[
  {
    "path": ".github/pull_request_template.md",
    "content": "## Describe tus cambios\n***(Opcional)*** *Sobre todo aconsejable si la \"Pull Request\" se corresponde con una corrección adicional y no con la presentación de un ejercicio.*\n\n## Comprobaciones\nAsegúrate de cumplir los siguientes puntos antes de realizar la \"Pull Request\":\n\n- [ ] El título de mi Pull Request sigue este formato: \"#[número] - [lenguaje_utilizado]\". *(Ej: #00 - Python\")*\n- [ ] El nombre el fichero se corresponde con el de mi usuario en GitHub más la extensión del lenguaje. *(Ej: mouredev.py)*\n- [ ] El fichero de corrección se encuentra dentro del directorio del ejercicio y en una carpeta con el nombre del lenguaje de programación utilizado en minúsculas. *(Ej: Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/mouredev.py)*\n- [ ] He revisado que el nombre del directorio del lenguaje no es conflictivo:\n\t- c#, no csharp\n\t- c++, no cplusplus\n\t- go, no golang\n\t- javascript, no js\n- [ ] Únicamente he incluido los ficheros de ejercicios. No se aceptarán Pull Requests que contengan archivos adicionales asociados a editores de código o semejantes.\n\n## Información\n\n* Tienes toda la información sobre los retos semanales en [retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap).\n* Recuerda que tienes un grupo de apoyo llamado \"ejercicios-logica\" en [Discord](https://discord.gg/mouredev).\n"
  },
  {
    "path": ".github/workflows/stats.yml",
    "content": "name: Stats\n\non:\n  schedule:\n    - cron: '0 0 * * *'\n\njobs:\n  build:\n    if: github.repository == 'mouredev/roadmap-retos-programacion' && github.ref == 'refs/heads/main'\n    runs-on: ubuntu-latest\n\n    permissions:\n      contents: write\n\n    steps:\n      - name: Checkout repo\n        uses: actions/checkout@v4\n\n      - name: Setup Python\n        uses: actions/setup-python@v5\n        with:\n          python-version: '3.11'\n\n      - name: Run script\n        run: python ./Roadmap/stats.py\n\n      - name: Commit and Push changes\n        uses: stefanzweifel/git-auto-commit-action@v5\n        with:\n          commit_message: Update stats\n          commit_user_name: Brais Moure [GitHub Actions]\n          commit_user_email: mouredev@gmail.com\n          commit_author: mouredev <mouredev@gmail.com>\n"
  },
  {
    "path": ".gitignore",
    "content": ".vscode/\n*.txt\n*.xml\n*.iml\n*.json\n*.csv\n*.zip\n!stats.json\n.DS_Store\n.idea/\npubspec.yaml\npubspec.lock\n.venv\n*.class\n*.gradle\n*.exe\n"
  },
  {
    "path": "LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "README.md",
    "content": "![https://retosdeprogramacion.com](./Images/header.jpg)\n\n# Roadmap retos de programación 2024\n\n### Ruta de estudio con ejercicios para mejorar tu lógica de programación y aprender cualquier lenguaje. Gratis, a tu ritmo y en comunidad.\n\n#### [https://retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)\n[![Retos programación web](https://img.shields.io/github/stars/mouredev/retos-programacion-web?label=Web%20Retos%20Programación&style=social)](https://github.com/mouredev/retos-programacion-web)\n\n## Ranking de lenguajes y usuarios\n\n#### ¿Estás participando en los retos? Ahora puedes consultar el ranking de usuarios y lenguajes según su número de contribuciones.\n\n#### [https://retosdeprogramacion.com/roadmap/ranking](https://retosdeprogramacion.com/roadmap/ranking)\n\n## Información importante\n\n* Puedes utilizar **cualquier lenguaje de programación**, y encontrar tanto mis correcciones como las de la comunidad en el directorio de cada reto.\n* **¿Quieres participar?** Te lo explico en la sección **[Instrucciones](https://github.com/mouredev/roadmap-retos-programacion#instrucciones)** en este mismo documento.\n* Los retos siguen un orden basado en su ruta de estudio pero si ya tienes conocimientos puedes resolverlos de manera totalmente independiente. Simplemente revisa su nivel de dificultad.\n\n> Consulta la [web](https://retosdeprogramacion.com/roadmap) para más información.\n\n## Roadmap\n\n| # | Ejercicio | Corrección | Vídeo | Comunidad |\n|---|-----------|------------|-------|-----------|\n|00|[SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO](./Roadmap/00%20-%20SINTAXIS,%20VARIABLES,%20TIPOS%20DE%20DATOS%20Y%20HOLA%20MUNDO/ejercicio.md)|[📝](./Roadmap/00%20-%20SINTAXIS,%20VARIABLES,%20TIPOS%20DE%20DATOS%20Y%20HOLA%20MUNDO/python/mouredev.py)|[▶️](https://youtu.be/gEIBJ7rmLa0)|[👥](./Roadmap/00%20-%20SINTAXIS,%20VARIABLES,%20TIPOS%20DE%20DATOS%20Y%20HOLA%20MUNDO/)\n|01|[OPERADORES Y ESTRUCTURAS DE CONTROL](./Roadmap/01%20-%20OPERADORES%20Y%20ESTRUCTURAS%20DE%20CONTROL/ejercicio.md)|[📝](./Roadmap/01%20-%20OPERADORES%20Y%20ESTRUCTURAS%20DE%20CONTROL/python/mouredev.py)|[▶️](https://youtu.be/DLSGCh9jdes)|[👥](./Roadmap/01%20-%20OPERADORES%20Y%20ESTRUCTURAS%20DE%20CONTROL/)\n|02|[FUNCIONES Y ALCANCE](./Roadmap/02%20-%20FUNCIONES%20Y%20ALCANCE/ejercicio.md)|[📝](./Roadmap/02%20-%20FUNCIONES%20Y%20ALCANCE/python/mouredev.py)|[▶️](https://youtu.be/auxClgiX6UM)|[👥](./Roadmap/02%20-%20FUNCIONES%20Y%20ALCANCE/)\n|03|[ESTRUCTURAS DE DATOS](./Roadmap/03%20-%20ESTRUCTURAS%20DE%20DATOS/ejercicio.md)|[📝](./Roadmap/03%20-%20ESTRUCTURAS%20DE%20DATOS/python/mouredev.py)|[▶️](https://youtu.be/brxtPtUbU7M)|[👥](./Roadmap/03%20-%20ESTRUCTURAS%20DE%20DATOS/)\n|04|[CADENAS DE CARACTERES](./Roadmap/04%20-%20CADENAS%20DE%20CARACTERES/ejercicio.md)|[📝](./Roadmap/04%20-%20CADENAS%20DE%20CARACTERES/python/mouredev.py)|[▶️](https://youtu.be/CKzY7nHwulA)|[👥](./Roadmap/04%20-%20CADENAS%20DE%20CARACTERES/)\n|05|[VALOR Y REFERENCIA](./Roadmap/05%20-%20VALOR%20Y%20REFERENCIA/ejercicio.md)|[📝](./Roadmap/05%20-%20VALOR%20Y%20REFERENCIA/python/mouredev.py)|[▶️](https://youtu.be/P2OQDT9Wrb0)|[👥](./Roadmap/05%20-%20VALOR%20Y%20REFERENCIA/)\n|06|[RECURSIVIDAD](./Roadmap/06%20-%20RECURSIVIDAD/ejercicio.md)|[📝](./Roadmap/06%20-%20RECURSIVIDAD/python/mouredev.py)|[▶️](https://youtu.be/nTfDkLRrYiM)|[👥](./Roadmap/06%20-%20RECURSIVIDAD/)\n|07|[PILAS Y COLAS](./Roadmap/07%20-%20PILAS%20Y%20COLAS/ejercicio.md)|[📝](./Roadmap/07%20-%20PILAS%20Y%20COLAS/python/mouredev.py)|[▶️](https://youtu.be/cBeRWS2X0CA)|[👥](./Roadmap/07%20-%20PILAS%20Y%20COLAS/)\n|08|[CLASES](./Roadmap/08%20-%20CLASES/ejercicio.md)|[📝](./Roadmap/08%20-%20CLASES/python/mouredev.py)|[▶️](https://youtu.be/W4tv8WUbum4)|[👥](./Roadmap/08%20-%20CLASES/)\n|09|[HERENCIA Y POLIMORFISMO](./Roadmap/09%20-%20HERENCIA/ejercicio.md)|[📝](./Roadmap/09%20-%20HERENCIA/python/mouredev.py)|[▶️](https://youtu.be/PVBs5PWjedA)|[👥](./Roadmap/09%20-%20HERENCIA/)\n|10|[EXCEPCIONES](./Roadmap/10%20-%20EXCEPCIONES/ejercicio.md)|[📝](./Roadmap/10%20-%20EXCEPCIONES/python/mouredev.py)|[▶️](https://youtu.be/mfOzfj-BrQo)|[👥](./Roadmap/10%20-%20EXCEPCIONES/)\n|11|[MANEJO DE FICHEROS](./Roadmap/11%20-%20MANEJO%20DE%20FICHEROS/ejercicio.md)|[📝](./Roadmap/11%20-%20MANEJO%20DE%20FICHEROS/python/mouredev.py)|[▶️](https://youtu.be/Bsiay2nax4Y)|[👥](./Roadmap/11%20-%20MANEJO%20DE%20FICHEROS/)\n|12|[JSON Y XML](./Roadmap/12%20-%20JSON%20Y%20XML/ejercicio.md)|[📝](./Roadmap/12%20-%20JSON%20Y%20XML/python/mouredev.py)|[▶️](https://youtu.be/OwStihBItEg)|[👥](./Roadmap/12%20-%20JSON%20Y%20XML/)\n|13|[PRUEBAS UNITARIAS](./Roadmap/13%20-%20PRUEBAS%20UNITARIAS/ejercicio.md)|[📝](./Roadmap/13%20-%20PRUEBAS%20UNITARIAS/python/mouredev.py)|[▶️](https://youtu.be/3WFQ2grp0h0)|[👥](./Roadmap/13%20-%20PRUEBAS%20UNITARIAS/)\n|14|[FECHAS](./Roadmap/14%20-%20FECHAS/ejercicio.md)|[📝](./Roadmap/14%20-%20FECHAS/python/mouredev.py)|[▶️](https://youtu.be/EQIAhF7NNMI)|[👥](./Roadmap/14%20-%20FECHAS/)\n|15|[ASINCRONÍA](./Roadmap/15%20-%20ASINCRONÍA/ejercicio.md)|[📝](./Roadmap/15%20-%20ASINCRONÍA/python/mouredev.py)|[▶️](https://youtu.be/YA8Ssd3AUwA)|[👥](./Roadmap/15%20-%20ASINCRONÍA/)\n|16|[EXPRESIONES REGULARES](./Roadmap/16%20-%20EXPRESIONES%20REGULARES/ejercicio.md)|[📝](./Roadmap/16%20-%20EXPRESIONES%20REGULARES/python/mouredev.py)|[▶️](https://youtu.be/0L7IfEF19ow)|[👥](./Roadmap/16%20-%20EXPRESIONES%20REGULARES/)\n|17|[ITERACIONES](./Roadmap/17%20-%20ITERACIONES/ejercicio.md)|[📝](./Roadmap/17%20-%20ITERACIONES/python/mouredev.py)|[▶️](https://youtu.be/X1ROaPH_ci8)|[👥](./Roadmap/17%20-%20ITERACIONES/)\n|18|[CONJUNTOS](./Roadmap/18%20-%20CONJUNTOS/ejercicio.md)|[📝](./Roadmap/18%20-%20CONJUNTOS/python/mouredev.py)|[▶️](https://youtu.be/0auuM4GROVA)|[👥](./Roadmap/18%20-%20CONJUNTOS/)\n|19|[ENUMERACIONES](./Roadmap/19%20-%20ENUMERACIONES/ejercicio.md)|[📝](./Roadmap/19%20-%20ENUMERACIONES/python/mouredev.py)|[▶️](https://youtu.be/0auuM4GROVA)|[👥](./Roadmap/19%20-%20ENUMERACIONES/)\n|20|[PETICIONES HTTP](./Roadmap/20%20-%20PETICIONES%20HTTP/ejercicio.md)|[📝](./Roadmap/20%20-%20PETICIONES%20HTTP/python/mouredev.py)|[▶️](https://youtu.be/-pYMoPYSkgM)|[👥](./Roadmap/20%20-%20PETICIONES%20HTTP/)\n|21|[CALLBACKS](./Roadmap/21%20-%20CALLBACKS/ejercicio.md)|[📝](./Roadmap/21%20-%20CALLBACKS/python/mouredev.py)|[▶️](https://youtu.be/tqQo9SjJFlY)|[👥](./Roadmap/21%20-%20CALLBACKS/)\n|22|[FUNCIONES DE ORDEN SUPERIOR](./Roadmap/22%20-%20FUNCIONES%20DE%20ORDEN%20SUPERIOR/ejercicio.md)|[📝](./Roadmap/22%20-%20FUNCIONES%20DE%20ORDEN%20SUPERIOR/python/mouredev.py)|[▶️](https://youtu.be/ABniGtbqAXk)|[👥](./Roadmap/22%20-%20FUNCIONES%20DE%20ORDEN%20SUPERIOR/)\n|23|[SINGLETON](./Roadmap/23%20-%20SINGLETON/ejercicio.md)|[📝](./Roadmap/23%20-%20SINGLETON/python/mouredev.py)|[▶️](https://youtu.be/cOIcFo_w9hA)|[👥](./Roadmap/23%20-%20SINGLETON/)\n|24|[DECORADORES](./Roadmap/24%20-%20DECORADORES/ejercicio.md)|[📝](./Roadmap/24%20-%20DECORADORES/python/mouredev.py)|[▶️](https://youtu.be/jxJOjg7gPG4)|[👥](./Roadmap/24%20-%20DECORADORES/)\n|25|[LOGS](./Roadmap/25%20-%20LOGS/ejercicio.md)|[📝](./Roadmap/25%20-%20LOGS/python/mouredev.py)|[▶️](https://youtu.be/y2O6L1r_skc)|[👥](./Roadmap/25%20-%20LOGS/)\n|26|[SOLID: PRINCIPIO DE RESPONSABILIDAD ÚNICA](./Roadmap/26%20-%20SOLID%20SRP/ejercicio.md)|[📝](./Roadmap/26%20-%20SOLID%20SRP/python/mouredev.py)|[▶️](https://youtu.be/7NM8FK9G91M)|[👥](./Roadmap/26%20-%20SOLID%20SRP)\n|27|[SOLID: PRINCIPIO ABIERTO-CERRADO](./Roadmap/27%20-%20SOLID%20OCP/ejercicio.md)|[📝](./Roadmap/27%20-%20SOLID%20OCP/python/mouredev.py)|[▶️](https://youtu.be/o0lSVzu4ur4)|[👥](./Roadmap/27%20-%20SOLID%20OCP/)\n|28|[SOLID: PRINCIPIO DE SUSTITUCIÓN DE LISKOV](./Roadmap/28%20-%20SOLID%20LSP/ejercicio.md)|[📝](./Roadmap/28%20-%20SOLID%20LSP/python/mouredev.py)|[▶️](https://youtu.be/SgHoiF1KLTo)|[👥](./Roadmap/28%20-%20SOLID%20LSP/)\n|29|[SOLID: PRINCIPIO DE SEGREGACIÓN DE INTERFACES](./Roadmap/29%20-%20SOLID%20ISP/ejercicio.md)|[📝](./Roadmap/29%20-%20SOLID%20ISP/python/mouredev.py)|[▶️](https://youtu.be/0zTmCTHJ_lg)|[👥](./Roadmap/29%20-%20SOLID%20ISP/)\n|30|[SOLID: PRINCIPIO DE INVERSIÓN DE DEPENDENCIAS](./Roadmap/30%20-%20SOLID%20DIP/ejercicio.md)|[📝](./Roadmap/30%20-%20SOLID%20DIP/python/mouredev.py)|[▶️](https://youtu.be/wxIj6Rs8rAU)|[👥](./Roadmap/30%20-%20SOLID%20DIP/)\n|31|[SIMULADOR JUEGOS OLÍMPICOS](./Roadmap/31%20-%20SIMULADOR%20JUEGOS%20OLÍMPICOS/ejercicio.md)|[📝](./Roadmap/31%20-%20SIMULADOR%20JUEGOS%20OLÍMPICOS/python/mouredev.py)|[▶️](https://youtu.be/JN656lQ9WBo)|[👥](./Roadmap/31%20-%20SIMULADOR%20JUEGOS%20OLÍMPICOS/)\n|32|[BATALLA DEADPOOL Y WOLVERINE](./Roadmap/32%20-%20BATALLA%20DEADPOOL%20Y%20WOLVERINE/ejercicio.md)|[📝](./Roadmap/32%20-%20BATALLA%20DEADPOOL%20Y%20WOLVERINE/python/mouredev.py)|[▶️](https://youtu.be/u2Tn2H3pqjw)|[👥](./Roadmap/32%20-%20BATALLA%20DEADPOOL%20Y%20WOLVERINE/)\n|33|[RESCATANDO A MICKEY](./Roadmap/33%20-%20RESCATANDO%20A%20MICKEY/ejercicio.md)|[📝](./Roadmap/33%20-%20RESCATANDO%20A%20MICKEY/python/mouredev.py)|[▶️](https://youtu.be/Bo9Cp3N68C0)|[👥](./Roadmap/33%20-%20RESCATANDO%20A%20MICKEY/)\n|34|[ÁRBOL GENEALÓGICO DE LA CASA DEL DRAGÓN](./Roadmap/34%20-%20ÁRBOL%20GENEALÓGICO%20LA%20CASA%20DEL%20DRAGÓN/ejercicio.md)|[📝](./Roadmap/34%20-%20ÁRBOL%20GENEALÓGICO%20LA%20CASA%20DEL%20DRAGÓN/python/mouredev.py)|[▶️](https://youtu.be/GAHBOAzgE2w)|[👥](./Roadmap/34%20-%20ÁRBOL%20GENEALÓGICO%20LA%20CASA%20DEL%20DRAGÓN/)\n|35|[REPARTIENDO LOS ANILLOS DE PODER](./Roadmap/35%20-%20REPARTIENDO%20LOS%20ANILLOS%20DE%20PODER/ejercicio.md)|[📝](./Roadmap/35%20-%20REPARTIENDO%20LOS%20ANILLOS%20DE%20PODER/python/mouredev.py)|[▶️](https://youtu.be/10i2dnaMLj8)|[👥](./Roadmap/35%20-%20REPARTIENDO%20LOS%20ANILLOS%20DE%20PODER/)\n|36|[EL SOMBRERO SELECCIONADOR](./Roadmap/36%20-%20EL%20SOMBRERO%20SELECCIONADOR/ejercicio.md)|[📝](./Roadmap/36%20-%20EL%20SOMBRERO%20SELECCIONADOR/python/mouredev.py)|[▶️](https://youtu.be/_UjOD587elY)|[👥](./Roadmap/36%20-%20EL%20SOMBRERO%20SELECCIONADOR/)\n|37|[OASIS VS LINKIN PARK](./Roadmap/37%20-%20OASIS%20VS%20LINKIN%20PARK/ejercicio.md)|[📝](./Roadmap/37%20-%20OASIS%20VS%20LINKIN%20PARK/python/mouredev.py)|[▶️](https://youtu.be/q-zBKriHupY)|[👥](./Roadmap/37%20-%20OASIS%20VS%20LINKIN%20PARK/)\n|38|[MOUREDEV PRO](./Roadmap/38%20-%20MOUREDEV%20PRO/ejercicio.md)|[📝](./Roadmap/38%20-%20MOUREDEV%20PRO/python/mouredev.py)|[▶️](https://youtu.be/AbGROLoAVLs)|[👥](./Roadmap/38%20-%20MOUREDEV%20PRO/)\n|39|[BATMAN DAY](./Roadmap/39%20-%20BATMAN%20DAY/ejercicio.md)|[📝](./Roadmap/39%20-%20BATMAN%20DAY/python/mouredev.py)|[▶️](https://youtu.be/Lmj5enZG5pg)|[👥](./Roadmap/39%20-%20BATMAN%20DAY/)\n|40|[FORTNITE RUBIUS CUP](./Roadmap/40%20-%20FORTNITE%20RUBIUS%20CUP/ejercicio.md)|[📝](./Roadmap/40%20-%20FORTNITE%20RUBIUS%20CUP/python/mouredev.py)|[▶️](https://youtu.be/UlWtFvLLSXw)|[👥](./Roadmap/40%20-%20FORTNITE%20RUBIUS%20CUP/)\n|41|[CAMISETA RAR](./Roadmap/41%20-%20CAMISETA%20RAR/ejercicio.md)|[📝](./Roadmap/41%20-%20CAMISETA%20RAR/python/mouredev.py)|[▶️](https://youtu.be/QXFrWIFCkGY)|[👥](./Roadmap/41%20-%20CAMISETA%20RAR/)\n|42|[TORNEO DRAGON BALL](./Roadmap/42%20-%20TORNEO%20DRAGON%20BALL/ejercicio.md)|[📝](./Roadmap/42%20-%20TORNEO%20DRAGON%20BALL/python/mouredev.py)|[▶️](https://youtu.be/SgwX7ISEkvM)|[👥](./Roadmap/42%20-%20TORNEO%20DRAGON%20BALL/)\n|43|[GIT GITHUB CLI](./Roadmap/43%20-%20GIT%20GITHUB%20CLI/ejercicio.md)|[📝](./Roadmap/43%20-%20GIT%20GITHUB%20CLI/python/mouredev.py)|[▶️](https://youtu.be/Ct4GKpbqflI)|[👥](./Roadmap/43%20-%20GIT%20GITHUB%20CLI/)\n|44|[CUENTA ATRÁS MOUREDEV PRO](./Roadmap/44%20-%20CUENTA%20ATRÁS%20MOUREDEV%20PRO/ejercicio.md)|[📝](./Roadmap/44%20-%20CUENTA%20ATRÁS%20MOUREDEV%20PRO/python/mouredev.py)|[▶️](https://youtu.be/9wsXz4K8Q-4)|[👥](./Roadmap/44%20-%20CUENTA%20ATRÁS%20MOUREDEV%20PRO/)\n|45|[GITHUB OCTOVERSE](./Roadmap/45%20-%20GITHUB%20OCTOVERSE/ejercicio.md)|[📝](./Roadmap/45%20-%20GITHUB%20OCTOVERSE/python/mouredev.py)|[▶️](https://youtu.be/yj5ZFT_Xmcs)|[👥](./Roadmap/45%20-%20GITHUB%20OCTOVERSE/)\n|46|[X VS BLUESKY](./Roadmap/46%20-%20X%20VS%20BLUESKY/ejercicio.md)|[📝](./Roadmap/46%20-%20X%20VS%20BLUESKY/python/mouredev.py)|[▶️](https://youtu.be/RzwFGihKpOM)|[👥](./Roadmap/46%20-%20X%20VS%20BLUESKY/)\n|47|[CALENDARIO DE ADVIENTO](./Roadmap/47%20-%20CALENDARIO%20DE%20ADVIENTO/ejercicio.md)|[📝](./Roadmap/47%20-%20CALENDARIO%20DE%20ADVIENTO/python/mouredev.py)|[▶️](https://youtu.be/LteI1J5gmZw)|[👥](./Roadmap/47%20-%20CALENDARIO%20DE%20ADVIENTO/)\n|48|[ÁRBOL DE NAVIDAD](./Roadmap/48%20-%20ÁRBOL%20DE%20NAVIDAD/ejercicio.md)|[📝](./Roadmap/48%20-%20ÁRBOL%20DE%20NAVIDAD/python/mouredev.py)|[▶️](https://youtu.be/bIguZe3iXVo)|[👥](./Roadmap/48%20-%20ÁRBOL%20DE%20NAVIDAD/)\n|49|[EL ALMACÉN DE PAPÁ NOEL](./Roadmap/49%20-%20EL%20ALMACÉN%20DE%20PAPÁ%20NOEL/ejercicio.md)|[📝](./Roadmap/49%20-%20EL%20ALMACÉN%20DE%20PAPÁ%20NOEL/python/mouredev.py)|[▶️](https://youtu.be/XGMxosQArxw)|[👥](./Roadmap/49%20-%20EL%20ALMACÉN%20DE%20PAPÁ%20NOEL/)\n|50|[PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO](./Roadmap/50%20-%20PLANIFICADOR%20DE%20OBJETIVOS%20DE%20A%C3%91O%20NUEVO/ejercicio.md)|[📝](./Roadmap/50%20-%20PLANIFICADOR%20DE%20OBJETIVOS%20DE%20A%C3%91O%20NUEVO/python/mouredev.py)|[▶️](https://youtu.be/MmHSEcWlSbk)|[👥](./Roadmap/50%20-%20PLANIFICADOR%20DE%20OBJETIVOS%20DE%20A%C3%91O%20NUEVO/)\n\n## Cursos en YouTube\n\nA media que avanzamos en el roadmap estoy creando cursos que agrupan las clases.\n\n[![Lógica 1](http://i3.ytimg.com/vi/TdITcVD64zI/maxresdefault.jpg)](https://youtu.be/TdITcVD64zI)\n\n[![Lógica 2](http://i3.ytimg.com/vi/b-kk1WQo-YA/maxresdefault.jpg)](https://youtu.be/b-kk1WQo-YA)\n\n[![Lógica 3 SOLID](http://i3.ytimg.com/vi/ASBC5drF-QU/maxresdefault.jpg)](https://youtu.be/ASBC5drF-QU)\n\n[![Lógica 4](http://i3.ytimg.com/vi/qSup_483xO8/maxresdefault.jpg)](https://youtu.be/qSup_483xO8)\n\n## Instrucciones\n\n**Haz un [FORK](https://github.com/mouredev/roadmap-retos-programacion/fork) del proyecto y trabaja con Git para ir sincronizando las actualizaciones.**\n\n1. En el proyecto tienes un directorio para cada ejercicio en la carpeta [Roadmap](./Roadmap). Dentro de cada directorio encontrarás un fichero llamado **ejercicio.md** con el enunciado de cada reto.\n2. Si quieres compartir tu propia solución de un ejercicio con la comunidad, crea un fichero de código con tu nombre y extensión, y realiza una [**PULL REQUEST**](https://docs.github.com/es/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request) contra el repositorio.\n3. El fichero de código debe situarse dentro del directorio del reto, en la carpeta correspondiente al lenguaje de programación utilizado (si no existe la carpeta del lenguaje, créala con todas sus letras en minúsculas). Por ejemplo, si has resuelto el reto #00 utilizando el lenguaje de programación Python y tu usuario de GitHub se llama \"mouredev\", tu corrección deberá estar en **\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/mouredev.py\"**. El título de la Pull Request también debe seguir este formato: **\"#[número] - [lenguaje_utilizado]\"**. En el ejemplo anterior sería **\"#00 - Python\"**. Se rechazarán las Pull Request que no sigan este formato o contengan ficheros adicionales.\n4. Si necesitas ayuda o quieres comentar cualquier cosa sobre los retos, tienes el canal \"ejercicios-logica” en nuestro servidor de **[Discord](https://discord.gg/mouredev)**.\n5. Puedes proponer Pull Request con propuestas o correcciones sobre ejercicios del resto de la comunidad si estos poseen errores. De esta manera colaboraremos para crear un repositorio cada vez más valioso.\n6. Si se te solicita un cambio/corrección en una Pull Request, y al cabo de 2 semanas no se muestra nueva actividad, se cerrará esa petición para mantener el repositorio limpio. Por supuesto, puedes volver a enviar la Pull Request cuando quieras.\n\n## Aclaraciones\n\nSi tienes dudas con el nombre del directorio de algún lenguaje, intenta consultar el nombre que se ha empleado en ejercicios anteriores. Algunos ejemplos que puedes llegar a dudar:\n    \n* c#, no csharp\n* c++, no cplusplus\n* go, no golang\n* javascript, no js\n\n## Guía rápida Git y GitHub\n\n1. Realiza un [FORK](https://github.com/mouredev/roadmap-retos-programacion/fork) del repositorio de retos desde GitHub.\n2. CLONA ese repositorio a tu máquina local `git clone [TU-REPOSITORIO]`.\n3. (Opcional) Crea una RAMA para la solución y desplázate a ella `git checkout -b [EL-NOMBRE-DE-TU-RAMA]`.\n4. Añade el fichero de tu solución al STAGE `git add [FICHERO-DE-TU-RETO]`.\n5. Haz COMMIT con el mensaje de la solución `git commit -m \"#[NÚMERO-RETO] - [LENGUAJE-UTILIZADO]\"`.\n6. Haz PUSH `git push [EL-NOMBRE-DE-TU-RAMA]` (puede ser la \"main\" o la que creaste en el paso 3)\n7. En el repositorio principal debes ir a la rama y hacer [PULL REQUEST](https://docs.github.com/es/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request).\n8. CONTRIBUTE.\n9. CREATE PULL REQUEST (cubre la plantilla que te aparecerá).\n10. Si el proceso de entrega se ha realizado de forma correcta, se añadirá tu corrección al repositorio. En caso contrario, se te notificarán los cambios a realizar o los motivos del rechazo.\n\n*He creado un curso completo gratis para aprender a trabajar con Git y GitHub desde cero.*\n\n[![Curso Git y GitHub](https://img.shields.io/github/stars/mouredev/hello-git?label=Curso%20Git%20GitHub&style=social)](https://github.com/mouredev/hello-git)\n\n## Más retos de programación\n\n**Consulta los 101 retos de programación resueltos y las 12 aplicaciones para tu portfolio que ya hemos desarrollado.**\n\n[![Retos programación 2023](https://img.shields.io/github/stars/mouredev/retos-programacion-2023?label=Retos%20Programación%202023&style=social)](https://github.com/mouredev/retos-programacion-2023)\n[![Retos programación 2022](https://img.shields.io/github/stars/mouredev/Weekly-Challenge-2022-Kotlin?label=Retos%20Semanales%202022&style=social)](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin)\n[![Aplicaciones portafolio](https://img.shields.io/github/stars/mouredev/Monthly-App-Challenge-2022?label=Aplicaciones%20portafolio&style=social)](https://github.com/mouredev/Monthly-App-Challenge-2022)\n\n## Únete al campus de programación de la comunidad\n\n![https://mouredev.pro](./Images/pro.jpg)\n\n#### Te presento [mouredev pro](https://mouredev.pro), mi proyecto más importante para ayudarte a estudiar programación y desarrollo de software de manera diferente.\n\n> **¿Buscas un extra?** Aquí encontrarás mis cursos editados por lecciones individuales, para avanzar a tu ritmo y guardar el progreso. También dispondrás de ejercicios y correcciones, test para validar tus conocimientos, examen y certificado público de finalización, soporte, foro de estudiantes, reunionnes grupales, cursos exclusivos y mucho más.\n> \n> Entra en **[mouredev.pro](https://mouredev.pro)** y utiliza el cupón **\"PRO\"** con un 10% de descuento en tu primera suscripción.\n\n## ![https://mouredev.com](https://raw.githubusercontent.com/mouredev/mouredev/master/mouredev_emote.png) Hola, mi nombre es Brais Moure.\n### Freelance full-stack iOS & Android engineer\n\n[![YouTube Channel Subscribers](https://img.shields.io/youtube/channel/subscribers/UCxPD7bsocoAMq8Dj18kmGyQ?style=social)](https://youtube.com/mouredevapps?sub_confirmation=1)\n[![Twitch Status](https://img.shields.io/twitch/status/mouredev?style=social)](https://twitch.com/mouredev)\n[![Discord](https://img.shields.io/discord/729672926432985098?style=social&label=Discord&logo=discord)](https://mouredev.com/discord)\n[![Twitter Follow](https://img.shields.io/twitter/follow/mouredev?style=social)](https://twitter.com/mouredev)\n![GitHub Followers](https://img.shields.io/github/followers/mouredev?style=social)\n![GitHub Followers](https://img.shields.io/github/stars/mouredev?style=social)\n\nSoy ingeniero de software desde 2010. Desde 2018 combino mi trabajo desarrollando Apps con la creación de contenido formativo sobre programación y tecnología en diferentes redes sociales como **[@mouredev](https://moure.dev)**.\n\nSi quieres unirte a nuestra comunidad de desarrollo, aprender programación, mejorar tus habilidades y ayudar a la continuidad del proyecto, puedes encontrarnos en:\n\n[![Twitch](https://img.shields.io/badge/Twitch-Programación_en_directo-9146FF?style=for-the-badge&logo=twitch&logoColor=white&labelColor=101010)](https://twitch.tv/mouredev)\n[![Discord](https://img.shields.io/badge/Discord-Servidor_de_la_comunidad-5865F2?style=for-the-badge&logo=discord&logoColor=white&labelColor=101010)](https://mouredev.com/discord) [![Pro](https://img.shields.io/badge/Cursos-mouredev.pro-FF5500?style=for-the-badge&logo=gnometerminal&logoColor=white&labelColor=101010)](https://mouredev.pro)\n[![Link](https://img.shields.io/badge/Links_de_interés-moure.dev-14a1f0?style=for-the-badge&logo=Linktree&logoColor=white&labelColor=101010)](https://moure.dev) [![Web](https://img.shields.io/badge/GitHub-MoureDev-087ec4?style=for-the-badge&logo=github&logoColor=white&labelColor=101010)](https://github.com/mouredev)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/abap/angelcruzg23.abap",
    "content": "* Link official https://help.sap.com/doc/abapdocu_750_index_htm/7.50/en-US/index.htm\n\n* Comentario de toda la linea de codigo, solo se colocar el asterisco al inicio \n\" También se puede utilizar comillas dobles \n\n* Como se crea una variable en ABAP\n\n\" Se utiliza la palabra reservada DATA al inicio con el tipo que corresponda\ndata my_var type string value 'Mi Variable'.\nmy_var = 'Nuevo valor'. \" Al final de cada sentencia se finaliza con punto (.).\n\n\" En la nueva sintaxis se crean variables en linea \ndata(my_var_inline) = 'Variable en linea'.\n\n\" Las constantes se crean con la sintaxis CONSTANTS\nCONSTANTS MY_CONSTANT type String value 'No Me Cambies'.\n\n\" Crear variable tipo entero \ndata my_int type I.\nmy_int = 1.\n\n\" Crear variable tipo decimal\ndata my_dec TYPE p LENGTH 8 DECIMALS 2.\nmy_dec = 10.02\n\n\" Como se escriben en pantalla las variables \n\nwrite:/ myvar.\nwrite:/ my_var_inline.\nwrite:/ my_int.\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/ada/edalmava.adb",
    "content": "-- Los comentarios en Ada comienzan con dos guiones (--)\n-- y se extienden hasta el final de la línea\n-- El lenguaje Ada esta especificado en la norma ISO/IEC 8652:2023\n-- a fecha 25-01-2025\n-- Sitios oficiales de organizaciones vinculadas a su desarrollo y promoción:\n-- https://www.adaic.org/\n-- https://www.adacore.com/\n-- https://learn.adacore.com/courses/intro-to-ada/index.html\n\nwith Ada.Text_IO; use Ada.Text_IO;\n\nprocedure Main is\n   -- Los tipos de datos elementales en Ada son los punteros y los escalares\n   -- Los tipos escalares se clasifican en discretos y reales\n   -- Declaración de variables\n   -- identificador { , identificador }: tipo [ := expresión ];   \n   entero : Integer := 5;\n   flotante : Float := 5.0;\n   caracter : Character := 'X';\n   verdadero : Boolean := True;\n   \n   -- Las constantes se declaran igual que las variables, pero añadiendo la palabra\n   -- reservada constant\n   -- identificador { , identificador } : constant [ tipo] [ := expresión ] ;\n   lenguaje : Constant String := \"¡Hola, Ada!\";\n   pi : Constant Float := 3.1416;\nbegin   \n   Put_Line(lenguaje); --  Mostrar la cadena \"¡Hola, Ada!\"\nend Main;\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/ada/reanthonyh.adb",
    "content": "-- https://learn.adacore.com/\n\n-- Comentario de una linea\n\n-- Ada no tiene equivalente para comentarios de multiples lineas como /**/\n-- Solo se usa varias lineas de con `--`\n\nwith Ada.Text_IO;\n\nprocedure Principal is\n   -- Creacion de una variable\n   Numero : Integer := 20;\n   -- Creacion de una variable float CONSTANTE\n   Pi : constant Float := 3.14;\n   Is_True : Boolean := True;\n   My_Char : Character := 'A';\n   My_String : String := \"Hello, Ada!\";\nbegin\n   -- Creacion de una variable en un bloque de codigo\n   declare\n      Alpha : Integer := 0;\n   begin\n      Alpha := Alpha + 1;\n   end;\n   -- Fin del bloque\n   \n   Ada.Text_IO.Put_Line (\"¡Hola, Ada!\");\nend Principal;\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/al/mickysoft.al",
    "content": "// https://learn.microsoft.com/en-us/dynamics365/business-central/dev-itpro/developer/devenv-programming-in-al\n\n// Comentario de una linea\n\n/*\nComentario de \nvarias \nlineas\n*/\n\nvar\n    //- Crea una variable (y una constante si el lenguaje lo soporta).\n    MyIntegerVal : Integer;        \n    MyConstText : Label 'My constant'; //Esto es una constante de texto, admite traducciones y se añade en el fichero .xliff que se genera al compilar\n    \n    //- Crea variables representando todos los tipos de datos primitivos\n    MyInteger : Integer;    \n    MyDecimal : Decimal;\n    MyBigInteger : BigInteger;\n    MyBoolean : Boolean;    \n    MyDate : Date;\n    MyTime : Time;\n    MyDateTime : DateTime;\n    MyDuration : Duration;\n    MyBigText : BigText;\n    MyByte : Byte;\n    MyText : Text[50];\n    MyChar : Char;\n    MyCode : Code[20];\n    MyGuid : Guid;\n    MyTextBuilder : TextBuilder;\n\n\nprocedure HelloWorld()\nbegin    \n    Message('¡Hola, AL!');\nend;\n\n    "
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/arduino/deimoshall.ino",
    "content": "// Enlance oficial para aprender sobre Arduino: https://www.arduino.cc/en/Guide\n// Este es un comentario en una sola linea\n/*\n\tEste es un comentario en varias lineas\n\tEste es otro comentario en varias lineas\n*/\n\n// Esta es una variable global\nint globalVariable = 0;\n\nvoid setup() {\n  // Esta es una variable local\n\tint localVariable = 2;\n\t// Esta es una constante\n\tconst int constantVariable = 3;  // Su valor no puede cambiar\n\n\t// Tipos de datos primitivos\n\tbool booleanVariable = true;  // true o false\n\tchar charVariable = 'a';  // Un solo caracter\n\tint intVariable = 1;  // Entero\n\tfloat floatVariable = 1.0;  // Decimal\n\tdouble doubleVariable = 1.0;  // Decimal con mayor precision\n\n\t// Tipos de datos compuestos\n\tconst char *stringVariable = \"Hola mundo\";  // Cadena de caracteres\n\tString stringVariable2 = \"Hola mundo\";  // Cadena de caracteres\n\tconst char arrayVariable[] = \"Hola mundo\";  // Arreglo de caracteres\n\tint arrayVariable2[] = {1, 2, 3};  // Arreglo de enteros\n\n\tSerial.begin(9600);  // Inicializa el puerto serial\n}\n\nvoid loop() {\n\tSerial.println(\"Hola Arduino!\");\t// Imprime en el puerto serial\n\tdelay(1000);  // Espera 1 segundo\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/arduino/santyjL.ino",
    "content": "//https://www.arduino.cc/\n\n/*\nno hay que olvidar que arduino se usa con las placas arduino haci que es recomendable\nuna vista de como se ejecutaria algunas cosas en el hardware\n\neste canal de youtube te podria a ayudar a prender si de verdad te interesa aprender el lenguaje al 100%\nhttps://www.youtube.com/@EdgarPonsYoutube\n*/\n\n\n// 00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO / documentacion de una linea\n\n/*\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\n * esta es la documentacion en varias lineas\n*/\n\n\nString lenguaje = \"Arduino!\"; //variabe\nconst int hora = 60; //constante\n\n//datos primitivos\n\nString texto = \"esto es un string\";\nint numeroEntero = 50;\nfloat numeroFlotante = 50.5;\nbool boleano = true;\n\nvoid setup (){\n    Serial.begin(9600);\n}\n\nvoid loop(){\n\n    Serial.print(\"¡Hola, \"); // Sigue en la misma línea el siguiente print\n    Serial.print(lenguaje); // El siguiente print se mostrará en la misma línea\n    Serial.println(\"!\"); // El siguiente print se mostrará en otra línea\n\n    return;\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/bash/HackyN3t.sh",
    "content": "#!/bin/bash\n\n# Página oficial de referencia de Bash:\n# https://www.gnu.org/software/bash/manual/\n\n# Esto es un comentario en Bash (línea única).\n\n# En Bash no existen comentarios multilínea nativos.\n# Sin embargo, se puede simular un bloque ignorado usando un *heredoc*:\n\n: <<'COMENTARIO'\nEste bloque no será ejecutado por Bash.\nAunque no es un comentario real, funciona como tal.\nEs útil para descripciones largas o documentación temporal.\n¡¡¡NO RECOMENDADO!!! PUEDE EJECUTAR COMANDOS EN ALGUNAS SITUACIONES, POR LO TANTO, NO ES SEGURO.\nCOMENTARIO\n\n# Variables\n# Las variables no pueden comenzar con un número y no pueden contener espacios.\n\n\n# En Bash, las variables no son tipadas.\n# Es decir, no se define el tipo de dato al declarar una variable.\n# Todo se trata internamente como texto (strings), aunque Bash puede operar con enteros si se requiere.\n\n# Ejemplos de variables sin tipo:\n\nx=42 \t\t\t# Número (entero)\ny=\"Hola Mundo!\" # Cadena (string)\n\n\n# Bash trata ambas como texto, a menos que se usen en contextos aritméticos:\n\necho $x\t\t\t# Muestra: 42\n\necho $y\t\t\t# Muestra: \"Hola Mundo!\"\n\n\n# Si la Variable x se utiliza en un contexto aritmetico se interpreta como entero:\n\necho $((x+1)) \t# Muestra:43\n\n# En Bash no existen constantes verdaderas.\n# Sin embargo, se pueden simular usando Variables readonly o convenciones de nomenclatura.\n\n# Ejemplo de Variable readonly\n\nPI=3.1415\nreadonly PI \t# Ahora PI no se puede modificar.\necho \"$PI\"\n\nPI=3.0  \t\t# Error: bash: PI: readonly variable.\n\n#Las constantes por convención tienen el nombre en mayúsculas.\n\n\n#Las Variables en Bash pueden almacenar los resultados de ejecuciones de comandos.\n\nresultadols=`ls`\nresultadols2=$(ls -la)\n\necho \"$resultadols\"\necho \"$resultadols2\"\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/bash/Van-02.sh",
    "content": "#!/bin/bash\n\n# URL del sitio web oficial de Bash: https://www.gnu.org/software/bash/\n\n# COMENTARIOS\n\n# Esto es un comentario de una linea.\n\n: '\n  Este es un comentario \n  de varias lineas\n'\n\n\n# VARIABLES\n\nvariable=0                          # variable\nreadonly constant=\"Mi constante\"    # constante\n\nfunction my_function {\n  local variable_local=0            # variable local\n}\n\n# TIPOS DE DATOS\n\nvariable=\"String\"                   # String\nvariable=1                          # Int\nvariable=(\"rojo\" \"verde\" \"azul\")    # Array\nvariable=true                       # Boolean\n\ndeclare -A dictionary\ndictionary[valor]='valor1'          # diccionario\n\n# Hola mundo\necho \"Hola, Bash!\"                  # echo sirve para imprimir en la terminal\n\n# Para llamar a una variable se usa el simbolo $[nombre de la variable]\nvariable=\"Hola Bash\"\necho $variable                      \n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/bash/abelsrzz.sh",
    "content": "#!/bin/bash\n: '\n\nNo hay una página oficial de bash así que coloco la página de Wikipedia.\n- https://es.wikipedia.org/wiki/Bash\n\n'\n\n# Esto es un comentario de una sola línea\n\n: '\nEsto es un comentario multi línea.\n'\n\n: << EOF\n\nEsto también es un comentario multi línea.\n\nEOF\n\ndeclare constante=\"constante\"\necho \"Esto es una $constante\"\n\ncadena=\"cadena\"\necho \"Esto es una $cadena\"\n\nint=1\necho \"Este ese mi int número $int\"\n\narray=(\"Esto\" \" es\" \" un\" \" array\")\necho \"${array[@]}\"\n\nbool_1=true\nbool_2=false\n\necho \"Existen booleanos $bool_1 y $bool_2\"\n\n\necho \"Hola Bash!\"\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/bash/alabacw74.sh",
    "content": "#!/bin/bash\n\n# 00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n# alabacw74\n\n# Sitio oficial\n# https://www.gnu.org/software/bash/manual/bash.html\n\n# Este es un comentario de una linea y los comentarios multilinea no estan\n# sustentados de manera directa pero podemos hacerlo como aqui.\n\n# Variables\nsaludo=\"Hola a todos yo soy $USER\"\necho $saludo\n\n# Constantes\ndeclare -r MI_CONSTANTE=\"2024-01-15\"\necho $MI_CONSTANTE\n\n# En bash las variables no se tratan como en otros lenguajes de alto nivel,\n# los valores de las  variables son trabajados como cadenas de texto. Si se\n# desea trabajar con numeros es necesario hacer una expansión aritmetica\n\n# Enviar por pantalla\necho \"¡Hola, bash!"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/bash/angelsanchezt.sh",
    "content": "#!/bin/bash\n# URL del sitio web oficial de Bash: https://www.gnu.org/software/bash/\n\n# Comentario de una línea\n# Otra forma de comentario de una línea\n\n: '\n  Este es un comentario de\n  varias líneas en Bash\n'\n\n# Declaración de variables y constante\nvariable=\"Hola, Bash\"  # Variable\nreadonly constante=\"Valor constante\"  # Constante\n\n# Tipos de datos primitivos en Bash\nentero=42  # Entero\nflotante=3.14  # Flotante (representado como cadena)\nbooleano=true  # Booleano (representado como cadena)\n\n# Imprimir por terminal\necho $variable\necho $constante\necho \"Entero: $entero\"\necho \"Flotante: $flotante\"\necho \"Booleano: $booleano\""
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/bash/arturonavas.sh",
    "content": "#!/bin/bash\n\n# https://www.gnu.org/software/bash/\n\n#esto es un comentario simple en bash\n\n: '\n esto es un\n comentario de\n varias lineas\n'\n\nsaludo=\"Hola Mundo!\" #string\na=1                  #integer\nb=2.7182             #float\nc=true               #boolean\nd='o'                #char\ne=(\"Hola\" \"Bash\"\"!\") #array\nreadonly pi=3.1416   #constante\n\necho \"${e[*]}\"       #imprimir en bash\nprintf \"Hola Mundo!\"\n\n: '\n echo imprime en consola, el \"$\" llama a una variable, \n 'e' es el array, los '{}' hace que echo imprima todo lo que este dentro \n y [*] imprime todo lo que este dentro del array\n'\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/bash/didacdev.sh",
    "content": "#!/bin/bash\n\n# https://www.gnu.org/software/bash/manual/bash.html\n\n# La forma de crear comentarios es con el hashtag\n# Incluso si el comentario es de varias líneas\n\n# Variable y constante\nnombre=\"Diego\"\ndeclare -r lenguaje=\"bash\"\n\n# Tipos\nstring=\"Cadena\"\ninteger=19\nfloat=2.1\nboolean=true\n\necho \"¡Hola $lenguaje!\"\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/bash/drvito1977.sh",
    "content": "#!/bin/bash\n\n# URL del sitio web oficial del lenguaje Bash:\n# https://www.gnu.org/software/bash/\n\n# Comentario de una línea\n\n: '\nComentario\nde varias\nlíneas\n'\n\n# Creación de una variable\nmi_variable=\"Hola, Mundo!\"\n\n# Creación de una constante (en Bash se usa la convención de variables de solo lectura)\nreadonly MI_CONSTANTE=\"Esto es una constante\"\n\n# Variables representando los tipos de datos primitivos en Bash\ncadena_de_texto=\"Esto es una cadena de texto\"\nentero=42\nflotante=3.14\nbooleano_verdadero=true\nbooleano_falso=false\n\n# Imprimir por terminal el texto: \"¡Hola, Bash!\"\necho \"¡Hola, Bash!\"\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/bash/h4ckxel.sh",
    "content": "#!/bin/bash\n\n# URL del sitio web oficial de Bash: https://www.gnu.org/software/bash/\n\n# COMENTARIOS\n\n# Esto es un comentario de una linea.\n\n: '\nEste es un comentario \nde varias lineas\n'\n\n\n# VARIABLES\n\nvariable=0                          # variable\nreadonly constant=\"Mi constante\"    # constante\n\nfunction my_function {\nlocal variable_local=0            # variable local\n}\n\n# TIPOS DE DATOS\n\nvariable=\"String\"                   # String\nvariable=1                          # Int\nvariable=(\"rojo\" \"verde\" \"azul\")    # Array\nvariable=true                       # Boolean\n\ndeclare -A dictionary\ndictionary[valor]='valor1'          # diccionario\n\n# Hola mundo\necho \"Hola, Bash!\"                  # echo sirve para imprimir en la terminal\n\n# Para llamar a una variable se usa el simbolo $[nombre de la variable]\nvariable=\"Hola Bash\"\necho $variable                      \n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/bash/juandaherrera.sh",
    "content": "# Página principal de Bash: https://www.gnu.org/software/bash/\n\n# Comentario de una línea\n\n: '\nComentario\nde varias líneas\n'\n\n# Variables\nmyVariable=\"Juan David\" # Esta es una variable que puede cambiar\nmyVariable=\"Juan David Herrera\"\n\nreadonly MY_CONSTANT=\"API_KEY\" # Esta es una constante que no puede cambiar\n\n# Tipos de datos primitivos en Bash\nmyInt=25 # Número entero\nmyFloat=1.33 # Número con punto flotante (Nota: Bash no diferencia entre int y float)\nmyBool=true # Booleano (Nota: Bash no tiene un tipo de dato booleano nativo)\nmyString=\"Mi cadena de texto\" # Cadena de texto\nmyOtherString='Mi otra cadena de texto' # Otra forma de representar cadenas de texto\nmyLanguage=\"Bash\" # Nombre del lenguaje\n\necho \"¡Hola, $myLanguage!\"\n\n# Bash no tiene una función incorporada para determinar el tipo de una variable.\n# Por lo general, todo se trata como una cadena de texto.\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/bash/neslarra.sh",
    "content": "#!/bin/env bash\n\n# EJERCICIO:\n#  - Crea un comentario en el código y coloca la URL del sitio web oficial del\n#    lenguaje de programación que has seleccionado.\n#  - Representa las diferentes sintaxis que existen de crear comentarios\n#    en el lenguaje (en una línea, varias...).\n#  - Crea una variable (y una constante si el lenguaje lo soporta).\n#  - Crea variables representando todos los tipos de datos primitivos\n#    del lenguaje (cadenas de texto, enteros, booleanos...).\n#  - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n#  ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n#  debemos comenzar por el principio\n\n# Los comentarios en bash se indican con \"#\" al comienzo de línea.\n# NO hay comentarios multilínea => se simulan con líneas consecutivas inicializadas con \"#\".\n\ntypeset -r URL_OFICIAL_BASH=\"https://www.gnu.org/software/bash/\"\necho \"Con \"'${URL_OFICIAL_BASH}'\" muestro el contenido de la CONSTANTE URL_OFICIAL_BASH = ${URL_OFICIAL_BASH}\"\n\ntypeset -i entero=1\necho \"Con \"'${entero}'\" muestro el contenido de la VARIABLE entero = ${entero}\"\n\ncadena=\"bash\"\necho \"Con \"'${cadena}'\" muestro el contenido de la VARIABLE cadena = ${cadena}\"\n\necho 'bash NO tiene variable booleanas => se debe operar con \"test expr\" y ver si retorna ($?) 0 True o 1 False'\necho \"test \"'${entero}'\" == 1; echo \"'$?'\" <= devuelve 0 = True\" \necho \"test \"'${entero}'\" == 2; echo \"'$?'\" <= devuelve 1 = False\"\n\necho \"bash no tiene aritmética de punto flotante => se debe usar una función y asignar a una variable de cadena.\"\necho \"flotante=\"'$(bc -l <<< 10/3)'\"; echo \"'${flotante} <= devuelve 3.3333333333333' \n\necho \"Hola ${cadena}\"\necho \"Aprende BASH en la web oficial: ${URL_OFICIAL_BASH}\"\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/bash/rantamhack.sh",
    "content": "#!/bin/bash\n\n# La pagina oficial de bash es https://gnu.org/software/bash\n\n# Para comentar una sola línea se usa el símbolo  \"#\"\n# Bash ignora todas las líneas que comiencen con este símbolo excepto la primera línea que define el script y se llama shebang\n\n\n<< 'Comment' \n    El heredoc se usa para pasar entradas multilíneas a un\n    comando. Se puede aprovechar para hacer un comentario\n    multilinea al no pasarselo a ningún comando aunque no\n    es lo mas apropiado. De hechos Visual Code lo adminte pero\n    lo señala como error\nComment\n\n\n\n\n# Constante\ndeclare -r CONSTANTE=100\n\n# También se puede expresar así:\ndeclare --readonly CONSTANTE2=99\n\n\n# Variables\n\n# Entera (Int)\nentera=5\n\n# Decimal (float)\ndecimal=3,14\n\n# String (str)\nstring=\"mi cadena de texo\"\n\n# Booleana (bool)\nbooleana=True\n\n# Saludo al lenguaje que quiero aprender\nLenguaje=\"Bash\"\n\necho $CONSTANTE\necho $CONSTANTE2\necho $entera\necho $decimal\necho $string\necho $booleana\necho \"Hola, $Lenguaje!!\"\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/bash/santyjL.sh",
    "content": "#!/bin/bash\n\n: \"\n/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\"\n\n# La pagina oficial de bash es https://gnu.org/software/bash\n\n# Para comentar una sola línea se usa el símbolo  \"#\"\n# Bash ignora todas las líneas que comiencen con este símbolo excepto la primera línea que define el script y se llama shebang\n\n: \"\nPara comentar varias líneas\nse puede usar el símbolo de dos\npuntos seguido de comillas dobles\n\"\n\n# Constante\ndeclare -r PI=3.14159\n\n# Variable\nlenguaje=\"Bash\"\n\n# Tipos de datos primitivos\n\nstring=\"Hola mundo\"\ninteger=73\nboolean=true    #no existe un tipo booleano nativo\nfloat=1.6180339887\n\n# Imprimir por terminal\n\necho \"$string, esto de aqui es $lenguaje\"\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/bash/x3mboy.sh",
    "content": "#!/bin/bash\n\n: '\nPágina oficial de Bash: https://www.gnu.org/software/bash/\n'\n\n# Los comentarios de una línea se hacen con el signo gato (numeral o hash)\n\n: '\nSe colocan con el comando \":\", un espacio y comilla simple para abrir,\nLuego se coloca una comilla de cierre para terminar el comentario\n'\n\n<<Document\nOtra manera de tener comentarios multilínea es con lo que se denominan\nHereDocuments, que básicamente son una manera de decirle a bash que lo que está\nentre el comienzo del documento, que se declara con \"<<\" y un nombre, y el cierre,\nque se declara con el nombre del documento solo en una línea, se procesa como una\nsola unidad\nDocument\n\nreadonly constante=\"x3mboy\" #Y los comentarios dentro de línea se hacen igual con el signo gato\n\nnombre=$constante\ncadena=\"Hola\"\nentero=1\nflotante=1.1\nbooleano=true\n\necho $cadena\" \"$nombre\necho \"Numero entero: \"$entero\necho \"Numero real: \"$flotante\necho \"Variable booleana: \"$booleano\n\necho \"Hola Bash!\"\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c/04khaos.c",
    "content": "// Página: https://en.cppreference.com/w/c\n\n// Comentario en una línea.\n\n/*\n   Comentario de varias líneas.\n   Aquí puedes añadir información... \n   :p\n*/\n\n#include <stdio.h>\n#include <stdbool.h>             // Para usar booleanos en C\n\n// Constante con '#define'\n#define PI 3.14159             \n\n// Constante con 'const'  \nconst int MAX_USERS = 100;       \n\nfloat radio = PI;                // Variable global usando '#define'\n\nint main(void)\n{\n    int usuarios_actuales = MAX_USERS - 10;    // Variable local usando 'const'\n\n    // Datatypes (Sistemas de 32 y 64 bits)\n    char a = 'C';                              // 1 byte  | Range: -128 a 127 (modern systems)\n    short b = -15;                             // 2 bytes | Range: -32,768 a 32,767\n    int c = 1024;                              // 4 bytes | Range: -2,147,483,648 a 2,147,483,647\n    unsigned int d = 128;                      // 4 bytes | Range: 0 a 4,294,967,295\n    long e = 123456;                           // 4 bytes (32-bit) / 8 bytes (64-bit)\n    float f = 15.678;                          // 4 bytes | ~6-7 dígitos de precisión\n    double g = 123123.123123;                  // 8 bytes | ~15-16 dígitos de precisión\n    bool h = true;                             // 1 byte  | Values: true (1) o false (0)\n\n    printf(\"¡Hola, %c!\\n\", a);  // Imprime \"¡Hola, C!\" usando el valor de la variable 'a' (char)\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c/1ceL4nc3.c",
    "content": "https://www.cprogramming.com\n\nTypes of comments\n// // = // comment // \n/* */ = /* comment */\n\n// constant value = const + type of variable + name of variable //\nconst int n = 5;\n\n//Data types //\nchar character = 'a';                            // Single character, 1 byte //\nint integer = 9;                                 // Signed integer in base 10, 4 bytes//\nfloat decimal = 1.5;                             // Floating point number with six digits of precision, 4 bytes //\ndouble decimalDouble = -2456.4452;               // Hold about 15 to 16 digits after and before any given decimal point, 8 bytes //\nlong longinteger = 132344546L;                   // Signed long integer, 4 bytes //\nshort shortinteger = 128;                        // Short signed integer, 2 bytes //\nunsigned unsignedinteger = 50;                   // Unsigned integer in base 10, 4 bytes //\nunsigned long unsignedlonginteger = 451345245UL; // Unsigned long long integer, 8 bytes // \nunsigned short unsignedshortinteger = 256;       // Short unsigned integer, 2 bytes //\n\n#include <stdio.h>                 // header function\n\nint main()                         // main function\n{                                  // indicates the beginning and end of functions and other code blocks // \n    char l_name = 'C';             // create a variable named l_name and assign it the character C //\n\n    printf(\"!Hola %c!\\n\", l_name); // print the string !Hola + variable l_name// // %c indicates that the funtion is printing a character// // \\n print another line//\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c/Aldroide.c",
    "content": "// Este es un comentario de una linea\n\n/*\nEste es un\ncomentario\nen varias\nlineas\n*/\n\n#include <stdio.h>\n\n\nint main(){\n    // variable\n    int a = 7;\n\n    //constante\n    const int e= 9;\n    \n    //tipos de datos primitivos\n    char letter = 'a';\n    int entero = 9;\n    float decimal = 1.5;\n    double decimalDoble = -2456.4452;\n    long enterolargo = 123344546L;\n    short enterocorto= 128;\n    unsigned enteroSinSigno = 10;\n    unsigned long enteroSinSignoLargo = 451345245UL;\n    unsigned short enteroSinSignoCorto = 256;\n\n    //impresion por consola\n    char lenguaje = 'C';\n    printf(\"Hola, %c!\\n\", lenguaje);\n    return 0;\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c/Angel-Delg.c",
    "content": "#include <stdio.h>\n#include <stdbool.h>\n\n// Constante Simbolica o Directriz\n#define CONSTANTE 2024\n\n// Puedes encontrar mas información a traves de estos enlaces\n// URL = https://www.w3schools.com/c/index.php\n/*\n   Comentario de varias lineas.\n   URL = https://www.w3schools.com/c/index.php\n*/\n\nint main(void){\n   int Variable = 2024;\n   const int CurrentYear = 2024;\n\n   // Tipos de datos\n   char String[10] = \"String\";\n   char Caracter = 'A';\n   int Entero = 2024;\n   double FlotanteDeMayorPresicion = 20.24;\n   \n   // Mensaje por consola.\n   printf(\"Hola Lenguaje C.\");\n\n   return 0;\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c/Angelo-Eyama.c",
    "content": "//Documentacion de C: https://devdocs.io/c/\n\n//Comentario de una linea\n\n/*\n    Comentario\n    de\n    varias\n    lineas\n*/\n\n//Librerias (necesarias para todo)\n#include<stdio.h>;\n#include<stdlib.h>;\n#include<stdbool.h>\n\n#define CONSTANTE 8\n\nint numero = 10;\nchar caracter = 'a';\nfloat decimal = 1.3;\n\nint main(){\n    printf(\"Hola, C\");\n    return 0;\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c/Arathhh8.c",
    "content": "/*\n * EJERCICIO:\n * 1 Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * 2 Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * 3 Crea una variable (y una constante si el lenguaje lo soporta).\n * 4 Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * 5 Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n\n    /* *************** 1 ************* */\n/* No existe un sitio web oficial para C, pero agrego una referencia del manual GNU\n * https://www.gnu.org/software/gnu-c-manual/gnu-c-manual.html  \n*/\n\n#include<stdio.h>\n\nint main(int argc, char **argv){\n\n    /* *************** 2 ************* */\n\n    // Este es un comentario en una sola línea\n    /* Este tambien es un comentario de una sola linea */\n\n    /*\n        Este es un comentario\n        de varias lineas\n    */\n   /* *************** 3 ************* */\n\n   int num = 5;                  /* Esta es una variable*/\n   const int pi = 3.1416;        /* Esta es una constante*/\n   #define PI 3.1416;            // Tambien puedes crear constantes de esta forma\n\n\n    /* *************** 4 ************* */\n    int numEntero;\n    char caracter;\n    short numCorto;\n    float numFlotante;\n    double numDouble;\n    // En el C el tipo \"Booleano no esta definido de manera nativa\"\n    \n    /* *************** 5 ************* */\n    printf(\"Hola C!\");\n\n    return 0;\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c/Bert008.c",
    "content": "/*\nhttps://www.open-std.org/jtc1/sc22/wg14/\n*/\n/* Comentario 1*/\n// comentario 2\n\n#include <stdio.h>\n\nint main() {\n    int x = 10;\n    int y = 2;\n    const int z = 5;\n    float g = 9.81;\n    double pi = 3.1416;\n    char letra = 'c';\n\n    print(\"Hola C\\n\");\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c/Carlitoindev.c",
    "content": "// comentario en una sola linea\n\n/*\ncomentario en varias lineas\n*/\n\n// Este lenguaje no tiene un sitio oficial, sino que funciona a travez de Manuales \n// Una referancia puede muy buena puede ser https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf  \n\n#include <stdio.h>\n\nint variable = 32;  // variable definida\n#define cantidad = 100; // constante(es mucho mas rapida a la hora de ejecutarse que otras como <const>) \n\n// tipos de variables\n\nint numero = 12; //  numero entero\nlong numero2; // numero entero pero mas largo que el admitido por <int>\nchar letra = 'r'; // un caracter independirnte o parte de una cadena\nfloat dinero = 3.05; // numeros reales hasta 6 decimales.\ndouble cuenta_bancaria = 123131312312312312312.312312312312312; // reales hasta 14 decimales.   \n\nint main(void){\n    printf(\"Hola C\\n\");\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c/Clotrack.c",
    "content": "// #00 Sintaxis, variables, tipos de datos y hola mundo\n// Autor: Clotrack | Lenguaje: C | Publucacion: 26/12/2023 | Correccion: 21/07/2024\n\n#include <stdio.h>\n#include <stdbool.h>\n\n/* Ejercicio 1: Crea un comentario en el código y coloca la URL del sitio web oficial del\n    lenguaje de programación que has seleccionado. */\n\n// No hay web oficial del lenguaje C pero aqui se puede encontrar mucha informacion\n// sobre el lenguaje: |  https://www.w3schools.com/c/index.php  |  \n\n/* Ejercicio 2: Representa las diferentes sintaxis que existen de crear comentarios\n   en el lenguaje (en una línea, varias...) */\n\n// Esto es un comentario de linea\n\n/* Esta es otra forma de hacer comentario, todo lo que escribamos dentro de estos simbolos \n    es un comentaro sin importar las lineas utilizadas */\n\nint main() {\n\n    /* Ejecicio 3: Crea una variable (y una constante si el lenguaje lo soporta). */\n\n    char caracter = 'C';\n    const int diasEnero = 31;\n\n    /* Ejercicio 4: Crea variables representando todos los tipos de datos primitivos\n    del lenguaje (cadenas de texto, enteros, booleanos...). */\n\n    int numEntero = 3;\n    short numcorto = -58;\n    float numFlotante = 3.5;\n    double numDoble = 35.55;\n    char unCaracter = 'L';\n    const int diasMarzo = 31;\n    bool clotrackEstado = true;\n\n    /* Ejercicio 5: Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"  */\n\n    printf(\"Maquina puedes escribir 0 si Clotrack esta cuerdo y 1 si esta loco: %d\\n\", clotrackEstado);\n    printf(\"¡Hola C bienvenido al mundo!\");\n    \n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c/DjSurgeon.c",
    "content": "/*\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n\n// Comentarios\n\n// Comentarios de una línea.\n\n/* \n* Comentarios de varias líneas.\n* Esto es otra línea de comentario.\n*/\n\n/*\n* He encontrado varias webs donde se habla de c y su estructura, pero no hay una página oficial de documentación en si o por lo menos yo no la he encontrado.\n* https://learn.microsoft.com/es-es/cpp/c-language/organization-of-the-c-language-reference?view=msvc-170 - Página web de Microsoft.\n* https://devdocs.io/c/ - Documentación de varios lenguajes de programación entre ellos c.\n* https://www.gnu.org/software/gnu-c-manual/gnu-c-manual.html - Otra documentación.\n*/\n\n#include <stdio.h>\n\nint main() {\n\n// Variables y constantes. Datos Primitivos\n\n// Enteros: Los enteros representan números sin parte decimal. Se utilizan para almacenar valores numéricos enteros, positivos o negativos.\n\nint numeroPositivo = 5;\nint numeroNegativo = -65;\n\nprintf(\"Impresión de valores enteros positivos: %i y enteros negativos: %i\\n\", numeroPositivo, numeroNegativo);\n\n// Coma flotante: Son los números que poseen una parte decimal, los hay de dos tipos float y double, float es menos preciso que double, y se double se deberia utilizar para operaciones matemáticas que necesiten mayor precisión.\n\nfloat decimalPositivo = 15.1548;\ndouble decimalMasPreciso = 65.14785421658;\n\nprintf(\"Impresión de valores de coma flotante float: %f y double %.15lf\\n\", decimalPositivo, decimalMasPreciso);\n\n// Caracteres: Son tipos de datos que representan símbolos individuales, como letras, números o otros caracteres especiales.\n\nchar caracterLetra = 'A';\nchar caracterNumero = '9';\n\nprintf(\"Impresión de valores carácter o char, por ejemplo letras: %c, o números: %c\\n\", caracterLetra, caracterNumero);\n\n// Constantes: Son valores que no cambian durante la ejecución del programa.\n\n#define PI 3.14159\n\nconst int DIAS_SEMANA = 7;\n\nprintf(\"Constantes preprocesadas: %.5f y constantes declaradas: %i.\\n\", PI, DIAS_SEMANA);\n\n// Para imprimir en consola se utiliza printf(\"\")\n\nconst char LENGUAJE = 'C';\n\nprintf(\"Hola, %c!!!\\n\", LENGUAJE);\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c/FullOvellas.c",
    "content": "/*\n * Documentación y estándar de C\n * +-----------------------------------------------------------------------------------------------------------------------+\n * |https://devdocs.io/c/                                                                                                  |\n * |https://web.archive.org/web/20180118051003/http://www.open-std.org/jtc1/sc22/wg14/www/abq/c17_updated_proposed_fdis.pdf|\n * +-----------------------------------------------------------------------------------------------------------------------+\n */\n\n#include <stdbool.h>\n#include <stddef.h>\n#include <stdint.h>\n#include <stdio.h>\n\n// Comentario monolínea\n\n/*\n * Comentario\n * multilínea\n */\n\n// Constante definida con una macro object-like\n#define MEANING_OF_LIFE 42\n\nint main() {\n    // Constante definida con la palabra reservada `const`\n    const double PI = 3.14159265;\n\n    // Variable\n    int one = 1;\n\n    // Tipos primitivos\n    // Los valores máximos y mínimos se define en el header `limits.h` y `float.h`\n    char c = 'a';\n    unsigned char uc = 255;\n    signed char sc = 127;\n    short s = 32767;\n    unsigned short us = 65535;\n    int i = 32767;\n    unsigned int ui = 65535;\n    long l = 2147483647l;\n    unsigned long ul = 4294967295ul;\n    long long ll = 9223372036854775807ll;\n    unsigned long long ull = 18446744073709551615ull;\n    float f = 1.1f;\n    double d = 1.1;\n    long double ld = 1.1l;\n    // Necesario incluír el header `stdbool.h` para tener acceso a las macros `true` y `false`.\n    // El tipo `_Bool` nos ayuda a prevenir errores de overflow\n    _Bool b = true;\n    // Entero sin signo definido en el header `stddef.h`, su tamaño depende de la plataforma\n    size_t arch = 0;\n    // Entero con signo definido en el header `stddef.h`, representa la diferencia entre punteros del mismo tipo\n    ptrdiff_t pd = 0;\n\n\n    // Enteros fixed-width\n    // Longitud exacta:\n    int8_t i8 = INT8_MAX;\n    int16_t i16 = INT16_MAX;\n    int32_t i32 = INT32_MAX;\n    uint8_t u8 = UINT8_MAX;\n    uint16_t u16 = UINT16_MAX;\n    uint32_t u32 = UINT32_MAX;\n    uint64_t u64 = UINT64_MAX;\n\n    // Longitud mínima\n    int_least8_t il8 = 0;\n    uint_least8_t uil8 = 0;\n    // etc...\n\n    // Más rápido\n    int_fast8_t if8 = 0;\n    uint_fast8_t uif8 = 0;\n    // etc...\n\n    // Puntero\n    intptr_t ip = INTPTR_MAX;\n\n    // Longitud máxima\n    intmax_t im = INTMAX_MAX;\n    uintmax_t uim = UINTMAX_MAX;\n\n    // C no tiene un tipo string básico\n    const char msg[] = \"¡Hola, C!\";\n\n    puts(msg);\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c/Gallitofast.c",
    "content": "// C no tiene una pagina principal del sitio web, pero existe un libro llamado the language of c muy util\n//Elegi el lenguaje de programacion c \n#include <stdio.h>\n#include <stdlib.h>\n#include <stdbool.h>\n#include <string.h>\nint main(){\n// Este es un comentario de una sola línea\n\n/*\nEste es un comentario\nde múltiples líneas\n*/\n\n/**\n * Este es un comentario de documentación\n * que puede ser utilizado por herramientas como Doxygen.\n */\n\n// Declaración de variables de tipos de datos primitivos\nint entero = 10;                // Entero\nfloat flotante = 3.14;          // Número de punto flotante\ndouble doble = 3.14159265359;   // Número de punto flotante de doble precisión\nchar caracter = 'A';            // Carácter\nbool booleano = true;           // Booleano (requiere <stdbool.h>)\n\n// Declaración de cadenas de caracteres\nchar cadena[] = \"Hola, mundo\";  // Cadena de caracteres\n\n// Imprimir un mensaje en la terminal\nprintf(\"¡Hola, C!\\n\");\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c/JustOrlo.c",
    "content": "\r\n#include <stdio.h>\r\n#include <stdbool.h> //Para trabajar con booleanos\r\n\r\n#define EULER 2.71828 //Declarando Constante con el método #define\r\n    const int No_Id = 15; //Constante con el método const\r\n\r\nint main(){\r\n    //    https://en.cppreference.com/w/c\r\n\r\n    /* Commentario de Multiples lienas \r\n    \r\n        https://en.cppreference.com/w/c\r\n\r\n    */\r\n\r\n\r\n    char caracter = 'C'; // -128 a 127\r\n    short edad = 24; // -32,768 a 32,767\r\n    int año = 2025; //-2,147,483,648 a 2,147,483,647\r\n    unsigned int año_anterior = 2024; //0 a 4,294,967,295\r\n    long numero = 12313484; //4 bytes (32-bit) / 8 bytes (64-bit)\r\n    float numero_f = 2.15468; //~6-7 dígitos de precisión\r\n    double numero_d = 24.3568186; //~15-16 dígitos de precisión\r\n    bool numero_b = false; // true = 1 y false = 0\r\n\r\n    printf(\"¡Hola, %c!\\n\", caracter); //Se imprime el mensaje Hola C, haciendo uso de la varia caracter de tipo char\r\n    \r\n    return 0;\r\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c/N0HagoNada.c",
    "content": "#include <stdio.h>\n#include <stdbool.h>\n#include <stdint.h> // Para tipos de tamaño fijo\n\n// Una pagina oficial podria ser https://www.learn-c.org/\n/*\nComentarios en varias lienas\nhttps://www.gnu.org/software/gnu-c-manual/gnu-c-manual.html\n*/\n\nint main()\n{\n    // Creación de una variable\n    int ejemploVariable = 10;\n\n    // Creación de una constante\n    const float PI = 3.1416;\n\n    // Variables representando todos los tipos de datos primitivos\n    char unCaracter = 'A'; // Carácter\n    int unEntero = 123;    // Número entero\n    unsigned int enteroSinSigno = 20;\n    short corto = 10;                                         // Entero corto\n    unsigned short cortoSinSigno = 20;                        // Entero corto sin signo\n    long largo = 123456789;                                   // Entero largo\n    unsigned long largoSinSigno = 987654321;                  // Entero largo sin signo\n    long long largoLargo = 123456789101112;                   // Entero largo largo\n    unsigned long long largoLargoSinSigno = 1098765432112345; //\n    long long int entero64 = 1234567890123456789;\n    float unFlotante = 123.456;                        // Número flotante\n    double unDoble = 123.456789;                       // Número de doble precisión\n    long double dobleLargo = 3.14159265358979323846L;  // Número de doble precisión largo\n    uint64_t entero64SinSigno = 18446744073709551615U; // Entero sin signo de 64 bits\n    bool unBooleano = true;                            // Booleano (requiere #include <stdbool.h>)\n    char *unaCadena = \"Esto es una cadena de texto\";   // Cadena de texto\n\n    // Imprime por terminal el texto solicitado\n    printf(\"¡Hola, C!\\n\");\n\n    // Imprime los valores de las variables (opcional, para demostración)\n    printf(\"Variable int: %d\\n\", ejemploVariable);\n    printf(\"Constante float: %f\\n\", PI);\n    printf(\"Entero sin signo: %u\\n\", enteroSinSigno);\n    printf(\"Corto: %hd\\n\", corto);\n    printf(\"Corto sin signo: %hu\\n\", cortoSinSigno);\n    printf(\"Largo: %ld\\n\", largo);\n    printf(\"Largo sin signo: %lu\\n\", largoSinSigno);\n    printf(\"Largo largo: %lld\\n\", largoLargo);\n    printf(\"Largo largo sin signo: %llu\\n\", largoLargoSinSigno);\n    printf(\"char: %c\\n\", unCaracter);\n    printf(\"int: %d\\n\", unEntero);\n    printf(\"float: %f\\n\", unFlotante);\n    printf(\"double: %lf\\n\", unDoble);\n    printf(\"Doble largo: %Lf\\n\", dobleLargo);\n    printf(\"Entero 64 bits: %ld\\n\", entero64);\n    printf(\"Entero 64 bits sin signo: %lu\\n\", entero64SinSigno);\n    printf(\"bool: %d\\n\", unBooleano); // En C, los booleanos se imprimen como enteros (0 para false, 1 para true)\n    printf(\"char*: %s\\n\", unaCadena);\n\n    return 0;\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c/OmarRoman29.c",
    "content": "/* C17 gratuito con wayback machine:\n   https://web.archive.org/web/20180118051003/http://www.open-std.org/jtc1/sc22/wg14/www/abq/c17_updated_proposed_fdis.pdf\n*/\n\n// Comentario de una linea\n\n// Para las constantes máximas de cada dato\n#include <limits.h>\n// Libreria estandar para leer y escribir\n#include <stdio.h>\n\n// Un tipo de constante\n#define PI 3.1416\n\nint main() {\n  // Otro tipo de constante de tipo caracter\n  const char character = 'C';\n\n  // VARIABLES EN SISTEMAS DE 64 BITS\n\n  // Enteros y caracteres\n  /* Puedes referenciarlo por caracter como 'A'\n   *  o por su número correspondiente en ASCII,\n   *  un char tiene 8 bits, por lo que sus\n   *  valores posibles son desde\n   *  -2^7 a (2^7)-1\n   */\n  char character2 = CHAR_MAX;\n  printf(\"char: %c\\n\", character);   // Imprimir como texto\n  printf(\"char: %hhd\\n\", character); // Imprimir como num\n\n  /* 16 bits: de -2^15 a (2^15)-1\n   * Se puede declarar como:\n   * short int shortInteger = SHRT_MIN;\n   * Pero abreviado es: */\n  short shortInteger = SHRT_MIN;\n  printf(\"short: %hd\\n\", shortInteger);\n\n  // 32 bits: de -2^31 a (2^31)-1\n  int integer = INT_MAX;\n  printf(\"int: %d\\n\", integer);\n\n  /* 64 bits: de -2^63 a (2^63)-1\n   * Se puede declarar como:\n   * long int longInteger = LONG_MIN;\n   * Pero abreviado es: */\n  long longInteger = LONG_MAX;\n  printf(\"long: %ld\\n\", longInteger);\n\n  // En sistemas de 32 bits se declaraban enteros de 64 bits se hacia con\n  long long llinteger;\n  printf(\"C rellenará las variables si no lo definimos nosotros\");\n  printf(\"No siempre tendrá el valor que queremos\");\n  printf(\"long long: %lld\\n\", llinteger);\n\n  //ENTEROS SIN SIGNO\n\n  /* Tenemos enteros que pueden tener signo positivo o negativo\n   * por lo que el ultimo bit de nuestra variable se usa para\n   * determinar si es positivo o negativo. Pero si no requerimos\n   * datos negativos podemos usar todos los bits para representar\n   * numeros. Para esto usamos la palabra reservada signed y \n   * unsigned, por defecto todos los tipos son signed\n   *\n   * int var == signed int  var*/\n  unsigned short uShortInteger = USHRT_MAX;\n  printf(\"ushort: %hu\\n\", uShortInteger);\n\n  unsigned long uLongInteger = ULONG_MAX;\n  printf(\"ushort: %lu\\n\", uLongInteger);\n\n  // VARIABLES DE COMA FLOTANTE\n  // Tiene 32 bits, pero el valor que contienen se calcula de forma más compleja\n  float floatData = 2.0;\n  printf(\"float: %f\\n\", floatData);\n  printf(\"float limitando decimales impresos: %.2f\\n\", floatData);\n\n  // Posee 64 bits\n  double doubleData = 3.0;\n  printf(\"float: %lf\\n\", doubleData);\n\n  printf(\"Hola %c\\n\", character);\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c/Ossytosis.c",
    "content": "// learn-c.org\n\n// comentario en una lines\n/*comentario\nen doble lineo*/\n\nMy_variable = Nicolas //Nombre de la variable\n\n//Sintaxis de constante.\nconst = 18 \ndefine = sexo\n\n//Datos primitivos\nint edad = 17 \n/*Representa números enteros (sin decimales).\nTamaño: Usualmente 4 bytes (dependiendo del sistema).\nRango: Depende del sistema, pero en sistemas comunes es entre -2,147,483,648 y 2,147,483,647.*/\nfloat peso = 48.7\n/*Representa números con decimales, pero con una precisión limitada.\nTamaño: Usualmente 4 bytes.\nRango: Aproximadamente -3.4E38 a 3.4E38.*/\ndouble temperatura = 2474758.3333444\n/*double - Número de punto flotante de doble precisión\nSimilar al float, pero con mayor precisión y mayor rango.\nTamaño: Usualmente 8 bytes.\nRango: Aproximadamente -1.7E308 a 1.7E308.*/\nchar = $\nshort = -1\nlong = 0.7838747L\nlong long\nunsigned //char/int\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c/Paluzz.c",
    "content": "/*\n * EJERCICIO:\n * 1 Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * 2 Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * 3 Crea una variable (y una constante si el lenguaje lo soporta).\n * 4 Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * 5 Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n// documentacion oficial: https://devdocs.io/c/\n\n// Comentario de una linea\n\n/*\n    Comentario en\n    varias lineas\n*/\n\n// header con algunas funcionalidades basicas\n#include <stdio.h>\n#include <stdlib.h> // contiene NULL y memoria dinamica\n#include <string.h> // contiene funciones de string\n\n// Hay varias formas de crear constante:\n// Forma 1: #define\n\n#define CONSTANTE ((int)5)\n\n// Forma 2: enum\nenum COLOR\n{\n    red,\n    blue,\n    grey,\n    yellow\n};\n/*\n    Cada constante perteneciente a COLOR empieza por orden numerico\n    ejemplo: red = 0; blue = 1;\n    Tambien se puede poner algun valor y los siguientes incrementan 1 en 1\n*/\n// ej2:\nenum DIAS_SEMANA\n{\n    lunes = 1,\n    martes,\n    miercoles,\n    jueves,\n    viernes\n    //   Aqui lunes = 1; martes = 2; ...\n\n};\n\nint main()\n{\n    // forma 3: palabra reservada 'const'\n    const int numero = 3;\n\n    // VARIABLES:\n\n    // enteras:\n    int num = 5;\n    unsigned int bit = 1;\n\n    long grande = 46648987;\n\n    // punto flotante:\n    float radio = 1.5;\n    double promedio;\n\n    // vectores:\n    int vector[5] = {1, 2, 4, 6, 7}; // vector tipo int\n\n    // punteros\n    int *p;\n    p = &vector[0];\n\n    // caracter:\n    char c;\n    c = 'a';\n\n    // strings:\n    // forma 1: memoria estatica\n    char str[10] = \"hola mundo\";\n\n    // forma 2: punteros y/o memoria dinamica\n    char *pString;\n    pString = (char *)malloc(sizeof(char) * 5); // complejo no?\n    // le ingresamos un texto al string\n    strcpy(pString, \"hola\");\n\n    // imprimimos en terminal\n\n    printf(\"Hola, lenguaje C\\n\");\n    printf(\"imprimimos entero: %d\\n\", num);\n    printf(\"imprimimos long: %ld\\n\", grande);\n    printf(\"imprimimos vector enteros: \");\n    for (int i = 0; i < 5; i++)\n    {\n        printf(\"%d \", vector[i]);\n    }\n    printf(\"\\n\");\n    printf(\"imprimimos puntero a entero: \");\n    for (int i = 0; i < 5; i++)\n    {\n        printf(\"%d \", *(p + i));\n    }\n    printf(\"\\n\");\n\n    printf(\"imprimimos flotante: %f\\n\", radio);\n    printf(\"imprimimos caracter: %c\\n\", c);\n    printf(\"imprimimos string1: %s\\n\", str);\n    printf(\"imprimimos string2: %s\\n\", pString);\n\n    // liberamos memoria del puntero a string (recomendable)\n    free(pString);\n\n    return 0;\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c/SoMaxB.c",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n#include <stdio.h>\n\nint\tmain(void){\n\n// No existe página oficial.\n\n/* I choose\n * you\n * dear C.\n */\n\n// variable\nint number;\n\n// constante\nconst int number_two;\n#define PI 3.141592\n\n/* Datos primitivos:\n- Tipos enteros: char, short, int, long, long long y enum\n- Tipos reales: float, double, y long double. */\n\nshort\t\tmy_short_var;\nint\t\t\tmy_int_var;\nchar \t\tmy_char_var;\nfloat \t\tmy_float_var;\nlong\t\tmy_long_var;\nlong long\tmy_long_long_var;\nenum\t\tmy_enum_var;\ndouble\t\tmy_double_var;\nlong double\tmy_long_double_var;\n\nprintf(\"!Hola, C!\\n\");\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c/SrVariable.c",
    "content": "/*\n * EJERCICIO:\n * 1 Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * 2 Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * 3 Crea una variable (y una constante si el lenguaje lo soporta).\n * 4 Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * 5 Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n#include <stdio.h>\n#include <stdbool.h>\n\nint    main(int argc, char **argv)\n{\n    /* ==== 1 ==== */\n    // En C no existe sitio web oficial, asi que muestro\n    // el manual de GNU\n    // https://www.gnu.org/software/gnu-c-manual/gnu-c-manual.html\n\n    /* ==== 2 ==== */\n\n    // Esto es un comentario en línea.\n    /* Esto también es un comentario en línea. */\n    /*\n     * Esto es un comentario\n     * en\n     * varias líneas.\n     */\n\n    // NOTA: En los comentarios de varias líneas no es necesario\n    // poner asterisco al principio, solo en el último para poder\n    // cerrar el comentario (*/).\n\n    /* ==== 3 ==== */\n    const char\tx; // Utilizando const se evita que el valor cambie.\n\n    /* ==== 4 ==== */\n    char                    lang = 'C'; // Este es el generalmente utilizado\n    unsigned char           uchar;\n    int                     number; // Este es el generalmente utilizado\n    unsigned int            unumber;\n    short int               snumber;\n    unsigned short int      usnumber;\n    long int                lint;\n    unsigned long int       ulint;\n    long long int           llint;\n    unsigned long long int  ullint;\n    float                   position = 1259.32f; // Este es el generalmente utilizado\n    double                  sqrt2 = 1.41421356237; // Este es el generalmente utilizado\n    long double             pi = 3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342L;\n\n    /* Bonus */\n    // En C no existe el tipo Strings. Para tener algo similar\n    // están los arrays de caracteres, con la característica de que\n    // terminan con el carácter nulo.\n    char                    hellostring[] = \"Hola\"; // Esto sería un array de 5 caracteres. {'H', 'o', 'l', 'a', '\\0'}\n\n    // Tampoco existe el tipo Bool (o Boolean) por defecto. Para el\n    // equivalente se suele utilizar un int con el valor 0 para\n    // representar el 'False' y cualquier otro valor para 'True'.\n    int                     nonprimitivebooltrue = -1;\n    int                     nonprimitivebooltrue2 = 1;\n    int                     nonprimitiveboolfalse = 0;\n    \n    // También puedes incluir la librería stdbool.h que incluye\n    // el tipo de dato bool.\n    bool                    abool = true;\n    bool                    abool2 = false;\n\n    /* ==== 5 ==== */\n    printf(\"¡%s, %c!\\n\", hellostring, lang); // Imprime por pantalla \"¡Hola, C!\" seguido de un salto de línea.\n    // NOTA: Para utilizar esta función necesitas incluir la librería\n    // stdio.h\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c/abelsrzz.c",
    "content": "#include <stdio.h>\n#include <stdbool.h>\n\n// No existe página oficial, por lo que adjunto la wikipedia\n// https://es.wikipedia.org/wiki/C_(lenguaje_de_programaci%C3%B3n)\n\n//Esto es un comentario de una sola línea\n\n/*\nEsto es un comentario multilínea.\n*/\n\nconst char GLOBAL[] =  \"Constante global\";\nint VARIABLE = 10;\n\nint ENTERO = 10000;\nshort ENTERO_CORTO = 5;\nlong ENTERO_LARGO = 1010010101;\nlong long ENTERO_MUY_LARGO = 999999999999999;\nfloat DECIMAL = 10.54;\ndouble DECIMAL_PRECISO = 10.44553434234;\nlong double DECIMAL_MUY_PRECISO = 43.3421342342341234141234;\nchar CARACTER = 1;\nsigned char CARACTER_FIRMADO = 1;\nunsigned char CARACTER_SIN_SIGNO = 1;\nbool BOOLEANO = true;\n\nint main() {\n    \n    const char LOCAL[] = \"Constante local\";\n\n    printf(\"Esto es una constante global: %s\\n\", GLOBAL);\n    printf(\"Esto es una constante local: %s\\n\", LOCAL);\n    printf(\"Esto es una variable de tipo int: %d\\n\", VARIABLE);\n\n    printf(\"Hola mundo!\");\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c/aggranadoss.c",
    "content": "/*\n  Reto #00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n  mouredev\n  \n  ANGEL GRANADOS ALIAS aggranadoss\n */\n\n\n/*\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n */\n\n#include<stdio.h>\n#include<stdbool.h>\n\nint main(int argc, char argv[argc + 1]){\n\n/********************************************/\n\n/*Sitio oficial del lenguaje C  https://www.iso-9899.info/wiki/The_Standard*/\n\n\n/********************************************/\n\n\n// Comentario en una sóla línea\n\n\n/********************************************/\n\n\n/********************************************/\n\n/*\n\n  Comentario en varias líneas\n\n*/\n\n\n/********************************************/\n\n\n/**\n * Comentario Doxygen se utiliza para generar documentacion\n * automaticamente a partir del codigo fuente. \n\n */\n\n/********************************************/\n\nconst int exit_success = 0;\n\nfloat variable = 10.5; // variable\nconst int constante = 3.141592; // constante\n\n/********************************************/\n\n// Entero\nint numero = 10;\nshort int numero_corto = 10;\nlong int numero_largo = 100000;\nlong long numero_muy_largo = 10000000000;\n\n\n// Flotantes\nfloat flotante = 3.141592;\ndouble doble = 1.4142;\nlong double doble_largo = 3.423482349283479283;\n\n// Flotantes con Complejos\nfloat _Complex complejo_float = 1.0 + 2.0i;\ndouble _Complex complejo_doble = 1.0 + 2.0i;\nlong double _Complex complejo_largo_doble = 1.0 + 2.0i;\n\n\n// Caracteres\n\nchar caracteres = 'A';\nunsigned char caracter_sin_signo = 'B';\n\n\n// Booleano\n\nbool boleano = true;\nbool boleano_2 = false;\n\n// Imprimir Hola y el nombre del lenguaje de programación\n\nprintf(\"\\n Hola, Lenguaje C \\n\\n\");\n\nreturn exit_success;\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c/agusrosero.c",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n#include <stdio.h>\n#include <stdbool.h>\n\n// Primera forma de crear constante\n#define CONSTANTE 3.14\n\nint main()\n{\n    // C no cuenta con un sitio oficial\n    // COMENTARIO DE UNA LINEA\n    /*\n    Comentario de\n    multiples lineas\n    */\n\n    // Segunda forma de crear constante\n    const int SEGUNDA_CONSTANTE = 10;\n\n    // Variables\n    int variable = 23;\n\n    // Datos primitivos\n    float miFlotante = 3.334455;\n    double miDouble = 12.222222333334;\n    bool miBooleano = true;\n    int miEntero = 20;\n    char caracter = 'M';\n    char miCadena[] = \"Cadena\";\n\n    printf(\"¡Hola, C!\");\n    return 0;\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c/barbafebles.c",
    "content": "#include <stdio.h> // printf\n#include <stdbool.h> // bool \n\n// No existe pagina oficial de C \n// URL = https://www.learn-c.org\n\n/*\n    Para comentar varias lineas \n    Se puede hacer de esta manera\n*/\n\n#include <stdio.h> // printf\n\n// Crea una variable \nint num = 1; \nint num2 = 2;\n\n// Variable constante\nconst float PI = 3.1416; \n\n// Variables \nint entero = 1;                                 // Tipo entero \nint *punteroAEntero = &entero;                  // Puntero a una variable de tipo entero \nshort int enteroCorto = 1;                      // Tipo entero corto \nlong int enteroLargo = 100000;                  // Tipo entero largo \nlong double dobleLargo = 3.1415926535897932;    // Tipo entero doble largo \nunsigned int enteroSinSigno = 20;               // Tipo entero sin signo \nunsigned long largoSinSigno = 30;               // Tipo entero largo sin signo \nunsigned short enteroCorto = 23;                // Tipo entero corto sin signo \nfloat flotante = 25.554;                        // Tipo flotante\ndouble doble = 30.5;                            // Tipo doble \nchar caracter = 'A';                            // Tipo caracter \nint array[5] = {1, 2, 3, 4, 5};                 // Array de enteros\nbool boole = true;                              // Tipo booleano\n\n// Programa \nint main()\n{\n    printf(\"Hola, C\\n\");\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c/cikethebear.c",
    "content": "// https://c-language.org\n\n// Esto es un comentario de una linea.\n\n/* Esto es un comentario\nde multiples lineas,\npuede tener tantas lineas como se requiera*/\n\n\n// Definicion de variables\nint var = 0;\nconst int constante = 0;\n\n// Tipos de datos primitivos\nint entero = 0;\nfloat flotante = 0.0;\ndouble flotantePreciso = 0.0;\nchar character = 'c';\n\n// Impresion por pantalla\n#include <stdio.h>\n\nint main(){\n\n    printf(\"Hola, esto es el lenguaje C\");\n\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c/d1d4cum.c",
    "content": "#include <stdio.h>\n#include <stdbool.h>\n\n// https://www.w3schools.com/c/index.php\n// Comentario de una sola línea\n/*\nComentario\nde varias\nlíneas\n*/\n\nint age = 28;\nconst char letter = 'D';\n\n// Tipos de datos\nchar caracter = 'A';\nint numero = 10;\nfloat decimalPequeño = 10.191283;\ndouble decimalGrande = 10.192845671829345;\nbool boolean = true;\n\nint main() {\n    printf(\"¡Hola, C!\\n\");\n    printf(\"%c\\n\", caracter);\n    printf(\"%d\\n\", numero);\n    printf(\"%f\\n\", decimalPequeño);\n    printf(\"%.1f\\n\", decimalPequeño);\n    printf(\"%.2f\\n\", decimalPequeño);\n    printf(\"%lf\\n\", decimalGrande);\n    printf(\"%.1lf\\n\", decimalGrande);\n    printf(\"%.2lf\\n\", decimalGrande);\n\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c/fefestuve.c",
    "content": "#include <stdio.h>\r\n#include <stdlib.h>\r\n\r\n//No existe pagina oficial para C\r\n/*tambien se puede escribir un comentario de varias lineas\r\nusando esta sintaxis*/\r\n\r\n//se puede escribir una constante con un define\r\n#define CONSTANTE 23\r\n\r\nint main(void){\r\n    //tambien se puede de esta forma\r\n    const int entero = 23;\r\n    int entero2 = 10;\r\n    long largo = 47398344837493;\r\n\r\n    float decimal = 0.5;\r\n    double doble = 0.473892762783;\r\n\r\n    char caracter = 'A';\r\n    char string1[5] = \"Hola\";\r\n    //tambien se puede generar un string de esta forma\r\n    char *string2 = malloc(5);\r\n    string2 = \"Hola\";\r\n\r\n    printf(\"¡Hola C!\");\r\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c/fsfigueroa77.c",
    "content": "// https://www.open-std.org/jtc1/sc22/wg14/\n\n// Comentario en una linea\n\n/*\nComentario\nen\nvarias\nlineas\nxd\n*/\n\n#include <stdio.h>\n#define MI_CONSTANTE 0 // Creacion de constante\n\nint main(){\n    int mi_variable = 1; // Creacion de variable\n\n    // variables con cada tipo de dato primitivo\n    int tipo_entero = 1;\n    float tipo_flotante = 1.1;\n    char tipo_caracter[] = \"hola\";\n\n    // hacer impresion de texto\n    printf(\"Hola, C!\");\n\n    return(0);\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c/heliercamejo.c",
    "content": "/**\n * Sitio oficial de C\n * https://www.open-std.org/jtc1/sc22/wg14/\n*/\n\n// Esto es un comentario de una linea \n\n/*\nEsto es un comentario de varias lineas\n*/\n#include <stdio.h>\n\nint main()\n{\n    //Una constante\n    const int constante = 5;\n    \n    //Una cadena\n    char cadena[] = \"C\";\n    \n    //Tipos primitivos\n    char caracter;\n    short entero_pequeño;\n    int entero;\n    long entero_grade;\n    float racional;\n    double racional_d;\n\n    //Impresion en Consola\n    printf(\"¡Hola, %s !\\n\", cadena);\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c/jchavescaceres.c",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n#include <stdio.h>\n\nint main(void) {\n\n/* Que yo sepa no existe web oficial de C */\n/* Los comentarios siempre entre /* y */\n/* \nTambién pueden ser varias líneas \n*/\n\nint variable = 2;\nconst int constante = 3;\n#define _CONTANTE_TAMBIEN_ASI 4\n\nchar miCaracter='C';\nint miEntero=7;\nlong miLong=4781818;\nfloat miFloat=0.0;\ndouble miDouble=1.0;\n\nprintf(\"¡Hola, C!\\n\");\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c/marianofernandezs.c",
    "content": "//https://learn.microsoft.com/en-us/cpp/c-language/?view=msvc-170\n\n// Comentario\n\n/*Esto tambien es\nun comentario en\nvarias lineas*/\n\n#include <stdio.h>\n#include <string.h>\n\nint main(){\n    char myVariable[] = \"Mi variable\";\n    strcpy(myVariable, \"Nuevo valor\");\n\n    int myInt = 4; // un numero entero\n    char myChar = 'h'; // un caracter\n    float myFloat = 4.35; // numero flotante\n    _Bool myBool = 1; // 1 es True\n\n    const int y = 1;\n\n    printf(\"!Hola Mundo!!!\");\n\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c/miguelex.c",
    "content": "// Documentación en https://devdocs.io/c/\n\n// Comentario de una linea\n\n/* Comentario\nen varias\nlineas */\n\n#include <stdio.h>\n\nint main()\n{\n    // Declaramos una variable\n    char lenguaje = 'C';\n\n    // Declaramos constante\n    const float PI = 3.1415;\n\n    // Tipos primitivos en C\n    char letra = 'a';\n    int numero = 5;\n    float decimalSimple = 0.25;\n    double decimalDoble = -5.10;\n    long enteroLargo = 12025865L;\n    short enteroCorto = 100;\n    unsigned enteroSinSigno = 10;\n    unsigned long enteroLargoSinSigno = 9889898989898UL;\n    unsigned short entroCortoSinSigno = 122;\n\n    // Imprimimos por consola\n    printf(\"Hola, %c!\\n\", lenguaje);\n\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c/othamae.c",
    "content": "/*\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n\n// https://www.gnu.org/software/gnu-c-manual/gnu-c-manual.html\n// https://en.wikibooks.org/wiki/C_Programming\n// https://devdocs.io/c/\n\n// Comment in one line\n\n/**\n * comment\n * in\n * block\n */\n\n#include <stdio.h>\n\n#define CONSTANT \"This is a constant\"\n\n\nint main() {\n\n    // Variables\n    char letter = 'a';\n    int integer = 1;\n    float floating = 10.5;\n    double double_floating = -1.35;\n        \n    printf(\"Hello C!\\n\");\n    printf(\"This is a constant: %s\\n\", CONSTANT);\n    printf(\"This is a char: %c\\n\", letter);\n    printf(\"This is an integer: %d\\n\", integer);\n    printf(\"This is a float: %g\\n\", floating);\n    printf(\"This is a double: %lf\\n\", double_floating);\n    return 0;\n}\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c/sergio-strazzacappa.c",
    "content": "// Este es un comentario de una línea\n\n/*\n * Este es un comentario\n * de multiples\n * líneas\n */\n\n/*\n * C no tiene un sitio web oficial\n *\n * Se puede acceder a la documentación de gcc:\n * https://man7.org/linux/man-pages/man1/gcc.1.html\n *\n * O al manual de referencia de C:\n * https://www.gnu.org/software/gnu-c-manual/\n */\n\n#include <stdio.h> // Se incluye la librearía para manejor de I/O\n\n#define PI 3.141592 // Esto es una directiva de preprocesador\n\nint main() {\n  // Una variable\n  int variable = 15;\n\n  // Una constante\n  const int constante = -4;\n\n  // Los tipos de datos primitivos\n  char c = 'f';\n  int i = 100;\n  float f = 1.4;\n  double d = -5.2;\n\n  /*\n   * Se pueden poner los siguientes modificadores a los tipos de datos\n   * - signed\n   * - unsigned\n   * - short\n   * - long\n   */\n\n  /*\n   * En C no existe ni el tipo Boolean, ni el tipo String\n   */\n  \n  printf(\"¡Hola, C!\\n\");\n  printf(\"La directiva de preprocesador PI: %f\\n\", PI);\n  printf(\"Variable: %d\\n\", variable);\n  printf(\"Constante: %d\\n\", constante);\n  printf(\"Los tipos de datos primitivos: %c, %d, %.2f, %.2f\\n\", c, i, f, d);\n\n  return 0;\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c/theposi.c",
    "content": "/*\n EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n */\n\n// Manual de C del proyecto GNU https://www.gnu.org/software/gnu-c-manual/gnu-c-manual.html\n\n// Comentario de una línea\n\n/*\n Comentario\n de varias\n líneas\n*/\n\n#include \"stdio.h\"\n\nint main(void){\n    // Variable & const\n    int num = 9;\n    const int year = 2024;\n\n    // primitive data types\n    int my_integer = 5;\n    char my_str = 'B';\n    float my_float = 5.5;\n    double my_double = 56.998;\n    long my_long = 123456879;\n    short my_short = 123;\n    unsigned int my_unsigned_int = 50;\n    signed int my_signed_int = -70;\n    unsigned long int my_u_l_int = 12345555678;\n    signed long int my_s_l_int = -1233324554;\n\n    // Terminal print\n    char language = 'C';\n    printf(\"¡Hola, %c!\\n\", language);\n    return (0);\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c/vec70rr.c",
    "content": "//No encontré una página oficial de C, asi que pongo la documentacion de Microsoft: https://learn.microsoft.com/es-es/cpp/c-language/\n\n//Comentario de una linea\n/*\nComentario de \nvarias lineas\n*/\n\n#include <stdio.h>\n\n#define constante 10 // Definicion de una constante\n\nint main(int argc, char const *argv[])\n{\n    int variable; //declaracion de variable\n\n    int entero;\n    double decimal;\n    float flotante;\n    char caracter;\n    char cadena[20];\n    \n    printf(\"¡Hola, C!\");\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c/vinyoles.c",
    "content": "//C documentation: https://devdocs.io/c/\n\n//This is a single line comment\n\n/*\n * This is a comment\n * divided into multiple lines\n * */\n\n#include <stdio.h>\n#include <stdlib.h>\n\nint main() {\n    //constant\n    const double GOLDEN_RATIO = 1.6180339887499;\n    printf(\"Golden ratio: %f \\n\", GOLDEN_RATIO);\n\n    //variables\n    char character = 'a';\n    printf(\"Character: %c \\n\", character);\n\n    char string[] = \"This is an string \\n\";\n    printf(\"String: %s\", string);\n\n    short shortNum = 32767; //16 bits\n    printf(\"Short: %hd \\n\", shortNum);\n\n    int integer = 2147483647; //32 bits.\n    printf(\"Integer: %i \\n\", integer);\n\n    long long longNum = 9223372036854775807; //64 bits\n    printf(\"Long: %lli \\n\", longNum);\n\n    float floatNum = 1.1f;\n    printf(\"Float: %f \\n\", floatNum);\n\n    double doubleNum = 1.1111111111111111111111111111;\n    printf(\"Double: %f \\n\", doubleNum);\n\n\n    printf(\"Hola, C! \\n\");\n\n    return 0;\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/AkaiSombra.cs",
    "content": "\n// Author: Nicolas Romero https://github.com/AkaiSombra\n\n/*\n * EJERCICIO:\n * 1. Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * 2. Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * 3. Crea una variable (y una constante si el lenguaje lo soporta).\n * 4. Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * 5. Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n*/\n\nusing System;\n\n// Ejercicio 1:\n\n// Sitio oficial de C#: https://learn.microsoft.com/en-us/dotnet/csharp/\n\n// Ejercicio 2:\n\n// Comentario de una sola linea en C#\n\n/*\nComentario de varias lineas\nen C#, igual que en JS\n*/\n\n// Ejercicio 3:\n\nvar Variable = 2;\n\nconst int Constante = 10;\n\n// Ejercicio 4:\n\n// Enteros(int)\n\nint IntNumber = 20;\n\n// Numero de punto flotante(float)\n\n// 32 bits\nfloat FloatNumber32Bits = 5.14f;\n\n// 64 bits\ndouble FloatNumber = 3.14;\n\n// Cadena de texto (String)\n\nstring StringText = \"Esto es un String\";\n\n// Booleanos (bool)\n\nbool BooleanTrue = true;\nbool BooleanFalse = false;\n\n// Ejercicio 5:\n\nclass AkaiSombra\n{\n    static void Main(string[] args)\n    {\n        string lenguaje = \"C#\";\n        Console.WriteLine($\"¡Hola, {lenguaje}!\");\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/Albertosogasol.cs",
    "content": "// URL oficial del lenguaje C#: https://learn.microsoft.com/en-us/dotnet/csharp/\n\nusing System;\n\nclass Program\n{\n    static void Main()\n    {\n        // Esto es un comentario de una sola línea\n\n        /*\n         * Esto es un comentario\n         * de múltiples líneas\n         */\n\n        /// <summary>\n        /// También se puede usar esta sintaxis para comentarios de documentación XML.\n        /// Se suelen usar para describir métodos, clases, etc.\n        /// </summary>\n\n        // Variable\n        string nombre = \"C#\";\n\n        // Constante\n        const double PI = 3.14159;\n\n        // Tipos de datos primitivos\n        string texto = \"Esto es una cadena de texto\";\n        char caracter = 'A';\n        int entero = 42;\n        long enteroLargo = 1234567890L;\n        float flotante = 3.14f;\n        double doble = 2.71828;\n        bool booleano = true;\n        decimal numeroDecimal = 19.99m;\n\n        // Imprimir mensaje por consola\n        Console.WriteLine(\"¡Hola, \" + nombre + \"!\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/Alfarog507.cs",
    "content": "// Documentación oficial: https://learn.microsoft.com/es-es/dotnet/csharp/\n/* Este es en comentario de múltiples líneas \nPrueba de comentarios\n*/\n// Este es un comentario de una linea\n\n//Definimos Variables y Constantes\nvar variable = 30; //Variable en C#\nconst int constante = 10; //Constante en C#\n\n//Tipos de Datos\nint entero = 20; //Entero\nfloat flotante32Bits = 5.14f; //Numero de punto flotante de 32 bits\ndouble doble = 3.14; //Numero de punto flotante de 64 bits\nlong largo = 3.2342; //Numero de punto flotante de 64 bits\ndecimal decimalNumber = 10.3; //Decimal\nstring cadena = \"Esto es un String\"; //Cadena de texto\nchar caracter = 'C'; //Caracter\nbool booleano = true; //Booleano\n\n//Imprimimos en consola\nConsole.WriteLine(\"Variable: \" + variable);\nConsole.WriteLine(\"Constante: \" + constante);\nConsole.WriteLine(\"Entero: \" + entero);\nConsole.WriteLine(\"Flotante 32 bits: \" + flotante32Bits);\nConsole.WriteLine(\"Doble: \" + doble);\nConsole.WriteLine(\"Largo: \" + largo);\nConsole.WriteLine(\"Decimal: \" + decimalNumber);\nConsole.WriteLine(\"Cadena: \" + cadena);\nConsole.WriteLine(\"Caracter: \" + caracter);\nConsole.WriteLine(\"Booleano Verdadero: \" + booleano);\nConsole.WriteLine(\"Booleano Falso: \" + !booleano);\nConsole.WriteLine(\"Hola Mundo!\");\n// // Documentación oficial: https://learn.microsoft.com/es-es/dotnet/csharp/\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/Andreavzqz.cs",
    "content": "using System;\n\n// Comentario con la URL del sitio web oficial de C#: https://docs.microsoft.com/es-es/dotnet/csharp/\n\nclass Program\n{\n    static void Main(string[] args)\n    {\n        // Comentario de una línea\n\n        /* Comentario\n           de\n           varias\n           líneas */\n\n        // Crear una variable y una constante\n        int variable = 10;\n        const double PI = 3.14159;\n\n        // Variables de diferentes tipos de datos primitivos\n        string cadena = \"Hola mundo\";\n        int entero = 42;\n        double doble = 3.14;\n        bool booleano = true;\n        bool booleano = false;\n        \n\n        // Imprimir por terminal\n        Console.WriteLine(\"¡Hola, C#!\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/Complex303.cs",
    "content": "using System;\n\n// https://dotnet.microsoft.com/es-es/languages/csharp\n// Este es un comentario de una sola linea\n\n/* Una constante es un valor fijo que no puede cambiar una vez asignado.\nSe declara usando la palabra clave const y debe inicializarse al momento de declararla. */\n\n///Son como los comentarios multilinea,\n///Se usan para describir funciones, clases o metodos, y se pueden leer desde herramientas como Visual Studio para autocompletar y documentaci�n autom�tica.\n\nclass Program  // Todo dentro de una clase\n{\n    static void Main() // Metodo principal\n    {\n        string nombre = \"Eddy\"; //variable\n\n        const cantidad_de_libros = 23; //constante\n\n        //Tipo de datos primitivos en C#\n\n        int edad = 23;\n        double area = 23.45; //tambien se puede usar float y decimal\n        char letra = 'E';\n        bool es_hombre = true;\n        string mensaje = \"Hola\";\n\n        Console.WriteLine(\"Hola, C#!!\");\n        Console.WriteLine(\"=================================\")\n        Console.WriteLine($\"La edad es: {edad}\");\n        Console.WriteLine(\"El area del triangulo es: \" + area);\n        Console.WriteLine(\"La letra es: \" + letra);\n\n\n    }\n}\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/Esaens12.cs",
    "content": "﻿namespace _00_SINTAXIS__VARIABLES__TIPOS_DE_DATOS_Y_HOLA_MUNDO\r\n{\r\n    internal class Program\r\n    {\r\n        static void Main(string[] args)\r\n        {\r\n            /* EJERCICIO:\r\n* - Crea un comentario en el código y coloca la URL del sitio web oficial del\r\n*   lenguaje de programación que has seleccionado.\r\n* - Representa las diferentes sintaxis que existen de crear comentarios\r\n*   en el lenguaje (en una línea, varias...).\r\n* - Crea una variable (y una constante si el lenguaje lo soporta).\r\n* - Crea variables representando todos los tipos de datos primitivos\r\n*   del lenguaje (cadenas de texto, enteros, booleanos...).\r\n* - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\" */\r\n\r\n            //https://dotnet.microsoft.com/es-es/languages/csharp SITIO OFICIAL DE C#\r\n\r\n            // COMENTARIO EN UNA SOLA LINEA\r\n\r\n            /* COMENTARIO\r\n             * EN \r\n             * VARIAS\r\n             * LINEAS */\r\n\r\n            string variable; // variable de tipo string\r\n\r\n            const double pi = 3.1416; // esto es una variable constante\r\n\r\n            // Tipos Enteros\r\n\r\n            // byte: Almacena un número entero sin signo de 8 bits (0 a 255)\r\n            byte byteVar = 255;\r\n\r\n            // sbyte: Almacena un número entero con signo de 8 bits (-128 a 127)\r\n            sbyte sbyteVar = -128;\r\n\r\n            // short: Almacena un número entero con signo de 16 bits (-32768 a 32767)\r\n            short shortVar = -32768;\r\n\r\n            // ushort: Almacena un número entero sin signo de 16 bits (0 a 65535)\r\n            ushort ushortVar = 65535;\r\n\r\n            // int: Almacena un número entero con signo de 32 bits (-2,147483648 a 2147483647)\r\n            int intVar = -2147483648;\r\n\r\n            // uint: Almacena un número entero sin signo de 32 bits (0 a 4294967295)\r\n            uint uintVar = 4294967295;\r\n\r\n            // long: Almacena un número entero con signo de 64 bits (-9223372036854775808 a 9223372036854775807)\r\n            long longVar = -9223372036854775808;\r\n\r\n            // ulong: Almacena un número entero sin signo de 64 bits (0 a 18446744073709551615)\r\n            ulong ulongVar = 18446744073709551615;\r\n\r\n            // Tipos de Coma Flotante\r\n\r\n            // float: Almacena un número de punto flotante de precisión simple de 32 bits (±1.5e-45 a ±3.4e38), con 7 dígitos de precisión\r\n            float floatVar = 3.14f;\r\n\r\n            // double: Almacena un número de punto flotante de precisión doble de 64 bits (±5.0e-324 a ±1.7e308), con 15-16 dígitos de precisión\r\n            double doubleVar = 3.141592653589793;\r\n\r\n            // Tipo Decimal\r\n\r\n            // decimal: Almacena un número de punto flotante decimal de 128 bits (±1.0e-28 a ±7.9e28), con 28-29 dígitos de precisión. Ideal para cálculos financieros\r\n            decimal decimalVar = 3.1415926535897932384626433832m;\r\n\r\n            // Tipo Booleano\r\n\r\n            // bool: Almacena un valor booleano que puede ser true o false\r\n            bool boolVar = true;\r\n\r\n            // Tipo de Carácter\r\n\r\n            // char: Almacena un carácter Unicode de 16 bits. Puede almacenar cualquier carácter Unicode\r\n            char charVar = 'A';\r\n\r\n            // Tipo de Cadena\r\n\r\n            // string: Almacena una secuencia de caracteres. Es un tipo de referencia\r\n            string stringVar = \"Hola, mundo!\";\r\n\r\n            // Tipo de Puntero Nulo\r\n\r\n            // object: El tipo base de todos los tipos en C#. Puede almacenar cualquier tipo de dato\r\n            object objectVar = \"Esto es un objeto\";\r\n            object objectVar2 = 35.6743;\r\n            object objectVar3 = 'a';\r\n            object objectVar4 = true;\r\n            object objectVar5 = 456;\r\n\r\n            string lenguaje = \"C#\";\r\n\r\n            Console.WriteLine($\" HOLA {lenguaje}\");\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/FreddyASierraJ.cs",
    "content": "﻿using System;\n\nnamespace RetosDeProgramacion\n{\n    //URL oficial de C#: https://learn.microsoft.com/es-es/collections/yz26f8y64n7k07\n    //comentario de una sola linea\n    /*\n     * comentario de multiples lineas\n     */\n\n    internal class Program\n    {\n        //creando variable global\n\n        int edad = 30;\n\n        //Creando variable tipo constante\n\n        const int numero = 1;\n        static void Main(string[] args)\n        {\n            byte myByte = 100;\n            Console.WriteLine($\"esto es un byte {myByte}\");\n            sbyte myByte2 = -10;\n            Console.WriteLine($\"esto es un sbyte {myByte2}\");\n            short myShort = 20000;\n            Console.WriteLine($\"esto es un short {myShort}\");\n            ushort myUShort = 60000;\n            Console.WriteLine($\"esto es un Ushort {myUShort}\");\n            int myInt = -2000000000;\n            Console.WriteLine($\"esto es un Int {myInt}\");\n            uint myUint = 2000000000;\n            Console.WriteLine($\"esto es un Uint {myUint}\");\n            long myLong = -1000000000000000000;\n            Console.WriteLine($\"esto es un Long {myLong}\");\n            ulong myULong = 1000000000000000000;\n            Console.WriteLine($\"esto es un ULong {myULong}\");\n            float myFloat = 1.3f;\n            Console.WriteLine($\"esto es un float {myFloat}\");\n            double myDouble = 10.2;\n            Console.WriteLine($\"esto es un double {myDouble}\");\n            String myString = \"Ejemplo de String\";\n            Console.WriteLine($\"esto es un String {myString}\");\n            bool myBool = false;\n            Console.WriteLine($\"esto es un boolean {myBool}\");\n\n            Console.WriteLine(\"Hola, C#!\");\n            Console.ReadKey();\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/GeorgeHaz.cs",
    "content": "using System;\nclass Ejercicio00\n{\n    static void Main(string[] args)\n    {\n        //**Pagina del lenguajes**\n        //https://dotnet.microsoft.com/es-es/languages/csharp\n\n        //**Sintaxis para crear comentarios\n        //Soy un comentario de una linea.\n        /*Soy un comnetario\n        de varias lineas\n        */\n\n        //Variables y constante\n        string variable;\n        const string constante;\n\n        //Datos primitivos\n        string texto = \"Hola\";\n        int entero = 20;\n        double miDouble = 1.1;\n        float miFloat = 1.1111f;\n        decimal miDecimal = 1.111m;\n        char miChart = 'k';\n        bool miBool = true;\n        bool miBool2 = false;\n        byte miByte = 255;\n        ushort miUShort = 82839;\n        \n        //Impresion por terminal\n        Console.WriteLine(\"¡Hola, C#!\");\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/Guufy12.cs",
    "content": "/*EJERCICIO:\n*-Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n*/\n\n//C#: https://dotnet.microsoft.com/es-es/languages/csharp\n\n//Comentario de una sola linea\n\n/* Comentario\n * de\n * multiples\n * lineas\n */\n\nconst int Constante = 10;\nstring Texto = \"Soy una variable string\";\n\nbyte numeroByte = 255;\nint entero = 120;\nfloat flotante = 83f;\ndecimal numerico = 3.14m;\ndouble numeroDouble = 12.34;\nchar letra = 'A';\nstring texto = \"Soy un string\";\nbool estado = true;\nobject objeto = false;\n\nConsole.WriteLine(\"Hola soy C#, un placer\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/Ishimaku.cs",
    "content": "using System;\n\nnamespace Ishimaku\n{\n    class Program\n    {\n        static void Main(string[] args)\n        {\n            //https://learn.microsoft.com/es-es/dotnet/csharp/tour-of-csharp/\n            //un comentario xd\n\n            /*\n            comentario\n            en\n            bloque\n            */\n\n            //se declara una variable\n            int variable;\n\n            //se declara una constante\n            const int constante;\n\n            //tipos de variables fundamentales\n            int variableint = 1;\n            float variablefloat = 0.25f;\n            string variablestring = \"variablestring\";\n            bool variablebooleano = true;\n\n            //mensaje en consola\n            System.Console.WriteLine(\"Hola, C#!\");\n        }\n    }\n}\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/Isj-code.cs",
    "content": "﻿// Link al lenguaje https://dotnet.microsoft.com/es-es/languages/csharp\n\n// Comentario de una línea\n\n/*\n * Comentario en bloque\n */\n \n// Variable inferida \nvar numeroReto = 00;\n\n// Constante\nconst string lenguaje = \"C#\";\n\n// Tipos de datos primitivos\n\n// Numeros de menos a mayor uso de memoria\nbyte numByte = 1;\nint numInt = 1;\nlong numLong = 1;\nfloat numFloat = 1.1f;\ndouble numDouble = 1.1;\ndecimal numDecimal = 1.1m;\n\n// Cadenas de texto\nchar letra = 'a';\nstring frase = \"El char anterior debe de ir entre comillas simples\";\n\n// Booleano\nbool respuesta = true;\n\n// Object y dynamic\ndynamic dinamico = \"Hola Caracola, no voy a poder usar Lenght\";\nobject nombre = \"Hola soy object y no sabre inferirte hasta que me ejecutes\";\n\n// Hola Mundo!!!!!! El System no haría falta ya que está importado, pero por si acaso.\nSystem.Console.WriteLine($\"¡Hola, {lenguaje}!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/IvanCalero04.cs",
    "content": "// https://dotnet.microsoft.com/en-us/languages/csharp\n\n// Esto es un comentario de una linea.\n/*\nY Esto \nes un comentario \nen varias lineas\n*/\n\n\nstring myString = \"Iván\"; // Variable\nconst string = \"Tengo 21 años.\"; // Constante\n\n// Tipos de variables:\n\nint myInt = 21;\nstring myString = \"C#\";\nfloat myFloat = 2.3f;\ndouble myDouble = 2.3;\nbool myBool = true;\nvar myVar = \"Variable de tipo inferido\";\ndynamic myDynamic = 6;\n\nConsole.WriteLine($\"¡Hola, {myString}!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/Jean-Carlos-Backend-Developer.cs",
    "content": "//------------------------------------------------------------------------------------\n/*\n1. Crea un comentario en el código y coloca la URL del sitio web oficial del\n   lenguaje de programación que has seleccionado.\n*/\n\n//Sitio oficial de C#: https://learn.microsoft.com/en-us/dotnet/csharp/\n\n//------------------------------------------------------------------------------------\n/*\n2. Representa las diferentes sintaxis que existen de crear comentarios\n   en el lenguaje(en una línea, varias...).\n*/\n\n//Esto es un comentario de una línea\n\n/*Esto es un comentario de \nvarias líneas*/\n\n//------------------------------------------------------------------------------------\n/*\n3. Crea una variable(y una constante si el lenguaje lo soporta).\n*/\n\nint entero = 1;\nconst int Max_Items = 15;\n\n//------------------------------------------------------------------------------------\n\n/*\n4. Crea variables representando todos los tipos de datos primitivos\n   del lenguaje(cadenas de texto, enteros, booleanos...).\n*/\n\n//Enteros\nbyte byteVar = 255;\nsbyte sbyteVar = -128;\nshort shortVar = 32767;\nushort ushortVar = 65535;\nint intVar = 2147483647;\nuint uintVar = 4294967295;\nlong longVar = 9223372036854775807L;\nulong ulongVar = 18446744073709551615UL;\n\n//Punto flotante\nfloat floatVar = 3.14f;\ndouble doubleVar = 3.14159265359;\ndecimal decimalVar = 3.14159265359m;\n\n// Booleano\nbool boolVar = true;\n\n// Caracteres y cadenas\nchar charVar = 'A';\nstring stringVar = \"Hola mundo\";\n\n// Fecha y hora\nDateTime dateTimeVar = DateTime.Now;\n\n//------------------------------------------------------------------------------------\n/*\n5. Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n*/\n\nConsole.WriteLine(\"¡Hola, C#!\");\n\n//------------------------------------------------------------------------------------"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/JoseEsmil04.cs",
    "content": "// https://docs.microsoft.com/en-us/dotnet/csharp/ -- Sitio web oficial del lenguaje de programación C#\n\n// Comentario de una línea\n\n/*\nComentario de múltiples\nlíneas utilizando barras\ny asteriscos.\n*/\n\n\nstring variable = \"Soy una variable\";  // Variable\n\nconst string CONSTANTE = \"¡Hola, C#!\";  // Constante\n\nvar miVar = \"JoseEsmil04\"; // Inferencia\n\nstring texto = \"Esto es una cadena de texto\";  // String\n\nbool booleano = false;  // Bool\n\nfloat flotante = 3.14f;  // Float\n\ndouble doble = 2.718281828459045; // Double\n\nchar caracter = 'A'; // Char\n\ndecimal decimalNum = 19.99m; // Decimal\n\nint entero = 42;  // Int\nuint uintNum = 4294967295; // UInt\n\nbyte byteNum = 255; // Byte\nsbyte sbyteNum = -128; // SByte\n\nshort corto = 32767; // Short\nushort ushortNum = 65535; // UShort\n\nlong largo = 9223372036854775807; // Long\nulong ulongNum = 18446744073709551615; // ULong\n\nobject nulo = null;  // Null\n\n// Imprimir por terminal el texto: \"¡Hola, C#!\"\nConsole.WriteLine(CONSTANTE);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/JuanCamiloGomezAlvarez.cs",
    "content": "//documentación oficial\n//https://learn.microsoft.com/es-es/dotnet/csharp/\n\n\n//C#\n\n//Este es un comentario de una linea\n\n/*\nEste es\nun comentario\nmultilinea\n*/\n\n// Variable de ejemplo\n\nstring helloWorld = \"Hello World!\";\n\n//Constante de ejemplo\n\nconst double PI = 3.14159f;\n\n// Tipos de variables mas comunes en C#\n\nvar lenguage = \"C#\";\nstring firstName = \"Juan\";\nint age = 31;\ndouble height = 1.75m;\nbool isAdmin = true;  \nchar gender = 'M';\n\nstring message = $\"Hello I\\\"m {firstName} and I want to learn {lenguage}\";\n\nConsole.WriteLine(message);"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/JuanpVelasquezR.cs",
    "content": "// Documentacin Oficial de C#\n// https://learn.microsoft.com/en-us/dotnet/csharp/\n\n// Este es un ejemplo de un comentario de una sola lnea\n\n/* Se permiten comentario de mltiples leas\n * Abriendo y cerrando adecaudamente los carcteres */\n\n//-----------------------------------------------------------------------------------------------------\n\n//Tipos de datos Primitivos:\n\nconst string constante = \"Constante de tipo strig, su valor es inmutable\";\n\nint entero = 56780;\n\nbool booleano = true;\n\nfloat puntoflotante = 46.9f;\n\nchar character = 'B';\n\nbyte tipobyte = 255;\n\nshort shortint = 3445;\n\nlong longint = 2304203953490;\n\ndecimal tipodecimal = 3424.43567M;\n\nstring cadena = \"!Hola, C#\";\n\n//Impresin por consola del Saludo con Lenguaje de programacin \n\nConsole.WriteLine(cadena);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/Kvr0th3c4t.cs",
    "content": "//https://dotnet.microsoft.com/es-es/languages/csharp\n\n/* Para comentarios multilínea*/\n//Para comentarios de una linea.\n\nvar variable;\nvar variableAsignada = \"Valor asignado\";\n\nconst double Pi = 3.14159;\n\n//Estos os últimos ejemplos se usan dentro de una clase siempre. \npublic const string constantePublica = \"Constante publica\";\nprivate const string constantePrivada = \"Constante privada\";\n\n\nint numeroEjemplo = 1;\ndouble numeroDoubleEjemplo = 1.2;\nstring palabraEjemplo = \"Hola\";\nchar charEjemplo = 'C';\nbool boolEjemplo = true;\ndecimal decimalEjemplo = 1.23;\n\nConsole.WriteLine(\"¡Hola, CSharp!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/Ledyam.cs",
    "content": "class ledyamdev\n{\n    // Documentación en https://learn.microsoft.com/es-es/dotnet/csharp/\n\n    // Comentario de una linea\n\n    /* Comentario\n        de \n       varias \n       líneas */\n\n    static void Main(string[] args)\n    {\n// Declaración de variables \n        string lenguaje = \"C#\";\n// Constante\n        const double GRAVEDAD = 9.8;\n\n        // Tipos de datos primitivos\n        int entero = 1;\n        double decimal = 2.5;\n        char caracter = 'l';\n        string cadena = \"HELLO\";\n        bool booleano = true;\n\n        // Imprimir por pantalla\n        Console.WriteLine($\"Hola {lenguaje}\");\n        Console.WriteLine(\"El valor de la variable es: \" + entero);\n        Console.WriteLine($\"El valor del caracter es: {caracter}\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/Lordibzn.cs",
    "content": " // paguina web de documentación: https://dotnet.microsoft.com/es-es/\n //Librerias utilizadas\n using system;\n\n// comentarios\n // comentario en una linea\n\n /*\n cometario en\n varias lineas\n */\n\n // Declaración de variables y constantes\n int edad = 27;\n const int variableConstante = 0;\n\n// Datos primirtivos\n//Boolenaos\nbool booleanData = true; // solo son verdadero o falso\n//Byte, short, Int y Long\nbyte valorByte = 99;\nshort valorShort = 100;\nint valorInt = 400;\nlong valorLong = 13123123123L;\n// Float, Double, Decimal\nfloat numeroFlotante = 66.66f;\ndouble numeroDoblePrecision = 0;\ndecimal decimales = 456.34m;\n//char\nchar caracter = 'a';\n\n//Hello world!\nConsole.WriteLine(\"Holla C#\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/Lovera7.cs",
    "content": "// 1.Primera instrucción\n// URL sitio oficial C# https://learn.microsoft.com/es-es/dotnet/csharp/\n\n// 2.Segunda instrucción\n/*\n  Este es un comentario\n  de varias lineas\n*/\n// Este es un comentario de una linea\n/// <summary>\n/// Este es un comentario para generar documentacion XML desde el compilador.\n/// </summary>\n\n// 3.Tercera instrucción\nstring miVariable = \"Esto es una variable\";\nconst int miConstante = 10;\n\n// 4.Cuarta instrucción\nsbyte temperatura = -128;\nshort numeroCorto = 32767;\nint numero = 2147483647;\nlong numeroLargo = 9223372036854775807L;\nbyte numeroByte = 255;\nushort numeroCorto2 = 65535;\nuint numero2 = 4294967295;\nulong numeroLargo2 = 18446744073709551615UL;\nchar caracter = 'A';\nfloat flotante = 3.14f;\ndouble doblePrecision = 2.718281828459045;\ndecimal decimalNum = 123.456m;\nbool booleano = true;\n\n// 5.Quinta instruccion\nConsole.WriteLine(\"¡Hola, C#!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/LuisOlivaresJ.cs",
    "content": "using System;\n\n/*\n* - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n*/\n\n// This is a one line comment\n\n/* This\nis a multiple \nlines comment.\n*/\n\n//* - Crea un comentario en el código y coloca la URL del sitio web oficial del\n// *   lenguaje de programación que has seleccionado.\n\n\n// https://dotnet.microsoft.com/es-es/languages/csharp\n\n\n //* - Crea una variable (y una constante si el lenguaje lo soporta).\n\n //const int myvar = 25;\n\n\nnamespace MyApplication\n{\n  class Program\n  {\n    static void Main(string[] args)\n    {\n      const int myNum = 15;\n      //myNum = 20;  // This makes an error\n      Console.WriteLine(myNum);\n\n      Console.WriteLine(myNum);\n\n      double pi = 3.14;  // A float data type variable\n      string name = \"Luis\";  // A string type variable\n      bool answ = true;\n\n      Console.WriteLine(pi);\n      Console.WriteLine(name);\n      Console.WriteLine(answ);\n\n      Console.WriteLine(\"Hola C sharp!\");\n    }\n  }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/MarvinAgui.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace _00_SINTAXIS__VARIABLES__TIPOS_DE_DATOS_Y_HOLA_MUNDO\n{\n    internal class Program\n    {\n        enum weekdays { Monday, Tuesday, Wednsday, thursday, Friday, Saturday, Sunday};\n        // Aqui observamos que tambine podemor declarar variables globales \n        // se dice que no es buena practica la utilizacion de este tipo de variables en C#, aunque dependera de la situacion\n\n        static void Main(string[] args)\n        {\n            // En C# hay dos maneras de reprensentar los comentarios\n\n            /* La primera es con dos barras // como observamos en la linea 13 del codigo y la segunda\n               se utiliza para seleccionar varias libeas de cogido o comentar en varias lideas diferentes que es \n               lo que estoy haciendo en este comentario.\n               - Aquí tenemos toda la documentacion Oficial de C#: https://learn.microsoft.com/es-es/dotnet/csharp/ */\n\n            // Ahora vamor a declarar algunas variables y veremos tambien los tipos primivitos que tenemos en C#\n            // En C# la sintaxis a¡para declaras las variables es: <tipo> <nombre_variable>\n\n            var greet = \"Hola\";\n            var age = 37;       // como podemos ver la palabra reservada \"var\" se puede utilizar para cualquier tipo de dato\n            var pi = 3.14;      // es el propio compilador quien establece el tipo en funcion del valor que le demos a la variable \n\n            // Aqui tenemos la declaracion de una constante (cuyo valor no puede cambiar)\n            const string despedida = \"adios\";\n\n            //tipos de datos \n\n            /* TIPOS SIMPLES: Sbyte, short, int, long --- enteros con signo\n                              Byte, unshort, uint, ulong --- enteros sin signo\n                              Float, double --- punto flotante\n                              Char --- caracteres\n                              Decimal --- decimal de alta precisión\n                              Bool --- booleano\n\n               TIPO DATO enum --- como hemos visto en la variable global \"Weekdays\" \n\n            */\n\n            // Algunos Ejemplos:\n\n            bool verdadero = true;\n            bool falso; // por default el tipo bool dara \"false\"\n\n            Char letra = 'a';\n\n            float numeros = 3.34f; // puede albergar hasta 4 bytes (32 bits) en memoria, que equivalen a 7 decimales\n\n            double num = 2.3432; // Es el que mas se utiliza ya que puede albergar hasta 8 bytes (64 bits) que equivalen hasta 15 decimales de precision\n\n            decimal precision = 322.9275624795m; // se utiliza para la maxima precision posible, para transacciones economicas por ejeplo\n            // decimal alberga valores de hasta 16 bytes (128 bits)\n\n\n            // Tipo String para representar cadenas de texto \n\n            string cadena = \" Hola, C# \";\n\n            // Tipo Matriz Unidimensional y Bidimensional\n            int[] miArray = new int[5]; // array tipo int con 5 posiciones \n            string [] miArray2 = new string[] { \"cocina\", \"baño\", \"salon\", \"comedor\", \"dormitorio\" }; // aqui observamos un array de tipo string tambien con 5 posiciones \n\n            int[,] arrayBidimensional = new int[2, 3]; // los valores se refieren a 2 Filas, 3 Columnas \n            int[,] bidimensional2 = { {'a', 'b', 'c' }, {'d', 'e', 'f' } }; // al igual que el anterior este array contiene 2 Filas y 3 Columnas, ahora los valores estan asignados\n\n            // Y para terminar sacaremos por consola nuestro \" Hola, C#\" y utilizaremos Console.ReadKey(); para que el programa espere y podamos observar lo que tenemos por consola\n\n            Console.WriteLine(cadena);\n            Console.ReadKey();\n\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/ProTpuS98.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.ConstrainedExecution;\nusing System.Security.Policy;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace PracticasLogicaProgramacion\n{\n    internal class Program\n    {\n        static void Main(string[] args)\n        {\n            //EJERCICIOS\n            //1. Crea un comentario en el código y coloca la URL del \n            //sitio web oficial del lenguaje de programación que has seleccionado.\n\n            https://learn.microsoft.com/en-us/dotnet/csharp/\n\n            //2. Representa las diferentes sintaxis que existen de crear comentarios\n            //en el lenguaje (en una línea, varias...).\n\n            //Este se utiliza para escribir comentarios de una sola linea.\n            /*\n            este se utiliza para escribir comentarios de varias lineas.\n            */\n\n            //3. Crea una variable (y una constante si el lenguaje lo soporta).\n\n            private int num;\n            private const int numConst;\n\n            //4. Crea variables representando todos los tipos de datos primitivos\n            //del lenguaje (cadenas de texto, enteros, booleanos...).\n\n            //1. Enteros\n            private int num1; //numeros enteros de 32 bits.\n            private long num2; //numeros enteros de 64 bits.\n            private short num3; //numeros enteros de 16 bits.\n            private byte num4; //numeros enteros sin signo de 8 bits.\n            private sbyte num5; //numeros enteros con signo de 8 bits.\n            private uint num6; //numeros enteros sin signo de 32 bits,\n            private ulong num7; //numeros enteros sin signo de 64 bits.\n            private ushort num8; //numeros enteros sin signo de 16 bits.\n\n            //2. Float\n            private float num9; //Números de punto flotante de precisión simple (32 bits).\n            private double num10; //Números de punto flotante de doble precisión (64 bits).\n\n            //3. Decimal\n            private decimal num11; //Números decimales de alta precisión, generalmente usados para cálculos financieros (128 bits).\n\n            //4. Booleanos\n            bool jump; // Representa valores booleanos (true o false).\n\n            //5. Caracteres\n            private char Caracter; //Representa un carácter Unicode UTF-16 (16 bits).\n\n            //6. Cadenas\n            private string name; //Secuencia de caracteres Unicode.\n\n            //5. Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n            EJERCICIO ejercicio = new EJERCICIO();\n            ejercicio.saludo();\n\n        }\n        public class EJERCICIOS\n        {\n            public void Saludo()\n            {\n                Console.WriteLines(\"¡Hola, [C#]!\")\n            }\n\n        }\n    }\n}\n\nnamespace _00_SINTAXIS__VARIABLES__TIPOS_DE_DATOS_Y_HOLA_MUNDO\n{\n    internal class Program\n    {\n        static void Main(string[] args)\n        {\n            // EJERCICIO:\n            //1-Crea un comentario en el código y coloca la URL del sitio web oficial del\n            //  lenguaje de programación que has seleccionado.\n            //https://learn.microsoft.com/en-us/dotnet/csharp/\n\n            //2-Representa las diferentes sintaxis que existen de crear comentarios\n            //  en el lenguaje(en una línea, varias...).\n\n            // Esta reprenta un comentario de una linea\n            /*\n             * esta representa un comentarios de varias lineas\n             */\n\n            //3-Crea una variable(y una constante si el lenguaje lo soporta).\n\n            //4-Crea variables representando todos los tipos de datos primitivos\n            //  del lenguaje(cadenas de texto, enteros, booleanos...).\n\n            //5-Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n            EJERCICIOS ejercicios = new EJERCICIOS();\n            ejercicios.getLenguaje();\n\n        }\n        public class EJERCICIOS\n        {\n            //3-Crea una variable(y una constante si el lenguaje lo soporta).\n            private int myNum;\n            private const int numConst = 0;\n\n            //4-Crea variables representando todos los tipos de datos primitivos\n            //  del lenguaje(cadenas de texto, enteros, booleanos...).\n            private int num1; //Números enteros de 32 bits.\n            private long num2; //Números enteros de 64 bits.\n            private short num3; //Números enteros de 16 bits.\n            private byte num4; //Números enteros sin signo de 8 bits.\n            private sbyte num5; //Números enteros con signo de 8 bits.\n            private uint num6; //Números enteros sin signo de 32 bits.\n            private ulong num7; //Números enteros sin signo de 64 bits.\n            private ushort num8; //Números enteros sin signo de 16 bits.\n            private float myfloat; //Números de punto flotante de precisión simple(32 bits).\n            private double num_double; //Números de punto flotante de doble precisión(64 bits).\n            private decimal num_decimal; //Números decimales de alta precisión, generalmente usados para cálculos financieros(128 bits).\n            private bool boolean; //Representa valores booleanos(true o false).\n            private char char1; //Representa un carácter Unicode UTF-16 (16 bits).\n            private string name; //Secuencia de caracteres Unicode.\n\n            public void getLenguaje()\n            {\n                Console.WriteLine(\"¡Hola, [C#]!\");\n            }\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/RXVLC.cs",
    "content": "﻿using System;\n\n/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\nnamespace R00\n{\n    internal class Program\n    {\n        static void Main(string[] args)\n        {\n            //https://learn.microsoft.com/en-us/dotnet/csharp/\n\n            //Comentario en una linea\n\n            /* \n             * Comentario\n             * en varias\n             * lineas\n             * */\n\n            string prueba1 = \"\";\n            const string prueba2 = \"prueba\";\n\n            string cadenaDeTexto = \"Esto es una cadena de texto\";\n            int numeroEntero = 3;\n            double numeroConDecimales = 10.2;\n            bool variableBooleana = false;\n            string nombreLenguaje = \"C#\";\n\n            Console.WriteLine($\"¡Hola, {nombreLenguaje}!\");\n\n            Console.ReadKey();\n\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/RocaDev2714.cs",
    "content": "﻿//La pagina web oficial es: https://learn.microsoft.com/es-es/dotnet/csharp/\n\n//Tipos de Comentarios\n//--------------------\n//Comentario de una Linea\n\n/*Comentario de\n  bloque\n*/\n\n///<summary>\n///Comentario XML\n/// </summary>\n\nint variable = 6;\nconst int constante = 100;\n\nbyte numeroByteMin = 0;\nbyte numeroByteMax = 255;\n\nsbyte numeroSbyteMin = -128;\nsbyte numeroSbyteMax = 127;\n\nshort numeroShortMin = -32768;\nshort numeroShortMax = 32767;\n\nushort numeroUshortMin = 0;\nushort numeroUshortMax = 65535;\n\nint numeroIntMin = -2147483648;\nint numeroIntMax = 2147483647;\n\nuint numeroUintMin = 0;\nuint numeroUintMax = 4294967295;\n\nlong numeroLongMin = -9223372036854775808;\nlong numeroLongMax = 9223372036854775807;\n\nulong numeroUlongMin = 0;\nulong numeroUlongMax = 18446744073709551615;\n\nfloat numeroFloat = 3.14f;\n\ndouble numeroDouble = 3.14;\n\ndecimal numeroDecimal = 3.14m;\n\nchar caracter = 'C';\n\nbool verdaderoFalso = true;\n\nstring cadena = \"Cadena de Texto\";\n\nConsole.WriteLine(\"¡Hola, C#!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/SBS24.cs",
    "content": "﻿//Author: Sandra Baigorri Saez\nusing System;\n\nnamespace _00\n{\n    internal class Program\n    {\n        static void Main(string[] args)\n        {\n            //Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n            //https://learn.microsoft.com/es-es/dotnet/csharp/\n\n            //Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje(en una línea, varias...).\n            // COMENTARIO EN UNA LINEA\n            /* COMENTARIO EN VARIAS LINEAS COMENTARIO EN VARIAS LINEAS COMENTARIO EN VARIAS LINEAS \n              COMENTARIO EN VARIAS LINEAS COMENTARIO EN VARIAS LINEAS \n              COMENTARIO EN VARIAS LINEAS COMENTARIO EN VARIAS LINEAS COMENTARIO EN VARIAS LINEAS  */\n            /// COMENTARIOS DE DOCUMENTACIÓN XLM\n\n            //Crea una variable(y una constante si el lenguaje lo soporta).\n            int variable = 0;\n            const int constante = 0;\n\n            //Crea variables representando todos los tipos de datos primitivos del lenguaje(cadenas de texto, enteros, booleanos...).\n            string cadena = \"\";\n            char caracter = ' ';\n            bool booleano = false;\n            int entero = 0;\n            short entero_peque = 0;\n            long entero_grande = 0;\n            float decimal_peque = 0;\n            double decimales = 0;\n            decimal decimal_grande = 0;\n\n            //Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n            Console.WriteLine(\"¡Hola, c#!\");\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/Wilibac.cs",
    "content": "\nclass Wilibac\n{\n    static void Main(string[] args)\n    {\n        // https://dotnet.microsoft.com/es-es/languages/csharp\n\n        // Comentario de una línea\n\n        /* Comentario\n            de varias\n            líneas\n        */\n\n        /// <summary>\n        /// Esto es un comentario de documentación\n        /// </summary>\n        /// <returns></returns>\n\n        string greeting = \"Hola\";\n        const int Months = 12;\n\n\n        // Tipos de datos\n        int employees = 50;\n        byte age = 10;\n        float rate = 60.5f;\n        double numberHours = 5250.2\n        decimal income = 2856.65m;\n        char symbol = '@';\n        bool isTrue = true;\n        string hello = \"Hola\";\n\n        System.Console.WriteLine($\"{greeting} C#\");\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/XPERIARGLUNA.cs",
    "content": "using System;\n\n// https://learn.microsoft.com/en-us/dotnet/csharp\n//Comentario de una sola línea\n/* Comentario en\n  varias \n  lineas \n */\n\nint My_variable = 10;\nconst double My_constant = 3.1416; \n\n//TIPOS DE DATOS\nint My_value = 6; \nfloat My_value2 = 1.5f;\ndouble My_double = 4.563;\ndecimal My_value3 = 3.9456m;\nchar My_char = 'a';\nstring My_lenguaje = \"C#\";\nbool My_bool = false;\nbool My_bool2 = true;\n\nConsole.WriteLine($\"¡Hola, {My_lenguaje}!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/YojanSamuel.cs",
    "content": "//https://microsoft.com\n\n/*\nEsto tambien \nes un comentario\n*/\n\n///Esto tambien es un comentario de varias lineas\n\n//Variables\n/*La variable se crea segun lo que necesite \npero es un espacio\ntipo nombre = valor;\n*/\n\nint edad = 17; //Esa es para números enteros\ndouble precio = 19.99; //Esa es para decimales\nstring apellido = Gomez; //Esa es para texto\n\n//Constante\n//La constante es const\nconst int = 99;\n\n//Datos primitivos\nint dia = 22;\nByte luz = 200;\nlong poblacionmundial = 79272727;\nfloat velocidad = 17.8f;\ndouble pi = 6.2789393;\nchar inicial = \"S\";\nbool juegoactivo = true;\nbool juegoactivo = false;\n\n//Imprimir texto\nconsole.WriteLine(\"¡Hola, C#!\")\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/aFacorroLoscos.cs",
    "content": "// Pagina Web de documentacion de C#: https://learn.microsoft.com/en-us/dotnet/csharp/\n//Librerias necesarias\nusing System;\n//---------\nclass Reto00\n{\n    static void Main()\n    {\n        //Comentario de codigo en 1 linea\n\n        /* Comentario\n         * de\n         * codigo\n         * varias lineas\n         */\n\n        // Declaracion de variable y constante\n        int variable = 1;\n        const int variableConstante = 1;\n\n        // Tipos de datos Primitivos\n        // Booleanos\n        bool booleanData = true;\n        // Byte,Short,Int y Long\n        byte valorByte = 99;\n        short valorShort = 100;\n        int entero = 33;\n        long valorLong = 10239L;\n        // Float, Double y Decimal\n        float numeroFlotante = 33.33F;\n        double numeroDoblePrecision = -0.213;\n        decimal decimales = 42.013M;\n        // Char\n        char caracter = 'b';\n\n        // Hello, world\n        Console.Write(\"Hola, C#!\");\n        \n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/abelsrzz.cs",
    "content": "// Documentación oficial: https://learn.microsoft.com/es-es/dotnet/csharp/\n/*\nEsto es un comentario de múltiples líneas.\n*/\n// Esto es un comentario de una sola línea\n\n\nint numeroEntero = 42;\nlong numeroLargo = 1234567890123456789L;\nfloat numeroFlotante = 3.14f;\ndouble numeroDoble = 2.71828;\ndecimal numeroDecimal = 123.456m;\n\nbool esVerdadero = true;\nbool esFalso = false;\n\nchar caracter = 'A';\n\nstring texto = \"Hola, mundo!\";\n\nDateTime fechaHoraActual = DateTime.Now;\n\nList<int> listaEnteros = new List<int>() { 1, 2, 3 };\nDictionary<string, int> diccionario = new Dictionary<string, int>();\n\nobject objetoGenerico = 42;\ndynamic variableDinamica = \"Hola, dinámico!\";\n\nConsole.WriteLine(\"Número Entero: \" + numeroEntero);\nConsole.WriteLine(\"Número Largo: \" + numeroLargo);\nConsole.WriteLine(\"Número Flotante: \" + numeroFlotante);\nConsole.WriteLine(\"Número Doble: \" + numeroDoble);\nConsole.WriteLine(\"Número Decimal: \" + numeroDecimal);\nConsole.WriteLine(\"Es Verdadero: \" + esVerdadero);\nConsole.WriteLine(\"Carácter: \" + caracter);\nConsole.WriteLine(\"Cadena de Texto: \" + texto);\nConsole.WriteLine(\"Fecha y Hora Actual: \" + fechaHoraActual);\nConsole.WriteLine(\"Lista de Enteros: \" + string.Join(\", \", listaEnteros));\nConsole.WriteLine(\"Objeto Genérico: \" + objetoGenerico);\nConsole.WriteLine(\"Variable Dinámica: \" + variableDinamica);\n\nConsole.WriteLine(\"Hola mundo!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/abrahamraies.cs",
    "content": "// Author: Abraham Raies https://github.com/abrahamraies\n\n/*\n * EJERCICIO:\n * 1. Crea un comentario en el cdigo y coloca la URL del sitio web oficial del\n *   lenguaje de programacin que has seleccionado.\n * 2. Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una lnea, varias...).\n * 3. Crea una variable (y una constante si el lenguaje lo soporta).\n * 4. Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * 5. Imprime por terminal el texto: \"Hola, [y el nombre de tu lenguaje]!\"\n*/\n\nusing System;\n\n// Ejercicio 1:\n\n// Sitio oficial de C#: https://dotnet.microsoft.com/en-us/languages/csharp\n\n// Ejercicio 2:\n\n// Comentario de una sola linea en C#\n\n/*\nComentario\nde\nvarias\nlineas\n*/\n\n/// Comentario utilizado para describir un metodo\n/// se pueden agregar variables para describir su funcion\n/// el retorno del metodo\n/// y los posibles errores.\n\n\n// Ejercicio 3:\n\nvar variable = 2;\n\nconst constante = 10;\n\n// Ejercicio 4:\n\n// Enteros(int)\n\nint intNumber = 20;\n\n// Numero de punto flotante(float)\n\n// 32 bits\nfloat floatNumber32Bits = 5.14f;\n\n// 64 bits\ndouble doubleNumber = 3.14;\n\nlong longNumber = 3.2342;\n\n// Decimal\ndecimal decimalNumber = 10.3;\n\n// Cadena de texto (String)\n\nstring stringText = \"Esto es un String\";\n\n// Caracter\n\nchar charText = 'C';\n\n// Booleanos (bool)\n\nbool booleanTrue = true;\nbool booleanFalse = false;\n\n// Ejercicio 5:\n\nclass abrahamraies\n{\n\tstatic void Main(string[] args)\n\t{\n\t\tstring lenguaje = \"C#\";\n\t\tConsole.WriteLine($\"Hola, {lenguaje}!\");\n\t}\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/analianovoa.cs",
    "content": "using System;\npublic class Program\n{\n\t/// <summary>\n\t/// Método que imprime un saludo en la consola.\n\t/// </summary>\n\tpublic void Saludar()\n\t{\n\t\tConsole.WriteLine(\"¡Hola, mundo! Con comentario para documentación XML\\n\");\n\t}\n\n\tpublic static void Main()\n\t{\n\t\tConsole.WriteLine(\"** Sitio oficial C#: https://dotnet.microsoft.com/es-es/languages/csharp\\n\");\n\t\tConsole.WriteLine(\"* Comentarios: https://learn.microsoft.com/es-es/dotnet/csharp/language-reference/tokens/comments\\n\");\n\n\t\t// Este es un comentario de una sola línea\t\t\t\n\t\tConsole.WriteLine(\"¡Hola, mundo! Con comentario de una sola línea.\"); // También se puede colocar al final de una línea de código\n\n\t\t/* Este es un comentario\n\t\t de varias líneas.\n\t\t Puede abarcar múltiples líneas. */\n\t\tConsole.WriteLine(\"¡Hola, mundo! Con comentario de varias líneas.\");\n\n\t\tProgram programa = new Program();\n\t\tprograma.Saludar();\n\n\t\t//Declaración implícita con var.\n\t\tConsole.WriteLine(\"* Tipos de datos primitivos: https://learn.microsoft.com/es-es/dotnet/csharp/language-reference/builtin-types/built-in-types\\n\");\n\t\tConsole.WriteLine(\"* Declaración implícita con var.\\n\");\n\t\tvar numero = 10;        // Se infiere como int\n\t\tvar precio = 99.99;     // Se infiere como double\n\t\tvar mensaje = \"¡Hola!\"; // Se infiere como string\n\t\tConsole.WriteLine(\"var numero = 10;        // Se infiere como int\");\n\t\tConsole.WriteLine(\"var precio = 99.99;     // Se infiere como double\");\n\t\tConsole.WriteLine($\"var mensaje = \\\"{mensaje}\\\"; // Se infiere como string\\n\");\n\n\t\tConsole.WriteLine($\"{numero},{precio},{mensaje}\\n\");\n\n\t\t//Declaración explícita con tipos primitivos\n\t\tConsole.WriteLine(\"* Declaración explícita con tipos primitivos\\n\");\n\t\tint numeroEntero = 10;\n\t\tdouble precioDecimal = 99.99;\n\t\tbool esActivo = true;\n\t\tchar letra = 'A';\n\t\tstring mensajeString = \"¡Hola, mundo!\";\n\t\tConsole.WriteLine(\"int numeroEntero = 10;\");\n\t\tConsole.WriteLine(\"double precioDecimal = 99.99;\");\n\t\tConsole.WriteLine(\"bool esActivo = true;\");\n\t\tConsole.WriteLine(\"char letra = 'A';\");\n\t\tConsole.WriteLine($\"string mensajeString = \\\"{mensajeString}\\\";\\n\");\n\t\tConsole.WriteLine(numeroEntero);\n\t\tConsole.WriteLine(precioDecimal);\n\t\tConsole.WriteLine(esActivo);\n\t\tConsole.WriteLine(letra);\n\t\tConsole.WriteLine(mensajeString + \"\\n\");\n\n\t\t//Declaración de constantes (const)\n\t\tConsole.WriteLine(\"* Declaración de constantes(const)\\n\");\n\t\tconst double PI = 3.1416;\n\t\tconst string saludo = \"¡Hola, mundo!\";\n\t\tConsole.WriteLine(\"const double PI = 3.1416;\");\n\t\tConsole.WriteLine($\"const string saludo = \\\"{saludo}\\\";\\n\");\n\t\tConsole.WriteLine(PI);\n\t\tConsole.WriteLine(saludo + \"\\n\");\n\n\n\t\tConsole.WriteLine(\"¡Hola, C# !\");\n\t}\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/angel-tineo.cs",
    "content": "﻿//https://dotnet.microsoft.com/en-us/\n\n//Ejemplo de comentario simple\n/*\n    Ejemplo comentarios\n    en varias lineas\n*/\n\nvar Variable = 1;\nconst int CONSTANTE = 3;\n\nint MyInt = 2;\nfloat MyFlot = 3.14f;\ndouble MyDoble = 3.14;\nbool MyBool = true;\ndecimal MyDecimal = 1.5m;\nchar MyChar = 'a';\nstring MyString = \"Cadena\";\n\nConsole.WriteLine(\"Hola, C#\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/angelsanchezt.cs",
    "content": "// Sitio Oficial del Lenguaje C#\n// https://dotnet.microsoft.com/en-us/learn/csharp\n\n// Comentario en una línea\n\n/*\n    Comentario de varias líneas\n    ----------------\n    Escribir su primera aplicación: https://aka.ms/dotnet-hello-world\n    Descubra las novedades: https://aka.ms/dotnet-whats-new\n    Explore la documentación: https://aka.ms/dotnet-docs\n    Notificar problemas y encontrar el origen en GitHub: https://github.com/dotnet/core\n*/\n\n/// <summary>\n/// Este es un comentario de Documentación XML\n/// </summary>\n\n/*\n    En C#, puedes utilizar el scripting con el apoyo de dotnet-script. \n    Asegúrate de tener dotnet-script instalado en tu máquina para ejecutar este tipo de programas.\n\n    1. Instalación del SDK de .NET, la ultima versión estable .NET 8.0\n\n    2. Instalación de dotnet-script: Abre la línea de comandos y ejecuta el siguiente comando para instalar dotnet-script.\n        dotnet tool install -g dotnet-script\n    \n    3. Ejecuta el script usando dotnet-script:\n        dotnet script angelsanchezt.cs\n*/\n\n// Convenciones de Codigo en C#\n// https://learn.microsoft.com/es-es/dotnet/csharp/fundamentals/coding-style/identifier-names\n// Use PascalCase para los nombres de clase y los nombres de método.\n// Use camelCase para los argumentos de método, las variables locales y los campos privados.\n// Use PascalCase para los nombres de las constantes, tanto campos como constantes locales.\nvar miVariable = \"Variable de Tipo String\";\n\n// https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/const\nconst string MiConstante = \"Constante: una variable que no puede cambiar su valor\";\n\n// Tipos de datos primitivos\n\n// Tipos numéricos enteros\n// https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/integral-numeric-types\nint numeroEntero = 512;\nlong numeroLargo = 12345690123456L;\nshort numeroCorto = 12;\nbyte numeroByte = 165;\n\n// Tipos numéricos de punto flotante\n// https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/floating-point-numeric-types\nfloat numeroFlotante = 3.14f;\ndouble numeroDoble = 3.14159265359;\ndecimal numeroDecimal = 123.456m;\n\n\n// Tipo carácter\n// https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/char\nchar caracter = 'A';\n\n// Tipo booleano\n// https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool\nbool esVerdadero = true;\n\n// Referencia nula\nstring referenciaNula = null;\n\n// https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/reference-types#the-string-type\nstring cadenaCaracteres = \"AngelSanchezT\";\n\nstring nombreLenguaje = \"C#\";\nConsole.WriteLine($\"¡Hola, {nombreLenguaje}!\");\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/angelsoft01.cs",
    "content": "namespace ConsoleApp1\n{\n    internal class Program\n    {\n        static void Main(string[] args)\n        {\n            Console.WriteLine(\"Hello, World!\");\n\n            Console.WriteLine(\"https://visualstudio.microsoft.com/es/downloads/\");\n            // mi primer comentario\n            /* este \n             * es \n             * mi \n             * comentario en multilpes lineas\n             */\n            int x = 1;\n            float y = 1.2f;\n\n            bool boleanoverdadero = true;\n            bool boleanofalso = false;\n\n            char letra = 'a';\n\n            string saludos = \"buenas, buenas\";\n            string nombre = \"Jamyr\" + saludos;\n\n            Console.WriteLine(\"Hola, C#\");\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/arkmiguel379.cs",
    "content": "﻿//https://learn.microsoft.com/es-es/dotnet/csharp/\n\n//Este es un comentario de una sola linea en C#\n\n/* Este es un comentario\n   de varias lineas en C#*/\n\nstring lenguaje = \"CSharp\";\nconst double myConstante = 3.14;\n\nint entero = 379;\nstring cadena = \"Esto es un a cadena de texto\";\nchar caracter = 'M';\nbool booleanD = true;\nfloat flotante = 13.5f;\ndouble doble = 33.79;\nlong numLargo = 379257172839465L;\ndecimal numDecimal = 15.9M;\n\nConsole.WriteLine($\"Hola {lenguaje}\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/astriebeck.cs",
    "content": ""
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/carresoft.cs",
    "content": "// - Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n// https://learn.microsoft.com/es-es/dotnet/csharp/\n\n// - Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n// Una sola línea de comentario\nint numero = 1; // Comentario final de una línea\nint suma = numero /* Comentario entre código */ + 1;\n/*\n Comentarios de varias\n líneas\n*/\n\n// - Crea una variable (y una constante si el lenguaje lo soporta).\nint numero1 = 1;\nconst double pi = 3.1415926535;\n\n// - Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\nbyte var1 = 255;\nsbyte var2 = 127;\nshort var3 = 32767;\nushort var4 = 65535;\nint var5 = 2147483647;\nuint var6 = 4294967295;\nlong var7 = 9223372036854775807;\nulong var8 = 18446744073709551615;\nchar var9 = 'A';\nbool var10 = true;\nfloat var11 = 3.402823e38f;\ndouble var12 = 1.79769313486232e38;\ndecimal var13 = 7.9e28M;\n\n// - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nstring lenguaje = \"C#\";\nConsole.WriteLine($\"¡Hola, {lenguaje}!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/charlerodriguez3.cs",
    "content": "\n/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n// Url C# : https://dotnet.microsoft.com/es-es/languages/csharp\n\n// Single line comment -> //\n\n/*\nThis is a comment of two or more lines\nasdasdasd */\n\n\n//numeros\n\n//integer ordered from the lowest to the largest ocuppation of memory\nsbyte edad = 120;\nshort number1 = 10500;\nint number2 = 2;\nlong trillion = 15004040404; // Not an actual trillion\n\n\n//float It's necessary to put F in upper so the interpreter doesn't makea problem with the number\n//of double type (less precision)\nfloat numberFloat = 2.5555F;\n\n//double (more precision than the float one)\ndouble numberDouble = 3.04;\n\n//decimal It's necessary to put M in upper \n//so the interpreter doesn't make a problem with the number of double type (More precision Required for Contable or Financial Use)\ndecimal numberDecimal = 5.23M;\n\n\n//boolean\nbool isItComplicated=false;\n\n//char Only one character from keyboard: It goes between single quotation marks\nchar letter = 'a';\n\n//string two or more characters: It goes between double quotation marks\nstring style = \"Cool\";\n\n//Print a string\nConsole.WriteLine(\"¡Hola, C#!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/chrisfelixgil.cs",
    "content": "﻿using System;\nusing System.Runtime.InteropServices;\n\nclass sintaxisVariables\n{\n    static void Main()\n    {\n        /*\n        * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n        * - Recuerda que todas las instrucciones de participación están en el\n        *   repositorio de GitHub.\n        *\n        * Lo primero... ¿Ya has elegido un lenguaje?\n        * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n        * - Este primer reto te servirá para familiarizarte con la forma de participar\n        *   enviando tus propias soluciones.\n        *\n        * EJERCICIO:\n        * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n        *   lenguaje de programación que has seleccionado.\n        * - Representa las diferentes sintaxis que existen de crear comentarios\n        *   en el lenguaje (en una línea, varias...).\n        * - Crea una variable (y una constante si el lenguaje lo soporta).\n        * - Crea variables representando todos los tipos de datos primitivos\n        *   del lenguaje (cadenas de texto, enteros, booleanos...).\n        * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n        *\n        * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n        * debemos comenzar por el principio.\n        */\n\n        //Ejercicio\n\n        //El leguaje de programación que estoy utilizando es C#: https://learn.microsoft.com/en-us/dotnet/csharp/\n\n        //Esto es para crear comentarios de una linea.\n\n        /*\n         * Así \n         * Se crean\n         * Comentarios de \n         * Varias Lineas\n         *  \n         */\n\n        /// <summary>\n        /// Esto es un comentario en formato XML\n        /// </summary>\n\n        //Variable\n        string variable = \"Esto es una variable\";\n\n        //Constante (Por convención, las constantes se declaran con nombre en MAYÚSCULAS)\n        const double PI = 3.1416d;\n\n        //Variables con todos los tipos de datos primitivos\n        //Cadena de texto\n        string maquina = \"Esto es una variable de texto\";\n\n        //Variables para representar numero decimales\n        //Para representar decimales grandes\n        double pi = 0.0d;\n\n        //Para representar decimales pequeños\n        float numeroFlotante = 0.0f;\n\n        //Para representar decimales muy exactos\n        decimal numeroDecimalExacto = 0.0m;\n\n        //Variable para representar números enteros\n        int num = 5;\n\n        //Variable boolean, true or false\n        bool verdaderoOfalso = true;\n\n        //Arreglos\n        //Arreglo de enteros de tamaño fijo\n        int[] numero = [5];\n\n        //Arreglo inicializado\n        int[] numeros = [5, 6, 3];\n        string[] supermercado = [\"aguacate\", \"papas\", \"Peras\", \"MANZANAS\"];\n        object[] arreglo = [1, \"Peras\", \"uvas\", 24, 23.5, \"Libro\"];\n\n        //Tuplas\n        (int, string) par = (1, \"Hola\");\n\n        //Hola Mundo\n        Console.WriteLine(\"¡Hola, C#!\");\n\n\n\n\n\n\n    }\n}\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/cristopherfdev.cs",
    "content": "//Comentario en C#. Web Oficial: https://dotnet.microsoft.com/en-us/languages/csharp\n\n// En C# podemos crear comentarios con dos barras \n\n/* También podemos crear un comentario \nde varias lineas con barra y signo de multiplicación*/\n\n//Creación de variable y constante \n\nint primerNumero = 12;\nconst int segundoNumero = 5; \n\n//Tipos de variables en C# \n\nint tercerNumero = 10; \nstring miTexto = \"Hello World\"; \ndouble cuartoNumero = 12.3; \ndecimal quintoNumero = 75.53m; \nchar myChar = 'C'; \nbool posivito = true; \nbool negativo = false; \nfloat myFloat = 15.5f; \n\nConsole.WriteLine (\"¡Hola C#!\"); \n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/daeduol.cs",
    "content": "//comentario de una sola linea \n\n/*cometario de 2\no mas lineas\n*/\n/* https://dotnet.microsoft.com/es-es/languages/csharp\nhttps://learn.microsoft.com/en-us/dotnet/csharp/\n*/\nclass daeduol{\n//variables y constantes\ndynamic myDynamic = 6;\nconst string MyConst = \"mi constante\";\nstring myString = \"Esto es una cadena de texto\";\nvar myVar = \"variable de tipo inferido\";\n//tipos de datos primitivos\nbyte number8 = 1;\nshort number16 = -32768;\nint myInt = 7;\nlong number64 = 2147483647;\nfloat myFloat = 6.5f;\ndouble myDouble = 3.0;\nchar char16 = 'a';\nbool myBoolean = true;\npublic static void Main(string[] args)\n{\nSystem.Console.WriteLine(\"¡Hola, C#!\");\n}\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/devcherry1.cs",
    "content": "\nusing System;\n\nclass Program\n{\n    static void Main()\n    {\n        //https://dotnet.microsoft.com/es-es/languages/csharp\n        /*\n        Comentario multilinea\n        */\n        const string so = \"Windows\";\n        var nombre = \"Juan\";\n        int edad = 68;\n        double altura = 1.90;\n        bool casado = true;\n        char interes = '$';\n        string[] peliculas = { \"Endgame\", \"Infinity war\" };\n\n        Console.WriteLine(\"¡Hola, C#!\");\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/edalmava.cs",
    "content": "// Comentario de una línea\n// Sitio oficial: https://dotnet.microsoft.com/es-es/languages/csharp\n\n/* \n   Comentario de \n   varias líneas\n*/\n\n// Declaración de variables\nbyte entero0a255 = 5;\nsbyte enteroConSigno127 = -5;\nshort enteroPequeño = 5000;\nint entero = 5;\nlong enteroLargo = 5_000_000;\nfloat flotante = 5000.0f;\ndouble doble = 5.0;\ndecimal decimalv = 5.0M;\n\nbool verdadero = true;\nbool falso = false;\n\nstring hola = \"Hola\";\nchar caracter = 'A';\n\n// Constantes\nconst string lenguaje = \"C#\";\n\nConsole.WriteLine($\"¡{hola}, {lenguaje}!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/estuardodev.cs",
    "content": "// #00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n/* \n    Sitio web oficial de C#\n    https://dotnet.microsoft.com/es-es/languages/csharp\n*/\n\nusing System;\nusing System.Threading.Tasks;\n\nclass estuardodev\n{\n    private static string _Greeting = \"Hola\";\n    private const string _Lenguage = \"C#\";\n    private static int _Year = 2024;\n    private static char _Comma = ',';\n    private static long _EarthYears = 45400000;\n    private static double _PiMedium = 3.14159265359;\n    private static float _PiShort = 3.14f;\n    private static bool _Susbscribed = true;\n\n    public static void Main(string[] args)\n    {\n        Console.WriteLine($\"¡{_Greeting}{_Comma} {_Lenguage} en Retos de Programación {_Year}!\");\n        }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/fgxmboa.cs",
    "content": "// https://dotnet.microsoft.com/en-us/languages/csharp\n/*  Comentario\n    de \n    varias\n    lineas\n*/\nusing System;\nclass Reto00{\n    static void Main(string[] args){\n        string variable = \"fgxmboa\";\n        const int edad_actual = 28;\n\n        int enteros;\n        long enteros_grandes;\n        float flotantes;\n        double dobles;\n        decimal decimales;\n        string cadena_texto;\n        char caracter_unico;\n        bool booleanos;\n\n        Console.Write(\"Hola, C#\");\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/gomezcamilo9701.cs",
    "content": "using System;\n\nnamespace CeroCero\n{\n    class CeroCero\n    {\n        static void Main(string[] args)\n        {\n            //https://dotnet.microsoft.com/es-es/languages/csharp\n            //Comentario\n            /* O Comentario*/\n            var variable = \"la variable ve\";\n            const string CONSTANTE = \"Constantebrrr\";\n            double doublee = 2.3;\n            int inttt = 2;\n            float floattt = 1.2f;\n            decimal decimalll = 12.2m;\n            bool bolll = true;\n            int[] intArray = {1,2,3,4};\n            (int, string) tuplaa = (2, \"tupla\");\n            Console.WriteLine(\"¡Hola, C#!\");\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/gquintal.cs",
    "content": "//https://dotnet.microsoft.com/es-es/languages/csharp\n\n//comentario en una linea\n\n/*\n  Comentario en varias lineas\n*/\n\n//variables\nint edad = 25;\nstring nombre = \"Gustavo\";\ndouble altura = 1.75;\n\n//constantes\nconst double PI = 3.1416;\nconst int Dias_Semana = 7;\nconst string Saludo = \"Hola Mundo\";\n\n//datos primitivos\nint myInt = 10;\nlong myLong = 20;\nshort myShort = 30;\nbyte myByte = 40;\nfloat myFloat = 50.5f;\ndouble myDouble = 60.6;\ndecimal myDecimal = 70.7m;\nchar myChar = 'A';\nstring myString = \"Hola Mundo\";\nbool myBool = true;\n\n\nConsole.WriteLine(\"Hola Mundo\"); //Imprimir en la consola\n\n//Obtener el tipo de dato de una variable\nConsole.WriteLine($\"El tipo de dato de la variable edad es: {edad.GetType()}\"); //Imprimir en la consola\nConsole.WriteLine($\"El tipo de dato de la variable nombre es: {nombre.GetType()}\"); //Imprimir en la consola\nConsole.WriteLine($\"El tipo de dato de la variable altura es: {altura.GetType()}\"); //Imprimir en la consola"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/hazartd.cs",
    "content": "//Pues no me da por poner aqui la url. XD. Anotare el titulo de la pull «#00 - C#»\n/*\nEsa doble diagonal toma por comentario el resto de la linea\nMientras que «/*» abre un comentario de varias lineas y «* /» lo cierra\nDe hecho, lo he tenido que poner separado (a diferencia de como se nota al final del comentario) porque se tomaba como cierre.\nOsea, lo que haya de esos 2 signos en adelante si se ejecutara, al menos segun github. Tenerlo en cuenta\n*/\n\n/// <summary>\n/// Esto es un comentario de documentación\n/// </summary>\n/// <returns></returns>\n\nusing System; //No termino de entender para que es el using, pero a finales del ejercicio estudie los otros que se enviaron\nusing System.Collections.Generic; //para ver si me faltaban tipos\nusing System.Linq; //y casi todos tenian estas cosas al mero inicio.\nusing System.Text;\nusing System.Threading.Tasks;\n\n//Variables\n////Puden escribirse asi nomas como el primer ejemplo, o con «private» y «public» segun el caso, ya que eso define desde que partes el codigo puedes acceder a la variable\nstring NombreDeVariable = \"Para poner una variable basta con poner el tipo de dato y su nombre. En esta el tipo es «string»\"; //se usa «PascalCase» para nombrar las cosas, consiste en poner cada primer letra en mayuscula\n\nconst string NOMBRECONSTANTE = \"Poner «const» antes del tipo hace que sea una constante\"; //solo pueden tener constantes de los tipos de estructura simple y se nombra con pura mayuscula\n\nenum WeekDays { Monday, Tuesday, Wednsday, thursday, Friday, Saturday, Sunday}; //esto ya es una estructura de valores y no puede ser constante.\n//aunque una manera de definir que es un enum, es «Un diccionario constante con claves string y valores int», segun tengo entendido\n\nstring? String_Nulleable = null //si pones un «?» despues del tipo la variable podra tener valores null, osea, nulo.\n\nint[] Array = new int[5]; // cuando despues del tipo se pone «[]» es un array o arreglo, se debe poner un «new» seguido por el tipo y entre los «[]» el numero de espacios que tiene\nstring [] Array2 = new string[] { \"cocina\", \"baño\", \"salon\", \"comedor\", \"dormitorio\" }; // aqui observamos un array de tipo string tambien con 5 posiciones pero ya con su valor\n//si no pones los valores de cada espacio agarra el predeterminado. Puedes escribir «Array[posision]=» para cambiar cualquier posicion pero el total de datos no pueden aumentar ni disminuir\n\nint[,] MultiDimencional = new int[2, 3]; // los valores se refieren a 2 Filas, 3 Columnas\nint[,,] MultiDimencional2 = new int[,,] { { { 1, 2, 3 }, { 4,   5,  6 } }, //Cada coma al incio junto al tipo indica una dimencion mas\n                                        { { 7, 8, 9 }, { 10, 11, 12 } } }; //para tomar los valores de estas debes poner el index de cada dimencion: Multidimencional2[1,2,3] es el 6\nvar NoSeQueEsEstoTodavia = \"al poner «var» se puede poner cualquier tipo de valor y el compilador identificara cual es y lo asignara\";\ndynamic puede_ser_lo_que_sea = \"poniendo «dynamic» se puede cambiar el tipo de dato al cambiar el valor\"; //en la doc note que para estas usan todo minusculas y separa con «_»\n\n\n//Tipos de datos\n////Numeros. cada variable tiene el valor maximo o minimo que puede tener el tipo de dato\n//////Se pueden usar «_» para separar los numeros y facilitar la lectura.\npublic byte UnNumeroDe1BytePorDefecto = 255; //es el numero mas alto que puede tener un solo byte, osea, 8 bits\npublic sbyte UnNumeroDe1BytePositivo = 127; //con la s al principio, se indica que tiene valores negativos. Pero al seguir siendo un solo byte, se recorta a la mitad su valor maximo.\npublic sbyte UnNumeroDe1ByteNegativo = -128; //\n\npublic short UnNumeroDe2BytesMax = 32_767; //como indica, estos pueden almacenar numeros de 2 bytes, osea, 16 bits.\npublic short UnNumeroDe2BytesMin = -32_768;\npublic ushort UnNumeroDe2BytesSoloPositivo = 65_535; //con esa u, estos no pueden tener negativos\n\npublic int UnNumeroPositivo = 2_147_483_647; //el int soporta numeros de 32 bits (4 bytes), positivos y negativos\npublic int UnNumeroNegativo = -2_147_483_648; //\npublic uint UnNumeroSoloPositivo = 4_294_967_295; //con esa u, se indica que solo tiene valores positivos\n\npublic long NumerosMasGrandesPositivo = 9_223_372_036_854_775_807; // Estos son de 64 bits, osea de 8 bytes\npublic long NumerosMasGrandesNegaivo = -9_223_372_036_854_775_808; //\npublic ulong NumerosMasGrandesSoloPositivo = 18_446_744_073_709_551_615; // La u indica que solo puede tener positivos. ¡No te lo esperabas, ¿vea?!\n\n//Creo yo, por el tema de exponentes de 2 y tal, que los numeros positivos tienen un valor absoluto menor porque en ellos cuentan el cero.\n//Dado que, los «u» pueden tener cero y no negativos.\n\npublic nint NumeroNativo; //con la «n» al incio de un int o uint, se usaran los numeros nativos del programa\npublic nuint NumeroNativo; //si se corre en una compu de 32bits funcionara como int/uint normal, si es de 64bits funcionara como long/ulong\n\npublic float UnDecimal =0.0f; //tiene una precicion de 6 a 9 dígitos aproximadamente, ya que usa 4 bytes. Termina con una f\npublic double UnDecimalMejor = 0.0; //es mas preciso usando 8 bytes, de 15 a 17 dígitos aproximadamente\npublic decimal ElMejorDecimal = 0.0m; //con 16 bytes es el tipo de decimal mas preciso, de 28-29 dígitos. Termina con una m\n/* En este no pongo los valores maximos y minimos porque lo que pone la documentacion es esto:\nfloat: De ±1,5 x 10^-45 a ±3,4 x 10^38\ndouble: De ±5,0 × 10^−324 a ±1,7 × 10^308\ndecimal: De ±1,0 x 10^-28 to ±7,9228 x 10^28\nPero, cada tipo de numero decimal tiene sus constantes, citando doc: «Por ejemplo, el tipo double ofrece las siguientes constantes: Double.NaN, Double.NegativeInfinity y Double.PositiveInfinity»\nAdemas, las tres tienen «MinValue» y «Max value» para representar esos numeros de arriba.\nAl final del ejercicio estos seran mostrados por la consola por si interesa y para mostras como poner esos datos en medio del mensaje, ya que me lo encontre mientras buscaba lo demas\n*/\n\npublic bool Verdadero = True; //estos son valores que solo cambian entre verdadero y falso\npublic bool Falso = False; //se deben poner los valores con la primera mayuscula\npublic bool Tambien_false = 0;//tambien, cuando se asigna sus valor se pueden poner numeros, 0 es false y cualquier otro es true\npublic bool Tambien_true = 31;\n\npublic char UnaSolaLetra = 'j'; //es como una string de solo 2 byte, por tanto, es solo una letra. Como representa los caracteres Unicode UTF-16\n//internamente tiene valores de 0 a 65_535 (U+0000 a U+FFFF, en unicode). Notaras que en eso es como el ushort, pero no se pueden pasar valores numericos a char\n//creo que era importante que para estos se usen las comillas simples\npublic char OtraLetra = NombreDeVariable[0]; //un char tambien puede hacerse tomando una letra de una string de este modo\nvar chars = new[] //para mostrar como funciona, todas estas siguen representando «j»\n{\n    (char)106,\n    '\\u006A', //esto es unicode, se debe poner «\\u» seguido de los 4 digitos hexadecimales\n    '\\x006A', //sin embargo, poniendo  «\\x» se identifica un codigo hexadecimal y se pueden omitir todos los ceros a la izquierda\n    '\\x06A', //haciendo que estas 3\n    '\\x6A', //tambien sean el mismo codigo\n};\n\n/*\nC# tiene 2 tipos de variable, las de valor (la mayoria de ejemplos de arriba) y las de referencia. La primeras almacenan su valor, y las otras tienen referencias a un objeto\nlos tipos para declarar variables de referencia son: class, interface, delegate, record, dynamic, object y string.\nLas arrays mencionadas al principio tambien son variables de referencia\nIncluyo esto porque la string entra en lo de variables primitivas (creo).\nAl ser de referencia, las variables strings guardan referencia a una cadena de char. 2 o mas variables pueden tener referencia a la misma instancia, si cambia una cambian todas\nPero, no por ser iguales refieren a la misma instancia. Por ejemplo:\n*/\npublic string a = \"hello\";\npublic string b = \"h\";\nb += \"ello\";\n/*\nAl final a y b tienen el mismo valor por lo cual, al comparar «a==b» dara true\nPero con object.ReferenceEquals(a, b) dara false, ya que siguen referenciando una instancia de string distinta\n*/\n\n/*Valores predeterminados\nCada tipo de dato tiene su valor predeterminado, si despues del nombre no asignas un valor, la varible toma el predeterminado\n\nTodos los tipos numericos, tanto enteros como decimales, tienen el 0.\nbool = false\nchar = '\\0'\ny todos los tipos que acepten null son null, incluye a los que les pones «?» cuando las declaras\n*/\n\nclass Program {\n    static void Main() { //por algun motivo, Main todos los que lo subian lo hacian con «string[] args», pero a mi el compilador que agarre para probar me lo deja usar asi\n        Console.WriteLine(\"¡Hello, C#!\");\n        Console.WriteLine(\"Hoy si, aqui esta la URL: https://learn.microsoft.com/es-es/dotnet/csharp/ .XD\");\n        Console.WriteLine(\"El valor maximo de float es: {0}\"+\" Y su minimo es {1}\", float.MaxValue, float.MinValue);\n        Console.WriteLine(\"El valor maximo de double es: {0}\"+\" Y su minimo es {1}\", Double.MaxValue, Double.MinValue);\n        Console.WriteLine(\"El valor maximo de decimal es: {0}\"+\" Y su minimo es {1}\", Decimal.MaxValue, Decimal.MinValue);\n    }\n} //ahorita lo voy a subier y me da que se olvida algo, pero de extrañar seria si lo he revisado 3 veces\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/hequebo.cs",
    "content": "// https://learn.microsoft.com/en-us/dotnet/csharp/\n\n// Este es un comentario en una sola línea\n\n/*\n Este es un \n comentario en \n múltiples líneas\n*/\n\nint myVar = 1;\nconst int myConst = 2;\n\n\n\n// Tipos de Datos\nint myInt = 3;\nfloat myFloat = 4.451354f;\ndouble myDouble = 3.1546;\ndecimal myDecimal = 1.3333m;\nchar myChar = 'C';\nstring myString = \"Hequebo\";\nbool myBool = false;\nstring languageName = \"C#\";\n\nConsole.WriteLine($\"¡Hola, {languageName}!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/isaacus98.cs",
    "content": "﻿/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\nnamespace RetosProgramacion2024\n{\n    internal class Reto0\n    {\n        static void Main(string[] args)\n        {\n            // https://learn.microsoft.com/es-es/dotnet/csharp/\n            // Comentario de una linea\n            /* Comentario de \n             * varias\n             * lineas\n             */\n\n            //Crear variable y constante\n            int a = 1;\n            const int b = 2;\n\n            // Tipos primitivos\n            sbyte mySbyte = 1;\n            byte myByte = 1;\n            short myShort = 1;\n            ushort myUShort = 1;\n            int myInt = 1;\n            uint myUInt = 1;\n            long myLong = 1;\n            ulong myULong = 1;\n            float myFloat = 1;\n            double myDouble = 1;\n            decimal myDecimal = 1;\n            char myChar = '\\0';\n            bool myBoolean = false;\n\n            Console.WriteLine(\"¡Hola, C#!\");\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/isco-mtz.cs",
    "content": "using System;\nnamespace retoProgramacion2025\n{\n    internal class reto00\n    {\n        static void Main(string[] args)\n        {\n            // https://learn.microsoft.com/es-es/dotnet/csharp/tour-of-csharp/overview\n            // Comentario de una linea\n\n            /* Comentario de \n             * varias\n             * lineas\n             */\n\n            //Crear variable y constante\n            int entero = 1;\n            const int constanteEntero = 2;\n\n            // Tipos primitivos\n            sbyte mySbyte = 1;\n            Console.WriteLine(mySbyte);\n            byte myByte = 1;\n            Console.WriteLine(myByte);\n            short myShort = 1;\n            Console.WriteLine(myShort);\n            ushort myUShort = 1;\n            Console.WriteLine(myUShort);\n            int myInt = 1;\n            Console.WriteLine(myInt);\n            uint myUInt = 1;\n            Console.WriteLine(myUInt);\n            long myLong = 1;\n            Console.WriteLine(myLong);\n            ulong myULong = 1;\n            Console.WriteLine(myULong);\n            float myFloat = 5.9998f;\n            Console.WriteLine(myFloat);\n            double myDouble = 5.99;\n            Console.WriteLine(myDouble);\n            decimal myDecimal = 10.0m;\n            Console.WriteLine(myDecimal);\n            char myChar = 'A';\n            Console.WriteLine(myChar);\n            bool myBoolean = false;\n            Console.WriteLine(myBoolean);\n            Console.WriteLine(\"\");\n            Console.WriteLine(\"¡Hola, C#!\");\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/jamerrq.cs",
    "content": "using System;\n\n// Documentación oficial de C#: https://docs.microsoft.com/es-es/dotnet/csharp/\n\n// Comentario de una sola línea\n/*\n    Comentario\n    de\n    varias\n    líneas\n*/\n\nclass RoadMap\n{\n    static void Main()\n    {\n        // Variables\n        var variable = \"Hola mundo\";\n        // Constantes\n        const string constante = \"Hola mundo\";\n        // constante = \"Adiós mundo\"; <- Error\n\n        // Tipos de datos\n        // https://docs.microsoft.com/es-es/dotnet/csharp/language-reference/builtin-types/built-in-types\n        // https://docs.microsoft.com/es-es/dotnet/csharp/language-reference/keywords/value-types\n\n        // Tipos de datos primitivos\n        // https://docs.microsoft.com/es-es/dotnet/csharp/language-reference/builtin-types/floating-point-numeric-types\n        float flotante = 1.5f;\n        double doble = 1.5;\n        decimal _decimal = 1.5m;\n\n        // https://docs.microsoft.com/es-es/dotnet/csharp/language-reference/builtin-types/integral-numeric-types\n        byte _byte = 1;\n        sbyte _sbyte = 1;\n        short _short = 1;\n        ushort _ushort = 1;\n        int entero = 1;\n        uint uinteger = 1;\n        long longo = 1;\n        ulong ulongo = 1;\n\n        // https://docs.microsoft.com/es-es/dotnet/csharp/language-reference/builtin-types/bool\n        bool booleano = true;\n\n        // https://docs.microsoft.com/es-es/dotnet/csharp/language-reference/builtin-types/char\n        char caracter = 'a';\n\n        // https://docs.microsoft.com/es-es/dotnet/csharp/language-reference/builtin-types/string\n        string cadena = \"Hola mundo\";\n\n        // https://docs.microsoft.com/es-es/dotnet/csharp/language-reference/builtin-types/object\n        object objeto = new object();\n\n        /*\n            Tipos de datos no primitivos\n        */\n\n        /*\n            Arrays\n        */\n        // https://docs.microsoft.com/es-es/dotnet/csharp/language-reference/builtin-types/pointer-types\n        // https://docs.microsoft.com/es-es/dotnet/csharp/language-reference/keywords/unsafe\n        unsafe\n        {\n            int entero = 1;\n            int* puntero = &entero;\n            Console.WriteLine(*puntero);\n        }\n\n        /*\n            Nullable value types\n        */\n        // https://docs.microsoft.com/es-es/dotnet/csharp/language-reference/builtin-types/nullable-value-types\n        int? enteroNulo = null;\n        Console.WriteLine($\"El valor de enteroNulo es {enteroNulo}\");\n\n        /*\n            Valor vacío\n        */\n        // https://docs.microsoft.com/es-es/dotnet/csharp/language-reference/builtin-types/void\n        unsafe\n        {\n            void* vacio = null;\n        }\n\n        /*\n            * Stackalloc\n        */\n        // https://docs.microsoft.com/es-es/dotnet/csharp/language-reference/builtin-types/stackalloc\n        unsafe\n        {\n            int* puntero2 = stackalloc int[10];\n            Console.WriteLine(*puntero2);\n        }\n\n        Console.WriteLine(\"Hola C#!\");\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/jatomas.cs",
    "content": "﻿/* Crea un comentario en el código y coloca la URL del sitio web oficial del\n *  lenguaje de programación que has seleccionado.*/\n\n// Web oficial C# -->     https://dotnet.microsoft.com/es-es/languages/csharp\n\n/* - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.*/\n// Este es un comentario en una línea\n\n/*\n    Este es un comentario con varias líneas\n*/\n\n/// <summary>\n///  Este es un comentario para generar documentacion XML desde el compilador.\n/// </summary>\n\n/* - Crea una variable (y una constante si el lenguaje lo soporta).*/\nint i;\nconst int J = 2;\n\n/* - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).*/\nint integer;\nlong bigInt;\nfloat puntoFlotante;\ndouble puntoFlotanteDoble;\ndecimal monetario;\nstring cadena;\nchar caracter;\nbool booleano;\n\n\n/* - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"*/\nstring lang = \"C#\";\nConsole.WriteLine($\"¡Hola, {lang}!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/jcrobles99.cs",
    "content": "/*\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n// Ejercicio #00.1\n// https://dotnet.microsoft.com/es-es/languages/csharp\n\n// Ejercicio #00.2: Comentario en una línea\n/*\n    Comentario\n    múltiples\n    líneas\n*/\nint x = /*comentario en linea de codigo*/ 1;\n\n// Ejercicio #00.3\nint y = 0; // Declaracion de variable (tipo int)\nconst double pi = 3.14159265; //Declaracion de constante (tipo double)\n\n// Ejercicio #00.4\n    //********Tipos enteros************\nsbyte sb = 0; //Variable tipo sbyte (8 bits con signo)\nbyte b = 0; //Variable tipo byte (8 bits sin signo)\nshort s = 0; //Variable tipo short (16 bits con signo)\nushort us = 0; //Variable tipo ushort (16 bits sin signo)\nint i = 0; //Variable tipo int (32 bits con signo)\nuint ui = 0; //Variable tipo uint (32 bits sin signo)\nlong L = 0; //Variable tipo long (64 bits con signo)\nulong uL = 0; //Variable tipo ulong (64 bits sin signo)\n//********Tipos punto flotante************\nfloat f = 0.0f; //Variable tipo float (decimales)(4 bytes)(presicion 6 a 9 digitos aprox.)\ndouble d = 0.0; //Variable tipo double (decimales)(8 bytes)(presicion 15 a 17 digitos aprox.)\ndecimal m = 0.0m; //Variable tipo decimal (decimales)(16 bytes)(presicion 28 a 29 digitos aprox.)\n//********Tipo bool************\nbool b1 = true; //Representacion true en bool\nbool b2 = false; //Representacion false en bool\n//********Tipo caracteres************\nchar c = 'a'; //Variable tipo char (16 bits)\nstring cadena = \"Variable para cadena de texto\"; //Variable tipo string (coleccion secuencial solo lectura objetos char)\n//*******Asignacion implicita********\nvar z = 1; //Asigna como int\nvar w = 'b'; //Asigna como char\nvar p = \"Hola\"; //Asigna como string\n\n// Ejercicio #00.5: \nConsole.WriteLine(\"Hola C#\");\n    \n\n "
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/jcubero12.cs",
    "content": "using System;\n\n// URl del sitio: https://learn.microsoft.com/es-es/dotnet/csharp/tour-of-csharp/overview\n\n// Este es comentario de una linea\n\n/*\nEste es el ejemplo de comentarios \nde varias lineas\n*/\n\n// Variables y constantes. \nvar nombre = \"Jose\";\nconst string Saludolenguaje = \"Hola!, C#\";\n\n//Tipos de datos de las variables\nint entero = 3; //32bit\nuint uenteroNum = 123423; // 32bit usigned\nlong largo = 1234567890123; //64bit\nulong uLargoNum = 1234567890123456789; //64bit unsigned\nshort corto = 23; //16bit \nushort ucortoNum = 12; //16bit unsigned\nbyte numbyte = 23; //8bit unsigned\nsbyte sbytenum = -12; //8bit signed\ndouble doble = 2.14; //32bit  \nfloat flotante =  3.14f; //64bit\ndecimal decimalNum = 12345.6789m; //128bit\nbool booleano = true; //true or false\nchar letra = 'A'; //16bit\nstring cadenaTexto = \"Esto es una cadena de texto\";\nobject nulo = null;\n\n//Impresion de texto\nConsole.WriteLine(Saludolenguaje);\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/kenysdev.cs",
    "content": "// ╔══════════════════════════════════════╗\n// ║ Autor: Kenys Alvarado                ║\n// ║ GitHub: https://github.com/Kenysdev  ║\n// ║ 2024 - C# - CSharp                   ║\n// ╚══════════════════════════════════════╝\n\n// 1. Sitio web oficial:\n// *********************\n// https://dotnet.microsoft.com/es-es/languages/csharp\n\n// 2. Sintaxis para comentarios:\n// *****************************\nint edad = 21; //comentario inline\n\n//Comentarios Block\n\n/*\n  comentario para\n  múltiples líneas.\n*/\n\n[Obsolete(\"Obsolete comment or Deprecated comment\")]\n\n// TODO: Futuras modificaciones o escritura.\n// HACK: Solución temporal, revisar y mejorar.\n// BUG: Corregir\n\n#pragma warning disable IDE0018 //desactivar temporalmente una advertencia.\n// codigo ...\n#pragma warning restore IDE0018 //restaurarla después\n\n/// <summary>\n/// comentarios XML, para generadores de documentación\n/// </summary>\n/// <param name=\"parametro\">Descripción del parámetro.</param>\n/// <returns>Descripción del valor de retorno.</returns>\n\n#if DEBUG\n    // Comentarios condicionales\n    // Este código se compila solo en configuraciones de depuración\n#endif\n\n// 3. Variable y constante.\n// ************************\nint variable_edad = 21;\nconst double Constante = 3.14;\n\n// 4. Variables para datos primitivos.\n// ***********************************\n// Enteros:\nint entero = 42;         // Entero de 32 bits\nbyte byteEntero = 255;   // Entero sin signo de 8 bits\nshort corto = 10000;     // Entero de 16 bits\nlong largo = 123456789L; // Entero de 64 bits\n// uint, ushort, ulong -> No soportan numeros negativos\n\n// Decimales:\nfloat flotante = 3.14f;          // Número de punto flotante de 32 bits\ndouble doble = 3.14159;          // Número de punto flotante de 64 bits\ndecimal decimalValor = 123.456m; // Número decimal de 128 bits\n\n// Caracteres y Cadenas:\nchar caracter = 'A';    // Carácter Unicode\nstring cadena = \"Hola\"; // Cadena de caracteres\n\n// Booleanos:\nbool esVerdadero = true; // Valor booleano verdadero\nbool esFalso = false;    // Valor booleano falso\n\n// 5. Imprime: hola, lenguaje:\n// **************************\nConsole.WriteLine(\"¡Hola, c#!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/kodenook.cs",
    "content": "// https://dotnet.microsoft.com/es-es/languages/csharp\n\n/*\n    Comments\n*/\n\n// single-line comment\n\n/*\n    this is a\n    multi-line comment\n*/\n\n/*\n    Vars And Constants\n*/\n\nstring name = \"kodenook\";\nconst int age = 20;\n\n/*\n    Primitive Types\n*/\n\nstring country = \"chile\";\nchar letter = 'c';\nint ageCountry = 200;\nlong peopleQ = 20000000;\nfloat myFloat = 3.5F;\ndouble myDouble = 5.323D;\nbool myBool = true;\n\n\nConsole.WriteLine(\"¡Hello, C#!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/lobogeekmx.cs",
    "content": "// using System;\n// using System.Collections.Generic;\n// using System.Linq;\n// using System.Threading.Tasks;\n\n/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\nnamespace Reto00\n{\n    public class lobogeekmx\n    {\n        // Pagina web de C# -->  https://dotnet.microsoft.com/es-es/languages/csharp\n\n        // Comentario de una sola línea\n\n        /*\n            Este es un comentario multilinea \n\n        */\n\n        var primer_variable = \"primer variable\";\n\n        const string VARIABLE_CONSTANTE = \"Esta variable no cambia\"; // por convencion se declara en mayuscula\n\n        int i = 0;\n\n        long l = 1234567890123456789L; // Se agrega una \"L\" al final \n\n        float f = 45.5f; // Se agrega la \"f\" al final. Float y decimal son mas rapidos. 7 digitos\n\n        double d = 3.14; // precision de 15 digitos\n\n        decimal de = 4562.25M; // Se agrega una \"M\" al final. Principlmente usado para dinero\n\n        char c = 'S';\n\n        bool b = true;\n\n        Console.WriteLine(\"¡Hola, C#!\")\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/luterfloyd.cs",
    "content": "// ESTA ES UNA LINEA DE COMENTARIO. PUEDE ESTAR UBICADA AL PRINCIPIO O EN ALGUN OTRO\n// LUGAR DEL CODIGO, TODO LO QUE SE ENCUENTRE A SU DERECHA SERA OMITIDO POR EL COMPILADOR\n\n/*\n    ESTO\n    ES\n    UN COMENTARIO \n    EN  VARIAS \n    LINEAS, TODO LO QUE SE \n    ENCUENTRE EN ESTE BLOQUE DELIMITADO POR ESTOS CARACTERES INICIALES Y FINALES\n    SERA OMITIDO POR EL COMPILADOR\n*/\n\n// SITIO OFICIAL DE CSHARP: https://learn.microsoft.com/en-us/dotnet/csharp/\n\nusing System;\n\nnamespace CSharpHelloWorld\n{\n    class HelloWorld\n    {\n        static void Main(string[] args)\n        {\n            Console.WriteLine(\"Hola CSharp!\");\n            // VARIABLES. DEBEN SER DECLARADAS ANTES DE SER UTILIZADAS\n            // * BASICAS O PRIMITIVAS: PUEDE DEFINIRSE CON EL TIPO DE DATO AL PRINCIPIO\n            //   O POR INFERENCIA DEL DATOS ASIGNADO A LA VARIABLE CREADA UTILIZANDO LA\n            //   PALABRA RESERVADA 'VAR'\n\n            string miTexto1   = \"esta es una variable tipo string en Csharp\";\n            char caracter = 'A';\n            int miEntero1     = 10;\n            long numeroLargo = 1234567890123456L;\n            short numeroCorto = 12323;\n            byte numeroByte = 211;\n            float miFlotante1 = 10.5f;\n            double miDoble1   = 10.99999;\n            decimal numeroDecimal = 123.456m;\n            bool miBooleano1  = true; \n            Console.WriteLine(\"TIPOS DE VARIABLE BASICAS O PRIMITIVAS:\");\n            Console.WriteLine(\"string,int, long, byte, float,double,bool\");\n\n            Console.WriteLine(\"* declaracion con tipo variable / impresion sin formato\");\n            Console.WriteLine(\"string: \" + miTexto1);\n            Console.WriteLine(\"entero: \" + miEntero1);\n            Console.WriteLine(\"flotante: \" + miFlotante1);\n            Console.WriteLine(\"doble: \" + miDoble1);\n            Console.WriteLine(\"booleano: \" + miBooleano1);\n\n            var miTexto2 = \"esta es una variable tipo string en Csharp\";\n            var miEntero2 = 10;\n            var miFlotante2 = 10.5f;\n            var miDoble2 = 10.99999;\n            var miBooleano2 = true; \n\n            Console.WriteLine(\"* declarando con var / impresion con formato incluido\");\n            Console.WriteLine($\"string:\\t\\t{miTexto2}\");\n            Console.WriteLine($\"entero:\\t\\t{miEntero2}\");\n            Console.WriteLine($\"flotante:\\t{miFlotante2}\");\n            Console.WriteLine($\"doble:\\t\\t{miDoble2}\");\n            Console.WriteLine($\"booleano:\\t{miBooleano2}\");\n\n            Console.WriteLine(\"Las constantes se declaran con la palabra reservada const\");\n            Console.WriteLine(\"seguido del tipo de dato\");\n            const int miConstanteNum = 10;\n            const string miConstanteTexto = \"CONSTANTE ALFANUMERICA\";\n\n            Console.WriteLine($\"CONSTANTE NUMERICA:{miConstanteNum}\");\n            Console.WriteLine($\"CONSTANTE ALFANUMERICA:\\t{miConstanteTexto}\");\n\n            Console.WriteLine(\"* ESTRUCTURAS DE DATOS: array, dictionary,set,tupla\");\n\n            var miArray = new string[] {\"rojo\",\"blanco\",\"verde\"};\n            Console.WriteLine($\"la posicion 2 de mi array es: {miArray[2]}\");\n\n            var miDict = new Dictionary <string, int>\n            {\n                {\"rojo\",36},\n                {\"verde\",15},\n                {\"azul\",23}\n            };\n\n            Console.WriteLine($\"la posicion 0 de mi diccionario es: {miDict[\"rojo\"]}\");\n\n            var miSet = new HashSet <string> {\"rojo\",\"verde\",\"azul\",\"verde\",\"azul\"};\n            Console.WriteLine(miSet); // los set no estan indexados, tampoco se admiten repetidos\n\n            var miTuple = (\"rojo\",\"verde\",\"azul\");\n            Console.WriteLine(miTuple); // no indexados, permiten visualizar todo el contenido\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/lydaf.cs",
    "content": "// Sitio web C# https://dotnet.microsoft.com/es-es/languages/csharp\n\n// Una linea\n/*\n  En varias\n  varias\n  varias\n  varias\n*/\n\nusing System;\n\nnamespace HolaMundo\n{\n  internal class lydaf \n  {\n    static void main(string[] args)\n    {\n      var variable;\n      const int constante;\n\n      //Si se añade u antes de los tipos numericos como int, long, short, double, float se puede restringir a que sean positivos\n      int entero = 1;\n      long largo = 1234567890123456L;\n      short corto = 12345;\n      double flotanteMasPreciso = 2.1D;\n      float flotante = 0.10f;\n      string texto = \"Esto es un string\";\n      char caracter = 'a';\n      bool booleano = true;\n      byte Byte = 255;\n\n      Console.WriteLine(\"Hola, C#!!\");\n    }\n  }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/marqitos.cs",
    "content": "/*\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n */\n// https://learn.microsoft.com/es-es/dotnet/csharp/\n\nusing System;\n\n/*\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n */\n\n// Comentario de una sola línea\n\n/*\n * Comentario\n * de varias\n * líneas\n */\n\n/// <summary>\n/// Comentario de documentación\n/// </summary>\n/// <remarks>\n/// Crea documentación de las funciones, variables, ...\n/// a partir de comentarios,\n/// con una sintaxis más específica\n/// </remarks>\n\n/*\n* - Crea una variable (y una constante si el lenguaje lo soporta).\n*/\n\nint miVariable = 1;\nconst int MI_CONSTANTE = 1;\n\n\n/*\n* - Crea variables representando todos los tipos de datos primitivos\n*   del lenguaje (cadenas de texto, enteros, booleanos...).\n*/\n\nstring variableTexto = \"Cadena de texto\";\nchar variableCaracter = 'Ñ';\n//Rune variableEscalarUnicode = 0x10FFFF;\n\nint variableEntero = -25;\nuint varaibleEnteroPositivo = 3500;\nlong variableEnteroGrande = -3500;\nulong varibleEnteroPositivoGrande = 987654321;\nshort variableEnteroPequeño = -700;\nushort variableEnteroPsitivoPequeño = 800;\nbyte variableByte = 128;\n\nfloat variableNumeroFlotante = 2.5f;\ndouble variableNumeroFlotantePrecisionDoble = 2.5D;\ndecimal variableNumeroDecimal = 2.5m;\n\nbool variableBooleano = true;\n\n\n/*\n* - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n*/\n\nConsole.WriteLine(\"¡Hola, C#!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/matteozhao98.cs",
    "content": "using System;\n\ninternal class matteozhao98\n{\n    //CREAR COMENTARIOS Y MOSTRAR LAS DISTINTAS FORMAS DE CREAR COMENTARIOS\n\n    // Documentación oficial en: https://learn.microsoft.com/en-us/dotnet/csharp/\n\n    /*\n    * Esto es un comentario multilínea, para poder crear este tipo de comentarios,\n    * es necesario iniciarlo con la secuencia de caracteres mostrados en la parte \n    * del principio y del final de este bloque\n    * \n    * Se usan para aclarar información a nosotros mismos o a compañeros que puedan\n    * estar trabajando con nosotros. Son líneas de texto que no se van a ejecutar.\n    */\n\n    static void Main(string[] args)\n    {\n        //CREAR UNA VARIABLE Y UNA CONSTANTE\n        string saludo = \"Hola mundo!\";\n        const double numPi = 3.1416;\n\n        //CREA VARIABLES PRIMITIVAS DEL LENGUAJE\n        int miEntero = 2;\n        long miLong = 5;\n        float miFloat = 3.14;\n        double miDouble = 3.14;\n        decimal miDecimal = 3.14;\n        string miString = \"C#\";\n        char miChar = 'a';\n        bool miBool = true;\n\n        Console.WriteLine($\"Hola {miString}!\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/miguelex.cs",
    "content": "class miguelex\n{\n    // Documentación en https://learn.microsoft.com/es-es/dotnet/csharp/\n\n    // Comentario en una linea\n\n    /* Comentario\n       en varias \n       líneas */\n\n    static void Main(string[] args)\n    {\n        // Declaración de variables y constantes\n        string lenguaje = \"C#\";\n        const double PI = 3.1416;\n\n        // Tipos primitivos\n        int entero = 10;\n        double numDecimal = 10.5;\n        char caracter = 'a';\n        string cadena = \"Hola mundo\";\n        bool booleano = true;\n\n        // Imprimir por pantalla\n        Console.WriteLine($\"Hola {lenguaje}\");\n        Console.WriteLine(\"El valor de la variable es: \" + entero);\n        Console.WriteLine($\"El valor del caracter es: {caracter}\");\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/miguelgargallo.cs",
    "content": "// URL del sitio web oficial de C#: https://learn.microsoft.com/en-us/dotnet/csharp/\r\n\r\n// Comentario de una sola línea en C#\r\n\r\n/*\r\n  Comentario de varias líneas en C#\r\n*/\r\n\r\n// Declaración de variable y constante\r\nstring nombreIdioma = \"C#\";\r\nconst string SALUDO = \"¡Hola, \";\r\n\r\n// Tipos de datos primitivos en C#\r\nint numero = 42;\r\ndouble numeroFraccionario = 3.14;\r\nbool esDivertidoProgramar = true;\r\nchar caracterIndividual = 'A';\r\n\r\n// Imprimir el mensaje\r\nConsole.WriteLine(SALUDO + nombreIdioma + \"!\");\r\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/mor39a.cs",
    "content": "/*\n--------------------------------------------------------------------------------------------------\n    Instrucciones:\n\n    1. Crea un comentario en el código y coloca la URL del sitio web oficial del\n       lenguaje de programación que has seleccionado.\n    2. Representa las diferentes sintaxis que existen de crear comentarios\n       en el lenguaje (en una línea, varias...).\n    3. Crea una variable (y una constante si el lenguaje lo soporta).\n    4. Crea variables representando todos los tipos de datos primitivos\n       del lenguaje (cadenas de texto, enteros, booleanos...).\n    5. Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n--------------------------------------------------------------------------------------------------\n*/\n\n// 1.\n// Sitio Oficial: https://dotnet.microsoft.com/es-es/languages/csharp\n\n//2.\n// En una linea\n/*\nVarias\nLineas\n*/\nstring comentario = /*\"Entre \" +*/ \"Medio\";\n\n//3.\nstring variable;\nconst string constante = null!;\n\n//4.\nstring cadena;\nint entero;\nfloat flotante;\ndouble doble;\nlong largo;\nbool booleano;\n\n//5.\nconst string lenguaje = \"C#\";\nConsole.WriteLine($\"¡Hola, {lenguaje}!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/nicolastapiasanz.cs",
    "content": "// Create by Nicolas Tapia -> https://www.github.com/nicolastapiasanz\n\n// EXERCISE #00\n\n// URL: https://learn.microsoft.com/es-es/dotnet/csharp/\n\n// One Line Comment\n\n/*\n * Multiple\n * lines\n * comment 1\n */\n\n/// Multiple\n/// lines\n/// comment 2\n\nint foo = 1;\nvar varFoo = 1;\nconst int constantFoo = 2;\n\nbool booleanFoo = false;\nbyte byteFoo = 1;\nsbyte sbyteFoo = 1;\nshort shortByteFoo = 1;\nushort ushortFoo = 1;\nint intFoo = -1;\nuint uintFoo = 1;\nulong ulongFoo = 1;\nfloat floatFoo = 1.0f;\ndouble doubleFoo = 1.0;\ndecimal decimalFoo = 1;\nchar charFoo = 'a';\nstring stringFoo = \"C#\";\nobject objectFoo = 1;\ndynamic dynamicFoo = 1;\n\nSystem.Console.WriteLine($\"Hola, {stringFoo}\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/nunezlagos.cs",
    "content": "﻿using System;\n\nclass Nunezlagos\n{\n    // Sitio oficial https://learn.microsoft.com/es-es/dotnet/csharp/\n\n    /*\n        Comentario de más de una\n        línea \n        de código.    \n    */\n\n    // Comentario de una línea de código\n\n    static void Main(string[] args)\n    {\n\n        string nombre_lenguaje = \"c#\";\n        const string usuario = \"nunezlagos\";\n\n        // Tipos de datos primitivos\n\n        // Enteros\n        int numeroEntero = 100;\n        long numeroLargo = 1234567890123456L;\n        short numeroCorto = 12323;\n        byte numeroByte = 211;\n\n        // Decimales\n        float numeroFlotante = 3.14f;\n        double numeroDoble = 3.14159265359;\n        decimal numeroDecimal = 123.456m;\n\n        // Caracteres\n        char caracter = 'A';\n\n        // Booleano\n        bool esVerdadero = true;\n\n        // Referencia nula\n        string referenciaNula = null;\n\n        // Mostrar información en la consola \n        Console.WriteLine(\"¡Hola, \"+nombre_lenguaje+\"!\");\n    }\n}\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/paalvarador.cs",
    "content": "namespace DefaultNamespace;\n\npublic class paalvarador\n{\n    // 1. Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n    // Primer comentario en C# (https://learn.microsoft.com/en-us/dotnet/csharp/)\n    \n    // 2. Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n    \n    // Comentario de una línea\n    /*\n     * Comentario de varias lineas\n     */\n    \n    // 3. Crea una variable (y una constante si el lenguaje lo soporta).\n    private var nombre = \"Pablo Antonio Alvarado\";\n    private const string iva = \"15%\";\n    \n    // 4. Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n    private string nombreCompleto = \"Pablo Antonio Alvarado Ruiz\";\n    private int edad = 32;\n    private float estatura = 1.68f;\n    private double peso = 70.5;\n    private bool estado = true;\n    private char inicial = 'P';\n    private string[] nombres = [\"Pablo\", \"Xavier\", \"Santiago\", \"Diana\"];\n    private List<string> nombres2 = new List<string>() { \"Pablo\", \"Xavier\", \"Santiago\", \"Diana\" };\n    private Dictionary<string, string> nombres3 = new Dictionary<string, string>()\n    {\n        { \"Pablo\", \"Antonio\" },\n        { \"Xavier\", \"Santiago\" },\n        { \"Diana\", \"Alvarado\" }\n    };\n    \n    // 5. Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n    Console.WriteLine(\"!Hola, C#!\")\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/pakiuh.cs",
    "content": "using System;\r\n\r\nclass Program\r\n{\r\n    static void Main()\r\n    {    \r\n        // Sitio web oficial de C#: https://docs.microsoft.com/en-us/dotnet/csharp/\r\n\r\n        // Este es un comentario de una línea\r\n\r\n        /*\r\n        Este es un comentario\r\n        de varias líneas\r\n        */\r\n\r\n        // Crea una variable\r\n        public void MyGenericMethod<T>(T genericVariable)\r\n        {\r\n            Console.WriteLine(genericVariable);\r\n        }\r\n\r\n        // Llamada al método con un valor específico\r\n        MyGenericMethod<int>(10);\r\n\r\n        // Declaración de una constante\r\n        const int MyConstant = 10;\r\n\r\n        // Crea una variable (y una constante si el lenguaje lo soporta)\r\n        int myInt = 10;\r\n        double myDouble = 9.99;\r\n        char myChar = 'A';\r\n        bool myBool = true;\r\n        float myFloat = 19.99F;\r\n        byte myByte = 255;\r\n        short myShort = 32767;\r\n        long myLong = 9223372036854775807;\r\n        sbyte mySbyte = 127;\r\n        ushort myUshort = 65535;\r\n        uint myUint = 4294967295;\r\n        ulong myUlong = 18446744073709551615;\r\n        decimal myDecimal = 79228162514264337593543950335M;\r\n\r\n        //Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\r\n        Console.WriteLine(\"¡Hola C#!\");\r\n    }\r\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/pkmaventura.cs",
    "content": "using System;\n\n//Autor: Ariel Ventura\n\n// 1. Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n\n    // Sitio oficial de C#: https://learn.microsoft.com/en-us/dotnet/csharp/\n\n// 2. Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje(en una línea, varias...).\n\n    // Esto es un comentario de un linea...\n\n    /*\n    * Es es un comentario\n    * de Varias lineas.\n    */\n\nnamespace ConsoleAppRoadMap001\n{\n    class Program\n    {\n        // 3. Crea una variable (y una constante si el lenguaje lo soporta).\n\n        string MiVariable = \"Hola\";\n        const string MiConst = \"SinCambio\";\n\n        // 4.Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n\n        string MiVariable2 = \"Esto es una cadena\";\n        int MiEntero = 17;\n        bool Positivo = true;\n        bool Negativo = false;\n        \n\n        static void Main(string[] args)\n        {\n            // 5.Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\n            Console.WriteLine(\"Hola C#!\");\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/rootqui.cs",
    "content": "﻿// Ejercicio 01\n\n// El sitio de referencia utilizado es https://learn.microsoft.com/en-us/dotnet/csharp/\n\n/*\n    Tipos de commentarios\n    ---------------------\n    - Comentarios de una sola línea\n    - Comentarios multilinea\n    - Comentarios de Documentación XML (https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/documentation-comments)\n*/\n\n/* Ejemplos */\n\n// Este es un comentario de una sola línea.\n\n/*  Esto podría ser un resumen de todos los códigos.\n    Puede agregar varios párrafos o enlaces a páginas como https://learn.microsoft.com/dotnet/csharp.\n\n    Incluso podrías incluir emojis. Un ejemplo es 🔥\n    Luego, cuando hayas terminado, cierra con\n*/\n\n/// <summary>\n/// Este es un comentario de Documentación XML\n/// </summary>\n\n// Variables\nint indice;\nindice = 0;\nindice = 3;\n\n// Constantes\n// https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/const\nconst int meses = 12;\n\n// Tipos Primitivos\n\n// Tipo booleano\n// https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool\nbool dosEsPar = true;\n\n// Tipos numéricos enteros\n// https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/integral-numeric-types\nbyte  totalDiasSemana = 7; \n\nsbyte velocidad = 120;\n\nshort lineasCodigo = 30000;\n\nint maxInt = 2147483647;\n\nuint maxUInt = 4294967295;\n\nlong minLong = -9223372036854775808;\n\nulong maxULong =  18446744073709551615;\n\nnint tamanio = -1302;\n\nnuint altura = 1302;\n\n// Tipos numéricos de punto flotante\n// https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/floating-point-numeric-types\ndouble d = 4d;\n\nfloat f = 3_000.5F;\n\ndecimal dec = 400.75M;\n\n// Tipo carácter\n// https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/char\nchar inicial = 'r';\n\n// Tipo secuencia de caracteres\n// https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/reference-types#the-string-type\nstring sistemaOperativo = \"Windows\";\n\nConsole.WriteLine(\"¡Hola, C#!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/sandrarg85.cs",
    "content": "// Ejercicio 1: Sitio oficial https://dotnet.microsoft.com/es-es/languages/csharp\n\n// Ejercicio 2: // Comentario en una linea \n\n/* Comentario\n * en varias\n * lineas */\n\nusing System;\nusing System.Linq.Expressions;\n\nnamespace SandraDev\n{\n    class Program\n    {\n        static void Main(string[] args)\n        {\n            // Ejercicio 3 - Variable y Constante declarada\n\n            int Variable = 0;\n            const string MiConstante = \" \";\n\n            // Ejercicio 4 - Datos primitivos\n\n            int NumeroEntero = 1;\n            long NumeroEnteroLargo = 1234567890;\n            float NumeroDecimal = 1.5f;\n            double NumeroDecimalLargo = 12.50;\n            decimal NumeroDecimalExtraLargo = 123567.50m;\n            string Texto = \"hola\";\n            char Letra = 'A';\n            bool verdadero = true;\n\n            // Ejercicio 5 - Imprimir por pantalla\n\n            Console.WriteLine(\"¡Hola, c#!\");\n\n\n\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/santiagorf23.cs",
    "content": "// Santiago Ramirez Florez - santiagorf23\n// Roadmap: SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n// https://learn.microsoft.com/es-es/dotnet/csharp/tour-of-csharp/overview\n\n/*\n    Comentario para varias lineas en C#\n    Este es un ejemplo de comentario que abarca varias lineas.\n*/\n\nusing System;\nnamespace Roadmap\n{\n    class Program\n    {\n        static void Main(string[] args)\n        {\n            int numero = 23;\n            string nombre = \"Santiago\";\n            float decimalFlotante = 23.08f;\n            double altura = 1.84;\n            bool esVerdadero = true;\n            decimal precio = 23.08m;\n            Console.WriteLine(\"Hola Mundo en C#.\");\n            const string saludo = \"Hola, soy Santiago Ramirez Florez y este es mi primer programa en C#.\";\n            Console.WriteLine(saludo);\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/tebaah.cs",
    "content": "﻿  // See https://aka.ms/new-console-template for more information\n\n  /*\n  * EJERCICIO:\n  * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n  *   lenguaje de programación que has seleccionado.\n  * - Representa las diferentes sintaxis que existen de crear comentarios\n  *   en el lenguaje (en una línea, varias...).\n  * - Crea una variable (y una constante si el lenguaje lo soporta).\n  * - Crea variables representando todos los tipos de datos primitivos\n  *   del lenguaje (cadenas de texto, enteros, booleanos...).\n  * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n  */\n\n  // tipos de comentarios\n\n  // este es un comentario de una linea url del sitio es https://dotnet.microsoft.com/es-es/languages/csharp\n  /* este es un comentario\n  de varias lineas */\n\n  // variables\n\n  public string variable = \"hola\";\n  public const string constante = \"hola\";\n  public char caracter = 'a';\n  public var variable = \"hola\";\n  public string[] arreglo = {\"hola\", \"mundo\"};\n  public List<string> lista = new List<string> {\"hola\", \"mundo\"};\n  public Dictionary<string, string> diccionario = new Dictionary<string, string> {{\"hola\", \"mundo\"}};\n\n\n  // tipos de datos primitivos\n\n  public byte b = 1;\n  public short corto = 1;\n  public int entero = 1;\n  public float flotante = 1.1f;\n  public double doble = 1.1;\n  public bool booleano = true;\n\n\n\n\n  // impresion por terminal\n  public string lenguaje = \"C#\";\n\n  Console.WriteLine($\"Hello, {lenguaje}\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/vasilealexandru02.cs",
    "content": "﻿public class vasilealexandru02\n{\n    public vasilealexandru02()\n    {\n        /*\n            * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n            * - Recuerda que todas las instrucciones de participación están en el\n            *   repositorio de GitHub.\n            *\n            * Lo primero... ¿Ya has elegido un lenguaje?\n            * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n            * - Este primer reto te servirá para familiarizarte con la forma de participar\n            *   enviando tus propias soluciones.\n            *\n            * EJERCICIO:\n            * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n            *   lenguaje de programación que has seleccionado.\n            * - Representa las diferentes sintaxis que existen de crear comentarios\n            *   en el lenguaje (en una línea, varias...).\n            * - Crea una variable (y una constante si el lenguaje lo soporta).\n            * - Crea variables representando todos los tipos de datos primitivos\n            *   del lenguaje (cadenas de texto, enteros, booleanos...).\n            * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n            *\n            * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n            * debemos comenzar por el principio.\n            */\n\n        // https://learn.microsoft.com/es-es/dotnet/csharp/\n\n        // Comentario en una línea\n\n        /* Este \n         * es \n         * un \n         * comentario\n         * en \n         * varias\n         * lineas\n         */\n\n        string miVariable = \"¡Hola, C#!\";\n        const string constante = \"Esta es mi constante\";\n\n        long numeroLong = 23232323232323l;\n        float numeroFloat = 1.0f;\n        double numeroDouble = 23.23;\n        int numero = 23;\n        byte numeroByte = 255;\n        decimal numeroDecimal = 0.42m;\n\n        char caracter = 'a';\n        bool booleano = true;\n        string texto = \"Texto\"\n\n        Console.WriteLine(miVariable);\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/vicgallego.cs",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.Reto_00Ro\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Roadmap_00\n{\n    internal class Program\n    {\n        static void Main(string[] args)\n        {\n            // Esta es la URL oficial de C# https://learn.microsoft.com/es-es/dotnet/csharp/\n            /* Esta es otra forma  de crear comentarios */\n\n            int entero = 5;\n            string cadena= \"hola\";\n            double ndecimal = 5.7;\n            bool ToF = true;\n            float flotante = 53.2f;\n            char caracter = 'A';\n\n            const int b= 5;\n\n            Console.WriteLine(\"HOLA C#\");\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/victormugo.cs",
    "content": "﻿namespace _00_sintaxis\n{\n    internal class Program\n    {\n        static void Main(string[] args)\n        {\n            // EJERCICIO:\n            //  * -Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n            //  * -Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje(en una línea, varias...).\n            //  * -Crea una variable(y una constante si el lenguaje lo soporta).\n            //  * -Crea variables representando todos los tipos de datos primitivos del lenguaje(cadenas de texto, enteros, booleanos...).\n            //  * -Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\n\n            // * -Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n            // https://learn.microsoft.com/en-us/dotnet/csharp/\n\n\n\n            //  * -Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje(en una línea, varias...).\n            // Ejemplo de comentario en línea\n            /*\n             * Ejemplo de comentario en varias líneas\n             * \n            */\n\n\n\n            //  * -Crea una variable (y una constante si el lenguaje lo soporta).\n            string example = \"Hola\";\n            const string constant = \"Victor\";\n\n\n            //  * -Crea variables representando todos los tipos de datos primitivos del lenguaje(cadenas de texto, enteros, booleanos...).\n            string name = \"Victor\";\n            char firstLetter = 'V';\n\n            short age2 = 4000;\n            int age = 400000000;\n            long age3 = 4000000000000000000;\n\n            ushort age4 = 40000;\n            uint age5 = 4000000000;\n            ulong age6 = 4000000000000000000;\n\n            double weight = 75.6;\n            float height = 1.778f;\n            decimal longPlay = 1.87665m;\n\n            string[] arrayExample = [\"Patatas\", \"Fruta\", \"Comida\"];\n\n            bool working = true;\n\n\n            //  * -Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n            string langName = \"C#\";\n            Console.WriteLine($\"¡Hola, {langName}!\");\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/vixxtory.cs",
    "content": "﻿using System;\nusing System.Runtime.InteropServices.Marshalling;\n\nclass Hello\n{\n\n    //Comentario de una sola linea\n    /* Comentario\n     * de\n     * multiples lineas */\n\n    //https://learn.microsoft.com/es-es/dotnet/csharp\n\n    static void Main()\n    {\n        //Variables primitivas\n\n        string nombre; //Declaracion de una variable\n        string saludo = \"Hola!\"; //Declaracion y asignacion de una variable\n        const int edadMaxima = 100; //Declaracion y asignacion de una constante\n\n        sbyte bytee= -128;\n        byte byteePositivos= 255;\n\n        short enteroDe16bits = -32768;\n        ushort enteroDe16bitsPositivos = 65535;\n\n        int enteroDe32bits = -2147483648;\n        uint enteroDe32bitsPositivos = 4294967295;\n\n        long enteroDe64bits = -9223372036854775808;\n        ulong enteroDe64bitsPositivos = 18446744073709551615;\n        \n        double floatDouble = 13.5;\n        float flotante = 13.5f;\n\n        string buendia = \"Como estas?\";\n        char caracter = 'a';\n\n        Console.WriteLine(\"Hola C#!\");\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#/wabish0.cs",
    "content": "\n// URl De C# -- https://learn.microsoft.com/es-es/dotnet/csharp/\n\n// Esto es un comentario de una linea en c#\n\n/* esto es un \ncomentario de \nvarias lineas en C# */\n\nint variable;\nconst int variable2;\n\n//tipos de datos\nint Myvar2 = 1;\nstring Mystring = \"C#\";\nbool Mybool = true;\nfloat Myfloat = 2.3775f;\ndouble Mydouble = 3.23332;\nchar Mychar = 'F';\n\nConsole.WriteLine($\"!Hola,{Mystring}!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++/0pio.cpp",
    "content": "//este lenguaje no tiene web oficial \n//comentario de una linea \n/*\n    comentario de varias lineas\n    todos los valres de bits que se ponen pueden ser variables dependiendo del compilador y arquitectura\n    ¿hey brais puedes compartir los playlists de rock que usas para tus directos?\n\n    este es el valor maximo que se puede representar con respecto a los bit que se maneja unsigned \n    8 bits  (1 byte)  = 255\n    16 bits (2 bytes) = 65,535\n    32 bits (4 bytes) = 4,294,967,295\n    64 bits (8 bytes) = 18,446,744,073,709,551,615\n\n    signed se puede manejar en estos rangos \n    8 bits  (1 byte)  = -128 a 127\n    16 bits (2 bytes) = -32,768 a 32,767\n    32 bits (4 bytes) = -2,147,483,648 a 2,147,483,647\n    64 bits (8 bytes) = -9,223,372,036,854,775,808 a 9,223,372,036,854,775,807\n\n    los valores de c++ son automaticamente signed \n\n*/\n#include <iostream>\n#include <string>\nusing namespace std;\n\nint main() {\n    const string constante = \"C++\";\n    string variable = \"¡Hola, \";\n\n    //hay diferentes valores numericos\n    short corto = 65524;//este es de 16 bits \n    int entero = 4294967294;//este es de 32 bits o 16 bits dependiendo del compilador\n    long largo = 4294967294;//este es de 32 bits\n    long long gigante = 18446744073709551614;//este es de 64 bits\n\n    float flotante = 3.141592;\n    double doble =  3.141592653589793;\n    long double giganteDoble = 1.000000000000001;\n    float scientifico = 6.02E23; //el float también puede usar notación cientifica\n\n    //también se pueden declarar los valores sin signo\n    unsigned short cortoSinSigno = 65535;\n    //también está el constexpr que es un valor que se va a calcular mientras se conpila no mientras se corre\n    constexpr float PI = 3.14159265358979323846;\n    //y se puede usar el auto que lo detecta automatico\n    auto autoDetectado = 3;\n    \n    //hay diferentes valores de texto\n    char caracter = 'a';\n    string texto = \"Hola, C++\";\n    char ascii = 65; //el char también puede ser un valor ascii\n\n    //y está el bool \n    bool booleano = true;\n\n    cout << texto;\n    return 0;\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++/Aldroide.cpp",
    "content": "// Comentario en una linea\n\n/*\nComentario\nen varias\nlineas\n*/\n\n#include <iostream>\n#include <string>\n\nusing namespace std;\n\nint main(){\n    // Variable\n    int variable = 9;\n    // Constante\n    const int constante = 8;\n\n    //Tipos de datos primitivos\n    int entero = 1;\n    unsigned int enteroSinSigno = 120;\n    short enteroCorto = 10;\n    unsigned short enteroCortoSinSigno = 10;\n    long enteroLargo = 123456789;\n    unsigned long enteroLargoSinSigno = 876543210;\n    long long enteroLargoLargo = 1236547899;\n    unsigned long long enteroLargoLargoSinSigno = 999999999;\n    float puntoFlotante = 3.1415f;\n    double puntoFlotanteDoble = 2.71828;\n    long double puntoFlotanteLargo = 0.123456789;\n    char caracter = 'a';\n    unsigned char caracterSinSigno = 'a';\n    wchar_t caracterAmplio = L'a';\n    bool Verdadero = true;\n    bool Falso = false;\n    string cadenaDeTexto = \"En C++ tenemos cadenas\";\n    int *punteroEntero = &entero;\n\n    string lenguaje = \"C++\";\n    cout<<\"Hola \"<<lenguaje<<\"!\"<<endl;\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++/AlejandroDave.cpp",
    "content": "// https://isocpp.org\n\n// Se puede realizar un comentario de una linea utilizando doble diagonal\n/* Puedo realizar comentarios de mas de una linea\n   encerrando el texto entre /*...*/\n\n\n#include <iostream>  // Para poder trabajar con c++ necesitamos importar la biblioteca iostream\n\nusing namespace std;\n// El comando anterior nos ayuda a acortar la escritura de los comandos principalmente de entrada y salida de consola\n\n// En c++ podemos declarar constantes\nconst int ct = 10;\n\nint main(){\n\n// Variables principales\nint i = -40;\nfloat fl = 34.5;\nchar c = 'C';\nstring st = \"Hola\";\ndouble db = 34535364;\n\n// C++ Permite tener una amplia variedad de tipos de variables derivadas de las principales utilizando terminos como \"long\" o \"unsigned\" entre otros\nunsigned int ui= 455;\nlong long int lli = 2342353464564;\n\nstring lenguaje = \"C++\";\n\ncout<<\"Hola \"<<lenguaje<<\"!\"<<endl;\n\n\nreturn 0;\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++/CesarCarmona30.cpp",
    "content": "// Sitio web del lenguaje\n// https://isocpp.org\n\n// Comentario de línea\n\n/*\n  Esto es un comentario\n  de varias líneas\n*/\n\n/**\n * Esto también es un \n * comentario de varias\n * líneas\n*/\n\n#include <iostream>\n\nusing namespace std;\n\nint main() {\n  //variable\n  int variable = 15;\n  //constante\n  const int constante = 20;\n\n  // Datos primitivos\n  short mi_short = 65535;         // 2 byte (16 bits)\n  int mi_int = 321;               // 4 bytes (32 bits) hasta 8 bytes (64 bits)\n  long mi_long = 4324;            // 8 bytes (64 bits)\n  long long mi_dobleLong = 48329; // 16 bytes (128 bits)\n  float mi_float = 321.4f;        // 4 bytes (32 bits)\n  double mi_double = 43124.432l;  // 8 bytes (64 bits)\n  bool mi_bool_ver = true;\n  bool mi_bool_al = false;\n  char mi_char = 'C';\n  char mi_string[] = \"cadena de texto\";\n\n  // Adicionalmente se pueden definir variables que solo sean positivas\n  // utilizando unsigned antes del tipo de dato\n\n  cout << \"¡Hola C++!\" << endl;\n\n  return 0;\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++/CrisVigas.cpp",
    "content": "// Sitio Oficial de C++: https://isocpp.org/\n\n// Esto es un comentario de una línea\n\n/* Y esto es un comentario\nde varias líneas. */\n\n// librería estandar de entrada y salida por terminal\n#include <iostream>\n\n// librería estandar de cadenas de texto\n#include <string>\n\nint main() {\n  // una variable\n  auto variable{101};\n\n  // una constante\n  const auto constante{42};\n\n  // un valor constante en tiempo de compilación\n  constexpr auto PI{3.141592653589};\n\n  // booleano\n  bool booleano{true};\n\n  // numeros con signo\n  short s{32767};\n  int i{2147483647};\n  long long l{9223372036854775807LL};\n\n  float f{9.8F};\n  double d{6.02E23};\n  long double ld{1.000000000000001L};\n\n  // numeros sin signo\n  unsigned short us{65535U};\n  unsigned int ui{4294967295U};\n  unsigned long long ull{18446744073709551615ULL};\n\n  // caracteres\n  char c{'C'};\n\n  // cadena de texto (definida en <string>)\n  std::string mensaje{\"Hola, C++!\"};\n\n  // para enviar variables a la salida de la terminal\n  std::cout << mensaje;\n\n  return EXIT_SUCCESS;\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++/DiegoIBB.cpp",
    "content": "#include <iostream>\nusing namespace std;\n\nint main(){\n\t// https://isocpp.org\n\t\n\t/*Comentario de varias\n\t  lineas*/\n\t  \n\t  //VARIABLES\n\t  int entero = 5;\n\t  float flotante = 4.5f;\n\t  string cadena = \"Cadena en C++\";\n\t  double Double = 5.6;\n\t  bool boolean = true;\n\t  char caracter = 'D';\n\t  \n\t  //CONSTANTE\n\t  const float constante = 3.14f;\n\t  \n\t  //SALIDA POR TERMINAL\n\t  cout << entero << endl;\n\t  cout << flotante << endl;\n\t  cout << cadena << endl;\n\t  cout << Double << endl;\n\t  cout << boolean << endl;\n\t  cout << caracter << endl;\n\t  cout << constante << endl;\n\t  \n\t  //TERMINAL\n\t  string cPlusPlus = \"C++\";\n\t  cout << \"Hola \"+ cPlusPlus;\n\t  \n\t  return 0;\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++/Eberstr.cpp",
    "content": "\n// url: isocpp.org (no hay sitio oficial)\n\n// Esto es un comentario\n\n/* Esto también es un comentario  */\n\n#include <iostream>\nusing namespace std;\n\n#define constante 1\n\nint main(){\n    char variable = 'variable';\n    const int constant2 = 2;\n\n    int numero = 10;\n    short numeroCorto = 5;\n    long numeroLargo = 100000;\n    long long numeroMuyLargo = 1000000000;\n    unsigned int numeroPositivo = 100;\n\n    char caracter = 'a';\n    char string = 'string';\n    wchar_t letraUnicode = L'Ω';\n    \n    bool verdad = true;\n    bool falso = false;\n\n    float flotante = 1.2f;\n    double float_largo = 1.22222222; // 15 decimales o menos\n    long double numeroLargoDoble = 3.14159265358979323846L;\n\n    cout << \"¡Hola, C++!\";\n    return 0;\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++/Fede6299.cpp",
    "content": "//  Sitio oficial: https://isocpp.org\n\n//  Comentario de una sola linea.\n\n/*  comentario en \n    varias lineas*/\n\n/*  El Header es necesario para poder hacer uso de los tipos de datos stream, en nuestro caso para dar uso a \n    std::cout (ouput stream).*/\n\n#include <iostream>  \n\nint main(){\n\n    char letra = 'A';\n    const unsigned ANIO {2024};\n\n    /* Tipos de datos primitivos/fundamentales */\n\n    // Flotaing Point: Un numero con parte fraccional, 3.14159\n\n    float numero;\n    double parte;\n    long double fraccional;\n\n    // Integral (Boolean) : true o false, true\n\n    bool booleano;\n\n    // Integral (Character) : Un caracter de texto, 'C'\n\n    char un;\n    wchar_t caracter;\n    char8_t de;  // C++20\n    char16_t texto; // C++11\n    char32_t C; // C++11\n\n    // Integral (Integer) : Numeros enteros, positivos y negativos (incluyen el 0), 24\n\n    short enteros;\n    int positivos;\n    long negativos;\n    long long cero;    // C++11\n\n    /*  Integral: dado que cuando estas variables se convierten a binario, el compilador considera a estos\n        tipos como numeros enteros */\n\n    // Null Pointer : Puntero nulo, nullptr\n\n    std::nullptr_t p;   // C++11\n\n    // Void : sin tipo (vacio), n/a\n\n    void HolaMundo(); \n\n    /*  Nota: void es el unico tipo de dato primitivo que con el cual no se pueden definir variables, el contexto\n        del uso del void, es para funcion que no devuelvan valores. Como por ejemplo:\n        \n        void HolaMundo(){\n            std::cout << \"Hello, world!\";\n        }\n\n        Dado que hay tipos de datos de C++20, el mismo archivo debe ser compilado en C++20.\n        Terminal: g++ Fede6299.cpp -o Fede6299.exe -std=c++20\n     \n        Otros tipos de datos son los compuestos y tipos de datos definidos por el usuario. Un ejemplo de tipo\n        de dato compuesto es el string que en otros lenguajes es un tipo de dato primitivo.\n        \n        El uso del sufijo _t, signfica type (tipo) que es parte de la nomenclatura estandar de las nuevas versiones\n        de C++.*/\n\n    std::cout << \"¡Hola, C++!\";\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++/Fravelz.cpp",
    "content": "#include <iostream>\n\n// **************** Pagina Web Oficial de C++ y Tipos de Comentarios **************** //\n\n// https://isocpp-org.translate.goog/?_x_tr_sl=en&_x_tr_tl=es&_x_tr_hl=es&_x_tr_pto=sge\n\n// Comentario de 1 linea\n\n/*\nComentario de\nVarias lineas.\n*/\n\nint main() {\n    // **************** Una variable y Una constante **************** //\n\n    int year = 2025;\n    const std::string name = \"Francisco Velez\";\n    \n    // **************** Tipos de datos nativos de c++ **************** //\n\n    bool booleano = true; \n    char caracter = 'a'; \n    int entero = 71; \n\n    float decimal_pi_f = 3.1;\n    double decimal_pi_d = 3.142;\n    long double decimal_pi_ld = 3.14159;\n\n    std::cout << \"¡Hola, C++!\" << std::endl;\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++/Gallitofast.cpp",
    "content": "// El lenguaje de c++ no tiene red oficial\n// comentario de una linea\n/*\ncomentario de varias lineas\naqui puedo decir lo que yo quiera\nmuchas gracias mouredev por el contenido gratuito\n*/\n\n#include <iostream>\n#include <string>\nusing namespace std;\nint main() {\n  const string constante = \"c++\";\n  string variable = \"Hola, \";\n\n  // Tipos de datos\n\n  // hay diferentes valores numericos\n  short corto = 65524; // este es de 16 bits\n  int entero =\n      4294967294; // este es de 32 bits o 16 bits dependiendo del compilador\n  long largo = 4294967294;                  // este es de 32 bits\n  long long gigante = 18446744073709551614; // este es de 64 bits\n  float flotante = 3.141592;\n  double doble = 3.141592653589793;\n  long double giganteDoble = 1.000000000000001;\n  float scientifico = 6.02E23; // el float también puede usar notación\n                               // cientifica\n  // cout<< corto;\n  // cout<< corto;\n  cout << corto << \"\\n\";\n\n  cout << entero << \"\\n\";\n  cout << largo << \"\\n\";\n  cout << variable + constante << \"\\n\";\n\n cout<<\"Hola mouredev\";\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++/Hades-Dark-X.cpp",
    "content": "# include <iostream>\n# include <string>\nusing namespace std;\n\n//-Sitio de C++: https://isocpp.org/\n\n// - Esto es un comentario en un linea\n\n/* -Esto\nes un comentario\nmultilinea */\n\n// - Tipos de datos números enteros\nint edad= 16;                               //- Entero con signo\nunsigned int puntosGanados= 1500;          //- Entero sin signo, solo valores positivos\nshort dias= 7;                             //- Entero corto\nlong poblacionCdmx= 9209944;              //- Entero largo\n\n// - Tipos de datos números decimales\nfloat temperatura= 36.15f;                 //- El sufijo 'f' para indicar que es un float y tiene menos pesición\ndouble altura= 1.78;                       //- Decimal con mayor precisión\nlong double pi= 3.1415926535;              //- Decimal de alta precicisón\n\n// - Tipos de datos caracter y cadena de carecteres\nchar miInicial= 'M';                       //- Un único caracter, se respetan las comillas simples\nstring miNombre= \"Marcos\";                 //- Es una cadena de texto\n\n// - Tipo de dato booleano\nbool aspiranteSelecionado= true;        //- Verdadero o falso\n\n// - Constantes en C++\nconst string holaMundo= \"Hola Mundo!\";  //- Se ecribe: cosnt tipo de dato nombre y valor\n\nint main(){\n\n    // - Vamos a mostrar los valores de las variables en pantalla\n    cout << \"Una constante: \" << holaMundo << endl;\n    cout << \"Nombre: \" << miNombre << endl;\n    cout << \"Inicial: \" << miInicial << endl;\n    cout << \"Edad: \" << edad << endl;\n    cout << \"Temperatura: \" << temperatura << endl;\n    cout << \"Altura: \" << altura << endl;\n    cout << \"Puntos Ganados: \" << puntosGanados << endl;\n    cout << \"Días de la semana: \" << dias << endl;\n    cout << \"Población de CDMX: \" << poblacionCdmx << endl;\n    cout << \"Número Pi: \" << pi << endl;\n    cout << \"Asipirante Seleccionado: \" << aspiranteSelecionado << endl;\n    return 0;\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++/ItsThemasii.cpp",
    "content": "#include <iostream>\nusing namespace std;\n\n// hola comentario, aqui dejo el url del sitio web de mi lenguaje https://cplusplus.com\n/*Este tambien es un comentario de varias lineas !!!! :p \ny  aqui tambien!!! */\n\nint main() {\n    // Variables\n    int massi = 2006;\n\n    string const massito = \"Este es mi constante\";\n\n    // Variables con sus representaciones\n    bool soytherian = false;\n    int entero = 20;\n    string texto = \"Hola que tal\";\n    float flotante = 1.15;\n    long numero1 = 12345566;\n    long long numero2 = 1234456789;\n    char letra = 'M';\n    \n    // Finalizando terminado el hola mundo y mi lenguaje\n\n\n    cout << \"Hola Mundo, este lenguaje es c++!!! \" << endl;\n\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++/JRmantilla66.cpp",
    "content": "#include <iostream>\n\n// https://isocpp.org\n\nusing namespace std;\nint main(){\n//comentario en una linea;\n\n/* comentario en varias lineas\n( se debe abrir y cerrar como se muestra aqui) */\nint variable_dedicada_a_enteros = 7;\nfloat variable_flotante = 8.9f;\nbool variable_de_verdadero = true;\nbool variable_de_falso = false;\nchar de_un_caracter = 'D';\n\nconst int para_que_la_variable_sea_constante_entero = 20;\ncout<<\"para poner una cadena de texto.\\n\";\ncout<<\"!hola_c++¡\" <<end1;\nreturn 0;\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++/MaviGareli.cpp",
    "content": "#include <iostream>\r\n\r\n\r\n/*  Crea un comentario en el código y coloca la URL del sitio web oficial del\r\n    lenguaje de programación que has seleccionado.*/\r\n\r\n        // https://isocpp.org/\r\n\r\n/*  Representa las diferentes sintaxis que existen de crear comentarios\r\n    en el lenguaje (en una línea, varias...).*/\r\n        \r\n        /*Bloque para varios comentarios*/\r\n        //Comentarios de una sola línea \r\nint main() {\r\n/*  Crea una variable (y una constante si el lenguaje lo soporta).*/\r\n        auto var = 0;\r\n        const auto myConst= 0;\r\n\r\n/*  Crea variables representando todos los tipos de datos primitivos\r\n    del lenguaje (cadenas de texto, enteros, booleanos...).*/\r\n\r\n        int numEntero = 0;\r\n        long numEnteroLargo = 123456789;\r\n        float numDecimal = 1.23;\r\n        double numDecimalDoblePrecision = 2.33333;   \r\n        char letra = 'M';\r\n        bool mybool = true;\r\n        void* myVoid = nullptr;\r\n\r\n/*  Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"*/\r\n\r\n    std::cout <<\"¡Hola, C++!\"<<std::endl;\r\n    \r\n    return 0;   //0 indica que el programa se ejecutó correctamente\r\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++/Over-KR.cpp",
    "content": "// Web Oficial De C++: https://isocpp.org/get-started\n\n\n//con este podemos hacer un comentario en una sola linea\n\n/*\neste para \nvarias lineas\n*/\n\n#include <iostream>\nusing namespace std ;\n\nint main () {\n\n//variable y constante\nconst int Constante = 1 ;\nint Variable = 0 ;\n\n//tipos de datos primitivos\nfloat Flotante = 1.12 ;\n\ndouble Doble = 1214123425325567432.23 ;\n\nint Entero = 1 ;\n\nchar Caracteres = 'a' ;\n\nbool e = true ;\n\n//Para imprimir un mensaje en la terminal\n\ncout<<\"Hola, C++\"<<endl ;\n\n\nreturn 0;\n\n\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++/Porto1090.cpp",
    "content": "#include <iostream>\nusing namespace std;\n\nint main()\n{\n    // https://isocpp.org\n\n    // Comentario de una sola línea\n\n    /*\n    Este es un comentario \n    compuesto\n    de varias líneas\n    */\n\n    //VARIABLES\n    int entero = 5;\n    float flotante = 4.5f;\n    string cadena = \"Cadena en C++\";\n    double Double = 5.6;\n    bool boolean = true;\n    char caracter = 'D';\n\n    //CONSTANTE\n    const float constante = 3.14f;\n\n    //SALIDA POR TERMINAL\n    cout << entero << endl;\n    cout << flotante << endl;\n    cout << cadena << endl;\n    cout << Double << endl;\n    cout << boolean << endl;\n    cout << caracter << endl;\n    cout << constante << endl;\n\n    //TERMINAL\n    string cPlusPlus = \"C++\";\n    cout << \"Hola \" + cPlusPlus << endl;\n\n    return 0;\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++/RoniPG.cpp",
    "content": "// @RoniPG\n\n#include <iostream>\n\nusing namespace std;\n\nint main(){\n\t//URL = https://cplusplus.com/\n\t// Comentario en una linea.\n\t/*\n\t * Comentario de varias lineas.\n\t*/\n\tshort sh = 0 ; // start= -32768; end = 32767 ;\n\tint in = 0; // start= -2^31; end = 2^31 ;\n\tlong long lo = 0; // start= -2^63; end = 2^63 ;\n\tfloat fl = 0.0; // ---> numeros decimales simples con 7 decimales.\n\tdouble dl = 0.0; // ---> numeros decimales largos con 15 decimales.\n\tbool bo = false; // ---> valores: true, false(por defecto).\n\tchar ch = 'a'; //---> valor para una letra/caracter.\n\n\t//Para crear una constante se añade 'const' antes de indicar el tipo de variable.\n\t//Destacar el 'unsiged' antes de la variable para utlizar solo los valores positivos.\n\tconst int fi=0;\n\n\tcout<<\"hola C++\";\n\treturn 0;\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++/VictorJaimesR.cpp",
    "content": "//https://isocpp.org/\n\n//En una línea\n\n/*En varias líneas*/\n\n#include<iostream>\nusing namespace std;\n\nint variable=1;\nconst int constante=0;\nbool booleano=true;\nfloat flotante= 1.5;\ndouble doble=1.4829382485;\nchar letra='a';\nstring cadena= \"hola\";\n\nint main(){\n\n    cout<<\"Hola mundo\"<<endl;\n    cout<<variable<<endl;\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++/Vid92.cpp",
    "content": "//https://cplusplus.com\n//https://isocpp.org\n\n/*\n  Esto es otro tipo de comentario,\n  varias líneas\n*/\n\n#include <iostream>\t\t\nusing namespace std;\n\nconst char lenguaje[4] = \"C++\";     //constante \n\nint main()\n{\n  int entero = -89;\n  long enterolargo = 1022;\n  short enterocorto = 256;\n  unsigned short int enterocorto_sinsigno = 23470;           \n  unsigned long int enterolargo_sinsigno = \t294967267;   \n \n  float y = -1.5;\t\t\t                         //variable tipo flotante\n  double z = 0.000809;                               //variable tipo double\n  \n  bool bandera = true;\t\t                         //variable tipo booleano\n  bool bandera2 = false;\n  \n  char letra = 'H';                                  //variable tipo char\n  unsigned char charsinsigno = 'A';\n   \n\n  cout << \"Hola \"<<lenguaje<<endl;\t\t             //imprime por terminal\n  \n  return 0;\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++/agusrosero.cpp",
    "content": "/*\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n// https://cplusplus.com/\n\n// Comentario de una linea\n\n/*\nComentario\nde\nvarias lineas\n*/\n\n#include <iostream>\n\nusing namespace std;\n\n#define PI 3.1416; // Definimos una constante llamada PI\n\nint main()\n{\n    string miVariable = \"C++\";\n\n    // Tipos Enteros\n    int myInt = 23;\n    short myShort = 7;\n    long myLong = 8888888888;\n    long long myLongLong = 999999999999999;\n    // Tipos de Punto Flotante\n    float myFloat = 3.14;\n    double myDouble = 33.3333;\n    long double myLongDouble = 33333.333333;\n    // Tipo Carácter\n    char myChar = 'a';\n    signed char mySignedChar = -65;\n    unsigned char myUnsignedChar = 200;\n    wchar_t myWideChar = L'Ω';\n    // Tipo Booleano\n    bool myBool = true;\n    // Tipos de Caracteres Unicode\n    char16_t myChar16 = u'Ω';\n    char32_t myChar32 = U'Ω';\n\n    cout << \"¡Hola, C++!\" << endl;\n    return 0;\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++/andreessj.cpp",
    "content": "/* EJERCICIO : Crea un comentario en el código y coloca la URL del sitio web oficial del\n            lenguaje de programación que has seleccionado.Representa las diferentes sintaxis que existen de crear comentarios\n            en el lenguaje(en una línea, varias...)\n            .Crea una variable(y una constante si el lenguaje lo soporta)\n            .Crea variables representando todos los tipos de datos primitivos del lenguaje(cadenas de texto, enteros, booleanos...)\n            .Imprime por terminal el texto : \"¡Hola, [y el nombre de tu lenguaje]!\" */\n\n#include <iostream>\n#include <stdio.h>\n\n#define MaxValue 256 // Constante\n\nusing namespace std;\n\nint main()\n{\n    int value = 3;         // enteros\n    float pi = 3.14;       // decimales\n    bool verdadero = true; // booleanos\n    bool falso = false;\n    char letter = 'a';            // de caracter\n    string hello = \"Hola C++!\\n\"; // cadena de caracteres\n\n    cout << hello;\n\n    system(\"pause\");\n    return 0;\n}\n\n/*\ncomentario\nen varias\nlineas\n*/\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++/carZep09.cpp",
    "content": "#include <iostream> \nusing namespace std; \n\nint main()\n{\n    // https://isocpp.org/\n\n    // comentario de una sola linea \n    \n    /* También esto \n        es un comentario \n        en varias lineas */\n\n\n    string mi_variable = \"Esta es mi variable\"; \n    mi_variable = \"Un nuevo mensaje en mi variable\"; \n\n    const string MI_CONSTANTE = \"Constante, ¡esta fija!\"; \n\n    int entero = 20;\n    double doble = 5.3; \n    float flotante = 10.2f; \n    bool booleo = true; \n    string cadena = \"Mi texto\";\n    char caracter = 'E';  \n\n    cout << \"Hola, C++\" << '\\n';  \n\n\n    return 0; \n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++/carlosguariglia.cpp",
    "content": "// URL del sitio web oficial de C++: https://isocpp.org/   \n// Generado por Chatgpt\n\n// Comentarios en una línea\n\n/*\n   Comentarios\n   en varias\n   líneas\n*/\n\n#include <iostream> // Para poder usar std::cout\n#include <string>   // Para poder usar el tipo std::string\n\n// Constante (en C++)\nconst double PI = 3.14159;\n\nint main() {\n    // Variables con diferentes tipos de datos primitivos\n    int numeroEntero = 42;\n    float numeroDecimal = 3.14f;\n    double numeroDoble = 2.718281828;\n    bool esVerdadero = true;\n    char letra = 'C';\n    std::string cadenaDeTexto = \"¡Hola, C++!\";\n\n    // Imprimir por terminal\n    std::cout << \"¡Hola, C++!\" << std::endl;\n\n    // Imprimir el valor de las variables\n    std::cout << \"Número Entero: \" << numeroEntero << std::endl;\n    std::cout << \"Número Decimal (float): \" << numeroDecimal << std::endl;\n    std::cout << \"Número Doble (double): \" << numeroDoble << std::endl;\n    std::cout << \"Booleano: \" << (esVerdadero ? \"Verdadero\" : \"Falso\") << std::endl;\n    std::cout << \"Carácter: \" << letra << std::endl;\n    std::cout << \"Cadena de Texto: \" << cadenaDeTexto << std::endl;\n\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++/cesar-ch.cpp",
    "content": "#include <iostream>\n\nusing namespace std;\n\n// URL: https://isocpp.org/\n\n// This is a one line comment\n\n/*\n    This is a multi-line comment\n*/\n\nint main()\n{\n    // This is a variable\n    int myVariable = 10;\n    // This is a constant\n    const int myConstant = 20;\n\n    // These are primitive data types\n    bool myBoolean = true;\n    char myChar = 'C';\n    int myInt = 10;\n    float myFloat = 10.5;\n    double myDouble = 10.5;\n    short int myShortInt = 10;\n    long int myLongInt = 2080991295;\n    long long int myLongLongInt = 2080991295;\n    unsigned int myUnsignedInt = 10;\n    unsigned long long int myUnsignedLongInt = 9223375775807;\n\n    // This prints in terminal\n    cout << \"Hola, C++!\" << endl;\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++/darkohokage.cpp",
    "content": "//https://cplusplus.com\n\n//Con dos barras se crea un comentario de linea\n\n/* Con barra y asterisco\nse crea un comentario de \nvarias lineas cerrando con asterisco y barra\n*/\n\n#include <iostream> //Se necesita incluir esta librería para las entradas y salidas en c++\n\nusing namespace std; //se utilizapara poder utilizar los identificadores de la biblioteca estandar sin tener que usar std:: aunque no es la mejor de las prácticas\n\nmain()\n{\nconst constante = 100; //con la palabra reservada const podemos declarar una constante seguidamente del nombre y del valor que va a tener\nint entero = 10; /*para decarar una variable que almacenará valores de tipo enteros de utiliza la parabra reservada int seguido del nombre \nde la variable, una buena practica es inicializar la variable es decir darle un valor en el momento de la declaración*/\nfloat decimal = 10.10; //se utiliza para declarar numeros decimales usando mismo esquema que la anterior pero con la palabra float\ndoble decimales = 10.000020020203030203004040404; //se utiliza cuando se necesita trabajar con decimales muy grandes\nbool logica = True; //esta es la forma de declarar una variable booleana de tipo logica, es decir, que sus valores son \"true\" o \"false\"\nchar texto = \"Cadena de Texto\"; //char se utiliza para declarar una variable de tipo cadena de texto\n\ncout <<\"¡Hola, C++!\" <<endl; //con cout se imprime en pantalla y el comando endl permite devolver el cursor en la siguiente linea\n  \n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++/davidvela-306.cpp",
    "content": "// Libraries\n#include <iostream> // this library let us work with input and output objects such as cout\n#include <string>\n\n// https://isocpp.org/\n/*\n * Este es un \n * comentario en \n * varias lineas\n * */\n\n// Variable\nstd:: string name = \"My name is David\"; //std:: show that we'll use standar librarie's string specifically\n// Constant\nconst float PI = 3.1415; // Unchangable, read-only\n\n/*\n * PRIMITIVE DATA TYPES\n * */\nint number = 1; // 4 bytes\nshort int short_number = 1; // 2 bytes\nlong int long_number = 12312938793847; // 4 u 8 bytes\nlong long int super_long_number =239482983748927; // more than 8 bytes\n\t\t\t\t\t\t //\nfloat float_number = 1.22f; // 4 bytes\ndouble double_number = 1.29303920; // 8 bytes\nlong double long_double_number = 1.230948023984023894; // 10 or 16 bytes\nstd:: string text = \"Hi\";\nchar letter = 'd';\n\nbool my_boolean = true; // only needs one bite but it is defined with 1 byte\n\n/*\n * PRINT HELLO [ LANGUAGE]\n * */\n\nint main(){\n\tstd:: cout << \"Hello, C++ \\n\"; // \\n is a line break\nreturn 0;\n}\n// it is not necesary call main function because is the entry point's program.\n\n/*\n * TO RUN THE PROGRAM I NEEDED TO USE g++\n * Create the executable with g++ ./davidvela-306.cpp -o davidvela-306\n * Then run ./davidvela-306\n * */\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++/diegomm27.cpp",
    "content": "/*\n    WEBSITE OFFICIAL URL: https://isocpp.org/\n*/\n\n/*\n    Code comments can be made by different ways:\n\n        1. For a long piece of code, we can use '/*' to start a comment and the reverse to finish it.\n        2. Using two slices slashes '//' to comment all the code in a line.\n\n*/\n\n#include <iostream>\n#include <string>\nusing namespace std;\n\n/*\n\n    Character types: They can represent a single character, such as 'A' or '$'. The most basic type is char, which is a one-byte character. Other types are also provided for wider characters.\n    Numerical integer types: They can store a whole number value, such as 7 or 1024. They exist in a variety of sizes, and can either be signed or unsigned, depending on whether they support negative values or not.\n    Floating-point types: They can represent real values, such as 3.14 or 0.01, with different levels of precision, depending on which of the three floating-point types is used.\n    Boolean type: The boolean type, known in C++ as bool, can only represent one of two states, true or false.\n\n*/\n\n\nconst string lenguaje = \"C++\"; // Variable tipo constante\n\n// Character types:\nstring mystring = \"¡Hola Mundo!\"; \n\nchar character = 'D'; // Exactly one byte in size. At least 8 bits.\nchar16_t char16 = '!'; // Not smaller than char. At least 16 bits.\nchar32_t char32 = '!'; // Not smaller than char16_t. At least 32 bits.\nwchar_t wchar = '!'; // Can represent the largest supported character set\n\n// Numerical integer types\nsigned char signedChar = 5; // Same size as char. At least 8 bits.\nsigned short int signedShortInt= 5; // \tNot smaller than char. At least 16 bits.\nsigned int signedInt = 5; // Not smaller than short. At least 16 bits.\nsigned long int signedLongInt= 5; // \tNot smaller than int. At least 32 bits.\nsigned long long int signedLong2int = 5; // Not smaller than long. At least 64 bits.\n\n// Just as we have for the numerical SIGNED integer types, we would have the UNSIGNED ones\n\n// Floating-point types\nfloat floatValue = 16.5;\ndouble doubleFloat = 16.5;\nlong double longDoubleFloat = 16.5;\n\n// Boolean type\nbool booleano = true;\n\n\nint main()\n{\n    cout << \"Hola, \" + lenguaje + \"!\"<< endl;\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++/dotero-dciencia.cpp",
    "content": "// https://isocpp.org/\n// Comentario en una línea\n/*\nComentario en varias líneas\n*/\n\n#include<iostream>\n#include<string>\n\nusing namespace std;\n\nint main()\n{\n    int numero = 5;\n    const int numeroConstante = 9;\n    \n    short a = 5;\n    long b = 123456;\n    long long c = 12391238214213;\n    \n    float d = 3.14;\n    double e = 3.1415926535;\n    long double f = 3.141592653584123123213;\n    \n    char caracter = 'A';\n    signed char caracterSigno = -65;\n    unsigned char caracterSinSigno = 65;\n    \n    bool verdadero = true;\n    \n    cout << \"¡Hola, C++!\";\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++/elsanty08.cpp",
    "content": "// https://isocpp.org/ \n//ademas usaré la documentacion de \n//https://dev.epicgames.com/documentation/en-us/unreal-engine/epic-cplusplus-coding-standard-for-unreal-engine\n\n// este es un comentario en una sola linea\n\n/*\nesto es un comentario\nen varias lineas\n*/\n\n#include <iostream>\n#include <string>\n\nint main() {\n//variable\nint num = 08;\n\n//datos primitivos\n\nint numerico = 08;\nfloat decimal = 2.3f;\ndouble decimal2 = 3.5;\nbool boleana = true;\n\nstd::string Hola = \"Este es el string\";\n\nconst float PI = 3.1416;\n\nstd::cout << \"!Hola C++¡\";\n\nreturn 0;\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++/hectorio23.cpp",
    "content": "// Bibliotecas requeridas\n#include <iostream>\n#include <string>\n\n// URL del sitio web oficial de C++\n// https://isocpp.org/\n// Comentarios de una línea\n\n/*\nComentario que \nrequiere de \nvarias lineas \n*/\n\n/* \nEn c++ existen un monton de datos primitivos, cada uno se usa para cumplir con una necesidad,\nsin embargo, los mas usados y conocidos son:\n- int\n- float\n- double\n- char\n- string\n- bool \n*/\n\n// Variable\nint unaSimpleVariable = 42;\n\n// Constante\nconst double PI = 3.14159;\n\n// Tipos de datos primitivos\n// Enteros\nint entero = 42;\nunsigned int enteroSinSigno = 123;\nshort enteroCorto = 10;\nunsigned short enteroCortoSinSigno = 20;\nlong enteroLargo = 12345;\nunsigned long enteroLargoSinSigno = 67890;\nlong long enteroLargoLargo = 987654321;\nunsigned long long enteroLargoLargoSinSigno = 876543210;\n\n// Punto flotante\nfloat puntoFlotante = 3.14f;\ndouble puntoFlotanteDoble = 2.71828;\nlong double puntoFlotanteLargo = 0.123456789;\n\n// Caracteres\nchar caracter = 'A';\nunsigned char caracterSinSigno = 'B';\nwchar_t caracterAmplio = L'C';\n\n// Booleano\nbool booleanoVerdadero = true;\nbool booleanoFalso = false;\n\n// Cadenas de texto\nstd::string cadenaDeTexto = \"Hola, C++!\";\n\n// Punteros\nint* punteroEntero = &entero;\n\n\nint main() {\n    // Imprimir por terminal\n    std::cout << \"¡Hola, C++!\" << std::endl;\n\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++/jhoshmc.cpp",
    "content": "/*\n? EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n*/\n//* citio que creo que es el oficial: https://cplusplus.com/\n//* la sintaxis para un  comentaio de una sola línea se representa por dos barras\n\n/*\n * En su contrario, la sintaxis para un comentario \n *  de varias lieas se representa por un inicio de una barra seguido de un asterisco\n * y terminando de un asterirsco seguido por una barra, esto el text en medio\n \n*/\n// *esta es una variable de tipo entera, solo acepta numeros enteros\nint variableEntera = 1; \n//* esta es una variable constante pero su tipo es flotante, acepta numeros flotantes y enteros\nconst float fl = 0.5;\n\nint entero= 1; // hacepra valor entero\nfloat flotante= 1.5; // acepta valores enteros y flotantes\nbool booleano = true; // acepta solo dos valores, true o false;\ndouble db = 1.6543; // es como un float pero con mayor cantidad de bits\nchar letra = 'a'; // hacepra un caracter\n// hacepra una cadena de caracteres, va entre comillas dobles\n//* string palabra = \"hola a todos\"; \nint array[5];// almacenamiento por celdas continuas en la memoria ram, puden ser números , caracteres, palabras, todo dependiendo del tipo en el que se declaren.\n\n// Vector es como un array, pero con más funcionalidades, según yo :v\n//* vector<string> vectorDePalabras(6);\n\n#include <iostream>\n#include <vector>\nusing namespace std;\nint main()\n{\n  cout << \"¡ Hola, C++ !\" << endl;\n  return 0;\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++/kevin05m.cpp",
    "content": "// Pagina web oficial: https://isocpp.org\n\n/* Comentario\nen varias\nlineas */\n\n// Utilizaré el paradigma Orientado a Objetos para practicar la Universidad\n\n#include <iostream>\n\nusing namespace std;\n\nclass TipoVariables{\n    private:\n    int entero;\n    float decimal;\n    double muchosDecimales;\n    bool booleano;\n    string cadenaDeTexto;\n    char caracter;\n    \n    public:\n    TipoVariables(){\n        // Constructor\n        entero = 2;\n        decimal = 2.12;\n        muchosDecimales = 3.14157;\n        booleano = true;\n        booleano = false;\n        cadenaDeTexto = \"Cadena de texto\";\n        caracter = 'A';\n    }\n    void print(){\n        cout << \"Entero: \" << entero << endl;\n        cout << \"Decimal: \" << decimal << endl;\n        cout << \"Double: \" << muchosDecimales << endl;\n        cout << \"Booleano: \" << booleano << endl;\n        cout << \"String: \" << cadenaDeTexto << endl;\n        cout << \"Caracter: \" << caracter << endl;\n    }\n    void hola_lenguaje(string lenguaje){\n        cout << \"Hola, \" << lenguaje << \"!\\n\";\n    }\n};\n\nint main(){\n    TipoVariables variable;\n    variable.print();\n    variable.hola_lenguaje(\"C++\");\n    return 0;\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++/lilberick.cpp",
    "content": "// https://cplusplus.com/\n#include<iostream>\nusing namespace std;\n// Comentario de una línea\n/*Comentario de \nvarias líneas*/\nint main(){\n\t// VARIABLE Y CONSTANTE\n\tdouble variable = 2.35;\n\tconst double PI = 3.14159;\n\n\t// TIPOS DE DATOS PRIMITIVOS\n\t// Cadenas de texto\n\tstring mi_nombre = \"Bard\";\n\tstring mi_frase = \"Hola, soy Bard\";\n\n\t// Enteros\n\tint mi_edad = 18;\n\tfloat mi_altura = 1.75;\n\n\t// Flotantes\n\tdouble mi_peso = 75.5;\n\tdouble mi_sueldo = 1500.00;\n\n\t// Booleanos\n\tbool soy_mayor_de_edad = true;\n\tbool soy_soltero = false;\n\n\t// Impresión\n\tcout << \"¡Hola, C++!\" << endl;\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++/m-doce.cpp",
    "content": "//Sitio oficial -> https://isocpp.org/\r\n\r\n//Comentario de una sola línea\r\n\r\n/*Comentario\r\nde\r\nmúltiples\r\nlíneas*/\r\n\r\n#include <iostream>\r\n\r\nint main()\r\n{\r\n    const int year = 2024;\r\n    int number = 12;\r\n    float distance = 24.7;\r\n    bool check = false;\r\n    char *letter = \"M\";\r\n\r\n    printf(\"Hola, C++ !\");\r\n\r\n    return 0;\r\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++/m-hadz.cpp",
    "content": "#include <iostream>\n\n// https://isocpp.org\n\n// Se usa para comentarios de una linea\n\n/*\n * Se utiliza para comentarios\n * de multiples lineas\n */\n\nchar variable = 'e';\n\nconst double constante = 3.14;\n\n// Estos son los tipos de datos primitivos de c++\n\nchar caracter = 'h';\n\nint entero = 9;\n\nfloat flotante = 3.1;\n\ndouble doble = 3.123;\n\nbool booleano = true;\n\n// Para imprimir se utiliza el objeto std::cout\n\nint main () {\n    std::cout << \"¡Hola, C++!\" << std::endl;\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++/miguelex.cpp",
    "content": "// Documentación en https://devdocs.io/cpp/\n\n// Comentario en una linea\n\n/*\nComentario\nen varias\nlineas\n*/\n\n#include <iostream>\n#include <string>\n\nint main()\n{\n\n    // Declaramos una variable\n    int unaSimpleVariable = 1;\n\n    // Constante\n    const double PI = 3.14159;\n\n    // Tipos de datos primitivos\n    int entero = 1;\n    unsigned int enteroSinSigno = 120;\n    short enteroCorto = 10;\n    unsigned short enteroCortoSinSigno = 10;\n    long enteroLargo = 123456789;\n    unsigned long enteroLargoSinSigno = 876543210;\n    long long enteroLargoLargo = 1236547899;\n    unsigned long long enteroLargoLargoSinSigno = 999999999;\n    float puntoFlotante = 3.1415f;\n    double puntoFlotanteDoble = 2.71828;\n    long double puntoFlotanteLargo = 0.123456789;\n    char caracter = 'a';\n    unsigned char caracterSinSigno = 'a';\n    wchar_t caracterAmplio = L'a';\n    bool Verdadero = true;\n    bool Falso = false;\n    std::string cadenaDeTexto = \"En C++ tenemos cadenas\";\n    int *punteroEntero = &entero;\n\n    // Impresión por consola\n    std::cout << \"Hola, C++!\" << std::endl;\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++/oixild.cpp",
    "content": "\n\n// WEBSITE> https://isocpp.org/\n\n// Code comments can be made by different ways :\n\n// Line Comment\n\n/*\nBlock\nComment\n*/\n#include <iostream>\n\nvoid varConstVar() {\n\tint var = 1;\n\tconst int constVar = 2;\n}\n\nvoid primitiveData() {\n\tint a = 0;\n\tfloat b = 1.5;\n\tdouble float c = 2.5;\n\tchar d = 'a';\n\tbool e = true;\n\twchar_t f = L'C';\n}\n\nint main() {\n\tstd::cout << \"Hola, [C++]!\" << std::endl;\n\treturn 0;\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++/pablo-lnx.cpp",
    "content": "#include <iostream>\n#include <string>\nusing namespace std;\n\n/* \nCrea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\nRepresenta las diferentes sintaxis que existen de crear comentariosen el lenguaje (en una línea, varias...).\nCrea una variable (y una constante si el lenguaje lo soporta).\nCrea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\nImprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n*/\n\n// Web Oficial de C++ -> https://isocpp.org/ \n\n/* Inicio del \ncódigo */\n\n// Tipos de datos\n    \n// 'int'\nint myInt = 112; \n\n// 'float'\nfloat myFloat = 7.9234;\n\n// 'double'\ndouble myDouble = 7.834758923745;\n\n// 'char'\nchar myChar = 'p';\n\n// 'string'\nstring myString = \"Aprendiendo C++\";\n\nint main(){\n    // Ejemplo práctico:\n    \n    // Creación de una constante: const type variableName = value;\n    const float PI = 3.141516;\n\n    // Creación de una varible: type variableName = value;\n    int radio = 15;\n    double area = radio * radio * PI;\n\n    // Imprime el resultado en la terminal\n    cout << \"Area: \"<< area << endl;\n\n    // Muestra en pantalla \"Hola C++\"\n    string language = \"C++\";\n    cout << \"Hola \" << language;\n\n    return 0;\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++/roscelidcode.cpp",
    "content": "//Sitio web de lengauje c++ https://isocpp.org/\n\n//comentario de una linea\n\n/*comentario \nde varias lineas*/\n\n#include <iostream>\n#include <string>\n\nusing namespace std;\n\nint main()\n{\n    string miVariable = \"Variable\"; //variable\n    miVariable = \"Mi nueva variable\"; //variable modificada\n    \n    const string variableConst = \"Variable constante\"; //variable constante\n\n    //datos primitivos\n    int num1 = 10; //entero\n    float num2 = 3.14; //flotante\n    double num3 = 3.14159; //double, el más usados para decimales\n    char caracter = 'A'; //caracter\n    bool booleano = true; //booleano\n    string texto = \"Hello, world!\"; //cadena de texto\n\n    cout << \"Hello, C++\" << endl;\n\n    return 0;\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++/sanet0512.cpp",
    "content": "// https://isocpp.org/\n// Comentario de una linea\n\n/* Comentario \n  de\n  multiples\n  Lineas */\n\n//Variable\n\nint numero = 9 ; \n\n//Constante \n\nconst tipo nombre = valor;\n\n/* \ntipo: Especifica el tipo de datos de la constante.\nnombre: Es el nombre único que se le da a la constante.\nvalor: Es el valor constante que se asigna a la constante. \n*/\n\nconst double PI = 3.14159;\n\nstd::cout << PI << std::endl; // Imprime: 3.14159\n\nPI = 3.5; // ❌ Esto dará un error, no puedes reasignar una constante\n\n//Tipos de Variables \n\nint edad = 0;\nfloat altura = 0.0f;\ndouble peso = 0.0;\nchar inicial = '\\0';\nbool esEstudiante = false;\n\n//Para imprimir por la terminal el texto\n\n#include <iostream>\n\nint main() {\n    // Imprime la cadena de texto en la terminal.\n    std::cout << \"¡Hola, C++!\" << std::endl;\n    \n    // Opcional: También puedes usar '\\n' en lugar de std::endl, a menudo es más rápido.\n    // std::cout << \"¡Hola, C++!\\n\";\n\n    return 0; \n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++/skala2301.cpp",
    "content": "#include <iostream>\n#include <cstdint>\n#include <stdio.h>\n#include <vector>\n#include <array>\n#include <string>\n#include <limits>\n#include <cassert>\n#include <type_traits>\n#include <bitset>\n/************************************************************************************************************\n*******************************REFERENCIAS DEL LENGUAJE C++**************************************************\n*************************************************************************************************************\n*sitio oficial de referencia https://learn.microsoft.com/es-es/cpp/cpp/cpp-language-reference?view=msvc-170 *\n*Referencias recomendadas personalmente:                                                                    *\n*  https://en.cppreference.com/w/                                                                           *\n*  https://www.learncpp.com/                                                                                *\n************************************************************************************************************/\nint returnTen();// fordware declaration de funcion que retorna el numero 10\n\n\n//TODO LO DECLARADO ACA ES GLOBAL\n\n/************************************************\n*AQUI DECLARAMOS TODAS LAS CONSTANTES A UTILIZAR*\n************************************************/\nconst int UNO{1}; //syntaxis: const /tipo/ /nombre/\nconst float UN_MEDIO{0.5};\nconst double UNO_Y_MEDIO{1.5};\nconst bool VERDADERO{true};\nconst int TEN{returnTen()};       //esta constante es especial, el valor no es conocido en tiempo de compilacion\n//LAS SIGUIENTES SON CONSTANTES CUYO VALOR SERA CONOCIDO SIEMPRE EN TIEMPO DE COMPILACION\nconstexpr int DOS{2};\nconstexpr double DOS_MEDIOS{2.5};\nconstexpr double Z{DOS_MEDIOS+DOS}; //AQUI SE VE LA UTILIDAD DEL constexpr SON CONSTANT EXPESSIONS AUNQUE SEAN OPERACIONES, ESTAS SON CONOCIDAS ANTES DE CORRER EL PROGRAMA EN TIEMPO DE COMPILASION, POR LO QUE ES MAS EFICIENTE YA QUE LA OPERACION NO SE REPITE CADA VEZ QUE SE CORRE EL PROGRAMA\n\n/*************************************************\n**AQUI DECLARAMOS TODAS LAS VARIABLES A UTILIZAR**\n*************************************************/\n\nchar miCaracterBase{0};                 //reservan 8bits de informacion en memoria, segun la arquitectura de sistema puede ser signado o no por defecto.\nsigned char miCaracter{-120};           //reservan 8bits de informacion en memoria, rango desde -128 a 127.\nunsigned char miCaracterNoSign{255};    //reservan 8bits de informacion en memoria, rango desde 0 a 255\nshort miInt{10};                        //reservan 16bits de informacion en memoria\nsigned short miIntSignado{};            //reservan 16bits de informacion en memoria, rango desde -32768 a 32767\nunsigned short miIntNoSignado{};        //reservan 16bits de informacion en memoria, rango desde 0 a 65535\nint miVariable{0};                      //valores enteros por defecto signado al menos de 16bits de informacion depende de modelo de datos del sistema en LP64 o 4/8/8 int es de 32bits\nlong miIntLong{0};                      //valores enteros por defecto signado al menos de 32bits de informacion depende de modelo de datos del sistema en LP64 o 4/8/8 int es de 64bits\nunsigned long miUIntLong{0};            //version no signada de long\nlong long miInt2Long{0};                //valores enteros por defecto signado de 64bits\nunsigned long long miUInt2Long{0};      //version no signada de long long\nfloat miFlotante{0.0};                  //valores punto flotante usualmente de 32bits, siguen formato de IEEE-754 binary32 format\ndouble miFlotanteD{0.0};                //valores punto flotante usualmente de 64bits, siguen formato de  IEEE-754 binary64 format\n/*********************\n*FIXED WIDTH INTEGERS*\n*********************/\nstd::int8_t miInt8bits{0};              //int de 8bits estandarizado\nstd::uint8_t miUInt8bits{0};            //int de 8bits no signado estandarizado\nstd::int16_t miInt16bits{0};            //int de 16bits estandarizado\nstd::uint16_t miUInt16bits{0};          //int de 16bits no signado estandarizado\nstd::int32_t miInt32bits{0};            //int de 32bits estandarizado\nstd::uint32_t miUInt32bits{0};          //int de 32bits no signado estandarizado\nstd::int64_t miInt64bits{0};            //int de 64bits estandarizado\nstd::uint64_t miUInt64bits{0};          //int de 64bits no signado estandarizado\nstd::size_t s_t{0};                     //es definido como un typo integral no signado su tamaño varia dependiendo la arquitectura pero garantiza ser de al menos 16Bits\n\nwchar_t miCaracter8Bit{};               //hecho para representar cualquier unidad de codigo UTF-32 en linux UTF-16 en windows\nchar16_t miCaracter16Bit{};             //para representar cualquier unidad de codigo UTF-16\nchar32_t miCaracter32Bit{};             //para representar cualquier unidad de codigo UTF-32\n\n//Los int fast funcionan como los fixed width integers, pero son mâs râpidos, sin embargo hay que evitarlos pueden provocar desperdicio de memoria y undefinded behaviour, que seria como comportamientos indefinidos, esto sucede cuando se pierde rastro de las regiones de memoria, pero lo mejor es ver la referencia oficial para mayor informacion\nstd::int_fast8_t miFastInt8bits{0};\nstd::uint_fast8_t miFastUInt8bits{0};\nstd::int_fast16_t miFastInt16bits{0};\nstd::uint_fast16_t miFastUInt16bits{0};\nstd::int_fast32_t miFastInt32bits{0};\nstd::uint_fast32_t miFastUInt32bits{0};\nstd::int_fast64_t miFastInt64bits{0};\nstd::uint_fast64_t miFastUInt64bits{0};\n\n\n\n\n/*****************************************************************************\n*<bitset> es una libreria que permite la manipulacion directa con bits en c++*\n*****************************************************************************/\nstd::bitset<8> banderas{0b0000'0000};   //el valor correcto a usar con bitset es en formato de bits como se muestra en este ejemplo\nstd::bitset<16> estados{0x00FF};        //en este caso colocamos el valor de 0x00FF que es tratado como int o char, pero cpp hace una conversion implîcita a bits\n\n//definicion de enum class Marca, los enum class se prefieren en ocaciones a los enum porque funcionan parecido a un namespace, esto evita colisiones entre tipos\nenum class Marca{\n    audi,\n    ferrari,\n    chevrolet,\n    toyota,\n    mercedez,\n    mazda,\n};\nstd::ostream& operator<< (std::ostream& out, const Marca& marca);// este es un fordwar declaration de el overloading que se hace del operador de salida\nconst std::string MarcaToString(const Marca& marca);//este es un overloading de la funcion que transforma de Marca (un enum class) a String\n\n//Estructura sin sentido colocada como ejemplo\nstruct noReasonToExist{\n    Marca foreverAndEver{Marca::mazda};\n    int sI{0};\n    std::string sExistance{\"Existo Luego Existo\"};\n    std::bitset<16> sBit{0xaefd};\n};\n/*********************\n*DEFINICION DE CLASES*\n*********************/\n//definicion de clase Velocidad que representa el movimiento hacia una direccion de un punto en el espacio 2D\nclass Velocidad{\n    private:\n        std::vector<double> mVel{0,0};\n    public:\n        Velocidad(double x=0, double y=0)\n        {\n            mVel[0]=x;\n            mVel[1]=y;\n        }\n\n        const double& getVelocidadX(){\n            return mVel[0];\n        }\n        const double& getVelocidadY(){\n            return mVel[1];\n        }\n        void setVelocidadX(double x){\n            mVel[0]=x;\n        }\n        void setVelocidadY(double y){\n            mVel[1]=y;\n        }\n\n        //overload de operador de subscripcion [] si se desea se puede quitar el comentario y velicidad podra modificarce haciendo objeto[index] como con cualquier array\n        /*\n        double& operator[] (int index)\n        {\n            return mVel[index];\n        }\n        */\n};\n\n//definicion de clase Punto que representa un punto en el espacio 2D\nclass Punto{\n    private:\n        std::array<double, 2> mPunto{0,0};\n    public:\n        Punto(double x=0, double y=0)\n        {\n            mPunto[0]=x;\n            mPunto[1]=y;\n        }\n\n        const double& getPuntoX(){\n            return mPunto[0];\n        }\n        const double& getPuntoY(){\n            return mPunto[1];\n        }\n        void setPuntoX(double x){\n            mPunto[0]=x;\n        }\n        void setPuntoY(double y){\n            mPunto[1]=y;\n        }\n\n        //overload de operador de subscripcion [] si se desea se puede quitar el comentario y punto podra modificarce haciendo objeto[index] como con cualquier array\n        /*\n        double& operator[] (int index)\n        {\n            return mVel[index];\n        }\n        */\n};\n\n\nclass Auto{\n    private://Los miembros privados solo son accesibles para la misma clase, no se pueden acceder por funciones externas, amenos que sean funciones amigas de la clase\n        /************************************\n        /*Propiedades o miembros de la clase*\n        ************************************/\n        Marca mMarca{Marca::mazda};\n        Velocidad mVelocidad2D{0,0};\n        Punto mPunto2D{0,0};\n    public://Los miembros publicos si pueden ser accedidos desde el exterior de la Clase utilizando la sintaxis objeto.miembro\n        /***************\n        *CONSTRUCTORES:*\n        ***************/\n        //Los constructores son funciones especiales que tienen el mismo nombre que la clase en c++\n        Auto(Marca marca=Marca::mazda, Velocidad velocidad0={0,0}, Punto punto0={1,1})//aqui estan los parametros de entrada, luego se define que hacer con ellos\n        {\n            //aca se copian los parametros de entrada a los miembros deseados de la clase\n            mMarca=marca;\n            mVelocidad2D.setVelocidadX(velocidad0.getVelocidadX());\n            mVelocidad2D.setVelocidadY(velocidad0.getVelocidadY());\n            mPunto2D=punto0;\n        }\n        /*********\n        *METODOS:*\n        *********/\n        //modifica la marca del auto Marca es tipo enum class\n        void setMarca(Marca marca){\n            mMarca = marca;\n        }\n        //retorna la marca del auto Marca es tipo enum class\n        Marca getMarca(){\n            return mMarca;\n        }\n        void setVelocidad2D(Velocidad velocidad){\n            mVelocidad2D.setVelocidadX(velocidad.getVelocidadX());//velocidad en x se coloca por el metodo set a partir de referencia de x en objeto velocidad\n            mVelocidad2D.setVelocidadY(velocidad.getVelocidadY());//igual que en caso anterior pero para Y\n        }\n        //Se modifica la velocidad del objeto, se necesita pasar objeto clase Velocidad(double x, double y), estos solo reciben dos parametros double\n        Velocidad getVelocidad2D(){\n            return mVelocidad2D;\n        }\n        //Se modifica la posicion del objeto, se necesita pasar objeto clase Punto(double x, double y), estos solo reciben dos parametros double\n        void setPunto2D(Punto punto){\n            mPunto2D = punto;                   //copia de objeto punto a mPunto2D\n        }\n        //Se retorna la posicion del objeto\n        Punto getPunto2D(){\n            return mPunto2D;\n        }\n\n\n\n};\n\n\n\n\n//Este es main, funcion principal\nint main(){\n    //Aqui colocamos variables que se usaran en la funcion main\n    //metodos de inicializacion\n    int numerador=0;            //inicializacion por copia\n    int denominador(1);         //inicializacion directa, se puede confundir con el forward declaration y por ello se evita, fordward declaration puede traducirse como declaracion frontal y es cuando un objeto o funcion se declara sin ser definida en su totalidad\n    int entrada1{1};            //inicializacion directa, modo lista\n    int entrada2{};             //igual que anterios, pero limpia la memoria reservada por la variable (coloca 0)\n    int resultado={99};         //inicializacion por copia a partir de lista\n\n    Auto primerAuto;            //se instancia un objeto primerAuto como clase Auto\n\n    noReasonToExist lameExistance;\n\n    std::cout<<\"\\n\\n\\nTEST DE PRINT\\n\\n\";\n    std::cout<<\"No te vayas, pero si quieres irte, no sigas el camino por el que vengo, mis pasos son pesados y los senderos que recorro los hecho a perder \\n\";\n    std::cout<<\"Imprimiendo una expresion constante\"<<Z<<'\\n';\n    std::cout<<\"Muestra de valor entero constante: \"<<TEN<<'\\n';\n\n    /*******************************************************************************************************************************************\n    *ACA SE IMPRIMEN LOS LIMITES MAYOR Y MENOR DE ALGUNAS VARIABLES, SE PUEDE USAR LA MISMA STRUCTURA PARA TODAS LAS VARIABLES DEFINIDAS EN C++*\n    *************************************CORRER EL PROGRAMA PARA VER LOS RESULTADOS SI SE DESEA*************************************************\n    *******************************************************************************************************************************************/\n\n    std::cout<<\"\\n\\n\\nRANGOS DE VALORES PARA ALGUNOS TIPOS DE VARIABLES\\n\\n\";\n    std::cout<<\"Limite char maximo: \"<<static_cast<int>(std::numeric_limits<decltype(miCaracterBase)>::max())<<'\\n';\n    std::cout<<\"Limite char minimo: \"<<static_cast<int>(std::numeric_limits<decltype(miCaracterBase)>::min())<<'\\n';\n    std::cout<<\"Limite signed char maximo: \"<<static_cast<int>(std::numeric_limits<decltype(miCaracter)>::max())<<'\\n';\n    std::cout<<\"Limite signed char minimo: \"<<static_cast<int>(std::numeric_limits<decltype(miCaracter)>::min())<<'\\n';\n    std::cout<<\"Limite unsigned char maximo: \"<<static_cast<int>(std::numeric_limits<decltype(miCaracterNoSign)>::max())<<'\\n';\n    std::cout<<\"Limite unsigned char minimo: \"<<static_cast<int>(std::numeric_limits<decltype(miCaracterNoSign)>::min())<<'\\n';\n    std::cout<<\"Limite short maximo: \"<<std::numeric_limits<decltype(miInt)>::max()<<'\\n';\n    std::cout<<\"Limite short minimo: \"<<std::numeric_limits<decltype(miInt)>::min()<<'\\n';\n    std::cout<<\"Limite signed short maximo: \"<<std::numeric_limits<decltype(miIntSignado)>::max()<<'\\n';\n    std::cout<<\"Limite signed short minimo: \"<<std::numeric_limits<decltype(miIntSignado)>::min()<<'\\n';\n    std::cout<<\"Limite unsigned short maximo: \"<<std::numeric_limits<decltype(miIntNoSignado)>::max()<<'\\n';\n    std::cout<<\"Limite unsigned short minimo: \"<<std::numeric_limits<decltype(miIntNoSignado)>::min()<<'\\n';\n    std::cout<<\"Limite int maximo: \"<<std::numeric_limits<decltype(miVariable)>::max()<<'\\n';\n    std::cout<<\"Limite int minimo: \"<<std::numeric_limits<decltype(miVariable)>::min()<<'\\n';\n    std::cout<<\"Limite long int maximo: \"<<std::numeric_limits<decltype(miIntLong)>::max()<<'\\n';\n    std::cout<<\"Limite long int minimo: \"<<std::numeric_limits<decltype(miIntLong)>::min()<<'\\n';\n    std::cout<<\"Limite unsigned long int maximo: \"<<std::numeric_limits<decltype(miUIntLong)>::max()<<'\\n';\n    std::cout<<\"Limite unsigned long int minimo: \"<<std::numeric_limits<decltype(miUIntLong)>::min()<<'\\n';\n    std::cout<<\"Limite long long int maximo: \"<<std::numeric_limits<decltype(miInt2Long)>::max()<<'\\n';\n    std::cout<<\"Limite long long int minimo: \"<<std::numeric_limits<decltype(miInt2Long)>::min()<<'\\n';\n    std::cout<<\"Limite unsigned long long int maximo: \"<<std::numeric_limits<decltype(miUInt2Long)>::max()<<'\\n';\n    std::cout<<\"Limite unsigned long long int minimo: \"<<std::numeric_limits<decltype(miUInt2Long)>::min()<<'\\n';\n    std::cout<<\"Limite float maximo: \"<<std::numeric_limits<decltype(miFlotante)>::max()<<'\\n';\n    std::cout<<\"Limite float minimo: \"<<std::numeric_limits<decltype(miFlotante)>::min()<<'\\n';\n\n    /*********************************************************************\n    *EN ESTA SECCION SE DEMUESTRAN ALGUNAS FORMAS DE TRABAJAR CON BITS****\n    *********************************************************************/\n\n    std::cout<<\"\\n\\n\\nTEST DE BANDERAS bitset\\n\\n\";\n    banderas.set(3);                                                    //set() es un metodo del tipo de objeto bitset que permite colocar el bit deseado como un 1 logico\n    std::cout<<\"Estados iniciales: \"<<estados<<'\\n';                    //imprimiendo estados iniciales\n    estados = (estados & static_cast<std::bitset<16>>(0x0000));         //operacion and aplicada entre estados y el valor 0x0000 para borrar todo\n    //se imprimen los datos\n    std::cout<<\"Estados reseteados exitosamente\\n\";\n    std::cout<<\"Muestra de estados despues de reset: \"<<estados<<'\\n';\n    std::cout<<\"Banderas: \"<<banderas<<'\\n';\n\n    /*********************************************************************\n    *EN ESTA SECCION SE DEMUESTRAN ALGUNAS FORMAS DE TRABAJAR CON OBJETOS*\n    *********************************************************************/\n    std::cout<<\"\\n\\n---------------------------------------------\\nPRUEBA DE OPERACIONES CON OBJETOS (OBJETO DE CLASE Auto).\\n---------------------------------------------------\";\n    std::cout<<\"\\n\\n\\nESTADO INICIAL DE AUTO:\\n\\n\";\n    std::cout<<\"Auto Marca: \"<<primerAuto.getMarca()<<'\\n'<<\"desde latitud: \"<<primerAuto.getPunto2D().getPuntoX()<<'\\n'\n    <<\"longitud: \"<<primerAuto.getPunto2D().getPuntoY()<<'\\n'<<\"Arrazando con todo a velocidad de: \"<<primerAuto.getVelocidad2D().getVelocidadX()<<\" al este\\n\"\n    <<primerAuto.getVelocidad2D().getVelocidadY()<<\" al norte\\n\";\n\n    //MODIFICACION DE DATOS DEL OBJETO primerAuto\n    primerAuto.setMarca(Marca::ferrari);                //NUEVA MARCA\n    primerAuto.setVelocidad2D(Velocidad(180.00, 0.00)); //NUEVA VELOCIDAD\n    primerAuto.setPunto2D(Punto(500.76, 122.55));       //NUEVO PUNTO EN EL ESPACIO 2D\n\n    std::cout<<\"\\n\\n\\nESTADO DE AUTO ACTUALIZADO:\\n\\n\";\n    std::cout<<\"Auto Marca: \"<<primerAuto.getMarca()<<'\\n'<<\"desde latitud: \"<<primerAuto.getPunto2D().getPuntoX()<<'\\n'\n    <<\"longitud: \"<<primerAuto.getPunto2D().getPuntoY()<<'\\n'<<\"Arrazando con todo a velocidad de: \"<<primerAuto.getVelocidad2D().getVelocidadX()<<\" al este\\n\"\n    <<primerAuto.getVelocidad2D().getVelocidadY()<<\" al norte\\n\";\n\n\n    std::cout<<\"\\n\\n\\nDATOS DE ESTRUCTURA lameExistance CREADA ANTERIORMENTE:\\n\\n\";\n    std::cout<<\"Auto: \"<<lameExistance.foreverAndEver<<'\\n';\n    std::cout<<\"sI: \"<<lameExistance.sI<<'\\n';\n    std::cout<<\"sExistance: \"<<lameExistance.sExistance<<'\\n';\n    std::cout<<\"sBit: \"<<lameExistance.sBit<<'\\n';\n    return 0;\n\n}\n\n//funcion que simplemente devuelve una constante como demostracion de el uso de constantes definidas en run time\nint returnTen(){\n    return 10;\n}\n//funcion que imprime string con nombre de auto seleccionado (convierte Marca a Cadena de caracteres\nconst std::string MarcaToString(const Marca& marca){\n    std::string strMarca{\"Mazda\"};\n\n    switch(marca){\n        case Marca::audi:\n            strMarca=\"Audi\";\n            break;\n        case Marca::ferrari:\n            strMarca=\"Ferrari\";\n            break;\n        case Marca::chevrolet:\n            strMarca=\"Chevrolet\";\n            break;\n        case Marca::toyota:\n            strMarca=\"Toyota\";\n            break;\n        case Marca::mercedez:\n            strMarca=\"Mercedez\";\n            break;\n        case Marca::mazda:\n            strMarca=\"Mazda\";\n            break;\n    }\n    return strMarca;\n}\n\n//definiendo el overloading del operador de output << para aceptar enum class\nstd::ostream& operator<< (std::ostream& out, const Marca& marca){\n    out<<MarcaToString(marca);\n    return out;\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++/tomytsa.cpp",
    "content": "// https://isocpp.org/\n\n// Comentario de una linea\n\n/* Comentario de \nvarias lineas*/\n\n#include <iostream>\nusing namespace std;\n\nint main(int argc, char const *argv[])\n{\n    \n\n\n    int variable;\n    const int numero = 1;\n\n\n\n    \n    char caracter; \n    int entero = 1;\n    short enteroCorto; \n    long enteroLargo;\n    bool booleano;\n    float flotante;  \n\n    cout << \"¡Hola, C++!\" << endl;\n\n\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++/whiterunjarl.cpp",
    "content": "#include <iostream>\nusing namespace std;\n\n// la web oficial es: https://isocpp.org/\n\n/* otra forma de \ncomentar */\n\n//comentario de una linea\n\n\nint vida = 52;\nstring perros = \"doce\";\ndouble flotante = 22;\nchar letra = 'N';\nbool falsito = false;\nstring lenguaje = \"C++\";\n\n\nint numeroBalas = 25, armorTotal = 78, hpLeft = 62;\nconst int miConstante = 12;\n\n\n\n\nint main()\n{\n    cout << \"esto anda de 10\" << \", Test si funciona\" << endl;\n    cout << \"La vida int es: \" << vida << endl;\n    cout << \"El string total de perros es: \" << perros << endl;\n    cout << \"el numero float es: \" << flotante << endl;\n    cout << \"La letra es: \" << letra << endl;\n    cout << \"El booleano es: \" << falsito << endl;\n    cout << \"Lo siguiente suma los valores de: numerosBalas, armorTotal y hpLeft \\nestadisticas de un juego por ejemplo.\" << endl;\n    cout << \"La suma de los ints es: \" << numeroBalas + armorTotal + hpLeft << endl;\n    cout << \"mi constante es:\" << miConstante << endl;\n    cout << \"Hola, mi lenguaje es: \" << lenguaje << \", y estoy encantado de ir aprendiendo.\" << endl;\n    return 0;\n\n}\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++/xooseph.cpp",
    "content": "#include <iostream>\n\nusing namespace std;\n\n/* Como tal no es la documentación oficial de C++: \n    https://learn.microsoft.com/es-es/cpp/cpp/?view=msvc-170\n\n    También se tomará como referencia el libro de \"Cómo programar C++, novena edición de\n    Deitel\"\n*/\n\n// Este es un comentario de una sola línea\n\n/* Este es comentario\n    de varias líneas.\n*/ \nint main() {\n    // Variable\n    int randomNumber = 45;\n\n    // Constante\n    const double PI = 3.1415;\n\n    // Tipos de datos primitivos\n    int number = 340;\n    float anotherNumber = 23.4;\n    double doubleNumber = 35.4;\n    char character = 'a';\n    bool boolean = false;\n    string text = \"Hello World!\";\n\n    cout << \"Hola, C++!\";\n\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++/yeisonagm.cpp",
    "content": "// https://isocpp.org/\n\n/*\n    Solución al problema #00\n    Permite familiarize con c++\n*/\n\n#include <iostream>\n#include <cstring>\n#include <string>\n\nint main() {\n    // Variable\n    int miVariable = 6174;\n\n    // Constante\n    const float PI = 3.1416;\n\n    // Enteros\n    short nota = 8;\n    unsigned short maximoShort = 65535;\n    int anio = 2024;\n    unsigned int enteroSinSigno = 4294967295;\n    long distanciaSol = 150000000L; // Distancia en km\n    unsigned long longSinSigno = 56389213233L;\n    long long numeroGrande = 1234567890123456789;\n    unsigned long long numeroGrandeSinSigno = 987123456789012345;\n\n    // Punto flotante\n    float numeroAureo = 1.618033f;\n    double numeroEuler = 2.718281828459045;\n    long double largePI = 3.14159265358979323846L;\n\n    // Carácter\n    char vocal = 'A';\n\n    // Booleano\n    bool verdadero = true;\n    bool falso = false;\n    bool mayor = 5 > 3;\n\n    // Cadenas\n    char nombre[] = \"Yeison\";\n    char lenguaje[10];\n    strcpy(lenguaje, \"C++\");\n    std::string apellido = \"Garcia\";\n    std::string nombreCompleto = apellido + \" \" + nombre;\n\n    // Imprimir\n    std::cout << \"¡Hola, \" << lenguaje << \"!\" << std::endl;\n\n    // Retorno de la función\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/cobol/any7dev.cbl",
    "content": "     /*\n      *    -Crea un comentario en el código y coloca la URL del sitio\n      *    web oficial del lenguaje de programación que has seleccionado\n      *    -Representa las diferentes sintaxis que existen de crear\n      *    comentarios en el lenguaje (en una línea, varias...).\n      *    -Crea una variable (y una constante).\n      *    -Crea variables representando todos los tipos de datos\n      *    primitivos del lenguaje (cadenas de texto, enteros...)\n      *    - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu\n      *    lenguaje]!\"\n     */\n\n      *    No es la oficial https://es.wikipedia.org/wiki/COBOL\n\n      *    Esto es una forma de poner comentarios\n      *>   Esta es otra forma de añadir comentarios\n\n       IDENTIFICATION DIVISION.\n       PROGRAM-ID. RETO-0.\n       DATA DIVISION.\n       FILE SECTION.\n       WORKING-STORAGE SECTION.\n      *    Variable\n           77 VAR PIC 9.\n      *    Constante\n           01 VAR-CONS CONSTANT AS 100.\n      *    Variable numerica entera\n           77 NUM-INT PIC 9.\n      *    Variable numerica entera negativa\n           77 INT-NEG PIC S9.\n      *    Variable numerica decimal\n           77 NUM-FLOAT PIC 9V99.\n      *    Variable numerica decimal negativa\n           77 FLOAT-NEG PIC S9V99.\n      *    Cadena\n           77 CADENA PIC X.\n      *    Cadena sin numeros\n           77 CAD-A PIC A.\n       PROCEDURE DIVISION.\n       MAIN-PROCEDURE.\n            DISPLAY \"¡Hola, COBOL!\"\n            STOP RUN.\n       END PROGRAM RETO-0.\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/cobol/gabrielCharibPolls.cbl",
    "content": "      *    -Crea un comentario en el código y coloca la URL del sitio\n      *    web oficial del lenguaje de programación que has seleccionado\n      *    -Representa las diferentes sintaxis que existen de crear\n      *    comentarios en el lenguaje (en una línea, varias...).\n      *    -Crea una variable (y una constante).\n      *    -Crea variables representando todos los tipos de datos\n      *    primitivos del lenguaje (cadenas de texto, enteros...)\n      *    - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu\n      *    lenguaje]!\"\n      **************************************************************************\n      *    commentaire  \n      **************************************************************************\n      *      Voici un commentaire en Cobol\n      *      URL officielle de GnuCOBOL: https://gnucobol.sourceforge.io/\n       IDENTIFICATION DIVISION.\n       PROGRAM-ID. RETO-O.\n       DATA DIVISION.\n       WORKING-STORAGE SECTION.\n      **************************************************************************\n      *    Variables \n      **************************************************************************\n           77 MY-VARIABLE    PIC 9(5) VALUE 12345.\n           77 MY-STRING      PIC X(20) VALUE \"COBOL Language\".\n      **************************************************************************\n      *    Type de données primitifs\n      **************************************************************************\n           77 MY-INTEGER     PIC 9(5) VALUE 12345.\n           77 MY-TEXT        PIC X(20) VALUE \"HOLA COBOL\".\n           77 MY-DECIMAL     PIC 99V99 VALUE 13.14.  \n           77 MY-BOOLEAN     PIC X VALUE \"T\".\n      **************************************************************************     \n      * Afficher un message dans le terminal\n      **************************************************************************\n       PROCEDURE DIVISION.\n           DISPLAY \"***************************\".\n           DISPLAY \"¡Hola, COBOL!\".\n           DISPLAY \"Valor de MY-VARIABLE : \" MY-VARIABLE.\n           DISPLAY \"Texto en MY-TEXT : \" MY-TEXT.\n           DISPLAY \"Valor de MY-INTEGER : \" MY-INTEGER.\n           DISPLAY \"Valor de MY-DECIMAL : \" MY-DECIMAL.\n           DISPLAY \"Booleano MY-BOOLEAN : \" MY-BOOLEAN.\n           DISPLAY \"***************************\".\n           STOP RUN.\n\n\n\n      \n\n\n\n\n\n\n\n \n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/cobol/keltoi-dev.cbl",
    "content": "      ******************************************************************\n      * - Crea un comentario en el cdigo y coloca la URL del sitio web oficial del\n      *   lenguaje de programacin que has seleccionado.\n      * - Representa las diferentes sintaxis que existen de crear comentarios\n      *   en el lenguaje (en una lnea, varias...).\n      * - Crea una variable (y una constante si el lenguaje lo soporta).\n      * - Crea variables representando todos los tipos de datos primitivos\n      *   del lenguaje (cadenas de texto, enteros, booleanos...).\n      * - Imprime por terminal el texto: \"Hola, [y el nombre de tu lenguaje]!\"\n      * Fcil? No te preocupes, recuerda que esta es una ruta de estudio y\n      * debemos comenzar por el principio.\n      ******************************************************************\n      * https://www.ibm.com/docs/es/i/7.3?topic=languages-cobol\n      * Se puede consultar documentacion sobre el lenguaje\n      ******************************************************************\n\n       IDENTIFICATION DIVISION.\n       PROGRAM-ID. RETO-00.\n       DATA DIVISION.\n       FILE SECTION.\n       WORKING-STORAGE SECTION.\n       01  TIPOS-DE-VARIABLES.\n           03 LETRAS PIC A(11) VALUE \"Alfabeticas\".\n           03 ALFANUMERICAS PIC X(10) VALUE \"abc123#$_%\".\n           03 NUMEROS-NATURALES PIC 9999 VALUE 1234.\n           03 NUMEROS-ENTEROS PIC S9999 VALUE -1234.\n           03 RACIONALES-SIN-SIGNO PIC 99V99 VALUE 12.34.\n           03 RACIONALES-CON-SIGNO PIC S99V99 VALUE -12.34.\n      * Nombre del lenguaje.\n           03 NOMBRE PIC X(5).\n       01  CONSTANTE.\n           03  FILLER PIC X(25) VALUE \"-------------------------\".\n       PROCEDURE DIVISION.\n       MAIN-PROCEDURE.\n           DISPLAY \"Tipos de variables.\".\n           DISPLAY LETRAS \": Con solo letras\".\n           DISPLAY \"alfanumericas: letras, numeros y simbolos \"\n           ALFANUMERICAS.\n           DISPLAY \"Con numeros enteros positivos: \" NUMEROS-NATURALES.\n           DISPLAY \"Con numeros enteros positivos y negativos: \"\n           NUMEROS-ENTEROS.\n           DISPLAY \"Con numeros positivos con decimales: \"\n           RACIONALES-SIN-SIGNO.\n           DISPLAY\n           \"Con numeros positivos y negativos con decimales: \"\n           RACIONALES-CON-SIGNO.\n           MOVE \"COBOL\" TO NOMBRE.\n           DISPLAY CONSTANTE.\n           DISPLAY \"Hola, \" NOMBRE.\n           STOP RUN.\n       END PROGRAM RETO-00.\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/cobol/llonardo798.cbl",
    "content": "\n      * CMENTARIO PERSONAL: \n      * No conozco nada de COBOL, pero al verlo en el roadmap de midudev\n      * me llamo la atención. \n      * Todo lo echo es a partir de la documentación de IBM, \n      * la IA de Gemini y los ejemplos de los usuarios.\n\n      * 1. URL documentación no oficial: \n      * https://www.ibm.com/docs/es/i/7.3?topic=languages-cobol - IBM COBOL\n\n       IDENTIFICATION DIVISION.\n       PROGRAM-ID. ROADMAP-MIDUDEV-00.\n       AUTHOR. LLONARDO798.\n       DATA DIVISION.\n       FILE SECTION.\n       WORKING-STORAGE SECTION.\n       \n      * 2. Formas de añadir comentarios\n\n      * Comentarios con * al inicio en la columna 7 de la linea.\n      * hasta la columna 80.\n      / Comentario que provoca un salto de página en el listado de compilación.\n      *> Comentario flotante, todo lo puesto despues de *> es un comentario. \n      *> Se puede colocar en cualquier columna de la linea de codigo. \n      *REMARKS. \n      *    Este programa realiza cálculos matemáticos básicos.\n      *    Fue creado el 20 de septiembre de 2023.\n      * REMARKS no es soportado por todos los compiladores, aunque es parte del\n      * estandar COBOL original.\n\n      * 3. Variables y constantes\n      * Variable numerica entera\n      \n      * En COBOL, las variables no existen de forma aislada. La declaración 01 \n      * crea un registro o grupo de datos llamado VARIABLES.\n       01  VARIABLES.\n           03 WS-NOMBRE PIC X(20).\n\n      * Variables CONSTANTES no hay en COBOL, pero se puede definir un valor\n      * inicial con VALUE.\n       \n           03 NUM-CONST PIC 99 VALUE 100.\n\n      * 4. Tipos de datos primitivos no existen, estos son los \"fundamentales\"\n           03  WS-CADENA PIC X(20) VALUE \"Cobol\". \n           *> Cadena de texto de 20 caracteres\n\n           03  WS-EDAD          PIC 9(3).    *> Número entero de hasta 3 dígitos\n           03  WS-NUMERO        PIC 99.      *> Digitos numericos de 0-99\n           03  WS-NEGATIVO      PIC S9.      *> Número entero negativo\n           03  WS-SALARIO       PIC 9(7)V99. *> Números decimales \n                                             *> 7 enteros y 2 decimales\n           03  WS-SALARIO-X     PIC 9V99.    *> Número decimal, la V indica la\n                                             *> posición del punto decimal\n           03  WS-ES-MAYOR-EDAD PIC A(3).    *> \"SI\" o \"NO\" (alfabético)\n           03  WS-CODIGO-POSTAL PIC X(5).    *> Código postal (alfanumérico)\n           03  WS-BINARIO       PIC 9(7)V9 COMP. \n           *> Número almacenado en memoria en formato binario 1/0\n\n      * 5. Impresión por consola\n\n       PROCEDURE DIVISION.\n       MAIN-PROCEDURE.\n           MOVE \"LEONARDO-AEDO\" TO WS-NOMBRE.\n           DISPLAY WS-NOMBRE.\n           DISPLAY \"¡Hola, \" WS-CADENA \"!\".\n           STOP RUN.\n       END PROGRAM ROADMAP-MIDUDEV-00."
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/d/ElHacedorDeCosas.d",
    "content": "/*\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n// https://dlang.org/\n\nvoid main()\n{\n    int variable = 2025;\n    const string constante = \"Hola\";\n\n\n    // - Tipos de datos - //\n\n    // Tipo buleano\n    bool buleano = true; // (true o false) verdadero o falso\n\n    // Tipos enteros con signo (pueden ser positivos o negativos)\n    byte bit;                  // entero de 8  bits\n    short corto;               // entero de 16 bits\n    int entero;                // entero de 32 bits\n    long largo;                // entero de 64 bits\n\n    // Tipos enteros sin signo (solo pueden ser positivos)\n    ubyte uBit;                // sin signo de 8  bits\n    ushort uCorto;             // sin signo de 16 bits\n    uint uEntero;              // sin signo de 32 bits\n    ulong uLargo;              // sin signo de 64 bits\n\n    // Tipo flotante (numeros con decimales)\n    float flotante;            // flotante de 32 bits\n    double doble;              // flotante de 64 bits\n    real flotanteReal;         // el tamaño del punto flotante más grande disponible\n\n    // Tipo caracter\n    char caracter;             // sin signo de 8  bits (UTF-8  code)\n    wchar wcaracter;           // sin signo de 16 bits (UTF-16 code)\n    dchar dcaracter;           // sin signo de 32 bits (UTF-32 code)\n\n    string cadena;             // alias de \"immutable(char)[]\"\n    wstring wcadena;           // alias de \"immutable(wchar)[]\"\n    dstring dcadena;           // alias de \"immutable(dchar)[]\"\n\n\n    // - Saludo por terminal - //\n\n    import std.stdio: writeln; // Estoy importando especificamente la función writeln\n                               // desde la biblioteca estandar de D para escribir en terminal\n    writeln(\"¡Hola, D o Dlang!\");\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/d/m-hadz.d",
    "content": "module mhadz;\n\n/*\n    Aqui se define el nombre del modulo\n    ya que el compilador dmd tira error\n    si el nombre del archivo tiene un -\n*/\n\nimport std.stdio;\n\n// https://dlang.org/\n\n// Se usa para comentarios de una linea\n\n/*\n  Se utiliza para comentarios\n  de multiples lineas\n*/\n\n\nint variable = 3;\n\nconst double constante = 3.14;\n\n// Estos son los tipos de datos primitivos de D\n\nbyte valorByte = 10;\n\nubyte valorUByte = 100; // byte sin signo\n\nshort valorShort = -200;\n\nushort valorUShort = 5000; // short sin signo\n\nint entero = 3;\n\nuint valorUInt = 3U; // entero sin signo\n\nlong valorLong = -123456789000000L;\n\nulong valorULong = 12345678990000000L; // long sin signo\n\nfloat valorFloat = 3.1F;\n\ndouble valorDouble = 3.14;\n\nreal valorReal = 1.925;\n\nbool booleano = true;\n\nchar valorChar = 'a'; // UTF8\n\nwchar valorWChar = 'ñ'; // UTF16\n\ndchar valorDCchar = '⚙'; // UTF32\n\nvoid main() {\n    writeln(\"¡Hola, D!\");\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/dart/CA2puntosV.dart",
    "content": "// LENGUARJE DART: https://dart.dev/\n\n// Comentarios de una sola línea\n\n/*\nComentario multilinea (se puede contraer)\n*/\n\n/// Comentarios multiple de una sola linea\n/// (Se pueden contraer los que esten seguidos)\n\n/// Variable\nString helloDart = '¡Hola, Dart!';\n\n/// Constantes (final y const) son de tipo @inmutable (no pueden cambiar su valor)\n/// un ejemplo para diferenciarlas es DateTime.now(). Si se intenta usando const, saldrá error\n/// porque se estará intentando inicializar al momento de compilar.\n\n// final se inicializa al momento de usarse\nfinal String varFinal = 'Final Variable';\n\n// const se inicializa al momento de escribirse\nconst String varConst = 'Final Variable';\n\n/// Variable primitivas\nString name = 'Pepito';\n\nbool active = true;\n\nint age = 40;\ndouble weight = 13.2;\nnum numeric = 100; // Puede ser int o double\n\ndynamic dynamicType; // Puede ser de cualquier tipo\nNull nullableType;\n\n// Null Safety (cualquier tipo de datos puede ser de tipo null usando '?')\nString? nullableString;\n\nvoid main(List<String> args) {\n  print('¡Hola, Dart!');\n\n  // Formas de usar variable\n  print(helloDart);\n  print('Concatenacion:' + helloDart);\n  print('Interpolación: $helloDart');\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/dart/D3rk1us.dart",
    "content": "/*\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n// https://dart.dev/\n\n/// Comentarios de\n/// documentación.\n\n\n/* Esto también es un comentario */\n\n\n// Variables\n\nlate String color; // Es una variable que se establece antes de ser utilizada.\n\nvoid main() {\n\n  Object name = 'Clark';\n  print(name);\n\n  String surname = 'Kent';\n  print(surname);\n\n  int? number1 = 23; // Permite que el valor sea null.\n  print(number1);\n\n  int age = 35;\n  print(age);\n\n  color = 'black';\n  print(color);\n\n  final double price = 40.99;\n  print(price);\n\n  const double pi = 3.1415;\n  print(pi);\n\n  List numberList = [1, 2, 4];\n  print(numberList);\n\n  Set collection1 = {'one', 'four'};\n  print(collection1);\n\n  Map firstMap = {'name': 'John', 'surname': 'Constantine'};\n  print(firstMap);\n\n  print('¡Hola, Dart!');\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/dart/Lia-M3dusa.dart",
    "content": "// https://dart.dev/\n\n// Comentario simple\n/**Comentario multiple */\n/// Comentario de documentacion \n/// \n\n\nvoid main(List<String> args) {\n  const String nombre = 'Liatoga';\n  int edad = 0;\n  double altura = 0.0;\n  bool isNumber = false;\n  dynamic variable = 'Hola';\n  Future future = Future.delayed(Duration(seconds: 1), () => 'Hola');\n  print('Hola, Dart');  \n}\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/dart/angelsanchezt.dart",
    "content": "// URL del sitio web oficial de Dart: https://dart.dev\n\n// Comentario de una línea\n\n/*\n  Comentario\n  de\n  varias\n  líneas\n*/\n\n/// Comentario de documentación (estilo DartDoc)\n\nvoid main() {\n  // Declaración de variables y constante\n  var variable = \"Hola, Dart\"; // Variable\n  const constante = 3.14; // Constante\n\n  // Tipos de datos primitivos en Dart\n  String cadenaTexto = \"¡Hola, Dart!\"; // Cadena de texto\n  int entero = 42; // Entero\n  double flotante = 3.14; // Punto flotante\n  bool booleano = true; // Booleano\n\n  // Imprimir por terminal\n  print(variable);\n  print(constante);\n  print(\"Cadena de texto: $cadenaTexto\");\n  print(\"Entero: $entero\");\n  print(\"Punto flotante: $flotante\");\n  print(\"Booleano: $booleano\");\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/dart/bluefeatherdev.dart",
    "content": "/*\n* ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n* - Recuerda que todas las instrucciones de participación están en el\n*   repositorio de GitHub.\n*\n* Lo primero... ¿Ya has elegido un lenguaje?\n* - No todos son iguales, pero sus fundamentos suelen ser comunes.\n* - Este primer reto te servirá para familiarizarte con la forma de participar\n*   enviando tus propias soluciones.\n*\n* EJERCICIO:\n* - Crea un comentario en el código y coloca la URL del sitio web oficial del\n*   lenguaje de programación que has seleccionado.\n* - Representa las diferentes sintaxis que existen de crear comentarios\n*   en el lenguaje (en una línea, varias...).\n* - Crea una variable (y una constante si el lenguaje lo soporta).\n* - Crea variables representando todos los tipos de datos primitivos\n*   del lenguaje (cadenas de texto, enteros, booleanos...).\n* - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n*\n* ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n* debemos comenzar por el principio.\n*/\n\nvoid main() {\n  // https://dart.dev/\n\n  // Esto es un comentario de una línea\n\n  // Esto es un comentario de una línea,\n  // que ocupa varias líneas,\n  // para no ser demasiado largo.\n\n  /*\n    Esto es un comentario de varias líneas,\n    puedes usar '*' para buenas prácticas,\n    y también '-' si deseas listar información.\n  */\n\n  /*\n  * ¡Comentarios de varias líneas!\n  * - Usas '*' en cada línea\n  * - En algunos editores y temas cambian de color\n  * - En mi editor (Visual Studio Code) son de color verdes\n  * - Uso Atom One Dark theme \n  */\n\n  /// Estos son comentarios tipo documentación para Dart,\n  /// puedes usar `` para especificar fragmentos de códigos,\n  /// así como keywords. También puedes usar [] \n  /// para enfatizar términos clave\n  \n  /// Por ejemplo, `void main() {}`,\n  /// es la [función de alto nivel],\n  /// donde dejo mis respuestas.\n  \n  /// Puedes también especificar código de un lenguaje así:\n  /// ```dart\n  /// void main() {\n  ///   print('Hello World!');\n  /// }\n  /// ```\n  \n  /// Crear una [variable] en Dart:\n  var myNum = 23; // Forma 1\n  print(myNum); // Imprime: 23\n\n  int myOtherNum = 46; // Forma 2\n  print(myOtherNum); // Imprime: 46\n\n  /// Crear una [constante] en Dart:\n  const myName = 'Jesús'; // Forma 1\n  print(myName);  // Imprime: 'Jesús'\n  \n  const String myLastName = 'Domínguez'; // Forma 2\n  print(myLastName);  // Imprime: 'Domínguez'\n\n  final myEyeColor = 'Brown'; // Forma 3\n  print(myEyeColor);  // Imprime: 'Brown'\n\n  final String myHairColor = 'Black'; // Forma 4\n  print(myHairColor);  // Imprime: 'Black'\n\n  /// [Datos primitivos] del lenguaje Dart:\n  \n  // int\n  var myInt = 1;\n  var myInt2 = 0xDEADBEEF;\n  var myInt3 = 1_000_000;\n\n  print(myInt); // Imprime: 1\n  print(myInt2);  // Imprime: 3735928559\n  print(myInt3);  // Imprime: 1_000_000\n\n  // double\n  var myDouble = 1.23;\n  var myDouble2 = 1.23e5;\n  var myDouble3 = 0.000_000_1;\n\n  print(myDouble);  // Imprime: 1.23\n  print(myDouble2); // Imprime: 123000.0\n  print(myDouble3); // Imprime: 1e-7\n\n  // String\n  var myString = 'Hello World!';\n  var myString2 = \"Hello World!\";\n  var myString3 = '\"Hello\" World!';\n  var myString4 = \"'Hello' World!\";\n  var myString5 = 'Hello\\' World!';\n  var myString6 = \"Hello\\\" World!\";\n  var myString7 = 'Hello' ' ' 'World!';\n  var myString8 = 'Hello' \" \" 'World!';\n  var myString9 = '''Hello...\n  ...World!''';\n  var myString10 = \"\"\"Hello...\n  ...World!\"\"\";\n  var myString11 = r'Hello World! + \\n';\n  \n\n  print(myString);  // Imprime: Hello World!\n  print(myString2); // Imprime: Hello World!\n  print(myString3); // Imprime: \"Hello\" World!\n  print(myString4); // Imprime: 'Hello' World!\n  print(myString5); // Imprime: Hello' World!\n  print(myString6); // Imprime: Hello\" World!\n  print(myString7); // Imprime: Hello World!\n  print(myString8); // Imprime: Hello World!\n  print(myString9); // Imprime: Hello... \\n ...World!\n  print(myString10); // Imprime: Hello... \\n ...World!\n  print(myString11); // Imprime: 'Hello World! + \\n'\n\n  // Booleans\n  var myBool = true;\n  var myBool2 = false;\n  bool myBool3 = true;\n\n  print(myBool);  // Imprime: true\n  print(myBool2); // Imprime: false\n  print(myBool3); // Imprime: true\n\n  // Symbols\n  print(#mySymbol); // Imprime: Symbol(\"mySymbol\")\n\n  Symbol mySymbol = #miIdentificador;\n  print('Symbol: $mySymbol'); // Imprime: Symbol: Symbol(\"miIdentificador\")\n\n  // Runes\n  Runes myRune = Runes('🎯');\n  print('Runes: $myRune');  // Prints: Runes: (127919)\n  print('Runes as char: ${String.fromCharCodes(myRune)}');  // Prints: Runes: 🎯\n\n  /// Imprimir en la terminal ¡Hola, [nombreLenguaje]!\n  print('¡Hola, Dart!');  // Imprime: ¡Hola, Dart!\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/dart/cristiansystem.dart",
    "content": "/*\n    retosdeprogramacion.com by Mouredev\n    Lenguaje: https://dart.dev/\n*/\n\n/// Representacion de comentarios en Dart\n\n    // Single-line comments\n\n    /* \n        Multi-line comments\n    */\n\n    /// Documentation comments\n    \n    // Crea una variable (y una constante si el lenguaje lo soporta)\n\nvoid main() {\n\n  var nameVar = 'Eminem'; // Deduce automáticamente el tipo de la variable\n  Object lastname = 'Dart'; // Con tipo dinámico\n  String lname = 'EM'; // Con tipo específico del lenguaje\n  final finalName = 'Eminem'; // La variable solo puede ser asignada una vez y se debe asignar en tiempo de ejecución\n  const middlename = 'E.'; // La variable es una constante de tiempo de compilación\n\n  /*\n      Null safety\n          El lenguaje Dart aplica la seguridad de nulos.\n  */\n\n  String? name; // Tipo nullable. Puede ser `null` o una cadena.\n  String nameNotNull; // Tipo no nullable. No puede ser `null` pero puede ser una cadena.\n\n  /*\n      Valor predeterminado\n          Las variables no inicializadas que tienen un tipo nullable tienen un valor inicial de null. Incluso las variables con tipos numéricos son inicialmente nulas, porque los números, como todo en Dart, son objetos.\n  */\n\n  int? lineCount;\n  assert(lineCount == null);\n\n  int lineCountNotNull = 0; // Con la seguridad de nulos, debes inicializar los valores de las variables no nulas antes de usarlas\n\n\n  /// Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n\n    // Cadenas de texto\n    String nombre = 'Juan';\n\n    // Enteros\n    int edad = 25;\n\n    // Números de punto flotante\n    double altura = 1.75;\n\n    // Booleanos\n    bool esEstudiante = true;\n\n    // Caracter\n    String inicial = 'J';\n\n    // Lista de enteros\n    List<int> numeros = [1, 2, 3, 4, 5];\n\n    // Conjunto de números de punto flotante\n    Set<double> alturas = {1.75, 1.80, 1.65};\n\n    // Mapa (diccionario) de información personal\n    Map<String, dynamic> informacionPersonal = {\n        'nombre': 'Juan',\n        'edad': 25,\n        'altura': 1.75,\n        'esEstudiante': true,\n    };\n\n    // Variable dinámica\n    dynamic variableDinamica = 'Hola';\n\n    //Variable Record syntax\n    var record = ('first', a: 2, b: true, 'last');\n\n    // Imprimir los valores\n    print('Nombre: $nombre');\n    print('Edad: $edad');\n    print('Altura: $altura');\n    print('¿Es estudiante?: $esEstudiante');\n    print('Inicial: $inicial');\n    print('Números: $numeros');\n    print('Alturas: $alturas');\n    print('Información Personal: $informacionPersonal');\n    print('Variable Dinámica: $variableDinamica');\n\n    //Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n    print('¡Hola, Dart!');\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/dart/darubiano.dart",
    "content": "/*\n    EJERCICIO:\n    1) Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n    2) Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n    3) Crea una variable (y una constante si el lenguaje lo soporta).\n    4) Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n    5) Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n */\n\n// 1) https://dart.dev/guides\n\n// 2) Comentario de una linea y varias\n\n/*\n  Comentario de varias lineas\n */\n\nvoid main() {\n  // 3) Variable y constante\n  var variable = \"texto\";\n  const pi = 3.1416;\n  // 4) Tipos de variables primitivas o Tipos incorporados https://dart.dev/language/built-in-types\n  // valores con tipo de dato dinamico\n  dynamic variableDinamica = 'Hola';\n  var variableVariable = 123;\n  // variable que pude ser null, se agrega ?\n  String? name = null;\n\n  // Tipos numericos dart\n  int numeroInt = 123;\n  BigInt numeroBigInt = BigInt.from(123456789);\n  double numeroDouble = 123.123;\n\n  // Tipos texto\n  String texto = 'texto';\n\n  // Tipos boleano\n  bool boolVerdadero = true;\n  bool boolFalso = false;\n\n  // Tipos list, record, sets y maps\n  List<int> lista = [1, 2, 3, 4, 5, 6];\n  Record registro = ('primero', a: 2, b: true, 'ultimo');\n  Set<String> conjunto = {'rojo', 'cafe', 'azul'};\n  Map<int, String> diccionario = {\n    1: 'primero',\n    2: 'segundo',\n    3: 'tercero',\n  };\n\n  // 5) print Dart\n  print(\"¡Hola, Dart!\");\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/dart/dimasb69.dart",
    "content": "// URL del Lenguaje usado: https://dart.dev\n\n// Sintaxis para crear una liena de comentario\n\n/* Sintaxis para un comentarios\nde multiples lineas */\n\nvar variable = 'esto es una variable '; \n\nconst constante = 3.141516; //Constante forma 1\n\nfinal constante2 = \"Esto tambien es constante\"; //es otra forma de declarar una cosntante\n\n\nString string = \"Hola,\"+' Dart'; //se puede usar comillas simples ' o triple \"\"\" ó ''' para multiples lineas\n\nint entero = 10; //Numeros enteros\n\ndouble decimal = 10.0; //Numeros con Decimales\n\nbool boleano = true; //True ó False\n\n\n\nvoid main() {\n \n  print(string);// Para imprimir por terminal\n\n}\n\n//Es igual para Flutter"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/dart/evelynnobile.dart",
    "content": "//https://dart.dev/ //\n\n/*\nEsto es\nun comentario\nde multiples\nlineas\n\n*/\n\n/// esto es un comentario\n///\n/// de documentación\n///\n\n//tipos de variables y constantes\nvar name = \"evelyn\";\n\nString username = \"evelyn nobile\";\n\nfinal age = 30;\n\nconst lenguage = \"Dart\";\n\n\n\n//tipos de datos\nint entero = 10;\ndouble decimal = 10.5;\nbool boleano = true;\n\nvar list = [1, 2, 3, 4, 5];\n\nvar map = {\n  \"name\": \"evelyn\",\n  \"age\": 30\n};\n\n//imprimir en terminal\nvoid main() {\n  print(\"¡Hola, Dart!\");\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/dart/jrvdev.dart",
    "content": "void main() {\n  // Documentacion oficial: https://dart.dev/language\n\n// Comentario en una linea\n\n/*\nComentario\nen varias \nlineas */\n\n  /// Comentario de documentacion, se genera con librerias\n\n//Variables y constantes\n\n  var variable1 = \"dart\"; // Sin especificar tipo\n  String variable2 = \"lenguaje\"; // Especificando el tipo\n  final CONSTANTE1 = 20; // no cambia despues de inicializar\n  const CONSTANTE2 = 30; // no cambia durante la compilacion\n\n//Tipos de datos primitivos\n  int edad = 21;\n  double sueldo = 500.30;\n  String nombre = \"Johan\";\n  bool estoyVivo = true;\n  Null estaNulo;\n\n  print(\"Hola dart\");\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/dart/kodenook.dart",
    "content": "// https://dart.dev\n\n/*\n    Comments\n*/\n\n// single-line comment\n\n/*\n    this is a\n    multi-line comment\n*/\n\n/*\n    Var And Const\n*/\n\nvar name = 'kodenook'; // the type is inferred\nString txt = 'string';\nfinal txt2 = 'string2'; // A final variable can be set only once\nfinal txt3 = 'string3'; // const variable is a compile-time constant\n\n/*\n    Primitive Types\n*/\n\nnum number = 2;\nint integer = 1;\ndouble decimal = 2.5;\nString word = 'word';\nbool boolean = true;\n\n/// The main function in Dart prints \"Hello, Dart!\" to the console.\nvoid main() {\n    print('¡Hello, Dart!');\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/dart/lydaf.dart",
    "content": "void main() {\n  //Pagina de Dart https://dart.dev/\n\n  //Comentario en una linea\n\n  /*\n    Comentario en varias\n    varias\n    varias\n  */\n\n  var variable = \"Si\";\n  const constante = 10.23;\n\n  String cadena = \"Hola Dart\";\n  int entero = 8;\n  bool booleano = true;\n  double dobleflotante = 2.891273;\n\n  //Imprimo las variables para evitar los warnings de variables en desuso\n  print(\"Variable: $variable\");\n  print(\"Constante: $constante\");\n  print(\"String: $cadena\");\n  print(\"Entero: $entero\");\n  print(\"Boolean: $booleano\");\n  print(\"Flotante: $dobleflotante\");\n\n  print(\"Hola, Dart!!\");\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/dart/marinaortells.dart",
    "content": "///URL del sitio web oficial: https://dart.dev/\n\n///Formas de crear comentarios:\n\n//Comentario de código en formato línea\n\n///Comentario docuementación en formato línea\n\n/** \n * Comentario de código y documentación en formato bloque\n*/\n\nvoid main() {\n\n  ///Crea una variable\n\n  var reto = 'reto_00'; //declaración implícita\n  String aspectoReto = 'Sintaxis'; //declaración explícita\n\n\n\n      ///Variables constantes. \n      ///   final: no se puede cambiar el valor\n      ///   const: constante en tiempo de compilación\n  \n\n  final nombre = 'Marina'; //declaración constante implícita \n  final String user = 'marina'; //declaración constante explícita\n\n  const mes = 'Enero';\n  const int dia = 1;\n\n  ///Tipos de datos primitivos\n\n  int numEntero = 34;\n  double numDoble = 56.9;\n\n  String texto = \"Reto 00\";\n\n  bool estadoTrue = true;\n  bool estadoFalse = false;\n\n  List listaValores = ['Sintaxis', 'Variables', 'Tipos', 'Print'];\n\n  Set lenguajes = {'dart', 'java', 'python', 'c++'};\n  Set<String> lenguajesPRG = {}; //Conjunto vacío\n\n  Map capitales = {\n    'España' : 'Madrid',\n    'Alemania' : 'Berlín',\n    'Francia' : 'París'\n  };\n\n  //Imprimir valores\n\n  print(\"¡Hola, dart!\");\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/dart/miguelex.dart",
    "content": "// Documentación en https://dart.dev\n\n// Comentario en una linea\n\n/* Comentario\nde varias lineas */\n\nvoid main() {\n  //Declaracion de una variable\n  var lenguaje = 'Dart';\n\n  // Declaracion de una constante\n  const PI = 3.14;\n\n  // Tipos primitivos de datos\n  int unNumero = 10;\n  double unDecimal = 0.5;\n  bool esBooleano = true;\n  String cadena = \"Soy una cadena\";\n\n  // Salida por consola\n  print('Hello $lenguaje!');\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/dart/misaelbentperez.dart",
    "content": "// Sitio oficial Dart: https://dart.dev/\n\n// Esto es un comentario en una linea\n\nfinal String test = ''; // Esto es un comentario de una linea, también...\n\n/* Esto es un comentario \nen varias lineas*/\n\n/// Esto es un comentario de documentación, ejemplo: [arg] representa el argumento\nvoid doNothing(String arg) {}\n\n/**\nEste también es para documentación \ncuando es muy extensa. \n...\n */\n\nvar age = 32; //Variable\n\nconst name = 'Misael'; //Constante\n\n//Datos Primitivos\nint fingersCant = 20; \ndouble pi = 3.1416;\nString language = 'dart';\nbool isEasy = false;\n\nvoid main(List<String> arguments) {\n  print('Hola, $language');\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/dart/raulfauli.dart",
    "content": "// https://dart.dev\n\n// Comentario en línea\n\n/* Comentario\nen varias lineas */\n\nvoid main() {\n  // Variable\n  var lenguaje = 'Dart';\n\n  // Constante\n  const PI = 3.14;\n  final roadmaps = ['00', '01'];\n  roadmaps.add('02');\n  // roadmaps = ['02']; // Error\n\n  // Tipos primitivos\n  int number = 10;\n  double decimal = 10.0;\n  bool boolean = true;\n  String string = \"Text\";\n\n  dynamic dynamicVariable = 'Hola';\n  dynamicVariable = 10;\n  String? nullableString = null;\n\n  List<int> punctuation = [10, 8, 9, 10];\n  Set<String> languages = {'dart', 'java', 'python', 'c++', 'dart'};\n  Map<String, dynamic> person = {'name': 'Raúl', 'age': 39, 'result': 9.25};\n\n  // Imprime por terminal\n  print('¡Hola, $lenguaje!');\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/dart/sitnestic.dart",
    "content": "//* - Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n/// https://dart.dev\n\n//* - Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...)\n// Comentarios de una sola línea\n// TODO: comentario para TODO\n\n/* Comentarios \nmultilínea */\n\n//! Comentarios de documentación\n/**  Los comentarios de documentación son comentarios de varias líneas \n * o de una sola línea que comienzan con /// or /**.  */ \n*/\n\n/// Usando /// en líneas consecutivas\n/// tiene el mismo efecto que un comentario\n/// de documento de varias líneas.\n\nvoid main() {\n  //* - Crea una variable (y una constante si el lenguaje lo soporta)\n  var variable = \"Mi variable\"; // variable\n  const castante = \"Mi constante\"; // constante\n\n  //* - Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...)\n  int integer = 1;\n  double decimal = 1.5;\n  bool boolean = true;\n  String string1 = 'Mi cadena de texto con simple commilla';\n  String string2 = \"Mi cadena de texto con doble comilla\";\n\n  Object object = 'Not single type';\n  dynamic dynamicVariable = 'Or dynamic if necessary';\n  dynamicVariable = 80;\n\n  // Null safety\n  String? nullableString; // Nullable type. Can be `null` or string.\n\n  List<int> integers = [1, 3, 4, 6, 25, 99];\n  Set<String> languages = {'dart', 'java', 'python', 'c++', 'dart'};\n  Map<String, dynamic> person = {'name': 'Gerard', 'age': 43, 'result': 9.25};\n\n  //* - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n  print('¡Hola MoureDev, desde ${languages.first}!');\n  print('integers $integers');\n  print('languages $languages');\n  person.forEach((key, value) {\n    print('$key: $value');\n  });\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/delphi/fduron.dpr",
    "content": "{La web oficial de delphi: https://www.embarcadero.com/products/delphi/}\n\n//Este es un comentario en una sola linea\n\n{Este es otro comentario\n  en varias lineas}\n\n(* Tambin de esta manera se realizan\n   comentarios en varias lneas *)\n\nprogram fduron;\n\n{$APPTYPE CONSOLE}\n\n{$R *.res}\nuses\n  System.SysUtils;\n\n//Las constantes se declaran sin tipo\nconst\n  EstaEsUnaConstante = 'A';\n  EstaEsOtraConstante = 1;\n\nvar\n  UnEntero: Integer;\n  UnEnteroCorto: ShortInt;\n  UnEnteroPequeo: SmallInt;\n  UnEnteroLargo: LongInt;\n\n  UnNumeroSencillo: Single; //Numero Real de 4 bytes\n  UnNumeroDoble: Double; //Numero Real de 8 bytes\n  UnNumeroExtendido: Extended; //Numero Real de 10 bytes\n  UnNumeroReal: Real; //Igual al Double\n\n  UnCaracterLargo: WideChar; //Caracter de tipo Unicode\n  UnCaracter: Char; //Igual que WideChar\n\n  UnTexto: String; //Texto\n  UnTextoAncho: WideString; //Texto con terminacin null (aplicaciones de escritorio)\n  UnTextoEnorme: AnsiString; //Texto de asignacin dinamica tamao esta limitado por el tamao de la memoria disponible\n\n  UnBoleano: Boolean;\n\n  UnSubRango: 1..100;\n\n  UnConjunto: set of 1..10;\n\n  UnApuntadorEntero: ^Integer;\n\n  UnRegistro: record\n    Campo1: Integer;\n    Campo2: String;\n  end;\n\n  UnArregloDeEnteros: array[1..5] of Integer;\n\n  UnaEnumeracion: (Primero, Segundo, Tercero);\nbegin\n  Write('Hola, Delphi!');\n  ReadLn; //Esperar que el usuario presione una tecla\nend.\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/ejercicio.md",
    "content": "# #00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n> #### Dificultad: Fácil | Publicación: 26/12/23 | Corrección: 02/01/24\n\n## Ejercicio\n\n```\n/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/elixir/edalmava.exs",
    "content": "# Comentario en Elixir\n\n# Sitio oficial: https://elixir-lang.org/\n\n# Tipos de datos\n# las variables inician con letra minúscula\n# Debido a que no se usan las variables se les antepone _ para prevenir warning\n\n# Átomo\n_atomo = Cancelado     # Inicia con letra mayúscula\n_atomo2 = :cancelado   # Anteponiendo los dos puntos (:)\n\n# Booleanos o lógicos\n_verdadero = true\n_verdadero2 = :true\n_falso = false\n_falso2 = :false\n\n# Valor nulo nil o ausencia de tipo\n_nulo = nil\n_nulo2 = :nil\n\n# Números\n_entero = 5\n_real = 10.0\n_octal = 0o10\n_binario = 0b1010\n_hexadecimal = 0xff\n_numero_grande = 1_000_000_000\n\n# Listas\n_lista = [1, 2, 3, 4, 5]\n\n# Listas de Caracteres\n# Tipo específico de lista.  Lista homogénea de elementos representables\n# como caracteres\n_lista_caracteres = 'Hola'  # Comilla sencilla\n\n# Cadenas de texto\n_cadena = \"Cadena de Texto\" # Comillas dobles\nsaludo = \"Hola\"\nlenguaje = \"Elixir\"\n\nIO.puts \"¡#{saludo}, #{lenguaje}!\"\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/elixir/juandbc.exs",
    "content": "# https://elixir-lang.org/#\n\n# Este es un comentario de una línea\n\n# Para comentario multi íneas\n# Se usa el símbolo # en cada línea\n\n# La convención en Elixir es snake_case, pero se antepone un _ por recomendacion para las variables no usadas.\n_ejemplo_de_variable = 42\n# No existen constantes reales en Elixir\n\n# Tipos de datos\nentero = 1\n_decimal = 3.14\ncadena = \"Elixir\"\n_booleano = true\natomo = :elixir\n_booleanos_tambien_son_atomos = :true # :false\n_lista = [1, 2, 3]\n_tupla = {atomo, true, \"string\", entero}\n_mapas = %{:nombre => \"Juan\", \"entero\" => entero}\n\nIO.puts(\"Hola \" <> cadena)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/elm/edalmava.elm",
    "content": "-- Este es un comentario de una línea\n\n{-\n  Este es un comentario\n  que abarca varias líneas.\n-}\n\n{-\n  {- Comentario anidado -}\n-}\n\n{-\n  Sitio oficial: https://elm-lang.org/\n-}\n\n{-\n  Las variables en Elm son inmutables\n  \n  nombreVariable : Tipo\n  nombreVariable = valor\n-}\n\nimport Html\n\npi : Float\npi = 3.141516\n\nnombre : String\nnombre = \"Elm\"\n\n-- Si no se proporciona un tipo Elm infiere el tipo\n\nentero = 5\n\nnumeros = [1, 2, 3, 4, 5]  -- Lista\npersona = { nombre = \"Alice\", edad = 30 } -- Registro\n\nmain =\n  Html.text \"¡Hola, Elm!\"\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/erlang/edalmava.erl",
    "content": "% https://www.erlang.org/\n\n% Comentario hasta el final de la línea\n\n-module(edalmava).\n-export([imprimir/0, imprimir/1, tiposDatos/0]).\n\nimprimir() ->\n    % Variables en Erlang\n    % Comienzan por una letra Mayúscula y su valor no puede cambiar    \n    Mensaje = \"Hola, Erlang\",\n    io:format(Mensaje).\nimprimir(Mensaje) ->    \n    io:format(Mensaje).\n\n% Tipos de dato en Erlang\n% Un dato de cualquier tipo se denomina término\ntiposDatos() ->      \n    % Números\n    Enteros = 5,    \n    Flotantes = 5.0, % Aritmética de Punto Flotante\n    % Átomos\n    Atomo = nombre, % Atomos -> Es un literal, una constante con nombre que comienza por una letra minúscula\n    OtroAtomo = 'Nombre',     % Comienza con Mayúscula se encierra entre comillas simples (').  Si comienza con un caracter distinto de minúscula\n    % Booleanos\n    % No existe el tipo booleano en Erlang.  Para denotar los valores booleanos se usan los átomos true y false   \n    % Compuestos\n    Tupla = {sistema, numero}, % Tuplas -> {} Son tipos de datos compuestos con un número fijo de términos\n    Lista = [1, 2, 3, 4, 5], % Listas -> [] Son tipos de datos compuestos con un número variable de términos\n    Cadena = \"Una cadena es una forma corta de lista\", % En Erlang no existe el tipo cadena.  \n    Mapa = #{clave => valor}, % Mapas -> #{clave => valor} Son tipos compuestos con un número variable de asociaciones de clave => valor\n    % TODO: Tipo Record     \n    io:format(\"~w~n\", [Enteros]), % Mostrar número entero\n    io:format(\"~w~n\", [Flotantes]), % Mostrar número Flotante\n    io:format(\"Verdadero: ~w Falso: ~w ~n\", [true, false]), % Mostrar átomos true y false\n    io:format(\"~w~n\", [Tupla]), % Mostrar Tupla\n    io:format(maps:get(clave, Mapa)). \n\n% erl\n% 1> c(edalmava). % Compilar el módulo edalmava\n% {ok, edalmava}  % Si la compilación es exitosa \n% 2> edalmava:imprimir(). % Ejecutar la función imprimir del módulo edalmava\n% Hola, Erlangok % Imprime la cadena 'Hola, Erlang'\n% 3> Mensaje = '¡Bienvenido a Erlang!'.\n% 4> edalmava:imprimir(Mensaje)\n% ¡Bienvenido a Erlang! % Imprime la variable Mensaje"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/f#/edalmava.fsx",
    "content": "// Sitio oficial: https://fsharp.org/\n// F# Basics: https://dotnet.microsoft.com/es-es/languages/fsharp\n// http://learn.microsoft.com/dotnet/fsharp\n\n// Variables en F#\n// Después de asignar un valor, no se puede cambiar, es inmutable\n// Para hacer que sea mutable se emplea la palabra reservada mutable\n// Con inferencia de tipos\nlet nombre_variable = \"Valor\"   // variable string\nlet entero = 5                     // variable int\nlet float = 1.0                  // variable float\nlet char = 'a'                    // variable char\nlet booleano = true               // variable bool - true o false\n\n// Con tipos\nlet cadena : string = \"Hola\"\nlet entero2 : int = 10\nlet float2 : float = 5.0e2\nlet double : double = 20.0\nlet char2 : char = '@'\nlet booleano2 : bool = false\n\n// variables mutables\nlet mutable name = \"Chris\"\nname <- \"Luis\" \n\nlet fsharp = \"F#\"\n\nprintfn $\"¡Hola, {fsharp}!\"   // Imprime la cadena en stdout y agrega un caracter de nueva línea\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/fortran/LeandroCFD.f90",
    "content": "program HOLA_FORTRAN\n    implicit none\n    \n    !Esto es un comentario.\n    !Los comentarios deben iniciar con el caracter \"!\" si es la versión Fortran90 o posterior y con \"c\" si es la versión Fortran77.\n    !La pagina web oficial de Fortran en español es https://fortran-lang.org/es/index , en la pestaña aprender pueden encontrar \n    !multiples recursos para aprender Fortran como manuales y tutoriales\n    !Puedes encotrar un manual muy completo en http://anyp.fcaglp.unlp.edu.ar/biblio/fortran/fortran90.pdf.\n    \n    !Para crear y utilizar una variable en Fortran primero se deben declarar, la sintaxis de declaración es la siguiente.\n    integer a   !Variable de tipo entero    (numeros enteros)\n    real b      !Variable de tipo real      (numeros reales)\n    complex c   !Variable de tipo complejo  (numeros complejos)\n    logical d   !Variable de tipo logico    (verdadero o falso)\n    character e !Variable de tipo caracter  (cadenas de caracteres)\n    !Los nombres de las variables deben iniciar con una letra y tener máximo 23 caracteres.\n    !Es importante saber que Fortran no distingue minusculas de mayusculas, \n    !por lo tanto la variable \"a\" y \"A\" es la misma para Fortran.\n\n    !Para declarar varias variables del mismo tipo de dato se puede utilizar la coma.\n    integer f,g,h,i\n    real j,k,l,m\n    complex n,o,p,q\n    logical r,s,t,u\n    character v,w,x,y\n\n    !Otra sintaxis permitida para declarar variables es utilizando doble dos puntos.\n    integer :: z,aa,ab,ac\n    real :: ad,ae,af,ag\n    complex :: ah,ai,aj,ak\n    logical :: al,am,an,ao\n    character :: ap,aq,ar,as\n\n    !Para declarar una constante se utiliza el atributo \"parameter\".\n    integer, parameter :: at=1000\n    !Las constantes son utiles cuando se tiene certeza que no van variar su valor durante la ejecución del programa.\n    !Por ejemplo valores como el numero pi o el numero de Euler.\n\n    !Se puede asignar un valor a la variable en el momento de su declaración.\n    integer :: au=1\n    real :: av=2.1\n    complex :: aw=(3,4) !A las variables complejas se les debe asignar dos valores, la parte entera (3) y la parte imaginaria (4).\n    logical :: ax=.true. !Las variables logical pueden ser o verdaderas (.true.) o falsas (.false.)\n    character (len=12):: ay='Hola Fortran' !Las variables de cadenas de caracteres deben especificar la longitud de caracteres que\n    !tiene la variable (esto se realiza con el atributo \"len\"), si no se especifica, Fortran asume que la variable solo tiene un \n    !caracter. Si no sabemos que tamaño va a tener la variable podemos utilizar el comodin \"*\".\n    character (len=*), parameter:: az='cadena de caracter', ba='otra cadena'\n    !Si la variable de cadena de caracteres tiene una comilla simple en su interior, entonces se debe asignar su valor con comillas\n    !dobles, tal y como se muestra a continuación.\n    character (len=16), parameter:: bb=\"Ciudad 'Bogotá'\"\n\n    !Las variables de tipo real pueden ser de precisión simple, doble o cuadruple. Para definir la presión se utiliza el atributo\n    !\"kind\", tal y como se muestra a continuación.\n    real (kind=4):: bc !la variable bc tiene precisión simple. Se pueden utilizar valores desde 1.2x10^-38 hasta 3.4x10^38 con\n    !8 cifras significativas.\n    real (kind=8):: bd !la variable bd tiene precisión doble. Se pueden utilizar valores desde 2.2x10^-308 hasta 1.8x10^308 con\n    !16 cifras significativas.\n    real (kind=16):: be !la variable be tiene precisión cuadruple. No se exactamente de que números a que números son permitidos \n    !con esta precisión (sería fabuloso que alguien completara esta información) pero son números con máximo 32 cifras \n    !significativas.\n\n    !Fortran permite crear variables de tipo derivado, las cuales se crean como combinación de variables tipo intrinseco (integer,\n    !real, complex, logical y character) la sintaxis para crear una variable de tipo derivado es la siguiente.\n    type fluido\n        character (len=10):: nombre !Nombre del fluido\n        integer :: gamma !Peso especifico\n        real :: rho !Densidad\n    end type\n\n    !Para declarar una variable tipo fluido es la siguiente.\n    type (fluido) :: water !En este caso la variable \"water\" es de tipo \"fluido\"\n\n    !La asignaciones de valores a la variable \"water\" se puede realizar de dos maneras, primero asignando valores de manera global\n    !o se puede realizar la asignación por componentes\n    water=fluido('agua',9810,999.7) !Asignación global\n    water%nombre='agua' !Asignación por componentes\n    water%gamma=9810\n    water%rho=999.7\n\n    !Para imprimir por terminal en Fortran se pueden utilizar las variables \"print\" o \"write\".\n    print*,'Hola Fortran' !El asterisco imprime el texto luego de la coma en formato por defecto de Fortran.\n    print*,ay !Se imprime en terminal la variable ay con print.\n    write(*,*)'Hola Fortran' !El primer asterisco dentro de los parentesis representa que se va a imprimir en la terminal y el\n    !segundo que se imprime el texto en formato por defecto de Fortran.\n    write(*,*)ay !Se imprime en terminal la variable ay con write.\n\n    !Algunos editores o compiladores de Fortran pueden reconocer que una variable no esta siedo usada dentro del programa, por lo\n    !tanto, para evitar warnings indeseados se utilizan todas las variables declaradas dentro del programa\n    a=1;b=1.1;c=(1,1);d=.true.;e='1';f=1;g=1;h=1;i=1;j=1.1;k=1.1;l=1.1;m=1.1;n=(1,1);o=(1,1);p=(1,1);q=(1,1);r=.true.;s=.true.\n    t=.true.;u=.true.;v='1';w='1';x='1';y='1';z=1;aa=1;ab=1;ac=1;ad=1.1;ae=1.1;af=1.1;ag=1.1;ah=(1,1);ai=(1,1);aj=(1,1);ak=(1,1)\n    al=.true.;am=.true.;an=.true.;ao=.true.;ap='1';aq='1';ar='1';as='1';au=1;av=1.1;aw=1;ax=.true.;bc=1.1;bd=1.1;be=1.1\n\nend program HOLA_FORTRAN"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/fortran/edalmava.f90",
    "content": "program helloworld\n    ! Este es un comentario de una línea\n    ! El caracter ! indica el inicio de un comentario.\n    ! El sitio oficial del lenguaje es https://fortran-lang.org/\n    ! El compilador usado es el GNU Fortran Compiler (gfortran) \n    ! Variables en Fortran\n    ! Hay 5 tipos de datos internos: integer, real, complex, character y logical\n    ! Los nombres de variables deben comenzar con una letra y solamente se pueden utilizar letras, dígitos y _\n    ! No se diferencia entre mayúscula y minúscula    \n    ! Antes que se use una variable se debe declarar\n    ! Fortran es un lenguaje de tipado estático para declarar una variable se usa la sintaxis:\n    !     <tipo_variable> :: <nombre_variable>\n    ! Una vez declarada una variable se le puede asignar y reasignar un valor usando el operador de asignación =\n    ! Declaración de variables\n    ! Variables de datos tipo integer (entera)\n    implicit none        ! Esto significa que las variables serán implícitamente declaradas\n    integer :: a         ! Declaración de la variable a y b\n    INTEGER :: b         ! No se diferencia entre mayúscula y minúscula - palabras reservadas\n    ! Variables de datos tipo real (punto flotante) \n    real :: radio, pi, area\n    ! Variables de datos tipo character (caracter)\n    character :: letra\n    character(7) :: fortran ! Character strings\n    ! Variable de datos complex\n    complex :: frecuencia\n    ! Variable de datos logical\n    logical :: isOK\n    ! Asignación de variables\n    a = 1; b = 2         ! Asignación de valores a las variables enteras\n    print *, a           ! Salida estándar - stdout de la variable a\n    print *, b           ! Salida estándar - stdout de la variable b\n    ! Asignación de valores a las variables reales\n    radio = 1.5              \n    pi = 3.1415927\n    area = pi * radio ** 2\n    print *, 'El área del círculo de radio 1.5 es: ', area\n    ! Asignación de valor a la variable complex\n    frecuencia = (1.0, -0.5)\n    print *, frecuencia\n    ! Asignación de valor a la variable logical \n    isOK = .true.        ! Los valores lógicos o booleanos son .true. y .false. \n    print *, isOK\n    ! Asignación de valores a las variables character\n    letra = 'A'\n    fortran = 'Fortran'\n    print *, '¡Hola, ', fortran, '!'\nend program helloworld"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/gdscript/ElHacedorDeCosas.gd",
    "content": "#https://godotengine.org/\n\n#En GDscript es un comentario todo lo que esté en la misma linea del # a partir de este\n# Para cada linea hay que poner uno nuevo\n\n#variable y constante\nvar variable_jamón = \"bueno\"\nconst constante_queso = \"exelente\"\n\n#variable null\nvar variable_null = null\n\n#variables booleanas o bool\nvar booleano_verdadera : bool = true\nvar booleano_falso : bool = false\nvar numero_verdadero : bool = 1 #cualquiern numero mayor a 0 es verdadero\nvar numero_falso : bool = 0\n\n#variables enteras o int\nvar variable_positiva : int = 1\nvar variable_negativa : int = -70\n\n#variables flotantes on float\nvar flotante_positiva : float = 1.5\nvar flotante_negativa : float = -27.591\n\n#variable de tipo texto o string\nvar texto_cualquiera : string = \"cualquiera\"\n\n#en GDscript todo script tiene que estar asociado a una escena o nodo para poder ejecutarlo\n#función de print\nfunc _ready():\n    var saludo : string = \"¡Hola \"\n    const lenguaje : string = \"GDscript!\"\n    print (saludo + lenguaje) # \",\" = \"+\""
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/gleam/edalmava.gleam",
    "content": "import gleam/io\n\n// Los comentario en Gleam son lineas simples precedidas por //\n// Sitio oficial: https://gleam.run/\n// Documentación: https://gleam.run/documentation/\n\nconst lenguaje = \"Gleam\"\n\npub fn main() {\n  // Declaración de variables con let\n  let saludo = \"¡Hola, \"\n  // Si una variable es asignada pero nunca se usa Gleam emitira un warning\n  let _seignora = \"\"\n  // Con el prefijo _ se ignora el warning\n\n  let _int = 1\n  let _float = 1.0\n  let _formato = 1_000_000\n  let _binario = 0b1010\n  let _octal = 0o10\n  let _hexadecimal = 0x1a0\n  let _string = \"\\\"Hola Mundo\\\"\"\n  let _unicode = \"\\u{1F600}\"\n  let _bool = True || False\n\n  io.println(saludo <> lenguaje <> \"!\")\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/go/Aldroide.go",
    "content": "package main\n\nimport \"fmt\"\n\n//Documentacipn en http://go.dev/\n\n//Comentario en una linea\n/*\nComentario\nen\nvarias\nlineas\n*/\n\nconst Pi float64 = 3.1416\nvar language string = \"Golang\"\n\nfunc main(){\n\tvar age int = 39\n\tvar name string = \"Aldo\"\n\tvar isDev bool = true\n\tvar nota float64 = 9.3\n\tfmt.Println(\"Hello, \" + language)\n\tfmt.Printf(\"Hola soy %v, tengo %v años, mi nota mas alta es %v, %v!\",age, name, nota, isDev)\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/go/AmadorQuispe.go",
    "content": "package main\n\nimport \"fmt\"\n\n//comentario de una sola linea sitio oficial de GO https://go.dev/\n\n/*\nComentario de varias lineas.\nGo es un lenguaje fuertemente tipado creado por Google en el año 2009,\nEn GO los comentarios sirven como documentación\n*/\n\n//Constante nombre\nconst name = \"Amador Quispe\"\n\nfunc sumTwoNumber(a, b int) int {\n\treturn a + b\n}\n\nfunc main() {\n\t//Declaración de variable corta\n\tjob := \"Desarrollador\"\n\t//Declaración de variable Larga, sin inicializar\n\tvar job1 string\n\tjob1 = \"Analista\"\n\t//Declaración de variable larga, con inicialización\n\tvar job2 string = \"Consultor\"\n\t//Asignación multiple\n\tj, k, l := \"dev\", 2.05, 15\n\n\tfmt.Println(name)\n\tfmt.Println(\"Trabajos\")\n\tfmt.Println(job, job1, job2)\n\tfmt.Println(j, k, l)\n\n\t//Tipos de variables en GO\n\n\t//======== TIPOS PRIMITIVOS ===========//\n\t//Tipos booleanos\n\t//---------------------\n\tvar varBoolean bool = true\n\n\t//Tipos numéricos\n\t//---------------------\n\t//Tipos numéricos enteros sin signo\n\n\t//uint8  => 8-bit integers (0 to 255)\n\tvar varUnit8 uint8 = 255\n\t//uint16 => 16-bit integers (0 to 65535)\n\tvar varUint16 uint16 = 1500\n\t//uint32 => 32-bit integers (0 to 4294967295)\n\tvar varUint32 uint32 = 50000\n\t//uint64 => 64-bit integers (0 to 18446744073709551615)\n\tvar varUint64 uint64 = 100000000\n\t//uint => either 32 or 64 bits\n\tvar varUint uint = 1500000\n\n\t//Tipos numéricos enteros con signo\n\n\t//int8 => 8-bit integers (-128 to 127)\n\tvar varInt8 int8 = 120\n\t//int16 => 16-bit integers (-32768 to 32767)\n\tvar varInt16 int16 = 32000\n\t//int32 => 32-bit integers (-2147483648 to 2147483647)\n\tvar varInt32 int32 = 21212212\n\t//int64 => 64-bit integers (-9223372036854775808 to 9223372036854775807)\n\tvar varInt64 int64 = 1000000000\n\t//int => same size as uint\n\tvar varInt int = 1111111112212\n\t//uintptr => suficientemente largo para almacenar bit no interpretados de un puntero\n\tvar varUintptr uintptr = 12312323232334343444\n\n\t//Tipos numéricos con punto flotante\n\n\t//float32 => IEEE-754 32-bit floating-point numbers\n\tvar varFloat32 float32 = 2500.5\n\t//float64 => IEEE-754 64-bit floating-point numbers\n\tvar varFloat64 float64 = 2544412342.3434342432\n\n\t//Tipos numéricos complejos\n\n\t// complex64 complex numbers with float32 real and imaginary parts\n\tvar varComplex64 complex64 = 2i\n\t// complex128 complex numbers with float32 real and imaginary parts\n\tvar varComplex128 complex128 = 1e32i\n\n\t//Tipos alias, el tipo uint8 y int32 tienen alias\n\tvar varAliasByte byte = 123\n\tvar varAliasRune rune = 12355\n\n\t//Tipos cadena\n\t//---------------------\n\tvar varString string = \"Hola dev\"\n\n\t//======== TIPOS COMPUESTOS Y ESTRUCTURADOS ===========//\n\n\t//Tipos array (matrices)\n\t//La capacidad de una matriz se define en el momento de su creación\n\t//---------------------\n\n\tvar varArray [4]int = [4]int{1, 2, 3, 5}\n\n\t//Tipos slice\n\t//Los slices pueden verse como arreglos de longitud dinámica\n\tvar varSlice []int = []int{1, 2, 3, 4, 5, 6}\n\tvarSlice = append(varSlice, 7)\n\n\t//Tipos map\n\t//Tipo de dato que representa una colección de pares clave-valor\n\tvar varMap map[string]string = map[string]string{\"clave1\": \"valor2\", \"clave2\": \"valor2\"}\n\n\t//Tipo Struct\n\t//un conjunto de campos con diferentes tipos de datos\n\ttype Person struct {\n\t\tname string\n\t\tage  int\n\t}\n\tvar person1 = Person{name: \"Amador\", age: 31}\n\n\t//======== TIPOS DE REFERENCIA ===========//\n\t//Tipo pointer\n\t//Representa la dirección de memoria de una variable\n\tvar age int = 28\n\tvar pointerAge *int = &age\n\n\t//Tipo función\n\t//Representa una función\n\tvar funcSum = sumTwoNumber\n\tresult := funcSum(5, 2)\n\n\t//Tipo interface\n\t//Define un conjunto de métodos que una estructura debe implementar\n\ttype Figure interface {\n\t\tArea() float64\n\t}\n\n\tfmt.Println(\n\t\tvarBoolean,\n\t\tvarUnit8,\n\t\tvarUint16,\n\t\tvarUint32,\n\t\tvarUint64,\n\t\tvarUint,\n\t\tvarInt8,\n\t\tvarInt16,\n\t\tvarInt32,\n\t\tvarInt64,\n\t\tvarInt,\n\t\tvarUintptr,\n\t\tvarFloat32,\n\t\tvarFloat64,\n\t\tvarComplex64,\n\t\tvarComplex128,\n\t\tvarAliasByte,\n\t\tvarAliasRune,\n\t\tvarString,\n\t\tvarArray,\n\t\tvarSlice,\n\t\tvarMap,\n\t\tperson1,\n\t\tpointerAge,\n\t\tresult,\n\t)\n\n\tfmt.Print(\"Hola, GO!\")\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/go/DiegoKarabin.go",
    "content": "// https://go.dev/\n\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\t// Este es un comentario de una sola línea\n\n\t// Este es un comentario\n\t// de múltiples líneas\n\n\t/*\n\tEste es un comentario\n\tde múltiples líneas\n\t*/\n\n\tconst foo string = \"bar\"\n\tvar baz string = \"vaz\"\n\n\t// boolean variables\n\tvar boolean_variable bool = true\n\n\t// numeric variables\n\n\t// unsigned integers\n\tvar uint_variable uint = 18446744073709551615\n\tvar uint8_variable uint8 = 255\n\tvar uint16_variable uint16 = 65535\n\tvar uint32_variable uint32 = 4294967295\n\tvar uint64_variable uint64 = 18446744073709551615\n\n\t// signed integers\n\tvar int_variable int = -2147483648\n\tvar int8_variable int8 = 127\n\tvar int16_variable int16 = 32767\n\tvar int32_variable int32 = 2147483647\n\tvar int64_variable int64 = 9223372036854775807\n\n\t// float point numbers\n\tvar float32_variable float32 = 1234.5\n\tvar float64_variable float64 = 13412341212342.3434342432\n\n\t// complex numbers\n\tvar complex64_variable complex64 = 1i\n\tvar complex128_variable complex128 = 1e64i\n\n\t// strings\n\tvar string_variable = \"foobar\"\n\n\tfmt.Println(\"¡Hola, Go!\")\n\n\tfmt.Println(\n\t\tbaz,\n\t\tboolean_variable,\n\t\tuint_variable,\n\t\tuint8_variable,\n\t\tuint16_variable,\n\t\tuint32_variable,\n\t\tuint64_variable,\n\t\tint_variable,\n\t\tint8_variable,\n\t\tint16_variable,\n\t\tint32_variable,\n\t\tint64_variable,\n\t\tfloat32_variable,\n\t\tfloat64_variable,\n\t\tcomplex64_variable,\n\t\tcomplex128_variable,\n\t\tstring_variable,\n\t)\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/go/FreyFonseca117.go",
    "content": "package main\n\nimport \"fmt\"\n\n//Documentacipn en http://go.dev/\n\n//Comentario en una linea\n/*\nComentario\nen\nvarias\nlineas\n*/\n\nconst Pi float64 = 3.1416\n\nvar language string = \"Golang\"\n\nfunc main() {\n\tvar age int = 39\n\tvar name string = \"Aldo\"\n\tvar isDev bool = true\n\tvar nota float64 = 9.3\n\tfmt.Println(\"Hello, \" + language)\n\tfmt.Printf(\"Hola soy %v, tengo %v años, mi nota mas alta es %v, %v!\", age, name, nota, isDev)\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/go/KevinED11.go",
    "content": "package main\n\nimport \"fmt\"\n\n// https://go.dev/\n\n// single line comment\n\n/*\nmulti line comment\n*/\n\nconst PI float64 = 3.1416\n\nfunc main() {\n\tvar lenguaje string = \"golang\"\n\totherLenguaje := \"python\"\n\n\t// primitive types\n\tvar age int = 25\n\tvar name string = \"Kevin\"\n\tvar married bool = true\n\tvar score float64 = 8.5\n\n\tfmt.Println(\"Hola\" + \" \" + lenguaje)\n\tfmt.Println(age, name, married, score, otherLenguaje)\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/go/MiguelP-Dev.go",
    "content": "// main: es el paquete principal del programa\npackage main\n\n// area de importación de paquetes\nimport (\n\t\"fmt\" /* Paquete Format: usado para formatear texto e imprimirlo en consola.*/)\n\n// Sitio oficial del lenguaje Go(Golang): https://go.dev/\n// Sitio oficial de ejemplos de uso del lenguaje: https://gobyexample.com/\n// Sitio oficial de codigo en linea: https://go.dev/play/\n\n/*\nComentarios de una línea(en go si se usan correctamente podemos generar la documentación a partir de estos)\nPara que la documentación se genere a partir de los comentarios debemos comentar de manera acertiva.\nSiempre se comienza por el nombre de la variable, constante, funcion, etc...\n\n// firstName Variable que contiene el nombre del usuario.\nvar firstName string = \"Miguel\"\n\n\nLos comentarios en bloque en go se usan sobre todo para bloques de código que no necesitemos usar en el momento\npero estos bloques de código no deben quedar ahí como comentarios sin usar, esto haría el código muy sucio.\n*/\n// main Es la función principal del programa\nfunc main() {\n\n\t// firstName declaración de variables simples\n\tvar firstName string\n\n\t// Asignación del valor de la variable\n\tfirstName = \"Miguel\"\n\n\t// lastName declaración y asignación de variables simples en la misma línea.\n\tvar lastName string = \"Portillo\"\n\n\t// correo delcaración y asignacion de una variable usando la asignación de variable corta(go infiere el tipo de dato)\n\temail := \"miguelportillo@gmail.com\"\n\n\t// declaracion de variables multiples y con variedad de tipos de datos, (Age es Int y birthDate es un String)\n\tvar age, birthDate = 31, \"13 - 10 - 1993\"\n\n\t/*\n\t\tA diferencia de las variables que se puede declarar y asignar su valor con solo una asignación corta (:=)\n\t\tlas cosntantes se declaran con la palabra reservada const\n\t*/\n\t// isDeveloper declaración de constantes simple\n\tconst isDeveloper = true\n\n\t/*\n\t\tAquí se usa iota para asignar un entero a cada més, que va desde 1 a 12. Iota es un metodo para asignar rapidamente\n\t\tel valor a las constantes si se quieren usar números.\n\t*/\n\t// declaración de constantes en bloque\n\tconst (\n\t\tenero      = iota + 1 // 1\n\t\tfebrero               // 2\n\t\tmarzo                 // 3\n\t\tabril                 // 4\n\t\tmayo                  // 5\n\t\tjunio                 // 6\n\t\tjulio                 // 7\n\t\tagosto                // 8\n\t\tseptiembre            // 9\n\t\toctubre               // 10\n\t\tnoviembre             // 11\n\t\tdiciembre             // 12\n\t)\n\n\t// Tipos de datos en go.\n\n\t// Booleanos(Valores 1 y 0, o Verdadero y falso)\n\tvar a bool = false\n\n\t// Los tipos de datos \"UINT\" aunque son enteros solo almacenan valores positivos.\n\n\t// u8 Variable uint8 Almacena desde 0 a 255\n\tvar u8 uint8 = 255\n\n\t// u16 Variable uint16 Alamcane de 0 a 65535\n\tvar u16 uint16 = 65535\n\n\t// u32 Almacena desde 0 a 4294967295\n\tvar u32 uint32 = 4294967295\n\n\t// u64 Alamacena de 0 a 18446744073709551615\n\tvar u64 uint64 = 18446744073709551615\n\n\t// u Se ajusta a los bits del sistema operativo, es decir que si es de 32Bits(Raro hoy dia) se ajusta a este, lo mismo para 64bits.\n\tvar u uint = 18446744073709551615\n\n\t// Los tipos Int permiten valores tanto negativos coomo positivos.\n\n\t// i8 Almacena desde -128 hasta 127\n\tvar i8 int8 = -128\n\n\t// i16 Alamacena desde -32768 hasta 32767\n\tvar i16 int16 = -32768\n\n\t// i32 Alamacena desde -2147483648 hasta 2147483647\n\tvar i32 int32 = -2147483648\n\n\t// i64 Alamacena desde -9223372036854775807  hasta 9223372036854775807\n\tvar i64 int64 = -9223372036854775808\n\n\t// i Alamacena desde - hasta\n\tvar i int = -9223372036854775808\n\n\t/*\n\t\tAlmacenar un valor mayor es overflow(Desbordamiento).\n\t\tUsar un tipo int que toma como referencia los bits del sistema operativo para asignar el valor: 64bits es igual a int64. Esto no es recomendable sobre todo si es una variable que almacena por ejemplo la edad, para eso el uint8 es más que suficiente.\n\t*/\n\n\t// Imprimiendo valores - Nota: Las variable declaradas deben ser usadas, en GO no se puede y no se debe declarar sin usar.\n\t/*\n\t\tLa unica forma de declararlas es con el ID Blank que se hace con un guión bajo.\n\t\tse usa cuando queres tener la variable sin comentarla porque se usara más tarde,\n\t\tpero solo las variables que estamos seguros de usar.\n\t*/\n\t// Alias de los tipos de datos.\n\t// b byte:es alias para uint8 (0 a 255)\n\tvar b byte = 99\n\n\t// Nota: para obtener valores unicode los datos van entre comillas simples.\n\t// r rune: alias para int32 o unicode\n\tvar r rune = -214748364\n\tvar r2 rune = 'a' // valor unicode = 97\n\n\t// f32 Float32 es una variable de números decimales pero este solo deja un digito luego de la coma.\n\tvar f32 float32 = 990.3\n\n\t// f64 Float64 al contrario qe float32 si toma multiples digitos luego de la coma.\n\tvar f64 float64 = 990.325\n\n\tvar chain string = \"¡Hola!\"\n\n\t// impresión de la primera variable nombre.\n\tfmt.Println(\"nombre :\", firstName, \"Apellido: \", lastName, \"Edad: \", age, \"Correo: \", email, \"Nacimineto: \", birthDate)\n\n\t// Impriendo valores de algunas constantes.\n\tfmt.Println(\"enero: \", enero, \"agosto: \", agosto, \"diciembre: \", diciembre)\n\n\t/*\n\t   Imprimiendo con Printf se pueden ver los placeholders(Verbos) de las variables y\n\t   datos impresos(incluso su dirección en memoria.)\n\t   estas impresiones se pueden y deben simplificar en una funcion para que las imprima una a una,\n\t   pero no es para este primer objetivo de la ruta.\n\t*/\n\tfmt.Printf(\"Tipo de dato: %T, Valor alamacenado: %v\\n\", a, a)\n\tfmt.Printf(\"Tipo de dato: %T, Valor alamacenado: %v\\n\", u8, u8)\n\tfmt.Printf(\"Tipo de dato: %T, Valor alamacenado: %v\\n\", u16, u16)\n\tfmt.Printf(\"Tipo de dato: %T, Valor alamacenado: %v\\n\", u32, u32)\n\tfmt.Printf(\"Tipo de dato: %T, Valor alamacenado: %v\\n\", u64, u64)\n\tfmt.Printf(\"Tipo de dato: %T, Valor alamacenado: %v\\n\", u, u)\n\tfmt.Printf(\"Tipo de dato: %T, Valor alamacenado: %v\\n\", i8, i8)\n\tfmt.Printf(\"Tipo de dato: %T, Valor alamacenado: %v\\n\", i16, i16)\n\tfmt.Printf(\"Tipo de dato: %T, Valor alamacenado: %v\\n\", i32, i32)\n\tfmt.Printf(\"Tipo de dato: %T, Valor alamacenado: %v\\n\", i64, i64)\n\tfmt.Printf(\"Tipo de dato: %T, Valor alamacenado: %v\\n\", i, i)\n\tfmt.Printf(\"Tipo de dato: %T, Valor alamacenado: %v\\n\", r, r)\n\tfmt.Printf(\"Tipo de dato: %T, Valor alamacenado: %v\\n\", r2, r2)\n\tfmt.Printf(\"Tipo de dato: %T, Valor alamacenado: %v\\n\", b, b)\n\tfmt.Printf(\"Tipo de dato: %T, Valor alamacenado: %v\\n\", f32, f32)\n\tfmt.Printf(\"Tipo de dato: %T, Valor alamacenado: %v\\n\", f64, f64)\n\tfmt.Printf(\"Tipo de dato: %T, Valor alamacenado: %q\\n\", chain, chain)\n\n\tfmt.Println(\"Hola, Go.\")\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/go/alexisbarradev.go",
    "content": "/*Crea un comentario en el código y coloca la URL del sitio web oficial del\nlenguaje de programación que has seleccionado\n*/\n\n//https://golang.org/\n\n/*Representa las diferentes sintaxis que existen de crear comentarios\nen el lenguaje (en una línea, varias...).\n*/\n\n/*\nun IDLE de ejemplo:\nhttps://www.jetbrains.com/go/\n*/\n\n//Crea una variable (y una constante si el lenguaje lo soporta)\n\npackage main\n\nimport \"fmt\"\n\nconst dobDay = 10\n\nvar dobYear int = 1984\n\n/*Crea variables representando todos los tipos de datos primitivos\ndel lenguaje (cadenas de texto, enteros, booleanos...).\n*/\n\nvar numInteger int = 2024\n\nvar numFloat float32 = 3.16\n\nvar numComp complex64 = 1 + 2i\n\nvar isTrue bool = true\n\nvar xMas string = \"Merry Xmas!\"\n\nvar letter byte = 'Z'\n\nvar simbolo rune = '±'\n\n//Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"//\nfunc main() {\n\tfmt.Println(\"¡Hola, Go!...\")\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/go/allanoscoding.go",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n// https://go.dev\n\npackage main\n\nimport (\n\t\"fmt\"\n\t\"math/cmplx\"\n)\n\n// Constantes numericas\nconst (\n\tBig   = 10000000000000\n\tSmall = 0.0000000001\n)\n\nfunc main() {\n\t// Este es un comentario normal\n\n\t/*\n\t\tEste es un comentario multilinea del estilo del lenguaje C\n\t*/\n\n\t// Inicialización de variables\n\tvar my_int int\n\tvar my_int_2 int = 2\n\tmy_int_3 := 2\n\n\tfmt.Printf(\"Variable entera 1: %d \\n\", my_int)\n\tfmt.Printf(\"Variable entera 2: %d \\n\", my_int_2)\n\tfmt.Printf(\"Variable entera 3: %d \\n\", my_int_3)\n\n\t// Constantes\n\tconst Verdad = true\n\n\tfmt.Println(Verdad)\n\tfmt.Println(Big)\n\tfmt.Println(Small)\n\n\t// Tipos primitivos\n\tvar my_int_4 int = 19\n\tvar my_uint uint = 1\n\tvar my_string string = \"String\"\n\tvar my_byte byte = 5\n\tvar my_rune rune = 1599\n\tvar my_float float32 = 1.0\n\tvar my_float_2 float64 = 3.5\n\tvar my_complex complex64 = 5i\n\tvar my_complex_2 complex128 = cmplx.Sqrt(5 + 3i)\n\tvar my_bool bool = true\n\n\tfmt.Printf(\"Variable entera 4: %d \\n\", my_int_4)\n\tfmt.Printf(\"Variable entera sin signo: %d \\n\", my_uint)\n\tfmt.Printf(\"Variable cadena de texto: %s \\n\", my_string)\n\tfmt.Printf(\"Variable byte (uint8): %d \\n\", my_byte)\n\tfmt.Printf(\"Variable rune (int32): %d \\n\", my_rune)\n\tfmt.Printf(\"Variable flotante 1: %f \\n\", my_float)\n\tfmt.Printf(\"Variable flotante 2: %f \\n\", my_float_2)\n\tfmt.Printf(\"Variable compleja 1: %v \\n\", my_complex)\n\tfmt.Printf(\"Variable compleja 2: %v \\n\", my_complex_2)\n\tfmt.Printf(\"Variable booleana: %v \\n\", my_bool)\n\n\n\t/*\n\t\tTambien existen los tipos int8, int16, int32, int64 al igual\n\t\tque los enteros sin signo uint8, uint16, uint32, uint64, uintptr.\n\n\t\tint, uint y uintptr dependen de la arquitectura del sistema (32-bits o 64-bits) por\n\t\tlo que si no hay un motivo concreto se recomienda usar int de forma generalizada.\n\t*/\n\n\tfmt.Printf(\"Hola, Go!\")\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/go/curtobrull.go",
    "content": "package main\n\nimport \"fmt\"\n\n// URL de GO => https://golang.org/\n\n// Comentario de 1 línea\n\n/*\nComentario de varias lineas\n*/\n\nconst Constante = \"Javier\"\n\nvar variable = \"Curto\"\n\nfunc main() {\n\n\tvar (\n\t\t// Primitivos\n\t\tintegerPos   uint32    = 10\n\t\tintegerNeg   int32     = -10\n\t\tnumFloat32   float32   = 10.5\n\t\tnumFloat64   float64   = 10.5\n\t\tnumComplex64 complex64 = 3 + 4i\n\t\tboolTrue     bool      = true\n\t\tboolFalse    bool\n\t\ttext         string = \"Javier\"\n\t\tcharRune     rune   = 'a'\n\t\tlanguage     string = \"Go\"\n\t)\n\n\tfmt.Println(\"¡Hola, \" + language + \"!\")\n\n\tfmt.Println(\"Primitivos: \"+Constante, variable, integerPos, integerNeg, numFloat32, numFloat64, numComplex64, boolTrue, boolFalse, text, charRune)\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/go/darubiano.go",
    "content": "/*\n   EJERCICIO:\n   1) Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n   2) Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n   3) Crea una variable (y una constante si el lenguaje lo soporta).\n   4) Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n   5) Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n*/\n\n// 1) https://go.dev/doc/\n\n// 2) Comentario de una linea y varias\n\n/*\nComentario de varias lineas\n*/\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\t// 3) Variable y constante\n\tconst pi float64 = 3.1416\n\tvar variable string = \"Go\"\n\totra_variable := \"otra manera de declarar variable\"\n\n\t// 4) Tipos de variables primitivas https://go.dev/learn/\n\t//Tipos numericos\n\t// unsigned integers\n\tvar _uint uint = 18446744073709551615\n\tvar _uint8 uint8 = 255\n\tvar _uint16 uint16 = 65535\n\tvar _uint32 uint32 = 4294967295\n\tvar _uint64 uint64 = 18446744073709551615\n\t// signed integers\n\tvar _int int = -2147483648\n\tvar _int8 int8 = 127\n\tvar _int16 int16 = 32767\n\tvar _int32 int32 = 2147483647\n\tvar _int64 int64 = 9223372036854775807\n\t// float point numbers\n\tvar _float32 float32 = 1234.5\n\tvar _float64 float64 = 13412341212342.3434342432\n\t// complex numbers\n\tvar _complex64 complex64 = 1i\n\tvar _complex128 complex128 = 1e64i\n\n\t// Tipos boleanos\n\tvar _true bool = true\n\tvar _false bool = false\n\n\t//Tipos lista o slice\n\tvar _slice_string []string = []string{\"1\", \"2\", \"3\"}\n\tvar _slice_int []int = []int{1, 2, 3}\n\n\t// Tipo de dato\n\tvar _map_string_string map[string]string = map[string]string{\"1\": \"first\", \"2\": \"second\", \"3\": \"third\"}\n\tvar _map_string_int map[string]int = map[string]int{\"first\": 1, \"second\": 2, \"third\": 3}\n\n\t// 5) print() hola Go\n\tfmt.Println(\"¡Hola, Go!\")\n\tfmt.Println(\n\t\tpi,\n\t\tvariable,\n\t\totra_variable,\n\t\t_uint,\n\t\t_uint8,\n\t\t_uint16,\n\t\t_uint32,\n\t\t_uint64,\n\t\t_int,\n\t\t_int8,\n\t\t_int16,\n\t\t_int32,\n\t\t_int64,\n\t\t_float32,\n\t\t_float64,\n\t\t_complex64,\n\t\t_complex128,\n\t\t_true,\n\t\t_false,\n\t\t_slice_string,\n\t\t_slice_int,\n\t\t_map_string_string,\n\t\t_map_string_int)\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/go/edalmava.go",
    "content": "package main\n\n// Comentario de una línea - comienza con // y van hasta el final de la línea\n/*\n   Comentarios generales - comienzan con /* y terminan con\n*/\n\n// Sitio oficial: https://go.dev/\n\nimport (\n\t\"fmt\"\n)\n\nvar lenguaje = \"Go\" // Tipo implicito string\n\nfunc main() {\n\t/*\n\t   Declaración de variables\n\n\t   var nombreVariable Tipo\n\t   var nombreVariable Tipo = valor\n\n\t   Declaración corta de variables - solo funciona dentro de funciones\n\n\t   nombreVariable := valor  // El tipo es implicito\n\t*/\n\tvariable := 0\n\tfmt.Println(variable)\n\n\t// Booleanas\n\tvar verdadero, falso bool = true, false\n\tfmt.Println(verdadero)\n\tfmt.Println(falso)\n\n\t// Numéricas\n\t/*\n\t\t\t\tuint\n\t\t        uint8       the set of all unsigned  8-bit integers (0 to 255)\n\t\t\t    uint16      the set of all unsigned 16-bit integers (0 to 65535)\n\t\t\t\tuint32      the set of all unsigned 32-bit integers (0 to 4294967295)\n\t\t\t\tuint64      the set of all unsigned 64-bit integers (0 to 18446744073709551615)\n\n\t\t\t\tbyte // alias for uint8\n\n\t\t\t\tint\n\t\t\t\tint8        the set of all signed  8-bit integers (-128 to 127)\n\t\t\t\tint16       the set of all signed 16-bit integers (-32768 to 32767)\n\t\t\t\tint32       the set of all signed 32-bit integers (-2147483648 to 2147483647)\n\t\t\t\tint64       the set of all signed 64-bit integers (-9223372036854775808 to 9223372036854775807)\n\n\t\t\t\trune // alias for int32\n\t\t\t\t     // represents a Unicode code point\n\n\t\t\t    float32     the set of all IEEE-754 32-bit floating-point numbers\n\t\t\t\tfloat64     the set of all IEEE-754 64-bit floating-point numbers\n\n\t\t\t\tcomplex\n\t\t\t\tcomplex64   the set of all complex numbers with float32 real and imaginary parts\n\t\t\t    complex128  the set of all complex numbers with float64 real and imaginary parts\n\t*/\n\tvar entero int8 = -5\n\tfmt.Println(entero)\n\n\tvar enteroSinSigno uint8 = 0\n\tfmt.Println(enteroSinSigno)\n\n\tvar flotante float32 = 1.2525\n\tfmt.Println(flotante)\n\n\tvar complejo complex64 = 4 + 1i\n\tfmt.Println(complejo)\n\n\t// Cadenas\n\tvar saludo string = \"Hola\"\n\tfmt.Println(saludo)\n\n\t// Arrays\n\tarreglo := [3]int{1, 2, 3}\n\tvar pow = []int{1, 2, 4, 8, 16, 32, 64, 128}\n\tfmt.Println(arreglo)\n\tfmt.Println(pow)\n\n\t// Constantes\n\tconst pi float64 = 3.14159265\n\tfmt.Println(pi)\n\n\t// Punteros\n\tvar p *int\n\ti := 42\n\tp = &i\n\tfmt.Println(*p)\n\n\tfmt.Printf(\"!%s, %s!\", saludo, lenguaje)\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/go/gabrielmoris.go",
    "content": "/*\n * Are you ready to learn or review the programming language of your choice?\n * - Remember that all participation instructions are in the\n *   GitHub repository.\n *\n * First things first... Have you already chosen a language?\n * - Not all of them are the same, but their fundamentals are usually common.\n * - This first challenge will help you familiarize yourself with how to participate\n *   by submitting your own solutions.\n *\n * EXERCISE:\n * - Create a comment in the code and place the URL of the official website of\n *   the programming language you have selected.\n * - Represent the different syntaxes that exist for creating comments\n *   in the language (single line, multiple lines...).\n * - Create a variable (and a constant if the language supports it).\n * - Create variables representing all the primitive data types\n *   of the language (strings, integers, booleans...).\n * - Print the text to the terminal: \"Hello, [and the name of your language]!\"\n *\n * Easy? Don't worry, remember that this is a study path and\n * we must start from the beginning.\n */\n\n//  Documentation: https://go.dev/doc/tutorial/getting-started\n\npackage main\n\nimport (\n\t\"fmt\"\n\t\"unsafe\"\n)\n\n// Declaring a constant\nconst greeting = \"Hello\"\n\nfunc main() {\n      // Declaring a variable\n    var name string = \"World\"\n    fmt.Println(greeting + \", \" + name + \"!\")\n\n     // Modifying the variable\n     name = \"Go\"\n     fmt.Println(greeting + \", \" + name + \"!\")\n\n     types()\n}\n\n\nfunc types(){\n     // Integer types\n     var intVar int = 42\n     var int8Var int8 = 127\n     var int16Var int16 = 32767\n     var int32Var int32 = 2147483647\n     var int64Var int64 = 9223372036854775807\n \n     var uintVar uint = 42\n     var uint8Var uint8 = 255\n     var uint16Var uint16 = 65535\n     var uint32Var uint32 = 4294967295\n     var uint64Var uint64 = 18446744073709551615\n \n     // Floating-point types\n     var float32Var float32 = 3.14159265358979323846\n     var float64Var float64 = 3.14159265358979323846\n \n     // Complex types\n     var complex64Var complex64 = 3.14 + 2.7i\n     var complex128Var complex128 = 3.14 + 2.7i\n \n     // Boolean type\n     var boolVar bool = true\n \n     // String type\n     var stringVar string = \"Hello, Gabriel!\"\n \n     // Byte (alias for uint8) and Rune (alias for int32)\n     var byteVar byte = 'A'\n     var runeVar rune = '☺'\n\n     fmt.Printf(\"int: %v, Type: %T, Size: %d bytes\\n\", intVar, intVar, unsafe.Sizeof(intVar))\n     fmt.Printf(\"int8: %v, Type: %T, Size: %d bytes\\n\", int8Var, int8Var, unsafe.Sizeof(int8Var))\n     fmt.Printf(\"int16: %v, Type: %T, Size: %d bytes\\n\", int16Var, int16Var, unsafe.Sizeof(int16Var))\n     fmt.Printf(\"int32: %v, Type: %T, Size: %d bytes\\n\", int32Var, int32Var, unsafe.Sizeof(int32Var))\n     fmt.Printf(\"int64: %v, Type: %T, Size: %d bytes\\n\", int64Var, int64Var, unsafe.Sizeof(int64Var))\n \n     fmt.Printf(\"uint: %v, Type: %T, Size: %d bytes\\n\", uintVar, uintVar, unsafe.Sizeof(uintVar))\n     fmt.Printf(\"uint8: %v, Type: %T, Size: %d bytes\\n\", uint8Var, uint8Var, unsafe.Sizeof(uint8Var))\n     fmt.Printf(\"uint16: %v, Type: %T, Size: %d bytes\\n\", uint16Var, uint16Var, unsafe.Sizeof(uint16Var))\n     fmt.Printf(\"uint32: %v, Type: %T, Size: %d bytes\\n\", uint32Var, uint32Var, unsafe.Sizeof(uint32Var))\n     fmt.Printf(\"uint64: %v, Type: %T, Size: %d bytes\\n\", uint64Var, uint64Var, unsafe.Sizeof(uint64Var))\n \n     fmt.Printf(\"float32: %v, Type: %T, Size: %d bytes\\n\", float32Var, float32Var, unsafe.Sizeof(float32Var))\n     fmt.Printf(\"float64: %v, Type: %T, Size: %d bytes\\n\", float64Var, float64Var, unsafe.Sizeof(float64Var))\n \n     fmt.Printf(\"complex64: %v, Type: %T, Size: %d bytes\\n\", complex64Var, complex64Var, unsafe.Sizeof(complex64Var))\n     fmt.Printf(\"complex128: %v, Type: %T, Size: %d bytes\\n\", complex128Var, complex128Var, unsafe.Sizeof(complex128Var))\n \n     fmt.Printf(\"bool: %v, Type: %T, Size: %d bytes\\n\", boolVar, boolVar, unsafe.Sizeof(boolVar))\n     fmt.Printf(\"string: %v, Type: %T, Size: %d bytes\\n\", stringVar, stringVar, unsafe.Sizeof(stringVar))\n \n     fmt.Printf(\"byte: %v, Type: %T, Size: %d bytes\\n\", byteVar, byteVar, unsafe.Sizeof(byteVar))\n     fmt.Printf(\"rune: %v, Type: %T, Size: %d bytes\\n\", runeVar, runeVar, unsafe.Sizeof(runeVar))\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/go/gugliio.go",
    "content": "package main\n\nimport \"fmt\"\n\n/* Crea un comentario en el código y coloca la URL del sitio web oficial del\nlenguaje de programación que has seleccionado. */\n\n// https://go.dev/\n\n/* Representa las diferentes sintaxis que existen de crear comentarios\nen el lenguaje (en una línea, varias...). */\n\n// Single line\n\n/*\nMultiLine 1\nMultiLine 2\n*/\n\n// Crea una variable (y una constante si el lenguaje lo soporta).\nvar lang = \"go\"\n\nconst fixedValue = \"constant\"\n\n/* Crea variables representando todos los tipos de datos primitivos del\nlenguaje (cadenas de texto, enteros, booleanos...) */\n\nvar enteros int = 40\nvar flotantes float64 = 0.5\nvar booleanos bool = false\nvar cadenaDeTexto string = \"nombre\"\n\nfunc main() {\n\t// Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\tfmt.Println(\"¡Hola, Go!\")\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/go/hozlucas28.go",
    "content": "// https://go.dev/\n\n// Single line comment.\n\n/*\n\tMulti line comment...\n*/\n\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\t// Variable declarations\n\tvar number01 int = 1\n\tconst number02 int = 2\n\n\tnumber01 = 3\n\t// number02 = 2 // Throw an error because It's a constant.\n\n\t// Primitive data types\n\tconst byteVar byte = 0\n\n\tconst integerVar int = -1\n\tconst integer8Var int8 = -12\n\tconst integer16Var int16 = -123\n\tconst integer32Var int32 = -1234\n\tconst integer64Var int64 = -12345\n\n\tconst uIntegerVar uint = 1\n\tconst uInteger8Var uint8 = 12\n\tconst uInteger16Var uint16 = 123\n\tconst uInteger32Var uint32 = 1234\n\tconst uInteger64Var uint64 = 12345\n\n\tconst float32Var float32 = 3.141592\n\tconst float64Var float64 = 3.141592\n\n\tconst booleanVar bool = true\n\n\tconst stringVar string = \"¡Hello World!\"\n\n\t// Outputs\n\tfmt.Printf(\"number01: %d\\nnumber02: %d\\n\\n\", number01, number02)\n\n\tfmt.Printf(\"> byteVar: %d --> %T\\n\\n\", byteVar, byteVar)\n\n\tfmt.Printf(\"> integerVar: %d --> %T\\n\", integerVar, integerVar)\n\tfmt.Printf(\"> integer8Var: %d --> %T\\n\", integer8Var, integer8Var)\n\tfmt.Printf(\"> integer16Var: %d --> %T\\n\", integer16Var, integer16Var)\n\tfmt.Printf(\"> integer32Var: %d --> %T\\n\", integer32Var, integer32Var)\n\tfmt.Printf(\"> integer64Var: %d --> %T\\n\\n\", integer64Var, integer64Var)\n\n\tfmt.Printf(\"> uIntegerVar: %d --> %T\\n\", uIntegerVar, uIntegerVar)\n\tfmt.Printf(\"> uInteger8Var: %d --> %T\\n\", uInteger8Var, uInteger8Var)\n\tfmt.Printf(\"> uInteger16Var: %d --> %T\\n\", uInteger16Var, uInteger16Var)\n\tfmt.Printf(\"> uInteger32Var: %d --> %T\\n\", uInteger32Var, uInteger32Var)\n\tfmt.Printf(\"> uInteger64Var: %d --> %T\\n\\n\", uInteger64Var, uInteger64Var)\n\n\tfmt.Printf(\"> float32Var: %f --> %T\\n\", float32Var, float32Var)\n\tfmt.Printf(\"> float64Var: %f --> %T\\n\\n\", float64Var, float64Var)\n\n\tfmt.Printf(\"> booleanVar: %t --> %T\\n\\n\", booleanVar, booleanVar)\n\n\tfmt.Printf(\"> stringVar: %s --> %T\\n\\n\", stringVar, stringVar)\n\n\tfmt.Printf(\"¡Hello, %s!\", \"Go\")\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/go/kelvinCB.go",
    "content": "//package main\n\n// Go official website: https://go.dev\n\n// This is a single line comment\n\n/*This is\n  a multiple line comment\n  for this tutorial\n*/\n\npackage main\n\nimport (\n\t\"fmt\"\n\t\"math/cmplx\"\n)\n\n// Variable\nvar my_name = \"CB\"\n\n// Constant\nconst Pi = 3.1416\n\n// Primitive types\nvar my_other_name string = \"Rafael\"\nvar my_number int = 8\nvar my_decimal float64 = 12.41\nvar my_bulb bool = false\nvar my_complex128 complex128 = cmplx.Sqrt(-5 + 12i)\nvar my_uint uint64 = 1<<64 - 1\nvar my_rune rune = 2147483647\n\nfunc main() {\n\t//Print on Terminal name of used programming language\n\tfmt.Println(\"¡Hello, Go!\")\n\n\t//Additional to know what type of variable is ->\n\tfmt.Printf(\"The type of %v is %T\", my_complex128, my_complex128)\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/go/kodenook.go",
    "content": "\n// https://go.dev\n\n/*\n\tComments\n*/\n\n// single-line comment\n\n/*\n\tthis is a\n\tmulti-line comment\n*/\n\npackage main\n\nimport \"fmt\"\n\n/*\n\tVars And Constants\n*/\n\nvar word string = \"string\"\n/*\n\tword2 := \"string2\" // the type is inferred and just inside functions\n*/\nconst constant string = \"constant\"\n\n/*\n\tPrimitive Types\n*/\n\nvar number int = 1 // can be unsigned(uint) and have different ranges(int, int8, int16, int32, int64 or uint versions)\nvar decimal float32 = 3.5 // float32 or float64\nvar txt string = \"word\"\nvar boolean bool = true\n\n/*\n\tPrint\n*/\n\n// The main function in Go prints \"¡Hello, Go!\" to the console.\nfunc main() {\n\tfmt.Println(\"¡Hello, Go!\")\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/go/lara-vel-dev.go",
    "content": "// https://go.dev/doc/\n\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\t// This is a single line comment\n\n\t/* This is a\n\t   multiline comment\n\t*/\n\n\t// Declaring variables\n\tvar myVar string = \"I'm a variable\"\n\tconst myConst string = \"I'm a constant\"\n\tshorthandVar := \"I'm a shorthand syntax variable\"\n\n\t// Print variables\n\tfmt.Printf(\"Var: %s, Const: %s, Shorthand: %s \", myVar, myConst, shorthandVar)\n\n\t/* D A T A    T Y P E S\n\t* int\n\t\t* int8\n\t\t* int16\n\t\t* int32\n\t\t* int64\n\t* uint\n\t\t* uint8\n\t\t* uint16\n\t\t* uint32\n\t\t* uint64\n\t* byte\n\t* float32\n\t* float64\n\t* string\n\t* bool\n\t* rune\n\t* complex\n\t*/\n\n\tvar number int = -56\n\tvar unsignedNumber uint = 24\n\tvar floating float32 = 2.25\n\tvar text string = \"hola\"\n\tvar myByte byte = 'a'\n\tvar isActive bool = true\n\tvar myRune rune = 'Ś'\n\tvar complexNum complex64 = 2.5 + 3.5i\n\n\tfmt.Printf(\"number: %d \\nunsigned number: %d \\nfloat: %f\\ntext: %s\"+\n\t\t\"\\nbyte: %T \\nboolean: %T \\nrune: %T \\ncomplex: %T\", number, unsignedNumber,\n\t\tfloating, text, myByte, isActive, myRune, complexNum)\n\n\t// Print hello go\n\tfmt.Println(\"Hello, Go!\")\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/go/lestaat.go",
    "content": "package main\n\n// This is the golang programing page https://go.dev/\n\n/*\nThis is a multiline comment\nof this beautiful program :-D\n*/\n\nimport \"fmt\"\n\nvar myVariable = \"Golang\"\n\nconst myConstant = \"My constant is here!\"\n\nvar myString string = \"String\"\nvar myBool bool = true\nvar myInt int = 10\nvar myFloat float32 = 3.14\nvar myComplex complex64 = 2 + 3i\nvar myAliasByte byte = 65\nvar myAliasRune rune = '☺'\n\nfunc main() {\n\tfmt.Println(\"Hola \" + myVariable)\n\tfmt.Println(myConstant, myString, myBool, myInt, myFloat, myComplex, myAliasByte, myAliasRune)\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/go/miguelex.go",
    "content": "package main\n\nimport \"fmt\"\n\n// Documentacion en https://go.dev/\n\n// Comentario de una sola linea\n\n/*\nComentario de\nmultiples lineas\n*/\n\nconst PI float64 = 3.1416\n\nvar lenguaje string = \"Go\"\n\nfunc main() {\n\t// Tipos de datos primitivos\n\tvar edad int = 25\n\tvar nombre string = \"Miguel\"\n\tvar isDev bool = true\n\tvar nota float64 = 8.5\n\n\t// Imprimir por consola\n\tfmt.Println(\"Hola \" + lenguaje)\n\tfmt.Println(edad, nombre, isDev, nota)\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/go/n0hagonada.go",
    "content": "package main\n\nimport \"fmt\"\n\n/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n// https://go.dev/doc/effective_go\n\nfunc main() {\n\tconst Pi float64 = 3.14159\n\tvar nombre string = \"Go\"\n\tvar edad int = 30\n\tvar esVerdadero bool = true\n\tvar altura float64 = 1.75\n\tvar b byte = 0x41\n\tvar letra rune = 'ñ'\n\tvar puntero *int = &edad\n\tvar g map[string]int = map[string]int{\"uno\": 1, \"dos\": 2}\n\ttype MiInterface interface{ MiMetodo() string }\n\tvar f []int = []int{1, 2, 3}\n\ttype H struct{ Campo string }\n\tfmt.Println(\"!Hola, \" + nombre)\n\timprimirDatos := fmt.Sprintf(\"Entero: %d\\nCadena de Texto: %s\\nBooleano: %t\\nFlotante: %f\\nByte: %c\\nRuna: %c\\nPuntero: %p\\nMapa: %v\\nArray: %v\", edad, nombre, esVerdadero, altura, b, letra, puntero, g, f)\n\tfmt.Println(imprimirDatos)\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/go/pguillo02.go",
    "content": "package main\n/*\nComentario de bloque: https://go.dev/\n*/\n\n//Comentario de línea\n\nimport \"fmt\"\n\nconst constante = 10 \n\nvar integer int = 1\nvar float float32 = 3.14\nvar complejo complex64 = 1 + 2i\nvar byte byte = 'A'\nvar booleano bool = true\nvar cadena string = \"Hola Go\"\nvar simbolo rune = '±'\n\n\nfunc main()  {\n\tfmt.Println(cadena)\t\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/go/qwik-zgheib.go",
    "content": "package main\n\nimport \"fmt\"\n\n// Golang language documentation: https://go.dev/doc/\n\nfunc main() {\n\t// comment line\n\n\t/*\n\t   multi-line comment\n\t*/\n\n\t// primitive data types\n\tvar number int = 10\n\tvar decimal float64 = 10.2\n\tvar text string = \"Hello, World!\"\n\tvar boolean bool = true\n\n\t// arrays\n\tvar numbers [5]int = [5]int{number, 2, 3, 4, 5}\n\n\t// slices\n\tvar numbersSlice []int = []int{numbers[1], 2, 3, 4, 5}\n\tnumbersSlice = append(numbersSlice, 6)\n\n\t// maps\n\tvar person map[string]string = map[string]string{\n\t\t\"name\":    \"qwik zgheib\",\n\t\t\"gender\":  \"male\",\n\t\t\"address\": \"hanac wichay\",\n\t}\n\n\t// structs\n\ttype Person struct {\n\t\tName    string\n\t\tGender  string\n\t\tAddress string\n\t}\n\n\tvar personStruct Person = Person{\n\t\tName:    person[\"name\"],\n\t\tGender:  person[\"gender\"],\n\t\tAddress: person[\"address\"],\n\t}\n\n\t// print variables\n\tfmt.Println(\"number:\", numbersSlice)\n\tfmt.Println(\"decimal:\", decimal)\n\tfmt.Println(\"text:\", text)\n\tfmt.Println(\"boolean:\", boolean)\n\n\t// print personStruct\n\tfmt.Println(\"personStruct:\", personStruct)\n\n\t/* --- */\n\tfmt.Println(\"Hello, go!\")\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/go/raynerpv2022.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc main() {\n\t// comentario\n\n\t/*\n\t\tcomentario\n\t\tmultiples\n\t\tlineas\n\t*/\n\tconst language string = \"gOlAng\"\n\tVarInt := 10\n\tVarFloat := 10.486485688\n\tVarBool := true\n\tVarString := \"esto es un String\"\n\tfmt.Printf(\"Variable Entera : %d\\n\", VarInt)\n\tfmt.Printf(\"Variable Float : %.2f\\n\", VarFloat)\n\tfmt.Printf(\"Variable Boolean : %v\\n\", VarBool)\n\tfmt.Printf(\"ariable String : %s\\n\", VarString)\n\tfmt.Println(\"Hello \" + language)\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/go/serg-pq.go",
    "content": "package main\n\nimport \"fmt\"\n\n// https://go.dev/\n\nfunc main() {\n\n\t// Comentario de una sola linea\n\n\t/* Comentario de\n\tmultiples lineas*/\n\n\t// Declaración de una Variable\n\tvar myVariable string = \"Sergio\"\n\n\t// Declaración de una Constante\n\tconst myConstant string = \"Colombia\"\n\n\t// Tipos de datos primitivos\n\t// Datos enteros\n\tvar myInt int = 10\n\tvar myInt8 int8 = 20\n\tvar myInt16 int16 = 30\n\tvar myInt32 int32 = 40\n\tvar myInt64 int64 = 50\n\n\tvar myUint uint = 60\n\tvar myUint8 uint8 = 70\n\tvar myUint16 uint16 = 80\n\tvar myUint32 uint32 = 90\n\tvar myUint64 uint64 = 100\n\n\t// Datos flotantes\n\tvar myFloat32 float32 = 123.45\n\tvar myFloat64 float64 = 1.2e+345\n\n\t// Datos caracter\n\tvar myRune rune = 'Ӂ'\n\tvar myByte byte = 'A'\n\n\t// Dato booleano\n\tvar myBooleano bool = true\n\n\t// Imprimir texto\n\tfmt.Println(\"¡Hola, Go!\")\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/go/stiware.go",
    "content": "//Pagina oficial del lenguaje: https://go.dev/\n\n//comentario en linea\n\n/*\ncomentario en varias lineas\n*/\n\n//declaración del paquete principal para que funcione go\npackage main\n//importar paquete fmt para impresiones por consola\nimport \"fmt\"\n\n\n//Crea una variable (y una constante si el lenguaje lo soporta).\nvar miVariable int\nconst miConstate  = \"Stiware\"\n\n\n/*\nla forma para definir varibles más llamativa en go es con := \npero esta solo se puede utilizar dentro de funciones así\n*/\nfunc main(){\n\totraVariable := \"hola\"\n\tfmt.Println(\"Otra forma de definir una variable: \",otraVariable)\n\tfmt.Println(\"Tipos de datos primitivos\")\n\t//llamada a la funcion para mostrar los tipos de datos basicos\n\ttiposPrimitivos()\n\n\t//llamada a la función para presentarme\n\tpresentacion()\n}\n\n\n//Crea variables representando todos los tipos de datos primitivos\nfunc tiposPrimitivos(){\n\tvar boleano bool // valores posibles: verdadero o falso\n\tvar textos string// cualquier cadena de texto como las que mostramos por consola\n\tvar entero int // número enteros (es decir sin decimales), su tamaño depende de si el SO es de 32 o 64 bits\n\tvar flotante float32 // números más grandes y con decimales, tambien esta el float64 que abarca numeros aun más grandes\n\n\tfmt.Println(\"Boleano\",boleano)\n\tfmt.Println(\"Strings\",textos)\n\tfmt.Println(\"Entero\",entero)\n\tfmt.Println(\"Flotante\",flotante)\n\n}\n\nfunc presentacion(){\n\t// El comodín %s me sirve para indicar que ahí se reemplazará un dato string que le enviaré después\n\tfmt.Printf(\"!Hola, GO. Me llamo %s!\",miConstate)\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/go/tartabullroberto.go",
    "content": "// https://go.dev/\n\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\t// Comentario de una sola línea\n\n\t// Comentario de\n\t// múltiples líneas\n\n\t/*\n\t\tComentario de\n\t\tmúltiples líneas\n\t*/\n\n\tconst firstString string = \"first\"\n\tvar secondString string = \"second\"\n\n\t// Otra manera de declarar variables\n\tthirdString := \"third\"\n\n\t// bool\n\tvar trueBool bool = true\n\tvar falseBool bool = false\n\n\t// uint integers\n\tvar _uint uint = 4294967295\n\tvar _uint8 uint8 = 255\n\tvar _uint16 uint16 = 65535\n\tvar _uint32 uint32 = 4294967295\n\tvar _uint64 uint64 = 18446744073709551615\n\n\t// int\n\tvar _int int = -2147483648\n\tvar _int8 int8 = 127\n\tvar _int16 int16 = 32767\n\tvar _int32 int32 = 2147483647\n\tvar _int64 int64 = 9223372036854775807\n\n\t// float\n\tvar _float32 float32 = 123.0\n\tvar _float64 float64 = 12345678910.12345678910\n\n\t// complex\n\tvar _complex64 complex64 = 1i\n\tvar _complex128 complex128 = 1e64i\n\n\t// slice\n\tvar firstSlice []string = []string{\"first\", \"second\", \"third\"}\n\tvar secondSlice []int = []int{1, 2, 3}\n\n\t// map\n\tvar firstMap map[string]string = map[string]string{\"first\": \"first\", \"second\": \"second\", \"third\": \"third\"}\n\tvar secondMap map[string]int = map[string]int{\"first\": 1, \"second\": 2, \"third\": 3}\n\n\tfmt.Println(\"¡Hola, Go!\")\n\n\tfmt.Println(\n\t\tfirstString,\n\t\tsecondString,\n\t\tthirdString,\n\t\ttrueBool,\n\t\tfalseBool,\n\t\t_uint,\n\t\t_uint8,\n\t\t_uint16,\n\t\t_uint32,\n\t\t_uint64,\n\t\t_int,\n\t\t_int8,\n\t\t_int16,\n\t\t_int32,\n\t\t_int64,\n\t\t_float32,\n\t\t_float64,\n\t\t_complex64,\n\t\t_complex128,\n\t\tfirstSlice,\n\t\tsecondSlice,\n\t\tfirstMap,\n\t\tsecondMap,\n\t)\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/go/thegera4.go",
    "content": "// Web oficial de \"GO\" -> https://go.dev/\n/* \nComentario\nen varias lineas \n*/\n\npackage main\n\nimport \"fmt\"\n\nvar isVariable bool = true \n\nconst gravity float64 = 9.8\n\nfunc main() {\n\t//hay muchos mas, pero estos son los mas comunes\n\tvar nickname string = \"thegera4\"\n\tvar age int = 36\n\tvar weight float64 = 80.5\n\t\n\t/* \n\tAlternativamente, se puede hacer lo siguiente:\n\n\tnickname := \"thegera4\"\n\tage := 36\n\tweight := 80.5\n\t\n\tCon esto GO infiere el tipo de dato de la variable, en este caso, string, int y float64\n\ty tambien inicializa la variable con el valor asignado\n\t*/\n\n\tfmt.Println(\"¡Hola, GO!\")\n\tfmt.Printf(\"Mi nombre es %s, tengo %d años y peso %.2f kg\\n\", nickname, age, weight)\n\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/go/zerpajose.go",
    "content": "// https://go.dev/\n/*\nComentarios multilinea\notra linea\notra linea\n*/\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\tvar nombre string = \"GO\"\n\tedad := 25\n\tisLanguage := true\n\tfmt.Println(\"Hola\", nombre)\n\n\t// GO no permite dejar variables sin usar\n\tfmt.Println(edad, isLanguage)\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/harbour/marcosjarrin.prg",
    "content": "/*\n\nweb oficial:\nhttps://harbour.github.io/\n\nDistribución utilizada:\nhttps://www.hmgextended.com/\n\nComentario en varias lineas\n\n*/\n\n// Comentario en una linea\n\n** Comentario en una linea\n\n#define CONSTANTE \"Valor no Cambia\"\n\nfunction main()\n\nlocal Entero, Flotante, Logico\nlocal Cadena\nlocal Fecha\n\n\tCadena   := \"Hola harbour\"\n\tEntero   := 1\n\tFlotante := 10.25\n\tFecha    := ctod('04-26-2024')\n    Logico   := .T.\n\tLogico   := .F.\n\n\t/*\n\t  Se puede crear variables con tipado dinámico sin especificar su alcance, pero no es\n\t  recomendable, el compilador identifica el tipo de datos automáticamente .\n\t  Es case insensitive\n\t  ValorCualquiera := \"Cadena\"  \t  Valorcualquiera := 12  \tvalorCualquiera := 12.45\n\t  es la misma variable.\n\t*/\n\tValorCualquiera := \"Cadena\"\n\tValorcualquiera := 12\n\tvalorCualquiera := 12.45\n\n\t? 'Hola Harbour'\n\nreturn NIL\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/haskell/SalazarProgrammer.hs",
    "content": "-- Sitio web oficial de Haskell: https://www.haskell.org/\n\n-- Comentario de una línea con el uso de dos guiones.\n\n{-\n  Comentario de varias lineas\n  con el uso de llaves y guiones\n-}\n\n{-|\n  Comentario de varias lineas\n  con el uso de llaves,\n  guiones y barra\n-}\n\n{-|\nVariables y constantes: En Haskell, todas las variables son inmutables por defecto (se comportan como constantes)\n-}\n\n-- Variable\nmiVariable :: String\nmiVariable = \"Hola, Haskell!\"\n\n-- Constante\nmiConstante :: Double\nmiConstante = 1.100\n\n{-\n  Tipos de Datos Primitivos:\n  - Enteros (Int e Integer): Int - Enteros de 32/64 bits/ Integer - Enteros de precisión arbitraria\n  - Números de punto flotante: Float - Números de punto flotante/ Double - Números de doble precisión\n  - Booleanos (Bool): (True/False)\n  - Caracteres (Char): Caracteres individuales\n  - Cadenas de texto (String): equivalente a [Char]\n-}\n\n-- Enteros\nentero :: Int\nentero = 45\n\ninteger :: Integer\ninteger = 1234567890\n\n-- Números de Punto Flotante\nflotante :: Float\nflotante = 1.10\n\ndouble :: Double\ndouble = 1.1000\n\n-- Booleanos\nverdadero :: Bool\nverdadero = True\n\nfalso :: Bool\nfalso = False\n\n-- Caracteres\ncaracter :: Char\ncaracter = 'J'\n\n-- Cadenas de Texto (String es sinónimo de [Char])\ncadena :: String\ncadena = \"Haskell es lo mejor\"\n\n{-|\n  Estructuras de datos:\n  - Listas: [a] - colección homogénea de elementos\n  - Tuplas: (a, b, c) - colección heterogénea de tamaño fijo\n-}\n\n-- Listas de enteros\nlistaEnteros :: [Int]\nlistaEnteros = [1, 2, 3, 4, 5, 6]\n\n-- Tuplas\ntuplaEnteros :: (Int, String, Bool)\ntuplaEnteros = (1, \"Haskell\", False)\n\n-- Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nmain :: IO ()\nmain = putStrLn \"¡Hola, Haskell!\"\n\n-- Fin\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/haskell/Seba9906.hs",
    "content": "-- URL oficial del lenguaje de programación Haskell: https://www.haskell.org/\n\n-- Esto es un comentario de una sola línea en Haskell\n\n{-\n   Esto es un comentario\n   de varias líneas en Haskell\n-}\n\n{-\n Crear una variable (en Haskell, las variables son inmutables por defecto)\n Aunque la declaratividad no es obligatoria es muy aconsejable\n-}\nnumero :: Int --Esta es la declaratividad\nnumero = 42\n\n-- Crear una constante (en Haskell todas las variables son básicamente constantes)\npiConstante :: Double\npiConstante = 3.1416\n\n-- Crear variables representando diferentes tipos de datos primitivos\nnombre :: String  -- Cadena de texto\nnombre = \"Haskell\"\n\nverdadero :: Bool  -- Booleano\nverdadero = True\n\nentero :: Int  -- Entero\nentero = 10\n\nflotante :: Float  -- Número de punto flotante\nflotante = 10.5\n\nmain :: IO ()\nmain = putStrLn (\"¡Hola, \" ++ nombre ++ \"!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/haskell/edalmava.hs",
    "content": "-- Comentario de una línea\n-- Sitio oficial: https://www.haskell.org/\n\n{- \n   Comentario de varias líneas\n\n   Documentación oficial: https://www.haskell.org/documentation/\n-}\n\n-- Las variables en Haskell son inmutables\n\ni :: Integer  -- Enteros\ni = 1\n\nd :: Double   -- Real de Punto Flotante de doble precision\nd = 1.0\n\nfl :: Float   -- Real Punto Flotante de simple precisión\nfl = 1.0\n\nc :: Char     -- Caracter\nc = 'a'\n\ns :: String   -- Cadena\ns = \"Haskell\"\n\nt :: Bool     -- Booleanos\nt = True      -- Verdadero\n\nf :: Bool\nf = False     -- Falso\n\no :: Integer\no = 0o10      -- 8 en notación octal\n\nh :: Integer\nh = 0x10      -- 16 en hexadecimal\n\nb :: Integer\nb = 0b1111    -- 15 en binario\n\nu :: ()       -- Tipo de la expresión (), llamada unit\nu = ()\n\nmain :: IO () -- Tipo de una expresión que representa una subrutina de IO que retorna ()\nmain = putStrLn \"¡Hola, Haskell!\"\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/AFOXJONES.java",
    "content": "// URL del sitio oficial de Java\n// https://www.java.com/es/\n\npublic class AFOXJONES {\n\n    // Declaración de una constante\n    private static final String CONSTANTE = \"SOY CONSTANTE\";\n\n    public static void main(String[] args) {\n        // Comentario en una línea\n\n        /*\n         * Comentario\n         * en varias\n         * líneas\n         */\n\n        // Declaración de variables con tipos primitivos\n        String stringVariable = \"variable\";\n        int number = 10;\n        double decimalNumber = 130.21;\n        float bigNumber = 3.4028235E38F;\n        short shortVariable = 1;\n        boolean isTrue = true;\n        char character = 'A';\n        byte byteVariable = 0;\n\n        // Imprimir mensaje en consola\n        System.out.println(\"¡Hola, Java!\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/ARHL2023.java",
    "content": "//Sitio web oficial de Java: https://www.java.com/\n\n// Sintaxis de comentarios en una línea\n/*\nSintaxis de comentarios\nen varias líneas\n*/\n\npublic class ARHL2023 {\n    public static void main(String[] args) {\n\n        // Tipos de datos primitivos en Java\n        String texto = \"Hola, Java!\"; // Cadena de texto\n        int entero = 25; // Entero\n        boolean booleano = true; // Booleano\n        double decimal = 3.14; // Decimal de doble precisión\n        float flotante = 5.67f; // Decimal de precisión simple\n        char caracter = 'A'; // Carácter\n\n        // Variable\n        int numero = 10; // Variable 'numero' de tipo entero con valor 10\n        // Constante\n        final double PI = 3.1416; // Constante 'PI' de tipo double con valor 3.1416\n        String lenguaje = \"Java\";\n\n        // Imprimir por terminal el texto\n        System.out.println(\"¡Hola, \"+lenguaje);\n\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/AbelADE.java",
    "content": "/**\n * Solución del reto #00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO;\n * @author AbelADE\n */\npublic class AbelADE {\n\n    /**\n     * @param args the command line arguments\n     */\n    public static void main(String[] args) {\n        //Comentario con URL del sitio web oficial = https://docs.oracle.com/javase/8/docs/api/\n\n        // Comentario de simple línea\n        \n        /*Comentario \n                de varias líneas*/\n        \n        /**\n         * Comentario JavaDoc, para generar documentación oficial\n         */\n        \n        // Crea una variable (y una constante si el lenguaje lo soporta).\n        final String TEXTO = \"Soy una constante\";\n        String textoVariable = \"Soy una variable\";\n        \n        \n        //Crea variables representando todos los tipos de datos primitivos\n        boolean datoLogico = true; // Almacena valores true o false\n        char caracter = 'a'; // Caracteres unicode de 2 bytes\n        byte numeroMuyPequeño = 100; // Entero entre -128 e 127\n        short numeroPequeño = 25000; //  Entero entre -32768 y 32767\n        int numero = 1000000; // Entero entre -2.147.483.648 y 2.147.483.647\n        long numeroMasGrande = 2000000000L; // Entero entre -9.223.372.036.854.775.808 e 9.223.372.036.854.775.807\n        float decimalPequeño = 15.6666F; // Decimal de 4 bytes\n        double decimal = 15.269899; // Decimal de 8 bytes\n\n        //Tipo de dato no primitivo (Objeto)\n        String texto = \"Soy un texto\";\n        \n        //Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n        System.out.println(\"¡Hola, Java!\");\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/AdrianGonzalezRoble.java",
    "content": "/**\n * Clase con el objetivo de realizar el primer desafío de programación de\n * moure.dev\n * https://dev.java/\n */\npublic class AdrianGonzalezRoble {\n\n    private static final String CONSTANTE = \"Esto es una constante a nivel de clase\";\n\n    public static void main(String[] args) {\n        // comentario en linea\n\n        String variable = \"Esto es una variable\";\n\n        final String constante = \"Esto es una constante local en el método\";\n\n        byte b = 0;\n        short s = 0;\n        int entero = 0;\n        long largo = 0L;\n        float flotante = 0.0f;\n        double doble = 0.0d;\n        char caracter = '\\u0000';\n        String cadena = \"Java\";\n        boolean booleano = false;\n\n        System.out.println(\"¡Hola, \" + cadena + \"!\");\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/AdrianNQ99.java",
    "content": "public class AdrianNQ99 {\n    // Comentario con URL del sitio web oficial de la documentación de Java 8\n    // https://docs.oracle.com/javase/8/docs/api/\n\n    // Comentario de una sola línea\n\n    /*\n     * Comentario de varias líneas\n     */\n    public static void main(String[] args) {\n        final String username = \"AdrianNQ99\"; // Declaración de una constante de tipo String\n\n        String name = \"Adrian\"; // Declaración de una variable de tipo String\n        int age = 21; // Declaración de una variable de tipo entero\n        float height = 1.75f; // Declaración de una variable de tipo flotante\n        char initial = 'A'; // Declaración de una variable de tipo caracter\n        boolean isStudent = true; // Declaración de una variable de tipo booleano\n        byte num = 127; // Declaración de una variable de tipo byte\n        long numLong = 1000000000000000000L; // Declaración de una variable de tipo long\n        short numShort = 32767; // Declaración de una variable de tipo short\n        double numDouble = 3.14159265359; // Declaración de una variable de tipo double\n\n        System.out.println(\"Hola, Java!\"); // Imprime \"Hola Java!\" en la consola\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/AdrianSaint07.java",
    "content": "public class Main {\n    public static void main(String[] args) {\n\n        // 4.  Datos primitivos en Java\n\n        char caraacter = 'A'; // caracter\n         boolean booleano = false; // booleano\n        String Texto = \"Hola, Java\"; // cadena de texto\n        int entero = 35; // entero\n         float flotante = 3.14f; // numero decimal simple\n        double decimal = 5.13; // numero decimal doble precision\n\n        // 3. Crear variable y constante\n\n        // Variable\n        int numero = 70; // variable tipo numero\n\n        // Constante\n        final double pi = 3.14; // Constante pi de tipo double con valor 13.1416\n        String lenguaje = \"Java\";\n\n        // imprimir en la terminal el texto\n\n        System.out.print(\"Hola, \"+\" Java!\");\n\n    }\n}\n\n/*   EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n// 1. Pagina web del lenguaje seleccionado\n\n// https://www.java.com/es/\n\n// 2. Hay dos formas de crear lineas de comentarios son las siguientes\n\n// se usan dos barras inclinadas para \"//\" comentarios de una linea\n\n/* se usa\n para varias lineas de comentarios\n */\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Ainoaran.java",
    "content": "//Reto #00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO;\n\n\npublic class Ainoaran {\n\n    public static void main(String[] args) {\n\n        //URL Sitio oficial JAVA: https://docs.oracle.com/javase/8/docs/api/\n\n        /*Comentarios:\n        - Los comentarios de una sola línea se realizan utilizando \"//\"\n        - Los comentarios en varias líneas se inicializan con \"/*\" y se finaliza con '* /'\n         */\n\n        //VARIABLES:\n\n        String variable = \"Es una variable\";\n        final String constante = \"Es una constante\";\n\n        //DATOS PRIMITIVOS:\n\n        // Byte: Ocupa 8 bits (1 byte). Valores de -128 a 127 (inclusive).\n        byte age = 25;\n\n        // Short: Ocupa 16 bits (2 bytes). Valores de -32,768 a 32,767 (inclusive).\n        short year = 2024;\n\n        // int: Numero entero. Ocupa 32 bits (4 bytes). Valores de -2,147,483,648 a 2,147,483,647 (inclusive).\n        int population = 8200000 ;\n\n        // long: Número entero largo. Ocupa 64 bits (8 bytes). Valores de -9,223,372,036,854,775,808 a 9,223,372,036,854,775,807 (inclusive).\n        long distance= 1000000000L;\n\n        // float: Número de punto flotante de precisión simple. Ocupa 32 bits (4 bytes).\n        float height = 1.75f;\n\n        // double: Número de punto flotante de doble precisión. Ocupa 64 bits (8 bytes).\n        double decimal = 6371.0;\n\n        // char: Un solo carácter Unicode. Ocupa 16 bits (2 bytes).\n        char character = 'A';\n\n        // boolean: Valor booleano, true o false. Ocupa 1 bit.\n        boolean isAdult = true;\n\n        // Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\n        System.out.println(\"¡Hola, Java!\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Albert-29.java",
    "content": "public class Albert29 {\n    public static void main(String[] args) {\n        /* https://www.oracle.com/java/ \n         * Java es un lenguaje orientado a objetos\n         * Multiplataforma es decir no importa el\n         * sistema operativo en que sea ejecutado \n        */\n        \n        //El anterior comentario es de varias lineas\n        //Este es un comentario de una sola linea\n        //Observa cual es la diferencia entre ellos\n\n        \n    //En java la sintaxis para crear una variables \n    int variable;\n    /* Para poder declarar una constante en java se utiliza la palabra     \n    reservada final, seguida del tipo de dato, nombre de la constante y al ser una constante es necesario inicializarla con un valor en este caso el valor de PI */\n    final double pi = 3.1416;\n\n    //Tipos de datos primitivos en java\n    \n    byte variable1 = 127;\n    short variable2 = 32000;  \n    int variable3 = 23485334;\n    long variable4 = 2398454345L;\n    float variable5 = 54.76F;\n    double variable6 = 1.2345676;\n    char variable7 = 'A';\n    boolean variable8 = true;\n\n    System.out.println(\"Hola, Java\");\n\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/AleFine.java",
    "content": "public class AleFine {\n    /* Crea un comentario en el código y coloca la URL del sitio web oficial del\n    lenguaje de programación que has seleccionado. */\n\n    \n    //Página Oficial: https://www.java.com/es/\n\n\n    /*Representa las diferentes sintaxis que existen de crear comentarios\n        en el lenguaje (en una línea, varias...). */\n\n    // Comentario Tipo 1:\n    // Comentario Tipo 1.\n\n    /*Comentario Tipo 2:\n     * \n     * \n     * \n     * Comentario Tipo 2.\n    */\n    \n    \n    //Crea una variable (y una constante si el lenguaje lo soporta).\n    int var;\n    final double pi = 3.14159;\n\n\n    //Crea variables representando todos los tipos de datos primitivos\n    int var_2;\n    boolean var_8;\n    char var_9;\n    double var_5;\n    float var_3;\n    byte var_10;\n    short var_11;\n    long var_12;\n\n    public static void main(String[] args) {\n    System.out.println(\"¡Hola, \"+\"Java!\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/AlexisDiaz000.java",
    "content": "public class AlexisDiaz000 {\n    public static void main(String[] args) {\n        /*\n        Este es un comentario de varias líneas en Java.\n        Puedes escribir varias líneas de comentario aquí.\n        */\n\n        // Este es un comentario de una línea en Java\n\n        // Creación de una variable\n        int variable = 10;\n\n        // Creación de una constante (usando 'final')\n        final double PI = 3.1416;\n\n        // Variables representando todos los tipos de datos primitivos en Java\n        byte byteVar = 127;  // 8-bit entero con signo\n        short shortVar = 32767;  // 16-bit entero con signo\n        int intVar = 2147483647;  // 32-bit entero con signo\n        long longVar = 9223372036854775807L;  // 64-bit entero con signo\n        float floatVar = 3.14f;  // 32-bit punto flotante\n        double doubleVar = 3.141592653589793;  // 64-bit punto flotante\n        char charVar = 'A';  // 16-bit carácter Unicode\n        boolean booleanVar = true;  // Valor booleano (true o false)\n\n        // Imprimir por terminal el texto: \"¡Hola, Java!\"\n        System.out.println(\"¡Hola, Java!\");\n        \n    }\n    \n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Alextc35.java",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n // 1.\n // Esta es la documentación oficial de Java https://dev.java/\n // Página web oficial de Java https://www.java.com\n\n public class Alextc35 {\n    public static void main (String[] args){\n        // 2.\n        // Esto es un comentario de una línea.\n\n        /* \n        * Esto es un comentario\n        * de varias líneas.\n        */\n\n        // 3.\n        // Variable;\n        String cadenaTexto = \"Esto es una cadena de texto\";\n\n        // Constante;\n        final int IVA = 21; // Esta variable es una constante.\n\n        // 4.\n        // Datos primitivos.\n\n        // Valores literales;\n        // Valor booleano VERDADERO:\n        boolean verdadero = true;\n\n        // Valor booleano FALSO:\n        boolean falso = false;\n\n        // Letra A:\n        char letraMayuscula = 'A';\n\n        // Número 100:\n        byte by = 100;\n\n        // Número 1000:\n        short sh = 1000;\n\n        // Número 1000000:\n        int in = 1000000;\n\n        // Valor 26 en decimal\n        int decVal = 26;\n\n        // Valor 26 en hexadecimal\n        int hexVal = 0x1a;\n\n        // Valor 26 en binario\n        int binVal = 0b11010;\n\n        // Números enteros;\n        // Comprendido entre [-128 , 127]:\n        byte b = 35;\n        \n        // Comprendido entre [-32.768 , 32.767]:\n        short s = 3500;\n        \n        // Comprendido entre [-2^31 , (2^31)-1]:\n        int i = 35000;\n        \n        // Comprendido entre [-2^63 , (2^63)-1]:\n        long l = 3_000_000_000L;\n\n        // Números reales:\n        // Precisión simple;\n        float f = 0.25f;\n\n        // Precisión doble;\n        double PI = Math.PI;\n\n        // 5.\n        System.out.println(\"¡Hola, Java!\");\n    }\n }\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/AlgelOro.java",
    "content": "public class AlgelOro {\n\n    //Esta es la documentación oficial de Java https://dev.java/\n \n    /**\n     * Este es un comentario multilinea\n     * Nos sirve para comentarios extensos \n     */ \n \n     //Variable constante\n     public static final String CONSTANTE = \"Esta es una constante\";\n\n     public static void main(String[] args) {\n         \n     /**\n      * Tipos de datos en Java\n      */\n \n      \n     //Variable tipo texto\n        String varString = \"Variable tipo string\";\n        //Variable tipo entero\n        int varInt = 12;\n        //Varibale tipo Long\n        long varLong = 4L;\n        //Variable tipo boolean\n        boolean isBoolean = false;\n        //Variable tipo float\n        float varFloat = 9.7f\n        //Variable tipo double\n        double varDouble = 6.4d\n        //Variable tipo char\n        char varChar = \\u0000;\n        //Variable tipo byte\n        byte varByte = 0;\n        \n        System.out.println(\"¡Hola, Java!\")\n    }\n \n }"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Alvaropg15.java",
    "content": "package Ejercicio00;\n\npublic class Ejercicio00 {\n    public static void main(String[] args) {\n        //Documentación oficial Java en: https://dev.java/\n\n        /*\n        EJERCICIO:\n         * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n         *   lenguaje de programación que has seleccionado.\n         * - Representa las diferentes sintaxis que existen de crear comentarios\n         *   en el lenguaje (en una línea, varias...).\n         * - Crea una variable (y una constante si el lenguaje lo soporta).\n         * - Crea variables representando todos los tipos de datos primitivos\n         *   del lenguaje (cadenas de texto, enteros, booleanos...).\n         * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n        */\n\n        String ejemploVariable = \"Esta es una variable\";\n         final int MI_CONSTANTE = 15; //Constante\n\n        //Datos primitivos:\n        char ejChar = 's';\n        short ejShort = 3;\n        int ejInt = 2024;\n        float ejFloat = 1.5f;\n        double ejDouble = 45.67;\n        boolean ejBoolean = true;\n        boolean ejBoolean2 = false;\n\n        String lenguaje = \"Java\";\n        System.out.println(\"Hola, \" + lenguaje + \"!\");\n\n\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/AmadorQuispe.java",
    "content": "public class AmadorQuispe {\n    // Esto es un comentaria de una sola linea\n    // URL Oficial: https://dev.java/\n    /*\n     * Esto esComentario\n     * de varias lineas.\n     */\n    static final String constante = \"Soy Dev\";\n\n    public static void main(String[] args) {\n\n        // Enteros\n        byte diasMes = 31;\n        short diasLustro = (12 * 31) * 5;\n        int velocidadLuz = 299792458;\n        long anioLuz = velocidadLuz * 365;\n        // Flotantes/Decimales\n        float pi = 3.1415926535f;\n        double e = 2.718281828459045235360;\n        // Caracteres\n        char letraA = 'a';\n        char letraANumerico = 61;\n        // Boleanos\n        boolean verdadero = true;\n        boolean falso = false;\n\n        // Tipo de datos Wrapper\n        // ejemplo\n        String saludo = \"Hola mundo\";\n\n        System.out.println(\"¡Hola, JAVA!\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/AnCarLu.java",
    "content": "//https://www.java.com/es/\n\n//Comentarios en Java\n\n//Comentario de una linea\n\n/*\n Comentario de varias lineas\n */\n\n /*\n  *Comentarios en bloque \n  *\n  */ \npublic static void main (String [] args){\n\t//Variables y constantes\n\tString variable = \"variables en java\";\n\tfinal String constante = \"Java\";\n\n\t//Datos primitivos en Java\n\tchar unicode = '&';\n\tbyte numeroMasPequeño = 1;\n\tshort numeroPequeno = 2;\n\tint numero = 10;\n\tlong numeroMayor= 152645231;\n\tfloat numeroComaFlotante = 45.25f;\n\tdouble numeroDecimal = 45.55;\n\tboolean operadorLogico = false;\n\n\t//Impresion por pantalla del saludo\n\tSystem.out.println(\"Hola \" + constante);\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/AnaLauDB.java",
    "content": "// URL oficial de Java: https://www.java.com\n\n/*\n  Ejemplo de comentarios en Java:\n  - Una sola línea: usando //\n  - Varias líneas: usando /* ... *​/\n  - Comentarios de documentación: usando /** ... *​/\n*/\n\n/**\n * Clase de ejemplo para el reto #00\n */\npublic class AnaLauDB {\n    public static void main(String[] args) {\n        // Constante para el valor de PI\n        final double PI = 3.1416;\n\n        // Variables con diferentes tipos de datos primitivos\n        String texto = \"Hola, mundo\";\n        int numeroEntero = 42;\n        double numeroDecimal = 2.718;\n        boolean valorBooleano = true;\n        char caracter = 'A';\n        byte numeroByte = 100;\n        short numeroCorto = 32000;\n        long numeroLargo = 123456789L;\n        float numeroFlotante = 3.14f;\n\n        // Imprimir por terminal el texto solicitado\n        System.out.println(\"¡Hola, Java!\");\n\n        // Imprimir variables para verificar\n        System.out.println(\"Texto: \" + texto);\n        System.out.println(\"Entero: \" + numeroEntero);\n        System.out.println(\"Decimal: \" + numeroDecimal);\n        System.out.println(\"Booleano: \" + valorBooleano);\n        System.out.println(\"Carácter: \" + caracter);\n        System.out.println(\"Byte: \" + numeroByte);\n        System.out.println(\"Short: \" + numeroCorto);\n        System.out.println(\"Long: \" + numeroLargo);\n        System.out.println(\"Float: \" + numeroFlotante);\n        System.out.println(\"Constante PI: \" + PI);\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Anaroncero.java",
    "content": "public class Anaroncero {\n    public static void main(String[] args) {\n \n    /*\n     * EJERCICIO:\n     * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n     *   lenguaje de programación que has seleccionado.\n     * - Representa las diferentes sintaxis que existen de crear comentarios\n     *   en el lenguaje (en una línea, varias...).\n     * - Crea una variable (y una constante si el lenguaje lo soporta).\n     * - Crea variables representando todos los tipos de datos primitivos\n     *   del lenguaje (cadenas de texto, enteros, booleanos...).\n     * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n     *\n     * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n     * debemos comenzar por el principio.\n     */\n\n\n    // 1.\n    // https://www.java.com/es/\n\n    // 2.\n    /* Comentario \n       varias \n       líneas */\n\n    // Comentario en una línea\n\n    // 3.\n    String variable = \"anaroncero\";\n    final String variable2 = \"usuario\";\n\n    // 4.\n    // enteros\n    byte num1 = 1; // –128 a 127\n    short num2 = 30000; // –32,768 a 32,767\n    int num3 = 2000000000; // –2,147,483,648 a 2,147,483,647\n    long num4 = 9000000; // –9,223,372,036,854,775,808 a 9,223,372,036,854,775,807\n\n    // decimales\n    float pi = 3.1415926535f; // 4 bytes \n    double e = 2.718281828459045235360; // 8 bytes \n\n    // carácter\n    char c = 'A';\n    char cnumerico = 78;\n\n    // alfanuméricos\n    String cadena = \"Hola Mundo\";\n\n    // booleanos\n    boolean verdadero = true;\n    boolean falso = false;\n\n    // 5.\n    System.out.println(\"Hola JAVA!\");\n}    \n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/AndresDevp.java",
    "content": "\npublic class AndresDevp{\nstatic void main(String args[]){\n    // EJERCICIO:\n    /* Crea un comentario en el código y coloca la URL del sitio web oficial del\n        lenguaje de programación que has seleccionado.*/\n\n        //https://dev.java/\n\n    /* Representa las diferentes sintaxis que existen de crear comentarios\n        en el lenguaje (en una línea, varias...).*/ \n\n        //\n        /* */ \n\n    /* Crea una variable (y una constante si el lenguaje lo soporta).*/ \n\n        String nombre;\n        final int numero;\n\n    /* Crea variables representando todos los tipos de datos primitivos\n        del lenguaje (cadenas de texto, enteros, booleanos...).*/\n\n        long enteroGrande = 10000;\n        int entero = 1;\n        double doble = 1.2;\n        float decimal = 1.3f;\n        boolean boleano = true;\n        String cadenaCaracteres = \"Soy Andres\";\n        char caracter = 'a';\n\n                \n    /* Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"*/ \n\n        System.out.println(\"¡Hola, Java!\");\n\n        }\n    }"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/AndrewCodev.java",
    "content": "// URL: https://www.java.com/es/\n\n//Esto es un comentario de una sola lines\n/*Comentario\n    * de\n    varias lineas*/\n\npublic class AndrewCodev {\n    public static void main(String args[]) {\n        final String constante = \"Mi primera constante\";\n        String lenguaje = \"Java\";\n        \n        byte edad = 25;\n        short poblacion = 30000;\n        int codigoPostal = 12345;\n        long cuentaBancaria = 1234567890L; // L al final para indicar que es un long\n        float temperatura = 25.5f; // f al final para indicar que es un float\n        double precio = 99.99;\n        char inicial = 'A';\n        boolean esMayorDeEdad = true;\n        \n        System.out.println(\"¡Hola, \"+lenguaje+\"!\");\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/AngelDevSarrollo.java",
    "content": "public class AngelDev {\n    public static void main(String[] args) {\n\n        // caracteres\n        char caracter = '\\u0040';\n        char decimal = 64;\n        System.out.println(\"caracter = \" + caracter);\n        System.out.println(\"decimal = \" + decimal);\n        System.out.println(\"decimal = caracter: \" + (decimal == caracter));\n\n        char simbolo = '@';\n        System.out.println(\"simbolo = \" + simbolo);\n        System.out.println(\"simbolo = caracter: \" + (simbolo == caracter));\n\n        char espacio = '\\u0020';\n        char retroceso = '\\b';\n        char tabulador = '\\t';\n        char nuevaLinea = '\\n';\n        char retornoCarro = '\\r';\n\n        System.out.println(\"char corresponde en byte:\" + System.lineSeparator() + Character.BYTES);\n        System.out.println(\"Char corresponde en bites = \" + Character.SIZE);\n        System.out.println(\"Character.MIN_VALUE = \" + Character.MIN_VALUE);\n        System.out.println(\"Character.MAX_VALUE = \" + Character.MAX_VALUE);\n\n\n        // Enteros y flotantes\n        byte numeroByte = 127;\n        System.out.println(\"numeroByte = \" + numeroByte);\n        System.out.println(\"tipo byte corresponde en byte a \" + Byte.BYTES);\n        System.out.println(\"tipo byte corresponde en bites a \" + Byte.SIZE);\n        System.out.println(\"valor máximo de un byte: \" + Byte.MAX_VALUE);\n        System.out.println(\"valor mínimo de un byte: \" + Byte.MIN_VALUE);\n\n        short numeroShort = 32767;\n        System.out.println(\"numeroShort = \" + numeroShort);\n        System.out.println(\"tipo short corresponde en byte a \" + Short.BYTES);\n        System.out.println(\"tipo short corresponde en bites a \" + Short.SIZE);\n        System.out.println(\"valor máximo de un short: \" + Short.MAX_VALUE);\n        System.out.println(\"valor mínimo de un short: \" + Short.MIN_VALUE);\n\n        int numeroInt = 2147483647;\n        System.out.println(\"numeroInt = \" + numeroInt);\n\n        System.out.println(\"tipo int corresponde en byte a \" + Integer.BYTES);\n        System.out.println(\"tipo int corresponde en bites a \" + Integer.SIZE);\n        System.out.println(\"valor máximo de un int: \" + Integer.MAX_VALUE);\n        System.out.println(\"valor mínimo de un int: \" + Integer.MIN_VALUE);\n\n        long numeroLong = 9223372036854775807L;\n        System.out.println(\"numeroLong = \" + numeroLong);\n\n        System.out.println(\"tipo long corresponde en byte a \" + Long.BYTES);\n        System.out.println(\"tipo long corresponde en bites a \" + Long.SIZE);\n        System.out.println(\"valor máximo de un long: \" + Long.MAX_VALUE);\n        System.out.println(\"valor mínimo de un long: \" + Long.MIN_VALUE);\n\n        var numeroVar = 9223372036854775808f;\n\n\n        // boleanos\n        boolean datoLogico = true;\n        System.out.println(\"datoLogico = \" + datoLogico);\n\n        double d = 98765.43e-3; // 98.76543\n        System.out.println(\"d = \" + d);\n\n        float f = 1.2345e2f; // 123.45\n        System.out.println(\"f = \" + f);\n\n        datoLogico = d < f;\n        System.out.println(\"datoLogico = \" + datoLogico);\n\n        boolean esIgual = (3-2 == 1);\n        System.out.println(\"esIgual = \" + esIgual);\n\n        String nombre = \"AngelDev\";\n\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/AngelSanchezT.java",
    "content": "// Visita el sitio oficial de Java: https://www.oracle.com/java/\n\n\n// Este es un comentario de una sola línea.\n\n/*\n   Este es un comentario\n   que abarca varias líneas.\n*/\n\n/*\n    Como ejecutar la siguiente clase de Java: \n    1. Instalación el JDK.\n\n    2. Validar que este instalado con el comando: java -version\n\n    3. Posicionar la terminal en la carpeta: \n    cd C:\\DESARROLLO\\git\\roadmap-retos-programacion\\Roadmap\\00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\\java\n\n    4. Compilación de la clase Java, el proceso genera un archivo AngelSanchezT.class\n        javac AngelSanchezT.java\n\n    5. Ejecución de la clase Java: (Ejecución del archivo sin la extensión .class)\n        java AngelSanchezT\n */\n\n public class AngelSanchezT {\n    public static void main(String[] args) {\n        // Declaración de una variable\n        String mensaje = \"¡Hola, Java!\";\n\n        // Declaración de una constante (final indica que es constante)\n        final int CONSTANTE = 42;\n\n        // Tipos de datos primitivos\n        int entero = 10;\n        double decimal = 3.14;\n        char caracter = 'A';\n        boolean booleano = true;\n\n        // Imprimir por terminal\n        System.out.println(mensaje);\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/AntonioJZP86.java",
    "content": "public class AntonioJZP86 {\n    // https://www.java.com/es/\n    // Esto es un comentario de una línea\n\n    /*\n     * Esto es un comentarrio en varias líneas\n     */\n\n    public static void main(String[] args){\n        String variable= \"¡Hola, \";\n        final String constante = \"Java!\";\n        char letra = 'A';\n\n        byte edad = 123;\n        short altura = 12345;\n        int cantidad = 1234567890;\n        long largo = 1234567890123456789L;\n\n        float flotante = 11.11f;\n        double doble = 11.1;\n\n        boolean esVerdadero = true;\n\n        System.out.println(variable + constante);\n\n    }\n}\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/AriasLopez.java",
    "content": "public class AriasLopez{\n    public static void main(String[] args){\n        \n        //https://www.oracle.com/java/\n\n        // Esto es un comentario de una linea\n        /*\n         * Esto es un comentario de \n         * varias lineas\n         * \n         */\n\n        int numero = 5;\n            System.out.println(\"Esta es una variable de tipo entero: \" + numero);\n        final int constante = 10;\n            System.out.println(\"Esta es una constante de tipo entero: \" + constante);\n        \n        // Tipos de datos\n\n        int entero = 1; // Tipo int, almacena numeros enteros\n        float flotante = 2.5f; // Tipo float, almacena numeros decimales\n        double doble = 15.52; // Tipo double, almacena numeros decimales mas grandes\n        String cadena = \"esto es un texto\"; // Tipo String, almacena cadenas de texto\n        char caracter = 'T'; // Tipo char, almacena un solo carácter\n        boolean Verdadero = true; // Tipo boolean, retorna un valor verdadero\n        boolean falso = false; // Tipo boolean, retorna un valor falso\n\n        System.out.println(\"entero: \" + entero + \", Flotante: \" + flotante + \", Doble: \" + doble + \", Cadena: \" + cadena + \", Char: \" + caracter + \", Verdadero: \" + Verdadero + \", Falso: \" + falso + \".\");\n\n        System.out.println(\"Hola, Java \");\n\n\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/B3nkos.java",
    "content": "// https://www.java.com\n\npublic class B3nkos {\n    public static void main(String[] args) {\n        // this is one line comment\n\n        /*This is a\n        * comment\n        * with\n        * multiple\n        * lines\n        */\n\n        // constant and variable\n        final String CONSTANT = \"My Constant\";\n        String variable = \"My variable\";\n        System.out.println(\"Hello from Java!\");\n\n        // primitives data types\n        boolean areYouReady = true;\n        char myChar = 'y';\n        byte myByte = 12;\n        short myShort = 20;\n        int myInt = 233;\n        long myLong = 34366L;\n        float myFloat = 12.45F;\n        double myDouble = 354.54;\n\n        // Non-primitive\n        String name = \"Doe\";\n\n        System.out.println(\"¡Hi, Java!\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Benja0501.java",
    "content": "public class Benja0501 {\n    // esto es un comentario de una linea\n    // https://www.java.com/es/\n    /*\n    esto es un comentario de varias lineas\n     */\n    public static void main(String[] args) {\n        var numero = 5;\n        var cadena =  \"esto es una cadena\";\n        //datos primitivos:\n        int entero = 5;\n        float flotante = 12.2f;\n        double  doble = 54.4;\n        char letra = 'a';\n        long largo = 5454545;\n        byte bit = 1;\n        String palabra = \"Hola mundo\";\n        boolean booleano = true;\n        //Salida en la terminal\n        System.out.println(\"¡Hola, Java!\");\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/BertoMP.java",
    "content": "public class BertoMP {\n    public static void main(String[] args) {\n        // WEB OFICIAL\n        // Para encontrar información sobre Java dirígite a su web oficial: https://www.java.com/\n\n        // COMENTARIOS\n        // En Java tenemos 3 tipos de comentarios:\n\n        // - Comentarios de una única línea (// Comentario):\n        // Sirven por ejemplo para explicar una variable.\n\n        // - Comentarios de varias líneas (/* Comentario */):\n        /* Este tipo de comentarios sirven\n         * para explicar por ejemplo un pequeño\n         * proceso que ocurre dentro de una\n         * de nuestras funciones. */\n\n        // - Comentarios de documentación (/** Comentario */):\n        /**\n         * Este tipo de comentarios se utilizan para generar documentación\n         * sobre el código que en el caso de Java se denomina JavaDoc.\n         * Por ejemplo, los podremos ver explicando de forma detallada cómo\n         * funciona una de las funciones que hayan sido implementadas.\n         * Suelen ir acompañadas de etiquetas que ayudan a entender mejor\n         * el código o aportan información extra:\n         *  - @param: Determina el tipo de parámetro que recibe la función.\n         *  - @return: Determina el tipo de resultado/retorno que produce\n         *             la función al final de su ejecución.\n         *  - @version: Versión del método o la clase.\n         *  - Etc.\n         */\n\n        // VARIABLES Y CONSTANTES\n        /* Para declarar una variable en Java debemos indicar su tipo y el\n         * nombre de la variable. Puede estar inicializada o no, en el caso\n         * de que no lo esté tendrá un valor por defecto u otro.\n         * Por convención, el nombre de las variables debe seguir la nomenclatura\n         * camelCase. */\n        int miVariableInicializada = 33;\n        int miVariableNoInicializada;\n\n        /* Para declarar una constante en Java debemos hacer algo similar\n         * pero utilizando la palabra reservada 'final'. Además, todas\n         * las constantes deben ser inicializadas en su declaración y,\n         * por convención, es recomendable que su nombre sea en mayúsculas. */\n        final int MI_CONSTANTE = 40;\n\n        // DATOS PRIMITIVOS\n        // En Java tenemos los siguientes tipos de datos primitivos:\n\n        // - DATOS NUMÉRICOS ENTEROS\n        byte miByte = 12; // Números desde -128 hasta 127.\n        short miShort = 12642; // Números desde -32.768 hasta el 32.767.\n        int miInt = 1726171821; // Números desde -2.147.483.648 hasta 2.147.483.647.\n        long miLong = 10000000000L; // Números desde -9.223.372.036.854.775.808 hasta 9.223.372.038.854.775.807.\n\n        // - DATOS NUMÉRICOS DECIMALES\n        float miFloat = 3.141592f; // Números hasta 6-7 decimales.\n        double miDouble = 3.141592653; // Números hasta 15 decimales.\n\n        // - DATOS LÓGICOS\n        boolean miBoolean = true; // Almacena un valor booleano (true o false).\n\n        // - CARACTERES\n        char miChar = 'A'; // Almacena un carácter o un valor ASCII.\n\n        /* Para declarar cadenas de texto en Java no tenemos un tipo primitivo como tal,\n         * sino que se utiliza la clase String para ello. */\n        String miString = \"Esto es un String de prueba\";\n\n        // IMPRESIÓN POR CONSOLA\n        System.out.println(\"¡Hola, Java!\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/BlasBarragan.java",
    "content": "/**\n * * EJERCICIO #00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n * \n * @version v1\n * \n * @since 06/01/2024\n * \n * @author Blas Barragán\n * \n */\n public class BlasBarragan {\n    public static void main(String[] args) {\n            \n        // WEB OFICIAL\n            // https://www.java.com/\n        \n        // COMENTARIOS\n            // Comentario simple (1 linea)\n                // Se encabeza cada linea por \"//\"\n            // Comentario compuesto (multilinea)\n                /*\n                * La primera linea se encabeza con \"/**\"\n                * Las lineas interiores iran siempre precedidas de \"*\"\n                * Y la linea final de cierre del comentario, unicamente contendrá \n                */ \n            // Comentario de documentación (multilinea)\n                /** <- Como el anterior pero con un \"*\" extra.\n                 * Este tipo de comentario multilinea, se usa para describir el código.\n                 * Podemos generar tantas lineas com queramos y también,\n                 * añadir tags usando \"@\" como los que se ven en la cabecera de este archivo.\n                 */\n\n        // DECLARACIÓN DE VARIABLES\n            /**\n             * Todas las variables en su definición iran precedidas de su tipo de dato.\n             * Y seguirán la siguiente extructura: \"tipoDatoVariable nombreVariable = valorVariable;\"\n             * Es recomendable declarar una variable por linea e inicializarlas donde esten declaradas.\n             * Pueden declararse en cualquier parte del programa, pero siempre antes de que sea usada.\n             * Por connvención, se declararán utilizando camelCase y al inicio del bloque correspondiente.\n             */\n            // Variables\n            int variable; // Si no inicializamos la variable, el sistema le atribuye un valor por defecto.\n            int variableInicializada = 0; // Al inicializar la variable, se le atribuye el valor declarado.\n            final int VARIABLE = 0; // Las variables constantes se declaran en MAYUSCULAS, van precedidas de la palabra \"final\" y siempre hay que inicializarlas.\n\n        // DATOS PRIMITIVOS\n            // Numericos\n            byte varByte = 1; // Enteros muy cortos. => Numeros de -128 a 127. Valor por defecto \"0\".\n            short varShort = 2; // Enteros cortos. => Numeros de -32.768 a 32.768. Valor por defecto \"0\".\n            int varInt = 3; // Enteros. => Numeros de -2.147.483.648 hasta 2.147.483.647. Valor por defecto \"0\".\n            long varLong = 4L; // Su valor, siempre irá terminado con \"L\". Enteros largos. => Números desde -9.223.372.036.854.775.808 hasta 9.223.372.038.854.775.807. Valor por defecto \"0L\".\n            // Decimales\n            float varFloat = 1.0F; // Su valor, siempre irá terminado con \"f\". Numeros de hasta 7 decimales. => Desde +/-1.4E-45 a +/-3.4E38. Valor por defecto \"0.0f\".\n            double varDouble = 2.0d; // Su valor, siempre irá terminado con \"d\". Numeros de hasta 16 decimales. => Desde +/-4.9E-324 a +/-1.7E308. Valor por defecto \"0.0d\".\n            // Caracteres\n            char varChar = 'A'; // Su valor siempre irá entre comillas simples 'X'. Caracter ASCII o Unicode de \\u0000 a \\uFFFF. \n            // Datos Lógicos\n            boolean varLogico = true; // Valor true o false. Valor por defecto false.\n\n        // CADENAS DE TEXTO\n            /* \n            * En JAVA, las variables String existen en forma de clase que representa cadenas de caracteres.\n            */ \n            String varCadena = \"Soy una String\"; // Su valor siempre irá entre comillas dobles \"X\". Valor por defecto \"null\".\n        \n        // IMPRESION POR TERMINAL\n            System.out.println(\"¡Hola, JAVA!\");\n\n    }\n }\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Bohorquezjael.java",
    "content": "public class Bohorquezjael {\n    /**\n     * * EJERCICIO #00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO:\n     * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n     *  lenguaje de programación que has seleccionado.\n     * - Representa las diferentes sintaxis que existen de crear comentarios\n     * en el lenguaje (en una línea, varias...).\n     * - Crea una variable (y una constante si el lenguaje lo soporta).\n     * - Crea variables representando todos los tipos de datos primitivos\n     * del lenguaje (cadenas de texto, enteros, booleanos...).\n     * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n     * \n     * @param void\n     */\n\n    public static void main(String[] args) {\n        // https://www.java.com/es/\n\n        // This is a single line comment\n        /*\n         * This is a multiline comment\n         */\n\n        String variable = \"this is a variable\";\n        final String constant = \"this is a constant\";\n\n        byte age = 123; // 8 bits\n        short height = 12345; // 16 bits\n        int quantity = 1234567890; // 32 bits\n        long longNumber = 1234567890123456789L; // 64 bits\n\n        float floating = 11.11f; // 32 bits\n        double doubleNumber = 11.1; // 64 bits\n\n        boolean isTrue = true;\n\n        char letter = 'A'; // 16 bits\n\n        System.out.println(\"¡Hola, Java!\");\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/BrayanDeLaOssa.java",
    "content": "\n// https://www.oracle.com/java/ \n\npackage com.mycompany.sintaxis.basica;\n\nimport javax.swing.DefaultListModel;\n\npublic class SintaxisBasica {\n\n    public static void main(String[] args) {\n      \n        // esto  es un comentario en java\n        \n        /*\n        esto es un comentarion de varias lineas en java \n        */\n        \n        \n        //DATOS PRIMITIVOS\n        \n        int a = 3;  //numero entero \n        double b = 4.6; // numero decimal \n        \n        boolean mayor= true;  //Boolean es Verdadero  \n        boolean menor = false;  // Boolean es Falso\n        \n        char c = 'A'; // un solo caracter\n        String valorNulo = null; // valor nulo/vacio \n        \n        final double Pi = 3.14; //valor constante \n        \n        \n        System.out.println(\"Hola Java\");\n        \n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/CesarCarmona30.java",
    "content": "// Sitio web del lenguaje:\n// https://docs.oracle.com/en/java/\n\n// Comentario de línea\n\n/**\n * Este es un comentario\n * de varias líneas\n */\n\n/*\n  Esto también es un\n  comentario de\n  varias líneas\n */\n\npublic class CesarCarmona30 {\n  public static void main(String[] args) {\n    \n    // Variable\n    String name = \"Cesar\";\n    // Constante: se declaran con final\n    final String GENDER = \"MALE\";\n\n    // TIpos de datos primitivos\n    byte numByte = 127;\n    short numShort = 32767;\n    int numInt = 2147483647;\n    long numLong = 9223372036854775807L;\n    float numFloat = 21.4f;\n    double height = 1.75;\n    boolean alive = true;\n    boolean dead = false;\n    char blood = 'O';\n    String country = \"México\";\n\n    String language = \"Java\";\n    System.out.println(\"¡Hola, \" + language + \"!\");\n  }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Chakerr.java",
    "content": "//https://www.oracle.com/java/\n\n// Comentario en una línea\n\n/**\n * \n * Comentario en varias lineas\n * \n */\n\n\n public class Chakerr {\n\n    public static void main(String[] args) {\n\n        //variables de todos los tipos primitivos\n\n        char variableChar;\n        String variableString = \"Hola mundo\";\n        boolean variableBoolean = false;\n        byte variableByte = 127;\n        double variableShort = 32.767;\n        int variableInt = 214748364;\n        long variableLong = 125000;\n        double variableFloat = 3.1;\n        \n        System.out.println(variableString);\n        System.out.println(variableBoolean);\n        System.out.println(variableByte);\n        System.out.println(variableShort);\n        System.out.println(variableInt);\n        System.out.println(variableLong);\n        System.out.println(variableFloat);\n        \n        System.out.println(\"¡Hola, java!\");\n        \n    }\n\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/ChrystianCalderon.java",
    "content": "// Sitio oficial https://www.java.com/\n\n// Comentario en linea\n\n/*\n    Comentario para\n    varias lineas\n*/\n\npublic class ChrystianCalderon {\n    public static void main(String[] args) {\n        // variable\n        String variable = \"variable\";\n        \n        // constante\n        final String constante = \"constante\";\n        \n        // tipos de datos primitivos\n        byte tipoByte = 20;\n        short tipoShort = 100;\n        int tipoInt = 1000;\n        long tipoLong = 10000;\n        float tipoFloat = 3.14f;\n        double tipoDouble = 3.14;\n        boolean tipoBoolean = true;\n        char caracter = 'a';\n        String cadena = \"Java\";\n        \n        System.out.println(\"¡Hola, \" + cadena + \"!\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/CikeTheBear.java",
    "content": "public class CikeTheBear {\n    public static void main(String[] args) {\n        \n    \n//https://java.com/\n\n//Asi se hace un comentario de una sola linea\n\n/* Y así se puede comentar en varias lineas,\nen todas las que quieras,\nno es broma,\nno hay limite de lineas\n.\n.\nlo ves?\n */\n\n\nString miNombre = \"CikeTheBear\"; // Mi variable.\nfinal double PI = 3.14159265358979323846; // Constante (el keyword \"final\" indica que no se puede cambiar el valor de la variable).\n\nint miEdad = 33; // Mi edad.\ndouble miAltura = 1.79f; // Mi altura en metros. \nboolean aprendiendoProgramacion = true; // Si, estoy aprendiendo programacion.\n\nSystem.out.println(\"Hola, Java!!!\");\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Clarancedev.java",
    "content": "/**\n * #00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n * @author clarancedev\n * @version 1.0\n * @date 2025-04-05\n */\n\n// Página web oficial de Java: https://www.java.com/en/\n\n// Esta es la sintaxis para comentarios de una sola linea.\n\n/*\nEsta es la sintaxis para\ncomentarios de varias líneas.\n */\n \npublic class Clarancedev {\n\n    public static final String CONSTANTE_STRING = \"Soy una constante de tipo String\";\n\n    public static void main(String[] args) {\n\n        // Java tiene 8 tipos de variables primitivos:\n        byte soyByte = 0; // Almaceno valores numéricos enteros. Rango: de -128 a 127\n        boolean soyBoolean = true; // Almaceno 2 valores: verdadero o falso\n        char soyChar = 'c'; // Almaceno un solo caracter, o valor de tipo ASCII\n        double soyDouble = 0.0; // Almaceno valores numéricos decimales. Rango: hasta 16 dígitos decimales\n        float soyFloat = 0.0f; // Almaceno valores numéricos decimales. Rango: hasta 7 dígitos decimales, añadiendo siempre la letra \"f\" al final\n        int soyInt = 0; // Almaceno valores numéricos enteros. Rango: de -2.147.483.648 a 2.147.483.647\n        long soyLong = 0; // Almaceno valores numéricos enteros. Rango: de -9.223.372.036.854.775.808 a 9.223.372.036.854.775.807\n        short soyShort = 0; //Almaceno valores numéricos enteros. Rango: de -32.768 a 32.767\n\n        // Esta es la variable para cadenas de texto en Java, aunque ojo, no es una variable primitiva:\n        String soyString = \"¡Hola, Java!\";\n\n        // Así se imprime por la terminal con Java:\n        System.out.println(soyString);\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/CoronelSam.java",
    "content": "public class CoronelSam {\n/*\n * Crea un comentario en el código y coloca la URL del sitio web oficial del\n * lenguaje de programación que has seleccionado.\n */\n\n// https://www.java.com/\n\n/* \n * Representa las diferentes sintaxis que existen de crear comentarios\n * en el lenguaje (en una línea, varias...).\n*/\n\n// Hola mundo\n\n/*\n * Hola\n * Mundo\n */\n    public static void main(String[] args) {\n    // - Crea una variable (y una constante si el lenguaje lo soporta).\n     int velocidad = 1;\n     final double PI = 3.1416;\n    //* - Crea variables representando todos los tipos de datos primitivos\n     int number = 2;\n     short corto = 20;\n     long numeroSeguridad = 20_42_12_16;\n     float tipoFloat = 16.00f;\n     double llama = 9.11;\n     boolean siNo = true;\n     char caracter = 'L';\n     String saludo = \"Hola, Java!!\";\n    //* - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n     System.out.println(saludo); \n    }\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/CristianMR87.java",
    "content": "public class CristianMR87 {\n    public static void main(String[] args) {\n        \n        // https://www.java.com/es/\n\n        //Comentario en una linea\n        /*\n         * Comentario\n         * en\n         * varias\n         * lineas\n         */\n\n        //Crear una variable:\n        int miVariable = 1234;\n        final int constante = 1;\n\n        //Variables con tipos de datos primitivos\n        int valorInt = 12;\n        double valorDouble = 12.3;\n        float valorFloat = 12.4f;\n        String valorString = \"JAVA\";\n        char valorChar = 'A';\n        boolean valorBoolean = true;\n\n        System.out.println(\"Hola, \"+valorString);\n\n\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/CyberSutro.java",
    "content": "//https://www.java.com/es/\n\n/**\n *\n * @author AdanSutro\n */\npackage algoritmos.retosprogramacion;\n\npublic class RetosProgramacion {\n\n    public static void main(String[] args) {\n    \n//datos primitivos\n      int num=1;\n      double num2=5;\n      boolean opcion3=true;\n      String Cybersutro;\n      float num3= 6.79f;\n      char adan;\n      \n      //variable\n      int cualquiernumero=100;\n      \n      //variable constante EULER\n      final double e = 2.71828;\n      \n     System.out.println(\"Hola Euler \" +e);\n   \n      \n      \n      \n      \n    }\n      \n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/DSMHP0.java",
    "content": "/*\n * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license\n * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Main.java to edit this template\n */\npackage javaapplication16;\n\n/**\n *\n * @author DAVID\n */\npublic class JavaApplication16 {\n\n \n    public static void main(String[] args) {\n        \n        /*__________ 1 _______________\n         Link del sitio oficial del Lenguaje: \n        https://www.java.com/es/\n        */\n        \n        //__________ 2 _______________\n        //EJEMPLO COEMTARIO DE (1) LINEA\n        \n        \n        /* _________ 3 _______________\n        \n        EJEMPLO COMENTARIOS EN BLOQUE\n        \n        */\n        \n        /* _________ 4 _______________\n        \n                 Variable\n        \n       */\n        \n        int VARIABLE_A = 15;\n\n        final int CONSTANTE_EJE = 7 ;\n        \n        /* _________ 4 _______________\n        \n             Tipos de Datos Primitivos\n        \n       */\n        \n        \n        long EJEMPLO_1 = 777666;\n        \n        char EJEMPLO_2 = 'L';\n        \n        String EJEMPLO_3 = \"Manolo\";\n        \n        System.out.println(\"My name is \"  + \"Manolo\" );\n        \n        boolean  EJEMPLO_4 = false;\n        \n        \n        \n         System.out.println(\"¡Hola, Jsva\");\n    }\n    \n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Daeduol.java",
    "content": "public class Daeduol {\n    //    linea comentada\n    /*multiples lineas comentadas\n    daeduol\n    java\n    */\n//    https://dev.java/\n\n    /* Variables primitivas */\n    byte number8 = 1;\n    short number16 = -32768;\n    int number32 = 12;\n    long number64 = 2147483647;\n    float aFloat32 = 1.13f;\n    double height = 1.70;\n    boolean SkyIsBlue = true;\n    char char16 = 'a';\n    /*Variables de tipo string*/\n    String nombre = \"Juan\";\n    String apellido = \"Pérez\";\n\n    public static void main(String[] args) {\n        System.out.println(\"¡Hola Java!\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/DanielBelenguer.java",
    "content": "public class DanielBelenguer {\n\n    /*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\npublic static void main(String[] args) {\n    // Esto es un comentario de una linea.\n\n    /* Esto\n     * es\n     * un\n     * comentario\n     * de\n     * varias\n     * lineas\n     */\n\n     // WEB Oficial de Java: https://www.java.com/es/\n\n    // Creacion de una variable y una constante\n    boolean siono = true;\n    final int NUMCONSTANTE = 10;\n    \n    // Todos los tipos de datos primitivos en Java\n    \n    // Numerales:\n    int num1 = 6;\n    long num2 = 154785;\n    float num3 = 15.6F;\n    double num4 = 25.5;\n    \n    // Caracteres:\n    String letra = \"a\";\n    char letra2 = 'b';    \n    \n    // Booleanos:\n    boolean siono2 = true;\n\n    System.out.println(\"¡Hola, Java!\");\n}\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Danisaurio94.java",
    "content": "\n\n    \n\n        /*EJERCICIO #00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO: \n        * EJERCICIO:\n        * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n         *   lenguaje de programación que has seleccionado.\n         * - Representa las diferentes sintaxis que existen de crear comentarios\n         *   en el lenguaje (en una línea, varias...).\n         * - Crea una variable (y una constante si el lenguaje lo soporta).\n         * - Crea variables representando todos los tipos de datos primitivos\n         *   del lenguaje (cadenas de texto, enteros, booleanos...).\n         * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n             */\n        \n             // Sitio web oficial del lenguage: https://www.java.com/es/\n        \n             //Sintaxis de una linea\n        \n             /* Sintaxis\n              * Multilinea\n              */\npublic class Danisaurio94 {\n\n                       \n        \n            public static void Danisaurio94(String[] args) {\n        \n                String variable1 = \"Esta es la primera variable\";\n                final int variable2 = 0; // Esta es la constante\n        \n                byte variablePrimitiva1 = 127; // admite números de -128 a 127\n                short variablePrimitiva2 = 32767; // admite números de -32,768 a 32,767\n                int variablePrimitiva3 = 2147483647; // admite números de -2,147,483,648 a 2,147,483,647\n                long variablePrimitiva4 = 922337206; // admite números de -9,223,372,036,854,775,808 a 9,223,372,036,854,775,807\n                float variablePrimitiva5 = 6;\n                double variablePrimitiva6 = 6;\n                boolean variablePrimitiva7 = true;\n                char variablePrimitiva8 = 'c'; // importante, aqui es comilla simple\n        \n                System.out.println(\"Hola, Java!\");\n        \n        \n        \n        \n        \n            }\n        }\n    \n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Dany3gs.java",
    "content": "/* #00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n\n EJERCICIO:\n * 1 - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * 2 - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * 3 - Crea una variable (y una constante si el lenguaje lo soporta).\n * 4 - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * 5 - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"*/\n\npublic class Dany3gs {\n    public static void main(String[] args) {\n        // 1\n        //  https://www.java.com/es/\n\n        // 2\n        // Esto es un comentario de una línea en Java.\n        /* Esto es un comentario de\n        varias líneas en Java.\n         */\n\n        // 3 por norma general, se usa camelCase\n        int varNum = 0;\n        final int constante = 0;\n\n        // 4\n\n        // Números enteros:\n        // Se pueden crear sin indicar valor, ejemplo ** byte num; **\n        byte numMasPequeno = 0; //1 byte (-128 a 127)\n        short numPequeno = 0; //2 bytes (-32,768 a 32,767)\n        int numeroMasUsado = 0; //4 bytes (-2,147,483,648 a 2,147,483,647)\n        long numMuyGrande = 0; //8 bytes (-9,223,372,036,854,775,808 a 9,223,372,036,854,775,807)\n        // Números reales:\n\n        float numFloat = 0.0f; //4 bytes. números de punto flotante, indicar con f al final\n        double numDouble = 0.0; //8 bytes coma flotantes hasta 15 decimales\n        String texto = \"variable para texto\"; //no primitivo, es un objeto por eso comienza en mayúscula\n        boolean boleano = true;\n        char caracter = 'a'; //con comillas simples\n\n        // 5\n        System.out.println(\"¡Hola, Java!\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/DanyCrk.java",
    "content": "public class DanyCrk {\n  public static void main(String[] args) {\n    // sitio oficial de Java: https://www.java.com/es/ comentario en una linea\n\n    /*\n     * comentario en\n     * varias\n     * lineas\n     */\n    // Crea una variable (y una constante si el lenguaje lo soporta).\n    final int entero = 5; // constante\n    String texto = \"Hola\"; // Variable tipo texto\n\n    // Crea variables representando todos los tipos de datos primitivos\n    byte tipo_1 = 120; // Entero de entre -128 a 127\n    short tipo_2 = 10000; // entero de entre -32768 a 32767\n    int tipo_3 = 2; // Entero (-2**31 a 2**31-1)\n    long tipo_4 = 210000000; // Entero (-2**63 a 2**63-1)\n    float tipo_5 = 215; // numero de coma flotante presicion simple\n    double tipo_6 = 12.2; // numero de coma flotante presicion doble\n\n    char tipo_7 = 'x'; // un solo caracter\n    boolean tipo_8 = false; // dato tipo verdadero o falso\n    String tipo_9 = \"¡Hola, Java!\"; // cadena de caracteres\n\n    // Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\n    System.out.println(tipo_9);\n\n  }\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Danymarsan1.java",
    "content": "/**\n * Solución del reto #00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO;\n * @author Danymarsan1\n */\npublic class Danymarsan1 {\n\n  public static void main(String[] args){\n    //Sitio oficial java: https://www.java.com/es/\n\n    /*\n     * Comentario de\n     * varias líneas\n     */\n\n     /**\n      * Comentario de varias líneas para javadoc\n      */\n\n    int variable = 0;\n    final String CONSTANTE = \"Esto es una constante\";\n\n    boolean esPar = false;\n    int contador = 0;\n    short dato = 0;\n    long datoLargo = 0L;\n    char caracter = 'A';\n    float decimal = 0.0F;\n    double decimalLargos = 0.0;\n\n    System.out.println(\"¡Hola, Java!\");\n  }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Dariel800XD.java",
    "content": "public class Dariel800XD {\r\n    \r\n    public static void main(String[] args) {\r\n        \r\n        //https://www.java.com\r\n\r\n        //esta es una forma de comentar en java\r\n        /*Esta es para varias lineas\r\n        de codigo*/ \r\n\r\n\r\n        //Constante:\r\n        final int constante;\r\n\r\n\r\n        //Variables:\r\n        byte var = 127;\r\n        short var2 = 20000;\r\n        int var3 = 2000;\r\n        long var4 = 400000;\r\n        float var5 = 2;\r\n        double var6 = 3.14;\r\n        boolean var7 = true;\r\n        char var8 = 'D';\r\n        String var9 = \"Hola\";\r\n\r\n        System.out.println(\"Hola, Java\");\r\n\r\n    }\r\n}\r\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Darubiano.java",
    "content": "/*\n    EJERCICIO:\n    1) Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n    2) Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n    3) Crea una variable (y una constante si el lenguaje lo soporta).\n    4) Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n    5) Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n */\n\n// 1) https://docs.oracle.com/en/java/javase/21/index.html\n\n// 2) Comentario de una linea y varias\n\n/*\n    Comentario de varias lineas\n\n */\n\npublic class Darubiano {\n    public static void main(String[] args) {\n\n        // 3) Variable y constante\n        String variable = \"Java\";\n        final String constante = \"Texto constante\";\n\n        // 4) Tipos de variables primitivas\n        // Tipos numericos java\n        byte numeroByte = 10;\n        short numeroShort = 1;\n        int numeroInt = 123;\n        long numeroLong = 123456789L;\n        float numeroFloat = 3.14F;\n        double numeroDouble = 123.123D;\n        // Tipos numericos java Objecto, pueden ser Nulos\n        Byte numeroByteObjeto = 10;\n        Short numeroShortObjeto = 1;\n        Integer numeroIntObjeto = 159;\n        Long numeroLongObjeto = 123456789L;\n        Float numeroFloatObjeto = 3.14F;\n        Double numeroDoubleObjeto = 123.123D;\n\n        // Tipos texto java\n        char textoChar = 'H';\n        String textoString = \"Texto\";\n        // Tipos texto java Objecto, pueden ser Nulos\n        Character textoCharObjeto = 'H';\n        String textoStringObjeto = \"Texto\";\n\n        // Tipo boleano\n        boolean valorVerdadero = true;\n        boolean valorFalso = false;\n        // Tipos boleano java Objecto, pueden ser Nulos\n        Boolean valorVerdaderoObjecto = true;\n        Boolean valorFalsoObjecto = false;\n\n        // Tipos Lista\n        Integer[] listaNumeros = { 1, 2, 3, 4, 5 };\n\n        // 5) print java\n        System.out.println(\"¡Hola, Java!\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Davidr1594.java",
    "content": "public class Davidr1594 {\n    public static void main(String[] args) {\n        int a = 10, b=5;\n        System.out.println(\"------Operadores de aritmeticas--------\");\n\n        System.out.println(\"suma\");\n        System.out.println(a+b);\n\n        System.out.println(\"Resta\");\n        System.out.println(a-b);\n\n        System.out.println(\"Multiplicación\");\n        System.out.println(a * b);\n        \n        System.out.println(\"Division\");\n        System.out.println(a/b);\n\n        System.out.println(\"Operadores de asignacion\");\n        // se utiliza el =\n        //a vale 10 pero le asignaremos el valor de b\n        a = b;\n        //ahora a vale 5\n\n        System.out.println(\"operador de asignacion simple\");\n        \n        System.out.println(\"+=\");\n        a += 5;\n        System.out.println(a);\n\n        System.out.println(\"--------Operadores de Comparacion---------\");\n\n        System.out.println(\"Comparacion: == compara si son iguales\");\n        System.out.println(\"!= Pregunta si es distinto a: \");\n        System.out.println(\"<  > menor y mayor que:\");\n        \n\n        System.out.println(\"---------Operadores Logicos--------\");\n        System.out.println(\"AND o &&\");\n        if(a > b && a> 0){\n            System.out.println(a);\n        }else System.out.println(b);\n\n        System.out.println(\"|| OR\");\n        if((a>b) || a> 0 ){\n            System.out.println(a);\n        }else System.out.println(b);\n\n        System.out.println(\"! NOT\");\n        if (a != b) {\n        System.out.println(a);    \n        } else {System.out.println(b);\n            \n        }\n\n        System.out.println(\"--------Operadores de incremento y decremento--------\");\n\n        System.out.println(\"++ y -- aumenta el valor de 1 en 1 o lo decrementa\");\n\n        System.out.println(\"----------Operador Ternario-------\");\n        System.out.println(\"String mensaje = (edad >= 18) ? \\\"Eres mayor de edad\\\" : \\\"Eres menor de edad\\\"\");\n        int resultado = ((a>b)? a:b);\n\n        /*\n         Operadores de bits\n        Los operadores de bits se utilizan para realizar operaciones a nivel de bits en valores enteros.\n        Estos operadores permiten manipular datos binarios y realizar operaciones de desplazamiento de bits. \n        Ejemplos de operadores de bits incluyen & (AND a nivel de bits), | (OR a nivel de bits), ^ (XOR a nivel de bits), \n        << (desplazamiento a la izquierda) y >> (desplazamiento a la derecha).\n         */\n\n        //Ejercicio Extra\n\n        System.out.println(\"ejercicio Extra\");\n        for (int i = 10; i < 55; i++) {\n            if(i != 16 && (i%3 != 0)){\n                System.out.print(i+\",\");\n            }\n            \n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/DeathbatO.java",
    "content": "// DeathbatO\npublic class Reto{\n\n    public static void main(String[] args) {\n        //En un comentario de linea colocamos el sitio oficial de Java\n        //https://www.java.com/es/\n\n        //Esto es un comentario en una linea\n\n        /*Esto es un comentario de varias lineas\n        usando el asterizco y la barra inclinada*/\n\n        int varInt = 90;\n        String varString = \"Holaaa\";\n        double varDouble = 2.25;\n        boolean varBool = true;\n        String Leng = \"Java\";\n\n        System.out.println(\"Tipos de variables y ejemplos: \");\n        System.out.println(\"Int: \"+varInt+\"\\nString: \"+varString+\"\\nDouble: \"+varDouble+\"\\nBoolean: \"+varBool);\n        System.out.println(\"Hola, \"+Leng);\n\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Derkopath.java",
    "content": "public class Derkopath{\n    public static void  main (String[] args) {\n\n        /*\n        Web oficial:\n        https://www.java.com/es/\n\n        Web de aprendizaje:\n        https://dev.java/learn/\n        */\n\n        // - Comentarios:\n\n        // Comentario en una línea\n\n        /* Comentario en\n            múltiples líneas.\n         */\n\n        // - Declara una variable:\n\n        int variable1 = 0;\n\n        // - Declara una constante\n\n        static final int CONSTANTE = \"constante\";\n\n        // - Tipos de datos primitivos:\n        byte tipo1 = 0;\n        short tipo2 = 0;\n        int tipo3 = 0;\n        long tipo4 = 0L;\n        float tipo5 = 0.0f;\n        double tipo6 = 0.0d;\n        char tipo7 = 'a';\n        String tipo8 = \"Hola mundo!\";\n        boolean tipo9 = true;\n\n        // - Imprimir por terminal:\n\n        System.out.println(\"¡Hola, Java!\");\n    }\n}\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/DevSantiagoO.java",
    "content": "public class DevSantiagoO {\n    public static void main(String[] args) {\n        /*\n         * EJERCICIO:\n         * - Crea un comentario en el sitio oficial del lenguaje.\n         * - Representa las diferentes sintaxis de comentarios (línea, bloque...).\n         * - Crea una variable (y una constante si el lenguaje lo permite).\n         * - Crea variables representando todos los tipos de datos primitivos del lenguaje.\n         * - Imprime por terminal el texto: \"¡Hola, Java!\"\n         */\n        /*\n        COMENTARIOS EN VARIOS LINEAS...\n        Sitio oficial de Java: https://www.java.com/es/\n        */\n        // COMENTARIO EN UNA LINEA\n        int i = 0;\n        char letra = 'b';\n        boolean verdadero = true;\n        double a = 2.40;\n        final double PI = 3.1416;\n        String saludo = \"Holaa mundooooo.\";\n\n        System.out.println(\"¡Hola, Java!\");\n        System.out.println(saludo);\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Devknn.java",
    "content": "/**\n * Devknn\n */\npublic class Devknn {\n\n    public static void main(String[] args) {\n        // https://www.java.com/es/\n\n        /*\n         * Comentario de \n         * varias \n         * lineas\n         */\n      \n        var name = \"java\";\n        //Variable constante\n        final String cadenaTexto = \"Java\";\n        int numeroEntero = 5;\n        boolean booleano = false;\n\n        System.out.println(String.format(\"Hola %s\", cadenaTexto));\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/DiegoIBB.java",
    "content": "package javaExample_;\n\npublic class Sintaxis_Variables_Tipos_00 {\n\tpublic static void main(String args[]) {\n\t\t//https://dev.java/learn/\n\t\t\n\t\t/*Comentario_de_varias_lineas\n\t\t  Se_puede_comentarun_parrafo*/\n\t\t\n\t\t//VARIABLES\n\t\t//Dato_tipo_cadena\n\t\tString cadena = \"Esto es una cadena\";\n\t\t\n\t\t//Dato_tipo_entero\n\t\tint entero = 18;\n\t\t\n\t\t//Dato_tipo_flotante\n\t\tfloat flotante = 23.5f;\n\t\t\n\t\t//Dato_tipo_double\n\t\tdouble decimal = 25.5;\n\t\t\n\t\t//Dato_tipo_caracter\n\t\tchar caracter = 'D';\n\t\t\n\t\t//Dato_tipo_booleano\n\t\tboolean booleano = true;\n\t\t\n\t\t//CONSTANTES\n\t\tfinal String constante = \"Valor de constante\";\n\t\t\n\t\t//IMPRESION_DE_DATOS_POR_CONSOLA\n\t\tSystem.out.println(cadena);\n\t\tSystem.out.println(entero);\n\t\tSystem.out.println(flotante);\n\t\tSystem.out.println(decimal);\n\t\tSystem.out.println(caracter);\n\t\tSystem.out.println(booleano);\n\t\tSystem.out.println(constante);\n\t\t\n\t\t//\n\t\tString lenguaje = \"Java\";\n\t\tSystem.out.println(\"Hola \" + lenguaje +\"!!\");\n\n\t}\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/DiegoPardoMontero.java",
    "content": "public class DiegoPardoMontero {\r\n    public static void main(String[] args) {\r\n        /*\r\n        Comentario con URL de mi lenguaje:\r\n        https://www.java.com/es/\r\n\r\n        Tres Formas de hacer comentarios:\r\n        1. Usando // para comentarios de una sola linea\r\n        2. Usando / * Contenido del comentario * / para comentarios de\r\n        varias lineas\r\n        3. Usando /** * / para comentarios de JavaDoc:\r\n        Compuestos por:\r\n        @author [nombreAutor]\r\n        @param [nombreParametro] [descripcion]\r\n        @return [descripcionDelRetorno]\r\n        @exception o @throws [tipoExcepcion] [razonExcepcion]\r\n        @version [versionSoftware]\r\n        @deprecated [razonObsolescencia]\r\n         */\r\n\r\n        //Variable ejemplo\r\n        String miVariable = \"¡Hola,\";\r\n\r\n        //Constante ejemplo\r\n        final String miConstante = \" Java!\";\r\n\r\n        //Variables con tipos de datos primitivos\r\n        byte miDatoByte = 1;\r\n        short miDatoShort = 2;\r\n        int miDatoEntero = 4;\r\n        long miDatoLong = 8;\r\n        double miDatoDouble = 3.2;\r\n        float miDatoFloat = 4.5f;\r\n        boolean miDatoBooleano = true;\r\n        char miDatoChar = 'A';\r\n\r\n        //Impresión normal:\r\n        System.out.println(miVariable + miConstante);\r\n    }\r\n}\r\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/DjSurgeon.java",
    "content": "/*\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\npublic class Java00 {\n  // Esto es un comentario de una linea.\n  // La web oficial de java es:\n  // https://www.oracle.com/java/\n\n  /*\n  Esto es un comentario de varias lineas, todo lo que se encuentra en su interior\n  no se ejecuta.\n   */\n\n  /**\n   * Esto es un JavaDoc sirve para generar documentacion sobre tu código.\n   */\n\n  public static void main(String[] args) {\n    /*\n    La sintaxis básica de Java para una variable es la siguiente:\n    tipoDeDato nombreDeLaVariable = valor;\n    int edad = 42;\n    Y los tipos de datos primitivos del lenguaje son:\n    - Enteros:\n    byte: Almacena números enteros con un tamaño de 8 bits.\n    short: Almacena números enteros con un tamaño de 16 bits.\n    int: Almacena números enteros con un tamaño de 32 bits, 42.\n    long: Almacena números enteros con un tamaño de  64 bits.\n    - Punto flotante:\n    float: Se utiliza para almacenar números fraccionarios con una única precisión.\n    double: Almacena números con decimales con doble precisión, 3.14.+\n    - Otros tipos:\n    char: Almacena un solo carácter 'a'.\n    boolean: Almacena un valor, true o false.\n     */\n    int edad = 42;\n\n    /*\n    Las constantes son variables cuyo valor no puede ser cambiado después de su inicialización.\n    final tipoDeDato NOMBRE_DE_LA_CONSTANTE = valor;\n    final double PI = 3.14159;\n     */\n\n    // Las strings no son un tipo primitivo, y son conjuntos de char y sirven para almacenar texto.\n    String nombre = \"Sergio\";\n\n    System.out.println(\"Hola, Java!\");\n  }\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/DomingoAndres.java",
    "content": "public class DomingoAndres {\n\n    public static void main(String[] args) {\n        \n        //Sitio web oficial del lenguaje seleccionado: https://www.java.com/es/\n\n        //Comentario de una linea\n\n        /*Comentario\n        de\n        Varias\n        Lineas*/ \n\n        String saludo = \"¡Hola, \"; //Variable\n\n        final String LENGUAJE = \"Java!\"; //Constante\n\n        //variables para los tipos de datos primitivos\n        String cadenaDeTexto = \"Soy una cadena de texto\";\n        int entero = 7;\n        boolean booleano = true;\n        char caracter = 'a';\n        long numeroGrande = 6546546546L;\n        double valorDePi = 3.14;\n        float flotante = 1.58f;\n        \n\n        System.out.println(saludo + LENGUAJE);\n\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/DovinHoyos.java",
    "content": "public class DovinHoyos {\n\n    public static void main(String[] args){\n\n        // https://www.java.com/es\n\n        //Esto es un comentario en linea\n\n        /*\n        este es un comentario\n        en varias lineas \n        */\n\n        var miVariable = \"Hola\";\n        final String MI_CONSTANTE = \"Java!\";\n        \n        //tipos de datos primitivos\n        byte numByte = 127;\n        short numShort = 32767;\n        int numInt = 2147483647;\n        long numLong = 9223372036854775807L;\n\n        double numDouble = 1.7976931348623157E308;\n        float numFloat = 3.4028235E38F;\n\n        char caracter = '@';\n\n        boolean bool = true;\n\n        System.out.println(miVariable+\", \"+MI_CONSTANTE);\n\n\n\n\n        \n\n\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Dredux2.java",
    "content": "/*\r\n * EJERCICIO:\r\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\r\n *   lenguaje de programación que has seleccionado.\r\n * - Representa las diferentes sintaxis que existen de crear comentarios\r\n *   en el lenguaje (en una línea, varias...).\r\n * - Crea una variable (y una constante si el lenguaje lo soporta).\r\n * - Crea variables representando todos los tipos de datos primitivos\r\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\r\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\r\n */\r\npackage org.example;\r\nclass Dredux {\r\n    public static void main(String[] args) {\r\n        // 1)\r\n        // https://dev.java\r\n\r\n        // 2)\r\n        // Comentario de una línea\r\n\r\n        /*\r\n         * Comentario de varias líneas\r\n         */\r\n\r\n        // 3)\r\n        int variable = 1;\r\n        final int constante = 2;\r\n\r\n        // 4)\r\n        String cadena = \"Hola\";\r\n        int entero = 1;\r\n        boolean booleano = true;\r\n        char caracter = 'a';\r\n        float flotante = 1.0f;\r\n        double doble = 1.0;\r\n        byte Byte = 1;\r\n        short corto = 1;\r\n        long largo = 1L;\r\n\r\n        // 5)\r\n        System.out.println(\"¡Hola, Java!\");\r\n    }\r\n}\r\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Durwian.java",
    "content": "/* EJERCICIO1:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n */\n\n\nclass Durwian{\n\n    // URL web sitio oficial: https://www.java.com\n\n    // Comentario de una línea con dos slash\n\n    /*\n     * Comentario en \n     * varias líneas.\n     * Con slash y asterisco.\n     */\n\n    private String variable = \"Hola mundo\";\n    \n    private static final Integer CONSTANTE = 2024;\n\n\n    //Tipos de variables primitivos\n    \n    byte ochoBits;\n    int entero;\n    short enteroPequeno;\n    long enteroGrande;\n    float decimal;\n    double decimalDoble;\n    boolean bolano;\n    char caracter;\n\n    // Tipos estructurados\n\n    String palabra;\n    String[] arreglo;\n    Durwian tipoObjeto;\n\n    public static void main (String [ ] args) {\n        System.out.println(\"¡Hola, Java!\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/EV3THlm.java",
    "content": "package roadmap;\n\npublic class WelcomeToJava {\n\n    // Este es un comentario de una sola linea\n\n    /*\n    *  Este es un comentario multilinea\n    * [LINK DE LA PAGINA OFICIAL DE JAVA --- https://www.oracle.com/java/technologies/downloads/]\n    * [LINK DE LA PAGINA DE LA DOCUMENTACION -- https://docs.oracle.com/en/java/javase/21/docs/api/index.html]\n    *\n    *\n    */\n\n\n    /*\n    * La funcion main es la parte mas importante de un programa en java\n    * ya que todo nuestro codigo debe estar dentro de esta funcion para poder ser ejecutado\n    **/\n    public static void main(String[] args) {\n\n        /* TIPOS DE DATOS\n\n        En java existen los siguientes tipos de datos\n           1: Primitivos\n           2: Object\n        * */\n\n        // 1: DATOS PRIMITIVOS\n\n        // ENTEROS          Tamaño                              Rango min y maximo que soporta\n        byte num; // soporta un tamaño de 8 bits            [-128 | 128]\n        short num2; // soporta un tamaño de 16 bits         [-32768 | 32768]\n        int num3; // soporta 32 bits                        [-9223372036854775808 | 9223372036854775808]\n        long num4; // soporta 64 bits\n\n        // FLOTANTES        Tamaño                              Rango min y maximo que soporta\n        float num5; // soporta 32 bits                      [+- 3.40282347E+38]\n        double num6; // soporta 64 bits                     [+- 1.79769313486231570E+308 ]\n\n        // CARACTER        Tamaño                              Rango min y maximo que soporta\n        char caracter; // soporta 16 bits                   [\\u0000 | \\uFFFF]\n\n        // BOOLEANOS        Tamaño                              Rango min y maximo que soporta\n        boolean booleano; // soporta 1 bit, este tipo de variable solo pueden tener dos valores, true o false\n\n\n\n\n        // 2: DATOS OBJECT\n\n        /*\n        Este tipo es una cadena de caracteres mas sin embargo es importante mencionar\n        que estamos haciendo una instancia de la clase String, por ende a diferencia de las variables\n        primitivas, esta comienza con la primera letra mayuscula.\n        * */\n        String cadena;\n        String cadena2 = new String(); // Basicamente es como si hicieramos esta llamada a la instancia, de forma simplificada\n\n        System.out.println(\"¡Hola!, Java\"); // Esta es la forma de imprimir un mensaje en consola.\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/EnrGarVic.java",
    "content": "public class EnrGarVic {\n    /*\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n */\n\n// comentario\n\n/*comentario largo */\n\n\n\n    //crear variables\n    int numero = 10;\n    final String NOMBRE=\"Kike\";\n\n    /*Crea variables representando todos los tipos de datos primitivos\n     del lenguaje (cadenas de texto, enteros, booleanos...).*/\n     byte numByte = 0;\n     short numShort = 0;\n     long numLong = 0L;\n     float numFloat = 0.0F;\n     String cadena = \"Hola\";\n     int num = 10;\n     double decimal = 10.5;\n     boolean bandera = true;\n     char caracter = 'a';\n\n    /*Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"*/\n\n    public static void main(String[] args) {\n        System.out.println(\"¡Hola, Java!\");\n}\n\n}\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/EspinoLeandroo.java",
    "content": "public class EspinoLeandroo {\n\n    /**\n     * Este es un comentario de documentación.\n     * Se utiliza para generar documentación automáticamente.\n     * @param args Descripción del parámetro args.\n     */\n    public static void main(String[] args) {\n        // https://www.java.com/es/\n        // Esto es un comentario de una línea\n\n        /*\n        * Esto es un comentario\n        * que abarca múltiples líneas.\n        * Puedes escribir varias líneas aquí.\n        */\n\n        final String ejercicio = \"#00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\";\n        String lenguaje = \"java\";\n        \n        byte edad = 27;\n        short distancia = 10000;\n        int cantidad = 1000000;\n        long poblacionMundial = 7800000000L;\n        \n        float altura  = 1.8f;\n        double pi = 3.141592653589793;\n        \n        char letra = 'A';\n\n        boolean esMayorDeEdad = true;\n        \n        System.out.println(\"¡Hoola, Java!\");\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/FedericoLazarte.java",
    "content": "public class FedericoLazarte {\n  public static void main(String[] args) {\n\t\t// Sitio oficial del lenguaje: https://www.java.com/\n\t\t\n\t\t// Comentario de una línea\n\t\t\n\t\t/*\n\t\t * Comentarios de varias líneas.\n\t\t * */\n\t\t\n\t\tfinal int NUMBER = 10; // Constante\n\t\tString language = \"Java\"; // Variable\n\t\t\n\t\t// Primitivos\n\t\tbyte byteNumber = 127;\n\t\tshort shortNumber = 30000;\n\t\tint intNumber = 1000000;\n\t\tlong longNumber = 1152921504606847000l;\n\t\tfloat floatNumber = 33.3f;\n\t\tdouble doubleNumber = 44.55;\n\t\tchar letter = 'a';\n\t\tboolean isTrue = true;\n\t\t\n\t\tSystem.out.println(\"¡Hola, Java!\");\n\t}\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Fluna29.java",
    "content": "public class Fluna29 {\n    public static void main(String[] args) throws Exception {\n        /**\n         * Coloco aqui el link de Java pero no de la página de descarga, sino de la pagina que tiene la documentación de Java\n         * https://docs.oracle.com/en/java/\n         * \n         * Por cierto esto es un comentario en varias lineas\n         */\n\n        //Y a partir de ahora voy a escribir comentarios de una sola linea, al igual que este mismo\n\n        //Esto es una variable\n        var nombre = \"El caballo es de color gris\";\n\n        //Esto es una constante\n        final double PI = 3.1416;\n\n\n        //A continuación voy a escribir los tipos primitivos de variables para numeros\n\n        byte bite = 1;\n        short corto = 2;\n        int entero = 3;\n        long largo = 4;\n        float flotante = 5.5f;\n        double numDecimal = 6.6;\n\n        //El tipo primitivo de texto sería Char, ya que String es un tipo de dato de referencia porque hacen referencia a objetos\n        char caracter = 'a';\n        \n        //El tipo primitivo de booleano es boolean\n        boolean dormido = true;\n\n\n        //Por último vamos a saludar a nuestro lenguaje de programación\n        System.out.println(\"Hola, Java!\");\n\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/FranDev200.java",
    "content": "public class FranDev200 {\n\n    static void main() {\n\n        /*\n        - Crea un comentario en el código y coloca la URL del sitio web oficial del\n        lenguaje de programación que has seleccionado.\n     */\n\n        // https://www.java.com/es/\n\n     /*\n       - Representa las diferentes sintaxis que existen de crear comentarios\n       en el lenguaje (en una línea, varias...).\n     */\n\n        // Comentario en una linea\n\n    /*\n    Comentario en\n    varias\n    lineas\n     */\n\n\n    /*\n        - Crea una variable (y una constante si el lenguaje lo soporta).\n     */\n\n        int variable;\n        final int CONSTANT = 0;\n\n    /*\n        - Crea variables representando todos los tipos de datos primitivos\n        del lenguaje (cadenas de texto, enteros, booleanos...).\n     */\n\n        int entero;\n        double decimal;\n        boolean bool;\n        char caracter;\n        String cadena_caracteres;\n\n\n    /*\n    - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n     */\n\n        System.out.println(\"¡Hola, Java!\");\n\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/FrancoFMV.java",
    "content": "public class FrancoFMV{\n    //sitio oficial de https://dev.java/\n    /*\n     * Este es un comentario\n     * en varias\n     * lineas\n     */\n    /*Este tambien\n     es un comentario\n     en varias lineas\n     */\n    public static void main(String[] args) {\n        String language = \"Java\"; // Variable\n        \n        //Tipo de datos primitivos: byte, short, int, long, float, double, char, boolean\n        int myInt = 1;\n        double myDouble = 1.5;\n        float myFloat = 1.5f;\n        char myChar = 'C';\n        boolean bTrue = true;\n        boolean bFalse = false;\n        byte  myByte = (byte)9;\n        short myShort = (short)27001;\n        long myLong = 8640000000001L;\n\n        final int constant = 6; //Constante\n\n        System.out.println(\"¡Hola \" + language + \"!\");\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/FrankMon03.java",
    "content": "public class FrankMon03 {\n  \n    public static void main(String[] args) {\n      //https://www.java.com/es/\n      \n      /* Sintaxis 1 de comentado */\n      // Sintaxis 2\n      \n      final int numc = 5;\n      int num1 = 900000;\n      long num2 = 9000000;\n      short num3 = 9999;\n      double dec1 = 8.9911111;\n      float dec2 = 1.2f;\n      char carac1 = 'F'; \n      String lang = \"Java\";\n      String texto;\n      boolean opt;\n      opt = false;\n      System.out.println(\"Hola, \"+ lang);\n    }//main\n  }//class \n  "
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/FreedAInew.java",
    "content": "public class FreedAInew {\n    public static void main(String[] args) {\n        System.out.println(\"Hello world!\");\n//create a comment in the code and place the URL of the official website of the programming language you have selected.\n\n        /*These comments are used to add longer explanations or to comment out blocks of code that should not be executed. */\n\n/**\n *Within them, a specific syntax is used to describe elements such as classes, methods, variables.\n *The comments are processed by the javadoc tool to generate HTML documentation of the code.\n */\n\n//Create a variable (and a constant if the language supports it).\n\n        int age = 7; // Integer variable with initial value 7\n        final int PI=314159; // Approximate value of Pi\n\n\n\n\n//Creates variables representing all the language's primitive data types (text strings, integers, booleans...).\n\n                byte weight = 30;\n                short temperature = 46;\n                int ageInYears = 7;\n                long nationalId = 1234567456L;\n                float pi = 3.141592f;\n                double e = 2.718281828459045;\n                boolean isStudent = true;\n                char symbol = '$';\n\n                System.out.println(\"hi java \"+symbol);\n            }\n        }\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Gerthai08.java",
    "content": "//sitio web oficial del lenguaje de programación\n//https://www.oracle.com/latam/java/\n\nimport org.w3c.dom.ls.LSOutput;\n\npublic class Gerthai08 {\n\n    public static void main(String[] args) {\n\n        //Diferentes sintaxis que existen para crear comentarios\n        //Comentarios en linea\n        /*\n         * Comentarios en varias lineas\n         */\n\n        //Crea una variable y una constante\n        //variable\n        int variable = 1;\n\n        //constante\n        final String constante = \"Esto es una constante\";\n\n        //variables primitivas\n        byte aByte = 127;\n        short aShort = 32767;\n        int aInt = 2147483647;\n        long aLong = 9223372036854775807L;\n        float aFloat = 19.1f;\n        double aDouble = 19.1;\n        char aChar = 'a';\n        boolean aBoolean = true;\n\n        //Imprime en la terminal de texto\n        System.out.println(\"¡Hola,java!\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Gipsydavy.java",
    "content": "/**\n * Enlace a pagina oficial de JAVA\n * https://www.java.com/es/\n * Esta es una forma de agregar comentarios\n */\n\n/* Esta es otra forma */\n\npublic class Gipsydavy {\n    public static void main(String[] args) {\n        int edad = 49;\n        final double pi = 3.1416;\n\n        int year = 2026;\n        char vocal = 'a';\n        float temperatura = 35.4F;\n        String coche = \"seat\";\n        boolean hora = true;\n        boolean minuto = false;\n        double radio = 3.456356765;\n        long dinero = 348756723;\n\n\n        System.out.println(\"Hola, este lenguaje es JAVA\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Guillermo-Munoz.java",
    "content": "public class GuillermoMunoz {\n\n    /*\n     * EJERCICIO #00: Guillermo-Munoz\n     * - Sintaxis, variables, tipos de datos y Hola mundo\n     * - Lenguaje: Java\n     */\n\n    public static void main(String[] args) {\n        \n        // 1. URL oficial del lenguaje\n        // https://www.oracle.com/java/\n        \n        // 2. Diferentes tipos de comentarios\n        \n        // Comentario de una línea\n        \n        /* Comentario\n           de varias\n           líneas */\n        \n        /**\n         * Comentario de documentación JavaDoc\n         * Útil para generar documentación automática\n         */\n        \n        // 3. Variables y constantes\n        final int CONSTANTE = 100;  // Las constantes se nombran en MAYÚSCULAS\n        int variable = 12;\n        \n        // 4. Tipos de datos primitivos\n        byte byteVar = 127;\n        short shortVar = 32767;\n        char charVar = 'a';\n        long longVar = 9223372036854775807L;\n        float floatVar = 2.2545445f;\n        double doubleVar = 45.121212454;\n        boolean booleanVar = true;\n        \n        // 5. Tipo referencia (no primitivo pero muy usado)\n        String stringVar = \"Java\";\n        \n        // 6. Imprimir por terminal\n        System.out.println(\"¡Hola, \" + stringVar + \"!\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/GustavoGomez19.java",
    "content": "public class GustavoGomez19 {\n    public static void main(String[] args){\n        //Punto 1: Web oficial de Java: https://www.java.com/es/\n\n        //Punto 2: Este es un comentario de una sola línea\n\n        /*Punto 2: Este es\n        * un comentario\n        * de varias líneas*/\n\n        //Punto 3: Creación de una variable (Tipo cadena de texto)\n        String saludo = \"¡Hola RoadMap 2024\";\n        //Punto 3: Creación de constante (final)\n        final int edad = 31;\n\n        //Punto 4: Creación de variables con todos los tipos de datos primitivos\n        byte numByte = 1;\n        short numShort = 10;\n        int numInt = 100;\n        long numLong = 1000;\n        float numFloat = 10000.0F;\n        double numDouble = 100000.0;\n        char caracter = 'G';\n        boolean boolT = true;\n        boolean boolF = false;\n        String apellido = \"Gomez\";\n\n        System.out.println(\"¡Hola, Java!\");\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Hersac.java",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n//https://www.java.com/es/\n/*Reto de programacion 00 j de Mouredev*/\n\npublic class reto00 {\n    public reto00() {\n\n        var laVariable = \"variable\";\n        final String laConstante = \"constante\";\n\n        String texto = \"Cadena de texto\";\n        int numero = 12;\n        double decimales = 12.2;\n        float flotantes = 1.5f;\n        boolean buleano = true;\n        char caracter = 'c';\n        long largos = 1234567890;\n        short cortos = 12345;\n        byte muyPequeño = 22;\n\n        String java = \"Java\";\n        System.out.println(\"¡Hola \" + java + \"!\");\n    }\n\n    public static void main(String args[]) {\n        reto00 newReto = new reto00();\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/IGuerreroV.java",
    "content": "public class IGuerreroV {\n    //Reto de programacion por MoureDev\n\n    /*\n\n        EJERCICIO:\n        - Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n        - Representa las diferentes sintaxis que existen para crear comentarios en el lenguaje (en una línea, varias...).\n        - Crea una variable (y una constante si el lenguaje lo soporta).\n        - Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n        - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\n    */\n\n    // URL SITIO WEB OFICIAL: https://www.java.com/es/\n\n    public static void main(String[] args) {\n\n        // Variable\n        var miVariable = \"variable\";\n\n        // Constante\n        final String miConstante = \"Constante\";\n\n        // Datos primitivos\n        byte datoPequeño = 8; // Almaneca valores pequeños\n        short datoMasGrandeQueByte = 120; // Almcaena mas datos que byte\n        int miEntero = 2000; // Es el mas comun\n        long miEnteroGrande = 200000; // Es para almacenar enteros mas grandes\n        double miFlotante = 120.5d; // Se usa para almacenar valores flotantes, mas precision\n        float miDecimal = 120.6f; // Se usa para almacenar valores flotantes, menos precision\n        char miChat = 'a'; // Se usa para almacenar caracteres (unicode) con comillas simples\n        boolean miBoolean = true; // Se usa para almacenar valores de verdad (true / false)\n\n        System.out.println(\"¡Hola, Java \");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Ignaciiodev.java",
    "content": "public class Ignaciiodev {\n    public static void main(String[] args) {\n        // #00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n\n        // URL oficial de Java: https://www.java.com/es/\n        \n        /*\n         * Comentario\n         * De\n         * Varias\n         * Lineas\n         */\n        \n        // Declaración de una variable de tipo String\n        String myVar = \"Esto es una Variable\";  // Hay que declara el tipo y luego el nombre\n        \n        // Declaración de una constante de tipo String\n        final String myConst = \"Esto es una Constante\";  // La constante no puede cambiar su valor después de ser inicializada\n\n        // Declaración de variables de tipos primitivos\n        byte myByte = 10;      // Variable de tipo byte, que almacena números enteros pequeños\n        short myShort = 20;    // Variable de tipo short, que almacena números enteros medianos\n        int myInt = 10000;     // Variable de tipo int, que almacena números enteros normales\n        long myLong = 10200;   // Variable de tipo long, que almacena números enteros grandes\n        char myChar = 'a';     // Variable de tipo char, que almacena un solo carácter\n        boolean myBool = false; // Variable de tipo boolean, que almacena un valor verdadero (true) o falso (false)\n\n        // Imprime el mensaje \"¡Hola, Java!\" en la consola\n        System.out.println(\"¡Hola, Java!\");  \n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/IsidroJNG.java",
    "content": "public class IsidroJNG {\n    public static void main(String[] args) {\n\t\t// Para cometarios en una línea\n\t\t\n\t\t/* Para comentarios de\n\t\t * varias líneas.\n\t\t */\n\t\t\n\t\t/**\n\t\t * Para textos largos\n\t\t * como documentación.\n\t\t */\n\t\t\n\t\t// Tipos de datos primitivos enteros\n        byte miByte = 10; // 8 bits\n        short miShort = 5000; // 16 bits\n        int miInt = 1000000000; // 32 bits\n        long miLong = 500000000000000L; // 64 bits\n        long otroLong = 6_000_000_000_000_000l; //64 bits\n        \n        // Números decimales\n \t\tfloat decimalCorto = 234.009f;\n \t\tdouble notacionCientifica = 3.345623E-10;\n \t\t\n \t\t// Booleanas\n\t\tboolean condicion = true; // 1 bit\n\t\t\n\t\t// Carácter\n\t\tchar caracter = 'c'; // 16 bits\n\t\t\n\t\t// Constante\n\t\tfinal float PI = 3.141592f;\n\t\t\n\t\tSystem.out.println(\"Hola, Java!\");\n\t\t\n\t}\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/IsmaelMatiz.java",
    "content": "package org.example;\n\n// Sitio web oficial Java: https://dev.java\n\n//Comentario de una linea\n\n/*\n* Comentario de multiples lineas\n* */\n\n\n/**\n * JavaDoc que permite de cierta forma documentar clases, funciones(metodos para los puristas XD)...\n */\npublic class Main {\n    public static void main(String[] args) {\n        //forma antigua y estandar\n        String name1;\n\n        //forma nueva aunque requiere inicializar al momento de declarar\n        var name2 = \"\";\n\n        //constante\n        final int num1;\n\n        //Variable primitivas\n        char c = 'c';//acepta cualquier caracter Unicode\n        int i = 50;//acepta enteros con signo desde -2.147.483.648 hasta 2.147.483.649\n        short s = -32768;// acepta enteros con signo desde -32.768 hasta 32.767\n        long l = -9223372036854775808L;// acepta enteros con signo desde -9.223.372.036.854.775.808 hasta 9.223.372.038.854.775.807\n        float f = 7.233433f;// acepta hasta 6 decimales\n        double d = 3.14159;// acepta hasta 14 decimales\n        boolean b = true;//True or false\n        byte byte1 = -128;// acepta enteros con signo desde -128 hasta 127\n\n        System.out.println(\"¡Hola, Java!\");\n\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Ismx17.java",
    "content": "public class Ismx17 {\n public static void main(String[] args) {\n    \n    // https://www.java.com/es/\n\n    // Comentario en una linea\n\n    /* Comentario\n    de varias\n    lineas */\n\n    String constante = \"Esto es una constante\";\n\n    int variable = 1; // Esto es una variable\n\n    byte my_byte = 1; // Esto es una variable de tipo byte\n    short my_short = 1; // Esto es una variable de tipo short\n    int my_int = 1; // Esto es una variable de tipo int\n    Long my_long = 1L; //Esto es una variable de tipo Long\n    float my_float = 1.0f; // Esto es una variable de tpo float\n    double my_double = 1.0; // Esto es una varable de tpo double\n    char my_char = 'a'; // Esto es una variable de tipo char\n    boolean my_boolean = true; // Esto es una variable de tipo boolean\n\n    String lenguaje = \"Java\";\n    System.out.println(\"¡Hola, \" + lenguaje + \"!\");\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/IvanSerran.java",
    "content": "public class IvanSerran {\n    \n        /*\n         * 1- Crea un comentario en el código y coloca la URL del sitio web oficial del\n         * lenguaje de programación que has seleccionado.\n         */\n        // https://www.java.com/en/\n\n        ////////////////////////////////////////////////////////////////////////\n        /*\n         * 2- Representa las diferentes sintaxis que existen de crear comentarios\n         * en el lenguaje (en una línea, varias...).\n         */\n        // Comentario de una línea\n        /*\n         * Comentario de\n         * múltiples líneas\n         */\n\n        ////////////////////////////////////////////////////////////////////////\n        // 3- Crea una variable (y una constante si el lenguaje lo soporta).\n        String texto = \"Esto es un texto\";\n        static final int IVA = 21;\n\n        public static void main(String[] args) {\n        ////////////////////////////////////////////////////////////////////////\n        /*\n         * 4- Crea variables representando todos los tipos de datos primitivos\n         * del lenguaje (cadenas de texto, enteros, booleanos...).\n         */\n        String frase = \"Escribiendo un texto entre comillas\";\n        int numeroEntero = 10;\n        float numeroFlotante = 3.5f;\n        boolean apagado = true;\n        char caracter = 'g';\n\n        ////////////////////////////////////////////////////////////////////////\n        // 5- Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n        System.out.println(\"¡Hola, Java!\");\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/JaquelineTorres.java",
    "content": "/**\n * Este es un programa de ejemplo en Java que cubre varios aspectos básicos del lenguaje.\n * Puedes encontrar más información sobre Java en el sitio web oficial:\n * https://www.oracle.com/java/\n */\n\npublic class JaquelineTorres {\n    public static void main(String[] args) {\n        // Comentarios de una línea\n\n        /*\n         * Comentarios\n         * de varias\n         * líneas o bloque\n         */\n\n        // Declaración de una variable\n        char variableA = 'a';\n\n        // Declaración de una constante usando la palabra clave 'final'\n        final double PI = 3.1416;\n\n        System.out.println(\"variableA: \" + variableA);\n        System.out.println(\"PI: \" + PI);\n\n        // Variables representando todos los tipos de datos primitivos del lenguaje\n\n        // Numéricos enteros\n        byte primitivoByte = 123;\n        short primitivoShort = 456;\n        int primitivoInt = 14;\n        long primitivoLong = 45435345;\n\n        System.out.println(\"byte: \" + primitivoByte + \", short: \" + primitivoShort + \", int: \" + primitivoInt + \", long: \" + primitivoLong);\n\n        // Numéricos en punto flotante\n        float primitivoFloat = 1.122F;\n        double primitivoDouble = 122.21212121D;\n\n        System.out.println(\"float: \" + primitivoFloat + \", double: \" + primitivoDouble);\n\n        // Caracteres\n        char primitivoChar = 'g';\n        System.out.println(\"char: \" + primitivoChar);\n\n        // Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n        System.out.println(\"¡Hola, Java!\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/JavierIncio.java",
    "content": "/**\n * # 00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n *\n * @author JavierIncio\n * @version 1.0\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n *\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n*/\n\npublic class JavierIncio {\n    public static void main(String[] args) {\n        // Sitio web oficial Java: https://www.oracle.com/java/\n\n        // Comentario de una línea\n\n        /*\n        Comentario\n        en\n        bloque\n         */\n\n        /**\n         * Comentario de\n         * documentación\n         */\n\n        final String CONSTANTE = \"Valor fijo\";\n        String variable = \"Valor fijo\";\n\n        byte varByte = 127;\n        short varShort = 32767;\n        int varInt = 2147483647;\n        long varLong = 9223372036854775807L;\n        float varFloat = 23.67F;\n        double varDouble = 145678.9785754D;\n        char varChar = 'a';\n        boolean varBoolean = true;\n        // Las cadenas de texto no son un tipo de dato primitivo en Java\n        String texto = \"¡Hola, Java!\";\n\n        System.out.println(texto);\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/JaviiR.java",
    "content": "\npublic class Javi {\n    public static void main(String[] args) {\n        // ----------------------------Sitio oficial Java------------------------------\n        /*\n         * \"https://www.java.com/es/\"\n         */\n\n        // ------------------sintaxis existentes para comentarios----------------------\n        // Comentario en una linea\n        /*\n         * comentario en\n         * varias líneas\n         */\n\n        // -------------------------variable y constante-------------------------------\n        // Variable\n        System.out.println(\"-Variable:\");\n        Object variable;\n        variable = 10;\n        System.out.println(variable);\n        variable = \"diez\";\n        System.out.println(variable);\n\n        // Constante\n        System.out.println(\"-Constante:\");\n        final Object constante = \"valor inmutable\";\n        System.out.println(constante);\n\n        // -----------------------------datos primitivos--------------------------------\n        boolean verdadero = true, falso = false;\n        char caracter = 97;\n        byte Bminimo = -128, Bmaximo = 127;\n        short Sminimo = -32768, Smaximo = 32767;\n        int Iminimo = -2147483648, Imaximo = 2147483647;\n        long Lminimo = -9223372036854775808L, Lmaximo = 9223372036854775807L;\n        float Fminimo = -Float.MAX_VALUE, Fmaximo = Float.MAX_VALUE;\n        double Dminimo = Double.MIN_VALUE, Dmaximo = Double.MAX_VALUE;\n        System.out.println(\"¡Hola, Java!\");\n        System.out.println(Fminimo);\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/JcKnot.java",
    "content": "package Retos;\n\n// Sitio oficial https://www.java.com/\n\n// Comentario en linea\n\n/*\n    Comentario para\n    varias lineas\n    @autor: JcKnot\n*/\n\n        \npublic class JcKnot {\n    public static void main(String[] args) {\n        // variable\n        String variable = \"variable\";\n        \n        // constante\n        final String constante = \"constante\";\n        \n        // tipos de datos primitivos\n        byte tipoByte = 20;\n        short tipoShort = 100;\n        int tipoInt = 1000;\n        long tipoLong = 10000;\n        float tipoFloat = 3.14f;\n        double tipoDouble = 3.14;\n        boolean tipoBoolean = true;\n        char caracter = 'a';\n        String jv = \"Java\";\n        \n        System.out.println(\"¡Hola, \" + jv + \"!\");\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/JehiselRuth.java",
    "content": "//Sitio oficial del lenguaje de Java url: https://www.java.com/es/\n\n/*En Java puedes comentar utilizando / y asterisco * cerrando finalmente con el asterisco y la barra, nuevamente */\n//También puedes usar doble barra si lo que quieres comentar se encuentra en una misma línea\n\n\npublic class JehiselRuth {\n    \n    //Variable \n    int variableNumber = 9;\n    //Constante\n    final int MY_AGE = 38;\n\n    //Tipos de datos primitivos\n    int fingers = 5;\n    float weight = 53.4f;\n    double average = 4.95;\n    char character = 'J';\n    boolean isComplete = true;\n    String myLanguage = \"Jehisel\";\n    \n    public static void main(String[] args) {\n        String myLanguage = \"Java\";\n        System.out.println(\"¡Hola, \"+ myLanguage + \"!\");\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Jeigar2.java",
    "content": "public class Jeigar2 {\n    // Crea un comentario en el código y coloca la URL del sitio web oficial del\n    // lenguaje de programación que has seleccionado.\n    // https://docs.oracle.com/en/java/javase/21/\n\n    /*\n     * Representa las diferentes sintaxis que existen de crear comentarios\n     * en el lenguaje (en una línea, varias...).\n     */\n\n    // The byte data type is an 8-bit signed two's complement integer.\n    // It has a minimum value of -128 and a maximum value of 127 (inclusive).\n    byte aByte;\n\n    // The short data type is a 16-bit signed two's complement integer.\n    // It has a minimum value of -32,768 and a maximum value of 32,767 (inclusive).\n    short aShort;\n\n    // By default, the int data type is a 32-bit signed two's complement integer,\n    // which has a minimum value of -231 and a maximum value of 231-1.\n    // In Java SE 8 and later, you can use the int data type to represent an unsigned 32-bit integer,\n    // which has a minimum value of 0 and a maximum value of 232-1.\n    int anInt;\n\n    // The long data type is a 64-bit two's complement integer.\n    // The signed long has a minimum value of -263 and a maximum value of 263-1.\n    // In Java SE 8 and later, you can use the long data type to represent an unsigned 64-bit long,\n    // which has a minimum value of 0 and a maximum value of 264-1.\n    long aLong;\n\n    // The float data type is a single-precision 32-bit IEEE 754 floating point.\n    // Its range of values is beyond the scope of this discussion, but is specified in the Floating-Point Types,\n    // Formats, and Values section of the Java Language Specification.\n    float aFloat;\n\n    // The double data type is a double-precision 64-bit IEEE 754 floating point.\n    // Its range of values is beyond the scope of this discussion, but is specified in the Floating-Point Types,\n    // Formats, and Values section of the Java Language Specification.\n    double aDouble;\n\n    // The boolean data type has only two possible values: true and false.\n    // Use this data type for simple flags that track true/false conditions.\n    // This data type represents one bit of information, but its \"size\" isn't something that's precisely defined.\n    boolean aBoolean;\n\n    // he char data type is a single 16-bit Unicode character.\n    // It has a minimum value of '\\u0000' (or 0) and a maximum value of '\\uffff' (or 65,535 inclusive).\n    char aChar;\n\n    // Constant\n    public static final String LANGUAGE = \"Java\";\n\n    public static void main(String[] args) {\n        System.out.println(\"¡Hola, \" + LANGUAGE + \"!\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/JerrySantana.java",
    "content": "public class JerrySantana {\n    public static void main(String[] args) {\n        // Esta es la página oficial del lenguaje, en español -> https://www.java.com/es/\n        // En este link encontramos tutoriales para empezar en el lenguaje -> https://dev.java/learn/getting-started/\n\n        // Sintaxis de comentraios\n\n        // Esta forma de comentar, utilizando dos diagonales, nos sirve para realizar comentarios en una sola línea o al final de una línea.\n        /* Para comentar código en una misma línea utilizamos esta notación. */\n        /*\n        Para realizar comentarios multilínea utilizamos,\n        de igual manera, este formato.\n        */\n        /**\n         * También están los comentarios de documentación, los cuales se utilizan para describir los\n         * elementos de nuestro programa como clases, interfaces, constructores, etc... Estos comentarios\n         * pueden o no ir acompañados de etiquetas que simplifican la explicación y los usos del programa.\n         * Para más información sobre estos comentario, visita este link: https://www.oracle.com/technical-resources/articles/java/javadoc-tool.html\n         *\n         * A partir de estos comentarios algunos IDE's crean el lllamado Javadoc, el cual es la documentación\n         * del funcionamientos y usos sobre todo el código de un programa.\n         */\n\n        // Declaración de variables y constantes.\n        int variable = 0;   // Esto es una variable de tipo entero.\n        final int constant = 1;    // Esto es una constante de tipo entero.\n\n        // Tipos de datos primitivos\n        byte mimimumSize = 125; // Para representar valores en un rango de -128 hasta 127 y no ocupar tanta memoria. Tamaño de 8 bit.\n        short smallSize =  32700; // Para representar valores en un rango de -32768 hasta 32767 y no ocupar mucha memoria. Tamaño de 16 bit.\n        int normalSize = 2003947423; // Para representar valores en un rango de -2^31 hasta 2^31 menos 1. Tamaño de 32 bit.\n        long bigSize = 29832829; // Para representar valores en un rango de -2^63 hasta 2^63 menos 1. Tamaño de 64 bit.\n        float regularSize = 123.5f; // Para representar valores decimales sin ocupar mucha memoria. Tamaño de 32 bit. No recomendado para valores precisos.\n        double aBigSize = 123.5; // Para representar valores decimanles ocupando más memoria. Tamaño de 64 bit. No recomendado para valores precisos.\n        boolean logicValue = true; // Para representar los valores lógicos verdadero y falso (true, false). Representa un bit de información.\n        char character = 'a'; // Para representar un caracter unicode de 16 bit.\n\n        System.out.println(\"¡Hola, Java!\");\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/JesusAntonioEEscamilla.java",
    "content": "/** #00 - Java -> Jesus Antonio Escamilla */\n\n//Estas son las paginas oficiales de Java => https://www.java.com/es/ y https://www.oracle.com/java/\n\n// Esta es una linea\n\n/*\n * Este es un comentario de multiples líneas.\n * Y se puede agregar mas\n * o las que necesites\n */\n\n\npublic class JesusAntonioEEscamilla {\n    public static void main(String[] args) {\n\n        // Declaración de una constaten\n        final String mi_Const = \"Soy una constante\";\n\n        //BYTE\n        byte byteVariable = 127;\n\n        //SHORT\n        short shortVariable = 32767;\n\n        //INT\n        int intVariable = 247483647;\n\n        //LONG\n        long longVariable = 9223372036854775807L;\n\n        //FLOAT\n        float floatVariable = 3.14F;\n\n        //DOUBLE\n        double doubleVariable = 3.141592653589793;\n\n        //CHART\n        char charVariable = 'A';\n\n        //BOOLEAN (true / false)\n        boolean booleanVariable = true;\n\n        //STRING\n        String stringVariable = \"¡¡Hola Mundo!!\";\n\n        // Imprimiendo la Constante\n        System.out.println(\"Soy una constante \" + mi_Const);\n\n        // Imprimiendo los datos Primitivos\n        System.out.println(\"byte: \" + byteVariable);\n        System.out.println(\"short: \" + shortVariable);\n        System.out.println(\"int: \" + intVariable);\n        System.out.println(\"long: \" + longVariable);\n        System.out.println(\"float: \" + floatVariable);\n        System.out.println(\"double: \" + doubleVariable);\n        System.out.println(\"char: \" + charVariable);\n        System.out.println(\"boolean: \" + booleanVariable);\n        System.out.println(\"string: \" + stringVariable);\n\n        //Imprimiendo en terminal\n        System.out.println(\"¡Hola, Java!\");\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/JesusEs1312.java",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n// Java API: https://docs.oracle.com/javase/8/docs/api/\n// Java Paginal Oficial: https://www.java.com/es/\n\n// Este es un comentario de una linea\n\n/*\n    Este es un comentario de \n    más de una linea\n\n    - Comentario 1\n\n    - Comentario 2\n\n    - Comentario 3\n */\n\nclass JesusEs1312 {\n    //--- Variables\n    // String\n    String var1 = \"Hola\";\n    String var2 = \"Mundo\";\n    // Integer\n    Integer var7 = 150;\n\n    //--- Tipos de Datos Primitivos\n    // double\n    double var3 = 10.02;\n    double var4 = 20.04;\n    // float\n    float var8 = 1.0f;\n    // char\n    char var9 = 'J';\n    // byte\n    byte var10 = 0001;\n    byte var11 = 0101;\n    // boolean\n    boolean var12 = true;\n    boolean var13 = false; \n    // short\n    short var15 = 9;\n    // lang\n    long var14 = 875L; \n    // int\n    int var5 = 50000;\n    int var6 = 9000000;\n    \n    //--- Constante\n    final static double PI = 3.1416;\n    public static void main(String []args) {\n        //--- Imprimir en consola\n        System.out.println(\"Hola Mundo\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/JimsimroDev.java",
    "content": "public class JimsimroDev {\n  public static void main(String[] args) {\n    // Sitio oficial de java licencia paga\n    // https://www.oracle.com/java/technologies/downloads/\n\n    /*\n     * Licencia gratis es el openjdk\n     * https://jdk.java.net/\n     */\n\n    // Tipos de datos primitivos son\n    // boolean, byte, char, short, int, long, float, double\n    int numero = 25;\n    String nombre = \"Jimmis J Simnaca\";\n    final long edad = 29; // constante en java\n    short fecha = 2024;\n    char letra = 'c';\n    float num = 23;\n    double decimal = 2.3;\n    boolean esEstudiandte = true;\n    String lenguaje = \"[Java]\";\n\n    // Precedencia de operadores\n    int precedencia = ((5 * 8) + 4) * 2; // el resultado es 88 primero se opera las multiplicacion dentro de los () y\n                                         // luego las sumas\n    System.out.printf(\"resultado %d \", precedencia);\n    System.out.println(\"\\n¡Hola, \" + lenguaje);\n  }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Jony_English22.java",
    "content": "public class Jony_English22 {\r\n\r\n    public static void main(String[] args) {\r\n\r\n        //https://docs.oracle.com/en/java\r\n\r\n        //Este es un comentario de una linea\r\n\r\n        /*\r\n        Este es un comentario\r\n        de varia lineas\r\n         */\r\n\r\n        //Constante\r\n        final String my_constant = \"#00- SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA  MUNDO\";\r\n\r\n        String my_variable = \"Variable de tipo string\"; //Variable\r\n\r\n        //Tipos de datos\r\n        byte my_byte = 127;\r\n        short my_short = 32727;\r\n        int my_int = 22;\r\n        long my_long = 1000000000;\r\n        float my_float = 12.12f;\r\n        double my_double = 56.978;\r\n        String my_String = \"Esta es una cadena de texto\";\r\n        char my_char = 'a';\r\n        boolean my_boolean = true;\r\n        boolean my_boolean2 = false;\r\n\r\n        System.out.println(\"¡Hola Java!\");\r\n        System.out.println(\"Este fue el ejercicio: \" + my_constant);\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/JoseEsmil04.java",
    "content": "public class JoseEsmil04 {\n    public static void main(String[] args) {\n        // Sitio Oficial del Lenguaje\n        // https://www.java.com\n\n        // Este es un comentario de una linea.\n\n        /*\n         * Este es un Comentario\n         * De Varias lineas!\n         */\n\n        // Variable\n        String variable = \"¡Hola,\";\n\n        // Constante\n        final String constante = \"Java!\";\n\n        // Tipos primitivos\n        String myCadena = \"String by Esmil\";\n        char myChar = 'E';\n        int myNumero = 44;\n        byte myByte = 4;\n        double myDouble = 105.44;\n        float myFloat = 33492.221f;\n        long myLong = 987654321;\n        boolean myBoolean = true;\n\n        // Salida por consola\n        System.out.println(variable + \" \" + constante);\n\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Josegs95.java",
    "content": "public class Josegs95 {\n    // Sitio web oficial Java: https://java.com/es\n\n    // Doble barra para un comentario en una línea\n\n    /* Barra asterisco para empezar un comentario en varias líneas\n       ... Aquí vendría la segunda línea del comentario ...\n       Para finalizar el comentario, hay que usar asterisco barra.\n    */\n\n\n    public static void main(String[] args) {\n\n        //Creo una variable con un valor\n        int miVariable = 8;\n        //Cambio el valor de la variable\n        miVariable = 12;\n\n        //Creo una constante\n        final double NUM_PI = 3.14;\n        //No se puede cambiar el valor de una variable final\n        //El código no compilaría\n        //NUM_PI = 3.1415;\n\n        //Tipos primitivos\n        byte miByte= 8;\n        short miShort = 16;\n        int miInt = 32;\n        long miLong = 64;\n        float miFloat = 32.0f; //Hay que especificar que es un float poniéndole la \"f\" al final\n        double miDouble = 64.0;\n\n        boolean miBoolean = true; //Solo admite dos valores, true o false.\n\n        char miChar = 'a'; //Hay que usar comillas simples, las comillas dobles son para cadenas\n\n        //El tipo String, que sirve para representar cadenas, no es un tipo primitivo en java\n        //Aún así, por ser un tipo especial (no hay que usar new para crear un objeto String)\n        //Pongo un ejemplo de como sería\n        String miString = \"Cadena\";\n\n        //Imprimir por consola usando el método println()\n        System.out.println (\"¡Hola, java!\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/JosueSaGa14.java",
    "content": "public class JosueSaGa14 {\n\n    public static void main(String[] args) {\n\n        // Url del sitio oficial de Java\n        //  https://www.java.com/es/\n        /// Comentarios\n\n        /*\n        *Este\n        * es\n        * un\n        * comentario\n        * de\n        * varias\n        * lineas\n        */\n        final String CONSTANTE = \"Variable constante\";\n        String nombre = \"Esto es una variable de cadena\";\n        int numero = 1;\n        float numero1 = 10.35f;\n        double numero2 = 15.1;\n        short numero3 = 25;\n        boolean isTrue = true;\n        char caracter = 'F';\n        byte valorByte = 64;\n\n        System.out.println(\"Hola, Java!\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Juan-Wills.java",
    "content": "//Official website: https://www.oracle.com/co/java\n\n//One line commentary\n\n/*\n *Multi-line commentary\n */\n\npublic class JuanWills_00 {\n    public static void main(String[] args){\n\n        //Variable \n        int var;\n        //Constant\n        final int cons;\n\n        //Primitive types\n        byte Byte;\n        short Short;\n        int Integer;\n        long Long;\n        boolean Boolean;\n        char Char;\n        String string; //Not a primitive type but an object\n\n        //Printing\n        System.out.println(\"Hola Java!\");\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/JuanGuzmanG.java",
    "content": "public class JuanGuzmanG {\n\n    public static void main(String args[]) {\n        //https://docs.oracle.com/en/java/index.html\n        \n        //tipos de comentarios\n        //una sola linea\n        /*\n        comentario de \n        varias lineas\n        */\n        /**\n        comentario de Javadoc\n        */\n        \n        //variable y constante\n        int valor = 0;\n        final int constante = 100;\n        \n        //primitivos\n        boolean resultado = true;\n        char letra = 'C';\n        byte b = 100;\n        short s = 10000;\n        int i = 1000000000;\n \n        System.out.println(\"¡Hola, Java\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Julian98789.java",
    "content": "package MauroDevRetos;\n\n//https://www.oracle.com/java/\n\n/*\n * https://www.oracle.com/java/\n */\n\n/**\n * https://www.oracle.com/java/\n */\npublic class julian98789 {\n\n    int numero;\n    final int numeros = 4;\n\n    byte unByte = 127; // Rango: -128 a 127\n    short unShort = 32767; // Rango: -32,768 a 32,767\n    int unInt = 2147483647; // Rango: -2^31 a 2^31-1\n    long unLong = 9223372036854775807l; // Rango: -2^63 a 2^63-1\n\n    // Punto flotante\n    float unFloat = 3.14f; // Precisión simple\n    double unDouble = 3.141592653589793; // Precisión doble\n\n    // Carácter\n    char unChar = 'A'; // Almacena un solo carácter Unicode\n\n    // Booleano\n    boolean unBoolean = true; // Puede ser true o false\n\n    public static void main(String[] args) {\n        System.out.println(\"Hola, Java\");\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/JulianJRA.java",
    "content": "\n//Url de Java oficial: https://www.java.com/es/\n\n//Comentario en linea\n\n/*\n * Comentario en\n * varias lineas\n */\n\npublic class JulianJRA {\n\n    public static void main(String[] args) {\n\n        //Variable en java\n        String miVariable = \"mi variable\";\n\n        //Constante en java\n        final String MI_CONSTANTE = \"mi constante\";\n\n        // Tipos de datos primitivos en java\n        byte b = 127;\n        short s = 32000;\n        int i = 100000;\n        long l = 10000000000L;\n\n        float f = 3.14f;\n        double d = 3.14159265359;\n\n        char c = 'A';\n        String st = \"Hola\";\n        boolean bool = true;\n\n        //Imprimir por terminal\n        System.out.println(\"¡Hola, Java!\");\n\n    }\n\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Karolle.java",
    "content": "public class Karolle {\n    public static void main(String[] args) {\n        // Java official website: https://www.java.com/\n\n        // This is a single-line comment\n\n        /* This is a \n        comment that \n        spans multiple\n        lines */\n\n        // Declaration of a variable\n        String myVariable = \"Hola\";\n\n        // Declaration of a constant\n        final String myLanguage = \"Java\";\n\n        // Variables representing primitive data types\n        byte myByte = -128;\n        short myShort = 32767;\n        int myNum = 5;               \n        long myLongnum = 922337203685477807L;\n        float myFloatNum = 5.99f;    \n        char myLetter = 'K';         \n        double myDoubleNum = 3.1415926535;\n        boolean myBool = true;            \n\n        System.out.println(\"¡\" + myVariable + \", \" + myLanguage + \"!\");\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/KennWudi.java",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\npublic class KennWudi {\n    public static void main(String[] args) {\n        /*\n         * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n         * lenguaje de programación que has seleccionado.\n         */\n\n        // https://docs.oracle.com/en/java/\n\n        /*\n         * - Representa las diferentes sintaxis que existen de crear comentarios\n         * en el lenguaje (en una línea, varias...).\n         */\n\n        // Comentario en una línea\n\n        /*\n         * Comentario\n         * en\n         * varias\n         * líneas\n         */\n        // - Crea una variable (y una constante si el lenguaje lo soporta).\n        String myString1 = \"myString\";\n        final String MY_CONSTANT = \"MY_CONSTANT\";\n\n        /*\n         * - Crea variables representando todos los tipos de datos primitivos\n         * del lenguaje (cadenas de texto, enteros, booleanos...).\n         */\n        int myInt = 1;\n        double myDouble = 2.2;\n        float myFloat = 2.2f;\n        String myString = \"myString\";\n        char myChar = 'K';\n        Boolean myBoolean = true;\n\n        // - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n        System.out.println(\"Hola, Java\");\n\n        // * Uso de variables\n        System.out.println(myString1);\n        System.out.println(MY_CONSTANT);\n        System.out.println(myInt);\n        System.out.println(myDouble);\n        System.out.println(myFloat);\n        System.out.println(myString);\n        System.out.println(myChar);\n        System.out.println(myBoolean);\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/KingSaul22.java",
    "content": "// https://developer.oracle.com/languages/java.html\n//  https://dev.java/\n\n\npublic class KingSaul22 {\n\n    public static void main(String[] args) {\n\n        //COMENTARIOS:\n\n        //Este es un comentario de una sola linea.\n\n        /*\n        Este comentario\n        incluye distintas\n        lineas.\n         */\n\n        /**\n         * Este comentario es usado para Javadoc.\n         */\n\n\n        //VARIABLE/CONSTANTE:\n\n        //Escribimos el tipo de variable, seguido del nombre que le daremos.\n        int variable;\n        //A lo hora de crear constantes, colocamos la palabra 'final' antes del tipo de la variable.\n        final int CONSTANTE = 0;\n\n\n        //VARIABLES PRIMITIVAS:\n\n        //Las variables char almacenan un caracter.\n        char letter = 'S';\n        //Variable de tipo boolean, indican Si o No; siempre se inicializan con el valor 'false'.\n        boolean isValid = true;\n        \n        /*\n        Las siguientes variables almacenarán numeros enteros,\n        cada una tiene una capacidad medida en bits.\n\n        Cabe destacar que las variables de tipo 'long' se les da el valor acabado en una 'L'.\n         */\n        byte bits8 = 8;\n        short bits16 = 16;\n        int bits32 = 32;\n        long bits64 = 64L;\n\n        //Para variables de números con decimales usamos los siguientes tipos,\n        //donde uno almacena 64 bits y otro 32, el cual se declara acabado en 'F'.\n        float decimal32 = 3.2F;\n        double decimal64 = 6.4;\n\n\n        //IMPRESION POR CONSOLA:\n\n        System.out.println(\"¡Hola, Java!\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Kronstadt-Lambda.java",
    "content": "// https://docs.oracle.com/en/java/javase/21/\n\n/**\n * This is a javadoc comment\n * @author Kronstadtlambda\n * @version 1.0\n */\n\n// here define the package name\n// package roadmap.java.r00;\n\n// here import the necessary library (optional)\nimport java.util.Random;\n\n/**\n * Class to show the basic sintax and others of Java programming language\n */\npublic class KronstadtLambda {\n    /**\n     * Main method to execute the code of this class (entry point)\n     */\n    public static void main(String[] args) {\n\n        // Sintax to create comments:\n        // This is a single line comment\n        /* This is a multi-line comment \n         * or more lines \n         */\n\n        // Sintax to manage puntuation:\n        // ; -> end of the statement.\n        // {} -> delimit block of code.\n        // () -> parameters, conditions, group expressions.\n        // [] -> declare arrays, [index] access to elements.\n        // . -> access to methods, attributes, etc.\n        // @ -> annotations.\n        // :: -> method reference (functional programming).\n\n        // Variables and constants\n        float variable_high; \n        final float CONSTANT_COULUMB;\n        variable_high = 1.7f;   //meters\n        CONSTANT_COULUMB = 8.9875517873681764e9f; // N m^2 C^-2\n\n        // Primitive data types\n        byte v_byte; // Integer 8 bits\n        short v_short; // Integer 16 bits\n        int v_int; // Integer 32 bits\n        long v_long; // Integer 64 bits\n        float v_float; // Floating point 32 bits\n        double v_double; // Floating point 64 bits\n        char v_char; // Unicode character 16 bits\n        boolean v_boolean; // Logical 8 bits\n\n        v_byte = 127;\n        v_short = 32767;\n        v_int = 2147483647;\n        v_long = 9223372036854775807L;\n        v_float = 3.4028235e38f;\n        v_double = 1.7976931348623157e308;\n        v_char = 'K';\n        v_boolean = true;\n\n        System.out.println(\"A byte: \" + v_byte);\n        System.out.println(\"A short: \" + v_short);\n        System.out.println(\"An int: \" + v_int);\n        System.out.println(\"A long: \" + v_long);\n        System.out.println(\"A float: \" + v_float);\n        System.out.println(\"A double: \" + v_double);\n        System.out.println(\"A char: \" + v_char);\n        System.out.println(\"A boolean: \" + v_boolean);\n\n        // Print a greeting\n        String v_language = \"Java\";\n        System.out.println(\"Hello, \" + v_language + \"!\");\n\n        // Style guide\n        /* \n         * Nomenclature:\n         * Use PascalCase for class names and interface names.\n         * Use camelCase for method and variables names.\n         * UPPER_CASE for constants.\n         * \n         * Comentary:\n         * Use comentary to explain the code, not what the code does.\n         * \n         * Code organization:\n         * Use a maximum of 80 characters per line.\n         * Use 4 spaces to indent code and avoid using tabs.\n         * \n         * Declaration:\n         * Group the declarations of variables at the beginning of the class.\n         */\n        \n    } // end of the main method\n} // end of the class\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Ldre3.java",
    "content": "public class Ldre3 {\n    // Creacion de constantes y variables\n\n    private int variable = 5;\n    private final char CONSTANTE = 'A';\n    public static void main(String[] args) {\n        // https://www.java.com/es/\n\n        // Comentario de una linea\n\n        /*\n        Comentario de\n        Varias lineas\n         */\n\n        /**\n         * Comentario en javadoc\n         */\n\n        byte mibyte = 5;\n        boolean booleano = true;\n        short numero = 4;\n        long largo = 486498468;\n        int entero = 5;\n        char letra = 'a';\n        double decimal = 5.5;\n        float flotante = 5.6F;\n\n        System.out.println(\"¡Hola, Java!\");\n\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/LewisOneil.java",
    "content": "/*\n * EJERCICIO:\n * 1) Crea un comentario en el código y coloca la URL del sitio web oficial del\n *      lenguaje de programación que has seleccionado.\n * 2) Representa las diferentes sintaxis que existen de crear comentarios\n *      en el lenguaje (en una línea, varias...).\n * 3) Crea una variable (y una constante si el lenguaje lo soporta).\n * 4) Crea variables representando todos los tipos de datos primitivos\n *      del lenguaje (cadenas de texto, enteros, booleanos...).\n * 5) Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n */\n\n public class LewisOneil {\n    // 1) URL web Java: https://www.oracle.com/java/\n\n    // 2.1) Esto es un comentario en una línea\n    \n    /* \n     * 2.2) Esto es un bloque\n     *      de comentarios\n     */\n    \n    /**\n     * 2.3) Comentario JavaDoc\n     */\n    \n    // 3.1) Variable\n    static String variable = \"¡Hola, \";\n    \n    // 3.2) Constante\n    static final String CONSTANTE = \"Java!\";\n    \n    // 4) Tipos de datos primitivos\n    byte bite = 127;            // byte\n    short corto = 23;           // entero corto\n    int entero = 23;            // entero\n    long largo = 23L;           // entero largo\n    float flotante = 30.23f;    // decimal, precisión simple\n    double doble = 23.30;       // decimal, precisión doble\n    boolean boleano = true;     // booleano\n    char caracter = 'c';        // carácter\n    \n    public static void main(String[] args) {\n\n        // 5) Imprimir por terminal\n        System.out.println(variable + CONSTANTE);\n    }\n\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/LizanDev.java",
    "content": "/**\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n * \n * \n */\n\n\n//https://www.java.com/es/\n//este es el comentario simple de una linea\n/*\n * con este podremos comentar varias linas\n * \n */\n\n\npublic class LizanDev {\n    \n    public static void main(String[] args) {\n        int numero=0;\n        double decimal = 0.0;\n        float otroDecimal= 0.0f;\n        char caracter = 'A';\n        String texto =\"entre comillas introduciremos el texto\";\n        boolean booleano = true;\n        long largo= 236297332L;\n        short corto= 32767;\n\n\n        String lenguaje= \"Java\";\n\n        System.out.println(\"¡Hola, \"+lenguaje);\n\n\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/LucasAG01.java",
    "content": "public class LucasAG01 {\n\n\n    public static void main(String[] args) {\n\n\n    //https://www.java.com/es/\n\n    //Esto es un comentario\n\n    /*\n    Aquí dentro puede haber otro comentario\n\n    las personas tambien declaran las variables y luego les dan valores en otras lineas siguientes.\n\n    */\n\n        //Constante\n        final int CONSTANTE_NUMERO = 12;\n\n    //variables\n\n        int numer0 = 12;\n        //hay que poner L\n        long numGrande = 321312312L;\n        //hay que poner f\n        float decimal = 12.3f;\n        double decimalGrande = 1.56;\n        short numChico = 10;\n        boolean check = true;\n        char carcter = 'a';\n        byte eso = 10;\n        String texto = \"QUE CARALLO\";\n\n        System.out.println(\"Hola,¡Java!\");\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/LuisK0706.java",
    "content": "public class Ejercicio00 {\n    public static void main(String[] args) {\n        \n        // Pagina oficial: https://www.java.com/es/\n\n        // Esto es un comentario de una sola linea\n\n        /*\n         * Esto es un comentario \n         * multilinea\n         */\n     \n         String mi_variable = \" java¡\"; // Declarando una variable\n\n         final float pi = 3.1416f;  // Declarando una constante\n\n         // Tipos de datos \n\n         int mi_entero = 7; // Variable entera: int (numeros enteros)\n\n         float mi_flotante = 7.5f; // Variable flotante: float (numeros decimales)\n\n         boolean mi_booleano = true; // Variable booleana: bool (true o false)\n\n         String mi_cadena = \"mi cadena\"; // Variable string: str (cualquier texto entre comillas dobles)\n\n         char mi_caracter = '5'; // Variable tipo caracter: char (una letra o numeros entre comillas simples )\n\n        System.out.println(\"!Hola\" + mi_variable);\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Marianoemir.java",
    "content": "\npublic class Marianoemir {\n\n    /* Esto es un comentario multilinea.\n    EJERCICIO:    \n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"*/\n    \n    //      Esto es un comentario de una linea.\n    //https://www.java.com/es/ sitio oficial de java \n    \n    //Hay una tercera forma de comentar con la sintaxis /***/ llamada Javadoc sirve para describir las clases, métodos, constructores, campos y otros elementos del código, \n    \n    public static void main(String[] args) {\n        //Variable\n        int variable = 10;\n        //Constante en Java, el valor de una constante, una vez asignado, no puede ser cambiado durante la ejecución del programa\n        final short Cons = 20;\n\n        //Byte   Tamaño: 8 bits  Rango: -128 a 127 Uso: Pequeños números enteros.  \n        byte byt = 127;\n\n        //short  Tamaño: 16 bits Rango: -32,768 a 32,767 Uso: Números enteros más grandes que byte\n        short corto = 30000;\n\n        //int Tamaño: 32 bits Rango: -2,147,483,648 a 2,147,483,647 Uso: Números enteros estándar.\n        int entero = 4000;\n\n        //long Tamaño: 64 bits Rango: -9,223,372,036,854,775,808 a 9,223,372,036,854,775,807 Uso: Números enteros muy grandes.\n        long largo = 15000000000L;\n\n        //float Tamaño: 32 bits Rango: Aproximadamente ±3.40282347E+38F (6-7 dígitos decimales) Uso: Números en punto flotante de precisión simple.\n        float decimal = 39f;\n        \n        //double Tamaño: 64 bits Rango: Aproximadamente ±1.79769313486231570E+308 (15 dígitos decimales) Uso: Números en punto flotante de precisión doble.\n        double dou = 439.99D;\n        //char Tamaño: 16 bits Rango: 0 a 65,535 (representa un solo carácter Unicode) Uso: Almacena caracteres individuales.\n        char caracter = '#'; //Puede representar un simbolo unicode una letra en minuscula o mayuscula ejemplo 'a' o 'A'\n        char simbolo = '\\u0024'; // '\\u0024' es el código Unicode para '$'\n        //boolean Tamaño: 1 bit (aunque su tamaño real puede ser dependiente de la implementación) Rango: true o false Uso: Almacena valores lógicos.\n        boolean estado = true; //boolean viene por default en false\n      \n        System.out.println(\"¡Hola, java!\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/MarioYellowy.java",
    "content": "class YellowDev {\n    public static void main(String[] args) {\n        //Comentario de una sola linea en Java\n        //Sitio oficial de Java https://www.java.com/es/\n        /*\n        * Comentario\n        * de\n        * varias\n        * lineas\n        * en\n        * Java\n        * */\n\n        String myVariable = \"Mi variable en Java\"; //Ejmplo de una variable en Java\n        final int version = 1; //Ejemplo de una constante en Java\n\n        //Java cuenta con ocho tipos de datos primitivos:\n        byte versionByte = 1;       //Tipo byte\n        short versionShort = 2;     //Tipo short\n        int versionInt = 3;         //Tipo int\n        long versionLong = 4;       //Tipo long\n        float versionFloat = 5.1f;  //Tipo float\n        double versionDouble = 7.3; //Tipo double\n        boolean isFree = false;     //TIpo booleano\n        char versionChar = 'A';     //Tipo char\n\n        //Tambien admite un tipo mas: String, pero este tipo no es considerado de tipo de primitivo\n        String myString = \"El bicho siu\";\n\n        String language = \"Java\";\n        System.out.println(\"Hola, \"+ language + \"!\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Mathiur.java",
    "content": "// Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado\n// https://www.java.com/es/\n// Esto es un comentario de una linea\n/*Esto es un comentario\n * multilinea\n */\n\npublic class Mathiur { // Renombrado para empezar con mayúscula\n    public static void main(String[] args) {\n        // DATOS PRIMITIVOS\n        int Entero = 2; //Entero\n        float Flotante = 15.4f; //Float\n        double Decimal = 18.4; //Decimal\n        boolean Booleano = true; //Booleano true o false\n        char Caracter = 'M'; //Caracter\n        String Texto = \"Mathiur\"; //Cadena de texto\n        //Constante\n        final int Constante = 18; //Constante\n\n        //Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n        String Lenguaje = \"Java\";\n        System.out.println(\"¡Hola, \" + Lenguaje + \" !\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Maynor06.java",
    "content": "//https://www.java.com/es/\n\n// comentarios en una sola linea \n/*\n * commentarios en \n * varias lineas\n */\n\n\n\npublic class MaynorSemeyá {\n\t\n\tpublic static void main(String[] args) {\n\t\t\n\t\n\t\tbyte primerVariable =1 ; /* representa un tipo de dato de 8 bits con signo\n\t\t*puede almacenar valores numericos en el rango de -128 a 127 \n\t\t*/\n\t\t\n\t\tshort seguandaVariable = 2; \n\t\t/* este utiliza 16 bits con signo puede almacenar valores numericos\n\t\t * en el rango de -32768 a 37767\n\t\t */\n\t\t\n\t\tint terceraVariable = 258; \n\t\t/*es un tipo de dato que utiliza 64 bits con signo y puede \n\t\t * almacenar valores numericos en el rango de -9223372036854775808 a 9,223,372,036,854,775,807 \n\t\t */\n\t\t\n\t\tfloat cuartaVariable = 8; \n\t\t/*es un tipo de dato diseñado para almacenar nùmeros en coma flotante\n\t\t * con precision simple de 32 bits \n\t\t */\n\t\t\n\t\tdouble quintaVariable = 25.5; \n\t\t/*este tipo de dato almacenta numeros en coma flotante con doble precision\n\t\t * de 64 bits, lo que proporciona una mayor precision que float\n\t\t */\n\t\t\n\t\tboolean sextaVariable = true ; \n\t\t/*define tipos de datos booleanos que pueden tener dos valores \n\t\t * true o false\n\t\t */\n\t\t\n\t\tchar septimaVariable = 'j'; \n\t\t/*es un tipo de datos que representa un caracter unicode sencillo \n\t\t * de 16 bits \n\t\t */\n\t\t\n\t\tSystem.out.println(\"Hola java!!\");\n\n\t\t\n\t}\t\n\n\t\n\t\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Mewynt.java",
    "content": "// https://developers.redhat.com/\n\n// comentario en una linea\n/* comentario en varias lineas\n\n */\n\npublic class Mewynt {\n  public static void main(String[] args) {\n\n    // CREACION DE VARIABLE\n\n    String variable = \"Hola soy una variable de JAVA\";\n\n    // CREACION VARIABLE CONSTANTE \"final\" Hace que la variable sea constante (no\n    // modificable)\n\n    final double DOLAR = 3.38; // Nombre en mayusculas Convención para distinguir constantes\n\n    /// ==================== CREACIÓN DE VARIABLES ====================\n    /// \n    int diasSemana = 7; // 4 bytes | -2,147,483,648 a 2,147,483,647 | Tipo entero más común.\n\n    double pi = 3.141592; // 8 bytes | ±1.7×10³⁰⁸ (15 decimales) | Números decimales con más precisión.\n\n    float precio = 5.75f; // 4 bytes | ±3.4×10³⁸ (6-7 decimales) | Números decimales pequeños (usa sufijo f).\n\n    short numero = 3000; // 2 bytes | -32,768 a 32,767 | Entero más grande que byte pero menor que int.\n\n    long distancia = 15000L; // 8 bytes | -2,147,483,648 a 2,147,483,647 | Enteros muy grandes (usa sufijo L).\n\n    byte edad = 20; // 1byte (8 bits) | -128 a 127 | Entero pequeño, útil para ahorrar memoria.\n\n    char letra = 'A'; // 2 bytes | Unicode (0 a 65,535) | Almacena un solo carácter.\n\n    boolean activo = true; // 1 bit(aprox.) | true o false | Representa valores logicos.\n\n    String nombre = \"Guillermo\"; // Variable | N/A | Cadena de texto (no primitivo, clase)\n\n    // Imprimiendo algunas cosas\n    System.out.print(\"yo siempre quise decir:\" + variable);\n  }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Natalinacn.java",
    "content": "package com.example.headfirstjava;\n\nimport org.springframework.boot.SpringApplication;\n\npublic class Natalinacn {\n\n    public static void main(String[] args) {\n        SpringApplication.run(HeadFirstjavaApplication.class, args);\n/*COMENTARIO MULTILINEA\n\nEJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"*/\n\n        // COMENTARIO DE UNA LINEA\n        // Información sobre descargas, documentación, tutoriales y recursos relacionados con Java:\n        // https://www.java.com/en/\n        // Información técnica y recursos para desarrolladores: https://www.oracle.com/java/\n\n        /**\n         * COMENTARIO DE DOCUMENTACIÓN (javadoc)\n         * @author natalin\n         * @version 1.0\n         */\n\n        //VARIABLES Y CONSTANTES\n        String variable = \"Variable\";\n        final String MI_CONSTANTE = \"Constante\";\n\n\n        //TIPOS DE DATOS PRIMITIVOS\n\n        byte tipoByte = 100; //Tamaño: 8 bits. Rango -128 a 127\n        short tipoShort = 10000; //Tamaño: 16 bits. Rango: -32.768 a 32.767\n        int tipoInt = 100000; //Tamaño: 32 bits. Rango: -2147483648 a 2147483647\n        long tipoLong = 100000L; //Tamaño: 34 bits. Rango: 2^63 a 2^63-1\n        float tipoFloat = 234.5f; //Tamaño: 32 bits. Rango: aproximadamente ±3.40282347E+38F (6-7 dígitos decimales). Float: Se usa cuando el ahorro de memoria es importante y la precisión de 6-7 dígitos decimales es suficiente.\n        double tipoDouble = 123.4; //Tamaño: 64 bits. Rango: aproximadamente ±1.79769313486231570E+308 (15-16 dígitos decimales). Double: Se usa para la mayoría de los cálculos de punto flotante debido a su mayor precisión y rango.\n        boolean tipoBoolean = true; // Tamaño: 1 bit (teóricamente). Valores posibles: true o false\n        char tipoChar = 'A'; // Tamaño: 16 bits. Rango: '\\u0000' (o 0) a '\\uffff' (o 65,535)\n\n\n        //Imprimir\n        String lenguaje = \"Java\";\n\n        System.out.println(\"¡Hola, \" + lenguaje + \"!\");\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/NazhirAvila.java",
    "content": "package RetosJava;\n\npublic class Reto1 {\n\t\n\tpublic static void main(String args[]) {\n\t\t\n\t\t//* - Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n\n\t\t//https://www.java.com/es/\n\t\t/*\t\n\t\t  //https://www.java.com/es/\n\t\t*/\n\t\t\n\t\t//- Crea una variable (y una constante si el lenguaje lo soporta).\n\t\tint variable1 = 0;\n\t\tfinal int const1 = 1;\n\t\t\n\t\t//- Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n\t\t\n\t\tbyte varByte = 127;\n\t\tshort varShort = 32767;\n\t\tint varInt = 999999999;\n\t\tlong varLong = 999999999;\n\t\tfloat varFloat = 1.26f;\n\t\tdouble varDouble = 1.25;\n\t\tboolean varBoolean = true;\n\t\tboolean varBoolean2 = false;\n\t\tchar varChar = 'A';\n\t\t\n\t\t//- Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\t\tString varString =\"Hola soy una variable de tipo String\";\n\t\t\n\t\tSystem.out.println(\"¡Hola JAVA!\");\n\t\t\n\t}\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/NicoFGT.java",
    "content": "// URL: https://www.java.com/es/\n\n/*\n * Esta sintaxis representa \n * un comentario que es hecho en\n * varias lineas...\n */\n\n//Esta sintaxis representa el comentario que es hecho en una sola linea \n\npublic class NicoFGT {\n\n    // VARIABLE asignada e inicilizada\n\n    float precio = 1.16f;\n\n    // CONSTANTE declarada e incilizada\n\n    final int ProductoID = 692710;\n    final String NOMBRE_PRDUCTO = \"CAFE\";\n\n    // TIPOS DE DATOS PRIMITIVOS DEL LENGUAJE\n\n    boolean Verdadero = true;\n    boolean Falso = false;\n    char Letra = 'N'; // introduce unicamente un solo caracter\n    byte EnteroNgeativo = -45; // Enteros con signo\n    short EnteroconSigno = -3444; // Entero con signo con mayor tamaño de caracteres\n    int EnteroPostitivo = 1555567154; // Entero con mayor volumen de carcateres\n    long PoblacionMundial = 8_000_000_000L; // Almacenar un número que excede la capacidad de un 'int'\n    float PrecioProducto = 16.16f; // numeros decimales\n    double pi = 3.141592653589793; // tambien almacena decimales\n\n    // IMPRESION HOLA MUNDO\n    public static void main(String[] args) {\n        System.out.println(\"Hola, mundo Java\");\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/NievesYonathan.java",
    "content": "// https://www.java.com/es/\n\n/* Esto es un comentario estilo C que puede ocupar varias líneas */ \n// Esto es un comentario que se extiende hasta el final de la línea\n\n/** \n * @author NievesYonathan\n * Esto es un comentario de javadoc que puede extenderse entre varias líneas \n**/\n\npublic class NievesYonathan {\n    // Variable de tipo string\n    String nombre = \"Yonathan\";\n\n    // Constante\n    final String apellido = \"Nieves\";\n\n    // Lista de variables según dato primitivo\n    byte centenas = 0;\n    short decenaMil = 15000;\n    int billon = 1365874589;\n    long granNum = 9223372036854775807L;\n    float e = 2.7182f;\n    double pi = 3.14159265358979323846;\n    boolean rendirse = false;\n    char z = 'Z';\n\n    public static void main(String[] args)\n    {\n        System.out.println(\"Hola JAVA!\");\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/ObidioTimoteo.java",
    "content": "/*\nReto de Programación 00: Sintaxis, Variables, Tipos de Datos y Hola Mundo\nLenguaje: Java\n*/\n\n/*\n    * 1. Crea un comentario en el código y coloca la URL del sitio web oficial del\n    * lenguaje de programación que has seleccionado.\n    */\n\n    // Sitio oficial de Java: https://www.java.com/\n\n    /*\n    * 2. Representa las diferentes sintaxis que existen de crear comentarios\n    * en el lenguaje (en una línea, varias...).\n    */\n\n    // Comentario en línea\n\n    /* \n    * Comentario\n    * en bloque\n    */\n\n   /** \n    * Comentario de documentación (Javadoc).\n    * Se utiliza para documentar el proyecto.\n    */\n\npublic class ObidioTimoteo {\n\n    // 3. Crea una variable y una constante\n\n    // Variable\n    String nombre = \"Obidio\";\n    \n    // Constante\n    final double PI = 3.1416;\n\n    /* \n    * 4. Crea variables representando todos los tipos de datos primitivos\n    * del lenguaje (cadenas de texto, enteros, booleanos...).\n    */\n\n    byte myByte = 120;              // Rango:   -128 a 127\n    short myShort = 1200;           // Rango:   -32.768 a 32.767\n    int myInt = 10000000;           // Rango:   -2^31 a 2^31-1\n    long mYLong = 100000000000000L; // Rango:   -2^63 a 2^63-1\n\n    float myFloat = 3.14f;                  // Se debe añadir 'f' al final\n    double myDouble = 3.141592653589793;    // Mayor precisión que float\n\n    char myCaracter = 'a';          // Solo un carácter\n    boolean myBoolean = true;       // true o false\n\n    /* \n    * 5. Imprime por terminal el texto:\n    * \"¡Hola, [y el nombre de tu lenguaje]!\"\n    */\n\n    public static void main(String[] args) {\n        \n        System.out.println(\"Hola, Java!\");\n        \n    }    \n\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/PPSystemsMX.java",
    "content": "// PÁGINA OFICIAL DE JAVA\n// https://www.java.com/es/\n\n// COMENTARIOS EN JAVA\n\n// Utilizar \"//\" para un comentario de una sola línea\n// Utilizar \"/*\" y \"*/\" para un bloque de comentarios de 2 o más líneas\n// Tambien se puede utilizar al iniciar el bloque de comentarios \"/*\", para cada linea \"*\" y para finalizar el bloque \"*/\"\n\n/*\n * Este es un bloque \n * de comentarios en donde \n * utilizamos varias lineas \n * y en cada linea, se \n * añade un \"*\"\n */\n\n\npublic class PPSystemsMX {\n\n    // Declaración de una variable\n    String miVariable = \"Mi variable es de tipo String\";\n\n    // Declaración de una constante\n    final String miConstante = \"Mi Constante es de tipo String\";\n\n    //Tipo de datos primitivos\n\n    // Byte acepta valores entre -128 to 127\n    byte miByte = 1;\n\n    // Short acepta valores entre -32,768 to 32,767\n    short miShort = 32767;\n\n    // int acepta valores entre -2,147,483,648 to 2,147,483,647\n    int miInt = 1000000000;\n\n    // long acepta valores entre -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807\n    long miLong = 1000000000;\n\n    // float acepta valores en coma flotante de precisión simple de 32 bits\n    float miFloat = 1.123456f;\n\n    // double acepta valores en coma flotante de precisión simple de 64 bits\n    double miDouble = 12345.1234567890;\n\n    // char acepta un solo carácter de 16 bits.\n    char miChar = 'l'; \n\n    // boolean representa un valor de verdad, true o false\n    boolean miBoolean = false;\n\n    public static void main(String[] args) {\n        //Impresión de texto en la terminal\n        System.out.println(\"¡Hola, Java!\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Password1989.java",
    "content": "package org.roadmap.java;\r\n\r\npublic class Password1989 {\r\n\r\n\tpublic static void main(String[] args) {\r\n\t\t/*\r\n\t\t * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\r\n\t\t * - Recuerda que todas las instrucciones de participación están en el\r\n\t\t *   repositorio de GitHub.\r\n\t\t *\r\n\t\t * Lo primero... ¿Ya has elegido un lenguaje?\r\n\t\t * - No todos son iguales, pero sus fundamentos suelen ser comunes.\r\n\t\t * - Este primer reto te servirá para familiarizarte con la forma de participar\r\n\t\t *   enviando tus propias soluciones.\r\n\t\t *\r\n\t\t * EJERCICIO:\r\n\t\t * - Crea un comentario en el código y coloca la URL del sitio web oficial del\r\n\t\t *   lenguaje de programación que has seleccionado.\r\n\t\t * - Representa las diferentes sintaxis que existen de crear comentarios\r\n\t\t *   en el lenguaje (en una línea, varias...).\r\n\t\t * - Crea una variable (y una constante si el lenguaje lo soporta).\r\n\t\t * - Crea variables representando todos los tipos de datos primitivos\r\n\t\t *   del lenguaje (cadenas de texto, enteros, booleanos...).\r\n\t\t * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\r\n\t\t *\r\n\t\t * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\r\n\t\t * debemos comenzar por el principio.\r\n\t\t */\r\n\t\t\r\n\t\t/* URL del sitio web oficial de JAVA: \r\n\t\t * https://www.java.com/es/\r\n\t\t */\r\n\t\t\r\n\t\t/*\r\n\t\t * Comentario de varias lineas\r\n\t\t */\r\n\t\t\r\n\t\t//Comentario de una linea\r\n\t\t\r\n\t\t/*\r\n\t\t * Ejercicio crea una variable:\r\n\t\t */\r\n\t\tString variableJava = \"Java\";\r\n\t\t\r\n\t\t/*\r\n\t\t * Ejercicio crea una constante:\r\n\t\t */\r\n\t\t\r\n\t\tfinal String constanteJava = \"Java\";\r\n\r\n\t\t/*\r\n\t\t * Datos primitivos en JAVA:\r\n\t\t * El lenguaje Java da de base una serie de tipos de datos primitivos.\r\n\t\t * \r\n\t\t * byte: \tRepresenta un tipo de dato de 8 bits con signo. De tal manera que puede almacenar los valores numéricos de -128 a 127 (ambos inclusive)\r\n\t\t * short: \tRepresenta un tipo de dato de 16 bits con signo. De esta manera almacena valores numéricos de -32.768 a 32.767.\r\n\t\t * int: \tEs un tipo de dato de 32 bits con signo para almacenar valores numéricos. Cuyo valor mínimo es -231 y el valor máximo 231-1.\r\n\t\t * long:\tEs un tipo de dato de 64 bits con signo que almacena valores numéricos entre -2 elevado 63 a 2 elevado a 63-1\r\n\t\t * float:\tEs un tipo dato para almacenar números en coma flotante con precisión simple de 32 bits.\r\n\t\t * double:\tEs un tipo de dato para almacenar números en coma flotante con doble precisión de 64 bits.\r\n\t\t * char:\tEs un tipo de datos que representa a un carácter Unicode sencillo de 16 bits.\r\n\t\t * boolean:\tSirve para definir tipos de datos booleanos. Es decir, aquellos que tienen un valor de true o false. Ocupa 1 bit de información.\r\n\t\t * \r\n\t\t * Primitivos\r\n\t\t * Lista de tipos de datos primitivos en JAVA\r\n\t\t * Tipo\t\tTamaño\tValor mínimo\t\t\tValor máximo\r\n\t\t * byte\t\t8 bits\t-128\t\t\t\t\t127\r\n\t\t * short\t16 bits\t-32768\t\t\t\t\t32767\r\n\t\t * int\t\t32 bits\t-2147483648\t\t\t\t2147483647\r\n\t\t * long\t\t64 bits\t-9223372036854775808\t9223372036854775807\r\n\t\t * float\t32 bits\t-3.402823e38\t\t\t3.402823e38\r\n\t\t * double\t64 bits\t-1.79769313486232e308\t1.79769313486232e308\r\n\t\t * char\t\t16 bits\t u000\t\t\t\tufff\r\n\t\t */\r\n\t\tbyte b = -128;\r\n\t\tshort s = -32768;\r\n\t\tint i = -2147483648;\r\n\t\tlong l = -9223372036854775808l;\r\n\t\tfloat f = -3.402823e38f;\r\n\t\tdouble d = -1.79769313486232e307d;\r\n\t\tchar c;\r\n\t\tboolean bl = true;\r\n\t\t\r\n\t\t//Facil: System.out.println(\"¡Hola, \" + variableJava + \"!\");\r\n\t\tSystem.out.println(String.format(\"¡Hola, %s!\", variableJava));\r\n\t\t\r\n\t\t/*\r\n\t\t * El título de la Pull Request también debe seguir este formato: \"#[número] - [lenguaje_utilizado]\". \r\n\t\t * En el ejemplo anterior sería \"#00 - Python\".\r\n\t\t * \r\n\t\t * En mi caso seria: \"#00 - Java\"\r\n\t\t */\r\n\r\n\t}\r\n\r\n}\r\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Pbjmg.java",
    "content": "public class Pbjmg {\n    public static void main(String[]args) {\n        // https://www.java.com/es/\n    // Esto es un comentario de una linea\n\n    /* Esto es un comentario\n     * multilinea\n     */\n\n    /**\n     * Esto es un comentario Javadoc\n     * Se usa para documentar clases, metodos y atributos\n     */\n\n    int edad = 25;  // Usamos var para inferir el tipo en variables locales\n    final int EDAD = 25; // Usamos final para declarar una variable de tipo constante\n\n    // Creamos las variables de los 8 tipos primitivos en Java\n    \n    byte b = 120;\n    short s = 25000;\n    int i = 2000000;\n    long l = 10000000000L;\n    float f = 2.2f;\n    double d = 24.213123;\n    char c = 'c';\n    boolean t = true;\n\n    System.out.println(\"¡Hola, Java!\");\n\n    }    \n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Peeanoot.java",
    "content": "public class Peeanoot {\n    public static void main(String[] args) {\n// https://www.java.com/es/\n\n// Comentario de una línea\n\n/* Comentario \n * de\n * varias\n * lineas\n */\n\n /** Los comentarios de documentación\n  * también conocidos como Javadoc\n  son un tipo especial de comentario \n  en Java que permite generar \n  automáticamente documentación \n  en formato HTML para clases\n  interfaces\n  métodos y variables \n  */\n\n\n  int ejericio = 1;\n\n  // Constante: \n\n  final int VALOR = 10;\n\n  // Variables representando todos los tipos de datos primitivos:\n\n  // Variables flotantes:\n  double precio = 19.99;\n\n  // Variables de caracteres:\n  char letra = 'A';\n\n  // Variables booleanas:\n  boolean esMayorDeEdad = true;\n\n  // Variables de cadena:\n  String nombre = \"Juan\";\n\n  // Variables de referencia: \n  Object objeto = new Object();\n\n  // Variables de arreglo (Array):\n  int[] numeros = {1, 2, 3, 4, 5};\n\n  // Variables enumerado:\n  enum DiaSemana {LUNES, MARTES, MIERCOLES, JUEVES, VIERNES, SABADO, DOMINGO};\n  DiaSemana diaActual = DiaSemana.MARTES;\n\n  // Variables byte:\n  byte valorByte = 127;\n\n  // Variables de tipo corto:\n  short valorShort = 32000;\n\n  // Variable de tipo largo:\n  long cantidad = 1000000000L;\n\n  System.out.println(\"Hola, mundo!\");\n    }\n}\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Pvigo10.java",
    "content": "// Página Oficial de Java : \"https://www.java.com/es/\"\n\n// Comentario de una línea\n/*\n* Comentarios\n* de varias\n* líneas\n*\n* */\n\npublic class pvigo{\n  public static void main(String[] args) {\n    //Una variable\n    String name_day;\n    //Una constante\n    final int year = 2024;\n\n    // Variable de todos los datos primitivos\n    //char\n    char letra = 'a';\n    // byte\n    byte edad = 31;\n    // short\n    short temperatura = -10;\n    // int\n    int numero_Estudiantes = 120;\n    // long\n    long numero_Poblacion = 1000000000;\n    // float\n    float precio = 14.50f;\n    // double\n    double area = 3.1415926535;\n    // boolean\n    boolean es_humano = true;\n\n    // Imprimir por terminal :\n    System.out.println(\"¡Hola, JAVA!\");\n\n  }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Qv1ko.java",
    "content": "// #00 - Sintaxis, variables, tipos de datos y hola mundo\n\n// www.java.com\n\npublic class Qv1ko {\n\n    public static void main (String[] args) {\n        \n        // Comment\n\n        /*\n         * Comment\n         */\n\n        int var1 = 1;\n        final int VAR2 = 2;\n\n        String str1 = \"Java\";\n        char var3 = 'c';\n        int var4 = 4;\n        float var5 = 5.5f;\n        double var6 = 6.6;\n        boolean bool = true;\n\n        System.out.println(\"¡Hola, \" + str1 + \"!\");\n\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/RREYES0424.java",
    "content": "public class RREYES0424 {\n    public static void main(String[] args) {\n        //https://www.java.com/es/\n\n        //Esta es una forma de crear comentarios en Java\n\n        /*\n        Esta es la\n        forma de crear\n        bloques de comentarios\n        en Java\n         */\n\n        String saludo = \"Hola Mundo!\";\n        final String nombre = \"Ricardo Reyes Flores\";\n\n        byte num1 = 21;\n        short num2 = 25;\n        int num3 = 524;\n        long num4 = 8387l;\n        float num5 = 778.34f;\n        double num6 = 89660.312;\n        boolean isActive = true;\n        char letra = 'R';\n\n        System.out.println(\"¡Hola, desde Java!\");\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Raghnus.java",
    "content": "public class Raghnus {\n    // URL: https://www.java.com/es/\n\n    // Comentario de una línea\n\n    /*\n     * Comentario\n     * de\n     * varias\n     * líneas\n     */\n\n    // Variable\n    int variable = 5;\n\n    // Constante\n    final double CONSTANTE = 3.689;\n\n    // Tipos de variables\n    int x = 5;\n    byte y = 10;\n    short z = 9;\n    long a = 58090;\n    double f = 89.6;\n    float g = 98.64f;\n    char i = 'h';\n    boolean k = true;\n    String l = \"Java\";\n\n    public static void main(String[] args) {\n        String lenguaje = \"Java\";\n        System.out.println(\"Hola, \" + lenguaje);\n    }\n\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Rantamhack.java",
    "content": "\n/*\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una lí­nea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n*/\n\n// Para tener una línea comentada en java se usa el simbolo \"//\"\n\n/* \nPara varias líneas se usa la combinacion barra \"/\" y Multiplicar \"*\" para abrir el comentario\ny la combinación Multiplicar \"*\" barra \"/\" para cerrar el comentario. Las lí­neas intermedias\nquedan comentadas\n*/\n\n/*\nLa página de referencia de java es https://www.java.com\nLa página para España es https://www.java.com/es/\n*/\n\npublic class Rantamhack {\n    public static void main (String[] args){\n\n\n        // Constante de programa\n        final int MY_CONSTANTE = 100;\n\n        // Variables\n\n        // Entera (int)\n        int my_integer_variable = 16;\n\n        // Decimal (float)\n        float my_pi_variable = 3.14f;\n\n        // Caracter(char)\n        char my_char_variable = 'a';\n\n        // Texto (string)\n        String my_text_variable = \"mi variable\";\n\n        // Booleana (bool)\n        boolean my_bool_variable = true;\n\n        // Mensaje de saludo al lenguaje\n        String lenguage = \"Java\";\n\n        // otras variable con menos uso\n        // --byte-- para cantidades pequeÃ±as (de -128 a 127)\n        byte my_byte_variable = 15;\n        \n        // --short-- para cantidades medianas ( de -32678 a 32677)\n        short my_short_variable = 15000;\n\n        // --long-- para numeros de -9223372036854775808 a 9223372036854775807\n        long  my_long_variable = 92233720368547756L;\n\n        // --double-- para decimales con gran numero de cifras donde no llegue float\n        double my_double_variable = 0.111111111111111111111;\n\n\n        System.out.println(MY_CONSTANTE);\n        System.out.println(my_integer_variable);\n        System.out.println(my_pi_variable);\n        System.out.println(my_char_variable);\n        System.out.println(my_text_variable);\n        System.out.println(my_bool_variable);\n        System.out.println(\"¡¡Hola, \"+lenguage +\"!!\");\n        System.out.println(my_byte_variable);\n        System.out.println(my_short_variable);\n        System.out.println(my_long_variable);\n        System.out.println(my_double_variable);\n        \n\n\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Robledom10.java",
    "content": "public class Robledom10 {\n\n    public static void main(String[] args) {\n    // https://www.java.com/es\n    // Esto es un comentario a una sola linea\n    /*\n     * Esto es un\n     * comentario en varias lineas\n     */\n\n    // Crea una variable\n    String variable = \"Esto es una variable\";\n\n    // Crea una constante\n    final String constante = \"Esto es una constante\";\n\n    // Datos primitivos\n    String typeString = \"Es una dato tipo String\";\n    char typeChar = 'R';\n    int typeInt = 10;\n    byte typeByte = 15;\n    short typeShort = 2;\n    long typeLong = 10L;\n    double typeDouble = 2.24;\n    boolean typeBooleanTrue = true;\n    boolean typeBooleanFalse = false;\n\n    System.out.println(\"¡Hola, Java!\");   \n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/RodrigoGit87.java",
    "content": "public class RodrigoGit87 {\n    public static void main(String[] args) {\n        // Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n        //            www.java.com\n\n        //Representa las diferentes sintaxis que existen de crear comentarios\n        // en el lenguaje (en una línea, varias...).\n\n        // comentario de una linea :)\n\n        /*\n        de varias lineas\n         */\n\n        // * - Crea una variable (y una constante si el lenguaje lo soporta).\n        String variable;\n        final String constante;\n\n        // * - Crea variables representando todos los tipos de datos primitivos\n        // del lenguaje (cadenas de texto, enteros, booleanos...).\n        variable = \" Hola Mundo de Moure\";\n        char caracter= 'a';\n        int numeroEntero = 0;\n        float numeroF = 1.2F; // la F al final pro q aveces da error si no se escribe. (no se por que)\n        double numeroDecimal = 1.2;\n        byte bytE= 1;\n        boolean boolE = true;\n\n        // - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\n\n        System.out.println( \" Hola, JAVA !\" );\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/RoniPG.java",
    "content": "\t//@Roni\n\npublic class SINTAXIS_VARIABLES_TIPOS_DE_DATOS_Y_HOLA_MUNDO_00 {\n\n\tpublic static void main(String[] args) {\n\t\t// TODO Auto-generated method stub\n\t\t\n\t\t//URL = https://www.java.com \n\t\t// Comentario en una linea.\n\t\t/*\n\t\t * Comentario de varias lineas.\n\t\t */\n\t\tbyte start, end; start= -128; end = 127 ;\n\t\tshort sh = 0 ; // start= -32768; end = 32767 ;\n\t\tint in = 0; // start= -2^31; end = 2^31 ;\n\t\tlong lo = 0; // start= -2^63; end = 2^63 ;\n\t\tfloat fl = 0.0f; // ---> numeros decimales simples.\n\t\tdouble dl = 0.0d; // ---> numeros decimales largos.\n\t\tboolean bo = false; // ---> valores true, false(por defecto).\n\t\tchar ch = 'a'; //---> valor para una letra/caracter.\n\t\tString st = \"Texto\"; //---> variable no primitivo para almacenar una cadena de caracteres.\n\t\t\n\t\t//Para crear una constante se a├▒ade 'final' antes de indicar el tipo de variable.\n\t\t\n\t\tfinal int fi=0;\n\t\t\n\t\tSystem.out.println(\"Hola JAVA\");\n\t}\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Rubioj17.java",
    "content": "public class Rubioj17 {\n    public static void main(String[] arg) {\n        /*\n            - Crea un comentario en el código y coloca la URL del sitio web oficial del\n              lenguaje de programación que has seleccionado.\n        */\n        //------------\n            // https://docs.oracle.com/en/java/javase/index.html\n\n            /*\n                El anterior es un comentario de una linea\n                y este es un comentario de varias lineas.\n                De estas 2 formas podemos escribir comentarios en Java\n            */\n        //------------\n\n        /*\n            - Crea una variable (y una constante si el lenguaje lo soporta).\n        */\n        //------------\n        int variable = 100; // Variable de tipo Número Entero\n        final int CONSTANTE = 200; // Constante de tipo Número Entero\n        //------------\n        /*\n            - Crea variables representando todos los tipos de datos primitivos\n              del lenguaje (cadenas de texto, enteros, booleanos...).\n        */\n        //------------\n        String texto = \"Java\";\n        char caracter = 'J';\n        int numeroEntero = 125;\n        float numeroDecimal = 125f;\n        boolean verdadero = true;\n        boolean falso = false;\n        //------------\n\n        /*\n            - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n        */\n        //------------\n        System.out.println(\"¡Hola, Java!\");\n        //------------\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/SXXNZDEV.java",
    "content": "public class SXXNZDEV {\n\n    //Sitio oficial de Java https://www.java.com/es/\n\n    /*Esto es para varias comentar varias lineas de codigo\n    se hace asi para no estar comentando linea por linea\n    si no las que se necesite a la vez*/\n\n    /**\n     * Esto es para generar la documentación en una API\n     */\n\n    //Genero una variable y una constante\n    int variable = 1;\n    final double PI = 3.1416;\n\n    //Tipos de datos primitivos\n    byte dato = 127;\n    short datoshort = 3452;\n    int datoInt = 1234423;\n    long datoLong = 1234234231;\n    float datoFloat = 124.434f;\n    double datoDouble = 342.434323d;\n    boolean datoBoolean = true;\n\n    public static void main (String[] args) {\n        //Mandar algun texto por el terminal\n        System.out.println(\"Hola, Java\" );\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/SamFuentes11.java",
    "content": "public class SamFuentes11 {\n    /*\n     * EJERCICIO:\n     * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n     *   lenguaje de programación que has seleccionado.\n     */\n        // Sitio web oficial de Java: https://www.java.com/es/\n\n     /* - Representa las diferentes sintaxis que existen de crear comentarios\n     *   en el lenguaje (en una línea, varias...).*/\n\n        // Comentarios en una línea utilizando (//)\n        // Comentarios de varias líneas (/* */)\n\n    /* - Crea una variable (y una constante si el lenguaje lo soporta).*/\n\n    public String primerVariable = \"Variable 1\";\n    public int CONSTANTE = 8;\n\n    /* - Crea variables representando todos los tipos de datos primitivos\n     *   del lenguaje (cadenas de texto, enteros, booleanos...).*/\n\n    byte bit = 127;\n    char caracter = 7;\n    short corto = 32766;\n    int entero = 4562654;\n    long largo = 458761624;\n    float flotante = 45.216545F;\n    double decimal = 20.2467;\n    boolean estaActivado = true;\n\n    /* - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\" */\n\n    public static void main(String[] args) {\n        System.out.println(\"¡Hola, Java!\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Sanuka78.java",
    "content": "public class Sanuka78 {\n    \n    public static void main(String[] args) {\n\n// https://www.java.com/es\n\n// Comentario de una línea\n/* Esto es un comentario\n  en varias líneas */\n\n//Crear una variable\nint edad = 8;\n\n//Crear una constante\nfinal String nombre = 'miNombre';\n\n//Crear datos primitivos\nchar letra = 'S';\nString cadena = 'hola';\nbyte num = 1;\nshort num2 = 2;\nint num3 = 3;\nlong cantidad = 23;\nDouble numero = 3.0;\nfloat altura = 50.0;\nboolean booleano = false;\n\n//Imprimir por pantalla\nSystem.out.println (\"Hola Mundo\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Slaughtbear.java",
    "content": "public class Slaughtbear {\n    public static void main(String[] args) {\n        // https://www.java.com/es/\n        // Esto es un comentario en una línea\n\n        /**\n         * Esto es un comentario\n         * de varias líneas.\n         */\n\n        // Crea una variable (y una constante si el lenguaje lo soporta).\n        String username = \"slaughtbear\";\n        final float PI = 3.14f;\n\n        // Crea variables representando todos los tipos de datos primitivos\n        // Enteros\n        byte numberByte = 100;\n        short numberShort = 10000;\n        int numberInt = 1000000000;\n        long numberLong = 10000000000000L;\n\n        // Decimales\n        float numberFloat = 6.66f;\n        double numberDouble = 888.0;\n\n        // Caracteres\n        char letterA = 'A';\n\n        // Booleanos\n        boolean isTrue = true;\n        boolean isFalse = false;\n\n        // Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n        System.out.println(\"¡Hola, Java!\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/SuaveSeda.java",
    "content": "public class SuaveSeda {\n\n    /*\n        Sintaxis\n        para crear comentarios\n        en varias lineas\n     */\n    \n    //  Sitio oficial del lenguaje seleccionado: https://www.java.com/es/\n    //  <--- Sintaxis para crear comentarios en una linea.\n    \n    public static void main(String[] args) {\n\n        String languaje= \"Java\"; // creación de una variable String\n        final int dia_semana = 7; // creacion de una constante \"final\"-> indica que no cambiará su valor.\n\n\n        // Representacion de los diferentes tipo primitivos\n\n        byte newByte= 2;               // Byte -128 t0 127\n        short newShort= 234;           // Short -32,6768 to 32,6767\n        int newInteger= 667889265;     // Integer -2,147,483,648 to 2,147,483,647\n        long newLong= 12345678900L;    // Long -9,223,372,036,854,775,808 y 9,223,372,036,854,775,807\n        float newFloat= 2314.98f;      // Float 6-7 decimal digits\n        double newDouble= 4563.78665;  // Double 15-16 decimal digits\n        boolean newBoolean= false;     // Boolean true or false\n        char newChar= 'H';             // Char single character/letter or ASCII\n\n\n        // Imprimir por pantalla el nombre del lenguaje que he seleccionado.\n\n        System.out.println(\"Hola Mundo! He escogido \" + languaje + \"!! WoooWW\");\n\n    }\n    \n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/TofeDev.java",
    "content": "public class TofeDev {\n    public static void main(String[] args) {\n\n        // Sitio oficial de Java: https://www.oracle.com/ar/java/\n        \n        // Comentario de una sola linea\n        \n        /* Comentario de\n         * varias lineas\n        */\n\n        // Variable y constante:\n        \n        var variable = \"Hola Mundo\";\n        final String constante = \"Hola Roadmap 2024\";\n        \n        //Datos Primitivos\n        \n        byte uno = 12;\n        short dos = 1542;\n        int tres = 35410;\n        long cuatro = 486415444;\n        float cinco = 1.84f;\n        double seis = 5.16d;\n        boolean siete = true;\n        char ocho = 'a';\n        \n        System.out.println(\"¡Hola, Java!\");\n\n    }\n        \n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/V1k770r.java",
    "content": "public class Main {\n    public static void main(String[] args) {\n        //  https://www.java.com\n        /*\n            \"https://www.java.com/\";\n            \"https://www.java.com/\";\n            \"https://www.java.com/\";\n        */\n        String direccion = \"https://www.java.com/\";\n        final String DIRECCION2 = \"https://retosdeprogramacion.com/roadmap/#last\";\n\n        char b = 'l';\n        byte a = 2;\n        int número = 10_000;\n        long numero2 = 100_000_000;\n        double nummero4 = 512_123_454;\n        float numero3 = 1.5F;\n        boolean valor = true;\n\n        System.out.println(\"Hola Java!!!\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Verschlingendenacht.java",
    "content": "public class Verschlingendenacht {\n    public static void main(String[] args){\n\n        ////////////////////////////////////////\n        //REQUISITO 1: LINK OFICIAL DEL LENGUAJE\n        //https://www.java.com/es/\n        ////////////////////////////////////////\n\n        ////////////////////////////////////////\n        //REQUISITO 2: REPRESENTACION DE COMENTARIOS EN JAVA\n\n        //comentario de línea definido por un doble slash al inicio   <------\n\n        /*\n        Hola, esto es un comentario de bloque\n        Estoy definidio por un slash seguido de un asterisco al inicio\n        Luego de mi comentario, un asterisco seguido de un slash invertido al final.\n         */\n        ////////////////////////////////////////\n\n        ////////////////////////////////////////\n        //REQUISITO 3: VARIABLE Y CONSTANTE\n\n        var x = \"soy una variable de valor manipulable\";\n        final var Y = \"soy una variable de valor constante, nadie me puede cambiar\";\n        ////////////////////////////////////////\n\n        ////////////////////////////////////////\n        //REQUISITO 4: DATOS PRIMITIVOS EN JAVA\n\n        //Para texto:\n        String miCadena = \"Java!\";\n        char miCaracter = 'a';\n\n        //Para numeros enteros:\n        byte miByte = 127;\n        short miShort = -32768;\n        int miEntero = 2147483647;\n        long miLong = -9223372036854775808L;\n\n        //Para numeros de punto flotante:\n        float miFloat = 3.14159f;\n        double miDouble = 3.14159265358979323846d;\n\n        //Para booleanos:\n        boolean miBooleano1 = true;\n        boolean miBooleano2 = false;\n        ////////////////////////////////////////\n\n        ////////////////////////////////////////\n        //REQUISITO 5: IMPRESION POR TERMINAL\n        System.out.println(\"¡Hola, \"+miCadena);\n        ////////////////////////////////////////\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/ViCtHoRmA.java",
    "content": "//Url del sitio web oficial\n// https://www.java.com/en/\n\n// Comentario en una sola linea\n/*\nComentario en varias lineas\n*/\n\n// Declaracion de variables\nstring variable = \"variable\"\nfinal int constante = 10\n\n//tipos de datos primitivos\n\nbyte variablebyte = 1 // numeros entre -128 y 127\nshort variableshort = 1000 // numeros entre -32.768 y 32.767\nlong variablelong = 100L // numeros grandes\nint variableint = 10 // numeros entre -2^31 y 2^31 -1\nfloat pi = 3.1416F //numeros decimales, se usa F al final para representarlo\ndouble e = 2.718281\nboolean variableboolean = true //almacena valores true or false\nchar variablechar = \"a\" // almacena un solo caracter\n\n  \n  \nSystem.out.println (\"Hi, java!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/VictorPolo28.java",
    "content": "public class VictorPolo28 {\n    public static void main(String[] args) {\n    //https://www.java.com/es/\n    \n\n    /*Este es  un comentario en \n    multiples \n    lienas\n     */\n\n    //datos primitivos\n    byte b = 100; //rango: de -128 a 127\n    short s = -3200; // rango de -32.768 a 32.767\n    int numero = 45 ; // rango de -2.147.483.648 a 2.147.483.647\n    long numeroGrande = 5000000; // rango de -9.223.372.036.854.775.808 a 9.223.372.036.854.775.807\n\n    float precio =19.95f; //tiene una precision  de  6-7 digitos decimales y lleva una f al final\n\n    double pi = 3.14159; // tiene una precisión de 15 dígitos decimales y el tipo preferido para operaciones decimales.\n\n    char letra ='A'; // almacena un único carácter en formato Unicode. Se declara usando comilas simples\n\n    boolean esVerdadero = true; //Solo puede tomar dos valores  true o false. Se usa para alamacenar valores lógicos.\n\n     //Creacions  de variables\n    int age = 25; // variable entera\n    double hight= 1.75;  //varible de numero con decimales\n    boolean employ = false; //variable booleana\n    String name = \"Victor\"; //variable  de tipo String \n\n    //Creacion de constanstes\n\n    final int MAX_NUMBER = 100; // Constante de tipo int\n    final  double MAX_HIGHT = 1.75;  // Constante de tipo double\n    final  String WELCOME_MESSAGE = \"Hola\"; // Constante de tipo String\n\n    System.out.println( \"Hola, Java\");\n\n}\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/VolumiDev.java",
    "content": "/*EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"*/\npublic class VolumiDev {\n\n\tpublic static void main(String[] args) {\n\t\t// TODO Auto-generated method stub\n\t\t// URL DE JAVA: https://www.java.com/es/\n\t\t\n\t\t//ESTO ES UN COMETARIO EN UNA LINEA\n\t\t\n\t\t/*ESTO ES UN COMETARIO EN PARRAFO\n\t\t * COMO SE HIZO ARRIBA CON EL E\n\t\t */\n\t\t\n\t\t//CREAMOS UNA VARIABLE DE TIPO CADENA\n\t\tString saludo=\"Hola, Java\";\n\t\t//CREAMOS UNA CONSTANTE POR EJEMPLO CON EL NUMERO PI;\n\t\tfinal double pi=3.1416;\n\t\t//VARIABLE ENTERA BYTE\n\t\tbyte n1=1;\n\t\t//VARIABLE ENTERA SHORT\n\t\tshort n2=2;\n\t\t//VARIABLE ENTEREA INT\n\t\tint n3=3;\n\t\t//VARIABLE ENTERA LONG\n\t\tlong n4=4;\n\t\t//VARIBALE REAL FLOAT\n\t\tfloat n5=5;\n\t\t//VARIABLE REAL DOUBLE\n\t\tdouble n6=6.2;\n\t\t//VARIABLE CARACTER\n\t\tchar caracter='a';\n\t\t//VARIABLE BOOLEAN\n\t\tboolean condicion=true;\n\t\t//VARIALBE CADENA DE TEXTO\n\t\tString cadena=\"Esto es una cadena de texto\";\n\t\t\n\t\tSystem.out.println(saludo);\n\n\t}\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Worlion.java",
    "content": "/* EJERCICIO 00:\n*/\n\npublic class Worlion {\n\n    // https://www.java.com/es/\n\n    // Esto es un comentario de una línea\n\n    /*\n     * Esto es un comentario de bloque\n     */\n\n     // Esto es una variable\n    int variable = 2;\n\n    // Esto es una constante\n    static final int CONSTANTE = 1;\n    \n    //Tipos primitivos\n    \n    //byte\n    byte byteVariable = 10;\n    \n    //short\n    short shortVariable = 20;\n    \n    //int\n    int intVariable = 30;\n    \n    //long\n    long longVariable = 40L;\n    \n    //float\n    float floatVariable = 3.14f;\n    \n    //double\n    double doubleVariable = 2.71828;\n    \n    //char\n    char charVariable = 'A';\n    \n    //boolean\n    boolean booleanVariable = true;\n\n    // El tipo String NO es un tipo primitivo\n    static String stringVariable = \"¡Hola, Java!\";\n\n    public static void main(String[] args) {\n        System.out.println(stringVariable);\n    }\n    \n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Zugarramurdi.java",
    "content": "/**\n * Clase Zugarramurdi donde se implementara el primer ejercicio del roadmap #00-SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n * @author Zugarramurdi\n * @version 1.0\n * @date 05/04/2025\n */\n// https://www.java.com/es/ - Web de Java\n// https://docs.oracle.com/en/java/javase/24/ - Documentación de Java\n\npublic class Zugarramurdi {\n\n    //Declaracion de una constante\n    public static final String TEXTO_CONSTANTE = \"Soy una constante\"; // Se declaran en mayusculas y con guiones bajos y a nivel de clase\n\n    public static void main(String[] args) {\n        // Esto es un comentario de una línea\n\n        /*\n         * Esto es un comentario en bloque\n         */\n\n        /**\n         * Esto es un comentario JavaDoc para generar documentacion\n         */\n\n        //Declaracion de variables\n        // Sintaxis: tipo nombreVariable = valor;\n        String texto = \"Soy una variable de tipo String\"; // Cadena de texto - valor entre comillas dobles\n        boolean booleano = true; // Almacena valores true o false\n        char caracter = 'A'; // Almacena un solo caracter - valor entre comillas simples\n        byte numeroByte = 100; // Almacena un entero entre -128 y 127\n        short numeroShort = 1000; // Almacena un entero entre -32,768 y 32,767\n        int numeroInt = 10000; // Almacena un entero entre -2,147,483,648 y 2,147,483,647\n        long numeroLong = 10000000; // Almacena un entero entre -9,223,372,036,854,775,808 y 9,223,372,036,854,775,807\n        float numeroFloat = 100.0f; // Almacena un decimal de 4 bytes, hasta 7 decimales - valor con f al final\n        double numeroDouble = 100.0d; // Almacena un decimal de 8 bytes, hasta 15 decimales\n\n        //Impresion por terminal\n        System.out.println(\"¡Hola, Java!\");\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/Zyn7e.java",
    "content": "public class Zyn7e {\n  public void main (String[] args) {\n\n    /*\n     * ###########################\n     * TIPOS DE COMENTARIOS\n     * ###########################\n     */\n\n    // Sitio oficial de Java en español en un cometario simple: https://www.java.com/es/\n\n    /*\n     * Este es un comentario en varias lineas\n     * y se puede escribir tantas lineas\n     * como necesites.\n     */\n\n    /**\n     * Este es un comentario de documentación en varias lineas\n     * Se utiliza antes de una clase, método o función\n     *\n     * Permite documentar el código usando etiquetas:\n     * @param nombreDelParametro permite documentar sobre un parametro\n     *                           y se pueden usar tantas como parametros\n     *                           tenga el método.\n     * @return Se utiliza para documentar el resultado que retorna un método.\n     * @throws Documenta una excepción.\n     */\n\n\n\n    /*\n     * ###########################\n     * CREACIÓN DE VARIABLES Y CONTANTES\n     * ###########################\n     */\n\n    // Variable\n    String miVariable = \"Hola\";\n\n    // Constante\n    const int miConstanteDePI = 3.14159;\n\n\n\n    /*\n     * ###########################\n     * VARIABLES Y TIPOS DE DATOS PRIMITIVOS\n     * ###########################\n     */\n\n    // Existen 8 tipos de datos primitivos:\n\n    // ###### Números enteros ######\n    /*\n     * byte: Representa un tipo de dato de 8 bits con signo.\n     * Puede almacenar valores numéricos en el rango de -128 a 127,\n     * incluyendo ambos extremos.\n     */\n    byte numeroNegativoByte = -26;\n    byte numeroPositivoByte = 50;\n\n    /*\n     * short: Representa un tipo de dato de 16 bits con signo.\n     * Puede almacenar valores numéricos en el rango de -32,768 a 32,767,\n     * incluyendo ambos extremos.\n     */\n    short numeroNegativoShort = -24000;\n    short numeroPositivoShort = 10000;\n\n    /*\n     * int: Representa un tipo de dato de 32 bits con signo.\n     * Puede almacenar valores numéricos en el rango de -2,147,483,648 a 2,147,483,647,\n     * incluyendo ambos extremos.\n     */\n    int numeroNegativoInt = -1000000000;\n    int numeroPositivoInt = 2000000000;\n\n    /*\n     * long: Representa un tipo de dato de 64 bits con signo.\n     * Puede almacenar valores numéricos muy grandes (y pequeños)\n     * con precisión.\n     */\n    long numeroNegativoLong = -30000000000000000000000000L;\n    long numeroPositivoLong = 3000000000000000000000000000L;\n\n\n    // ###### Números de punto flotante ######\n\n    /*\n     * float: Representa un número de punto flotante de 32 bits.\n     */\n    float numeroFloat = 12.450F;\n\n    /*\n     * double: Representa un número de punto flotante de 64 bits.\n     */\n    double numeroDouble = 12345.34564567D;\n\n\n    // ###### Char ######\n\n    /*\n     * char: Representa un carácter Unicode de 16 bits.\n     */\n    char miChar = 'A';\n\n\n    // ###### Valores lógicos ######\n    /*\n     * boolean: Representa un valor lógico, verdadero o falso.\n     */\n    boolean booleanVerdadero = true;\n    boolean booleanFalso = false;\n\n\n\n    /*\n     * ###########################\n     * IMPRESIÓN EN PANTALLA\n     * ###########################\n     */\n\n    System.out.println(\"Hola, Java!!\");\n  }\n\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/adrs1166ma.java",
    "content": "public class adrs1166ma {\n    public static void main(String[] args) {\n        // URL del sitio oficial Java: https://www.java.com/\n\n        // - - - Tipos de comentario - - -\n\n        // Una linea 1\n\n        /* Una linea 2 */\n\n        /*\n         * Varias\n         * lineas 1\n         */\n\n        /*\n        Varias\n        lineas 2\n         */\n\n        // -- -- Variables y Constantes -- --\n        String miVariable = \"Soy una variable\";\n        final String miConstante = \"Soy una constante\";\n\n        // -- -- Tipos de datos primitivos -- --\n        //   Caja[tipo]   =  Numero Maximo\n\n        /* Primitivos Enteros */\n        byte datoByte     = 127;\n        short datoShort   = 32767;\n        int datoInt       = 2147483647;\n\n        /* Primitivos Flotantes */\n        long datoLong     = 9223372036854775807L; // L al final\n        float datoFloat   = 3.4028235E38F;        // F al final\n        double datoDouble = 1.7976931348623157E308;\n\n        /* Primitivos Character */\n        char datoCharSimbolo = 'a';\n        char datoCharDecimal = 80;\n\n        /* Primitivos Booleano */\n        boolean datoBoolean1 = true;\n        boolean datoBoolean2 = false;\n\n        String saludo = \"¡Hola\";\n        final String lenguaje = \"Java\";\n        System.out.println(saludo + \", \" + lenguaje + \"!\");\n\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/agusrosero.java",
    "content": "public class agusrosero {\n    public static void main(String[] args) {\n        // https://www.java.com/es/\n\n        // Comentario de una linea\n        /*\n         * Comentario de\n         * varias lineas\n         */\n\n        var miVariable = \"Hola!\";\n        final var MI_CONSTANTE = 3.14;\n\n        double miDouble = 3.33;\n        float miFlotante = 2.2f;\n        int miEntero = 10;\n        String miCadena = \"Hola!\";\n        boolean miBooleano = true;\n        char miChar = 'A';\n\n        System.out.println(\"¡Hola, [Java]!\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/akaidmaru.java",
    "content": "\npublic class akaidmaru {\n    public static void main(String[] args) {\n        /*\n         * EJERCICIO:\n         * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n         * lenguaje de programación que has seleccionado.\n         * - Representa las diferentes sintaxis que existen de crear comentarios\n         * en el lenguaje (en una línea, varias...).\n         * - Crea una variable (y una constante si el lenguaje lo soporta).\n         * - Crea variables representando todos los tipos de datos primitivos\n         * del lenguaje (cadenas de texto, enteros, booleanos...).\n         * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n         *\n         */\n\n        // Official Site: https://www.java.com/en/\n        // Developer Resources: https://dev.java/\n        // Documentation: https://docs.oracle.com/en/\n\n        // Comentario en una línea\n        /*\n         * Comentario multilínea\n         */\n        /**\n         * Javadocs para documentación.\n         */\n\n        String variable = \"Esto es una variable\"; // Hay que declarar el tipo primero, luego el nombre\n        final String CONSTANT = \"Esto es una constant\"; // Hay que usar final para volverla inmutable y también por\n                                                        // convención, el nombre es todo en mayúsculas.\n\n        // Tipos de datos primitivos\n        byte byteNumber = 127; // Almacena 1 byte\n        short shortNumber = 32767; // Almacena 2 bytes\n        int integer = 2147483647; // Almacena 4 bytes\n        long longNumber = 922337203685775807L; // Almacena 8 bytes\n        float floatNumber = 0.24234f; // Almacena 4 bytes\n        double doubleNumber = 0.224982410982; // Almacena 8 bytes\n        boolean isBoolean = true; // Almacena 1 bit\n        char character = 'a'; // Almacena 2 bytes\n\n        // Tipos de datos no primitivos (Objeto)\n        String string = \"Soy un string\";\n        \n        // Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]\n        System.out.println(\"¡Hola, Java!\");\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/alejosor.java",
    "content": "/**\n * Solución del reto #00: Sintaxis, variables, tipos de  datos y hola mundo;\n * @author Alejosor\n */\npublic class alejosor {\n    \n    public static final int num_max = 100; // Constante entera\n    \n    public static final String mensaje_bienvenida = \"¡Bienvenido a Java!\"; // Constante de cadena\n\n    public static void main(String[] args) {\n        /*\n         * EJERCICIO:\n         * - Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n         * - Representa las diferentes sintaxis que existen de crear comentario en el lenguaje (en una línea, varias...).\n         * - Crea una variable (y una constante si el lenguaje lo soporta).\n         * - Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n         * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n         */\n\n        // - Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n        // URL del sitio web oficial de Java: https://www.java.com/es/\n\n\n        // - Representa las diferentes sintaxis que existen de crear comentario en el lenguaje (en una línea, varias...).\n            // <- Forma de comentar en una sola línea.\n\n            /*\n             *  <- Forma de comentar en varias líneas.\n             */\n        \n        // - Crea una variable (y una constante si el lenguaje lo soporta).\n        String variable = \"Esto es una variable\";  // Creación de una variable.\n\n        final int num_mim = 1; //Constante dentro de un método\n\n        // - Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n        byte byt = 10; // Tipo de dato primitivo -> Byte\n\n        short shrt = 12; // Tipo de dato primitivo -> Short\n\n        int entero = 150; // Tipo de dato primitivo -> Int\n\n        long lng = 14567l; // Tipo de dato primitivo -> Long\n\n        float flat = 23.6f; // Tipo de dato primitivo -> Float\n\n        double dbl = 23.54566; // Tipo de dato primitivo -> Double\n\n        char chr = 'A'; // Tipo de dato primitivo -> Char\n\n        boolean bool = true; // Tipo de dato primitivo -> Boolean\n\n        // - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n        System.out.println(\"¡Hola, Java!\");\n\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/alexeigio.java",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n\n //URL JAVA: https://www.java.com/es/\n\npublic class alexeigio {\n    //Crear variable y constante \n    int variable1 = 666;\n    static final int constante = 777;\n\n    //Crear variables representando tipos de datos primitivos del lenguaje\n\n    byte byteJAVA = 127;\n    short shortJAVA = 32767;\n    long longJAVA = 11111;\n    double doubleJAVA = 22.3;\n    boolean booleanJAVA = false;\n    String stringJAVA = \"Esto es Texto en JAVA\";\n   \n\n    public static void main(String[] args) {\n     String lenProgra = \"JAVA PAPI GOD\";\n     System.out.println(\"HOLA JAVA TE AMO\");\n     System.out.println(\"Hola \" + lenProgra);   \n    }\n}\n "
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/alvarofernandezavalos.java",
    "content": "public class alvarofernandezavalos {\n  // this is a comment\n  /*\n    https://www.oracle.com/es/\n    https://www.java.com/es/\n   */\n  // constante\n  private static final String CONSTANTE = \"CONSTANTE\";\n  public static void main (String[] args) {\n    // variables\n    boolean bVar1  = true;\n    float fVar2    = 6.9f;\n    int fVar3      = 2;\n    char fVar4     = 'H';\n    byte fVar5     = 0;\n    short fVar6    = 1;\n    long fVar7     = 33L;\n    double fVar8   = 1.23d;\n\n    System.out.println(\"Hola, Java\");\n  }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/andresmendozaf.java",
    "content": "\npublic class andresmendozaf {\n\n    public static void main(String[] args) {\n\n        //Sitio oficial de JAVA en un comentario simple http://www.java.com.es\n        //Este es un comentario de una línea\n\n        /*\n        Esto permite\n        comentar varias\n        líneas de texto \n         */\n        /**\n         * Comentario de documentación en varias lineas Se utiliza antes de una\n         * clase, método o función\n         *\n         * Permite documentar el código usando etiquetas:\n         *\n         * @param nombreDelParametro permite documentar sobre un parametro y se\n         * pueden usar tantas como parametros tenga el método.\n         * @return Se utiliza para documentar el resultado que retorna un\n         * método.\n         * @throws Documenta una excepción. otros\n         */\n        /**\n         * CREACIÓN DE VARIABLES Y CONTANTES\n         */\n        String variable = \"variable\";\n        System.out.println(\"Este es el ejemplo de una \" + variable);\n\n        final double pi = 3.1416;\n        System.out.println(\"Este podría ser un ejemplo de constante \" + pi);\n\n        /**\n         * TIPOS DE DATOS PRIMITIVOS\n         */\n        /**\n         * byte: Representa un tipo de dato de 8 bits con signo. Puede almacenar\n         * valores numéricos en el rango de -128 a 127, incluyendo ambos\n         * extremos.\n         */\n        byte byteNegativo = -15;\n        byte bytePositivo = 15;\n        System.out.println(\"Esto es el ejemplo de BYTE, tanto negativo como positivo : \" + byteNegativo + \" - \" + bytePositivo);\n\n        /**\n         * short: Este tipo de dato utiliza 16 bits con signo y puede almacenar\n         * valores numéricos en el rango de -32,768 a 32,767.\n         */\n        short shortNegativo = -15600;\n        short shortPositivo = 15600;\n        System.out.println(\"Esto es el ejemplo de SHORT, tanto negativo como positivo : \" + shortNegativo + \" - \" + shortPositivo);\n\n        /**\n         * int: Es un tipo de dato de 32 bits con signo utilizado para almacenar\n         * valores numéricos. Su rango va desde -2,147,483,648 (-2^31) hasta\n         * 2,147,483,647 (2^31 - 1). Es el tipo de dato más comúnmente utilizado\n         * para representar números enteros.\n         */\n        int intNegativo = -14;\n        int intPositivo = 14;\n        System.out.println(\"Esto es el ejemplo de INT, tanto negativo como positivo : \" + intNegativo + \" - \" + intPositivo);\n\n        /**\n         * long: Este tipo de dato utiliza 64 bits con signo y puede almacenar\n         * valores numéricos en el rango de -9,223,372,036,854,775,808 (-2^63) a\n         * 9,223,372,036,854,775,807 (2^63 - 1). Se utiliza cuando se necesitan\n         * números enteros muy grandes.\n         */\n        long longNegativo = -19042011;\n        long longPositivo = 19042011;\n        System.out.println(\"Esto es el ejemplo de LONG, tanto negativo como positivo : \" + longNegativo + \" - \" + longPositivo);\n\n        /**\n         * float: Es un tipo de dato diseñado para almacenar números en coma\n         * flotante con precisión simple de 32 bits. Se utiliza cuando se\n         * requieren números decimales con un grado de precisión adecuado para\n         * muchas aplicaciones.\n         */\n        float floatNegativo = -186.56874f;\n        float floatPositivo = 186.56874f;\n        System.out.println(\"Esto es el ejemplo de FLOAT, tanto negativo como positivo : \" + floatNegativo + \" - \" + floatPositivo);\n\n        /**\n         * double: Este tipo de dato almacena números en coma flotante con doble\n         * precisión de 64 bits, lo que proporciona una mayor precisión que\n         * float. Se usa en aplicaciones que requieren una alta precisión en\n         * cálculos numéricos.\n         */\n        double doubletNegativo = -19879886.56564874d;\n        double doublePositivo = 18987986.56874564d;\n        System.out.println(\"Esto es el ejemplo de DOUBLE, tanto negativo como positivo : \" + doubletNegativo + \" - \" + doublePositivo);\n\n        /**\n         * boolean: Sirve para definir tipos de datos booleanos que pueden tener\n         * solo dos valores: true o false. Aunque ocupa solo 1 bit de\n         * información, generalmente se almacena en un byte completo por razones\n         * de eficiencia.\n         */\n        boolean booleanFalse = false;\n        boolean booleanTrue = true;\n        System.out.println(\"Esto es el ejemplo de BOOLENA, tanto \" + booleanFalse + \" como \" + booleanTrue);\n\n        /**\n         * char: Es un tipo de datos que representa un carácter Unicode sencillo\n         * de 16 bits. Se utiliza para almacenar caracteres individuales, como\n         * letras o símbolos en diferentes lenguajes y conjuntos de caracteres.\n         */\n        char charNumerico = 5;\n        char charCaracteres = 'r';\n        System.out.println(\"Esto es el ejemplo de CHAR, puede ser numérico \" + charNumerico + \" o de caracteres \" + charCaracteres);\n\n        /**\n         * Imprimir por consola\n         */\n        System.out.println(\"Hola JAVA!\");\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/asjordi.java",
    "content": "public class Main {\n\n    /**\n     * https://www.oracle.com/java/technologies/downloads/\n     * https://www.java.com/es/\n     * https://devdocs.io/openjdk~19/\n     */\n\n    /**\n     * Comentario de varias líneas\n     * @param args\n     */\n    public static void main(String[] args) {\n        // Comentario de una linea\n\n        // Variable\n        String reto = \"Ejercicio 1\";\n\n        // Constante\n        final String leng = \"Java\";\n\n        // Tipos de datos\n\n        String cadena = \"Hola\";\n        int num1 = 1;\n        float num2 = 1.0f;\n        double num3 = 1.0;\n        long num4 = 1L;\n        short num5 = 1;\n        byte num6 = 1;\n        boolean bool = true;\n        char letra = 'a';\n\n        System.out.println(\"¡Hola, Java!\");\n\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/bladi23.java",
    "content": "//https://www.java.com/es//\n\n//Ejemplo de un comentario en una linea//\n\n/*Ejemplo \nde comenatrios \nen varias \nlineas\n*/\npublic class BladimirVelasco {\n    static final String constante = \"Hola esto es una constante\";\n\n\n\npublic static void main(String[] args) {\n\n\n// Tipos de datos primitivos\nint numeroEntero = 10;\ndouble numeroDecimal = 3.14;\nboolean esVerdadero = true;\nchar caracter = 'A';\nfloat numeroFlotante = 3.1415926535f;\nlong numeroLargo = 299792458;\nbyte numeroByte = 127;\nshort numeroCorto = 32767;\n\n// Tipos de datos de referencia\nString cadenaTexto = \"Hola, mundo!\";\n\n// Imprimir en consola\n\nSystem.out.println(\"¡Hola, JAVA!\");\n}\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/bycris13.java",
    "content": "/*\n * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license\n * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Main.java to edit this template\n */\n\n/**\n *\n * @author Cris\n */\npublic class bycris13 {\n    //Declaracionde una constante\n    static final int MI_CONSTANTE = 10;\n\n    public static void main(String[] args) {\n        // https://www.java.com/es/\n\n        // comentario de una linea.\n        /* comentario de vaias lineas\n        puede contener multiples lieneas de codiogo.\n         */\n        int miVariable = 10;\n\n        \n        // Enteros\n        int entero = 10;\n        byte byteEntero = 127;\n        short shortEntero = 32000;\n        long  longEntero = 1234567890L;\n        \n        // Decimales\n        float decimalFlotante = 3.14f;\n        double  decimalDoble = 3.14159265359;\n        \n        // Caracteres\n        char caracter  = 'A';\n        \n        // Booleano\n        boolean booleano = true; \n        \n        String nombreDelLenguaje = \"java\";\n        System.out.println(\"¡Hola, \"+nombreDelLenguaje+\"!\");\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/camiloforero1997.java",
    "content": "// Comentario en una sola linea\n\n//Aqui en en el siguiente link podremos encontrar todo lo relacionado con Java https://www.java.com/\n\n/*Comentario\n * de varias\n * lineas\n */\n\npublic class Camiloforero1997{\n\n    Public static void main (String[] args){\n\n        //Creando una variable definida y no definida\n\n        String variableDefinida = \"Tengo un valor\";\n        String variableNoDefinida;\n\n        //Constantes\n\n        final String SOYUNACONSTANTE = \"Constante\";\n\n        //Datos primitivos\n\n        int datoInt = 5000;\n        float datoFloat = 3,892f;\n        double datoDouble = 3,127128231731D;\n        char datoChar = 122;\n        long datoLong =829L;\n        short datoShort = 238;\n        byte datoByte = 2;\n        boolean datoBoolean = true;\n        String DatoString = \"Soy string\";\n\n        System.out.println(\"Hola Java\");\n\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/canrosss.java",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\npublic class canrosss {\n\n    /* - Crea un comentario en el código y coloca la URL del sitio web oficial del */\n    //Sitio Oficial de Java en Español\n    //URL: https://www.java.com/es/\n    \n    //Comentario de una linea en Java hace esta manera con un doble backslash\n   \n    /* El comentario multilinea en Java se hace con un backslash y termina con asterisco backslash */ \n\n    //Constante\n    static final String username = \"canrosss\";\n\n    //Variables en sus tipos de datos primitivos\n    //Enteros y char\n    char nombre = 'c';\n    byte edad = 38;\n    short anio = 2025;\n    int sueldo = 54000;  //Mexican MXN\n    long distanciaLunaTierra = 384400000L; // en metros\n\n    //puntos decimales\n    float temperatura = 33.40f;\n    double pi = 3.141592653589793;\n\n    //Boolean primitivo\n    Boolean isReady=false;\n\n    public static void main(String[] args){\n        System.out.println(\"!Hola, Java!\");\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/cesar-ch.java",
    "content": "﻿// URL: https://www.java.com/es/\n\n// Este es un comentario de una sola línea\n\n/*\n * Este es un comentario \n * de varias líneas\n */\n\n\npublic class cesarch {\n    public static void main(String[] args) {\n    \n        // Variable y constante\n        String lenguaje = \"Java\";\n        final int YEAR = 2024;\n        \n        // Tipos de datos primitivos\n        byte numeroByte = 127;\n        short numeroShort = 32767;\n        int numeroInt = 2147483647;\n        long numeroLong = 9223372036854775807L;\n        float numeroFloat = 3.14f;\n        double numeroDouble = 3.14;\n        boolean booleano = true;\n        char caracter = 'a';\n        String cadena = \"Hola mundo\";\n\n        System.out.print(\"¡Hola, \" + lenguaje + \"!\");\n\n    }\n    \n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/chalaito88.java",
    "content": "public class chalaito88 {\n    public static void main(String[] args) {\n        //https://www.java.com/es/\n\n        //Esto es un comentario de una sola línea.\n        /*Esto\n        * es\n        * un\n        * comentario\n        * de\n        * más\n        * de\n        * una\n        * línea*/\n\n        //Constante\n        final float PRECIO = 10.25f;\n        //Variables\n        float preciofinal = 50.30f;\n        double precioManzana = 1.50;\n        short cosita = 10;\n        int numero = 80;\n        long numeroUtilizado = 100000000;\n        String nombre = \"Daniel\";\n        char vocal = 'A';\n        boolean siono = true;\n        byte codita2 = 6;\n\n        System.out.println(\"Hola Java!!\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/chartypes.java",
    "content": "// https://java.com\n\n// Comentario de una sola linea\n\n/*\n  Comentario de multiples lineas\n*/\npublic class chartypes{\n  public static void main(String[] args){\n\n    char var = 'a';\n    final CONSTANT = 10;\n    int interger = 3;\n    float floating = 3.14f;\n    double double = 3.14;\n    boolean bool = true;\n    String lenguageName = \"Java\";\n\n    System.out.println(\"Hola,\" +lenguageName+\"!\");\n\n  }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/clespinosa2024.java",
    "content": "/*\n * Este es un comentario multilínea \n * https://www.java.com\n */\npackage vaariables;\n\n/**\n *\n * @author Claudia\n */\npublic class Variables {\n    \n    public static void main(String[] args) {\n        \n        String mensaje = \"Hola Java\";\n        \n        // variable de tipo int inicializada \n        int edad = 32;\n        //variable de tipo char inicializada\n        char sexo = 'F';\n        /* variable tipo float mediante un casteo.\n           Representa mi estatura en metros\n        */\n        float estatura = 1.50f;       \n        \n        \n        //constante de tipo double\n        double pi  = 3.141592265358979323846;\n        \n        //variable de tipo boleana que representa mi estado civil\n        boolean single = true;\n        System.out.println(mensaje);\n       \n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/cristian-encalada.java",
    "content": "package reto00;\n\n/*\n * 1. Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n */\n\n// https://www.java.com/en/\n\n/*\n * 2. Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n*/\n\n// Comentario de una sola línea\n\n/*\n * Comentario de múltiples líneas\n * @author Cristian Encalada\n */\n\n/**\n * Documentation type comment\n */\n\n/*\n3. Crea una variable (y una constante si el lenguaje lo soporta).\n\n    int myVar = 10;\n\n    final int MIN_VALUE = 1;\n*/\n\npublic class sintaxisVariables00 {  \n// variable a nivel de objeto\npublic  int objectVariable = 9;\n// variable a nivel de clase\npublic  static int classVariable = 15;\n    public static void main(String[] args) {\n        // variable local\n        int localVariable = 10;\n\n        /*\n        * 4. Crea variables representando todos los tipos de datos primitivos\n        *   del lenguaje (cadenas de texto, enteros, booleanos...).\n       */\n\n        int myInt = 10; // 4 byte/32 bits - range: -2e31 to 2e-31-1\n        short myShort;  // 16 bits - range: -32,768 to 32,767 - better for integers\n        long myLong = 123456L;  // 64 bits - range: -2e63 to 2e-63-1\n        double myDouble = 5.5d; // 64 bits - range: 4.9e-324 to 1.8e+308\n        float myFloat = 9.99f; // 4 byte (32 bits) - range:  1.40129846432481707e-45 to 3.40282346638528860e+38\n        boolean myBool = false; \n        byte myByte = -128;  // 8 bits - range: -128 to 127\n        char myChar = 'Z';\n        String myString = \"¡Hola, Java!\";\n        \n        \n        //  5. Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n        System.out.println(myString);\n    }\n    \n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/cristobalbelcor.java",
    "content": "    /*  * EJERCICIO:\n        * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n        *   lenguaje de programación que has seleccionado.\n        * - Representa las diferentes sintaxis que existen de crear comentarios\n        *   en el lenguaje (en una línea, varias...).\n        * - Crea una variable (y una constante si el lenguaje lo soporta).\n        * - Crea variables representando todos los tipos de datos primitivos\n        *   del lenguaje (cadenas de texto, enteros, booleanos...).\n        * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n     */\n\n\n    //#00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n\n    /*\n    Sitio web oficial de java\n    https://www.java.com/es/\n    */\n\npublic class Main {\n    public static void main(String[] args) {\n\n// variable de datos primitivos\n\n        char Char = 'D';\n        boolean Boolean = true;\n        byte Byte = 1;\n        short Short = 32767;\n        int Int = 2147483647;\n        long Long = 9223372036854775807L;\n        float Float = 19.1f;\n        double Double = 19.1;\n\n\n        System.out.println(\"¡Hola, Java!\");\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/curtobrull.java",
    "content": "public class curtobrull {\n    public static void main(String[] args) {\n\n        // Web Oficial: https://www.java.com\n\n        // Comentario 1 línea.\n\n        /*\n         * Comentario multilinea.\n         */\n\n        String CONSTANTE = \"Java\";\n\n        boolean bool = false;\n        char character = 'a';\n        byte numByte = 0;\n        short numShort = 0;\n        int integer = 0;\n        double numDouble = 0.0;\n        float numFloat = 0.0f;\n        long numLong = 0L;\n\n        System.out.println(\"¡Hola, \" + CONSTANTE + \"!\");\n    }\n\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/danhingar.java",
    "content": "//URL OFICIAL JAVA: https://www.java.com/es/\n\n//Comentario en una linea\n\n/*Comentarios\n en \n varias \n lineas \n */\n\n/**\n * Comentarios para generar documentación JAVADOC\n * \n * Estos comentarios se utilizan para documentar los ficheros Java,\n * para ello utilizamos las siguientes etiquetas:\n * \n * @author Daniel -> especifica el autor del fichero\n * \n * @param name\n * @return String\n * @throws Exception\n * @since\n */\n\npublic class danhingar {\n\n    // Para poder ejecutar algo en Java necesitamos tener definido un método main\n    public static void main(String[] args) {\n\n        /*\n         * Datos primitivos\n         * \n         * Tenemos tres tipo de datos: númericos, carácteres y booleanos\n         */\n\n        // Tipo primitivos númerico\n\n        byte numero1 = 127; // Almacena un número hasta 8 bits(-127,127)\n        short numero2 = 3242; // Almacena un número hasta 16 bits(-32768,32767)\n        int numero3 = -235546234; // Almacena un número hasta 32 bits\n        long numero4 = 716473841782738267l; // Almacena un número hasta 64 bits, obligatorio añadir 'l' al final\n        float numero5 = 213123213.213f; // Almacena un número con decimales hasta 32 bits, obligatorio añadir 'f' al final\n        double numero6 = -327163782136.2138762163876; // Almacena un número con decimales hasta 64 bits\n\n        // Tipo primitivo boolean\n        boolean condition = Boolean.TRUE;\n\n        // Tipo primitivo caracter;\n        char A = 'A';\n\n        //Una constante se define usando 'final'\n        final int constante= 23;\n\n        // Para imprimir por terminal usamos:\n        System.out.println(\"¡Hola,Java!\");\n    }\n\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/david-quinones.java",
    "content": "\n// URL Oficial --> https://www.java.com/es/\n\n// Comentario de una linia\n\n/*\n* Comentario\n* de\n* muchas\n* linieas\n* */\n\n/**\n * Comentario JavaDoc\n * Muchas linias\n */\n\n\n/* Variable i Constante */\nprivate var variable = 1;\nprivate static final String CONSTANTE = \"david-quinones\"; //final definie que es constante + MAYUSCULA el nombre\n\n// variable de tipos primitivos\n\nprivate char aChar = 'D';\nprivate boolean aBoolean = true;\nprivate byte aByte = 128;\nprivate short aShort = 32767;\nprivate int anInt = 2147483647;\nprivate long aLong = 9223372036854775807;\nprivate float aFloat = 19.1f;\nprivate double aDouble = 19.1;\n\n//imprimir por terminal\nSystem.out.println(\"¡Hola, Java!\");\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/det3992.java",
    "content": "package retosDeProgramacion;\n\npublic class Ejercicio01 {\n\tpublic static void main(String[] args) {\n\n\t\t// https://www.java.com/es/\n\n\t\t// COMENTARIO DE UNA UNICA LINEA\n\n\t\t/*\n\t\t * COMENTARIO DE VARIAS LINEAS\n\t\t * \n\t\t */\n\n\t\tint myNum = 0; // he definido una variable de tipo int con valor 0\n\t\tfinal double pi = 3.14; // para definir una constante basta con poner el modificador \"final\" delante del\n\t\t\t\t\t\t\t\t// tipo de dato\n\n\t\tString myName = \"David\"; \t\t// Cadena de texto con mi nnombre.\n\t\tchar type = 'a';\t\t\t\t// Variable de un solo caracter.\n\t\tboolean myBool = true; \t\t\t// Variable de tipo booleano.\n\t\tint myNum2 = 39; \t\t\t\t// Variable de tipo entero.\n\t\tdouble alonsoVictory = 33.33; \t//Variable de tipo decimal.\n\t\t\n\t\tSystem.out.println(\"¡Hola, Java!\");\n\t}\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/devVdroid01.java",
    "content": "// Aquí se crea un package \"retos_de_programacion\"\npackage retos_de_programacion;\n\npublic class devVdroid01 {\n\tpublic static void main(String[] args) {\n\t\t// El sitio oficial de Java es:: https://www.java.com/es/\n\n        // Esto es un comentario de una sola línea\n\n        /* Esto es un comentario de una \n        o más líneas (multilínea)*/\n\n        /** Esto es un comentario para javadoc (para documentar con esta herramienta) */\n\t\n        int variable_edad;\n        final int NUMERO_CABEZA = 1;\n        // Tipos de datos primitivos\n        byte v_byte;\n        short v_short;\n        int v_int;\n        long v_long;\n        float v_float;\n        double v_double;\n        char v_char;\n        String v_string = \"Java\";\n        boolean v_boolean;\n\n        System.out.println(\"¡Hola, \" + v_string + \"!\");\n\t}\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/dmauricio4.java",
    "content": "package com.dm4.roadmap;\n\n\n\npublic class Roadmap00_SintaxisVariables {\n\n    public static void main(String[] args) {\n\n        //Sitio oficial de Java: https://java.com/es/\n\n        /*\n        Comentario de\n        varias\n        lineas\n         */\n\n        /**\n         Este tipo de comentarios\n         los utiliza la\n         herramienta javadoc\n         */\n\n        //Crea una variable (y una constante si el lenguaje lo soporta).\n        String miVariable = \"Mi primera variable\";\n        String MY_CONSTANTE = \"My primera constante\";\n\n        //Crea variables representando todos los tipos de datos primitivos.\n        byte valorByte = 6;\n        short valorShort = 10;\n        int numero = 100;\n        long numeroLong = 100000000;\n        float valorFloat = 10.20f;\n        double precioFinal = 10.25;\n        boolean verdadero = true;\n        boolean falso = false;\n        char caracter = 'A';\n        String texto = \"JAVA\";\n\n        //Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n        System.out.println(\"¡Hola, \" + texto + \"!\");\n\n    }\n    \n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/edalmava.java",
    "content": "// Comentario de fin de línea\n\n// Sitio oficial: https://www.oracle.com/java/\n\n/*\n * Comentario de varias líneas\n */\n\n/**\n * Comentarios de documentación JavaDoc\n */\n\npublic class Edalmava {\n    public static void main(String[] args) {\n        // Tipos de datos primitivos\n        // Declaración de variables:\n        // Tipo nombre_variable = valor;\n\n        byte b = 64;             // Byte\n        short s = 1000;          // Short\n        int i = 5_000_000;       // Enteros\n        long l = 5_000_000_000l; // Long\n        float f = 5.0f;          // Float\n        double d = 5.0;          // Double\n        char ch = 'a';           // Char\n        boolean v = true;        // Boolean - verdadero\n        boolean fa = false;      // Boolean - falso        \n\n        System.out.println(\"¡Hola, Java!\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/eleite_d.java",
    "content": "//Single-line comment\n//https://www.java.com/es/\n/*Multi-line\n comment*/\n\npublic class eleite_d {\n    public static void main(String[] args) {\n        int year = 2025; //variable\n        int BORN = 1992; //constant\n\n        //Primitive data types\n        byte children = 0;\n        short day = 18;\n        int age = year - BORN;\n        long bigNumber = 1856516502060650601L;\n        float weight = 65.5f;\n        double height = 1.65;\n        char sex = 'f';\n        boolean female = (sex == 'f');\n\n        //Pseudo primitive data type\n        String language = \"Java\";\n\n        System.out.println(\"¡Hola, \" + language + \"!\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/estuardodev.java",
    "content": "// #00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n/*\n* Sitio web oficial de C#\n* https://dotnet.microsoft.com/es-es/languages/csharp\n*\n* */\n\npublic class estuardodev {\n    private static String _Greeting = \"Hola\";\n    private static final String _Language = \"C#\";\n    private static int _Year = 2024;\n    private static char _Comma = ',';\n    private static long _EarthYears = 45400000;\n    private static double _PiMedium = 3.14159265359;\n    private static float _PiShort = 3.14f;\n    private static boolean _Subscribed = true;\n\n    public static void main(String[] args) {\n        System.out.println(\"¡\" + _Greeting + _Comma + \" \" + _Language + \" en Retos de Programación \" + _Year + \"!\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/eulogioep.java",
    "content": "// URL del sitio web oficial de Java\n// https://www.oracle.com/java/\n\n// Diferentes formas de crear comentarios en Java:\n\n// 1. Comentario de una línea\n\n/*\n * 2. Comentario\n * de varias\n * líneas\n */\n\n/**\n * 3. Comentario de documentación (Javadoc)\n * Se usa para generar documentación automática del código\n */\n\n public class eulogioep {\n    public static void main(String[] args) {\n        // Creación de una variable\n        String miVariable = \"Hola, Java!\";\n\n        // Creación de una constante\n        final int MI_CONSTANTE = 42;\n\n        // Variables representando tipos de datos primitivos en Java\n        byte miByte = 127;\n        short miShort = 32767;\n        int miInt = 2147483647;\n        long miLong = 9223372036854775807L;\n        float miFloat = 3.14f;\n        double miDouble = 3.14159265359;\n        boolean miBoolean = true;\n        char miChar = 'A';\n\n        // Impresión del texto solicitado\n        System.out.println(\"¡Hola, Java!\");\n\n        // Impresión de los valores de las variables (opcional, para verificación)\n        System.out.println(\"miVariable: \" + miVariable);\n        System.out.println(\"MI_CONSTANTE: \" + MI_CONSTANTE);\n        System.out.println(\"miByte: \" + miByte);\n        System.out.println(\"miShort: \" + miShort);\n        System.out.println(\"miInt: \" + miInt);\n        System.out.println(\"miLong: \" + miLong);\n        System.out.println(\"miFloat: \" + miFloat);\n        System.out.println(\"miDouble: \" + miDouble);\n        System.out.println(\"miBoolean: \" + miBoolean);\n        System.out.println(\"miChar: \" + miChar);\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/feliduarte.java",
    "content": "public class feliduarte {\n    public static void main(String[] args) {\n\n        // https://www.oracle.com/java/\n\n        // Comentario para una sola línea.\n        /* Comentario para varias líneas */\n\n        int cantAnimales = 500;\n        final double PI = 12.123;\n\n        byte num1 = 1;\n        short num2 = 100;\n        int num3 = 1000;\n        String nombrePersona = \"Felipe\";\n        double altura = 1.90;\n        boolean trabajador = true;\n\n        System.out.println(\"¡Hola, Java!\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/francescvm8.java",
    "content": "/**\n * Lloc web: https://www.java.com/es/\n */\n// Comentario de una línea\n/* Comentario */\n/*\n * Comentario\n * de\n * varias\n * líneas\n */\n\npublic class francescvm8 {\n   public static void main(String[] args) {\n      // declaración de variables\n      String lenguaje = \"Java\";\n      int numero = 1;\n      boolean booleano = true;\n      double decimal = 1.5;\n\n      // declaración de constante\n      final String constante = \"Hola\";\n\n      // imprimir por terminal\n      System.out.println(\"¡Hola, \" + lenguaje + \"!\");\n\n   }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/fredylopez01.java",
    "content": "public class fredylopez01 {\n\n  /*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n    public static void main(String[] args) {\n        //Sitio de JAVA\n        //https://www.java.com/es/\n\n        //Diferentes sintaxis de comentarios JAVA\n        //Unica línea\n        /*\n         * Varias lineas\n         */\n\n        String miVariable;       //variable\n        final int constante = 2; //constante\n\n        //Datos Primitivos\n        int numeroEntero = 1;\n        double decimal = 0.3;\n        byte bite = 4;\n        short corto = 32000;\n        long extenso = 4444444;\n        char caracter = 'a';\n\n        //String es una clase que puede almacenar cadenas de caracteres\n        String saludo = \"¡Hola, \";\n\n        //Impresión de información\n        System.out.println(saludo + \"JAVA!\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/gian247.java",
    "content": "public class gian247 {\n\n\n    public static void main(String[] args) {\n        //https://docs.oracle.com/en/java/\n\n        //COMENTARIO DE 1 SOLA LINEA\n        /* COMENTARIO\n        EN\n        BLOQUE */\n\n        /** COMENTARIO DE COUMENTACION */\n\n        //VARIABLES\n\n        String variable=\"Hola mundo\";\n\n        final String CONSTANTE= \"LUNES\";\n\n\n        //TIPOS DE DATOS PRIMITIVOS\n\n        //ENTEROS\n\n        byte byteDato=5; // va desde el -128 al 127\n        short shortDato= 20000; // va desde -32,768 al 32.767\n        int intDato= 30000; // va desde el -2 ^ 31 al 2 ^ 31 -1\n        long longDato= 40000; // va desde el -2 ^ 63 al 2 ^ 63 -1\n\n        //CARACTER\n\n        char caracter='H'; //Almacena un unico valor Unicode\n\n        //PUNTO FLOTANTE\n\n        float floatDato= 5.0f; // de 6 a 7 decimales\n        double doubleDato= 6.0; // 15 decimales\n\n        //BOOLEANO\n\n        boolean activo=true; // TRUE O FALSE\n\n        System.out.println(\"!Hola Java!\");\n\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/gianellannie.java",
    "content": "public class Main {\n  public static void main(String[] args) {\n    // URL del sitio web oficial de Java: https://docs.oracle.com/en/java/\n    \n    // Comentario en una línea de código\n    /* \n    Comentario \n    en varias \n    líneas de código\n    */\n    \n    var variable = 1;\n    final int constante = 5;\n    \n    // Tipos de datos primitivos\n    byte numeroByte = 1;\n    short numeroShort = 10;\n    int entero = 15;\n    long numeroLong = 100;\n    double doble = 15.64;\n    float flotante = 15.64f;\n    char caracter = 'C';\n    boolean booleano = true;\n    \n    System.out.println(\"¡Hola, Java!\");\n  }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/h4ckxel.java",
    "content": "public class EspinoLeandroo {\n\n    /**\n     * Este es un comentario de documentación.\n     * Se utiliza para generar documentación automáticamente.\n     * @param args Descripción del parámetro args.\n     */\n    public static void main(String[] args) {\n        // https://www.java.com/es/\n        // Esto es un comentario de una línea\n\n        /*\n        * Esto es un comentario\n        * que abarca múltiples líneas.\n        * Puedes escribir varias líneas aquí.\n        */\n\n        final String ejercicio = \"#00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\";\n        String lenguaje = \"java\";\n        \n        byte edad = 27;\n        short distancia = 10000;\n        int cantidad = 1000000;\n        long poblacionMundial = 7800000000L;\n        \n        float altura  = 1.8f;\n        double pi = 3.1415926535897;\n        \n        char letra = 'A';\n\n        boolean esMayorDeEdad = true;\n        \n        System.out.println(\"¡Hola, Java!\");\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/hanzd07.java",
    "content": "// https://www.java.com/es/\n\n//Crear un comentario en una sola línea\n\n/*Crear comentario \n  en varias líneas*/\n\n// Crea una variable (y una constante si el lenguaje lo soporta).\n\nString miVariable = \"Crear una variable en java\";\n\n// Crear una constante en java\n\nstatic final double numero_PI = \"3.14159\";\n\n/* Crea variables representando todos los tipos de datos primitivos\n   del lenguaje (cadenas de texto, enteros, booleanos...). */\n\nString texto = \"Nombre\"\nint numeroEntero = 1;\ndouble numeroDecimal = 2.14;\nchar unSoloCaracter = 'A';\nboolean verdadero = True;\nboolean falso = False;\n\n// Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\npublic class HolaJava {\n  public static void main (String[] args) {\n    System.out.println(\"¡Hola, Java!\");\n  }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/inmortalnight.java",
    "content": "//#00 - Java\n\n// Comentar en una línea\n/*Comentar en varias líneas */\n/*\n * Comentar\n * en varias líneas\n * docuemntación\n */\n\npublic class inmortalnight {\n    //Variable\n    String var = \"something\";\n    //Constante\n    final String constant= \"something\";\n    //Tipos de datos primitivos\n    byte bit = 8; //-128 al 127\n    short one = 1; //-32,768 al 32,767, igual que int pero con menos memoria\n    int realNumber = 24; //-2,147,483,648 al 2,147,483,647\n    long bigNumber = 1000000000; //-9,223,372,036,854,775,808 al 9,223,372,036,854,775,807\n    float decimal = 1.5f; //32 bits, rango de 1.4e-45 a 3.4028235e+38\n    double doubleDecimal = 1.5; //64 bits, rango de 4.9e-324 a 1.7976931348623157e+308\n    boolean negativo = true; //true o false, 1 bit\n    char letter = 'a'; //16 bits, rango de 0 a 65,535, letras y simbolos\n    public static void main(String[] args) {\n        System.out.println(\"Hola Mundo\");\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/jaimeNar.java",
    "content": "public class jaimeNar {\n  public static void main(String args[]) {\n    // URL del sitio web oficial\n\t\t/**\n\t\t * https://www.java.com\n\t\t **/\n\n\t\t// Diferentes sintáxis para crear comentarios\n\t\t// Comentario de una sola línea\n\n\t\t/*\n\t\t * Comentario de varias líneas\n\t\t */\n\n\t\t/**\n\t\t * Otro comentario de varias líneas\n\t\t **/\n\n\t\tint variable; // Variable\n\n\t\tfinal int constant; // Constante\n\n\t\t// Variables que representan los tipos de datos primitivos\n\t\tbyte by = 127;\n\t\tshort num_sh = 32767;\n\t\tint num = 234567834;\n\t\tlong num_long = 456546465L;\n\t\tfloat num_float = 1.5f;\n\t\tdouble num_double = 3.7;\n\t\tchar character = 'A';\n\t\tboolean bool = true;\n\n\t\t// Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\t\tSystem.out.println(\"¡Hola, Java!\");\n  }\n}\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/jcrodmir.java",
    "content": "public class  jcrodmir{\n\n/*\n Programm Language/ Programmiersprache: Java\n Official Java Website / offizielle Java WebSite: https://docs.oracle.com/javase/8/docs/\n Other Java Website/ andere Java WebSite : https://www.javatpoint.com/java-tutorial\n\n*/\n\n//  Diferents types of comment one line/verschiedene Typen von Kommentaren\n\n/*  multiples lines/ mehrere Zeilen\n*/\n\n    /**\n     *  Documentation\n     *\n     * */\n\n//Create a variable and constant/Variable und Konstante erstellen\n/*\n    The variables at Java have the type of the variable the name and the value, if you want a constant, must add\n    a the keyword final.\n    Die Variablen bei Java haben den Typ der Variablen, den Namen und den Wert, wenn Sie eine Konstante wollen, müssen Sie\n    ein das Schlüsselwort final.\n\n */\n\n    int variableNumber = 8;\n    final int finalNumber= 9;\n\n    //Primitives Types/ primitive Datentypen\n/*\n    Byte/Short/Int/Long/Float/Double/Boolean/Char\n */\n    byte ReallySmallNumber=10;\n    short smallNumber=10000;\n    int number= 100000;\n    long  ReallyBigNumber=53856421646L;\n    float decimalNumber= 2.5f;\n    double decimalBigNumber= 52556.684684446;\n    boolean trueOrFalse= true;\n    char character= 'A';\n\n    public static void main(String[] args) {\n        System.out.print(\"Hello World\");\n        System.out.print(\"Hallo Welt\");\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/jlrojano.java",
    "content": "// Reto 1 de programacion 2024 por MoureDev\n\n/*\nEJERCICIO:\n    1. Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n    2. Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n    3. Crea una variable (y una constante si el lenguaje lo soporta).\n    4. Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n    5. Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n*/\n\npublic class jlrojano {\n\n\n\n    // 1. URL del sitio oficial: https://www.java.com/\n\n    // 2. Una linea comentada\n    /*\n       2. Varias lineas...\n       ... comentadas\n     */\n\n\n    public static void main(String[] args) {\n\n        // 3. Crea una variable (y una constante si el lenguaje lo soporta).\n        // VARIABLE\n        var myVar = 100;\n        // CONSTANTE\n        final var MY_VAR = false;\n        // 4. Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n        byte bByte = 127;\n        short sShort = 32767;\n        int iInt = 2^32;\n        long lLong = 2^63L;\n        float fFloat = 123;\n        double dMyDouble = 12e306D;\n        boolean bMybool = true;\n        char cMyChar = 'c';\n\n\n        // 5. Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n        System.out.println(\"¡Hola, java!\");\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/jose-zga.java",
    "content": "//https://www.java.com/es/\n\n//Se utulizan dos parentesis para indicar o comentar una línea\n\n/* Para realizar un conetario de\n  varias líneas en Java,\n  se usa un parentesis y un asterisco y tiene cierre\n  */\n\nlet miVariable; //una variable en Java se crea usando let o var al inicio de la declaración\nconst miConstante; //una constante se declara usando const al inicio de la declaración\n\nint variableInteger = 8;\nfloat variableFloat = 2.5;\ndouble variableDouble = 2.4647497;\nString variableString = \"Esto es un string\";\nboolean variableBoolean = true;\n\nSystem.out.println(\"¡Hola Java!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/josepilco7501.java",
    "content": "/**\n * Solución del ejercicio #00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n * @author JOSE HAMMER\n */\npublic class josepilco7501{\n    /**\n     *\n     * @param args\n     */\n    public static void main(String[] args) {\n\n        //https://www.java.com/es/\n\n        //Comentario de una linea\n\n        /*\n        Comentarios de\n        varias lineas\n         */\n\n        /**\n         * Comentario JavaDoc para documentacion de codigo fuente\n         */\n\n        /**\n         * Creacion e inicializacion de una variable y un numero\n         * @numeroA variable no iniciliazada\n         * @numeroB constatnte inicializada\n         */\n        int numeroA; //Creacion de una variable de tipo entero llamada numeroA\n        final double numeroB = 2.5; //Creacion e inicializacion de una constante llamada numeroB\n\n        /**\n         * - Crea variables representando todos los tipos de datos primitivos\n         * del lenguaje (cadenas de texto, enteros, booleanos...).\n         */\n\n        /*\n            | Tipo      | Tamaño  | Valor por defecto | Rango                                    | Descripción breve |\n            | --------- | ------- | ----------------- | ---------------------------------------- | ----------------- |\n            | `byte`    | 8 bits  | `0`               | -128 a 127                               | Entero pequeño    |\n            | `short`   | 16 bits | `0`               | -32,768 a 32,767                         | Entero corto      |\n            | `int`     | 32 bits | `0`               | -2³¹ a 2³¹-1                             | Entero estándar   |\n            | `long`    | 64 bits | `0L`              | -2⁶³ a 2⁶³-1                             | Entero largo      |\n            | `float`   | 32 bits | `0.0f`            | ±1.4e-45 a ±3.4e+38                      | Decimal simple    |\n            | `double`  | 64 bits | `0.0d`            | ±4.9e-324 a ±1.7e+308                    | Decimal doble     |\n            | `char`    | 16 bits | `'\\u0000'`        | '\\u0000' a '\\uffff' (caracteres Unicode) | Carácter unicode  |\n            | `boolean` | 1 bit   | `false`           | `true` o `false`                         | Lógico            |\n\n         */\n\n        byte edad = 25;\n        short año = 2025;\n        int poblacion = 1000000;\n        long distancia = 9223372036854775807L;\n\n        float temperatura = 36.6f;\n        double pi = 3.14159265359;\n\n        char inicial = 'J';\n        boolean esJavaGenial = true;\n\n        /**\n         * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n         */\n\n        System.out.println(\"¡Hola, java!\");\n\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/jossfullstack.java",
    "content": "\npublic class cero_Cero {\n\n\tpublic static void main(String[] args) {\n\t\t// TODO Auto-generated method stub\n\n    //Sitio web oficial:\n\t\t// https://www.java.com/es/\n\n\t\t/*\n\t\t * https://www.java.com/es/\n\t\t */\n\t\t\n\t\t//Variable\n\t\t//Tipo --->> + Nombre de la variable ´;\n\t\tString tazo;\n\t\t\n\t\t// Constante:::::::\n\t\tdouble pi = 3.14;\n\t\t\n\t\t//Variables con los tipos de datos primitivos:::::::\n\t\t\n\t\tbyte ochobites;\n\t\tshort dieciseisbites;\n\t\tint treintaydosbites;\n\t\tlong sesentaycuatrobites;\n\t\tfloat treintaydosbotes_flotantecondobleprecisionde64bites;\n\t\tboolean trueorfalse;\n\t\tchar caracterunidoce;\n\t\t\n\t\t//CONSTANTES RESPRESENTACION \n\n    byte ochobites;\n\t\tshort dieciseisbites;\n\t\tint treintaydosbites;\n\t\tlong sesentaycuatrobites;\n\t\tfloat treintaydosbotes_flotantecondobleprecisionde64bites;\n\t\tboolean trueorfalse;\n\t\tchar caracterunidoce;\n\n    byte numeroMuyPequeño = 120; // Entero entre -128 e 127\n    short numeroPequeño = 31465; //  Entero entre -32768 y 32767\n    int numero = 1000000; // Entero entre -2.147.483.648 y 2.147.483.647\n    long numeroMasGrande = 2000000000L; // Entero entre -9.223.372.036.854.775.808 e 9.223.372.036.854.775.807\n    float decimalPequeño = 14.3333F; // Decimal de 4 bytes\n    boolean datoLogico = false; // Almacena valores true o false\n    char caracter = '@'; // Caracteres unicode de 2 bytes\n    double decimal = 12.1234657; // Decimal de 8 bytes   \n       \n\n\t\tSystem.out.println(\"¡Hola, Java!!\");\n\t\t\n\t\t\n\t\t\n\t}\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/jrgim.java",
    "content": "public class Jorge {\n    // Lenguaje elegido: Java https://www.java.com/es/\n    /*\n     * Tipos de comentarios //\n     */\n    public static void main(String[] args) throws Exception {\n        int a = 0;\n        long b = 0L;\n        float c = 9.4f;\n        double d = 3.5;\n        char e = 'a';\n        String f = \"Hola\";\n        boolean g = true;\n        System.out.println(\"!Hola, Java!\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/juanca2805.java",
    "content": "public class juanca2805 {\n \n    // Lenguaje elegido: Java https://www.java.com/es/\n   /* Tipos de comentario\n     que existen :)\n    */\n   /*\n    * Otro tipo de comentario\n    * \n    */\n   //Crear una variable y una constante si el lenguaje lo soporta\npublic static void main(String[] args) throws Exception { \n\n   int  Number = 3;\n   String Cadena = \"hola\";\n   boolean flag = false;\n\n\n   // Constante\n   final String constante = \"Java!\";\n\n   //Salida por consola \n\n   System.out.println(Cadena + \" \" + constante);\n}\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/kgrc05.java",
    "content": "package paquete;\n\n/*\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n */\npublic class KGRC {\n\n\t// https://www.java.com/es/\n\n\t// SINTAXIS 1 DE COMENTARIO\n\t/* SINTAXIS 2 DE COMENTARIO MÚLTIPLE */\n\t/** SINTAXÍS 3 PARA ANOTACIONES EN EL CÓDIGO */\n\n\tint var = 1; // variable\n\tfinal double PI = 3.1416; // constante\n\n\tbyte var_byte = -128;\n\tshort var_short = -32768;\n\tint var_int = -2147483648;\n\tlong var_long = 41324394823l; // REQUIERE \"L\" AL FINAL\n\tfloat var_float = 3.1365243f; // REQUIERE \"F\" AL FINAL\n\tdouble var_double = 3.2392482923209;\n\tchar var_char = '\\0';\n\tboolean var_boolean = true && false;\n\n  System.out.println(\"¡Hola,Java!\");\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/kilianhc.java",
    "content": "package retosProgramacion;\n\n\npublic class RetoUno {\n\n  \n    public static void main(String[] args) {\n        \n        // url oficial de java: https://www.java.com/es/\n        \n        //Comentario en una línea\n        /*Comentario de\n        varias líneas */\n       \n        //variable y constante\n        int edad = 30;\n        final String nombre = (\"Kilian\");\n        \n        //datos primitivos\n        byte numero = 13;\n        short codigo = 13017;\n        int pin = 123456789;\n        long numeroLargo = 1000000000;\n        float numeroDecimal = 3.75f;\n        double numeroPi = 3.141592653589793;\n        char letra = 'K';\n        boolean logico = true;\n        \n        //imprimir texto por terminal\n        System.out.println(\"¡Hola, Java!\");\n        \n    }\n    \n}\n\n/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/kuroz00.java",
    "content": "public class kuroz00 {\n    public static void Main(String[] args){\n        //hola, https://www.oracle.com/java/\n        /*\n         comentario de varias lineas\n         */\n        // .-.- Datos primitivos.-\n        Integer entero = 10;\n        float flotante = 10;\n        double Fdoble = 10.00; \n        char caracter = 'A';\n        String myString = \"Java\";\n        boolean booleano = true;\n        //Constante\n        final String constante = \"Hola, soy una constante! :D\";\n        System.out.println(\"Hola \" + myString + \"!!!\");\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/lautarorisso.java",
    "content": "// https://www.java.com/en/\n\npublic class LogicaJava {\n\n    public static final double PI = Math.PI;\n    \n    public static void main(String[] args) {\n        \n        // 1.\n        // comentario en una línea\n\n        // 2.\n        /*\n          comentario en varias\n          líneas\n        */\n\n        // 3.\n        String hola = \"¡Hola, Java!\";\n        \n        // 4.\n        byte b = 1;\n        short s = 10;\n        int i = 100 ;\n        long l = 1000;\n        \n        float f = 3.14f;\n        double d = 1.1;\n        \n        char c = 'c';\n        boolean vf = true;\n        \n        // 5.\n        System.out.println(hola);\n        \n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/lautimorales.java",
    "content": "// Solución del reto #00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n\n// - Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n// https://dev.java/    --->    Web oficial del lenguaje de programación Java\n\n// - Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n// Este es un comentario en 1 línea\n/* Este es un\n * comentario en\n * varias líneas\n */\n /** Este comentario es para la herramienta de documentación JavaDoc */\n\n public class lautimorales{\n    public static void main(String[] args){\n        // - Crea una variable (y una constante si el lenguaje lo soporta).\n        int edad;   // Una variable se crea solo con el tipo de dato ('int' en este caso) y el nombre de ('edad' en este caso)\n        final int dni;  // Una constante se crea con la palabra reservada 'final'\n\n        // - Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n        byte enteroMuyPequenio = 110; // Valor mínimo -128 y valor máximo 127\n        short enteroPequenio = 1100; // Valor mínimo -32.768 y valor máximo 32.767\n        int entero = 11110000; // Valor mínimo -2.147.483.648 y valor máximo 2.147.483.647\n        long enteroGrande = 111100000;  // Valor mínimo -9.223.372.036.854.775.808 y valor máximo 9.223.372.036.854.775.807\n        char caracterSimple = 'A';    // Sirve para representar un caracter unicode\n        float decimalMenorPrecision = 10.3232F;    // Se utiliza para representar números con decimales con menor precisión (32 bits)\n        double decimalMayorPrecision = 10.64;   // Se utiliza para representar números con decimales con mayor precisión (64 bits)\n        boolean booleano = true;   //Representa expresiones lógicas (verdadero o falso)\n\n        // - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n        // Opción 1\n        String saludo = \"¡Hola, Java!\";\n        System.out.println(saludo);\n        // Opción 2\n        System.out.println(\"¡Hola, Java!\");\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/llonardo798.java",
    "content": "public class llonardo798 {\n\n    public static void main(String[] args) {\n        \n        // 1. Documentación oficial en https://www.java.com/\n        \n        // 2. Tipos de comentarios.\n        \n        // Para comentarios de una sola línea\n\n        /* \n         * para comentarios de\n         * varias líneas\n         */\n        \n        /**\n         * para comentarios de\n         * varias lineas pero es\n         * formato de documentación\n         * (JavaDoc).\n         */ \n        \n        // 3. Vairables y Constantes.\n        String nombre = \"Leonardo Aedo Jimenez\";\n        final int numeros = 21;\n\n        // 4. Tipos de datos primitivos.\n        byte edad = 30;                             // 8 bits, rango de valores permitidos -128 hasta 127\n        short anoNacimiento = 1990;                 // 16 bits, rango de valores permitidos -32768 hasta 32767\n        int poblacionCiudad = 5000000;              // 32 bits, rango de valores permitidos -2147483648 hasta 2147483647\n        long distanciaTierraSol = 149600000000L;    // 64 bits, rango de valores permitidos -9223372036854775808 hasta 9223372036854775807\n        float precioProducto  = 19.99f;             // 32 bits, rango de valores permitidos 1.4e-045 hasta 3.4e+038\n        double gravedadTierra = 9.80665;            // 64 bits, rango de valores permitidos -1.79769313486232e308 hasta 1.79769313486232e308\n        char primeraLetra = 'L';                    // 16 bits, rango de valores permitidos '\\u0000' hasta '\\uffff' (Caracteres Unicode)\n\n        // 5. Imprimir en consola.\n        System.out.println(\"Hola, Java!\");\n\n    }\n    \n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/marce1084.java",
    "content": "public class marce1084 {\n    public static void main(String[] args) {\n        //https://www.java.com/es/\n\n        //Esto es un comentario simple\n\n        /*Esto tambien es un\n        * comentario de\n        * varias lineas\n        */\n\n        String nombre = \"Ariel\"; //Variable\n\n        int valor = 253; //Constante\n\n        //Datos primitivos\n        int num1 = 23784;\n        double num2 = 56.54;\n        float num3 = 23.4f;\n        byte num4 = 12;\n        short num5 = 124;\n        long num6 = 891293;\n        char letra7 = 'A';\n        boolean valor8 = true;\n        String frase9 = \"Hola a todos\";\n\n        System.out.println(\"¡Hola, Java!\");\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/mariovelascodev.java",
    "content": "public class mariovelascodev {\n    public static void main(String[] args){\n        //Sitio web oficial del lenguaje: https://www.java.com/es/\n\n        //Comentario de una línea\n\n        /*\n        Este es un comentario\n        de varias líneas en\n        el lenguaje de programación Java\n        */\n\n        //Constante\n        final double PI = 3.14;\n\n        //Variables\n        String name = \"Mario\";\n        int age = 36;\n        double height = 1.80;\n        boolean power = true;\n        char gender = 'F';\n        byte byteNumber = 12;\n        long longNumber = 123657733;\n        short shortNumber = 123;\n\n        System.out.println(\"¡Hola Java!\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/martinaq.java",
    "content": "public class martinaq {\n\n    // Static variables have to be declared before any instance and can be shared among other instances.\n    static final String myVar = \"This is a const variable in Java\"; \n    public static void main(String[] args) {\n        /*\n        * EJERCICIO:\n        * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n        *   lenguaje de programación que has seleccionado.\n        * - Representa las diferentes sintaxis que existen de crear comentarios\n        *   en el lenguaje (en una línea, varias...).\n        * - Crea una variable (y una constante si el lenguaje lo soporta).\n        * - Crea variables representando todos los tipos de datos primitivos\n        *   del lenguaje (cadenas de texto, enteros, booleanos...).\n        * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n        *\n        * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n        * debemos comenzar por el principio.\n        */\n\n        /* 1. Crea un comentario en el código y coloca la URL del sitio web oficial del\n         *   lenguaje de programación que has seleccionado. */\n\n        // https://www.java.com/es/\n\n        /* 2. Representa las diferentes sintaxis que existen de crear comentarios\n         *   en el lenguaje (en una línea, varias...). */\n\n        /* Comentario en\n         * varias\n         * lineas. */\n\n        // 3. Crea una variable (y una constante si el lenguaje lo soporta).\n        String username = \"martin-aq\";\n        System.out.println(username);\n\n        // 4. Crea variables representando todos los tipos de datos primitivos.\n        boolean a = true; // 1 bit\n        char b = '$'; // 2 bytes, char uses 2 bytes due to the usage of Unicode.\n        byte c = 120; // 1 byte\n        short d = 250; // 2 bytes\n        int e = 36432; // 4 bytes\n        long f = 9223372036854775L; // 8 bytes\n        float g = 36739.24f; // 4 bytes, same as int data type\n        double h = 9223372036854775.12d; // 8 bytes, same as long data type\n\n        System.out.printf(\"boolean: %s\\nchar: %c\\nbyte: %d\\nshort: %d\\nint: %d\\nlong: %d\\nfloat: %f\\ndouble: %f\\n\", a,b,c,d,e,f,g,h);\n\n        // 5. Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n        System.out.println(\"Hello Java!\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/martinbohorquez.java",
    "content": "/**\n * 00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n * @author martinbohorquez\n */\npublic class martinbohorquez {\n\n    // https://www.oracle.com/java/\n\n    // Esto es un comentario en una sola línea.\n\n    /*\n     * Esto es un comentario\n     * usando varías líneas\n     * para describir el código.\n     */\n\n    public static void main(String[] args){\n        // Variable\n        String saludo = \"¡Hola, \";\n\n        // Constante\n        final String PROGRAMMING_LANGUAGE = \"Java!\";\n\n        // Datos Primitivos\n        char letter = 'M';\n        printMessage(\"letter\", letter);\n\n        byte age = 29;\n        printMessage(\"age\", age);\n\n        short year = 2024;\n        printMessage(\"year\", year);\n        int quantity = 1234567890;\n        printMessage(\"quantity\", quantity);\n        long large = 1234567890123456789L;\n        printMessage(\"large\", large);\n\n        float pi = 3.1415926535f;\n        printMessage(\"pi\", pi);\n        double e = 2.718281828459045235360d;\n        printMessage(\"e\", e);\n\n        boolean esVerdadero = true;\n        printMessage(\"esVerdadero\", esVerdadero);\n        boolean esFalso = false;\n        printMessage(\"esFalso\", esFalso);\n\n        System.out.println(saludo + PROGRAMMING_LANGUAGE);\n\n    }\n\n    private static void printMessage(String string, Object object) {\n        System.out.println(\"El valor de '\" + string + \"' es: \" + object + \", y su tipo es: \"\n                + object.getClass().getSimpleName().toLowerCase());\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/matisuarezm.java",
    "content": "//00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n\npublic class Reto_Programacion_00 {\n\n    public static void main (String[] args){\n\n        //1.- Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n\n                // java.com/es\n\n        //2.- Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n\n                // Sintaxis para crear comentarios lineales\n\n                /*\n                    Esta es la forma en que\n                    puedes comentar en\n                    varias lienas\n                 */\n\n        //3.- Crea una variable (y una constante si el lenguaje lo soporta).\n\n                String variable;\n                final constante;\n\n        //4.- Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n\n                byte numPequeno;\n                short numMediano;\n                int numGrande;\n                long numGigante;\n                float numFlotante;\n                double numConDecimiales;\n                char caracter;\n                boolean truefalse;\n\n        //5.- Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\n                System.out.println(\"¡Hola, Java!\");\n\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/maximilianofuentesalcocer-cibernético.java",
    "content": "//Sitio web: java: https://www.java.com/es/\n\n//Comentario en una línea.\n\n/*\nComentarios en\nvarias\nlíneas\n*/\n\n//varible.\nboolean soyNuevo = true;\n//constante.\nfinal int edadFalsa = 25;\n\n//Datos primitivos.\nint edad = 16;\nboolean estaEncendido = false;\nString nombre = \"JUAN\";\ndouble pi = 3.1416d;\nfloat flota = 5.23f;\nchar caracter = \"A\"\nlong largo = 16L;\n\n//imprimir variable.\nSystem.out.println(\"El estaEncendido es\" + edadFalsa)\nSystem.out.println(\"El edadFalsa es\" + estaEncendido\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/mensius87.java",
    "content": "// Comentario de una línea en Java. Sitio oficial de JAVA: https://www.java.com/es/\n\n/*\n  Este es un comentario multilínea en Java.\n  Puedes escribir varias líneas y todas serán consideradas como parte del comentario.\n*/\n\npublic class Ejercicio {\n    public static void main(String[] args) {\n        // Creación de una variable\n        String saludo = \"Hola MoureDev\";\n\n        // Creación de una constante en Java\n        final double CONSTANTE = 3.14;\n\n        // Variables representando tipos de datos primitivos\n        int entero = 20;\n        double flotante = 1.4;\n        String texto = \"Java\";\n        boolean booleano = true;\n\n        // Imprimir por terminal\n        System.out.println(\"¡Hola, \" + texto + \"!\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/miguelex.java",
    "content": "public class miguelex {\n\n    // Documetación en https://www.java.com/\n    public static void main(String[] args) {\n        // Comentario en una sola linea\n\n        /*\n         * Comentario\n         * en varias\n         * lineas\n         */\n\n        // Variables y constantes\n        String lenguaje = \"Java\";\n        final String constante = \"Soy Dev\";\n\n        // Tipos primitivos\n        byte diasMes = 31;\n        short diasLustro = (12 * 31) * 5;\n        int velocidadLuz = 299792458;\n        long anioLuz = velocidadLuz * 365;\n        float pi = 3.1415926535f;\n        double e = 2.718281828459045235360;\n        char letraA = 'a';\n        char letraANumerico = 61;\n        boolean verdadero = true;\n        boolean falso = false;\n\n        // Salida por consola\n        System.out.println(\"¡Hola, \" + lenguaje + \"!\");\n\n    }\n\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/mtirador.java",
    "content": "public class mtirador {\n    public static void main(String[] args) {\n        //https://www.java.com/es/\n\n        /*diferente comentario para varias lineas\n         * \n         * ......\n         */\n        /**\n         * Comentarios de documentación\n         */\n\n         /*Declaracion de variables y constante */\n        int unidades =12;\n        final float precio = 9.99f;\n\n\n        /*Crea variables representando todos los tipos de datos primitivos\n        *   del lenguaje (cadenas de texto, enteros, booleanos...).*/\n\n        int num=5;\n        short snum=9;\n        long lnum= 3;\n        double dnum=3.4;\n        float fnum=5.4f;\n        boolean condi=true;\n        byte bnum=2;\n        char a= 'b';\n\n        //imprimir hola + lenguaje\n\n        String palabra=\"Java\";\n\n        System.out.println(\"¡Hola,\"+ palabra +\"!\");\n    }    \n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/nolemoon.java",
    "content": "public class Nolemoon {\n    public static void main(String[] args) {\n       // https://www.oracle.com/ar/java/\n        //Diferentes\n        /*\n         formas de\n         comentar\n         */\n\n        String nombre = \"María\"; //variable\n        final int edad = 23; //constante\n\n        //tipos de datos primitivos\n\n        int entero = 10;\n        float decimal = 5.4f ;\n        double doble = 32.4324;\n        boolean verdaderoFalso = true;\n        char letra = 'n';\n\n        //tipos de datos no primitivos\n        String saludo = \" Hola cómo estás ?\";\n\n        //Saludo en consola\n        System.out.println(\"Hola, JAVA!\");\n\n\n\n        }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/nwpablodeveloper.java",
    "content": "\n\n// #00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n\n// https://www.java.com/es/\n\npublic class nwpablodeveloper {\n        \n    // Variable\n    private static String unaVariable = \"! Hola \";\n    \n    // Constante\n    private static final String _lenguaje  = \"desde Java ¡\" ; \n\n    // Declaracion de variables sin datos ( undefinded )\n    private static String tipoStringUndefine;\n    \n    // Variables con tipos de datos primitivos enteros\n    private static byte tipoByte = 127;              // Max permitido\n    private static short tipoShort = 32767;          // Max permitido\n    private static int tipoInteger = 2147483647;     // Max permitido\n\n    // Variables con tipos de datos primitivos flotantes\n    private static long tipoLong = 9223372036854775807L;       // Max permitido poner L al final\n    private static float tipoFloat = 3.4028235E38F;            // Max permitido. Poner F para representar numeros flotantes\n    private static double tipoDouble = 1.7976931348623157E308; // Max permitido\n\n    // Variables con tipos de datos primitivos character\n    private static char tipoCharSimbolo = 'P';\n    private static char tipoCharUnicode = '\\u0050'; // https://en.wikipedia.org/wiki/List_of_Unicode_characters\n    private static char tipoCharDecimal = 80;\n  \n    // Variables con tipos de datos primitivos de decision\n    private static boolean tipoBoolean = true;\n\n    public static void main(String[] args) {\n        \n        System.out.println( unaVariable + _lenguaje );\n        \n    }\n\n\n    \n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/oixild.java",
    "content": "\n// https://www.java.com\n\npublic class oixild {\n    public static void main(String[] args) {\n\n        // Comentario de una sola línea\n\n        /*\n         * Comentario en\n         * varias líneas\n         */\n\n        // variable y constante\n        String lenguajeRetos = \"Esto es una cadena de texto (String) \";\n        final String java = \"Java\";\n\n        // Variables representando todos los tipos de datos primitivos del lenguaje\n        byte miByte = 1;\n        short miShort = 55;\n        int miInt = 7414;\n        long miLong = 831823821;\n        float miFloat = 1.1f;\n        double miDouble = 5.5;\n        char miChar = 'a';\n        boolean miBoolean = true;\n\n        System.out.println(\"¡Hola,\" + java + \"!\");\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/pakiuh.java",
    "content": "/**\n * https://docs.oracle.com/en/java/\n */\n\n// Comentario de una línea\n\n/**\n * Esto es un comentario en varias líneas.\n */\npublic class pakiuh {\n\n// Define una constante\n\n    private static final int MY_CONSTANT = 10;\n    \n    public static void main(String[] args) {\n\n        // Declaramos varios ejemplos de variables primitivas\n        byte myByte = 10;\n        short myShort = 100;\n        int myInt = 1000;\n        long myLong = 10000L;\n        float myFloat = 3.14f;\n        double myDouble = 3.14159;\n        char myChar = 'A';\n        boolean myBoolean = true;\n\n        //Imprimimos por consola el \"¡Hola, Java!\"\n            System.out.println(\"¡Hola, Java5!\");\n        \n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/pguillo.java",
    "content": "//Sitio oficial de java: https://www.oracle.com/es/ \n\n/**\n * pguillo\n */\n\n public class pguillo {\n    //Se puede generar una constante a través de la palabra reservada final\n    public static final String CONSTANTE = \"CONSTANTE\";\n\n    public static void main(String[] args) {\n        // variables\n        boolean booleana = true;\n        float flotante = 6.9f;\n        int integer = 2;\n        char character = 'H';\n        byte bte = 0;\n        short shor = 1;\n        long lon = 33L;\n        double doble = 1.23d;\n        \n        System.out.println(\"Hola, Java\");\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/queralesDev.java",
    "content": "\npublic class queralesDev {\n    public static void main(String[] args) {\n        /*\n        https://www.java.com/es/\n         */\n\n        /*\n        Las diferentes sintaxis para crear comentarios son las siguientes\n         /* Esto es Comentario de varias lineas\n        //comentario de una sola linea\n        ///comentario de una sola linea tambien\n         */\n\n        int numeroEntero;\n        String JAVA = \"Soy una constante\";\n\n        byte numero;\n        int numeroEntero2;\n        short numeroCorto;\n        long numeroLargo;\n        double numeroConComa;\n        char caracter;\n        float numeroConComa2;\n\n        System.out.printf(\"Hola soy java\");\n\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/rballestercoll.java",
    "content": "//#00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO;\n/* EJERCICIO:\n * 1- Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * 2- Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * 3- Crea una variable (y una constante si el lenguaje lo soporta).\n * 4- Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * 5- Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n */\npublic class rballestercoll {\n\n    // 1 - WEB OFICIAL DE JAVA : https://www.java.com/es/\n\n    // 2 - DIFERENTES SINTAXIX PARA CREAR COMENTARIOS\n\n        // Comentario de una línea con dos slash\n\n        /*\n         * Comentario en\n         * varias líneas.\n         * Con slash y asterisco.\n         */\n\n    public static void main(String[] args) {\n\n        // 3 - CREA UNA VARIABLE Y UNA CONSTANTE\n\n            int edad = 36; // (VARIABLE)Antes de JDK 10, las variables se escribian indicando el tipo.\n\n            var meses = 12; // (VARIABLE) A partir de JDK 10 las variables indistintamente del tipo que sean pueden declararse con \"var\". solo pueden declararse dentro de métodos y bloques de inicialización, pero no como variables de instancia o estáticas.\n\n            final double precio = 3.6; //(CONSTANTE) Las constantes como tal en Java no existen, se coloca la partícula \"final\" delante del tipo y la variable se vuelve inmutable.\n\n        // 4 - CREA UN LISTADO DE VARIABLES CON TODOS LOS TIPOS DE DATOS PRIMITIVOS\n\n            int temperatura = -6;\n            boolean existe = true;\n            byte amigos = 13;\n            short fecha = 4567;\n            char clase = 'B';\n            long hectareas = 65L;\n            float medida = 100F;\n            double medidas = 23.789;\n\n        // 5 - IMPRIME LA FRASE \"HOLA MUNDO EN (JAVA)\"\n\n            String lenguajeProgramacion = \"Java\";\n            System.out.println(\"Hola Mundo en \" + lenguajeProgramacion);\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/reneguzman7.java",
    "content": "// #00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n// URL del sitio web oficial de Java: https://www.java.com/es/\n// Comentario de una línea\n/*\n * Comentario \n * en\n * bloque \n */\n\npublic class reneguzman7 {\n    public static void main(String[] args) {\n        // Creación de una variable\n         String miVariable = \"Hola\";\n         // Creación de una constante\n         final double PI = 3.1416;\n\n        byte  datoTipoByte; \n\t\tshort datoTipoShort; \n\t\tint datoTipoEntero; \n\t\tlong datoTipoLargo; \n\t\tfloat datoTipoFloat; \n\t\tdouble datoTipoDouble;\n\t\tchar datoTipoChar;\n\t\tboolean datoTipoBoolean; \n\t\tString datoTipoString; \n\n        System.out.println(\"Hola, Java!\");\n    }\n }"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/ricarditodev.java",
    "content": "public class ricarditodev {\n    public static void main(String[] args) {\n        //https://www.java.com/\n        //https://dev.java/\n        //https://docs.oracle.com/en/java/\n\n        //Esta es la manera de crear comentarios de una linea\n        /*\n        Esta es la manera de\n        crear comentarios de\n        varias lineas\n        */\n        /**\n         * Esto es Javadoc, una manera mas especial de crear comentarios en java\n         * :)\n         */\n\n        String username = \"ricarditodev\";\n        final String myUsername = \"esto es una constante\";\n\n        //todos los tipos de datos primitivos\n        //tipo de dato byte: 1 byte - Números enteros entre -128 y 127\n        byte num = 24;\n\n        //tipo de dato short: 2 bytes - Números enteros entre -32768 y 32767\n        short num2 = 2001;\n\n        //tipo de dato int: 4 bytes - Números enteros entre -2147483648 y 2147483647\n        int num3 = 2025;\n\n        //tipo de dato long: 8 bytes - Números enteros entre -9223372036854775808 y 9223372036854775807\n        long num4 = 10000L;\n\n        //tipo de dato float: 4 bytes-  Números de coma flotante de hasta 6 y 7 dígitos decimales.\n        float num5 = 3.14f;\n\n        //tipo de dato double: 8 bytes - Ídem anterior pero de hasta 15 dígitos decimales.\n        double num6 = 3.14567537;\n\n        //tipo de dato boolean: 1 bit - Valores true o false.\n        boolean num7 = true;\n\n        //tipo de dato char: 2 bytes - Un caracter simple dentro de los valores ASCII.\n        char letra = 'a';\n\n        System.out.println(\"¡Hola, Java!\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/robermejia.java",
    "content": "// #00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA, MUNDO.\n/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n/* COMENTARIO \nMULTIPLES\nLINEAS */\n// SITIO WEB OFICIAL DE JAVA https://www.java.com/es/ \npublic class robermejia {\n    public static void main(String[] args) {      \n        byte my_byte = 12; // Entero\n        short my_short = 9898; // Entero\n        int my_int = 2024;  // Entero\n        long my_long = 1234567890; // Entero\n        char my_char = 'A'; // Caracteres\n        float my_float = 9.8f; // Decimal\n        double my_double = 9.8; // Decimal\n        boolean my_bolean = true; // Booleans\n        \n        final double pi = 3.14; // Constante     \n        System.out.println(\"Hola, mundo\");   \n    }\n}\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/rumacar05.java",
    "content": "public class rumacar05 {\n\n    // https://www.java.com/es/\n\n    // Comentario en una sola línea\n    /*\n     Comentario \n     en varias \n     lineas\n    */\n    public static void main(String[] args) {\n        String saludo = \"Hola\"; // Variable\n        final String LENGUAJE = \"Java\"; // Constante\n\n        // Variables primitivas\n        byte a = 10;\n        short b = 100;\n        int c = 1000;\n        long d = 10000L;\n        double e = 100000.0;\n        float f = 1000000.0f;\n        char g = 'a';\n        boolean h = true;\n\n        System.out.println(\"¡\" + saludo + \", \" + LENGUAJE + \"!\");\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/santiagopereiraviroga.java",
    "content": "package com.github.mouredev.roadmap.cero;\r\n\r\npublic class santiagopereiraviroga {\r\n\r\n    public static void main(String[] args) {\r\n\r\n        // Sitio oficial del lenguaje de programación Java: https://www.java.com/en/\r\n\r\n\r\n        // Esta sintáxis permite realizer un comentario de una sola línea\r\n\r\n        /* Esta sintáxis\r\n         permite realizar\r\n         un comentario\r\n         de más\r\n         de una\r\n         línea\r\n        */\r\n\r\n        /**\r\n         *\r\n         * @author SantiagoPereiraViroga\r\n         *\r\n         * Esta sintáxis permite realizar comentarios\r\n         * con el fin de documentar tu código en Java\r\n         *\r\n         *\r\n         */\r\n\r\n\r\n        String cadenaDeTexto = \"Esta es una cadena de texto en Java.\";\r\n\r\n        char caracterUnico = 'a'; // 'a', '1', '?' ...\r\n\r\n        byte rangoDeEnterosMenor = 0; // De -128 a 127\r\n\r\n        short rangoDeEnterosCorto = 0; // De -32,768 a 32,767\r\n\r\n        int rangoDeEnterosEstandar = 0; // De -2,147,483,648 a 2,147,483,647\r\n\r\n        long rangoDeEnterosExtenso = 0; // De -9,223,372,036,854,775,808 a 9,223,372,036,854,775,807\r\n\r\n        float rangoDeDecimalesEstandar = 3.14f; // Considera 7 decimales\r\n\r\n        double rangoDeDecimalesExtenso = 3.14; // Considera unos 15 o 16 decimales\r\n\r\n        boolean verdaderoOFalso = true; // TRUE o FALSE\r\n\r\n\r\n        final String UNA_CONSTANTE = \"Esta es una constante en Java.\";\r\n\r\n\r\n        System.out.println(\"¡Hola, Java!\");\r\n\r\n    }\r\n}\r\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/serg_pq.java",
    "content": "public class serg_pq {\n\n    public static void main(String[] args) {\n        // Web oficial: www.java.com\n\n        // Comentario de una sola linea\n\n        /*\n        Comentario de\n        multiples lineas\n         */\n\n\n        String username = \"Sergio\"; // Declaración de una Variable\n        final String country = \"Colombia\"; // Declaración de una Constante\n\n\n        // Tipos de datos primitivos\n        // Datos enteros\n        byte myByte = 123;\n        short myShort = 12345;\n        int myInt = 1234567890;\n        long myLong = 1234567890987654321L;\n\n        // Datos flotantes\n        float myFloat = 1.23f;\n        double myDouble = 1.23456;\n\n        // Dato caracter\n        char myChar = 'A';\n\n        // Dato booleano\n        boolean myBoolean = true;\n\n\n        // Imprimir texto\n        System.out.println(\"¡Hola, Java!\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/simonguzman.java",
    "content": "\npublic class simonguzman {\n    //https://dev.java/\n\n    //Comentario en una linea\n\n    /**\n     * \n     * Comentario en varias lineas(Documentacion)\n     */\n\n    /*\n    Documentacion en varias lineas\n     */ \n    public static void main(String[] args) {\n        \n        //Datos primitivos y creacion de variables\n        //Variables con valores numericos\n        byte Byte = 127;\n        short corto = 1;\n        int entero = 2;\n        long numerogrande = 3;\n        float numeroFlotante = 3.3f;\n        double numeroDoble = 3.3;\n\n        //Representaciones de valores numericos\n\n        //Numero decimal\n        int decimalValue = 16;\n        //Numero hexadecimal\n        int hexadecimalValue = 0x1a;\n        //Numero binario\n        int binaryValue = 0b11010;\n\n        //Expresiones para punto flotante\n        double double1 = 123.4;\n\n        //Notaciones diferentes\n        double double2 = 1.234e2;\n        float f1 = 123.4f; \n\n        //Variables de texto(Lineas de caracteres y cadenas de texto)\n        String cadena = \"Texto\";\n        char Caracter = 'a';\n        boolean result = true;\n\n        System.out.println(\"¡Hola, java!\");\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/sniker1223.java",
    "content": "//https://www.oracle.com/mx/java/\n\n/** Document \n * Comment */\n\n//Single Line Comment\n\n/* Multiple\nLine \nComment */\n\npublic class sniker1223 {\n\n  public static final String FIRST_NAME = \"Sara\";\n  public static void main(String[] args){\n\n    //primitive Data types\n    boolean var1 = true;\n    char var2 = 'A';\n    byte var3 = 1;\n    short var4 = 1;\n    int var5 = 1;\n    long var6 = 1l;\n    float var7 = 1.1f;\n    double var8 = 1.1d;\n    \n    System.out.print(\"¡Hola, JAVA!\");\n  }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/swifty0705.java",
    "content": "package com.mouredev.retosprogramacion.roadmap.cero;\n\npublic class swifty0705 {\n    // URL oficial: https://www.java.com/es/\n    // JDK: https://www.oracle.com/co/java/technologies/downloads/\n    // IDE: https://www.jetbrains.com/es-es/idea/\n\n    public static void main(String[] args) {\n        // comentario de una linea\n        /*\n         * comentario de varias lineas\n         */\n\n        /**\n         *\n         *  JavaDocs\n         *\n         * */\n\n        // variables\n        byte b = 100;\n        short s = 10000;\n        int i = 100000;\n        long l = 100000L;\n        float f = 10000.0f;\n        double d = 10000.0d;\n        char c = 'A';\n        String usuario = \"Swifty0705\";\n\n        var integer = 100;\n\n        //constante\n        final double PI = 3.141516;\n\n        System.out.println(\"Hola Java! soy \"+usuario);\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/vikinghost.java",
    "content": "public class vikinghost {\n\n    public static void main(String[] args) {\n        \n        //Este es el enlace a la web de java = https://www.java.com/es/\n\n        //comentario de una linea\n        \n        /*comentario\n                de bloque*/\n        \n         /**\n          *  Comentario de documentación.\n          */\n        \n        //Crea una variable y una constante.\n\n        short variableInicial;\n        \n\n        final int value = 234; \n\n        //Recogidos los tipos primitivos\n        String texto = \"cadena de texto\";\n        byte num0 = -128;\n        short num1= 3;\n        int num2= 2;\n        long num3 = 92211703;        \n        float num4 = 2.1233f;\n        double num5 = 3.222232;\n        char caract = 'a';\n        boolean value2 = true;\n\n        //Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\n        System.out.println(\"Hola, Java!\");\n    }\n        \n    \n}    \n   \n\n       \n\n\n\n\n\n\n\n\n    \n\n\n\n\n\n\n\n\n\n\n "
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/vixxtory.java",
    "content": "public class vixxtory {\n    public static void main(String[] args) {\n        // https://www.java.com/es/\n\n        // Comentario de una sola linea\n\n        /* Comentario\n            de\n            multiples\n            lineas\n         */\n\n        /** Comentarios de documentacion o JavaDocs\n         * Estos comentarios no solo documentan el código fuente, sino el proyecto como tal.\n         * Tambien indican los componentes del código fuente, tales como parámetros, tipos de retorno, entre otros.\n         * Estos componentes se preceden por un @, por ejemplo en el metodo main:\n         * @param args[] es un arreglo con los parámetros que reciba por consola.\n         */\n\n        // Las VARIABLES se almacenan en un espacio de memoria de la computadora y se utilizan para manejar y/o manipular información dentro de un sistema\n        // Declaración de Variable constante: una vez asignado el valor inicial no se puede cambiar durante la ejecucion del programa\n        final double IVA = 21.5;\n        //Variable: Pueden cambiar su valor a los largo del tiempo.\n        int edad = 29;\n\n        // TIPOS DE DATOS PRIMITIVOS\n        /**\n         * Numericos Enteros\n         */\n        //byte: 8 bits de almacenamiento | valores en el rango [-128, 127]\n        byte miByte = 5;\n        //short: 2 bytes de almacenamiento | valores en el rango [-32.768, 32.767]\n        short miShort = 12596;\n        //int: 4 bytes de almacenamiento | valores en el rango  [-2 elevado 31 a 2 elevado 31-1]\n        int miInt = 10;\n        //long: 8 bytes de almacenamiento | valores en el rango  [-2 elevado a 63 a 2 elevado 63-1]\n        long miLong = 1000000000;\n        /**\n         * Numericos de tipo punto flotante\n         */\n        //float: 4 bytes de almacenamiento | valores en el rango [1.4x10 elevado -45 a 3.4028235x10 elevado 38]\n        float miFloat = 10.58f;\n        //double: 8 bytes de almacenamiento | valores en el rango 4.9x10 elevado -324 a 1.7976931348623157x10 elevado 308.\n        double miDouble = 10.58;\n        /**\n         * Booleanos y caracteres\n         */\n        //boolean: 1 byte de almacenamiento | valores porsibles [true/false]\n        boolean miBoolean = false;\n        //char: 2 bytes de almacenamiento | valores posibles [caracteres simples]\n        char miChar = 'P';\n        /**\n         * Datos Estructurados\n         */\n        //String: cadena de caracteres\n        String miString = \"Hola Mundo\";\n\n        System.out.println(\"¡Hola, Java!\");\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/xHALOIDx.java",
    "content": "public class Ejercicio00 {\n    public static void main(String[] args) {\n        // Url del sitio web oficial del lenguaje Java:  https://www.java.com/\n\n        // Comentarios en una sola linea en java\n        /* Este es un comentarios de varias lienas en java se puede usar para explicar detalladamente o explicar cosas largas\n        */\n\n        // Crear una variable y una constante.java\n        int edad = 27; // Variable entera\n        final double PI = 3.14159; // Constante de tipo double\n\n        // Crear variables representando todos los tipos de datos primitivos en Java\n        String nombre = \"Luis Eduardo\"; // Cadena de texto\n        int numeroEntero = 100; // Entero\n        double numeroDecimal = 99.99; // Decimal\n        boolean esProgramador = true; // Booleano\n        char inicial = 'L'; // Carácter\n        long numeroGrande = 1000000L; // Entero largo\n        float numeroFlotante = 10.5f; // Decimal flotante\n        byte numeroPequeno = 127; // Entero pequeño (byte)\n        short numeroCorto = 32767; // Entero corto\n\n        //Imprimir por terminal el texto \"Hola y el lenguaje\"\n        System.out.println(\"Hola soy luis eduardo y estoy aprendiendo Java\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/xebaztiandev.java",
    "content": "public class xebaztiandev {\n\n    public static void main(String[] args) {\n        /*\n        Url of the official java site: https://www.java.com/es/\n        */\n\n        // SYNTAX TYPES FOR COMMENTS :)\n\n        // This is a single line comment.\n\n        /*\n        This is a comment of several lines.\n        It is useful to describe or reference something in our code.\n        */\n\n        /**\n         * Comments for documenting our code, it can be classes, methods, attributes, interfaces, etc.\n         * I show you an example in line [numero de linea].\n         */\n\n        // Here a variable is created without storing a value. In addition, variables must be defined using the camelCase convention.\n        int myVariable;\n        // Here in our variable, we store a value in memory.\n        myVariable = 200;\n\n        /*\n        By convention, the names of the constants in Java are written in capital letters and underlined.\n        Below is an example of a constant variable.\n        */\n        final double PI_VALUE = 3.1416;\n\n        // Primitive data types in Java, we can find them in: https://dev.java/learn/language-basics/primitive-types/\n        byte myByte = 100; // 8-bit integer type (-128 to 127).\n        short myShort = 10000; // 16-bit integer type (-32,768 to 32,767).\n        int myInt = 100; // 32-bit integer type, with a minimum value of -2^31 and a maximum value of 2^31 -1.\n        long myLong = 900000000L; // 64-bit integer type, with a minimum value of -2^63 and maximum value of 2^63 -1.\n        float myFloat = 10.001f; // 32-bit single-precision floating point type.\n        double myDouble = 1.80d; // 64-bit double-precision floating point type.\n        boolean myBoolean = true; // A type of Boolean data that track true/false conditions.\n        char myChar = 'a'; // 16-bit Unicode character.\n\n        // Note: String and integer are not primitive data types, they are special classes instead.\n        String message = \"¡Hola, java!\";\n        System.out.println(message);\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/xurxogz.java",
    "content": "public class xurxogz {\n    public static void main(String[] args) {\n        // #00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n\n        // URL oficial de Java: https://www.java.com/es/\n        /*\n         * Comentario\n         * De\n         * Varias\n         * Lineas\n         */\n\n        String myVar = \"Variable\";\n        final String myConst = \"Constante\";\n\n        byte myByte = 10;\n        short myShort = 20;\n        int myInt = 10000;\n        long myLong = 10200;\n        char myChar = 'a';\n        boolean myBool = false;\n\n        System.out.println(\"¡Hola, Java!\");\n\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/yaretzyrb.java",
    "content": "//Sitio oficial de Java: https://www.java.com/es/\n\n//Comentario simple\n\n/*Comentario de \n* varias\n* líneas\n*/\n\npublic static void main(String[] args) {\n\n    // Variable y constante\n    String a = \"Esto es una variable\";\n    \n    final double b = 3.1416;\n    \n    // Tipos de datos\n    byte c = 1;\n    int d = 2;\n    double e = 3.3;\n    long f = 4;\n    float g = 5;\n    short h = 6;\n    char i = 7;\n    boolean j = true;\n    String k = \"Hola\";\n    \n    System.out.println(k +\" Java\");\n    }\n    "
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java/zemanue.java",
    "content": "\n// EJERCICIO #00: SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n\npublic class zemanue {\n\n    // URL del sitio web oficial de Java: https://www.java.com/es/\n\n    // Ejemplos de diferentes tipos de comentarios:\n        // Comentario de una línea\n        /* Comentario\n         * de\n         * varias\n         * líneas */\n\n    // Creación de variables y constantes:\n    final String constante = \"roadmap\";\n    byte b = 127;\n    short corto = 32767;\n    int entero = 99999999;\n    long largo = 1234567890;\n    float flotante = 3.1f;\n    double decimal = 124.912;\n    char caracter = 'c';\n    boolean booleano = true;\n    \n    // Impresión de \"¡Hola, Java!\"\n    public static void main(String[] args) {\n        System.out.println(\"¡Hola, Java!\");\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/08BLL.js",
    "content": "/* Esta es la documentación que voy a seguir: https://developer.mozilla.org/es/docs/Web/JavaScript */\n\n// Esta es la sintaxis para comentar en una línea\n\n/*\n    Esta es la sintaxis para comentar en varias líneas\n*/\n\n//Variables\n//let es más utilizado, declara una variable local con ámbito de bloque\nlet saludar=\"Hola\";\n//var declara una variable\nvar saludar1=\"Hola\";\n\n//Constante\nconst saludar2=\"Hola\";\n\n//Variables con todos los tipos de datos primitivos\n\nlet indefinido=undefined;\nlet booleano=true;\nlet numero=1;\nlet decimal=1.13;\nlet nombre=\"Pedro\";\nlet nulo=null;\n\n//Imprimir por terminal\nconsole.log(\"¡Hola, JavaScript!\");\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/1978acb.js",
    "content": "//EJERCICIO:\n\n//Este es un comentario con la URL del la web oficial de JavaScript:  * https://developer.mozilla.org/es/docs/Web/JavaScript\n\n\n    //Este es un comentario en una linea.\n\n    /*Este es un comentario\n      en varias\n      lineas*/\n\n//Una variable y una constante\n\n    const sol = true\n    let clima = Boolean\n    console.log(sol)\n\n//Variables de datos de tipo primitivo\n\n    let string = \"Esto es una cadena de texto\"\n    let booleano = false\n    let number = 2\n    let numeroGrande = 12165464654654964841651n\n    let float = 15.8\n    let nulo = null\n    let indefinido\n    let simbolo = Symbol (\"Simbolo1\")\n\n//Imprimiendo un mensaje por consola con la palabra Hola y el nombre del lenguaje que estoy utilizando\n\nlet nombreLenguaje = \"JavaScript\"\nconsole.log(\"Hola, \" + nombreLenguaje)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/1Nonamed.js",
    "content": "// Documentación oficial de JavaScript : https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n// Diferentes sintaxis para crear comentarios en JS\n\n// Una línea: Comienza con '//' y sólo comenta la linea actual desde donde se escribe.\n\n/* Múltiples líneas: Comentarios extensos. \nComienzan por \"/*\" y comentará todo el texto que escribamos hasta que cerremos el comentario con un */\n\n// Variables y Constantes\nlet name = 'Juan'\nconst ten = 10\n\n// Datos primitivos\nlet lastname = 'López' // String\nlet age = 25 // Number\nlet isMale = true // Boolean\nlet address // Undefined\nlet stockAvailble = null // null\nlet myBigInt = 2343n // BigInt\n\nlet mySymbol = Symbol('unique') // Symbol\n// Se utilizan para añadir llaves de propiedades únicas a un objeto que no sean iguales a las claves que cualquier otro código pueda añadir al objeto, y que están ocultas de otro código utilice normalmente para acceder al objeto. \n\nconsole.log(\"Hola, JavaScript\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/7R0N1X.js",
    "content": "// Documentación de JavaScript --> https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Este es un comentario de una line\n\n/*\n  Este \n  es\n  un\n  comentario\n  de\n  varias\n  lineas\n*/\n\nvar miVariable // Declara una variable\nlet miVariable // Declara una variable local con ámbito de bloque\nconst miConstante = 3.1416 // Declara un nombre de constante de solo lectura y ámbito de bloque\n\nlet bool = true\nlet _null = null\nlet _undefined = undefined\nlet number = 24\nlet float = 3.1416\nlet bigint = 9007199254740992n\nlet str = 'Hola mundo'\n\nconsole.log(`Hola JavaScrip`);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/AChapeton.js",
    "content": "// Sitio web oficial: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Comentario de una linea\n\n/* Comentario\nen multiples\nlineas */\n\nvar languageName = 'JavaScript';\nvar stringType = 'string';\nvar numberType = 10;\nvar booleanType = true;\nvar nullType = null;\nvar undefinedType = undefined;\nconsole.log(\"Hola \" + languageName + \"!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Abel-ADE.js",
    "content": "// Página Web Oficial: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n//Tipos de comentarios en JS:\n\n    // Comentario de una sola línea\n    /*  Comentario \n        multilínea \n    */\n\n    /**\n     * Comentario multilínea \n     * que se utiliza \n     * para generar documentación del programa\n     */\n\n//Declaración y asignación de variables\nvar miVariableGlobal = 'Soy otra variable';\nlet miVariableLocal = 'Soy una variable'; //Se recomienda usar esta\n\n//Declaración y asignación de constantes\nconst MI_CONSTANTE = 12; //Se define en tiempo de compilación\n\n//Mostrar el contenido\nconsole.log(miVariableGlobal);\nconsole.log(miVariableLocal);\nconsole.log(MI_CONSTANTE);\n\n//Tipos de datos primitivos en JS\nlet miNumero = 100;\nlet miBooleano = true;\nlet miTexto = 'Soy un texto';\nlet miNulo = null;\nlet miVariableNoDefinida; // devuelve 'undefined'\n\n//Formas de declarar strings\nlet miTexto1 = 'Soy un texto';\nlet miTexto2 = \"Soy un texto\";\nlet miTexto3 = `Soy un texto`;\n\n//Imprime por terminal el texto: 'Hola, Js!'\nconsole.log('Hola, Js!');\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Abraham9804.js",
    "content": "//https://developer.mozilla.org/en-US/docs/Web/javascript\n\n//Comentario en una linea \n\n/*Comentario \nen multiples \nlineas */\n\nlet num = 1\nconst pi = 3.1416\n\nlet entero = 1\nlet decimal = 1.5\nlet numeroGrande = 1234567890123456789n\nlet texto = \"Hola mundo\"\nlet booleano = true\nlet indefinido = undefined\n\n\nconsole.log(\"¡Hola, Javascript!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Agus-IG.js",
    "content": "//Sitio web: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n//Comentario de una sola linea\n\n/*Comentario\nen multiples\nlineas*/\n\nlet variable = \"Hola\";\nconst constante = \"Mundo\";\n\nlet numero = 1;\nlet cadena = \"Hola mundo\";\nlet booleano = true;\nlet indefinido = undefined;\n\nconsole.log(\"Hola, JavaScript!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/AgusBelP.js",
    "content": "// -------------------------- ENUNCIADO\n\n/*\n ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n - Recuerda que todas las instrucciones de participación están en el repositorio de GitHub.\n \n Lo primero... ¿Ya has elegido un lenguaje?\n - No todos son iguales, pero sus fundamentos suelen ser comunes.\n - Este primer reto te servirá para familiarizarte con la forma de participar enviando tus propias soluciones.\n \n EJERCICIO:\n - Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n- Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n - Crea una variable (y una constante si el lenguaje lo soporta).\n - Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n \n ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y debemos comenzar por el principio.\n */\n\n// -------------------------- RESOLUCIÓN\n// Mi lenguaje de programación es Javascript\n\n/* No existe una página oficvial, lo más cercano es https://developer.mozilla.org/es/docs/Web/JavaScript  */\n\n// Es posible hacer comentarios en una sola línea utilizando dos barras\n\n/* Los comentarios multilinea se generan con la ayuda de una barra y un asterisco */\n\n// ---------- Creación de variables\n\nvar variable = 'Backend'; // Las variables declaradas con var son procesadas antes de la ejecución del código.El scope de una variable declarada con var, es su contexto de ejecución.\n\nconst variable2 = 'Frontend'; // Const es un tipo de variable a la cual no es posible re asignar su valor una vez declarada\n\n// ---------- Tipos de datos\n//En Javascript existen 7 tipos de datos. En los siguientes ejemplos el nombre de la variable es el nombre del tipo de dato\n\nlet undefined_example = undefined; // representa una variable que no ha sido declarada o a la cual no se le ha asignado un valor.\n\nlet boolean = true; //representa un valor lógico y puede tener dos valores, ya sean true o false.\n\nlet number = 1; //permite representar y manipular valores numéricos\n\nlet string = 'Soy una cadena de texto'; // representa cadenas de caracteres\n\nlet bigInt = 1234567890123456789012345678901234567890n; //representa valores numéricos que son demasiado grandes para ser representados por el tipo de dato number.\n\nlet symbol = Symbol(); //El tipo symbol (símbolo) se utiliza para crear identificadores únicos para los objetos.\n\nlet variable_null = null; //representa la ausencia intencional de cualquier valor, un valor nulo o «vacío»\n\n// ---------- Impresión por consola\nconsole.log('Hola Javascript!!!');\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/AiresEsteban.js",
    "content": "// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n/* Este es un \ncomentario en \nvarias lineas */\n\nlet result = 1\nconst num = 1\n\nlet myName = \"Esteban\"\nlet myNumber = 3\nlet myBoolean = true\nlet myUndefined\nlet myNull = null\nlet mySymbol = Symbol(\"mySymbol\")\nlet bigInt = BigInt(32420348230498230498230948230492830492304928304923049238402)\n\nconsole.log(\"¡Hola, javascript!\")\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/AitorLcom.js",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n// URL del sitio oficial de JavaScript https://developer.mozilla.org/es/docs/Web/JavaScript\n\n//Comentario de una linea\n\n/*Comentario\nde varias\nlineas\n*/\n\n/**\n * Comentario par usar\n * con la documentacion automatica de JSDoc\n */\n\n//Variable y constante\nlet nombre = \"Manuel\";\nconst nombreConst = \"Manuel Constante\";\n\n//Variables con todos los tipos de datos primitivos\n//String\nlet str1 = \"Manolo\";\n//Number\nlet num1 = 100;\n//bigInt\nlet bigInt1 = 1234567890123456789012345678901234567890n;\nlet bigInt2 = BigInt(651684734138461684341684634168434);\n//Boolean\nlet bool1 = true;\n//Null\nlet nul1 = null;\n//Undefined\nlet und1;\n//Symbol\nlet sym1 = Symbol(\"Manolo\");\n\nlet nombreLenguaje = \"JavaScript\";\nconsole.log(\"¡Hola, \" + nombreLenguaje + \"!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Akzorla.js",
    "content": "//EJERCICIO 00-SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n\n\n//-------------------------------------------------------------\n//- Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n\n// JAVASCRIPT https://developer.mozilla.org/es/docs/Web/JavaScript\n\n\n//--------------------------------------------------------------\n//- Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n\n//comentario de una linea\n/*comentario de \nvarias \nlineas\n*/\n\n\n//---------------------------------------------------------------\n// - Crea una variable (y una constante si el lenguaje lo soporta).\n\nlet variable = 'esto es una variable'\nconst constante = 'esto es una constante'\n\n\n//----------------------------------------------------------------\n// - Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n\n//STRING\nlet texto = 'string'            //cadena de texto\n\n//NUMBER\nlet integer = 37                //numero entero \nlet float = 37.1                //numero decimal\n\n//NULL\nlet datoNull = null             //dato objeto\n\n//UNDEFINED\nlet noDefinido = undefined      //dato no definido\n\n//BOOLEAN\nlet booleano = true             //dato booelano\nlet booleano1 = false           //dato booleano\n\n//BIGINT\nlet bigInt = 50n                //dato bigint (numero muy grande)\n\n//SYMBOL\nlet simbol = Symbol('whaterver')\n\n\n\n//----------------------------------------------------------------\n\n //- Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n console.log('Hola Javascrip!')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/AlanKevinCT.js",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n// 1. \n\n// https://www.javascript.com/\n\n\n// 2. \n\n// Comentario de una linea\n\n/*\n * Comentario de varias lineas\n *\n */\n\n// 3. \nvar global = \"variable global\";\nlet local = 10;\nconst constante = 21;\n\n// 4. \n\nvar respuesta = true;\nvar vacio = null;\nvar desconocido = undefined;\nvar numero = 21;\nvar gran_numero = 222231312312312n;\nvar cadena = \"cadenita\";\nvar simbolo = Symbol('simbolo');\n\n// 5. \n\nconsole.log(\"¡Hola Javascript!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Alanox1.js",
    "content": "//Sitio oficial de JavaScript:  https://javascript.com\n\n// Esta es la forma de comentar en una línea\n\n//acá estoy comentando otra línea\n\n\n/* De esta forma\n   se escribe\n   un comentario \n   en diferentes líneas\n   !!!!!!\n*/\n\n\nlet mi_variable = \"Hola, soy una variable de tipo string\" //Asi se crea una variable \n\nconst mi_constante = \"Hola, soy una constante\" //Asi se crea una constante, quiere decir que el valor no se va a poder cambiar\n\nlet my_string = \"Hola, yo soy un string (cadena de texto)\" // Asi se crea un string\nlet my_number = 7  //Asi se crea una variable de tipo number\nlet my_boolean = true  //asi se crea un booleano, puede ser unicamente estos 2 valores: true o false\nlet my_undefined = undefined  //asi se crea un undefined, es un valor predeterminado para variables no inicializadas\nlet my_null = null  //asi se crea un null, indica la ausencia intencional de un valor\nlet my_symbol = Symbol('identificador');  //asi se crea un symbol\nlet my_bigint = 1234567890123456789012345678901234567890n;    //asi se crea un bigint\n\n\n\nconsole.log(\"¡Hola, JavaScript!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/AlbaBP.js",
    "content": "// Sitio oficial JavaScript: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// 1. Comentarios\n\n// Comentario de una línea\n\n/*\nComentario\nde\nvarias\nlíneas\n*/\n\n// 2. Variables\n\n// Declaración de variables\nvar x = 5;\nlet y = 10;\nconst z = 15;\n\n// 3. Tipos de datos\nlet a = 5; // Number\nlet b = \"Hola\"; // String\nlet c = true; // Boolean\nlet d = [1, 2, 3]; // Array\nlet e = {nombre: \"Albrox\", edad: 25}; // Object\n\n// 4. Hola mundo\nlet language = \"JavaScript\";\nconsole.log(\"Hola mundo desde \" + language + \"!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Alemar16.js",
    "content": "\r\n//1. Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\r\n\r\n//https://developer.mozilla.org/es/docs/Web/JavaScript\r\n\r\n\r\n\r\n\r\n//2. Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\r\n\r\n    // El uso de dos barras seguidas (//) sirve para comentarios de una sola linea de código tambien usando en shortcut ( control + } ), Ejemplo:\r\n\r\n        //este es un ejemplo.\r\n\r\n    // El uso de una barra y un asterisco como si fuera una etiqueta de apertura y de forma invertida como una etiqueta de cierra (/*  */), sirve para comentarios de varias lineas de códigos tambien usando en shortcut ( Alt + shif + A } ), Ejemplo:\r\n\r\n        /* este es un ejemplo de\r\n        comentar varias lineas de \r\n        codigo en JavaScript */\r\n\r\n\r\n\r\n//3. Crea una variable (y una constante si el lenguaje lo soporta).\r\n\r\n    let nombre = \"Jose\";\r\n    const pi = 3.14;// por convención\r\n\r\n\r\n\r\n//4. Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\r\n\r\n    //cadenas de texto:\r\n        let texto = \"El lenguaje de programacion es JavaScript, y es ...\" // ejemplo de cadena de texto\r\n\r\n    //enteros:\r\n        let isNumber = 23; //ejemplo de numero, puede se negarivo tambien\r\n        let isNotNunber = NaN // cuando una variable se asigna un valor de numero pero el resultado es un valor no numerico.\r\n    \r\n    //flotante:\r\n        let isFloat = 1.5; //ejemplo de numero con decimal\r\n    \r\n    //booleanos:\r\n        let isBoolean1 = true;\r\n        let isBoolean2 = false;\r\n\r\n//5. Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\r\n\r\n    let languaje = \"JavaScript\";\r\n    console.log(\"Hola Mundo \"+ languaje);\r\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Aleoe01.js",
    "content": "// URL sitio web oficial JavaScript: \"https://developer.mozilla.org/es/\"\n\n// comentario en una sola linea\n\n/* \neste es un comentario\nmultilinea \n*/\n\n// variable y constante en JS\n\nlet variable = 1;\nconst constante = 2024;\n\n// tipos de datos en JS\n\nlet number = 10;\nlet boolean = false;\nlet string = \"JavaScript\";\nlet array = [1, 2, 3, 5, 7, 11];\nlet objeto = {};\n\nconsole.log(\"¡Hola, \" + string + \"!\"); // Imprime por consola: \"¡Hola, JavaScript!\"\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/AlexXAwada.js",
    "content": "// https://developer.mozilla.org/es/docs/Learn/Getting_started_with_the_web/JavaScript_basics\n\n// Comentario en una linea\n/*\nComentario en\nvarias lineas\n*/\n\nvar myVariable1 = \"Variable 1\"\nlet myVariable2 = \"Variable 2\" // variable primitiva String\n\nconst MY_CONST= \"Constante\"\n\nlet myInt= 1 // variable primitiva NUMBER\nlet myBoolean= true // variable primitiva BOOLEAN\nlet myBigInt=100000000000000 // variable primitiva de numeros grandes\nlet myUndefined // variable primitiva undefined\nlet mySymbol= Symbol(\"Key\") //variable primitiva symbol\nlet myNull= null //variable primitiva null\n\nconsole.log(\"Hello, JavaScript\")\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/AlexanderTejedor.js",
    "content": "//https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Comentario de una sola línea en JavaScript\n\n/*\nComentario en\nvarias líneas\nen JavaScript\n*/\n\n/**\n * Comentario de documentación\n * en JavaScript\n */\n\n// Declaración de variables en JavaScript\nvar name = 'AlexTejedorDev';\nlet lastName = 'Tejedor';\nconst myId = 123456789;\n\n// Tipos de datos primitivos con JavaScript\nlet str = 'Esto es un String';\nlet num = 26;\nlet float = 26.5;\nlet bigInt = 123456n; \nlet isTrue = true; //or false\nlet nulo = null;\nlet und = undefined;\nlet idUnico = Symbol('Id Unico')\n\n//Imprimir en pantalla un mensaje\nconsole.log('Hola, JavaScript');\nconsole.log(typeof(str))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Alexis0717.js",
    "content": "/*\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n//https://developer.mozilla.org/es/docs/Web/JavaScript\n\n//Comentario en una linea\n\n/*Comentario\n    en varias  \n    lineas\n*/\n//asi se crea una variable\n\nlet EstoesUnavariable = \"Hola Mundo\"\n\n//asi se crea una constante\nconst EstaesunaConstante = \"Hi world\"\n\n//Distintos tipos de variables representando datos primitivos\n\nlet number = 9\nlet float = 0.8\n\nlet boolean = true\nlet booleano = false\nlet mystring = \"Hola mundo\"\nlet bigInt = 9000000000000000\nlet miSyimbol = Symbol(\"foo\")\n//input\nconsole.log(\"holaaa mundoooo\");\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Alfarog507.js",
    "content": "// URL sitio web oficial JavaScript: \"https://developer.mozilla.org/es/docs/Learn/JavaScript\"\n// Este es un comentario de una linea\n/* \nEste es un comentario de muchas lineas\n*/\n\n// Variables y constantes en JS\nlet miNombre = \"Gabriel\";\nconst miApellido = \"Alfaro\";\nvar miEdad = 21;\n\n// Tipos de datos en JS\nlet numero = 10;\nlet booleano = true;\nlet cadena = \"JavaScript\";\nlet array = [1, 2, 3, 4, 5];\nlet objeto = {};\n\nconsole.log(\"¡Hola, \" + cadena + \"!\"); // Imprime por consola: \"¡Hola, JavaScript!\"\nconsole.log(`Hola mi nombre es ${miNombre} ${miApellido}`);\nconsole.log(`Tengo ${miEdad} años`);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Alvaro-Neyra.js",
    "content": "// WEB OFICIAL:\n// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Existen 3 tipos de comentarios en JavaScript:\n// - Comentario de una linea:\n// Este es un comentario de una linea\n// - Comentario de varias lineas:\n/* Y Este es un comentario de varias lineas, como puedes ver estoy intentando escribir un comentario lo suficientemente largo\npara ensenarte que de esta manera se puede hacer un comentario de varias lineas, gracias por leer. */\n\n\n// Creando una variable (var, let) y una constante:\n/* Creando una variable usando var (function scope (si se declara dentro de un bloque condicional, se podra usar fuera de la condicional), \n    se puede volver a declarar con el mismo nombre y debido al hoisting estas variables\n    durante la fase de compilacion son movidas al comienzo del ambito o scope en el que se encuentran, si no han sido declaradas antes \n    de una ejecucion devolvera undefined) */\nvar variable_var = \"Soy una variable var\"; // Actualmente var no se usa, ya que no es una practica usada en el JavaScript moderno\nconsole.log(variable_var)\n// Creando una variable usando let (local scope (dependiendo en donde se declare y no se puede volver a redeclarar (mas optima de usar)))\nlet variableLet = \"Soy una variable let\";\nconsole.log(variableLet)\n/* Creando una variable const (Una variable constante (no podra volver a cambiar su valor), tiene que\ndeclararse con un valor sino dara error y tiene ambito de bloque (block scope)) */\nconst variableConstante = \"Soy una variable constante y no podre volver a ser asignada\";\nconsole.log(variableConstante)\n\n// Tipos de datos primitivos de JavaScript\n// String: Sirve para almacenar cadenas de texto.\nlet cadena = \"Hola, mundo!\";\nconsole.log(cadena)\n// Number: Sirve para almacenar numeros\nlet numero = 40;\nconsole.log(numero)\n/* BigInt: Sirve para almacenar numeros más grandes que el tipo 'number'. Se define\nagregando la letra \"n\" al final del número seguido de \"n\". */\nlet numeroBigInt = 1234567890123456789012345678901234567890n;\nconsole.log(numeroBigInt)\n// Boolean: Sirve para almacenar tipos booleanos que son true y false\nlet booleano = true;\nconsole.log(booleano)\n// Undefined: Las variables que son de tipo undefined significa que ya han sido declarado pero no les asignaron un valor\nlet variableUndefined;\nlet variableUndefinedExplicita = undefined\nconsole.log(variableUndefined) // undefined\nconsole.log(variableUndefinedExplicita)\n// Symbol: Es un tipo de dato que sus instancias son unicas e inmutables\nlet variableSymbol = Symbol(\"foo\");\nconsole.log(variableSymbol)\n\n// IMPRIMIR POR CONSOLA \"HOLA, [NOMBRE DEL LENGUAJE]!\"\nconsole.log(\"¡Hola, JavaScript!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/AndNikDev.js",
    "content": "// ? https://developer.mozilla.org/es/docs/Web/JavaScript\n\n'use strict'\n\n// ! Este es un comentario de una sola línea\n\n/*\n * Este es un comentario multilinea en JavaScript\n */\n\nvar variableSinRestricciones = \"Hola Mundo\";\nlet variableConRestricciones = \"Hola Mundo\";\nconst constante = \"Hola Mundo\";\n\nlet integer = 10;\nlet float = 10.10;\nlet string = \"Hola, soy Nikolayk!\";\nlet bool = true;\nlet array = [10, 'Bob', true, 10.10];\nlet object = {};\nlet nulo = null;\nlet indefinido = undefined;\nlet symbol = Symbol('symbol');\n\nconst funcionClg = () => {\n    console.log(\"¡Hola, JavaScript!\");\n}\n\nfuncionClg();"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/AndSoria.js",
    "content": "// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n // Comentario en una linea\n\n/* Comentario\n    de\n    varias\n    lineas\n */\n\n/**\n * Comentario de JSDoc, sirve para documentar nuestro codigo, \n * este comentario genera informacion para poder comprender y \n * mantener nuestro codigo.Tiene como recursos el uso de \n * etiqueras (@param, @return) para indicar valores de entrada y \n * el retorno de la funcion\n */\n\n/** \n * funcion que devuelve la suma de dos paramentros\n * @param {*} a number\n * @param {*} b number\n * @returns number\n */\n\nfunction sum(a,b)\n{\n    return a+b;\n};\n\n\n// Declaracion de una constante\nconst variable1=\"123\";\n\n// Declaracion de una variable\nvar variable2;\nlet variable3;\n\n\n//Tipos de datos de primitivos\nlet v_Boo2= false // boolean es un tipo de dato logico que puede tener dos valores: true o false\nlet v_null= null; // null representa a una referencia que apunta a una inexistente o invalido onbjeto o direccion.\nlet v_undefined // undefined es una variable que no tiene un valor asignado\nlet v_int = 1 // number el dato tipo number representa tanto numeros enteros como numeros decimales\nlet v_bigInt= 9173294628n // BigInt es un tipo usado para contener numero muy grandes\nlet v_str = \"Andres\" // string el tipo string contiene cadenas de texto\nlet v_Symbol =Symbol(\"anything\") // Symbol representa valores unicos e inmutables que se utilizan principalmente como identificadores unicos para propiedades de objetos.\n\n//Impresion por consola\nconsole.log(\"¡Hola, Javascript\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/AndresMCardenas.js",
    "content": "// web oficial: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// asi se comenta en javascript en una sola linea\n\n/*\nEsta es la forma de comentar en \njavascript en \nvarias lineas\n*/\n\n// esta es una variable\n// las variables se declaran con la palabra reservada var es de forma global\nvar nombre1 = \"Andres\";\n// las variables se declaran con la palabra reservada let es de forma local\nlet nombre2 = \"Mauricio\";\n// las variables se declaran con la palabra reservada const es de forma local y no se puede cambiar su valor\nconst apellido = \"Cardenas\";\n\n// tipos de datos primitivos\n\n// string es un tipo de dato que se usa para guardar cadenas de texto\nlet usuarioTwitch = \"Xamael123\";\n// number \nlet edad = 37;\n// boolean  es un tipo de dato que solo puede tener dos valores true o false\nlet casado = false;\n// null es un tipo de dato que se usa para inicializar una variable\nlet carro = null;\n// undefined es un tipo de dato que se usa para inicializar una variable\nlet casa;\n// symbol es un tipo de dato que se usa para crear identificadores unicos para objetos inmutables\nlet simbolo = Symbol(\"mi simbolo\");\n\n// tipos de datos estructurados\n\n// object es un tipo de dato que se usa para guardar objetos\nlet persona = {\n  nombre: \"Andres\",\n  edad: 37,\n  casado: false\n};\n// array es un tipo de dato que se usa para guardar arreglos\n\nlet nombreCompleto = [\"Andres\", \"Mauricio\", \"Cardenas\"];\n\n// asi se imprime en consola\nconsole.log(\"Hola mundo!!!\" , \"Javascript\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Andresargote.js",
    "content": "// Documentación de JavaScript (no oficial): https://es.javascript.info\n\n/*\n    En JavaScript y en otros lenguajes de programación usamos los comentarios para poder explicar cómo funciona nuestro código.\n\n    No tienen ninguna función más que la de explicar el código a otras personas o a nosotros mismos.\n\n    Hay dos tipos de comentarios en JavaScript:\n    - Comentarios de una sola línea: Se crean con // y todo lo que escribamos después de las dos barras será un comentario.\n    - Comentarios de varias líneas: Se crean con /* y se cierran con * / (sin el espacio entre el asterisco y la barra) y todo lo que escribamos entre ellos será un comentario.\n\\*/\n\n// Variables: Es un nombre simbólico que se le da a un espacio de memoria que almacena un valor. Normalmente el espacio para almacenar el valor ocurre en la memoria RAM.\n/*\n    El proceso para reservar el espacio en memoria inicia con la declaración de la variable, luego la asignación y por último el acceso a ese valor asignado.\n*/\n\n/*\n    En JavaScript se pueden declarar variables de tres formas:\n    - var: Es la forma antigua de declarar variables. No se recomienda su uso (Hay excepciones).\n    - let: Es la forma moderna de declarar variables. Se recomienda su uso.\n    - const: Es la forma de declarar constantes. No se puede cambiar su valor una vez asignado.\n*/\n\n/*\nLa diferencia entre var y let y const es el alcance de la variables. var tiene un alcance de función, let y const tienen un alcance de bloque.\n*/\nvar antigua = 'Soy una variable antigua';\nlet moderna = 'Soy una variable moderna';\nconst CONSTANTE = 'Soy una constante';\n\n// Tipos de datos:\nlet n = 123;\nlet n2 = 12.345;\nlet n3 = 1 / 0; // Infinity (Infinito) también el -Infinity y el NaN (Not a Number)\n\n// BigInt: Es un tipo de dato numérico que puede representar números enteros de longitud arbitraria.\nconst bigInt = 1234567890123456789012345678901234567890n; // Se declara con la letra n al final del número.\n\nlet str = 'Hola'; // Las cadenas de texto se declaran con comillas simples, dobles o con comillas invertidas.\n\nlet boolean = true; // Los valores booleanos son true (verdadero) y false (falso).\n\nlet nullValue = null; // null es un valor especial que no pertenece a ningún tipo de dato.\n\nlet undefinedValue = undefined; // undefined es un valor especial que significa que la variable no está asignada.\n\nlet simbolo = Symbol('Simbolo'); // Symbol es un tipo de dato que se utiliza para crear identificadores únicos.\n\nlet obj = {\n  nombre: 'Andres',\n  edad: 21,\n}; // Los objetos son colecciones de datos y/o funcionalidades.\n\nlet array = [1, 2, 3, 4, 5]; // Los arrays son colecciones de datos.\n\n// ps: En JavaScript todo lo que no sea un tipo de dato primitivo es un objeto.\n\nconsole.log('¡Hola, JavaScript!');\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/AndrewCodev.js",
    "content": "// https://www.javascript.com/\n\n/*Esto es \nun comentario\nen bloque*/\n\nconst MI_CONSTANTE = \"Mi Constante\";\nlet miVariable = \"Mi variable\";\n\nlet myString = \"Esto es una cadena de texto\";\nlet myInt = 52;\nlet myDouble = 1.2;\nlet myBoolean = true;\nlet myUndefined;\nlet myNull = null;\nlet mySymbol = Symbol(\"id\");\nlet myBigint = 123456789012345678901234567890n;\n\nconsole.log(\"¡Hola, JavaScript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Angel-Delg.js",
    "content": "// URL = https://developer.mozilla.org/en-US/docs/Web/JavaScript\n/*\n   Comentarios de varias Lineas.\n   URL = https://developer.mozilla.org/en-US/docs/Web/JavaScript\n*/\n\nlet variable;\nconst constante = {}\n\n// tipos de datos primitivos\nlet numerico = 2024\nlet cadenaTexto = \"2024\"\nlet isNewYear = true\nlet indefinido = undefined\nlet nulo = null\n\n// Mensaje por consola\nconsole.log(\"Hola Javascript\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/AngelVelasco1.js",
    "content": "/* https://developer.mozilla.org/es/docs/Web/JavaScript */\n\n//? 1. Representa las diferentes formas de comentar \n// -> En una linea\n/* \n    --> Multiples \n    Lineas\n*/\n\n//? 2. Variables y constantes \nlet number = 1;\nconst athmosphere = 3.4745;\n\n//? 3. Tipos de datos primitivos\nlet string = \"Hi\";\nlet int = 1;\nlet boolean = true;\nlet float = 1.5;\nlet notDefined = undefined;\nlet symbol = Symbol\n\n//? 4. Mensaje por consola\nconst languageName = \"JavaScript\"\nconsole.log(`¡Hola ${languageName}!`);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Angelo-Eyama.js",
    "content": "// Documentacion oficial de Javascript\n// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n//Comentario de una linea\n/**\n * Comentario\n * de\n * varias\n * lineas\n */\n\nlet variable = 10;\nconst constante = 5;\nlet cadena = \"Cadena de texto\";\nlet numeroEntero = 123;\nlet numeroDecimal = 12.3;\nlet booleano = false;\nlet indefinido;\nlet valorNulo = null;\n\n//Mensaje en pantalla\nconsole.log(\"Hola, Javascript\");\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/ArliumDev.js",
    "content": "// URL = https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Esto es un comentario en una línea\n\n/* Esto es un comentario\nen varias líneas */\n\nlet variable = \"Variable\";\nconst constante = \"Constante\";\n\nlet cadenaTexto = \"Soy una cadena de texto\";\nlet num = 22;\nlet bigInt = 123456789012345678901234567890;\nlet boolean = true;\nlet undef = undefined;\nlet nul = null;\nlet symbol = Symbol(\"simbolo\");\n\nconsole.log(\"¡Hola, Javascript!\");\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/ArticKun.js",
    "content": "\n\n// Web Oficial Js //\n//https://developer.mozilla.org/es/docs/Web/JavaScript\n\n\n//Comentario de una linea\n// OnlyLove JavaScript\n\n\n/*\nComentario de varias lineas\n\nJavaScript el mejor lenguaje,\nLos ardidos dirán que no ... hehe\n*/\n\n// Inicializar Una Variable\nlet persona     = 'Fabian';\n// Reasignacion\npersona         = 'Fabian Patinho';\n\n// Inicializar Varias variables\nlet musico      = true,\n    programador = true,\n    diseñador   = true;\n\n// Constante\nconst HUMANO    = 'La mayoria del tiempo';\n\n// -- Tipos de Datos --\n// String\nlet texto      = 'No seré un Hola, Mundo';\n// Number\nlet entero     = 35;\nlet decimal    = 20.24; \n// BigInt\nlet grande     = 2353535353535353535353535n;\n// Null\nlet nulo       = null;\n// Undefined\nlet indefinido = undefined;\n// Symbol\nlet simbolo    = Symbol();\n//Boolean\nlet loveMoure  = true;\n\n// -- Impresion en Consola --\nconst LENGUAJE = 'JavaScript';\nconsole.log( `Hola Mundo, desde: ${LENGUAJE}` );"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/AugustBs.js",
    "content": "// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Comentario de una sola línea\n\n/* Comentario \nde \nvarias \nlíneas */\n\nlet nombre = \"Mi nombre\";\nconst PI = 3.1416;\n\nlet numero = 10;\nlet decimal = 10.5;\nlet booleano = true;\n\nconsole.log(\"Hola Mundo\");\nconsole.log(nombre);\nconsole.log(numero);\nconsole.log(decimal);\nconsole.log(booleano);"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/BenjaminSk09.js",
    "content": "// Hola Esta Es la web de Java script https://javascript.com/ //\n\n// Este es un comentario de una sola linea//\n\n/*Este esta es la forma de crear\nun comentario de multiples Lineas*/\n\nlet a;\nlet b = 10;\n\nconst name = \"BenjaminSk09\";\n\n// Creacion de variables representando todos los tipos de datos primitivos //\n\nlet number = 10;\nconst Number = 40;\n\nlet numero = 2 * 400;\n\nconst texto = \"Hola yo soy benjamin de Guatemala\";\n\nconst boolean = true ;\n\nconst simbolo = Symbol(\"Hola este es un Simbolo\");\n\nconsole.log(\"Hola, esto es un mensaje en la consola\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Berentolkien.js",
    "content": "// https://retosdeprogramacion.com/\n\n/*\nhttps://retosdeprogramacion.com/\nhttps://retosdeprogramacion.com/\nhttps://retosdeprogramacion.com/\n*/\n\nlet nombre = lucas\nconst apellido = bernaola\nlet edad = 34\nconst añoNacimiento = 1989\nlet casado = true\n\nlet string = JavaScript\nlet number = 123456\nlet isBooleanTrue = true\nlet isBooleanFalse = false\nlet isNull = null\nlet indefined;\nlet myArray = [\"Hola\", \"como\", \"estas\", \"?\"]\nlet myObject = {nombre: \"lucas\", apellido: \"bernaola\"}\n\nconsole.log(\"Hola JavaScript\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/BertoMP.js",
    "content": "// WEB OFICIAL\n// Para encontrar información de JavaScript se puede utilizar la web:\n// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// COMENTARIOS\n// En JavaScript tenemos 3 tipos de comentarios:\n// - Comentarios de una única línea (// Comentario):\n// Esto es un comentario de una línea y puede servir, por ejemplo, para explicar una variable.\n\n// - Comentarios de varias líneas (/* Comentario */):\n/* Esto es un comentario\n * de varias líneas y puede\n * servir para explicar una parte\n * más extensa del código. */\n\n// - Comentarios de documentación (/** Comentario */):\n/**\n * Este tipo de comentarios nos van a servir para documentar\n * nuestro código y van a permitir la generación de documentación\n * automática llamada JSDoc que facilita la comprensión\n * y el mantenimiento del código.\n * Al igual que pasa con otros lenguajes, pueden ir acompañados\n * de etiquetas como @param o @return que identifican valores\n * como los parámetros de entrada de la función o el valor de\n * retorno que produce la función. */\n\n// VARIABLES Y CONSTANTES\n/*  - Variables: En JavaScript podemos declarar una variable de dos formas:\n                 a) Usando 'var' seguido del nombre de la variable: esta forma no es recomendable y se encuentra\n                   actualmente en desuso.\n                 b) Usando 'let' seguido del nombre de la variable. */\nvar miVariableVar = 33;\nlet miVariableLet = 33;\n\n/* - Constantes: Usamos la palabra clave 'const' para declarar constantes en JavaScript. A diferencia de las variables,\n                 las constantes siempre deben estar inicializadas al momento de su declaración. La convención común\n                 en JavaScript es favorecer la inmutabilidad, por lo que es frecuente encontrar el uso de constantes\n                 en el código. */\nconst miConstante = 'Alberto';\n\n// DATOS PRIMITIVOS\n/* En JavaScript existen 6 tipos de valores o datos primitivos, aunque al ser un lenguaje no tipado, no es necesario\n   explicitar el tipo de la variable. */\n\nconst miString = 'Esto es un string'; // string: Sirve para almacenar cadenas de texto.\n\nconst miNumberEntero = 40; // number: Sirve para almacenar datos de tipo numérico, ya sean enteros o decimales.\nconst miNumberDecimal = 23.4;\nconst miBigInt = 123456789012345678901234567890n; /* bigint: Es otro tipo de dato numérico que permite representar\n                                                             enteros más grandes que el tipo 'number'. Se define\n                                                             agregando la letra \"n\" al final del número seguido de\n                                                             \"n\". */\nconst miBoolean = true; // boolean: Este tipo de dato representa un valor lógico, que puede ser verdadero o falso.\nlet miUndefined; // undefined: Indica que una variable ha sido declarada pero aún no se le ha asignado un valor.\nconst miSymbol = Symbol('mi Symbol'); // symbol: Es un tipo de dato cuyas instancias son únicas e inmutables.\n// También existe el null que aunque puede tomarse como primitivo, en realidad es propio de cada Object.\n\n// IMPRESIÓN POR CONSOLA\nconsole.log('¡Hola, JavaScript!');"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/BrayanCordova1.js",
    "content": "//Url del lenguaje: https://developer.mozilla.org/es/docs/Web/JavaScript\n// Soy un comentario\n/* Soy un comentario \n   Soy un comentario */\nlet Variable1 = 'Hola'; // let es una variable local\nvar Variable2 = 'Mundo'; // var es una variable global\nz = 1; // z es una variable global\n// const no se puede cambiar a diferencia de let y var\nconst Varible3 = 'JavaScript';\n\nlet number = 4; // Number es un tipo de dato primitivo que representa un número entero o decimal positivo o negativo con una precisión de 64 bits\nlet string = 'Hola mundo'; // String es un tipo de dato primitivo que representa una secuencia de caracteres.\nlet boolean = true; // Boolean es un tipo de dato primitivo que representa un valor lógico verdadero o falso\nlet Null = null; // Null es un tipo de dato primitivo que representa un valor nulo.\nlet undefined = undefined; // Undefined es un tipo de dato primitivo que representa un valor no definido\nlet Bigint = BigInt(10n); // BigInt es un tipo de dato primitivo que representa un número entero mayor que 2^53 - 1 o menor que -2^53 + 1\nlet Symbol = Symbol('Hola'); // Symbol es un tipo de dato primitivo que representa un valor único e inmutable que puede ser utilizado como clave de una propiedad de un objeto.\nlet Object = {\n  // Object es un tipo de dato primitivo que representa un objeto que contiene una colección de pares de clave-valor\n  name: 'Brayan',\n  age: 20,\n};\n\nlet Array = [1, 2, 3, 4, 5]; // Array es un tipo de dato primitivo que representa una lista ordenada de elementos que pueden ser de cualquier tipo de dato\n\nlet Function = function () {\n  // Function es un tipo de dato primitivo que representa una función\n  console.log('Hola JavaScript');\n};\n\nconsole.log('¡Hola, JavaScript!');\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Brigham09.js",
    "content": "// Escojí el lenguaje JavaScript, el sitio del cual obtendré la información es: https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n// Esta es una lina de comentario.\n\n/*\nEste tipo de comentado\npermite varias lineas \nde código dentro\n*/\n\n// Variables\nlet cadena = 'variable de tipo cadena';\nlet numero = 10;\nlet decimal = 3.141516;\nlet booleano = true;\nlet indefinido = undefined;\nlet nulo = null;\n\n//Constante\nconst gravedad = 9.807; //metros*segundo²\n\n// Imprimir por consola\nconsole.log (\"¡Hola, JavaScript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Bruno1084.js",
    "content": "// Javascript no tiene una página oficial así que coloqué la se ECMA.\n// https://ecma-international.org/\n\n// Comentario de linea simple\n\n/*\nComentario\nde \nmultiples\nlineas\n*/\n\n// Variable global\nvar var1 = \"Global\";\n\n// Variable local\nlet var2 = \"Local\";\n\n// Constante\nconst con1 = \"Constant\";\n\n// Número\nlet number = 100;\n\n// Cadena\nlet string = \"Javascript\";\n\n// Booleano\nlet bool = true;\n\n// Print\nconsole.log(\"¡Hola, \" + string + \"!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Bryan112094.js",
    "content": "//PAGINA WEB OFICIAL\n//https://developer.mozilla.org/es/docs/Web/JavaScript\n\n//COMENTARIOS\n// -> dos / es comentario de una línea\n/*\n    Asi se ve\n    los comentarios\n    multilíneas\n*/\n\n//VARIABLES\nlet variable01 = 2; // esta variable puede cambiar su valor al utilizarla en otra parte del codigo\nconst variable02 = \"hola\"; // esta variable no puede cambiar su valor una vez declarada\n\n//DATOS PRIMITIVOS\n// Undefined\nlet valor;\n// Booleano\nlet bool = true;\n// String\nlet texto = \"hola\";\n// Number\nlet numero = 2;\n// BigInt\nlet big = 120n;\n// Symbol\nlet sym = Symbol(\"Queso\");\n\n//IMPRIMIR\nconsole.log(\"Hola, JavaScript\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Caleb-Acarapi.js",
    "content": "/* * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]! */\n\n // 1. https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n //2  Comentario de una linea\n /*\n Comentario \n de varias lineas\n */\n\n// 3. Crear una variable\nlet variable =  \"variable\";\n// Variable constante\nconst pi = 3.14159;\n\n// 4. Crear variables representando todos los tipos de datos primitivos.\nlet number = 10; // De tipo Number\nlet begint = 1234378938438478374 // De tipo Number grande\nlet undefined; //Es un tipo de datos indfinido\nlet nulo = null; // Es un tipo de dato Nulo\nlet string = \"cadena\"; // Es un tipo de dato cadena o llamado string\nlet booleano = true; // Es un tipo de dato bolleano solo puede tener 2 valores (True or False)\nlet simbol = Symbol('id_clave'); // Es un tipo de dato unico e inmutable\n\n// Algunos otros tipos de datos no primitivos\nlet lista = [1,2,3]; // Es un tipo de dato Array\nlet listaClaveValor = {         // Es un tipo de dato Objeto\n    clave1 : \"valor1\",\n    clave2 : \"valor2\"\n};\n\n// 5. Imprimir \"¡Hola, [y el nombre de tu lenguaje]!\"\nconsole.log(\"¡Hola, JavaScript!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Carles11.js",
    "content": "\n// ex1\n// https://ecma-international.org/publications-and-standards/standards/ecma-262/\n\n\n// ex2\n// comentario en linea\n/* comentario\nen \nvarias\nlineas\n*/\n\n// ex3\nvar greeting = \"olakease\"\nconst otroGreeting = \"Hola\"\n\n// ex4\nvar aString = \"esto es una string\"\nvar aNumber = 1978\nvar aBoolean = true\nvar aNull = null\nvar aUndefined = undefined\nvar aSymbol = Symbol(\"único\")\nvar aBigInt = BigInt(12345678999887765465465551321321321651681)\n\n// ex5\nconsole.log(\"¡Hola, JavaScript!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/CarlosMqz969.js",
    "content": "/* - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado. */\n\n\n// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n/* - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).*/\n\n/* Este es \nUn comentario de \nVarias lineas */\n\n// Este es un comentario de una sola linea de código\n\n// * - Crea una variable (y una constante si el lenguaje lo soporta).\n\nconst lenguajeName = \"JavaScript\"\nlet userName = \"CarlosMqz969\"\n\n/* * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...). */\n\nlet myStringVar = \"Hola mundo de la programación aquí vamos :D!\"\n\nlet myIntVar = 365\n\nlet myFloatVar = 3.1416\n\nlet myBoolVar = true\n\n// - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\nconsole.log(`Hola, ${lenguajeName}! `)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/CaveroBrandon.js",
    "content": "/* EJERCICIO:\n    Crea un comentario en el código y coloca la URL del sitio web oficial\n    del lenguaje de programación que has seleccionado.\n*/\n\n// Javascript official website: https://www.javascript.com/\n\n// Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...)\n// ** Single line comment **\n// This is a single line comment\n// ** Multi-Line comment **\n/* This is a multi-line comment\n   This is a multi-line comment\n   This is a multi-line comment\n*/\n\n\n// Crea una variable (y una constante si el lenguaje lo soporta).\n// Auto-declared variable\nauto_declared_variable = 5;\n// Using var\nvar year = 2025;\n// Using let\nlet month = 'January';\n// Using const\nconst day = 17;\n\n// Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n// Strings\nlet first_name = 'Brandon';\nlet last_name = \"Cavero\";\n// Number\nlet random_number = 123;\n// Float or BigInt\nlet pi_number = 3.14;\n// Boolean\nlet is_sunny = true;\n// Undefined\nlet undefined_value;\n\n// Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nconsole.log('Hello, Javascript!');\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/CesarCarmona30.js",
    "content": "// Sitio web del lenguaje\n// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Formas de elaborar comentarios\n\n// Comentario de línea\n\n/*\n  Comentario multilínea\n */\n\n/**\n * Esto también es un\n * comentario multilínea\n */\n\n// Variables\n\n/*\n  var y let sirven para declarar variables\n  var tiene un ámbito global o local,\n  el hoisting con var permite mover\n  la declaración en la cabecera del\n  código inicializandolo en undefined\n  let tiene un ámbito de bloque,\n  el hoisting con let tambien mueve\n  la declaración a la cabecera del \n  código pero no se inicializa\n  var se encuentra en desuso, por\n  buenas prácticas es mejor ocupar let\n*/\nvar country = 'México';\nlet name = 'César';\n// las constantes se manejan con const\nconst sex = 'Masculino';\n\n// Variables para datos primitivos\n\n// int\nlet age = 19;\n// float\nlet height = 1.75;\n// boolean\nlet alive = true;\nlet dead = false;\n// string\nlet city = \"México City\";\n// undefined\nlet status = undefined;\n// Symbol\nlet my_symbol = Symbol('My symbol');\n\nconst language = 'JavaScript'\nconsole.log(`¡Hola, ${language}!`);"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/ChWDev.js",
    "content": "// Web oficisl de JavaScript: https://262.ecma-international.org/\n\n/**\n * Tambien se puede encontrar documentacion de JavaScript en:\n *  \n *  MDN Web Docs: https://developer.mozilla.org/es/docs/Web/JavaScript\n *  \n */\n\nlet greeting = 'Hola';\nconst programmingLanguaje = 'JavaScript';\n\n// Datos primitivos en JavaScript 👀\n\nlet age = 18; //number\nlet country = 'Colombia'; //string\nlet isHappy = true; //boolean   \nlet roadmapComplete = undefined; //undefined \nlet updated = null; //null\nlet dreamSalary = 999999999999999999999999999n; //BigInt\nconst rockSymbol = Symbol('SOAD') // Symbol\n\nconsole.log(`¡${greeting}, ${programmingLanguaje}`);"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/ChrisSR0.js",
    "content": "//documentacion de javaScript MDN WEB DOCS\n//https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// comentario de una linea y empieza con // solo se comenta esta linea\n\n/* comentario de varias lines (bloque) nos permite\n    comentar en varias\n    lineas de codigo.\n    \n   */\n\nlet nombre = 'Cristian';//esta es una variale usando let\nvar apellido = 'salvatore';//varible usando var\n\nconst duracionDiaHoras= 24;//esta es una variable usando const, que almacena las horas del dia\n\n//Datos primitivos\n\n/*  number => incluye a numeros entros y decimales.\n    string => son cadenas de texto ''\n    boolean=> pueden ser true o false\n    null   => representa la ausencia de valor\n    undefined => se usa cuando una variable no tiene un valor definido\n    symbol => es un tipo unico y no mutable de datos\n*/\n\nconsole.log('¡Hola javaScript!');"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/CliverJimny123.js",
    "content": "// 1. Sitio Web\n// URL del sitio web oficial  -> https://ecma-international.org/\n// URL mas usado              -> https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// 2. Comentarios\n// Comentario de una sola linea de codigo \n/* Comentario de \n   varias lineas \n   de codigo*/\n\n// 3. Variable y Constante\nlet variable = \"hola temporal\"\nconst constante = \"hola eterno\"\n\n// 4. Tipos de datos primitivos\nlet edad = 25;  // number\nlet precio = 9.99; //float \nlet mensaje = 'Hola, ¿cómo estás?'; //string\nlet boleano = true;//bolean\nlet valorNulo = null;//null\nlet variableNoDefinida;//undefined\nlet simbolo2 = Symbol('descripcion');\n\n// 5. Impresion\nconsole.log(\"¡Hola, JavaScript!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Cris575.js",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n//Documentación oficial JavaScript: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// - Comentarios\n\n//Una sola línea\n\n/*\n    Varias lineas\n    Varias lineas\n    Varias lineas\n*/\n\n//Variables\nlet variable1 = \"\";\nvar variable2 = \"\";\nconst variable3 = \"\";\n\n// Variables y constantes\n\nlet string = \"string\";\nlet number = 12345;\nlet booleano = true || false;\nlet undefined;\nlet object = { test: \"test\" };\nlet bigInt = 173291978332997812712389n;\nlet symbol = Symbol(\"a\");\nlet _null = null;\n\nvar old;\nconst _const = \"\";\n\n//Imprimiendo en terminal\nconsole.log(\"Hola, JavaScript\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/DAVstudy.js",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n/*\n    Comentario\n                en \n                    varias\n                            lineas\n*/\n\n// Variables\nvar myVariable = 0 // notacion no recomendada\nlet myVariable2 = 0 // notacion recomendad\n\n// Constante\nconst myConst = \"Constante\"\n\n// Tipos de datos primitivos\n\n// Number\nlet myNumber = -1\nlet myNumber2 = 0.29\nlet myNumber3 = 100\n\n// NaN\nlet myNaN = NaN // dato no numerico\n\n// String\nlet myString = '¡Hola, JavaScript!'\n\n// Boolean\nlet myBoolean = true\nmyBoolean = false\n\n// null y undefined\nlet myUndefined = undefined\nlet myNull = null\n\n\n// BigInt para numeros enteros de longitud arbitraria\nlet myBigInt = 218928918291829129019210\n\n// Symbol \nlet mySym = Symbol(\"foo\")\n\n// console.log(typeof myNumber);\n// console.log(typeof myNaN);\n// console.log(typeof myString);\n// console.log(typeof myBoolean);\n// console.log(typeof myNull);\n// console.log(typeof myUndefined);\n// console.log(typeof myBigInt);\n// console.log(typeof mySym);\n\n\nconsole.log(myString);\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/DHBellini.js",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n\n\n// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n\n// Comentario\n\n/*\nComentario de varias lineas\n*/\n\n\nlet variable = \"esto es una variable\"\nconst constante = \"esto es una constante\"\n\n\nlet string = \"para los textos\"\nlet numeroEntero = 3\nlet booleanT = true\nlet booleanF = false\nlet nulo = null\nlet array = []\nlet objeto = {}\n\n\nconsole.log(\"¡Hola, JavaScript!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Dan-Corbo.js",
    "content": "/* \n* EJERCICIO:\n* 1- Crea un comentario en el código y coloca la URL del sitio web oficial del\n* lenguaje de programación que has seleccionado.\n* 2- Representa las diferentes sintaxis que existen de crear comentarios en el\n* lenguaje (en una línea, varias...).\n* 3- Crea una variable (y una constante si el lenguaje lo soporta).\n* 4- Crea variables representando todos los tipos de datos primitivos del\n* lenguaje (cadenas de texto, enteros, booleanos...).\n* 5- Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\" \n*/\n\n\n/* Soluciones */\n\n/* 1 */\n\n// La pagina oficial de Javascript es: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n/* 2 */\n\n//  Esta es la sintaxis para un comentario en una linea\n\n/* esta es \nla sintaxis \npara un comentario \nen varias lineas \n*/\n\n/* 3 */\n\nlet variable = \"Esta es una variable local\";\n\nvar variable1 = \"Esta es una variable global\";\n\nconst constante = \"Esta es una constante\";\n\n/* 4 */\n\nlet cadenaDeTexto = \"Esta es una cadena de texto o string\";\n\nlet enteros = 24;\n\nlet decimales = 2.5;\n\nlet BigInt = 123456789012345678901234567890n;\n\nlet booleanos = true > false;\n\nlet Nulo = null;\n\nlet indefinido = undefined;\n\nlet valorNaN = NaN;\n\nlet Symbol = Symbol('mi Simbolo');\n\nlet arreglos = ['Daniel', 24, 'Uruguay', 1];\n\nlet objetos = new Date(\"2024-01-06\");\n\n/* 5 */\n\nconsole.log(\"¡Hola, JavaScript!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/DanielBustos342.js",
    "content": "//? URL: https://www.javascript.com/\n\n/*\n !Fuentes de información:\n?- https://www.javascript.com/\n?- https://developer.mozilla.org/en-US/docs/Web/JavaScript\n*/\n\nvar numero = 0;\nlet variable = 0;\nconst constante = 3.14;\n\n// !Tipos de datos primitivos:\nlet string = \"Cadena de texto\";\nlet entero = 0;\nlet booleano = true;\nlet nulo = null;\nlet indefinido = undefined;\n\nconsole.log(\"!Hola, JavaScript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/DannyMarperOne.js",
    "content": "/* \n¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n- Recuerda que todas las instrucciones de participación están en el\nrepositorio de GitHub.\n\nLo primero... ¿Ya has elegido un lenguaje?\n- No todos son iguales, pero sus fundamentos suelen ser comunes.\n- Este primer reto te servirá para familiarizarte con la forma de participar\nenviando tus propias soluciones.\n\nEJERCICIO:\n1- Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n2- Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n3- Crea una variable (y una constante si el lenguaje lo soporta).\n4- Crea variables representando todos los tipos de datos primitivos\ndel lenguaje (cadenas de texto, enteros, booleanos...).\n5- Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\n¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y debemos \ncomenzar por el principio. */\n\n\n/* *********************************************************************************************** */\n//1.-\n//La página oficial de JavaScript es: https://www.javascript.com/\n\n\n//2.-\n//Comentario con doble diagonal: este unicamente funciona en una sola linea.\n/* Comentario con asteriscos y diagonal: sirve para escribir el comentario en varias lineas. */\n\n//3.-\nlet edad = 0;\nconst sexo = \"Masculino\";\n\n//4.-\n//Tipo de null\nlet nulo = null;\n\n//Tipo undefined\nlet noDefinido = undefined;\n\n//Tipo Number\nlet number = 1;\nlet noNumber = NaN;\n\n//Tipo String\nlet cadena = \"Hola Mundo\";\n\n//Tipo booleano\nlet verdad = true;\nlet falso = false;\n\n//5.-\nconsole.log(\"Hola JavaScript\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/DavidMoralesDeveloper.js",
    "content": "/*   EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\" */\n// 1\n//  Mi primer comentario despues de el ejercicio \"https://developer.mozilla.org/es/docs/Web/JavaScript\"\n\n// 2\n//  comentario en una sola linea\n/*  comentario de mas lineas\nlinea 1 */\n\n// 3\nconst constante = 'soy una constante'\nlet variable = 'soy una variable'\n\n// 4\n\nconst string  = 'soy un string'\nconst number = 5 //'soy un numero entero o decimal'\nnumber = number(1) //1\nconst numberEntero = 123n  //BigInt numeros muy grandes enteros\nnumber = BigInt(number) // 5n\nconst booleanos = true //false\nlet sym2 = Symbol(\"foo\") //symbol\nlet sym = new Symbol(); // TypeError\n//extras\nconst nada = null // null\nconst noencontrado = undefined //undefined\n\n//5\nconsole.log(\"¡Hola, Javascript!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/DaxterDEV.js",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n/*\n * Sitio web oficial de JavaScript:\n * https://developer.mozilla.org/es/docs/Web/JavaScript\n */\n\n// Comentario de una sola línea\n\n/*\nComentario\nde varias\nlíneas\n*/\n\n// Variable\nlet miVariable = \"Soy una variable\";\n\n// Constante\nconst MI_CONSTANTE = 3.1416;\n\n// Tipos de datos primitivos\nlet texto = \"Hola mundo\"; // String\nlet numero = 42; // Number\nlet decimal = 3.14; // Number (decimal)\nlet booleano = true; // Boolean\nlet indefinido = undefined; // Undefined\nlet nulo = null; // Null\nlet simbolo = Symbol(\"sim\"); // Symbol\nlet bigInt = 12345678901234567890n; // BigInt\n\n// Imprimir por terminal\nconsole.log(\"¡Hola, JavaScript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/DenisOrtega.js",
    "content": "// Lo primero ya elegiste el lenguaje? : Si\n// JavaScript https://developer.mozilla.org/es/docs/Web/JavaScript\n\n\n/**\n * Esto es un comentario\n * de varias lineas.\n */\n\n\nlet lenguaje = \"JavaScript\";\nconsole.log(\"Elijo:\", lenguaje);\n\n// Variables\n\nlet miVariable = 10;  // Las variables pueden cambiar su valor.\nmiVariable = 20;\nconsole.log(miVariable);\n\nvar miOtraVariable = 30;  // var es muy similar a let, pero tiene un alcance global.\nmiOtraVariable = 40;\nconsole.log(miOtraVariable);\n\n// Constantes\n\nconst PI = 3.1416;  // Las constantes no pueden cambiar su valor. En cambio puedes cambiar sus propiedades cuando se trata de un objeto.\nconsole.log(PI);\n\nconst persona = {   // En este caso, la constante persona es un objeto, por lo que sus propiedades pueden cambiar.\n    nombre: \"Denis\",\n    edad: 36\n};\nconsole.log(persona);\n\npersona.edad = 37;\nconsole.log(persona);\n\n// Tipos de datos\n\nlet numero = 10;\nlet cadena = \"Hola mundo\";\nlet booleano = true;\nlet arreglo = [1, 2, 3];\nlet objeto = {nombre: \"Denis\", edad: 37};\nlet nulo = null;\nlet indefinido = undefined;\nlet simbolo = Symbol(\"simbolo\");\nlet fecha = new Date();\nlet error = new Error(\"Error\");\n\n\n// typeof devuelve el tipo de dato de una variable.\nconsole.log(typeof numero);  // Devuelve \"number\"  Pueden ser enteros o decimales.\nconsole.log(typeof cadena);  // Devuelve \"string\"  Las cadenas de texto deben ir entre comillas dobles o simples.\nconsole.log(typeof booleano); // Devuelve \"boolean\" Pueden ser true o false.\nconsole.log(typeof arreglo); // Devuelve \"object\" Los arreglos son objetos.\nconsole.log(typeof nulo);  // Devuelve \"object\"  Es un error de JavaScript.\nconsole.log(typeof indefinido); // Devuelve \"undefined\"  Es un error de JavaScript.\nconsole.log(typeof simbolo); // Devuelve \"symbol\"  Se usa para identificadores únicos.\nconsole.log(typeof fecha);  // Devuelve \"object\"  Se usa para trabajar con fechas.\nconsole.log(typeof error);  // Devuelve \"object\" Se usa para trabajar con errores.\nconsole.log(typeof objeto);  // Devuelve \"object\"  Los objetos son colecciones de propiedades.\n\n// Operadores\n\nlet a = 10;\nlet b = 5;\n\nlet suma = a + b; // Suma\nlet resta = a - b; // Resta\nlet multiplicacion = a * b; // Multiplicación\nlet division = a / b; // División \nlet modulo = a % b; // Módulo (resto de la división) \nlet exponente = a ** b; // Exponente (a elevado a la b)\nlet incremento = a++; // Incremento en 1\nlet decremento = b--; // Decremento en 1 \nlet negacion = !true; // Negación (no) Devuelve false si el operando es true.\nlet and = true && false; // AND (y) Devuelve true si ambos operandos son true.\nlet or = true || false; // OR (o) Devuelve true si al menos uno de los operandos es true.\nlet igualdad = a == b; // Igualdad Devuelve true si los operandos son iguales. solo compara el valor.\nlet igualdadEstricta = a === b; // Igualdad estricta Devuelve true si los operandos son iguales y del mismo tipo.\nlet desigualdad = a != b; // Desigualdad Devuelve true si los operandos no son iguales.\nlet desigualdadEstricta = a !== b; // Desigualdad estricta Devuelve true si los operandos no son iguales o no son del mismo tipo.\nlet mayorQue = a > b; // Mayor que Devuelve true si el operando de la izquierda es mayor que el de la derecha.\nlet menorQue = a < b; // Menor que Devuelve true si el operando de la izquierda es menor que el de la derecha.\nlet ternario = a > b ? \"a es mayor que b\" : \"b es mayor que a\"; // Operador ternario : la primera expresion es cuando la condicion es verdadera, la segunda cuando es falsa.\n\nconsole.log(\n    suma,\n    resta,\n    multiplicacion,\n    division,\n    modulo,\n    exponente,\n    incremento,\n    decremento,\n    negacion,\n    and,\n    or,\n    igualdad,\n    igualdadEstricta,\n    desigualdad,\n    desigualdadEstricta,\n    mayorQue,\n    menorQue,\n    ternario\n);\n\n\nconsole.log(\"Hola mundo!\");\nconsole.log(\"Fin del ejercicio.\");\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/DerlingR.js",
    "content": "// https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n//Esta es la forma de hacer un comentario de una línea en JavaScript\n\n/* Esta es la forma\nde\nhacer comentarios\nde multiples líneas\nen JavaScript*/\n\nconst pi = 3.1416;\nlet edad = 23;\n\n//String\nlet nombre = \"Derling\";\n\n//Number\nlet anios = 23;\n\n//Boolean\nlet esMayor = true;\nlet esMenor = false;\n\n//undefined\nlet sinValor;\nconsole.log(sinValor); //undefined\n\n//null\nlet datos = null;\n\n//bigint\nlet numeroGrande = 9007199254740991n;\n\n//symbol\nlet id = Symbol(\"miSimbolo\");\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Deyvid-10.js",
    "content": "// URL del sitio web oficial de JavaScript: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Este es un comentario en línea\n\n/* Y esta es la manera \nen la que se hacen comentarios \nen varias líneas */\n\n// Creación de variable y constante\n\nlet variable = \"variable\"\nvar variable2 = \"variable 2\"\nconst constante = \"constante\"\n\n// Variables representando los tipos de datos primitivos\n\nlet cadenaTexto = \"Cadena de texto\"\nlet entero = 0\nlet booleano = true\nlet nulo = null\nlet indefinido = undefined\n\n\n// Imprimir por terminal\n\nconsole.log(\"¡Hola, JavaScript!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Diego-Santana23.js",
    "content": "// EJERCICIO\n\n\n// 1. Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n   \n//https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// 2. Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n\n// Comentario de una sola linea\n\n/* \nComentario \nen varias\nlineas\n*/\n\n// 3. Crea una variable (y una constante si el lenguaje lo soporta).\n\nvar numero = 5;\nconst pi = 3.1415;\n\n// 4. Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n\nlet numeroEntero = 15;\nlet numeroDecimal = 0.0034;\nlet numeroExadecimal = 0x7DE;\nlet boleano = true;\nlet nulo = null;\nlet indefinido = undefined;\nlet string = 'Primer ejercicio de logica de programacion';\n\n// 4. Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\nlet lenguaje = 'Javascript';\nconsole.log(`!Hola, ${lenguaje}`)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/DjSurgeon.js",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n// https://www.javascript.com/ \n/* https://developer.mozilla.org/es/docs/Web/JavaScript\n   https://es.javascript.info/ */\n\n// Variables y Constantes\nvar enDesuso = \"Ya no se suele usar para nombrar variables.\";\nlet masHabitual = \"Normalmente se utilizan asi.\";\nconst constanteInmutable = \"Esto es una constante y no puede variar\";\n\n// Datos primitivos\nlet indefinido = undefined;\nlet nulo = null;\nlet num = 879;\nlet string = \"Esto es una string o cadena de caracteres.\";\nlet boolean = true;\nlet boolean = false;\n\n//Saludos!\n\nconsole.log(\"¡Hola Javascript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/DobleDJ.js",
    "content": "/**\n * Retos de programación\n * Roadmap 00\n * Author: Yoandy Doble Herrera\n * Date: 05/12/2024\n */\n\n// Ejercicio 1\n/**\n * Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n */\n\n// Sitio oficial de Javascript => https://www.javascript.com/\n\n// Ejercicio 2 Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...)\n\n// Comentario en una línea\n\n/**\n * Este es un comentario\n * con varias líneas\n * by codebydoble\n */\n\n// Ejercicio 3 Crea una variable (y una constante si el lenguaje lo soporta).\n\nvar username = \"dobledj\" // var is deprecated\nlet nameUser = \"codebydoble\"\nconst piValue = 3.141592653589793\n\n/**\n * Ejercicio 4\n * - Crea variables representando todos los tipos de datos primitivos\n */\n\nlet fullName = \"Yoandy Doble Herrera\" //string\nlet count = 22 // number\nlet isTech = true //boolean\nlet nullValue = null //null\nlet emptyValue // undefined\nlet personalChart = Symbol(\"Abc\") // symbol\nlet hugeData = BigInt(\"9999999999999999999999999999999999999999999999999\") // bigInt\n\n/**\n * Ejercicio 5\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n */\n\nconsole.log(\"¡Hola, JavaScript!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/DouglasDiazR.js",
    "content": "/*https://developer.mozilla.org/es/docs/Web/JavaScript*/\n\n//Comentario en una sóla línea \n\n/*Comentarios\nen\nvarias\nlíneas*/\n\nvar miVariable = \"variable\";\nconst miConstante = \"constante\";\n\nvar number = 5;\nvar string = \"JavaScript\";\nvar boolean = true;\nvar boolean = false;\nvar undefined = undefined;\nvar nulo = null;\nvar BigInt = 12324239583049683049683025436n; //Representa números enteros mayores que el rango seguro para el tipo Number. Se declara añadiendo una n al final del número literal.\nconsole.log(\"hola \" + string);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/EdGonzz.js",
    "content": "/* Mi lenguaje de programación es JavaScript. \nCada dia aprendo algo nuevo de este lenguaje, y me encanta.*/\n\n// La documentación oficial de JavaScript es https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Este es un comentario en una linea\n/* Y este es un comentario de varias lineas */\n\nvar nombre = \"Edwin\"; // Var es una variable de contexto de ejecución global.\nlet apellido = \"Contreras\"; // Let es una variable con un contexto de ejecución local.\nconst PI = 3.1416; // Const es una constante.\n\n// En JavaScript existen 7 tipos de datos primitivos:\nconst Number = 1; // Para números de cualquier tipo: enteros o flotantes, etc.\n\nconst BigInt = 1234567890123456789012345678901234567890n; // BigInt es un tipo de dato que permite almacenar números enteros de longitud arbitraria.\n\nconst String = \"Hola mundo\"; // Para cadenas de texto. Se pueden definir con comillas simples, dobles o invertidas.\n\nconst Boolean = true; // Boolean son valores booleanos, true o false.\n\nconst Null = null; // El valor null es un literal de Javascript que representa intencionalmente un valor nulo o \"vacío\".\n\nconst Undefined = undefined; // Tipo especial que solo contiene el valor undefined.\n\nconst Symbol = Symbol('Esto es un valor único.'); // Para valores únicos.\n\n// Para imprimir en consola se utiliza console.log()\nconsole.log(\"Hola mundo les presento JavaScript\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/EliMejiaP.js",
    "content": "\n/*\n*Ejercicio\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n// Iniciando el ejercicio numero 00 de la ruta de estudio Roadmap\n\n//https://www.ecma-international.org/ecma-262/. \n\n// primera forma de hacer comentarios en ua linea(//)\n\n/* segunda forma de hacer\ncomentarios multiples en varias lineas*/\n\nlet variable = \"cadena de texto\";\nconst constante = \"constante\";\n/* la palabra reservada var antes se usaba para declarar variables en javascript\npero ya no se usa en la actualidad */\n\n//el punto y coma al final de una sentencia es opcional en javascript\nlet number= 10;//Representa tanto números enteros como números de punto flotante.\nlet numero = 1.5;\n\nlet boolean = true;//Representa valores lógicos: true (verdadero) o false (falso).\nlet booleano = false;\n\nlet nullValue = null;//Representa la ausencia intencional de cualquier valor\nlet undefinedValue = undefined;//Representa una variable a la que no se le ha asignado un valor.\n\nlet string = \"cadena de texto\"; //Representa secuencias de caracteres. Se pueden definir con comillas simples (' '), dobles (\" \") o backticks (`).\n\nlet symbol = Symbol(\"symbol\");  //Representa un valor único e inmutable.\n\nlet bigInt = 1234567890123456789012345678901234567890n;//de esta forma se declara un bigInt     \nlet bigInt2 = BigInt(1234567890123456789012345678901234567890);//otra  forma de declarar un bigInt\n\nconsole.log(\"¡Hola, JavaScript!\");//Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/EliTeDev-44.js",
    "content": "/*\n_____________________________________\nhttps://github.com/JDesing\n2025 - JavaScript\n___________________________________________________\n00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n---------------------------------------------------\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n*/\n\n// Documentación:\n// https://www.ecma-international.org/publications-and-standards/standards/ecma-262/\n// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Comentario de una línea\n\n/*\nComentario\nde varias\nlíneas\n*/\n// _______________________\n// Creando tipos de Variables y Constantes\nlet = miVariable = \"JDesing\" // Variable\nconst PI = 3.14159; // Constante\n\n// _______________________\n// Tipos de datos primitivos (https://developer.mozilla.org/es/docs/Web/JavaScript/Data_structures#valores_primitivos).\n// Variables con datos Primitivos\nlet numero = 2025          // Tipo Number (número entero).\nlet decimal = 3.14         // Tipo Number (número decimal).\nlet miString = 'JDesing'   // Tipo String (cadena de texto).\nlet boleanoTrue = true     // Tipo Boolean (booleano).\nlet boleanoFalse = false   // Tipo Boolean (booleano).\nlet nulo = null            // Tipo Null (valor nulo).\nlet indefinido              // Tipo Undefined (variable no definida).\nlet numeroGrande = 1447999254740991n // Tipo BigInt (número entero grande).\nlet simbolo = Symbol(\"id\") // Tipo Symbol (valor único e inmutable).\n\n// Mostrando el tipo de dato de cada variable\nconsole.log(\"===============================\")\nconsole.log(\"Tipos de datos primitivos:\")\nconsole.log(typeof numero)\nconsole.log(typeof decimal)\nconsole.log(typeof miString)\nconsole.log(typeof boleanoTrue)\nconsole.log(typeof boleanoFalse)\nconsole.log(typeof nulo)\nconsole.log(typeof indefinido)\nconsole.log(typeof numeroGrande)\nconsole.log(typeof simbolo)\n\n// _______________________\n// Imprimiendo en consola\nconsole.log(\"¡Hola, JavaScript!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/EloyChavezDev.js",
    "content": "// URL del sitio web oficial de JavaScript: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Comentario de una línea\n\n/*\n  Comentario de varias líneas\n  (JavaScript)\n*/\n\n// Variable\nvar nombre = \"Tu nombre\";\n\n// Constante (a partir de ES6)\nconst PI = 3.14159;\n\n// Tipos de datos primitivos\nlet cadena = \"Hola, mundo!\";\nlet numeroEntero = 10;\nlet numeroDecimal = 10.5;\nlet booleano = true;\nlet nulo = null;\nlet indefinido = undefined;\n\n// Imprimir por terminal\nconsole.log(`¡Hola, JavaScript!`);"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/EloyParga.js",
    "content": "// Esto es Un comentario en linea\n\n/*\nEste es un\ncomentario en \nBloque\n*/\n\n/**\n * Esta es otra forma de comentar\n * es en bloque\n * y se usa para documentar.\n */\n\n// Sitio web oficial de JavaScript:\n// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n\n//VARIABLES Y CONSTANTES\n\n//Variables (SE USA NORMALMENTE 'let')\nlet varibleLet = 'Esto es una cadena de texto'\nvar variableVar = \"Esto tambien es un txt\" //No se suele usar normalmente \n\n//Constantes (No puede cambiar de Valor una vez se asigne)\nconst CONSTANTE_EJEMPLO = \"Esto es una constante\"\n\n//DATOS PRIMITIVOS\n\n//String\nlet cadena = \"Hola, JS\"\nlet cadena2 = 'Hola , JavaScript'\n\n//Number (Int, float, ...)\nlet entero = 276\nlet decimal = 0.4\nlet negativo = -8\n//BigInt (numero muy grande)\nlet numeroGrande = 8349586348294983248723\n\n//Boolean (Valores lógicos True o False)\nlet verdadero = true\nlet falso = false\n\n//Undifined (Variable sin valor)\nlet indefinida;\n\n//Null (Dato que vale Nulo)\nlet nulo = null\n\n//Symbol (Valor Unico e Inmutable)\nlet Simbolo = Symbol(\"simbolo\")\n\n// IMPRIMIR POR TERMINAL\nconsole.log(\"==== ¡HOLA, JavaScript! ====\")\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/EnrGarVic.js",
    "content": "    /*\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n */\n\n    //comentario\n    /*comentario largo*/\n\n    //variables\n    let variableLet = \"Soy una variable let\";\n    console.log(variableLet)\n    const VARIABLE_CONST = \"Soy una variable constante\";\n    console.log(VARIABLE_CONST)\n\n    /*Representa las diferentes sintaxis que existen de crear comentarios\n    en el lenguaje (en una línea, varias...)*/\n    let texto = \"Hola mundo\";\n    let numero = 5;\n    let verdadera = true;\n    let falsa = false;\n    let nulo = null;\n    let indefinido = undefined;\n    let objeto = {};\n    let array = [];\n    let funcion = function(){}\n\n    //Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n    console.log(\"Hola, JavaScript\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Ercky1980.js",
    "content": "// https://www.javascript.com/\n\n//Comentario en una linea\n\n/**Esto es comentario en\n * varias lineas con javascript\n */\n\n/*\nComentario en varias lineas\nsin el asterisco en cada una\n */\n\nlet myAge = \"43\";\n\nconst myName = \"Erick E.\";\n\nlet number = 10;\nlet decimal = 0.5;\nlet string = \"SantaAna\";\nlet otherString = 'SantaAna';\nlet verdadero = true;\n\nconsole.log(\"Hola JavaScript\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/EricJoel-code.js",
    "content": "// https://www.javascript.com/\n\n// JavaScript es un lenguaje de programación que se utiliza principalmente para crear contenido interactivo en sitios web.\n\n// Sintaxis de comentarios en JavaScript:\n\n// Comentario de una sola línea\n\n/* Comentario\n   de múltiples líneas */\n\n// Declaración de variables en JavaScript:\n\n// Usando var (antiguo, no recomendado)\nvar name = \"Eric Joel\";\n\n// Usando let (recomendado para variables que pueden cambiar)\nlet age = 25;\n\n// Usando const (recomendado para valores constantes)\nconst PI = 3.1416;\n\n// Tipos de datos en JavaScript:\n\nlet number = 26; // Número\nlet text = \"Hola\"; // Cadena de texto\nlet isTrue = true; // Booleano\nlet nullValue = null; // Valor nulo\nlet undefinedValue; // Valor indefinido\nlet object = { key: \"value\" }; // Objeto\nlet array = [1, 2, 3]; // Arreglo\n\n// Imprimir en la consola\nconsole.log(\"¡Hola, JavaScript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Erysnell.js",
    "content": "// https://developer.mozilla.org/es/docs/Web/JavaScript\r\n\r\n// comentarios de una sola linea\r\n/*comentarios\r\nde varias lineas*/\r\n\r\nlet variable;\r\nconst constante = 5;\r\n\r\nlet number = 1;\r\nlet string = 'string';\r\nlet boolean = true;\r\nlet array = [1,2,3];\r\n\r\nconsole.log(\"Hola Javascript\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/FabianRpv.js",
    "content": "// Sitio oficial: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Esto es un comentario de una sola línea\n\n\n/*\nEsto es un comentario\nde varias líneas\n*/\n\n\n// Crear una variable\n\nvar variable1 = 1; // Forma antigua de declarar una variable\nlet variable2 = 2; // Forma utilizada en ES6\n\n// Crear una constante\n\nconst constante = 3;\n\n\n// Tipos de datos\n\nlet name = 'Fabian'; // String (cadena de texto)\n//console.log(typeof name);\n\nlet age = 25; // Number (número)\n//console.log(typeof age);\n\nlet height = 1.65; // Number (número con decimales)\n//console.log(typeof height);\n\nlet isMale = true; // Boolean (valor verdadero o falso)\n//console.log(typeof isMale);\n\nlet undefinedVariable; // Undefined (variable sin valor)\n//console.log(typeof undefinedVariable);\n\nlet nullVariable = null; // Null (valor nulo)\n//console.log(typeof nullVariable);\n\nlet mySymbol = Symbol('mySymbol'); // Symbol (valor único)\n//console.log(typeof mySymbol);\n\nlet myBigInt = 9007199254740991n; // BigInt (números enteros muy grandes)\n//console.log(typeof myBigInt);\n\n\n// Imprimiendo en consola\n\nconsole.log('¡Hola, JavaScript!');"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Facundo-Muoio.js",
    "content": "// Esta es la forma de realizar comentario en linea en JavaScript.\n\n/* \nY esta es la forma de hacer comentarios en \nmultiples líneas\ndentro de JavaScript. \n*/\n\n// Creando una variable y una constante\nlet age = 28;\nconst name = \"Facundo Muoio\";\n\n// Tipos de datos primitivos en JS:\n// valor de cadena de texto\nlet string = \"Hello World!\";\n// valor de tipo numérico\nlet number = 26;\n// valor de tipo booleano\nlet truty = true;\nlet falsy = false;\n// valor de tipo nulo\nlet nullish = null;\n// valor de tipo undefined\nlet undefinish = undefined;\n// valor de tipo symbol\nlet symbol = Symbol(\"foo\");\n// valor de tipo bigInt\nlet bigInt = BigInt(9007199254740991);\n\nconsole.log(\"Hello JavaScript\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/FernandoFL.js",
    "content": "// URL documentación de Javascript --> https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Este es un comentario en línea\n\n/* \nEste \nes un\ncomentario\nen\nbloque\n */\n\n// Variables y Constantes\nlet miVariable = 'Esta es una variable'\nconst miConstante = 'Esta es una constante'\n\n// Tipo de datos primitivos\n\n// BOOLEAN\nlet boolean = true;\nboolean = false;\n\n// NULL\nlet isNull = null;\n\n// UNDEFINED\nlet isUndefined = undefined;\n\n// NUMBER\nlet number = 1;\nnumber = 12.345;\n// NOTA: En JS todos los valores numéricos se representan como números de punto flotante\n\n// BIGINT\nlet bigInt = 1234567890123456789n;\n// NOTA: Para que sea considerado como BigInt al final del número se debe adicionar la letra 'n' \n\n// STRING\nlet string= 'Este es un String';\n\n// SYMBOL\nlet symbol=Symbol('MI-SYMBOL');\n\n// Imprimir por terminal\nlet nombreLenguaje = 'JavaScript';\nconsole.log(`Hola, ${nombreLenguaje}`);"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Flarien.js",
    "content": "//  EJERCICIO:\n\n//  - Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n\n// JavaScript rules! ❤️ https://www.javascript.com/\n\n\n\n//  - Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n\n/* Comentario \nen \nvarias \nlineas\n¡CHAN! \n*/\n\n\n\n//  - Crea una variable (y una constante si el lenguaje lo soporta).\nvar variable = \"Variable viejita, voluble\";\n\nconst constante = \"Una variable... pero constante(?\";\n\nlet variableLimitada = \"Variable, pero mas estable\";\n\n\n\n//  - Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n\n// Cadena de texto (string)\nlet string = \"JavaScript\";\n\n// Número entero (integer)\nlet entero = 8;\n\n// Número decimal (float)\nlet decimal = 3.14;\n\n// Booleano (boolean)\nlet verdadero = true;\nlet falso = false;\n\n// Undefined\nlet undefined;\n\n// Null\nlet nulo = null;\n\n// Símbolo (symbol)\nlet simbolo = Symbol('simbolo');\n\n// BigInt\nlet grande = BigInt(9007199254740991);\n\n\n\n//  - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nconsole.log(`¡Hola, ${string}`);"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/FranciscoCuminiLondero.js",
    "content": "// https://www.javascript.com/\n\n// Comentario de una línea\n\n/*\nComentario \nde varias \nlíneas\n*/\n\nconst MI_NOMBRE = \"Francisco Cumini\";\nlet edad = 23;\n\nlet myString = \"Francisco\";\nlet myNumber = 1;\nlet myBoolean = true;\nlet myNull = null;\nlet myUndefined = undefined;\nlet mySymbol = Symbol();\nlet myBigInt = BigInt(32);\n\nconsole.log(\"¡Hola, JavaScript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/FrannM29.js",
    "content": "// Sitio oficial del lenguaje en cuestion https://developer.mozilla.org/es/docs/Web/JavaScript\n\n/*\nesto\nes\nun\ncomentario\nde\nvarias\nlineas\n*/\nvar lenguajeName = \"JavaScript\";\nvar numberType = 77;\nvar booleanType = \"false\";\nvar stringType = \"string\";\nvar nullType = null ;\nvar undefinedTipe = \"undefined1\";\nvar bigInt = 1000000000000000000000000000;\n\nconsole.log (\"Hola, JavaScript\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/FullStacKarlo.js",
    "content": "//https://www.javascript.com//\r\n\r\n//Comentario de una sola línea//\r\n\r\n/*\r\n    Esto\r\n    Es\r\n    Un\r\n    Comentario\r\n    Multilinea\r\n*/\r\n\r\n\r\nvar x = 5; //Variable llamada X con valor igual a 5//\r\n\r\nconst price = 20; //Variable constante llamada price con valor igual a 20//\r\n\r\nlet name = carlos; //string//\r\nlet age = 24; //int//\r\nlet sundistanceinmeters = 149597870700; //BigInt//\r\nlet boolean = false; //Booleano//\r\nlet imNull = null; //Null//\r\nlet sym1 = Symbol(\"simbolo1\"); //Symbol//\r\nlet myundefined = undefined; //Undefined//\r\n\r\nconsole.log(\"¡Hola, JavaScript!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Glitzypanic.js",
    "content": "// https://developer.mozilla.org/en-US/docs/Learn/Getting_started_with_the_web/JavaScript_basics sitio no oficial\n\n// Esta es una forma de comentar en JavaScript en una linea\n\n/* \n    Esta es otra forma de comentar en JavaScript\n    en mas de una linea\n*/\n\nvar nombre = \"José\"; // Declaración de una variable\n\nconst apellido = \"Farías\"; // Declaración de una constante\n\nvar edad = 25; // Number\nvar nombre = \"José\"; // String\nvar estudiante = false; // Boolean\nvar vacio = null; // Null\nvar indefinido = undefined; // Undefined\nvar array = [1, 2, 3, 4, 5]; // Array\nvar objeto = {\n  nombre: \"José\",\n  edad: 25,\n}; // Object\n\nconsole.log(\"!Hola, JavaScript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/HaryBlanco20.js",
    "content": "/*El lenguaje de programación que he seleccionado es JavaScript.\nURL del sitio web oficial de JavaScript es https://developer.mozilla.org/es/docs/Web/JavaScript\n*/\n\n//Comentario de una línea\n\n/*Comentatio de\nvarias\nlíneas*/\n\n//variable\nlet miVariable = \"variable\";\nconst miConstante = \"constante\"\n\n\n//Tipos de datos\nlet cadena =\"Hola mundo\"\nlet booleano = true\nlet entero = 567\nlet flotante = 1.43\nlet array = [1, \"Hola\", true]\nlet objeto = {\n    nombre: \"Hary\",\n    apellido: \"Blanco\",\n    edad: 28\n}\nlet arregloDeObjetos = [\n    {\n        nombre: \"Hary\",\n        apellido: \"Blanco\",\n        edad: 28\n    },\n    {\n        nombre: \"Pedro\",\n        apellido: \"Blanco\",\n        edad: 56\n    }\n]\n\nlet lenguaje = javascript\nconsole.log('\"¡Hola, mi lenguaje es' + lenguaje + '!\"')\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/HectorIglesias.js",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n//Sitio web oficial: https://developer.mozilla.org/es/\n\n//Comentario en línea\n/*\n* Comentario en bloque \n*/\n\n//Tipos de datos primitivos\nlet int = 0  //Int\nlet float = 1.0 //Float\nlet string = \"Hola mundo\" //String\nlet boolean = True //Boolean\nlet undefined = undefined\nlet bigInt = 121437679698743648965734542653n //BigInt\n\n//Constante\nconst constante = [\"Hola mundo\"]\n\n//Mensaje por consola\nconsole.log(\"Hola Javascript\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/HugoLuquePerez.js",
    "content": "/* Esta es la documentación que voy a seguir: https://developer.mozilla.org/es/docs/Web/JavaScript */\n\n// Esta es la sintaxis para comentar en una linea\n\n/*\n    Esta es la sintaxis para comentar en varias líneas\n*/\n\n// Varibles\n// Let es más utilizadp, declara una variable local con ámbito de bloque\n\nlet saludar=\"Hola\";\n\n// var declara una variable\nvar saludar1=\"Hola\";\n\n// Constante\nconst saludar2=\"Hola\";\n\n// Variables con todos los tipos de datos primitivos\n\nlet indefinido=undefined;\nlet booleano=true;\nlet numero=1;\nlet decimal=1.13;\nlet nombre=\"Pedro\";\nlet nulo=null;\n\n//Imprimir por terminal\nconsole.log(\"¡Hola, JavaScript!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/IsNatthy.js",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */ \n\n// This is a one-line comment: https://developer.mozilla.org/en-US/docs/Web/javascript\n\n/*\n This is\n a multiple line\n comment\n*/\n\nlet IsNatthy = \"Tonta\" \n\nconst MyStupidity = 999999 \n\n//Number\nlet Myself = 18\n\n//String\nlet HW = \"Hello, JavaScript!\"\n\n//Boolean\nlet falsetype = false\n\nconsole.log(HW); \n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/JELozanoV.js",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n// 1. Sintaxis de cometarios en javascript \n/* 2. sintaxis de comentarios \nEsto es un comentario\nde varias lineas \n*/\n// https://www.javascript.com/\n\nlet variable1 = \"Variable let\"\nvar variable2 = \"Variable var\"\nconst pi = 3.14\n\nlet string = \"string\"\nlet number = 0\nlet numGrande = 2727272727272727n;\nlet boolean = true \nlet nula = null\nlet indefinida = undefined\nlet simboloRaro = Symbol()\n\nconsole.log('Hola Javascript');\n\nconsole.log(typeof(string));\nconsole.log(typeof(number));\nconsole.log(typeof(boolean));\nconsole.log(typeof(nula));\nconsole.log(typeof(indefinida));\nconsole.log(typeof(simboloRaro));\nconsole.log(typeof(numGrande));"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/JLCareglio.js",
    "content": "/*\n JavaScript no tiene un sitio web oficial como tal,\n pero las siguientes paginas son relevantes para el lenguaje:\n\n - MDN Web Docs: documentación oficial y mantenida por los creadores de JavaScript.\n   (https://developer.mozilla.org/es/docs/Web/JavaScript)\n\n - ECMAScript: es el estándar que regula el lenguaje JavaScript\n   (https://ecma-international.org/)\n*/\n\n// Este es un ejemplo de comentario de una linea.\n\n/*\n Este es un ejemplo\n de comentario de\n multiples lineas\n*/\n\n// Declaración de variable y constante\nlet variable;\nconst LANG = \"JavaScript\";\n\n// Hay 6 tipos de datos primitivos: string, number, bigint, boolean, undefined y symbol.\nlet my_string = \"cadena de caracteres\";\nlet my_number = 7;\nlet my_bigint = 7n;\nlet my_boolean = true;\nlet my_undefined = undefined;\nlet my_symbol = Symbol();\n// null aparentemente es primitivo, pero de hecho es un caso especial para cada Object.\n\nconsole.log(`¡Hola, ${LANG}!`);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Ja-bell.js",
    "content": "/* Web oficial del lenguaje: \n * https://developer.mozilla.org/es/docs/Web/JavaScript \n */\n\n// Esto es un comentario de una linea\n\n/*\nEsto es\nun comentario\nde varias lineas\n*/\n\n// Variables y constantes del lenguaje\nvar variable1\nlet variable2\nconst constante\n\n// Tipos de datos primitivos (segun la pagina web oficial del lenguaje)\nvar boleano1 = true\nvar boleano2 = false\nvar nulo = null\nvar indefinido //este es un valor que se le asigna a una variable la cual fue declarada mas no inicializada o no utilizadas\nvar number1 = 21 //un numero entero\nvar number2 = 21.5 //un numero decimal\nvar bigInt = 9876543210 //numero entero grande (podria ser mas grande)\nvar string = \"Javascript\" //una linea de texto (las comillas son importantes)\nvar symbol = symbol(\"simbolo\") //tipo de dato primitivo añadido el 2015 que sirve como un identificador unico e inmutable (que no se puede cambiar)\n\n// Imprimiendo por la terminal un 'hola javascript'\nconsole.log(\"Hola Javascript\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Jalivur.js",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n*/\n\n\n\n//https://developer.mozilla.org/es/docs/\n//COMENTARIOS:\n\n// un comentario de una línea\n\n/* \neste es un comentario\nmás largo, de varias líneas\n*/\n\n//* Sin embargo, no puedes /* anidar comentarios */ SyntaxError */\n\n//DECLARACIONES:\n\n    var firstVar =\"En desuso\"; //declaracion en sesuso, no tiene ambito de declaracion de bloque\n    console.log(firstVar);\n    console.log(typeof(firstVar));\n    firstVar=5;\n    console.log(firstVar);\n    console.log(typeof(firstVar));\n    let secondVar; \n    console.log(secondVar);\n    secondVar= \"Uso actual\"; //declaracion variable local y de bloque, se pueden inicializar con valor o no.\n    console.log(secondVar);\n    console.log(typeof(secondVar));\n    secondVar=5;\n    console.log(secondVar);\n    console.log(typeof(secondVar));\n    const firstConst = \"No puedo cambiar\" //Declara un nombre de constante de solo lectura y ámbito de bloque.\n    console.log(firstConst);\n    console.log(typeof(firstConst));\n    //firstConst =5; no se puede cambiar su valor\n\n/*\nUtiliza variables como nombres simbólicos para valores en tu aplicación. \nLos nombres de las variables, llamados identificadores, se ajustan a ciertas reglas.\nUn identificador de JavaScript debe comenzar con una letra, un guión bajo (_) o un signo de dólar ($). \nLos siguientes caracteres también pueden ser dígitos (0-9).\n*/\n\n//javaScript tiene siete tipos de datos que son primitivos:\n    //booleano\n    let myBool=true;\n    console.log(myBool);\n    console.log(typeof(myBool));\n    myBool=false;\n    console.log(myBool);\n    console.log(typeof(myBool));\n    /*nulo o null Una palabra clave especial que denota un valor nulo. \n    (Dado que JavaScript distingue entre mayúsculas y minúsculas, \n    null no es lo mismo que Null, NULL o cualquier otra variante).*/\n    let myNull = null;\n    console.log(myNull);\n    console.log(typeof(myNull));\n    //undefined, o sin definir.\n    let myUndefined;\n    console.log(myUndefined);\n    console.log(typeof(myUndefined));\n    //Number. Un número entero o un número con coma flotante. Por ejemplo: 42 o 3.14159.\n    let myNumber = 5;\n    console.log(myNumber);\n    console.log(typeof(myNumber));\n    myNumber = -596.5;\n    console.log(myNumber);\n    console.log(typeof(myNumber));\n    //Bigint. Un número entero con precisión arbitraria. Por ejemplo: 9007199254740992n.\n    const myBigint=5896n;\n    console.log(myBigint);\n    console.log(typeof(myBigint));\n    myNumber=4796;\n    let mySecondBigint=BigInt(myNumber);\n    console.log(mySecondBigint);\n    console.log(typeof(mySecondBigint));\n    //String. Una secuencia de caracteres que representan un valor de texto. Por ejemplo: \"Hola\".\n    let myString=\"Hola, Me llamo Alberto\";\n    console.log(myString);\n    console.log(typeof(myString));\n    //Simbol (nuevo en ECMAScript 2015). Un tipo de dato cuyas instancias son únicas e inmutables. Se utiliza para crear identificaodres únicos para los objetos.\n    let mySymbol = Symbol();\n    console.log(mySymbol);\n    console.log(typeof(mySymbol));\n//Hola Mundo:\n    // Imprimir por terminal:\n    console.log(\"¡Hola, JavaScript!\");\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/JanuarAsprilla.js",
    "content": "//Sitio oficial de la documentacion de JavaScript -> https://developer.mozilla.org/es/docs/Web/JavaScript\n\n//Comentarios\n// Esta sintaxis es para crear un comentario de una linea\n/*\nEsta sintexis es para crear comentarios de diferentes lineas\n*/\n\n//Variables\nvar Variable1 = 'Esta Variable esta declarada en var'\nlet Variable2 = 'Esta Variable esta declarada en let'\nconst Constante1 = 0\n\n//Tipos de Datos\nconst str = 'Letras'\nconst num = 10\nconst float = 12.5\nconst bool = true || false\nconst BigInt = 23165451651135165135145641n\nlet udf = undefined\nconst nulo = null\nconst id = Symbol(\"id_unico\")\n\n//imprimir console log\nlet holaJavaScript\nconsole.log(holaJavaScript(\"Hola, JavaScript\"))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/JavierADev.js",
    "content": "//https://developer.mozilla.org/es/docs/Web/JavaScript\n\n//ESTO ES UN COMENTARIO DE UNA SOLA LINEA \n\n/*ESTO ES UN COMENTARIO\nDE MULTIPLES LINEAS*/\n\nlet text = \"esto es una variable\";\nconst text2 = \"esto es una constante\";\n\n// ESTO ES UNA VARIABLE TIPO TEXTO\nlet string = \"Hola mundo\";\n\n// ESTO ES UNA VARIABLE TIPO NUMERO ENTERO\nlet numeroEntero = 50;\n\n// ESTO ES UNA VARIABLE TIPO NUMERO FLOTANTE\nlet numeroFlotante = 5.14;\n\n// ESTO ES UNA VARIABLE TIPO BOOLEANO\nlet verdadero = true;\nlet falso = false;\n\n// ESTO ES UNA VARIABLE TIPO INDEFINIDO SE UTILIZA CUANDO NO QUIERES DEFINIR LA VARIABLE \nlet undefined;\n\n// ESTO ES UNA VARIABLE TIPO NULL SE UTILIZA PARA DEFINIR UNA VARIABLE PERO SIN NINGUN VALOR\nlet nulo = null;\n\n\n// ESTO ES UNA VARIABLE TIPO Symbol\nlet idenficador = Symbol(\"descripcion\");\n\n// ESTO IMPRIMI UN MENSAJE EN CONSOLA\nconsole.log('\"¡Hola, JavaScript!\"');\nconsole.log(numeroEntero + numeroFlotante);"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/JehiselRuth.js",
    "content": "// EJERCICIO:\n\n//  * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n//  *   lenguaje de programación que has seleccionado.\n//  * - Representa las diferentes sintaxis que existen de crear comentarios\n//  *   en el lenguaje (en una línea, varias...).\n//  * - Crea una variable (y una constante si el lenguaje lo soporta).\n//  * - Crea variables representando todos los tipos de datos primitivos\n//  *   del lenguaje (cadenas de texto, enteros, booleanos...).\n//  * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\n// --------------------------------------------------------------------------------------------------------------------\n\n//Sitio oficial del lenguaje de Javascript ECMA url: https://262.ecma-international.org/\n\n/*Javascript tiene dos formas de crear comentarios, la primera con barra lateral / y asterisco * como vemos \ncon este estilo puedes comentar varias líneas.\nLas...\nQue...\nNecesites. */\n\n// Esta es la segunda forma, sólo con dos barras laterales, pero sólo te vale para una línea a la vez y tiene un atajo\n// el cual es la tecla CTRL y la tecla Ç sostenidas.\n\nlet myLanguage = 'Javascript';\nconst studyTime = 25;\n\n//Datos primitivos en Javascript:\n\nlet stringType =  \"Hello world\";\nlet numberType = 23;\nlet booleanType = true;\nlet nullType = null;\nlet undefinedType = undefined;\nlet symbolType = Symbol;\nlet biginitType = 23n;\n\n\nconsole.log('¡Hola', myLanguage +'!');\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/JeisonRedondo.js",
    "content": "// Hola soy Jeison Redondo y este es un comentario de una linea, la url de Javascript es :https://www.javascript.com/\n\n/*\nEste es un comentario que puede \nmanejar varias lineas\n*/\n\n// Javascript y sus variables\n\nvar estaEsUnaVariable = false; //Aunque no recomendada, esta es una forma de definir una variable\n\nlet estaEsOtraVariable = true; //Esta es hoy en dia la recomendación a la hora de definir una variable dinamica.\n\nconst laReinaDeJS = \"Hola como estan\"; // Si esta es la variable constante de JS\n\n// Javascript - Datos Primitivos\n\nlet numerosNormales = 21;\n\n// Estos dos numeros son la forma de manejar numeros muy grandes en JS\nlet numerosGrandes = BigInt(234934823984);\n\nlet otroNumeroGrande = 23894284729374823748937n;\n\nconst cadenasDeTexto = \"Esto es una cadena de texto\";\n\nconst otraCadenaDeTexto = \"Tambien podemos hacerlas con estas comillas\";\n\nlet unaCadenaMuyEspecial = `Con estas comillas podemos incluir ${\"varia\" + \"bles\"}`;\n\nlet soyFalso = false;\n\nconst soyVerdadero = true;\n\nlet soyNull = null;\n\nconst estoyUndefined = undefined;\n\nlet noSoyUnNumero = NaN;\n\nconsole.log(\"¡Hola, estoy estudiando Javascript\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #00 - JavaScript ->Jesus Antonio Escamilla */\n// Este es parte de la documentación del programa de lenguaje JavaScript https://developer.mozilla.org/es/docs/Web/JavaScript\n\n\n// Se puede expresar de la siguientes maneras.\n\n// La forma mas común de comentar un comentario de una línea (// Comentario)\n\n/**\n    De esta manera se puede\n    comentar partes grandes de\n    de un comentario.\n*/\n//  (/*Comentario*/)\n\n\n// Dentro de las variables tenemos estas\n// VAR\nvar nombre = \"Jesus Antonio\";\n// LET\nlet apellido = \"Solano\";\n\n// Solo existe una constante que es CONST\nconst celular = 1234567890;\n\n\n// Dentro de los datos Primitivos son los siguientes:\n\n// NULL\nvar x = null; /**O*/ var y = undefined;\n\n// Number O Number Decimal\nvar numeroEntero = 1;\nvar numeroDecimal = 1.1;\n\n// String\nvar cadena = \"Jesus Antonio\";\n\n//Boolean\nvar VerdaderoOFalso = true; /**O*/ var VerdaderoOFalso = false;\n\n\n// Imprime en la consola\nconsole.log(\"¡Hola, JavaScript\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/JheisonQuiroga.js",
    "content": "/* \n# Author: Jheison Duban Quiroga Quintero\n# Github: https://github.com/JheisonQuiroga\n\n* EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\" */\n\n\n/* \nJavaScript\nNo tiene una página oficial como tal, pero su documentación se encuentra en ECMASCRIPT y MDN\n- https://ecma-international.org/publications-and-standards/standards/ecma-262/\n- https://developer.mozilla.org/es/docs/Web/JavaScript\n*/\n\n// Comentario de una línea\n\nlet myvar\nconst name = \"Duban\"\n\n// Tipos de datos primitivos\nlet name2 = \"Duban\"\nlet age = 26\nlet isStudent = true\nlet graduated\nlet status = new String(\"Estudiante\")\nlet sym = Symbol(\"id\")\n\nconsole.log(typeof name2) // string\nconsole.log(typeof age) // number\nconsole.log(typeof isStudent) // boolean\nconsole.log(typeof graduated) // undefined\nconsole.log(typeof status) // object\nconsole.log(typeof sym) // symbol\n\nconst language = \"JavaScript\"\n\nconsole.log(`Hello, ${language}`)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Joanfv-git.js",
    "content": "//https://www.javascript.com/\n\n//Este es un comentario de una sola línea\n/* Este es un comentario de varias líneas */\n\n//Declaración de variables\n//var es la forma antigua de declarar variables\nvar x;\n//let es la forma moderna de declarar variables y se diferencia de var en que let tiene un alcance de bloque y var tiene un alcance de función\nlet y;\n//const es la forma moderna de declarar constantes\nconst z = \"constante\";\n\n//Tipos de variables\n//number\nlet a = 1;\n//string\nlet b = \"Hola Mundo\";\n//boolean\nlet c = true;\n//array\nlet d = [1, 2, 3];\n//object\nlet e = { nombre: \"Joan\", edad: 27 };\n//function\nlet f = function () {\n  return \"Hola Mundo\";\n};\n//undefined\nlet g;\n//null\nlet h = null;\n\n//Mostrar en consola\nconsole.log(\"¡Hola, JavaScript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/JoaquinLopez14.js",
    "content": "/*\n * EJERCICIO:\n * 1 Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * 2 Representa las diferentes sintaxis que existen de crear comentarios\n    en el lenguaje (en una línea, varias...).\n * 3 Crea una variable (y una constante si el lenguaje lo soporta).\n * 4 Crea variables representando todos los tipos de datos primitivos\n    del lenguaje (cadenas de texto, enteros, booleanos...).\n * 5 Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n */\n\n\n// 1: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// 2: Existen 2 formas de crear comentarios en JavaScript:\n// Comentario de una sola línea\n// Esto es un comentario de una sola línea\n\n/* \n  Comentario de múltiples líneas\n  Esto es un comentario\n  que abarca varias líneas\n*/\n\n // 3 =\n let variable = 1; // variable\n const variable2 = 2; // constante\n\n // 4 =\n let string = \"esto es un string\";\n let numEntero = 1;\n let numDecimal = 1.5;\n let booleanTrue = true;\n let booleanFalse = false;\n let nulo = null;\n\n let object = {\n    nombre: \"Joaquin\",\n    apellido: \"Lopez\"\n };\n\n //5 =\n let helloWorld = \"¡Hola, Javascript!\";\n console.log(helloWorld);\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/JohanRV.js",
    "content": "/* \n    https://developer.mozilla.org/es/docs/Web/JavaScript    sitio web oficial\n    https://es.javascript.info/     sitio de aprendizaje preferido\n*/\n\n// Este es un comentario en una linea\n\n/* \n    Este es \n    un \n    comentario\n    en varias lineas\n*/\n\nvar myFirtVariable = \"texto\"; // primera forma de crear variables -> es la antigua forma no se recomienda.\nlet mySecondVariable = \"Otro texto\"; // segunda forma de crear variables -> es la forma recomendada\n\nconst myConstant = \"Texto que no cambia\"; // tercera forma de crear variable, funciona como una constante.\n\n// Tipos de datos primitivos\n\n// Boolean\nlet myBooleanTrue = true;\nlet myBooleanFalse = false;\n// Null\nlet myNull = null;\n// Undefined\nlet myUndefined = undefined;\n// Number\nlet myNumber = 20;\nlet myOtherNumber = 3.14;\n// BigInt\nlet myBigInt = 9007199254740992n;\n// String\nlet myStringOne = \"Hola\";\nlet myStringTwo = \"Hola\";\nlet myStringThree = `Hola`;\n// Symbol\nlet mySymbol = Symbol(\"identificador\");\n\nconsole.log(\"Hola, JavaScript\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/JonassegDev.js",
    "content": "// Este es el repositorio que seguire https://developer.mozilla.org/en-US/docs/Web/JavaScript\n/* Puedo hacer comentarios\nen varias lineas tambien*/ \n\n//Variables Constante\n\n/*la variable \"const\"\nes una variable con datos constantes o que no se cambian*/\nconst PI = 3.1416\nconsole.log(PI)\n// PI = 3.15; // Error: asignación a variable constante.\n\n//Variable var\n\n/*la variable \"var\" puede ser \nreasignada y redeclarada*/\nvar nombre = \"Juan\";\nnombre = \"Carlos\"; // Reasignación\nvar nombre = \"Pedro\"; // Redeclaración\n\n//variables var diferentes comillas.\nvar texto1 = \"Mis Primeras Variables\" //comillas dobles\nvar texto2 = 'Texto Con Comillas Simples' // Comillas Simples\nvar texto3 = \"comillas 'simples' dentro de unas dobles\" // Comillas mixtas\n\nconsole.log(texto1)\nconsole.log(texto2)\nconsole.log(texto3)\n\n//Variable let\n\n/*la variable let puede ser\nreasignada pero no redeclarada*/\nlet edad = 25\nedad = 30 // Reasignacion\n// let edad = 32 // Error \"edad\" no puede ser redeclarada la misma variable.\n\n// Tipos de datos.\n\n/*JavaScript es un lenguaje de tipado dinámico, \nlo que significa que no necesitas especificar el tipo de dato de una variable al declararla. \nJavaScript determinará el tipo de dato en tiempo de ejecución. \nLos tipos de datos principales son:*/\n\n//Numeros (number).\nlet entero = 10\nlet decimal = 3.14\n\n//Cadena (string).\nlet saludo = \"Hola Mundo\"\n\n//Booleanos (booleans) representan valores logicos como: \"true\" o \"false\"\nlet soyEstudiante = true\nlet soyDocente = false\n\n//Indefinido (indefined) Representa una variable que ha sido declarada pero no se le ha asignado un valor.\n\nlet sinValor\nconsole.log (sinValor) // Resultado \"undefined\"\n\n//Nulo (null) Representa un valor nulo o vacío.\n\nlet valorNulo = null\n\n//Objetos (object) Representan colecciones de propiedades (pares clave-valor).\nlet gato = {\nnombre: \"Michi\",\nedad: 2\n}\n\n//Simbolo (symbol) Representan valores únicos e inmutables.\n\nlet simbolo = Symbol(\"mySymbol\")\n\n// Imprimir el Hola mundo.\n\nlet miSaludo = 'Hola, JavaScript'\nconsole.log (miSaludo)\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Jorge186414.js",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n// Documentacion JavaScript: https://developer.mozilla.org/es/docs/Web/JavaScript\n/*\nDe esta forma se \npueden hacer comentarios\nen varias lineas\n*/\n// Y este seria un comentario de una sola linea\n\n\nvar nombre = 'Jorge'\nconst PI = 3.1416\n// number\nconst entero = 1\nconst puntoFlotante = 9.7\n// string\nconst apellido = 'Miranda'\n// boolean\nconst suscrito = true\nconst noSuscrito = false\n// object\nconst persona = {\n  nombre: 'Jorge',\n  apellido: 'Miranda',\n  edadl: 21\n}\n// array\nconst lenguajesProgramacion = ['JavaScript', 'Java', 'Python', 'C']\n// bigint\nconst x = 2n ** 65n\n// symbol\nconst symbol = Symbol('Hola')\n// unndefined\nconst undefined = undefined\n\nconsole.log('Hola, JavaScript')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Jose-Miguel1.js",
    "content": "// URL: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Hola soy un comentario en una sola linea\n\n/* \nhola \nsoy\nun \ncomentario\nen\nvarias lineas\n*/\n\nlet nombre;\n\nconst dni = \"43543423\";\n\nlet apellido = \"Loodermin\";\n\nlet edad = 18;\n\nlet altura = 1.80;\n\nlet casado = true;\n\nlet fechaMuerte = undefined;\n\nlet certificados = null;\n\nconsole.log(\"¡Hola, JavaScript!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/JoseAndresGC.js",
    "content": "// https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n// comentario de una línea\n\n/*\ncomentario\nde\nmultiples\nlíneas\n*/\n\nlet variable = 'variable';\nconst CONSTANTE = 'constante';\n\n// tipos de datos\nlet cadenaDeTexto = 'texto';\nlet booleano1 = true;\nlet booleano2 = false;\nlet entero = 1;\nlet float = 1.2;\nlet nulo = null; // especial\nlet indefinido = undefined // especial\n\n// imprimir en consola\nconsole.log(\"¡Hola, javascript!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/JoseFuentes-Dev.js",
    "content": "//https://www.javascript.com\n/*Comentario\nen varias \nlineas javascript\n */\nlet variable = 'esto es una variable'; //una variable\nconst constante = 7; //una constante \n\n//Distintos tipos de variables en javascript\nlet strg = \"esto es una cadena de texto\"\nlet bool = true;\nbool = false;\nlet int = 1;\nlet float = 1.5;\n\n//Imprimir por consola\nconsole.log(\"¡Hola, desde javascript!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/JosePeresini.js",
    "content": "/*\n    *1 - Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n       ! https://developer.mozilla.org/en-US/docs/Web/javascript\n\n    *2 - Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n        ! /**/ //\n\n// *3 - Crea una variable (y una constante si el lenguaje lo soporta).\n\n    let number = 10;\n    const miNombre = \"Jose\";\n\n// *4 - Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n    let thisIsAString = \"String\";\n    let thisIsANumber = 10;\n    let thisIsBooleanTrue = true;\n    let thisIsBooleanFalse = false;\n    let thisIsUndefined;\n    let thisIsNull = null;\n    let thisIsASymbol = Symbol(\"Symbol\");\n\n// *5 - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n    let welcomeJavaScript = \"¡Hola, JavaScript!\";\n    console.log(welcomeJavaScript);\n\n/*\n    EJERCICIO:\n    * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n    * debemos comenzar por el principio. \n*/"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/JoseSalazar1312.js",
    "content": "//https://www.javascript.com/\n\n//Comentario en una línea\n\n/*\nEjemplo de un comentario\nque puede ser escrito \nen varias lineas\n*/\n\nvar myVarVariable = \"Variable var\";\n\nlet myLetVariabe = \"Variable let\";\n\nconst myConstant = \"Constante\";\n\n/*Js es un lenguaje de tipo dinamico\nes decir, los tipos de variable se \ncomprueban durante el tiempo de ejecucion.\n*/\n\nlet myInt = 1; //variable de tipo entero\n\nlet myString = \"texto\"; //Variable del tipo string\n\nlet myboolean = true; //Variable del tipo boleano\nlet mybooleanF = false; //Variable del tipo boleano\n\nlet myFloat = 1.5 //Variable del tipo float\n\nconsole.log(\"Hola mundo\");\nconsole.log(myInt);\nconsole.log(myString);\nconsole.log(myboolean);\nconsole.log(mybooleanF);\nconsole.log(myFloat);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Joshua0730-star.js",
    "content": "// https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n// este es un comentario de una sola linea\n\n/*\nEste es un comentario\nmultilinea\n*/\n\nlet variable = \"Hola\" // Variable (puede ser reasignada)\nvariable = \"Mundo\" // Cambia el valor de la variable\n\nconst PI = 3.14  // Constante ---> no puede cambiar de tipo de dato\n\n\n\n// datos primitivos \n\nlet string = \"Hola, Mundo!\" // texto\nlet int = 40; // entero\nlet float = 3.14; // decimal\nlet boolean = true; // booleano\nlet Nulish = null; // nulo\nlet indefinido = undefined; // indefinido\nlet bigInt = 9007199254740991n; // entero grande\n\n\nconsole.log(\"¡Hola, JavaScript!\");\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/JosueVH07.js",
    "content": "// Documentacion de JavaScript --> https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Este es un comentario de una linea\n\n/*\n    Esto es un comentario\n    de varias lineas\n    😎\n*/\n\n// variable mutable\n\nlet variable\n\nvariable = 'JosueVH07'\n\nvar  variable2 = 'JosueVH07'\n\nvariable2 = 'JosueVH'\nvariable = 'JosueVH'\n\n\n// Variables de datos primitivos\n\nlet string = 'JosueVH07'\nlet number = 7\nlet float = 7.7\nlet bool = true\nlet nullValue = null\nlet undefinedValue = undefined\nlet symbolValue = Symbol('a')\nlet bigIntValue = 7n\nlet array = [1, 2, 3, 4, 5]\nlet object = {\n    name: 'Josue',\n    age: 20,\n    city: 'CDMX',\n    country: 'Mexico'\n}\nconsole.log(symbolValue)\n\nconst lenguaje = 'JavaScript'\n\nconsole.log(`Hola ${lenguaje}`)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Josueeeee.js",
    "content": "// https://www.javascript.com/\n\n//Comentario en una linea es de esta forma\n\n/*\nComentarios en multilinea se\nhace de \nesta otra forma\n*/\n\n// tipos de variables\nvar variable = \"Variable en Javascript\";\nconst varibaleCostante = \"Variable constante\";\n\n//tipos de datos\nconst string = \"texto\";\nconst numeroEntero = 200;\nconst numeroDecimal = 1.09;\nconst boleano = true;\n\n//imprimir\nconsole.log(\"Hola, Javascript\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Jovany-java.js",
    "content": "/**EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n      a-. Sitio web oficial de Java Script: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n * - Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n \n      a.- //Soy un comentario de una linea\n      \n      b.- /**\n            Soy un comentario multilinea\n      **/\n  /**      \n  \n   **/\n\n// * - Crea una variable (y una constante si el lenguaje lo soporta).\n\n//Variables:\n\n      let My_Variable =0;\n      var My_Var =10;\n\n//Constante:\n\n      const Myconstan =0;\n      \n //* - Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n    \n    \n      //NUll \n            let Null = null;\n\n      //Undefined\n            let Undefined = undefined;\n\n      //Boleean- True && false\n\n             let My_BoleeanT = true;\n             let My_BoleeanF= false;\n\n      //Number\n            let My_Number = 14;\n\n      //String\n            let My_String = \"i'm programmer\";\n\n      //Bigint\n            let My_Bigint = 300n;\n\n      //Symbol\n            let sym1 = Symbol();\n            let sym2 = Symbol(\"FOG\");      \n\n // * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\nconsole.log( \"¡Hola, Java Script!\");\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/JuPerDev.js",
    "content": "// JavaScript no tiene una página oficial\n// La especificación oficial se encuenta en https://ecma-international.org/publications-and-standards/standards/ecma-262/\n/* Las Webs mas populares para consultar documentación son:\n https://developer.mozilla.org/en-US/docs/Web/JavaScript \n https://www.w3schools.com/js/default.asp\n*/\n\n// Comentarios en una línea\n/* \n    Comentarios \n    en varias \n    líneas\n*/\n// Declaración variable y constante\nlet variable = 0;\nconst constante = 3.14;\n\n// Tipos de datos primitivos\n\nlet nombre = 'Juan'; // String\nlet numero = 2024; // Number\nlet boolean = true; // Puede ser true or false o 0 y 1...n\nlet noDefinida; // Undefined se aplica a una variable que no ha sido inicializada.\nlet simb1 = Symbol('mi_simbolo'); // Crea un identificador unico\nlet nulo = null; // Sin valor o referencia.\nlet bigInt = 312838917418927498127n; // Numeros muy grandes que number no soporta\n\n// Imprimir mensaje\n\nconsole.log(\"¡Hola, JavaScript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/JuSeRDev.js",
    "content": "//  !EJERCICIO:\n//  *Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n\n// esta es la web oficial de JavaScript https://www.javascript.com\n\n/* \n    tambien se puede comentar\n    en varias \n    lineas\n    https://www.javascript.com\n*/\n\n//  *Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n\n// en una linea\n/*\n    en varioas\n    lienas\n */\n\n//  *Crea una variable (y una constante si el lenguaje lo soporta).\n\nlet saludo = \"Hola, soy una variable\"\nconst saludar = \"Hola, soy una constante\"\n\n//  *Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n\nlet sting = \"cadena de texto (string)\"\nlet number = 10\nlet booleanTrue = true\nlet booleanFalse = false\n\n//  *Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\nconsole.log(\"¡Hola, JavaScript\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/JuanCaicedo1024.js",
    "content": "// https://developer.mozilla.org/es/docs/Web/JavaScript\n/* Comentarios en varias lineas */\n\nlet Name = \"juan\";\nconst name = \"Juan\"\n\n//tipos de datos \n\nlet Number = 1;\nlet Float = 1.4\nlet Stright = \"Hola\"\nlet Boolean = true\nlet Undefined = undefined\nlet Null = null\n\nconsole.log (\"¡Hola, JavaScript!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/JuanCamiloGomezAlvarez.js",
    "content": "// Documentación oficial de JavaScript : https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n//Esto es un comentario de una sola linea\n\n/*\n De esta manera \n puedo crear comentarios\n en varias lineas\n*/\n\n// variable en JavaScript\nlet altura = 1.74;\n\n// otra forma de crear una variable\n\nvar weight = \"70-kg\";\n\n// constante en js\n\nconst PI = 3.1415;\n\n// Algunos tipos de datos primitivos en JavaScript\n\nlet name = \"Juan Camilo\" // string\nlet age = 32 // number\nlet isMale = true // boolean\nlet money = null // null\nlet indefinido = undefined // undefined\n\nlet mensaje = `Hola mi nombre es ${name} tengo ${age} años y estoy aprendiendo JavaScript}`;\nconsole.log(mensaje)\nconsole.log(\"hola, JavaScript\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/JuanFlP30.js",
    "content": "/*\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\n*/\n\n// Página principal de JavaScript: https://developer.mozilla.org/es/docs/Learn_web_development/Core/Scripting/What_is_JavaScript\n\n// Comentario de una línea\n\n/*\nComentario\nde varias líneas\n*/\n\nlet name = \"Juan Felipe\"; // Esta es una variable que puede cambiar\nvar fullname = \"Juan Felipe Zapata\";\n\nconst MY_CONSTANT = \"API_KEY\"; // Esta es una constante que no puede cambiar\n\nlet int = 25; // Número entero\nlet float = 1.33; // Número con punto flotante\nlet bool = true; // Booleano\nlet string = \"Mi cadena de texto\"; // Cadena de texto\nlet otherString = 'Mi otra cadena de texto'; // Otra forma de representar cadenas de texto\nlet language = \"JavaScript\"; // Nombre del lenguaje\n\nconsole.log(`¡Hola Mundo, Esto es ${language}!`); // Imprime un saludo personalizado\n\nconsole.log(typeof int, int); // Imprime el tipo de la variable int\nconsole.log(typeof float, float); // Imprime el tipo de la variable float\nconsole.log(typeof bool, bool); // Imprime el tipo de la variable bool\nconsole.log(typeof string, string); // Imprime el tipo de la variable string\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/JuanPablo-A.js",
    "content": "/*\r\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\r\n * - Recuerda que todas las instrucciones de participación están en el\r\n *   repositorio de GitHub.\r\n *\r\n * Lo primero... ¿Ya has elegido un lenguaje?\r\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\r\n * - Este primer reto te servirá para familiarizarte con la forma de participar\r\n *   enviando tus propias soluciones.\r\n *\r\n * EJERCICIO:\r\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\r\n *   lenguaje de programación que has seleccionado.\r\n * - Representa las diferentes sintaxis que existen de crear comentarios\r\n *   en el lenguaje (en una línea, varias...).\r\n * - Crea una variable (y una constante si el lenguaje lo soporta).\r\n * - Crea variables representando todos los tipos de datos primitivos\r\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\r\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\r\n *\r\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\r\n * debemos comenzar por el principio.\r\n */\r\n\r\n// Página principal de JavaScript: https://developer.mozilla.org/en-US/docs/Web/JavaScript\r\n\r\n\r\n// Comentario en una linea \r\n\r\n/* \r\n    Este es un comentario de varias líneas\r\n*/\r\n\r\n\r\n//Crear una variable\r\nlet variable = \"Mi variable\"; \r\nvariable = 1;  // Cambiar el valor de la variable\r\n// console.log(variable);\r\n\r\n//Crear una constante\r\nconst constante = \"Mi constante\";\r\n\r\n//Crear variables de todos los tipos de datos primitivos\r\nlet miString = \"Hola Mundo\"; // Cadena de texto\r\nlet miNumero = 25; // Número entero \r\nlet miBooleano = true; // Booleano, tambien puede ser False\r\nlet miFloat = 1.33; \r\nlet miUndefined = undefined;\r\nlet miNull = null; \r\nlet miSymbol = Symbol(\"Hola\");\r\nlet miObjeto = {\r\n            nombre: \"Juan Pablo\", \r\n            edad: 25};\r\n\r\nconsole.log(\"¡Hola, JavaScript!\");\r\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/JuanSeRDev.js",
    "content": "//  * - Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n\n// esta es la web oficion de [JavaScript](https://www.javascript.com)\n\n//  * - Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n\n    // Comentario en una linea\n    /*\n        Comentario en \n        bloque de \n        lineas\n     */\n\n//  * - Crea una variable (y una constante si el lenguaje lo soporta).\n\n    let saludo = \"Hola\"\n    const saludar = \"Hola a todos\"\n\n//  * - Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n\n    let string = \"string\"\n    let number = 10\n    let booleanTrue = true\n    let BooleanFalse = false\n    \n//  * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\nconsole.log(\"¡Hola, JavaScript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Juancamilo3821.js",
    "content": "//https://www.javascript.com//\n/*Comentario para multiples lineas*/\n\n//Declarar Variable y una constante//\nlet X = 5;\nconst x = 5;\n\n//Variables segun el tipo de dato//\n\n//String//\nlet Name = \"Juan\";\n\n//Int//\nlet Cedula = 1097910073;\n\n//Booleano//\nlet esMusico = true;\n\n//Indefinido//\nlet undefined;\n\n//Null//\nlet cajaVacia = null;\n\n//Objeto//\nconst usuario = {\n    nombre: \"Juan\",\n    edad:22\n};\n\n//Array//\nlet listaNumeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n\n//Funcion//\nconst saludar = function() {\n  return \"Todo bien?\";\n};\n\n//Print//\nconsole.log(\"!Hola, Javascript!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/JuitoMG.js",
    "content": "// EJERCICIO:\n// -Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n\n// https://www.javascript.com/\n\n\n// - Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n\n// Comentario en una línea\n\n/*\nComentario\nen varias\nlíneas\n*/\n\n\n// - Crea una variable (y una constante si el lenguaje lo soporta).\n\nlet pajaro = \"loro\"\n\nconst constante = 10\n\n// - Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n\nlet string = \"Nombre\"\nlet entero = 33\nlet float = 3.56\nlet booleano = true\nlet enteroGrande = 852342634578246587264527645n\nlet nulo = null\n\n\n// - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\nlet lenguaje = \"Javascript\"\nconsole.log(\"Hola, \"+lenguaje+\"!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Kenzambrano.js",
    "content": "// WEB OFICIAL\n// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// COMENTARIOS\n\n/**\n* Comentarios de varias lineas\n* Este es un tipo de comentario sirve para describir funcionalidades de metodos, clases, etc\n*/\n// Comentarios de una linea. Para comentarios breves\n\n// Javascript\nvar name = \"Ken\";\nlet lastName = \"Zambrano\";\nconst PI = 3.1416;\nlet boolean = true;\n\nconsole.log(\"Hola este es mi javascript!!! \", name + \" \" lastName);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Kocho03.js",
    "content": "//Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n// -https://developer.mozilla.org/es/docs/Web/JavaScript\n\n\n//Representa las diferentes sintaxis que existen de crear comentarios\n/* Esto es tambien un comentario escrito en barias \nlineas en JavaScript\n\"Hola Mundo\"*/\n\n\n//Crea una variable (y una constante si el lenguaje lo soporta).\nvar holaMundo = (\"Estoy aprendiendo a programar con el curso de MoureDev\")\nlet tipoDeVariable = (\"Esta es otra forma de escribir una variable\")\nconst nombre = (\"Hola Mundo, me llamo Kocho\")\n\n//Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n\nlet numerosEteros = 2\nlet numerosFlotantes = 2.123\n\n\nlet bigInt = BigInt(9007199254740991)\n\nlet string = \"Hola Mundo\"\n\nlet booleanos1 = true \nlet booleanos2 = false \n\nlet undefinedVariable\n\nlet simbolo = Symbol(\"😁👍\")\n\nlet nullVariable = null\n\n\n// Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\nconsole.log(\"¡Hola, JavaSript!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Kronstadt-Lambda.js",
    "content": "// https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n// * Syntax to create comments in JavaScript\n// Single line comments like this\n/* Multi-line comments\nlike this */\n/**\n * Documentation comments\n * like this\n * @author Kronstadt\n */\n\n// * Syntax to manage punctuation in JavaScript\n// ; (semicolon) is used to separate statements. It is optional in JavaScript but it is a good practice to use it.\n// , (comma) is used to separate items in a arrays, elements in objects and parameters in functions.\n// . (dot) is used to access properties and methods of objects.\n// : (colon) is used to separate keys and values in objects. Too, it is used in ternary operator.\n// () (parentheses) are used to define parameters in functions, to group expressions and to call functions.\n// [] (brackets) are used to define arrays, to access elements in arrays and objects.\n// {} (braces) are used to define objects and blocks of code like in loops and conditionals.\n// \"\" (double quotes) and '' (simple quotes) are used to define strings.\n// `` (backticks) are used to define template literals.\n\n// * Variables and constants in JavaScript\nlet variable_string = 'value'; // Declares a variable with a value\nlet variable_number = 1; // Declares a variable with a number\nlet variable_boolean = true; // Declares a variable with a boolean\nlet variable_array = [1, 2, 3]; // Declares a variable with an array\nlet variable_object = { key: 'value' }; // Declares a variable with an object\nlet variable_undefined; // Declares a variable without a value\n\nconst constant_string = 'value'; // Declares a constant with a value\nconst constant_array = [1, 2, 3]; // Declares a constant with an array\nconst constant_object = { key: 'value' }; // Declares a constant with an object\nconst constant_undefined = undefined; // Declares a constant with a value of undefined\n// Note: It does not define a constant value. IT DEFINES A CONSTANT REFERENCE TO A VALUE.\n// Note: var is an old way to declare variables in JavaScript. It is not recommended to use it.\n\n// Best practices:\n// 1. Always declare variables\n// 2. Always use const if the value should not be changed\n// 3. Always use const if the type should not be changed (Arrays and Objects)\n// 4. Only use let if you can't use const\n// 5. Only use var if you MUST support old browsers.\n\n// * Primitive data types in JavaScript\n// String: Represents a sequence of characters.\nconst string = 'Hello, World!';\n// Number: Represents a number.\nconst number = 42;\n// BigInt: Represents a number that can store big integers with arbitrary precision.\nconst bigInt = 9007199254740991n;\n// Boolean: Represents a logical entity and can have two values: true or false.\nconst boolean = true;\n// Symbol: Represents a unique values and inmutable data type that may be used as an identifier for object properties.\nconst symbol = Symbol('description');\n// Undefined: Represents an undefined value. This means that the variable has not been assigned a value.\nlet undefinedValue; \n// Null: Represents an intentional absence of any object value.\nconst nullValue = null;\n\nconsole.log(\"A string:\", string, \", typeof:\", typeof string);\nconsole.log(\"A number:\", number, \", typeof:\", typeof number);\nconsole.log(\"A BigInt:\", bigInt, \", typeof:\", typeof bigInt);\nconsole.log(\"A boolean:\", boolean, \", typeof:\", typeof boolean);\nconsole.log(\"A symbol:\", symbol, \", typeof:\", typeof symbol);\nconsole.log(\"An undefined value:\", undefinedValue, \", typeof:\", typeof undefinedValue);\nconsole.log(\"A null value:\", nullValue, \", typeof:\", typeof nullValue); // Note: typeof null returns 'object'.\n\n// * Print a greeting\nconst language = \"JavaScript\";\nconsole.log(`Hello, ${language}!`);\n\n// Style guide:\n/*\n1. Nomenclature:\n- Use camelCase for variables and functions.\n- Use PascalCase for classes.\n- Use UPPERCASE for constants.\n2. Indentation:\n- Use 2 spaces for indentation.\n3. Comentaries:\n- Use // above the code to comment.\n- Use /* to comment a block of code.\n- Use /** JSDoc comments to document functions, methods and classes.\n4. Code organization:\n- Group `imports` at the top of the file.\n- Group `constants` next.\n- Group `variables` next.\n- Group `functions` next.\n- Group `classes` next.\n*/\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/L3v1xx.js",
    "content": "// Ejercicio 00 - Sintaxis, variables, tipos de datos y hola mundo\n\n\n//URL Javascript -> https://developer.mozilla.org/es/docs/Web/JavaScript\\\n\n\n// Comentario de una sola línea\n\n/*Comentario en\nvarias lineas de texto\n*/\n\n\n// Variables y constantes en JS\n\nvar MyVariable = \"L3v1xx\";\nlet MyLet = \"L3v1xx\";\nconst MyConstant = \"L3v1xx\";\n\n// Variables primitivas\n\nvar MyString = \"Hola estoy aprendiendo a programar\" //Tipo String\nvar MyNumber = 5 // Tipo numero entero\nvar MyNumberFloat = 5.5 // Tipo numero flotante\nvar MyBoolean = true // Tipo booleano\nvar MyUndefined = undefined // Tipo indefinido\nvar MyNull = null // Tipo nulo\nvar MyArray = [1,2,3,4,5] // Tipo array\nvar MyObject = {nombre: \"L3v1xx\", edad: \"27\"} // Tipo objeto\nvar MySymbol = Symbol() // Tipo simbolo\nvar MyBigInt = 9007199254740991n    // Tipo BigInt\n\nconsole.log(\"¡Hola, JavaScript!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/LJBARAJAS.js",
    "content": "// https://www.javascript.com/\n\n\n// Comentario de uan linea.\n\n/*\nComentario \nde varias\nlineas\n*/\n\n// Variable y constante\n\nconst salario = 1000;\n\nlet miVariable = 10;\n\nlet MiTexto = \"Hola Mundo\";\n\nlet Numero = 20;\n\nlet boolean = true; // o false\n\nlet miNull = null;\n\nlet miBigInt = 1234542n;\n\nconsole.log(\"¡Hola, Javascript!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/LauraCastrillonMp.js",
    "content": "// URL Javascript -> https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Comentario de una sola línea \n/*\n    Un comentario\n    que se extiende\n    en varias\n    líneas\n*/\n\n// Variables y constantes\n/*\n    var -> Alcance global\n    let -> Alcance bloque\n*/\n// Declaración de una variable\nlet miVariable = \"valor de la variable\";\n\n// Declaración de una constante\nconst miConstante = \"valor de la constante\";\n\n// Datos primitivos\nlet cadenaDeTexto = \"Hola, soy una cadena de texto\";\nlet numeroEntero = 42;\nlet booleano = true;\nlet nulo = null;\nlet vacio = undefined;\nlet simbolo = Symbol();\nlet bigInt = 9007199254740991n;\n\n// Impresión por consola\nconsole.log(\"¡Hola, JavaScript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Lemito66.js",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n// Comentario en una línea  del sitio web oficial de JavaScript: https://developer.mozilla.org/es/\n\n/* Comentario de varias lineas del sitio web oficial de Javascript:\nhttps://developer.mozilla.org/es/\n*/\n\n// Creación de una variable\n\nlet name = \"Emill\";\n\n// Creación de una constante, se usa la nomenglatura de mayúsculas y guión bajo para separar palabras\nconst NAME = \"Emill\";\n\nlet string = \"Hola mundo\";\nlet boolean = false;\nlet integer = 123;\nlet float = 123.45;\n\nconst PROGRAMMING_LANGUAGE = \"JavaScript\";\n\n// Concatenación de variables\n\nconsole.log(\"¡Hola, \" + PROGRAMMING_LANGUAGE + \"!\");\n// Otra forma de concatenar variables   \nconsole.log(`¡Hola, ${PROGRAMMING_LANGUAGE}!`);"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Leonardo291024.js",
    "content": "//https://developer.mozilla.org/es/docs/Web/JavaScript\n\n//Comentario en una linea \n\n/*\nComentario \nen varias \nLineas\n */\n\n/**\n * Comentario\n * con \n * asteriscos\n */\n\n//Crea una variable (y una constante si el lenguaje lo soporta).\nmyVariable = \"My Variable\";\nconst myConstant = \"My Constant\";\n\n//Crea variables representando todos los tipos de datos primitivos  del lenguaje (cadenas de texto, enteros, booleanos...).\n\nconst numero = 7;\nconst string = \"Hola Mundo\";\nconst booleano = true;\n\n//Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nconst lenguaje = \"Javascript\";\n\nconsole.log(`!Hola ${lenguaje}`);\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/LugRyssD3V.js",
    "content": "//1- Crea un comentario en el código y coloca la URL del sitio web oficial dellenguaje de programación que has seleccionado:\n//URL de la web oficial de java script: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n\n//2- Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...): \n//En una linea = //\n/*\nEsta es la forma de escribir\nen varias lineas.\n*/\n\n\n//3- Crea una variable (y una constante si el lenguaje lo soporta):\nvar nombre1 = 'Luiggi';\nlet apellido = 'Reyes';\nconst pais = 'Republica Dominicana';\n\n\n//4- Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...):\n\n/*String (Cadena de textos): se refiere a una cadena de texto, es decir, una secuencia de caracteres que puede estar encerrada \nentre comillas simples ('), dobles (\") o backticks (`).*/\nlet nombre  = 'Luiggi';\nlet lenguaje = 'javascript';\nlet saludo = 'hola';\n\n/*Number (Numero): los números son de tipo number y pueden ser enteros o decimales.*/\nlet edad = '21';\nlet precio = '99.99';\n\n/*Boolean (booleano): es un valor que puede ser true (verdadero) o false (falso), estos no se ponen en comillas.*/\nlet estaAprendiendoAPrograma = true;\nlet MiEdadEs21 = false;\n\n/*Null: es un valor intencionalmente vacio o desconocido.*/\nlet moto = null;\n\n/*Undefined: indica que una variable ha sido delcarada pero no tiene un valor asiganado.*/\nlet valorIndefinido;\n\n/*Symbol: es un valor unico e inmutable que sirve como identificador.*/\nlet id = Symbol();\n//Tambien a este tipo de dato se le puede asignar una descripcion como referencia para depuracion:\nlet idDescrpcion = symbol('este id es unico');\n\n/*BigInt: se utiliza para representar numeros enteros grandes, que no pueden ser representados con el\ntipo Number.*/\nlet numeroGrande = BigInt(97374320283746383627);\n\n\n//5- Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"*/\nconsole.log('¡Hola, [JavaScript]!');"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/M4XISIL.js",
    "content": "/************ 1 - SITIO OFICIAL DE JAVASCRIPT ************/\n\n// Pagina que encontre muy completa de JS, con la que me saco las dudas. Me parece que no tiene una oficial. https://developer.mozilla.org/en-US/docs/Learn/JavaScript\n\n/*********************************************************/\n\n/************ 2 - TIPOS DE COMENTARIOS ************/\n\n// Para colocar un comentario en 1 sola linea.\n\n/* Para comentar\nen varias \nlineas */\n\n/**************************************************/\n\n/************ 3 - CREANDO VARIABLES ************/\nvar variableVar = \"Una variable usando VAR\"; //Desde hace años, ya no se recomienda usar VAR\nlet variableLet = \"Una variable usando LET\";\nconst CONSTANTE = \"Una constante\";\n/***********************************************/\n\n/************ 4 - TIPOS DE DATOS PRIMITIVOS ************/\nlet tipoCadena = \"Hola, soy una cadena de texto\";\n//Los de tipo number pueden ser enteros o decimales\nlet tipoNumber = 42;\ntipoNumber = 42.5;\nlet tipoBooleano = true;\nlet tipoIndefinido = undefined;\nlet tipoSimbolo = Symbol(\"mySymbol\");\nlet tipoBigInt = 1234567890123456789012345678901234567890n;\nlet tipoNulo = null; //Aunque algunos ejemplos lo clasifican como primitivo, en la documentación de Mozilla (https://developer.mozilla.org/es/docs/Glossary/Primitive) se indica que es un \"caso especial\".\n/*******************************************************/\n\n/************ 5 - HOLA, JAVASCRIPT ************/\nconsole.log(\"¡Hola, JavaScript!\");\n/**********************************************/"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/MBBellini.js",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n//Comentario con la URL de la pagina web oficial de Javascript *https://developer.mozilla.org/en-US/docs/Web/JavaScript\n//Este es un comentario\n\n/*\nComentario en  varias lineas\n*/\n\nvar variable = \"estoy declarando una variable\" // Define una variable global sin importar el bloque \nlet variable2 = \"declaramos otra variable\" // Creamos una variable que se limita solo al bloque, declaración o expresión donde se esta usando\nconst constante = \"declaramos una constante\" // Crea una constante que puede ser global o local para el bloque que se declare\nlet string = \"cadena de texto\" //string se utiliza para representar una cadena de texto\nlet array = [];\nlet objeto = {}\nlet nulo = null;\nlet booleanT= true\nlet booleanF= false\nlet number = 5\n\n\nconsole.log(\"¡Hola, javascript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/MadeleFonB.js",
    "content": "//https://www.javascript.com/\n\n/*\nEsto es un comentario de varias lineas\nEsto es un comentario de varias lineas\nEsto es un comentario de varias lineas\n*/\n\n\n//Variables y constante\nvar edad = 25;\nconst año = 2024;\n\n\n//Datos primitivos\n/*Number:El tipo de dato Number representa tanto números enteros como decimales\nTambién puede representar números en notación científica, Infinity (infinito) y NaN (Not a Number).\n*/\nvar edad = 16;\nvar peso = 60.3;\nvar infinito = Infinity\nvar NoEsNumero = NaN\n\n/*\nSTRING: El tipo de dato String representa cadenas de texto, que pueden ser escritas utilizando comillas simples, dobles o acentos graves (backticks).\nLos acentos graves permiten crear plantillas literales (template literals) que incluyen interpolación de variables y expresiones.\n*/\nvar entero=0;\nvar comillasimple = 'Hola mundo';\nvar comillaDoble = \"Hola mundo\";\nvar plantillaLiteral = `Minumero favorito es ${entero}`;\nvar caracteresEscape = 'Texto con \\\"comillas\\\" y salto de linea  \\n';\n\n/*\nBOOLEAN:El tipo de dato Boolean representa valores lógicos, que pueden ser verdadero (true) o falso (false). \nEstos valores son comúnmente utilizados en operaciones lógicas y de comparación.\n*/\n\nvar falso = false;\nvar verdadero = true;\nvar mayorDeEdad = (5 >= 18)\n\n/*\nNULL:El tipo de dato Null representa un valor nulo o vacío. Se utiliza para indicar que una variable no tiene ningún valor asignado.\n*/\n\nvar valorNulo = null;\n\n/*\nUNDEFINED:El tipo de dato Undefined indica que una variable no ha sido asignada a ningún valor. \nEste es el valor por defecto de las variables que no han sido inicializadas.\n */\n\nvar valorIndefinido;\n\n/*\nBIGINT:Es útil para representar números muy grandes que no caben en un tipo de dato “Number” y es compatible con la mayoría de las operaciones aritméticas básicas.\nSin embargo, aún no es compatible con algunas funciones como Math.floor o parseInt, por lo que es importante tener en cuenta sus limitaciones.\nSe agregó en la versión ECMAScript 2020 y se puede crear añadiendo “n” al final de un número.\n */\n\nvar bigIntValue = 1234567891011n;\n\n/*\nSYMBOL:El tipo de dato Symbol representa valores únicos e inmutables que pueden ser utilizados como identificadores de propiedades en objetos.\nLos símbolos se crean utilizando la función Symbol(), que opcionalmente puede recibir un argumento de tipo String para describir el símbolo.\n */\n\nvar simbolo1;\nvar simbolo2= Symbol('dos');\nvar simbolo3 = Symbol('tres')\n//Imprimir por consola lenguaje seleccionado\nconsole.log('¡Hola,[JavaScript]')\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Magupe09.js",
    "content": "\n//  https://developer.mozilla.org/es/docs/Web/JavaScrip , comentario de una linea en js\n\n/*\n  Este es un \n  comentario de varias\n  lineas en js\n*/\n\nlet variable= \"magupe09\";\nconst NOMBRE= \"Mauricio\";\n\n// variables que representan los tipos de datos primitivos en javascript\n\nlet number = 12345;\nlet string = \"texto\";\nlet boolean = false;\nlet boolean2 = true;\nlet nulo= null;\nlet undefined = undefined ; // variable no definida\nlet sym = Symbol(); // para un valor secreto dentro de un objeto\n\n\n// IMPRESION EN CONSOLA\n\nconsole.log(\"¡Hola, javascript!\")\nconsole.log(typeof(number));\nconsole.log(typeof(string));\nconsole.log(typeof(boolean));\nconsole.log(typeof(boolean2));\nconsole.log(typeof(nulo));\nconsole.log(typeof(undefined));\nconsole.log(typeof(sym));"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/ManuelD95.js",
    "content": "//https://www.javascript.com/\n\n// Este es un comentario de una línea\n\n/* Este es un comentario\nEntre varias lineas\nY se puede usar para \nExplicar algo mas extenso*/\n\n// Crea una variable\nvar Nombre = 'Java'\nvar Apellido = ' Script'\n\nconsole.log (Nombre)\nconsole.log (Apellido)\nconsole.log (Nombre+Apellido)\nconsole.log ('Hola Manuel')\n\n// Crea una constante\n\nconst Pi = 3.1416 \nconsole.log (Pi)\n\nconst Nombre1 = \"Juan\"; // Correcto\nconst Nombre2 = \" Maria\";\n\nconsole.log(Nombre1 + Nombre2); // María\n\n// Crear variables de diferentes tipos primitivos\n\nlet Nombre3 = \"Manuel\"; //string\nlet Edad = 30; // number int\nlet Agua = 4.20; // number float\nlet Enorme = 11170225n; // bigint\nlet esEncendido = true // boolean\nlet sinValor; // undefined, variable no inicializada \nlet Vacio = null; // Sin valor\nlet id = Symbol(\"Clave\"); // Identidicador\n\nconsole.log (typeof Nombre);\nconsole.log (typeof Enorme)\nconsole.log (sinValor);\n\n// Otras primitivas\n\nlet Persona = {       // object\n    Nombre4: \"Camilo\",\n    Edad: 29\n};\nconsole.log (Persona.Nombre4);\nconsole.log (Persona.Edad);\n\nlet Colores = [\"Amarillo\", \"Azul\", \"rojo\"]; // Array\nconsole.log (Colores)\n\n// Imprime por terminal el texto \"hola JavaScript\"\n\nfunction saludar(Nombre) {    //Function\n    return `Hola, ${Nombre+Apellido}`;\n  }\nconsole.log(saludar(Nombre));\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/MarcosLombardo.js",
    "content": "// El url del sitio web oficial de JavaScript: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Comentario en linea\n\n/*\nComentario\nen\nvarias\nlineas\n*/\n\nvar miNombre = \"Marcos\";\nlet miSegundoNombre = \"Pedro\";\nconst miApellido = \"Lombardo\";\n\nlet string = \"JavaScript\";\nlet number = 8;\nlet boolean = true;\nlet indefinido = undefined;\nlet nulo = null;\n\nconsole.log(`¡Hola, ${string}!`);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/MatiTC.js",
    "content": "// Sitio web oficial: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n/*\nComentarios en JavaScript\nExisten dos formas, comentarios en solo una linea o en varias lineas \n*/\n\n//Ejemplo 1. Este es un Comentario en una linea \n/* Ejemplo 2. \nEste es un comentario en varias lineas\ncomo un bloque de información\n*/\n\n// Declaramos una Variable\nlet miVariable = \"Soy una variable\";\n\n// Declaramos una Constante\nconst PI = 3.141592653589793;\n\n// JavaScript tiene seis tipos de datos primitivos:\n//String: Representa una cadena de texto.\nconst nombre = \"Matias Tardones\";\n\n//Number: Representa un número.\nconst edad = 24;\n\n//Boolean: Representa un valor booleano.\n//El dia esta soleado\nconst estaSoleado = true; // Valor true\nconst estaNublado = false; // Valor false\n\n//Null: Representa la ausencia de valor.\nconst variable = null;\n\n//Undefined: Representa la ausencia de valor inicial.\nconst variableUndefined = undefined\n\n//Symbol: Representa un símbolo.\nvar simbolo = Symbol('mi-Símbolo');\n\n//Imprimir por terminar\nconsole.log(\"¡Hola, [y el nombre de tu lenguaje]!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Matiascba27.js",
    "content": "// link de la documentacion oficial de Javascript https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// este es un comentario de una sola linea\n\n/* este \nes\nun\ncomentario\nde\nvarias\nlineas\n*/\n\nlet nombre = \"Matias\";\nconst apellido = \"Nuñez\";\n\nlet string = \"Cadena de texto\"; // cadena de texto\nlet numero = 10; // entero\nlet booleano = true; // booleano\nlet flotante = 10.5; // flotante\nlet nulo = null; // nulo\nlet indefinido; // udefined\n\nconsole.log(\"Hola, Javascript!\");\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/MaximoToro.js",
    "content": "/*\nURL WEB del lenguaje JavaScript\nhttps://developer.mozilla.org/es/docs/Web/javascript\n*/\n\n//este es un comentario en linea\n\n/*\nestos son \n\nmultiples \n\ncomentarios \n\n*/\n\n// variables \nlet prueba; \n\nconst pi = 3.14;\n\n//Datos primitivos \n\nlet texto = nombre;\nlet boolean = true; \nlet undefinido = undefined; \nlet edad = 10; \nlet bigInt = 139012839012839012839028132190312n; \nlet symbol = Symbol(); \n\n//imprimir \n\nconsole.log(\" hola [Javascript] \");\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/MiguelAngelMTZ000414.js",
    "content": "// JavaScript URL = https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// 2.- Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n\n// Este es un ejemplo de un comentario de una sola linea\n\n/* \nEste es un ejemplo\nde un comentario\nen varias lineas\n.\n*/\n\n// 3.- Crea una variable (y una constante si el lenguaje lo soporta)\nlet miNombre = \"Miguel\" // Esta es una variable \"let\", una variable let\nconst miSegundoNombre = \"Angel\" // Esta es una variable \"const\", una variable constante \"const\"\n\n// Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\nlet Number = 24, number = 24.5 // Tipo de dato primitivo: Number\nlet String = \"Miguel Angel\" // Tipo de dato primitivo: String\nlet BooleanTrue = true // Tipo de dato primitivo: Boolean (true)\nlet BooleanFalse = false // Tipo de dato primitivo: Boolean (false)\nlet Undefined // Tipo de dato primitivo: Undefined (indefinido)\nlet Null = null // Tipo de dato primitivo: Null (nulo/ninguno)\nlet symbol = Symbol(\"Symbol\") // Tipo de dato primitivo: Symbol\nlet bigintN = 123456789101112131415161718192021222324252627282930313233n // Tipo de dato primitivo: BigInt (numeros de enteros grande)\nlet bigint = BigInt(123456789101112131415161718192021222324252627282930) // Tipo de dato primitivo: BigInt (numeros de enteros grande)\n\nconsole.log(\"Tipo de dato: \" + typeof Number + \", Tipo de dato primitivo (Number): \" + Number)\nconsole.log(\"Tipo de dato: \" + typeof Number + \", Tipo de dato primitivo (Number): \" + number)\nconsole.log(\"Tipo de dato: \" + typeof String + \", Tipo de dato primitivo (String): \" + String)\nconsole.log(\"Tipo de dato: \" + typeof BooleanTrue + \", Tipo de dato primitivo (Boolean): \" + BooleanTrue)\nconsole.log(\"Tipo de dato: \" + typeof BooleanFalse + \", Tipo de dato primitivo (Boolean): \" + BooleanFalse)\nconsole.log(\"Tipo de dato: \" + typeof Undefined + \", Tipo de dato primitivo (Undefined): \" + Undefined)\nconsole.log(\"Tipo de dato: \" + typeof symbol + \", Tipo de dato primitivo (Symbol): \", symbol)\nconsole.log(\"Tipo de dato: \" + typeof bigintN + \", Tipo de dato primitivo (BigInt): \" + bigintN)\nconsole.log(\"Tipo de dato: \" + typeof bigint + \", Tipo de dato primitivo (BigInt): \" + bigint)\nconsole.log(\"Tipo de dato: \" + typeof Null + \", Tipo de dato primitivo: \" + Null)\n\n// Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nconsole.log(\"Hola [JavaScript]¡\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/MiguelP-Dev.js",
    "content": "// URL del estandar de JavaScript\n// https://tc39.es/ecma262/\n\n// URL oficial de JavaScript\n// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Comentario en una linea\n\n/* Comentario\n    en varias  \n    lineas\n*/\n\n/* Variable Es el nombre que se le da a un pequeño compartimento en memoria.\nSu nombre nos dice que está sujeta a cambios de su valor a en diferentes puntos del programa\nla estructura de las variables es la siguiente:\n    - Un nombre: para identificarlas\n    - Un signo de igual: para asignarles un valor\n    - Un valor: para darle un valor a la variable\n    - Un tipo de dato: para saber el tipo de dato que tiene la variable */\nlet miVariable = 1;\n\n// Constantes son variables que no puenden cambiar su valor.\nconst miConstante = 3.15;\n\n// NOTAS: \n// En javascript los nombres de las variables se escriben en camelCase.\n// Al finalizar la declararión de una línea de código se debe colocar un punto y coma (;).\n\n// Tipos de datos\n\n// Number\nlet myInt = 10;\n\nlet myFloat = 3.14;\n\n// Boolean \nlet x = true;\nlet y = false;\n\n// Null\nlet myNull = null;\n\n// Undefined\nlet myUndefined = undefined;\n\n// BigInt\nlet myBigInt = 1234567890123456789012345678901234567890n;\n\n// Symbol\nlet mySymbol = Symbol(\"foo\");\n\n// Object:\nlet person = {firstName:\"John\", lastName:\"Doe\"};\n\n// Array object:\nlet cars = [\"Saab\", \"Volvo\", \"BMW\"];\n\n// Date object:\nlet date = new Date(\"2022-03-25\");\n\n// Salida por consola\nconsole.log(\"¡Hola, JavaScript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/MrYanxX.js",
    "content": "// # #00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n// > #### Dificultad: Fácil | Publicación: 26/12/23 | Corrección: 02/01/24\n\n//  * EJERCICIO:\n//  * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n//  *   lenguaje de programación que has seleccionado.\n//  * - Representa las diferentes sintaxis que existen de crear comentarios\n//  *   en el lenguaje (en una línea, varias...).\n//  * - Crea una variable (y una constante si el lenguaje lo soporta).\n//  * - Crea variables representando todos los tipos de datos primitivos\n//  *   del lenguaje (cadenas de texto, enteros, booleanos...).\n//  * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\n\n//1. \n// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n\n// Comentario de una linea\n/*\nComentario de \nvarias lineas\n*/\n\n// variables \nlet variable = 0\nconst constante = 1\n\n// Variables para cada tipo de dato\nlet number = 1\nlet bool = true\nlet string = 'string'\nlet undefined\nlet nullValue = null\nlet symbol = Symbol('ThisIsASymbol')\nlet bigInt = BigInt(821983619283712837721893791287398123791283791283)\nlet bigIntAlternative = 89176291837981273928631716319836981273912873273827329982n\nlet valueNaN = NaN\n\n//Nota: NaN pertenece al grupo de datos primitivos number\n\nconsole.log(typeof valueNaN);\n\n\n//Console\nconsole.log('Hola, Javascript');\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Mvillegas18.js",
    "content": "/*\n  Documentacion de JavaScript en MDN\n\n  https://developer.mozilla.org/en-US/docs/Web/javascript\n*/\n\n// Comentario de una sola línea\n\n/*\n  Comentario de\n  multiples\n  lineas\n*/\n\nlet name = 'Miguel';\nconst age = 20;\n\n// Tipos de datos primitivos\n\nlet texto = 'Hola mundo';\nlet numero = 20;\nlet esVerdadero = true;\nlet indefinido = undefined;\nlet nulo = null;\nlet simbolo = Symbol('descripcion');\nlet tipoNAN = NaN;\n\nconsole.log('¡Hola, JavaScript!');\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/N1sek.js",
    "content": "//Aprendiendo Javascript 2024\n// Web oficial de Javascript: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n/*\nEste es \nun comentario\nmultilinea\n*/\n\n//Este es un comentario de solo una linea\n\n/* Dato JavaScript\n-------------------\nEn Javascript no es obligatorio poner \";\" al final de cada linea ya que el\nAutomatic Semicolon Insertion (ASI) los pone automaticamente siguiendo ciertas normas.\nPor eso habrá algun caso en particular en el que si no ponemos \";\" al final de la linea\nnos puede llegar a dar un error.\n*/\n\nconst SOY_UNA_CONSTANTE = 3.1415\n\nlet numero = 1\nlet cadena = \"Hola, JavaScript!\" \nlet booleano = true \nlet numeroEnorme = 12345678n\n\nlet nulo = null \nlet indefinido\n\nlet simbolo = Symbol(\"Hello\")\n\nconsole.log(simbolo)\n\nconsole.log(\"Hola, JavaScript!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/NNunezMedina.js",
    "content": "// https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n//Comentario en una linea \n\n/*\nEsto tambien es\nun comentario \nen varias lineas\n*/\n\n//CREA UNA VARIABLE Y UNA CONSTANTE----------\n\nlet variable = \"Mi variable\";\nvariable = \"Nuevo valor de mi variable\";\n\nconst otraVariable = \"Esta es mi variable constante\";\n\n//DATOS PRIMITIVOS---------------------------\n\nlet datoPrimitivoString = \"Esto es un string\";\nlet datoPrimitivoNumero = 1;\nlet datoPrimitivoBigInt = BigInt(9007199254740991);\nlet datoPrimitivoBooleanTrue = true;\nlet datoPrimitivoBooleanFalse = false;\nlet datoPrimitivoUndefined = undefined;\nlet datoPrimitivoSymbol = Symbol(\"simbolo\");\nconsole.log(datoPrimitivoString)\nconsole.log(datoPrimitivoNumero)\nconsole.log(datoPrimitivoBigInt)\nconsole.log(datoPrimitivoBooleanFalse)\nconsole.log(datoPrimitivoBooleanTrue)\nconsole.log(datoPrimitivoUndefined)\nconsole.log(datoPrimitivoSymbol)\n\n//IMPRESION POR CONSOLA\nconsole.log(\"Hola!, Javascript!\")\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/NathaliaMF.js",
    "content": "//https://developer.mozilla.org/es/docs/Web/JavaScript\n\n/**SINTAXIS, \n * VARIABLES, TIPOS DE DATOS Y \n * HOLA MUNDO\n */\n\n//SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n\n\n/**Declaracion de variables y constantes */\n\nlet age=27;\nconst name='Nathalia'; \n\n/**Datos primitivos\n *  number, string, boolean, Symbol, BigInt, Null, Undefined\n */\nlet height=1.59;\nlet gender='female'\nlet driverLicense=true;\nlet sym = Symbol(\"Valor primitivo\");\nlet elapsedDays = 1234567890123456789012345n;\nlet valueNull= null;\nlet valueUndefined = undefined;\n\nconsole.log('Hola Mundo, el lenguaje que aprendere sera JavaScript');\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/NightAlchemist.js",
    "content": "//https://developer.mozilla.org/en-US/docs/Web/JavaScript\r\n\r\n// one line comment\r\n/* \r\nmulti-line comment\r\nmulti-line comment\r\n*/\r\n\r\n// variables and constants\r\na = 32;\r\nvar x = 2; //only for old browsers\r\nlet y = 3;\r\nconst z = 4;\r\n\r\n// data types\r\nlet str = \"This is a string data type\";\r\n\r\nlet num1 = 45.90;\r\nlet num2 = 34;\r\nlet num3 = 12e3;\r\n\r\nlet bigInt = BigInt(\"123456789012345678901234567890\");\r\n\r\nlet bool = true;\r\n\r\nconst movies = [\"Deadpool\", \"Titanic\"];\r\n\r\nconst person = {firstName:\"John\", lastName:\"Doe\", age:50, eyeColor:\"blue\"}; //objects need classes\r\n\r\nlet color = undefined;\r\n\r\nconsole.log(\"¡Hola, JavaScript!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Nightblockchain30.js",
    "content": "// Existen 3 tipos de comentarios en JavaScript:\n// - Comentario de una linea:\n// Este es un comentario de una linea\n// - Comentario de varias lineas:\n/* Y Este es un comentario de varias lineas, como puedes ver estoy intentando escribir un comentario lo suficientemente largo\npara ensenarte que de esta manera se puede hacer un comentario de varias lineas, gracias por leer. */\n\n\n// Creando una variable (var, let) y una constante:\n/* Creando una variable usando var (function scope (si se declara dentro de un bloque condicional, se podra usar fuera de la condicional), \n    se puede volver a declarar con el mismo nombre y debido al hoisting estas variables\n    durante la fase de compilacion son movidas al comienzo del ambito o scope en el que se encuentran, si no han sido declaradas antes \n    de una ejecucion devolvera undefined) */\n    var variable_var = \"Soy una variable var\"; // Actualmente var no se usa, ya que no es una practica usada en el JavaScript moderno\n    console.log(variable_var)\n    // Creando una variable usando let (local scope (dependiendo en donde se declare y no se puede volver a redeclarar (mas optima de usar)))\n    let variableLet = \"Soy una variable let\";\n    console.log(variableLet)\n    /* Creando una variable const (Una variable constante (no podra volver a cambiar su valor), tiene que\n    declararse con un valor sino dara error y tiene ambito de bloque (block scope)) */\n    const variableConstante = \"Soy una variable constante y no podre volver a ser asignada\";\n    console.log(variableConstante)\n    \n    // Tipos de datos primitivos de JavaScript\n    // String: Sirve para almacenar cadenas de texto.\n    let cadena = \"Hola, mundo!\";\n    console.log(cadena)\n    // Number: Sirve para almacenar numeros\n    let numero = 40;\n    console.log(numero)\n    /* BigInt: Sirve para almacenar numeros más grandes que el tipo 'number'. Se define\n    agregando la letra \"n\" al final del número seguido de \"n\". */\n    let numeroBigInt = 1234567890123456789012345678901234567890n;\n    console.log(numeroBigInt)\n    // Boolean: Sirve para almacenar tipos booleanos que son true y false\n    let booleano = true;\n    console.log(booleano)\n    // Undefined: Las variables que son de tipo undefined significa que ya han sido declarado pero no les asignaron un valor\n    let variableUndefined;\n    let variableUndefinedExplicita = undefined\n    console.log(variableUndefined) // undefined\n    console.log(variableUndefinedExplicita)\n    // Symbol: Es un tipo de dato que sus instancias son unicas e inmutables\n    let variableSymbol = Symbol(\"foo\");\n    console.log(variableSymbol)\n    \n    // IMPRIMIR POR CONSOLA \"HOLA, [NOMBRE DEL LENGUAJE]!\"\n    console.log(\"¡Hola, JavaScript!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Nixoo657.js",
    "content": "// sitio web: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// torta\n\n/* jijija */\n\nvar balduino = \"jijjja\";\n\nconst felipe = \"301\";\n\nlet boolean = false;\n\nlet number = 301;\n\nlet string = \"soy muy bueno programando\";\n\nlet bigint = 111111111234567899098765432123456789098765423456789098;\n\nlet symbol = Symbol(); \n\nlet variable_null = null;\n\nconsole.log(\"hola Javascropt!!!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/NxL22.js",
    "content": "// Web: https://www.javascript.com/\n\n// Comentario de una Linea\n\n/* comentario en varias \nlineas\n¿Si lo entiendes? \n*/\n\n// variable\nlet variable = \"variable\";\n// esta es una variable global\nvar myVar = \"variable global\";\n// constante\nconst constante = \"no varia\";\n\n// Tipo de dato number (número)\nlet numero = 2;\nlet numeroDecimal = 2.5;\n\n// Tipo de dato string (cadena de texto)\nlet string = \"texto loco\";\n\n// Tipo de dato boolean (booleano)\nlet esVerdadero = true;\nlet esFalso = false;\n\n// Tipo de dato undefined\nlet sinDefinir;\n\n// Tipo de dato null\nlet nulo = null;\n\n// Tipo de dato symbol (símbolo)\nlet simbolo = Symbol(\"mi-simbolo\");\n\n// Tipo de dato bigint (entero grande)\nlet numeroGrande = 9007199254740991n; // Notación con la letra 'n' al final\n\n\nconsole.log(\"Hola, Javascript\")\n\n\n// imprimir los valores y tipos en la consola\nconsole.log(\"Valor de 'variable':\", variable, typeof variable);\nconsole.log(\"Valor de 'myVar':\", myVar, typeof myVar);\nconsole.log(\"Valor de 'constante':\", constante, typeof constante);\nconsole.log(\"Valor de 'numero':\", numero, typeof numero);\nconsole.log(\"Valor de 'numeroDecimal':\",numeroDecimal, typeof numeroDecimal);\nconsole.log(\"Valor de 'string':\", string, typeof string);\nconsole.log(\"Valor de 'esVerdadero':\", esVerdadero, typeof esVerdadero);\nconsole.log(\"Valor de 'esFalso':\", esFalso, typeof esFalso);\nconsole.log(\"Valor de 'sinDefinir':\", sinDefinir, typeof sinDefinir);\nconsole.log(\"Valor de 'nulo':\", nulo, typeof nulo);\nconsole.log(\"Valor de 'simbolo':\", simbolo, typeof simbolo);\nconsole.log(\"Valor de 'numeroGrande':\", numeroGrande, typeof numeroGrande);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/OmarLand.js",
    "content": "// Voy a Retomar la programación con el lenguaje JavasCript espero todo vaya bien\n// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Comentario una linea\n\n/*\n    ##\n    ## Para varias lineas\n    ##\n*/\n\nconst pi = \"3.14\"\nlet saludo = \"Hola\"\nlet lenguaje = \"Javascript\"\n\n// Tipo de datos primitivos\n// Number\nlet num = 100;\nlet floating = 100.5;\n\n// boolean\nlet isActive    = true;\nlet isNotActive = false;\n\n//string\nlet nombre = \"Omar\"\nlet nombreCompleto = \"Omar Jesús Landaeta\"\n\n//undefined \nlet anything = undefined;\n\n//null\nlet fname = null;\n\nconsole.log(`¡Hola, ${lenguaje}!`);"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/OmaritoAtPoly.js",
    "content": "// This is the URL for the official documentation for JavaScript https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n// This is the way to write inline comments\n\n/* This is a multi \n\nline comment syntax */\n\n// IN JS we can declare a variable using three different syntax:\n\nconst thisIsAConstant = 100;\n\nlet thisIsNotConstant = \"scoped value\";\n\nvar thisIsGlobal = true;\n\n// All primitives in JavaScript\n\nlet stringValue = \"this is a string\" ;\n\nlet numberValue = 999 ;\n\nlet bigintValue = BigInt(Number.MAX_SAFE_INTEGER); // 9007199254740991n;\n\nlet booleanValue = false;\n\nlet undefinedValue;\n\nlet symbolValue = Symbol(\"foo\");\n\nlet nullValue = null;\n\nlet usedLanguage = \"JavaScript\";\n\nconsole.log(\"¡Hola,\", usedLanguage+\"!\" );\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/OscarLetelier.js",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n\n\n// 1. SOLUCIÓN\n/* \nSitio Web Oficial de JavaScript\nURL: https://developer.mozilla.org/es/docs/Web/JavaScript\n*/\n\n\n// 2. SOLUCIÓN\n// Comtentario de una Linea\n/*\nComentario de varias\nLineas\n*/\n\n\n// 3. SOLUCIÓN\nlet nombre = \"oscar\";\nconst estudios = \"Foreva\";\n\n\n// 4. SOLUCIÓN\nlet string = \"Hola\";\nlet number = 1;\nlet booleano = true;\nlet float = 1.5;\nlet hola = ''; //Undefined\n\n\n// 5. SOLUCIÓN\nlet saludo = \"¡Hola, JavaScript!\";\nconsole.log(saludo)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/OskarCali.js",
    "content": "// **********     ENLACES DE REFERENCIA     **********\n// Estandar de ECMAScript             ==>   https://ecma-international.org/publications-and-standards/standards/ecma-262/\n// Especificacion de ECMAScript(2023) ==>   https://262.ecma-international.org/14.0/\n// Referencia de JavaScript           ==>   https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// **********     FORMAS DE COMENTAR     **********\n// Comentario en una sola linea\n/* Comentario en\n * multiples lineas\n */\n\n// **********     DECLARAR VARIABLES Y CONSTANTES     **********\n// var  ==>   Declara una variable; puede tener cambios de valor y asignacion posterior\nvar globalScoped = \"Valor\";\nglobalScoped = 18;\n// let  ==>   Declara una variable en el scope (local); puede tener cambios de valor y asignacion posterior\nlet localScoped;\nlocalScoped = \"Asignacion\";\n// const ==>  Constante en el scope; no puede cambiar de valor\nconst readOnlyScoped = \"OskarCali\";\n\n// **********     TIPOS DE DATO (PRIMITIVOS)     **********\nlet _boolean = Boolean(true)\nlet _null = null\nlet _undefined = undefined\nlet _number = Number(87.654)\nlet _bigInt = BigInt(Number.MAX_SAFE_INTEGER)\nlet _string = String(\"OskarCali\")\nlet _symbol = Symbol(894)\n\n// **********     IMPRESION EN TERMINAL     **********\nconsole.log(\"¡Hola, javascript!\");\n\n// **********     REFERENCIAS ADICIONALES     **********\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#comments\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#primitive_values"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Ovmiguel16.js",
    "content": "// Sitio web oficial de Javascript https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Para realizar comentarios de una linea se utilizan las barras inclinadas dobles \"//\"\n\n/* Para realizar comentarios de varias lineas \nse utilizan las barras inclinadas dobles y se añaden los asteriscos despues y al principio respectivamente\n\n*/\n\nlet variable = \"Variable let\"; //El valor puede cambiar  \n\nconst variableDos = \"Variable const\"; // El valor no se va a poder cambiar\n\nlet variableString = \"texto\";\nlet variableNumber = 100; \nlet variableBooleano = true;\nlet undefined;\nlet variableNull = null; \n\nlet mensajeBienvenida = \"¡Hola, JavaScript!\";\n\nconsole.log(mensajeBienvenida);"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Pancratzia.js",
    "content": "/************ 1 - SITIO OFICIAL DE JAVASCRIPT ************/\n/*\nPodría decirse que, como standard (ECMAScript) el sitio oficial del lenguaje es: http://www.ecmascript.org/\nSin embargo, este sitio solo se ocupa de la estandarización.\nLas especificaciones del lenguaje para desarrolladores se encuentra en el siguiente url: https://developer.mozilla.org/en/JavaScript\n*/\n/*********************************************************/\n\n/************ 2 - TIPOS DE COMENTARIOS ************/\n\n// COMENTARIOS DE UNA SOLA LINEA\n/*\nCOMENTARIOS\nDE\nVARIAS\nLINEAS\n*/\n\n/**************************************************/\n\n/************ 3 - CREANDO VARIABLES ************/\nvar variableVar = \"Una variable usando VAR\"; //Desde hace años, ya no se recomienda usar VAR\nlet variableLet = \"Una variable usando LET\";\nconst CONSTANTE = \"Una constante\";\n/***********************************************/\n\n/************ 4 - TIPOS DE DATOS PRIMITIVOS ************/\n\nlet tipoCadena = \"Hola, soy una cadena de texto\";\n//Los de tipo number pueden ser enteros o decimales\nlet tipoNumber = 42;\ntipoNumber = 42.5;\nlet tipoBooleano = true;\nlet tipoIndefinido = undefined;\nlet tipoSimbolo = Symbol(\"mySymbol\");\nlet tipoBigInt = 1234567890123456789012345678901234567890n;\n\n\nlet tipoNulo = null; //Aunque algunos ejemplos lo clasifican como primitivo, en la documentación de Mozilla (https://developer.mozilla.org/es/docs/Glossary/Primitive) se indica que es un \"caso especial\".\n\n/*******************************************************/\n\n/************ 5 - HOLA, JAVASCRIPT ************/\nconsole.log(\"¡Hola, JavaScript!\");\n/**********************************************/"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Pierre-OL.js",
    "content": "// url del lenguaje de programación elegido (\"https://developer.mozilla.org/es/docs/Web/JavaScript\");\n\n// Comentario de una sola línea\n\n/*Comentario de \n  varias \n  lineas*/\n\n// Declarando variables\nvar firstName = \"Jhon\";\nlet lastName = \"Doe\";\n\n// Declarando constante\nconst idTag = \"Jhdoe\";\n\n// Tipos de datos primitivos\n\n//Numbers\nlet edad = 18;\nlet estatura = 170.5;\n\n// Strings\nlet myString = \"Hello!\";\nlet otherString = \"oceano\";\nlet oneMoreString = `navegar`;\n\n// Booleans\nlet esVerdad = true;\nlet esFalso = false;\n\n// Null\nlet esNulo = null;\n\n// Undefined\nlet electricCar;\n\n// Symbol\nconst simbolOne = Symbol(\"MySimbol\");\n\n// BigInt\nconst numGrande = 9007199254740991n;\n\n// Object\nconst user = {\n  someName: \"Bart\",\n  someLastName: \"Simpson\",\n};\n\n// Array Object\nconst tool = [\"chainsaw\", \"screwdriver\", \"drill\"];\n\n// Date object\nconst date = new Date(\"2024-02-06\");\n\n// Imprimit en consola:\nlet mensaje = \"Javascript\";\nconsole.log(`¡Hola, ${mensaje}!`);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Poetry0354.js",
    "content": "//https://www.javascript.com/ O https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n/* \nHola Como estamos?\nEste es un coomentario en varias lineas, algo que realmente no sabia\nHasta este momento jssjsjs \nPero bueno :D\n*/\nlet adios = \"Hasta luego\";\nconst bueno = \"Hola\";\nvar viejito = \"edad\";\n\n //Tipos de datos en JavaScript (Segun el curso que hice del ministerio de educacion :D).\n /* \n Encontramos los datos esenciales.\n - Number\n - String\n - Boolean\n - Undefined\n - Null\n - Object\n - Symbol\n */\nlet Number = 10; //Cualquier tipo de Numero incluyendo los decimales.\nlet String = \"Hola Comunidad\" //Cualquier tipo de texto que debe estar entre comillas.\nlet Boolean = true; //Cualquier tipo de booleano. Verdadero o Falso.\nlet Undefined; //Variable declara pero que no tiene un valor asignado por ahora.\nlet Null = null;//Variable que no tiene valor.\nlet Object = {\n    nombre: \"Diego\",\n    edad: 20,\n    estatura: 1.70\n};//Objeto que contiene varios datos. Atributos.\n\nconsole.log(\"Hola, JavaScript, ¿Como estamos?\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Pogo182028.js",
    "content": "// https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n// comentarios de una sola línea (solo se puede comentar en esta línea)\n\n/* \n    comentarios en bloque\n    (se puede comentar en varias líneas)\n*/\n\nlet variable;\nconst variableConstante = 100;\n\nlet cadena = \"Esto es una cadena\";\nlet numero = 182028;\nlet booleano = true;\n\nconsole.log(\"¡Hola, JavaScript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/QuirogaPau.js",
    "content": "// https://developer.mozilla.org/es/docs/Web/JavaScript\n// Comentario de una linea\n/* Comentario\nde \nvarias \nlineas */\n\n// - Crea una variable (y una constante si el lenguaje lo soporta).\n\nlet variable;\nconst CONSTANTE = 3.14;\n\n/* Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).*/\n\nlet string = \"texto\"; //Representa cadenas de textos.\nlet number = 10; //Representa numeros \nlet booleano = false; //Representa un valor lógico y puede tener dos valores, ya sean true o false.\nlet BigInt = 1234567890123456789012345678901234567890n; //Representa valores numéricos que son demasiado grandes para ser representados por el tipo de dato number.\nlet valor = null; //Representa la ausencia intencional de cualquier valor, un valor nulo o «vacío»\nlet indefinido = undefined; // Representa una variable que no ha sido declarada o a la cual no se le ha asignado un valor.\nlet symbol = Symbol(); //El tipo symbol (símbolo) se utiliza para crear identificadores únicos para los objetos.\n\n/* - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"*/\nlet javascript = \"JavaScript\";\nconsole.log(`¡Hola, ${javascript}!`);"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/RaquelTejada.js",
    "content": "// Esta es la web oficial de JavaScript https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Este es un comentario en una línea\n\n/*\n *Este es un comentario en varias líneas\n *Esta es la web oficial de JavaScript\n *https://developer.mozilla.org/es/docs/Web/JavaScript\n */\n\nvar firstVariable = variableValue;\n\nconst firstConstant = constantValue;\n\n// String\nvar stringVar = \"Esto es una string\";\n\n// Number\nvar numberVar = 2;\n\n// Big Int\nvar bigIntVar = 237349857239458034725n;\n\n// Boolen\nvar booleanVar = true;\n\n// Null\nvar nullVar = null;\n\n// Undefined\nvar undefinedVar = undefined;\n\n// Symbol\nvar symbolVar = Symbol(\"sym\");\n\nconsole.log(\"Hola, JavaScript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/RaulDoezon.js",
    "content": "/*\n * EJERCICIO:\n * 1. Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * 2. Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * 3. Crea una variable (y una constante si el lenguaje lo soporta).\n * 4. Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * 5. Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n*/\n\n// +++++++++ 1 +++++++++\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n// +++++++++ 2 +++++++++\n// Soy un comentario de una línea.\n\n/*\n  Y yo soy\n  un comentario\n  de múltiples\n  líneas\n*/\n\n// +++++++++ 3 +++++++++\nvar name = 'Raúl';\nconst height = 1.82;\n\n// +++++++++ 4 +++++++++\nvar soyString = 'Juan';\nvar soyNumber = 3.16;\nvar soyBigInt = 9007199254740991n;\nvar soyBoolean = true;\nvar soyUndefined = undefined;\nvar soySymbol = Symbol('Símbolo');\n\n// +++++++++ 5 +++++++++\nconsole.log('¡Hola, JavaScript!');\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Recamalesdev.js",
    "content": "/* EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"*/\n\n// https://262.ecma-international.org/\n\n/* Este es un ejemplo de \n   comentario multilínea \n*/\n\nlet age = 38;\nconst name = \"Bernardo\";\n\nconst string1 = \"Una cadena primitiva\";\nvar number = 38;\n\nconst previouslyMaxSafeInteger = 9007199254740991n;\nlet x1 = false;\nlet x = true;\nlet sym1 = Symbol();\nlet variable1 = undefined;\nlet variable2 = null;\n\nconsole.log(\"¡Hola, JavaScript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/RicJDev.js",
    "content": "//EJERCICIO\n//https://developer.mozilla.org/es/docs/Web/JavaScript\n//comentario en una linea\n\n/*\n:D\ncomentario en varias lineas\n*/\n\nlet myAge = 21;\nconst myName = 'Ricardo';\nconst myStr = 'Esta es una string';\nconst myInt = 3;\nconst myFloat = 3.45;\nconst myBool = true;\nconst myUndefined = undefined;\n\nconsole.log('Hola, JavaScript');\nconsole.log(`Tengo ${myAge} años`);\nconsole.log(`Mi nombre es ${myName}`);\nconsole.log(`${myFloat} es un number`)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Ricarsur.js",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n//https://www.javascript.com/\n\n/*\ncomentario\nen \nvarias \nlineas\n*/\n\nvar my_variable = 20\nconst MY_CONSTANT = 10\n\n\nlet int = 1\nlet float = 1.5\nlet intBig = BigInt(33454634123456789545)\nlet none = null\nlet boolean = true\nlet arreglo = [1,2,3]\nlet undefine\nlet string = \"hola\"\n\nconsole.log(`¡Hola, JavaScript!`)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Rikar2o.js",
    "content": "//El lenguaje mas chingon JavaScript https://www.javascript.com/\n\n// comentario de una linea\n\n/*\ncomentarios de varias\nlineas o de parrafos\n*/\n\n//Crea una variable y una constante\nlet miVariable = \"soy una variable\";\nconst miConstante = \"soy una constante\";\n\n//Crea variables representando todos los tipos de datos primitivos//\n\nlet numero = 12;\nlet string = \"soy una cadena de texto\";\nlet booleano = true;\n\n//Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\nlet lenguajeProgramacion = \"JavaScript\";\n\nconsole.log(`Hola ${lenguajeProgramacion}`);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Robindev1812.js",
    "content": "/*\r\nEjercicios:\r\n*/\r\n\r\n/* \r\n1. Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\r\n*/\r\n\r\n//https://javascript.info/\r\n\r\n\r\n/*\r\n2. Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\r\n*/\r\n\r\n//Éste es un comentario de una sola linea\r\n\r\n/*\r\nÉste es un comentario\r\nde \r\nvarias lineas\r\n*/\r\n\r\n\r\n/*\r\n3. Crea una variable (y una constante si el lenguaje lo soporta).\r\n*/\r\n\r\nlet name = 'Robinson'\r\nconst SALUDO = 'Hello!'\r\n\r\n\r\n/*\r\n4. Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\r\n */\r\n\r\n\r\n//String:\r\nlet my_str = 'my str'\r\n\r\n//Number:\r\nlet number = 48\r\nlet number2 = 12.3\r\n\r\n//Boolean:\r\nlet varTrue = true\r\nlet varFalse = false\r\n\r\n//Null:\r\nlet isNull = null\r\n\r\n//Undefined:\r\nlet comidaFavorita\r\n\r\n//Symbol:\r\nconst simbolo = Symbol('foo');\r\n\r\n//BigInt:\r\nlet bigInt = 10n\r\n\r\n\r\n/*\r\n5. Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\r\n*/\r\n\r\nconsole.log(\"¡Hola, JavaScript!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Rodmiggithub.js",
    "content": "/*  \nCrea un comentario en el código y coloca la URL del sitio web oficial del\nlenguaje de programación que has seleccionado.\n*/\n// https://developer.mozilla.org/es/docs/Web/JavaScript\n/*\nRepresenta las diferentes sintaxis que existen de crear \ncomentarios en el lenguaje\n*/\n// Comentario en una linea\n\n/*\n    Esto es un comentario\n    en varias\n    lineas\n*/\n//Crea una variable (y una constante si el lenguaje lo soporta).\nvar variable\nlet variable2\nconst variable3 = 'variable constante';\n/*\nCrea variables representando todos los tipos de datos primitivos  \ndel lenguaje (cadenas de texto, enteros, booleanos...).\n*/\nlet cadena = 'variable string'; // string\nlet numero = 1;                 // number\nlet boolean = false;            // boolean\nlet nulo = null;                // null\nlet indefinido = undefined;     // undefined\nlet bigint = 2n;                // bigint\nlet simbol = Symbol();          // simbol\n\n// - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nconsole.log(\"¡Hola, JavaScript!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Rolo27s.js",
    "content": "// Usuario: Rolo27s - https://github.com/Rolo27s/Rolo27s\n// Ejercicio #00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n/* \nSITIO WEB OFICIAL DE JAVASCRIPT\nhttps://developer.mozilla.org/es/docs/Web/JavaScript \n*/\n\n// Comentario de una línea\n\n/* \nComentarios de varias líneas\nVarias lineas...\nVarias lineas...\nwhile (true) ...\n*/\n\n// Declares a block-scoped, read-only named constant.\nconst E = 2.71828; // Declaración de una constante\n\n// Declares a block-scoped, local variable, optionally initializing it to a value.\nlet variable_usuario_local = \"Rolo27s\"; // Declaración de una variable\n\n// Declares a variable, optionally initializing it to a value.\nvar variable_usuario_global = \"Rolo27s_GLOBAL\"; // Declaración de una variable. Personalmente suelo codear usando let y modularizando.\n\n// Hay siete tipos de datos primitivos en JavaScript:\n// 1. Boolean\nlet tipo_booleano = true; // true o false\n// 2. null (JS is case-sensitive)\nlet tipo_null = null; // Valor nulo. Cuidado que no es Null, NULL o cualquier otra variante. Debe ser estrictamente null (minúsculas).\n// 3. undefined\nlet tipo_undefined = undefined; // Valor no definido.\n// 4. Number\nlet tipo_numero_entero = 42; // Valor numérico entero.\nlet tipo_numero_decimal = 42.56; // Valor numérico decimal.\n// 5. BigInt\nlet tipo_bigint = 9007199254740992n; // Valor numérico BigInt. Se remarca con la 'n' al final del numero.\n// 6. String\nlet tipo_string = \"Brais Moure - @mouredev\"; // Valor numérico String.\n// 7. Symbol\nlet tipo_Symbol = Symbol(\"mySymbol\"); // Valor numérico Symbol.\n\n/* Imprimimos por terminal un mensaje. \nPara hacer esto de manera literal necesitaríamos tener instalado NodeJS. \nhttps://nodejs.org/en\nEjecutamos nuestro archivo .js usando el comando: node 'nombre-de-tu-js.js'*/\nconsole.log(\"¡Hola, JavaScript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/RoniPg.js",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\t\n\n\n//URL : https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Comentario en una linea.\n/*\n* Comentario de varias lineas.\n*/\nlet numero = 0 // Tipo Number, valores numericos\nlet flotante = 3.14 // Tipo float, valor numerico de coma flotante\nlet noEsUnNumero= Nan // Tipo Not at Number, valor NoEsUnNumero\nlet infinito = Infinity // Tipo Infinity, valor Infinito\n\nlet string = \"\" // Tipo string, valores de tipo texto\nlet comillaSimple = '' // Tipo string, valores de tipo texto\nlet comillasDobles= \"\" // Tipo string, valores de tipo texto\nlet textoFormateado = `${string}`// Tipo string, valores de tipo texto y formateados\n\nlet boleano = false; // Tipo Boolean, valores true, false.\n\nlet indefinido // Tipo Undefined, no contiene valor asignado\nlet nulo = null // Tipo Null, valor nulo\nlet simbolo = Symbol('')// Tipo Symbol, valor único e inmutable\nlet enteroGrande = 0n // Tipo BigInt, valores que superan el rango de los Number \n\n\n//Para crear una constante se añade utiliza la palabra reservada 'const'.\n\nconst constante = 0  // Las constantes aceptas los datos primitivos mencionados antes \n\nconsole.log(\"Hola JavaScript\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/RoyHuamanAvila.js",
    "content": "//https://developer.mozilla.org/en-US/docs/Web/javascript\n\n//En Linea\n\n/*\n  Comentario\n  Multiline \n*/\n\nvar variable;\nconst constante = 0;\n\nlet cadena = \"String\";\nlet numero = 2002;\nlet booleano = true;\nlet decimal = 2.2;\nlet array = [1, 2, 3, 4];\nlet objeto = {\n  name: \"Roy Andres\",\n  age: 22,\n};\nlet nan = NaN;\nlet indefinido = undefined;\nlet nulo = null;\nlet symbol = Symbol(\"Symbol object\");\n\nconst lenguaje = \"Javascript\";\n\nconsole.log(`¡Hola, ${lenguaje}!`);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/SRSURY.js",
    "content": "// url de javascript: https://developer.mozilla.org/es/docs/Web/JavaScript\n// esta es la sintaxis de javascript para hacer un comentario de una sola lìnea\n/*\n    Esta es la sintaxis de javascript para hacer un comentario de varias líneas\n*/\n//variables\nvar variableVar = \"la mas basica\";\nlet variableLet = \"la mas versatil\";\nconst variableConst = \"la mas segura\";\n// tipos de datos primitivos\nlet numero = 10; // number\nlet texto = \"Hola Mundo\"; // string\nlet booleano = true; // boolean \nlet booleano2= false; // boolean\nlet nulo = null; // null\nlet indefinido; // undefined\nlet simbolo = Symbol(\"mi simbolo\"); // symbol\n// dos tipos de datos que no son primitivos\nlet objeto = { clave: \"valor\" }; // object\nlet arreglo = [1, 2, 3]; // array\n//imprimir en consola\nconsole.log(\"Hola, JavaScript!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Sac-Corts.js",
    "content": "// JavaScript programming language official website URL:\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n// Single line comment in JavaScript\n\n/*\nMulti-line comment in JavaScript\nIt is used to describe longer blocks of code.\nor provide detailed information.\n*/\n\nvar myGlobalVariable = \"This is a global variable\"\n\nlet myLocalVariable = \"This is a local variable\";\n\nconst MY_CONSTANT = \"This is a constant\";\n\n// String\nlet textString = \"Hello, I am a string\";\nconsole.log(typeof(textString))\n\n// Number\nlet integer = 42;\nconsole.log(typeof(integer))\n\nlet float = 3.14;\nconsole.log(typeof(float))\n\n// Boolean\nlet boolean = true;\nconsole.log(typeof(boolean))\n\n// Undefined\nlet undefinedVar;\nconsole.log(typeof(undefinedVar))\n\n// Null\nlet nullVar = null;\nconsole.log(typeof(nullVar))\n\n// Symbol\nlet symbol = Symbol('description');\nconsole.log(typeof(symbol))\n\n// BigInt\nlet bigInt = BigInt(1234567890123456789012345678901234567890n);\nconsole.log(typeof(bigInt))\n\n// Print the required text via terminal\nconsole.log(\"¡Hello, JavaScript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/SaintsLuis.js",
    "content": "// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Comentario de una linea\n/* Comentario de \nvarias lineas \n*/\n\nconst const1 = 1\nvar var1 = 1\nlet var2\n\nconst stringType = 'JavaScript'\nconst intType = 1\nconst boolType = true\nconst nullType = null\nconst undefinedType = undefined\n\nconsole.log(`¡Hola, ${stringType}`)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/SalazarProgrammer.js",
    "content": "/*\nEJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n */\n\n// Sitio web oficial de JavaScript: https://developer.mozilla.org/es/docs/Web/JavaScript\n// También puedes visitar: https://www.javascript.com/\n\n/*\n * DIFERENTES SINTAXIS DE COMENTARIOS EN JAVASCRIPT:\n */\n\n// Comentario de una línea\n\n/*\n    Comentario de múltiples líneas\n    que puede abarcar varias líneas\n    de código\n*/\n\n/**\n * Comentario de documentación JSDoc\n * @param {string} nombre - Descripción del parámetro\n * @returns {string} - Descripción del retorno\n */\n\n// VARIABLES Y CONSTANTES\nlet variable = 'Soy una variable'; // Variable que puede cambiar\nconst constante = 'Soy una constante'; // Constante que no puede cambiar\n\n// TIPOS DE DATOS PRIMITIVOS EN JAVASCRIPT\nlet cadenaTexto = 'Hola Mundo'; // String\nlet numeroEntero = 42; // Number (entero)\nlet numeroDecimal = 3.14; // Number (decimal)\nlet booleanoVerdadero = true; // Boolean\nlet booleanoFalso = false; // Boolean\nlet nulo = null; // Null\nlet indefinido = undefined; // Undefined\nlet simbolo = Symbol('miSimbolo'); // Symbol (ES6)\nlet bigInt = 9007199254740991n; // BigInt (ES2020)\n\n// IMPRIMIR POR TERMINAL\nconsole.log('¡Hola, JavaScript!');\n\n// También puedes mostrar las variables\nconsole.log('Cadena de texto:', cadenaTexto);\nconsole.log('Número entero:', numeroEntero);\nconsole.log('Booleano:', booleanoVerdadero);\n\n// Ejemplo de uso de template strings (más moderno)\nconst lenguaje = 'JavaScript';\nconsole.log(`¡Hola, ${lenguaje}!`); // Usando template literals\n\n// Fin del programa\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/SergioGI99.js",
    "content": "/*\n------------------------------------------------\nSINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n------------------------------------------------\n¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n- Recuerda que todas las instrucciones de participación están en el\n  repositorio de GitHub.\n\nLo primero... ¿Ya has elegido un lenguaje?\n- No todos son iguales, pero sus fundamentos suelen ser comunes.\n- Este primer reto te servirá para familiarizarte con la forma de participar\n  enviando tus propias soluciones.\n\nEJERCICIO:\n- Crea un comentario en el código y coloca la URL del sitio web oficial del\n  lenguaje de programación que has seleccionado.\n- Representa las diferentes sintaxis que existen de crear comentarios\n  en el lenguaje (en una línea, varias...).\n- Crea una variable (y una constante si el lenguaje lo soporta).\n- Crea variables representando todos los tipos de datos primitivos\n  del lenguaje (cadenas de texto, enteros, booleanos...).\n- Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\n¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\ndebemos comenzar por el principio.\n*/\n\n// https://developer.mozilla.org/es/docs/Web/JavaScript\n\nvar myString = \"Esto es un string\"\n\nconst myConst = \"Esto es una constante\"\n\nlet myInt = 8\nlet myFloat = 3.14\nlet myBool = true\nlet myNull = null\nlet myUndefined = undefined \nlet myBigInt = 123124235234123123124n\nlet mySymbol = Symbol()\n\nconst myLang = \"JavaScript\"\n\nconsole.log(`¡Hola, ${myLang}`)\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/SingularPigeon.js",
    "content": "// https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n// Comentario de una línea\n\n/*\n * Comentario\n * de varias\n * lineas\n */\n\nlet cantante = 'Billie Eilish';\nconst escuchar = 'música'; \n\nmy_integer = 44;\nmy_float = 44.8;\nmy_string = 'Quiero papitas';\nmy_booleanT = true;\nmy_booleanF = false;\nmy_undifined = undefined;\nmy_symbol = Symbol();\nbig_number = 73632732732823n;\n\nconsole.log('¡Hola el lenguaje es Javascript!')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/SirNaze0.js",
    "content": "//https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n//Comentario de una línea\n\n/*Comentario de varias líneas*/\n\nlet myVariable=\"variable\";\n\nconst myConstante =3.14;\n\n//Data types\n\n//String\nlet myString =\"texto\";\nlet myString2='texto';\nlet myString3=`texto`;\n//Numbers(integers o floats)\nlet myNumber=2;\nlet myNumber2=2.4;\n//BigInt\nlet myBigInt=10101000n;\n//Boolean\nlet myBoolean=false;\n//Object\nlet myObject={tipo:\"Regla\",tamaño:\"30cm\"};\n//Undefined\nlet myUndefined= undefined;\n//Null\nlet myNull=null;\n//Symbol\nlet mySymbol=Symbol(\"mySymbol\");\n\nconsole.log(\"¡Hola, Javascript!Hola\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/SiulDev.js",
    "content": "// URL de la pagina oficial:\n// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// --------------------------------------------------------------------------------------------------------\n// TIPOS DE COMENTARIOS EN JAVASCRIPT:\n\n// Comentario de una linea en JavaScript.\n\n/* \nEsto tambien es un comentario\npero de varias lineas\nen JavaScript .\n*/\n\n/**\n * Esto de aqui\n * tambien es un comentario\n * de varias lineas\n * en JavaScript\n * pero con asteriscos\n * para hacerlo mas \"legible\".\n */\n\n// --------------------------------------------------------------------------------------------------------\n// TIPOS DE VARIABLES EN JAVASCRIPT:\n\nvar helloWorld ;            // variable con scope global, que puede ser re-declarada y modificada (uso NO recomendado).\nlet userMessage;            // variable con scope limitado a un bloque de codigo y puede ser modificada (uso recomendado).\nconst USER_PASSWORD = 123;  // Variable Constante en JavaScript que no puede ser modificada.\n\n// para las variables se usa calmeCase y para las Constantes se usa UPPER_SNAKE_CASE como tecnica de Naming en javaScript.\n\n// --------------------------------------------------------------------------------------------------------\n// TIPOS DE DATOS PRIMITIVOS\n\nlet myBolean = true;          // Bolean     -> El tipo boolean tiene sólo dos valores posibles: true y false.\nlet myString = 'hello world'; // String     -> cadena de texto donde se usan '' o \"\" para el string.\nlet myNumber = 123;           // Number     -> El tipo number representa tanto números enteros como de punto flotante.\nlet myBigInt = 32983192898n;  // BigInt     -> Para representar enteros de longitud arbitraria, se usa \"n\" para identificar que es BingInt.\nlet myNull = null;            // Null       -> Para valores desconocidos – un tipo independiente que tiene un solo valor nulo.\nlet myUndefined;              // Undefined  -> Para valores no definidos o \"no asignados aun\".\nlet mySymbol = Symbol(\"id\");  // Symbol     -> Los Symbols se utilizan a menudo para añadir claves de propiedades únicas.\n\n// --------------------------------------------------------------------------------------------------------\n// IMPRIMIENDO UN SALUDO CON EL LENGUAJE DE PROGRAMACION USADO\n\nconsole.log(\"¡Hola, JavaScript!\"); //se reflejara en la terminal el saludo!."
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Sjho-406.js",
    "content": "//https://www.javascript100.dev/ (No es el sitio web oficial pero no se cual es el original UnU)\n\n//Formas de comentar (En una linea)\n/* \nEste sería para \ncomentar en \nvarias lienas\n*/\n\nvar myVariable\nlet variable\nconst constante = 0\n\nlet int = 1 // number/int\nlet float = 1.5 // number /float\nlet str = 'hola' // string\nlet bool = true // boolean\nlet nd = null // null\nlet undefined // undefined\nlet symbol = Symbol() // symbol\nlet big = 31497272638737836n // bigint\n\nconsole.log('Hola, JavaScript')\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/TasyMed.js",
    "content": "// ---- Web ----\n\n// www.javascript.com\n\n// ---- Comentarios ----\n\n// Comentario \n\n/*\n    Comentario de varias lineas\n*/\n\n// ---- Variables y constantes ----\n\nlet Variable = \"Se puede declarar depues o al momento de crearla\"\n\nconst Constante = \"Siempre se debe de declarar\"\n\n// ---- Tipos de datos primitivos ----\n\n// 1 - String\n\nconst String = \"Esto es un String\"\n\n// 2 - Boolean\n\nconst BooleanTrue = true\nconst BooleanFalse = false\n\n// 3 - Tipo numero\n\nconst numero = 23\n\n// 4 - Symbol \n\nconst Symbol = Symbol(\"Unico\")\n\n// 5 - Undefined\n\nlet Undefined;\n\n// 6 - Null\n\nconst Null = null\n\n// ---- Imprimir en la consola ----\n\nconsole.log(\"!Hola, JS¡\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/TizoG.js",
    "content": "\n/* \n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n * lenguaje de programación que has seleccionado\n*/\n// Sitio web oficial de JavaScript -> https://developer.mozilla.org/es/docs/Web/JavaScript\n\n\n/*\n* - Representa las diferentes sintaxis que existen de crear comentarios\n*   en el lenguaje (en una línea, varias...).*/ \n/*\nEsto es\nun comentario \nen varias\nlineas \n*/\n\n\n// * - Crea una variable (y una constante si el lenguaje lo soporta).\n/* \nVar -> Variable Global. \nlet -> Variable Local.\n*/\n\nvar variableGlobal = \"Esto es una variable global.\"\nlet variableLocal = \"Estos es una variable local.\"\n\n// Const -> Constantes.\nconst constante = \"Esto es una constante.\"\n\n\n/*\n* - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n*/\n\n// Datos Primitivos.\nlet entero = 1              // Number\nlet conDecimal = 3.12       // Decimal\nlet texto1 = \"Hola Mundo\"   // String\nlet verdaddero = true       // Boolean\nlet falso = false           // Boolean\nlet noDefinido              \nlet unDefined = undefined   // Undefined\nlet conPrecision = 9862534839n //BigInt\nlet nulo = null             // null\n\n\n//  * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\nconsole.log(\"¡Hola, JavaScript!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/TofeDev.js",
    "content": "// No hay sitio oficial, pero existe estos famosos documentos sobre js: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Comentario de una linea\n\n/* Comentario de\n*varias lineas \n*/\n\nvar x = 50 //Variable global\nlet y = 20 //Variable local\nconst z = 100 //Variable local, que NO se puede cambiar su value\n\nlet String = \"JavaScript\"\nlet boolean = true\nlet number = 40\nlet float = 1.52\nlet dnull = null\nlet bigInt = 152n\nlet indefinido = undefined\nlet array = [1, 2, 3, 4, 5]\nlet objeto = {lenguaje: \"JavaScript\", reto: 0}\nlet simbol = Symbol('algo')\n\nconsole.log(\"¡Hola, \" + String + \"!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/UserMatthew.js",
    "content": "//# #00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n\n// #1 URL del sitio oficinal del lenguaje https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// #2 Comentario de una unica linea (Se realiza con \"//\" al inicio)\n\n/*\n    Comentarios en multiples lineas\n    Se realizan con \"/*\" al inicio y \"* /\" al final\n*/\n\n// #3 Crea una variable (y una constante si el lenguaje lo soporta).\n\n// ---- Variable -----\n\nlet nombreLenguaje = \"JavaScript\";\nvar Cliente\n\n// ---- Constante -----\n\nconst VersionLenguaje = \"ECMAScript 13\";\n\n// #4 Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n\n// ---- String ----- Representa una cadena de texto.\n\nlet string = \"Hello, world!\";\nlet nombre = \"UserMatthew\"\n\n// ---- Number ----- Representa un número.\n\nlet number = \"27\"\n\n// ---- Boolean ----- Representa un valor booleano (Verdadero o falso)\n\nlet boolean = true\n\n// ---- Null ----- Representa un valor nulo.\n\nlet nullVariable = null\n\n// ---- Undefined ----- Representa un valor indefinido.\n\nlet undefinedVariable \n\n// ---- Symbol ----- Representa un identificador único.\n\nlet symbolVariable = Symbol(\"Unique\");\n\n// ---- BigInt ---- Representa un número entero de gran tamaño.\n\nlet bigIntVariable = 1234567890123456789012345678901234567890\n\n// Imprime por terminal \n\nconsole.log(`${string}, Mi nombre es ${nombre} y esto es ${nombreLenguaje}!`); \n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Uyarra73.js",
    "content": "// La pagina oficial de JavaScript es la siguiente: https://www.javascript.com/  \n\n// Este es un comentario de una sola linea \n\n/* Este es un comentario \nde varias lineas */\n\n// Diferentes tipos de variables\n\n// Variables en JavaScript (su valor se puede reasignar):\n\nvar name = \"Nombre\";\nlet age = 49;\n\n// Constantes en JavaScript (su valor es inmutable):\n\nconst PI = 3.1416;\n\n// Tipos de datos primitivos en JavaScript:\n\n// String: Representa una cadena de texto.\n\nlet palabra = \"miercoles\";\n\n// Number: Representa un número.\n\nlet numero = 12345;\n\n// Boolean: Representa un valor booleano.\n\nlet festivo = true;\n\n// Null: Representa un valor nulo.\n\nlet nada = null;\n\n// Undefined: Representa un valor indefinido.\n\nlet desconocido;\n\n// Symbol: Representa un identificador único.\n\nlet simbolo = Symbol();\n\n// BigInt: Representa un número entero de gran tamaño\n\nlet numeroGrande = 1234567890123456789012345678901234567890n;\n\n// Imprimir por consola\n\nconsole.log(\"Hola, JavaScript\");\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/VictorSschz.js",
    "content": "//www.javascript.com\n/**Esta es una manera\n * de representar comentarios en varias lineas\n */\n\nconst num= 1;\nlet num2 = 2;\nlet decimal = 5.5;\nconst verdadero = true;\nconst falso = false;\nlet indefinido;\nconst sinValor = null;\nlet noDef= NaN;\n\nconsole.log('Hola, Javascript')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Vixito.js",
    "content": "// https://developer.mozilla.org/es/docs/Web/JavaScript\n/* Comentario\ncon muchas\nlíneas */\n\nvar zzz;\nconst uno = undefined; // Indefinido\n\nlet dos = 'Hola'; // String\nlet tres = 3; // Entero\nlet cuatro = 4.0; // Float\nlet boolean = true; // Boolean\nlet a = null; // null\n\nconsole.log(\"¡Hola, JavaScript!\");\nconsole.log(uno); // Para ejecutar el const inicializado y no causar errores xD."
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/VolumiDev.js",
    "content": "\n/*\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n\n\n//✅Pagina web del lenguaje. https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// ✅Este es un comentario en unas sola linea\n\n/**\n * ✅Este es un comentario en varias lineas\n * como puedes ver \n * estan en 3 lineas\n */\n\n// ✅una variable tipo string\nvar lenguaje = 'Java Script'\n// ✅una constante tipo number, con coma flotante\nconst pi = 3.14\n// ✅variable de tipo  number, pero entero\nvar entero = 34\n// ✅varialbe de tipo boolean \nvar flag = true\n// ✅variable de tipo BigInt\nvar granEntero = 12391239182938917785676283904n\n// ✅variable de tipo null\nvar vacio = null\n// ✅ variablede tipo symbol\nvar sym = Symbol();\n\nconsole.log(`Hola, ${lenguaje}`)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/YessikaMichelle.js",
    "content": "// https://developer.mozilla.org/es/docs/Web/JavaScript \n\n// this is a one line comment\n\n/* this a multiple line comment\nbla bla bla\n*/\n\n// tipos de datos primitivos\n\n// undefined\nvar variable1;\n\n// boolean\nlet bolean1 = true;\n\n// number\nconst PI = 3.1416;\n\n// string\nlet str1 = \"¿me voy a ganar un choco por esto?\";\n\n// bigint\nlet bigint1 = 1234567890123456789012345678901234567890;\n\n//symbol\nlet symbol1 = Symbol(\"Miau\");\n\n//mensaje en consola\nconsole.log(\"¡Hola, javascript!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/YgriegaSB.js",
    "content": "// https://developer.mozilla.org/en-US/docs/Web/JavaScript\n// https://262.ecma-international.org/#sec-intro\n\n/*\n    Comentario multiples lineas\n    1\n    2\n    3\n*/\n\nconst myLenguage = \"JavaScript\";\n\n// Constante y variable\nconst cantChange = 10;\nlet canChange2 = 10;\n\n// Datos primitivos en JavaScript\n\n// Números (Number)\nlet numero = 42;\nlet decimal = 3.14;\n\n// Cadenas de texto (String)\nlet cadena = \"Hola, mundo!\";\nlet otraCadena = 'Esto es una cadena';\n\n// Booleanos (Boolean)\nlet verdadero = true;\nlet falso = false;\n\n// Valores nulos (Null) y sin definir (Undefined)\nlet nulo = null;\nlet indefinido = undefined;\n\n// Símbolos (Symbol) (nuevo en ECMAScript 2015)\nlet simbolo = Symbol(\"descripción\");\n\nconsole.log(`Hola ${myLenguage}`);"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Younes0-0.js",
    "content": "//Documentación: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Comentario en una línea \n\n/*\n  Comentario \n  en \n  varias \n  líneas\n*/\n\n// Variables \n\n// Declara una variable, opcionalmente la inicia a un valor\nvar variable\n\n// Declara una variable local con ámbito de bloque, opcionalmente la inicia a un valor.\nlet local\n\n// Declara un nombre de constante de solo lectura, ámbito de bloque y tiene que inicializarse \nconst CONSTANTE = Math.PI\n\n// Los tipos de datos primitivos\n\n// String -> Cadena de texto\nconst string = \"Hola mundo\"\nconst simple = 'Hola mundo'\nconst especial = `Hola mundo`\n\n// Number \nconst number = 123\nconst decimales = 1.5\nconst scientificNotation = 25e105\n\n// BigInt -> es un tipo de dato introducido en JavaScript para representar números enteros de tamaño arbitrario. \n// Es útil para realizar operaciones matemáticas con números que superen los límites máximos y mínimos permitidos por JavaScript\n// Para crearlo se añade un \"n\" al final \nconst bigInt = 123n\nconst numeroNormal = 9000000000000000000111     // -> 9e+21 perdemos valor \nconst numeroBigInt = 9000000000000000000111n   // -> No pierde valor 9000000000000000000111n\n\n//Boolean \nlet boolean = true\nboolean = false\n\n//Undefined -> indica que una variable no tiene un valor asignado\nlet sinValor  \n\n//Symbol -> Identificadores que son únicos \nconst sym1 = Symbol()\n\n//Null -> indica que una variable tiene un valor nulo\nconst nulo = null\n\nconsole.log(\"Hola JavaScript\",scientificNotation)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/Zunigaj1101.js",
    "content": "// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Esto es un comentario en una sola linea\n\n/* Esto \nes \nun\ncomnetario \nen \nvaria\nlineas\n*/\n\nvar myVar = 'Hola'\nlet myLet = 'Mundo'\nconst myConst = 'JavaScript'\n\nlet myNumber = 1\nlet myText = 'texto'\nlet myFloat = 1.23\nlet myBooleanTrue = true\nlet myBooleanFalse = false\nlet myNan = NaN\nlet myNull = null\nlet myUndefined = undefined\nlet mySymbol = Symbol('simbolo')\n\nconsole.log (`${myVar} ${myLet} estoy usando ${myConst}`)   "
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/a-mayans.js",
    "content": "// Documentación oficial de JavaScript --> https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Comentario en una linea\n\n/* \nAsi podemos introducir\nvarias lineas de comentario\n*/\n\n// Declarar una variable\nlet nombre = 'Alejandro';\n// Declarar una constante\nconst PI = 3.14;\n\n// Tipos de datos primitivos\n// STRING\nlet cadena = 'Hola, amigos';\n// NUMBER\nlet un_integer = 27;\nlet un_float = 27.27; // un decimal\n// BIGINT\nlet num_grande = 2727272727272727n;\n// NULL\nlet un_null = null;\n// UNDEFINED\nlet un_undefined = undefined;\n// SYMBOL\nlet un_simbolo = Symbol('Nuevo simbolo');\n\n// Imprimir saludo\nlet lenguaje = 'Javascript';\nconsole.log(`¡Hola, ${lenguaje}!`);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/aarxnmendez.js",
    "content": "// https://developer.mozilla.org/es/docs/Web/JavaScript\r\n\r\n// Comentario una linea\r\n\r\n/*\r\nComentario\r\nvarias\r\nlineas\r\n*/\r\n\r\n// Declarar una variable\r\nvar var1;\r\nlet var2;\r\n// Declarar una constante\r\nconst CONSTANTE = \"constante\";\r\n\r\n\r\n// Tipos datos primitivos\r\n// STRING\r\nlet cadena = \"comillas dobles\";\r\nlet cadena2 = 'comillas simples'\r\n// NUMBER\r\nlet numEntero = 1;\r\nlet numDecimal = 0.1;\r\n// BOOLEAN\r\nlet booleano = true;\r\n// UNDEFINED\r\nlet noDefinida;\r\n// NULL\r\nlet y = null;\r\n// SYMBOL\r\nlet sym = Symbol('descripcion');\r\n// BIGINT\r\nlet big = 1234567890123456789012345678901234567890n;\r\n\r\n// Imprimir saludo por terminal\r\nconsole.log(\"¡Hola, JavaScript!\");\r\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/abengl.js",
    "content": "//Ejercicio 00\n\n//1- Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n//https://developer.mozilla.org/es/docs/Web/JavaScript\n\n//2- Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n\n//JavaScript (JS) es un lenguaje de programación ligero, interpretado, o compilado justo-a-tiempo.\n\n/*\n    Si bien es más conocido como un lenguaje de scripting (secuencias de comandos) para páginas web, y es usado en muchos entornos fuera del navegador, tal como Node.js, Apache CouchDB y Adobe Acrobat JavaScript es un lenguaje de programación basada en prototipos, multiparadigma, de un solo hilo, dinámico, con soporte para programación orientada a objetos, imperativa y declarativa (por ejemplo programación funcional). Lee más en acerca de JavaScript.\n*/\n\n//3- Crea una variable (y una constante si el lenguaje lo soporta).\nlet counter = 0;    //Variable\nconst PI = 3.1415;  //Constante\n\n//4- Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\nconst text = \"Hello\";    //string\nconst interestRate = 5.3;  //number\nconst population = 149_597_870_700n //bigint\nconst status = true;    //boolean\nlet sum;    //undefined\nconst userID = Symbol(\"id\");    //symbol\nconst array = null;     //null\n\n//5- Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nconsole.log(\"¡Hola, JavaScript!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/adant11235.js",
    "content": "// comentario de una linea\n\n// Web oficial https://ecma-international.org/publications-and-standards/standards/ecma-262/\n\n/* Comentario\n    en multiples\n      lineas\n*/\n\n/*\notra web \n\nhttps://developer.mozilla.org/es/docs/Web/JavaScript\n\n*/\n\nlet myVariable = \"variable\";\n\nconst myConst = \"costante\";\n\nconsole.log(myVariable);\nconsole.log(myConst);\n\n//Integer\nlet numero = 1;\nconsole.log(typeof numero);\n\n//bigInt\nlet bigNumero = BigInt(222544343533131315);\nconsole.log(typeof bigNumero);\n\n//Float\nlet numDec = 1.5;\nconsole.log(typeof numDec);\n\n//String\nlet texto = \"Javascript\";\nconsole.log(typeof texto);\n\n//Booleans\nlet boo = true;\nlet boo2 = false;\nconsole.log(typeof boo,typeof boo2);\n\n//null\nlet nul = null;\nconsole.log(typeof nul);\n\n//undefined\nlet unkn = undefined;\nconsole.log(typeof unkn);\n\nlet sym = Symbol();\nconsole.log(sym);\n\n\n\nconsole.log(`hola ${texto}`);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/adrs1166ma.js",
    "content": "/*\nEJERCICIO:\n- Crea un comentario en el código y coloca la URL del sitio web oficial del\n  lenguaje de programación que has seleccionado.\n- Representa las diferentes sintaxis que existen de crear comentarios\n  en el lenguaje (en una línea, varias...).\n- Crea una variable (y una constante si el lenguaje lo soporta).\n- Crea variables representando todos los tipos de datos primitivos\n  del lenguaje (cadenas de texto, enteros, booleanos...).\n- Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n */\n\n\n// 🔥 sitio web oficial:  https://js.org/index.html\n// Documentacion:  https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// 🔥 Una linea\n\n/* 🔥 Varias\n    Lineas\n*/\n\n\n// 🔥 Variables\nlet uno = \"one\" // let \nvar dos = \"two\" // var\nconst tres = \"three\" // const\n\n\nlet hola = \"hola\" // siempre inicia con un caracter normal\n\nlet saludo // el valor es undefined\nsaludo = \"Hola, que tal?\" // asignar valor a la variable\n\nvar hello = \"hello\" // no recomendable y no es muy usado\n\nconst hi = \"hi\" // siempre se debe asignar la constante inicialmente\n\n\n// 🔥 Tipos de datos\n\nconst nombre = \"javascript\" // String\nconsole.log(typeof nombre)\n\nconst precio = 100 // number\nconst precio1 = 10.40 // number\nconst precio2 = -100 // number\nconst precio3 = \"100\" // String\nconst precio4 = '100' // String\n\n\nconst activo = false // boolean\n\nconst cliente = null // null\nlet cliente1 // undefined\n\nconst numeroGigante = BigInt(12345678912345678902345678)\nconsole.log(typeof numeroGigante) // bigint\n\n\n// 🔥 Saludo al lenguaje \nconsole.log(\"¡Hola,\" + nombre +\"!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/afl0r3s.js",
    "content": "//Documentacion oficial de JavaScript ->\n//  -> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide\n//  -> https://javascript.info/\n\n// Ejemplo de comentario en una linea\n\n/*\nEjemplo de comentario \nen varias lineas\n*/\n\n//Declarar variables (metodo no recomendado)\nvar variable1 = 'Hola';\n//Declarar variables (metodo si recomendado)\nlet variable2 = 'Hola mundo..';\n//Declarar constantes\nconst variable3 = 'Esto no se podra modificar despues';\n\n//Tipos de Datos Primitivos\n//-- String >>\nlet cadena = 'Cadena de texto de cualquier longitud';\n//-- Number >>\nlet numero1 = 5;\nlet numero2 = 6.77;\n//-- BitInt (numeros muy grandes) >>\nlet numeroGrande1 = 1234567890123456789012345n;\nlet numeroGrande2 = BigInt(1234567890123456789012345);\n//-- Boolean >>\nlet booleano1 = true;\nlet booleano2 = false;\n//-- Undefined >>\nlet noDefinido = undefined;\n//-- Symbol >>\nlet simbolo = Symbol('algo');\n//-- Null >>\nlet nulo = null;\n\n//Imprimir mensajes usando la consola del lenguaje\nconsole.log('¡Hola, JavaScript!');\n//Imprimir mensajes usando texto y valor de variables\nlet lenguaje = 'JavaScript';\nconsole.log(`¡Hola, ${lenguaje}!`);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/agusrosero.js",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Comentario de una linea\n\n/*\nComentario\nde \nvarias lineas\n*/\n\nlet miVariable = \"Hola, soy una variable\";\nconst miConstante = \"Hola, soy una constante\";\n\nlet cadena = \"Hola\";\nlet numero = 42;\nlet nulo = null;\nlet indefinido = undefined;\nlet booleano = true;\n\nlet lenguaje = \"Javascript\";\nconsole.log(`¡Hola, ${lenguaje}!`);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/ahinar.js",
    "content": "/*Crea un comentario en el código\r\n y coloca la URL del sitio web oficial del  lenguaje de programación que has seleccionado.*/\r\n\r\n// La pagina que se acerca mas a ser la oficial es https://developer.mozilla.org/en-US/\r\n\r\n//- Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\r\n\r\n// este es un comentario de una linea\r\n\r\n/* Este es\r\nun comentario\r\nmultilinea*/\r\n\r\n//- Crea una variable (y una constante si el lenguaje lo soporta).\r\n\r\nlet var1 = \"variable\";\r\nconst var2 = \"Constante\";\r\n\r\n/*- Crea variables representando todos los tipos de datos primitivos\r\ndel lenguaje (cadenas de texto, enteros, booleanos...).*/\r\n\r\n//variables tipo numero\r\nlet entero = 1452; //numero entero\r\nlet float = 3.15; //float\r\n\r\nlet cadena = \"esto es un string\";// tipo string\r\n\r\nlet boolTrue = true; //booleanos\r\nlet boolFalse = false;\r\n\r\n//- Imprime por terminal el texto: \"¡Hola, Javascript!\"\r\nconsole.log(\"¡Hola; javascript!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/aidicoop.js",
    "content": "// EJERCICIO:\n// * - Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n// * - Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n// * - Crea una variable (y una constante si el lenguaje lo soporta).\n// * - Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n// * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\n\n// https://www.javascript.com/ | https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Una linea\n\n/*\nLinea 1\nLinea 2\nLinea 3 \n*/\n\nvar hola = \"hola\";\n\nvar number = 1;\nvar boolean = 1.2;\nvar text = \"Hola\";\nvar list = [\"Hola\", 1, \"Bye\", 1.2];\n\nvar lenguaje = \"Javascript\";\n\nconsole.log(`¡Hola, ${lenguaje}!`);\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/akaidmaru.js",
    "content": "// https://developer.mozilla.org/en-US/docs/Web/javascript\n\n// Esto es un comentario en Javascript\n\n/*\n    Esto también es un comentario, pero\n    en múltiples líneas.\n*/\n\n// Esto es una variable\nlet variable = \"Soy una variable.\";\nconst CONSTANTE = \"Soy una constante.\";\n\nlet stringVar = \"Soy un String.\";\nlet integerVar = 230;\nlet bigIntegerVar = BigInt(\"12345678901234567890\");\nlet floatVar = 0.23;\nlet booleanVar = true;\nlet undefinedVar;\nlet symbolVar = Symbol(\"Redd\");\n\nconsole.log(\"¡Hola, Javascript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/aleclto7.js",
    "content": "// Sitio Web Oficial JavaScript: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Sintaxis para crear comantarios\n// Este es un comentario en una linea\n/* Este es \nun comentario \nen multilinea */\n\n// Variable y Constante\nconst nombre = 'Alexis'\nlet edad = 23\n\n// Variables con diferentes tipos de datos primitivos\nlet string = 'Esta es una cadena de texto'\n\nlet numero_entero = 10\nlet numero_decimal = 10.5\n\nlet boolean1 = true\nlet boolean2 = false\n\nlet tipo_null = null\n\nlet tipo_undefineds = undefined\n\nlet simbol = Symbol.for('key')\n\n// Imprime en consola\nconsole.log('Hola JavaScript!');\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/alexdevrep.js",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n//https://www.javascript.com/\n\n//así puedo escribir un comentario en una línea\n\n/*\nasi \npuedo\nescribir\ncomentarios \nmultilinea\n*/\n\n// así creo una variable\n\nlet UnaVariable = \"soy una variable tipo string\";\n\n// asi creo una constante\n\nconst UNACONSTANTE = \"soy una cosntante tipo string\";\n\n// Estos son los distintos tipos de datos disponibles en JavaScript\n\n// Datos primitivos (aquellos que no son un objeto y no tiene métodos)\n\n//Número entero\nlet numero = 18\n\n//Números decimales floats\nlet float = 3.14\n\n//Cadena de texto\nlet srting = \"Esto es una cadena de texto\"\n\n//Valor booleano\nlet booleanos = true\n\n//Valor nulo o vacío\nlet nullValue = null\n\n// una variable sin valor\nlet undefined\n\n//Crear propiedades privadas de forma única\nlet symbol = Symbol (\"mySymbol\")\n\n//Para números enteros muy grandes\nlet bigint = 485704087244087658n\n\n//Hacemos nuestro primer Hola Mundo!\n\nconsole.log(\"Hola, JavaScript.\")\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/alexsamboy.js",
    "content": "// https://developer.mozilla.org/es/docs/Learn/JavaScript\n\n// Este es un comentario de una linea\n/*\nEste es\nel comentario\nmultilínea.\n */\n\nvar miNombre = 'Manuel';\nlet miApellido = \"Pérez\";\nconst esConstante = \"Esta es una constante\";\n\n// Datos primitivos\n\nlet varIndefinida = undefined;\nlet varBooleana = false;\nvarBooleana = true;\nlet varNumero = 50;\nlet varString = \"Cadena de texto\";\nlet varBigInt = 9007199254740992n;\nlet varNull = null;\nlet varSymbol = Symbol('Symbol');\nlet varObject = new Object();\n\n//Imprimir en consola\nconsole.log(\"¡Hola, Javascript!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/alvarommedia.js",
    "content": "'use strict'\n\n//\"https://developer.mozilla.org/es/docs/Web/JavaScript\"\n\n// Esto es un comentario de una sola linea\n\n/**Esto es un comentrio\n * multilinea\n * en JavaScript \n */\n\nlet miPrimeraVariable = \"Hola Mundo\"\nconst miPrimeraConstante = \"Hola Mundo\"\n\nlet integer = 10;\nlet float = 10.10;\nlet string = \"Hola Brais Moure\";\nlet bool = true;\nlet array = [10, 'Bob', true, 10.10];\nlet object = document.querySelector('h1');\n\nconsole.log(\"¡Hola, JavaScript!\")\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/andresgcastillo.js",
    "content": "// #00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n//https://www.javascript.com/\n\n// Comentario de una linea\n\n/*\n    Comentario\n    de\n    varias\n    lineas\n\n*/\n\nlet variable = \"Hola Mundo!\";\nconst constant = \"Hello Mundo!\";\n\nlet number = 23;\nlet bigint = 9876543219876543210;\nlet string = \"hello\";\nlet boolean = false;\nlet decimal = 3.14;\nvar undefinedValue = undefined;\nlet symbol = symbol(\"nuevoSimbolo\");\n\nconsole.log(\"¡Hola Javascript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/andyfg0289.js",
    "content": "/* \nEJERCICIO:\n * 1- Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * 2- Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * 3- Crea una variable (y una constante si el lenguaje lo soporta).\n * 4- Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * 5- Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *  */\n\n//  1- Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n\n// https://www.javascript.com/\n\n//___________________________//\n\n// 2- Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n\n// Comentario en una sola linea\n\n/* \nComentario de \nmultiples lineas\n*/\n\n//___________________________//\n\n// 3- Crea una variable (y una constante si el lenguaje lo soporta).\n\nlet edad = 35;\n\nconst nombre = \"andy\";\n\n//___________________________//\n\n//4- Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n\n// 1) Number\n\nlet entero = 12;\nlet flotante = 5.14;\n\n// 2) String\n\nlet objeto = \"carro\";\nlet color = 'rojo';\nlet plantilla = `El ${objeto} es ${color}`;\nconsole.log(plantilla); // El carro es rojo\n\n// 3) Boolean\n\nlet verdadero = true;\nlet falso = false;\n\n// 4) Undefined\n\nlet fruta; \n\nconsole.log(fruta)//undefined\n\n// 5) Null\n\nlet nulo = null;\n\n//6) Symbol \n\nlet simbolo = Symbol('datos');\n\n// 7) BigInt\n\nlet bigboy = BigInt(345234623563245623562362346234652354623546);\n\nlet bigGirl = 5234562346234623456234562345623465234n;\n\n// 5 - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\nconsole.log(\"!hola, JavaScript\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/angelsanchezt.js",
    "content": "// Sitio web oficial de JavaScript: \n//      https://developer.mozilla.org/es/docs/Web/JavaScript\n//      https://ecma-international.org/technical-committees/tc39/\n\n// Comentario de una línea\n\n/*\n   Comentario\n   Multilínea\n*/\n\n/*\n   OPCIONAL: Proceso de Ejecución del Script de javascript\n   1. Ve al sitio web oficial de Node.js: https://nodejs.org/.\n   2. Descarga el instalador para Windows.\n   3. Ejecuta el instalador y sigue las instrucciones para completar la instalación.\n   4. Verificación de instalación: \n      node -v\n   5. Buscar la carpeta de javascript: \n      cd roadmap-retos-programacion\\Roadmap\\00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\\JavaScript\n   6. Ejecutar el siguiente comando: \n      node angelsanchezt.js      \n*/\n\n// Creación de variables\nlet variable = \"Hola, soy una variable\";\nconst constante = \"Hola, soy una constante\";\n\n// Tipos de datos primitivos\nlet booleano = true;\nlet numero = 42;\nlet cadena = \"Hola, soy una cadena\";\nlet nulo = null;\nlet indefinido;\nlet persona = {firstName: \"Sara\", lastName: \"sniker\"}; //object\nlet bigint = 11n //bigint\n\n// Imprimir por terminal\nconst lenguaje = 'JavaScript';\nconsole.log(`!Hola, ${lenguaje}`);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/angelurrutdev.js",
    "content": "// https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n// Formas de hacer comentarios en JavaScript\n\n// Comentario en linea\n\n/* Comentario \n    en Bloque\n*/\n\n\n/**\n * Comentario en bloque con asteriscos\n * \n */\n\n// Variable y Constante\nvar Variable = \"Hola\"\nconst ValorConstante = \"Mundo\"\n\n\n// Tipos de Datos:\nvar string = \"Hola Mundo\"\nvar string = 'Hola Mundo'\nvar number = 1\nvar nulo = null;\nvar indefinido = undefined;\nvar booleanoTrue = true;\nvar booleanoFalse = false;\n\nvar lenguaje = \"JavaScript\"\n\n//Imprimir en consola:\n\nconsole.log('!Hola JavaScript!')\n\n\n//Imprimir en consola con varible (Backstricks, se hacen con Alt + 96)\nconsole.log(`¡Hola, ${lenguaje}!`);"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/anjamape1972.js",
    "content": "// https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n// Comentario en una línea\n\n/*\nEsto es un\ncomentario en\nvarias líneas\n*/\n\nlet myVariable = 1;\nconst MY_CONSTANT = 22;\n\nlet myString = \"Hola\";\nlet myOtherString = `Hola`;\nlet myNumber = 33;\nlet myBigInt = 9007199254740991n;\nlet myBoolean = true;\nlet myUndefined;\nlet myNull = null;\n\nconsole.log (\"¡Hola, Javascript!\");\n\nconsole.log (typeof (myString));\nconsole.log (typeof (myOtherString));\nconsole.log (typeof (myNumber));\nconsole.log (typeof (myBigInt));\nconsole.log (typeof (myBoolean));\nconsole.log (typeof (myUndefined));\nconsole.log (typeof (myNull));"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/ant000o.js",
    "content": "// Sitio web documentación JavaScript: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Comentario de una linea\n\n/* \nComentario \nde \nvarias \nlineas \n*/\n\n// Crea una variable y constante\nlet variable = \"hola\";\nconst constante = \"mundo\";\n\n// Crea variables representando todos los tipos de datos primitivos\nlet myNumber = 21;\nlet myString = \"ant000o\";\nlet myBoolean = true;\nlet myUndefined;\nlet myNull = null;\nlet mySymbol = Symbol('mySymbol');\nlet myBigInt = 12312312423412243124343242342321n;\n\n//Print\nconsole.log('¡Hola, JavaScript!');"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/anto-dasein.js",
    "content": "// Sitio oficial del Lenguaje JavaScript https://www.javascript.com/ -> Documentación: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// ¡He elegido Javascript!\n\n\n// De esta forma se hace un comentario en una línea\n\n\n/* De esta otra forma se puede hacer un \n\ncomentario en varias líneas */\n\n//Variables\n\nlet numero = 10; // Constante\nconst nombre = Antonio; // Variable let, acaba por sustituir a la variable var\n\n \n\n// Tipos de datos primitivos\n\n\nlet number = 20; // Tipo de dato number\nlet String = \"Hola qué tal\"; // Tipo de dato String o cadena de texto\nlet boolean = true;\nlet undefined = undefined;\nlet simbolo = Symbol(\"hey!\"); \nlet bigint = 123456789905660n; // Tipo de dato Bigint\nlet nulo = null; // Tipo de dato null\n\n\n// Print por pantalla\n\nconsole.log(\"¡Hola, JavaScript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/antonioclaros93.js",
    "content": "// https://www.javascript.com/ -- Comentario de una línea\n/* Comentarios de Varias líneas\nen JavaScript*/\n\nconst nombre = \"Antonio\"; // Constante\nlet apellido = \"Claros\";    // Variable string\nlet edad = 30;       // Variable Numérica\nlet esEstudiante = true;        // Variable Booleana\nlet x = null;  // Variable nula\nlet z = undefined;   // Variable indefinida\nlet simbolo = Symbol(\"mi simbolo\");  // Variable simbolo\nlet numeroGrande = BigInt(1234567890123456789012345678901234567890n);  // Variable BigInt\n\n\n\nconsole.log(\"Hola, Javascript!\"); // Imprime en consola\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/antonioverdugo.js",
    "content": "// Lenguaje javascript \n// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n//Comentario en una linea\n\n/*\nComentario en varias\nlineas\n*/\n\n//Variable\n\nlet variable = \"hola mundo desde let\"; //Recomendable utilizar let para las variables\nvar variable2 = \"hola mundo desde var\"; //var es menos recomendable la diferencia es que var es mas global\n\n//Constante\n\nconst constante = \"Antonio\"; \n\n//Tipos de datos primitivos\n\nlet cadena = \"Esto es una cadena\"; //Tipo primitivo String\nlet numero = 23.5; //Tipo primitivo Number pueden ser enteros o decimales\nlet bigint = 123456789905660n; //Tipo de dato Bigint\nlet booleano = true; //Tipo primitivo Boolean\nlet simbolo = Symbol(\"hola\"); //Tipo primitivo Symbol\nlet indefinido = undefined; //Tipo de dato undefined\nlet nulo = null; //Tipo de dato null\n\n//Imprimir por pantalla\nconsole.log(\"¡Hola, javascript!\");\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/arbenisacosta.js",
    "content": "// 00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n\n/*\n  EJERCICIO:\n  - Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n  - Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n  - Crea una variable (y una constante si el lenguaje lo soporta).\n  - Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n  - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n*/\n\n/* --------------------------------*/\n\n// - Sitio oficial del lenguaje Javascript: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n/* - Comentarios */\n\n// Comentario de una sola línea\n\n/*\n  Un comentario\n  que se extiende\n  en varias\n  líneas\n*/\n\n// - Variable y constantes\n\nlet variable = 1;\nconst constante = 2;\n\n// - Datos primitivos\n\nlet miUndefined; // undefined: Un valor primitivo automáticamente asignado a las variables que solo han sido declarados o a los argumentos formales para los cuales no existe argumentos reales.\n\nlet miBoolean = false // Boolean: En ciencias de informática, un boolean es un dato lógico que solo puede tener los valores true o false.\n\nlet miNumber = 7 //Number: es un tipo de datos numérico\n\nlet miString = \"Hola Mundo\" // String: En cualquier lenguaje de programación, un string es una secuencia de caracteres usado para representar el texto.\n\nlet miBigInt = 777n //BigInt: En JavaScript, BigInt es un tipo de dato numerico que puede representar números enteros en el formato de precision arbitrario. En otros lenguajes de programación pueden existir diferentes tipos numéricos, por ejemplo: enteros, flotantes, dobles o bignums (numeros grandes).\n\nlet miSimbol = Symbol(\"key\") // Symbol: es un tipo de datos cuyos valores son únicos e immutables. Dichos valores pueden ser utilizados como identificadores (claves) de las propiedades de los objetos.\n\n// - Imprimir por pantalla\n\nconsole.log(\"¡Hola, javascript!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/asaelz.js",
    "content": "/**\n * * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n */\n\n// SITIO OFICIAL -> https://developer.mozilla.org/es/docs/Web/JavaScript\n/**\n * ESTO ES UN COMENTARIO MULTILINEAS \n * :D\n */\n// comentario de una linea \nlet user = \"asaelz\"\nconst lenguaje = \"JS\"\n\n/**\n * PRIMITIVOS\n */\nlet PrimitivoString = \"Valor de texto\"\nlet Number = 13\nlet PBigInt = 23n\nlet booleano = true\nlet Undf = undefined\nlet simbolo = Symbol(42)\n\n\n//🤟🤟\nconsole.log(\"¡Hola, JavaScript 🤟🤟!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/bebebo79.js",
    "content": "// https://lenguajejs.com/javascript/\n\n\n// comentario de una sola linea\n\n/****\n * comentario de varias lineas\n * de codigo si es necesario\n * \n */\n\nlet medida = 'litros';\nconst nombre = 'beatriz';\n\nconst tiposDeDatos = ['string', 'number', 'boolean']\n\nconst lenguaje = 'javascript'\n\nconst res = `!Hola ${lenguaje}`\n\nconsole.log(res)\n   "
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/beccaribenjamin.js",
    "content": "// * EJERCICIO:\n//  * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n//  *   lenguaje de programación que has seleccionado.\n\n// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n\n//  * - Representa las diferentes sintaxis que existen de crear comentarios\n//  *   en el lenguaje (en una línea, varias...).\n\n\n\n// Comentarios de una sola linea → //\n\n/*\n    Comentarios\n    De \n    Mas de\n    Una\n    Linea\n\n*/\n\n\n//  * - Crea una variable (y una constante si el lenguaje lo soporta).\n\nlet variable = \"Hola Mundo\";\nconst constantes = \"Esto es una constante\";\n\n//  * - Crea variables representando todos los tipos de datos primitivos\n//  *   del lenguaje (cadenas de texto, enteros, booleanos...).\n\nlet cadena = \"Esto es una cadena o string\";\nlet numeros = 45;\nlet booleanos = true;\nlet nulo  = null;\nlet indefinido;\n\n//  * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\nlet lenguaje = \"JavaScript\"\nconsole.log(`¡Hola, ${lenguaje}!`)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/bernatcs.js",
    "content": "// -1-\n\n// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// -2-\n\n// Comentario en una línea\n\n/* Comentario\nen\nvarias\nlineas */\n\n// -3-\n\nvar miVariable = 'Esto es una variable'\nconst miConstante = 'Esto es una constante'\n\n// -4-\n\nvar stringVariable = 'Esto es una variable con texto'\nvar stringVariable2 = \"Esto es una variable con texto\"\nvar stringVariable3 = `Esto es una variable con texto`\n//console.log(typeof(stringVariable))\n\nvar numberVariable = 1\nvar numberVariable2 = NaN\n//console.log(typeof(numberVariable))\n\nvar boolVariable = true\n//console.log(typeof(boolVariable))\n\nvar objectVariable = [1, 2, 3, 4] // Aunque es un Array\nvar objectVariable2 = {\n    Nombre: 'Bernat',\n    Apellido: 'Cucarella',\n}\n//console.log(typeof(objectVariable))\n\n// -5-\nlet nombreLenguaje = 'JavaScript'\nconsole.log(\"¡Hola, \" + nombreLenguaje + \"!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/bladi23.js",
    "content": "// URL DEL SITIO WEB OFICIAL DE JAVASCRIPT -- https://developer.mozilla.org/es/docs/Web/JavaScript\n// En JavaScript se puede comentar con // en una sola linea y con /* en varias lineas y */ para cerrar el comentario\n// Crear una variable \nlet nombre = \"Juan\";\n// Crear una constante\nconst apellido = \"Perez\"; \n// Crear variables con todos los tipos de datos primitivos\nconst string = \"Hola\";\nconst number = 10;\nconst boolean = true;\nconst nullValue = null;\nconst undefinedValue = undefined;\nconst symbol = Symbol(\"symbol\");\nconst bigint = BigInt(10);\n\nconsole.log(\"Hola, JavaScript\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/blancowilson.js",
    "content": "/* Pagina Oficial https://developer.mozilla.org/es/docs/Web/JavaScript */\n\nlet cadena = \"String\"\nlet number = 30\nlet bool = true\nlet nothing = null\nlet array = [1, 2, 3, 4];\nconst PI = 3.1416\nlet lenguaje = \"JavaScript\"\n\nlet objeto = {\n    name:\"Wilson\",\n    edad: 41\n}\n\nconsole.log(\"variable tipo string\",cadena)\nconsole.warn(\"variable tipo numerico\",number)\nconsole.log(\"variable tipo booleana\",bool)\nconsole.log(\"variable tipo null\",nothing)\nconsole.log(\"variable tipo array\",array)\n\nconsole.log(\"Objeto\", objeto)\n\nconsole.log('Hola', lenguaje)\n\n\n\n\n//Comentario de una linea\n\n/* Esto es \nun comentario\nde Varias Linea\n*/\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/bmayo08.js",
    "content": "/* Pagina Oficial https://developer.mozilla.org/es/docs/Web/JavaScript */\n\n// comentario de una linea\n/* comentario\nde varias\nleneas*/\n\nlet variable= \"mi variable\"\nconst variable_conts= \"variable constante\"\n\nlet entero= 2\nlet float= 2.3\nlet booleanTrue= true\nlet bolleanFalse= false\nlet string= \"cadena de texto\"\n\nlet lenguaje =\"javascript\"\nconsole.log(`hola ${lenguaje}`)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/carlosdiaz-dev.js",
    "content": "// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Sintaxis de comentario para una sola línea \n\n/* Sintaxis de \ncomentario para \nvarias líneas \n(bloque de código)*/\n\n//Variables y constantes JS\nvar nombre = 'Carlos';\nlet edad = 32; // Disponible sólo dentro del bloque en que se decla\nconst lenguaje = 'JavaScript'; // Su valor no cambia una vez asignado\n\n// Datos primitivos JS\n// undefined: Variable sin valor asignado\nlet a;\n// null: Objeto sin valor\nlet b = null;\n// boolean: Valor lógico 1|0\nlet c = true;\nlet d = false;\n// number: Valor numérico enteros y flotantes. Valores especiales infinity, NaN (Not a Number)\nlet e = 32;\nlet f = 3.14\nlet g = Infinity;\nlet h = NaN;\n// string: Cadena de caracteres, admite \"\", '', ´´\nlet i = 'Esto es un string';\n// symbol: Valor único, identificadores únicos para propiedades de objetos\nlet j = Symbol('descripcion');\n// bigint: Enteros fuera del rango de number\nlet k = 123456778900009877765432346789000n;\n\nconsole.log('Hola, ' + lenguaje);"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/carlosguerra1997.js",
    "content": "// Official Webpage: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Line Comment\n\n/*\n  Multiline Comment\n*/\n\n/**\n * JSDoc Comment\n */\n\n// Variables\nvar name = 'Carlos'\nlet name = 'Carlos'\nconst name = 'Carlos'\n\n// Primitives\nlet numberValue = 50;\nlet stringValue = \"Hello World\";\nlet booleanValue = true;\nlet nullValue = null;\nlet undefinedValue;\nlet symbolValue = Symbol(\"Symbol\");\nlet bigIntValue = 1234567890123456789012345678901234567890n;\nlet objectValue = { name: 'Carlos', age: 27 }\nlet arrayValue = [1, 2, 3]\n\n// Printing log\nconst language = 'JavaScript'\nconsole.log(`Hello, ${language}`);"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/caterinarodriguezdev.js",
    "content": "// https://developer.mozilla.org/es/docs/Web/JavaScript\n/**\n * El sitio web oficial de Javascript es mdn\n */\nlet variable;\nconst constante = 0;\n\nconst string = '';\nconst number = 0;\nconst boolean = true;\nconst nulo = null;\nconst noDefinido = undefined;\nconst simbolo = Symbol('simbolo');\nconst bigint = 1234556559606854609863568n;\n\nconsole.log('Hola Javascript');"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/ceciliarava1.js",
    "content": "// 00-Javascript\n\n\n // Website: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n /*\n    What better than start learning Javascript\n    in Christmas? Merry Christmas and Happy New Year! \n    2026\n */\n\n// Data Types\nlet myString = 'Santa Claus'\nlet MY_CONST = 2026\nlet myNumber = 1\nlet myBoolean = True\n\nconsole.log('Hello Javascript!')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/cesar-ch.js",
    "content": "﻿// URL: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Esto es un comentario de una sola línea\n\n/*\n    Esto es un comentario \n    de varias líneas\n*/\n\n// Variable y contante\n\nlet miVariable = 2024\nconst miConstante = \"Javascript\"\n\n// Tipos de datos primitivos\n\nlet numero = 10;\nlet cadena = \"Hola mundo\";\nlet booleano = true;\nlet nulo = null;\nlet indefinido;\nlet symbol = Symbol(\"Mi simbolo\");\nlet bigInt = 1234567890123456789012345678901234567890n;\n\nconsole.log(`Hola, ${miConstante}`);"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/cesarocbu.js",
    "content": "//Documentación oficial JavaScript: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Comentario de una sola línea\n\n/*Comentario\nde varias\nlineas\n*/\n\n// Variable y constante\n\nvar variable1 = \"hola con var\"; //Actualmente var ya no se usa porque puede causar confusiones, como el Hoisting\nlet variable2 = \"hola con let\";\nconst variable3 = \"hola con const\";\n\nlet js = \"JavaScript\"\n\n//Variables representando todos los tipos de datos primitivos del lenguaje\n\nlet texto = \"hola\";\nlet numero = 10;\nlet booleano = true;\nlet nulo = null;\nlet symbol = Symbol(\"foo\");\nlet bigInt = 1234567890123456789012345678901234567890n;\nlet undef = undefined;\n\n//Imprimiendo en terminal\n\nconsole.log('Hola, ' + js + '!');"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/cgomezadolfo.js",
    "content": "// No hay sitio web oficial, lo mas cercano es https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Comentario de una linea \n\n/*Comentario de \nvarias \nlineas */\n//declaracion de variable y constante\nvar variableQueNoSeUsa = 1;\nlet variable = 2;\nconst constante= 3;\n\n//variables de datos primitivos\n\nlet numero = 123;\nlet string = 'JavaScript'\nlet boolean = true;\nlet nulo = null;\n\nconsole.log('Hola, '+ string);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/charlscrxs.js",
    "content": "//https://developer.mozilla.org/es/docs/Web/JavaScript\n\n\n// este es un comentario de una sola linea\n\n/**\n * este es un comentario\n * que contiene varias lineas\n * me gustan los tacos\n */\n\n//esto es una variable\n\nlet saludo = \"hola\"\n\n//esto es una constante\n\nconst lugar = \"mexico\"\n\n\n//tipos de datos primitivos\nlet numero = 1\nlet float = 2.4\nlet texto = \"holis\"\nlet nulo = null\nlet boolean = false\n\n\nconsole.log(\"hola javascript\")\n\n\nconsole.log(typeof numero)\nconsole.log(typeof float)\nconsole.log(typeof texto)\nconsole.log(typeof boolean)\nconsole.log(typeof nulo)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/christian-jfr.js",
    "content": "// #00 - Sintaxis, Variables, Tipos de datos y Hola mundo.\n\n/* \n1. Crea un comentario en el código y coloca la URL del sitio web oficial del \nlenguaje de programación que has seleccionado. \n*/\n\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n\n/* \n2. Representa las diferentes sintaxis que existen de crear comentarios \nen el lenguaje (en una línea, varias...).\n*/\n\n// Comentario de una línea\n\n/*\n    Comentario \n    de \n    varias \n    lineas    \n*/\n\n\n/*\n3. Crea una variable (y una constante si el lenguaje lo soporta).\n*/\n\nvar variableVar = 1;\nlet variableLet = 2;\nconst constante = 3;\n\n\n/*\n4. Crea variables representando todos los tipos de datos primitivos \ndel lenguaje (cadenas de texto, enteros, booleanos...).\n*/\n\n// String (cadenas de texto)\nconst nombre = 'Knives';\nconst mayor = \"18\";\nconst saludo = 'Hola mundo';\n// Number (enteros y decimales)\nconst pi = 3.1416;\nlet edad = 18;\n// BigInt\nconst numeroGrande = 1234567890123456789012345678901234567890n;\nlet numeroGrande2 = 10n;\n// Boolean\nconst booleano = true;\nlet booleano2 = false;\n// Null\nconst nulo = null;\n// Undefined\nconst indefinido = undefined;\nlet myIndefinido;\n// Symbol\nlet mySymbol = Symbol('clave');\n\n/*\n5. Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n*/\n\nconsole.log(`¡Hola, JavaScript!`)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/christianhernandezb.js",
    "content": "// URL: https://www.javascript.com/\n\n\n//Comentarios de una linea\n\n/*\nComentarios de linea multiple\n*/\n\n//variables\nlet numero = 1;\nconst numero2 = 2;\n\n//datos primitivos\n//variable de tipo indefinida\nconst variable1 = undefined;\n\n//variable de tipo nulo\nconst variable2 = null;\n\n//variable de tipo numero\nconst variable3 = 1;\n\n//variable de tipo caracter\nconst variable4 = 'string';\n\n//variable de tipo boolean\nconst variable5 = true;\n\nconsole.log('¡Hola, Javascript!');"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/christianumb.js",
    "content": "// https://www.javascript.com/ \n// Comentarios de una sola línea\n/* Comentarios de varias líneas\n*/\nlet a = 10\nconst b = 5\nlet c = \"Hola\" //String\nlet d = 5 //Number\nlet e = true //Boleano\nlet f = null //Nulo\nlet g = undefined\n\nconsole.log (\"¡Hola, JavaScript!\")\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/chriszaldana.js",
    "content": "//No hay una pagina en especifico para Javascript pero estan las siguientes paginas donde se encuentra toda la documentacion del lenguaje\n//https://developer.mozilla.org/en-US/docs/Web/JavaScript\n//https://www.w3schools.com/js/\n\n//Los tipos de sintaxis para comentar en JS son:\n\n//De una sola linea\n\n/**\n * Y los comentarios\n * de \n * linea multiple\n */\n\n//Variables en Javascript\n\nvar ejemplo = 0\n\nlet ejemplo2 = 0\n\nconst ejemplo3 = 0\n\n//Datos primitivos dentro de Javascript\n\nlet dato1 = \"hola\" //string\n\nlet dato2 = 42 //number\n\nlet dato3 = true //boolean\n\nlet dato4 = null //nulo\n\nlet dato5 = undefined //indefinido\n\nlet dato6 = Symbol() //Simbolo\n\nlet dato7 = 123456789n //bigint\n\n//Imprimir en terminal\n\nconsole.log(\"Hola, Javascript\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/claudio-ortiz-dev.js",
    "content": "/**\n * ============================================================================\n * EJERCICIO 01 - FUNDAMENTOS DE JAVASCRIPT\n * ============================================================================\n * \n * @author Claudio Ortiz Dev\n * @date 2026-01-31\n * @description Ejercicio completo sobre fundamentos de JavaScript con\n *              ejemplos prácticos, buenas prácticas y documentación detallada.\n * \n * Sitio oficial: https://developer.mozilla.org/es/docs/Web/JavaScript\n * Especificación: https://www.ecma-international.org/publications-and-standards/standards/ecma-262/\n * \n * ============================================================================\n */\n\n// ============================================================================\n// 1️1 COMENTARIOS EN JAVASCRIPT\n// ============================================================================\n\n// Comentario de una sola línea: útil para explicaciones breves\n// Se usa con dos barras diagonales //\n\n/*\n * Comentario multilínea: ideal para bloques de texto más largos\n * o para comentar temporalmente secciones de código.\n * \n * Tip: Atajo de teclado en VS Code\n * - Línea única: Ctrl + / (Windows) o Cmd + / (Mac)\n * - Multilínea: Alt + Shift + A (Windows) o Option + Shift + A (Mac)\n */\n\n/**\n * Comentario JSDoc: El estándar profesional para documentar código\n * Se usa para documentar funciones, clases y módulos.\n * Los editores modernos lo usan para autocompletado y ayuda contextual.\n * \n * @example\n * // Este tipo de comentario es el que usan las bibliotecas profesionales\n * @see https://jsdoc.app/\n */\n\n// ========================================\n// 2. VARIABLES Y CONSTANTES\n// ========================================\n\n// VARIABLE: Su valor puede cambiar\nlet miVariable = \"Puedo cambiar\";\nvar otraVariable = \"Esta es la forma antigua (evitar usar var)\";\n\n// CONSTANTE: Su valor NO puede cambiar\nconst MI_CONSTANTE = \"No puedo cambiar\";\n\n\n// ========================================\n// 3. TIPOS DE DATOS PRIMITIVOS\n// ========================================\n\n// STRING (Cadena de texto)\nlet texto = \"Hola, soy un texto\";\nlet otroTexto = 'También puedo usar comillas simples';\nlet textoModerno = `Y comillas invertidas para templates`;\n\n// NUMBER (Números enteros y decimales)\nlet numeroEntero = 42;\nlet numeroDecimal = 3.14;\nlet numeroNegativo = -17;\n\n// BOOLEAN (Verdadero o Falso)\nlet esVerdadero = true;\nlet esFalso = false;\n\n// UNDEFINED (Variable declarada pero sin valor asignado)\nlet sinValor;\n// Si imprimes sinValor, verás: undefined\n\n// NULL (Ausencia intencional de valor)\nlet valorNulo = null;\n\n// SYMBOL (Valor único e inmutable - avanzado)\nlet simbolo = Symbol(\"descripcion\");\n\n// BIGINT (Números muy grandes - ES2020)\nlet numeroGigante = 123456789012345678901234567890n;\n\n\n// ========================================\n// 4. IMPRIMIR EN LA CONSOLA\n// ========================================\n\nconsole.log(\"¡Hola, JavaScript!\");\n\n// También puedes imprimir las variables:\nconsole.log(\"\\n--- Mis Variables ---\");\nconsole.log(\"Texto:\", texto);\nconsole.log(\"Número entero:\", numeroEntero);\nconsole.log(\"Número decimal:\", numeroDecimal);\nconsole.log(\"Boolean verdadero:\", esVerdadero);\nconsole.log(\"Boolean falso:\", esFalso);\nconsole.log(\"Undefined:\", sinValor);\nconsole.log(\"Null:\", valorNulo);\n\n\n// ========================================\n// EXTRA: Información útil\n// ========================================\n\nconsole.log(\"\\n--- Información Extra ---\");\nconsole.log(\"Tipo de 'texto':\", typeof texto);\nconsole.log(\"Tipo de 'numeroEntero':\", typeof numeroEntero);\nconsole.log(\"Tipo de 'esVerdadero':\", typeof esVerdadero);\nconsole.log(\"Tipo de 'sinValor':\", typeof sinValor);\nconsole.log(\"Tipo de 'valorNulo':\", typeof valorNulo);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/cmejiajulian.js",
    "content": "// *Ejercicio #00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n\n/*\n*   Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado  \n*/\n\n//  https://developer.mozilla.org/es/docs/Web/JavaScript\n    console.log('https://developer.mozilla.org/es/docs/Web/JavaScript');\n\n/*\n *   Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n*/\n\n// doble slash '//' para comentar una sola linea.\n/* Slash y asterisco para hacer comentarios multilinea. */\n\n /*\n *   Crea una variable (y una constante si el lenguaje lo soporta).\n */\n\n var a = 10;\n let b = 20;\n const c = 30;\n\n /*\n *  Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n */\n\n // cadena de caracteres o string\n\n let nombre = ' Brian Oconor ';\n\n // Numero enteros \n\n let number = 123546;\n\n //  BigInt\n\n let numberGrande = BigInt(5115421368641);\n\n // Booleano o Boolean \n\n let  boleanitoF = false; \n let  boleanitoV = true; \n\n // symbol \n\n let symbol1 = Symbol('a');\n let symbol2 = Symbol('a');\n \n /*\n * Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n*/\n\nconsole.log('Hola JavaScript ');\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/codejoss.js",
    "content": "// Especificacion oficial de Javascript: https://ecma-international.org\n// Documentación más ocupada: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Javascript\n\n// Doble diagonal para comentarios de una sola linea\n\n/*\n  Diagonal y asterisco para encerrar comentarios de bloque de varias lineas\n*/\n\n// --------------------------------\n// Creación de variable\n// Existen 3 formas, var y let, sin embargo, actualmente la que se recomienda usar es let\nvar variableConVar = 'Soy una variable con var'\nlet variableConLet = 'Soy una variable con let'\nvariableSinPalabraClave = 'Soy una variable sin palabra clave' // Este tipo de variable suele ocacionar problemas ya que se elevan a variables globales y pueden llevar a problemas de alcance\n\n// --------------------------------\n// Creación de constantes\nconst pi = 3.1416\n// Se pueden declarar variasa constantes en una sola linea separando cada una con una coma «,»\nconst name = 'Josue', apellido = 'Quevedo'\n\n// --------------------------------\n// Datos primitivos\n// Existen 6 tipos de datos primitivos en Javascript\nconst string = 'Soy un string'\nconst number = 10\nconst booleanTrue = true\nconst booleanFalse = false\nconst nullData = null\nconst undefinedData = undefined\nconst symbolData = Symbol('Soy un symbolo')\n\n// --------------------------------\n// Imprimiendo por terminal\n\nconsole.log('Hola, Javascript');"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/conrado85.js",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n\n\n// Especificacion oficial de Javascript: https://ecma-international.org\n// Documentación más ocupada: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Javascript\n\n// Doble diagonal para comentarios de una sola linea\n\n/*\n  Diagonal y asterisco para encerrar comentarios de bloque de varias lineas\n*/\n\n// --------------------------------\n// Creación de variable\n// Existen 3 formas, var y let, sin embargo, actualmente la que se recomienda usar es let\nvar variableConVar = 'Soy una variable con var'\nlet variableConLet = 'Soy una variable con let'\n\n\n// --------------------------------\n// Creación de constantes\nconst pi = 3.1416\n// Se pueden declarar variasa constantes en una sola linea separando cada una con una coma «,»\nconst name = 'conrado', apellido = 'Gonzalez'\n\n// --------------------------------\n// Datos primitivos\n// Existen 6 tipos de datos primitivos en Javascript\nconst string = 'Soy un string'\nconst number = 20\nconst booleanTrue = true\nconst booleanFalse = false\nconst nullData = null\nconst undefinedData = undefined\nconst symbolData = Symbol('Soy un symbolo')\n\n// --------------------------------\n// Imprimiendo por terminal\n\nconsole.log('Hola, Javascript');"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/cpcarlosprieto.js",
    "content": "// URL del sitio web oficial de JavaScript: https://developer.mozilla.org/es/docs/Web/JavaScript\r\n// Representación de comentarios en JavaScript:\r\n\r\n// Comentario de una línea\r\nlet comentarioDeUnaLinea = \"Este es un comentario de una línea\";\r\n\r\n/*\r\n  Comentario\r\n  de\r\n  varias\r\n  líneas\r\n*/\r\nlet comentarioDeVariasLineas = `\r\n  Este es un comentario de varias líneas.\r\n  Puede abarcar varias líneas utilizando el formato de plantilla.\r\n`;\r\n\r\n// Crear una variable y una constante:\r\nlet miVariable = \"Hola, soy una variable\";\r\nconst MI_CONSTANTE = \"¡Soy una constante!\";\r\n\r\n// Variables de diferentes tipos de datos primitivos:\r\nlet cadenaDeTexto = \"Hola, soy una cadena de texto\";\r\nlet numeroEntero = 42;\r\nlet booleano = true;\r\n\r\n// Imprimir por terminal:\r\nconsole.log(\"¡Hola, JavaScript!\");\r\n\r\n// Operaciones matemáticas:\r\nlet resultadoSuma = numeroEntero + 8; // Suma\r\nlet resultadoMultiplicacion = numeroEntero * 2; // Multiplicación\r\n\r\n// Concatenación de cadenas:\r\nlet saludoPersonalizado = \"Hola, \" + \"mundo\" + \"!\";\r\n\r\n// Estructuras de control - if statement:\r\nif (booleano) {\r\n  console.log(\"La variable booleano es verdadera\");\r\n} else {\r\n  console.log(\"La variable booleano es falsa\");\r\n}\r\n\r\n// Bucle for:\r\nfor (let i = 0; i < 3; i++) {\r\n  console.log(\"Iteración #\" + (i + 1));\r\n}\r\n\r\n// Funciones:\r\nfunction saludar(nombre) {\r\n  return \"¡Hola, \" + nombre + \"!\";\r\n}\r\n\r\nlet mensajeSaludo = saludar(\"Brais Moure - @mouredev\");\r\nconsole.log(mensajeSaludo);\r\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/crisscde.js",
    "content": "/* \n  * Documentación de JS\n  JS tiene 2 documentaciones oficiales:\n    - MDN JavaScript => https://developer.mozilla.org/es/docs/Web/JavaScript\n    - ECMAScript => https://ecma-international.org/publications-and-standards/standards/ecma-262/\n*/\n\n\n// * Formas de crear comentarios\n\n// Comentarío de una sola linea\n\n/* \n  Comentario \n  multilínea\n*/\n\n// * Formas de crear variables\n/* \n  Antes de ECMAScript 6\n    Antes solo se podían crear variables con var, estas variables tienen:\n      - 2 ámbitos (global y función)\n      - Puede ser re-asignadas y re-declaradas\n      - Puede ser declarada sin inicializar \n      - Al momento de ser elevadas al inicio de su scope (Hoisting). Las variables creadas con var\n        son inicializadas con undefined\n*/\nvar variable1 = \"Antes de ECMAScript 6 se usaba esta forma de declarar variables\";\n\n/*\n  Despues de ECMAScript 6\n    \n    - Let -> Sirve para crear variables al igual que var, las diferencias son las siguientes>\n      - Su ámbito es de bloque\n      - Solo puede ser re-asignada\n      - Puede ser declara sin inicializar\n      - Al momento de ser elevadas al inicio de su scope (Hoisting). Las variables creadas con let\n        no son inicializadas\n    - const -> Sirve para crear constantes, estas toma todas las caracteristicas de var, la unica\n                diferencia es que no pueden ser re-asignadas, por lo mismo, al momento de\n                declararlas, se deben de inicializar\n*/\nlet variable2 = \"El cambio es el scope, var tiene un scope global y let tiene un scope local\"\nconst constante = \"Forma de crear constantes\";\n\n// * Tipos de datos primitivos\nconst string = \"Cadena de texto\"; // => String\nconst number = 6; // => Number (integer or float)\nconst boolean = true; // => Boolean\nconst nulo = null; // => Null;\nconst undefinido = undefined; // => undefined\nconst simbolo = Symbol(\"Único e inmutable\"); // => Symbol\nconst bigInt = 7893160947916243814n; // => BigInt\n\n// * Mostrando información en la consola\nconsole.log(\"Hola, JavaScript\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/cristiantorres53.js",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n//SOLUCION\n\n//url oficial del sitio: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n//comentario de una linea\n\n/*\n *\n *Comentario de varias filas\n *\n */\n\n//variables\n\nvar variableJS = \"var es el tipo de dato para variable en JS\";\n\n//constantes\n\nconst numero = 55;\n\n//variables tipos de datos primitivos\n\nlet numeros = 1;\nlet nombre = \"cristiantorres53\";\nlet booleanos = true;\nlet char = a;\nlet sinValor;\nlet vacio = null;\nlet precio = 19.22;\n\n//imprime el texto\n\nconsole.log(\"¡Hola, JavaScript!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/cristophher087.js",
    "content": "// https://www.javascript.com/\n\n// comentario de una linea\n\n/* \nComentario\nde multiples\nlineas\n*/\n\nvar variable = 'Variable mas antigua en js';\n\nlet variableActual = \"Puede variar\";\n \nconst constante = \"No puede variar\";\n\n//Tipos de datos\n\nlet string = 'Cadena de caracteres';\nlet number = 0;\nlet bigint = 1000000000n;\nlet boolean = true;\nlet mayorQue = 0>10;\nlet undefined;\nlet valorNulo = null;\nlet id = symbol(\"idUnica\");\n\n//Imprimir en terminal\n\nconsole.log(\"¡Hola, [JavaScript]!\");  //En consola\n\nalert(\"¡Hola, [JavaScript]!\");        //Unicamente en Navegadores\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/d4-n1.js",
    "content": "// Documentación oficial de JavaScript: https://developer.mozilla.org/en-US/docs/Web/javascript\n\n// Esto es un comentario de una sola línea.\n\n/*\nEsto es un comentario de varias líneas de longitud.\n*/\n\n// Variables y constantes\nconst name = \"d4-n1\"\nvar oldSchoolVariable = \"I'm the old way to write a variable\"\nlet newVariable = \"I'm the current way to write a variable\"\n\n// Primitives\nlet string = \"string\"\nlet number = 8\nlet boolean = true\nlet undefined\n\n// Console.log\nconsole.log(\"¡Hola, JavaScript!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/dacronik.js",
    "content": "// https://developer.mozilla.org/es/docs/Web/JavaScript es la web oficial de JavaScript\n\n// Comentario en una sola linea\n/*\nEste es un comentario\nen varias lineas\nen JavaScript \n*/\nvar variableVar = 'esta es una forma que no es recomendable usar';\nlet myVariable = 'esta es una variable en JavaScript';\nconst myConstante = 'Esta es una constante en JS';\n\nlet myInt = 1; // soy un entero\nlet myFloat = 1.5; // soy una variable float\nlet myString = 'soy un dato string'; \nlet myBoolean = true; // tambien puedo ser false\nlet myUndefined = undefined; // soy una variable no definida\nlet myNull = null; // tambien soy una variable nula\nlet myBigInt = 9007199254740991n // tambien puedo ser un numero grande\nlet mySimbol = Symbol('kunfu') /// soy unico e inmutable\n\nlet myLenjuage = 'JavaScript'\nconsole.log(`¡Hola, ${myLenjuage}`);"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/daniback95.js",
    "content": "// Documentación oficial https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Comentario de una sola línea\n\n/* \n  comentario \n  de \n  varias lineas\n*/\n\n// variable\nlet nombre = 'Juan';\n// mutación de variable\nnombre = 'el nuevo nombre es: Sebastián';\n\n\n// constante\n// por convención el nombre se escribe en mayúsculas\nconst PI = 3.1416;\n\n// datos primitivos\n\n// comillas simples\nlet myString = 'Hola mundo';\n// comillas dobles\nlet otherString = \"Otra cadena de texto\";\n// Backticks o comillas invertidas\nlet phrase = `Podemos incrustar otro string ${myString}`;\n\n// entero\nlet myInteger = 33;\n// flotante\nlet myFloat = 3.9;\n// Infinity: el resultado es Infinity, también esta -Infinity\nlet myInfinity = 1 / 0;\n// la n al final significa que es un BigInt\nlet myBigInt = 1234567890123456789012345678901234567890n; \n\n// Boolenos\nlet myBool = true;\nmyBool = false;\n\n// NaN: Resultado debido a una operación matemática incorrecta\nlet notAtNumber = 'esto no es un numero' / 2; \n\n/* \nnull: representa nada, vacío o desconocido, es un valor especial\nse aisgna de manera explícita\n*/\nlet myNull = null;\n\n/* \nundefined, es un valor especial, siginifica valor no asignado.\nAl declarar una variable pero al no ser asignada, su valor es undefined;\neste valor se puede asignar manualmente, pero no se recomienda, para ello\nusamos null, para asignar un valor \"vacío\" o \"desconocido\".\nUndefined es un valor inicial reservado para cosas que aún no \nhan sido asignadas, es decir se asgina automaticamente para aquellas varialbles\nque no han sido inicializadas con ningún valor de manera explícita.\n*/\nlet myUndefined = undefined; // Asignado manualmente\nconsole.log({myUndefined});\nlet indefinido; // Valor inicial implícito undefined\nconsole.log({indefinido})\n\nconsole.log(\"Hola, JavaScript\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/dariorfm.js",
    "content": "// URL \"https://developer.mozilla.org/en-US/docs/Web/JavaScript\"\n\n// Este es un comentario de una linea\n// Esta es otra línea de comentario\n\n/**\n * Este sintaxya de comentarios \n * se usa para varias líneas \n * y tiene un aspecto más ordenado.\n */\n\n/*\nEsta es otra sintaxys de \ncomentarios multilíneas\nalgo más simple que el anterior\n*/\n\n/**\n * JavaScript es un lenguaje de TIPADO DINAMICO.\n * A las variables se les puede asignar y reasignar valores de todos los TIPOS.\n */\n\n// Delcaracion de una variable\nlet variable = \"valor\";\nvar variable01 = \"No recomendado hacer uso var para declarar variable\";\n\n// Declaración de una constante\nconst CONSTANTE = 3000;\n\n/**\n * TIPOS DE DATOS: son 9 en total de los cuales \n * 6 seis son PRIMITIVOS\n */\n\n// Datos primitivos.\nlet myString = \"string o cadena de texto\"; \nlet myNumber = 1000;\nlet myBoolean = false; // psolo toma 2 valores true o false\nlet myUndefined = undefined;\nlet myBigInt = 987898789876554678987655467899765567898877666789877999n;\nlet mySymbol = Symbol(\"Símbolo\");\n\n\n// Otros tipo.\n\nlet myNull = null;\n\nlet myObject = {};\n\nlet myFunction = funcion() {\n    //Instrucciones\n};\n\n\n// Imprimir por consola.\n\nconsole.log(\"¡Hola, JavaScript!\");\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/darkhouselab08.js",
    "content": "// URL del sitio web oficial de JavaScript\n// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// --- Comentarios ---\n\n// Esta es la sintaxis de un comentario en una sola línea.\n\n/*\n  Esta es la sintaxis\n  para un comentario\n  en múltiples líneas.\n*/\n\n// --- Variables y Constantes ---\n\n// Una variable (let) permite que su valor cambie.\nlet myVariable = \"Esta es mi primera variable\";\nmyVariable = \"Este es un nuevo valor para mi variable\"; // El valor cambió\n\n// Una constante (const) no puede ser reasignada después de su creación.\nconst MY_CONSTANT = \"Este es un valor constante\";\n// Si intentaras: MY_CONSTANT = \"Otro valor\"; // Esto daría un error.\n\n// --- Tipos de Datos Primitivos (con más ejemplos) ---\n\n// 1. String (Cadena de texto)\nlet myString = \"Hola, Franco\";\nlet myOtherString = 'Esto también es un string.';\nlet email = \"darkhouselab08@gmail.com\";\n\n// 2. Number (Número) - JavaScript no distingue entre enteros y flotantes.\nlet myInteger = 42;\nlet myFloat = 3.1416;\nlet myNegativeNumber = -10;\n\n// 3. Boolean (Booleano) - Solo puede ser Verdadero o Falso\nlet isLearning = true;\nlet isFinished = false;\n\n// 4. Undefined (Indefinido)\n// Una variable que ha sido declarada pero aún no tiene valor.\nlet myFutureValue;\n// console.log(myFutureValue); // Esto imprimiría 'undefined'\n\n// 5. Null (Nulo)\n// Representa la ausencia intencional de cualquier valor. Es un \"valor vacío\" a propósito.\nlet myEmptyValue = null;\n\n// 6. BigInt\n// Para números enteros que son demasiado grandes para el tipo 'Number'.\nlet myBigNumber = 90071992547409912345n; // La 'n' al final lo define como BigInt\n\n// 7. Symbol\n// Para crear identificadores únicos (lo usarás en temas avanzados).\nlet myUniqueId = Symbol(\"id\");\nlet myOtherUniqueId = Symbol(\"id\");\n// myUniqueId === myOtherUniqueId; // Esto sería 'false'\n\n// --- Impresión por Terminal ---\n\n// (En JavaScript, la \"terminal\" es la \"consola\" del navegador o de Node.js)\nconsole.log(\"¡Hola, JavaScript!\");\n\n// (Bonus: Cómo imprimir el tipo de dato, como en el ejemplo de Python)\nconsole.log(typeof myString);      // Imprimirá \"string\"\nconsole.log(typeof myInteger);     // Imprimirá \"number\"\nconsole.log(typeof isLearning);    // Imprimirá \"boolean\"\nconsole.log(typeof myFutureValue); // Imprimirá \"undefined\"\nconsole.log(typeof myEmptyValue);  // Imprimirá \"object\" (¡un detalle peculiar de JS!)\nconsole.log(typeof myBigNumber);   // Imprimirá \"bigint\"\nconsole.log(typeof myUniqueId);    // Imprimirá \"symbol\""
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/darubiano.js",
    "content": "/*\n    EJERCICIO:\n    1) Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n    2) Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n    3) Crea una variable (y una constante si el lenguaje lo soporta).\n    4) Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n    5) Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n */\n\n// 1) https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n// 2) Comentario de una linea y varias\n\n/*\n    Comentario de varias lineas\n */\n\n// 3) Variable y constante\nlet variable = \"texto\";\nconst pi = 3.1416;\n// 4) Tipos de variables primitivas o Tipos incorporados https://developer.mozilla.org/en-US/docs/Glossary/Primitive\n\n// Tipos de dato undefined y null\nlet nulo = null;\nlet indefinido = undefined;\n\n// Tipos de dato numericos, number,BigInt\nlet numero = 123;\nlet decimal = 3.1416;\nlet color = 0xFF0000;\nlet numeroGrande = 9007199254740991n;\n\n// Tipos de dato texto\nlet cadena = \"Texto\";\n\n// Tipos de dato boleano\nlet boleanoVerdadero = true;\nlet boleanoFalso = false;\n\n// Tipos de dato Symbol, se usa crear identificadores unicos\nlet variableSymbol = Symbol(\"descripcion\");\n\n// Tipos de dato lista y objectos\nlet lista = [1, 2, 3];\nlet objecto = { 1: \"primero\", 2: \"segundo\" };\n\n// 5) print JavaScript\nconsole.log(\"¡Hola, JavaScript!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/datrujillog.js",
    "content": "\n/*  \n    * @autor: Diego Trujillo\n    * @name datrujillog.js\n    * @Linkedin: https://www.linkedin.com/in/trujillo-diego/\n    * @type javascript\n    * @description Este archivo contiene ejemplos de sintaxis, variables, tipos de datos y un saludo en consola.\n    * @site_referencia https://developer.mozilla.org/en-US/docs/Web/JavaScript\n    * \n*/\n\n// 1) https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n\n// 2)  Comentario de una linea\n\n// una linea\n\n/*\nComentario de varias lineas\nComentario de varias lineas\nComentario de varias lineas\n*/\n\n\n\n// 3) Variable y constante\nlet variable = \"Hola\";\nconst constante = \"Mundo\";\n\n// 4) Variables de tipos de datos primitivos \n\n// Number\nlet age = 25;\n\n// String\nlet name = \"John\";\n\n// Boolean\nlet isStudent = true;\n\n// Undefined\nlet score = undefined;\n\n// Null\nlet country = null;\n\n// Symbol\nconst mySymbol = Symbol(\"description\");\n\n// BigInt\nconst bigNumber = 1234567890123456789012345678901234567890n;\n\n\n// 5) del lenguaje (cadenas de texto, enteros, booleanos...).\n\n// String\nlet string = \"Soy un string\";\n\n// Number\nlet number = 10;\n\n// Boolean\nlet booleanTrue = true;\nlet booleanFalse = false;\n\n// Null\nlet nullData = null;\n\n// Undefined\nlet undefinedData = undefined;\n\n// Symbol\nlet symbolData = Symbol('Soy un symbolo');\n\n// BigInt\nlet bigInt = 1234567890123456789012345678901234567890n;\n\n\n// 6) Imprimir texto en consola\n\nconsole.log(\"¡Hola, JavaScript!\");\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/davhage.js",
    "content": "//?https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n//* Comentario de una línea\n/*\n    Comentario de\n    varias líneas\n*/\n\nlet variable = 'Hola';\nconst constante = 'Mundo';\n\nlet name = 'David';\nlet age = 33;\nlet student = true;\nlet city = null;\nlet centimeterToTheMoon = 38440000000n;\nlet array = [1, 2, 3];\nlet objeto = {id: 1, name: 'david', email: 'davidhage@hotmail.com'};\n\nconsole.log('Hola javascript!');\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/davidb313.js",
    "content": "/*   EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\" */\n\n//comentario de una línea https://developer.mozilla.org/es/docs/Web/JavaScript\n\n/* Comentarios en\nvarias lineas */\n\nlet variableQuePuedeCambiar = \"este es un string que se puede modificar\"; // let permite modificar el valor que se ha guardado\nconst variableQueNoPuedeModificarse = \"variable que no se va a modificar\"; // el valor de const no se puede modificar\n\n//Tipos de datos primitivos en JS\nlet number = 13;\nlet string = \"Javascript\";\nlet boolean = true;\nlet variableNull = null;\nlet variableUndefined = undefined;\nlet array = [\"pera\", \"manzanar\", \"limon\"];\nlet objeto = { nombre: \"David\", edad: 34, pais: \"Colombia\" };\n\nconsole.log(\"Hola\", string);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/davidgar42.js",
    "content": "/*\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n//https://devdocs.io/javascript/\n/*Otro comentario\nde bloque*/\n\nlet myVariable \nconst myConstant = \"Hola\"\n\nlet myNumber = 14\nlet myBigNumber = 125435345345n\nlet myString = \"Mundo\"\nlet myDecimal = 1.3\nlet myBoolean = false\nlet mySymbol = Symbol(\"miSimbolo\")\n\n\nlet lang = \"Javascript\"\nconsole.log(`Hola ${lang}!!`)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/dev-marco-dev.js",
    "content": "\n//este es un comentario https://developer.mozilla.org/es/docs/Web/JavaScript\n/*este es \nun comentario\nde varias lineas */\n\nlet example \n\nconst example1 = 'example'\n\nlet number = 20\nlet number2 = 4.5\nlet string = 'this is a string'\nlet boolean = true\nlet boolean2 = false\nlet undefined = undefined\nlet null1 = null\nlet sym = Symbol('description')\nlet bigNumber = 4736287647759899387266347499588734838439234293423423488n\n\nconsole.log(\"hola javascript\");\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/dianelis1.js",
    "content": "// https://developer.mozilla.org/es/docs/Learn/JavaScript/First_steps/What_is_JavaScript\n// This is a one line comment\n/* But this is a \n      multi-line \n        comment. */\n\nvar myVariable = 3;\nconst MY_CONST = 4;\n\nvar string = \"Hello\";\nvar boolean = true;\nvar numbers = 2;\n\nconsole.log( \"¡Hola, Javascript !\" );\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/diegoasebey.js",
    "content": "#! El sitio oficial (?) de Javascript, dicen, puede ser, dicen: https://developer.mozilla.org, https://www.javascript.com/javascrpit.com, o https://ecma-international.org/publications-and-standards/standards/ecma-262/\n\n/*\nEste tipo de comentario en bloque permite crear varias\nlíneas\nde\ntexto\nignorado por el navegador o lo que sea que lo interprete\n*/\n\n//Este es un comentario de una sola línea, por lo que no es necesario cerrarlo, como el comentario de múltiples líneas\n\nvar x; //variable global declarada\nlet y; //variable de bloque declarada\nconst z = 3; //constante declarada\n\nx = 1; //variable inicializada\ny = 2; //variable inicializada\n\nvar $booleano = true;\nvar $nulo = null;\nvar $indefinido = undefined;\nvar $entero = 25.6;\nvar $punto_flotante = 26.543;\nvar $cadena = \"¡Hola, Javascript!\";\nvar $simbolo = Symbol(\"un simbolo\");\n\nconsole.log($cadena);"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/diegoxxd.js",
    "content": "// Comentario + URL del programa\n// www.javascript.com\n\n//Sintaxis de comentarios\n\n// Este es un comentario en una línea.\n\n/*\nEste\nes\nun\ncomentario\nen \nvarias\nlíneas.\n*/\n\n\n// Variables (Let y Var) y una constante (Const)\nlet EsUnaVariable = \"Limitada\" // Permite declarar una variable limitando su alcance al bloque, declaración o expresión donde se esté usando.\nvar EsOtraVariable = \"Ilimitada\" // Permite definir una variable global o local en una función sin importar el ámbito del bloque.\nconst PI = 3.14 // Es para declarar una constante. Es un valor que no se puede cambiar.\n\n\n// Ejemplos de variables con datos primitivos\n\n// String\nlet my_string = \"Esta es una cadena de texto\"; //Se usa para escribit texto\n\n// Number\nlet my_number = 8; // Se usa con numeros enteros.\nlet other_number = 1.5; // También con números decimales.\nlet bigInt = 1234567898765432123456789n; // Es una variable para números largos.\n\n// Boolean: tipo lógico\nlet my_boolean = true;\nlet other_boolean = false;\n\n// Undefined y Null\nlet undefined; // Es un valor no asignado.\nlet abc = null; // Es un valor desconocido. Vacío. Nada.\n\n// Symbol y Object\nlet object = new Date(\"2024-03-14\")  // Se usan para almacenar colecciones de datos y entidades más complejas\nlet symbol = Symbol(); // Se utiliza para crear identificaodres únicos para los objetos.\n\n//Imprimir un texto dentro de la consola.\nconsole.log(\"Hola, Javascript!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/dieswae.js",
    "content": "// https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n// Comentario de una linea\n\n/*\n  Comentario \n  de varias\n  lineas\n*/\n\nlet soyVariable = 'Soy una variable';\nconst soyConstante = 'Soy una constante';\n\nlet String = 'Soy una cadena de texto';\nlet Number = 10;\nlet Boolean = true;\nlet Boolean2 = false;\nlet undefined; // undefined\nlet undef = undefined;\nlet nulo = null\n\nconsole.log('¡Hola, JavaScript!');\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/dmhenaopa.js",
    "content": "/**\n * 00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n*/\n\n /**\n * Esta es la URL del sitio web oficial de Javascript correspondiente a la\n * estandarización del lenguaje JavaScript: https://ecma-international.org/\n * Documentación de referencia MDN web docs: https://developer.mozilla.org/es/docs/Web/JavaScript\n */\n\n /**\n  * Existen diferentes sintaxis para crear comentarios en JavaScript:\n  * 1. Cuando el comentario es de una sola linea se utiliza // al inicio \n  *    del comentario\n  * 2. Cuando el comentario es de varias lineas se utilizan // /**/\n\n/**\n * Variables en JavaScript\n * 1. Con var: Desaconsejada actualmente por problemas con scope\n * 2. Con let: Forma aconsejada para declarar variables\n * 3. Con const: Esta es la forma utilizada para declarar constantes\n */\nvar varFormaDesaconsejada = 1;\nlet varFormaAconsejada = 'String';\nconst constante = [0, 1, 2];\n\n/**\n * Datos primitivos: string, number, bigint, boolean, undefined y symbol\n */\nlet string = 'Este es un string';\nlet numero = 12345;\nlet bigint1 = 1234567890n; //Indicación de un bigint con una 'n' al final \nlet bigint2 = BigInt(1234567890);\nlet booleano = true;\nlet varUndefined;\nlet simbolo = Symbol('Key'); //Cadena dentro de Symbol es opcional\n\n/**\n * Funcion para imprimir saludo a lenguaje\n * @param { String } miLenguaje - Lenguaje de programación seleccionado\n */\nlet paraImprimir = ( miLenguaje ) => {\n    console.log(`¡Hola, ${miLenguaje}!`);\n};\n\nparaImprimir('JavaScript');\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/doblea74.js",
    "content": "//web oficial https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n//comentario en una linea\n\n/* esto es un comentario\nen varias lineas */\n\nlet unaVariable = 'esto es una variable'; \nconst unaConstante = 'esto es una constante';\n\nlet numero = 0;\nlet boolean = true;\nlet string = 'esto es un string';\nlet array = [];\nlet varUndefined;\nlet BigInt = 131312316n;\nlet isNull = null;\n\nlet miLenguaje ='JavaScript'\n\nconsole.log(\"¡Hola, \" + miLenguaje + \"!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/domo2pdev.js",
    "content": "/*\nEJERCICIO:\n - Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n - Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n - Crea una variable (y una constante si el lenguaje lo soporta).\n - Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n*/\n\n// La web oficial de JavaScript es https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Esta es la sintaxis apara generar comentarios en javaScript:\n\n// Comentario en una línea\n\n/* Esto es un comentario\nde varias lineas*/\n\n// Esta es la sintaxis para crear variables:\n\nlet my_variable = \"Snake case\"\nlet soyUnaVariable = \"Lower Camel Case\"\nlet SoyOtraVariable = \"Upper Camel Case\"\n\n/*Se suele usar Upper Camel Case en los nombres de las clases y archivos. \nLower Camel Case en los nombres de las variables o métodos.*/\n\n// Esta es la forma de crear constantes:\nconst PI = 3.14159265359\n\n// Estos son los diferentes tipos de datos primitivos en javaScript:\nlet myString = \"Soy un String\" // Type String\nlet myNumber = 42.622 // Type Number\nlet myBigInt = BigInt(\"123456789012345678901234567890\") // type BigInt\nlet myBool = true // Type boolean\nlet myUndefined = undefined // Type Undefined\nlet mySymbol = Symbol //Type Symbol\nlet myNull = null // Type Null\n\nconsole.log(\"Hola! JavaScript.\")\nconsole.log(myString)\nconsole.log(typeof myNull)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/dragneelito.js",
    "content": "//http://ecmascript.org/.\n\n\n/* Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...) */\n\n// Comentario en 1 linea \n\n/* Comentario \npara bloques \nmás extensos */\n\n// Crea una variable (y una constante si el lenguaje lo soporta).\n\nvar variable = \"alcance global si esta afuera de una funcion\";\n\nlet variable = \"tiene alcance de bloque ({})\";\n\nconst constante = 'su valor no puede ser reasignado después de la inicialización';\n\n\n/*Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...)*/\n\nlet string = \"Cadena de texto\";\n\nlet number = 2305;\n\nlet undefined = \"Valor de una variable que ha sido declarada pero no se le ha asignado un valor\";\n\nlet symbol = \"Un identificador único e inmutable, útil para claves de objetos\";\n\nlet null = \"Representa la ausencia intencional de un valor, aunque su tipo en typeof es 'object' debido a un error histórico\";\n\nlet boolean = \"Representa valores lógicos: true o false\";\n\nlet BigInt = \"Para números enteros que superan el límite seguro del tipo Number, se añade una n al final, como 9007199254740991n\"\n\n\n// Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\nconsole.log(\"¡Hola, JavaScript\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/drfcozapata.js",
    "content": "// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Comentario de una línea\n\n/*\nComentario\nde\nvarias\nlíneas\n*/\n\nlet variable;\nconst VARIABLE = \"Some text\";\n\nlet cadena = \"Text chain\";\nlet numero = 123;\nlet booleano = true;\nlet bigEntero = 1234567890n;\nlet simbolo = Symbol(\"symbol\");\nlet indefinido;\nlet nulo = null;\n\nconsole.log(typeof cadena);\nconsole.log(typeof numero);\nconsole.log(typeof booleano);\nconsole.log(typeof bigEntero);\nconsole.log(typeof simbolo);\nconsole.log(typeof indefinido);\nconsole.log(typeof nulo);\n\nconsole.log(\"¡Hola, JavaScript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/duendeintemporal.js",
    "content": "//It seems to me that there is no official language page, however I leave two reference links\n//The first to a documentation of language as such: https://lenguajejs.com/\n/*The second is an ECMAScript documentation, the standard set for the language: https://262.ecma-international.org/12.0/ Note: There is a more current specification: https://ecma-international.org/publications-and-standards/standards/ecma-262/ */\n\n// One-line comments \n/* Comments\n                of\n                     many lines */\n\nvar num; /* It declares a variable, is deprecated as its scope definition gives way to potential errors. Has a defined scope at the function level */\n\n\nlet lang; /* It is most commonly used and has a defined scope at the block level.\nUnlike the var keyword, when declaring variables using let in the global context, variables will not\nattach to the window object as they do with var. */\n\nconst MIN_VA=0; /* Like the previous one, it has a scope defined in block, but it declares a constant and must be initialized at some value. By convention, capital letters are usually used */\n\n\n// Primitive Types or Primitive Values\n\nlet hello='Hi Girl!'; // string type\nconsole.log(`String type: ${hello}`);\n\nlet x_coord=100; // number type\nconsole.log('Number type: ', num);\n\nlet bool=true; // boolean type\nconsole.log('Boolean type: ', bool);\n\nlet stack=[0,1,2,3,4,5,6]; // array type\nconsole.log('Array type: ', stack);\n\nlet obj={\n    name:'Niko',\n    age:41,\n    profession: 'Writer & Web Developer',\n\n  // method\n    greetings: function(){\n        console.log(`Hello I am ${this.name} and it's a pleasure to start and share this roadmap with you`) }\n} // object type\nconsole.log('Object type: ', obj);\nobj.greetings();\n\nlet obj2=null; // null type\n/* Representing the absence of a value helps to handle situations where a value is not available or has not been intentionally defined. */\nconsole.log('Null type: ', obj2);\n\nlet obj3; // undefined type\n/* undefined is a value that indicates that a variable has been declared but not initialized. */\nconsole.log('Undefined type: ', obj3);\n\nlet syn=Symbol('syn'); // symbol type\nconsole.log('Symbol type: ', syn);// Symbol can't be converted to string\n/* Symbols can be used to prevent object collisions, such as to create hidden non-enumerable properties on objects or private methods in a class */\n\nlet amount=BigInt(3783787487877877887)*BigInt(2); //bigint type\nconsole.log(`BigInt type: ${amount}`);\n/* Using BigInt is especially useful in situations where accuracy is required in calculations with large integers, such as in financial or crypto applications. */\n\n\n/* Typeof is an operator that we can use to figure out a type or make type comparisons */\nconsole.log('Type of syn:', typeof syn);\nconsole.log('Is amount of bigint type:', (typeof amount == \"bigint\"));\n\n// short for console.log()\nlet log=console.log.bind(console);\n\n// mapping to a previously declared variable\nlang='JavaScript';\n\n//print in console\nlog(`Hello, ${lang}`);"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/dumbnoxx.js",
    "content": "// La documentacion que voy a utilizar es esta: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n/*\n  Esta es la sintaxis de los comentarios multilinea\n*/\n\n// Javascript tiene 3 maneras de declarar variables\nvar primera;\nlet segunda;\nconst TERCERA = \"\";\n\n// Siendo let y const las mas usadas\n\n//Los tipos primitivos de javascript son\nconst string = \"Esto es una string\";\nconst number = 12;\nconst boolean = true || false;\nconst Null = null;\nconst Undefined = undefined;\nconst BigInt = 12n;\n\nconsole.log(\"¡Hola, JavaScript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/edalmava.js",
    "content": "// Comentario de una línea\n// La especificación oficial del lenguaje es ECMAScript(ECMA-262)\n// Sitio oficial: https://ecma-international.org/publications-and-standards/standards/ecma-262/\n// Ultima edición a 26/06/2024: https://262.ecma-international.org/14.0/\n\n/* \n  Comentario de varias líneas o multilinea\n*/\n\n/* \n   Para declarar una variable se usa la palabra reservada var, let o const\n   Para variables mutables se usa var y let\n   Actualmente se debería usar let \n\n   Para variables inmutables(contantes) se usa la palabra reservada const\n\n   Se asignan valores usando el operador =\n\n   La asignación sigue la siguiente sintaxis:\n       nombre_variable = valor\n*/\n\n// Tipos de datos y valores\n\n// Tipos primitivos\n\n// Tipo null\nconst tipo_null = null\n\n// Tipo undefined - cualquier variable a la que no se le ha asignado un valor tiene le valor undefined\nlet tipo_undefined       // El valor de la variable es undefined \n\n// Tipo Boolean - dos valores true y false\nconst verdadero = true\nconst falso = false\n\n// Tipo cadena(String)\nconst lenguaje = \"JavaScript\"\nconst cadena2 = 'Otra cadena'\nconst mensaje = `¡Hola, ${lenguaje}!` \n\n// Tipo Symbol - Representan identificadores únicos\nconst id = Symbol(\"id\")\n\n// Tipos Númericos\n// Tipo Number - Representan valores de doble precisión de 64 bits siguiendo el formato IEEE 754-2019 \nconst numero = 5\nconst numero2 = 5.0\nconst no_es_un_numero = NaN  // valor especial de 'Not-a-Number' \nconst mas_infinito = +Infinity   // valor especial infinito positivo \nconst menos_infinito = -Infinity // valor especial infinito negativo\n\n// Tipo BigInt - Representan valores enteros muy grandes que no se pueden alamacenar de forma segura como tipo NUmber\nconst bigInt = 1234567890123456789012345678901234567890n;  // Se agrega la n al final del número entero\n\n// Tipos no primitivos\n// Tipo Object\nconst objeto = {\n\n}\n\nconsole.log(mensaje)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/edisplai.js",
    "content": "//https://developer.mozilla.org/es/docs/Web/JavaScript\n\n//este es un comentario de una linea \n\n/* \neste es \nun comentario \nde varias lineas \n*/\n\nlet saludo = hola;\nconst constante = mundo;\n\nlet texto = \"hola\";\nlet años = 23;\nlet booleano = true; \n\nconsole.log(\"Hola JavaScript\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/edperez07.js",
    "content": "// https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n//  Sintaxis para comentario de una linea\n\n/*  Sintaxis para comentario\n    de varias lineas */\n\n//  Crear variable y constante\nlet myVariable = 10;\nconst PI = 3.14159;\n\n//  Tipos de variables\nlet myString = \"hola\";  //  Cadena o secuencia de texto \nlet myNumber = 7;       //  Número\nlet myBoolean = true;   //  Booleana\nlet myVariable = null;  //  Null \nlet myVariable;         //  Undefined\nlet hugeInteger = 9007199254740991n;  //  BigInt: utilizando 'n' al final de un numero\nlet hugeInteger = BigInt(9007199254740991); // BigInt: haciendo llamado a la funcion de BigInt()\nlet mySymbol = Symbol();  // Symbol (se puede incluir un string dentro del parentesis como descripción)\n\n// Imprimir en terminal\nconsole.log(\"¡Hola, Javascript!¨);      \n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/elianisdev.js",
    "content": "\n// Description: Elianisdev - Retos de programación en JavaScript\n\n// https://github.com/elianisdev/roadmap-retos-programacion.git\n\n/*Comentario en varias lineas\n coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado\nhttps://devdocs.io/javascript/\nhttps://developer.mozilla.org/es/docs/Web/JavaScript/Guide/Introduction */\n\n//crea una constante\nconst name = \"Mia\"\nconsole.log(name)\n\n//crea una variable\nlet age = 30\nconsole.log(age)\n\n//crea una variable con un valor de tipo string\nlet fruit = \"Manzana\"\nconsole.log(fruit)\n\n//crea una variable con un valor de tipo number\n\nlet number = 10\nconsole.log(number)\n\n//crea una variable con un valor de tipo float\nlet float = 10.5\nconsole.log(float)\n\n\n//crea una variable con un valor de tipo boolean\nlet isTrue = true\nconsole.log(isTrue)\n\n//crea una variable con un valor de tipo array\nlet colors = [\"red\", \"blue\", \"green\"]\nconsole.log(colors)\n\n//crea una variable con un valor de tipo object\nlet person = {\n    name: \"Mia\",\n    age: 30\n}\nconsole.log(person)\n\n//Crea una variale con un tido de dato funcion\nlet myFunction = function() {\n    console.log(\"¡Hola, JavaScript!\")\n}\nmyFunction()\n\n//imprime en terminal el texto \"¡Hola, [y el nombre de tu lenguaje]!\"\n\nlet myLanguage = \"JavaScript\"\nconsole.log(`¡Hola, ${myLanguage}!`)\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/emaenriquez.js",
    "content": "//SITIO OFICIAL JAVASCRIPT\n// https://ecma-international.org/\n\n//TIPOS DE COMENTARIOS\n// Comentario de una línea\n\n/* Comentario\nde varias\nlineas*/\n\n// VARIABLE Y CONSTANTE\nlet numero = 2;\nconst lenguaje = \"Javascript\";\n\n// TIPOS DE DATOS PRIMITIVOS\n// Number\nlet fecha = 2003;\n\n//String\nlet name = \"Emanuel\";\n\n//Boolean\nlet verdadero = true;\nlet falso = false;\n\n//Null\nlet pais = null;\n\n//Undefined\nlet age;\n\nconsole.log(`Hola ${lenguaje}`)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/emedevelopa.js",
    "content": "//SITIO OFICIAL JAVASCRIPT\n// https://ecma-international.org/\n\n//TIPOS DE COMENTARIOS\n// Comentario de una línea\n/* Comentario\nde varias\nlineas*/\n\n//VARIABLE Y CONSTANTE\nlet manos = 2;\nconst color = \"azul\";\n\n//TIPOS DE DATOS PRIMITIVOS\n//Number\nlet age = 17;\n\n//String\nlet name = \"Maria\";\n\n//Boolean\nlet cieloAzul = true;\nlet cieloVerde = false;\n\n//Null\nlet country = null;\n\n//Undefined\nlet age;\n\n\nconsole.log(\"Hola, Javascript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/eonOzux.js",
    "content": "/* * EJERCICIO:\n* 1 Crea un comentario en el código y coloca la URL del sitio web oficial del\n*   lenguaje de programación que has seleccionado.\n* 2 Representa las diferentes sintaxis que existen de crear comentarios\n*   en el lenguaje (en una línea, varias...).\n* 3 Crea una variable (y una constante si el lenguaje lo soporta).\n* 4 Crea variables representando todos los tipos de datos primitivos\n*   del lenguaje (cadenas de texto, enteros, booleanos...).\n* 5 Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\" */\n\n/* 1- Primer comentario en Javascrip en bloque \nURL de Javascript: https://www.javascript.com/ */\n\n//2- Tipos de comentario de linea// \n\n/* Comentario \nde \nbloques */\n\n/* 3- Variables y Constantes */\nvar primerVariable = \"Javascript\";\nlet segundaVariable = \"\";  \n// Las variables son valores que pueden ser actualizados con nuevos valores en el codigo.\n\nconst primerContante = \"\";\n // Las Constantes son valores que a diferencia de las variables, \n//se les asignan valores pero estos son estaticos a lo largo del codigo si se invocan \n//no pueden almacenar nuevos valores. \n\n/* 4- Tipos de Datos */\n\n/* \n1. String\n2. Number\n3. Bigint\n4. Boolean\n5. Undefined\n6. Null\n7. Symbol\n8. Object \n*/\n\nvar datos_texto = \"Mi nombre es Yohan Arce\"; // Tipo String.\n\nlet dato_Num = 2024 // Tipo Number o Bigint.\n\nlet valor = true && false;  // Tipo Booleano.\n\nconst a = \"\";// El resultado de la constante \"a\" es Undefined la estamos definiendo pero no tiene ningun valor.\n\nlet b = null; // El valor de Nulo puede ser asignado a una variable. Se usa para comprobaciones\n\nconst sym1 = Symbol(); // Por medio del metodo Symbol se pueden crear o insertar algun simbolo\nconst sym2 = Symbol(\"foo\"); \nconst sym = new Symbol(); // Este codigo arroja el error -> TypeError\n\nconst person = {firstName:\"John\", lastName:\"Doe\", age:50, eyeColor:\"blue\"}; // Creacion de objetos\n// El objeto es una constante al que se le pueden asignar valores y atributos.\n\n/* 5- Imprimir en la consola el lenguaje */\nconsole.log(\"Hola soy\" + primerVariable + datos_texto);"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/erikayeah.js",
    "content": "// https://www.javascript.com\n\n//! This is a comment in red\n//* This is a comment in green\n//? This is a comment in blue\n\n/* \nyou can start your comment \nhere and ended it in another \nline like this\n*/\n\nvar one = \"variable 1\";\nlet two = \"variable 2\";\nconst three = \"variable 3\";\n\n// datos primitivos\n\nlet string = \"Hola, amigos\";\nlet number = 27;\nlet float = 27.27;\nlet boolean = true;\nlet nullValue = null;\nlet undefinedValue = undefined;\nlet symbol = Symbol(\"Nuevo simbolo\"); //(ES6 -  In JavaScript, Symbol is a built-in object whose constructor returns a symbol primitive — a unique and immutable data type.)\n\nconsole.log(\"¡Hola, Javascript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/esdras-josue.js",
    "content": "//Sitio web: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n//Comentario de una sola linea\n\n/*Comentario\nen multiples\nlineas*/\n\nlet variable = \"Hola\";\nconst PI = 3.14;\n\nlet numero = 1;\nlet cadena = \"Hola mundo\";\nlet booleano = true;\nlet indefinido;\n\nconsole.log(\"Hola, JavaScript!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/estefrac.js",
    "content": "// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Este es un ejenplo de como hacer comentarios en una sola línea.\n\n/* Para hacer comentarios en varias líneas\n   se puede hacer de esta manera, se incia con\n   un slash y un asterisco y se cierra con un asterisco\n   y un slash \n*/\n\n// Creamos una variable y una constante.\n\nlet nombre = \"Estefrac\";\nconst pulgadas = 2.54; \n\n// Variables representando tipos de datos primitivos.\n\nlet texto = \"Retos de Programación\"; // String\nlet numEntero = 43; // Number\nlet numDecimal = 1.23; // Number\nlet mejorRoadmap = true; // Boolean\nlet proximasVacaciones; // Undefined\nlet tiempoLibre = null; // Null\n\n// Imprimir en consola el mensaje \"¡Hola, JavaScript!\"\n\nconsole.log(\"¡Hola, Javascript!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/eugeniasoria.js",
    "content": "/*\r\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\r\n * - Recuerda que todas las instrucciones de participación están en el\r\n *   repositorio de GitHub.\r\n *\r\n * Lo primero... ¿Ya has elegido un lenguaje?\r\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\r\n * - Este primer reto te servirá para familiarizarte con la forma de participar\r\n *   enviando tus propias soluciones.\r\n *\r\n * EJERCICIO:\r\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\r\n *   lenguaje de programación que has seleccionado.\r\n * - Representa las diferentes sintaxis que existen de crear comentarios\r\n *   en el lenguaje (en una línea, varias...).\r\n * - Crea una variable (y una constante si el lenguaje lo soporta).\r\n * - Crea variables representando todos los tipos de datos primitivos\r\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\r\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\r\n *\r\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\r\n * debemos comenzar por el principio.\r\n */\r\n\r\n/* \r\nEsto es lo que me dijo ChatGPT al preguntar sobre el sitio oficial de Javascript =>\r\n\r\nEl lenguaje de programación JavaScript no tiene un sitio web oficial único y exclusivo, ya que es un lenguaje de programación de código abierto mantenido por la comunidad y está estandarizado por el organismo ECMA International. Sin embargo, hay recursos importantes relacionados con JavaScript que son muy utilizados y ampliamente reconocidos:\r\n\r\nDocumentación oficial de JavaScript (MDN Web Docs): Este es uno de los recursos más completos y confiables para aprender sobre JavaScript. Puedes encontrar la documentación en el siguiente enlace: MDN Web Docs - JavaScript https://developer.mozilla.org/en-US/docs/Web/JavaScript\r\n\r\nSitio web de ECMAScript: ECMAScript es el estándar en el que se basa JavaScript. El sitio web de ECMAScript proporciona información sobre las especificaciones actuales y anteriores del lenguaje: ECMAScript https://tc39.es/\r\n\r\nSitio web de Node.js: Node.js es un entorno de ejecución de JavaScript en el lado del servidor. Su sitio web oficial es una fuente valiosa de información y recursos para desarrolladores de Node.js: Node.js https://nodejs.org/en\r\n\r\nSitio web de npm (Node Package Manager): npm es el gestor de paquetes más grande del ecosistema JavaScript. Su sitio web es una referencia importante para buscar, compartir y administrar paquetes de software para Node.js: npm https://www.npmjs.com/\r\n\r\nEstos son algunos de los recursos más relevantes para los desarrolladores que trabajan con JavaScript. \r\n\r\nY esto agrego yo:\r\nOtro que es bastante útil es https://www.w3schools.com/js/default.asp\r\n*/\r\n\r\n//Este es un single line comment o comentario de una sola linea\r\n\r\n/*\r\nEste es un multi-line comment \r\no comentario de múltiples líneas\r\n*/\r\n\r\n//Variables con var y let\r\nvar variableCreadaConVar;\r\nlet variableCreadaconLet;\r\n\r\n//Constante\r\nconst CONSTANTE = \"debo Inicializar las constantes con un valor\";\r\n\r\n//Datos primitivos\r\n//Javascript es un lenguaje dinámico con tipos dinámicos.\r\n//Las variables no son asociadas con un tipo en particular y se pueden reasignar con valores de otro tipo.\r\n//Es weakly typed por lo que permite conversion de tipo de manera implícita.\r\n\r\n/*Los tipos de datos primitivos son:\r\n  1. String\r\n  2. Number\r\n  3. Bigint\r\n  4. Boolean\r\n  5. Undefined\r\n  6. Null\r\n  7. Symbol\r\n  8. Object\r\n*/\r\n\r\nlet varString = \"Esta es una variable de tipo String\";\r\nlet varNumber = 125.63; //Esta es una variable de tipo number\r\nlet varBigint = 123654789741258963n;\r\nlet varBoolean = true;\r\nlet varUndefined = undefined;\r\nlet varNull = null;\r\nlet varSymbol = Symbol();\r\nlet varObject = { prop1: 1, prop2: \"dos\" };\r\n\r\nelNombreDeMiLenguaje = \"Javascript\";\r\nconsole.log(`¡Hola, ${elNombreDeMiLenguaje}!`);\r\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/eulogioep.js",
    "content": "// URL del sitio web oficial de JavaScript\n// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Diferentes formas de crear comentarios en JavaScript:\n\n// 1. Comentario de una línea\n\n/*\n   2. Comentario \n   de varias \n   líneas\n*/\n\n/**\n * 3. Comentario de documentación\n * Usado frecuentemente para describir funciones y clases\n */\n\n// Creación de una variable\nlet miVariable = \"Soy una variable\";\n\n// Creación de una constante\nconst MI_CONSTANTE = \"Soy una constante\";\n\n// Variables representando tipos de datos primitivos en JavaScript\n\n// String (cadena de texto)\nlet cadena = \"Hola, mundo\";\n\n// Number (número)\nlet entero = 42;\nlet decimal = 3.14;\n\n// Boolean (booleano)\nlet verdadero = true;\nlet falso = false;\n\n// Undefined (indefinido)\nlet indefinido;\n\n// Null (nulo)\nlet nulo = null;\n\n// Symbol (símbolo)\nlet simbolo = Symbol(\"descripción\");\n\n// BigInt (entero grande)\nlet enteroGrande = BigInt(9007199254740991);\n\n// Imprimir por terminal\nconsole.log(\"¡Hola, JavaScript!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/evaristojs.js",
    "content": "// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Esta es la forma de representar un comentario en una sola línea\n\n/* Esta es la forma de representar un comentario en varias líneas */\n\n// Variables y Constantes\nvar name = 'Pedro'\nlet name = 'Juan'\nconst ten = 10\n\n// Datos primitivos\nlet lastname = 'López' // String\nlet age = 25 // Number\nlet isMale = true // Boolean\nlet address // Undefined\nlet stockAvailble = null // null\nlet myBigInt = 2343n // BigInt\nlet mySymbol = Symbol('unique') // Symbol\n\n\nconsole.log(\"Hola, JavaScript\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/faga01.js",
    "content": "// Punto 1. Sitio de la documentacion oficial de JavaScript\n// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n\n// Punto 2.\n// Comentarios en una (1) Linea\n\n/*\nComentarios de varias lineas \n*/\n\n\n// Punto 3. Se representan las 3 formas de tipos de variables.\n// No se declara la variable, se declaran automaticamente. Por buenas practicas de programación se deben declarar las variables.\nx = 33;\n// Variable con la palabra reservada var, se puede modificar su contenido y es de scope global.\nvar string = \"Texto\";\n// Variable con la palabra reservada let, se puede modificar su contenido y es de scope local.\nlet number = 8;\n// Variable con la palabra reservada const, no se puede modificar su contenido y es de scope local.\nconst bool = true;\n\n\n// Punto 4.\n// Se declara una variable de tipo number(Número entero)\nlet int = 10;\n// Se declara una variable de tipo string(cadena de texto)\nlet str = \"cadena de texto\";\n// Se declara una variable de tipo Booleano(Booleabi)\nlet boolean = true;\n// Se declara una variable de tipo undefined(indefinido)\nlet indefined;\n// Se declara una variable de tipo Null(Nulo)\nconst nulo = null;\n// Se declara una variable de tipo object(objeto)\nconst objeto = {color:\"Amarillo\", unidad:11, puesto: 1};\nconst arreglo = [\"primero\", \"campeon\", 1];\n\n\n// Punto 5.\n// Imprimir en el Dom y en consola\nconsole.log(\"objeto\");\ndocument.write(\"nulo\");\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/farthaz.js",
    "content": "/* https://developer.mozilla.org/en-US/docs/Web/JavaScript este no es el sitio oficial de JS\r\nsegun internet, no posee un sitio como tal y esta es la principal fuente de consulta (documeentacion*/\r\n\r\n// Variables\r\nvar number = 20//este valor puede cambiar y solo se utiliza en navegadores viejos\r\nlet value = BigInt(\"1234567890123454756564968684\")\r\nlet money = null\r\n\r\nconst text = \"JavaScript\" //constantes, no pueden cambiar\r\nconst question = true\r\nconst fruits = [\"bananas\", \"apples\", \"pears\"]\r\nconst employeeId = {firstName: \"Alicia\", lastName: \"Gomez\", ID: \"1566\", department:\"IT\", shift: \"Fixed\"}\r\nconst d = new Date()\r\n\r\nconsole.log(\"Hola,\", text)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/fdcorreadev.js",
    "content": "/**\n * https://nodejs.org/en\n * https://developer.mozilla.org/es/docs/Web/JavaScript\n * \n * comentario con descripciones lagras asi como bullets, viñetas\n * Tambien se puede escribir como puede recibir paramtros y que retorna o para lo que quieras describir\n * \n * @param {string}\n * @return {object}\n * \n */\n\n\n/* \n esta es otra forma de realizar comentarios\n*/\n\n// tambien existe el cometario por linea\n\n//---------------------------------------------TIPOS DE DATOS--------------------------------------------------------------\n\n// DATOS PRIMITIVOS\n\n//string\nvar  string  = 'primer variable'\nlet stringLet = \"segunda variable\"\nconst stringConst = `tercer string`\n\n//number\nvar number = 0\nconst float = 25.9\n\n//boolean\nvar boolean = true\n\n//undefined\nlet noDefinido  =  undefined\n\n//null\nconst isNull = null\n\n//symbol- valor unico\nlet simboloUnico = Symbol('único')\n\n//bigint-datos grandes\nlet datosGrandes  = 2n\n\n// imprimir algo en consola\nconsole.log(\"¡Hola, JavaScript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/felipeDev303.js",
    "content": "// Documentación\n\n// Los estándares de javascript los escuentras aquí: https://www.ecma-international.org/publications/standards/Ecma-262.html\n// Documentación de Javascript en español: https://developer.mozilla.org/es/docs/Web/JavaScript\n// Manz.dev tiene un recurso que también puede ayudar https://lenguajejs.com/\n\n// SINTAXIS\n\n// Este es un comentario de una sola línea en JavaScript y se utilizan principalmente para explicar el porqué no el cómo\n\n/* Si prefieres puedes utlizar este tipo sintaxis \npara crear un comentario de varias líneas \nEs útil en el caso de que quieras \"esconder\" \ncódigo y no tener que borrarlo*/\n\n/* Crear una variable en JavaScript se hace con la palabra reservada var y let, \nse escriben en minúsculas, se usa camelCase y se pueden modificar */\nvar nombreDesarrollador = \"Felipe\";\nvar edadDesarrollador = 35;\nvar lenguajeDesarrollador = \"JavaScript\";\n\nlet nombreDesarrollador = \"Felipe\";\nlet edadDesarrollador = 35;\nlet lenguajeDesarrollador = \"JavaScript\";\n\n/* Crear una constante en JavaScript se hace con la palabra reservada const, \nse escriben en mayúsculas y no se pueden modificar */\nconst NOMBRE_DESARROLLADOR = \"Felipe\";\nconst EDAD_DESARROLLADOR = 35;\nconst LENGUAJE_DESARROLLADOR = \"JavaScript\";\n\n// Tipos de datos primitivos en JavaScript\n// 1. String: cadena de texto\nvar nombreDesarrollador = \"Felipe Morales\";\n\n// 2. Number: números enteros o decimales (javascript no diferencia entre enteros y decimales)\nvar edadDesarrollador = 35;\n\n// 3. Boolean: verdadero o falso\nvar esDesarrollador = true;\n\n// 4. Undefined: Variable declarada pero sin valor\nvar lenguajeDesarrollador;\n\n// 5. Null: Valor nulo que representa la ausencia intencionada de un objeto\nvar lenguajeDesarrollador = null;\n\n// 6. Symbol: Tipo de dato cuyas instancias son únicas e inmutables\nvar simbolo = Symbol();\n\n// 7. BigInt: Tipo de dato numérico que permite representar números enteros de longitud arbitraria, mayor que 2^53 - 1\nvar numeroGrande = 1234567890123456789012345678901234567890n;\n\n// Imprime en consola el texto: \"¡Hola [Lenguaje de programación]!\"\nconsole.log(\"¡Hola, \" + lenguajeDesarrollador + \"!\"); // concatenación de strings\nlet lenguajeDesarrollador = \"JavaScript\"; // reasignación de variable\nconsole.log(`¡Hola, ${lenguajeDesarrollador}!`); // template string\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/fernandog25.js",
    "content": "// https://www.javascript.com/\n\n// Primer commentario\n/* Segundo comentario */\n\nvar x = 1\nvar y= \"¡Hola, Javascript!\"\nvar z = true\nvar a = null\nvar b\nvar c = 10000n\nvar d = Symbol()\nvar e = Function()\n\nconst f = 3.14\n\nconsole.log(\"los tipos de variables que hay en JS son: \\n\" \n                + typeof x + \", \" + typeof y + \", \" + typeof z + \", \" + typeof a + \", \" + typeof b + \", \" \n                + typeof c + \", \" + typeof d + \", \" + typeof e)\n\nconsole.log(\"\\nUn ejemplo de una constante es el número pi que se aproxima a \" + f + \"\\n\")\n\nconsole.log(y);\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/fidelysla.js",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n\n// Pagina Web: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Este es un comentario de una linea\n\n/*\nEsto es un comenterio\nde varias lineas\nque puedes hacer\nen JS\n*/\n\n\n// Variables\n\nlet myVariable = \"Hello Word\"\nconst MY_CONST = \"Soy una constante\"\n\n// Datos Primitivos\n\nlet myString = \"Hello\";\nlet myNumber1 = 123, myNumber2 = 123.4;\nlet myBool1 = true, myBool2 = false;\nlet myNull = null;\nlet myUndefined;\nlet myNaN1 = NaN, myNaN2 = \"hola\" * 3.7\nlet mySymbol = Symbol();\n\n// Saludo\n\nconsole.log(\"¡Hola, JavaScript\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/fiedri.js",
    "content": "// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// comentario de una sola linea\n\n/*\n * Este es un comentario\n * De varias lineas\n */\n\n// Variables y Constantes\nlet miVariableModificable = \"Puedo cambiar\";\nconst MI_CONSTANTE = \"Soy inmutable\";\n\n// Tipos de Datos Primitivos\nlet texto = \"JavaScript\";// String\nlet numero = 28;// Number\nlet esVerdadero = true;// Boolean\nlet noDefinido;// Undefined\nlet esNulo = null;// Null\nlet simbolo = Symbol('id');// Symbol\nlet numeroGrande = 9007199254740991n;// BigInt\n\n\nconsole.log(\"¡Hola, \" + texto + \"!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/francescoalterio.js",
    "content": "/* Javascript no cuenta con un sitio oficial pero podemos encontrar una gran documentacion en: \nhttps://developer.mozilla.org/en-US/docs/Web/JavaScript */\n\n// Comentario de una linea\n/* Comentario de varias lineas */\n\nlet varaible = 20;\nconst CONSTANTE = \"Hola Mundo\";\n\n// Tipos de datos primitivos\nconst MyString = \"Hola Mundo\";\nconst MyNumber = 20;\nconst MyBoolean = true;\nconst MyBigInt = BigInt(\"1234567890123454756564968684\");\nconst MyNull = null;\nconst MyUndefined = undefined;\nconst MySymbol = Symbol(\"Hola Mundo\");\n\nconsole.log(\"Hola, Javascript\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/francisoRocha.js",
    "content": "// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n//ESTE ES UN COMENTARIO DE UNA LINEA\n\n/*\n    ESTE ES \n    UN COMENTARIO \n    DE\n    MULTIPLE LINEA\n*/\n\n//variables\nlet nombre = 'Francisco';\nlet edad = 25;\n\n//Constante\nconst apellido = 'Rocha';\nconst ID = 123456;\n\n//Datos primitivos\nlet numero = 10;\nlet booleano = true;\nlet cadena = 'Hola soy francisco';\nlet nullType = null;\nlet undefinedType = undefined;\nlet simbolo = Symbol('Este es un simbolo');\n\n//Imprimir el nombre del lenguaje de programacion que se esta aprendiendo\n\nconst lenguaje = 'JavaScript';\n\nconsole.log(`Hola soy ${nombre} y estoy aprendiendo ${lenguaje}`);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/francomoreira.js",
    "content": "/*\nEJERCICIO:\n 1. - Crea un comentario en el código y coloca la URL del sitio web oficial del\n      lenguaje de programación que has seleccionado.\n 2. - Representa las diferentes sintaxis que existen de crear comentarios\n      en el lenguaje (en una línea, varias...).\n 3. - Crea una variable (y una constante si el lenguaje lo soporta).\n 4. - Crea variables representando todos los tipos de datos primitivos\n      del lenguaje (cadenas de texto, enteros, booleanos...).\n 5. - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\n*/\n\n\n// 1 . https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// 2 . para comentario en una linea\n\n/* para comentarios \nmultilineas\nes asi */\n\n// 3.\n\nlet lenguaje = 'Javascript';\nconst CONSTANTE = 'se declara si o si con un valor';\n\n\n// 4.\n\nlet string = 'cadenas de texto';\nlet number = 5;\nlet booleanos = true\nlet bigInt = 123456789n;\nlet nullType = null;\nlet undefinedType = undefined;\nlet simbolito = Symbol('mi-simbolo');\n\n// 5.\n\nconsole.log(`¡Hola, ${lenguaje}`);"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/frankqv.js",
    "content": "// 🌐 URL oficial del lenguaje de programación JavaScript (creado en 1995)\n// 🦊 https://developer.mozilla.org/es/docs/Web/JavaScript \n// 📖 Especificación oficial de ECMAScript: https://262.ecma-international.org/14.0/\n// (La base estándar para el desarrollo de JavaScript)\n\n\n// 🧐 Sabías que...\n// - Fue creado en ¡10 días! por Brendan Eich mientras trabajaba para Netscape.\n// - Su nombre original era \"Mocha\", luego \"LiveScript\", antes de ser rebautizado como \"JavaScript\".\n// - Aunque su nombre sugiere relación con Java, no tienen nada que ver (puro marketing).\n\n\n// 📝 Comentario de una sola línea\nconsole.log(\"Este es un ejemplo de comentario de una sola línea.\");\n\n/*\n * Comentario de varias líneas:\n * JavaScript puede usarse tanto en el navegador como en el servidor\n * (¡gracias a Node.js desde 2009!).\n * Su flexibilidad lo ha convertido en uno de los lenguajes más populares del mundo.\n */\n\n\n\n// Declaración de una variable \nlet variable = \"el valor puede variar cuantas veces quiera\";\n\n// Declaración de una constante (su valor no cambia)\nconst CONSTANTE = \"Valor inmutable\";\n\n// Declarando variables de todos los tipos de datos primitivos\nlet cadenaDeTexto = \"Soy un texto\"; // String\nlet numeroEntero = 42; // Number (entero)\nlet numeroDecimal = 3.14; // Number (decimal)\nlet booleano = true; // Boolean\nlet indefinido; // Undefined\nlet nulo = null; // Null\nlet simbolo = Symbol(\"simbolo\"); // Symbol (ES6+)\n\n\n\n// Imprimir por terminal el texto \"¡Hola, JavaScript!\"\nconsole.log(\"¡Hellouw JavaScript!\");\n\n// Extra: Ejemplo de un objeto y un array (no son primitivos, pero son importantes)\nlet objeto = { clave: \"valor\" }; // Object\nlet arreglo = [1, 2, 3, \"cuatro\"]; // Array\n\n// Mostramos todas las variables por consola\nconsole.log(\"Variables de tipos primitivos:\");\nconsole.log(\"Cadena de texto:\", cadenaDeTexto);\nconsole.log(\"Número entero:\", numeroEntero);\nconsole.log(\"Número decimal:\", numeroDecimal);\nconsole.log(\"Booleano:\", booleano);\nconsole.log(\"Indefinido:\", indefinido);\nconsole.log(\"Nulo:\", nulo);\nconsole.log(\"Símbolo:\", simbolo);\n\n// Extra: Mostramos el objeto y el array\nconsole.log(\"Objeto:\", objeto);\nconsole.log(\"Arreglo:\", arreglo);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/fravelz.js",
    "content": "\n// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Comentario de una sola linea\n\n/*\nComentario de\nvarias lineas\n*/ \n\nvar varName = \"Valor de la variable\";\nconst CONSTANTE = \"Valor de la constante\";\n\nvar numberType = 7_799; //7799 con guion bajo para mejor lectura\nvar bigInt = BigInt(9007199254740991); // Numero grande\n\nvar booleanType = false;\nvar stringType = \"string\";\n\nvar nullType; // null por defecto\nvar undefinedTipe = undefined; // undefined solo al colocarlo explicitamente\n\nconst symbolType = Symbol(); // Tipo de dato simbolo\n\nconsole.log (\"Hola, JavaScript\");\n\n// > Autor: Fravelz\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/frcan89.js",
    "content": "// https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n// Comentarios de una sola línea\n\n/*\n    Comentario de\n    multiples\n    lineas\n*/\n\nvar myName = 'Ferney';\nlet name = 'Ferney';\nconst age = 30; \n\n// Tipos de datos primitivos\n\nlet texto = 'Hola mundo'; //ejemplo de String\nlet numero = 20; //ejemplo de Number\nlet esVerdadero = true; //ejemplo de Boolean\nlet indefinido = undefined; //ejemplo de Undefined\nlet nulo = null; //ejemplo de Null\nlet simbolo = Symbol('descripcion'); //ejemplo de Symbol\nlet bigint = 9007199254740992n; //ejemplo de BigInt\n\nconsole.log('¡Hola, JavaScript!');"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/fzcarlitos.js",
    "content": "// https://www.javascript.com/\n\n// Comentario en una linea\n\n/*Comentario \nen varias lineas*/\n\nlet variableNombre = Carlos;\nvar variableApellido = Fernandez;\nconst constanteEdad = 31; // Definición de Variables utilizando Let y Var, y Constante utilizando const.\n\nlet string = \"cadena de texto\"; // Variable que define una cadena de texto.\n\nlet numero = 1; //Variable que define un numero entero.\n\nlet booleanoTrue = true;\nlet booleanoFalse = false; //Variable que define booleanos True y False.\n\nlet indefinido = undefined; // Variable que define dato undefined.\n\nlet nulo = null; //Variable que define dato primitivo null.\n\nconsole.log (\"Hola, Javascript!\") //Imprime en consola \"Hola, Javascript!\""
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/gamitocu.js",
    "content": "/*\n  - Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n*/\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n/*\n  - Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n*/\n// Esto es un comentario en una linea\n/* \n  Esto es un comentario en varias lineas:\n  Linea 1\n  Linea 2\n*/\n\n/*\n  - Crea una variable (y una constante si el lenguaje lo soporta).\n*/\n// Declara una variable, opcionalmente la inicia a un valor.\nvar name = 'Nombre';\n// Declara una variable local con ámbito de bloque, opcionalmente la inicia a un valor.\nlet surname = 'Apellido';\n// Declara un nombre de constante de solo lectura y ámbito de bloque.\nconst PI = 3.14;\n\n/*\n  - Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n*/\nlet string = 'test';\nlet numr = 123;\nlet float = 1.5;\nlet bool = true;\nlet test = null;\nlet undefined;\n\n/*\n  - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n*/\nconsole.log('¡Hola JavaScript!')\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/garos01.js",
    "content": "// Este es un comentario en una línea.\n//Visita el sitio oficial de JavaScript en: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n/*\nEste es un comentario multilinea.\nPuedes usar /* para iniciar y \n*/\n\n// Creación de una variable y una constante\nlet miVariable = 10;\nconst MI_CONSTANTE = \"Hola\";\n\n// Variables representando tipos de datos primitivos\nlet cadenaTexto = \"JavaScript!\";\nlet entero = 42;\nlet flotante = 3.14;\nlet booleano = true;\n\n// Imprimir por terminal el texto\nconsole.log(`¡Hola, ${cadenaTexto}`);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/gc796.js",
    "content": "// * EJERCICIO:\n// * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n// *   lenguaje de programación que has seleccionado.\n// * - Representa las diferentes sintaxis que existen de crear comentarios\n// *   en el lenguaje (en una línea, varias...).\n// * - Crea una variable (y una constante si el lenguaje lo soporta).\n// * - Crea variables representando todos los tipos de datos primitivos\n// *   del lenguaje (cadenas de texto, enteros, booleanos...).\n// * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\n// Pagina Web: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Comentario de linea\n\n/*\nComentario\nde\nvarias \nlineas\n*/\n\nlet variable1;\nconst constante = \"Hola\";\n\n// Tipos de datos primitivos\n\n// undefined\nlet undefinedVar = undefined;\n// boolean\nlet booleanVar = true;\n// number\nlet numberVar = 123;\n// string\nlet stringVar = \"Esto es una cadena de texto\";\n// bigint\nlet bigIntVar = 123123123n;\n// symbol\nlet symbolVar = Symbol(\"Valor unico e inmutable\");\n// null\nlet nullVar = null;\n\nconsole.log(\"¡Hola,JavaScript! \");\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/gerardovguzman.js",
    "content": "// https://javascript.com/\n\n// one line comment\n\n/*\nmany \nlines \ncomments\n*/\n\nlet myVar = \"my variable\"\nconst MAX_SPEED = 50\nlet str = \"This is a group of letters\"\nlet bool = false\nlet otherBool = true\nlet int = 5\nlet float = 3.4\n\nconsole.log(\"¡Hola, gerardovguzman!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/gerespinosa.js",
    "content": "// #00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n\n// Web oficial del lenguaje\n// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Tipos de comentario que hay en el lenguaje\n// Esto es un comentario en una línea\n\n// Esto es un comentario en varias líneas y por eso\n// esto es otr línea\n\n// Crear una variable y una constante\nlet miVariable\n\nconst miConstante = 'Hola Mundo'\n\n// Tipos de datos primitivos\nlet miCadena = 'Mi primer string'\nlet miEntero = 9999\nlet miFloat = 9.9999\nlet miBoolean = 'True'\nlet miNull = null\nlet miIndefinido = undefined\nlet miSimbolo = Symbol('esto es un símbolo')\n\n// Imprimir texto por consola\nconsole.log('¡Hola JavaScript!')\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/gianbordon.js",
    "content": "// URL: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Comentario en una sola linea: por ejemplo ---- Section Header ----\n\n// Comentario \n// en varias\n// lineas de \n// codigo \n\nlet nombre;\n\nconst tipoAnimal = \"Pinguino\";\n\nlet edad = 24;\n\nlet estaVivo = true;\n\nlet altura = 1.80;\n\nlet apellido = \"Loodermin\";\n\nlet fechaMuerte = undefined;\n\nlet cantCertificados = null;\n\nconsole.log(\"¡Hola, JavaScript!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/giovanyosorio.js",
    "content": "/* EJERCICIO:\n* - Crea un comentario en el código y coloca la URL del sitio web oficial del\n*   lenguaje de programación que has seleccionado.\n* - Representa las diferentes sintaxis que existen de crear comentarios\n*   en el lenguaje (en una línea, varias...).\n* - Crea una variable (y una constante si el lenguaje lo soporta).\n* - Crea variables representando todos los tipos de datos primitivos\n*   del lenguaje (cadenas de texto, enteros, booleanos...).\n* - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n*\n* ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n* debemos comenzar por el principio.\n*/\n\n//Web official \n//https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// one line for comment\n\n/*\nMultiple lines for comment\n*/\n\n//variables\nvar age=28\nvar city =\"Bogota\"\n\n// constantes\nconst name=\"Giovany\"\n\n//datos primitivos\n\ntypeof \"hola!\" // \"string\"\ntypeof 42 // \"number\"\ntypeof true // \"boolean\"\ntypeof null // \"object\" ???\ntypeof undefined // \"undefined\"\ntypeof Symbol // \"symbol\"\ntypeof 23n // \"bigint\"\n\nvar programmingLanguage=\"JavaScript\"\nconsole.log(`¡Hola, ${programmingLanguage}`)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/glaboryp.js",
    "content": "// Web oficial JavaScript: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Esto es un comentario de una linea\n\n/* \nEsto es \nun comentario\nde varias lineas\n*/\n\nconst nuevaConstante = 'Esto es una constante'\nvar variableOldMode = 'Esto es una variable de la \"vieja escuela\"'\nlet variableNueva = 'Y esto es una variable moderna'\n\ntypeof 'Hola' // \"string\"\ntypeof 12345 // \"number\"\ntypeof true // \"boolean\"\ntypeof null // \"object\" ???\ntypeof undefined // \"undefined\"\ntypeof Symbol // \"symbol\"\ntypeof 23n // \"bigint\"\n\nlet objeto = { nombre: 'Gloria', apellido: 'Labory' }\n\nconst lenguaje = 'JavaScript'\n\nconsole.log(`¡Hola, ${lenguaje}!`)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/gonzadev28.js",
    "content": "/*Escribo un comentario añadiendo la URL oficial\ndel lenguaje de programacion seleccionado.\nWeb oficial de Javascript ----> https://www.javascript.com/ */\n\n//Otro metodo de añadir un comentario\n\n//Igualmente se puede comentar en varias lineas\n//con éste metodo \n\n//Crear variables \n\nlet variable1 = '';\nconst variable2 = '';\n\n//Crear variables con tipo de datos primitivos\n\nlet texto = 'string';\nlet numero = 50;\nlet boolean = true;\nlet boolean2 = false;\nlet nulo = null;\nlet indefinido = undefined;\n\n//Imprimir en el terminal \nconsole.log('Hola, Javascript!');"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/gonzalo-cordoba.js",
    "content": "// 1.\n\n// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Comentario en una linea\n\n/*\n\nComentario\nen\nvarias \nlineas\n\n\n\n*/\n\n// 2.\nvar miVariable1 = 23;\nlet miVariable = 1;\n\nconst miConstante = \"Esta es la constante numero dos\";\n\n// 3.\n\nlet miString = \"Esto es una cadena de texto\";\n\nlet booleanTrue = true;\n\nlet booleanFalse = false;\n\nlet Array = [\n  { id: 1, nombre: \"Juan\" },\n  { id: 2, nombre: \"Pedro\" },\n];\n\nlet number = 7;\n\nlet bigInt = BigInt(324234324234324242);\n\nlet symbol = Symbol();\n\nlet indefinido = undefined;\n\nlet nulo = null;\n\nconsole.log(\"¡Hola, JavaScript!\");\n\nconsole.log(miString, booleanTrue, booleanFalse, Array, number, bigInt, symbol);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/gpinedaoviedo.js",
    "content": "//Sitio web oficial: https://www.javascript.com\n\n/////////////////////////////////////\n//Comentario en una linea\n\n/////////////////////////////////\n/*Comentario en \nmultiples\nlineas */\n\n///////////////////////////////////\n//constante\nconst languajeName = \"JavaScript\";\n\n//variables\nlet num = 88;\nlet text = 'hola, que tal!!';\nlet bool = false;\nlet nullValue = null;\nlet undefinedType = undefined;\n\n///////////////////////////////////////////\nconsole.log(`¡Hola, ${languajeName}!`);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/gustavoguerrero.js",
    "content": "// Documentación: https://developer.mozilla.org/es/docs/Web/JavaScript  \n\n// Una linea de comentario\n/* \n    Comentario para\n    varias lineas\n*/ \n\nlet variable = \"variable\";\n\nconst constante = \"constante\";\n\nlet cadena = \"esta es un String\";\nlet booleano = false;\nlet entero = 123;\n\nlet lenguaje = \"javascript\"\n\nlet array = [1, \"juan\", true];\n\nlet objeto = {\n    nombre: \"Juan\", \n    apellido: \"Perez\", \n    edad: 30, \n    ciudad: \"montevideo\", \n    pais: \"uy\"\n    };\n\nlet arregloDeObjetos = [\n    {\n    nombre: \"Juan\", \n    apellido: \"Perez\", \n    edad: 30, \n    ciudad: \"montevideo\", \n    pais: \"uy\"\n    },\n    {\n    nombre: \"Martín\", \n    apellido: \"Gomez\", \n    edad: 21, \n    ciudad: \"madrid\", \n    pais: \"es\"\n    }\n];\n\n\nconsole.log('\"Hola ' + lenguaje + '!\"');"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/h4ckxel.js",
    "content": "// ? https://developer.mozilla.org/es/docs/Web/JavaScript\n\n'use strict'\n\n// ! Este es un comentario de una sola línea\n\n/*\n * Este es un comentario multiline en JavaScript\n */\n\nvar variableSinRestricciones = \"Hola Mundo\";\nlet variableConRestricciones = \"Hola Mundo\";\nconst constante = \"Hola Mundo\";\n\nlet integer = 10;\nlet float = 10.10;\nlet string = \"Hola, soy Nikolayk!\";\nlet bool = true;\nlet array = [10, 'Bob', true, 10.10];\nlet object = {};\nlet nulo = null;\nlet indefinido = undefined;\nlet symbol = Symbol('symbol');\n\nconst funcionClg = () => {\n    console.log(\"¡Hola, JavaScript!\");\n}\n\nfuncionClg();"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/hatorob.js",
    "content": "// https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n// comentario de una sola línea\n/*\n    comentario de multiple lineas\n*/\n\n//! var is global scope -> not recommend to use\nvar greeting = \"Hello world\";\n//! let is block scope -> is recommend to use\nlet name = \"Alejandro Toro\";\n//! const is global or block scope -> is constant, not variable\nconst baseUrl = \"https://developer.mozilla.org/en-US/docs/Web/JavaScript\";\n\n//! primitive - init\nlet lenguaje = \"Javascript\";\nlet age = 29;\nlet isActive = true;\nlet notValue = null;\nlet noDefined = undefined;\n//! primitive - end\n//! other types - initi\nlet fruits = [\"Manzana\",\"Pera\",\"Sandía\",\"Banano\"];\nlet user = {\n    name: \"Alejandro Toro\",\n    age: 29,\n    userName: \"hatorob\"\n}\n//! other types - end\n\nconsole.log(`¡Hola, ${lenguaje}!`);"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/hectorio23.js",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n// Documentacion oficial de JavaScript: https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\"use strict\";\n\n// Single-line comment\n\n/*\n  This is a\n  multi-line comment\n*/\n\n// Creando una variable, no es necesarios especificar el tipo de dato, pero si el scope; let, var o const\nlet myVariable = \"Hello\";\n\n// Creando una constante\nconst MY_CONSTANT = 10;\n\n// Variables que representan los distintos tipos de datos básicos en JavaScript\nlet stringVariable = \"Hello, JavaScript!\";\nlet integerVariable = 42;\nlet floatVariable = 3.14;\nlet booleanVariable = true;\n\n// Imprimiento un mensaje mediante el terminal\nconsole.log(\"¡Hola, JavaScript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/herwingx-dev.js",
    "content": "//Este es un comentario con la URL del la web oficial de JavaScript:  * https://developer.mozilla.org/es/docs/Web/JavaScript\n\n\n    //Este es un comentario en una linea.\n\n    /*Este es un comentario\n      en varias\n      lineas*/\n\n//Una variable y una constante\n\n    const sol = true\n    let clima = Boolean\n    console.log(sol)\n\n//Variables de datos de tipo primitivo\n\n    let string = \"Esto es una cadena de texto\"\n    let booleano = false\n    let number = 2\n    let numeroGrande = 12165464654654964841651n\n    let float = 15.8\n    let nulo = null\n    let indefinido\n    let simbolo = Symbol (\"Simbolo1\")\n\n//Imprimiendo un mensaje por consola con la palabra Hola y el nombre del lenguaje que estoy utilizando\n\nlet nombreLenguaje = \"JavaScript\"\nconsole.log(\"Hola, \" + nombreLenguaje)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/hfvaronb.js",
    "content": "// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Comentario en una linea\n\n/* \nComentario\nen varias\nlineas\n */\n\n// Representación de los tipos de datos primitivos de JavaScript\nmi_variable = \"Variable\";\nconst PI = 3.14159;\n\nlet ciudad = \"Bogotá\"; // String\nlet telefono = 312457897; // Number\nlet aprobado = true; // Boolean\nlet nulo = null; // Variable sin valor\nlet estado = undefined; // Valor desconocido\nconst unico = Symbol(80123654); // Valores unicos\nconst numeroGrande = 987654321n; // Entero sin limite de tamaño\n\nconsole.log(\"¡Hola, JavaScript!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/imista.js",
    "content": "// #00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n\n//https://www.javascript.com/\n\n//One line\n/*\n    Multiple line\n*/\n\nlet variable;\nconst constant = 1;\n\n// String\nvar textString = \"Hello, world!\";\n// Integer\nvar integer = 42;\n// Floating-point number\nvar decimalNumber = 3.14;\n// Boolean\nvar isTrue = true;\n// Null value\nvar nullValue = null;\n// Undefined value\nvar undefinedValue;\n// Symbol\nvar symbol = Symbol(\"mySymbol\");\n// BigInt\nvar bigint = 9007199254740991n;\n\nconsole.log(\"Hola javascript\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/isaias-alt.js",
    "content": "// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Comentario de una sola linea\n\n/**\n * Comentario de\n * multiples lineas\n */\n\nlet variable = 'Variable'\nconst LANGUAGE = 'JavaScript'\n\nlet stringType = 'string'\nlet numberType = 17\nlet decimalNumber = 3.14\nlet booleanType = false\nlet nullType = null\nlet undefinedType = undefined\n\nconsole.log(`Hola, ${LANGUAGE}!`)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/jacarrillob.js",
    "content": "// https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n// This is a single-line comment\n\n\n/* \nThis is a\nmulti-line comment\n*/\n\nlet variable = \"Hello\" // Variable (can be reassigned)\nvariable = \"World\" // Change value of the variable\n\nconst PI = 3.14  // Constant\n\n\nlet numberVariable = 42\n\nlet stringVariable = \"Hello, World!\"\n\nlet booleanVariable = true\n\nlet undefinedVariable // It's not necessary to initialize\n\nlet nullVariable = null\n\nlet symbolVariable = Symbol(\"description\")\n\nlet bigIntVariable = 9007199254740991n\n\n\nconst language = 'JavaScript'\n\nconsole.log(`¡Hola, ${language}`)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/jacobrwx.js",
    "content": "// https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n// This is a Single-Line Comment.\n\n/* This is a Multi-Line Comment. */\n\nvar varible1;\nlet variable2;\n\nconst VARIABLE_CONST = 11;\n\nlet num = 11;\nlet str = \"Hello, World\";\nlet bool = true;\nlet undef;\nlet n = null;\nconst SYM = Symbol(\"foo\");\n\nconsole.log(\"Hello, Javascript\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/jaimemunozdev.js",
    "content": "// https://developer.mozilla.org/es/docs/Web/JavaScript JavaScript no tiene una página oficial, pero podemos encontrar su documentación en MDN Web Docs de Mozilla\n\n// Comentarios en una línea\n\n/*\nComentarios en\nvarias lineas\n*/\n\nlet variable // Variable nombrada, sin declaración\nconst constante = '' // Constante nombrada, y declarada, ya que si no lo hacemos tendríamos un error\n\n// TIPOS DE DATOS\n\nlet string = 'Cadena de texto'\nlet number = 5\nlet bigInt = 333n\nlet nulo = null\nlet undefined = undefined\nlet boolean = true   // o false\nlet symbol = symbol()\n\nconsole.log('¡Hola, JavaScript!')\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/jaxi86.js",
    "content": "// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n//esta es una forma de comentar.\n\n/** esta es una forma de \n*comentar en varias \n*lineas\n*/\n\n/*esta es otra forma\nde comentar en\nvarias linea*/\n\nlet numero = 30;\nconst nombre = 'jaxi';\n\nlet string = 'string';\nlet number = 11;\nlet boolean = true;\nlet boolean2 = false;\nlet undefined;\nlet nulo = null\nlet simbolo = symbol('yo');\nlet bigint = 6537468565046484688575n;\n\nconsole.log('¡hola, JavaScript!');\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/jd-gm.js",
    "content": "// https://ecma-international.org/\n\n// Comentario de una línea\n\n/* Comentario de \n *  varias líneas \n */\n\n// Creación de una variable\nlet variable = \"¡Hola, mundo!\";\n\n// Creación de una constante\nconst CONSTANTE = \"¡Hola, JavaScript!\";\n\n// Creación de variables con los 7 tipos de datos primitivos\nlet number = 1;\nlet string = \"Hola\";\nlet boolean = true;\nlet BigInt = 1234567890123456789012345678901234567890n;\nlet symbol = Symbol(\"id\");\nlet undefined;\nlet nullValue = null;\n\n// Imprimir saludo en consola\nconsole.log(CONSTANTE);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/jeronimocardu.js",
    "content": "// https://www.javascript.com\n\n/**\n * https://www.javascript.com\n */\n\n/*\nhttps://www.javascript.com\n*/\n\nlet variableLet;\nconst variableConst = 0;\n\nlet string = 'Hola mundo!';\nlet number = 0;\nlet boolean = true;\nlet undefined = undefined;\nlet isNull = null;\n\nconsole.log('¡Hola, JavaScript!')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/jesus30cano.js",
    "content": "// Documentación oficial de JavaScript : https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n// Diferentes sintaxis para crear comentarios en JS\n\n// Una línea: Comienza con '//' y sólo comenta la linea actual desde donde se escribe.\n\n/* Múltiples líneas: Comentarios extensos. \nComienzan por \"/*\" y comentará todo el texto que escribamos hasta que cerremos el comentario con un */\n\n// Variables y Constantes\nlet name = 'Juan'\nconst ten = 10\n\n// Datos primitivos\nlet lastname = 'López' // String\nlet age = 25 // Number\nlet isMale = true // Boolean\nlet address // Undefined\nlet stockAvailble = null // null\nlet myBigInt = 2343n // BigInt\n\nlet mySymbol = Symbol('unique') // Symbol\n// Se utilizan para añadir llaves de propiedades únicas a un objeto que no sean iguales a las claves que cualquier otro código pueda añadir al objeto, y que están ocultas de otro código utilice normalmente para acceder al objeto. \n\nconsole.log(\"Hola, JavaScript\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/jesusWay69.js",
    "content": "/*\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.   \n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"*/\n\n// Comentario en una línea\n\n/*\nComentario\nen varias \nlíneas\n*/\n\nlet myString = \"Javascript\"\nconst myConstString = \"Typescript\"\nlet myNum = 50\nlet myBigNum = 646448546854584368458464n\nlet myFloat = 6.5\nlet myBool = true\nlet myUndef\nlet myNul = null\nconst mySymbol = Symbol('mySymbol')\n\nconsole.log(\"Hola\" + \" \" + myString) // Concatención string\nconsole.log(`Hola ${myConstString}`) // Formateo string\nconsole.log(50 + myNum) // Operiación numérica\nconsole.log(60 + myNum + myConstString + 25) // opera y cuando aparece un string concatena\n\nconsole.group(\"Agrupación de impresiones por consola:\") // Agrupar logs\nconsole.log(`tipo de dato: ${typeof(myString)}, valor: ${myString}`)\nconsole.log(`tipo de dato: ${typeof(myConstString)}, valor: ${myConstString}`)\nconsole.log(`tipo de dato: ${typeof(myNum)}, valor: ${myNum}`)\nconsole.log(`tipo de dato: ${typeof(myBigNum)}, valor: ${myBigNum}`)\nconsole.log(`tipo de dato: ${typeof(myFloat)}, valor: ${myFloat}`)\nconsole.groupEnd() // Fin del grupo de logs\n\nconsole.log(`tipo de dato: ${typeof(myBool)}, valor: ${myBool}\ntipo de dato: ${typeof(myUndef)}, valor: ${myUndef}\ntipo de dato: ${typeof(myNul)}, valor: ${myNul}\ntipo de dato: ${typeof(mySymbol)}, valor: ${mySymbol.description}\n`) //Impresión en varias líneas con un solo console.log\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/jfigueroa24.js",
    "content": "// https://www.javascript.com/\n// comentario en una linea\n\n/*\n  comentario en varias lineas\n*/\n\ncadenaDeTexto = \"Hola\";\nvar numeroPar = 6;\nlet decimal = 6.5;\nconst PI = 3.1416;\nesVerdadero = true;\ncadenaDeTexto = \"Nuevo Hola\";\notraCadenaDeTexto = \"Nuevo Hola\";\nconsole.log(\"Hola Mundo\");\nconsole.log(typeof numeroPar);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/jhonf1992.js",
    "content": "// JavaScript sitio oficial \n// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Como realizar comentarios:\n\n// Con dos lineas diagonales podremos crear comentarios de una linea //\n\n/* Tambien podemos crear comentarios \nde multiples lines solo debemos abrir el\ncomentario con barra inclinada asterisco \n/* y cerrarlo con asterisco barra inclinada */  \n\n// Variables y constantes \nvar name = jhon;\nlet number = 2;\nconst number2 = 5;\n\n// Datos primitivos \n\nlet string = 'Esto es un string', // String\nlet number = 25;   // Number\nlet boolean = true;  // Boolean\nlet nulo = null;  // Dull\nlet undefined;  // undefined\nconst uniqueId = Symbol('id'); // Symbol\nlet bigInt = 325214241214613246131215412; // BigInt\n\nconsole.log(\"¡Hola, JavaScript\");\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/jhoshmc.js",
    "content": "/*\n? EJERCICIO:\n* - Crea un comentario en el código y coloca la URL del sitio web oficial del\n*   lenguaje de programación que has seleccionado.\n* - Representa las diferentes sintaxis que existen de crear comentarios\n*   en el lenguaje (en una línea, varias...).\n* - Crea una variable (y una constante si el lenguaje lo soporta).\n* - Crea variables representando todos los tipos de datos primitivos\n*   del lenguaje (cadenas de texto, enteros, booleanos...).\n* - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n*\n* ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n* debemos comenzar por el principio.\n*/\n\n//* sitio web: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n//* este es un comentario de una sola linea, puesto por dos barras\n/*\n * este es el comnetario\n * de varias líneas,\n * puesto entre una barra y un asteristo\n * y cerrado con un asterisco y una barra\n */\n//* esta es un variable, puede ser de culquier tipo, ya sea real, flotante, string,etc;\nlet variable = 1;\n//* esta es una variable constante, algo que no se va a cambiar a lo largo del código\nconst variableConstante = 3.14;\n\nlet entero = 10;\nlet real = 1.5;\nlet booleano = true;\nlet doble = 1.563356;\nlet caracter = \"a\";\nlet palabra = \"¡hola javaScript!\";\nlet array = []; // este es un array vacio\n\nconsole.log(palabra);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/joapalobael.js",
    "content": "// #1 - Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado:\n// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n/* #2 - Representa las diferentes sintaxis que existen de crear comentarios\nen el lenguaje (en una línea, varias...).*/\n\n//#3 - Crea una variable (y una constante si el lenguaje lo soporta).\nlet variable1 = \"Soy un string\";\nconst variable2 = 3;\n\n//#4 Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...)\nconst booleano = true;\nconst nulo = null;\nlet indefinida;\nconst numero= 3;\nconst randomEntero = BigInt(13);\nconst cadenaTexto = \"String // Cadena de texto\";\nconst simbolo = Symbol('claveUnica');\n\n//#5 - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nconsole.log(\"¡Hola, JavaScript!\");\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/johnniew81.js",
    "content": "/*\r\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\r\n * - Recuerda que todas las instrucciones de participación están en el\r\n *   repositorio de GitHub.\r\n *\r\n * Lo primero... ¿Ya has elegido un lenguaje?\r\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\r\n * - Este primer reto te servirá para familiarizarte con la forma de participar\r\n *   enviando tus propias soluciones.\r\n *\r\n * EJERCICIO:\r\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\r\n *   lenguaje de programación que has seleccionado.\r\n * - Representa las diferentes sintaxis que existen de crear comentarios\r\n *   en el lenguaje (en una línea, varias...).\r\n * - Crea una variable (y una constante si el lenguaje lo soporta).\r\n * - Crea variables representando todos los tipos de datos primitivos\r\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\r\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\r\n *\r\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\r\n * debemos comenzar por el principio.\r\n */\r\n\r\n// --------------------------- Crea un comentario en el código y coloca la URL del sitio web oficial del ------------------------------------//\r\n\r\n// JavaScript - https://developer.mozilla.org/es/docs/Web/JavaScript\r\n\r\n// ------------------------------ Representa las diferentes sintaxis que existen de crear comentarios --------------------------------------//\r\n\r\n// Comentaro en una linea\r\n\r\n/* comentario en \r\nvarias\r\nlineas\r\n*/\r\n\r\n// ---------------------------------- Crea una variable (y una constante si el lenguaje lo soporta) ------------------------------------------//\r\n\r\nvar saludo = \"Hola\"; // en desuso\r\nlet despedida = \"Adios\";\r\nconst saludoDespedida = \"Hola y adios\";\r\n\r\n// -------------------------------- Crea variables representando todos los tipos de datos primitivos ----------------------------------------//\r\n\r\n// String\r\nlet string = \"Cadena de texto\";\r\n// Number\r\nlet number1 = 5; //entero\r\nlet number2 = 5.5; //decimal\r\n// Booleano\r\nlet boolean1 = false;\r\nlet boolean2 = true;\r\n//NULL\r\nlet datoNull = null;\r\n//UNDEFINED\r\nlet noDefinido = undefined;\r\n//BIGINT\r\nlet bigInt = 50n;\r\n//SYMBOL\r\nlet simbol = Symbol(\"whaterver\");\r\n\r\n// ------------------------------- Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\" ---------------------------------------//\r\n\r\nconsole.log(\"Hola JavaScript\");\r\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/jolimadev2.js",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\nconst moureDev = \"Excelente creador de Contenido y Dev para la comunidad Hispana\"\n\nvar pepe = \"Jose\" //string\nlet dosmilVeinticinco = true // boolean\nconst num = 2025\nvar frutas = [\"manzana\", \"pera\", \"banana\", \"kiwi\"] // array\nlet any = undefined //undefined\nlet bigInt = 123454646434354564648646546n //bigInt\n\nconsole.log(\"!Hola, Javascript!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/jorgeSilencio.js",
    "content": "//Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n// Documentación URL: https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n\n\n\n// Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n\n// 1) Comentario de una línea\n\n// 2) \n/* Comentario\nde varias\nlíneas */\n\n\n\n\n// Crea una variable (y una constante si el lenguaje lo soporta).\n\n// Variables en Javascript\nvar numero = 9;\nlet letra = \"A\";\nconst texto = \"Hola\";\n\n// También se pueden escribir varias variables separadas por comas.\nlet numero = 1, numero2 = 2, numero3 = 3;\n\n\n\n\n\n // Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...)\n\n // TIPOS DE DATOS\n\n// String\nlet saludo = \"Hola Mundo\";\n\n// Number\nlet entero = 135;\nlet flotante = 1.54;\n\n// BigInt\nlet numeroGrande = 1238734534863143n;\nlet numeroGrande2 = BigInt(1237653465713654);\n\n// Boolean\nlet booleano1 = true;\nlet booleano2 = false;\n\n// Null\nlet nulo = null;\n\n// Undefined\nlet indefinido = undefined;\n\n// NaN\nlet notANumber = \"Hola1\" * \"Hola2\";\n\n// Array\nlet arreglo = ['Elemento1', 'Elemento2', 'Elemento3', true, false, {propiedad1: 'valor1'}];\n\n// Object\nlet objetos = {\n    nombre: 'Jorge',\n    apellido: 'Silencio',\n    edad: 40,\n    suscrito: true,\n    tipoDeSuscripcion: {\n        github: true,\n        youtube: true,\n    }\n}\n\n\n\n\n// Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nconsole.log(\"¡Hola Javascript!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/joseptarres.js",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n// EJERCICIOS\n\n// - Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n// El lenguaje de programación seleccionada es Javascript y el sitio web oficial de este lenguaje es https://developer.mozilla.org/es/docs/Web/JavaScript. También \n// podemos encontrar información normativa en https://262.ecma-international.org/5.1/#sec-4.2\n\n// - Representa las diferentes sintaxis que existen de crear comentarios\n// Podemos crear 2 tipos de comentarios: \n// 1. Comentario de una linea: \n// Comentario de una linea\n// 2. Comentarios de varias lineas:\n/* Esto es un comentario\nde varias lineas */\n\n// - Crea una variable (y una constante si el lenguaje lo soporta).\nlet a = 2\nconst b = 3\n\n// - Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\nlet c = 4\nlet d = 'Hola'\nlet e = true\nlet f = undefined\nlet g = null\nlet h = Symbol('a')\n\n// - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nconsole.log('¡Hola, Javascript!')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/joshbaez.js",
    "content": "//  https://www.javascript.com/\n\n// comentario de una linea \n/**\n * comentario de varias lineas\n*/\n \nlet myAge = 21;\nconst myName = 'josh'\nlet myNumber = 33;\nlet MyStrin = 'hola';\nlet falso = false;\nlet noDefinido;\nlet nulo = null; \n\n\nconsole.log('hola javascript');\nconsole.log(`tengo ${myAge} anos`);\nconsole.log(`mi nombre es ${myName}`);\nconsole.log(`${myNumber} es un numero`);"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/jpiacaruso.js",
    "content": "// Link del sitio oficial de Javascript https://www.javascript.com/\n\n// Este es un comentario de una sola linea //\n\n/* Este \nes\nun comentario\nde multiples\nlineas */\n\n// Variable Antigua\nvar variableantigua = \"Antigua\"; // CASI NI SE USA\n\n// Variable Modernas\nlet lenguaje = \"javascript\"; // CUANDO LA VARIABLE PUEDE SER REDEFINIDA MAS ADELANTE.\nconst numeroElegido = 25; // CUANDO SABEMOS QUE NO DEBE CAMBIAR \"SE RECOMIENDA\".\n\n// Tipos de variables en Javascript\n\nlet string = \"string\"; // STRING\nlet altString = \"altString\";\nlet numeroEntero = 12; // NUMERO ENTE RO\nlet numeroFlotante = 1.68; // NUMERO FLOTANTE\nlet booleanoVerdadero = true; // BOOLEANO\nlet booleanoFalso = false; // BOOLEANO\n\n// Objeto en JS\n\nlet objeto = {\n  nombre: \"Juan Pablo Iacaruso\",\n  edad: 35,\n  pais: \"Argentina\",\n};\n\n// Arreglo en JS\n\nlet arreglo = [\n  \"Lunes\",\n  \"Martes\",\n  \"Miercoles\",\n  \"Jueves\",\n  \"Viernes\",\n  \"Sabado\",\n  \"Domingo\",\n];\n\n// Consola de salida\n\nconsole.log(\"Hola, \" + lenguaje + \"!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/jrcoste6.js",
    "content": "//Ejercicio #00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO;\n\n//Sitio Web Oficial de JavaScript: https://developer.mozilla.org/es/docs/Web/JavaScript;\n\n//Formas de crear comentarios en JavaScript;\n\n    //#1 Usando el caracter \"Slash\" de forma duplicada y seguida al inicio de la línea de código, solamente para una efectuar una línea de comentario.\n\n    /*#2 Usando el caracter \"Slash\" y \"Asterisk\" lo cual permite plasmar el comentario en forma de varias\n    *lineas como está viendose en este ejemplo*/;\n\n    /*#3 Bonus: Según la documentación oficial de JavaScript, hay una tercera forma de declarar un \n    *comentario, el cual es el comentario Hashbang, y se usa para especificar la ruta de un motor de\n    *JavaScript en particular.*/;\n\n/* VARIABLES Y FORMAS DE DECLARARLAS EN JAVASCRIPT\n\n    Con la palabra reservada VAR\n    Con la palabra reservada LET\n    Con la palabra reservada CONST\n*/\n\nvar letras = \"ABC\";\nlet numeros = \"1,2,3\";\nconst PI = 3.14;\n\n/* TIPOS DE DATOS\n\n    1- Booleano. true y false.\n    2- null. Una palabra clave especial que denota un valor nulo. (Dado que JavaScript distingue entre mayúsculas y minúsculas, null no es lo mismo que Null, NULL o cualquier otra variante).\n    3- undefined. Una propiedad de alto nivel cuyo valor no está definido.\n    4- Number. Un número entero o un número con coma flotante. Por ejemplo: 42 o 3.14159.\n    5- BigInt. Un número entero con precisión arbitraria. Por ejemplo: 9007199254740992n.\n    6- String. Una secuencia de caracteres que representan un valor de texto. Por ejemplo: \"Hola\"\n    7- Symbol (nuevo en ECMAScript 2015). Un tipo de dato cuyas instancias son únicas e inmutables\n    8- Object.*/\n\nlet myboolean = true;\nlet mynull = null;\nlet myUndefined = undefined;\nlet myNumber = 1234;\nlet myBigInt = 3835853489573827548873461733924n;\nlet myString = \"Hola\";\nlet mySymbol =  Symbol();\nlet myObject = {\n    name: \"Junior\",\n    edad: 36,\n    sexo: \"Masculino\"\n\n}\n\nconsole.log(\"¡Hola, JavaScript!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/jrincondev.js",
    "content": "// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Comentario en una linea\n\n/*\nComentario en\nvarias lineas\n*/\n\n// Variable - Constante\nlet myVariable = 'Mi variable';\nconst myConstante = 'Mi constante';\n\n// Datos primitivos\n\n// Cadenas de texto\nlet string = 'Esta es mi cadena de texto';\n\n// Numeros enteros y decimales\nlet numberWhole = 23;\nlet numberDecimal = 32.3;\n\n// Numeros grandes\nlet bigint = 2000033334443434n;\n\n// Booleanos\nlet boolean = true;\nlet boolean1 = false;\n\n// Indefinido\nlet undefined;\n\n// Nulo\nlet myNull = null;\n\n// Símbolo\nlet symbol = Symbol('my symbol');\n\n\n// Imprimimos el texto \nconsole.log('¡Hola, JavaScript');"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/jrvdev.js",
    "content": "// Documentacion oficial:  https://developer.mozilla.org/es/docs/Web/JavaScript\n\n//Docuementacion no oficial pero muy util:  https://es.javascript.info/\n\n// Comentario en una linea\n\n/*\nComentario\nen varias \nlineas */\n\n// Variables y constantes\nvar numero1 = 1; // forma vieja\nlet numero2 = 2; // forma nueva\nconst CONSTANTE = \"Hola\";\n\n// tipos de datos primitivos\n\nlet numberInteger = 20;\nlet numberDouble = 20.5;\nlet cadena = \"texto\";\nlet boolean = true;\nlet undefined;\nlet numberMayor = BigInt(9999399939393);\nlet symbol = Symbol(\"mi simbolo\");\n\nconsole.log(\"Hola JavaScript\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/jsruedatorres.js",
    "content": "/* \nDocumentación de JavaScript:\nhttps://developer.mozilla.org/es/docs/Web/JavaScript\n*/\n\n// Este es un comentario de una línea\n\n/* Este es\nun comentario\nde muchas\nlíneas */\n\nlet variableDeTexto = \"Cadena de texto en una variable\"\nconst constanteDeTexto = \"Cadena de texto en una constante\"\n\n// Variables\nlet nombre = \"Juan Sebastián Rueda Torres\" // Texto\nlet edad = 27 // Número entero\nlet altura = 1.64 // Número flotante\nlet soyMayorDeEdad = true // Booleano verdadero\nlet soySenior = false // Booleano falso\nlet vacio = null // Nulo\n\n\nconsole.log(\"¡Hola, JavaScript!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/juandaherrera.js",
    "content": "/*\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\n*/\n\n// Página principal de JavaScript: https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n// Comentario de una línea\n\n/*\nComentario\nde varias líneas\n*/\n\nlet myVariable = \"Juan David\"; // Esta es una variable que puede cambiar\nmyVariable = \"Juan David Herrera\";\n\nconst MY_CONSTANT = \"API_KEY\"; // Esta es una constante que no puede cambiar\n\nlet myInt = 25; // Número entero\nlet myFloat = 1.33; // Número con punto flotante\nlet myBool = true; // Booleano\nlet myString = \"Mi cadena de texto\"; // Cadena de texto\nlet myOtherString = 'Mi otra cadena de texto'; // Otra forma de representar cadenas de texto\nlet myLanguage = \"JavaScript\"; // Nombre del lenguaje\n\nconsole.log(`¡Hola, ${myLanguage}!`); // Imprime un saludo personalizado\n\nconsole.log(typeof myInt); // Imprime el tipo de la variable myInt\nconsole.log(typeof myFloat); // Imprime el tipo de la variable myFloat\nconsole.log(typeof myBool); // Imprime el tipo de la variable myBool\nconsole.log(typeof myString); // Imprime el tipo de la variable myString\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/juanfeoru.js",
    "content": "// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Esto es un comentario de una sola línea\n\n/* Y esto es\n  un comentario\n  de\n  varias líneas\n*/\n\nlet prueba1 = 'Variable de prueba usando let';\nconst prueba2 = 'Variable de prueba usando const';\n\nlet numero = 5;\nlet cadenaDeTexto = 'Esto es una cadena de texto';\nlet booleano = true;\nlet indefinido = undefined;\nlet nulo = null;\n\nconsole.log('¡Hola, Javascript!');\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/juangomezn.js",
    "content": "// - Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado\n\n//https://www.javascript.com\n\n// - Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n\n//En_una_linea\n\n/*En Varias\nlineas de\ncodigo*/\n\n// - Crea una variable (y una constante si el lenguaje lo soporta).\n\nlet Nombre = \"Juan\"\n\nconst e = 2.7182; //Constante Euler por convención\n\n// - Crea variables representando todos los tipos de datos primitivo del lenguaje (cadenas de texto, enteros, booleanos...).\n\nlet int = 1  //Int\nlet float = 1.0 //Float\nlet string = \"Hola mundo\" //String\nlet boolean = true //Boolean\nlet any = undefined //Undefined\nlet bigInt = 121437679698743648965734542653n //BigInt\n\n// - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\nconsole.log(\"¡Hola, javascript!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/julianbuitragocharry-dev.js",
    "content": "const urlPaginaOficialJavaScript = 'https://developer.mozilla.org/es/docs/Web/JavaScript'\n\n//=== COMENTARIOS ===\n// Comentario en una línea del sitio oficial de JavaScript: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n/* Comentario de varias lineas \ndel sitio oficial de Javascript:\nhttps://developer.mozilla.org/es/docs/Web/JavaScript\n*/\n\n/*=== DECLARACIÓN DE VARIABLES ===\nEn javascript existe diferentes formas de declarar variables, primero conozcamo su anatonomia\n\nlet nombreVariable = 'valor';\nlet -------------- - -------;\n--- nombreVariable - -------;\n--- -------------- = 'valor';\nDECLARACIÓN       | ASIGNACIÓN\n*/\n\n/*=== FORMAS DE DECLARAR UNA VARIABLE ===\nPara declarar constante utilizaremos la palabra reservada {const}\n\nconst PI = 3.141592\n\nPara declarar no constantes utilizaremos las palabras reservadas {let} & {var}\nLa diferencia principal de var y let es que uno tiene un scope de bloque mientras que la otra es global\n\nlet --> Alcance bloque\nvar --> Alcance global\n*/\n\n/*=== TIPO DE DATOS ===\nExisten 10 tipos de datos\n\nPRIMITIVOS = ['string', 'number', 'boolean', 'undefined', 'null', 'symbol', 'bigint']\nCOMPLEJOS = ['object', 'array', 'function']\n*/\n\n//STRING\nlet variableString = 'Hello world'\n\n//NUMBER\nlet variableNumber = 10;\n\n//BOOLEAN\nlet variableBoolean = true;\n\n//NULL\nlet variableNula = null;\n\n//UNDEFINED\nlet variableIndefinida;\n\n//SYMBOL --> Sirven para crear identificadores\nlet variableSymbol = Symbol('Descripcion del símbolo');\n\n//BIGINT --> Sirven para representar numeros extremadamente largos\nlet bigintLiteral = 1234567890123456789012345678901234567890n;\nlet bigintLiteral2 = BigInt(1234567890123456789012345678901234567890);\n\n//OBJECT\nlet MoureDev = {\n    nombre: \"Brais Moure\",\n    tecnologias: ['Swift','Object-C','Kotlin','Java','Python','Flutter'],\n    esUnCrack: true,\n    pais: \"España\",\n    ocupacion: \"Desarrollador de Software\"\n};\n\n//ARRAY\nlet tecnologias = ['Swift','Object-C','Kotlin','Java','Python','Flutter'];\n\n//FUNCTION\nfunction cambiarOcupacion (object){\n    object.ocupacion = 'Desarrollador de Software Android & IOS';\n};\n\ncambiarOcupacion(MoureDev);\n\n\nconst LENGUAJEDEPROGRAMACION = 'JavaScript';\n\nconsole.log(`¡Hola, ${LENGUAJEDEPROGRAMACION}!`);"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/jurgen-alfaro.js",
    "content": "// SITIO WEB OFICIAL\n/*\n|---------------------------------------------------------------|\n|    https://developer.mozilla.org/en-US/docs/Web/JavaScript    |\n|_______________________________________________________________| \n*/\n\n// COMENTARIOS\n// Comentario de una sola línea\n/*  Comentario\n    de varias \n    líneas\n*/\n\n// CREACIÓN DE VARIABLES\nvar nombre = \"Bob\"; // No se recomendado usar 'var'\nlet apellido = \"Esponja\";\nconst CIUDAD = \"Fondo de Bikini\";\n\n// DATOS PRIMITIVOS\nconst varNull = null; // Type: Null | typeof: \"object\"\nconst varUndefined = undefined; // Type: Undefined  | typeof: \"undefined\"\nconst varBoolean = true; // Type: Boolean | typeof: \"boolean\"\nconst varNumberInt = 25; // Type: Number | typeof: \"number\"\nconst varNumberFloat = 140.24; // Type: Number | typeof: \"number\"\nconst varBigInt = 900719n; // Type: BigInt | typeof: \"bigint\"\nconst varString = \"Texto\"; // Type: String | typeof: \"string\"\nconst varSymbol = Symbol(\"valor\"); // Type: Symbol | typeof: \"symbol\"\n\n// IMPRIMIR EN CONSOLA/TERMINAL\nconsole.log(\"¡Hola, JavaScript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/k3nvd.js",
    "content": "// https://www.javascript.com/\n\n// Hello World\n/* Hello World */\n\nlet a = 'Hello';\nvar b = 'Hello';\n\nconst pi = 3.1416;\n\nlet name = \"Alice\";\nlet isLoggedIn = true;\nlet declaredVariable;       //undefined\nlet emptyObject = null; \nlet largeNumber = 9007199254740991n;\n\nlet language  = 'JavaScript';\n\nconsole.log('Hello',language);\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/k4rv3r.js",
    "content": "// Documentación: https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n// Utilizar \"//\" crea un comentario de una linea.\n\n// Utilizar \"/*<texto>*/\" crea un comentario en varias lineas:\n/* \nEsto es\nun comentario\nen varias\nlineas.\n*/\n\n/////////////////////////////////////////////////////////////////////////\n\n// --  TIPOS DE VARIABLES  --\nlet variable_1 = \"Estos es una variable.\";\nvar variable_2 = \"Esta es la version antigua de una variable\";\nconst constante_1 = \"Esto es una constante\";\n\n// -- TIPOS DE DATOS PRIMITIVOS --\n\n/*\nTodos los tipos, excepto los objetos, definen valores inmutables (es decir, valores que no se pueden cambiar).\nPor ejemplo (y a diferencia de C), las cadenas son inmutables. \nNos referimos a los valores de estos tipos como \"valores primitivos\".\n*/\n\n// - Cadenas de texto (strings):\n\nlet texto_1 = 'Esto es una cadena de texto con comillas simples';\nlet texto_2 = \"Esto es una cadena de texto con comillas dobles\";\nlet texto_3 = `Esto es una cadena de texto con acentos`; // Acepta operaciones dentro con \"${}\" como: `la mitad de 100 es ${100 / 2}`.\n\n// - Números\n\nlet numero_1 = 13; // Esto es un numero Entero o \"INT\" de integer.\nlet numero_2 = 13.27; // Esto es un numero Fraccionado o \"FLOAT\".\nlet numero_3 =  9007199254740992n; // Es es un \"BigInt\"\n/*\nEl tipo BigInt es un primitivo numérico en JavaScript que puede representar\nnúmeros enteros con precisión arbitraria. \nCon BigInts, puedes almacenar y operar de forma segura \nen números enteros grandes incluso más allá del límite seguro de \nenteros para Numbers.\n*/\n\n// - Boolean: representa una entidad lógica y puede tener dos valores: true y false.\n\nlet bool_1 = true;\nlet bool_2 = false;\n\n// - Null, Undefined & Symbol\n\nlet nulo = null; // El valor null es un literal de Javascript que representa intencionalmente un valor nulo o \"vacío\".\nlet indefinido = undefined; // La propiedad global undefined representa el valor primitivo undefined.\nlet simbolo = Symbol(\"Simbolo\"); // Symbol es un objeto incorporado cuyo constructor devuelve un symbol primitivo — también llamado Symbol value o simplemente Symbol — que está garantizado que sea único.\n\n///////////////////////////////////////////////////////////////////\n\nlet nombre = \"JavaScript\";\n\nconsole.log(\"Hello,\",nombre);"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/kaesar84.js",
    "content": "//  ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n// - Recuerda que todas las instrucciones de participación están en el\n//   repositorio de GitHub.\n//  Lo primero... ¿Ya has elegido un lenguaje?\n// - No todos son iguales, pero sus fundamentos suelen ser comunes.\n// - Este primer reto te servirá para familiarizarte con la forma de participar\n//   enviando tus propias soluciones.\n//  EJERCICIO:\n// - Crea un comentario en el código y coloca la URL del sitio web oficial del\n//   lenguaje de programación que has seleccionado.\n// - Representa las diferentes sintaxis que existen de crear comentarios\n//   en el lenguaje (en una línea, varias...).\n// - Crea una variable (y una constante si el lenguaje lo soporta).\n// - Crea variables representando todos los tipos de datos primitivos\n//   del lenguaje (cadenas de texto, enteros, booleanos...).\n// - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n//  ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n// debemos comenzar por el principio.\n\n/**\n * Lenguaje JavaScript\n    Sites de interés\n   https://developer.mozilla.org/es/docs/Web/JavaScript\n*/\n\nlet my_string = \"Hola\"\nlet my_number= 5\nlet my_big_int= 5.5e50\nlet my_boolean=true\nlet my_nan=NaN\nlet my_undifined=undefined\nlet my_symbol = Symbol(\"único\")\n\nconst MY_LANGUAGE =\"JavaScript\"\nconsole.log(`¡Hola ${MY_LANGUAGE}!`)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n___________________________________________________\n00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n---------------------------------------------------\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n*/\n\n// https://www.ecma-international.org/publications-and-standards/standards/ecma-262/\n// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n/**\n * Documentación\n * @param {string} name - Usuario\n * @returns {string} Un saludo.\n */\nfunction hello(name) {\n    return `Hola, ${name}!`;\n}\n\nlet x = 5           // Variable numérica.\nconst PI = 3.14159; // una constante.\n\n// Tipos de datos primitivos (https://developer.mozilla.org/es/docs/Web/JavaScript/Data_structures#valores_primitivos).\nlet isAdult = true;    // Tipo Boolean\nlet emptyValue = null; // Tipo Null\nlet undefinedVariable; // Tipo Undefined\nlet price = 9.99;      // Tipo Number\nlet name = \"Kenys\";    // Tipo String\nlet hugeNumber = 9007199254740991n; // Tipo BigInt\nlet sym = Symbol(\"id\"); // Tipo Symbol\n\nconsole.log(typeof price);\nconsole.log(\"¡Hola, JavaScript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/kevinramirez28.js",
    "content": "\n\n// mi sitio web de javascrip: https://www.w3schools.com/js/js_objects.asp\n\n// esto es un comentario de una sola linea \n\n/*\n esto es un comentario\nde varias lineas de \ntexto\n*/\n\n//  variables y constantes\n\nvar kevin = \"kevin\";\nconst x = 25;\n\n// numbers:\n\nlet peso = 85;\nlet altura = 1.75; \n\n//string:\n\nlet color = \"blanco\";\n\n//booleans:\n\nlet booleans = true;\n\n//object:\n\nconst cars = {llantas: \"invierno\", nieve: \"moderado\"};\n\n//array:\n\nconst caract = [\"cuatroPuertas\", \"blanco\", \"bmw\"];\n\nconsole.log(\"hola, mi lenguaje es javascript\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/kinrgdev.js",
    "content": "/* EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n// Sitio web oficial de javascript: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Método de comentario de una línea > //\n\n// Método de comentario en más de una línea > /* */\n\n/*\nMétodo\nde\ncomentario\nen\nmás de una\nlínea \n*/\n\n// Crear variable y constante\nlet Mi_variable = \"Aprendizaje\";\nconst Mi_constante = \"Estudio\";\n\n// Datos primitivos\n\nlet string = \"Cadena de texto\";\nlet numEntero = 25;\nlet booleano = true;\nlet valorNulo = null;\nlet variableNoAsignada\n\nlet lenguaje = \"JavaScript\";\nconsole.log(`Hola ${lenguaje}`);\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/kodenook.js",
    "content": "// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Comments\n\n//single-line comment\n/*\n    this is a\n    multi-line comment\n*/\n\n//Variables and Constants\n\n\nlet variable = 'variable'\nconst constant = 'constant'\n\n\n// Data Types\n\nlet string = 'string'\nlet number = 1\nlet boolean = true // true or false\nlet array = ['saturday', 'sunday']\nlet person = { first_name: 'john', last_name: 'doe' }\n\n// Print\n\nconsole.info('¡Hola, javascript!')\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/kouski.js",
    "content": "/* https://developer.mozilla.org/es/docs/Web/JavaScript */\n\n/* Sintaxis \n  en dos lineas */\n\n/*********************\nOtra sintaxis\n**********************/\n\nlet nombre = 'JavaScript';\nconst edad = 25;\n\nlet isTrue = true;\nlet nulo = null;\nlet nodefinido = undefined;\n\nconsole.log(`Hola, ${nombre}`);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/kronomio.js",
    "content": "// #00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n//https://www.javascript.com/\n\n// One line\n\n/*\n\n    Multiple Lines\n\n*/\n\nlet variable=0;\n\nconst constant=\"Hello World!\"\n\nlet string=\"hello\";\nlet number=54;\nlet bigint=58469854587859652;\nlet boolean=false;\nlet decimal=6.54;\nlet symbol= symbol(\"newSymbol\");\nlet nullValue=null;\nvar  undefinedValue=undefined;\n\nconsole.log(\"¡Hola Javascript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/krrattoss5.js",
    "content": "// https://developer.mozilla.org/es/docs/Web/JavaScript  sitio oficial de javascript\n\nlet variable = \"javascript\"\n\nconst saludo = `¡Hola, ${variable}!`\n\nconst boolean = true\n\nconst string = \"string\"\n\nconst numbers = 123456\n\nconst literalObject = {}\n\nconst nullData = null\n\nconst notIsANumber = NAN\n\nconst notDefined = undefined\n\nconsole.log(saludo)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/legs30011.js",
    "content": "//Comentario en Java Script\n\n//1: Comentario de una linea\n\n//https://www.python.org/\n\n//2: cometario varias lineas\n\n/* asdsadas\nasdsad\nasdasd */\n//3: Sytaxis para nombrar variables\n\n//cadena de texto\nlet myvariable = \"myvarible\";\n//constante\nconst quique = \"constante\"; //por convencion\n\n//tipos de datos primitivos\nlet string = \"Hola mundo\";\nlet boolean = false;\nlet integer = 123;\nlet float = 123.45;\n\n//como imprimir texto en cosola\nconsole.log(quique)\n\nconst PROGRAMMING_LANGUAGE = \"JavaScript\";\n\n// Concatenación de variables\n\nconsole.log(\"¡Hola, \" + PROGRAMMING_LANGUAGE + \"!\");\n// Otra forma de concatenar variables   \nconsole.log(`¡Hola, ${PROGRAMMING_LANGUAGE}!`);\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/levsistemas.js",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\nconsole.clear()\n\nconsole.log(\"Javascript\")\nconsole.log(\"https://nodejs.org/es\")\n\nconsole.log(\"comentario1\")\nconsole.info(\"comentario2\")\nconsole.error(\"comentario3\")\nconsole.warn(\"comentario4\")\n\nlet data = [[\"Leandro\", 38], [\"Brais\", 37]]\nconsole.table(data)\n\nconsole.group(\"Usuario:\")\nconsole.log(\"Nombre: Leandro\")\nconsole.log(\"Edad: 38\")\nconsole.log(\"otra linea\")\nconsole.groupEnd()\n\nconsole.time(\"Tiempo de ejecución\")\n\nfor (let i = 0; i < 20000; i++ ) {\n\n}\n\nconsole.timeEnd(\"Tiempo de ejecución\")\n\nlet age = 18\nconsole.assert(age >= 18, \"El usuario debe ser mayor de edad.\")\n\nconsole.count(\"Click\")\nconsole.count(\"Click\")\nconsole.countReset(\"Click\")\n\nfunction funcionA() {\n    funcionB()\n}\n\nfunction funcionB() {\n    console.trace(\"Seguimiento de la ejecución\")\n}\n\nfuncionA()\n\nlet miNombre = 'Leandro'\nconst fechaNacimiento = 1986\n\nlet string = 'Hola Mundo'\nlet number = 38\nlet float = 20.5\nlet boolean = true\nlet boolean_f = false\nlet vacio = null\nlet empty // Undefined\nlet mySymbol = Symbol('Mouredev')\nlet BigInt = 1000000000000000\n\nconsole.log(\"¡Hola, Javascript!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/leydimadrid.js",
    "content": "/* Web Oficial de JavaScript:\nURL: https://developer.mozilla.org/en-US/docs/Web/JavaScript */\n\n//Comentario de una línea\n\n/* Esto es un \nComentario en varias lìneas*/\n\n//Let y const\nlet myVariable = \"Soy una variable con let\";\nconst MYVARIABLE = \"Soy una constante\";\n\n//Tipos de datos primitivos en JavaScript\n\nlet string = \"Soy un String\";\nlet number = 10;\nlet booleanTrue = true;\nlet booleanFalse = false;\nlet nullType = null;\nlet undefined;\nlet symbol = Symbol(\"Soy un Symbol\");\nlet Bignit = 100000000000000000000;\n\n//Imprimir en la consola\nconsole.log(\"¡Hola, JavaScript\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/lfam200.js",
    "content": "// JavaScript website: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Sintax for comments\n// This is a comment in one line\n/* This is\na multipline line\ncomment */\n\n// var and const\nlet age = 34\nconst name = 'Luis'\n\n// primitive data types\nlet string = 'This is a string'\nlet integer = 10\nlet decimal = 10.5\n\nlet booleanTrue = true\nlet booleanFalse = false\n\nlet nullType = null\n\nlet undefinedType = undefined\n\nlet simbol = Symbol.for('key')\n\n// print in console\nconsole.log('Hello JavaScript!');"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/lfwzk.js",
    "content": "// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// en una linea\n\n/* \nen varias \nlineas de codigo\n\n*/\n\nconst constante = \"Esto es una constante\";\n\nlet variable = \"Esto es una variable\";\n\nvar variableGlobal = \"Esto es una variable global\";\n\n// TIPOS DE DATOS PRIMITIVOS\n\n// String\nlet string = \"Esto es un string\";\n\n// Number\nlet entero = 10;\nlet flotante = 10.5;\n\n// BigInt\nlet bigInt = BigInt(9007199254740991);\n\n// Boolean\nlet booleanTrue = true;\nlet booleanFalse = false;\n\n// Undefined\n\nlet variableIndefinida;\n\n// imprimir por consola\n\nconsole.log(\"¡Hola, JavaScript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/llonardo798.js",
    "content": "// 1. URL del sitio web oficial de JavaScript: https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n// 2. Sintaxis de comentarios en JavaScript:\n\n// Comentario de una línea\n\n/*\n *  Comentario de\n *  varias líneas\n */\n\n/**\n * Comentario de varias líneas\n * en formato de documentación\n * (JSDoc)\n * \n * @param {string} param1 - Descripción del parámetro\n * @returns {number} - Descripción del valor de retorno\n */\n\n// 3. Creación de variables y constantes en JavaScript:\nlet variable = 'Variable en JavaScript!';\n\nconst constante = '¡Constantes en JavaScript!';\n\n// 4. Tipos de datos primitivos en JavaScript:\n\nlet cadena = 'Cadena de texto';             // String (cadenas de texto) - Comillas simples\nlet otraCadena = \"Otra cadena de texto\";    // String (cadenas de texto) - Comillas dobles\nlet numero = 42;                            // Number (números) - Numeros enteros \nlet decimal = 3.14;                         // Decimal (números) - Números decimales o de punto flotante\nlet bigInt = BigInt(9007199254740992);      // BigInt (números) - Números enteros que son más grandes que el límite que puede manejar number\nlet booleano = true;                        // Boolean (valores booleanos) - true o false\nlet valorNoDefinido;                        // Undefined (valor no definido) - Variable que no ha sido asignada\nlet valorNulo = null;                       // Null (valor nulo) - Valor nulo\nlet id = Symbol(\"id\");                      // Symbol (símbolos) - Valor único e inmutable que puede ser utilizado como clave de una propiedad de un objeto\n\n// 5. Imprimir por consola\nconsole.log(`¡Hola, JavaScript!`);"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/lopesteban.js",
    "content": "// ##00 - SINTAXIS, VARIABLES, TIPOS DE DATOS, Y \"HOLA MUNDO\"*/\n\n/*EJERCICIO: \nCrea un comentario en el código y coloca la URL del sitio web oficial del\n  lenguaje de programación que has seleccionado. */\n\n//https://developer.mozilla.org/es/docs/Web/JavaScript\n\n/*EJERCICIO:\n  Representa las diferentes sintaxis que existen de crear comentarios\n   en el lenguaje (en una línea, varias...)*/\n\n//  Esta es la forma de comentar el código con una sola línea\n/*Esta es la forma de comentar el código usando más de una línea. Es muy similar a otros lenguajes de programación */\n\n/*EJERCICIO:\n   Crea una variable (y una constante si el lenguaje lo soporta)\n    */\n\n// Variable  usando \"let\"\nlet variableNueva = \"Variable no constante\";\n\n//Variable usando \"var\" (en desuso)\nvar variableVieja = \"Variale no constante vieja\";\n\n// Variable llamada Constante. Sólo se usa para crear una variable que no se modificará\nconst variableConstante = \"Variable constante\";\n\n/*EJERCICIO:\n Crea variables representando todos los tipos de datos primitivos\n   del lenguaje (cadenas de texto, enteros, booleanos...)*/\n\n/*Los tipos de datos son la naturaleza del contenido de una variable o constante.Javascript dispone de muchos tipos de datos, sin embargo, se suelen catalogar en dos grupos: tipos de datos primitivos (básicos) y tipos de datos no primitivos (complejos). Los datos primitivos son siete*/\n\n// \"String\" o Cadena de texto\nlet cadenaDeTexto = \"Esteban\";\n\n// \"Number\" o valor numérico\nlet valorNumérico = 45;\n\n// \"Bigint\". Es un valor numérico muy grande\n\nlet valorNumericoGrande = 50n;\n\n// \"Boolean\" o booleano: Tipo de valor \"Falso\" o \"Verdadero\"\nlet valorBooleanoFalso = false,\n  valorBooleanoVerdadero = true;\n\n//\"Symbol\": Tipo de dato para crear valores únicos.\nconst valorUnico = Symbol(\"Único\");\n\n// \"Unefined\": Valor sin definir (variable sin inicializar)\nlet valorIndef = undefined;\n\n//\"Null\": Representa un valor vacío o ausencia de información\nlet valorNulo = null;\n\n/*EJERCICIO:\nImprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\" */\n\nconsole.log(\"¡Hola, Javascript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/lrpeset.js",
    "content": "// URL JavaScript: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n//  Comentario en una sola línea\n/*  \n    Comentario\n    En varias\n    líneas  \n*/\n\n//  Creación de varibale\nlet myVariable = \"miVariable\"\n//  Creación de constante\nconst myConstant = \"miConstante\"\n\n//  Tipos de datos primitivos\nlet number = 1;\nlet float = 1.5;\nlet bigInt = 923104n;\n\nlet string = \"Cadena de texto\";\n\nlet booleanTrue = true;\nlet booleanFalse = false;\n\nlet myNull = null;\n\nlet myUndefined = undefined;\n\n//  Impresión por terminal\nconsole.log(\"¡Hola, JavaScript!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/luchof5.js",
    "content": "// https://www.javascript.com/\n\n// Comentario en una sola linea\n\n/* \n    Comentarios\n    en \n    multiples \n    lineas\n*/\n\nlet variable = \"Esto puede variar\";\nconst constante = \"Esto es una constante\";\nvar variableGlobal = 'Variable global';\n\n// Enteros\nlet numero = 10;\n\n// Decimal / Float\nlet decimal = 0.5;\n\n// String\nlet string = \"SantaAna\";\nlet otroString = 'SantaAna';\n\n// Boolean\nlet verdadero = true;\nlet falso = false;\n\n// Undefined\nlet indefinido = undefined;\n\n// Null\nlet nulo = null;\n\n// Symbol\nlet simbolo = Symbol();\n\n// BigInt\nlet numueroGrande = BigInt('293029301903821908390283092183982190389083910281')\nlet otroNumeroGrande = 293029301903821908390283092183982190389083910281n\n\n\nconsole.log(\"Hola JavaScript\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/lucianogriffa.js",
    "content": "// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Comment on the line\n\n/*\nComment \non \nmultiple \nlines\n*/\n\nconst constant = 'This is a constant'\n\nlet variable = 'This is a variable'\n\nvar globalVariable= 'This is a global variable'\n\n// PRIMITIVE DATA TYPE\n// String\nlet string = 'This is a string'\n\n// Number   \nlet int = 10\nlet float = 10.5\n\n// BigInt\nlet bigInt = BigInt(9007199254740991) // 9007199254740991n\n\n// Boolean\nlet booleanTrue = true\nlet booleanFalse = false\n\n// Undefined\nlet undefinedVariable\n\n// Symbol\nlet symbol = Symbol('This is a symbol')\n\n// Null\nlet nullVariable = null\n\nconsole.log(\"¡Hola, [y el nombre de tu lenguaje]!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/lytsar.js",
    "content": "/* https://developer.mozilla.org/es/ */\n\n/* comentario de una linea */\n\n/*Un comentario\nque se extiende\nen varias\nlíneas*/\n/* Tipos De Variables */\nvar name1 = 317 ;\n\nlet  name2 = 519; \n\nconst Pi = 3.1419;\n\n/* Datos Primitivos */\nvar texto = \"tpm\";\nvar number = 0 ;\nvar granentero = 556n ;\nvar y = false ; /*boolean true or false*/\nvar x ;\nlet sym1 = Symbol(\"simbolo\");\n\nvar nulo = null ;\n/*Imprimir por Terminal El nombre de tu lenguaje*/\nvar lenguaje = \"¡Hola, JavaScript!\";\nconsole.log (lenguaje)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/m-hadz.js",
    "content": "// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Se usa para comentarios de una linea\n\n/*\n * Se utiliza para comentarios\n * de multiples lineas\n */\n\nlet variable = \"ejemplo\";\nvar variable2 = 1234;\n\nconst constante = 3.14;\n\n// Estos son los tipos de datos primitivos de JavaScript\n\nlet string = \"hola\"; // String\n\nlet entero = 3; // Number\n\nlet grande = 3429875825378523n; // BigInt\n\nlet booleano = true; // Boolean\n\nlet indefinido; // Undefined\n\nlet simbolo = Symbol(); // Symbol\n\nlet nulo = null; // Null\n\n// para imprimir se utiliza la funcion log del objeto console\nconsole.log(\"¡Hola, JavaScript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/manuelgomezg.js",
    "content": "// _1.URL del sito Oficial:\n// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// _2.Sintaxis de comentarios\n// Este comentario es de una sola linea\n/*\nEste comentario es \nmultilinea\nideal para \nhacerlo en bloque\n*/\n\n//_3.Creacion de Variables y Constantes\n\n//Definicion de Variable y Constante:\nvar variable = 1;\nlet Bloque = 20;\nconst constante = 3;\n\n//_4. Tipos de datos primitivos en JavaScritp\n\nlet cadena = 'Esto es un string';\nlet otroString  = \"JavaScript\"\nlet numero = 1;\nlet decimal = 1.1;\nlet bigInt = BigInt(6665625687975325);\nlet boolean = true;\nlet valorNulo = null;\nlet id = Symbol(\"id\");\n\n//_5.Imprime por consola\n\nconsole.log('Hola, JavaScript');\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/manuelleon225.js",
    "content": "// Reto #00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n// Autor: manuelleon225\n// Lenguaje: JavaScript\n// Documentación: https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n/* Comentarios largos\n   permiten estar en varias líneas */\n// Comentarios cortos de una sola línea\n\n// VARIABLES\nlet a; // Declaramos variable sin valor (undefined)\nlet b = 0; // Declaramos variable con valor 0\n\nconsole.log(a); // Muestra: undefined\nconsole.log(b); // Muestra: 0\n\n// CONSTANTES\nconst name = \"Manuel\";\nconsole.log(name); // Muestra: Manuel\n\n// TIPOS DE DATOS PRIMITIVOS\n// Undefined\nlet undefinedVar; // undefined\nconsole.log(undefinedVar); // Muestra: undefined\n\n// Null\nlet nullVar = null; // null\nconsole.log(nullVar); // Muestra: null\n\n// String (Cadena, Texto o carácter)\nlet text = \"Hola me llamo Manuel\";\nconsole.log(text); // Muestra: Hola me llamo Manuel\n\n// Number (números enteros o decimales)\nlet number = 27;\nconsole.log(number); // Muestra: 27\nlet number2 = 5.3;\nconsole.log(number2); // Muestra: 5.3\n\n// BigInt (número muy grande)\nlet bigNumber = 12345678901234567890n;\nconsole.log(bigNumber); // Muestra: 12345678901234567890n\n\n// Boolean (valor verdadero o falso)\nconst boolean = true;\nconsole.log(boolean); // Muestra: true\n\n// Symbol (valor único)\nconst symbol = Symbol(\"unique\");\nconsole.log(symbol); // Muestra: Symbol(unique)\n\n// TIPOS DE DATOS NO PRIMITIVOS\n// Objeto\nlet user = { name: \"Manuel\", edad: 30 };\nconsole.log(user); // Muestra: { name: 'Manuel', edad: 30 }\n\n// Array\nlet users = [\"Jhoan\", \"Magdali\", \"Jose\", \"Doris\"];\nconsole.log(users); // Muestra: ['Jhoan', 'Magdali', 'Jose', 'Doris']\n\n// Mensaje final\nconsole.log(\"¡Hola, JavaScript!\"); // Muestra: ¡Hola, JavaScript!"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/marcode24.js",
    "content": "// ¡Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n// - Recuerda que todas las instrucciones de participación están en el\n//   repositorio de GitHub.\n//\n// Lo primero... ¿Ya has elegido un lenguaje?\n// - No todos son iguales, pero sus fundamentos suelen ser comunes.\n// - Este primer reto te servirá para familiarizarte con la forma de participar\n//   enviando tus propias soluciones.\n//\n// EJERCICIO:\n// - Sitio web oficial de JavaScript: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// - Representa las diferentes sintaxis que existen de crear comentarios\n//   en el lenguaje (en una línea, varias...).\n\n/*\n   Comentario de múltiples líneas\n*/\n\n// - Crea una variable (y una constante si el lenguaje lo soporta).\nlet miVariable = 'Hola, mundo';\n// eslint-disable-next-line no-unused-vars\nconst miConstante = 42;\n\n// - Crea variables representando todos los tipos de datos primitivos\n//   del lenguaje (cadenas de texto, enteros, booleanos...).\nlet cadenaTexto = 'Hola';\nlet numeroEntero = 42;\nlet numeroDecimal = 3.14;\nlet booleano = true;\nlet bigInt = 9007199254740991n;\nlet nulo = null;\nlet indefinido = undefined;\nlet simbolo = Symbol('Hola');\nlet objeto = {\n  nombre: 'Pepe',\n  edad: 42,\n};\nlet array = [1, 2, 3];\n\n// - Imprime por terminal el texto: \"¡Hola, JavaScript!\"\nconsole.log('¡Hola, JavaScript!');\n\n// Visita mi repo en GitHub para ver y correr los tests de este código --> https://github.com/marcode24/weekly-challenges"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/mariovelascodev.js",
    "content": "//https://developer.mozilla.org/es/docs/Web/JavaScript\n\n//Comentario en una línea\n/*\n    Comentatio en \n    varias líneas\n */\n\n//Variable\nlet myVariable;\n//Constante\nconst PI = 3.1415;\n\n//Tipos primitivos\nlet variableStr = \"Esto es un string\";\nlet variableNumber = 3;\nlet variableBoolean = false;\nlet variableNull = null;\nlet variableUndefined = undefined;\n\nconsole.log(\"¡Hola, Javascript!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/martinbohorquez.js",
    "content": "// https://www.typescriptlang.org/\n// Esto es un comentario en una sola línea.\n/*\n * Esto es un comentario\n * usando varías líneas\n * para describir el código.\n */\n// Variable\nvar saludo = '¡Hola, ';\n// Constante\nconst PROGRAMMING_LANGUAGE = 'TypeScript!';\n// Datos Primitivos\n// String\nvar palabra = 'Palabra';\nprintMessage(\"palabra\", palabra);\nvar texto = 'Este string es un texto';\nprintMessage(\"texto\", texto);\n// Numbers\nvar numero = 123;\nprintMessage(\"numero\", numero);\nvar decimal = 3.1415926535;\nprintMessage(\"decimal\", decimal);\nvar negativo = -123;\nprintMessage(\"negativo\", negativo);\nvar enteroGrande = 1234567890123456789012345678901234567890n;\nprintMessage(\"enteroGrande\", enteroGrande);\n// Booleans\nvar verdadero = true;\nprintMessage(\"verdadero\", verdadero);\nvar falso = false;\nprintMessage(\"falso\", falso);\n// Symbol\nvar simbolo = Symbol('mi-simbolo');\nprintMessage(\"simbolo\", simbolo);\n// Undefined\nvar indefinido = undefined;\nprintMessage(\"indefinido\", indefinido);\n// Null\nvar nulo = null;\nprintMessage(\"texto\", texto);\n// Imprimir por terminal\nconsole.log(saludo + PROGRAMMING_LANGUAGE);\nfunction printMessage(string, any) {\n    if (typeof (any) == \"symbol\") {\n        console.log(\"La descripción de '\" + string + \"' es: \" + any.description + \", y su tipo es: \"\n            + typeof (any));\n    }\n    else {\n        console.log(\"El valor de '\" + string + \"' es: \" + any + \", y su tipo es: \"\n            + typeof (any));\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/mateo423.js",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n/**\n * URL del sitio web oficial\n * https://developer.mozilla.org/es/docs/Web/JavaScript\n */\n\n// Comentario en una linea\n\n/* Comentaio en varias \n  lineas \n  */\n\n// Variables\nlet my_variable = 'Mi variable';\n\n// Constante\nconst my_variable_1 = 'Mi Constante';\n\n// Tipos de datos primitivos\nlet strings = 'Cadena de texto';\nlet entero = 34;\nlet decimal = 14.5;\nlet Null = null;\nlet miUndefined;\nlet booleanos = true;\nconst miSymbol = Symbol('my Symbol')\nconst miBigInt = 123456789012345678901234567890n;\n\n// Imprimir texto en consola\nconsole.log(\"¡Hola, \" + language + \"!\");\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/matiasFarfan89.js",
    "content": "// https://www.javascript.com/ \n\n//Asi se anotan comentarios para solo una linea de codigo\n\n/*\n *Asi se anotan comentarios\n *para  un bloque de\n *codigo\n*/\n\n// Crea una variable (y una constante si el lenguaje lo soporta).\n\nvar nombre = \"Matias\";\nlet edad = 34;\nconst mesDeNacimiento = Septiembre;\n\n// Crea variables representando todos los tipos de datos primitivos \n\n// Cadenas de texto (strings)\nvar cadenaTexto = \"Hola, mundo!\";\n\n// Números (numbers)\nvar numeroEntero = 42;\nvar numeroDecimal = 3.14;\n\n// Booleanos (booleans)\nvar esVerdadero = true;\nvar esFalso = false;\n\n// Simbolos (symbols)\nvar simbolo = Symbol('descripcion');\n\n// Nulos (null)\nvar valorNulo = null;\n\n// Indefinidos (undefined)\nvar valorIndefinido;\n\n// Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\nvar nombreDelLenguaje = \"JavaScript\";\nconsole.log(\"¡Hola, \" + nombreDelLenguaje + \"!\");\n\nlet nombreDelLenguaje = \"JavaScript\";\nconsole.log(`¡Hola, ${nombreDelLenguaje}!`);\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/matrix-miguel.js",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n\n\n\n/**\n * URL del sitio web oficial\n * https://developer.mozilla.org/es/docs/Web/JavaScript\n */\n\n// comentario de una línea\n\n/**\n * comentario de multiples líneas destacado\n */\n\n/* comentario de multiples líneas*/\n\n// variable and constant\nlet variable = 'variable';\nconst constante = 'constante';\n\n//datos primitivos\nlet number = 1;\nlet float = 1.1;\nlet string = 'string';\nlet boolean = true;\nlet nul = null;\nlet indefinido = undefined; \nlet bigInt = 2123554054504543823289223928389288223n; \n\n//print language\nconsole.log(\"Hola, [Javascript]\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/max23esau.js",
    "content": "// https://www.javascript.com/\n\n// Estructura de comentario de una sola linea\n\n/*\n  Este es un comentario \n  donde puedes tener multiples lineas\n  por si una no te es suficiente\n*/\n\nlet firtsVariable = 'This is a variable';\n\nconst PI = 3.1416;\n\nvar globalVariable = 'This variable is saved in the object window in the browser or the object global if its declared in the server (node.js)'\n\nlet number = 1234567890;\n\nlet strings = 'This is a string';\n\nlet floats = 57.8;\n\nlet booleanTrue = true;\n\nlet booleanFalse = false;\n\nlet variableUndefined = undefined;\n\nlet variableNull = null;\n\nlet bigInt = 1234567890123456789012345678901234567890n;\n\nconst variableSymbol = Symbol('id'); \n\n\nconsole.log('¡Hola, JavaScript!');"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/maximiliano1997.js",
    "content": "/*\r\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\r\n * - Recuerda que todas las instrucciones de participación están en el\r\n *   repositorio de GitHub.\r\n *\r\n * Lo primero... ¿Ya has elegido un lenguaje?\r\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\r\n * - Este primer reto te servirá para familiarizarte con la forma de participar\r\n *   enviando tus propias soluciones.\r\n *\r\n * EJERCICIO:\r\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\r\n *   lenguaje de programación que has seleccionado.\r\n * - Representa las diferentes sintaxis que existen de crear comentarios\r\n *   en el lenguaje (en una línea, varias...).\r\n * - Crea una variable (y una constante si el lenguaje lo soporta).\r\n * - Crea variables representando todos los tipos de datos primitivos\r\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\r\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\r\n *\r\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\r\n * debemos comenzar por el principio.\r\n */\r\n\r\n\r\n/* SOLUCION: */\r\n\r\n// https://www.javascript.com/\r\n\r\n/*\r\n    Representacion de comentario en \r\n    varias lineas.\r\n*/\r\n\r\n\r\nvar variable = 10\r\nlet variableLet = 10\r\nconst constante = 10\r\n\r\n// Primitivos\r\nlet primitivo_number = 10\r\nlet primitivo_booleano_true = true\r\nlet primitivo_booleano_False = false\r\nlet primitivo_string = 'String'\r\nlet primitivo_null = null\r\nlet primitivo_undefined;\r\nlet primitivo_bigInt = 123456789012345678901234567890n\r\nlet primitivo_Symbol = Symbol('symbol')\r\n\r\n\r\nconsole.log('¡Hola, Javascript!')\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n// comprobaciones en consola\r\nconsole.log(`\r\n    Variables y Constante: \\n\r\n    variable: ${variable}\r\n    variableLet: ${variableLet} \r\n    constante: ${constante} \r\n    \\n\r\n    Primitivos:\r\n    primitivo_number: ${primitivo_number}   <-- ${typeof primitivo_number}\r\n    primitivo_booleano_true: ${primitivo_booleano_true} <-- ${typeof primitivo_booleano_true}\r\n    primitivo_booleano_False: ${primitivo_booleano_False} <-- ${typeof primitivo_booleano_False}\r\n    primitivo_string: ${primitivo_string} <-- ${typeof primitivo_string}\r\n    primitivo_null: ${primitivo_null} <-- ${typeof primitivo_null} //Curiosa historia sobre porque null es marcado como object en javascript :D\r\n    primitivo_bigInt: ${primitivo_bigInt} <-- ${typeof primitivo_bigInt}\r\n    primitivo_undefined: ${primitivo_undefined} <-- ${typeof primitivo_undefined}\r\n    primitivo_Symbol: ${primitivo_undefined} <-- ${typeof primitivo_Symbol}\r\n    \r\n    `)\r\n\r\n\r\n\r\n// Gracias Mouredev #00\r\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/mdemena.js",
    "content": "//https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Solo una linea\n\n/*\nBloque de comenatrios\nPara que sea más fácil\n*/\n\nlet language = \"Javascript\";\nconst CONSTANT = \"CONSTANTE\";\n\nlet varNumber = 0;\nlet varBigInt = 9007199254740991;\nlet varString = \"STRING\";\nlet varBoolean = true;\nlet varNull = null;\nlet varUndefined = undefined;\nlet varSymbol = Symbol(language);\n\nconsole.log(\"¡Hola, \" + language + \"!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/mekanicas.js",
    "content": "//https://www.javascript.com/\n\n/* Esta es otra manera \nde colocar \ncomentarios en más de una línea */\n\nlet js = \"JavaScript\";\nconst cinco = 5;\n\n/* - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...). */\n\nlet string = \"Un string, se puede utilizar para texto plano\";\nlet number = 10;\nlet booleanT = true;\nlet booleanF = false;\nconst x = BigInt(Number.MAX_SAFE_INTEGER);\nconst sym = Symbol();\nlet myUndefined; //undefined\nlet Null = null\n\nconsole.log(\"¡Hola \" + js + \"¡\" )"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/memoGV.js",
    "content": "\n/*Hola mouredev, empezando con los retos de prgramacion, espero no sea demasiado tarde\nhttps://developer.mozilla.org/en-US/ */  //Diferente Comentario//\n\nlet a = 1\nvar b = 2\nconst c = b - a\n\nlet numero = 0\nlet string = \"Hola\"\nlet boleano = true\nlet sinDefinir = undefined\nlet nulo = null\nlet simbolo = Symbol('descripcion')\nlet numeroGrande = BigInt(909090909090909090909)\n\nconsole.log('Hola JavaScript')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/memoo77.js",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n\n// www.retosdeprogramacion.com\n// Comentario de una línea\n\n/*\ncomentario para varias líneas\nesta es otra línea\n*/\n\n//Tipos de variables constantes o varaibles\nvar tipoVariableNoUsar\nlet tipoVariableSiUsar\nconst constante = 'Hola'\n\n// varaibles primitivas\nconst string = 'Hola'\nconst number = 123\nconst boolean = false\nlet Symbol\nconst Null = null\nconst Undefined = undefined\n\n\n//PRUEBA\nconsole.log('Hola, javascript')\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/mensius87.js",
    "content": "// Sitio oficial de JavaScript: https://developer.mozilla.org/es/docs/Web/JavaScript \n\n// Comentario de una línea\n\n/* Este es un comentario multilínea\n   en JavaScript tan largo como\n   desees. */\n\n// Creación de variables\nvar variable = \"Hola MoureDev\";\n\n// Creación de una constante\nconst CONSTANTE = 3.14;\n\n// Variables representando diferentes tipos de datos primitivos\nvar entero = 20; // Número entero\nvar flotante = 1.4; // Número con punto flotante (decimal)\nvar texto = \"JavaScript\"; // Cadena de texto (string)\nvar booleano = true;   // Booleano\n\n// Imprimir por consola\nconsole.log(\"¡Hola \" + texto + \"!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/mhrosariom.js",
    "content": "/* https://developer.mozilla.org/es/docs/Web/JavaScript */\n\n// Este es uncomentario en una sola linea\n\n/* \nEste es un comentario\nque contiene\nvarias Lineas \n*/\n\n// VARIALBLE\n\nlet myVariable = \"Mi primera Variable\";\n\n//CONSTANTE\n\nconst MY_CONSTANTE = 8;\n\n// TIPOS DE DATOS PRIMITIVOS\n\nNumber = 235.33;\nString = \"cadena de texto\";\nBoolean = true;\nBoolean = false;\nBigInt = 9007199254740992n;\nundefined = undefined;\nSymbol = Symbol\n\nconsole.log(\"Hola JavaScript\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/mickel-arroz.js",
    "content": "// Ejercicio #00 - Mickel Arroz\n\n/*\nWeb Oficial de Documentacion:  \nhttps://developer.mozilla.org/es/docs/Web/JavaScript\n*/\n\n// Comentario simple (de una sola linea)\n/*\n    Comentario de varias lineas\n    (comentario extenso)\n*/\n\n// VARIABLES\n// Se usa 'let' en lugar de 'var', ya que permite trabajar con el scope de la variable, mientras 'var' no.\nlet variable = \"valor\";\n\n// CONSTANTES\n// Valor inmutable. Por convenio se suelen crear constantes en mayusculas, para visualmente identificarlas.\nconst CONSTANTE = \"valor inmutable\";\n\n// TIPOS DE DATOS PRIMITIVOS EN JAVASCRIPT\n// Se definen datos primitivos a los que no son objetos ni poseen metodos.\n\n// String\n// Secuencia de caracteres\nlet texto = \"Texto de ejemplo. String es Primitivo\";\n\n// Number\n// Tipo de dato numerico\nlet num = 1;\n\n// Bigint\n// Tipo de dato numerico tambien, pero que permite almacenar numeros mucho mas grandes.\n// Para indicar que es un Bigint se agg la 'n' al final del numero.\nlet big = 123456789123456789n;\n\n// Boolean\n// Indica un valor de verdad o falso (1 o 0)\nlet bool = false;\n\n// Undefined\n// Son datos que no estan definidos. Es decir \"sin definir\".\n// Al crear una variable sin asignarle un valor, se crea un Undefined\nlet und;\n\n// Symbol\n//  Se utiliza principalmente para crear propiedades de objetos que son garantizadas como únicas.\nlet sim = Symbol();\n\n// IMPRIMIR POR TERMINAL\nconsole.log(\"¡Hola, JavaScript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/miguelRejon96.js",
    "content": "// Sitio oficial de Javascript: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n//Este es un comentario en una línea\n/*\n    Este es un comentario en varías líneas\n*/\n\n//Constante\nconst greetings = 'Hello'\n\n//Variable\nlet language = 'Javascript'\n\n//Tipos de datos:\n\n//String \nconst thiIsAString = 'This is a string'\n\n//Number\nconst thisIsANumber = 1\n\n//BigInt\nconst thisIsABigInt = BigInt(9007199254740991)\n\n//Boolean\nconst thisIsABoolean = true \n\n//Undefined\nlet thisIsAnUndefined\n\n//Symbol\nconst thisIsASymbol = Symbol()\n\n\nconsole.log(`${greetings} ${language}`)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/miguelex.js",
    "content": "// Documentación en https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Comentario de una línea\n\n/*\nComentario de\nvarias líneas\n*/\n\nlet nombre = \"Javascript\"; // Variables\n\nconst PI = 3.1415; // Constantes\n\n// Tipos primitivos\nlet variableStr = \"Esto es un string\";\nlet variableNumber = 3;\nlet variableBoolean = false;\nlet variableNull = null;\nlet variableUndefined = undefined;\n\n// Mensajes por consola\n\nconsole.log(\"Hola, \" + nombre);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/miguelsarm.js",
    "content": "// https://retosdeprogramacion.com/roadmap/ miguelsarm run #!1 javascript\n\n// -------------------------- ENUNCIADO\n\n/*\n ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n - Recuerda que todas las instrucciones de participación están en el repositorio de GitHub.\n \n Lo primero... ¿Ya has elegido un lenguaje?\n - No todos son iguales, pero sus fundamentos suelen ser comunes.\n - Este primer reto te servirá para familiarizarte con la forma de participar enviando tus propias soluciones.\n \n EJERCICIO:\n - Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n- Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n - Crea una variable (y una constante si el lenguaje lo soporta).\n - Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n \n ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y debemos comenzar por el principio.\n */\n\n/* este lo voy a hacer con javasript\n\nvarias lineas de codigo\npd: es igual que en css\n*/\n\n// declaring variables\nvar old = \"this is the old version\";\nlet variable;\nconst pi = 3.14159;\n//=========================\n\n// PRIMITIVE TYPE OF DATA BECAUSE IT ONLY STORES ONE VALUE\n\n//number ==================\nconst constante = 3.14;\n//=========================\n\n//bigint ==================\nconst bignumber = 1234567890123456789012345678901234567890n; // you have to append an N at the end to indentified it as a bigint\n// at this moment, BigInt is supported in Firefox/Chrome/Edge/Safari, but not in IE.\n//=========================\n\n//string ==================\nvariable = \"hello\";\nlet str = \"single quotes hehe\";\nlet str1 = `${variable}, Backticks as well hehe`; // You can insert or it allows embedding code by wrapping them in ${…} “extended functionality”\nconsole.log(str1);\n//=========================\n\n//boolean(logical type)==================\nlet one = true; // yes\nlet zero = false; // no\n\n//boolean type because of comparison\nlet comparison = 1 > 0;\nconsole.log(typeof comparison); // boolean type\n//=========================\n\n// THE NULL VALUE ==========================\nlet age = null; // age is unknown.\n// represents “nothing”, “empty” or “value unknown”.\n//=========================\n\n// undefined value ==========================\nlet people;\n// If a variable is declared, but not assigned, then its value is undefined:\nconsole.log(people);\n//=========================\n\n// SYMBOL  ==========================bol\nconst sym1 = Symbol(\"hello\"); //guaranteed to be unique\nconsole.log(variable == sym1); // false\n// symbols are the only primitive data type that has reference identity (that is, you cannot create the same symbol twice)\n//=========================\n\n// END OF PRIMITIVE ======================================================================\n\n// OBJECTS\nconst normalObj = {}; // create a normal object\n// It is used to store various keyed collections and more complex entities.\nconsole.log(typeof normalObj);\n//=========================\nconsole.log(\"¡Hola, Javascript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/migueltfangche.js",
    "content": "console.log('url oficial de JS:https://www.javascript.com/');\n\n//* este es un comentario*/\n/**\n * este es un comentario\n * con\n * salto\n * de linea\n */\n\nlet variable = {};\nconst variableConst = {};\n\nlet numero = 1;\nlet texto = \"hola mundo\";\nlet bolean = true;\nlet bolean2 = false;\nlet indefinido = undefined;\n\nconsole.log('Hola-Javascript');\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/misterdan100.js",
    "content": "// #00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n\n// JavaScript - https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n// one line comment\n\n/* comment on \nmultiple lines */\n\n//* Basic variables\nlet changingVariable\nconst constVariable = 0\n\n//* Primitive data types\nconst string = 'daniel' // String\nconst number = 100 // Number\nconst boolean = true || false // Boolean\nconst undefined = undefined // Undefined\nconst nullType = null // Null\nconst symbol = Symbol('id') // Symbol\nconst bigInt = 1234567890123456789012345n // BigInt\n\n//* Not primitives\n// this dates are objects themself\nconst object = { name: 'daniel', age: '28'} // Object\nconst array = ['apple', 'orange', 'banana'] // Array\nconst functionType = function() { console.log('Hi, Dan!')}\n\n//* Print something\nconsole.log('¡Hola, JavaScript!')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/monicavaquerano.js",
    "content": "// 00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n// Monica Vaquerano\n// https://monicavaquerano.dev\n\n/*\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n */\n\n// https://developer.mozilla.org/en-US/docs/Web/javascript\n\n// One-line comments\n\n/* \nMore\nthan\none\nline\ncomments \n*/\n\nvar variable = \"soy una variable\";\nlet variable2 = \"soy una variable tambien\";\nconst constante = \"soy una constante\";\n\n// Strings\nlet str = \"JavaScript\";\n// Numbers\nlet int = 1;\nlet float = 1.5;\nlet biggy = BigInt(\"123456789012345678901234567890\");\n// Booleans\nlet x = true;\nlet y = false;\n// Object\nlet person = { name: \"Monica\", lastname: \"Vaquerano\" }\n// Date\nconst today = new Date();\n// Null\nlet nulo = null;\n// Undefined\nlet indefinido = undefined;\n// Arrays\nlet cars = [\"Saab\", \"Volvo\", \"BMW\"];\n\nconsole.log(`¡Hola, ${str}!`)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/murquisdev.js",
    "content": "\r\n// DOCUMENTACIÓN JS\r\n// https://developer.mozilla.org/es/docs/Web/JavaScript \r\n\r\n// COMENTARIOS\r\n// Se pueden crear comentarios en una línea\r\n\r\n/* O en \r\nvarias líneas\r\n*/\r\n\r\nx = 3 // tanto los \"slash\" (barra /) como el \"slash\" + *  crean el comentario después /*, no a línea completa\r\nx = x + 5 // 8\r\n\r\n// VARIABLES Y CONSTANTES\r\n// JS tiene dos formas de crear variables, la diferencia se explicará más adelante\r\n// Al ser un lenguaje debilmente tipado, NO es necesario añadir el tipo de variable\r\n\r\n// Usando la palabra reservada var\r\nvar variableUno = 1 // tipo number (número)\r\nvariableUno = \"Uno\" // tipo String (cadena)\r\n\r\n// Usando la palabra reservada let\r\nlet variableDos = 2\r\nvariableDos = \"Dos\"\r\n\r\n// Las constantes se crean con la palabra CONST\r\n\r\nconst CONSTANTE = \"Soy una constante\"\r\n\r\n// DATOS PRIMITIVOS\r\n\r\n/* JS tiene 7 tipos de datos primitivos y NO es necesario indicar que tipo de dato va almacenar la variable\r\n    Los 3 \"básicos\"\r\n    number\r\n    string\r\n    boolean\r\n\r\n    null --> valor literal de JS, indica el valor nulo o \"vacío\" --> https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Operators/null\r\n    undefined --> Sin definir, una variable a lo que no se le asigna un valor --> https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/undefined\r\n    symbol  --> Un objeto para crear valores únicos --> https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Symbol\r\n    bigint --> Como number pero para almacenar números muy grandes\r\n\r\n*/\r\nlet numero = 1 // number\r\n\r\nlet cadena = \"String\" // String --> Se puede indicar un String con \"\", con '' o ``.\r\nlet comillasSimples = 'Cadena con comillas simples'\r\nlet comillasInclinadas = `Cadena con comillas inclinadas`\r\n\r\nlet boleano = true // boolean --> Solo acepta true o false (verdadero o falso)\r\n\r\n// ESCRIBIR POR CONSOLA\r\n// Para escribir por consola se utiliza la función console.log()\r\nconsole.log(\"!Hola, JavaScript!\")\r\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/n-skot.js",
    "content": "/* \n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n*/\n\n/* 00- Sintaxis, variables, tipo de datos, hola mundo */\n\n//------------------------------------------------------------------------------------------\n\n// Comentarios\n/* https://developer.mozilla.org/es/docs/Web/JavaScript */\n\n// variables\nvar variable1 = \"variable\";\nlet lenguaje = 'JavaScript';\nconst texto = 'constante';\n\n// datos primitivos\n\nconst string = 'string';\nconst number = 10;\nconst bigInt = 65654654654654654n;\nconst boolean = true;\nconst symbol = Symbol('numero');\nlet indefinido;\n\nconsole.log(`\n    La variable es tipo: ${typeof string} \\n\n    La variable es tipo: ${typeof number} \\n\n    La variable es tipo: ${typeof bigInt} \\n\n    La variable es tipo: ${typeof boolean} \\n\n    La variable es tipo: ${typeof symbol} \\n\n    La variable es tipo: ${typeof indefinido}\n`);\n\n// Hola mundo\nconsole.log(`Hola, ${lenguaje}!`);"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/natalyjoanna.js",
    "content": "// url: https://developer.mozilla.org/en-US/docs/Learn/JavaScript\n\n// Linea comentada\n\n/*\n    Varias\n    lineas\n    comentadas\n*/\n\nvar num = 0\nlet num2 = 0\nconst name = 'nataly'\n\nlet integer = 1\nlet double = 2.2\nlet float = 3.14159265359\nlet string = 'String'\nlet boolean = false\nlet boolean2 = true\nlet undefined\nlet symbol = Symbol('Symbol')\nlet bigNum = BigInt(23n)\n\nconsole.log(\"¡Hola, JavaScript!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/nestord23.js",
    "content": "//https://developer.mozilla.org/es/docs/Web/JavaScript\n\n/**SINTAXIS,\n * VARIABLES, TIPOS DE DATOS Y\n * HOLA MUNDO\n */\n\n//SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n\n// VARIABLES Y CONSTANTES\n\n// Variable (puede cambiar su valor)\nlet miVariable = \"Puedo cambiar\";\n\n// Constante (no puede cambiar su valor)\nconst MI_CONSTANTE = \"No puedo cambiar\";\n\n// Variable con var (antigua forma, no recomendada)\nvar variableAntigua = \"Mejor usar let\";\n\n// TIPOS DE DATOS PRIMITIVOS EN JAVASCRIPT\n\n// 1. String (cadena de texto)\nlet texto = \"Hola mundo\";\nlet textoComillasSimples = \"También con comillas simples\";\nlet textoTemplate = `Texto con template literals`;\n\n// 2. Number (número - enteros y decimales)\nlet entero = 42;\nlet decimal = 3.14159;\nlet negativo = -15;\nlet notacionCientifica = 2.5e6; // 2.5 * 10^6\n\n// 3. BigInt (números enteros muy grandes)\nlet numeroGrande = 9007199254740991n;\nlet otroGrande = BigInt(\"123456789012345678901234567890\");\n\n// 4. Boolean (booleano - verdadero o falso)\nlet verdadero = true;\nlet falso = false;\n\n// 5. Undefined (indefinido)\nlet indefinido;\nlet explicitamenteIndefinido = undefined;\n\n// 6. Null (nulo - ausencia intencional de valor)\nlet nulo = null;\n\n// 7. Symbol (símbolo - valor único e inmutable)\nlet simbolo = Symbol(\"descripción\");\nlet otroSimbolo = Symbol(\"descripción\"); // Cada Symbol es único\n\n// IMPRESIÓN POR TERMINAL\nconsole.log(\"¡Hola, JavaScript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/nfom24.js",
    "content": "/* 1.Crea un comentario en el código y coloca la URL del sitio web oficial del\nlenguaje de programación que has seleccionado.*/\n\n// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n/* 2.Representa las diferentes sintaxis que existen de crear comentarios\nen el lenguaje (en una línea, varias...)*/\n\nfunction comment() {\n    // Este es un comentario JavaScript de una línea\n    console.log(\"¡Hola mundo!\");\n  }\n  comment();\n\n  function comment() {\n    /*Este es un comentario \n    JavaScript de varias líneas*/\n    console.log(\"¡Hola mundo!\");\n  }\n  comment();\n\n// 3.Crea una variable (y una constante si el lenguaje lo soporta).\n\n//antes del ES6 las variables solo se declaraban con VAR\n\nvar javascript = true;\nvar edad = 18; \nvar precio = 9.99; \nvar nombre = 'Juan';\n\nlet javascript = true;\nlet edad = 18; \nlet precio = 9.99; \nlet nombre = 'Juan'; \n\nconst nombre = 'Juan'; // Es necesario agregar un valor \n// const nombre; Si la constante no tiene valor genera error\n\n/* 4.Crea variables representando todos los tipos de datos primitivos\ndel lenguaje (cadenas de texto, enteros, booleanos...)*/\n\nlet javascript = true; // boolean\nlet edad = 18; // Entero\nlet precio = 9.99; // Float \nlet nombre = 'Juan'; // String\n\n// 5.Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\nlet nombre = 'JavaScript';\n console.log(\"Hola\" + nombre)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/nicorey89.js",
    "content": "//comentario en una sola linea\n\n// link a la documentacion de javascript https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n/**\n * comentario de varias\n * lineas de codigo\n */\n\n//esto es una variable\n\nvar nombre = \"Nicolas\";\nlet apellido = \"Rey\";\n\n// esto es una constante\n\nconst lenguaje = \"Javascript\";\n\n// string\n\nconst string = \"soy un string\";\n\n//boolean\n\nconst booleanTrue = true;\nconst booleasFalse = false;\n\n//number y decimal\n\nconst number = 1;\nconst decimal = 1.1;\n\n//array\n\nconst array = [\"esto\", \"es\", \"un\", \"array\", 1, 2, 3];\n\n//objeto\n\nconst objeto = {\n    nombre:\"Nicolas\",\n    apellido:\"Rey\",\n};\n\nconsole.log(`¡Hola, ${lenguaje}! Soy ${nombre} ${apellido}.`);\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/nlarrea.js",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n// Documentación JavaScript: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n\n// Comentario de una línea\n\n/*\n    Comentario\n    de varias\n    líneas\n*/\n\n\n// Variables y constantes\nlet myVariable = 'Hello there!';\nconst myConstant = 'JavaScript';\n\n\n// Tipos de datos\nlet cadenaTexto = 'This is a string';\nlet entero = 7;\nlet decimal = 3.14;\nlet booleano = true;\nlet array = ['foo', 15, false, [1, 2, 3]];\nlet objeto = {\n    name: 'Naia',\n    age: 25\n};\nlet nulo = null;\nlet indefinido = undefined;\n\n\n// Imprimir texto por consola\nconsole.log('¡Hola JavaScript!');"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/nozodev.js",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n ** - Crea un comentario en el código y coloca la URL del sitio web oficial del\n **   lenguaje de programación que has seleccionado.\n ** - Representa las diferentes sintaxis que existen de crear comentarios\n **   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n//! Solucion 1\n\n// JAVASCRIPT no tiene sitio web oficial pero la mas cercanada es MDN.\n\n/**Comentario multilieal */\n// Comentario de una linea\n\n// Crea una variable (y una constante si el lenguaje lo soporta).\nconst lenguajeName = \"Javascript\";\n\nlet name = \"kevin\";\nconst apellido = \"rojas\";\n\n// Crea variables representando todos los tipos de datos primitivos\n\nlet str = \"Hola soy un dato primitivo cadena\";\n\nlet number = 10;\n\nlet bigInt = 9007199254740991n;\n\nlet booleanos = Boolean(true || false);\n\nlet symbol = Symbol;\n\nconsole.log(`Hola ${lenguajeName}`);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/nwpablodeveloper.js",
    "content": "// #00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n// https://www.javascript.com/\n\n/*\n    Comentario de\n    varias\n    lineas\n */\n\n\nlet variable;                       // Undefined\nconst variableConstante = 3.14; \n\n// Tipo de variables con datos primitivos numericos\nlet tipoInteger = 123;\nlet tipoFloat = 3.14;\nlet tipoEnteroNegativos = -354565;\nlet tipoBigInt = 123456789n         // Importante la \"n\" al final\n\n// Tipo de variables con datos primitivos booleanos\nlet tipoBoolean = true;\n\n// Tipo de variables con datos primitivos referenciados\nlet tipoArreglo = ['Pablo', 'Veiga', 'Argentino', 'Barcelona'];\nlet tipoObjeto = {\n    nombre: \"pablo\",\n    ciudad: \"barcelona\",\n    nacionalidad: \"Arg/Ita\",\n    edad: 35,\n    trabaja: true\n}\n \nconst saludoBienvenida = \"¡Hola\";\nconst lenguaje = \"javascript\";\n\nconsole.log(`${ saludoBienvenida } desde ${ lenguaje }`)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/ocram1304.js",
    "content": "//Para este proyeto he elegido la página de desarrolladoeres de mozilla, pues es ahí en donde aprendí las bases de JS\n//https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n//COMENTARIOS\n//Comentarios de una línea.\n/*\ncomentario de multiples lineas\n¡NO SE PUEDEN ANIDAR COMENTARIOS!\n*/\n//VARIABLES\n//JS soporta variables y constantes, cabe resaltar que la varibles son de tipo dinámico es decir, el tipo de dato que almacena la varible lo define el contenido \n//y no el contenedor.\nlet miVariable;\n// var era la antigua manera de declarar varibles sin embargo ha sido remplazada por let.\nvar miVaribleAntigu;\nconst miConstante = \"soyUnaConstante\";\n//TIPOS DE DATOS\n//JS cuenta con distintos tipos de datos.\n//datos númericos, entre los que se encuantran los enteros y los décimales o flotantes.\nlet datoEnter = 13;\nlet datoFlotante = 13.04;\n//datos de tipo caracter\nlet datoCadena = \"soyUnaCadena\";\n//datos de tipo referencia\n//Este tipo de datos funcinan como un apuntador, su función es representar el vació, o la ausencia de significado.\n//Null representa un valor vacío (aunque támbien se utiliza como apuntador)\nlet valorNulo = null;\n//undefined representar una varible a la que no se le ha asignado un valor, a direncia de \"null\" que reprenta el vacio, pero un valor al fin y al cabo\n//undifined representa lat total ausencia de valor. \nlet indefinido = undefined;\n\n//Hora de saludar\nconsole.log(\"HOLA JavaScript\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/oleojake.js",
    "content": "\n// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n/*\nOtra forma de hacerlo es así que nos permite escribir en varias líneas\n*/\n\n//Las variables pueden cambiar de valor\nvar variableVar; //Variable de alcance global\nlet variableLet; //Variable de alcance de bloque\n//Las constantes no pueden cambiar de valor, se deben inicializar cuando se declaran\nconst constantePi = 3.14;\n\n//Number\nlet numberExample = 1;\n//String\nlet stringExample = \"¡Hola, Javascript!\"\n//Boolean\nlet booleanExample = false;\n//Null, asigna un espacio vacío en memoria\nlet nullExample = null;\n//Undefined, no está asignada a ninguna parte de la memoria\nlet undefinedExample = undefined;\n//BigInt para números muy grandes\nlet bigIntExample = 1234567890987654321n;\n// Symbol cuyas instancias son unicas e inmutables\nlet symbolExample = Symbol(\"SYMBOL\");\n\nconsole.log(stringExample);"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/omegatroy.js",
    "content": "// * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n//  *   lenguaje de programación que has seleccionado.\n//  * - Representa las diferentes sintaxis que existen de crear comentarios\n//  *   en el lenguaje (en una línea, varias...).\n//  * - Crea una variable (y una constante si el lenguaje lo soporta).\n//  * - Crea variables representando todos los tipos de datos primitivos\n//  *   del lenguaje (cadenas de texto, enteros, booleanos...).\n//  * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n//  *\n\n// hola esto es un comentario en linea\n\n/* \n  esto es un comentario en loque\n  o tambien de varias lineas\n*/\n\n// una variable\nlet manga = 'Jujutsu Kaisen'\n\n//una constante\nconst creador = \"Gege Akutami\"\n\n// esta es una variable global. Desde hace años, ya no se recomienda usar var\nvar studio = \"MAPPA\"\n\n// tipos de datos primitivos\n\nlet cadenaDeTexto = 'esto es una cadena de texto o mejor conocida como string'\n\nlet numeroEntero = 2024 // --> esto es un numero entero\n\nlet booleanos = true // los booleanos pueden ser true o false, 0 o 1\n\nlet nula = null // --> null es inexistente o inválido\n\nlet variableIndefinida // --> undefined no existe argumentos reales\n\nlet identificadorSymbol = Symbol('símbolo') // --> symbol Sirven para crear identificadores\n\nlet bigintLiteral = 9007199254740991n // --> bigint Sirven para representar numeros extremadamente largos\nlet bigintLiteral2 = BigInt(9007199254740991)\n\nconst mortalKombat = {\n  nombre: 'mortal kombat',\n  creadores: 'Ed Boon y John Tobias',\n  año: 1992\n} // esto es un objeto tiene clave valor\n\n/*\n  Básicamente, TODO lo que no sea un valor primitivo, es un objeto. \n  Así que tanto arreglos como funciones son considerados \"Objetos\". \n  Lo que si es verdad es que podemos considerar los arreglos y las funciones como \n  \"sub-tipos de objetos\", ya que estos se comportan como tal, pero tienen \n  propiedades y comportamientos especiales\n*/\n\nlet arr = ['javaScript','python','java','rust','php'] // --> los array o listas pueden almacenar un conjunto de elementos\n\nfunction soyUnaFuncion(){\n  return console.log('¡Hola, javaScript!')\n}\n\nsoyUnaFuncion()"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/orlas135.js",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n\n//Comentario de una sola línea en JavaScript\n\n/*\n  Comentarios de\n  varias líneas\n  en JavaScript\n*/\n\n\n// Sitios WEB y documentación de Javascript de interés: \n\n/* \n  https://developer.mozilla.org/es/docs/Web/JavaScript\n  https://jonmircha.com/javascript\n  https://lenguajejs.com/javascript/\n*/\n\n\n\n/*Definiendo variables*/\n//Para definir una variable se hace uso de la palabra reservada let.\n//Para definir una constante se hace uso de la palabra reservada const\n\n/* \nTIPOS DE DATOS EN JS:\nPrimitivos: Se accede directamente al valor.\n\nstring\nnumber\nboolean\nnull\nundefined\nNaN\n\nCompuestos: Se accede a la referencia del valor.\n\nobject = {}\narray = []\nfunction () { }\nClass {}\n*/\n\n\n/*Definiendo el nombre de una variable*/\nlet nombre;\n\n/*Inicializando el valor de una variable*/\nnombre = 'Alexander';\n\n//Definiendo e inicializando una variable es una misma línea de código:\nlet apellido = 'Martínez'\n\n/*Number*/\nlet edad = 28;\n\n\n/*Boolean*/\nlet es_menor = false;\n\n/*Creando un objeto en JS*/\nlet persona = {\n  nombre: nombre,\n  apellido: apellido,\n  edad: edad,\n  saludo : () => {\n    console.log(`Mi nombre es: ${nombre + \" \" + apellido}. Tengo ${edad} años`)\n  }\n}\n\n/*Haciendo uso de los demás tipos primitivos en JS*/\nlet variable_nula = null;\nlet no_es_numero = NaN;\nlet indefinido;\n\n/*Utilizando la función saludo del objeto persona*/\npersona.saludo();\n\n/*Imprimiendo el valor de los demás tipos primitivos de JS*/\nconsole.log(indefinido);\nconsole.log(variable_nula)\nconsole.log(no_es_numero)\n\n/*Consultado el tipo de dato de algunas variables y del objeto*/\nconsole.log(typeof(nombre))\nconsole.log(typeof(es_menor))\nconsole.log(typeof(persona))"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/oscar503sv.js",
    "content": "// Web oficial de JavaScript\n// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Ejemplo de comentario en una linea\n\n/*\nEjemplo de comentario \nen varias lineas\n*/\n\n// Declarar variables (metodo no recomendado)\nvar variable1 = 'Hola';\n// Declarar variables (metodo si recomendado)\nlet variable2 = 'Hola mundo..';\n// Declarar constantes\nconst variable3 = 'Esto no se podra modificar despues';\n\n// Tipos de Datos Primitivos\n// -- String >>\nlet cadena = 'Cadena de texto de cualquier longitud';\n// -- Number >>\nlet numero1 = 5;\nlet numero2 = 6.77;\n// -- BitInt (numeros muy grandes) >>\nlet numeroGrande1 = 1234567890123456789012345n;\nlet numeroGrande2 = BigInt(1234567890123456789012345);\n// -- Boolean >>\nlet booleano1 = true;\nlet booleano2 = false;\n// -- Undefined >>\nlet noDefinido = undefined;\n// -- Symbol >>\nlet simbolo = Symbol('algo');\n// -- Null >>\nlet nulo = null;\n\n// Imprimir mensajes usando la consola del lenguaje\nconsole.log('¡Hola, JavaScript!');\n// Imprimir mensajes usando texto y valor de variables\nlet lenguaje = 'JavaScript';\nconsole.log(`¡Hola, ${lenguaje}!`);"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/othamae.js",
    "content": "/*\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n// Comment in one line\n\n/**\n * comment\n * in\n * block\n */\n\n\nconst constant = 'This is a constant'\n\nlet variable = 'This is a variable'\n\nvar globalVariable= 'This is a global variable'\n\n\n// 7 PRIMITIVE TYPES:\n\n// 1 - String\nlet string = 'This is a string'\n\n// 2 - Number   \nlet number = 10\nlet float = 10.5\n\n// 3 - BigInt\nlet bigInt = BigInt(9007199254740991) // 9007199254740991n\n\n// 4 - Boolean\nlet boolean = true\n\n// 5 - Undefined\nlet undefinedVariable\n\n// 6 - Symbol\nlet symbol = Symbol('This is a symbol')\n\n// 7 - Null\nlet nullVariable = null\n\n\n// Print in terminal:\nconsole.log(\"¡Hola, JavaScript!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/ovjohn.js",
    "content": "//URL del sitio web oficial: \"https://developer.mozilla.org/es/docs/Web/JavaScript\"\n\n//Esta es la forma de hacer un comentario de una linea\n\n/*De esta forma \nse puede realizar\ncomentarios  \nde valiar lineas*/\n\nvar variableGlobal = \"Esta es una variable Global\"\nlet variable = \"Variable con alcance limitado a su bloque\";\nconst constante = 4;\n\n\n //Crea variables representando todos los tipos de datos primitivos\nlet numero = 4; //number\nlet cadena =\"Javascript\" //String \nlet booleana = true; //Boolean\nlet r; //undefined\nlet varNula = null; //Nulo\n\nconst name = \"Javascript\"; \nconsole.log(\" !Hola,\" + name + \"!\")\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/pabloTaber.js",
    "content": "// Pagina web oficial para JavaScript --> https://developer.mozilla.org/es/docs/Web/JavaScript\n\n//Comentario de una linea.\n\n/*\n    Comentario\n    de\n    varias\n    lienas\n */\n\n// --- Crea una variable y una constante ---\nlet variable = \"Esto es una variable\";\nconst constante = \"Esto es una constante\";\n\n// --- Crea variables representando los tipos de datos primitivos ---\n\n//Variable para el tipo de datos Boolean\nlet boolean = true;\n\n//Variables para el tipo de datos Number\nlet numeroEntero = 12;\nlet numeroDecimal = 12.12;\n\n//Variable para el tipo de datos BigInt\nlet numeroGrande = 12345678997452n;\n\n//Variable para el tipo de datos String\nlet cadena = \"Estos es un string\";\n\n//Variable para el tipo de datos Undefined\nlet sinDefinir;\n\n//Variable para el tipo de datos Symbol\nlet simbolo = Symbol(\"simbolo\");\n\n// --- Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\" ---\nconsole.log(\"¡Hola, Javascript!\")\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/pakiuh.js",
    "content": "/** This function does something. */\r\n// Comentario en una línea.\r\n/**\r\n * Comentario en varias líneas.\r\n * @param {number} num - The input number.\r\n * @returns {number} - The result of the operation.\r\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript|JavaScript Official Documentation}\r\n */\r\n\r\n// Declaración de una variable\r\nlet myVariable = 10;\r\n\r\n// Declaración de una constante\r\nconst MY_CONSTANT = 20;\r\n\r\n// Declaración de una variable de tipo string\r\nlet myString = \"Hello, World!\";\r\n\r\n// Declaración de una variable de tipo number\r\nlet myNumber = 10;\r\n\r\n// Declaración de una variable de tipo boolean\r\nlet myBoolean = true;\r\n\r\n// Declaración de una variable de tipo null\r\nlet myNull = null;\r\n\r\n// Declaración de una variable de tipo undefined\r\nlet myUndefined;\r\n\r\n// Declaración de una variable de tipo symbol\r\nlet mySymbol = Symbol();\r\n\r\n// Declaración de una variable de tipo bigint\r\nlet myBigint = 10n;\r\n\r\n// Imprimir hola JavaScript en la consola\r\nconsole.log(\"Hola JavaScript!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/parababire.js",
    "content": "/* EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n\n//La url que más uso en JavaScript es https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n//Comentario de una linea\n\n/*Comentario de \nlineas multiples*/\n\nlet nombre = \"Ángel Narváez\"; //Una variable\n\nconst sexo = \"masculino\"; //Una constante\n\n//Datos primitivos\n\n//string\nlet str = \"hola mundo\";\n\n//number\nlet edad = 44;\n\n//bigint\nlet bigInt = 9007199254740991n;\n\n//boolean\nlet futuroDev = true;\n\n//undefined\nlet terminareReto2024;\n\n//symbol\nlet sym = Symbol();\n\n//null\nlet quizaNull = null;\n\n//Impresión en consola\nconsole.log(\"Hola, JavaScript\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/patricioguerra30.js",
    "content": "//https://developer.mozilla.org/es/docs/Web/JavaScript\n\n/* para comentar varias lineas\nxd\n*/\nvar nombre1 = \"nombre\";\nlet numero1 = 6;\nconst constante1 = \"xd\";\n// datos primitivos\nlet texto = \"isa se quedo jataso\";\nlet decimal = 3.14;\n\nlet verdadero = true;\nlet falso = false;\nlet nulo = null;\n\nconsole.log(\"¡Hola, Javascript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/pedamoci.js",
    "content": "// sitio web oficial: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// El doble slash te permite hacer un comentario de uana sola linea\n\n/* El slash y le asterisco \n    te permiten hacer comentarios\n    de múltiples lineas\n*/ \n\n// Variable global\nvar pokemon = 'Snorlax'\n\n// Variable local\nlet tipo = 'Normal'\n\n// Constante\nconst nivelMaximo = 100\n\n// tipos de datos primitivos\nlet varBoolean = true\nlet varNull = null\nlet varUndifined = undefined\nlet varNumber = 2002\nlet varBigInt = 3141592653589793238462643n\nlet varString = 'JavaScript'\nlet varSymbol = Symbol('JS')\n\n// Imprimir en terminal\nconsole.log(`¡Hola, JavaScript!`)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/pedroomar23.js",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n// Sitio web para ver la documentacion de Java Script https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n// Esto es un comentario de una sola linea \n\n/*\n    Esto son comantarios de \n    varias lineas \n*/\n\n// Variable y Constante\nlet nombre = \"Hola Mundo\"\nconst numero = 35\n\n// String \nlet nombre1 = \"Hola Mundo\"\n\n// Bool\nlet active = true\nlet notActive = false \n\n// Enteros\nlet number = 27\n\n// Nil\nlet hola = nil \n\n//Undefinid\nlet holaMundo\n\n// Symbols\nlet symbol = Symbol('Hola Mundo')\n\n// Consola \nconsole.log(\"!Hola, Estoy aprendiendo Java Script\")\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/peticas.js",
    "content": "/**\n * https://www.javascript.com/\n * https://developer.mozilla.org/es/docs/Web/JavaScript\n */\n\n// Comentario de una linea\n\n/*\n   Comentetio entre varias lineas\n*/\n\nlet variable_alcance_de_bloque;\nvar variable_alcance_local;\nconst constante = 1;\n\nlet numero1 = 1;\nlet numero2 = 1.1;\nlet caracter1 = \"Caracter\";\nlet caracter2 = \"Caracter\";\nlet caracter3 = \"C\";\nlet cadena = [\"1\", 2, \"3\"];\nlet booleanos = true;\nlet nuleable = null;\nlet indefinido = undefined;\n\nconsole.log(\"¡Hola, JavaScript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/pguillo02.js",
    "content": "//Se declaran variables con let y constantes con const\n//Se pueden incializar variables sin valor y asignarselo después, también se pueden cambiar después de inicializarlas\nlet variable = 'Hola Mundo';\nvariable = 5\nlet mundo;\nmundo = 'Hola Mundo';\n\n\n//Tipos de datos primitivos\n\nlet Boolean = true;\nlet Number = 5;\nlet BigInt = 9007199254740991n;\nlet __undefined = undefined;\nlet __null = null;\nlet String = 'Hola Mundo';\nlet Symbol = Symbol('Hola Mundo');\n\n//PRINT\nconsole.log(\"Hola Mundo\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/pointfs.js",
    "content": "/*https://tc39.es/ecma262 \n\nhttps://developer.mozilla.org/es/docs/Web/JavaScript/*/\n\n// Variables\n\nlet myVar = 10;\n\nconsole.log(myVar);\n\nvar myVar2 = 20; //en desuso nada recomendable//\n\nconsole.log(myVar2);\n\n//constantes\n\nconst myVar3 = 30;\n\nconsole.log(myVar3);\n\n//Tipos de datos primitivos\n\nlet myString= \"Hola Mundo\";\n\nlet myNumber = 10;\n\nlet myBoolean = true;\n\nlet myBoolean2 = false;\n\nlet myUndefined = undefined;\n\nlet myNull = null;\n\nconsole.log(myString, myNumber, myBoolean, myBoolean2, myUndefined, myNull);\n\n//Tipos de datos especiales\n\nlet myNumberEnorme= BigInt(9007199254740991);\n\nconsole.log(myNumberEnorme);\n\nlet mySymbol = Symbol(\"mi simbolo\");\n\nconsole.log(mySymbol);\n\nlet myNumberDecimal = 10.5;\n\nconsole.log(myNumberDecimal);\n\nlet myInfinity = Infinity;\n\nconsole.log(myInfinity);\n\nlet myNaN = NaN;\n\nconsole.log(myNaN);\n\n\n//Tipos de datos compuestos\n\nlet myArray = [10, 20, 30, 40, 50];\n\nlet myObject = {\n    nombre: \"Juan\",\n    edad: 30\n};\n\nconsole.log(myArray, myObject);\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/popmaquin.js",
    "content": "/*https://developer.mozilla.org/es/docs/Web/JavaScript */\n// comentario de una sola línea.\n/*\n    Comentario de\n    Varias líneas.\n*/\n\nlet nombre= \"Julio\";\nconst Genero =\"Masculino\";\n\n//Datos primitivos.\nlet DP_cadenaTexto= \"Hola soy string\";  //String\nlet DP_numero= 125;                     //number\nlet DP_boolean= true;                   //boolean valor-> true o false.\nlet DP_symbol= Symbol(1);               //Symbol\nlet DP_undefined;                       //undefined\nlet DP_null=null;                       //null\n\nconsole.log(\"¡Hola, Javascript!\");      //Salida: ¡Hola, Javascript!\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/ppinilla.js",
    "content": "//00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n\n/*\n EJERCICIO:\n - Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n - Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n - Crea una variable (y una constante si el lenguaje lo soporta).\n - Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n */\n\n//- Sitio web oficial de JavaScript: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n//a one line comment\n\n/* this is a longer, \nmulti-line comment\n*/\n\n//- Declaraciones de variables:\n//Declara una variable, opcionalmente la inicia a un valor.\nvar user = \"ppinilla\";\n\n//Declara una variable local con ámbito de bloque, opcionalmente la inicia a un valor.\nlet age = 23;\n\n//Declara un nombre de constante de solo lectura y ámbito de bloque\nconst PI = 3.14\n\n// - Tipos de datos primitivos\nlet float = 1.5\nlet int = 10\nlet booleanoT = true\nlet booleanoF = false\nlet string = \"JavaScript\"\nlet n = null\nlet undf = undefined\n\n// - Imprimir por terminal\nconsole.log(\"¡Hola, JavaScript!\");\n\nconsole.log(typeof(float));\nconsole.log(typeof(int));\nconsole.log(typeof(booleanoT));\nconsole.log(typeof(booleanoF));\nconsole.log(typeof(string));\nconsole.log(typeof(n));\nconsole.log(typeof(undf));"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/pype-Dev.js",
    "content": "// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Esto es un comentario breve en una sola línea código\n\n/*\nEste es un bloque de comentario o un comentario de varias lineas.\nAunque JavaScrip no cuente con un sitio oficial como si lo hacen otros lenguajes, contamos con tres referencias bastante grandes y muy útiles:\n1. Estandar internacional ECMAScript: https://ecma-international.org/\n2. Documentación más completa y autorizada utilizada por desarrolladores: https://developer.mozilla.org/es/docs/Web/JavaScript\n3. Iniciativa impulsada por Google para mejorar las prácticas de programación: https://web.dev/javascript?hl=es-419\n*/\n\n/**\n * Aunque la sintaxis con el comentario en bloque es muy similar, esto es más que un comentario.\n * JSDoc es un lenguaje de marcado para documentar el código escrito en JS, permitiendo a los\n * desarrolladores destacar funciones, algoritmos, clases, etc.\n * \n * NOTA: La información presente en este bloque es más poderosa y se puede integrar con otros ambientes.\n */\n\n\n// Declarar varialbes en js\nvar name = \"Felipe\" //sentencia que dejo de ser utilizada tras la llegada de ES6\n\nlet edad = 23;\nedad = 30;\n\n// Declarar variables en js\nconst PI = 3.1416;\n\n// Tipos de datos primitivos\nlet $precio = 100000; //number\nlet ciudad = \"Bogotá\"; //string\nlet esMayor = true; //boolean\nlet x; //undefined\nlet resultado = null; //null\nconst idUnico = Symbol(\"MySymbol\"); //symbol\nconst numGrande = 4561654894516548974841515n; //BigInt\n\n// Imprimir mensaje\nlet message = \"JavaScript\";\nconsole.log(`¡Hola, ${message}!`)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/qwik-zgheib.js",
    "content": "// this comment is a single line comment\n\n/*\nthis is a multi-line comment\n*/\n\n/* read docummentation js in: https://developer.mozilla.org/en-US/docs/Web/javascript */\n\nvar text = \"Hello, Javascript!\";\nvar number = 10;\nvar boolean = true;\n\nconsole.log(text);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/r4kso.js",
    "content": "// 00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n\n/*\n  EJERCICIO:\n  - Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n  - Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n  - Crea una variable (y una constante si el lenguaje lo soporta).\n  - Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n  - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n*/\n\n/* --------------------------------*/\n\n// - Sitio oficial del lenguaje JavaScript: https://developer.mozilla.org/en-US/docs/Web/javascript\n\n/* COMENTARIOS:\n    -> // Comentario de una sola línea\n    -> /*\n        Comentario\n        de\n        múltiples\n        líneas\n       */\n\n// VARIABLES Y CONSTANTES\nlet variable = 69\nconst constant = 13\n\n// DATOS PRIMITIVOS\n// 1. Undefined: Es una manera de representar la ausencia de un valor\nlet undefinedAux;\n\n// 2. Null: Quiere decir que tenemos un valor nulo y es otra manera de representar la ausencia de un valor\nconst nullAux = null\n\n// 3. Number: Todos los valores que representan un número, tanto enteros como racionales\nconst numberAux = 3\n\n// 4. String: Datos en formato texto (Cadena de caracteres)\nconst stringAux = \"Esto es un string\"\n\n// 5. Boolean: Aquellos valores que se representan como verdadero/falso (1/0)\nconst booleanAux = true\n\n// 6. BigInt: Permite representar números muy grandes\nconst bigIntAux = 1234783n\n\n// 7. Symbol: Incluye un constructor que devuelve un symbol primitivo cuyo valor está garantizado que es único. Se suelen usar para añadir claves únicas a objetos\nconst symbolAux = Symbol(\"key\")\n\n// IMPRIMIR POR PANTALLA\nconsole.log(\"¡Hola, JavaScript!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/ralphmcralph.js",
    "content": "// Esto es un ejemplo de comentario\r\n// La documentación de Javascript puede encontrarse en: https://developer.mozilla.org/en-US/docs/Web/JavaScript\r\n\r\n// También es posible comentar en varias líneas\r\n\r\n/* Este es el caso\r\n * comentario multilínea\r\n */\r\n\r\n// Las variables se pueden declarar con var, const y let\r\n\r\nvar a = 1;\r\n\r\nlet b = 2;\r\n\r\nconst c = 3;\r\n\r\n// Ahora crearemos variables representando todos los tipos de datos primitivos del lenguaje:\r\n\r\n// Cadenas de texto\r\n\r\nlet textString = \"Hola mundo\";\r\n\r\n// Enteros\r\n\r\nlet intNumber = 33;\r\n\r\n// Booleanos\r\n\r\nlet boolExample = true;\r\n\r\n// Nulos\r\n\r\nlet nullExample = null;\r\n\r\n// Indefinidos\r\n\r\nlet undefinedExample = undefined;\r\n\r\n// Grandes enteros\r\n\r\nlet bitInteger = 796845464644324564687n;\r\n\r\n// Símbolos\r\n\r\nconst sym1 = Symbol(\"foo\");\r\n\r\n// Última tarea\r\n\r\nconst lenguaje = \"Javascript\"\r\n\r\nconsole.log(`¡Hola, ${lenguaje}!`);\r\n\r\n\r\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/raul-progr.js",
    "content": "/* La pagina oficial de JS es : https://developer.mozilla.org/es/ */\n\n/* esto es un comentario en una linea */\n/* esto\nes\nun\ncomentario\nen\nvarias\nlineas\n*/\n\n/* declaracion de variables */\n\nvar variable = \"esta es una variable\";\nlet otraVariable = \"esta es una variable, pero se usa en el scope de un bloque\"\nconst Pi = 3.1415 /* esta es una constante, nunca cambia de valor */\n\n/* Datos primitivos */\n\nvar texto = \"Esto es un string\";\nvar numero = 69.69; /* esto es un numero, puede ser float tambien */\nvar numeroGrande = BigInt(Number.MAX_SAFE_INTEGER); /* esto es un bigint */\nvar numeroGrande2 = 9007199254740991n; /* esto tambien es un bigint, se agrega n al final */\n/* comparemos si los bigints son iguales */\nif (numeroGrande === numeroGrande2){\n    console.log(true);\n} else{\n    console.log(false);\n}\nvar buleano = true; /* variable boolean con valor true asignado, puede ser false */\nvar indefinida; /* el valor primitivo undefined es cuando una variable no se le a asignado un valor */\nvar nulo = null;\n/* hola Javascript!!! */\n\nconsole.log(\"¡Hola, Javascript!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/raulG91.js",
    "content": "//URL: https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n/*\nThis is a comment in Javascript\n*/\n\n//This is also a comment in Javascript\n\n//Variable declaration\nlet number = 0;\n\n//Constant\nconst PI = 3.1416;\n\nlet integer = 2;\nlet bigInt = 1234567890123456789012345678901234567890n;\nlet double = 3.5;\nlet string = \"This is an string\";\nlet another_string = 'This is another string';\nlet string_v3 = `This is a string with calculations ${1+2}`\nlet boolean = true;\nlet another_boolean = false;\nlet isNull = null;\nlet isUndefined = undefined;\n\n\nconsole.log(\"¡Hola Javascript!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/reinaldosanchez.js",
    "content": "//URL oficial de JavaScript: https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n// Comentarios\n// Comentario de una línea\n/* Comentario de varias líneas */\n\n// Variables\nlet nombre = \"Reinaldo\";\nconst apellido = \"Sanchez\";\nvar edad = 39;\n\n// Tipos de datos\nlet tuNombre = \"Reinaldo\"; // String\nlet edad = 39; // Number\nlet esMayorDeEdad = true; // Boolean\nlet precio = 19.99; // Number\nlet nombreCompleto = \"Reinaldo Sanchez\"; // String\n\nconsole.log(\"Hola, JavaScript!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/rlores-edison.js",
    "content": "//00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n//Ejercicio\n\n/*\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n */\n\n\n\n\n\n//este es el comentario de mi lenguaje de programación\n\n/* este es un comentario de más de una línea que contiene la página web oficial \ndel lenguaje elegido, que es javascript y la página oficial es \nhttps://262.ecma-international.org/14.0/ y también https://developer.mozilla.org/es/*/\n\nlet miVariable = \"hola mundo\"; // se utiliza si no se puede usar const\nvar MiOtraVariable = \"hello world\"; //se utiliza en código escrito para navegadores antiguos\nconst miConstante = \"ciao mondo\"; // esta es una constante, cuyo valor no debería cambiar (arrays y objetos)\n\n\nconst actor = \"Chuck Norris\", //esto es un string o cadena de texto\nage = 69, \nisMale = true, //este dato es un boolean: true or false\nheight = 1.8, //float = decimales\nweight = 70, // integer = entero\neyeColor = \"blue\", \nhairColor = \"blond\", \nbirthday = new Date(\"1980-01-01\"), \nhobbies = [\"chess\", \"baseball\", \"snowboarding\"], //Esto es un array\nfavFood = \"\", //esta variable tiene un valor undefined\nlanguage = \"English\";\n\nArray.isArray(hobbies);\n\n\nvar numeroGrande = 9007199254740991n; // esto es un bigint, se añade \"n\" al final\nconst nullAux = null // esto es un valor nulo. En javascript, el valor null es una forma de representar la ausencia de un valor\ntypeof {name: \"Raquel\", age: 99} // devuelve object\n\n\nconsole.log(\"¡Hola, JavaScript!\");\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/robmxz.js",
    "content": "// https://developer.mozilla.org/es/docs/Web/JavaScript/Guide --> Documentación oficial de JavaScript\n\n// Comentario de una línea\n\n/*\n  Comentario\n  de \n  varias \n  lineas\n*/\n\n// Variables\n\nvar miVariable = \"Esta es una variable global\";\n\n// Constantes\n\nconst VARIABLE = \"Esta es una variable constante\";\n\n// Tipos de datos\n\nlet miCadena = \"Hola Retos de Programación\";\nlet miNumero = \"26122023\";\nlet miBooleano = true;\nlet miArreglo = [26, 12, 2023];\nlet miObjeto = { Dev: \"RobMxz\", Pais: \"Peru\" };\n\n// Impresión por consola\n\nconsole.log(\"Hola, Javascript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/rojasvargas.js",
    "content": "/**\n * * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n */\n\n// Javascript - Los comentarios: este es un comentario de una línea, se puede colocar al inicio de la linea o al final\n\n/* este es un comentario\n * más largo, de varias líneas\n */\n\n/* - Crea una variable (y una constante si el lenguaje lo soporta).*/\n\n/** VARIABLES : \n *  var\n        Declara una variable, opcionalmente la inicia a un valor.  se puede utilizar para declarar variables locales y globales, dependiendo del contexto de ejecución. (NO RECOMENDADO)\n*/\n\nvar variableGlobal = 0;\n\n/**\n * let\n        Declara una variable local con ámbito de bloque, opcionalmente la inicia a un valor.\n */\n\nlet variable = 0;\n\n/** CONSTANTES\n * const\n        Declara un nombre de constante de solo lectura y ámbito de bloque.\n */\n\nconst constante = 0;\n\n// * - Crea variables representando todos los tipos de datos primitivos\n// *   del lenguaje (cadenas de texto, enteros, booleanos...).\n/**\n * Javascript cuenta con Siete tipos de datos que son primitivos\n */\n\nlet entero = 9;             //Number\nlet conDecimal = 3.14159    //Number\nlet texto1 = 'Hola Mundo' ;  //String,\nlet texto2 = \"Hola Mundo\" ;  //String,\nlet texto3 = `Hola Mundo` ;  //String,\nlet verdader = true;        // Boolean\nlet falso = false;          // Boolean\nlet noDefinido;\nlet unDefinido = undefined  // Undefined\nlet conPrecision = 9007199254740992n; //BigInt\nlet sym1 = Symbol();        //Symbo (nuevo en ECMAScript 2015).\nlet  nulo = null            // null\n\n\n// * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\nconsole.log(\"¡Hola, javascript!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/romanocoder.js",
    "content": "// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Comentario de una linea\n\n/* \nComentario de mas de una linea\n\n¡Gracias Brais! Aprovecho para saludarte desde Argentina.\n*/\n\nconst user = \"Romanocoder\"\n\nlet reto = [\"#00\", \"Sintaxis, Variables, tipos de datos y hola mundo\"]\n\nconst JavaScript = true\n\nlet exp = null\n\nlet edad = 27\n\nlet texto = \"Mi primer reto,hasta que entendi el flujo colaborativo\"\n\nconsole.log(\"Hola JavaScript\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/ronitzdev.js",
    "content": "/* Sitio oficial: Mozilla Developer Network (MDN) | URL: https://developer.mozilla.org/es/docs/Web/JavaScript */\n\n/* Este es un comentario de una linea */\n\n/*  \n    Este es \n    un comentario \n    de varias lineas \n*/\n\nvar var1 = 1; /* tienen alcance de función o alcance global, se pueden volver a declarar */\nlet var2 = 2; /* tienen alcance de bloque, no se pueden volver a declarar dentro del mismo bloque */\nconst var3 = 3; /* también tienen alcance de bloque, no pueden ser reasignadas a un nuevo valor */\n\nlet nombre = \"Juan\";              // String\nlet edad = 25;                    // Number\nlet precio = 19.99;               // Number (flotante)\nlet numeroGrande = 9007199254740991n; // BigInt\nlet esMayorDeEdad = true;         // Boolean\nlet esEstudiante = false;         // Boolean\nlet noDefinido;                   // undefined\nlet valorNulo = null;             // null\nlet simbolo = Symbol('descripcion'); // Symbol\n\nconsole.log('¡Hola, JavaScript!'); //Imprime por terminal"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/ronnieruuz.js",
    "content": "//#00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n\n// *** JAVASCRIPT *** https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// *** CREAR COMENTARIOS *** https://developer.mozilla.org/es/docs/Web/JavaScript/Guide/Grammar_and_types#comentarios\n// Este es un comentario de una linea\n\n/* Este es un comentario\n * más largo, de varias líneas\n */\n\n// *** DECLARAR VARIABLES *** https://developer.mozilla.org/es/docs/Web/JavaScript/Guide/Grammar_and_types#variables\nvar variableVar; // No se recomienda utilizar var para crear variables.\nlet variableLet;\nconst variableConst = \"1\"; //Siempre debe estar inicializada (asignar un valor)\n\n// TIPOS DE DATOS PRIMITIVOS https://developer.mozilla.org/es/docs/Web/JavaScript/Guide/Grammar_and_types#tipos_de_datos\n//https://developer.mozilla.org/es/docs/Learn/Getting_started_with_the_web/JavaScript_basics#variables\nlet booleano = true;\nlet string = 'Bob';\nlet number = 10;\nlet array = [1,'bob','Steve', 10];\n\n// *** IMPRIMIR HOLA MUNDO *** https://developer.mozilla.org/es/docs/Learn/Getting_started_with_the_web/JavaScript_basics#ejemplo_%C2%AB%C2%A1hola_mundo!%C2%BB\n// Para imprimir por consola es necesario instalar NodeJS (https://nodejs.org/en)\nconsole.log(\"¡Hola, JavaScript!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/rotsenn.js",
    "content": "// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Comentario de una linea / one line comment --> // \n\n/*\n    comentario de \n    multiples \n    lineas\n    /\n    multiples lines comment\n*/ \n\n\n\nvar variableVar; // variable usando la palabra reservada var\nlet variableLet; // variable usando la palabra reservada let\nconst variableConst = undefined; // variable usando la palabra reservada const\n\n// datos primitivos\nlet indefinido = undefined; \nlet booleanoTrue = true; // devulve palabra reservada true\nlet booleanoFalse = false; // devulve palabra reservada false\nlet numero = 5; // devulve un numero\nlet texto = 'Hola Mundo' // devulve una cadena de caracteres\nlet numeroGrande = 2n ** 53n; // numero entero muy grande, se crea agregando n al final de un numero entero\nlet simbolo = Symbol('foo'); // valor unico\n\nconsole.log('\\\"\\!Hola, Javascript!\\\"\\ ');\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/rserradev.js",
    "content": "// Crear comentario y colocar la URL del sitio web oficial\n\n// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Diferentes maneras de hacer comentarios\n\n// Comentario de una linea\n\n/* \nComentario\nde \nvarias\nlineas \n*/\n\n// Crear una variable y una constante\nlet myVariable = \"String\";\nconst MyConstant = \"My constant\";\n\n// Tipos de datos primitivos\nlet number = 1;\nlet string = \"1\";\nlet float = 1.1;\nlet bool = true;\nlet undefined;\nlet symbol = Symbol(\"1\");\n\n// Imprimir por pantalla el texto Hola -> nombre del lenguaje\nlet saludo = \"¡Hola\"\nlet lenguaje = \"Javascript!\"\n\nconsole.log(saludo + \" \" + lenguaje);"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/s9code.js",
    "content": "// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Comentario de una linea\n\n/* Comentario \nde varias\nlineas\n*/\n\n/* \n1. Variable y constante\n2. Crear viarbles representando los tipos de datos primitivos\n*/\n\nlet variable;\nconst noDoyError = 'Si no declaro, doy error'\n\nconst string = 'Hola'\nconst number = 1\nconst boolean = true\nconst nulo = null\nlet undefined;\nlet symbol = Symbol(\"simbolo\")\nconst bigInt = 222n\n\n// Imprimir por terminal\n\nconsole.log('Hola, Javascript')\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/saicobys.js",
    "content": "/*\n  EJERCICIO:\n  - Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n  - Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n  - Crea una variable (y una constante si el lenguaje lo soporta).\n  - Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n  - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n*/\n\n// Sitio web oficial de JavaScript: https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n/* Crea todo los tipos de variable */\nvar camelCase = \"ThisIsCamelCase\";\nlet UpperCase = \"ThisIsUpperCase\";\nconst PERMANENT_DATA = \"JavaScript\";\n\n// Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\nvar country = \"Dominican Reoublic\";\nvar numeroDeProvincias = 32;\nvar colonizadoPorCristobal = true;\nvar suma = x + 3;\nvar numeroEntero = 4;\n\n// Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\nvar saludoYLenguaje = \"¡Hola, JavaScript!\";\nconsole.log(saludoYLenguaje);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/samrdx.js",
    "content": "// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Comentario de una linea\n/* Comentario de \nvarias lineas \n*/\n\nconst const1 = 1\nvar var1 = 1\nlet var2\n\nconst stringType = 'JavaScript'\nconst intType = 1\nconst boolType = true\nconst nullType = null\nconst undefinedType = undefined\n\nconsole.log(`¡Hola, ${stringType}`)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/sandracalatayud.js",
    "content": "/* \n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n */\n\n/* \n    El lenguaje que he elegido es javascript\n    https://developer.mozilla.org/en-US/docs/Web/JavaScript\n*/\n\n//Puede haber comentarios en una línea\n\n/* \n    O comentarios\n    en varias líneas\n*/\n\n//Creación de una variable:\n\n    var mi_variable = \"Esta es mi variable\"\n    let mi_variable_2 = \"Esta es mi segunda variable\"\n\n        /*\n            var = permite acceder desde cualquier parte del código\n            let = solo se puede acceder desde el bloque de código en el que se declare\n        */\n\n//Creación de una constante\n\n    const mi_constante = \"Esta es mi constante\"\n\n//Variables que representen todos los tipos de datos:\n\n    var tipo_booleano = true;\n    var tipo_null = null;\n    var tipo_undifined;\n    var tipo_numero = 10;\n    var tipo_float = 1.5;\n    var tipo_bigInt = 38382928485922n;\n    var tipo_string = 'Hola mundo';\n    var tipo_symbol = Symbol('simbolo');\n\n//Imprimir en consola\n\n    console.log('¡Hola, Javascript!')\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/sans6114.js",
    "content": "//solución de parte de: https://github.com/sans6114\n\n// lenguaje seleccionado: javascript\n//documentación: https://developer.mozilla.org/en-US/docs/Web/JavaScript\n// comentarios:  one line comment = '//'    multi line comment: start with '/*' and end with '*/'\n\n// examples: one line comment: '//este es un comentario de una linea' multi line comment: \n/* \ndocument.getElementById(\"myH\").innerHTML = \"My First Page\"; --> esta linea de codigo sera ignorada por javascript\n*/\nlet miVariable = 'hola soy una variable'\nconst miConstante = 'hola soy una constante'\n\n\nlet strings = 'este es un string'\nlet numbers = 10\nlet boolean = true\nlet nullish = null\nlet undefined = undefined\nlet bigInt = 67890987654323456789n\nlet symbol = symbol()\n\nconst lenguaje = 'javascript'\n\nconsole.log(`¡Hola, ${lenguaje}`)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/santaravena.js",
    "content": "// 00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n\n// Sitio web documentacion: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Comentario en una linea\n\n/* Comentario en mas de una linea: Lorem ipsum dolor sit amet, consectetur adipiscing elit. \nCras maximus lectus at mi aliquet luctus. Maecenas tincidunt a sapien vel finibus. Maecenas feugiat magna ante, sed rhoncus purus sodales ut. Morbi urna nibh, dictum in quam at, posuere scelerisque erat. Donec in erat tristique, scelerisque nisi eget, varius tortor.*/ \n\n// Variable y constante\nlet edad = 33;\nconst nombre = \"Angel\";\n\n//Datos primitivos\nlet direccion = 25; // Number\nlet decimal = 2.5; // Number\nlet apellido = \"Santana\"; // String\nlet segundoApellido = 'Aravena'; // String\nlet tieneMascota = true; // Booleano\nlet tieneMascota2 = false; // Booleano\nlet tieneCasa = null; // Null\nlet automovil; //undefined\nlet viaje = Symbol(\"descripcion\"); // Symbol\n\n// Imprimir por terminal\nconsole.log(\"¡Hola, Javascript!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/santiagoCamachoCamino.js",
    "content": "// 00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n// Santiago Camacho Camino\n// 2025-04-21\n\n/**\n * Crea un comentario en el código y coloca la URL del  \n * sitio web oficial del lenguaje de programación que ha\n * seleccionado.\n */\n//Documentación de JavaScript\n//https://developer.mozilla.org/es/docs/Web/JavaScript\n\n/** \n * Representa las diferentes sintaxis que existen de \n * crear comentariosen el lenguaje (en una línea, \n * varias...).\n*/\n// Se puede hacer comentarios con // o con /* */\n// -> '//' para una línea\n/**\n * -> '/*' para varias líneas\n */\n\n/**\n * Crea una variable (y una constante si el lenguaje lo soporta).\n */\nlet variable1=\"Esto es un String\";\n\nconst constante1=\"Esto es una constante\";\n\n/**\n * Crea variables representando todos los tipos de datos \n * primitivos del lenguaje (cadenas de texto, enteros, \n * booleanos...).\n */\n\nlet numero=2; //number\nlet testo=\"Hola mundo\"; //string\nlet verdadero=true; //boolean\nlet falso=false; //boolean  \nlet undef=undefined; //undefined\nlet noDefinido;\nlet nulo=null; //Null\nlet bigInt=BigInt(123456789012345678901234567890); //bigint\nlet symbol=Symbol(\"Esto es un symbol\"); //symbol\n\n/**\n * Imprime por terminal el texto: \"¡Hola, [y el nombre de \n * tu lenguaje]!\"\n */\nconsole.log(\"!Hola, Javascript!\");\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/santiixs.js",
    "content": "/*\nLa URL de la documentación: https://developer.mozilla.org/en-US/docs/Web/JavaScript\n*/\n\n// Este es un comentario en una sola línea\n\n/*\nComentario en varias lineas\n*/\n\n/**\n * Este tipo de comentario se utiliza más para documentar código\n * funciones\n * variables\n * clases\n */\n\nvar myVariable =\n  'Este tipo de variable ya no se utiliza tanto, pero sigue funcionando';\nlet myLet = 'Este tipo de variable es de ámbito de bloque';\nconst myConst =\n  'Esta variable no puede cambiar su valor a menos que sea un objeto o array';\n\nlet number = 20;\nlet string = 'Hola Mundo';\nlet boolean = true; // o false\nlet array = [1, 2, 3, 4, 5];\nlet object = {\n  name: 'Santi',\n  age: 20,\n  isStudent: true,\n  hobbies: [\n    'Programar',\n    'Leer',\n    'Estar en la naturaleza',\n    'Cocinar',\n    'Viajar',\n    'y más...',\n  ],\n};\nlet nothing = null;\nlet notDefined; // undefined\nlet symbol = Symbol('This is a symbol');\nlet bigInt = 9007199254740991n;\n\n// Imprimir en terminal\nconsole.log('¡Hola, JavaScript!');\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/seandsun.js",
    "content": "// El sitio web oficial: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// ----------------------------------------------------------------------------------------------------\n\n// Este es un comentario de una sola línea.\n\n/*\nEste es un\ncomentario de\nvarias líneas.\n*/\n\n/**\n* Este comentario es para observar\n* que cada línea inicia con un \n* asterísco ya que es más \"elegante\".\n*/\n\n// ----------------------------------------------------------------------------------------------------\n\nvar myUsername = \"seandsun\" // Variable global, puede ser re-declarada y modificada.\nvar myUsername = \"hola\"\n\nlet myAge = 26 // Variable cuyo alcance está limitado a un bloque de código, puede ser modificada.\nmyAge = 24\n\nconst SITIO_WEB = \"https://retosdeprogramacion.com/\" // Variable constante, no puede ser modificada.\n\n// ----------------------------------------------------------------------------------------------------\n\nlet string = \"Yo soy Groot\" // Con comillas dobles (\"\")\nstring = 'Nosotros tenemos un Hulk' // Con comillas simples (')\nstring = `Podría estar haciendo esto todo el día` // Con \"backticks\" (`)\n\nlet number = 12 // Int\nnumber = 3.14 // Float\n\nlet noBigInt = 9007199254740991 // Int\nlet BigInt = 9007199254740992n // El último \"1\" fue cambiado por un \"2\" y js ya no lo soporta como int.\n\nlet boolean = true\nboolean = false\n\nlet symbol = symbol() // Crea valores únicos e irrepetibles\n\nlet isNull = null // Ausencia de valor\n\nlet noUndefined = \"No soy indefinada\" // \"undefined\" es un valor que se asigna automáticamente a variables sin valor\nlet undefined // Es una variable cuyo valor sí es \"undefined\" porque no se le ha asignado ningúl valor\n\n// ----------------------------------------------------------------------------------------------------\n\nconsole.log(\"!Hola, JavaScript¡\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/sebascmb.js",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n\n// ! Ejercicio 1\n\n// Sitio web JavaScript\n// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// ! Ejercicio 2\n\n// Este es un comentario de una sola linea\n\n/**\n * Este es un comentario de multiples lineas\n * ejemplo\n * Hola mundo :D\n */\n\n// ! Ejercicio 3 Crea una variable (y una constante si el lenguaje lo soporta).\n\n\n\nlet saludoQuePuedeCambiar = 'Hola gente';\nconst SALUDOQUENOPUEDECAMBIAR = 'Hola';\n\n\n// ! Ejercicio 4 - Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n\n// ? String\nlet cadenaTexto = 'Esto es una cadena de texto';\nconsole.log( typeof cadenaTexto ); // string\n\n\n// ? Number\nlet miPrimerNumero = 10;\nconsole.log( typeof miPrimerNumero ); // number\n\n\n// ? Boolean\nlet estaCorriendo = true;\nconsole.log( typeof estaCorriendo ); // boolean\n\n\n// ? null\nlet soyunNull = null;\nconsole.log( typeof soyunNull );\n\n// ? undefined\nlet deportista;\nconsole.log( typeof deportista ); // undefined\n\n// ? bigint\n\nlet numero2 = 23n;\nconsole.log( typeof numero2 ); // bigint\n\n\n// ! Ejercicio 5 Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\nconsole.log(`Hola mundo desde JavaScript!`);\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/sejotaz.js",
    "content": "//Esto es una comentario de una línea \n// La URL es: https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n/*\nEsto es un comentario de varias linea\n*/\n\nlet Mi_variable = \"Variable\"\nconst Mi_constante = \"Constante\"\n\n//Tipos de datos primitivos\nconst texto = \"\"\nconst number = 123\nconst float = 1.4\nconst boolean = true\nconst nulll = null\nconst unde = undefined\n\n//Lenguaje elegido\nconst len_Elegido = \"Javascript\"\nconsole.log(´¡Hola, ${len_Elegido}!´)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/septarian.js",
    "content": "// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n/*\nhola\n*/\n\nlet a = \"hola\"\nconst b = []\nvar c = 0\nconst d = false\nlet e = 3.1415\nlet f = null\nlet g = {}\n\nconsole.log(\"Hola Javascript\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/sergioab7.js",
    "content": "/*\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * \n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * \n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n*/\n\n//Web oficial: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n//Comentario normal\n\n/*\nComentario de varias lineas de código\n*/\n\nlet variable_local = \"variable local\";\nvar variable_global = \"variable global\";\nconst constante = \"constante\";\n\nlet numero_entero = 1;\nlet mi_String = \"hola xaxxjs\";\nlet decimal = 2.5;\nlet booleano = true;\nlet booleano2 = false;\nlet valor_nulo = null;\nlet valor_NaN = NaN;\nlet valor_indefinido = undefined;\nlet simbolo = Symbol(\"el simbolo\");\nlet matriz = [\"xaxxjs\", 5, \"test\"];\nlet mi_objeto = {\n    fecha:\"hola\"\n}\n\nconsole.log(\"¡HOla, javascript!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/shevotool.js",
    "content": "// https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n// Lorem ipsum dolor sit amet, consectetur adipiscing elit\n\n/* Lorem ipsum dolor sit amet, consectetur adipiscing elit */\n\n/* Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.  */\n\nlet edad = 30;\nconst correo = \"correo@correo.com\";\nconst nombre = undefined;\nconst hasPhone = false;\nlet miEdad = 25;\nconst apellido = \"Carvajal\";\nconst hasZip = null;\nconst persona = {};\nconst id = Symbol(\"id\");\n\nconst lenguaje = \"JavaScript\";\n\nconsole.log(`¡Hola, ${lenguaje}!`);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/sixtodev.js",
    "content": "/*\r\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\r\n * - Recuerda que todas las instrucciones de participación están en el\r\n *   repositorio de GitHub.\r\n *\r\n * Lo primero... ¿Ya has elegido un lenguaje?\r\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\r\n * - Este primer reto te servirá para familiarizarte con la forma de participar\r\n *   enviando tus propias soluciones.\r\n *\r\n * EJERCICIO:\r\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\r\n *   lenguaje de programación que has seleccionado.\r\n * - Representa las diferentes sintaxis que existen de crear comentarios\r\n *   en el lenguaje (en una línea, varias...).\r\n * - Crea una variable (y una constante si el lenguaje lo soporta).\r\n * - Crea variables representando todos los tipos de datos primitivos\r\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\r\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\r\n *\r\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\r\n * debemos comenzar por el principio.\r\n * \r\n * \r\n * \r\n * // url de javascript: https://developer.mozilla.org/es/docs/Web/JavaScript\r\n * \r\n * // este es un comentario de una sola linea\r\n * \r\n *  /* este es un comentario de varias lineas\r\n * que puedes explicar mas detallamante que esa una function o archivo en espeficico*/\r\n\r\n/** \r\n * Este es un comentario para documentar una funcion , varialbe o archivo en especifico\r\n @param {string} name - nombre de la persona\r\n @returns {string} - retorna un saludo\r\n */\r\n\r\n function saludo (name){\r\n     return `Hola ${name}`\r\n }\r\n \r\n\r\n // variables y constantes\r\n\r\n const myConstant = 'soy una constante '; // constante que no cambia y su valor es string\r\n let  nombre = 'sixto'; // tipo de dato string\r\n let edad = 25; // tipo de dato numerico\r\n let isDeveloper = true; // tipo de dato booleano que puede ser true o false\r\n let variableNull = null; //  se declara una variable y se inicializa con valor null - no tiene valor o refereincia a un objeto\r\n let bigInt = 1234567890123456789012345678901234567890n; // tipo de dato para representar numero grandes \r\n let symbol =   Symbol(\"hola soy inmutable\"); // tipo de dato que se usa para crear identificadores unicos , datos primitivos inmutables , su valor no puede ser modificado una vez creado\r\n let indefinido = undefined; // se declara una variable pero no se ha inicializado\r\n let array = [1,3,5,7,2, 1]; // un array de numeros desordenados\r\nlet array2 = ['sixto', 'crack', 'moure', 'javascript']; // un array de string \r\n\r\n\r\n// Imprime por terminal el texto: \"¡Hola, [Javascript]!\"\r\n\r\nlet miLenguaje = 'Javascript';\r\nconsole.log(`!Hola, ${miLenguaje}!`); // imprime por consola el saludo con el nombre del lenguaje"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/skala2301.js",
    "content": "/****************REFERENCIAS**************************************************************\n*Referencia de JavaScript: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference\n*Referencia de JavaScript Estandarizado (ECMAScript): \n*   https://www.ecma-international.org/\n*   https://ecma-international.org/publications-and-standards/standards/ecma-262/\n*******************************************************************************************/\n//declaracion de variables\nvar primeraDeclaracion;           //estoy declarando una variable, pero no se inicializa, \nlet segundaDeclaracion;           //su valor sera undefined\n//inicializacion de variables\nprimeraDeclaracion = 0;           //aqui inicializo mis variables\nsegundaDeclaracion = 12;\n\n/*******************************\n * TIPOS DE DATOS EN JAVASCRIPT*\n ******************************/\n\nlet myBool = Boolean();             //Boolean   -> valores pueden ser: true, false un boleano. Es un wrapper (funcion que se llama segun convenga)\nlet myNumber = Number();            //Number    -> en escencia es un flotante de (double-precision) de 64bits  esta definido segun IEEE 754\nlet myBigInt = BigInt(2393243);     //BigInt    -> trabaja segun el estandard de formato de precision arbitrario, esto significa que sus digitos estan limitados por el poder de la memoria disponible en el host\nlet myString = String(\"Muestra\");   //String    -> es texto o cadena de caracteres, en escencia es tambien un wrapper (funcion que se llama segun convenga)\nlet mySymbol = Symbol(\"@\");         //Symbol    -> regresan una primitiva de symbol y estan garantizados de retornar un symbol unico\n                                //Object    ->\nlet soyNull = null;                 //null      -> valor primitivo de javascript, pero es en escencia un objeto\nlet noDefinido = undefined;         //undefined -> valor primitivo de javascript, se asignan automaticamente a variables no inicializadas\nlet noDefinido2;\n\nconsole.log(\"myNumber: \",myBool);\nconsole.log(\"myNumber: \",myNumber);\nconsole.log(\"myBigInt: \",myBigInt);\nconsole.log(\"myString: \",myString);\nconsole.log(\"mySymbol: \",mySymbol);\nconsole.log(\"soyNull: \",soyNull);\nconsole.log(\"noDefinido: \",noDefinido);\nconsole.log(\"noDefinido2: \",noDefinido2);\n\nmyNumber = Number(myBigInt);            //aqui convertimos de BigInt a Number\nconsole.log(\"myNumber: \",myNumber);\n/*********************************\n*Las siguientes son constantes****\n*********************************/\nconst Uno = 1;                                  //declaracion y asignasion en la misma linea, \nconst Hola = \"Hola\";                            //constantes deben inicializarce en la misma linea en que son declaradas\n   \n//las constantes no se pueden re-declarar ni pueden cambiar valor por asignasion, pero\n//pueden mutar\nconst credenciales = {nombre: \"Simon\", apellido: \"Belmonth\", clave: \"MyVampireKillerShinesLikeADimond\"};\nconsole.log(\"clave original de Simon: \",credenciales.clave);\ncredenciales.clave=\"TuAmigoDracula\";\nconsole.log(\"clave hackeada de Simon: \", credenciales.clave);\ncredenciales[\"contacto\"]= \"1111111\";\nconsole.log(credenciales);\n//el contenido de los arreglos tampoco estan protegidos y por tanto lo siguiente es permitido\nconst misJuegos = [\"SILENT HILL 2\",\"ELDEN RING\",\"FFXVI\",\"CHRONO TRIGGER\"];\nconsole.log(\"Juegos originales: \",misJuegos);\nmisJuegos.push(\"LUFIA FORTRESS OF DOOM\");\nconsole.log(\"Juegos actualizados: \",misJuegos);\n\n\n/*********************************\n*Las siguientes son variables****\n*********************************/\n\nlet variableLocalMayor = \"Fui declarada al inicio del codigo\"; //Variables declaradas con let tienen alcance \nlet variableLocal = 10;                                        //dentro del bloque y sus sub-bloques\nvar variableGlobal = 0.5;   //variables que usan var, pueden tener alcance global, modular o dentro de funcion\n\n\n//formas de asignasion de variables\nvar miArray = [1,2,3,4,5];                      //declaracion y asignasion de array\nvar miObjeto = {A: \"Si\", B: \"No\", C: \"Talvez\"}; //declaracion y asignasion de objeto\nvar misDimensiones = {X: 22.4, Y: 83.1, Z: 10}; //otro objeto, pero con numeros\n\n\n/*************************************************************************\n*La siguiente forma de asignasion se conoce como destructuring assignment*\n*************************************************************************/\nconst {A} = miObjeto; \n({X,Z} = misDimensiones);\n[a,b,c,d,...others] = [1,2,3,4,5,6,7,8,9,0,10,20,30,40,50];//aqui utilizamos la propiedad rest (resto)\n//rest property, quiere decir que tomamos algunas variables especificas como a,b,c y d, pero\n//el resto de valores los almacenamos en others, esta variable debe ser la ultima y debe comenzar con ...(...others en este caso)\nlet {C, Y} = {...miObjeto, ...misDimensiones};     //esta asignasion se da por una fusion o merge y se toman los elementos C y Y por destructuring assignment\nvar union = {...miObjeto, ...misDimensiones};   //esta asignasion se da por una fusion de objetos (merge)\n\nconsole.log(\"Hoisted variable: \",hoisted);// una traduccion es elevacion de variable, la variable es declarada en la siguiente linea, \n//pero ya existe, sin embargo no tiene asignado ningun valor, mostrara undefined\nvar hoisted = \"Ya fui declarada\";\nconsole.log(\"Hoisted variable con valor: \",hoisted);// aca mostramos la variable global nuevamente, ya tiene un valor asignado\n\n\n\n/*************************************************\n * HOISTING (IZAMIENTO O ELEVACION) EN FUNCIONES**\n ************************************************/\nconsole.log(callMyName());//esta funcion es declarada hasta el final, pero por propiedad de hoisting javascript\n//la define por completo desde iniciado el programa\n\nlet copiaFuncion = imprimeEsto; //podemos copiar la direccion de la funcion, \n                                //no se copia sino que se toma la referencia de la region de memoria\nconsole.log(\"Aqui se copio una funcion, la funcion no se llama si no se usa (), en la siguiente linea se imprimira \\\npor medio de su copia\");\ncopiaFuncion(); //Ahora se llama la funcion por medio de su referencia\n\n\n/**********************************************************************************************\n * LOS SIGUIENTES BLOQUES DE CODIGO MUESTRAN EL USO BASICO DE LAS VARIABLES E IMPRIME ALGUNAS,* \n * PERO NO ES ESCENCIAL PARA EL RETO, MAS QUE NADA DEMUESTRAN EL SCOPE DE LAS VARIABLES********\n * \n**********************************************************************************************/\nconsole.log(\"constant A: \",A,\"local variable C: \",C,\"local variable Y: \",Y);\nconsole.log(\"X: \",X,\"Z: \",Z);\nconsole.log(\"a: \", a, \"b: \", b, \"c: \", c, \"d: \", d, \"others: \", others);\nconsole.log(\"union:\", union);\n\n\n{\n    \n    console.log(\"dentro de bloque 1 valor variable global: \",variableGlobal);\n    console.log(\"dentro de bloque 1 valor variable local: \",variableLocal);\n    {\n        const Hola = \"Hola 2\";\n\n        var variableGlobalPluss = \"soy Global\";//\n        var variableGlobal = 0.1;\n        let variableLocal = 5;             //Esta variableLocal tiene el mismo nombre que la variableLocal declarada en bloque anterior, pero su alcance es este bloque\n        \n        console.log(\"dentro de sub-bloque valor variable Global: \",variableGlobal); //se imprime 0.1\n        console.log(\"dentro de sub-bloque valor variable local: \",variableLocal); //se imprime 5\n        variableLocal += 20;\n        console.log(\"dentro de sub-bloque valor variable local:: \",variableLocal);//se imprime 25\n        \n        console.log(Hola); \n        console.log(variableLocalMayor,\", pero en este momento esta en un sub-bloque de codigo\");//las variables \n        //locales viven dentro de todo su propio bloque y sus sub-bloques, \n        //pero solo tienen prioridad en el nivel de bloque en que son declaradas, \n        //y mueren al terminar todo el bloque\n        variableLocalMayor+=\" (modificada en sub-bloque)\";\n    }\n    console.log(Hola); \n    console.log(\"dentro de sub-bloque valor variable local:: \",variableLocal);//se imprime 25\n    console.log(\"dentro de sub-bloque valor variable Global: \",variableGlobal); //se imprime 0.1\n    \n    console.log(\"Las Variables globales se pueden usar fuera del bloque donde se declaran: \",variableGlobalPluss);\n\n}\nconsole.log(variableLocalMayor,\", y en este momento esta al final del codigo\");\n\n\n\n\nfunction callMyName(){\n    return \"Athanasius\";\n}\nfunction imprimeEsto(){\n    console.log(\"Yes, Master, My Master!!\");\n}\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/sniker1223.js",
    "content": "// https://developer.mozilla.org/es/docs/Web/JavaScript\n// Single Line Comment\n\n/* Multiple\nLine \nComment */\n\n//const variable\nconst PI = 3.141592653589793;\n\n// primitive Data types\nlet color = \"Blue\"; //String\nlet length = 16; //number\nlet x = true; //booleans\nlet person = {firstName: \"Sara\", lastName: \"sniker\"}; //object\nlet nulo = null; //null\nlet type_Undefined = undefined; //unfefined\nlet type_Symbol = \"Symbol\"; //Symbol\nlet tyoe_bigint = 11n //bigint\n\n// print in console\nconsole.log(\"¡Hola, Javascript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/socramwd.js",
    "content": "\n/*\nDocumentación de mozilla, altamente cualificada\nhttps://developer.mozilla.org/es/docs/Web/JavaScript\n\nDocumentación oficial de ECMA\nhttps://262.ecma-international.org/5.1/#sec-7\n*/\n\n// Este es un comentario en una línea\n\n/* Este es\nun comentario\nmultilínea\n*/\n\n// Variable mutable\nlet variableModificable = 'socramdev'\n\n// Variable inmutable\nconst variableFija = 'MarcosPG'\n\n// Variable tipo string\nconst string = 'socramdev'\n\n// Variable tipo number\nconst number = 1977\n\n// Variable tipo float\nconst float = 46.75\n\n// Variable tipo booleano\nconst bool = true\n\n// Otras variables no primitivas\nconst bigInt = 1234567891011121314151617181920n\nconst nullValor = null\nconst simbolo = Symbol()\nconst array = [1, 2, 3, 4, 5]\nconst object = {\n    name: 'Marcos',\n    age: 46,\n    city: 'Sevilla',\n    country: 'España'\n}\n\nconsole.log('Hola, JavaScript')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/soldochris.js",
    "content": "//URL de sitio web de Javascript: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n//Este es un comentario de una sola linea\n\n/*\nEste es un comentario\nen varias lineas,\npuede ser de la longitud\nque tu quieras\n*/\n\nlet miVariable = \"es una variable\";\n\nconst constante = \"es una constante\";\n\nlet string = \"esta es una cadena de texto\";\n\nlet number = 2;\n\nlet boolean = true;\n\nlet nulo = null;\n\nconsole.log(\"¡Hola, Javascript!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/ssanjua.js",
    "content": "\n// https://developer.mozilla.org/en-US/docs/Web/javascript\n\n// una linea\n\n/* \n multilinea\n multiline\n multili\n multi\n mult\n mul\n mu\n m\n*/\n\n// variable\nlet algo = \"cosa\";\n\n// constante\nconst algoConstante = \"cosaConstante\";\n\n// tipos de datos primitivos\nlet string = \"esto es una cadena de textos\";\nlet number = 123;\nlet boolean = true;\nlet booleanoMalo = false;\nlet indefinit = undefined;\nlet nada = null;\nlet numeroDecimal = 3.14;\nlet numeroGrande = 1234567890123456789012345678901234567890n;\n\nlet lenguajeElegido = \"JavaScript\"\nconsole.log(`hola ${lenguajeElegido}`)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/super490.js",
    "content": "// Sitio web oficial de Javascript\n// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Sintaxis para crear comentarios:\n\n// Esto es un comentario de una línea\n\n/*\nEste es un \ncomentario de \nmúltiples líneas.\n*/\n\nlet variable1 = 'Cambia';\nconst variable2 = 'No cambia';\n\n//Tipos de Datos Primitivos:\n\nconst edad = 30; let pi = 3.14; // Number integer and float\nconst nombre = \"Manuel\"; let saludo = 'Hola, mundo!' // String\nconst esMayorDeEdad = true; let esMenorDeEdad = false; // Boolean\nconst edadKey = Symbol('edad'); // Symbol\nconst numeroGrande = 9007199254740991n; // BigInt\n\n\nconsole.log('¡Hola, Javascript!')\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/vainsito1.js",
    "content": "//  https://developer.mozilla.org\n// comentarios de una sola linea\n\n/* \ncomentario multiples\nvarias lineas\n*/\nvar variable numero = 1\nconst constante numero = 2\nvar  datoINT= 1\nvar float = 1.3\nvar bolean= true\nvar bolean2= false\nvar datoundefined= undefined\nvar datoNUll= null\nvar datosymbols = symbol :D\n\nconsole.log(\"¡Hola,javascript\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/valeriatorrealba.js",
    "content": "// EJERCICIO:\n//- Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n\n// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n//- Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n\n    // Esto es un comentario\n\n    /*\n        Esto es un comentario\n        de varias líneas.\n    */\n\n//- Crea una variable (y una constante si el lenguaje lo soporta).\n\n    let nombre;\n    const Apellido = 'Torrealba';\n\n//- Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n\n    //String\n    let name = 'Bob';\n\n    //Number\n    let edad = 10;\n\n    //Boolean true/false\n    let activo = true;\n\n    //Array\n    let miArray = [1,'Bob','Steve',10];\n\n    //Object\n    let miVariable = document.querySelector('h1');\n//- Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\nlet saludo = '¡Hola, ';\nlet lenguaje = 'JavaScript!'\n\nconsole.log(saludo + lenguaje);"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/victor-Casta.js",
    "content": "//Sintaxis para representar comentarios\n// En JavaScript existen dos formas para usar comentarios en nuestro código, comentarios de una sola línea y comentarios de varias líneas\n\n//✅Comentarios de una sola línea: //\n//✅Comentarios de varias líneas: /**/\n\n//Variables y constantes\n//✅Constantes:\nconst PI = Math.PI;\n\n//✅Variables:\nlet a = 'Hola';\nvar b = 'Mundo';\n\n//Datos Primitivos\n//✅String: Texto o Caracteres\nlet saludo = 'Hola';\n\n//✅Number: Número\n//⚠️Se pueden crear utilizando enteros, decimales o hexadecimales\nconst edad = 30;\nconst altura = 1.70;\nconst color = 0xFF0000;\n\n//✅Boolean: Boolenos true y false\nlet verdadero = true;\nlet falso = false;\n\n//✅Null: Representa la ausencia de un valor\nlet nulo = null;\n\n//✅Undefined: Representa un valor que aún no está definido o ausencia de un valor inicial\nlet sinDefinir = undefined;\n\n//Imprimir en consola\nconsole.log(`${a} ${b} Bienvenidos a JavaScript`);"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/victorMDev24.js",
    "content": "//https://developer.mozilla.org/es/docs/Web/JavaScript/Guide\n\n//comentario de una linea \n\n    /*\n    comentariuo \n    de\n    varias lineas\n    */ \n\n    const constante = \"inamovible\"\n    let  palabraclave =\"alcance de bloque\"\n    var variable =\"igual que let pero no es buena practica usarla\"\n\n    let numero = 1;\n    let numeroGrande = 98987562335554n;\n    let nombre = \"hola mundo\";\n    let verdadero = true;\n    let falso = false;\n    let undef = undefined;\n    let nulo = null;\n    let miSimbol = Symbol(\"key\")\n\n\n    console.log(Hola,javascript)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/vmatmarco.js",
    "content": "/* 1- SITIO WEB OFFICAL DE JAVASCRIPT */\n//Puedes encontrar la documentación oficial de JavaScript en https://developer.mozilla.org/es/docs/Web/JavaScript\n\n\n/* 2- TIPOS DE COMENTARIOS EN */\n/*  \n    En JavaScript, existen dos tipos de comentarios:\n    1. Comentarios de una línea comienzan con // y se extienden hasta el final de la línea.\n    2. Comentarios de varias líneas comienzan con /* y terminan con * / (sin espacio entre * y /) \n*/\n\n\n/* 3- DECLARACION DE VARIABLES */\n\n    var variableVar; //Variable global (Actualmente en desuso)\n    let variableLet; //Variable local\n    const variableConst = 3.1415; //Variable constante (No se puede modificar su valor)\n\n\n/* 4- TIPOS DE DATOS PRIMITIVOS */\n\n    //1. String: Para representar una cadena de caracteres se utilizan las comillas simples o dobles.\n        let nombre = \"Vicente\";\n\n    //2. Number: Para representar numeros enteros o decimales.\n        let edad = 23;\n        let altura = 1.75;\n\n    //3. Boolean: Para representar valores lógicos. Solo puede ser true o false.\n        let esEstudiante = true;\n        let esMayorDeEdad = false;\n\n    //4. Undefined: Representa una variable sin valor asignado.\n        let variableSinValor;\n\n    //5. Null: Representa una variable con valor nulo.\n        let variableNula = null;\n\n    //6. Symbol: Representa un valor único e inmutable, puede ser utilizado como clave de las propiedades de los objetos.\n        let simbolo = Symbol('mi-simbolo');\n\n    //7. BigInt: Permite representar números enteros mayores que (2^53 - 1) o menor que -(2^53 - 1).\n        let numeroGrande = 1234567890123456789012345678901234567890n;\n\n\n/* 5- IMPRIMIR POR CONSOLA */\n\n    console.log(\"¡Hola, JavaScript!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/vmga09.js",
    "content": "/* Primer ejercicio de los retos de programación\nEste reto es en el leguaje de JavaScript\nhttps://www.javascript.com/ */\n\n// Definbición de constantes como string\nconst nombre = \"Victor Gonzalez\";\nlet lenguaje = \"Javascript\";\n\n// Constantes del tipo numérico\n\nconst numeroSuerte = 7;\nlet numeroFloat = 3.5;\n\n// Booleanos\n\nconst falso = false;\nlet verdadero = true;\n\n// Undefinido Nulo\n\nconst undefinido = undefined;\nlet nulo = null;\n\nconsole.log( `${nombre} ${lenguaje} ${numeroSuerte} ${numeroFloat} esto puede ser ${falso} o ${verdadero}` );\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/vsUnix0.js",
    "content": "// https://developer.mozilla.org/es/docs/Web/JavaScript\r\n/*Este es un comentario en javaScript\r\npero con varias líneas*/\r\n\r\nlet numero = 1;//variable \r\nconst name = 'JavaScript';//constante\r\n\r\n// tipos de datos primitivos\r\nlet text = 'Hola,';//tipo string\r\nlet number = 2;//tipo número\r\nlet bigInt = 7381263167832168362176321786381632613612362136781n;//tipo bigInt\r\nlet boolean = true;//tipo booleano\r\nlet car;// tipo indefinido\r\nlet sym = Symbol(\"foo\");//para simbolo\r\n\r\nconsole.log(text + ' ' + name)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/walkerlyna.js",
    "content": "/* Sitio oficial de JavaScript\n- https://www.javascript.com/\n*/\n\n// <-- Este es la sintaxis para representar un comentario de una sola linea.\n\n/*\n    De esta manera\n    se puede comentar \n    en varias líneas\n*/\n\n// - Crea una variable (y una constante si el lenguaje lo soporta).\nlet primeraVariable = 'Hola Mundo';\nconst primeraConst = 27;\n\n// - Crea variables representando todos los tipos de datos primitivos\nlet number = 12;\nlet float = 4.72;\nlet string = 'Feliz año nuevo';\nlet boolean = true;\nlet esNulo = null;\nlet noDefinido;\nlet simbolo = Symbol(\"unico\");\n\n// Comenzamos\nconst lenguaje = 'JavaScript';\n\nconsole.log(`!Hola, ${lenguaje}`);"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/wapastorv.js",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n// URL del sitio web oficial de JavaScript  https://developer.mozilla.org/es/docs/Web/JavaScript \n/*\n    Otras fuerntes de información de javascript: \n    https://www.ecma-international.org/publications/standards/Ecma-262.html\n    https://www.w3schools.com/js/default.asp\n    https://developer.mozilla.org/es/docs/Web/JavaScript\n\n*/\n\n/* \n    Comentario de varias líneas\n    Este es un ejemplo de JavaScript para comentarios  de varias líneas \n*/\n\n/*\n    Variables en JavaScript, let y const son las formas de declarar variables en JavaScript, \n    let es una variable que puede cambiar su valor, const es una variable que no puede cambiar su valor.\n    También se puede declarar una variable con var, pero no se recomienda su uso por problemas de scope.\n    Scope es el alcance de la variable en el código.\n*/\nlet variable = \"Soy una variable\";\nconst constante = \"Soy una constante\";\nvar variable2 = \"Soy una variable con var\";\n\n/* \n    Tipos de datos primitivos en JavaScript\n    - String : Cadena de texto \n    - Number : Número\n    - Boolean: Verdadero o Falso\n    - Null: Valor nulo\n    - Undefined : Valor indefinido\n    - Symbol: Valor único\n*/\n\nlet string = \"Soy un string\";\nlet number = 10;\nlet boolean = true;\nlet nulo = null;\nlet indefinido = undefined;\nlet simbolo = Symbol();\n\n// Imprimir por terminal el texto: \"¡Hola, JavaScript!\"\nconsole.log(\"¡Hola, JavaScript!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/wdiegow.js",
    "content": "/* 1.Crea un comentario en el código y coloca la URL del sitio web oficial del\nlenguaje de programación que has seleccionado. */\n// https://developer.mozilla.org/es/docs/Web/JavaScript \n\n/* 2. Representa las diferentes sintaxis que existen de crear comentarios\nen el lenguaje (en una línea, varias...). */\n// con dos barras se puede hacer un comentario de una linea \n/* \ny barra asterisco se puede hacer un \ncomentario de varias lineas \n*/\n\n/* 3. Crea una variable (y una constante si el lenguaje lo soporta). */\nlet mi_Variable = 1; // se puede declarar una variable con let\nvar mi_Variable2 = 2; // se puede declarar una variable con var pero ya no se usa\nconst mi_constante = \"Hola Mundo\"; // se puede declarar una constante con const \n\n/* 4. Crea variables representando todos los tipos de datos primitivos\ndel lenguaje (cadenas de texto, enteros, booleanos...). */ \nlet var1; // esta variable es de tipo undefined \nlet var2 = null; // esta variable es de tipo null\nlet var3 = \"esto es un string\"; // esta variable es de tipo string\nlet var4 = 1; // esta variable es de tipo number \nlet var5 = true; // esta variable es de tipo boolean\nlet var6 = Symbol(\"esto es un symbol\"); // esta variable es de tipo symbol\n\n/* 5. Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\" */\nconsole.log(\"¡Hola, JavaScript!\");  \n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/wesborland-github.js",
    "content": "// Sitio web del lenguaje elegido : https://developer.mozilla.org/en-US/docs/Web/JavaScript \n\n// Comentario de 1 línea.\n\n/* \nComentario\nmulti-línea\n*/\n\n// Variables \n\n//var = variable global, puede actualizarse y redeclararse en cualquier lado. NO recomendada.\n\n\nvar saludo = \"Hola, soy var\"\n\n\n\n/*let = variable no global, puede actualizarse y pero no redeclararse en cualquier lado, salvo, se lo haga en otro ámbito como por ej :\n\nlet saludar = \"Hola\";\n    if (true) {\n        let saludar = \"Hola tambien\";\n        console.log(saludar); // \"Hola tambien\"\n    }\n    console.log(saludar); // \"Hola\"\n\nAquí si podremos modificar la variable. RECOMENDADA UTILIZAR.\n\n*/\n\n\nlet saludo2 = \"Hola, soy let\"\n\n\n\n//const = variable global, no puede reescribirse ni declararse nuevamente.\n\n\nconst saludo3 = \"Hola, soy const\"\n\n\n\nlet numero = 1; // Variable Number.\nnumero = \"uno\"; // Variable String.\nnumero = true; // Variable Boolean.\nnumero = false; // Variable Boolean.\nnumero = Symbol(\"unico\"); // Variable Symbol (único e inmutable).\nnumero = 12n; // Variable BigInt.\nnumero = BigInt(10); // Variable BigInt ( es igual a 10n ).\nnumero = null; // Variable Null.\nnumero; // Variable Undefined.\n\n\nlet lenguaje = \"Javascript\"\nconsole.log(\"!Hola, \" + lenguaje + \"!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/willicar27.js",
    "content": "//Esta es la url de JavaScript 'https://www.javascript.com/'\n\n// Primera sintaxis de los comentarios en Javascript\n\n/*\nsegundunda forma de comentar en Javascript en\nvarias lineas\n */\n\nlet primeraVariable = 'abc'  //caracter\nvar segundaVariable = 123    //numeros\nconst TerceraVariable = true  //booleano\nlet cuartaVariable = undefined  // undefined\nlet quintaVariable = NaN //sin definir\n\nconsole.log('¡hola, esto es javaScript!')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/wolffcode.js",
    "content": "    // Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n// https://www.javascript.com/\n\n\n    // Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n// como anteriormente puse la manera de crear comentarios de una linea en JavaScript es esta.\n/*\nesta es una manera de agregar comentarios multilinea en JavaScript.\n*/\n\n    // Crea una variable (y una constante si el lenguaje lo soporta).\n\n// existen 3 tipos de variables\nvar a //la clasica pero que no se usa mucho, hasta donde entiendo tiene un scoope global\nlet b //esta variable es una variable mutable, podemos reasignarles valores despues de declararla\nconst c = '' //mas que una variable es una cosntante, esta una vez declarada no puede mutar, debemos declararla y asignarle un valor en la misma linea \n\n    // Crea variables representando todos los tipos de datos primitivos\nlet num = 8\nlet float = 13.5\nlet str = \"anita lava la tina\"\nlet bool = true\nlet n = null\nlet indefinido = undefined\n\n    // Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nconsole.log(\"!hola, JavaScript\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/xBrianOS.js",
    "content": "// Página oficial: https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n// Este es un comentario de una sola línea\n\n/* Este es el tipo de \ncomentario multiliena \nen JavaScript */\n\n// Declaración de una variable:\nlet languageName = 'JavaScript';\n\n// Declaración de una constante:\nconst name = 'Moure';\n\n// Tipos de datos en JavaScript\nlet text = 'Hola Mundo'; // String\nlet x = 13; // Number\nlet isTrue = true; // Boolean\nlet nullValue = null; // Null\nlet undefinedValue; // Undifined\n\n// Imprimir mensaje en consola\nconsole.log('Hola, ' + languageName);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/xNomada.js",
    "content": "// Javascript website: https://www.javascript.com/\n\n// Comentario en una linea\n\n/* \n  Comentario\n  en\n  multiples\n  lineas\n*/\n\nlet myVariable;\nconst myConst = 'Constante';\n\nlet myString = \"Hola mundo!\";\nlet myOtherString = 'Hola mundo!';\nlet myInt = 15;\nlet myFloat = 23.50;\nlet booleanTrue = true;\nlet booleanFalse = false;\nlet myArray = [ 15, 25, \"A\", \"B\"];\nlet myObject = {name:\"xNomada\", edad:26, lenguaje:\"Javascript\"};\nlet myUndefined = undefined;\nlet nulo = null;\nlet mySymbol = Symbol('Mi symbol');\nlet myBigInt = 123456789012345678901234567890n;\n\nconsole.log(\"Hola, Javascript!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/xebaztiandev.js",
    "content": "/*\nJavaScript website url that provides basic information of this programming language:\nhttps://developer.mozilla.org/es/docs/Web/JavaScript\n*/\n\n// This is a single line comment\n\n/*\nThis is a comment\nof several lines.\n*/\n\n// How to define a variable and a constant\nlet myVaryable = \"This is a variable!\";\nconst PI = 3.1416;\n\n\n// Primitive data types in JavaScript\nlet myBoolean = true;\nlet myNull = null;\nlet myUndefined;\nlet myNumber = 100;\nlet myBigInt = 56567878783232n;\nlet myString = \"How it's going\";\nlet mySymbol = Symbol(\"test\");\n\n// Message printed in console\nconsole.log(\"¡Hola, JavaScript!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/xmunder.js",
    "content": "/*\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n */\n\n// Sitio web oficial de JavaScript:  https://developer.mozilla.org/en-US/docs/Web/javascript\n\n// Esto es un comentario de una sola línea\n\n/*\n    Esto es un\n    Comentario de\n    varias líneas  \n*/\n\n// Representación de variables y constantes\n\nlet variable = \"Variable\";\nconst constante = \"Constante\";\n\n// Tipos de datos primitivos de JavaScript\n\n// String\nlet cadena = \"Cadena de texto\";\n// Number\nlet numero = 12345;\n// Boolean\nlet booleano = true;\n// Null\nlet nulo = null;\n// Undefined\nlet indefinido = undefined;\n// Symbol\nlet simbolo = Symbol();\n// BigInt\nlet bigInt = BigInt(123456789);\n\n// Imprimir en consola\nconsole.log(\"¡Hola, JavaScript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/yaojema.js",
    "content": "//\"use strict\";\n// ------- DOCUEMNTACION --------\n\n// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// ------- COMENTARIOS  --------\n\n// Son los mismos que C++\n// comentario inline\n/*\ncomentarios\nen bloque\n*/\n\n// No se pueden anidar comentarios\n\n// ------- VARIABLES Y CONSTANTES --------\n\n// Existen 3 tipos de delcaraciones de variables\n\n// scope global\nvar variableInt = 1;\n\n// Scope local\nlet variableString = \"hola\";\n\nconst MI_CONSTANTE_PI = 3.1416;\n\n// variable global no declarada, puede crearte problemas\nx = 12;\n\n// ------- TIPOS DE DATOS --------\n\n// En el último ECMAScript define 8 tipos de datos en Js\n\nlet myBoolean = true;\nlet myNull = null;\nlet myUnd = undefined;\n//numerico\nlet myInt = 10;\nlet myFloat = 10.5;\n// formato de precición arbritrario BIG\nlet myBig = 9007199254740992n;\nlet myString = \"Mi texto\";\n// Instancia unica e inmutable\nlet mySymbol = Symbol();\nlet mySym2 = Symbol(\"something\");\nlet myObj = new Object(null);\n\n// ------- IMPRESION --------\n\nconsole.log(\"¡Hola, Javascript!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/yedixdev.js",
    "content": "/* Web Oficial del lenguaje\nhttps://www.javascript.com/\n*/\n\n// Esta sintaxis para representar un comentario de una sola linea.\n\n/*\n    De esta manera\n    se puede comentar \n    en varias líneas\n*/\n\n//Variables que pueden cambiar de valor\n\nlet nombre = \"Yedixdev\";\nnombre = \"Yedixon\"; //cambiando el valor de la variable\n\n//Variables Constantes\n//Una constante no se puede cambiar el valor una vez asigando\n\nconst edad = 22;\n\n//-------------------------------------------------------------------\n\n//Variables representando todos los tipos primitivos del lenguaje\n\n//cadena de texto (string)\nlet fullname = \"Yedixon Jose Ramones Flores\";\n\n//Numeros (number)\nlet peso = 74;\nlet altura = 1.74;\n\n//Booleanos - true o false\nlet soyEstudiante = true;\nlet soyHacker = false;\n\n// Undefined - una variable que no ha sido asignada aún\nlet indefinido;\n\n// Null - representa un valor intencionalmente vacío\nlet valorNulo = null;\n\n//---------------------------------------------------------------------\n// Imprime por terminal el texto \"¡Hola, [y el nombre de tu lenguaje]!\"\n\nconst mensaje = \"¡Hola mundo, JavaScript!\";\n\nconsole.log(mensaje);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/yesidl12.js",
    "content": "// https://lenguajejs.com/javascript/\n//https://lenguajejs.com/javascript/cheatsheets/download/javascript-cheatsheet-2019.pdf\n\n// Esto es un comentario de una linea\n\n/** Esto es \n * un comentario de\n * multiples lineas.\n */\n\n// variables y constantes\n\nlet variable = \"mi variable\";\nvariable = \"Este es el nuevo valor de ni variable\"; // let permite modificar las variables\n\nconst constante = \"No se puede modificar\";\n\n// Tipos de datos\n\n// <------- PRIMITIVOS ----------->\nlet num = 10; // number\nlet bigInt = 99999999999; // valor númerico muy grande\nlet str = \"Hola mundo\" // string\nlet boolean = true;\nlet boolean2 = false;\nlet indefinido = undefined; // variable sin inicializar\n\nconsole.log(\"Hola, JavaScripts\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript/zuluangel.js",
    "content": "// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n//This is a oneline comment\n\n/*\nThis is a multi-line comment\nIt can span multiple lines\n*/\n\nvar oldWay = 'This is the old way to declare a variable in js'\nlet newWay = 'This is the new way'\nconst CONSTANT = 'This is a constant, commonly are named on UPPER case, not mandatory'\n\nlet string = \"JavaScript\"\nlet string2 = 'Could be written by single or double quotes'\nlet string3 = `Could be written by backticks, useful for multi-line strings and to introduce variables on it`\nlet number = 1231243214\nlet boolean = true || false\nlet undefined // It is undefined because does not have a value or it is not defined\n\nconsole.log(`Hello, ${string}`);\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/julia/edalmava.jl",
    "content": "# Comentario de una línea en Julia\n\n#=\n   Comentario de varias líneas en Julia\n=#\n\n#=\n   Sitio oficial: https://julialang.org/\n   Documentación: https://docs.julialang.org/en/v1/\n=#\n\n# Expresiones de Asignación\n# variable = valor\n\n# Tipos Primitivos\n\n# Tipos Enteros\nent = 10                # Int32 o Int64 según el sistema\nent = 3000000000        # Int64\n# - Hexadecimales\nhex = 0x1               # UInt8\nhex = 0x123             # UInt16\nhex = 0x1234567         # UInt32\nhex = 0x123456789abcdef # UInt64\n# - Binarios \nbin = 0b10\n# - Octales\noct = 0o010\n# - Booleanos\nverdadero = true        # (1)\nfalso = false           # (0)\n\n# Tipo Punto Flotante\nflo = 1.0               # Float64\nflo = -1.23             # Float64\nflo = 1e10              # Float64\nflo = 2.5e-4            # Float64\n\nflo = 0.5f0             # Float32 - se cambia e por f\n\n# - Valores especiales de Punto Flotante\ninfinito_positivo = Inf\ninfinito_negativo = -Inf\nNot_a_Number = NaN\n\n# Strings\n# - Tipo Char\ncar = 'X'\nunicode = '\\u78'       # Unicode \\u seguido por los 4 digitos hexadecimales \nunicode = '\\U10ffff'   # o \\U seguido por los 6 u 8 digitos hexadecimales\n# - Cadenas Básicas\nlenguaje = \"Julia\"\n\n# Constantes \nconst gravedad = 9.8\nconst a, b = 1, 2\n\n#print(\"¡Hola, \", lenguaje, \"!\")  # Usando concatenación\nprint(\"¡Hola, $(lenguaje)!\")      # Usando interpolación\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/julia/owen-ian.jl",
    "content": "# URL del sitio web oficial: https://julialang.org/\n\n# Comentario de una sola línea en Julia\n\n#=\nComentario de varias\nlíneas en Julia\n=#\n\n# Variable\nvariable_entera = 10\n\n# Constante\nconst CONSTANTE = \"Esto es una constante\"\n\n# Variables de tipos de datos primitivos\ntexto = \"Cadena de texto\" # Cadena de texto\nentero = 42 # Entero\nflotante = 3.14 # Flotante\nbooleano = true # Booleano\ncaracter = 'A' # Carácter\n\n# Imprimir por terminal\nprintln(\"¡Hola, Julia!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/julia/roilhi.jl",
    "content": "# Comentario con el sitio web oficial Julia\n# https://julialang.org/\n\n# Comentario en una sola linea \n\n#=\n  Esto es un \n  comentario \n  usando \n  múltiples\n  líneas\n=#\n\n# Creando una variable \nmi_variable = \"string julia\";\n\n# creando una constante \nconst epsilon_0 = 8.854;\n\n# Creando variables con los tipos de datos primtivos\na = 5; # Int64\nb = 6.5; # Float64\nc = 0.5f0 #float32 \nd = Float32(0.35); # otra forma Float32\ne = true; # variable bool\nf = 'x'; # variable char \ng = \"soy cadena\"; # variable string \n\n\n\n# imprimir en texto el \"hola mundo\"\nprint(\"Hola Julia\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/julia/santiago-munoz-garcia.jl",
    "content": "# Sitio web oficial de Julia: https://julialang.org\n\n# Comentario de una sola línea en Julia\n\n#=\nComentario de \nmúltiples\nlíneas \nen Julia\n=#\n\n# Declaración de una variable\nvariable = \"Cadena de texto\"\n\n# Declaración de una constante (número pi)\nconst PI = 3.14159 \n\n# Tipos de datos primitivos \nnumero_entero::Int = 23 # Int\nnumero_flotante::Float64 = 23.10 # Float64\ncadena_de_texto::String = \"Hola mundo\" # String\nbooleano::Bool = true # Bool\n\nlenguaje = \"Julia\"\nprint(\"¡Hola, $(lenguaje)!\") \n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/julia/urigroisman.jl",
    "content": "# Sitio web oficial de Julia: https://julialang.org\n\n# Comentario de una sola línea en Julia\n\n#=\nJulia soporta la escritura de comentarios \nen múltiples líneas\n=#\n\n# También soporta comentarios a continuación de un comando\nd = 17 # asigné a la variable a el valor 17\n\n\n# Declaración de una variable\nvariable_texto = \"Cadena de texto\"\n\n# Se pueden asignar multiples variables de la siguiente forma\na = (b = 2 + 2) + 3\n\n# Julia también soporta caracteres Unicode como nombre de variable\nα = 30\nΗ = 3.14\n\n# Julia soporta declaración de constantes. \nconst c = 3.14159 \n\n# Tipos de datos primitivos \n\n#Enteros\nnumero_entero_64b::Int = 64 # Int es por default un entero de 64bits\nnumero_entero_64bU::UInt = 64 # es un entero de 64bits sin signo, lo que permite obtener un entero mayor\n#=\nTambién existen Int16, Int32, Int64 e Int128\ny las mismas opciones con UInt\nPor ejemplo el entero más grande con Int128 es 2^127 - 1\ny con UInt128 2^128 - 1\n=#\n\n#Reales\nnumero_flotante::Float64 = 64.10 # Float64\n# Existe la posibilidad de trabajar con precisión media Float16 o con simple Float32\n\n\ncadena_de_texto::String = \"Hola mundo\" # String\n\n\nbooleano::Bool = true # Bool\n\n\n# Imprimir a la terminal al REPL Hola Julia\nlenguaje_de_programacion = \"Julia\"\nprint(\"¡Hola, $(lenguaje_de_programacion)!\") \n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/AcirDevelper.kt",
    "content": "// One line comment \n\n/*\n  Multi-line comment\n  https://kotlinlang.org/\n*/\n\n //Declare variables and constants\n \n var developer= \"AcirDevelper\"\n val language =\"Kotlin\"\n\n//Type of data\n\n// Byte \nval typeVariable1: Byte = 1\n \n// Short \nval typeVariable2: Short = 25\n \n// Integer  \nval typeVariable3: Int = 8\n \n// Long \nval typeVariable4: Long = 1000000008\n \n// Float  \nval typeVariable5: Float = 96.00f\n \n// Double  \nval typeVariable6: Double = 36.00\n\n//Boolean\nval stockSoldOut: Boolean = false \n \n\n//Arrays \nval date = arrayOf(14, 17, 20, 24, 27)\n \nval desserts = arrayOf(\"Chocolate Cake\", \"Strawberry Jelly\", \"Apple Pie\", \"Flipped Cream\")\n \nval firtNameDesserts = arrayOf('C', 'S', 'A', 'F')\n \nval datesNull = arrayOfNulls<String>(7)\n\n//Print \nfun main(){\n    println(\"¡Hello Developer, ${language}!\")\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/AlvaroMinarro.kt",
    "content": "//  https://kotlinlang.org/\n\n// Comentario de una linea\n\n/*\n    Comentario de varias lineas\n */\n\n// Variable y constante \nvar variable = \"Una variable en kotlin\"\nconst val constant = \"Una constante en kotlin\"\n\n// Tipos de variables\nvar integer: Int = 1\nvar byte: Byte = 1\nvar decimal: Float = 18.3F\nvar decimalDouble: Double = 2.56\nvar numberLonger: Long = 8L\nvar shortVariable: Short = 2\nvar boolean: Boolean = false\nvar char: Char = \"a\"\nvar string: String = \"Hola kotlin\"\nvar array: Array<Number> = arrayOf(1,2,3,4,5)\n\n//  Variables no negativas\nvar nonNegativeByte : UByte = 1U\nvar nonNegativeShort : UShort = 2U\nvar nonNegativeInt : UInt = 3U\nvar nonNegativeLong : ULong = 4UL\n\n//  Imprimir por pantalla\nprint(\"¡Hola, Kotlin!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/AnCarlu.kt",
    "content": "//https://kotlinlang.org/\n\n//Comentarios en Kotlin\n\n//Comentario de una linea\n/*\nComentario de varias lineas\n */\n\n //Declaración de variables y constantes\n var variable = \"AnCarlu\"\n\n val constante = \"Kotlin\"\n\n //Datos primitivos en Kotlin\n\n val string : String = \"Hola a todos\"\n\n val char : Char  = 'P'\n\n val byte : Byte = 5\n\n val short : Short = 55\n\n val int :Int = 555\n\n val long : Long = 40000000L\n\n val float : Float = 15.544546f\n\n val double :Double = 452.456\n\n val boolean : Boolean = true\n\n//Impresion por pantalla del nombre del lenguaje\n\nfun imprimir(){\n    println(\"Hola ${constante}\")\n}\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/Bokysherlo.kt",
    "content": " * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n//https://kotlinlang.org/\n\n//De esta forma se escribe en una sola linea.\n\n/*\nDe esta manera\npodemos hablar \nen varias lineas\n*/\n\n//VARIABLES Y CONSTANTES\n//Para las variables utilizares el termino var y para las constantes val\n\nvar myFristVariable =¨Rojo¨\nval myFristConstante =¨Coche¨\n\n//TIPOS DE DATOS PRIMITIVOS\n\nvar myFristByte = 1\nvar myFristShort = 12\nvar myFristInt = 1545\nvar myFristLong = 1252525252\n\nvar myFristFoat = 1,6f\nvar myFristDouble = 15,12\n\nvar myFristBool = true\n\nPrintln (¨hola Kotlin¨)\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/Braiso-22.kts",
    "content": "/*\n *   EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n */\n\n// https://kotlinlang.org/\n\n// Single line comment\n\n/* Multi\nline\ncomment */\n\n/**\n * Documentation comment\n */\n\nvar age = 22\nage++ // this compiles, it's a variable\n\nval name = \"Brais\" // runtime constant\n\n/**\n * name = \"Blas\"\n * this won't compile\n * */\n\nconst val PI = 3.1415926535F // compile-time constant\n\n// Primitive types\n\n// Integer Numbers\nval byte: Byte = 127 // (+-) 2.pow(7)\nval short: Short = -32768 // (+-) 2.pow(15)\nval int: Int = 2_147_483_647 // (+-) 2.pow(31)\nval long: Long = 0L // to long number (+-) 2.pow(63)\n\n// You can do the same with a U before the type to make it unsigned\nval example: UShort = 65_535u // (+) 2.pow(16)\n\n// Decimals\nval float: Float = 0.000_000_1f\nval double: Double = 0.000_000_000_000_000_2\n\n// Booleans\nval imSmart: Boolean = true\n\n// Char\nval initial: Char = 'B'\n\n// String\nval text: String = \"string\"\n\n// Array\nval lastNames: Array<String> = arrayOf(\"Fernández\", \"Vázquez\")\n\nprintln(\"Hola, Kotlin!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/CrisDev3.kt",
    "content": "// sitio oficial de kotlin https://kotlinlang.org/\n\n// comentario de una linea\n\n/*\ncomentario de\nvarias lineas\n */\n\n// Representación de una variable y una constante\nvar variableExample = 1\nval constantExample = 2\n\n\n// Tipos de datos\n// Numericos\nvar byteExample: Byte = 127\nvar integerExample: Int = 12\nvar shortExample: Short = -32768\nvar longExample: Long = 100000000000\nvar floatExample: Float = 2.1234567\nvar doubleExample: Double = 2.12345678911234567\n\n// Alfanumericos\nvar stringExample: String = \"verde\"\nvar charExample: Char = '@'\n\n// Boolean\nvar booleanExample: Boolean = true\n\n// Arrays\nvar name = \"Pancracio\"\nvar lastName = \"Sanjur\"\nvar nickName = \"TitoDev\"\nvar age = \"26\"\n\nval arrayExample = arrayListOf<String>(name, lastName, nickName, age)\n\nprint(\"¡Hola, Kotlin!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/DONCHUY846.kt",
    "content": "/*\nTHIS IS A BLOCK COMMENT ON MULTIPLE LINES\n SITIO OFICIAL SOBRE EL LENGUAJE DE PROGRAMACION KOTLIN\n    https://kotlinlang.org/docs/getting-started.html#is-anything-missing\n */\n\n//    THIS IS AN END-OF-LINE COMMENT\n\n// constant variables and must be a global variable\nconst val MYFIRSTCONSTANT = \"HOLA\"\nfun main(){\n\n\n    /* variables\n        val to declare variables that are assigned a value only once. These are immutable, can't be reassigned a different value after initialization\n        var to declare variables that can be reassigned. There are mutable variables, and you can change their values after initialization\n     */\n    val x : Int = 5\n    //5\n\n    var xx : Int = 5\n    xx++\n\n    // You can omit the type  after the variable name\n    //Declares the variable x with the value\n    val xxx = 8\n\n\n\n    // Primitive data types are\n\n    val integer: Byte = 127\n    val short: Short = 32767\n    val int: Int = 2147483647\n    val long: Long = 9223372036854775807\n\n    val float: Float = 4.4f\n    val double: Double = 4.4\n\n    val char: Char = '1'\n\n    val boolean:  Boolean = true\n\n    val string : String = \"Apanialo pepe\"\n\n\n    print(\"!Hola, KOTLIN!\")\n\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/Daniel-Cas.kt",
    "content": "// https://kotlinlang.org/\n\n// One line comment\n\n/*\n   Multiple line comment\n*/\n\nval variable = \"Some value\"\nconst val constant = \"Some const\"\n\nval integer: Int = 1\nval byte: Byte = 1\nval decimal: Float = 3.14F\nval decimalDouble: Double = 3.14\nval numberLonger: Long = 1L\nval boolean: Boolean = true\nval char: Char = 'a'\nval string: String = \"Hello World\"\nval array: Array<Number> = arrayOf(1)\n\nfun main() {\n    val language: String = \"kotlin\"\n    println(\"¡Hola ${language}!\")\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/FrancisLeBle.kt",
    "content": "fun main() {\n    println(\"¡Hola, Kotlin!\")\n}\n\nvar myVariable = \"Mi primera variable\"\nval myConstante = \"Mi primera constante\"\n\n// Ejercicio 1 2 y ultimo completo\n\nvar myNumeroEntero: Byte = 1\nvar myShort: Short = 300\nvar myInt: Int = 1\nvar myLong: Long = 300000000000000\nvar myFloat: Float = 22.5F\nvar myStringEquipo: String = \"San Lorenzo\"\nval myArray = arrayOf(\"San\", \"Lorenzo\", \"Boca\", \"River\")\n\n/*\n * No puse todos los tipos de datos basicos. Hice los mas rapidos.\n * Aguante San Lorenzo de Argentina!\n*/\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/HawkBott.kt",
    "content": "/*APARTADO 1 */\n\n/*https://kotlinlang.org/ */\n\n\n/*APARTADO 2 */\n\n/*Comentario 1 */\n//Comentario 2\n\n\n/*APARTADO 3 */\n\nvar myVariable = \"Esto es una variable\"\nval myConstante = \"Esto es una constante\"\n\n\n\n/*APARTADO 4 */\n\n\nvar numeroEntero: Int = 12\nvar numeroByte: Byte = 78\nvar numeroLong: Long = 930273982983\nvar nuemeroShort: Short = 637\n\nvar numeroDouble: Double = 873.8937\nvar nuemeroFloat: Float = 21.32f\n\nvar myCaracter: Char = 'I'\n\nvar primerBolean: Boolean = true \nvar segundoBolean: Boolean = false\n\n\n\n\n\n/*APARTADO 5 */\n\nfun main(){\n    println (\"¡Hola, Kotlin!\")\n}\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/Highscorec1.kt",
    "content": "\n//Pagina de Compilador En Linea Ideal para ejerecicios basicos \n//   https://pl.kotl.in/AoeqZtsuv\n\n//Pagina Oficial del Lenguaje \n//   https://kotlinlang.org/docs/home.html\n\n//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n//                                                     Tipos de Comentarios                                                         //\n//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n\n// Comentario de una sola línea\n\n/*\n   Comentario de varias líneas.\n   Puede ocupar más de una línea.\n*/\n\n/*\n   Comentario de bloque anidado\n   /* Comentario interno */\n*/\n\n/**\n * Comentario de documentación (KDoc)\n * Usado para documentar funciones, clases, etc.\n */\n\n//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n//                                                 Crear variable y constante                                                       //\n//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n\n// Variable mutable (puede cambiar su valor)\nvar miVariable = 10\n\n// Constante (no puede cambiar su valor)\nval miConstante = 20\n\n//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n//                                           Variables con tipos de datos primitivos                                                //\n//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n\n// Cadenas de texto (String)\nval miCadena: String = \"Hola, Kotlin!\"\n\n// Enteros (Int)\nval miEntero: Int = 42\n\n// Números decimales (Double, Float)\nval miDecimal: Double = 3.1416\nval miFloat: Float = 2.5f\n\n// Booleanos (Boolean)\nval miBooleano: Boolean = true\n\n// Caracteres (Char)\nval miCaracter: Char = 'K'\n\n// Byte (8 bits), Short (16 bits), Long (64 bits)\nval miByte: Byte = 127\nval miShort: Short = 32000\nval miLong: Long = 123456789L\n\nfun main() {\n    holaMundo()\n}\n\nfun holaMundo(){\n  val saludo: String = \"Hola Mundo. El Lengueje es Kotlin\"\n    println(saludo)\n}\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/IsmaelMatiz.kt",
    "content": "//pagina oficial https://kotlinlang.org/\n/*\n* comentario de varias lineas\n* */\n\n/**\n * Kdoc lo mismo que Javadoc pero en kotlin\n */\nfun main(args: Array<String>) {\n      //variable\n      var name: String\n\n      //constante\n      val str1: String\n\n      /*\n       * Variable primitivas, en teoria son las mismas de Java pero aqui es como si siempre\n       * usaramos los wrappers y pues no es tan necesario especificarlos excepto\n       * quizas en los casos de short y byte\n       */\n      val c: Char = 'c' //acepta cualquier caracter Unicode\n\n      val i: Int = 50 //acepta enteros con signo desde -2.147.483.648 hasta 2.147.483.649\n\n      val s: Short = -32768 // acepta enteros con signo desde -32.768 hasta 32.767\n\n      val l: Long = -9223372036854775807L // acepta enteros con signo desde -9.223.372.036.854.775.807 hasta 9.223.372.038.854.775.807\n\n      val f: Float = 7.233433f // acepta hasta 6 decimales\n\n      val d: Double = 3.14159 // acepta hasta 14 decimales\n\n      val b: Boolean = true //True or false\n\n      val byte1: Byte = -128 // acepta enteros con signo desde -128 hasta 127\n\n\n      println(\"¡Hola, Kotlin!\")\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/Luis-VB.kt",
    "content": "// https://kotlinlang.org/\n\n//  Comentario en una linea\n\n/*\n*   Comentario en varias lineas\n*\n*/\n\nfun main() {\n    // Variables y constantes\n    var variable: String = \"Variable\"\n    val constante: String = \"Constante\"\n    //Tipos de variables\n    val a: Int = 1000\n    val b: String = \"log message\"\n    val c: Double = 3.14\n    val d: Long  = 100_000_000_000_000\n    val e: Boolean = false\n    val f: Char = '\\n'\n\n// Imprimir por consola hola kotlin\n\n    val kotlin: String = \"¡Hola, Kotlin ☺!\"\n    println(kotlin)\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/LuisAlberto22.kt",
    "content": "//link: https://kotlinlang.org/\n\n/*\n * Este \n * es\n * un\n * comentario\n * en\n * varias\n * lineas\n * \n * */\n\n/* The comment starts here\n/* contains a nested comment */\nand ends here. */\n\nfun main() {\n    val valorConstante = \"Constante\"\n    var valorVariable = \"variable\"\n    \n    //String\n    var stringVariable : String = \"hola mundo\"\n    // o\n    var stringVariableSegundaForma = \"hola mundo\"\n    \n    var charVariable : Char = 'a'\n    var booleanVariable : Boolean = false\n    var integerVariable : Int = 1\n    var longVariable : Long = 1L\n    var floatVariable : Float = 2.51241242141244f\n    var doubleVariable : Double = 12341234213124.5123213123123213\n    var shortVariable : Short = 2\n    var byteVariable : Byte = 127\n    \n    //No Negativos\n    var nonNegativeByte : UByte = 1U\n    var nonNegativeShort : UShort = 2U\n    var nonNegativeInt : UInt = 3U\n    var nonNegativeLong : ULong = 4UL\n    \n    print(\"¡Hola. [Kotlin]!\")\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/OcandoDev.kt",
    "content": "//Documentacion oficial de Kotlin => https://kotlinlang.org/docs\n\n//Tipos de comentarios\n\n// Comentario de una linea\n\n/* \n    Comentario \n    de varias\n    lineas\n*/\n\nfun main(){\n\n    //Variables y constantes\n    val dev = \"OcandoDev\" //Las constantes se definen con val \n    var exercise = 0 //Las variables se definen con var\n\n    //Tipos de datos en Kotlin\n    var _string: String = \"Cadena de texto\"\n    var _int: Int = 1\n    var _boolean: Boolean = false\n    var _float: Float = 26.9f\n    var _double: Double = 26.9\n    var _char: Char = 'A'\n    var _byte: Byte = 127\n    var _short: Short = 32767\n    var _long: Long = 9223372036854775807\n    var _array: Array<Int> = arrayOf(1,2,3)\n\n    var language = \"Kotlin\"\n\n    print(\"Hola, $language!\")\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/OskarCali.kt",
    "content": "// https://kotlinlang.org/\n\n// Comentario en una sola linea\n/* Comentario en\n * multiples lineas\n */\n\n// val -> variable de solo lectura, no puede cambiar de valor\n// var -> variable mutable, que puede cambiar de valor\nval x = 5\nvar y = 8\n\n// Los datos primitivos/básicos son\n//\n// Enteros -> Byte, Short, Int, Long\n// Enteros sin signo -> UByte, UShort, UInt, ULong\n// Números con decimal -> Float, Double\n// Booleanos -> Boolean\n// Caracteres -> Char\n// Cadenas de texto -> String\n\nval entero: Int = 843\nval text = \"Hola comunidad\"\nval decimal: Double = 3.141592\nval largeNumber: Long = 48_365_102_000\nval aprendiendo = true\n\nfun main() {\n    print(\"¡Hola, Kotlin!\")\n}\n\n// NOTAS FINALES\n//\n// 1) Se recomienda utilizar var solamente cuando sea necesario.\n// 2) Los tipos de dato pueden ser inferidos al momento de la asignación o definirse después\n//    del nombre de la variable con : (dos puntos) y el tipo de dato.\n// 3) Para los números se pueden colocar _ (guion bajo) para mejorar la lectura\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/SebasGRDev.kt",
    "content": "//Sitio oficial Kotlin = https://kotlinlang.org/\n\n\n//Comentario de una linea\n\n/*\nComentario\nde\nvarias\nlineas\n */\n\n\n//Crea una variable (y una constante si el lenguaje lo soporta).\n var variable: String = \"Hola variable!\"\n val constante: String = \"Hola constante!\"\n\n const CONSTANTE = \"CONSTANTE\"\n\n /*\n Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n  */\n  var texto: String = \"Hola mundo!\"\n  var entero: Int = 31\n  var decimal: Double = 1.3\n  var flotantes: Float = 5.0f\n  var booleanos: Boolean = false\n\n  println(\"Hola, Kotlin!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/Vikkanh.kt",
    "content": "    \n    // https://kotlinlang.org/\n    \n    // comentario en una linea\n    \n    /*comentario\n     en\n     varias\n     lineas*/\n    \n     var myVariable: String = \"Variable\"\n     val myConstant: String = \"Constante\"\n     \n     \n     val byte:Byte = 8   // contiene valores entre -128 y 127\n     val short:Short = 16   // contiene valores entre -32768 y 32767\n     val entero:Int = 32   // contiene valores entre -2,147,483,648 y 2,147,483,647\n     val long: Long = 64   // contiene valores entre -9,223,372,036,854,775,808 y 9,223,372,036,854,775,807\n     val float: Float = 16.10f   // contiene valores con hasta 7 decimales\n     val double: Double = 64.10   // contiene valores con hasta 16 decimales\n     \n     val string: String = \"Cadena de texto\"   // contiene caracteres alfanumericos siempre entre comillas dobles\n     val char: Char = 'A'   // contiene un solo caracter siempre entre comillas simples\n     \n     val boolean: Boolean = true   // contiene valores true o false\n     \n     \n     val nombreLenguaje: String = \"Kotlin\"\n     println(\"¡Hola, $nombreLenguaje!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/VincentRodriguezR.kt",
    "content": "// https://kotlinlang.org/\n\n/*\nEsto es\nun comentario\nmultilinea en\nKotlin\n */\n\nfun main() {\n\n\n    //Definicion de Variable y constante\n    var Variable = \"Variable\"\n    val Constante = \"Constante\"\n\n    //Tipos de datos primitivos\n    var entero: Int = 33\n    var decimal: Double = 3.3\n    var flotante: Float = 3.333f\n    var caracter: Char = 's'\n    var boleano: Boolean = true\n\n    //Hola mundo en Kotlin\n    val sayHi = \"Hola Kotlin!!!\"\n    println(sayHi)\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/VolumiDev.kt",
    "content": "fun main(args: Array<String>) {\n// Esta es la pagina del lenguaje https://kotlinlang.org/\n\n// Con esto representamos un comentario en una sola linea\n\n/*Aqui tenemos \npara meter comentarios en varias\nlineas */\n\n//  ✅ Creamos una variable\nvar language = \"kotlin\"\n\n//  ✅ Creamos una constante\nval pi = 3.14\n\n// ✅ Tipos de datos primitivos de tipo Integer (Byte, Short, Int, Long)\nvar exm_byte : Byte = 6\nprintln(\"Ejemplo de byte: $exm_byte\")\n\nvar exm_short : Short = 5555\nprintln(\"Ejemplo de short: $exm_short\")\n\nvar exm_int : Int = 429496\nprintln(\"Ejemplo de int: $exm_int\")\n\nvar exm_long : Long = 999999999999234 \nprintln(\"Ejemplo de long: $exm_long\")\n\n// ✅ Tipos de datos primitivos de tipo Unsigned Integers (UByte, UShort, UInt, ULong)\nvar exm_Ubyte : UByte = 6u // tiene un rango entre 0-8 \nprintln(\"Ejemplo de Ubyte: $exm_Ubyte\")\n\nvar exm_Ushort : UShort = 5555u \nprintln(\"Ejemplo de Ushort: $exm_Ushort\")\n\nvar exm_Uint : UInt = 429496u \nprintln(\"Ejemplo de Uint: $exm_Uint\")\n\nvar exm_Ulong : ULong = 999999999999234u\nprintln(\"Ejemplo de Ulong: $exm_Ulong\")\n\n// ✅ Tipos de datos primitivos de tipo Floating point  (Float, Double)\nvar exm_float : Float = 2.43f\nprintln(\"Ejemplo de Float: $exm_float\")\n\nvar exm_double : Double = 125.55566\nprintln(\"Ejemplo de Double: $exm_double\")\n\n// ✅ Tipos de datos prmitivo de tipo Booolean\nvar exm_bol : Boolean = true\nprintln(\"Ejemplo de boolean a : $exm_bol\")\nexm_bol = false\nprintln(\"Ejemplo de boolean a : $exm_bol\")\n\n// ✅ Tipo de dato Char \nvar exm_char : Char = 'a'\nprintln(\"Ejemplo char : $exm_char\")\n\n// ✅ Tipo de dato String\nvar exm_string : String = \"Kotlin\"\nprintln(\"Hola $exm_string!!!\")\n\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/adridoce.kt",
    "content": "// https://kotlinlang.org/\n\n// Comentario en una linea\n\n/*\n    Comentario multilinea\n */\n\nconst val PI = 3.1416                       // Constante, usando const debe de ser una variable global\n\nfun main() {\n    /*\n        val se utiliza para declarar variables inmutables con valores conocidos en tiempo de ejecución, \n        mientras que const se utiliza para declarar constantes de tiempo de compilación cuyos valores son conocidos en tiempo de compilación.\n    */\n\n    var numero: Int = 1                     // Variable mutable\n    val lenguaje: String = \"Kotlin\"         // Variable inmutable\n    \n    // Numeros enteros\n    var byte: Byte = 127                    // 8 bits\n    var short: Short = 32767                // 16 bits\n    var entero: Int = 2147483647            // 32 bits\n    var long: Long = 9223372036854775807    // 64 bits\n\n    // Numeros de punto flotante o decimales\n    var float: Float = 1.5f                 // 32 bits\n    var double: Double = 1.5                // 64 bits\n\n    // Caracteres\n    var char: Char = 'A'\n\n    // Cadenas de texto\n    var string: String = \"Hola mundo!\"\n\n    // Booleanos\n    var booleano: Boolean = true            \n\n    // Arrays\n    val array: Array<Int> = arrayOf(1, 2, 3)\n\n    print(\"Hola, $lenguaje\")\n    \n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/blackriper.kt",
    "content": "// comentarios de una linea y mas de  una linea \n\n/*\n https://kotlinlang.org/\n*/\n\n //declarar varibles y constantes \n \n var developer= \"blackriper\"\n val language =\"Kotlin\"\n\n//tipos de datos\n\n// Byte \nval tipovariable1: Byte = 1\n \n// Short \nval tipovariable2: Short = 25\n \n// Integer  \nval tipovariable3: Int = 8\n \n// Long \nval tipovariable4: Long = 1000000008\n \n// Float  \nval tipovariable5: Float = 96.00f\n \n// Double  \nval tipovariable6: Double = 36.00\n\n//booleano\nval stockagotado: Boolean = true \n \n\n//arrays \nval edades = arrayOf(14, 17, 20, 24, 27)\n \nval postres = arrayOf(\"Torta de Chocolate\", \"Gelatina de Fresa\", \"Pie de Manzana\", \"Crema Volteada\")\n \nval primerNombrePostre = arrayOf('T', 'G', 'P', 'C')\n \nval datosnull = arrayOfNulls<String>(7)\n\n//imprimir \nfun main(){\n    println(\"¡Hola,${language}!\")\n}\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/borjadelgadodev.kts",
    "content": "// Lenguaje Kotlin --> https://kotlinlang.org/\n\n// Este es un comentario de una línea\n\n/* Comentario\n    varias\n    lineas\n */\n\n// Variable y constante\nvar variable = \"Borja\"\nval constante = 1993\n\n// Primitivos\nval num1: Byte = 1\nval num2: Short = 1\nval num3: Int = 30\nval num4: Long = 1039984\nval num5: Double = 1.5\nval num6: Float = 6.8\nval letra: Char = 'a'\nval cadenaTexto: String = \"Cadena de texto\"\nval prueba: Boolean = true // false\n\n// Imprimir texto\nval lenguaje: String = \"Kotlin\"\nprintln(\"¡Hola, $lenguaje!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/clotrack.kt",
    "content": "fun main(){\n    \n    // 00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n\n        // EJERCICIO 00:\n        // 0-01 Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n\n        // 0-01-a Esta es la URL del sitio oficial de kotlin | https://kotlinlang.org/ |\n\n        // 0-01-b Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n\n        // Este es un comentario de una linea\n\n        /* Sin embargo este es un comentario\n         * de varias lineas lo escrito aqui\n         * es un comentario.\n         */\n\n        // 0-02 Crea una variable (y una constante si el lenguaje lo soporta).\n\n        var myVariable = \"Esta es una variable de tipo sting\"\n        val constantePi = 3.1416\n        // Pi = 5.2514 ---> esto proboca un error dado que 'val' es una constante y 'var' es una variable\n\n        // 0-03 Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n\n        // 0-03-a Variables de tipo texto\n        var continuarSiChar = 'Y'\n        var stringCoqueto = \"keh ase una shika como tu en un juglar come ete?\"\n\n        // 0-03-b Variables de tipo numerico (Hay mas como las hexadecimales entre otras, pero e puesto las mas comunes)\n        var myNumByte = 3\n        var myNumShort = 35\n        var myNumInteger = 1518\n        var myNumLong = 15487569\n        var myNumDouble = 3.5934\n        var myNumFloat = 3.5935488f\n\n        // 0-03-c Variables de tipo Booleanas con sus tres posibilidades\n        val myTrue = true\n        val myFlase = false\n        val myIndecision = null\n\n        // 0-04 Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\n        // El texto provoca un fallo de impresion en mi compilador devido a que el caracter | ¡ | \n        // igual no se encontrara en la escritura inglesa?!?!?\n        println(\"¡Hola, kotlin!\" + \"¡Bienvenido al mundo!\")\n        \n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/davidcv-dev.kt",
    "content": "// https://kotlinlang.org/\n\n//  Comentario de una linea\n\n/*\n*   Comentario en varias lineas\n*   del codigo\n*/\n\nfun main() {\n    // Variables y constantes\n    var variable: String = \"Variable\"\n    val constante: String = \"Constante\"\n    //Tipos de variables\n    val a: Int = 50\n    val c: Double = 3.14\n    val b: String = \"log message\"\n    val d: Long  = 100_000_000_000_000\n    val e: Boolean = false\n    val f: Char = '\\n'\n\n// Imprimir por consola\n\n    val texto: String = \"¡Hola, David\"\n    println(texto)\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/deiiviitdev.kt",
    "content": "// https://kotlinlang.org/\n\n// One line comment\n\n/*\n   Multiple line comment\n*/\n\n/**\n * This is a documentation comment\n */\n\nval drink = \"Cafe\"\nconst val dish = \"Pizza\"\n\n\n/**\n * Basic types\n */\n// Integer types\nval one: Int = 1\nval threeBillions: Long = 3000000000\nval oneByte: Byte = 1\nval oneShort: Short = 1\n\n// Floating point types\nval pi: Float = 3.14f\nval e: Double = 2.71828\n\n// Unsigned types\nval oneUByte: UByte = 1u\nval oneUShort: UShort = 1u\nval oneUInt: UInt = 1u\nval oneULong: ULong = 1u\n\n// Boolean type\nval isTrue: Boolean = true\n\n// Character type\nval a: Char = 'a'\n\n// String type\nval hello: String = \"Hello\"\n\n// Array type\nval oneToFive: Array<Int> = arrayOf(1, 2, 3, 4, 5)\nval oneToFive2: IntArray = intArrayOf(1, 2, 3, 4, 5)\n\n/**\n * Print \"Hola, Kotlin\" to the console\n */\nfun main() {\n    println(\"Hola, Kotlin\")\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/didacdev.kt",
    "content": "// https://kotlinlang.org\n\n// Comentario de una línea\n\n/*\n    Comentario\n    de\n    varias\n    líneas\n */\n\nval name = \"Diego\" // Constante\nvar age = 27 // Variable\n\nval integer: Int = 0\nval float: Float = 0.1\nval double: Double = 0.01\nval string: String = \"string\"\nval boolean: Boolean = true\n\nfun main() {\n\n    println(\"¡Hola, Kotlin!\")\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/diegopc-dev.kt",
    "content": "// Sintasix, variables y tipos de datos\n\n// Web oficial: https://kotlinlang.org\n\n// Comentario de una línea\n\n/*\n    Comentario de varias lineas,\n    o tambien llamado multilinea\n*/\n\n// Constante\nval text = \"Esto no puede cambiarse\"\n\n// Variable\nvar number = 10\n\n// Datos primitivos\nval numA: Int = 2 // Numeros entero\nval numB: Float = 2.3 //Numero flotante\nval numC: Double = 0.03 //Numero flotante grande\nval text2: String = \"Cadena\" //Cadena de caracteres\nval bool: Boolean = true //Tipo booleano\n\nfun main (){ //Declaracion Funcion\n\n    println(\"Hola, kotlin\") //Instruccion\n\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/eloitr.kt",
    "content": "fun main() {\n    // Pagina oficial: https://kotlinlang.org/\n\n    // Comentario de una linea\n\n    /* Comentario\n       en varias\n       lineas\n    */\n\n    // Declaración de variables y constantes\n    var lenguaje = \"Kotlin\" \n    val E = 2.71 \n\n    // Tipos primitivos\n    var tipovariable_1: Int = 10\n    var decimal: Double = 12.5\n    var caracter: Char = 'a'\n    var cadena: String = \"Hola esto es una cadena\"\n    var booleano: Boolean = true\n\n    // Imprimir en la terminal\n    println(\"Hola \"+ lenguaje)\n    println(\"Hola ${lenguaje}\")\n    \n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/elpeque29.kt",
    "content": "// FIRST\n\n// https://kotlinlang.org/\n\n// SECOND\n\n// Comment in one line\n\n/*\n* Comment in\n* multiple lines\n*/\n\n// THIRD \n\nfun main() {\n\n    val myFistVal = 1\n    var myFirstVar = 2\n\n// FORTH \n\n    // Primitives\n    val aByte: Byte = 127\n    val aShort: Short = 32767\n    val aInt: Int = 2147483647\n    val aLong: Long = 9223372036854775807\n    val aFloat = 1.1111112f\n    val aDouble = 1.1111111111111110\n    val myTrue = true\n    val myFalse = false\n    val boolNull: Boolean? = null\n    val aChar = 'a'\n    val aString = \"(°-°)\"\n    val anArray = arrayOf(\"a\", \"b\", \"c\")\n\n    //  Non Negative\n    var nonNegativeByte : UByte = 1U\n    var nonNegativeShort : UShort = 2U\n    var nonNegativeInt : UInt = 3U\n    var nonNegativeLong : ULong = 4UL\n\n// FIFTH\n    println(\"Hello Kotlin\")\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/eulogioep.kt",
    "content": "// URL del sitio web oficial de Kotlin: https://kotlinlang.org/\n\n// Esto es un comentario de una línea\n\n/*\n * Esto es un comentario\n * de varias líneas\n */\n\n// Creación de una variable\nvar miVariable = \"Hola, soy una variable\"\n\n// Creación de una constante\nval MI_CONSTANTE = 3.14159\n\n// Variables representando tipos de datos primitivos\nval entero: Int = 42\nval flotante: Float = 3.14f\nval doble: Double = 3.14159\nval booleano: Boolean = true\nval caracter: Char = 'A'\nval cadena: String = \"Esto es una cadena de texto\"\n\n// En Kotlin no hay un tipo \"null\" primitivo, pero se puede usar tipos nullables\nval nulo: String? = null\n\n// Imprimir por terminal\nfun main(){\n    val nombreLenguaje: String = \"Kotlin\"\n    println(\"¡Hola, $nombreLenguaje!\")\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/frealexandro.kt",
    "content": "\n\n// URL del sitio web oficial de Kotlin\n// https://kotlinlang.org/\n\n// Comentario de una línea\n\n/*\n * Comentario de varias líneas\n */\n\n\n// Variable\nvar myVariable = \"Mi primera variable\"\nval myConstante = \"Mi primera constante\"\n\n\n// Tipos de datos\nval myInt: Int = 5\nval myByte: Byte = 100\nval myShort: Short = 5000\nvar myLong: Long = 2147483648\nval myFloat: Float = 3.7f\nval myDouble: Double= 5.99\nval myChar: Char = 'D'\nval myString: String = \"Hello\"\nval myBoolean: Boolean = true\nvar myArray: Array<Number> = arrayOf(1,2,3,4,5)\n\n// Imprimir\nfun main() {\n    println(\"¡Hola, Kotlin!\")\n}\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/gamitocu.kt",
    "content": "// https://kotlinlang.org\n\n// Comentar una linea\n\n/*\n * Comentar multiples lineas\n */\n\n// Variable y Constante\nvar myVariable = \"Variable\"\nval myConst = \"Constante\"\n\n// Tipos de datos\nval myInt: Int = 5\nval myByte: Byte = 100\nval myShort: Short = 5000\nvar myLong: Long = 2147483648\nval myFloat: Float = 3.7\nval myDouble: Double= 5.99\nval myChar: Char = 'D'\nval myString: String = \"Hello\"\nval myBoolean: Boolean = true\nvar myArray: Array<Number> = arrayOf(1,2,3,4,5)\n\n// Imprimir\nvar language = \"Kotlin\"\nprintln(\"Hola, $language!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/icedrek.kt",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n// Sitio oficial: https://kotlinlang.org/\n\n// Comentario de una linea con '//'\n\n/*\n * Comentario de\n * varias lineas\n */\n\nvar a = 1  // tras el codigo tambien se pueden incluir comentarios\n\n// VARIABLES\n// las variables se escriben con letras minúsculas\n// Para definir una variable se utiliza \"var\"\nvar variable = \"hola\"\n\n// si el nombre de la variable es compuesto, se utiliza camelCase\nvar variableNombreCompuesto = \"hola\"\n\n// también se puede definir el tipo de la variable\nvar variableTipo: String = \"hola\"\n\n\n// En Kotlin se pueden definir las constantes de dos formas\n// Mediante \"val\", se genera una variable de solo lectura\nval variableInmutable = \"hola\"\n\n// Mediante \"const\", se genera una constante. \n// Se utiliza cuando se conoce el valor de la constante de antemano\n// Se escribe en mayusculas para diferenciarla\nconst val PI = 3.14\n\n// TIPOS\nval variableByte: Byte = 8 // Puede tomar valores entre -128 y 127\nval variabteShort: Short = 16 // Puede tomar valores entre -32768 y 32767\nval variableInt: Int = 32 // Puede tomar valores entre -2^31 y 2^31 - 1\nval variableLong: Long = 64 // Puede tomar valores entre -2^63 y 2^63 - 1\n\nval variableFloat: Float = 32.00f //Puede tener hasta 7 dígitos decimales\nval variableDouble: Double = 64.00 //Puede tener hasta 16 dígitos decimales\n\nval variableBoolean: Boolean = true //Puede tener valores 'true' o 'false'\n\nval variableChar: Char = 'a' //Se definen con comilla simple para que no se interprete como String(de lo contrario dara error)\nval variableString: String = \"cadena de texto\" // Se utiliza para almacenar cadenas alfanumericas\n\n//para mostrar un valor por pantalla se utiliza la funcion println()\nprintln(\"hola Python\") \n\n// tambien podemos mostrar el valor de una variable\nval lenguaje = \"Kotlin\"\nprintln(\"hola ${lenguaje}\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/isaacus98.kt",
    "content": "// https://kotlinlang.org/\n// Comentario de una linea\n/*\n * Comentario de varias lineas\n */\n\n// Declarar variable y constante\nvar variable = \"variable\"\nval variable2 = \"variable2\"\nconst val constante = \"constante\"\n\n// Primitivos\nval byte: Byte = 1\nval short: Short = 1\nval int: Int = 1\nval long: Long = 1\nval bool: Boolean = true\nval char: Char = 'a'\nval string: String = \"a\"\n\nfun main() {\n    // Imprimir por pantalla\n    print(\"¡Hola, Kotlin!\")\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/jaennova.kt",
    "content": "/*\n * Kotlin es un lenguaje de programación moderno y conciso que se enfoca en\n * la interoperabilidad con Java. Puedes encontrar más información en su sitio\n * web oficial: https://kotlinlang.org/\n */\n\n// Comentario de una línea\nval mensaje: String = \"¡Hola, Kotlin!\" // Comentario en línea después de la declaración de la variable\n\n/*\n   Comentario multilinea\n   para explicar\n   varios detalles\n*/\n\n/**\n * Este es un comentario de documentación\n * Puedes acceder a él mediante herramientas de generación de documentación.\n */\n\n// Variable y constante\nvar variableMutable = \"Hola, Kotlin\"\nval constanteInmutable = 42\n\nvar texto: String = \"Hola, \" // Variable de tipo cadena de texto\nvar entero: Int = 10 // Variable de tipo entero\nvar decimal: Double = 5.5 // Variable de tipo decimal\nvar booleano: Boolean = true // Variable de tipo booleano\n\nfun main() {\n    println(\"$texto${mensaje.substringAfter(\", \")}\") // Imprime: ¡Hola, Kotlin!\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/jhordanluyo.kt",
    "content": "const val SecLastName = \"Luyo\"// la constantes \"Const\" se determinar en el tiempo de compilacion se usa como una variable global\nfun main(){\n//kotlin es un lenguaje de programacion moderno y con facil sintaxtis enfocado en reemplazar a java \n//creado por la empresa JetBrains\n//Ademas de ser impulsado para uso en multiplitaforma y contar con todas las caracteristicas\n\n//https://kotlinlang.org\n\n//Tipos de comentarios\n//comentarios de una sola linea\n/*comentarios de multiples lineas\nlinea 1\nlinea 2\nlinea 3 */\n\n\n//variables\nvar name = \"Jhordan\"\n\n//constante\nval lastName = \"Luyo\" // la constate val se determina en el tiempo de ejecucion\n\n\n//Tipos de datos en kotlin\n\n//datos numericos \nval byte:Byte = 127         //8 bits\nval short:Short = 32767     //16 bit\nval entero:Int = 233333     //32 bits\nval long: Long = 12121212   //64 bits\n\n//numericos con puntos flotantes\nval float:Float = 12.4f         //Decimal de simple precisión\nval double:Double = 23.233232   //Decimal de doble precisión\n\n//cadenas y caracter\nval cadena:String = \"Cadena\"  \nval caracter: Char = 'C'\n\n//dato booleano\nval booleano:Boolean = true\n\n//arrays\nval array: Array = arrayOf(1,2,3)\n\n\n\nprint(\"¡Hola, kotlin!\")\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/juaruibr.kt",
    "content": "//Al igual que la mayoría de los lenguajes modernos, Kotlin admite comentarios de una sola línea (o fin de línea ) y de varias líneas ( bloque ).\n\n//Comentario en una sola linea\n\n/* Comentario en bloque o de varias lineas\n        URL Sitio oficila Kotlin\n        https://kotlinlang.org/\n*/\n\n//Los comentarios de bloque en Kotlin se pueden anidar.\n\n/*Comentario inicia aqui\n/*Contine un comentario anidado*/\ny el comentario finaliza aqui! */\n\n//*********** VARIABLES **********\nvar variable\nval constante\n\n//Enteros\nvar entero_AI: Int = 5 // asignación inmediata\nvar entero_Inf = 5 // se infiere el tipo \"Int\"\nvar entero_Sin_Inicializar: Int  //Tipo requerido cuando no tiene inicialización\nentero_Sin_Inicializar = 5 // asignación diferida\n\nvar enteroLargo: Long = 3000000000\n\n//Decimales\nval pi = 3.14 //Double\n\n//Para especificar explícitamente el Floattipo de un valor, agregue el sufijo fo F. Si dicho valor contiene más de 6 o 7 dígitos decimales, se redondeará: Float, actual value is 2.7182817\nval float = 2.7182818284f\n\n//Booleanos\nval myTrue: Boolean = true\nval myFalse: Boolean = false\nval boolNull: Boolean? = null\n\n//Char / Caracteres\nval aChar: Char = 'a'\n\n//Cadenas de Texto\nval str = \"abcd 123\"\n\n//Matrices\nvar riversArray = arrayOf(\"Nile\", \"Amazon\", \"Yangtze\")\nriversArray += \"Mississipi\" //Lo que hace es adicionar un valor mas a la matriz\n\nfun main(){\n    println(\"¡Hola, Kotlin!\")\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/kuroz00.kt",
    "content": "fun main() {\n    println(\"Hello World!\")\n    //https://kotlinlang.org/\n    //comentario una linea\n    /*\n    Comentario\n    de varias\n    lineas\n     */\n    var numeroVariable : Int = 1\n    val numeroConstante : Int = 1\n\n    //Datos primitivos\n    val entero : Int = 1\n    val flotante : Float = 1f\n    val largo : Long = 1\n    val letra : Char = 'a'\n    val cadena : String = \"kotlin\"\n    val booleano : Boolean = true\n    val arreglo = arrayOf(\"esto\", \"es\", \"un\", \"arreglo\")\n\n    //Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n    println(\"Hola! $cadena\")\n\n\n}\n/*\n* EJERCICIO:\n* - Crea un comentario en el código y coloca la URL del sitio web oficial del\n*   lenguaje de programación que has seleccionado.\n* - Representa las diferentes sintaxis que existen de crear comentarios\n*   en el lenguaje (en una línea, varias...).\n* - Crea una variable (y una constante si el lenguaje lo soporta).\n* - Crea variables representando todos los tipos de datos primitivos\n*   del lenguaje (cadenas de texto, enteros, booleanos...).\n* - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n*\n */"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/m-doce.kt",
    "content": "package com.mdoce.androidtutorial.mouredevretos\r\n\r\nfun main() {\r\n\r\n    //  https://kotlinlang.org/\r\n\r\n    /*\r\n    * Comentario\r\n    * en\r\n    * múltiples\r\n    * líneas\r\n    * */\r\n\r\n    var variable = 7\r\n    val constante = \"Kotlin\"\r\n\r\n    var numero: Int = 12\r\n    var texto: String = \"Doce\"\r\n    var verdadero: Boolean = true\r\n    val pi: Double = 3.1415\r\n    val letra: Char = 'M'\r\n\r\n    print(\"¡Hola, Kotlin!\")\r\n\r\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/mbmaeso.kt",
    "content": "// https://kotlinlang.org/\n\n// One line comment\n/*\n  Block comment\n*/\n\n// Creation of variables and constants\nvar variable = \"This is a Kotlin variable\"\nval constant = \"This is a Kotlin constant\"\n\n// Primitive types\n// Numbers\nval int: Int = 1\nval long: Long = 1L\nval byte: Byte = 1\nval short: Short = 1\nval float: Float = 1.0f\nval double: Double = 1.0\n\n// Unsigned arrays and ranges\nval ubyte: UByte = 1u\nval ushort: UShort = 1u\nval uint: UInt = 1u\nval ulong: ULong = 1u\n\n// Booleans\nval boolean: Boolean = true\n\n// Characters\nval char: Char = 'q'\nval string: String = \"abc\"\nval multilineString: String = \"\"\"\n  I am\n  a multiline\n  string\n\"\"\"\n\nprint(\"¡Hola, Kotlin!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/miguelex.kt",
    "content": "fun main() {\n    // Documentacion en https://kotlinlang.org/\n\n    // Comentario en una linea\n\n    /* Comentario\n       en varias\n       lineas\n    */\n\n    // Declaración de variables y constantes\n    var lenguaje = \"Kotlin\" // Variable\n    val PI = 3.1416 // Constante\n\n    // Tipos primitivos\n    var entero: Int = 10\n    var decimal: Double = 12.5\n    var caracter: Char = 'a'\n    var cadena: String = \"Hola\"\n    var booleano: Boolean = true\n\n    // Salida por consolaç\n    println(\"Hola ${lenguaje}\")\n    println(\n            \"El valor de la variable es $entero y el valor de la constante es $PI y el valor de la variable es $decimal y el valor de la variable es $caracter y el valor de la variable es $cadena y el valor de la variable es $booleano\"\n    )\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/pedroomar23.kt",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n // Este es el sitio web de Kotlin https://kotlinlang.org\n\n // Este es un comentario de una sola linea \n\n /*\n  Este es un comentario de mas de 2 lineas \n */\n\n // Variables y Constantes \n var numero: Int = 0 \n val nombre: String = \"\"\n\n var new: Bool = false \n val newNombre: Bool = true \n\n var pi = 3.1415\n\n var kotlin = \"!Este es el lenguaje que estoy aprendiendo ahora!\"\n \n print(\"!Hola, [kotlin]!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/r-flavio.kt",
    "content": "// https://kotlinlang.org\n\n// Esta es una línea de comentario\n\n/* Este es un bloque de comentario\nque termina cuando se cierra\naquí  */\n\n\n// Variables en Kotlin\nvar textoExplicativo: String = \"Esto es una variable en Kotlin.\"\nval textoConstante: String = \"Esto es una constante en Kotlin y no varía.\"\n\n// Tipos de datos en Kotlin\nval byteNumber: Byte = 101\nval shortNumber: Short = 2242\nval intNumber: Int = 324234\nval longNumber: Long = -32423423423L\nval floatNumber: Float = 3.445f\nval doubleNumber: Double = 113.45345345\nval valorBooleano: Boolean = true\nval unChar: Char = '$'\n\nfun main() {\n    println(\"Hola, Kotlin!\")\n}\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/rikmij.kt",
    "content": "//Con la doble barra creas un comentario de 1 sola línea\n/*\nCon estos símbolos se crea el comentario de varias líneas\nEn esta segunda línea agrego la web de Kotlin que es https://kotlinlang.org/\n*/\n\n//constantes y variables en Kotlin\nval constante = \"Soy una constante porque llevo val delante\"\n\nvar variable = \"Soy una variable declarada con var\"\n\n\nfun main() {\n    /*Creando variables de distintos tipos\nEn Kotlin las variables se inician con camel case por convención\n*/\n    //Se puede cambiar por estar dentro de main, si no no se podría cambiar\n    var tipoStr = \"Esta variable va a ser cambiada\"\n    tipoStr = \"Kotlin\"\n\n    var tipoNumEntero = 33\n\n    var tipoDoub = 3.1415\n\n    // Es un float porque lleva una f al final, si no sería Double\n    var tipoFl = 3.1415f\n\n    var tipoBool = true\n\n    var tipoNulo = null\n\n    var tipoArStr = arrayOf(\"Gracias\", \"por esto\", \"eres grande\", \"Moure\")\n\n    var tipoArNum = arrayOf(1, 2, 3, 4, 5)\n\n    //Para imprimir hay que declarar la función main, si no no imprime\n    println(\"Hola, $tipoStr\")\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/saracorraless.kt",
    "content": "//https://kotlinlang.org/\n\n//comentario de una línea\n\n/*comentario\nen\nvarias\nlíneas*/\n\nfun main() {\n    //constante\n    val CONSTANTE = 2\n\n    //variable\n    var variable = 3\n\n    //tipos de variables\n    var byteVar :Byte = 20\n    var shortVar :Short = 20\n    var intVar :Int = 20\n    var longVar :Long = 20\n    var floatVar :Float = 2.2f\n    var doubleVar :Double = 0.3\n    var charVar :Char = 'Y'\n    var booleanVar :Boolean = true\n\n    var bitmapLocation = 0b00100001 // Literal binario 0b ó 0B   33\n    var chestColor = 0xCCC // Literal hexadecimal 0x ó 0X   3276\n\n    // Literales reales\n    var exp1 = 3.211e2  //321.1\n    var exp2 = .0001e10 // 1000000.0\n    var exp3 = 48e5 //4800000.0\n    var exp4 = 10e-4 //0.001\n\n    //Caracteres de escape\n    /**\n    \\t: Tabulación\n    \\b: Retroceso\n    \\r: Retorno de carro\n    \\n: Salto de línea\n    \\': Apostrofe\n    \\\": Comilla doble\n    \\\\: Backslash\n    \\$: Símbolo de dólar\n    \\u+XXXX: Símbolo Unicode con 4 dígitos hexadecimales\n\n     */\n\n    //mensaje por consola\n    println(\"¡Hola, Kotlin!\")\n\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/sgb004.kt",
    "content": "fun main(){\n\t// https://kotlinlang.org/\n\n\t/* https://kotlinlang.org/ */\n\n\tval constant = \"Constant\"\n\tvar variable = \"Variable\"\n\n\tval varByte: Byte = 1\n\tval varShort: Short = 2\n\tval varInt: Int = 3\n\tval varLong: Long = 4\n\tval varFloat: Float = 5.67f\n\tval varDouble: Double = 8.91\n\tvar varChar: Char = 'A'\n\tvar varBoolean: Boolean = true\n\n\tprintln(\"¡Hola, Kotlin!\")\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/tecfer.kt",
    "content": "//# #00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n//#### Dificultad: Fácil | Publicación: 26/12/23 | Corrección: 02/01/24\n\n//## Ejercicio\n\n/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n//## Solución\n\n//# Url del lenguaje  https://kotlinlang.org/ -> los comenterios simples empiezan por \"//\" Este es una línea de comentario.\n\n/* \nLo que es encuentre en medio de la barra asterisco y asterisco barra es un bloque de comenterio, \npuede ser de múltiples líneas. \n*/\n\nvar valorVariable: String = \"\"\nval ValorConstante: Int = 10 // Kotlin permite declarar constantes con \"val\", val es inmutable, var es mutable.\n\n// El tipado de datos en Kotlin es estático, se puede omitir el tipo y que lo infiera al darle el valor.\nval booleano: Boolean = true // false\nval entero: Int = 15\nval decimal: Double = 1.2\nval cadena: String = \"Esto es una cadena\"   \n\nfun main() {\n    println(\"¡Hola, Kotlin!\")\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/traver79.kt",
    "content": "// comentarios de una linea y mas de  una linea \n\n/*\n https://kotlinlang.org/\n*/\n\n //declarar varibles y constantes \n \n var developer= \"Traver79\"\n val language =\"Kotlin\"\n\n//tipos de datos\n\n// Byte \nval tipovariable1: Byte = 1\n \n// Short \nval tipovariable2: Short = 25\n \n// Integer  \nval tipovariable3: Int = 8\n \n// Long \nval tipovariable4: Long = 1000000008\n \n// Float  \nval tipovariable5: Float = 96.00f\n \n// Double  \nval tipovariable6: Double = 36.00\n\n//booleano\nval tipodevariable7: Boolean = true \n \n//arrays \nval tipodevariable8 = arrayOf(14, 17, 20, 24, 27)\n\n//imprimir \nfun main(){\n    println(\"¡Hola,${language}!\")\n}\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin/westwbn.kt",
    "content": "// Sitio Web Oficial: https://kotlinlang.org/\n\n//Constante\nconst val LANGUAGE = \"Kotlin\"\n\nfun main() {\n    //Comentario de una linea\n\n    /*\n    * Comentario\n    * de\n    * varias\n    * líneas\n    */\n    val firstNumber: Int = 12 //Variable inmutable (su valor no puede modificarse)\n    var result: Int = 0 // Variable mutable (su valor puede modificarse)\n    result = firstNumber * 2 // result = 24\n//    Tipos Primitivos:\n\n    // #Enteros\n    val number: Int = 8\n    val one: Short = 1\n    val threeBillion: Long = 3_000_000_000\n    val oneByte: Byte = 1\n\n    // #Punto flotante\n    val pi = 3.14 // Double\n    val floatNumber: Float = 2.71f\n\n    // #Constantes literales\n    val hexadecimal = 0x0F\n    val binaryNumber = 0b00001011\n    val text: String = \"Programación\"\n    val myTrue: Boolean = true\n    val myFalse: Boolean = false\n    val character: Char = 'C'\n    val unicodeChar: Char = '\\uFF00'\n//    Caracteres de escape:\n\n    /*\n    \\t: Tabulación\n    \\b: Retroceso\n    \\r: Retorno de carro\n    \\n: Salto de línea\n    \\': Apostrofe\n    \\\": Comillas doble\n    \\\\: Backslash\n    \\$: Símbolo de dólar\n     */\n\n    println(\"Hola $LANGUAGE\")\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/lisp/edalmava.lisp",
    "content": ";; La implementación usada es Steel Bank Common Lisp (SBCL)\n;; Sitio consultado: https://lisp-lang.org/\n;; IDE usado: https://portacle.github.io/\n\n;; Los comentarios de una línea empiezan por punto y coma ;\n;; y pueden comenzar en cualquier punto de la línea\n\n#|\nEste es un comentario\nde varias líneas.\nTodo lo que esté aquí será ignorado.\n|#\n\n;; Las variables léxicas locales se declaran con el operador especial let:\n(let ((x 5)(y 2)) (* x y))   ; 10\n; Usando definiciones anteriores\n(let* ((x 10)(y (+ x 5)))(* x y)) ; 150\n\n;; defparameter declara una variable global y la inicializa. Si ya existe, se vuelve a inicializar.\n(defparameter *mi-variable* 42) ; Variable global con valor 42\n;; defvar declara una variable global solo si no existe ya. Si existe, no cambia su valor.\n(defvar *otra-variable* 100) ; Declara si no está definida\n(defvar *otra-variable* 200) ; No cambia el valor existente\n\n;; Usa defconstant para definir una constante cuyo valor no debe cambiar.\n(defconstant +pi+ 3.14159)\n\n(format t \"¡Hola, Lisp!\")  ; Imprimir la cadena \"¡Hola, Lisp!\"\n(print \"¡Hola, Lisp usando SBCL!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/lua/ shadowSmen-cyber.lua",
    "content": "#https://lua.org/\n\n-- Este es un comentario de una línea\n\n--[[\nEste es un \ncomentario de\nvarias lineas\n]]\n\nLocal book = \"La vida y la muerte\", \"Libro de 100 años\"\nLocal book = \"Hidden\"\n\n--[[ \nPss, no se pueden crear contantes, pero encontre algunas soluciones\ncomo escribir el nombre de la varialbe en mayuscula\nTambién se pueden hacer metatablas, pero, aún no me atrevo, jeje\n]]\n\nLocal BOOK = 1000\n-- Los tipos de dato son 8 en total, y aqui van\n\n-- Este seria nil\nLocal page = 1\nLocal page = nil\n\n-- Este otro seria number\nLocal book = 1000\n\n-- El tercero seria string\nLocal book = \"Libro antiguo\"\n\n-- Este otro es boolean\nLocal book = true\n\n-- El de aca es una tabla\nLocal book = {\n  Paginas = 1000,\n  Lectores = 2\n  Nombres = {\"Yo\", \"EL\"}\n}\n\n--Aqui otro que serian las funciones\nLocal function addnumbers (a, b)\n  return a + b\nend\n\nLocal operation = addnumbers(20, 30)\nprint (operation)\n  \n  \n--El ultimo, seria el thread, ese no lo entendi, al parecer es como una funcion, pero para cosas mas especificas\n\nprint (\"Holaaa, Lua\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/lua/14DavidNKT.lua",
    "content": "-- www.lua.org\n\n-- Esto es un comentario en una linea\n\n--[[Esta es la\nmanera de hacer\nun comentario en varias\nlineas]]\n\n--[[En LUA solo existen variables, mas no constantes, y las mismas pueden ser de tipo globales o locales\nusadas dentro de funciones.]]\n\n-- TIPOS DE VALORES QUE PUEDEN USAR ALMACENAR LAS VARIABLES\n\na = nil -- Nulo, ausencia de valor\nb = true -- booleano, pueden ser true o false (verdadero o falso)\nc = 120 -- number (numericos)\nd = \"Cadena\" -- String o cadena de texto de hasta 8 bist\n\nlocal e = function(args)\n    print(\"Funcion: \", args)\nend\n\ne = {2,\"Hola\" , 4,5} -- tabla que almacena valores\n\nprint(\"¡Hola Lua!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/lua/Bert008.lua",
    "content": "--[[\n  EJERCICIO:\n  Crea un comentario en el código y coloca la URL del sitio web oficial del\n  lenguaje de programación que has seleccionado.\n  Representa las diferentes sintaxis que existen de crear comentariosen\n  en el lenguaje (en una línea, varias...).\n  Crea una variable (y una constante si el lenguaje lo soporta).\n  Crea variables representando todos los tipos de datos primitivos\n  del lenguaje (cadenas de texto, enteros, booleanos...).\n  Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n]]\n-- https://www.lua.org/\n-- Este es un comentario en Lua\n--[[\nY este es un comentario de varias lineas.\nEs importante no separar -- de [[ (siendo --[[ la syntaxis crrecta).\n]]\nvalor_nulo = nil\nentero = 10\nlocal entero_local = 10\ndecimal = 3.1416\nhex = 0xff\ncadena = \"Hola\"\ncadena_larga = [[\"Hola\nMundo\"]]\nbooleanos = true\nfunction hola()\n  print(\"Hola\")\nend\n\nhola()\n\nprint(\"Hola, Lua\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/lua/ElTitoJet.lua",
    "content": "-- https://www.lua.org/\n\n-- Esto es un comentario\n\n--[[Esto es un comentario\nMultilinea]]--\n\nlocal variableChula; -- Variable Local\n\nlocal variableTexto = \"Esto es un texto\"; \nlocal variableNumero = 1;\nlocal variableTabla = {};\nlocal variableTabla1 = {1, 2, 3, 4};\nlocal variabelTabla2 = {\"Pepe\", \"Manuela\", \"Federica\"};\nlocal variableBoolean = true;\n\nprint(\"Hola, soy \" ..variabelTabla2[1]..\" y esta es mi amiga \"..variabelTabla2[3])"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/lua/ansuzgs.lua",
    "content": "-- https://lua.org/\n\n-- Comentarios de una linea\n--[[\n--Comentarios multilinea\n--]]\n\ni = 10\n\n-- Lua no soporta las constantes\n\na = 10 -- todos los numeros son doble precision\nb = \"HOLA\"\nc = [[\"HOLA\"]]\nd = true\nlocal e = 10 --variable local\nlocal f = nil\nlocal g = function(args)\n  print(\"My print: \", args)\nend\nh = {} -- tabla\n\nprint(\"¡Hola, Lua!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/lua/bjchavez.lua",
    "content": "--[[\n  EJERCICIO:\n  Crea un comentario en el código y coloca la URL del sitio web oficial del\n  lenguaje de programación que has seleccionado.\n  Representa las diferentes sintaxis que existen de crear comentariosen\n  en el lenguaje (en una línea, varias...).\n  Crea una variable (y una constante si el lenguaje lo soporta).\n  Crea variables representando todos los tipos de datos primitivos\n  del lenguaje (cadenas de texto, enteros, booleanos...).\n  Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n--]]\n\n-- Lua Language: https://www.lua.org/\nlocal language = \"Lua\"\n\n-- Comentario de una sola linea\n\n--[[\nEste es un comentario de varias lineas\n--]]\n\n\n-- Lua no trabaja con CONSTANTES, en su lugar define el scope de las variables en locales y globales.\n\nlocal page_url = \"https://www.lua.org\"              -- string\nlocal number_one = 34                               -- number\nlocal data = { name = \"Hacker\", username = \"diabolico\", id = 666 }          -- table\nlocal deprecated = nil                              -- nil\nlocal programming = true                            -- boolean\nlocal get_data = function ()                        -- function\n  print(data.name .. \" \" .. data.username .. \" \" .. data.id)\nend\n\nprint(\"Hola, \" .. language .. \" es cool!!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/lua/edalmava.lua",
    "content": "-- Este es un comentario de una sola línea\n\n--[[\nEste es un comentario\nde múltiples líneas.\n]]\n\n-- Sitio oficial: https://www.lua.org/\n\n-- Lua es un lenguaje tipado dinámicamente.  Por defecto, todas las variables en Lua son globales.\n\n-- Declaración de variables\nlenguaje = \"Lua\"            -- variable global\nmensaje = \"¡Hola, \"         -- variable global\nlocal z                     -- Si no se asigna un valor inicial, el valor es nil\nlocal a, b, c = 1, 2, 3     -- Asignación múltiple\n\n-- Tipos básicos en Lua\n\nlocal sinValor = nil        -- Nil: Representa la ausencia de un valor. \nlocal esVerdadero = true    -- Booleano verdadero\nlocal esFalso = false       -- Booleano falso\nlocal entero = 42           -- Número entero\nlocal decimal = 3.14        -- Número decimal\nlocal saludo = \"Hola\"       -- Cadena con comillas dobles\nlocal mundo = 'Mundo'     -- Cadena con comilla sencilla\n-- Tipos tablas que pueden usarse para crear arrays, listas, diccionarios\nlocal tabla = {1, 2, 3, \"cuatro\", \"cinco\"}\nlocal diccionario = {nombre = \"Juan\", edad = 30}\n\n--[[\n    Las funciones se tratan como valores de primera clase, lo que significa que puedes \n    almacenarlas en variables, pasarlas como argumentos y retornarlas desde otras funciones.\n]]\nlocal function saludar()\n    return mensaje\nend\n\nprint(saludar() .. lenguaje .. \" :)!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/lua/elsanty08.lua",
    "content": "-- https://www.lua.org/\n\n-- Esto es un comentario en una linea\n\n--[[\nEsto es un comentario \nen varias lineas\n]]\n\nlocal miVariable = 34\n\n--[[ \n\nlua no soporta constantes, Pero los que están enfocados en Roblox studio \nusamos como constante con el metodo \"screaming snake case\" para crear algun elemento\nadentro del espacio de trabajo que no debe ser eliminado en ningun momento(nuestra constante) \n\n]]\n\n-- Variables de datos primitivos\n\nlocal variableNumerica = 4\nlocal variableString = \"Hola\"\nlocal variableBooleano = true or false\nlocal variableNulo = nil\n\nlocal texto = \"!Hola lua¡\"\n\nprint(texto)\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/lua/santyjL.lua",
    "content": "--[[\n#00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n]]\n\n-- https://www.lua.org/ pagina ofical de lua\n\n--[[\nEste comentario me permite\ndocumentar en varias lineas\n]]\n\nlocal nombre = \"Gonzalo\"\nlocal PI = 3.1415\n\n-- tipos de datos primitivos\n\nlocal texto = \"Lua\"\nlocal numero = 73\nlocal flotante = 73.12456897\nlocal boleano = false\n\nprint(\"\\n\\nHola \" .. texto .. \",esto es todo\\n\\n\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/maxmsp/bernatcs.maxpat",
    "content": "{\n\t\"boxes\" : [ \t\t{\n\t\t\t\"box\" : \t\t\t{\n\t\t\t\t\"maxclass\" : \"newobj\",\n\t\t\t\t\"text\" : \"print @popup 1\",\n\t\t\t\t\"numinlets\" : 1,\n\t\t\t\t\"fontname\" : \"Arial\",\n\t\t\t\t\"patching_rect\" : [ 40.0, 567.0, 102.0, 23.0 ],\n\t\t\t\t\"numoutlets\" : 0,\n\t\t\t\t\"id\" : \"obj-19\",\n\t\t\t\t\"fontsize\" : 13.0\n\t\t\t}\n\n\t\t}\n, \t\t{\n\t\t\t\"box\" : \t\t\t{\n\t\t\t\t\"maxclass\" : \"message\",\n\t\t\t\t\"text\" : \"¡Hola, MaxMSP!\",\n\t\t\t\t\"numinlets\" : 2,\n\t\t\t\t\"patching_rect\" : [ 40.0, 530.0, 96.0, 22.0 ],\n\t\t\t\t\"numoutlets\" : 1,\n\t\t\t\t\"outlettype\" : [ \"\" ],\n\t\t\t\t\"id\" : \"obj-30\"\n\t\t\t}\n\n\t\t}\n, \t\t{\n\t\t\t\"box\" : \t\t\t{\n\t\t\t\t\"maxclass\" : \"kslider\",\n\t\t\t\t\"numinlets\" : 2,\n\t\t\t\t\"patching_rect\" : [ 40.0, 408.0, 336.0, 53.0 ],\n\t\t\t\t\"numoutlets\" : 2,\n\t\t\t\t\"outlettype\" : [ \"int\", \"int\" ],\n\t\t\t\t\"id\" : \"obj-26\",\n\t\t\t\t\"parameter_enable\" : 0\n\t\t\t}\n\n\t\t}\n, \t\t{\n\t\t\t\"box\" : \t\t\t{\n\t\t\t\t\"maxclass\" : \"button\",\n\t\t\t\t\"numinlets\" : 1,\n\t\t\t\t\"patching_rect\" : [ 252.0, 368.0, 24.0, 24.0 ],\n\t\t\t\t\"numoutlets\" : 1,\n\t\t\t\t\"outlettype\" : [ \"bang\" ],\n\t\t\t\t\"id\" : \"obj-18\",\n\t\t\t\t\"parameter_enable\" : 0\n\t\t\t}\n\n\t\t}\n, \t\t{\n\t\t\t\"box\" : \t\t\t{\n\t\t\t\t\"maxclass\" : \"toggle\",\n\t\t\t\t\"numinlets\" : 1,\n\t\t\t\t\"patching_rect\" : [ 218.0, 368.0, 24.0, 24.0 ],\n\t\t\t\t\"numoutlets\" : 1,\n\t\t\t\t\"outlettype\" : [ \"int\" ],\n\t\t\t\t\"id\" : \"obj-16\",\n\t\t\t\t\"parameter_enable\" : 0\n\t\t\t}\n\n\t\t}\n, \t\t{\n\t\t\t\"box\" : \t\t\t{\n\t\t\t\t\"maxclass\" : \"message\",\n\t\t\t\t\"numinlets\" : 2,\n\t\t\t\t\"patching_rect\" : [ 156.5, 369.0, 50.0, 22.0 ],\n\t\t\t\t\"numoutlets\" : 1,\n\t\t\t\t\"outlettype\" : [ \"\" ],\n\t\t\t\t\"id\" : \"obj-14\"\n\t\t\t}\n\n\t\t}\n, \t\t{\n\t\t\t\"box\" : \t\t\t{\n\t\t\t\t\"maxclass\" : \"flonum\",\n\t\t\t\t\"numinlets\" : 1,\n\t\t\t\t\"patching_rect\" : [ 99.0, 369.0, 50.0, 22.0 ],\n\t\t\t\t\"numoutlets\" : 2,\n\t\t\t\t\"format\" : 6,\n\t\t\t\t\"outlettype\" : [ \"\", \"bang\" ],\n\t\t\t\t\"id\" : \"obj-12\",\n\t\t\t\t\"parameter_enable\" : 0\n\t\t\t}\n\n\t\t}\n, \t\t{\n\t\t\t\"box\" : \t\t\t{\n\t\t\t\t\"maxclass\" : \"number\",\n\t\t\t\t\"numinlets\" : 1,\n\t\t\t\t\"patching_rect\" : [ 40.0, 369.0, 50.0, 22.0 ],\n\t\t\t\t\"numoutlets\" : 2,\n\t\t\t\t\"outlettype\" : [ \"\", \"bang\" ],\n\t\t\t\t\"id\" : \"obj-10\",\n\t\t\t\t\"parameter_enable\" : 0\n\t\t\t}\n\n\t\t}\n, \t\t{\n\t\t\t\"box\" : \t\t\t{\n\t\t\t\t\"maxclass\" : \"comment\",\n\t\t\t\t\"text\" : \"Estos son los objetos habituales:\",\n\t\t\t\t\"numinlets\" : 1,\n\t\t\t\t\"patching_rect\" : [ 40.0, 327.0, 283.0, 20.0 ],\n\t\t\t\t\"numoutlets\" : 0,\n\t\t\t\t\"id\" : \"obj-8\"\n\t\t\t}\n\n\t\t}\n, \t\t{\n\t\t\t\"box\" : \t\t\t{\n\t\t\t\t\"maxclass\" : \"message\",\n\t\t\t\t\"text\" : \"No existen las Variables en Max. En cambio puedes utilizar diferentes elementos [como este] para asignarle valores cambiantes\",\n\t\t\t\t\"numinlets\" : 2,\n\t\t\t\t\"patching_rect\" : [ 40.0, 210.0, 689.0, 22.0 ],\n\t\t\t\t\"numoutlets\" : 1,\n\t\t\t\t\"outlettype\" : [ \"\" ],\n\t\t\t\t\"id\" : \"obj-6\"\n\t\t\t}\n\n\t\t}\n, \t\t{\n\t\t\t\"box\" : \t\t\t{\n\t\t\t\t\"maxclass\" : \"comment\",\n\t\t\t\t\"text\" : \"Esto es un comentario y ya está\",\n\t\t\t\t\"presentation_linecount\" : 2,\n\t\t\t\t\"numinlets\" : 1,\n\t\t\t\t\"patching_rect\" : [ 40.0, 136.0, 304.0, 20.0 ],\n\t\t\t\t\"numoutlets\" : 0,\n\t\t\t\t\"id\" : \"obj-3\"\n\t\t\t}\n\n\t\t}\n, \t\t{\n\t\t\t\"box\" : \t\t\t{\n\t\t\t\t\"maxclass\" : \"comment\",\n\t\t\t\t\"text\" : \"https://cycling74.com/\",\n\t\t\t\t\"numinlets\" : 1,\n\t\t\t\t\"patching_rect\" : [ 40.0, 81.0, 150.0, 20.0 ],\n\t\t\t\t\"numoutlets\" : 0,\n\t\t\t\t\"id\" : \"obj-2\"\n\t\t\t}\n\n\t\t}\n ],\n\t\"lines\" : [ \t\t{\n\t\t\t\"patchline\" : \t\t\t{\n\t\t\t\t\"source\" : [ \"obj-30\", 0 ],\n\t\t\t\t\"destination\" : [ \"obj-19\", 0 ]\n\t\t\t}\n\n\t\t}\n ],\n\t\"appversion\" : \t{\n\t\t\"major\" : 8,\n\t\t\"minor\" : 6,\n\t\t\"revision\" : 2,\n\t\t\"architecture\" : \"x64\",\n\t\t\"modernui\" : 1\n\t}\n,\n\t\"classnamespace\" : \"box\"\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/mojo/angelsanchezt.mojo",
    "content": "# URL del sitio web oficial de Mojo 🔥: https://modular.com/max/mojo\n# Documentación inicial 🔥: https://docs.modular.com/\n# Inicio Rapido de Mojo 🔥: https://docs.modular.com/mojo/manual/get-started/\n# Comentario en una línea\n\n\"\"\"\nComentario \nde\nvarias\nlíneas\n\"\"\"\nfn main():\n\n    var firts_name = \"Sam\"  # Mutable\n    var last_name: String = \"Smith\" # Mutable\n    var gender = String(\"Male\") # Mutable\n    let user_id = 42  # Immutable\n\n    # Ejemplo Variable Mutable\n    var x: Int = 100\n    print(x)\n    x += 10\n    print(x)\n\n    print(\"Hello, Mojo 🔥!\")\n\n    print(firts_name);\n    print(last_name);\n    print(gender);\n    print(user_id);\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/mql4/confley.mq4",
    "content": "// https://docs.mql4.com/\n\n// Comentario de una sola línea \n\n/*  Está es la menra \n    de escribir un comentario\n    de varias líneas \n*/ \n\n\n\n#define MY_CONSTANT \"hola\"; \n\nstring miVariable = \"Variable tipo tetxo\"; // Variable global\n// string miVariable = \"Nuevo valor\"; //! error \n\n\n\nvoid OnStart() {\n    miVariable = \"Cambiando el valor de la variable\";\n    \n    int     my_int      = 0; \n    double  my_double   = 1.1; \n    bool    my_bool     = false; // true\n    string  my_string   = \"Cadena de texto\"; \n    color   my_clr      = clrRed;           // Uso de colores predefinidos (web colors)\n    color   my_customColor = C'255,0,0';    // Definición personalizada de un color (rojo)\n    datetime my_datetime = D'2014.03.05 15:46:58'; \n    \n    Print(\"¡Hola, mql4!\");\n}\n\n\n\n//* OBSERVACIONES \n// - Para cambiar el valor de una variable global tiene que ser dentro de un método, fuera no es posible.\n// - Print() no puede ser ejecutado fuera de un método \n// - Las constantes no se pueden imprimir ( Print(MY_CONSTANT) ) directamente. \n// - Hay muchas formas de especificar una fecha ( https://docs.mql4.com/basis/types/integer/datetime ). \n//?- Para programar MQL4 con VScode ( https://www.youtube.com/watch?v=WMe7ihFempE ). "
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/nasm/evanz2608.s",
    "content": ";\thttps://www.nasm.us/\n\n; IMPORTANTE\n; =============================================================================================\n; Aclarar que NASM es uno de los ensambladores que existen y no el lenguaje en si,\n; aunque cada ensamblador define una sintaxis, en ensamblador las instrucciones son las mismas,\n; y solo cambian cosas que no son especificas del lenguaje ensamblador en si.\n;\n; La sintaxis que se usa es la de Intel, y se escribe codigo para 64 bits en Linux.\n; =============================================================================================\n\n\n\n\n\n\n; Los comentarios inician con punto y coma.\n\n%if 0\n\tNo existen comentarios multilinea como tal, pero se pueden usar macros como esta\n\tque el ensamblador ignorará a la hora de procesar el archivo porque al evaluar la macro\n\t0 es false, y por lo tanto esto no se incluirá, al igual que un comentario\n%endif ;0\n\n\nsection .data\n\t; las \"variables\" en ensablador son simples porciones de memoria que reservamos para su uso\n\t; no tienen tipo, y van dentro de la seccion .data\n\n\tmi_variable: db 0\t\t\t\t\t\t\t\t\t\t; mi_variable reserva 1 byte inicializado a 0.\n\tmi_segunda_variable: dw 0\t\t\t\t\t\t; aquí reservamos 2 bytes, lo que se llama word, también inicializado a 0\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t; Se puede usar dq para reservar 4 bytes, y dq para reservar 8 bytes.\n\n\tmi_array: db 0, 1, 2, 3, 4\t\t\t\t\t; Puesto que las variables son porciones de memoria, podemos definir arrays separando cada valor con una coma.\n\n\tmi_segundo_array: times 20 dw 0\t\t\t; Reservamos 20 words, lo que serían 40 bytes y los inicializamos a 0.\n\n\tmi_string: db \"Cadena de texto\"\t\t\t; Se pueden inicializar variables con cadenas de texto y el tamaño sería igual a la cantidad de caracteres\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t; que contenga la cadena, y cada caracter será tratado como un byte. \n\n\nsection .rodata\n\tmi_constante: equ 10\t\t\t\t\t\t\t\t; Para las \"constantes\" usamos la seccion .rodata (read only data) y usamos EQU para definirles un valor.\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t; Decir que las constantes son meros nombres para el valor que definamos.\n\n\thello: db \"Hola, NASM!\", 0x0A\t\t\t\t; para imprimir por consola el texto. (0x0A es el caracter para salto de línea. En otros lenguajes se puede denotar como '\\n')\n\thello_len: equ $-hello\t\t\t\t\t\t\t; calculamos el largo del texto a imprimir.\n\n\n\nsection .text\t\t\t\t\t; la seccion donde ira nuestro codigo.\nglobal _start\t\t\t\t\t; declaramos el punto de entrada de nuesto programa. Similar a la funcion main de algunos lenguajes.\n\n_start:\t\t\t\t\t\t\t\t; y aquí la implementamos\n\t; Imprimimos por pantalla el texto \"Hola mundo\"\n\tmov rax, 1\n\tmov rdi, 1\n\tlea rsi, [hello]\n\tmov rdx, hello_len\n\tsyscall\n\n\t; y salimos de nuestro programa.\n\tmov rax, 60\n\tmov rdi, 0\n\tsyscall\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/objectivec/armm77.m",
    "content": "// armm77 ver. 0.1\n\n// - Crea un comentario en el código y coloca la URL del sitio web oficial del\n//   lenguaje de programación que has seleccionado.\n\n// Documentacion oficial Apple\n// https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ObjectiveC/Introduction/introObjectiveC.html\n\n// Documentacion Alternativa GNUStep\n// https://gnustep.github.io/developers/documentation.html\n\n// - Representa las diferentes sintaxis que existen de crear comentarios\n//   en el lenguaje (en una línea, varias...).\n \n// 1. Comentario de una sola linea, se utiliza.\n/*\n   2. Comentario de varias lineas,\n      seccion de codigo o documentacion.\n */\n\n// - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\n#import <Foundation/Foundation.h>\n\nint main(int argc, const char * argv[]) {\n\n// - Crea una variable (y una constante si el lenguaje lo soporta).\n    int weight = 0; // Variable\n    const int  LENGTH = 10; // Constante\n    const char NEWLINE = '\\n'; // Constante\n    const float PI = 3.1415926535; // Constante\n    const double WIDTH = 47.120577; // Constante\n\n/*\n   - Crea variables representando todos los tipos de datos primitivos\n     del lenguaje (cadenas de texto, enteros, booleanos...).\n \n     Al ser Objective-C una variantes del lenguaje C con clases al estilo de\n     Smalltalk, hereda los tipos de datos del mismo C.\n*/\n    int i = 1; // valor entero\n    char c = 'c'; // valor caracter\n    float f = 1.11111111; // valor decimal\n    double d = 12.2222222; // valor decimal\n    BOOL Y = YES; // valor boleano\n    BOOL N = NO; // valor boleano\n\n    @autoreleasepool {\n        NSLog(@\"Hola, Mundo!\");\n        NSLog(@\"Variable: %d\", weight);\n        NSLog(@\"Valores costantes: %d, %f, %f\",LENGTH,PI,WIDTH);\n        NSLog(@\"Salto de linea %c\",NEWLINE);\n        printf(\"Valor entero: %d \\n\", i);\n        printf(\"Valor caracter: %c \\n\", c);\n        printf(\"Valor decimal: %f \\n\", f);\n        printf(\"Valor decimal: %f \\n\", d);\n        NSLog(@\"Valor boleano: %d\", Y);\n        NSLog(@\"Valor boleano: %d\", N);\n    }\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/ocaml/luishendrix92.ml",
    "content": "(******************************************************************************\n * OCaml | An industrial-strength functional programming                      *\n *       | language with an emphasis on expressiveness and safety.            *\n * -------------------------------------------------------------------------- *\n * Official Website: https://ocaml.org/                                       *\n *****************************************************************************)\n\n(* Single line comment *)\n(* Multi\n   Line\n   Comment *)\n\n(* Top level let binding, can be re-assigned but not written. *)\nlet my_name = \"luishendrix92\"\n\n(* Local bindings that are visible in their current scope\n   and anything that is within it, but not to the outside *)\nlet my_function =\n  let x = 5 in\n  let y = x + 10 in\n  if x + y = 20\n  then x * y\n  else (\n    let z = x - y in\n    z / 10)\n;;\n\n(* References: These are mutable variables but limited to the type you\n   express at compile type. They can be re-assigned with [:=] and\n   de-referenced with [!] which reads the value contained in it. *)\nlet counter : int ref = ref 0;;\n\n(* Replaces 0 with 10 *)\ncounter := 10;\n(* Replaces 0 with 11 *)\ncounter := !counter + 1;\n(* Prints \"11\" *)\nprint_int !counter\n\n(* Primitive data types\n   -------------------- *)\n\nlet str = \"Here is a string\\nJust like any other language.\"\nlet ch = 'A'\nlet integer = 10 + 3 + int_of_float 3.14\nlet floating = 0.5 +. 5. -. float_of_int 1\nlet answer = (true && false) || true\nlet unit = ()\n\n(* Built-in container data types\n   ----------------------------- *)\n\n(* A tuple of two ints. Tuples can have more than 2 elements. *)\nlet point = 4, 7;;\n\nmatch point with\n| x, y -> Printf.printf \"\\nP(%d, %d)\" x y\n\n(* Immutable singly-linked lists. *)\nlet my_list = true :: [ true; false; false; true; true ]\n\n(* Mutable index-based arrays. *)\nlet my_array = [| 'A', 'B', 'C', 'D' |]\n\n(* Ocaml has built-in support for optional types. It also has Result, and\n   many others but you'll find yourself using this one more. *)\nlet option =\n  match Some 42 with\n  | Some x -> \"The answer to everything is \" ^ string_of_int x\n  | None -> \"There is no answer to anything...\"\n;;\n\n(* Building custom exceptions and handling them is simple. *)\nlet ex =\n  try raise (Failure \"Something went wrong\") with\n  | Failure _ -> print_endline \"\\nBoom!\"\n;;\n\n(* Functions are first-class citizens, as expected of a functional language. *)\nlet list_product = List.fold_left (fun acc x -> acc * x) 1\nlet add a b = a + b\nlet apply_twice f v = f v |> f\n\n(* Records, Variants, Polymorphic Variants, and Modules\n   These can be thought of as user-defined types!\n   ---------------------------------------------------- *)\n\nmodule R3Vector : sig\n  type t\n\n  val of_tuple : float * float * float -> t\n  val dot_product : t -> t -> float\nend = struct\n  (* Records can have mutable fields by marking them with the [mutable]\n     keyword before its name. Assignment is done with the [<-] operator\n     and dereferencing is the same as with immutable fields using the\n     [rec.field] dot syntax. For more information, refer to:\n     https://cs3110.github.io/textbook/chapters/mut/mutable_fields.html *)\n  type t =\n    { i : float\n    ; j : float\n    ; k : float\n    }\n\n  let of_tuple (i, j, k) = { i; j; k }\n  let dot_product a b = (a.i *. b.i) +. (a.j *. b.j) +. (a.k *. b.k)\nend\n\nlet result =\n  let open R3Vector in\n  let v1 = of_tuple (1.5, 0.2, 2.1) in\n  let v2 = of_tuple (0., 1., 3.8) in\n  dot_product v1 v2\n;;\n\n(* Nullary variant type, no type parameters *)\ntype shape =\n  | Rectangle of (float * float)\n  | Circle of float\n\nlet area s =\n  match s with\n  | Rectangle (a, b) -> a *. b\n  | Circle radius -> Float.pi *. radius *. radius\n;;\n\n(* Polymorphic variant type, analogous to generics in OOP *)\ntype 'a maybe =\n  | Just of 'a\n  | Nothing\n\nlet maybe_a_string = Just \"do it\"\nlet maybe_an_int = Nothing\nlet maybe_a_maybe = Just (Just 9999)\n\n(* According to the official documentation, OCaml has objects and classes but\n   I have never seen it used. I don't doubt people use it but it may be a rare\n   sight. Since I don't know how it's done I'll just copy and paste the\n   example from the doc site: https://ocaml.org/docs/objects. *)\nclass ['a] stack =\n  object (self)\n    val mutable list : 'a list = [] (* instance variable *)\n\n    method push x = (* push method *)\n                    list <- x :: list\n\n    method pop =\n      (* pop method *)\n      let result = List.hd list in\n      list <- List.tl list;\n      result\n\n    method peek = (* peek method *)\n                  List.hd list\n\n    method size = (* size method *)\n                  List.length list\n  end\n\nlet s = new stack;;\n\ns#push 1.0 (* Method call *)\n\n(* Printing Hello World\n   -------------------- *)\nlet () = print_endline \"Hello World from OCaml\"\n\n(** ODoc's documentation code block. At the very top level, this comment will\n    document the entire module which corresponds to this [.ml] file.\n    These comments allow special syntax which can be found at ODoc's official\n    website https://ocaml.github.io/odoc/odoc_for_authors.html. Here are some\n    examples of the things that can be expressed:\n\n    Syntax for {b bold}, {i italic}, {e emphasis}, {^ super}, {_ under}.\n\n    - there are\n    - unoredered\n    - lists\n\n    + and of course\n    + ordered\n    + lists\n\n    Code blocks for any language, useful to demo your functions:\n    {[let sum_list = List.fold_left ( + ) 0\n\n      sum_list [5; 3; -8; 4] = 4]}\n\n    @author luishendrix92\n    @since 1.5\n\n    NOTE: This comment was attached to a dummy variable so you can read it\n    using your IDE's autocomplete or LSP hover functionality. *)\nlet read_me = () (* Unit type *)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/pascal/edalmava.pas",
    "content": "(* Este es un comentario *)\n{ Este es otro comentario }\n\n{ Sitio de FreePascal: https://www.freepascal.org/ }\n\n{ Los programas en Pascal siguen una estructura }\n\nprogram Inicio;\nuses Crt;\n\n{ Definicion de constantes (const) }\nconst\n    NumAlumnos = 10;\n    Cadena = 'Hola, Pascal!';\n\n{ Definicion de tipos (type) }\ntype\n    DiasSemana = (Domingo, Lunes, Martes, Miercoles, Jueves, Viernes, Sabado); { Tipos enumerados }\n    Digitos = 1..NumAlumnos;   { Tipos subrango (intervalo) }\n    { Tipo registro }\n    Estudiante = record\n        Nombre : String[30];\n        Edad   : Integer;\n        Curso  : Integer\n    end;\n\n{ Declaracion de variables (var) }\nvar\n    { Valores enteros (Integer) }\n    a : Byte = 0;\n    b : ShortInt = -128;\n    c : Integer = -32768;\n    d : Word = 65535;\n    e : LongInt = 2147483647;\n\n    { Valores Reales }\n    r : Real = 1.7E38;\n    s : Single = 3.4E38;\n    de : Double = 1.7E100;\n    ed : Extended = 1.1E400;\n\n    { Valores logicos (Boolean) }\n    falso : Boolean = false;\n    verdadero : Boolean = true;\n\n    { Tipo Caracter (Char) }\n    car : Char = 'A';\n\n    { Cadenas de caracteres }\n    cadena2 : String = 'Cadena en Pascal';\n\n{ Declaracion de procedimientos y funciones }\n\n{ Cuerpo principal del programa }\nbegin\n    ClrScr; { Procedimiento de la unidad Crt que borra la pantalla completa o la ventana actual }\n\n    WriteLn(Cadena) { Enviar valores a la pantalla anadiendo caracteres de control de retorno de carro y avance de linea }\nend.\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/pascal/implevacui.pas",
    "content": "program implevacui;\r\n\r\n//Aquí esta la url del sitio web oficial de Pascal  https://www.freepascal.org/\r\n\r\n(*Añado tambien un comentario\r\nmultilinea*)\r\n\r\n{Aqui va otro comentario\r\nmultilinea}\r\n\r\n\r\nConst\r\n  pi=3.1416;\r\n\r\nvar\r\n  cadena: string;\r\n  caracter: char;\r\n  opcion: boolean;\r\n\r\n  enterocorto: shortint; //-128...127\r\n  entero8bits: byte; //0...255\r\n  entero16bits: integer; //-32768...32767\r\n  entero32bits: longint; //-2.147.483.648...2.147.483.647\r\n  enteropositivo: word;  //0...65535\r\n  decimal: real;\r\n\r\n\r\nbegin\r\n   writeln('Hola! Aprendiendo con Pascal');\r\n   readln;\r\nend.                  "
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/pascal/miguelex.pas",
    "content": "Program miguelex;\n\n{ Documentación en https://www.freepascal.org/docs.html }\n\nconst\n  PI = 3.14156;\n\nvar\n  radio : Integer;\n\n{ Tipos primitivos en Pascal }\nvar \n  entero : Integer;\nvar \n  decimal : Real;\nvar \n  cadena : String;\nvar \n  booleano : Boolean;\n\nbegin\n  {* Comentario *}\n  { Otro tipo de comentario }\n \n  { Mostrar por consola }\n  cadena := 'Pascal';\n  writeln('Hola ' + cadena + '!');\n  readln;\nend.\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/perl/edalmava.pl",
    "content": "use Modern::Perl '2015';\nuse autodie;\n\n#  Comentario en perl\n#  Sitio oficial: https://www.perl.org/\n#  En Perl las variables tienen un símbolo que indica el tipo del valor de la variable\n\n#  Variables Escalares (Usan el signo de dólar $)\nmy $escalares;\n\n#  Variables de Matriz - Arreglos (usan el signo at @)\nmy @arreglo;\n\n#  Variables Hash (usan el signo de porcentaje %)\nmy %hash;\n\n#  Strings \nmy $perl_language = \"Perl\";\n\n#  Números\nmy $integer   = 42;\nmy $float     = 0.007;\nmy $sci_float = 1.02e14;\nmy $binary    = 0b101010;\nmy $octal     = 052;\nmy $hex       = 0x20;\n\nprint \"¡Hola, \", $perl_language, \"!\\n\";\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/Abel-ADE.php",
    "content": "<?php\n\n// Página Web Oficial: https://www.php.net/manual/es/index.php\n\n//Tipos de comentarios en PHP:\n\n    // Comentario de una sola línea\n    # Otro Comentario de una línea\n    /*  Comentario \n        multilínea \n    */\n\n    /**\n     * Comentario multilínea \n     * que se utiliza \n     * para generar documentación del programa\n     */\n\n//Declaración y asignación de variables\n$variableCamelCase = 'Hola, Mundo!';\n\n//Declaración y asignación de constantes\nconst MI_CONSTANTE = 12; //Se define en tiempo de compilación\ndefine('OTRA_CONSTANTE', 50); //Se define en tiempo de ejecución\n\n//Mostrar el contenido\nprint $variableCamelCase;\nprint MI_CONSTANTE;\nprint OTRA_CONSTANTE;\n\n//Tipos de datos primitivos en PHP\n$miEntero = 100;\n$miDecimal = 20.50;\n$miBooleano = true;\n$miTexto = 'Soy un texto';\n$miNulo = null;\n\n//Imprime por terminal el texto: 'Hola, PHP!'\nprint 'Hola, PHP!';\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/BertoMP.php",
    "content": "<?php\n// WEB OFICIAL\n// Sitio web oficial de PHP: https://www.php.net/\n\n// COMENTARIOS\n// En PHP tenemos 3 tipos de comentarios:\n\n// - Comentarios de una sola línea (// Comentario): Se utilizan para explicar partes concretas del código.\n// Esto es un comentario de una línea.\n\n// - Comentarios de varias líneas (/* Comentario */): Estos comentarios permiten explicar bloques extensos de código.\n/*\n * Esto es un ejemplo de\n * un comentario\n * de varias líneas. */\n\n// - Comentarios de documentación (/** Comentario */): Sirven para generar documentación.\n/**\n * Este tipo de comentarios son los que usaremos cuando queramos\n * explicar el funcionamiento de, por ejemplo, una función\n * o una clase de PHP.\n * Generan documentación de forma automática, también llamada\n * PHPDoc y suelen ir acompañados de etiquetas que mejoran\n * su comprensión:\n * - @param: Nos sirve para determinar el tipo de variable que\n *           recibe la función.\n * - @return: En este caso lo que nos informará del tipo de\n *            retorno o resultado que produce la función. */\n\n// VARIABLES Y CONSTANTES\n/* - Variables: Para declarar una variable en PHP utilizamos\n                el nombre que le queramos dar a la variable\n                precedido por el símbolo del dólar ($).\n                Podemos dejar una variable sin inicializar o\n                darle el valor null. */\n$miVariable = 12;\n$miVariableSinInicializar = null;\n\n/* - Constantes: En PHP tenemos dos formas de declarar una constante,\n                 la primera de ellas es la palabra const seguido del\n                 nombre de nuestra constante y su valor.\n                 También las podemos declarar con el método define(),\n                 que recibe 2 parámetros: un string con el nombre de la\n                 constante y un valor.\n                 Por convención, las constantes deben declararse con mayúsculas. */\nconst MI_CONSTANTE = 33;\ndefine('MI_OTRA_CONSTANTE', 40);\n\n// DATOS PRIMITIVOS\n// En PHP tenemos los siguientes tipos de datos primitivos:\n$miInteger = 12; // Integer: Almacena números enteros.\n$miFloat = 12.64; // Float: Almacena números con decimales.\n$miBoolean = true; // Boolean: Sirve para valores lógicos (true o false).\n$miNull = null; // Null: Almacena un dato nulo -sin valor-.\n$miString = 'Esto es una cadena'; // String: Sirve para cadenas de texto o caracteres únicos.\n$miArray = array('a', 'b', 'c'); // Array: Sirve para almacenar varios datos en un mismo lugar.\n\n// IMPRESIÓN\necho '¡Hola, PHP!';"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/BrunoM-93.php",
    "content": "<?php\n# -SITIO WEB OFICIAL- \n  // PHP: Hypertext Preprocessor - https://www.php.net/\n\n\n# -COMENTARIOS-\n\n  //Esto es un comentario de una sola línea\n  #Esto tambien es un comentario de una sola línea\n\n  /*\n  Esto es\n  un comentario\n  de varias\n  líneas\n  */\n\n  /**\n     * Los DocBlocks en PHP son comentarios de documentación especialmente formateados que se utilizan\n     * para describir elementos del código, como funciones, clases, métodos, propiedades, y otros.\n     * Estos comentarios están diseñados para ser interpretados por herramientas externas que generan documentación automáticamente,\n     * como PHPDocumentor o Doxygen.\n     *\n     * @param string $nombre Nombre de la persona\n     * @param int $edad Edad de la persona\n     * @return string Saludo personalizado\n  */\n    function saludar($nombre, $edad) {\n        // Implementación de la función\n    }\n\n# -VARIABLES-\n\n  /* En PHP las variables se declaran con un signo de dólar seguido\n     por el nombre de la variable, es sensible a minúsculas y mayúsculas.\n     Un nombre de variable válido tiene que empezar con una letra o un\n     carácter de subrayado (underscore), seguido de cualquier número de\n     letras, números y caracteres de subrayado.\n  */\n  \n  $nombre_variable = \"valor de la variable\";\n\n# -CONSTANTES-\n\n  /* Usamos constantes cuando necesitamos que el valor que almacenamos\n     no se modifique aunque cometamos un error. Es decir, necesitamos\n     que el valor almacenado permanezca idéntico, constante.\n     A diferencia de las variables, es imposible definirles un valor\n     mediante un operador de asignación (el signo igual), lo que facilita\n     que “ni por error” alteremos su valor durante toda su vida útil,\n     ya que siempre almacenarán el mismo valor.\n  */\n  \n  // Hay dos formas de definir una constante en PHP\n    const nom_const = \"valor de la constante\";\n    define('nom_const2', \"valor de la constate\");\n\n# -TIPOS DE DATOS PRIMITIVOS-\n\n  /* PHP soporta varios tipos de datos primitivos entre ellos:\n      *Escalares\n          -boleanos (boolean)\n          -enteros (integer)\n          -punto flotante (float)\n          -cadena (string)\n      *Compuestos:\n          -arreglos (array)\n          -objetos (object)\n      *Especiales:\n          -null\n  */\n  \n  $boolean = True; //o False\n  $interger = 4; //Numeros entero\n  $float = 4.5; //Numeros con coma decimal\n  $string = \"Hola Mundo!\"; //Cadenas de caracteres con comillas dobles\n  $string2 = 'Hola Mundo!'; //Cadenas de caracteres con comillas simples\n  \n  $array = array(1, 2, 3, 4); //Almacena varios datos en un mismo espacio de memoria.\n  \n  //Declaracion de una clase\n  class Objeto {\n      // Declaración de una propiedad\n      public $nombre = 'un valor predeterminado';\n      public $tipo = 'un valor';\n  }\n  \n  //Creacion de un objeto de la clase previamente declarada\n  $objeto = new Objeto();\n  \n  $var = null; //El tipo de dato especial NULL representa una variable sin valor.\n\n# -IMPRESION POR TERMINAL-\n  \n  $lenguaje = 'PHP';\n\n  // echo\n  echo \"¡Hola \".$lenguaje.\"!\\n\"; // Salida: ¡Hola PHP!\n\n  // print\n  print \"¡Hola \".$lenguaje.\"!\\n\"; // Salida: ¡Hola PHP!\n\n  // printf (formateo)\n  printf(\"¡Hola %s!\\n\", $lenguaje); // Salida: ¡Hola PHP!\n\n  // sprintf (parecido a printf, pero devuelve en una variable la cadena formateada)\n  $cadena_formateada = sprintf(\"¡Hola %s!\\n\", $lenguaje);\n  echo $cadena_formateada; // Salida: ¡Hola PHP!\n\n?>"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/Bryan112094.php",
    "content": "<?php\n//PAGINA WEB OFICIAL\n//https://www.php.net/\n\n//COMENTARIOS\n// -> dos / es comentario de una línea\n/*\n    Asi se ve\n    los comentarios\n    multilíneas\n*/\n# comentraio de una sola linea estilo consola\n\n//VARIABLES\n$variable01 = 2; // La variable toma el tipo del dato que se declara\n\n//DATOS PRIMITIVOS\n// Booleano\n$bool = true;\n// Cadena\n$texto = \"hola\";\n// Integer\n$numero = 2;\n// Float\n$decimal = 120.2;\n// Matriz\n$matriz01 = array(\"uno\", \"dos\", \"tres\");\n$matriz02 = [\"uno\", \"dos\", \"tres\"];\n$matriz03 = [\"Nombre\" => \"Bryan\", \"Apellidos\" => \"Guevara Ascoy\"];\n// Null\n$nulo = null;\n\n//IMPRIMIR\necho \"Hola, PHP\";"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/CeciliaPorras01.php",
    "content": "<?php  \n\n\n//https://www.php.net/docs.php\n\n//Comentario en una linea\n\n/***\n Comentarios en varias lineas\n**/\n\n/*Otro tipo de comentario\nen php */\n\n$my_variable = 0;\n\nconst MY_CONSTANT = 5;\nprint 'Constante:' . MY_CONSTANT . \"\\n\";\nprint 'Variable:' . $my_variable = 9;\n\n//Tipos de datos\n$my_integer = 1;\n$my_float = 1.5;\n$my_boolean = true;\n$my_boolean = false;\n$my_string = 'Hola Mundo :)';\n$my_string2 = \"Hola Mundo 2 :p\";\n\nprint gettype($my_integer). \"\\n\";\nprint gettype($my_float ). \"\\n\";\nprint gettype($my_boolean). \"\\n\";\nprint gettype($my_string). \"\\n\";\n\n\n//Operadores\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/DanielBelenguer.php",
    "content": "<?php \n/*\n* ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n* - Recuerda que todas las instrucciones de participación están en el\n*   repositorio de GitHub.\n*\n* Lo primero... ¿Ya has elegido un lenguaje?\n* - No todos son iguales, pero sus fundamentos suelen ser comunes.\n* - Este primer reto te servirá para familiarizarte con la forma de participar\n*   enviando tus propias soluciones.\n*\n* EJERCICIO:\n* - Crea un comentario en el código y coloca la URL del sitio web oficial del\n*   lenguaje de programación que has seleccionado.\n* - Representa las diferentes sintaxis que existen de crear comentarios\n*   en el lenguaje (en una línea, varias...).\n* - Crea una variable (y una constante si el lenguaje lo soporta).\n* - Crea variables representando todos los tipos de datos primitivos\n*   del lenguaje (cadenas de texto, enteros, booleanos...).\n* - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n*\n* ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n* debemos comenzar por el principio.\n*/\n\n// https://www.php.net/ Web official de lenguaje de programación PHP\n\n// Esto es un comentario de una sola línea en PHP\n\n/*\n* Esto es\n* un comentario\n* de varias líneas\n*/\n\n// Creación de una variables\n$num1 = 5;\n$nombre = \"Daniel Belenguer\";\n$numero_real = 5.5;\n$var_boolean = true;\n// Creación de una constante\ndefine('PI', 3.14159);\n\necho \"Hola, PHP!\";\n?>"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/Edm1ya.php",
    "content": "<?php\n/*\n* EJERCICIO:\n* - Crea un comentario en el código y coloca la URL del sitio web oficial del\n* lenguaje de programación que has seleccionado.\n* - Representa las diferentes sintaxis que existen de crear comentarios\n* en el lenguaje (en una línea, varias...).\n* - Crea una variable (y una constante si el lenguaje lo soporta).\n* - Crea variables representando todos los tipos de datos primitivos\n* del lenguaje (cadenas de texto, enteros, booleanos...).\n* - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n*\n* ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n* debemos comenzar por el principio.\n*/\n\n\n/*\nPagina web oficial de PHP\nhttps://www.php.net/\n*/\n\n// Comentario en una sola linea\n\n/*\ncomentario en\nvarias lineas\n*/\n\n\n// variable\n$variable = \"esta es una variable\";\n\n// contantes\ndefine('CONSTANTE', \"Esto es una constante antigua\");\nconst CONSTANTE2 = \"esto es una constante nueva\";\n\n\n// tipos de variables\n$numeroEntero = 10;\n$numeroDecimal =  13.5;\n$texto = \"Esto es un string\";\n$texto2 = 'esto es un string ccon comillas simples';\n$boolean = true;\n$nulo = null;\n\n\necho \"Hola!. PHP\";\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/Franckdot.php",
    "content": "<?php\n    //https://www.php.net/\n    //Esto es un solo comentario para lineas de codigo individuales\n    /* Este es un comentario \n    para usar en varias lineas de codigo */\n\n    //variable\n    $myFirstVariable = \"PHP\";\n    //constante\n    define(\"PI\", 3.14);\n\n    //tipos de datos\n    //entero\n    $valorEntero = 3;\n    //float\n    $valorPi = 3.14;\n    //cadena\n    $valorCadena = \"Cadena\"; \n    //boleano\n    $valorBooleano = true;\n    $valorBooleano1 = false;\n    //null (indica que no hay valor)\n    $valorVacio = null;\n\n    echo 'Hola, ',$myFirstVariable;\n\n?>"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/GitHjuan.php",
    "content": "\n\n\n\n\n\n<!DOCTYPE html>\n<html\n  lang=\"en\"\n  \n  data-color-mode=\"auto\" data-light-theme=\"light\" data-dark-theme=\"dark\"\n  data-a11y-animated-images=\"system\" data-a11y-link-underlines=\"true\"\n  >\n\n\n\n\n  <head>\n    <meta charset=\"utf-8\">\n  <link rel=\"dns-prefetch\" href=\"https://github.githubassets.com\">\n  <link rel=\"dns-prefetch\" href=\"https://avatars.githubusercontent.com\">\n  <link rel=\"dns-prefetch\" href=\"https://github-cloud.s3.amazonaws.com\">\n  <link rel=\"dns-prefetch\" href=\"https://user-images.githubusercontent.com/\">\n  <link rel=\"preconnect\" href=\"https://github.githubassets.com\" crossorigin>\n  <link rel=\"preconnect\" href=\"https://avatars.githubusercontent.com\">\n\n  \n\n\n  <link crossorigin=\"anonymous\" media=\"all\" rel=\"stylesheet\" href=\"https://github.githubassets.com/assets/light-f552bab6ce72.css\" /><link crossorigin=\"anonymous\" media=\"all\" rel=\"stylesheet\" href=\"https://github.githubassets.com/assets/dark-4589f64a2275.css\" /><link data-color-theme=\"dark_dimmed\" crossorigin=\"anonymous\" media=\"all\" rel=\"stylesheet\" data-href=\"https://github.githubassets.com/assets/dark_dimmed-a7246d2d6733.css\" /><link data-color-theme=\"dark_high_contrast\" crossorigin=\"anonymous\" media=\"all\" rel=\"stylesheet\" data-href=\"https://github.githubassets.com/assets/dark_high_contrast-f2ef05cef2f1.css\" /><link data-color-theme=\"dark_colorblind\" crossorigin=\"anonymous\" media=\"all\" rel=\"stylesheet\" data-href=\"https://github.githubassets.com/assets/dark_colorblind-daa1fe317131.css\" /><link data-color-theme=\"light_colorblind\" crossorigin=\"anonymous\" media=\"all\" rel=\"stylesheet\" data-href=\"https://github.githubassets.com/assets/light_colorblind-1ab6fcc64845.css\" /><link data-color-theme=\"light_high_contrast\" crossorigin=\"anonymous\" media=\"all\" rel=\"stylesheet\" data-href=\"https://github.githubassets.com/assets/light_high_contrast-46de871e876c.css\" /><link data-color-theme=\"light_tritanopia\" crossorigin=\"anonymous\" media=\"all\" rel=\"stylesheet\" data-href=\"https://github.githubassets.com/assets/light_tritanopia-c9754fef2a31.css\" /><link data-color-theme=\"dark_tritanopia\" crossorigin=\"anonymous\" media=\"all\" rel=\"stylesheet\" data-href=\"https://github.githubassets.com/assets/dark_tritanopia-dba748981a29.css\" />\n    <link crossorigin=\"anonymous\" media=\"all\" rel=\"stylesheet\" href=\"https://github.githubassets.com/assets/primer-primitives-4cbeaa0795ef.css\" />\n    <link crossorigin=\"anonymous\" media=\"all\" rel=\"stylesheet\" href=\"https://github.githubassets.com/assets/primer-fa3434a1ba0a.css\" />\n    <link crossorigin=\"anonymous\" media=\"all\" rel=\"stylesheet\" href=\"https://github.githubassets.com/assets/global-31defe89cafd.css\" />\n    <link crossorigin=\"anonymous\" media=\"all\" rel=\"stylesheet\" href=\"https://github.githubassets.com/assets/github-151c896d0930.css\" />\n  <link crossorigin=\"anonymous\" media=\"all\" rel=\"stylesheet\" href=\"https://github.githubassets.com/assets/repository-2e900f0ac288.css\" />\n<link crossorigin=\"anonymous\" media=\"all\" rel=\"stylesheet\" href=\"https://github.githubassets.com/assets/code-33498bbbf39d.css\" />\n\n  \n\n\n  <script type=\"application/json\" id=\"client-env\">{\"locale\":\"en\",\"featureFlags\":[\"code_vulnerability_scanning\",\"copilot_chat_static_thread_suggestions\",\"copilot_chat_in_mobile_ga\",\"copilot_conversational_ux_history_refs\",\"copilot_followup_to_agent\",\"copilot_smell_icebreaker_ux\",\"copilot_implicit_context\",\"copilot_stop_response\",\"copilot_updated_function_buttons\",\"failbot_handle_non_errors\",\"geojson_azure_maps\",\"image_metric_tracking\",\"marketing_forms_api_integration_contact_request\",\"marketing_pages_search_explore_provider\",\"repository_suggester_elastic_search\",\"turbo_experiment_risky\",\"sample_network_conn_type\",\"no_character_key_shortcuts_in_inputs\",\"react_start_transition_for_navigations\",\"custom_inp\",\"remove_child_patch\",\"kb_source_repos\"]}</script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/wp-runtime-39a72518443f.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/vendors-node_modules_dompurify_dist_purify_js-810e4b1b9abd.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/vendors-node_modules_oddbird_popover-polyfill_dist_popover_js-4ac41d0a76fd.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/vendors-node_modules_smoothscroll-polyfill_dist_smoothscroll_js-node_modules_stacktrace-parse-a448e4-f17a27f30529.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/environment-2168885ea2b8.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/vendors-node_modules_primer_behaviors_dist_esm_focus-zone_js-c7679f99a1f3.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/vendors-node_modules_github_selector-observer_dist_index_esm_js-9f960d9b217c.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/vendors-node_modules_github_relative-time-element_dist_index_js-c76945c5961a.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/vendors-node_modules_github_combobox-nav_dist_index_js-node_modules_github_markdown-toolbar-e-820fc0-1176135e4d90.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/vendors-node_modules_github_auto-complete-element_dist_index_js-node_modules_github_catalyst_-392fe4-1327b94f3269.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/vendors-node_modules_github_text-expander-element_dist_index_js-b2135edb5ced.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/vendors-node_modules_github_filter-input-element_dist_index_js-node_modules_github_remote-inp-b7d8f4-6e6f83bcc978.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/vendors-node_modules_delegated-events_dist_index_js-node_modules_stacktrace-parser_dist_stack-8585c6-b62c48e55af5.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/vendors-node_modules_github_file-attachment-element_dist_index_js-node_modules_primer_view-co-3959a9-8b35cf73f178.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/app_assets_modules_github_onfocus_ts-ui_packages_trusted-types-policies_policy_ts-ui_packages-6fe316-ae5060590d17.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/github-elements-524aae40a1ff.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/element-registry-10250650a1f1.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/vendors-node_modules_braintree_browser-detection_dist_browser-detection_js-node_modules_githu-fd5530-141bf1a3abfb.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/vendors-node_modules_lit-html_lit-html_js-cc7cb714ead5.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/vendors-node_modules_morphdom_dist_morphdom-esm_js-node_modules_github_memoize_dist_esm_index_js-8d7117d67c36.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/vendors-node_modules_github_turbo_dist_turbo_es2017-esm_js-1cea0f5eff45.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/vendors-node_modules_github_remote-form_dist_index_js-node_modules_delegated-events_dist_inde-893f9f-880ac2bbb719.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/vendors-node_modules_scroll-anchoring_dist_scroll-anchoring_esm_js-node_modules_github_hotkey-1a1d91-1bb71f3f93c2.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/vendors-node_modules_color-convert_index_js-94fdbf91204e.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/vendors-node_modules_primer_behaviors_dist_esm_dimensions_js-node_modules_github_jtml_lib_index_js-b1947a1d4855.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/vendors-node_modules_github_session-resume_dist_index_js-node_modules_primer_behaviors_dist_e-da6ec6-77ce2f267f4e.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/vendors-node_modules_github_quote-selection_dist_index_js-node_modules_github_textarea-autosi-9e0349-704599a61056.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/app_assets_modules_github_updatable-content_ts-4d91e80fb877.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/app_assets_modules_github_behaviors_task-list_ts-app_assets_modules_github_onfocus_ts-app_ass-421cec-d3af2356fb47.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/app_assets_modules_github_sticky-scroll-into-view_ts-72d6e7bfb28f.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/app_assets_modules_github_behaviors_ajax-error_ts-app_assets_modules_github_behaviors_include-467754-25aa4f5b0d26.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/app_assets_modules_github_behaviors_commenting_edit_ts-app_assets_modules_github_behaviors_ht-83c235-5276a3faf037.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/behaviors-b75fc2506ff4.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/vendors-node_modules_delegated-events_dist_index_js-node_modules_github_catalyst_lib_index_js-06ff531-2ea61fcc9a71.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/notifications-global-1506817815cf.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/app_assets_modules_github_repositories_get-repo-element_ts-e21ae6671295.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/code-menu-67595c3a6d0c.js\"></script>\n  \n  <script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/react-lib-dc88c1a68b28.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/vendors-node_modules_primer_octicons-react_dist_index_esm_js-node_modules_primer_react_lib-es-541a38-c63b7a3484dd.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/vendors-node_modules_primer_react_lib-esm_Box_Box_js-8f8c5e2a2cbf.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/vendors-node_modules_primer_react_lib-esm_FeatureFlags_FeatureFlags_js-node_modules_github_ca-9009bd-47065f21e9ac.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/vendors-node_modules_primer_react_lib-esm_Button_Button_js-97ed51d4f278.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/vendors-node_modules_primer_react_lib-esm_TooltipV2_Tooltip_js-334106258bdb.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/vendors-node_modules_primer_react_node_modules_primer_octicons-react_dist_index_esm_mjs-dc98a76c65d6.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/vendors-node_modules_primer_react_lib-esm_ActionList_index_js-9e50e37cd494.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/vendors-node_modules_primer_react_lib-esm_TextInput_TextInput_js-15046fb40abc.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/vendors-node_modules_primer_react_lib-esm_AnchoredOverlay_AnchoredOverlay_js-4c761b535add.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/vendors-node_modules_primer_react_lib-esm_FormControl_FormControl_js-a8d16e422c06.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/vendors-node_modules_primer_react_lib-esm_ActionMenu_ActionMenu_js-3936ca1bc46c.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/vendors-node_modules_react-router-dom_dist_index_js-2b1dbeadb6d4.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/vendors-node_modules_primer_react_lib-esm_ConfirmationDialog_ConfirmationDialog_js-e77978dd27f4.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/vendors-node_modules_primer_react_lib-esm_Heading_Heading_js-node_modules_primer_react_lib-es-3d3c74-b0dc89be21ef.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/vendors-node_modules_primer_react_lib-esm_PageLayout_PageLayout_js-node_modules_github_hydro--f8521d-0253212e1803.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/vendors-node_modules_primer_react_lib-esm_AvatarStack_AvatarStack_js-node_modules_primer_reac-6dc608-7db6cfae96f8.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/vendors-node_modules_primer_react_lib-esm_Avatar_Avatar_js-node_modules_primer_react_lib-esm_-7f6456-c20b6dc732fc.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/ui_packages_react-core_create-browser-history_ts-ui_packages_safe-storage_safe-storage_ts-ui_-682c2c-44ed51a2083d.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/ui_packages_react-core_register-app_ts-cdec9cf45205.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/ui_packages_paths_index_ts-6a5742f488e3.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/ui_packages_ref-selector_RefSelector_tsx-69aff3dba3cb.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/ui_packages_commit-attribution_index_ts-ui_packages_commit-checks-status_index_ts-ui_packages-59a8e3-7facab980ffb.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/app_assets_modules_react-shared_hooks_use-canonical-object_ts-ui_packages_code-view-shared_ho-e725dc-935487bb4506.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/node_modules_github_mini-throttle_dist_index_js-app_assets_modules_github_blob-anchor_ts-app_-55c012-0a425c5f01b6.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/react-code-view-a64eb553026b.js\"></script>\n<link crossorigin=\"anonymous\" media=\"all\" rel=\"stylesheet\" href=\"https://github.githubassets.com/assets/react-code-view.f2d60f636eb02c2001df.module.css\" />\n\n\n  <title>roadmap-retos-programacion/Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/GitHjuan.php at main · mouredev/roadmap-retos-programacion</title>\n\n\n\n  <meta name=\"route-pattern\" content=\"/:user_id/:repository/blob/*name(/*path)\" data-turbo-transient>\n  <meta name=\"route-controller\" content=\"blob\" data-turbo-transient>\n  <meta name=\"route-action\" content=\"show\" data-turbo-transient>\n\n    \n  <meta name=\"current-catalog-service-hash\" content=\"82c569b93da5c18ed649ebd4c2c79437db4611a6a1373e805a3cb001c64130b7\">\n\n\n  <meta name=\"request-id\" content=\"DE86:9D388:F8535A:118A936:66538287\" data-turbo-transient=\"true\" /><meta name=\"html-safe-nonce\" content=\"6d16d1046b578431ec4901140df54520f17f18730fae842555af0f7a6fc9c034\" data-turbo-transient=\"true\" /><meta name=\"visitor-payload\" content=\"eyJyZWZlcnJlciI6Imh0dHBzOi8vZ2l0aHViLmNvbS9tb3VyZWRldi9yb2FkbWFwLXJldG9zLXByb2dyYW1hY2lvbi90cmVlL21haW4vUm9hZG1hcC8wMCUyMC0lMjBTSU5UQVhJUyUyQyUyMFZBUklBQkxFUyUyQyUyMFRJUE9TJTIwREUlMjBEQVRPUyUyMFklMjBIT0xBJTIwTVVORE8vcGhwIiwicmVxdWVzdF9pZCI6IkRFODY6OUQzODg6Rjg1MzVBOjExOEE5MzY6NjY1MzgyODciLCJ2aXNpdG9yX2lkIjoiMjE2ODQxNjU3NzI4MjY3MjcyNyIsInJlZ2lvbl9lZGdlIjoiYnJhemlsc291dGgiLCJyZWdpb25fcmVuZGVyIjoiaWFkIn0=\" data-turbo-transient=\"true\" /><meta name=\"visitor-hmac\" content=\"28533725b8dfac87c3d18a4b04ce25f70cd63b2996a3db98f6cc18eb1eca1cd0\" data-turbo-transient=\"true\" />\n\n\n    <meta name=\"hovercard-subject-tag\" content=\"repository:733006926\" data-turbo-transient>\n\n\n  <meta name=\"github-keyboard-shortcuts\" content=\"repository,source-code,file-tree,copilot\" data-turbo-transient=\"true\" />\n  \n\n  <meta name=\"selected-link\" value=\"repo_source\" data-turbo-transient>\n  <link rel=\"assets\" href=\"https://github.githubassets.com/\">\n\n    <meta name=\"google-site-verification\" content=\"Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I\">\n\n<meta name=\"octolytics-url\" content=\"https://collector.github.com/github/collect\" /><meta name=\"octolytics-actor-id\" content=\"88008233\" /><meta name=\"octolytics-actor-login\" content=\"Roswell468\" /><meta name=\"octolytics-actor-hash\" content=\"bdd465bc58b692f21434d876756fa2bb174b9056723375d962f07c451e6a05cb\" />\n\n  <meta name=\"analytics-location\" content=\"/&lt;user-name&gt;/&lt;repo-name&gt;/blob/show\" data-turbo-transient=\"true\" />\n\n  \n\n\n\n\n    <meta name=\"user-login\" content=\"Roswell468\">\n\n  <link rel=\"sudo-modal\" href=\"/sessions/sudo_modal\">\n\n    <meta name=\"viewport\" content=\"width=device-width\">\n\n    \n\n      <meta name=\"description\" content=\"Ruta de estudio basada en ejercicios de código semanales en 2024 de la comunidad MoureDev para aprender y practicar lógica usando cualquier lenguaje de programación. - roadmap-retos-programacion/Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/GitHjuan.php at main · mouredev/roadmap-retos-programacion\">\n\n      <link rel=\"search\" type=\"application/opensearchdescription+xml\" href=\"/opensearch.xml\" title=\"GitHub\">\n\n    <link rel=\"fluid-icon\" href=\"https://github.com/fluidicon.png\" title=\"GitHub\">\n    <meta property=\"fb:app_id\" content=\"1401488693436528\">\n    <meta name=\"apple-itunes-app\" content=\"app-id=1477376905, app-argument=https://github.com/mouredev/roadmap-retos-programacion/blob/main/Roadmap/00%20-%20SINTAXIS%2C%20VARIABLES%2C%20TIPOS%20DE%20DATOS%20Y%20HOLA%20MUNDO/php/GitHjuan.php\" />\n\n      <meta name=\"twitter:image:src\" content=\"https://repository-images.githubusercontent.com/733006926/8816e47d-37ca-4b6a-befd-c8ffa76352b7\" /><meta name=\"twitter:site\" content=\"@github\" /><meta name=\"twitter:card\" content=\"summary_large_image\" /><meta name=\"twitter:title\" content=\"roadmap-retos-programacion/Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/GitHjuan.php at main · mouredev/roadmap-retos-programacion\" /><meta name=\"twitter:description\" content=\"Ruta de estudio basada en ejercicios de código semanales en 2024 de la comunidad MoureDev para aprender y practicar lógica usando cualquier lenguaje de programación. - mouredev/roadmap-retos-progra...\" />\n  <meta property=\"og:image\" content=\"https://repository-images.githubusercontent.com/733006926/8816e47d-37ca-4b6a-befd-c8ffa76352b7\" /><meta property=\"og:image:alt\" content=\"Ruta de estudio basada en ejercicios de código semanales en 2024 de la comunidad MoureDev para aprender y practicar lógica usando cualquier lenguaje de programación. - mouredev/roadmap-retos-progra...\" /><meta property=\"og:site_name\" content=\"GitHub\" /><meta property=\"og:type\" content=\"object\" /><meta property=\"og:title\" content=\"roadmap-retos-programacion/Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/GitHjuan.php at main · mouredev/roadmap-retos-programacion\" /><meta property=\"og:url\" content=\"https://github.com/mouredev/roadmap-retos-programacion/blob/main/Roadmap/00%20-%20SINTAXIS%2C%20VARIABLES%2C%20TIPOS%20DE%20DATOS%20Y%20HOLA%20MUNDO/php/GitHjuan.php\" /><meta property=\"og:description\" content=\"Ruta de estudio basada en ejercicios de código semanales en 2024 de la comunidad MoureDev para aprender y practicar lógica usando cualquier lenguaje de programación. - mouredev/roadmap-retos-progra...\" />\n  \n\n\n      <link rel=\"shared-web-socket\" href=\"wss://alive.github.com/_sockets/u/88008233/ws?session=eyJ2IjoiVjMiLCJ1Ijo4ODAwODIzMywicyI6MTE5NTQ4MzYzMiwiYyI6MzEyNjI3MjI0OCwidCI6MTcxNjc0ODk0M30=--1c8eb02bb42c12cd08ac4edf0415709dc208224611fa6882f92f9bcab8fd8770\" data-refresh-url=\"/_alive\" data-session-id=\"c5a9267fbb3ee5a3cce9251095da6470013e5da1940413805a1602340cc479f4\">\n      <link rel=\"shared-web-socket-src\" href=\"/assets-cdn/worker/socket-worker-2ec9fc0c9740.js\">\n\n\n      <meta name=\"hostname\" content=\"github.com\">\n\n\n      <meta name=\"keyboard-shortcuts-preference\" content=\"all\">\n\n        <meta name=\"expected-hostname\" content=\"github.com\">\n\n\n  <meta http-equiv=\"x-pjax-version\" content=\"34babae02e63d53c7b915db7797718d75b60dbe3e877faa20ad03a0b81bbfc4b\" data-turbo-track=\"reload\">\n  <meta http-equiv=\"x-pjax-csp-version\" content=\"38c639a245e1dd04786881fae1060fbd72d3ed419b2f0d38d6082dc9d67876c3\" data-turbo-track=\"reload\">\n  <meta http-equiv=\"x-pjax-css-version\" content=\"8297669360f26c55eaf368df3078812f654eff1244bb59f8c32594aa15b30b3d\" data-turbo-track=\"reload\">\n  <meta http-equiv=\"x-pjax-js-version\" content=\"256a32581ec96d92cf471432537500e7698dfb422de8395b8988aa08d79823b6\" data-turbo-track=\"reload\">\n\n  <meta name=\"turbo-cache-control\" content=\"no-preview\" data-turbo-transient=\"\">\n\n      <meta name=\"turbo-cache-control\" content=\"no-cache\" data-turbo-transient>\n    <meta data-hydrostats=\"publish\">\n  <meta name=\"go-import\" content=\"github.com/mouredev/roadmap-retos-programacion git https://github.com/mouredev/roadmap-retos-programacion.git\">\n\n  <meta name=\"octolytics-dimension-user_id\" content=\"17043402\" /><meta name=\"octolytics-dimension-user_login\" content=\"mouredev\" /><meta name=\"octolytics-dimension-repository_id\" content=\"733006926\" /><meta name=\"octolytics-dimension-repository_nwo\" content=\"mouredev/roadmap-retos-programacion\" /><meta name=\"octolytics-dimension-repository_public\" content=\"true\" /><meta name=\"octolytics-dimension-repository_is_fork\" content=\"false\" /><meta name=\"octolytics-dimension-repository_network_root_id\" content=\"733006926\" /><meta name=\"octolytics-dimension-repository_network_root_nwo\" content=\"mouredev/roadmap-retos-programacion\" />\n\n\n\n    \n\n    <meta name=\"turbo-body-classes\" content=\"logged-in env-production page-responsive\">\n\n\n  <meta name=\"browser-stats-url\" content=\"https://api.github.com/_private/browser/stats\">\n\n  <meta name=\"browser-errors-url\" content=\"https://api.github.com/_private/browser/errors\">\n\n  <link rel=\"mask-icon\" href=\"https://github.githubassets.com/assets/pinned-octocat-093da3e6fa40.svg\" color=\"#000000\">\n  <link rel=\"alternate icon\" class=\"js-site-favicon\" type=\"image/png\" href=\"https://github.githubassets.com/favicons/favicon.png\">\n  <link rel=\"icon\" class=\"js-site-favicon\" type=\"image/svg+xml\" href=\"https://github.githubassets.com/favicons/favicon.svg\">\n\n<meta name=\"theme-color\" content=\"#1e2327\">\n<meta name=\"color-scheme\" content=\"light dark\" />\n\n  <meta name=\"msapplication-TileImage\" content=\"/windows-tile.png\">\n  <meta name=\"msapplication-TileColor\" content=\"#ffffff\">\n\n  <link rel=\"manifest\" href=\"/manifest.json\" crossOrigin=\"use-credentials\">\n\n  </head>\n\n  <body class=\"logged-in env-production page-responsive\" style=\"word-wrap: break-word;\">\n    <div data-turbo-body class=\"logged-in env-production page-responsive\" style=\"word-wrap: break-word;\">\n      \n\n\n    <div class=\"position-relative js-header-wrapper \">\n      <a href=\"#start-of-content\" data-skip-target-assigned=\"false\" class=\"p-3 color-bg-accent-emphasis color-fg-on-emphasis show-on-focus js-skip-to-content\">Skip to content</a>\n\n      <span data-view-component=\"true\" class=\"progress-pjax-loader Progress position-fixed width-full\">\n    <span style=\"width: 0%;\" data-view-component=\"true\" class=\"Progress-item progress-pjax-loader-bar left-0 top-0 color-bg-accent-emphasis\"></span>\n</span>      \n      \n      \n\n\n\n\n\n\n\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/vendors-node_modules_primer_react_lib-esm_Button_IconButton_js-node_modules_primer_react_lib--1cd808-6070bc6b2c67.js\"></script>\n\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/keyboard-shortcuts-dialog-52a107eb77ae.js\"></script>\n\n<react-partial\n  partial-name=\"keyboard-shortcuts-dialog\"\n  data-ssr=\"false\"\n>\n  \n  <script type=\"application/json\" data-target=\"react-partial.embeddedData\">{\"props\":{\"docsUrl\":\"https://docs.github.com/get-started/accessibility/keyboard-shortcuts\"}}</script>\n  <div data-target=\"react-partial.reactRoot\"></div>\n</react-partial>\n\n\n\n\n      \n\n        <script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/vendors-node_modules_allex_crc32_lib_crc32_esm_js-node_modules_github_mini-throttle_dist_deco-a9eeba-34e4d091ae23.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/vendors-node_modules_github_clipboard-copy-element_dist_index_esm_js-node_modules_delegated-e-b37f7d-cb3d06ead51a.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/app_assets_modules_github_command-palette_items_help-item_ts-app_assets_modules_github_comman-48ad9d-8c5f299d00ae.js\"></script>\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/command-palette-a99cf9e9f4ca.js\"></script>\n\n            <header class=\"AppHeader\" role=\"banner\">\n  <h2 class=\"sr-only\">Navigation Menu</h2>\n\n    \n\n    <div class=\"AppHeader-globalBar pb-2 js-global-bar\">\n      <div class=\"AppHeader-globalBar-start\">\n          <deferred-side-panel data-url=\"/_side-panels/global\">\n  <include-fragment data-target=\"deferred-side-panel.fragment\">\n      <button aria-label=\"Open global navigation menu\" data-action=\"click:deferred-side-panel#loadPanel click:deferred-side-panel#panelOpened\" data-show-dialog-id=\"dialog-13716ffa-7180-4fec-a815-7260794c0540\" id=\"dialog-show-dialog-13716ffa-7180-4fec-a815-7260794c0540\" type=\"button\" data-view-component=\"true\" class=\"Button Button--iconOnly Button--secondary Button--medium AppHeader-button color-bg-transparent p-0 color-fg-muted\">  <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-three-bars Button-visual\">\n    <path d=\"M1 2.75A.75.75 0 0 1 1.75 2h12.5a.75.75 0 0 1 0 1.5H1.75A.75.75 0 0 1 1 2.75Zm0 5A.75.75 0 0 1 1.75 7h12.5a.75.75 0 0 1 0 1.5H1.75A.75.75 0 0 1 1 7.75ZM1.75 12h12.5a.75.75 0 0 1 0 1.5H1.75a.75.75 0 0 1 0-1.5Z\"></path>\n</svg>\n</button>\n\n<dialog-helper>\n  <dialog data-target=\"deferred-side-panel.panel\" id=\"dialog-13716ffa-7180-4fec-a815-7260794c0540\" aria-modal=\"true\" aria-labelledby=\"dialog-13716ffa-7180-4fec-a815-7260794c0540-title\" aria-describedby=\"dialog-13716ffa-7180-4fec-a815-7260794c0540-description\" data-view-component=\"true\" class=\"Overlay Overlay-whenNarrow Overlay--size-small-portrait Overlay--motion-scaleFade Overlay--placement-left SidePanel\">\n    <div styles=\"flex-direction: row;\" data-view-component=\"true\" class=\"Overlay-header\">\n  <div class=\"Overlay-headerContentWrap\">\n    <div class=\"Overlay-titleWrap\">\n      <h1 class=\"Overlay-title sr-only\" id=\"dialog-13716ffa-7180-4fec-a815-7260794c0540-title\">\n        Global navigation\n      </h1>\n            <div data-view-component=\"true\" class=\"d-flex\">\n      <div data-view-component=\"true\" class=\"AppHeader-logo position-relative\">\n        <svg aria-hidden=\"true\" height=\"24\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"24\" data-view-component=\"true\" class=\"octicon octicon-mark-github\">\n    <path d=\"M8 0c4.42 0 8 3.58 8 8a8.013 8.013 0 0 1-5.45 7.59c-.4.08-.55-.17-.55-.38 0-.27.01-1.13.01-2.2 0-.75-.25-1.23-.54-1.48 1.78-.2 3.65-.88 3.65-3.95 0-.88-.31-1.59-.82-2.15.08-.2.36-1.02-.08-2.12 0 0-.67-.22-2.2.82-.64-.18-1.32-.27-2-.27-.68 0-1.36.09-2 .27-1.53-1.03-2.2-.82-2.2-.82-.44 1.1-.16 1.92-.08 2.12-.51.56-.82 1.28-.82 2.15 0 3.06 1.86 3.75 3.64 3.95-.23.2-.44.55-.51 1.07-.46.21-1.61.55-2.33-.66-.15-.24-.6-.83-1.23-.82-.67.01-.27.38.01.53.34.19.73.9.82 1.13.16.45.68 1.31 2.69.94 0 .67.01 1.3.01 1.49 0 .21-.15.45-.55.38A7.995 7.995 0 0 1 0 8c0-4.42 3.58-8 8-8Z\"></path>\n</svg>\n</div></div>\n    </div>\n    <div class=\"Overlay-actionWrap\">\n      <button data-close-dialog-id=\"dialog-13716ffa-7180-4fec-a815-7260794c0540\" aria-label=\"Close\" type=\"button\" data-view-component=\"true\" class=\"close-button Overlay-closeButton\"><svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-x\">\n    <path d=\"M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z\"></path>\n</svg></button>\n    </div>\n  </div>\n  \n</div>\n      <scrollable-region data-labelled-by=\"dialog-13716ffa-7180-4fec-a815-7260794c0540-title\">\n        <div data-view-component=\"true\" class=\"Overlay-body d-flex flex-column px-2\">    <div data-view-component=\"true\" class=\"d-flex flex-column mb-3\">\n        <nav aria-label=\"Site navigation\" data-view-component=\"true\" class=\"ActionList\">\n  \n  <nav-list>\n    <ul data-target=\"nav-list.topLevelList\" data-view-component=\"true\" class=\"ActionListWrap\">\n        \n          \n<li data-item-id=\"\" data-targets=\"nav-list.items\" data-view-component=\"true\" class=\"ActionListItem\">\n    \n    \n    <a data-hotkey=\"g d\" data-analytics-event=\"{&quot;category&quot;:&quot;Global navigation&quot;,&quot;action&quot;:&quot;HOME&quot;,&quot;label&quot;:null}\" id=\"item-ea403719-2bdd-42ee-ae86-b3e9fcca262c\" href=\"/dashboard\" data-view-component=\"true\" class=\"ActionListContent ActionListContent--visual16\">\n        <span class=\"ActionListItem-visual ActionListItem-visual--leading\">\n          <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-home\">\n    <path d=\"M6.906.664a1.749 1.749 0 0 1 2.187 0l5.25 4.2c.415.332.657.835.657 1.367v7.019A1.75 1.75 0 0 1 13.25 15h-3.5a.75.75 0 0 1-.75-.75V9H7v5.25a.75.75 0 0 1-.75.75h-3.5A1.75 1.75 0 0 1 1 13.25V6.23c0-.531.242-1.034.657-1.366l5.25-4.2Zm1.25 1.171a.25.25 0 0 0-.312 0l-5.25 4.2a.25.25 0 0 0-.094.196v7.019c0 .138.112.25.25.25H5.5V8.25a.75.75 0 0 1 .75-.75h3.5a.75.75 0 0 1 .75.75v5.25h2.75a.25.25 0 0 0 .25-.25V6.23a.25.25 0 0 0-.094-.195Z\"></path>\n</svg>\n        </span>\n      \n        <span data-view-component=\"true\" class=\"ActionListItem-label\">\n          Home\n</span></a>\n  \n</li>\n\n        \n          \n<li data-item-id=\"\" data-targets=\"nav-list.items\" data-view-component=\"true\" class=\"ActionListItem\">\n    \n    \n    <a data-hotkey=\"g i\" data-analytics-event=\"{&quot;category&quot;:&quot;Global navigation&quot;,&quot;action&quot;:&quot;ISSUES&quot;,&quot;label&quot;:null}\" id=\"item-8b28b5ee-655e-48b8-add2-c7a833ff6155\" href=\"/issues\" data-view-component=\"true\" class=\"ActionListContent ActionListContent--visual16\">\n        <span class=\"ActionListItem-visual ActionListItem-visual--leading\">\n          <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-issue-opened\">\n    <path d=\"M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z\"></path><path d=\"M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Z\"></path>\n</svg>\n        </span>\n      \n        <span data-view-component=\"true\" class=\"ActionListItem-label\">\n          Issues\n</span></a>\n  \n</li>\n\n        \n          \n<li data-item-id=\"\" data-targets=\"nav-list.items\" data-view-component=\"true\" class=\"ActionListItem\">\n    \n    \n    <a data-hotkey=\"g p\" data-analytics-event=\"{&quot;category&quot;:&quot;Global navigation&quot;,&quot;action&quot;:&quot;PULL_REQUESTS&quot;,&quot;label&quot;:null}\" id=\"item-5abd24c8-a439-47a3-8930-1a42df4ee2df\" href=\"/pulls\" data-view-component=\"true\" class=\"ActionListContent ActionListContent--visual16\">\n        <span class=\"ActionListItem-visual ActionListItem-visual--leading\">\n          <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-git-pull-request\">\n    <path d=\"M1.5 3.25a2.25 2.25 0 1 1 3 2.122v5.256a2.251 2.251 0 1 1-1.5 0V5.372A2.25 2.25 0 0 1 1.5 3.25Zm5.677-.177L9.573.677A.25.25 0 0 1 10 .854V2.5h1A2.5 2.5 0 0 1 13.5 5v5.628a2.251 2.251 0 1 1-1.5 0V5a1 1 0 0 0-1-1h-1v1.646a.25.25 0 0 1-.427.177L7.177 3.427a.25.25 0 0 1 0-.354ZM3.75 2.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm0 9.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm8.25.75a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Z\"></path>\n</svg>\n        </span>\n      \n        <span data-view-component=\"true\" class=\"ActionListItem-label\">\n          Pull requests\n</span></a>\n  \n</li>\n\n        \n          \n<li data-item-id=\"\" data-targets=\"nav-list.items\" data-item-id=\"projects\" data-view-component=\"true\" class=\"ActionListItem\">\n    \n    \n    <a data-analytics-event=\"{&quot;category&quot;:&quot;Global navigation&quot;,&quot;action&quot;:&quot;PROJECTS&quot;,&quot;label&quot;:null}\" id=\"item-022bed91-4e54-43d9-b323-2c42acb03edd\" href=\"/projects\" data-view-component=\"true\" class=\"ActionListContent ActionListContent--visual16\">\n        <span class=\"ActionListItem-visual ActionListItem-visual--leading\">\n          <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-table\">\n    <path d=\"M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25ZM6.5 6.5v8h7.75a.25.25 0 0 0 .25-.25V6.5Zm8-1.5V1.75a.25.25 0 0 0-.25-.25H6.5V5Zm-13 1.5v7.75c0 .138.112.25.25.25H5v-8ZM5 5V1.5H1.75a.25.25 0 0 0-.25.25V5Z\"></path>\n</svg>\n        </span>\n      \n        <span data-view-component=\"true\" class=\"ActionListItem-label\">\n          Projects\n</span></a>\n  \n</li>\n\n        \n          \n<li data-item-id=\"\" data-targets=\"nav-list.items\" data-view-component=\"true\" class=\"ActionListItem\">\n    \n    \n    <a data-analytics-event=\"{&quot;category&quot;:&quot;Global navigation&quot;,&quot;action&quot;:&quot;DISCUSSIONS&quot;,&quot;label&quot;:null}\" id=\"item-028a2182-537e-4d38-b488-048520d00a00\" href=\"/discussions\" data-view-component=\"true\" class=\"ActionListContent ActionListContent--visual16\">\n        <span class=\"ActionListItem-visual ActionListItem-visual--leading\">\n          <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-comment-discussion\">\n    <path d=\"M1.75 1h8.5c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 10.25 10H7.061l-2.574 2.573A1.458 1.458 0 0 1 2 11.543V10h-.25A1.75 1.75 0 0 1 0 8.25v-5.5C0 1.784.784 1 1.75 1ZM1.5 2.75v5.5c0 .138.112.25.25.25h1a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h3.5a.25.25 0 0 0 .25-.25v-5.5a.25.25 0 0 0-.25-.25h-8.5a.25.25 0 0 0-.25.25Zm13 2a.25.25 0 0 0-.25-.25h-.5a.75.75 0 0 1 0-1.5h.5c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 14.25 12H14v1.543a1.458 1.458 0 0 1-2.487 1.03L9.22 12.28a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215l2.22 2.22v-2.19a.75.75 0 0 1 .75-.75h1a.25.25 0 0 0 .25-.25Z\"></path>\n</svg>\n        </span>\n      \n        <span data-view-component=\"true\" class=\"ActionListItem-label\">\n          Discussions\n</span></a>\n  \n</li>\n\n        \n          \n<li data-item-id=\"\" data-targets=\"nav-list.items\" data-view-component=\"true\" class=\"ActionListItem\">\n    \n    \n    <a data-analytics-event=\"{&quot;category&quot;:&quot;Global navigation&quot;,&quot;action&quot;:&quot;CODESPACES&quot;,&quot;label&quot;:null}\" id=\"item-4e4d0507-72b4-4347-ba3c-ffd960f34218\" href=\"https://github.com/codespaces\" data-view-component=\"true\" class=\"ActionListContent ActionListContent--visual16\">\n        <span class=\"ActionListItem-visual ActionListItem-visual--leading\">\n          <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-codespaces\">\n    <path d=\"M0 11.25c0-.966.784-1.75 1.75-1.75h12.5c.966 0 1.75.784 1.75 1.75v3A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25Zm2-9.5C2 .784 2.784 0 3.75 0h8.5C13.216 0 14 .784 14 1.75v5a1.75 1.75 0 0 1-1.75 1.75h-8.5A1.75 1.75 0 0 1 2 6.75Zm1.75-.25a.25.25 0 0 0-.25.25v5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-5a.25.25 0 0 0-.25-.25Zm-2 9.5a.25.25 0 0 0-.25.25v3c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25v-3a.25.25 0 0 0-.25-.25Z\"></path><path d=\"M7 12.75a.75.75 0 0 1 .75-.75h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1-.75-.75Zm-4 0a.75.75 0 0 1 .75-.75h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1-.75-.75Z\"></path>\n</svg>\n        </span>\n      \n        <span data-view-component=\"true\" class=\"ActionListItem-label\">\n          Codespaces\n</span></a>\n  \n</li>\n\n        \n          <li role=\"presentation\" aria-hidden=\"true\" data-view-component=\"true\" class=\"ActionList-sectionDivider\"></li>\n        \n          \n<li data-item-id=\"\" data-targets=\"nav-list.items\" data-view-component=\"true\" class=\"ActionListItem\">\n    \n    \n    <a data-analytics-event=\"{&quot;category&quot;:&quot;Global navigation&quot;,&quot;action&quot;:&quot;EXPLORE&quot;,&quot;label&quot;:null}\" id=\"item-cd2c47a0-ebad-4ef3-86f1-caeb38b00252\" href=\"/explore\" data-view-component=\"true\" class=\"ActionListContent ActionListContent--visual16\">\n        <span class=\"ActionListItem-visual ActionListItem-visual--leading\">\n          <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-telescope\">\n    <path d=\"M14.184 1.143v-.001l1.422 2.464a1.75 1.75 0 0 1-.757 2.451L3.104 11.713a1.75 1.75 0 0 1-2.275-.702l-.447-.775a1.75 1.75 0 0 1 .53-2.32L11.682.573a1.748 1.748 0 0 1 2.502.57Zm-4.709 9.32h-.001l2.644 3.863a.75.75 0 1 1-1.238.848l-1.881-2.75v2.826a.75.75 0 0 1-1.5 0v-2.826l-1.881 2.75a.75.75 0 1 1-1.238-.848l2.049-2.992a.746.746 0 0 1 .293-.253l1.809-.87a.749.749 0 0 1 .944.252ZM9.436 3.92h-.001l-4.97 3.39.942 1.63 5.42-2.61Zm3.091-2.108h.001l-1.85 1.26 1.505 2.605 2.016-.97a.247.247 0 0 0 .13-.151.247.247 0 0 0-.022-.199l-1.422-2.464a.253.253 0 0 0-.161-.119.254.254 0 0 0-.197.038ZM1.756 9.157a.25.25 0 0 0-.075.33l.447.775a.25.25 0 0 0 .325.1l1.598-.769-.83-1.436-1.465 1Z\"></path>\n</svg>\n        </span>\n      \n        <span data-view-component=\"true\" class=\"ActionListItem-label\">\n          Explore\n</span></a>\n  \n</li>\n\n        \n          \n<li data-item-id=\"\" data-targets=\"nav-list.items\" data-view-component=\"true\" class=\"ActionListItem\">\n    \n    \n    <a data-analytics-event=\"{&quot;category&quot;:&quot;Global navigation&quot;,&quot;action&quot;:&quot;MARKETPLACE&quot;,&quot;label&quot;:null}\" id=\"item-e2af73ac-9f51-4960-8d20-b4f5169810a9\" href=\"/marketplace\" data-view-component=\"true\" class=\"ActionListContent ActionListContent--visual16\">\n        <span class=\"ActionListItem-visual ActionListItem-visual--leading\">\n          <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-gift\">\n    <path d=\"M2 2.75A2.75 2.75 0 0 1 4.75 0c.983 0 1.873.42 2.57 1.232.268.318.497.668.68 1.042.183-.375.411-.725.68-1.044C9.376.42 10.266 0 11.25 0a2.75 2.75 0 0 1 2.45 4h.55c.966 0 1.75.784 1.75 1.75v2c0 .698-.409 1.301-1 1.582v4.918A1.75 1.75 0 0 1 13.25 16H2.75A1.75 1.75 0 0 1 1 14.25V9.332C.409 9.05 0 8.448 0 7.75v-2C0 4.784.784 4 1.75 4h.55c-.192-.375-.3-.8-.3-1.25ZM7.25 9.5H2.5v4.75c0 .138.112.25.25.25h4.5Zm1.5 0v5h4.5a.25.25 0 0 0 .25-.25V9.5Zm0-4V8h5.5a.25.25 0 0 0 .25-.25v-2a.25.25 0 0 0-.25-.25Zm-7 0a.25.25 0 0 0-.25.25v2c0 .138.112.25.25.25h5.5V5.5h-5.5Zm3-4a1.25 1.25 0 0 0 0 2.5h2.309c-.233-.818-.542-1.401-.878-1.793-.43-.502-.915-.707-1.431-.707ZM8.941 4h2.309a1.25 1.25 0 0 0 0-2.5c-.516 0-1 .205-1.43.707-.337.392-.646.975-.879 1.793Z\"></path>\n</svg>\n        </span>\n      \n        <span data-view-component=\"true\" class=\"ActionListItem-label\">\n          Marketplace\n</span></a>\n  \n</li>\n\n</ul>  </nav-list>\n</nav>\n\n        <div data-view-component=\"true\" class=\"my-3 d-flex flex-justify-center height-full\">\n          <svg style=\"box-sizing: content-box; color: var(--color-icon-primary);\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" data-view-component=\"true\" class=\"anim-rotate\">\n  <circle cx=\"8\" cy=\"8\" r=\"7\" stroke=\"currentColor\" stroke-opacity=\"0.25\" stroke-width=\"2\" vector-effect=\"non-scaling-stroke\" fill=\"none\" />\n  <path d=\"M15 8a7.002 7.002 0 00-7-7\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" vector-effect=\"non-scaling-stroke\" />\n</svg>\n</div>\n</div>\n      <div data-view-component=\"true\" class=\"flex-1\"></div>\n\n\n      <div data-view-component=\"true\" class=\"px-2\">      <p class=\"color-fg-subtle text-small text-light\">&copy; 2024 GitHub, Inc.</p>\n\n      <div data-view-component=\"true\" class=\"d-flex flex-wrap text-small text-light\">\n          <a target=\"_blank\" href=\"https://github.com/about\" data-view-component=\"true\" class=\"Link mr-2\">About</a>\n          <a target=\"_blank\" href=\"https://github.blog\" data-view-component=\"true\" class=\"Link mr-2\">Blog</a>\n          <a target=\"_blank\" href=\"https://docs.github.com/site-policy/github-terms/github-terms-of-service\" data-view-component=\"true\" class=\"Link mr-2\">Terms</a>\n          <a target=\"_blank\" href=\"https://docs.github.com/site-policy/privacy-policies/github-privacy-statement\" data-view-component=\"true\" class=\"Link mr-2\">Privacy</a>\n          <a target=\"_blank\" href=\"https://github.com/security\" data-view-component=\"true\" class=\"Link mr-2\">Security</a>\n          <a target=\"_blank\" href=\"https://www.githubstatus.com/\" data-view-component=\"true\" class=\"Link mr-3\">Status</a>\n\n</div></div>\n</div>\n      </scrollable-region>\n      \n</dialog></dialog-helper>\n\n  </include-fragment>\n</deferred-side-panel>\n\n        <a\n          class=\"AppHeader-logo ml-2\"\n          href=\"https://github.com/\"\n          data-hotkey=\"g d\"\n          aria-label=\"Homepage \"\n          data-turbo=\"false\"\n          data-analytics-event=\"{&quot;category&quot;:&quot;Header&quot;,&quot;action&quot;:&quot;go to dashboard&quot;,&quot;label&quot;:&quot;icon:logo&quot;}\"\n        >\n          <svg height=\"32\" aria-hidden=\"true\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"32\" data-view-component=\"true\" class=\"octicon octicon-mark-github v-align-middle color-fg-default\">\n    <path d=\"M8 0c4.42 0 8 3.58 8 8a8.013 8.013 0 0 1-5.45 7.59c-.4.08-.55-.17-.55-.38 0-.27.01-1.13.01-2.2 0-.75-.25-1.23-.54-1.48 1.78-.2 3.65-.88 3.65-3.95 0-.88-.31-1.59-.82-2.15.08-.2.36-1.02-.08-2.12 0 0-.67-.22-2.2.82-.64-.18-1.32-.27-2-.27-.68 0-1.36.09-2 .27-1.53-1.03-2.2-.82-2.2-.82-.44 1.1-.16 1.92-.08 2.12-.51.56-.82 1.28-.82 2.15 0 3.06 1.86 3.75 3.64 3.95-.23.2-.44.55-.51 1.07-.46.21-1.61.55-2.33-.66-.15-.24-.6-.83-1.23-.82-.67.01-.27.38.01.53.34.19.73.9.82 1.13.16.45.68 1.31 2.69.94 0 .67.01 1.3.01 1.49 0 .21-.15.45-.55.38A7.995 7.995 0 0 1 0 8c0-4.42 3.58-8 8-8Z\"></path>\n</svg>\n        </a>\n\n          <div class=\"AppHeader-context\" >\n  <div class=\"AppHeader-context-compact\">\n      <button aria-expanded=\"false\" aria-haspopup=\"dialog\" aria-label=\"Page context: mouredev / roadmap-retos-programacion\" id=\"dialog-show-context-region-dialog\" data-show-dialog-id=\"context-region-dialog\" type=\"button\" data-view-component=\"true\" class=\"AppHeader-context-compact-trigger Truncate Button--secondary Button--medium Button box-shadow-none\">  <span class=\"Button-content\">\n    <span class=\"Button-label\"><span class=\"AppHeader-context-compact-lead\">\n                <span class=\"AppHeader-context-compact-parentItem\">mouredev</span>\n                <span class=\"no-wrap\">&nbsp;/</span>\n\n            </span>\n\n            <strong class=\"AppHeader-context-compact-mainItem d-flex flex-items-center Truncate\" >\n  <span class=\"Truncate-text \">roadmap-retos-programacion</span>\n\n</strong></span>\n  </span>\n</button>\n\n<dialog-helper>\n  <dialog id=\"context-region-dialog\" aria-modal=\"true\" aria-labelledby=\"context-region-dialog-title\" aria-describedby=\"context-region-dialog-description\" data-view-component=\"true\" class=\"Overlay Overlay-whenNarrow Overlay--size-medium Overlay--motion-scaleFade\">\n    <div data-view-component=\"true\" class=\"Overlay-header\">\n  <div class=\"Overlay-headerContentWrap\">\n    <div class=\"Overlay-titleWrap\">\n      <h1 class=\"Overlay-title \" id=\"context-region-dialog-title\">\n        Navigate back to\n      </h1>\n        \n    </div>\n    <div class=\"Overlay-actionWrap\">\n      <button data-close-dialog-id=\"context-region-dialog\" aria-label=\"Close\" type=\"button\" data-view-component=\"true\" class=\"close-button Overlay-closeButton\"><svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-x\">\n    <path d=\"M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z\"></path>\n</svg></button>\n    </div>\n  </div>\n  \n</div>\n      <scrollable-region data-labelled-by=\"context-region-dialog-title\">\n        <div data-view-component=\"true\" class=\"Overlay-body\">          <ul role=\"list\" class=\"list-style-none\" >\n    <li>\n      <a data-analytics-event=\"{&quot;category&quot;:&quot;SiteHeaderComponent&quot;,&quot;action&quot;:&quot;context_region_crumb&quot;,&quot;label&quot;:&quot;mouredev&quot;,&quot;screen_size&quot;:&quot;compact&quot;}\" href=\"/mouredev\" data-view-component=\"true\" class=\"Link--primary Truncate d-flex flex-items-center py-1\">\n        <span class=\"AppHeader-context-item-label Truncate-text \">\n            <svg aria-hidden=\"true\" height=\"12\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"12\" data-view-component=\"true\" class=\"octicon octicon-person mr-1\">\n    <path d=\"M10.561 8.073a6.005 6.005 0 0 1 3.432 5.142.75.75 0 1 1-1.498.07 4.5 4.5 0 0 0-8.99 0 .75.75 0 0 1-1.498-.07 6.004 6.004 0 0 1 3.431-5.142 3.999 3.999 0 1 1 5.123 0ZM10.5 5a2.5 2.5 0 1 0-5 0 2.5 2.5 0 0 0 5 0Z\"></path>\n</svg>\n\n          mouredev\n        </span>\n\n</a>\n    </li>\n    <li>\n      <a data-analytics-event=\"{&quot;category&quot;:&quot;SiteHeaderComponent&quot;,&quot;action&quot;:&quot;context_region_crumb&quot;,&quot;label&quot;:&quot;roadmap-retos-programacion&quot;,&quot;screen_size&quot;:&quot;compact&quot;}\" href=\"/mouredev/roadmap-retos-programacion\" data-view-component=\"true\" class=\"Link--primary Truncate d-flex flex-items-center py-1\">\n        <span class=\"AppHeader-context-item-label Truncate-text \">\n            <svg aria-hidden=\"true\" height=\"12\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"12\" data-view-component=\"true\" class=\"octicon octicon-repo mr-1\">\n    <path d=\"M2 2.5A2.5 2.5 0 0 1 4.5 0h8.75a.75.75 0 0 1 .75.75v12.5a.75.75 0 0 1-.75.75h-2.5a.75.75 0 0 1 0-1.5h1.75v-2h-8a1 1 0 0 0-.714 1.7.75.75 0 1 1-1.072 1.05A2.495 2.495 0 0 1 2 11.5Zm10.5-1h-8a1 1 0 0 0-1 1v6.708A2.486 2.486 0 0 1 4.5 9h8ZM5 12.25a.25.25 0 0 1 .25-.25h3.5a.25.25 0 0 1 .25.25v3.25a.25.25 0 0 1-.4.2l-1.45-1.087a.249.249 0 0 0-.3 0L5.4 15.7a.25.25 0 0 1-.4-.2Z\"></path>\n</svg>\n\n          roadmap-retos-programacion\n        </span>\n\n</a>\n    </li>\n</ul>\n\n</div>\n      </scrollable-region>\n      \n</dialog></dialog-helper>\n  </div>\n\n  <div class=\"AppHeader-context-full\">\n    <nav role=\"navigation\" aria-label=\"Page context\">\n      <ul role=\"list\" class=\"list-style-none\" >\n    <li>\n      <a data-analytics-event=\"{&quot;category&quot;:&quot;SiteHeaderComponent&quot;,&quot;action&quot;:&quot;context_region_crumb&quot;,&quot;label&quot;:&quot;mouredev&quot;,&quot;screen_size&quot;:&quot;full&quot;}\" data-hovercard-type=\"user\" data-hovercard-url=\"/users/mouredev/hovercard\" data-octo-click=\"hovercard-link-click\" data-octo-dimensions=\"link_type:self\" href=\"/mouredev\" data-view-component=\"true\" class=\"AppHeader-context-item\">\n        <span class=\"AppHeader-context-item-label  \">\n\n          mouredev\n        </span>\n\n</a>\n        <span class=\"AppHeader-context-item-separator\">/</span>\n    </li>\n    <li>\n      <a data-analytics-event=\"{&quot;category&quot;:&quot;SiteHeaderComponent&quot;,&quot;action&quot;:&quot;context_region_crumb&quot;,&quot;label&quot;:&quot;roadmap-retos-programacion&quot;,&quot;screen_size&quot;:&quot;full&quot;}\" href=\"/mouredev/roadmap-retos-programacion\" data-view-component=\"true\" class=\"AppHeader-context-item\">\n        <span class=\"AppHeader-context-item-label  \">\n\n          roadmap-retos-programacion\n        </span>\n\n</a>\n    </li>\n</ul>\n\n    </nav>\n  </div>\n</div>\n\n      </div>\n      <div class=\"AppHeader-globalBar-end\">\n          <div class=\"AppHeader-search\" >\n              \n\n\n<qbsearch-input class=\"search-input\" data-scope=\"repo:mouredev/roadmap-retos-programacion\" data-custom-scopes-path=\"/search/custom_scopes\" data-delete-custom-scopes-csrf=\"wvobtbAxNSwrWLSK5Xwjw4B1n5x-FCIoI8AFuBDfJ7z-JVMk5MbQU-Dh3d3sKTkek_5iFQm9EEwOXETrUq-CFA\" data-max-custom-scopes=\"10\" data-header-redesign-enabled=\"true\" data-initial-value=\"\" data-blackbird-suggestions-path=\"/search/suggestions\" data-jump-to-suggestions-path=\"/_graphql/GetSuggestedNavigationDestinations\" data-current-repository=\"mouredev/roadmap-retos-programacion\" data-current-org=\"\" data-current-owner=\"mouredev\" data-logged-in=\"true\" data-copilot-chat-enabled=\"false\" data-blackbird-indexed-repo-csrf=\"<input type=&quot;hidden&quot; value=&quot;r4rgw8A8FacpbW0rlde9JGyGpH6TXlI85Mre9Yrc1E9y0Ch-7we-P-pYX5WVnFlthY8yl_KO4OvZ4Yz5ibFGhw&quot; data-csrf=&quot;true&quot; />\">\n  <div\n    class=\"search-input-container search-with-dialog position-relative d-flex flex-row flex-items-center height-auto color-bg-transparent border-0 color-fg-subtle mx-0\"\n    data-action=\"click:qbsearch-input#searchInputContainerClicked\"\n  >\n      \n            <button type=\"button\" data-action=\"click:qbsearch-input#handleExpand\" class=\"AppHeader-button AppHeader-search-whenNarrow\" aria-label=\"Search or jump to…\" aria-expanded=\"false\" aria-haspopup=\"dialog\">\n            <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-search\">\n    <path d=\"M10.68 11.74a6 6 0 0 1-7.922-8.982 6 6 0 0 1 8.982 7.922l3.04 3.04a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215ZM11.5 7a4.499 4.499 0 1 0-8.997 0A4.499 4.499 0 0 0 11.5 7Z\"></path>\n</svg>\n          </button>\n\n\n<div class=\"AppHeader-search-whenRegular\">\n  <div class=\"AppHeader-search-wrap AppHeader-search-wrap--hasTrailing\">\n    <div class=\"AppHeader-search-control\">\n      <label\n        for=\"AppHeader-searchInput\"\n        aria-label=\"Search or jump to…\"\n        class=\"AppHeader-search-visual--leading\"\n      >\n        <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-search\">\n    <path d=\"M10.68 11.74a6 6 0 0 1-7.922-8.982 6 6 0 0 1 8.982 7.922l3.04 3.04a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215ZM11.5 7a4.499 4.499 0 1 0-8.997 0A4.499 4.499 0 0 0 11.5 7Z\"></path>\n</svg>\n      </label>\n\n                <button\n            type=\"button\"\n            data-target=\"qbsearch-input.inputButton\"\n            data-action=\"click:qbsearch-input#handleExpand\"\n            class=\"AppHeader-searchButton form-control input-contrast text-left color-fg-subtle no-wrap\"\n            data-hotkey=\"s,/\"\n            data-analytics-event=\"{&quot;category&quot;:&quot;Global navigation&quot;,&quot;action&quot;:&quot;SEARCH&quot;,&quot;label&quot;:null}\"\n            aria-describedby=\"search-error-message-flash\"\n          >\n            <div class=\"overflow-hidden\">\n              <span id=\"qb-input-query\" data-target=\"qbsearch-input.inputButtonText\">\n                  Type <kbd class=\"AppHeader-search-kbd\">/</kbd> to search\n              </span>\n            </div>\n          </button>\n\n    </div>\n\n\n      <button type=\"button\" id=\"AppHeader-commandPalette-button\" class=\"AppHeader-search-action--trailing js-activate-command-palette\" data-analytics-event=\"{&quot;category&quot;:&quot;SiteHeaderComponent&quot;,&quot;action&quot;:&quot;command_palette&quot;,&quot;label&quot;:&quot;open command palette&quot;}\">\n        <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-command-palette\">\n    <path d=\"m6.354 8.04-4.773 4.773a.75.75 0 1 0 1.061 1.06L7.945 8.57a.75.75 0 0 0 0-1.06L2.642 2.206a.75.75 0 0 0-1.06 1.061L6.353 8.04ZM8.75 11.5a.75.75 0 0 0 0 1.5h5.5a.75.75 0 0 0 0-1.5h-5.5Z\"></path>\n</svg>\n      </button>\n\n      <tool-tip id=\"tooltip-b4438194-058d-4b8a-a60d-faa36fefc872\" for=\"AppHeader-commandPalette-button\" popover=\"manual\" data-direction=\"s\" data-type=\"label\" data-view-component=\"true\" class=\"sr-only position-absolute\">Command palette</tool-tip>\n  </div>\n</div>\n\n    <input type=\"hidden\" name=\"type\" class=\"js-site-search-type-field\">\n\n    \n<div class=\"Overlay--hidden \" data-modal-dialog-overlay>\n  <modal-dialog data-action=\"close:qbsearch-input#handleClose cancel:qbsearch-input#handleClose\" data-target=\"qbsearch-input.searchSuggestionsDialog\" role=\"dialog\" id=\"search-suggestions-dialog\" aria-modal=\"true\" aria-labelledby=\"search-suggestions-dialog-header\" data-view-component=\"true\" class=\"Overlay Overlay--width-medium Overlay--height-auto\">\n      <h1 id=\"search-suggestions-dialog-header\" class=\"sr-only\">Search code, repositories, users, issues, pull requests...</h1>\n    <div class=\"Overlay-body Overlay-body--paddingNone\">\n      \n          <div data-view-component=\"true\">        <div class=\"search-suggestions position-absolute width-full color-shadow-large border color-fg-default color-bg-default overflow-hidden d-flex flex-column query-builder-container\"\n          style=\"border-radius: 12px;\"\n          data-target=\"qbsearch-input.queryBuilderContainer\"\n          hidden\n        >\n          <!-- '\"` --><!-- </textarea></xmp> --></option></form><form id=\"query-builder-test-form\" action=\"\" accept-charset=\"UTF-8\" method=\"get\">\n  <query-builder data-target=\"qbsearch-input.queryBuilder\" id=\"query-builder-query-builder-test\" data-filter-key=\":\" data-view-component=\"true\" class=\"QueryBuilder search-query-builder\">\n    <div class=\"FormControl FormControl--fullWidth\">\n      <label id=\"query-builder-test-label\" for=\"query-builder-test\" class=\"FormControl-label sr-only\">\n        Search\n      </label>\n      <div\n        class=\"QueryBuilder-StyledInput width-fit \"\n        data-target=\"query-builder.styledInput\"\n      >\n          <span id=\"query-builder-test-leadingvisual-wrap\" class=\"FormControl-input-leadingVisualWrap QueryBuilder-leadingVisualWrap\">\n            <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-search FormControl-input-leadingVisual\">\n    <path d=\"M10.68 11.74a6 6 0 0 1-7.922-8.982 6 6 0 0 1 8.982 7.922l3.04 3.04a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215ZM11.5 7a4.499 4.499 0 1 0-8.997 0A4.499 4.499 0 0 0 11.5 7Z\"></path>\n</svg>\n          </span>\n        <div data-target=\"query-builder.styledInputContainer\" class=\"QueryBuilder-StyledInputContainer\">\n          <div\n            aria-hidden=\"true\"\n            class=\"QueryBuilder-StyledInputContent\"\n            data-target=\"query-builder.styledInputContent\"\n          ></div>\n          <div class=\"QueryBuilder-InputWrapper\">\n            <div aria-hidden=\"true\" class=\"QueryBuilder-Sizer\" data-target=\"query-builder.sizer\"></div>\n            <input id=\"query-builder-test\" name=\"query-builder-test\" value=\"\" autocomplete=\"off\" type=\"text\" role=\"combobox\" spellcheck=\"false\" aria-expanded=\"false\" aria-describedby=\"validation-25130bc6-7deb-4401-bf40-5353d351cfe9\" data-target=\"query-builder.input\" data-action=\"\n          input:query-builder#inputChange\n          blur:query-builder#inputBlur\n          keydown:query-builder#inputKeydown\n          focus:query-builder#inputFocus\n        \" data-view-component=\"true\" class=\"FormControl-input QueryBuilder-Input FormControl-medium\" />\n          </div>\n        </div>\n          <span class=\"sr-only\" id=\"query-builder-test-clear\">Clear</span>\n          <button role=\"button\" id=\"query-builder-test-clear-button\" aria-labelledby=\"query-builder-test-clear query-builder-test-label\" data-target=\"query-builder.clearButton\" data-action=\"\n                click:query-builder#clear\n                focus:query-builder#clearButtonFocus\n                blur:query-builder#clearButtonBlur\n              \" variant=\"small\" hidden=\"hidden\" type=\"button\" data-view-component=\"true\" class=\"Button Button--iconOnly Button--invisible Button--medium mr-1 px-2 py-0 d-flex flex-items-center rounded-1 color-fg-muted\">  <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-x-circle-fill Button-visual\">\n    <path d=\"M2.343 13.657A8 8 0 1 1 13.658 2.343 8 8 0 0 1 2.343 13.657ZM6.03 4.97a.751.751 0 0 0-1.042.018.751.751 0 0 0-.018 1.042L6.94 8 4.97 9.97a.749.749 0 0 0 .326 1.275.749.749 0 0 0 .734-.215L8 9.06l1.97 1.97a.749.749 0 0 0 1.275-.326.749.749 0 0 0-.215-.734L9.06 8l1.97-1.97a.749.749 0 0 0-.326-1.275.749.749 0 0 0-.734.215L8 6.94Z\"></path>\n</svg>\n</button>\n\n      </div>\n      <template id=\"search-icon\">\n  <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-search\">\n    <path d=\"M10.68 11.74a6 6 0 0 1-7.922-8.982 6 6 0 0 1 8.982 7.922l3.04 3.04a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215ZM11.5 7a4.499 4.499 0 1 0-8.997 0A4.499 4.499 0 0 0 11.5 7Z\"></path>\n</svg>\n</template>\n\n<template id=\"code-icon\">\n  <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-code\">\n    <path d=\"m11.28 3.22 4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L13.94 8l-3.72-3.72a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215Zm-6.56 0a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L2.06 8l3.72 3.72a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L.47 8.53a.75.75 0 0 1 0-1.06Z\"></path>\n</svg>\n</template>\n\n<template id=\"file-code-icon\">\n  <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-file-code\">\n    <path d=\"M4 1.75C4 .784 4.784 0 5.75 0h5.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v8.586A1.75 1.75 0 0 1 14.25 15h-9a.75.75 0 0 1 0-1.5h9a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 10 4.25V1.5H5.75a.25.25 0 0 0-.25.25v2.5a.75.75 0 0 1-1.5 0Zm1.72 4.97a.75.75 0 0 1 1.06 0l2 2a.75.75 0 0 1 0 1.06l-2 2a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734l1.47-1.47-1.47-1.47a.75.75 0 0 1 0-1.06ZM3.28 7.78 1.81 9.25l1.47 1.47a.751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018l-2-2a.75.75 0 0 1 0-1.06l2-2a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Zm8.22-6.218V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z\"></path>\n</svg>\n</template>\n\n<template id=\"history-icon\">\n  <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-history\">\n    <path d=\"m.427 1.927 1.215 1.215a8.002 8.002 0 1 1-1.6 5.685.75.75 0 1 1 1.493-.154 6.5 6.5 0 1 0 1.18-4.458l1.358 1.358A.25.25 0 0 1 3.896 6H.25A.25.25 0 0 1 0 5.75V2.104a.25.25 0 0 1 .427-.177ZM7.75 4a.75.75 0 0 1 .75.75v2.992l2.028.812a.75.75 0 0 1-.557 1.392l-2.5-1A.751.751 0 0 1 7 8.25v-3.5A.75.75 0 0 1 7.75 4Z\"></path>\n</svg>\n</template>\n\n<template id=\"repo-icon\">\n  <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-repo\">\n    <path d=\"M2 2.5A2.5 2.5 0 0 1 4.5 0h8.75a.75.75 0 0 1 .75.75v12.5a.75.75 0 0 1-.75.75h-2.5a.75.75 0 0 1 0-1.5h1.75v-2h-8a1 1 0 0 0-.714 1.7.75.75 0 1 1-1.072 1.05A2.495 2.495 0 0 1 2 11.5Zm10.5-1h-8a1 1 0 0 0-1 1v6.708A2.486 2.486 0 0 1 4.5 9h8ZM5 12.25a.25.25 0 0 1 .25-.25h3.5a.25.25 0 0 1 .25.25v3.25a.25.25 0 0 1-.4.2l-1.45-1.087a.249.249 0 0 0-.3 0L5.4 15.7a.25.25 0 0 1-.4-.2Z\"></path>\n</svg>\n</template>\n\n<template id=\"bookmark-icon\">\n  <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-bookmark\">\n    <path d=\"M3 2.75C3 1.784 3.784 1 4.75 1h6.5c.966 0 1.75.784 1.75 1.75v11.5a.75.75 0 0 1-1.227.579L8 11.722l-3.773 3.107A.751.751 0 0 1 3 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v9.91l3.023-2.489a.75.75 0 0 1 .954 0l3.023 2.49V2.75a.25.25 0 0 0-.25-.25Z\"></path>\n</svg>\n</template>\n\n<template id=\"plus-circle-icon\">\n  <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-plus-circle\">\n    <path d=\"M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Zm7.25-3.25v2.5h2.5a.75.75 0 0 1 0 1.5h-2.5v2.5a.75.75 0 0 1-1.5 0v-2.5h-2.5a.75.75 0 0 1 0-1.5h2.5v-2.5a.75.75 0 0 1 1.5 0Z\"></path>\n</svg>\n</template>\n\n<template id=\"circle-icon\">\n  <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-dot-fill\">\n    <path d=\"M8 4a4 4 0 1 1 0 8 4 4 0 0 1 0-8Z\"></path>\n</svg>\n</template>\n\n<template id=\"trash-icon\">\n  <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-trash\">\n    <path d=\"M11 1.75V3h2.25a.75.75 0 0 1 0 1.5H2.75a.75.75 0 0 1 0-1.5H5V1.75C5 .784 5.784 0 6.75 0h2.5C10.216 0 11 .784 11 1.75ZM4.496 6.675l.66 6.6a.25.25 0 0 0 .249.225h5.19a.25.25 0 0 0 .249-.225l.66-6.6a.75.75 0 0 1 1.492.149l-.66 6.6A1.748 1.748 0 0 1 10.595 15h-5.19a1.75 1.75 0 0 1-1.741-1.575l-.66-6.6a.75.75 0 1 1 1.492-.15ZM6.5 1.75V3h3V1.75a.25.25 0 0 0-.25-.25h-2.5a.25.25 0 0 0-.25.25Z\"></path>\n</svg>\n</template>\n\n<template id=\"team-icon\">\n  <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-people\">\n    <path d=\"M2 5.5a3.5 3.5 0 1 1 5.898 2.549 5.508 5.508 0 0 1 3.034 4.084.75.75 0 1 1-1.482.235 4 4 0 0 0-7.9 0 .75.75 0 0 1-1.482-.236A5.507 5.507 0 0 1 3.102 8.05 3.493 3.493 0 0 1 2 5.5ZM11 4a3.001 3.001 0 0 1 2.22 5.018 5.01 5.01 0 0 1 2.56 3.012.749.749 0 0 1-.885.954.752.752 0 0 1-.549-.514 3.507 3.507 0 0 0-2.522-2.372.75.75 0 0 1-.574-.73v-.352a.75.75 0 0 1 .416-.672A1.5 1.5 0 0 0 11 5.5.75.75 0 0 1 11 4Zm-5.5-.5a2 2 0 1 0-.001 3.999A2 2 0 0 0 5.5 3.5Z\"></path>\n</svg>\n</template>\n\n<template id=\"project-icon\">\n  <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-project\">\n    <path d=\"M1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25V1.75C0 .784.784 0 1.75 0ZM1.5 1.75v12.5c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25H1.75a.25.25 0 0 0-.25.25ZM11.75 3a.75.75 0 0 1 .75.75v7.5a.75.75 0 0 1-1.5 0v-7.5a.75.75 0 0 1 .75-.75Zm-8.25.75a.75.75 0 0 1 1.5 0v5.5a.75.75 0 0 1-1.5 0ZM8 3a.75.75 0 0 1 .75.75v3.5a.75.75 0 0 1-1.5 0v-3.5A.75.75 0 0 1 8 3Z\"></path>\n</svg>\n</template>\n\n<template id=\"pencil-icon\">\n  <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-pencil\">\n    <path d=\"M11.013 1.427a1.75 1.75 0 0 1 2.474 0l1.086 1.086a1.75 1.75 0 0 1 0 2.474l-8.61 8.61c-.21.21-.47.364-.756.445l-3.251.93a.75.75 0 0 1-.927-.928l.929-3.25c.081-.286.235-.547.445-.758l8.61-8.61Zm.176 4.823L9.75 4.81l-6.286 6.287a.253.253 0 0 0-.064.108l-.558 1.953 1.953-.558a.253.253 0 0 0 .108-.064Zm1.238-3.763a.25.25 0 0 0-.354 0L10.811 3.75l1.439 1.44 1.263-1.263a.25.25 0 0 0 0-.354Z\"></path>\n</svg>\n</template>\n\n<template id=\"copilot-icon\">\n  <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-copilot\">\n    <path d=\"M7.998 15.035c-4.562 0-7.873-2.914-7.998-3.749V9.338c.085-.628.677-1.686 1.588-2.065.013-.07.024-.143.036-.218.029-.183.06-.384.126-.612-.201-.508-.254-1.084-.254-1.656 0-.87.128-1.769.693-2.484.579-.733 1.494-1.124 2.724-1.261 1.206-.134 2.262.034 2.944.765.05.053.096.108.139.165.044-.057.094-.112.143-.165.682-.731 1.738-.899 2.944-.765 1.23.137 2.145.528 2.724 1.261.566.715.693 1.614.693 2.484 0 .572-.053 1.148-.254 1.656.066.228.098.429.126.612.012.076.024.148.037.218.924.385 1.522 1.471 1.591 2.095v1.872c0 .766-3.351 3.795-8.002 3.795Zm0-1.485c2.28 0 4.584-1.11 5.002-1.433V7.862l-.023-.116c-.49.21-1.075.291-1.727.291-1.146 0-2.059-.327-2.71-.991A3.222 3.222 0 0 1 8 6.303a3.24 3.24 0 0 1-.544.743c-.65.664-1.563.991-2.71.991-.652 0-1.236-.081-1.727-.291l-.023.116v4.255c.419.323 2.722 1.433 5.002 1.433ZM6.762 2.83c-.193-.206-.637-.413-1.682-.297-1.019.113-1.479.404-1.713.7-.247.312-.369.789-.369 1.554 0 .793.129 1.171.308 1.371.162.181.519.379 1.442.379.853 0 1.339-.235 1.638-.54.315-.322.527-.827.617-1.553.117-.935-.037-1.395-.241-1.614Zm4.155-.297c-1.044-.116-1.488.091-1.681.297-.204.219-.359.679-.242 1.614.091.726.303 1.231.618 1.553.299.305.784.54 1.638.54.922 0 1.28-.198 1.442-.379.179-.2.308-.578.308-1.371 0-.765-.123-1.242-.37-1.554-.233-.296-.693-.587-1.713-.7Z\"></path><path d=\"M6.25 9.037a.75.75 0 0 1 .75.75v1.501a.75.75 0 0 1-1.5 0V9.787a.75.75 0 0 1 .75-.75Zm4.25.75v1.501a.75.75 0 0 1-1.5 0V9.787a.75.75 0 0 1 1.5 0Z\"></path>\n</svg>\n</template>\n\n<template id=\"workflow-icon\">\n  <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-workflow\">\n    <path d=\"M0 1.75C0 .784.784 0 1.75 0h3.5C6.216 0 7 .784 7 1.75v3.5A1.75 1.75 0 0 1 5.25 7H4v4a1 1 0 0 0 1 1h4v-1.25C9 9.784 9.784 9 10.75 9h3.5c.966 0 1.75.784 1.75 1.75v3.5A1.75 1.75 0 0 1 14.25 16h-3.5A1.75 1.75 0 0 1 9 14.25v-.75H5A2.5 2.5 0 0 1 2.5 11V7h-.75A1.75 1.75 0 0 1 0 5.25Zm1.75-.25a.25.25 0 0 0-.25.25v3.5c0 .138.112.25.25.25h3.5a.25.25 0 0 0 .25-.25v-3.5a.25.25 0 0 0-.25-.25Zm9 9a.25.25 0 0 0-.25.25v3.5c0 .138.112.25.25.25h3.5a.25.25 0 0 0 .25-.25v-3.5a.25.25 0 0 0-.25-.25Z\"></path>\n</svg>\n</template>\n\n<template id=\"book-icon\">\n  <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-book\">\n    <path d=\"M0 1.75A.75.75 0 0 1 .75 1h4.253c1.227 0 2.317.59 3 1.501A3.743 3.743 0 0 1 11.006 1h4.245a.75.75 0 0 1 .75.75v10.5a.75.75 0 0 1-.75.75h-4.507a2.25 2.25 0 0 0-1.591.659l-.622.621a.75.75 0 0 1-1.06 0l-.622-.621A2.25 2.25 0 0 0 5.258 13H.75a.75.75 0 0 1-.75-.75Zm7.251 10.324.004-5.073-.002-2.253A2.25 2.25 0 0 0 5.003 2.5H1.5v9h3.757a3.75 3.75 0 0 1 1.994.574ZM8.755 4.75l-.004 7.322a3.752 3.752 0 0 1 1.992-.572H14.5v-9h-3.495a2.25 2.25 0 0 0-2.25 2.25Z\"></path>\n</svg>\n</template>\n\n<template id=\"code-review-icon\">\n  <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-code-review\">\n    <path d=\"M1.75 1h12.5c.966 0 1.75.784 1.75 1.75v8.5A1.75 1.75 0 0 1 14.25 13H8.061l-2.574 2.573A1.458 1.458 0 0 1 3 14.543V13H1.75A1.75 1.75 0 0 1 0 11.25v-8.5C0 1.784.784 1 1.75 1ZM1.5 2.75v8.5c0 .138.112.25.25.25h2a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h6.5a.25.25 0 0 0 .25-.25v-8.5a.25.25 0 0 0-.25-.25H1.75a.25.25 0 0 0-.25.25Zm5.28 1.72a.75.75 0 0 1 0 1.06L5.31 7l1.47 1.47a.751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018l-2-2a.75.75 0 0 1 0-1.06l2-2a.75.75 0 0 1 1.06 0Zm2.44 0a.75.75 0 0 1 1.06 0l2 2a.75.75 0 0 1 0 1.06l-2 2a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L10.69 7 9.22 5.53a.75.75 0 0 1 0-1.06Z\"></path>\n</svg>\n</template>\n\n<template id=\"codespaces-icon\">\n  <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-codespaces\">\n    <path d=\"M0 11.25c0-.966.784-1.75 1.75-1.75h12.5c.966 0 1.75.784 1.75 1.75v3A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25Zm2-9.5C2 .784 2.784 0 3.75 0h8.5C13.216 0 14 .784 14 1.75v5a1.75 1.75 0 0 1-1.75 1.75h-8.5A1.75 1.75 0 0 1 2 6.75Zm1.75-.25a.25.25 0 0 0-.25.25v5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-5a.25.25 0 0 0-.25-.25Zm-2 9.5a.25.25 0 0 0-.25.25v3c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25v-3a.25.25 0 0 0-.25-.25Z\"></path><path d=\"M7 12.75a.75.75 0 0 1 .75-.75h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1-.75-.75Zm-4 0a.75.75 0 0 1 .75-.75h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1-.75-.75Z\"></path>\n</svg>\n</template>\n\n<template id=\"comment-icon\">\n  <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-comment\">\n    <path d=\"M1 2.75C1 1.784 1.784 1 2.75 1h10.5c.966 0 1.75.784 1.75 1.75v7.5A1.75 1.75 0 0 1 13.25 12H9.06l-2.573 2.573A1.458 1.458 0 0 1 4 13.543V12H2.75A1.75 1.75 0 0 1 1 10.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h2a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h4.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z\"></path>\n</svg>\n</template>\n\n<template id=\"comment-discussion-icon\">\n  <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-comment-discussion\">\n    <path d=\"M1.75 1h8.5c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 10.25 10H7.061l-2.574 2.573A1.458 1.458 0 0 1 2 11.543V10h-.25A1.75 1.75 0 0 1 0 8.25v-5.5C0 1.784.784 1 1.75 1ZM1.5 2.75v5.5c0 .138.112.25.25.25h1a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h3.5a.25.25 0 0 0 .25-.25v-5.5a.25.25 0 0 0-.25-.25h-8.5a.25.25 0 0 0-.25.25Zm13 2a.25.25 0 0 0-.25-.25h-.5a.75.75 0 0 1 0-1.5h.5c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 14.25 12H14v1.543a1.458 1.458 0 0 1-2.487 1.03L9.22 12.28a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215l2.22 2.22v-2.19a.75.75 0 0 1 .75-.75h1a.25.25 0 0 0 .25-.25Z\"></path>\n</svg>\n</template>\n\n<template id=\"organization-icon\">\n  <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-organization\">\n    <path d=\"M1.75 16A1.75 1.75 0 0 1 0 14.25V1.75C0 .784.784 0 1.75 0h8.5C11.216 0 12 .784 12 1.75v12.5c0 .085-.006.168-.018.25h2.268a.25.25 0 0 0 .25-.25V8.285a.25.25 0 0 0-.111-.208l-1.055-.703a.749.749 0 1 1 .832-1.248l1.055.703c.487.325.779.871.779 1.456v5.965A1.75 1.75 0 0 1 14.25 16h-3.5a.766.766 0 0 1-.197-.026c-.099.017-.2.026-.303.026h-3a.75.75 0 0 1-.75-.75V14h-1v1.25a.75.75 0 0 1-.75.75Zm-.25-1.75c0 .138.112.25.25.25H4v-1.25a.75.75 0 0 1 .75-.75h2.5a.75.75 0 0 1 .75.75v1.25h2.25a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25h-8.5a.25.25 0 0 0-.25.25ZM3.75 6h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1 0-1.5ZM3 3.75A.75.75 0 0 1 3.75 3h.5a.75.75 0 0 1 0 1.5h-.5A.75.75 0 0 1 3 3.75Zm4 3A.75.75 0 0 1 7.75 6h.5a.75.75 0 0 1 0 1.5h-.5A.75.75 0 0 1 7 6.75ZM7.75 3h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1 0-1.5ZM3 9.75A.75.75 0 0 1 3.75 9h.5a.75.75 0 0 1 0 1.5h-.5A.75.75 0 0 1 3 9.75ZM7.75 9h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1 0-1.5Z\"></path>\n</svg>\n</template>\n\n<template id=\"rocket-icon\">\n  <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-rocket\">\n    <path d=\"M14.064 0h.186C15.216 0 16 .784 16 1.75v.186a8.752 8.752 0 0 1-2.564 6.186l-.458.459c-.314.314-.641.616-.979.904v3.207c0 .608-.315 1.172-.833 1.49l-2.774 1.707a.749.749 0 0 1-1.11-.418l-.954-3.102a1.214 1.214 0 0 1-.145-.125L3.754 9.816a1.218 1.218 0 0 1-.124-.145L.528 8.717a.749.749 0 0 1-.418-1.11l1.71-2.774A1.748 1.748 0 0 1 3.31 4h3.204c.288-.338.59-.665.904-.979l.459-.458A8.749 8.749 0 0 1 14.064 0ZM8.938 3.623h-.002l-.458.458c-.76.76-1.437 1.598-2.02 2.5l-1.5 2.317 2.143 2.143 2.317-1.5c.902-.583 1.74-1.26 2.499-2.02l.459-.458a7.25 7.25 0 0 0 2.123-5.127V1.75a.25.25 0 0 0-.25-.25h-.186a7.249 7.249 0 0 0-5.125 2.123ZM3.56 14.56c-.732.732-2.334 1.045-3.005 1.148a.234.234 0 0 1-.201-.064.234.234 0 0 1-.064-.201c.103-.671.416-2.273 1.15-3.003a1.502 1.502 0 1 1 2.12 2.12Zm6.94-3.935c-.088.06-.177.118-.266.175l-2.35 1.521.548 1.783 1.949-1.2a.25.25 0 0 0 .119-.213ZM3.678 8.116 5.2 5.766c.058-.09.117-.178.176-.266H3.309a.25.25 0 0 0-.213.119l-1.2 1.95ZM12 5a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\"></path>\n</svg>\n</template>\n\n<template id=\"shield-check-icon\">\n  <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-shield-check\">\n    <path d=\"m8.533.133 5.25 1.68A1.75 1.75 0 0 1 15 3.48V7c0 1.566-.32 3.182-1.303 4.682-.983 1.498-2.585 2.813-5.032 3.855a1.697 1.697 0 0 1-1.33 0c-2.447-1.042-4.049-2.357-5.032-3.855C1.32 10.182 1 8.566 1 7V3.48a1.75 1.75 0 0 1 1.217-1.667l5.25-1.68a1.748 1.748 0 0 1 1.066 0Zm-.61 1.429.001.001-5.25 1.68a.251.251 0 0 0-.174.237V7c0 1.36.275 2.666 1.057 3.859.784 1.194 2.121 2.342 4.366 3.298a.196.196 0 0 0 .154 0c2.245-.957 3.582-2.103 4.366-3.297C13.225 9.666 13.5 8.358 13.5 7V3.48a.25.25 0 0 0-.174-.238l-5.25-1.68a.25.25 0 0 0-.153 0ZM11.28 6.28l-3.5 3.5a.75.75 0 0 1-1.06 0l-1.5-1.5a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215l.97.97 2.97-2.97a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z\"></path>\n</svg>\n</template>\n\n<template id=\"heart-icon\">\n  <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-heart\">\n    <path d=\"m8 14.25.345.666a.75.75 0 0 1-.69 0l-.008-.004-.018-.01a7.152 7.152 0 0 1-.31-.17 22.055 22.055 0 0 1-3.434-2.414C2.045 10.731 0 8.35 0 5.5 0 2.836 2.086 1 4.25 1 5.797 1 7.153 1.802 8 3.02 8.847 1.802 10.203 1 11.75 1 13.914 1 16 2.836 16 5.5c0 2.85-2.045 5.231-3.885 6.818a22.066 22.066 0 0 1-3.744 2.584l-.018.01-.006.003h-.002ZM4.25 2.5c-1.336 0-2.75 1.164-2.75 3 0 2.15 1.58 4.144 3.365 5.682A20.58 20.58 0 0 0 8 13.393a20.58 20.58 0 0 0 3.135-2.211C12.92 9.644 14.5 7.65 14.5 5.5c0-1.836-1.414-3-2.75-3-1.373 0-2.609.986-3.029 2.456a.749.749 0 0 1-1.442 0C6.859 3.486 5.623 2.5 4.25 2.5Z\"></path>\n</svg>\n</template>\n\n<template id=\"server-icon\">\n  <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-server\">\n    <path d=\"M1.75 1h12.5c.966 0 1.75.784 1.75 1.75v4c0 .372-.116.717-.314 1 .198.283.314.628.314 1v4a1.75 1.75 0 0 1-1.75 1.75H1.75A1.75 1.75 0 0 1 0 12.75v-4c0-.358.109-.707.314-1a1.739 1.739 0 0 1-.314-1v-4C0 1.784.784 1 1.75 1ZM1.5 2.75v4c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25v-4a.25.25 0 0 0-.25-.25H1.75a.25.25 0 0 0-.25.25Zm.25 5.75a.25.25 0 0 0-.25.25v4c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25v-4a.25.25 0 0 0-.25-.25ZM7 4.75A.75.75 0 0 1 7.75 4h4.5a.75.75 0 0 1 0 1.5h-4.5A.75.75 0 0 1 7 4.75ZM7.75 10h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1 0-1.5ZM3 4.75A.75.75 0 0 1 3.75 4h.5a.75.75 0 0 1 0 1.5h-.5A.75.75 0 0 1 3 4.75ZM3.75 10h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1 0-1.5Z\"></path>\n</svg>\n</template>\n\n<template id=\"globe-icon\">\n  <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-globe\">\n    <path d=\"M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM5.78 8.75a9.64 9.64 0 0 0 1.363 4.177c.255.426.542.832.857 1.215.245-.296.551-.705.857-1.215A9.64 9.64 0 0 0 10.22 8.75Zm4.44-1.5a9.64 9.64 0 0 0-1.363-4.177c-.307-.51-.612-.919-.857-1.215a9.927 9.927 0 0 0-.857 1.215A9.64 9.64 0 0 0 5.78 7.25Zm-5.944 1.5H1.543a6.507 6.507 0 0 0 4.666 5.5c-.123-.181-.24-.365-.352-.552-.715-1.192-1.437-2.874-1.581-4.948Zm-2.733-1.5h2.733c.144-2.074.866-3.756 1.58-4.948.12-.197.237-.381.353-.552a6.507 6.507 0 0 0-4.666 5.5Zm10.181 1.5c-.144 2.074-.866 3.756-1.58 4.948-.12.197-.237.381-.353.552a6.507 6.507 0 0 0 4.666-5.5Zm2.733-1.5a6.507 6.507 0 0 0-4.666-5.5c.123.181.24.365.353.552.714 1.192 1.436 2.874 1.58 4.948Z\"></path>\n</svg>\n</template>\n\n<template id=\"issue-opened-icon\">\n  <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-issue-opened\">\n    <path d=\"M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z\"></path><path d=\"M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Z\"></path>\n</svg>\n</template>\n\n<template id=\"device-mobile-icon\">\n  <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-device-mobile\">\n    <path d=\"M3.75 0h8.5C13.216 0 14 .784 14 1.75v12.5A1.75 1.75 0 0 1 12.25 16h-8.5A1.75 1.75 0 0 1 2 14.25V1.75C2 .784 2.784 0 3.75 0ZM3.5 1.75v12.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25h-8.5a.25.25 0 0 0-.25.25ZM8 13a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\"></path>\n</svg>\n</template>\n\n<template id=\"package-icon\">\n  <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-package\">\n    <path d=\"m8.878.392 5.25 3.045c.54.314.872.89.872 1.514v6.098a1.75 1.75 0 0 1-.872 1.514l-5.25 3.045a1.75 1.75 0 0 1-1.756 0l-5.25-3.045A1.75 1.75 0 0 1 1 11.049V4.951c0-.624.332-1.201.872-1.514L7.122.392a1.75 1.75 0 0 1 1.756 0ZM7.875 1.69l-4.63 2.685L8 7.133l4.755-2.758-4.63-2.685a.248.248 0 0 0-.25 0ZM2.5 5.677v5.372c0 .09.047.171.125.216l4.625 2.683V8.432Zm6.25 8.271 4.625-2.683a.25.25 0 0 0 .125-.216V5.677L8.75 8.432Z\"></path>\n</svg>\n</template>\n\n<template id=\"credit-card-icon\">\n  <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-credit-card\">\n    <path d=\"M10.75 9a.75.75 0 0 0 0 1.5h1.5a.75.75 0 0 0 0-1.5h-1.5Z\"></path><path d=\"M0 3.75C0 2.784.784 2 1.75 2h12.5c.966 0 1.75.784 1.75 1.75v8.5A1.75 1.75 0 0 1 14.25 14H1.75A1.75 1.75 0 0 1 0 12.25ZM14.5 6.5h-13v5.75c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25Zm0-2.75a.25.25 0 0 0-.25-.25H1.75a.25.25 0 0 0-.25.25V5h13Z\"></path>\n</svg>\n</template>\n\n<template id=\"play-icon\">\n  <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-play\">\n    <path d=\"M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Zm4.879-2.773 4.264 2.559a.25.25 0 0 1 0 .428l-4.264 2.559A.25.25 0 0 1 6 10.559V5.442a.25.25 0 0 1 .379-.215Z\"></path>\n</svg>\n</template>\n\n<template id=\"gift-icon\">\n  <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-gift\">\n    <path d=\"M2 2.75A2.75 2.75 0 0 1 4.75 0c.983 0 1.873.42 2.57 1.232.268.318.497.668.68 1.042.183-.375.411-.725.68-1.044C9.376.42 10.266 0 11.25 0a2.75 2.75 0 0 1 2.45 4h.55c.966 0 1.75.784 1.75 1.75v2c0 .698-.409 1.301-1 1.582v4.918A1.75 1.75 0 0 1 13.25 16H2.75A1.75 1.75 0 0 1 1 14.25V9.332C.409 9.05 0 8.448 0 7.75v-2C0 4.784.784 4 1.75 4h.55c-.192-.375-.3-.8-.3-1.25ZM7.25 9.5H2.5v4.75c0 .138.112.25.25.25h4.5Zm1.5 0v5h4.5a.25.25 0 0 0 .25-.25V9.5Zm0-4V8h5.5a.25.25 0 0 0 .25-.25v-2a.25.25 0 0 0-.25-.25Zm-7 0a.25.25 0 0 0-.25.25v2c0 .138.112.25.25.25h5.5V5.5h-5.5Zm3-4a1.25 1.25 0 0 0 0 2.5h2.309c-.233-.818-.542-1.401-.878-1.793-.43-.502-.915-.707-1.431-.707ZM8.941 4h2.309a1.25 1.25 0 0 0 0-2.5c-.516 0-1 .205-1.43.707-.337.392-.646.975-.879 1.793Z\"></path>\n</svg>\n</template>\n\n<template id=\"code-square-icon\">\n  <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-code-square\">\n    <path d=\"M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25Zm7.47 3.97a.75.75 0 0 1 1.06 0l2 2a.75.75 0 0 1 0 1.06l-2 2a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L10.69 8 9.22 6.53a.75.75 0 0 1 0-1.06ZM6.78 6.53 5.31 8l1.47 1.47a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215l-2-2a.75.75 0 0 1 0-1.06l2-2a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z\"></path>\n</svg>\n</template>\n\n<template id=\"device-desktop-icon\">\n  <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-device-desktop\">\n    <path d=\"M14.25 1c.966 0 1.75.784 1.75 1.75v7.5A1.75 1.75 0 0 1 14.25 12h-3.727c.099 1.041.52 1.872 1.292 2.757A.752.752 0 0 1 11.25 16h-6.5a.75.75 0 0 1-.565-1.243c.772-.885 1.192-1.716 1.292-2.757H1.75A1.75 1.75 0 0 1 0 10.25v-7.5C0 1.784.784 1 1.75 1ZM1.75 2.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25ZM9.018 12H6.982a5.72 5.72 0 0 1-.765 2.5h3.566a5.72 5.72 0 0 1-.765-2.5Z\"></path>\n</svg>\n</template>\n\n        <div class=\"position-relative\">\n                <ul\n                  role=\"listbox\"\n                  class=\"ActionListWrap QueryBuilder-ListWrap\"\n                  aria-label=\"Suggestions\"\n                  data-action=\"\n                    combobox-commit:query-builder#comboboxCommit\n                    mousedown:query-builder#resultsMousedown\n                  \"\n                  data-target=\"query-builder.resultsList\"\n                  data-persist-list=false\n                  id=\"query-builder-test-results\"\n                ></ul>\n        </div>\n      <div class=\"FormControl-inlineValidation\" id=\"validation-25130bc6-7deb-4401-bf40-5353d351cfe9\" hidden=\"hidden\">\n        <span class=\"FormControl-inlineValidation--visual\">\n          <svg aria-hidden=\"true\" height=\"12\" viewBox=\"0 0 12 12\" version=\"1.1\" width=\"12\" data-view-component=\"true\" class=\"octicon octicon-alert-fill\">\n    <path d=\"M4.855.708c.5-.896 1.79-.896 2.29 0l4.675 8.351a1.312 1.312 0 0 1-1.146 1.954H1.33A1.313 1.313 0 0 1 .183 9.058ZM7 7V3H5v4Zm-1 3a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z\"></path>\n</svg>\n        </span>\n        <span></span>\n</div>    </div>\n    <div data-target=\"query-builder.screenReaderFeedback\" aria-live=\"polite\" aria-atomic=\"true\" class=\"sr-only\"></div>\n</query-builder></form>\n          <div class=\"d-flex flex-row color-fg-muted px-3 text-small color-bg-default search-feedback-prompt\">\n            <a target=\"_blank\" href=\"https://docs.github.com/search-github/github-code-search/understanding-github-code-search-syntax\" data-view-component=\"true\" class=\"Link color-fg-accent text-normal ml-2\">\n              Search syntax tips\n</a>            <div class=\"d-flex flex-1\"></div>\n              <button data-action=\"click:qbsearch-input#showFeedbackDialog\" type=\"button\" data-view-component=\"true\" class=\"Button--link Button--medium Button color-fg-accent text-normal ml-2\">  <span class=\"Button-content\">\n    <span class=\"Button-label\">Give feedback</span>\n  </span>\n</button>\n          </div>\n        </div>\n</div>\n\n    </div>\n</modal-dialog></div>\n  </div>\n  <div data-action=\"click:qbsearch-input#retract\" class=\"dark-backdrop position-fixed\" hidden data-target=\"qbsearch-input.darkBackdrop\"></div>\n  <div class=\"color-fg-default\">\n    \n<dialog-helper>\n  <dialog data-target=\"qbsearch-input.feedbackDialog\" data-action=\"close:qbsearch-input#handleDialogClose cancel:qbsearch-input#handleDialogClose\" id=\"feedback-dialog\" aria-modal=\"true\" aria-labelledby=\"feedback-dialog-title\" aria-describedby=\"feedback-dialog-description\" data-view-component=\"true\" class=\"Overlay Overlay-whenNarrow Overlay--size-medium Overlay--motion-scaleFade\">\n    <div data-view-component=\"true\" class=\"Overlay-header\">\n  <div class=\"Overlay-headerContentWrap\">\n    <div class=\"Overlay-titleWrap\">\n      <h1 class=\"Overlay-title \" id=\"feedback-dialog-title\">\n        Provide feedback\n      </h1>\n        \n    </div>\n    <div class=\"Overlay-actionWrap\">\n      <button data-close-dialog-id=\"feedback-dialog\" aria-label=\"Close\" type=\"button\" data-view-component=\"true\" class=\"close-button Overlay-closeButton\"><svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-x\">\n    <path d=\"M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z\"></path>\n</svg></button>\n    </div>\n  </div>\n  \n</div>\n      <scrollable-region data-labelled-by=\"feedback-dialog-title\">\n        <div data-view-component=\"true\" class=\"Overlay-body\">        <!-- '\"` --><!-- </textarea></xmp> --></option></form><form id=\"code-search-feedback-form\" data-turbo=\"false\" action=\"/search/feedback\" accept-charset=\"UTF-8\" method=\"post\"><input type=\"hidden\" name=\"authenticity_token\" value=\"RmK5gFv2xUvFKJRh57An3K5oCRRphrRJeq3F7Hs33qvls351mUyXBA3fYFffpjWP2iY6XBPBK9uBqQEBDGQ0Dg\" />\n          <p>We read every piece of feedback, and take your input very seriously.</p>\n          <textarea name=\"feedback\" class=\"form-control width-full mb-2\" style=\"height: 120px\" id=\"feedback\"></textarea>\n          <input name=\"include_email\" id=\"include_email\" aria-label=\"Include my email address so I can be contacted\" class=\"form-control mr-2\" type=\"checkbox\">\n          <label for=\"include_email\" style=\"font-weight: normal\">Include my email address so I can be contacted</label>\n</form></div>\n      </scrollable-region>\n      <div data-view-component=\"true\" class=\"Overlay-footer Overlay-footer--alignEnd\">          <button data-close-dialog-id=\"feedback-dialog\" type=\"button\" data-view-component=\"true\" class=\"btn\">    Cancel\n</button>\n          <button form=\"code-search-feedback-form\" data-action=\"click:qbsearch-input#submitFeedback\" type=\"submit\" data-view-component=\"true\" class=\"btn-primary btn\">    Submit feedback\n</button>\n</div>\n</dialog></dialog-helper>\n\n    <custom-scopes data-target=\"qbsearch-input.customScopesManager\">\n    \n<dialog-helper>\n  <dialog data-target=\"custom-scopes.customScopesModalDialog\" data-action=\"close:qbsearch-input#handleDialogClose cancel:qbsearch-input#handleDialogClose\" id=\"custom-scopes-dialog\" aria-modal=\"true\" aria-labelledby=\"custom-scopes-dialog-title\" aria-describedby=\"custom-scopes-dialog-description\" data-view-component=\"true\" class=\"Overlay Overlay-whenNarrow Overlay--size-medium Overlay--motion-scaleFade\">\n    <div data-view-component=\"true\" class=\"Overlay-header Overlay-header--divided\">\n  <div class=\"Overlay-headerContentWrap\">\n    <div class=\"Overlay-titleWrap\">\n      <h1 class=\"Overlay-title \" id=\"custom-scopes-dialog-title\">\n        Saved searches\n      </h1>\n        <h2 id=\"custom-scopes-dialog-description\" class=\"Overlay-description\">Use saved searches to filter your results more quickly</h2>\n    </div>\n    <div class=\"Overlay-actionWrap\">\n      <button data-close-dialog-id=\"custom-scopes-dialog\" aria-label=\"Close\" type=\"button\" data-view-component=\"true\" class=\"close-button Overlay-closeButton\"><svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-x\">\n    <path d=\"M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z\"></path>\n</svg></button>\n    </div>\n  </div>\n  \n</div>\n      <scrollable-region data-labelled-by=\"custom-scopes-dialog-title\">\n        <div data-view-component=\"true\" class=\"Overlay-body\">        <div data-target=\"custom-scopes.customScopesModalDialogFlash\"></div>\n\n        <div hidden class=\"create-custom-scope-form\" data-target=\"custom-scopes.createCustomScopeForm\">\n        <!-- '\"` --><!-- </textarea></xmp> --></option></form><form id=\"custom-scopes-dialog-form\" data-turbo=\"false\" action=\"/search/custom_scopes\" accept-charset=\"UTF-8\" method=\"post\"><input type=\"hidden\" name=\"authenticity_token\" value=\"w8iI5IPWB97cIwpMX476WavRDbrzLjxksHHzyOdD_cSuVc1NNG_RkkxIjouaxAXlQfy-ETm1ukqrPsYYz3IVkQ\" />\n          <div data-target=\"custom-scopes.customScopesModalDialogFlash\"></div>\n\n          <input type=\"hidden\" id=\"custom_scope_id\" name=\"custom_scope_id\" data-target=\"custom-scopes.customScopesIdField\">\n\n          <div class=\"form-group\">\n            <label for=\"custom_scope_name\">Name</label>\n            <auto-check src=\"/search/custom_scopes/check_name\" required>\n              <input\n                type=\"text\"\n                name=\"custom_scope_name\"\n                id=\"custom_scope_name\"\n                data-target=\"custom-scopes.customScopesNameField\"\n                class=\"form-control\"\n                autocomplete=\"off\"\n                placeholder=\"github-ruby\"\n                required\n                maxlength=\"50\">\n              <input type=\"hidden\" value=\"Xdfqa_kfaTTToVLiXs1X-DHt4eZ9oZoqnThKpgH-7tOmqyYmqinZExiOEb8xu6gCMOZUYU49o38YCYRCyH-feA\" data-csrf=\"true\" />\n            </auto-check>\n          </div>\n\n          <div class=\"form-group\">\n            <label for=\"custom_scope_query\">Query</label>\n            <input\n              type=\"text\"\n              name=\"custom_scope_query\"\n              id=\"custom_scope_query\"\n              data-target=\"custom-scopes.customScopesQueryField\"\n              class=\"form-control\"\n              autocomplete=\"off\"\n              placeholder=\"(repo:mona/a OR repo:mona/b) AND lang:python\"\n              required\n              maxlength=\"500\">\n          </div>\n\n          <p class=\"text-small color-fg-muted\">\n            To see all available qualifiers, see our <a class=\"Link--inTextBlock\" href=\"https://docs.github.com/search-github/github-code-search/understanding-github-code-search-syntax\">documentation</a>.\n          </p>\n</form>        </div>\n\n        <div data-target=\"custom-scopes.manageCustomScopesForm\">\n          <div data-target=\"custom-scopes.list\"></div>\n        </div>\n\n</div>\n      </scrollable-region>\n      <div data-view-component=\"true\" class=\"Overlay-footer Overlay-footer--alignEnd Overlay-footer--divided\">          <button data-action=\"click:custom-scopes#customScopesCancel\" type=\"button\" data-view-component=\"true\" class=\"btn\">    Cancel\n</button>\n          <button form=\"custom-scopes-dialog-form\" data-action=\"click:custom-scopes#customScopesSubmit\" data-target=\"custom-scopes.customScopesSubmitButton\" type=\"submit\" data-view-component=\"true\" class=\"btn-primary btn\">    Create saved search\n</button>\n</div>\n</dialog></dialog-helper>\n    </custom-scopes>\n  </div>\n</qbsearch-input><input type=\"hidden\" value=\"5jC4Y9jzjXGFEArHW2WcJPRddAlfF5Malflg-BxQDx87n4krvG2Q7aBDle63Po50Qp4uX6c9LP4uCC7VtuZgGw\" data-csrf=\"true\" class=\"js-data-jump-to-suggestions-path-csrf\" />\n\n          </div>\n\n        <div class=\"AppHeader-actions position-relative\">\n             <react-partial-anchor>\n      <button id=\"global-create-menu-anchor\" aria-label=\"Create something new\" data-target=\"react-partial-anchor.anchor\" type=\"button\" disabled=\"disabled\" data-view-component=\"true\" class=\"AppHeader-button global-create-button cursor-wait Button--secondary Button--medium Button width-auto color-fg-muted\">  <span class=\"Button-content\">\n      <span class=\"Button-visual Button-leadingVisual\">\n        <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-plus\">\n    <path d=\"M7.75 2a.75.75 0 0 1 .75.75V7h4.25a.75.75 0 0 1 0 1.5H8.5v4.25a.75.75 0 0 1-1.5 0V8.5H2.75a.75.75 0 0 1 0-1.5H7V2.75A.75.75 0 0 1 7.75 2Z\"></path>\n</svg>\n      </span>\n    <span class=\"Button-label\"><svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-triangle-down\">\n    <path d=\"m4.427 7.427 3.396 3.396a.25.25 0 0 0 .354 0l3.396-3.396A.25.25 0 0 0 11.396 7H4.604a.25.25 0 0 0-.177.427Z\"></path>\n</svg></span>\n  </span>\n</button><tool-tip id=\"tooltip-0e196211-1803-408e-b7e7-3c4f56631b72\" for=\"global-create-menu-anchor\" popover=\"manual\" data-direction=\"s\" data-type=\"description\" data-view-component=\"true\" class=\"sr-only position-absolute\">Create new...</tool-tip>\n\n      <template data-target=\"react-partial-anchor.template\">\n        \n\n\n\n\n\n\n\n\n\n\n<script crossorigin=\"anonymous\" defer=\"defer\" type=\"application/javascript\" src=\"https://github.githubassets.com/assets/global-create-menu-4aa638742b63.js\"></script>\n\n<react-partial\n  partial-name=\"global-create-menu\"\n  data-ssr=\"false\"\n>\n  \n  <script type=\"application/json\" data-target=\"react-partial.embeddedData\">{\"props\":{\"createRepo\":true,\"importRepo\":true,\"codespaces\":true,\"gist\":true,\"createOrg\":true,\"createProject\":false,\"createProjectUrl\":\"/Roswell468?tab=projects\",\"createLegacyProject\":false,\"createIssue\":false,\"org\":null,\"owner\":\"mouredev\",\"repo\":\"roadmap-retos-programacion\"}}</script>\n  <div data-target=\"react-partial.reactRoot\"></div>\n</react-partial>\n\n      </template>\n    </react-partial-anchor>\n\n\n          <a href=\"/issues\" data-analytics-event=\"{&quot;category&quot;:&quot;Global navigation&quot;,&quot;action&quot;:&quot;ISSUES_HEADER&quot;,&quot;label&quot;:null}\" id=\"icon-button-413820a6-268d-4f94-9d46-1e6dbed83436\" aria-labelledby=\"tooltip-802df048-43a6-463e-b67c-85191a26b22c\" data-view-component=\"true\" class=\"Button Button--iconOnly Button--secondary Button--medium AppHeader-button color-fg-muted\">  <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-issue-opened Button-visual\">\n    <path d=\"M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z\"></path><path d=\"M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Z\"></path>\n</svg>\n</a><tool-tip id=\"tooltip-802df048-43a6-463e-b67c-85191a26b22c\" for=\"icon-button-413820a6-268d-4f94-9d46-1e6dbed83436\" popover=\"manual\" data-direction=\"s\" data-type=\"label\" data-view-component=\"true\" class=\"sr-only position-absolute\">Issues</tool-tip>\n\n          <a href=\"/pulls\" data-analytics-event=\"{&quot;category&quot;:&quot;Global navigation&quot;,&quot;action&quot;:&quot;PULL_REQUESTS_HEADER&quot;,&quot;label&quot;:null}\" id=\"icon-button-2897de4c-9a6d-4218-a0a1-0b169876c3fb\" aria-labelledby=\"tooltip-afe51589-21cd-4f48-abb3-09b592d32b4d\" data-view-component=\"true\" class=\"Button Button--iconOnly Button--secondary Button--medium AppHeader-button color-fg-muted\">  <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-git-pull-request Button-visual\">\n    <path d=\"M1.5 3.25a2.25 2.25 0 1 1 3 2.122v5.256a2.251 2.251 0 1 1-1.5 0V5.372A2.25 2.25 0 0 1 1.5 3.25Zm5.677-.177L9.573.677A.25.25 0 0 1 10 .854V2.5h1A2.5 2.5 0 0 1 13.5 5v5.628a2.251 2.251 0 1 1-1.5 0V5a1 1 0 0 0-1-1h-1v1.646a.25.25 0 0 1-.427.177L7.177 3.427a.25.25 0 0 1 0-.354ZM3.75 2.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm0 9.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm8.25.75a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Z\"></path>\n</svg>\n</a><tool-tip id=\"tooltip-afe51589-21cd-4f48-abb3-09b592d32b4d\" for=\"icon-button-2897de4c-9a6d-4218-a0a1-0b169876c3fb\" popover=\"manual\" data-direction=\"s\" data-type=\"label\" data-view-component=\"true\" class=\"sr-only position-absolute\">Pull requests</tool-tip>\n\n        </div>\n\n        \n<notification-indicator data-channel=\"eyJjIjoibm90aWZpY2F0aW9uLWNoYW5nZWQ6ODgwMDgyMzMiLCJ0IjoxNzE2NzQ4OTQzfQ==--b1083487b9b6110891feb4d51836354ff62cc6eb5da8cc09208921b3bb02171d\" data-indicator-mode=\"none\" data-tooltip-global=\"You have unread notifications\" data-tooltip-unavailable=\"Notifications are unavailable at the moment.\" data-tooltip-none=\"You have no unread notifications\" data-header-redesign-enabled=\"true\" data-fetch-indicator-src=\"/notifications/indicator\" data-fetch-indicator-enabled=\"true\" data-view-component=\"true\" class=\"js-socket-channel\">\n    <a id=\"AppHeader-notifications-button\" href=\"/notifications\" aria-label=\"Notifications\" data-hotkey=\"g n\" data-target=\"notification-indicator.link\" data-analytics-event=\"{&quot;category&quot;:&quot;Global navigation&quot;,&quot;action&quot;:&quot;NOTIFICATIONS_HEADER&quot;,&quot;label&quot;:null}\" data-view-component=\"true\" class=\"Button Button--iconOnly Button--secondary Button--medium AppHeader-button  color-fg-muted\">  <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-inbox Button-visual\">\n    <path d=\"M2.8 2.06A1.75 1.75 0 0 1 4.41 1h7.18c.7 0 1.333.417 1.61 1.06l2.74 6.395c.04.093.06.194.06.295v4.5A1.75 1.75 0 0 1 14.25 15H1.75A1.75 1.75 0 0 1 0 13.25v-4.5c0-.101.02-.202.06-.295Zm1.61.44a.25.25 0 0 0-.23.152L1.887 8H4.75a.75.75 0 0 1 .6.3L6.625 10h2.75l1.275-1.7a.75.75 0 0 1 .6-.3h2.863L11.82 2.652a.25.25 0 0 0-.23-.152Zm10.09 7h-2.875l-1.275 1.7a.75.75 0 0 1-.6.3h-3.5a.75.75 0 0 1-.6-.3L4.375 9.5H1.5v3.75c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25Z\"></path>\n</svg>\n</a>\n\n    <tool-tip data-target=\"notification-indicator.tooltip\" id=\"tooltip-1fb34c37-09b4-4d1d-90ff-ca8570d3401d\" for=\"AppHeader-notifications-button\" popover=\"manual\" data-direction=\"s\" data-type=\"description\" data-view-component=\"true\" class=\"sr-only position-absolute\">Notifications</tool-tip>\n</notification-indicator>\n\n        \n\n        <div class=\"AppHeader-user\">\n          <deferred-side-panel data-url=\"/_side-panels/user?react_global_nav=false&amp;repository_id=733006926\">\n  <include-fragment data-target=\"deferred-side-panel.fragment\">\n        <user-drawer-side-panel>\n      <button aria-label=\"Open user account menu\" data-action=\"click:deferred-side-panel#loadPanel click:deferred-side-panel#panelOpened\" data-show-dialog-id=\"dialog-78cf383b-ba3c-488e-8e99-e70d6ed6cdca\" id=\"dialog-show-dialog-78cf383b-ba3c-488e-8e99-e70d6ed6cdca\" type=\"button\" data-view-component=\"true\" class=\"AppHeader-logo Button--invisible Button--medium Button Button--invisible-noVisuals color-bg-transparent p-0\">  <span class=\"Button-content\">\n    <span class=\"Button-label\"><img src=\"https://avatars.githubusercontent.com/u/88008233?v=4\" alt=\"\" size=\"32\" height=\"32\" width=\"32\" data-view-component=\"true\" class=\"avatar circle\" /></span>\n  </span>\n</button>\n\n<dialog-helper>\n  <dialog data-target=\"deferred-side-panel.panel\" id=\"dialog-78cf383b-ba3c-488e-8e99-e70d6ed6cdca\" aria-modal=\"true\" aria-labelledby=\"dialog-78cf383b-ba3c-488e-8e99-e70d6ed6cdca-title\" aria-describedby=\"dialog-78cf383b-ba3c-488e-8e99-e70d6ed6cdca-description\" data-view-component=\"true\" class=\"Overlay Overlay-whenNarrow Overlay--size-small-portrait Overlay--motion-scaleFade Overlay--placement-right SidePanel\">\n    <div styles=\"flex-direction: row;\" data-view-component=\"true\" class=\"Overlay-header\">\n  <div class=\"Overlay-headerContentWrap\">\n    <div class=\"Overlay-titleWrap\">\n      <h1 class=\"Overlay-title sr-only\" id=\"dialog-78cf383b-ba3c-488e-8e99-e70d6ed6cdca-title\">\n        Account menu\n      </h1>\n            <div data-view-component=\"true\" class=\"d-flex\">\n      <div data-view-component=\"true\" class=\"AppHeader-logo position-relative\">\n        <img src=\"https://avatars.githubusercontent.com/u/88008233?v=4\" alt=\"\" size=\"32\" height=\"32\" width=\"32\" data-view-component=\"true\" class=\"avatar circle\" />\n</div>        <div data-view-component=\"true\" class=\"overflow-hidden d-flex width-full\">          <div data-view-component=\"true\" class=\"lh-condensed overflow-hidden d-flex flex-column flex-justify-center ml-2 f5 mr-auto width-full\">\n            <span data-view-component=\"true\" class=\"Truncate text-bold\">\n    <span data-view-component=\"true\" class=\"Truncate-text\">\n              Roswell468\n</span>\n</span>            <span data-view-component=\"true\" class=\"Truncate color-fg-subtle\">\n    <span data-view-component=\"true\" class=\"Truncate-text\">\n              Bruce\n</span>\n</span></div>\n            <action-menu data-select-variant=\"none\" data-view-component=\"true\" class=\"d-sm-none d-md-none d-lg-none\">\n  <focus-group direction=\"vertical\" mnemonics retain>\n    <button id=\"user-create-menu-button\" popovertarget=\"user-create-menu-overlay\" aria-label=\"Create something new\" aria-controls=\"user-create-menu-list\" aria-haspopup=\"true\" type=\"button\" data-view-component=\"true\" class=\"AppHeader-button global-create-button Button--secondary Button--medium Button width-auto color-fg-muted\">  <span class=\"Button-content\">\n      <span class=\"Button-visual Button-leadingVisual\">\n        <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-plus\">\n    <path d=\"M7.75 2a.75.75 0 0 1 .75.75V7h4.25a.75.75 0 0 1 0 1.5H8.5v4.25a.75.75 0 0 1-1.5 0V8.5H2.75a.75.75 0 0 1 0-1.5H7V2.75A.75.75 0 0 1 7.75 2Z\"></path>\n</svg>\n      </span>\n    <span class=\"Button-label\"><svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-triangle-down\">\n    <path d=\"m4.427 7.427 3.396 3.396a.25.25 0 0 0 .354 0l3.396-3.396A.25.25 0 0 0 11.396 7H4.604a.25.25 0 0 0-.177.427Z\"></path>\n</svg></span>\n  </span>\n</button><tool-tip id=\"tooltip-18c1087e-df5f-4e47-9d2a-28b1fd19efeb\" for=\"user-create-menu-button\" popover=\"manual\" data-direction=\"s\" data-type=\"description\" data-view-component=\"true\" class=\"sr-only position-absolute\">Create new...</tool-tip>\n\n\n<anchored-position id=\"user-create-menu-overlay\" anchor=\"user-create-menu-button\" align=\"end\" side=\"outside-bottom\" anchor-offset=\"normal\" popover=\"auto\" data-view-component=\"true\">\n  <div data-view-component=\"true\" class=\"Overlay Overlay--size-auto\">\n    \n      <div data-view-component=\"true\" class=\"Overlay-body Overlay-body--paddingNone\">          <action-list>\n  <div data-view-component=\"true\">\n    <ul aria-labelledby=\"user-create-menu-button\" id=\"user-create-menu-list\" role=\"menu\" data-view-component=\"true\" class=\"ActionListWrap--inset ActionListWrap\">\n        <li data-analytics-event=\"{&quot;category&quot;:&quot;SiteHeaderComponent&quot;,&quot;action&quot;:&quot;add_dropdown&quot;,&quot;label&quot;:&quot;new repository&quot;}\" data-targets=\"action-list.items\" role=\"none\" data-view-component=\"true\" class=\"ActionListItem\">\n    \n    \n    <a href=\"/new\" tabindex=\"-1\" id=\"item-04103488-88fd-49b2-adb9-b0ee38f2d007\" role=\"menuitem\" data-view-component=\"true\" class=\"ActionListContent ActionListContent--visual16\">\n        <span class=\"ActionListItem-visual ActionListItem-visual--leading\">\n          <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-repo\">\n    <path d=\"M2 2.5A2.5 2.5 0 0 1 4.5 0h8.75a.75.75 0 0 1 .75.75v12.5a.75.75 0 0 1-.75.75h-2.5a.75.75 0 0 1 0-1.5h1.75v-2h-8a1 1 0 0 0-.714 1.7.75.75 0 1 1-1.072 1.05A2.495 2.495 0 0 1 2 11.5Zm10.5-1h-8a1 1 0 0 0-1 1v6.708A2.486 2.486 0 0 1 4.5 9h8ZM5 12.25a.25.25 0 0 1 .25-.25h3.5a.25.25 0 0 1 .25.25v3.25a.25.25 0 0 1-.4.2l-1.45-1.087a.249.249 0 0 0-.3 0L5.4 15.7a.25.25 0 0 1-.4-.2Z\"></path>\n</svg>\n        </span>\n      \n        <span data-view-component=\"true\" class=\"ActionListItem-label\">\n                  New repository\n\n</span></a>\n  \n</li>\n        <li data-analytics-event=\"{&quot;category&quot;:&quot;SiteHeaderComponent&quot;,&quot;action&quot;:&quot;add_dropdown&quot;,&quot;label&quot;:&quot;import repository&quot;}\" data-targets=\"action-list.items\" role=\"none\" data-view-component=\"true\" class=\"ActionListItem\">\n    \n    \n    <a href=\"/new/import\" tabindex=\"-1\" id=\"item-86f0fc16-b03f-4145-9a15-af6c6e333e02\" role=\"menuitem\" data-view-component=\"true\" class=\"ActionListContent ActionListContent--visual16\">\n        <span class=\"ActionListItem-visual ActionListItem-visual--leading\">\n          <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-repo-push\">\n    <path d=\"M1 2.5A2.5 2.5 0 0 1 3.5 0h8.75a.75.75 0 0 1 .75.75v3.5a.75.75 0 0 1-1.5 0V1.5h-8a1 1 0 0 0-1 1v6.708A2.493 2.493 0 0 1 3.5 9h3.25a.75.75 0 0 1 0 1.5H3.5a1 1 0 0 0 0 2h5.75a.75.75 0 0 1 0 1.5H3.5A2.5 2.5 0 0 1 1 11.5Zm13.23 7.79h-.001l-1.224-1.224v6.184a.75.75 0 0 1-1.5 0V9.066L10.28 10.29a.75.75 0 0 1-1.06-1.061l2.505-2.504a.75.75 0 0 1 1.06 0L15.29 9.23a.751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018Z\"></path>\n</svg>\n        </span>\n      \n        <span data-view-component=\"true\" class=\"ActionListItem-label\">\n                  Import repository\n\n</span></a>\n  \n</li>\n        <li role=\"presentation\" aria-hidden=\"true\" data-view-component=\"true\" class=\"ActionList-sectionDivider\"></li>\n        <li data-analytics-event=\"{&quot;category&quot;:&quot;SiteHeaderComponent&quot;,&quot;action&quot;:&quot;add_dropdown&quot;,&quot;label&quot;:&quot;new codespace&quot;}\" data-targets=\"action-list.items\" role=\"none\" data-view-component=\"true\" class=\"ActionListItem\">\n    \n    \n    <a href=\"/codespaces/new\" tabindex=\"-1\" id=\"item-adbcd6de-1eef-482f-ba6d-c8814d15f631\" role=\"menuitem\" data-view-component=\"true\" class=\"ActionListContent ActionListContent--visual16\">\n        <span class=\"ActionListItem-visual ActionListItem-visual--leading\">\n          <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-codespaces\">\n    <path d=\"M0 11.25c0-.966.784-1.75 1.75-1.75h12.5c.966 0 1.75.784 1.75 1.75v3A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25Zm2-9.5C2 .784 2.784 0 3.75 0h8.5C13.216 0 14 .784 14 1.75v5a1.75 1.75 0 0 1-1.75 1.75h-8.5A1.75 1.75 0 0 1 2 6.75Zm1.75-.25a.25.25 0 0 0-.25.25v5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-5a.25.25 0 0 0-.25-.25Zm-2 9.5a.25.25 0 0 0-.25.25v3c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25v-3a.25.25 0 0 0-.25-.25Z\"></path><path d=\"M7 12.75a.75.75 0 0 1 .75-.75h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1-.75-.75Zm-4 0a.75.75 0 0 1 .75-.75h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1-.75-.75Z\"></path>\n</svg>\n        </span>\n      \n        <span data-view-component=\"true\" class=\"ActionListItem-label\">\n                  New codespace\n\n</span></a>\n  \n</li>\n        <li data-analytics-event=\"{&quot;category&quot;:&quot;SiteHeaderComponent&quot;,&quot;action&quot;:&quot;add_dropdown&quot;,&quot;label&quot;:&quot;new gist&quot;}\" data-targets=\"action-list.items\" role=\"none\" data-view-component=\"true\" class=\"ActionListItem\">\n    \n    \n    <a href=\"https://gist.github.com/\" tabindex=\"-1\" id=\"item-97be0242-dbd9-4762-a56e-e17401f17924\" role=\"menuitem\" data-view-component=\"true\" class=\"ActionListContent ActionListContent--visual16\">\n        <span class=\"ActionListItem-visual ActionListItem-visual--leading\">\n          <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-code\">\n    <path d=\"m11.28 3.22 4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L13.94 8l-3.72-3.72a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215Zm-6.56 0a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L2.06 8l3.72 3.72a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L.47 8.53a.75.75 0 0 1 0-1.06Z\"></path>\n</svg>\n        </span>\n      \n        <span data-view-component=\"true\" class=\"ActionListItem-label\">\n                  New gist\n\n</span></a>\n  \n</li>\n        <li role=\"presentation\" aria-hidden=\"true\" data-view-component=\"true\" class=\"ActionList-sectionDivider\"></li>\n        <li data-targets=\"action-list.items\" role=\"none\" data-view-component=\"true\" class=\"ActionListItem\">\n    \n    \n    <a href=\"/account/organizations/new\" tabindex=\"-1\" data-dont-follow-via-test=\"true\" data-analytics-event=\"{&quot;category&quot;:&quot;SiteHeaderComponent&quot;,&quot;action&quot;:&quot;add_dropdown&quot;,&quot;label&quot;:&quot;new organization&quot;}\" id=\"item-fac3c7c8-21d2-417d-bec0-2b16302a6682\" role=\"menuitem\" data-view-component=\"true\" class=\"ActionListContent ActionListContent--visual16\">\n        <span class=\"ActionListItem-visual ActionListItem-visual--leading\">\n          <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-organization\">\n    <path d=\"M1.75 16A1.75 1.75 0 0 1 0 14.25V1.75C0 .784.784 0 1.75 0h8.5C11.216 0 12 .784 12 1.75v12.5c0 .085-.006.168-.018.25h2.268a.25.25 0 0 0 .25-.25V8.285a.25.25 0 0 0-.111-.208l-1.055-.703a.749.749 0 1 1 .832-1.248l1.055.703c.487.325.779.871.779 1.456v5.965A1.75 1.75 0 0 1 14.25 16h-3.5a.766.766 0 0 1-.197-.026c-.099.017-.2.026-.303.026h-3a.75.75 0 0 1-.75-.75V14h-1v1.25a.75.75 0 0 1-.75.75Zm-.25-1.75c0 .138.112.25.25.25H4v-1.25a.75.75 0 0 1 .75-.75h2.5a.75.75 0 0 1 .75.75v1.25h2.25a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25h-8.5a.25.25 0 0 0-.25.25ZM3.75 6h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1 0-1.5ZM3 3.75A.75.75 0 0 1 3.75 3h.5a.75.75 0 0 1 0 1.5h-.5A.75.75 0 0 1 3 3.75Zm4 3A.75.75 0 0 1 7.75 6h.5a.75.75 0 0 1 0 1.5h-.5A.75.75 0 0 1 7 6.75ZM7.75 3h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1 0-1.5ZM3 9.75A.75.75 0 0 1 3.75 9h.5a.75.75 0 0 1 0 1.5h-.5A.75.75 0 0 1 3 9.75ZM7.75 9h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1 0-1.5Z\"></path>\n</svg>\n        </span>\n      \n        <span data-view-component=\"true\" class=\"ActionListItem-label\">\n                  New organization\n\n</span></a>\n  \n</li>\n</ul>    \n</div></action-list>\n\n\n</div>\n      \n</div></anchored-position>  </focus-group>\n</action-menu>\n</div>\n</div>\n    </div>\n    <div class=\"Overlay-actionWrap\">\n      <button data-close-dialog-id=\"dialog-78cf383b-ba3c-488e-8e99-e70d6ed6cdca\" aria-label=\"Close\" type=\"button\" data-view-component=\"true\" class=\"close-button Overlay-closeButton\"><svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-x\">\n    <path d=\"M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z\"></path>\n</svg></button>\n    </div>\n  </div>\n  \n</div>\n      <scrollable-region data-labelled-by=\"dialog-78cf383b-ba3c-488e-8e99-e70d6ed6cdca-title\">\n        <div data-view-component=\"true\" class=\"Overlay-body d-flex flex-column px-2\">    <div data-view-component=\"true\" class=\"d-flex flex-column mb-3\">\n        <nav aria-label=\"User navigation\" data-view-component=\"true\" class=\"ActionList\">\n  \n  <nav-list>\n    <ul data-target=\"nav-list.topLevelList\" data-view-component=\"true\" class=\"ActionListWrap\">\n        \n          \n<li data-item-id=\"\" data-targets=\"nav-list.items\" data-view-component=\"true\" class=\"ActionListItem\">\n    \n    \n    <button id=\"item-18bbd9c7-3ac6-4e6a-92d3-3bd93de243a3\" type=\"button\" data-view-component=\"true\" class=\"ActionListContent ActionListContent--visual16\">\n        <span class=\"ActionListItem-visual ActionListItem-visual--leading\">\n          <span data-view-component=\"true\" class=\"d-flex flex-items-center\">    <svg style=\"box-sizing: content-box; color: var(--color-icon-primary);\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" data-view-component=\"true\" class=\"anim-rotate\">\n  <circle cx=\"8\" cy=\"8\" r=\"7\" stroke=\"currentColor\" stroke-opacity=\"0.25\" stroke-width=\"2\" vector-effect=\"non-scaling-stroke\" fill=\"none\" />\n  <path d=\"M15 8a7.002 7.002 0 00-7-7\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" vector-effect=\"non-scaling-stroke\" />\n</svg>\n</span>\n        </span>\n      \n        <span data-view-component=\"true\" class=\"ActionListItem-label\">\n          \n\n  <span class=\"color-fg-muted\">\n    Loading...\n  </span>\n\n</span></button>\n  \n</li>\n\n        \n          <li role=\"presentation\" aria-hidden=\"true\" data-view-component=\"true\" class=\"ActionList-sectionDivider\"></li>\n        \n          \n<li data-item-id=\"\" data-targets=\"nav-list.items\" data-view-component=\"true\" class=\"ActionListItem\">\n    \n    \n    <a data-analytics-event=\"{&quot;category&quot;:&quot;Global navigation&quot;,&quot;action&quot;:&quot;PROFILE&quot;,&quot;label&quot;:null}\" id=\"item-bc3d9501-4dad-4ed7-9116-0c8b0be177a9\" href=\"https://github.com/Roswell468\" data-view-component=\"true\" class=\"ActionListContent ActionListContent--visual16\">\n        <span class=\"ActionListItem-visual ActionListItem-visual--leading\">\n          <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-person\">\n    <path d=\"M10.561 8.073a6.005 6.005 0 0 1 3.432 5.142.75.75 0 1 1-1.498.07 4.5 4.5 0 0 0-8.99 0 .75.75 0 0 1-1.498-.07 6.004 6.004 0 0 1 3.431-5.142 3.999 3.999 0 1 1 5.123 0ZM10.5 5a2.5 2.5 0 1 0-5 0 2.5 2.5 0 0 0 5 0Z\"></path>\n</svg>\n        </span>\n      \n        <span data-view-component=\"true\" class=\"ActionListItem-label\">\n          Your profile\n</span></a>\n  \n</li>\n\n        \n          \n<li data-item-id=\"\" data-targets=\"nav-list.items\" data-view-component=\"true\" class=\"ActionListItem\">\n    \n    \n    <button id=\"item-4d24186f-3f07-46b8-8da8-e61602bba4b8\" type=\"button\" data-view-component=\"true\" class=\"ActionListContent ActionListContent--visual16\">\n        <span class=\"ActionListItem-visual ActionListItem-visual--leading\">\n          <span data-view-component=\"true\" class=\"d-flex flex-items-center\">    <svg style=\"box-sizing: content-box; color: var(--color-icon-primary);\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" data-view-component=\"true\" class=\"anim-rotate\">\n  <circle cx=\"8\" cy=\"8\" r=\"7\" stroke=\"currentColor\" stroke-opacity=\"0.25\" stroke-width=\"2\" vector-effect=\"non-scaling-stroke\" fill=\"none\" />\n  <path d=\"M15 8a7.002 7.002 0 00-7-7\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" vector-effect=\"non-scaling-stroke\" />\n</svg>\n</span>\n        </span>\n      \n        <span data-view-component=\"true\" class=\"ActionListItem-label\">\n          \n\n  <span class=\"color-fg-muted\">\n    Loading...\n  </span>\n\n</span></button>\n  \n</li>\n\n        \n          <li role=\"presentation\" aria-hidden=\"true\" data-view-component=\"true\" class=\"ActionList-sectionDivider\"></li>\n        \n          \n<li data-item-id=\"\" data-targets=\"nav-list.items\" data-view-component=\"true\" class=\"ActionListItem\">\n    \n    \n    <a data-analytics-event=\"{&quot;category&quot;:&quot;Global navigation&quot;,&quot;action&quot;:&quot;YOUR_REPOSITORIES&quot;,&quot;label&quot;:null}\" id=\"item-d61df503-214e-41e2-82c2-ef0c27865049\" href=\"/Roswell468?tab=repositories\" data-view-component=\"true\" class=\"ActionListContent ActionListContent--visual16\">\n        <span class=\"ActionListItem-visual ActionListItem-visual--leading\">\n          <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-repo\">\n    <path d=\"M2 2.5A2.5 2.5 0 0 1 4.5 0h8.75a.75.75 0 0 1 .75.75v12.5a.75.75 0 0 1-.75.75h-2.5a.75.75 0 0 1 0-1.5h1.75v-2h-8a1 1 0 0 0-.714 1.7.75.75 0 1 1-1.072 1.05A2.495 2.495 0 0 1 2 11.5Zm10.5-1h-8a1 1 0 0 0-1 1v6.708A2.486 2.486 0 0 1 4.5 9h8ZM5 12.25a.25.25 0 0 1 .25-.25h3.5a.25.25 0 0 1 .25.25v3.25a.25.25 0 0 1-.4.2l-1.45-1.087a.249.249 0 0 0-.3 0L5.4 15.7a.25.25 0 0 1-.4-.2Z\"></path>\n</svg>\n        </span>\n      \n        <span data-view-component=\"true\" class=\"ActionListItem-label\">\n          Your repositories\n</span></a>\n  \n</li>\n\n        \n          \n<li data-item-id=\"\" data-targets=\"nav-list.items\" data-view-component=\"true\" class=\"ActionListItem\">\n    \n    \n    <a data-analytics-event=\"{&quot;category&quot;:&quot;Global navigation&quot;,&quot;action&quot;:&quot;YOUR_PROJECTS&quot;,&quot;label&quot;:null}\" id=\"item-63dbdcd8-4332-42ad-b075-8d46686ae8b2\" href=\"/Roswell468?tab=projects\" data-view-component=\"true\" class=\"ActionListContent ActionListContent--visual16\">\n        <span class=\"ActionListItem-visual ActionListItem-visual--leading\">\n          <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-project\">\n    <path d=\"M1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25V1.75C0 .784.784 0 1.75 0ZM1.5 1.75v12.5c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25H1.75a.25.25 0 0 0-.25.25ZM11.75 3a.75.75 0 0 1 .75.75v7.5a.75.75 0 0 1-1.5 0v-7.5a.75.75 0 0 1 .75-.75Zm-8.25.75a.75.75 0 0 1 1.5 0v5.5a.75.75 0 0 1-1.5 0ZM8 3a.75.75 0 0 1 .75.75v3.5a.75.75 0 0 1-1.5 0v-3.5A.75.75 0 0 1 8 3Z\"></path>\n</svg>\n        </span>\n      \n        <span data-view-component=\"true\" class=\"ActionListItem-label\">\n          Your projects\n</span></a>\n  \n</li>\n\n        \n          \n<li data-item-id=\"\" data-targets=\"nav-list.items\" data-view-component=\"true\" class=\"ActionListItem\">\n    \n    \n    <button id=\"item-1c3f6c64-d05b-45f2-947f-5dff04e37e13\" type=\"button\" data-view-component=\"true\" class=\"ActionListContent ActionListContent--visual16\">\n        <span class=\"ActionListItem-visual ActionListItem-visual--leading\">\n          <span data-view-component=\"true\" class=\"d-flex flex-items-center\">    <svg style=\"box-sizing: content-box; color: var(--color-icon-primary);\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" data-view-component=\"true\" class=\"anim-rotate\">\n  <circle cx=\"8\" cy=\"8\" r=\"7\" stroke=\"currentColor\" stroke-opacity=\"0.25\" stroke-width=\"2\" vector-effect=\"non-scaling-stroke\" fill=\"none\" />\n  <path d=\"M15 8a7.002 7.002 0 00-7-7\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" vector-effect=\"non-scaling-stroke\" />\n</svg>\n</span>\n        </span>\n      \n        <span data-view-component=\"true\" class=\"ActionListItem-label\">\n          \n\n  <span class=\"color-fg-muted\">\n    Loading...\n  </span>\n\n</span></button>\n  \n</li>\n\n        \n          \n<li data-item-id=\"\" data-targets=\"nav-list.items\" data-view-component=\"true\" class=\"ActionListItem\">\n    \n    \n    <button id=\"item-4952b49c-1793-4b9a-82a9-299d7bf7a405\" type=\"button\" data-view-component=\"true\" class=\"ActionListContent ActionListContent--visual16\">\n        <span class=\"ActionListItem-visual ActionListItem-visual--leading\">\n          <span data-view-component=\"true\" class=\"d-flex flex-items-center\">    <svg style=\"box-sizing: content-box; color: var(--color-icon-primary);\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" data-view-component=\"true\" class=\"anim-rotate\">\n  <circle cx=\"8\" cy=\"8\" r=\"7\" stroke=\"currentColor\" stroke-opacity=\"0.25\" stroke-width=\"2\" vector-effect=\"non-scaling-stroke\" fill=\"none\" />\n  <path d=\"M15 8a7.002 7.002 0 00-7-7\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" vector-effect=\"non-scaling-stroke\" />\n</svg>\n</span>\n        </span>\n      \n        <span data-view-component=\"true\" class=\"ActionListItem-label\">\n          \n\n  <span class=\"color-fg-muted\">\n    Loading...\n  </span>\n\n</span></button>\n  \n</li>\n\n        \n          \n<li data-item-id=\"\" data-targets=\"nav-list.items\" data-view-component=\"true\" class=\"ActionListItem\">\n    \n    \n    <a data-analytics-event=\"{&quot;category&quot;:&quot;Global navigation&quot;,&quot;action&quot;:&quot;YOUR_STARS&quot;,&quot;label&quot;:null}\" id=\"item-c0b05145-929f-4da6-998c-4a1a399ddc2f\" href=\"/Roswell468?tab=stars\" data-view-component=\"true\" class=\"ActionListContent ActionListContent--visual16\">\n        <span class=\"ActionListItem-visual ActionListItem-visual--leading\">\n          <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-star\">\n    <path d=\"M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.751.751 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25Zm0 2.445L6.615 5.5a.75.75 0 0 1-.564.41l-3.097.45 2.24 2.184a.75.75 0 0 1 .216.664l-.528 3.084 2.769-1.456a.75.75 0 0 1 .698 0l2.77 1.456-.53-3.084a.75.75 0 0 1 .216-.664l2.24-2.183-3.096-.45a.75.75 0 0 1-.564-.41L8 2.694Z\"></path>\n</svg>\n        </span>\n      \n        <span data-view-component=\"true\" class=\"ActionListItem-label\">\n          Your stars\n</span></a>\n  \n</li>\n\n        \n          \n<li data-item-id=\"\" data-targets=\"nav-list.items\" data-view-component=\"true\" class=\"ActionListItem\">\n    \n    \n    <a data-analytics-event=\"{&quot;category&quot;:&quot;Global navigation&quot;,&quot;action&quot;:&quot;SPONSORS&quot;,&quot;label&quot;:null}\" id=\"item-8ed6878a-3a7b-4c16-8db8-8f8c91cd18dd\" href=\"/sponsors/accounts\" data-view-component=\"true\" class=\"ActionListContent ActionListContent--visual16\">\n        <span class=\"ActionListItem-visual ActionListItem-visual--leading\">\n          <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-heart\">\n    <path d=\"m8 14.25.345.666a.75.75 0 0 1-.69 0l-.008-.004-.018-.01a7.152 7.152 0 0 1-.31-.17 22.055 22.055 0 0 1-3.434-2.414C2.045 10.731 0 8.35 0 5.5 0 2.836 2.086 1 4.25 1 5.797 1 7.153 1.802 8 3.02 8.847 1.802 10.203 1 11.75 1 13.914 1 16 2.836 16 5.5c0 2.85-2.045 5.231-3.885 6.818a22.066 22.066 0 0 1-3.744 2.584l-.018.01-.006.003h-.002ZM4.25 2.5c-1.336 0-2.75 1.164-2.75 3 0 2.15 1.58 4.144 3.365 5.682A20.58 20.58 0 0 0 8 13.393a20.58 20.58 0 0 0 3.135-2.211C12.92 9.644 14.5 7.65 14.5 5.5c0-1.836-1.414-3-2.75-3-1.373 0-2.609.986-3.029 2.456a.749.749 0 0 1-1.442 0C6.859 3.486 5.623 2.5 4.25 2.5Z\"></path>\n</svg>\n        </span>\n      \n        <span data-view-component=\"true\" class=\"ActionListItem-label\">\n          Your sponsors\n</span></a>\n  \n</li>\n\n        \n          \n<li data-item-id=\"\" data-targets=\"nav-list.items\" data-view-component=\"true\" class=\"ActionListItem\">\n    \n    \n    <a data-analytics-event=\"{&quot;category&quot;:&quot;Global navigation&quot;,&quot;action&quot;:&quot;YOUR_GISTS&quot;,&quot;label&quot;:null}\" id=\"item-147b0c0d-8543-48f8-ab2f-32adbefbe34e\" href=\"https://gist.github.com/mine\" data-view-component=\"true\" class=\"ActionListContent ActionListContent--visual16\">\n        <span class=\"ActionListItem-visual ActionListItem-visual--leading\">\n          <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-code-square\">\n    <path d=\"M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25Zm7.47 3.97a.75.75 0 0 1 1.06 0l2 2a.75.75 0 0 1 0 1.06l-2 2a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L10.69 8 9.22 6.53a.75.75 0 0 1 0-1.06ZM6.78 6.53 5.31 8l1.47 1.47a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215l-2-2a.75.75 0 0 1 0-1.06l2-2a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z\"></path>\n</svg>\n        </span>\n      \n        <span data-view-component=\"true\" class=\"ActionListItem-label\">\n          Your gists\n</span></a>\n  \n</li>\n\n        \n          <li role=\"presentation\" aria-hidden=\"true\" data-view-component=\"true\" class=\"ActionList-sectionDivider\"></li>\n        \n          \n<li data-item-id=\"\" data-targets=\"nav-list.items\" data-view-component=\"true\" class=\"ActionListItem\">\n    \n    \n    <button id=\"item-59f12569-3278-465e-bf61-d949af69d1b4\" type=\"button\" data-view-component=\"true\" class=\"ActionListContent ActionListContent--visual16\">\n        <span class=\"ActionListItem-visual ActionListItem-visual--leading\">\n          <span data-view-component=\"true\" class=\"d-flex flex-items-center\">    <svg style=\"box-sizing: content-box; color: var(--color-icon-primary);\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" data-view-component=\"true\" class=\"anim-rotate\">\n  <circle cx=\"8\" cy=\"8\" r=\"7\" stroke=\"currentColor\" stroke-opacity=\"0.25\" stroke-width=\"2\" vector-effect=\"non-scaling-stroke\" fill=\"none\" />\n  <path d=\"M15 8a7.002 7.002 0 00-7-7\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" vector-effect=\"non-scaling-stroke\" />\n</svg>\n</span>\n        </span>\n      \n        <span data-view-component=\"true\" class=\"ActionListItem-label\">\n          \n\n  <span class=\"color-fg-muted\">\n    Loading...\n  </span>\n\n</span></button>\n  \n</li>\n\n        \n          \n<li data-item-id=\"\" data-targets=\"nav-list.items\" data-view-component=\"true\" class=\"ActionListItem\">\n    \n    \n    <button id=\"item-cd2c4cc8-e3f0-4dd4-9f1d-53e492640ebe\" type=\"button\" data-view-component=\"true\" class=\"ActionListContent ActionListContent--visual16\">\n        <span class=\"ActionListItem-visual ActionListItem-visual--leading\">\n          <span data-view-component=\"true\" class=\"d-flex flex-items-center\">    <svg style=\"box-sizing: content-box; color: var(--color-icon-primary);\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" data-view-component=\"true\" class=\"anim-rotate\">\n  <circle cx=\"8\" cy=\"8\" r=\"7\" stroke=\"currentColor\" stroke-opacity=\"0.25\" stroke-width=\"2\" vector-effect=\"non-scaling-stroke\" fill=\"none\" />\n  <path d=\"M15 8a7.002 7.002 0 00-7-7\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" vector-effect=\"non-scaling-stroke\" />\n</svg>\n</span>\n        </span>\n      \n        <span data-view-component=\"true\" class=\"ActionListItem-label\">\n          \n\n  <span class=\"color-fg-muted\">\n    Loading...\n  </span>\n\n</span></button>\n  \n</li>\n\n        \n          \n<li data-item-id=\"\" data-targets=\"nav-list.items\" data-view-component=\"true\" class=\"ActionListItem\">\n    \n    \n    <a data-analytics-event=\"{&quot;category&quot;:&quot;Global navigation&quot;,&quot;action&quot;:&quot;SETTINGS&quot;,&quot;label&quot;:null}\" id=\"item-ff9358fd-c863-4797-bd8d-7a3e4843ca1a\" href=\"/settings/profile\" data-view-component=\"true\" class=\"ActionListContent ActionListContent--visual16\">\n        <span class=\"ActionListItem-visual ActionListItem-visual--leading\">\n          <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-gear\">\n    <path d=\"M8 0a8.2 8.2 0 0 1 .701.031C9.444.095 9.99.645 10.16 1.29l.288 1.107c.018.066.079.158.212.224.231.114.454.243.668.386.123.082.233.09.299.071l1.103-.303c.644-.176 1.392.021 1.82.63.27.385.506.792.704 1.218.315.675.111 1.422-.364 1.891l-.814.806c-.049.048-.098.147-.088.294.016.257.016.515 0 .772-.01.147.038.246.088.294l.814.806c.475.469.679 1.216.364 1.891a7.977 7.977 0 0 1-.704 1.217c-.428.61-1.176.807-1.82.63l-1.102-.302c-.067-.019-.177-.011-.3.071a5.909 5.909 0 0 1-.668.386c-.133.066-.194.158-.211.224l-.29 1.106c-.168.646-.715 1.196-1.458 1.26a8.006 8.006 0 0 1-1.402 0c-.743-.064-1.289-.614-1.458-1.26l-.289-1.106c-.018-.066-.079-.158-.212-.224a5.738 5.738 0 0 1-.668-.386c-.123-.082-.233-.09-.299-.071l-1.103.303c-.644.176-1.392-.021-1.82-.63a8.12 8.12 0 0 1-.704-1.218c-.315-.675-.111-1.422.363-1.891l.815-.806c.05-.048.098-.147.088-.294a6.214 6.214 0 0 1 0-.772c.01-.147-.038-.246-.088-.294l-.815-.806C.635 6.045.431 5.298.746 4.623a7.92 7.92 0 0 1 .704-1.217c.428-.61 1.176-.807 1.82-.63l1.102.302c.067.019.177.011.3-.071.214-.143.437-.272.668-.386.133-.066.194-.158.211-.224l.29-1.106C6.009.645 6.556.095 7.299.03 7.53.01 7.764 0 8 0Zm-.571 1.525c-.036.003-.108.036-.137.146l-.289 1.105c-.147.561-.549.967-.998 1.189-.173.086-.34.183-.5.29-.417.278-.97.423-1.529.27l-1.103-.303c-.109-.03-.175.016-.195.045-.22.312-.412.644-.573.99-.014.031-.021.11.059.19l.815.806c.411.406.562.957.53 1.456a4.709 4.709 0 0 0 0 .582c.032.499-.119 1.05-.53 1.456l-.815.806c-.081.08-.073.159-.059.19.162.346.353.677.573.989.02.03.085.076.195.046l1.102-.303c.56-.153 1.113-.008 1.53.27.161.107.328.204.501.29.447.222.85.629.997 1.189l.289 1.105c.029.109.101.143.137.146a6.6 6.6 0 0 0 1.142 0c.036-.003.108-.036.137-.146l.289-1.105c.147-.561.549-.967.998-1.189.173-.086.34-.183.5-.29.417-.278.97-.423 1.529-.27l1.103.303c.109.029.175-.016.195-.045.22-.313.411-.644.573-.99.014-.031.021-.11-.059-.19l-.815-.806c-.411-.406-.562-.957-.53-1.456a4.709 4.709 0 0 0 0-.582c-.032-.499.119-1.05.53-1.456l.815-.806c.081-.08.073-.159.059-.19a6.464 6.464 0 0 0-.573-.989c-.02-.03-.085-.076-.195-.046l-1.102.303c-.56.153-1.113.008-1.53-.27a4.44 4.44 0 0 0-.501-.29c-.447-.222-.85-.629-.997-1.189l-.289-1.105c-.029-.11-.101-.143-.137-.146a6.6 6.6 0 0 0-1.142 0ZM11 8a3 3 0 1 1-6 0 3 3 0 0 1 6 0ZM9.5 8a1.5 1.5 0 1 0-3.001.001A1.5 1.5 0 0 0 9.5 8Z\"></path>\n</svg>\n        </span>\n      \n        <span data-view-component=\"true\" class=\"ActionListItem-label\">\n          Settings\n</span></a>\n  \n</li>\n\n        \n          <li role=\"presentation\" aria-hidden=\"true\" data-view-component=\"true\" class=\"ActionList-sectionDivider\"></li>\n        \n          \n<li data-item-id=\"\" data-targets=\"nav-list.items\" data-view-component=\"true\" class=\"ActionListItem\">\n    \n    \n    <a data-analytics-event=\"{&quot;category&quot;:&quot;Global navigation&quot;,&quot;action&quot;:&quot;SUPPORT&quot;,&quot;label&quot;:null}\" id=\"item-5dc069b6-8380-4554-b366-18399c0248d7\" href=\"https://support.github.com\" data-view-component=\"true\" class=\"ActionListContent ActionListContent--visual16\">\n        <span class=\"ActionListItem-visual ActionListItem-visual--leading\">\n          <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-people\">\n    <path d=\"M2 5.5a3.5 3.5 0 1 1 5.898 2.549 5.508 5.508 0 0 1 3.034 4.084.75.75 0 1 1-1.482.235 4 4 0 0 0-7.9 0 .75.75 0 0 1-1.482-.236A5.507 5.507 0 0 1 3.102 8.05 3.493 3.493 0 0 1 2 5.5ZM11 4a3.001 3.001 0 0 1 2.22 5.018 5.01 5.01 0 0 1 2.56 3.012.749.749 0 0 1-.885.954.752.752 0 0 1-.549-.514 3.507 3.507 0 0 0-2.522-2.372.75.75 0 0 1-.574-.73v-.352a.75.75 0 0 1 .416-.672A1.5 1.5 0 0 0 11 5.5.75.75 0 0 1 11 4Zm-5.5-.5a2 2 0 1 0-.001 3.999A2 2 0 0 0 5.5 3.5Z\"></path>\n</svg>\n        </span>\n      \n        <span data-view-component=\"true\" class=\"ActionListItem-label\">\n          GitHub Support\n</span></a>\n  \n</li>\n\n        \n          \n<li data-item-id=\"\" data-targets=\"nav-list.items\" data-view-component=\"true\" class=\"ActionListItem\">\n    \n    \n    <a data-analytics-event=\"{&quot;category&quot;:&quot;Global navigation&quot;,&quot;action&quot;:&quot;COMMUNITY&quot;,&quot;label&quot;:null}\" id=\"item-a0dbf441-a840-44f3-ad84-69528d9cd70c\" href=\"https://community.github.com\" data-view-component=\"true\" class=\"ActionListContent ActionListContent--visual16\">\n        <span class=\"ActionListItem-visual ActionListItem-visual--leading\">\n          <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-comment-discussion\">\n    <path d=\"M1.75 1h8.5c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 10.25 10H7.061l-2.574 2.573A1.458 1.458 0 0 1 2 11.543V10h-.25A1.75 1.75 0 0 1 0 8.25v-5.5C0 1.784.784 1 1.75 1ZM1.5 2.75v5.5c0 .138.112.25.25.25h1a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h3.5a.25.25 0 0 0 .25-.25v-5.5a.25.25 0 0 0-.25-.25h-8.5a.25.25 0 0 0-.25.25Zm13 2a.25.25 0 0 0-.25-.25h-.5a.75.75 0 0 1 0-1.5h.5c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 14.25 12H14v1.543a1.458 1.458 0 0 1-2.487 1.03L9.22 12.28a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215l2.22 2.22v-2.19a.75.75 0 0 1 .75-.75h1a.25.25 0 0 0 .25-.25Z\"></path>\n</svg>\n        </span>\n      \n        <span data-view-component=\"true\" class=\"ActionListItem-label\">\n          GitHub Community\n</span></a>\n  \n</li>\n\n        \n          <li role=\"presentation\" aria-hidden=\"true\" data-view-component=\"true\" class=\"ActionList-sectionDivider\"></li>\n        \n          \n<li data-item-id=\"\" data-targets=\"nav-list.items\" data-view-component=\"true\" class=\"ActionListItem\">\n    \n    \n    <a data-analytics-event=\"{&quot;category&quot;:&quot;Global navigation&quot;,&quot;action&quot;:&quot;LOGOUT&quot;,&quot;label&quot;:null}\" id=\"item-7fe37573-9998-4297-885a-e5ca49d4babc\" href=\"/logout\" data-view-component=\"true\" class=\"ActionListContent\">\n      \n        <span data-view-component=\"true\" class=\"ActionListItem-label\">\n          Sign out\n</span></a>\n  \n</li>\n\n</ul>  </nav-list>\n</nav>\n\n\n</div>\n</div>\n      </scrollable-region>\n      \n</dialog></dialog-helper>\n    </user-drawer-side-panel>\n\n  </include-fragment>\n</deferred-side-panel>\n        </div>\n\n        <div class=\"position-absolute mt-2\">\n            \n<site-header-logged-in-user-menu>\n\n</site-header-logged-in-user-menu>\n\n        </div>\n      </div>\n    </div>\n\n\n      <div class=\"AppHeader-localBar\" >\n        <nav data-pjax=\"#js-repo-pjax-container\" aria-label=\"Repository\" data-view-component=\"true\" class=\"js-repo-nav js-sidenav-container-pjax js-responsive-underlinenav overflow-hidden UnderlineNav\">\n\n  <ul data-view-component=\"true\" class=\"UnderlineNav-body list-style-none\">\n      <li data-view-component=\"true\" class=\"d-inline-flex\">\n  <a id=\"code-tab\" href=\"/mouredev/roadmap-retos-programacion\" data-tab-item=\"i0code-tab\" data-selected-links=\"repo_source repo_downloads repo_commits repo_releases repo_tags repo_branches repo_packages repo_deployments repo_attestations /mouredev/roadmap-retos-programacion\" data-pjax=\"#repo-content-pjax-container\" data-turbo-frame=\"repo-content-turbo-frame\" data-hotkey=\"g c\" data-analytics-event=\"{&quot;category&quot;:&quot;Underline navbar&quot;,&quot;action&quot;:&quot;Click tab&quot;,&quot;label&quot;:&quot;Code&quot;,&quot;target&quot;:&quot;UNDERLINE_NAV.TAB&quot;}\" data-view-component=\"true\" class=\"UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item\">\n    \n              <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-code UnderlineNav-octicon d-none d-sm-inline\">\n    <path d=\"m11.28 3.22 4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L13.94 8l-3.72-3.72a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215Zm-6.56 0a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L2.06 8l3.72 3.72a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L.47 8.53a.75.75 0 0 1 0-1.06Z\"></path>\n</svg>\n        <span data-content=\"Code\">Code</span>\n          <span id=\"code-repo-tab-count\" data-pjax-replace=\"\" data-turbo-replace=\"\" title=\"Not available\" data-view-component=\"true\" class=\"Counter\"></span>\n\n\n    \n</a></li>\n      <li data-view-component=\"true\" class=\"d-inline-flex\">\n  <a id=\"issues-tab\" href=\"/mouredev/roadmap-retos-programacion/issues\" data-tab-item=\"i1issues-tab\" data-selected-links=\"repo_issues repo_labels repo_milestones /mouredev/roadmap-retos-programacion/issues\" data-pjax=\"#repo-content-pjax-container\" data-turbo-frame=\"repo-content-turbo-frame\" data-hotkey=\"g i\" data-analytics-event=\"{&quot;category&quot;:&quot;Underline navbar&quot;,&quot;action&quot;:&quot;Click tab&quot;,&quot;label&quot;:&quot;Issues&quot;,&quot;target&quot;:&quot;UNDERLINE_NAV.TAB&quot;}\" data-view-component=\"true\" class=\"UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item\">\n    \n              <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-issue-opened UnderlineNav-octicon d-none d-sm-inline\">\n    <path d=\"M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z\"></path><path d=\"M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Z\"></path>\n</svg>\n        <span data-content=\"Issues\">Issues</span>\n          <span id=\"issues-repo-tab-count\" data-pjax-replace=\"\" data-turbo-replace=\"\" title=\"2\" data-view-component=\"true\" class=\"Counter\">2</span>\n\n\n    \n</a></li>\n      <li data-view-component=\"true\" class=\"d-inline-flex\">\n  <a id=\"pull-requests-tab\" href=\"/mouredev/roadmap-retos-programacion/pulls\" data-tab-item=\"i2pull-requests-tab\" data-selected-links=\"repo_pulls checks /mouredev/roadmap-retos-programacion/pulls\" data-pjax=\"#repo-content-pjax-container\" data-turbo-frame=\"repo-content-turbo-frame\" data-hotkey=\"g p\" data-analytics-event=\"{&quot;category&quot;:&quot;Underline navbar&quot;,&quot;action&quot;:&quot;Click tab&quot;,&quot;label&quot;:&quot;Pull requests&quot;,&quot;target&quot;:&quot;UNDERLINE_NAV.TAB&quot;}\" data-view-component=\"true\" class=\"UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item\">\n    \n              <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-git-pull-request UnderlineNav-octicon d-none d-sm-inline\">\n    <path d=\"M1.5 3.25a2.25 2.25 0 1 1 3 2.122v5.256a2.251 2.251 0 1 1-1.5 0V5.372A2.25 2.25 0 0 1 1.5 3.25Zm5.677-.177L9.573.677A.25.25 0 0 1 10 .854V2.5h1A2.5 2.5 0 0 1 13.5 5v5.628a2.251 2.251 0 1 1-1.5 0V5a1 1 0 0 0-1-1h-1v1.646a.25.25 0 0 1-.427.177L7.177 3.427a.25.25 0 0 1 0-.354ZM3.75 2.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm0 9.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm8.25.75a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Z\"></path>\n</svg>\n        <span data-content=\"Pull requests\">Pull requests</span>\n          <span id=\"pull-requests-repo-tab-count\" data-pjax-replace=\"\" data-turbo-replace=\"\" title=\"14\" data-view-component=\"true\" class=\"Counter\">14</span>\n\n\n    \n</a></li>\n      <li data-view-component=\"true\" class=\"d-inline-flex\">\n  <a id=\"actions-tab\" href=\"/mouredev/roadmap-retos-programacion/actions\" data-tab-item=\"i3actions-tab\" data-selected-links=\"repo_actions /mouredev/roadmap-retos-programacion/actions\" data-pjax=\"#repo-content-pjax-container\" data-turbo-frame=\"repo-content-turbo-frame\" data-hotkey=\"g a\" data-analytics-event=\"{&quot;category&quot;:&quot;Underline navbar&quot;,&quot;action&quot;:&quot;Click tab&quot;,&quot;label&quot;:&quot;Actions&quot;,&quot;target&quot;:&quot;UNDERLINE_NAV.TAB&quot;}\" data-view-component=\"true\" class=\"UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item\">\n    \n              <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-play UnderlineNav-octicon d-none d-sm-inline\">\n    <path d=\"M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Zm4.879-2.773 4.264 2.559a.25.25 0 0 1 0 .428l-4.264 2.559A.25.25 0 0 1 6 10.559V5.442a.25.25 0 0 1 .379-.215Z\"></path>\n</svg>\n        <span data-content=\"Actions\">Actions</span>\n          <span id=\"actions-repo-tab-count\" data-pjax-replace=\"\" data-turbo-replace=\"\" title=\"Not available\" data-view-component=\"true\" class=\"Counter\"></span>\n\n\n    \n</a></li>\n      <li data-view-component=\"true\" class=\"d-inline-flex\">\n  <a id=\"projects-tab\" href=\"/mouredev/roadmap-retos-programacion/projects\" data-tab-item=\"i4projects-tab\" data-selected-links=\"repo_projects new_repo_project repo_project /mouredev/roadmap-retos-programacion/projects\" data-pjax=\"#repo-content-pjax-container\" data-turbo-frame=\"repo-content-turbo-frame\" data-hotkey=\"g b\" data-analytics-event=\"{&quot;category&quot;:&quot;Underline navbar&quot;,&quot;action&quot;:&quot;Click tab&quot;,&quot;label&quot;:&quot;Projects&quot;,&quot;target&quot;:&quot;UNDERLINE_NAV.TAB&quot;}\" data-view-component=\"true\" class=\"UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item\">\n    \n              <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-table UnderlineNav-octicon d-none d-sm-inline\">\n    <path d=\"M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25ZM6.5 6.5v8h7.75a.25.25 0 0 0 .25-.25V6.5Zm8-1.5V1.75a.25.25 0 0 0-.25-.25H6.5V5Zm-13 1.5v7.75c0 .138.112.25.25.25H5v-8ZM5 5V1.5H1.75a.25.25 0 0 0-.25.25V5Z\"></path>\n</svg>\n        <span data-content=\"Projects\">Projects</span>\n          <span id=\"projects-repo-tab-count\" data-pjax-replace=\"\" data-turbo-replace=\"\" title=\"0\" hidden=\"hidden\" data-view-component=\"true\" class=\"Counter\">0</span>\n\n\n    \n</a></li>\n      <li data-view-component=\"true\" class=\"d-inline-flex\">\n  <a id=\"wiki-tab\" href=\"/mouredev/roadmap-retos-programacion/wiki\" data-tab-item=\"i5wiki-tab\" data-selected-links=\"repo_wiki /mouredev/roadmap-retos-programacion/wiki\" data-pjax=\"#repo-content-pjax-container\" data-turbo-frame=\"repo-content-turbo-frame\" data-hotkey=\"g w\" data-analytics-event=\"{&quot;category&quot;:&quot;Underline navbar&quot;,&quot;action&quot;:&quot;Click tab&quot;,&quot;label&quot;:&quot;Wiki&quot;,&quot;target&quot;:&quot;UNDERLINE_NAV.TAB&quot;}\" data-view-component=\"true\" class=\"UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item\">\n    \n              <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-book UnderlineNav-octicon d-none d-sm-inline\">\n    <path d=\"M0 1.75A.75.75 0 0 1 .75 1h4.253c1.227 0 2.317.59 3 1.501A3.743 3.743 0 0 1 11.006 1h4.245a.75.75 0 0 1 .75.75v10.5a.75.75 0 0 1-.75.75h-4.507a2.25 2.25 0 0 0-1.591.659l-.622.621a.75.75 0 0 1-1.06 0l-.622-.621A2.25 2.25 0 0 0 5.258 13H.75a.75.75 0 0 1-.75-.75Zm7.251 10.324.004-5.073-.002-2.253A2.25 2.25 0 0 0 5.003 2.5H1.5v9h3.757a3.75 3.75 0 0 1 1.994.574ZM8.755 4.75l-.004 7.322a3.752 3.752 0 0 1 1.992-.572H14.5v-9h-3.495a2.25 2.25 0 0 0-2.25 2.25Z\"></path>\n</svg>\n        <span data-content=\"Wiki\">Wiki</span>\n          <span id=\"wiki-repo-tab-count\" data-pjax-replace=\"\" data-turbo-replace=\"\" title=\"Not available\" data-view-component=\"true\" class=\"Counter\"></span>\n\n\n    \n</a></li>\n      <li data-view-component=\"true\" class=\"d-inline-flex\">\n  <a id=\"security-tab\" href=\"/mouredev/roadmap-retos-programacion/security\" data-tab-item=\"i6security-tab\" data-selected-links=\"security overview alerts policy token_scanning code_scanning /mouredev/roadmap-retos-programacion/security\" data-pjax=\"#repo-content-pjax-container\" data-turbo-frame=\"repo-content-turbo-frame\" data-hotkey=\"g s\" data-analytics-event=\"{&quot;category&quot;:&quot;Underline navbar&quot;,&quot;action&quot;:&quot;Click tab&quot;,&quot;label&quot;:&quot;Security&quot;,&quot;target&quot;:&quot;UNDERLINE_NAV.TAB&quot;}\" data-view-component=\"true\" class=\"UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item\">\n    \n              <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-shield UnderlineNav-octicon d-none d-sm-inline\">\n    <path d=\"M7.467.133a1.748 1.748 0 0 1 1.066 0l5.25 1.68A1.75 1.75 0 0 1 15 3.48V7c0 1.566-.32 3.182-1.303 4.682-.983 1.498-2.585 2.813-5.032 3.855a1.697 1.697 0 0 1-1.33 0c-2.447-1.042-4.049-2.357-5.032-3.855C1.32 10.182 1 8.566 1 7V3.48a1.75 1.75 0 0 1 1.217-1.667Zm.61 1.429a.25.25 0 0 0-.153 0l-5.25 1.68a.25.25 0 0 0-.174.238V7c0 1.358.275 2.666 1.057 3.86.784 1.194 2.121 2.34 4.366 3.297a.196.196 0 0 0 .154 0c2.245-.956 3.582-2.104 4.366-3.298C13.225 9.666 13.5 8.36 13.5 7V3.48a.251.251 0 0 0-.174-.237l-5.25-1.68ZM8.75 4.75v3a.75.75 0 0 1-1.5 0v-3a.75.75 0 0 1 1.5 0ZM9 10.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\"></path>\n</svg>\n        <span data-content=\"Security\">Security</span>\n          <include-fragment src=\"/mouredev/roadmap-retos-programacion/security/overall-count\" accept=\"text/fragment+html\"></include-fragment>\n\n    \n</a></li>\n      <li data-view-component=\"true\" class=\"d-inline-flex\">\n  <a id=\"insights-tab\" href=\"/mouredev/roadmap-retos-programacion/pulse\" data-tab-item=\"i7insights-tab\" data-selected-links=\"repo_graphs repo_contributors dependency_graph dependabot_updates pulse people community /mouredev/roadmap-retos-programacion/pulse\" data-pjax=\"#repo-content-pjax-container\" data-turbo-frame=\"repo-content-turbo-frame\" data-analytics-event=\"{&quot;category&quot;:&quot;Underline navbar&quot;,&quot;action&quot;:&quot;Click tab&quot;,&quot;label&quot;:&quot;Insights&quot;,&quot;target&quot;:&quot;UNDERLINE_NAV.TAB&quot;}\" data-view-component=\"true\" class=\"UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item\">\n    \n              <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-graph UnderlineNav-octicon d-none d-sm-inline\">\n    <path d=\"M1.5 1.75V13.5h13.75a.75.75 0 0 1 0 1.5H.75a.75.75 0 0 1-.75-.75V1.75a.75.75 0 0 1 1.5 0Zm14.28 2.53-5.25 5.25a.75.75 0 0 1-1.06 0L7 7.06 4.28 9.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.25-3.25a.75.75 0 0 1 1.06 0L10 7.94l4.72-4.72a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z\"></path>\n</svg>\n        <span data-content=\"Insights\">Insights</span>\n          <span id=\"insights-repo-tab-count\" data-pjax-replace=\"\" data-turbo-replace=\"\" title=\"Not available\" data-view-component=\"true\" class=\"Counter\"></span>\n\n\n    \n</a></li>\n</ul>\n    <div style=\"visibility:hidden;\" data-view-component=\"true\" class=\"UnderlineNav-actions js-responsive-underlinenav-overflow position-absolute pr-3 pr-md-4 pr-lg-5 right-0\">      <action-menu data-select-variant=\"none\" data-view-component=\"true\">\n  <focus-group direction=\"vertical\" mnemonics retain>\n    <button id=\"action-menu-1b92d7c5-f52b-48ed-83ed-13ea051830e0-button\" popovertarget=\"action-menu-1b92d7c5-f52b-48ed-83ed-13ea051830e0-overlay\" aria-controls=\"action-menu-1b92d7c5-f52b-48ed-83ed-13ea051830e0-list\" aria-haspopup=\"true\" aria-labelledby=\"tooltip-2f78e616-24e8-4857-a93a-271c6e17070e\" type=\"button\" data-view-component=\"true\" class=\"Button Button--iconOnly Button--secondary Button--medium UnderlineNav-item\">  <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-kebab-horizontal Button-visual\">\n    <path d=\"M8 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM1.5 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm13 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z\"></path>\n</svg>\n</button><tool-tip id=\"tooltip-2f78e616-24e8-4857-a93a-271c6e17070e\" for=\"action-menu-1b92d7c5-f52b-48ed-83ed-13ea051830e0-button\" popover=\"manual\" data-direction=\"s\" data-type=\"label\" data-view-component=\"true\" class=\"sr-only position-absolute\">Additional navigation options</tool-tip>\n\n\n<anchored-position id=\"action-menu-1b92d7c5-f52b-48ed-83ed-13ea051830e0-overlay\" anchor=\"action-menu-1b92d7c5-f52b-48ed-83ed-13ea051830e0-button\" align=\"start\" side=\"outside-bottom\" anchor-offset=\"normal\" popover=\"auto\" data-view-component=\"true\">\n  <div data-view-component=\"true\" class=\"Overlay Overlay--size-auto\">\n    \n      <div data-view-component=\"true\" class=\"Overlay-body Overlay-body--paddingNone\">          <action-list>\n  <div data-view-component=\"true\">\n    <ul aria-labelledby=\"action-menu-1b92d7c5-f52b-48ed-83ed-13ea051830e0-button\" id=\"action-menu-1b92d7c5-f52b-48ed-83ed-13ea051830e0-list\" role=\"menu\" data-view-component=\"true\" class=\"ActionListWrap--inset ActionListWrap\">\n        <li hidden=\"hidden\" data-menu-item=\"i0code-tab\" data-targets=\"action-list.items\" role=\"none\" data-view-component=\"true\" class=\"ActionListItem\">\n    \n    \n    <a tabindex=\"-1\" id=\"item-55987a50-0e95-47f3-b1a4-2aaf2c6988fc\" href=\"/mouredev/roadmap-retos-programacion\" role=\"menuitem\" data-view-component=\"true\" class=\"ActionListContent ActionListContent--visual16\">\n        <span class=\"ActionListItem-visual ActionListItem-visual--leading\">\n          <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-code\">\n    <path d=\"m11.28 3.22 4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L13.94 8l-3.72-3.72a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215Zm-6.56 0a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L2.06 8l3.72 3.72a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L.47 8.53a.75.75 0 0 1 0-1.06Z\"></path>\n</svg>\n        </span>\n      \n        <span data-view-component=\"true\" class=\"ActionListItem-label\">\n          Code\n</span></a>\n  \n</li>\n        <li hidden=\"hidden\" data-menu-item=\"i1issues-tab\" data-targets=\"action-list.items\" role=\"none\" data-view-component=\"true\" class=\"ActionListItem\">\n    \n    \n    <a tabindex=\"-1\" id=\"item-bc7e575e-df08-43cd-9fa1-8719d054b2f3\" href=\"/mouredev/roadmap-retos-programacion/issues\" role=\"menuitem\" data-view-component=\"true\" class=\"ActionListContent ActionListContent--visual16\">\n        <span class=\"ActionListItem-visual ActionListItem-visual--leading\">\n          <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-issue-opened\">\n    <path d=\"M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z\"></path><path d=\"M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Z\"></path>\n</svg>\n        </span>\n      \n        <span data-view-component=\"true\" class=\"ActionListItem-label\">\n          Issues\n</span></a>\n  \n</li>\n        <li hidden=\"hidden\" data-menu-item=\"i2pull-requests-tab\" data-targets=\"action-list.items\" role=\"none\" data-view-component=\"true\" class=\"ActionListItem\">\n    \n    \n    <a tabindex=\"-1\" id=\"item-d7ff5841-229a-4936-ac98-f5596aefe4fb\" href=\"/mouredev/roadmap-retos-programacion/pulls\" role=\"menuitem\" data-view-component=\"true\" class=\"ActionListContent ActionListContent--visual16\">\n        <span class=\"ActionListItem-visual ActionListItem-visual--leading\">\n          <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-git-pull-request\">\n    <path d=\"M1.5 3.25a2.25 2.25 0 1 1 3 2.122v5.256a2.251 2.251 0 1 1-1.5 0V5.372A2.25 2.25 0 0 1 1.5 3.25Zm5.677-.177L9.573.677A.25.25 0 0 1 10 .854V2.5h1A2.5 2.5 0 0 1 13.5 5v5.628a2.251 2.251 0 1 1-1.5 0V5a1 1 0 0 0-1-1h-1v1.646a.25.25 0 0 1-.427.177L7.177 3.427a.25.25 0 0 1 0-.354ZM3.75 2.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm0 9.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm8.25.75a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Z\"></path>\n</svg>\n        </span>\n      \n        <span data-view-component=\"true\" class=\"ActionListItem-label\">\n          Pull requests\n</span></a>\n  \n</li>\n        <li hidden=\"hidden\" data-menu-item=\"i3actions-tab\" data-targets=\"action-list.items\" role=\"none\" data-view-component=\"true\" class=\"ActionListItem\">\n    \n    \n    <a tabindex=\"-1\" id=\"item-89976f6a-110d-414c-a052-4a9fa5e3db38\" href=\"/mouredev/roadmap-retos-programacion/actions\" role=\"menuitem\" data-view-component=\"true\" class=\"ActionListContent ActionListContent--visual16\">\n        <span class=\"ActionListItem-visual ActionListItem-visual--leading\">\n          <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-play\">\n    <path d=\"M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Zm4.879-2.773 4.264 2.559a.25.25 0 0 1 0 .428l-4.264 2.559A.25.25 0 0 1 6 10.559V5.442a.25.25 0 0 1 .379-.215Z\"></path>\n</svg>\n        </span>\n      \n        <span data-view-component=\"true\" class=\"ActionListItem-label\">\n          Actions\n</span></a>\n  \n</li>\n        <li hidden=\"hidden\" data-menu-item=\"i4projects-tab\" data-targets=\"action-list.items\" role=\"none\" data-view-component=\"true\" class=\"ActionListItem\">\n    \n    \n    <a tabindex=\"-1\" id=\"item-b63fe06f-c8d5-4808-8acf-0dce48ad1a6a\" href=\"/mouredev/roadmap-retos-programacion/projects\" role=\"menuitem\" data-view-component=\"true\" class=\"ActionListContent ActionListContent--visual16\">\n        <span class=\"ActionListItem-visual ActionListItem-visual--leading\">\n          <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-table\">\n    <path d=\"M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25ZM6.5 6.5v8h7.75a.25.25 0 0 0 .25-.25V6.5Zm8-1.5V1.75a.25.25 0 0 0-.25-.25H6.5V5Zm-13 1.5v7.75c0 .138.112.25.25.25H5v-8ZM5 5V1.5H1.75a.25.25 0 0 0-.25.25V5Z\"></path>\n</svg>\n        </span>\n      \n        <span data-view-component=\"true\" class=\"ActionListItem-label\">\n          Projects\n</span></a>\n  \n</li>\n        <li hidden=\"hidden\" data-menu-item=\"i5wiki-tab\" data-targets=\"action-list.items\" role=\"none\" data-view-component=\"true\" class=\"ActionListItem\">\n    \n    \n    <a tabindex=\"-1\" id=\"item-b9648d16-3b54-4acf-b0a7-8d71f759e981\" href=\"/mouredev/roadmap-retos-programacion/wiki\" role=\"menuitem\" data-view-component=\"true\" class=\"ActionListContent ActionListContent--visual16\">\n        <span class=\"ActionListItem-visual ActionListItem-visual--leading\">\n          <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-book\">\n    <path d=\"M0 1.75A.75.75 0 0 1 .75 1h4.253c1.227 0 2.317.59 3 1.501A3.743 3.743 0 0 1 11.006 1h4.245a.75.75 0 0 1 .75.75v10.5a.75.75 0 0 1-.75.75h-4.507a2.25 2.25 0 0 0-1.591.659l-.622.621a.75.75 0 0 1-1.06 0l-.622-.621A2.25 2.25 0 0 0 5.258 13H.75a.75.75 0 0 1-.75-.75Zm7.251 10.324.004-5.073-.002-2.253A2.25 2.25 0 0 0 5.003 2.5H1.5v9h3.757a3.75 3.75 0 0 1 1.994.574ZM8.755 4.75l-.004 7.322a3.752 3.752 0 0 1 1.992-.572H14.5v-9h-3.495a2.25 2.25 0 0 0-2.25 2.25Z\"></path>\n</svg>\n        </span>\n      \n        <span data-view-component=\"true\" class=\"ActionListItem-label\">\n          Wiki\n</span></a>\n  \n</li>\n        <li hidden=\"hidden\" data-menu-item=\"i6security-tab\" data-targets=\"action-list.items\" role=\"none\" data-view-component=\"true\" class=\"ActionListItem\">\n    \n    \n    <a tabindex=\"-1\" id=\"item-3ca9d918-a497-4185-b6ca-20f3fe4758fa\" href=\"/mouredev/roadmap-retos-programacion/security\" role=\"menuitem\" data-view-component=\"true\" class=\"ActionListContent ActionListContent--visual16\">\n        <span class=\"ActionListItem-visual ActionListItem-visual--leading\">\n          <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-shield\">\n    <path d=\"M7.467.133a1.748 1.748 0 0 1 1.066 0l5.25 1.68A1.75 1.75 0 0 1 15 3.48V7c0 1.566-.32 3.182-1.303 4.682-.983 1.498-2.585 2.813-5.032 3.855a1.697 1.697 0 0 1-1.33 0c-2.447-1.042-4.049-2.357-5.032-3.855C1.32 10.182 1 8.566 1 7V3.48a1.75 1.75 0 0 1 1.217-1.667Zm.61 1.429a.25.25 0 0 0-.153 0l-5.25 1.68a.25.25 0 0 0-.174.238V7c0 1.358.275 2.666 1.057 3.86.784 1.194 2.121 2.34 4.366 3.297a.196.196 0 0 0 .154 0c2.245-.956 3.582-2.104 4.366-3.298C13.225 9.666 13.5 8.36 13.5 7V3.48a.251.251 0 0 0-.174-.237l-5.25-1.68ZM8.75 4.75v3a.75.75 0 0 1-1.5 0v-3a.75.75 0 0 1 1.5 0ZM9 10.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\"></path>\n</svg>\n        </span>\n      \n        <span data-view-component=\"true\" class=\"ActionListItem-label\">\n          Security\n</span></a>\n  \n</li>\n        <li hidden=\"hidden\" data-menu-item=\"i7insights-tab\" data-targets=\"action-list.items\" role=\"none\" data-view-component=\"true\" class=\"ActionListItem\">\n    \n    \n    <a tabindex=\"-1\" id=\"item-6ebceda7-8a6f-433b-afbe-4617e9e23432\" href=\"/mouredev/roadmap-retos-programacion/pulse\" role=\"menuitem\" data-view-component=\"true\" class=\"ActionListContent ActionListContent--visual16\">\n        <span class=\"ActionListItem-visual ActionListItem-visual--leading\">\n          <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-graph\">\n    <path d=\"M1.5 1.75V13.5h13.75a.75.75 0 0 1 0 1.5H.75a.75.75 0 0 1-.75-.75V1.75a.75.75 0 0 1 1.5 0Zm14.28 2.53-5.25 5.25a.75.75 0 0 1-1.06 0L7 7.06 4.28 9.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.25-3.25a.75.75 0 0 1 1.06 0L10 7.94l4.72-4.72a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z\"></path>\n</svg>\n        </span>\n      \n        <span data-view-component=\"true\" class=\"ActionListItem-label\">\n          Insights\n</span></a>\n  \n</li>\n</ul>    \n</div></action-list>\n\n\n</div>\n      \n</div></anchored-position>  </focus-group>\n</action-menu></div>\n</nav>\n      </div>\n</header>\n\n\n      <div hidden=\"hidden\" data-view-component=\"true\" class=\"js-stale-session-flash stale-session-flash flash flash-warn flash-full mb-3\">\n  \n        <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-alert\">\n    <path d=\"M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\"></path>\n</svg>\n        <span class=\"js-stale-session-flash-signed-in\" hidden>You signed in with another tab or window. <a class=\"Link--inTextBlock\" href=\"\">Reload</a> to refresh your session.</span>\n        <span class=\"js-stale-session-flash-signed-out\" hidden>You signed out in another tab or window. <a class=\"Link--inTextBlock\" href=\"\">Reload</a> to refresh your session.</span>\n        <span class=\"js-stale-session-flash-switched\" hidden>You switched accounts on another tab or window. <a class=\"Link--inTextBlock\" href=\"\">Reload</a> to refresh your session.</span>\n\n    <button id=\"icon-button-7a720e76-1185-4d97-8f65-801efa46040b\" aria-labelledby=\"tooltip-2fe807d5-bc37-4837-b146-be9536ba7b52\" type=\"button\" data-view-component=\"true\" class=\"Button Button--iconOnly Button--invisible Button--medium flash-close js-flash-close\">  <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-x Button-visual\">\n    <path d=\"M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z\"></path>\n</svg>\n</button><tool-tip id=\"tooltip-2fe807d5-bc37-4837-b146-be9536ba7b52\" for=\"icon-button-7a720e76-1185-4d97-8f65-801efa46040b\" popover=\"manual\" data-direction=\"s\" data-type=\"label\" data-view-component=\"true\" class=\"sr-only position-absolute\">Dismiss alert</tool-tip>\n\n\n  \n</div>\n          \n    </div>\n\n  <div id=\"start-of-content\" class=\"show-on-focus\"></div>\n\n\n\n\n\n\n\n\n    <div id=\"js-flash-container\" class=\"flash-container\" data-turbo-replace>\n\n\n\n\n\n  <template class=\"js-flash-template\">\n    \n<div class=\"flash flash-full   {{ className }}\">\n  <div >\n    <button autofocus class=\"flash-close js-flash-close\" type=\"button\" aria-label=\"Dismiss this message\">\n      <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-x\">\n    <path d=\"M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z\"></path>\n</svg>\n    </button>\n    <div aria-atomic=\"true\" role=\"alert\" class=\"js-flash-alert\">\n      \n      <div>{{ message }}</div>\n\n    </div>\n  </div>\n</div>\n  </template>\n</div>\n\n\n    \n    <notification-shelf-watcher data-base-url=\"https://github.com/notifications/beta/shelf\" data-channel=\"eyJjIjoibm90aWZpY2F0aW9uLWNoYW5nZWQ6ODgwMDgyMzMiLCJ0IjoxNzE2NzQ4OTQzfQ==--b1083487b9b6110891feb4d51836354ff62cc6eb5da8cc09208921b3bb02171d\" data-view-component=\"true\" class=\"js-socket-channel\"></notification-shelf-watcher>\n  <div hidden data-initial data-target=\"notification-shelf-watcher.placeholder\"></div>\n\n\n\n\n\n      <details\n  class=\"details-reset details-overlay details-overlay-dark js-command-palette-dialog\"\n  id=\"command-palette-pjax-container\"\n  data-turbo-replace\n>\n  <summary aria-label=\"Command palette trigger\" tabindex=\"-1\"></summary>\n  <details-dialog class=\"command-palette-details-dialog d-flex flex-column flex-justify-center height-fit\" aria-label=\"Command palette\">\n    <command-palette\n      class=\"command-palette color-bg-default rounded-3 border color-shadow-small\"\n      return-to=/mouredev/roadmap-retos-programacion/blob/main/Roadmap/00%20-%20SINTAXIS%2C%20VARIABLES%2C%20TIPOS%20DE%20DATOS%20Y%20HOLA%20MUNDO/php/GitHjuan.php\n      user-id=\"88008233\"\n      activation-hotkey=\"Mod+k,Mod+Alt+k\"\n      command-mode-hotkey=\"Mod+Shift+K\"\n      data-action=\"\n        command-palette-input-ready:command-palette#inputReady\n        command-palette-page-stack-updated:command-palette#updateInputScope\n        itemsUpdated:command-palette#itemsUpdated\n        keydown:command-palette#onKeydown\n        loadingStateChanged:command-palette#loadingStateChanged\n        selectedItemChanged:command-palette#selectedItemChanged\n        pageFetchError:command-palette#pageFetchError\n      \">\n\n        <command-palette-mode\n          data-char=\"#\"\n            data-scope-types=\"[&quot;&quot;]\"\n            data-placeholder=\"Search issues and pull requests\"\n        ></command-palette-mode>\n        <command-palette-mode\n          data-char=\"#\"\n            data-scope-types=\"[&quot;owner&quot;,&quot;repository&quot;]\"\n            data-placeholder=\"Search issues, pull requests, discussions, and projects\"\n        ></command-palette-mode>\n        <command-palette-mode\n          data-char=\"!\"\n            data-scope-types=\"[&quot;owner&quot;,&quot;repository&quot;]\"\n            data-placeholder=\"Search projects\"\n        ></command-palette-mode>\n        <command-palette-mode\n          data-char=\"@\"\n            data-scope-types=\"[&quot;&quot;]\"\n            data-placeholder=\"Search or jump to a user, organization, or repository\"\n        ></command-palette-mode>\n        <command-palette-mode\n          data-char=\"@\"\n            data-scope-types=\"[&quot;owner&quot;]\"\n            data-placeholder=\"Search or jump to a repository\"\n        ></command-palette-mode>\n        <command-palette-mode\n          data-char=\"/\"\n            data-scope-types=\"[&quot;repository&quot;]\"\n            data-placeholder=\"Search files\"\n        ></command-palette-mode>\n        <command-palette-mode\n          data-char=\"?\"\n        ></command-palette-mode>\n        <command-palette-mode\n          data-char=\"&gt;\"\n            data-placeholder=\"Run a command\"\n        ></command-palette-mode>\n        <command-palette-mode\n          data-char=\"\"\n            data-scope-types=\"[&quot;&quot;]\"\n            data-placeholder=\"Search or jump to...\"\n        ></command-palette-mode>\n        <command-palette-mode\n          data-char=\"\"\n            data-scope-types=\"[&quot;owner&quot;]\"\n            data-placeholder=\"Search or jump to...\"\n        ></command-palette-mode>\n      <command-palette-mode\n        class=\"js-command-palette-default-mode\"\n        data-char=\"\"\n        data-placeholder=\"Search or jump to...\"\n      ></command-palette-mode>\n\n      <command-palette-input placeholder=\"Search or jump to...\"\n\n        data-action=\"\n          command-palette-input:command-palette#onInput\n          command-palette-select:command-palette#onSelect\n          command-palette-descope:command-palette#onDescope\n          command-palette-cleared:command-palette#onInputClear\n        \"\n      >\n        <div class=\"js-search-icon d-flex flex-items-center mr-2\" style=\"height: 26px\">\n          <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-search color-fg-muted\">\n    <path d=\"M10.68 11.74a6 6 0 0 1-7.922-8.982 6 6 0 0 1 8.982 7.922l3.04 3.04a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215ZM11.5 7a4.499 4.499 0 1 0-8.997 0A4.499 4.499 0 0 0 11.5 7Z\"></path>\n</svg>\n        </div>\n        <div class=\"js-spinner d-flex flex-items-center mr-2 color-fg-muted\" hidden>\n          <svg aria-label=\"Loading\" class=\"anim-rotate\" viewBox=\"0 0 16 16\" fill=\"none\" width=\"16\" height=\"16\">\n            <circle\n              cx=\"8\"\n              cy=\"8\"\n              r=\"7\"\n              stroke=\"currentColor\"\n              stroke-opacity=\"0.25\"\n              stroke-width=\"2\"\n              vector-effect=\"non-scaling-stroke\"\n            ></circle>\n            <path\n              d=\"M15 8a7.002 7.002 0 00-7-7\"\n              stroke=\"currentColor\"\n              stroke-width=\"2\"\n              stroke-linecap=\"round\"\n              vector-effect=\"non-scaling-stroke\"\n            ></path>\n          </svg>\n        </div>\n        <command-palette-scope >\n          <div data-target=\"command-palette-scope.placeholder\" hidden class=\"color-fg-subtle\">/&nbsp;&nbsp;<span class=\"text-semibold color-fg-default\">...</span>&nbsp;&nbsp;/&nbsp;&nbsp;</div>\n              <command-palette-token\n                data-text=\"mouredev\"\n                data-id=\"MDQ6VXNlcjE3MDQzNDAy\"\n                data-type=\"owner\"\n                data-value=\"mouredev\"\n                data-targets=\"command-palette-scope.tokens\"\n                class=\"color-fg-default text-semibold\"\n                style=\"white-space:nowrap;line-height:20px;\"\n                >mouredev<span class=\"color-fg-subtle text-normal\">&nbsp;&nbsp;/&nbsp;&nbsp;</span></command-palette-token>\n              <command-palette-token\n                data-text=\"roadmap-retos-programacion\"\n                data-id=\"R_kgDOK7DMTg\"\n                data-type=\"repository\"\n                data-value=\"roadmap-retos-programacion\"\n                data-targets=\"command-palette-scope.tokens\"\n                class=\"color-fg-default text-semibold\"\n                style=\"white-space:nowrap;line-height:20px;\"\n                >roadmap-retos-pro...<span class=\"color-fg-subtle text-normal\">&nbsp;&nbsp;/&nbsp;&nbsp;</span></command-palette-token>\n        </command-palette-scope>\n        <div class=\"command-palette-input-group flex-1 form-control border-0 box-shadow-none\" style=\"z-index: 0\">\n          <div class=\"command-palette-typeahead position-absolute d-flex flex-items-center Truncate\">\n            <span class=\"typeahead-segment input-mirror\" data-target=\"command-palette-input.mirror\"></span>\n            <span class=\"Truncate-text\" data-target=\"command-palette-input.typeaheadText\"></span>\n            <span class=\"typeahead-segment\" data-target=\"command-palette-input.typeaheadPlaceholder\"></span>\n          </div>\n          <input\n            class=\"js-overlay-input typeahead-input d-none\"\n            disabled\n            tabindex=\"-1\"\n            aria-label=\"Hidden input for typeahead\"\n          >\n          <input\n            type=\"text\"\n            autocomplete=\"off\"\n            autocorrect=\"off\"\n            autocapitalize=\"off\"\n            spellcheck=\"false\"\n            class=\"js-input typeahead-input form-control border-0 box-shadow-none input-block width-full no-focus-indicator\"\n            aria-label=\"Command palette input\"\n            aria-haspopup=\"listbox\"\n            aria-expanded=\"false\"\n            aria-autocomplete=\"list\"\n            aria-controls=\"command-palette-page-stack\"\n            role=\"combobox\"\n            data-action=\"\n              input:command-palette-input#onInput\n              keydown:command-palette-input#onKeydown\n            \"\n          >\n        </div>\n          <div data-view-component=\"true\" class=\"position-relative d-inline-block\">\n    <button aria-keyshortcuts=\"Control+Backspace\" data-action=\"click:command-palette-input#onClear keypress:command-palette-input#onClear\" data-target=\"command-palette-input.clearButton\" id=\"command-palette-clear-button\" hidden=\"hidden\" type=\"button\" data-view-component=\"true\" class=\"btn-octicon command-palette-input-clear-button\">      <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-x-circle-fill\">\n    <path d=\"M2.343 13.657A8 8 0 1 1 13.658 2.343 8 8 0 0 1 2.343 13.657ZM6.03 4.97a.751.751 0 0 0-1.042.018.751.751 0 0 0-.018 1.042L6.94 8 4.97 9.97a.749.749 0 0 0 .326 1.275.749.749 0 0 0 .734-.215L8 9.06l1.97 1.97a.749.749 0 0 0 1.275-.326.749.749 0 0 0-.215-.734L9.06 8l1.97-1.97a.749.749 0 0 0-.326-1.275.749.749 0 0 0-.734.215L8 6.94Z\"></path>\n</svg>\n</button>    <tool-tip id=\"tooltip-57918c6c-42ee-4882-b11f-673ce6d20a31\" for=\"command-palette-clear-button\" popover=\"manual\" data-direction=\"w\" data-type=\"label\" data-view-component=\"true\" class=\"sr-only position-absolute\">Clear Command Palette</tool-tip>\n</div>\n      </command-palette-input>\n\n      <command-palette-page-stack\n        data-default-scope-id=\"R_kgDOK7DMTg\"\n        data-default-scope-type=\"Repository\"\n        data-action=\"command-palette-page-octicons-cached:command-palette-page-stack#cacheOcticons\"\n      >\n          <command-palette-tip\n            class=\"color-fg-muted f6 px-3 py-1 my-2\"\n              data-scope-types=\"[&quot;&quot;,&quot;owner&quot;,&quot;repository&quot;]\"\n            data-mode=\"\"\n            data-value=\"\">\n            <div class=\"d-flex flex-items-start flex-justify-between\">\n              <div>\n                <span class=\"text-bold\">Tip:</span>\n                  Type <kbd class=\"hx_kbd\">#</kbd> to search pull requests\n              </div>\n              <div class=\"ml-2 flex-shrink-0\">\n                Type <kbd class=\"hx_kbd\">?</kbd> for help and tips\n              </div>\n            </div>\n          </command-palette-tip>\n          <command-palette-tip\n            class=\"color-fg-muted f6 px-3 py-1 my-2\"\n              data-scope-types=\"[&quot;&quot;,&quot;owner&quot;,&quot;repository&quot;]\"\n            data-mode=\"\"\n            data-value=\"\">\n            <div class=\"d-flex flex-items-start flex-justify-between\">\n              <div>\n                <span class=\"text-bold\">Tip:</span>\n                  Type <kbd class=\"hx_kbd\">#</kbd> to search issues\n              </div>\n              <div class=\"ml-2 flex-shrink-0\">\n                Type <kbd class=\"hx_kbd\">?</kbd> for help and tips\n              </div>\n            </div>\n          </command-palette-tip>\n          <command-palette-tip\n            class=\"color-fg-muted f6 px-3 py-1 my-2\"\n              data-scope-types=\"[&quot;owner&quot;,&quot;repository&quot;]\"\n            data-mode=\"\"\n            data-value=\"\">\n            <div class=\"d-flex flex-items-start flex-justify-between\">\n              <div>\n                <span class=\"text-bold\">Tip:</span>\n                  Type <kbd class=\"hx_kbd\">#</kbd> to search discussions\n              </div>\n              <div class=\"ml-2 flex-shrink-0\">\n                Type <kbd class=\"hx_kbd\">?</kbd> for help and tips\n              </div>\n            </div>\n          </command-palette-tip>\n          <command-palette-tip\n            class=\"color-fg-muted f6 px-3 py-1 my-2\"\n              data-scope-types=\"[&quot;owner&quot;,&quot;repository&quot;]\"\n            data-mode=\"\"\n            data-value=\"\">\n            <div class=\"d-flex flex-items-start flex-justify-between\">\n              <div>\n                <span class=\"text-bold\">Tip:</span>\n                  Type <kbd class=\"hx_kbd\">!</kbd> to search projects\n              </div>\n              <div class=\"ml-2 flex-shrink-0\">\n                Type <kbd class=\"hx_kbd\">?</kbd> for help and tips\n              </div>\n            </div>\n          </command-palette-tip>\n          <command-palette-tip\n            class=\"color-fg-muted f6 px-3 py-1 my-2\"\n              data-scope-types=\"[&quot;owner&quot;]\"\n            data-mode=\"\"\n            data-value=\"\">\n            <div class=\"d-flex flex-items-start flex-justify-between\">\n              <div>\n                <span class=\"text-bold\">Tip:</span>\n                  Type <kbd class=\"hx_kbd\">@</kbd> to search teams\n              </div>\n              <div class=\"ml-2 flex-shrink-0\">\n                Type <kbd class=\"hx_kbd\">?</kbd> for help and tips\n              </div>\n            </div>\n          </command-palette-tip>\n          <command-palette-tip\n            class=\"color-fg-muted f6 px-3 py-1 my-2\"\n              data-scope-types=\"[&quot;&quot;]\"\n            data-mode=\"\"\n            data-value=\"\">\n            <div class=\"d-flex flex-items-start flex-justify-between\">\n              <div>\n                <span class=\"text-bold\">Tip:</span>\n                  Type <kbd class=\"hx_kbd\">@</kbd> to search people and organizations\n              </div>\n              <div class=\"ml-2 flex-shrink-0\">\n                Type <kbd class=\"hx_kbd\">?</kbd> for help and tips\n              </div>\n            </div>\n          </command-palette-tip>\n          <command-palette-tip\n            class=\"color-fg-muted f6 px-3 py-1 my-2\"\n              data-scope-types=\"[&quot;&quot;,&quot;owner&quot;,&quot;repository&quot;]\"\n            data-mode=\"\"\n            data-value=\"\">\n            <div class=\"d-flex flex-items-start flex-justify-between\">\n              <div>\n                <span class=\"text-bold\">Tip:</span>\n                  Type <kbd class=\"hx_kbd\">&gt;</kbd> to activate command mode\n              </div>\n              <div class=\"ml-2 flex-shrink-0\">\n                Type <kbd class=\"hx_kbd\">?</kbd> for help and tips\n              </div>\n            </div>\n          </command-palette-tip>\n          <command-palette-tip\n            class=\"color-fg-muted f6 px-3 py-1 my-2\"\n              data-scope-types=\"[&quot;&quot;,&quot;owner&quot;,&quot;repository&quot;]\"\n            data-mode=\"\"\n            data-value=\"\">\n            <div class=\"d-flex flex-items-start flex-justify-between\">\n              <div>\n                <span class=\"text-bold\">Tip:</span>\n                  Go to your accessibility settings to change your keyboard shortcuts\n              </div>\n              <div class=\"ml-2 flex-shrink-0\">\n                Type <kbd class=\"hx_kbd\">?</kbd> for help and tips\n              </div>\n            </div>\n          </command-palette-tip>\n          <command-palette-tip\n            class=\"color-fg-muted f6 px-3 py-1 my-2\"\n              data-scope-types=\"[&quot;&quot;,&quot;owner&quot;,&quot;repository&quot;]\"\n            data-mode=\"#\"\n            data-value=\"\">\n            <div class=\"d-flex flex-items-start flex-justify-between\">\n              <div>\n                <span class=\"text-bold\">Tip:</span>\n                  Type author:@me to search your content\n              </div>\n              <div class=\"ml-2 flex-shrink-0\">\n                Type <kbd class=\"hx_kbd\">?</kbd> for help and tips\n              </div>\n            </div>\n          </command-palette-tip>\n          <command-palette-tip\n            class=\"color-fg-muted f6 px-3 py-1 my-2\"\n              data-scope-types=\"[&quot;&quot;,&quot;owner&quot;,&quot;repository&quot;]\"\n            data-mode=\"#\"\n            data-value=\"\">\n            <div class=\"d-flex flex-items-start flex-justify-between\">\n              <div>\n                <span class=\"text-bold\">Tip:</span>\n                  Type is:pr to filter to pull requests\n              </div>\n              <div class=\"ml-2 flex-shrink-0\">\n                Type <kbd class=\"hx_kbd\">?</kbd> for help and tips\n              </div>\n            </div>\n          </command-palette-tip>\n          <command-palette-tip\n            class=\"color-fg-muted f6 px-3 py-1 my-2\"\n              data-scope-types=\"[&quot;&quot;,&quot;owner&quot;,&quot;repository&quot;]\"\n            data-mode=\"#\"\n            data-value=\"\">\n            <div class=\"d-flex flex-items-start flex-justify-between\">\n              <div>\n                <span class=\"text-bold\">Tip:</span>\n                  Type is:issue to filter to issues\n              </div>\n              <div class=\"ml-2 flex-shrink-0\">\n                Type <kbd class=\"hx_kbd\">?</kbd> for help and tips\n              </div>\n            </div>\n          </command-palette-tip>\n          <command-palette-tip\n            class=\"color-fg-muted f6 px-3 py-1 my-2\"\n              data-scope-types=\"[&quot;owner&quot;,&quot;repository&quot;]\"\n            data-mode=\"#\"\n            data-value=\"\">\n            <div class=\"d-flex flex-items-start flex-justify-between\">\n              <div>\n                <span class=\"text-bold\">Tip:</span>\n                  Type is:project to filter to projects\n              </div>\n              <div class=\"ml-2 flex-shrink-0\">\n                Type <kbd class=\"hx_kbd\">?</kbd> for help and tips\n              </div>\n            </div>\n          </command-palette-tip>\n          <command-palette-tip\n            class=\"color-fg-muted f6 px-3 py-1 my-2\"\n              data-scope-types=\"[&quot;&quot;,&quot;owner&quot;,&quot;repository&quot;]\"\n            data-mode=\"#\"\n            data-value=\"\">\n            <div class=\"d-flex flex-items-start flex-justify-between\">\n              <div>\n                <span class=\"text-bold\">Tip:</span>\n                  Type is:open to filter to open content\n              </div>\n              <div class=\"ml-2 flex-shrink-0\">\n                Type <kbd class=\"hx_kbd\">?</kbd> for help and tips\n              </div>\n            </div>\n          </command-palette-tip>\n        <command-palette-tip class=\"mx-3 my-2 flash flash-error d-flex flex-items-center\" data-scope-types=\"*\" data-on-error>\n          <div>\n            <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-alert\">\n    <path d=\"M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\"></path>\n</svg>\n          </div>\n          <div class=\"px-2\">\n            We’ve encountered an error and some results aren't available at this time. Type a new search or try again later.\n          </div>\n        </command-palette-tip>\n        <command-palette-tip class=\"h4 color-fg-default pl-3 pb-2 pt-3\" data-on-empty data-scope-types=\"*\" data-match-mode=\"[^?]|^$\">\n          No results matched your search\n        </command-palette-tip>\n\n        <div hidden>\n\n            <div data-targets=\"command-palette-page-stack.localOcticons\" data-octicon-id=\"arrow-right-color-fg-muted\">\n              <svg height=\"16\" class=\"octicon octicon-arrow-right color-fg-muted\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" aria-hidden=\"true\"><path d=\"M8.22 2.97a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l2.97-2.97H3.75a.75.75 0 0 1 0-1.5h7.44L8.22 4.03a.75.75 0 0 1 0-1.06Z\"></path></svg>\n            </div>\n            <div data-targets=\"command-palette-page-stack.localOcticons\" data-octicon-id=\"arrow-right-color-fg-default\">\n              <svg height=\"16\" class=\"octicon octicon-arrow-right color-fg-default\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" aria-hidden=\"true\"><path d=\"M8.22 2.97a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l2.97-2.97H3.75a.75.75 0 0 1 0-1.5h7.44L8.22 4.03a.75.75 0 0 1 0-1.06Z\"></path></svg>\n            </div>\n            <div data-targets=\"command-palette-page-stack.localOcticons\" data-octicon-id=\"codespaces-color-fg-muted\">\n              <svg height=\"16\" class=\"octicon octicon-codespaces color-fg-muted\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" aria-hidden=\"true\"><path d=\"M0 11.25c0-.966.784-1.75 1.75-1.75h12.5c.966 0 1.75.784 1.75 1.75v3A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25Zm2-9.5C2 .784 2.784 0 3.75 0h8.5C13.216 0 14 .784 14 1.75v5a1.75 1.75 0 0 1-1.75 1.75h-8.5A1.75 1.75 0 0 1 2 6.75Zm1.75-.25a.25.25 0 0 0-.25.25v5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-5a.25.25 0 0 0-.25-.25Zm-2 9.5a.25.25 0 0 0-.25.25v3c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25v-3a.25.25 0 0 0-.25-.25Z\"></path><path d=\"M7 12.75a.75.75 0 0 1 .75-.75h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1-.75-.75Zm-4 0a.75.75 0 0 1 .75-.75h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1-.75-.75Z\"></path></svg>\n            </div>\n            <div data-targets=\"command-palette-page-stack.localOcticons\" data-octicon-id=\"copy-color-fg-muted\">\n              <svg height=\"16\" class=\"octicon octicon-copy color-fg-muted\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" aria-hidden=\"true\"><path d=\"M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z\"></path><path d=\"M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z\"></path></svg>\n            </div>\n            <div data-targets=\"command-palette-page-stack.localOcticons\" data-octicon-id=\"dash-color-fg-muted\">\n              <svg height=\"16\" class=\"octicon octicon-dash color-fg-muted\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" aria-hidden=\"true\"><path d=\"M2 7.75A.75.75 0 0 1 2.75 7h10a.75.75 0 0 1 0 1.5h-10A.75.75 0 0 1 2 7.75Z\"></path></svg>\n            </div>\n            <div data-targets=\"command-palette-page-stack.localOcticons\" data-octicon-id=\"file-color-fg-muted\">\n              <svg height=\"16\" class=\"octicon octicon-file color-fg-muted\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" aria-hidden=\"true\"><path d=\"M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 9 4.25V1.5Zm6.75.062V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z\"></path></svg>\n            </div>\n            <div data-targets=\"command-palette-page-stack.localOcticons\" data-octicon-id=\"gear-color-fg-muted\">\n              <svg height=\"16\" class=\"octicon octicon-gear color-fg-muted\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" aria-hidden=\"true\"><path d=\"M8 0a8.2 8.2 0 0 1 .701.031C9.444.095 9.99.645 10.16 1.29l.288 1.107c.018.066.079.158.212.224.231.114.454.243.668.386.123.082.233.09.299.071l1.103-.303c.644-.176 1.392.021 1.82.63.27.385.506.792.704 1.218.315.675.111 1.422-.364 1.891l-.814.806c-.049.048-.098.147-.088.294.016.257.016.515 0 .772-.01.147.038.246.088.294l.814.806c.475.469.679 1.216.364 1.891a7.977 7.977 0 0 1-.704 1.217c-.428.61-1.176.807-1.82.63l-1.102-.302c-.067-.019-.177-.011-.3.071a5.909 5.909 0 0 1-.668.386c-.133.066-.194.158-.211.224l-.29 1.106c-.168.646-.715 1.196-1.458 1.26a8.006 8.006 0 0 1-1.402 0c-.743-.064-1.289-.614-1.458-1.26l-.289-1.106c-.018-.066-.079-.158-.212-.224a5.738 5.738 0 0 1-.668-.386c-.123-.082-.233-.09-.299-.071l-1.103.303c-.644.176-1.392-.021-1.82-.63a8.12 8.12 0 0 1-.704-1.218c-.315-.675-.111-1.422.363-1.891l.815-.806c.05-.048.098-.147.088-.294a6.214 6.214 0 0 1 0-.772c.01-.147-.038-.246-.088-.294l-.815-.806C.635 6.045.431 5.298.746 4.623a7.92 7.92 0 0 1 .704-1.217c.428-.61 1.176-.807 1.82-.63l1.102.302c.067.019.177.011.3-.071.214-.143.437-.272.668-.386.133-.066.194-.158.211-.224l.29-1.106C6.009.645 6.556.095 7.299.03 7.53.01 7.764 0 8 0Zm-.571 1.525c-.036.003-.108.036-.137.146l-.289 1.105c-.147.561-.549.967-.998 1.189-.173.086-.34.183-.5.29-.417.278-.97.423-1.529.27l-1.103-.303c-.109-.03-.175.016-.195.045-.22.312-.412.644-.573.99-.014.031-.021.11.059.19l.815.806c.411.406.562.957.53 1.456a4.709 4.709 0 0 0 0 .582c.032.499-.119 1.05-.53 1.456l-.815.806c-.081.08-.073.159-.059.19.162.346.353.677.573.989.02.03.085.076.195.046l1.102-.303c.56-.153 1.113-.008 1.53.27.161.107.328.204.501.29.447.222.85.629.997 1.189l.289 1.105c.029.109.101.143.137.146a6.6 6.6 0 0 0 1.142 0c.036-.003.108-.036.137-.146l.289-1.105c.147-.561.549-.967.998-1.189.173-.086.34-.183.5-.29.417-.278.97-.423 1.529-.27l1.103.303c.109.029.175-.016.195-.045.22-.313.411-.644.573-.99.014-.031.021-.11-.059-.19l-.815-.806c-.411-.406-.562-.957-.53-1.456a4.709 4.709 0 0 0 0-.582c-.032-.499.119-1.05.53-1.456l.815-.806c.081-.08.073-.159.059-.19a6.464 6.464 0 0 0-.573-.989c-.02-.03-.085-.076-.195-.046l-1.102.303c-.56.153-1.113.008-1.53-.27a4.44 4.44 0 0 0-.501-.29c-.447-.222-.85-.629-.997-1.189l-.289-1.105c-.029-.11-.101-.143-.137-.146a6.6 6.6 0 0 0-1.142 0ZM11 8a3 3 0 1 1-6 0 3 3 0 0 1 6 0ZM9.5 8a1.5 1.5 0 1 0-3.001.001A1.5 1.5 0 0 0 9.5 8Z\"></path></svg>\n            </div>\n            <div data-targets=\"command-palette-page-stack.localOcticons\" data-octicon-id=\"lock-color-fg-muted\">\n              <svg height=\"16\" class=\"octicon octicon-lock color-fg-muted\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" aria-hidden=\"true\"><path d=\"M4 4a4 4 0 0 1 8 0v2h.25c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 12.25 15h-8.5A1.75 1.75 0 0 1 2 13.25v-5.5C2 6.784 2.784 6 3.75 6H4Zm8.25 3.5h-8.5a.25.25 0 0 0-.25.25v5.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-5.5a.25.25 0 0 0-.25-.25ZM10.5 6V4a2.5 2.5 0 1 0-5 0v2Z\"></path></svg>\n            </div>\n            <div data-targets=\"command-palette-page-stack.localOcticons\" data-octicon-id=\"moon-color-fg-muted\">\n              <svg height=\"16\" class=\"octicon octicon-moon color-fg-muted\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" aria-hidden=\"true\"><path d=\"M9.598 1.591a.749.749 0 0 1 .785-.175 7.001 7.001 0 1 1-8.967 8.967.75.75 0 0 1 .961-.96 5.5 5.5 0 0 0 7.046-7.046.75.75 0 0 1 .175-.786Zm1.616 1.945a7 7 0 0 1-7.678 7.678 5.499 5.499 0 1 0 7.678-7.678Z\"></path></svg>\n            </div>\n            <div data-targets=\"command-palette-page-stack.localOcticons\" data-octicon-id=\"person-color-fg-muted\">\n              <svg height=\"16\" class=\"octicon octicon-person color-fg-muted\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" aria-hidden=\"true\"><path d=\"M10.561 8.073a6.005 6.005 0 0 1 3.432 5.142.75.75 0 1 1-1.498.07 4.5 4.5 0 0 0-8.99 0 .75.75 0 0 1-1.498-.07 6.004 6.004 0 0 1 3.431-5.142 3.999 3.999 0 1 1 5.123 0ZM10.5 5a2.5 2.5 0 1 0-5 0 2.5 2.5 0 0 0 5 0Z\"></path></svg>\n            </div>\n            <div data-targets=\"command-palette-page-stack.localOcticons\" data-octicon-id=\"pencil-color-fg-muted\">\n              <svg height=\"16\" class=\"octicon octicon-pencil color-fg-muted\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" aria-hidden=\"true\"><path d=\"M11.013 1.427a1.75 1.75 0 0 1 2.474 0l1.086 1.086a1.75 1.75 0 0 1 0 2.474l-8.61 8.61c-.21.21-.47.364-.756.445l-3.251.93a.75.75 0 0 1-.927-.928l.929-3.25c.081-.286.235-.547.445-.758l8.61-8.61Zm.176 4.823L9.75 4.81l-6.286 6.287a.253.253 0 0 0-.064.108l-.558 1.953 1.953-.558a.253.253 0 0 0 .108-.064Zm1.238-3.763a.25.25 0 0 0-.354 0L10.811 3.75l1.439 1.44 1.263-1.263a.25.25 0 0 0 0-.354Z\"></path></svg>\n            </div>\n            <div data-targets=\"command-palette-page-stack.localOcticons\" data-octicon-id=\"issue-opened-open\">\n              <svg height=\"16\" class=\"octicon octicon-issue-opened open\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" aria-hidden=\"true\"><path d=\"M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z\"></path><path d=\"M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Z\"></path></svg>\n            </div>\n            <div data-targets=\"command-palette-page-stack.localOcticons\" data-octicon-id=\"git-pull-request-draft-color-fg-muted\">\n              <svg height=\"16\" class=\"octicon octicon-git-pull-request-draft color-fg-muted\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" aria-hidden=\"true\"><path d=\"M3.25 1A2.25 2.25 0 0 1 4 5.372v5.256a2.251 2.251 0 1 1-1.5 0V5.372A2.251 2.251 0 0 1 3.25 1Zm9.5 14a2.25 2.25 0 1 1 0-4.5 2.25 2.25 0 0 1 0 4.5ZM2.5 3.25a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0ZM3.25 12a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm9.5 0a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5ZM14 7.5a1.25 1.25 0 1 1-2.5 0 1.25 1.25 0 0 1 2.5 0Zm0-4.25a1.25 1.25 0 1 1-2.5 0 1.25 1.25 0 0 1 2.5 0Z\"></path></svg>\n            </div>\n            <div data-targets=\"command-palette-page-stack.localOcticons\" data-octicon-id=\"search-color-fg-muted\">\n              <svg height=\"16\" class=\"octicon octicon-search color-fg-muted\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" aria-hidden=\"true\"><path d=\"M10.68 11.74a6 6 0 0 1-7.922-8.982 6 6 0 0 1 8.982 7.922l3.04 3.04a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215ZM11.5 7a4.499 4.499 0 1 0-8.997 0A4.499 4.499 0 0 0 11.5 7Z\"></path></svg>\n            </div>\n            <div data-targets=\"command-palette-page-stack.localOcticons\" data-octicon-id=\"sun-color-fg-muted\">\n              <svg height=\"16\" class=\"octicon octicon-sun color-fg-muted\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" aria-hidden=\"true\"><path d=\"M8 12a4 4 0 1 1 0-8 4 4 0 0 1 0 8Zm0-1.5a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5Zm5.657-8.157a.75.75 0 0 1 0 1.061l-1.061 1.06a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734l1.06-1.06a.75.75 0 0 1 1.06 0Zm-9.193 9.193a.75.75 0 0 1 0 1.06l-1.06 1.061a.75.75 0 1 1-1.061-1.06l1.06-1.061a.75.75 0 0 1 1.061 0ZM8 0a.75.75 0 0 1 .75.75v1.5a.75.75 0 0 1-1.5 0V.75A.75.75 0 0 1 8 0ZM3 8a.75.75 0 0 1-.75.75H.75a.75.75 0 0 1 0-1.5h1.5A.75.75 0 0 1 3 8Zm13 0a.75.75 0 0 1-.75.75h-1.5a.75.75 0 0 1 0-1.5h1.5A.75.75 0 0 1 16 8Zm-8 5a.75.75 0 0 1 .75.75v1.5a.75.75 0 0 1-1.5 0v-1.5A.75.75 0 0 1 8 13Zm3.536-1.464a.75.75 0 0 1 1.06 0l1.061 1.06a.75.75 0 0 1-1.06 1.061l-1.061-1.06a.75.75 0 0 1 0-1.061ZM2.343 2.343a.75.75 0 0 1 1.061 0l1.06 1.061a.751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018l-1.06-1.06a.75.75 0 0 1 0-1.06Z\"></path></svg>\n            </div>\n            <div data-targets=\"command-palette-page-stack.localOcticons\" data-octicon-id=\"sync-color-fg-muted\">\n              <svg height=\"16\" class=\"octicon octicon-sync color-fg-muted\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" aria-hidden=\"true\"><path d=\"M1.705 8.005a.75.75 0 0 1 .834.656 5.5 5.5 0 0 0 9.592 2.97l-1.204-1.204a.25.25 0 0 1 .177-.427h3.646a.25.25 0 0 1 .25.25v3.646a.25.25 0 0 1-.427.177l-1.38-1.38A7.002 7.002 0 0 1 1.05 8.84a.75.75 0 0 1 .656-.834ZM8 2.5a5.487 5.487 0 0 0-4.131 1.869l1.204 1.204A.25.25 0 0 1 4.896 6H1.25A.25.25 0 0 1 1 5.75V2.104a.25.25 0 0 1 .427-.177l1.38 1.38A7.002 7.002 0 0 1 14.95 7.16a.75.75 0 0 1-1.49.178A5.5 5.5 0 0 0 8 2.5Z\"></path></svg>\n            </div>\n            <div data-targets=\"command-palette-page-stack.localOcticons\" data-octicon-id=\"trash-color-fg-muted\">\n              <svg height=\"16\" class=\"octicon octicon-trash color-fg-muted\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" aria-hidden=\"true\"><path d=\"M11 1.75V3h2.25a.75.75 0 0 1 0 1.5H2.75a.75.75 0 0 1 0-1.5H5V1.75C5 .784 5.784 0 6.75 0h2.5C10.216 0 11 .784 11 1.75ZM4.496 6.675l.66 6.6a.25.25 0 0 0 .249.225h5.19a.25.25 0 0 0 .249-.225l.66-6.6a.75.75 0 0 1 1.492.149l-.66 6.6A1.748 1.748 0 0 1 10.595 15h-5.19a1.75 1.75 0 0 1-1.741-1.575l-.66-6.6a.75.75 0 1 1 1.492-.15ZM6.5 1.75V3h3V1.75a.25.25 0 0 0-.25-.25h-2.5a.25.25 0 0 0-.25.25Z\"></path></svg>\n            </div>\n            <div data-targets=\"command-palette-page-stack.localOcticons\" data-octicon-id=\"key-color-fg-muted\">\n              <svg height=\"16\" class=\"octicon octicon-key color-fg-muted\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" aria-hidden=\"true\"><path d=\"M10.5 0a5.499 5.499 0 1 1-1.288 10.848l-.932.932a.749.749 0 0 1-.53.22H7v.75a.749.749 0 0 1-.22.53l-.5.5a.749.749 0 0 1-.53.22H5v.75a.749.749 0 0 1-.22.53l-.5.5a.749.749 0 0 1-.53.22h-2A1.75 1.75 0 0 1 0 14.25v-2c0-.199.079-.389.22-.53l4.932-4.932A5.5 5.5 0 0 1 10.5 0Zm-4 5.5c-.001.431.069.86.205 1.269a.75.75 0 0 1-.181.768L1.5 12.56v1.69c0 .138.112.25.25.25h1.69l.06-.06v-1.19a.75.75 0 0 1 .75-.75h1.19l.06-.06v-1.19a.75.75 0 0 1 .75-.75h1.19l1.023-1.025a.75.75 0 0 1 .768-.18A4 4 0 1 0 6.5 5.5ZM11 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\"></path></svg>\n            </div>\n            <div data-targets=\"command-palette-page-stack.localOcticons\" data-octicon-id=\"comment-discussion-color-fg-muted\">\n              <svg height=\"16\" class=\"octicon octicon-comment-discussion color-fg-muted\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" aria-hidden=\"true\"><path d=\"M1.75 1h8.5c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 10.25 10H7.061l-2.574 2.573A1.458 1.458 0 0 1 2 11.543V10h-.25A1.75 1.75 0 0 1 0 8.25v-5.5C0 1.784.784 1 1.75 1ZM1.5 2.75v5.5c0 .138.112.25.25.25h1a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h3.5a.25.25 0 0 0 .25-.25v-5.5a.25.25 0 0 0-.25-.25h-8.5a.25.25 0 0 0-.25.25Zm13 2a.25.25 0 0 0-.25-.25h-.5a.75.75 0 0 1 0-1.5h.5c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 14.25 12H14v1.543a1.458 1.458 0 0 1-2.487 1.03L9.22 12.28a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215l2.22 2.22v-2.19a.75.75 0 0 1 .75-.75h1a.25.25 0 0 0 .25-.25Z\"></path></svg>\n            </div>\n            <div data-targets=\"command-palette-page-stack.localOcticons\" data-octicon-id=\"bell-color-fg-muted\">\n              <svg height=\"16\" class=\"octicon octicon-bell color-fg-muted\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" aria-hidden=\"true\"><path d=\"M8 16a2 2 0 0 0 1.985-1.75c.017-.137-.097-.25-.235-.25h-3.5c-.138 0-.252.113-.235.25A2 2 0 0 0 8 16ZM3 5a5 5 0 0 1 10 0v2.947c0 .05.015.098.042.139l1.703 2.555A1.519 1.519 0 0 1 13.482 13H2.518a1.516 1.516 0 0 1-1.263-2.36l1.703-2.554A.255.255 0 0 0 3 7.947Zm5-3.5A3.5 3.5 0 0 0 4.5 5v2.947c0 .346-.102.683-.294.97l-1.703 2.556a.017.017 0 0 0-.003.01l.001.006c0 .002.002.004.004.006l.006.004.007.001h10.964l.007-.001.006-.004.004-.006.001-.007a.017.017 0 0 0-.003-.01l-1.703-2.554a1.745 1.745 0 0 1-.294-.97V5A3.5 3.5 0 0 0 8 1.5Z\"></path></svg>\n            </div>\n            <div data-targets=\"command-palette-page-stack.localOcticons\" data-octicon-id=\"bell-slash-color-fg-muted\">\n              <svg height=\"16\" class=\"octicon octicon-bell-slash color-fg-muted\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" aria-hidden=\"true\"><path d=\"m4.182 4.31.016.011 10.104 7.316.013.01 1.375.996a.75.75 0 1 1-.88 1.214L13.626 13H2.518a1.516 1.516 0 0 1-1.263-2.36l1.703-2.554A.255.255 0 0 0 3 7.947V5.305L.31 3.357a.75.75 0 1 1 .88-1.214Zm7.373 7.19L4.5 6.391v1.556c0 .346-.102.683-.294.97l-1.703 2.556a.017.017 0 0 0-.003.01c0 .005.002.009.005.012l.006.004.007.001ZM8 1.5c-.997 0-1.895.416-2.534 1.086A.75.75 0 1 1 4.38 1.55 5 5 0 0 1 13 5v2.373a.75.75 0 0 1-1.5 0V5A3.5 3.5 0 0 0 8 1.5ZM8 16a2 2 0 0 1-1.985-1.75c-.017-.137.097-.25.235-.25h3.5c.138 0 .252.113.235.25A2 2 0 0 1 8 16Z\"></path></svg>\n            </div>\n            <div data-targets=\"command-palette-page-stack.localOcticons\" data-octicon-id=\"paintbrush-color-fg-muted\">\n              <svg height=\"16\" class=\"octicon octicon-paintbrush color-fg-muted\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" aria-hidden=\"true\"><path d=\"M11.134 1.535c.7-.509 1.416-.942 2.076-1.155.649-.21 1.463-.267 2.069.34.603.601.568 1.411.368 2.07-.202.668-.624 1.39-1.125 2.096-1.011 1.424-2.496 2.987-3.775 4.249-1.098 1.084-2.132 1.839-3.04 2.3a3.744 3.744 0 0 1-1.055 3.217c-.431.431-1.065.691-1.657.861-.614.177-1.294.287-1.914.357A21.151 21.151 0 0 1 .797 16H.743l.007-.75H.749L.742 16a.75.75 0 0 1-.743-.742l.743-.008-.742.007v-.054a21.25 21.25 0 0 1 .13-2.284c.067-.647.187-1.287.358-1.914.17-.591.43-1.226.86-1.657a3.746 3.746 0 0 1 3.227-1.054c.466-.893 1.225-1.907 2.314-2.982 1.271-1.255 2.833-2.75 4.245-3.777ZM1.62 13.089c-.051.464-.086.929-.104 1.395.466-.018.932-.053 1.396-.104a10.511 10.511 0 0 0 1.668-.309c.526-.151.856-.325 1.011-.48a2.25 2.25 0 1 0-3.182-3.182c-.155.155-.329.485-.48 1.01a10.515 10.515 0 0 0-.309 1.67Zm10.396-10.34c-1.224.89-2.605 2.189-3.822 3.384l1.718 1.718c1.21-1.205 2.51-2.597 3.387-3.833.47-.662.78-1.227.912-1.662.134-.444.032-.551.009-.575h-.001V1.78c-.014-.014-.113-.113-.548.027-.432.14-.995.462-1.655.942Zm-4.832 7.266-.001.001a9.859 9.859 0 0 0 1.63-1.142L7.155 7.216a9.7 9.7 0 0 0-1.161 1.607c.482.302.889.71 1.19 1.192Z\"></path></svg>\n            </div>\n\n            <command-palette-item-group\n              data-group-id=\"top\"\n              data-group-title=\"Top result\"\n              data-group-hint=\"\"\n              data-group-limits=\"{}\"\n              data-default-priority=\"0\"\n            >\n            </command-palette-item-group>\n            <command-palette-item-group\n              data-group-id=\"commands\"\n              data-group-title=\"Commands\"\n              data-group-hint=\"Type &gt; to filter\"\n              data-group-limits=\"{&quot;static_items_page&quot;:50,&quot;issue&quot;:50,&quot;pull_request&quot;:50,&quot;discussion&quot;:50}\"\n              data-default-priority=\"1\"\n            >\n            </command-palette-item-group>\n            <command-palette-item-group\n              data-group-id=\"global_commands\"\n              data-group-title=\"Global Commands\"\n              data-group-hint=\"Type &gt; to filter\"\n              data-group-limits=\"{&quot;issue&quot;:0,&quot;pull_request&quot;:0,&quot;discussion&quot;:0}\"\n              data-default-priority=\"2\"\n            >\n            </command-palette-item-group>\n            <command-palette-item-group\n              data-group-id=\"this_page\"\n              data-group-title=\"This Page\"\n              data-group-hint=\"\"\n              data-group-limits=\"{}\"\n              data-default-priority=\"3\"\n            >\n            </command-palette-item-group>\n            <command-palette-item-group\n              data-group-id=\"files\"\n              data-group-title=\"Files\"\n              data-group-hint=\"\"\n              data-group-limits=\"{}\"\n              data-default-priority=\"4\"\n            >\n            </command-palette-item-group>\n            <command-palette-item-group\n              data-group-id=\"default\"\n              data-group-title=\"Default\"\n              data-group-hint=\"\"\n              data-group-limits=\"{&quot;static_items_page&quot;:50}\"\n              data-default-priority=\"5\"\n            >\n            </command-palette-item-group>\n            <command-palette-item-group\n              data-group-id=\"pages\"\n              data-group-title=\"Pages\"\n              data-group-hint=\"\"\n              data-group-limits=\"{&quot;repository&quot;:10}\"\n              data-default-priority=\"6\"\n            >\n            </command-palette-item-group>\n            <command-palette-item-group\n              data-group-id=\"access_policies\"\n              data-group-title=\"Access Policies\"\n              data-group-hint=\"\"\n              data-group-limits=\"{}\"\n              data-default-priority=\"7\"\n            >\n            </command-palette-item-group>\n            <command-palette-item-group\n              data-group-id=\"organizations\"\n              data-group-title=\"Organizations\"\n              data-group-hint=\"\"\n              data-group-limits=\"{}\"\n              data-default-priority=\"8\"\n            >\n            </command-palette-item-group>\n            <command-palette-item-group\n              data-group-id=\"repositories\"\n              data-group-title=\"Repositories\"\n              data-group-hint=\"\"\n              data-group-limits=\"{}\"\n              data-default-priority=\"9\"\n            >\n            </command-palette-item-group>\n            <command-palette-item-group\n              data-group-id=\"references\"\n              data-group-title=\"Issues, pull requests, and discussions\"\n              data-group-hint=\"Type # to filter\"\n              data-group-limits=\"{}\"\n              data-default-priority=\"10\"\n            >\n            </command-palette-item-group>\n            <command-palette-item-group\n              data-group-id=\"teams\"\n              data-group-title=\"Teams\"\n              data-group-hint=\"\"\n              data-group-limits=\"{}\"\n              data-default-priority=\"11\"\n            >\n            </command-palette-item-group>\n            <command-palette-item-group\n              data-group-id=\"users\"\n              data-group-title=\"Users\"\n              data-group-hint=\"\"\n              data-group-limits=\"{}\"\n              data-default-priority=\"12\"\n            >\n            </command-palette-item-group>\n            <command-palette-item-group\n              data-group-id=\"memex_projects\"\n              data-group-title=\"Projects\"\n              data-group-hint=\"\"\n              data-group-limits=\"{}\"\n              data-default-priority=\"13\"\n            >\n            </command-palette-item-group>\n            <command-palette-item-group\n              data-group-id=\"projects\"\n              data-group-title=\"Projects (classic)\"\n              data-group-hint=\"\"\n              data-group-limits=\"{}\"\n              data-default-priority=\"14\"\n            >\n            </command-palette-item-group>\n            <command-palette-item-group\n              data-group-id=\"footer\"\n              data-group-title=\"Footer\"\n              data-group-hint=\"\"\n              data-group-limits=\"{}\"\n              data-default-priority=\"15\"\n            >\n            </command-palette-item-group>\n            <command-palette-item-group\n              data-group-id=\"modes_help\"\n              data-group-title=\"Modes\"\n              data-group-hint=\"\"\n              data-group-limits=\"{}\"\n              data-default-priority=\"16\"\n            >\n            </command-palette-item-group>\n            <command-palette-item-group\n              data-group-id=\"filters_help\"\n              data-group-title=\"Use filters in issues, pull requests, discussions, and projects\"\n              data-group-hint=\"\"\n              data-group-limits=\"{}\"\n              data-default-priority=\"17\"\n            >\n            </command-palette-item-group>\n\n            <command-palette-page\n              data-page-title=\"mouredev\"\n              data-scope-id=\"MDQ6VXNlcjE3MDQzNDAy\"\n              data-scope-type=\"owner\"\n              data-targets=\"command-palette-page-stack.defaultPages\"\n              hidden\n            >\n            </command-palette-page>\n            <command-palette-page\n              data-page-title=\"roadmap-retos-programacion\"\n              data-scope-id=\"R_kgDOK7DMTg\"\n              data-scope-type=\"repository\"\n              data-targets=\"command-palette-page-stack.defaultPages\"\n              hidden\n            >\n            </command-palette-page>\n        </div>\n\n        <command-palette-page data-is-root>\n        </command-palette-page>\n          <command-palette-page\n            data-page-title=\"mouredev\"\n            data-scope-id=\"MDQ6VXNlcjE3MDQzNDAy\"\n            data-scope-type=\"owner\"\n          >\n          </command-palette-page>\n          <command-palette-page\n            data-page-title=\"roadmap-retos-programacion\"\n            data-scope-id=\"R_kgDOK7DMTg\"\n            data-scope-type=\"repository\"\n          >\n          </command-palette-page>\n      </command-palette-page-stack>\n\n      <server-defined-provider data-type=\"search-links\" data-targets=\"command-palette.serverDefinedProviderElements\"></server-defined-provider>\n      <server-defined-provider data-type=\"help\" data-targets=\"command-palette.serverDefinedProviderElements\">\n          <command-palette-help\n            data-group=\"modes_help\"\n              data-prefix=\"#\"\n              data-scope-types=\"[&quot;&quot;]\"\n          >\n            <span data-target=\"command-palette-help.titleElement\">Search for <strong>issues</strong> and <strong>pull requests</strong></span>\n              <span data-target=\"command-palette-help.hintElement\">\n                <kbd class=\"hx_kbd\">#</kbd>\n              </span>\n          </command-palette-help>\n          <command-palette-help\n            data-group=\"modes_help\"\n              data-prefix=\"#\"\n              data-scope-types=\"[&quot;owner&quot;,&quot;repository&quot;]\"\n          >\n            <span data-target=\"command-palette-help.titleElement\">Search for <strong>issues, pull requests, discussions,</strong> and <strong>projects</strong></span>\n              <span data-target=\"command-palette-help.hintElement\">\n                <kbd class=\"hx_kbd\">#</kbd>\n              </span>\n          </command-palette-help>\n          <command-palette-help\n            data-group=\"modes_help\"\n              data-prefix=\"@\"\n              data-scope-types=\"[&quot;&quot;]\"\n          >\n            <span data-target=\"command-palette-help.titleElement\">Search for <strong>organizations, repositories,</strong> and <strong>users</strong></span>\n              <span data-target=\"command-palette-help.hintElement\">\n                <kbd class=\"hx_kbd\">@</kbd>\n              </span>\n          </command-palette-help>\n          <command-palette-help\n            data-group=\"modes_help\"\n              data-prefix=\"!\"\n              data-scope-types=\"[&quot;owner&quot;,&quot;repository&quot;]\"\n          >\n            <span data-target=\"command-palette-help.titleElement\">Search for <strong>projects</strong></span>\n              <span data-target=\"command-palette-help.hintElement\">\n                <kbd class=\"hx_kbd\">!</kbd>\n              </span>\n          </command-palette-help>\n          <command-palette-help\n            data-group=\"modes_help\"\n              data-prefix=\"/\"\n              data-scope-types=\"[&quot;repository&quot;]\"\n          >\n            <span data-target=\"command-palette-help.titleElement\">Search for <strong>files</strong></span>\n              <span data-target=\"command-palette-help.hintElement\">\n                <kbd class=\"hx_kbd\">/</kbd>\n              </span>\n          </command-palette-help>\n          <command-palette-help\n            data-group=\"modes_help\"\n              data-prefix=\"&gt;\"\n          >\n            <span data-target=\"command-palette-help.titleElement\">Activate <strong>command mode</strong></span>\n              <span data-target=\"command-palette-help.hintElement\">\n                <kbd class=\"hx_kbd\">&gt;</kbd>\n              </span>\n          </command-palette-help>\n          <command-palette-help\n            data-group=\"filters_help\"\n              data-prefix=\"# author:@me\"\n          >\n            <span data-target=\"command-palette-help.titleElement\">Search your issues, pull requests, and discussions</span>\n              <span data-target=\"command-palette-help.hintElement\">\n                <kbd class=\"hx_kbd\"># author:@me</kbd>\n              </span>\n          </command-palette-help>\n          <command-palette-help\n            data-group=\"filters_help\"\n              data-prefix=\"# author:@me\"\n          >\n            <span data-target=\"command-palette-help.titleElement\">Search your issues, pull requests, and discussions</span>\n              <span data-target=\"command-palette-help.hintElement\">\n                <kbd class=\"hx_kbd\"># author:@me</kbd>\n              </span>\n          </command-palette-help>\n          <command-palette-help\n            data-group=\"filters_help\"\n              data-prefix=\"# is:pr\"\n          >\n            <span data-target=\"command-palette-help.titleElement\">Filter to pull requests</span>\n              <span data-target=\"command-palette-help.hintElement\">\n                <kbd class=\"hx_kbd\"># is:pr</kbd>\n              </span>\n          </command-palette-help>\n          <command-palette-help\n            data-group=\"filters_help\"\n              data-prefix=\"# is:issue\"\n          >\n            <span data-target=\"command-palette-help.titleElement\">Filter to issues</span>\n              <span data-target=\"command-palette-help.hintElement\">\n                <kbd class=\"hx_kbd\"># is:issue</kbd>\n              </span>\n          </command-palette-help>\n          <command-palette-help\n            data-group=\"filters_help\"\n              data-prefix=\"# is:discussion\"\n              data-scope-types=\"[&quot;owner&quot;,&quot;repository&quot;]\"\n          >\n            <span data-target=\"command-palette-help.titleElement\">Filter to discussions</span>\n              <span data-target=\"command-palette-help.hintElement\">\n                <kbd class=\"hx_kbd\"># is:discussion</kbd>\n              </span>\n          </command-palette-help>\n          <command-palette-help\n            data-group=\"filters_help\"\n              data-prefix=\"# is:project\"\n              data-scope-types=\"[&quot;owner&quot;,&quot;repository&quot;]\"\n          >\n            <span data-target=\"command-palette-help.titleElement\">Filter to projects</span>\n              <span data-target=\"command-palette-help.hintElement\">\n                <kbd class=\"hx_kbd\"># is:project</kbd>\n              </span>\n          </command-palette-help>\n          <command-palette-help\n            data-group=\"filters_help\"\n              data-prefix=\"# is:open\"\n          >\n            <span data-target=\"command-palette-help.titleElement\">Filter to open issues, pull requests, and discussions</span>\n              <span data-target=\"command-palette-help.hintElement\">\n                <kbd class=\"hx_kbd\"># is:open</kbd>\n              </span>\n          </command-palette-help>\n      </server-defined-provider>\n\n        <server-defined-provider\n          data-type=\"commands\"\n          data-fetch-debounce=\"0\"\n            data-src=\"/command_palette/commands\"\n          data-supported-modes=\"[]\"\n            data-supports-commands\n          \n          data-targets=\"command-palette.serverDefinedProviderElements\"\n          ></server-defined-provider>\n        <server-defined-provider\n          data-type=\"prefetched\"\n          data-fetch-debounce=\"0\"\n            data-src=\"/command_palette/jump_to_page_navigation\"\n          data-supported-modes=\"[&quot;&quot;]\"\n            data-supported-scope-types=\"[&quot;&quot;,&quot;owner&quot;,&quot;repository&quot;]\"\n          \n          data-targets=\"command-palette.serverDefinedProviderElements\"\n          ></server-defined-provider>\n        <server-defined-provider\n          data-type=\"remote\"\n          data-fetch-debounce=\"200\"\n            data-src=\"/command_palette/issues\"\n          data-supported-modes=\"[&quot;#&quot;,&quot;#&quot;]\"\n            data-supported-scope-types=\"[&quot;owner&quot;,&quot;repository&quot;,&quot;&quot;]\"\n          \n          data-targets=\"command-palette.serverDefinedProviderElements\"\n          ></server-defined-provider>\n        <server-defined-provider\n          data-type=\"remote\"\n          data-fetch-debounce=\"200\"\n            data-src=\"/command_palette/jump_to\"\n          data-supported-modes=\"[&quot;@&quot;,&quot;@&quot;]\"\n            data-supported-scope-types=\"[&quot;&quot;,&quot;owner&quot;]\"\n          \n          data-targets=\"command-palette.serverDefinedProviderElements\"\n          ></server-defined-provider>\n        <server-defined-provider\n          data-type=\"remote\"\n          data-fetch-debounce=\"200\"\n            data-src=\"/command_palette/jump_to_members_only\"\n          data-supported-modes=\"[&quot;@&quot;,&quot;@&quot;,&quot;&quot;,&quot;&quot;]\"\n            data-supported-scope-types=\"[&quot;&quot;,&quot;owner&quot;]\"\n          \n          data-targets=\"command-palette.serverDefinedProviderElements\"\n          ></server-defined-provider>\n        <server-defined-provider\n          data-type=\"prefetched\"\n          data-fetch-debounce=\"0\"\n            data-src=\"/command_palette/jump_to_members_only_prefetched\"\n          data-supported-modes=\"[&quot;@&quot;,&quot;@&quot;,&quot;&quot;,&quot;&quot;]\"\n            data-supported-scope-types=\"[&quot;&quot;,&quot;owner&quot;]\"\n          \n          data-targets=\"command-palette.serverDefinedProviderElements\"\n          ></server-defined-provider>\n        <server-defined-provider\n          data-type=\"files\"\n          data-fetch-debounce=\"0\"\n            data-src=\"/command_palette/files\"\n          data-supported-modes=\"[&quot;/&quot;]\"\n            data-supported-scope-types=\"[&quot;repository&quot;]\"\n          \n          data-targets=\"command-palette.serverDefinedProviderElements\"\n          ></server-defined-provider>\n        <server-defined-provider\n          data-type=\"remote\"\n          data-fetch-debounce=\"200\"\n            data-src=\"/command_palette/discussions\"\n          data-supported-modes=\"[&quot;#&quot;]\"\n            data-supported-scope-types=\"[&quot;owner&quot;,&quot;repository&quot;]\"\n          \n          data-targets=\"command-palette.serverDefinedProviderElements\"\n          ></server-defined-provider>\n        <server-defined-provider\n          data-type=\"remote\"\n          data-fetch-debounce=\"200\"\n            data-src=\"/command_palette/projects\"\n          data-supported-modes=\"[&quot;#&quot;,&quot;!&quot;]\"\n            data-supported-scope-types=\"[&quot;owner&quot;,&quot;repository&quot;]\"\n          \n          data-targets=\"command-palette.serverDefinedProviderElements\"\n          ></server-defined-provider>\n        <server-defined-provider\n          data-type=\"prefetched\"\n          data-fetch-debounce=\"0\"\n            data-src=\"/command_palette/recent_issues\"\n          data-supported-modes=\"[&quot;#&quot;,&quot;#&quot;]\"\n            data-supported-scope-types=\"[&quot;owner&quot;,&quot;repository&quot;,&quot;&quot;]\"\n          \n          data-targets=\"command-palette.serverDefinedProviderElements\"\n          ></server-defined-provider>\n        <server-defined-provider\n          data-type=\"remote\"\n          data-fetch-debounce=\"200\"\n            data-src=\"/command_palette/teams\"\n          data-supported-modes=\"[&quot;@&quot;,&quot;&quot;]\"\n            data-supported-scope-types=\"[&quot;owner&quot;]\"\n          \n          data-targets=\"command-palette.serverDefinedProviderElements\"\n          ></server-defined-provider>\n        <server-defined-provider\n          data-type=\"remote\"\n          data-fetch-debounce=\"200\"\n            data-src=\"/command_palette/name_with_owner_repository\"\n          data-supported-modes=\"[&quot;@&quot;,&quot;@&quot;,&quot;&quot;,&quot;&quot;]\"\n            data-supported-scope-types=\"[&quot;&quot;,&quot;owner&quot;]\"\n          \n          data-targets=\"command-palette.serverDefinedProviderElements\"\n          ></server-defined-provider>\n    </command-palette>\n  </details-dialog>\n</details>\n\n<div class=\"position-fixed bottom-0 left-0 ml-5 mb-5 js-command-palette-toasts\" style=\"z-index: 1000\">\n  <div hidden class=\"Toast Toast--loading\">\n    <span class=\"Toast-icon\">\n      <svg class=\"Toast--spinner\" viewBox=\"0 0 32 32\" width=\"18\" height=\"18\" aria-hidden=\"true\">\n        <path\n          fill=\"#959da5\"\n          d=\"M16 0 A16 16 0 0 0 16 32 A16 16 0 0 0 16 0 M16 4 A12 12 0 0 1 16 28 A12 12 0 0 1 16 4\"\n        />\n        <path fill=\"#ffffff\" d=\"M16 0 A16 16 0 0 1 32 16 L28 16 A12 12 0 0 0 16 4z\"></path>\n      </svg>\n    </span>\n    <span class=\"Toast-content\"></span>\n  </div>\n\n  <div hidden class=\"anim-fade-in fast Toast Toast--error\">\n    <span class=\"Toast-icon\">\n      <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-stop\">\n    <path d=\"M4.47.22A.749.749 0 0 1 5 0h6c.199 0 .389.079.53.22l4.25 4.25c.141.14.22.331.22.53v6a.749.749 0 0 1-.22.53l-4.25 4.25A.749.749 0 0 1 11 16H5a.749.749 0 0 1-.53-.22L.22 11.53A.749.749 0 0 1 0 11V5c0-.199.079-.389.22-.53Zm.84 1.28L1.5 5.31v5.38l3.81 3.81h5.38l3.81-3.81V5.31L10.69 1.5ZM8 4a.75.75 0 0 1 .75.75v3.5a.75.75 0 0 1-1.5 0v-3.5A.75.75 0 0 1 8 4Zm0 8a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\"></path>\n</svg>\n    </span>\n    <span class=\"Toast-content\"></span>\n  </div>\n\n  <div hidden class=\"anim-fade-in fast Toast Toast--warning\">\n    <span class=\"Toast-icon\">\n      <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-alert\">\n    <path d=\"M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\"></path>\n</svg>\n    </span>\n    <span class=\"Toast-content\"></span>\n  </div>\n\n\n  <div hidden class=\"anim-fade-in fast Toast Toast--success\">\n    <span class=\"Toast-icon\">\n      <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-check\">\n    <path d=\"M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z\"></path>\n</svg>\n    </span>\n    <span class=\"Toast-content\"></span>\n  </div>\n\n  <div hidden class=\"anim-fade-in fast Toast\">\n    <span class=\"Toast-icon\">\n      <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-info\">\n    <path d=\"M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\"></path>\n</svg>\n    </span>\n    <span class=\"Toast-content\"></span>\n  </div>\n</div>\n\n\n  <div\n    class=\"application-main \"\n    data-commit-hovercards-enabled\n    data-discussion-hovercards-enabled\n    data-issue-and-pr-hovercards-enabled\n  >\n        <div itemscope itemtype=\"http://schema.org/SoftwareSourceCode\" class=\"\">\n    <main id=\"js-repo-pjax-container\" >\n      \n      \n\n\n\n\n\n\n    \n  <div id=\"repository-container-header\" data-turbo-replace hidden></div>\n\n\n\n\n<turbo-frame id=\"repo-content-turbo-frame\" target=\"_top\" data-turbo-action=\"advance\" class=\"\">\n    <div id=\"repo-content-pjax-container\" class=\"repository-content \" >\n      <a href=\"https://github.dev/\" class=\"d-none js-github-dev-shortcut\" data-hotkey=\".,Mod+Alt+.\">Open in github.dev</a>\n  <a href=\"https://github.dev/\" class=\"d-none js-github-dev-new-tab-shortcut\" data-hotkey=\"Shift+.,Shift+&gt;,&gt;\" target=\"_blank\" rel=\"noopener noreferrer\">Open in a new github.dev tab</a>\n    <a class=\"d-none\" data-hotkey=\",,Mod+Alt+,\" target=\"_blank\" href=\"/codespaces/new/mouredev/roadmap-retos-programacion/tree/main?resume=1\">Open in codespace</a>\n\n\n\n\n    \n      \n    \n\n\n\n\n\n<react-app\n  app-name=\"react-code-view\"\n  initial-path=\"/mouredev/roadmap-retos-programacion/blob/main/Roadmap/00%20-%20SINTAXIS%2C%20VARIABLES%2C%20TIPOS%20DE%20DATOS%20Y%20HOLA%20MUNDO/php/GitHjuan.php\"\n  style=\"display: block; min-height: calc(100vh - 64px)\" \n  data-ssr=\"true\"\n  data-lazy=\"false\"\n  data-alternate=\"false\"\n>\n  \n  <script type=\"application/json\" data-target=\"react-app.embeddedData\">{\"payload\":{\"allShortcutsEnabled\":true,\"fileTree\":{\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php\":{\"items\":[{\"name\":\"BertoMP.php\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/BertoMP.php\",\"contentType\":\"file\"},{\"name\":\"BrunoM-93.php\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/BrunoM-93.php\",\"contentType\":\"file\"},{\"name\":\"Bryan112094.php\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/Bryan112094.php\",\"contentType\":\"file\"},{\"name\":\"Edm1ya.php\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/Edm1ya.php\",\"contentType\":\"file\"},{\"name\":\"GitHjuan.php\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/GitHjuan.php\",\"contentType\":\"file\"},{\"name\":\"Hugovrc.php\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/Hugovrc.php\",\"contentType\":\"file\"},{\"name\":\"JaimeSoftDev.php\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/JaimeSoftDev.php\",\"contentType\":\"file\"},{\"name\":\"JehiselRuth.php\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/JehiselRuth.php\",\"contentType\":\"file\"},{\"name\":\"alejandroruiz23.php\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/alejandroruiz23.php\",\"contentType\":\"file\"},{\"name\":\"gabrielmoris.php\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/gabrielmoris.php\",\"contentType\":\"file\"},{\"name\":\"guido2288.php\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/guido2288.php\",\"contentType\":\"file\"},{\"name\":\"jarzatedev.php\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/jarzatedev.php\",\"contentType\":\"file\"},{\"name\":\"johannhsdev.php\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/johannhsdev.php\",\"contentType\":\"file\"},{\"name\":\"kodenook.php\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/kodenook.php\",\"contentType\":\"file\"},{\"name\":\"marcode24.php\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/marcode24.php\",\"contentType\":\"file\"},{\"name\":\"mayerga.php\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/mayerga.php\",\"contentType\":\"file\"},{\"name\":\"mensius87.php\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/mensius87.php\",\"contentType\":\"file\"},{\"name\":\"miguelex.php\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/miguelex.php\",\"contentType\":\"file\"},{\"name\":\"pabloTaber.php\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/pabloTaber.php\",\"contentType\":\"file\"},{\"name\":\"rocallejas.php\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/rocallejas.php\",\"contentType\":\"file\"},{\"name\":\"trollface77.php\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/trollface77.php\",\"contentType\":\"file\"},{\"name\":\"zarakilancelot.php\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/zarakilancelot.php\",\"contentType\":\"file\"}],\"totalCount\":22},\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\":{\"items\":[{\"name\":\"abap\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/abap\",\"contentType\":\"directory\"},{\"name\":\"ada\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/ada\",\"contentType\":\"directory\"},{\"name\":\"al\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/al\",\"contentType\":\"directory\"},{\"name\":\"arduino\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/arduino\",\"contentType\":\"directory\"},{\"name\":\"bash\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/bash\",\"contentType\":\"directory\"},{\"name\":\"c#\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#\",\"contentType\":\"directory\"},{\"name\":\"c++\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++\",\"contentType\":\"directory\"},{\"name\":\"c\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c\",\"contentType\":\"directory\"},{\"name\":\"cobol\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/cobol\",\"contentType\":\"directory\"},{\"name\":\"dart\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/dart\",\"contentType\":\"directory\"},{\"name\":\"erlang\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/erlang\",\"contentType\":\"directory\"},{\"name\":\"fortran\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/fortran\",\"contentType\":\"directory\"},{\"name\":\"go\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/go\",\"contentType\":\"directory\"},{\"name\":\"harbour\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/harbour\",\"contentType\":\"directory\"},{\"name\":\"haskell\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/haskell\",\"contentType\":\"directory\"},{\"name\":\"java\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java\",\"contentType\":\"directory\"},{\"name\":\"javascript\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript\",\"contentType\":\"directory\"},{\"name\":\"julia\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/julia\",\"contentType\":\"directory\"},{\"name\":\"kotlin\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin\",\"contentType\":\"directory\"},{\"name\":\"lua\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/lua\",\"contentType\":\"directory\"},{\"name\":\"mojo\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/mojo\",\"contentType\":\"directory\"},{\"name\":\"nasm\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/nasm\",\"contentType\":\"directory\"},{\"name\":\"objectivec\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/objectivec\",\"contentType\":\"directory\"},{\"name\":\"ocaml\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/ocaml\",\"contentType\":\"directory\"},{\"name\":\"pascal\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/pascal\",\"contentType\":\"directory\"},{\"name\":\"php\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php\",\"contentType\":\"directory\"},{\"name\":\"prolog\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/prolog\",\"contentType\":\"directory\"},{\"name\":\"python\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python\",\"contentType\":\"directory\"},{\"name\":\"r\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/r\",\"contentType\":\"directory\"},{\"name\":\"racket\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/racket\",\"contentType\":\"directory\"},{\"name\":\"ruby\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/ruby\",\"contentType\":\"directory\"},{\"name\":\"rust\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/rust\",\"contentType\":\"directory\"},{\"name\":\"scala\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/scala\",\"contentType\":\"directory\"},{\"name\":\"solidity\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/solidity\",\"contentType\":\"directory\"},{\"name\":\"sql\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/sql\",\"contentType\":\"directory\"},{\"name\":\"swift\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/swift\",\"contentType\":\"directory\"},{\"name\":\"typescript\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript\",\"contentType\":\"directory\"},{\"name\":\"vb.net\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/vb.net\",\"contentType\":\"directory\"},{\"name\":\"ejercicio.md\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/ejercicio.md\",\"contentType\":\"file\"}],\"totalCount\":39},\"Roadmap\":{\"items\":[{\"name\":\"00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\",\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\",\"contentType\":\"directory\"},{\"name\":\"01 - OPERADORES Y ESTRUCTURAS DE CONTROL\",\"path\":\"Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL\",\"contentType\":\"directory\"},{\"name\":\"02 - FUNCIONES Y ALCANCE\",\"path\":\"Roadmap/02 - FUNCIONES Y ALCANCE\",\"contentType\":\"directory\"},{\"name\":\"03 - ESTRUCTURAS DE DATOS\",\"path\":\"Roadmap/03 - ESTRUCTURAS DE DATOS\",\"contentType\":\"directory\"},{\"name\":\"04 - CADENAS DE CARACTERES\",\"path\":\"Roadmap/04 - CADENAS DE CARACTERES\",\"contentType\":\"directory\"},{\"name\":\"05 - VALOR Y REFERENCIA\",\"path\":\"Roadmap/05 - VALOR Y REFERENCIA\",\"contentType\":\"directory\"},{\"name\":\"06 - RECURSIVIDAD\",\"path\":\"Roadmap/06 - RECURSIVIDAD\",\"contentType\":\"directory\"},{\"name\":\"07 - PILAS Y COLAS\",\"path\":\"Roadmap/07 - PILAS Y COLAS\",\"contentType\":\"directory\"},{\"name\":\"08 - CLASES\",\"path\":\"Roadmap/08 - CLASES\",\"contentType\":\"directory\"},{\"name\":\"09 - HERENCIA\",\"path\":\"Roadmap/09 - HERENCIA\",\"contentType\":\"directory\"},{\"name\":\"10 - EXCEPCIONES\",\"path\":\"Roadmap/10 - EXCEPCIONES\",\"contentType\":\"directory\"},{\"name\":\"11 - MANEJO DE FICHEROS\",\"path\":\"Roadmap/11 - MANEJO DE FICHEROS\",\"contentType\":\"directory\"},{\"name\":\"12 - JSON Y XML\",\"path\":\"Roadmap/12 - JSON Y XML\",\"contentType\":\"directory\"},{\"name\":\"13 - PRUEBAS UNITARIAS\",\"path\":\"Roadmap/13 - PRUEBAS UNITARIAS\",\"contentType\":\"directory\"},{\"name\":\"14 - FECHAS\",\"path\":\"Roadmap/14 - FECHAS\",\"contentType\":\"directory\"},{\"name\":\"15 - ASINCRONÍA\",\"path\":\"Roadmap/15 - ASINCRONÍA\",\"contentType\":\"directory\"},{\"name\":\"16 - EXPRESIONES REGULARES\",\"path\":\"Roadmap/16 - EXPRESIONES REGULARES\",\"contentType\":\"directory\"},{\"name\":\"17 - ITERACIONES\",\"path\":\"Roadmap/17 - ITERACIONES\",\"contentType\":\"directory\"},{\"name\":\"18 - CONJUNTOS\",\"path\":\"Roadmap/18 - CONJUNTOS\",\"contentType\":\"directory\"},{\"name\":\"19 - ENUMERACIONES\",\"path\":\"Roadmap/19 - ENUMERACIONES\",\"contentType\":\"directory\"},{\"name\":\"20 - PETICIONES HTTP\",\"path\":\"Roadmap/20 - PETICIONES HTTP\",\"contentType\":\"directory\"},{\"name\":\"21 - CALLBACKS\",\"path\":\"Roadmap/21 - CALLBACKS\",\"contentType\":\"directory\"},{\"name\":\"stats.json\",\"path\":\"Roadmap/stats.json\",\"contentType\":\"file\"},{\"name\":\"stats.py\",\"path\":\"Roadmap/stats.py\",\"contentType\":\"file\"}],\"totalCount\":24},\"\":{\"items\":[{\"name\":\".github\",\"path\":\".github\",\"contentType\":\"directory\"},{\"name\":\"Images\",\"path\":\"Images\",\"contentType\":\"directory\"},{\"name\":\"Roadmap\",\"path\":\"Roadmap\",\"contentType\":\"directory\"},{\"name\":\".gitignore\",\"path\":\".gitignore\",\"contentType\":\"file\"},{\"name\":\"LICENSE\",\"path\":\"LICENSE\",\"contentType\":\"file\"},{\"name\":\"README.md\",\"path\":\"README.md\",\"contentType\":\"file\"}],\"totalCount\":6}},\"fileTreeProcessingTime\":24.653966,\"foldersToFetch\":[],\"repo\":{\"id\":733006926,\"defaultBranch\":\"main\",\"name\":\"roadmap-retos-programacion\",\"ownerLogin\":\"mouredev\",\"currentUserCanPush\":true,\"isFork\":false,\"isEmpty\":false,\"createdAt\":\"2023-12-18T07:59:18.000-03:00\",\"ownerAvatar\":\"https://avatars.githubusercontent.com/u/17043402?v=4\",\"public\":true,\"private\":false,\"isOrgOwned\":false},\"codeLineWrapEnabled\":false,\"symbolsExpanded\":true,\"treeExpanded\":true,\"refInfo\":{\"name\":\"main\",\"listCacheKey\":\"v0:1705925979.0\",\"canEdit\":true,\"refType\":\"branch\",\"currentOid\":\"f57fb0deda19bafabc0c546e88c1fb04520ec264\"},\"path\":\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/GitHjuan.php\",\"currentUser\":{\"id\":88008233,\"login\":\"Roswell468\",\"userEmail\":\"brunoveg@outlook.com.ar\"},\"blob\":{\"rawLines\":[\"\\u003c?php\",\"\",\"// https://www.php.net/\",\"\",\"//comentario de una linea\",\"\",\"/*\",\"comentario\",\"de varias\",\"lineas\",\"*/\",\"\",\"//CREA UNA VARIABLE Y UNA CONSTANTE\",\"\",\"$variable = \\\"Valor de mi variable\\\"; // Esto es una variable\",\"\",\"define(CONSTANTE, \\\"Esto es una constante\\\" ); //Esto es una constante\",\"\",\"$string = \\\" PHP\\\"; //cadena de texto\",\"$int = 12 ; //numero entero\",\"$false = false; //booleano\",\"$true = true;\",\"$decimal = 1.2;\",\"$array = [\\\"uno\\\" , \\\"dos\\\", \\\"tres\\\"];\",\"\",\"// Imprime por terminal el texto: \\\"¡Hola, [y el nombre de tu lenguaje]!\\\"\",\"\",\"echo \\\"Hola \\\" . $string;\"],\"stylingDirectives\":[[{\"s\":0,\"e\":5,\"c\":\"pl-ent\"}],[],[{\"s\":0,\"e\":23,\"c\":\"pl-c\"}],[],[{\"s\":0,\"e\":25,\"c\":\"pl-c\"}],[],[{\"s\":0,\"e\":2,\"c\":\"pl-c\"}],[{\"s\":0,\"e\":10,\"c\":\"pl-c\"}],[{\"s\":0,\"e\":9,\"c\":\"pl-c\"}],[{\"s\":0,\"e\":6,\"c\":\"pl-c\"}],[{\"s\":0,\"e\":2,\"c\":\"pl-c\"}],[],[{\"s\":0,\"e\":35,\"c\":\"pl-c\"}],[],[{\"s\":0,\"e\":9,\"c\":\"pl-s1\"},{\"s\":0,\"e\":1,\"c\":\"pl-c1\"},{\"s\":13,\"e\":33,\"c\":\"pl-s\"},{\"s\":36,\"e\":59,\"c\":\"pl-c\"}],[],[{\"s\":7,\"e\":16,\"c\":\"pl-c1\"},{\"s\":19,\"e\":40,\"c\":\"pl-s\"},{\"s\":45,\"e\":68,\"c\":\"pl-c\"}],[],[{\"s\":0,\"e\":7,\"c\":\"pl-s1\"},{\"s\":0,\"e\":1,\"c\":\"pl-c1\"},{\"s\":11,\"e\":15,\"c\":\"pl-s\"},{\"s\":18,\"e\":35,\"c\":\"pl-c\"}],[{\"s\":0,\"e\":4,\"c\":\"pl-s1\"},{\"s\":0,\"e\":1,\"c\":\"pl-c1\"},{\"s\":7,\"e\":9,\"c\":\"pl-c1\"},{\"s\":12,\"e\":27,\"c\":\"pl-c\"}],[{\"s\":0,\"e\":6,\"c\":\"pl-s1\"},{\"s\":0,\"e\":1,\"c\":\"pl-c1\"},{\"s\":9,\"e\":14,\"c\":\"pl-c1\"},{\"s\":16,\"e\":26,\"c\":\"pl-c\"}],[{\"s\":0,\"e\":5,\"c\":\"pl-s1\"},{\"s\":0,\"e\":1,\"c\":\"pl-c1\"},{\"s\":8,\"e\":12,\"c\":\"pl-c1\"}],[{\"s\":0,\"e\":8,\"c\":\"pl-s1\"},{\"s\":0,\"e\":1,\"c\":\"pl-c1\"},{\"s\":11,\"e\":14,\"c\":\"pl-c1\"}],[{\"s\":0,\"e\":6,\"c\":\"pl-s1\"},{\"s\":0,\"e\":1,\"c\":\"pl-c1\"},{\"s\":11,\"e\":14,\"c\":\"pl-s\"},{\"s\":19,\"e\":22,\"c\":\"pl-s\"},{\"s\":26,\"e\":30,\"c\":\"pl-s\"}],[],[{\"s\":0,\"e\":72,\"c\":\"pl-c\"}],[],[{\"s\":0,\"e\":4,\"c\":\"pl-k\"},{\"s\":6,\"e\":11,\"c\":\"pl-s\"},{\"s\":15,\"e\":22,\"c\":\"pl-s1\"},{\"s\":15,\"e\":16,\"c\":\"pl-c1\"}]],\"colorizedLines\":null,\"csv\":null,\"csvError\":null,\"dependabotInfo\":{\"showConfigurationBanner\":null,\"configFilePath\":null,\"networkDependabotPath\":\"/mouredev/roadmap-retos-programacion/network/updates\",\"dismissConfigurationNoticePath\":\"/settings/dismiss-notice/dependabot_configuration_notice\",\"configurationNoticeDismissed\":false},\"displayName\":\"GitHjuan.php\",\"displayUrl\":\"https://github.com/mouredev/roadmap-retos-programacion/blob/main/Roadmap/00%20-%20SINTAXIS,%20VARIABLES,%20TIPOS%20DE%20DATOS%20Y%20HOLA%20MUNDO/php/GitHjuan.php?raw=true\",\"headerInfo\":{\"blobSize\":\"516 Bytes\",\"deleteTooltip\":\"Delete this file\",\"editTooltip\":\"Edit this file\",\"ghDesktopPath\":\"https://desktop.github.com\",\"isGitLfs\":false,\"onBranch\":true,\"shortPath\":\"16d256c\",\"siteNavLoginPath\":\"/login?return_to=https%3A%2F%2Fgithub.com%2Fmouredev%2Froadmap-retos-programacion%2Fblob%2Fmain%2FRoadmap%2F00%2520-%2520SINTAXIS%252C%2520VARIABLES%252C%2520TIPOS%2520DE%2520DATOS%2520Y%2520HOLA%2520MUNDO%2Fphp%2FGitHjuan.php\",\"isCSV\":false,\"isRichtext\":false,\"toc\":null,\"lineInfo\":{\"truncatedLoc\":\"28\",\"truncatedSloc\":\"19\"},\"mode\":\"file\"},\"image\":false,\"isCodeownersFile\":null,\"isPlain\":false,\"isValidLegacyIssueTemplate\":false,\"issueTemplate\":null,\"discussionTemplate\":null,\"language\":\"PHP\",\"languageID\":272,\"large\":false,\"planSupportInfo\":{\"repoIsFork\":null,\"repoOwnedByCurrentUser\":null,\"requestFullPath\":\"/mouredev/roadmap-retos-programacion/blob/main/Roadmap/00%20-%20SINTAXIS%2C%20VARIABLES%2C%20TIPOS%20DE%20DATOS%20Y%20HOLA%20MUNDO/php/GitHjuan.php\",\"showFreeOrgGatedFeatureMessage\":null,\"showPlanSupportBanner\":null,\"upgradeDataAttributes\":null,\"upgradePath\":null},\"publishBannersInfo\":{\"dismissActionNoticePath\":\"/settings/dismiss-notice/publish_action_from_dockerfile\",\"releasePath\":\"/mouredev/roadmap-retos-programacion/releases/new?marketplace=true\",\"showPublishActionBanner\":false},\"rawBlobUrl\":\"https://github.com/mouredev/roadmap-retos-programacion/raw/main/Roadmap/00%20-%20SINTAXIS,%20VARIABLES,%20TIPOS%20DE%20DATOS%20Y%20HOLA%20MUNDO/php/GitHjuan.php\",\"renderImageOrRaw\":false,\"richText\":null,\"renderedFileInfo\":null,\"shortPath\":null,\"symbolsEnabled\":true,\"tabSize\":8,\"topBannersInfo\":{\"overridingGlobalFundingFile\":false,\"globalPreferredFundingPath\":null,\"showInvalidCitationWarning\":false,\"citationHelpUrl\":\"https://docs.github.com/github/creating-cloning-and-archiving-repositories/creating-a-repository-on-github/about-citation-files\",\"actionsOnboardingTip\":null},\"truncated\":false,\"viewable\":true,\"workflowRedirectUrl\":null,\"symbols\":{\"timed_out\":false,\"not_analyzed\":false,\"symbols\":[]}},\"copilotInfo\":null,\"copilotAccessAllowed\":false,\"csrf_tokens\":{\"/mouredev/roadmap-retos-programacion/branches\":{\"post\":\"KNGyceO0EwdxWWlSGKaq6GN8GZRowXRqVphsjiuDZPovKNwtG2FGn5rcLrGbz-uEyUhC71OXKRSInHHIX9acnw\"},\"/repos/preferences\":{\"post\":\"8X_s12KbezhmtfNtbk0leMnTJ4Ir7oCuIOLP9iilhFxDYuQO8MEGCE0QHRnAXECfJIB22F1XnXRx2BSG1jhukA\"}}},\"title\":\"roadmap-retos-programacion/Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/GitHjuan.php at main · mouredev/roadmap-retos-programacion\",\"appPayload\":{\"helpUrl\":\"https://docs.github.com\",\"findFileWorkerPath\":\"/assets-cdn/worker/find-file-worker-1583894afd38.js\",\"findInFileWorkerPath\":\"/assets-cdn/worker/find-in-file-worker-3a63a487027b.js\",\"githubDevUrl\":\"https://github.dev/\",\"enabled_features\":{\"code_nav_ui_events\":false,\"react_blob_overlay\":false,\"copilot_conversational_ux_embedding_update\":false,\"copilot_smell_icebreaker_ux\":true,\"copilot_workspace\":false}}}</script>\n  <div data-target=\"react-app.reactRoot\"><style data-styled=\"true\" data-styled-version=\"5.3.6\">.jUriTl{font-weight:600;font-size:32px;margin:0;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;font-size:14px;}/*!sc*/\n.imcwCi{font-weight:600;font-size:32px;margin:0;font-size:16px;margin-left:8px;}/*!sc*/\n.cgQnMS{font-weight:600;font-size:32px;margin:0;}/*!sc*/\n.diwsLq{font-weight:600;font-size:32px;margin:0;font-weight:600;display:inline-block;max-width:100%;font-size:16px;}/*!sc*/\n.jAEDJk{font-weight:600;font-size:32px;margin:0;font-weight:600;display:inline-block;max-width:100%;font-size:14px;}/*!sc*/\ndata-styled.g1[id=\"Heading__StyledHeading-sc-1c1dgg0-0\"]{content:\"jUriTl,imcwCi,cgQnMS,diwsLq,jAEDJk,\"}/*!sc*/\n.fSWWem{padding:0;}/*!sc*/\n.kPPmzM{max-width:100%;margin-left:auto;margin-right:auto;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;}/*!sc*/\n.cIAPDV{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex:1 1 100%;-ms-flex:1 1 100%;flex:1 1 100%;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;max-width:100%;}/*!sc*/\n.gvCnwW{width:100%;}/*!sc*/\n@media screen and (min-width:544px){.gvCnwW{width:100%;}}/*!sc*/\n@media screen and (min-width:768px){.gvCnwW{width:auto;}}/*!sc*/\n.heUiss{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-order:1;-ms-flex-order:1;order:1;width:100%;margin-left:0;margin-right:0;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;margin-bottom:0;min-width:0;}/*!sc*/\n@media screen and (min-width:544px){.heUiss{-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}}/*!sc*/\n@media screen and (min-width:768px){.heUiss{width:auto;margin-top:0 !important;margin-bottom:0 !important;position:-webkit-sticky;position:sticky;top:0px;max-height:var(--sticky-pane-height);-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;margin-right:0;}}/*!sc*/\n@media screen and (min-width:769px){.heUiss{height:100vh;max-height:100vh !important;}}/*!sc*/\n@media print,screen and (max-width:1349px) and (min-width:768px){.heUiss{display:none;}}/*!sc*/\n.eUyHuk{margin-left:0;margin-right:0;display:none;margin-top:0;}/*!sc*/\n@media screen and (min-width:768px){.eUyHuk{margin-left:0 !important;margin-right:0 !important;}}/*!sc*/\n.gNdDUH{--pane-min-width:256px;--pane-max-width-diff:511px;--pane-max-width:calc(100vw - var(--pane-max-width-diff));width:100%;padding:0;}/*!sc*/\n@media screen and (min-width:544px){}/*!sc*/\n@media screen and (min-width:768px){.gNdDUH{width:clamp(var(--pane-min-width),var(--pane-width),var(--pane-max-width));overflow:auto;}}/*!sc*/\n@media screen and (min-width:1280px){.gNdDUH{--pane-max-width-diff:959px;}}/*!sc*/\n.jywUSN{max-height:100%;height:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}/*!sc*/\n@media screen and (max-width:768px){.jywUSN{display:none;}}/*!sc*/\n@media screen and (min-width:768px){.jywUSN{max-height:100vh;height:100vh;}}/*!sc*/\n.hBSSUC{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding-left:16px;padding-right:16px;padding-bottom:8px;padding-top:16px;}/*!sc*/\n.iPurHz{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;width:100%;margin-bottom:16px;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}/*!sc*/\n.kkrdEu{-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;}/*!sc*/\n.trpoQ{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;pointer-events:none;}/*!sc*/\n.hVHHYa{margin-left:24px;margin-right:24px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;width:100%;}/*!sc*/\n.idZfsJ{-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;}/*!sc*/\n.bKgizp{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;width:100%;}/*!sc*/\n.dIAShY{margin-right:4px;color:var(--fgColor-muted,var(--color-fg-muted,#848d97));}/*!sc*/\n.caeYDk{font-size:14px;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}/*!sc*/\n.jahcnb{margin-left:8px;white-space:nowrap;}/*!sc*/\n.jahcnb:hover button:not(:hover){border-left-color:var(--button-default-borderColor-hover,var(--color-btn-hover-border));}/*!sc*/\n.ccToMy{margin-left:16px;margin-right:16px;margin-bottom:12px;}/*!sc*/\n@media screen and (max-width:768px){.ccToMy{display:none;}}/*!sc*/\n.cNvKlH{margin-right:-6px;}/*!sc*/\n.cLfAnm{-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;max-height:100% !important;overflow-y:auto;-webkit-scrollbar-gutter:stable;-moz-scrollbar-gutter:stable;-ms-scrollbar-gutter:stable;scrollbar-gutter:stable;}/*!sc*/\n@media screen and (max-width:768px){.cLfAnm{display:none;}}/*!sc*/\n.erWCJP{padding-left:16px;padding-right:16px;padding-bottom:8px;}/*!sc*/\n.hAeDYA{height:100%;position:relative;display:none;margin-left:0;}/*!sc*/\n.gZHqlw{position:absolute;inset:0 -2px;cursor:col-resize;background-color:transparent;-webkit-transition-delay:0.1s;transition-delay:0.1s;}/*!sc*/\n.gZHqlw:hover{background-color:var(--bgColor-neutral-muted,var(--color-neutral-muted,rgba(110,118,129,0.4)));}/*!sc*/\n.emFMJu{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-order:2;-ms-flex-order:2;order:2;-webkit-flex-basis:0;-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;-webkit-flex-shrink:1;-ms-flex-negative:1;flex-shrink:1;min-width:1px;margin-right:auto;}/*!sc*/\n@media print{.emFMJu{display:-webkit-box !important;display:-webkit-flex !important;display:-ms-flexbox !important;display:flex !important;}}/*!sc*/\n.hlUAHL{width:100%;max-width:100%;margin-left:auto;margin-right:auto;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;padding:0;}/*!sc*/\n.iStsmI{margin-left:auto;margin-right:auto;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;padding-bottom:40px;max-width:100%;margin-top:0;}/*!sc*/\n.eIgvIk{display:inherit;}/*!sc*/\n.eVFfWF{width:100%;}/*!sc*/\n.fywjmm{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;gap:8px;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;width:100%;}/*!sc*/\n.dyczTK{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:start;-webkit-box-align:start;-ms-flex-align:start;align-items:start;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;gap:8px;}/*!sc*/\n.kszRgZ{-webkit-align-self:center;-ms-flex-item-align:center;align-self:center;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;padding-right:8px;min-width:0;}/*!sc*/\n.eTvGbF{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;font-size:16px;min-width:0;-webkit-flex-shrink:1;-ms-flex-negative:1;flex-shrink:1;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;max-width:100%;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}/*!sc*/\n.kzRgrI{max-width:100%;}/*!sc*/\n.cmAPIB{max-width:100%;list-style:none;display:inline-block;}/*!sc*/\n.jwXCBK{display:inline-block;max-width:100%;}/*!sc*/\n.gtBUEp{min-height:32px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:start;-webkit-box-align:start;-ms-flex-align:start;align-items:start;}/*!sc*/\n.hVZtwF{margin-left:16px;margin-right:16px;}/*!sc*/\n.cMYnca{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}/*!sc*/\n.brJRqk{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;gap:8px;min-width:273px;padding:8px;}/*!sc*/\n@media screen and (min-width:544px){.brJRqk{-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;}}/*!sc*/\n.bqgLjk{display:inherit;}/*!sc*/\n@media screen and (min-width:544px){.bqgLjk{display:none;}}/*!sc*/\n@media screen and (min-width:768px){.bqgLjk{display:none;}}/*!sc*/\n.iJmJly{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;}/*!sc*/\n.jACbi{width:100%;height:-webkit-fit-content;height:-moz-fit-content;height:fit-content;min-width:0;margin-right:0;}/*!sc*/\n.gIJuDf{height:40px;padding-left:4px;padding-bottom:16px;}/*!sc*/\n.fleZSW{-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}/*!sc*/\n.dVVHlo{font-size:12px;-webkit-flex:auto;-ms-flex:auto;flex:auto;padding-right:16px;color:var(--fgColor-muted,var(--color-fg-muted,#848d97));min-width:0;}/*!sc*/\n.VHzRk{top:0px;z-index:4;background:var(--bgColor-default,var(--color-canvas-default));position:-webkit-sticky;position:sticky;}/*!sc*/\n.ePiodO{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;width:100%;position:absolute;}/*!sc*/\n.kQJlnf{display:none;min-width:0;padding-top:8px;padding-bottom:8px;}/*!sc*/\n.gJICKO{margin-right:8px;margin-left:16px;text-overflow:ellipsis;overflow:hidden;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;width:100%;}/*!sc*/\n.iZJewz{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;font-size:14px;min-width:0;-webkit-flex-shrink:1;-ms-flex-negative:1;flex-shrink:1;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;max-width:100%;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}/*!sc*/\n.jtQniD{padding-left:8px;padding-top:8px;padding-bottom:8px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex:1;-ms-flex:1;flex:1;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;background-color:var(--bgColor-muted,var(--color-canvas-subtle,#161b22));border:1px solid var(--borderColor-default,var(--color-border-default));border-radius:6px 6px 0px 0px;}/*!sc*/\n.bfkNRF{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;gap:8px;min-width:0;}/*!sc*/\n.fXBLEV{display:block;position:relative;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;margin-top:-1px;margin-bottom:-1px;--separator-color:transparent;}/*!sc*/\n.fXBLEV:not(:last-child){margin-right:1px;}/*!sc*/\n.fXBLEV:not(:last-child):after{background-color:var(--separator-color);content:\"\";position:absolute;right:-2px;top:8px;bottom:8px;width:1px;}/*!sc*/\n.fXBLEV:focus-within:has(:focus-visible){--separator-color:transparent;}/*!sc*/\n.fXBLEV:first-child{margin-left:-1px;}/*!sc*/\n.fXBLEV:last-child{margin-right:-1px;}/*!sc*/\n.illvPQ{display:block;position:relative;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;margin-top:-1px;margin-bottom:-1px;--separator-color:var(--borderColor-default,var(--color-border-default,#30363d));}/*!sc*/\n.illvPQ:not(:last-child){margin-right:1px;}/*!sc*/\n.illvPQ:not(:last-child):after{background-color:var(--separator-color);content:\"\";position:absolute;right:-2px;top:8px;bottom:8px;width:1px;}/*!sc*/\n.illvPQ:focus-within:has(:focus-visible){--separator-color:transparent;}/*!sc*/\n.illvPQ:first-child{margin-left:-1px;}/*!sc*/\n.illvPQ:last-child{margin-right:-1px;}/*!sc*/\n.iBylDf{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;gap:8px;margin-right:8px;}/*!sc*/\n.kSGBPx{gap:8px;}/*!sc*/\n.jMJFjm{border:1px solid;border-top:none;border-color:var(--borderColor-default,var(--color-border-default,#30363d));border-radius:0px 0px 6px 6px;min-width:273px;}/*!sc*/\n.jWnGGx{background-color:var(--bgColor-default,var(--color-canvas-default));border:0px;border-width:0;border-radius:0px 0px 6px 6px;padding:0;min-width:0;margin-top:46px;}/*!sc*/\n.TCenl{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex:1;-ms-flex:1;flex:1;padding-top:8px;padding-bottom:8px;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;min-width:0;position:relative;}/*!sc*/\n.cluMzC{position:relative;}/*!sc*/\n.eRkHwF{-webkit-flex:1;-ms-flex:1;flex:1;position:relative;min-width:0;}/*!sc*/\n.knCTAx{tab-size:8;isolation:isolate;position:relative;overflow:auto;max-width:unset;}/*!sc*/\n.aZrVR{position:fixed;top:0;right:0;height:100%;width:15px;-webkit-transition:-webkit-transform 0.3s;-webkit-transition:transform 0.3s;transition:transform 0.3s;z-index:1;}/*!sc*/\n.aZrVR:hover{-webkit-transform:scaleX(1.5);-ms-transform:scaleX(1.5);transform:scaleX(1.5);}/*!sc*/\ndata-styled.g2[id=\"Box-sc-g0xbh4-0\"]{content:\"fSWWem,kPPmzM,cIAPDV,gvCnwW,heUiss,eUyHuk,gNdDUH,jywUSN,hBSSUC,iPurHz,kkrdEu,trpoQ,hVHHYa,idZfsJ,bKgizp,dIAShY,caeYDk,jahcnb,ccToMy,cNvKlH,cLfAnm,erWCJP,hAeDYA,gZHqlw,emFMJu,hlUAHL,iStsmI,eIgvIk,eVFfWF,fywjmm,dyczTK,kszRgZ,eTvGbF,kzRgrI,cmAPIB,jwXCBK,gtBUEp,hVZtwF,cMYnca,brJRqk,bqgLjk,iJmJly,jACbi,gIJuDf,fleZSW,dVVHlo,VHzRk,ePiodO,kQJlnf,gJICKO,iZJewz,jtQniD,bfkNRF,fXBLEV,illvPQ,iBylDf,kSGBPx,jMJFjm,jWnGGx,TCenl,cluMzC,eRkHwF,knCTAx,aZrVR,\"}/*!sc*/\nbody[data-page-layout-dragging=\"true\"]{cursor:col-resize;}/*!sc*/\nbody[data-page-layout-dragging=\"true\"] *{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;}/*!sc*/\ndata-styled.g3[id=\"sc-global-gbKrvU1\"]{content:\"sc-global-gbKrvU1,\"}/*!sc*/\n.bOMzPg{min-width:0;}/*!sc*/\n.ePvrxx{padding-left:4px;padding-right:4px;font-weight:400;color:var(--fgColor-muted,var(--color-fg-muted,#848d97));font-size:16px;}/*!sc*/\n.fQxKLn{padding-left:4px;padding-right:4px;font-weight:400;color:var(--fgColor-muted,var(--color-fg-muted,#848d97));font-size:14px;}/*!sc*/\ndata-styled.g6[id=\"Text-sc-17v1xeu-0\"]{content:\"bOMzPg,ePvrxx,gPDEWA,fQxKLn,\"}/*!sc*/\n.dpowyu{color:var(--fgColor-accent,var(--color-accent-fg,#2f81f7));-webkit-text-decoration:none;text-decoration:none;font-weight:600;}/*!sc*/\n[data-a11y-link-underlines='true'] .Link__StyledLink-sc-14289xe-0[data-inline='true']{-webkit-text-decoration:underline;text-decoration:underline;}/*!sc*/\n.dpowyu:hover{-webkit-text-decoration:underline;text-decoration:underline;}/*!sc*/\n.dpowyu:is(button){display:inline-block;padding:0;font-size:inherit;white-space:nowrap;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:transparent;border:0;-webkit-appearance:none;-moz-appearance:none;appearance:none;}/*!sc*/\n.csCkZA{color:var(--fgColor-accent,var(--color-accent-fg,#2f81f7));-webkit-text-decoration:none;text-decoration:none;font-weight:400;}/*!sc*/\n[data-a11y-link-underlines='true'] .Link__StyledLink-sc-14289xe-0[data-inline='true']{-webkit-text-decoration:underline;text-decoration:underline;}/*!sc*/\n.csCkZA:hover{-webkit-text-decoration:underline;text-decoration:underline;}/*!sc*/\n.csCkZA:is(button){display:inline-block;padding:0;font-size:inherit;white-space:nowrap;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:transparent;border:0;-webkit-appearance:none;-moz-appearance:none;appearance:none;}/*!sc*/\n.elltiT{color:var(--fgColor-accent,var(--color-accent-fg,#2f81f7));-webkit-text-decoration:none;text-decoration:none;}/*!sc*/\n[data-a11y-link-underlines='true'] .Link__StyledLink-sc-14289xe-0[data-inline='true']{-webkit-text-decoration:underline;text-decoration:underline;}/*!sc*/\n.elltiT:hover{-webkit-text-decoration:underline;text-decoration:underline;}/*!sc*/\n.elltiT:is(button){display:inline-block;padding:0;font-size:inherit;white-space:nowrap;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:transparent;border:0;-webkit-appearance:none;-moz-appearance:none;appearance:none;}/*!sc*/\ndata-styled.g8[id=\"Link__StyledLink-sc-14289xe-0\"]{content:\"dpowyu,csCkZA,elltiT,\"}/*!sc*/\n.iKABXH{border-radius:6px;border:1px solid;border-color:transparent;font-family:inherit;font-weight:500;font-size:14px;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-text-decoration:none;text-decoration:none;text-align:center;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;height:32px;padding:0 12px;gap:8px;min-width:-webkit-max-content;min-width:-moz-max-content;min-width:max-content;-webkit-transition:80ms cubic-bezier(0.65,0,0.35,1);transition:80ms cubic-bezier(0.65,0,0.35,1);-webkit-transition-property:color,fill,background-color,border-color;transition-property:color,fill,background-color,border-color;color:var(--button-default-fgColor-rest,var(--color-btn-text,#c9d1d9));background-color:transparent;box-shadow:none;}/*!sc*/\n.iKABXH:focus:not(:disabled){box-shadow:none;outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#2f81f7));outline-offset:-2px;}/*!sc*/\n.iKABXH:focus:not(:disabled):not(:focus-visible){outline:solid 1px transparent;}/*!sc*/\n.iKABXH:focus-visible:not(:disabled){box-shadow:none;outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#2f81f7));outline-offset:-2px;}/*!sc*/\n.iKABXH[href]{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;}/*!sc*/\n.iKABXH[href]:hover{-webkit-text-decoration:none;text-decoration:none;}/*!sc*/\n.iKABXH:hover{-webkit-transition-duration:80ms;transition-duration:80ms;}/*!sc*/\n.iKABXH:active{-webkit-transition:none;transition:none;}/*!sc*/\n.iKABXH[data-inactive]{cursor:auto;}/*!sc*/\n.iKABXH:disabled{cursor:not-allowed;box-shadow:none;color:var(--fgColor-disabled,var(--color-primer-fg-disabled,#484f58));}/*!sc*/\n.iKABXH:disabled [data-component=ButtonCounter],.iKABXH:disabled [data-component=\"leadingVisual\"],.iKABXH:disabled [data-component=\"trailingAction\"]{color:inherit;}/*!sc*/\n@media (forced-colors:active){.iKABXH:focus{outline:solid 1px transparent;}}/*!sc*/\n.iKABXH [data-component=ButtonCounter]{font-size:12px;}/*!sc*/\n.iKABXH[data-component=IconButton]{display:inline-grid;padding:unset;place-content:center;width:32px;min-width:unset;}/*!sc*/\n.iKABXH[data-size=\"small\"]{padding:0 8px;height:28px;gap:4px;font-size:12px;}/*!sc*/\n.iKABXH[data-size=\"small\"] [data-component=\"text\"]{line-height:calc(20 / 12);}/*!sc*/\n.iKABXH[data-size=\"small\"] [data-component=ButtonCounter]{font-size:12px;}/*!sc*/\n.iKABXH[data-size=\"small\"] [data-component=\"buttonContent\"] > :not(:last-child){margin-right:4px;}/*!sc*/\n.iKABXH[data-size=\"small\"][data-component=IconButton]{width:28px;padding:unset;}/*!sc*/\n.iKABXH[data-size=\"large\"]{padding:0 16px;height:40px;gap:8px;}/*!sc*/\n.iKABXH[data-size=\"large\"] [data-component=\"buttonContent\"] > :not(:last-child){margin-right:8px;}/*!sc*/\n.iKABXH[data-size=\"large\"][data-component=IconButton]{width:40px;padding:unset;}/*!sc*/\n.iKABXH[data-block=\"block\"]{width:100%;}/*!sc*/\n.iKABXH[data-inactive]:not([disabled]){background-color:var(--button-inactive-bgColor,var(--button-inactive-bgColor-rest,var(--color-btn-inactive-bg,#21262d)));border-color:var(--button-inactive-bgColor,var(--button-inactive-bgColor-rest,var(--color-btn-inactive-bg,#21262d)));color:var(--button-inactive-fgColor,var(--button-inactive-fgColor-rest,var(--color-btn-inactive-text,#8b949e)));}/*!sc*/\n.iKABXH[data-inactive]:not([disabled]):focus-visible{box-shadow:none;}/*!sc*/\n.iKABXH [data-component=\"leadingVisual\"]{grid-area:leadingVisual;color:var(--fgColor-muted,var(--color-fg-muted,#848d97));}/*!sc*/\n.iKABXH [data-component=\"text\"]{grid-area:text;line-height:calc(20/14);white-space:nowrap;}/*!sc*/\n.iKABXH [data-component=\"trailingVisual\"]{grid-area:trailingVisual;}/*!sc*/\n.iKABXH [data-component=\"trailingAction\"]{margin-right:-4px;color:var(--fgColor-muted,var(--color-fg-muted,#848d97));}/*!sc*/\n.iKABXH [data-component=\"buttonContent\"]{-webkit-flex:1 0 auto;-ms-flex:1 0 auto;flex:1 0 auto;display:grid;grid-template-areas:\"leadingVisual text trailingVisual\";grid-template-columns:min-content minmax(0,auto) min-content;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-align-content:center;-ms-flex-line-pack:center;align-content:center;}/*!sc*/\n.iKABXH [data-component=\"buttonContent\"] > :not(:last-child){margin-right:8px;}/*!sc*/\n.iKABXH:hover:not([disabled]){background-color:var(--control-transparent-bgColor-hover,var(--color-action-list-item-default-hover-bg,rgba(177,186,196,0.12)));}/*!sc*/\n.iKABXH:active:not([disabled]){background-color:var(--control-transparent-bgColor-active,var(--color-action-list-item-default-active-bg,rgba(177,186,196,0.2)));}/*!sc*/\n.iKABXH[aria-expanded=true]{background-color:var(--control-transparent-bgColor-selected,var(--color-action-list-item-default-selected-bg,rgba(177,186,196,0.08)));}/*!sc*/\n.iKABXH[data-component=\"IconButton\"][data-no-visuals]{color:var(--fgColor-muted,var(--color-fg-muted,#848d97));}/*!sc*/\n.iKABXH[data-no-visuals]{color:var(--fgColor-accent,var(--color-accent-fg,#2f81f7));}/*!sc*/\n.iKABXH:has([data-component=\"ButtonCounter\"]){color:var(--button-default-fgColor-rest,var(--color-btn-text,#c9d1d9));}/*!sc*/\n.iKABXH:disabled[data-no-visuals]{color:var(--fgColor-disabled,var(--color-primer-fg-disabled,#484f58));}/*!sc*/\n.iKABXH:disabled[data-no-visuals] [data-component=ButtonCounter]{color:inherit;}/*!sc*/\n.iKABXH{color:var(--fgColor-muted,var(--color-fg-muted,#848d97));padding-left:8px;padding-right:8px;display:none;}/*!sc*/\n@media screen and (max-width:768px){.iKABXH{display:block;}}/*!sc*/\n.hfWObv{border-radius:6px;border:1px solid;border-color:transparent;font-family:inherit;font-weight:500;font-size:14px;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-text-decoration:none;text-decoration:none;text-align:center;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;height:32px;padding:0 12px;gap:8px;min-width:-webkit-max-content;min-width:-moz-max-content;min-width:max-content;-webkit-transition:80ms cubic-bezier(0.65,0,0.35,1);transition:80ms cubic-bezier(0.65,0,0.35,1);-webkit-transition-property:color,fill,background-color,border-color;transition-property:color,fill,background-color,border-color;color:var(--button-default-fgColor-rest,var(--color-btn-text,#c9d1d9));background-color:transparent;box-shadow:none;}/*!sc*/\n.hfWObv:focus:not(:disabled){box-shadow:none;outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#2f81f7));outline-offset:-2px;}/*!sc*/\n.hfWObv:focus:not(:disabled):not(:focus-visible){outline:solid 1px transparent;}/*!sc*/\n.hfWObv:focus-visible:not(:disabled){box-shadow:none;outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#2f81f7));outline-offset:-2px;}/*!sc*/\n.hfWObv[href]{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;}/*!sc*/\n.hfWObv[href]:hover{-webkit-text-decoration:none;text-decoration:none;}/*!sc*/\n.hfWObv:hover{-webkit-transition-duration:80ms;transition-duration:80ms;}/*!sc*/\n.hfWObv:active{-webkit-transition:none;transition:none;}/*!sc*/\n.hfWObv[data-inactive]{cursor:auto;}/*!sc*/\n.hfWObv:disabled{cursor:not-allowed;box-shadow:none;color:var(--fgColor-disabled,var(--color-primer-fg-disabled,#484f58));}/*!sc*/\n.hfWObv:disabled [data-component=ButtonCounter],.hfWObv:disabled [data-component=\"leadingVisual\"],.hfWObv:disabled [data-component=\"trailingAction\"]{color:inherit;}/*!sc*/\n@media (forced-colors:active){.hfWObv:focus{outline:solid 1px transparent;}}/*!sc*/\n.hfWObv [data-component=ButtonCounter]{font-size:12px;}/*!sc*/\n.hfWObv[data-component=IconButton]{display:inline-grid;padding:unset;place-content:center;width:32px;min-width:unset;}/*!sc*/\n.hfWObv[data-size=\"small\"]{padding:0 8px;height:28px;gap:4px;font-size:12px;}/*!sc*/\n.hfWObv[data-size=\"small\"] [data-component=\"text\"]{line-height:calc(20 / 12);}/*!sc*/\n.hfWObv[data-size=\"small\"] [data-component=ButtonCounter]{font-size:12px;}/*!sc*/\n.hfWObv[data-size=\"small\"] [data-component=\"buttonContent\"] > :not(:last-child){margin-right:4px;}/*!sc*/\n.hfWObv[data-size=\"small\"][data-component=IconButton]{width:28px;padding:unset;}/*!sc*/\n.hfWObv[data-size=\"large\"]{padding:0 16px;height:40px;gap:8px;}/*!sc*/\n.hfWObv[data-size=\"large\"] [data-component=\"buttonContent\"] > :not(:last-child){margin-right:8px;}/*!sc*/\n.hfWObv[data-size=\"large\"][data-component=IconButton]{width:40px;padding:unset;}/*!sc*/\n.hfWObv[data-block=\"block\"]{width:100%;}/*!sc*/\n.hfWObv[data-inactive]:not([disabled]){background-color:var(--button-inactive-bgColor,var(--button-inactive-bgColor-rest,var(--color-btn-inactive-bg,#21262d)));border-color:var(--button-inactive-bgColor,var(--button-inactive-bgColor-rest,var(--color-btn-inactive-bg,#21262d)));color:var(--button-inactive-fgColor,var(--button-inactive-fgColor-rest,var(--color-btn-inactive-text,#8b949e)));}/*!sc*/\n.hfWObv[data-inactive]:not([disabled]):focus-visible{box-shadow:none;}/*!sc*/\n.hfWObv [data-component=\"leadingVisual\"]{grid-area:leadingVisual;color:var(--fgColor-muted,var(--color-fg-muted,#848d97));}/*!sc*/\n.hfWObv [data-component=\"text\"]{grid-area:text;line-height:calc(20/14);white-space:nowrap;}/*!sc*/\n.hfWObv [data-component=\"trailingVisual\"]{grid-area:trailingVisual;}/*!sc*/\n.hfWObv [data-component=\"trailingAction\"]{margin-right:-4px;color:var(--fgColor-muted,var(--color-fg-muted,#848d97));}/*!sc*/\n.hfWObv [data-component=\"buttonContent\"]{-webkit-flex:1 0 auto;-ms-flex:1 0 auto;flex:1 0 auto;display:grid;grid-template-areas:\"leadingVisual text trailingVisual\";grid-template-columns:min-content minmax(0,auto) min-content;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-align-content:center;-ms-flex-line-pack:center;align-content:center;}/*!sc*/\n.hfWObv [data-component=\"buttonContent\"] > :not(:last-child){margin-right:8px;}/*!sc*/\n.hfWObv:hover:not([disabled]){background-color:var(--control-transparent-bgColor-hover,var(--color-action-list-item-default-hover-bg,rgba(177,186,196,0.12)));}/*!sc*/\n.hfWObv:active:not([disabled]){background-color:var(--control-transparent-bgColor-active,var(--color-action-list-item-default-active-bg,rgba(177,186,196,0.2)));}/*!sc*/\n.hfWObv[aria-expanded=true]{background-color:var(--control-transparent-bgColor-selected,var(--color-action-list-item-default-selected-bg,rgba(177,186,196,0.08)));}/*!sc*/\n.hfWObv[data-component=\"IconButton\"][data-no-visuals]{color:var(--fgColor-muted,var(--color-fg-muted,#848d97));}/*!sc*/\n.hfWObv[data-no-visuals]{color:var(--fgColor-muted,var(--color-fg-muted,#848d97));height:32px;position:relative;}/*!sc*/\n@media screen and (max-width:768px){.hfWObv[data-no-visuals]{display:none;}}/*!sc*/\n.hfWObv:has([data-component=\"ButtonCounter\"]){color:var(--button-default-fgColor-rest,var(--color-btn-text,#c9d1d9));}/*!sc*/\n.hfWObv:disabled[data-no-visuals]{color:var(--fgColor-disabled,var(--color-primer-fg-disabled,#484f58));}/*!sc*/\n.hfWObv:disabled[data-no-visuals] [data-component=ButtonCounter]{color:inherit;}/*!sc*/\n.gBsjGI{border-radius:6px;border:1px solid;border-color:var(--button-default-borderColor-rest,var(--button-default-borderColor-rest,var(--color-btn-border,rgba(240,246,252,0.1))));font-family:inherit;font-weight:500;font-size:14px;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-text-decoration:none;text-decoration:none;text-align:center;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;height:32px;padding:0 12px;gap:8px;min-width:-webkit-max-content;min-width:-moz-max-content;min-width:max-content;-webkit-transition:80ms cubic-bezier(0.65,0,0.35,1);transition:80ms cubic-bezier(0.65,0,0.35,1);-webkit-transition-property:color,fill,background-color,border-color;transition-property:color,fill,background-color,border-color;color:var(--button-default-fgColor-rest,var(--color-btn-text,#c9d1d9));background-color:var(--button-default-bgColor-rest,var(--color-btn-bg,#21262d));box-shadow:var(--button-default-shadow-resting,var(--color-btn-shadow,0 0 transparent)),var(--button-default-shadow-inset,var(--color-btn-inset-shadow,0 0 transparent));}/*!sc*/\n.gBsjGI:focus:not(:disabled){box-shadow:none;outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#2f81f7));outline-offset:-2px;}/*!sc*/\n.gBsjGI:focus:not(:disabled):not(:focus-visible){outline:solid 1px transparent;}/*!sc*/\n.gBsjGI:focus-visible:not(:disabled){box-shadow:none;outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#2f81f7));outline-offset:-2px;}/*!sc*/\n.gBsjGI[href]{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;}/*!sc*/\n.gBsjGI[href]:hover{-webkit-text-decoration:none;text-decoration:none;}/*!sc*/\n.gBsjGI:hover{-webkit-transition-duration:80ms;transition-duration:80ms;}/*!sc*/\n.gBsjGI:active{-webkit-transition:none;transition:none;}/*!sc*/\n.gBsjGI[data-inactive]{cursor:auto;}/*!sc*/\n.gBsjGI:disabled{cursor:not-allowed;box-shadow:none;color:var(--fgColor-disabled,var(--color-primer-fg-disabled,#484f58));border-color:var(--button-default-borderColor-disabled,var(--button-default-borderColor-rest,var(--color-btn-border,rgba(240,246,252,0.1))));background-color:var(--button-default-bgColor-disabled,var(--control-bgColor-disabled,var(--color-input-disabled-bg,rgba(110,118,129,0))));}/*!sc*/\n.gBsjGI:disabled [data-component=ButtonCounter]{color:inherit;}/*!sc*/\n@media (forced-colors:active){.gBsjGI:focus{outline:solid 1px transparent;}}/*!sc*/\n.gBsjGI [data-component=ButtonCounter]{font-size:12px;background-color:var(--buttonCounter-default-bgColor-rest,var(--color-btn-counter-bg,#30363d));}/*!sc*/\n.gBsjGI[data-component=IconButton]{display:inline-grid;padding:unset;place-content:center;width:32px;min-width:unset;}/*!sc*/\n.gBsjGI[data-size=\"small\"]{padding:0 8px;height:28px;gap:4px;font-size:12px;}/*!sc*/\n.gBsjGI[data-size=\"small\"] [data-component=\"text\"]{line-height:calc(20 / 12);}/*!sc*/\n.gBsjGI[data-size=\"small\"] [data-component=ButtonCounter]{font-size:12px;}/*!sc*/\n.gBsjGI[data-size=\"small\"] [data-component=\"buttonContent\"] > :not(:last-child){margin-right:4px;}/*!sc*/\n.gBsjGI[data-size=\"small\"][data-component=IconButton]{width:28px;padding:unset;}/*!sc*/\n.gBsjGI[data-size=\"large\"]{padding:0 16px;height:40px;gap:8px;}/*!sc*/\n.gBsjGI[data-size=\"large\"] [data-component=\"buttonContent\"] > :not(:last-child){margin-right:8px;}/*!sc*/\n.gBsjGI[data-size=\"large\"][data-component=IconButton]{width:40px;padding:unset;}/*!sc*/\n.gBsjGI[data-block=\"block\"]{width:100%;}/*!sc*/\n.gBsjGI[data-inactive]:not([disabled]){background-color:var(--button-inactive-bgColor,var(--button-inactive-bgColor-rest,var(--color-btn-inactive-bg,#21262d)));border-color:var(--button-inactive-bgColor,var(--button-inactive-bgColor-rest,var(--color-btn-inactive-bg,#21262d)));color:var(--button-inactive-fgColor,var(--button-inactive-fgColor-rest,var(--color-btn-inactive-text,#8b949e)));}/*!sc*/\n.gBsjGI[data-inactive]:not([disabled]):focus-visible{box-shadow:none;}/*!sc*/\n.gBsjGI [data-component=\"leadingVisual\"]{grid-area:leadingVisual;}/*!sc*/\n.gBsjGI [data-component=\"text\"]{grid-area:text;line-height:calc(20/14);white-space:nowrap;}/*!sc*/\n.gBsjGI [data-component=\"trailingVisual\"]{grid-area:trailingVisual;}/*!sc*/\n.gBsjGI [data-component=\"trailingAction\"]{margin-right:-4px;}/*!sc*/\n.gBsjGI [data-component=\"buttonContent\"]{-webkit-flex:1 0 auto;-ms-flex:1 0 auto;flex:1 0 auto;display:grid;grid-template-areas:\"leadingVisual text trailingVisual\";grid-template-columns:min-content minmax(0,auto) min-content;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-align-content:center;-ms-flex-line-pack:center;align-content:center;}/*!sc*/\n.gBsjGI [data-component=\"buttonContent\"] > :not(:last-child){margin-right:8px;}/*!sc*/\n.gBsjGI:hover:not([disabled]):not([data-inactive]){background-color:var(--button-default-bgColor-hover,var(--color-btn-hover-bg,#30363d));border-color:var(--button-default-borderColor-hover,var(--button-default-borderColor-hover,var(--color-btn-hover-border,#8b949e)));}/*!sc*/\n.gBsjGI:active:not([disabled]):not([data-inactive]){background-color:var(--button-default-bgColor-active,var(--color-btn-active-bg,hsla(212,12%,18%,1)));border-color:var(--button-default-borderColor-active,var(--button-default-borderColor-active,var(--color-btn-active-border,#6e7681)));}/*!sc*/\n.gBsjGI[aria-expanded=true]{background-color:var(--button-default-bgColor-active,var(--color-btn-active-bg,hsla(212,12%,18%,1)));border-color:var(--button-default-borderColor-active,var(--button-default-borderColor-active,var(--color-btn-active-border,#6e7681)));}/*!sc*/\n.gBsjGI [data-component=\"leadingVisual\"],.gBsjGI [data-component=\"trailingVisual\"],.gBsjGI [data-component=\"trailingAction\"]{color:var(--button-color,var(--fgColor-muted,var(--color-fg-muted,#848d97)));}/*!sc*/\n.gBsjGI[data-component=\"IconButton\"][data-no-visuals]{color:var(--fgColor-muted,var(--color-fg-muted,#848d97));}/*!sc*/\n.gBsjGI{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;min-width:0;}/*!sc*/\n.gBsjGI svg{color:var(--fgColor-muted,var(--color-fg-muted,#848d97));}/*!sc*/\n.gBsjGI > span{width:inherit;}/*!sc*/\n.XJZbf{border-radius:6px;border:1px solid;border-color:var(--button-default-borderColor-rest,var(--button-default-borderColor-rest,var(--color-btn-border,rgba(240,246,252,0.1))));font-family:inherit;font-weight:500;font-size:14px;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-text-decoration:none;text-decoration:none;text-align:center;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;height:32px;padding:0 12px;gap:8px;min-width:-webkit-max-content;min-width:-moz-max-content;min-width:max-content;-webkit-transition:80ms cubic-bezier(0.65,0,0.35,1);transition:80ms cubic-bezier(0.65,0,0.35,1);-webkit-transition-property:color,fill,background-color,border-color;transition-property:color,fill,background-color,border-color;color:var(--button-default-fgColor-rest,var(--color-btn-text,#c9d1d9));background-color:var(--button-default-bgColor-rest,var(--color-btn-bg,#21262d));box-shadow:var(--button-default-shadow-resting,var(--color-btn-shadow,0 0 transparent)),var(--button-default-shadow-inset,var(--color-btn-inset-shadow,0 0 transparent));}/*!sc*/\n.XJZbf:focus:not(:disabled){box-shadow:none;outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#2f81f7));outline-offset:-2px;}/*!sc*/\n.XJZbf:focus:not(:disabled):not(:focus-visible){outline:solid 1px transparent;}/*!sc*/\n.XJZbf:focus-visible:not(:disabled){box-shadow:none;outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#2f81f7));outline-offset:-2px;}/*!sc*/\n.XJZbf[href]{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;}/*!sc*/\n.XJZbf[href]:hover{-webkit-text-decoration:none;text-decoration:none;}/*!sc*/\n.XJZbf:hover{-webkit-transition-duration:80ms;transition-duration:80ms;}/*!sc*/\n.XJZbf:active{-webkit-transition:none;transition:none;}/*!sc*/\n.XJZbf[data-inactive]{cursor:auto;}/*!sc*/\n.XJZbf:disabled{cursor:not-allowed;box-shadow:none;color:var(--fgColor-disabled,var(--color-primer-fg-disabled,#484f58));border-color:var(--button-default-borderColor-disabled,var(--button-default-borderColor-rest,var(--color-btn-border,rgba(240,246,252,0.1))));background-color:var(--button-default-bgColor-disabled,var(--control-bgColor-disabled,var(--color-input-disabled-bg,rgba(110,118,129,0))));}/*!sc*/\n.XJZbf:disabled [data-component=ButtonCounter]{color:inherit;}/*!sc*/\n@media (forced-colors:active){.XJZbf:focus{outline:solid 1px transparent;}}/*!sc*/\n.XJZbf [data-component=ButtonCounter]{font-size:12px;background-color:var(--buttonCounter-default-bgColor-rest,var(--color-btn-counter-bg,#30363d));}/*!sc*/\n.XJZbf[data-component=IconButton]{display:inline-grid;padding:unset;place-content:center;width:32px;min-width:unset;}/*!sc*/\n.XJZbf[data-size=\"small\"]{padding:0 8px;height:28px;gap:4px;font-size:12px;}/*!sc*/\n.XJZbf[data-size=\"small\"] [data-component=\"text\"]{line-height:calc(20 / 12);}/*!sc*/\n.XJZbf[data-size=\"small\"] [data-component=ButtonCounter]{font-size:12px;}/*!sc*/\n.XJZbf[data-size=\"small\"] [data-component=\"buttonContent\"] > :not(:last-child){margin-right:4px;}/*!sc*/\n.XJZbf[data-size=\"small\"][data-component=IconButton]{width:28px;padding:unset;}/*!sc*/\n.XJZbf[data-size=\"large\"]{padding:0 16px;height:40px;gap:8px;}/*!sc*/\n.XJZbf[data-size=\"large\"] [data-component=\"buttonContent\"] > :not(:last-child){margin-right:8px;}/*!sc*/\n.XJZbf[data-size=\"large\"][data-component=IconButton]{width:40px;padding:unset;}/*!sc*/\n.XJZbf[data-block=\"block\"]{width:100%;}/*!sc*/\n.XJZbf[data-inactive]:not([disabled]){background-color:var(--button-inactive-bgColor,var(--button-inactive-bgColor-rest,var(--color-btn-inactive-bg,#21262d)));border-color:var(--button-inactive-bgColor,var(--button-inactive-bgColor-rest,var(--color-btn-inactive-bg,#21262d)));color:var(--button-inactive-fgColor,var(--button-inactive-fgColor-rest,var(--color-btn-inactive-text,#8b949e)));}/*!sc*/\n.XJZbf[data-inactive]:not([disabled]):focus-visible{box-shadow:none;}/*!sc*/\n.XJZbf [data-component=\"leadingVisual\"]{grid-area:leadingVisual;}/*!sc*/\n.XJZbf [data-component=\"text\"]{grid-area:text;line-height:calc(20/14);white-space:nowrap;}/*!sc*/\n.XJZbf [data-component=\"trailingVisual\"]{grid-area:trailingVisual;}/*!sc*/\n.XJZbf [data-component=\"trailingAction\"]{margin-right:-4px;}/*!sc*/\n.XJZbf [data-component=\"buttonContent\"]{-webkit-flex:1 0 auto;-ms-flex:1 0 auto;flex:1 0 auto;display:grid;grid-template-areas:\"leadingVisual text trailingVisual\";grid-template-columns:min-content minmax(0,auto) min-content;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-align-content:center;-ms-flex-line-pack:center;align-content:center;}/*!sc*/\n.XJZbf [data-component=\"buttonContent\"] > :not(:last-child){margin-right:8px;}/*!sc*/\n.XJZbf:hover:not([disabled]):not([data-inactive]){background-color:var(--button-default-bgColor-hover,var(--color-btn-hover-bg,#30363d));border-color:var(--button-default-borderColor-hover,var(--button-default-borderColor-hover,var(--color-btn-hover-border,#8b949e)));}/*!sc*/\n.XJZbf:active:not([disabled]):not([data-inactive]){background-color:var(--button-default-bgColor-active,var(--color-btn-active-bg,hsla(212,12%,18%,1)));border-color:var(--button-default-borderColor-active,var(--button-default-borderColor-active,var(--color-btn-active-border,#6e7681)));}/*!sc*/\n.XJZbf[aria-expanded=true]{background-color:var(--button-default-bgColor-active,var(--color-btn-active-bg,hsla(212,12%,18%,1)));border-color:var(--button-default-borderColor-active,var(--button-default-borderColor-active,var(--color-btn-active-border,#6e7681)));}/*!sc*/\n.XJZbf [data-component=\"leadingVisual\"],.XJZbf [data-component=\"trailingVisual\"],.XJZbf [data-component=\"trailingAction\"]{color:var(--button-color,var(--fgColor-muted,var(--color-fg-muted,#848d97)));}/*!sc*/\n.XJZbf[data-component=\"IconButton\"][data-no-visuals]{color:var(--fgColor-muted,var(--color-fg-muted,#848d97));}/*!sc*/\n.XJZbf[data-no-visuals]{color:var(--fgColor-muted,var(--color-fg-subtle,#6e7681));border-top-right-radius:0;border-bottom-right-radius:0;border-right:0;}/*!sc*/\n.cBjhIZ{border-radius:6px;border:1px solid;border-color:var(--button-default-borderColor-rest,var(--button-default-borderColor-rest,var(--color-btn-border,rgba(240,246,252,0.1))));font-family:inherit;font-weight:500;font-size:14px;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-text-decoration:none;text-decoration:none;text-align:center;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;height:32px;padding:0 12px;gap:8px;min-width:-webkit-max-content;min-width:-moz-max-content;min-width:max-content;-webkit-transition:80ms cubic-bezier(0.65,0,0.35,1);transition:80ms cubic-bezier(0.65,0,0.35,1);-webkit-transition-property:color,fill,background-color,border-color;transition-property:color,fill,background-color,border-color;color:var(--button-default-fgColor-rest,var(--color-btn-text,#c9d1d9));background-color:var(--button-default-bgColor-rest,var(--color-btn-bg,#21262d));box-shadow:var(--button-default-shadow-resting,var(--color-btn-shadow,0 0 transparent)),var(--button-default-shadow-inset,var(--color-btn-inset-shadow,0 0 transparent));}/*!sc*/\n.cBjhIZ:focus:not(:disabled){box-shadow:none;outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#2f81f7));outline-offset:-2px;}/*!sc*/\n.cBjhIZ:focus:not(:disabled):not(:focus-visible){outline:solid 1px transparent;}/*!sc*/\n.cBjhIZ:focus-visible:not(:disabled){box-shadow:none;outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#2f81f7));outline-offset:-2px;}/*!sc*/\n.cBjhIZ[href]{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;}/*!sc*/\n.cBjhIZ[href]:hover{-webkit-text-decoration:none;text-decoration:none;}/*!sc*/\n.cBjhIZ:hover{-webkit-transition-duration:80ms;transition-duration:80ms;}/*!sc*/\n.cBjhIZ:active{-webkit-transition:none;transition:none;}/*!sc*/\n.cBjhIZ[data-inactive]{cursor:auto;}/*!sc*/\n.cBjhIZ:disabled{cursor:not-allowed;box-shadow:none;color:var(--fgColor-disabled,var(--color-primer-fg-disabled,#484f58));border-color:var(--button-default-borderColor-disabled,var(--button-default-borderColor-rest,var(--color-btn-border,rgba(240,246,252,0.1))));background-color:var(--button-default-bgColor-disabled,var(--control-bgColor-disabled,var(--color-input-disabled-bg,rgba(110,118,129,0))));}/*!sc*/\n.cBjhIZ:disabled [data-component=ButtonCounter]{color:inherit;}/*!sc*/\n@media (forced-colors:active){.cBjhIZ:focus{outline:solid 1px transparent;}}/*!sc*/\n.cBjhIZ [data-component=ButtonCounter]{font-size:12px;background-color:var(--buttonCounter-default-bgColor-rest,var(--color-btn-counter-bg,#30363d));}/*!sc*/\n.cBjhIZ[data-component=IconButton]{display:inline-grid;padding:unset;place-content:center;width:32px;min-width:unset;}/*!sc*/\n.cBjhIZ[data-size=\"small\"]{padding:0 8px;height:28px;gap:4px;font-size:12px;}/*!sc*/\n.cBjhIZ[data-size=\"small\"] [data-component=\"text\"]{line-height:calc(20 / 12);}/*!sc*/\n.cBjhIZ[data-size=\"small\"] [data-component=ButtonCounter]{font-size:12px;}/*!sc*/\n.cBjhIZ[data-size=\"small\"] [data-component=\"buttonContent\"] > :not(:last-child){margin-right:4px;}/*!sc*/\n.cBjhIZ[data-size=\"small\"][data-component=IconButton]{width:28px;padding:unset;}/*!sc*/\n.cBjhIZ[data-size=\"large\"]{padding:0 16px;height:40px;gap:8px;}/*!sc*/\n.cBjhIZ[data-size=\"large\"] [data-component=\"buttonContent\"] > :not(:last-child){margin-right:8px;}/*!sc*/\n.cBjhIZ[data-size=\"large\"][data-component=IconButton]{width:40px;padding:unset;}/*!sc*/\n.cBjhIZ[data-block=\"block\"]{width:100%;}/*!sc*/\n.cBjhIZ[data-inactive]:not([disabled]){background-color:var(--button-inactive-bgColor,var(--button-inactive-bgColor-rest,var(--color-btn-inactive-bg,#21262d)));border-color:var(--button-inactive-bgColor,var(--button-inactive-bgColor-rest,var(--color-btn-inactive-bg,#21262d)));color:var(--button-inactive-fgColor,var(--button-inactive-fgColor-rest,var(--color-btn-inactive-text,#8b949e)));}/*!sc*/\n.cBjhIZ[data-inactive]:not([disabled]):focus-visible{box-shadow:none;}/*!sc*/\n.cBjhIZ [data-component=\"leadingVisual\"]{grid-area:leadingVisual;}/*!sc*/\n.cBjhIZ [data-component=\"text\"]{grid-area:text;line-height:calc(20/14);white-space:nowrap;}/*!sc*/\n.cBjhIZ [data-component=\"trailingVisual\"]{grid-area:trailingVisual;}/*!sc*/\n.cBjhIZ [data-component=\"trailingAction\"]{margin-right:-4px;}/*!sc*/\n.cBjhIZ [data-component=\"buttonContent\"]{-webkit-flex:1 0 auto;-ms-flex:1 0 auto;flex:1 0 auto;display:grid;grid-template-areas:\"leadingVisual text trailingVisual\";grid-template-columns:min-content minmax(0,auto) min-content;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-align-content:center;-ms-flex-line-pack:center;align-content:center;}/*!sc*/\n.cBjhIZ [data-component=\"buttonContent\"] > :not(:last-child){margin-right:8px;}/*!sc*/\n.cBjhIZ:hover:not([disabled]):not([data-inactive]){background-color:var(--button-default-bgColor-hover,var(--color-btn-hover-bg,#30363d));border-color:var(--button-default-borderColor-hover,var(--button-default-borderColor-hover,var(--color-btn-hover-border,#8b949e)));}/*!sc*/\n.cBjhIZ:active:not([disabled]):not([data-inactive]){background-color:var(--button-default-bgColor-active,var(--color-btn-active-bg,hsla(212,12%,18%,1)));border-color:var(--button-default-borderColor-active,var(--button-default-borderColor-active,var(--color-btn-active-border,#6e7681)));}/*!sc*/\n.cBjhIZ[aria-expanded=true]{background-color:var(--button-default-bgColor-active,var(--color-btn-active-bg,hsla(212,12%,18%,1)));border-color:var(--button-default-borderColor-active,var(--button-default-borderColor-active,var(--color-btn-active-border,#6e7681)));}/*!sc*/\n.cBjhIZ [data-component=\"leadingVisual\"],.cBjhIZ [data-component=\"trailingVisual\"],.cBjhIZ [data-component=\"trailingAction\"]{color:var(--button-color,var(--fgColor-muted,var(--color-fg-muted,#848d97)));}/*!sc*/\n.cBjhIZ[data-component=\"IconButton\"][data-no-visuals]{color:var(--fgColor-muted,var(--color-fg-muted,#848d97));}/*!sc*/\n.cBjhIZ[data-no-visuals]{color:var(--fgColor-muted,var(--color-fg-subtle,#6e7681));font-size:14px;font-weight:400;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;border-top-left-radius:0;border-bottom-left-radius:0;}/*!sc*/\n.IIGly{border-radius:6px;border:1px solid;border-color:transparent;font-family:inherit;font-weight:500;font-size:14px;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-text-decoration:none;text-decoration:none;text-align:center;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;height:32px;padding:0 12px;gap:8px;min-width:-webkit-max-content;min-width:-moz-max-content;min-width:max-content;-webkit-transition:80ms cubic-bezier(0.65,0,0.35,1);transition:80ms cubic-bezier(0.65,0,0.35,1);-webkit-transition-property:color,fill,background-color,border-color;transition-property:color,fill,background-color,border-color;color:var(--button-default-fgColor-rest,var(--color-btn-text,#c9d1d9));background-color:transparent;box-shadow:none;}/*!sc*/\n.IIGly:focus:not(:disabled){box-shadow:none;outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#2f81f7));outline-offset:-2px;}/*!sc*/\n.IIGly:focus:not(:disabled):not(:focus-visible){outline:solid 1px transparent;}/*!sc*/\n.IIGly:focus-visible:not(:disabled){box-shadow:none;outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#2f81f7));outline-offset:-2px;}/*!sc*/\n.IIGly[href]{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;}/*!sc*/\n.IIGly[href]:hover{-webkit-text-decoration:none;text-decoration:none;}/*!sc*/\n.IIGly:hover{-webkit-transition-duration:80ms;transition-duration:80ms;}/*!sc*/\n.IIGly:active{-webkit-transition:none;transition:none;}/*!sc*/\n.IIGly[data-inactive]{cursor:auto;}/*!sc*/\n.IIGly:disabled{cursor:not-allowed;box-shadow:none;color:var(--fgColor-disabled,var(--color-primer-fg-disabled,#484f58));}/*!sc*/\n.IIGly:disabled [data-component=ButtonCounter],.IIGly:disabled [data-component=\"leadingVisual\"],.IIGly:disabled [data-component=\"trailingAction\"]{color:inherit;}/*!sc*/\n@media (forced-colors:active){.IIGly:focus{outline:solid 1px transparent;}}/*!sc*/\n.IIGly [data-component=ButtonCounter]{font-size:12px;}/*!sc*/\n.IIGly[data-component=IconButton]{display:inline-grid;padding:unset;place-content:center;width:32px;min-width:unset;}/*!sc*/\n.IIGly[data-size=\"small\"]{padding:0 8px;height:28px;gap:4px;font-size:12px;}/*!sc*/\n.IIGly[data-size=\"small\"] [data-component=\"text\"]{line-height:calc(20 / 12);}/*!sc*/\n.IIGly[data-size=\"small\"] [data-component=ButtonCounter]{font-size:12px;}/*!sc*/\n.IIGly[data-size=\"small\"] [data-component=\"buttonContent\"] > :not(:last-child){margin-right:4px;}/*!sc*/\n.IIGly[data-size=\"small\"][data-component=IconButton]{width:28px;padding:unset;}/*!sc*/\n.IIGly[data-size=\"large\"]{padding:0 16px;height:40px;gap:8px;}/*!sc*/\n.IIGly[data-size=\"large\"] [data-component=\"buttonContent\"] > :not(:last-child){margin-right:8px;}/*!sc*/\n.IIGly[data-size=\"large\"][data-component=IconButton]{width:40px;padding:unset;}/*!sc*/\n.IIGly[data-block=\"block\"]{width:100%;}/*!sc*/\n.IIGly[data-inactive]:not([disabled]){background-color:var(--button-inactive-bgColor,var(--button-inactive-bgColor-rest,var(--color-btn-inactive-bg,#21262d)));border-color:var(--button-inactive-bgColor,var(--button-inactive-bgColor-rest,var(--color-btn-inactive-bg,#21262d)));color:var(--button-inactive-fgColor,var(--button-inactive-fgColor-rest,var(--color-btn-inactive-text,#8b949e)));}/*!sc*/\n.IIGly[data-inactive]:not([disabled]):focus-visible{box-shadow:none;}/*!sc*/\n.IIGly [data-component=\"leadingVisual\"]{grid-area:leadingVisual;color:var(--fgColor-muted,var(--color-fg-muted,#848d97));}/*!sc*/\n.IIGly [data-component=\"text\"]{grid-area:text;line-height:calc(20/14);white-space:nowrap;}/*!sc*/\n.IIGly [data-component=\"trailingVisual\"]{grid-area:trailingVisual;}/*!sc*/\n.IIGly [data-component=\"trailingAction\"]{margin-right:-4px;color:var(--fgColor-muted,var(--color-fg-muted,#848d97));}/*!sc*/\n.IIGly [data-component=\"buttonContent\"]{-webkit-flex:1 0 auto;-ms-flex:1 0 auto;flex:1 0 auto;display:grid;grid-template-areas:\"leadingVisual text trailingVisual\";grid-template-columns:min-content minmax(0,auto) min-content;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-align-content:center;-ms-flex-line-pack:center;align-content:center;}/*!sc*/\n.IIGly [data-component=\"buttonContent\"] > :not(:last-child){margin-right:8px;}/*!sc*/\n.IIGly:hover:not([disabled]){background-color:var(--control-transparent-bgColor-hover,var(--color-action-list-item-default-hover-bg,rgba(177,186,196,0.12)));}/*!sc*/\n.IIGly:active:not([disabled]){background-color:var(--control-transparent-bgColor-active,var(--color-action-list-item-default-active-bg,rgba(177,186,196,0.2)));}/*!sc*/\n.IIGly[aria-expanded=true]{background-color:var(--control-transparent-bgColor-selected,var(--color-action-list-item-default-selected-bg,rgba(177,186,196,0.08)));}/*!sc*/\n.IIGly[data-component=\"IconButton\"][data-no-visuals]{color:var(--fgColor-muted,var(--color-fg-muted,#848d97));}/*!sc*/\n.IIGly[data-no-visuals]{color:var(--fgColor-accent,var(--color-accent-fg,#2f81f7));}/*!sc*/\n.IIGly:has([data-component=\"ButtonCounter\"]){color:var(--button-default-fgColor-rest,var(--color-btn-text,#c9d1d9));}/*!sc*/\n.IIGly:disabled[data-no-visuals]{color:var(--fgColor-disabled,var(--color-primer-fg-disabled,#484f58));}/*!sc*/\n.IIGly:disabled[data-no-visuals] [data-component=ButtonCounter]{color:inherit;}/*!sc*/\n.IIGly[data-size=\"small\"][data-no-visuals]{margin-left:8px;}/*!sc*/\n.fXsbsD{border-radius:6px;border:1px solid;border-color:var(--button-default-borderColor-rest,var(--button-default-borderColor-rest,var(--color-btn-border,rgba(240,246,252,0.1))));font-family:inherit;font-weight:500;font-size:14px;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-text-decoration:none;text-decoration:none;text-align:center;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;height:32px;padding:0 12px;gap:8px;min-width:-webkit-max-content;min-width:-moz-max-content;min-width:max-content;-webkit-transition:80ms cubic-bezier(0.65,0,0.35,1);transition:80ms cubic-bezier(0.65,0,0.35,1);-webkit-transition-property:color,fill,background-color,border-color;transition-property:color,fill,background-color,border-color;color:var(--button-default-fgColor-rest,var(--color-btn-text,#c9d1d9));background-color:var(--button-default-bgColor-rest,var(--color-btn-bg,#21262d));box-shadow:var(--button-default-shadow-resting,var(--color-btn-shadow,0 0 transparent)),var(--button-default-shadow-inset,var(--color-btn-inset-shadow,0 0 transparent));}/*!sc*/\n.fXsbsD:focus:not(:disabled){box-shadow:none;outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#2f81f7));outline-offset:-2px;}/*!sc*/\n.fXsbsD:focus:not(:disabled):not(:focus-visible){outline:solid 1px transparent;}/*!sc*/\n.fXsbsD:focus-visible:not(:disabled){box-shadow:none;outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#2f81f7));outline-offset:-2px;}/*!sc*/\n.fXsbsD[href]{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;}/*!sc*/\n.fXsbsD[href]:hover{-webkit-text-decoration:none;text-decoration:none;}/*!sc*/\n.fXsbsD:hover{-webkit-transition-duration:80ms;transition-duration:80ms;}/*!sc*/\n.fXsbsD:active{-webkit-transition:none;transition:none;}/*!sc*/\n.fXsbsD[data-inactive]{cursor:auto;}/*!sc*/\n.fXsbsD:disabled{cursor:not-allowed;box-shadow:none;color:var(--fgColor-disabled,var(--color-primer-fg-disabled,#484f58));border-color:var(--button-default-borderColor-disabled,var(--button-default-borderColor-rest,var(--color-btn-border,rgba(240,246,252,0.1))));background-color:var(--button-default-bgColor-disabled,var(--control-bgColor-disabled,var(--color-input-disabled-bg,rgba(110,118,129,0))));}/*!sc*/\n.fXsbsD:disabled [data-component=ButtonCounter]{color:inherit;}/*!sc*/\n@media (forced-colors:active){.fXsbsD:focus{outline:solid 1px transparent;}}/*!sc*/\n.fXsbsD [data-component=ButtonCounter]{font-size:12px;background-color:var(--buttonCounter-default-bgColor-rest,var(--color-btn-counter-bg,#30363d));}/*!sc*/\n.fXsbsD[data-component=IconButton]{display:inline-grid;padding:unset;place-content:center;width:32px;min-width:unset;}/*!sc*/\n.fXsbsD[data-size=\"small\"]{padding:0 8px;height:28px;gap:4px;font-size:12px;}/*!sc*/\n.fXsbsD[data-size=\"small\"] [data-component=\"text\"]{line-height:calc(20 / 12);}/*!sc*/\n.fXsbsD[data-size=\"small\"] [data-component=ButtonCounter]{font-size:12px;}/*!sc*/\n.fXsbsD[data-size=\"small\"] [data-component=\"buttonContent\"] > :not(:last-child){margin-right:4px;}/*!sc*/\n.fXsbsD[data-size=\"small\"][data-component=IconButton]{width:28px;padding:unset;}/*!sc*/\n.fXsbsD[data-size=\"large\"]{padding:0 16px;height:40px;gap:8px;}/*!sc*/\n.fXsbsD[data-size=\"large\"] [data-component=\"buttonContent\"] > :not(:last-child){margin-right:8px;}/*!sc*/\n.fXsbsD[data-size=\"large\"][data-component=IconButton]{width:40px;padding:unset;}/*!sc*/\n.fXsbsD[data-block=\"block\"]{width:100%;}/*!sc*/\n.fXsbsD[data-inactive]:not([disabled]){background-color:var(--button-inactive-bgColor,var(--button-inactive-bgColor-rest,var(--color-btn-inactive-bg,#21262d)));border-color:var(--button-inactive-bgColor,var(--button-inactive-bgColor-rest,var(--color-btn-inactive-bg,#21262d)));color:var(--button-inactive-fgColor,var(--button-inactive-fgColor-rest,var(--color-btn-inactive-text,#8b949e)));}/*!sc*/\n.fXsbsD[data-inactive]:not([disabled]):focus-visible{box-shadow:none;}/*!sc*/\n.fXsbsD [data-component=\"leadingVisual\"]{grid-area:leadingVisual;}/*!sc*/\n.fXsbsD [data-component=\"text\"]{grid-area:text;line-height:calc(20/14);white-space:nowrap;}/*!sc*/\n.fXsbsD [data-component=\"trailingVisual\"]{grid-area:trailingVisual;}/*!sc*/\n.fXsbsD [data-component=\"trailingAction\"]{margin-right:-4px;}/*!sc*/\n.fXsbsD [data-component=\"buttonContent\"]{-webkit-flex:1 0 auto;-ms-flex:1 0 auto;flex:1 0 auto;display:grid;grid-template-areas:\"leadingVisual text trailingVisual\";grid-template-columns:min-content minmax(0,auto) min-content;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-align-content:center;-ms-flex-line-pack:center;align-content:center;}/*!sc*/\n.fXsbsD [data-component=\"buttonContent\"] > :not(:last-child){margin-right:8px;}/*!sc*/\n.fXsbsD:hover:not([disabled]):not([data-inactive]){background-color:var(--button-default-bgColor-hover,var(--color-btn-hover-bg,#30363d));border-color:var(--button-default-borderColor-hover,var(--button-default-borderColor-hover,var(--color-btn-hover-border,#8b949e)));}/*!sc*/\n.fXsbsD:active:not([disabled]):not([data-inactive]){background-color:var(--button-default-bgColor-active,var(--color-btn-active-bg,hsla(212,12%,18%,1)));border-color:var(--button-default-borderColor-active,var(--button-default-borderColor-active,var(--color-btn-active-border,#6e7681)));}/*!sc*/\n.fXsbsD[aria-expanded=true]{background-color:var(--button-default-bgColor-active,var(--color-btn-active-bg,hsla(212,12%,18%,1)));border-color:var(--button-default-borderColor-active,var(--button-default-borderColor-active,var(--color-btn-active-border,#6e7681)));}/*!sc*/\n.fXsbsD [data-component=\"leadingVisual\"],.fXsbsD [data-component=\"trailingVisual\"],.fXsbsD [data-component=\"trailingAction\"]{color:var(--button-color,var(--fgColor-muted,var(--color-fg-muted,#848d97)));}/*!sc*/\n.fXsbsD[data-component=\"IconButton\"][data-no-visuals]{color:var(--fgColor-muted,var(--color-fg-muted,#848d97));}/*!sc*/\n.fXsbsD[data-no-visuals]{border-top-left-radius:0;border-bottom-left-radius:0;display:none;}/*!sc*/\n.hiXxwe{border-radius:6px;border:1px solid;border-color:var(--button-default-borderColor-rest,var(--button-default-borderColor-rest,var(--color-btn-border,rgba(240,246,252,0.1))));font-family:inherit;font-weight:500;font-size:14px;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-text-decoration:none;text-decoration:none;text-align:center;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;height:32px;padding:0 12px;gap:8px;min-width:-webkit-max-content;min-width:-moz-max-content;min-width:max-content;-webkit-transition:80ms cubic-bezier(0.65,0,0.35,1);transition:80ms cubic-bezier(0.65,0,0.35,1);-webkit-transition-property:color,fill,background-color,border-color;transition-property:color,fill,background-color,border-color;color:var(--button-default-fgColor-rest,var(--color-btn-text,#c9d1d9));background-color:var(--button-default-bgColor-rest,var(--color-btn-bg,#21262d));box-shadow:var(--button-default-shadow-resting,var(--color-btn-shadow,0 0 transparent)),var(--button-default-shadow-inset,var(--color-btn-inset-shadow,0 0 transparent));}/*!sc*/\n.hiXxwe:focus:not(:disabled){box-shadow:none;outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#2f81f7));outline-offset:-2px;}/*!sc*/\n.hiXxwe:focus:not(:disabled):not(:focus-visible){outline:solid 1px transparent;}/*!sc*/\n.hiXxwe:focus-visible:not(:disabled){box-shadow:none;outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#2f81f7));outline-offset:-2px;}/*!sc*/\n.hiXxwe[href]{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;}/*!sc*/\n.hiXxwe[href]:hover{-webkit-text-decoration:none;text-decoration:none;}/*!sc*/\n.hiXxwe:hover{-webkit-transition-duration:80ms;transition-duration:80ms;}/*!sc*/\n.hiXxwe:active{-webkit-transition:none;transition:none;}/*!sc*/\n.hiXxwe[data-inactive]{cursor:auto;}/*!sc*/\n.hiXxwe:disabled{cursor:not-allowed;box-shadow:none;color:var(--fgColor-disabled,var(--color-primer-fg-disabled,#484f58));border-color:var(--button-default-borderColor-disabled,var(--button-default-borderColor-rest,var(--color-btn-border,rgba(240,246,252,0.1))));background-color:var(--button-default-bgColor-disabled,var(--control-bgColor-disabled,var(--color-input-disabled-bg,rgba(110,118,129,0))));}/*!sc*/\n.hiXxwe:disabled [data-component=ButtonCounter]{color:inherit;}/*!sc*/\n@media (forced-colors:active){.hiXxwe:focus{outline:solid 1px transparent;}}/*!sc*/\n.hiXxwe [data-component=ButtonCounter]{font-size:12px;background-color:var(--buttonCounter-default-bgColor-rest,var(--color-btn-counter-bg,#30363d));}/*!sc*/\n.hiXxwe[data-component=IconButton]{display:inline-grid;padding:unset;place-content:center;width:32px;min-width:unset;}/*!sc*/\n.hiXxwe[data-size=\"small\"]{padding:0 8px;height:28px;gap:4px;font-size:12px;}/*!sc*/\n.hiXxwe[data-size=\"small\"] [data-component=\"text\"]{line-height:calc(20 / 12);}/*!sc*/\n.hiXxwe[data-size=\"small\"] [data-component=ButtonCounter]{font-size:12px;}/*!sc*/\n.hiXxwe[data-size=\"small\"] [data-component=\"buttonContent\"] > :not(:last-child){margin-right:4px;}/*!sc*/\n.hiXxwe[data-size=\"small\"][data-component=IconButton]{width:28px;padding:unset;}/*!sc*/\n.hiXxwe[data-size=\"large\"]{padding:0 16px;height:40px;gap:8px;}/*!sc*/\n.hiXxwe[data-size=\"large\"] [data-component=\"buttonContent\"] > :not(:last-child){margin-right:8px;}/*!sc*/\n.hiXxwe[data-size=\"large\"][data-component=IconButton]{width:40px;padding:unset;}/*!sc*/\n.hiXxwe[data-block=\"block\"]{width:100%;}/*!sc*/\n.hiXxwe[data-inactive]:not([disabled]){background-color:var(--button-inactive-bgColor,var(--button-inactive-bgColor-rest,var(--color-btn-inactive-bg,#21262d)));border-color:var(--button-inactive-bgColor,var(--button-inactive-bgColor-rest,var(--color-btn-inactive-bg,#21262d)));color:var(--button-inactive-fgColor,var(--button-inactive-fgColor-rest,var(--color-btn-inactive-text,#8b949e)));}/*!sc*/\n.hiXxwe[data-inactive]:not([disabled]):focus-visible{box-shadow:none;}/*!sc*/\n.hiXxwe [data-component=\"leadingVisual\"]{grid-area:leadingVisual;}/*!sc*/\n.hiXxwe [data-component=\"text\"]{grid-area:text;line-height:calc(20/14);white-space:nowrap;}/*!sc*/\n.hiXxwe [data-component=\"trailingVisual\"]{grid-area:trailingVisual;}/*!sc*/\n.hiXxwe [data-component=\"trailingAction\"]{margin-right:-4px;}/*!sc*/\n.hiXxwe [data-component=\"buttonContent\"]{-webkit-flex:1 0 auto;-ms-flex:1 0 auto;flex:1 0 auto;display:grid;grid-template-areas:\"leadingVisual text trailingVisual\";grid-template-columns:min-content minmax(0,auto) min-content;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-align-content:center;-ms-flex-line-pack:center;align-content:center;}/*!sc*/\n.hiXxwe [data-component=\"buttonContent\"] > :not(:last-child){margin-right:8px;}/*!sc*/\n.hiXxwe:hover:not([disabled]):not([data-inactive]){background-color:var(--button-default-bgColor-hover,var(--color-btn-hover-bg,#30363d));border-color:var(--button-default-borderColor-hover,var(--button-default-borderColor-hover,var(--color-btn-hover-border,#8b949e)));}/*!sc*/\n.hiXxwe:active:not([disabled]):not([data-inactive]){background-color:var(--button-default-bgColor-active,var(--color-btn-active-bg,hsla(212,12%,18%,1)));border-color:var(--button-default-borderColor-active,var(--button-default-borderColor-active,var(--color-btn-active-border,#6e7681)));}/*!sc*/\n.hiXxwe[aria-expanded=true]{background-color:var(--button-default-bgColor-active,var(--color-btn-active-bg,hsla(212,12%,18%,1)));border-color:var(--button-default-borderColor-active,var(--button-default-borderColor-active,var(--color-btn-active-border,#6e7681)));}/*!sc*/\n.hiXxwe [data-component=\"leadingVisual\"],.hiXxwe [data-component=\"trailingVisual\"],.hiXxwe [data-component=\"trailingAction\"]{color:var(--button-color,var(--fgColor-muted,var(--color-fg-muted,#848d97)));}/*!sc*/\n.hiXxwe[data-component=\"IconButton\"][data-no-visuals]{color:var(--fgColor-muted,var(--color-fg-muted,#848d97));}/*!sc*/\n.hiXxwe[data-no-visuals]{color:var(--fgColor-muted,var(--color-fg-muted,#848d97));}/*!sc*/\n.saA-Dg{border-radius:6px;border:1px solid;border-color:transparent;font-family:inherit;font-weight:500;font-size:14px;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-text-decoration:none;text-decoration:none;text-align:center;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;height:32px;padding:0 12px;gap:8px;min-width:-webkit-max-content;min-width:-moz-max-content;min-width:max-content;-webkit-transition:80ms cubic-bezier(0.65,0,0.35,1);transition:80ms cubic-bezier(0.65,0,0.35,1);-webkit-transition-property:color,fill,background-color,border-color;transition-property:color,fill,background-color,border-color;color:var(--fgColor-default,var(--color-fg-default,#e6edf3));background-color:transparent;box-shadow:none;}/*!sc*/\n.saA-Dg:focus:not(:disabled){box-shadow:none;outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#2f81f7));outline-offset:-2px;}/*!sc*/\n.saA-Dg:focus:not(:disabled):not(:focus-visible){outline:solid 1px transparent;}/*!sc*/\n.saA-Dg:focus-visible:not(:disabled){box-shadow:none;outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#2f81f7));outline-offset:-2px;}/*!sc*/\n.saA-Dg[href]{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;}/*!sc*/\n.saA-Dg[href]:hover{-webkit-text-decoration:none;text-decoration:none;}/*!sc*/\n.saA-Dg:hover{-webkit-transition-duration:80ms;transition-duration:80ms;}/*!sc*/\n.saA-Dg:active{-webkit-transition:none;transition:none;}/*!sc*/\n.saA-Dg[data-inactive]{cursor:auto;}/*!sc*/\n.saA-Dg:disabled{cursor:not-allowed;box-shadow:none;color:var(--fgColor-disabled,var(--color-primer-fg-disabled,#484f58));}/*!sc*/\n.saA-Dg:disabled [data-component=ButtonCounter],.saA-Dg:disabled [data-component=\"leadingVisual\"],.saA-Dg:disabled [data-component=\"trailingAction\"]{color:inherit;}/*!sc*/\n@media (forced-colors:active){.saA-Dg:focus{outline:solid 1px transparent;}}/*!sc*/\n.saA-Dg [data-component=ButtonCounter]{font-size:12px;}/*!sc*/\n.saA-Dg[data-component=IconButton]{display:inline-grid;padding:unset;place-content:center;width:32px;min-width:unset;}/*!sc*/\n.saA-Dg[data-size=\"small\"]{padding:0 8px;height:28px;gap:4px;font-size:12px;}/*!sc*/\n.saA-Dg[data-size=\"small\"] [data-component=\"text\"]{line-height:calc(20 / 12);}/*!sc*/\n.saA-Dg[data-size=\"small\"] [data-component=ButtonCounter]{font-size:12px;}/*!sc*/\n.saA-Dg[data-size=\"small\"] [data-component=\"buttonContent\"] > :not(:last-child){margin-right:4px;}/*!sc*/\n.saA-Dg[data-size=\"small\"][data-component=IconButton]{width:28px;padding:unset;}/*!sc*/\n.saA-Dg[data-size=\"large\"]{padding:0 16px;height:40px;gap:8px;}/*!sc*/\n.saA-Dg[data-size=\"large\"] [data-component=\"buttonContent\"] > :not(:last-child){margin-right:8px;}/*!sc*/\n.saA-Dg[data-size=\"large\"][data-component=IconButton]{width:40px;padding:unset;}/*!sc*/\n.saA-Dg[data-block=\"block\"]{width:100%;}/*!sc*/\n.saA-Dg[data-inactive]:not([disabled]){background-color:var(--button-inactive-bgColor,var(--button-inactive-bgColor-rest,var(--color-btn-inactive-bg,#21262d)));border-color:var(--button-inactive-bgColor,var(--button-inactive-bgColor-rest,var(--color-btn-inactive-bg,#21262d)));color:var(--button-inactive-fgColor,var(--button-inactive-fgColor-rest,var(--color-btn-inactive-text,#8b949e)));}/*!sc*/\n.saA-Dg[data-inactive]:not([disabled]):focus-visible{box-shadow:none;}/*!sc*/\n.saA-Dg [data-component=\"leadingVisual\"]{grid-area:leadingVisual;color:var(--fgColor-muted,var(--color-fg-muted,#848d97));}/*!sc*/\n.saA-Dg [data-component=\"text\"]{grid-area:text;line-height:calc(20/14);white-space:nowrap;}/*!sc*/\n.saA-Dg [data-component=\"trailingVisual\"]{grid-area:trailingVisual;}/*!sc*/\n.saA-Dg [data-component=\"trailingAction\"]{margin-right:-4px;color:var(--fgColor-muted,var(--color-fg-muted,#848d97));}/*!sc*/\n.saA-Dg [data-component=\"buttonContent\"]{-webkit-flex:1 0 auto;-ms-flex:1 0 auto;flex:1 0 auto;display:grid;grid-template-areas:\"leadingVisual text trailingVisual\";grid-template-columns:min-content minmax(0,auto) min-content;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-align-content:center;-ms-flex-line-pack:center;align-content:center;}/*!sc*/\n.saA-Dg [data-component=\"buttonContent\"] > :not(:last-child){margin-right:8px;}/*!sc*/\n.saA-Dg:hover:not([disabled]){background-color:var(--control-transparent-bgColor-hover,var(--color-action-list-item-default-hover-bg,rgba(177,186,196,0.12)));-webkit-text-decoration:none;text-decoration:none;}/*!sc*/\n.saA-Dg:active:not([disabled]){background-color:var(--control-transparent-bgColor-active,var(--color-action-list-item-default-active-bg,rgba(177,186,196,0.2)));-webkit-text-decoration:none;text-decoration:none;}/*!sc*/\n.saA-Dg[aria-expanded=true]{background-color:var(--control-transparent-bgColor-selected,var(--color-action-list-item-default-selected-bg,rgba(177,186,196,0.08)));}/*!sc*/\n.saA-Dg[data-component=\"IconButton\"][data-no-visuals]{color:var(--fgColor-muted,var(--color-fg-muted,#848d97));}/*!sc*/\n.saA-Dg[data-no-visuals]{color:var(--fgColor-accent,var(--color-accent-fg,#2f81f7));}/*!sc*/\n.saA-Dg:has([data-component=\"ButtonCounter\"]){color:var(--button-default-fgColor-rest,var(--color-btn-text,#c9d1d9));}/*!sc*/\n.saA-Dg:disabled[data-no-visuals]{color:var(--fgColor-disabled,var(--color-primer-fg-disabled,#484f58));}/*!sc*/\n.saA-Dg:disabled[data-no-visuals] [data-component=ButtonCounter]{color:inherit;}/*!sc*/\n.saA-Dg:focus:not([disabled]){-webkit-text-decoration:none;text-decoration:none;}/*!sc*/\n.ecGgfP{border-radius:6px;border:1px solid;border-color:transparent;font-family:inherit;font-weight:500;font-size:14px;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-text-decoration:none;text-decoration:none;text-align:center;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;height:32px;padding:0 12px;gap:8px;min-width:-webkit-max-content;min-width:-moz-max-content;min-width:max-content;-webkit-transition:80ms cubic-bezier(0.65,0,0.35,1);transition:80ms cubic-bezier(0.65,0,0.35,1);-webkit-transition-property:color,fill,background-color,border-color;transition-property:color,fill,background-color,border-color;color:var(--button-default-fgColor-rest,var(--color-btn-text,#c9d1d9));background-color:transparent;box-shadow:none;}/*!sc*/\n.ecGgfP:focus:not(:disabled){box-shadow:none;outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#2f81f7));outline-offset:-2px;}/*!sc*/\n.ecGgfP:focus:not(:disabled):not(:focus-visible){outline:solid 1px transparent;}/*!sc*/\n.ecGgfP:focus-visible:not(:disabled){box-shadow:none;outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#2f81f7));outline-offset:-2px;}/*!sc*/\n.ecGgfP[href]{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;}/*!sc*/\n.ecGgfP[href]:hover{-webkit-text-decoration:none;text-decoration:none;}/*!sc*/\n.ecGgfP:hover{-webkit-transition-duration:80ms;transition-duration:80ms;}/*!sc*/\n.ecGgfP:active{-webkit-transition:none;transition:none;}/*!sc*/\n.ecGgfP[data-inactive]{cursor:auto;}/*!sc*/\n.ecGgfP:disabled{cursor:not-allowed;box-shadow:none;color:var(--fgColor-disabled,var(--color-primer-fg-disabled,#484f58));}/*!sc*/\n.ecGgfP:disabled [data-component=ButtonCounter],.ecGgfP:disabled [data-component=\"leadingVisual\"],.ecGgfP:disabled [data-component=\"trailingAction\"]{color:inherit;}/*!sc*/\n@media (forced-colors:active){.ecGgfP:focus{outline:solid 1px transparent;}}/*!sc*/\n.ecGgfP [data-component=ButtonCounter]{font-size:12px;}/*!sc*/\n.ecGgfP[data-component=IconButton]{display:inline-grid;padding:unset;place-content:center;width:32px;min-width:unset;}/*!sc*/\n.ecGgfP[data-size=\"small\"]{padding:0 8px;height:28px;gap:4px;font-size:12px;color:var(--fgColor-default,var(--color-fg-default,#e6edf3));margin-left:8px;}/*!sc*/\n.ecGgfP[data-size=\"small\"] [data-component=\"text\"]{line-height:calc(20 / 12);}/*!sc*/\n.ecGgfP[data-size=\"small\"] [data-component=ButtonCounter]{font-size:12px;}/*!sc*/\n.ecGgfP[data-size=\"small\"] [data-component=\"buttonContent\"] > :not(:last-child){margin-right:4px;}/*!sc*/\n.ecGgfP[data-size=\"small\"][data-component=IconButton]{width:28px;padding:unset;}/*!sc*/\n.ecGgfP[data-size=\"large\"]{padding:0 16px;height:40px;gap:8px;}/*!sc*/\n.ecGgfP[data-size=\"large\"] [data-component=\"buttonContent\"] > :not(:last-child){margin-right:8px;}/*!sc*/\n.ecGgfP[data-size=\"large\"][data-component=IconButton]{width:40px;padding:unset;}/*!sc*/\n.ecGgfP[data-block=\"block\"]{width:100%;}/*!sc*/\n.ecGgfP[data-inactive]:not([disabled]){background-color:var(--button-inactive-bgColor,var(--button-inactive-bgColor-rest,var(--color-btn-inactive-bg,#21262d)));border-color:var(--button-inactive-bgColor,var(--button-inactive-bgColor-rest,var(--color-btn-inactive-bg,#21262d)));color:var(--button-inactive-fgColor,var(--button-inactive-fgColor-rest,var(--color-btn-inactive-text,#8b949e)));}/*!sc*/\n.ecGgfP[data-inactive]:not([disabled]):focus-visible{box-shadow:none;}/*!sc*/\n.ecGgfP [data-component=\"leadingVisual\"]{grid-area:leadingVisual;color:var(--fgColor-muted,var(--color-fg-muted,#848d97));}/*!sc*/\n.ecGgfP [data-component=\"text\"]{grid-area:text;line-height:calc(20/14);white-space:nowrap;}/*!sc*/\n.ecGgfP [data-component=\"trailingVisual\"]{grid-area:trailingVisual;}/*!sc*/\n.ecGgfP [data-component=\"trailingAction\"]{margin-right:-4px;color:var(--fgColor-muted,var(--color-fg-muted,#848d97));}/*!sc*/\n.ecGgfP [data-component=\"buttonContent\"]{-webkit-flex:1 0 auto;-ms-flex:1 0 auto;flex:1 0 auto;display:grid;grid-template-areas:\"leadingVisual text trailingVisual\";grid-template-columns:min-content minmax(0,auto) min-content;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-align-content:center;-ms-flex-line-pack:center;align-content:center;}/*!sc*/\n.ecGgfP [data-component=\"buttonContent\"] > :not(:last-child){margin-right:8px;}/*!sc*/\n.ecGgfP:hover:not([disabled]){background-color:var(--control-transparent-bgColor-hover,var(--color-action-list-item-default-hover-bg,rgba(177,186,196,0.12)));}/*!sc*/\n.ecGgfP:active:not([disabled]){background-color:var(--control-transparent-bgColor-active,var(--color-action-list-item-default-active-bg,rgba(177,186,196,0.2)));}/*!sc*/\n.ecGgfP[aria-expanded=true]{background-color:var(--control-transparent-bgColor-selected,var(--color-action-list-item-default-selected-bg,rgba(177,186,196,0.08)));}/*!sc*/\n.ecGgfP[data-component=\"IconButton\"][data-no-visuals]{color:var(--fgColor-muted,var(--color-fg-muted,#848d97));}/*!sc*/\n.ecGgfP[data-no-visuals]{color:var(--fgColor-accent,var(--color-accent-fg,#2f81f7));}/*!sc*/\n.ecGgfP:has([data-component=\"ButtonCounter\"]){color:var(--button-default-fgColor-rest,var(--color-btn-text,#c9d1d9));}/*!sc*/\n.ecGgfP:disabled[data-no-visuals]{color:var(--fgColor-disabled,var(--color-primer-fg-disabled,#484f58));}/*!sc*/\n.ecGgfP:disabled[data-no-visuals] [data-component=ButtonCounter]{color:inherit;}/*!sc*/\n.dupbIv{border-radius:6px;border:1px solid;border-color:var(--button-default-borderColor-rest,var(--button-default-borderColor-rest,var(--color-btn-border,rgba(240,246,252,0.1))));font-family:inherit;font-weight:500;font-size:14px;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-text-decoration:none;text-decoration:none;text-align:center;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;height:32px;padding:0 12px;gap:8px;min-width:-webkit-max-content;min-width:-moz-max-content;min-width:max-content;-webkit-transition:80ms cubic-bezier(0.65,0,0.35,1);transition:80ms cubic-bezier(0.65,0,0.35,1);-webkit-transition-property:color,fill,background-color,border-color;transition-property:color,fill,background-color,border-color;color:var(--button-default-fgColor-rest,var(--color-btn-text,#c9d1d9));background-color:var(--button-default-bgColor-rest,var(--color-btn-bg,#21262d));box-shadow:var(--button-default-shadow-resting,var(--color-btn-shadow,0 0 transparent)),var(--button-default-shadow-inset,var(--color-btn-inset-shadow,0 0 transparent));padding-left:8px;padding-right:8px;}/*!sc*/\n.dupbIv:focus:not(:disabled){box-shadow:none;outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#2f81f7));outline-offset:-2px;}/*!sc*/\n.dupbIv:focus:not(:disabled):not(:focus-visible){outline:solid 1px transparent;}/*!sc*/\n.dupbIv:focus-visible:not(:disabled){box-shadow:none;outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#2f81f7));outline-offset:-2px;}/*!sc*/\n.dupbIv[href]{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;}/*!sc*/\n.dupbIv[href]:hover{-webkit-text-decoration:none;text-decoration:none;}/*!sc*/\n.dupbIv:hover{-webkit-transition-duration:80ms;transition-duration:80ms;}/*!sc*/\n.dupbIv:active{-webkit-transition:none;transition:none;}/*!sc*/\n.dupbIv[data-inactive]{cursor:auto;}/*!sc*/\n.dupbIv:disabled{cursor:not-allowed;box-shadow:none;color:var(--fgColor-disabled,var(--color-primer-fg-disabled,#484f58));border-color:var(--button-default-borderColor-disabled,var(--button-default-borderColor-rest,var(--color-btn-border,rgba(240,246,252,0.1))));background-color:var(--button-default-bgColor-disabled,var(--control-bgColor-disabled,var(--color-input-disabled-bg,rgba(110,118,129,0))));}/*!sc*/\n.dupbIv:disabled [data-component=ButtonCounter]{color:inherit;}/*!sc*/\n@media (forced-colors:active){.dupbIv:focus{outline:solid 1px transparent;}}/*!sc*/\n.dupbIv [data-component=ButtonCounter]{font-size:12px;background-color:var(--buttonCounter-default-bgColor-rest,var(--color-btn-counter-bg,#30363d));}/*!sc*/\n.dupbIv[data-component=IconButton]{display:inline-grid;padding:unset;place-content:center;width:32px;min-width:unset;}/*!sc*/\n.dupbIv[data-size=\"small\"]{padding:0 8px;height:28px;gap:4px;font-size:12px;}/*!sc*/\n.dupbIv[data-size=\"small\"] [data-component=\"text\"]{line-height:calc(20 / 12);}/*!sc*/\n.dupbIv[data-size=\"small\"] [data-component=ButtonCounter]{font-size:12px;}/*!sc*/\n.dupbIv[data-size=\"small\"] [data-component=\"buttonContent\"] > :not(:last-child){margin-right:4px;}/*!sc*/\n.dupbIv[data-size=\"small\"][data-component=IconButton]{width:28px;padding:unset;}/*!sc*/\n.dupbIv[data-size=\"large\"]{padding:0 16px;height:40px;gap:8px;}/*!sc*/\n.dupbIv[data-size=\"large\"] [data-component=\"buttonContent\"] > :not(:last-child){margin-right:8px;}/*!sc*/\n.dupbIv[data-size=\"large\"][data-component=IconButton]{width:40px;padding:unset;}/*!sc*/\n.dupbIv[data-block=\"block\"]{width:100%;}/*!sc*/\n.dupbIv[data-inactive]:not([disabled]){background-color:var(--button-inactive-bgColor,var(--button-inactive-bgColor-rest,var(--color-btn-inactive-bg,#21262d)));border-color:var(--button-inactive-bgColor,var(--button-inactive-bgColor-rest,var(--color-btn-inactive-bg,#21262d)));color:var(--button-inactive-fgColor,var(--button-inactive-fgColor-rest,var(--color-btn-inactive-text,#8b949e)));}/*!sc*/\n.dupbIv[data-inactive]:not([disabled]):focus-visible{box-shadow:none;}/*!sc*/\n.dupbIv [data-component=\"leadingVisual\"]{grid-area:leadingVisual;}/*!sc*/\n.dupbIv [data-component=\"text\"]{grid-area:text;line-height:calc(20/14);white-space:nowrap;}/*!sc*/\n.dupbIv [data-component=\"trailingVisual\"]{grid-area:trailingVisual;}/*!sc*/\n.dupbIv [data-component=\"trailingAction\"]{margin-right:-4px;}/*!sc*/\n.dupbIv [data-component=\"buttonContent\"]{-webkit-flex:1 0 auto;-ms-flex:1 0 auto;flex:1 0 auto;display:grid;grid-template-areas:\"leadingVisual text trailingVisual\";grid-template-columns:min-content minmax(0,auto) min-content;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-align-content:center;-ms-flex-line-pack:center;align-content:center;}/*!sc*/\n.dupbIv [data-component=\"buttonContent\"] > :not(:last-child){margin-right:8px;}/*!sc*/\n.dupbIv:hover:not([disabled]):not([data-inactive]){background-color:var(--button-default-bgColor-hover,var(--color-btn-hover-bg,#30363d));border-color:var(--button-default-borderColor-hover,var(--button-default-borderColor-hover,var(--color-btn-hover-border,#8b949e)));}/*!sc*/\n.dupbIv:active:not([disabled]):not([data-inactive]){background-color:var(--button-default-bgColor-active,var(--color-btn-active-bg,hsla(212,12%,18%,1)));border-color:var(--button-default-borderColor-active,var(--button-default-borderColor-active,var(--color-btn-active-border,#6e7681)));}/*!sc*/\n.dupbIv[aria-expanded=true]{background-color:var(--button-default-bgColor-active,var(--color-btn-active-bg,hsla(212,12%,18%,1)));border-color:var(--button-default-borderColor-active,var(--button-default-borderColor-active,var(--color-btn-active-border,#6e7681)));}/*!sc*/\n.dupbIv [data-component=\"leadingVisual\"],.dupbIv [data-component=\"trailingVisual\"],.dupbIv [data-component=\"trailingAction\"]{color:var(--button-color,var(--fgColor-muted,var(--color-fg-muted,#848d97)));}/*!sc*/\n.dupbIv[data-component=\"IconButton\"][data-no-visuals]{color:var(--fgColor-muted,var(--color-fg-muted,#848d97));}/*!sc*/\n.dupbIv linkButtonSx:hover:not([disabled]){-webkit-text-decoration:none;text-decoration:none;}/*!sc*/\n.dupbIv linkButtonSx:focus:not([disabled]){-webkit-text-decoration:none;text-decoration:none;}/*!sc*/\n.dupbIv linkButtonSx:active:not([disabled]){-webkit-text-decoration:none;text-decoration:none;}/*!sc*/\n.dMUxwi{border-radius:6px;border:1px solid;border-color:var(--button-default-borderColor-rest,var(--button-default-borderColor-rest,var(--color-btn-border,rgba(240,246,252,0.1))));font-family:inherit;font-weight:500;font-size:14px;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-text-decoration:none;text-decoration:none;text-align:center;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;height:32px;padding:0 12px;gap:8px;min-width:-webkit-max-content;min-width:-moz-max-content;min-width:max-content;-webkit-transition:80ms cubic-bezier(0.65,0,0.35,1);transition:80ms cubic-bezier(0.65,0,0.35,1);-webkit-transition-property:color,fill,background-color,border-color;transition-property:color,fill,background-color,border-color;color:var(--button-default-fgColor-rest,var(--color-btn-text,#c9d1d9));background-color:var(--button-default-bgColor-rest,var(--color-btn-bg,#21262d));box-shadow:var(--button-default-shadow-resting,var(--color-btn-shadow,0 0 transparent)),var(--button-default-shadow-inset,var(--color-btn-inset-shadow,0 0 transparent));}/*!sc*/\n.dMUxwi:focus:not(:disabled){box-shadow:none;outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#2f81f7));outline-offset:-2px;}/*!sc*/\n.dMUxwi:focus:not(:disabled):not(:focus-visible){outline:solid 1px transparent;}/*!sc*/\n.dMUxwi:focus-visible:not(:disabled){box-shadow:none;outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#2f81f7));outline-offset:-2px;}/*!sc*/\n.dMUxwi[href]{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;}/*!sc*/\n.dMUxwi[href]:hover{-webkit-text-decoration:none;text-decoration:none;}/*!sc*/\n.dMUxwi:hover{-webkit-transition-duration:80ms;transition-duration:80ms;}/*!sc*/\n.dMUxwi:active{-webkit-transition:none;transition:none;}/*!sc*/\n.dMUxwi[data-inactive]{cursor:auto;}/*!sc*/\n.dMUxwi:disabled{cursor:not-allowed;box-shadow:none;color:var(--fgColor-disabled,var(--color-primer-fg-disabled,#484f58));border-color:var(--button-default-borderColor-disabled,var(--button-default-borderColor-rest,var(--color-btn-border,rgba(240,246,252,0.1))));background-color:var(--button-default-bgColor-disabled,var(--control-bgColor-disabled,var(--color-input-disabled-bg,rgba(110,118,129,0))));}/*!sc*/\n.dMUxwi:disabled [data-component=ButtonCounter]{color:inherit;}/*!sc*/\n@media (forced-colors:active){.dMUxwi:focus{outline:solid 1px transparent;}}/*!sc*/\n.dMUxwi [data-component=ButtonCounter]{font-size:12px;background-color:var(--buttonCounter-default-bgColor-rest,var(--color-btn-counter-bg,#30363d));}/*!sc*/\n.dMUxwi[data-component=IconButton]{display:inline-grid;padding:unset;place-content:center;width:32px;min-width:unset;}/*!sc*/\n.dMUxwi[data-size=\"small\"]{padding:0 8px;height:28px;gap:4px;font-size:12px;}/*!sc*/\n.dMUxwi[data-size=\"small\"] [data-component=\"text\"]{line-height:calc(20 / 12);}/*!sc*/\n.dMUxwi[data-size=\"small\"] [data-component=ButtonCounter]{font-size:12px;}/*!sc*/\n.dMUxwi[data-size=\"small\"] [data-component=\"buttonContent\"] > :not(:last-child){margin-right:4px;}/*!sc*/\n.dMUxwi[data-size=\"small\"][data-component=IconButton]{width:28px;padding:unset;}/*!sc*/\n.dMUxwi[data-size=\"large\"]{padding:0 16px;height:40px;gap:8px;}/*!sc*/\n.dMUxwi[data-size=\"large\"] [data-component=\"buttonContent\"] > :not(:last-child){margin-right:8px;}/*!sc*/\n.dMUxwi[data-size=\"large\"][data-component=IconButton]{width:40px;padding:unset;}/*!sc*/\n.dMUxwi[data-block=\"block\"]{width:100%;}/*!sc*/\n.dMUxwi[data-inactive]:not([disabled]){background-color:var(--button-inactive-bgColor,var(--button-inactive-bgColor-rest,var(--color-btn-inactive-bg,#21262d)));border-color:var(--button-inactive-bgColor,var(--button-inactive-bgColor-rest,var(--color-btn-inactive-bg,#21262d)));color:var(--button-inactive-fgColor,var(--button-inactive-fgColor-rest,var(--color-btn-inactive-text,#8b949e)));}/*!sc*/\n.dMUxwi[data-inactive]:not([disabled]):focus-visible{box-shadow:none;}/*!sc*/\n.dMUxwi [data-component=\"leadingVisual\"]{grid-area:leadingVisual;}/*!sc*/\n.dMUxwi [data-component=\"text\"]{grid-area:text;line-height:calc(20/14);white-space:nowrap;}/*!sc*/\n.dMUxwi [data-component=\"trailingVisual\"]{grid-area:trailingVisual;}/*!sc*/\n.dMUxwi [data-component=\"trailingAction\"]{margin-right:-4px;}/*!sc*/\n.dMUxwi [data-component=\"buttonContent\"]{-webkit-flex:1 0 auto;-ms-flex:1 0 auto;flex:1 0 auto;display:grid;grid-template-areas:\"leadingVisual text trailingVisual\";grid-template-columns:min-content minmax(0,auto) min-content;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-align-content:center;-ms-flex-line-pack:center;align-content:center;}/*!sc*/\n.dMUxwi [data-component=\"buttonContent\"] > :not(:last-child){margin-right:8px;}/*!sc*/\n.dMUxwi:hover:not([disabled]):not([data-inactive]){background-color:var(--button-default-bgColor-hover,var(--color-btn-hover-bg,#30363d));border-color:var(--button-default-borderColor-hover,var(--button-default-borderColor-hover,var(--color-btn-hover-border,#8b949e)));}/*!sc*/\n.dMUxwi:active:not([disabled]):not([data-inactive]){background-color:var(--button-default-bgColor-active,var(--color-btn-active-bg,hsla(212,12%,18%,1)));border-color:var(--button-default-borderColor-active,var(--button-default-borderColor-active,var(--color-btn-active-border,#6e7681)));}/*!sc*/\n.dMUxwi[aria-expanded=true]{background-color:var(--button-default-bgColor-active,var(--color-btn-active-bg,hsla(212,12%,18%,1)));border-color:var(--button-default-borderColor-active,var(--button-default-borderColor-active,var(--color-btn-active-border,#6e7681)));}/*!sc*/\n.dMUxwi [data-component=\"leadingVisual\"],.dMUxwi [data-component=\"trailingVisual\"],.dMUxwi [data-component=\"trailingAction\"]{color:var(--button-color,var(--fgColor-muted,var(--color-fg-muted,#848d97)));}/*!sc*/\n.dMUxwi[data-component=\"IconButton\"][data-no-visuals]{color:var(--fgColor-muted,var(--color-fg-muted,#848d97));}/*!sc*/\n.fCIOmi{border-radius:6px;border:1px solid;border-color:var(--button-default-borderColor-rest,var(--button-default-borderColor-rest,var(--color-btn-border,rgba(240,246,252,0.1))));font-family:inherit;font-weight:500;font-size:14px;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-text-decoration:none;text-decoration:none;text-align:center;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;height:32px;padding:0 12px;gap:8px;min-width:-webkit-max-content;min-width:-moz-max-content;min-width:max-content;-webkit-transition:80ms cubic-bezier(0.65,0,0.35,1);transition:80ms cubic-bezier(0.65,0,0.35,1);-webkit-transition-property:color,fill,background-color,border-color;transition-property:color,fill,background-color,border-color;color:var(--button-default-fgColor-rest,var(--color-btn-text,#c9d1d9));background-color:var(--button-default-bgColor-rest,var(--color-btn-bg,#21262d));box-shadow:var(--button-default-shadow-resting,var(--color-btn-shadow,0 0 transparent)),var(--button-default-shadow-inset,var(--color-btn-inset-shadow,0 0 transparent));}/*!sc*/\n.fCIOmi:focus:not(:disabled){box-shadow:none;outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#2f81f7));outline-offset:-2px;}/*!sc*/\n.fCIOmi:focus:not(:disabled):not(:focus-visible){outline:solid 1px transparent;}/*!sc*/\n.fCIOmi:focus-visible:not(:disabled){box-shadow:none;outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#2f81f7));outline-offset:-2px;}/*!sc*/\n.fCIOmi[href]{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;}/*!sc*/\n.fCIOmi[href]:hover{-webkit-text-decoration:none;text-decoration:none;}/*!sc*/\n.fCIOmi:hover{-webkit-transition-duration:80ms;transition-duration:80ms;}/*!sc*/\n.fCIOmi:active{-webkit-transition:none;transition:none;}/*!sc*/\n.fCIOmi[data-inactive]{cursor:auto;}/*!sc*/\n.fCIOmi:disabled{cursor:not-allowed;box-shadow:none;color:var(--fgColor-disabled,var(--color-primer-fg-disabled,#484f58));border-color:var(--button-default-borderColor-disabled,var(--button-default-borderColor-rest,var(--color-btn-border,rgba(240,246,252,0.1))));background-color:var(--button-default-bgColor-disabled,var(--control-bgColor-disabled,var(--color-input-disabled-bg,rgba(110,118,129,0))));}/*!sc*/\n.fCIOmi:disabled [data-component=ButtonCounter]{color:inherit;}/*!sc*/\n@media (forced-colors:active){.fCIOmi:focus{outline:solid 1px transparent;}}/*!sc*/\n.fCIOmi [data-component=ButtonCounter]{font-size:12px;background-color:var(--buttonCounter-default-bgColor-rest,var(--color-btn-counter-bg,#30363d));}/*!sc*/\n.fCIOmi[data-component=IconButton]{display:inline-grid;padding:unset;place-content:center;width:32px;min-width:unset;}/*!sc*/\n.fCIOmi[data-size=\"small\"]{padding:0 8px;height:28px;gap:4px;font-size:12px;}/*!sc*/\n.fCIOmi[data-size=\"small\"] [data-component=\"text\"]{line-height:calc(20 / 12);}/*!sc*/\n.fCIOmi[data-size=\"small\"] [data-component=ButtonCounter]{font-size:12px;}/*!sc*/\n.fCIOmi[data-size=\"small\"] [data-component=\"buttonContent\"] > :not(:last-child){margin-right:4px;}/*!sc*/\n.fCIOmi[data-size=\"small\"][data-component=IconButton]{width:28px;padding:unset;}/*!sc*/\n.fCIOmi[data-size=\"large\"]{padding:0 16px;height:40px;gap:8px;}/*!sc*/\n.fCIOmi[data-size=\"large\"] [data-component=\"buttonContent\"] > :not(:last-child){margin-right:8px;}/*!sc*/\n.fCIOmi[data-size=\"large\"][data-component=IconButton]{width:40px;padding:unset;}/*!sc*/\n.fCIOmi[data-block=\"block\"]{width:100%;}/*!sc*/\n.fCIOmi[data-inactive]:not([disabled]){background-color:var(--button-inactive-bgColor,var(--button-inactive-bgColor-rest,var(--color-btn-inactive-bg,#21262d)));border-color:var(--button-inactive-bgColor,var(--button-inactive-bgColor-rest,var(--color-btn-inactive-bg,#21262d)));color:var(--button-inactive-fgColor,var(--button-inactive-fgColor-rest,var(--color-btn-inactive-text,#8b949e)));}/*!sc*/\n.fCIOmi[data-inactive]:not([disabled]):focus-visible{box-shadow:none;}/*!sc*/\n.fCIOmi [data-component=\"leadingVisual\"]{grid-area:leadingVisual;}/*!sc*/\n.fCIOmi [data-component=\"text\"]{grid-area:text;line-height:calc(20/14);white-space:nowrap;}/*!sc*/\n.fCIOmi [data-component=\"trailingVisual\"]{grid-area:trailingVisual;}/*!sc*/\n.fCIOmi [data-component=\"trailingAction\"]{margin-right:-4px;}/*!sc*/\n.fCIOmi [data-component=\"buttonContent\"]{-webkit-flex:1 0 auto;-ms-flex:1 0 auto;flex:1 0 auto;display:grid;grid-template-areas:\"leadingVisual text trailingVisual\";grid-template-columns:min-content minmax(0,auto) min-content;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-align-content:center;-ms-flex-line-pack:center;align-content:center;}/*!sc*/\n.fCIOmi [data-component=\"buttonContent\"] > :not(:last-child){margin-right:8px;}/*!sc*/\n.fCIOmi:hover:not([disabled]):not([data-inactive]){background-color:var(--button-default-bgColor-hover,var(--color-btn-hover-bg,#30363d));border-color:var(--button-default-borderColor-hover,var(--button-default-borderColor-hover,var(--color-btn-hover-border,#8b949e)));}/*!sc*/\n.fCIOmi:active:not([disabled]):not([data-inactive]){background-color:var(--button-default-bgColor-active,var(--color-btn-active-bg,hsla(212,12%,18%,1)));border-color:var(--button-default-borderColor-active,var(--button-default-borderColor-active,var(--color-btn-active-border,#6e7681)));}/*!sc*/\n.fCIOmi[aria-expanded=true]{background-color:var(--button-default-bgColor-active,var(--color-btn-active-bg,hsla(212,12%,18%,1)));border-color:var(--button-default-borderColor-active,var(--button-default-borderColor-active,var(--color-btn-active-border,#6e7681)));}/*!sc*/\n.fCIOmi [data-component=\"leadingVisual\"],.fCIOmi [data-component=\"trailingVisual\"],.fCIOmi [data-component=\"trailingAction\"]{color:var(--button-color,var(--fgColor-muted,var(--color-fg-muted,#848d97)));}/*!sc*/\n.fCIOmi[data-component=\"IconButton\"][data-no-visuals]{color:var(--fgColor-muted,var(--color-fg-muted,#848d97));}/*!sc*/\n.fCIOmi[data-size=\"small\"][data-no-visuals]{border-top-left-radius:0;border-bottom-left-radius:0;}/*!sc*/\n.ksnFc{border-radius:6px;border:1px solid;border-color:var(--button-default-borderColor-rest,var(--button-default-borderColor-rest,var(--color-btn-border,rgba(240,246,252,0.1))));font-family:inherit;font-weight:500;font-size:14px;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-text-decoration:none;text-decoration:none;text-align:center;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;height:32px;padding:0 12px;gap:8px;min-width:-webkit-max-content;min-width:-moz-max-content;min-width:max-content;-webkit-transition:80ms cubic-bezier(0.65,0,0.35,1);transition:80ms cubic-bezier(0.65,0,0.35,1);-webkit-transition-property:color,fill,background-color,border-color;transition-property:color,fill,background-color,border-color;color:var(--button-default-fgColor-rest,var(--color-btn-text,#c9d1d9));background-color:var(--button-default-bgColor-rest,var(--color-btn-bg,#21262d));box-shadow:var(--button-default-shadow-resting,var(--color-btn-shadow,0 0 transparent)),var(--button-default-shadow-inset,var(--color-btn-inset-shadow,0 0 transparent));}/*!sc*/\n.ksnFc:focus:not(:disabled){box-shadow:none;outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#2f81f7));outline-offset:-2px;}/*!sc*/\n.ksnFc:focus:not(:disabled):not(:focus-visible){outline:solid 1px transparent;}/*!sc*/\n.ksnFc:focus-visible:not(:disabled){box-shadow:none;outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#2f81f7));outline-offset:-2px;}/*!sc*/\n.ksnFc[href]{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;}/*!sc*/\n.ksnFc[href]:hover{-webkit-text-decoration:none;text-decoration:none;}/*!sc*/\n.ksnFc:hover{-webkit-transition-duration:80ms;transition-duration:80ms;}/*!sc*/\n.ksnFc:active{-webkit-transition:none;transition:none;}/*!sc*/\n.ksnFc[data-inactive]{cursor:auto;}/*!sc*/\n.ksnFc:disabled{cursor:not-allowed;box-shadow:none;color:var(--fgColor-disabled,var(--color-primer-fg-disabled,#484f58));border-color:var(--button-default-borderColor-disabled,var(--button-default-borderColor-rest,var(--color-btn-border,rgba(240,246,252,0.1))));background-color:var(--button-default-bgColor-disabled,var(--control-bgColor-disabled,var(--color-input-disabled-bg,rgba(110,118,129,0))));}/*!sc*/\n.ksnFc:disabled [data-component=ButtonCounter]{color:inherit;}/*!sc*/\n@media (forced-colors:active){.ksnFc:focus{outline:solid 1px transparent;}}/*!sc*/\n.ksnFc [data-component=ButtonCounter]{font-size:12px;background-color:var(--buttonCounter-default-bgColor-rest,var(--color-btn-counter-bg,#30363d));}/*!sc*/\n.ksnFc[data-component=IconButton]{display:inline-grid;padding:unset;place-content:center;width:32px;min-width:unset;}/*!sc*/\n.ksnFc[data-size=\"small\"]{padding:0 8px;height:28px;gap:4px;font-size:12px;}/*!sc*/\n.ksnFc[data-size=\"small\"] [data-component=\"text\"]{line-height:calc(20 / 12);}/*!sc*/\n.ksnFc[data-size=\"small\"] [data-component=ButtonCounter]{font-size:12px;}/*!sc*/\n.ksnFc[data-size=\"small\"] [data-component=\"buttonContent\"] > :not(:last-child){margin-right:4px;}/*!sc*/\n.ksnFc[data-size=\"small\"][data-component=IconButton]{width:28px;padding:unset;}/*!sc*/\n.ksnFc[data-size=\"large\"]{padding:0 16px;height:40px;gap:8px;}/*!sc*/\n.ksnFc[data-size=\"large\"] [data-component=\"buttonContent\"] > :not(:last-child){margin-right:8px;}/*!sc*/\n.ksnFc[data-size=\"large\"][data-component=IconButton]{width:40px;padding:unset;}/*!sc*/\n.ksnFc[data-block=\"block\"]{width:100%;}/*!sc*/\n.ksnFc[data-inactive]:not([disabled]){background-color:var(--button-inactive-bgColor,var(--button-inactive-bgColor-rest,var(--color-btn-inactive-bg,#21262d)));border-color:var(--button-inactive-bgColor,var(--button-inactive-bgColor-rest,var(--color-btn-inactive-bg,#21262d)));color:var(--button-inactive-fgColor,var(--button-inactive-fgColor-rest,var(--color-btn-inactive-text,#8b949e)));}/*!sc*/\n.ksnFc[data-inactive]:not([disabled]):focus-visible{box-shadow:none;}/*!sc*/\n.ksnFc [data-component=\"leadingVisual\"]{grid-area:leadingVisual;}/*!sc*/\n.ksnFc [data-component=\"text\"]{grid-area:text;line-height:calc(20/14);white-space:nowrap;}/*!sc*/\n.ksnFc [data-component=\"trailingVisual\"]{grid-area:trailingVisual;}/*!sc*/\n.ksnFc [data-component=\"trailingAction\"]{margin-right:-4px;}/*!sc*/\n.ksnFc [data-component=\"buttonContent\"]{-webkit-flex:1 0 auto;-ms-flex:1 0 auto;flex:1 0 auto;display:grid;grid-template-areas:\"leadingVisual text trailingVisual\";grid-template-columns:min-content minmax(0,auto) min-content;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-align-content:center;-ms-flex-line-pack:center;align-content:center;}/*!sc*/\n.ksnFc [data-component=\"buttonContent\"] > :not(:last-child){margin-right:8px;}/*!sc*/\n.ksnFc:hover:not([disabled]):not([data-inactive]){background-color:var(--button-default-bgColor-hover,var(--color-btn-hover-bg,#30363d));border-color:var(--button-default-borderColor-hover,var(--button-default-borderColor-hover,var(--color-btn-hover-border,#8b949e)));}/*!sc*/\n.ksnFc:active:not([disabled]):not([data-inactive]){background-color:var(--button-default-bgColor-active,var(--color-btn-active-bg,hsla(212,12%,18%,1)));border-color:var(--button-default-borderColor-active,var(--button-default-borderColor-active,var(--color-btn-active-border,#6e7681)));}/*!sc*/\n.ksnFc[aria-expanded=true]{background-color:var(--button-default-bgColor-active,var(--color-btn-active-bg,hsla(212,12%,18%,1)));border-color:var(--button-default-borderColor-active,var(--button-default-borderColor-active,var(--color-btn-active-border,#6e7681)));}/*!sc*/\n.ksnFc [data-component=\"leadingVisual\"],.ksnFc [data-component=\"trailingVisual\"],.ksnFc [data-component=\"trailingAction\"]{color:var(--button-color,var(--fgColor-muted,var(--color-fg-muted,#848d97)));}/*!sc*/\n.ksnFc[data-component=\"IconButton\"][data-no-visuals]{color:var(--fgColor-muted,var(--color-fg-muted,#848d97));}/*!sc*/\n.ksnFc[data-size=\"small\"][data-no-visuals]{border-top-right-radius:0;border-bottom-right-radius:0;border-right-width:0;}/*!sc*/\n.ksnFc[data-size=\"small\"][data-no-visuals]:hover:not([disabled]){-webkit-text-decoration:none;text-decoration:none;}/*!sc*/\n.ksnFc[data-size=\"small\"][data-no-visuals]:focus:not([disabled]){-webkit-text-decoration:none;text-decoration:none;}/*!sc*/\n.ksnFc[data-size=\"small\"][data-no-visuals]:active:not([disabled]){-webkit-text-decoration:none;text-decoration:none;}/*!sc*/\n.jgnIDP{border-radius:6px;border:1px solid;border-color:transparent;font-family:inherit;font-weight:500;font-size:14px;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-text-decoration:none;text-decoration:none;text-align:center;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;height:32px;padding:0 12px;gap:8px;min-width:-webkit-max-content;min-width:-moz-max-content;min-width:max-content;-webkit-transition:80ms cubic-bezier(0.65,0,0.35,1);transition:80ms cubic-bezier(0.65,0,0.35,1);-webkit-transition-property:color,fill,background-color,border-color;transition-property:color,fill,background-color,border-color;color:var(--button-default-fgColor-rest,var(--color-btn-text,#c9d1d9));background-color:transparent;box-shadow:none;}/*!sc*/\n.jgnIDP:focus:not(:disabled){box-shadow:none;outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#2f81f7));outline-offset:-2px;}/*!sc*/\n.jgnIDP:focus:not(:disabled):not(:focus-visible){outline:solid 1px transparent;}/*!sc*/\n.jgnIDP:focus-visible:not(:disabled){box-shadow:none;outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#2f81f7));outline-offset:-2px;}/*!sc*/\n.jgnIDP[href]{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;}/*!sc*/\n.jgnIDP[href]:hover{-webkit-text-decoration:none;text-decoration:none;}/*!sc*/\n.jgnIDP:hover{-webkit-transition-duration:80ms;transition-duration:80ms;}/*!sc*/\n.jgnIDP:active{-webkit-transition:none;transition:none;}/*!sc*/\n.jgnIDP[data-inactive]{cursor:auto;}/*!sc*/\n.jgnIDP:disabled{cursor:not-allowed;box-shadow:none;color:var(--fgColor-disabled,var(--color-primer-fg-disabled,#484f58));}/*!sc*/\n.jgnIDP:disabled [data-component=ButtonCounter],.jgnIDP:disabled [data-component=\"leadingVisual\"],.jgnIDP:disabled [data-component=\"trailingAction\"]{color:inherit;}/*!sc*/\n@media (forced-colors:active){.jgnIDP:focus{outline:solid 1px transparent;}}/*!sc*/\n.jgnIDP [data-component=ButtonCounter]{font-size:12px;}/*!sc*/\n.jgnIDP[data-component=IconButton]{display:inline-grid;padding:unset;place-content:center;width:32px;min-width:unset;}/*!sc*/\n.jgnIDP[data-size=\"small\"]{padding:0 8px;height:28px;gap:4px;font-size:12px;}/*!sc*/\n.jgnIDP[data-size=\"small\"] [data-component=\"text\"]{line-height:calc(20 / 12);}/*!sc*/\n.jgnIDP[data-size=\"small\"] [data-component=ButtonCounter]{font-size:12px;}/*!sc*/\n.jgnIDP[data-size=\"small\"] [data-component=\"buttonContent\"] > :not(:last-child){margin-right:4px;}/*!sc*/\n.jgnIDP[data-size=\"small\"][data-component=IconButton]{width:28px;padding:unset;}/*!sc*/\n.jgnIDP[data-size=\"large\"]{padding:0 16px;height:40px;gap:8px;}/*!sc*/\n.jgnIDP[data-size=\"large\"] [data-component=\"buttonContent\"] > :not(:last-child){margin-right:8px;}/*!sc*/\n.jgnIDP[data-size=\"large\"][data-component=IconButton]{width:40px;padding:unset;}/*!sc*/\n.jgnIDP[data-block=\"block\"]{width:100%;}/*!sc*/\n.jgnIDP[data-inactive]:not([disabled]){background-color:var(--button-inactive-bgColor,var(--button-inactive-bgColor-rest,var(--color-btn-inactive-bg,#21262d)));border-color:var(--button-inactive-bgColor,var(--button-inactive-bgColor-rest,var(--color-btn-inactive-bg,#21262d)));color:var(--button-inactive-fgColor,var(--button-inactive-fgColor-rest,var(--color-btn-inactive-text,#8b949e)));}/*!sc*/\n.jgnIDP[data-inactive]:not([disabled]):focus-visible{box-shadow:none;}/*!sc*/\n.jgnIDP [data-component=\"leadingVisual\"]{grid-area:leadingVisual;color:var(--fgColor-muted,var(--color-fg-muted,#848d97));}/*!sc*/\n.jgnIDP [data-component=\"text\"]{grid-area:text;line-height:calc(20/14);white-space:nowrap;}/*!sc*/\n.jgnIDP [data-component=\"trailingVisual\"]{grid-area:trailingVisual;}/*!sc*/\n.jgnIDP [data-component=\"trailingAction\"]{margin-right:-4px;color:var(--fgColor-muted,var(--color-fg-muted,#848d97));}/*!sc*/\n.jgnIDP [data-component=\"buttonContent\"]{-webkit-flex:1 0 auto;-ms-flex:1 0 auto;flex:1 0 auto;display:grid;grid-template-areas:\"leadingVisual text trailingVisual\";grid-template-columns:min-content minmax(0,auto) min-content;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-align-content:center;-ms-flex-line-pack:center;align-content:center;}/*!sc*/\n.jgnIDP [data-component=\"buttonContent\"] > :not(:last-child){margin-right:8px;}/*!sc*/\n.jgnIDP:hover:not([disabled]){background-color:var(--control-transparent-bgColor-hover,var(--color-action-list-item-default-hover-bg,rgba(177,186,196,0.12)));}/*!sc*/\n.jgnIDP:active:not([disabled]){background-color:var(--control-transparent-bgColor-active,var(--color-action-list-item-default-active-bg,rgba(177,186,196,0.2)));}/*!sc*/\n.jgnIDP[aria-expanded=true]{background-color:var(--control-transparent-bgColor-selected,var(--color-action-list-item-default-selected-bg,rgba(177,186,196,0.08)));}/*!sc*/\n.jgnIDP[data-component=\"IconButton\"][data-no-visuals]{color:var(--fgColor-muted,var(--color-fg-muted,#848d97));}/*!sc*/\n.jgnIDP[data-no-visuals]{color:var(--fgColor-accent,var(--color-accent-fg,#2f81f7));}/*!sc*/\n.jgnIDP:has([data-component=\"ButtonCounter\"]){color:var(--button-default-fgColor-rest,var(--color-btn-text,#c9d1d9));}/*!sc*/\n.jgnIDP:disabled[data-no-visuals]{color:var(--fgColor-disabled,var(--color-primer-fg-disabled,#484f58));}/*!sc*/\n.jgnIDP:disabled[data-no-visuals] [data-component=ButtonCounter]{color:inherit;}/*!sc*/\n.jgnIDP[data-size=\"small\"][data-no-visuals]{color:var(--fgColor-muted,var(--color-fg-muted,#848d97));position:relative;}/*!sc*/\n.htXhGX{border-radius:6px;border:1px solid;border-color:transparent;font-family:inherit;font-weight:500;font-size:14px;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-text-decoration:none;text-decoration:none;text-align:center;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;height:32px;padding:0 12px;gap:8px;min-width:-webkit-max-content;min-width:-moz-max-content;min-width:max-content;-webkit-transition:80ms cubic-bezier(0.65,0,0.35,1);transition:80ms cubic-bezier(0.65,0,0.35,1);-webkit-transition-property:color,fill,background-color,border-color;transition-property:color,fill,background-color,border-color;color:var(--button-default-fgColor-rest,var(--color-btn-text,#c9d1d9));background-color:transparent;box-shadow:none;}/*!sc*/\n.htXhGX:focus:not(:disabled){box-shadow:none;outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#2f81f7));outline-offset:-2px;}/*!sc*/\n.htXhGX:focus:not(:disabled):not(:focus-visible){outline:solid 1px transparent;}/*!sc*/\n.htXhGX:focus-visible:not(:disabled){box-shadow:none;outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#2f81f7));outline-offset:-2px;}/*!sc*/\n.htXhGX[href]{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;}/*!sc*/\n.htXhGX[href]:hover{-webkit-text-decoration:none;text-decoration:none;}/*!sc*/\n.htXhGX:hover{-webkit-transition-duration:80ms;transition-duration:80ms;}/*!sc*/\n.htXhGX:active{-webkit-transition:none;transition:none;}/*!sc*/\n.htXhGX[data-inactive]{cursor:auto;}/*!sc*/\n.htXhGX:disabled{cursor:not-allowed;box-shadow:none;color:var(--fgColor-disabled,var(--color-primer-fg-disabled,#484f58));}/*!sc*/\n.htXhGX:disabled [data-component=ButtonCounter],.htXhGX:disabled [data-component=\"leadingVisual\"],.htXhGX:disabled [data-component=\"trailingAction\"]{color:inherit;}/*!sc*/\n@media (forced-colors:active){.htXhGX:focus{outline:solid 1px transparent;}}/*!sc*/\n.htXhGX [data-component=ButtonCounter]{font-size:12px;}/*!sc*/\n.htXhGX[data-component=IconButton]{display:inline-grid;padding:unset;place-content:center;width:32px;min-width:unset;}/*!sc*/\n.htXhGX[data-size=\"small\"]{padding:0 8px;height:28px;gap:4px;font-size:12px;}/*!sc*/\n.htXhGX[data-size=\"small\"] [data-component=\"text\"]{line-height:calc(20 / 12);}/*!sc*/\n.htXhGX[data-size=\"small\"] [data-component=ButtonCounter]{font-size:12px;}/*!sc*/\n.htXhGX[data-size=\"small\"] [data-component=\"buttonContent\"] > :not(:last-child){margin-right:4px;}/*!sc*/\n.htXhGX[data-size=\"small\"][data-component=IconButton]{width:28px;padding:unset;}/*!sc*/\n.htXhGX[data-size=\"large\"]{padding:0 16px;height:40px;gap:8px;}/*!sc*/\n.htXhGX[data-size=\"large\"] [data-component=\"buttonContent\"] > :not(:last-child){margin-right:8px;}/*!sc*/\n.htXhGX[data-size=\"large\"][data-component=IconButton]{width:40px;padding:unset;}/*!sc*/\n.htXhGX[data-block=\"block\"]{width:100%;}/*!sc*/\n.htXhGX[data-inactive]:not([disabled]){background-color:var(--button-inactive-bgColor,var(--button-inactive-bgColor-rest,var(--color-btn-inactive-bg,#21262d)));border-color:var(--button-inactive-bgColor,var(--button-inactive-bgColor-rest,var(--color-btn-inactive-bg,#21262d)));color:var(--button-inactive-fgColor,var(--button-inactive-fgColor-rest,var(--color-btn-inactive-text,#8b949e)));}/*!sc*/\n.htXhGX[data-inactive]:not([disabled]):focus-visible{box-shadow:none;}/*!sc*/\n.htXhGX [data-component=\"leadingVisual\"]{grid-area:leadingVisual;color:var(--fgColor-muted,var(--color-fg-muted,#848d97));}/*!sc*/\n.htXhGX [data-component=\"text\"]{grid-area:text;line-height:calc(20/14);white-space:nowrap;}/*!sc*/\n.htXhGX [data-component=\"trailingVisual\"]{grid-area:trailingVisual;}/*!sc*/\n.htXhGX [data-component=\"trailingAction\"]{margin-right:-4px;color:var(--fgColor-muted,var(--color-fg-muted,#848d97));}/*!sc*/\n.htXhGX [data-component=\"buttonContent\"]{-webkit-flex:1 0 auto;-ms-flex:1 0 auto;flex:1 0 auto;display:grid;grid-template-areas:\"leadingVisual text trailingVisual\";grid-template-columns:min-content minmax(0,auto) min-content;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-align-content:center;-ms-flex-line-pack:center;align-content:center;}/*!sc*/\n.htXhGX [data-component=\"buttonContent\"] > :not(:last-child){margin-right:8px;}/*!sc*/\n.htXhGX:hover:not([disabled]){background-color:var(--control-transparent-bgColor-hover,var(--color-action-list-item-default-hover-bg,rgba(177,186,196,0.12)));}/*!sc*/\n.htXhGX:active:not([disabled]){background-color:var(--control-transparent-bgColor-active,var(--color-action-list-item-default-active-bg,rgba(177,186,196,0.2)));}/*!sc*/\n.htXhGX[aria-expanded=true]{background-color:var(--control-transparent-bgColor-selected,var(--color-action-list-item-default-selected-bg,rgba(177,186,196,0.08)));}/*!sc*/\n.htXhGX[data-component=\"IconButton\"][data-no-visuals]{color:var(--fgColor-muted,var(--color-fg-muted,#848d97));}/*!sc*/\n.htXhGX[data-no-visuals]{color:var(--fgColor-accent,var(--color-accent-fg,#2f81f7));}/*!sc*/\n.htXhGX:has([data-component=\"ButtonCounter\"]){color:var(--button-default-fgColor-rest,var(--color-btn-text,#c9d1d9));}/*!sc*/\n.htXhGX:disabled[data-no-visuals]{color:var(--fgColor-disabled,var(--color-primer-fg-disabled,#484f58));}/*!sc*/\n.htXhGX:disabled[data-no-visuals] [data-component=ButtonCounter]{color:inherit;}/*!sc*/\n.htXhGX[data-size=\"small\"][data-no-visuals]{color:var(--fgColor-muted,var(--color-fg-muted,#848d97));}/*!sc*/\ndata-styled.g9[id=\"types__StyledButton-sc-ws60qy-0\"]{content:\"iKABXH,hfWObv,gBsjGI,XJZbf,cBjhIZ,IIGly,fXsbsD,hiXxwe,saA-Dg,ecGgfP,dupbIv,dMUxwi,fCIOmi,ksnFc,jgnIDP,htXhGX,\"}/*!sc*/\n.rTZSs{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;-webkit-clip:rect(0,0,0,0);clip:rect(0,0,0,0);white-space:nowrap;border-width:0;}/*!sc*/\ndata-styled.g10[id=\"_VisuallyHidden__VisuallyHidden-sc-11jhm7a-0\"]{content:\"rTZSs,\"}/*!sc*/\n.izAlVj{position:relative;display:inline-block;}/*!sc*/\n.izAlVj::after{position:absolute;z-index:1000000;display:none;padding:0.5em 0.75em;font:normal normal 11px/1.5 -apple-system,BlinkMacSystemFont,\"Segoe UI\",\"Noto Sans\",Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\";-webkit-font-smoothing:subpixel-antialiased;color:var(--fgColor-onEmphasis,var(--color-fg-on-emphasis,#ffffff));text-align:center;-webkit-text-decoration:none;text-decoration:none;text-shadow:none;text-transform:none;-webkit-letter-spacing:normal;-moz-letter-spacing:normal;-ms-letter-spacing:normal;letter-spacing:normal;word-wrap:break-word;white-space:pre;pointer-events:none;content:attr(aria-label);background:var(--bgColor-emphasis,var(--color-neutral-emphasis-plus,#6e7681));border-radius:6px;opacity:0;}/*!sc*/\n@-webkit-keyframes tooltip-appear{from{opacity:0;}to{opacity:1;}}/*!sc*/\n@keyframes tooltip-appear{from{opacity:0;}to{opacity:1;}}/*!sc*/\n.izAlVj:hover::after,.izAlVj:active::after,.izAlVj:focus::after,.izAlVj:focus-within::after{display:inline-block;-webkit-text-decoration:none;text-decoration:none;-webkit-animation-name:tooltip-appear;animation-name:tooltip-appear;-webkit-animation-duration:0.1s;animation-duration:0.1s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;-webkit-animation-delay:0s;animation-delay:0s;}/*!sc*/\n.izAlVj.tooltipped-no-delay:hover::after,.izAlVj.tooltipped-no-delay:active::after,.izAlVj.tooltipped-no-delay:focus::after,.izAlVj.tooltipped-no-delay:focus-within::after{-webkit-animation-delay:0s;animation-delay:0s;}/*!sc*/\n.izAlVj.tooltipped-multiline:hover::after,.izAlVj.tooltipped-multiline:active::after,.izAlVj.tooltipped-multiline:focus::after,.izAlVj.tooltipped-multiline:focus-within::after{display:table-cell;}/*!sc*/\n.izAlVj.tooltipped-s::after,.izAlVj.tooltipped-se::after,.izAlVj.tooltipped-sw::after{top:100%;right:50%;margin-top:6px;}/*!sc*/\n.izAlVj.tooltipped-se::after{right:auto;left:50%;margin-left:-16px;}/*!sc*/\n.izAlVj.tooltipped-sw::after{margin-right:-16px;}/*!sc*/\n.izAlVj.tooltipped-n::after,.izAlVj.tooltipped-ne::after,.izAlVj.tooltipped-nw::after{right:50%;bottom:100%;margin-bottom:6px;}/*!sc*/\n.izAlVj.tooltipped-ne::after{right:auto;left:50%;margin-left:-16px;}/*!sc*/\n.izAlVj.tooltipped-nw::after{margin-right:-16px;}/*!sc*/\n.izAlVj.tooltipped-s::after,.izAlVj.tooltipped-n::after{-webkit-transform:translateX(50%);-ms-transform:translateX(50%);transform:translateX(50%);}/*!sc*/\n.izAlVj.tooltipped-w::after{right:100%;bottom:50%;margin-right:6px;-webkit-transform:translateY(50%);-ms-transform:translateY(50%);transform:translateY(50%);}/*!sc*/\n.izAlVj.tooltipped-e::after{bottom:50%;left:100%;margin-left:6px;-webkit-transform:translateY(50%);-ms-transform:translateY(50%);transform:translateY(50%);}/*!sc*/\n.izAlVj.tooltipped-multiline::after{width:-webkit-max-content;width:-moz-max-content;width:max-content;max-width:250px;word-wrap:break-word;white-space:pre-line;border-collapse:separate;}/*!sc*/\n.izAlVj.tooltipped-multiline.tooltipped-s::after,.izAlVj.tooltipped-multiline.tooltipped-n::after{right:auto;left:50%;-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);}/*!sc*/\n.izAlVj.tooltipped-multiline.tooltipped-w::after,.izAlVj.tooltipped-multiline.tooltipped-e::after{right:100%;}/*!sc*/\n.izAlVj.tooltipped-align-right-2::after{right:0;margin-right:0;}/*!sc*/\n.izAlVj.tooltipped-align-left-2::after{left:0;margin-left:0;}/*!sc*/\ndata-styled.g14[id=\"Tooltip__TooltipBase-sc-17tf59c-0\"]{content:\"izAlVj,\"}/*!sc*/\n.fUpWeN{display:inline-block;overflow:hidden;text-overflow:ellipsis;vertical-align:top;white-space:nowrap;max-width:125px;max-width:100%;}/*!sc*/\ndata-styled.g16[id=\"Truncate__StyledTruncate-sc-23o1d2-0\"]{content:\"fUpWeN,\"}/*!sc*/\n.kbCZWh{font-size:14px;line-height:20px;color:var(--fgColor-default,var(--color-fg-default,#e6edf3));vertical-align:middle;background-color:var(--bgColor-default,var(--color-canvas-default,#0d1117));border:1px solid var(--control-borderColor-rest,var(--borderColor-default,var(--color-border-default,#30363d)));border-radius:6px;outline:none;box-shadow:var(--shadow-inset,var(--color-primer-shadow-inset,0 0 transparent));display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-align-items:stretch;-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch;min-height:32px;overflow:hidden;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;min-width:160px;}/*!sc*/\n.kbCZWh input,.kbCZWh textarea{cursor:text;}/*!sc*/\n.kbCZWh select{cursor:pointer;}/*!sc*/\n.kbCZWh input::-webkit-input-placeholder,.kbCZWh textarea::-webkit-input-placeholder,.kbCZWh select::-webkit-input-placeholder{color:var(---control-fgColor-placeholder,var(--fgColor-muted,var(--color-fg-muted,#848d97)));}/*!sc*/\n.kbCZWh input::-moz-placeholder,.kbCZWh textarea::-moz-placeholder,.kbCZWh select::-moz-placeholder{color:var(---control-fgColor-placeholder,var(--fgColor-muted,var(--color-fg-muted,#848d97)));}/*!sc*/\n.kbCZWh input:-ms-input-placeholder,.kbCZWh textarea:-ms-input-placeholder,.kbCZWh select:-ms-input-placeholder{color:var(---control-fgColor-placeholder,var(--fgColor-muted,var(--color-fg-muted,#848d97)));}/*!sc*/\n.kbCZWh input::placeholder,.kbCZWh textarea::placeholder,.kbCZWh select::placeholder{color:var(---control-fgColor-placeholder,var(--fgColor-muted,var(--color-fg-muted,#848d97)));}/*!sc*/\n.kbCZWh:focus-within{border-color:var(--fgColor-accent,var(--color-accent-fg,#2f81f7));outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#2f81f7));outline-offset:-1px;}/*!sc*/\n.kbCZWh > textarea{padding:12px;}/*!sc*/\n@media (min-width:768px){.kbCZWh{font-size:14px;}}/*!sc*/\ndata-styled.g37[id=\"TextInputWrapper__TextInputBaseWrapper-sc-1mqhpbi-0\"]{content:\"kbCZWh,\"}/*!sc*/\n.jxgrJS{background-repeat:no-repeat;background-position:right 8px center;padding-left:12px;padding-right:12px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;min-width:160px;}/*!sc*/\n.jxgrJS > :not(:last-child){margin-right:8px;}/*!sc*/\n.jxgrJS .TextInput-icon,.jxgrJS .TextInput-action{-webkit-align-self:center;-ms-flex-item-align:center;align-self:center;color:var(--fgColor-muted,var(--color-fg-muted,#848d97));-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;}/*!sc*/\n.jxgrJS > input,.jxgrJS > select{padding-left:0;padding-right:0;}/*!sc*/\ndata-styled.g38[id=\"TextInputWrapper-sc-1mqhpbi-1\"]{content:\"jxgrJS,\"}/*!sc*/\n.cDLBls{border:0;font-size:inherit;font-family:inherit;background-color:transparent;-webkit-appearance:none;color:inherit;width:100%;}/*!sc*/\n.cDLBls:focus{outline:0;}/*!sc*/\ndata-styled.g39[id=\"UnstyledTextInput-sc-14ypya-0\"]{content:\"cDLBls,\"}/*!sc*/\n.kNvrzW{--segmented-control-button-inner-padding:12px;--segmented-control-button-bg-inset:4px;--segmented-control-outer-radius:6px;background-color:transparent;border-color:transparent;border-radius:var(--segmented-control-outer-radius);border-width:0;color:currentColor;cursor:pointer;font-family:inherit;font-size:inherit;font-weight:600;padding:0;height:100%;width:100%;}/*!sc*/\n.kNvrzW .segmentedControl-content{-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background-color:var(--controlKnob-bgColor-rest,var(--color-segmented-control-button-bg,#0d1117));border-color:var(--controlKnob-borderColor-rest,var(--color-segmented-control-button-selected-border,#6e7681));border-style:solid;border-width:1px;border-radius:var(--segmented-control-outer-radius);display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;height:100%;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;padding-left:var(--segmented-control-button-inner-padding);padding-right:var(--segmented-control-button-inner-padding);}/*!sc*/\n.kNvrzW svg{fill:var(--fgColor-muted,var(--color-fg-muted,#848d97));}/*!sc*/\n.kNvrzW:focus:focus-visible:not(:last-child):after{width:0;}/*!sc*/\n.kNvrzW .segmentedControl-text:after{content:\"Code\";display:block;font-weight:600;height:0;overflow:hidden;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;visibility:hidden;}/*!sc*/\n@media (pointer:coarse){.kNvrzW:before{content:\"\";position:absolute;left:0;right:0;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%);top:50%;min-height:44px;}}/*!sc*/\n.iDBPxb{--segmented-control-button-inner-padding:12px;--segmented-control-button-bg-inset:4px;--segmented-control-outer-radius:6px;background-color:transparent;border-color:transparent;border-radius:var(--segmented-control-outer-radius);border-width:0;color:currentColor;cursor:pointer;font-family:inherit;font-size:inherit;font-weight:400;padding:var(--segmented-control-button-bg-inset);height:100%;width:100%;}/*!sc*/\n.iDBPxb .segmentedControl-content{-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background-color:transparent;border-color:transparent;border-style:solid;border-width:1px;border-radius:calc(var(--segmented-control-outer-radius) - var(--segmented-control-button-bg-inset) / 2);display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;height:100%;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;padding-left:calc(var(--segmented-control-button-inner-padding) - var(--segmented-control-button-bg-inset));padding-right:calc(var(--segmented-control-button-inner-padding) - var(--segmented-control-button-bg-inset));}/*!sc*/\n.iDBPxb svg{fill:var(--fgColor-muted,var(--color-fg-muted,#848d97));}/*!sc*/\n.iDBPxb:hover .segmentedControl-content{background-color:var(--controlTrack-bgColor-hover,var(--color-segmented-control-button-hover-bg,#30363d));}/*!sc*/\n.iDBPxb:active .segmentedControl-content{background-color:var(--controlTrack-bgColor-active,var(--color-segmented-control-button-active-bg,#21262d));}/*!sc*/\n.iDBPxb:focus:focus-visible:not(:last-child):after{width:0;}/*!sc*/\n.iDBPxb .segmentedControl-text:after{content:\"Blame\";display:block;font-weight:600;height:0;overflow:hidden;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;visibility:hidden;}/*!sc*/\n@media (pointer:coarse){.iDBPxb:before{content:\"\";position:absolute;left:0;right:0;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%);top:50%;min-height:44px;}}/*!sc*/\ndata-styled.g69[id=\"SegmentedControlButton__SegmentedControlButtonStyled-sc-8lkgxl-0\"]{content:\"kNvrzW,iDBPxb,\"}/*!sc*/\n.dlXtLG{background-color:var(--controlTrack-bgColor-rest,var(--color-segmented-control-bg,rgba(110,118,129,0.1)));border-radius:6px;display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;font-size:14px;height:28px;margin:0;padding:0;}/*!sc*/\ndata-styled.g71[id=\"SegmentedControl__SegmentedControlList-sc-1rzig82-0\"]{content:\"dlXtLG,\"}/*!sc*/\n.dcpVHE{list-style:none;padding:0;margin:0;}/*!sc*/\n.dcpVHE .PRIVATE_TreeView-item{outline:none;}/*!sc*/\n.dcpVHE .PRIVATE_TreeView-item:focus-visible > div,.dcpVHE .PRIVATE_TreeView-item.focus-visible > div{box-shadow:inset 0 0 0 2px var(--fgColor-accent,var(--color-accent-fg,#2f81f7));}/*!sc*/\n@media (forced-colors:active){.dcpVHE .PRIVATE_TreeView-item:focus-visible > div,.dcpVHE .PRIVATE_TreeView-item.focus-visible > div{outline:2px solid HighlightText;outline-offset:-2;}}/*!sc*/\n.dcpVHE .PRIVATE_TreeView-item-container{--level:1;--toggle-width:1rem;position:relative;display:grid;grid-template-columns:calc(calc(var(--level) - 1) * (var(--toggle-width) / 2)) var(--toggle-width) 1fr;grid-template-areas:'spacer toggle content';width:100%;min-height:2rem;font-size:14px;color:var(--fgColor-default,var(--color-fg-default,#e6edf3));border-radius:6px;cursor:pointer;}/*!sc*/\n.dcpVHE .PRIVATE_TreeView-item-container:hover{background-color:var(--control-transparent-bgColor-hover,var(--color-action-list-item-default-hover-bg,rgba(177,186,196,0.12)));}/*!sc*/\n@media (forced-colors:active){.dcpVHE .PRIVATE_TreeView-item-container:hover{outline:2px solid transparent;outline-offset:-2px;}}/*!sc*/\n@media (pointer:coarse){.dcpVHE .PRIVATE_TreeView-item-container{--toggle-width:1.5rem;min-height:2.75rem;}}/*!sc*/\n.dcpVHE .PRIVATE_TreeView-item-container:has(.PRIVATE_TreeView-item-skeleton):hover{background-color:transparent;cursor:default;}/*!sc*/\n@media (forced-colors:active){.dcpVHE .PRIVATE_TreeView-item-container:has(.PRIVATE_TreeView-item-skeleton):hover{outline:none;}}/*!sc*/\n.dcpVHE[data-omit-spacer='true'] .PRIVATE_TreeView-item-container{grid-template-columns:0 0 1fr;}/*!sc*/\n.dcpVHE .PRIVATE_TreeView-item[aria-current='true'] > .PRIVATE_TreeView-item-container{background-color:var(--control-transparent-bgColor-selected,var(--color-action-list-item-default-selected-bg,rgba(177,186,196,0.08)));}/*!sc*/\n.dcpVHE .PRIVATE_TreeView-item[aria-current='true'] > .PRIVATE_TreeView-item-container::after{content:'';position:absolute;top:calc(50% - 0.75rem);left:-8px;width:0.25rem;height:1.5rem;background-color:var(--fgColor-accent,var(--color-accent-fg,#2f81f7));border-radius:6px;}/*!sc*/\n@media (forced-colors:active){.dcpVHE .PRIVATE_TreeView-item[aria-current='true'] > .PRIVATE_TreeView-item-container::after{background-color:HighlightText;}}/*!sc*/\n.dcpVHE .PRIVATE_TreeView-item-toggle{grid-area:toggle;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;height:100%;color:var(--fgColor-muted,var(--color-fg-muted,#848d97));}/*!sc*/\n.dcpVHE .PRIVATE_TreeView-item-toggle--hover:hover{background-color:var(--control-transparent-bgColor-hover,var(--color-tree-view-item-chevron-hover-bg,rgba(177,186,196,0.12)));}/*!sc*/\n.dcpVHE .PRIVATE_TreeView-item-toggle--end{border-top-left-radius:6px;border-bottom-left-radius:6px;}/*!sc*/\n.dcpVHE .PRIVATE_TreeView-item-content{grid-area:content;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;height:100%;padding:0 8px;gap:8px;}/*!sc*/\n.dcpVHE .PRIVATE_TreeView-item-content-text{-webkit-flex:1 1 auto;-ms-flex:1 1 auto;flex:1 1 auto;width:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}/*!sc*/\n.dcpVHE .PRIVATE_TreeView-item-visual{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;color:var(--fgColor-muted,var(--color-fg-muted,#848d97));}/*!sc*/\n.dcpVHE .PRIVATE_TreeView-item-level-line{width:100%;height:100%;border-right:1px solid;border-color:var(--borderColor-muted,var(--color-border-subtle,rgba(240,246,252,0.1)));}/*!sc*/\n@media (hover:hover){.dcpVHE .PRIVATE_TreeView-item-level-line{border-color:transparent;}.dcpVHE:hover .PRIVATE_TreeView-item-level-line,.dcpVHE:focus-within .PRIVATE_TreeView-item-level-line{border-color:var(--borderColor-muted,var(--color-border-subtle,rgba(240,246,252,0.1)));}}/*!sc*/\n.dcpVHE .PRIVATE_TreeView-directory-icon{display:grid;color:var(--treeViewItem-leadingVisual-bgColor-rest,var(--color-tree-view-item-directory-fill,#848d97));}/*!sc*/\n.dcpVHE .PRIVATE_VisuallyHidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;-webkit-clip:rect(0,0,0,0);clip:rect(0,0,0,0);white-space:nowrap;border-width:0;}/*!sc*/\ndata-styled.g85[id=\"TreeView__UlBox-sc-4ex6b6-0\"]{content:\"dcpVHE,\"}/*!sc*/\n.cjbBGq{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;vertical-align:middle;isolation:isolate;}/*!sc*/\n.cjbBGq.cjbBGq > *{margin-inline-end:-1px;position:relative;border-radius:0;}/*!sc*/\n.cjbBGq.cjbBGq > *:first-child{border-top-left-radius:6px;border-bottom-left-radius:6px;}/*!sc*/\n.cjbBGq.cjbBGq > *:last-child{border-top-right-radius:6px;border-bottom-right-radius:6px;}/*!sc*/\n.cjbBGq.cjbBGq > *:focus,.cjbBGq.cjbBGq > *:active,.cjbBGq.cjbBGq > *:hover{z-index:1;}/*!sc*/\ndata-styled.g87[id=\"ButtonGroup-sc-1gxhls1-0\"]{content:\"cjbBGq,\"}/*!sc*/\n</style><meta data-hydrostats=\"publish\"/> <!-- --> <!-- --> <!-- --> <button hidden=\"\" data-testid=\"header-permalink-button\" data-hotkey-scope=\"read-only-cursor-text-area\"></button><button hidden=\"\"></button><div><div style=\"--sticky-pane-height:100vh\" class=\"Box-sc-g0xbh4-0 fSWWem\"><div class=\"Box-sc-g0xbh4-0 kPPmzM\"><div class=\"Box-sc-g0xbh4-0 cIAPDV\"><div tabindex=\"0\" class=\"Box-sc-g0xbh4-0 gvCnwW\"><div class=\"Box-sc-g0xbh4-0 heUiss\"><div class=\"Box-sc-g0xbh4-0 eUyHuk\"></div><div style=\"--pane-width:320px\" class=\"Box-sc-g0xbh4-0 gNdDUH\"><div class=\"Box-sc-g0xbh4-0 react-tree-pane-contents-3-panel\"><div id=\"repos-file-tree\" class=\"Box-sc-g0xbh4-0 jywUSN\"><div class=\"Box-sc-g0xbh4-0 hBSSUC\"><div class=\"Box-sc-g0xbh4-0 iPurHz\"><h2 class=\"Heading__StyledHeading-sc-1c1dgg0-0 jUriTl\"><button style=\"--button-color:fg.muted\" type=\"button\" aria-label=\"Expand file tree\" data-testid=\"expand-file-tree-button-mobile\" class=\"types__StyledButton-sc-ws60qy-0 iKABXH\"><span data-component=\"buttonContent\" class=\"Box-sc-g0xbh4-0 kkrdEu\"><span data-component=\"leadingVisual\" class=\"Box-sc-g0xbh4-0 trpoQ\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-arrow-left\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M7.78 12.53a.75.75 0 0 1-1.06 0L2.47 8.28a.75.75 0 0 1 0-1.06l4.25-4.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L4.81 7h7.44a.75.75 0 0 1 0 1.5H4.81l2.97 2.97a.75.75 0 0 1 0 1.06Z\"></path></svg></span><span data-component=\"text\">Files</span></span></button><span role=\"tooltip\" aria-label=\"Collapse file tree\" id=\"expand-button-file-tree-button\" class=\"Tooltip__TooltipBase-sc-17tf59c-0 izAlVj tooltipped-se\"><button data-component=\"IconButton\" type=\"button\" data-testid=\"collapse-file-tree-button\" aria-labelledby=\"expand-button-file-tree-button\" aria-expanded=\"true\" aria-controls=\"repos-file-tree\" class=\"types__StyledButton-sc-ws60qy-0 hfWObv\" data-no-visuals=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-sidebar-expand\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"m4.177 7.823 2.396-2.396A.25.25 0 0 1 7 5.604v4.792a.25.25 0 0 1-.427.177L4.177 8.177a.25.25 0 0 1 0-.354Z\"></path><path d=\"M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25H9.5v-13Zm12.5 13a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25H11v13Z\"></path></svg></button></span><button hidden=\"\" data-testid=\"\" data-hotkey-scope=\"read-only-cursor-text-area\"></button></h2><h2 class=\"Heading__StyledHeading-sc-1c1dgg0-0 imcwCi\">Files</h2></div><div class=\"Box-sc-g0xbh4-0 hVHHYa\"><div class=\"Box-sc-g0xbh4-0 idZfsJ\"><button type=\"button\" id=\"branch-picker-repos-header-ref-selector\" aria-haspopup=\"true\" tabindex=\"0\" aria-label=\"main branch\" data-testid=\"anchor-button\" class=\"types__StyledButton-sc-ws60qy-0 gBsjGI react-repos-tree-pane-ref-selector width-full ref-selector-class\"><span data-component=\"buttonContent\" class=\"Box-sc-g0xbh4-0 kkrdEu\"><span data-component=\"text\"><div class=\"Box-sc-g0xbh4-0 bKgizp\"><div class=\"Box-sc-g0xbh4-0 dIAShY\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-git-branch\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M9.5 3.25a2.25 2.25 0 1 1 3 2.122V6A2.5 2.5 0 0 1 10 8.5H6a1 1 0 0 0-1 1v1.128a2.251 2.251 0 1 1-1.5 0V5.372a2.25 2.25 0 1 1 1.5 0v1.836A2.493 2.493 0 0 1 6 7h4a1 1 0 0 0 1-1v-.628A2.25 2.25 0 0 1 9.5 3.25Zm-6 0a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Zm8.25-.75a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5ZM4.25 12a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Z\"></path></svg></div><div class=\"Box-sc-g0xbh4-0 caeYDk ref-selector-button-text-container\"><span class=\"Text-sc-17v1xeu-0 bOMzPg\"> <!-- -->main</span></div></div></span><span data-component=\"trailingVisual\" class=\"Box-sc-g0xbh4-0 trpoQ\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-triangle-down\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"m4.427 7.427 3.396 3.396a.25.25 0 0 0 .354 0l3.396-3.396A.25.25 0 0 0 11.396 7H4.604a.25.25 0 0 0-.177.427Z\"></path></svg></span></span></button><button hidden=\"\" data-hotkey-scope=\"read-only-cursor-text-area\"></button></div><div class=\"Box-sc-g0xbh4-0 jahcnb\"><span role=\"tooltip\" aria-label=\"Add file\" id=\":Rq6mplaeb:\" class=\"Tooltip__TooltipBase-sc-17tf59c-0 izAlVj tooltipped-s\"><a sx=\"[object Object]\" data-component=\"IconButton\" type=\"button\" aria-label=\"Add file\" data-no-visuals=\"true\" class=\"types__StyledButton-sc-ws60qy-0 XJZbf\" href=\"/mouredev/roadmap-retos-programacion/new/main/Roadmap/00%20-%20SINTAXIS%2C%20VARIABLES%2C%20TIPOS%20DE%20DATOS%20Y%20HOLA%20MUNDO/php\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-plus\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M7.75 2a.75.75 0 0 1 .75.75V7h4.25a.75.75 0 0 1 0 1.5H8.5v4.25a.75.75 0 0 1-1.5 0V8.5H2.75a.75.75 0 0 1 0-1.5H7V2.75A.75.75 0 0 1 7.75 2Z\"></path></svg></a></span><button data-component=\"IconButton\" type=\"button\" aria-label=\"Search this repository\" data-no-visuals=\"true\" class=\"types__StyledButton-sc-ws60qy-0 cBjhIZ\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-search\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M10.68 11.74a6 6 0 0 1-7.922-8.982 6 6 0 0 1 8.982 7.922l3.04 3.04a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215ZM11.5 7a4.499 4.499 0 1 0-8.997 0A4.499 4.499 0 0 0 11.5 7Z\"></path></svg></button><button hidden=\"\" data-testid=\"\" data-hotkey-scope=\"read-only-cursor-text-area\"></button></div></div></div><div class=\"Box-sc-g0xbh4-0 ccToMy\"><span class=\"TextInputWrapper__TextInputBaseWrapper-sc-1mqhpbi-0 TextInputWrapper-sc-1mqhpbi-1 kbCZWh jxgrJS TextInput-wrapper\" aria-busy=\"false\"><span class=\"TextInput-icon\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-search\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M10.68 11.74a6 6 0 0 1-7.922-8.982 6 6 0 0 1 8.982 7.922l3.04 3.04a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215ZM11.5 7a4.499 4.499 0 1 0-8.997 0A4.499 4.499 0 0 0 11.5 7Z\"></path></svg></span><input type=\"text\" aria-label=\"Go to file\" role=\"combobox\" aria-controls=\"file-results-list\" aria-expanded=\"false\" aria-haspopup=\"dialog\" autoCorrect=\"off\" spellcheck=\"false\" placeholder=\"Go to file\" data-component=\"input\" class=\"UnstyledTextInput-sc-14ypya-0 cDLBls\" value=\"\"/><span class=\"TextInput-icon\"><div class=\"Box-sc-g0xbh4-0 cNvKlH\"><kbd>t</kbd></div></span></span></div><button hidden=\"\" data-testid=\"\" data-hotkey-scope=\"read-only-cursor-text-area\"></button><button hidden=\"\"></button><div class=\"Box-sc-g0xbh4-0 cLfAnm\"><div class=\"react-tree-show-tree-items\"><div data-testid=\"repos-file-tree-container\" class=\"Box-sc-g0xbh4-0 erWCJP\"><nav aria-label=\"File Tree Navigation\"><span role=\"status\" aria-live=\"polite\" aria-atomic=\"true\" class=\"_VisuallyHidden__VisuallyHidden-sc-11jhm7a-0 rTZSs\"></span><ul role=\"tree\" aria-label=\"Files\" class=\"TreeView__UlBox-sc-4ex6b6-0 dcpVHE\"><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\".github-item\" role=\"treeitem\" aria-labelledby=\":R39implaeb:\" aria-describedby=\":R39implaebH1: :R39implaebH2:\" aria-level=\"1\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:1;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover PRIVATE_TreeView-item-toggle--end\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":R39implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R39implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>.github</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Images-item\" role=\"treeitem\" aria-labelledby=\":R59implaeb:\" aria-describedby=\":R59implaebH1: :R59implaebH2:\" aria-level=\"1\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:1;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover PRIVATE_TreeView-item-toggle--end\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":R59implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R59implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>Images</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap-item\" role=\"treeitem\" aria-labelledby=\":R79implaeb:\" aria-describedby=\":R79implaebH1: :R79implaebH2:\" aria-level=\"1\" aria-expanded=\"true\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:1;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover PRIVATE_TreeView-item-toggle--end\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-down\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M6 8.825c-.2 0-.4-.1-.5-.2l-3.3-3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l2.7 2.7 2.7-2.7c.3-.3.8-.3 1.1 0 .3.3.3.8 0 1.1l-3.2 3.2c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":R79implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R79implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-open-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M.513 1.513A1.75 1.75 0 0 1 1.75 1h3.5c.55 0 1.07.26 1.4.7l.9 1.2a.25.25 0 0 0 .2.1H13a1 1 0 0 1 1 1v.5H2.75a.75.75 0 0 0 0 1.5h11.978a1 1 0 0 1 .994 1.117L15 13.25A1.75 1.75 0 0 1 13.25 15H1.75A1.75 1.75 0 0 1 0 13.25V2.75c0-.464.184-.91.513-1.237Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>Roadmap</span></span></div></div><ul role=\"group\" style=\"list-style:none;padding:0;margin:0\"><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO-item\" role=\"treeitem\" aria-labelledby=\":Rmn9implaeb:\" aria-describedby=\":Rmn9implaebH1: :Rmn9implaebH2:\" aria-level=\"2\" aria-expanded=\"true\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:2;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-down\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M6 8.825c-.2 0-.4-.1-.5-.2l-3.3-3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l2.7 2.7 2.7-2.7c.3-.3.8-.3 1.1 0 .3.3.3.8 0 1.1l-3.2 3.2c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":Rmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":Rmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-open-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M.513 1.513A1.75 1.75 0 0 1 1.75 1h3.5c.55 0 1.07.26 1.4.7l.9 1.2a.25.25 0 0 0 .2.1H13a1 1 0 0 1 1 1v.5H2.75a.75.75 0 0 0 0 1.5h11.978a1 1 0 0 1 .994 1.117L15 13.25A1.75 1.75 0 0 1 13.25 15H1.75A1.75 1.75 0 0 1 0 13.25V2.75c0-.464.184-.91.513-1.237Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO</span></span></div></div><ul role=\"group\" style=\"list-style:none;padding:0;margin:0\"><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/abap-item\" role=\"treeitem\" aria-labelledby=\":Rmgmn9implaeb:\" aria-describedby=\":Rmgmn9implaebH1: :Rmgmn9implaebH2:\" aria-level=\"3\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:3;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":Rmgmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":Rmgmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>abap</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/ada-item\" role=\"treeitem\" aria-labelledby=\":R16gmn9implaeb:\" aria-describedby=\":R16gmn9implaebH1: :R16gmn9implaebH2:\" aria-level=\"3\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:3;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":R16gmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R16gmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>ada</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/al-item\" role=\"treeitem\" aria-labelledby=\":R1mgmn9implaeb:\" aria-describedby=\":R1mgmn9implaebH1: :R1mgmn9implaebH2:\" aria-level=\"3\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:3;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":R1mgmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R1mgmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>al</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/arduino-item\" role=\"treeitem\" aria-labelledby=\":R26gmn9implaeb:\" aria-describedby=\":R26gmn9implaebH1: :R26gmn9implaebH2:\" aria-level=\"3\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:3;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":R26gmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R26gmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>arduino</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/bash-item\" role=\"treeitem\" aria-labelledby=\":R2mgmn9implaeb:\" aria-describedby=\":R2mgmn9implaebH1: :R2mgmn9implaebH2:\" aria-level=\"3\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:3;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":R2mgmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R2mgmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>bash</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c#-item\" role=\"treeitem\" aria-labelledby=\":R36gmn9implaeb:\" aria-describedby=\":R36gmn9implaebH1: :R36gmn9implaebH2:\" aria-level=\"3\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:3;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":R36gmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R36gmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>c#</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c++-item\" role=\"treeitem\" aria-labelledby=\":R3mgmn9implaeb:\" aria-describedby=\":R3mgmn9implaebH1: :R3mgmn9implaebH2:\" aria-level=\"3\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:3;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":R3mgmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R3mgmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>c++</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/c-item\" role=\"treeitem\" aria-labelledby=\":R46gmn9implaeb:\" aria-describedby=\":R46gmn9implaebH1: :R46gmn9implaebH2:\" aria-level=\"3\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:3;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":R46gmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R46gmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>c</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/cobol-item\" role=\"treeitem\" aria-labelledby=\":R4mgmn9implaeb:\" aria-describedby=\":R4mgmn9implaebH1: :R4mgmn9implaebH2:\" aria-level=\"3\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:3;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":R4mgmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R4mgmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>cobol</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/dart-item\" role=\"treeitem\" aria-labelledby=\":R56gmn9implaeb:\" aria-describedby=\":R56gmn9implaebH1: :R56gmn9implaebH2:\" aria-level=\"3\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:3;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":R56gmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R56gmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>dart</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/erlang-item\" role=\"treeitem\" aria-labelledby=\":R5mgmn9implaeb:\" aria-describedby=\":R5mgmn9implaebH1: :R5mgmn9implaebH2:\" aria-level=\"3\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:3;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":R5mgmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R5mgmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>erlang</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/fortran-item\" role=\"treeitem\" aria-labelledby=\":R66gmn9implaeb:\" aria-describedby=\":R66gmn9implaebH1: :R66gmn9implaebH2:\" aria-level=\"3\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:3;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":R66gmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R66gmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>fortran</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/go-item\" role=\"treeitem\" aria-labelledby=\":R6mgmn9implaeb:\" aria-describedby=\":R6mgmn9implaebH1: :R6mgmn9implaebH2:\" aria-level=\"3\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:3;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":R6mgmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R6mgmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>go</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/harbour-item\" role=\"treeitem\" aria-labelledby=\":R76gmn9implaeb:\" aria-describedby=\":R76gmn9implaebH1: :R76gmn9implaebH2:\" aria-level=\"3\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:3;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":R76gmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R76gmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>harbour</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/haskell-item\" role=\"treeitem\" aria-labelledby=\":R7mgmn9implaeb:\" aria-describedby=\":R7mgmn9implaebH1: :R7mgmn9implaebH2:\" aria-level=\"3\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:3;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":R7mgmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R7mgmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>haskell</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/java-item\" role=\"treeitem\" aria-labelledby=\":R86gmn9implaeb:\" aria-describedby=\":R86gmn9implaebH1: :R86gmn9implaebH2:\" aria-level=\"3\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:3;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":R86gmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R86gmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>java</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/javascript-item\" role=\"treeitem\" aria-labelledby=\":R8mgmn9implaeb:\" aria-describedby=\":R8mgmn9implaebH1: :R8mgmn9implaebH2:\" aria-level=\"3\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:3;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":R8mgmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R8mgmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>javascript</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/julia-item\" role=\"treeitem\" aria-labelledby=\":R96gmn9implaeb:\" aria-describedby=\":R96gmn9implaebH1: :R96gmn9implaebH2:\" aria-level=\"3\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:3;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":R96gmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R96gmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>julia</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/kotlin-item\" role=\"treeitem\" aria-labelledby=\":R9mgmn9implaeb:\" aria-describedby=\":R9mgmn9implaebH1: :R9mgmn9implaebH2:\" aria-level=\"3\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:3;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":R9mgmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R9mgmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>kotlin</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/lua-item\" role=\"treeitem\" aria-labelledby=\":Ra6gmn9implaeb:\" aria-describedby=\":Ra6gmn9implaebH1: :Ra6gmn9implaebH2:\" aria-level=\"3\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:3;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":Ra6gmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":Ra6gmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>lua</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/mojo-item\" role=\"treeitem\" aria-labelledby=\":Ramgmn9implaeb:\" aria-describedby=\":Ramgmn9implaebH1: :Ramgmn9implaebH2:\" aria-level=\"3\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:3;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":Ramgmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":Ramgmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>mojo</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/nasm-item\" role=\"treeitem\" aria-labelledby=\":Rb6gmn9implaeb:\" aria-describedby=\":Rb6gmn9implaebH1: :Rb6gmn9implaebH2:\" aria-level=\"3\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:3;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":Rb6gmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":Rb6gmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>nasm</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/objectivec-item\" role=\"treeitem\" aria-labelledby=\":Rbmgmn9implaeb:\" aria-describedby=\":Rbmgmn9implaebH1: :Rbmgmn9implaebH2:\" aria-level=\"3\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:3;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":Rbmgmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":Rbmgmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>objectivec</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/ocaml-item\" role=\"treeitem\" aria-labelledby=\":Rc6gmn9implaeb:\" aria-describedby=\":Rc6gmn9implaebH1: :Rc6gmn9implaebH2:\" aria-level=\"3\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:3;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":Rc6gmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":Rc6gmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>ocaml</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/pascal-item\" role=\"treeitem\" aria-labelledby=\":Rcmgmn9implaeb:\" aria-describedby=\":Rcmgmn9implaebH1: :Rcmgmn9implaebH2:\" aria-level=\"3\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:3;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":Rcmgmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":Rcmgmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>pascal</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php-item\" role=\"treeitem\" aria-labelledby=\":Rd6gmn9implaeb:\" aria-describedby=\":Rd6gmn9implaebH1: :Rd6gmn9implaebH2:\" aria-level=\"3\" aria-expanded=\"true\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:3;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-down\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M6 8.825c-.2 0-.4-.1-.5-.2l-3.3-3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l2.7 2.7 2.7-2.7c.3-.3.8-.3 1.1 0 .3.3.3.8 0 1.1l-3.2 3.2c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":Rd6gmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":Rd6gmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-open-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M.513 1.513A1.75 1.75 0 0 1 1.75 1h3.5c.55 0 1.07.26 1.4.7l.9 1.2a.25.25 0 0 0 .2.1H13a1 1 0 0 1 1 1v.5H2.75a.75.75 0 0 0 0 1.5h11.978a1 1 0 0 1 .994 1.117L15 13.25A1.75 1.75 0 0 1 13.25 15H1.75A1.75 1.75 0 0 1 0 13.25V2.75c0-.464.184-.91.513-1.237Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>php</span></span></div></div><ul role=\"group\" style=\"list-style:none;padding:0;margin:0\"><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/BertoMP.php-item\" role=\"treeitem\" aria-labelledby=\":R1dd6gmn9implaeb:\" aria-describedby=\":R1dd6gmn9implaebH1: :R1dd6gmn9implaebH2:\" aria-level=\"4\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:4;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div id=\":R1dd6gmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R1dd6gmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-file\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 9 4.25V1.5Zm6.75.062V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z\"></path></svg></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>BertoMP.php</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/BrunoM-93.php-item\" role=\"treeitem\" aria-labelledby=\":R2dd6gmn9implaeb:\" aria-describedby=\":R2dd6gmn9implaebH1: :R2dd6gmn9implaebH2:\" aria-level=\"4\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:4;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div id=\":R2dd6gmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R2dd6gmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-file\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 9 4.25V1.5Zm6.75.062V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z\"></path></svg></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>BrunoM-93.php</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/Bryan112094.php-item\" role=\"treeitem\" aria-labelledby=\":R3dd6gmn9implaeb:\" aria-describedby=\":R3dd6gmn9implaebH1: :R3dd6gmn9implaebH2:\" aria-level=\"4\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:4;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div id=\":R3dd6gmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R3dd6gmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-file\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 9 4.25V1.5Zm6.75.062V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z\"></path></svg></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>Bryan112094.php</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/Edm1ya.php-item\" role=\"treeitem\" aria-labelledby=\":R4dd6gmn9implaeb:\" aria-describedby=\":R4dd6gmn9implaebH1: :R4dd6gmn9implaebH2:\" aria-level=\"4\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:4;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div id=\":R4dd6gmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R4dd6gmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-file\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 9 4.25V1.5Zm6.75.062V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z\"></path></svg></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>Edm1ya.php</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/GitHjuan.php-item\" role=\"treeitem\" aria-labelledby=\":R5dd6gmn9implaeb:\" aria-describedby=\":R5dd6gmn9implaebH1: :R5dd6gmn9implaebH2:\" aria-level=\"4\" aria-current=\"true\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:4\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div id=\":R5dd6gmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R5dd6gmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-file\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 9 4.25V1.5Zm6.75.062V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z\"></path></svg></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>GitHjuan.php</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/Hugovrc.php-item\" role=\"treeitem\" aria-labelledby=\":R6dd6gmn9implaeb:\" aria-describedby=\":R6dd6gmn9implaebH1: :R6dd6gmn9implaebH2:\" aria-level=\"4\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:4;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div id=\":R6dd6gmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R6dd6gmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-file\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 9 4.25V1.5Zm6.75.062V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z\"></path></svg></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>Hugovrc.php</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/JaimeSoftDev.php-item\" role=\"treeitem\" aria-labelledby=\":R7dd6gmn9implaeb:\" aria-describedby=\":R7dd6gmn9implaebH1: :R7dd6gmn9implaebH2:\" aria-level=\"4\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:4;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div id=\":R7dd6gmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R7dd6gmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-file\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 9 4.25V1.5Zm6.75.062V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z\"></path></svg></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>JaimeSoftDev.php</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/JehiselRuth.php-item\" role=\"treeitem\" aria-labelledby=\":R8dd6gmn9implaeb:\" aria-describedby=\":R8dd6gmn9implaebH1: :R8dd6gmn9implaebH2:\" aria-level=\"4\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:4;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div id=\":R8dd6gmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R8dd6gmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-file\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 9 4.25V1.5Zm6.75.062V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z\"></path></svg></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>JehiselRuth.php</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/alejandroruiz23.php-item\" role=\"treeitem\" aria-labelledby=\":R9dd6gmn9implaeb:\" aria-describedby=\":R9dd6gmn9implaebH1: :R9dd6gmn9implaebH2:\" aria-level=\"4\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:4;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div id=\":R9dd6gmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R9dd6gmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-file\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 9 4.25V1.5Zm6.75.062V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z\"></path></svg></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>alejandroruiz23.php</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/gabrielmoris.php-item\" role=\"treeitem\" aria-labelledby=\":Radd6gmn9implaeb:\" aria-describedby=\":Radd6gmn9implaebH1: :Radd6gmn9implaebH2:\" aria-level=\"4\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:4;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div id=\":Radd6gmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":Radd6gmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-file\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 9 4.25V1.5Zm6.75.062V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z\"></path></svg></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>gabrielmoris.php</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/guido2288.php-item\" role=\"treeitem\" aria-labelledby=\":Rbdd6gmn9implaeb:\" aria-describedby=\":Rbdd6gmn9implaebH1: :Rbdd6gmn9implaebH2:\" aria-level=\"4\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:4;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div id=\":Rbdd6gmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":Rbdd6gmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-file\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 9 4.25V1.5Zm6.75.062V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z\"></path></svg></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>guido2288.php</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/jarzatedev.php-item\" role=\"treeitem\" aria-labelledby=\":Rcdd6gmn9implaeb:\" aria-describedby=\":Rcdd6gmn9implaebH1: :Rcdd6gmn9implaebH2:\" aria-level=\"4\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:4;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div id=\":Rcdd6gmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":Rcdd6gmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-file\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 9 4.25V1.5Zm6.75.062V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z\"></path></svg></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>jarzatedev.php</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/johannhsdev.php-item\" role=\"treeitem\" aria-labelledby=\":Rddd6gmn9implaeb:\" aria-describedby=\":Rddd6gmn9implaebH1: :Rddd6gmn9implaebH2:\" aria-level=\"4\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:4;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div id=\":Rddd6gmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":Rddd6gmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-file\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 9 4.25V1.5Zm6.75.062V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z\"></path></svg></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>johannhsdev.php</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/kodenook.php-item\" role=\"treeitem\" aria-labelledby=\":Redd6gmn9implaeb:\" aria-describedby=\":Redd6gmn9implaebH1: :Redd6gmn9implaebH2:\" aria-level=\"4\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:4;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div id=\":Redd6gmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":Redd6gmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-file\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 9 4.25V1.5Zm6.75.062V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z\"></path></svg></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>kodenook.php</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/marcode24.php-item\" role=\"treeitem\" aria-labelledby=\":Rfdd6gmn9implaeb:\" aria-describedby=\":Rfdd6gmn9implaebH1: :Rfdd6gmn9implaebH2:\" aria-level=\"4\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:4;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div id=\":Rfdd6gmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":Rfdd6gmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-file\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 9 4.25V1.5Zm6.75.062V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z\"></path></svg></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>marcode24.php</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/mayerga.php-item\" role=\"treeitem\" aria-labelledby=\":Rgdd6gmn9implaeb:\" aria-describedby=\":Rgdd6gmn9implaebH1: :Rgdd6gmn9implaebH2:\" aria-level=\"4\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:4;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div id=\":Rgdd6gmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":Rgdd6gmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-file\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 9 4.25V1.5Zm6.75.062V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z\"></path></svg></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>mayerga.php</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/mensius87.php-item\" role=\"treeitem\" aria-labelledby=\":Rhdd6gmn9implaeb:\" aria-describedby=\":Rhdd6gmn9implaebH1: :Rhdd6gmn9implaebH2:\" aria-level=\"4\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:4;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div id=\":Rhdd6gmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":Rhdd6gmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-file\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 9 4.25V1.5Zm6.75.062V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z\"></path></svg></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>mensius87.php</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/miguelex.php-item\" role=\"treeitem\" aria-labelledby=\":Ridd6gmn9implaeb:\" aria-describedby=\":Ridd6gmn9implaebH1: :Ridd6gmn9implaebH2:\" aria-level=\"4\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:4;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div id=\":Ridd6gmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":Ridd6gmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-file\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 9 4.25V1.5Zm6.75.062V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z\"></path></svg></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>miguelex.php</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/pabloTaber.php-item\" role=\"treeitem\" aria-labelledby=\":Rjdd6gmn9implaeb:\" aria-describedby=\":Rjdd6gmn9implaebH1: :Rjdd6gmn9implaebH2:\" aria-level=\"4\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:4;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div id=\":Rjdd6gmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":Rjdd6gmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-file\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 9 4.25V1.5Zm6.75.062V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z\"></path></svg></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>pabloTaber.php</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/rocallejas.php-item\" role=\"treeitem\" aria-labelledby=\":Rkdd6gmn9implaeb:\" aria-describedby=\":Rkdd6gmn9implaebH1: :Rkdd6gmn9implaebH2:\" aria-level=\"4\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:4;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div id=\":Rkdd6gmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":Rkdd6gmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-file\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 9 4.25V1.5Zm6.75.062V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z\"></path></svg></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>rocallejas.php</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/trollface77.php-item\" role=\"treeitem\" aria-labelledby=\":Rldd6gmn9implaeb:\" aria-describedby=\":Rldd6gmn9implaebH1: :Rldd6gmn9implaebH2:\" aria-level=\"4\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:4;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div id=\":Rldd6gmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":Rldd6gmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-file\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 9 4.25V1.5Zm6.75.062V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z\"></path></svg></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>trollface77.php</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/zarakilancelot.php-item\" role=\"treeitem\" aria-labelledby=\":Rmdd6gmn9implaeb:\" aria-describedby=\":Rmdd6gmn9implaebH1: :Rmdd6gmn9implaebH2:\" aria-level=\"4\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:4;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div id=\":Rmdd6gmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":Rmdd6gmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-file\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 9 4.25V1.5Zm6.75.062V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z\"></path></svg></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>zarakilancelot.php</span></span></div></div></li></ul></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/prolog-item\" role=\"treeitem\" aria-labelledby=\":Rdmgmn9implaeb:\" aria-describedby=\":Rdmgmn9implaebH1: :Rdmgmn9implaebH2:\" aria-level=\"3\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:3;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":Rdmgmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":Rdmgmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>prolog</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python-item\" role=\"treeitem\" aria-labelledby=\":Re6gmn9implaeb:\" aria-describedby=\":Re6gmn9implaebH1: :Re6gmn9implaebH2:\" aria-level=\"3\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:3;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":Re6gmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":Re6gmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>python</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/r-item\" role=\"treeitem\" aria-labelledby=\":Remgmn9implaeb:\" aria-describedby=\":Remgmn9implaebH1: :Remgmn9implaebH2:\" aria-level=\"3\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:3;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":Remgmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":Remgmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>r</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/racket-item\" role=\"treeitem\" aria-labelledby=\":Rf6gmn9implaeb:\" aria-describedby=\":Rf6gmn9implaebH1: :Rf6gmn9implaebH2:\" aria-level=\"3\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:3;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":Rf6gmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":Rf6gmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>racket</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/ruby-item\" role=\"treeitem\" aria-labelledby=\":Rfmgmn9implaeb:\" aria-describedby=\":Rfmgmn9implaebH1: :Rfmgmn9implaebH2:\" aria-level=\"3\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:3;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":Rfmgmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":Rfmgmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>ruby</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/rust-item\" role=\"treeitem\" aria-labelledby=\":Rg6gmn9implaeb:\" aria-describedby=\":Rg6gmn9implaebH1: :Rg6gmn9implaebH2:\" aria-level=\"3\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:3;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":Rg6gmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":Rg6gmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>rust</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/scala-item\" role=\"treeitem\" aria-labelledby=\":Rgmgmn9implaeb:\" aria-describedby=\":Rgmgmn9implaebH1: :Rgmgmn9implaebH2:\" aria-level=\"3\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:3;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":Rgmgmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":Rgmgmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>scala</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/solidity-item\" role=\"treeitem\" aria-labelledby=\":Rh6gmn9implaeb:\" aria-describedby=\":Rh6gmn9implaebH1: :Rh6gmn9implaebH2:\" aria-level=\"3\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:3;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":Rh6gmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":Rh6gmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>solidity</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/sql-item\" role=\"treeitem\" aria-labelledby=\":Rhmgmn9implaeb:\" aria-describedby=\":Rhmgmn9implaebH1: :Rhmgmn9implaebH2:\" aria-level=\"3\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:3;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":Rhmgmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":Rhmgmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>sql</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/swift-item\" role=\"treeitem\" aria-labelledby=\":Ri6gmn9implaeb:\" aria-describedby=\":Ri6gmn9implaebH1: :Ri6gmn9implaebH2:\" aria-level=\"3\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:3;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":Ri6gmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":Ri6gmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>swift</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript-item\" role=\"treeitem\" aria-labelledby=\":Rimgmn9implaeb:\" aria-describedby=\":Rimgmn9implaebH1: :Rimgmn9implaebH2:\" aria-level=\"3\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:3;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":Rimgmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":Rimgmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>typescript</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/vb.net-item\" role=\"treeitem\" aria-labelledby=\":Rj6gmn9implaeb:\" aria-describedby=\":Rj6gmn9implaebH1: :Rj6gmn9implaebH2:\" aria-level=\"3\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:3;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":Rj6gmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":Rj6gmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>vb.net</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/ejercicio.md-item\" role=\"treeitem\" aria-labelledby=\":Rjmgmn9implaeb:\" aria-describedby=\":Rjmgmn9implaebH1: :Rjmgmn9implaebH2:\" aria-level=\"3\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:3;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div id=\":Rjmgmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":Rjmgmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-file\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 9 4.25V1.5Zm6.75.062V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z\"></path></svg></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>ejercicio.md</span></span></div></div></li></ul></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL-item\" role=\"treeitem\" aria-labelledby=\":R16n9implaeb:\" aria-describedby=\":R16n9implaebH1: :R16n9implaebH2:\" aria-level=\"2\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:2;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":R16n9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R16n9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>01 - OPERADORES Y ESTRUCTURAS DE CONTROL</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/02 - FUNCIONES Y ALCANCE-item\" role=\"treeitem\" aria-labelledby=\":R1mn9implaeb:\" aria-describedby=\":R1mn9implaebH1: :R1mn9implaebH2:\" aria-level=\"2\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:2;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":R1mn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R1mn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>02 - FUNCIONES Y ALCANCE</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/03 - ESTRUCTURAS DE DATOS-item\" role=\"treeitem\" aria-labelledby=\":R26n9implaeb:\" aria-describedby=\":R26n9implaebH1: :R26n9implaebH2:\" aria-level=\"2\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:2;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":R26n9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R26n9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>03 - ESTRUCTURAS DE DATOS</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/04 - CADENAS DE CARACTERES-item\" role=\"treeitem\" aria-labelledby=\":R2mn9implaeb:\" aria-describedby=\":R2mn9implaebH1: :R2mn9implaebH2:\" aria-level=\"2\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:2;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":R2mn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R2mn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>04 - CADENAS DE CARACTERES</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/05 - VALOR Y REFERENCIA-item\" role=\"treeitem\" aria-labelledby=\":R36n9implaeb:\" aria-describedby=\":R36n9implaebH1: :R36n9implaebH2:\" aria-level=\"2\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:2;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":R36n9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R36n9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>05 - VALOR Y REFERENCIA</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/06 - RECURSIVIDAD-item\" role=\"treeitem\" aria-labelledby=\":R3mn9implaeb:\" aria-describedby=\":R3mn9implaebH1: :R3mn9implaebH2:\" aria-level=\"2\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:2;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":R3mn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R3mn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>06 - RECURSIVIDAD</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/07 - PILAS Y COLAS-item\" role=\"treeitem\" aria-labelledby=\":R46n9implaeb:\" aria-describedby=\":R46n9implaebH1: :R46n9implaebH2:\" aria-level=\"2\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:2;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":R46n9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R46n9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>07 - PILAS Y COLAS</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/08 - CLASES-item\" role=\"treeitem\" aria-labelledby=\":R4mn9implaeb:\" aria-describedby=\":R4mn9implaebH1: :R4mn9implaebH2:\" aria-level=\"2\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:2;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":R4mn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R4mn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>08 - CLASES</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/09 - HERENCIA-item\" role=\"treeitem\" aria-labelledby=\":R56n9implaeb:\" aria-describedby=\":R56n9implaebH1: :R56n9implaebH2:\" aria-level=\"2\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:2;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":R56n9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R56n9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>09 - HERENCIA</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/10 - EXCEPCIONES-item\" role=\"treeitem\" aria-labelledby=\":R5mn9implaeb:\" aria-describedby=\":R5mn9implaebH1: :R5mn9implaebH2:\" aria-level=\"2\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:2;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":R5mn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R5mn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>10 - EXCEPCIONES</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/11 - MANEJO DE FICHEROS-item\" role=\"treeitem\" aria-labelledby=\":R66n9implaeb:\" aria-describedby=\":R66n9implaebH1: :R66n9implaebH2:\" aria-level=\"2\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:2;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":R66n9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R66n9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>11 - MANEJO DE FICHEROS</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/12 - JSON Y XML-item\" role=\"treeitem\" aria-labelledby=\":R6mn9implaeb:\" aria-describedby=\":R6mn9implaebH1: :R6mn9implaebH2:\" aria-level=\"2\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:2;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":R6mn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R6mn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>12 - JSON Y XML</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/13 - PRUEBAS UNITARIAS-item\" role=\"treeitem\" aria-labelledby=\":R76n9implaeb:\" aria-describedby=\":R76n9implaebH1: :R76n9implaebH2:\" aria-level=\"2\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:2;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":R76n9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R76n9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>13 - PRUEBAS UNITARIAS</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/14 - FECHAS-item\" role=\"treeitem\" aria-labelledby=\":R7mn9implaeb:\" aria-describedby=\":R7mn9implaebH1: :R7mn9implaebH2:\" aria-level=\"2\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:2;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":R7mn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R7mn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>14 - FECHAS</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/15 - ASINCRONÍA-item\" role=\"treeitem\" aria-labelledby=\":R86n9implaeb:\" aria-describedby=\":R86n9implaebH1: :R86n9implaebH2:\" aria-level=\"2\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:2;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":R86n9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R86n9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>15 - ASINCRONÍA</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/16 - EXPRESIONES REGULARES-item\" role=\"treeitem\" aria-labelledby=\":R8mn9implaeb:\" aria-describedby=\":R8mn9implaebH1: :R8mn9implaebH2:\" aria-level=\"2\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:2;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":R8mn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R8mn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>16 - EXPRESIONES REGULARES</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/17 - ITERACIONES-item\" role=\"treeitem\" aria-labelledby=\":R96n9implaeb:\" aria-describedby=\":R96n9implaebH1: :R96n9implaebH2:\" aria-level=\"2\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:2;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":R96n9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R96n9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>17 - ITERACIONES</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/18 - CONJUNTOS-item\" role=\"treeitem\" aria-labelledby=\":R9mn9implaeb:\" aria-describedby=\":R9mn9implaebH1: :R9mn9implaebH2:\" aria-level=\"2\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:2;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":R9mn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R9mn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>18 - CONJUNTOS</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/19 - ENUMERACIONES-item\" role=\"treeitem\" aria-labelledby=\":Ra6n9implaeb:\" aria-describedby=\":Ra6n9implaebH1: :Ra6n9implaebH2:\" aria-level=\"2\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:2;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":Ra6n9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":Ra6n9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>19 - ENUMERACIONES</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/20 - PETICIONES HTTP-item\" role=\"treeitem\" aria-labelledby=\":Ramn9implaeb:\" aria-describedby=\":Ramn9implaebH1: :Ramn9implaebH2:\" aria-level=\"2\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:2;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":Ramn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":Ramn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>20 - PETICIONES HTTP</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/21 - CALLBACKS-item\" role=\"treeitem\" aria-labelledby=\":Rb6n9implaeb:\" aria-describedby=\":Rb6n9implaebH1: :Rb6n9implaebH2:\" aria-level=\"2\" aria-expanded=\"false\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:2;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div class=\"PRIVATE_TreeView-item-toggle PRIVATE_TreeView-item-toggle--hover\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-chevron-right\" viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M4.7 10c-.2 0-.4-.1-.5-.2-.3-.3-.3-.8 0-1.1L6.9 6 4.2 3.3c-.3-.3-.3-.8 0-1.1.3-.3.8-.3 1.1 0l3.3 3.2c.3.3.3.8 0 1.1L5.3 9.7c-.2.2-.4.3-.6.3Z\"></path></svg></div><div id=\":Rb6n9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":Rb6n9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><div class=\"PRIVATE_TreeView-directory-icon\"><svg aria-hidden=\"true\" focusable=\"false\" class=\"octicon octicon-file-directory-fill\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z\"></path></svg></div></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>21 - CALLBACKS</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/stats.json-item\" role=\"treeitem\" aria-labelledby=\":Rbmn9implaeb:\" aria-describedby=\":Rbmn9implaebH1: :Rbmn9implaebH2:\" aria-level=\"2\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:2;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div id=\":Rbmn9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":Rbmn9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-file\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 9 4.25V1.5Zm6.75.062V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z\"></path></svg></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>stats.json</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"Roadmap/stats.py-item\" role=\"treeitem\" aria-labelledby=\":Rc6n9implaeb:\" aria-describedby=\":Rc6n9implaebH1: :Rc6n9implaebH2:\" aria-level=\"2\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:2;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"><div class=\"PRIVATE_TreeView-item-level-line\"></div></div></div><div id=\":Rc6n9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":Rc6n9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-file\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 9 4.25V1.5Zm6.75.062V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z\"></path></svg></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>stats.py</span></span></div></div></li></ul></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\".gitignore-item\" role=\"treeitem\" aria-labelledby=\":R99implaeb:\" aria-describedby=\":R99implaebH1: :R99implaebH2:\" aria-level=\"1\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:1;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"></div></div><div id=\":R99implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":R99implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-file\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 9 4.25V1.5Zm6.75.062V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z\"></path></svg></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>.gitignore</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"LICENSE-item\" role=\"treeitem\" aria-labelledby=\":Rb9implaeb:\" aria-describedby=\":Rb9implaebH1: :Rb9implaebH2:\" aria-level=\"1\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:1;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"></div></div><div id=\":Rb9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":Rb9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-file\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 9 4.25V1.5Zm6.75.062V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z\"></path></svg></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>LICENSE</span></span></div></div></li><li class=\"PRIVATE_TreeView-item\" tabindex=\"0\" id=\"README.md-item\" role=\"treeitem\" aria-labelledby=\":Rd9implaeb:\" aria-describedby=\":Rd9implaebH1: :Rd9implaebH2:\" aria-level=\"1\" aria-selected=\"false\"><div class=\"PRIVATE_TreeView-item-container\" style=\"--level:1;content-visibility:auto;contain-intrinsic-size:auto 2rem\"><div style=\"grid-area:spacer;display:flex\"><div style=\"width:100%;display:flex\"></div></div><div id=\":Rd9implaeb:\" class=\"PRIVATE_TreeView-item-content\"><div class=\"PRIVATE_VisuallyHidden\" aria-hidden=\"true\" id=\":Rd9implaebH1:\"></div><div class=\"PRIVATE_TreeView-item-visual\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-file\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 9 4.25V1.5Zm6.75.062V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z\"></path></svg></div><span class=\"PRIVATE_TreeView-item-content-text\"><span>README.md</span></span></div></div></li></ul></nav></div></div></div></div></div></div><div class=\"Box-sc-g0xbh4-0 hAeDYA\"><div role=\"slider\" aria-label=\"Draggable pane splitter\" aria-valuemin=\"0\" aria-valuemax=\"0\" aria-valuenow=\"0\" aria-valuetext=\"Pane width 0 pixels\" tabindex=\"0\" class=\"Box-sc-g0xbh4-0 gZHqlw\"></div></div></div></div><div class=\"Box-sc-g0xbh4-0 emFMJu\"><div class=\"Box-sc-g0xbh4-0\"></div><div class=\"Box-sc-g0xbh4-0 hlUAHL\"><div data-selector=\"repos-split-pane-content\" tabindex=\"0\" class=\"Box-sc-g0xbh4-0 iStsmI\"><div class=\"Box-sc-g0xbh4-0 eIgvIk\"><div class=\"Box-sc-g0xbh4-0 eVFfWF container\"><div class=\"px-3 pt-3 pb-0\" id=\"StickyHeader\"><div class=\"Box-sc-g0xbh4-0 fywjmm\"><div class=\"Box-sc-g0xbh4-0 dyczTK\"><div class=\"Box-sc-g0xbh4-0 kszRgZ\"><div class=\"Box-sc-g0xbh4-0 eTvGbF\"><nav data-testid=\"breadcrumbs\" aria-labelledby=\"repos-header-breadcrumb--wide-heading\" id=\"repos-header-breadcrumb--wide\" class=\"Box-sc-g0xbh4-0 kzRgrI\"><h2 class=\"Heading__StyledHeading-sc-1c1dgg0-0 cgQnMS sr-only\" data-testid=\"screen-reader-heading\" id=\"repos-header-breadcrumb--wide-heading\">Breadcrumbs</h2><ol class=\"Box-sc-g0xbh4-0 cmAPIB\"><li class=\"Box-sc-g0xbh4-0 jwXCBK\"><a sx=\"[object Object]\" data-testid=\"breadcrumbs-repo-link\" class=\"Link__StyledLink-sc-14289xe-0 dpowyu\" href=\"/mouredev/roadmap-retos-programacion/tree/main\">roadmap-retos-programacion</a></li><li class=\"Box-sc-g0xbh4-0 jwXCBK\"><span aria-hidden=\"true\" class=\"Text-sc-17v1xeu-0 ePvrxx\">/</span><a sx=\"[object Object]\" class=\"Link__StyledLink-sc-14289xe-0 csCkZA\" href=\"/mouredev/roadmap-retos-programacion/tree/main/Roadmap\">Roadmap</a></li><li class=\"Box-sc-g0xbh4-0 jwXCBK\"><span aria-hidden=\"true\" class=\"Text-sc-17v1xeu-0 ePvrxx\">/</span><a sx=\"[object Object]\" class=\"Link__StyledLink-sc-14289xe-0 csCkZA\" href=\"/mouredev/roadmap-retos-programacion/tree/main/Roadmap/00%20-%20SINTAXIS%2C%20VARIABLES%2C%20TIPOS%20DE%20DATOS%20Y%20HOLA%20MUNDO\">00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO</a></li><li class=\"Box-sc-g0xbh4-0 jwXCBK\"><span aria-hidden=\"true\" class=\"Text-sc-17v1xeu-0 ePvrxx\">/</span><a sx=\"[object Object]\" class=\"Link__StyledLink-sc-14289xe-0 csCkZA\" href=\"/mouredev/roadmap-retos-programacion/tree/main/Roadmap/00%20-%20SINTAXIS%2C%20VARIABLES%2C%20TIPOS%20DE%20DATOS%20Y%20HOLA%20MUNDO/php\">php</a></li></ol></nav><div data-testid=\"breadcrumbs-filename\" class=\"Box-sc-g0xbh4-0 jwXCBK\"><span aria-hidden=\"true\" class=\"Text-sc-17v1xeu-0 ePvrxx\">/</span><h1 tabindex=\"-1\" id=\"file-name-id-wide\" class=\"Heading__StyledHeading-sc-1c1dgg0-0 diwsLq\">GitHjuan.php</h1></div><button data-component=\"IconButton\" type=\"button\" aria-label=\"Copy path\" data-testid=\"breadcrumb-copy-path-button\" data-size=\"small\" data-no-visuals=\"true\" class=\"types__StyledButton-sc-ws60qy-0 IIGly\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-copy\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z\"></path><path d=\"M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z\"></path></svg></button></div></div><div class=\"react-code-view-header-element--wide\"><div class=\"Box-sc-g0xbh4-0 gtBUEp\"><div class=\"d-flex gap-2\"> <button hidden=\"\" data-testid=\"\" data-hotkey-scope=\"read-only-cursor-text-area\"></button><button hidden=\"\"></button><button hidden=\"\" data-testid=\"\" data-hotkey-scope=\"read-only-cursor-text-area\"></button><button hidden=\"\"></button><button type=\"button\" data-no-visuals=\"true\" class=\"types__StyledButton-sc-ws60qy-0 fXsbsD\"><span data-component=\"buttonContent\" class=\"Box-sc-g0xbh4-0 kkrdEu\"><span data-component=\"text\">Blame</span></span></button><button hidden=\"\" data-testid=\"\" data-hotkey-scope=\"read-only-cursor-text-area\"></button><button data-component=\"IconButton\" type=\"button\" aria-label=\"More file actions\" class=\"types__StyledButton-sc-ws60qy-0 hiXxwe js-blob-dropdown-click\" title=\"More file actions\" data-testid=\"more-file-actions-button-nav-menu-wide\" id=\":R156d9laeb:\" aria-haspopup=\"true\" tabindex=\"0\" data-no-visuals=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-kebab-horizontal\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M8 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM1.5 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm13 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z\"></path></svg></button> </div></div></div><div class=\"react-code-view-header-element--narrow\"><div class=\"Box-sc-g0xbh4-0 gtBUEp\"><div class=\"d-flex gap-2\"> <button hidden=\"\" data-testid=\"\" data-hotkey-scope=\"read-only-cursor-text-area\"></button><button hidden=\"\"></button><button hidden=\"\" data-testid=\"\" data-hotkey-scope=\"read-only-cursor-text-area\"></button><button hidden=\"\"></button><button type=\"button\" data-no-visuals=\"true\" class=\"types__StyledButton-sc-ws60qy-0 fXsbsD\"><span data-component=\"buttonContent\" class=\"Box-sc-g0xbh4-0 kkrdEu\"><span data-component=\"text\">Blame</span></span></button><button hidden=\"\" data-testid=\"\" data-hotkey-scope=\"read-only-cursor-text-area\"></button><button data-component=\"IconButton\" type=\"button\" aria-label=\"More file actions\" class=\"types__StyledButton-sc-ws60qy-0 hiXxwe js-blob-dropdown-click\" title=\"More file actions\" data-testid=\"more-file-actions-button-nav-menu-narrow\" id=\":R157d9laeb:\" aria-haspopup=\"true\" tabindex=\"0\" data-no-visuals=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-kebab-horizontal\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M8 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM1.5 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm13 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z\"></path></svg></button> </div></div></div></div></div></div></div></div><div class=\"Box-sc-g0xbh4-0 hVZtwF react-code-view-bottom-padding\"> <div class=\"Box-sc-g0xbh4-0 cMYnca\"></div> <!-- --> <!-- --> </div><div class=\"Box-sc-g0xbh4-0 hVZtwF\"> <!-- --> <!-- --> <div class=\"d-flex flex-column border rounded-2 mb-3 pl-1\"><div class=\"Box-sc-g0xbh4-0 brJRqk\"><h2 class=\"Heading__StyledHeading-sc-1c1dgg0-0 cgQnMS sr-only\" data-testid=\"screen-reader-heading\">Latest commit</h2><div style=\"width:120px\" class=\"Skeleton Skeleton--text\" data-testid=\"loading\"> </div><div class=\"d-flex gap-2\"><div data-testid=\"latest-commit-details\" class=\"d-none d-sm-flex flex-items-center\"></div><div class=\"d-flex gap-2\"><h2 class=\"Heading__StyledHeading-sc-1c1dgg0-0 cgQnMS sr-only\" data-testid=\"screen-reader-heading\">History</h2><a aria-label=\"Commit history\" class=\"types__StyledButton-sc-ws60qy-0 saA-Dg d-none d-lg-flex\" href=\"/mouredev/roadmap-retos-programacion/commits/main/Roadmap/00%20-%20SINTAXIS%2C%20VARIABLES%2C%20TIPOS%20DE%20DATOS%20Y%20HOLA%20MUNDO/php/GitHjuan.php\" data-size=\"small\"><span data-component=\"buttonContent\" class=\"Box-sc-g0xbh4-0 kkrdEu\"><span data-component=\"leadingVisual\" class=\"Box-sc-g0xbh4-0 trpoQ\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-history\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"m.427 1.927 1.215 1.215a8.002 8.002 0 1 1-1.6 5.685.75.75 0 1 1 1.493-.154 6.5 6.5 0 1 0 1.18-4.458l1.358 1.358A.25.25 0 0 1 3.896 6H.25A.25.25 0 0 1 0 5.75V2.104a.25.25 0 0 1 .427-.177ZM7.75 4a.75.75 0 0 1 .75.75v2.992l2.028.812a.75.75 0 0 1-.557 1.392l-2.5-1A.751.751 0 0 1 7 8.25v-3.5A.75.75 0 0 1 7.75 4Z\"></path></svg></span><span data-component=\"text\"><span class=\"Text-sc-17v1xeu-0 gPDEWA fgColor-default\">History</span></span></span></a><div class=\"Box-sc-g0xbh4-0 bqgLjk\"></div><div class=\"d-flex d-lg-none\"><span role=\"tooltip\" aria-label=\"History\" id=\"history-icon-button-tooltip\" class=\"Tooltip__TooltipBase-sc-17tf59c-0 izAlVj tooltipped-n\"><a aria-label=\"Commit history\" aria-describedby=\"history-icon-button-tooltip\" class=\"types__StyledButton-sc-ws60qy-0 saA-Dg\" href=\"/mouredev/roadmap-retos-programacion/commits/main/Roadmap/00%20-%20SINTAXIS%2C%20VARIABLES%2C%20TIPOS%20DE%20DATOS%20Y%20HOLA%20MUNDO/php/GitHjuan.php\" data-size=\"small\"><span data-component=\"buttonContent\" class=\"Box-sc-g0xbh4-0 kkrdEu\"><span data-component=\"leadingVisual\" class=\"Box-sc-g0xbh4-0 trpoQ\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-history\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"m.427 1.927 1.215 1.215a8.002 8.002 0 1 1-1.6 5.685.75.75 0 1 1 1.493-.154 6.5 6.5 0 1 0 1.18-4.458l1.358 1.358A.25.25 0 0 1 3.896 6H.25A.25.25 0 0 1 0 5.75V2.104a.25.25 0 0 1 .427-.177ZM7.75 4a.75.75 0 0 1 .75.75v2.992l2.028.812a.75.75 0 0 1-.557 1.392l-2.5-1A.751.751 0 0 1 7 8.25v-3.5A.75.75 0 0 1 7.75 4Z\"></path></svg></span></span></a></span></div></div></div></div></div><div class=\"Box-sc-g0xbh4-0 iJmJly\"><div class=\"Box-sc-g0xbh4-0 jACbi container\"><div class=\"Box-sc-g0xbh4-0 gIJuDf react-code-size-details-banner\"><div class=\"Box-sc-g0xbh4-0 fleZSW react-code-size-details-banner\"><div class=\"Box-sc-g0xbh4-0 dVVHlo text-mono\"><div title=\"516 Bytes\" data-testid=\"blob-size\" class=\"Truncate__StyledTruncate-sc-23o1d2-0 fUpWeN\"><span class=\"Text-sc-17v1xeu-0 gPDEWA\">28 lines (19 loc) · 516 Bytes</span></div></div></div></div><div class=\"Box-sc-g0xbh4-0 VHzRk react-blob-view-header-sticky\" id=\"repos-sticky-header\"><div class=\"Box-sc-g0xbh4-0 ePiodO\"><div class=\"Box-sc-g0xbh4-0 react-blob-sticky-header\"><div class=\"Box-sc-g0xbh4-0 kQJlnf\"><div class=\"Box-sc-g0xbh4-0 gJICKO\"><div class=\"Box-sc-g0xbh4-0 iZJewz\"><nav data-testid=\"breadcrumbs\" aria-labelledby=\"sticky-breadcrumb-heading\" id=\"sticky-breadcrumb\" class=\"Box-sc-g0xbh4-0 kzRgrI\"><h2 class=\"Heading__StyledHeading-sc-1c1dgg0-0 cgQnMS sr-only\" data-testid=\"screen-reader-heading\" id=\"sticky-breadcrumb-heading\">Breadcrumbs</h2><ol class=\"Box-sc-g0xbh4-0 cmAPIB\"><li class=\"Box-sc-g0xbh4-0 jwXCBK\"><a sx=\"[object Object]\" data-testid=\"breadcrumbs-repo-link\" class=\"Link__StyledLink-sc-14289xe-0 dpowyu\" href=\"/mouredev/roadmap-retos-programacion/tree/main\">roadmap-retos-programacion</a></li><li class=\"Box-sc-g0xbh4-0 jwXCBK\"><span aria-hidden=\"true\" class=\"Text-sc-17v1xeu-0 fQxKLn\">/</span><a sx=\"[object Object]\" class=\"Link__StyledLink-sc-14289xe-0 csCkZA\" href=\"/mouredev/roadmap-retos-programacion/tree/main/Roadmap\">Roadmap</a></li><li class=\"Box-sc-g0xbh4-0 jwXCBK\"><span aria-hidden=\"true\" class=\"Text-sc-17v1xeu-0 fQxKLn\">/</span><a sx=\"[object Object]\" class=\"Link__StyledLink-sc-14289xe-0 csCkZA\" href=\"/mouredev/roadmap-retos-programacion/tree/main/Roadmap/00%20-%20SINTAXIS%2C%20VARIABLES%2C%20TIPOS%20DE%20DATOS%20Y%20HOLA%20MUNDO\">00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO</a></li><li class=\"Box-sc-g0xbh4-0 jwXCBK\"><span aria-hidden=\"true\" class=\"Text-sc-17v1xeu-0 fQxKLn\">/</span><a sx=\"[object Object]\" class=\"Link__StyledLink-sc-14289xe-0 csCkZA\" href=\"/mouredev/roadmap-retos-programacion/tree/main/Roadmap/00%20-%20SINTAXIS%2C%20VARIABLES%2C%20TIPOS%20DE%20DATOS%20Y%20HOLA%20MUNDO/php\">php</a></li></ol></nav><div data-testid=\"breadcrumbs-filename\" class=\"Box-sc-g0xbh4-0 jwXCBK\"><span aria-hidden=\"true\" class=\"Text-sc-17v1xeu-0 fQxKLn\">/</span><h1 tabindex=\"-1\" id=\"sticky-file-name-id\" class=\"Heading__StyledHeading-sc-1c1dgg0-0 jAEDJk\">GitHjuan.php</h1></div></div><button style=\"--button-color:fg.default\" type=\"button\" data-size=\"small\" class=\"types__StyledButton-sc-ws60qy-0 ecGgfP\"><span data-component=\"buttonContent\" class=\"Box-sc-g0xbh4-0 kkrdEu\"><span data-component=\"leadingVisual\" class=\"Box-sc-g0xbh4-0 trpoQ\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-arrow-up\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M3.47 7.78a.75.75 0 0 1 0-1.06l4.25-4.25a.75.75 0 0 1 1.06 0l4.25 4.25a.751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018L9 4.81v7.44a.75.75 0 0 1-1.5 0V4.81L4.53 7.78a.75.75 0 0 1-1.06 0Z\"></path></svg></span><span data-component=\"text\">Top</span></span></button></div></div></div><div class=\"Box-sc-g0xbh4-0 jtQniD\"><h2 class=\"Heading__StyledHeading-sc-1c1dgg0-0 cgQnMS sr-only\" data-testid=\"screen-reader-heading\">File metadata and controls</h2><div class=\"Box-sc-g0xbh4-0 bfkNRF\"><ul aria-label=\"File view\" class=\"SegmentedControl__SegmentedControlList-sc-1rzig82-0 dlXtLG\"><li class=\"Box-sc-g0xbh4-0 fXBLEV\"><button aria-current=\"true\" class=\"SegmentedControlButton__SegmentedControlButtonStyled-sc-8lkgxl-0 kNvrzW\"><span class=\"segmentedControl-content\"><div class=\"Box-sc-g0xbh4-0 segmentedControl-text\">Code</div></span></button></li><li class=\"Box-sc-g0xbh4-0 illvPQ\"><button aria-current=\"false\" class=\"SegmentedControlButton__SegmentedControlButtonStyled-sc-8lkgxl-0 iDBPxb\"><span class=\"segmentedControl-content\"><div class=\"Box-sc-g0xbh4-0 segmentedControl-text\">Blame</div></span></button></li></ul><button hidden=\"\" data-testid=\"\" data-hotkey-scope=\"read-only-cursor-text-area\"></button><button hidden=\"\" data-testid=\"\" data-hotkey-scope=\"read-only-cursor-text-area\"></button><div class=\"Box-sc-g0xbh4-0 fleZSW react-code-size-details-in-header\"><div class=\"Box-sc-g0xbh4-0 dVVHlo text-mono\"><div title=\"516 Bytes\" data-testid=\"blob-size\" class=\"Truncate__StyledTruncate-sc-23o1d2-0 fUpWeN\"><span class=\"Text-sc-17v1xeu-0 gPDEWA\">28 lines (19 loc) · 516 Bytes</span></div></div></div></div><div class=\"Box-sc-g0xbh4-0 iBylDf\"><div class=\"Box-sc-g0xbh4-0 kSGBPx react-blob-header-edit-and-raw-actions\"><div class=\"ButtonGroup-sc-1gxhls1-0 cjbBGq\"><a href=\"https://github.com/mouredev/roadmap-retos-programacion/raw/main/Roadmap/00%20-%20SINTAXIS,%20VARIABLES,%20TIPOS%20DE%20DATOS%20Y%20HOLA%20MUNDO/php/GitHjuan.php\" data-testid=\"raw-button\" data-size=\"small\" data-no-visuals=\"true\" class=\"types__StyledButton-sc-ws60qy-0 dupbIv\"><span data-component=\"buttonContent\" class=\"Box-sc-g0xbh4-0 kkrdEu\"><span data-component=\"text\">Raw</span></span></a><button data-component=\"IconButton\" type=\"button\" aria-label=\"Copy raw content\" data-testid=\"copy-raw-button\" data-size=\"small\" data-no-visuals=\"true\" class=\"types__StyledButton-sc-ws60qy-0 dMUxwi\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-copy\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z\"></path><path d=\"M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z\"></path></svg></button><span role=\"tooltip\" aria-label=\"Download raw file\" id=\":Rdcsptal9laeb:\" class=\"Tooltip__TooltipBase-sc-17tf59c-0 izAlVj tooltipped-n\"><button data-component=\"IconButton\" type=\"button\" aria-label=\"Download raw content\" data-testid=\"download-raw-button\" data-size=\"small\" data-no-visuals=\"true\" class=\"types__StyledButton-sc-ws60qy-0 fCIOmi\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-download\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M2.75 14A1.75 1.75 0 0 1 1 12.25v-2.5a.75.75 0 0 1 1.5 0v2.5c0 .138.112.25.25.25h10.5a.25.25 0 0 0 .25-.25v-2.5a.75.75 0 0 1 1.5 0v2.5A1.75 1.75 0 0 1 13.25 14Z\"></path><path d=\"M7.25 7.689V2a.75.75 0 0 1 1.5 0v5.689l1.97-1.969a.749.749 0 1 1 1.06 1.06l-3.25 3.25a.749.749 0 0 1-1.06 0L4.22 6.78a.749.749 0 1 1 1.06-1.06l1.97 1.969Z\"></path></svg></button></span></div><button hidden=\"\" data-testid=\"raw-button-shortcut\" data-hotkey-scope=\"read-only-cursor-text-area\"></button><button hidden=\"\" data-testid=\"copy-raw-button-shortcut\" data-hotkey-scope=\"read-only-cursor-text-area\"></button><button hidden=\"\" data-testid=\"download-raw-button-shortcut\" data-hotkey-scope=\"read-only-cursor-text-area\"></button><a class=\"Link__StyledLink-sc-14289xe-0 elltiT js-github-dev-shortcut d-none\" href=\"https://github.dev/\"></a><button hidden=\"\" data-testid=\"\" data-hotkey-scope=\"read-only-cursor-text-area\"></button><a class=\"Link__StyledLink-sc-14289xe-0 elltiT js-github-dev-new-tab-shortcut d-none\" href=\"https://github.dev/\" target=\"_blank\"></a><button hidden=\"\" data-testid=\"\" data-hotkey-scope=\"read-only-cursor-text-area\"></button><div class=\"ButtonGroup-sc-1gxhls1-0 cjbBGq\"><span role=\"tooltip\" aria-label=\"Edit this file\" id=\":R6ksptal9laeb:\" class=\"Tooltip__TooltipBase-sc-17tf59c-0 izAlVj tooltipped-nw\"><a sx=\"[object Object]\" data-component=\"IconButton\" type=\"button\" aria-label=\"Edit file\" data-testid=\"edit-button\" data-size=\"small\" data-no-visuals=\"true\" class=\"types__StyledButton-sc-ws60qy-0 ksnFc\" href=\"/mouredev/roadmap-retos-programacion/edit/main/Roadmap/00%20-%20SINTAXIS%2C%20VARIABLES%2C%20TIPOS%20DE%20DATOS%20Y%20HOLA%20MUNDO/php/GitHjuan.php\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-pencil\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M11.013 1.427a1.75 1.75 0 0 1 2.474 0l1.086 1.086a1.75 1.75 0 0 1 0 2.474l-8.61 8.61c-.21.21-.47.364-.756.445l-3.251.93a.75.75 0 0 1-.927-.928l.929-3.25c.081-.286.235-.547.445-.758l8.61-8.61Zm.176 4.823L9.75 4.81l-6.286 6.287a.253.253 0 0 0-.064.108l-.558 1.953 1.953-.558a.253.253 0 0 0 .108-.064Zm1.238-3.763a.25.25 0 0 0-.354 0L10.811 3.75l1.439 1.44 1.263-1.263a.25.25 0 0 0 0-.354Z\"></path></svg></a></span><button data-component=\"IconButton\" type=\"button\" aria-label=\"More edit options\" data-testid=\"more-edit-button\" id=\":Raksptal9laeb:\" aria-haspopup=\"true\" tabindex=\"0\" data-size=\"small\" data-no-visuals=\"true\" class=\"types__StyledButton-sc-ws60qy-0 dMUxwi\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-triangle-down\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"m4.427 7.427 3.396 3.396a.25.25 0 0 0 .354 0l3.396-3.396A.25.25 0 0 0 11.396 7H4.604a.25.25 0 0 0-.177.427Z\"></path></svg></button></div><button hidden=\"\" data-testid=\"\" data-hotkey=\"e,Shift+E\" data-hotkey-scope=\"read-only-cursor-text-area\"></button></div><span role=\"tooltip\" aria-label=\"Open symbols panel\" id=\":R5sptal9laeb:\" class=\"Tooltip__TooltipBase-sc-17tf59c-0 izAlVj tooltipped-nw\"><button data-component=\"IconButton\" type=\"button\" aria-label=\"Symbols\" aria-pressed=\"false\" aria-expanded=\"false\" aria-controls=\"symbols-pane\" class=\"types__StyledButton-sc-ws60qy-0 jgnIDP\" data-testid=\"symbols-button\" id=\"symbols-button\" data-size=\"small\" data-no-visuals=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-code-square\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25Zm7.47 3.97a.75.75 0 0 1 1.06 0l2 2a.75.75 0 0 1 0 1.06l-2 2a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L10.69 8 9.22 6.53a.75.75 0 0 1 0-1.06ZM6.78 6.53 5.31 8l1.47 1.47a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215l-2-2a.75.75 0 0 1 0-1.06l2-2a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z\"></path></svg></button></span><div class=\"Box-sc-g0xbh4-0 react-blob-header-edit-and-raw-actions-combined\"><button data-component=\"IconButton\" type=\"button\" aria-label=\"Edit and raw actions\" class=\"types__StyledButton-sc-ws60qy-0 htXhGX js-blob-dropdown-click\" title=\"More file actions\" data-testid=\"more-file-actions-button\" id=\":Rnsptal9laeb:\" aria-haspopup=\"true\" tabindex=\"0\" data-size=\"small\" data-no-visuals=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" role=\"img\" class=\"octicon octicon-kebab-horizontal\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" style=\"display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible\"><path d=\"M8 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM1.5 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm13 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z\"></path></svg></button></div></div></div></div><div></div></div><div class=\"Box-sc-g0xbh4-0 jMJFjm\"><section aria-labelledby=\"file-name-id-wide file-name-id-mobile\" class=\"Box-sc-g0xbh4-0 jWnGGx\"><div class=\"Box-sc-g0xbh4-0 TCenl\"><div id=\"highlighted-line-menu-positioner\" class=\"position-relative\"><div id=\"copilot-button-positioner\" class=\"Box-sc-g0xbh4-0 cluMzC\"><div class=\"Box-sc-g0xbh4-0 eRkHwF\"><div class=\"Box-sc-g0xbh4-0 knCTAx react-code-file-contents\" role=\"presentation\" aria-hidden=\"true\" data-tab-size=\"8\" data-paste-markdown-skip=\"true\" data-hpc=\"true\"><div class=\"react-line-numbers\" style=\"pointer-events:auto\"><div data-line-number=\"1\" class=\"react-line-number react-code-text\" style=\"padding-right:16px\">1</div><div data-line-number=\"2\" class=\"react-line-number react-code-text\" style=\"padding-right:16px\">2</div><div data-line-number=\"3\" class=\"react-line-number react-code-text\" style=\"padding-right:16px\">3</div><div data-line-number=\"4\" class=\"react-line-number react-code-text\" style=\"padding-right:16px\">4</div><div data-line-number=\"5\" class=\"react-line-number react-code-text\" style=\"padding-right:16px\">5</div><div data-line-number=\"6\" class=\"react-line-number react-code-text\" style=\"padding-right:16px\">6</div><div data-line-number=\"7\" class=\"react-line-number react-code-text\" style=\"padding-right:16px\">7</div><div data-line-number=\"8\" class=\"react-line-number react-code-text\" style=\"padding-right:16px\">8</div><div data-line-number=\"9\" class=\"react-line-number react-code-text\" style=\"padding-right:16px\">9</div><div data-line-number=\"10\" class=\"react-line-number react-code-text\" style=\"padding-right:16px\">10</div><div data-line-number=\"11\" class=\"react-line-number react-code-text\" style=\"padding-right:16px\">11</div><div data-line-number=\"12\" class=\"react-line-number react-code-text\" style=\"padding-right:16px\">12</div><div data-line-number=\"13\" class=\"react-line-number react-code-text\" style=\"padding-right:16px\">13</div><div data-line-number=\"14\" class=\"react-line-number react-code-text\" style=\"padding-right:16px\">14</div><div data-line-number=\"15\" class=\"react-line-number react-code-text\" style=\"padding-right:16px\">15</div><div data-line-number=\"16\" class=\"react-line-number react-code-text\" style=\"padding-right:16px\">16</div><div data-line-number=\"17\" class=\"react-line-number react-code-text\" style=\"padding-right:16px\">17</div><div data-line-number=\"18\" class=\"react-line-number react-code-text\" style=\"padding-right:16px\">18</div><div data-line-number=\"19\" class=\"react-line-number react-code-text\" style=\"padding-right:16px\">19</div><div data-line-number=\"20\" class=\"react-line-number react-code-text\" style=\"padding-right:16px\">20</div><div data-line-number=\"21\" class=\"react-line-number react-code-text\" style=\"padding-right:16px\">21</div><div data-line-number=\"22\" class=\"react-line-number react-code-text\" style=\"padding-right:16px\">22</div><div data-line-number=\"23\" class=\"react-line-number react-code-text\" style=\"padding-right:16px\">23</div><div data-line-number=\"24\" class=\"react-line-number react-code-text\" style=\"padding-right:16px\">24</div><div data-line-number=\"25\" class=\"react-line-number react-code-text\" style=\"padding-right:16px\">25</div><div data-line-number=\"26\" class=\"react-line-number react-code-text\" style=\"padding-right:16px\">26</div><div data-line-number=\"27\" class=\"react-line-number react-code-text\" style=\"padding-right:16px\">27</div><div data-line-number=\"28\" class=\"react-line-number react-code-text\" style=\"padding-right:16px\">28</div></div><div class=\"react-code-lines\"><div class=\"react-code-text react-code-line-contents\" style=\"min-height:auto\"><div><div id=\"LC1\" class=\"react-file-line html-div\" data-testid=\"code-cell\" data-line-number=\"1\" style=\"position:relative\"><span class=\"pl-ent\">&lt;?php</span></div></div></div><div class=\"react-code-text react-code-line-contents\" style=\"min-height:auto\"><div><div id=\"LC2\" class=\"react-file-line html-div\" data-testid=\"code-cell\" data-line-number=\"2\" style=\"position:relative\">\n</div></div></div><div class=\"react-code-text react-code-line-contents\" style=\"min-height:auto\"><div><div id=\"LC3\" class=\"react-file-line html-div\" data-testid=\"code-cell\" data-line-number=\"3\" style=\"position:relative\"><span class=\"pl-c\">// https://www.php.net/</span></div></div></div><div class=\"react-code-text react-code-line-contents\" style=\"min-height:auto\"><div><div id=\"LC4\" class=\"react-file-line html-div\" data-testid=\"code-cell\" data-line-number=\"4\" style=\"position:relative\">\n</div></div></div><div class=\"react-code-text react-code-line-contents\" style=\"min-height:auto\"><div><div id=\"LC5\" class=\"react-file-line html-div\" data-testid=\"code-cell\" data-line-number=\"5\" style=\"position:relative\"><span class=\"pl-c\">//comentario de una linea</span></div></div></div><div class=\"react-code-text react-code-line-contents\" style=\"min-height:auto\"><div><div id=\"LC6\" class=\"react-file-line html-div\" data-testid=\"code-cell\" data-line-number=\"6\" style=\"position:relative\">\n</div></div></div><div class=\"react-code-text react-code-line-contents\" style=\"min-height:auto\"><div><div id=\"LC7\" class=\"react-file-line html-div\" data-testid=\"code-cell\" data-line-number=\"7\" style=\"position:relative\"><span class=\"pl-c\">/*</span></div></div></div><div class=\"react-code-text react-code-line-contents\" style=\"min-height:auto\"><div><div id=\"LC8\" class=\"react-file-line html-div\" data-testid=\"code-cell\" data-line-number=\"8\" style=\"position:relative\"><span class=\"pl-c\">comentario</span></div></div></div><div class=\"react-code-text react-code-line-contents\" style=\"min-height:auto\"><div><div id=\"LC9\" class=\"react-file-line html-div\" data-testid=\"code-cell\" data-line-number=\"9\" style=\"position:relative\"><span class=\"pl-c\">de varias</span></div></div></div><div class=\"react-code-text react-code-line-contents\" style=\"min-height:auto\"><div><div id=\"LC10\" class=\"react-file-line html-div\" data-testid=\"code-cell\" data-line-number=\"10\" style=\"position:relative\"><span class=\"pl-c\">lineas</span></div></div></div><div class=\"react-code-text react-code-line-contents\" style=\"min-height:auto\"><div><div id=\"LC11\" class=\"react-file-line html-div\" data-testid=\"code-cell\" data-line-number=\"11\" style=\"position:relative\"><span class=\"pl-c\">*/</span></div></div></div><div class=\"react-code-text react-code-line-contents\" style=\"min-height:auto\"><div><div id=\"LC12\" class=\"react-file-line html-div\" data-testid=\"code-cell\" data-line-number=\"12\" style=\"position:relative\">\n</div></div></div><div class=\"react-code-text react-code-line-contents\" style=\"min-height:auto\"><div><div id=\"LC13\" class=\"react-file-line html-div\" data-testid=\"code-cell\" data-line-number=\"13\" style=\"position:relative\"><span class=\"pl-c\">//CREA UNA VARIABLE Y UNA CONSTANTE</span></div></div></div><div class=\"react-code-text react-code-line-contents\" style=\"min-height:auto\"><div><div id=\"LC14\" class=\"react-file-line html-div\" data-testid=\"code-cell\" data-line-number=\"14\" style=\"position:relative\">\n</div></div></div><div class=\"react-code-text react-code-line-contents\" style=\"min-height:auto\"><div><div id=\"LC15\" class=\"react-file-line html-div\" data-testid=\"code-cell\" data-line-number=\"15\" style=\"position:relative\"><span class=\"pl-s1\"><span class=\"pl-c1\">$</span>variable</span> = &quot;<span class=\"pl-s\">Valor de mi variable</span>&quot;; <span class=\"pl-c\">// Esto es una variable</span></div></div></div><div class=\"react-code-text react-code-line-contents\" style=\"min-height:auto\"><div><div id=\"LC16\" class=\"react-file-line html-div\" data-testid=\"code-cell\" data-line-number=\"16\" style=\"position:relative\">\n</div></div></div><div class=\"react-code-text react-code-line-contents\" style=\"min-height:auto\"><div><div id=\"LC17\" class=\"react-file-line html-div\" data-testid=\"code-cell\" data-line-number=\"17\" style=\"position:relative\">define(<span class=\"pl-c1\">CONSTANTE</span>, &quot;<span class=\"pl-s\">Esto es una constante</span>&quot; ); <span class=\"pl-c\">//Esto es una constante</span></div></div></div><div class=\"react-code-text react-code-line-contents\" style=\"min-height:auto\"><div><div id=\"LC18\" class=\"react-file-line html-div\" data-testid=\"code-cell\" data-line-number=\"18\" style=\"position:relative\">\n</div></div></div><div class=\"react-code-text react-code-line-contents\" style=\"min-height:auto\"><div><div id=\"LC19\" class=\"react-file-line html-div\" data-testid=\"code-cell\" data-line-number=\"19\" style=\"position:relative\"><span class=\"pl-s1\"><span class=\"pl-c1\">$</span>string</span> = &quot;<span class=\"pl-s\"> PHP</span>&quot;; <span class=\"pl-c\">//cadena de texto</span></div></div></div><div class=\"react-code-text react-code-line-contents\" style=\"min-height:auto\"><div><div id=\"LC20\" class=\"react-file-line html-div\" data-testid=\"code-cell\" data-line-number=\"20\" style=\"position:relative\"><span class=\"pl-s1\"><span class=\"pl-c1\">$</span>int</span> = <span class=\"pl-c1\">12</span> ; <span class=\"pl-c\">//numero entero</span></div></div></div><div class=\"react-code-text react-code-line-contents\" style=\"min-height:auto\"><div><div id=\"LC21\" class=\"react-file-line html-div\" data-testid=\"code-cell\" data-line-number=\"21\" style=\"position:relative\"><span class=\"pl-s1\"><span class=\"pl-c1\">$</span>false</span> = <span class=\"pl-c1\">false</span>; <span class=\"pl-c\">//booleano</span></div></div></div><div class=\"react-code-text react-code-line-contents\" style=\"min-height:auto\"><div><div id=\"LC22\" class=\"react-file-line html-div\" data-testid=\"code-cell\" data-line-number=\"22\" style=\"position:relative\"><span class=\"pl-s1\"><span class=\"pl-c1\">$</span>true</span> = <span class=\"pl-c1\">true</span>;</div></div></div><div class=\"react-code-text react-code-line-contents\" style=\"min-height:auto\"><div><div id=\"LC23\" class=\"react-file-line html-div\" data-testid=\"code-cell\" data-line-number=\"23\" style=\"position:relative\"><span class=\"pl-s1\"><span class=\"pl-c1\">$</span>decimal</span> = <span class=\"pl-c1\">1.2</span>;</div></div></div><div class=\"react-code-text react-code-line-contents\" style=\"min-height:auto\"><div><div id=\"LC24\" class=\"react-file-line html-div\" data-testid=\"code-cell\" data-line-number=\"24\" style=\"position:relative\"><span class=\"pl-s1\"><span class=\"pl-c1\">$</span>array</span> = [&quot;<span class=\"pl-s\">uno</span>&quot; , &quot;<span class=\"pl-s\">dos</span>&quot;, &quot;<span class=\"pl-s\">tres</span>&quot;];</div></div></div><div class=\"react-code-text react-code-line-contents\" style=\"min-height:auto\"><div><div id=\"LC25\" class=\"react-file-line html-div\" data-testid=\"code-cell\" data-line-number=\"25\" style=\"position:relative\">\n</div></div></div><div class=\"react-code-text react-code-line-contents\" style=\"min-height:auto\"><div><div id=\"LC26\" class=\"react-file-line html-div\" data-testid=\"code-cell\" data-line-number=\"26\" style=\"position:relative\"><span class=\"pl-c\">// Imprime por terminal el texto: &quot;¡Hola, [y el nombre de tu lenguaje]!&quot;</span></div></div></div><div class=\"react-code-text react-code-line-contents\" style=\"min-height:auto\"><div><div id=\"LC27\" class=\"react-file-line html-div\" data-testid=\"code-cell\" data-line-number=\"27\" style=\"position:relative\">\n</div></div></div><div class=\"react-code-text react-code-line-contents\" style=\"min-height:auto\"><div><div id=\"LC28\" class=\"react-file-line html-div\" data-testid=\"code-cell\" data-line-number=\"28\" style=\"position:relative\"><span class=\"pl-k\">echo</span> &quot;<span class=\"pl-s\">Hola </span>&quot; . <span class=\"pl-s1\"><span class=\"pl-c1\">$</span>string</span>;</div></div></div></div></div></div><div id=\"copilot-button-container\"></div></div><div id=\"highlighted-line-menu-container\"></div></div></div><button hidden=\"\" data-testid=\"hotkey-button\" data-hotkey-scope=\"read-only-cursor-text-area\"></button><button hidden=\"\"></button></section></div></div></div> <!-- --> <!-- --> </div></div></div><div class=\"Box-sc-g0xbh4-0\"></div></div></div></div></div><div id=\"find-result-marks-container\" class=\"Box-sc-g0xbh4-0 aZrVR\"></div><button hidden=\"\" data-testid=\"\" data-hotkey-scope=\"read-only-cursor-text-area\"></button><button hidden=\"\"></button></div> <!-- --> <!-- --> <!-- --> <script type=\"application/json\" id=\"__PRIMER_DATA_:R0:__\">{\"resolvedServerColorMode\":\"night\"}</script></div>\n</react-app>\n</turbo-frame>\n\n\n\n  </div>\n\n</turbo-frame>\n\n    </main>\n  </div>\n\n  </div>\n\n          <footer class=\"footer pt-8 pb-6 f6 color-fg-muted p-responsive\" role=\"contentinfo\" >\n  <h2 class='sr-only'>Footer</h2>\n\n  \n\n\n  <div class=\"d-flex flex-justify-center flex-items-center flex-column-reverse flex-lg-row flex-wrap flex-lg-nowrap\">\n    <div class=\"d-flex flex-items-center flex-shrink-0 mx-2\">\n      <a aria-label=\"Homepage\" title=\"GitHub\" class=\"footer-octicon mr-2\" href=\"https://github.com\">\n        <svg aria-hidden=\"true\" height=\"24\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"24\" data-view-component=\"true\" class=\"octicon octicon-mark-github\">\n    <path d=\"M8 0c4.42 0 8 3.58 8 8a8.013 8.013 0 0 1-5.45 7.59c-.4.08-.55-.17-.55-.38 0-.27.01-1.13.01-2.2 0-.75-.25-1.23-.54-1.48 1.78-.2 3.65-.88 3.65-3.95 0-.88-.31-1.59-.82-2.15.08-.2.36-1.02-.08-2.12 0 0-.67-.22-2.2.82-.64-.18-1.32-.27-2-.27-.68 0-1.36.09-2 .27-1.53-1.03-2.2-.82-2.2-.82-.44 1.1-.16 1.92-.08 2.12-.51.56-.82 1.28-.82 2.15 0 3.06 1.86 3.75 3.64 3.95-.23.2-.44.55-.51 1.07-.46.21-1.61.55-2.33-.66-.15-.24-.6-.83-1.23-.82-.67.01-.27.38.01.53.34.19.73.9.82 1.13.16.45.68 1.31 2.69.94 0 .67.01 1.3.01 1.49 0 .21-.15.45-.55.38A7.995 7.995 0 0 1 0 8c0-4.42 3.58-8 8-8Z\"></path>\n</svg>\n</a>\n      <span>\n        &copy; 2024 GitHub,&nbsp;Inc.\n      </span>\n    </div>\n\n    <nav aria-label=\"Footer\">\n      <h3 class=\"sr-only\" id=\"sr-footer-heading\">Footer navigation</h3>\n\n      <ul class=\"list-style-none d-flex flex-justify-center flex-wrap mb-2 mb-lg-0\" aria-labelledby=\"sr-footer-heading\">\n\n          <li class=\"mx-2\">\n            <a data-analytics-event=\"{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to Terms&quot;,&quot;label&quot;:&quot;text:terms&quot;}\" href=\"https://docs.github.com/site-policy/github-terms/github-terms-of-service\" data-view-component=\"true\" class=\"Link--secondary Link\">Terms</a>\n          </li>\n\n          <li class=\"mx-2\">\n            <a data-analytics-event=\"{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to privacy&quot;,&quot;label&quot;:&quot;text:privacy&quot;}\" href=\"https://docs.github.com/site-policy/privacy-policies/github-privacy-statement\" data-view-component=\"true\" class=\"Link--secondary Link\">Privacy</a>\n          </li>\n\n          <li class=\"mx-2\">\n            <a data-analytics-event=\"{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to security&quot;,&quot;label&quot;:&quot;text:security&quot;}\" href=\"https://github.com/security\" data-view-component=\"true\" class=\"Link--secondary Link\">Security</a>\n          </li>\n\n          <li class=\"mx-2\">\n            <a data-analytics-event=\"{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to status&quot;,&quot;label&quot;:&quot;text:status&quot;}\" href=\"https://www.githubstatus.com/\" data-view-component=\"true\" class=\"Link--secondary Link\">Status</a>\n          </li>\n\n          <li class=\"mx-2\">\n            <a data-analytics-event=\"{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to docs&quot;,&quot;label&quot;:&quot;text:docs&quot;}\" href=\"https://docs.github.com/\" data-view-component=\"true\" class=\"Link--secondary Link\">Docs</a>\n          </li>\n\n          <li class=\"mx-2\">\n            <a data-analytics-event=\"{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to contact&quot;,&quot;label&quot;:&quot;text:contact&quot;}\" href=\"https://support.github.com?tags=dotcom-footer\" data-view-component=\"true\" class=\"Link--secondary Link\">Contact</a>\n          </li>\n\n          <li class=\"mr-3\" >\n  <cookie-consent-link>\n    <button type=\"button\" class=\"Link--secondary underline-on-hover border-0 p-0 color-bg-transparent\" data-action=\"click:cookie-consent-link#showConsentManagement\">\n      Manage cookies\n    </button>\n  </cookie-consent-link>\n</li>\n\n<li class=\"mr-3\">\n  <cookie-consent-link>\n    <button type=\"button\" class=\"Link--secondary underline-on-hover border-0 p-0 color-bg-transparent\" data-action=\"click:cookie-consent-link#showConsentManagement\">\n      Do not share my personal information\n    </button>\n  </cookie-consent-link>\n</li>\n\n      </ul>\n    </nav>\n  </div>\n</footer>\n\n\n\n\n    <ghcc-consent id=\"ghcc\" class=\"position-fixed bottom-0 left-0\" style=\"z-index: 999999\" data-initial-cookie-consent-allowed=\"\" data-cookie-consent-required=\"false\"></ghcc-consent>\n\n\n  <div id=\"ajax-error-message\" class=\"ajax-error-message flash flash-error\" hidden>\n    <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-alert\">\n    <path d=\"M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\"></path>\n</svg>\n    <button type=\"button\" class=\"flash-close js-ajax-error-dismiss\" aria-label=\"Dismiss error\">\n      <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-x\">\n    <path d=\"M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z\"></path>\n</svg>\n    </button>\n    You can’t perform that action at this time.\n  </div>\n\n    <template id=\"site-details-dialog\">\n  <details class=\"details-reset details-overlay details-overlay-dark lh-default color-fg-default hx_rsm\" open>\n    <summary role=\"button\" aria-label=\"Close dialog\"></summary>\n    <details-dialog class=\"Box Box--overlay d-flex flex-column anim-fade-in fast hx_rsm-dialog hx_rsm-modal\">\n      <button class=\"Box-btn-octicon m-0 btn-octicon position-absolute right-0 top-0\" type=\"button\" aria-label=\"Close dialog\" data-close-dialog>\n        <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-x\">\n    <path d=\"M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z\"></path>\n</svg>\n      </button>\n      <div class=\"octocat-spinner my-6 js-details-dialog-spinner\"></div>\n    </details-dialog>\n  </details>\n</template>\n\n    <div class=\"Popover js-hovercard-content position-absolute\" style=\"display: none; outline: none;\" tabindex=\"0\">\n  <div class=\"Popover-message Popover-message--bottom-left Popover-message--large Box color-shadow-large\" style=\"width:360px;\">\n  </div>\n</div>\n\n    <template id=\"snippet-clipboard-copy-button\">\n  <div class=\"zeroclipboard-container position-absolute right-0 top-0\">\n    <clipboard-copy aria-label=\"Copy\" class=\"ClipboardButton btn js-clipboard-copy m-2 p-0 tooltipped-no-delay\" data-copy-feedback=\"Copied!\" data-tooltip-direction=\"w\">\n      <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-copy js-clipboard-copy-icon m-2\">\n    <path d=\"M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z\"></path><path d=\"M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z\"></path>\n</svg>\n      <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-check js-clipboard-check-icon color-fg-success d-none m-2\">\n    <path d=\"M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z\"></path>\n</svg>\n    </clipboard-copy>\n  </div>\n</template>\n<template id=\"snippet-clipboard-copy-button-unpositioned\">\n  <div class=\"zeroclipboard-container\">\n    <clipboard-copy aria-label=\"Copy\" class=\"ClipboardButton btn btn-invisible js-clipboard-copy m-2 p-0 tooltipped-no-delay d-flex flex-justify-center flex-items-center\" data-copy-feedback=\"Copied!\" data-tooltip-direction=\"w\">\n      <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-copy js-clipboard-copy-icon\">\n    <path d=\"M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z\"></path><path d=\"M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z\"></path>\n</svg>\n      <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-check js-clipboard-check-icon color-fg-success d-none\">\n    <path d=\"M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z\"></path>\n</svg>\n    </clipboard-copy>\n  </div>\n</template>\n\n\n    <style>\n      .user-mention[href$=\"/Roswell468\"] {\n        color: var(--color-user-mention-fg);\n        background-color: var(--bgColor-attention-muted, var(--color-attention-subtle));\n        border-radius: 2px;\n        margin-left: -2px;\n        margin-right: -2px;\n        padding: 0 2px;\n      }\n    </style>\n\n\n    </div>\n\n    <div id=\"js-global-screen-reader-notice\" class=\"sr-only\" aria-live=\"polite\" aria-atomic=\"true\" ></div>\n    <div id=\"js-global-screen-reader-notice-assertive\" class=\"sr-only\" aria-live=\"assertive\" aria-atomic=\"true\"></div>\n  </body>\n</html>\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/H4cker0n.php",
    "content": "<?php\n// https://www.php.net/ //\n\n/* COMENTARIOS */\n\n// Esto es un comentario de una sola línea en PHP.\n\n/*\nEsto es un comentario de varias líneas en PHP.\nPuedes usarlo para bloques de texto más largos.\n*/\n\n# También puedes usar el signo de número (#) para comentarios de una sola línea,\n# aunque las dos barras (//) son más comunes.\n\n/* VARIABLES Y CONSTANTES */\n$Variable = \"¡HOLA MUNDO!\"; // Una variable en PHP siempre comienza con $.\ndefine(\"hello\", 3.14159); // Una constante definida con define().\nconst GRAVEDAD = 9.81; // Otra forma de definir una constante a partir de PHP 5.3.\n\n/* TIPO DE DATOS */\n\n$cadena = \"Esto es una cadena de texto.\"; // string\n$numeroEntero = 150; // integer\n$numeroFlotante = 20.5; // float (o double, son similares en PHP)\n$booleanoVerdadero = true; // boolean\n$booleanoFalso = false; // boolean\n$valorNulo = null; // null\n$array = [1, 2, 3]; // array (o puedes usar la sintaxis corta [])\n\n/* IMPRIMIR */\n$miVariable = \"¡Hola, PHP!\";\necho $miVariable; // Imprime el valor de la variable \n\n?>"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/Hugovrc.php",
    "content": "<?php\n// https://www.php.net/\n\n// Este es un comentario de una sola linea\n/* Este es un \n   comentario\n   multilinea */\n\n//Declaracion de variables\n$mi_variable = 'Mi primer variable';\n\n//Declaracion de constantes\n$MI_CONSTANTE = 'Mi primer constante';\n\n//Tipos de datos primitivos\n$nulo = NULL;\n$booleano = True;\n$entero = 10;\n$punto_flotante= 1.5;\n$cadena_de_caracteres = 'Esta es una cadena de caracteres';\n\necho \"¡Hola, PHP!\"\n\n?>"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/JaimeSoftDev.php",
    "content": "<?php\n//https://www.php.net/\n\n//Esto es un comentario de una línea\n\n/* Esto es un comentario\nde varias líneas\n*/\n\n//Definiendo una variable y dos constantes con const y define\n$variable = \"variable\";\nconst CONSTANTE = \"constante\";\ndefine(\"const2\", \"constante con define\");\n\n//Definiendo los tipos de variables que hay\n$numeroEntero = 8;\n$booleano = true;\n$numeroFloat = 54312.78;\n$variableNula = null;\n$variableCadena = \"PHP\";\n$variableArray = array(1, 2, 3);\n$arrayCorchetes = [1, 2, 3];\n$arrayAsociativo = [\n    \"nombre\" => \"Jaime\",\n    \"apellido\" => \"Maciá\",\n    \"estudios\" => \"DAW\",\n];\n\n//Imprimiendo por pantalla\necho \"Hola, {$variableCadena}\";\n?>"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/JehiselRuth.php",
    "content": "<?php\n//Sitio oficial del lenguaje de Java url: https://www.java.com/es/\n\n#En Java puedes comentar utilizando # en comentarios de una sola línea\n/*Mientras que la barra lateral y el asterisco \nte permite comentar más de una línea*/\n\n//Variable\n$hello = 'Hola';\n#Constante\n$language = 'PHP';    \n\n//Tipos primitivos\n$stringMyName = \"Jehisel\";\n$numb_age = 38;\n$double_weight = 53.3;\n$booleanIsActive = true;\n\n\necho \"¡$hello, $language!\";\n?>"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/Jeyker-Dev.php",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n <?php\n\n// URL Offical oh PHP\n // https://www.php.net\n\n // One Line\n\n/*\n    More Than One Line\n    U Can See\n*/\n\n$variable;\n\ndefine('constant', 'This is a constant');\n\n// Booleans\n$bool_1 = true;\n$bool_2 = false;\n\n// Integer\n$integer = 1;\n\n// Float\n$float = 1.00;\n\n// String\n$string = 'This is a string';\n\n// Indexed Arrays\n$palabra_1[0] = 'Hello';\n$palabra_1[1] = 'World';\n\n$palabra_2 = array('Im', 'Going', 'To', 'Be', 'A', 'Programmer');\n\necho '!Hola, PHP';\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/Jovany-java.php",
    "content": "<?\n\n//Sitio web Oficial: https://www.php.net\n\necho \"Comentario de varias lineas\";\n/*\nComentario de varias lineas\n\n*/\necho \"Comentarios de una sola linea\"; //Soy un comentario de una linea\n\necho \"Comentario de una sola linea\"; #Soy un comentario de una linea al estilo consola de Unix \n\n//Declaración de una variable y una constante\n$nameDeVariable = \"Variable pueden ser cualquier tipo de dato\";\ndefine('nameDeLaConstante', 'valor de la constante');\ndefine('PI', 3.1416); \necho \"El valor de pi es:\".PI;\n\n//Declaraciones de los tipos de Datos primivitios\n$integer = 10;\n$float = 10.9;\n$double = 1990.10;\n$string = \"Recien empiezo y apenas se usar github, si me pueden decir que fallo \nal subir la PR xfa\";\n$boolean = true;\n$boolean = false;\n$null = null;\n\n//Array indexado\n$numeros = array(1,2,4,5,6);\n//Array asociativo\n$datosUsuario = array(\n\n    \"nombre\" => \"juan\",\n    \"edad\" => 19\n\n);\n\necho \"Hola, mi proximo dolor de cabeza PHP\";\n\n\n?>"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/Luisfcaro.php",
    "content": "<?php\n\n// La documentacion oficial de php la puedes encontrar en https://www.php.net\n\n// Comentario de una linea\n\n# Otra forma de realizar comentarios de una sola linea\n\n/*\n    Esta es la forma de realizar comentarios de multiples lineas en PHP. \n    \n    ¿Existen otras formas de realizar comentarios?\n*/\n\n/* CONSTANTES */\n\ndefine('Prueba', 'Hola Mundo'); // De esta forma puedes definir una constante, el primer parametro sera su nombre, y el segundo su valor\nconst Prueba2 = 'Hola Mundo'; // Esta es otra forma de definir una constante, personalmente esta es la que mas me gusta\n\n\n/* VARIABLES */\n\n$cadena = \"Hola Mundo\"; // Variable de tipo string\n$entero = 10; // Variable de tipo int\n$real = 10.5; // Variable de tipo float\n$booleano = true; // Variable de tipo boolean\n$nulo = null; // Variable de tipo null\n$array = array(1, 2, 3, 4, 5); // Variable de tipo array\n$array_alterno = [1, 2, 3, 4, 5]; // Esta es otra forma de declarar un array en php\n$asociativo = array('nombre' => 'Luis', 'apellido' => 'Fernández'); // Variable de tipo array asociativo\n$asociativo_alterno = ['nombre' => 'Luis', 'apellido' => 'Fernández']; // Esta es otra forma de declarar un array asociativo en php\n\n\n/* OBJETOS */\n\n$fecha = new DateTime(); // Variable de tipo objeto\n\n\n/* IMPRIMIR EN PANTALLA */\n\necho $cadena . ' ' . 'Disfrutar del Roadmap' . \"\\n\"; // Esta es la forma de imprimir en pantalla en php\nprint \"El numero entero es $entero\\n\"; // Esta es otra forma de imprimir en pantalla en php \n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/NievesYonathan.php",
    "content": "<?php\n// https://www.php.net/\n\n// Sintaxis para comentario de una línea usando '//'.\n\n#  Sintaxis para comentario de una línea usando '#'.\n\n/*\n   Sintaxis que permite\n   comentarios de varias líneas.\n*/\n\n$variablePHP; //Esto es una variable PHP. Se inicia con '$'.\n\n// Las constantes se pueden declarar de las siguientes formas:\nconst CONSTANTE_PHP = \"Texto constante.\"; // Con esta forma la constante se debe declar en el nivel superior.\ndefine(\"CONSTANTE_PHP_2\", \"Segunto texto constante.\");\n\n#Datos primitivos de PHP\n$var_booleana = true;\n$var_string = \"Nice to meet you!\";\n$var_string2 = 'Texto en comillas simples.';\n$var_int = 2004;\n$var_float = 13.1416;\n\n// Imprimir saludo.\necho \"¡Hola, PHP!\";"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/NightAlchemist.php",
    "content": "<?php \r\n\r\n// https://www.php.net/\r\n\r\n// one line comment\r\n# one line comment too\r\n\r\n/* \r\nMulti-line comment\r\nMulti-line comment\r\n*/\r\n\r\n//variables\r\n$var_example = \"\";\r\n$var2 = 2;\r\n\r\n//contantes\r\ndefine(\"CONST1\", \"No cambio\");\r\nconst MYCONST = \"Const2\";\r\ndefine(\"array\", [\r\n    1,\r\n    3,\r\n    \"good\"\r\n]);\r\n\r\n//tipos de datos primitivos\r\n\r\n$string = \"Esto es una línea de texto\";\r\n$integer = 15;\r\n$float = 1.5;\r\n$boolean = true;\r\n$var_array = [\"my\", 568, false, \"Jimmyyyy\"];\r\n\r\n//El siguiente es el tipo de dato objeto, creamos antes una clase\r\nclass Car {\r\n    public $color;\r\n    public $model;\r\n    public function __construct($color, $model) {\r\n      $this->color = $color;\r\n      $this->model = $model;\r\n    }\r\n    public function message() {\r\n      return \"My car is a \" . $this->color . \" \" . $this->model . \"!\";\r\n    }\r\n  }\r\n  \r\n  $myCar = new Car(\"red\", \"Volvo\"); # <= Este es el objeto, instanciado desde la clase\r\n//fin del objeto\r\n\r\necho \"Hola PHP!\";\r\n\r\n?>"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/Rob-Gon.php",
    "content": "<?php\n\n// https://www.php.net\n\n// Este es un comentario de una línea\n\n/*\n* Este es un comentario\n* de varias líneas\n*/\n\n$variable = \"Mi variable\"; // Esta es una variable\nconst CONSTANTE = \"Mi constante\"; // Esta es una constante en tiempo de compilación\ndefine(\"CONSTANTE\", \"Mi constante\"); // Esta es una constante en tiempo de ejecución\n\n$string = \"Cadena de texto\"; // Cadena de texto\n$integer = 18; // Número entero\n$float = 1.8; // Número decimal\n$boolean = true; // Booleano\n$null = null; // Valor nulo\n\necho(\"¡Hola, PHP!\"); // Imprime \"¡Hola, PHP!\""
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/Zakeyo.php",
    "content": "<?php\n\n// https://www.php.net\n\n// Esta es la primera forma de escribir comentarios con PHP, como una sola linea\n/*\n    Y para escribir lineas multiples se puede usar de esta manera\n    Así puedo escribir varias lineas sin necesidad de agregar una\n    doble barra cada vez (y hace el código más legible a veces, a mi parecer)\n*/\n\n$varDobl = \"Hola, soy una variable de doble comillas\";\n$varSimpl = 'Y yo de comillas simples!';\nconst CONSTANTE = \"Y yo soy una constante!!\";\n\n$lang = \"PHP\";\n\n\n// Tipos de datos\n\n$integer = \"Esto es una cadena de texto\";  // Texto plano\n$number = 123;  // numérico\n$float = 123.45;  // flotante (o decimal)\n$bool = true;  // booleano (también puede ser 'false')\n$null = NULL;  // null (vacío)\n$array = array(\n    'clave'  => 'valor',\n    'clave2' => 'valor2',\n    'clave3' => 'valor3',\n);  // Tipo array\n\n\necho \"Hola, $lang!\"\n\n?>"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/adrs1166ma.php",
    "content": "<?php\n\n/* \n* EJERCICIO:\n* - Crea un comentario en el código y coloca la URL del sitio web oficial del\n*   lenguaje de programación que has seleccionado.\n* - Representa las diferentes sintaxis que existen de crear comentarios\n*   en el lenguaje (en una línea, varias...).\n* - Crea una variable (y una constante si el lenguaje lo soporta).\n* - Crea variables representando todos los tipos de datos primitivos\n*   del lenguaje (cadenas de texto, enteros, booleanos...).\n* - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"  \n*/\n\n/*\n    🟢 Documentación PHP en https://www.php.net/\n*/\n\n\n/* \n    🟢 Tipos de sintaxis para Cometario:\n    🔸 Se debe de cerrar si se integra codigo html <?php  ?>\n*/\n\n// Comentario de una línea \n\n/*  comentario..\n  Comentario para varías líneas\n*/\n\n\n/*\n    🟢 Variable y Constante\n*/\n\n\n\n/**\n * DEFINIR VARIABLES \n */\n// ✔️ Empieza siempre con signo de '💲' al inicio\n$lenguaje = \"php\";\n$_saludo = \"¡Hola, \";\n$saludoFinal_ = \"!\";\n// ❌ $11lenguaje = \"php\";//no empieza con numeros despues del '💲'\n\n// Imprimir variables\necho $lenguaje;\necho $_saludo . ' ' . $lenguaje. $saludoFinal_;\necho '<br>';\n\n\n\n/**\n * DEFINIR Constante\n */\n// ✔️ 2 formas\ndefine(\"PI\", 3.14);\nconst e = 2.7182; // 🔹 no comun\n\n// Imprimir constantes\nprint PI;\nprint \"El numero PI es \".PI;\necho '<br>';\n\nprint e;\nprint \"El numero e es \".e;\necho '<br>';\n\n\n\n/*\n    🟢 Tipos de datos\n*/\n$entero = 3; // Tipo entero\n$float = 125.00; // Tipo float\n$booleano = true; // Tipo boolean\n$nulo = null; // Tipo null \n$cadena = \"¡Hola, \"; // Tipo string\n$arreglo = array(1, 2, 3); // Tipo array\n$otro_arreglo = [1, 2, 3]; // Otra forma de declarar un arreglo\n$asociativo = array(\"nombre\" => \"adrs\", \"apellido\" => \"ma\"); // Arreglo asociativo\n$otro_asociativo = [\"nombre\" => \"adrs\", \"apellido\" => \"ma\"]; // Otra forma de declarar un arreglo asociativo\n$fecha = new DateTime(); // Tipo objeto\n\n// Solo para imprimir y verificar el tipo de dato en pantalla\n\n\necho '<br>'; // 🔸 Espacio de linea en pantalla\n\n// Imprimir variables\nprint \"El numero entero es $entero\\n\";\nvar_dump($entero); echo '<br>';\n\nprint \"El numero flotante es $float\\n\";\nvar_dump($float); echo '<br>';\n\nprint \"El valor booleano es $booleano\\n\";\nvar_dump($booleano); echo '<br>';\n\nprint \"El valor nulo es $nulo\\n\";\nvar_dump($nulo); echo '<br>';\n\n\necho '<br>'; // Arrays 🔸\n\n\necho '<pre>'; // Formatear los arreglos, start 🟣\n\nprint \"El arreglo es $arreglo[0], $arreglo[1], $arreglo[2]\\n\";\nvar_dump($arreglo); echo '<br>'; echo '<br>';\n\nvar_dump($otro_arreglo); echo '<br>'; echo '<br>';\n\nprint \"El arreglo asociativo es $asociativo[nombre] $asociativo[apellido]\\n\";\nvar_dump($asociativo); echo '<br>'; echo '<br>';\n\nvar_dump($otro_asociativo); echo '<br>';\n\necho '</pre>'; // Formatear los arreglos, end 🟣\n\n\necho '<br>'; // Fecha 🔸\n\n\necho '<pre>';\nvar_dump($fecha); echo '<br>'; echo '<br>';\necho '</pre>';\n?>\n<?php\n/*\n    🟢 Imprimir en pantalla\n*/\necho \"¡Hola, php!\";\necho \"<h1>¡Hola, php!</h1>\";\n?>\n\n<h1><?php echo \"¡Hola php!\" ?></h1> <!-- En HTML -->\n\n<?php\necho(\"¡Hola, php!\"); echo '<br>'; // 🔹 no comun\nprint(\"¡Hola, php!\"); echo '<br>'; // 🔹 no comun\nprint \"¡Hola, php!\"; echo '<br>';// 🔹 no comun\nprint_r(\"¡Hola, php!\"); echo '<br>'; // 🔹 no comun, 🔸sin parentesis no funciona\n\nvar_dump(\"¡Hola, php!\"); echo '<br>'; //info de dato o arreglo\n\n?>"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/agusrosero.php",
    "content": "<?php\n/*\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n// https://www.php.net/\n\n// Comentario en una linea\n# Esto tambien es un comentario en una linea\n/*\nComentario de\nvarias lineas\n*/\n\n// Variables y constantes\n$miVariable = \"Mi variable\";\ndefine(\"MI_CONSTANTE\", \"Valor de mi constante\");\n\n// Tipos de datos\n$entero = 23;\n$cadena = \"Mi cadena\";\n$flotante = 3.14;\n$booleano = true;\n$arrays = array(\"Rojo\", \"Negro\", \"Blanco\");\n$nulo = null;\n\n// Imprime por terminal \nprint \"¡Hola, PHP!\";\n?>"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/alejandroruiz23.php",
    "content": "<?php\r\n// 1.web oficial de PHP\r\n//https://www.php.net/\r\n\r\n// 2.Tipos de comentarios:\r\n\r\n// 2.1. Con doble barra puedo crear un comentario de una sola linea\r\n\r\n/* 2.2. Para crear comentarios de mas de una linea uso barra más asterisco para abrir y cierro con\r\nasterisco más barra */\r\n\r\n// 3.Creación de variables\r\n//php es sensible a mayusculas y minusculas. \r\n$mi_variable = \"Mi primera variable\"\r\n$Mi_variable = \"Esta varables es diferente por la mayuscula\"\r\n\r\n// 3.1Creación de constantes en PHP\r\n//Puedo nombras constantes de dos formas\r\ndefine(\"MI_CONSTANTE_1\",23);\r\n\r\n//dentro de una clase\r\nclass Unaclase{\r\n    const MI_CONSTANTE_2 = 5;\r\n}\r\n\r\n// 4.Variables con tipos de datos primitivos\r\n//Null\r\n$variable_1 = NULL;\r\n//Boolean\r\n$variable_2 = True;\r\n//integer\r\n$variable_3 = 3;\r\n//float\r\n$variable_4 = 3.141516;\r\n//string\r\n$variable_5 = 'Variable-string':\r\n//arrays\r\n$variable_6 = array(\"sin-clave\", \"con\"=>\"clave\", \"numero\"=>23);\r\n\r\n// 5. Imprimir\r\n\r\necho \"¡Hola, PHP!\";\r\n\r\n\r\n?>"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/alexsamboy.php",
    "content": "<?php\n\n// Sitio oficial: https://www.php.net/\n\n// Comentario de una sola línea\n/*\nEste es un\ncomentario\nmulti línea\n*/\n# Comentario de una línea tipo consola.\n\n$unaVariable = 'Esta es una variable';\nconst CONSTANTE = 'Esta es mi constante';\n\n$un_bool = true;   // un valor booleano\n$un_bool = false;   // un valor booleano\n$un_str  = \"foo\";  // una cadena de caracteres\n$un_str2 = 'foo';  // una cadena de caracteres\n$un_int  = 12;     // un número entero\n$var_float = 1.0;   // un decimal\n$var_null = null;    // valor nulo\n$var_arreglo = [1,2,3]; // array\n$var_objeto = {\n    'name':'nombre',\n    'numero': 2,\n    'visible': false\n};    // Objeto\n\nprint(\"¡Hola, PHP!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/alexvasquez199914.php",
    "content": "<?php\n\n# https://www.php.net\n\n//Este es un comentario de una línea//\n/* Este es un \ncomentario multilínea */ \n# Este es un comentario de consola una línea\n\n#definiendo variable\n\n$url= 'https://www.php.net';\n\n# definiendo constante\n\ndefine(\"url2\",     \"15\");\n\n#tipos de datos primarios\n\n$myvariable_int=1;\n$myvariable_string=\"texto\";\n$myvariable_bool=true;\n$myvariable_bool2=false;\n$myvariable_float= \"0.5\";\n\n\n# imprimir hola y lenguaje\n\necho \"<h1>Hola php</h1>\";\n?>"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/cmahecha291-beep.php",
    "content": "<?php\r\n    //WEB OFICIAL PHP\r\n        // https://www.php.net\r\n    //TIPOS DE COMENTARIOS EN PHP :\r\n        // Comentario de una sola linea \" // \" es utilizando dos barras o slash.\r\n        # Comentario de una sola linea \" # \" este se genera utilisando un numeral.\r\n        /* \r\n            Comentario multilinea \" / * * / \" se genera utilizando una barra al inicio con un asterisco y se cierra \r\n            al final con un asterisco y una barra, y sirve para hacer que todo el texto o codigo que este dentro de \r\n            dichos simbolos no se tomara en cuenta a la hora de ejecutar el codigo.\r\n        */\r\n    //DECLARACION DE VARIABLES\r\n        /*\r\n            Para declara variables en el leguaje de programacion PHP se utiliza el simbolo \"$\" segudo del nombre de\r\n            la variable, luego en el signo \" = \" con el cual se le asigna un valor a dicha variable y por ultimo se finaliza \r\n            con un punto y coma \" ; \", ejemplo : $myfloat = 19,9; oh $name = value; , como php es un lenguje de tipado \r\n            dinamico no es necesario asignar directamente el tipo de valor a ingresar, si es una cadena de texto seria \r\n            \" $mystring = \"Christian\"; \" con comillas dobles para identificar que es una cadena de texto.\r\n        */\r\n            $my_integer = 17;\r\n            $my_float = 17,5;\r\n            $my_string = \"Christian\";\r\n            $my_array = array(1, 2, 3);\r\n            $my_boolean = true;\r\n            $my_boolean = false;\r\n        //  Constantes en PHP\r\n            /*\r\n                Una variable se caracteriaza por que no cambia su contenido despues de asignarlo, en php a diferencia de las \r\n                las variables no es necesario declararlas con el signo \" $ \" y dichas constantes se utilizan para definir \r\n                informacion fija. \r\n             */\r\n            public const pi = 3.1415926535;\r\n            define(\"MI_CONSTANTE\", 17);\r\n        // Imprimir en  PHP\r\n            /*\r\n                Para imprimir en PHP debemos escribir echo, luego dentro de comillas ponemos en texto y terminamos con punto y coma,\r\n                ejemplo : echo \"Hola soy PHP\";\r\n             */\r\n            echo \" Hola soy PHP ! \";\r\n            /* \r\n                Imprimir textoy variables al tiempo\r\n                    Para imprimir un texto y una variable al tiempo debemos escibir echo, luego enttre comillar el texto y para concatenar\r\n                    utilizamnos un punto \" . \", luego el nombre de la variable, ejemplo: echo \"Soy una cadena de texto: \" . $mysting; \r\n                    \" Siempre que llamemos una variable la tendremos que llamar con el signo $\".\r\n            */\r\n            echo \" Soy una cadena de texto: \" . $my_string;\r\n    \r\n        // OPERADORES EN PHP\r\n            // Operadores Aritmeticos\r\n                $a = 10;\r\n                $b = 5;\r\n                echo \" La suma de a + b es: \" . ($a + $b);\r\n                echo \" La resta de a - b es: \" . ($a - $b);\r\n                echo \" La multiplicacion de a * b es: \" . ($a * $b);\r\n                echo \" La division de a / b es: \" . ($a / $b);\r\n                echo \" El modulo de a % b es: \" . ($a % $b);\r\n        \r\n\r\n    \r\n \r\n?>"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/edalmava.php",
    "content": "<?php\n\n// Esto es un comentario de una línea\n\n/*\n  Este es un comentario de varias líneas o multilinea\n*/\n\n// Sitio oficial: \n\n//   Variables: se representan con un signo de dolar $ seguido del nombre de la variable\n//   De forma predeterminada, las variables siempre se asignan por valor. \n//   Para asignar por referencia se antepone un signo ampersand (&) al comienzo de la variable \n//   cuyo valor se está asignando (la variable fuente). \n\n$mi_variable = 1;\n\n// Tipos\n\n// Tipo null: representa una variable sin valor\n$var = null;         // insensible a minúsculas/mayúsculas - null - NULL\n$var2;               // Si a una variable no se le ha asignado valor su valor es null\n\n// Booleanos: expresa un valor que indica verdad.  Puede ser true(verdadero) o false(falso)\n$verdadero = true;\n$falso = false;\n\n// Números enteros (Integers)\n$entero = 127;\n$octal = 020;\n$hexadecimal = 0xFF;\n$binario = 0b1111;\n\n// Números de punto flotante (floats)\n$float = 1.23;\n$float2 = 1.23e10;\n$float3 = 5E-10;\n$float4 = 1_234.54;\n\n// cadenas de caracteres (Strings)\n$simple = 'Hola';\n$doble = \"PHP\";\n$con_secuencias = \"Esto es un ejemplo con \\n secuencias de escape\";\n\n$heredoc = <<<EOD\nEjemplo de una cadena\nexpandida en varias líneas\nempleando la sintaxis heredoc.\nEOD;\n\n$str = <<<'EOD'\nEjemplo de un string\nexpandido en varias líneas\nempleando la sintaxis nowdoc.\nEOD;\n\n// Arrays: mapas ordenados\n$arreglo = [\n  \"foo\" => \"bar\",\n  \"bar\" => \"foo\",\n];\n$arreglo2 = [1, 2, 3, 4, 5];\n\n// Imprimir por consola o terminal\necho \"¡{$simple}, {$doble}!\";\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/eloy1290.php",
    "content": "<?php \n\n// https://www.php.net/manual/es/\n\n// Comentario de una línea\n\n# Comentario de una línea\n\n/* \nComentario de\nvarias líneas\n*/\n\n// Variable\n$variable = 'Eloy';\n\n\n// Constante\ndefine(\"CONSTANTE\", \"Esto es la constante\");\n\n// Tipos de datos primitivos\n$string = \"Hola Mundo\";\n$boolean = true;\n$number = 10;\n$decimal = 10.5;\n\n// Imprimir mensaje\necho \"¡Hola, PHP!\";\n\n\n\n\n\n?>"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/eulogioep.php",
    "content": "<?php\n\n// URL del sitio web oficial de PHP\n// https://www.php.net/\n\n// Diferentes formas de crear comentarios en PHP:\n\n// 1. Comentario de una línea\n\n/*\n * 2. Comentario\n * de varias\n * líneas\n */\n\n/**\n * 3. Comentario de documentación (DocBlock)\n * Se usa para generar documentación automática del código\n */\n\n// Creación de una variable\n$miVariable = \"Hola, PHP!\";\n\n// Creación de una constante\ndefine(\"MI_CONSTANTE\", 42);\n\n// Variables representando tipos de datos en PHP\n$miEntero = 10;\n$miFlotante = 3.14;\n$miBooleano = true;\n$miCadena = \"Esto es una cadena\";\n$miArray = array(1, 2, 3);\n$miArrayAsociativo = [\"clave\" => \"valor\"];\n$miNulo = null;\n\n// Impresión del texto solicitado\necho \"¡Hola, PHP!\\n\";\n\n// Impresión de los valores de las variables (opcional, para verificación)\necho \"miVariable: \" . $miVariable . \"\\n\";\necho \"MI_CONSTANTE: \" . MI_CONSTANTE . \"\\n\";\necho \"miEntero: \" . $miEntero . \"\\n\";\necho \"miFlotante: \" . $miFlotante . \"\\n\";\necho \"miBooleano: \" . ($miBooleano ? \"true\" : \"false\") . \"\\n\";\necho \"miCadena: \" . $miCadena . \"\\n\";\necho \"miArray: \" . print_r($miArray, true) . \"\\n\";\necho \"miArrayAsociativo: \" . print_r($miArrayAsociativo, true) . \"\\n\";\necho \"miNulo: \" . var_export($miNulo, true) . \"\\n\";\n\n// Demostración de tipos de datos adicionales en PHP\n$miObjeto = new stdClass();\n$miObjeto->propiedad = \"valor\";\necho \"miObjeto: \" . print_r($miObjeto, true) . \"\\n\";\n\n$miCallable = function() { return \"Soy una función anónima\"; };\necho \"miCallable: \" . $miCallable() . \"\\n\";\n\n// Demostración de tipado fuerte (disponible desde PHP 7)\nfunction sumaEntera(int $a, int $b): int {\n    return $a + $b;\n}\necho \"Suma entera: \" . sumaEntera(5, 3) . \"\\n\";\n\n?>"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/gabrielmoris.php",
    "content": "<?php\n\n// This is a single line comment: https://www.php.net/manual/en/\n\n/*this \nis \na \nmultiline \ncomment \n*/\n\n// Variables\n$variable =\"I am a siple basic variable.\"\n// Constants\n\ndefine(\"constant\", \"I am inmutable.\");\n\n// Strings\n$var = 'String';\n$multilineString ='This\nis\na\nmultiline\nstring';\n\n// Null\n$nullType = NULL;\n\n// Boolean\n$bool = True;\n\n// Numbers\n$decimal = 1234;\n$octals = 0123;\n$hechadecimal =0x1A;\n$binary = 0b11111111;\n\n// Floats\n$fl= 3.141632;\n\n// Arrays\n$arr =array(\n    \"key\"  => \"value\",\n    \"key2\" => \"value2\",\n    \"key3\" => \"value3\",\n);\n\n$arr2 = [\n    \"key\"  => \"value\",\n    \"key2\" => \"value2\",\n    \"key3\" => \"value3\",\n];\n\n// Objects\nclass obj \n{\n    function do_sth()\n    {\n        echo \"Hello, Php\";\n    }\n};\n\n$object = new obj;\n\n$object->do_sth();\n\n?>"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/guido2288.php",
    "content": "<?php\n  // Sitio Oficial:  https://www.php.net/manual/es/\n\n  // Diferentes sintaxis para crear comentarios:\n\n  // Comentario de una sola línea\n\n  /* Comentario\n     multilínea\n  */\n\n  # Comentario al estilo de consola\n\n  // Crea una variable (y una constante si el lenguaje lo soporta).\n\n  $nombre = 'Guido'; // variable\n  \n  define(\"apellido\", \"Garcia\"); // constante\n\n  // Crea variables representando todos los tipos de datos primitivos\n\n  $string = 'Esto es un string';\n  $int = 35;\n  $booleano = true;\n  $null = null;\n  $array = [\"Pepito\", \"Juancito\", \"Carlitos\"];\n  \n\n  // Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n  echo \"¡Hola, php!\";\n?>"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/jago86.php",
    "content": "<?php\n// https://www.php.net/\n\n// Comentario de una sola línea\n\n# Esto es un comentario\n\n/*\nComentarios de multiples\nlíneas\n*/\n\n$age = 37;\n\nconst NAME = 'Jairo';\n\n$boolean = true;\n$integer = 7;\n$float = 3.1416;\n$string = \"Hello world\";\n$array = [1, 2, 3, 4, 5];\n$object = new class {\n\n\tpublic $name = 'Jairo';\n\n\tpublic $age = 37;\n\n};\n$null = null;\n\necho \"¡Hola, PHP!\";"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/jarzatedev.php",
    "content": "<?php\n\n// this is a comment.\n\n// url for php: https://www.php.net\n\n// this is a single-line comment in PHP\n\n/*\n    this is a multi-line comment in php\n*/\n\n$myVarible = \"I'm a variable.\";\n\ndefine(\"CONSTANT\", \"I'm a constant\");\n\n$integer = 1;\n\n$float = 3.1416;\n\n$string = \"String\";\n\n$boolean = TRUE;\n\n$array = array(\"1\",\"2\",\"3\",\"4\",\"5\",\"6\");\n\nclass MyClass {\n    public $property = \"I'm a class property\";\n}\n\n$object = new MyClass();\n\n$resource = fopen(\"example.txt\",\"r\");\n\n$null = null;\n\necho \"Hello, PHP!\";\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/jhonnfl.php",
    "content": "<?php\n\n// https://php.net\n\n// Esto es un comentario en una línea\n\n/* \nEsto es un comentario\nde varias líneas\n*/\n\n// Crea una variable (y una constante si el lenguaje lo soporta).\n$variable = \"Esto es una variable\";\n\nconst CONSTANTE = \"Esto es una constante\";\n\ndefine(\"Constante 2\", \"Esto es una constante con define\");\n\n/*\nCrea variables representando todos los tipos de datos primitivos\ndel lenguaje (cadenas de texto, enteros, booleanos...).\n*/\n\n$variableNumeroEntero = 6;\n\n$variableBooleanoTrue = true;\n\n$variableBooleanoFalse = false;\n\n$variableNumeroFlotante = 54312.78;\n\n$variableNula = null;\n\n$variableString = \"PHP\";\n\n$variable_con_array = array(6, 8, 10);\n\n$array_con_corchetes = [5, 6, 7];\n\n$arrayAsociativo = [\n    \"nombre\" => \"Jhonn\",\n    \"apellido\" => \"Flores\",\n    \"Nacionalidad\" => \"VZLA\",\n];\n\n\n//Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\necho \"¡Hola, {$variableString}!\\n\";\necho \"Esto es una segunda forma de concatenar en \" . $variableString;\n?>"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/johannhsdev.php",
    "content": "<?php\n\n// RETO 00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO EN PHP\n\n //web oficial PHP: https://www.php.net\n\n // Este es un comentario de una linea en php con //\n\n/*\n    Este es un comentario de multiples lienas en php\n*/\n\n# Esto es un comentario de una sola línea con #\n\n// Crear una Variable en php\n$myVarible = \"I'm a variable.\";\n\n// Crear una constante en php\ndefine(\"MY_CONSTANT\", \"I'm a constant.\");\n\n// Crear variables de los tipos de datos primitivos en php\n$stringVar = \"Esto es una cadena de texto\"; // Cadena de texto\n$intVar = 123; // Entero\n$boolVar = true; // Booleano\n$floatVar = 12.34; // Número de punto flotante\n$arrayVar = array(\"elemento1\", \"elemento2\"); // Array\n$nullVar = null; // Null\n\n// Imprimir por terminal el texto: \"¡Hola, PHP!\"\necho \"¡Hola, PHP!\";"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/jonathanj20.php",
    "content": "<?php\n// https://www.php.net\n\n//Esto es un comentario de una sola línea.\n/**\n * Esto es un comentario\n * multilínea   \n * */\n\n#Este es un comentario al estilo Shell\n\n//definición de una variable \n$name = \"Jonathan\";\n\n//definición de una constante\n#El nombre de las constantes suelen escribirse en mayúsculas\ndefine(\"PI\", 3.1416);\nconst MY_CONST = \"value\";\n\n//Tipos de datos primitivos\n$integer = 12;\n$float = 12.4;\n$string = \"Hello\";\n$boolean = true;\n$null = null;\n\necho \"¡Hola, PHP!\";\n?>"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/kodenook.php",
    "content": "<?php\n\n// https://www.php.net\n\n# Comments\n\n// single-line comment\n# another single comment\n/*\n    this is a\n    multi-line comment\n*/\n\n# Variables and Constants\n\n$variable = 'variable';\ndefine('const', 'constant');\nconst const2 = 'another const';\n\n# Data types\n\n$string = 'string';\n$int = 1;\n$float = 2.5;\n$boolean = true; // true(1) or false(0)\n$array = ['saturday', 'sunday'];\n\n# Print\n\necho \"¡Hola, php!\";\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/kuroz00.php",
    "content": "<?php\n//https://www.php.net/\n\n//comentario de linea unica\n\n/*comentario\nde varias\nlineas */\n\n//variable/constante\n$edadPerro = 3;\ndefine('apodoPerro', 'thortilla');\nconst nombrePerro = 'thor';\n\n//Tipos de datos primitivos\n$numeroEntero = 1;\n$numeroFlotante = 1.5;\n$booleano = true;\n$string= \"texo dentro del string\";\n$arreglo = ['perro', 'gato', 'pajaro'];\n\n//imprimir por terminal hola php\n$lenguaje = \"PHP\"\necho \"¡Hola, \".$lenguaje;\n?>"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/manuelgomezg.php",
    "content": "// https://www.php.net/manual/es/index.php\n// comentario de una linea\n# Esto es un comentario al estilo de consola de una sola línea\n<!-- comentario\nde \nmultiples\nlineas -->\n<?php\n$name = \"PHP\"; // string\n$quantity = 33; // integer\n$price = 9.99; // float\n$paymentStatus = true; // boll\n$startDate = null; // Null\n// echo 'hola $name ';\necho \"Hola {$name} \";\n?>"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/marcode24.php",
    "content": "<?php\n/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n// - Crea una variable (y una constante si el lenguaje lo soporta).\n$miVariable = 'Hola, mundo';\n// Definir una constante en PHP (a partir de PHP 7.0)\ndefine('MI_CONSTANTE', 42);\n\n// - Crea variables representando todos los tipos de datos primitivos\n//   del lenguaje (cadenas de texto, enteros, booleanos...).\n$cadenaTexto = 'Hola';\n$numeroEntero = 42;\n$numeroDecimal = 3.14;\n$booleano = true;\n$bigInt = 9007199254740991; // PHP no tiene un tipo de dato BigInt como JavaScript\n$nulo = null;\n$indefinido = null; // En PHP, una variable sin valor asignado es nula\n$objeto = [\n  'nombre' => 'Pepe',\n  'edad' => 42,\n];\n$array = [1, 2, 3];\n\n// - Imprime por terminal el texto: \"¡Hola, PHP!\"\necho '¡Hola, PHP!';\n\n// Otra forma de imprimir por terminal con salto de línea\necho PHP_EOL;\n\n// Visita mi repo en GitHub para ver y correr los tests de este código --> https://github.com/marcode24/weekly-challenges\n?>\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/martireyes.php",
    "content": "<?php\n/* https://php.net/ */\n\n# Comentario de tipo Shell, de una sola línea\n// Comentario de tipo C++, también de una sola línea\n/* Comentario de tipo C\nque son de varias líneas*/\n\n$a = 'Esta es una variable';\ndefine(\"CONSTANTE\", \"Esta una constante con define()\");\nconst Constante = \"Esta es una constante con const\";\n\n#bool - Booleano\n$mi_bool = TRUE;\n$mi_bool = FALSE;\n\n#Integer - Número Entero\n$entero = 123;\n\n#String - Cadena de texto\n$texto = \"Variable de texto\";\n\n#float - Punto flotante\n$a = 1.234;\n\n#Para imprimir en la consola\necho \"¡Hola, PHP!\"\n?>"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/maurspi.php",
    "content": "<?php\n\n//URL DEL LENGUAJE ELEGIDO: https://www.php.net/manual/es/intro-whatis.php\n\n/*Comentarios \nmuchas \nlineas\n*/\n\n $variable = 0;\n//FORMAS DE DECLARAR CONSTANTES\n\nconst GATO_GORDO = \"PEPO\";\ndefine(\"CONSTANTE\", 8);\n\necho 'Valor de la primera constante: '. GATO_GORDO . PHP_EOL; // salto de linea php_eol\necho 'Valor de la segunda constante: '. CONSTANTE .PHP_EOL;\n\n//Datos primivitos. Es un lenguaje de tipado dinamico por eso no se declaran los tipos de datos\n$numero=123;\n$decimal=12.12;\n$esVerdad=true;\n$esFalso = false;\n$cadenaTexto='Hola Pepo';\n$otraCadenaDeTexto = \"Buenas tardes China\";\n$arreglos = array('Hola',12,332,\"tres\");\n$variableNula = null;\n\n$lenguaje = 'PHP';\n\necho 'Hola '. $lenguaje .PHP_EOL;\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/maussho.php",
    "content": "\n<?php\n\n    // 1. Crea un comentario con la URL del sitio oficial\n\n    # https://www.php.net/\n\n    // 2. Representa las diferentes sintaxis que existen de crear comentarios\n\n    /*\n        Hola mundo, esto es un comentario\n    */\n    \n    # Esto tambien es un comentario en php\n\n    // 3. Crea una variable y una constante si lo permite\n\n    # Variable\n    $nombre = \"mauri\";\n\n    # Constante\n    const valor = 23;\n    define(\"num\", 3);\n\n    // 4. Crea variables representando todos los tipos de datos primitivos\n\n    # Entero\n    $my_int = 2;\n\n    # String\n    $my_text = 'cadena de texto';\n    \n    # Boolean\n    $my_boolean = true;\n    $my_boolean = false;\n    \n    # Float\n    $my_float = 4.32;\n\n    # Null\n    $null = null;\n\n    // 5. Imprime por terminal el texto \"Hola [y el nombre del lenguaje]\"\n\n    echo \"Hola, el lenguaje es PHP\";\n?>\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/mayerga.php",
    "content": "<?php\n\n// Esto es un comentario de una sola línea de PHP\n// https://www.php.net/\n/* Esto es un comentario\n    de varias líneas */\n\n//Variable\n$mi_nombre = 'Manuel';\n\n//constante\ndefine('mi_nombre', 'Manuel');\n//Haciendo uso de mi variable\necho nombre;\n\n//Tipos de datos\n$var_null = NULL;\n$var_boolT = True;\n$var_boolF = False;\n$var_entero = 1234;\n$var_decimal = 123.4;\n$var_string = 'Hola, me llamo Manuel';\n\n  \n// a partir de PHP 5.4\n$arreglo = [\n    \"foo\" => \"bar\",\n    \"bar\" => \"foo\"\n];\n\n$nombreLenguage = \"PHP\";\n\necho \"¡Hola, \" . $nombreLenguage . \"!\";\nprint \"¡Hola, $nombreLenguage!\";\n?>"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/mensius87.php",
    "content": "<?php\n\n/*\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n * \n */\n\n// Existen tres tipos de comentarios:\n\n// Comentario de una sola línea\n\n# Otro comentario de una sola línea con otro formato\n\n/* Comentario multilínea:\n    línea\n    línea\n    línea\n*/\n\n\n/**\n * Comentario de documentación (lleva 2 astericos al principio). Sirve para generar docuemntación\n * automáticamente.\n * Esta es una descripción de la función\n * \n * Más detalles sobre esta función aquí.\n */\n\n// variables\n$variableString = \"Hola MoureDev\"; // variable String\n$variableInteger = 12; // variable entera\n$variableFloat = 12.5; // variable decimal\n$variableBoolean = true; // variable booleana\n$variableArray = array(\"a\", \"b\",\"c\"); // variable tipo array\n\n// Constantes\nconst CONSTANTEPI = 3.14; // forma de crear constante (debe de ir en mayúscula)\ndefine(\"CONSTANTEPI2\",3.14); // otra forma de crear constante, también tiene que ir en mayúscula\n\n$nombreLenguage = \"PHP\";\n\n// Imprimir mensaje con el nombre del lenguaje\necho \"¡Hola, \" . $nombreLenguage . \"!\";\n?>"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/miguelex.php",
    "content": "<?php\n\n// Puedes encontrar la documentación en https://www.php.net/\n\n// Comentario de una línea\n\n/* Este es un ejemplo\n  de como podemos poner un \n  comentario en varías líneas\n*/\n\n$lenguaje = \"php\"; // Declaración de una variable de tipo string\n\n\ndefine(\"PI\", 3.14); // Declaracion de constante\nconst e = 2.7182; // Otra forma de declarar constantes\n\n// Tipos de datos\n\n$entero = 3; // Tipo entero\n$booleano = true; // booleano. Solo toma valores true o false\n$real = 125.00; // Tipo float\n$nulo = null; // Tipo null \n$cadena = \"Hola\"; // Tipo string\n$arreglo = array(1, 2, 3); // Tipo array\n$otro_arreglo = [1, 2, 3]; // Otra forma de declarar un arreglo\n$asociativo = array(\"nombre\" => \"Juan\", \"apellido\" => \"Perez\"); // Arreglo asociativo\n$otro_asociativo = [\"nombre\" => \"Juan\", \"apellido\" => \"Perez\"]; // Otra forma de declarar un arreglo asociativo\n$fecha = new DateTime(); // Tipo objeto\n\n// Imprimir en pantalla\necho $cadena . ' ' . $lenguaje.\"\\n\";\nprint \"El numero entero es $entero\\n\";\nprint \"El numero real es $real\\n\";\nprint \"El numero PI es \".PI.\"\\n\";\nprint \"El numero e es \".e.\"\\n\";\nprint \"El valor nulo es $nulo\\n\";\nprint \"El valor booleano es $booleano\\n\";\nprint \"El arreglo es $arreglo[0], $arreglo[1], $arreglo[2]\\n\";\nprint \"El arreglo asociativo es $asociativo[nombre] $asociativo[apellido]\\n\";\n\n\n?>"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/pabloTaber.php",
    "content": "<?php\n\n/* --- Crea un comentario en el código y coloca la URL del sitio web \n    oficial dellenguaje de programación que has seleccionado. --- */ \n\n    //Sitio web oficial de php: https://www.php.net\n\n/* --- Representa las diferentes sintaxis que existen de crear comentarios\n    en el lenguaje (en una línea, varias...). --- */\n\n    // Comentario de una linea.\n\n    /* Comentario\n        de varias\n        lineas \n    */\n\n// --- rea una variable (y una constante si el lenguaje lo soporta). --- \n\n    //variable\n    $variable = \"Esto es una variable.\";\n\n    //Constante\n    define(\"CONSTANTE\", \"Esto es una constante\");\n\n /* --- Crea variables representando todos los tipos de datos primitivos\n    del lenguaje (cadenas de texto, enteros, booleanos...). --- */   \n\n    //Boolean\n    $verdadero = true;\n    $falso = false;\n\n    //Integer\n    $numeroEntero = 10;\n    $numeroEnteroNegativo = -10;\n\n    //Float\n    $numeroReal = 1.5;\n\n    //String\n    $comillasDobles = \"Estas comillas expanden el contenido de las variables. Ej: numeroEntero es igual a $numeroEntero\";\n    $comillasSimples = 'Estas comillas no expanden el contenido de las variables';\n\n    //Array\n        //Array Indexado.\n        $arrayIndexado = array (\"Hola\", \"a\", \"todos\"); \n        $arrayIndexado2[0] = \"Hola\"; //Tambien se pueden asignar valores directamente, los 2 arrays son iguales.\n        $arrayIndexado2[1] = \"a\";\n        $arrayIndexado2[2] = \"todos\";\n\n        //Array Asociativo.\n        $arrayAsociativo = array ( \"es\" => \"Hola\", \"gz\" => \"Ola\", \"pt\" => \"Olá\");\n        $arrayAsociativo2[\"es\"] = \"Hola\"; //Tambien se pueden asignar valores directamente, los 2 arrays son iguales.\n        $arrayAsociativo2[\"gz\"] = \"Ola\";\n        $arrayAsociativo2[\"pt\"] = \"Olá\";\n        \n    //Object\n    class Objeto {\n        public $descripcion = \"Soy un objeto\";\n    }\n\n    $objeto = new Objeto();\n\n    //Null\n    $nulo = NULL;\n    $tambienNulo; \n\n// --- * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\" \n\n    $lenguaje = \"PHP\";\n    echo \"¡Hola, $lenguaje!\";"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/qv1ko.php",
    "content": "<?php\n\n    # #00 - Sintaxis, variables, tipos de datos y hola mundo\n\n    # www.php.net\n\n    main();\n\n    function main() {\n\n        /* comment */\n\n        // comment\n\n        # comment\n\n        $var1 = 1;\n\n        define(\"VAR2\", 2);\n\n        $str = 'PHP';\n        $var3 = 3;\n        $var4 = 4.4;\n        $bool = true;\n\n        echo \"¡Hola, \" . $str . \"!\";\n\n    }\n\n?>\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/rocallejas.php",
    "content": "<?php\n\n# Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n\n    // https://www.php.net\n\n# Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n\n    // Este es un ejemplo de comentario de una sola línea\n\n    # Esta es otra forma de crear un comentario de una sola línea, aunque no es lo común\n\n    /*\n        Este es un comentario\n        que abarca varias líneas\n    */\n\n    /**\n     * Los DocBlocks en PHP son comentarios de documentación especialmente formateados que se utilizan\n     * para describir elementos del código, como funciones, clases, métodos, propiedades, y otros.\n     * Estos comentarios están diseñados para ser interpretados por herramientas externas que generan documentación automáticamente,\n     * como PHPDocumentor o Doxygen.\n     *\n     * @param string $nombre Nombre de la persona\n     * @param int $edad Edad de la persona\n     * @return string Saludo personalizado\n     */\n    function saludar($nombre, $edad) {\n        // Implementación de la función\n    }\n\n# Crea una variable (y una constante si el lenguaje lo soporta).\n\n    // Variable\n    $miVariable = \"Asignamos un texto como valor de la variable\";\n\n    // Constantes\n    // Usando la función define()\n    define(\"MI_CONSTANTE\", \"Hola mundo.\");\n    // Usando la palabra reservada 'const' fuera de la definición de una clase a partir PHP 5.3.0\n    const OTRA_CONSTANTE = 'Hola Mundo';\n\n# Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n    # PHP maneja ocho (8) tipos de datos primitivos:\n    // Tipo entero\n    $entero = 16;\n\n    // Tipo punto flotante (número decimal)\n    $flotante = 3.14;\n\n    // Tipo cadena de texto\n    $cadena = \"¡Hola, PHP!\";\n\n    // Tipo booleano\n    $verdadero = true;\n    $falso = false;\n\n    // Tipo arreglo (array)\n    $arreglo = array(1, 2, 3, \"cuatro\", 5.5); // Es común tener arreglos con elementos de diferentes tipos de datos\n    $arregloIndexado = array(\"Manzana\", \"Banana\", \"Cereza\");\n    $arregloAsociativo = array(\"nombre\" => \"John Doe\", \"edad\" => 30, \"ciudad\" => \"Raccoon City\");\n    $arregloMultidimensional = array(\n        array(\"Manzana\", \"Banana\", \"Cereza\"),\n        array(\"Rojo\", \"Amarillo\", \"Rojo\"),\n        array(\"Dulce\", \"Dulce\", \"Ácido\")\n    );\n    $arregloLista = [\"Elemento 1\", \"Elemento 2\", \"Elemento 3\"]; // Arreglo con Sintaxis Corta (PHP 5.4+)\n    $arregloCorto = [\"nombre\" => \"María\", \"edad\" => 25, \"ciudad\" => \"Barcelona\"]; // Arreglo Asociativo con Sintaxis Corta (PHP 5.4+)\n\n    // Tipo objeto (a partir de una clase definida)\n    class MiClase {\n        public $propiedad;\n\n        public function __construct($valor) {\n            $this->propiedad = $valor;\n        }\n    }\n\n    $objeto = new MiClase(\"Valor del objeto\");\n\n    // Tipo recurso (utilizado para manejar recursos externos, como archivos)\n    $archivo = fopen(\"archivo.txt\", \"r\");\n\n    // Tipo nulo\n    $nulo = null;\n\n# Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n    // Forma 1: echo\n    echo $cadena; // Salida: ¡Hola, PHP!\n\n    // Forma 2: print\n    print $cadena; // Salida: ¡Hola, PHP!\n\n    // Forma 3: printf (formateo)\n    printf(\"Mensaje: %s\", $cadena); // Salida: Mensaje: ¡Hola, PHP!\n\n    // Forma 4: sprintf (similar a printf, pero devuelve la cadena formateada en lugar de imprimirla)\n    $mensaje_formateado = sprintf(\"Saludo: %s\", $cadena);\n    echo $mensaje_formateado; // Salida: Saludo: ¡Hola, PHP!\n\n?>"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/samuel20-dev.php",
    "content": "<?php\n\n/*\ndocumentacion oficial de PHP:\nhttps://www.php.net/manual/es/\n*/\n\n// Este es un comentario de una linea\n# Este tambien es un comentario de una linea\n\n/*\n   Este es un comentario multilinea \n   en php.\n*/\n\n\n// variables\n$my_variable = \"hola mundo\";\n$my_variable = \"nuevo valor\";\n\n// constantes ( const , define)\nconst CONSTANTE = \"HOLA\"; #constante con \"const\"S\ndefine('CONSTANTE_CON_DEFINE', \"Esta tambien es una constante\"); #constante con define\n\n\n#Variables con todos los tipos de datos primitivos\n$my_int = 12;\n$my_float = 23.02;\n$my_str = \"carlos\";\n$my_str2 = 'samuel';\n$my_bool = false;\n\n// Imprimir por terminal (echo, print)\necho \"¡Hola, PHP!\";\necho \"Imprimiendo texto con Echo.\";\necho \"Echo no es una funcion, y no es necesario\nutilizar parentesis, ademas, hace salto de linea.\n\";\n\nprint(\"Hola mundo!\");\nprint 'Print tambien funciona sin parentesis';\nprint \"Tambien serpara los\nsaltos de lineas utilizando print.\";\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/trollface77.php",
    "content": "<?php\n\n/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n\n\n// Lenguaje seleccionado PHP https://www.php.net/\n\n# Comentario en una sola linea\n\n/* \nComentario en varias lineas\n*/\n\n# VARIABLE\n$variable = \"Soy una variable\"; \n\n$variable = \"Acabo de cambiar el valor de esta variable\";\n\n# CONSTANTE\ndefine (\"CONSTANTE\",  \"Soy una constante\");\nconst CONSTANTE1 = \"Creaste otra constante satisfactoriamente\"; \n\n\n#string \n\n$str = \"Soy un string\";\n\n#integer == numero entero \n\n$integer = 1; \n\n#float == numero decimal \n\n$float = 0.3 ;\n\n#booleano \n\n$verdader0 = true; \n$falso = false; \n\n#null \n\n$nulo = null; \n\n#array \n\n$lista_simple = [\"papel\", \"jabon\", \"hielo\", \"madera\"]; \n\n#array asociativo \n\n\n$lista_cantidades = [\n        \"arroz\" => \"bastante\",\n        \"fideos\" => \"tambien\",\n        \"cristale\" => \"masomenos\" \n];\n\n\necho $lista_simple[0]; \n\necho $lista_cantidades['cristale'];\n\necho \"Hola, PHP\";\n\nvar_dump($str);\n\nvar_dump($integer);\n\nvar_dump($float);\n\nvar_dump($verdader0);\n\nvar_dump($falso);\n\nvar_dump($lista_cantidades['fideos']);\n\nvar_dump(CONSTANTE);\nvar_dump(CONSTANTE1);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/php/zarakilancelot.php",
    "content": "<?php\n// Realizado con https://www.php.net/\n\n// Comentario de una línea\n/* Comentario\n  de varias\n  líneas\n*/\n\n$variable = \"Una variable\";\nconst CONSTANTE = \"Una constante\";\n\n// Numéricos\n$entero = 12345;\n$flotante = 1.2345;\n\n// Nulo\n$nulo = NULL;\n\n// Booleanos\n$verdadero = True;\n$falso = False;\n\n// Cadenas / Strings\n$cadena = \"PHP\";\n$cadena_larga = <<<EOD\n  Esta es una cadena\n  que ocupa varias líneas\n  y que se escribe\n  tal cual con la sintaxis\n  heredoc.\nEOD;\n\n// Arreglos\n$arreglo = array(\n  \"foo\" => \"bar\",\n  \"bar\" => \"foo\"\n);\n\n// a partir de PHP 5.4\n$otro_arreglo = [\n  \"foo\" => \"bar\",\n  \"bar\" => \"foo\"\n];\n\necho \"¡Hola, $cadena!\";\nprint \"¡Hola, $cadena!\";\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/prolog/blfuentes.pl",
    "content": "% https://www.swi-prolog.org/\n\n% Esto también es para\n% comentarios multi-línea\n\n% Tipos de datos\n% Data objets\n% - Structures\n% - Simple Objects\n%   - Variables\n%   - Constants\n%       - Numbers\n%       - Atoms\n\n% variables en un fact\npersona(blfuentes, 38, ingeniero).\n% pare recuperar los valores en variables. ejecutando por ejemplo persona(X, Y, ingeniero).\n% ?- persona(X, Y, ingeniero).\n% X = blfuentes,\n% Y = 38.\n\n% variables en una rule\nparent(uno, dos).\nparent(dos, tres).\nmale(uno).\n\npadre(X, Y) :- parent(X, Y), male(X).\n\n% en prolog no hay booleanos, los facts se evalúan en éxito o fracaso\n% ?- male(uno). -> devuelve true.\n% ?- male(dos). -> devuelve false.\n\nmain :- write(\"¡Hola, prolog!\")."
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/ JesusAcst.py",
    "content": "# Comentario en una línea\n\n\"\"\"\nComentario en varias líneas\n\"\"\"\n\n# https://www.python.org/\n\n# -----------------------------\n# Variables\n# -----------------------------\nlenguaje = \"Python\"\nsaludo = \"¡Hola, \"\nsigno = \"!\"\n\n# Concatenación\nmensaje = saludo + lenguaje + signo\n\nmy_int = 3\nmy_float = 1.0\nmy_bool = True\n\n# -----------------------------\n# Constantes\n# -----------------------------\nMY_CONSTANT = \"Este es un valor constante\"\n\n# -----------------------------\n# Funciones\n# -----------------------------\ndef suma(a, b):\n    \"\"\"\n    Esta función recibe dos números\n    y retorna su suma.\n    \"\"\"\n    return a + b\n\n# -----------------------------\n# Salida por consola\n# -----------------------------\nprint(mensaje)\nprint(\"La suma es:\", suma(1, 2))\n\n# -----------------------------\n# Tipos de datos\n# -----------------------------\nprint(type(my_int))\nprint(type(my_float))\nprint(type(my_bool))\nprint(type(lenguaje))\nprint(type(MY_CONSTANT))\nprint(type(suma))\n\n# -----------------------------\n# Documentación de la función\n# -----------------------------\nprint(suma.__doc__)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/033A130.py",
    "content": "# https://python.org\n\n# => Esto es un comentario en una línea en Python.\n\n\"\"\"\nAsí se crean comentarios \nmultilínea en Python.\n\"\"\"\n\n'''\nTambién podemos usar comillas simples\npara comentarios multilínea.\n'''\n\n# Variables en Python.\n\"\"\"En Python, es una convención nombrar las variables en formato `snake_case`,\nes decir, todo en minúsculas y separado por guiones bajos.\n\"\"\"\n\n# Tipo de variable tipo cadena de texto = string.\n\"\"\"Cuando asignamos un valor entre comillas (simples o dobles), la variable\nautomáticamente toma el tipo `str` (cadena de texto). Incluso si parece un número.\n\"\"\"\n\nmy_variable = \"¡Hola, esta es mi variable!\"\n\nmy_string = \"¡Esta es una string!\"\nmy_other_string = '¡También esta es una string!'\n\nmy_variable_saludos = \"¡Hola Python!\"\n# Las variables pueden cambiar de valor. Hasta este punto, `my_variable` es:\n# \"¡Hola, esta es mi variable!\". Ahora le asignamos un nuevo valor:\nmy_variable = \"Ahora mi variable ha tomado este nuevo valor de texto.\"\n\n# Tipo de variable tipo entero = int\n\"\"\"Si creamos una variable y le asignamos un número sin comillas,\nel tipo asignado será automáticamente un entero (`int`).\"\"\"\n\nmy_int = 1 \n\n# Tipo de variable tipo flotante = float\n\"\"\"Si creamos una variable y le asignamos un número decimal (separado por un punto,\nno por una coma), el tipo asignado será automáticamente flotante (`float`).\n\"\"\"\n\nmy_float = 1.735\n\n# Tipo de variable tipo booleano = bool\n\"\"\"Las variables booleanas (`bool`) solo pueden tener dos valores posibles:\n`True` o `False` (en mayúsculas, ya que son palabras clave de Python).\n\"\"\"\n\nmy_bool = True \nmy_second_bool = False \n\n# Constantes en Python.\n\"\"\"En Python, las constantes no existen como tal. Sin embargo, por convención,\nse escriben con letras mayúsculas para indicar que no deberían modificarse.\nAunque técnicamente, su valor puede cambiar.\n\"\"\"\n\nMY_CONSTANTE = \"Mi Constante\"  # Por convención.\n\n# Aquí cambiamos el valor de la \"constante\", aunque no debería hacerse.\nMY_CONSTANTE = \"¡Mi Constante ha cambiado de valor!\"\n\n# Maneras de imprimir un valor, una variable o una CONSTANTE por convención.\nprint(\"Hello World!\")  # Si queremos imprimir un número u otro tipo, no ponemos comillas.\nprint(my_variable_saludos)\nprint(MY_CONSTANTE)\n\n# Manera de imprimir el tipo de una variable.\n# La función `type` nos muestra el tipo de una variable.\nprint(type(my_string))  # Salida: <class 'str'>\nprint(type(my_int))     # Salida: <class 'int'>\nprint(type(my_float))   # Salida: <class 'float'>\nprint(type(my_bool))    # Salida: <class 'bool'>\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/13sauca13.py",
    "content": "# www.python.org\n\n# Esto es un comentario de una sola linea, se realiza con #\n\n\"\"\"\nEsto es un comentario multilinea\nPuede escribirse en diferentes lineas\nSe abre con tres comillas simples ( ' ) o con tres comillas dobles (como las usadas en este comentario)\nY se cierra de la misma manera\n\nOJO: se pueden usar dentro del bloque las comillas que no hayamos usado para abrir el bloque\nSi usasemos las mismas cerrariamos el comentario sin querer\nPor ejemplo en este puedo usar las simples sin problema '''''''\n\"\"\"\n\n'''\nAqui puedo usar comillas dobles si quiero \"\"\"\"\"\"\"\"\"\"\"\"\n'''\n\n\n# Tipos de datos primitivos\nCONSTANTE = \"esta es sólo la manera de escribir su nombre por convencion, Python no tiene constantes\"\ncadena = \"esto es una string\"\nentero = 5\nflotante = 4.2\ncomplejo = 4j\nbooleano = False\nlista = [1,dos,3]\ntupla = (uno,2,tres)\ndiccionario = {\"valor1\":1,\"valor2\":\"dos\"}\n#Es importante recalcar que una cosa son las funciones primitivas de python y otras son tipos de datos integrados para almacenar y manipular colecciones de elementos. \n\n# Imprimiendo el nombre del lenguaje\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/59822.py",
    "content": "# Link de la página de Python: https://www.python.org/\n\n#Comentario de una línea\n\n\"\"\" \nComentario de \nvarias lineas\n\"\"\"\n\n'''\nComentario de varias lineas\n'''\nsaludo = \"hola\"\nMY_CONST_SAL = \"Hola amigos\" #Hacer una constante de variable\n\nvariable_float = 4.255\nvariable_int = 2\nvariable_bool1 = True\nvariable_bool2 = False\nvariable_string = \"Hola mundo\"\n\nprint(\"¡Holaaa  Pythonn!\")\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n-- INSERT --\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/90dread.py",
    "content": "# https://www.python.org/\r\n\r\n# Comentarios en Python\r\n# La # se usa para comentarios simples\r\n\r\n\"\"\"El \\\"\"\"\\ se usa para comentarios multiples\"\"\"\r\n\r\n# Creando una variable y asignandole un valor\r\na = 10\r\n\r\n# Esto es una constante\r\nNone\r\n\r\n# Variables para cada tipo de datos\r\n# Numeros\r\nnum = 10\r\n\r\n# String\r\nnombre = \"90dread\"\r\n\r\n# Boolean\r\nvalor = True\r\n\r\n# Listas\r\nlista = [1, 2, 3, 4, 5]\r\n\r\n# Tuplas\r\ntupla = (1, 2, 3, 4, 5)\r\n\r\n# Diccionarios\r\npersona = {\"nombre\": \"90dread\", \"edad\": 33}\r\n\r\n# Imprimiendo en pantalla\r\nprint(\"Hola, Python\")\r\n\r\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/AChapeton.py",
    "content": "# https://www.python.org/\n\n# Comentario de una linea\n\"\"\"\n  Comentario\n  en varias\n  lineas\n\"\"\"\n\n#Crear variables\nx = 'Nombre'\ny = 5\n\n#En Python no existe el concepto de constantes, pero en la cominidad se representan declarando una variables en mayusculas\nPI = 3.1416\n\n#Tipos de datos primitivos\n\n#String\nmy_string = \"Hello\"\n\n#Enteros\nmy_number = 10\nmy_float = 2.5\n\n#Booleanos\nmy_boolean = True\nother_boolean = False\n\n#None - Ausencia de valor\nmy_none = None\n\nname = 'Python'\nprint('¡Hola, ' + name + \"!\")\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/AMG-AA.py",
    "content": "# 00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUND#\n\n# https://python.org\n\n# Comentario de uns sola línea\n\n'''\nComentario de \nvarias líneas\n'''\n\n\"\"\"\nComentario de\nvarias líneas\n\"\"\"\n\nmivariable = \"Hello, World!\"\nmivariable = \"Actualizando el valor de la variable\"\n\nMI_CONSTANTE = \"Soy una constante\" # Las constantes se escriben en mayúsculas\n\nmiInt = 5\nmiFloat = 3.1416\nmiBool = True # False\nmiString = \"Hola Mundo\"\nmiList = [1, 2, 3, 4, 5]\nmiDict = {\"nombre\": \"Juan\", \"apellido\": \"Perez\"}\nmiTuple = (1, 2, 3, 4, 5)\nmiSet = {1, 2, 3, 4, 5}\nmiNone = None\n\nprint(\"Comienzo los retos de programción en Python\")\n\nprint(type(miInt))\nprint(type(miFloat))\nprint(type(miBool))\nprint(type(miString))\nprint(type(miList))\nprint(type(miDict))\nprint(type(miTuple))\nprint(type(miSet))\nprint(type(miNone))\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/AMitchellG.py",
    "content": "# Pagina Web: https://www.python.org/\n\n# COMENTARIOS\n\n# Esto se usa para un comentario de una sola linea\n\n\"\"\"\nEsto da referencia a un comentario en multiples lineas codigo\n\"\"\"\n\n'''\nOtra forma de comentar multiples lineas de codigo\n'''\n\n# VARIABLES Y CONSTANTES\n\nvariable = \"nueva variable\"\nCONSTANTE = 99\n'''En el caso de python una constante \nes mas una convencion que una restriccion, y estas se representan poniendo su nombre en mayusculas'''\n\n# VARIABLES DE TIPO PRIMITIVO\n\n# Enteros (int)\nentero = 99\n\n# Flotantes (float)\nflotante = 2.99\n\n# Cadenas de Texto (str)\nstr = \"Cadena de texto\"\n\n# Booleanos (bool)\nverdadero = True\nfalso = False\n\n# Nulos (nonetype)\nvalor_nulo = None\n\n# Mensaje saludando con el lenguaje que quiero aprender\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/AbelPerezCollado.py",
    "content": "# https://www.python.org\n\n# Comentario en una linea\n\n'''\nComentario\npara\nvarias\nlineas \n\n'''\n# Variable en python\nvariable = None\n\n# Tipos de datos\nnum = 100\ncadena = 'Cadena de caracteres'\nf_num = 100.50\nb_var = True\nb_var_2 = False\nsin_asignar_tipo = None\n\n# Imprimir por consola nombre del lenguaje\n\nlenguaje = 'Python'\nprint(f\"¡Hola, {lenguaje}!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/AdamTormer.py",
    "content": "#https://www.python.org/\n\n#Asi se crea una comentario en una linea en phyton colocando un # y despues del comentario \n\n\"\"\"\" con tripe comillas puedo colocar varias lineas de comentario \npara utilizarlo tiene que abrir triple comillas y cerrar con triple comillas\nasi se crea varias lineas de comentario\n\"\"\"\n\nmi_varibles = \"lo que va a valga\"\nmi_constant = \"un valor constante\"\n\nmi_int =3\nmi_flot =3.14\nmi_bool =True \nmi_bool=False\nmi_string=\"cadena de texto\"\n\nprint(\"hola, mundo\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Adirv5.py",
    "content": "# https://www.python.org/\n\n# Comentario en una linea\n\n\"\"\"\nEsto tambien es un comentario multilinea\"\"\"\n''' \nEsto tambien es un comentario multilinea'''\n\nmy_variable = \"Mi primera variable\"\nmy_variable = \"Nuevo valor de mi variable\"\nMY_CONSTANTE = \"Mi primera constante\" # Por convencion, las constantes se escriben en mayusculas\nmy_integer = 10\nmy_float = 10.5\nmy_boolean = True\nmy_boolean = False\nmy_string = \"Hola, soy una cadena de texto\"\nmy_other_string = 'Hola, tambien puedo usar comillas simples'\n\nprint(\"Hola, Python!\")\nprint(my_variable)\nprint(MY_CONSTANTE)\nprint(my_integer)\nprint(my_float)\n\n\"comentario para verificar que el codigo se ejecuta correctamente\"\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/AdrianRuizC.py",
    "content": "#Este es el comentario de el link de python: https://www.python.org/\n\n'Este es un comentario de una sola linea'\n\n'''\nEste es un comentario de varias lineas \n'''\n\n\"Este es otro comentario de una sola linea\"\n\n\"\"\"\nEste es otro comentario de varias lineas\n\"\"\"\n\n# Comentario de una sola linea con el simbolo numeral\n\n\n####\n# este es un comentario de varias lineas\n####\n\nMi_Variable = \"Esta es una variable en Python\"\n\nMI_CONSTANTE = \"Esta es la representacion de una constante en Python\"\n\nprint(Mi_Variable)\nprint(MI_CONSTANTE)\n\n# ESTOS SON TIPOS DE DATOS EN PYTHON\n\nNumero_Entero = 10 #int por Messi \nNumero_Decimal = 10.5 #float \nCadena_de_Caracteres = \"Hola Mundo, Hola python\" #str\nValor_Booleano = True #bool\nValor_Nulo = None #NoneType\nLista = [1, 2, 3, 4, 5] #list\nTupla = (1, 2, 3, 4, 5) #tuple\nConjunto = {1, 2, 3, 4, 5} #set\nDiccionario = {\"clave1\": \"valor1\", \"clave2\": \"valor2\"} #dict\nRango = range(1, 10) #range\nBytes = b\"Hola\" #bytes\nBytearray = bytearray(5) #bytearray\nMemoria_Vista = memoryview(bytes(5)) #memoryview\nComplejo = 1 + 2j #complex\n\nprint(type(Numero_Entero))\nprint(type(Numero_Decimal))\nprint(type(Cadena_de_Caracteres))\nprint(type(Valor_Booleano))\nprint(type(Valor_Nulo))\nprint(type(Lista))\nprint(type(Tupla))\nprint(type(Conjunto))\nprint(type(Diccionario))\nprint(type(Rango))\nprint(type(Bytes))\nprint(type(Bytearray))\nprint(type(Memoria_Vista))\nprint(type(Complejo))\n\nLenguaje = \"Python\"\n\nprint(\"!Hola,\" '' + Lenguaje + \"!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Adricego.py",
    "content": "#utilizaré Python para desarrollar estos retos https://www.python.org\n\n#Este es un comentario\nprint(\"Hola, Mundo\") #También se pueden ingresar al final de una línea de código.\n\n#Se pueden hacer\n#comentarios\n#en varias líneas\n\n\"\"\"\nEsto es un comentarios \nescríto en varias líneas\nigual que el anterior, para esto\nse usan tres comillas dobles (\"\").\n\"\"\"\n\n# Constante (se escriben en mayúsculas)\nPI = 3.1416\n\n# Variables con todos los tipos de datos primitivos en Python\n\nentero = 1          # Entero (int) \ndecimal = 1.1       # flotante (float)\nbooleano = True     # Booleano (bool)\ntexto = \"hola\"      # Cadena de texto (str)\nnulo = None         # tipo especial (NoneType)\n\n# Variables y f-strings\nlenguaje = \"Python\"\n\nprint (f\"hola, {lenguaje}\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/AgustinDamonte17.py",
    "content": "# https://www.python.org\n\n#Comentario en una línea\n\n\"\"\"\nEsto también es\nun comentario\nen varias líneas\n\"\"\"\n'''\nEsto también es\nun comentario\nen varias líneas\n'''\n\nmi_variable = \"Mi variable\"\nmi_variable = \"Nuevo valor de variable\"\n\nMI_CONSTANTE = \"Mi constante\" #por convención\n\nmy_int = 666\nmy_float = 1.5\nmy_bool = True\nmy_bool = False\nmy_string = \"Wont stop until I reach 1 billion dollars\"\n\nprint(\"Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/AkaiSombra.py",
    "content": "\n# Author: Nicolas Romero https://github.com/AkaiSombra\n\n\"\"\" \n * EJERCICIO:\n * 1. Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * 2. Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * 3. Crea una variable (y una constante si el lenguaje lo soporta).\n * 4. Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * 5. Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\"\"\"\n\n\n# Ejercicio 1:\n# Sitio oficial de Python: https://www.python.org\n\n# Ejercicio 2:\n\n# Comentario de una linea en Python.\n\n\"\"\" \nComentario de varias lineas\nen Python con comillas dobles.\n\"\"\"\n\n'''\nComentario de varias lineas\nen Python con comillas simples.\n'''\n\n# Ejercicio 3: \n\n# Variable\n\nvar = 2\n\n\"\"\"\nPython no posee constantes pero si escribimos \nuna varible en mayusculas se toma como una const\npero solo a nivel de semantica\n\"\"\"\n\nTHIS_IS_A_CONSTANT = 25\n\n# Ejercicio 4:\n\n# Datos primitivos\n\n# Entero(int)\nint_number = 2\n\n# Numero de punto flotante(float)\nfloat_number = 2.5\n\n# Cadena de texto (str)\nstring = \"Cadena de texto\"\n\n# Booleanos (bool)\nboolean_True = True\nboolean_False = False\n\n# Nulo (NoneType)\n\nNulo = None\n\n# Ejercicio 5:\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/AlainMartz.py",
    "content": "# https://www.python.org/\n\n\n### Sintaxis de comentarios ###\n\n## Comentarios de una línea ##\n\n# Por sus propios medios - Robert A. Heinlein    \n'Wilson no tenía razón alguna para sospechar que hubiera nadie más en su habitación:'\n\"de hecho, tenía todas las razones del mundo para esperar justamente lo contrario.\"\n\n\n## Comentarios multilínea ##\n\n# Se había encerrado en su habitación con el propósito\n# de terminar su tesis de una sola sentada. Tenía que hacerlo: mañana era el\n# último día del plazo y ayer la tesis no era todavía más que un título. «Una\n# investigación sobre ciertos aspectos matemáticos del rigor metafísico». \n''' \nCincuenta y dos cigarrillos, cuatro cafeteras y trece horas de trabajo sin parar\nhabían añadido siete mil palabras al titulo. En cuanto a la validez de su tesis,\nestaba demasiado aturdido por el cansancio como para que eso le importara lo\nmás mínimo. Lo único que pensaba era: acaba con ella, escríbela, entrégala,\ntómate tres copas llenas hasta el borde y duerme durante una semana entera. \n'''\n\"\"\"\nAlzó los ojos y los dejó vagar sobre la puerta de su armario tras la cual había\nescondido una botella de ginebra, casi llena. No, se amonestó en silencio, un\ntrago más y nunca terminarás tu tesis, viejo amigo. \n\"\"\"\n\n### Creación de variable ###\n\nautor = \"Robert A. Heinlein\" # Variable\nAUTOR = \"R.A.H.\" # Las mayúsculas son un convención para definir constantes, aunque esta sea realmente una\n\n### Tipos de datos primitivos ###\n\ntitulo = \"Por sus propios medios\" # Tipo string / cadena\naño = 1941 # Tipo integer / int / entero\ncalificación = 4.01 # Tipo float / flotante\nfallecido = True # Tipo boolean / bool / booleano\n\nprint (\"Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/AlbertoMorilla.py",
    "content": "# Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n\n# #https://www.python.org/\n\n# Asi se puede crear un comentario\n\n\"\"\"Asi tambien se puede\ncrear un comentario\"\"\"\n\n'''Esta es otra manera \nde crear un comentario'''\n\n# Crea una variable\n\nmi_variable = 'Variable'\nmi_variable = 'Modificacion de la variable'\n\nprint(mi_variable)\n\n#Constante\nConstante = 3.1415\n\n#Tipos de datos primitivos del lenguaje\n\nmi_int = 13\nmi_str = 'Frase creada'\nmi_float = 0.13\nmi_bool = True\nmi_boole = False\nmi_otro_str = 'Nuevo string'\nmi_lista = ['verde', 'blanco', 'azul']\nmi_dicc = {'colores': ('verde', 'blanco'), 'equipo': ('real', 'betis')}\nmi_tupla = ('naranja', 'rojo', 12, 249)\nset = {1, 2, 3}\n\nprint(type(mi_int), mi_int)\nprint(type(mi_str), mi_str)\nprint(type(mi_float), mi_float)\nprint(type(mi_bool), mi_bool)\nprint(type(mi_boole), mi_boole)\nprint(type(mi_otro_str), mi_otro_str)\nprint(type(mi_lista), mi_lista)\nprint(type(mi_dicc), mi_dicc)\nprint(type(mi_tupla), mi_tupla)\nprint(type(set), set)\n\n#Imprimir Saludo\n\nprint(f'¡Hola, Python!')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Albertosogasol.py",
    "content": "# URL del sitio oficial de Python: https://www.python.org/\n\n# Comentarios de una línea:\n# Este es un comentario de una sola línea en Python\n\n# Comentarios de múltiples líneas (uso de comillas triples):\n\"\"\"\nEste es un comentario de varias líneas.\nPuedes usar comillas triples para comentarios largos.\n\"\"\"\n\n# Variables y tipos de datos primitivos\nnombre = \"Python\"  # Cadena de texto\nedad = 30  # Entero\nes_programador = True  # Booleano\naltura = 1.75  # Float (número decimal)\n\n# Constante (en Python no hay una sintaxis específica para constantes, pero se conviene usar mayúsculas)\nPI = 3.14159  # Constante\n\n# Imprimir en consola\nprint(f\"¡Hola, {nombre}!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/AldousFV.py",
    "content": "# https://www.python.org\n\n# Comentario con una línea\n\n\"\"\"\nEsto también\nes un comentario\nen varias líneas\n\"\"\"\n\n'''\nEsto también\nes un comentario\nen varias líneas\n'''\n\nmy_variable = \"Esta es mi variable\"\nmy_variables = \"Este es el nuevo valor de mi variable\"\n\nMY_CONSTANT = \"Esta es mi constante\" #por convención\n\nmy_int = 35\nmy_float = 35.5\nmy_bool = True\nmy_bool = False\nmy_string = \"Mi cadena de texto\"    # Con doble comilla\nmy_other_string = 'Mi otra cadena de texto'   # Con comillas simples\n\nprint('¡Hola, Python!')\n\nprint(type(my_int))\nprint(type(my_float))\nprint(type(my_bool))\nprint(type(my_string))"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Aldroide.py",
    "content": "# Este es un comentario en python  https://www.python.org/\n\n\"\"\"\n    Este comentario es una muestra para multiples lienas\n    dentro del codigo de python  tambien puede ser usado para documenación\n\"\"\"\nvariable = 1\ntexto = \"John wick is the baba yaga\"\nentero = 12\nflotante = 24.5\nboleano = True\nnulo = None\n\nprint(\"hola python, https://www.python.org/ \")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Ale_Cervi.py",
    "content": "# https://www.python.org/ #\n\n# Esto es un comentario en una sola linea\n\n\"\"\"\nEsto es un\ncomentario\ncon salto\nde lineas\n\"\"\"\n#* Variables\n\nmy_str_value = \"string\"\nmy_int_value = 1\nmy_float_value = 1.5\nmy_bool_value = True\nmy_first_print = \"¡Hola, Python!\"\n\n#* Constante \n\nMY_CONSTANT = \"18/11/2024\"\n\nprint(my_first_print)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Alejandro000.py",
    "content": "#https://www.python.org/\r\n\r\n#Esto es un comentario de una linea\r\n\r\n'''\r\nEsto es un \r\ncomentario de\r\nvarias lineas\r\n'''\r\n\r\n\"\"\"\r\nEste es otro\r\ncomentario de\r\nvarias lineas\r\n\"\"\"\r\n\r\nvariable = \"\"\r\nCONSTANTE = 1 #Por convención, se puede cambiar el valor\r\n\r\nvariable_entera = 3\r\nvariable_float = 3.1416 #Para numeros decimales\r\nvariable_booleana = True #Solo puede ser True o False\r\nvariable_string = \"Hola\"\r\nvariable_string2 = 'Python'\r\n\r\nprint(f\"{variable_string} {variable_string2}\")\r\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/AlejandroDave.py",
    "content": "# https://www.python.org/\n\n# Este es un comentario de una linea.\n\n'''\nPuedo realizar comentarios de mas de una linea\nutilizando tres comillas simples.\n'''\n\n\"\"\"\nTambien puedo realizar comentarios del mismo tipo\nutilizando tres comillas dobles.\n\"\"\"\n\n# Variables\nvarInt, varFloat, varString, varBool = 40, 38.454, \"Hola\", False\nlenguaje = \"Python\"\nprint(\"Variables:\\nInt= \",varInt,\"\\nFloat= \",varFloat,\"\\nString= \",varString,\"\\nBoolean= \",varBool)\nprint(\"Hola {}!\".format(lenguaje))"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/AlejandroVelasquezR.py",
    "content": " #* EJERCICIO:\n\n\n #* - Crea un comentario en el código y coloca la URL del sitio web oficial del\n #*   lenguaje de programación que has seleccionado.\n            #* URL: https://www.python.org/\n\n #* - Representa las diferentes sintaxis que existen de crear comentarios\n #*   en el lenguaje (en una línea, varias...).\n\n# Comentario de una línea\n\"\"\"\nComentario \nde\nvarias\nlineas\n\"\"\"\n\n'''\nComentario\nde\nvarias\nlineas\n'''\n\n #* - Crea una variable (y una constante si el lenguaje lo soporta).\n #* - Crea variables representando todos los tipos de datos primitivos\nvariable = \"variable\"\nconstante = 2\n\n\n #* - Crea variables representando todos los tipos de datos primitivos\n #*   del lenguaje (cadenas de texto, enteros, booleanos...).\ntexto = \"cadena de texto\" # cadena de texto\nentero = 1 # entero\nflotante = 1.1 # flotante\nbooleano = True # booleano\nnulo = None\n\n #* - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nprint(\"¡Hola, Python!\")\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Aleran07.py",
    "content": "# 00\n#https://www.python.org/\n\n\"\"\"\nEsto es un comentario\n\"\"\"\n\n'''\nEsto es otro comentario\n'''\n\nmi_variable = \"Una variable\"\n\nMY_CONSTANT = \"Un constante\" # Se una como indicador de constante el mayuscula\n\nx = str(3)    # x will be '3'\ny = int(3)    # y will be 3\nz = float(3)  # z will be 3.0\n\nx = 5\ny = \"John\"\nprint(type(x))\nprint(type(y))\n\nx = \"John\"\n# is the same as\nx = 'John'\n\n\na = 4\nA = \"Sally\"\n#A will not overwrite a\n\nx, y, z = \"Orange\", 2, \"Cherry\" # se pueden guardar multiples valores en una sola line\nprint(x)\nprint(y)\nprint(z)\n\nx = y = z = \"Orange\" # tambien varias variables con el mismo\nprint(x)\nprint(y)\nprint(z)\n\nfruits = [\"apple\", \"banana\", \"cherry\"]\nx, y, z = fruits\nprint(x)\nprint(y)\nprint(z)\n\nx = \"Python\"\ny = \"2\"\nz = \"awesome\"\nprint(x, y, z) # se puede imprimir texto concatenando en el print\n\n\nx = \"Python \"\ny = \"is \"\nz = \"awesome\"\nprint(x + y + z) # concatenar pero con el + no le agrega espacios por defecto\n\nx = 5\ny = 10\nprint(x + y)\n\nx = 5\ny = \"John\"\n#print(x + y) # Esto es un error porque no se puede sumar diferente variables\nprint(x, y)\n\nx = \"awesome\"\n\ndef myfunc():\n  global x  #Existen variables globales\n  x = \"fantastic\"\n\nmyfunc()\n\nprint(\"Python is \" + x)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/AllanYSalazarG.py",
    "content": "\"\"\"#00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\"\"\"\n\n# https://www.python.org/\n\n# Comentario con una línea (usando el atajo CTRL + /)\n\"\"\" Comentario con \nvarias líneas (Llamados DOCSTRINGS) \n(Usando el atajo ALT + SHIFT + A)\"\"\"\n\nvariableNumero = 1  # Variable de tipo entero\nPI = 3.1416  # Aunque las constantes en Python no existen,\n# normalmente se suelen escribir con MAYUSCULAS\n# para saber (Nosotros los humanos) que el valor\n# de esta variable no debe cambiar (para ser constante)\n\nnumero = 1  # Entero\nflotante = 1.0  # Flotante\ncaracter = 'a'  # Caracter\ncadena = \"Allan Salazar\"  # Cadena.\n# NOTA: En Python, las cadenas y caracteres\n# se pueden indicar con '' o \"\"\nbooleano = True\nnulo = None  # Representa que no hay un valor asignado a la variable\n\nprint(\"Hola, Python\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Alvaro-Neyra.py",
    "content": "# Este es el sitio web oficial de Python : https://www.python.org/\r\n# Existen dos maneras para hacer comentarios en python:\r\n# Comentario de una linea\r\n# Y estas son comentarios con varias lineas:\r\n\"\"\" Hola soy Alvaro y estoy haciendo un comentario con \r\nmas de una linea, puedo seguir escribiendo pero no quiero, pero debido a este ejercicio\r\ntengo que seguir para demostrarles que aunque esto tambien sirve para declarar strings de varias lineas puede usarse como comentarios\r\nde varias lineas, tip final: esto se llama docstring\"\"\"\r\n\r\n# Creando una variable normal\r\nmi_variable = \"Hola soy una variable\"\r\nnumero = 50\r\nnumero_por_dos = 50 * 2\r\n# Creando una variable constante (Python no soporta el hecho de crear variables CONSTANTE pero se sigue una convencion para indicar que es una variable constante y no debe\r\n# modificarse convencionalmente utilizando las letras mayusculas y guiones bajos, esta convencion se llama SNAKE_CASE)\r\nVARIABLE_CONSTANTE = 20 # Esta variable debe seguir la convencion de no poder cambiarse\r\n\r\n# Creando variables representado todos los datos primitivos:\r\n\r\n# Numero entero (int)\r\nnumero_entero = 10 \r\n\r\n# Numero flotante (float)\r\nnumero_flotante = 20.8\r\n\r\n# Numero booleano (bool)\r\nvariable_booleana = True \r\n\r\n# Cadena de texto (str)\r\ncadena_de_texto = \"Hola, mundo\" \r\n\r\n# Imprime por la terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\r\nprint(\"Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/AmbrocioJRDeLaCruz.py",
    "content": "# https://www.python.org\n\n# esta es la sintaxis que se utiliza para comentar una linea\n\n'''\nEsta es la sintaxis que se utiliza para comentar varias lineas\n\n'''\n\nCONSTANTW = 0 # realmente el lenguaje no soporta constante pero la podemos represnetar con una variable con todo en mayusculas.\n\ntexto = \"Este es un texto\"  # esta es una variable de tipo string\nentero = 7 # esta es una variable de tipo entero\nflotante = 7.0 # esta es una variable de tipo flotante\nbooleano_true = True # esta es una variable de tipo Booleano\nbooleano_false = False # esta es una variable de tipo Booleano\n\nprint(\"¡Hola, Python!\")\n\nprint(f\"String: {type(texto)}\")\nprint(f\"Entero: {type(entero)}\")\nprint(f\"Flotante: {type(flotante)}\")\nprint(f\"Booleano True: {type(booleano_true)}\")\nprint(f\"Booleano False: {type(booleano_false)}\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/And-Y21.py",
    "content": "#https://www.python.org/\n#Comentario de una linea\n\n\"\"\"\nEjemplo\nComentario de varias lineas\n\"\"\"\n\ntexto=\"Esta es una cadena\"\nentero=int(4)\ndecimalf=float(4.5)\nverd=bool(True)\nverd=bool(False)\n\n\n\nprint(\"hola python, https://www.python.org/ \")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/AndresMCardenas.py",
    "content": "#https://python.org/\n\n# Comentarios de una sola linea\n\n\"\"\"\nComentarios \nde \nmultiples \nlineas\n\"\"\"\n'''\nOtra forma de hacer \ncomentarios en multiples \nlineas\n'''\n# Estas son variables\nmy_name = \"Andres Cardenas\"\nmy_github_name  = \"AndresMCardenas\"\nmy_twicth_name = \"Xamale123\"\nmy_age = 37\n\n# en Python no existen las constantes pero esta es una convencion para constantes es usar mayusculas\n\nPI = 3.1416\n\n# Tipos de datos primitivos\n# String\ntexto = \"Hola Mundo\"\ncadena_de_texto = 'Hola Mundo'\n# Integer\nnumero = 10\n# Float\nnumero_decimal = 10.5\n# Boolean\nverdadero = True\n\n#asi se imprime en consola\nprint(\"Hola Mundo\", \"Python\")\n\n# asi se imprime una variable\nprint(my_name)\n\n# asi se imprime el tipo de dato de una variable\nprint(type(my_name))"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Anexo01.py",
    "content": "# Comentario con la pagina oficial de Python: https://www.python.org/\n\n\"\"\"\nPara hacer comentarios en diferentes linias\nhay que poner 3 dobles comillas para que funcione\nse puede hacer con comillas simples\n\"\"\"\n\n'''\nEjemplo con comillas simples\n'''\n\nvarstring = \"Cadena de texto\"\nvarint = 2\nvarbool = True\nvardouble = 2.45\n\nprint(\"Hola, python!\")\nprint(varstring)\nprint(varint)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Angel-Alvarez-Dev.py",
    "content": "\"\"\"\n* EJERCICIO:\n   - Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n   - Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n   - Crea una variable (y una constante si el lenguaje lo soporta).\n   - Crea variables representando todos los tipos de datos primitivos\n     del lenguaje (cadenas de texto, enteros, booleanos...).\n   - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\"\"\"\n\n# Python URL:\n# https://www.python.org/\n\n# Este es un comentario en Python usando el \"numeral\".\n\n\"\"\"\nEste es un comentario\nen varias líneas\nusando comillas triples (simples o dobles).\n\"\"\"\n\n# Variables y Constantes\nvariable = \"Mi variable en Python\"\nCONSTANTE = \"Esta es una constante por convención\"  # Convención\n\n# Datos primitivos\n# Tipo números\na_int = 3\na_float = 3.1415927\na_complex = 3.3 + 3j\n\n# Tipo booleanos\na_true = True\na_false = False\na_none = None  # None es el equivalente a NULL en otros lenguajes.\n\n# Tipo cadenas de caracteres\na_string = \"Cadena de texto\"  # Entre comillas simples o dobles.\n\n# Imprimir tipos de datos\nprint(type(a_int))    # <class 'int'>\nprint(type(a_float))  # <class 'float'>\nprint(type(a_complex))  # <class 'complex'>\nprint(type(a_true))   # <class 'bool'>\nprint(type(a_false))  # <class 'bool'>\nprint(type(a_none))   # <class 'NoneType'>\nprint(type(a_string))  # <class 'str'>\n\n# Imprime por terminal \"¡Hola, [y el nombre de tu lenguaje]!\"\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Angel-Delg.py",
    "content": "# Puedeas aprender mas de python en las siguiente URL.\n# URL = https://www.python.org/doc/\n\n\"\"\"\n   Comentario de varias Lineas\n   URL = https://www.python.org/doc/\n\"\"\"\n\n# Python no tiene una forma de definir Constantes.\nvariable:str = \"This is a var\"\n\n#Tipos de datos Primitivos\nTexto: str = \"text\"\nEntero: int = 2024\nisNewYear: bool = True\n\nprint(\"Hola python\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Angell4S.py",
    "content": "# https://www.python.org/\r\n\r\n# con #Comentario\r\n# con \"\"\"Comentario multilinea\"\"\"\r\n\r\n#Variable\r\na = 1\r\n\r\n#Constante\r\nPI = 3.1416\r\n\r\n#Tipos de datos\r\na = 1\r\nb = 1.1\r\nc = \"Hola\"\r\nd = True\r\ne = 4j\r\n\r\n#Imprimir\r\nlenguaje = \"Python\"\r\nprint(f\"Hola, {lenguaje}!\")\r\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Angelo-Eyama.py",
    "content": "#https://www.python.org/\n'''\n    Comentario\n    De\n    Varias\n    Lineas\n'''\n\nvariable = \"157are\"\n\ncadena = \"cadena de texto\"\nentero = 45\ndecimal = 4.5\nbooleano = True\nnulo = None\n\nprint(\"Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Anvildestroyer.py",
    "content": "#Url del sitio oficial de python en una linea: https://www.python.org/ \n\n\"\"\" \nCon 3 comillas dobles al \ninicio y al final\nrepresentamos \nun tipo de sintaxis para crear\ncomentarios en bloque\n\"\"\"\n\n'''\nY con 3 comillas simples al\ninicio y al final,\ntambien :D\n'''\n\n\n#tipo String/Cadena\nmi_Variable_saludo = \"Hola, mouredev\"\nmi_Variable_lenguaje = \"¡Hola, Python!\"\n\n#Constante\nMY_CONSTANT = \"Mi constante mentirosa\" # por convención, en python no existe las constantes \n\n#booleano\nmi_Variable_false_true = False\n\n#Enteros #Numerica \n\nmi_Variable_entera = 5\n\n#Float \n\nmi_Variable_float = 2.6\n\n#Imprime por terminal el texto\nprint (mi_Variable_lenguaje)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Aquiles735.py",
    "content": "\n\n        #colocando # al inicio \n#primera forma de comentar    \n        #seleccionando el bloque y '''\n'''comentar mas\nde una linea'''                \n\n        #seleccionando el bloque y \"\"\"\n\"\"\"comentar mas               \nde una linea\"\"\"\n\n        #Seleccionando el bloque y Ctrl+k   +  Ctrl+c (para desmarcar Ctrl+k  +  Ctrl+u  )  la que suelo usar\n# comentar mas\n# de una linea\n\n                #variable en datos primitivos\nmy_variable_int=\"entero\"\nmy_variable_float=\"real\"\nmy_variable_str=\"Hola Python\"\nmy_variable_boll=False\nmy_variable_list= \"silla\"\nmy_variable_tuple=(\"a\")\nmy_variable_dic={\"casa\"}\nmy_variable_set={\"n\"}\n\n\nprint(my_variable_str)    #Hola Python \n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Ariel-Plaza.py",
    "content": "# Comentarios en linea\n# https://www.python.org\n\n# Comentarios en bloque\n''''\nhttps://www.python.org\n'''\n\n# Variable y constante\nfrom pickle import FALSE\n\n\nvariable = 2\nconstante = 3.14\n\n# Datos primitivos\n# Enteros\nvalor_entero = 10\n\n# Flotantes\nvalor_flotante = 20.5\n\n# Booleanos\nvalor = FALSE\n\n# String\ntexto = 'valor de tipo string'\n\n# terminal\n\nprint('¡Hola Python!')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/ArliumDev.py",
    "content": "# Sitio web oficial: https://www.python.org/\n\n# Esto es un comentario\n\n\"\"\"\nEsto es \nun comentario\nmultilínea\n\"\"\"\n\n'''\nEsto es\notro comentario\nmultilínea\n'''\n\nmy_string = \"Soy un string\"\n\nmy_int = 1\n\nmy_double = 1.2\n\nmy_boolean = True\n\nprint('¡Hola, Python!')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/ArtDugarte.py",
    "content": "\ndef main ():\n    #Página Oficial del Lenguaje Python: https://www.python.org/\n\n    #Esta es la primera sintaxi para escribir un comentario en Python (comentario de una sola línea)\n\n    \"\"\"\n    Esta es la segunda sintaxis para escribir un comentario\n    en Python (comentario de varias lineas o comentario en bloque)\n    \"\"\"\n\n    saludo = str(\"¡Hola, \")\n\n    \"\"\"\n    En Python, las constantes no son una característica nativa como en otros lenguajes de programación. Sin embargo, puedes simular una constante declarando una variable con un nombre característico y asignándole un valor que no debería modificarse durante la ejecución del programa.\n    \"\"\"\n\n    MI_CONSTANTE = \"Valor de mi constante\"\n\n    numero_entero = int(25)\n    numero_decimal = float(3.1416) \n    cadena_texto = str(\"Python!\") \n    booleano = bool(True) \n\n    print(saludo + cadena_texto)\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/BassAlex27.py",
    "content": "#Web oficial del sitio de Python \n#https://www.python.org/\n#Comentario de una linea\n\"\"\"Este es un comentarios \nde mas de una linea\"\"\"\n''' Otra forma de comentar en \nvarias lineas'''\n#Variable\nedad = 5\nvari = \"variable\"\n#Constante , no existe propiamente tal\nMY_CONSTANTE = \"mi constante\"\n\n#Tipos de datos primitivos\nint = 1\nfloat = 1.8\nboolean = True\nBoolean = False\nstr = \"Cadena de texto\"\nstr1 = 'Cadena de texto 1'\n\nprint(\"Hola, en el mundo de python\")\n\nprint((int))\nprint((float))\nprint((boolean))\nprint((str))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Berentolkien.py",
    "content": "# https://retosdeprogramacion.com/\n\n'''\nhttps://retosdeprogramacion.com/\nhttps://retosdeprogramacion.com/\n'''\n\n\"\"\"\nhttps://retosdeprogramacion.com/\nhttps://retosdeprogramacion.com/\nhttps://retosdeprogramacion.com/\n\"\"\"\n\nnombre = \"lucas\"\napellido = \"bernaola\"\nedad = 34\naño_nacimiento = 1989\nmes_nacimiento = \"Diciembre\"\ncasado = True\n\nprint(\"Hola Python\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/BerlinBeltranAvila.py",
    "content": "'''\n/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n '''\n# https://www.python.org/\n# comentario de una linea\n# comentario de varias lineas\n\"\"\"comentario de varias lineas\n\"\"\" \n'comentario simple'\nmi_variable = \"python\";\nMYCONSTANT= 'berlinbeltran';\nnumber = 30;\nstring= \"practicando gracias a mouredev\";\nfloat_number = 30.5;\nlist = [\"hola\", \"mouredev\"];\ntuple= (\"no \" \"cambian\");\ndictionary = {\n    \"berlin\": \"lo vamos a lograr\",\n    \"mouredev\": \"gracias por el repo\",\n    'tiktok': \"berlinbeltran\"\n}\nboolean = True;\nboolean = False;\n\nprint(f\"!hola {mi_variable}!\");\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Bert008.py",
    "content": "#https://www.python.org/\n# Con el simbolo # creamos un comentario\n'''\n    Este es un comentario\n'''\n\"\"\"\"\n    Este es un comentraio tambien\n\"\"\"\n\nx = 10\npi = 3.1416\nname = \"Bert008\"\nbooleano = True\n\nprint(\"Hola Python\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/BertoMP.py",
    "content": "# WEB OFICIAL\n# Sitio web oficial de Python: https://www.python.org/\n\n# COMENTARIOS\n# En Python tenemos dos tipos de comentarios:\n# - Comentarios de una sola línea (#): Se utilizan para explicar partes del código.\n# - Comentarios de varias líneas (\"\"\"): Se utilizan para explicar bloques de código o documentar funciones.\n\"\"\"\nEsto es un comentario\nde prueba\nescritor en varias\nlíneas.\n\"\"\"\n\n# VARIABLES Y CONSTANTES\n\"\"\"\n- Variables: En Python para declarar una variable simplemente debemos escribir el nombre de la\n             variable y asignarle un valor de inicio. Siempre se deben inicializar las variables\n             si se quiere declarar una variable no inicializada se puede usar la palabra 'None'\n             Por convención se utiliza la nomenclatura snake_case.\n\"\"\"\nmi_variable_inicializada = 33\nmi_variable_no_inicializada = None\n\n\"\"\"\n- Constantes: En Python no existen las constantes como tal, pero por convención, si queremos\n              declarar una constante debemos escribirla en mayúsculas. Pero esto es una simple\n              convención, no hay nada que indique a Python que ese dato sea inmutable y, por\n              tanto, constante.\n\"\"\"\nMI_CONSTANTE = 40\n\n# DATOS PRIMITIVOS\n# En Python tenemos 4 tipos de datos primitivos\nmi_int = 42  # Integer (int): Almacena números sin decimales.\nmi_float = 3.14159  # Float (float): Almacena números con decimales.\nmi_bool = True  # Boolean (bool): Almacena datos lógicos (True o False).\nmi_str = 'Esto es una cadena o String.'  # String (str): Almacena una cadena de caracteres (o un carácter único).\n\n# IMPRESIÓN POR CONSOLA\nprint('¡Hola, Python!')\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Bertolini-Victor.py",
    "content": "\"\"\"\n    * EJERCICIO:\n    * 1) Crea un comentario en el código y coloca la URL del sitio web oficial del\n    *    lenguaje de programación que has seleccionado.\n    * 2) Representa las diferentes sintaxis que existen de crear comentarios\n    *    en el lenguaje (en una línea, varias...).\n    * 3) Crea una variable (y una constante si el lenguaje lo soporta).\n    * 4) Crea variables representando todos los tipos de datos primitivos\n    *    del lenguaje (cadenas de texto, enteros, booleanos...).\n    * 5) Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\"\"\"\n\n\n# 1)\n# Link a la pagina de Python - Link to Python's webpage: https://www.python.org/\n\n\n# 2) \n# Esto es un comentario de linea - This is a single-line comment.\n\"\"\" \n    Esto es un comentario multiinea.\n                -\n    This is a multi-line comment.\n\"\"\"\n\n\n# 3)\nmy_var   = \"Hello World!\"\nMY_CONST = \"I am constant.\" \"\"\"\n                            Cabe aclarar que en realidad las constantes en Python no son nativas\n                            pero se puede tomar a esto como una constante por conveniencia en la comunidad\n                            de programadores de Python. \n                                            -\n                            It's important to mention that although this is a accepted form of constants in\n                            Python by the community that uses this language, by default Python does not have\n                            a official sintax for constants.\n                            \"\"\"\n\n\n# 4)\nmy_int = 20\nmy_float = 20.0\nmy_bool = True\nmy_str = \"Hello World, I am string in Python!\"\n\n\n# 5)\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Betulioo.py",
    "content": "# this is the web of the lenguaje i selected https://python.org\n\n\n\"\"\" we can also create\n    multiple lines coments\n\"\"\"\n\n''' this works too '''\n\n\nthis_variable = \"My variable\"\nthis_variable = \"new valor for variable\"\n\nTHIS_CONSTANT = \"this is not actualy a constant is just for convention\" \n\nthis_string = \"Python!\"\nthis_stringToo = 'String'\nthis_int = 5\nthis_float = 5.5\nthis_boolean = True\nthis_boolean = False\n\nprint('¡ Hola, ' + this_string)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Billy-Ugalde.py",
    "content": "# Hola estoy aprendiendo python  en 2025, pura vida desde COSTA RICA tierra de paz.....\n\n\n\"\"\"\nEsta es el link a la documentacion oficial de python:\nhttps://www.python.org/about/\n\nNota: python no permite variables constantes.\n\n\"\"\"\npalabra_str = \"e4frffr\"\nnum_int = 300\nnum2_float = 2.5\nnum3_complex = 1 +2j\nbool  = False\n\nprint(f'Es de tipo: + {type(num3_complex)}')\nprint('Hola python')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/BrianSilvero.py",
    "content": "# http://python.org\n\n# Comentario en una linea\n\n\"\"\"\nEsto es\nun comentario\nen varias lineas\n\"\"\"\n\n'''\nEsto tambien es\nun comentario \nen varias lineas\n'''\n\nmy_variable = \"Mi variable\"\nmy_variable = \"Nuevo valor de mi variable\"\n\nMY_CONSTANT = \"Mi constante\" # por convencion \n\nmy_int = 1\nmy_float= 1.5\nmy_bool = True\nmy_bool = False\nmy_string = \"Mi cadena de texto\"\nmy_other_string = 'Mi otra cadena de texto'\n\nprint(\"Hola, Python!\")\n\nprint(type(my_int))\nprint(type(my_float))\nprint(type(my_bool))\nprint(type(my_string))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Bryan112094.py",
    "content": "#PAGINA WEB OFICIAL\n#https://www.python.org/\n\n#COMENTARIOS\n# -> una sola almuadilla es un comentario de una línea\n\"\"\"\n    Las tres comillas al abrir y cerrar\n    se puede poner comentarios\n    multilíneas\n\"\"\"\n\n#VARIABLES -> la variable no tiene un tipo definido, toma el tipo del valor que declares\nvariable = 20.2\n\n#DATOS PRIMITIVOS\n# String\ntexto = \"hola\"\n# Int\nnumero = 2\n# Decimal\ndecimal = 2.2\n# Tupla\ntupla = (2, 3, \"ds\")\n# Lista\nlista = [29, 30, \"ad\"]\n# Diccionario\ndiccionario = {\"Nombre\": \"Bryan\", \"Apellidos\": \"Guevara Ascoy\"}\n# Booleano\nbooleano = True\n\n#IMPRIMIR\nprint(\"Hola, Python\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/BuriticaSara.py",
    "content": "# https://python.org\n# se utiliza númeral para comentar una sola línea\n\"\"\" se utiliza 3 comillas (pueden ser simples o dobles) para \ncomentar varias líneas\"\"\"\n\n#Declaración de variable\nminombre = 'Sara'\n\"\"\"Declaración de constante (las constantes no existen en python pero podemos \nutilizar una variable y nombrarla en mayúscula para identificar que no se cambia\"\"\"\nMESES_DEL_ANNE = 12\n\n#variables que representan cada tipo de dato primitivo\ntipostring = 'texto'\ntipoint = 10\ntipofloat = 1.5\ntipobool = True\n\n#imprimir Hola Python\nprint ('Hola, python')\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/C-Gabs.py",
    "content": "'''Reto #00 Sintaxsis, variables y tipos de datos\nEJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"'''\n\n\n'https://www.python.org'\n\n#Este es un comentario en python creado con el simbolo de numeral\n'''Este es un comentario en python creado con comillas simples'''\n'''Este es un parrafo \n   comentado con comillas\n   simples'''\n\n#Creación de una variable\n\nnumero = 5\n\n#otra forma de hacerlo\n\nfila, columna = 4,5\n\n#Creación de una constante\n\n'''Python no soporta la creación de constantes,\n   por lo tanto, por convención, para crear\n   constantes se declara una variable\n   con su nombre en mayuscula para\n   indicar que no se debe modificar'''\n\nCONSTANTE = 5\n\n#otra forma de hacerlo\n\nNUMERO_1, NUMERO_2 = 1,2\n\n#Tipos de datos primitivos en python\n\n#String (str)\n\nstring = \"Hola mundo\"\n\n#Entero (int)\n\ninteger = 5\n\n#Flotante o decimal (float)\n\nfloat = 3.7\n\n#Booleanos (bool)\n\ntrue = True\nfalse = False\n\n#NoneType\n\nvariable = None\n\n#Imprimimos en el terminal\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/CD1974.py",
    "content": "# El lenguaje que he escogido es Python y esta es su página oficial https://www.python.org/doc/\r\n\r\n\"\"\"Esta es otra manera de realizar\r\ncomentarios de varias líneas...\"\"\"\r\n\r\nmy_var = 'Variable inicial'\r\n\r\n# Datos primitivos\r\n\r\nvar_texto = 'Variable que representa una cadena de texto'\r\n\r\nvar_enteros = int(numero)\r\n\r\nvar_flotantes = float(numero)\r\n\r\nvar_booleanos = True and False\r\n\r\nprint(\"¡Hola, Python!\")\r\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/CRaphaelAM.py",
    "content": "\"\"\"\n/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\"\"\"\n\n# URL oficioal de Python: https://www.python.org/\n#Comentario de una linea\n\n\"\"\"Comentario de\nvarias\nlineas\n\"\"\"\nnumero_entero = 7\nnumero_flotante = 7.0\nstring = \"algo\"\nbooleano = True\n\nprint(\"¡Hola Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/CT-Zodiako.py",
    "content": "# URL Python: https://www.python.org/\n\n# Esto es un comentario de una lnea\n\n\"\"\"\nEsto es un comentario de varias linea\n\"\"\"\n\n# Variables\nnumero : int = 10 # Variable\nCONSTANTE: float = 14.15 # Constante\n\n#Tipos de datos\nletra : str = \"A\" # String\nverdadero : bool = True # Boolean\nfalso : bool = False # Boolean\nnumero_decimal : float = 10.5 # Float\nnumero_entero : int = 10 # Integer\ndesconocido : None = None # None\n\n#Print\nprint(\"Hola, Python\")\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Caleb-Acarapi.py",
    "content": "\"\"\" * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\"\"\n\n# 1. www.python.org\n\n# 2. Este es un comentario de una sola linea\n\"\"\"\nEste es un \ncomentario de \nvarias lineas\n\"\"\"\n\n# 3. En python no existen las constantes pero las podemos representar con Mayuscualas\nCONSTANTE = 3.14159\n\nnombre = \"Ejemplo\"\n\n# 4. Tipos de datos\nentero = 10\nflotante = 3.14\nbooleano = True\nlista =[1, 2, 3]\ndiccionario = {\"clave1\": \"valor1\", \"clave2\": \"valor2\"}\ntupla = (1, 2, 3)\nconjuntos = {1, 2, 3}\ncadena = \"str\"\ncomplejo =  (3 + 1j)\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Carl6289.py",
    "content": "# https://www.python.org/\n\n\"\"\" Esto es un comentario \n    de varias líneas,\n    haciendo uso de las \n    triples comillas dobles \"\"\"\n\n''' Esto tambien es un comentario \n    de varias líneas,\n    haciendo uso de las\n    triples comillas simples '''\n\n# Variable\nnombre = \"Carlos\"\n\n# \"Constante\" en Python siguiendo la convención de nomenclatura \nPI = 3.14159\n\n# Tipos de datos primitivos\napellido = \"Mercado\" # Variable tipo cadena (str)\nedad = 36 # Variable tipo entero (int)\nposee_vehiculo = False # Variable tipo booleana (bool)\npeso = 55.5 # Variable tipo flotante (float)\nlista = [1, 2, 3, 4, 5, 6, 7, 8] # Variable tipo lista (list) mutable\ntupla = (10, 20, 30, 40, 50) # Variable tipo tupla (tuple) inmutable\ndatos_de_personas = {\"nombre\": \"Carlos\", \"apellido\": \"Mercado\", \"edad\": 36} # Variable tipo diccionario (dict)\nconjunto = {8, 3, 5} #Variable tipo conjunto (set)\n\nprint (\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/CarlosMqz969.py",
    "content": "\"\"\"\nCrea un comentario en el código y coloca la URL del sitio web oficial del\nlenguaje de programación que has seleccionado.\n\"\"\"\n\n# https://www.python.org/\n\n\"\"\"\n- Representa las diferentes sintaxis que existen de crear comentarios\nen el lenguaje (en una línea, varias...).\n\"\"\"\n\n# Comentario de una línea\n\n\"\"\"\nEsto\nes\ncomentario\nde \nvarias \nlíneas\n\"\"\"\n\n#- Crea una variable (y una constante si el lenguaje lo soporta).\n\nmy_first_var = \"Mi primera variable del reto\"\n\nMY_CONSTANT = \"Mi constante\" # Por convención me lo enseño BRAIS pero python no tiene constantes\n\n\"\"\"\n- Crea variables representando todos los tipos de datos primitivos\ndel lenguaje (cadenas de texto, enteros, booleanos...).\n\"\"\"\n\nmy_string_var = \"Hola roadmap\"\nmy_int_var = 25\nmy_float_var = 21.5\nmy_bool_var = True\n\n# * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\nprint(\"Hola, Python!\")\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/CaveroBrandon.py",
    "content": "# Crea un comentario en el código y coloca la URL del sitio web oficial\n# Python's official website: https://www.python.org/\n\n# Representa las diferentes sintaxis que existen de crear comentarios\n\"\"\"\n**************************\nBlock comments\nUsing double quotation marks\n**************************\n\"\"\"\n\n'''\n**************************\nBlock Comments\nUsing single quotation marks\n**************************\n'''\n\n# Crea una variable (y una constante si el lenguaje lo soporta).\nWELCOME_CONSTANT = 'Hello World'\nwelcome_variable = WELCOME_CONSTANT\n\n# Crea variables representando todos los tipos de datos primitivos\nyear = 2023  # Integers\ngolden_ratio = 1.618  # Floating numbers\nselected_language = 'Python'  # Strings\nhas_last_name = True  # Booleans\n\n# Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nprint(f'Hola, {selected_language}')\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/CeciliaRava1.py",
    "content": "# Python oficial documentation: https://docs.python.org/3/\n'''\nThis is a \nmultiline comment\n'''\n\nvariable = 'Hello Python!'\nCONSTANT = 'I am very cool'\n\nint = 2\nfloat = 2.3\nboolean = True\nstring = 'World'\n\nprint(variable)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/CesarCarmona30.py",
    "content": "# Sitio web del lenguaje:\n# https://www.python.org/\n\n\n# Formas de elaborar comentarios\n\n# Comentario de línea\n\n'''\n  Comentario multilínea\n'''\n\n\"\"\"\n  Esto también es un \n  comentario multilínea\n\"\"\"\n\n\n# Variable y constante\n\nnombre = 'César'\nGENERO = 'MASCULINO' # Constante por convención\n\n# Variables para datos primitivos\n\n# int\nedad = 19\n# float\nestatura = 175.5\n# boolean: true\nvivo = True\n# boolean: false\nmuerto = False\n# string\nciudad = \"Ciudad de México\"\n\n# ¡Hola, [lenguaje]!\"\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Cesir72.py",
    "content": "# EJERCICIO RETO 00\n\n\n\n# - Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n\n# https://www.python.org\n\n# - Representa las diferentes sintaxis que existen de crear comentariose en el lenguaje (en una línea, varias...).\n'''\n    Este es un comentario \n    en varias líneas\n    usando comillas simples\n'''\n\n\"\"\"\n    Este es un comentario\n    en varias líneas \n    usando comisillas dobles\n\"\"\"\n\n\n# - Crea una variable (y una constante si el lenguaje lo soporta).\n\nCONST= PI = 3.1416\nnombre = 'César'\n\n# - Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n\n # esto es una cadena de texto\nMystring = \"Hola Mundo\"\n# y esto es un entero\nnumero = 23\n# podemos comprobarlo con la función type\nprint(type(Mystring))\nprint(type(numero))\nprint(type(PI))\nbooleano = True , False\nprint(type(booleano))\nfloat = 3.1416\nprint(type(float))\nnumeros_complejos = 1 + 2j\nprint(type(numeros_complejos))\nreal = 0.2703E2\nprint(type(real))\n# - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Charly024.py",
    "content": "#PYTHON\n\n#Link de Sitio Web: https://www.python.org/\n\n#Sintaxis para comentarios en Python:\n# - Inline ->  #\n\"\"\"  - MultiLine -> Este es un comentario de varias lineas\nEn Python\n\"\"\"\n\n#Variable y constante en Python\n# - Variable\nnombre = \"hola mundo\"\n\n# Constante se declaran en mayusculas desde un archivo separado y estas son importadas desde ese archivo\nEDAD = 23\n\n# Ejemplos de variables segun el tipo de datos\n\n# string\ncomida = \"Sushi\"\n\n# flotante\nprecio = 86.90\n\n# entero\ncantidad = 4\n\n# boleano\ndisponibilidad = true\n\n# Impresion en terminal de texto\nprint(\"¡Hola, [y el nombre de tu lenguaje]!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/CipollaLucas.py",
    "content": "# * - EJERCICIO * :\n\n# * ------------------------------------------------------------------------------------ * #\n#  * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n#  *   lenguaje de programación que has seleccionado.\n\n\"\"\" \nSitio oficial Python -> https://www.python.org\n\"\"\"\n# Sitio oficial Python -> https://www.python.org\n\n# * ------------------------------------------------------------------------------------ * #\n\n# * - Representa las diferentes sintaxis que existen de crear comentarios\n# *   en el lenguaje (en una línea, varias...).\n\n# - Utilizo Python PEP 8 cómo convención estilistica.\n# - Esta guía es excelente https://kinsta.com/es/blog/comentarios-python/\n# - Con el símbolo #, podemos hacer comentarios inline\n\"\"\"\nCon las comillas simples('') u dobles, podemos comentar\nmultilineas. \n\"\"\"\n\n# Además existen los comentarios del tipo Docstring. Son multilineas y explican como utilizar determinada función u clase.\n\n'''\nComentarios del tipo TODO\nTODO Comentamos algo para mostrar como funciona.\n'''\n\n# * ------------------------------------------------------------------------------------ * #\n\n# * - Crea una variable (y una constante si el lenguaje lo soporta).\n# *   del lenguaje (cadenas de texto, enteros, booleanos...).\n\nvariable = \"contiene algo\"\nconstante_PI = 3.145 # Una constante no cambia su valor.\n\n# * ------------------------------------------------------------------------------------ * #\n\n# * - Crea variables representando todos los tipos de datos primitivos\n\nstring = \"dato primitivo cadena de texto\"\ncaracter = \"L\"\nentero = 10\nflotante = 6.5\nboleano = True\n\n# * ------------------------------------------------------------------------------------ * #\n\n# * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\nprint(\"Hola, Python!\")\n\n# * ------------------------------------------------------------------------------------ * #"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/ClaraLopezGonzalez.py",
    "content": "#https://www.python.org/\n\n# Comentario en una linea\n\n\"\"\" Comentario en \nvarias lineas\n\"\"\"\n\n# Variable\nnombre = \"Clara\"  # Variable de tipo str\nedad = 31  # Variable de tipo int\naltura = 1.68  # Variable de tipo float\n\n\n# Tipos de datos primitivos\ndía = 8\nhora = 22,59 \nstr = \"octubre\"\nera_guapo = True\nvariable_sin_valor = None\n\n\n# Imprimir saludo lenguaje\nprint(\"¡Hola, Python\")\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Complex303.py",
    "content": "# https://www.python.org/\n\n# Comentario en una sola linea\n\n\n\n\"\"\"\nsnake_case es una convención para nombrar variables, funciones o identificadores en programación, donde:\ntodas las letras son minúsculas\nlas palabras se separan con guiones bajos _\n\"\"\"\n\n\n'''\nUna variable es un espacio en memoria donde se guarda un valor que puede cambiar durante la ejecución del programa.\nPython no tiene constantes reales como en otros lenguajes.\nPero por convención, se escriben en mayúsculas para indicar que su valor no debería cambiar.\n'''\n\nmy_variable = 'Esto es una variable'\nedad = 24\nMY_CONSTANTE = 'Esto es una constante' #por convencion\nNOMBRE = 'Eddy'\n\n#TIPOS DE DATOS PRIMITIVO\ncantidad: int = 10      #tipo entero\nprecio = 5.75           #tipo decimal\nes_casado = True        #tipo booleano\ntiene_hijos = False     #tipo booleano\nmensaje = 'Ejemplo de una cadena de tipo string'\n\nprint('Hola, Python!!')\n\nprint(type(cantidad))\nprint(type(precio))\nprint(type(es_casado))\nprint(type(mensaje))\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Copamire.py",
    "content": "# https://www.python.org\n\n#Comentario en una linea\n\n\"\"\"\nEsto tambien es\nun comentario\nen varias lineas\n\"\"\"\n\n'''\nEsto tambien es\nun comentario \nvarias lineas\n'''\n\nmy_variable = \"Mi variable\"\nmy_variable = \"Nuevo valor de mi variable\"\n\nMY_CONSTANT = \"Mi constante\" #por convención\n\nmy_int = 1\nmy_float = 1.5\nmy_bool = True\nmy_bool = False\nmy_string = 'Mi cadena de texto'\n\n\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Cristianfer1991.py",
    "content": "# URL del sitio web oficial de Python: https://www.python.org/\n# Comentario en una línea\n\n\"\"\"\nComentario\nen varias líneas\n\"\"\"\n\n# Variable\nvariable = \"Variable\"\nCONSTANTE = \"Constante\"\n\n# Tipos de datos primitivos\ncadena = \"Cadena de texto\"\nentero = 10\nflotante = 10.5\nbooleano = True\n\n# Imprimir por terminal\nprint(\"¡Hola, Python!\")\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/D3rk1us.py",
    "content": "\n# Comentarios:\n\n'''\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n '''\n\n\"\"\"\nWeb Oficial de Python:\n\nhttps://www.python.org/\n\"\"\"\n\n# Esto es un comentario de una línea.\n\n# Variables:\n\nvariable = 15 #variable\nPI = 3.141592 # constante\n\n# Tipos de Variables:\n\ntexto = \"Hola Mundo\" # cadena de caracteres\nprint(type(texto)) # comprueba el tipo de dato.\n \nnum1 = 10 # número entero\nprint(type(num1))\n\nnum2 = 1.5 # flotante\nprint(type(num2))\n\nbooleano = True \nprint(type(booleano))\n\nfoo = None # dato especial que no asigna un valor.\nprint(type(foo))\n\n\n# Hello World\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/DAVstudy.py",
    "content": "\n# https://www.python.org/\n\n# Este es un comentario en solo una linea\n\n'''\nEste es un comentario\nen varias lineas\n'''\n\n\"\"\"\nEste es otro metodo\nde comentario\nen varias lineas\n\"\"\"\n\nvariable = \"variable\"  # Asi se declara una variable, esta es una variable tipo string\n\nVARIABLE = \"constante\"  # En python no existen, pero se llego a la convención de que para las \"costantes\" se nombrarán con mayusculas todas sus letras\n\n# Tipos de variables primitivas en Python\n\nstring = \"hola soy una variable string\"  # Variable tipo 'cadena' o 'string'\nbooleano = True  # Variable tipo 'booleana' o 'bool'\nnumero_entero = 33  # Variable tipo 'entero' o'int'\nnumero_decimal = 33.33  # Variable tipo 'flotante' o 'float'\n\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/DGJuancho.py",
    "content": "# https://www.python.org/\n\n# Este es un comentario de una línea, se crea utilizando al inicio el símbolo \"#\"\n\n\"\"\"Este es un comentario de varias líneas,\nse crea encerrando el comentario entre 3 comillas seguidas,\nestas pueden ser dobles ' \" ' \"\"\"\n\n\n\"\"\"O pueden ser también sencillas \" ' \"\nY si nos fijamos bien, hewmos utilizado las comillas dobles y sencillas en cada comntario comentario\"\"\"\n\nmiVariable = \"Esta es una variable\"\nMICONSTANTE = \"Esta es una constante\"  # Realmente python no utiliza constantes como tal, sólo que por convención se nombra la variable \"CONSTANTE\" con el estilo UPPERCASE.\n\nmyString = \"DG Juancho\"\notherString = \"Python\"\nmyInt = 46\nmyFloat = 1.78\nmyBoolean = True\nmyBoolean = False\n\nprint(f'\"¡Hola, {otherString}!\"')\n\nprint(type(myString))\nprint(type(myInt))\nprint(type(myFloat))\nprint(type(myBoolean))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/DGrex.py",
    "content": "# https://www.python.org/\n\n# Comentario en una linea\n\n\"\"\"\nComentario en\nvarias lineas \n\"\"\"\n\n'''\nComentario en\nvarias lineas \n'''\n\n# Variable\nname = \"DGrex\"\n\n# Pyton no soporta variables constantes\n\nstring: str = \"Python\" # Cadena de caracteres\nnumero_entero: int = 20 # Numeros enteros\nnumero_real: float = 20.00 # Numeros reales\nbooleanos: bool = True # Verdadero o Falso\n\n# Nota: En python el tipado de las variables es dinamico\n\n\n# Imprimiendo en consola\nprint(\"¡Hola Python!\")\n \n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/DJordanV.py",
    "content": "'''EJERCICIO:\n- Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n- Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n- Crea una variable (y una constante si el lenguaje lo soporta).\n- Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n- Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\n¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y debemos comenzar por el principio.'''\n\n# https://www.python.org/\n\n# Comentario en una línea con almohadilla\n\n\"\"\"\nComentario multilínea con tres comillas dobles\n\"\"\"\n\n'''\nTambién con comillas simples\n'''\n\nvariable = 'un valor str'\nvariable = 6 # Puedo cambiarle el valor y el tipo de variable sin problema\n\nCONSTANTE = 'usando mayúsculas' # Se usan las mayúsculas por convención, pero no hay una diferencia real\n\nstring_ = 'variable de cadena de texto'\nint_ = 1\nfloat_ = 3.14\nbool_ = True\n\nprint('Hola, python!')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/DLGAI12.py",
    "content": "#   Crea un comentario en el código y coloca la URL del sitio web oficial del\n#   lenguaje de programación que has seleccionado.\n\n\"\"\"   https://www.python.org\"\"\"\n# Representa las diferentes sintaxis que existen de crear comentarios\n#   en el lenguaje (en una línea, varias...).\n\"\"\" Una linea\"\"\"\n\n# Otra forma de representar un comentario en una linea\n\n\"\"\" Un comentario\n    de varias\n    lineas\n\"\"\"\n\n# Crea una variable (y una constante si el lenguaje lo soporta).\n\nvariable=\"Python\"\n\n\"\"\" Python no proporciona soporte nativo para las constantes.\n    Sin embargo, se puede simular una constante al declarar una variable con todas las letras en mayúsculas.\n    Esto sirve como una señal para los desarrolladores de que la variable debe ser tratada como una constante, \n    lo que significa que su valor no debe modificarse después de su asignación inicial.\n\"\"\"\nCONSTANTE = \"Python\"\n\n#   Crea variables representando todos los tipos de datos primitivos\n#   del lenguaje (cadenas de texto, enteros, booleanos...)\n\n\"\"\" Numeros\"\"\"\nentero   =  10\nflotante =  10.05\n\n\"\"\" Cadenas\"\"\"\ncadena = \"Hola\"\n\n\"\"\"Booleanos\"\"\"\n\nverdadero   = True\nfalso      =  False\n\nprint(\"¡\"+cadena+\",\"+variable +\"!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/DacalDev.py",
    "content": "# Esta es la web oficial de Python: https://www.python.org\n\n# Esto es un comentario en una linea\n\n\"\"\"\nEsto\nes\nun\ncomentario\nen\nvarias\nlineas\n\"\"\"\n\n'''\nEsto\ntambien\nes\nun\ncomentario\nen\nvarias\nlineas\n'''\n\nmy_variable = \"Hola Mundo\"\nmy_variable = \"Hola Python\" # Modifico el valos de my_variable\n\nMY_CONST = \"Constante por convención\"\n\nmy_string = \"Hola\"\nmy_int = 5\nmy_float = 5.5\nmy_complex = -5j\nmy_bool = True # La otra opción seria False para una variable de tipo bool\nmy_list = [1, 2, 3, 4, 5]\nmy_tuple = (1, 2, 3, 4, 5)\nmy_set = {1, 2, 3, 4, 5}\nmy_dict = {1:\"Uno\", 2:\"Dos\", 3:\"Tres\", 4:\"Cuatro\", 5:\"Cinco\"}\n\nprint(\"Hola Python\")\nprint(my_variable) # Podemos imprimir el string directamente o imprimir la variable que contiene el string\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/DaftFunked.py",
    "content": "# https://www.python.org\n\n# Este es un comentario de una sola línea\n\n''' Este es un comentario\nde varias líneas '''\n\nx = 5 # Esto es una variable de tipo entero\ny = \"Hello, World!\" # Esto es una variable de tipo cadena\nz = 20.5 # Esto es una variable de tipo flotante\na = True # Esto es una variable de tipo booleano\nb = False # Esto es una variable de tipo booleano\n\nprint (\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Dakkaj.py",
    "content": "#* EJERCICIO:\r\n# * - Crea un comentario en el código y coloca la URL del sitio web oficial del\r\n#*   lenguaje de programación que has seleccionado. ---\r\n#* - Representa las diferentes sintaxis que existen de crear comentarios\r\n#*   en el lenguaje (en una línea, varias...). ---\r\n#* - Crea una variable (y una constante si el lenguaje lo soporta). ---\r\n#* - Crea variables representando todos los tipos de datos primitivos\r\n#*   del lenguaje (cadenas de texto, enteros, booleanos...). \r\n#* - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\r\n#*\r\n#* ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\r\n#* debemos comenzar por el principio.\r\n\r\n#----------------------- Solución\r\n\r\n#1---\r\n#Crea un comentario en el código y coloca la URL del sitio web oficial del\r\n#lenguaje de programación que has seleccionado. ---\r\n\r\n# * Comentario sitio web oficial de python:\r\n#   sitio web python: https://www.python.org/\r\n\r\n#2---\r\n#Representa las diferentes sintaxis que existen de crear comentarios\r\n#*   en el lenguaje (en una línea, varias...)\r\n\r\n#Con el \"#\" podemos crear comentarios que el interprete obveará, también se puede\r\n# utilizar para comentar el código\r\n\r\n\"\"\"\r\nForma para crear\r\ncomentarios en multiples lineas de código.\r\n3 comillas dobles.\r\nFunciona para comentar también\r\npython ignora esto al no estar asignado a algún tipo de variable\r\nutilizamos comillas '' simples\r\n\r\n\"\"\"\r\n'''\r\nCasi similar a lo anterior, pero en este caso utilizamos comillas dobles\r\n\"hola mundo\"\r\n\r\n'''\r\n\r\n#3---\r\n#Crea una variable (y una constante si el lenguaje lo soporta)\r\n\r\n#El valor de la variable es suceptible a cambio\r\nvariable= input(\"Inserte el valor de la variable: \")#Directamente pido al usuario un valor aleatorio\r\n\r\nconstant= 23 #Un valor constante, permanece.\r\n\r\n#4---\r\n#Crea variables representando todos los tipos de datos primitivos\r\n#del lenguaje (cadenas de texto, enteros, booleanos...)\r\n#Cabe aclarar que los tipos de datos primitivos son cuatro: \r\n# int(enteros), floats(flotantes), booleanos y strings(cadenas)\r\n\r\n#tipo de dato entero\r\ndata_type_int= 23\r\nage= data_type_int #edad es un tipo de dato entero.\r\n\r\n\r\n#tipo de dato flotante\r\ndata_type_float= 2.5\r\n\r\n#el f-string imprime multiples variables en cadena de texto.\r\ntemperature= f\"La temperatura es de; {data_type_float} C\" #f-string permite incluir cadenas con datos \r\nprint(temperature) \r\n\r\n#booleanos\r\n#True & False\r\nverdadero= True\r\nfalso= False #Siempre en mayúsculas\r\n\r\n\r\n#Cadenas - Strings\r\nstr= \"\"\"\r\n\r\nStr de Multiples líneas, se realiza con 'tres' comillas 'dobles'.\r\n\r\n\"\"\"\r\nprint(str)\r\n\r\nstr= '''\r\n\r\nStr de múltiples líneas realizado con \"tres\" comillas \"dobles\".\r\n\r\n'''\r\nprint(str)\r\n\r\nstr= \"Comillas 'dobles' utilizadas 'una' sola vez, comentario para una sola línea\"\r\nprint(str)\r\n\r\n#5---\r\n#Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\r\n\r\nprint(\"¡Hola, Python!\")\r\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/DaniQB99.py",
    "content": "\"\"\"\n * EJERCICIO:\n\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\n \"\"\"\n\n\n# https://www.python.org\n\n'''\nEsto es un comentario\nde python en varias\nlineas de codigo\n'''\n\n# Variable de python\nmy_variable = 'Hola mundo' # Esto es una variable\n\nMY_VARIABLE_CONSTANTE = '10' # No existe en python, pero se puede usar por convención\nMY_VARIABLE_CONSTANTE = 10 # Deja modificar el valor de la constante\n\n# Variables de tipos primitivos\nmy_integer = 10             # Esto es un entero\nmy_string = 'Hola'          # Esto es una cadena de texto\nmy_boolean = True           # Esto es un booleano\nmy_float = 10.5             # Esto es un float\nmy_other_string = 'Python'  # Esto es una cadena de texto\n\n\n# Imprimir mensaje por terminal\nprint(f\"¡{my_string}, {my_other_string}!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/DaniRojasDev.py",
    "content": "# https://www.python.org\n\n# Esto es un comentario en una linea\n \nvariable = 10 # Esto es un comentario tras una línea de programación\n\n'''\nEsto es un comentario en varias líneas\n'''\n\n\"\"\"\nEsto también es un comentario en varias lineas\n\"\"\"\n\nvariable = 10\n\n'''\nDatos primitivos\n'''\n\n# enteros (números sin decimales) \nint = 7\n\n# flotantes (números con decimales)\nfloat = 7,7\n\n# booleanos (verdadero o falso)\nno_tengo_ni_idea = True\nsi_tengo_idea = False\n\n#string (cadenas de caracteres)\nstring = \"no tengo ni idea\"\n\n'''\nimprimir por terminal hola mundo\n'''\n\nprint (\"Hola, Python!!\")\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Daniel-sanabria0419.py",
    "content": "#Pagina python = \"https://www.python.org/\"\n'''\nEste es otro tipo de comentario en el que se abarca mas lineas de codigo \nno es necesario escribir almohadillas al inicio de cada linea\n'''\n\n#varible en python\nmiPrimeraVariable =  \"esto es una variable\" \n\n\n#En python no hay constantes sin embargo se usan variables en mayusculas para \n#informar que esa variable no se cambia de valor por lo tanto es una cosntante\nlenguaje = \"python\"\nCONSTANT = 3.1416\n#TIPOS DE DATOS COMUNES\ncadena = \"Esto es una cadena de texto\" #TIPO STR\nnumero = 123 #TIPO INT\nbooleano = False #TIPO BOOLEAN\ndecimal = 23230.2 #TIPO FLOAT\n#TIPOS DE DATOS INTEGRADOS\nlista =[2,3,1,5,4] #LISTAS\ntupla = (1,2,3,4,5) #TUPLAS\nrango = range(10) #RANGO DE NUMEROS\nconjutos_set = {10,20,30} #CONJUTO ELEMENTOS UNICOS\ndiccionario = {\"clave\" : \"valor\" , \"mil\" :1000} #DICCIONARIOS\nnull = None #TIPO NULO no tiene valor\n\n#HAY 2 O 3 MAS PERO SON MUCHO MAS COMPLEAJOS Y VEO INNECESARIO PONERLOS EN UN EJERCICIO DE ESTE NIVEL}\nprint(\"!Hola\", lenguaje,sep=\", \", end=\"!\\n\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Danilo0203.py",
    "content": "# Pagina oficial de Python\n# https://www.python.org/\n\n# Esto es un comentario de una solo linea\n\n\"\"\" Comentario\nde multiples\nlineas \"\"\"\n\n# Variables\nmi_variable = 'Mi Variable'\n\n# Constante\nCONSTANTE = 'Mi constante'\n\n# Datos Primitivos\n\n# int => Intenger => Numeros Enteros\nmi_int = 123\nprint(type(mi_int))\n\n# float => Float => Numeros Decimales\nmi_float = 123.12\nprint(type(mi_float))\n\n# Bool => Booleans => Datos Booleanos (Verdadero / Falso)\nmi_bool_true = True\nmi_bool_false = False\nprint(type(mi_bool_true), type(mi_bool_false))\n\n# Str => Sttrings => Cadena de textos\nmi_cadena_texto = 'Mi cadena de texto'\nprint(type(mi_cadena_texto))\n\nprint('¡¡Hola Python!!')\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Dans182.py",
    "content": "\"\"\"EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\"\"\"\n# - Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n# https://www.python.org/\n\n\n# - Representa las diferentes sintaxis que existen de crear comentarios\n# Esto es un comentario\n\"\"\"Esto tambien es un comentario\"\"\"\n\n# - Crea una variable (y una constante si el lenguaje lo soporta).\nvariable_de_prueba = 1\nCONSTANTE_DE_PRUEBA = 2\n\n# - Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n\nstring = \"string\"\nstring2 = 'string'\nint = 1\nfloat = 1.5\nboolean = True\n\n# - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nprint(\"Hola Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Daparradom.py",
    "content": "# Sitio oficial Python: https://www.python.org/\n\n# Este es un comentario en una línea\n\n\"\"\"\nEste es un comentario en varias líneas\nTal como podemos observar se puede \nescribir en varias lineas.\n\n\"\"\"\n\n# Tipos de Datos\n\nentero = 1\nstring = \"Esta es una cadena de texto\"\nbooleano = False\nflotante = 5.555\ncomplejo = 5 + 7j\n\n# saludando a Python\n\nprint(\"¡Hola Python!\")\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/DarianGL.py",
    "content": "# https://www.python.org/\n\n# Este es un comentario en una linea de codigo\n\n\"\"\"\nEste es un comentario \nen varias lineas\nde codigo en Python\n\"\"\"\n\n# Variables y Constantes\nprimer_variable = \"Representa un valor que ira cambiando\"\nsegunda_variable = \"De esta forma\"\n\nCONSTANTE = \"Representa un valor que se mantendrá igual\"\n\n# Datos primitivos\nmy_int = 8 # sirve para numeros enteros\nmy_float = 8.5 #sirve para numeros decimales\nmy_bool = True\nmy_bool = False #sirve para aplicar variables de verdadero y falso\nmy_string = \"para crear cadenas de texto\"\nmy_other_string = 'Tambien se puede utilizando comillas simples'\n\nprint(\"¡Hola, Python!\") # Esto sirve para imprimir por computadora\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/DataCiriano.py",
    "content": "#00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n\"\"\"\nDificultad: Fácil | Publicación: 26/12/23 | Corrección: 02/01/24\nEjercicio\n/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n \"\"\"\n \n # https://www.python.org/\n \n\"\"\"\nComentario \nen varias\nlíneas\n\"\"\"\n\n#Comentario en una sola línea\n\nejemplo_variable = 3\n\nvariable_int = 5\n\nvariable_float = 3.5\n\nvariable_bool = True\n\nvariable_str = \"perro\"\n\nprint(\"¡Hola, Python!\")\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/DavidGRamiro.py",
    "content": "\r\n\r\n# MAGIC PYTHON \r\n# Documentación oficial -> https://www.python.org/\r\n\r\n\r\n\r\n# Esto es un comentario en una sola línea\r\n'''\r\n    Esto sigue siendo un comentario\r\n    pero en multiples líneas.\r\n'''\r\n\r\n\"\"\"\r\n    También se puede definir con comillas \r\n    dobles para comentarios multilínea\r\n\"\"\"\r\n\r\nvariable = 'moureDev'\r\nvariable_tipada : str = 'moureDev'\r\n\r\nCONTANTES = 'Esto es una constante'\r\nCONSTANTE_TIPADA : str = 'Constante tipada'\r\n\r\nint = 2024\r\nfloat = 2024.0\r\nbool = True or False\r\nstr = 'Dato de tipo string'\r\ntuple = (1,2,4,5,6)\r\nlist = [1,2,3,4,5]\r\ndict = {'color': 'Rojo', 'marca': 'Audi', \"modelo\": 'A3'}\r\n\r\n\r\nprint('Hola, Python!')\r\n\r\n\r\n\r\n\r\n\r\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/DerianCastilloP.py",
    "content": "##############################################################\n#- Crea un comentario en el código y coloca la URL del sitio web oficial del\n# lenguaje de programación que has seleccionado.\n##############################################################\n\n\n#https://wwww.python.org\n\n\n##############################################################\n#- Representa las diferentes sintaxis que existen de crear comentarios\n# en el lenguaje (en una línea, varias...).\n##############################################################\n\n\n#Este es un comentario de una linea\n\n\"\"\"\nEste es un comentario \nde varias lineas. \n(nota: tambien lo puedes hacer \ncon comillas simples)\n\"\"\"\n\n'''Este es\nel ejemplo con comillas \nSimples'''\n\n\n##############################################################\n#- Crea una variable (y una constante si el lenguaje lo soporta).\n##############################################################\n\n\nvariable = 'Esta es una variable'\n\nCONSTANTE = 'Esta es una constante' #Nota: Python no tiene una sintaxis específica para constantes, pero \n                                          #por convención se escribe el nombre de la variable(constante) en mayúsculas.\n\n\n##############################################################\n#- Crea variables representando todos los tipos de datos primitivos\n# del lenguaje (cadenas de texto, enteros, booleanos...).\n##############################################################\n\n\ncadena_ca = \"Esto es un String y/o arreglo de caracteres\" #Nota: estas se pueden crear tambien con comillas simples o triples\n\nnumero_entero = 7          #Este es un tipo de dato numerico entero(int)\n\nnumero_float = 2.0         #Este es un tipo de dato numerico de punto flotante(float)\n\nnumero_complex = 4j        #Este es un tipo de dato numerico complejo (complex)\n\nbooleano_t = True          #Este es un tipo de dato (bool) verdadero\n\nbooleano_f = False         #Este es un tipo de dato (bool) falso\n\n\n##############################################################\n#- Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n##############################################################\n\nprint('¡Hola, python!')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Devkenn.py",
    "content": "# https://www.python.org/\n\"\"\"\nComentario de\nvarias \nlineas\n\"\"\"\ncadenaTexto = \"python\"\nnumeroEntero = 6\nbooleano = False\n\nprint(f\"Hola {cadenaTexto}\")\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/DiazYY.py",
    "content": "# this is a comment\n# https://www.python.org/\n\n'''Esto es un comentario de varias\nlineas, en python'''\n\nvariable = \"Esto es una variable\"\nCONSTANTE = \"No cambiar esta constante\"\n\ncadena_texto = \"Esto es un string\"\nnumero_entero = 21\nnumero_decimal = 32.2\nbooleano = False\nbooleano1 = True\nlista = list('casa')\nlista1 = ['esta', 'es', 'otra', 'lista']\ntupla = ('esto', 'es', 'una','tupla')\nconjunto = {'esto','es', 'un', \"set\"}\ndiccionario = {'valor1':2}\nlenguaje = 'python'\nprint('hola {}'.format(lenguaje))\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Dieggop0.py",
    "content": "# https://www.python.org/\n# Primera vez usando Python \n\n\"\"\"\nNo sabia esto\nwow\nQue loco\n\n\"\"\"\n'''\nnya \nlol\nxd\n'''\n\n\nmy_variable = \"jamon con queso\"\nmy_variable = \"queso con jamon\"\n\n\nVALOR_DE_PI =3.1416 #Se usa por conveniencia\n\n\nel_int = 2\nel_float = 1.3\nel_bool = true\nel_bool = false \nun_string = \"La vida loca\"\notro_string =\"locura\"\n  \nPrint (\"¡Hola python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/DiegoGomezcor4.py",
    "content": "\"\"\"\nEJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\"\"\"\n\n# https://www.python.org/\n\n# comentario de una sola linea\n\"\"\"\ncomentario de\nmultiples\nlineas\n\"\"\"\n\n#variable\nvariable = 'valor'\nCONSTANTE = 'valor constante'\n\n\nentero = 5\nflotante = 5.2\nbooleano = True\ncadena = 'valor de cadena'\n\nprint('¡Hola, Python!')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/DiegoIBB.py",
    "content": "#https://www.python.org/\n\n#Comentario de una linea\n\n\"\"\"\nComentario de varias\nlineas\n\"\"\"\n\nvariable = \"Esta es una variable\"\nCONSTANTE = \"Esta es una constante\"\n\ntipo_integer = 1\ntipo_float = 2.3\ntipo_boolean = True\ntipo_string = \"Cadena o String\"\n\nprint(\"Hola Python!!\")\n\nprint(tipo_integer)\nprint(tipo_float)\nprint(tipo_boolean)\nprint(tipo_string)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Dkp-Dev.py",
    "content": "# 1.Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n# Empezamos de cero!\n\n# https://www.python.org\n\n\"\"\" \n    Este es\n    un comentario\n    en 3 lineas\n\"\"\"\n# 2.Crea una variable (y una constante si el lenguaje lo soporta).\nvariable = \"Mi Variable\"\nMY_CONSTANT = \"Constante\" # Esta constante puede mutar, pero al estar en mayusculas, por convencion nadie la deberia de cambiar\n\n# 3.Crea variables representando todos los tipos de datos primitivos\nint_var     = 7\nfloat_var   = 2.5\nbool_var    = True\nbool2_var   = False\nstring_var  = \"Cadena de texto\"\nstring2_var = 'Cadena de texto con comilla simple'\n\n# 4.Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\nYO      = \"Dkp-Dev!\"\nPYTHON  = \"Python!!\"\n\nprint(\"Hola\", PYTHON, \"soy \",YO)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Dota43ver.py",
    "content": "# https://python.org\n\n# esto es un comentario\n\n\"\"\"\nesto es\nun comentario en\nvarias lineas\n\n\"\"\"\n\n'''\nesto es\nun comentario en\nvarias lineas\ntambien\n'''\n\nmi_variable = \"esto es una variable\"\n\nMY_CONSTANT = \"esto simula una constante\"\n\nmi_int = 1\nmi_float = 1.5\nmi_bool = True\nmi_bool2 = False\nmi_str = \"esto es un str\"\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/E-techgod.py",
    "content": "# Python url: https://www.python.org/ #\n\n# This is a comment on a line\"\n\n\"\"\" THis is a comment\non several lines using double quotes \n\"\"\"\n\n''' THis is a comment\non several lines using single quotes \n'''\n\nmy_name= \"Elias Arellano Campos\"\nPI= 3.14592\n\nstr_var1= \"String\" # string\nint_var2= 20 #int\nfloat_var3= 20.5 # float \nbool_var4= True # bool \nbool_var5= False # bool\ncomp_var5= (3+2j) # complex\n\nprint (\"Hello, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/E-xtian",
    "content": "#https://www.python.org/\n#varias lineas\n#de comentarios\n\"\"\"\ncomentario\nde varias\nlineas\n\"\"\"\n\nmy_variable = 3434\nmy_variable2 = \"3434\"\nmy_variableboleana = True\nmy_variablefloat = 0.5\n\nif __name__ == '__main__':\n    print(\"Hola mundo, este es python\")\n    print(\"Ahora los combinamos\",\"sumando\",my_variablefloat+my_variable)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/ETrauco.py",
    "content": "# https://www.python.org\n\n#Esto es un comentario\n\n'''\nEsto también es un comentario\npero de más de una sola\nlínea\n'''\n\n\"\"\"\nMismo del anterior pero con doble comillas\n\"\"\"\n\n# Crea una variable\nmi_variable = 14\n\n# Crea una variable constante\nMI_VARIABLE = 20 # en python las variables constantes se representan en mayúsculas\n\n\"\"\"\nTipo de datos primitivos\n\"\"\"\n\n# Cadenas de textos\nmi_nombre = \"ETrauco\"\nprint(type(mi_nombre))\n\n# Enteros\nmi_edad = 34\nprint(type(mi_edad))\n\n# Float\nmi_estatura = 1.90\nprint(type(mi_estatura))\n\n# booleans\ninfo = True\ninfo2 = False\nprint(type(info))\nprint(type(info2))\n\n# None\ndireccion = None\nprint(type(direccion))\n\n\"\"\"\nImprimir \"Hola Python\"\n\"\"\"\n\nprint(\"Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Eberstr.py",
    "content": "# url: https://www.python.org/\n\n# comentario\n\n'''\nTambién un comentario\n'''\n\n\"\"\"\nOtro comentario\n\"\"\"\n\nvariable = \"Hola\"\nCONSTANTE = \"Constante?\" # Es por convención, no es una contante real\n\nvar_int = 1\nvar_str = \"string\"\nvar_bool = True\nvar_float = 1.0\n\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Elbam.py",
    "content": "#https://www.python.org/\n#Este coentario es e varias LIneas\nletra=\"A'\" #Aqui creo una variable\nDB_NAME=\"root\" #esto es constante\ndatoprimitivo1=12 #entero\ndatoprimitivo2=54.46 #real\ndatoprimitivo3 = False #booelan\ndatoprimitivo4 = \"Elba M2\" #string\nprint (\"¡Hola, Python!\")\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/EliasBonnin.py",
    "content": "# Ejercicio 00\n# En el siguiente URL https:/python.org Tenemos la documentacion de phyton\n# # Los retos se encuentran en https://retosdeprogramacion.com\n\n# Hola mundo Python\n\nprint(\"Hola, Phython\")\n\n# Declarando variables\n\nmy_variable = \"Variable de string\"\nprint(my_variable)\n\nmy_string = \"Esto es una cadena de texto\"\nmy_int = 7\nmy_float = 3.14\nmy_bool = False\n\nMY_CONSTAT = 1  # Constantes en Python\n\nprint(type(my_int))\nprint(type(my_float))\nprint(type(my_bool))\nprint(type(my_string))\n\n'''\nEsto es un comentario de otro tipo.\nComentamos varias lineas\nDe\nCodigo\n\n'''\n\n\"\"\"\nEsto es otra forma de comentar.\nMuchas lineas de codigo\n\n\"\"\"\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Eliskopun.py",
    "content": "# sitio web oficial de Python: https://www.python.org/ fuente sobre uso de comentarios y docstrings: https://peps.python.org/pep-0008/\n\n\n# Sintaxis de comentarios:\n\n# *Comentario de una linea (uso comun y recomendado para todo el codigo)\n\n# Este es un comentario de varias líneas\n# utilizando el símbolo de almohadilla\n# en cada línea.\n\n\"\"\" \n*Docstring segun lo que investigue su uso \nprincipal es para documentaciondentro del \ncontexto de: funciones, métodos, clases\ny módulos.\n\"\"\"\n\n'''\ntambien pueden escribirse con comillas \nsimples aparte de las dobles, no se \nrecomienda para simples comentarios ya \nque las docstrings se almacenan como \nparte de los atributos del objeto y \npueden ser accesibles en tiempo \nde ejecución, lo que no ocurre \ncon los comentarios regulares.\n'''\n\nmi_variable = \"las variables almacenan datos que pueden ser manipulados\"\n\nMI_CONSTANTE = 299792458\n\nmi_entero = 11\n\nmi_flotante = 99.99\n\nmi_cadena = \"¡Hola, Python!\"\n\nmi_booleano = False\n\nmi_none = None\n\nprint(mi_cadena)\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/EmmanuelMMontesinos .py",
    "content": "# Sitio oficial de Python -> https://www.python.org/\r\n\r\n# Comentario de una linea\r\n\r\n\"\"\"\r\nComentario de multíples lineas\r\n\"\"\"\r\n\r\n'''\r\nOtro comentario de multíplas lineas\r\n'''\r\n\r\nvariable = \"hola\"\r\nCONSTANTE_FALSA = \"Mundo\"\r\n\r\ntexto = \"Texto de ejemplo\"\r\nentero = 100\r\nflotante = 15.6\r\nbooleano = True\r\nnone = None\r\n\r\nprint(\"Hola, Python!\")\r\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/EricJoel-code.py",
    "content": "# https://www.python.org/\n\n# Este es un comentario en Python\n\n\"\"\" Esto es un comentario de varias líneas en Python \"\"\"\n\nmy_variable = \"Hola\"\n\nMY_CONSTANT = 3.14 # Esto es una constante por convención\n\n# Tipos de datos primitivos \n\nmy_integer = 10         # Entero\nmy_float = 3.14        # Flotante\nmy_string = \"Hola\"      # Cadena de texto\nmy_other_string = 'Mundo' # Cadena de texto\nmy_boolean = True       # Booleano\nmy_other_boolean = False # Booleano\n\nprint(\"Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/ErickCis.py",
    "content": "# https://www.python.org/\n\n\"\"\"\nComentario\n1\n\"\"\"\n'''\nComentario\n2\n'''\n\nmy_var='Hola soy Erick :)'\n\nvar_1 : int = 10\nvar_2 : float = 10.0\nvar_3 : bool = True\nvar_4 : str = 'texto'\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/EriickM.py",
    "content": "# https://www.python.org/\n\n# Este comentario es de una linea\n\"\"\" Este es un bloque de comentario\npor lo que puedo escribir en varias lineas\ny más usando triple doble comilla.\n\"\"\"\n\n'''\nO tambien usando \ntriple comillas simples\n'''\n# Variable y constante\nvariable = 24\nVARIABLE_CONSTANTE = 2\n# Tipos de datos en variables\ncadenas = type('Python')\nenteros = type(3)\nflotantes = type(3.1416)\nboleanos = type(True)\n#Impresion en consola\nprint('¡Hola, Python!')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/EspinoLeandroo.py",
    "content": "# https://www.python.org/\n\n\"\"\"\nEsto es un comentario\nque abarca múltiples líneas.\nPuedes escribir varias líneas aquí.\n\"\"\"\n\n# Esto es un comentario de una línea\n\n\nejercicio = \"#00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\"\nlenguaje = \"python\"\n\nedad = 27\ndistancia = 10000\ncantidad = 1000000\npoblacion_mundial = 7800000000\n\naltura = 1.8\npi = 3.141592653589793\n\nletra = 'A'\n\nes_mayor_de_edad = True\n\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/ExanderGuitar.py",
    "content": "# Pagina web oficial de Python\n# https://www.python.org\n\n# Este es un lenguaje de una linea\n\n'''\nEste es\nun comentario\nmultilinea\n'''\n\n\"\"\"\nY este\ntambién\n\"\"\"\n\n# Variables\nmi_edad = 50\n\n# Constantes (convención en mayúsculas, no deberían ser cambiados sus valores)\nCASAS = 30\n\n# Tipos primitivos\nentero = 5\nflotante = 23.0\ncadenas_texto = \"Paraguas\"\nbooleanos = True\nsin_tipo = None\n\n# Imprimir por pantalla\nprint(\"¡Hola, Python\")\n\nprint(type(entero))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/ExpertHacker444.py",
    "content": "#00_retoLogicaProgramacion 🧑‍💻\n\n# Esta es una línea de comentario simple 👌\n# \"https://www.python.org/\"\n\n#Esta es una forma de poder comentar en varias lineas 😁\n\n'''\n Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed sit amet nulla auctor, vestibulum magna sed, convallis ex. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Integer posuere erat a ante venenatis dapibus posuere velit aliquet.\n'''\n\n# Aquí tenemos una variable en Python 😏\n# Esta variable no tiene un tipo asignado y se inicializa como None\nValor = None\n\n\n# Python soporta varios tipos de datos 🤷‍♂️\n\n# Números enteros\ntiempo = 100\n\n# Cadenas de caracteres se puede utilizar \"\" o ''\nnombre = 'Peter Parquer' \n\n# Números de punto flotante\ncantidad = 100.50\n\n# Variables booleanas (verdadero/falso)\nbase_1 = True\nbase_2 = False\n\n\n#constante en python😏\n\n'''En Python, no hay una forma explícita de declarar constantes\n  Sin embargo, se pueden utilizar variables con nombres en mayúsculas\n  para indicar que no deben ser modificadas.\n  Esto es una convención común en la comunidad de Python\n  para indicar que una variable es una constante'''\n \n# Constante para el valor de pi \nPI = 3.14159\n\n# Se puede acceder a la constante de la misma manera que a una variable\nprint(PI)  # Imprime 3.14159\n\n\n# Imprimir por consola el nombre del lenguaje🤗\n\n#una fomra sencilla es creando una variable e ingresando el valor a la variable hacemos print del mismo \nnombre = 'Python🐍'\nprint(nombre)\n\n# Aquí asignamos el nombre del lenguaje a una variable \nlenguaje = 'Amo aprender Python🐍'\n\n# Utilizamos f-string para imprimir el nombre del lenguaje\nprint(f\"¡Hola, {lenguaje}!\")\n\n# ¡gracias por su visita!\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/FabianCz95.py",
    "content": "#Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n# https://www.python.org/\n\n#  Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n# Comentario de una sola línea\n\n'''\nComentario de multiples líneas:\n    Esto en realidad es un string de multiples líneas pero se puede utilizar como comentario al no ser asignado a una variable.\n    \n    EJERCICIO:\n    * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n    *   lenguaje de programación que has seleccionado.\n    * - Representa las diferentes sintaxis que existen de crear comentarios\n    *   en el lenguaje (en una línea, varias...).\n    * - Crea una variable (y una constante si el lenguaje lo soporta).\n    * - Crea variables representando todos los tipos de datos primitivos\n    *   del lenguaje (cadenas de texto, enteros, booleanos...).\n    * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n    *\n    * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n    * debemos comenzar por el principio.\n'''\n# Crea una variable (y una constante si el lenguaje lo soporta).\n# En Python no existe una forma de definir una constante, pero se puede simular definiendo una variable en mayúsculas.\nvariable = \"Py\"\nCONSTANTE = \"Python\"\n\n# Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\ncadena_de_texto = \"Esto es una cadena de texto\"\nentero = 10\nflotante = 10.5\nbooleano = True\n\n# Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nprint(\"¡Hola, \" + CONSTANTE +  \"!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/FabianPA505.py",
    "content": "#Python.org\n\n#this is a comment in one line\n'''\nthis is a comment in three lines\nFirst comment\nSecund comment\n'''\n\nmy_variable_constant=\"CONSTANT\" \n\nmy_string=\"string\"\nmy_int=5\nmy_boolean=True\nmy_boolean_false=False\nmy_float=4-0\n\nprint(\"!Hola Python¡\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/FabianRpv.py",
    "content": "# Sitio web Oficial: python.org\n\n# Comentario de una linea\n\n\"\"\"\ncomentario\nde varias\nlineas\n\"\"\"\n\n'''\ncomentario\nde varias\nlineas\n'''\n\nmy_variable = \"Esta es una variable\"\n\nMY_CONSTAN = \"Esta es una constante pero en realidad no lo es\"\n\n\nint = 5  #entero\nfloat = 25.5  #decimal\nbool = True  #booleano\nstring = \"Hello world!\"  #cadena de texto\n\nprint(\"Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/FedeAirala.py",
    "content": "# Reto #0 Roadmap\n\n\"\"\"\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n\"\"\"\n\n# Sitio oficial Python: https://www.python.org\n\n# Esto es un comentario en una línea.\n\n\"\"\"\nEsto es \nun comentario\nen varias líneas\n\n\"\"\"\n\n\"\"\"\nTipos de Variable en Python\n\n\"\"\"\n# Variable String\n\nstring = \"Esto es una variable string\"\n\n# Variable Constante\n\nstring_constant = \"Hola string constante\"\nnum_constante = 2024\n\n# Variable global\n\nglobal my_var\nmy_var = 2024\n\n# Números\n\n# Enteros\n\nnum_int = int\n\n# Float\n\nnum_float = float\n\n# Variable Booleana\n\nmy_var_bool = True\nmy_var_bool = False\n\n# Impresión por terminal con print\n\nprint (\"¡Hola Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/FerGz1988.py",
    "content": "# https://www.python.org/\n\n# Comentario en una linea\n\"\"\"\ncomentario en\nvarias\nlineas\n\n\"\"\"\n\n\n'''\ncomentario varias lines\n\n'''\n\nmy_variable = \"Felipe\"\n\nMY_CONSTANT = \"mi constante\"\n\n\nmy_int :int  = 1\n\nmy_float :float = 1,2\n\nmy_bool : bool = True\n\nmy_string :str = \"Texto\"\n\nprint(\"Hola, Python!!!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Fernando-Antoni0.py",
    "content": "'''\n**Crea un comentario en el código y coloca la URL del sitio web oficial del\nlenguaje de programación que has seleccionado.'''\n# https://www.python.org/\n\n'''\n**Representa las diferentes sintaxis que existen de crear comentarios\nen el lenguaje (en una línea, varias...).'''\n\n# Comentario en una linea\n\n\"\"\"\nAqui hay comentario\nen\nmultiples\nlineas\n\"\"\"\n\n'''\nAqui tambien \nhay comentarios\nen\nmultiples\nlineas\n'''\n\n# **Crea una variable (y una constante si el lenguaje lo soporta).\nvariable = \"Esta es una variable\"\nVARIABLE_CONST = \"Esta es una variable, constante\" #En python no hay constantes, constante por convencion se indica en mayuscula la variable\n\n\n'''\n**Crea variables representando todos los tipos de datos primitivos\ndel lenguaje (cadenas de texto, enteros, booleanos...).'''\n\nvariable_int = 10\nvariable_float = 2.9\nvariable_boolT = True\nvariable_boolF = False\nvariable_string = \"Cadena de Texto\"\n\n# Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\npy = \"Python!\"\n\nprint(f\"¡Hola, \" + py )"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/FernandoATello.py",
    "content": "#Este es la URL de PYTHON: https://www.python.org/\n\n#Empezando Retos de Programación con Python con el apoyo de Mouredev\n\n'''Creando un comentario con comilla simple'''\n\n\"\"\"Comentarios de varias líneas: \nQué es programar? Es indicarle a una computadora lo que debe hacer a través de\nindicaciones o instrucciones logarítmicas que pueda comprender la máquina\"\"\" \n\n#Tipos de datos\n\ntipo_string = \"Aprendiendo lógica de programación\"\ntipo_int = 23 #número favorito\ntipo_float = 23.05 #mi fecha de cumple\ntipo_bool1 = True\ntipo_bool0 = False\n\nMY_CONSTANT_PI = 3.141592 #número Pi\nMY_CONSTANT_G = 9.8 #número aceleración de la gravedad\n\nprint(\"¡Hola, Python! A darlo con todo!!!\")\n\nprint(type(tipo_string))\nprint(type(tipo_int))\nprint(type(tipo_float))\nprint(type(tipo_bool0))\nprint(type(tipo_bool1))\n\nprint(type(MY_CONSTANT_PI))\nprint(type(MY_CONSTANT_G))\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Franz-Arzapalo.py",
    "content": "\"\"\"\nEJERCICIO #00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO:\n\n- Crea un comentario en el código y coloca la URL del sitio web oficial del\n  lenguaje de programación que has seleccionado.\n- Representa las diferentes sintaxis que existen de crear comentarios\n  en el lenguaje (en una línea, varias...).\n- Crea una variable (y una constante si el lenguaje lo soporta).\n- Crea variables representando todos los tipos de datos primitivos\n  del lenguaje (cadenas de texto, enteros, booleanos...).\n- Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\"\"\"\n\n# 1. Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n\n#Url: https://www.python.org\n\n# 2. Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n\n\"\"\"\nPara crear un comentario de una sola linea se puede hacer con (#) \nponiendo ese signo antes de la linea que se desea comentar:\n\"\"\"\n\n# Ejemplo de comentario de una sola linea.\n\n\"\"\"\nPara comentar mas de una linea de codigo con python se tiene que untilizar \nel signo de las comillas pueden ser simples o dobles se tinen que repetir \n3 veces al inicio y al final de las lineas que se desean comentar:\n\"\"\"\n\n\"\"\"\nEjemplo de comentario\nde mas de una linea.\n\"\"\"\n\n# 3. Crea una variable (y una constante si el lenguaje lo soporta).\n\n\"\"\" \nPara deifinir una varible en python solo tenemos que iniciar nombrando la variable y \ndefinir su valor despues de un signo igual:\n\"\"\"\n\nVariable_ejemplo = 1\n\n\"\"\"\nNo se puede definir una constante en python pero es una convencción el nombrar una \nvariable solo con mayusculas para establecer que no se debe modificar el valor de dicha variable:\n\"\"\"\n\nCONSTANTE_EJEMPLO = 2\n\n# 4. Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n\n\"\"\"\nEstos son los tipos de datos primitivos que se pueden manejar con python:\n\"\"\"\n\nIntegers = 1 # Integers o Int son tipos de datos primitivos numericos enteros.\nprint(type(Integers))\n\nFloats = 0.5 # Floats son tipos de datos primitivos numericos decimales.\nprint(type(Floats))\n\nBoolanos = True # Booleanos son tipos de datos primitivos cuyo valor es (0 o 1) o (True or False).\nprint(type(Boolanos))\n\nStrings = \"Cadenas\" # Strings son tipos de datos primitivos de valor alfabetico son cadenas de texto.\nprint(type(Strings))\n\n# 5. Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\n\"\"\"\nEl comando print sirve para imprimir un mensaje o valor en la terminal.\n\"\"\"\n\nprint(\"Hola, Python!\")\n\n# Fin."
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/FreyFonseca.py",
    "content": "# https://python.org\n\n# Comentario en una línea\n\n\"\"\"\nEsto también es\nun comentario\nen varias líneas\n\"\"\"\n\n'''\nEsto también es\nun comentario\nen varias líneas\n'''\n\nmy_variable = \"Mi variable\"\nmy_variable = \"Nuevo valor de mi variable\"\n\nMY_CONSTANT = \"Mi constante\"  # por convención\n\nmy_int = 1\nmy_float = 1.5\nmy_bool = True\nmy_bool = False\nmy_string = \"Mi cadena de texto\"\nmy_other_string = 'Mi otra cadena de texto'\n\nprint(\"¡Hola, Python!\")\n\nprint(type(my_int))\nprint(type(my_float))\nprint(type(my_bool))\nprint(type(my_string))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/GaboDev23.py",
    "content": "# https://python.org/\n\n# Comentario en una línea\n\n\"\"\"\nEsto también es\nun comentario \nen varias lineas\n\"\"\"\n\nmy_variable = \"Mi variable\"\nmy_variable = \"Nuevo valor de mi variable\"\n\nMY_CONSTANT = 'Mi constante' # Por convención\n\nmy_int = 1\nmy_float = 1.5\nmy_boolean = True\nmy_boolean = False\nmy_string = \"Mi cadena de texto\"\nmy_other_string = 'Mi otra cadena de texto'\n\nprint('¡Hola, Python!')\n\nprint(type(my_int))\nprint(type(my_float))\nprint(type(my_boolean))\nprint(type(my_string))"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Gallitofast.py",
    "content": "#https://python.org\n\n#Este es un comentario de una linea\n\n\"\"\"\nesto es un comentario\nque puede ser de varias lineas\n\"\"\"\n'''\nEsto también es\nun comentario\nque pudeser de varias\n\nlíneas\n'''\nGallo_variable = \"Mi variable\"\nGallo_variable = \"Gallo esta aprendiendo\"\n\nMY_CONSTANT = \"Mi constante\"  # por convención\n#Ya que es una constante el valor no va a cambiar\n\nmy_int = 1\nmy_float = 1.5\nmy_bool = True\nmy_bool = False\nmy_string = \"Mi cadena de texto\"\nmy_other_string = 'Mi otra cadena de texto'\nprint(\"¡Hola, Python!\")\nprint(f\"{Gallo_variable}\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Geridage.py",
    "content": "\n# Sitio web oficial del lenguaje en comentario\n# https://www.python.org\n\n# Diferentes formas de crear comentarios en pyton\n\n# Esto es un comentario en una sola línea\n\"\"\"\nY esto es un comentario\nen varias líneas \n\"\"\"\n# Creación de una variable. No existen constantes en Python\nvariable_str = \"variable\"\nvariable_int = 9\nvariable_float = 9.9\nvariable_bool = False\n\n# Los programadores usan Mayúsculas para presentar constante, Python no tiene una sintaxis dedicada para la declaración de constantes\nPI = 3.14592\nSEGUNDOS_HORA = 3600\nANCHURA_VENTANA = 760\n\n# Imprimir \"hola\" y el nombre del lenguaje\nprint(\"Hola Python\")\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/GianninaGit.py",
    "content": "\"\"\"\n/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\"\"\"\n# COMENTARIOS:\n\n# SITIO WEB OFICIAL:\n# https://www.python.org/\n\n\"\"\"\nComentario en \nvarias líneas\n\"\"\"\n\n'''\nComentario en \nvarias líneas\n'''\n\n# DECLARACION DE VARIABLES Y CONSTANTES:\n# VARIABLE\nmy_variable: str = \"Un string\"\nmy_variable = \"Otro string\"\n# CONSTANTE\nMY_CONSTANT: str = \"Un string constante que por convención no debe cambiarse porque está en mayúscula\"\n\n# DATATYPES PRIMITIVOS:\nmy_string: str = \"¡Hola, Python!\"\nmy_int: int = 1\nmy_float: float = 1.0\nmy_bool: bool = True\n\nprint(my_string)\nprint(type(MY_CONSTANT))\nprint(type(my_string))\nprint(type(my_int))\nprint(type(my_bool))"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Giovanni-Schmaily.py",
    "content": "#  https://www.python.org/\n''' https://www.python.org/ '''\n### https://www.python.org/ ###\n\na = \"Giovanni\"\n\n# cadena de caracteres (str)\nnombre = \" Giovanni \"\n\n# Entero (int)\nedad = 39\n\n# Flotante (float)\naltura = 1.78\n\n# Booleano (True)\nestudia = True\n\n# Nulo (none)\nnulo = None\n\nprint (\" Hola, Python! \")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/GomezJustine.py",
    "content": "# Esto es un comentario y el link del sitio web oficial de Python https://www.python.org/\n\n# Comentario a una linea\n\n\"\"\"\nComentario \nen \nvarias \nlineas\n\"\"\"\n\n#Esto es una variable y una constante \nx = 5\nx = x + 3\nPI = 3.14159 # Aunque no impida que se pueda cambiar el valor, al estar en mayuscula se intuye en el lenguaje que es una constante \n\n# Variables con los datos primitivos\nedad = 19 # int (entero)\nestatura = 1,78 # float (flotante o decimales)\nes_lindo = True # bool (boleano solo aceptan true o false )\nes_bajo = False \nnombre = \"Justine Gomez\" #string ( cadenas de texto)\n\n\ny = \"¡Hola, Python!\"\nprint (y)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Gordo-Master.py",
    "content": "# https://python.org\n\n# Comentario en una sola linea\n\"\"\"\nComentario \nen \nvarias \nlineas \n\"\"\"\n\n'''\nOtra forma de hacer \nun comentario \nvarias lineas\n'''\n\n\nmy_variable = \"Mi variable de Python\"\nmy_variable = \"Segundo valor de la variable\"\n\n# Python no tiene una constante. \n# Pero se tiene la convención de poner en MAYUSCULA para representar una constante\n\nCONSTANT = \"Mi (no) constante xd\"\n\n# Datos primitivos\nmy_entero: int = 73 # int\nmy_float: float = 73.73 # float\nmy_complex: complex = 4 + 8j # complex: numero complejo\nmy_bool: bool = True # boolean\nmy_string: str = \"Este es el dato primitivo: cadena de texto\" # string\nmy_other_string: str = 'Este es el dato primitivo: cadena de texto' # string\n\n# Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\nprint(\"¡Hola Python!\")\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/GySeR17.py",
    "content": "#Hola buenas, me presento, soy Sergio, el sitio wwweb oficial de Python es: https://python.org/\n\n#Los tipos de comentarios en Python pueden ser:\n\n#1. Comentarios en una linea.\n\n\"\"\"2. Comentarios\nen 2 o\nmas lineas (multilinea)\"\"\"\n\n'''2.1 Comentarios \nen 2 o\nmas lineas (multilinea)'''\n\n\"\"\"Segun ChatGPT (No quise buscar en toooooda la documentacion srry), no se pueden crear constantes\n...estrictas en Python pero si se pueden tomar convenciones para evitar cambiar el valor de las...\n...variables que llevan su nombre con letras mayusculas, creando clases o estableciendo el valor... \n...final de alguna variable\"\"\"\nPI = 3.141592 #Constante\nGRAVEDAD = 9.81 \n\nnombre = \"Sergio\" #variable\n\n#Tipos de variables:\n\"\"\"\n1. str = String o cadena de texto.\n2. int = Numeros positivos o negativos pero con valor ENTERO sin decimales.\n3. float = Numeros positivos o negativos pero con valor entero o DECIMAL.\n4. bool = Representa valores logicos de verdadero o falso.\n5. complex = Numeros complejos(positivos/negativos y numeros int/float), con una parte real y otra imaginaria.\n6. NoneType = Representa la ausencia de valor o valor nulo\n\"\"\"\n\nstring1 = \"Esto es un string\"\nentero = 5 #Enteros\nflotante = -7.35 #Flotantes\n#Booleanos (True y False):\nverdad = True\nfalso = False\n#Numberos complejos\nk = 5 - 3.21j #Donde 5 es la parte real y j denota la parte imaginaria de la ecuacion\nsuma = None #Para representar la ausencia de valor o valor nulo\n\nprint(\"Hola, python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/HackyN3t.py",
    "content": "\n# Esto es un comentario\n# multilínea usando el símbolo `#` en cada línea\n\n\"\"\"\nTambién este\nes\nun comentario multilínea\n\"\"\"\n\n'''\nEste también\nes un comentario multilínea\n'''\n\n# Variables:\n\nmy_variable = \"Esta es una cadena de texto\"\n\n# Se puede cambiar el valor de la variable:\nmy_variable = \"Se puede cambiar el valor de la variable\"\n\n# Python no tiene constantes. Por convención, las variables que deben\n# tratarse como constantes se escriben en mayúsculas:\nMY_CONSTANTE = 3.14\n\n# Datos Primitivos\n\nmy_int = 23\nmy_float: float = 33.3 \t\t# Podemos indicar con los : que tipo tiene que ser nuestra Variable\nmy_bool = True\nmy_bool2 = False\nmy_string = \"Hola Mundo!\"\n\nprint(my_string)\n\n#Si queremos saber que tipo de dato es una variable podemos usar la funcion type()\n\nprint(type(my_int))\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Hanns87.py",
    "content": "# https://python.org\n\n# Coentamtario en una linea\n\n\"\"\"\nEsto tambien es\nun comentario \nen varias lines\n\"\"\"\n\n'''\nEsto tambien es\nun comentario \nen varias lines\n'''\n\nmy_variable = \"My variable\"\nmy_variable = \" Nuevo valor de mi variable\"\n\n# Python no tiene constantes, no existe\nMY_CONTANT = \"My constante\" # por convencion en python se define algo como constante, escribiendola en mayuscula\n\n# Variables con todos los tipos primitivos\nmy_int = 6 # numerico\nmy_float = 5.5 # decimal\nmy_bool= True # variable booleana, verdadero o falso\nmy_bool= False # variable booleana, verdadero o falso\nmy_string = \"Mi cadena\" # variable de texto\nmy_other_string = 'Mi cadena' # variable de texto\n\nPrint(\"Hola, Python\")\n\nPrint(type(my_int))\nPrint(type(my_float))\nPrint(type(my_bool))\nPrint(type(my_string))\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/HarrisonGuerrero18.py",
    "content": "# URL: https://www.python.org/\n\n# Comentario con una línea\n\n\"\"\"\n    Comentario con varias líneas\n    que abarca múltiples líneas\n\"\"\"\n\n'''\n    Comentario con varias líneas\n    que abarca múltiples líneas\n'''\n\n# Crear variable\n\nnombre = \"Harrison\"\napellido = \"Guerrero\"\n\n# Crear constante \n\nMI_CONSTANTE = \"Harrison David\" # Por convención\n\n# Variables con tipo de datos \n\n## Tipo de Dato Entero\n\nvariable_entero = 7\nprint(type(variable_entero))\n\n## Tipo de dato Flotante\n\nvariable_flotante = 7.5\nprint(type(variable_flotante))\n\n## Tipo de dato Booleano\n\nvariable_booleana = False\nprint(type(variable_booleana))\n\n## Tipo de dato Cadena de texto\n\nvariable_string = \"Hola\"\nprint(type(variable_string))\n\nvariable_string_dos = 'Hola'\nprint(type(variable_string_dos))\n\n# Imprimir por terminal\n\nprint(\"¡Hola, Python! :D\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Harry-GNS.py",
    "content": "\n## Web Oficial de python\n\n## https://www.python.org/\n\n## Este es un comentario normal\n\n\"\"\"\nEste es un comentario en varias lineas\n\n\"\"\"\n\n'''\nEsto tambien es un comentario en varias lineas\n\n'''\n\na = 'esta es una variable'\nCONSTANTE = 'Por convencion esto es constante'\n\n\n\nint= 2\nfloat= 2.5\nboolean= True   \nboolean= False \nstring= \"esta es una cadena\"    \nstring2= 'esta es otra cadena'\nstring_multiline= \"\"\"Esta es una cadena\nen varias lineas\"\"\" \n\nprint('!Hola Mundo!')\n\n\n\n\n\n "
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/HectrAlvz.py",
    "content": "# https://python.org/\n# https://peps.python.org/pep-0008/\n\n\n# Sintaxis que existen para crear comentarios:\n\n# Comentarios de una sola línea (usando #)\n\n# Comentario de Multiples líneas, cada uno...\n# se considera un comentario de una sola línea\n\n# Los siguientes comentarios se utilizan habitualmente para los docstrings:\n# - Para documentar módulos, clases, métodos y funciones.\n# - Su propósito principal es proporcionar una descripción clara sobre\n#   el funcionamiento y el uso del código (o comentarlo por completo).\n\n\"\"\"\nEste es un comentario \nde varias líneas,\no de bloque\n\"\"\"\n\n'''\nOtra forma de\nhacer comentarios\nvarias líneas,\no de bloque\n'''\n\n# Otra forma que no es considerada como tal un comentario son:\n# - Las cadenas de texto que no estén asignadas a una variable\n#   ni se utiliza son ignoradas por python:\n\n\" Comentarios de una sola línea (cadena de texto)\"\n' Comentarios de una sola línea (otra forma)'\n\n# NOTE: Etiquetas en Comentarios\n# Las etiquetas en comentarios son una práctica común para organizar y documentar el código.\n# Nos ayudan a identificar tareas pendientes, problemas o mejoras.\n\n# TODO: Se utiliza para indicar una tarea pendiente o una funcionalidad que falta implementar.\n# Esto sirve como recordatorio para completar una tarea en el futuro.\n\n# FIXME: Se utiliza para marcar un problema en el código que necesita ser corregido.\n# Esto indica que hay un error o un comportamiento inesperado que debe ser revisado.\n\n# Otras etiquetas comunes:\n# NOTE: Para resaltar información importante o explicaciones adicionales.\n# HACK: Para indicar soluciones temporales o poco elegantes que deben mejorarse.\n# WARNING: Para advertir sobre posibles problemas o comportamientos riesgosos.\n\n\n# Variable (y una constante si el lenguaje lo soporta).\nmy_variable = \"Esto es una Variable\"\nCONSTANTE = \"Esto es una constante. Por convención, se escribe en mayúscula.\"\n\n# Tipos de Datos Primitivos\n# No es necesario colocar type hints (anotaciones de tipo) para declarar variables,\n# ya que Python es un lenguaje de tipado dinámico.\n\n# Enteros: Número Entero\nmi_int: int = 1234567890\n# mi_int = 1234567890 # sin type hint\n# Decimales: Número Real\nmi_float: float = 1.23\n# Boléanos: Lógico\nmi_bool: bool = True # True / False\n# String: sCadena de Texto\nmi_str_1: str = \"String comillas dobles\"\nmi_str_2: str = 'String comillas simples'\nmi_char = \"A\" # \"char\" se representa como str de 1 carácter\n# NoneType: Ausencia de valor\nmi_NoneType: None = None\n# Bytes: Secuencia de bytes (0-255)\nmi_bytes_1: bytes = b\"\\x48\\x6f\\x6c\\x61\" # Hola\nmi_bytes_2: bytes = b'abc'\n# Complejos: Números complejos (parte real + imaginaria)\nmi_complejo: complex = 3 + 4j\n\nprint(type(mi_int), mi_int)\nprint(type(mi_float), mi_float)\nprint(type(mi_bool), mi_bool)\nprint(type(mi_str_1), mi_str_1)\nprint(type(mi_str_2), mi_str_2)\nprint(type(mi_char), mi_char)\nprint(type(mi_NoneType), mi_NoneType)\nprint(type(mi_bytes_1), mi_bytes_1)\nprint(type(mi_bytes_2), mi_bytes_2)\nprint(type(mi_complejo), mi_complejo)\n\nprint(\"\\n¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/HendryAvila.py",
    "content": "# Esto es un comentario en una linea\n\"\"\"\nEsto es un comentario multilñinea    \n\"\"\"\n\n'''\nEsto tambien es un comentario multilinea\n'''\nPYTHON = \"https://www.python.org.com\"\n\n#Tipos de datos primitivos\nmy_string = \"texto\"\nmy_string2 = 'texto'\nmy_int = 100\nmy_bool = True | False\nmy_float = 1.2\n\n#Tipos de datos compuestos\nmy_list = []\nmy_tuple = (\"\",\"\")\nmy_set = {\"\",\"\",\"\"}\nmy_dict = {\"name\":\"hendry\"}\n\n\n#Datos especiales\nmy_none = None\n\nprint(f\"Hola {PYTHON}!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/HenryDavidPrimera.py",
    "content": "# https://docs.python.org/3/\n\n# Este es un comentario de una línea es recomendable\n# por las buenas prácticas qué máximo tenga 80 caracteres.\n\n\"\"\"\nEsto también es un\ncomentario pero\nde varias líneas\n\"\"\"\n\n'''\nEsto también es un \ncomentario pero \nde varias lineas\n'''\n\n# Crear una variable\nhola_mundo = \"Hola mundo\"\nhola_mundo = \"Nuevo valor de mi variable\"\n\n# Python no tiene constantes, sin embargo; se puede hacer algo parecido.\n\nMY_CONSTANTE = \"Mi constante\"  # por convención\n\nentero: int = 1\nflotante = 9.10\nbooleano1 = True\nbooleano2 = False\nString = \"Este es un str\"\n\n# También se pueden transformar algunos valores a otros.\n\nprint(float(1))\n# 1.0\nprint(int(9.10))\n# 9\nprint(bool(1))\n# True\nprint(bool(15))\n# True\nprint(bool(-4))\n# True\nprint(bool(0))\n# False\nprint(str(1))\n# '1'\nprint(str(True))\n# 'True'\n\n# También se pueden transformar str a int, float y bool\n# siempre y cuando sean los valores correctos.\n\nprint(int(\"9\"))\n# 9\nprint(int(\"9.10\"))  # No se puede transformar.\n# ValueError: invalid literal for int() with base 10: '9.10'\nprint(float(\"3.10\"))\n# 3.1\nprint(float(\"1\"))\n# 1.0\nprint(float(\"3.4, 1\"))  # No se puede transformar.\n# ValueError: could not convert string to float: '3.4, 1'\n\nprint(bool(\"0\"))  # aquí pasa algo diferente, si el str tiene carácteres es True.\n# True\nprint(bool(\"\"))  # si no tiene devuelve False.\n# False\n\n\"\"\"\nAdicional:\nPor cierto si vas a ejecutar el código \nrecomiendo que comentes las lineas que dan error\ny también cuando hagas un proyecto en Python y uses PyCharm \nsegún la PeP8 debes dejar un espacio en blanco al final del código.\n\"\"\"\n# Por último hay una función de python que sirve para saber el tipo de dato.\n\nprint(type(entero))\nprint(type(flotante))\nprint(type(booleano1))\nprint(type(booleano2))\nprint(type(String))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Howlett9999.py",
    "content": "#https://www.python.org/\n\n#Esto es un comentario de una sola línea\n\n\"\"\"\nEsto es un comentario \nde varias líneas\n\"\"\"\n#Python no tiene un delimitador especifico para comentarios en multiples lineas,\n#por lo que se usan comillas triples, que funcionan como cadenas de texto no asignadas a una variable\n'''\nEsto tambien es un \ncomentario de \nvarias lineas\n'''\n\nnueva_variable = \"nueva variable\"\nvariable1 = 10\nprecio_con_impuesto = 19.90\n\nCONSTANTE1 = \"Constante 1\"     #por convencion porque python no tiene constantes\nMI_CONSTANTE_1= \"100\" \nPI = 3.1416\n\n#Tipos de datos numéricos\ndato_int = 10\ndato_float = 3.1416\ndato_complex = 2 + 3j\n#Tipos de datos booleanos\ndato_bool = True\ndato_bool = False\n#Tipos de datos secuenciales\ndato_str = \"nueva cadena de texto\" #cadenas de caracteres\notro_dato_str = 'segunda cadena de texto'\ndato_list = [1,2,3,\"cuatro\"]  #lista, colección ordenada y mutable de elementos\ndato_tuple = (1,2,3,\"cuatro\") #coleccion ordenada e inmutable de elementos\ndato_range = range(0,10) #secuencias de numeros enteros, comunmente usadas en bucles\n#Tipos de datos conjuntos\ndato_set = {1,2,3,4} #conjuntos, colección desordenadande elementos unicos\ndato_frozenset = frozenset([1,2,3,4]) #conjuntos inmutables\n#Tipos de dato de mapeo\ndato_dict = {\"clave\": \"valor\", \"edad\": 25} #diccionarios, una colección desordenada de pares clave-valor\n#Tipos de dato binario\ndato_bytes = b\"hola\" #secuencia inmutable de enteros en el rango de 0 a 255\ndato_bytearray = bytearray(b\"hola\") #secuencia mutable de enteros en el rango de 0 a 255\ndato_memoryview = memoryview(b\"hola\") #un objeto que puede acceder a los datos subyacentes de un objeto binario sin copiarlo\n\n#Tipo Especial\ndato_NoneType = None #representa el valor none, es decir, la ausencia de valor\n\nprint(\"¡Hola, Python!\")\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/HumbertoMorales1416.py",
    "content": "# Sitio web oficial - https://www.python.org/\n\n# Este es un comentario en una sola linea en Python\n\n\"\"\"\nEste es un comentario \ncon mas de una linea de codigo\nen Python\n\"\"\"\n\nmy_variable = \"Esta es una variable\"\nmy_variable = \"Esta es una actualizacion de las variables\"\n\n# En python no existen constantes, todas son variables\n# Por lo regular se realiza por convencion colocando el nombre de la variable en mayusculas\n\nMY_CONSTANT = \"Esta es una constante\"\n\nmy_str = \"Esta es una variable de texto\"\nmy_int = 10\nmy_float = 10.5\nmy_bool = True\nmy_bool = False\n\nprint(\"¡Hola!, este es el lenguaje Python\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Hyromy.py",
    "content": "# https://www.python.org\n\n# comentario monolinea\n\"\"\"\n    comentario\n    multilinea\n\"\"\"\n\nvariable = 777\nPI_NO_CONSTANTE = 3.14159\nPI_CONSTANTE = (3.14159)\n\nboleano = True\nentero = 55\ndecimal = 1.77\ncadena = \"Hyromy\"\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/IgnacioGM1973.py",
    "content": "'''\nEsta es la la URL del sitio web oficial del lenguaje de programación que he seleccionado.\nhttps://www.python.org/\n'''\n# Comentario en un sola línea\n'''\n  Comentario en varias líneas\n'''\n\nMiPrimeraVariable = \"Hola\"\nMI_PRIMERA_CONSTANTE = 3.1416\n\n# Muestra de las variables tipo de datos primitivos\n\n# String(cadena)\ncadena = \"Hola Mundo\"\nprint(\"cadena-->\", type(cadena))\n# integer(entero)\nnumero = 10\nprint(\"numero-->\", type(numero))\n# float\nnumeroFloat = 4.5\nprint(\"numeroFloat-->\", type(numeroFloat))\n# nulo\nresultado = None\nprint(\"resultado-->\", type(numeroFloat))\n\nprint(f\"Hola, python\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Ipfabio.py",
    "content": "# https://www.python.org/\n\n\"\"\" \nEsto es\nun comentario\nmultilinea \n\"\"\"\n\n'''\nEsto también es \nun comentario\nmultilinea \n'''\n\nsaludo = \"Hola\"\nCONSTANTE = \"Mi 'constante'\" # No me cambies.\n\nmy_int = 1\nmy_float = 2.5\nmy_bool = True\nmy_bool = False\n\nprint(f'{saludo}, elijo Python')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Irenetitor.py",
    "content": "#1.\n# The language I've selected is Python and you can find all the information about on it's official website: https://www.python.org/\n\n#2. \n#this is a one line comment \n\n\"\"\" \nthis is a multiline comment \n\"\"\"\n'''\nthis is another approach for a multiline comment\n'''\n\n#3.\nmy_variable = \"this is my first variable\"\n \n #There is no built-in way to declare constants in Python\n\n#4. \nx = 10               # int\ny = 3.14                # float\nz = \"Hi\"                # str\nflag = True  # or False   bool\nc = 2 + 3j              # complex\n\n#5. \nprint(\"Hello, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Ivanpelu7.py",
    "content": "#Esta es la página oficial de Python: https://www.python.org/\n\n\"\"\"\nEste es\nun comentario\nen varias\nlineas\n\"\"\"\n\n#Este es un comentario en una linea\n\nMI_CONSTANTE = \"Mi constante\"\nmi_variable = 3\n\nmi_string = \"Python\"\nmi_int = 5\nmi_float = 6.6\nmi_sin_tipo = None\nmi_booleano = True\n\nprint(f\"¡Hola, {mi_string}!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/JAdraz.py",
    "content": "# To know more about python clic on https://python.org\n\n# COMMENTS\n\n# We use an # to create one line comments over our code\n\n\"\"\"\nAlso, we can use double quotes to create\ncomments in several lines\n\"\"\"\n\n'''\nOr we can use single quotes to create comments\nin several lines as well\n'''\n\n# VARIABLE AND CONSTANT\n\nmy_var = 'This is a string variable'\n\nMY_VAR = 'This is a constant variable in Python by convention'\n\n# DIFFERENT VARIABLES IN PYHTON\n\nmy_string = 'my string'\nmy_integer = 10\nmy_float = 10.50\nmy_bool = True\nmy_nule = None\n\n# PRINT\nprint('Hello, Python!')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/JacMac45.py",
    "content": "# https://www.python.org/\n\n# Comentario de una linea\n\n\"\"\"\nComentario de varias lineas\n\"\"\"\n'''\nComentario de varias lineas\n'''\n\n# Variable\nname = \"JacMac45\"\n\n# Pyton no soporta variables constantes\n\nMY_CONSTANT = \"Mi variable constante\" # Por convencion\n\n# Tipos de datos primitivos\n\n# String\nmy_string = \"Python\"\n\n# Integer\nmy_integer = 10\n\n# Float\nmy_float = 10.5\n\n# Boolean\nmy_boolean = True\nmy_boolean = False\n\n# Print\nprint(\"¡Hola, Python!\")\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Jackziel-Sumoza.py",
    "content": "# Este es el sitio web oficial de Python (https://www.python.org/)\n# Además de los comentarios normales yo utilizo better-comments para utilizarlo en mis proyectos\n\n# comentario básico: para explicar piezas de código\n#* texto color verde: importante\n#** texto color morado: anotaciones sobre el código o anotaciones personales.\n#! texto color rojo: errores, problemas, detección de malas practicas etc.\n#TODO: texto color naranja: aclarar una funcionalidad global. \n#? texto color amarillo: Preguntas, ideas de código, ayuda.\n#// texto color gris: subraya el texto, código obsoleto, código erróneo.\n\n\"\"\"Este es un comentario multiline.\n\ncomentario básico: para explicar piezas de código\n#* texto color verde: importante\n#** texto color morado: anotaciones sobre el código, personales.\n#! texto color rojo: errores, problemas, detección de malas practicas etc.\n#TODO: texto color naranja: aclarar una funcionalidad global. \n#? texto color amarillo: Preguntas, ideas de código, ayuda.\n#// texto color gris: subraya el texto, código obsoleto, código erróneo.\n\n\"\"\"\n\nvariable_normal = \"Esto es una variable normal\"\n# En el caso de python yo no defino las variables antes de crearlas como en javascript que se utiliza var,let,const\n\nCONSTANTE = \"Esto es una constante en python (solo es una convención)\"\n# SIN EMBARGO LOS DATOS LOS PODEMOS MODIFICAR SIN PROBLEMAS, ESTO ES PARA QUE EL PROGRAMADOR SEPA QUE NO DEBE MODIFICAR EL DATO\n\ncadena = \"Esto es un string (str)\"\nenteros = 14\nflotantes = 23.4\nverdadero = True\nfalso = False\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Jalivur.py",
    "content": "# Pagina web Fuente de recursos e informaión: https://python.land/python-tutorial\n\"\"\"\nEJERCICIO:\n- Crea un comentario en el código y coloca la URL del sitio web oficial del\n    lenguaje de programación que has seleccionado.\n- Representa las diferentes sintaxis que existen de crear comentarios\n    en el lenguaje (en una línea, varias...).\n- Crea una variable (y una constante si el lenguaje lo soporta).\n- Crea variables representando todos los tipos de datos primitivos\n    del lenguaje (cadenas de texto, enteros, booleanos...).\n- Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\"\"\"\n#COMENTARIOS:\n#Se pueden hacer de una sola liena como este, o de varias como el siguente.\n\"\"\"\nPython es fácil de utilizar y es un verdadero lenguaje de programación ofreciendo mucha más estructura y soporte para programas grandes que la que ofrecen scripts de shell o archivos por lotes. \nPor otro lado, Python también ofrece mayor comprobación de errores que C y siendo un lenguaje de muy alto nivel tiene tipos de datos de alto nivel incorporados como listas flexibles y diccionarios. \nDebido a sus tipos de datos más generales, Python es aplicable a más dominios que Awk o Perl, aunque hay muchas cosas que son tan sencillas en Python como en esos lenguajes.\n\"\"\"\n#tambien admite comillas simples.\n'''\nEsto tambien es un comentario, \nde varias lienas en \nPython.\n'''\n\n#VARIABLES Y TIPOS DE DATOS PRIMITIVOS:\n\n'''\nPython es un lenguaje de tipado dinamico, por lo que no existenten constantes como tal,\nel tipo de una variable puede cambiar en cualquier momento en tiempo de ejcución, por lo que es algo a tener \nmuy en cuenta.\n'''\n\"\"\"\nAquí hay algunos nombres de variables válidos:\n    - name_1\n    - name_2\n    - _database_connection\nEstos son nombres no válidos:\n\n    - 1tomany (no empiezan con numeros)\n    - my-number (- no esta permitido)\n    - my number (espacions no permitidos)\nAsi como tampoco esta pirmitido camelCase, como en otros lenguajes.\n\"\"\"\n#tambien se pueden insertar comentarios junto a la linea de codigo.\n#str, Cadenas de texto, mas adelante veremos mas opciones de su sintaxis.\nmy_first_var=\"esta es mi primera variable\" #en este caso se trata de una string o cadena de texto.\n#por combencion, se pueden establecer constantes por llamarlas asi a variables que no se van a manipular en tiempo de ejcucion.\nMY_FIRT_CONSTANT=\"esto es una constante entre comillas\" #se declaran en mayusculas, y por combencion se establece que son variables a consultar, solo de lectura.\n#int, puede almacenar números de -2^31 a 2^31 – 1, o lo que es lo mismo, de -2.147.483.648 a 2.147.483.647.\nmy_second_var=1 #tambien exixten variables numericas, en este caso un int o integer (entrero).\nprint(type(my_second_var))\n#float, culla capacidad es 2.2250738585072014e-308 y la máxima 1.7976931348623157e+308, equivale a un doble de C.\nmy_third_var=5.5 #floating point number, numero de coma flotante.\nprint(type(my_third_var))\n#complex, Los números complejos tienen una parte real y otra imaginaria, ambas representadas con números en coma flotante.\nmy_fourth_var=3+5j\nprint(type(my_fourth_var))\n#Tambien tenemos datos de tipo bool.\nmy_bool_var=True #son valores binarios, True(uno) o False (cero). \nprint(type(my_bool_var))\n\n#sintaxis en cadenas de caracteres.\nmy_string='esta es otra cadena de texto.'#tambien se pueden usar comillas simples.\n'''\nEn cadenas de texto, se pueden usar \\ para escapar los caracters especiales, y que no sean interpretados.\nDe esta manera podemos incluirlos en el texto,\nsin que el interprete los interprete como codigo.\nO por el contrario, para que el codigo reacciones como nos interesa.\n'''\n#my_none_scape_string='doesn't' #en este caso si no escapamos el apostrofe, lo interpreta como cierre de comillas, y genera un error.\n#SyntaxError: unterminated string literal (detected at line 53), esto se produce si decomentas liena 53.\nmy_scape_string='doesn\\'t'\nprint(my_scape_string)\n'''\nSi no quieres que los caracteres precedidos por \\ se interpreten como caracteres especiales, \npuedes usar cadenas sin formato agregando una r antes de la primera comilla:\n'''\nprint(f'C:\\some\\name')#salto de linea y con formato de string\nprint(r'C:\\some\\name')#cadena de una liena\nmy_special_string=\"esta es una cadena \\ncon salto de linea\" #esta cadena se establede en dos lineas.\nprint(my_special_string)\nmy_multiline_string=\"\"\"tambien puedes hacer estring de varias lineas,\nalnacenadolas cen variables de esta forma,\ntantas lienas como quieras.\"\"\"\nprint(my_multiline_string)\nprint(my_first_var[0])#indicando un idice podemos extraer los caracteres de una str, en este caso la primera letra.\nprint(my_first_var[6])#en este caso la posicion 7.\nprint(my_first_var[-1])#ultima posicion.\nprint(my_first_var[-2])#penultima posicion.\nprint(my_first_var[0:5])#rango de posicion 0 a 5 excluyendo el ultimo.\nprint(my_first_var[3:7])#rango de 4 a 8 sin 8.\nprint(my_first_var[:8])#rango posicion inicial a 8.\nprint(my_first_var[2:])#rango de 3 posicion en adelante.\nprint(my_first_var[-6:])#rango de posicion -6 a final.\nprint(len(my_first_var))#len() funcion para contavilizar longitud de la variable.\n\n\n\n#tambien disponemos de almacenes de datos como listas.\nmy_list=[]#esto es una lista vacia.\nmy_list=[\"hola\", 3, 3.5, 3+6j, True]#esta es una lista con todos los timpos de datos en ella.\n'''\nLas listas se pueden manejar como las cadenas de texto,\na la hora de buscar en ellas algun valor en concreto,\no valores.\n'''\n\"\"\" \nExixten infinidad de operaciones posibles con\ncada uno de los tipos de datos, en los que se pueden ir profundizando,\na medida que se abanza o se necesita.\n\"\"\"\n#hola mundo.\nprint(\"¡Hola, Python!\")\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Jalonso76.py",
    "content": "# https://www.python.org/\n\n# Este es un comentario de una línea\n\n\"\"\"\nEste es un comentario\nen vairas líneas \npara probar que funciona\n\"\"\"\n\n'''\nesto tambien es\nun comentario en \nvarias líneas\n'''\n\n#Variables\n\nmy_str_variable=\"cadena de texto\"\nprint (my_str_variable)\n\nmy_int_variable=7\nprint (my_int_variable)\n\nmy_float_variable=0.1093\nprint (my_float_variable)\n\nmy_complex_number_variable=5+5j\nprint (my_complex_number_variable)\n\nmy_bool_variable=True\nprint (my_bool_variable)\n\nmy_list_variable=(2,5,'Hola', 0.34)\nprint (my_list_variable)\n\nprint (\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/JanSua.py",
    "content": "# https://www.python.org/\n\n# Comentario de una línea\n\"\"\"\nComentario de\nvarias líneas\n\"\"\"\n\n\"Creación de variables y cte\"\na = None\nPI_CONST = 3.141592359\nb = 10\nd = 'a'\ne = 'Hola'\nf = True\n_ = \"Temporal\"\ng = (\"Tupla\", \"Inmutable\", 123)\nh = [\"Lista\", \"Mutable\", 456]\ni = {\"Llave1\":\"Diccionario\",\n     \"Llave2\":\"Mutable en valores\",\n     \"Llave3\":\"Inmutable en llave\",\n     \"Llavex\":1928}\n# En Python todo son objetos, por lo que puedo definir hasta funciones, clases y objetos a \"variables\"\n\nclass P():\n    pass\np_var = P\nany_object = p_var() # Creé un objeto de la clase P, utilizando la variable p_var de tipo clase P.\nlang_name = \"Python\"\nprint(f\"Hola, {lang_name}\")\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Jandresalvar.py",
    "content": "### 00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n\n## Ejercicio\n\n# - Crea un comentario en el codigo y coloca la URL del sitio web oficial del\n#   lenguaje de programacion que has seleccionado.\n\n# - Representa las diferentes sintaxis que existen de crear comentarios\n#   en el lenguaje (en una linea, varias...).\n\n# - Crea una variable (y una constante si el lenguaje lo soporta).\n\n# - Crea variables representando todos los tipos de datos primitivos\n#   del lenguaje (cadenas de texto, enteros, booleanos...).\n\n# - Imprime por terminal el texto: \"!Hola, [y el nombre de tu lenguaje]!\"\n\n## Solucion\n\n# - La documentación oficial de Python 3 se encuentra en la url https://docs.python.org/3/\n\n# - Para crear un comentario de una linea en python se utiliza el operador #.\n#   Python no tiene un operador para comentar multiples lineas, como otros lenguajes.\n#   No es recomendable utilizar cadenas multilinea (\"\"\") para comentar, pues aunque el codigo\n#   no se ejecuta, si ocupa espacio en memoria. Lo mejor es usar # cuantas veces sea necesario.\n\n# - En Python solo existe un operador de asignación para crear variables: el signo igual =. \n#   Este operador asigna el valor que está a la derecha al nombre que definimos a la izquierda. \n        my_var = \"Hello, Python!\"\n        my_var2 = 5 * 4\n#   Los nombres de las variables en Python deben cumplir ciertas reglas:\n#   * No pueden ser palabras reservadas del lenguaje, como if, for, while, class, etc.\n#   * Deben comenzar con una letra o un guion bajo (_), seguido de letras, números o guion bajo:\n#       * Válidos: my_var, _variable, var123\n#       * Inválidos: 2var, my-var, my var\n#   * No pueden contener espacios ni caracteres especiales como -, $, o @.\n#   * Son sensibles a mayúsculas y minúsculas: myvar, MyVar, y MYVAR son variables diferentes.\n#   En python se pueden asignar multiples valores a multiples variables en una sola linea:\n       x, y, z = 1, 2, 3\n#   En Python, las constantes no tienen un tratamiento especial como en algunos otros lenguajes. \n#   Se suelen definir usando nombres en mayúsculas por convención, pero no hay nada que impida que su valor cambie:\n        PI = 3.14159  \n        MONTHS = [\"January\", \"February\", \"March\", ...]\n# - Los tipos de datos primitivos en python y las estructuras de datos mas comunes son:\n   # Tipos numéricos\n    entero = 42                # int\n    decimal = 3.14159          # float\n    complejo = 2 + 3j          # complex\n\n    # Tipo de texto\n    cadena = \"Hola, mundo\"     # str\n\n    # Tipo booleano\n    verdadero = True           # bool\n    falso = False              # bool\n\n    # Tipo None\n    nulo = None                # NoneType\n\n    # Estructuras de datos:\n    lista = [1, 2, 3, 4]       # list\n    tupla = (5, 6, 7, 8)       # tuple\n    conjunto = {9, 10, 11, 12} # set\n    diccionario = {\"clave\": \"valor\"} # dict\n\n# - En python se usa la funcion prin() para imprimir por consola:\nprint(¡Hola Python!)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Jav-mol.py",
    "content": "# --- COMENTARIOS ---\n# Web Oficial de Python -> https://www.python.org\n\n\"\"\"\nEste es\nun comentario\nen varias \nlineas\n\"\"\"\n\n\n# --- VARIABLES ---\n# Variables\nmi_variable = \"Javi\"\n\n# Constante -> Si una variable esta en mayusculas, por convencion, se la toma por una contante\nMI_CONSTANTE = 123 \n\n\n# --- DATOS PRIMITIVOS ---\n# Integer\nnumero = 20\n\n#Flotante\ndecimal = 10.2\n\n#String\ntexto = 'Hola Mundo'\n\n#Booleanos\nbool_true = True \nbool_false = False\n\n#Nulo\nnulo = None\n\n\n# --- FINAL ---\npython = 'Python'\n\nprint(f'\"¡Hola {python}!\"')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/JaviCT14.py",
    "content": "# https://www.python.org\n\n# Comentario en una linea \n\n\"\"\"\nCreo que esto vendria\nsiendo un comentario en \n3 lineas\n\"\"\"\n\nmy_variable = \"Intento 1\"\nmy_variable = \"Intento 2\"\n\nMY_CONSTANT = \"No lo quites please\"\n\nmy_int = 5\nmy_float = 5.5\nmy_bool = True \nmy_bool = False\nmy_string = \"Cadena de Texto 1\"\nmy_other_string = \"Cadena de Texto 2\"\n\nprint (\"Hola, Phyton!\")\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Javidp01.py",
    "content": "# https://www.python.org/\n\"\"\"\nEsto también es un comentario \nen varias líneas\n\"\"\"\n\n'''\nEsto también es otroa forma de \nomentar en varias líneas\n'''\nmy_variable = \"hola\"\nmy_variable = \"adiós\"\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/JavierS123.py",
    "content": "#1 Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n \n# https://www.python.org\n\n#2 Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n\n# Comentario de una línea\n'''\ncomentario en\nvarias lineas\n'''\n\"\"\"\ntambien sirve asi\n\"\"\"\n\n#3 Crea una variable (y una constante si el lenguaje lo soporta).\nvariable = \"hola mundo\"\n\n\n#4  Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n\n\nentero = 123\nflotante = 123,0\nstring = \"hola\"\nbooleano1 = True\nbooleano2 = False\nnull = None\nlista = ['a','b','c',1,2,3]\ntupla = ('a','b',True,False,1,2,3)\nconjunto = {1,2,3,\"a\",\"b\",True}\ndiccionario = {'hola': \"mundo\", \"a\": \"b\",}\n\n\n#5 Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Jeisson-Castro.py",
    "content": "# Este es el sitio web oficial de Python : https://www.python.org/\n# Existen dos maneras para hacer comentarios en python:\n# Comentario de una linea\n# Y estas son comentarios con varias lineas:\n\"\"\" Hola soy Alvaro y estoy haciendo un comentario con \nmas de una linea, puedo seguir escribiendo pero no quiero, pero debido a este ejercicio\ntengo que seguir para demostrarles que aunque esto tambien sirve para declarar strings de varias lineas puede usarse como comentarios\nde varias lineas, tip final: esto se llama docstring\"\"\"\n\n# Creando una variable normal\nmi_variable = \"Hola soy una variable\"\nnumero = 50\nnumero_por_dos = 50 * 2\n# Creando una variable constante (Python no soporta el hecho de crear variables CONSTANTE pero se sigue una convencion para indicar que es una variable constante y no debe\n# modificarse convencionalmente utilizando las letras mayusculas y guiones bajos, esta convencion se llama SNAKE_CASE)\nVARIABLE_CONSTANTE = 20 # Esta variable debe seguir la convencion de no poder cambiarse\n\n# Creando variables representado todos los datos primitivos:\n\n# Numero entero (int)\nnumero_entero = 10 \n\n# Numero flotante (float)\nnumero_flotante = 20.8\n\n# Numero booleano (bool)\nvariable_booleana = True \n\n# Cadena de texto (str)\ncadena_de_texto = \"Hola, mundo\" \n\n# Imprime por la terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nprint(\"Hola, Python!\")\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/JesusAntonioEEscamilla.py",
    "content": "# #00 - Python -> Jesus Antonio Escamilla\n\n# Aquí es el sitio de Python => https://www.python.org/\n\n\n# Comentar una linea\n\n\n\"\"\"\nEsto es un comentario de varias lineas\nusando comillas triples. Aunque este formato\nes mas para documentar o de módulos o clases y\ny comentario largos\n\"\"\"\n\n\n'''\nTambién este es un\ncomentario de varias\nlineas con comillas \ntriples simples\n'''\n\n\nmi_variable = \"Python\"\nMI_CONSTANT = \"Python constante\"  # por convención\n\n\nintVariable = 42\nfloatVariable = 3.14159\nstrVariable = '¡¡Hola, Mundo!!'\nbooleanoVariable = True\n\n\nprint(f'Hola,{mi_variable}')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/JhonMarin12.py",
    "content": "# El sitio web oficial de python: https://www.python.org/\n\n# Esto es un comentario de una sla linea\n\n\"\"\"\nEsto es un\nComentario de\nMultiples\nLineas\n...\n\"\"\"\n\n# Creación de variables\n# En python definimos variables con el signo igual, que se conoce como operador de asignación, lo podemos leer tal que:\na = 12\n\n# Si bien python no tiene una forma de guardar constantes, se usa una convención de usar el nombre de la variable en mayusculas.\nCONSTANTE = 12\nGRAVEDAD = 9.8\n\n\n# Existe varios tipos da datos\n\n# Enteros (int)\nb = 12\nc = -12\n\n# Decimales (float)\nd = 21.5\ne = -90.89\n\n# Cadenas de texto (str)\nmystring = 'Hola como estas?'\nmystring_1 = \"Hola como estas?\"\ncharacter = 'a'\n\n# Booleanos (Bool)\nverdero = True\nfalso = False\n\n# Listas (list)\nmylist = [1, 2, '3', 'Cuatro']\n\n# Tuplas (Tuple)\nmytuple = (1, 2, 3)\n\n# Diccionarios (dict)\nmydict = {\"clave\": \"valor\"}\n\nprint(\"Hola, Python\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Jmofuture.py",
    "content": "# URL: https://staging.python.org/downloads/\n\n#Esto es un comentario\n\na = 0 #Comentario al lado del codigo\n\n\"\"\"\nEsto tambien es un comentario\n\"\"\"\n\n# Variables\n\nvariable = 0\nCONSTANTE = 0\n\n\n#Tipos de datos primitivos\n\n#Numericos\n\nentero = 1\nflotante = 2.5\n\n#Strings\n\ncadena = \"Hola Mundo!\"\n\n#Binarios\n\ndatos_binarios = b'\\xDE\\xAD\\xBE\\xEF'\n\n# Booleano\n\nverdadero = True\nfalso = False\n\nprint(\"Hola Mundo!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/JohannManrique.py",
    "content": "#https://www.python.org/\n\n#esto es un comentario\n\"\"\"\nesto tambien es un comentario \n\"\"\"\n'''\ny esta creo que es otra forma de hacer un comentario\n'''\n\na = \"esto es una variable\"\n\nCONSTANTES=\"creo que en este lenguaje no existen perce, pero se puede indicar creando la variable en mayusculas\"\n\ntexto= \"esto es una cadena de texto o string\"\nenteros= 1234\nbooleanos= True\nbooleanos2= False\ndecimales= 1.29\nA=\"¡Hola, Python!\"\nprint(A)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Johao23.py",
    "content": "# Esta es la página oficial de mi lenguaje preferido, Python: https://www.python.org/\n\n# Podemos comentar en una línea\n\"\"\"\nTambién podemos comentar\nen varias lineas,\nlas que queramos\n:)\n\"\"\"\n\naño = 2024 # Esto es una variable\n\n# Las variables pueden ser de tipo int, float, string, boolean, etc.\nedad = 24 # int\naltura = 1.82 # float\npython_es_facil = True # Boolean\nnombre = \"William\" # string\ntipos_variables = \"\"\"\n1. Intiger\n2. Float\n3. String\n4. Boolean\n\"\"\" # Esta variable también es un string\n\n\n# Las variables también pueden ser de tipo lista, tupla, diccionario, etc.\nmi_lista = [1, 2, 3, 4, 5] # lista\nmi_tupla = (1, 2, 3, 4, 5) # tupla\nmi_diccionario = {\"clave1\": \"valor1\", \"clave2\": \"valor2\"} # diccionario\n\nlenguaje_preferido = \"Python\" # Definimos una variable con el nombre de mi lenguaje de programación preferido\n\nprint(f\"¡Hola, {lenguaje_preferido}!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/JorDevOro.py",
    "content": "# www.python.org\n\n# Comentario en una linea\n\n\"\"\"\nEsto tambien es\nun comentario\nen varias lineas\n\"\"\"\n\n'''\nEsto tambien es\nun comentario\nen varias lineas\n'''\n\nmy_variable = \"Mi variable\"\nmy_variable = \"Nuevo valor de mi variable\"\n\nMY_CONSTANT = \"Mi constante\" # por convención\n\nmy_int = 1\nmy_float = 1.5\nmy_bool = True\nmy_bool = False\nmy_string = \"Mi candena de texto\"\nmy_other_string = 'Mi otra cadena de texto'\n\nprint(\"¡Hola, Python!\")\n\nprint(type(my_int))\nprint(type(my_float))\nprint(type(my_bool))\nprint(type(my_string))"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/JorgeGarcia-Dev.py",
    "content": "# Crea un comentario en el código y coloca la URL del sitio web oficial del\n# lenguaje de programación que has seleccionado.\n\n\n# https://www.python.org/\n\n\n# Representa las diferentes sintaxis que existen de crear comentarios\n# en el lenguaje (en una línea, varias...)\n\n\n# Comentatio en una línea\n\n\"\"\"\nComentario en varias lineas\n\"\"\"\n\n\"\"\"\nComentario en varias lineas\n\"\"\"\n\n\n# Crea una variable (y una constante si el lenguaje lo soporta).\n\nesta_es_una_variable = \"variable\"\nESTA_ES_UNA_CONSTANTE = 3.1416\n\n\n# Crea variables representando todos los tipos de datos primitivos\n# del lenguaje (cadenas de texto, enteros, booleanos...).\n\n\nnumero_entero = 1\nnumero_flotante = 1.0\ncadena_de_texto = \"texto\"\nbooleano_true_or_false = True\nnulo = None\n\n# Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/JorleGp.py",
    "content": "# https://www.python.org/\n\n# Comentario de una linea\n\n\"\"\" Comentario\nen varias\nlineas\"\"\" \n\n''' Otra forma de \ncomentar\nen varfias lineas '''\n\n# Creacion de variable\n\nmy_variable = \"Mi variable\" \nmy_variable =  \" Mi nueva variable\"\n\n# Creacion de una Constante\n\nMY_CONSTANT = \"Mi constante\"          # Si se escribe en mayuscula de entiende que es una constante, se usa a convención\nMY_CONSTANT = \"Constante\"\n\n# Datos primitivos\n\n\"\"\" int= Enteros ,float= decimales, bool= verdadero o falso\"\"\"\n\nmy_int = 30\n\nmy_float= 30.50\n\nmy_bool_true= \"Verdadero\"\n\nmy_bool_false= \" Falso\"\n\nmy_string= \"Mi cadena de texto\"\n\nmy_other_string = \"Mi ootra cadena de texto\"\n\n# Impresion\n\nprint(\"¡Hola Phyton!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Jose-Luis-Lanza.py",
    "content": "# https://www.python.org/\n\n# Esto es un comentario\n\n\"\"\"\nEsto es un comentario de varias lineas\n\"\"\"\n\n'''\nEsto tambien es un comentario de varias lineas\n'''\n\nmy_variable = \"Esto es una variable\"\n# No existen constantes en Python, pero por convención se escribe con MAYUSCULA para indicar que es una constante\nMASS = 50.5\n\nstring = \"Esto es un string\"\ninteger = 27\nfloat = 3.1416\nbool = True\nbool = False\n\nprint(\"¡Hola, Python\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/JoseAlberto13.py",
    "content": "\"\"\" * EJERCICIO:\r\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\r\n *   lenguaje de programación que has seleccionado.\r\n * - Representa las diferentes sintaxis que existen de crear comentarios\r\n *   en el lenguaje (en una línea, varias...).\r\n * - Crea una variable (y una constante si el lenguaje lo soporta).\r\n * - Crea variables representando todos los tipos de datos primitivos\r\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\r\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\r\n *\r\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\r\n * debemos comenzar por el principio.\r\n */ \"\"\"\r\n\r\n#Este es un comentario de una linea\r\n\"\"\"\r\nEsto es un comentrario de varia lineas\r\nSitio Oficial de Python\r\nhttps://www.python.org/\r\n\"\"\"\r\n#Variables y \"CONSTANTE\"\r\nes_variable = \"Es una Variable\"\r\nES_CONSTANTE = \"Esto es una Constante.\" #Las const se definen asi en py (Mayúsculas) para envitar que puedan modificar su contenido. (No hay conts en py)\r\n#Tipos de Datos Primitivos\r\nes_int = 13\r\nes_float = 2.1\r\nes_string = 'Podemos usar comillas simples'\r\nes_string2 = \"Y comillas dobles\"\r\nes_bool = True\r\nes_bool2 = False\r\nprint(\"Hola, Python\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/JoseFuentes-Dev.py",
    "content": "#https://www.python.org/\n\n\"\"\"\nEsto es un \ncomentario\nen varias lineas\nen python\n\"\"\"\nint = 1\nfloat = 1.5\nbool = True\nbool = False\ncadena_de_texto = \"esto es una cadena de texto\"\nlista = {1, 2 ,3 ,4 ,5 }\nnulo = None\nESTO_ES_CONSTANTE= 4 # contante\n\nprint(\"¡Hola desde python\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/JoseGago27.py",
    "content": "# www.python.org\n\n\"\"\" Se utiliza para \nhacer comentarios\nen varias lineas\n\"\"\"\n\n''' Tambien es utilizado para comentar\nen varias\nlineas'''\n\nvariable_1 = \"esto es una variable\"\n\nCONSTANT_1 = \"No hay constantes en Python, pero al utilizar mayusculas le estamos diciendo a otros programadores que es una constante por convencion\"\n\ntipo_int = 1\ntipo_float = 1.2\ntipo_boolean = True\ntipo_string = \"Esto es un string\"\n\nprint(\"!Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/JosephFaster.py",
    "content": "#Existen diversas maneras de poner comentarios en Python como los siguientes:\n\n#https://www.python.org/\n\n\"\"\"\nEsto tambien es \nun comentario\nde varias lineas de texto\n\"\"\"\n\n'''Tambien se pueden usar comidas simples\ny no pasa nada, no afecta al código'''\n\nmy_variable = 'Mi variable'\nmy_variable = 'Nuevo valor de mi variable'\n\n\"\"\"Python no tiene constantes\"\"\"\n\nMY_CONSTANT = 'Mi constante' #Por convención se utilizan las constantes en mayusculas y las variables con formato snake_case\nMY_CONSTANT = 'LE PUEDO CAMBIAR EL VALOR POR QUE NO HAY CONSTANTES'\n\n#Python tiene 4 tipo de datos primitivos\n#De esta manera se ve puede especificar que a esa variable solo se le pone el tipo de datos que le antepones en la etiqueta\nmy_int: int = 1\nmy_float: float = 2.3\nmy_boolean: bool = True\nmy_bool: bool = False\nmy_string: str = 'hola mundo'\n\nprint(my_string)\n\n\nprint(type(my_int))\nprint(type(my_float))\nprint(type(my_boolean))\nprint(type(my_string))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/JosmaroBH.py",
    "content": "#https://www.python.org/\n\n#Comentario de una Linea\n\n\"\"\"\nComentario en \nVarias \nLineas\n\"\"\"\n\n'''\nComentario en \nVarias \nLineas\n'''\n\nvariable = \"Esto es un Variable\"\n\nCONSTANTE = \"Esto es una Constante\" #Por convencion, no cambiar el valor\n\nvar_int = 16 #Valores enteros\nvar_float = 16.5 #Valores decimales\nvar_bool = True #Valores booleanos\nvar_bol = False #Valores booleanos\nvar_string = \"Cadena de texto\" #Valores cadena de texto\nvar_string2 = 'Otra cadena de texto' #Otra forma de poner cadena de texto\n\nprint(\"¡Hola, Pthon!\")\n\nprint(type(var_int))\nprint(type(var_float))\nprint(type(var_bol))\nprint(type(var_string))"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Josue-py.py",
    "content": "# https://www.python.org/\n\n# Con el numeral se escribe un comentario de una linea.\n\n\"\"\"\n\nCon tres comillas al principio,\ny al final de el texto se pueden crear,\ncomentarios con varias lineas\n\n\"\"\"\n\n\"\"\"Hasta donde se, en python no existen constantes,todas las variables\n      se pueden modificar,segun tengo entendido\"\"\"\n\n\nanimal = \"Perro\" # Esto es una variable.\nPI = 3.14 # Esto es una constante,su valor no puede variar mientras, la variable si\n\nnumber_int = 20\nnumber_float = 20.5\nboolean_data = number_int == number_float\nstring_data = \"Break the ice!\"\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/JosueLopez5.py",
    "content": "#https://www.python.org/\n\n#Esto es un comentario en una linea\n\n\"\"\"\nEsto es un cometario en un bloque utilizando comillas dobles\n\"\"\"\n\n'''\nEsto es un cometario en un bloque utilizando comillas simples\n'''\n\nmy_variable = \"Mi Variable\"\n\n#En Python no extinten las constantes, pero se pueden hacer por convencion\nMY_CONSTANT = \"Mi Constante\"\n\nmy_int = 10\nmy_float = 2.2\nmy_bool = True\nmy_bool = False\nmy_str = \"Cadena de Texto\"\n\nprint(\"¡Hola, Python!\")\n\nprint(type(my_int))\nprint(type(my_float))\nprint(type(my_bool))\nprint(type(my_str))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/JosuePerez004.py",
    "content": "# https://www.python.org\n\n# comentario en una linea \n\n\"\"\"\nvarias lineas con doble comilla triple\n\n\"\"\"\n'''\nY tambien triple comilla simple\n\n'''\nSuma = a + b # La suma de a y b dara un resultado\n\nnueva_variable = \"Mi variable\"\nnueva_variable = \"Gato\"\n\nMy_CONSTANT = \"Mi constante\" #por convencion\n\nmy_int = 1\nmy_float = 1.5\nmy_bool = True\nmy_bool = False\nmy_string = \"Mi primer cadena de texto\"\nmy_other_string = 'Mi otra cadena de texto'\n\nprint(\"Hola, Python\")\n\nprint(type(my_int))\nprint(type(my_float))\nprint(type(my_bool))\nprint(type(my_string))"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/JowelGod.py",
    "content": "# Sitio oficial de Python: https://www.python.org/\n\n# Comentarios\n# Esto es un comentario de una línea\n\n\"\"\"\nEste es un comentario\nde varias líneas\n\"\"\"\n''' \nEsto tambien es un \ncomentario de varias lineas\n'''\n\n# Variable normal\nlenguaje = \"Python\"\n\n# 📌 Constante por convención (pero no protegida)\nPI = 3.14159\n\n# 🧠 Tipos de datos primitivos\nentero = 42                   # int\ndecimal = 3.14                # float\nbooleano = True               # bool\ncaracter = 'A'                # string de un solo carácter\ncadena = \"Hola mundo\"         # str\nlista = [1, 2, 3]             # list\ntupla = (1, 2)                # tuple\ndiccionario = {\"a\": 1, \"b\": 2}# dict\nnulo = None                   # NoneType\n\n# Conversión de tipos (casting)\nnumero = \"10\"\nsuma = int(numero) + 5  # sin int() fallaría\n\n# Control de flujo\nif booleano:\n    print(\"El valor booleano es verdadero\")\n\n# Función\ndef saludar(nombre):\n    return f\"Hola, {nombre}!\"\n\n# Imprimir resultados\nprint(saludar(lenguaje))\nprint(f\"Valor de PI (constante): {PI}\")\nprint(f\"Suma convertida: {suma}\")\nprint(f\"Tipos: entero={type(entero)}, cadena={type(cadena)}, lista={type(lista)}\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/JuanAlbornoz32.py",
    "content": "# Página principal de Python: http://www.python.org\n\n#######TIPOS DE COMENTARIOS#######\n\n# Esta es la forma para hacer un comentario de una sola línea.\n\n\"\"\" \nLas comillas dobles nos sirven para escribir\ncomentarios de más de una línea.\n\n\"\"\"\n\n'''\nLas comillas simples tambien nos sirven para escribir\ncomentarios de más de una línea.\n\n'''\n\n#######TIPOS DE VARIABLES#######\n\n# Forma de declarar una variable en Python\nvariable = \"Python\"\n\n# En Python no existen las variables constantes propiamente tal, pero por convención se usan mayúsculas para representarlas.       \nVARIABLE_CONSTATE = \"Python\"\n\n#######TIPOS DE DATOS PRIMITIVOS#######\n\n# Números enteros (int)\nentero = 2\n\n# Números decimales (float)\ndecimal = 3.14159\n\n# Números complejos (complex)\ncomplejo = 3j + 1\n\n# Cadenas de texto (str)\ncadena = \"Python\"\n\n# Booleanos (bool)  \nbooleano = True\n\n# Valor nulo (None)\nnulo = None\n\n#######IMPRIMIENDO POR TERMINAL#######\n\nprint(\"¡Hola, Python!\")\n# Imprimiendo con f-strings\nprint(f\"¡Hola, {variable}!\")    \n# Imprimiendo con el metodo format()\nprint(\"¡Hola, {}!\".format(variable))\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/JuanD1Q94.py",
    "content": "# https://www.python.org/\n\n# Comentario en una linea\n\n\"\"\"\nEsto tambien es \nun comentatio \nen varias lines\n\"\"\"\n'''\nEsto tambien es \nun comentatio \nen varias lines\n'''\n\nmy_variable = \"Mi varuable\"\nmy_variable = \"Nuevo valor de mi variable\"\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Juanma0416.py",
    "content": "#1. \n\n# https://www.python.org/\n\n#2.\n\n# Comentario en una linea\n\n\n# Comentarios en varias lineas\n\"\"\"\nSe puede con\n3 comillas dobles\npara abrir y cerrar\n\"\"\"\n\n'''\nTambién se\npuede con \ncomillas simples\n'''\n\n#3.\n\n#Variables\nmy_variable = \"Mi variable\"\nmy_variable = \"Nuevo valor de mi variable\"\n\n#Constantes\nMY_CONSTANT = \"Mi constante\" # Por convención los constantes se escriben en mayúsculas para diferenciarlas de las variables y asi evitar que modifiquemos su valor accidentalmente.\n\n\n#4.\n\n#INTEGER\nmy_int: int = 26 # Indicamos el tipo de dato para evitar que se ingrese otro tipo de dato en la variable y evitar casos como este: \n# my_int = \"8\" -- Esto no debería ser posible si hemos indicado que my_int es de tipo entero.\n\n#FLOAT\nmy_float = 2.6\n\n#BOOLEAN\nmy_bool = True\nmy_bool = False\n\n#STRING\nmy_string = \"Mi cadena de texto\"\nmy_other_string = 'Mi otra cadena de texto'\n\n#5\n\nprint(\"¡Hola, python!\")\n\n\n#PLUS - DETERMINAR EL TIPO DE DATO QUE ESTAMOS REPRESENTANDO\n\nprint(type(my_int))\nprint(type(my_float))\nprint(type(my_bool))\nprint(type(my_string))"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Juanseevn.py",
    "content": "#COMENTARIO EN PYTHON\n\n#SITIO WEB OFICIAL DE PYTHON\n#URL = https://www.python.org\n\n#COMENTARIO DE UNA LINEA\n\n\"\"\"COMENTARIO\nDE\nVARIAS\nLINEAS\"\"\"\n\nPrimeraVariable = 0\nCONSTANTE = 123\n\ncadena_de_texto = \"Hola\"\nint = 1\nfloat = 15.4\nboolean = True\n\nprint(\"¡Hola, python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/JuitoMG.py",
    "content": "#   EJERCICIO:\n#  - Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n\n# https://www.python.org/\n\n\n#  - Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n\n# Comentario en una línea\n\n\"\"\"\nComentario\nen varias\nlíneas\n\"\"\"\n\n'''\nAlternativa\ncomentario \nen varias\nlíneas\n'''\n\n#  - Crea una variable (y una constante si el lenguaje lo soporta).\n\npajaro = \"loro\"\n\n# Python no admite constantes, aunque podemos indicarlas igualmente en el código de la siguiente manera\n\nMI_CONSTANTE = 10\nPI = 3.14\n\n#Como ejemplo, vamos a probar que es posible no solo cambiar el valor de la \"constante\", sino también su tipo.\n\nprint(type(MI_CONSTANTE)) #Tipo int\nprint(type(PI))  #Tipo float\n\nMI_CONSTANTE = MI_CONSTANTE + PI\n\nprint(MI_CONSTANTE)\nprint(type(MI_CONSTANTE))  #Nos devuelve que ahora esta \"constante\" pasó de ser tipo int a tipo float\n\n#  - Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n\nstring = \"Nombre\"\nentero = 33\nfloat = 3.56\nbooleano = True\n\n\n#  - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\nlenguaje = \"Python\"\nprint(f\"Hola, {lenguaje}!\")\nprint(\"Hola\",lenguaje,\"!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Julind0.py",
    "content": "#https://www.python.org/ #URL del sitio web en el cual estoy programando\n\n#Esto es un comentario de linea \n\n\"\"\"\n\nEsto es un comentario de bloque\n\n\"\"\"\n\nmy_variable = \"Variable de cadena de texto\"\nMY_CONSTANTE_ARTIFICIAL = \" KASMKASMASKA \"\n\nentero = 1 #variable int o entera\ndecimal = 20.34 #variable float o decimal \ntexto = \"holamundo\" #str o string variable de cadena de texto\nbooleano_o_bool = True #variable boolean solo admite False o True \n\nprint(\"!Hola, phyton¡\")\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/KateAmador.py",
    "content": "# Sitio web oficial del lenguaje de programación Python \n# https://www.python.org/\n\n# Comentario de una sola línea en Python se hace con el símbolo #\n\n\"\"\"Comentario multilínea\nusando tres comillas dobles.\n\"\"\"\n\n'''\nComentario multilínea \nusando tres comillas simples.\n'''\n\nmy_variable = \"Esta es una variable en Python\"\nMY_CONSTANT = \"Esta es una constante por convención en Python\"\n\n# Tipos de datos primitivos en Python\nstring_var = \"Esto es una cadena de texto\" # cadena de texto\ninteger_var = 30 # entero\nfloat_var = 1.72 # flotante\nboolean_var = True # booleano\ncomplex_var = 2 + 3j # número complejo\nchar_var = 'A'  # En Python no hay un tipo de dato específico para caracteres, se usan strings de longitud 1\n\n# Imprimiendo el nombre del lenguaje\nprint(\"¡Hola, Python!\")\n\n# Imprimir los tipos de datos\nprint(type(string_var))\nprint(type(integer_var))\nprint(type(float_var))\nprint(type(boolean_var))\nprint(type(complex_var))\nprint(type(char_var))"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Kcx46.py",
    "content": "#Este es el sitio oficial del programa#\n#https://www.python.org/\n#La sintaxis para crear un comentario es con el simbolo de numeral (#)\n'''\nO se pueden crear comentarios\nmultinlinea con tres comillas al inci\ny al final del comentario\n'''\n\nthis_is_a_variable = 1\nthere_is_no_constants_in_python = 2\nthis_is_a_string = \"Hello World\"\nthis_is_a_number = 3\nthis_is_also_a_number = 3.14\nthis_is_a_boolean = True\nthis_is_a_list = [1, 2, 3, \"Paco\", True, [\"Perro, Gato, Pajaro\"]]\nthis_is_also_a_list = list([1,2,3,4,5,6,7,8,9,10])\nthis_is_a_tuple = (1, 2, 3, 4, 5)\nthis_is_also_a_tuple = tuple((1, 2, 3, 4, 5))\nthis_is_a_set = {1,2,3,3,4,5,5}\nthis_is_also_a_set = set([1,2,3,4,5,6,7,8,9,10,10,10,10,10])\nthis_is_a_dict = {\"name\": \"Paco\", \"age\": 25, \"city\": \"CDMX\"}\nthis_is_also_a_dict = dict(name=\"Paco\", age=25, city=\"CDMX\")\n\nprint(\"***Hola Python***\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/KevinED11.py",
    "content": "# https://www.python.org/\n\n# single line comment\n\n\"\"\"\nmulti line comment\n\"\"\"\n\n\nname = \"Kevin\"  # variable\nPI = 3.14  # constant\n\n\n# primitive types\nage: int = 20\nname: str = \"Kevin\"\nis_ok: bool = True\npi: float = 3.14\n\n\n# print\nprint(\"Hola Python\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Lazar171717ech.py",
    "content": "# https://www.python.org/\n\n## 1. COMENTARIOS ##\n\n#Esto es un comentario en una línea.\n\n\"\"\"Esto, en cambio, es un comentario\nen varias líneas y no termina hasta que\nse cierran las tres comillas\"\"\"\n\n'''También se pueden escribir los\ncomentarios en varias lineas con comillas simples'''\n\n## 2. VARIABLE Y CONSTANTE ##\n\nvar = \"Hola!\"\nCONST = \"Adios!\"\n\n## 3. VARIABLES Y DATOS ##\n\nstr_var = \"Hello World!\"\n\nint_var = 11\n\nfloat_var = 11.5\n\nbool_var = False\n\ncomplex_var = 11j\n\ntype_var = type(11)\n\nNoneType_var = print()\n\n## 3. MENSAJE FINAL ##\n\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Lean993.py",
    "content": "# https://python.org\n\n# Esto es un comentario\n\n\"\"\"\nEsto es un comentario\nen varias líneas\n\"\"\"\n\n'''\nEsto también es \nun comentario\nen varias líneas\n'''\n\nmy_variable = \"Mi variable\"\nmy_variable = \"Mi nuevo valor de variable\"\n\nMY_CONSTANT = \"Mi constante\"  # por convención\n\nmy_int = 10\nmy_float = 1.50\nmy_bool = True\nmy_bool = False\nmy_string = \"Mi cadena de texto\"\nmy_other_string = 'Mi otra cadena de texto'\n\nprint(\"¡Hola, Python!\")\n\nprint(type(my_int))\nprint(type(my_float))\nprint(type(my_bool))\nprint(type(my_string))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Lemito66.py",
    "content": "# Documentación de python en comentario de una línea: https://docs.python.org/3/\n\n\"\"\"\nDocumentación de python en comentario de varias líneas:\nhttps://docs.python.org/3/ \n\"\"\"\n\n# Creación de una variable\nmy_first_variable = \"Hello World\"\n\n# Aunque en python no existen las constantes tiene una convención escribiendolo en mayúsculas\nMY_FIRST_CONSTANT = \"Hello World\"\n\nstring = \"Hello World\"\ninteger = 1\nboolean = True\nfloat = 1.5\nprogramming_language = \"Python\"\n\n# Concatenación de cadenas de texto\nprint('¡Hola, ' + programming_language + '!')\n# Otra forma\nprint(f'¡Hola, {programming_language}!')\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Lilitr09.py",
    "content": "# *********************************\n# * Nombre: Liliana Torres        *\n# * 2024 - Python                 *\n# *********************************\n\n# 1 - Crea un comentario en el código y coloca la URL del sitio web oficial del\n#     lenguaje de programación que has seleccionado.\n# Sitio oficial de Python: https://www.python.org\n\n\n# 2 - Representa las diferentes sintaxis que existen de crear comentarios\n#     en el lenguaje (en una línea, varias...).\n# Este es un comentario en una linea\n\n\"\"\"Este es\nun comentario \nde \nvarias lineas\n\"\"\"\n\n\n# 3 - Crea una variable (y una constante si el lenguaje lo soporta).\nmy_variable = \"This is a variable\"\n\nPLANCK_CONSTANT = 6.626\n\n\n# 4 - Crea variables representando todos los tipos de datos primitivos\n#     del lenguaje (cadenas de texto, enteros, booleanos...).\nmy_integer = 13\n\nmy_string = \"This is a string\"\n\nmy_float = 13.89\n\nmy_boolean = True\n\n\n\n# 5 - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nprint(\"Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Lio7master.py",
    "content": "'''\n  EJERCICIO 00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO:\n  - Crea un comentario en el código y coloca la URL del sitio web oficial del\n    lenguaje de programación que has seleccionado.\n  - Representa las diferentes sintaxis que existen de crear comentarios\n    en el lenguaje (en una línea, varias...).\n  - Crea una variable (y una constante si el lenguaje lo soporta).\n  - Crea variables representando todos los tipos de datos primitivos\n    del lenguaje (cadenas de texto, enteros, booleanos...).\n  - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n'''\n# Enlace a la página oficial de Python: https://www.python.org/\n\n# Este es un comentario de una línea -> La documentacion lo indica como el medio oficial en 2.1.3. Comments\n# Cita de la documentacion oficial de Python:\n# \"A comment starts with a hash character (#) that is not part of a string literal, and ends at the end of the physical line.\n#  A comment signifies the end of the logical line unless the implicit line joining rules are invoked. \n#  Comments are ignored by the syntax.\"\n\n\n#Los  string no son comentarios, pero se pueden usar como tal mientras no esten asignados a una variable se consideran comentarios.\n# Uso de strings como comentarios multilínea \n'''\n   En python se puede usar comillas simples o dobles para crear cadenas de texto.\n   En este caso se han utilizado comillas simples para crear un comentario multilínea.\n   Python no tiene un símbolo específico para comentarios multilínea, pero ignora las cadenas de texto\n   que no están asignadas a ninguna variable.\n'''\n\n\"\"\"\n   En python se puede usar comillas simples o dobles para crear cadenas de texto.\n   En este caso se han utilizado comillas dobles para crear un comentario multilínea.\n   Python no tiene un símbolo específico para comentarios multilínea, pero ignora las cadenas de texto\n   que no están asignadas a ninguna variable.\n\"\"\"\n# Uso de strings como comentarios de línea \n\" En python se puede usar comillas simples o dobles para crear cadenas de texto.\"\n\n'En python se puede usar comillas simples o dobles para crear cadenas de texto.'\n\n#Creación de variables\n# En python se recomienda usar snake_case para nombrar variables, aunque no es obligatorio.\n    #Los nombres de las varibles se diferencian incluso por el uso de mayúsculas y minúsculas.\n   \n\nmi_variable_1 = 2025 #Tipo int\nmi_variable_2 = 3.14 #Tipo float\nmi_variable_3 = True #Tipo bool\n\nmi_variable = \"Mexico\" #tipo str\nMi_variable = 'Cadena de caracteres, entre comillas simples' #Tipo str\nMi_Variable = \"Cadena de caracteres, entre comillas dobles\" #Tipo str\n    #Por convención, para nombrar constantes en Python, se escribe en mayúsculas.\nMI_CONSTANTE = \"hola mundo\" #Tipo str\n\nprint(MI_CONSTANTE) #Imprime el texto en la terminal"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Lioomx.py",
    "content": "# https://www.python.org/\n\n# Esto es un comentario de una sola línea\n\n''' \nEsto también es \nun comentario, pero\nen varias líneas\n'''\n\nfirst_variable = \"Primer variable\"\n\nMY_CONSTANT = \"Constante\" # En Python las constantes no existen, pero se pueden declarar en mayusculas.\n\nclass_int = 1 # type entero\nclass_float = 1.1 # type decimal\nclass_str = \"Hi\" # type texto \nclass_bool = True # or false (type booleano)\n\nprint(\"¡Hola, Python!\") # Imprime en consola\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/LisandroArnodo.py",
    "content": "# https://www.python.org/\n\n#Esto es un comentario de una linea\n\n\n\"\"\"\nEsto es tambien un \ncomentario de \nvarias lineas\n\"\"\"\n\n#Variables\nmy_variable = \"Mi variable\"\nmy_variable = \"Nuevo valor de mi variable\"\n\n#Las variables constantes no existen en Python pero se escriben en mayuscula por convesion\n\nMY_CONSTANT = \"Mi variable constante\"\n\n#Tipos primitivos de datos\nmy_int = 1\nmy_float = 1.5\nmy_boolean = True\nmy_boolean = False\nmy_string = \"Mi cadena de texto\"\nmy_other_tring = \"Mi otra cadena de texto\"\n\nprint (\"Mi primer Hola Mundo en Python\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/LittleMabbit.py",
    "content": "# https://www.python.org/\n\n# Con una almohadilla indicamos un comentario de una linea.\n'''\nDe esta forma, con comillas simples o dobles, tres en orden seguido, podemos indicar un comentario\nque puede llenar varias lineas.\n'''\n# * - Crea una variable (y una constante si el lenguaje lo soporta).\ngithub_name = 'LittleMabbit' # Variable 'github_name' asignado el valor de 'LittleMabbit'.\nCONSTANTE = 21 # A pesar de que el lenguaje no soporta constantes, se puede indicar entre la comunidad escribiendo en mayúsculas.\n\n# * - Crea variables representando todos los tipos de datos primitivos\n# del lenguaje (cadenas de texto, enteros, booleanos...).\n\nname = 'StringyThingy' # Valor tipo string, puede ser indicado con comillas dobles o simples.\nname = \"StringyThingyy\" # Valor tipo string, en este caso usando doble comilla.\nedad = 99 # Valor tipo integer.\nedad = 99.9 # Valor tipo float/decimal.\nedad = 99 + 4j # Valor tipo complex / complejo.\nboolean_is_true = True # Valor tipo booleano, verdadero (True) o un sí, por así decirlo.\nboolean_is_false = False # Valor tipo booleano, falso (False) o un no, por así decirlo.\nany_value = None # Valor tipo None o Null, donde literalmente no hay ningún valor dentro de la variable.\n\n# * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nlanguage = 'Python'\nprint(f'¡Hola, {language}!')\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/LizzyMaken.py",
    "content": "# 1. URL OFICIAL DE PYTHON\n\n# https://www.python.org/\n\n# 2. COMENTARIOS\n\n# Este comentario es de una línea.\n\n'''\nEste es,\npor convención,\nun comentario\nmultilínea.\n'''\n\n# 3. VARIABLES\n\nvariable1 = \"python\" # Variable.\n\nVARIABLE2 = \"Hola\" # Se escribe en mayúscula por convención. Pero se puede cambiar.\n\n# 4. TIPOS DE DATOS PRIMITIVOS\n\n# strings o cadenas de texto\ntexto = \"este es un texto\"\n\n# integers o enteros\nentero = 10\n\n# floats o números decimales\nflotante = 2.5\n\n# booleans\nis_code = True\n\n# 5. IMPRESIÓN POR TERMINAL\n\nprint(\"¡Hola, python!\")\nprint(\"¡\"+VARIABLE2+\", \"+variable1+\"!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/LordAguaKate.py",
    "content": "#Creacion de SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n\n#Sintaxis\n'''\nLa sintaxis es nada mas y nada menos que el lenguaje de programacion,\nque hace el conjunto de reglas que define las combinaciones de simbolos que\nse consideran declaraciones o expresiones validas en ese lenguaje.\n'''\n#Ejemplos\nx = 0\nprint(\"hola soy una sintaxis\")\nx < 0\n2 + 3\nnumeros = [0, 1, 2, 3, 4, 5]\n#Comentarios para una sola linea\n''' comentarios para multiples lineas'''\n\n\n#Varaibles\n'''\nLas variables son elementos de un lenguaje de programacion que tiene asignado un valor unico, \nel cual puede se puede asignar, manipular y reutilizar. Para crear una variable se necesita\nel nombre de la variable asignar un valor usando = y el valor en si.\n'''\n#Ejemplos\n#Variable normal\nnumero = 12\nnombre = \"LordAguaKate\"\nfrio = True\n#Variable con asignacion multiple\ncodigo = 9999\ncodigo2 = codigo\n'''\nNota: hay que tener en cuenta que en python las variables pueden tener cualquier longitud y\npueden consistir en letras mayusculas y minusculas (A-Z, a-z), digitos (0-9) y el caracter\nde subrayado(_)\n'''\n#Ejemplos\n_variable = \"Esto es correcto\"\nvAriable = \"Esto es correcto\"\nvariabel_2 = \"Esto es correcto\"\n\n# variable$ = \"Esto es incorrecto\"\n# 1variable = \"Esto es incorrecto\"\n\n\n#Tipos de datos\n'''\nLos tipos de datos vienen de la mano con el interprete, los tipos de datos que existen\nson : Integers(int), Floats (float), Strings (str), Booleanos (bool), Listas (list),\nTuplas (tuple), Diccionarios (dict), Conjuntos (set)\n'''\n#Ejemplo\n#Integers (int)  Números enteros, como 1, 2, 3, etc.\nintegers = 3\n#Floats (float)  Números con decimales, como 3.14 o -0.5.\nfloats = 9.99\n#Strings (str): Cadenas de texto, como “hola” o ‘adiós’.\nstrings = \"Con comilla doble\"\nstrings2 = 'Con comilla simple'\n#Booleanos (bool): Valores lógicos que pueden ser True o False.\nbooleanos = True\nbooleanos2 = False\n#Listas (list): Conjuntos ordenados y modificables de elementos, como [1, 2, 3] o [“a”, “b”, “c”].\nlistas = [\"Esto es\", \"una lista\", 10]\n#Tuplas (tuple): Conjuntos ordenados e inmutables de elementos, como (1, 2, 3) o (“a”, “b”, “c”).\ntuplas = (\"Esto es\", \"una tupla\", 10)\n#Diccionarios (dict): Colecciones no ordenadas de pares clave-valor, como {“nombre”: “Juan”, “edad”: 30}.\ndiccionario = {\n    \"nombre\": \"lordaguakate\",\n    \"GitHub\": \"LordAguaKate\",\n    \"Edad\": 24\n}\n#Conjuntos (set): Conjuntos no ordenados y sin elementos duplicados, como {1, 2, 3} o {“a”, “b”, “c”}.\nconjuntos = {1,2,3,\"Esto es un conjunto\"}\n\n\n#Hola mundo\nsaludo = \"Hola mundo\"\nsaludo2 = saludo\nprint(saludo)\nprint(saludo2)\nprint(\"Hola mundo\")\nprint('Hola mundo')\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/LucasRebuffo.py",
    "content": "\"\"\" /*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */ \"\"\"\n\n# https://www.python.org/\n\n# Comentario de una linea\n\"\"\" Docstring (varias lineas) \"\"\"\n\nvariable = 10\nCONSTANTE = \"Python\"  # Realmente no es una constante pero se pone en mayuscula para indicar que lo es\n\nnumero = 2\ncadena_texto = \"cadena\"\nvalor_booleano = True\nflotente = 1.2\n\nprint(f\"¡Hola, {CONSTANTE}!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/LuciaRF.py",
    "content": "\"\"\" \nSINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n \"\"\"\n\n#Python:  https://www.python.org/\n\n#Crear una variable y una constante\nindice = 4\nPI = 3.1416 \nnumero_int = 2\nnumero_float = 3.2\nnumero_compplejo = 3 + 4j\n\ncadena_1 = \"Hola mundo 1\"\ncadena_2 = \"Hola mundo 2\"\n\nbool_true = True\n\nsin_valor = None\n\nprint(\"Hola, python\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/LuisCalle17.py",
    "content": "\"\"\"\n=====================================================================================\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n=====================================================================================\n\"\"\"\n\n# https://www.python.org/\n\n# comentario una sola linea = #\n# comentario en multiples lineas = \"\"\" \"\"\"\n\nmi_variable = \"Esto es una variable\"\nMI_CONSTANTE = \"Esto es una constante\"\n\ncadena_texto = \"Mi cadena de texto\"\nentero = 1\nflotante = 10.5\nbooleano = True or False\n\nprint(\"Hola Python\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/LuisK0706.py",
    "content": "# URL lenguaje de programacion https://www.python.org\n\n# Comentario de una linea\n\n\"\"\"\ntres comillas simples o dobles para un\ncomentario de varios lineas\n\"\"\"\n\n\nhola_mundo = 'Hola mundo'  # Variable\ncadena = 'Proyecto #00'  # Cadena de texto \nentero = 10  # Entero \nflotante = 4.5  # Flotante \nbooleano = False  # Booleano \nnulo = None  # Nulo\n\nprint('¡Hola, Python!')\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/LuisOlivaresJ.py",
    "content": "\"\"\"\n* EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\n \"\"\"\n\n# https://www.python.org/\n\n # Este es un comentario.\n\n\"Este es un segundo comentario en una línea.\"\n\n\"\"\"\nEste es un tercer\ncomentario en\ntres líneas.\n\"\"\"\n\nvariable = 0  # Ejemplo de una variable.\n\nPI = 3.14159  # Esta es una constante.\nprint(type(PI))\n\nint_var = 1   # Una variable int\nprint(type(int_var))\n\nfloat_var = 3.14  # Una variable float\nprint(type(float_var))\n\ncomplex_var  = 3+2j  # A complex variable\nprint(type(complex_var))\n\nstring_var = \"Hola mundo.\"\nprint(type(string_var))\n\nbool_var = True\nprint(type(bool_var))\n\nprint(\"Hola, python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Lumanet.py",
    "content": "# Python: https://www.python.org/\n\n# Comentario en una línea\n\n\"\"\"\nComentario\nde varias\nlíneas\n\"\"\"\n\n'''\nComentario \nde varias\nlíneas también\n'''\n\nvariable = \"Valor de la variable\"\n\nCONSTANTE = \"Valor de la constante\"\n\ncadena = \"Cadena de texto\"\nentero = 7\nbooleano = True\nfloat = 7.77\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/LuxIlith.py",
    "content": "# https://www.python.org\n\n\n# Este es un comentario en una sola linea\n\n\n\"\"\"\nEsto es un comentario\nen varias lineas\n\"\"\"\n\n\n'''\nEsta es otra sintaxis\nque te permite comentar\nen varias lineas\n'''\n\n\nvariable_string = \"Hello Python!\"                   # Variable de tipo string\n\nvariable_string2 = 'Hello Python!'                  # Variable de tipo string - second option\n\nvariable_int = 22                                   # Variable de tipo int\n\nvariable_float = 2.1                                # Variable de tipo float\n\nvariable_bool = True                                # Variable de tipo bool (True or False)\n\nvariable_list = [1, 2, 3, 4, 5]                     # Variable de tipo list\n\nvariable_dict = {\"Texto1\": \"Texto2\", \"Texto3\": 25}  # Variable de tipo dict\n\nVARIABLE_CONSTANT = \"Hello Python!\"                 # Variable de tipo constant\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Maanghel.py",
    "content": "\"\"\"\nEJERCICIO:\n- Crea un comentario en el código y coloca la URL del sitio web oficial del\n    lenguaje de programación que has seleccionado.\n- Representa las diferentes sintaxis que existen de crear comentarios\n    en el lenguaje (en una línea, varias...).\n- Crea una variable (y una constante si el lenguaje lo soporta).\n- Crea variables representando todos los tipos de datos primitivos\n    del lenguaje (cadenas de texto, enteros, booleanos...).\n- Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\ndebemos comenzar por el principio.\n\"\"\"\n\n# https://www.python.org/\n\n# Comentario de una linea\n\n\"\"\"\nComentario de varias \nlineas usando comillas dobles\n\"\"\"\n\n'''\nComentario de varias\nlineas usando comillas simples\n'''\n\n# Declaracion de variables en Python\nmi_variable = \"creacion de una variable de tipo string\" # str\n\n# No hay un tipo de dato para constantes en Python, pero se pueden simular declarando una variable en mayúsculas\nMI_CONSTANTE = \"por convencion\"\n\n# Declaracion de variables con cada tipo de dato primitivo\nvariable_tipo_string = \"Hola, Python\" # str\nvariable_tipo_int = 1 # int\nvariable_tipo_float = 2.5 # float\nvariable_tipo_bool = True # bool\n\nprint(\"¡Hola, Python!\") # Impresion de una linea de texto en consola"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/MagicDev-Rc.py",
    "content": "# website del LP: https://www.python.org/\n\n# comentario de una linea\n\n\"\"\"\nHola soy Edwin Reyes, y esté es un\ncomentario de varias lineas, usando\ncomillas dobles. \n\"\"\"\n\n'''\ncomentario de varias lineas, usando\ncomillas simples.\n'''\n\n# variable\nmy_name = \"Edwin Reyes\"\n\n# constante\nmy_const = \"CONSTANTE\"\nmy_const = \"CAMBIO DE CONSTANTE\"\n\n# CONCLUSION: EN PYTHON NO EXISTEN LAS \n# CONSTANTES\n\n# Tipos de datos primitivos\nentero = 1996\ndecimal = 16.5\nstring = \"Python\"\ncaracter = 'A'\nbooleano = True\ncadena_texto = \"Logica de Programacion\"\n\n# Imprimiendo \nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/ManuelD95.py",
    "content": "# *********************************\n# * Nombre: Manuel Delgado        *\n# * 2025 - Python                 *\n# *********************************\n\n# Crea un comentario y coloca la URL del sitio web oficial del\n# Lenguaje de programnacion seleccionado\n\n#1 https://www.python.org/\n\n#2 Comentario de una linea \n\n#3 Este es un comentario\n#Entre varias lineas\n#Recomendado maximo 72 caracteres\n#Para mantener un codigo limpio\n\n#3 Crea una variable\n\nmy_variable = \"Lenguaje limpio\" #Primer valor de la variable\nmy_variable = \"Lenguaje ordenado\" #Nuevo valor de la variable principal\nprint (my_variable)\n\n#4 Crea una constante\n\nMY_CONSTANTE = \"Valor fijo\"\nprint(MY_CONSTANTE)\n\n#5 Crear variables de diferentes tipos primitivos\n\nBloques = 50 # Entero (int)\nPi = 3.1416 # Flotantes (float)\nNombre = \"Manuel\" # Cadenas de texto (str)\nApellido = \"Delgado\" # Otra cadena de texto\nLa_Casa = True # Valores logicos (bool)\nEs_Amarilla = False\n\n#6 imprime  por terminal el texto \"Hola Python\"\n\nprint(\"¡Hola, Python!\")\n\nprint(type(Bloques))\nprint(type(Pi))\nprint(type(Nombre))\nprint(type(Apellido))\nprint(type(La_Casa))\nprint(type(Es_Amarilla))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/ManuelDenisDev.py",
    "content": "# Sitio web oficial de la documentación de Python: https://docs.python.org/3/\n\n# Esto es un comentario de una sola línea\n\n\"\"\"\nEsto es un\ncomentario de\nvarias líneas\n\"\"\"\n\n'''\nEsto tambien\nes un comentario\nde varias líneas\n'''\n# Variables en Python (No se necesita declarar el tipo de dato)\nmi_variable = \"Hola Mundo\" # String (str)\nmi_variable = \"Hola Mundo modificado\" # String (str)\n\n# Python no contiene constantes, pero se puede simular con variables en mayúsculas\nMI_CONSTANTE = \"Soy una constante\" # Por convención, las constantes se escriben en mayúsculas\n\n# Tipos de datos primitivos en Python\nmi_entero = 10 # Entero (int)\nmi_decimal = 10.5 # Decimal (float)\nmi_booleano = True # Booleano (bool)\nmi_booleano = False # Booleano (bool)\nmi_string = \"Hola Mundo\" # String (str)\n\n# Imprimir en consola\nprint(\"Hola Python\")\n\nprint(type(mi_entero)) # <class 'int'>\nprint(type(mi_decimal)) # <class 'float'>\nprint(type(mi_booleano)) # <class 'bool'>\nprint(type(mi_string)) # <class 'str'>\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/ManuelRTL.py",
    "content": "\"\"\"Crea un comentario en el código y coloca la URL del sitio web oficial del\nlenguaje de programación que has seleccionado\"\"\"\n\n#1.https://www.python.org/\n\n\"\"\"Representa las diferentes sintaxis que existen de crear comentarios\nen el lenguaje (en una línea, varias...).\"\"\"\n\n#Primero comentario\n\n\"\"\"Segundo comentario\"\"\"\n\n\"\"\"Crea una variable (y una constante si el lenguaje lo soporta).\"\"\"\n\nvariable1 = 1\nCONSTAN_DOS= 45\n\n\"\"\"Crea variables representando todos los tipos de datos primitivos\ndel lenguaje (cadenas de texto, enteros, booleanos...).\"\"\"\n\nnumber= 10\nfloat_number=10.5\nstring_letter=\"Hola amigo mío\"\nstring_dos='Hola Manuel'\nboolean=True\nboolean_dos=False\n\n\nprint(\"Hola el lenguaje es Python\")\n\nlenguaje='Python'\nprint('Hola el lenguaje es ' + lenguaje)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Manuu42.py",
    "content": "\n# https://www.python.org\n\n#varias lineas\n#de comentarios\n\"\"\"\ncomentario\nde varias\nlineas\n\"\"\"\n\n'''\n1. Operadores Aritméticos:\n    + Suma\n    - Resta\n    * Multiplicación\n    / División\n    // División entera\n    % Módulo (resto de la división)\n    ** Potenciación\n'''\nnumero1 = 20\nnumero2 = 30\n\nprint(\"Suma\", numero1 + numero2)        # 50\nprint(\"Resta\", numero1 - numero2)       # -10\nprint(\"Multiplicación\", numero1 * numero2)  # 600\nprint(\"División\", numero1 / numero2)    # 0.6666666666666666\nprint(\"División entera\", numero1 // numero2)  # 0\nprint(\"Módulo\", numero1 % numero2)     # 20\nprint(\"Potenciación\", numero1 ** numero2)  # 107374182400\n\n# Operadores de comparación ( >, <, ==, >=, <=, !=, ) -> devuelve un valor booleano\n# Estructuras de control (if, elif, else), condicionales\n'''\n\n2. Operadores de Comparación:\n    == Igual a\n    != Diferente de\n    < Menor que\n    > Mayor que\n    <= Menor o igual que\n    >= Mayor o igual que\n'''\nif numero1 == numero2:\n    print(\"Los números son iguales\")\nelif numero1 != numero2:\n    print(\"Los números son diferentes\")\n    if numero1 < numero2:\n        print(f\"El numero {numero1} es menor que {numero2}\")\n    elif numero1 > numero2:\n        print(f\"El numero {numero1} es mayor que {numero2}\")    \nif numero1 <= numero2 or numero1 >= numero2:\n    if numero1 <= numero2:\n        print(f\"El numero {numero1} es menor o igual que {numero2}\")\n    elif numero1 >= numero2:\n        print(f\"El numero {numero1} es mayor o igual que {numero2}\")\n\n# Operadores lógicos (para trabajar con valores de tipo bool) -> AND, OR, NOT\n'''\n\n3. Operadores Lógicos:\n    and = Y\n    or  = O\n    not = Negación\n'''\nprint(True and True)        # devuelve True\nprint(True and False)       # devuelve False\nprint(True or False)        # devuelve True\nprint(False or True)        # devuelve True\nprint(not True)             # devuelve False\nprint(not False)            # devuelve True\n\n'''\n4. Operadores de Asignación:\n    = Asignación\n    += Suma y asignación\n    -= Resta y asignación\n    *= Multiplicación y asignación\n    /= División y asignación\n    //= División entera y asignación\n    %= Módulo y asignación\n    **= Potenciación y asignación\n'''\nnumero_uno = 10\nnumero_dos = 20\n\nnumero_uno -= numero_dos\nprint(numero_uno)\nnumero_uno *= numero_dos\nprint(numero_uno)\nnumero_uno /= numero_dos\nprint(numero_uno)\nnumero_uno //= numero_dos\nprint(numero_uno)\nnumero_uno %= numero_dos\nprint(numero_uno)\nnumero_uno **= numero_dos\nprint (numero_uno)\n\n\n'''\n5. Operadores de Identidad:\n    is     - Es el mismo objeto\n    is not - No es el mismo objeto\n'''\na = 1\nb = 2\nc = 2\n\na is b # False\nb is c # True\nb is not c # False\na is not c # True\n\n\n'''\n6. Operadores de Pertenencia:\n    in      = (...Está en)\n    not in  = (...No está en)\n'''\nlista = [1, 2, 3, 4, 5, 12]\nprint(9 in lista) # False\nprint(9 not in lista) # True\nprint(12 in lista) # True\nprint(12 not in lista) # False\n\n\n# For para la iteración en listas y tuplas\n\ntupla = (\"Colombia\", \"Perú\", \"México\", \"Argentina\", \"Chile\")\nfor i in tupla:\n    print(i)\n\n\n''' DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.'''\n\nfor i in range (10, 56):\n    if i % 2 == 0 and i != 16 and i % 3 != 0: #Si el residuo de la division entre 2 es 0 y entre 3 es diferente 0 \n        print(i)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/MarcosE-FerretoE.py",
    "content": "# https://www.python.org/\n\n# Esto es una linea de comentario\n\n\"\"\" Esto es un bloque\nde comentario \"\"\"\n\n''' Esto es un bloque\nde comentario '''\n\nmi_variable = 'Mi variable'\nMI_CONSTANTE = 'Mi constante'\n\nmi_cadena = 'Mi cadena'\nmi_entero = 343\nmi_decimal = 3.14169\nmi_booleano = True\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/MarkTwin25.py",
    "content": "# Comentarios!\r\n\r\n# Comentario una linea \r\n\r\n\"\"\"\r\nComentario\r\nde\r\nvarias\r\nlineas\r\n\"\"\"\r\n\r\n# Variable\r\nvar = \"OLIWIS\"\r\n\r\n# Constante\r\nPI = 3.1416\r\n\r\n# tipos de datos\r\nentero = 8\r\ncadena = \"Hola\"\r\nflotante = 3.5\r\nbooleano = True\r\n\r\nprint(\"Hola, python!!!! SIUUUUUUU\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/MartaProg.py",
    "content": "#https://python.org\n\n#Comentario en una línea. \n\n\"\"\"\nComentario en dos \nlíeas, \no más.\n\"\"\"\n\n'''\nOtro comentario\nen dos líneas \no más.\n'''\n\nvariabe = \"Esto es una variable\"\nCONSTANTE = \"Esto es una constante por convención\"\n\nint = 3\nfloat = 3.4\nstr = \"Esto es una cadena\"\nbool = True\nbool = False\nnone = None\n\n\nprint(\"Hola Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/MartinZeta.py",
    "content": "\"\"\"\n# #00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n> #### Dificultad: Fácil | Publicación: 26/12/23 | Corrección: 02/01/24\n\n## Ejercicio\n\n```\n/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n\"\"\"\n\n#  https://www.python.org/\n\n# Comentario en una sola linea\n\n\"\"\"\nComentario \nen \nvarias \nlineas\n\n\"\"\"\n\n'''\nOtra forma de hacer \ncomentarios en multiples \nlineas\n\n'''\n\nmy_variable = \"Mi variable\"\n\n\nMY_CONSTANT = \"Mi constante\" # por convencion\n\n# Datos primitivos\nmy_int = 1\nmy_float = 1.5\nmy_bool = True\nmy_bool = False\nmy_string = 'Mi cadena de texto'\n\n# Imprimir\nprint(\"¡Hola, Python!\")\n\n# Tipos \nprint(type(my_string))\nprint(type(my_int))\nprint(type(my_float))\nprint(type(my_bool))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Masenace.py",
    "content": " * EJERCICIO:\n * - 1. Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - 2. Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - 3. Crea una variable (y una constante si el lenguaje lo soporta).\n * - 4. Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - 5. Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n \"\"\"\n #1 este es solo un comentario\n \n #3\nmi_variable = \"variable constante\"\nMI_VARIABLE = \"No debe cambiar\"\n \n #4\ndato_string = \"Python\"\ndato_entero = 24\ndato_float = 24.5\ndato_booleano = True\n \n #5\nprint(f\"hola {dato_string}\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Matc-Channel.py",
    "content": "# www.python.org\n\n# comentario en una linea\n\n\"\"\"\nEsto es un comentario\nen varias\nlíneas\n\"\"\"\n\n'''\ncomentario\nen\nvarias líneas\n'''\n\nmy_variable = \"Mi variable\"\nmy_variable = \"Nuevo valor a la variable\"\n\n# constantes\nMY_CONSTANT = \"Mi constante\"    # por conveniencia\n\n\n# 4 tipos de datos primitivos\nmy_int = 3\nmy_float = 2.21\nmy_bool = False\nmy_bool2 = True\nmy_str = 'Esto es una cadena str'\nother_str = \"Mi otra cadena de texto\"\n\n\nprint(\"Hola, Python!\")\n\n# Saber tipo de DATO\nprint(type(my_int))\nprint(type(my_float))\nprint(type(my_bool))\nprint(type(my_bool2))\nprint(type(my_str))\nprint(type(other_str))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/MercedesDF.py",
    "content": "#EJERCICIO 00:\n\n#https://www.python.org/\n\n# 1.  Comentario en una linea.\n\n''' 2. Para \npárrafos I\n'''\n\n\"\"\" 3. Para \npárrafos II\n\"\"\"\n\nCONSTANTE = \"CARPE DIEM\"\n\ncarpe_diem = \"Hola mundo. Ahora es el momento de aprovechar todas las oportunidades que nos ofrece Retos de Programación.\"\n\nedad = 16  # Un número entero, como la edad de una persona\n\naltura = 1.75  # La altura de una persona en metros\n\nmensaje = \"¡Bienvenidos a los Retos de ^rogramación!\"  # Un mensaje de bienvenida\n\ntarea_terminada = False  # Indica si la tarea ha sido completada\n\nnota_final = None  # Aún no se ha calculado la nota final\n\nprint(\"¡Hola, Python\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Migue1lll.py",
    "content": "#  https://www.python.org\n\n# comentario en una linea \n\n\"\"\"\n\nesto seria\nun comentario en \nvarias lineas \n\"\"\"\n#VARIABLES\n\nmy_varialble  =  \"mi variable 1 SE PUEDE ESCRIBIR UNA VARIABLE CON COMENTARIO EN LINEA\"\nMy_variable  =  \"mi nuevo valor de mi variable 2\"\n\n#no existen constantes en python, puede variar pero se puede representar por convencion\n\nMY_CONSTANT  =  \"ESTO SERIA UNA CONSTANTE, NO TIENE QUE CAMBIAR\" #por comvencion aunque puede variar\nMY_CONSTANTE  =  \"PROBANDO AL AZAR SOLO ASI JAJA\"\n\nmy_int  =  1 #acepta numero entero aunque no tenga comillas\nmy_float  =  3.5 # para decimales \nmy_bool  =  true #los bool pueden ser verdadero o falso escrito, true o false\nmy_bool  =  false\nmy_string  =  \"se puede usar comilla para texto\"\n\n\nprint(\"hola, python\")   \n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/MiguelAngel861.py",
    "content": "#https://wiki.python.org\n\n#Comentario 1\n\n\"\"\"\n\nComentario 2\n\n\"\"\"\n\n'''\n\nComentario 3\n\n'''\n\nVariable_1 = \"Esto es una Variable\"\nConstante_1 = \"Esto es una Constante\"\n\n\n# Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...)\n\nString = \"Hola Mundo\"\nIntegers = 12\nFloat = 12.5\nBoolean_1 = False\nBoolean_2 = True\nNon = None\n\n#Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\nprint(\"Hello, Python!\")\n\nprint(type(String))\nprint(type(Integers))\nprint(type(Float))\nprint(type(Boolean_1))\nprint(type(Boolean_2))\nprint(type(Non))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/MiguelMancebo.py",
    "content": "# https://www.python.org/\n\n\"\"\" Asi son los comentarios en python \"\"\"\n\nmy_variable = 'mi variable'\nmy_variable = \"mi variable\"\n\nMY_CONSTANT = 1\nMY_CONSTANT = 2\n\nMY_INT = 1\nMY_STR = \"JUAN\"\nMY_FLOAT = 1.2\nmy_bool = true\n\nprint(\"hola, Python\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Miguelberrio0810.py",
    "content": "# Comentario de una linea\n\n\"\"\"\nComentario de multiples lineas, con dobles comillas\n\n\"\"\"\n'''\nComentario de multiples lineas, con comillas simples\n'''\n\nMy_name = \"Miguel Angel\"\nMy_int = 1\nMy_float = 2.35\nMy_boolf = False\nMy_boolt = True\nMy_list = [\"Azul\", \"Rojo\", \"Amarillo\"]\nMy_dict = {'name' : 'Miguel', 'Age' : 23}\nMy_bites = b\"Miguel\"\nMy_complex = 1j\nMY_CONSONANT = \"Hello\"\n\nprint(\"¡Hola, Python!\")\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/MirandaYuber.py",
    "content": "# https://www.python.org/\n\n# Comentario de una sola linea\n\n\"\"\"\nComentario de varias\nlineas\n\"\"\"\n\n# Ejemplo de una variable\nmi_variable = 'Python'\n\n# Ejemplo de una constante\nMI_CONSTANTE = 1\n\n# Variables con los diferentes tipos de datos\ntexto = 'Hola Mundo'\nentero = 1\nflotante = 1.2\nbooleano = False\n\nprint(f'Hola, {mi_variable}')\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/MizadloGcia.py",
    "content": "# https://www.python.org/\n\n# One line comment\n\n\"\"\"\nThis is a\nmulti-line\ncomment\n\"\"\"\n\n'''\nThis is\nalso a\nmulti-line comment\n'''\n\nmy_var = \"My variable\"\n\nPI_CONST = 3.1416\n\nyear_of_birth = 1991\nheight = 1.70\nis_programmer = True\nfirst_name = \"Mizadlo\"\nlast_name = 'Garcia'\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Monikgbar.py",
    "content": "# www.python.org\n\n# Las almohadillas crean comentarios de una sola línea\n\n'''Con las triples comillas simples \npodemos hacer un \ncomentario multilínea'''\n\n\"\"\"Con las triples comillas dobles \ntambién haremos un\ncomentario multilínea\"\"\"\n\nmi_variable = \"Esto es una variable\" \n\n# String\ntexto = \"Hola mundo\"\n\n# Integer\nnumero = 12\n\n# Float\ndecimal = 3.14\n\n# Complex\nnum_complejo = 5 + 4j\n\n# Booleano\nbool_1 = True\nbool_2 = False\n\nprint(\"Hola, Python\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Mstaz4.py",
    "content": "\n# EJERCICIO #00:\n\n# 1- Crea un comentario en el código y coloca la URL del sitio web oficial dellenguaje de programación que has seleccionado.\n# https://www.python.org\n\n\n# 2- Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n\n# Se usa un numeral para los comentarios de una línea\n\"\"\"\n  Se usan tres comillas dobles o simples para comentarios de varias líneas\n\"\"\"\n\n# 3- Crea una variable (y una constante si el lenguaje lo soporta).\n\nvariable = \"Esta es una variable\"\nCONSTANTE = \"No existen las variables en Python. Por convención se identifican con mayúsculas las variables cuyo valor debe mantenerse constante\"\n\n# 4- Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\nentero = 1\nflotante = 2.3\ncomplejo = 4j\n\ncaracter = \"a\"\ncadena = \"cadena\"\n\nbooleano = True\n\nlista = [1, 2, 3, 5]\ntupla = (1, 2, 3, 4, 5)\nconjunto = {1, 2, 3, 4, 5}\ndiccionario = {\"alfredo\": \"esperanza\"}\n\n# 5- Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/MyloRobot2024.py",
    "content": "# Hola, aqui estan las soluciones del primer ejercicio\n\n\n# Comentario en una sola linea con Python\n# https://www.python.org/ \n\n'''\n\n'''"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Nach012.py",
    "content": "# https://python.org\n\n# Comentario en una linea\n\n\"\"\"\nPara realizar un comentario\nen varias\nlineas, debo iniciar y finalizar\ncon 3 comillas\n\"\"\"\n\n'''\nPara realizar un comentario\nen varias\nlineas, debo iniciar y finalizar\ncon 3 comillas\n'''\n\nmy_variable =  \"Mi variable\"\nmy_variable =  \"Nuevo valor de mi variable\"\n\nmy_int = 1\nmy_flot = 1.5\nmy_bool = true\nmy_bool = false\nmy_string = \"Mi cadena de texto\"\nmy_other_string = 'Mi cadena de texto'\n\nprint(\"¡Hola, Phyton!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/NatanaeLZubiri.py",
    "content": "#* EJERCICIO:\n# - Crea un comentario en el código y coloca la URL del sitio web oficial del\n#    lenguaje de programación que has seleccionado.\n# - Representa las diferentes sintaxis que existen de crear comentarios\n#    en el lenguaje (en una línea, varias...).\n# - Crea una variable (y una constante si el lenguaje lo soporta).\n# - Crea variables representando todos los tipos de datos primitivos\n#    del lenguaje (cadenas de texto, enteros, booleanos...).\n# - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\n#Link: https://www.python.org\n\n#Esto es un comentario de una sola linea\n\n#esta de multiples\n#lineas de\n#comentado\n\n\"\"\"\nEste es un comentario de múltiples líneas\nutilizando un docstring. Puede abarcar\nvarias líneas. no es un comentario en si, pero se puede usar\n\"\"\"\n\n#Creando una variable\n\nmi_variable = \"holis\"\n\n#Python no soporta Constantes, pero por convención se hace asi:\n\nMI_CONSTANTE = \"soy una constante, o no...\"\n\n#Tipos de Datos Primitivos\n\n#Cadena de texto\nmi_str = \"string\"\n\n#Enteros\nmi_entero = 10\n\n#Flotantes\nmi_flotante = 10.5\n\n#Booleanos\nmi_booleano1 = True\nmi_boooleano2 = False\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/NeftalyR.py",
    "content": "#PAGINA WEB OFICIAL\n#https://www.python.org/\n\n#COMENTARIOS\n# -> una sola almuadilla es un comentario de una línea\n\"\"\"\n    Las tres comillas al abrir y cerrar\n    se puede poner comentarios\n    multilíneas\n\"\"\"\n\n#VARIABLES -> la variable no tiene un tipo definido, toma el tipo del valor que declares\nvariable = 20.2\n\n#DATOS PRIMITIVOS\n# String\ntexto = \"hola\"\n# Int\nnumero = 2\n# Decimal\ndecimal = 2.2\n# Tupla\ntupla = (2, 3, \"ds\")\n# Lista\nlista = [29, 30, \"ad\"]\n# Diccionario\ndiccionario = {\"Nombre\": \"Bryan\", \"Apellidos\": \"Guevara Ascoy\"}\n# Booleano\nbooleano = True\n\n#IMPRIMIR\nprint(\"Hola, Python\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/NeosV.py",
    "content": "#https://www.python.org\n\n#comentario de linea\n\n'comentario en lineas'\n\n\"otra forma de comentar\"\n\nvariable = \"una variable\"\n\nCONSTANTE = \"Constante ya que python no las maneja literalmente\"\n\nprint (type(\"Andres\"))\nprint (type(10))\nprint (type(3.14))\nprint (type(1+1j))\nprint (type(True))\nprint (type ([1,2,3,4]))\nprint (type({'name':'andres', 'age':22, 'casado': False}))\nprint (type((1,2)))\nprint (type(zip([1,2],[3,4])))\n\nprint (\"Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/NesHurtado.py",
    "content": "#https://www.python.org/\n\n#comentario es un codigo que no se ejecuta para esto se usa numeral\n\n\"\"\"\nComentarios en\nvarias\nlineas\n\"\"\"\n\n´´´\nOtra forma\nde dejar\ncomentarios\n´´´\n#las variables son datos que pueden seguir mutando\n#lo siguiente son variables\n\nmy_name : \"Nestor Hurtado\"\nmy_nick : \"Ness\"\n\n#py no tiene constantes todo son variables pero si queremos representar una se usa mayusculas\n\nMY_BIKE : \"Honda Navi\" #por convension\n\n#tipos de datos primitivos\n\nmy_int : 7\nmy_string : \"cadena de texto\"\nmy_fload : 3.14\nmy_bool : True\nmy_bool: False\n\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Neusier101.py",
    "content": "# https://www.python.org/\n\n# Comentario en una línea\n\n\"\"\" Comentario en \nvarias líneas \"\"\"\n\nvariable = 5\n\nCONSTANTE = 4\n\nvar_int = 3\nvar_float = 6.5\nvar_string = \"variable\"\nvar_boolean = True\n\nprint(\"Hola, Python\")\n\n    \n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Neyan52.py",
    "content": "# https://python.org\n\n# Comentario de una linea\n\n\"\"\"\nComentario\nde varias \nlineas\n\"\"\"\n'''\nComentario\nde varias \nlineas\n'''\nmy_variable = \"variable\"\nmy_variable = \"nueva variable\"\n\nMY_CONSTANT = \"constante\"\n\nmy_int = 1\nmy_float = 1.5\nmy_bool = True\nmy-bool = False\nmy_string = \"Cadena de texto\"\nmy_other_string = \"otra cadena de texto\"\n\nprint(\"!Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Nico70012.py",
    "content": "#https://www.python.org\n\n#Comentario en una linea\n\n\"\"\"\nEste es mi primer comentario \nen varias lineas\nsegun el video\n\"\"\"\n\n'''\nEste es mi primer comentario \nen varias lineas\nsegun el video\n'''\n\nmy_variable = \"Mi variable\"\nmy_variable = \"Nuevo valer de mi variable\"\n\nMY_CONSTANT = \"Mi constante\" #por convencion \nMY_CONSTANT = \n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/NicoHeguaburu.py",
    "content": "# https://python.org/\n\n# Comentario de una linea\n\n\"\"\"\nComentario en \nvarias lineas\n\"\"\"\n\n'''\nOtra opccion de \ncomentario en varias\nlineas\n'''\n\nvariable = \"Mi variable\"\n\nCONSTANTE = \"Mi constante\"\n\nentero = 1\ndecimal = 1,2\nbooleano = False\ntexto = \"Mi texto\" \n\nprint(\"Hola Python\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Nicojsuarez2.py",
    "content": "# #00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n> #### Dificultad: Fácil | Publicación: 26/12/23 | Corrección: 02/01/24\n\n## Ejercicio\n\n```\n/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/NicolasCalderonBolivar.py",
    "content": "\n# https://www.python.org/\n\n# asi es un comentario de una linea\n\"\"\" asi comentarios en bloque y template\"\"\"\n\nvariable_numerica_entera = int() # 0\nvariable_numerica_flotante = float() # 2.5\nvariable_texto = str() # \"\"\nvariable_diccionario = dict() # {}\nvariable_lista = list() # []\nvariable_booleano = bool()  # False\n\nCONSTANTE = None # una Variable constante vacia. se pone en MAYUSCULA porque python no soporta Constantes.\n\nprint(\"¡Hola, python!\")\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Niconbravo.py",
    "content": "#https://www.python.org/\nlenguaje_escogido= \"Python\"\n\n#Así se crea un comentario simple de una línea en Python\n\"También pueden usarse doble comillas\"\n'Y también son funcionales las comillas simples'\n#Se puede combinar las comillas y doble comillas sin problemas para hacer énfasis:\n\"Esta es una 'frase' que combina ambas sin problemas\"\n\n#Se puede hacer un comentario de varias lineas con triple comillas\n'''\nEsto es un comentario de bloque de varias líneas\nque puede ser utilizado para explicar código\n'''\n#También se puede hacer con doble comilas:\n\"\"\"\nEsto es un comentario de bloque de varias líneas\nque puede ser utilizado para explicar código\n\"\"\"\n#¿Cómo nombrar variables?\n\"\"\"\nLas variables en Python pueden ser nombradas de la siguiente manera:\n1. No pueden comenzar con números\n2. No pueden contener espacios en blanco\n3. No pueden contener caracteres especiales\n4. No pueden ser iguales a palabras reservadas de Python\n\"\"\"\n#Por convención se recomienda utiizar snake case para nombrar variables. Esta utiliza guión bajo para separar palabras.\n#Además se recomienda que el nombre sea fácil de comprender:\n#Ejemplo de variable con snake case\nnombre_usuario = \"Juan\"\n\n\n#Tipo de datos:\n\"Datos numéricos:\"\nnumeros_enteros = 1\nnumeros_flotantes = 3.14\n\n\"Datos de caracteres:\"\ncadena_de_texto = \"Esta es una cadena de texto\"\n\n\"Datos booleanos\"\nboleanos_verdadero = True\nboleanos_falso = False\n\nvariable = \"Carlos\"\n\"\"\"En python no existen las constantes pero por convención.\nSe pueden utilizar mayúsculas y guiones bajos \n para indicar que es una constante\"\"\"\nCONSTANTE_NOMBRE = \"Carlos\"\n\nprint(\"¡Hola, {}!\".format(lenguaje_escogido))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/NoMeLlamoDante.py",
    "content": "# Visita la página oficial en: https://www.python.org/\n# o visita la documentación en : https://docs.python.org/3/\n\n\n# Comentarios de una sola línea\n\n\"\"\"\nBloques de \nComentarios\nen Python\n\"\"\"\n\n\n\"\"\" En python, las variables se declaran escribiendo el nombre de la misma, y su valor\npara ello se pueden usar diferentes convenciones\naunque lo más estándar es usar:\nsnake_case para las VARIABLES\nUPPER_SNAKE_CASE para las CONSTANTES\n\"\"\"\n\n\nvariable_int = 0;\nvariable_long = 123123123123123\nvariable_string = \"Hola\"\nvariable_boolean = False\nvariable_char = 'g'\n\nGRAVEDAD_TERRESTRE = 9.8 #Float\nDIAS_DE_LA_SEMANA = 7\n\nprint(variable_string, \"Mundo\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/NotJ0S3.py",
    "content": "# - Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n# https://docs.python.org/3/tutorial/index.html\n\n# - Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n# Este es un comentario en una sola linea\n\n\"\"\"\nEste es un\ncomentario\nen varias lineas\n\"\"\"\n# - Crea una variable (y una constante si el lenguaje lo soporta).\nmi_primer_variable = \"Mi primera variable\"\n\nmi_primera_constante = \"Mi primera constante (imaginaria)\" # Python no tiene constantes :(\n\n# - Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\nint = 23\nfloat = 3.14\nbool = True\nbool2 = False\nstring = \"A una cadena de caracteres se le denomina string\"\n\n# - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/NuOldev.py",
    "content": "# https://www.python.org/\n\n# comentario en una linea\n\"\"\"Comentario mutilinea\"\"\"\n\nvariable = \"python\"\nVARIABLE_CONSTANTE = 1000\n\nbooleans = True\nintegers = 100\nstrings = \"este es un string\"\nfloats = 1.0\n\nprint(\"Hola, \" + variable + \"!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/NyxtByteX.py",
    "content": "# https://www.python.org\n\n# Comentario en una línea\n\n\"\"\"\nEsto también es \nun comentario\nen varias líneas\n\"\"\"\n\n'''\nEsto también es \nun comentario\nen varias líneas\n'''\n\n#¿Qué es una variable?\n# Una variable es un nombre que guarda un valor en memoria.\nmy_variable = \"Mi variable\"\nmy_variable = \"Nuevo valor de mi variable\"\n\n# Las constantes se escriben en MAYÚSCULAS por convención,\n# aunque técnicamente sí se puede cambiar.\nMY_CONSTANT = \"Mi constante\" # por convención\n\n# Tipos de datos básicos en Python\nmy_int = 1 # int (entero)\nmy_float = 1.5 # float (decimal)\nmy_bool = True # bool (booleano)\nmy_bool = False # bool (booleano)\nmy_string = \"Mi cadena de texto\"  # str (cadena de texto)\nmy_other_string = 'Mi otra cadena de texto' \n\n# Puedes usar type() para saber el tipo de dato\nprint(type(my_int))  # <class 'int'>\n\n# Imprimir mensaje en consola\nprint(\"¡Hola, Python!\")\n\n# Saber el tipo de dato\nprint(type(my_int))\nprint(type(my_float))\nprint(type(my_bool))\nprint(type(my_string))\nprint(type(my_other_string))\n\n# Concatenar texto con variables (cómo imprimir valores)\nnombre = \"Ana\"\nprint(\"Hola \" + nombre)\n\n# Mejor forma: f-string\nprint(f\"Hola {nombre}\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/OscarDRD.py",
    "content": "#https://www.python.org/\n\n#Comentario de una sola línea\n'''\nComentario de varias líneas\ncon triple comilla simple\n'''\n\"\"\"\nComentario de varias líneas\ncon triple comilla doble\n\"\"\"\n\nCONST = 1 #En Python no existen las constantes, pero se puede simular con mayúsculas\nvar = 1 #Variable numérica\n\n#Variables primitivas\nint = 1\nfloat = 1.1\nstring = \"Hola, Python\"\nbool = True\nbool = False\n\n\nprint(\"¡Hola, Python! Te Quiero\") #Imprime un mensaje en pantalla\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/OsneiderT.py",
    "content": "# Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n'python https://python.org'\n\n# Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n# esto es un comentario de una sola linea\n\"\"\"\nesto es un comentario \nde varias lineas\n\"\"\"\n'''\nesto tambien es un comentario\nde varias lineas en python\n'''\n\n# Crea una variable (y una constante si el lenguaje lo soporta).\nvariable = \"hola\"\nCONSTANTE = \"hola\" # la constante en python no existe pero se puede representar la variable en mayuscula y sera una constante\n\n# Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\ntexto = \"hola\" # Str-> cadenas de texto\nentero = 4 # Int-> numeros enteros sea 1, 3, 25, 100.....\nparte_decimal = 1.2 # Float-> numeros con punto decimal 3.5, 1.5.....\nboleanos = True # Bool-> o False\n\n# Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nprint(\"¡Hola, Python!\") # funcion definida en python print() para imprimir por terminal \n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/PR1DE-23.py",
    "content": "#https://python.org\n\n# Comentario en una linea\n\n\"\"\"\nEsto tambien es \nun comentario pero\nen varias lineas\n\"\"\"\n\n'''\nEsto tambien es\nun comentario\nen varias lineas\n'''\n\n#declaracion de variable\nmy_variable = \"mi variable\"\nmy_variable = \"Nuevo valor de mi variable\"\n\n#declaracion de falsa constante\nMY_CONSTANT = \"mi constante\" #por convencion\n\n#tipos de variables primitivas\nmy_int: int = 2\nmy_float = 2.0\nmy_bool = True\nmy_bool = False\nmy_string = \"mi cadena de texto\"\nmy_other_string = 'mi otra cadena de texto'\n\n#imprimir por terminal\nprint(\"¡Hola, Python!\")\n\nprint(type(my_int))\nprint(type(my_bool))\nprint(type(my_float))\nprint(type(my_string))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Pablo25.py",
    "content": "# 00 Python\n\n# https://www.python.org/\n\n# En python se pueden crear comentarios de una linea usando el caracter del numeral.\n\n'''Así como también comentarios \nen bloque usando las comillas \nsimples o dobles'''\n\n\"\"\"Instrucciones\nRealiza un FORK del repositorio de retos desde GitHub. Hecho.\nCLONA ese repositorio a tu máquina local git clone [TU-REPOSITORIO]. Hecho.\n(Opcional) Crea una RAMA para la solución y desplázate a ella git checkout -b [EL-NOMBRE-DE-TU-RAMA]. Hecho.\"\"\"\n\n# Variable\nAge = 30\n# Al cumplir años\nAge = Age + 1 \n\n# Constante, python no tiene soporte, pero por regla no escrita, se entiende que:\nMy_CONSTANT = 3.1416 # Todo el que lea el codigo, no ouede modificar la constante.\n\n# * - Crea variables representando todos los tipos de datos primitivos\nMy_integer = 10\nMy_float = 2.5\nMy_string = \"Saint Seiya\"\nMy_boolean1 = \"true\"\nMy_boolean2 = \"false\"\n\nprint(\"Hola! Python\")\n\n# Extras\nprint(type(My_integer))\nprint(type(My_float))\nprint(type(My_string))\nprint(type(My_boolean1))\nprint(type(My_boolean2))"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/PabloM-2015.py",
    "content": "# https://www.python.org\n# Esto es un comentario de linea para dejar informacion a tener en cuenta para mi mismo o personas que quieran ver el proyecto\n\n\"\"\"\nasi serian los \ncomentarios en \nvarias lineas\nestos no pueden hacer fallar \nel codigo\n\"\"\"\n\n'''\nLas comillas simples\ntambien se pueden \nutilizar en python para\ncomentarios de varias lineas\n'''\n\nif True:\n    print(\"True\")\n# Esto seria una condicional que afectaria un bloque toca dejar por norma general 4 espacios.Por lo tanto, todo lo que tenga esa identación pertenecerá al bloque del if.\n# En este lenguaje tampoco es necesario utilizar ; para terminar las lineas, simplemente basta con saltar de una linea a otra\n# Pero se puede usar el ; para tener dos sentencias en una misma linea, una sentencia seria una linea de codigo al mando de una tarea, y cada programa consiste en una secuencia de sentencias\n\n#Ahora tratare de explicar el concepto de multiples lineas, esta sirve para dar una solo instruccion en varias lineas de codigo \ntotal = 10 + \\\n        20 + \\\n        30\n# Tal que esa expresion de varias lineas cuente como solo una operacion, regularmente se usa para que no sean tan largas las lineas y sea mas facil de leer\n\n# Ahora voy a crear una variable: \nnombre de la moto = \"Yamaha MT-09\"\ncaballos de fuerza = 117\n# En resumen, para crear una variable en Python, simplemente asigna un valor a un nombre de variable utilizando el operador de asignación =.\n\n#los tipos de variables son:\nmy_int = 50 #variable de numero enteros, debe ir sin comilla\nmy_float = 1.9 #variable de numero decimal\nmy_bool = True #Variable boleana verdadera\nmy_bool = False #Variable Boleana falsa\nmy_string = \"Hola como estan\"\n\nprint(\"¡Hola,Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/PaoloF16.py",
    "content": "# Desarrollo del Ejercicio\n#https://www.python.org/\n\n# Para comentario de una sola linea se usa el \"#\"\n\n\n\"\"\"\nLas triples comillas simples se usan para\nescribir texto em multiples lineas \n\"\"\"\n\n\n''' \nEsta tambien es una linea de texto \nen multilinea solo con comillas simples \n'''\n\n#Variables \n#¿Cómo nombrar variables?\n\"\"\"\nLas variables en Python pueden ser nombradas de la siguiente manera:\n1. No pueden comenzar con números\n2. No pueden contener espacios en blanco\n3. No pueden contener caracteres especiales\n4. No pueden ser iguales a palabras reservadas de Python\n\"\"\"\n#Por convención se recomienda utiizar snake case para nombrar variables. Esta utiliza guión bajo para separar palabras.\n#Además se recomienda que el nombre sea fácil de comprender:\n#Ejemplo de variable con snake case\nmy_user = \"Paolo\"\nMY_CONSTANT = \"12\"\n\n\n'''\nPython admite diferentes tipos de variables sean numericas o textuales dentro de tipo de datos numericos tenemos a enteros (int) flotante\n(float) o complejos (complex) que se pueden combinar mediante operadores, una parte es real y una parte es imaginaria\n'''\n# Ejemplos de variables numericos \n # Enteros o int \nmy_int = 3\n\n # Flotantes o float\nmy_float = 3,5\n # Complejos o complex\nmy_complex = 3 + 5j\n\n#Datos booleanos \n#Se representa por verdadero o falso\n\nmy_bool = True\nmy_bool = False\n\n#Strings\n\nmy_string = \"My first line\"\nmy_new_string = \"My second line\"\n\n\nprint(\"Hola Python\")\nprint(type(my_int))\nprint(type(my_float))\nprint(type(my_bool))\nprint(type(my_string))\nprint(type(my_new_string))\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Paprikaistkrieg.py",
    "content": "# URL: https://www.python.org/\n# esto es un comentario en una línea (con # al principio)\n\n\n\"\"\" Esto también es\nun comentario\nen varias líneas\n(con comillas dobles)\n\"\"\"\n\n'''Esto también es\nun comentario\nen varias líneas\n(con comillas simples)'''\n\n# Variable\nmy_variable = \"la variable de paprikaistkrieg\"\n\n# Constante: hecha por convención escrita en mayúscula\nMY_CONSTANT = \"la constante de paprikaistkrieg\"\n# convencion: es una regla no obligatoria que se sigue para mejorar la legibilidad del código\n\n# Datos Primitivos\n\nmy_int = 42    \n# Ejemplo: 5, -10, 0 - \n# Representan números sin decimales: positivos, negativos o cero.\n\nmy_float = 3.14\n# Ejemplo: 3.14, -0.001, 2.71828 Números con decimales.\n\nmy_string = \"mi cadena de texto\"\nmy_other_string = 'otra cadena de texto'\n# Secuencia de caracteres entre comillas simples ' o dobles \".\n# Se usan para representar palabras, frases, etc.\n# Ejemplo: \"Hola, mundo\", 'Python es genial'\n\nmy_bool = True  \nmy_bool = False\n# Se usan para tomar decisiones en el código (condicionales).\n# Solo tienen dos valores: True o False.\n\n# Imprimir por consola\nprint(\"¡Hola Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/PatrickFER99.py",
    "content": "#EJERCICIO 1:\n#https://www.python.org/\n\n#EJERCICIO 2:\n#COMENTARIO 1 LINEA\n\"\"\"\nESTO ES UN COMENTARIO \nEN \nTODAS \nLAS \nLINEAS\nQUE DESEAS\n\"\"\"\n\n#EJERCICIO 3:\nMy_Variable = \"SOY EL MEJOR PROGRAMADOR DEL MUNDO\" \nMy_Variable = \"SOY EL MEJOR PROGRAMADOR DEL UNIVERSO\"\n\n#EN PYTOM NO HAY CONSTANTES, PERO SE USAN VARIABLES EN MAYUSCULAS PARA SIMULARLAS \nMY_CONSTANTE = 3.1416\n\n#EJERCICIO 4:\n#Declaracion de variables y tipos de datos\nint_Variable = 10         #Tipo de dato entero\nfloat_Variable = 10.5     #Tipo de dato decimal\nstr_Variable = \"Hola Mundo\" #Tipo de dato cadena de texto\nbool_Variable = True      #Tipo de dato booleano\nchar_Variable = 'A'       #Tipo de dato caracter\n\n#EJERCICIO 5:\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Paula2409.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n\"\"\"\nfrom datetime import datetime, timezone\n\n# https://www.python.org/\n\n# Comentario de linea\n\n\"\"\" Comentario de multiples lineas \"\"\"\n\nvariable = 'Soy una variable'\nCONSTANTE = 'Soy una constante'\n\n# str\nstr_var = 'Hola'\nprint(f\"la variable {str_var} es de tipo {type(str_var)}\")\n\n# int\nint_var = 5\nprint(f\"la variable {int_var} es de tipo {type(int_var)}\")\n\n# float\nfloat_var = 3.4\nprint(f\"la variable {float_var} es de tipo {type(float_var)}\")\n\n# Boolean\nbool_var = True\nprint(f\"la variable {bool_var} es de tipo {type(bool_var)}\")\n\n# Complex\ncomplex_var = 3 + 5j\nprint(f\"la variable {complex_var} es de tipo {type(complex_var)}\")\n\n# List\nlist_var = [5,4,'a']\nprint(f\"la variable {list_var} es de tipo {type(list_var)}\")\n\n# Dictionary\ndict_var = {'1':'a', '2':'b'}\nprint(f\"la variable {dict_var} es de tipo {type(dict_var)}\")\n\n# Set\nset_var = {'1','a',8,(5,'e')}\nprint(f\"la variable {set_var} es de tipo {type(set_var)}\")\n\n# Tuple\ntuple_var = (5,6,'a',(6,9))\nprint(f\"la variable {tuple_var} es de tipo {type(tuple_var)}\")\n\n# Datetime\ndate_var = datetime.now()\nprint(f\"la variable {date_var} es de tipo {type(date_var)}\")\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/PedroJOG.py",
    "content": "# Comentario en una línea\n\n\"\"\"\ncomentario en \nvarias líneas\n\"\"\"\n\n'''\nOtro tipo de comentario \nen varias líneas\n'''\n\nmy_variable = \"Variable\"\nmy_variable = \"Variable modificada\"\n\nMY_CONSTANT = \"Constante\"  #Se suele utilizar mayúsculas para que se respete la constante pero aún así se puede modificar\n\nentero = 5\nfloat = 5.5\ncadena = \"Mi cadena\"\nbool = true\n\nprint(\"Hola, Python\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/PepeMN23.py",
    "content": "# Sitio web oficial de Python: https://www.python.org/\n\n# Comentario en una sola línea\n\n'''\nComentario con saltos \nde línea\n'''\n\na = 10 # Esto es una variable, el numero puede cambiar\nDIEZ = 10 # Este valor se conserva lo largo del programa, es una constante.\n\n# Tipos de datos primitivos\nstring = \"Este es un string\"\ninteger = 15\nfloat = 12.56\nbooleano = True\nbooleano = False\nlista = [1,2,3,4,5]\ntupla = (1,2,3,4,5)\n\n#Imprimir por la terminal \"¡Hola Mundo!\"\nprint(\"¡Hola, Python!\")\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Pipe281.py",
    "content": "# Este es un comentario en python  https://www.python.org/\n\n\"\"\"\n    Este es otro tipo de comentario, se pueden generar mas lineas\n    dentro del codigo de python  tambien puede ser usado para documenación\n\"\"\"\nvariable = 1\ntexto = \"Esto es un texto\"\nentero = 33\nflotante = 23.5\nboleano = True\nboleano = False\nnulo = None\n\nprint(\"Hola python, https://www.python.org/ \")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Print-Alan.py",
    "content": "#https://python.org\n\n#Comentario en una línea\n\n'''\nComentario en\nvarias lineas\n'''\n\n\"\"\"\nComentario en\nvarias líneas\n\"\"\"\n\n\"\"\"\nPython es un leguaje de tipado dinamico, esto quiere decir\nque identifica el tipo de dato en automatico, ya sea entero,decimal,\ncadena de texto, etc.\n\"\"\"\n\nmy_varible = \"varable\"\nMY_CONSTANT = \"constante\" #En python no existen como tal las constantes, pero los tipos de datos que esten escritos en MAYUSCULAS se pueden interpretar como constantes\n\n#Tipos de datos primitivos\nmy_int = 7\nmy_float = 5.4\nmy_bool = False\nmy_bool = True\nmy_string = \"Cadena de texto\"\n\nprint(\"Hola Python\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/PyTorDev.py",
    "content": "'''\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n'''\n# La url con la documntación de Python es https://docs.python.org/es/3.13/\n\n  #Comentario de una linea\n\n'''\nComentario multilinea\nEste tipo de comentario en Python, no es un comentario real, y ocupa meemoria en ejecución\n'''\n\n  #Declaración de variable\n\nvarianble1 = 1 #Asigna el valor 1 a variable1\nvariable_nombre= \"Paco\" #Asigna el valor Paco a variable_nombre\na, b, c = 1, 2, 3 #Asinga los valores 1, 2 y 3 a las variables a, b y c respectivamente\n\n  #Declaración de constante\n\n#En Python no existen las constantes, pero existe la conveción de que una variable en mayusculas, se considera constante,\n#por tanto no deberia ser cambiada aunque el lenguje lo permite\n\nURL_API = 'https:\\\\la-web-de-la-api.com'\n\n  #Tipos de datos primitivos\n#Enteros (int)\nx = 1\nnum_int = 1234\n\n#Flotantes/Decimales (float)\ny = 1.12\nnum_float = 2345.1234\n\n#Buleano (bool)\nxBoolean = True\nmy_boolean = False\n\n#Cadena de texto (String)\ntext = \"Hola mundo\"\ntext2 = 'Python es el lenguaje de la pitón'\ntexto_multilinea = '''\nEste string esta dentro \nde texto_multilinea\n'''\n\n\nleng = 'Python'\n\nprint('Hola, el lenguaje es ' + leng)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Raghnus.py",
    "content": "# URL: https://www.python.org\n\n#Comentario de una linea\n\n\"\"\"\nComentario\nde\nvarias lineas\n\"\"\"\n\n#Variable\nx = 5\n\n#Constante\nVARIABLE_CONSTANTE = 'Constante'\n\n#Tipos primitivos del lenguaje\ncadena = \"Python\"               #String\nentero = 8                      #Int\nflotante = 9.05                 #Float\nbooleano = True                 #Boolean\n\n#Imprimir mensaje\nprint(\"Hola,\", cadena)\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Ramirofordev.py",
    "content": "# Python: https://www.python.org/\n'''\nEsta es la forma de comentar en varias lineas\n'''\n\n# Y esta es la forma de comentar en una sola linea\n\nx = 5\nPI = 3.1416\n\n# Int\ny = 6\n\n# Float\nn = 1.5\n\n# String\nnombre = \"Nacho\"\n\n# Boolean\nestudiando = True\n\nprint(\"Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Ramon01-ing.py",
    "content": "# https://www.python.org/\n\n# Esto es un comentario\n\n'''\nEsto también es\nun comentario\nen varias lineas\n'''\n\nvariable_1 = \"Variable Uno\"\nvariable_1 = \"Variable Dos\"\n\nvar_int = 10\nvar_str = \"Hola\"\nvar_bool = True\n\nprint(\"¡Hola, python! \")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Rastaxico.py",
    "content": "# Ejercicio realizado por Rastaxico\n\n# Ruta web Python https://www.python.org/\n\n# Comentario de una sola linea\n\n\"\"\"\nComentario \nde \nvarias lineas\n\"\"\"\n\n# Ejemplo de como crear una variable \nmi_variable = \"Mi variable\"\nmi_variable = 9\n\n#Como crear una constante - Se hace por convencion\nMI_CONSTANTE = \"Mi Constante\"\n\n# Crear variables con cada uno de los tipo de datos primitivos\n\n# Strings o Cadenas de texto\nnombre_github = \"Rastaxico\"\nmi_lenguaje = \"Python\"\nmis_disculpas = \"Por favor Disculpenme por llegar tarde al curso, espero no haberme hecho bolas para subir la tarea al github\"\n\n# Integer o Enteros\nedad_en_años = 42\n\n# Floats o Flotantes\nestarura = 1,72\n\n# Booleanos o de verdad\ndesea_programar = True\n\n# Imprimir en terminal \nprint(\"Hola, soy\", nombre_github, \"y uso\", mi_lenguaje)\nprint(mis_disculpas)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/RgeditV1.py",
    "content": "#https//www.python.org\n#Para comentar una linea solamente ponemos '#' y luego comentamos esa misma linea\n    \n\"\"\"\nPara comentar con mas lineas podemos poner triple comillas para abrir, comentamos y luego triple comillas para cerrar\n\\\"\"\"\n\"\"\"\n\n#Tipos de datos primitivos\nVAR_CONST = 1 #variable constante, osea no se puede modificar cuando volvamos a usarlo\nvar_string = \"esto es un string\"  #esto es una cadena de texto plano\nvar_int = 1 #esto es una variable de tipo entero 'int'\nvar_float = 1.5 #Esto es una variable de tipo flotante 'float'\nvar_boolean = True #esto es una variable de tipo Booleano 'Boolean'\n\nprint('¡Hola, Python!')\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/RickUbb.py",
    "content": "#Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n# https://www.python.org/\n\n# Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n# Comentario de una linea\n\"\"\"\nComentario\nde\nvarias\nlineas\n\"\"\"\n\n# Crea una variable (y una constante si el lenguaje lo soporta).\ndia = \"Jueves\"\n# En Python el concepto de constante simbolico, se lo pone al nombre en mayusculas pero el lenguaje si permite cambiar el valor\nNOMBRE = \"Ricardo\"\n\n# Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\nmi_cadena = \"Hola soy un String\"\nmi_entero = 7\nmi_decimal = 3.14\nmi_boolean = True\n\n# Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nprint(\"Hola, Python!\")\n\nmi_lenguaje = \"Python!\"\n\nprint(\"Hola, \" + mi_lenguaje)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Robindev1812.py",
    "content": "# Ejercicios:\r\n\r\n# 01 - Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\r\n\r\n# https://www.python.org/\r\n\r\n# <------------------------------------------------------------> <------------------------------------------------------------>\r\n# 02 - Representa las diferentes sintaxis que existen de crear comentarios.\r\n\r\n# Esto es un comentario de una sola línea.\r\n\r\n\"\"\"\r\nEsto es un comentario\r\nde múltiples líneas.\r\n\"\"\"\r\n\r\n\r\n# <------------------------------------------------------------> <------------------------------------------------------------>\r\n# 03 - Crea una variable (y una constante si el lenguaje lo soporta).\r\n\r\n# para crear una variable simplemente le damos nombre y asignamos el valor que queremos que tenga.\r\nmy_variable = \"Hello\"\r\n\r\n# Python no consta de una estructura para poder asignar que un tipo de dato sea constante. Por conversión se suele escribir el nombre de la variable en mayúscula.\r\nMY_CONST = \"I'm CONST\"\r\n\r\n\r\n# <------------------------------------------------------------> <------------------------------------------------------------>\r\n# 04 - Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\r\n\r\ntype_str = \"I'm string\"\r\ntype_int = 4\r\ntype_float = 10.3\r\ntype_boolean = True\r\n\r\n\r\n# <------------------------------------------------------------> <------------------------------------------------------------>\r\n# 05 - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\r\n\r\nprint(\"¡Hola, Python!\")\r\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Rodrigoghr.py",
    "content": "# #00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n\n## Ejercicio\n\n'''\n\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n\n'''\n# https://python.org\n\n# hola soy un comentario\n\n'''\n    Hola soy un \n    comentario de varias lineas\n    con el uso de 3 comillas simples.\n'''\n\n\"\"\"\n    Hola soy un \n    comentario de varias lineas\n    con el uso de 3 comillas dobles.\n\"\"\"\n\n# Variable:\nmi_variable = 12\n\n# Constante:\nCONSTANTE_EULER = 2.71\n\n# Tipos de datos primitivos\nmi_entero = 16\nmi_flotante = 1.25\nmi_cadena = \"Hola Mouredev!\"\nmi_otra_cadena = 'Buen día Mouredev'\nmi_booleano = True\nmi_complejo = 2 + 3j\nmi_nulo = None\n\n# Impresión por terminal:\nlenguaje = \"Python\"\nprint(f\"¡Hola, {lenguaje}!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/RoniPG.py",
    "content": "# @RoniPG\n\n# https://www.python.org/\n\n# Comentario en una linea.\n\n\"\"\"\nComentario de varias lineas.\n\"\"\"\n\n# Variables\nint = 0  # ---> numeros decimales.\nfloat = 0.0 # ---> numeros decimales.\nboolean = False # ---> valores true, false(por defecto).\nString = \"Texto\" #---> variable para almacenar un texto.\n\t\t\nprint(\"Hola mundo\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/RuhlMirko.py",
    "content": "# https://www.python.org/\n\n# Comentario de una linea\n\n\"\"\"\nComentario\nen mulltiples\nlineas\n\"\"\"\n\nprimera_variable = \"\"\nCONSTANTE = \"\"\nvariable_int = 1\nvariable_float = 1.1\nvariable_string = \"Hola mundo!\"\nvariable_bool = False\n\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Rusanov16.py",
    "content": "\"\"\"\nEJERCICIO 00:\n    - Crea un comentario en el código y coloca la URL del sitio web oficial del\n    lenguaje de programación que has seleccionado.\n    - Representa las diferentes sintaxis que existen de crear comentarios\n    en el lenguaje (en una línea, varias...).\n    - Crea una variable (y una constante si el lenguaje lo soporta).\n    - Crea variables representando todos los tipos de datos primitivos\n    del lenguaje (cadenas de texto, enteros, booleanos...).\n    - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\"\"\"\n\n#*-------------------------------------------------------------------------------------------------------------#\n\n# * - Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n# https://www.python.org\n\n#*-------------------------------------------------------------------------------------------------------------#\n\n#  * - Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n\n# Con el # se puede escribir un comentario de una linea.\n\n\"\"\"\nOtra forma de escribir comentarios, en este caso en varias líneas. Además, tambien se puede escribir comentarios en varias \nlineas utilizando las comillas simples: '''\n\"\"\"\n#*-------------------------------------------------------------------------------------------------------------#\n\n#  * - Crea una variable (y una constante si el lenguaje lo soporta).\nvariable = \"2\" #Variable de tipo String (Cadena)\nCONSTANTE_PI = 3.141592 #Para declarar una constante en python se debe declarar la variable en mayúsculas\n\n#*-------------------------------------------------------------------------------------------------------------#\n\n#  * - Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\nvariable_string = \"Github\"\nvariable_integer = 35\nvariable_booleano = True\nvariable_float = 0.9873\n\n#*-------------------------------------------------------------------------------------------------------------#\n\n#  * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nprint(\"Hola Mundo desde Python!!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/SBNGL.py",
    "content": "#https://www.python.org/\n\n#COMENTARIOS\n\n\"\"\"\nEJEMPLO COMENTARIO 1\n\"\"\"\n\n'''\nEJEMPLO COMENTARIO 2\n'''\n# VARIABLE Y CONSTANTE\nmi_variable = \"una variable\"\nCONSTANTE = 23\n\n#CADENA DE TEXTO\nstr = \"Cadena de texto\"\n\n#ENTEROS (int)\nEnteros = 1\n\n#BOOLEANOS (bool)\nbooleanos = True and False\n\n#FLOATS\nfloats = 0.154266\n\n#LISTA\nlista = [1,2,3,4,\"hola\"]\n\n#TUPLA\ntupla = (\"a\",\"b\",1,3,67)\n\n#DICCIONARIO\ndiccionario = {\n  \"nombre\" : \"Camilo\";\n  \"Edad\" : \"15\"}\n\n#Mensaje saludando con el lenguaje que quiero aprender\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/SMSPROGRAMACION1236.PY",
    "content": "#  * EJERCICIO:\r\n#  * - Crea un comentario en el código y coloca la URL del sitio web oficial del\r\n#  *   lenguaje de programación que has seleccionado.\r\n#  * - Representa las diferentes sintaxis que existen de crear comentarios\r\n#  *   en el lenguaje (en una línea, varias...).\r\n#  * - Crea una variable (y una constante si el lenguaje lo soporta).\r\n#  * - Crea variables representando todos los tipos de datos primitivos\r\n#  *   del lenguaje (cadenas de texto, enteros, booleanos...).\r\n#  * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\r\n#  *\r\n#  * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\r\n#  * debemos comenzar por el principio.\r\n#  */\r\n\r\n\r\n# https://www.python.org/\r\n\r\n\r\n# Comentario Simple(Una linea)\r\n\"\"\"Comentario de varias lineas(comillas dobles)\r\n\"\"\"\r\n\r\n\r\n'''Comentarios de varias lineas(comillas simples)'''\r\n\r\n\r\n\r\n#* Variable y Constante\r\nnombre =\"Pedro\"\r\nPI = 3.14 # Como tal no es una constante, pero es lo mas cercano\r\n\r\n\r\n\r\n#* Tipos de Variables\r\ncadena = \"Hola Mundo\"\r\nentero = 30\r\nflotante = 10\r\nboleano = True\r\nnulo = None\r\n# Para saber el tipo de variable\r\nprint(type(cadena))\r\nprint(type(entero))\r\nprint(type(boleano))\r\nprint(type(nulo))\r\n\r\n\r\nprint(\"¡Hola, Python!\")\r\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/SNaoj.py",
    "content": "#https://www.python.org/\n\n\"\"\"\nHola, esta es una prueba\nde comentario en varias lineas\n\"\"\"\n\nNombres = \"Juan\"\nEdad = 22\nIs_male = True\nNota_final = 4.5\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Sac-Corts.py",
    "content": "# https://www.python.org/\n\n# Comentario en una línea\n\n\"\"\"\nEsto también es un \ncomentario en varias\nlíneas\n\"\"\" \n\n'''\nEsto también es un \ncomentario en varias\nlíneas\n'''\n\nmy_variable = \"Mi variable\"\nmy_variable = \"Nuevo valor de mi variable\"\n\nMY_CONSTANT = \"Mi constante\"\n\nmy_int = 11\nmy_float = 9.99\nmy_bool = False\nmy_bool = True\nmy_str = \"Mi cadena de texto\"\nmy_other_str = 'Mi otra cadena de texto'\n\nprint(\"Hola, Python\") \n\nprint(type(my_int))\nprint(type(my_float))\nprint(type(my_bool))\nprint(type(my_str))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Sandrogmz.py",
    "content": "#[00] - [Python]\"\n# https://www.python.org\n\n\"\"\"\ncomentario \nde varias\nlineas \"\"\"\n\n#VARIABLES\nvar = exit\nvar = IndentationError\n\n#CONSTANTE\n\nconstante = False\n# TIPOS DE DATOS\n\nint = 4\nfloat = 12.3\nstr = \"Hola\"\nbool = True\n\n\n#Mi primer programa\n\nprint (\"Hola Python!\")\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/SantiFer26.py",
    "content": "\"\"\"\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n\"\"\"  \n\n# Web oficial de python: https://www.python.org/\n\n# Comentario de una sola línea\n\n\"\"\"\nComentario de \nvarias líneas\n\"\"\"\n\n'''\nOtro comentario \nde varias líneas\n'''\n\nnombre = \"Santiago\" # variable\n\nEDAD = 22 # constante\n\n\n#Variables de tipos de datos primitivos:\ndia = 26 # integer\n\nprecio = 39.99 # float \n\nbooleano = True # boolean\n\nlugar = \"Argentina\" # string\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Seba9906.py",
    "content": "# https://www.python.org/\n#Comentario de una linea\n\"\"\"\ncomentario\nde\nmultiples\nlineas\n\n\"\"\"\n'''\ncomentario \nde\nmultiples\nlineas\n\n'''\n#variable\nmy_var = \"variable de texto\"\n#constante\nPI = 3.14159265359\nenteros:int=24\nflotantes:float = 23.45\ncadenas:str = \"esto es un dato tipo cadena\"\nbooleanos:bool = True\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/SergioGI99.py",
    "content": "\"\"\"\n------------------------------------------------\nSINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n------------------------------------------------\n¿Preparado para aprender o repasar el lenguaje de programación que tú quieras?\n- Recuerda que todas las instrucciones de participación están en el\n  repositorio de GitHub.\nLo primero... ¿Ya has elegido un lenguaje?\n- No todos son iguales, pero sus fundamentos suelen ser comunes.\n- Este primer reto te servirá para familiarizarte con la forma de participar\n  enviando tus propias soluciones.\nEJERCICIO:\n- Crea un comentario en el código y coloca la URL del sitio web oficial del\n  lenguaje de programación que has seleccionado.\n- Representa las diferentes sintaxis que existen de crear comentarios\n  en el lenguaje (en una línea, varias...).\n- Crea una variable (y una constante si el lenguaje lo soporta).\n- Crea variables representando todos los tipos de datos primitivos\n  del lenguaje (cadenas de texto, enteros, booleanos...).\n- Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\ndebemos comenzar por el principio.\n\"\"\"\n\n# https://www.python.org/\n\n# Esto es un comentario\n\n\"\"\"\nEsto en un comentario\nen varias líneas\n\"\"\"\n\n'''\nEsto también es un comentario\nen varias líneas\n'''\n\nmy_variable = \"Esto es una variable\"\nMY_CONSTANT = \"Esto es una constante\" # No existen las constantes en Python aunque se pueden representar por convención\n\nstr_variable = \"Esto es un str\"\nint_variable = 6\nfloat_variable = 3.14\nbool_variable = True\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Sharguidev.py",
    "content": "# https://www.python.org/\n\n\n# este es un comentario de una linea\n\n\"\"\"\nEste\nes un \ncomentario\nde varias lineas\n\"\"\"\n\n#este \n#tambien\n#es de varias lineas\n\n\ninteger = 2\nstring = \"Hola soy de Costa Rica\"\nbooleano = True\n\n\n#firstway\n\nprint(\"Hello, my language is Python\")\n\n#secondway\n\ntech = \"Python\"\np = (f\"Hello, my language is {tech}\")\nprint(p)\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Sherete2000.py",
    "content": "#https://www.python.org/\n#comentario en linea\n//dadadad\n\"\"\"\nesto tambien\nes un\ncomentario\nen varias lineas\n\"\"\"\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Sherkla12e.py",
    "content": "# sherklan\n\n# ej1: este es un comentario  pagina de mi lenguaje = https://www.python.org/\n\n\n# ej2:  \n# Comentarios\n\"Este es un comentario\"\n\n\n\"\"\"Este tambien es un comentario\n    con\n    mas\n    lineas de\n    codigo\n\n\"\"\"\n# ej3:\n# Variable y constante\n\nvariable = 'Me llamo davis'\n# Mayormente alas constantes see le coloca su respectiva mayuscula\nPI = 3\n\n# ej4\n#  TIPOS DE DATOS PRIMITIVOS\nentero = 32\ncadena:str = 'Hola'\ndecimal:float = 324.2\nbooleano = True # o False\nlista = [2,3,4,3]\ntupla = (32,56,67,67,55,67,5,6,756,3)\ndiciconario = {'llave':1, 'llave2':2}\nconjunto = {23,32,3,5,65}\nnone = None\n# ej5 imprimir\nprint('Hola Python!')\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/SnowAle.py",
    "content": "#1.- https://www.python.org\n\n#2 Los comentarios se pueden realizar utilizado \"#\" para comentarios en una linea\n\"\"\"\nConla utilizacion de 3 comillas dobles\npara realizar comentarios en varias lineas\n\"\"\"\n'''\nO en algunos casos tambien son permitidas\nlas comillas simples para comentarios en varias\nlineas\n'''\n\n#3\nAnimus= \"Esta es una \\\"str o variable en cadena mejor conocidas como variables de tipo texto\"\n\n#En python no es posible el uso de constantes pero podemos declarar variables con letras mayusuculas para representarlas y aclarar que no queremos que se modifiquen... \n\nPI= 3.14 # Pero esto es a convencion o conveniencia, es decir, si volvemos a crear la misma variable \"PI\" en otra linea y modificamos su valor este se modificara de igualforma...\n\n#4\n\nText= \"Texto\"\nText2= 'texto2'\nMyInt= 0\nMyFloat= 0.3\nBool= True\n\nprint (type(Text))\nprint (type(MyInt))\nprint (type(MyFloat))\nprint (type(Bool))\n\n#5\n\nprint (\"Hola Python\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/SnowCardenas.py",
    "content": "# https://python.org\n\n# Comentario de una línea\n    \n''' \n    Comentario de varias líneas\n    Comentario de varias líneas\n'''\n\nvariable = \"Hola soy una variable\"\nCONSTANTE = \"Hola soy una constante\"\n\nstring = \"Hola soy un string\"\nentero = 1\nflotante = 1.1\nbooleano = True\nNoneType = None\n\nprint(\"¡Hola, Python!\")\n\nprint(variable)\nprint(CONSTANTE)\nprint(type(string))\nprint(type(entero))\nprint(type(flotante))\nprint(type(booleano))\nprint(type(NoneType))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Sofia-d-p.py",
    "content": "#Creo comentario y agrego url de Python https://www.python.org/ \n\n\n#Esto es un comentario de una linea de texto\n\n\"\"\"\nEsto es\nun comentario\nde varias lineas\nde texto\n\"\"\"\n\n'''\nEsta es \notra forma \nde hacer comentarios\nde varias líneas de texto\n'''\n\n#Crear variable\nmi_variable = \"variable\"\n\n#Cambio el valor de mi variable\nmi_variable = \"nuevo valor de mi variable\"\n\n#Tipos de datos primitivos\nmy_int = 10\nmy_float = 1.23\nmy_bool = False\nmy_string = \"cadena de texto\"\n\n#Imprimir el valor de mi variable\nprint(my_int)\nprint(my_float)\nprint(my_bool)\nprint(my_string)\nprint(\"hola Python!\")\n\n#Para saber el tipo de dato que es la variable\nprint(type(my_int))\nprint(type(my_float))\nprint(type(my_bool))\nprint(type(my_string))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/SooHav.py",
    "content": "#00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n\n#Este es un comentario (en una línea) que indica la URL del sitio web oficial de python: https://www.python.org/\n\n\"\"\" \nEsto es un bloque comentado en Python, que puede ser multilínea,\ngeneralmente usado para documentar el codigo para \nlos potenciales usuarios.\n\"\"\"\n\n#Variable\nmi_variable = \"variable\"\n\n#Constante\n\"\"\"\nLas contantes no existen en python como tal, sin embargo,\npor convención se asigna a una variable como contante y\nse nombran con el nombre todo en mayúsculas.\n\"\"\"\nMI_CONSTANTE = \"constante\" \n\n#Tipos de datos primitivos priuncipales, ejemplos enteros (a), flotantes(b), complejos(c), booleanos(x) y cadenas(s).\na = 1   \nb = 2.3 \nc = 5j-87 \nx = True    \ns = \"sofia\"\n\n#Impresión por consola\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Tallahashee.py",
    "content": "# https://python.org\n\n# Esto es un comentario en una linea\n\n\"\"\"\nEsto es un \ncomentario en\nvarias lineas\n\"\"\"\nmy_variable = \"Mi variable\"\nmy_variable = \"Nuevo valor de mi variable\"\n\nMY_CONSTANT = \"Mi constante\" # por conveccion\n\nmy_int = 1\nmy_float = 2.5 \nmy_bool = True\nmy_bool = False\nmy_string = \"Mi cadena de texto\"\nmy_other_string\" = 'Mi otra cadena de texto'\n\nprint(\"¡Hola, Python!\")\n\nprint(type(my_int))\nprint(type(my_float))\nprint(type(my_bool))\nprint(type(my_string))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/TarLomin.py",
    "content": "#https://www.python.org/\n\n# Este es un comentario de una linea en Python #\n\"\"\"\nEste es un comentario \nde varias lineas en Python \n\"\"\"\nvariable = 10\nCONSTANTE = 3.14 # En Python no existen constantes en el sentido estricto del lenguaje, pero por convención se crean variables en mayúsculas para indicar que no deben cambiar su valor.#\n\n#Datos primitivos#\nstring = \"Esto es un string o cadena de texto\"\nentero = 10\nflotante = 3.1416\nboolean_1 = True\nboolean_2 = False\nnone = None # Representa la ausencia de valor #\n\nprint (\"Hola Python\")\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Tashidian.py",
    "content": "# https://www.python.org/\n\n\n# comentario de una sola línea\n\n\n\"\"\"\nEste comentario es realidad una\nun bloque de texto multilínea,\npero al no estar asignado actúa\ncomo un comentario.\n\"\"\"\n\n# VARIABLES\n\nfirst_var = \"Mi primera variable en Python.\"\n\nCONSTANT = \"Por convención, las constantes en Python se escriben en mayúsculas, sin embargo son variables normales que se pueden modificar.\"\n\n# TIPOS DE DATOS PRIMITIVOS\n\n# string str\nmy_string = \"Cadena de texto.\"\n\n# Integer int\nmy_integer = 7\n\n# Float float\nmy_float = 7.3\n\n# Boolean bool\nmy_boolean  = False\n\n# None NoneType\nmy_none = None\n\n# IMPRESIÓN POR TERMINAL\nlanguage = \"Python\"\nprint(f\"¡Hola, {language}!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Tecno85.py",
    "content": "# https://python.org\n\n# Comentario en una línea\n\n\"\"\"\nComentario en\nvarias líneas\n\"\"\"\n\n'''\nOtro comentario\nen varias líneas\n'''\n\nname = \"Ivan Dario Madrid Daza\"\nname = \"Ismael Madrid Gamez\"\n\n# Python no tiene constantes\n\nMY_CONSTANT = \"Mi constante\"\n\n\"\"\"Las constante en Python, se colocan en mayusculas, este es un método por\nconvención, de la misma manera es posible cambiarle el valor. A la final\nrealmente no hay constantes en Python.\"\"\"\n\n#  DATOS PRIMITIVOS\n\nmy_int = 15\n# Esta es un dato primitivo entero\n\nmy_float = 1.64\n# Este es un dato primitivo flotante o float\n\nmy_bool = True\n# Este es un dato primitivo boleano\n\nmy_str = \"Aprendiendo Python\"\nmy_other_string = 'Aprendiendo Python con MoureDev'\n# Este es un dato primitivo string o cadena de texto\n\n# Imprimir mensaje por consola\nlenguaje = \"Python\"\nprint(f\"\\n¡Hola, el lenguaje que estoy aprendiendo es: {lenguaje}\\n\")\n\n# Obtener tipo de dato\nprint(my_int)\nprint(my_float)\nprint(my_bool)\nprint(my_str)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Testiman-78.py",
    "content": "# Sitio web de phython https://docs.python.org/\r\n\r\n\r\n\r\n\"\"\"\r\nFor some comments\r\n\r\n\"\"\"\r\n\r\n# Integer\r\nnum = 10\r\n\r\n# string\r\nname = \"Juan\"\r\n\r\n# boolean\r\nis_admin = True\r\n\r\n# list\r\nfrutas = [\"manzana\", \"pera\", \"naranja\"]\r\n\r\n# tupla\r\nfrutas_tupla = (\"manzana\", \"pera\", \"naranja\")\r\n\r\n# diccionario\r\nperson = {\"nombre\": \"Juan\", \"edad\": 30}\r\n\r\n# set\r\nfrutas_set = {\"manzana\", \"pera\", \"naranja\"}\r\n\r\n# float\r\nprecio = 10.99\r\n\r\n# None\r\nNone_type = None\r\n\r\n#constante  \r\nPI = 3.14 \r\nIP_DB_SERVER = \"127.0.0.1\"\r\n\r\nprint(\"¡Hola, Python 3.1.2\")\r\n\r\n\r\n\r\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/ThePhobos01.py",
    "content": "# www.python.org\n\n# Esto es un comentario en Python\n\n'''\nEsto es un comentario en Python\npero\nen varias lineas\n'''\n\nmi_variable = \"Esta es mi variable\"\n\nmi_constante = \"Esta es una constante, pero de mentiritas, por que en Python no existen constantes\"\n\n#Tipos de datos primitivos en Python\n\nmi_int = 5\nmi_str = \"Hola mundo\"\nmi_float = 3.5\nmy_bool = True\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/TheReDNooB.py",
    "content": "# https://www.python.org/\n\n# comentario de una linea\n\n\"\"\"\ncomentario\nen\nmultiples\nlineas\n\"\"\"\n\n'''\ncomentario\nen\nmultiples\nlineas\npero\ncon\ncomillas\nsimples\n'''\n\nmi_variable = \"esta es una variable\"\nMY_CONSTANT = \"esta es una variable contante, no me cambies de valor :(\" # como tal no existe constantes, seria por convencion\n\nmy_Int = 1\nmy_Float = 2.5\nmy_String = \"este es una variable de tipo String\"\nmy_second_String = 'este es una variable de tipo String, pero con comillas simples'\nmy_Bool = True\nmy_Bool = False\nmy_programming_language = \"Python\"\n\nprint(f\"Hola, {my_programming_language}!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/TheeWiick.py",
    "content": "# Web oficial de Python: https://www.python.org\n\n# Comentario de una línea\n\n\"\"\"\nComentario\nen varias\nlíneas\n\"\"\"\n\n'''\nOtro comentario\nen varias\nlíneas\n'''\n\n# Variable\nnombre = \"Javi\"\n\n# Constante\nEDAD = 19\n\n# Cadena texto\ncadena_texto = \"String\"\n\n# Numeros enteros\nnumero_entero = 9\n\n# Numeros decimales\nnumero_decimal = 9.9\n\n# Booleanos\njoven = True\nanciano = False\n\n# Imprimir texto por consola\nprint(\"Hola mundo\")\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/ThonyS07.py",
    "content": "#https://www.python.org/ URL oficial python\n\n# comentario de una sola linea\n\n'comentario de una sola linea'\n\n'''\ncomentario\nen multiples lineas\n'''\n\"\"\"\ncomentario\nen multiples lineas\n\"\"\"\n#variables\nstring_variable=\"Anthony\"\nmy_languague=\"Python\"\ninteger_variable=7\nboolean_variable=True\nfloat_variable=3.14\n#constante\nCONSTANT=3.1416\n\n#consola\nprint(\"Hola, \",string_variable, \", esto es \", my_languague, sep=\"\")\nprint(f\"Hola, {string_variable}, esto es {my_languague}\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/TizoG.py",
    "content": "# https://python.org\n\n# Comentario en una linea\n\n'''\nEsto es un \ncomentario en \nvarias lineas\n'''\n\nmy_variable = \"Esto es una variable\"\n\nMY_CONSTANTE = \"Esto es una constante\"\n\nmy_int = 1\nmy_float = 1.1\nmy_boolean = True\nmy_boolean = False\nmy_string = \"Cadena de texto\"\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Tomu98.py",
    "content": "# https://www.python.org/\n\n# Comentario en una linea\n\n\"\"\"\nEste es un comentario\nes de varias lineas,\ncon tres comillas dobles\n\"\"\"\n\n'''\nEste es un comentario también\nes de varias lineas,\ncon tres comillas simples\n'''\n\n# Crear una variable\n# En Python se recomienda usar la convención \"snake_case\" para nombrar variables.\nmi_varible = \"Esto es una variable\"\n\n# Crear una constante \n# En Python las constantes NO funcionan como tal y sus valores pueden cambiar.\n# Se las representa por convención con MAYÚSCULAS.\nMI_CONSTANTE = \"Esto es una constante\"\n\n# Tipos de datos primitivos\nstring: str = \"Cadena de texto\"\ninteger: int = 21\nfloat: float = 12.23\nbool_true: bool = True\nbool_false: bool = False\n\n# Imprimir en la terminal\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Tonywarcode.py",
    "content": "#https://www.python.org/\n\n# Comentario en una linea \n\n'''\nEjemplo de \ncomentarios en \nvarias líneas\n'''\n\n\"\"\"\nEstas dobles\ncomillas\ntambien valen como\ncomentarios\nen varias líneas\n\"\"\"\n\n# variable\n\nmy_variable_str = \"Aqui tu texto\" # variable tipo texto\nmy_variable_num = 0 # variable tipo numero\nmy_variable_bool = True # variable tipo booleano\nmy_variable_bool = False # variable tipo booleano\n\nMY_CONSTANTE = \"Esta es una constante\" #constante\n\n# Tipos de datos primitivos de variables\nprint(\"----- String -----\")\nmy_string = \"variable tipo string\"\nprint(my_string)\nprint(type(my_string))\nprint('\\n')\n\nprint(\"----- Integers -----\")\nmy_integers = 15\nprint(my_integers)\nprint(type(my_integers))\nprint('\\n')\n\nprint(\"----- float -----\")\nmy_float = 30.15\nprint(my_float)\nprint(type(my_float))\nprint('\\n')\n\nprint(\"----- bool -----\")\nmy_boolean = True\nprint(my_boolean)\nprint(type(my_boolean))\n\n# Impresion de texto\nprint('\\n')\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Trosky-Wolf.py",
    "content": "# https://python.org/\n\n# Hola a todos soy nuevo en el lenguade la programación, espero aprender mucho\n\n\"\"\"\nAl princiio esto me ha vuelto loco, he tenido que devolver el tutorial desde un principio un millón de veces\nsin embargo, ya le he cogido el hilo, ahora me siento más comodo al inicio,\nes cuestión de mucha practica como nos lo ha aconsejado nuestro amigo en el tutorial\nsin embargo la constancia vence lo que la dicha no alcanza.\n\"\"\"\n\ntrosky_wolf = \"el lider de la manada\"\ntrosky_wolf = \"nuevo valor trosky wolf\"\n\nMY_CONSTANT = \"Mi constante\" # por convención\nMY_CONSTANT = \"Requiere de Persmisos Universales para ejecutar\"\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/TroyNebula.py",
    "content": "#!/usr/bin/env python\r\n\r\n# - Crea un comentario en el cOdigo y coloca la URL del sitio web oficial del lenguaje seleccionado.\r\n# https://www.python.org/\r\n\r\n\r\n#  - Representa las diferentes sintaxis que existen de crear comentarios\r\n# Este es un comentario habitual que tambien puede ir tras una linea de codigo\r\n\r\n\"\"\"Este es un comentario\r\nde mas de una linea.\r\n\r\nPuedo dejar lineas vacias tambien\r\n\"\"\"\r\n\r\n'''Este es otro comentario\r\nde mas de una linea.'''\r\n\r\n\r\n# - Variable\r\nvariable=1\r\n# - Constante: \r\n\"\"\"En Python las constantes no existen. \r\nPara guardar un valor constante se utiliza una variable pero, como buena practica, \r\nse utilizan las letras mayusculas para darle nombre a dicha variable. \r\nAsi, si al programar nos encontramos con un identificador en mayusculas \r\nsabremos que no debe ser alterado\"\"\"\r\nCONSTANTE=10\r\n\r\n\r\n# - Crea variables representando todos los tipos de datos primitivos\r\nentero:int = 0  # anotacion de tipo \r\nentero= 0  # declaracion simple de variable\r\ntexto:str = \"string\"\r\nbooleana:bool = True  # o False\r\ndecimal:float = 0.5\r\nlista = [1, 2, 3]  # conjunto ordenado de valores dinamico que permiten un amplio manejo de los valores\r\ntupla = (4, 5, 6)  # conjunto ordenado de valores estatico\r\ndiccionario = {'a': 1, 'b': 2}  #claves/valores, se ordenan y son mutables, pero solo permiten entradas unicas no duplicadas\r\nconjunto = {7, 8, 9}  # set/coleccion no ordenada de objetos unicos, pueden ser de diversos tipos objetos mutables como listas, diccionarios, e incluso otros conjuntos\r\nnone = None # Especial data type que no tiene valor\r\ncomplejo:complex = 4+5j # datos complejos\r\n''' Ver lista entera en: https://docs.python.org/3/reference/datamodel.html#set-types'''\r\n\r\n\r\n# - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\r\nprint (\"¡Hola, Python! 🐍\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/TuruDev1979.py",
    "content": "# 00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n# Dificultad: Fácil | Publicación: 26/12/23 | Corrección: 02/01/24\n\n# Crea un comentario en el código y coloca la URL del sitio\n# web oficial del lenguaje de programación que has seleccionado.\n\n# La url del sitio oficial de python es: https://www.python.org\n\n# Representa las diferentes sintaxis que existen de crear\n# comentarios en el lenguaje (en una línea, varias...).\n\n# Esto es un comentario en una línea\n\n'''Esto es un \ncomentario\nen varias \nlineas'''\n\n# Crea una variable (y una constante si el lenguaje lo soporta).\n\n# Declaración de una variable\nmi_edad_actual = 44\n# Declaración de una constante (Aunque el lenguaje no impide la modificación de valores a una variable, se suele poner en mayusculas...)\nMI_NOMBRE = \"TuruDev\"\n\n# Crea variables representando todos los tipos de datos primitivos\n# del lenguaje (cadenas de texto, enteros, booleanos...).\n\nmi_str = \"Estoy declarando un string\"\nentero = 44\ndecimal = 1.82\nbooleano = True\nmy_set = {\"hola\", \"juanjo\", 44}\ntuple = (\"hola\", 15, False)\nlista = [1, 15, 44]\ndiccionario = {\"pais\": \"España\", \"codigo_postal\": 28342}\ncomplejo = 4j + 5\n\n# Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/VSXR.py",
    "content": "# www.python.org\n\n# Comentario una linea\n\n\"\"\"\nComentario de\nvarias lineas\n\"\"\"\n\nvariable = 1\nCONSTANTE = 100\n\na = \"String\"\nb = 1\nc = 1.55\nd = True\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Vesubius.py",
    "content": "\"\"\"\n\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n \n \"\"\"\n\n\n#https://www.python.org/\n\n\n\n# One line comment\n\n\"\"\"\nmultiline \ncomment\n\"\"\"\n\n#var\nnum = 1\n\n\n# Data types\nmy_int = 1\nmy_float = 0.1\nmy_str = \"Hello Programming Challenges\"\nmy_bool = True\nmy_list = [1, 2, 3, 4, 5]\nmy_tuple = (1, 2, 3, 4, 5)\nmy_set = {1, 2, 3, 4, 5}\nmy_dictionary = {\"key1\": 1, \"key2\": \"value2\"}\nmy_null = None\n\n# List with all values\nlist_with_all = [my_int, my_float, my_str, my_bool, my_list, my_tuple, my_set, my_dictionary, my_null]\n\nprint(\"-----Python Data Types-----\")\nfor datatype in list_with_all:\n    print(type(datatype).__name__,)\n    print(\"-------------------\")\n\nprint(\"hello, python\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Vice29.py",
    "content": "# https://www.python.org/\n\n# Comentario en una linea\n\n\"\"\"\nEsto es un comentario en\nvarias lineas.\n\"\"\"\n'''\nHola esto es otra forma de hacer \nun comentario\nen varias \nlineas.\n'''\n\n\nvariable = \"Mi variable\"\nCONSTANTE = 2332\n\n# Tipos de datos primitivos\nnumber = 123\nfloat = 1.1\nstring = \"Hola\"\nboolean = True\n\n\nprint(\"Hola, python\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/VickAlck.py",
    "content": "# Este es un comentario con la URL del programa Python\n'''\nhttps://www.python.org/\n'''\n\n# Variable y contante\nvariable = 4\nCONSTANTE = 3.1416\n\n# Datos primitivos de Python\nentero = -6\nflotante = 12.358\ncadena_texto = 'Python'\nbooleano = True\nnulo = None\n\n# Impresión en terminal\nprint(f'¡Hola, {cadena_texto}!')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/VictorE16.py",
    "content": "#Reto No.1 Retos de programacion Roadmap 2024\n\n# https://www.python.org/\n\n#Comentario de una linea en python\n\n\"\"\"\nEste es un comentario\npara varias lineas\nen python\n\n\"\"\"\n\n'''\nAsi tambien se puede\nrealizar un comentario\nde varias lineas\nen python\n'''\n\nmy_variable = \"Mi variable\"\n\nMY_CONSTANT = \"Mi constante\" #Por convencion\n\nmy_string = \"Este es un string\"\nmy_int = 16\nmy_float = 0.5\nmy_boolean = True\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/VictorJaimesR.py",
    "content": "#https://www.python.org/\n\n#En una línea\n\n\"\"\"\nEn varias líneas\n\"\"\"\n\nmy_variable= \"Mi variable\"\nmy_variable= \"Nuevo valor de mi variable\"\n\nMY_CONSTANTE= \"MI CONSTANTE\"\n\nmy_int= 1\nmy_float= 1.5\nmy_bool= False\nmy_string= 'Mi cadena'\nmy_string2= \"Mi cadena 2\"\n\nprint(\"Hola Python\")\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/VictorRivero1204.py",
    "content": ""
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/VictorZm0h.py",
    "content": "#https://www.python.org/\r\n\r\n#Esto es un comentario\r\n\"\"\"\r\nEsto tambien es un comentario\r\n\"\"\"\r\n\r\n'''\r\nEsto tambien es un comentario\r\n'''\r\n\r\nvariable1= \"Esto es una variable\"\r\nCONSTANTE= \"Esto es una constante\" # En Python no hay constantes, pero se suele usar mayúsculas para indicar que no debe cambiar\r\n\r\n#Tipos de datos primitivos\r\nentero= 10 #int\r\nflotante= 10.5 #float\r\nbooleano= True #bool\r\ncadena= \"Hola Mundo\" #str\r\nlista= [1, 2, 3] #list\r\ntupla= (1, 2, 3) #tuple\r\ndiccionario= {\"clave1\": \"valor1\", \"clave2\": \"valor2\"} #dict\r\nconjunto= {1, 2, 3} #set\r\n\r\nvariable2= \"¡Hola, Python!\"\r\n\r\nprint(variable2)\r\n\r\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/VomsAVC.py",
    "content": "# #00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n\n# Ejercicio\n# Lo primero... ¿Ya has elegido un lenguaje?\n# - Crea un comentario en el código y coloca la URL del sitio web oficial del\n#   lenguaje de programación que has seleccionado.\n\n# https://www.python.org/\n\n# - Representa las diferentes sintaxis que existen de crear comentarios\n#   en el lenguaje (en una línea, varias...).\n\n# La forma correcta y recomendada para varias líneas de comentario es repetir # en cada línea:\n# Esto es un comentario de varias líneas\n# Otra línea de comentario\n# Luego están las triple comillas (\"\"\" o '''), pero ojo: no son comentarios, son strings multilínea.\n\"\"\"\nEsto NO es un comentario real.\nEs una cadena de texto que no se usa.\n\"\"\"\n# Python las ignora solo si no están asignadas a nada, pero técnicamente crea un string\n# Resumen: \n# Una línea → #\n# Varias líneas → # en cada línea\n# Documentación → \"\"\" docstring \"\"\"\n# Comentarios tipo /* */ → no existen en Python\n\n    \n# - Crea una variable (y una constante si el lenguaje lo soporta).\nmi_var = 13\nMI_CONST = 3.14  # En Python no hay constantes reales, pero se usa esta convención\n\n\n# - Crea variables representando todos los tipos de datos primitivos\n#   del lenguaje (cadenas de texto, enteros, booleanos...).\n\n# En Python no se habla oficialmente de “primitivos” como en C o Java, pero sí hay un conjunto de tipos básicos integrados (built-in types) que cumplen ese papel. Según la documentación oficial de Python, los fundamentales son estos:\nmi_string = \"Hola\" # str cadenas de texto (unicode)\nmi_entero = 42 # int\nmi_flotante = 3.14 # float\nmi_booleano = True # bool valores lógicos booleano true/false\nmi_bytes = b\"Hola\"          # bytes secuencia inmutable de bytes\nmi_bytearray = bytearray(b\"Hola\")  # bytearray secuencia mutable de bytes\nmi_none = None # NoneType valor nulo o ausencia de valor\n\n# - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/WinstonS6079.py",
    "content": "#Esta es la URL oficial del lenguaj de programación Python:\n#https://www.python.org/\n\n#Comentario en una línea\n\n\"\"\"\nEste es un comentario\nen varias líneas con comillas dobles\n\"\"\"\n\n''' \nEste es un comentario\nen varias líneas con comillas simples\n'''\n\nmy_int = 777 # Tipo de dato entero\nmy_string = \"Hola, Mundo\" # Tipo de dato cadena de texto\nmy_float = 3.14 # Tipo de dato flotante\nmy_bool = True # Tipo de dato booleano\nmy_otherstring = 'Hola, Mundo'\n\nMI_CONSTANTE = 3.1416  # Convención para constantes escrito en mayúsculas ya que no se deben modificar.\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Xhinto.py",
    "content": "\"\"\"\nCrea un comentario en el código y coloca la URL del sitio web oficial del\nlenguaje de programación que has seleccionado.\n\"\"\" \n# https://www.python.org/\n\n\n\"\"\"\nRepresenta las diferentes sintaxis que existen de crear comentarios\nen el lenguaje (en una línea, varias...).\n\"\"\"\n#Este es un comentario en una línea\n\"\"\"\nEste es un comentario\nen varias líneas\n\"\"\"\n\n\n\"\"\"\nCrea una variable (y una constante si el lenguaje lo soporta).\n\"\"\"\nmy_variable = \"hola\"\n\n\n\"\"\"\nCrea variables representando todos los tipos de datos primitivos \ndel lenguaje (cadenas de texto, enteros, booleanos...).\n\"\"\"\nmy_string = \"Hola Mundo\"\nmy_int = 0\nmy_float = 10.5\nmy_boolean = False\n\n\"\"\"\nImprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\"\"\"\nprint(\"¡Hola, Python!\")\n\n\n\n \n \n "
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/XtinaRita.py",
    "content": "# https://python.org\n\n# Comentario en una línea\n\n\"\"\"\nEsto es un comentario\nen varias líneas\n\"\"\"\n\nmy_var = \"Mi Variable\"\n\nMY_CONST = \"Mi constante\" # En realidad, no existen constantes en python\nMYY_CONST = \"Mi constante ha cambiado\"\n\nmy_int = 12\nmy_float = 3,15\nmy_bool = True\nmy_string = 'Mi cadena de texto'\n\nprint(\"¡Hola, Python!\")\nprint(type(my_int))\nprint(type(my_float))\nprint(type(my_bool))\nprint(type(my_string))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/YCmorejon.py",
    "content": "# Visita la documentación oficial en: https://www.python.org\n\n# --------------------------------------------------\n# COMENTARIOS EN PYTHON\n# --------------------------------------------------\nprint(\"\\n--- COMENTARIOS EN PYTHON ---\")\n\n# Esto es un comentario de una línea (usando #)\n\n\"\"\"\nEste es un comentario multilínea\nusando comillas dobles triples\nPuede abarcar múltiples líneas\n\"\"\"\n\n'''\nEste también es un comentario multilínea\nusando comillas simples triples\nIgualmente válido en Python\n'''\n\n# --------------------------------------------------\n# VARIABLES Y CONSTANTES\n# --------------------------------------------------\nprint(\"\\n--- VARIABLES Y CONSTANTES ---\")\n\n# Creando una variable (nombre en minúsculas)\nvariable = \"Dato\"\nprint(f\"Variable normal: {variable}\")\n\n# Creando una constante (por convención se usa MAYÚSCULAS)\nCONSTANTE = \"Valor que no debería cambiar\"\nprint(f\"Constante (por convención): {CONSTANTE}\")\n\n# Nota: En Python no existen constantes inmutables realmente,\n# pero por convención usamos MAYÚSCULAS para indicar que no deberían modificarse\n\n# --------------------------------------------------\n# TIPOS DE DATOS BÁSICOS\n# --------------------------------------------------\nprint(\"\\n--- TIPOS DE DATOS BÁSICOS ---\")\n\n# Cadena de texto (str)\ntexto = \"Hola Mundo\"  # Usando comillas dobles\nprint(f\"String (str): {texto} - Tipo: {type(texto)}\")\n\n# Número entero (int)\nentero = 42\nprint(f\"Entero (int): {entero} - Tipo: {type(entero)}\")\n\n# Número decimal (float)\ndecimal = 3.1416\nprint(f\"Decimal (float): {decimal} - Tipo: {type(decimal)}\")\n\n# Valores booleanos (bool)\nverdadero = True\nfalso = False\nprint(f\"Booleanos (bool): {verdadero} y {falso} - Tipos: {type(verdadero)} y {type(falso)}\")\n\n# --------------------------------------------------\n# IMPRESIÓN EN CONSOLA\n# --------------------------------------------------\nprint(\"\\n--- IMPRESIÓN EN CONSOLA ---\")\n\n# Usando f-strings (formato moderno, Python 3.6+)\nnombre_lenguaje = \"Python\"\nprint(f\"Hola {nombre_lenguaje}!\")\n\n# Formas alternativas de imprimir\nprint(\"Hola\", nombre_lenguaje)  # Múltiples argumentos\nprint(\"Hola {}\".format(nombre_lenguaje))  # Método format"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/YamiYugi25.py",
    "content": "# Author: Andrés Orozco https://github.com/YamiYugi25\n\"\"\" \n * EJERCICIO:\n * 1. Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * 2. Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * 3. Crea una variable (y una constante si el lenguaje lo soporta).\n * 4. Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * 5. Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\"\"\"\n\n# Ejercicio 1\n\n# Esto es un comentario https://www.python.org\n\n# Ejercicio 2\n\n#En una linea \n\n\"\"\" Esto\nEs\nUn\nComentario\nDe Varias lineas\"\"\"\n\n# Ejercicio 3\n\n\"Para python las constantes no existe para eso se usa todo el texto en mayuscula simplemente para diferenciarlas (solo por sintaxis) \"\n\nYOSOYTUPADRE = 1\nvar = 25\n\n# Ejercicio 4\n\n# Número punto flotante (Float)\nfloat_numero = 3.14\n\n# Número Entero (int)\nint_numero = 5\n\n# (str)\nstring_texto = \"Hola mundo\"\n\n#Booleanos (bool)\nboolean_True = True\nboolean_False = False\n\n#(Nonetype)\nNulo = None\n\n# Ejercicio 5\nprint(\"¡¡Hola Python!!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/YeisonGil.py",
    "content": "\n#? Comentario\n# https://www.python.org/\n\n#? Comentario MULTILINEA\n'''\nEsto es un\ncomentario\nMultilinea\nTambien se puede con las comillas dobles en python\n'''\n\n#? Variables\nnombre = \"Yeison\"\nprint(nombre)\n\n#? Variable \"snake_case\"\nnombres_y_apellidos = \"Yeison Gil Alzate\"\nprint(f\"Nombres y Apellidos: {nombres_y_apellidos}\")\n\n#? Constante\n'''\nLas constantes en python se crean\nigual que una variable normal\npero se pueden crear en \nMAYUSCULAS para diferenciarlas\nde las variables.\nCabe aclarar que las variables\ncomo lo dice su nombre pueden\n\"variar\" a diferencia de las\nconstantes que es un valor \nunico y no es buena practica \nrenombrarlas.\n'''\n\n#? Constante UPPER_SNAKE_CASE\nFECHA_DE_NACIMIENTO = \"07/09/2001\"\nprint(FECHA_DE_NACIMIENTO)\n\n#?Variables DATOS_PRIMITIVOS\n#* Tipo entero (int)\nedad = 21\nprint(edad)\n#* Tipo flotante \"decimales\" (float)\nPI = 3.1416\nprint(PI)\n#* Tipo texto (string)\nsaludo = \"Hola, ¿Como estas? \"\nprint (saludo)\n#* Tipo booleano (boolean)\nverdadero = True\nfalso = False\n#* Tipo Nulo (NoneType)\nresultado = None\n\n#? Imprimiendo texto + nombre del lenguaje\nnombre_lenguaje = \"Python\"\nprint(f\"¡Hola {nombre_lenguaje}¡\")\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/YetlaneziLS.py",
    "content": "# https://python.org\n\n# Esto es un comentario de una sola línea\n\n\"\"\"Esto es\nun comentario\nde varias líneas\"\"\"\n    \nvariable = \"Esto es una variable\"\nCONSTANTE = \"\"\"En Python, no existen las constantes como tal\npor lo que se tiene que poner en mayúsculas\"\"\"\n\ncadena_texto = \"Hola, soy una cadena de texto\"\n\nentero = 32\n\nflotantes = 32.5\n\nbooleano_positivo = True\n\nbooleano_negativo = False\n\nprint (\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/YgriegaSB.py",
    "content": "\n# https://www.python.org/\n\n\n\"\"\"\nMultiple Lines\n\"\"\"\n\nvariable = 'variable'\nprint(variable)\n\nx = 42\nprint(type(x))  # <class 'int'>\n\ny = 3.14\nprint(type(y))  # <class 'float'>\n\nz = True\nprint(type(z))  # <class 'bool'>\n\ns = \"Hola\"\nprint(type(s))  # <class 'str'>\n\nl = 'Python'\n\nc = 3 + 2j\nprint(type(c))  # <class 'complex'>\n\nprint(f'{s}, {l}')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Yisusocanto.py",
    "content": "#https://www.python.org/\n\n#esto es un comentario de una sola linea\n\n'''\nesto es un comentario multilinea\ntambien se pueden usar las doble comillas \"\"\"\npero se tiene que abrir y cerrar con el mismo tipo de comilla\n'''\n\nmi_variable = \"mi variable\"\n\nMY_CONSTANT = \"mi constante\"\n\n#variables para cada tipo de datos primitivos\n\nvar_str = \"cadena de texto\"\nvar_int = 5\nvar_float = 8.5\nvar_bool1 = True\nVar_bool2 = False\n\nprint(\"¡Hola, python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/YorjanVarela.py",
    "content": "#https://www.python.org/ url del sitio oficial de python\n\n#comemtario de una línea \n\n\"\"\"\ncomentario \nde\n varias lineas\n\n\n\"\"\"\nvariable = \"variable\"\nCONSTANTE = 99 #sengún investigue se acostumbra a colocar las constantes en mayúsculas\n\n#tipos de variables primitivas\n\nstring = \"hola soy una variable string\" #o cadena de texto\nstrign = 'hola soy una variable string'\nstring_2 = \"\"\"hola soy una variable string\nen varias lineas\"\"\"\n\nbooleano = True or false #valores de verdadero o falso\nint = 33 #un entero \nfloat = 33.33 #un flotante o decimal\n\nlista = [1,2,3,4,5]\ntupla = (1,2,3,4,5)\ndict = {\"llave1\":1, \"llave2\":2, \"llave3\":3, \"llave4\":4, \"llave5\":5}\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Younes0-0.py",
    "content": "# Documentación: https://docs.python.org/es/3/\n\n# Comentario de una línea\n\n\"\"\"\nComentarios \nde varias\nlíneas\n\"\"\"\n\n'''\nComentarios \nde varias\nlíneas\n'''\n\n# Variables: no existe una palabra reservada para declarar una variable solo hay que escribirla en minúscula y en snake_case\nstring = \"hola\"\nmy_variable = \"Hola Python\"\n\n# Constantes\n# No hay constantes en Python, pero sí hay forma de declarar una constante y esperar a que los demás respeten.\nimport math \nCONSTANTE = math.pi\n\n# Integer ( int )\nentero = 1\n\n# Float ( float )\nflotante = 1.5\n\n# Boolean ( bool ) \nverdadero = True\nfalso = False\n\n# String ( str )\ncadena_doble = \"Cadena de caracteres \"\ncadena_simple = 'Cadena de caracteres'\n\n# None\nnada = None\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Ysmoraa.py",
    "content": "#Web Oficial\n#https://www.python.org/\n\n#Comentario de una sola linea\n\n\"\"\"Comentario de varias lineas\"\"\"\n\n\"\"\"Otra forma de poner comentarios de varias lineas\"\"\"\n\n\n#Crear una variable\nmyvariable = ''\n\n\"\"\"en Python no hay una palabra para definir una constante solo se definen de manera especifica\"\"\"\n#Crear una constante\npi = 3.1416\n\n#Tipos de datos nativos\n\n\"\"\"en Python no hay una palabra para definir el tipo de datos Python lo detecta solo\"\"\"\n\n#int\n\nentero = 8\n\n#float\n\nflotante = 8.8\n\n#bool\n\nboleano = True\n\n#str\n\ntexto = \"Hola, Python\"\n\n#none type\n\nno = None\n\nprint (texto)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/YulioBNO.py",
    "content": "#https://www.python.org\n\n#En una línea\n\n\"\"\"\nEsto es un\ncomentario\nen varias líneas\n\"\"\"\n\n'''\nOtra forma de \nhacer comentarios\n'''\n\nmy_variable = \"Una variable random\" #Variable\n\nMY_CONSTANT = \"Constante\" #Convención\n\nmy_int = 4 #un numero entero definido\n\nmy_float = 4.432 #un numero decimal definido\n\nmy_bool = True #un valor booleano definido como verdadero\nmy_bool2= False #Un booleano definido como falso\n\nmy_string = \"Un texto\" #Una cadena de texto\n\nmy_other_string = 'Otro texto' #Otra cadena de texto\n\nprint(\"Texto completamente general\") #Imprime en consola\n\nprint(my_variable) #Imprime el valor de la variable\nprint(MY_CONSTANT) #Imprime el valor de la constante\nprint(my_int) #Imprime el valor del entero\nprint(my_float) #Imprime el valor del decimal\nprint(my_bool) #Imprime el valor del booleano verdadero\nprint(my_bool2) #Imprime el valor del booleano falso\nprint(my_string) #Imprime el valor de la cadena de texto\nprint(my_other_string) #Imprime el valor de la otra cadena de texto"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/ZAKKDRTE.py",
    "content": "#  https://www.python.org/\n\n# Este es un comentario.\n\n\"\"\"\nEste es un comentario\nen varias\nlíneas\n\"\"\"\n\n'''\nEste también es otra forma k\nde poner \nun\ncomentario \nen varias \nlíneas \n'''\n\n# Creación de una variable\n\nmy_variable = \"\"    \n\n# Tipos de variables\n\nmy_string = \"My String in Python\"\nprint(type(my_string))  # Tipo de variable\nprint(my_string)    # Impresión de la variable\n\nmy_int = 13\nprint(type(my_int))\nprint(my_int)\n\nmy_float = 1.3\nprint(type(my_float))\nprint(my_float)\n\nmy_complex = 1j\nprint(type(my_complex))\nprint(my_complex)\n\nmy_boolean = True \nprint(type(my_boolean))\nprint(my_boolean)\n\nmy_list = []\nprint(type(my_list))\nprint(my_list)\n\nmy_tuple = ()\nprint(type(my_tuple))\nprint(my_tuple)\n\nmy_sets = {\"It is set\"}\nprint(type(my_sets))\nprint(my_sets)\n\nmy_dictionary = {}\nprint(type(my_dictionary))\nprint(my_dictionary)\n\n# Cambiar tipos de datos a otro tipo de dato\n# OJO ASI TAMBIÉN SE PUEDE DEFINIR UNA VARIABLE A ESE TIPO DE DATO, ES DECIR, ES LO MISMO \"LIST() == []\", \"TUPLE() == ()\", \"SET() == {}\"\n\nconvert_to_str = str()\nconvert_to_int = int()\nconvert_to_float = float()\nconvert_to_complex = complex()\nconvert_to_bool = bool()\nconvert_to_list = list()\nconvert_to_tuple = tuple()\nconvert_to_set = set()\nconvert_to_dictionary = dict()\n\nlanguage = \"Python\"\nprint(\"Hola %s\" %(language))"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Zeraven09.py",
    "content": "\"\"\"/*\n* EJERCICIO:\n* - Crea un comentario en el código y coloca la URL del sitio web oficial del\n*   lenguaje de programación que has seleccionado.\n* - Representa las diferentes sintaxis que existen de crear comentarios\n*   en el lenguaje (en una línea, varias...).\n* - Crea una variable (y una constante si el lenguaje lo soporta).\n* - Crea variables representando todos los tipos de datos primitivos\n*   del lenguaje (cadenas de texto, enteros, booleanos...).\n* - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n*\n* ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n* debemos comenzar por el principio.\n*/\"\"\"\n\n#https://www.python.org/\n\n#Este es un comentario en una línea\n\n\"\"\"\nEste es un comentario\nque puede ser escrito\nen varias líneas\n\"\"\"\n\n'''\nEste también es un comentario\nque puede ser escrito\nen varias líneas\n'''\n\nvariable = \"Esta es una variable que contiene un string\"\n\nCONSTANTE = \"Esta es una variable que debe ser tratada como constante\" #Por convención se escriben en mayúsculas las variables que se desea sean tratadas como constantes\n\nvariable_string = \"variable tipo string\"\n\nvariable_integer = 1\n\nvariable_float = 1.5\n\nvariable_boolean = True\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Zerek247.py",
    "content": "# https://www.python.org/\n\n# Esta es una primera forma para comentar una linea en python\n\n# Esta es la primera línea comentada\n# Esta es la segunda línea comentada\n# Esta es la tercera línea comentada\n\n\"\"\"\nEste es un comentario\nmultilínea que abarca\nvarias líneas\n\"\"\"\n\n'''\nEste es un comentario\nmultilínea que abarca\nvarias líneas.\n'''\n\n# Crear una variable\nmi_variable = 42\nprint(mi_variable)\n\n# Crear una \"constante\" por convención\nMI_CONSTANTE = 3.14159\nprint(MI_CONSTANTE)\n\n\n# Cadena de texto (String)\nmi_cadena = \"Hola, mundo\"\nprint(mi_cadena)\n\n# Entero (Integer)\nmi_entero = 42\nprint(mi_entero)\n\n# Número de punto flotante (Float)\nmi_flotante = 3.14159\nprint(mi_flotante)\n\n# Booleano (Boolean)\nmi_booleano = True\nprint(mi_booleano)\n\n# Número complejo (Complex)\nmi_complejo = 1 + 2j\nprint(mi_complejo)\n\n# Ningún valor (NoneType)\nmi_none = None\nprint(mi_none)\n\n#Imprimiendo el texto con el lenguaje seleccionado\nprint(\"¡Hola, Python!\")\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/ZyoDev1.py",
    "content": "# Sitio web oficial de Python: https://www.python.org/\r\n\r\n# Este es un comentario en una línea. Con el Símbolo #\r\n\r\n\"\"\"Comentarios de múltiples líneas:\r\nSe pueden escribir entre comillas triples.\r\n\"\"\"\r\n\r\n# Crear una variable\r\nnombre_lenguaje = \"Python\"\r\n\r\n# Python no tiene constantes\r\n\r\n# Crear variables de todos los tipos de datos primitivos:\r\ncadena_texto = \"¡Hola, Python!\"    # String\r\nnumero_entero = 42                 # Int\r\nnumero_flotante = 3.14159          # Float\r\nvalor_booleano = True              # Bool\r\nnumero_complejo = 1 + 2j           # Complex\r\n\r\n# Imprimir el texto solicitado\r\nprint(f\"¡Hola, {nombre_lenguaje}!\")\r\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/Zzepu.py",
    "content": "# https://www.python.org/\n\n# Comentario en una linea\n\n\"\"\"\nHe aqui un\ncomentario en\nvarias lineas\n\"\"\"\n\nsweet_variable = 'Hello World!'\nsweet_variable = 'New value'\n\nSWEET_CONSTANT = 'Hi folks!'\n\nsweet_int = 10\nsweet_float = 4.20\nsweet_bool = True\nsweet_bool = False\nsweet_string = 'i am tired boss'\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/a-mayans.py",
    "content": "# https://www.python.org/\n\n# esto es un comentario en una línea \n\n''' \nCon tres comillas simples\npodemos realizar comentarios\nen varias lineas\n'''\n\n\"\"\"\nTambien lo podemos realizar\ncon comillas dobles\n\"\"\"\n\n# crear una variable\nnombe = 'Alejandro'\n# constante\nPI = 3.14\n\n# tipos de datos primitivos. Python dispone de 4:\nun_string = 'cadena'\nun_integer = 27\nun_float = 27.27\nun_boolean = True\n\n# imprimir por terminal un mensaje\nlenguaje = 'Python'\nprint(f\"¡Hola, {lenguaje}!\")\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/aBoredLlama.py",
    "content": "# Lenguaje de programación escogido para el reto: Python (https://www.python.org/)\n\n# Tipos de comentarios en Python:\n\n# Comentario de una línea\n\n\"\"\"\nComentario de\nvarias líneas\n\"\"\"\n\n'''\nComentario de\nvarias líneas\n'''\n\n# Declaración de variables en Python:\n\nstring = \"Hola mundo\"\nstring2 = \"Hola otra vez\"\ninteger = 2\nfloat = 4.255\nboolean1 = True\nboolean2 = False\n\n# Imprimir en pantalla:\n\nprint(\"¡Hola, Python!\")\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/aDogdev.py",
    "content": "#  URL del lenguaje seleccionado: https://es.python.org/\n\n# con una almohadilla podemos hacer un comentario en línea como este\n\n'''\ny si lo envolvemos entre \ntres comillas se convierte \nen un comentario de varias líneas\n''' \n\n# variable, se escriben por convención en snake_case\nfirst_name = 'Adrian'\n# constante, no existen en python, pero pueden representarse por convención en mayúsculas\nCONSTANT_PI = 3.14\n\n# tipos de datos primitivos\nstring = 'cadena de texto'\nstring = \"cadena de texto\"\nint = 24\nfloat = 170.5\nboolean = True\nboolean = False\n\n# imprimir un mensaje por la terminal\nprint('¡Hola, Python!')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/abascal92.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\n \"\"\"\n\n# Python\n\"https://www.python.org/\"\n\n# Comentario de una línea\n\n\"\"\"\nComentario\nen\nvarias\nlíneas\n\"\"\"\n\n'''\nComentario\nen\nvarias\nlíneas\n'''\n\n# Variables\nname = \"Alejandro\" \nname = \"Alvaro\"\n\n# No existen constantes en Python, pero por convención se escriben en mayúsculas\nCONSTANT_PI = 3.14\n\n# Tipos de datos primitivos\nstring = \"cadena de texto\"  # str\ninteger = 2                 # int\nfloat = 174.5               # float\nbool = True                 # bool\nbool = False                # bool\nmy_string = \"Hola\"          # str\nmy_other_string = \"Python\"  # str\n\n# Imprimir mensaje por terminal\nprint(f\"¡{my_string}, {my_other_string}!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/acobo3.py",
    "content": "# https://www.python.org/\n# puedes comentar así\n\n\"\"\"\ntambién puedes comentar así\nen varias líneas\n\"\"\"\n\n# asignamos una variable y una constante\nx = 3\nCONSTANTE = 55\n\n# creamos variables representando los tipos de dato primitvos\nentero = 9 #integer\ndecimal = 6.7 #float\ntexto = \"esto es un texto\" #string\nverdadero = True #boolean\n\n# vamos a imprimer por terminal el texto \"Hola Python\"\nprint(\"Hola Python\")\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/adcarret.py",
    "content": "#esta es la URL del lenguaje elegido: https://es.python.org/ ESTO ES UN COMENTARIO EN LINEA\r\n\"\"\"\r\nEsto es un comentario en bloque\r\nAqui podemos escribir todas las lineas que queramos.\r\nSe usan con tres comillas\r\n\"\"\"\r\n\r\n#declaramos una variable\r\nnumero = 5\r\n#declaramos una variable constante. No hace falta ponerle final como en java, simplemente el nombre en mayusculas.\r\nPI = 3.14\r\n\"\"\"\r\nCrea variables representando todos los tipos de datos primitivos\r\n del lenguaje (cadenas de texto, enteros, booleanos...).\r\n\"\"\"\r\n\r\ncadena = \"Esto es una cadena de texto\"\r\nnumeroEntero = 5 #esto es una variable de numero entero\r\nnumeroNegativo = -7\r\nnumeroDecimal = 3.2 #esto es una variable de numero decimal\r\nlenguaje = \"Python\"\r\nboolean = True #esto es un booleano\r\n#ahora imprimimos el tipico hola con nuestro lenguaje\r\nprint(\"¡Hola, \" + lenguaje + \"!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/adolfolozaa.py",
    "content": "# https://www.python.org/\n\n\"\"\"\ncomentario en varias lineas\n\"\"\"\n''' tambien es un comentario\n'''\nvariable = \"esta es una variable\"\nvariable = \"Nuevo valor a variable\"\nconstantes = \"no hay constantes en python\"\n# constantes por convencion se nombran con mayusculas\nMI_CONSTANTE = \"CONSTANTE\"\ntexto =\"esto es texto\"\nentero = 3\ndecimal = 3.0\nbooleano = False\nprint ('Hola, Python')\nprint(type(variable)\nprint(type(entero)\nprint(type(decimal)\nprint(type(booleano)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/adra-dev.py",
    "content": "\"\"\"\nEJERCICIO:\n- Crea un comentario en el código y coloca la URL del sitio web\noficial del lenguaje de programación que has seleccionado.\n- Representa las diferentes sintaxis que existen de crear\ncomentarios en el lenguaje (en una línea, varias...).\n- Crea una variable (y una constante si el lenguaje lo soporta).\n- Crea variables representando todos los tipos de datos primitivos\ndel lenguaje (cadenas de texto, enteros, booleanos...).\n- Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\nby adra-dev.\n\"\"\"\n\n# https://www.python.org/\n\n# This is a coment in line\n\n'''\nThis \nis \na multi\nline coment.\n'''\n\n\"\"\"\nThis \nis \nalso\na multi\nline coment.\n\"\"\"\n\nvariable = 'This is a variable'\n\nCONSTANT = 'This is a constant if you read pep8 documentation'\n\n# Crea variables representando los tipos de datos primitivos\n\nnone = None # Especial data type that has no value\nint = 5 # integral data type\nbool = True or False # logic or boolean data type\nfloat = 3.141592 # real data type\ncomplex = 3+5j # complex data type\nstr = 'Hello World!' # string data type\ntuple = (334, 87.156) # An arbitrary secuence of objects\nlist = [2, 4.5, 65] # An arbitrary secuence of objects that we can manipulate\nset = {\"grape\", \"kiwi\", \"tomatoe\"} # Like a list but elements can not repeat or be indexed\ndict= {'price': 34, 'product': 'console', 'stock': 2} # These represent finite sets of objects indexed by nearly arbitrary values.\n\n# See the entire list in: https://docs.python.org/3/reference/datamodel.html#set-types\n\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/adridlth.py",
    "content": "# EJERCICIO:\n\n# - Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n\n# https://www.python.org/\n\n# --------------------------------------------------------------------------------------------\n# --------------------------------------------------------------------------------------------\n\n# - Representa las diferentes sintaxis que existen de crear comentarios  en el lenguaje (en una línea, varias...).\n\n'''Esto es un comentario en Python\n\tcon varias líneas'''\n\n# --------------------------------------------------------------------------------------------\n# --------------------------------------------------------------------------------------------\n\n# - Crea una variable (y una constante si el lenguaje lo soporta).\n\nMY_CONSTANT = \"New constant\"\nmy_var = \"New variable\" \n\n# --------------------------------------------------------------------------------------------\n# --------------------------------------------------------------------------------------------\n\n# - Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n\ninteger = 10\nfloat = 10.5\nboolean = True\nstring = \"John\"\n\n# --------------------------------------------------------------------------------------------\n# --------------------------------------------------------------------------------------------\n\n# - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\nprint(\"¡Hola Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/adry2024Salt.py",
    "content": "# https://www.python.org/\n\n\"\"\"triples comillas dobles permite ingresasr\nsin  que se ejecute ningun comando\"\"\"\n\n'''tambien con estas comillas '''\nmi_var_str = \"hola\"\nmi_var_int = 254\nmi_var_float = 0.254\nmi_var_bool = True\nmi_var_bool2 = False\n\nprint(\"hola Python\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/aegpgrafologo.py",
    "content": "#RETO 00\n# https://python.org\n# Comentario en una sola linea\n\"\"\"\nComentario  lineas\nen varias\nlineas de codigo\n\"\"\"\n'''\nOtra forma de \ncomentar en \nmas de una linea\n'''\n# Variable tipo entero o integer.\nmy_codigo = 88 \n\n# El lenguaje Phyton no tiene constantes definidas, todo puede cambiar.\n# Por convencion se usa el nombre de una variable en mayuscula sostenida\nCONSTANTE = \"Faro\"\n\n# Tipos de datos primitivos (Hay cuatro tipos)\n\nentero_integer = 8\nfloat_decimal = 1.5\nbooleanos = True\nbooleanos1 = False\nstring_cadenatexto = \"FFF\"\n\n# Impresión texto por consola\nprint(\"!hola, Phyton¡\")\n\n# Por ser lenguaje debilmente tipado, es posible omprobar el tipo de dato, asi:\n\nprint(type(entero_integer))\nprint(type(float_decimal))\nprint(type(booleanos))\nprint(type(booleanos1))\nprint(type(string_cadenatexto))"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/agusrosero.py",
    "content": "# https://www.python.org/\n\n# Comentario de una linea\n\n'''\nComentario\nde\nmultiple lineas\n'''\n\nmi_variable = \"Hola\"\nMI_CONSTANTE = \"Python\"\n\nmi_cadena = \"Hola\"\nmi_booleano = True\nmi_entero = 10\nmi_flotante = 10.5\nmi_lista = [1,2,3,4,5]\nmi_tupla = (1,2,3,4,5)\nmi_diccionario = {\n    \"nombre\": \"Hernan\",\n}\n\nprint(f'¡Hola, {MI_CONSTANTE}!')\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/ainaragmt.py",
    "content": "# https://www.python.org/\n\n# Comentario en una línea\n\n\"\"\"\nComentario en\nvarias líneas\n\"\"\"\n\n'''\nEsto también es un\ncomentario en\nvarias líneas\n'''\n\nmy_str = \"variable\"\nmy_int = 0\nmy_float = 3.14\nmy_bool = True\n\nMY_CONSTANT = \"constant\" # Variable en mayúsculas = constante\n\nlanguage = \"Python\"\nprint(\"¡Hola, \" + language + \"!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/akrxb.py",
    "content": "#https://www.python.org/\n\n#Esto es un comentario en línea.\n\"\"\"\nEsto es un comentario en múltiples líneas. También se puede escribir con comillas simples.\n\"\"\"\n\n#Variables:\nx = 1 #int\ny = 1.0 #float\nverdadero = True #boolean  \nfalso = False #boolean\nprimera_cadena_de_texto = \"Hola, Python!\" #string (por convenio esta también sería una cte.)\n\nprint(\"Hola, Python!\")\nprint(primera_cadena_de_texto) #Es lo mismo que la línea de arriba.\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/alabacw74.py",
    "content": "'''\n# #00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n> #### Dificultad: Fácil | Publicación: 26/12/23 | Corrección: 02/01/24\n\nAuthor: Alfredo Aburto Alcudia: https://github.com/alabacw74\n\n## Ejercicio\n\n```\n/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n```\n'''\n\n# Ejercicio 1\n# Documentación oficial\n# https://python-docs-es.readthedocs.io/es/3.12/\n\n# Ejercicio 2\n\n\"\"\"\nEste es un comentario\nde varias líneas en Python.\nPuede abarcar múltiples líneas\nsin necesidad de agregar el carácter \"#\" en cada línea.\n\"\"\"\n\n'''\nTambien se pueden utilizar comillas simples \npara crear comentarios multilinea\n'''\n\n# Ejercicio 3\n\n'''\nEn python se incluyen valrores a muchas constantes universales, para hacer\nuso de ellas es necesario importar librerias por ejemplo, math.\n\nSi deseamos crear nuestras propias constantes podemos usar una sintaxis especial\nen la definición de nuestras variables, un ejemplo sería utilizar un nombre que\nsolo incluya letras mayusculas\n'''\n\nMICONSTANTE = 12.2545\nprint(f'La variable MICONSTANTE es de tipo {type(MICONSTANTE)}')\n\n\n# Ejercicio 4\n\n# Definición de variables nativas en Python\n\n# Numericas (int y float)\n\nnumero_entero = 27\nprint(f'La variable numero_entero es de tipo {type(numero_entero)}')\n\nnumero_decimal = 6.685\nprint(f'La variable numero_entero es de tipo {type(numero_decimal)}')\n\n# Texto (string)\ncaracter = \"Cadena de texto en Python\" # Podemos usar comillas simples o dobles\nprint(f'La variable caracter es de tipo {type(caracter)}')\n\n# Booleanas\naprendo_python = True\nprint(f'La variable aprendo_python es de tipo {type(aprendo_python)}')\n\n# Ejercicio 5\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/alberba.py",
    "content": "# https://www.python.org/\n\n# Esto es un comentario de una línea\n\n\"\"\" Esto es un comentario\n    de varias líneas\n    que se puede escribir\n\"\"\"\n\n'''Asi también se puede escribir\n    en distintas líneas'''\n\nvar = 1\nCONSTANTE = 5\n\ninteger = 8\nfloat = 8.5\nstring = \"Hola mundo\"\nboolean = True\n\nlenguaje = \"Python\"\nprint(f\"¡Hola, {lenguaje}!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/albertorevel.py",
    "content": "# @author Alberto Revel\n\n# Crea un comentario en el código y coloca la URL del sitio web oficial del\n\n# https://www.python.org/\n\n# Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n\n# Representa las diferentes sintaxis que existen\n# de crear comentarios en el lenguaje (en una línea, varias...).\n\n\"\"\"\nRepresenta las diferentes sintaxis que existen\nde crear comentarios en el lenguaje (en una línea, varias...).\n\"\"\"\n\n'''\nRepresenta las diferentes sintaxis que existen\nde crear comentarios en el lenguaje (en una línea, varias...).\n'''\n\na = 1 # Comment at the end\n\n\n# Crea una variable (y una constante si el lenguaje lo soporta).\nvar1 = 'Hello'\n\nFAKE_CONSTANT = 2024; # Constants doesn't exist in python, this is only a naming convention.\n\n# Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n# Data type of the variable can be inferred\nyear = 2024\nname = 'Alberto'\nage = 31.4\n\n# We can specify the data type of the variable too\nint_specified = int(2024)\nstr_specified = str(2024)\nfloat_specified = float(2024)\n\n# Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nprint(\"¡Hola, python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/alejandro-mantilla.py",
    "content": "# Comentario en una linea \n\n# https://www.python.org/\n\n\"\"\"\nEste es \nun comentario \nen varias lineas\n\"\"\"\n\n'''\nEste es \notro comentario\nen varias lineas\n'''\n\nvariable = \"Mi primera variable\"\nvariable = \"Nueva variable\"\n\nMY_CONSTANT = \"mi constante\" # Por convención\n\nint = 11\nfloat = 0.5\nboolean = True\nboolean = False\nstr = \"Hola Mundo\"\nother_str = 'Hello World'\n\nprint(\"¡Hola mundo, estoy haciendo este reto con Python!\")\n\n# Tipo de datos\nprint(type(int))\nprint(type(float))\nprint(type(boolean))\nprint(type(str))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/alejarandro.py",
    "content": "# https://www.python.org/\n\n# Este es el ejemplo de un comentario de una sola linea\n\n\"\"\"\nEste el el ejemplo \nde un comentario de \nvarias lineas\n\"\"\"\n\n# En Python las constantes no existen. La convención para nombrar constantes es hacerlo con el nombre todo en mayúsculas\n\nalumno = \"Alejandro \"\nMATERIA = \"Historia\"\n\n\n# Crea variables representando todos los tipos de datos primitivos del lenguaje (\n\nnombre = \"Alejandro\"  # String\nedad = 25  # Integers\nestatura = 1.86  # Floats\nes_alto = True  # Booleans\n\n\n# Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nprint(\"Hola, Python!!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/alejo-digital.py",
    "content": "# 00 Sintaxis, Variables, Tipos de Datos y Hola Mundo\n\n\"\"\"\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n \"\"\"\n\n# URL del sitio web oficial del lenguaje: https://www.python.org/\n\n# Comentarios en una línea\n# Este es un comentario en una línea\n\n# Comentarios en varias líneas\n\"\"\" \nEste es un comentario\nen varias líneas\n\"\"\"\n\n# Variable\nmi_variable = \"Hola, Python\"\n\n# Constante (en Python, por convención, se usa mayúsculas)\nMI_CONSTANTE = 42\n\n# Tipos de datos primitivos\ncadena_texto = \"Python\"\nentero = 100\nflotante = 3.14\nbooleano = True\nlista = [1, 2, 3]\ndiccionario = {\"clave\": \"valor\"}\nmy_byte = b\"byte\"\nmy_none = None\nprint(type(my_none))  # Verifica el tipo de dato\nprint(type(my_byte))  # Verifica el tipo de dato\nprint(type(diccionario))  # Verifica el tipo de dato\nprint(type(lista))  # Verifica el tipo de dato\nprint(type(booleano))  # Verifica el tipo de dato\nprint(type(flotante))  # Verifica el tipo de dato\nprint(type(entero))  # Verifica el tipo de dato\n\n# Imprimir el mensaje\nprint(f\"¡Hola, {cadena_texto}!\")  # Imprime el mensaje en la terminal\n\nMI_CONSTANTE = 33\nprint(MI_CONSTANTE) #Para confirmar que la constante se ha modificado\n\nprint(\"Fin del reto. ¡Sigue practicando y aprendiendo!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/alejomazov.py",
    "content": "### https://www.python.org/\n\n'''\nComentario en \nvarias lineas\n'''\n\n\"\"\"\n Comentario en\n varias lineas\n\"\"\"\n#Comentario en un alinea\n\nCONSTANTE = \"Mi primera constante\" # En python no existen las constantes, pero se suelen poner por convencion en mayusculas \nvariable = \"Mi primera variable\"\n\nstring = \"String\"\nentero = 2 # Se puede marcar tambien int(2)\nflotante = float(2.5) \nbooleano_false = False \nbooleano_true = True \nvalor_nulo = None\n\nprint (\"¡Hola, Python!\")\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/alejosor.py",
    "content": "\"\"\"\nSolución del reto #00: Sintaxis, variables, tipos de  datos y hola mundo;\n@ author: Alejosor\n\nEJERCICIO:\n- Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n- Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n- Crea una variable (y una constante si el lenguaje lo soporta).\n- Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n- Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\"\"\"\n\n# - Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado\n# URL del sitio web oficial de Python: https://www.python.org/\n\n# - Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n# Comentario en una línea\n\n\"\"\"\nComentario\nen varias líneas\n\"\"\"\n\n# - Crea una variable (y una constante si el lenguaje lo soporta).\n\n# Crear una variable\nsaludo = \"Holaa soy Alejosor\"\n\n# Crear una constante (En Python no hay soporte para constantes nativas, pero por convención se usa el nombre en mayúsculas)\nMI_CONSTANTE = 456.43\nPI = 3.141592653589793\n\n# - Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\ncadenaDeTexto = \"Tipo de dato: String\"\nentero = 50 # Tipo de dato: Int\ndecimal = 25.67 # Tipo de dato: Float\nbooleano = True # Tipo de dato: Boolean\n\n# - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nprint(\"¡Hola , Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/allbertoMD.py",
    "content": "# https://www.python.org\n# \n\"\"\"\nThis is a multiline comment in python.\nTypyng python.\n\"\"\"\n\n# Variables\nstr = \"I am a string\"\nint = 4\nfloat = 0.4\ndouble = 4.440044004400\nbool = False\n\n# Contants\nSTR = \"My name is Alberto\"\nINT = 12844987\nFLOAT = 3.14\nDOUBLE = 9.80665\nBOOL = True\n\n# Hello, World\nprint(\"Hello, World.\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/aloween.py",
    "content": "#https://www.python.org/\n#comentario en una linea\n\"\"\"\ncomentario en varias lineas\nHola\nMundo \n\n''''\nmas lineas \"\"\"\n\n'''\n#crear variables\n# en python no existe el concepto de constantes, pero en la comunidad se representan declarando una variable en mayusculas'''\n\nmi_variable= \"mi nombre es Alonso\"\n\nMY_CONSTANT = \"No cambiar el valor de una constante\"\n\n# Existen 4 tipos de datos primitivos!!! \nmy_int: int  = 10 # int es un numero entero ( podemos usar type hints para indicar el tipo de dato)\nmy_float: float = 2.5 # float es un numero decimal\nmy_oolean = True # boolean es un valor logico (True o False)\nmy_none = None # none es un valor nulo o ausencia de valor \nmy_string = \"Hola Mundo\" # string es una cadena de texto y podemos usar comillas simples o dobles.  \nprint(\"Hola \" + mi_variable)\nprint(\"Hola \" + \"https://www.python.org/\")\n\nprint(type(my_int))\nprint(type(mi_variable))\nprint(type(my_float))"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/anblackter.py",
    "content": "# Python official website https://www.python.org/\n\n# Single line comment\n\n# For a multiple line comment\n# we can use the same #\n# or we can use the multiple quotes but\n# according to PEP8, multiple quotes apply\n# for documentation string\n\n\"\"\"\nA multi-line comment\nor a documentation string\n\"\"\"\n\nvariable = 'Variable'\nCONST = 'contant'\n\nstring_variable = 'string_variable'\nnumeric_variable = 1\nboolean_variable = True\n\nprint('¡Hola, Python!')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/andres-54-coder.py",
    "content": "# Esta es la página oficial de mi lenguaje preferido, Python: https://www.python.org/\n\n# Podemos comentar en una línea\n\"\"\"\nTambién podemos comentar\nen varias lineas,\nlas que queramos\n:)\n\"\"\"\n\naño = 2024 # Esto es una variable\n\n# Las variables pueden ser de tipo int, float, string, boolean, etc.\nedad = 24 # int\naltura = 1.82 # float\npython_es_facil = True # Boolean\nnombre = \"Andres\" # string\ntipos_variables = \"\"\"\n1. Intiger\n2. Float\n3. String\n4. Boolean\n\"\"\" # Esta variable también es un string\n\n\n# Las variables también pueden ser de tipo lista, tupla, diccionario, etc.\nmi_lista = [1, 2, 3, 4, 5] # lista\nmi_tupla = (1, 2, 3, 4, 5) # tupla\nmi_diccionario = {\"clave1\": \"valor1\", \"clave2\": \"valor2\"} # diccionario\n\nlenguaje_preferido = \"Python\" # Definimos una variable con el nombre de mi lenguaje de programación preferido\n\nprint(f\"¡Hola, {lenguaje_preferido}!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/andresgcastillo.py",
    "content": "# Este es un comentario de una línea en Python\n# URL oficial de Python: https://www.python.org\n\n\"\"\"\nEste es un comentario multilínea en Python\n\"\"\"\n\n# Creación de una variable\nmi_variable = \"Hola, Python!\"\n\n# Python no soporta constantes de manera nativa, pero por convención, las variables en mayúsculas se tratan como constantes\nMI_CONSTANTE = \"Soy una constante\"\n\n# Variables representando todos los tipos de datos primitivos\ncadena = \"Esto es una cadena de texto\"\nentero = 10\nbooleano = True\nflotante = 10.5\n\n# Imprimir por terminal\nprint(mi_variable)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/andresmendozaf.py",
    "content": "# https://python.org\n\n# Esto es un comentario\n\n\"\"\"\nEsto se utiliza \npara realizar un comentario \nen varias líneas\n\"\"\"\n\n'''\nEsto también aplica \npara realizar comentarios \nde multilínea\n'''\n\nmi_variable = \"Una variable\"\nprint(mi_variable)\n\n#No existen constantes en python pero por convención se utilzan con mayúscula para darlo como constante\nUNA_CONSTANTE = \"Puede utilizarce como constante\"\nprint(UNA_CONSTANTE)\n\n#Cuatro son los datos primitivos \npri_int = 1\nseg_float = 1.5\nter_bool_t = True\nter_bool_f = False\ncuar_str = \"Cadena de texto\"\ncuar_string = 'También sirve con comillas simples'\n\nstr_saludo = \"Hola Mundo, Python!\"\nprint(str_saludo)\n\n#Para imprimir por consola los tipos de datos\nprint(type(pri_int))\nprint(type(seg_float))\nprint(type(ter_bool_t))\nprint(type(ter_bool_f))\nprint(type(cuar_str))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/angelsanchezt.py",
    "content": "# La URL del sitio web oficial de Python es: https://www.python.org/\n\n# Este es un comentario de una línea en Python. Puedes poner cualquier comentario aquí.\n\n\"\"\"\nPasos para Ejecutar un Script de Python: \n1. Instala Python: https://www.python.org/\n2. Abre la terminal o consola de comandos en tu sistema operativo.\n3. Navega al Directorio del Script:\n    cd roadmap-retos-programacion\\Roadmap\\00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\\python\n4. Ejecuta el script:\n    python angelsanchezt.py\n\"\"\"\n\n\"\"\"\nEste es un comentario\nde varias líneas\nen Python.\n\"\"\"\n\n# Variable\nmi_variable = 42\n\n# Constante (en Python no hay constantes, pero por convención se usan mayúsculas para indicar que una variable no debería cambiar)\nMI_CONSTANTE = 3.14\n\n# Tipos de datos primitivos\nentero = 10\nflotante = 3.14\ncadena = \"Hola, Python!\"\nbooleano = True\nlista = [1, 2, 3]\ntupla = (4, 5, 6)\ndiccionario = {\"clave\": \"valor\"}\n\n# Imprimir por terminal\nprint(\"¡Hola, Python!🐍\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/annnerssv.py",
    "content": "# ----COMENTARIOS-----\n\n#Sitio oficial del lenguaje python: https://www.python.org/\n\n#Este es un comentario de una sola linea\n\n'''Este es un \ncomentario de \nmultiples lineas'''\n\n\n# ----VARIABLES----\n\nmy_variable = \"Esta es una variable\"\nMY_CONSTANT = \"Esta es una constante\"\n\n# -----TIPOS DE DATOS PRIMITIVOS -----\n\nstring_variable = \"Esta es una Variable de tipo cadena\"\nint_varible = 5 #Esta es una variable de tipo entero\nbool_variable = True #Esta es una variable de tipo boleano(True/False)\nfloat_variable = 20.25 # Esta es una variable de tipo flotante\n\n\n# ---Impresion de saludo con el lenguaje a aprender -----\n\nlenguaje = \"Python\"\n\n#Impresion simple \nprint(\"!Hola estoy repasando\" + \" \" + lenguaje)\n\n#Con interpolacion\nprint(f\"!Hola estoy repasando {lenguaje}\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/ansuzgs.py",
    "content": "# https://www.python.org/\n\n# Comentario de una linea\n\n\"\"\"\nComentario\nde\nvarias\nlineas\n\"\"\"\n\n# Crear una variable\nmy_variable = \"Python\"  # Variable\n\n# Crear una constante\nMY_CONSTANTE = 3.14  # Constante (en eralidad no existe en Python)\n\n# Crear variables de diferentes tipos primitivos\nmy_int = 1  # Entero\nmy_float = 3.14  # Flotante\nmy_bool = True  # Booleano\nmy_string = \"Hola, Python\"  # Cadena de texto\n\n# Imprimir en consola\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/antii16.py",
    "content": "# https://www.python.org/\n\n# Una línea \n\"\"\"\nMultilínea\nRepresenta las diferentes sintaxis que existen de crear comentarios\nen el lenguaje (en una línea, varias...).\n\"\"\"\n\n# Variable y constante\nnombre = 'Anto' # variable\nPI = 3.14       # constante\n\n# Tipos de datos \n\nentero = 10\nflotante = 2.35\ncadena = 'amarillo'\nbooleano = False\n\n# Saludo\nprint('¡Hola, Python!')\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/antoniosuero.py",
    "content": "# https://www.python.org/\n\n# Comentario de una línea.\n\n\"\"\"\nEsto es un \ncomentario en \nvarias líneas.\n\"\"\"\n\n'''\nEsto también es un \ncomentario en\nvarias líneas.\n'''\n\nmi_lenguaje = \"Python\"  # Varialbe string\nmi_entero = 50  # Variable int\nmi_decimales = 3.5  # Variable float\nes_verdadero = True  # Varialbe bool\n\n\"\"\"\nLas constantes no existen en Python como tal. Sin embargo, por convención, \nse utilizan variables en mayúsculas para indicar que una variable debe ser \ntratada como una constante y no debe ser modificada.\n\"\"\"\nNUMERO_PI = 3.1416\n\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/any7dev.py",
    "content": "\"\"\" /*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */ \"\"\"\n\n# Web Oficial https://www.python.org/\n\n# Esto es un comentario\n\n\"\"\" Esto es un comentario\nen varios\nbloques\"\"\"\n\n'''Esta es otra forma de\ncrear un comentario\nen varias líneas'''\n\n# Variable global\nglobal variable\nvariable = \"x\"\n\n# Tipos de variables\nvar_int = 1\nvar_float = 0.5\nvar_string = \"Esto es una cadena de texto\"\nvar_string = 'Esta es otra cadena'\nvar_bool = True\n\nprint(\"¡Hola, Python\")\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/aritapia19.py",
    "content": "'''\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n '''\n\n#Este es mi primer reto de proramacion. Dejo la web oficial del programa que voy a utilizar. https://www.python.org/ \n\nprimer_variable = \"\"\nSEUDOCONSTANTE = \"\"\nnumero = 1\nletra = \"A\"\nbooleanos = True\ndecimal = 2,3\nprint(\"Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/arkmiguel379.py",
    "content": "# https://www.python.org/\n\n# Este es un comentario de una sola linea en Python\n\n'''Este es un comentario\nde varias lineas en Python'''\n\nmy_variable = \"Python\"\nMY_CONSTANTE = 3.14\n\nentero = 33\ncadena = \"Esto es una cadena de texto\"\nchar = 'a'\nbooleano = True\nflotante = 13.5\n\nlista = [1,2,3,4,5]\ntupla = (1,2,3,4,5)\nconjunto = {1,2,3,4,5}\ndiccionario = {\"nombre\":\"Miguel\", \"apellido\":\"Moreno\", \"alias\":\"Logan\", \"edad\":\"28\"}\n\nprint(f\"Hola {my_variable}\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/arturodlapaz17.py",
    "content": "#https://python.org\n\n# Comentario en una línea\n\n\"\"\"Esto es un \ncomentario en varias \nlineas\"\"\"\n\n'''Esto es otra \nfomar de comentar \nen Python en \nvarias lineas'''\n\nmi_variable = \"Mi Variable\"\nmi_variable =  \"Mi Nueva Variable\"\n\nMI_CONSTANTE = \"Mi Constatnte\" # por convención\n\nmi_integer = 1\n\nmi_float = 0.5\nmi_Boolean = True\nmi_Boolean = False\nmi_string  = \"Mi cadena de texto\"\nmi_otro_string = \"Mi otra cadena de texto\"\n\nprint(\"Hola Mundo\")\n\n# Imprime los tipos de datos\n\nprint(type(mi_float))\nprint(type(mi_integer))\nprint(type(mi_Boolean))\nprint(type(mi_string))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/aserranot.py",
    "content": "## El lenguaje que quiero aprender es Python\n## https://www.python.org\n\n# Los comentarios de una sola linea se realizan con una almohadilla al principo de la linea\n\n\"\"\" Si queremos\nhacer un cometario para\nmultiples lineas es necesario\nincluir triples comillas al principio\ny final del bloque \"\"\"\n\n## Ejemplo de variable\nname = \"Alejandro\"\n## Ejemplo de constante, una constante es una variable que no modifica su valor durante la ejecución, se declara en mayúsculas\nWEB = \"https://retosdeprogramacion.com\"\n\n## Tipos de datos primitivos\n# enteros (int)\nmes = 12\n# booleanos (bool)\nes_verdadero = True\n# flotantes (float) \npi = 3.1416\n# cadenas o strings\ncadena_string = \"Esto es una cadena o string\"\n\nprint(\"¡Hola, Python!\")\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/augustdev2003.py",
    "content": "# https://www.python.org\n\n# Este es un comentario en una línea\n\n\"\"\"\nEste es un\ncomentario en\nvarias líneas\n\"\"\"\n\n'''\nEste también es un\ncomentario en\nvarias líneas\n'''\n\nvariable = \"Esta es una variable\"\nCONSTANTE = \"Esta es una constante\"  # por convención\n\ntype_integer = 10\ntype_float = 32.4\ntype_string = \"Este es un string\"\ntype_string = 'Este también es un string'\ntype_boolean = True\ntype_boolean = False\n\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/augustosdev.py",
    "content": "# Sitio oficial de Python: https://www.python.org/\n\n# Comentario de una linea\n\n'''\nComentario \nde varias\nlineas\n'''\n\nnueva_variable = 'Esta es una variable'\n\npy_string = 'Este es un string'\npy_integer = 36\npy_float = 21.3\npy_boolean = True\npy_none = None\n\nprint('Hola, Python!')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/avcenal.py",
    "content": "#AUTOR: avcenal\n#LENGUAJE ELEGIDO: Python\n#URL: https://www.python.org\n\n\"\"\"\nComentario\nen varias\nlíneas\n\"\"\"\n#Comentario en una línea\n\nmy_variable = \"Hola Mundo\"\n#no existen constantes en Python\n\n\n#Variables básicas\nmy_integer = 39\nmy_float = 1.82\nmy_string = \"Hola Alex\"\nmy_boolean = True\nmy_complex_number = 1 + 4j\n\nmy_language = \"Python\"\nprint(f\"Hola {my_language}!!!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/axelprz.py",
    "content": "\"\"\" EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\" \"\"\"\n \n#URL del sitio web oficial de Python: https://www.python.org\n#Lenguaje seleccionado: Python\n#Estos son los distintos tipos de comentarios que existen en Python:\n\n\"\"\" Comentarios Inline\nLos comentarios inline proporcionan descripciones breves de variables y operaciones sencillas, y se escriben en la misma línea que la sentencia del código: \"\"\"\n\nx = 0\nborder = x + 10  # Haz un desplazamiento de 10px.\n\n\"\"\" Comentarios Block\nLos comentarios block se utilizan para describir la lógica compleja del código. Los comentarios block en Python se construyen de forma similar a los comentarios inline, la única diferencia es que los comentarios block se escriben en una línea aparte: \"\"\"\n\n#Realizar una suma\nx = 15 + 10\n\n\"\"\" Comentarios Multilínea\nPython no admite de forma nativa los comentarios multilínea, lo que significa que no hay ninguna disposición especial para definirlos. A pesar de ello, a menudo se utilizan comentarios que abarcan varias líneas.\n\nPuedes crear un comentario multilínea a partir de varios comentarios de una sola línea precediendo cada línea con #: \"\"\"\n\n#Sumar\n#Restar\n#Multiplicar\n#Dividir\n\n\"\"\" También puedes utilizar la sintaxis de cadenas multilínea. En Python, puedes definir cadenas de varias líneas encerrándolas entre comillas dobles triples, o comillas simples triples: \"\"\"\n\n\"\"\" \nEste \nString \nes \nMultilínea \n\"\"\"\n\n\"\"\"Variables y constantes en Python\"\"\"\n\n#Variable en Python:\nnumero = 10\n\n#Constante en Python\nNUMERO_DOCUMENTO = 12345678\n\n\"\"\"Tipos de variables en Python\"\"\"\n\n# Entero\nentero = 42\n\n# Punto flotante\nflotante = 3.14\n\n# Cadena de texto\ncadena = \"Hola, mundo!\"\n\n# Booleano\nbooleano = True\n\n# Lista\nlista = [1, 2, 3, 4]\n\n# Tupla\ntupla = (5, 6, 7, 8)\n\n# Conjunto\nconjunto = {9, 10, 11, 12}\n\n# Diccionario\ndiccionario = {\"clave1\": \"valor1\", \"clave2\": \"valor2\"}\n\n# None (tipo nulo)\nnulo = None\n\nprint(\"¡Hola, Python!\")\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/aztharoth87.py",
    "content": "# HTTP://PYTHON.ORG\n\n# COMENTARIO EN UNA LINEA\n\n\"\"\"\nAqui se puede ingresar\ncomentarios en varias\nlineas\n\"\"\"\n\n'''\nAqui tambien se puede ingresar\ncomentarios en varia\nlineas\n'''\n\nmi_variable = \"Mi variable\"\nmi_variable = \"Otro valor de mi variable\"\n\nMI_CONSTANTE = \"Mi constante\"  # por convención\n\nmi_int = 1\nmi_float = 1.5\nmi_bool = True\nmi_bool = False\nmi_string = \"Mi cadena de texto\"\nmi_otra_str = \"Mi otra cadena de texto\"\n\n\n\nprint (\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/baauus.py",
    "content": "# 1. Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n\n# https://www.python.org/\n\n# 2. Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n\"\"\"\nEsto es un comentario\nde varias lineas\n\"\"\"\n'''\nComentario de varias lineas\n'''\n# Comenmtario de una linea\n\n# 3. Crea una variable (y una constante si el lenguaje lo soporta).\nvariable = 3\nMY_CONSTANT = \"Valor constante\"\n\n# 4. Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\nentero = 4\nstring = \"Hola\"\nboolean = True\nfloat = 1.82\n\n# 5. Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/barrancus.py",
    "content": "# https://www.python.org/\r\n# Comentario simple\r\n'''Comentario en varias\r\nlíneas sin problemas'''\r\n\"\"\"Esta es otra forma\r\nde comentario en varias líneas\"\"\"\r\nfirst_var = ''\r\nvar_str = str(\"hello\")\r\nvar_int = int(1)\r\nvar_float = float(1)\r\nvar_bool = bool(0)\r\nvar_comp = complex(1j)\r\nMY_CONSTANT = \"CONSTANTE\" # por convención\r\nvar_leng = 'Python'\r\nprint(f'Hola {var_leng}!!!')\r\nprint(f'La variable definida \"{first_var}\" es de tipo: {type(first_var)}')\r\nprint(f'La variable definida \"{var_str}\" es de tipo: {type(var_str)}')\r\nprint(f'La variable definida \"{var_int}\" es de tipo: {type(var_int)}')\r\nprint(f'La variable definida \"{var_float}\" es de tipo: {type(var_float)}')\r\nprint(f'La variable definida \"{var_bool}\" es de tipo: {type(var_bool)}')\r\nprint(f'La variable definida \"{var_comp}\" es de tipo: {type(var_comp)}')\r\nprint(f'La constante definida {MY_CONSTANT} es de tipo: {type(MY_CONSTANT)}')\r\n\r\nvar_str = 1\r\nvar_int = True\r\nvar_float = \"pero que pasa\"\r\nvar_bool = 1+2j\r\nvar_comp = 3.25\r\nMY_CONSTANT = 3.14\r\n\r\nprint(f'La variable definida \"{first_var}\" es de tipo: {type(first_var)}')\r\nprint(f'La variable definida \"{var_str}\" es de tipo: {type(var_str)}')\r\nprint(f'La variable definida \"{var_int}\" es de tipo: {type(var_int)}')\r\nprint(f'La variable definida \"{var_float}\" es de tipo: {type(var_float)}')\r\nprint(f'La variable definida \"{var_bool}\" es de tipo: {type(var_bool)}')\r\nprint(f'La variable definida \"{var_comp}\" es de tipo: {type(var_comp)}')\r\nprint(f'La constante definida {MY_CONSTANT} es de tipo: {type(MY_CONSTANT)}')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/beonzj.py",
    "content": "# https://python.org/\n\n# Comentario de una sola línea\n\n\"\"\"\n    Este es un\n    comentario de\n    varias lineas\n\"\"\"\n\n'''\n    Esta es otra\n    sintaxis para\n    comentarios de \n    varias lineas\n'''\n\n# Creación de variables:\n\nvariable = \"Variable\"\nCONSTANT = \"Constante\"\n\n# Tipos de datos primitivos:\n\nstring = \"Cadena de texto\"\nint = 10\nfloat = 10.5\nboolean = True\nboolean = False\nfoo = None\n\n# Imprimir\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/betzadev.py",
    "content": "# La URL del sitio web oficial de Python 🐍 es: https://www.python.org/\n\n#--- Hay varias maneras de hacer cometarios en Python ---\n\n#Este es un comentario de una línea\n\"\"\"\nEn cambio, este es un cometario\nde varias líneas.\n\"\"\"\n'''\nTambién se pueden usar\ncomillas simples 😙\n'''\n\n# --- Al momento de crear variables en Python, la convención recomendada para nombrarlas es Snake Case.\n# --- En este estilo, los nombres de las variables se escriben en minúsculas y las palabras se separan por guiones bajos (underscore). Por ejemplo:\n\nmi_variable = \"¡Hola, soy una variable!\"\n\n# --- Tipos de datos en Python 😯\n\n#🔷 Entero:\n\nmi_entero = 22\n\n#🔷 Decimal:\n\nmi_decimal = 2,2\n\n#🔷 Booleanos:\n\nmi_booleano_verdadero = True\nmi_booleano_falso = False\n\n#🔷 String:\n\nmi_string = \"Soy una cadena de texto\"\n\n# Para imprimir texto por consola se utiliza print().\n\nprint(\"¡Hola, Python 🐍!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/bhairava11.py",
    "content": "# https://python.org\n\n# Comentario en una línea\n\n\"\"\"\nEsto también es\nun comentario\nen varias líneas\n\"\"\"\n\n'''\nEsto también es\nun comentario\nen varias líneas pero con comillas simples\n'''\n\nmy_variable = \"Mi tarea\"\nmy_variable = \"Nuevo valor de mi tarea\"\n\nMY_CONSTANT = \"Mi constante\"  # por convención\n\nmy_int = 8\nmy_float = 4.7\nmy_bool = True\nmy_bool = False\nmy_string = \"Mi cadena de texto\"\nmy_other_string = 'Mi otra cadena de texto'\n\nprint(\"¡Hola, Python!\")\n\nprint(type(my_int))\nprint(type(my_float))\nprint(type(my_bool))\nprint(type(my_string))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/bladi23.py",
    "content": "\"\"\"\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n\"\"\"\n# https://www.python.org/\n\n# Comentario de una línea\n\n\"\"\"\nComentario de varias líneas\nque ocupa más de una línea\n\"\"\"\n\n# Variable y constante\nnombre = \"Bladi\"  # variable\nPI = 3.14159      # constante (por convención)\n\n# Tipos de datos primitivos\ntexto = \"Hola\"\nentero = 23\ndecimal = 23.5\nbooleano = True\nvacio = None\n\n# Imprimir mensaje\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/blancowilson.py",
    "content": "# Pagina oficial de Python\n# https://python.org/\n\n# Comentario de una linea\n\"\"\"\nComentario en varias lineas \nse coloca con comilas siples \no comillas dobles\n\n\"\"\"\n\nstring_var:str =\"Python\"\ninteger_var:int = 1\nfloat_var:float = 3.5\nboolean_var:bool= True\ntuple_var:tuple = (3,2,4,5)\nlist_var:list = ['a','b','x','z']\ndict_var:dict = {\"key1\": \"data1\"}\n\nprint (f\"¡Hola {string_var}!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/blonsh.py",
    "content": "# https://python.org\n\n# Comentario en una línea\n\n\"\"\"\"\nEsto también se\nun comentario\nen varias líneas \n\"\"\"\n\n'''\nEsto también se\nun comentario\nen varias líneas \n'''\n\n# Crea una variable y una constante si el lenguaje lo soporta.\nmi_variable = \"Me gusta el café\"\n\nMY_CONSTANT = \"Mi constante\"  # por convención esto técnicamente funciona, aunque no es buena práctica.\n\n# Crea variables representando todos los tipos de datos primitivos\n# Entero (int)\nedad = 25\n\n# Número decimal (float)\naltura = 1.75\n\n# Booleano (bool)\nes_estudiante = True\nes_estudiante = False\n\n# Cadena de texto (str)\nnombre = \"Blanca\"\nmy_other_string = \"Mi otra cadena de texto\"\n\n# NoneType (None, representa ausencia de valor)\nnada = None\n\n# Mostramos los valores y sus tipos\nprint(edad, type(edad))\nprint(altura, type(altura))\nprint(es_estudiante, type(es_estudiante))\nprint(nombre, type(nombre))\nprint(nada, type(nada))\n\n#Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nprint (\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/bluefeatherdev.py",
    "content": "\"\"\"\n¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n- Recuerda que todas las instrucciones de participación están en el\n  repositorio de GitHub.\n\nLo primero... ¿Ya has elegido un lenguaje?\n- No todos son iguales, pero sus fundamentos suelen ser comunes.\n- Este primer reto te servirá para familiarizarte con la forma de participar\n  enviando tus propias soluciones.\n\nEJERCICIO:\n- Crea un comentario en el código y coloca la URL del sitio web oficial del\n  lenguaje de programación que has seleccionado.\n- Representa las diferentes sintaxis que existen de crear comentarios\n  en el lenguaje (en una línea, varias...).\n- Crea una variable (y una constante si el lenguaje lo soporta).\n- Crea variables representando todos los tipos de datos primitivos\n  del lenguaje (cadenas de texto, enteros, booleanos...).\n- Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\n¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\ndebemos comenzar por el principio.\n\"\"\"\n\n# https://www.python.org/\n\n# This is a single-line comment\n\n# This \n# is \n# a \n# multi-line \n# comment\n\n\"\"\"This is a single-line comment\"\"\"\n\n\"\"\"\nThis \nis \na \nmulti-line \ncomment\n\"\"\"\n\nmy_variable = 'Python'\nMY_CONSTANT = 23\n\nprint(f'{my_variable = }')\nprint(f'{MY_CONSTANT = }')\n\nmy_str = 'Jesús'\nmy_int = 21\nmy_float = 1.623\nmy_complex = 1j\nmy_boolean = True\n# my_bytes = b'Hello'\n# my_bytearray = bytearray(23)\n# my_memoryview = memoryview(bytes(b'Hello'))\n\nprint(type(my_str))           # <class 'str'>\nprint(type(my_int))           # <class 'int'>\nprint(type(my_float))         # <class 'float'>\nprint(type(my_complex))       # <class 'complex'>\nprint(type(my_boolean))       # <class 'bool'>\n# print(type(my_bytes))       # <class 'bytes'>\n# print(type(my_bytearray))   # <class 'bytearray'>\n# print(type(my_memoryview))  # <class 'memoryview'>\n\nprint('¡Hola, Python!') # ¡Hola, Python!\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/breiner712.py",
    "content": "# https://www.python.org/\n# Comentario en una linea\n\n\"\"\"\nEjemplo \nde comentario\nmultilinea\n\"\"\"\n\nmi_variable = \"my variable\"\nmi_variable = \"Nuevo valor de mi variable\"\n\nMY_CONSTANT= \"Mi Constante\" # Por convención\n\nmy_int=1\nmy_float=1.5\nmy_bool=True\nmy_bool=False\nmy_string= \"Mi cadena de Texto\"\nmy_other_string= \"Mi otra cadena de Texto\"\n\nprint (\"¡Hola, Python!\")\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/byte-punk.py",
    "content": "\"Comentario\"\n\n\"https://www.python.org/\"\n\n\"Comentario de una línea\"\n\n\"\"\"\nComentario\nde \nvarías\nlíneas\nPython\n\"\"\"\n\nvariable = \"Diego\"\nCONSTANTE = \"Hombre\"\n\n\"Tipos de datos en Python:\"\n\n#Enteros\nedad = 31\n\n#Flotantes\npi = 3.141598\n\n#Cadena de texto\nlenguaje = \"Python\"\n\n#Booleano\nVerdadero = True\nFalso = False\n\n#None \nAusenciaDeValor = None\n\nprint(\"¡Hola\", lenguaje + \"!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/bytecodesky.py",
    "content": "\"\"\"\nEJERCICIO:\n* - Crea un comentario en el código y coloca la URL del sitio web oficial del\n*   lenguaje de programación que has seleccionado.\n* - Representa las diferentes sintaxis que existen de crear comentarios\n*   en el lenguaje (en una línea, varias...).\n* - Crea una variable (y una constante si el lenguaje lo soporta).\n* - Crea variables representando todos los tipos de datos primitivos\n*   del lenguaje (cadenas de texto, enteros, booleanos...).\n* - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\"\"\"\n\n#Link de la pagina web del lenguaje de programacion seleccionado: https://www.python.org/\n#Link de la pagina web de la documentacion del lenguaje de programacion: https://docs.python.org/3/\n\n#Comentario de una linea\n\n\"\"\"\nComentario de\nvarias lineas\n\"\"\"\n\n# 2 formas de representar variables\nnombre = \"Python\"\nnombre, apellido = \"Python\", \"Developer\"\n\n#Constante\n#Para representar constantes en python se utiliza el nombre de la variable en mayusculas para indicar que no se debe modificar su valor o se usa snake_case para indicar que es una constante de esta manera: CONSTANTE = \"Valor\" o VARIABLE_CONSTANTE = \"Valor\"\nCONSTANTE = \"Valor\"\nVARIABLE_CONSTANTE = \"Valor\"\n\n\n#Tipos de datos primitivos\n#String-Cadena de texto\nsaludo = \"Hola mundo\"\n#Entero-Integer\nedad = 23\n#Decimal-Float\npi = 3.1416\n#Booleano-Boolean\nverdadero = True\nfalso = False\n\nprint(f\"¡Hola, {nombre}!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/c3sarmx.py",
    "content": "\"\"\"\n# 00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO.python.c3sarmx\n\n* EJERCICIO:\n* - Crea un comentario en el código y coloca la URL del sitio web oficial del\n*   lenguaje de programación que has seleccionado.\n* - Representa las diferentes sintaxis que existen de crear comentarios\n*   en el lenguaje (en una línea, varias...).\n* - Crea una variable (y una constante si el lenguaje lo soporta).\n* - Crea variables representando todos los tipos de datos primitivos\n*   del lenguaje (cadenas de texto, enteros, booleanos...).\n* - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\"\"\"\n\n# https://www.python.org/\n# Esto es un comentario en una sola línea.\n\n''' \nEsto es \nun comentario en \nvarias líneas\n'''\n\n\"\"\"\nEsto también es \nun comentario en \nvarias líneas\n\"\"\"\n\n# Variable \nvariable = \"Esto es una variable\"\n\n# Constante (Python no tiene constantes reales, solo por convención)\nPI = 3.1416\n\n# Tipos de datos primitivos\ntexto = \"Hola Mundo\" # String\nentero = 5 # Integer\ndecimal = 2.5 # Float\nbooleano = True # Boolean\n\n# Imprimir por terminal \nprint(\"Hola Python!!\")\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/caleb699-hub.py",
    "content": "#Este es un comentario en python https://www.python.org/\n\"\"\"este \nes un comentario\nde varias \nlineas\"\"\"\nvariable1 = \"Esta es una variable\"\nentero = 1\nflotante = 1.5 \ntexto = \"Python\"\nbooleano = True\nprint(f\"¡Hola {texto}!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/camilo-zuluaga.py",
    "content": "# Lenguaje seleccionado: https://www.python.org/\n\n# Comentario de una sola linea\n\n\"\"\" \n    Comentario de varias lineas\n    con comillas dobles\n    -> Tambien se puede con comillas simples\n\"\"\"\n\n# Declaramos una variable\nfoo = \"bar\"\n\n# Declaramos una constante, por convencion se escribe en mayusculas\nPI = 3.14\n\n# Variables con todos los datos de tipo primitivo\n\ncadena = \"Esto es una cadena de texto\"  # String\ninteger = 5  # Int\nboolean = True  # Or False\ndecimal = 5.5  # Float\nmy_string = \"Python\"  # String con mi lenguaje\n\nprint(f\"¡Hola, {my_string}!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/camiloforero1997.py",
    "content": "# Comentario de una linea\n\n\"\"\"\n    Comentario de varias lineas\n    Documentacion oficial: # Lenguaje seleccionado: https://www.python.org/\n\n\"\"\"\n\n\nvariable_declarada = \"No necesitamos poner el tipo de dato\"\n\n\n# La contante se declara en mayuscula\nEJEMPLO = 4\n\ncadena_ejemplo= \"Python\"\nint_ejemplo = 2\nfloat_ejemplo = 3.14\nboolean_ejemplo = True\n\nprint(f\"Hola, {cadena_ejemplo}\")\nprint(\"Hola {} este es el lenguaje seleccionado\".format(cadena_ejemplo))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/carlosalberto05.py",
    "content": "# https://www.python.org/\n\n# Comentario para una línea\n\n\"\"\"\nAsí se coloca un comentario para varias lineas\n\"\"\"\n\n'''\nEsto es otra forma de escribir comentarios\n'''\n\nmy_variable = \"No hace falta una palabra reservada para declararla\"\nmy_variable = \"Lo común en python es usar snake case\"\n\n# Python no tiene constantes\n\nMY_CONSTANT = \"Mi constante\" #por convención se usan mayus pero no hay const en python\n\n#En python existen 4 tipos de datos primitivos\nmy_int = 9\nmy_float = 9.3\nmy_bool = True\nmy_str = \"Hola mundo\"\n\nprint('¡Hola, Python!')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/carlosbb70.py",
    "content": "# Sitio oficial de Python: https://www.python.org\n\n# Comentario una línea.\n\n\"\"\"\nComentario\nvarias\nlíneas\n\"\"\"\n\n''' \nOtra forma\ncomentario\nvarias\nlíneas\n'''\n\nmyVar = \"Python!\"\nMY_CONST_PI = 3.14\n\nmyString = \"Variable tipo Texto o String\"\nmyInteger = 45\nmyFloat = 45.3\nmyBooleam = True\n\nprint(\"¡Hola,\", myVar)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/carlosmarte23.py",
    "content": "# https://www.python.org/\n\n# Este es un comentario de una linea.\n\n\"\"\"\n    Este es un comentario de varias lineas.\n    Se crea usando tres comillas dobles.\n    Y se cierra tambien usando las tres comillas dobles.\n\"\"\"\nvariable = \"Hola, Mundo!\" # Esta es una variable\n\nentero = 1; # Esta es una variable de numero entero.\nflotante = 1.0; # Esta es una variable de numero decimal.\nbooleano = True; # Esta es una variable de tipo booleano.\ncadena = \"Hola, Mundo!\"; # Esta es una variable de tipo cadena de texto.\ncaracter = 'H'; # Esta es una variable de tipo caracter.\nlista = [1,2,3,4,5]; # Esta es una variable de tipo lista.\ntupla = (1,2,3,4,5); # Esta es una variable de tipo tupla.\ndiccionario = {'nombre':'Camilo', 'apellido':'Zuluaga', 'edad':26}; # Esta es una variable de tipo\n\nprint(\"Hola, Python!\"); # Imprimir a la consola"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/carlostoledoe.py",
    "content": "# https://www.python.org/\n\n\n# Este es un comentario\n\n\n'''\nEste es un comentario\nmultilínea\n'''\n\n\n\"\"\"\nEste es otra forma \ndel comenatario\nmultilínea\n\"\"\"\n\nvariable = 'Valor de la variable'\n\nvariable_entero = 2024\nvariable_flotante = 3.1416\nvariable_booleano_verdadero = True\nvariable_booleano_falso = False\nvariable_string = 'Contenido'\nvariable_string_otro = \"Contenido\"\n\nprint('¡Hola, Python!')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/carrenoalexander.py",
    "content": "# 'https://www.python.org'\n\n# Comentario en una linea \n\n\"\"\"\nComentario de bloque\no en varias lineas\n\"\"\"\n\nmy_variable = \"Variable\"\n\nMY_CONSTANT = \"Constant\"  # \"Constante\"\n\nmy_str = \"Alex\"\nmy_int = 8\nmy_float = 2.5\nmy_bool = True\n\nprint(type(my_str))\nprint(type(my_int))\nprint(type(my_float))\nprint(type(my_bool))\n\nprint(\"Hello, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/carresoft.py",
    "content": "\n# - Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n# https://docs.python.org/3/\n\n# - Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n# Comentario en una sola línea\nnumero = 1  # Comentario al final de una línea de código\n'''\n Comentarios de varias líneas \n usando tres comillas simples \n al inicio y al final\n'''\n\"\"\"\n Comentarios de varias líneas \n usando tres comillas dobles \n al inicio y al final\n\"\"\"\n\n# - Crea una variable (y una constante si el lenguaje lo soporta).\nnumero = 1\n# En Python no hay declaración de constantes, pero por convención se define la variable (constante) en mayúsculas\nPI = 3.14159\n\n# - Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\nentero = 5  # Entero (int)\nflotante = 3.14159  # Flotante (float)\nlenguaje = 'Python'  # Cadenas de texto (str)\nboleano = True  # Boleanos (bool)\n# Nulo (None): Representa la ausencia de valor o un valor nulo. Se utiliza para inicializar variables que pueden ser asignadas más adelante.\nNulo = None\n\n# - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nprint(f\"¡Hola, {lenguaje}!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/caterinaarata.py",
    "content": "# comentario\n\n\"\"\"\nComentario entre\nlineas\n\"\"\"\n\n'''\nMas comentario\nentre lineas\n'''\n\nmy_variable = \"Hola\"\n\nMY_CONSTANT = \"Adios\"\n\nmy_int = 1\nmy_float = 2.5\nmy_bool = TRUE\nmy_bool = FALSE\nmy_string = \"Cadena de txt\"\nmy_other_sting = 'Otra cadena'\n\nprint (Hola, Python)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/cbobadil2006.py",
    "content": "# Enlace a la página oficial de Pythom: https://www.python.org/\n\n# Este es un comentario de una línea\n\n'''\n    Este es un comentario\n    multilíneas, pero en el que\n    se utilizan las comillas \n    simples.\n'''\n\n\"\"\"\n    Este es un comentario\n    multilíneas, pero en el que\n    se utilizan las comillas \n    dobles.\n\"\"\"\n\n# En Python se utiliza el estilo snake case para nombrar variables\nmi_variable_1 = 1974\nmi_variable_2 = \"San Ignacio\"\n\n# Por convención, para nombrar constantes en Python, se escribe en mayúsculas.\nMI_CONSTANTE = \"3.14\"\n\n# Tipos de datos primitivos (En Python son int, float, bool, str, ...)\nmi_entero = 1537    # tipo int\nmi_real =   3.52    # tipo float\nmi_booleano = True  # tipo bool\nmi_cadena = \"Cadena de caracteres, entre comillas dobles\"  # tipo str\nmi_otra_cadena = 'Otra cadena de caracteres, con comillas simples'  # tipo str\n\n# Uso de la función print para salida de datos.\nprint(\"¡Hola, Python!\")\n\n# Uso de la función interna type, para determianr el tipo de dato de la variable en cuestión\nprint(type(mi_entero))\nprint(type(mi_real))\nprint(type(mi_booleano))\nprint(type(mi_cadena))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/cbuenrostrovalverde.py",
    "content": "## Ejercicio\n\n'''\n EJERCICIO:\n - Crea un comentario en el código y coloca la URL del sitio web oficial del\n   lenguaje de programación que has seleccionado.\n - Representa las diferentes sintaxis que existen de crear comentarios\n   en el lenguaje (en una línea, varias...).\n - Crea una variable (y una constante si el lenguaje lo soporta).\n - Crea variables representando todos los tipos de datos primitivos\n   del lenguaje (cadenas de texto, enteros, booleanos...).\n - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n debemos comenzar por el principio.\n'''\n\n# URL del sitio web oficial de Python\n# https://www.python.org/\n\n# Comentario de una linea\n\n# Comentario de varias líneas\n'''\nComentario\nde\nvarias\nlíneas\n'''\n# Creación de una variable\nvariable = 1\n\n# Creación de una constante\nCONSTANTE = 2\n\n# Creación de variables de diferentes tipos de datos\ncadena = 'Hola, Mundo!'\nentero = 1\nflotante = 1.0\nbooleano = True\nlenguaje = 'Python'\n\n# Impresión por terminal\nprint(f'Hola, {lenguaje}!')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/cdbiancotti.py",
    "content": "#  * EJERCICIO:\n#  * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n#  *   lenguaje de programación que has seleccionado.\n\n# https://docs.python.org/3/\n\n#  * - Representa las diferentes sintaxis que existen de crear comentarios\n#  *   en el lenguaje (en una línea, varias...).\n\n# Esto es un comentario\n\n#  * - Crea una variable (y una constante si el lenguaje lo soporta).\nPSEUDO_CONSTANTE = ('python no posee constantes por lo cual se usa por convencion este'\n                    'formato para representar que la variable se quiere utilizar como constante')\nvariable = 'soy una variable'\n\n#  * - Crea variables representando todos los tipos de datos primitivos\n#  *   del lenguaje (cadenas de texto, enteros, booleanos...).\n\n# los que conocia\nentero = 1\nflotante = 1.5\ncomplejo = 3j\nstring = 'soy un string'\nbooleano = True  # False\nlista = [1, 2, 3, 4]\ntupla = (1, 2, 3, 4)\nconjunto = {1, 2, 3, 4}\ndiccionario = {\n    1: 'prueba',\n    '2': ['otro', 'dato']\n}\n\n# los que no conocia como primitivos\nconjunto_congelado = frozenset({1, 2, 3, 4})\nrango = range(5)\n\n# los que no conocia como primitivos pero no use nunca\nbyte1 = b'Esto lo transformo a bytes'  # bytes\nbyte2 = bytes(15)  # bytes\nbytearray1 = bytearray(10)  # bytearray\n\n#  * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/cesar-ch.py",
    "content": "# URL: https://www.python.org/\n\n# Comentarios\n# ------------\n# Este es un comentario de una sola línea \n\"\"\"\n    Este es un comentario\n    de varias líneas\n\"\"\"\n\n# Variable y constante\n# ---------------------\nmy_variable = \"Python\"\nMY_CONSTANT = 3.14 # En python no hay constantes, pero por convencion se usan mayúsculas\n\n# Tipos de datos primitivos\n# -------------------------\nmy_int = 2024 # Este es un número entero\nmy_float = 2024.1 # Este es un número real\nmy_string = \"Python\" # Este es una cadena de texto\nmy_boolean = True # Este es un valor lógico\n\n\nprint(f\"Hola {my_string}\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/cesar-rosado.py",
    "content": "# Sitio oficial\n# https://www.python.org\n\n# Comentarios\n\n# Esto es un comentario de una sola linea\n\n\"\"\"\n    Este es un comentario \n    en varias líneas\n    usando comillas dobles\n\"\"\"\n\n\"\"\"\n    Este es un comentario\n    en varias líneas \n    usando comisillas simples\n\"\"\"\n\n# Variables\nx = 10\n\n# Constantes\nPI = 3.14159\n\n# Variables con datos primitivos\n\n# Enteros\nnum = 5\n# Flotantes\nnum2 = 5.5\n# Cadena de texto\ntexto = \"Hola mundo\"\n# Boolean\nx = True\ny = False\n\n# Imprime Hola, [Nombre del lenguaje]\nprint(\"Hola, Python\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/cevicheconaji.py",
    "content": "#https://www.python.org/#\n\n#Esto es un comentario de una sola línea#\n\n'''\nEsto es un comentario de varias líneas\n'''\n\n#Esto es una variable#\nx = \"Esto es un texto\" \n#Esto es una constante#\nPI = 3.1416\n\n#Varibles de diferentes tipos de datos primitivos#\n\n# Entero #\nentero = 1\n\n# Bolleano #\nbooleano = True\n\n# Flotante #\nflotante = 1.5\n\n# Cadena de texto #\ncadena = \"Hola mundo\"\n\n# Lista #\nlista = [1,2,3,4]\n\n# set #\nconjunto = {1,2,3,4}\n\nconjunto = set([1,2,3,4])\n\n# Tupla #\ntupla = (1,2,3,4)\n\ntupla = tuple((1,2,3,4))\n\ntupla = tuple([1,2,3,4])\n\ntupla = 1,2,3,4\n\n# Diccionario #\ndiccionario = {\n    \"nombre\": \"Juan\",\n    \"edad\": 25\n}\ndiccionario = dict(nombre=\"Juan\",\n                    edad=25)\n\ndiccionario = dict(zip(('nombre', 'edad'), ('Juan', 25)))\n\n# Conjunto congelado #\nconjunto_congelado = frozenset([1,2,3,4])\n\n#Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/chema-dw.py",
    "content": "# Python official website https://www.python.org/\n\n# Comentario en una linea\n\n\"\"\"\nEsto es un comentario\nen varias lineas\n\"\"\"\n\n'''\nEsto también\nes un comentario\nen varias lineas\n'''\n\n# VARIABLES\nvar1 = \"Mi primera variable\"\n# variable constante por convención ya que en Phyton no exsiten las variables constantes\nAGE = 30\n\n# TIPOS\nvar_string = \"My string\"\nvar_string = 'Other string'\nvar_boolean = True\nvar_int = int(1)\nvar_float = float(4.5)\n\n# PRINT\nlanguage = \"Python\"\nprint(f\"¡Hola, {language}!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/chrispro-afk.py",
    "content": "#https://phyton.org\n\"\"\"\nmi primer comentario en varias lineas\n\"\"\"\nmy_variable = \"mi variable\"\nm_variable = \"nuevo valor de mi variable\"\n\nMY_CONSTANT = \"nueva variable\" #por convencion\nMY_CONSTANT = \"holaaaaa\"\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/christiancoc.py",
    "content": "\"\"\"Sitio web \ndel lenguaje:\"\"\"\n# https://www.python.org/\n\nvariable = \"Esta es una variable\"\n\nMI_CONSTANTE = \"Esta es una constante\"\n\nnumero_entero = 1 #int\n\nnumero_flotante = 1.0 #float\n\n#Booleanos\nbooleano_verdadero = True\nbooleano_falso = False\n\ncadena_de_texto = \"Esta es una cadena de texto\" #str\n\nvalor_nulo = None #None\n\nprint(\"Hola, Python!!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/chuanmi.py",
    "content": "'''\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n     lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n     en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n     del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n \n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n'''\n\n# COMENTARIOS\n \n# https://www.python.org\n'''\nComentario de varias lineas\n'''\n\n\n# VARIABLES Y CONSTANTES\nmi_variable = 14\nMI_CONSTANTE = 1980\n\n\n# TIPOS\nvar_string = 'texto'\nvar_string = \"texto2\"\nvar_string = \"Esto es un string\"\nvar_int = int(1)\nvar_float = float(1.5)\nboolean = True\nPI = 3.14\n\n\n# PRINT\nmi_lenguaje = \"Python\"\nprint(f\"¡Hola, {mi_lenguaje}!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/cisneros2404.py",
    "content": "\"\"\"\n  ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n  - Recuerda que todas las instrucciones de participación están en el\n    repositorio de GitHub.\n \n  Lo primero... ¿Ya has elegido un lenguaje?\n  - No todos son iguales, pero sus fundamentos suelen ser comunes.\n  - Este primer reto te servirá para familiarizarte con la forma de participar\n    enviando tus propias soluciones.\n \n  EJERCICIO:\n  - Crea un comentario en el código y coloca la URL del sitio web oficial del\n    lenguaje de programación que has seleccionado.\n  - Representa las diferentes sintaxis que existen de crear comentarios\n    en el lenguaje (en una línea, varias...).\n  - Crea una variable (y una constante si el lenguaje lo soporta).\n  - Crea variables representando todos los tipos de datos primitivos\n    del lenguaje (cadenas de texto, enteros, booleanos...).\n  - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n \n  ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n  debemos comenzar por el principio.\n \"\"\"\n\n\"\"\"\nEsto es un comentario hecho por cisneros2404 usando Python\nhttps://www.python.org/\n\"\"\"\n#Esta es la primero forma de hacer un comentario en Python\n\"\"\"\nEsta es la segunda forma\nde hacer un comentario\nen Python\n\"\"\"\n\nvariable_01 = 'ESta es mi primer variable'\n\nMI_CONSTANTE = \"cisneros2404\"\n\nvar_Entero = 55\nvar_Decimal = 5.5\nvar_Booleano = True\nvar_String = \"Python\"\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/cit-star.py",
    "content": "# Esto un comentario \n\n\"\"\" Esto es \nun \ncomentario\n\"\"\"\n\n''' Esto también es un comentario '''\n\nmy_variable = \"Mi variable\" \nmy variable = \"Nuevo valor de mi variable\"\n\nMY_CONSTANT = \"Mi constante\"\n\nmy_int = 1 \nmy_float = 1.5 \nmy_bool = True\nmy_bool = False \nmy_string = \"Mi cadena de texto\"\nmy_other_string = 'Mi otra cadena de texto'\n\n\nprint(\"¡Hola, Python!\")\n\nprint(type(my_int))\nprint(type(my_float))\nprint(type(my_bool))\nprint(type(my_int))\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/clainu04.py",
    "content": "#https://www.python.org/\n\n\"\"\"\n    Este es un comentario\n    de varias lineas\n\"\"\"\n\nnombre = \"Clainudev\"\n\nstring = \"hola soy una variable string\"\nnumero = 100\nflotante = 10.5\nbooleano = True\n\nnombre_lenguaje = \"Python\"\n\nprint = (f\"Mi nombre es {nombre} y mi lenguaje favorito es {nombre_lenguaje}\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/claudio-ortiz-dev.py",
    "content": "# https://docs.python.org/3/\n# Comentario en una línea\n\n\"\"\"\nEste es\nun comentario\nen varias líneas\n\"\"\"\n\n# Variables (pueden cambiar)\nnombre = \"Claudio\"\nnombre = \"Claudio Ortiz\"  # sobreescribe el valor anterior\n\n# Constante (por convención no se modifica)\nMY_CONSTANT = \"mi constante\"\n\n# Tipos de datos básicos\nedad = 40                  # int\nprecio = 0.5               # float\nactivo = True              # bool\nsaludo = \"Hola Mundo\"      # str\n\n# Imprimir tipos\nprint(type(edad))\nprint(type(precio))\nprint(type(activo))\nprint(type(saludo))\n\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/claudios1980.py",
    "content": "\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/clmiranda.py",
    "content": "# https://www.python.org/\n\n# Este es un comentario de una línea\n\n\"\"\"\nEste es un comentario\nen varias líneas\nse usan tanto con comillas simples (')\no comillas dobles (\")\n\"\"\"\n\nmi_primer_variable = \"Esta es mi primer variable\"  # variable\n\nVARIABLE_CONSTANTE = 3.141592  # variable tipo constante\n\nnombre = \"Cliver\"  # variable tipo string (cadena de texto)\n\nedad = 27  # variable tipo int (entera)\n\naltura = 1.75  # variable tipo float (flotante)\n\nflag = True  # variable tipo bool (booleana => True o False)\n\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/codeskin-r.py",
    "content": "# https://www.python.org/    # comentario de una linea\n\n\"\"\"\ncomentario de varias lineas\nen este caso podria ser util\npara realizar aclaraciones que\nnecesiten de una mayor cantidad\nde texto\n\n\"\"\"\n\n# Variables\n\nx = 10    #entero\ny = 3.14  #flotante\nz = 2 + 3j  # Número complejo\n\n# variables de texto\n\nnombre = \"Carlitos\"\nmensaje = \"Hola, universo 🌍️!\"\nfrase_multilinea = \"\"\"Hola Moure, te agradezco\nmucho por lo que haces por nosotros, parece\nsimple, pero esto es demasiado!\"\"\"\n\n# Constantes\n\n\"\"\"\nPython no tiene constantes verdaderas como otros lenguajes (por ejemplo, const en JavaScript o final en Java).\nPero, por convención, las constantes se escriben en mayúsculas para indicar que no deberían modificarse.\n\n\"\"\"\n\nPI = 3.1416\nGRAVEDAD = 9.81\n\nprint(PI)         # 3.1416\nprint(GRAVEDAD)   # 9.81\n\n\n# variables que representan datos primitivos del lenguaje Python\n\n# Entero (int)\nnumero_entero = 42\n\n# Flotante (float)\nnumero_decimal = 3.14\n\n# Número complejo (complex)\nnumero_complejo = 6 + 1\n\n# Booleano (bool)\nes_verdadero = True\nes_falso = False\n\n# Cadena de texto (str)\nmensaje = \"Hola, como estas Moure?\"\n\n# Bytes (bytes)\ndato_bytes = b\"Hola\"\n\n# Bytearray (bytearray)\ndato_bytearray = bytearray(5)  # Crea un array de 5 bytes vacíos\n\n# NoneType (None)\nsin_valor = None\n\nprint(\"Hola, Python 🦎\")\nprint(type(numero_decimal))\nprint(type(numero_complejo))\nprint(type(es_verdadero))\nprint(type(mensaje))\n\n\n\n\n# Fin.\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/cris10026.py",
    "content": "#Link de python. https://www.python.org/\n\n#esto es comentario\n\n#jemplo comentario comillas dobles\n\"\"\"\nComentario en varias \nlineas\n\"\"\"\n#Ejemplo comillas simples\n'''\ncomentario en varias \nlineas= otro ejemplo\n'''\n\n#Ejemplo variables\nmy_variable = \"Mi variable\"\nvariable = \"nueva variable\"\n\n#Ejemplo constante\nMY_CONSTANTprueba = 16\n\n#Ejemplo Float\nmy_floatprueba = 15.6\n\n#Ejemplos bool\nmy_bollfalse = falso\nmy_bolltrue = verdadero\n\n#Ejemplo cadena de texto \n\nmy_str = \"mi mensaje doble comillas\"\nmy_string = 'mi mensaje con comillas simples'\n\nprint=(\"HOLA, MUNDO\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/crisky94.py",
    "content": "# https://www.python.org\n\n# Comentario en una línea\n\n\"\"\"ESTO\n    ES UN COMENTARIO\n    MULTILINEA\n\"\"\"\n\n'''\nEsto también \nes un comentario\nmultilinea\n'''\n\nmy_variable = 'Hola Mundo'\n\nMY_CONSTANTE = 'Esta es una constante' # Convención \n\nmy_int = 5\nmy_float = 4.2\nmy_bool = True\nmy_bool = False\nmy_text = 'Hola Mundo'\nmy_tupla = (1, 2, 3, 4, 5)\nmy_lista = [1, 2, 3, 4, 5]\nmy_dict = {'nombre': 'Crisky', 'edad': 30}\n\n\n\nprint('¡Hola, Python!')\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/cristianvergaraf.py",
    "content": "# Buenos días, buenas tardes: La documentación de python la podrá encontrar en la siguiente URL: https://www.python.org/ \n\n# Hola soy una línea de comentario\n\n### \n\n    Hola soy varias líneas de comentarios para describir cosas más complejas. \n    He visto que se utilizan para documentar funciones. Seguro eso lo vemos más adelante.\n    \n    Para finalizar un poema de chat gtp editado por el autor.\n    \n    \"En la oscuridad de la incertidumbre, palabras florecen, ideas inquietas\"\n    \n\n## Las variables en python se definen de forma directa\n\npython = \"Hola, Soy python\"\n\n### Python no tiene constantes, pero se pueden declarar escriendo el nombre en mayúscula,\n# esperando no sea cambiada. \n\nCONSTANTE = \"Python no tiene la posibilidad de crear constates\" \n\n# Crear variables representando todos los tipos primitivos\n\n# String\n\npythonisa = \"Vuoi un biscotto della fortuna?\"\n\n# Integers: Número entero. Las variable que contiene un número entero es capaz de ajustar\n# automaticamente el tamaño del entero (16,32,64 bytes) de acuerdo al número entero seleccionado\n# otros lenguajes requieren que el tamaño sea especificado. Esto se puede ajustar especificamente \n# numpy o ctypes.\n\n\nnumero_galletas = 4\n\n# Float: Número que permite contener decimales. Se definen usando como punto decimal \n# corresponden por defecto a 64-bit (8 bytes) (doble precision de acuerdo al estandar IEEE754).\n# Aproximadamente 15-17 decimales. Al igual que en los enteros el tamaño se ajusta automaticamente \n# pero en algunos casos especificos podemos definirlo usando numpy o ctypes\n\ntotal_numero_galletas = 12.55\n\n# Complex: Los números complejos son aquellos que tienen una parte imaginaria\n\nnumero_alicia = 11 + 36j\n\n# Bytes (butes): representan secuencias que no se pueden cambiar de bytes. Usados para datos\n# binarios o para la comunicarse con sistemas binarios\n\nrobots = b'robot'\n\n# Bytearray son secuencias de bytes mutables.\n\nmister_robot = bytearray(b'Yo soy tu padre')\n\n# Valor None. representan la ausencia de valor, la nada.\n\nFantasia = None\n\n# Boolean: Las variables boolean son variables que son verdadero o falso\n\nbtc_to_the_moon = True\n\n# Mostrar por pantalla el nombre del lenguaje\n\nnombre_lenguaje = \"Monty Python\"\n\nprint(f'Hola soy {nombre_lenguaje}')\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/csaraugusto2.py",
    "content": "# Pagina web del lenguaje Pyton --> https://www.python.org/\n\n# Esto es un comentario de una sola linea\n\n'''\nCon triple comillas\nal principio y al final\nde un parrafo \nse pueden crear \ncomentarios por \nbloques en \nvarias lineas\n'''\n\n\"\"\"\nTanto las comillas simples (')\ncomo las comillas dobles (\")\nsirven para hacer comentarios\nen varias lineas.\n\"\"\"\n\n# Creamos variables de la siguiente manera\n\nmi_variable = 'esto es una variable'\n\n# Para las constantes en Pyton no existen, pero se pueden representar escribiendola en MAYUSCULAS para distinguirlas.\n# Sin embargo pueden cambiar su valor en cualquier momento.\n\nMI_CONSTANTE = \"Una constante que no es constante xD\"\n\n# Tipos de datos Primitivos en Pyton\n\nnombre = 'Cesar' # es un string\n\nedad = 41 # Es un entero\n\naltura = 1.78 # Es un Flotante\n\nluz = True # Es un booleano true o false\n\n\n# Imprimir Hola Pyton\n\nprint('Hola Pyton')\n\nprint(type(nombre))\nprint(type(edad))\nprint(type(altura))\nprint(type(luz))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/cubandeveloper89.py",
    "content": "# https://www.python.org/\n\n# Este es un comentario\n\n\"\"\"\ncomentario de varias lineas\neste año es mi año\nde veras que quiero aprender!\n\"\"\"\n\n# Variables\n\nmy_string = \"variable1\" # tipo string\n\nMY_CONSTANT = \"variable2\" # solo por convencion\n\n# Tipos de datos primitivos\n\nmy_int = 35\n\nmy_float = 3.5\n\nmy_boolean = True   # or False\n\nmy_str = \"Hola\"\n\n# el Print\n\nprint(\"Hola python! Vamos por mas!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/culebropalido.py",
    "content": "#!/usr/bin/env  python3\n\n#   https://www.python.org/ Web oficial de python\n\n#   Esto es un comentario de una sola linea\n\n'''\n    Esto es un comnentario con varias lineas,\n    en python podemos hacerlo englobando el texto \n    entre tres comillas. \n    No confundir con docstrings.\n'''\nvariable = 1    # Asignamos el valor 1 a la variable\n\nCONSTANTE = 3.141592    #  python no soporta variables como tal pero con mayus\n                        #  podemos por convención usarlas.\n\n# A continuación se crean variables primitivas de python\n\nentero = 10                 # Variable tipo integer\n\ndecimal = 44.5              # Variable tipo float\n\ncomplejo = e = 1 + 2j       # Varibale tipo complex\n\ncadena = \"Hola que tal\"     # Variable tipo string\n\nbooleana = True             # Variable tipo booleana con valor True \n\nbooleana_dos = False        # Variable booleana con valor False\n\n# Imprimir el mensaje indicado\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/damaas1925-alt.py",
    "content": "#https://www.python.org/\n# esto es un comentario en una sola linea \n\"\"\"\nEsto es un comentario de \nvarias lines\n\"\"\"\nname = \"Damaas1925\"\niva = 0.16 # porcentaje de IVA (CONSTANTE)\n\nstring = \"cadena de texto\"\ninteger = 10 # numero entero\nfloat_number = 10.5 # numero decimal\nboolean = True # valor booleano (True o False)\nprint(\"Hola Mundo\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/dandrusco.py",
    "content": "# https://www.python.org/\n\n# Esto es un comentario de una línea\nvariable = 10  # También se puede agregar un comentario al final de una línea de código\n\n'''\nEste es un comentario de\nmúltiples líneas en Python.\nPuede abarcar varias líneas de código.\n'''\n\n\"\"\"\nTambién se pueden utilizar triples comillas dobles.\nEste es otro ejemplo de comentario de múltiples líneas.\n\"\"\"\n\nvariable = 1\n\n# Cadena de texto\ncadena = \"Hola, mundo!\"\n\n# Entero\nentero = 42\n\n# Número de punto flotante\nflotante = 3.14\n\n# Booleano\nbooleano = True\n\n# Lista\nmi_lista = [1, 2, 3, 4, 5]\n\n# Tupla\nmi_tupla = (10, 20, 30)\n\n# Diccionario\nmi_diccionario = {\"clave1\": \"valor1\", \"clave2\": \"valor2\"}\n\n# Conjunto\nmi_conjunto = {1, 2, 3}\n\nprint(\"Hola, Python\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/danidan1214.py",
    "content": "# https://www.python.org/\n# Comentario de una linea\n\"\"\"\nEsto es un comentario de varias líneas\n\"\"\"\n'''\nEsto también es un comentaio de varias lineas\n'''\n\nmy_variable = \"Mi variable\"\nmy_variable = \"Nuevo valor de mi variable\"\n\nMY_CONSTANT = \"Mi constante\"  #No hay constantes en Python, es por convención\n\n# Variables\nmy_int = 1\nmy_float = 1.5\nmy_bool = True\nmy_bool = False\nmy_string = \"Mi cadena de texto\"\nmy_string2 = 'Mi otra cadena de texto'\n\nprint(\"¡Hola, Python!\")\n\n#Funcion del sistema para mostrar el tipo de dato\nprint (type(my_int))\nprint (type(my_float))\nprint (type(my_bool))\nprint (type(my_string))\nprint (type(my_string2))"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/danielhdzr.py",
    "content": "# Comentarios: Pagina Web: https://www.python.org/\n\n\"\"\"\nEste es un comentario\nde multiples\nlineas\n\"\"\"\n\n'''\nOtro modo de comentar\nmultiples lineas\n'''\n# Constante\nCONSTANTE_PI= 3.1416\n# Variable\na = \"Variable\"\n\n# Variable string\ntext = \"Hola\"\n\n# Variable int\nNumber = 10\n\n# Variable float\nfloat_number = 5.0\n\n# Variable Boolean\nverdadero = True\n\n# Variable nulo\nvalor = None\n\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/danielperezrubio.py",
    "content": "# https://www.python.org/\n\n# Comentario en línea\n\n\"\"\"\nUn comentario en\nvarias líneas\n\"\"\"\n\n'''\nOtro comentario en\nvarias líneas\n'''\n\nvariable = 1\nCONSTANTE = 3.14\n\nmy_string = \"Python\"\nmy_int = 23\nmy_float = 8.5\nmy_bool = True\n\nprint(f\"¡Hola, {my_string}!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/darubiano.py",
    "content": "\"\"\"\nEJERCICIO:\n1) Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n2) Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n3) Crea una variable (y una constante si el lenguaje lo soporta).\n4) Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n5) Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\"\"\"\n\n# 1) https://www.python.org/\n\n# 2) Comentario de una linea y varias\n\n\"\"\"\nComentario de varias lineas\n\"\"\"\n\n''' \nOtro comentario de varias lineas\n'''\n\n# 3) variable y constante\nvariable = \"texto\"\nCONSTANTE = \"texto constante\"\n\n# 4) Tipos de variables primitivas https://docs.python.org/es/3/library/stdtypes.html    \n# Los nombre:int= 123 son anotaciones para especificar el tipo de una variable es opcional.\n# Tipos numericos, int,float,complex\nnumero:int = 123\nflotante:float = 3.1416\ncomplejo:complex = 3j\n\n# Tipos boleanos\nverdadero:bool = True\nfalso:bool = False\n\n# Tipos secuencia, list,tuple, range\nlista:list = [1,2,3,4,4,4]\ntupla:tuple = (1,2,3,4)\nrangos = list(range(10))\n\n# Tipo de dato string\ntexto:str = \"string\"\ntexto1,texto2 = \"str\",'str'\ntexto_multilinea:str = \"\"\"\nTexto multilinea en python\n\"\"\"\n# Tipo de dato bytes\nbyte = b'valor binario' \n\n# Tipo de dato set frozenset y dict\nconjunto:set = {1,2,3}\nconjunto_inmutable:frozenset = {1,2,3,4}\ndicionario:dict = {\"one\":1,\"two\":2,\"three\":3}\n\n# Tipo de dato NULL o None\nnull = None\n\n# 5) print() hola Python\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/davidrguez98.py",
    "content": "\"\"\" /*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */ \"\"\"\n\n#EJERCICIO\n\n# https://python.org\n\n# Comentario en una línea\n\n\"\"\"\nEsto también es\nun comentario\nen varias líneas\n\"\"\"\n\n'''\nEsto también es\nun comentario\nen varias líneas\n'''\n\nmy_variable = \"Mi variable\"\nmy_variable = \"Nuevo valor de mi variable\"\n\nMY_CONSTANT = \"Mi constante\"  # por convención\n\nmy_int = 1\nmy_float = 1.5\nmy_bool = True\nmy_bool = False\nmy_string = \"Mi cadena de texto\"\nmy_other_string = 'Mi otra cadena de texto'\n\nprint(\"¡Hola, Python!\")\n\nprint(type(my_int))\nprint(type(my_float))\nprint(type(my_bool))\nprint(type(my_string))"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/decinx1.py",
    "content": "# ESTE ES UN COMENTARIO SENCILLO, UTILIZADO PARA COMENTAR UNA SOLA LINA \n# ESTA ES LA URL DE PYTHON : https://www.python.org/ \n\n\n\"\"\"\n----------------------------------------------- Inicio ------------------------------------------------\n\nEste es un ejemplo de comentario en multiples lienas, utilizado para docuemntar partes extensas de codigo \niniciar una documentacion extensa  como esta por ejemplo o para lo que gustes realizar en esta clase de coentarios \n\nOJO: tener en cuenta que tienes que ser 3 pares de comillas para englobar como comentario todos lo que este dentro de esta \nsi no se cierran estas comillas comenraran todo, hasta encontrar de comillas dobles que  las cierren veamoslo como lo son los \n\ncodigo{\ncontenido del codigo\n}\n\ncodigo[\ncontenido del codigo \n]\n\no como lo son las tabulacion es python \n\n------------------------------------------------- Fin --------------------------------------------------\n\"\"\"\n\n\n'''\n----------------------------------------------- Inicio ------------------------------------------------\n\nEsta misma manera de docuemtnar funciona con comillas simples ''  teniendo los mismo parametros y condiciones\nque la aanterir manera de comentar \n\n------------------------------------------------- Fin --------------------------------------------------\n'''\n\n#Variale \npython = \"python\"\n\n#Python no admite constantes de manera nativa \n\n#Tipos de datos primarios \n\nNumero_entero = int(10) #Numeros enteros, no admite decimales \nNumero_flotante = float(10.11) #Numeros flotantes admite numeros decimales \nBooleano1 = bool(1) #Numeros bo0leanos solo admiten 0 y 1\nBooleano = bool(0)# Solo admite Verdadero = 1 y Falso = 0\nCadena = str('!Hola')#Tipo de dato que admite letras utilizado para guardar valores \n\nprint((Cadena), python )"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/deivimiller.py",
    "content": "#  https://python.org\n\n# eso es un comentario de una linea \n\n\"\"\" \neso es un comentario \nde varias \nlienas \n\"\"\"\n\n''' \neso es un comentario \nde varias \nliena\n´´´\n\nmy_variable = \" Mi variable\"\nmy_variable = \" Mi nuevo valor de la variable\"\n\nmy_CONSTANT = \" Mi constante \"  # por convencion \n\nmy_int = 1\nmy_float = 1.5\nmy_bools = True\nmy_bools = False\nmy_string = \" Mi cadena de texto\"\nmy_other_string = ´ Mi otra cadena de texto ´\n\nprint(\"hola , python \")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/demegorash.py",
    "content": "# Hello, this is a comment showing the official website for Python: https://www.python.org\n\n# This is a single line comment.\n\n\"\"\"\nHere, I can show and type\na multi-line code.  As you can\nsee, I am using double coutes in order\nto show it.  Nice right?\n\"\"\"\n\n# This is going to be a varible example\n\nname = \"Demegorash\"\nage = 45\ncountry = \"Costa Rica\"\n\nprint(\"My name is:\", name, \".\", \"I am \", age, \"years old\", \".\", \"I live in: \", country, \".\")\n\n# This is going to be a constant example\n\nPI = 3.1415927\nC =  299792458\n\nprint(PI)\nprint(C)\nprint(PI, \"is Pi and\", C, \"is ligth speed in the vacuum (we represent it as c).\")\n\n\n# Some examples of data in python\n\nstring_example = \"This is a string example\"\nprint(type(string_example))\ninteger = 42\nprint(type(integer))\nfloat = 3.14\nprint(type(float))\nboolean = True\nprint(type(boolean))\ncomplex_number = 2 + 3j\nprint(type(complex_number))\n\n# This is an example of a function named print\nthis_example = \"Python\"\nprint(\"Hola, \", this_example, \"!!!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/devjerez.py",
    "content": "# App: Gestor TPV Pan-game\n\n# Tecnologia aplicada: https://python.org\n\n\"\"\"\n¡App para la gestión de los clientes, cuando pagan y cuando dejan una barra a deber!\n\n\"\"\"\n\n# Variables\nmi_producto = \"barra\"\nmi_producto = \"barra grande\" \n\n# Constante por convección\nRECETA_MASA = \"receta.txt\"\n\n# Datos primitivos\n\n# Enteros - Int\nharina_Kg = 25\n\n# Decimal - Float\nagua_L = 4.5\n\n# Booleano - True or False\ntipo_Integral = False\n\n# Cadena de texto - String\ndias_Tienda = \"Lunes a Domingo\"\nhorario_Tienda = '06:00 a 13.30'\n\n#Impresion por consola\nprint(\"¡Hola, esta app esta creada en Python!\")\n\nprint(type(harina_Kg))\nprint(type(agua_L))\nprint(type(tipo_Integral))\nprint(type(dias_Tienda))\nprint(type(horario_Tienda))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/dfnevar.py",
    "content": "# Link página: https://www.python.org/\n\n#Comentario de una línea\n\n\"\"\" \nComentario de \nmultiples lineas\n\"\"\"\n\nmivariable = \"variable\"\nmiconstante = \"constante\" #Hacer una constante de variable\n\nvariable_float = 1.1\nvariable_int = 1\nvariable_bool1 = True\nvariable_string = \"Hola python\"\n\nprint(\"Holaaa  Python\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/dgroes.py",
    "content": "# La documentación de Python oficial: https://www.python.org/\n\"\"\"\nEsta sería una variable básica en Python, \nuna regla básica para crear una variable es elegir una sintaxis de escritura. No es una regla extricta elegir un tipo, lo ideal es elegir uno para todo\nel código a escribir. Pero por \"convenciones generales\" es mas usado 'snake_case' mas que otros tipos de sintaxis.\n\"\"\"\nfirst_string = \"Variable básica de Python (tipo String)\"\n\n# En python no hay algo especial para crear variables constantes, pero un ayuda visual es siempre crear las constantes en mayúsculas.\nPI = 3, 14159\n\n# Datos primitivos en Python\ncadena_texto = \"The winter is coming\"  # <- Variable Tipo: String\nnumero_entero = 7\nnumero_decimal = 23.2\ndato_boleano = True\nlista = [\"Needle\", \"Widow's Wail\", \"Oathkeeper\", \"Ice\"]\ntupla = (\"Stark\", \"Targaryen\", \"Bolton\", \"Lannister\")\ndiccionario = {\n    \"character\": \"Jon Snow\",\n    \"house\": \"Stark\",\n    \"status\": \"King in the North\"\n}\n\nprint(\"Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/didacdev.py",
    "content": "## https://www.python.org\n\n# Comentario de una línea\n\n\"\"\"\n    Comentario\n    de\n    varias\n    líneas\n\"\"\"\n\n# variables\nNAME = \"Diego\"\nage = 27\n\n# Tipos de datos primitivos\ninteger = 0\nfloat = 0.1\nstring = \"string\"\nboolean = True\n\n# Imprimir\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/diegoasebey.py",
    "content": "# La página oficial de Python: https://www.python.org/\n\n# Este es un comentario. Sirve para crear una sola línea física\n\n\"\"\" Esto corresponde\ncon un comentario en\nmúltiples líneas.\nSegún la documenta-\nción de Python se \nllama \"cadena de do-\ncomentación\n\"\"\"\n\n'''\nAsí también se puede\nescribir un comentario\nde varias líneas\n'''\n\nvariable = \"esto es una variable\"\nCONSTANTE = \"esto es una constante\" # Python, al parecer, no tiene constantes, pero, dicen, se suele escribir en mayúsculas el id. de un objeto que se pretende invariable\n\na = None    # none\nb = 5       # entero\nc = True    # booleano\nd = 4.5     # punto flotante\ne = \"perro\" # cadena\nf = 'gato'  # cadena variando las comillas, igual de válidas\n\n\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/diegopc-dev.py",
    "content": "#Variables y tipos de datos\n\n#Web oficial Python: https://www.python.org/\n\n#Comentario de una línea\n\n'''\n    Comentario de varias líneas\n    Normalmente se usa para describir las funciones\n    indicando el/los parametro/s de entrada y/o salida\n'''\n\ntext = \"variable\"\n\nCONSTANT = \"constante\"\n#En python no existe este tipo de dato,\n#pero se representa con la variable en mayusculas\n\nnum_int = 23 #integer (int)\nprint(num_int, type(num_int))\nnum_float = 23.33 #float\nprint(num_float, type(num_float))\nvar1_bool = True\nprint(var1_bool, type(var1_bool))\nvar2_bool = False\nprint(var2_bool, type(var2_bool))\ntext2 = \"Esto es una cadena de texto\"\nprint(text2, type(text2))\ntext3 = 'Puede usarse con comillas simples tambien'\nprint(text3, type(text3))\n\nprint(\"¡Hola, python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/dieguillo1985.py",
    "content": "# https://python.org\n\n# haremos comentarios simples encabezando con una almohadilla\n\n  \"\"\"\n  abriendo con tres dobles comillas y cerrando con las mismas \n  tres dobles comillas podemos\n  hacer comentario simples en varias lineas\n  \"\"\"\n\n  '''\n  con comillas simples \n  tambien podemos escribir \n  comenatarios simples\n  '''\n\n  my_variable = \"esta es mi variable\"\n  my_variable = \"esta es mi nueva variable\"\n\n  MY_CONSTANT = \"mi constante\" #por convención\n  \n  my_int = 1\n  my_float = 3,5\n  my_bool = True\n  my_bool = False\n  my_string = \"esta es mi cadena de texto\"\n  my_other_string = 'esta es mi otra cadena de texto'\n    \n  print = (\"¡ Hola , Python !\") \n    \n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/dimanu-py.py",
    "content": "# Selected language: https://www.python.org/\n\nprogramming_language = \"Python\" # This is a variable and a single line comment\n\n'''\nIn Python we don't have constants, but we can use a variable with uppercase letters to indicate that it is a constant\n'''\nGRAVITY = 9.81\n\n\"\"\"\nOne problem we can face defining constants this way is that we can change its value.\n\nOne alternative way to create constants value is to create enumerations or dataclasses with the argument frozen=True\n\"\"\"\n\n# Using enumerations\nfrom enum import Enum\n\nclass ConstantsEnum(Enum):\n    GRAVITY = 9.81\n\ngravity = ConstantsEnum.GRAVITY.value\nprint(f\"Gravity value: {gravity}\")\n\n# ConstantsEnum.GRAVITY.value = 100 # This will raise an error if uncommented\n\n# Using dataclasses\nfrom dataclasses import dataclass\n\n@dataclass(frozen=True)\nclass ConstantsDataClass:\n    GRAVITY = 9.81\n    \nconstants_dataclass = ConstantsDataClass()\ngravity = constants_dataclass.GRAVITY\nprint(f\"Gravity value: {gravity}\")\n\n# constants_dataclass.GRAVITY = 100 # This will raise an error if uncommented\n\n# Data types\nname = \"Diego\"\nage = 25\nheight = 1.79\nis_developer = True\nlanguages = [\"Python\", \"C++\", \"Java\"]\nbirth_date = (1_998, 12, 6)\ndog = {\n    \"name\": \"Bruno\",\n    \"age\": 2,\n    \"breed\": \"French Poodle\"\n}\n\n# Greeting\nprint(f\"Hello, {programming_language}!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/dimasb69.py",
    "content": "# URL del Lenguaje usado: https://www.python.org/\n\n#Sintaxis para crear una liena de comentario\n\n'''Sintaxis para un comentarios\nde multiples lineas'''\n\nvariable = \"valor de la variale\"\n\nCONSTANTE = \"Valor constante\" #en Python todo es variable pero por practica se usa una variable en mayusculas para indicar que es constante\n\n\nvar_str = \"Hola,\"+' Python' #se puede usar comillas simples o triple doble comiila \"\"\" ó ''' para multiples lineas\n\n\nvar_int = 5 # solo enteros \n\n\nvar_float = 5.1 # soporta decimales\n\n\nvar_bool = True # solo puede ser True o False\n\nprint(f'''\n      var_str es de {type(var_str)}\n      \n      var_int es de {type(var_int)}\n      \n      var_float es de {type(var_float)}\n      \n      var_bool es de {type(var_bool)}\n      \n      \n      {var_str}\n      ''')\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/dmiaan.py",
    "content": "# Creación de comentario con la URL:\n# https://www.python.org/\n\n\n# Sintaxis de comentarios:\n# En una línea\n\"\"\"\nVarias líneas\n\"\"\"\n\n# Creacion de variable:\nlenguaje = \"python\"\n\n# Creación de variables representadndo los tipos de datos:\n\n# numeros enteros(int): pueden ser 1, 2, 3 , 40, etc.\nnumero_entero = 10\n\n# numeros flotantes o numeros con decimales(float): 2.10, 2.50, etc.\nnumero_float = 2.40\n\n# cadenas de texto(string): es un dato que sirve para colocar texto.\n\ncadena_texto = \"Hola, soy nuevo\"\n\n# char: caracter de una sola letra o simbolo, ya sea \"A\", \"?\", \"!\", etc.\n\nchar = \"a\"\n\n# Booleano: Basicamente es si una condicion es verdadera o falsa y se identifican como: True = Verdarero y False = Falso.\n\nverdadero = True\nfalso = False\n\nprint(\"¡Hola, [Python]!\")\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/dokeys28.py",
    "content": "#https://www.python.org\n\n'''\nLink oficial de Python\nhttp://www.python.org\n'''\n\nmi_variable = 'Manzana'\nmi_variable = 'Pera'\nMICONSTANTE = 3.14\n\nmi_string : str = 'soy un string'\nmi_int : int = 1\nmi_float : float = 0.35\nmi_booleano : bool = True\nmi_lista : list = []\nmi_tupla : tuple = (1, 2, 3, 4)\nmi_set : set = (['Negro','Rojo','Azul'])\nmi_diccionario : dict = {'a' : 1, 'b': 2, 'c': 3, 'd': 4}\nprint('¡Hola, Python!')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/domo2pdev.py",
    "content": "\"\"\"\nEJERCICIO:\n - Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n - Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n - Crea una variable (y una constante si el lenguaje lo soporta).\n - Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n \"\"\"\n\n\n# Esta es la web oficial de python https://python.org\n\n# Sintaxis de comentarios:\n\n# Este es un comentario de una sola linea\n\n\"\"\"\nEste es un comentario de varias lineas\n\"\"\"\n\n'''Este es otro comentario de varias lineas'''\n\n# Definicion de variables:\nmy_variable = \"Soy una variable\"\n\n#definicion de constantes por convencion se escriben en MAYUSCULAS.\nMY_CONSTANT = \"Soy una constante\"\n\n# Tipos de datos primitivos:\nmy_int = 42\nmy_float = 6.22\nmy_string = \"Hola, Python\"\nanother_string = 'Python, Hola!'\nmy_bool = True\nanother_bool = False    \n\n# Imprimir por consola:\nprint(\"Hola, Python!\")\nprint(my_variable)\nprint(MY_CONSTANT)\nprint(my_int)\nprint(my_float)\nprint(another_string)\nprint(type(my_bool))\nprint(type(my_string))"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/duendeintemporal.py",
    "content": "# Documentación https://www.python.org/\n#Exercise 0 rutaparaprogramadores\n\n#one line comment\n'''\nmulti\nlines comment\n\n'''\n\"\"\"\nmulti line \ncomment\n\n\"\"\"\nlenguage = 'RUST'\nlenguage = 'PYTHON'\n\nprint(lenguage) #Print: Python\n\nmy_int = 4\nmy_float = 4.8\nmy_string = 'Oh Boy!!'\nmy_bool = False\nmy_bool = not my_bool\nmy_null = None\n\nprint(my_int) # Print:  4\nprint(type(my_int)) # Print:  class int\nprint(my_float) # Print: 4.8\nprint(type(my_float)) # Print: class float\nprint(my_string) # Print: Oh Boy!!\nprint(type(my_string)) # Print: class str\nprint(my_bool) # Print: class bool\nprint(type(my_bool)) # Print: True\nprint(my_null) # Print: None\nprint(type(my_null)) # Print: class NoneType\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/dvidmdina.py",
    "content": "# https://www.python.org/\n\n# comentario en una linea\n \n\"\"\"\ncomentario en\nvarias lineas\n\"\"\"\n\nvariable_num = 1\n\nvariable_num = \"varia\"\n\nvariable_str = \"hola\"\n\nvariable_bool = True\n\nvariable_int = 3\n\nvariable_float = 1.5\n\n\nCONST_STR = \"constante por convencion\"\n\nprint(\"hola, python\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/eamartin96.py",
    "content": "# https://www.python.org/\n\n# Single line comment\n\n\"\"\"\nMultiple\nline\ncomment\n\"\"\"\n\n# Create variables\nvariable1 = 5\n\n# Create a constant\nE = 2.718\n\n# Data types\n\n# Text type\ndata_string = \"Hola mundo\"\n\n# Numeric types\ndata_int = 96\ndata_float = 3.14\n\n# Sequence types\ndata_list = [\"apple\", \"banana\", \"cherry\"]\ndata_tuple = (\"apple\", \"banana\", \"cherry\")\ndata_range = range(1,100)\n\n# Mapping type\ndata_dict = {\"Name\" : \"Jane\", \"Last_Name\" : \"Doe\", \"Age\" : 30}\n\n# Boolean types\ndata_bool = True\n\n# Binary types\ndata_bytes = b\"Hello\"\n\nlanguage = \"Python\"\nprint(f\"¡Hola, {language}!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/eatsangels.py",
    "content": "# Con el simbolo # podemos hacer comentarios de una sola linea, Esta es la web oficinal de Python: https://www.python.org\n\n\"\"\" Con est se puede hacer\ncomentarios de varias lineas\n\"\"\"\n\n''' Con triple comillas igual se puede\nhacer comentarios de varias lineas'''\n\n\n# Creando una variable\nVariable =  \"Soy Edward Trinidad!\"\n\n# Creando una constante (En eralidad no existe en Python).\nCONSTANTE = \"Programar\"\n\n\n# Creando variables de diferentes tipos primitivos\nEntero = 1\n\nFlotante = 1.1\n\nBooleano = True\nBooleano = False\n\nCadena = \"Hola\"\notra_cadena_texto = 'Python'\n\n\nprint (f\"Hola {Variable} y megusta {CONSTANTE}\")\n\n\n# Imprimiendo el tipo de dato de las variables\nprint(type(Variable))\nprint(type(Entero))\nprint(type(Flotante))\nprint(type(Booleano))\nprint(type(Booleano))\nprint(type(Cadena))\nprint(type(otra_cadena_texto))\n\n\n\"\"\"\nFin del primer\nejercicio.\n\"\"\"\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/eckoseal89.py",
    "content": "#http://python.org/\r\n\r\n#En una linea\r\n#O en otra linea\r\n\r\n\"\"\"Otro\r\nComentario\"\"\"\r\n\r\nvar1 = 1\r\n\r\ntext = \"Una cadena\"\r\nentero = 1\r\nlista = [\"lista\", 1, 3.5, [1,2,3], (1,2)]\r\nflotante = 3.14\r\ntupla = (1, \"hola\", 3.5)\r\nunset = {1, 3.5, \"hola\", [1,2,3]}\r\n\r\nprint(\"Hola, Python\")\r\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/edalmava.py",
    "content": "# Un comentario comienza con un carácter de almohadilla (#) que no es parte de un literal de cadena,\n# y termina al final de la línea física\n# Comentario de una línea que va hasta el final\n\n# Si un comentario en la primera o segunda línea del script de Python coincide con la expresión regular \n# coding[=:]\\s*([-\\w.]+), este comentario se procesa como una declaración de codificación; \n# -*- coding: <encoding-name> -*-\n# Si no hay una declaración de codificación, la codificación por defecto es UTF-8\n\n# Sitio oficial: https://www.python.org/\n\n# Variables\nvariable = 'valor'         # Operador de asignación =\n\n# Tipos Numéricos\nenteros = -37              # Números enteros (int)\nflotante = 10.5            # Números de punto flotante de doble precisión (float)\ncomplejo = complex(1, 4.5) # complex(real=0, imag=0)\n\n# Tipos Booleanos (bool) en Python son un subtipo del tipo entero\nverdadero = True           # Se comporta como un 1\nfalso = False              # Se comporta como un 0\n\n# Tipos Texto: son secuencias inmutables\nsaludo = \"Hola\"\nlenguaje = 'Python'\n# f-strings\nmensaje = f\"¡{saludo}, {lenguaje}!\"\n\n# Tipos Compuestos\n# Tuplas: secuencias inmutables\ntupla = (1, 2, 3, 4, 5)\n# Listas: secuencias mutables\nnumeros = [1, 2, 3, 4, 5]\n\n# Mapeos - Diccionarios - son mutables\n# Estos representan conjuntos finitos de objetos indexados por conjuntos de índices arbitrarios. \ndiccionario = {'hello': \"hola\", 'sun': \"sol\", 'hi': \"hola\"}\n\n# Imprimir por consola\nprint(mensaje)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/eddyelx.py",
    "content": "# https://www.python.org/\n\n\n# Comentario en una linea\n\n\"\"\"\nEsto tambien es \nun comentario\nen varias lineas\n\"\"\"\n\nmy_variable = \"Mi variable\"\nmy_variable = \"Nuevo valor de mi variable\"\n\nMY_CONSTANTE = \"Mi constante\" # por convencion\n\nmy_int = 1\nmy_float = 1,5\nmy_bool = True\nmy_bool = False\nmy_string = \"Mi cadena de texto\"\nmy_other_string = \"Mi otra cadena de texto\"\n\nprint (\"¡Hola,Python\")\n\nprint (type(my_int))\nprint (type(my_float))\nprint (type(my_bool))\nprint (type(my_string))\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/eddyfals0.py",
    "content": "############################################################\n#  Lenguaje: PYTHON\n#  OFFICIAL SITE → https://www.python.org\n############################################################\n\n# ===============================\n# // COMMENTS: SINGLE LINE\n# ===============================\n# Acceso concedido. Inicializando sistema...\n\n\"\"\"\n=================================\n|| COMMENTS: MULTI LINE BLOCK  ||\n=================================\n\"\"\"\n\n# ===============================\n# // VARIABLES & CONSTANTS\n# ===============================\n\nLANGUAGE = \"Python\"      # Constante (convención)\nuser_alias = \"root\"      # Variable\naccess_level = 0x2A      # Entero en hexadecimal\nprecision = 3.14159      # Float\nsystem_online = True    # Boolean\nnull_pointer = None     # Null / NoneType\n\n# ===============================\n# // DATA TYPES DUMP\n# ===============================\n\nstring_data = \"Encrypted string\"\nint_data = 1337\nfloat_data = 0.404\nbool_data = False\n\n# ===============================\n# // TERMINAL OUTPUT\n# ===============================\n\nprint(\"=================================\")\nprint(f\">>> BOOT SEQUENCE COMPLETE\")\nprint(f\">>> Hola, {LANGUAGE}\")\nprint(f\">>> User: {user_alias}\")\nprint(\"=================================\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/eduardoherrarte.py",
    "content": "# https://www.python.org/\n\n# Comentario de una sola línea\n\n\"\"\"\nComentario multilínea:\nPuedes usar comillas triples para escribir\ncomentarios en varias líneas.\n\"\"\"\n\n'''\nTambién puedes usar comillas simples triples.\npara comentarios multilínea.\n'''\n\n# Variables y constantes\n\n# En Python no existen constantes reales, pero por convención\n# se escriben en MAYÚSCULAS para indicar que no deberían cambiar.\nPI = 3.14159\n\n# Variable normal\nmensaje = \"Aprendiendo Python\"\n\n# Tipos de datos primitivos en Python\n\ncadena = \"Hola mundo\"     # str\nentero = 42               # int\nflotante = 3.14           # float\nbooleano = True           # bool\ncomplejo = 2 + 3j         # complex\nnulo = None               # NoneType\n\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/eduhumanes91.py",
    "content": "#La Web oficial de Python es: https://www.python.org/\n\n#Esto es un comentario en una linea\n\n\"\"\"\nEsto es un comentario\nen varias lineas\n\"\"\"\nvariable = \"Esto es una variable\"\n\n#En Python no existen las contantes\n\ncadena_de_texto = \"Esto es una variable de tipo texto: str\"\nentero = 1 #Esto es una variable de tipo entero: int\nflotante = 1.52 #Esto es una variable de tipo flotante: float\nbooleano = True #Esto es una variable de tipo booleano: bool\ncomplejo = 2 + 1j #Esto es una variable de tipo complejo: complex\nlista = [1, 2, 3] #Esto es una variable del tipo lista: list\ntupla = (1, 2, 3) #Esto es una variable del tipo tupla: tuple\ndiccionario = {1:\"uno\", 2:\"dos\", 3:\"tres\"}#Esto es una variable del tipo diccionario: diet\nset = {1, 2, 3, \"a\", \"b\"} #Esto es una variable del tipo set: set\n\nprint (\"¡Hola, Python!\")\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/ejaram3.py",
    "content": "# https://www.python.org\n\n# Este es un comentario de una sola linea\n\n\"\"\"\nEste\nes un\ncomentario\nde varias\nlineas\n\"\"\"\n\nvariable: str  # Variable\nCONSTANTE = \"\"  # Constante\n\nnombre: str = \"python\"  # Texto o secuencia de caracteres\nx: int = 123  # Números enteros (positivos y negativos)\npi: float = 23.4  # Números de punto flotante\nactivo: bool = True  # Valores de verdad (True o False)\ndato: None = None  # Representa la ausencia de valor\nb: bytes = b\"ABC\"  # Secuencia inmutable de datos binarios\nba: bytearray = bytearray(3)  # Secuencia mutable de los datos binarios\nmv: memoryview = memoryview(b)  # Vista de memoria sobre los datos binarios\nz: complex = 2 + 3j  # Número complejos (parte real e imaginaria)\n\nprint(\"!Hola Python¡\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/elder202.py",
    "content": "# https://www.python.org/\n\n# Primer comentario\n\n''' Segundo \ncomentario \n'''\n\nvariable1 = 'texto'\nvariable2 = \"texto2\"\nvariable3 = \"Esto es un string\"\nvariable4 = int(1)\nvariable5 = float(1.5)\nvariable6 = True\nPI = 3.14\n\nlenguaje = \"python\"\nprint(f\"¡Hola, {lenguaje}!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/eljavi0.py",
    "content": "# https://www.python.org/\n\n# comentario en una linea\n\n\"\"\"\nesto tambien es un\ncomentario en varias\nlineas\n\"\"\"\n\n'''\notro comentario\nen varias lineas\n'''\n\nnew_variable = \"nueva variable\"\nnew_variable = \"nuevo valor de la variable\"\n\nMY_CONSTANT = \"nueva constante\" #no puede cambiar el valor de esta variable!, #por convencion\n\n# tipos de datos primitivos\n\nmy_number = 1 #un int\nmy_float = 1.2\nmy_bool = True\nmy_bool = False\nmy_string = 'cadena de texo'\nmy_other_string = \"otra cadena de texto\"\n\nprint(\"¡hola, python!\")\n\nprint(type(my_number))\nprint(type(my_float))\nprint(type(my_bool))\nprint(type(my_string))\nprint(type(my_other_string))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/elkin-dev.py",
    "content": "# url de la página oficial de Python, https://www.python.org/\n\n# Esto en un comentario de una sola línea\n\"\"\" Esto es\nun comentario\nde varias líneas\nen Python\"\"\"\n\nvariable = \"\"\nCONSTANT = 3.14\n\n# Tipos de datos en Python\ntype_int: int = 10\ntype_float: float = 1.4\ntype_complex: complex = 2 + 4j\ntype_string: str = \"I am a string\"\ntype_boolean: bool = True\n\nname_language: str = \"Python\"\nprint(\"Hola\", name_language)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/eloitr.py",
    "content": "from types import NoneType\n\n\"\"\"\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n\"\"\"\n\n#https://www.python.org\n\n#Este es un comenario en una línea\n\"\"\"\nEste\nes\nun\ncomentario \nen\nvarias\nlíneas\n\"\"\"\n'''\nEste\nes\nun\ncomentario \nen\nvarias\nlíneas\n'''\n\n\n\n#CREAR VARIABLE Y CONSTANTE\nmi_variable = \"¡Hola, PYTHON!\"\nMI_CONSTANTE = 1234567890988776756\n\n#TIPOS DE VARIABLE\nmy_string: str = \"Hola Python\"\nmy_int: int = 1234567890\nmy_float: float = 1.123456789\nmy_bool: bool = True\nvalor_nulo: NoneType = None\n\n#PRINT \nprint(\"¡Hola, PYTHON!\")\nprint(mi_variable)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/emilianohoyos.py",
    "content": "#https://www.python.org/\n\n#comentario una sola linea\n\n\"\"\"\ncomentario en \nvarias lineas\n\"\"\"\n\n'''\ncomentario en \nvarias lineas\n'''\n\nmi_color='rojo'\n\nMI_CONSTANTE='ESTATICO' #esto me esta intentando representar una constante, en python no existen\n \n#Crea variables representando todos los tipos de datos primitivos\n#   del lenguaje (cadenas de texto, enteros, booleanos...).\n\nenteros=1\n\nflotante=9.3\n\ncomplejo=3+2j\n\ntexto='Hola Mundo'\n\nbooleano=False\nbooleano=True\n\nlista=[1,2,3,4,5]\n\ntupla=(1,2,3,4)\n\nrango=(0,10,1)\n\ndiccionario={'nombre':'Carlos', 'edad':30, 'ciudad':'Medellin'}\n\n#Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\nprint(\"hola\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/estelacode.py",
    "content": "## 1.Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n\n#Website of Python: https://www.python.org/ ; Documentation: https://docs.python.org/3/ ; Python Documentation by Version: https://www.python.org/doc/versions/\n\n\n## 2. Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n\n# This is a comment on a line\n\n\n# Multi \n# Line \n# Comment\n\n\"\"\" Multi-line Comment\"\"\"  # double triple quotes multiline string \n\n''' Multi-line Comment'''  # simple triple quotes multiline string \n\n## 3. Crea una variable (y una constante si el lenguaje lo soporta).\n\n# variable  \nnum=10\n\n#Constante\nPI = 3.1416\n\n## 4. Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n\n# String\nname = \"Alejandro\"\n# Integer\nage = 30\n# Float\nheight = 1.80\n# Boolean\nis_male = True\nis_female = False\n\n## 5. Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nprint('¡Hola, Python!')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/estuardodev.py",
    "content": "# #00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n'''\n    Sitio web oficial de C#\n    https://dotnet.microsoft.com/es-es/languages/csharp\n'''\n\ndef run():\n    _greeting = \"Hola\"\n    _language = \"C#\"\n    _year = 2024\n    _comma = ','\n    _earthYears = 45400000\n    _pi = 3.14159265359\n    _piShort = 3.14\n    _subscribed = True\n\n    print(f\"¡{_greeting}{_comma} {_language} en Retos de Programación {_year}!\")\n\nif __name__ == '__main__':\n    run()"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/eugeniasoria.py",
    "content": "# #00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\r\n\"\"\"\r\n * EJERCICIO:\r\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\r\n *   lenguaje de programación que has seleccionado.\r\n * - Representa las diferentes sintaxis que existen de crear comentarios\r\n *   en el lenguaje (en una línea, varias...).\r\n * - Crea una variable (y una constante si el lenguaje lo soporta).\r\n * - Crea variables representando todos los tipos de datos primitivos\r\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\r\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\r\n *\r\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\r\n * debemos comenzar por el principio.\r\n */\r\n\"\"\"\r\n\r\n# Sitio oficial de Python\r\n# https://www.python.org/\r\n \r\n# Comentario de una linea\r\n\r\n\"\"\"\r\n   Comentario de múltiples líneas \r\n   con comillas dobles\r\n\"\"\"\r\n\r\n'''\r\n  Comentario de múltiples líneas \r\n  con comillas simples\r\n'''\r\n\r\n# Variable\r\nmi_variable = 'valor'\r\n'''\r\nConstante: No existen las constantes en Python pero se puede usar \r\nun nombre en mayúsculas como convención para identificarla como tal\r\n''' \r\nMI_CONSTANTE = 'NO CAMBIAR'\r\n'''\r\n# Tipos de Datos primitivos\r\nStrings (str).\r\nIntegers (int).\r\nFloats (float).\r\nBooleans (bool)\r\nNone (caso especial).\r\n'''\r\nstring_var = 'Esta es una variable string'\r\nprint(type(string_var))\r\n\r\ninteger_var = 44\r\nprint(type(integer_var))\r\n\r\nfloat_var = 16.8\r\nprint(type(float_var))\r\n\r\nboolean_var = True\r\nprint(type(boolean_var))\r\n\r\nnone_var = None\r\nprint(type(none_var))\r\n\r\nprint ('¡Hola, Python!')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/evilpotato04.py",
    "content": "#/*\n# * EJERCICIO:\n# * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n# *   lenguaje de programación que has seleccionado.\n# * - Representa las diferentes sintaxis que existen de crear comentarios\n# *   en el lenguaje (en una línea, varias...).\n# * - Crea una variable (y una constante si el lenguaje lo soporta).\n# * - Crea variables representando todos los tipos de datos primitivos\n# *   del lenguaje (cadenas de texto, enteros, booleanos...).\n# * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n# */\n\n# https://www.python.org/\n\n\"\"\"\nEsto no es exactamente un comentario,\npero sirve como un comentario de varias líneas\no una String para la documentación del método\n\"\"\"\n\n# Tipos de datos primitivos simples\n# -> numeros enteros (int)\nnumero_entero = 42\nnumero_negativo = -42\n\n# -> numeros decimales (float)\nnumero_decimal = 4.2\n\n# -> cadenas (strings)\nmessage = 'hola mundo'\nmessage2 = \"hola mundo 2\"\n\n# -> booleanos (boolean)\nesta_completo = True\nse_acabo = False\n\n# Tipos de datos primitivos compuestos (contenedores)\n# -> listas (lists)\nlista_de_tareas_1 = [\"barrer la casa\", \"lavar la loza\", \"hacer la cena\"]\n\n# -> tuplas (tuples)\nlista_de_tareas_2 = (\"barrer la casa\", \"lavar la loza\", \"hacer la cena\")\n\n# -> diccionarios (dictionaries)\nlista_de_tareas_3 = {\n    \"tarea_1\": \"barrer la casa\",\n    \"tarea_2\": \"lavar la loza\",\n    \"tarea_3\": \"hacer la cena\"\n}\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/facundorsabia.py",
    "content": "# Ejercicio 00\n\n# https://www.python.org\n\n# Sintaxis para comentarios en Python\n\n# Este es un lenguaje de una linea\n\n'''\nEste es\nun comentario\nmultilinea\n'''\n\n\"\"\"\nY este\ntambién\n\"\"\"\n\n#Variables\nmy_variable = \"Mi Variable\"\nmy_variable = \"Nuevo valor de mi variable\"\n\n\n'''\nEn Python no existen las constantes, aunque es lo que se pide.\nSin embargo por convención la idea sería utilizar mayúsculas \npara que se entienda la intención de que no cambie el valor del dato\n'''\n\nMY_CONSTANT = \"Mi Constante\"\n\n#Datos primitivos, en Python existen 4\n\n#Numeros Enteros\nmy_int = 1\n\n#Números decimales\nmy_float = 1.5\n\n#Boolean\nmy_bool = True\nmy_bool = False\n\n#Cadena de texto\nmy_string = \"Mi cadena de texto\"\n\n#Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\nprint(\"¡Hola, Python!\")\n\nprint(type(my_int))\nprint(type(my_float))\nprint(type(my_bool))\nprint(type(my_string))"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/fborjalv.py",
    "content": "\n# COMENTARIOS EN UNA ÚNICA LINEA\n\n# URL Sitio oficial de Python: https://python.org/\n# Puedes crear un comentario en una línea \n\n\n# COMENTARIOS EN VARIAS LINEAS\n\"\"\" \nPuedes crear un comentario en varias lineas,\nhaciendo uso de  tres  dobles comillas tanto al inicio como al final\n\n\"\"\"\n\n'''\nTambién dudes hacer un comentario en varias lineas,\ncon tres comillas simples, tanto al inicio como al final \n'''\n\n# DECLARACIÓN DE VARIABLES \n'''\nLas variables y las constantes se declaran de igual forma, con la única diferencia de que\nen los estandares de python las constantes se declaran en mayúsculas\n'''\n\nMY_CONSTANT = \"Esto es una constate\"\n\nmy_variable = \"esto es una variable\"\nmy_variable_2 = 2345\n\n# TIPOS DE DATOS\n\nenteros_int = 9\nflotante_float = 10.5\ncadena_texto_string = \"esto es una cadena de texto\"\nbool_true = True\nbool_false = False \n\n\n# Imprimir un texto por pantalla \n\nprint(\"Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/felipeDev303.py",
    "content": "# Web oficial de Python https://www.python.org/\n\n# Un comentario de una linea se utiliza el simbolo HASH (#)\n\n'''Para comentar varias lineas en Python se utilizan tres comillas simples o dobles \nal inicio y al final de cada bloque de texto.'''\n\n\"\"\"Este es el otro ejemplo de \nun comentario de varias lineas \ncon comillas dobles.\"\"\"\n\n# Las variables en Python se definen con el nombre de la variable seguido de un signo igual y el valor que se le asigna.\nmy_variable = \"Esta es mi variable\"\n\n# La misma variable puede ser reasignada con otro valor.\nmy_variable = \"Este es mi nuevo valor\"\n\n# Las constantes en Python por convención se definen con mayusculas y guiones bajos.\nMY_CONSTANT = \"Esta es mi constante\"\n\n# Tipos de datos en Python\n\n# Enteros (int)\nmy_int = 10\n\n# Flotantes (float)\nmy_float = 0.5\n\n# Cadenas de texto (str)\nmy_string = \"Hola Mundo\"\n\n# Booleanos (bool)\nmy_bool = True\nmy_bool = False\n\n# Para imprimir en consola se utiliza la función print()\nprint(\"Hola Mundo\")\n\n# Para determinar el tipo de dato\nprint(type(my_int))\nprint(type(my_float))\nprint(type(my_string))\nprint(type(my_bool))"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/fernando0gallego.py",
    "content": "#https://www.python.org/\n\n#comentario en una linea\n\"\"\"\nesto tambien es un\n comentario en varias lineas\n\"\"\"\n'''esto tambien es una\nforma de comentar'''\n\nmy_variable=\"mi nombre\"\nmy_variable= \"nuevo nombre para mi\"\n\nMY_CONSTANT=\"mi constante\" #por convencion\n\n#datos primitivos\n\n#enteros\nmy_int = 20\n#flotantes\n\nmy_float = 3.5\n\n\n\n\n#cadenas de texto\n\nmy_str = \"hola soy fernando\"\n\n\"\"\"booleanos\"\"\"\nmy_bool = True\nmy_bool= False\n\nprint(\"hola python\")\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/ferngPV.py",
    "content": "# www.python.org\n\n# este es un comentario de una sola linea \n\n\"\"\" \neste es un docstring un comentario de varias lineas\nque comunmente se utiliza para \npara documentar módulos, funciones, clases y métodos\n\"\"\"\n\n# Crea una variable (y una constante si el lenguaje lo soporta)\n# variable \nmy_variable = \"my_variable\"\n\n# constante\nMY_CONSTANT = \"my_constant\" #no es una constante pero se usa esta forma \n\n\"\"\"\nCrea variables representando todos los tipos de datos primitivos\ndel lenguaje (cadenas de texto, enteros, booleanos...).\n\"\"\"\n# Variable int (o numeros completos )\nX= 1\n#variable float (numeros decimales)\nY = 1.5\n# variable complex (donde se usan dos numeros int o float + una unidad imaginaria)\nZ = 2 + 3j\n# variable string (cadenas de texto)\nmy_variable = my_variable\n# varialbe boolean (variable de comparacion verdadero o falso\nMy_variable = True\nNot_myvariable = False\n\n#Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nmy_variable = \"hola python\"\nprint(my_variable)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/fidelysla.py",
    "content": "\"\"\"\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n\"\"\"\n\n# Pagina Web: https://www.python.org/\n\n# Este es un comentario de una linea\n\n\"\"\"\nEsto es un comenterio\nde varias lineas\nque puedes hacer\nen Python\n\"\"\"\n\n'''\nEsto tambien es un comenterio\nde varias lineas\nque puedes hacer\nen Python con \n'''\n\n# Variables\n\nmyVariable = \"Hello Word\"\nMY_CONST = \"Soy una constante\"\n\n# Datos Primitivos\n\nmyString = \"Hello\"\nmyInt = 123\nmyFloat = 123.4\nmyBool1 = True; myBool2 = False\nmyNonetype = None\n\n# Saludo\n\nprint(\"¡Hola, Python\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/fishellVvv.py",
    "content": "# https://pithon.org\n\n# comentario en una linea\n\n\"\"\"\ncomentario en\nvarias lineas\n\"\"\"\n\n'''\notro comentario en\nvarias lineas\n'''\n\nvariable = 0\nCONSTANTE = 0 # aunque no sea constante\n\nentero = 1 # int\nflotante = 2.5 # float\nbooleano = True # bool\ntexto = \"hola\" # str\n\nprint(\"Hola, Python\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/fjsubero.py",
    "content": "\"\"\"\n* EJERCICIO:\n   - Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n   - Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n   - Crea una variable (y una constante si el lenguaje lo soporta).\n   - Crea variables representando todos los tipos de datos primitivos\n     del lenguaje (cadenas de texto, enteros, booleanos...).\n   - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\"\"\"\n\n## Lenguaje Python ##\n\n# URL sitio web oficial:\n# https://www.python.org/\n\n## Sintaxis para crear comentarios ##\n\n# Comentarios en un sola linea:\n# Se utiliza el caracter \"#\" para esto\n\n# Comentarios en varias líneas:\n\"\"\"\nEsto es un comentario\nen varias líneas\n\"\"\"\n'''\nEsto tambien es\nun comentario\nde varias lineas\n'''\n\n## Variables y Constantes ##\nvar_mi_variable = \"esto es una variable\" # método de asignación de nombres snakecase\nVALOR_CONSTANTE = 3.14 # por convención se nombra en mayusculas\n\n## Datos primitivos ##\n\n# Tipo numérico\nentero = 8 # entero\ndecimal = 3.1415927 # decimales\ncomplejo = 3.3 + 3j # complejo\n\n# Tipo booleano\nverdadero = True\nfalso = False\nnulo = None  # None es el equivalente a NULL en otros lenguajes.\n\n# Tipo cadenas de caracteres\nstring = \"Cadena de texto\"  # Entre comillas simples o dobles.\n\n## Imprimir tipos de datos ##\nprint(type(entero))    # <class 'int'>\nprint(type(decimal))  # <class 'float'>\nprint(type(complejo))  # <class 'complex'>\nprint(type(verdadero))   # <class 'bool'>\nprint(type(falso))  # <class 'bool'>\nprint(type(nulo))   # <class 'NoneType'>\nprint(type(string))  # <class 'str'>\n\n# Imprime por terminal \"¡Hola, [y el nombre de tu lenguaje]!\"\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/francgci.py",
    "content": "# https://www.python.org/\n\n# estoy estudiando\n\n\"\"\"\ntodo lo\nque escribo\nes un\ncomentario\n\"\"\"\n\n'''\ntodo lo\nque escribo\nes un\ncomentario\n'''\n\ncarros = 3\ncarros = 9\n\nGALLINERO = 2\n\nmi_entero = 10\nmi_decimal  = 4.8\nmy_bool = True\nmy_bool = False\nmi_cadena = \"mi cadena de texto\"\n\nprint (\"Hola,[python]\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/franmux01.py",
    "content": "# https://python.org/\n\n# Comentario en una linea\n\n\"\"\"\nEsto tambien\nes un comentario\nen varias lineas\n\"\"\"\n\n'''\nProbando comillas simples\nen varias lineas\n'''\n\nmiVariable = \"Mi variable\"\nmiVariable = \"Nuevo valor de mi variable\"\n\nMY_CONSTANT = \"Mi constante\" #Por convencion\n\nmi_int = 5\nmi_float = 9.5\nmi_bool = True\nmi_str = \"Hola gente\"\n\nprint(\"Hola, Python!\")\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/franvozzi.py",
    "content": "# Sitio oficial Python https://www.python.org/\n\n# Comentario línea símple\n\n\"\"\"\nComentario de línea múltiple (docstring)\n\"\"\"\n\nprimerVariable = \"Hola curso!\"\n\ndiaDeHoy = 21\n\ncursoNuevo = True\n\nprint(\"Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/franxiscodev.py",
    "content": "# https://www.python.org/\n\n# comentario de una línea\n\n\"\"\"\nComentario \nde \nvarias \nlíneas\n\"\"\"\n\n'''\nComentario  de varias líneas\nComentario  de varias líneas\n'''\n\nmy_variable = \"Hello World\"\nprint(my_variable)\n\nMY_CONSTANT = \"valor constante en mayúsculas el nombre de la constante\"\nprint(MY_CONSTANT)\n\n# Datos primitivos\nmy_int = 1\nmy_float = 1.0  # float\nmy_bool = True  # boolean   True False\nmy_str = \"Hello World\"  # string\n\n# Imprimir\nprint(\"¡Hola, Python!\")\n\n# Tipos\nprint(type(my_str))\nprint(type(my_int))\nprint(type(my_float))\nprint(type(my_bool))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/frostbitepy.py",
    "content": "# https://www.python.org/\n\n# Comentario en una linea \n\n\"\"\"\nComentario \nen varias \nlineas\n\"\"\"\n\n'''\nComentario \nen varias \nlineas\n'''\n\n\nmy_variable = 0\nMY_CONSTANT = 3.14\n\n# Tipo de dato entero\nentero = 10\n\n# Tipo de dato punto flotante\nflotante = 3.14\n\n# Tipo de dato booleano\nbooleano = True\n\n# Tipo de dato cadena de texto\ncadena = \"Hola, mundo!\"\n\n# Tipo de dato lista\nlista = [1, 2, 3, 4, 5]\n\n# Tipo de dato tupla\ntupla = (1, 2, 3, 4, 5)\n\n# Tipo de dato conjunto\nconjunto = {1, 2, 3, 4, 5}\n\n# Tipo de dato diccionario\ndiccionario = {\"clave1\": \"valor1\", \"clave2\": \"valor2\"}\n\n# Tipo de dato None (nulo)\nnulo = None\n\n\nprint(\"Hola, Python!🐍\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/g4nd4lf.py",
    "content": "# https://www.python.org/\n\n# Este carácter sirve para comentar una sola línea\n\n\"\"\"Con triples comillas simples o dobles se pueden\ncomentar varias lineas.\n\"\"\"\n\n'''Ejemplo para comentar múltiples lineas\ncon las triples comillas simples.\n'''\n\n#Creación de una variable\nvble_name=\"Hello world\"\n\n#No existen constantes como tal, pero por convenio se usan mayúsculas para identificar una varible que se usará como constante\nMY_CONSTANT=\"Esto se usará como constante\" #Aunque en realidad es también una variable (es mutable), al ponerla en mayúscula hacemos ver que se va a usar como constante.\n\n#Tipos primitivos de python:\ninteger_vble=4\nfloat_vble=2.345\nboolean_vble=False\nboolean_vble=True\nstring_vble=\"Hello world\"\nbinary_vble=b'\\x68\\x65\\x6c\\x6c\\x6f'\nnone_vble=None\n\n#Impresión por pantalla:\nprint(\"¡Hola, Python!\")\n\nprint(type(integer_vble))\nprint(type(float_vble))\nprint(type(boolean_vble))\nprint(type(string_vble))\nprint(type(binary_vble))\nprint(type(none_vble))"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/gabrielramos02.py",
    "content": "# https://www.python.org/\n\n# Comentario de una sola linea\n\n\"\"\"\n    Comentario de multiples lineas\n\"\"\"\n\n# Variables\n\nstring_var = \"Hello World\"\nint_var = 123\nfloat_var = 1.23\nbool_var = True\n\n# Print\n\nprint(\"Hello World\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/garos01.py",
    "content": "# Este es un comentario en una línea.\n# Visita el sitio oficial de Python en: https://www.python.org/\n\"\"\"\nEste es un comentario multilinea.\nPuedes usar tres comillas simples o dobles.\n\"\"\"\n\n# Creación de una variable y una constante\nmi_variable = 10\nMI_CONSTANTE = \"Hola\"\n\n# Variables representando tipos de datos primitivos\ncadena_texto = \"Python!\"\nentero = 42\nflotante = 3.14\nbooleano = True\n\n# Imprimir por terminal el texto\nprint(f\"¡Hola, {cadena_texto}\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/gersonoroz.py",
    "content": "# Hola esto es un comentario y esta es la url de mi lenguaje https://www.python.org/\n\n'''\nEsto es otro comentario se puede \nescribir en diferentes lineas\n'''\n\nvariable = \"Esto es una variable de tipo cadena de texto\"\n\nCONSTANTE = 9\n\nFlotante = 9.8 \n\nBuleana = True\n\nprint(\"Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/ggilperez.py",
    "content": "# https://python.org\n\n# This is a comment in python\n\n\"\"\"\nblock comment\nwith double colons\n\"\"\"\n\n\n'''\nblock comment\nwith simple colons\n'''\n\nmy_variable = None\nMY_CONSTANT = 3.14\n\nmy_string = \"Hello World\"\nmy_int = 0\nmy_bool = True\nmy_float = 3.14\n\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/ggtorca.py",
    "content": "# Esto es un comentario. Sitio web oficial de python: https://www.python.org/\n\n\"\"\"\"\"\nEsto\nTambien\n¡Es un comentario!\n\"\"\"\nmi_variable = \"esto es mi variable\"\n\nMI_CONSTANTE = \"Esto es mi constante\"\n\n# Datos primitivos en python\nun_int = 10\nun_float= 3.14\nun_string =\"Esta es mi string\"\nun_booleano_cierto = True\nun_booleano_false = False\nun_nulo = None\n\n# Imprimir por pantalla\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/gilbertho502.py",
    "content": "# link de la pagina oficial de Python:\n# https://www.python.org/\n\n# tipos de comentarios\n# de una linea se utiliza numeral \"#\"\n# de varias lineas: \"\"\"\"\"\" o ''''''\n\n\"\"\"\"\nEste es un comentario de varias lineas\n\n\"\"\"\n\n#contante\nPI = 3.141592653\n\n#tipos de Datos:\n\n#numerica o enteros\nedad = 28\n\n#cadena de texto o string\nnombre = \"Gilberto\"\n\n#flotante:\naltura = 1.60\n\n#boleana\ncompletado = True\n\n#lista\nnombres = ['Carlos','Juan','Pedro']\n\n\nprint(\"Hola Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/giulianovfz.py",
    "content": "\"\"\"\n/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\"\"\"\n\n# comentario de línea\n\n\"\"\"\ncomentario de \nvarias lineas\n\"\"\"\n\nprimera_variable = \"hola mundo\"\nPRIMERA_CONSTANTE = \"valor constante\"\n\nentero = 3\nflotante = 3.14\nbooleano = True\nbooleano = False\ntexto = \"Cadena de texto\"\nlista = [1, 'puede', 'contener', 'distintos', 'datos', 3.14]\ntuplas = (1, 2, 3)\ntuplas = ('casa', 'vivienda', 'hogar')\ndiccionario = {1: 'Entrar', 'pasos': 'Caminar', 'Salir': 3}\nrango = range(0, 5)\n\nprint('¡Hola, [Python]!')\n\nprint(type(entero))\nprint(type(flotante))\nprint(type(booleano))\nprint(type(booleano))\nprint(type(texto))\nprint(type(lista))\nprint(type(tuplas))\nprint(type(tuplas))\nprint(type(diccionario))\nprint(type(rango))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/gjbecerrae.py",
    "content": "# https://www.python.org/\n\"\"\" \nthis is also a coment\nin multiple lines\n3 lines here\n\"\"\"\n\na = 3\ncadena = 'this is a string'\nlista = ['esta','es','una','lista']\n#esto es un diccionario\ndiccionario = {\"key\":\"value\",\"llave\":\"valor\"}\n#esto es una tupla\ntupla =('a','b')\nbooleano = True\nsetPython = {\"apple\", \"banana\", \"cherry\"}\nprint(\"¡Hola, Python!\"\n)\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/gl-informatica.py",
    "content": "# URL oficial del lenguaje seleccionado: https://www.python.org/\n\n#Comentario de una línea\n\n\"\"\"Comentario de \nmúltiples líneas\"\"\"\n\n'''Otro comentario de \nmúltiples líneas'''\n\n#Creando una variable\nvariable1 = \"\" #Creamos una variable con una cadena vacía.\n\n#Python no puede crear constantes, pero por convención se utiliza el nombre de las variables en MAYÚSCULAS para representarlas.\nNUMERO_PI = 3.14159\n\n#Creando variables con datos primitivos\ncadena = \"Soy una cadena\"\ncadena_2 = 'Soy otra cadena'\nentero = 10\nflotante = 10.0\nbooleano = True\nnulo = None\n\n#Imprimiendo en pantalla ¡Hola, Python!\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/gmbarrios.py",
    "content": "# 1. Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n# https://www.python.org/\n\n# 2. Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una linea, varias...)\n# De esta manera se escribe un comentario de una linea.\n\"\"\"\nTengo entendido que en realidad esto NO es un comentario de multiples lineas, sino una cadena de texto (string) que ocupa varias lineas.\n\"\"\"\n\n# 3. Crea una variable (y una constante si el lenguaje lo soporta).\nexample = 10\nEXAMPLE_CONST = 500\n\n# 4. Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\ninteger = 99\nfloat_number = 6.9\nlanguage = \"PYTHON\"\nboolean = True\n\n# 5. Imprime por terminal el texto:\nprint(f\"¡Hola {language}!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/gmedinat911.py",
    "content": "\n'''\n/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n'''\n# https://www.python.org/\n\n'''\nPython\n'''\n\"Python\"\n'Python'\n# Python\n\nLANGUAGE = \"Python\"\nlanguage_name = \"Python\"\n\n# Determinar tipos de datos primitivos\n\nstring = \"Este es un String\"\nnumero_entero = 123 # Este es un numero entero. \nnumero_flotante = 1.23 # Este es un numero flotante. \nbooleano = True # Este es un booleano. \n\n# Imprimir Texto en Terminal\nprint(f'¡Hola, {language_name}! ')\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/gmigues.py",
    "content": "'''\n/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n'''\n\n################################################################\n\n# Sitio oficial: https://www.python.org/\n\n### COMENTARIOS  ###\n\n# Comentarios en una linea\n\n'''\n\nComentarios\nen \nvarias\nlineas\n\n'''\n\n### VARIABLES Y CONSTANTES ####\n\nvariable = 1\nCONSTANTE = 100\n\n\n### TIPO DE DATOS ###\n\nint = 10\nfloat = 36.7\nbool = True or False\nstr = \"Dato de tipo cadena\"\ntuple = (1,2,4,5,6,7,8,9)\nlist = [1,2,3,4,5,6,7,8,9]\ndict = {'nombre': 'pepe', 'edad': '36', \"profesion\": 'músico'}\n\n\nlenguaje = \"python\"\nprint(\"hola \" + lenguaje)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/gonzadev28.py",
    "content": "\n# Comentario en una linea \n# Web oficial de python https://www.python.org/\n\n\"\"\"\nEscribiendo comentario \nen varias \nlineas \n\"\"\"\nvariable = \"mi variable\"\nCONSTANTE = \"mi constante\" # Constante no existe en python, por convencion se escribe en mayusculas \n\n#Tipos de variables \n\nun_string = \"mi string\"\nun_int = 28\nun_boolean = True\nun_float = 2.5 \n\n#Imprimir por terminal\nprint(\"¡Hola, Python!\")\n\nprint(type(un_int)) #Imprime el tipo de variable "
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/gregfc95.py",
    "content": "# * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n# *   lenguaje de programación que has seleccionado.\n    # https://www.python.org/\n\n# * - Representa las diferentes sintaxis que existen de crear comentarios\n# *   en el lenguaje (en una línea, varias...).\n    #   Python realmente no tiene una sintaxis multilineas, pero \n    #ignorará string que no estan asignados a una variable\n\n\"\"\"\n    Comentario\n    multi\n    linea\n    Ignorado por python puesto que no esta asignado a una variable\n\"\"\"\n\n# * - Crea una variable (y una constante si el lenguaje lo soporta).\n\ncont = 0\nmyNombre = \"Jose\"\n\n# * - Crea una variable global (y una constante si el lenguaje lo soporta).\n\nglobal x\nx = \"Mundial\"\n\n#* - Crea variables representando todos los tipos de datos primitivos\n#*   del lenguaje (cadenas de texto, enteros, booleanos...).\n\nvarString = str(\"Es es una string\")\nvarInt = int(10)\nvarFloat = float(3.41)\n#cualquier String es true a menos que esté vacia\nvarBooleanTrue = bool(\"Hello\")\n#cualquier String es true a menos que esté vacia\nvarBooleanFalse = bool(\"\")\n\nvarText = str(\"¡Hola, [y el nombre de tu lenguaje]!\")\nprint(varText) "
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/gringoam.py",
    "content": "# https://python.org\r\n\r\n# Comentario en una línea\r\n\r\n\"\"\"\r\nEsto también es\r\nun comentario\r\nen varias líneas\r\n\"\"\"\r\n\r\n'''\r\nEsto también es\r\nun comentario\r\nen varias líneas\r\n'''\r\n\r\nmy_variable = \"Mi variable\"\r\nmy_variable = \"Nuevo valor de mi variable\"\r\n\r\nMY_CONSTANT = \"Mi constante\"  # por convención\r\n\r\nmy_int = 1\r\nmy_float = 1.5\r\nmy_bool = True\r\nmy_bool = False\r\nmy_string = \"Mi cadena de texto\"\r\nmy_other_string = 'Mi otra cadena de texto'\r\n\r\nprint(\"¡Hola, Python!\")\r\n\r\nprint(type(my_int))\r\nprint(type(my_float))\r\nprint(type(my_bool))\r\nprint(type(my_string))\r\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/guillermo-k.py",
    "content": "\"\"\"\r\n    Reto de programación #00  SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\r\n\"\"\"\r\n\r\n'''EJERCICIO:\r\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\r\n *   lenguaje de programación que has seleccionado.\r\n * - Representa las diferentes sintaxis que existen de crear comentarios\r\n *   en el lenguaje (en una línea, varias...).\r\n * - Crea una variable (y una constante si el lenguaje lo soporta).\r\n * - Crea variables representando todos los tipos de datos primitivos\r\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\r\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"'''\r\n\r\n# URL del sitio oficial de Python: https://www.python.org/\r\n\r\n\"\"\"En el lenguaje Python existen 2 tipos de comentarios:\r\n    -Comentarios en linéa, cuya sintaxis es agregar un signo \"Numeral\"(#) antes\r\n     del comentario, con el cual, se puede, comentar toda una linéa, o solo parte de ella.\r\n     los mismos, no llevan un \"cierre\", ya que se \"cierran\" automaticamente al hacer un salto de linea.\r\n    \r\n    -Comentarios en bloque, los cuales, tienen 2 sintaxis posibles, \r\n        estos son el uso de 3 comillas seguidas para su apertura, y estas pueden ser\r\n        simples(') o dobles(\"), y nuevamente, 3 comillas para el cierre(del mismo tipo usado para la apertura).\r\n        Este tipo de comentario permite que el interprete \"ignore\" una o varias linéas consecutivas.\r\n        Todo lo que este entre una apertura y el proximo cierre, sera un comentario.\r\n\"\"\"\r\n\r\n# Esto es un comentario en linéa (de linéa completa).\r\n\r\nlenguaje = 'Python' # Esto es un comentario en linéa (parcial).\r\n\r\n\"\"\"Esto es un comentario de bloque con comillas dobles.\"\"\"\r\n\r\n'''Esto es un comentario de bloque con comillas simples.'''\r\n\r\n# Creación de una variable\r\nedad = 38\r\n\r\n# Creación de una constante\r\n'''Si bien, python no cuenta con \"Constantes\" como tales\r\n    Se utiliza la sintaxis de nombrar a la variable con mayusculas\r\n    cuando se requiere de una constante. Esta, igualmente, podra ser \r\n    modificada posteriormente, pero el uso de mayusculas, le deberia\r\n    recordar al programador que no se debe modificar su valor\r\n'''\r\nPI = 3.14159265\r\n\r\n# Variable del tipo entero (int)\r\nnumeroReto = 0\r\n\r\n# Variable del tipo decimal (float)\r\ntemperatura = 28.37\r\n\r\n# Variable del tipo caracter (char)\r\nletra = 'a'\r\n\r\n# Variable del tipo cadena de caracteres (String)\r\nsaludo = '¡Hola,'\r\n\r\n# Variable del tipo booleano (bool)\r\nestado = True\r\n\r\n# Impresión de \"Hola mundo!!!\"\r\nprint(saludo,lenguaje+'!')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/guillesese.py",
    "content": "# EJERCICIO 00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n\n\n#  - Crea un comentario en el código y coloca la URL del sitio web oficial del\n#  lenguaje de programación que has seleccionado.\n# URL: https://www.python.org/\n\n#  -  Representa las diferentes sintaxis que existen de crear comentarios\n#  en el lenguaje (en una línea, varias...).\n\n# Comentario de una línea. \nvariable = 3 # Comentario sobre una línea de código. \n'''Comentario con comillas simples'''\n\"\"\"Comenatrio con comillas dobles\"\"\"\n\n# - Crea una variable (y una constante si el lenguaje lo soporta).\nmiVariable = 2 #Creación de variable\n# En Python no hay constantes como tal, por convención se utilizan las mayúsculas. \nPI = 3.1416\n\n# - Crea variables representando todos los tipos de datos primitivos\n#  del lenguaje (cadenas de texto, enteros, booleanos...).\nvarString = \"hola\" #variable string \nvarChars = 'hola'\nvarLetra = 'a'\n\nvarInt = 1 #variable entera\n\nvarFloat = 1.2 #variable float\n\nvarBool = True #variable bool\n\n# - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nprint (\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/h4ckxel.py",
    "content": "# https://python.org\n# Comentario en linea\n\n\"\"\"\nComentario en\nvarias lineas\n\"\"\"\nvariable = \"mi variable\"\nvariable = \"nuevo valor de variable\"\n\nCONSTANT = \"constante\"  \n\nint = 10\nfloat = 10.5\nbool = True\nbool = False\nstring = \"Mi cadena de texto\"\notherstring = 'Mi otra cadena de texto'\n\nprint(\"Hola, Python!\")\n\nprint(type(int))\nprint(type(float))\nprint(type(bool))\nprint(type(string))\nprint(type(otherstring))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/hardynsnet.py",
    "content": "# 1. Crear un comentario y colocar la URL del sitio web oficial del lenguaje de programación que he seleccionado\n\n# https://www.python.org/\n\n# 2. Representar las diferentes sintaxis que existen para creación de comentarios\n\n# (#) <- Hash caracter o numeral\n\n# Este es un comentario\n\n# \"\"\" <- Triple quoted string\n\n\"\"\"\nEste es un comentario\n\"\"\"\n\n# 3. Creación de una variable y constante\nnombre_de_usuario = \"hardynsnet\" # Variable\n\n# Nota: No existe una sintaxis que indique como se crea una constante en Python\n# Sin embargo, se usa una convención de nomenclatura en mayusculas para representar una constante en el lenguaje\nPI = 3.1416 # Ejemplo\n\n# 4. Creacióon de variables representando tipos de datos primitivos.\nanio_actual = 2025 # Entero\nprecio = 14.45 # Flotante\nes_activo = True # Booleano\nmensaje = \"Hola Mundo\" # Cadena\n\n# 5. Imprimir por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nprint(\"¡Hola, Python!\")\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/haroldAlb.py",
    "content": "# Web oficial del lenguaaje de programación elejido: https://python.org\n\n#Comentario de una línea\n\"\"\"\nComentario de \nvarias líneas en \nPython\n\"\"\"\n\nvariable= 666\nMI_CONSTANTE= 3.1416\n\nentero= -68\nentero1: int = 33 #Estoy indicando que esta variable debe ser siempre de tipo entero y debe cambiar durante su ejecución a otro tipo de variable\nflotante= 0.333\ntexto= \"En una galaxia, muy, muy lejana...\"\nbooleano= True\n\nprint(\"Hola, Python\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/hectorio23.py",
    "content": "# Autor: Héctor Adán\n# GitHub: https://github.com/hectorio23\n\n# Si quieres saber más información sobre python visita su web oficial: https://www.python.org/\n\n# Comentario de una sola linea, para ello se usa el simbolo << # >>\n\n\"\"\"\nThis is a\nmulti-line comment\n\"\"\"\n\n'''\nThis is also a\nmulti-line comment\n'''\n\n# Creando una variable, no es necesarios especificar el tipo de dato\nmy_variable = \"Hello\"\n\n# Creando una constante, en python no existen como tal, si no que por convencion estas\n# se escriben con letras mayúsculas\nMY_CONSTANT = 10\nGRAVITY_VALUE = 9.7881 # .., etc\n\n# Variables que guardan diferentes tipos de datos\nstring_variable = \"Hello, Python!\"\ninteger_variable = 42\nfloat_variable = 3.14\nboolean_variable = True\n\n# Imprimiendo un mensage en el terminal\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/hermanyepes.py",
    "content": "\"\"\"\nEJERCICIO:\n* Crea un comentario en el código y coloca la URL del sitio web oficial del\n  lenguaje de programación que has seleccionado.\n\"\"\"\n\n# La URL del sitio oficial de Python es: https://python.org/\n\n\"\"\"\n* Representa las diferentes sintaxis que existen de crear comentarios\n  en el lenguaje (en una línea, varias...).\n\"\"\"\n\n# Este es un comentario de una sola línea.\n\n\"\"\"\nEste es un comentario\ncon saltos de línea.\n\n\"\"\"\n\n'''\nEste también es un comentario\ncon saltos de línea.\n'''\n\n# Crea una variable (y una constante si el lenguaje lo soporta).\n\nmy_variable = 10 # Asignamos el valor 10 a la variable.\n\nMY_CONSTANT = 3.14 # Las constantes se escriben en mayúsculas.\n\n\"\"\"\n* Crea variables representando todos los tipos de datos primitivos\n  del lenguaje (cadenas de texto, enteros, booleanos...).\n\"\"\"\n# Variable de tipo cadena de texto (string).\nmy_string = \"Hola, mundo!\" \nmy_string_2 = '¡Hola, mundo 2!'\n# Variable de tipo entero (integer).\nmy_int = 42 \n# Variable de tipo booleano (boolean).\nmy_boolean = True\n# Variable de tipo flotante (float).\nmy_float = 3.14 \n# Variable de tipo None (NoneType).\nmy_null = None\n\n\n# * Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nprint(\"¡Hola, Python🐍!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/hnaranjog.py",
    "content": "# https://www.python.org/\n\"\"\" \nLenguaje Utilizado Python \nDiferentes formas de comentar el código.\n\"\"\"\n'''\nOtra forma de comentar el código.\n'''\n\nCONS_VALUE = 10       # Constante\ncodex = 10            # Integer\nfloat_value = 3.14    # Float\nlanguage = \"Python\"   # String\nstring_multiline = \"\"\"This is a Multiline String.\nThis is the second line of the code.\"\"\"  # Multiline String\nbool_value = True     # Boolean\n\nprint(f\"Language selected: {language}\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/hozlucas28.py",
    "content": "# https://www.python.org/\n\n# Single line comment.\n\n\"\"\"\n    Multi line comment...\n\"\"\"\n\n# Variable declarations\nnumber_01 = 1\nNUMBER_02 = 2  # Constant by convention.\n\n# Primitive data types\nINTEGER_VAR = 12345\n\nFLOAT_VAR = 1.141516\n\nBOOLEAN_VAR = True\n\nSTRING_VAR = \"¡Hello World!\"\n\n# Outputs\nprint(f\"number_01: {number_01}\\nNUMBER_02: {NUMBER_02}\\n\")\n\nprint(f\"> INTEGER_VAR: {INTEGER_VAR} --> {type(INTEGER_VAR)}\\n\")\n\nprint(f\"> FLOAT_VAR: {FLOAT_VAR} --> {type(FLOAT_VAR)}\\n\")\n\nprint(f\"> BOOLEAN_VAR: {BOOLEAN_VAR} --> {type(BOOLEAN_VAR)}\\n\")\n\nprint(f\"> STRING_VAR: {STRING_VAR} --> {type(STRING_VAR)}\\n\")\n\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/iban99.py",
    "content": "#Comentario web oficial: https://www.python.org/\n\n#Comentario1\n\"\"\"Comentario \nvarias lineas\"\"\"\n\n#Variables y constantes\nvariable = 1\nCONST = 34 #Mayúscula constante, por consenso\n\n#Tipos de datos\nentero = 1\nstring = 'Hola mundo'\nbooleano = True\nflotante = 2.00 \ncomplejo = 56j\nlista = [1,2,3]\ndiccionario = {'hola':'mundo'}\nsetdatos (1,2,3)\n\n#Imprimir \nprint(\"¡Hola, Python!\")\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/ibuetab.py",
    "content": "# https://python.org\n# Comentario de una sola línea\n\n\n\"\"\"\nComentario \nde varias\nlíneas\n\"\"\"\n\n'''\nComentario \nde varias\nlíneas\n'''\n\nvariable = \"Hola Mundo\";\nCONSTANTE = \"Constante\";\n\nvariable_int = 2;\nvariable_float = 2.5;\nvariable_bool = True;\nvariable_bool = False;\nvariable_str = \"Variable string\";\n\nprint(f\"{variable_int}:{type(variable_int)}, {variable_float}:{type(variable_float)}, {variable_bool}:{type(variable_bool)}, {variable_str}:{type(variable_str)}\");\n\nprint(\"Hola Python\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/icedrek.py",
    "content": "\"\"\"\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n\"\"\"\n\n# Sitio oficial: https://www.python.org/\n\n# Comentario de una linea con '#'\n\n\"\"\"\nComentario de varias lineas.\nEn Python se pueden utilizar indistintamente comillas dobles \"\" o simples ''\n\"\"\"\n\na = 1  # tras el codigo tambien se pueden incluir comentarios\n\n# VARIABLES\n# las variables se escriben con letras minúsculas\nvariable = \"hola\"\n\n# si el nombre de la variable es compuesto, se utiliza snake_case(palabras separadas por '_'\nvariable_nombre_compuesto = \"hola\"\n\n# también se puede definir el tipo de la variable\nvariable_tipo: str = 'hola'\n\n# En python no existen las constantes.\n# Se utiliza una variable escrita en mayusculas para indicar que es constante y no se debe cambiar\nPI = 3.14\n\n# TIPOS SIMPLES\nvariable_str: str = 'cadena de texto'  # Cadenas de texto (String)\nvariable_bool: bool = True  # Booleanos, pueden tener valor True o False\nvariable_int: int = 1  # Numero entero, en principio se puede escribir cualquier entero sin restricciones.\nvariable_float: float = 1.23  # Números reales (con decimales)\nvariable_compleja: complex = 2j  # Números complejos o imaginarios\n\n# TIPOS COMPUESTOS\n# Lista de elementos, puede contener varios tipos. Ordenada, mutable y admite duplicados\nvariable_lista: list = [1, 2, '3']\n# Lista de elementos, puede contener varios tipos. Ordenada, inmutable y admite duplicados\nvariable_tupla: tuple = (1, '2', 3)\n# Lista de elementos, puede contener varios tipos. Desordenada, inmutable y no admite duplicados\nvariable_set: set = {1, 2, 3}\n# lista de clave:valor. Ordenada, mutable y no admite duplicados\nvariable_diccionario: dict = {1: 'a', 2: 'b', 3: 'c'}\n\n# para mostrar un valor por pantalla se utiliza la funcion print()\nprint('hola Python')\n\n# tambien podemos mostrar el valor de una variable\nlenguaje = \"Python\"\nprint(f\"hola {lenguaje}\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/idiegorojas.py",
    "content": "# https://www.python.org/\n\n# Comentario en una linea\n\n\"\"\"\nEsto tambien \nes un \ncomentario\n\"\"\"\n\n'''\nEsto tambien \nes un \ncomentario\n'''\n\nvariable = 'Almacena un valor'\n\nMY_CONSTANT = 'Mi Constante'\n\nstr = 'Texto'\nint = 12\nfloat = 12.5\nbool = True\n\nprint('¡Hola Python!')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/ignacioskm.py",
    "content": "'''\r\n* EJERCICIO:\r\n - Crea un comentario en el código y coloca la URL del sitio web oficial del\r\n   lenguaje de programación que has seleccionado.\r\n - Representa las diferentes sintaxis que existen de crear comentarios\r\n   en el lenguaje (en una línea, varias...).\r\n - Crea una variable (y una constante si el lenguaje lo soporta).\r\n - Crea variables representando todos los tipos de datos primitivos\r\n   del lenguaje (cadenas de texto, enteros, booleanos...).\r\n - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\r\n'''\r\n\r\n# Link de web oficial python : https://www.python.org/  \r\n\r\n# Comentario en una línea\r\n\r\n\"\"\"\r\nEsto es un comentario de varias líneas\r\n\"\"\"\r\n\r\n'''\r\nEsto es otra forma de un comentario\r\nde varias líneas\r\n'''\r\n\r\nmy_variable = \"Hola\"\r\nmy_variable = \"Hola dios soy yo denuevo\"\r\n\r\nprint(my_variable)\r\n\r\n\r\n# Escribirlo en mayusculas ayuda a saber que esta variable es una cosntante por lo que no habria que cambiarla. \r\n\r\nMY_CONSTANT = \"Mi constante\" # por convención\r\n\r\n\r\n# Datos Primitivos\r\n\r\nvariable_int = 2\r\nvariable_float = 2.5\r\nvariable_string = \"Colo-colo\"\r\nvariable_bool = True\r\nvariable_bool = False\r\n\r\nprint(\"Hola, python!\")\r\n\r\n\r\n# Para poder ver los tipos de datos de la variable podemos ocupar type()\r\n\r\nprint(type(variable_int))\r\nprint(type(variable_float))\r\nprint(type(variable_string))\r\nprint(type(variable_bool))\r\n\r\nsaludo = \"Hola Mundo!\"\r\nprint(saludo)\r\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/ignaciovihe.py",
    "content": "# https://www.python.org/\n\n# Este es un comentario de una linea\n\n\"\"\"\nEste es un \ncomentario en\nvarias líneas\n\"\"\"\n\n'''\nEste también es\nun comentario\nen varias líneas'''\n\nmy_variable = \"Python\"\nPI = 3.1416 # Aunque se considera una constante, python no mostrara error si cambiamos el valor.\n\nmy_int = 5\nmy_float = 3.14\nmy_str = \"Ejercicio-00\"\nmy_bool = True\n\nprint(f\"¡Hola, {my_variable}!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/ihunivers.py",
    "content": "# EJERCICIO:\n# - Crea un comentario en el código y coloca la URL del sitio web oficial del\n#   lenguaje de programación que has seleccionado.\n#  Punto 1\n#  https://www.python.org/\n\n\n# - Representa las diferentes sintaxis que existen de crear comentarios\n#   en el lenguaje (en una línea, varias...).\n# Punto 2\n# Comentario de una línea\n\"\"\"\nComentario \nde varias \nlíneas con comillas dobles\nmultiples líneas\n\"\"\"\n\n'''Comentario\nde varias\nlíneas con comillas simples\nmultiples líneas\n'''\n\n\n# - Crea una variable (y una constante si el lenguaje lo soporta).\n# Punto 3\ndia = 'Sábado'\nCONSTANTE = \"Domingo\"  # Por convención se representa en mayuscula, pero no existe.\n\n\n# - Crea variables representando todos los tipos de datos primitivos \n#   del lenguaje (cadenas de texto, enteros, booleanos...).\n# Punto 4\n'''primitivos en Python'''\n# Tipo entero (int)\nentero = 7\nflotante = 0.36\n# Tipo cadena (str)\ncadenatexto = \"Python\"\n# Tipo booleano (bool)\nbooleano1 = True\nbooleano2 = False\n# Tipo Nulo (None)\nnulo = None\n# Tipo complejo (complex), considerado primitivo en Python\nnumero_complejo = 20 + 25j\n\n\n# - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n# Punto 5\nprint(\"¡Hola, Python!\")\nprint(f\"¡Hola, {cadenatexto}!\")  # Usando la variable de cadena\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/inf015.py",
    "content": "#* EJERCICIO:\n# 1-Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n#https://www.python.org/\n\n# 2-Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n#Este es un comenterio en monolinea\n\"\"\"\nEste \nes \nun \ncomentario \nmultilineal\n\"\"\"\n# 3-Crea una variable (y una constante si el lenguaje lo soporta).\nmi_variable = 'Porsche'\nMI_CONSTANTE = '992.1 GT3'\n\n# 4-Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\nstring = 'Me encantan los autos'\ninterger = 15\ndecimal = 122.46\nbooleano = True\n\n# 5-Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"#\nprint('¡Hola, Python')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/ingothik.py",
    "content": "# Sitio web oficial de Python: https://www.python.org/\n\n\"\"\" Sitio web oficial de Python:\nhttps://www.python.org/\"\"\"\n\n''' Sitio web oficial:\nhttps://www.python.org/'''\n\n\nvariable1 = \"Bienvenido\"\n\nstring = \"Esto es una cadena\"\nentero = 33\nflotante = 21.5\nbooleano = True\n\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/initkey.py",
    "content": "# https://www.python.org/\n\n# Comentario de una línea\n\n\"\"\"\n    Comentario con\n    varias líneas\n    de código\n\"\"\"\n\n'''\nComentario con\nvarias líneas\nde código\n'''\n\nlanguage = \"Python\"\nother_language = \"PHP\"\n\nCONSTANT = \"Es una constate por convención\"\nprint(CONSTANT)\n\n# Enteros - Integer\nage = 15\n\n# Flotante o Decimal - Float\ntotal = 25.3\n\n# Booleano - Boolean\nstatus = True\nstatus = False\n\n# Cadena - String Str\ntext = \"Esta es una cadena\"\nother_string = 'Otra cadena de texto'\n\nprint(f\"¡Hola, {language}!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/inkhemi.py",
    "content": "#   ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n#   - Recuerda que todas las instrucciones de participación están en el\n#     repositorio de GitHub.\n\n#   Lo primero... ¿Ya has elegido un lenguaje?\n#   - No todos son iguales, pero sus fundamentos suelen ser comunes.\n#   - Este primer reto te servirá para familiarizarte con la forma de participar\n#     enviando tus propias soluciones.\n\n#   EJERCICIO:\n#   - Crea un comentario en el código y coloca la URL del sitio web oficial del\n#     lenguaje de programación que has seleccionado.\n#   - Representa las diferentes sintaxis que existen de crear comentarios\n#     en el lenguaje (en una línea, varias...).\n#   - Crea una variable (y una constante si el lenguaje lo soporta).\n#   - Crea variables representando todos los tipos de datos primitivos\n#     del lenguaje (cadenas de texto, enteros, booleanos...).\n#   - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\n#   ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n#   debemos comenzar por el principio.\n\n\n# https://www.python.org/\n\n# Comentario en una sola linea\n\"\"\"\nComentario\nen multiples\nlineas\n\"\"\"\n'''\notro comentario\nen multiples\nlineas\n'''\n\nvariable = \"Variable\"\nprint(variable)\n\nmyString = \"My String Variable\"\nprint(myString)\n\nmyInt = 5\nprint(myInt)\n\nmyBool = False\nprint(myBool)\n\nmyFloat = 3.1416\nprint(myFloat)\n\nprint('¡Hola, Python!')\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/inmortalnight.py",
    "content": "# www.python.org\n\n# Comentario en una línea\n'''Comentario en \"\"\"varias\"\"\" líneas'''\n\"\"\"Comentario en '''varias''' líneas\"\"\"\n\n# variable, sin constantes pero se puede declarar asi\nCONSTANT = \"string\" \n\n# tipos de datos\nnulo = None #no tiene valor\nstring = \"hi\"\nentero = 2\nentero: int = 2  # Anotación de tipo int\nentero = int(2)    # Conversión a entero\nfloat = 3.4\ncomplex = 4j    # Número complejo\nboolean = False\nrange = range(6) #rango\nbyte = b\"Python\"\nbyteArray = bytearray(byte)     # Secuencia de bytes modificable\nmemoryview = memoryview(byteArray)  # Secuencia de bytes que permite el acceso a la memoria\nlist = [1, 2, 3, \".\", [1,2]]   # Lista que puede ser modificada y contiene elementos de diferentes tipos\ntuple = (1, 2, 3)  # Tupla que no puede ser modificada y contiene elementos de diferentes tipos\nset = {1, 2, 3}     # Conjunto que no puede contener elementos duplicados y no tiene orden\nset_congelado = ({1, 2, 3}) #no se puede modificar y no tiene orden\ndictionary = {\"key1\": 1, \"key2\": \"dos\", \"key3\":[1,2]}  # Diccionario que contiene pares clave-valor\n\n#imprimir\nprint(\"¡Hola, Python!\")\nprint(f\"Número {entero}\")\nprint(\"Número\" + entero)\nprint(\"¡Hola, {}!\".format(\"mundo\")) #format, insertar\nmodel = '¡Hola, {0:s}!' #format, restriccion de tipo y indice\nprint = model.format(\"string\")\n\nprint(float(1)) #cambiar a float\nprint(int(3.4)) #cambiar a entero\nprint(bool(1)) #cambiar a booleano\nprint(type(entero)) #tipo de dato\n\n# Objetos\nclass Type(): #definir una clase\n    pass\nobject = Type() #instanciar un objeto"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/isaacdci.py",
    "content": "#  https://www.python.org/\n#  esto si es un comentario\n\"\"\"\nyo pongo \nmuchos \ncomentaros\n\"\"\"\n\n'''\nhacer \nmuchos \ncomentarios\n'''\nbosques = 12000\nbosques = 45000\n\nBOSQUES = 51000\n\nmientero = 60\nmiflotante = 63.9\nmicadena = \" Python de isaac\"\nmibool = True\nmibool = False\nimprime = mientero + miflotante  \nprint (\"Hola (python)\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/isilanes.py",
    "content": "# https://www.python.org/\n# This is a one-line comment\nx = 1  # this is an inline comment\n\"\"\"\nThis is a multi-line comment.\n\"\"\"\ny = 1  # this is a variable\n...    # Python does not support constants\nsome_integer: int = 123  # integer variable\nsome_float: float = 0.5  # float variable\nsome_string: str = \"some string\"  # string variable\nsome_boolean: bool = True  # boolean variable\nsome_null: None = None  # NoneType variable\nsome_list: list = [1, 2, 3]  # list variable\nsome_tuple: tuple = (1, \"two\", 3.0)  # tuple variable\nsome_set: set = {1, 2, 3}  # set variable\nsome_dictionary: dict = {\"key1\": 2, \"key2\": 4}  # dictionary variable\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/ivangdev.py",
    "content": "# Web Oficial de python https://www.python.org/\n# Comentario con numeral\n\n\"\"\"\nComentario con comillas triples\n\"\"\"\n\n'''\nEsto es un comentario con comillas simples\n'''\n\nivangdev = \"Mi variable\"\n\n# Datos primitivos\nentero = 10\nflotante = 10.5\ncadena_texto = 'Hola'\nbooleano = True # False\nNoneType = None\n\nprint(f\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/j0nvthvn.py",
    "content": "# https://www.python.org/\n\n# comentario en una línea\n\n\"\"\"\nEsto también es un comentario \nen varias líneas\n\"\"\"\n\n'''\nEsto también es un comentario\nen varias líneas\n'''\n\nmy_variable = \"Mi variable\"\nmy_variable = \"Nuevo valor de mi variable\"\n\nMY_CONSTANT = \"Mi constante\" # por convención\n\nmy_int = 5\nmy_float = 5.5\nmy_bool = True\nmy_bool = False\nmy_string = \"Mi cadena de texto\"\nmy_other_string = 'Mi otra cadena de texto'\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/jabgnecco.py",
    "content": "# https://python.org\n\n# Comentario en una linea\n\n\"\"\"\nComentario\nen varias\nlineas\n\"\"\"\n\nmy_variable = \"Esto es una variable\"\nMY_CONSTANTE = \"Esto es una constante\"\nmy_int = 1\nmy_float = 1.5\nmy_bool = True\nmy_string = \"Cadena de texto\"\nmy_other_string = 'Otra cadena de texto'\n\nprint(\"Hola, Python!\")\n\nprint(type(my_variable))\nprint(type(my_int))\nprint(type(my_float))\nprint(type(my_bool))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/jaennova.py",
    "content": "# https://python.org/\n\n# variable no tipada\nlanguage = \"Python\"\n\n# variables tipadas\nmy_string:str = \"Hola Mundo\"\nmy_boolean:bool = True\nmy_integer:int = 42\nmy_float:float = 3.1416\nprint(f'¡Hola, {language}!')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/jafuma0320.py",
    "content": "# EJERCICIO:\n\n# Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n# Pagina oficial del lenguaje (https://www.python.org/)\n \n# Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n# un comentario ( # )\n# varios comentarios :\n\"\"\"\"\"\"\"\"\"\"\"\n\n\n\"\"\"\"\"\"\"\"\"\"\"\n\n#  Crea una variable (y una constante si el lenguaje lo soporta).\nEstaturas = [1.78, 1.89, 1.52]\n \n#  Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\nprint(type(10))                                # Int\nprint(type(3.14))                             # Float = decimal\nprint(type(1 + 3j))                           # Complex  \nprint(type('Asabeneh'))                   # String = texto\nprint(type([1, 2, 3]))                         # List\nprint(type({'name':'Asabeneh'}))      # Dictionary\nprint(type({9.8, 3.14, 2.7}))               # Set\nprint(type((9.8, 3.14, 2.7)))                # Tuple\n\n#  Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nprint (\"¡Hola, [PYTHON]!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/jandortiz.py",
    "content": "# Parte 1.\n# https://www.python.org/\n\n# Parte 2.\n# Esto es un primer comentario.\n\n\"\"\"\nOtra forma de realizar\ncomentarios de varias líneas.\n\"\"\"\n\n# Parte 3.\nmi_primera_variable = 3\nHORAS_DIA = 24\n\n# Parte 4.\nnumero_entero = 54\nnumero_decimal = 43.2\ncadena_texto = \"Hola mundo\"\nvariable_booleana = True\nvariable_none = None\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/javierfiestasbotella.py",
    "content": "'''\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n'''\n#https://www.python.org\n\n'''Esto es un \ncomentario para cosas largas'''\nx='tipo_variable'\nEDAD='Constante'\n\nnumero=3\nflotante=3.5\nstring='lo que sea'\nmayor_de_edad=True\n\nprint('¡Hola, Python!')\n#Comentario de una sola linea\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/javierjoyera.py",
    "content": "# Sitio web oficial de Python: https://www.python.org/\n# Documentación oficial de Python: https://docs.python.org/3/\n\n# Creación de comentarios:\n# Comentario de una línea\n''' Comentario\nde varias líneas\n'''\n\"\"\" Comentario de\nvarias líneas\n\"\"\"\n\n# Creación de una variable y una constante (en Python, las constantes son convenciones)\nmy_variable = 27\nMY_CONSTANT = \"Hola, soy una constante\"\n\n# Tipos de datos primitivos en Python:\nmy_string = \"Hola, esto es una cadena de texto\"\nmy_int = 10\nmy_float = 3.14\nmy_boolean = True\n\n# Imprimir por terminal el texto solicitado:\nmy_lenguage = \"Python\"\n#print(\"¡Hola, \" + my_lenguage + \"!\")\n\n# Otra forma de imprimir por terminal el texto solicitado:\nprint(\"¡Hola, %s!\" % my_lenguage)\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/javirr4.py",
    "content": "# https://es.python.org/\r\n# Comentario 1 línea\r\n'''\r\nEsto también es\r\nun comentario\r\nen varias líneas\r\n'''\r\nmy_variable = \"Mi variable\"\r\n\r\nMY_CONSTANT = \"Mi constante\"  # por convención\r\n\r\nmy_int = 10\r\nmy_float = 5.0\r\nmy_bool = True\r\nmy_bool = False\r\nmy_string = \"Bienvenidos a todos\" \r\n\r\nprint (\"¡Hola,Python!\")\r\nprint(my_variable)\r\nprint(my_float)\r\nprint(my_bool)\r\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/javirub.py",
    "content": "'''\n/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n'''\n\n#https://www.python.org/\n\nentero = 123\nCONSTANTE = 3.14159265\nflotante = 0.123\nbooleano = True\ncadenas = \"Hello World\"\nprint(\"Hola, Python!\")\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/javitron100.py",
    "content": "# https://www.python.org/\r\n\r\n#Comentario en una línea\r\n\r\n\"\"\" \r\nComentario\r\nen varias\r\nlineas\r\n\"\"\"\r\n\r\nmi_variable = 10\r\n\r\nmi_entero = int()\r\nmi_float = float()\r\nmi_texto = str()\r\nmi_booleano = bool()\r\n\r\nprint(\"!Hola, Python!\")\r\n\r\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/jcdm60.py",
    "content": "\n# EJERCICIO:\n# - Crea un comentario en el código y coloca la URL del sitio web oficial del\n#   lenguaje de programación que has seleccionado.\n# - Representa las diferentes sintaxis que existen de crear comentarios\n#   en el lenguaje (en una línea, varias...).\n# - Crea una variable (y una constante si el lenguaje lo soporta).\n# - Crea variables representando todos los tipos de datos primitivos\n#   del lenguaje (cadenas de texto, enteros, booleanos...).\n# - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\n\n\n\n# URL del sitio web oficial de Python: https://www.python.org/\n\n\n# Comentario de una línea\n\n\"\"\"\nComentario\nde\nvarias\nlíneas\n\"\"\"\n\n# Creación de una variable\nmi_variable = 100\n\n# Creación de una constante (Python no tiene constantes, pero se usa convención para denotarlas en mayúsculas)\nMI_CONSTANTE = 3.1416\n\n# Tipos de datos primitivos\ncadena_texto = \"Hola, mundo!\"\nentero = 56\nbooleano = True\nflotante = 3.14\nlista = [1, 2, 3]\ntupla = (4, 5, 6)\ndiccionario = {'clave': 'valor'}\n\n# Imprimir por terminal\nprint(f\"¡Hola, Python!\")\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/jchernandez87.py",
    "content": "# https://www.python.org/\n\n# Single line comment\n\"\"\"\nThis can be use to do\nmultiline comments in python\n\"\"\"\n# Or you \n# can use a\n# hash\n# for every line\n\n# Python variable\nmy_first_variable = 'Hello World!!'\n\n#Python primitive data types\ndata_type_int = 8\ndata_type_float = 8.0\ndata_type_string = 'My string'\ndata_type_boolean = True\n\nprint('Hello Python!!')\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/jean1129.py",
    "content": "# https://python.org\n\n# Comentario en linea\n\nMy_variable = \"Mi variable\"\n\nMY_ CONSTANTE = \"Mi constante\"\n\nMy_int =5\n\nMy_float =5.0\n\nMy_bool = true\n\nMy_bool = flase\n\nMy_string = \"My cadena de texto -_- \"\n\nprint=(\"!hola, python¡\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/jehiselruth.py",
    "content": "# https://phyton.org\n\n# comentario\n\n\"\"\"\nCometario\nen dos líneas\n\"\"\"\n\n'''\nComentario en \ntres\nlíneas\n'''\n\nmy_varriable = \"Mi variable\";\nmy_variable = \"Otra variable\";\n\n# Phyton no tiene constantes. Todos son variables. \n\nMY_CONSTANT = \"Mi constante\" # por convención\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/jereAguilar.py",
    "content": "#https://www.python.org/\n\n#Comentario en una linea\n\n\"\"\"\nComentarios de varias lineas\nEsto es un comentario\nen varias lineas\n\"\"\"\n\n'''\nEsta es otra forma\nDe hacer comentarios \nEn varias lineas\n'''\n\n# Creacion de una variable\nmi_variable = 10\n\n# Las constantes no se declaran explicitamente en Python, pero se puede seguir la convención de nombres en mayúsculas para indicar que una variable es constante\nMI_CONSTANTE = 3.1416\n\n# Variables representando todos los tipos de datos primitivos del lenguaje\ncadena_texto = \"Hola, Python!\"\nentero = 42\nfloat = 3.14\nBooleano = True\n\n# Impremir por terminal el texto \"¡Hola, Python!\"\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/jesusgdev.py",
    "content": "# URL del sitio web oficial de python en español: https://www.python.org/es/\n\n# Existen muchas formas de crear un comentario en Python, pero la más común \n# es usar el símbolo de numeral (#).\n# Este es un comentario de una sola línea.\n\n\"\"\"\nEste es un comentario de varias líneas.\nPuedes usar comillas triples para crear comentarios más largos.\n\"\"\"\n\n'''\nTambién puedes usar comillas simples para crear comentarios de varias líneas.\n'''\n\nx = 4 # Esta es una variable llamada x que almacena el valor 4.\nPI = 3.14159  # Esta es una constante que almacena el valor de pi.\n\nnum = 6 # Esta es una variable de tipo entero que almacena el valor 6.\ndec = 3.14 # Esta es una variable de tipo flotante que almacena el valor 3.14.\ngreeting = \"Hola, Python!\" # Esta es una variable de tipo cadena que almacena el texto \"Hola, Python!\".\nIstrue = True # Esta es una variable de tipo booleano que almacena el valor True.\n\nprint(\"¡Hola, Python!\")  # Esta línea imprime el texto \"¡Hola, Python!\" en la consola.\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/jesusway69.py",
    "content": "import os\nos.system('clear')\n#os.system('cls')\n\n# COMENTARIO EN UN LÍNEA\n\n\n\"\"\"\nCOMENTARIO EN VARIAS LÍNEAS:\n\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n        https://www.python.org/\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\"\"\"\n\nmi_variable_string = \"Hola\"\nprint(type(mi_variable_string))\nMI_CONSTANTE_STRING = \"Python\"\nprint(type(MI_CONSTANTE_STRING))\nmi_numero_int = 8\nprint(type(mi_numero_int))\nmi_numero_float = 3.5\nprint(type(mi_numero_float))\nmi_booleano = True\nprint(type(mi_booleano))\nmi_numero_complex = 1+2j\nprint(type(mi_numero_complex))\nmi_lista = ['¡',1,2,3,4,'!']\nprint(type(mi_lista))\nmi_tupla = (1,2,3,4)\nprint(type(mi_tupla))\nmi_diccionario = {\"Hola\":\"Python\"}\nprint(type(mi_diccionario))\nmi_dato_vacio = None\nprint(type(mi_dato_vacio))\n\nprint (mi_lista[0] + mi_variable_string + \" \" + MI_CONSTANTE_STRING + mi_lista[5])\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/jfdacovich.py",
    "content": "# https://www.python.org/\n\n# Esto es un comentario\n\n# Comentando\n# varias \n# líneas\n# de código\n\n\"\"\"\nComentario de\nvarias\nlíneas\n\"\"\"\n\n'''\nComentario de\nvarias\nlíneas\n'''\n\nvariable = \"Mi primera variable\"\n\nMY_CONSTANT = \"Mi constante\"\n\n# Tipos de datos primitivos\n\nmy_int = 77\nmy_float = 7.5\nmy_string = \"Cadena de caracteres\"\nmy_booleano = True\nmy_booleano = False\nmy_none = None\n\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/jgarteag.py",
    "content": "# https://www.python.org/\n\n# comentarios que se pueden hacer en python\n# comentario de una sola línea\n\"\"\" comentario de varias líneas \"\"\"\n\nmy_var = \"Hola\"\nMY_CONST: str = \"Python\"\n\n# tipos de datos primitivos\nmy_string: str = \"Hola\"\nmy_int: int = 5\nmy_float: float = 3.5\nmy_bool: bool = True\nmy_complex: complex = 1+2j\nmy_list: list = ['¡',1,2,3,4,'!']\nmy_tuple: tuple = (1,2,3,4)\nmy_dict: dict = {\"Hola\":\"Python\"}\nmy_none: None = None\n\nprint(\"¡Hola, Python!\")\n\nprint(type(my_string))\nprint(type(my_int))\nprint(type(my_float))\nprint(type(my_bool))\nprint(type(my_complex))\nprint(type(my_list))\nprint(type(my_tuple))\nprint(type(my_dict))\nprint(type(my_none))"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/jgcmurcia.py",
    "content": "#00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n\n'''Enunciado copiado /*\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n '''\n\"\"\"\n* ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */ \n\"\"\"\nhttps://www.python.org/downloads/ #url phyton\n\n#Variables\n\nnombre= \"jgc\" #int\nedad= 50      #int\naltura= 1.2   #float\nes_estudiante= True #bool\n\n#Constante\nconstante= 10 #int\n\n# Tipos de datos primitivos adicionales\nnumero_complejo = 1 + 2j  # complex (número complejo)\nnulo = None  # NoneType (valor nulo)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/jgregoris.py",
    "content": "# https://www.python.org\n\n# Primer comentario\n\n\"\"\"Se pueden crear comentarios,\ncon comillas dobles\"\"\"\n'''Y tambien con comillas simples'''\n\nvariable= \"Esto es una variable\"\n\nstring = \"Cadenas de texto\"\nint = 5\nfloat = 4.6\nbool = True\nprint (type(bool))\nprint (\"¡Hola, Python!\")\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/jheisonquiroga.py",
    "content": "#https://www.python.org/\n#1. Sintaxis de creacion de comentarios\n#1.1. Para una sola linea se utilizan los numerales (#)\n\"\"\"\n1.2. Comentar varias lineas: Se utilizan las comillas dobles o simples triples\n\"\"\"\n'''\n1.2. Comentar varias lineas: Se utilizan las comillas dobles o simples triples\n'''\n#2. Crea una variable y una constante si el lenguaje lo soporta\nmi_variable = 69\n\n#2.1. Costante\nPI = 3.1416\n\n#3. Tipos de datos\n\ncadena = \"string\" #Cadena de texto (str)\nnumero_entero = 10 # Numero entero (int)\nnumero_flotante = 3.5 # Numero flotante (float)\nbooleano = True # Valor booleano (bool)\nlista = [1,2,3] # Lista (list)\ntupla = (1,2,3) # tupla (tuple)\ndiccionario = {\"clave\" : \"valor\"} #Diccionario (dict)\n\nnombre_lenguaje = \"Python\"\nprint(f\"¡Hola, {nombre_lenguaje}!\")\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/jhoshmc.py",
    "content": "\"\"\"\"\n EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n\"\"\"\n\n#* ulr= https://www.python.org/\n\n#* Este es un comentario en una sola línea\n\n\"\"\"\nno tenia idea que así se hacia un comentario\ncon varias líneas en pyton\nque raro :v\n\"\"\"\n\nvariable= 1\nVARIABLE_CONSTANTE= 3.1416\n\nnumeroEntero= 1\nnumeroReal= 1.5\nbooleano=True\ndouble= 1.3453355\ncaracter= 'a'\npalabra = '!hola pyton!'\narray=[]\n\nprint(palabra)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/jm158960-beep.py",
    "content": "# https://python.org\n\n# comentario en una linea\n\n\"\"\"\nEsto tambien\nes un comentario\nen varias lineas\n\"\"\"\n\n'''\nEsto tambien\nes un comentario\nen varias lineas\n'''\n\n#esto se usa para representar una variable, las comillas se usan para representar cadenas de textos \nnombre_acido = \"HCL\"\nconcentracion_molar = 12\nmolecula_polar = True \n\nNOMBRE_ACIDO = \"HCL\" #por convencion se deja en mayuscula para que se entienda que no hay que cambiarlo dado que es constante, dado que Python no acepta constantes\n\n#Variables con tipos de datos primitivos\n\n#numeros\n#int(entero)\nnumero = 20\n#float(decimal)\ndecimales = 3.14\n#complex(complejos)\ncomplejo = 2 + 4j\n\n#texto\n#str(cadena de texto)\ntexto = \"hola mundo\" \n\n#booleanos\n#bool\nverdadero = True\nfalso = False \n\nPrint(¡Hola, Python)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/jmontoyac.py",
    "content": "# https://www.python.org/\n\n# Comentario de una linea\n\n'''\n# Comentario multi lineas\n# Segunda linea de comentario\n'''\n\n# Variable en Python\nprimera_variable = 0\n\n# Constante en Python\nDURACION_MILISEGUNDOS = 300\n\n# Tipos de datos primitivos\nvariable_string_comillas_simples = 'String de comillas simples'\nVariable_string_comillas_dobles = \"String de comillas dobles\"\nvariable_int = 3600\nvariable_float = 5.5\nvariable_boolean = True\nvariable_nula = None\n\nprint(\"¡Hola Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/joamgreen.py",
    "content": "#esta es la url oficial de python: https://www.python.org/ \n#una clase de comentario\n'''otra clase de comentario  pero multilinea'''\n\n#variable\nvariable = 1\n#constante deben de ir en mayusculas\nCONSTANTE = 2\n\n#tipo de datos en python\nx = \"hello world\"#string\nx=20 #int\nx=20.5 #float\nx=[\"apple\", \"banana\", \"mango\"] #list\nx=(\"apple\", \"banana\", \"mango\") #tuple\nx=range(4) #range\nx={\"name\" : \"Johnyonny\", \"age\" : 50} #dict\nx=True #bool\nX=False #bool\nx=b\"Jhonnny\" #bytes\nx =memoryview(bytes(5)) #memoryview\nx=None #None\n\n#imprimir texto\nlenguaje='python'\nprint(f\"hola este lenguaje es: {lenguaje}\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/joandevpy.py",
    "content": "# Sitio web de Python: https://www.python.org/\n\n# Esto es un comentario\n\n\"\"\"\nEsto es un comentario en varias lineas en Python \n\"\"\"\n\n'''\nEsto tambien es un comentario en varias lineas en Python \n'''\n\n#  Crear variable\nmi_variable = \"Hola, esta es mi variable\"\n\n# Suelen ser en MAYUSCULAS para nombrarlas y no se deben cambiar \nMI_CONSTANTE = 3,14 \nMI_CONSTANTE = \"Puede ser numerica tambien\"\n\nmi_cadena_texto = \"Esto es una cadena de texto\"\n\n# Enteros, solo numeros enteros\n\nmy_int = 1\n\n# Flotantes, usados para decimales \n\nmy_float = 3.14\n\n# Booleanos, solo pueden tener estos dos valores \n\nmy_bool = True\nmy_bool = False\n\nmy_string = \"Otra cadena de texto\"\nmy_other_string = 'Asi se puede representar tambien'\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/jofedev.py",
    "content": "\"\"\"/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * -x Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n \"\"\"\n\n # Este es un comentario de una linea\n\n # Este es el URL de la pagina oficial de Python: https://www.python.org/\n\n\"\"\"\n    Este es un comenratario\n    de varias lineas\n    con comillas dobles    \n\"\"\"\n\n'''\n    Este es un comentario \n    de varias lineas\n    con comillas simples\n'''\n\n\n#Python usa Snake Case como convencion para declarar variables\n\nmy_variable = 1\n\n# Python no tiene constantes, todos los datos se pueden mutar.\n\nMY_VARIABLE = \"constante\" # Por convencion asi se puede declarar una constante, sin embargo igual su valor puede mutar.\n\n#Tipos de datos primitivos \n\nmy_int = 1\nmy_float = 1.3\nmy_bool = True\nmy_bool = False\nmy_string = \"Tipo de dato primitivo\"\nmy_strig = 'Tipo de dato primitivo con comillas simples'\n\n\nprint(\"Hola, Python!\")\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/jordanurzua.py",
    "content": "#https://www.python.org\n\n#Comentario en una línea\n\n\"\"\"\nEsto es un comentario\nen varias\nlíneas\n\n\"\"\"\n\n'''\nEsto es un comentario\nen varias\nlíneas\n'''\n\nmy_variable = \"Mi variable\"\nmy_variable = \"Nuevo valor de mi variable\"\n\nMY_CONSTANT= \"Por favor no cambies mi constante\"\n\n\nmy_int = 1\nmy_float = 1.5\nmy_bool = True\nmy_bool = False\nmy_string = \"Mi cadena de texto\"\nmy_other_string = 'Mi otra cadena de texto'\n\nprint(\"¡Hola, Python!\")\n\nprint(Type(my_int))\nprint(Type(my_float))\nprint(Type(my_bool))\nprint(Type(my_string))\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/jorge23-blip.py",
    "content": "#https://www.python.org/ pagina oficial de python papa\n\n\"\"\"\ncomentario\nen \nvarias\nlineas jaja\n\n\"\"\"\n'''\notro\ncomentario\nen \nvarias\nlineas jeje\n'''\n\nMy_variable = \"hola xd\"\nMy_variable = \"hola xd otra vez xd\"\n\nMY_CONSTANT = \"SOY LA CONSTANTE\"\n\nmy_int = 1\nmy_float = 1.5\nmy_bool = True\nmy_bool = False\nmy_string = \"cadena de texto\"\nmy_other_string = \"otra adena de texto\"\n\nprint (\"hola python\")\nprint(type(my_int))\nprint(type(my_float))\nprint(type(my_bool))\nprint(type(my_string))"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/jorgeSilencio.py",
    "content": "# Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n# Documentación URL: https://developer.mozilla.org/en-US/docs/Web/JavaScript\n\n\n\n\n# Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n\n# Comentario de una línea\n\n\"\"\" \nComentario\nde varias\nlíneas\n\"\"\"\n\n\n# Crea una variable (y una constante si el lenguaje lo soporta).\nvariable_numero = 2\nvariable_texto = \"Variable numerica\"\nvariable_de_lista = [1, 2, 3]\n\nSIMULACION_DE_CONSTANTE = \"Constante\"\n\n\n# Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...)\n\nentero = 5\n\nflotante = 5.343\n\nbooleano = True\n\ncadena_de_texto = 'Hola'\n\n\n\n\n# Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nmensaje = \"¡Hola Python!\"\nprint(mensaje)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/jorgeadamowicz.py",
    "content": "# 1- Crea un comentario en el código y coloca la URL del sitio web oficial del\n#esta es la Web oficial de Python : https://www.python.org/\n\n# 2-Representa las diferentes sintaxis que existen de crear comentarios\n#en el lenguaje (en una línea, varias...).\n#Este es mi comentario en una sola línea!\n\n'''\neste es mi comentario\nen varias lineas\n'''\n#nota: si bien entendí el concepto, no entiendo por qué el editor de codigo marca \n#en rojo mi comentario en varias lineas. es porque lo toma como cadena de texto?. gracias! \n\n# 3- Crea una variable (y una constante si el lenguaje lo soporta).\n# esta es mi variable.\nmy_variable = \"mi variable\"\n\n# 4 - Crea variables representando todos los tipos de datos primitivos del lenguaje\n # (cadenas de texto, enteros, booleanos...).\nmy_string = \"mi cadena de texto\" # esta es mi variable para \"cadenas de texto\"\nmy_int = int(5) #esta es mi variable \"enteros\"\nmy_float = float(5.0) #esta es mi variable para valores \"flotantes\"\nmy_boolean = bool(True)# esta es mi variable para \"booleanos\"\n\n\n# 5 - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nprint(\"¡Hola\", \"Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/josandgon12.py",
    "content": "#Este es un comentario de una linea\n\n\"\"\"\nEsto es un comentrario de varia lineas\nSitio Oficial de Python\nhttps://www.python.org/\n\"\"\"\n#Variables y \"CONSTANTE\"\nvariable = \"Esto es una Variable\"\nCONSTANTE = \"Esto es una Constante\"\n\n#Tipos de Datos Primitivos\nes_int = 13\nes_float = 2.1\nes_string = 'Se pueden usar comillas simples'\nes_string2 = \"O comillas dobles\"\nes_bool = True\nes_bool2 = False\nprint(\"Hola, Python\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/josded21.py",
    "content": "# https://python.org\n\n# Comentario en una línea\n\n\"\"\"\nEsto también es\nun comentario\nen varias líneas\n\"\"\"\n\n'''\nEsto también es\nun comentario\nen varias líneas\n'''\n\nmy_variable = \"Mi variable\"\nmy_variable = \"Nuevo valor de mi variable\"\n\nMY_CONSTANT = \"Mi constante\"  # por convención\n\nmy_int = 1\nmy_float = 1.5\nmy_bool = True\nmy_bool = False\nmy_string = \"Mi cadena de texto\"\nmy_other_string = 'Mi otra cadena de texto'\n\nprint(\"¡Hola, Python!\")\n\nprint(type(my_int))\nprint(type(my_float))\nprint(type(my_bool))\nprint(type(my_string))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/jose-larss.py",
    "content": "# https://www.python.org/\n\n# Esto es un comentario en una linea\n\n\"\"\"\nEsto es\nun comentario\nen varias lineas\n\"\"\"\n\n'''\nEsto es\nun comentario\nen varias lineas\n'''\n\n# variables y constantes\nmi_variable = \"esto es una variable\"\nCONSTANTE = \"esto es una constante\"\n\n# Datos primitivos\nnumero = 12\nflotante = 12.5\nbooleano = True # o False\nstring = \"esto es un string\"\n\n# salida por consola\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/josecox13.py",
    "content": "#https://www.python.org/\n\n#Esto es un comentario de una línea\n\n'''\nEsto es un \ncomentario de\nvarias líneas\n'''\n\nvariable = 'Pedro'\n\n\n#En Python no existe el concepto de variables. En la comunidad se suele emplear mayúsculas para definir la variable\nPI = 3.141596\n\n#Los tipos de datos primitivos son\n#string\nejemplo_string = 'Cuadrado'\n\n#int\nejemplo_int = 8\n\n#float\nejemplo_float = 7.5\n\n#boolean\nejemplo_bool = True\n\n#nulo\nejemplo_nulo = None\n\n#Imprimir Hola, Python\nprint('Hola, Python')\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/joselin0407.py",
    "content": "# https://www.python.org\n# Comentarios:\n\n#Con el signo '#', se inicia un comentario y todo lo que se encuentren esa linea corresponde a comentarios del codigo\n\"\"\"\nTambien se pueden realizar comentarios extensos que se ubican dentro del rango de las tres comillas dobles\n\"\"\"\n\n'''\nLos comentarios que se encuentran dentro de estas comillas de tres sencillas \npueden tambien registrar comentarios de varias lineas\ncomo este\n'''\n#Variables\n\nVariable_Mes1 = Enero\nConstante_Año1  = 2025\n\n# - Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/josem17-cyber.py",
    "content": "# https://python.org\n\n# Comentario en una linea\n\n'''\nComentario en varias\nlíneas\n'''\n\n\"\"\"\nEsto también es un comentario en\nvarias líneas\n\n\"\"\"\n\nvar = 1 # Crea una variable\n\n\nCONS = \"hola\" # Crea una constante\n\n# Variables por tipos de datos\n\nnum = 1\nnum_float = 0.5\nstr = \"hola\"\nbool = True\n\nprint(\"Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/joshu725.py",
    "content": "# https://www.python.org/\n\n# Comentario de una linea\n\n\"\"\"\nComentario de\nvarias lineas\n:D\n\"\"\"\n\n# Creacion de variables (se recomienda el uso de snake_case para nombrar las variables)\nvariable = \"Esta es una variable\"\n# Creacion de constantes, se usa MAYUSCULAS por convención\nCONSTANT = \"Esta es una constante\"\n\n# Datos primitivos\nstr_variable = \"Cadena de texto\"\nint_variable = 25\nfloat_variable = 13.99\nbool_variable = True\n\nprint(\"¡Hola, Python! :)\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/jptxaya.py",
    "content": "#https://www.python.org/\n'''Comentarion en \nmas de una linea\n'''\n\n#Creacion de una variable\nmy_variable = 0\n\n#Variables con datos primitivos\nmy_int = 0\nmy_float = 1.5\nmy_boolean = True\nmy_string = \"Primitiva String\"\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/jrgranadosb.py",
    "content": "# https://python.org\n\n# comentario en una linea\n\n\"\"\" \nEsto tambien es un comentario en varias lineas\n\"\"\"\n\n'''\n Esta es otra forma de comentarios en varias lineas\n'''\n\n#Crear variables\nmy_var1 = \"my texto texto\"\nMY_CONSTANTE = \"esta es una constante\"\n\n# Tipos datos primitivos\n\n#Enteros\nmy_int = 1\nmy_float = 1.1\nmy_boolean = True\nmy_boolean = False\nmy_string = \"abcdef\"\n\n#imprimir texto \nprint(\"!Hola!, Python\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/jsacristanbeltri.py",
    "content": "#https://www.python.org/\n'''Otra forma de escribir comentarios'''\nCONSTANTE_PI = 3.14\nvariable_string = 'python'\nvariable_int = 1\nvariable_float = 1.5\nvariable_boolean = True\nvariable_complejos = 3 + 2j\nprint(f'¡Hola, [{variable_string}]!' )\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/jtrujilloalcocer.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n\"\"\"\n# Pagina Web: https://www.python.org/\n\n#Esto es un comentario con almoadilla\n\n'''\nEste es un ejemplo de comentario en donde se pueden escribir varias lineas, tantas como necesites.\n'''\n\n\"\"\"\nOtro ejemplo de comentario para mas de una linea\n\"\"\"\n\n#Declaracion de variables\nDatoVacio=None\nDatoEntero=2024\nDatoFlotante=3.1416\n\nDatoCadena=\"Este es mi primer reto\"\nDatoCaracter=\"A\"\n\nDatoBool=True\n\nprint(\"¡Hola Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/juan-cruz01.py",
    "content": "\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/juanDAW37.py",
    "content": "\"\"\"EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\"\"\"\n# URL https://python.org/\n\n# Comentario en una linea\n\n\"\"\" Comentario en \nvarias lineas \"\"\"\n\n# Variable\nvariable = \"Pepe\"\n\n# Constante\nPI = 3.1416\n\n# Tipos de datos primitivos\nvar = 1 # Tipo entero\nvar1 = 1.5 # Tipo double\nvar2 = \"Python\" # Tipo cadena de texto\n# Tipo booleano\nvar3 = True \nvar3 = False\n\n# Impresión por terminal\nprint(f\"¡Hola, {var2}!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/juanG482.py",
    "content": "python/juanG482.py\n\n#https://www.python.org esta es la pagina oficial de \n\n\"\"\"\nEsto es un comentario usando docstrings\n\"\"\"\n#variables\ntexto = \"hola mundo\"\nEnteros = 1\nes_valido = True\nEs_Falso = False\nDecimales = 10.22\n\nprint(texto)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/juanRCoder.py",
    "content": "# EJERCICIO 00:\n\n# Pagina oficial de python (https://www.python.org/)\n\n# comentario de una linea\n\n\"\"\"\nForma de hacer comentarios \npara multiples lineas\n\"\"\"\n\n'''\nOtra forma de hacer comentarios\nen multiples lineas\n'''\n\nlenguage = 'python'\nNUMERO_PI = 3.1416   # convención para variables constantes\nvariable_string = 'juanRCoder'\nvariable_int = 23\nvariable_float = 21.4\nvariable_bool = True | False\n\nprint(\"¡Hola, python!\")\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/juananguloardila.py",
    "content": "# https://python.org/\n\n# Comentario en una linea\n\n\"\"\"\nTextazo\n\"\"\"\n\nmy_variable = \"Mi variable\"\nmy_variable = \"Mi nueva variable\"\n# Ahi se cambio a mi nueva variable ya que se puede hacer conforme avanza la cadena\n\nMY_CONSTANT = \"Mi mi\" # por convencion en Python no hay constantes\n\nmy_int = 1\nmy_float = 1.5\nmy_bool = True\nmy_bool = False\nmy_string = \"Mi cadena de texto\" # se puede hacer texto con una sola comilla lado a lado\nmy_other_string = 'Mi otra cadena de texto'\n\nprint(\"¡Hola, Python!\")\n\nprint(type(my_float))\nprint(type(my_int))\nprint(type(my_bool))\nprint(type(my_string))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/juandaherrera.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\n\"\"\"\n# Página principal de Python: http://www.python.org\n\n# Comentario de una línea\n\n\"\"\"\nComentario\nde varias líneas\n\"\"\"\n\nmy_variable = \"Juan David\"\nmy_variable = \"Juan David Herrera\"\n\nMY_CONSTANT = \"API_KEY\"\n\nmy_int = 25\nmy_float = 1.33\nmy_bool = True or False\nmy_string = \"Mi cadena de texto\"\nmy_other_string = 'Mi otra cadena de texto'\nmy_lenguage = \"Python\"\n\nprint(f\"¡Hola, {my_lenguage}!\")\n\nprint(type(my_int))\nprint(type(my_float))\nprint(type(my_bool))\nprint(type(my_string))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/juanmax2.py",
    "content": "# Web oficial del idioma elegido -> https://python.org/\n\n# Comentario en una línea\n\n'''\nComentario en varias \nlineas con triple ' \n'''\n\n\"\"\"\nOtra manera de hacer un \ncomentario en varias lineas\ncon triple \"\n\"\"\"\n\n# Crear una variable\nmy_variable = \"Mi variable\"\n\n# El valor puede modificarse\nmy_variable = \"Mi variable modificada\"\n\n\"\"\"Solo es por convención, es decir se puede cambiar el\nvalor pero con las mayusculas indicamos que no se deberia hacer \n\"\"\"\nMY_CONSTANT = \"Mi constante\"\n\n# Datos primitivos\nmy_int = 1\nmy_float = 3.1\nmy_boolean = True\nmy_string = \"Mi string o str\"\n\n# Imprimir por pantalla\nprint(\"Hola, Python!\")\n   \n# Comprobación de los tipos de datos\nprint(type(my_int))\nprint(type(my_float))\nprint(type(my_boolean))\nprint(type(my_string))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/juanppdev.py",
    "content": "# https://www.python.org/\n\n# Conetario en una sola linea\n\"\"\"\nEsto es un\ncomentario en\nvarias lineas\n\"\"\"\n'''\nEsto tambien es un\ncomentario en \nvarias lineas\n'''\n\nmy_variable = 'My String Variable'\nprint(my_variable)\n\n# Variables\nmy_variable = 'My String Variable'\nprint(my_variable)\n\nmy_int_variable = 5\nprint(my_int_variable)\n\nmy_int_to_str = str(my_int_variable)\nprint(my_int_to_str)\nprint(type(my_int_to_str))\n\nmy_bool_variable = False\nprint(my_bool_variable)\n\nlenguaje = \"python\"\nprint(f\"Hola {lenguaje}\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/jucedinv.py",
    "content": "#https://www.python.org\n\nvprueba = \"\"#Comentario inline\n#Comentario en un bloque\n\"\"\"\nComentario multilínea\n\"\"\"\n\nvariableTest = \"\"\nCONSTANT_TEST = 1\n\nvint = 10\nvfloat = 20.1\nvboolean = False\nvstr = 'texto'\nvnone = None\n\nprint('¡Hola, python!')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/judithernandez.py",
    "content": "\"\"\" \n1.\nCrea un comentario en el código y coloca la URL del sitio web oficial del\nlenguaje de programación que has seleccionado. \n\"\"\"\n1.1\n# https://www.python.org/\n\n\"\"\" \n2.\nRepresenta las diferentes sintaxis que existen de crear comentarios\nen el lenguaje (en una línea, varias...).\n\"\"\"\n2.1\n# Comentario en una sola linea\n2.2\n\"\"\"\nEsto es un\ncomentario en\nvarias lineas\n\"\"\"\n2.3\n'''\nEsto tambien es un\ncomentario en\nvarias lineas\n'''\n\n\"\"\" \n3.\nCrea una variable (y una constante si el lenguaje lo soporta)\n\"\"\"\n3.1\nvar = \"variable\"\n3.2\nCONST = \"constante\"\n\n\"\"\"\n4.\nCrea variables representando todos los tipos de datos primitivos\ndel lenguaje (cadenas de texto, enteros, booleanos...).\n\"\"\"\n4.1\nstr_var = 'My String Variable'\n4.2\nint_var = 5\n4.3\nbool_var = False\n4.4\nfloat_var = 5.5\n4.5\ncomplex_var = 1j\n4.6\nlist_var = [\"apple\", \"banana\", \"cherry\"]\n4.7\ntuple_var = (\"apple\", \"banana\", \"cherry\")\n4.8\nrange_var = range(6)\n4.9\ndict_var = {\"name\" : \"John\", \"age\" : 36}\n4.10\nset_var = {\"apple\", \"banana\", \"cherry\"}\n\n\"\"\"\n5.\nImprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\"\"\"\n5.1\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/juli-m4.py",
    "content": "#https://python.org \n#comentario en linea\n...\ncomentario en\nvarias\nlineas\n...\n\n\" \" \"\notro comentario\nen varias\nlineas\n\" \" \"\n\nvariable_uno = 'Programa'\nVAR_CONSTANT = 'mi_var_constan'\n\ndato_int = 4\ndato_float = 4,5\ndato_bool = True\ndato_string\n\nprint('¡Hola, Python!')\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/julianbuitragocharry-dev.py",
    "content": "\"\"\"\n ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n - Recuerda que todas las instrucciones de participación están en el\n repositorio de GitHub.\n\n Lo primero... ¿Ya has elegido un lenguaje?\n - No todos son iguales, pero sus fundamentos suelen ser comunes.\n - Este primer reto te servirá para familiarizarte con la forma de participar\n enviando tus propias soluciones.\n \n EJERCICIO:\n Crea un comentario en el código y coloca la URL del sitio web oficial del\n lenguaje de programación que has seleccionado.\n Representa las diferentes sintaxis que existen de crear comentarios\n en el lenguaje (en una línea, varias...).\n - Crea una variable (y una constante si el lenguaje lo soporta).\n - Crea variables representando todos los tipos de datos primitivos\n del lenguaje (cadenas de texto, enteros, booleanos...).\n Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n \n ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n debemos comenzar por el principio.\n\"\"\"\n\n# https://www.python.org/\n\n### COMENTARIOS ###\n# Comentario de una sola linea\n\"\"\"\nComentario\nMultilinea\n\"\"\"\n\n### VARIABLES ###\n# Integer\nmy_int_variable = 7\n\n# Float\nmy_float_variable = 3.153\n\n# String\nmy_string_variable = 'Hello,'\n\n# Boolean\nmy_boolean_variable = True\n\nprint(my_string_variable, 'Python!')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/juliand89.py",
    "content": "#https://www.python.org/\n\n#esto es un comentario \n\n\"\"\"\nEsto es un comentario \nde varias lineas\n\"\"\"\n\nvariable = \"Esta es una variable \"\nvariable = \"variable modificada\"\n\nCONSTANTE = \"es una constante, valor no cambia\"\n\nstring = \"texto\"\nentero = 89\ndecimal = 12.2\nimaginario = 8j\ntrue = True\nfalse = False\n\nprint(\"Hola, python!\")\nprint(string)\nprint(entero)\nprint(decimal)\nprint(imaginario)\nprint(true)\nprint(false)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/julioorozco05.py",
    "content": "# Paso 1: \"comentar la URL del lenguaje\"\n\"https://www.python.org/\"\n\n\"-------------------------------------------------------------------------------------------------------------\"\n\n# Paso 2: \"diferentes maneras de comentar en python\"\n\n# - Existes varias maneras de poder comentar por ejemplo: (#, \"\", '') con estos podremos escribir lo que queramos.\n# El más común es el Comentario en una linea utilizando el (#)\n\n\"\"\"\ncon las comillas dobles podemos comentar varias lineas dentro de python \n\"\"\"\n\n'''\nTambién se puede realizar con las comillas simples\n'''\n\n\"-------------------------------------------------------------------------------------------------------------\"\n\n# Paso 3:\n# variable tipo número y tipo texto\ny = 5\npaís = USA\n# constante\nPI = 3.141592\n\n\"-------------------------------------------------------------------------------------------------------------\"\n\n# Paso 4: \"Tipos de variables\" \n\n# 1: tipo número (int)\nnumero = 55\n\n# 2: tipo texto (string)\nlenguaje = \"python\"\n\n# 3: tipo booleano (bool)\ncasa = True \n\n# 4: tipo flotante (float)\ndecimal_num = 212.56\n\n\"-------------------------------------------------------------------------------------------------------------\"\n\n# Paso 5: \"imprimir resultados\"\n\nprint(\"Hola, python\")\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/k-90.py",
    "content": "### Mi lenguaje va a ser python y su pagina web es https//:python.org\n# Comentario en una línea\n\n\"\"\"\nEsto también es\nun comentario\nen varias líneas\n\"\"\"\n\n'''\nEsto también es\nun comentario\nen varias líneas\n'''\n\nmy_variable = \"Mi variable\"\nmy_variable = \"Nuevo valor de mi variable\"\n\nMY_CONSTANT = \"Mi constante\"  # por convención\n\nmy_int = 1\nmy_float = 1.5\nmy_bool = True\nmy_bool = False\nmy_string = \"Mi cadena de texto\"\nmy_other_string = 'Mi otra cadena de texto'\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/k3nvd.py",
    "content": "#https://www.python.org/\n\n#There are two ways to comment in Python\n#                                                    \"#Hello World\"\n#                                                ''' Hello World'''\n\nvar1 = 'Python'                                              #simple var\nPI = 3.1426                                                  #const var   \n\n#Primitive data types \n\nage = 25  \nscore = -7  \nnumber_of_lives = 3 \nstringg = 'Hello' \ndictt = {\n    'name':'Kevin',\n}\nlitt = [1,2,4,5]\nsett = (1,'Hello',2,35,3,100)\n\n\nprint('Hello', var1)                       \n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/kai2908.py",
    "content": "# https://www.python.org/\n\n# comentario en python\n\n\"\"\"\neste comentario es un poco mas extenso.\nlo realizo para descubrir los limites del\ncomentario\n\"\"\"\n\n'''\ntambien se pueden realizar\nde esta manera\n\n'''\n\n_variable = \"mi variable de texto\"\n_variable = \"nuevo valor de mi variable de texto\"\n\n# Las constantes las voy a representar con mayusculas \n\n_CONSTANTE = \"mi constante\"\n\n# datos primitivos de python\n\n# tipo: int (numeros enteros) \n\nedad = 25\ncantidad_personas = 100\nprint( edad + 10 ) # resultado: 35\n\n# float (nunero decimal)\n\nprecio = 20.99\ntasa_interes = 0.6\nprint(precio * ( 1 + tasa_interes )) # resultado: 33.584\n\n# tipo: str (cadena de texto)\n\nnombre = \"ariel\"\nsaludo = \"hola \" + nombre\nprint(saludo) # resultado: hola ariel\n\n# varios ejemplos de booleanos\n\n# tipo: bool (booleano) — ejemplos lógicos\n\nes_verdad = True\nes_falso = False\nprint(es_verdad and es_falso) # resultado: False ( para que \"and\" de \"True\" ambos deben de ser verdaderos)\nprint(es_verdad or es_falso) # resultado: True (para que \"or\" de \"False\" ninguno deben de ser \"True\")\nprint(not es_falso) # resultado: True (\"not\" invierte el resultado, por lo cual lo que \"False\" pasa a ser \"True\")\nprint(not es_verdad) # resultado: False (en este caso, \"not\" invirte el resultado \"true\" y lo comvierte en \"False\")\n\nprint(type(precio))\nprint(type(nombre))\nprint(type(es_falso))\nprint(type(edad))\n  \nprint(\"¡hola, python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/kata-lg.py",
    "content": "# 1.- Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n#https://www.python.org/\n\n# 2.- Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n# Este es un comentario de una linea\n\n'''\nEste es un comentario\nde varias lineas\n'''\n#3.- Crea una variable (y una constante si el lenguaje lo soporta).\n\nvariable = 'esta es una variable'\nVARIABLE = 2\n\nvariable_str = 'esta es una variable de tipo texto'\nvariable_int = 5\nvariable_float = 2.5\nvariable_bool = True\n\nprint = 'Hola Python'"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/keltoi-dev.py",
    "content": "\"\"\"\n* EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n\"\"\"\n# Ese es un comentario multilinea y este es de una linea\n\n# Sitio oficial: https://www.python.org/\n\ncadena = str(\"abc 123 @#$\")\nnumeros_enteros = int(\"123\")\nnumeros_con_decimales = float(\"12.34\")\nbooleanos = bool(0)\n\nprint(\"Tipos de datos en las variables\")\nprint(\"Strings:\", cadena)\nprint(\"Numeros enteros:\", numeros_enteros)\nprint(\"Numeros con decimales:\", numeros_con_decimales)\nprint(\"Datos booleanos:\", booleanos)\nprint(\"-\" * 25)\nnumeros_enteros = \"Python\"\nprint(\"Hola,\", numeros_enteros)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/kenysdev.py",
    "content": "# ╔══════════════════════════════════════╗\n# ║ Autor: Kenys Alvarado                ║\n# ║ GitHub: https://github.com/Kenysdev  ║\n# ║ 2024 - Python                        ║\n# ╚══════════════════════════════════════╝\n\n# 1. Sitio web oficial:\n# *********************\n# https://www.python.org/\n\n# 2. Sintaxis para comentarios:\n# *****************************\nsuma = 1 + 2 # comentario inline\n\n# Comentarios Block\nsuma = 1 + 2\n'''\ncomentario para\nmúltiples líneas.\n'''\n# TODO Para explicar función de código aún no escrito\n# TODO actualizaciones o cambios en tu código.\n\n\"\"\"Docstring en una linea\"\"\"\n\n\"\"\"\nComentarios Docstring múltiples líneas.\nprimera declaración en una definición \nde módulo, función, clase o método. \nhttps://peps.python.org/pep-0257/\n\"\"\"\n\n# 3. Variable y constante.\n# ************************\nvariable_str = \"ejemplo str\"\n\n# python no tiene contantes pero \n# por convenio comunitario se usa:\nCONSTANTS_STR = \"https://peps.python.org/pep-0008/#constants\"\n\n# 4. Variables para datos primitivos.\n# ***********************************\nint_entero = 12\nfloat_decimal = 12.21\nstr_texto = \"Hola, Python\"\nbool_booleano = True # o False\n# a + b numeros reales y j unidad imaginaria  \ncomplex_complejo = 12 + 21j \n\n# imprimir tipo de variable:\nprint(type(int_entero)) # Salida: <class 'int'>\n\n# 5. Imprime: hola, lenguaje:\n# **************************\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/kkstrofico.py",
    "content": "# www.python.org\n\n# Esto es un comentario de una sola linea, se realiza con #\n\n\"\"\"\nEsto es un comentario de multiples linas \n\"\"\"\n\n\n\n# Tipos de datos primitivos\nCONSTANTE = \"Esto es una constante en python(Anque realme python como tal no tiene constantes)\"\ncadena = \"esto es una dato de tipo string\"\nentero = 1\nflotante = 1.2\ncomplejo = 4j\nbooleano = True\nlista = [1,'dos',3]\ntupla = ('uno',2,'tres')\ndiccionario = {\"valor1\":1,\"valor2\":\"dos\"}\n\n\n# Imprimiendo el nombre del lenguaje\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/knowledgesoftdev.py",
    "content": "#https://www.python.org/\n\n#Comentarios de una sola linea\n\n\"\"\"\nEsto es un \ncomentario en \nmultilinea\n\"\"\"\n\n#Ejemplo de Variable\nprecio=13\n\n#Ejemplo de Constante\nPI=3.1415\n\n#Variables Primitivas\ncadena=\"Brayan\"\nentero=17\ndecimal=12.7\nboolean=True\n\nprint(\"Hola, python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/kodenook.py",
    "content": "# https://www.python.org\n\n\"\"\" Comments \"\"\"\n\n\n# single-line comment\n\n# this is a\n# multi-line comment\n\n'''\nthis is a multi-line string\nand is ignored if not are assigned\nto a variable so can use it as a comment\n'''\n\n\n\"\"\" Variables and Constants \"\"\"\n\nvariable = 'variable'\nCONST = 'const' # The keyword 'const' does not exist in Python; this is a convention and the variable is mutable\n\n\n\n\"\"\" Data Types \"\"\"\n\nstring:str = 'string'\nint:int = 1\nfloat:float = 2.5\ncomplex:complex = 3j\nlist:list = [1,2,3]\ntuple:tuple = (1,2,3) # tuples are inmutable\nset:set = {1,2,3} # unique elements and unordered(not support indexes)\ndict:dict = {'first': 1, 'second': 'me'} #key-value pairs\nbool:bool = True # True or False\n\n\n\"\"\" Print \"\"\"\n\nprint('¡Hola, python!')\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/krisipo.py",
    "content": "\n# URL oficial de Python: https://www.python.org/\n\n# Diferentes formas de crear comentarios en Python\n# ------------------------------------------------\n\n# Esto es un Comentario in-line\n\n# Python no permite de manera nativa comentarios multilínea\n# por lo que podmeos \"simular\" esta característica enlazando \n# diversos comentario in-line\n\n'''\nO bien, utilizando la sintaxis de cadenas multilíneas \ncon triple comilla simple o triple comilla doble\n'''\n\n# Creación de una variable y una constante\n# ------------------------------------\nsaludo = \"Hola Mouredev\"  \n\n# Para crear una constante declaramos igualmente una variable,\n# y utilizamos la convención de designar el identificador en mayúsculas \n# para que otros programadores sepan que ese variable no debe ser alterada\nCTE = 3.14\n\n# Representación de datos primitivos mediante variables \n# -----------------------------------------------------\nint_entero = 66 # Número enteros\nfloat_decimal = 3.14\nstr_texto = \"Hola Mouredev\"\nbool_booleano = True # Se le pueden asignar dos valores True o False\ncomplex_complejo = 4.5 + 6j # a + b numeros reales y j unidad imaginaria\n\n# Imprimir por terminal\n# ---------------------\nprint (\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/kronoscba.py",
    "content": "\"\"\"\"\nEJERCICIO\n   Crea un comentario en el código y coloca la URL del sitio web oficial del\n   lenguaje de programación que has seleccionado.\n  Representa las diferentes sintaxis que existen de crear comentarios\n    en el lenguaje (en una línea, varias...).\n   Crea una variable (y una constante si el lenguaje lo soporta).\n   Crea variables representando todos los tipos de datos primitivos\n    del lenguaje (cadenas de texto, enteros, booleanos...).\n   Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\"\"\n\n# https://www.python.org.ar/\n\n# comentario de una linea\n\n\n\"\"\"comentario de \n    varias lineas\"\"\"\n\n\"comentario de una linea\"\n\nmi_variable = \"esta es mi variable\"\nmi_variable = \"esta es mi nueva variable\"\n\nMI_CONSTANTE = \"mi constante\"  # cuando tiene mayuscula represnta que no se debe cambiar\n\nmi_entero = 48\nmi_flotante = 1.25\nmi_boleano = True\nmi_boleano = False\nmi_cadena = \" esta es una cadena de texto\"\nmi_otra_cadena = \"esto es mi otra cadena de texto\"\n\nprint(\"Hola Python\")\nprint(type(mi_entero))\nprint(type(mi_flotante))\nprint(type(mi_boleano))\nprint(type(mi_cadena))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/kshields51.py",
    "content": "#\n# ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n# - Recuerda que todas las instrucciones de participación están en el\n#   repositorio de GitHub.\n#\n# Lo primero... ¿Ya has elegido un lenguaje?\n# - No todos son iguales, pero sus fundamentos suelen ser comunes.\n# - Este primer reto te servirá para familiarizarte con la forma de participar\n#   enviando tus propias soluciones.\n#\n# EJERCICIO:\n# - Crea un comentario en el código y coloca la URL del sitio web oficial del\n#   lenguaje de programación que has seleccionado.\n# - Representa las diferentes sintaxis que existen de crear comentarios\n#   en el lenguaje (en una línea, varias...).\n# - Crea una variable (y una constante si el lenguaje lo soporta).\n# - Crea variables representando todos los tipos de datos primitivos\n#   del lenguaje (cadenas de texto, enteros, booleanos...).\n# - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n#\n# ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n# debemos comenzar por el principio.\n \n\n# https://www.python.org/\n\n# comment\n\n'''\nThis is a docstring\n'''\n\n\nvar_1 = \"somevar\"\nSOME_CONSTANT = 'This is a constant'\n\nsome_string = \"This is a string\"\nsome_int = 1\nsome_bool = True\nsome_float = 3.3\n\nprint('¡Hola, Python!')\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/kuroz00.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\"\"\"\n\n#https://www.python.org/\n\n#comentario de una linea\n\n\"\"\"\ncomentario de \nvarias\nlineas\n\"\"\"\n\n'''\ncomentario de varias lineas\npero con comillas simples\n'''\n\n#variable y constante \n\ncaja1 = 10\n\nfelicidad = \"python\"\n\n#tipos de datos primitivos\n\nnumero_numeroEntero = 25\nnumero_flotante = 25,5\nnumero_complejo = 1j #complex\nlista_list = [\"manzana\", \"platano\", \"naranja\"]\nlista_tuple = (\"manzana\", \"platano\", \"naranja\")\nrango_range = range(25)\nlist_frozenSet = {{\"manzana\", \"platano\", \"naranja\"}}\ncadenaDeTexto = \"hola, desea comer un pie de limon?\"\nvalorBooleano = True\n\n#Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\n\nprint(\"Hola,\", felicidad,\"!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/lPassword012.py",
    "content": "# URL del sitio web oficial de Python: https://www.python.org/\r\n\r\n# Primer Script: desafio #00\r\n\r\n\"\"\"\r\nUsuario: lPassword012\r\nRol: Estudiante analista de datos\r\n\"\"\"\r\n\r\n# Creacion de una variable y una constante (aunque Python no tiene constantes estrictas)\r\nnombre_lenguaje = \"Python\"\r\nversion_lenguaje = \"3.12.1\"\r\nNOMBRE_USUARIO = \"lPassword012\"  # Convencion: se usa mayusculas para indicar que no deberia modificarse.\r\n\r\n# Variables de tipos de datos primitivos.\r\ncadena_texto = \"Esto es una cadena\"\r\nentero = 42\r\nflotante = 3.14\r\nbooleano = True\r\ncomplejo = 1 + 2j\r\nlista = [1, 2, 3]\r\ntupla = (4, 5, 6)\r\ndiccionario = {\"clave\": \"valor\"}\r\nconjunto = {7, 8, 9}\r\n\r\n# Imprimir mensaje por la terminal.\r\nprint(f\"¡Hola, {nombre_lenguaje}!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/lagoausente.py",
    "content": "# https://www.python.org/\n#  Hola Moure, gracias por tanto contenido\n\n\"\"\"\nY por hacerlo \naccesible desde cero\n\"\"\"\n'''\nEmpezamos con ilusión, \na ver si la mantenemos\n'''\n\nmy_counter = 1\nmy_counter = 5\n\nMY_CONSTANT = \"mi constante\"  # convención\n\nintegrado = 20\nflotante = 20.6\nboleano = True\nBoleano = False\nCadena_texto = \"entre comillas\"\nCadena_texto = 'comillas simples'\n\nprint (\"Hola, Python!!\")\n\nprint (type(integrado))\nprint (type(flotante))\nprint (type(boleano))\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/latorredev.py",
    "content": "# https://python.org/\n\n# One line comment\n\n\"\"\"\nDouble\nLine\nComment\n\"\"\"\n\n# Variable\nmy_var = \"This is a variable\"\n# Constant\nMY_CONS = \"This is a constant\"\n\n# Integer\nmy_int = 7\n# Float\nmy_float = 7.7\n# Boolean\nmy_boolean = True\n# String\nmy_string = \"This is a string\"\n\n# Hello world!\nprint(\"¡Hola, python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/latteMiguelangel.py",
    "content": "#EJERCICIO:\n#Crea un comentario en el código y coloca la URL del sitio web oficial del\n#lenguaje de programación que has seleccionado.\n#Representa las diferentes sintaxis que existen de crear comentarios\n#en el lenguaje (en una línea, varias...).\n#Crea una variable (y una constante si el lenguaje lo soporta).\n#Crea variables representando todos los tipos de datos primitivos\n#del lenguaje (cadenas de texto, enteros, booleanos...).\n#Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\n# ------ PHASE 1 ------\n# OFFICIAL WEBSITE OF PYTHON: ------> https://www.python.org/ <-----------\n# comment in python --------> #\n\n\"\"\"\nComment in many lines\nit's pretty good \n:D\n\"\"\"\n\n'''\nthis is another form to\ncomment in many lines\n;)\n'''\n\n# comment in HTML ----------> /* */\n# comment in C (& others) --> //\n\n# ------ PHASE 2 ------\nLUCKY_NUMBER = 55    # Python doesn't have a const type, but has conventions\ntypeInteger = 0\ntypeFloat = 0.12\nString = \"This is a type of var String\" # really is an object but, it's acceptable\ntypeComplex = 4 + 3j\nisBoolean = True\n\n#python convention\nvar = \"snake_case\"\n\n# ------ PHASE 3 ------\nlanguage = \"Python\"\nprint(f\"Hi!!!, this is {language}\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/lauradiazm29.py",
    "content": "#Esta es la página oficial de Python: https://www.python.org/\n\n#Esto es un comentario de una línea\n\n'''Esto es un comentario de varias lineas.\nAunque en verdad se utiliza para definir funciones, clases, etc.'''\n\n#una variable tipo int\nmi_variable = 9 \n\n#una constante, aunque habria que hacerlo en otro file e immportarla\nMICONSTANTE = 59\n\n#entero o int\nnumero1 = 2\n#decimal o float\nnumero2 = 3.5\n#cadena de texto o string\ntexto = \"Hola, soy Laura\"\n#booleano o bool\nverdad = True\n#variable de ningun tipo\nnada = None\n\nprint('¡Hola, Python')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/lauvis11.py",
    "content": "# pagina web de python oficial https://www.python.org/\n# variables\nmy_int = 20\nmy_string = \"este es un texto\"\nMY_CONSTANT = \"esta es una constante\"\nmy_boolean = True\nmy_languaje = \"Python\"\n\nprint(\"Hola, \" + my_languaje)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/leanaren.py",
    "content": "# https://www.python.org/\n\n\"\"\" HOLA\nPROBANDO\nLOS \nCOMENTARIOS\"\"\"\n\nmy_variable = \"variable1\"\n\nmy_constant = \"constante1\"\n\nmy_int = 1\nmy_float = 1.5\nmy_bool = True\nmy_bool = False\nmy_string = \"cadenas de textos\"\n\nprint (\"¡Hola, python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/leo18q.py",
    "content": "\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/lilberick.py",
    "content": "# https://www.python.org/\n#######TIPOS DE DATOS PRIMITIVOS#######\n# Comentrio de una linea\n\"\"\"\nComentario de\nvarias lineas\n\"\"\"\n\n#######VARIABLE Y CONSTANTE#######\nvariable = 2.35\nPI = 3.14159 #En Python no hay constantes pero por convención podemos usar mayúsculas para representarlas\n\n#######TIPOS DE DATOS PRIMITIVOS#######\n# Cadenas de texto\nmi_nombre = \"Bard\"\nmi_frase = \"Hola, soy Bard\"\n\n# Enteros\nmi_edad = 18\nmi_altura = 1.75\n\n# Flotantes\nmi_peso = 75.5\nmi_sueldo = 1500.00\n\n# Booleanos\nsoy_mayor_de_edad = True\nsoy_soltero = False\n\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/linerlander.py",
    "content": "# https://www.python.org/\n\n# Comenterio en una línea\n\n\"\"\"\nEsto también es\nun comenterio\nen varias líneas\n\"\"\"\n\n'''\nEsto también es\nun comenterio\nen varias líneas\n'''\n#Variable\nmy_variable = \"Liner\"\nmy_variable = \"Liner Lander\"\n\n#Constante\nMY_CONSTANTE = 'Mi constante' #por convención\nMY_CONSTANTE = 'Cambiando mi constante'\n\n#Datos primitvos\n\nmy_int = 24 #entero\n\nmy_float = 1.67 #float\n\nmy_bool = True #boolean True\nmy_bool = False #boolean False\n\nmy_string = \"Liner Lander\" # string con comilla doble\nmy_other_string = 'Hanny' # string con comilla simples\n\nprint('¡Hola, Python!') #imprimir \n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/ljoecordoba.py",
    "content": "# URL del sitio web oficial del lenguaje de programación Python:\n# https://www.python.org/\n\n# Comentario de una sola línea en Python\n\n\"\"\"\nComentario de varias líneas en Python.\nPuede abarcar múltiples líneas sin problemas.\n\"\"\"\n\n# Declaración de una variable\nvariable_ejemplo = \"Esta es una variable\"\n\n# Declaración de una constante (en Python, no hay una verdadera constante,\n# pero se usa la convención de nombrar en mayúsculas)\nCONSTANTE_EJEMPLO = \"Esta es una constante\"\n\n# Declaración de variables con diferentes tipos de datos primitivos en Python\ncadena_texto = \"Este es un texto\"  # Cadena de texto\nnumero_entero = 42  # Entero\nnumero_flotante = 3.1415  # Flotante\nbooleano = True  # Booleano\n\n# Imprime por terminal el texto: \"¡Hola, Python!\"\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/llonardo798.py",
    "content": "# 1. URL del sitio web oficial de Python: https://docs.python.org/\n\n# 2. Sintaxis de comentarios en Python:\n\n# Comentario de una sola línea\n\n\"\"\" \nComentario de \nvarias líneas \n\"\"\"\n\n# 3. Creación de una variable y una constante:\n\nvariable = 10\n\nCONSTANTE = 3.1416\n\n# 4. Tipos de datos primitivos (Fundamentales) en Python:\n\ncadena = \"Hola, mundo!\" # Cadena de texto (String)\nentero = 10 # Entero (Integer)\nflotante = 3.14 # Flotante (Float) - Número decimal\nbooleano = True # Booleano (Boolean) - True o False\ncomplex = 1 + 2j # Número complejo (Complex) - Parte real e imaginaria (j)\nbytes = b\"Python\" # Bytes (Bytes) - Secuencia de bytes\nbytesUnicode = b'\\x41' # Bytes Unicode (Bytes) - Secuencia de bytes Unicode\nvalorNulo = None # Valor nulo (None) - Representa la ausencia de valor\n\n# 5. Imprimir por consola\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/lluistech.py",
    "content": "# https://www.python.org/\n\n# Esto es un comentario\n\n'''\nEsto es un comentario\nde diferentes líneas\nque también puede ser útil\n'''\n\nprimeraVariable =\"Esta es mi primera variable en estos retos\"\n\nCONSTANTEFAKE= \"En python no existen las constantes pero se simulan escribiendo en mayusculas\"\n\n# En Python tenemos estos tipos de datos primitivos\n\nnumero= 12 # Esto es un dato Int\nnumeroFlotante= 30,50 # Este es un dato float \ntexto=\"Esto es un dato tipo string\"\nboleano= True # Este es un tipo de dato boleano\n\nprint(\"Hola Python\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/luceldasilva.py",
    "content": "# Este es un comentario de una línea\n\n'''\n    Comentario de párrafos\n    URL de python https://www.python.org \n'''\n\n\"\"\"\n    Truco usar constantes usar typing.Final\n    Y verificar archivo con la librería mypy\n    `mypy tu_archivo.py`\n    para indicar si tienes constantes que intentaste editarlas\n    las constantes sin esa librería si son el mismo tipo de dato\n    te validará que es el correcto cosa que no es cierto xP\n    \n    Aprendido en Código Facilito \n    URL = https://codigofacilito.com/cursos/type-hints\n    y encontré en youtube un short\n    URL = https://www.youtube.com/shorts/fNMgJaDYxvk\n\"\"\"\nfrom typing import Final\n\n\nMY_CONSTANT: Final[str] = 'esto es una constante'\n\nmy_variable: str = 'esto es un texto'\n\nmy_integer: int = 4\n\nmy_float: float = 5.23\n\nmy_bool: bool = True\n\n\nprint('Hola, Python!')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/luisangeles20.py",
    "content": "# Sitio web oficial del lenguaje Python: https://python.org/\n\n# Esta es una forma de crear comentarios de una línea con Python\n\n# Esta es una forma\n# de crear comentarios\n# de varias líneas con Python\n\n'''\nEsta es otra forma de crear \ncomentarios de varias líneas\nen Python\n'''\n\n# Variables en lenguaje Python:\n\nString_Simple = 'Python'\nString_Multiline = '''Esta es una variable\nde multiples líneas'''\n\nNumber_int = 20\nNumber_float = 10.5\nNumber_complex = 4 + 5j\n\nVar_Boolean = True\n\nCONSTANTE = 'Valor estático'\n\nVar_Lista = [15, 2.8, 'Un texto', ['Otra lista']]\n\nVar_Tupla = (2, 4.8, 'Python')  # Similar a una lista, no se puede modificar\n\nVar_Diccionario = {'Nombre': 'Luisana', 'Edad': 27, 'Lenguajes':['Python', 'VisualBasic']}\n\nVar_Conjunto = {1, 2, 3, 4, 5}\n\n# Hola, mundo!\nResult = '¡Hola, Python!'\nprint(Result)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/luisantoniob18.py",
    "content": "#https://www.python.org/\n\n##SINTAXIS PARA CREAR COMENTARIOS DE UNA LINEA O DE VARIAS\n\n#Esto es un comentario de una sola línea\n\n#No existen una sintaxis para\n#comentarios de varias líneas\n# en py como en c# (/* ... */)\n\n#Alternativa a comentarios de varias líneas\n\"\"\"\nNo es una sintaxis como tal, pero\nal ser texto que no esta asginado\na una variable, el interprete no \ntomará en cuenta este fragmento.\nQue de hecho es lo recomendable por\nconvención para documentar funciones,\nclases o módulos.\n\"\"\"\n\n##CREACION DE UNA VARIABLE Y CONTANTE*\nnombre_variable = 'uisbaquiaxb18'\nconstante = 3.1416\n\n#En py no se especifica el tipo de variable\n#ni tampoco existen las contantes nativas\n\n##CREACION DE VARIABLES CON TIPOS DE DATOS PRIMITIVOS\n\n#int \nmi_edad = 27\n#float\nsalario = 6500.50\n#complex o complejos\nz = 5 + 6j\n#str o cadenas de texto\nmi_nombre = \"Luis\"\n#booleano\nactivo = False\n\n#no primitivo\n\n#byte\ndato = b\"Hello!\"\n\n##IMPRESION DE TEXTO POR TERMINAL\nlenguaje = \"Python\"\n\nprint(\"!Hola, \", lenguaje, \"!\")\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/luisfglondono.py",
    "content": "# https://www.python.org/\n\n# comentario en una línea\n\n\"\"\"\ncomentario en\nvarias líneas\n\"\"\"\n\n'''\ncomentario en\nvarias líneas\n'''\n\nmy_variable = 'variable'\n\nMY_CONSTANT = 'constante' # convención\n\nmy_int = 1\nmy_float = 2.5\nmy_str = \"string\"\nmy_bool = True\n\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/luisssSoto.py",
    "content": "#1. This is a comment in Python, and here is the official URL: https://www.python.org/\n\n#2. In python is not possible to type a multiline comment with only \"#\"\n# however, you can use another method calls \"doc string\":\n\n\"\"\"Doc string \"\"\"\n'''is a way to write information, frequently use it in modules,\nto any user that want to use our module, so you can type specific \ninformation about what the name is and what the purpose is'''\n\n#3 Python doesn't have a strict way to declare variables as\n# constants and only variables, but it's a good practice to\n# type a constant with uppercase and variables with lowercase:\n\nfullName = input('Write your name: ')\nPI = 3.1416\n\n#4. Primitive data types in Python are called literals\n\nstring = 'It\\'s any amount of characters that you want'\ninteger = 30\nfloat = 2.718281828459045\nboolean = True\nboolean = False\nnone = None\n\n#5 In python it's quite easy to print somethin, just look it:\nprint('Hello Python!!!')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/luistecnocode.py",
    "content": "'''\n /*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n'''\n###### COMENTARIOS ######\n\n# https://www.python.org/\n\n# Una línea\n\n# Varias\n# Lineas\n\n'''\nMultilinea\n'''\n\n\"\"\"\nOtra multilinea\n\"\"\"\n\n###### VARIABLES #######\nmy_variable = 5\nMY_CONSTANT = \"mi constante\" # No lo es, pero por convencion MAYUSCULAS\n\nmy_int = 1\nmy_float = 1.2\nmy_bool = True\nmy_string = \"eso es un texto\"\nmy_other_string = 'esto es otro texto'\n\nprint(\"Hola, Python!\")\n\nprint(type(my_int))\nprint(type(my_float))\nprint(type(my_bool))\nprint(type(my_string))\nprint(type(my_other_string))"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/luterfloyd.py",
    "content": "# URL OFCIAL DE PYTHON: https://www.python.org/\n\n# COMENTARIO DE UNA LINEA: COLOCAR # A LA IZQUIERDA\n# lo que se encuentre hacia la derecha del hashtag sera omitido por el interprete python\n\n''' \n    COMENTARIO EN VARIAS LINEAS (1 de 2):\n        se demarca tanto al principio como al final tres comillas\n        pudiendo ser simples...\n\n'''\n\"\"\"\n    COMENTARIO EN VARIAS LINEAS (2 de 2):\n        ...como comillas dobles, el resultado sera el mismo.\n        Todo lo que se encuentre dentro del bloque de comillas\n        sera omitido por el interprete de python\n\"\"\"\n'''\n    CONSTANTES Y VARIABLES\n    \n    * constantes: no existe como tal una forma de declarar constante en python, aunque se puede\n    respetar una convencion al identificar nombre de varia en mayuscula como si fuera \n    un valor inmutable. Sin embargo, existen algunas constantes propias del lenguaje,\n    como por elemplo: True o False\n\n    * variables: python tiene 4 tipos de variables primitivas (referidas a aquellas que\n    no pueden dividirse en partes mas peque#as). No es necesario declararlas como sucede\n    en otros lenguajes, aunque se puede indicar cual sera su configuracion inicial,\n    lo cual servira de referencia para evitar inconvenientes con su uso. Ademas, los IDE\n    podran monitorear mejor el codigo.\n    Sin embargo, al ser un lemguaje de tipado dinamico, una vez que se han creado, \n    las mismas pueden ser modificadas en el mismo proceso de ejecucion. Pueden ser nombradas\n    en cualquier estilo aunque se recomienda que sean facil de identificar al leer el codigo:\n\n    Los tipos de variables primitivas serian:\n    variables numericas: int, float\n    alfanumericas: str\n    booleanas: bool\n'''\nCONSTANTE = 10\nvariable_numerica_entera = 5\nvariable_numerica_flotante = 5.5\nvariable_alfanumerica = \"Hola\"\nvariable_booleana = True\n\nlenguaje_usado = \"python\"\n\nprint (f\"Hola mundo, esta es mi primer reto en {lenguaje_usado} \")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/m-doce.py",
    "content": "#Sitio Oficial -> https://www.python.org/\r\n\r\n#Para crear comentarios de una sola línea, se coloca el '#' al comienzo de la misma\r\n\r\n'''Para crear\r\ncomentarios de\r\nmúltiples líneas\r\nse utilizan tres\r\ncomillas simples\r\nal comienzo y\r\nal final del mismo'''\r\n\r\nyear = 2024 #Para crear una variable debemos escribir su nombre y darle un valor\r\nseason = \"Summer\" #No es necesario definir el tipo de dato\r\n\r\nWORLD = \"Earth\" #En Python no existen las constantes como tal, pero por convención se declaran con letras mayúsculas aquellas variables cuyos valores no queremos modificar\r\n\r\n#Tipos primitivos\r\nentero = 12\r\nflotante = 24.7\r\ncadena = \"github\"\r\nbooleano = True\r\nninguno = None #Para variables a las que aún no le asignamos ningún dato\r\n\r\nprint(\"Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/m-hadz.py",
    "content": "# https://www.python.org/\n\n# Se usa para comentarios de una linea\n\n\"\"\"\nSe utiliza para comentarios\nde multiples lineas\n\"\"\"\n\nvariable = \"ejemplo\"\n\nCONSTANTE = 3.14 # Las mayusculas se usan para indicar constantes\n\n\n# Estos son los tipos de datos primitivos de Python\n\nstring = \"hola\" # Str\n\nentero = 3 # Int\n\nflotante = 3.14 # Float\n\nbooleano = True # Boolean\n\nsintipo = None # NoneType\n\n# para imprimir se utiliza la función print\n\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/m4nu3Il.py",
    "content": "\"\"\"\n* EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n\"\"\"\n\n# python.org\n\n# Commentary in hash\n\n\"\"\"\nCommentary in quotation marks\n\"\"\"\n\n'''\nCommentary in apostrophes\n'''\n\ndonkey = \"animal\"\n\nñ = \"String\"\n1 = \"Int\"\n0.1 = \"Float\"\nFalse = \"Binary\"\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/m4xxDeV.py",
    "content": "#Sitio oficial de Python: https://www.python.org\n\n#Comentario de una sola linea usando #\n\n'''\nEsto es un comentario multilinea usando tres comillas simples\n'''\n\nvariable_texto = \"Hola Mundo\" #String (texto literal) entre comillas\nCONSTANTE_PI = 3.141592 #Se usan las mayusculas por convención para las constantes\nvariable_entero = 10 #Numero entero (integer) sin comillas\nvariable_decimal = 53.6 #Numero decimal (float) usando un punto\nvariable_booleana = True #Valor de verdad (True/False)\nvariable_none = None #Variable vacia (sin valor)\n\nprint(\"Hola, Python!\")\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/macova96.py",
    "content": "\"\"\"\nSitio Oficial de python ---> https://www.python.org/\n\"\"\"\n\n# Este es un comentario de una sola linea\n\n\"\"\"\nEste es\nun comentario\nde varias lineas\n\"\"\"\n\n#Variables y Constantes\nradio = 13.45   # Esta es una variable de tipo Float\nPI = 3.14159    # Esta es una constante <--- por CONVENCIÓN\n\"\"\"\nEn python no existen las constantes hablando de manera estricta,\naunque por convención se suele declarar variables con MAYUSCULAS\npara indicar que son constantes a las cuales no se les deberia cambiar\nsu valor una ves declarada.\n\"\"\"\n\n#Tipos de Datos Primitivos\n\nstr_var = \"hola mundo\" #Variable string (texto) (str)\nint_var = 12345         #Variable integger (numeros enteros) (int)\nfloat_var = 1.2345      #Variable floating number (numero de punto floatante) (float)\ncomplex_var = 123j      #Variable complex (numeros complejos) (complex)\n\nlist_var = [1, 2, 3, 4, 5]  #Variable list (list)\ntuple_var = (1, 2, 3, 4, 5) #Variable tupla (tuple)\ndict_var = {\n    \"marco\": \"polo\",\n    \"user\": \"macova96\",\n    \"language\": \"python\"\n}   #Variable dictionary (Conjunto de datos de clave y valor) (dict)\n\nbool_var = True #Variable booleana (datos de tipo True False) (bool)\n\n\nlanguage =\"Python\"\nprint(f\"¡Hola {language}!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/majinka10.py",
    "content": "\"\"\"\nHola, ¿cómo estás?\nhttps://www.python.org/\n\"\"\"\n# Este es otro tipo de comentario\n\n'''\nTambién se puede comentar con comillas simples\nen varias líneas\n'''\n\nvariable = int\nCONSTANTE = 'Python'\n\ntexto = 'Soy una cadena de texto'\nprint(type(texto))\nentero = 2024\nprint(type(entero))\nbooleano = True\nprint(type(booleano))\nflotante = 3.1416\nprint(type(flotante))\n\nprint(f'!Hola, {CONSTANTE}!')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/mallcca.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\"\"\"\n\n# Ejemplos de comentarios\n# https://www.python.org/\n\n\"\"\"\n    Comentario\n    en varias \n    líneas\n\"\"\"\n\n# Python no tiene sintaxis dedicada a constantes, pero como buena práctica se define en mayúsculas\nPI = 3.1415\n\n# Ejemplos de variables\nvar1 = 100\nvar2 = 'string'\nvar3 = 100.45\nvar4 = True\n\n# Imprimir un mensaje\ntemplate = '¡Hola, {0:s}!'\nlanguage = 'Python'\nmessage = template.format(language)\nprint(message)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/mamartinez14.py",
    "content": "#Comentario en python --> https://www.python.org/\n\n\"\"\"\nComentario en varias\nlineas\n\"\"\"\n\n'''\ncomentario con \ncomillas \nsimples en varias lineas\n'''\n\n#Variables \nmy_int = 88 # tipo entero\nmy_float = 10.8 # tipo decimal\nmy_boolean = True # tipo boleano\nmy_boolean = False # tipo boleano\nmy_string = \"Mi cadena de texto\" # tipo texto\nmy_string = 'Mi otra cadena de texto, pero con comillas simples' # tipo texto\n\nprint('Hi Python xd!')\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/manjaitan.py",
    "content": "\"\"\"\n/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n \n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n \n * - Crea una variable (y una constante si el lenguaje lo soporta).\n \n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n \n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\"\"\"\n \n# URL del sitio oficinal Python. \n# https://www.python.org/\n\n# Diferentes sintaxis para crear comentarios:\n# Comentario de única línea.\n\n# Comentario en bloque:\n\"\"\"\nEl texto incluido entre las tres comillas, es un texto comentario, y podemos incluir bloque de texto como utilidad para comentar nuestro código.\n\"\"\"\n\n# Crea una variable ( y una constante si el lenguaje lo soporta)\nvariable1=\"Esto es una variable\"\n\n# En python no existen como tal y para diferenciarlas tenemos que ponerlas en mayúsculas.\nCONSTANTE1=\"Esto es una conStante\"\n\n# Crea variables representando todos los tipos de datos primitivos\n# del lenguaje (cadenas de texto, enteros, booleanos...).\n\nvar_cadena1=\"Python\"\nvar_int=3\nvar_decimal=2.2\nvar_boolean=True\n\nprint (type(var_cadena1))\nprint (type(var_int))\nprint (type(var_decimal))\nprint (type(var_boolean))\n\n# Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\nprint (\"¡Hola, \" + var_cadena1 + \"!\")\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/manueldes27.py",
    "content": "# Sitio web oficial de Python: https://python.org\n\n# Para escribir comun comentario en una sola línea se utiliza # \n\n# Ejemplo:\n\n# Este es un ejemplo de un comentario en una sola línea\n\n# Para escribir un comentario en varias líneas se utiliza \"\"\" \"\"\" o ''' ''' escribiendose en medio de las comillas el comentario\n\n# Ejemplo:\n\n\"\"\"\nEste es un ejemplo\nde un comentario\nen varias líneas\n\"\"\"\n\n'''\nEste es un ejemplo \nde un comentario \nen varias líneas\n'''\n\n# Crea una variable\n\nmy_variable = \"Mi variable\"\n\n# Crea una costante \n\nMY_COSTANTE = \"MI COSTANTE\" # No es una costante como tal ya que se puede modificar en este lenguaje de programación.\n# Al ponerse en mayúsculas se diferencia de una variable dando a entender al programador que es una costante.\n\n# Tipos de datos primitivos\n\nmy_string = \"Esto es un string\"\nmy_int = 7 # Esto es un entero\nmy_float = 7.5 # Esto es un decimal\nmy_bool = True # Puede ser True o False\n\n# Imprimir saludo y el lenguaje de programación que se está usando\n\nprint(\"Hola, estás usando Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/manuelgomezg.py",
    "content": "# https://python.org\n# Esto es un comentario de una linea\n\n\"\"\"\nEsto es un comentario \nmultilinea\nen python\n\"\"\"\n\nmy_variable = \"Hola que tal\"\nmy_variable = \"Dale tu puedes\"\n\nMI_CONSTANTE = \"mi constante\" #por convencion\n\nmy_int = 20\nmy_float = 19.9\nmy_bool = True\nmy_boll = False\nmy_str = \"Cadena de texto\"\n\nprint (\"Hola, Phyton!\")\n\nprint (type(my_int))\nprint (type(my_float))\nprint (type(my_bool))\nprint (type(my_str))"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/marcelinoarias369.py",
    "content": "# https://www.python.org/\n\n# Esto es un comentario de una linea\n\n'''\nEsto es un\ncomentario de varias lineas\ncon comillas simples\n'''\n\n\"\"\"\nTambien podemos crear\ncomentarios de varias lineas\ncon comillas dobles\n\"\"\"\n\n#variable\nmy_variable = \"Hello World!!\"\n\n\n\"\"\"\nConstantes:\nSe usa la convención de nombrar con letras mayúsculas\npara indicar que estos valores no deben cambiar a lo \nlargo del programa.\n\"\"\"\nPI = 3.14159\nMAX_CONNECTIONS = 100\n\n#str\nprogramming_language = \"Python\"\n\n#int\nnum_negativo = -45\nnum = 33\n\n#float\nnota_final = 4.5\n\n#bool\nsoy_lindo = True\n\nprint (f\"¡Hola, {programming_language}\")\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/marcelosanchez166.py",
    "content": "# https://docs.python.org/3/\r\n\r\n# Comentario de una linea\r\n\r\n\"\"\"Comentarios de \r\nvarias lineas\"\"\"\r\n\r\nvariable = \"Soy una variable\"\r\nPI = 3.14159  # Las constantes se escriben con MAYUSCULAS\r\nGRAVITY = 9.8  # Otra constante\r\n\r\nvariable_string = \"string\"\r\nvariable_entero = 9\r\nvariable_float = 9.1\r\nvariable_boolean = True\r\n\r\n\r\nprint(\"¡Hola, [Python]!\")\r\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/marcoh2325.py",
    "content": "# https://www.python.org/\n# Se puede crear un comentario en una única línea utilizando el carácter almohadilla (hash, octothorphe o pound en inglés)\n\"Tambien podemos comentar por medio de un string que no se asigne a ninguna variable\"\n\"\"\"Aprovechando esta posibilidad, podemos comentar en varias líneas utilizando la sintaxis\npara escribir un string en varias lineas\"\"\"\n'Luego también se puede hacer lo mismo creando los strings con comillas simples'\n'''Estan son las diferentes posibilidades que tenemos de hacer comentarios en python'''\n\nla_respuesta_a_todo = 42\n\n\"\"\"No existe una forma sencilla de crear una constante en python, aunque se podría\nindicar a otros desarrolladores que se trata de una constante creando una variable escrita en mayúsculas\"\"\"\nLEY_DE_MURPHY = \"\"\"Dada una serie de eventos, todo lo que puede salir mal,\nsaldrá mal en el peor orden posible\"\"\"\n\nmedallas = None #none\nhablas_frances = False #boolean\nedad = 29 #int\nestatura = 1.74 #float\nnombre_completo = \"Marco Hernani\" #string\nposicion_mosquito_en_mi_habitacion = 1.4 +  1.7j #complex\nnombres_animales = [\"oso\", \"delfín\", \"panda\"] #list\nvocales = (\"a\", \"e\", \"i\", \"o\", \"u\") #tuple\nprimos_menores_10 = {2, 3, 5, 7} #set\nidentidades_superheroes = {\"Spiderman\": \"Peter Parker\", \"Batman\": \"Bruce Wayne\", \"Superman\": \"Clark Kent\", \"Pastelman\": \"Homer Simpson\"}\nprint(\"¡Hola, Python!\")\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/marcos0803.py",
    "content": "#Web oficial con la ducumentacion de pyhton https://www.python.org/ \n\n#Comentarios en python\n\n# Este es un comentario en una linea\n\n\"\"\"Este es un comentario en bloque.\"\"\"\n\n'''Tambien se pueden usar comillas simples para los cometarios en bloque'''\n\n#Variables y Constastantes\n\nvariable = 20\nCONSTANTE = 30 #Python no admite constantes pero por convencion se las puede definir con mayusculas para representarlas\n\n#Tipos de datos\n\n#Tipos numericos\nentero = 1 #Numeros enteros\npunto_flotante = 2.3 #Numeros de punto flotante\nde_numero_complejo = 1 + 2j #Los números complejos tienen una parte real y otra imaginaria y cada una de ellas se representa como un float.\n\n#Cadena de caracteres\ncaracteres = '3'\ncadenas  = \"cadena de caracteres\"\n#en cualquier caso se puede utilizar comillas simples o dobles\n\n#Booleanos\n\nmi_nombre_es_marcos = True\nmi_nombre_no_es_marcos = False\n\n#imprimiendo un saludo\n\nsaludo = \"Python\"\nprint(f\"Hola, {saludo}!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/mariovelascodev.py",
    "content": "#https://www.python.org/\n\n#Comentatio en una línea\n\"\"\"\nComentario en \nvarias líneas\n\"\"\"\n\n#Variables\nmy_variable = \"\"\nPI = 3.1415 #declaración de una constante, aunque no existen como tal\nvariable_str = \"Esto es un string\"\nvariable_int = 2\nvariable_booleana = True\nvariable_float = 12.0\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/maxiRica.py",
    "content": "# ejercicio realizado por Maxi Rica \n''' \nel ejercicio lo voy a realizar sobre\n    PYTHON \n'''\n\"\"\" \nhttps://www.python.org/ \n\"\"\"\n\n# como antes he dibujado tienes la opción de realizar un comentario en una línea con esta opción\n\"\"\" o tienes la opción de usar tres comillas o comillas dobles para poder realizar comentarios\nde varias líneas. Abres con las comillas, y finalizas el escrito con las comillas otra vez.\n\"\"\"\n\n\"\"\" \nEn Python las variables no son tipadas en la declaración, y no hay constantes. Aún así, por consenso, las variables que sean constantes se escriben en mayúscula\npara que se entienda que ese identificador no ha de ser usada como una variable\n\"\"\"\n\nvariable = true\nCONSTANTE = 10\n\n# tipos de datos primitivos\n\nboolean = true # es el tipo bool\nentero = 1 # es el tipo int\nflotante = 0.1 # es el tipo float\ntexto = \"tipo string\" # es el tipo str\nnull = none # es el tipo NoneType, en otros lenguajes en null\n\n# imprimir por pantalla \"hola mundo\"\n\nprint(\"¡hola Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/mendozalz.py",
    "content": "'''\nEJERCICIO:\n[X] Crea un comentario en el código y coloca la URL del sitio web oficial del\n    lenguaje de programación que has seleccionado.\n\n[X] Representa las diferentes sintaxis que existen de crear comentarios\n    en el lenguaje (en una línea, varias...).\n\n[X] Crea una variable (y una constante si el lenguaje lo soporta).\n\n[X] Crea variables representando todos los tipos de datos primitivos\n    del lenguaje (cadenas de texto, enteros, booleanos...).\n\n[X] Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\n\n'''\n\n\n# Pagina web de python - https://www.python.org/\n\n#--------------------------------------------------#\n\n## Comentarios en una Linea con Python\n\n# Esto es un comentario de una linea\n\n#--------------------------------------------------#\n\n## Comentarios en varias Lineas con Python\n\n\"\"\"\nEsto es un comentario\nde varia Lineas con comillas dobles\n\"\"\"\n\n'''\nEsto es un comentario\nde varia Lineas con comillas sencillas\n'''\n\n#--------------------------------------------------#\n\n## Variable\n\nmi_var = \"Esta es una variables\"\n\n\n## Constante según convención\n\nMI_VAR = \"Esta es una constante según la convención\"\n\n#--------------------------------------------------#\n\n## Datos primitivos y sus tipos\n\n### Entero o Int\n\nmi_int = 44\n\n### Float (datos flotantes o con decimales)\n\nmi_float = 3.14\n\n### Bool (booleanos)\n\nmi_bool_true = True\nmi_bool_false = False\n\n### String o Str\n\nmi_string = \"Esta es una cadena de texto\"\n\n#--------------------------------------------------#\n\n### Imprimiendo en la terminal\n\np = \"Python\"\n\nprint (f\"¡Hola, {p}!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/mensius87.py",
    "content": "\"\"\"\n * EJERCICIO:\n - Crea un comentario en el código y coloca la URL del sitio web oficial del\n    lenguaje de programación que has seleccionado.\n - Representa las diferentes sintaxis que existen de crear comentarios\n    en el lenguaje (en una línea, varias...).\n - Crea una variable (y una constante si el lenguaje lo soporta).\n - Crea variables representando todos los tipos de datos primitivos\n    del lenguaje (cadenas de texto, enteros, booleanos...).\n - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\"\"\"\n\n\n# Sitio oficial de Python: https://www.python.org/\n\n# Comentario de una línea\n\n\"\"\"\nEste es un comentario multilínea. Aunque Python no tiene una forma de generar este tipo de comentarios, si a una cadena\nde texto envuelta entre estas comillas triples no se le asigna una variable, Python la ignorará y servirá de comentario.\n\"\"\"\n\nvariable = \"Hola MoureDev\"\n\nCONSTANTE = 3,14 # en Python no hay constantes, pero por convención si la variable está en mayúsculas se tomará como tal\n\nentero = 20\n\nflotante = 1.4\n\ntexto = \"Python\"\n\nBooleano = True\n\n\nprint(f\"Hola {texto}\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/mhayhem.py",
    "content": "# @author: Mhayhem\n \n # - Crea un comentario en el código y coloca la URL del sitio web oficial del\n #   lenguaje de programación que has seleccionado.\n \n # lenguaje elegído python => https://www.python.org/downloads/\n\n # - Representa las diferentes sintaxis que existen de crear comentarios\n #   en el lenguaje (en una línea, varias...).\n \n# comentario de una sola linea\n\n\"\"\"comentario varias lineas\naqui puedes usar comillas dobles {\"} \no comillas simples {'}\"\"\"\n \n\n # - Crea una variable (y una constante si el lenguaje lo soporta).\n \nname = \"python\"\n \n\"\"\"en python no existen contastes como en otros leguajes, pero por convenio se suele usar letras mayusculas para indicar a otros \ndesarrolladores que esa variable no ha de cambiarse\n\"\"\"\nNO_CAMBIAR = \"Valor único\"\n\n # - Crea variables representando todos los tipos de datos primitivos\n #   del lenguaje (cadenas de texto, enteros, booleanos...).\n \nmy_string = f\"Hola, {name}!\"\nmy_int = 58\nmy_float = 2.34\nmy_bool = True\n \n # - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\nprint(my_string)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/mick2332-q.py",
    "content": "'''EJERCICIO:\n- Crea un comentario en el código y coloca la URL del sitio web oficial del\n    lenguaje de programación que has seleccionado.\n- Representa las diferentes sintaxis que existen de crear comentarios\n    en el lenguaje (en una línea, varias...).\n- Crea una variable (y una constante si el lenguaje lo soporta).\n- Crea variables representando todos los tipos de datos primitivos\n    del lenguaje (cadenas de texto, enteros, booleanos...).\n- Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"'''\n\n\n# www.python.org\n\n# Esto es un comentario de una sola linea, se realiza con \n\n#Esto es un comentraio multilinea\n#Puede escribirse en diferentes lineas\n\n'''Esto es un comentario multilinea\nPuede escribirse en diferentes lineas'''\n\"\"\"\nEsto es un comentario multilinea\nPuede escribirse en diferentes lineas\"\"\"\n\n# Tipos de datos primitivos\nCONSTANTE = \"esta es sólo la manera de escribir su nombre por convencion, Python\"\ncadena = \"esto es una string\"\nentero = 5\nflotante = 4.2\nbooleano = False\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/miguelex.py",
    "content": "# Documentación https://www.python.org/\n\n# Comentario de una línea\n\n\"\"\"\nComentario\nde varias\nlíneas\n\"\"\"\n\nlenguaje = \"Python\" \n\n# Python no tiene una forma para declarar constante. En su defecto,\n# se usa una convención de nombrar las constantes con mayúsculas.\n\nPI = 3.1416 \n\n# Tipos primitivos\nentero = 1\nflotante = 1.1\ncadena = \"Ejemplo de cadena\"\nbooleano = True\ncaracter = 'A'\nnulo = None\n\n# Imprimir por consola\nprint(f\"Hola {lenguaje}!!!\") \nprint(f\"\"\"Tipos primitivos:\n      Entero {entero} <= nombre de la clase: {entero.__class__.__name__}\n      Flotante {flotante} <= nombre de la clase: {flotante.__class__.__name__}\n      Cadena {cadena} <= nombre de la clase: {cadena.__class__.__name__}\n      Booleano {booleano} <= nombre de la clase: {booleano.__class__.__name__}\n      Caracter {caracter} <= nombre de la clase: {caracter.__class__.__name__}\n      Nulo {nulo} <= nombre de la clase: {nulo.__class__.__name__}\n      \"\"\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/miguezzb.py",
    "content": "# #00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n### Por: MiguelBlanco (miguezzb ON GitHub)\n\n## URL del sitio web oficial del lenguaje de programación que has seleccionado\n# https://www.python.org/\n\n# Definir una variable\nhola = \"Hola, mundo!\"\n\n## Definir una constante (por convención, en mayúsculas)\nPI = 3.14159\n\n## Tipos de datos primitivos en Python\nentero = 42                # int\nflotante = 3.14            # float\nbooleano = True            # bool\ncaracter = 'a'             # str (no hay tipo char, se usa str de un solo carácter)\ncadena = \"Hola\"            # str\nnulo = None                # NoneType\n\nprint('¡Hola, Python!')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/mikelm2020.py",
    "content": "# https://www.python.org/\n\n# Variable\nnumber = 100\n\n# Constantes\nPI = 3.1416\n\n# Variables\nname = \"Miguel Angel\" # Variable de cadena de texto\ndigit = 10 # Variable de tipo entero\nis_digit = True # Variable de tipo booleano\nmount = 1500.00 # Variable de tipo flotante\n\nprint(\"¡Hola, Python!\")\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/minn09.py",
    "content": "# https://www.python.org/\n\n# Comentario de una linea\n\n\"\"\"\nBloque de comentario\n\"\"\"\n\nvariable = \"Soy una variable\"\n\ntexto = \"Soy un texto\"\nentero = 10\nflotante = 4.2\nbooleano = True\ncomplejo = 4+4j\n\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/mjordanaam.py",
    "content": "'''\n/*\n* - Crea un comentario en el código y coloca la URL del sitio web oficial del\n*   lenguaje de programación que has seleccionado.\n* - Representa las diferentes sintaxis que existen de crear comentarios\n*   en el lenguaje (en una línea, varias...).\n* - Crea una variable (y una constante si el lenguaje lo soporta).\n* - Crea variables representando todos los tipos de datos primitivos\n*   del lenguaje (cadenas de texto, enteros, booleanos...).\n* - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n*\n* ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n* debemos comenzar por el principio.\n*/\n'''\n\n# https://www.python.org/\n\n# Single line comment\n\n\"\"\"\nBlock comment line1\nBlock comment line2\n\"\"\"\n\n# Variable\nmy_variable = 1\n\n# Constant\nMY_CONSTANT = 3.1415\n\n# Constant typed\nMY_CONSTANT_TYPED: int = 1\n\n# String\nmy_string = \"Hello World!\"\n\n# String typed\nmy_string_typed: str = \"Hello World!\"\n\n# Integer\nmy_integer = 1\n\n# Integer typed\nmy_integer_typed: int = 1\n\n# Float\nmy_float = 1.0\n\n# Float typed\nmy_float_typed: float = 1.0\n\n# Boolean\nmy_boolean = True\n\n# Boolean typed\nmy_boolean_typed: bool = True\n\n# List\nmy_list = [1, 2, 3]\n\n# List typed\nmy_list_typed: list = [1, 2, 3]\n\n# Tuple\nmy_tuple = (1, 2, 3)\n\n# Tuple typed\nmy_tuple_typed: tuple = (1, 2, 3)\n\n# Dictionary\nmy_dictionary = {\"key\": \"value\"}\n\n# Dictionary typed\nmy_dictionary_typed: dict = {\"key\": \"value\"}\n\n# Set\nmy_set = {1, 2, 3}\n\n# Set typed\nmy_set_typed: set = {1, 2, 3}\n\n\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/mmacalli.py",
    "content": "# https://www.python.org/\n\n# comentario de una linea\n\n\"\"\" \nEste es\nun comentario \nde mas de una \nlinea \n\n\"\"\"\n\n''' Esta tambien \nes un comentario \nde mas \nde una linea'''\n\nmy_variable = \"Mi variable\"\nmy_variable = \"Mi nueva varible\"\n\nMY_CONSTANT = \"mi constanta\" #por convencion\n\nmy_int = 1\nmy_float = 2.5\nmy_bool = True\nmy_bool = False\nmy_string = \"Cadena de texto\"\nmy_other_sting = 'otro tipo de cadena de texto'\n\nprint(\"Hola, Python\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/monicavaquerano.py",
    "content": "# Mónica Vaquerano\n# https://monicavaquerano.dev\n\n# EJERCICIO 00:\n# Crea un comentario en el código y coloca la URL del sitio web oficial del\n# lenguaje de programación que has seleccionado.\n\n# https://www.python.org/\n\n\n# Representa las diferentes sintaxis que existen de crear comentarios\n# en el lenguaje (en una línea, varias...).\n\n# Comentario de una línea\n\n\"\"\"\nComentario \nde varias \nlíneas usando\ncomillas simples\n\"\"\"\n\n\"\"\"\nComentario \nde varias \nlíneas usando\ncomillas dobles\n\"\"\"\n\n# Crea una variable (y una constante si el lenguaje lo soporta).\n\nvariable = \"Python\"\nCONSTANTE = 3.14159\n\n# Crea variables representando todos los tipos de datos primitivos\n# del lenguaje (cadenas de texto, enteros, booleanos...).\n\nstring = \"soy una string o cadena de caracteres\"\ninteger = 1\nfloat = 1.5\nbooleano = True\ntuple = (1, 2)\nlista = [1, 2, 3, 4, 5, 6]\nset = {\"Alice\", \"Bob\", \"Charlie\"}\ndiccionario = {\n    \"Alicia\": {\"edad\": 20, \"idioma\": \"español\"},\n    \"Bob\": {\"edad\": 25, \"idioma\": \"inglés\"},\n}\nnada = None\nrango = range(9)\ncomplejo = 1j\nset_congelado = frozenset({\"Alice\", \"Bob\", \"Charlie\"})\nbytes = b\"Hello\"\nbyteArray = bytearray(5)\nmemoryView = memoryview(bytes)\n\n\ntipos_de_datos = [\n    string,\n    integer,\n    float,\n    booleano,\n    tuple,\n    lista,\n    set,\n    set_congelado,\n    bytes,\n    byteArray,\n    diccionario,\n    nada,\n    rango,\n    complejo,\n    memoryView,\n]\n\nprint(\"\\tTipos de datos: \")\nfor dato in tipos_de_datos:\n    print(\"\\t\", type(dato))\nprint()\n\n\n#  Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nprint(f\"¡Hola, {variable}!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/monisstar.py",
    "content": "# https://www.python.org\n\n# Comentario en una linea mediante la almohadilla\n\n\"\"\"\nCon dobles comillas\npuedo hacer un comentario\nen varias líneas\n\"\"\"\n\n'''\nTambién se puede hacer\nun comentario en varías líneas\nmediante comillas simples\n'''\n\nvariable = 'Nueva variable'\n\n# Python no tiene constantes :)\n\nstring = 'Nueva cadena de texto' # variable de tipo cadena de texto\nmy_int = 10  # variable de tipo entero\nmy_float = 10.5  # variable de tipo flotante\nmy_bool = True  # variable de tipo booleano\nmy_bool1 = False\n\nprint('Hola, Python!')\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/mordevspt.py",
    "content": "'''\n* - Crea un comentario en el código y coloca la URL del sitio web oficial del\n*   lenguaje de programación que has seleccionado.\n'''\n# https://www.python.org/\n\n\n'''\n* - Representa las diferentes sintaxis que existen de crear comentarios\n*   en el lenguaje (en una línea, varias...).\n'''\n\n# Comentario de una sola línea\n\n'''\nComentarios con más de una línea:\nLínea 1\nLínea 2\n...\nLínea N\n'''\n\n\"\"\"\nComentarios con más de una línea 2:\nLínea 1\nLínea 2\n...\nLínea N\n\"\"\"\n\n'''\n* - Crea una variable (y una constante si el lenguaje lo soporta).\n'''\n# Constante, que no se soporta, pero por convención se deja en Mayúsculas\nPI = 3.14\n\n# Variable de tipo String\nnombreUsuaro = \"user1\"\n\n'''\n* - Crea variables representando todos los tipos de datos primitivos\n*   del lenguaje (cadenas de texto, enteros, booleanos...).\n'''\n\n# Integer\nnumero = 5\n# Float\nflotante = 3.14\n# Tuple\ntupla = (1,2,3,\"cuatro\",\"cinco\")\n# List\nlista = [1,2,3,\"cuatro\",\"cinco\"]\n# Set\nconjunto = {1,2,3,\"cuatro\",\"cinco\"}\n# Dictionary\ndiccionario = {\"primero\":\"Hola\", \"segundo\":\"Mundo\"}\n# Bolean\nestado = True\n# String\ncomentario = \"¡Hola Mundo!\"\n\n'''\n* - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n'''\nprint(\"¡Hola, Python! \\n\")\n\n'''\nImpresiión de las diferentes variables\n'''\nprint(f\"Constante: {PI} \\n\")\nprint(f\"String: {nombreUsuaro} \\n\")\nprint(f\"Integer: {numero} \\n\")\nprint(f\"Float: {flotante} \\n\")\nprint(f\"Tuple: {tupla} \\n\")\nprint(f\"List: {lista} \\n\")\nprint(f\"Set: {conjunto} \\n\")\nprint(f\"Dictionary: {diccionario} \\n\")\nprint(f\"Bolean: {estado} \\n\")\nprint(f\"String: {comentario} \\n\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/mouredev.py",
    "content": "# https://python.org\n\n# Comentario en una línea\n\n\"\"\"\nEsto también es\nun comentario\nen varias líneas\n\"\"\"\n\n'''\nEsto también es\nun comentario\nen varias líneas\n'''\n\nmy_variable = \"Mi variable\"\nmy_variable = \"Nuevo valor de mi variable\"\n\nMY_CONSTANT = \"Mi constante\"  # por convención\n\nmy_int = 1\nmy_float = 1.5\nmy_bool = True\nmy_bool = False\nmy_string = \"Mi cadena de texto\"\nmy_other_string = 'Mi otra cadena de texto'\n\nprint(\"¡Hola, Python!\")\n\nprint(type(my_int))\nprint(type(my_float))\nprint(type(my_bool))\nprint(type(my_string))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/mplatab.py",
    "content": "# https://www.python.org\n\n# Comentario en una linea\n\n\"\"\"\nEsto es un comentario\nde varias\nlineas\n\"\"\"\n\n'''\nEsto tambien es \nun comentariode \nvarias lineas\n'''\n\nmy_variable = \"Mi variable\"\n\n# Tipos de datos primitivos\nmy_int = 25 # Enteros representa numeros sin punto decimal\nmy_float = 1.80 # Flotantes representa números con punto decimal\nmy_bool = True or False # Booleanos representa valor verdaderos o falso\nmy_string = \"Cadena de texto\" # Cadenas de Texto representa secuencias de caracteres encerradas entre comillas 'simple' o \"dobles\"\nmy_none = None # NoneType representa ausencia de valor\n\n\nprint(\"Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/mrf1989.py",
    "content": "# Python: https://www.python.org/\n\n# Comentario de una línea\n\n# Comentario de varias\n# líneas, que será ignorado\n# en la ejecución ## del programa\n\n'''\nComentario de varias\nlíneas para documentación\n\nEsto será interpretado como documentación del programa\n'''\n\n# Declaración de variables...\nprogramming_lang = \"Python\"\n# ... porque Python no acepta constantes\n# pero se pueden \"crear\" con UPPER_SNAKE_CASE\nCONSTANT_VALUE = \"Retos de Programación\"\n\n# Tipos de datos primitivos\nstr = \"Esto es una cadena de texto\"\nconcat_str = \"Esta es una idea. \" 'Esta otra. ' \"Y otra.\"\ninteger_val: int = 1\nfloat_val: float = 2.5\nboolean_val: bool = True\n\nprint(concat_str)\nprint(f\"Hello, {programming_lang}!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/mrodara.py",
    "content": "# www.python.org\n\n'''\nEsto es un comentario\nde varias lineas en python\n'''\n\n\"\"\"\nEsto es otro comentario\n\nde varias lineas en python\n\"\"\"\n\nmy_var = \"Hola Mundo\"\n\nmy_int = 0\nmy_float = 0.0\nmy_bool = True\nmy_string = \"Soy una cadena de caracteres\"\n\n\nMY_CONSTANT = \"SALUDO\"\n\nprint('Hola Python')\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/mvidalb.py",
    "content": "# https://www.python.org/\n\n# Comment in one line\n\n'''\nComment in\nseveral lines\n'''\n\n\"\"\"\nThis is also\na comment in \nseveral lines\n\"\"\"\n\n# Variable\nmy_var = \"My variable\"\nmy_var = \"New assignment of my variable\"\n\n# Constant\nMY_CONSTANT = \"My constant\" # by convention\n\n# Text string\nmy_string = \"This is a string\"\n\n# Integer\nmy_integer = 7\n\n#Float\nmy_float = 7.5\n\n# Boolean\nmy_boolean = True\nmy_boolean = False\n\nprint(\"¡Hi, Python!\")\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/n-skot.py",
    "content": "#* EJERCICIO:\n\"\"\" * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: ¡Hola, [y el nombre de tu lenguaje]! \"\"\"\n # Este es un comentario\n\"\"\" Sitio oficial https://www.python.org/ \"\"\"\n\n# Variables\nx = 10\nnombre = \"Richard\"\n\n\"\"\"\" En Python, no hay un tipo específico llamado \"constante\". Sin embargo, por convención, si quieres declarar una variable cuyo valor no cambiará durante\nla ejecución del programa y quieres que otros programadores sepan que es una constante, puedes nombrarla con letras mayúsculas. \"\"\"\n\nPYTHON = 'Python'   # <= Constante\n\n# Datos primitivos\n\nstring = 'Esto es un string'\nnumero = 1120\nfloat = 12.5\nverdadero = True\n\n# Hola mundo\n\nprint('Hola', PYTHON, '!')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/nachodev7.py",
    "content": "# https://www.python.org/ \n\n# This is a comment of one line \n''' \n    This is a comment \n    whit many lines \n'''\n\"\"\"\n    This is also a comment\n    with many lines\n\"\"\"\n\nmy_variable = 'Python'\n\nMY_CONST = 'Constant'\n\n\nmy_int = 2 \nmy_float = 2.2 \nmy_bool = True \nmy_str = 'String'\n\nprint(\"Hello, Python!\")\n\nprint(type(my_int))\nprint(type(my_float))\nprint(type(my_bool))\nprint(type(my_str))"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/ndepaul82.py",
    "content": "# Lenguaje de programacion, Python, url: https://www.python.org\n\n# Diferentes formas de comentar:\n\n# Esto es un comentario\n''' Esto\n    es otra\n    forma de \n    comentario\n    '''\n\n\"\"\" Y \n    esto es\n    otra forma mas\n    de comentario\n    \"\"\"\n\n# Crear una variable y una constante:\n\nlenguaje = \"Python\"\nCONST = 3.141592\n\n\n# Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n\nstring = \"esto es una cadena\"\nentero = 1\nfloat = 3.14\nbool = True\nnada = None\n\n# Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nprint(f\"Hola, {lenguaje}!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/neslarra.py",
    "content": "\"\"\"\nÉsto es un comentario multilínea:\n\nEJERCICIO:\n - Crea un comentario en el código y coloca la URL del sitio web oficial del\n   lenguaje de programación que has seleccionado.\n - Representa las diferentes sintaxis que existen de crear comentarios\n   en el lenguaje (en una línea, varias...).\n - Crea una variable (y una constante si el lenguaje lo soporta).\n - Crea variables representando todos los tipos de datos primitivos\n   del lenguaje (cadenas de texto, enteros, booleanos...).\n - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n debemos comenzar por el principio.\n\"\"\"\n\n# Ésto es un cometario en una línea => Aprende sobre Python en su web oficial: https://www.python.org/\n\n# las constantes en Python son variables, que por convención, se crean en MAYÚSCULA y se asume NO alterarlas.\nCONSTANTE_URL_LENGUAGE: str = \"https://www.python.org/\"\n\n# Tipos primitivos\nentero: int = 1\nflotante: float = 1.1\ncadena: str = \"Python\"\nbooleano: bool = True\n\nprint(f\"\"\"Tipos primitivos:\n      Entero {entero} <= nombre de la clase: {entero.__class__.__name__}\n      Flotante {flotante} <= nombre de la clase: {flotante.__class__.__name__}\n      Cadena {cadena} <= nombre de la clase: {cadena.__class__.__name__}\n      Booleano {booleano} <= nombre de la clase: {booleano.__class__.__name__}\n      \"\"\")\n\nprint(f\"Hola {cadena}!!!\")   # Ah, también puedo comentar al margen de la instrucción.\nprint(f\"Disponible en {CONSTANTE_URL_LENGUAGE}\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/nevaito.py",
    "content": "# https://python.org\n\n# esto es un comentario en una linea\n\"\"\"\nEsto es un comentario\nen varias lineas\nentre comillas dobles\n\"\"\"\n'''\nEsto es un comentario\nen varias lineas\nentre comillas simples\n'''\n\nmy_variable = \"Mi variable\"\nmy_variable = \"Nuevo valor de mi variable\"\n\nMY_CONSTANT = \"No es una constante pero estando en mayusculas se entiende que si\" # por conveccion\n\nmy_int:int = 1\nmy_float:float = 1.5\nmy_bool:bool = True\nmy_bool = False\nmy_string:str = \"Mi cadena de texto\"\nmy_other_string = 'Mi cadena de texto'\n\nprint(\"¡Hola, Python!\")\n\nprint(type(my_int))\nprint(type(my_bool))\nprint(type(my_float))\nprint(type(my_string))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/nikorasu-d.py",
    "content": "# https://www.python.org/\n\n'''\n\nEsto es un comentario multiple\n\n'''\n\n\n# Variable en Python:\n\nx = 1\n\n# Constante en Python:\n\ntupla = (1,2,3,4,5,6) # Las tuplas se pueden considerar como una constante por que son inmutables a diferencia de los array\n\n\n#Tipos Primitivos:\n\nentero = 1\nflotante = 0.1\nstring = 'Hola Mundo'\nbooleano = True\nnone = None\n\nprint ('Hola, Python')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/njaimev.py",
    "content": "# https://www.pythong.org\n\n\"\"\"\nTambién se pueden\nescribir comentarios\nen varias líneas \nusando comillas\n\"\"\"\n\n# Creación de variables\nx = 20\n\n# No existe una palabra clave para crear una constante, pero en general\n# en python el nombre de la variable se ponga en mayusculas\n\nCONSTANTE = 23\n\n# También se les puede asignar un nombre\nvariable_numero = 10\n\n\n# En python no es necesario declarar si una variable es int, float o string ya \n# que lo reconoce solo\ninteger = 10\nfloat = 3.4\nstring = \"Hola\"\nboolean = True\nboolean = False\n\n# Se puede hacer una lista, tanto de numeros como int\nlista_numeros = [1, 4, 8 ,10, 15]\nlista_nombres = [\"Jose\", \"Maria\", \"Alfredo\", \"Sebastian\", \"Antonia\"]\n\nprint(\"Hola, Python!\")\n\n# En python para saber el tipo de dato se utiliza la función type\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/nlarrea.py",
    "content": "\"\"\"\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n\"\"\"\n\n# Documentación Python: https://www.python.org/\n\n\n# Comentario de una línea\n\n\"\"\" \nComentario\nde varias\nlíneas\n\"\"\"\n\n\n# Variables y constantes\nmy_variable = \"Hello there!\"\n# No existen constantes, pero se llegó a convención de que se usaran MAYÚSCULAS\nMY_CONSTANT = \"Python\"\n\n\n# Tipos de datos\nmy_str = \"This is a string\"\nentero = 7\ndecimal = 3.14\ncomplejo = 3j + 1\nbooleano = True\nlista = [\"foo\", 15, False, [1, 2, 3]]\ntuple = (\"foo\", 15, False, [1, 2, 3])\nmy_set = {\"foo\", 15, False}\ndiccionario = {\n    \"name\": \"Naia\",\n    \"age\": 25\n}\nmy_none = None\n\n\n# Imprimir por consola\nprint(\"¡Hola Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/noaregui.py",
    "content": "# URL Python\n#  https://python.org\n\n\n# Representa diferentes sintaxis que existen de crear comentarios en Python\n\n# Comentario en una línea\n\n\"\"\"\nComentario en varias \nlíneas con comillas\ndobles.\n\"\"\"\n\n'''\nComentario en varias \nlíneas con comillas\nsimples.\n'''\n\n# Crear variable y constante\nmi_variable = \"¡Hola!\"\nmi_constante = \"¿Cómov vas?\"\n\n# Tipos de datos\nnumero_int = 4\nnumero_float = 2.0\nbooleano_true = True\nbooleano_false = False\nmi_string = \"Soy un string\"\n\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/nox456.py",
    "content": "# https://www.python.org\n\n# Comentario de una línea\n\nvariable = \"hola\"\n\ntexto = \"hola mundo\"\nnumero = 19\nbooleano = True\n\nprint(\"Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/nwpablodeveloper.py",
    "content": "# https://www.python.org/\n\n# Esto es un comentario de 1 sola línea\n\n\"\"\"\n    Con triple comillas\n    Esto es\n    un comentario\n    de varias \n    lineas\n\"\"\"\n\n'''\n    También podemnos\n    usar comillas \n    simples para\n    varias lineas\n\n    Python usa sintaxis de Snake_Case\n'''\n\nmi_variable_string = \"Esto es una variables\"\nmi_variable_string = \"ahora tiene nuevo valor\"\n\n# python no tiene constantes\n'''\n    En python no existen las constantes, \n    todas son variables, pero podemos hacerlo\n    de la sig. manera\n    la declaramos con mayusculas\n'''\n\nMY_CONSTANT = \"Esto va hacer mi constante\" # Pero la pudo modificar\n\n\n# Tipos de datos primitivos\n\n# Tipo entero\nmy_int = 1\n\n# Tipo decimal\nmy_float = 1.72\n\n# Tipo Boolean\nmy_bool = True\nmy_bool = False\n\n# Tipo String\nmy_str = \"Cadena de texto\"\nmy_str = 'Cadena de texto con comillas simples'\n\n# Imprimir texto por consola\nprint(\"¡Hola, Python!\")\n\n# Comprobar el tipo de dato que representamos en las variables\n\nprint(type(my_int))\nprint(type(my_bool))\nprint(type(my_float))\nprint(type(my_str))\nprint(type(MY_CONSTANT))"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/obed-tc.py",
    "content": "\n\n# https://www.python.org/\n\n# Comentario en una linea\n\n'''\nComentarios usando comilla simple\nen varias lineas\n'''\n\n\"\"\"\nComentario usando doble comillas\nen varias lineas\n\"\"\"\n\n\nvariable=\"Hola mundo\"\nCONSTANTE=\"Hola mundo\"\n\nbooleano=True\nflotante=1.23\nentero=77\nstring=\"Cadena de texto\"\nlista=[\"es\",\"una\",\"lista\"]\ntupla = (3,2,1)\nconjunto = {2,3,1,2}\ndiccionario = {\"clave\": \"valor\", \"clave2\": \"valor2\"}\n\n\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/omar8102.py",
    "content": "# https://www.python.org/\n\n# Comentario de una linea\n\n'''\nComentario\nde\nmultiple lineas\n'''\n\nmi_variable = \"Hola Mundo\"\nMI_CONSTANTE = \"HOLA\"\n\nmi_cadena = \"Hola\"\nmi_booleano = True\nmi_entero = 10\nmi_flotante = 10.5\nmi_lista = [1,2,3,4,5]\nmi_tupla = (1,2,3,4,5)\nmi_diccionario = {\n    \"nombre\": \"Hernan\",\n}\n\nprint(f'¡Hola, {MI_CONSTANTE}!')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/oniricoh.py",
    "content": "\"\"\"\nEL lenguaje que estoy utilizando es python y su web es:\nhttps://www.python.org/\n\n\"\"\"\n#Aqui deberia empezar mi codigo\n\nvariable = \"Esta es una variable\"\nint = 5\nfloat = 0.5\nboolean = True\nstring = \"Cadena de texto\"\n\nprint(\"!Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/oriaj3.py",
    "content": "# Web oficial de Python: https://www.python.org/\n# Web para aprender Python: https://www.learnpython.org/es/\n\n#Comentario de una sola linea\n\n\"\"\"\nComentario de varias lineas\n\"\"\"\n\n#Variables\n#Una variable es un contenedor de informacion\nvariable = \"Hola Mundo\"\nvariable = 10\n\n#Constante \n#Es un contenedor de informacion que no puede cambiar su valor, en Python no existen las constantes, pero se llego a una convencion de que se usaran mayusculas para identificarlas\nPI = 3.1416\n\n#Variables de todos los tipos de datos primitivos\ncadena = \"Hola soy una cadena de texto\"\nentero = 99\nflotante = 4.2\nbooleano = True\n\n#Variables de todos los tipos de datos complejos o estructurados\nlista = [10,20,30,40,50]\ntupla = (100,200,300,400,500)\nmy_set = {\"Hola\", \"Mundo\", \"!\"}\ndiccionario = {\n    \"nombre\":\"Victor\",\n    \"apellido\":\"Robles\",\n    \"curso\":\"Master en Python\"\n}\nrango = range(9)\ncomplejo = 7j + 3\n\n#Byte \n#Es un tipo de dato que se utiliza para trabajar con datos binarios\ndato_byte = b\"Probando\"\ndato_normal = \"Probando\"\n\n#Imprimir por consola\nprint(f\"La variable declarada con byte es: {dato_byte}\")\nprint(f\"La variable declarada normal es: {dato_normal}\")\nprint(f\"El primer caracter del byte es: {dato_byte[0]}\")\nprint(f\"El primer caracter del normal es: {dato_normal[0]}\")\n\n#No se puede modicar dato_byte\ntry:\n    dato_byte[0]=\"p\"\nexcept TypeError as e:\n    #Captura el error y lo muestra\n    print(f\"Error: {e}\")\n \nprint(f\"La variable declarada con byte no se puede modificar individualmente {dato_byte}\")\n\n#Imprimir hola mundo\nprint(f\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/oscargeovannyrincon.py",
    "content": "#   https://www.python.org/doc/     #\n\n#   comentario de una linea     #\n\"\"\"comentario de varias\nlineas con doble comilla\"\"\"\n'''comentario de varias\nlineas con comilla simple'''\n\n\n\nprint('RETO_01')\n\nmy_variable=\"Mi variable\"\nMY_CONSTANT=\"MI CONSTANTE\"\n\nprint(my_variable,'\\t',type(my_variable))\nprint(MY_CONSTANT,'\\t',type(MY_CONSTANT))\n\n\nmy_integer=123\nmy_float=123.456\nmy_string='hola'+'python'\nmy_boolean=True\nprint(my_integer,'\\t',type(my_integer))\nprint(my_float,'\\t',type(my_float))\nprint(my_string,'\\t',type(my_string))\nprint(my_boolean,'\\t',type(my_boolean))\nprint(\"Este el primer reto y sus impresiones entero {}, flotante {}, string {} y boolean {}\".format(my_integer, my_float, my_string, my_boolean))\n\nprint('FIN DEL RETO')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/oscarhub90.py",
    "content": "\n# https://www.python.org/\n\n\"\"\"\nEste es un comentario \nde varias líneas\n\"\"\"\n\n'''\nEste también funciona\nlo importante es que hayan\n3 comillas\n'''\n\n# 3. Crea una variable (y una constante si el lenguaje lo soporta).\n\nmy_name = \"Oscar C\"\n\n# Python no tiene declaración explícita de constantes, sin embargo, por convención se declaran en mayúscula las vaiables que no se deben editar.\n\nCONSTANT_PI = 3.1416\n\n# 4. Crea variables representando todos los tipos de datos primitivos\n\nvar_int = 33\nvar_float = 3.14\nvar_string = 'hello'\nvar_boolean = True\nvar_boolean = False\n\n\n# 5. Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\nprint (\"¡Hola, Phyton!\")\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/othamae.py",
    "content": "\"\"\"\n- Crea un comentario en el código y coloca la URL del sitio web oficial del\n   lenguaje de programación que has seleccionado.\n- Representa las diferentes sintaxis que existen de crear comentarios\n   en el lenguaje (en una línea, varias...).\n- Crea una variable (y una constante si el lenguaje lo soporta).\n- Crea variables representando todos los tipos de datos primitivos\n   del lenguaje (cadenas de texto, enteros, booleanos...).\n- Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\"\"\"\n\n# https://www.python.org/\n\n# Comment in one line\n\n\n\"\"\"\n    Comment \n    in\n    multiple\n    lines\n\"\"\"\n\n'''\n    Also comment\n    in multiple\n    lines\n'''\n\nCONSTANT = \"this is a constant\"\nvariable = \"this is a variable\"\n\n# PRIMITIVE TYPES:\nstring: str = \"this is a string\"\ninteger:int = 1\nfloat:float = 1.2\nboolean:bool = True\nnulo: None = None\n\n# Print in terminal\nprint(\"Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/owen-ian.py",
    "content": "# URL del sitio web oficial de Python: https://www.python.org/\n\n# La amohadilla nos permite escribir un comentario de una sola línea\n\n\"\"\"\nLas comillas dobles nos permiten \nescribir un comentario de varias líneas\n\"\"\"\n\n'''\nLas comillas simples tambien nos permiten \nescribir un comentario de varias líneas\n'''\n\n# Variable\nmy_variable = \"Una variable en Python\"\n\n# Constante\nMY_CONSTANTE = \"Una constante en Python\" # Aclaracion, al parecer la gente escribe sus constantes en MAYUSCULAS\n\nmy_int = 1\nmy_float = 1.5\nmy_bool = True\nmy_bool = False\nmy_string = \"Cadena de texto\"\nmy_other_string = 'Otra cadena de texto'\n\n# Imprimir por terminal\nprint(\"¡Hola, Python!\")\n\nprint(type(my_int))\nprint(type(my_float))\nprint(type(my_bool))\nprint(type(my_string))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/oxtornado.py",
    "content": "# https://www.python.org/\n\n# comments conventions:\n# \n# this way\n\n\"\"\"\nor this way \n\"\"\" \n\nvariable = 123\nCONSTANTE = \"i'm a constant\"\n\n# primitive variables\n\nstring_variable = \"i'm a string\"\nboolean_variable = False\ninteger_variable = 25\nfloat_variable = 12.12\n\nprint('¡Hola, python! hope we get along')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/pabloche73.py",
    "content": "### http:\\\\python.org ###\r\n\r\n# Esta es una de las formas de comentar en Python\r\n# Podemos usar el símbolo numeral (#) para comentar una sola línea\r\n# Podemos usar tres comillas dobles para comentar varias líneas\r\n\r\n\"\"\"\r\nEste es un comentario multilínea\r\n¿Se nota?¿No?\r\nUa línea mas.\r\n\"\"\"\r\n\r\n# Podemos usar comillas simples tambien en comentarios multilínea\r\n\r\n'''\r\nEste\r\ntambién\r\nes un\r\ncomntario multilinea\r\n'''\r\n\r\n# Tipos de Variables\r\n\r\nmy_str = \"Hola, mundo!\" # String\r\nmy_int = 52 # Integer\r\nmy_float = 1.80 # Float\r\nmy_bool = True # Boolean\r\nmy_list = [35, 24, 62, 52, 30, 30, 17] # List\r\nmy_tuple = (52, 1.80, \"Pablo\", \"Demonte\", \"Pablo\") # Tupla\r\nmy_set = {\"Pablo\", \"Demonte\", 52} # Set\r\nmy_dict = {\"Nombre\": \"Pablo\", \"Apellido\": \"Demonte\", \"Edad\": 52, 1: \"Python\"} # Dictionario\r\n\r\n# Para saber el tipo de variable podemos usar la funcion type()\r\nprint(type(my_str))\r\nprint(type(my_int))\r\nprint(type(my_float))\r\nprint(type(my_bool))\r\n\r\n# Como en Python las constantes no existen como tal, se usa la convención de escribir las variables en mayúsculas\r\nMY_CONST = \"Soy una constante\" # O al menos eso intento\r\n\r\nmy_str = \"Hola, Python!\"\r\nprint(my_str)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/pablosalme.py",
    "content": "'''/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */'''\n\n#https://www.python.org/\n\n#comentario en un linea\n''' comentario\nen\nvarias\nlineas '''\n\nfirst_var = 'Mi primera variable'\nFIRST_CONSTANT = 'Mi primera constante'\n\n#numeric\nentero = 10\nvar_float = 1.1123\n#sequences\nvar_list = [\"hola\", \"esto\", \"es\", \"una\", \"lista\"]\nvar_tuple = (\"esto\", \"es\", \"una\", \"tupla\")\nvar_range = range(5)\n#maps\nvar_dict = {\"clave\" : \"valor\", \"en\" : \"dicccionario\"}\n#str\nvar_text = 'variable tipo texto'\n#bools\nvar_bool = True\n#binary\nvar_binary = b\"Esto es texto en binario\"\n\nprint(\"Hola Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/pakiuh.py",
    "content": "# Sitio web oficial de Python: https://www.python.org/\r\n# Esto es un comentario en una línea\r\n\r\n\"\"\"\r\nEsto es un comentario\r\nen varias líneas\r\n\"\"\"\r\n\r\n'''\r\nEsto también es un comentario\r\nen varias líneas\r\n'''\r\n\r\nCONSTANTE = 10\r\nvariable = \"Soy una Variable\"\r\n\r\n# Tipos de datos primitivos en Python\r\n\r\n# Entero\r\nentero = 10\r\n\r\n# Flotante\r\nflotante = 3.14\r\n\r\n# Cadena de caracteres\r\ncadena = \"Hola, mundo!\"\r\n\r\n# Booleano\r\nbooleano = True\r\n\r\n# Lista\r\nlista = [1, 2, 3, 4, 5]\r\n\r\n# Tupla\r\ntupla = (1, 2, 3, 4, 5)\r\n\r\n# Conjunto\r\nconjunto = {1, 2, 3, 4, 5}\r\n\r\n# Diccionario\r\ndiccionario = {\"clave1\": \"valor1\", \"clave2\": \"valor2\"}\r\n\r\n# Imprime por terminal el texto: \"¡Hola, Python!\"\r\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/pakomor.py",
    "content": "# https://www.python.org/\n\n\" Aquí un comentario en una sola línea \"\n\n\"\"\" \nAquí un comentario en varías líeas\ninsertando el simbolo de comillas \n3 veces \n\n\"\"\"\n\n# Variables y Constantes\n\nnombre_variable = \"fran\"\n\nPI = 3.1416  # Es una constante\n\nprint(nombre_variable, PI)\n\n# Datos primitivos\n\n# String\n\nnombre = \"fran\"\nlenguaje = \"python\"\n\nprint(type(nombre and lenguaje))\n\n# Números enteros\n\nedad = 39\nanyo = 1984\n\nprint(type(edad and anyo))\n\n# Números flotantes\n\npeso = 74.600\ndolar = 1.10\n\nprint(type(peso and dolar))\n\n# Boolean\n\ntengo_frio = True\ntengo_calor = False\n\nprint(type(tengo_frio and tengo_calor))\n\n# Imprimir por pantalla\n\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/pandawanGT.py",
    "content": "# https://python.org\n\n# Comentario en una línea\n\n\"\"\"\nEsto también es\nun comentario\nen varias líneas\n\"\"\"\n\n'''\nEsto también es\nun comentario\nen varias líneas\n'''\n\nmy_variable = \"Mi variable\"\nmy_variable = \"Nuevo valor de mi variable\"\n\nMY_CONSTANT = \"Mi constante\"  # por convención\n\nmy_int = 1\nmy_float = 1.5\nmy_bool = True\nmy_bool = False\nmy_string = \"Mi cadena de texto\"\nmy_other_string = 'Mi otra cadena de texto'\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/pcosin.py",
    "content": "# Sitio web oficial de Python: https://www.python.org/\n\n# Comentario de una sóla línea\n\n\"\"\"\nComentario de varias líneas\ncon comillas\ndobles\n\n\"\"\"\n\n'''\n\nComentario en \nvarias \nlíneas con comillas simples\n\n'''\n\n# Variable\n\nnombre_completo = \"Pablo Cosin\"\n\n# Constante: convención escrita en mayúscula\n\nIDENTIFICADOR = 98887366\n\n# Primitivos\n\n# Cadena de texto\nvar_string = \"Una cadena de texto\"\n\n# Número entero\nvar_int = 87\n\n# Número decimal\nvar_float = 23.3\n\n# Boolean\nvar_bool = True\n\n# Imprimir por consola\n\nvar_lenguaje = \"Python\"\n\nprint(f\"¡Hola,{var_lenguaje}!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/pedro-blasco.py",
    "content": "# https://python.org/\n\n# Comentario en una sola Linea\n'''\nComentario en varias Lineas\n'''\n\"\"\"\nComentario en varias Lineas Tambien\n\"\"\"\nvariable = \"Hola Mundo\" # \"Hola Mundo\" es un string o cadena de texto\nint = 1 # 1 es un numero entero\nfloat = 1.5 # 1.5 es un numero decimal\nboolean = True # 2 valores posibles: True o False\nstring = \"Esto es un string\" # Un string es una cadena de texto\n\nprint(\"Hola, Python!\") # Imprime en consola el mensaje \"Hola, Python!\"\nprint(\"Comenzare a imprimir las distintas variables que he creado\")\n\nprint(variable) # Imprime en consola el valor de la variable \"variable\"\nprint(int) # Imprime en consola el valor de la variable \"int\"\nprint(float) # Imprime en consola el valor de la variable \"float\"\nprint(boolean) # Imprime en consola el valor de la variable \"boolean\"\nprint(string) # Imprime en consola el valor de la variable \"string\""
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/pedroomar23 2.py",
    "content": "# Este es el sitio web del lenguaje de programación Python https://python.org\n\n# Esto es un comentario en linea \n\n'''\nAqui puedes poner un comatario \nde varias lineas \n'''\n\n\"\"\"\nEsto tambien es una comentario \nde varias lineas\n\"\"\"\n\n# Aquí tenemos un ejemplo de variable \nmy_variable = \"Esta es mi variable\" \n\n# Aquí vemos como cambia \nmy_variable = \"Esta variable tiene un nuevo\" \n\n\n# Aqui tenemos un ejemplo de una constante \nmy_constant = \"Esto es una constante\" \n\n# Aquí tenemos un valor de tipo string o cadena de texto \nmy_string = \"Esto es un String\"\n\n# Aqui tenemos un valor de tipo entero \nmy_int = 1 \n\n# Aqui tenemos un valor de float \nmy_float = 1.5 \n\n# Aqui tenemos valores de tipos boleanos (true or false)\nmy_bool = True \nmy_bool = False \n\n# Imprimir en la consola \nprint(\"Hola, estoy aprendiendo Python\") \nprint(type(my_variable))\nprint(type(my_variable))\nprint(type(my_string))\nprint(type(my_string))\nprint(type(my_int))\nprint(type(my_float))\nprint(type(my_bool))\nprint(type(my_bool))\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/pepitoladino.py",
    "content": "\"\"\"\nCreated on Mon Nov 18 22:16:07 2024\n\n@author: Diego Ladino\n\"\"\"\n\n# https://www.python.org/\n\n#Esta es otra forma de crear comentarios en lenguaje python\n\"\"\" Esta es otra forma de crear comentarios en lenguaje python,\nse llama comentario de varias lineas \"\"\"\n\n#asignando valor a una variable\na = 1\n\n#asignando valor a una contante\n#Python no usa constantes, sin embargo en la comunidad se usa mayusculas para declarar un valor constante\nPI=3.1416\n\n#Datos primitivos\nnuumero_entero = int(1)\nnumero_flotante = float(1.1)\ncadena_texto = str(\"texto\")\nboleano = bool(True)\nboleano = bool(False)\n\n\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/perezfacundo.py",
    "content": "# https://www.python.org/\n\n# comentario de una sola linea\n\"\"\"comentario de una sola linea\"\"\"\n\n# comentario\n# multi\n# linea\n\"\"\"comentario\nmulti\nlinea\"\"\"\n\nyear = 2026\n\n# Variables de tipo primitivo\ntexto = \"cadena de texto\"\nentero = 3\ndecimal = 2.3\nbooleano = True\nnone_type = None\n\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/perla-zg.py",
    "content": "#https://www.python.org/\n\n#comentario de una linea\n \n\"\"\"\ncomentario\nde varias \nlíneas\n\"\"\"\n\nvariable = 1\nCONSTANTE = 2\n\nstring = \"cadena de texto\"\nint = 1\nfloat = 2.1\nbool = (False, True)\ncomplex = 1 + 3j\nbytes = b'\\x00\\x01\\x02\\x03'\nbytearray = bytearray(b'\\x00\\x01\\x02\\x03')\nnonetype = None\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/pguillo02.py",
    "content": "#Python es un lenguaje de programación interpretado, podras encontrar su página web oficial en la siguiente url: https://es.python.org/\n\n#Python es un lenguaje muy poco tipado en el cual no hay que indicar el tipo de una variable al declararla\n\nvariable = \"Mi primera variable\" #Esta variable se declara directamente, el interprete determinará que es de tipo String\n\n#En python existen 5 tipos de datos básicos, enteros, flotantes, booleanos, strings y variables nulas\n#Todas se declaran de la misma manera\n\ninteger = 12\nstring = \"Hola\"\nbooleana = True\nFlotantes = 12.34\nNulas = None\n\n#Constantes\n\nCONST = 23\n\n#Se pueden mostrar elementos por pantalla mediante print()\n\nprint(\"Hola Python\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/pipngpop.py",
    "content": "# https://es.python.org/\n\n# comentario en una linea\n\n\"\"\"\ncomentario en \nvarias\nlineas\n\"\"\"\n\n'''\notro comentario en \nvarias lines\n'''\n###ELEMENTOS PRIMITIVOS\n\n# crear una variable\nmy_variable = \"Mi variable\"\nmy_variable = \"Nuevo valor de mi variable\"\n\n# EN PYTHON NO HAY CONSTANTES\nMY_CONSTANT = \"Mi constante\"\n\nmy_int = 1 #numeros enteros\nmy_float = 1.5 #numeros decimales\nmy_bool = True\nmy_bool = False\nmy_string = \"Cadena de texto\"\nmy_other_string = \"Otra cadena de texto\"\n\nprint(\"¡¡¡Hola, Python!!!\")\nprint(type(my_float))\nprint(type(my_bool))\nprint(type(my_int))\nprint(type(my_string))\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/pirrin22.py",
    "content": "# Esto es un comentario de una sola línea. https://www.python.org/\n\n\"\"\"\nEsto es un comentario\nde varias líneas.\n\"\"\"\n\n'''\nEsto es otro comentario\nde varias líneas.\n'''\n\nmyvar = \"Hola Mundo!\"\n\nnumero_entero = 10\nnumero_flotante = 10.5\nnumero_complejo = 1j\ncadena = \"Hola\"\nbooleano = True\n\n\nprint('Hola Python!')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/pol-fradera.py",
    "content": "# URL del sitio web oficial de Python: https://www.python.org/\n\n# Comentario de una línea\n\n\"\"\"\nComentario \nde \nvarias \nlíneas\n\"\"\"\n\n# Crear una variable\nvar = 1\n\n# Crear una consante (es simplemente una convención)\nCONSTANTE = 'Constante'\n\n# Crear variables representando todos los tipos de datos primitivos\ncadena_de_texto = 'Hola'  # str\nnumero_entero = 42        # int\nnumero_decimal = 3.14     # float\nbooleano = True           # bool\nindefinido = None         # NoneType\n\n# Imprimir por terminal el texto: \"¡Hola, Python!\"\nprint('¡Hola, Python!')\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/pushodev.py",
    "content": "# solución del Reto 00\r\n# Pushodev\r\n# https://github.com/pushodev\r\n\r\nprint(\"solición al problema: #00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\")\r\n\r\n\r\n# Lengueaje utilizado PYTHON\r\n# Sitio web oficial de Python: https://www.python.org/\r\n\r\n# Este es un comentario en una línea con este lenguaje\r\n\r\n\"\"\"\r\nEste es un comentario de múltiples líneas en Python\r\nOrden del ejercicio:\r\n\r\n ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\r\n - Recuerda que todas las instrucciones de participación están en el\r\n   repositorio de GitHub.\r\n\r\n Lo primero... ¿Ya has elegido un lenguaje?\r\n - No todos son iguales, pero sus fundamentos suelen ser comunes.\r\n - Este primer reto te servirá para familiarizarte con la forma de participar\r\n   enviando tus propias soluciones.\r\n\r\n EJERCICIO:\r\n - Crea un comentario en el código y coloca la URL del sitio web oficial del\r\n   lenguaje de programación que has seleccionado.\r\n - Representa las diferentes sintaxis que existen de crear comentarios\r\n   en el lenguaje (en una línea, varias...).\r\n - Crea una variable (y una constante si el lenguaje lo soporta).\r\n - Crea variables representando todos los tipos de datos primitivos\r\n   del lenguaje (cadenas de texto, enteros, booleanos...).\r\n   debemos comenzar por el principio.\r\n- Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\r\n\r\n ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\r\n\r\n\"\"\"\r\n# Mi variable\r\nvariable_uno = 42\r\n\r\n# Constante\r\nCONST = \"Hola\"\r\n\r\n\r\ncadena_texto = \"Hola, mundo!\"\r\nentero = 42\r\nflotante = 3.14\r\nbooleano = True\r\n\r\nprint(\"¡Hola, Mundo!\")\r\nprint(\"Creado por Luis Alberto Guisado\")\r\n\r\n\r\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/pyramsd.py",
    "content": "# https://www.python.org/\n\n# Sintaxi de comentario uno\n''' Sintaxi de \ncomentario dos '''\n\n# variables\nvar_1 = 1\n# constante en python en con mayúsculas\nCONSTANTE_PI = 3.14\n\n# datos\nvar_int = 12\nvar_float = 12.5\nvar_str = \"python\"\nvar_boolean = True\nvar_complex = 4j + 5\nvar_lista = [1,2,3,4,5,6]\nvar_tupla = (7,8,9,10)\nvar_set = {11,12,13,14,15}\nvar_dict = {0:'zanahoria', 1:'papas', 2:'pollo'}\n\n# imporimir\nprint('¡Hola python!')\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/quejuan52.py",
    "content": "#EJERCICIO:\n # -Crea un comentario en el código y coloca la URL del sitio web oficial del\n # -lenguaje de programación que has seleccionado.\n\n            # URL: https://www.python.org/\n\n# Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n\n'''metodo de comillas sencilla para colocar comentario\nde varias lineas de codigo en python'''\n\n\"\"\"metodo de comillas dobles para colocar comentario\nde varias lineas de codigo en python\"\"\"\n\n# metodo para colocar comentario de una linea en python\n\n# Crea una variable (y una constante si el lenguaje lo soporta).\n\nvariable = 'hola mundo'\n# variable constante en python\n\nMI_VARIABLE = \"valor constante\"\n\n# variables segun el tipo de datos\n\n# str\ndeporte = 'futbol'\n\n# entero\nedad = 30\n\n# float\npeso = 62.5\n\n# boleano\ncondicion = False\n\n# imprimir en consola\n\nprint(f'hola mundo con python') # para imprimir varias lineas de codigo"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/qv1ko.py",
    "content": "# #00 - Sintaxis, variables, tipos de datos y hola mundo\n\n# www.python.org\n\n# Comment\n\"\"\"\nComment\n\"\"\"\n\nvar1 = 1\nVAR2 = 2\n\nvar3 = \"Python\"\nvar4 = 4\nvar5 = 5.5\n\nprint(\"¡Hola, \" + var3 + \"!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/qwik-zgheib.py",
    "content": "# visite oficial page https://www.python.org/\n\n# comment in one line\n\n\"\"\"\ncomment in multiple lines\n\"\"\"\n\nnumber_int: int = 10\nnumber_float: float = 10.5\nCONSTANT: float = 3.14\nstring: str = \"Hello, Python!\"\nboolen: bool = True\n\n\nprint(f\"{string}\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/ramon-almeida.py",
    "content": "# https://www.python.org/\n\n\"\"\"\nComentario de varias\nlineas. Que bueno está el jamón!\n\"\"\"\n'''\nEsto también es un comentario\n'''\n# Y esto.\n\njamon = 'Manjar'\n\njamon = True\njamon = ['Vida', 'Sabor', 'Maravilla']\njamon = {'Manjar': True}\n\nprint('Hola Python!')\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/ramxv.py",
    "content": "# Sitio web Oficial: https://www.python.org/\r\n\r\n## Comentarios ##\r\n\r\n# En python tenemos 2 formas diferentes de comentar. \r\n\r\n# Inline (en línea).\r\n\r\n'''\r\nY multilínea, este tenemos dos maneras de escribirlo.\r\nPodemos hacer comentarios multilínea con \r\ncomillas simples ('').\r\n'''\r\n\r\n\"\"\"\r\nTambién podemos hacer comentarios multilínea \r\ncon comillas dobles(\"\").\r\n\"\"\"\r\n\r\n## Variables y Constantes ##\r\n\r\nuna_variable = \"Retos de Programación\"\r\n'''\r\nPython no soporta las constantes. No obstante, podemos trabajar con estas\r\nescribiendo una variable en mayúsculas para indicar que esa variable debe\r\ntratarse como una constante. \r\n'''\r\nUNA_CONSTANTE = 2024\r\n\r\n## Tipos de Datos ##\r\n\r\n# int \r\nedad = 22\r\n# float\r\nsalario = 1350.70\r\n# complex \r\ncomplx = 1j + 2\r\n# string\r\ntexto = \"Roadmap 2024\"\r\n# bool\r\nes_anio_nuevo = True\r\n# diccionario\r\ndicc = {\"nombre\":\"Ram\", \"edad\":22}\r\n# lista\r\nli = [1,34,55,9j,12]\r\n# tupla\r\ntu = (3,'ratón',2.3)\r\n# conjunto (set)\r\ncon = {3,14,89,'Juan',True}\r\n# conjunto inmutable\r\ncon_inm = frozenset([1,3,'Luis',1j,4.5])\r\n# rango \r\nran = range(5,12)\r\n# binario\r\nby = bytes(15)\r\n\r\n## Impresión por Terminal ##\r\n\r\nlenguaje = \"Python\"\r\nprint(f\"¡Hola, {lenguaje}!\")\r\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/randy7394.py",
    "content": "# https://www.python.org/\n\n# Comentario en una linea\n\n'''\nComentario\nen\nvarias\nlineas\n'''\n\n\"\"\"\nEsto tambien\nes un comentario\nen varias\nlineas\n\"\"\"\n\nmy_variable = \"Esta es mi varibale\"\nmy_variable = \"Este es el nuevo valor de my_variable\"\n\nMY_CONSTANT = \"Esta es mi constante. Por favor no cambiar!\" #Esto es una constante por convencion\n\nmy_integer = 1\nmy_float = 1.5\nmy_boolean = False\nmy_string = \"Hola mundo!\"\n\nprint(f\"Hola Python!\")\nprint(type(my_variable))\nprint(type(MY_CONSTANT))\nprint(type(my_integer))\nprint(type(my_float))\nprint(type(my_boolean))\nprint(type(my_string))"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/rantamhack.py",
    "content": "#!/usr/bin/python3\n\n\n# Para tener una línea comentada en python se usa el simbolo \"#\"\n\n''' \nPara varias líneas se puede usar la triple comilla\ny tendremos las lineas intermedias comentadas\n'''\n\n\"\"\"\nTambien se pueden usar las comillas\ndobles para comentar varias líneas\n\"\"\"\n\n'''\nLa página de referencia de python es https://python.org\nLa página para España es https.es.python.org\n'''\n\n'''\nEn python no existen las constantes aunque por convencion y para poder usarlas \ncuando es necesario se definen como una variable pero dándole el nombre en mayusculas\n'''\n# Constante\nMY_CONSTANTE = 100\n\n# Variables\n\n# Entera (int)\nmy_integer_variable = 16\n\n# Decimal (float)\nmy_float_variable = 3.14\n\n# Texto (str)\nmy_text_variable = \"mi variable\"\n\n# Booleana (bool)\nmy_bool_variable = True\n\n# Mensaje de saludo al lenguaje\nlenguage = \"Python\"\n\nprint(MY_CONSTANTE)\nprint(my_integer_variable)\nprint(my_float_variable)\nprint(my_text_variable)\nprint(my_bool_variable)\nprint(f'Hola, {lenguage}!!')\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/raul-progr.py",
    "content": "# https://www.python.org/\n\n# Comentario en una linea\n\"\"\" comentario \n    en \n    varias \n    lineas\n\"\"\"\n'''\n    Esto\n    tambien\n    es\n    un\n    comentario\n    multiple\n    lineas\n'''\n\nuna_variable = \"\" # variable tipo texto\notra_variable = 0 # variable tipo numero\nuna_booleana = True # variable tipo falso verdadero / boolean\n\nUNA_CONSTANTE = \"Esta es una constante no tocar\" \"\"\"\" python no tiene constantes nativas\n                                                    pero por conveccion asi se usan \"\"\"\n# tipos de datos primitivos\n\nun_entero = 7\nun_flotante = 6.9\nun_booleano = False\nun_string = \"un string\"\n\nprint(\"Hola, Python! Feliz 2024\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/raulG91.py",
    "content": "#https://docs.python.org/3/\n\n# This is a comment\n'''\nThis is also a comment\n'''\nvariable = \"Hello\"\nCOSNTANT = 3.14\ninteger = 1\ndouble = 5.5\nboolean = True\nstring = \"This is a string\"\n\nprint(\"¡Hola, Python!\")\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/rayn1er.py",
    "content": "# /*\n#  * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n#  * - Recuerda que todas las instrucciones de participación están en el\n#  *   repositorio de GitHub.\n#  *\n#  * Lo primero... ¿Ya has elegido un lenguaje?\n#  * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n#  * - Este primer reto te servirá para familiarizarte con la forma de participar\n#  *   enviando tus propias soluciones.\n#  *\n#  * EJERCICIO:\n#  * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n#  *   lenguaje de programación que has seleccionado.\n#  * - Representa las diferentes sintaxis que existen de crear comentarios\n#  *   en el lenguaje (en una línea, varias...).\n#  * - Crea una variable (y una constante si el lenguaje lo soporta).\n#  * - Crea variables representando todos los tipos de datos primitivos\n#  *   del lenguaje (cadenas de texto, enteros, booleanos...).\n#  * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n#  *\n#  * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n#  * debemos comenzar por el principio.\n#  */\n\n#Hola! Mi nombre es raul, realmente estoy decidido a cambiar mi vida finalmente despues de haber tropezado 3000 veces, asi que voy esta vez en serio!\n#Estaremos estudiando python! puedes descargarlo aca: https://www.python.org/\n'''Asi tambien podemos comentar codigo\n   ..... :)\n'''\n\n\npython_variable = 'python' #esta es una variable\nPYTHON_CONSTANT = 'PYTHON' #como no existe en python una manera especifica para generar una constante, por convencion se escribe toda en mayusculas\ntext = 'hola' #esto es un dato primitivo del tipo string o cadena de texto\nnumber = 123456  # y esto es un dato primitivo del tipo int\nfloat_number = 12.31313 # este es un float :)\ntrue = True #Un booleano verdadero\nfalse = False #un booleano falso\n\nprint(f'Hola {python_variable}')\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/raynerpv2022.py",
    "content": "\"\"\"\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n \"\"\"\n\n# http://pyhton.org\n#  comentario\n\n\"\"\"\ncomentario \nvarias \nlineas\n\"\"\"\n\nvar_1 = \"primera variable\"\n\"\"\"\nno existen constantes, \npero por convencion se pone en\nmayuscula para que no se cambie \naccidentalmente\n\n\"\"\" \nCONSTANTE_1 = \"Python\"\n\nvar_int = 10\nvar_float = 10.1\nvar_bool = True\nvar_string = \"string 1\"\n\nprint(\"Hola \" ,CONSTANTE_1)\n\nprint(type(var_float))\nprint(type(var_int))\nprint(type(var_string))\nprint(type(var_bool))\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/restevean.py",
    "content": "# https://www.python.org/\n\n# Comentario de una sola linea\n\n\"\"\"\nComentario multilínea\ncon comillas dobles\n\"\"\"\n\n'''\nComentario multilínea\ncon comillas simples\n'''\n\nvariable_string: str = \"Hola Python\"\nCONSTANTE: str = \"Soy una constante\"\nentero: int = 1\ndecimal: float = 1.5\nbooleano: bool = True\nlista: list = [1, 2, 3]\ntupla: tuple = (1, 2, 3)\ndiccionario: dict = {\"nombre\": \"Juan\", \"apellido\": \"Perez\"}\n\nprint(variable_string)\nprint(f'CONSTANTE {type(CONSTANTE)}, {repr(CONSTANTE)}')\nprint(f'entero {type(entero)}, {repr(entero)}')\nprint(f'decimal {type(decimal)}, {repr(decimal)}')\nprint(f'booleano {type(booleano)} {repr(booleano)}')\nprint(f'lista {type(lista)}, {repr(lista)}')\nprint(f'tupla {type(tupla)}, {repr(tupla)}')\nprint(f'diccionario {type(diccionario)}, {repr(diccionario)}')\n\n# Texto sin cambiar en main\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/rianojnicolas.py",
    "content": "# 1. Sitio web oficial del lenguaje de de programacion python\n# https://python.org\n\n# 2. Sintaxis de comentarios\n\n# Comentario de una linea\n\n\"\"\"\nEsto tambien se trata como\nun comentario, pero se puede\ntratar como un parrafo\n\"\"\"\n\n'''\nAhora tambien se puede\ncon comilla simple\n\n'''\n\n# 3. Variables\na = 1\nb = 2\nc = a + b\n\n# 4. Tipos de datos primitivos\nmyint = 1\nmyfloat = 1.0\nmychar = 'a'\nmystring = \"Hola\"\nmybool = True\nmylist = [1,2]\n\n# 5. Imprimir en terminal => \"¡Hola, python!\"\nprint(\"¡Hola, python!\")\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/rigo93acosta.py",
    "content": "# Reto 00\n''' \n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n'''\n\n# web_page_python: https://www.python.org\n\n# Comentario one line\n\n\"\"\" \nComentario\nmulti\nline\n\"\"\"\n\n# Variables y constantes\nfirst_var = \"Hi, I'm Rigo\"\n# No existen constantes, pero se llegó a convención de que se usaran MAYÚSCULAS\nMY_CONST = \"Rigo\"\n\n# Tipos de datos primitivos\nfirst_str = \"I's a string\"\nentero = 7\ndecimal = 3.14\ncomplejo = 1993 + 25j \nbooleano = False\nlista = [\"rigo\", 25, False, [1, 2, 3]]\ntuple = (\"rigo\", 25, True, [4, 5, 6])\nmy_set = {\"rigo\", 25, True}\ndiccionario = {\n    \"name\": \"Rigoberto  \",\n    \"age\": 30\n}\nfirst_none = None\n\nprint('¡Hola, Python!')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/rikmij.py",
    "content": "#Para un comentario de 1 línea en Python, se pone una almohadilla antes\n\n'''\nSi quieres un comentario de varias líneas como este, son 3 comillas para abrir y 3\npara cerrar.\nAprovecho este comentario para la url de Python, que es https://www.python.org/\n'''\n\n#Creación de variables. No hay constantes como tal, pues todo en Python es editable\nvariable = \"Esto es una variable tipo String en Python, no hay constantes en Python como tal\"\n\n'''Creación de variables por tipos\nPor norma, las variables se nombran en snake-case'''\nvar_string = \"Python\"\n#print(type(var_string))\n\nvar_integer = 33\n#print(type(var_integer))\n\nvar_float = 3.1415\n#print(type(var_float))\n\nvar_bool = True\n#print(type(var_bool))\n\n#Impresión Hola Python\nprint(f\"Hola, {var_string}!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/rodrigolopez25.py",
    "content": "#https://www.python.org/\n\n# Comentario en una linea\n\n\"\"\"\nEsto es tambien es \nun comentario \nen varias lineas \n\"\"\" \n\n'''\nEsto tambien es\nun comentario \nen varias lineas\n'''\n\nmy_variable = \"mi variable\"\nmy_variable = \"nuevo valor de mi variable\"\n\nMY_CONSTANT = \"Mi constante\" #Por convención\nMY_CONSTANT = \"oevkokrfvmfjmv+\"\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/rojasricoo.py",
    "content": "# author: Oscar Duvan Rojas R\n\n# SOLUCION:\n# python: https://www.python.org/\n\n\n# 1)\n# comentario en python\n\n\"\"\"\ncomentario en python\n\"\"\"\n\n'''\ncomentario en python\n'''\n\n# 2)\none_variable = 'Esto es una variable'\n\n# 3)\nstring = 'String'\nnumero_entero = 3\nnumero_decimal = 4.4\nbool_True = True\nbool_False = False\nMY_CONST_SAL = 'Soy una constante'\n\nprint('¡Hola, Python!')\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/rserradev.py",
    "content": "# Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n# https://www.python.org/doc/\n# https://www.w3schools.com/python\n\n#  * - Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n\n##Comentario de una linea\n\n\"\"\"\nComentario\nde\nvarias\nlineas\n\"\"\"\n\n#  * - Crea una variable (y una constante si el lenguaje lo soporta).\n\nvariable1 = 1\n\n#  * - Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n\nentero = 1\ncadenaDeTexto = \"Hola\"\nflotante = 1.1\nbuleano = True\n\n#  * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\nprint(cadenaDeTexto + \" \" + \"Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/s384.py",
    "content": "# url de python https://www.python.org/\n\n# Comentario de una linea\n\n\"\"\"\nComentario \nde \nvarias \nlineas\n\"\"\"\n\n# Variable\nnumer = 10\n# Las constantes no existen en python, pero por convención se usan mayusculas\nPI = 3.1416\n\n# Tipos de datos primitivos\nstring = \"variable string\"\nnumer = 10 # Variable numerica\nnumer_float = 3.1416 # Variable flotante\nboolean = True # Variable booleana\n\n# Imprimir por pantalla\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/saezMD.py",
    "content": "# https://python.org\n\n# Only one line\n\n\"\"\"\nYou can also use this solution\nfor multiple lines\ncomments and symbols: ?()/=&)%($&·)\n\"\"\"\n\nprint(\"Help me!!!\") #This is a comment at the end of a line. \n\n#You can also \n#use several lines\n#like this\n\n#Variable\nx = 20\n\n#Constant\nPI = 3.14\n\n#Types of data\ndecimal = 10\nbinary = 0b11\noctal = 0o13\nhexadecimal = 0x14\nfloat= 10.44\ncomplexLiteral = 7+12j\n\nboolean01 = True\n\nstrings = \"this is a str\"\n\nliteralNone = None\n\nlist_fruit = [\"pear\", \"apple\", \"orange\"]\ntuple_numbs = (1,2,3,4)\ndictionary_animals = {\"a\":\"andas\", \"b\":\"boat\", \"c\":\"cat\"}\nset_leters = {\"c\",\"a\",\"r\"}\n\n\n#Print in the terminal\nprint(\"Hello, Python!\")\n\nprint(type(decimal))\nprint(type(binary))\nprint(type(octal))\nprint(type(hexadecimal))\nprint(type(float))\nprint(type(complexLiteral))\n\nprint(type(literalNone))\nprint(type(dictionary_animals))\nprint(type(set_leters))\n\nprint(type(PI))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/sagro27.py",
    "content": "# https://www.python.org/ \n\n#este es un comentario\n\n'''comentario de\nbloque con triple \ncomillas simples''' \n\n\"\"\"Este es otro comentario\nden bloque con comillas \ndobles válido\"\"\"\n\n\nvariable = 10\n\nnumero_entero = 2\n\nnumero_flotante = 1.5\n\ncadena_de_texto = \"Cadena\"\n\nbooleano = False\n\nbooleano = True\n\nTipos_de_datos = [2,\"string\", False, True, 1.5]\n\n\nprint(\"Hola Python\" )\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/salas89.py",
    "content": "/*\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n\n#comentario en python --> https://www.python.org/\n\"\"\"\nComentario\nen varias\nlineas\n\"\"\"\n\n'''\ncomentario con \ncomillas \nsimples\n'''\n\nvariable= 11\n\nentero=1\ndecimales=1.1\nbooleano = True\ntexto = \"Esto es un String\"\nlista = [a,,b,c,d,e]\ntupla = (a,b,c,d,e)\ndiccionario = {alumno = \"salas\", materia=\"python\"}\n\nprint(\"Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/salazar-sys.py",
    "content": "#pagina oficial del lenguaje: https://www.python.org/\n\n#Comentario en\n#varias lineas\n\n\n\"\"\" Comentario en\nvarias lineas \"\"\"\n\n''' Otro comentario\nen varias líneas '''\n\nvariable= \"esto es una variable\"\nCONSTANTE = \"Python no tiene constantes\" #por convencion\n\ntupla = {\"las tuplas son valores contantes\", \"19\", 19}\n\nnumero_entero = 5\nnumero_decimal = 2,5\nbooleano = True\nbooleano = False\ntexto = \"variable string\"\n\nprint(\"¡Hola, Python!\")\n\nprint (\"Esto es un valor constante\")\nprint(tupla)\nprint(type(tupla))\n\nprint (\"Datos primitivos\")\nprint(f\"la variable\", numero_entero, \"es un valor\",type(numero_entero))\nprint(type(numero_entero))\nprint(numero_decimal)\nprint(type(numero_decimal))\nprint(booleano)\nprint(type(booleano))\nprint(texto)\nprint(type(texto))"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/salkalero.py",
    "content": "# Con este elemento \"#\" podemos crear los comentarios en una línea.\n\n#La Web oficial de Python es la siguiente. https://www.python.org\nprint(\"\\n\"*0)#Con esto añado separaciones entre los resultados del código\nprint(\"Hello, World!\")#Se puede añadir los comentarios al final de una orden.\n\n#pint(\"Hello,World!\")#Se pueden usar para evitar que se ejecuten cualquier orden.\n\n#Python no dispone de una sintaxis para crear varias líneas de comentarios\n#para ello se pueden ir añadiendo \"#\" en cada línea para crear comentarios\n#con varias líneas.\n\n\"\"\"Pero, dado que python ignorará los literales de cadena que no estén\nasignados a una variable, se puede crear un comentario usando doble \ncomillas tres veces, como el usado en este comentario.Hay que \ntener en cuenta, que esta cadena no puede estar asignada\n a una variable.\n\"\"\"\nprint(\"\\n\"*0)#Con esto añado separaciones entre los resultados del código\nprint(\"\"\"Si sale este mensaje, el comentario usando las triples \n      comillas es un éxito!!!. Recuerda que la cadena no\n      debe de estar asignada a una  variable.\"\"\")\n\n\nprint(\"\\n\"*0)#Con esto añado separaciones entre los resultados del código\n#Creando una variable.\nmy_Variable = \"Estos son variables\"\nprint (my_Variable)\na = 250\nb = \"doscientos cincuenta\"\nc = 250.0\nprint (a)\nprint (b)\nprint (c)\nprint (250,\"doscientos cincuenta\",250.0)\nprint (a,b,c,\"[con formato print (a,b,c)]\")\nprint(\"\\n\"*0)#Con esto añado separaciones entre los resultados del código\n\"\"\"En python no existe la variable constante, pero existe un concenso \nque si te encuentras una variable escrita en mayúsculas, esto quiere \ndecir que esa variable hay que considerarla como si fuera una \nconstante, por lo que no hay que cambiar el valor.\n\"\"\"\nMY_CONSTANTE = \"\"\"En python no existe la variable constante, pero existe un concenso \nque si te encuentras una variable escrita en mayúsculas, esto quiere \ndecir que esa variable hay que considerarla como si fuera una \nconstante, por lo que no hay que cambiar el valor.\"\"\"\nprint (MY_CONSTANTE)\nprint(\"\\n\"*0)#Con esto añado separaciones entre los resultados del código\n#Creamos variables con los distintos tipos de datos que soporta python.\n#Usamos la función \"type() para mostrar el tipo de datos\"\nprint (\"A continuación se representa varios tipos de variables\")\nprint(\"\\n\"*0)\na = 100\nb = \"Cien\"\nc = 27.6\nd = 1j\nprint((a),type(a),(b),type(b),(c),type(c),(d),type(d))\n\nprint(\"\\n\"*0)#Con esto añado separaciones entre los resultados del código\na = [\"manzana\",\"peras\",\"limones\",\"mango\"]\nb = (\"manzana\",\"peras\",\"limones\",\"mango\")\nc = range(15)\nd = {\"name\" : \"Salvador\" , \"altura\" : \"325Cm\" , \"age\" : 12.5}\nprint((a),type(a),(b),type(b),(c),type(c),(d),type(d))\nprint(\"\\n\"*0)\n\ne = {\"vaso\" , \"botellas\" ,\"sartén\" }\nf = frozenset({\"cuchara\" , \"cuchillo\" , \"tenedor\"})\ng = True\nh = b\"Hola\"\nprint((e),type(e),(f),type(f),(g),type(g),(h),type(h))\n\nprint(\"\\n\"*0)\n\ni =bytearray(1)\nj = memoryview(bytes(2))\nk = None\n\nprint((i),type(i),(j),type(j),(k),type(k))\nprint(\"ªn\"*0)\n#Imprimiendo \"Hola,Python\"\nprint(\"Hola,Python\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/santiago434c.py",
    "content": "#EJERCICIO:\n\"\"\"\n   1. Crea un comentario en el código y coloca la URL del sitio web oficial del\n     lenguaje de programación que has seleccionado.\n  2. Representa las diferentes sintaxis que existen de crear comentarios\n      en el lenguaje (en una línea, varias...).\n   3. Crea una variable (y una constante si el lenguaje lo soporta).\n   4. Crea variables representando todos los tipos de datos primitivos\n     del lenguaje (cadenas de texto, enteros, booleanos...).\n   5. Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\n\"\"\"\n#SOLUCION:\n\n#1. https://www.python.org/\n\n#2. Varias Lineas\n\"\"\"\nEste es otro\ntipo de comentario\nen Python.\n\"\"\"\n\n#3. Variable y constante\nvariable = 1\n\n#4. Varios tipo de datos primitivos\n\n#Texto\ntexto = \"Python\"\n\n#Enteros\nnum = 5\n\n#Boleano\nbooleano = True\n\n#Float\ndec = 2.56\n\n#5. Print\nprint(\"Hola \" + texto)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/santiagobailleres.py",
    "content": "''' * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n'''\n# Solución:\n# 1. https://www.python.org/\n\n# 2. Una línea \n# Este es un comentario en Python\n'''\nVarias\nlineas\n'''\n\n# 3. Crea una variable (y una constante si el lenguaje lo soporta).\nvar = 1\n# No hay constantes en Python\n\n# 4. Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\nentero = 1\nflotante = 1.0\nstring = \"Hola\"\nbooleano = True\nnulo = None\n\n# 5. Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/santiagobima.py",
    "content": "# https://www.python.org/\n\n#comentarioenunalinea\n\n\"\"\"\nuna manera de escribir\n\"\"\"\n    \n'''\notra forma de escribir\n'''\n    \nunavariable= \"esto si es una variable\"\n\nUNACONSTANTE = \"Esto es una constante, es una forma de representarlo\"\n\n\nentero = int(4)\nflotante= float(4)\nbool = False\nstring = \"esto es un texto\"\n\n\nprint(type(entero))\nprint(type(flotante))\nprint(type(bool))\nprint(type(string))\n\nprint('Hola Python')\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/santiagodc8.py",
    "content": "# Web Oficial Python https://www.python.org \n# Esto es un comentario\n# pero tambien hay una opcion de varias lineas\n\n\"\"\"\nEste es el comentario\nen varias lineas\n\"\"\"\n\n'''\nTambien se puede \ncon comillas simples\n'''\n\nmy_variable = \"Mi variable\"\nmy_variable = \"Nuevo valor de mi variable\"\n\nMY_CONSTANT = \"Mi constante\" # por convencion\n\n# Tipos de Datos Primitivos\n\nmy_int = 88 # tipo entero\nmy_float = 10.8 # tipo decimal\nmy_boolean = True # tipo boleano\nmy_boolean = False # tipo boleano\nmy_string = \"Mi cadena de texto\" # tipo texto\nmy_string = 'Mi otra cadena de texto, pero con comillas simples' # tipo texto\n\nprint(\"!Hola Python xd!\")\n\nprint(type(my_int))\nprint(type(my_float))\nprint(type(my_boolean))\nprint(type(my_string))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/santyjL.py",
    "content": "#https://www.python.org/\n#00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n\n\"Ejercicio : \"\n\n#documentar en varias lineas\n\"\"\"\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\"\"\"\n\n\nnombre = \"santy\" #Variable\nVELOCIDAD_DE_LA_LUZ = 299792458 #CONSTANTE\n\n#Tipo de datos primitivos\n\nString : str = \"Cadena de Texto\"\nNumero_Entero : int = 14\nNumero_flotante : float = 13.9\nBoleano_True : bool = True\nBoleano_False : bool = False\n\n#Hola\nprint(\"Hola , mi nombre es \" , nombre , \" y esto es python God\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/sarismejiasanchez.py",
    "content": "# https://www.python.org/\n\n# Comentario de una linea\n\n\"\"\"\nEste es un comentario\nde múltiples líneas\n\"\"\"\n\n'''\nEste es otro comentario\nde múltiples líneas\n'''\n\n\"\"\"\nNombres de variables en Python\nSegún la PEP 8 los nombres de las variables de Python deben de escribirse en snake_case. Además en deben de cumplir las siguientes características:\n\nTienen que empezar por una letra o barra baja.\nEl uso de keywords como nombres está prohibido.\nLos nombres deben de ser descriptivos.\nDeben de estar en minúsculas y separando palabras por barras bajas ‘_’.\nLas constantes se escriben en mayúsculas y SNAKE_CASE.\n\nFuente: https://elpythonista.com/variables-python\n\"\"\"\n\nmy_variable = \"Esto es una variale\"\nMY_CONSTANT = \"Esto es una constante\"\n\n# TIPOS DE DATOS PRIMITIVOS\n# Entero (int)\n\"\"\"\nRepresenta números enteros, positivos o negativos, sin parte fraccionaria.\n\"\"\"\nentero = 10\nprint(entero)\nprint(type(entero))\n\n# Flotate (float)\n\"\"\"\nRepresenta números decimales, es decir, números con parte fraccionaria.\n\"\"\"\nflotante = 3.14\nprint(flotante)\nprint(type(flotante))\n\n# Cadena de caracteres (str)\n\"\"\"\nRepresenta una secuencia de caracteres. Puede contener letras, números, y otros caracteres.\n\"\"\"\ncadena = \"¡Hola, Python!\"\nprint(cadena)\nprint(type(cadena))\n\n# Booleano (bool)\n\"\"\"\nRepresenta valores de verdad, es decir, True (verdadero) o False (falso).\n\"\"\"\nbooleano = True\nprint(booleano)\nprint(type(booleano))\nbooleano = False\nprint(booleano)\nprint(type(booleano))\n\n# Numero complejo (complex)\n\"\"\"\nUn número complejo consta de dos partes: la parte real y la parte imaginaria. \nSe expresan en la forma a + bj, donde a es la parte real, b es la parte imaginaria \ny j es la unidad imaginaria (que es la raíz cuadrada de -1).\n\"\"\"\ncomplejo = 1 + 2j\nprint(complejo)\nprint(type(complejo))\n\n# NoneType\n\"\"\"\nEl tipo de dato None representa la ausencia de un valor o la falta de un objeto. \nSe utiliza comúnmente para indicar que una variable no tiene un valor asignado.\n\"\"\"\nnulo = None\nprint(nulo)\nprint(type(nulo))\n\n# Lista (list)\n\"\"\"\nRepresenta una secuencia mutable de elementos. \nPuedes modificar, añadir o eliminar elementos de una lista.\n\"\"\"\nlista = [1, 2, 3]\nprint(lista)\nprint(type(lista))\n\n# Tupla (tuple)\n\"\"\"\nSimilar a una lista, pero es inmutable, lo que significa que \nno puedes modificar su contenido después de crearla.\n\"\"\"\ntupla = (4, 5, 6)\nprint(tupla)\nprint(type(tupla))\n\n# Conjunto (set)\n\"\"\"\nRepresenta una colección desordenada de elementos únicos. No permite elementos duplicados.\n\"\"\"\nconjunto = {7, 8, 9}\nprint(conjunto)\nprint(type(conjunto))\n\n# Diccionario (dict)\n\"\"\"\nRepresenta una colección de pares clave-valor. Cada valor está asociado con una clave única.\n\"\"\"\ndiccionario = {\"a\": 1, \"b\": 2, \"c\": 3}\nprint(diccionario)\nprint(type(diccionario))\n\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/saulmrto.py",
    "content": "# https://www.python.org/\n\n# Comentario en una linea\n\n\"\"\"\nEsto es un comentario\nen varias lineas\n\"\"\"\n\n'''\nEsto tambien \nes un comentario\nen varias lineas\n'''\n\nmy_variable = \"Mi variable\"\nmy_variable = \"Nuevo valor de mi variable\"\n\nMY_CONSTANT = \"Mi constante\" # por convencion\n\nmy_int = 1\nmy_int : int = 1 # se puede especificar el tipo\nmy_float = 1.5\nmy_bool = True\nmy_bool = False\nmy_string = \"Mi cadena de texto\"\nmy_other_string = 'Mi otra cadena de texto'\n\nprint(\"¡Hola, Python!\")\n\nprint(type(my_int))\nprint(type(my_float))\nprint(type(my_bool))\nprint(type(my_string))\nprint(type(my_other_string))"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/seni889.py",
    "content": "#Este es un comentario\n\n# url =\"https://www.python.org\"\n\n\"\"\"\nesto tambien es un comentario \n\"\"\"\n\n'''\nEste texto tambien es un comentario\n'''\n\nmy_variable = \"Mi variable\"\nmy_variable = \"Nueva variable\"\n\nMY_CONSTANT = \"Mi constante\"\nMY_CONSTANT = \"AHEBGEHEVKE\"\n\nmy_int = 1\nmy_float = 1.5\n\nmy_bool = True\nmy_bool = False\n\nmy_string = \"Micadena de texto\"\nmy_other_string = 'Mi otra cadena de texto'\n\nprint(\"Hola, Mundo\")\n\nprint(type(my_int)),\n\nint = 1\nprecio = 9.99\nnombre = \"Panchito\"\n\nprint(\"codigo\",int)\nprint(\"El precio del producto\",precio)\nprint(\"Nombre del producto\",nombre)\nprint(\"muchequie\")\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/sergiomhernandez.py",
    "content": "\"\"\"\n1) Crea un comentario en el código y coloca la URL del sitio web oficial del\n\"\"\"\n\n#Respuesta: https://www.python.org/\n\n\"\"\"\n2) Representa las diferentes sintaxis que existen de crear comentarios\n\"\"\"\n\n#Esto es un comentario de una linea\n\n'''\nEsto es un comentario \nen varias lineas\n'''\n\n\"\"\"\nEsto tambien es un comentario en varias lineas \n\"\"\"\n\n\"\"\"\n3) Crea una variable (y una constante si el lenguaje lo soporta).\n\"\"\"\nvar = \"String\" \nMY_CONSTANT = \"Una constante\"\n\n\"\"\"\n4) Crea variables representando todos los tipos de datos primitivos\n   del lenguaje (cadenas de texto, enteros, booleanos...).\n\"\"\"\n\nstr_var = \"Retos de programacion\"\nint_var = 100\nbool_var = True\nfloat_var = 3.14\ncomplex_var = 1j\nlist_var = [1, 2, 3, 4, 5]\ndict_var = {'name': 'Sergio', 'age':27}\ntuple_var = (\"teclado\", \"mouse\", \"monitor\")\nset_var = {'teclado', 'mouse', 'monitor'}\n\n\"\"\"\n5) Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\"\"\"\nprint(\"!Hola python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/sergiovelayos.py",
    "content": "# https://www.python.org/\n\n \n\n# Comentario en una línea\n# Comentario 2\n# Comentario 3\n\n \n\n\"\"\"\n\nEsto es un comentario\n\nen varias líneas\n\n\"\"\"\n\n \n\n'''\n\nEsto es un comentario\n\nen varias líneas\n\n'''\n\n \n\n# Crear una variable\n\nmy_variable = 1 + 1\n\n \n\n# crear una constante\n\n# Python no tiene\n\n \n\n# datos primitivos\n\n# numeros enteros\n\nvar_entero = 4\n\n \n\n# numeros decimales\n\nvar_decimal = 4.3\nvar_deci = 2.1\n\n \n\n# boolean\n\nvar_booleano = True\n\n \n\n# cadena de texto\n\nvar_cadena = \"ola k ase\"\n\n \n\nprint(\"Imprimir texto\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/slaughtbear.py",
    "content": "#                       P Y T H O N --> https://www.python.org/\n\n# C O M E N T A R I O S\n#   1. Comentario en una línea.\n\n\"\"\"\n    2. Comentario en varias líneas con comillas dobles.\n\"\"\"\n\n'''\n    3. Comentario en varias líneas con comillas simples.\n'''\n\n# V A R I A B L E S\nvariable = 'Variable con valor de tipo String'\n\n# En Python no existen las variables constantes, sin embargo -\nCONSTANTE = 'Variable \"constante\" de tipo String' # se usan mayúsculas para representarlas por convención.\n\n# T I P O S   D E   D A T O S   P R I M I T I V O S\ncadena = 'Esto es una cadena' # String\nentero = 999 # Int\ndecimal = 6.66 # Float\nverdadero = True # Bool True\nfalso = False # Bool False\nsin_valor = None # None\n\nprint('¡Hola, Python!')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/smelo0.py",
    "content": "# Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje\n# Esto es un comentario. https://www.python.org/\n\n\n# Sintaxis de comentarios. Comentario uno\n\"\"\"\nComentario dos\n\"\"\"\n'''\nComentario tres\n'''\nvariable = \"esto es una variable\" #Variable\nCONSTANTE = 5 # Esto es una constante por convencion\n\n# tipos de variables en python\n\nstring = \"esto es un string\"\nboolean = True\ninteger = 21\nfloat = 5.555\n \nPrint(\"¡Hola, Python!\")\n\n# that's it.\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/sniker1223.py",
    "content": "#https://www.python.org/\n# Single Line Comment\n\n\"\"\" Multiple\nLine \nComment 1 \"\"\"\n\n''' Multiple\nLine \nComment 2 '''\n\n#constant type\nLANGUAJE = \"PHYTHON\"\n\n#primitive Data types\nvar_int = 0\nvar_float = 2.0\nvar_bool = True\nvar_string = \"Sara\"\n\n#print in console\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/sofiamfernandez.py",
    "content": "# #00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO by sofiamfernandez \n# url del sitio oficial https://www.python.org/\n\n#Diferentes sintaxis de comentarios en Python:  \n\n#Comentario en línea\n\n\"\"\"\nEsto es un bloque\ncomentado o un\ncomentario \nen bloque\n\"\"\"\n\n#VARIABLES\n\nnombre_de_usuario = \"Pepe Hongo\"\nprint(nombre_de_usuario)\n\n#CONSTANTES : En Py no existen las constantes pero nos referimos a las variables que no cambian con el nombre en mayúsculas\n\nDIAS_DE_LA_SEMANA = 7\nprint(DIAS_DE_LA_SEMANA)\n\n#TIPOS DE DATOS BASITOS\n\nentero       = 77                          #int\nflotante     = 7.4                         #float\ncomplejos    = 10.3j                       #complex\ncadenas      = \"Pepe\", \"Pepa\", \"Pig\"       #str\nbooleano     = True , False                #bool\ndiccionario  = {\n  \"Nombre\": \"Pepe\",\n  \"Edad\": 27,\n  \"Documento\": 1003882\n}                                           #dict\nlista        = [\"Paula\", 14, True]          #list\ntupla        = (\"Paula\", 14, 7.8 , False)   #tuple\nconjunto     = {3, 4, 5, \"Jimena\", 3.21}    #set\nrango        = range(5,10)                  #range\nbinario      = bytes(45)                    #bytes\n\n#IMPRIMIR POR TERMINAL \nnombre_de_lenguaje = \"Python\"\nprint(\"Hola \" + nombre_de_lenguaje)\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/sorubadguy.py",
    "content": "#https://python.org\n\n#Comentario de una linea\n\n\"\"\"\ncomentario\nde varias\nlineas\n\"\"\"\n\n'''\ncomentario de \nvarias lienas\ncon comillas simples\n'''\n\nvariable = \"valor variable 1\"\nvariable = \"valor de variable 1 cambiado\"\n\nCONSTANTE = \"python no soporta constantes, pero por convencio van asi\"\n\nmi_entero = 27\nmi_decimal = 0.3\nmi_texto = \"hola mundo\"\nmi_texto2 = 'chau mundo'\nmi_boleano = True\nmi_boleano2 = False\n\nprint(\"hola, python\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/soydaviddev.py",
    "content": "\"\"\" * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */ \"\"\"\n\n\"\"\"\nhttps://www.python.org/\n\"\"\"\n# Ejercicio 00\n\nvariable = ''\nCONSTANTE = 0\n\nstring = \"Hola\"\nnum = 28\nmi_float  = 3.7\nmi_booleano = True\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/soydianaibarra.py",
    "content": "\n# https://python.org\n\n# Con el simbolo # puedes crear un comentario en una linea\n\n\"\"\"\nPara realizar un comentario\nen varias lineas se utilizan \ntreples comillas dobles.\n\"\"\"\n\n'''\nTambién es posible crear\nun comentario de varias lineas\ncon triple comillas simples.\n'''\n\nmy_variable = \"Mi variable\"\nmy_variable = \"Nuevo valor de mi variable\"\n\nMY_CONSTANT = \"Mi constante\" # Por convención, el valor de la variable si se puede cambiar pero con las mayusculas se intenta representar que es el valor de una constante.\n\nmy_int = 2601\nmy_float = 3.1416\nmy_bool = True\nmy_bool = False\nmy_string = \"Mi primer cadena de texto\"\nmy_other_string = 'Mi otra cadena de texto'\n\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/soyjosep.py",
    "content": "# https://python.org\n\n# Comentario de una sola línea en Python\n\n\"\"\"\nEste es un comentario\nque se extiende por varias líneas,\nusado principalmente para docstrings o documentación detallada.\n\"\"\"\n\n# Definición de variables\nnombre_variable = \"Mi variable\"  # Asignando un valor inicial\nnombre_variable = \"Nuevo valor de la variable\"  # Reasignando un valor nuevo\n\n# Definición de una constante (convención en mayúsculas para constantes)\nMI_CONSTANTE = \"Esta es una constante\"  # En Python las constantes no son inmutables, pero es una convención no modificarlas\n\n# Tipos de datos primitivos en Python\nentero = 42  # Tipo entero\nflotante = 3.1416  # Tipo flotante\nbooleano_verdadero = True  # Tipo booleano (valor verdadero)\nbooleano_falso = False  # Tipo booleano (valor falso)\ncadena_texto = \"Hola, soy una cadena de texto\"  # Tipo cadena de texto (str)\notra_cadena = \"Otra cadena de ejemplo\"  # Otra cadena de texto\n\n# Imprimiendo el mensaje solicitado\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/steven9708m.py",
    "content": "# https://www.python.org\n\n# Esto es un Comenatrio de una linea\n\n\"\"\"\nEste es un comentario de varias líneas.\nPuedes escribir tanto como necesites\ndentro de estas comillas triples.\n\"\"\"\n\n'''\nCon estas otras comillas tambien puedo\ncolocar comentarios.\n'''\n\nmy_variable = \"Variable de Prueba\"\n\nMY_CONSTANT = \"Mi constante que puede variar\"\n\nmy_int = 1\nmy_float = 1.5\nmy_bool = True\nmy_bool = False\nmy_string = \"Mi cadena de texto\"\nmy_other_string = 'Mi otra cadena de texto'\nmy_variable_bytes = b\"Tipo de dato primitipo de Bytes\"\n\n\n#Impresion por consola\n\nprint (\"¡Hola, Phyton! . . . Steven a cumplido su tarea :)\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/strooplab.py",
    "content": "#https://www.python.org/\n#00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n\n\"\"\"\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\"\"\"\n\n\nnombre = \"Diego\" #Variable\nTIEMPO_RESTANTE = 24 #constante\n\n#Tipo de datos primitivos\n\nString = \"Cadena de Texto\"\nNumero_Entero = 14\nNumero_flotante = 13.9\nBoleano_True = True\nBoleano_False = False\n\nprint(f\"Hola , mi nombre es: {nombre}, y faltan {TIEMPO_RESTANTE} segundos para que el mundo explote\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/suescun845.py",
    "content": "# URL: https://www.python.org/\r\n\r\n# Comentario De Una Sola Linea\r\n\r\n'''\r\n\r\nComentario\r\nEn\r\nVarias\r\nLineas\r\n\r\n'''\r\n\r\n# Creacion De Una Variable\r\n\r\nvariable = 12\r\n\r\n#Tipos De Datos\r\n\r\nstring = 'Hola Mundo'\r\nNumber = 13\r\nmy_float = 3.14\r\nbooleano = True\r\nlista = [1, 2, 3.14, True, 'Hola Mundo']\r\ntupla = (4, 5, 6, 7.32, False, 'Hola Mundo')\r\nconjunto =  {1, 2, 3, 4, 5, 6}\r\ndiccionario = {'nombre': 'Angel', 'edad': 18, 'ciudad': 'Bogota'}\r\n\r\n\r\n#Terminal\r\n\r\nprint('Hola, Python')\r\nprint(type(string))\r\nprint(type(Number))\r\nprint(type(my_float))\r\nprint(type(booleano))\r\nprint(type(lista))\r\nprint(type(tupla))\r\nprint(type(conjunto))\r\nprint(type(diccionario))\r\n\r\n\r\n'''\r\n\r\nAutor: Suescun845\r\nFecha: 27/12/2023\r\n\r\n'''\r\n\r\n\r\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/sunjamer.py",
    "content": "# https://www.python.org\n\n# comentario en una linia\n\n\"\"\" un comentario \nen varias \nlinias con\ncomillas dobles\n\"\"\"\n\n''' comentario\nen varias \nlinias \ncon \ncomillas simples\n'''\n\nmi_variable = str\n\nmi_constante = \"me llamo sunjamer\"\n\nmi_var_int = 26 \nmi_var_float = 3.14\nmi_bool = True\nmi_var_str = \"un string\"\nmy_var_str_2 = 'otro string'\n\nMI_CONSTANTE = \"CONSTANTE QUE NO DEBE VARIAR\"\n\nprint (\"Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/super490.py",
    "content": "#  URL del sitio web \n# https://www.python.org/\n\n\n# Comentario de una línea\n\n'''\nComentario\nde varias líneas con\ncomillas simple\n\n'''\n\n\"\"\"\nComentario\nde varias líneas con\ncomillas dobles\n\n\"\"\"\n\n# Creacion de una variable\n\nnueva_variable = 'Hola mundo'\n\n# Tipos de variables\n\nnombre = \"Manuel\"  # string\nedad = 28  # integer\naltura = 1.72  # float\nes_estudiante = True  # booleano\nhoy_es_lunes = False # booleano\n\nprint (\"¡Hola, Python!\")\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/tecfer.py",
    "content": "# #00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n#### Dificultad: Fácil | Publicación: 26/12/23 | Corrección: 02/01/24\n\n## Ejercicio\n'''\n/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n'''\n## Solución\n\n# Url del lenguaje  https://www.python.org/  -> los comenterios simples empiezan por \"#\" Este es una línea de comentario.\n'''\nLo que es encuentre en medio de las commilas es un bloque de comenterio, \npuede ser de múltiples líneas. \n'''\nvariable =''\nCONSTANTE = 10 # el lenguaje no soporta constantes pero por convención se utilizan las mayúsculas.\n\n#el tipado de datos en python es dinámico\nboobleano = True # False    \nentero = 15\nfloat = 1.2\ncomplejo = 2 + 5j\nstring = \"Esto es una cadena\"\n\n\nprint(\"¡Hola, python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/tekatoki.py",
    "content": "'''\nExerise #00: Sintaxix, variables, tipos de datos y hola mundo\n- Create a comment and insert your programming language official website's URL\n- Represent the different ways to create comments in your chosen language\n- Create a variable and a constant\n- Create variables representing all diferent primate data of your language\n- Print at the terminal: \"Hello, [your_language]\"\n'''\n\n# Python's official website: https://www.python.org/\n\n# This is single-line comment on python\n'''\nThis\nis \na \nmulti-line\ncomment \non \npython\n'''\n\nmutable_var = 23\nCONSTANT_VAR = 3\n\nint_var : int = 2\nfloat_var : float = 3.14\nboolean_var : bool = True\nstring_var : str = 'python'\n\nprint(f'Hello, {string_var}!')\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/therealinfinity2.py",
    "content": "\"https://python.org\"\n\n#comentario en una linea\n\n\"\"\"\nesto es un \ncomentario en\nvarias lineas\n\"\"\"\n\nmy_variable= \"mi variable\"\nmy_variable= \"nuevo valor de mi variable\"\n\nMY_CONSTANT= \"mi constante\"\nMY_CONSTANT= \"is real\"\n\nmy_int= 1\nmy_float= 1.5\nmy_bool= True\nmy_bool= False\nmy_string= \"cadena de texto\"\nmy_other_string= \"otra cadena de texto\"\n\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/thezhizn.py",
    "content": "# https://www.python.org/\n\n#hola esta es una forma de usar poner los comentarios \n\n\"\"\" este es \nun comentario \nen varias lineas\n \"\"\"\n\n''' este tambien es\nun comentario en varias \nlineas '''\n\n# variable y constante \nmy_name = \"thezhizn\"\nMY_AGE = \"24 years\"\n\n# tipos de datos primitivos \nmy_str =\"hola\"\nmy_int = 4\nmy_float = 2.4\nmy_bool = True \nprint(\"hola python\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/tic4.py",
    "content": "# Pagina Oficial de Phyton = https://www.python.org/\n\n#Comentario de una linea en phyton\n\"\"\"\nComentario en varias\nlineas\n\"\"\"\n\nmy_variable= \"mi variable\"\n\nMY_CONSTANT = \" MI CONSTANTE\"\n\nint= 0\nint= -16\nint= 6\n\nfloat= 3,14\nbool= true\nbool= false\n\nstring= \"mi comentario\"\n\nprint(\"¡hola,Phyton!\") \n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/tito-delpino.py",
    "content": "# EJERCICIOS:\n\n'''Crea un comentario en el código y coloca la URL del sitio web oficial del\nlenguaje de programación que has seleccionado.'''\n\n# Sitio web oficial del leguaje que utilizo : https://www.python.org/\n\n'''Representa las diferentes sintaxis que existen de crear comentarios\nen el lenguaje (en una línea, varias...).'''\n# opcion1 - comentario en una linea\n'opcion2 - comentario en una linea'\n\"opcion3 - comentario en una linea\"\n\"\"\"opcion4  - comentario en una linea\"\"\"\n\n'''opcion1-\ncomentario en\nvarias lineas'''\n\n\"\"\"opcion1-\ncomentario en\nvarias lineas\"\"\"\n\n# Crea una variable (y una constante si el lenguaje lo soporta).\nvar = 2 # variable\nVAR = 10 # constante\n\n# Crea variables representando todos los tipos de datos primitivos\ninteger_int = 30 # numero entero\ninteger_int2 = -30 # numero entero\ninteger_int3 = 30 # numero entero\ndecimal_float = 3.4 # numero con decimales\nstring = 'esto es un string' # cadena de texto\nbooleano_positivo = True # variable con valor booleana Verdadera\nbooleano_negativo = False # variable con valor booleana Falsa\n\n#  * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nprint(\"Hola, Python\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/tobiBordino.py",
    "content": "# https://www.python.org/\n\n# Comentario de una línea\n\n'''\nComentario \nen \nvarias\nlíneas\n'''\n\n\"\"\"\nSegunda \nforma\nde\nhacer\ncomentario \nen \nvarias\nlíneas\n\"\"\"\n\n# Creación de una variable\nmy_variable = \"Mi variable\"\n\n# Creación de una constante (en Python no existen las constantes porque todo puede variar)\nMY_CONSTANT = \"Mi constante\" # convención de CTE en mayúsculas\n\n# Datos primitivos en Python\nmy_int: int = 1 # int\nmy_float = 1.5 # float\nmy_str = \"Hola mundo\" # str\nmy_bool: bool = True # bool\n\n# Imprimir en consola\nprint(\"¡Hola, Python!\")\n\n# Tipo de dato de cada variable\nprint(type(my_int))\nprint(type(my_float))\nprint(type(my_str))\nprint(type(my_bool))"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/toral24.py",
    "content": "# https://www.python.org/\n\n# Comentario de una linea.\n\n\"\"\"\"Comentario\nde\nvarias\nlíneas\n\"\"\"\n\n# En Python no existen constantes, por lo que se crea una variable.\n\nVariable1 = \"Primera variable del roadmap\"\n\n# Tipos de datos primitivos.\n\nCadena = \"Python\"\nEntero = int(3)\nFlotante = float(3.14)\nBooleano = True\n\n# Impresión por pantalla de hola Python.\n\nprint(\"¡Hola, \"+Cadena+\"!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/trasherzzzz.py",
    "content": "#https://www.python.org/\n#comentario en una sola linea \n\"\"\" \nOpcion1\nEsto es un \n comentario en varias lineas \"\"\"\n\n'''\nOpcion2\nDe igual forma estas comillas \nsimples son para un comentarios \nen varias lineas\n'''\nmi_variable= \" mi variable  \"\nmi_variable= \"Nuevo valor de mi variable \"\n\nMI_CONSTANTE =\"Mi constante \"# aunque se pueda modificar , lo usamos por convencion\n\nmy_int=1 # valor enetero\nmy_float=5.5 #valor con punto decimal \nmy_bool=True \nmy_bool=False\n#booleanos para cierto o falso \nmy_string= \" mi cadena de texto \"\nmy_other_string= \" mi otra cadena de texto \"\n\n#para imprimir se usa el print \nprint(\"¡Hola, Python!\")\n\nprint(type(my_int))\nprint(type(my_float))\nprint(type(my_bool))\nprint(type(my_string))"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/troleomotor10.py",
    "content": "# https://www.python.org/\n\n# Esto es un comentario en un linea\n\n\"\"\"\nEsto es un comentario en python,\npero en diferentes \nlineas :)\n\"\"\"\n\n# Variables\nnumber = 33\nfloat = 4.5\nstring = \"python\"\nbool = True\nnotype = None\n\nlist = [2, 3, 7, 9, 1, 4, 7]\ntuple = (2, \"Mouredev\", 56.8)\ndictionary = {\n    \"Jose\": 34,\n    \"Manuel\": 56,\n    \"Luis\": 22\n}\n\n# Constantes (En python no existen. Para diferenciarlos se suele usar las constantes)\nPI = 3.14\n\n# Imprimimos por pantalla\nprint(f'¡Hola, {string}!')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/txuky.py",
    "content": "# https://www.python.org/\n\n# Aqui empieza el ejercicio\n\n'''\nla URL de la pagina oficial de \nPython es https://www.python.org/\n'''\n\"\"\"\nAsi tambien puedo \nescribir un comentario\n\"\"\"\n\nmy_first_variable = 'txuky'\nmy_first_constant = ('txuky') # una tupla, que entre sus condiciones esta el que el elemento no se puede modificar\nMY_CONSTANT = \"constante\" #aunque se puede cambiar por convencion seria una constante\n\n\n# tipos de variables\n\nmy_boolean = True #boolean\nmy_string = 'txuky' #string\nmy_age = 57 #integer\nmy_height = 1.70 #float\nmy_compex_number = 1 + 3j #complex\nmy_list = ['francesc', 'more'] #list\nmy_tuple =(12, 3.1415, 9.2) #tuple\nmy_set = {3.45, 4.6, 5.75 } #set\nmy_dict = {'Potencias' : 'kW', 'Consumos' : 'kW/h'} #dict\n\nprint('Hola Python')\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/v0l0v.py",
    "content": "  GNU nano 8.0       v0l0v.py                   \n# https://www.python.org/\n\n# Sintaxis de comentario en una linea\n\n''' Sintaxis de\ncomentario en dos\no mas lineas  '''\n\n# variables\nedad = 44\n\n# constante en python, no existe.Convención, lo>\nVAR_CONSTANTE = 3.14\n\n# datos primitivos\n\nvar_int = 12\nvar_float = 12.5\nvar_string = \"python\"\nvar_boolean = True\nvar_complex = 4j + 5\nvar_lista = [1,2,3,4,5,6]\nvar_tupla = (7,8,9,10)\nvar_set = {11,12,13,14,15}\nvar_dict = {0:'zanahoria', 1:'papas', 2:'pollo'}\n# imprimir\nprint('¡Hola python!')\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/varoblanco.py",
    "content": "print(\" URL: https://www.python.org/\")\n\n#Solo 1 línea de comentarios\n\n\"\"\"\nVarias líneas de comentarios\nVarias líneas de comentarios\nVarias líneas de comentarios\n\"\"\"\n'''Comentario en variad líneas\nVarias\nVarias'''\n\na=1\n\nPECES = 2 #Por conveccion las mayus son cte en python pero no existen ctes como tal\n\nprint(a)\n\nentero = 1\nflotante = 1.2\ntexto =  \"string\"\ncheck = True\n\nprint(\"Hola, Python\")\n\nprint(type(entero))\nprint(type(flotante))\nprint(type(texto))\nprint(type(check))"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/vicman-182.py",
    "content": "\"\"\"\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n\"\"\"\n\n# https://www.python.org/\n\n# Comentario en una linea.\n\n\"\"\"\nEsto es un comentario\nen varias lineas\n\"\"\"\n\n'''\nEsto tambien es un \ncomentario en varias lineas\n'''\n\nmi_variable = \"Esta es una variable\"\n\nMI_CONSTANTE = \"Esto es una constante\" # por convencion ya que el lenguaje python no posee constantes.\n\nmi_string = \"Esto es un String\" # Variable que representa el tipo de dato primitivo String\n\nmi_entero = 10 # Variable que representa el tipo de dato primitivo integer int\n\nmi_flotante = 3.1416 # Variable que representa el tipo de dato float\n\nmi_booleano = True # Variable que representa el tipo de dato Boolean\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/victor-Casta.py",
    "content": "# Python https://www.python.org/\n\n#Comentarios en una linea\n\"\"\"\ncomentarios\nen varias\nlineas\n\"\"\"\n\nmy_variable = 'Hola Python'\n\ncadenas = 'cadenas de texto'\nenteros = 7\nis_boolean = True\nflotantes = 2.5\nnulo = None\nlistas = [1,2,3,4]\ntuplas = (1,2,3,4)\nsets = {1,2,3,4}\ndiccionarios = {\n  'first': 1,\n  'second': 2,\n  'third': 3,\n}\n\nprint('¡Hola, Python!')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/victorfer69.py",
    "content": "#https://www.python.org/\n\n#COMENTARIOS\n\n#Esto es un comentario de una línea\n\n\"\"\"\nEsto es un comentario\nde varias líneas\n\"\"\"\n\n'''\nEsto es un comentario \nde varias líneas\n'''\n\n#VARIABLE/CONSTANTE\n\nvariable = \"Esto es una variable\"\nCONSTANTE = \"Esto es una cosntante\"\n\n#TIPOS PRIMITIVOS\n\na = 1                           #Esto es un int\nb = 1.5                         #Esto es un float\nc = True                        #Esto es un boolean\nd = False                       #Esto es un boolean\ne = 'a'                         #Esto es un char\nf = \"Cadena de caracteres\"      #Esto es un string\n\n#IMPRIMIR MENSAJE\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/vicvilla30.py",
    "content": "# Crea un comentario en el código y coloca la URL del sitio web oficial del\n# lenguaje de programación que has seleccionado.\n\n#Esta es la URL de Python www.python.org\n\n# Representa las diferentes sintaxis que existen de crear comentarios\n# en el lenguaje (en una línea, varias...).\n\n# Hola \n\n\"\"\"\nHola\nEsto es un \ncomentario\n\"\"\"\n\n\"Esto es otro comentario\"\n\n# Crea una variable (y una constante si el lenguaje lo soporta)\n\nmy_variable = \"Valor de mi  variable\"\n\nmy_constante = 25\n\n# Crea variables representando todos los tipos de datos primitivos\n# del lenguaje (cadenas de texto, enteros, booleanos...)\n\nmy_int = 5\nmy_float = 5.5\nmy_boolean = True\nmy_boolean = False\nmy_string = \"Mi texto\"\n\n#Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]\n\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/vmarialuzm.py",
    "content": "# https://www.python.org/\n\n# Este es un comentario de una línea\n\n\"\"\" Este es un comentario de varias \nlíneas \"\"\"\n\nvariable_ejemplo0 = 0\n\nvariable_texto = \"texto\"\nvariable_numero = 1\nvariable_booleano = True\nvariable_lista = [1, 2, 3]\nvariable_diccionario = {\"num1\": 1, \"num2\": 2}\nvariable_tupla = (1, 2, 3)\nvariable_conjunto = {1, 2, 3}\n\nprint(\"¡Hola, python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/vmatmarco.py",
    "content": "# EJERCICIO 1 (Página oficial de Python)\n# https://www.python.org/\n\n\n# EJERCICIO 2 (Tipos de comentarios)\n# Comentario en una línea\n\n\"\"\" \nComentario\nen varias líneas\n\"\"\"\n\n\n# EJERCICIO 3 (Variables y constantes)\n\nvariable = \"Esto es una variable\"\nCONSTANTE = \"Esto es una constante\" # En python no existen las constantes. Sin embargo, por convención, se escriben en mayúsculas.\n\n\n# EJERCICIO 4 (Tipos de datos primitivos)\n\n# Enteros\nentero = 5\n\n# Flotantes\nflotante = 5.5\n\n# Cadenas \ncadena = \"Esto es una cadena\"\n\n# Booleanos\nbooleano = True\n\n\n\n# EJERCICIO 5 (Imprimir por pantalla)\n\nprint(\"!Hola Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/wallsified.py",
    "content": "# https://www.python.org/\n# Esto es un comentario de una linea. \n\n\"\"\"\nY esto un comentario \nmultilinea. \n\"\"\"\n\n'''\nTambién se puede hacer con comillas simples. \n'''\n\n\"\"\"\ntodo en python es una variable, pero por convención se usa snake_case en minúsculas para variables y \nen mayúsculas para \"constantes\".\n\"\"\"\n\nlanguage_name = \"Python\" # es de tipo String, osea, cadena,\nRANDOM_CONSTANT = 1234567890 # Un int, un entero\nrandom_float = 12.334 # Un float, un valor decimal\nrandom_bool = True # Un booleano, verdadero o falso\n\nprint(\"Hola, \" + language_name + \"!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/walyfigueroa.py",
    "content": "#Primero tenemos que escribir un comentario, estos comentarios no se ejecutan\n\n\"\"\"\nEsto es un comentario en varias lineas \nNo necesito poner un # para cada linea de código\n\n\"\"\"\n\n#Crea una variable y una constante\n\nmi_variable = \"hola mundo\"\n\nmi_variable = \"Esto es un enlace\"\n\nMI_CONSTANTE = \"No puede cambiar\" #No existen constantes en Python. Pero se pone en mayusculas para que no cambiar el valor. \n\n\n\n#Crear variables con todos los tipos de datos. Datos primitivos del lenguaje\n\nmi_booleano = True\nmi_string = \"Soy un string\"\nmy_int = 30\nmy_float = 1.70 #variable de tipo decimal\n\nprint(\"Hola Python\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/warclimb.py",
    "content": "\n\"\"\"\n * EJERCICIO 1:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n \"\"\"\n\n# Python: https://www.python.org/\n\"\"\"\nEste es un comentario de varias líneas\n\n\"\"\"\n\n# creación de variable de prueba\nvariable_prueba = 420 # Python no tiene constantes\n\n# Tipos de datos primitivos\nstring = \"Hola chat\"\ninteger = 69\nfloat = 4.20\nboolean = True\nNoneType = None\ncomplex_number = 50 + 9j\n\n# imprimir por terminal\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/willianl731.py",
    "content": "# Sitio oficial de python: https://www.python.org/\n#hay 2 formas principales de crear comentarios en python:\n# 1. Comentarios de una sola línea: Se utilizan el símbolo # al inicio de la línea.Se usan para explicar una línea específica de código o para desactivar código temporalmente.\n#Para explicar el propósito de una variable.\n#Para describir qué hace una función breve.\n#Para \"desactivar\" una línea de código sin borrarla (debugging).\n# # Ejemplo: Esto es un comentario de una línea\n\nprint(\"Hola mundo\")  # Este comentario explica esta línea en específico\n# La línea de abajo está \"comentada\" y no se ejecutará\n# print(\"Esto no se imprimirá\")\n\n# 2. Comentarios de varias líneas o docstrings: Se encierran entre comillas triples (''' o \"\"\"). Se usan principalmente para documentar módulos, clases, funciones o métodos.\n#ejemplo: Documentar una función o clase.\ndef mi_funcion():\n    \"\"\"\n    Esta es una docstring que explica la función.\n    Puede tener múltiples líneas y se usa para documentar.\n    \"\"\"\n    return True\n\n'''\nEsto también es una docstring (pero no es la forma convencional para comentar).\nSe usa más para documentación que para comentarios temporales.\n'''\n#variables: (puede cambiar), minusculas_con_guiones_bajos\nedad = 25\nnombre = \"Ana\"\nprecio_producto = 19.99\nesta_activo = True\n\n# \"Constantes\" : (por convención, no se deberían cambiar),MAYUSCULAS_CON_GUIONES_BAJOS\nPI = 3.1415926535\nIVA = 0.21\nURL_BASE = \"https://mi-api.com\"\nMAXIMO_INTENTOS = 3\n\n# Las usamos en cálculos\nradio = 5\narea_circulo = PI * radio ** 2\n\n# 1. CADENA DE TEXTO (string - str)\n# Secuencia de caracteres: entre comillas simples o dobles\nnombre = \"Ana García\"\nmensaje = 'Hola, ¿cómo estás?'\n\n# 2. ENTERO (integer - int)\n# Número sin parte decimal\nedad = 25\ncantidad_productos = 10\n\n# 3. FLOTANTE (float)\n# Número con parte decimal\nprecio = 19.99\npi = 3.141592\n\n# 4. BOOLEANO (bool)\n# Solo puede ser True (Verdadero) o False (Falso)\nes_mayor_de_edad = True\ntiene_descuento = False\n\n# 5. COMPLEJO (complex)\n# Número con parte real e imaginaria (se usa en matemáticas avanzadas)\nnumero_complejo = 3 + 4j\nimpedancia = 5 + 2j\n\n# 6. NONE TYPE (NoneType)\n# Representa la ausencia de valor\nresultado = None\ndato_faltante = None\n\nprint(\"¡Hola , Python!\")\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/willr30.py",
    "content": "\n\n#Esto es un comentario en python\n#Esto es otro comentario\n\n#Link oficial: https://www.python.org/\n\nvariable = \"Soy una variable\"\nCONSTANTE = 123456789\n\ncadena_de_texto =\"Mi mamá me ama\"\nnumero_entero = 30\nnumero_decimal = 3.14\nbooleano = False\n\n\nprint(\"¡Hola, Python!\")\n\n#####\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/wilsonbarrera.py",
    "content": "#https://www.python.org/\n\n\n'''este es un comentario donde pongo\nalgunas lineas y no debo tener problemas\npara ubicar por ejemplo la web oficial\nde python que es: https://www.python.org/ '''\n\n\"\"\"este es un comentario donde pongo\nalgunas lineas y no debo tener problemas\npara ubicar por ejemplo la web oficial\nde python que es: https://www.python.org/ \"\"\"\n\n\n\nuna_variable = \"con un string interno\"\nUNA_CONSTANTE = 3.1416 #no hay constantes en python pero por convención pongo el nombre de la variable con letras mayúsculas para identificarlo \n\n# Crea variables representando todos los tipos de datos primitivosdel lenguaje (cadenas de texto, enteros, booleanos...).\n#variable con string\nvariable_string = \"hola\"\n\n#variable entero\nvariable_entero = 10\n\n#variable flotante\nvariable_flotante = 4.8\n\n#variable booleano\nvariable_booleano = True\n\n#Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/worlion.py",
    "content": "# https://www.python.org/\n\n# Comentario de una línea\n\n\"\"\"\nEsto es un comentario en varis líneas\n\"\"\"\n'''\nEsto es otro comentario en varias líneas\n'''\n\nmy_variable = \"Mi variable\"\nMY_CONSTANT = \"Mi constante\" # Por convencion, las constantes se escriben en mayúsculas\n\nmy_integer = 42\nmy_float = 3.14\nmy_boolean = True\nmy_string = \"¡Hola, Python!\"\n\nprint(type(my_integer))\nprint(type(my_float))\nprint(type(my_boolean))\nprint(type(my_string))\nprint(my_string)  # Imprime por terminal el texto: \"¡Hola, Python!\""
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/x1ph3r.py",
    "content": "#https://www.python.org/\n\n#hola parcer@s\n\"\"\"\nHola cracks\nparceros\n\"\"\"\n\n'''\nHola cracks\nparceros\n'''\n#VARIABLES\n#en python para crear varaiblaes no hace falta un nombreclave soloseasigna el nombre seguido del signo(=)\n\"\"\"\npara separar palabrasse usa el guion bajo (_).\nestees conocidocomo snake_case siempre se debn separarpor guin bajo y lo ideal tambien en minuscula\nejemplo:\nuser_name\nlista_de_utiles\n\"\"\"\n'''variabletio cadena de texto(string)= se utiliza para almacenar secuncia de caracteres, que pueden incluir:\nletras, simbolos y espacios y se deben encerrar en comilla doble o sencilla\nejemploe:  my_variable = \"Kain\"\n'''\nmy_variable = \" Hola, Como estan parcer@s?\"\n#en python no existen las constantes solo existen variables y pueden mutar o cambiar\n# las variables tambien pueden cambiar de valor\nmy_variable = 'ahora esta sera mi nuevo valor'\n\n\"\"\"\npor convecnion en python para sugerir una constante el nombre se coloca en mayuscula para decir que nopuede cambiar\nejemplo\nMY_CONSTANT = \"crack\"\n\"\"\"\n#tipos de datos\n\n#cadena de texto (string)\nuser_name = \"kkknnnn\"\n\n#enteros int\nnumber = 10\nmy_number =-4\n\n#flotantes(float)\nmy_float = 3.1416\nmy_float1 = -4.32\n\n#booleano (bool) verdadero o falso)\nmy_bool = True\nmy_bool = False\n\n#imprimir texto porconsola se utiliza print()\nprint \"¡Hola, Python!\"\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/xCoreYx0.py",
    "content": "#https://python.org \n\n\"\"\"\n Esto es un comentario\n de más \n líneas.\n Aunque en Python se pueden usar # repetidas veces.\n\"\"\"\n\npais = \"Perú\"\nCIUDAD = \"Lima\" #Python no cuenta con costantes como tal pero se usan mayúsculas para identificarlas\n\nstring = \"Python\" #string\nint = 13 #Número entero\nfloat = 4.23 #Número decimal\nboolean = True #True or false\nlist = [20, 32, 49, 12] #Lista\ntuple = (20, 13, 32) #Tupla\ndict = {\"nombre\": \"Javier\", \"edad\": 16} #Diccionario\nset = {10, 22} #Conjunto de elementos únicos.\n\nprint(\"¡Hola \" + string + \"!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/xalejandrow.py",
    "content": "'''\n EJERCICIO:\n - Crea un comentario en el código y coloca la URL del sitio web oficial del\n   lenguaje de programación que has seleccionado.\n - Representa las diferentes sintaxis que existen de crear comentarios\n   en el lenguaje (en una línea, varias...).\n - Crea una variable (y una constante si el lenguaje lo soporta).\n - Crea variables representando todos los tipos de datos primitivos\n   del lenguaje (cadenas de texto, enteros, booleanos...).\n - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n'''\n\n#https://www.python.org/\n\n#one line\n'''\nmutliple line comments \nin python\n'''\n\n#variable\ni=100 #integer\ntext='Hello World' #string\n\n#constantes\nCONSTANTE = 10 #por convencion en mayuscula\n\n#tipos de datos en python\n\n#integer\nyear=2021\n\n#float\npi=3.1416\n\n#boolean\nis_boolean= True\n\n#string\ntext=\"this is a text variable\"\ntext2='this is a text variable other form'\ntext_multi_line=\"\"\"\nthis is a multiple line\ntext variable\nin python\n\"\"\"\n#null\nvar_nulo=None\n#lists\nlista=[1,\"dos\",3,\"cuatro\",5]\n\n#tuple\ntupla=(1,2,3,4,5)\n\n#conjunto - Set\nconjunto={\"negro\",\"cyan\",\"magenta\",\"amarillo\"}\n\n#diccionary\ndicc={\n    \"nombre\":\"Juan\",\n    \"edad\":40,\n    \"casado\":True,\n    \"list_hijos\":[\"Maria\", \"Pedro\"],\n    \"var_tup\":(-1,\"tres\",10,True)\n}\n\n#Set\n\n\nprint(\"¡Hola, Python!\")\n#Another way\n'''lang='Python'\nprint(\"¡Hola,\", lang ,\"!\")'''"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/xcortes.py",
    "content": "#00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n# Sitio Oficial Python https://www.python.org/\n\n# Sintaxis para realizar comentarios en Python\n# Para una sola línea se usa el simbolo numeral '#'\n\n'''\nPara comentarios de varias líneas se usa:\n(') Comilla sensilla, \ncomo se esta usando en este ejemplo   \n'''\n\n\"\"\"\no también para comentarios de varias l´neas se usa:\n(\") Comilla doble,\ncomo se esta usando en este ejemplo\n\"\"\"\n\n# Variables\nnombre = 'Ximena Cortes' # Variable tipo String\nlenguaje = 'Python' # Variable tipo String\nyear = 2024 # Variable tipo int\nestatura = 69.5 # Variable tipo float\ninteres_en_python = True # Varuiable de tipo booleano \nNUM_PI=3.1416 #Variable tipo Constante\n\nSaludo = '¡Hola, Python!'\nSaludo2 = 'Hola', lenguaje\nprint(Saludo)\nprint(Saludo2, '\\n')\n\nprint(\"=== Imprimir tipo de variables y constante ===\")\nprint ('==============================================')\nprint(type(nombre), '->', nombre)\nprint(type(lenguaje),'->', lenguaje)\nprint(type(year), '->',year)\nprint(type(estatura), '->', estatura)\nprint(type(interes_en_python), '->', interes_en_python)\nprint(type(NUM_PI), 'Constante ->',NUM_PI)\nprint ('\\n ==============================================')\nprint (' ==============================================')\n\n\n#Autor: Ximena Cortes\n'''\n/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n \n'''"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/xebaztiandev.py",
    "content": "# Programming challenge 00 - Python - @XebaztianDev\n\n# Url of the official python website:\n# https://www.python.org/\n\n\n# SYNTAX TYPES FOR COMMENTS IN PYTHON :)\n\n# This is a single line comment.\n\n# This is a comment\n# in several lines.\n\n\"\"\"\nThis is a special type of comment.\nIts called docstrings: Use triple quotation marks to describe or document your code.\nWe can do this in classes, methods, attributes, interfaces, etc.\n\"\"\"\n\nmyVariable = 10 # Here a variable is created. All variables must always be initialized with a value.\n\n\nMY_CONSTANT = 3.1416 # A variable cannot be declared as a constant directly, but by convention, uppercase letters and underlined letters are used to understand what a constant represents, but the value can still be changed.\n\n\n# BASIC OR PRIMITIVE DATA TYPES\nmyString = \"Hi, there!.\" # Variable defined as string data type\nmyInteger = 10 # Variable defined as integer data type\nmyFloat = 10.2 # Variable defined as floating point data type\nmyBoolean = True # Variable defined as Boolean data type, only accepts true or false\nmyNone = None # Variable that does not yet have a defined value\n\n# With this line we can print a variable on our terminal\nmessage = \"¡Hola, python!\"\nprint(message)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/xemita007.py",
    "content": "'''\n# #00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n> #### Dificultad: Fácil | Publicación: 26/12/23 | Corrección: 02/01/24\n\nAuthor: Alfredo Aburto Alcudia: https://github.com/alabacw74\n\n## Ejercicio\n\n```\n/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n```\n'''\n\n\n#https://www.python.org/\n\n\"\"\"\"\nEste comentario \nes \nde varias lineas \n\"\"\"\n\n\n'''\nEsta es otra manera de comentar \n\nentre lineas\n\n'''\n\nmy_variable=\"hola mundo\"\nCONSTANTE=\" mi variable constante\"\n\n#my_variable=5 si lo desconmentamos no da error \n\ntry:\n    \n    print(int(my_variable))\n    print(type(my_variable))\n\nexcept ValueError:\n\n    print(\"da error por que no se puede convertir una cadena a int salvo que sea un numero\")\n\n#var primitivos\n    \nmy_variable=\"mi cadena de texto\"\n\nmy_variable=5 #entero\nprint(type(my_variable))\nmy_variable=1.5 #float\nprint(type(my_variable))\nmy_variable=True # boleano\nprint(type(my_variable))\n    \nprint(\"¡Hola, [python]!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/yablik.py",
    "content": "# Comentario en una línea\n\n\"\"\"\nEsto es un\ncomentario de varial líneas.\nTambién se puede con comillas simples\n\"\"\"\n\nprint(\"¡Hola desde Python!\")\n\nv_variable = \"Mi variable\"\nv_variable = \"Nuevo valor de mi variable\"\n\nMY_CONSTANT = \"Mi constante\"  # por convención\n\nv_int = 2\nv_float = 7.5\nv_bool = True #o False.\nv_string = \"Mi cadena de texto\"\notra_string = 'Mi otra cadena de texto'\n\nprint(type(v_int))\nprint(type(v_float))\nprint(type(v_bool))\nprint(type(v_string))"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/yah1r404.py",
    "content": "# URL DEL SITIO WEB DE PYTHON\n# https://www.python.org/\n\n# OTRAS FORMAS DE HACER COMENTARIOS\n\n\"\"\"\npaiton\npaiton\npaiton\npaiton???¿\"\"\"\n\n'''\ncaracoles,\ncaracoles,\ncaracoles,\ncaracoles,\n'''\n# VARIABLE\n\nhunter_x_hunter = \"besto shonen\"\n\n# CONSTANTE (python no tiene constantes reales, pero usualmente se escriben con mayúsculas)\n\nPI_ZZA = 3.1416\n\n# TIPOS DE DATOS PRIMITIVOS\n\nsabor_helado = \"helado de chocochips\"\nmil_menos_uno = 999\nhora = 11.11\nqueso = True\nquesillo = False\n\n# Hola, 'lenguaje q estoy usando'\n\nprint(\"hola, python!\")\n\n# ver q tipo de dato es una variable\n\nprint(type(sabor_helado))\nprint(type(mil_menos_uno))\nprint(type(hora))\nprint(type(queso))\nprint(type(quesillo))"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/yani-git.py",
    "content": "# Reto #00 - ¡Hola, mundo!\n# Solución de yani-git\n\nprint(\"¡Hola, mundo!\")\n\n# Reto #00 - ¡Hola, mundo!\n# Solución de yani-git\nprint(\"¡Hola, mundo!\")\n\nmy_variable = \"Mi variable \"\nmy_variable = \"Mi nuevo valor de mi variable \"\nMY_CONSTANT = \"Mi constante \"  # por convención\n\nmy_int = 1\nmy_float = 1.5\nmy_bool = True\nmy_string = \"Mi cadena de texto\"\n\nprint(\"Hola, python\")\nprint(type(my_int))\nprint(type(my_float))\nprint(type(my_bool))\nprint(type(my_string))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/ycanas.py",
    "content": "# https://www.python.org/\n\n\n# Hola, soy un comentario de una línea\n\n\n\"\"\"\nHola, yo tambien soy un comentario...\npero de varias lineas ;)\n\"\"\"\n\n\nmy_var = 'Hola, soy una variable'\nMY_CONST = 'Hola, soy una constante'\n\n\nmy_int = 1\nmi_float = 1.0\nmi_bool = True\nmi_str = 'Hola, soy un String'\n\n\nprint('¡Hola, Python!')\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/yeam-10.py",
    "content": "#Este es un comentario que muestra el sitio wrb oficial de python https://es.python.org/ \n\nvar = \"new var\"\nVAR_CONSTANT = 3.14\n\nvar_string = \"Esta es una cadena de texto\"\nvar_int = 32\nvar_boolean_true = True\nvar_b_false = False\n\n\nprint(\"aprendiendo Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/yenneralayon142.py",
    "content": "#Web oficial\n#https://www.python.org/\n\n\n#Comentarios\n\n# Esto es un comentario de una sola linea\n\n\"\"\"\nEsto \nes \nun \ncomentario de\nvarias \nlineas\n\"\"\"\n\n#VARIABLE\nnumero = 0\n\n\n#En python no existen las constantes, sin embargo si queremos declarar una hay que escribirla en mayuscula\nMY_CONSTANT = 49\n\n\n#Datos primitivos\n\nnumero = 0  # int\n\ncadena = \"Hola\" # string\n\nbool1 , bool2 = True, False # bool\n\ndecimal = 2.8  # float\n\n\n# Impresión en consola\n\nprint(\"¡Hola, Python!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/yharyarias.py",
    "content": "# Punto 1\n\n# https://www.python.org/\n\n\n# Punto 2\n\"\"\" \nhttps://www.python.org/\n\nEJERCICIO:\n - Crea un comentario en el código y coloca la URL del sitio web oficial del\n  lenguaje de programación que has seleccionado.\n - Representa las diferentes sintaxis que existen de crear comentarios\n  en el lenguaje (en una línea, varias...).\n - Crea una variable (y una constante si el lenguaje lo soporta).\n - Crea variables representando todos los tipos de datos primitivos\n  del lenguaje (cadenas de texto, enteros, booleanos...).\n - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\"\"\"\n\n# Punto 3\n\nvariable = 1\nCONSTANTE = 2\n\n# Punto 4\n\n# Entero int\nentero = 3\n\n# Flotante (float)\nflotante = 4\n\n# Cadena de caracteres (str)\nstring = \"Hola\"\n\n# Booleano (bool)\nboolean_true = True\nboolean_false = False\n\n# Numeros complejos\ncomplex_numero = 2 + 3j\n\n# Lista (list)\nlista = [1, 2, 3, 4]\n\n# Tupla (tuple)\ntupla = (1, 2, 3, 4)\n\n# Conjunto (set)\nconjunto = {1, 2, 3, 4}\n\n# Diccionario (dict)\ndiccionario =  {\"clave\": \"valor\"}\n\n# NoneType (None)\nnulo = None\n\n# Punto 5\nlenguaje = \"Python\"\nprint(f\"¡Hola, {lenguaje}!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/yoezequiel.py",
    "content": "# URL del sitio web oficial de Python: https://www.python.org/\n\n# Comentario en una línea\n\n\"\"\"\nComentario\nen\nvarias\nlíneas\n\"\"\"\n\n# Crear una variable\nmi_variable = \"Hola, Python!\"\n\n# Constante (en Python no hay constantes, pero por convención se usan mayúsculas)\nMI_CONSTANTE = 7\n\n# Tipos de datos primitivos\ncadena_texto = \"Hola, mundo!\"\nentero = 21\nflotante = 3.14\nbooleano = True\n\n# Imprimir por terminal\nprint(mi_variable)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/zalazarmartin.py",
    "content": "# Comentario simple\n\n'''\nComenario en varias lineas opcion 1\n'''\n\n\"\"\"\nComentario en varias lineas opcion 2\n\"\"\"\n\ndato_str = 'hola'\ndato_int = 10\ndato_float = 10.2\ndato_bool = True  # False\n\nprint(\"¡Hola, Python!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/zetared92.py",
    "content": "# https://www.python.org/\n\n# Comentario en una línea\n\n\"\"\"\nEsto es un comentario\nen varias líneas\n\"\"\"\n\n'''\nTambién se puede usar\nlas comillas simples \npara los comentarios \nen varias líneas\n'''\n\nmy_var = \"Variable\"\nmy_var = \"Variable actualizada\"\n\n# Constante por convención\nMY_CONSTANT = \"Constante\"\n\nmy_int = 2\nmy_float = 1.5\nmy_bool = True\nmy_bool = False\nmy_string = \"Esta es mi cadena de texto\"\nmy_second_string = 'Cadena de texto 2'\n\nprint(\"Hello, Python!\")\n\nprint(type(my_int))\nprint(type(my_float))\nprint(type(my_bool))\nprint(type(my_string))\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/zeti1231.py",
    "content": "# https://python.org\n\n# Tipo de comentario en una línea\n\n\"\"\"\nTipo de \ncomentario \nen varias \nlíneas\n\"\"\"\n\n'''\nTipo de \ncomentario \nen varias \nlíneas\n'''\n\nmy_variable = \"Mi variable\"\nmy_variable = \"Valor nuevo de mi variable\"\n\nMY_CONSTANT = \"Mi constante\" # Representación por convención\n\nmy_int = 4\nmy_float = 8.6\nmy_bool = True\nmy_bool = False\nmy_string = \"Mi cadena de texto\"\nmy_string = 'Mi otra cadena de texto'\n\nprint(\"Hola, Python!\")\n\nprint(type(my_int))\nprint(type(my_float)) \nprint(type(my_bool)) \nprint(type(my_bool)) \nprint(type(my_string)) \nprint(type(my_string)) \n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/ziellucio01.py",
    "content": "# https://www.python.org/\n\n# Comentario en una linea \n\n\"\"\"\nEsto tambien es \nun comentario\nen varias lineas \n\"\"\"\n\n''' \nEsto tambien es \nun comentario\nen varias lineas \n'''\n\nmy_variable = \"Mi variable\"\nmy_variable = \"Nuevo valor de mi variable\"\n\nMY_CONSTANT = \"Mi constante\" # por convención\n\nmy_int: int = 1\nmy_float = 1.5\nmy_bool = True\nmy_bool = False\nmy_string = \"Mi cadena de texto\"\nmy_other_string = 'Mi otra cadena de texto'\n\nprint(\"¡Hola, Python!\")\n\nprint(type(my_int))\nprint(type(my_float))\nprint(type(my_bool))\nprint(type(my_string))"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/python/zka21.py",
    "content": "#Comentario en una sola linea\n# https://www.python.org/\n\n#Comentario en varias lineas\n'''\n    https://www.python.org/\n    https://www.python.org/\n'''\n\n\"\"\"\n    https://www.python.org/\n    https://www.python.org/\n    https://www.python.org/\n\"\"\"\n\n#Creación de variables\nnombre = \"Zhaida\"\napellido = \"Cazasola\"\n\n#Creación de constantes\nLENGUAJE = \"Python\"\nEDAD = 21\nALTURA = 1.65\nES_ESTUDIANTE = True\n\nprint(\"¡Hola, \" + LENGUAJE + \"!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/r/Jandresalvar.r",
    "content": "### 00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\r\n\r\n## Ejercicio\r\n  \r\n# - Crea un comentario en el codigo y coloca la URL del sitio web oficial del\r\n#   lenguaje de programacion que has seleccionado.\r\n\r\n# - Representa las diferentes sintaxis que existen de crear comentarios\r\n#   en el lenguaje (en una linea, varias...).\r\n\r\n# - Crea una variable (y una constante si el lenguaje lo soporta).\r\n\r\n# - Crea variables representando todos los tipos de datos primitivos\r\n#   del lenguaje (cadenas de texto, enteros, booleanos...).\r\n\r\n# - Imprime por terminal el texto: \"!Hola, [y el nombre de tu lenguaje]!\"\r\n\r\n## Solucion\r\n\r\n# - La documentacion oficial del lenguaje R se encuentra en: https://cran.r-project.org/\r\n\r\n# - A diferencia de otros lenguajes, R solo permite añadir comentarios mediante\r\n#   el operador #. Si se quiere realizar comentarios de varias lineas, la solucion\r\n#   es simple, poner # en cada linea (como lo estamos haciendo en este caso).\r\n\r\n# - Para crear una variable en R, se pueden utilizar dos operadores, los cuales\r\n#   son equivalentes, es decir, no hay diferencia en utilizar uno u otro. El mas\r\n#   utilizado es <-, que representa una flecha y asigna lo que esta en la derecha\r\n#   al nombre que pongamos a la izquierda. El otro es operador es el famoso =, \r\n#   utilizado en la mayoria de lenguajes.\r\n#   Los nombres permitidos por las variables en R deben cumplir algunas condiciones:\r\n#   1.No pueden ser palabras reservadas del sistema.\r\n#   2.No pueden iniciar por numeros o guion bajo (_).\r\n#   3.Debe iniciar por una letra o un punto (.) y continuar con combinaciones de\r\n#   letras, numeros, punto, y guion bajo (_). No pueden contener espacios o guion\r\n#   medio (-).\r\n#   4.Los nombres de las variables son sensibles a mayusculas (var != Var).\r\n#   Finalmente, aplicando el operador <-\r\nmyVar <- \"Hello World!\"\r\n#   Y, aplicando el operador =\r\nmyVar2 = 5*4\r\n#   En R las constantes se tratan igual que las variables, con los mismos operadores.\r\n#   No es comun declarar constantes y hay algunas que vienen por defecto: pi, \r\n#   month.abb, month.name, LETTERS, letters.\r\n\r\n# - En R, los tipos de datos mas basicos que existen son:\r\n# 1. numeric\r\nc(10, 10.5, 105, 1)\r\n# 2. integer\r\nc(1L, 10L, 105L) # En donde la letra \"L\" declara que es un entero\r\n# 3. complex\r\nc(9 + 8i, 5i) # En donde la letra \"i\" declara la parte imaginaria\r\n# 4. character (a.k.a string)\r\nc(\"s\", \"R\", \"Hello\", \"12 + 4\")\r\n# 5. logical (a.k.a boolean)\r\nc(TRUE, FALSE)\r\n\r\n# la funcion class() permite evaluar el tipo (clase) de un objeto\r\nclass(c(10, 10.5, 105, 1))\r\nclass(c(1L, 10L, 105L))\r\nclass(c(9 + 8i, 5i))\r\nclass(c(\"s\", \"R\", \"Hello\", \"12 + 4\"))\r\nclass(c(TRUE, FALSE))\r\n\r\n# - En R se puede imprimir de dos maneras, simplemente escribiendo el identificador,\r\n#   numero u objeto en la consola y dar enter. Tambien esta la funcion print() que\r\n#   cumple la misma funcion.\r\n'Hola, R!'\r\nprint(\"Hola, R!\")\r\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/r/Micromantic.R",
    "content": "#\n  # ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n  # - Recuerda que todas las instrucciones de participación están en el\n#   repositorio de GitHub.\n#\n  # Lo primero... ¿Ya has elegido un lenguaje?\n  # - No todos son iguales, pero sus fundamentos suelen ser comunes.\n# - Este primer reto te servirá para familiarizarte con la forma de participar\n#   enviando tus propias soluciones.\n#\n  # EJERCICIO:\n# - Crea un comentario en el código y coloca la URL del sitio web oficial del\n#   lenguaje de programación que has seleccionado.\n# - Representa las diferentes sintaxis que existen de crear comentarios\n#   en el lenguaje (en una línea, varias...).\n# - Crea una variable (y una constante si el lenguaje lo soporta).\n# - Crea variables representando todos los tipos de datos primitivos\n#   del lenguaje (cadenas de texto, enteros, booleanos...).\n# - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n#\n  # ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n# debemos comenzar por el principio.\n#\n\n# Comentario\n# Este es el sitio web oficial de R https://cran.r-project.org\n\n# Una variable y una constante\n\nconstante <- 5\n\nvariable <- constante + 1\n\n# En R solo se utiliza el # para crear comentarios\n\n# Distintos datos primitivos\n\nun_numero <- as.numeric(5.5)\n\nun_entero <- as.integer(5)\n\nun_booleano <- TRUE\n\nun_caracter <- \"actuario\"\n\nun_complejo <- 5i\n\nun_raw <- raw(5)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/r/alabacw74.Rmd",
    "content": "---\ntitle: \"00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\"\nauthor: \"Alfredo Aburto Alcudia: https://github.com/alabacw74 roadmap-retos-programacion\"\ndate: \"`r Sys.Date()`\"\noutput:\n   html_document:\n    toc: true # Mostrar tabla de contenido en documento R markdown\n    toc_depth: 5 # Niveles de la tabla de contenidoo\n    toc_float: true # Mostrar la tabla de contenido en todo el documento\n    collapsed: true # Si solo queremos que muestre el nivel principal\n    smooth_scroll: true # Reflejar nuestra ubicación en barra de contenido\n    theme: journal # Estilo del documento\n    highlight: kate # Estilo del codigo\n    df_print: paged # Estilo para mostrar los datos\n    code_folding: show # Mostrar o no el código del documento\n---\n<div style=\"text-align: justify;\">\n## roadmap-retos-programacion\n## Ejercicio\n ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n  - Recuerda que todas las instrucciones de participación están en el\n    repositorio de GitHub.\n \n  Lo primero... ¿Ya has elegido un lenguaje?\n  - No todos son iguales, pero sus fundamentos suelen ser comunes.\n  - Este primer reto te servirá para familiarizarte con la forma de participar\n    enviando tus propias soluciones.\n \n  EJERCICIO:\n  - Crea un comentario en el código y coloca la URL del sitio web oficial del\n    lenguaje de programación que has seleccionado.\n  - Representa las diferentes sintaxis que existen de crear comentarios\n    en el lenguaje (en una línea, varias...).\n  - Crea una variable (y una constante si el lenguaje lo soporta).\n  - Crea variables representando todos los tipos de datos primitivos\n    del lenguaje (cadenas de texto, enteros, booleanos...).\n  - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n \n  ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n  debemos comenzar por el principio.\n  \n## 1. Comentarios\n\n```{r}\n# Esto es un comentario de una linea\n# En R no figura un caracter especial para comentarios multilinea, de ser \n# necesario seguimos los siguientes pasos\n#   1. Escribimos el texto que deseamos comentar\n#   2. Seleccionamos dichas lineas\n#   3. Ejecutamos el comando de teclado ctrl + mayus + c para windows o command\n#       para mac\n```\n\n## 2. Documentación\n\nEn R podemos encontrar la documentación en el siguiente link\n[Documentacion de R](https://stat.ethz.ch/R-manual/) en el encontraremos un \ncompendio de documentos que abordan el funcionamiento y aplicaciones de R, entre\nlos que destacaria los siguientes recursos en español traducidos por la \ncomunidad:\n\n  1. [R para principiantes](https://bookdown.org/jboscomendoza/r-principiantes4/)\n  2. [R para ciencia de datos](https://es.r4ds.hadley.nz/)\n  \n## 3. Variables y constantes\n\nEn R no hay una forma directa de construir constantes, se pueden utilizar \nconvenciones en la definicion de una variable para distinguirlas, por ejemplo\ndefiniendo el nombre de la variable con mayusculas\n\n```{r}\nCONSTANTE <- pi\nCONSTANTE\n```\n\n### Definiendo variables de los tipos primitivos\n\n#### Tipo entero\n\n```{r}\nvar_entera <- 5L\ntypeof(var_entera)\n```\n\n#### Tipo Numerico (punto decimal)\n\n```{r}\nvar_numerico <- 16.4546\ntypeof(var_numerico)\n```\n\n#### Tipo caracter\n\n```{r}\nvar_caracter <- \"Aprendiendo R\"\ntypeof(var_caracter)\n```\n\n#### Tipo entero\n\n```{r}\nvar_entera <- 5L\ntypeof(var_entera)\n```\n\n#### Tipo factor\n\n```{r}\n# Crear un vector de género\ngenero <- c(1, 2, 1, 1, 2, 2, 1, 2, 1, 1)\n\n# Convertir el vector a una variable de tipo factor\ngenero_factor <- factor(genero, levels = c(1, 2), labels = c(\"Femenino\", \"Masculino\"))\ntypeof(genero_factor)\n\n# Imprimir la variable de tipo factor\nprint(genero_factor)\n# Mostrar los niveles de la variable de tipo factor\nprint(levels(genero_factor))\n\n# Usar los niveles al extraer informacion del vector genero\nprint(genero_factor[2]) # Muestra el elemento 2 del vector genero y los niveles\n\nprint(as.character(genero_factor[2])) # Usa los niveles\n\n```\n\n#### Tipo logico\n\n```{r}\nvar_logica <- TRUE\ntypeof(var_logica)\n\n```\n\n#### Tipo NA y NULL\n\nNA representa datos perdidos y NULL ausencia de datos\n\n```{r}\nvar_nula <- NULL\ntypeof(var_nula)\n\n```\n\n```{r}\nvar_na <- NA\ntypeof(var_na)\n\n```\n\n```{r}\nprint(\"Hola, R\")\n```\n\n### Notas finales\n\nEn algunos casos al utilizar la funcion 'typeof()' se muestra por consola un \nresultado diferente al que hace referencia la sección en donde se encuentra\ndicha variable, pero si ejecutas los comandos en R studio podras ir a el\npanel del IDE 'Enviroment' donde muestra el tipo de cada una de las variables\nal ser ejecutadas, ahí podras ver que la correspondencia es adecuada.\n</div>"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/r/fidelysla.r",
    "content": "# ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n# - Recuerda que todas las instrucciones de participación están en el\n#   repositorio de GitHub.\n#\n# Lo primero... ¿Ya has elegido un lenguaje?\n# - No todos son iguales, pero sus fundamentos suelen ser comunes.\n# - Este primer reto te servirá para familiarizarte con la forma de participar\n#   enviando tus propias soluciones.\n#\n# EJERCICIO:\n# - Crea un comentario en el código y coloca la URL del sitio web oficial del\n#   lenguaje de programación que has seleccionado.\n# - Representa las diferentes sintaxis que existen de crear comentarios\n#   en el lenguaje (en una línea, varias...).\n# - Crea una variable (y una constante si el lenguaje lo soporta).\n# - Crea variables representando todos los tipos de datos primitivos\n#   del lenguaje (cadenas de texto, enteros, booleanos...).\n# - Imprime por terminal el texto: '¡Hola, [y el nombre de tu lenguaje]!'\n#\n# ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n# debemos comenzar por el principio.\n\n# ? Crea un comentario en el código y coloca la URL del sitio web oficial del\n# ? lenguaje de programación que has seleccionado.\n\n# https://www.r-project.org/\n\n\n# ? - Representa las diferentes sintaxis que existen de crear comentarios\n# ?   en el lenguaje (en una línea, varias...).\n\n# Comentario de una linea\n\n# \"\n# Comentarios de\n# varias lineas\n# (no recomendable)\n# \"\n\n# ? - Crea una variable (y una constante si el lenguaje lo soporta).\n\nmy_variable <- \"Hola\"\n\nMI_CONSTANTE <- 3.14\n\n# ? - Crea variables representando todos los tipos de datos primitivos\n# ?   del lenguaje (cadenas de texto, enteros, booleanos...).\n\nmy_char <- \"Hola Mundo\"\nmy_numeric <- 1.5\nmy_integer <- -20L\nmy_logical <- TRUE\nmy_complex <- 1 + 2i\nmy_raw <- charToRaw(\"ABC\")\nmy_null <- NULL\nmy_na <- NA\nmy_nan <- NaN\n\n# ? Imprime por terminal el texto: '¡Hola, [y el nombre de tu lenguaje]!'\n\nsprintf(\"¡%s R!\", my_variable)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/r/julian-arias.r",
    "content": "# 1. Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n\n# Esto es R y sirve demasiado para el análisis de datos. La web oficial de R es\n# https://www.r-project.org/\n\n# 2. Representa las diferentes sintaxis que existen de crear comentarios\n#   en el lenguaje (en una línea, varias...).\n\n# 3. Este lenaguaje de programación R me sirve mucho como Ingeniero Industrial porque puedo aplicar para\n# diferentes campos en la cadena de suministro, tales como planeación, transporte, demanda, almacenamiento\n\n# 4. Crea una variable (y una constante si el lenguaje lo soporta).\n\nvector1 <- c(12,5,80,63)\nconst <- pi\n\n# 5. Crea variables representando todos los tipos de datos primitivos\n#   del lenguaje (cadenas de texto, enteros, booleanos...).\n\nnombre_propio <- \"R\"\nnumero6 <- c(12,52,6)\nvalidador <- TRUE\n\n# - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\nprint(paste(\"Hola\", nombre_propio))\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/racket/luishendrix92.rkt",
    "content": "#lang racket\n\n#|-----------------------------------------------------------------+\\\n||                Racket - The programming language                ||\n||                                                                 ||\n|| Official Website: https://racket-lang.org/#racket-lang          ||\n|| Documentation: https://docs.racket-lang.org/quick/index.html    ||\n||                                                                 ||\n|| This is a multi-line (block) comment using the `#||#` syntax.   ||\n||                                                                 ||\n\\+-----------------------------------------------------------------|#\n\n; Single-line comments\n; --------------------\n; Unfortunately, there is no built-in way to provide documentation\n; comments in Racket, but we could define a custom macro to do so.\n\n; Top level variables in LISP-based languages are called definitions and they\n; can mutated in-place, and can't be re-defined unlike in other functional\n; languages. To mutate a definition we use the `set!` function although it's\n; heavily discouraged in any *Scheme* dialect (chicken, racket, MIT, etc).\n;\n; NOTE: Definitions created inside a function's body are local to it.\n(define x 5)\n; (define x (+ x 10)) <- compilation error\n(printf \"Value of definition 'x': ~a\\n\" x)\n(set! x (+ x 10)) ; In-place mutation of 'x'\n(printf \"Value of definition 'x' after mutation with set!: ~a.\\n\" x)\n\n; Local bindings with `let` and `let*`.\n(let ([grade1 95]\n      [grade2 100]\n      [grade3 66])\n  (printf \"Average of the grades ~a, ~a, and ~a is ~a.\\n\"\n          grade1 grade2 grade3\n          (exact->inexact (/ (+ grade1 grade2 grade3) 3))))\n\n; `let*` allows us to refer to earlier bindings inside the vector.\n(let* ([height 6.5]\n       [width 12.0]\n       [area (* height width)]) ; would give compilation error in a `let` block\n  (printf \"The area of a rectangle w=~am, h=~am is ~am^2.\\n\"\n          height width area))\n\n; Primitive data types\n; --------------------\n\n(displayln 42) ; Number (integer)\n(displayln -99.99) ; Number (float / inexact)\n(displayln 3/4) ; Number (fraction / exact)\n(displayln 1+2i) ; Number (imaginary)\n(displayln 3.3e+5) ; Number (scientific notation)\n(displayln \"Half Life 2 \\u03BB\") ; String\n(displayln true) ; Boolean (true -> #t)\n(displayln false) ; Boolean (false -> #f)\n\n; In LISP langauges, lists are important as well, and the language itself\n; is just data represented as unevaluated lists of symbols and values.\n; So, even though they're not considered \"primitive\", they are foundational.\n(displayln '(5 4 3 2 1 0)) ; List (quoted representation)\n(displayln (list 0 1 2 3 4 5)) ; List (constructed through the `list` function)\n\n(println \"¡Hola, Racket!\")\n\n#|\n  Output of running `racket luishendrix92.rkt`:\n  #############################################\n\n  Value of definition 'x': 5\n  Value of definition 'x' after mutation with set!: 15.\n  Average of the grades 95, 100, and 66 is 87.0.\n  The area of a rectangle w=6.5m, h=12.0m is 78.0m^2.\n  42\n  -99.99\n  3/4\n  1+2i\n  330000.0\n  Half Life 2 λ\n  #t\n  #f\n  (5 4 3 2 1 0)\n  (0 1 2 3 4 5)\n  \"¡Hola, Racket!\"\n|#"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/raku/edalmava.raku",
    "content": "# Sitio oficial: https://raku.org/\n\n# Comentario de una sola línea\n\n#`(\n Comentario de varias líneas comienzan con los caracteres #` seguidos de un par de estos caracteres\n (), {}, []\n)\n\n# Variables escalares comienzan con el signo dólar $\nmy $escalares;\n\n# Strings\nmy $raku_language = \"Raku\";\n\n# Números \nmy $entero = 42;\nmy $racional = 3/4;\nmy $ieee = 5.424E40;\n\n# Booleanos\nmy $true = True;\nmy $false = False;\n\n# Rangos\nmy $mi_rango = 1 .. 5;\n\nsay \"¡Hola, \" ~ $raku_language ~ \"!\\n\";     # Para concatenar cadenas se usa el signo ~\nprint \"¡Hola, $raku_language!\";             # Usando interpolación de variables\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/ruby/AkaiSombra.rb",
    "content": "\n# Author: Nicolas Romero https://github.com/AkaiSombra\n\n=begin\n * EJERCICIO:\n * 1. Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * 2. Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * 3. Crea una variable (y una constante si el lenguaje lo soporta).\n * 4. Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * 5. Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n=end\n\n# Ejercicio 1:\n\n# Sitio oficial de Ruby: https://www.ruby-lang.org/en/\n\n# Ejercicio 2:\n\n# Comentario de una linea en Ruby\n\n=begin\nComentario de varios lineas\nen Ruby\n=end\n\n# Ejercicio 3:\n\n# Variable\n\nparecido = \"Python\"\n\n# Al igual que Python Ruby no tiene Const\n# Pero si escribimos una variable en mayusculas\n# se toma como constante pero solo a nivel de semantica\n\nLENGUAJE = \"Ruby\"\n\n# Ejercico 4:\n# Datos primitivos\n\n# Entero(int)\nint_number = 2024\n\n# Numero con punto flotante(float)\nfloat_number = 3.14\n\n# Cadena de texto(string)\nstring = \"Cadena de texto\"\n\n# Booleanos (bool)\n\nboolean_true = true\nboolean_false = false\n\n# Simbolos (Symbol)\nsimbolo = :Symbol\n\n\n# Nulo (Null)\nvalor_nulo = nil\n\n# Ejercicio 5:\n\nputs \"¡Hola, #{LENGUAJE}!\"\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/ruby/domo2pdev.rb",
    "content": "\n=begin \nEJERCICIO:\n - Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n - Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n - Crea una variable (y una constante si el lenguaje lo soporta).\n - Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n=end\n\n# This is the official Ruby website.: https://www.ruby-lang.org/es/\n\n# Comment Syntax in Ruby:\n\n# This is a single-line comment.\n\n=begin \nThis is another comment, but \nthis time it spans multiple lines\n=end\n\n# Variable Definition: Variables can be defined and assigned values dynamically using the assignment operator (=).\ngreet = \"hello\"\nname = \"world\"\n\n# Constant Definition: Constants are variables that cannot be modified once assigned.\n# Constants are defined with the first letter in uppercase.\n\nPI = 3.1416\nMy_constant = \"Hi\"\n\n# Print to screen.:\nputs \"#{greet}, #{name}\"\n\ngreet = \"hola\" # It is possible to change the value of a previously defined variable.\nname = \"mundo\"\n\nputs \"#{greet}, #{name}\"\n\nmy_number = 8\nputs my_number\n\n# Data types in Ruby:\n\n# Strings:\nmy_string = \"This is a string.\"\n\n# Integers: Whole numbers without decimals, like 42 or -7.\nmy_integer = 42\n\n# Floats: Numbers with decimals, like 3.14 or -0.5\nmy_float = 3.14\n\n# Booleans: Logical values that can be either true or false.\nmy_boolean = true\nanother_boolean = false\n\n# Symbols: Immutable and unique values, like :name or :age, commonly used for labels or identifiers.\nmy_symbol = :name\n\n# Nil: Nil: Represents the absence of a value or \"nothing,\" it is a special value in Ruby, similar to null in other languages.\nmy_nil = nil\n\n# Printinng to screen the language name we are learning:\nlanguage_name = \"Ruby\"\nputs \"¡Hola, #{language_name}!\" # interpolation uses #{variable_name} to insert the value of the variable into the string\n\n# Printing to screen data types:\nputs \"String: #{my_string}\"\nputs \"Integer: #{my_integer}\"\nputs \"Float: #{my_float}\"\nputs \"Boolean: #{my_boolean}\"\nputs \"Another Boolean: #{another_boolean}\"\nputs \"Symbol: #{my_symbol}\"\nputs \"Nil: #{my_nil}\"\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/ruby/edalmava.rb",
    "content": "# https://www.ruby-lang.org/es/\n\n# *** Diferentes sintaxis de comentarios ***\n\n# 1. Comentario de una línea\n\nlenguaje = 'Ruby'\nputs \"Hola #{lenguaje}\" # 2. Comentario sobre línea de código\n\n=begin\n  3. Comentario de\n  varías líneas\n=end\n\n# *** Declaración de una variable y una constante ***\n\nmi_var = 'Esto es una cadena' # Variable Local\n\nMI_CONST = 3.1416 # Constante\n\n# Alcances de una variable (scope)\n=begin\n  Nombre comienza con | Alcance variable\n  $                   | Variable global\n  @                   | Variable de instancia\n  @@                  | Variable de clase\n  [a-z] o _           | Variable local\n  [A-Z]               | Una constante\n=end\n\n# *** Tipos de datos ***\n# Casi todo en Ruby es un objeto\n# Clases Números\n\nmi_entero = 5\nmi_float = 5.0\n\n# Cadenas\n\nmi_cadena = 'Esto es una cadena de texto'\nmi_cadena = \"Esto es otra cadena de texto\"\n\n# Booleanos: los valores true y false\n\nverdadero = true\nfalso = false # En Ruby solo se evalúa a falso el valor false y nil\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/ruby/kodenook.rb",
    "content": "# https://www.ruby-lang.org/es/\n\n# Comments\n\n# single-line comment\n\n=begin\n    this is a\n    multi-line comment\n=end\n\n# Variables and Constants\n\nvariable = 'variable'\nCONSTANT = 'constant' # constants must begin with upper, Constant and CONSTANT are the same\n\n# Data Types\n\nint = 1\nstring = 'string'\nbool = true\narray = ['saturday', 'sunday']\n\n# Print\n\nputs '¡Hola, ruby!'"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/ruby/m-hadz.rb",
    "content": "# https://www.ruby-lang.org/\n\n# Se usa para comentarios de una linea\n\n=begin\n  Se utiliza para comentarios\n  de multiples lineas\n=end\n\nvariable = \"ejemplo\"\n\nCONSTANTE = 3.14 # Las mayusculas se usan para indicar constantes\n\n=begin\n  Ruby no tiene datos de tipo primitivos, ya\n  que todo es un objeto, aunque podemos definir\n  los mas basicos\n=end\n\nstring = \"hola\" # Str\n\nentero = 3 # Int\n\nflotante = 3.14 # Float\n\n# Notese que no existe el objeto Boolean\nverdadero = true # TrueClass\nfalso = false # FalseClass\n\n\nsimbolo = :activo # Symbol\n\nvacio = nil # Nil\n\nrango = 0..10 # Range\n# Para imprimir se utiliiza la funcion puts\n\nputs \"¡Hola, Ruby!\"\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/ruby/miguelex.rb",
    "content": "# Documentación en https://www.ruby-lang.org/es/documentation/\n\n# Comentario en una linea\n\n=begin\n    Comentario\n    en varias\n    lineas\n=end\n\n# Declaramos una variable\nlenguaje = \"Ruby\"\n\n# Declaramos una constante\nPI = 2.1415\n\n# Ejemplos de tipos primitivos de Ruby\nnumero = 25\ncadena = \"Hola\"\narray = [1, 2, 3]\nhash = { \"uno\" => 1, \"dos\" => 2}\nhash2 = { :primero => 1, :segundo => 2}\nhash3 = { cabeza: 1, cola: 2}\nrango1 = 1..10\nrango2 = 0...99\nsimbolo = :simbolo\nverdadero = true\nfalso = false\nnulo = nil\n\nputs \"Hola #{lenguaje}!\"\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/ruby/nicolascampos-git.rb",
    "content": "# Web: https://www.ruby-lang.org/es/\n\n=begin\nesto es\nun comentario\nen\ncuotas\n=end\n\n# Declaracion de variables:\n\nvariable = \"hola\"\nVARIABLE_CONSTANTE = 'Ruby'\n\n# Declaracion de variables con datos primitivos:\n\nvar_int = 10\nvar_string = 'cadena'\nvar_float = 9,99\nvar_boolean = true\nvar_array = [ 1, 2, 3]\nvar_hash = { nombre: 'nicolas', apelido: 'campos' }\nvar_null = nil\nvar_symbol = :Symbol\n\n# Saludo desde el lenguaje:\nputs \"Hola #{VARIABLE_CONSTANTE}\"\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/ruby/palons29.rb",
    "content": "#https://www.ruby-lang.org/es/\r\n#Comentario de una linea\r\n=begin\r\nComentario de \r\nvarias lineas\r\n=end\r\n\r\n#Variable\r\nvariable = \"Variable\"\r\n#Constante\r\nCONSTANTE = \"Constantes\"\r\n\r\n#Variables\r\n#Variables global\r\n$variable_global = \"Variable global\"\r\n\r\n#Variables de instancia\r\n@variable_instancia = \"Variable de instancia\"\r\n\r\n#Variables de clase\r\n@@variable_clase = \"Variable de clase\"\r\n\r\n#Variables locales\r\nvariable_local = \"Variable local\"\r\n\r\n#Variables numerica\r\nentero = 10\r\nreal = 10.5\r\n\r\n#Variables de texto\r\ntexto = \"Hola Mundo\"\r\n\r\n#Variables booleanas\r\nverdadero = true\r\nfalso = false\r\n\r\n#Variables nulas\r\nnulo = nil\r\n\r\n#Arrays\r\narreglo =[1, 2, 3]\r\n\r\n#Hash\r\nhash = {nombre: \"Juan\", apellido: \"Perez\"}\r\n\r\nputs \"¡Hola, Ruby!\"\r\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/ruby/zarakilancelot.rb",
    "content": "# Realizado con https://www.ruby-lang.org/es/\n# Comentario de una lína\n=begin\n  Comentario\n  de varias\n  líneas\n=end\n\nvariable = \"Una variable\"\nCONSTANTE = \"Una constante\"\n\n# En Ruby no hay primitivos, casi todo es un objeto\n=begin\nNuméricos:\n- Integer\n    - Fixnum\n    - Bignum\n- Float\n- Complex\n- BigDecimal\n- Rational\n=end\nnumero = 1_000\n\n=begin\nTexto\n=end\ncadena_de_texto = \"Ruby\"\n\n# Arrays\nun_array = [1, 2, 3]\n\n# Hash\nun_hash = { \"uno\" => 1, \"dos\" => 2}\notro_hash = { :uno => 1, :dos => 2}\notro_hash_mas = { uno: 1, dos: 2}\n\n# Range\nprimera_guerra_mundial = 1914..1918   # Entre 1914 y 1918 inclusive\nsegunda_guerra_mundial = 1939...1946  # Entre 1939 y 1946 (se excluye 1946)\n\n# Symbol\nsimbolo = :simbolo\n\n# Booleans\nverdadero = true\nfalso = false\n\n# Nulo\nnulo = nil\n\nputs \"¡Hola, #{cadena_de_texto}!\"\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/rust/Angel-Alvarez-Dev.rs",
    "content": "// Rust URL: https://www.rust-lang.org/\n\n// Este es un comentario usando dos diagonales.\n\n/*\n*  Comentario en bloque\n*\n*/\n\n// Variables\nfn main() {\n    let mut variable = \"Esto es una variable con propiedad mutable\";\n    let variable = \"Esta es una variable\";\n}\n\n// Sombra (Shadowing)\nfn main() {\n    let x = 3;\n    let x = \"a\";\n}\n\n// Constantes\nconst CONSTANTE: f32 = 1.0;\n\nfn main() {\n    // Datos primitivos\n    // Enteros con signo\n    let a_int: i8 = 1;\n    let a_int_suffix = 1i8; // Notación con sufijo\n\n    let a_int_2: i16 = 1;\n    let a_int_3: i32 = 1;\n    let a_int_4: i64 = 1;\n    let a_int_5: i128 = 1;\n    let a_uint_6: isize = 1;\n\n    // Enteros sin signo\n    let a_uint: u8 = 1;\n    let a_uint_2: u16 = 1;\n    let a_uint_3: u32 = 1;\n    let a_uint_4: u64 = 1;\n    let a_uint_5: u128 = 1;\n    let a_uint_6: usize = 1;\n\n    // Coma flotante\n    let my_float: f32 = 1.0;\n    let my_float_2: f64 = 1.0;\n\n    // Caracteres UNICODE\n    let my_char: char = 'a';\n\n    // Booleanos\n    let a_true: bool = true;\n    let a_false: bool = false;\n\n    // Unit (Tupla vacía)\n    let my_unit = ();\n\n    // Arrays y Tuplas\n    let my_array: [i32; 5] = [1, 2, 3, 4, 5];\n    let my_tuple: (i32, f64, u8) = (1, 3.0, 1);\n\n    // Imprime por terminal \"¡Hola, [y el nombre de tu lenguaje]!\"\n    println!(\"¡Hola, Rust!\");\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/rust/Coshiloco.rs",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n\n// URL del sitio web oficial del lenguaje de programación: https://www.rust-lang.org/\n\n// Comentario de una línea\n\n/*\nComentario \nMultilinea\n*/\n\n// Creación de una variable\nlet mut variable = 10;\n\n// Creación de una constante \nconst PI: f64 = 3.14159265358979323846264338327950288;\n\n// Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...)\nlet cadena = \"Hola, Rust!\";\nlet entero = 42;\nlet booleano = true;\nlet flotante = 5.87;\n\n\nfn main() {\n    // Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n    println!(\"{}\", cadena);\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/rust/CurtoBrull.rs",
    "content": "// Url oficial de Rust: https://www.rust-lang.org/es\n\n// Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...)\n\n// Esto es un comentario de una una línea\n\n/*\nLos comentarios de multiples líneas\nvan entre /* */\n*/\n\n/// Con una triple barra antes de una función, estructura, etc... se crea la documentación\n///\n/// Al colocarnos sobre el nombre de la funcion (suma en este caso)\n/// aparecerán los comentarios de la documentación\n///\n/// Esta es una función para sumar 2 números\nfn suma(a: i32, b: i32) -> i32 {\n    return a + b\n}\n\n/*\nUna forma especial de \"comentar\" un bloque de código podría ser el que se declara con\n#[cfg(never)]\nNo es un comentario como tal pero se puede usar de forma similar.\nÚtil para probar algo desactivando una parte del codigo sin tener que borrarlo\n */\n\nfn reto00() {\n    // Crea una variable (y una constante si el lenguaje lo soporta)\n    // Las variables se declaran con let y las constantes con const\n    let number: i8 = 1;\n    const LANGUAGE: &str = \"Rust\";\n\n    // Crea variables representando todos los tipos de datos primitivos\n    let text: &str = \"Hello, World!\";\n    // Aquí llamamos al metodo from de la clase String\n    let text2: String = String::from(\"Hello, World!\");\n\n    let boolean: bool = false;\n    let character: char = 'A';\n\n    let float: f64 = 3.14;\n    let integer_unsigned: u8 = 255;\n    let integer: i32 = -10;\n    let isize_unsigned: usize = 255;\n    let isize: isize = 42;\n\n    let _tuple: (i8, &str, &str, String, bool, char, f64, u8, i32, usize, isize) = (number, LANGUAGE, text, text2, boolean, character, float, integer_unsigned, integer, isize_unsigned, isize);\n    let _array: [i8; 10] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n    let mut _vector: Vec<i8> = Vec::new();\n    _vector.push(1);\n    _vector.push(2);\n\n    println!(\"¡Hola, {}!\", LANGUAGE);\n\n    let result = suma(1,2);\n    println!(\"La suma es: {}\", result);\n}\n\nfn main() {\n    reto00();\n}\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/rust/EAbalde.rs",
    "content": "/*\nComentario en bloque con el enunciado del ejercicio:\n\n¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n- Recuerda que todas las instrucciones de participación están en el\nrepositorio de GitHub.\n\nLo primero... ¿Ya has elegido un lenguaje?\n- No todos son iguales, pero sus fundamentos suelen ser comunes.\n- Este primer reto te servirá para familiarizarte con la forma de participar\nenviando tus propias soluciones.\n\nEJERCICIO:\n- Crea un comentario en el código y coloca la URL del sitio web oficial del\nlenguaje de programación que has seleccionado.\n- Representa las diferentes sintaxis que existen de crear comentarios\nen el lenguaje (en una línea, varias...).\n- Crea una variable (y una constante si el lenguaje lo soporta).\n- Crea variables representando todos los tipos de datos primitivos\ndel lenguaje (cadenas de texto, enteros, booleanos...).\n- Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\n¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\ndebemos comenzar por el principio.\n */\n\n// Comentario de una sola línea con la URL oficial:  https://www.rust-lang.org\n\nfn main() {\n/*\nRust no permite declarar variables que no sean usadas.\nPara evitar que marque warnings en esas variables\nes necesario iniciarlas con un guión bajo.\n*/\t\n\t// VARIABLES Y CONSTANTES:\n\tlet _x = 1; // Esta es una variable inmutable.\n\tlet mut _y = 2; // Esta es una variable mutable.\n\n\tconst _YEAR: i32 = 365; // Esta es una constante.\n\n\t// DATOS PRIMITIVOS ESCALARES:\n\tlet _a: i32 = -50; // Enteros con signo. Pueden ser i8, i16, i32, i64, i128 o isize.\n\tlet _b: u32 = 100; // Enteros sin signo. Pueden ser u8, u16, u32, u64, u128 o usize.\n\tlet _c: f32 = 1.0; // Decimales o de coma flotante. Pueden ser f32 o f64.\n\tlet _d = true; // Datos booleanos. Pueden ser true o false.\n\tlet _e: char = 'A'; // Caracteres Unicode. Pueden ser letras, números o símbolos.\n\tlet _f: &str = \"¡Hola Mundo!\"; // Cadenas de texto.\n\n\t// DATOS PRIMITIVOS COMPUESTOS:\n\n\t// Arreglo o array. Colección de elementos del mismo tipo con longitud fija.\n\tlet _g: [i32; 5] = [1, 2, 3, 4, 5];\n\t// Tuplas. Colecciones de elementos que pueden ser de distinto tipo.\n\tlet _h: (i32, f64, char) = (-50, 3.1416927, '');\n\n\t// HOLA RUST:\n\tprintln!(\"¡Hola, Rust!\");\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/rust/LuisGarM.rs",
    "content": "/*COMENTARIOS MULTLINEA\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarioss\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n*/\n// URL del sitio web oficial de Rust\n// https://www.rust-lang.org/\n// Comentario de una línea\n/*\n * Comentario\n * Multilínea\n */\n\n fn main() {\n    // Las variables en Rust son inmutables por defecto\n    // Para hacerlas mutables se debe agregar la palabra reservada mut\n    // Para declarar una variable se utiliza la palabra reservada let\n    //Rust puede inferir el tipo de dato de la variable, pero también se puede especificar el tipo de dato\n\n    // Variables\n\n    let variable = 10; //i32 es el tamaño de la variable\n                       // variable = 20; //Error, la variable es inmutable por defecto\n    let mut variable_mut = 20; //Se puede cambiar el valor de la variable\n    variable_mut = 30; //Ahora sí se puede cambiar el valor de la variable\n\n    // Constante\n    const PI: f32 = 3.1416; //Las constantes se declaran con la palabra reservada const y se debe especificar el tipo de dato\n\n    // Tipos de datos primitivos\n\n    //Enteros con signo\n    let entero: i8 = -10; //i8, i16, i32, i64, i128, isize\n    let _entero_i64: i64 = 1_000_000_000; // Se pueden usar guiones bajos para mejorar la legibilidad\n\n    //Enteros sin signo\n    let entero_sin_signo: u8 = 10; //Igualmente se pueden usar u16, u32, u64, u128, usize\n\n    //Punto flotante\n    let flotante: f32 = 10.5; //f32, f64\n\n    //Booleano\n    let booleano = true; //false\n\n    //Valores unicode\n    let caracter = 'a'; //Se pueden usar comillas simples para representar un solo caracter\n\n    //Cadena de texto\n    let cadena: &str = \"¡Hola, Rust!\"; //Las cadenas de texto son inmutables por defecto\n\n    // Imprimir por terminal\n    println!(\"Constante: {}\", PI);\n    println!(\"Variable mutable: {}\", variable_mut);\n    variable_mut = 40; //Se puede cambiar el valor de la variable\n    println!(\"Variable mutable: {}\", variable_mut);\n    println!(\"Variable: {}\", variable);\n    println!(\"¡Hola, Rust!\"); //Se puede imprimir una cadena de texto directamente\n    println!(\"{}\", cadena); //También se puede imprimir una variable, los {} son marcadores de posición en esa posición se imprimirá el valor de la variable\n    println!(\"Entero con signo: {}\", entero);\n    println!(\"Entero sin signo: {}\", entero_sin_signo);\n    println!(\"Punto flotante: {}\", flotante);\n    println!(\"Booleano: {}\", booleano);\n    println!(\"Caracter: {}\", caracter);\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/rust/allanoscoding.rs",
    "content": "// https://www.rust-lang.org/\n\n// Esto es un comentario simple\n\n// Si se desea escribir un comentario multilinea\n// debemos colocar '//' en cada linea del mismo.\n\n/// Para documentar items dentro de paquetes o crates podemos emplear '///', que aparecera \n/// a continuacion del item que queramos explicar. Ademas tiene soporte para Markdown \n/// enriqueciendo la documentacion con code snippets\n\n//! Si se quisiera dar una explicacion general del paquete o create usariamos '//!'\n\n\n// Variables (inmutables en Rust por defecto)\nlet my_variable = 5;\nlet mut my_variable_2 = 3; // Mutable\n\n// Constantes\nstatic LANG = \"Rust\"; // Imposible asignar otro valor despues de la def.\nconst INFO = \"Dev\"; // Variable que puede mutar dentro de un 'static lifetime\n\n// Tipos Primitivos\n\n// Enteros con signo\nlet my_int: i8 = 1;\nlet my_int_suffix = 1i8; // Notacion con sufijo\n\nlet my_int_2: i16 = 1;\nlet my_int_3: i32 = 1;\nlet my_int_4: i64 = 1;\nlet my_int_5: i128 = 1;\n\n// Enteros sin signo\nlet my_uint_2: u16 = 1;\nlet my_uint_3: u32 = 1;\nlet my_uint_4: u64 = 1;\nlet my_uint_5: u128 = 1;\n\n// Coma flotante\nlet my_float: f32 = 1.0;\nlet my_float_2: f64 = 1.0;\n\n// Caracteres UNICODE\nlet my_char: char = 'a';\n\n// Booleanos\nlet my_bool: bool = true;\n\n// Unit(Tupla vacia)\nlet my_unit = ();\n\n// Arrays y Tuplas\nlet my_array: [i32; 5] = [1, 2, 3, 4, 5];\nlet my_tuple: (i32, f64, u8) = (1, 3.0, 1);\n\nprintln!(\"Hola, Rust!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/rust/angelsanchezt.rs",
    "content": "// URL del sitio web oficial de Rust: https://www.rust-lang.org\n\n// Comentarios de una línea\n\n/*\n  Comentarios\n  de\n  varias\n  líneas\n*/\n\nfn main() {\n    // Declaración de variables y constantes\n    let mut variable_mutable = 42; // Variable mutable\n    let constante = 3.14; // Constante\n\n    // Tipos de datos primitivos\n    let caracter: char = 'A'; // Carácter\n    let entero: i32 = -42; // Entero con signo de 32 bits\n    let entero_sin_signo: u64 = 123; // Entero sin signo de 64 bits\n    let flotante: f64 = 3.14159; // Punto flotante de 64 bits\n    let booleano: bool = true; // Booleano\n\n    // Cadenas de texto\n    let cadena_texto: &str = \"¡Hola, Rust!\"; // Cadena de texto (inmutable)\n    let cadena_texto_mut: String = String::from(\"¡Hola, Rust mutable!\"); // Cadena de texto mutable\n\n    // Imprimir por terminal\n    println!(\"¡Hola, {}!\", \"Rust\");\n    println!(\"Valor de la variable mutable: {}\", variable_mutable);\n    println!(\"Valor de la constante: {}\", constante);\n    println!(\"Carácter: {}\", caracter);\n    println!(\"Entero con signo: {}\", entero);\n    println!(\"Entero sin signo: {}\", entero_sin_signo);\n    println!(\"Punto flotante: {}\", flotante);\n    println!(\"Booleano: {}\", booleano);\n    println!(\"Cadena de texto (inmutable): {}\", cadena_texto);\n    println!(\"Cadena de texto mutable: {}\", cadena_texto_mut);\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/rust/atienzar.rs",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n // Comentario de 1 línea => https://www.rust-lang.org/es\n\n /*\n *  Comentario en bloque\n *  \n */\nuse std::{vec, collections::HashSet, collections::HashMap};\n\n\nfn main(){\n\n    // 1 cte y vble\n    let mut mivar = 8;\n    let miconst = 10;\n    println!(\"{mivar}  {miconst}\");\n\n    let mibool:bool = false;\n    let miint:i32 = 4;\n    let mut micad: &str = \"Mi primera cadena\";\n\n    // print \n    println!(\"Hola Rust!\");\n    println!(\"{mibool}  {miint} {micad}\");\n\n\n\n    //Lista \n\n    let mut my_list = vec!(\"atienzar\", \"pedro\", \"juan\", \"52\", \"atienzar\");\n    my_list.push(\"atienzar\");\n    println!(\"{:?}\", my_list);\n    println!(\"{}\", my_list[2]);\n\n\n    // Sets\n    // es como el vector pero SIN duplicados y desordenado\n    let mut my_set: HashSet<&str> = vec!(\"atienzar\", \"pedro\", \"juan\", \"52\", \"atienzar\").into_iter().collect();\n    println!(\"{:?}\", my_set);\n    my_set.insert(\"Pedro\");\n    println!(\"{:?}\", my_set);\n\n\n    //Mapa KEY: VALUE\n    let mut my_map: HashMap<&str,i32> = vec![(\"atienzar\",52),(\"pedro\",42),(\"pedrop\",15)].into_iter().collect();\n    println!(\"{:?}\", my_set);\n    my_map.insert(\"atienzaj\", 26);\n    println!(\"{:?}\", my_map);\n    \n    \n\n}\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/rust/brockar.rs",
    "content": "/* \nSitio web oficial:\nhttps://www.rust-lang.org/es\n*/\n\n// Sitio web oficial: \n// https://www.rust-lang.org/es\n\nfn main(){\n    let mut variable = \"Esto es una variable\"; // variable mutable\n    let constante = \"Esto es una constante\"; // variable inmutable\n    const PI: f32 = 3.1416; // const must be declared with a type\n\n    // INT \n    let entero8: i8= 126; // -128 to 127\n    let unsigned_entero: u8 = 254; // 0 to 255\n    let entero16: i16 = 16; // -32768 to 32767\n    let entero32: i32 = 32; // -2147483648 to 2147483647\n    let entero64: i64 = 64; // -9223372036854775808 to 9223372036854775807\n    let entero128: i128 = 128; // -170141183460469231731687303715884105728 to 170141183460469231731687303715884105727\n\n    // Each type of integer can be either signed (positive and negative) or unsigned (just positive)\n    // Signed: i8, i16, i32, i64, i128\n    // Unsigned: u8, u16, u32, u64, u128\n    \n    // FLOAT\n    let flotante32: f32 = 32.0; // 32-bit floating point\n    let flotante64: f64 = 64.0; // 64-bit floating point\n\n    // BOOLEAN\n    let booleano: bool = true;\n\n    // CHAR\n    let caracter: char = 'a';\n\n    // STRING\n    let cadena: &str = \"Hola, Rust!\"; // Static\n    let string1: String = String::from(\"Rust\"); // Dynamic like a vector\n    \n\n    // ARRAY\n    let arreglo: [i32; 5] = [1, 2, 3, 4, 5]; // [type; number of elements]\n\n    // TUPLE\n    let tupla: (i32, f64, u8) = (500, 6.4, 1); // (type, type, type)\n\n    // PRINT\n    println!(\"¡Hola, {}!\", string1);\n\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/rust/cesar-ch.rs",
    "content": "// URL: https://www.rust-lang.org/\n\n// This is a one line comment\n\n/*\n    This is a multi line comment\n*/\n\nfn main() {\n    // This is a variable\n    let mut my_varianble = 5;\n    println!(\"The value of my_varianble is: {}\", my_varianble);\n    my_varianble = 6;\n    println!(\"The value of my_varianble is: {}\", my_varianble);\n    // This is a constant\n    let my_constant = 7;\n    println!(\"The value of my_constant is: {}\", my_constant);\n\n    // Data types\n    // Integer\n    // Signed\n    // i8, i16, i32, i64, i128, isize\n    // Unsigned\n    // u8, u16, u32, u64, u128, usize\n    let my_integer = 8;\n    println!(\"The value of my_integer is: {}\", my_integer);\n    // Floating point\n    // f32, f64\n    let my_float = 9.0;\n    println!(\"The value of my_float is: {}\", my_float);\n    // Boolean\n    let my_boolean = true;\n    println!(\"The value of my_boolean is: {}\", my_boolean);\n    // Character\n    let my_char = '🤡';\n    println!(\"The value of my_char is: {}\", my_char);\n    // String\n    let my_string = \"¡Hola, Rust!\";\n    println!(\"{}\", my_string);\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/rust/darubiano.rs",
    "content": "/*\n    EJERCICIO:\n    1) Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n    2) Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n    3) Crea una variable (y una constante si el lenguaje lo soporta).\n    4) Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n    5) Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n*/\n\n// 1) https://www.rust-lang.org/es/\n\n// 2) Comentario de una linea y varias\n\n/*\nComentario de varias lineas\n*/\nfn main() {\n    // 3) Variables son (inmutables en Rust por defecto) y constante\n    let variable: &str = \"variable\";\n    let mut variable_mutable: &str = \"variable_mutable\";\n    // Constantes\n    const MY_CONST: &str = \"constante\";\n\n    // 4) Tipos de variables primitivas https://doc.rust-lang.org/rust-by-example/primitives.html\n    //Tipos numericos\n    // Enteros con signo\n    let int: i8 = 1;\n    let int_suffix = 1i8;\n    let int_i16: i16 = 1;\n    let int_i32: i32 = 1;\n    let int_i64: i64 = 1;\n    let int_i128: i128 = 1;\n    // Enteros sin signo\n    let uint_u16: u16 = 1;\n    let uint_u32: u32 = 1;\n    let uint_u64: u64 = 1;\n    let uint_u128: u128 = 1;\n    // Coma flotante\n    let float_f32: f32 = 1.0;\n    let float_f64: f64 = 1.0;\n\n    // Tipo de dato texto\n    let caracter: char = 'a';\n    let variable: &str = \"variable\";\n    let mut texto_mutable: String = String::from(\"¡Hola, \");\n\n    // Tipos boleanos\n    let verdadero: bool = true;\n    let falso: bool = false;\n\n    // Tipos arreglos,slices, tuplas y unidad\n    let array: [i32; 3] = [1, 2, 3];\n    let slice: &[i32] = &array[1..3];\n    let tupla: (i32, f64, char) = (42, 3.14, 'A');\n    let unidad: () = ();\n\n    // 5) print() hola Go\n    println!(\"¡Hola, Rust!\");\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/rust/didacdev.rs",
    "content": "// https://doc.rust-lang.org/book/\n\n// Comentario de una línea\n/* Comentario de\nvarias líneas */\n\nfn main() {\n    let mut name = \"Diego\";\n    let greeting = \"Hello\";\n\n    //------- Integers\n\n    // Unsigned\n    let u8 = 20u8;\n    let u16 = 20u16;\n    let u32 = 20u32;\n    let u64 = 20u64;\n    let u128 = 20u128;\n\n    // Signed\n    let i8 = 20i8;\n    let i16 = 20i16;\n    let i32 = 20i32;\n    let i64 = 20i64;\n    let i128 = 20i128;\n\n    //------- Floating\n    let f64 = 3.0;\n    let f32: f32 = 3.0;\n\n    //------- Boolean\n    let boolean = false;\n\n    //------- Character\n    let character = 'c';\n\n    //------- Tuple\n    let tuple: (i32, f64, u8) = (500, 3.0, 20);\n\n    //------- Array\n    let months = [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\",\n        \"August\", \"September\", \"October\", \"November\", \"December\"];\n    let a: [i32; 5] = [1, 2, 3, 4, 5];\n    let a = [3; 5];\n\n    println!(\"¡Hola, Rust!\")\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/rust/gabrielmoris.rs",
    "content": "/// https://www.rust-lang.org/\n\n/*\nThis is a\nmulti-line\nblock comment\n*/\n\nfn main() {\n    // Constant Variables\n    let _string = \"Hello\";\n    let _string2 = \"Rust\";\n    // Mutables\n    let mut _y = 10;\n    _y = 20;\n\n    // Strings\n    let _str: &str = \" This is a string\";\n\n    // Integers\n    let _int: i32 = 42;\n\n    // Floating points\n    let _fl1: f64 = 3.1416;\n\n    //Booleans\n    let _bool: bool = false;\n\n    // Characters\n    let _char: char = '😂';\n\n    // tuples\n    let _tup: (i32, f64, bool) = (2, 1.5, false);\n\n    // Arrays\n    let _arr: [i32; 4] = [1, 5, 7, 9];\n\n    // Objects: 1. define structure and create the instance.\n    struct Person {\n        _name: String,\n        _age: u32,\n    }\n\n    let _person: Person = Person {\n        _name: String::from(\"Alice\"),\n        _age: 30,\n    };\n\n    // Classes: 1. Define structure, add constructor and methods\n    impl Person {\n        // Constructor function\n        fn _new(_name: &str, _age: u32) -> Person {\n            Person {\n                _name: String::from(_name),\n                _age,\n            }\n        }\n\n        // Method to greet the person\n        fn _greet(&self) {\n            println!(\"Hello, my name is {} and I'm {} years old.\", self._name, self._age);\n        }\n    }\n\n    let _person = Person::_new(\"Gabrielmoris\", 34);\n\n    println!(\"{_string}, {_string2}\");\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/rust/javiearth.rs",
    "content": "//=====================================================\n// 00 - Sintaxis, variales, tipos de datos y hola mundo\n//=====================================================\n\n// 1. WEB  OFICIAL\n// Rust official documentation: https://www.rust-lang.org\n\n// 2. COMENTARIOS EN RUST\n// One line comment\n/* Multiple line comments\njust like C!!\n*/\n\n// CREANDO UNA VARIALE Y UNA CONSTANTE\n\n// Variable\nlet a = 5;\n\n// Creando una constante:\nconst GRAVEDAD_TERRESTRE: 9.81;\n\n// CREA VARIABLES REPRESENTANDO TODOS LOS TIPOS DE DATOS\n\n// NOTA: el compilador infiere el tipo de dato y no es necesatio indicarlo, pero se puede hacer.\n\n// Tipo escalar:\n  // Tipos integer, pueden ser con signo (i) o sin signo (u): i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize.\n  let entero_8bits i8 = -128;\n  let positivo_8bits u8 = 255;\n  let entero_16bits i16 = =-32768;\n  let positivo_16bits u16 = 62535;\n  let entero_32bits i32 = 42;\n  let positivo_32bits u32 = 73;\n  let entero_64bits i64 = 137;\n  let positivo_64bits u64 = 20000000;\n  let entero_128bits i128 = 1;\n  let positivo_128bits u128 = 345;\n  let entero_arquitectura isize = 546236;\n  let positivo_arquitectura usize = 243653426;\n  // Tipos integer literals: son enteros en otras notaciones(0x, 0o, 0b)\n  let moure_dev = 1_987; //Decimal, sin prefijo, se puede usar _ para leerlo mejor sin que afecte en nada.\n  let que_champu = 0x7C3; //Hexadecimal (todos los numeros hexadecimales empiezan por 0x, 7C3 es 1987 en hexadecimal)\n  let usas_para = 0o3703; //Octal (notacion octal empieza por 0o)\n  let la_barba = 0b11111000011; //Binario (0b indica binario)\n  \n// Coma flotante (f32 y f64, IEEE-754 standard)\n  let x f32 = 1.234;\n  let y f64 = -1.23456789;\n\n//Tipo boolean:\nlet delicioso = true;\nlet love: = 0; // notacion explicita\n\n// Tipo character (ocupan 4 bytes y represaentan valores Unicode):\nlet g = 'j';\nlet v: char = 'B';\nlet heart = 💓;\n\n// Tipos compuestos: Tupla. almacena varios datos de diferente tipo.\nlet tuplita: (i32, f64, u8) = (500, 6.4, 1);\n// Tipos compuestos: array. Almacena varios valores del mismo tipo.\nlet array = [1,2,3,4,5];\n\n //Cadenas de caracteres: para este caso hay que usar la funcion String::from o el metodo .to_string().\n let mi_cadena: String = String::from(\"mi casa\");\n let mi_otra_cadena: String = \"mi otra casa\".to_string();\n // Seria incorrecto escribir algo como let mi-cadena: String = \"mi casa\".\n\n // IMPREME POR PANTALLA \"HOLA MUNDO\"\n\n fn main() {\n    println(\"Hola, mundo\");\n }"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/rust/julianbuitragocharry-dev.rs",
    "content": "use std::io;\n\n// https://www.rust-lang.org/\n// Sintaxis de comentario en una linea\n/* Sintaxis de comentario multilinea*/\n\nfn main() {\n    println!(r#\"Do you want to know about Rust? 🦀\n    1) Mutability\n    2) Primitive Variables\n    3) Constant\n    4) Say Hello to me\n    5) Exit\n    \"#);\n\n    let mut option = String::new();\n    io::stdin().read_line(&mut option).expect(\"Failed to read line\");\n\n    let option: u32 = option.trim().parse().expect(\"Please enter a number\");\n\n    match option {\n        1 => mutability(),\n        2 => primitive_variables(),\n        3 => constant(),\n        4 => hi(),\n        5 => println!(\"See you soon...\"),\n        _ => {\n            println!(\"Choose the right option...\\n\");\n            main();\n        }\n    }\n}\n\nfn mutability() {\n    println!(r#\"What is a mutable variable\n    1) let mut exit: bool = true;\n    2) let exit: bool = true; \n    \"#);\n        \n    let mut option = String::new();\n    io::stdin().read_line(&mut option).expect(\"Failed to read line\");\n\n    let option: u32 = option.trim().parse().expect(\"Please enter a number\");\n    \n    if option == 1 {\n        println!(\"Correct Option...\\n\");\n        main();\n    } else {\n        println!(\"Wrong Option... Repeat mutability test\");\n        mutability();\n    }\n}\n\nfn primitive_variables() {\n    let logical: bool = true;\n\n    println!(r#\"Boolean\n    let logical: bool = true;\n    {}\n    \"#, logical);\n\n    let unsigned_integer: u32 = 1024;\n    println!(r#\"Unsigned Integer  \n    let unsigned_integer: i32 = 1024;\n    {}\n    \"#, unsigned_integer);\n\n    let integer: i32 = -1024;\n    println!(r#\"Integer\n    let integer: i32 = -1024;\n    {}\n    \"#, integer);\n\n    let float: f64 = 100.0;\n    println!(r#\"Float \n    let float: f64 = 100.0;\n    {}\n    \"#, float);\n\n    let chart: char = 'D';\n    println!(r#\"Char\n    let chart: char = 'D';\n    {}\n    \"#, chart);\n    \n    let empty = ();\n    println!(r#\"Tuple Empty \n    let empty = ();\n    {:?}\n    \"#, empty);\n    \n    main();\n}\n\nfn constant() {\n    const PI: f64 = 3.1416; \n\n    println!(r#\"Constant\n    const PI: f64 = 3.1416;\n    {}\n    \"#, PI);\n    \n    main();\n}\n\nfn hi() {\n    let language: &str = \"Rust\";\n    println!(\"Hello, {}\\n\", language);\n\n    main();\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/rust/kenysdev.rs",
    "content": "// no advertencia(variables no utilizadas)\n#![allow(unused_variables)] \n\n/* Comentario de bloque\n╔═══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado                ║\n║ GitHub: https://github.com/Kenysdev   ║\n║ 2024 -  Rust                          ║\n╚═══════════════════════════════════════╝\n\nWeb: https://www.rust-lang.org/es/\n*/\n// Comentarios de una línea\n\n/// * Comentarios de documentación (Doc comments)\n/// - genera documentación automáticamente con rustdoc.\n/// - Genera la documentación en formato HTML.\n/// - https://doc.rust-lang.org/cargo/commands/cargo-doc.html\n\nfn main(){\n  // * Variables\n  // - Las variables por defecto son inmutables.\n  let my_str1 = \"Dejar que el compilador infiera el tipo.|\";\n  let my_str2: &str = \"Especificar el tipo.|\";\n  let mut my_str3 = \"variable mutable.|\";\n  \n  /* Constante\n  - No se permite usar *mut* con constantes.\n  - El tipo del valor debe  especificarse.\n  - Se pueden declarar en cualquier ámbito. */\n  const MY_CONSTANT: i32 = 12; \n\n  /* Shadowing\n  - Es redefinir una variable existente con el mismo nombre.\n  - Permite cambios en el valor y tipo de la variable original\n    sin necesidad de mutabilidad. */\n  let x = 10;\n  let x = x + 10;\n  println!(\"Resultado: {}\", x);\n\n  // _________________________________________\n  // * Tipos de datos primitivos\n  // - Enteros (Decimal, Hex, Octal, Binario)\n  let hex = 0x2A;\n  let binary = 0b101010;\n\n  // NOTA: se permite '_' en la asignación para más claridad.\n\n  // - Enteros con signo\n  let integer: i8 = -128; // a 127\n  let integer: i16 = -32_768; // a 32,767\n  let integer: i32 = -2_147_483_648; // a .,.,647\n  let integer: i64 = 9_223_372_036_854_775_807;\n  let integer: i128 = 170; // ...\n  let integer: isize = 0; // Conforme a la arquitectura.\n\n  // - Enteros sin signo\n  let integer: u8 = 255;\n  let integer: u16 = 65_535;\n  let integer: u32 = 4_294_967_295;\n  let integer: u64 = 18_446_744_073_709_551_615;\n  let integer: u128 = 340; // ...\n  let integer: usize = 0; // Conforme a la arquitectura.\n\n  // _________________________________________\n  // - Tipos de punto flotante\n  //   De precisión simple y mas eficiencia.\n  let y: f32 = 4.0;\n\n  // De precisión doble pero ligeramente más lento.\n  let x = 2.0; // f64\n  let x: f64 = 3.0;\n\n  // _________________________________________\n  // - El tipo booleano\n  let t = true;\n  let f: bool = false;\n\n  // _________________________________________\n  // - Tipo de dato texto\n  //   char: tamaño de cuatro bytes y representa un valor escalar Unicode\n  //   (Letras acentuadas, Caracteres chinos, japoneses y coreanos; Emojis).\n  let my_char: char = 'a';\n\n  // \"slice de cadena\" y solo puede ser inmutable.\n  let my_str: &str = \"variable\";\n\n  // cadena de texto dinámica.\n  let mut _my_string: String = String::from(\"abc\");\n\n  // _________________________________________\n  println!(\"{} {} {} {}\", \n  my_str1, my_str2, my_str3, MY_CONSTANT);\n\n  my_str3 = \"¡Hola, Rust!\";\n  println!(\"{my_str3}\");\n\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/rust/kodenook.rs",
    "content": "\n// https://www.rust-lang.org\n\n/*\n    Comments\n*/\n\n// single-line comment\n\n/*\n    this is a\n    multi-line comment\n*/\n\n\n/// This Rust program declares variables of different types and prints a greeting message.\nfn main(){\n\n    /*\n        Vars and Constants\n    */\n\n    // The variables that start with _ are not used\n\n    let _x = \"4\"; // variable inmutable\n    let mut _y = \"5\"; // variable mutable\n    const _Z: &str = \"6\"; // const must have the type\n\n    /*\n        Primitive Types\n    */\n\n    let _number: u8 = 16; // unsigned 8-bits number, i8 for signed, there are 8, 16, 32, 64 and 128 bits\n    let _boolean: bool = true;\n    let _floating32: f32 = 2.5;\n    let _floating64: f64 = 2.553;\n    let _letter: char = 'a';\n\n    println!(\"¡Hello, Rust!\");\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/rust/miguelex.rs",
    "content": "// Documentación en https://prev.rust-lang.org/es-ES/documentation.html\n\n// Comentario en una linea\n\n/*\n  Comentario\n  en varias\n  lineas\n*/\n\nfn main() {\n    // Declaración de variables y constantes\n    let mut lenguaje = String::from(\"Rust\"); // Variable\n    let PI = 3.1415; // Constante\n\n    // Tipos de datos primitivos\n    let letra: char = 'A'; // Carácter\n    let numero: i32 = -1; // Entero con signo de 32 bits\n    let numerosinsigno: u64 = 1; // Entero sin signo de 64 bits\n    let decimal: f64 = 3.1415; // Punto flotante de 64 bits\n    let booleano: bool = true; // Booleano\n\n    //Salida por pantalla\n    println!(\"Hola {}!\", lenguaje);\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/rust/owen-ian.rs",
    "content": "////===========================================//\n/// 00 - SINTAXIS, VARIABLES Y TIPOS DE DATOS // \n//===========================================//\n\n// URL del sitio web oficial: https://www.rust-lang.org/\n\n// Comentario de una sola línea en Rust\n\n/* Y este es un\ncomentario de varias\nlíneas en Rust */\n\n//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//\n//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//\n\nfn main() {\n    let x = 10; // Variable\n  \n    let mut y = 5; // Esta es una\n    y = 10; // Variable mutable\n\n    const PI: f32 = 1.99; // Constante\n\n    let x = x + 1; // Let let (shadowing) -----------------> \n    println!(\"Valor de x después del shadowing: {}\", x); // Reemplaza el valor anterior de x\n\n//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//\n//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//\n  \n    // Cadenas de texto\n    let texto: &str = \"Cadena de texto\"; // Cadena de texto\n    let mut string: String = String::from(\"Cadena de texto mutable\"); // Cadena de texto mutable\n\n    // Enteros con signo (Signed)\n    let a: i8 = 10; // Entero con signo de 8 bits, puede ser del -128 al 127\n    let b: i16 = 10; // Entero con signo de 16 bits, puede ser del -32,768 al 32,767\n    let c: i32 = 10; // Entero con signo de 32 bits, puede ser del -2,147,483,648 al 2,147,483,647 -->-->--> [VALOR POR DEFECTO] <--<--<--\n    let d: i64 = 10; // Entero con signo de 64 bits, puede ser del -9,223,372,036,854,775,808 al 9,223,372,036,854,775,807\n    let e: i128 = 10; // Entero con signo de 128 bits, puede ser del -170,141,183,460,469,231,731,687,303,715,884,105,727 al 170,141,183,460,469,231,731,687,303,715,884,105,727\n\n    // Enteros sin signo (Unsigned)\n    let f: u8 = 10; // Entero sin signo de 8 bits, puede ser del 0 al 255\n    let g: u16 = 10; // Entero sin signo de 16 bits, puede ser del 0 al 65,535\n    let h: u32 = 10; // Entero sin signo de 32 bits, puede ser del 0 al 4,294,967,295 -->-->--> [EL VALOR POR DEFECTO SIGUE SIENDO I32] <--<--<--\n    let i: u64 = 10; // Entero sin signo de 64 bits, puede ser del 0 al 18,446,744,073,709,551,615\n    let j: u128 = 10; // Entero sin signo de 128 bits, puede ser del 0 al 340,282,366,920,938,463,463,374,607,431,768,211,455\n\n    // Flotantes\n    let k: f32 = 3.141592; // Flotante de 32 bits, llega a 6 decimales\n    let l: f64 = 3.1415926535897932; // Flotante de 64 bits, llega a 16 decimales\n\n    // Por cierto, en Rust puedes escribir los números con _ cada que te resulte cómodo, por ejemplo:\n    // 3.14159_26535_89793_23846_26433\n    // 3.141_592_653_589_793_238_462_643_3\n    // Ambos ejemplos siguen siendo iguales para la máquina, esto no afecta en absolutamente nada\n    // Sino más bien que resulta ser una característica implementada para facilitar la lectura de números largos al desarrollador\n    // Te recomiendo separar cada 3, 4 o 5 dígitos, depende tu región, idioma o normas de trabajo.\n\n    let booleano: bool = true; // Verdadero\n    let booleano2: bool = false; // Falso\n    \n    let caracter: char = 'A'; // Carácter\n\n    // POO en Rust\n    let tupla: (i32, f64, &str) = (c, l, texto); // Tupla, estructura que puede contener varios elementos con distintos tipos de datos\n    let arreglo: [i32; 5] = [1, 2, 3, 4, 5]; // Arreglo (array), estructura que puede contener varios elementos pero un solo tipo de dato\n\n    // Tanto las tuplas como arrays pueden ser variables, variables mutables, constantes, o let let (shadowing)\n    // Por ultimo aclaro que si bien yo menciono let let, el termino correcto o al menos mas popular es Shadowing, let let es solo un chiste jajaja\n\n    println!(\"¡Hola, Rust!\"); // Imprimir por terminal\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/rust/pguillo02.rs",
    "content": "fn main(){\n    println!(\"Hola mundo\");\n\n    //En rust podemos tener variables mutables e inmutables \n\n    let mut x = 5;\n\n    let y = 5\n\n    let entero_signed: i32 = -42; // Entero con signo de 32 bits\n    let entero_unsigned: u64 = 42; // Entero sin signo de 64 bits\n\n    let flotante_f32: f32 = 3.14; // Punto flotante de 32 bits\n    let flotante_f64: f64 = 3.14159; // Punto flotante de 64 bits\n\n    let verdadero: bool = true;\n    let falso: bool = false;\n\n    let caracter = 'a'; // Carácter Unicode, Rust infiere el tipo (char por defecto)\n\n    let cadena_str = \"Hola, mundo!\"; // Cadena de texto en formato UTF-8 (tipo &str)\n    let cadena_string = String::from(\"¡Hola, mundo!\"); // Cadena de texto en formato UTF-8 mutable (tipo String)\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/rust/pipeyz21.rs",
    "content": "// Sitio web Rust: https://www.rust-lang.org/\n\n// Comentario de una línea\n\n/*  \n    Comentario \n    de\n    multiples\n    lineas \n*/\n\nfn main() {\n    // Crear una variable\n    let var_inmutable = 50;      // variable inmutable\n    let mut var_mutable: u8 = 5;  // variable mutable\n    const NUM_EULER = 2.71  // constante\n\n    // Crear variables representado los tipos primitivos\n    // Variables númericas enteras -> existen de 8, 16, 32 y 64 bits\n    let num: u8 = 1;        // u: negativos y positivos \n    let num_neg: i8 = -1;   // i: solo toma valores positivos\n\n    // variables númericas flotantes -> existen de 32 y 64 bits\n    let num_pi = 3.1416;\n\n    // variables booleanas\n    let verdadero = true;\n    let falso = false;\n\n    // variables de cadena de texto\n    let a: char = 'a';      // caracter\n    let b: &str = \"cadena de caracteres\";\n    let c: String = String::from(\"¡Hola Rust!\"); \n\n    println!(\"{}\", c)\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/rust/raulfauli.rs",
    "content": "/// # Documentación en https://www.rust-lang.org/\n\n// Comentario en una linea\n\n/*\n    Comentario\n    en varias\n    lineas\n*/\nfn main() {\n    // Variables\n    let y = 10; // Variable inmutable\n    let z: i32 = 15; // Variable inmutable con tipo de dato especificado\n    let mut x = 5; // Variable mutable\n\n    // Constantes\n    const PI: f32 = 3.1415; // Es necesario especificar el tipo de dato\n\n    // Tipos primitivos\n    let a: i8 = 127; // Entero de 8 bits\n    let b: i16 = 32767; // Entero de 16 bits\n    let c: i32 = 2147483647; // Entero de 32 bits\n    let d: i64 = 9223372036854775807; // Entero de 64 bits\n    let e: i128 = 170141183460469231731687303715884105727; // Entero de 128 bits\n    let f: isize = 9223372036854775807; // Entero de 32 o 64 bits dependiendo de la arquitectura\n\n    let g: u8 = 255; // Entero sin signo de 8 bits\n    let h: u16 = 65535; // Entero sin signo de 16 bits\n    let i: u32 = 4294967295; // Entero sin signo de 32 bits\n    let j: u64 = 18446744073709551615; // Entero sin signo de 64 bits\n    let k: u128 = 340282366920938463463374607431768211455; // Entero sin signo de 128 bits\n    let l: usize = 18446744073709551615; // Entero sin signo de 32 o 64 bits dependiendo de la arquitectura\n\n    let m: f32 = 3.1415; // Flotante de 32 bits\n    let n: f64 = 3.1415926535898; // Flotante de 64 bits\n\n    let o: bool = true; // Booleano\n    let p: char = 'a'; // Caracter unicode\n    let q: &str = \"Hola Rust!\"; // Cadena de caracteres\n\n    let s: String = String::from(\"Hola Rust!\"); // Cadena de caracteres dinamica\n\n    println!(\"¡Hola, Rust!\");\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/rust/santiagomac.rs",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n// Documentación de RUST: https://www.rust-lang.org/\n\n// Comentario de una línea\n\n/*\n   Comentario\n   de varias lineas\n*/\n\nfn main() {\n    let _age: i32 = 23;\n    const _NAME: &str = \"Santiago Mazuera\";\n\n    let _integer = 1;\n    let _char = 'c';\n    let _string = \"42\";\n    let _boolean: bool = true;\n\n    let language: String = String::from(\"Rust\");\n\n    println!(\"Hola {}\", language)\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/rust/tetotille.rs",
    "content": "// Sitio Web Oficial de rust\n// https://www.rust-lang.org\n\n/*\n    rust sigue la misma lógica de comentarios que c++ para los comentarios no documentales,\n    por lo que para los comentarios multilínea se utiliza el mismo método.\n    \n    Para los documentales se utiliza otro formato pero a su vez siempre siguen la misma lógica\n    de utilizar comentarios de una línea o multilínea.\n\n    referencia:\n    https://doc.rust-lang.org/reference/comments.html\n*/\n\nfn main(){\n    // Variables\n    let _x = \"Hello, World!\";\n    let mut _y = 5;\n    const _DOS_HORAS_EN_SEGUNDOS: u32 = 60 * 60 * 2;\n\n    // Tipos de datos\n    let _entero: i32 = 5;\n    let _flotante: f32 = 3.14;\n    let _booleano: bool = true;\n    let _caracter: char = 'a';\n    let _tupla: (i32, f64, u8) = (500, 6.4, 1);\n    let _arreglo: [i32; 5] = [1, 2, 3, 4, 5];\n    let string: String = String::from(\"rust\");\n\n    // Imprimir\n    println!(\"¡Hola, {string}!\");\n\n}\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/rust/vorosdev.rs",
    "content": "// Documentacion: https://www.rust-lang.org/ \n\n/*\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n*/\n\nfn main() {\n    // variables\n    let _immutable = 12;\n    let mut _mutable = \":D\";\n\n    // constante\n    const _CONSTANT: i32 = 20;\n\n    // tipos de datos primitivos\n    let _string: &str = \"Rust\";\n    let _floating32: f32 = 4.1 ;\n    let _floating64: f64 = 4.323;\n    let _number: i32 = 24;\n    let _boolean: bool = true;\n\n    // hello world\n    println!(\"Hola, {}!\", _string);\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/rust/zetared92.rs",
    "content": "// RETO #00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n\n// La documentación de Rust la podemos encontrar en: https://doc.rust-lang.org/book/\n\n/*\nEsto es un comentario\nen varias líneas\n*/\n\n// Declaración de variables y constantes\nfn main() {\n    let var = 15; // Variable\n    let permittivity = 8.8541878176; // Constante (Permitividad) \n\n\n// Tipos de datos primitivos\nlet character: char = 'Z'; // Caracteres\nlet integer: i32 = 15; // Int 32bits\nlet intwithoutsign: u64 = 420; // Int 64bits\nlet float: f64 = 3.141592; // Flotante 64bits\nlet boolean: bool = false; // Booleano\n\n// Strings\nlet str_1: &str = \"Hello, Rust!\" ;// Cadena de caracteres\nlet str_2: String = String::from(\"Hello, Ferris!\"); // Cadena de caracteres mutable\n\n// Prints\nprintln!(\"Hello {}!\", \"Rust\");\nprintln!(\"Variable: {}\", var);\nprintln!(\"Permittivity Constant: {}\", permittivity);\nprintln!(\"Character: {}\", character);\nprintln!(\"Integer: {}\", integer);\nprintln!(\"Integer without sign: {}\", intwithoutsign);\nprintln!(\"Float: {}\", float);\nprintln!(\"Boolean: {}\", boolean);\nprintln!(\"Strings: {}\", str_1);\nprintln!(\"Mutable String: {}\", str_2);\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/scala/Jmofuture.scala",
    "content": "object Main {\n    def main(args: Array[String]): Unit = {\n\n        // URL https://scala-lang.org/\n        \n        // Esto es un comentario\n        \n        /* \n        Esto tambien es un comentario\n        de varias lineas\n        */\n        \n        \n        // Variables\n        \n        var Entero: Int = 1\n        val EnteroInmutable: Int = 2\n        \n        //Tipos de datos primitivos\n        \n        //Numericos\n        \n        val OtroEnteroInmutable: Int = 1\n        var OtroEntero: Int = 1\n        val LongInmutable: Long = 12345678901L\n        var Long: Long = 12345678901L\n        val ShortInmutable: Short = 12345\n        var Short: Short = 12345\n        val ByteInmutable: Byte = 12\n        var Byte: Byte = 12\n        \n        val DobleInmutable: Double = 3.14\n        var Doble: Double = 3.14\n        val FlotanteInmutable: Float = 1234.45f\n        var Flotante: Float = 1234.45f\n        \n        \n        //Strings\n        \n        val CadenaInmutable: String = \"Hola Mundo!\"\n        var Cadena: String = \"Hola Mundo!\"\n        \n        // Booleano\n        \n        val VerdaderoInmutable: Boolean = true\n        var Verdadero: Boolean = true\n        \n        val FalsoInmutable: Boolean = false\n        var Falso: Boolean = false\n        \n        \n        print(\"Hello World!\")\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/scala/angelsanchezt.scala",
    "content": "// Sitio web oficial de Scala: https://www.scala-lang.org/\n// Puedes ejecutar el codigo de Scala en: https://scastie.scala-lang.org/\n\n\n// Comentario en una línea\n/* Comentario\n   en varias líneas */\n\n// Variable\nvar miVariable: String = \"Scala!\"\n\n// Constante (en Scala, las constantes son variables inmutables)\nval miConstante: Int = 42\n\n// Tipos de datos primitivos\nval entero: Int = 10\nval decimal: Double = 3.14\nval flotante: Float = 2.5f\nval caracter: Char = 'A'\nval booleano: Boolean = true\n\n// Imprimir por terminal\nprintln(s\"¡Hola, $miVariable\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/scala/edalmava.scala",
    "content": "// Comentario de una línea\n/* \n    Comentario de varias \n    líneas\n*/\n\n// Sitio oficial: https://scala-lang.org/\n\n// Variables y tipos de datos: https://docs.scala-lang.org/scala3/book/taste-vars-data-types.html\n\n// Inmutables\nval a = 0\n\n// Mutables\nvar c = 1\nc = 2          // Una variable var puede ser reasignada\n\n// Declaración de tipos\n\nval x: Int = 1 // Declaración explícita de tipo\nval y =  1     // Declaración implícita de tipo\n\n// Tipo primitivos (built-in)\nval b: Byte = 1\nval i: Int = 1\nval l: Long = 1\nval s: Short = 1\nval d: Double = 2.0\nval f: Float = 3.0\n\nval int = 123      // Por defecto es Int\nval flo = 1.0      // Por defecto es Double\n\nval lon = 1_000L   // val lon: Long = 1000\nval dou = 2.2D     // val dou: Double = 2.2\nval fla = 3.3F     // val fla: Float = 3.3\n\nval lenguaje = \"Scala\" //String\nval char = 'a'         // Char\n\n// booleanos\nval falso: Boolean = false\nval verdadero = true\n\nprintln(s\"¡Hola, $lenguaje!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/scala/franciscokarriere.scala",
    "content": "// link oficial de lenguaje SCALA\n// https://www.scala-lang.org/\n\n// link no oficial para hacer compilacion en linea para pruebas antes de instalar\n// https://scastie.scala-lang.org/\n\n//sintaxis de comentarios\n//comentario en Scala de una sola linea\n/* comentario en Scala\nde\nmultiples lineas\n */\n\n/** Este es comentario de tipo JavaDoc se puede tags como @param, @return,\n  * \\@throws, etc. entremezclado con el comentario.\n  */\n\nobject variables {\n// variable ejemplo\n  val b: Int = 25 // tipo de dato : Int\n  var c: Double = 34.67 // tipo de dato : Double (\n  // se pueden asignar y cambiar su valor)\n\n}\n\nobject constantes {\n//constante\n  val pi =\n    scala.math.Pi // la constante Pi es un valor numerico que representa el valor representado en matematica por la letra griega π,\n\n}\n\n//imprimo en terminal saludo\n\nobject HolaScala {\n\n  val scala = \"scala\"\n\n  def main(): Unit = {\n    println(\"Hola \" + scala + \"!\")\n  }\n}\n\nHolaScala.main()\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/scala/rianojnicolas.scala",
    "content": "// 1. Sitio web oficial del lenguaje de de programacion python\n// https://scala-lang.org/\n\n// 2. Sintaxis de comentarios\n// Este es un comentario de una linea\n\n/*\nEste es un comentario\nen varias lineas\n*/\n\n/**\n* Este es un comentario de Documentacion\n* para que el compilador lo lea\n*/\n\n// 3. Variables y Constantes\n\nvar myVariable = 1+1\nvar myVariable_1: Int = 1+1\n\nval myConst = 1+1\nval myConst_1: Int = 1+1\n\n// 4. Tipos de datos primitivos\n\nvar myByte: Byte = 1           // 8 bits con numeros enteros como simbolos\nvar myShort: Short = 10        // 16 bits con numeros enteros como simbolos\nvar myInt: Int = 1000          // 32 bits con numeros enteros como simbolos\nvar myLong: Long = 200000      // 64 bits con numeros enteros como simbolos\nvar myFloat: Float = 2.11      // Precision de 32 bits para numeros de punto flotante\nvar myDoible: Double = 100.40  // Precision de 64 bits para numeros de punto flotante\nvar myChar: Char = 'a'         // 16 bits con tipo de simbolo unicode\nvar myString: String = \"Hola\"  // Secuencia de tipo char\nvar myBool: Boolean = true     // Verdadero o falso\n\n// 5. Imprimir en terminal => \"¡Hola, python!\"\nprintln(\"¡Hola, scala!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/solidity/angelsanchezt.sol",
    "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n// Encuentra más información en: https://docs.soliditylang.org/\n\n// Este es un comentario de una línea en Solidity.\n\n/*\n  Este es un comentario de varias líneas en Solidity.\n  Puedes añadir más información aquí.\n*/\n\ncontract MiContrato {\n    // Variable\n    uint256 public miVariable;\n\n    // Constante\n    uint256 public constant MI_CONSTANTE = 42;\n\n    // Variables representando tipos de datos primitivos\n    bool public miBool = true;\n    int256 public miInt = -123;\n    uint256 public miUint = 456;\n    address public miAddress = 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4;\n    string public miString = \"Hola, mundo!\";\n    bytes32 public miBytes32 = 0x5a78f59fd5c970eddfdbb96bb5ca45671b63b3bb9c8427e4b9503260d297056a;\n\n    // Constructor\n    constructor() {\n        miVariable = 7;\n    }\n\n    // Función para imprimir por terminal\n    function imprimirSaludo() public pure returns (string memory) {\n        return \"Hola, Solidity!\";\n    }\n}\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/sql/JoferPG.sql",
    "content": "--https://www.microsoft.com/es-co/sql-server/sql-server-downloads\n\n--comentario simple de una linea\n\n/*Comentario compuesto \nde varias lineas/*\n\n--Tipo de variable:\nDECLARE @my_variable INT; --Variable local\nSET @my_varible = 10;\n\nDECLARE @@my_varible#2 INT; --Variable global\nSET @@my_varible#2 = 10;\n\n--Constante (en SQL las constantes son un valor especifico)\nDECLARE @My_Constante INT;\nSET @My_constante = 10;\n\n--tipos de datos primitivos\n\nDECLARE @char CHAR(60);\n        @date DATE;\n        @binary BINARY;\n        @money MONEY:\n        @time TIME;\n        @float FLOAT;\n        @int INT;\n\nSET @char = Zapato;\n    @date = 01/08/2024;\n    @binary = 1;\n    @money = 3000.29;\n    @time = 12:45:32.345;\n    @float = 4.7;\n    @int = 5;\n\n--Imprimir terminal de texto \nPRINT (\"Hola, SQL\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/sql/Nicojsuarez2.sql",
    "content": "# #00 SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n> #### Dificultad: Fácil | Publicación: 26/12/23 | Corrección: 02/01/24\n\n## Ejercicio\n\n```\n/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/sql/adrs1166ma.sql",
    "content": "\n/*\nEJERCICIO:\n- Crea un comentario en el código y coloca la URL del sitio web oficial del\n  lenguaje de programación que has seleccionado.\n- Representa las diferentes sintaxis que existen de crear comentarios\n  en el lenguaje (en una línea, varias...).\n- Crea una variable (y una constante si el lenguaje lo soporta).\n- Crea variables representando todos los tipos de datos primitivos\n  del lenguaje (cadenas de texto, enteros, booleanos...).\n- Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n*/\n\n/*\n🔥 sitio web oficial\nhttps://www.sql.org\n\nsitio web oficial Server\nhttps://learn.microsoft.com/en-us/sql\n\nDocumentacion \nhttps://www.quackit.com/sql_server/sql_server_2017/tutorial/create_a_database_in_sql_server_2017.cfm\n*/\n\n\n-- 🔥 Comentario en una linea \n\n/*  🔥Comentario en\nvarias lineas \n*/\n\n\n-- 🔥 Variables y Tipos de datos \n\nDECLARE @nombre VARCHAR(50) = 'SQL Server'; -- Variable\nDECLARE @entero INT = 10; -- Entero\nDECLARE @decimal DECIMAL(10,2) = 99.99; -- Decimal\nDECLARE @booleano BIT = 1; -- SQL no tiene booleanos puros, se usara BIT (1 = true, 0 = false)\nDECLARE @fecha DATE = '2025-01-29'; -- Fecha\nDECLARE @texto NVARCHAR(100) = 'Hola, SQL Server!'; -- Cadena de texto\nDECLARE @my_var VARCHAR(50);\nSET @my_var = 'Esta es la variable';\n\nDECLARE @fecha DATE; -- variable de tipo DATE\nSET @fecha = '2025-01-29'; -- Asignación\nPRINT @fecha; -- Imprimirlo\n\n/*\n\nchar -- almacenar tipo de datos de ancho fijo.\nvarchar -- almacena tipo de datos alfanumericos de ancho variable.\ntext -- almacena tipos de datos texto.\nnchar -- almacenar tipo de datos de ancho fijo.\nnvarchar -- almacena tipo de datos alfanumericos de ancho variable.\nbit -- almacena valores de 1 y 0\nint -- almacena valores entre -2,147,483,648 y 2,147,483,647.\nbigint -- almacena valores entre -9,223,372,036,854,775, 808 and 9,223,372,036,854, 775, 807\ndecimal -- almacena valores entre -10^38 + 1 to 10^38-1.\nnumeric -- almacena valores entre -10^38 + 1 to 10^38-1.\nmoney -- almacena valores entre -9,223,372,036,854,775,808 and 9,223,372,036,854, 775, 807\nfloat -- almacena valores entre -1.79E + 308 to 1.79E + 308.\n\n*/\n-- 🔥 Imprimir en la consola:\nPRINT '¡Hola, ' + @nombre + '!';\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/sql/angelsanchezt.sql",
    "content": "-- URL del sitio web oficial de SQL: https://www.sql.org/\n-- https://www.iso.org/standard/76583.html\n\n/*\n También el SQL a veces se describe como un lenguaje declarativo, también incluye elementos procesales.\n*/\n\n-- Este es un comentario de una sola línea en SQL.\n\n/* \n    Este es un comentario\n    que puede ocupar múltiples líneas en SQL. \n*/\n\n\n-- Variables\nDECLARE @mi_variable INT;\nSET @mi_variable = 42;\n\n-- Constantes (No todos los sistemas de base de datos admiten constantes)\nDECLARE @mi_constante INT;\nSET @mi_constante = 100;\n\n-- Tipos de Datos Primitivos:\nDECLARE @entero INT;\nDECLARE @decimal DECIMAL(10, 2);\nDECLARE @cadena VARCHAR(50);\nDECLARE @fecha DATE;\nDECLARE @booleano BIT;\n\n-- Impresión por Terminal:\nDECLARE @saludo NVARCHAR(50);\nSET @saludo = '¡Hola, SQL!';\nPRINT @saludo;\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/sql/augustosdev.sql",
    "content": "-- https://www.sql.org/\n\n-- Comentario en una linea \n\n/* Comentario en\nvarias lineas \n*/\n\nDECLARE @my_var VARCHAR(50);\nSET @my_var = 'Esta es la variable';\n\n-- Datos Primitivos\nDECLARE @type_numeric INTEGER;\nSET @type_numeric = 14;\nDECLARE @type_real REAL;\nSET @type_real = 10.5;\nDECLARE @type_char CHAR;\nSET @type_char = 'sinEspacios';\nDECLARE @type_varchar VARCHAR;\nSET @type_varchar = 'Con espacios';\nDECLARE @type_boolean BOOLEAN;\nSET @type_boolean = true;\nDECLARE @type_date DATE;\nSET @type_date = '2024-04-21';\nDECLARE @type_time TIME;\nSET @type_time = '21:54:12';\nDECLARE @type_timestamp TIMESTAMP;\nSET @type_char = '2024-04-21 21:55:15';\n\nPRINT \"Hola, SQL\";\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/sql/eulogioep.sql",
    "content": "-- URL del sitio web oficial de SQL (estándar ANSI)\n-- https://www.iso.org/standard/63555.html\n\n-- Diferentes formas de crear comentarios en SQL:\n\n-- 1. Comentario de una línea\n\n/*\n * 2. Comentario\n * de varias\n * líneas\n */\n\n-- Creación de una tabla para demostrar los tipos de datos\nCREATE TABLE EjemploTipos (\n    id INT PRIMARY KEY,\n    texto VARCHAR(50),\n    numero_entero INT,\n    numero_decimal DECIMAL(10, 2),\n    fecha DATE,\n    hora TIME,\n    fecha_hora DATETIME,\n    booleano BOOLEAN\n);\n\n-- Inserción de datos para demostrar los tipos\nINSERT INTO EjemploTipos (id, texto, numero_entero, numero_decimal, fecha, hora, fecha_hora, booleano)\nVALUES (1, 'Hola, SQL!', 42, 3.14, '2024-09-11', '12:00:00', '2024-09-11 12:00:00', TRUE);\n\n-- Consulta para mostrar los datos (equivalente a \"imprimir\")\nSELECT 'Hola, SQL!' AS saludo;\n\n-- Consulta para mostrar todos los datos insertados\nSELECT * FROM EjemploTipos;\n\n-- Uso de variables (en algunos sistemas de gestión de bases de datos)\n-- Nota: La sintaxis puede variar según el sistema que se use\n\n-- En MySQL:\nSET @mi_variable = 'Valor de ejemplo';\nSELECT @mi_variable;\n\n-- En SQL Server:\nDECLARE @mi_variable VARCHAR(50) = 'Valor de ejemplo';\nSELECT @mi_variable;\n\n-- En PostgreSQL:\nDO $$\nDECLARE\n    mi_variable VARCHAR(50) := 'Valor de ejemplo';\nBEGIN\n    RAISE NOTICE 'Mi variable: %', mi_variable;\nEND $$;\n\n-- Creación de una constante (simulada mediante una vista)\nCREATE VIEW ConstanteEjemplo AS\nSELECT 42 AS MI_CONSTANTE;\n\n-- Consulta de la constante\nSELECT * FROM ConstanteEjemplo;"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/sql/idiegorojas.sql",
    "content": "/*\n01 Sintaxis, Variables y Tipos de Datos\n*/\n\n-- Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n-- Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n-- Crea una variable (y una constante si el lenguaje lo soporta).\n-- Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n-- Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\n-- El lenguaje de programación seleccionado es SQL.\n-- URL de uno de los sitios web oficiales: https://www.oracle.com/database/technologies/appdev/sql.html\n\n-- Comentario de una linea\n\n/* \nComentario de varias lineas\n*/\n\n-- Declaración de una variable\nDECLARE @variable_name datatype;\nSET @variable_name = value;\n\n-- Declaración de una constante\nDECLARE @constant_name datatype;\nSET @constant_name = value;\n\n-- Ejemplo:\nDECLARE @totalSales INT;\nSET @totalSales = (SELECT SUM(sales) FROM sales_table);\n\n\n/*\nTipos de datos\n*/\n\n-- Tipos de datos numéricos:\n-- INT: Enteros.\n-- SMALLINT: Enteros pequeños.\n-- BIGINT: Enteros grandes.\n-- FLOAT: Números de punto flotante.\n-- REAL: Números de punto flotante de precisión simple.\n-- DECIMAL: Números decimales con una precisión específica.\n-- NUMERIC: Similar a DECIMAL, pero conforme al estándar SQL.\n\n-- Tipos de datos de caracteres:\n-- CHAR(n): Cadena de caracteres de longitud fija.\n-- VARCHAR(n): Cadena de caracteres de longitud variable.\n-- TEXT: Cadena de caracteres de longitud variable, usada para texto largo.\n\n-- Tipos de datos de fecha y hora:\n-- DATE: Fecha (año, mes y día).\n-- TIME: Hora (hora, minuto y segundo).\n-- DATETIME: Combinación de fecha y hora.\n-- TIMESTAMP: Marca de tiempo.\n-- YEAR: Año.\n\n-- Tipos de datos binarios:\n-- BINARY: Datos binarios de longitud fija.\n-- VARBINARY: Datos binarios de longitud variable.\n-- BLOB: Objeto binario grande, usado para almacenar datos binarios como imágenes o archivos.\n\n-- Tipos de datos booleanos:\n-- BOOLEAN: Valores de verdadero o falso.\n\nCREATE TABLE example_table(\n    id INT,\n    name VARCHAR(50),\n    birthdate DATE,\n    salary FLOAT\n);\n\n-- Hola SQL\nPRINT \"¡Hola, SQL!\";"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/sql/llonardo798.sql",
    "content": "\n-- 1. Documentación oficial en  https://www.iso.org/standard/76583.html\n-- Documentación complementaria en https://www.w3schools.com/sql/ se divide por cada gestor de base de datos y por ejemplos.\n\n-- 2. Tipos de comentarios.\n\n-- Comentario de una línea en SQL\n\n/*\nComentario de varias líneas\nen SQL\n*/\n\n-- 3. Vairables y Constantes segun lenguaje\n-- En SQL Nativo no existe una forma de declarar variables ni constantes, por lo cual depende del SGBD (sistema gestor de base de datos)\n\n\n-- SQL Server\n-- Declarar una variable\nDECLARE @variable VARCHAR(50);\n-- Asignar un valor a una variable\nSET @variable = 'SQL Server'; \n-- Todo junto\nDECLARE @otraVariable INT = 20;\n\n\n-- Oracle\nDECLARE\n  mi_variable NUMBER;\nBEGIN\n  mi_variable := 10;\nEND;\n\n\n-- MySQL\nSET @miVariable = 10;\n\n\n-- 4. Tipos de datos primitivos.\n-- Tipos numéricos:\n\nDECLARE @variable INTEGER(10);          -- Números enteros.\nDECLARE @variable2 INT;                 -- Números enteros.\nDECLARE @variable3 SMALLINT;            -- Enteros pequeños.\nDECLARE @variable4 BIGINT;              -- Enteros grandes.\nDECLARE @variable5 DECIMAL(10,2);       -- Números decimales de precisión fija.\nDECLARE @variable6 FLOAT(10);           -- Números de punto flotante.\nDECLARE @variable7 REAL;                -- Números de punto flotante de precisión simple.\nDECLARE @variable8 DOUBLE PRECISION;    -- Números de punto flotante de doble precisión.\n\n-- Tipos de caracteres:\n\nDECLARE @variable9 CHAR(10);            -- Cadena de caracteres de longitud fija. Ocupa la misma cantidad de espacio en disco.\nDECLARE @variable10 VARCHAR(10);        -- Cadena de caracteres de longitud variable. Ocupa solo el espacio usado por la cantidad de caractres.\nDECLARE @variable11 CHARACTER VARYING(10); -- Cadena de caracteres de longitud variable. Equivalente a VARCHAR se diferencia solo por el nombre segun estandar ANSI SQL\n\n-- Tipos de fecha y hora:\n\nDECLARE @variable12 DATE;               -- Fecha (año, mes, día).\nDECLARE @variable13 TIME;               -- Hora (hora, minuto, segundo).\nDECLARE @variable14 TIMESTAMP;          -- Combinación de fecha y hora.\nDECLARE @variable15 INTERVAL;           -- Representa un intervalo de tiempo.\n\n-- Tipos booleanos:\n\nDECLARE @variable16 BOOLEAN;            -- Valor booleano. Puede almacenar TRUE, FALSE o NULL.\n\n-- Tipos binarios:\n\nDECLARE @variable17 BINARY(10);         -- Datos binarios de longitud fija.\nDECLARE @variable18 VARBINARY(10);      -- Datos binarios de longitud variable.\n\n-- Otros tipos:\n\nDECLARE @variable19 CLOB;              -- Caracteres grandes.\nDECLARE @variable20 BLOB;              -- Binarios grandes.\n\n\n-- 5. Imprimir en consola.\n\nPRINT '¡Hola, ' + @variable + '!';\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/sql/salkalero.sql",
    "content": "/* No encuentro una web oficial de SQL, \npor lo menos uno que me de confianza, asi que pongo éste\nque sí es de confianza. https://www.w3schools.com/sql/ */\n\n-- Para los comentarios en una sola línea se usa \"--....\"\n\n/* Para los comentarios en varias líneas\nse utiliza /*....*/ */ \n\n/*La variable se forma de dos instrucciones: \"DECLARE\" y \"SET\" \n(Sintaxis DECLARE: \"Instrucción\", \"NombreVariable\", \"Tipo de Datos\")\n(Sintaxis SET: \"Instrucción\", \"Nombre de la variable DECLARE \na la que hace referencia\", \"=\", \"Valor\")*/\n\nDECLARE @NombreVariable INT ;/*en una instrucción se puede añadir \n                            más de una variable.*/\n        @NombreVariable2 VARCHAR(50) ;\n\nSET     @NombreVariable = 25 ;/*en una instrucción se puede añadir \n                            más de un valor.*/\n        @NombreVariable2 = María de la O ;\n\n/*SQL no soporta constantes de forma nativa pero puedes usar una \nvariable para simular una constante*/\n DECLARE @NombreConstante INT ;\n\n SET    @NombreConstante = 50 ;/*Sólo hay que evitar cambiar este \n                                valor y declararlo en un comentario.*/\n\n\n--Variables y sus tipos de datos nativos (algunos)\n\nDECLARE @char CHAR(50) ;\n        @binary BINARY ;\n        @bool BOOLEAN ;\n        @int INT ;\n        @float FLOAT ;\n        @date DATE ;\n        \nSET     @char = Pepe ;\n        @binary = 1 ;\n        @bool = true ;\n        @int = 2 ; \n        @float = 2.5 ; \n        @date = 2025/12/13 ;\n\n\nPRINT (\"Hola,SQL\") ;\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/swift/18miguelgalarza.swift",
    "content": "\n/*\n *\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\nimport Foundation\n\n//Sitio web oficial de Swift https://www.swift.org\n\n//Comentario en una línea\n\n/*\n Comentario\n de\n varias \n líneas\n*/\n\nvar variable = \"mi primer var\"\nlet constante = \"mi primera constante\"\n\nvar entero = \"mi primer entero\"\nvar cadena = \"mi primer String\"\nvar double  = \"mi primer double\"\nvar booleano = true\n\nlet lenguaje = \"Swift\"\nprint(\"¡Hola, \\(lenguaje)!\")\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/swift/DevM0nk3y.swift",
    "content": "/*\n* EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n */\n\nimport Foundation\n\n// sitio web oficial de swift https://www.swift.org\n\n//comentario de una linea\n\n/*\n comentarios\n de multiples\n lineas\n */\n\n/*\n /* comentario anidado */\n*/\n\nvar myVariable = \"Im a variable\"\nlet myConstant = \"Im a constant\"\n\n//Int: Un entero con signo, que puede ser positivo, negativo o cero. Su tamaño depende de la plataforma (32 o 64 bits).\nvar myInt = 1\n\n//UInt: Un entero sin signo, que solo puede ser positivo o cero.\nvar myUInt = 100\n\n//Float: Número de punto flotante de precisión simple (32 bits).\nvar myFloat = 1.12345\n\n//Double: Número de punto flotante de precisión doble (64 bits). Se usa cuando necesitas más precisión que Float.\nvar myDouble = 1.1234567890\n\n//Boolean: Valores que representan verdadero o falso (true o false).\nvar myBool = true\n\n//String: Tipo de dato que almacena texto.\nvar myString = \"Swift\"\n\n//Character: Almacena un solo carácter.\nvar myChar = \"a\"\n\nprint(\"¡Hola, \\(myString)!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/swift/JuitoMG.swift",
    "content": "// EJERCICIO:\n// -Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n\n// https://www.swift.org\n\n\n// - Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n\n// Comentario en una línea\n\n/*\nComentario\nen varias\nlíneas\n*/\n\n\n// - Crea una variable (y una constante si el lenguaje lo soporta).\n\nvar pajaro: String = \"loro\"\nlet pi: Float = 3.14\n\n\n// - Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n\nvar cadena: String = \"Nombre\"\nvar entero: Int = 4\nvar float: Float = 4.8\nvar booleano: Bool = true\nvar double: Double = 3.14159\n\n\n// - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\nvar lenguaje: String = \"Swift\"\nprint(\"Hola, \\(lenguaje)!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/swift/MarcSL2014.swift",
    "content": "// https://developer.apple.com/swift/\r\n// Una linea\r\n/* Varias\r\nlineas **/\r\n\r\nvar variable = \"\"\r\nlet constante = \"\"\r\n\r\nvar bool:Bool = true\r\nvar texto:String = \"Hola\"\r\nvar entero:Int = 1\r\nvar float:Float = 1.99\r\nvar double:Double = 1.9999999999\r\nvar character:Character = \"H\"\r\n\r\nprint(\"¡Hola, Swift!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/swift/PeibolStrike.swift",
    "content": "/*\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\nimport UIKit\n\n//Esta es la URL del sitio web oficial de Swift https://www.swift.org\n\n//Este es un comentario en una línea\n/*\n Este es un comentario\n que ocupa\n varias líneas\n */\n\nvar variable = \"Hola! Soy una variable\" // Variable\nlet constante = \"Hola! Soy una constante\" // Constante\n\nvar entero = 11 // Variable Int\nvar string = \"Hola! Soy una string\" // Variable String\nvar double = 14.5346 // Variable double\nvar booleano = true // Variable booleano, puede contener true o false\n\nlet lenguaje = \"Swift\"\nprint(\"¡Hola, \\(lenguaje)!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/swift/PineroDev.swift",
    "content": "import Foundation\n\n// Esta es la pagina oficial de Swift https://www.swift.org/\n\n// Comentario de una sola linea\n\n/* Comentario de\n   varias linias de\n   texto*/\n\nvar miVariable: Int\nlet miContante: double\n\nvar miCadena: String = \"Texto\"\nvar miEntero: Int = 45\nvar miDecimal: Double = 3.14\nvar esVerdadero: Bool = false\n\nprint(\"¡Hola, Swift!\")\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/swift/Sirvega83.swift",
    "content": "\nimport SwiftUI\n\n//EJERCICIO:\n// * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n// *   lenguaje de programación que has seleccionado.\n\n//https://developer.apple.com/swift/\n\n// * - Representa las diferentes sintaxis que existen de crear comentarios\n// *   en el lenguaje (en una línea, varias...).\n\n//Comentario 1\n/*\n Multiples\n comentarios\n */\n\n// * - Crea una variable (y una constante si el lenguaje lo soporta).\n\nvar myLanguague: String = \"Swift\"\nlet year: Int = 2024\n\n// * - Crea variables representando todos los tipos de datos primitivos\n// *   del lenguaje (cadenas de texto, enteros, booleanos...).\n\n\nvar myAge: Int = 40\nvar myMoneyBag = 41.5\nvar myExactMoneyBag: Double = 41.52\nvar myName = \"Said\"\nvar myChar: Character = \"S\"\nvar myAgeBool = true\n\n// * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\nprint(\"¡Hola \\(myLanguague)!\")\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/swift/allbertoMD.swift",
    "content": "import Foundation\n\n// Esta es la pagina de Swift: https://www.swift.org\n\n/*\n Esto es un comentario de multiples lineas\n 1.\n 2.\n 3.\n */\n\n let constant = \"Alberto\"\n var varialbe = 39\n\n var string: String = \"Esto es un string\"\n var boolean: Bool = true\n var integer: Int = 1\nvar floating: Float = 1.1\nvar double: Double = 1.10000\n\nprint(\"Hello Swift\")\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/swift/blackriper.swift",
    "content": "import Foundation\n\n//https://www.swift.org/\n\n// comentario de una lineal \n\n/* comenterio de varias lineas\n   de texto  \n */\n\n//variable\n var heroe=\"Ironman\"\n print(heroe)\n\n var enemy:String\n enemy=\"Thanos\"\n print(enemy)\n\n//constante\nlet lenguage=\"Swift\"\n\n//tipos de datos primitivos\nvar name:String\nvar age:Int\nvar height:Float\nvar weight:Double\nvar isMarried:Bool\n\n//mostrar por consola\nprint(\"Hola \\(lenguage)!\")\nprint(\"Hola \"+lenguage)\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/swift/cardonagustavo.swift",
    "content": "\n\n* EJERCICIO:\n* - Crea un comentario en el código y coloca la URL del sitio web oficial del\n*   lenguaje de programación que has seleccionado.\n* - Representa las diferentes sintaxis que existen de crear comentarios\n*   en el lenguaje (en una línea, varias...).\n* - Crea una variable (y una constante si el lenguaje lo soporta).\n* - Crea variables representando todos los tipos de datos primitivos\n*   del lenguaje (cadenas de texto, enteros, booleanos...).\n* - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n\n\n// Official website: https://developer.apple.com\n\n// Single-line comment\n\n/*\n Multi-line comment\n */\n\n/// Documentation comment\n\n// MARK:  A mutable variable and an immutable constant\nvar mutable: String = \"variable format\"\nlet immutable: String = \"constant format\"\n\n// MARK: Primitive data types\nvar string: String = \"Hello, Swift!\"\nvar number: Int = 10\nvar boolean: Bool: true\nvar float: Float = 3.14\nvar double: Double = 3.14159\nvar letter: character = \"a\"\nvar emoji: UnicodeScalar = \"😄\"\n\n// MARK: Print the greeting\nprint(string)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/swift/chuanmi.swift",
    "content": "/*EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n import UIKit\n\n // Voy a utilizar https://www.swift.org\n\n// esto es un comentario de 1 linea.\n\n/* esto es un\n comentario de\n varias lineas\n */\n\nlet lenguaje: String = \"Swift\"\nvar variable: String = \"Esto será una variable de tipo string\"\n\nvar boolean: Bool = true\nvar integer: Int = 10\nvar floating: Float = 14.09\nvar double: Double = 3.1416\n\nprint(\"¡Hola, \\(lenguaje)!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/swift/corvo-99.swift",
    "content": "//https://www.swift.org/\n\n//Single line comment\n\n/*Multi\n line\n comment\n */\n\n/* Multi line comment start\n    /* Nested multiline comment. */\nEnd of the first multiline comment. */\n\n\n//En swift los tipos pueden estar expresados o ser inferidos\nvar myVar = \"Esta es mi variable\"\nlet myLet: String = \"Constante con el tipo String declarado\"\n\nlet myInt: Int = 1      //Integers\nlet myDouble: Double = 3.14     //Floating-point numbers\nlet myBool: Bool = false        //Boolean\nlet myString: String = \"Swift\"    //String\n\nprint(\"Hola \\(myString)!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/swift/danielCastillo1112.swift",
    "content": "//\n//  danielCastillo1112.swift\n//  \n//\n//  Created by Daniel Castillo on 27-07-24.\n//\n\nimport Foundation\n//https://www.swift.org/\n/*este es un comentario multilinea\n */\n/**\n este es un comentario para documentacion de multiple linea\n */\n///este es para la documentacion para una linea\n\nvar ejercicioParaVar = \"Mi primera variable\"\nlet miConstante = \"1\"\n\nvar string = \"esta es mi cadena de texto\"\nvar integer = 1\nvar double: Double = 1.2\nvar bool = true\nvar float: Float = 2.345\n\nprint(\"¡Hola,swift!\")\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/swift/didacdev.swift",
    "content": "// https://www.swift.org\n\nimport Fundations\n\n// Comentario de una línea\n\n/*\n    Comentario\n    de\n    varias\n    líneas\n */\n\n let name = \"Diego\" // constante\n var age = 27 // variable\n\n var integer: Int = 0\n var float: Float = 0.1\n var double: Double = 0.01\n var string: String = \"hola\"\n var boolean: Bool = true\n\n print(\"¡Hola, Swift!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/swift/edalmava.swift",
    "content": "// Comentario de una línea\n\n/*\n   Comentario de varias líneas\n\n   Sitio oficial: https://www.swift.org/\n*/\n\n// Declaración de variables\nvar nombreVariable = 0\n// Con anotación de tipo\nvar variable : Int = 0\n\n// Declaración de constantes\nlet nombreConstante = 10\n// Con anotación de tipo\nlet constante : Int = 10\n\n// Tipo Entero\nlet entero = 10\nlet binario = 0b1111\nlet octal = 0o10\nlet hexadecimal = 0x11\n\nlet int    : Int   = 0\nlet int32  : Int32 = 0\nlet int64  : Int64 = 0\nlet uint   : UInt  = 0\nlet uint32 : UInt32 = 0\nlet uint64 : UInt64 = 0\n\n// Tipo Double y Float\nlet doblePF = 1.0\n\nlet doble : Double = 10.00000015\nlet flotante : Float = 15.0\n\n// Tipo Booleanos\nlet verdadero = true\nlet falso = false\n\nlet bool : Bool = true\n\n// Tuplas\nlet http404Error = (404, \"Not Found\")\nlet (statusCode, statusMessage) = http404Error\n\n// Cadenas\nlet cadena = \"Esto es una cadena de texto\"\n\nlet saludo : String = \"Hola\"\nlet lenguaje : String = \"Swift\"\n\nprint(\"¡\\(saludo), \\(lenguaje)!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/swift/franpua.swift",
    "content": "import Foundation\n\n// Lenguaje utilizado --> www.swift.org\n\n// Este es un comentario en un línea\n\n/* Este puede ser\n un comentario\n en varias líneas o para comentar fragamentos de código agrupado.\n */\n\nlet constante = \"La palabra reservada let es para crear constantes en swift\"\n\nvar variable = \"La palabra reservada var es para crear variables en swift\"\n\nvar numerosEnteros: [Int] = [46, 17, 05]\n\nvar numerosDecimales: [Double] = [0.5, 1,6, 3,1415]\n\nvar booleano: Bool = true\n\nvar cadena: String = \"Roadmap Retos 2024\"\n\nlet languaje = \"Swift\"\n\nprint(\"Hola \\(languaje) !\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/swift/gianninagit.swift",
    "content": "/*\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n */\n\n// https://www.swift.org/\n\n// Comentario de una línea\n\n/*\n Comentario\n en varias\n líneas.\n */\n\nvar aVariable\nlet aConstant\n\nvar myIntVariable = 42\nmyIntVariable = 50\nvar myConstant = 42\nvar explicitFloat: Float = 4.0\nvar myDouble = 3.1416\nvar myBool = true\n\nprint(\"¡Hola, \\(\"Swift\")\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/swift/gliadev.swift",
    "content": "import Foundation\n\n/*\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n\n// Esto es un comentario de una sola línea en Swift\n\n// URL del sitio web oficial de Swift: https://swift.org\n\n/*\n Esto es un comentario\n de varias líneas\n en Swift\n*/\n\n// Crear una variable\nvar variableDinamica = \"Soy una variable\"\n\n// Crear una constante\nlet constanteEstatica = \"Soy una constante\"\n\n// Variables con tipos de datos primitivos\nvar entero: Int = 42             // Un entero\nvar decimal: Double = 3.14       // Un número decimal\nvar cadena: String = \"Swift\"     // Una cadena de texto\nvar booleano: Bool = true        // Un valor booleano\n\n// Imprimir en la terminal\nprint(\"¡Hola, \\(cadena)!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/swift/karys4.swift",
    "content": "// https://www.swift.org/documentation/\n/*  Hola \n    soy\n    un comentario \n    de \n    múltiples\n    líneas\n*/\n\n// Constante\nlet nombre: String \n\n// Variable\nvar edad: Int \n\n// Tipos de datos primitivos\nvar cadena: String\nvar entero: Int\nvar doble: Double\nvar flotante: Float \nvar caracter: Character \nvar booleano: Bool \n\nprint(\"Hola Swift\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/swift/kontroldev.swift",
    "content": "/*\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n */\n\n// URL oficial del lenguaje: https://www.swift.org\n\n// Comentarios en Swift:\n// Comentario de una línea\n/*\n Comentario de \n varias líneas\n */\n\n// Constante\nlet mensajeConstante = \"Esto es una constante\"\n\n// Variable\nvar mensajeVariable = \"Esto es una variable\"\n\n// Tipos de datos primitivos\nvar texto: String = \"Esto es una cadena de texto\"\nvar numeroEntero: Int = 42\nvar numeroDecimal: Float = 3.14\nvar numeroDoble: Double = 2.718281828\nvar valorBooleano: Bool = true\n\n// Nombre del lenguaje\nlet lenguaje = \"Swift\"\n\n// Imprimir mensaje en consola\nprint(\"¡Hola, \\(lenguaje)!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/swift/malkarmah.swift",
    "content": "import UIKit\n\n/*EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n// https://www.swift.org/\n\n//Esto es un comentario\n\n/* Esto es un comentario\n en varias lineas */\n\nvar var1 = \"Esto es una variable\"\nlet const1 = \"Esto es una constante\"\n\nvar int = 98\nvar double = 6.66432706\nvar float = 7.5\nvar bool = true\nvar string = \"Esto es un string\"\n\nprint (\"¡Hola, Swift!\")\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/swift/miguelex.swift",
    "content": "import UIKit\n\n// Documentación en https://developer.apple.com/documentation/swift\n\n// Comentario en una linea\n\n/* Comentario\n en varias\n líneas */\n\nvar lenguaje = \"Swift\" // Variable\n\nlet PI = 3.1415 // Constante\n\n// Tipos primitivos\n\nvar cadena: String = \"Esto es una cadena\"\nvar numero: Int = 1\nvar decimal: Float = 3.1415\nvar decimalGrande: Double = 2.717171717\nvar booleano: Bool = true\n\n// Mostrar por consola\n\nprint(\"Hola \\(lenguaje)!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/swift/nahuelborromeo.swift",
    "content": "// https://developer.apple.com/swift/\n\n// Este es un comentario de una línea\n\n/*\nEste es un comentario\nde varias líneas\nen Swift\n*/\n\n//Variables:\n\nvar myFirtsVariable = 18\n\n//Constantes:\n\nlet myFirstConstant = 3.1416\n\n//Tipos de datos primitivos:\n\n//INT: (Enteros)\n\nlet numeroEntero: Int = 42  /* Nota: Se puede especificar el tamaño del entero\n                            con Int8, Int16, Int32 e Int64\n                            para un control más preciso\n                            */\n\n//UINT: (Enteros positivos, sin signo)\n\nlet numeroSinSigno: UInt = 42 /* Nota: Se puede especificar el tamaño del entero\n                            con Int8, Int16, Int32 e Int64\n                            para un control más preciso\n                            */\n    \n//Float: (Flotante 32 bits)\n\nlet numeroFloat: Float = 3.14\n\n//Double: (Flotante 64 bits)\n\nlet numeroDouble: Double = 3.14159265359\n\n//Bool: (Booleano)\n\nlet esVerdadero: Bool = true\nlet esFalso: Bool = false\n\n//Character (Carácter Unicode)\n\nlet letra: Character = \"N\"\n\n//String: (Cadena de texto)\n\nlet nombre: String = \"Nahuel Borromeo\"\n\n//Imprimir en consola:\n\nprint(\"¡Hola, Swift!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/swift/paola-itzel-martinez.swift",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n\n\n/*\n Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n */\n\n//https://swift.org\n\n\n\n/*\n Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n */\n\n// one line\n\n/*\n multiple lines\n */\n\n/* This is the start of the first multiline comment.\n    /* This is the second, nested multiline comment. */\nThis is the end of the first multiline comment. */\n\n\n\n/*\n Crea una variable (y una constante si el lenguaje lo soporta).\n */\n\nvar oneVariable: String\n\nlet oneConstant: String\n\n\n\n/*\n Crea variables representando todos los tipos de datos primitivos\n del lenguaje (cadenas de texto, enteros, booleanos...).\n */\n\nlet dataString: String = \"dataString\"\n\nlet dataInt: Int = 1\n\nlet dataFloat: Float = 1.1\n\nlet dataDouble: Double = 1.1416\n\nlet dataBoolean: Bool = true\n\n\n/*\n Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n */\n\nprint(\"¡Hola, Swift!\")\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/swift/pedroomar23.swift",
    "content": "import Foundation \n\n## Ejercicio\n\n```\n/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n// El sitio web para buscar la documentacion de Swift es https://www.swift.org\n\n// Esto es una comentario en una sola linea \n\n/* Esto es una comentario \n    varias lineas\n*/\n \n var texto // Esto es una variable \nlet texto // Esto es una contante \n\nvar text = \"Swift es el lenguaje de programcion que se utiliza para desarrollo iOS\" // String \nlet double = 100 // Aqui podemos var un double que se utiliza para definir los enteros \nvar booleano = false or true // Esto principalmente se utiliza en las propiedades \n\nvar lenguaje = \"!Hola, Swift es un lenguaje de programación\" // Este texto de tipo String va aparecer en la consola \nprint(\"\\(lenguaje)\") // Expresión que se utiliza para imprimir datos en la consola "
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/swift/sgb004.swift",
    "content": "// https://www.swift.org/\n\n/* https://www.swift.org/ */\n\nlet constant = \"Constant\"\nvar variable = \"Variable\"\n\nvar varInt: Int = 1\nvar varUInt: UInt = 2\nvar varFloat: Float = 3.45\nvar varDouble: Double = 6.78\nvar varBool: Bool = true\nvar varCharacter: Character = \"A\"\nvar varString: String = \"String\"\n\nprint(\"¡Hola Swift!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/swift/zetared92.swift",
    "content": "// El lenguaje que voy a aprender en este 2024 es https://www.swift.org/\n\n/* Esto es un comentario\nmultilínea. */\n\n/* También se pueden hacer comentarios multilínea.\n    /*Como si fueran dos líneas independientes dentro\n    del mismo apartado.*/\nesto facilita el agrupar los comentarios. */\n\nlet constante = x // Se declara las constantes con let\nvar variable = y // Las variables se declaran con var\n\n/* Los nombres de las constantes y las variables,\npueden contener cualquier tipo de caracter.\n    /* Aunque es recomendable ser claros y concisos.\n    No usar espacios en blanco ni símbolos matemáticos.*/\nIncluido emojis!. */\n\n\nvar int = 15 // numero entero\nvar double = 3.14159265 // numero flotante hasta 15 decimales\nvar float = 1.5 // numero flotante hasta 6 decimales\nvar bool = true // numero booleano 0 (false) o 1 (true)\nvar string = \"Roadmap 2024\" // cadena de caracteres\n\nprint(\"¡Hola, Swift!\")\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/tcl/edalmava.tcl",
    "content": "#!/usr/bin/tclsh\n\n# Comentario en tcl\n\n# Sitio oficial: https://www.tcl-lang.org/\n\n# Con set se asignan valores a una variable\nset lenguaje Tcl;  # Comentario en línea luego de un comando terminado con ;\n\nset entero 5;       # Número entero\nset saludo Hola;    # Cadena\nset verdadeeo true; # Booleano\nset falso false;    # Booleano\n\nputs \"¡$saludo, $lenguaje!\";    # Imprimir Texto\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/AChapeton.ts",
    "content": "// Sitio web oficial: https://www.typescriptlang.org/docs/\n\n// Comentario de una linea\n\n/* Comentario\nen multiples\nlineas */\n\nconst languageName: string = 'Typescript';\n\nlet stringType: string = 'string';\nlet numberType: number = 10;\nlet booleanType: boolean = true;\nlet nullType: null = null;\nlet undefinedType: undefined = undefined;\n\nconsole.log(\"Hola \" + languageName + \"!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/Andeveling.ts",
    "content": "// Pagina oficial de TypeScript\n// https://www.typescriptlang.org/\n// Comentarios en TypeScript\n\n// Esto es un comentario de una sola linea\n\n/* Esto es un comentario de \nmultiples lineas */\n\n\n// Variable\nlet saludar: string = 'Hola'\n\n// Constante\n const lenguaje: string = 'TypeScript'\n\n// 📌 Datos Primitivos\n// String\nlet texto: string = 'Texto'\nlet mensaje: string = 'Hola esto es un string también'\n\n// Numbers\nlet numero: number = 123\nlet decimal: number = 3.1416\nlet negativo: number = -123\nlet enteroGrande: bigint = 1234567890123456789012345678901234567890n\n\n// Booleans\nlet verdadero: boolean = true\nlet falso: boolean = false\n\n// Symbol\nlet simbolo: symbol = Symbol('mi-simbolo') \n\n// Undefined\nlet indefinido: undefined = undefined\n\n// Null\nlet nulo: null = null\n\n// Imprimir por terminal\nconsole.log(\"¡Hola, TypeScript!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/AxelWestman.ts",
    "content": "\n// Crea un comentario en el código y coloca la URL del sitio web oficial del\n//lenguaje de programación que has seleccionado:\n\n//Sitio web oficial: https://www.typescriptlang.org/docs/\n\n//Representa las diferentes sintaxis que existen de crear comentarios\n//en el lenguaje (en una línea, varias...).\n\n//Esto es un comentario de una linea\n/*Esto también\n es un comentario\n en múltiples lineas*/ \n\n\n//Crea una variable (y una constante si el lenguaje lo soporta).\nlet variable: string = 'cadena';\nconst constante: string = 'constantes';\n\n/*Crea variables representando todos los tipos de datos primitivos\n   del lenguaje (cadenas de texto, enteros, booleanos...). */\n\nlet stringType: string  = 'string';\nlet numberType: number = 24;\nlet booleanType: boolean = true;\nlet nullType: null = null;\nlet undefinedType: undefined= undefined;\n\n//Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\nconsole.log(\"¡Hola, TypeScript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/BertoMP.ts",
    "content": "// WEB OFICIAL\n// Para encontrar información sobre TypeScript, se puede utilizar la web:\n// https://www.typescriptlang.org/\n\n// COMENTARIOS\n// En TypeScript existen tres tipos de comentarios:\n// - Comentarios de una única línea (// Comentario):\n// Esto es un comentario de una línea y puede servir, por ejemplo, para explicar una variable.\n\n// - Comentarios de varias líneas (/* Comentario */):\n/* Esto es un comentario\n * de varias líneas y puede\n * servir para explicar una parte\n * más extensa del código. */\n\n// - Comentarios de documentación (/** Comentario */):\n/**\n * Este tipo de comentarios nos van a servir para documentar\n * nuestro código y van a permitir la generación de documentación\n * automática llamada TSDoc que facilita la comprensión\n * y el mantenimiento del código.\n * Al igual que pasa con otros lenguajes, pueden ir acompañados\n * de etiquetas como @param o @return que identifican valores\n * como los parámetros de entrada de la función o el valor de\n * retorno que produce la función. */\n\n// VARIABLES Y CONSTANTES\n/* - Variables: En TypeScript, se puede declarar una variable utilizando 'let' o 'var' seguido del nombre de la\n                variable, dos puntos (:), el tipo de dato y el valor asignado.\n                La declaración con 'var' se considera obsoleta y su uso no se recomienda ampliamente. */\nvar miVariableVar: number = 12;\nlet miVariableLet: number = 33;\n\n/* - Constantes: Para declarar constantes en TypeScript, utilizamos la palabra clave 'const'. Similar a las variables,\n                 las constantes deben tiparse al momento de la declaración. Se fomenta la inmutabilidad en el\n                 código TypeScript mediante el uso de constantes. */\nconst miConstante: string = 'Alberto';\n\n// DATOS PRIMITIVOS\n//En TypeScript, los tipos de datos primitivos son los siguientes:\nconst miString: string = \"Esto es un string\"; // string: Sirve para almacenar cadenas de texto.\nconst miNumberEntero: number = 40; // number: Sirve para almacenar datos de tipo numérico, ya sean enteros o decimales.\nconst miNumberDecimal: number = 23.4;\nconst miBigInt: bigint = 123456789012345678901234567890n; /* bigint: Es otro tipo de dato numérico que permite\n                                                                     representar enteros más grandes que el tipo\n                                                                     'number'. Se define agregando la letra \"n\" al\n                                                                     final del número seguido de \"n\". */\nconst miBoolean: boolean = true; // boolean: Representa un valor lógico, verdadero o falso.\nlet miUndefined: undefined; // undefined: Indica que una variable ha sido declarada pero no tiene un valor asignado.\nconst miSymbol: symbol = Symbol('mi Symbol'); // symbol: Tipo de dato cuyas instancias son únicas e inmutables.\n// También existe el null que aunque puede tomarse como primitivo, en realidad es propio de cada Object.\n\n// IMPRESIÓN POR CONSOLA\nconsole.log('¡Hola, TypeScript!');"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/CarlosAVargas7.ts",
    "content": "// https://www.typescriptlang.org/ \n\n/* Varias\nlineas */\n\n//Una linea\n\n// Otra linea\n\nvar unaVariable\nconst unaConstante: string = \"Typescript\";\n\n//Common Primitive Types\nvar varString: string\nvar varNumber: number\nvar varBoolean: boolean\n\n//Less Common Primitive Types\nvar varBigint: bigint\nvar varSymbol: symbol\n\n//Special Types\nvar varNull: null\nvar varUndefined: undefined\n\nconsole.log (\"Hola,\",unaConstante)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/Cibacoa.ts",
    "content": "\n\n/**\n * Esto es un comentario multilinea\n * que además nos permite recoger a posteriori la documentación necesaria\n * automáticamente sólo teniendo en cuenta estos comentarios\n */\n\n\n// Primera variable\n\nvar variable: string = 'Hola mundo'\nconst constante: number = 3;\n\n// Tipos primitivos\n\nvar numero: number = 3;\nvar texto: string = 'Hola mundo'\nvar myBoolean: boolean = true;\n\nconsole.log('¡Hola, Typescript!');\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/Danilo0203.ts",
    "content": "// Comentario de una sola linea\n\n/* Este es un comentarios de\n   multiples lineas */\n\n// Pagina oficial de TypeScript\n// https://www.typescriptlang.org/\n\n// Variable\nlet saludar: string = 'Hola'\n\n// Constante\nconst lenguaje: string = 'TypeScript'\n\n// 📌 Datos Primitivos\n// String\nlet texto: string = 'Texto'\nconsole.log(typeof texto)\n\n// Numbers\nlet numeros: number = 123\nconsole.log(typeof numeros)\n\n// Booleans\nlet verdadero: boolean = true\nlet falso: boolean = false \nconsole.log(typeof verdadero, typeof falso);\n\n// Symbol\nlet simbolo: symbol = Symbol('Soy un tipo de dato Simbolo')\nconsole.log(typeof simbolo);\n\n// Bigint\nlet big: bigint = 9007199254740991n;\nconsole.log(typeof big);\n\n// Null\nlet vacio: null = null\nconsole.log(typeof vacio);\n\n// undefined\nlet sinDeclarar: undefined\nconsole.log(typeof sinDeclarar);\n\n/* Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\" */\nconsole.log(saludar + ' ' + lenguaje)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/DeaconSt.ts",
    "content": "//////////////////////////////////////Punto #1///////////////////////////////////////\n//Documentación oficial de TypeScript: https://www.typescriptlang.org/es/docs/\n//////////////////////////////////////Punto #2///////////////////////////////////////\n//Comentario monolineal: Como por ejemplo este\n/* Comentario \nmultilineal: \nComo por ejemplo este\n*/\n//////////////////////////////////////Punto #3///////////////////////////////////////\nlet nombre: string = \"Juan Felipe \";\nconst diasAñoNormal: number = 365;\n//////////////////////////////////////Punto #4///////////////////////////////////////\nlet pais: string = \"Colombia y/o algo más\";\nlet peso: number = 80;\nlet premisa: boolean = true; //o false\nlet nullType: null = null;\nlet undefindeType: undefined = undefined;\nlet symbol: symbol = Symbol('S')\n//////////////////////////////////////Punto #5///////////////////////////////////////\nlet message: string = \"TypeScript\";\nconsole.log(\"¡Hola \"+message+\"!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/FeliAguirre7.ts",
    "content": "// https://www.typescriptlang.org/\n\n// Comentario de una linea\n\n/*Comentario de varias\nlineas*/\n\n// Declaración de variable y constante\nlet texto: string = \"texto\";\nconst año: number = 1999;\n\n// Declaración de variables con tipos primitivos\nlet dia: number = 3; //Ejemplo de enteros\nlet esActivo: boolean = true; // Ejemplo de booleano\nlet saludo: string = \"Hola\";  // Ejemplo de string\nlet arreglo: number[] = [1, 2, 3, 4, 5]; // Ejemplo de arreglo de números\n\n//Imprimir en consola\nconsole.log(\"Hola, Typescript!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/Guillemduno.ts",
    "content": "\n\n// https://www.typescriptlang.org/\n\n// One line comment\n\n/*\n    Multiple line comment\n    Multiple line comment\n */\n\nconst username = \"Guillemduno\";\nlet age: number;\nlet isDeveloper: boolean;\nlet hobbies: string[];\nlet qttyFriends: number;\nconst myLang = \"Typescript\";\n\nconsole.log(`¡Hola, ${myLang}!`);\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/Igledev.ts",
    "content": "// 1º URL de TypeScript https://www.typescriptlang.org/\n\n// 2º Tipos de Comentarios:\n    // - Comentarios de una línea: \n        // Comentario\n    // - Comentarios de varias línea: \n        /* Comentario de \n         * varias líneas \n         * de código \n        */\n    // - Comentarios para la documentación: \n        /* Son comentarios que nos permiten documentar\n        * nuestro código y la generación de documentación\n        * automática conocidda como TSDoc que facilita la comprensión\n        * y mantenimiento del código.\n        * Pueden ir acompañados de etiquetas como @param o @return\n        * que identifican valores \n        */\n\n// 3º Variables - En Typescript las variables se pueden declarar con un let o un var\nlet variable1 : number = 18;\nvar variable2 : number = 19;\n// Constantes\nconst constante1 : string = 'Adrián';\n\n// 4º Lenguajes Primivitivos\nconst nombre : string = 'Igledev';\nconst edad : number = 19;\nconst peso : number = 67.8 // Tambien se utiliza para número decimales\nconst webdev : boolean = true;\nconst loquesea : any = 'Any' // Any es un tipo de dato que acepta cualquier valor pero no se recomienda su uso\n//Arrays, pueden ser de 3 tipos y definirlas de maneras distintas\nconst lenguajes : Array<string> = ['TypeScript' , 'PHP' , 'JavaScript'];\nconst notas : Array<number> = [9.8, 5, 7.5];\nconst todo : Array<any> = ['TypeScript' , 'PHP' , 'JavaScript', 9.8 , 5 , 7.5];\n// Tambien se pueden definir de esta manera:\nconst anhos : number[] = [2021, 2022, 2023, 2024]\nconst dinero : number | string = 20000; // Esto se llama Tupla y se utiliza para que una variable tengo múltiples tipos de datos\nconst sin_definir : undefined = undefined;\nconst vacio : null = null;\nconst numero_grande : bigint = 999999999999999999999999999999n; //permite representar enteros más grandes que el tipo number\nconst simbolo : symbol = Symbol('trifuerza'); // Es un tipo de dato cuyas instancias son únicas e inmutables\nconst objet : object = {};\nconst enum Tallas {Small, Medium, Large, ExtraLarge} //El tipo enum son listas de constantes que podemos referenciar en un futuro\n\n// 5º Impresión por consola\nconsole.log('¡Hola, TypeScript!')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/JLCareglio.ts",
    "content": "// https://www.typescriptlang.org/es\n\n// Este es un ejemplo de comentario de una linea.\n\n/*\n Este es un ejemplo\n de comentario de\n multiples lineas\n*/\n\n// Declaración de variable y constante\nlet variable: string;\nconst LANG = \"TypeScript\"; // LANG es string por inferencia de tipo\n\n// Hay 7 tipos de datos primitivos: string, number, bigint, boolean, undefined, symbol y null.\nlet my_string: string;\nlet my_number: number;\nlet my_bigint: bigint;\nlet my_boolean: boolean;\nlet my_undefined: undefined;\nlet my_symbol: symbol = Symbol(\"clave\");\nlet my_null: null;\n\nconsole.log(`¡Hola, ${LANG}!`);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/Jaimerocel96.ts",
    "content": "// - Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n\n// https://www.typescriptlang.org/\n\n// comentario en una línea\n\n/*\n    comentario en varias líneas\n*/\n\n\n// - Crea una variable (y una constante si el lenguaje lo soporta).\nlet titulo: string = \"Ejercicio 0\";\nconst lenguaje: string = \"Typescript\";\n\n// - Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\nlet numberVar: number = 13;\nlet booleanVar: boolean = true;\nlet stringVar: string = \"Texto\";\nlet listVar: number[] = [10,20,30];\nlet undefinedVar: undefined = undefined;\nlet nullVar: null = null;\n\n// - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nconsole.log(`¡Hola ${lenguaje}!`);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/JanCalos.ts",
    "content": "//https://www.typescriptlang.org/\n\n//coemntario de una linea.\n\n/*comentario\nde\nvarias\nlineas.*/\n\n//Una variables y una constante.\nlet nombre = \"Jancarlos\";\nconst edad = 20;\n\n//variables con todos tipos de datos.\nlet numero:number; // esto es un numero.\nlet texto: string; // esto es una cadena de texto.\nlet booleanos: boolean; // esto es un booleano(  true || false).\nlet array: Array<string>; // esto es un array [].\nlet nulo: null; // esto es un valor nulo.\nlet indefinido: undefined; // esto es indefinido.\nlet cualquier_cosa:any; // cualquier cosa, ignora el tipo de dato o no lo toma en cuenta(no recomendable utilizar).\nlet simbolo:symbol ; // esto es un simbolo.\nlet objeto:object; // esto es un objeto.\n\n//Nombre del lenguaje.\n\nlet lenguaje = 'Typescript';\nconsole.log(`Hola ${lenguaje}`);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/KevinED11.ts",
    "content": "// https://www.typescriptlang.org/\n\n// single line comment\n\n/*\nmulti line comment\n*/\n\nlet lenguaje: string = \"typescript\";\nconst PI: number = 3.1416;\n\n// primitive types\nlet name2: string = \"Kevin\";\nlet age: number = 25;\nlet isMarried: boolean = false;\nlet pi: number = 3.1416;\n\n// console.log\nconsole.log(lenguaje);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/LUCC4SZ.ts",
    "content": "// https://www.typescriptlang.org\n\n// Esto es un comentario en una sola linea\n/*\nEsto es un\ncomentario en\nvarias lineas\n*/\n\nlet myString= \"Mi cadena\"\nlet myNumber= 7\nlet myBoolean= true\n\nconst miSaludo= \"Hola, TypeScript!\"\n\nconsole.log(miSaludo)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/ManuGonzalito.ts",
    "content": "// https://www.typescriptlang.org/\n\n//Comentario en una linea\n/* Comentarios \n en varias\n líneas */\n \n //Variable\n let nombre: string = \"Manuel\"\n //Constante\n const lenguaje: string = \"Typescript\"\n \n //Tipos de Datos\n  //Number\n  let numero: number = 15\n  //string\n  let apellido: string = 'Gonzalez'\n  //Boolean\n  let is_studying: boolean = true\n  //Array\n  let array: number[] = [1, 2, 3]\n  //Objeto\n  let automovil: {marca: string, modelo: number} = {marca: \"Toyota\", modelo: 2022}\n \n//Imprimir mensaje por terminal\nconsole.log(`Hola ${lenguaje}!`)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/MiguelAngelEc.ts",
    "content": "// https://www.typescriptlang.org\n/*https://www.typescriptlang.org*/\n\nvar variable: string = \"String\"\nconst constante: number = 1988\n\nlet string: string = \"TypeScript\"\nlet number:number = 1988\nlet boolean:boolean = false\nlet nullVar:null = null\nlet undefinedVar:undefined = undefined\nlet symbol:symbol = Symbol(\"id\")\nlet bigint:bigint = 1234567890123456789012345678901234567890n\n\nconst tsVar:string = \"TypeScript\"\n\nconsole.log(`Hi, ${tsVar}`)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/NavarroEmiliano.ts",
    "content": "// https://www.typescriptlang.org/\n\n// Single line comment\n/* \nMulti-line\ncomment\n*/\n\n// Way to declare variables and constants\nlet variable: string = 'I am a variable';\nconst constante: string = 'I am a constant';\n\n// Primitive data types\nlet typeNumber: number = 10;\nlet typeString: string = 'Hello';\nlet typeBoolean: boolean = true;\nlet typeNull: null = null;\nlet typeUndefined: undefined = undefined;\nlet typeSymbol: symbol = Symbol('symbol');\nlet typeBigInt: bigint = 10n;\n\n// Printing in the console\nconsole.log('Hello, TypeScript!');\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/OskarCali.ts",
    "content": "// **********     ENLACES DE REFERENCIA     **********\n// Sitio web oficial    ==>   https://www.typescriptlang.org/\n\n// **********     FORMAS DE COMENTAR     **********\n// Comentario en una sola linea\n/* Comentario en\n * multiples lineas\n */\n\n// **********     DECLARAR VARIABLES Y CONSTANTES     **********\n// var  ==>   Declara una variable; puede tener cambios de valor pero NO del tipo\nvar globalScoped = \"Valor\";\nglobalScoped = \"Otro valor\";\n// let  ==>   Declara una variable en el scope (local); puede tener cambios de valor pero NO del tipo\nlet localScoped: number;\nlocalScoped = 8;\n// const ==>  Constante en el scope; no puede cambiar de valor\nconst readOnlyScoped = \"OskarCali\";\n\n// **********     TIPOS DE DATO (PRIMITIVOS)     **********\nlet _boolean: boolean = true;\nlet _number: number = 792.186;\nlet _bigInt: bigint = 1684324n;\nlet _string: string = \"OskarCali\";\nlet _symbol: symbol = Symbol(\"Something\");\n\n// **********     IMPRESION EN TERMINAL     **********\nconsole.log(\"¡Hola, typescript!\");\n\n// **********     REFERENCIAS ADICIONALES     **********\n// https://www.typescriptlang.org/docs/handbook/variable-declarations.html\n// https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#the-primitives-string-number-and-boolean\n// https://www.typescriptlang.org/play?target=7&ts=5.3.3\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/RicJDev.ts",
    "content": "/*\nhttps://www.typescriptlang.org/\n*/\n\n//Comentario en una línea\n\n/*\nComentario\nen\nmúltiples\nlíneas\n*/\n\n//Declarando variables\nconst myConstVarable: number = 23;\nlet myLetVariable: number = 12;\nmyLetVariable = 10;\nvar myVarVariable: string = 'Hola';\nmyVarVariable = 'Mundo';\n\nlet a: number = 10,\n\tb: number = 20,\n\tc: number = 30;\n\n//Numbers\nlet integer: number = 12;\nlet float: number = 32.12;\n\n//Booleans\nlet bool1: boolean = true;\nlet bool2: boolean = false;\n\n//Otros\nlet other1: undefined = undefined;\nlet other2: null = null;\n\nconsole.log('Hola, TypeScript');\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/RobertoAmaroHub.ts",
    "content": "/* 1- Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.*/\n//https://www.typescriptlang.org/\n\n/* 2- Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).*/\n//Inicio del TSDoc, TSDoc is a proposal to standardize the doc comments used in TypeScript code e.g.:\nexport class Statistics {\n    /**\n     * Returns the average of two numbers.\n     *\n     * @remarks\n     * This method is part of the {@link core-library#Statistics | Statistics subsystem}.\n     *\n     * @param x - The first input number\n     * @param y - The second input number\n     * @returns The arithmetic mean of `x` and `y`\n     *|\n     * @beta\n     */\n    public static getAverage(x: number, y: number): number {\n      return (x + y) / 2.0;\n    }\n  }\n//Final del TSDoc\n\n/*\nMultilinea con este tipo de comentarios podemos agregar muchos saltos de linea\n\nSin preocuparnos de seguir especificando que la linea actual es un comentario\n*/\n\n/* 3- Crea una variable (y una constante si el lenguaje lo soporta).*/\nvar isDone: boolean = true;\nconst num:number = 10;\n\n/* 4- Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...). */\n//Numbers\nlet decimal: number = 6;\nlet hex: number = 0xf00d;\nlet binary: number = 0b1010;\nlet octal: number = 0o744;\nlet big: bigint = 900719925474n;\n\n//Strings\nlet color: string = \"blue\";\ncolor = 'red';\nlet lenguaje: string = \"Typescript\"\n\n//Boolean\nlet isTrue: boolean = true;\n\n/* 5- Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!*/\nconsole.log(`¡Hola, ${lenguaje}!`)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/Rulo77.ts",
    "content": "//sitio oficial https://www.typescriptlang.org/docs/\n\n//comentario en una linea\n\n/*\n    Esto es un comentario\n    en varias lineas\n    de codigo\n*/\n\n//maneras de declarar una variable\nvar variable = 4;\nlet variable2 = 1.2;\n//manera de declarar una constante\nconst constante = 'Hola';\n\n// primitives types\nconst cadena:string = \"mi cadena\";\nconst numero:number = 124;\nconst booleano:boolean = true;\n\n//Less Common Primitives\n// Creating a bigint via the BigInt function\nconst numeroGrande:bigint = BigInt(100);\n// Creating a BigInt via the literal syntax\nconst anotherHundred:bigint = 100n;\nconst nombre:symbol = Symbol(\"name\");\n\n//primitive values\nconst nulo:null = null;\nconst indefinido:undefined = undefined;\n\n//others variables types\nconst array:Array<string> = ['hola','adios'];\nconst array2:number[] = [1,2,2,4];\nconst cualquierCosa:any = '';\nconst objeto: {x:number, y:number} = {x:10, y:5}\n\nconsole.log('Hola typescript');\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/Sac-Corts.ts",
    "content": "// https://www.typescriptlang.org/ \n// Single-line comment\n\n/*\n * Multi-line comment\n * Explaining the purpose of the code\n * or any other revelant information\n */\n\n// Declaring a variable\nlet language: string = \"TypeScript\";\n\n// Declaring a constant\nconst version: string = \"5.5.4\";\n\n// Declaring variables representing different primitive data types\nlet text: string = \"This is a string\"; // String\nlet number: number = 43; // Number (integer or decimal)\nlet boolean: boolean = true; // Boolean\n\n// Undefined and null are also considered types in TypeScript\nlet undefinedVar: undefined = undefined; //Undefined\nlet nullVar: null = null; // Null\n\nconsole.log(`Hello, ${language}!`);"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/SeigiGim.ts",
    "content": "// Typescript official website: https://www.typescriptlang.org/\n\n// One line comment\n\n/* Multiple lines\ncomment */\n\n// Variable creation\nlet variable: string;\n\n// Constant creation\nconst constante: string[] = [];\n\n// Primitive types\nlet myString: string;\nlet myNumber: number;\nlet myBoolean: boolean;\nlet myUndefined: undefined;\nlet myNull: null;\n\n// Hello\nconsole.log(\"¡Hola, TypeScript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/Sharah07.ts",
    "content": "//typescriptlang.org\n\n// Comentario de una sola línea\n\n/**\n * Comentario \n * de\n * varias\n * líneas\n*/\n\n\n//Variables y cosntantes\n\nlet miVariable = \"variable\";\n\nconst MI_CONSTANTE = \"constante\";\n\n\n//Tipos de datos primitivos en TS\n\nlet numero:Number = 12;\nlet cadena:String = \"Hola Mundo\";\nlet miBoleano:Boolean = true;\nlet nulo:null = null;\nlet indefinido:undefined = undefined;\n\n\nconsole.log(cadena + \"!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/Waldid32.ts",
    "content": "//Doc TypeScript: https://www.typescriptlang.org/\n\n/*\n Vamos por aprender TS para implementar con Next JS\n*/\n\n// Variables y constantes\nlet texto: String = 'Waldid';\nconst ts: String = 'TypeScript';\n\n// Datos primitivos\nlet textoString: string = 'Gaby';\nlet numero: number = 1;\nlet booleano: boolean = true;\nlet indefinido: undefined;\nlet nulo: null = null;\nlet bigNumero: bigint = 362564143n;\nlet simbolo: symbol = Symbol(\"Simbolo de TS\");\n\nconsole.log(`¡Hola, ${ts}!`);"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/XhuaSpy.ts",
    "content": "//https://www.typescriptlang.org/\n\nconsole.log(\"Hola typeScript\");\n\n// variables y constantes\nconst constante : string = \"constante\";\nlet variableLet : string;\nvar variableVar : string;\n\n// Tipos de datos permitos den \nlet variableNumerica : number;\nlet variableString : string;\nlet variableBoolean : boolean;\nlet variableArray : Array<string>;\n\n// Arreglos de strings\nconst arr1: string[] = ['foo', 'bar'];\nconst arr2: Array<string> = ['foo', 'bar'];\n// Arreglos de números\nconst arr3: number[] = [1, 2, 3, 4, 5];\nconst arr4: Array<number> = [1, 2, 3, 4, 5];\n// Arreglos de strings o números\nconst arr5: (string|number)[] = ['foo', 1, 'bar', 2];\nconst arr6: Array<string|number> = ['foo', 1, 'bar', 2];\n\n// tipo object generico\nconst fruticas : object  = {\n    nombre: \"nombre\",\n    apellido : \"apellido\"\n}\n\n// objeto con propiedades\nconst fruticasConCiudad : { nombre: string, ciudad: string } = {\n    nombre: \"manzana\",\n    ciudad: \"cali\"\n}\n\n// Los ennumeradores son un tipo de dato donde todos los valores\n// que contiene son constantes.\nenum ProductosLimpieza {\n    FABULOSO,\n    JABON_LOSA,\n    JAVON_BAÑO,\n}\n\n// any es el tipo mas flexible, es como trabajar cono js directamente\nlet variableAny : any;\nvariableAny = 23\nvariableAny = \"Hola como estas\";\nvariableAny = {\n    nombre: \"hola como estas?\",\n    numero: 23,\n}\n\n// Alias\ntype StringOrNumber = string | number;\nconst var20: StringOrNumber = '1';\nconst var21: StringOrNumber = 1;\n\ntype Geo = { country: string; city: string; };\nconst var22: Geo = {\n    country: 'Spain',\n    city: 'Málaga',\n}\n\n// never, void, unknown, funciones y callbacks;\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/angelsanchezt.ts",
    "content": "// TypeScript - URL oficial: https://www.typescriptlang.org/\n\n// Comentario en una línea\n\n// OPCIONAL: Ejecución del Script.\n// Prerrequisitos:\n//      1. Instalación de Node y NPM\n// Instalación de Typescript de forma global:\n//      npm install -g typescript\n// Transpilar el codigo de Typescript a Javascript\n//      tsc angelsanchezt.ts\n// Ejecutar el codigo de Javascipt generado\n//      node angelsachezt.js\n\n/*\n   Comentario\n   en\n   varias\n   líneas\n*/\n\n// Variable y constante\nlet miVariable : string = \"Hola\";\nconst miConstante: number = 42;\n\n// Tipos de datos primitivos\nlet variableNumero: number = 5;\nlet variableCadena: string = \"TypeScript\";\nlet variableLogico: boolean = true;\nlet arreglo: number[] = [1, 2, 3];\nlet objeto: { nombre: string, edad: number } = { nombre: \"Juan\", edad: 25 };\n\n// Imprimir por terminal\nconsole.log(`¡Hola, ${variableCadena}!`);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/arnodchirivi08.ts",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n//Url oficial https://www.typescriptlang.org/\n/*\n    Varias\n    lineas\n    comentarios\n*/\n\n//Variables y constantes\nlet firstName;\nvar lastName;\nconst nameLanguage= 'Typescript';\n\n// Tipos de datos primitivos\nlet isEnabled: boolean = true;\nlet numberOne: number = 1;\nlet nameText: string = 'Carolina';\nlet valueNull: null = null;\nlet valueUndefined: undefined= undefined\nconst id = Symbol('id');\nconst numberBig: BigInt = 1234567890123456789012345678901234567890n;\n\n// Tipos de datos adicionales\nlet nombres: string[] = [\"Ana\", \"Juan\", \"María\"];\nlet persona: [string, number, boolean] = [\"Carlos\", 35, true];\nenum Color {\n    Rojo, \n    Verde, \n    Azul\n}\n\nconsole.log(\"¡Hola, Typescript!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/axelsparta.ts",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n// Typescript: https://www.typescriptlang.org/\n/* Typescript añade tipos estáticos y funciones avanzadas a javascript */\n// Comentario de una línea\n/* Comentario\n\tde\n\tmúltiples\n\tlíneas\n*/\n\n// A la hora de definir variables y asignarles un valor no es necesario indicar el tipo ya que typescript lo infiere automáticamente\n\n// Tipos de datos más primitivos son los más simples y son la forma más primitiva de representar estos datos\n\nlet years = 23\nconst NAME = 'Axel'\n\nlet myString = 'My string variable'\nlet myNumber = 42\nlet myBoolean = true\nlet myUndefinedVariable\nlet myNullVariable = null\nlet mySymbol = Symbol('my description') // es un valor único e inmutable(no se puede modificar), se pueden utilizar para añadir claves únicas a objetos\nlet myBigInt = 2n // datos numéricos muy grandes que no pueden ser representados con Number\n\nconsole.log(typeof myString)\nconsole.log(typeof myNumber)\nconsole.log(typeof myBoolean)\nconsole.log(typeof myUndefinedVariable)\nconsole.log(typeof myNullVariable) // 'object', esto es por un bug histórico (no se soluciona porque puede romper internet)\nconsole.log(typeof mySymbol)\nconsole.log(typeof myBigInt)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/azfe.ts",
    "content": "// 1.- Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n\n// https://www.typescriptlang.org/\n\n/*\n* TypeScript es un lenguaje de programación de código abierto desarrollado por Microsoft. Es un superconjunto de JavaScript, lo que significa que cualquier código JavaScript válido también es válido en TypeScript. TypeScript agrega características adicionales a JavaScript, como tipado estático, clases, interfaces y módulos, lo que facilita el desarrollo de aplicaciones grandes y complejas.\n\n* Algunas de las características clave de TypeScript incluyen:\n* 1. Tipado estático: TypeScript permite a los desarrolladores definir tipos para variables, funciones y objetos, lo que ayuda a detectar errores en tiempo de compilación y mejora la legibilidad del código.\n* 2. Clases y objetos: TypeScript soporta la programación orientada a objetos, lo que permite a los desarrolladores crear clases, interfaces y herencia, facilitando la organización y reutilización del código.\n* 3. Módulos: TypeScript permite a los desarrolladores organizar su código en módulos, lo que facilita la gestión de dependencias y la reutilización de código.\n* 4. Compatibilidad con JavaScript: TypeScript es compatible con JavaScript, lo que significa que los desarrolladores pueden usar bibliotecas y frameworks de JavaScript existentes sin problemas.\n* 5. Herramientas de desarrollo: TypeScript cuenta con un sistema de compilación que convierte el código TypeScript en JavaScript, lo que permite a los desarrolladores aprovechar las herramientas de desarrollo y depuración disponibles para JavaScript.\n\n* En resumen, TypeScript es un lenguaje de programación que mejora la experiencia de desarrollo en JavaScript al agregar características de tipado estático y programación orientada a objetos, lo que facilita la creación de aplicaciones grandes y complejas.\n*/\n\n// 2.- Crea una variable (y una constante si el lenguaje lo soporta).\n\nlet variable: string = \"Hola Mundo\";\n\nconst PI: number = 3.1416;\n\n// 3.- Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n\nlet texto: string = \"Esto es una cadena de texto\";\nlet num: number = 42;\nlet isTrue: boolean = true;\nlet valorNulo: null = null;\nlet valorUndefined: undefined = undefined;\nlet simbolo: symbol = Symbol(\"símbolo\");\nlet any: any = \"Esto puede ser cualquier tipo de dato\";\nlet avoid: void = undefined;\nlet never: never;\n\n// 4.- Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nconsole.log(\"¡Hola, TypeScript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/barbarasg92.ts",
    "content": "/*/ Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado. /*/\n\n/*/ https://www.typescriptlang.org/ /*/\n\n /*/ - Representa las diferentes sintaxis que existen de crear comentarios\n    en el lenguaje (en una línea, varias...). /*/\n\n // Esto es un comentario en 1 línea\n /*/ Esto es un comentario en múltiples líneas /*/\n\n\n // - Crea una variable (y una constante si el lenguaje lo soporta).\n\n let ciudad: string = \"Madrid\";\n const nombre: string = \"Barbara\";\n\n // Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n\n let pueblo: string = \"Sant Cugat\";\n let numero: number = 25;\n let esBoolean: boolean = true;\n let valorNulo: null = null;\n let valorUndefined: undefined = undefined;\n let idUnico = Symbol(\"id\");\n\n\n// Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\" /*/\n\nconsole.log(\"¡Hola, TypeScript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/coletonosh.ts",
    "content": "// Typescript https://www.typescriptlang.org/docs/\r\n\r\n//Esto es un comentario simple\r\n\r\n/** Esto es otro comentario\r\n * en multiples\r\n * lineas\r\n */\r\n\r\n const programLanguage: string = \"Typescript\";\r\n\r\n let simpleString: string = \"\";\r\n let simpleNumber: number = 0;\r\n let simpleBoolean: boolean = true;\r\n let simpleNull: null = null;\r\n let simpleUndefined: undefined = undefined;\r\n \r\n console.log(`¡Hola, ${programLanguage}!`);\r\n "
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/cubandeveloper89.ts",
    "content": "// URL de Typescript: https://www.typescriptlang.org/\n\n// Este es un comentario de una sola linea\n\n/*\nEste es el comentario de diferentes lineas\nEste año tengo que convertirme en un verdadero programador\nTengo que dejar los videojuegos\n*/\n\n// Variables:\n\nlet my_variable1: string = \"variable numero uno\"\n\nconst my_constant1: string = \"constante numero uno\"\n\n// Datos primitivos:\n\nlet miString: string = \"Esto es un string\"; // Asi se almacenan las cadenas de texto.\n\nlet miNumberEntero: number = 40; // Asi se almacenan los datos de tipo numérico, ya sean enteros o decimales.\n\nlet miNumberDecimal: number = 23.4;\n\nlet miBoolean: boolean = true; // boolean: Representa un valor lógico, verdadero o falso.\n\n// LA IMPRESION\n\nconsole.log(\"Hola TypeScript! Vamos por más\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/dannyvera1234.ts",
    "content": "/* *********************************************************************************************** */\n//1.-\n//La página oficial de ts es: https://www.typescriptlang.org/docs/\n\n//2.-\n//Comentario con doble diagonal: este unicamente funciona en una sola linea.\n/* Comentario con asteriscos y diagonal: sirve para escribir el comentario en varias lineas. */\n\n// String\n  const lenguaje = \"typescript\"\n// number\n var edad = 27;\n// nul\n const dato = null;\n// undefined\n let datos = undefined\n// Boolean\n var verdad = true;\n const falso = false;\n\nconsole.log(\"hola \"+ lenguaje );"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/dararod.ts",
    "content": "// WEB OFICIAL\n//https://www.typescriptlang.org/\n\n//COMENTARIOS\n//That is a Single line comment\n/* \nAnd that is a Multi line comment\n*/\n\n//VARIABLES\nlet myVariable: string = \"That's a variable\";\nconst myConst: string = \"That's a const\";\n\n//TIPOS DE DATOS\nconst string: string = \"I'm a string\";\nconst boolean: boolean = true;\nconst number: number = 10;\nconst bigInt: bigint = 999n\nconst myUndefined: undefined = undefined\nconst symbol: symbol = Symbol('My symbol')\n\n//IMPRESION EN CONSOLA\nconsole.log(\"¡Hola, typescript!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/darubiano.ts",
    "content": "/*\n    EJERCICIO:\n    1) Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n    2) Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n    3) Crea una variable (y una constante si el lenguaje lo soporta).\n    4) Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n    5) Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n */\n\n// 1) https://www.typescriptlang.org/docs/\n\n// 2) Comentario de una linea y varias\n\n/*\n    Comentario de varias lineas\n */\n// 3) Variable y constante\nlet variable: string = \"texto\";\nconst pi: number = 3.1416;\n// 4) Tipos de variables primitivas https://www.typescriptlang.org/docs/handbook/2/everyday-types.html\n\n// Tipos de dato undefined, null o cualquier cosa\nlet nulo = null;\nlet indefinido: undefined = undefined;\nlet cualquier_cosa: any = \"Cualquier cosa\";\n\n// Tipos de dato numericos, number,BigInt\nlet numero: number = 123;\nlet decimal: number = 3.1416;\nlet color: number = 0xFF0000;\nlet numeroGrande: bigint = 9007199254740991n;\n\n// Tipos de dato texto\nlet cadena: string = \"Texto\";\n\n// Tipos de dato boleano\nlet boleanoVerdadero: boolean = true;\nlet boleanoFalso: boolean = false;\n\n// Tipos de dato Symbol, se usa crear identificadores unicos\nlet variableSymbol: symbol = Symbol(\"descripcion\");\n\n// Tipos de dato lista y objetos\nlet lista: Array<number> = [1, 2, 3];\nlet objecto: object = { 1: \"primero\", 2: \"segundo\" };\n\n// 5) print JavaScript\nconsole.log(\"¡Hola, TypeScript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/david-git-dev.ts",
    "content": " // url del sitio web oficial: https://www.typescriptlang.org/\n //SINTAXIS DE COMENTARIOS\n //comentarios de una linea\n /*comentarios\n de varias lineas*/\n //variables\n let codeVar;\n const constante ='';\n //datos primitivos\n let num:number = 1;\n let float = 1.1;\n let cadena:string ='';\n let arreglo:[];\n let obj:{};\n let booleano:boolean ;\n //mensaje\n console.log('Hola! Javascript')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/duendeintemporal.ts",
    "content": "// #00 { retosparaprogramadores } SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n// TypeScript - Official URL: https://www.typescriptlang.org/\n\n/* by @duendeintemporal */\n\n// One-line comments \n/* Comments\n                of\n                     many lines */\n\n/* I set my environment in the following way:\n1. First, run:\n   npm init -y\n2. Then, install TypeScript and ts-node globally:\n   npm install -g typescript ts-node\n3. Now I can run my TypeScript files directly using:\n   ts-node ./src/my_file.ts\n*/\n\n\nlet lang: string; // Variable to hold the programming language\nlet num: number; /* \n   The 'let' keyword declares a variable with block scope. \n   Unlike 'var' in JavaScript, 'let' does not attach to the window object in the global context.\n*/\n\nconst MIN_VA: number = 0; /* \n   'const' declares a constant with block scope and must be initialized with a value. \n   By convention, constants are usually named using capital letters.\n*/\n\n// Primitive Types or Primitive Values\n\nlet hello: string = 'Hi Girl!'; // string type\nconsole.log(hello); // Hi Girl!\nconsole.log(`String type: ${hello}`, typeof hello); // String type: Hi Girl! string\n\nlet x_coord: number = 100; // number type\nconsole.log(x_coord); // 100\nconsole.log('Number type: ', typeof x_coord); // Number type:  number\n\nlet bool: boolean = true; // boolean type\nconsole.log(bool); // true\nconsole.log('Boolean type: ', typeof bool); // Boolean type:  boolean\n\nlet stack: number[] = [0, 1, 2, 3, 4, 5, 6]; // array type\nconsole.log(stack); // [ 0, 1, 2, 3, 4, 5, 6 ]\nconsole.log('Array type: ', typeof stack); // Array type:  object\n\nlet obj: { name: string; age: number; profession: string; greetings: () => void } = {\n    name: 'Niko',\n    age: 41,\n    profession: 'Writer & Web Developer',\n    // method\n    greetings: function () {\n        console.log(`Hello, I am ${this.name} and it's a pleasure to start and share this roadmap with you !!`);\n    }\n}; // object type\n\nconsole.log(obj);\n/* \nObject type:  {\n    name: 'Niko',\n    age: 41,\n    profession: 'Writer & Web Developer',\n    greetings: [Function: greetings]\n  } */\n    console.log('Object type: ', typeof obj);  // Object type:  object\n    obj.greetings(); // Hello, I am Niko and it's a pleasure to start and share this roadmap with you !!\n\nlet tuple: [string, number, boolean, { webmaster: string }] = ['Soe', 35, true, { webmaster: 'Niko' }];\nconsole.log(tuple); // [ 'Soe', 35, true, { webmaster: 'Niko' } ]\nconsole.log('Tuple type: ', typeof tuple); // Tuple type:  object\n\nenum Color {\n    Red,\n    Green,\n    Blue,\n    Black,\n    Purple\n}\nconsole.log('Enum type: ', typeof Color); // Enum type:  object\nlet fontColor: Color = Color.Green;\nconsole.log('Enum type: ', typeof fontColor); // Enum type:  number\n\n\nlet obj2: null = null; \n/* \n   Represents the absence of a value, helping to handle situations where a value is not available \n   or has not been intentionally defined.\n*/\nconsole.log('Null type: ', typeof obj2); // Null type:  object\n\nlet obj3: undefined; // undefined type \n/* \n   'undefined' indicates that a variable has been declared but not initialized.\n*/\nconsole.log('Undefined type: ', typeof obj3); // Undefined type:  undefined\n\nlet anything: any = \"I can be anything!\";\nconsole.log('Any type: ', typeof anything); // Any type:  string\nanything = 42; // Now it's a number type\nconsole.log('Any type after reassignment: ', typeof anything); // Any type after reassignment:  number\n\n\nlet syn: symbol = Symbol('syn'); // symbol type\nconsole.log('Symbol type: ', typeof syn); // Symbol type:  symbol\n/* \n   Symbols can be used to prevent object collisions, such as creating hidden non-enumerable properties \n   on objects or private methods in a class.\n*/\n\nlet amount: bigint = BigInt(3783787487877877887) * BigInt(2); // bigint type\nconsole.log(amount) // 7567574975755755520n\nconsole.log(`BigInt type: ${amount}`, typeof amount); // BigInt type: 7567574975755755520 bigint\n/* \n   Using BigInt is especially useful in situations where accuracy is required in calculations \n   with large integers, such as in financial or crypto applications.\n*/\n\n/* \n   'typeof' is an operator that we can use to determine a type or make type comparisons.\n*/\nconsole.log('Is amount of bigint type:', (typeof amount === \"bigint\")); // Is amount of bigint type: true\n\n// Short for console.log()\nlet log = console.log.bind(console); \n\n// Function with type annotations\nfunction add(a: number, b: number): number {\n    return a + b;\n}\nlog('Function result: ', add(25, 18)); // Function result: 43\n\n// Interfaces in Typescript are use to define a type with properties.\ninterface Person {\n    name: string;\n    age: number;\n}\n\nlet person: Person = {\n    name: 'Bob',\n    age: 34\n};\nlog('Interface type: ', typeof person); // object\n\n// Ejemple of Type Assertion\nlet someValue: any = \"this is a example string\";\nlet strLength: number = (someValue as string).length;\nlog('String length: ', strLength); // String length: 24\n\n// Arrow function with type annotations and Promises\nconst fetchData = (): Promise<string> => {\n    return new Promise((resolve) => {\n        setTimeout(() => {\n            resolve(\"Data fetched!\");\n        }, 2000);\n    });\n};\n\nfetchData().then(data => log(data)); // Data fetched! (after 2 seconds)\n\n// Assigning a new value to a previously declared variable\nlang = 'Typescript';\n\n// Print in console\nlog(`Hello, ${lang}`); // Hello, Typescript\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/eulogioep.ts",
    "content": "// URL del sitio web oficial de TypeScript\n// https://www.typescriptlang.org/\n\n// Diferentes formas de crear comentarios en TypeScript:\n\n// 1. Comentario de una línea\n\n/*\n   2. Comentario \n   de varias \n   líneas\n*/\n\n/**\n * 3. Comentario de documentación\n * Usado frecuentemente para describir funciones, clases e interfaces\n */\n\n// Creación de una variable con tipo inferido\nlet miVariable = \"Soy una variable\";\n\n// Creación de una constante con tipo explícito\nconst MI_CONSTANTE: string = \"Soy una constante\";\n\n// Variables representando tipos de datos en TypeScript\n\n// String (cadena de texto)\nlet cadena: string = \"Hola, mundo\";\n\n// Number (número)\nlet entero: number = 42;\nlet decimal: number = 3.14;\n\n// Boolean (booleano)\nlet verdadero: boolean = true;\nlet falso: boolean = false;\n\n// Undefined (indefinido)\nlet indefinido: undefined = undefined;\n\n// Null (nulo)\nlet nulo: null = null;\n\n// Symbol (símbolo)\nlet simbolo: symbol = Symbol(\"descripción\");\n\n// BigInt (entero grande)\nlet enteroGrande: bigint = BigInt(9007199254740991);\n\n// Any (cualquier tipo)\nlet cualquiera: any = \"Puedo ser cualquier cosa\";\n\n// Unknown (desconocido)\nlet desconocido: unknown = 4;\n\n// Void (vacío, típicamente para funciones sin retorno)\nfunction sinRetorno(): void {\n    console.log(\"Esta función no retorna nada\");\n}\n\n// Never (nunca, para funciones que nunca retornan)\nfunction error(mensaje: string): never {\n    throw new Error(mensaje);\n}\n\n// Tuple (tupla)\nlet tupla: [string, number] = [\"hola\", 42];\n\n// Enum (enumeración)\nenum Color {\n    Rojo,\n    Verde,\n    Azul\n}\n\n// Imprimir por terminal\nconsole.log(\"¡Hola, TypeScript!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/fhdzleon.ts",
    "content": "/* * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n/* \nVisita el sitio oficial de typescript: \nhttps://www.typescriptlang.org/\n*/\n\n// Comentario de una sola linea\n\n/*  \nComentario\nmultilineas\n*/\n\nlet edad: number = 45;\nconst nombre: string = \"skulldev\";\n\nlet string: string = \"Esta es una cadena de texto\";\nlet number: number = 0;\nlet bool: boolean = true;\nlet myArray: string[] = [\"soy\", \"un\", \"array\"];\nlet myObject: object = {};\n\nlet sayHello: () => void = () => console.log(\"hola typescript\");\n\nsayHello();\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/fravelz.ts",
    "content": "// https://www.typescriptlang.org/\n\n// Comentario de una sola linea\n\n/*\nComentario de\nvarias lineas\n*/ \n\nlet varName: string = \"Valor de la variable\";\nconst CONSTANTE: string = \"Valor de la constante\";\n\nlet numberType: number = 7_799; //7799 con guion bajo para mejor lectura\nlet bigInt: bigint = 9007199254740991n; // Numero grande\n\nlet booleanType: boolean = false;\nlet stringType: string = \"string\";\n\nlet nullType: null = null; // null por defecto\nlet undefinedType: undefined = undefined; // undefined solo al colocarlo explicitamente\n\nconst symbolType: symbol = Symbol('id'); // Tipo de dato simbolo\n\nlet numberArray: number[] = [1, 2, 3];\nlet stringArray: string[] = [\"a\", \"b\", \"c\"];\n\nconsole.log (\"Hola, TypeScript\");\n\nexport {}; // Evita el error de \"Cannot redeclare block-scoped variable\" al ejecutar el código en un entorno global\n\n// > Autor: Fravelz\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/giovanyosorio.ts",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n// https://www.typescriptlang.org/\n\n// Comentario de una línea\n/*\n * Comentario\n * de\n * varias\n * líneas\n */\n\n// Variable\nlet variable = \"variable\";\n\n// Constante\nconst constante = \"constante\";\n\n// Tipos de datos primitivos\nlet cadena: string = \"cadena\";\nlet numero: number = 1;\nlet booleano: boolean = true;\nlet nulo: null = null;\nlet indefinido: undefined = undefined;\nlet simbolo: symbol = Symbol(\"simbolo\");\n\n// Imprimir por terminal\nconsole.log(`¡Hola, TypeScript!`);\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/gitperalta.ts",
    "content": "/*\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n */\n\n// - https://www.typescriptlang.org/\n\n// - Comentario de una linea\n\n/**\n * - Comentario en varias lineas\n */\n\n// -\nlet a = \"variable\";\nconst b = \"constante\";\n\n// -\nlet boolean = true;\nlet number = 1;\nlet string = \"string\";\nlet bigint = 9999999999999999n;\nlet symbol = Symbol(\"symbol\");\nlet nullType = null;\nlet undefinedType = undefined;\n\n// -\nconsole.log(\"¡Hola, TypeScript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/gizelads.ts",
    "content": "// https://www.typescriptlang.org/\n\n// Inline comment\n/*\n  Block\n  comment\n*/\n\n// Variable creation\nlet myVariable: string = \"Hello, TypeScript\";\n// Constant creation\nconst myConstant: number = 42;\n\n// Primitive Data Types\nlet str: string = \"Hello\";\nlet num: number = 123;\nconst bigNumber: bigint = 100n;\nlet isTrue: boolean = true;\nlet a: null = null;\nlet b: undefined = undefined;\nconst uniqueID: symbol = Symbol(\"id\");\n\n// Imprimir por terminal\nconsole.log(`¡${myVariable}😀!`);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/hozlucas28.ts",
    "content": "// https://www.typescriptlang.org/\n\n// Single line comment.\n\n/*\n    Multi line comment...\n*/\n\nlet number01: number = 1\nconst number02: number = 2\n\nnumber01 = 3\n// number02 = 4 // Throw an error because It's a constant.\n\n// Primitive data types\nconst numberVar: number = 12345\nconst bigIntVar: bigint = BigInt(1000)\n\nconst booleanVar: boolean = true\n\nconst stringVar: string = '¡Hello World!'\n\nconst symbolVar: symbol = Symbol('fibonacci')\n\nconst nullVar: null = null\nconst undefinedVar: undefined = undefined\n\n// Outputs\nconsole.log(`number01: ${number01}\\nnumber02: ${number02}\\n`)\n\nconsole.log(`> numberVar: ${numberVar} --> ${typeof numberVar}`)\nconsole.log(`> bigIntVar: ${bigIntVar} --> ${typeof bigIntVar}\\n`)\n\nconsole.log(`> booleanVar: ${booleanVar} --> ${typeof booleanVar}\\n`)\n\nconsole.log(`> stringVar: ${stringVar} --> ${typeof stringVar}\\n`)\n\nconsole.log(`> symbolVar: ${String(symbolVar)} --> ${typeof symbolVar}\\n`)\n\nconsole.log(`> nullVar: ${nullVar} --> ${typeof nullVar}\\n`)\nconsole.log(`> nullVar: ${undefinedVar} --> ${typeof undefinedVar}\\n`)\n\nconsole.log('¡Hello, TypeScript!')\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/ialmontedr0.ts",
    "content": "/**https://www.typescriptlang.org/*/\r\n\r\n// Comentario de una linea\r\n/**\r\n * Comentario de varias lineas,\r\n *continua aqui\r\n */\r\n\r\n let variable = \"Esta es una variable\"; // Declaracion de una variable\r\n const constante = \"Esta es una constante\"; // Declaracion de una constante\r\n\r\n // Tipos de datos\r\n let numero: number = 10; // Numero entero\r\n let cadena: string = \"Esta es una cadena\"; // Cadena de caracteres\r\n let arreglo: number[] = [1, 2, 3, 4, 5]; // Arreglo de numeros\r\n let objeto: object = { nombre: \"Anthony\", edad: 26 }; // Objeto\r\n let booleano: boolean = true; // Booleano\r\n let fecha: Date = new Date(); // Fecha\r\n\r\n console.log(\"¡Hola, Typescript!\"); // Imprimir en consola/terminal"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/is2095.ts",
    "content": "// Página oficial de TypeScript: https://www.typescriptlang.org\n\n// tipos de comentarios:\n\n// comentario: una línea.\n/* comentario: múltiples línea\n    línea 1\n    línea 2\n    línea 3\n    línea 4\n    línea 5\n    línea 6\n*/\n\n// variables:\n\nvar variable: string = 'es una variable tipo string'; // el uso de var no es aconsejable y no se aconseja\nconst constante: string = 'este tipo de variable es una constante'; // en este tipo el valor es constante, no puede ser modificado.\nlet variableLet: string = 'es una variable let tipo string'; // este tipo de variable si admite se modificado su valor\n\n// tipos primitivos de las variables:\n\nlet variableNumero: number = 10; // variable tipo número, es de punto flotante o entero, de 64bits\nlet variableString: string = 'esto es un string'; // variable tipo string, representa una o una secuencia de caracteres.\nlet variableBoolean: boolean = true; // variable de valor booleano: puede tomar los valores de verdadero o falso.\nlet variableNull: null = null; // variable con valor nulo\nlet variableundefined: undefined = undefined; // Variable\n\n// impresión por consola del texto \"¡Hola, [nombre del lenguaje]\"\n\nconsole.log(\"¡Hola, TypeScript!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/isaias-alt.ts",
    "content": "// https://www.typescriptlang.org/\n\n// Comentario de una sola linea\n\n/**\n * Comentario de\n * multiples lineas\n */\n\nlet variableDec: string = \"Variable\";\nconst LANGUAGENAME: string = \"TypeScript\";\n\nlet stringDataType: string = \"string\";\nlet numberDataType: number = 17;\nlet decimalNumberDataType: number = 3.14;\nlet booleanDataType: boolean = false;\nlet nullDataType: null = null;\nlet undefinedDataType: undefined = undefined;\n\nconsole.log(`Hola ${LANGUAGENAME}`);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/javi8d.ts",
    "content": "//https://www.typescriptlang.org\n//Comentario en una linea\n/*/\nComentario\nen\nmuchas lineas\n/*/\n\nlet variable_string: string = \"string\"\nconst constant_string: string = \"string\"\nlet variable_number: number = 8\nlet variable_boolean: boolean = true\nlet variable_array: number[] = [1,2,3]\nlet variable_object: object = {name:\"Justine\", age:19}\nlet variable_date: Date = new Date();\n\nconsole.log(\"Hola, Typescript!\")"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/javodevon.ts",
    "content": "//https://www.typescriptlang.org/\n\n//Comentario en una linea: Para comentarios cortos y concisos, como explicar una línea de código en particular.\n\n/**\n * Comentario multilinea: \n * Se utilizan para comentarios más largos, \n * como explicar una sección de código o documentar una función.\n */\n\n//Variables Tipadas\nvar variable1: string = 'Variable de tipo Texto';\nlet variable2: string = 'Variable de tipo Texto';\n\n/**\n * ¿Diferencia entre var y let?\n * Principalmente el scope\n * var: Tiene un alcance funcional o global.\n * let: Tiene un alcance de bloque.\n * \n * Más información en https://www.typescriptlang.org/docs/handbook/variable-declarations.html\n */\n\n//Constante tipada\nconst constante: boolean = false;\n\n// Datos Primitivos (Disponibles en JS)\nlet edad: number = 30;\nlet saludo: string = \"Hola, mundo!\";\nlet valorBooleano: boolean = false;\nlet valorNulo: null = null;\nlet valorIndefinido: undefined = undefined;\nlet simbolo: symbol = Symbol(\"miSimbolo\");\nlet numeroGrande: bigint = 1234567890123456789n;\n\nconsole.log('¡Hola, Typescript!')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/jmcavilla.ts",
    "content": "// Sitio web oficial: https://www.typescriptlang.org/docs/\n\n// TypeScript es un lenguaje de programación de código abierto desarrollado y mantenido por Microsoft. Es un superconjunto de JavaScript, y añade tipado estático y objetos basados en clases. TypeScript es usado para desarrollar aplicaciones JavaScript que se ejecutarán en el lado del cliente o del servidor.\n\n/** Comentario con varias lineas\n * \n * \n * \n */\n\n\nlet variable = \"Hola Mundo\";\nconst constante = \"Hola Mundo\";\n\nlet numero: number = 5;\nlet cadena: string = \"Hola Mundo\";\nlet booleano: boolean = true;\nlet nullVariable: null = null;\nlet undefinedVariable: undefined = undefined;\n\nconsole.log(\"!Hola, TypeScript!\");"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/joseptarres.ts",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n// EJERCICIOS\n\n// - Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n// El lenguaje escogido es Typescript  y la URL del sitio web oficial es https://www.typescriptlang.org/\n\n// - Representa las diferentes sintaxis que existen de crear comentarios\n// Podemos crear 2 tipos de comentarios: \n// 1. Comentario de una linea: \n// Comentario de una linea\n// 2. Comentarios de varias lineas:\n/* Esto es un comentario\nde varias lineas */\n\n// - Crea una variable (y una constante si el lenguaje lo soporta).\nlet isNumber: number = 2;\nvar isString: string = 'Hola';\nconst isBoolean: boolean = true;\n\n// - Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\nlet isNumDec: number = 4\nlet isNumHex: number = 0xf00d;\nlet isNumBinary: number = 0b1010;\nlet isNumOctal: number = 0o744\nlet isStr: string = 'Hola'\nlet isBool1: boolean = true\nlet isBool2: boolean = false\nlet isUnd: undefined = undefined\nlet isNull: null = null\nlet isSymbol: symbol = Symbol('a')\n\n// - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nconsole.log('¡Hola, Typescript!')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/juanRCoder.ts",
    "content": "// Pagina web oficial de TypeScript: https://www.typescriptlang.org\r\n\r\n// Comentario de una linea\r\n\r\n/**\r\n * Comentario\r\n * multilineal\r\n */\r\n\r\nlet nombre: string = 'typeScript';\r\nconst LUCK: number = 7;\r\nlet bigNumber: bigint = 325094922n;\r\n\r\nlet bool: boolean = true;\r\nlet bool2: boolean = false;\r\n\r\nlet nulo: null = null;\r\nlet indefinido: undefined = undefined;\r\n\r\nlet random: any = 'hola' || true || 12;\r\nlet fruits: string[] = ['banana', 'orange', 'apple'];\r\nlet obj: {[key: string]: number} = {'edad': 23};\r\n\r\nconsole.log(`¡Hola, ${nombre}!`)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/jurgen-alfaro.ts",
    "content": "// https://www.typescriptlang.org/\n\n// COMENTARIOS\n// Comentario de una sola línea\n/* \n    Comentario de \n    varias líneas \n*/\n\n// VARIABLES Y CONSTANTES\nlet myVar = \"Valor variable\";\nconst PI = 3.14;\n\n// DATA TYPES\nlet isDone: boolean = false;\nlet decimal: number = 6;\nlet bigInt: bigint = 1234567890n;\nlet hex: number = 0xf00d;\nlet binario: number = 0b1010;\nlet octal: number = 0o744;\nlet nombre: string = \"Trollistar\";\nlet numeros: number[] = [1, 2, 3, 4];\nlet nombres: string[] = [\"Jorge\", \"Ana\", \"Guido\"];\nlet tupla: [string, number] = [\"hola\", 10];\n\nlet notSure: any = 4;\nlet u: undefined = undefined;\nlet n: null = null;\n\n// IMPRIMIR EN CONSOLA\nconsole.log(\"¡Hola, TypeScript!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/juserdev.ts",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n ! - Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n ! - Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n ! - Crea una variable (y una constante si el lenguaje lo soporta).\n ! - Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n ! - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n\n// https://www.typescriptlang.org\n\n/*\n Este es otra manera de crear comencatarios en bloques\n*/\n\n\nlet myLet: number = 12\nconst myConst: string = \"TypeScript\"\n\nlet myString: string = \"hola\"\nlet myNumber: number = 12\nlet myBoolean: boolean = false\nlet myNull: null = null\nlet myUndefinder: undefined = undefined\n\nconsole.log(`${myString} ${myConst}`)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/kodenook.ts",
    "content": "// https://www.typescriptlang.org\n\n// Comments\n\n//single-line comment\n\n/*\n    this is a\n    multi-line comment\n*/\n\n// Variables and Constants\n\nlet variable = 'variable'\nconst constant = 'constant'\n\n// Data Types\n\nlet string: string = 'string'\nlet number: number = 1\nlet boolean: boolean = true // true or false\nlet array: any[] = ['saturday', 'sunday']\n\n// Print\n\nconsole.log('¡Hola, typescript')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/kraltar.ts",
    "content": "// https://www.typescriptlang.org/\n\n// single line comment\n\n/* \n    multi line comment\n*/\n\n/**\n * JSDoc\n * \n * \n * \n */\n\n\nlet myName = 'kraltar'\n\nconst myAlterName = 'Mauricio'\n\n//types\n\nlet myOnlineName: string = 'kraltar' \nlet edad: number = 123\nlet bolivian: boolean = true\nlet friendNames: string[] = ['Leonardo', 'Arturo', 'MoureDev']\nlet numeros: number[] = [1,2,3,4,5,]\nlet nul: null = null\nlet undefnd: undefined = undefined\nlet nunca: never\nlet edadAmigo: [number, string] = [30, 'Leonardo']\nlet vacio: void \n\n\nconsole.log('Hola, typescript');\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/llonardo798.ts",
    "content": "// 1. URL del sitio web oficial de TypeScript: https://www.typescriptlang.org/\n\n// 2. Tipos de comentarios en TypeScript:\n\n// Comentario de una línea\n\n/*\n  Comentario de varias líneas\n*/\n\n/**\n * Comentario de documentación (JSDoc)\n * @param {string} nameDoc - Nombre de la persona\n * @returns {string} Saludo\n * @example greet('Luis') // => '¡Hola, Leonardo!'\n */\n\n// 3. Creación de variables y constantes:\n\nconst EDAD: number = 25;\nlet variables: string = \"Leonardo\";\n\n// 4. Tipos de datos primitivos:\n\nlet nombre: string = 'Leonardo Aedo'; // Cadena de texto (string),  con comillas simples, dobles o backticks (``)\nlet edad: number = 25; // Número entero (number)\nlet todoOk: boolean = true; // Booleano (boolean) con valores true o false\nlet nulo: null = null; // Valor nulo (null)\nlet indefinido: undefined = undefined; // Valor indefinido (undefined)\nlet simbolo: symbol = Symbol('Simbolo'); // Valor único (symbol) e inmutable\nlet numeroGrande: bigint = 9007199254740991n; // Número entero grande (bigint)\nlet cualquierCosa: any = 'Hola'; // Cualquier tipo de dato (any)\ncualquierCosa = 25; // Se puede cambiar el tipo de dato\n\n// 5. Imprimir en consola;\n\nconsole.log(`¡Hola, TypeScript!`);\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/manuhssj.ts",
    "content": "/*\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n */\n// URL del sitio web oficial: https://www.typescriptlang.org/\n\n// Comentario de una línea\n\n/**\n * Comentario en varias líneas\n */\n\n// Declaración de variables\nconst myName:string = \"Manuel\";\nconst username:string = \"Manuhssj\";\nlet age:number = 25; \nlet isDeveloper:boolean = true;\nlet hobbies:string[] = [\"Fútbol\", \"Pintura\", \"Música\"];\nconst learningLanguage:string = \"TypeScript\";\n\n\nconsole.log(`¡Hola, ${learningLanguage}! Mi nombre es ${myName}, tengo ${age} años de edad y estoy aprendiendo ${learningLanguage}!`);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/marcode24.ts",
    "content": "// ¡Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n// - Recuerda que todas las instrucciones de participación están en el\n//   repositorio de GitHub.\n//\n// Lo primero... ¿Ya has elegido un lenguaje?\n// - No todos son iguales, pero sus fundamentos suelen ser comunes.\n// - Este primer reto te servirá para familiarizarte con la forma de participar\n//   enviando tus propias soluciones.\n//\n// EJERCICIO:\n// - Sitio web oficial de JavaScript: https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// - Representa las diferentes sintaxis que existen de crear comentarios\n//   en el lenguaje (en una línea, varias...).\n\n/*\n   Comentario de múltiples líneas\n*/\n\n// - Crea una variable (y una constante si el lenguaje lo soporta).\nlet miVariable2: string = 'Hola, mundo';\n// eslint-disable-next-line no-unused-vars\nconst miConstante2: number = 42;\n\n// - Crea variables representando todos los tipos de datos primitivos\n//   del lenguaje (cadenas de texto, enteros, booleanos...).\nlet cadenaTexto2: string = 'Hola';\nlet numeroEntero2: number = 42;\nlet numeroDecimal2: number = 3.14;\nlet booleano2: boolean = true;\nlet bigInt2: bigint = 9007199254740991n;\nlet nulo2: null = null;\nlet indefinido2: undefined = undefined;\nlet simbolo2: symbol = Symbol('Hola');\nlet objeto2: { nombre: string; edad: number } = {\n  nombre: 'Pepe',\n  edad: 42,\n};\nlet array2: number[] = [1, 2, 3];\n\n// - Imprime por terminal el texto: \"¡Hola, JavaScript!\"\nconsole.log('¡Hola, JavaScript!');\n\n// Visita mi repo en GitHub para ver y correr los tests de este código --> https://github.com/marcode24/weekly-challenges\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/marcosApodaca.ts",
    "content": "// **********     ENLACES OFFICIAL     **********\n// https://www.typescriptlang.org/\n\n/*La siguente manera de comentar en \nvarias linea es esta */\n\n// **********     DECLARAR VARIABLES Y CONSTANTES     **********\nlet variable:string = 'Mi variable';\nconst LENGUAGE:string = 'Typescript';\n\n\n// **********    DATO PRIMITIVOS     **********\nconst numerosEnteros:number = 5;\nconst string:string = 'Cadena de texto';\nconst booleanTrue:boolean = true\nconst booleanFalse:boolean = false\n\n// **********     IMPRESION EN CONSOLA     **********\nconsole.log(`Hola ${LENGUAGE}!`);"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/markc1234.ts",
    "content": "// EJERCICIO:\n// Crea un comentario en el código y coloca la URL del sitio web oficial del lenguaje de programación que has seleccionado.\n// https://www.typescriptlang.org\n\n\n// Representa las diferentes sintaxis que existen de crear comentarios en el lenguaje (en una línea, varias...).\n// Comentario de una linea\n/*\n    Comentario de\n    varias \n    lineas\n*/\n\n\n(() => {\n    // Crea una variable (y una constante si el lenguaje lo soporta).\n    let cadena:string = \"Cadena de texto\"\n    const numero = 10\n\n    // Crea variables representando todos los tipos de datos primitivos del lenguaje (cadenas de texto, enteros, booleanos...).\n    const name = \"Typescript\"\n    const age = 20\n    const isStudent = true\n    const nullVal = null\n    const undefinedVal = undefined\n\n    // Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n    console.log(`¡Hola, ${name}`)\n})()"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/martinbohorquez.ts",
    "content": "// https://www.typescriptlang.org/\n\n// Esto es un comentario en una sola línea.\n\n/*\n * Esto es un comentario\n * usando varías líneas\n * para describir el código.\n */\n\n// Variable\nlet saludo: string = '¡Hola, '\n\n// Constante\nconst PROGRAMMING_LANGUAGE: string = 'TypeScript!'\n\n// Datos Primitivos\n// String\nlet palabra: string = 'Palabra'\nprintMessage(\"palabra\", palabra);\nlet texto: string = 'Este string es un texto'\nprintMessage(\"texto\", texto);\n\n// Numbers\nlet numero: number = 123\nprintMessage(\"numero\", numero);\nlet decimal: number = 3.1415926535\nprintMessage(\"decimal\", decimal);\nlet negativo: number = -123\nprintMessage(\"negativo\", negativo);\nlet enteroGrande: bigint = 1234567890123456789012345678901234567890n\nprintMessage(\"enteroGrande\", enteroGrande);\n\n// Booleans\nlet verdadero: boolean = true\nprintMessage(\"verdadero\", verdadero);\nlet falso: boolean = false\nprintMessage(\"falso\", falso);\n\n// Symbol\nlet simbolo: symbol = Symbol('mi-simbolo') \nprintMessage(\"simbolo\", simbolo);\n\n// Undefined\nlet indefinido: undefined = undefined\nprintMessage(\"indefinido\", indefinido);\n\n// Null\nlet nulo: null = null\nprintMessage(\"texto\", texto);\n\n// Imprimir por terminal\nconsole.log(saludo + PROGRAMMING_LANGUAGE)\n\nfunction printMessage(string: string, any: any) {\n    if (typeof (any) == \"symbol\") {\n        console.log(\"La descripción de '\" + string + \"' es: \" + any.description + \", y su tipo es: \"\n            + typeof (any))\n    } else {\n        console.log(\"El valor de '\" + string + \"' es: \" + any + \", y su tipo es: \"\n            + typeof (any))\n    }\n}"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/mauricioyair.ts",
    "content": "//Sitio Web Oficial: https://www.typescriptlang.org\n\n// Comentario de una sola linea\n\n/* \nComentario\nen multiples\nlineas \n*/\n\nvar typeScriptVariable: string = 'TypeScript Variable'\nconst TYPESCRIPTCONSTANT: string = 'TypeScript Constant'\n\nlet stringType: string = 'string'\nlet numberType: number = 10\nlet booleanType: boolean = true\nlet bigIntType: bigint = BigInt(100)\n\nconsole.log('¡Hola, TypeScript!')\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/mendozalz.ts",
    "content": "\n/* \nEJERCICIO:\n[X] Crea un comentario en el código y coloca la URL del sitio web oficial del\n    lenguaje de programación que has seleccionado.\n\n[X] Representa las diferentes sintaxis que existen de crear comentarios\n    en el lenguaje (en una línea, varias...).\n\n[X] Crea una variable (y una constante si el lenguaje lo soporta).\n\n[X] Crea variables representando todos los tipos de datos primitivos\n    del lenguaje (cadenas de texto, enteros, booleanos...).\n\n[ ] Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\" \n*/\n\n\n\n// Pagina web de TypeScript - https://www.typescriptlang.org/\n\n\n/* ------------------------------------------------------------ */\n\n// Comentarios en una Linea con TS\n\n// Esto es un comentario de una linea\n\n/* ------------------------------------------------------------ */\n\n// Comentarios en varia Linea con TS\n\n/* \nEsto es un comentario\nde varia Lineas  \n*/\n\n/* ------------------------------------------------------------ */\n\n// Variables y Constantes en TS\n\nvar unaVar = \"Esta es una varibles global\";\n\nlet unaLet = \"Esta es una varibles con scope\";\n\nconst unaConst = \"Esta es una constante\";\n\n\n/* ------------------------------------------------------------ */\n\n// Datos primitivos en TS y JS\n\n// String\n\nconst nombre: string = \"Lenin\";\n\n// Number\n\nconst edad:number = 44;\n\n// Boolean\n\nconst latino:boolean = true;\n\nconst europeo:boolean = false;\n\n// Undefined\n\nconst und:undefined = undefined\n\n// Null\n\nconst nll:null = null\n\n/* ------------------------------------------------------------ */\n\nconst ts = \"TypeScript\"\n\nconsole.log(`¡Hola, ${ts}!`);\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/miguelangelmz21.ts",
    "content": "// https://www.typescriptlang.org/docs\n\n// Comentario en una línea\n\n/*\nComentario en varias líneas \nEJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n */\n\n// Crea una variable (y una constante si el lenguaje lo soporta).\nlet myVariable: string = \"Mi variable\";\nmyVariable = \"He cambiado el valor de mi variable\";\nconst myConstant: string = \"Mi constante\";\n// myConstant = \"He cambiado el valor de mi constante\"; // Esto dará un error porque las constantes no se pueden reasignar\n\n// Crea variables representando todos los tipos de datos primitivos\nlet myString: string = \"Hola, TypeScript\"; // Cadena de texto\nlet myNumber: number = 42; // Número (puede ser entero o decimal)\nlet myBoolean: boolean = true; // Booleano\nlet myUndefined: undefined; // Indefinido\nlet myNull: null = null; // Nulo\nlet mySymbol: symbol = Symbol(\"miSimbolo\"); // Símbolo\nlet myBigInt: bigint = BigInt(9007199254740991n); // BigInt\n// Imprime por terminal el texto\nconsole.log(`¡Hola, TypeScript!`);"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/miguelex.ts",
    "content": "// Documentación en https://www.typescriptlang.org/docs/\n\n// Comentario en una linea\n\n/* Comentario\nen varias\nlineas */\n\n// Declaracion de variable \nlet lenguaje: string = 'typescript';\n\n// Declaracion de constante\nconst PI: number = 3.1515;\n\n// Tipo de datos primitivos\nlet cadena: string = 'cadena';\nlet numero: number = 10;\nlet booleano: boolean = true;\nlet nulo: null = null;\nlet indefinido: undefined = undefined;\n\n// Salida por consola\n\nconsole.log(\"Hola \" + lenguaje + \"!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/mikelroset.ts",
    "content": "// ------------------------- DOCUMENTACIÓN OFICIAL ------------------------- //\n\n// https://www.typescriptlang.org/\n\n\n// -------------------------- TIPOS DE COMENTARIOS -------------------------- //\n\n// Esto es un comentario de línea\nlet x = 10; // Comentario al final de la línea\n\n/*\n Esto es un comentario de bloque\n Puede abarcar varias líneas\n*/\nlet y = 20;\n\n/**\n * Suma dos números\n * @param {number} a - El primer número\n * @param {number} b - El segundo número\n * @returns {number} - La suma de a y b\n */\nfunction sum(a, b) {\n  return a + b;\n}\n\n\n// ------------------------- VARIABLES Y CONSTANTES ------------------------- //\n\n// Let\nlet age: number = 25;\nage = 30; // OK, ya que 'let' permite reasignación\n\n// Var\n/**\n * var también se usa para declarar variables, pero tiene un ámbito global o de\n * función (function scope), lo que puede llevar a comportamientos inesperados,\n * por lo que en TypeScript se prefiere el uso de let\n */\n\nvar username: string = \"Alice\";\n// OK, 'var' también permite reasignación, pero su uso es menos recomendable\nusername = \"Bob\"; \n\n// Const\nconst PI: number = 3.1416;\n// PI = 3.15; // Error: no se puede reasignar una constante\n\n// Plus: Inferir tipos\nlet city = \"Madrid\"; // TypeScript infiere que 'city' es de tipo 'string'\n// TypeScript infiere que 'numberOfPlanets' es de tipo 'number'\nconst numberOfPlanets = 8; \n\n\n// ---------------------------- DATOS PRIMITIVOS ---------------------------- //\n// Y datos no estrictamente primitivos pero valen la pena mencionarlos para TS)\n\n// number\nlet myAge: number = 25; \n\n// string\nlet myName: string = \"John\"; \n\n// boolean\nlet isActive: boolean = true; \n\n// null\nlet value: null = null; \n\n// undefined\nlet notAssigned: undefined = undefined; \n\n/*\n  Array\n  Ambas formas son equivalentes en términos de funcionalidad, varían en estilo:\n  \n  1. `number[]`: Es más concisa y comúnmente usada por simplicidad y legibilidad\n  2. `Array<number>`: Usa sintaxis genérica, útil para casos más complejos o \n     cuando se trabaja con programación genérica (ej. arrays multidimensionales)\n\n  Elección:\n  - Para arreglos simples, como `number[]`, se prefiere la notación simplificada\n  - En tipos de datos más complejos, `Array<T>`, puede ofrecer mayor claridad\n  \n  No hay una forma \"más correcta\", la elección depende de las convenciones de\n  estilo del proyecto y del equipo.\n*/\n\nlet numbers: Array<number> = [1, 2, 3];\nlet numbers2: number[] = [1, 2, 3];\n\nlet strings: Array<string> = [\"a\", \"b\", \"c\"];\nlet strings2: string[] = [\"a\", \"b\", \"c\"];\n\n// Object\nlet obj: object = { key: \"value\" };\n\n// Tupla\nlet tuple: [number, string] = [25, \"John\"];\n\n// Enum\nenum Color {\n  Red,\n  Green,\n  Blue\n}\nlet c: Color = Color.Green;\n\n// Union\nlet id: number | string;\nid = 10;  // OK\nid = \"ABC123\";  // OK\n\n// Literales\nlet direction: \"up\" | \"down\";\ndirection = \"up\"; // OK\n// direction = \"left\"; // Error\n\n// Any (Desactiva la verificación de tipos. Útil cuando no se conoce el tipo)\nlet randomAnyValue: any = \"Hello\";\nrandomAnyValue = 10;  // OK\n\n// Void (Se utiliza principalmente en funciones que no devuelven un valor)\nfunction logMessage(message: string): void {\n  console.log(message);\n}\n\n// Never (Representa el tipo de valores que nunca ocurren)\n// útil para funciones que nunca terminan o que siempre lanzan errores\nfunction throwError(message: string): never { \n  throw new Error(message);\n}\n\n// Interface\ninterface Person {\n  name: string;\n  age: number;\n}\nlet employee: Person = { name: \"Bob\", age: 25 };\n\n// Personalizados (Permiten crear alias para un tipo o una combinación de tipos)\ntype ID = number | string;\nlet userId: ID = 123;\n\n// Functions (Se pueden tipar tanto los parámetros como el valor de retorno)\nfunction add(a: number, b: number): number {\n  return a + b;\n}\n\n// Symbol\nlet sym1: symbol = Symbol();\nlet sym2: symbol = Symbol(\"description\");\n\n/* \n  Unknown \n   Es un tipo seguro que se usa cuando no sabemos de antemano cuál será el tipo\n   de una variable. A diferencia de any, no se pueden realizar operaciones\n   sobre un valor unknown sin verificar su tipo primero.\n*/\nlet randomUnknownValue: unknown = \"Hello\";\nif (typeof randomUnknownValue === \"string\") {\n  console.log(randomUnknownValue.toUpperCase()); // OK\n}\n\n/* \n  BigInt\n  Es un tipo de dato que representa números enteros muy grandes, mayores de lo\n  que puede manejar el tipo number.\n  Los valores de tipo bigint se crean añadiendo una n al final de un número\n  entero o usando el constructor BigInt().\n*/\n  let bigNumber: bigint = 9007199254740n; // Usando 'n'\n  let anotherBigNumber: bigint = BigInt(9007199254740); // Usando el constructor\n\n\n  // ------------------------- IMPRIMIR POR CONSOLA ------------------------- //\nlet language = 'TypeScript';\nconsole.log(`Hola ${language}`);"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/mxtrar23.ts",
    "content": "// Sitio Oficial: https://www.typescriptlang.org/\n\n// Este es un comentario de una sola linea \n\n/* \n  Este es un comentario\n  de múltiples línesas\n*/\n\nlet mivariable:string = 'Esta puede cambiar su valor';\n\nconst miConstante:string = 'Esta no permite cambiar su valor';\n\n\n//Tipo de Datos Primitivos\n\nconst lenguage :string = 'TypeScript';\n\nconst year:number = 2024; \n\nconst isJanuary :boolean = true;\nconsole.log(`¡ Hola, ${lenguage} !`);\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/nathanaellara.ts",
    "content": "// https://www.typescriptlang.org/\n\n/*\nThis a multi-line comments\n*/\n\n/*\nComentarios para deshabilitar comprobaciones de TypeScript\nPuedes usar // @ts-ignore o // @ts-nocheck para ignorar errores en líneas específicas.\n\nIgnorar un error en una línea específica:\n// @ts-ignore\nlet resultado: number = \"Hola\"; // No marca error aunque es incorrecto\n\nIgnorar comprobaciones en todo el archivo:\n// @ts-nocheck\nlet mensaje: number = \"Esto no marcará error\";\n\n*/\n\n// Comentarios de documentación (/** ... */)\n/* TypeScript admite comentarios de documentación estilo JSDoc, útiles para proporcionar información sobre funciones, clases o variables. Estos comentarios pueden ser procesados por herramientas como TypeDoc.\n*/\n\n/**\n * Suma dos números y devuelve el resultado.\n * @param a Primer número\n * @param b Segundo número\n * @returns La suma de ambos números\n */\n\n/*\n\nfunction sumar(a: number, b: number): number {\n    return a + b;\n  }\n\n*/\n\n\n/*\nlet edad: number = 23; // Variable de tipo numero\nedad = 26; // Se puede reasignar\nconsole.log(edad); // Salida: 26\n*/\n\n/*\nconst nombre: string = \"Santiago\" // Constante de tipo string\n// nombre = \"Carlos\"; // Esto daria un error porque no se puede reasignar\nconsole.log(nombre); // Salida: Santiago\n*/\n\nlet age: number = 23;\nlet nombre: string = 'Typescript';\nlet esEstudiante: boolean = true;\n\nconsole.log('Hola, ' + nombre)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/nlarrea.ts",
    "content": "/*\n * ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n * - Recuerda que todas las instrucciones de participación están en el\n *   repositorio de GitHub.\n *\n * Lo primero... ¿Ya has elegido un lenguaje?\n * - No todos son iguales, pero sus fundamentos suelen ser comunes.\n * - Este primer reto te servirá para familiarizarte con la forma de participar\n *   enviando tus propias soluciones.\n *\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n *\n * ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n * debemos comenzar por el principio.\n */\n\n// https://www.typescriptlang.org/\n\n// Single line comment\n\n/**\n * This is a\n * multiline comment\n */\n\n// Variables\nlet variable1: any\nvar variable2: any\n\n// Constants\nconst PI: number = 3.14\n\n// Variable types\nlet username: string = 'nlarrea'\nlet age: number = 25\nlet isError: boolean = false\nlet notDefined: undefined\nlet nullValue: null = null\n\n// Print to console\nconsole.log('¡Hola TypeScript!')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/pcosin.ts",
    "content": "//  https://www.typescriptlang.org/\n\n// Este es un comentario para una sola línea\n\n/* Este es un comentario\n para varias líneas */\n\n// Variables\n\nlet vinculo: string = \"Esto es una variable\";\nconst VINCULOCONSTANTE: string = \"Esto es una constante\";\n\n// Tipos primitivos;\n\nlet num: number = Infinity;\nlet lenguage: string = \"TypeScript\";\nlet boolean: boolean = true;\nlet undefinedVar: undefined = undefined;\nlet nullVar: null = null; \nlet bigNumber: bigint = 12345678901234567890n;\nlet symbolVar: symbol = Symbol(\"mi-simbolo\");\n\nconsole.log(`Hola ${lenguage}`);"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/qv1ko.ts",
    "content": "// #00 Sintaxis, variables, tipos de datos y hola mundo\n\n// www.typescriptlang.org\n\n/** Comment */\n// Comment\n\nvar var1: number = 1;\nconst VAR2: string = \"TypeScript\";\n\nvar var2: string = 'TypeScript';\nvar var3: number = 3.3;\nvar var4: boolean = true;\n\nconsole.log(\"¡Hola, \" + VAR2 + \"!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/qwik-zgheib.ts",
    "content": "// this comment is a single line comment\n\n/*\nthis is a multi-line comment\n*/\n\n/* read docummentation ts in: https://www.typescriptlang.org/ */\n\nvar text: string = \"Hello, Typescript!\";\nvar number: number = 10;\nvar boolean: boolean = true;\n\nconsole.log(text);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/rendonnm.ts",
    "content": "// * - Crea un comentario en el código y coloca la URL del sitio web oficial \n//  R.) https://www.typescriptlang.org/\n\n//  *   lenguaje de programación que has seleccionado.\n// R.) TypeScript\n\n//  * - Representa las diferentes sintaxis que existen de crear comentarios\n//  *   en el lenguaje (en una línea, varias...).\n// Primera forma - Una línea\n/* Segunda \nforma - varias\nlíneas */\n\n//  * - Crea una variable (y una constante si el lenguaje lo soporta).\nlet mainLanguage = 'TypeScript'\nconst CITY = 'Envigado'\n\n//  * - Crea variables representando todos los tipos de datos primitivos\n//  *   del lenguaje (cadenas de texto, enteros, booleanos...).\nconst thisIsBigInt = 439221312312312321n\nconst isTrue = true // Boolean\nconst thisIsNull = null // null\nconst num = 27 // Number\nconst predecesor = 'JavaScript' // String\nconst thisIsUndefined = undefined // undefined\nconst uniqueSymbol = Symbol('This is unique')\n\n//  * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\nconsole.log('Hola, TypeScript!')"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/rubenplazavi.ts",
    "content": "//https://www.typescriptlang.org/\n/*\nComentario de varias lineas\nlas que quieras\n*/\nconst num: number = 0;\nconst stringLenguaje: string = 'typescript';\nconst miBoolean: boolean = true;\nconst nullValue: null = null;\nconst undefinedValue: undefined = undefined;\n\nconsole.log(`¡Hola ${stringLenguaje}!`);"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/samuelarandia.ts",
    "content": "\n// https://www.typescriptlang.org/\n\n// Una línea de comentario \n\n/* Comentario \nde varias líneas */\n\n// Creación de variable\nlet variable: string = \"variable\";\nconst constante: string = \"constante\";\n\n// Tipos de datos\nlet numero: number = 15;\nlet cadena: string = 'cadena';\nlet booleano: boolean = true;\nlet array: number[] = [1, 2, 3];\nlet objeto: {marca: string, modelo: number} = {marca: \"Toyota\", modelo: 2022};\n\n\nconst myName: string = 'Samuel Arandia';\nconsole.log(\"¡Hola\" + myName + \"!\");\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/serg032.ts",
    "content": "// Typescript: https://www.typescriptlang.org/\n\n/*\nOther way to create comments with Typescript\n/\n\n/**\n * @author Sergio Radigales\n */\n\nlet firstVariable = \"First variable\";\nconst firstConstant = \"First Constant\";\nconst numberVariable: number = 1993;\nconst stringVariable: string = \"Software development\";\nconst booleanVariable: boolean = true;\nconst nullVariable: null = null;\nconst undefinedVariable: undefined = undefined;\nconst bigIntvariable: bigint = 10n;\nconst symbolVariable = Symbol(\"My symbol\");\nconst arrayVaraible: [] = [];\nconst array2Variable: Array<number> = [1, 2, 3, 4, 5];\nconst multitypeVariable: boolean | number = 4;\nenum Techs {\n  Typescript,\n  Node,\n}\n\nconst tech: Techs = Techs.Typescript;\nconst tupleVariable: [number, Techs] = [55, Techs.Node];\n\nconst helloTech = (tech: string): string => `Hola, ${tech}`;\nconsole.log(helloTech(\"Typescript\"));\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/sniker1223.ts",
    "content": "//https://www.typescriptlang.org/\n\n/** Document \n * Comment */\n\n//Single Line Comment\n\n/* Multiple\nLine \nComment */\n\n//constant type\nconst var1 = 'variable';\n\n//primitive Data types\nlet firstName: string = 'Sara'; // string\nlet var2: number = 3; // number\nlet var3: boolean = true; // boolean and undefined\nvar var4: bigint = 12n; // bigint\nvar var5: symbol = Symbol('My Symbol'); // symbol\n\n//print in console\nconsole.log('¡Hola, Typescript!');"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/tolomero.ts",
    "content": "//https://www.typescriptlang.org/\n\n\n// Declaración de variables con tipos de datos\n\n/** comentar un documento \n * multilinea de comentarios en TypeScrpt\n * puedo seguir escribiendo\n */\n//comentar una sola linea\n\n/*\ncomentar varias lineas\nen TypeScript\t\n*/\n//number\n\nlet edad: number = 25;\n//declarar una constante\nconst edad3: number = 30;\n\n// Cadena de texto\nconst nombre: string = \"Juan\";\n\n// Booleano\nconst esEstudiante: boolean = true;\n// Arreglo de números\n\n// Tupla\nlet persona: [string, number] = [\"Juan\", 25];\n\n// Enumeración\nenum Color {\n    Rojo,\n    Verde,\n    Azul\n}\nlet colorFavorito: Color = Color.Verde;\n\n// Any (puede ser cualquier tipo de dato)\nlet variableIndefinida: any = \"Hola\";\nvariableIndefinida = 10;\n\n// Void (usualmente para funciones que no retornan valor)\nfunction saludar(): void {\n    console.log(\"Hola, mundo!\");\n}\n\n// Null y Undefined\nlet variableNula: null = null;\nlet variableIndefinida2: undefined = undefined;\n\n// Object\nlet personaObj: { nombre: string, edad: number } = { nombre: \"Juan\", edad: 25 };\n\nconsole.log('Hola TypeScript!');\n\n\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/victor-Casta.ts",
    "content": "//Sitio web: https://www.typescriptlang.org/\n\n//Comentarios de una linea\n/*\n  Comentarios de varias lineas\n*/\n\n//Variables y constantes\nlet a:String = 'Hello';\nconst LANGUAGE:String = 'TypeScript';\n\n//Datos primitivos\nlet c:string  = 'c';\nlet number:number = 1;\nlet isTrue:boolean = true;\nlet isFalse:boolean = false;\nlet Undefined:undefined;\nlet Null:null = null;\nlet bigNumber: bigint = 12345678901234567890n;\nlet simbolo: symbol = Symbol(\"mi-simbolo\");\n\nconsole.log(`¡${a}, ${LANGUAGE}!`)"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/victoriaparraf.ts",
    "content": "// Esto es un comentario de una línea \n\n/*\n    Este es un comentario de varias líneas\n    Aquí está la URL de la página oficial de Typescript:\n    https://www.typescriptlang.org\n*/\n\n// Variable let: con alcance de bloque\nlet nombre: string = 'Victoria';\n\n// Variable const: solo lectura, alcance de bloque\nconst pi: number = 3.1415;\n\n// Variable var: alcance de función o global\nvar apellido: string = 'Parra';\n\n//Tipos de datos primitivos: string,number,boolean,any,void,null, undefined\nlet color: string = 'Rosa';\nlet edad: number = 23;\nlet soltera: boolean = true;\nlet cosa: any = 'Soy frase';\ncosa = 225;\nlet nada: null = null;\nlet sinDefinir: undefined = undefined;\n\n//Imprimir un mensaje por consola \nconsole.log('¡Hola, Typescript!');\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/xmunder.ts",
    "content": "/*\n * EJERCICIO:\n * - Crea un comentario en el código y coloca la URL del sitio web oficial del\n *   lenguaje de programación que has seleccionado.\n * - Representa las diferentes sintaxis que existen de crear comentarios\n *   en el lenguaje (en una línea, varias...).\n * - Crea una variable (y una constante si el lenguaje lo soporta).\n * - Crea variables representando todos los tipos de datos primitivos\n *   del lenguaje (cadenas de texto, enteros, booleanos...).\n * - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n */\n\n//Pagina oficial de typescript: https://www.typescriptlang.org/\n\n// Esto es un comentario de una sola línea\n\n/*\n    Esto es un\n    Comentario de\n    varias líneas  \n*/\n\nlet lenguaje:string = \"typescript\";\nconst edad:number = 21;\n\n//Tipos de datos primitivos en typescript\n\n// String\nlet miCadena:string = \"Hola mundo\";\n// Number\nlet miNumero:number = 21;\n// Boolean\nlet miBooleano:boolean = true;\n// Null\nlet miNulo:null = null;\n// Undefined\nlet miIndefinido:undefined = undefined;\n// Symbol\nlet miSimbolo:symbol = Symbol(\"Simbolo\");\n// BigInt\nlet miBigint:bigint = 12345678901234567890n;\n\nconsole.log(`¡Hola, ${lenguaje}!`)\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/typescript/zarakilancelot.ts",
    "content": "// Realizado con https://www.typescriptlang.org/\n\n// Comentarios\n// Comentario de línea\n/*\nComentario de bloque\n*/\n\n// Variables\n// var, let, const\nvar variable_var = \"Una variable\";\nlet variable_let = \"Una variable\";\nconst CONSTANTE = \"Una constante\";\n\n// Tipos de datos\n// number, string, boolean, any, void, null, undefined, never, object\nconst numero: number = 1;\nconst cadena: string = \"TypeScript\";\nconst booleano: boolean = true;\nconst cualquier_cosa: any = \"Cualquier cosa\";\nconst nada: void = undefined;\nconst nulo: null = null;\nconst indefinido: undefined = undefined;\nconst objeto: object = {};\n\n// Arrays\nconst arreglo: number[] = [1, 2, 3];\nconst otro_arreglo: Array<number> = [1, 2, 3];\n\n// Tuplas\nconst tupla: [number, string] = [1, \"Hola\"];\n\n// Enumeración\nenum Color {\n  Rojo,\n  Verde,\n  Azul,\n}\n\nconst color: Color = Color.Rojo;\n\nconsole.log(`¡Hola, ${cadena}`);\ndocument.write(`¡Hola, ${cadena}`);\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/vb.net/juandevian.vb",
    "content": "﻿\n' ╔══════════════════════════════════════════╗\n' ║ Autor:  Juan Villegas Dev (Devian)       ║\n' ║ Ejercicio:  00 - SINTAXIS, VARIABLES,... ║\n' ║ GitHub: https://github.com/juandevian    ║\n' ║ Fecha enunciado: 26/12/2023              ║\n' ║ Fecha publicación solución: 26/09/2024   ║\n' ║ Dificultad: BAJA                         ║\n' ║ 2024 -  VB.NET  Visual Basic.NET         ║\n' ╚══════════════════════════════════════════╝\n\nModule ModProgram\n    ' 00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\n    ' Visual Basic.NET\n    ' Sitio web oficial: https://learn.microsoft.com/es-es/dotnet/visual-basic/\n\n    ' Los comentarios son notas cortas explicativas que se agregan al código\n    ' para aportar mayor información a las personas que lo lean.\n    ' Este es un comentario que comienza en el lado hizquierdo de la pantalla.\n\n    ' TODO es una etiqueta de comentario. podemos crear las eqiqueas que necesitamos.\n    ' desde el menú de Herramiesntas -> Configuración.\n\n    Dim mStrLenguaje As String = \"Visual Basic.NET\"   ' Este es un comentario en líena de código.\n    REM Esta es otra forma de escribir comentarios,\n    REM es menos usada y requiere más espacio en memoria.\n    REM Se recomienda usar ' para los comentarios.\n\n    ' No Exist una forma para comentarios multilínea\n    ' Al necesitar extender el comentario se requiere\n    ' agregar el simbolo ' al inicio de cada línea. \n\n    ''' Esta es la estructura para realizar comentaris XML\n    ''' Podemos agregar infomración importante a IntelliSense de esta forma\n    ''' <summary>\n    ''' Determina cualquier espesificación clave que exista\n    ''' </summary>\n    ''' <param name=\"regKey\"> Definimos el string de saludo</param>\n    ''' <return> Cuál es el valor de retorno y las condiciones para el mismo</return>\n    ''' <author></author>\n    Function RegKeyExists(ByVal regKey As String) As Boolean\n        Dim exists As Boolean = False\n        Try\n\n        Catch ex As Exception\n\n        End Try\n    End Function\n    ' Los comentarios XML se realizan antes de una declaración de procedimiento,\n    ' variable o función.\n\n    ' Así se declara una variables locales: Dim nombreVariable As TipoDato\n    Dim i, j, k As Integer\n    ' Las tres variables de la declaración son definidas como típo Integer.  \n\n    Dim l, m As Long, x, y As Single\n    ' En esta declaracíon, l y m son tipo Long, x y y son Single.\n\n    ' A las variables se les asigna el valor por medio del operador =,\n    ' Dim nameVar As TipoDato = Valor\n    Dim num1 As Integer = 3 ' Uso de tipado explícito.\n\n    ' También se puede usar la inferencia de tipado.\n    Dim num2 = 5\n    ' Si quiere usar la inferencia de tipo de variable local,\n    ' Option Infer debe establecerse en On.\n    '\n    ' La declaración de una variable depende de la \"vigencia\" que necesitemos de la misma.\n    ' Podemos usar el modificador de acceso Public, Shared, Private o Static, que nos permiten\n    ' ampliar o reducur suvigencia.\n\n    ' Declaración de constantes. Valore almacenado en memoria que son inmutables e invariables.\n    Const VERSION As Byte = 1\n\n    ' Declaración de variables\n\n    Dim variableBoolean As Boolean = True\n    Dim variableByte As Byte = 255\n    Dim variableChar As Char = \"a\"\n    Dim variableDataTime As DateTime = \"13:22:48 26-09-2024\"\n    Dim variableDecimal As Decimal = 1.0123456789012346\n    Dim variableDouble As Double = 2.0123456789012346\n    Dim variableInteger As Integer = 1999\n    Dim variableInt32 As Int32 = -1999\n    Dim variableInt64 As Int64 = -900000000\n    Dim variableLong As Long = -900000000\n    Dim variableObject As Object = {\"Raro es \", 1, \"el objeto aquel.\"}\n    Dim variableSByte As SByte = -128\n    Dim variableShort As Short = -32767\n    Dim variableSingle As Single = 3.1416\n    Dim varString As String = \"Acá se esecribe el menaje con la historia de IAN\"\n    Dim varUInteger As UInteger = 3276744567\n    Dim varUULong As ULong = 3215647465468454901\n    Dim varUShort As UShort = 65535\n\n    '  ========================================================================\n    ' | TIPO DE DATO      | ALMACENAMIENTO NOMINAL  | INTERVALO DE VALORES     |\n    ' |===================|=========================|==========================|\n    ' | Boolean           | Depende de la plataforma| True o False             |\n    ' | Byte              | 1 byte                  | De 0 a 255 (sin signo)   |\n    ' | Char              | 2 bytes                 | De 0 a 65535 (sin signo) |\n    ' | DateTime          | 8 bytes                 | F 00:00:00 1-1-1900      |\n    ' | Decimal           | 16 byte                 | 0 a 7.9E + 28 digitos    |\n    ' | Double            | 8 bytes                 | - 1.7E 308 a 4.9E 324    |\n    ' | Int32, Integer    | 4 bytes                 | -2147483648 a 2147483647 |\n    ' | Int64, Long       | 8 bytes                 | +-9223372036854775808    |\n    ' | Object            | 8 bytes                 | Cuañquier tipo de dato   |\n    ' | SByte             | 1 byte                  | De -128 a 127 (con signo)|\n    ' | Short             | 2 bytes                 | -32768 a 32767           |\n    ' | Single            | 4 bytes                 | 3.40E 45                 |\n    ' | String            | Variable                | De 0 a 2000 millones     |\n    ' | UInteger, UInt32  | 4 bytes                 | De 0 a 4294967295        |\n    ' | ULong, UInt64     | 8 bytes                 | De 0 a 1.8E 19           |\n    ' | ValueType (Custom)| Variable                |                          |\n    ' | UShort            | 2 bytes                 | De 0 a 65535 (sin signo) |\n    ' --------------------------------------------------------------------------\n\n    Sub Main()\n\n        Console.WriteLine(\"Hola, {0}.\", mStrLenguaje)\n\n    End Sub\n\nEnd Module\n\n' Fuente. https://retosdeprogramacion.com/roadmap/\n' ¿Preparad@ para aprender o repasar el lenguaje de programación que tú quieras?\n' - Recuerda que todas las instrucciones de participación están en el\n'   repositorio de GitHub.\n' \n' Lo primero... ¿Ya has elegido un lenguaje?\n' - No todos son iguales, pero sus fundamentos suelen ser comunes.\n' - Este primer reto te servirá para familiarizarte con la forma de participar\n'   enviando tus propias soluciones.\n' \n'-----------------------------------------------------\n' ### EJERCICIO:\n'-----------------------------------------------------\n' - Crea un comentario en el código y coloca la URL del sitio web oficial del\n'   lenguaje de programación que has seleccionado.\n' - Representa las diferentes sintaxis que existen de crear comentarios\n'   en el lenguaje (en una línea, varias...).\n' - Crea una variable (y una constante si el lenguaje lo soporta).\n' - Crea variables representando todos los tipos de datos primitivos\n'   del lenguaje (cadenas de texto, enteros, booleanos...).\n' - Imprime por terminal el texto: \"¡Hola, [y el nombre de tu lenguaje]!\"\n' \n'  ¿Fácil? No te preocupes, recuerda que esta es una ruta de estudio y\n'  debemos comenzar por el principio.\n'____________________________________________________\n' # INFORMACIÓN ADICIONAL:\n''\n' ____________________________________________________\n' # COMENTARIOS PERSONALES:\n'\n' Finalizado exitosamente\n' Elaboración más extensa de lo calculado, especialmente realizando la busqueda de\n' todos los tipos de datos nativos en la documentación del lenguaje.\n' ____________________________________________________\n"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/vb.net/kenysdev.vb",
    "content": "' ╔══════════════════════════════════════╗\n' ║ Autor: Kenys Alvarado                ║\n' ║ GitHub: https://github.com/Kenysdev  ║\n' ║ 2024 - VB.NET                        ║\n' ╚══════════════════════════════════════╝\n' 1. Sitio web oficial:\n' *********************\n' https://learn.microsoft.com/es-es/dotnet/visual-basic/\n\nImports System\nModule Program\n    Sub Main(args As String())\n\n        ' 2. Sintaxis para comentarios:\n        ' *****************************\n        Dim edad As Integer = 21 'comentario inline\n\n        ' Comentarios Block\n        ' '''\n        '   comentario para\n        '   múltiples líneas.\n        ' '''\n\n        ' TODO: Futuras modificaciones o escritura.\n        ' HACK: Solución temporal, revisar y mejorar.\n        ' BUG: Corregir\n\n#Disable Warning IDE0018 ' Desactivar temporalmente una advertencia.\n        ' código ...\n#Enable Warning IDE0018 ' Restaurarla después\n\n        ''' <summary>\n        ''' Comentarios XML, para generadores de documentación\n        ''' </summary>\n        ''' <param name=\"parametro\">Descripción del parámetro.</param>\n        ''' <returns>Descripción del valor de retorno.</returns>\n\n#If DEBUG Then\n        ' Comentarios condicionales\n        ' Este código se compila solo en configuraciones de depuración\n#End If\n\n        ' 3. Variable y constante.\n        ' ************************\n        Dim variable_edad As Integer = 21\n        Const Constante As Double = 3.14\n\n        ' 4. Variables para datos primitivos.\n        ' ***********************************\n        ' Enteros:\n        Dim entero As Integer = 42         ' Entero de 32 bits\n        Dim byteEntero As Byte = 255       ' Entero sin signo de 8 bits\n        Dim corto As Short = 10000         ' Entero de 16 bits\n        Dim largo As Long = 123456789L     ' Entero de 64 bits\n        ' uint, ushort, ulong -> No soportan números negativos\n\n        ' Decimales:\n        Dim flotante As Single = 3.14F          ' Número de punto flotante de 32 bits\n        Dim doble As Double = 3.14159           ' Número de punto flotante de 64 bits\n        Dim decimalValor As Decimal = 123.456D ' Número decimal de 128 bits\n\n        ' Caracteres y Cadenas:\n        Dim caracter As Char = \"A\"c           ' Carácter Unicode\n        Dim cadena As String = \"Hola\"         ' Cadena de caracteres\n\n        ' Booleanos:\n        Dim esVerdadero As Boolean = True     ' Valor booleano verdadero\n        Dim esFalso As Boolean = False        ' Valor booleano falso\n\n        ' 5. Imprime: hola, lenguaje:\n        ' **************************\n        Console.WriteLine(\"¡Hola, VB.NET!\")\n    End Sub\nEnd Module"
  },
  {
    "path": "Roadmap/00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/zig/edalmava.zig",
    "content": "//! Comentario Doc de nivel superior: comienzan con dos barras y un signo de exclamación\n//! Documenta el módulo actual\n//! Es un error de compilación si no se coloca un comentario doc de nivel superior al principio,\n//! antes de cualquier expresión.\n\n// Los comentarios en Zig inician con // y va hasta el final de la línea\n// No existen comentarios de varias líneas\n\n/// Comentarios Doc: comienzan con tres barras ///\n\n// Sitio oficial: https://ziglang.org/\n// En este archivo se uso Zig 0.13.0\n// Documentación Oficial: https://ziglang.org/documentation/0.13.0/\n\nconst std = @import(\"std\");\nconst print = std.debug.print;\n\npub fn main() void {\n    // Para declarar una variable es preferible utilizar la palabra const en lugar de var\n    // Usar la palabra clave const para asignar un valor a un identificador\n    // El valor no se puede modificar\n    // Si se desea modificar el valor usar la palabra clave var\n\n    // Valores enteros\n    const entero: i32 = 1 + 1;\n    print(\"1 + 1 = {}\\n\", .{entero});\n    // entero = 2;   // Esta línea sin comentar genera un error debido a que no se puede asignar un nuevo valor a const\n\n    var entero2: i32 = 1;\n    entero2 = 2;\n\n    // Valores flotantes\n    const flotante: f32 = 7.0 / 3.0;\n    print(\"7.0 / 3.0 = {}\\n\", .{flotante});\n\n    // Valores Booleanos\n    print(\"true and false = {}\\ntrue or false = {}\\n!true = {}\\n\", .{ true and false, true or false, !true });\n\n    // Valores caracter o Unicode\n    const letra = 'A';\n    const rayo = '⚡';\n    print(\"{u} - {u}\\n\", .{ letra, rayo });\n\n    // Cadenas literales de varias líneas se usan dos barras invertidas \\\\ por cada línea\n    const plantilla_html =\n        \\\\ <html>\n        \\\\   <head></head>\n        \\\\   <body></body>\n        \\\\ </html>\n    ;\n    print(\"{s}\\n\", .{plantilla_html});\n\n    // Cadenas literales\n    const lenguaje = \"Zig\";\n    print(\"¡Hola, {s}!\\n\", .{lenguaje});\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/ada/reanthonyh.adb",
    "content": "with Ada.Text_IO;\n\nprocedure Operadores is\n   A, B             : constant Boolean := True;\n   C, D             : constant Boolean := False;\n   Numero1, Numero2 : Integer          := 5;\nbegin\n   -- Operadores Aritmeticos\n   Ada.Text_IO.Put_Line (\"Suma:\" & Integer'Image (Numero1 + Numero2));\n   Ada.Text_IO.Put_Line (\"Resta:\" & Integer'Image (Numero1 - Numero2));\n   Ada.Text_IO.Put_Line\n     (\"Multiplicacion:\" & Integer'Image (Numero1 * Numero2));\n   Ada.Text_IO.Put_Line\n     (\"Division:\" & Float'Image (Float (Numero1) / Float (2)));\n   Ada.Text_IO.Put_Line (\"Resta_Division:\" & Integer'Image (Numero1 rem 3));\n   Ada.Text_IO.Put_Line (\"Exponencial:\" & Float'Image (Float (Numero1**2)));\n   -- Cambio de signo usando + o -\n   Numero2 := -Numero2;\n   Ada.Text_IO.Put_Line\n     (\"Cambio de signo:\" & Integer'Image (Numero1 + Numero2));\n\n   -- Operadores Logicos\n   if A and B then\n      Ada.Text_IO.Put_Line (\"A y B son True\");\n   else\n      Ada.Text_IO.Put_Line (\"A y B son False\");\n   end if;\n\n   if C or D then\n      Ada.Text_IO.Put_Line (\"C o D son True\");\n   else\n      Ada.Text_IO.Put_Line (\"C o D son False\");\n   end if;\n\n   if not C then\n      Ada.Text_IO.Put_Line (\"Negacion de C es True\");\n   else\n      Ada.Text_IO.Put_Line (\"Negacion de C es False\");\n   end if;\n\n   if A xor C then\n      Ada.Text_IO.Put_Line (\"A xor C es True\");\n   else\n      Ada.Text_IO.Put_Line (\"A xor C es False\");\n   end if;\n\n   -- LOOPS\n   declare\n      Contador : Integer := 10;\n   begin\n      -- Simple Loop\n      loop\n         Ada.Text_IO.Put_Line (Integer'Image (Contador));\n         Contador := Contador - 1;\n         exit when Contador = 0;\n      end loop;\n      -- While\n      while Contador < 10 loop\n         Contador := Contador + 1;\n         Ada.Text_IO.Put_Line (Integer'Image (Contador));\n      end loop;\n   end;\n\n   -- Ejercicio\n   for J in 10 .. 55 loop\n      declare\n         isPar          : Boolean;\n         isMultiploTres : Boolean;\n      begin\n         isPar          := J rem 2 = 0;\n         isMultiploTres := J rem 3 = 0;\n         if isPar and not (isMultiploTres or J = 16) then\n            Ada.Text_IO.Put_Line (\"Numero: \" & Integer'Image (J));\n         end if;\n      end;\n   end loop;\nend Operadores;\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/arduino/santyjL.ino",
    "content": "//#01 OPERADORES Y ESTRUCTURAS DE CONTROL\n\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n//variables - operadores del lenguaje\n\n//aritmetica\nint suma = 3 + 4;\nint resta = 3 - 4;\nint multiplicacion = 3 * 5;\nfloat division = 3 / 5;\nint potencia =pow(3 , 5);\nfloat modulo = 5 % 3;\n\n//logicos -- los true y false en la terminal se presentan como 1 para true y 0 para false\nbool AND0 = true && true;\nbool AND1 = true && false ;\nbool AND2= false && true;\nbool AND3 = false && false;\n\nbool OR0 = true || true;\nbool OR1 = true || false;\nbool OR2 = false || true;\nbool OR3 = false || false;\n\nbool NOT0 = !true;\nbool NOT1 = !false;\n\n//comparacion\nbool mayorQue= 3 > 5;\nbool menorQue= 3 < 5;\nbool igualQue= 3 == 5;  //se puede considerar de identidad\nbool mayorOIgualQue = 3 >= 5;\nbool menorOIgualQue = 3 <= 5 ;\nbool diferenteQUE = 3 != 5; //se puede considerar de identidad\n\n//asignacion\nint num = 12;\nint num1 = num += 5;\nint num2 = num -= 3;\nint num3 = num *= 3;\nfloat num4 = num /=5;\nint num5 = num %= 3;\n\n//pertenencia\n\n//en arduino no existen por el hecho de que se prioriza el rendimiento y el almacenamiento por lo cual no se suele utilizar listas o datos compuestos\n\n//bits\nint byte1 = 0b11011010;\nint byte2 = 0b10101011;\n\nbyte resultadoAND = byte1 & byte2;\nbyte resultadoOR = byte1 | byte2;\nbyte resultadoXOR = byte1 ^ byte2;\nbyte resultadoNOT = ~byte1;\nbyte resultadoShiftLeft = byte1 << 2;\nbyte resultadoShiftRight = byte1 >> 1;\n\n\nvoid setup(){\n  Serial.begin(9600);\n\n  Serial.println(\"Operaciones Aritméticas:\");\n  Serial.println(\"Suma: \" + String(suma));\n  Serial.println(\"Resta: \" + String(resta));\n  Serial.println(\"Multiplicación: \" + String(multiplicacion));\n  Serial.println(\"División: \" + String(division));\n  Serial.println(\"Potencia: \" + String(potencia));\n  Serial.println(\"Módulo: \" + String(modulo));\n\n  delay(900);\n\n  Serial.println(\"\\nOperadores Lógicos:\");\n  Serial.println(\"AND0: \" + String(AND0));\n  Serial.println(\"AND1: \" + String(AND1));\n  Serial.println(\"OR0: \" + String(OR0));\n  Serial.println(\"OR1: \" + String(OR1));\n\n  delay(900);\n\n  Serial.println(\"\\nOperadores de Comparación:\");\n  Serial.println(\"Mayor que: \" + String(mayorQue));\n  Serial.println(\"Menor que: \" + String(menorQue));\n  Serial.println(\"Igual que: \" + String(igualQue));\n\n delay(900);\n\n  Serial.println(\"\\nOperadores de Asignación:\");\n  Serial.println(\"Num1: \" + String(num1));\n  Serial.println(\"Num2: \" + String(num2));\n  Serial.println(\"Num3: \" + String(num3));\n  Serial.println(\"Num4: \" + String(num4));\n  Serial.println(\"Num5: \" + String(num5));\n\n delay(900);\n\n  Serial.println(\"\\nOperadores de Bits:\");\n  Serial.println(\"Resultado AND: \" + String(resultadoAND, BIN));\n  Serial.println(\"Resultado OR: \" + String(resultadoOR, BIN));\n  Serial.println(\"Resultado XOR: \" + String(resultadoXOR, BIN));\n  Serial.println(\"Resultado NOT: \" + String(resultadoNOT, BIN));\n  Serial.println(\"Resultado Shift Left: \" + String(resultadoShiftLeft, BIN));\n  Serial.println(\"Resultado Shift Right: \" + String(resultadoShiftRight, BIN));\n\n delay(900);\n\n  //CONTROL DE FLUJO\n  //CONDICIONALES\n\n  int num = 1 ;\n  Serial.println(\"\\nCondicionales\");\n\n  if (num == 1){\n    Serial.println(\"el numero es 1\");\n     delay(900);\n  }\n\n  else if (num == 2){\n    Serial.println(\"cambiaron el codigo\");\n     delay(900);\n  }\n\n  else {\n    Serial.println(\"cambiastes el codigo a algo que no es 2 ni 1\");\n     delay(900);\n  }\n\n\n  //BUCLES\n  Serial.println(\"\\nBucle For:\");\n\n  for (int i = 0; i <=10; i++ ){  //el i ++ es para sumarle un 1 a la       variable i la razon es porque este consume menos espacio\n    Serial.println(\"valor de i : \" + String(i));\n     delay(250);\n  }\n\n    // Bucle While con Condiciones\n    Serial.println(\"\\nBucle While con Condiciones:\");\n\n    int contador = 0;\n    while (contador <= 10) {\n\n      if (contador % 2 == 0) {\n        Serial.println(\"Número par: \" + String(contador));\n        delay(250);\n\n    }\n      contador++;\n  }\n\n  // Estructura switch\n\n  Serial.println(\"\\nSwitch\");\n  switch (num) {\n    case 1:\n      Serial.println(\"num es 1\");\n      break;\n    case 2:\n      Serial.println(\"num es 2\");\n      break;\n    default:\n      Serial.println(\"num no es ni 1 ni 2\");\n  }\n  delay(900);\n\n  //Extra\n  Serial.println(\"\\nEjercicio Extra : \");\n  for (int i = 10 ; i <=55 ; i++ ){\n    if(i % 2 == 0 && i % 3 != 0 || i == 55 && i != 16 ){\n      Serial.println(\"valor es : \" + String(i));\n    }\n  }\n}\n\n\n\nvoid loop(){ //el bucle loop es un bucle que nunca se deja de repetir este si es 100% infinito\n\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/bash/angelsanchezt.sh",
    "content": "#!/bin/bash\n\n# Operadores Ariméticos\necho \"Operadores Ariméticos\"\na=5\nb=2\necho \"Suma ($a + $b): $((a + b))\"\necho \"Resta ($a - $b): $((a - b))\"\necho \"Multiplicación ($a * $b): $((a * b))\"\necho \"División ($a / $b): $((a / b))\"\necho \"Módulo ($a % $b): $((a % b))\"\n\na=10\nb=20\n\nval=`expr $a + $b`\necho \"a + b : $val\"\n\n# Operadores de Comparación\necho \"\\nOperadores de Comparación:\"\necho \"Igualdad ($a == $b) es: $((a == b))\"\necho \"Desigualdad ($a != $b) es: $((a != b))\"\necho \"Menor que: ($a < $b) es: $((a < b))\"\necho \"Mayor que: ($a > $b) es: $((a < b))\"\necho \"Mayor o igual que: ($a >= $b) es $((a >= b))\"\necho \"Menor o igual que: ($a <= $b) es $((a <= b))\"\n\n# Lógicos\necho \"\\nOperadores Lógicos:\"\necho \"AND &&: ($a != $b) && ($a > $b) es $(( a != b && a > b))\"\necho \"OR ||: ($a != $b) || ($a > $b) es $(( a != b || a > b))\"\necho \"NOT !: !($a != $b) es $(( ! (a != b) ))\"\n\n# Operadores de asignación\necho \"\\nOperadores de asignación\"\na=10\necho \"Antes de la asignación: $a\"\na=$((a + 5))\necho \"Después de la asignación: $a\"\n\n# aproximación de pi\necho \"scale=7; 355 / 113\" | bc -l\necho \"4 ^ 2\" | bc -l\necho \"scale=2; sqrt(4)\" | bc -l\necho \"scale=3; (1.23 / 0.32) + (5 * 2)\" | bc -l\n\n# Estructuras de Control\necho \"\\nEstructuras de Control:\"\n\n# Condicionales\necho \"\\nCondicionales\"\nif [ $a -gt 15 ]; then\n  echo \"$a es mayor que 15\"\nelse\n  echo \"$a es menor o igual que 15\"\nfi\n\nstr1=\"Hola\"\nstr2=\"Hola\"\n\nif [ \"$str1\" = \"$str2\" ]; then\n    echo \"Equal\"\nelse\n    echo \"No equals\"\nfi\n\n# Iterativas\necho -e \"\\nEstructuras Iterativas:\"\necho \"Números del 10 al 55 (pares y no múltiplos de 3):\"\nfor ((i=10; i<=55; i++)); do\n  if [ $((i % 2)) -eq 0 ] && [ $((i % 3)) -ne 0 ]; then\n    echo $i\n  fi\ndone\n\n\nset -e\n \n# Some commands that may fail\ncommand1 && command2 && command3\n# This line will only be reached if all the commands above succeed\necho \"All commands completed successfully\"\n\necho \"EXTRA\"\necho \"Números entre 10 y 55 (incluidos), pares, y no múltiplos de 3 ni 16:\"\n\nfor ((i=10; i<=55; i++)); do\n  if [ $((i % 2)) -eq 0 ] && [ $((i % 3)) -ne 0 ] && [ $i -ne 16 ]; then\n    echo $i\n  fi\ndone\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/bash/arturonavas.sh",
    "content": "#!/bin/bash\n: '\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n'\n# variables\na=5\nb=2\narr=(\"uno\" \"dos\" \"tres\")\n\n# operadores aritmeticos\necho \"::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\"\necho \"operaciones de:\" \"$a\" \"y\" \"$b\"\necho \"suma:\" \"$(( a + b ))\"\necho \"resta:\" \"$(( a - b ))\"\necho \"multiplicacion:\" \"$(( a * b ))\"\necho \"division:\" \"$(( a / b ))\"\necho \"modulo:\" \"$(( a % b ))\"\necho \"exponencial:\" \"$(( a ** b ))\"\necho \"::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\"\n# operadores logicos\necho \"and:\" \"$(( a && b ))\"\necho \"or:\"  \"$(( a || b ))\"\necho \"not:\" \"$(( ! a ))\"\necho \"::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\"\n# operadores de comparacion\necho \"igual:\"          \"$(( a == b ))\"\necho \"distinto:\"       \"$(( a != b ))\"\necho \"menor:\"          \"$(( a < b ))\"\necho \"mayor:\"          \"$(( a > b ))\"\necho \"menor o igual:\"  \"$(( a <= b ))\"\necho \"mayor o igual:\"  \"$(( a >= b ))\"\necho \"::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\"\n# operadores de asignacion\nx=$a\necho \"asignacion simple x=\\$a:\"          \"$x\"\necho \"asignacion directa x=b:\"          \"$(( x=b ))\"\necho \"suma compuesta x+=b:\"             \"$(( x+=b ))\"\necho \"resta compuesta x-=b:\"            \"$(( x-=b ))\"\necho \"multiplicacion compuesta x*=b:\"   \"$(( x*=b ))\"\necho \"division compuesta x/=b:\"         \"$(( x/=b ))\"\necho \"modulo compuesto x%=b:\"           \"$(( x%=b ))\"\necho \"::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\"\n# operadores de pertenencia\necho \"archivo existe -e /etc/passwd:\"     \"$([ -e /etc/passwd ] && echo 1 || echo 0)\"\necho \"directorio existe -d /tmp:\"         \"$([ -d /tmp ] && echo 1 || echo 0)\"\nval=\"dos\"\necho \"valor en array dos:\"               \"$([[ \" ${arr[@]} \" =~ \" ${val} \" ]] && echo 1 || echo 0)\"\necho \"::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\"\n# operadores bit a bit, me costo entender esto\necho \"and bit\"                     \"$(( a & b ))\"\necho \"or bit\"                      \"$(( a | b ))\"\necho \"xor:\"                        \"$(( a ^ b ))\"\necho \"desplazamiento izq:\"         \"$(( a << b ))\"\necho \"desplazamiento der\"          \"$(( a >> b ))\"\necho \"::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\"\n# condicionales (if)\nif [[ $a -gt $b ]]; then\n  echo \"a mayor que b\"\nelif [[ $a -lt $b ]]; then\n  echo \"a menor que b\"\nelse\n  echo \"a igual b\"\nfi\necho \"::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\"\n# bucles iterativos\n\n# for en shell (for in)\nfor item in \"${arr[@]}\"; do\n  echo \"item: $item\"\ndone\necho \"::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\"\n\n# for estilo c (for comun)\nfor (( i=0; i<b; i++ )); do\n  echo \"for en c i: $i\"\ndone\necho \"::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\"\n\n# while\ni=0\nwhile [[ $i -lt 3 ]]; do\n  echo \"while i: $i\"\n  (( i++ ))\ndone\necho \"::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\"\n\n# until\ni=0\nuntil [[ $i -ge 3 ]]; do\n  echo \"until i: $i\"\n  (( i++ ))\ndone\necho \"::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\"\n# gestion de errores (excepciones)\n\n#redirije el output del error para que no lo muestre\nls /ruta/que/no/existe\nls /ruta/que/no/existe 2>/dev/null\n\n# salir si un comando falla\nset -e\n# atrapar cualquier error\ntrap 'echo \"error en el script\"; exit 1' ERR\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/bash/drvito1977.sh",
    "content": "#!/bin/bash\n\n# Sección de operadores (ejemplo básico)\na=10 # Asignación de valor a la variable a\nb=5 # Asignación de valor a la variable b\n\nsuma=$((a+b))\nresta=$((a-b))\nmultiplicacion=$((a*b)) \ndivision=$((a/b))\nmodulo=$((a%b))\nmayor=$((a>b))\nmenor=$((a<b))\nigual=$((a==b))\ndiferente=$((a!=b))\nand_logico=$((a && b))\nor_logico=$((a || b))\nnot_logico=$((!a))\n\n# Imprimir resultados de los operadores\necho \"Suma: $suma\"\necho \"Resta: $resta\"\necho \"Multiplicación: $multiplicacion\"\necho \"División: $division\"\necho \"Módulo: $modulo\"\necho \"Mayor: $mayor\"\necho \"Menor: $menor\"\necho \"Igual: $igual\"\necho \"Diferente: $diferente\"\necho \"AND lógico: $and_logico\"\necho \"OR lógico: $or_logico\"\necho \"NOT lógico: $not_logico\"\n\n# Sección de estructuras de control y operadores de comparación\n\nif [ $a -gt 5 ]; then #Comparación de la variable a \n                      #con el operador de mayor que -gt\n  echo \"$a es mayor que 5\"\nelse\n  echo \"$a es menor o igual que 5\"\nfi\n\nif [ $b -eq  5 ]; then #Comparación de la variable b \n                       #con el operador de igualdad -eq\n  echo \"$b es igual a 5\"\nelse\n  echo \"$b no es igual a 5\"\nfi\n\nif [ ! $a -eq 5 ]; then #Comparación de la variable a\n                       #con el operador de negación \"!\" de igualdad -eq  \n  echo \"$a no es igual a 5\"\nelse\n  echo \"$a es igual a 5\"\nfi\n\n# Ejemplo de case con la variable b\nb=2\ncase $b in\n  1)\n    echo \"$b es 1\" # Caso 1  \n    ;;\n  2)\n    echo \"$b es 2\" # Caso 2\n    ;;\n  *)\n    echo \"$b no es ni 1 ni 2\" # Caso por defecto\n    ;;\nesac\n\n#while [ $c -eq 10 ]; do # Bucle mientras c sea igual a 10\n\n# Bucle while con una variable c\nc=10\n\nprimera_vez=true # Variable para saber si es la primera vez que se ejecuta el bucle\nwhile [ $c -ge 1 ]; do # Bucle mientras c sea mayor o igual a 1\n  if [ $primera_vez = true ]; then\n    echo \"El contador empieza en $c\"\n    primera_vez=false\n  else\n    echo \"El contador continua con $c\"\n  fi\n  ((c--)) # Decremento de la variable\ndone\necho \"El contador termina en $c\"\n\n# Bucle for con una secuencia de números\nfor i in {1..5}; do # Bucle de 1 a 5\n  echo \"Iteración $i del bucle for\"\ndone\n\n#Ejercicio opcional\nfor ((i=10; i<=55; i++)); do # Bucle de 10 a 55\n  if (( i % 2 == 0 )) && (( i != 16 )) && (( i % 3 != 0 )); then # Condiciones para que el número sea par, \n                                                                  #!/usr/bin/env bash\n                                                                  # -*- coding: utf-8 -*-no sea 16 y no sea divisible por 3\n    echo $i\n  fi\ndone\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/bash/h4ckxel.sh",
    "content": "#!/bin/bash\n\n# Operadores Ariméticos\necho \"Operadores Ariméticos\"\na=5\nb=2\necho \"Suma ($a + $b): $((a + b))\"\necho \"Resta ($a - $b): $((a - b))\"\necho \"Multiplicación ($a * $b): $((a * b))\"\necho \"División ($a / $b): $((a / b))\"\necho \"Módulo ($a % $b): $((a % b))\"\n\na=10\nb=20\n\nval=`expr $a + $b`\necho \"a + b : $val\"\n\n# Operadores de Comparación\necho \"\\nOperadores de Comparación:\"\necho \"Igualdad ($a == $b) es: $((a == b))\"\necho \"Desigualdad ($a != $b) es: $((a != b))\"\necho \"Menor que: ($a < $b) es: $((a < b))\"\necho \"Mayor que: ($a > $b) es: $((a < b))\"\necho \"Mayor o igual que: ($a >= $b) es $((a >= b))\"\necho \"Menor o igual que: ($a <= $b) es $((a <= b))\"\n\n# Lógicos\necho \"\\nOperadores Lógicos:\"\necho \"AND &&: ($a != $b) && ($a > $b) es $(( a != b && a > b))\"\necho \"OR ||: ($a != $b) || ($a > $b) es $(( a != b || a > b))\"\necho \"NOT !: !($a != $b) es $(( ! (a != b) ))\"\n\n# Operadores de asignación\necho \"\\nOperadores de asignación\"\na=10\necho \"Antes de la asignación: $a\"\na=$((a + 5))\necho \"Después de la asignación: $a\"\n\n# aproximación de pi\necho \"scale=7; 355 / 113\" | bc -l\necho \"4 ^ 2\" | bc -l\necho \"scale=2; sqrt(4)\" | bc -l\necho \"scale=3; (1.23 / 0.32) + (5 * 2)\" | bc -l\n\n# Estructuras de Control\necho \"\\nEstructuras de Control:\"\n\n# Condicionales\necho \"\\nCondicionales\"\nif [ $a -gt 15 ]; then\n    echo \"$a es mayor que 15\"\nelse\n    echo \"$a es menor o igual que 15\"\nfi\n\nstr1=\"Hola\"\nstr2=\"Hola\"\n\nif [ \"$str1\" = \"$str2\" ]; then\n    echo \"Equal\"\nelse\n    echo \"No equals\"\nfi\n\n# Iterativas\necho -e \"\\nEstructuras Iterativas:\"\necho \"Números del 10 al 55 (pares y no múltiplos de 3):\"\nfor ((i=10; i<=55; i++)); do\n    if [ $((i % 2)) -eq 0 ] && [ $((i % 3)) -ne 0 ]; then\n        echo $i\n    fi\ndone\n\n\nset -e\n\ncommand1 && command2 && command3\necho \"All commands completed successfully\"\n\necho \"EXTRA\"\necho \"Números entre 10 y 55 (incluidos), pares, y no múltiplos de 3 ni 16:\"\n\nfor ((i=10; i<=55; i++)); do\n    if [ $((i % 2)) -eq 0 ] && [ $((i % 3)) -ne 0 ] && [ $i -ne 16 ]; then\n        echo $i\n    fi\ndone\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/bash/rantamhack.sh",
    "content": "# OPERADORES ARITMETICOS\n# toman los operadores que se le indican y realizan un cálculo matemático\n\n\nsuma=$((5+3))\necho $suma\nresta=$((5-3))\necho $resta\nmultiplicacion=$((5*3)) \necho $multiplicacion\ndivision=$((5/2))\necho $division\nmodulo=$((10%3))  # Modulo es el resto que nos queda de la división en éste caso es 1\necho $modulo\npotencia=$((10**3)) # Eleva a la potencia 3 el pirmer operando que le pasamos \necho $potencia\n\necho -e \"\\n\\n=======================================================================\\n\\n\"\n\n# OPERADORES RELACIONALES\n# Son los que relacionan dos elementos entre sí\n\necho $((5>3))  # Devuelve 1 (True) si es verdadero\necho $((5>=3)) # Devuelve 1 (True) si es verdadero\necho $((5<3))  # Devuelve 1 (True) si es verdadero\necho $((5<=3)) # Devuelve 1 (True) si es verdadero\necho $((5==3)) # Devuelve 1 (True) solo si los dos operandos son iguales\necho $((5!=3)) # Devuelve 1 (True) solo si los dos operandos son diferentes\n\necho -e \"\\n\\n=======================================================================\\n\\n\"\n\n# OPERADORES LOGICOS\n# Se usan basandonos en condiciones\n\n# El operando \"AND\" \"&&\" devuelve True (1) siempre que los dos operandos sean correctos\necho \"$(( 3 + 2 == 5 && 7 * 2 == 14 ))\"\n# El operando \"OR\" \"||\" devuelve True (1) siempre que uno de los dos operandos sea correcto\necho \"$((3 + 2 == 5 || 7 * 2 == 10 ))\"\n# El operando \"NOT\" \"!\" devuelve True (1) siempre que uno de los dos operandos sea falso\necho \"$(( 10 + 3 != 14 ))\"\n\necho -e \"\\n\\n=======================================================================\\n\\n\"\n\n# OPERADORES DE ASIGNACION\n# Son los que se usan para dar valor a una variable por ejemplo\n\nmy_variable=5         # Asignación    \necho $my_variable\n\nlet my_variable+=1\necho $my_variable      # Suma y Asignación\n\nlet my_variable-=1\necho $my_variable      # Resta y Asignación\n\nlet my_variable*=2\necho $my_variable      # Multiplicación y Asignación\n\nlet my_variable/=2\necho $my_variable      # División y Asignación\n\nlet my_variable%=3\necho $my_variable      # Mòdulo y aAsignación\n\n\necho -e \"\\n\\n=======================================================================\\n\\n\"\n\n\n# Operadores de bit\n# Realiza operaciones en los operandos bit a bit\n\na=10 # 1010 en binario\nb=3  # 0011 en binario\n\necho $(( $a >> $b ))    # 0001 (1) Desplazamos a la derecha 3 bits y rellenamos con ceros por delante\necho $(( $a << $b ))    #1010000 (80) Cubrimos con ceros por detras las posiciones que nos pide el segundo operando\n\necho -e \"\\n\\n=======================================================================\\n\\n\"\n\n# ESTRUCTURAS DE CONTROL \n# CONDICIONALES \n\nif [ $a -lt $b ]; then\n    echo \"$a es menor que $b\"\nelif [ $a -eq $b ];then\n    echo \"$a es igual a $b\"\nelse [ $a -gt $b ];\n    echo  \"$a en mayor que $b\"\nfi\necho -e \"\\n\\tla equivalencia de condicionales es:\\n\n        -gt     >       mayor\\n\n        -lt     <       menor\\n\n        -ge     >=      mayor o igual\\n\n        -le     <=      menor o igual\\n\n        -eq     ==      igual\\n\n        -ne     !=      distinto\\n\"\n\necho -e \"\\n\\n=======================================================================\\n\\n\"\n\n# ESTRUCTURAS DE CONTROL \n# ITERATIVAS\n\nfor i in $(seq 1 10); do\n    echo \"$i\"\ndone\n\necho -e \"\\n\\n=======================================================================\\n\\n\"\n\ncomienza=10\ntermina=20\n\nwhile [ $termina -ge $comienza ] \ndo\n    echo $comienza\n    let comienza=$comienza+1\ndone\n\necho -e \"\\n\\n=======================================================================\\n\\n\"\n\n\nfor number in $(seq 10 56);do\n    if [ $((number % 2)) -eq 0 ] && [ $((number)) -ne 16 ] && [ $((number %3)) -ne 0 ]; then\n        echo \"$number\"\n    fi\ndone\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/bash/santyjL.sh",
    "content": "#!/bin/bash\n\n: \"\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\"\n\n# Operadores Aritméticos\na=10\nb=3\n\necho \"Operadores Aritméticos:\"\n\necho \"Suma: $((a+b))\"\necho \"Resta: $((a-b))\"\necho \"Multiplicación: $((a*b))\"\necho \"División: $((a/b))\"\necho \"Módulo: $((a%b))\"\necho \"Exponenciación: $((a**b))\"\necho -e \"\\n################################################################\\n\"\n\n# Operadores de Comparación\necho \"Operadores de Comparación:\"\necho \"Mayor que: $((a>b))\"\necho \"Mayor o igual que: $((a>=b))\"\necho \"Menor que: $((a<b))\"\necho \"Menor o igual que: $((a<=b))\"\necho \"Igual a: $((a==b))\"\necho \"Distinto de: $((a!=b))\"\necho -e \"\\n################################################################\\n\"\n\n# Operadores Lógicos\necho \"Operadores Lógicos:\"\n\necho \"AND: $((a+b==13 && a>b))\" #Devuelve 1 si ambas condiciones son verdaderas si no 0\necho \"OR: $((a+b==13 || a<b))\" # #Devuelve 1 si al menos una de las condiciones es verdadera si no 0\necho \"NOT: $((!(a==b)))\" #Devuelve 0 si es verdadero y 1 si es falso\necho -e \"\\n################################################################\\n\"\n# Operadores de Asignación\n\necho \"Operadores de Asignación:\"\n\nvariable=15\necho \"asignación: $variable\"\necho \"Suma y Asignación: $((variable+=5))\"\necho \"Resta y Asignación: $((variable-=3))\"\necho \"Multiplicación y Asignación: $((variable*=2))\"\necho \"División y Asignación: $((variable/=2))\"\necho \"Módulo y Asignación: $((variable%=4))\"\necho -e \"\\n################################################################\\n\"\n\n# Operadores de bits\necho \"Operadores de bits:\"\necho \"AND: $((a & b))\" # AND bit a bit\necho \"OR: $((a | b))\" # OR bit a bit\necho \"XOR: $((a ^ b))\" # XOR bit a bit\n\necho -e \"\\n################################################################\\n\"\n\n# Estructuras de Control\necho \"Estructuras de Control:\"\n\n## Condicionales Enteros\necho \"Condicionales Enteros:\"\n\nvalor_1=5*4\nvalor_2=4*8\n\necho -e \"\\n::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\\n\"\n\necho \"primer valor: $((valor_1))\"\necho \"segundo valor: $((valor_2))\"\n\nif [[ $((valor_1)) > $((valor_2)) ]]; then\n    echo \"$((valor_1)) es mayor que $((valor_2))\"\nelse\n    echo \"$((valor_1)) no es mayor que $((valor_2))\"\nfi  # Para cerrar los condiciones se usa fi\n\nif [[ $((valor_1)) -le $((valor_2)) ]]; then        #el <= || >= son excepciones a la regla de usar [[]] para comparar\n    echo \"$((valor_1)) es menor o igual que $((valor_2))\"\nelse\n    echo \"$((valor_1)) no es menor o igual que $((valor_2))\"\nfi\n\n## Condicionales de cadenas\n\ncadena_1=\"Hola\"\ncadena_2=\"Mundo\"\necho -e \"\\n::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\\n\"\n\necho \"primer texto: $cadena_1\"\necho \"segundo texto: $cadena_2\"\n\nif [[ \"$cadena_1\" == \"$cadena_2\" ]]; then    #se usa [[]] cuando se usan signos/operadores de comparación\n    echo \"Las cadenas son iguales\"\nelse\n    echo \"Las cadenas son diferentes\"\nfi\n\nif [[ \"$cadena_1\" > \"$cadena_2\" ]]; then\n    echo \"$cadena_1 es alfabéticamente mayor que $cadena_2\"\n\nelif [[ \"$cadena_1\" < \"$cadena_2\" ]]; then\n    echo \"$cadena_1 es alfabéticamente menor que $cadena_2\"\n\nelse\n    echo \"$cadena_1 no es ni mayor ni menor alfabéticamente que $cadena_2\"\nfi\n\necho -e \"\\n################################################################\\n\"\n\n# Iterativas, bucles\n\necho \"Estructuras Iterativas:\"\n## Bucle for\n\nfor ((i=0; i<10; i++)); do\n    echo \"esta es la iteracion número: $i\"\ndone\n\nfor i in {1..4}; do\n    echo \"esta es la iteracion número: $i\"\ndone\n\nfor ((i=10; i<31; i+=5)); do # no cuenta el ultimo numero\n    echo \"el valor de i es: $i y ademas se va sumando 5 por iteracion\"\ndone\n\necho -e \"\\n::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\\n\"\n# Bucle while\n\ncontador=0\n\nwhile [[ contador < 10 ]]; do\n    echo \"contador: $contador\"\n    contador+=1\ndone\n\necho -e \"\\n#######################################################################\\n\"\n\n# Ejercio EXTRA\necho \"Ejercicio Extra:\"\n\nfor ((numero=10; numero<=55; numero++)); do\n    if [[ $numero == 10 || $numero == 16 || $((numero % 3)) == 0 || $((numero % 2)) != 0 ]]; then\n        continue\n\n    else\n        echo \"El número $numero es par y no es ni el 16 ni múltiplo de 3\"\n    fi\ndone\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c/04khaos.c",
    "content": "#include <stdio.h>\n\nvoid operadores();\nvoid condicionales();\nvoid iterativas();\nvoid desafio();\n\n\n/* OPERADORES\n   Este programa (código) demuestra los operadores más comunes en C, clasificados en:\n   - Aritméticos: para realizar cálculos matemáticos\n   - Comparación: para comparar valores y generar resultados booleanos\n   - Lógicos: para realizar operaciones con condiciones (AND, OR, NOT)\n   - Asignación: para modificar el valor de una variable\n   - Bits: para trabajar con operaciones a nivel de bits (AND, OR, desplazamientos) */\n\nvoid operadores() {\n\n    // Operadores Aritméticos\n    printf(\"== Operadores Aritméticos ==\\n\");\n    int a = 5, b = 10, c = 5; // Variables globales de la función\n    {\n        printf(\"Suma: %d + %d = %d\\n\", a, b, a + b);\n        printf(\"Resta: %d - %d = %d\\n\", a, b, a - b);\n        printf(\"Multiplicación: %d * %d = %d\\n\", a, b, a * b);\n        printf(\"División: %d / %d = %d\\n\", a, b, a / b); // División por 0 da error\n        printf(\"Módulo: %d %% %d = %d\\n\\n\", a, b, a % b);\n\n        printf(\"Signo negativo: %d → %d\\n\", c, -c);\n        c++; // Incremento\n        printf(\"Incremento: %d → %d\\n\", c - 1, c); // Mostrar el valor antes y después del incremento\n        c--; // Decremento\n        printf(\"Decremento: %d → %d\\n\\n\", c + 1, c); // Mostrar el valor antes y después del decremento\n    }\n\n    //Operadores de Comparación\n    printf(\"== Operadores de Comparación ==\\n    0 (false) || 1 (true)\\n\");\n    {\n        printf(\"Igualdad: (%d == %d) = %d\\n\", a, b, a == b);\n        printf(\"Diferencia: (%d != %d) = %d\\n\", a, b, a != b);\n        printf(\"Mayor que: (%d > %d) = %d\\n\", a, b, a > b);\n        printf(\"Menor que: (%d < %d) = %d\\n\", a, b, a < b);\n        printf(\"Mayor o igual: (%d >= %d) = %d\\n\", a, b, a >= b);\n        printf(\"Menor o igual: (%d <= %d) = %d\\n\\n\", a, b, a <= b);\n    }\n\n    // Operadores Lógicos\n    printf(\"== Operadores Lógicos ==\\n   0 (false) || 1 (true)\\n\");\n    {\n        // AND (&&) - Solo es true si ambas son verdaderas\n        printf(\"¿Ambas son verdaderas? (%d == %d && %d > %d) = %d\\n\", a, c, b, c, a == c && b > c);\n        // OR (||) - Es true si al menos una es verdadera\n        printf(\"¿Alguna es verdadera? (%d == %d || %d < %d) = %d\\n\", b, c, b, a, b == c || b < a);\n        // NOT (!) - Invierte el valor de una condición\n        printf(\"Inverso (a == c); !(%d == %d) = %d\\n\\n\", a, c, !(a == c));\n    }\n\n    // Operadores de Asignación\n    printf(\"== Operadores de Asignación ==\\n\");\n    {\n        int x = 2; // Variable local\n\n        x = 2;  // Valor inicial de x\n        printf(\"(x = 2) = %d\\n\", x);\n        x += 7; // Equivalente a: x = x + 7\"\n        printf(\"(x += 7) = %d\\n\", x);\n        x -= 3; // Equivalente a: x = x - 3\n        printf(\"(x -= 3) = %d\\n\", x);\n        x *= 5; // Equivalente a: x = x * 5\n        printf(\"(x *= 5) = %d\\n\", x);\n        x /= 10;\n        printf(\"(x /= 10) = %d\\n\", x);\n        x %= 2;\n        printf(\"(x %%= 2) = %d\\n\\n\", x);\n    }\n\n    // Operadores de Bits\n    printf(\"== Operadores de Bits ==\\n\");\n    {\n        int x = 3; // Variable local\n        // Operaciones de bits con AND, OR, XOR, etc..\n        printf(\"(a & x) = %d\\n\", a & x);\n        printf(\"(a | x) = %d\\n\", a | x);\n        printf(\"(a ^ x) = %d\\n\", a ^ x);\n        printf(\"(~a) = %d\\n\", ~a);\n        printf(\"(x << 1) = %d\\n\", x << 1);\n        printf(\"(x >> 1) = %d\\n\\n\", x >> 1);\n    }\n}\n\n\n\n\n/* CONDICIONALES\n   Este segmento explora las estructuras condicionales en C, que toma decisiones\n   basadas en condiciones, cambiando su flujo según lo que ocurra. */\n\n   /* \"if - else\" Mejor cuando se comparan rangos de valores o condiciones\n       complejas (>, <, !=). Más flexible para evaluaciones no exactas */\n\nvoid condicionales() {\n\n   printf(\"== Condicionales (if, else) ==\\n\");\n   int age = 20;\n\n   if (age >= 18)\n   {\n    printf(\"Tienes %d, eres mayor de edad\\n\", age);\n   }\n   else\n   {\n    printf(\"Tienes %d, eres menor de edad\\n\", age);\n   }\n\n   if (age >= 1 && age <= 18) { // Entre 1 y 17 años\n    printf(\"¿Cuál es tu videojuego favorito?\\n\\n\");\n   }\n   else if (age < 26) { // Desde los 18 hasta los 25 años\n    printf(\"¿Cuál es tu lenguaje de programación favorito?\\n\\n\");\n   }\n   else { // Desde los 25 años en adelante..\n    printf(\"¿Cuántos años de experiencia tienes programando?\\n\\n\");\n   }\n\n\n   // if-else + switch\n\n   printf(\"== Condicionales (if-else + switch) ==\\n> Sistema de roles\\n\");\n   int rol = 3; // Cambia el valor manualmente para probar distintos casos\n\n   if (rol >= 1 && rol <= 3)\n   {\n    printf(\"> Tu rol asignado: %d\\n\", rol);\n   }\n   else\n   {\n    printf(\"> ERROR\\n\");\n   }\n\n   /* \"switch\" Útil cuando se evalúa una variable contra valores específicos,\n      como enteros o caracteres. Es más legible cuando hay muchas opciones */\n\n   switch (rol) {\n    case 1:\n        printf(\"¡Bienvenido jugador! Puedes explorar y disfrutar del mundo, ¿quieres ver el tutorial?\\n\\n\");\n        break;\n    case 2:\n        printf(\"Saludos, Moderador. Puedes administrar ciertas funciones y mantener el orden\\n\\n\");\n        break;\n    case 3:\n        printf(\"Guild Master. Tienes control total sobre este mundo\\n\\n\");\n        break;\n    default:\n        printf(\"Error: Rol no reconocido. Verifica el valor asignado\\n\\n\");\n   }\n}\n\n\n\n\n/* ITERATIVAS (BUCLES)\n   Estas estructuras permiten repetir bloques de código bajo ciertas condiciones.\n   Se usan cuando queremos ejecutar algo varias veces sin escribir el código manulamente */\n\nvoid iterativas() {\n\n   printf(\"== Estructuras Iterativas ==\\n\");\n\n\n   // Bucle while - Se ejecuta mientras la condición sea verdadera\n   printf(\"> Bucle while:\\n\");\n   int i = 1;\n\n   while( i <= 5) {\n    printf(\"Iteración %d\\n\", i);\n    i++; // Incrementamos i hasta 5 para evitar un bucle infinito\n   }\n   printf(\"\\n\");\n\n\n   // Bucle for: Utiliza una variable de control con inicio, condición y actualización\n   printf(\"> Bucle for:\\n\");\n   int f = 1;\n\n   for (f = 1; f <= 3; f++) {\n    printf(\"Iteración %d\\n\", f);\n   }\n   printf(\"\\n\");\n\n   // Bucle do-while: Garantiza al menos una ejecución antes de comprobar la condición\n   printf(\"> Bucle do-while:\\n\");\n   int d = 10; // Se ejecuta sin importar si la condición es falsa o verdadera al principio\n\n   do {\n    printf(\"Iteración %d\\n\", d);\n    d++;\n   }\n   while (d <= 5);\n   printf(\"\\n\");\n}\n\n\n\n\nvoid desafio() {\n\n    //\n    printf(\"== Desafio Extra ==\\n\");\n\n    for (int x = 10; x <= 55; x++) {\n        if (x != 16 && x % 2 == 0 && x % 3 != 0)\n        printf(\"%d. \", x);\n    }\n    printf(\"\\n\");\n}\n\n\n// FIN. Gracias por ver :p \n\nint main(void) {\n    operadores();\n    condicionales();\n    iterativas();\n    desafio();\n\n    return 0;\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c/Aldroide.c",
    "content": "//Operadores y extructuras de control\n// Ejercicio crea ehemplos utilizando los tipos de operadores en tu lenguaje\n// Aritmetico, lógicos, comparativos, asignación, identidad, pertenencia, bits.\n\n#include <stdio.h>\n#include <conio.h>\n\nint main(){\n    // Ejemplos de operadores de asignación\n    printf(\"Operadores de asignación \\n\");\n    int var =20;\n    printf(\"Operador de asignación var = 20, %d \\n\",var);\n    var +=5;\n    printf(\"Suma 5 a la variable  var += 5, %d\\n\",var);\n    var -= 10;\n    printf(\"Resta 10 a la variable var -= 10, %d\\n\",var);\n    var *= 2;\n    printf(\"Multiplica 2 a la variable var *= 10, %d\\n\",var);\n    var /= 5;    \n    printf(\"Divide entre 5 a la variable var /= 5, %d\\n\",var);\n    var %= 2;\n    printf(\"Modulo entre 2 a la variable var = 2, %d\\n\",var);\n\n     // Ejemplos de operadores aritmeticos\n    printf(\"\\nOperadores aritmeticos\\n\");\n    var = 10;\n    printf(\"operador Signo negativo: %d.\\n\", -var);\n    printf(\"operador Incremento: %d.\\n\", ++var);\n    printf(\"operador Decremento: %d.\\n\", --var);\n    printf(\"operador Suma: 2 + 3 = %d.\\n\", 2 + 3);\n    printf(\"operador Resta: 3 - 2 = %d.\\n\", 3 - 2);\n    printf(\"operador Multiplicacion: 10 * 5 = %d.\\n\", 10 * 5);\n    printf(\"operador Division: 24 / 6 = %d.\\n\", 24 / 6);\n    printf(\"operador  Modulo: 30 % 11 = %d.\\n\", 30 % 11);\n\n    // Ejemplos de operadores relacionales\n    printf(\"\\nOperadores relacionales\\n\");\n    int a=10, b=20;\n    printf(\"resultado a<b: %d \\n\",a<b);\n    printf(\"resultado a>b: %d\\n\",a>b);\n    printf(\"resultado de igualdad a==b: %d\\n\",a==b);\n    printf(\"resultado de desigualdad a!=b: %d\\n\",a!=b);\n    printf(\"resultado de mayor o igual que a>=b: %d\\n\",a>=b);\n    printf(\"resultado de menor o igual que a<=b: %d\\n\",a<=b);\n\n    // Ejemplos de operadores lógicos\n    printf(\"\\nOperadores lógicos\\n\");\n    a = 13;\n\n    printf(\"AND a > 5 && a < 15: %d\\n\", a > 5 && a < 15);\n    printf(\"OR a > 5 || a < 15: %d\\n\", a > 5 || a < 15);\n    printf(\"NOT !(a > 5 && a < 15): %d\\n\", !(a > 5 && a < 15));\n\n// If and Else\n    printf(\"\\n Condicional if-else a>b \\n\");\n    if(a>b){\n        printf(\"a es mayor que b\\n\");\n    }\n    else{\n        printf(\"a es menor que b\\n\");\n    }\n\n// switch case\n    printf(\"\\n Switch Case \\n\");\n    int option = 2;\n    switch (option)\n    {\n    case 1:\n        printf(\"Realizar acción 1\\n\");\n        break;\n    case 2:\n        printf(\"Realizar acción 2\\n\");\n        break;    \n    default:\n        printf(\"No hay mas acciones\");\n        break;\n    }\n    \n\n    // for\n    printf(\"\\n estructura for \\n\");\n    for(int i=0; i<=10;i++)\n        printf(\"%d, \",i);\n\n    // do While\n    printf(\"\\n estructura do while \\n\");\n    do\n    {\n        printf(\"Ingresar 1 para salir\\n\");\n        scanf(\"%d\",&option);\n    } while (option!=1);\n    \n\n    // While\n    printf(\"\\n estructura while \\n\");\n    int c=1;\n    while(c<=10){\n        printf(\"%d \",c);\n        c++;\n    }\n\n\n// Dificultad Extra\n    printf(\"\\n Dificultad extra \\n\");\n    for (int i=1; i<=25; i++)\n        if(i!=16 && i%2 ==0 && i%3 != 0)\n            printf(\"%d \",i);\n    \n    getch();\n    return 0;\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c/Angel-Delg.c",
    "content": "#include <stdio.h>\n#include <time.h>\n#include <stdbool.h>\n#include <windows.h>\n#include <unistd.h>\n\nint main(){\n\n   // Tipos de datos primitivos\n   short Int16 = 10;\n   int Int32 = 100;\n   long Int64 = 1000;\n\n   // Podemos realizar operaciones matematicas usanod\n   printf(\"Suma: %ld\\n\", Int16 + Int32);\n   printf(\"Resta: %i\\n\", Int32 - Int16);\n   printf(\"Division: %i\\n\", Int64 / Int32);\n   printf(\"Multiplicacion: %ld\\n\", Int16 * Int32);\n   printf(\"Modulo: %i\", Int32 % Int16);\n\n   // Tambien tenemos los deplazamiento unitarios\n   printf(\"Desplazamiento derecha: %i\", 3 >> 2);\n   printf(\"Desplazamiento izquierda: %i\", 3 >> 2);\n\n   // Podemos realizar sentencias de control selectiva\n   if(Int16 < Int32){\n      printf(\"True\\n\");\n   }\n   else{\n      printf(\"False\\n\");\n   }\n   // Tambien podemos realizar multiples caso con Switch ; case\n   const int option = 1;\n\n   switch (option) {\n      case 1: {\n         printf(\"Realizar el registro de n usuarios\\n\");\n         // procesoo...\n         break;\n      }\n      case 2: {\n         printf(\"Buscar usuario mediante su ID\\n\");\n         // procesoo...\n         break;\n      }\n      default:{\n         printf(\"Este caso no existe!\\n\");\n         // procesoo...\n         break;\n      }\n   }\n   // cada caso es detenido con break o return\n\n   // Uso de for: puedes usar for para realizar tareas repetitivas, como imprimir números o bien\n   // Rellenar el registro de muchos usuarios\n   for(int i = 1; i <= 10; i++){\n      printf(\"%i, \", i);\n   }\n   printf(\"\\n\");\n   // Tambien tenemos do while\n   int response;\n\n   do{\n      // proceso..\n      printf(\"Ingrese 1 para salir del ciclo\\n\");\n      scanf(\"%i\", &response);\n   }while(response != 1);\n\n\n   // solucion del reto extra\n\n   for(int i = 10; i <= 55; i++){\n      if(i != 16 && i % 2 == 0 && i % 3 != 0){\n         printf(\"%i, \", i);\n      }\n   }\n\n   time_t tiempo_actual;\n   struct tm* info_tiempo;\n\n   printf(\"Para finalizar presentar un reloj en tiempo real\\n\");\n   system(\"pause\");\n   \n   while(true){\n      time(&tiempo_actual);\n      info_tiempo = localtime(&tiempo_actual);\n      printf(\"La hora actual es: %02d:%02d:%02d\\n\", info_tiempo->tm_hour, info_tiempo->tm_min, info_tiempo->tm_sec);\n      sleep(1);\n\n      system(\"cls\");\n   }\n   return 0;\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c/DjSurgeon.c",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n#include <stdio.h>\n#include <stdbool.h>\n\n  // Los principales operadores en c son los ariméticos, lógicos, comparación, de asignación, de bits y unarios.\n\nint main() {\n  \n  int a = 5;\n  int b = 9;\n\n  // Operadores aritméticos\n\n  // Suma\n  printf(\"Suma: %d\\n\", a + b);\n  //Resta\n  printf(\"Resta: %d\\n\", a - b);\n  //Multiplicación\n  printf(\"Multiplicación: %d\\n\", a * b);\n  //División\n  printf(\"División: %d\\n\", a / b);\n  //Módulo o Resto\n  printf(\"Módulo: %d\\n\", a % b);\n  //Incremento\n  a++;\n  printf(\"Incremento: %d\\n\", a);\n  //Decremento\n  b--;\n  printf(\"Decremento: %d\\n\", b);\n\n  // Operadores lógicos\n  bool c = true, d = false;\n\n  // AND\n  printf(\"AND lógico: %d (0 = false, 1 = true)\\n\", c && d);\n  // OR\n  printf(\"OR lógico: %d (0 = false, 1 = true)\\n\", c || d);\n  // NOT\n  printf(\"NOT lógico: %d (0 = false, 1 = true)\\n\", !d);\n  printf(\"NOT lógico: %d (0 = false, 1 = true)\\n\", !c);\n\n  // Operadores de comparación\n  int e = 5;\n  int f = 8;\n  \n  // Igual a\n  printf(\"Igual a: %d (0 false, 1 = true)\\n\", e == f);\n  // Diferente de\n  printf(\"Diferente de: %d (0 false, 1 = true)\\n\", e != f);\n  // Mayor que\n  printf(\"Mayor que: %d (0 false, 1 = true)\\n\", e > f);\n  // Menor que\n  printf(\"Menor que: %d (0 false, 1 = true)\\n\", e < f);\n  // Mayor o igual que\n  printf(\"Mayor o igual que: %d (0 false, 1 = true)\\n\", e >= f);\n  // Menor o igual que\n  printf(\"Menor o igual que: %d (0 false, 1 = true)\\n\", e <= f);\n\n  //Operadores de asignación\n  int g = 4;\n  int h = 8;\n\n  // Asignación =\n  // Asignación con suma\n  printf(\"Asignación con suma: %d\\n\", g += h);\n  // Asignación con resta\n  printf(\"Asignación con resta: %d\\n\", g -= h);\n  // Asignación con multiplicación\n  printf(\"Asignación con multiplicación: %d\\n\", g *= h);\n  // Asignación con división\n  printf(\"Asignación con división: %d\\n\", g /= h);\n  // Asignación con módulo\n  printf(\"Asignación con modulo: %d\\n\", g %= h);\n\n  /*\n  Existen otros operadores como los operadores de Bits, Unarios y Ternario.\n  - Los operadores de bits realizan operaciones directamente sobre los bits individuales de los operandos. Estos son útiles en situaciones que requieren manipulación a nivel de bits, como en programación de sistemas, controladores de hardware, y algoritmos de criptografía.\n  - Los operadores unarios son aquellos que operan sobre un solo operando. Estos operadores se utilizan comúnmente para operaciones aritméticas, lógicas y de punteros.\n  - El operador ternario es una forma concisa de realizar una operación condicional. Es el único operador en C que toma tres operandos. La sintaxis es condicion ? expresion_si_true : expresion_si_false.\n  */\n\n  // Estructuras de control\n  /* La principales estructuras de control en c serian:\n  - Estructuras condicionales: Permite ejecutar u omitir bloques de código según se cumplan o no ciertas condiciones. if-else y switch\n  - Estructuras de repetición o bucles: permiten ejecutar bloques de código repetidamente mientras se cumple una condición o hasta que se cumpla la condición. while, do-while y for\n  - Estructuras de salto: Controlan el flujo del programa saltando a diferentes partes del código. break, continue, goto, return\n  */\n\n  // If-Else\n  int num1 = 5;\n  if (num1 > 0) {\n    printf(\"El número %i es positivo\\n\", num1);\n  }\n  else {\n    printf(\"El número %i es negativo\\n\", num1);\n  }\n\n  // Switch\n  int num2 = 1;\n  switch (num2)\n  {\n  case 2:\n    printf(\"El número %i es 2.\\n\", num2);\n    break;\n  case 0:\n    printf(\"El número %i es 0.\\n\", num2);\n  default:\n  printf(\"El número %i no es ni 0 ni 2.\\n\", num2);\n  }\n\n  // For\n  int i;\n  for (i = 0; i < 5; i++) {\n    printf(\"El valor es %i por cada paso del bucle.\\n\", i);\n  }\n  // While\n  i = 0;\n  while (i < 6){\n    printf(\"El valor de i es: %i.\\n\", i);\n    i++;\n  }\n  //Do While\n  i = 3;\n  do{\n    printf(\"El valor de i es: %i.\\n\", i);\n    i++;\n  }\n  while(i < 6);\n\n  // Ejercicio Extra\n\n  printf(\"== Ejercicio Extra ==\\n\");\n\n  for (i = 10; i <= 55; i++) {\n    if (i % 2 == 0 && i !=16 && i % 3 != 0){\n    printf(\"Números: %i\\n\", i);\n    }\n  }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c/FullOvellas.c",
    "content": "#include <stdint.h>\n#include <stdio.h>\n\nconst uint8_t UPPER_BOUND = 55;\nconst uint8_t LOWER_BOUND = 10;\n\nint main() {\n    int32_t foo = 5;\n    int32_t bar = 15;\n    // Operadores aritméticos\n    foo + bar; // 20\n    foo - bar; // -15\n    foo * bar; // 75\n    bar / foo; // 3\n    foo % foo; // 0\n    ++foo;     // 6\n\n    // Operadores a nivel de bit\n    printf(\"%i\\n\", 2 & 1);\n    printf(\"%i\\n\", 2 << 1);\n    printf(\"%i\\n\", 2 >> 1);\n    printf(\"%i\\n\", 2 | 1);\n\n    // Operadores de asignación\n    int32_t baz = 0;\n    baz += 6; // 6\n    baz -= 2; // 4\n    baz /= 2; // 2\n    baz *= 4; // 8\n    baz %= 2; // 0\n\n    // Operadores de comparación\n    printf(\"%i\\n\", 1 > 2);  // 0\n    printf(\"%i\\n\", 1 < 2);  // 1\n    printf(\"%i\\n\", 1 >= 2); // 0\n    printf(\"%i\\n\", 1 <= 2);  // 1\n    printf(\"%i\\n\", 1 == 2);  // 0\n\n    // Operadores lógicos\n    1 && 0; // 0\n    1 || 0; // 1\n\n    // Estructuras de control\n    // if\n    if (5 == 2 + 2) {\n        puts(\"Tenemos un problema\");\n    }\n\n    // if-else\n    if (5 == 2 + 2) {\n        puts(\"Tenemos un problema\");\n    } else {\n        puts(\"Las mates siguen funcionando\");\n    }\n\n    // if-else if\n    if (0) {\n        puts(\"Cero\");\n    } else if (0 == 0) {\n        puts(\"Cero ;)\");\n    } else {\n        puts(\"No cero :(\");\n    }\n\n    // for\n    int32_t running_sum = 0;\n    for (int32_t i = 0; i < 10; i++) {\n        running_sum += i;\n    }\n    printf(\"Resultado de la suma: %i\\n\", running_sum);\n\n    // while\n    int32_t countdown = 10;\n    while (countdown > 0) {\n        printf(\"%i!\\n\", countdown);\n        countdown--;\n    }\n\n    // do while\n    int32_t c = 0;\n    do {\n        printf(\"%i\\n\", c);\n        c--;\n    } while (c > 0);\n\n    // continue\n    for (int32_t i = 0; i < 5; i++) {\n        if (i == 3) {\n            continue;\n        }\n        printf(\"%i\\n\", i);\n    }\n\n    // break\n    for (int32_t i = 0; i < 5; i++) {\n        if (i == 3) {\n            break;\n        }\n        printf(\"%i\\n\", i);\n    }\n\n    // goto\n    for (int32_t i = 0; i < 5; i++) {\n        if (i == 3) {\n            goto nos_fuimos;\n        }\n        printf(\"%i\\n\", i);\n    }\n\nnos_volvimos: {}\n    // switch\n    char command = 'q';\n    switch(command) {\n        case 'y':\n            puts(\"Sí\");\n            break;\n        case 'n':\n            puts(\"No\");\n            break;\n        case 'w':\n        case 'a':\n        case 's':\n        case 'd':\n            puts(\"Movimiento\");\n            break;\n        case 'q':\n            puts(\"Saliendo\");\n            break;\n        default:\n            printf(\"Comando '%c' no reconocido\\n\", command);\n    }\n\n    // Opcional: imprimir por consola los números pares entre 10 y 55\n    // excluyendo el 16 y los múltiplos de 3\n    for (uint8_t i = LOWER_BOUND; i <= UPPER_BOUND; i++) {\n        if (i % 2 || (i % 3) == 0 || i == 16) {\n            continue;\n        }\n\n        printf(\"%i\\n\", i);\n    }\n    return 0;\n\nnos_fuimos:\n    puts(\"Efectivamente nos fuimos\");\n    goto nos_volvimos;\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c/Gallitofast.c",
    "content": "#include <stdio.h>\n//estoy aprendiendo pero me inspire en el codigo de 04khaos\n//para organizar el codigo en difetentes funciones y llamarlas en el main.\nvoid operadores();\nvoid condicionales();\nvoid iterativas();\nvoid desafio();\n\nvoid operadores(){\n    // Operadores Aritméticos\n    printf(\"== Operadores Aritméticos ==\\n\");\n    int a = 5, b = 10, c = 5; // Variables globales de la función\n    {\n        printf(\"Suma: %d + %d = %d\\n\", a, b, a + b);\n        printf(\"Resta: %d - %d = %d\\n\", a, b, a - b);\n        printf(\"Multiplicación: %d * %d = %d\\n\", a, b, a * b);\n        printf(\"División: %d / %d = %d\\n\", a, b, a / b); // División por 0 da error\n        printf(\"Módulo: %d %% %d = %d\\n\\n\", a, b, a % b);\n\n        printf(\"Signo negativo: %d → %d\\n\", c, -c);\n        c++; // Incremento\n        printf(\"Incremento: %d → %d\\n\", c - 1, c); // Mostrar el valor antes y después del incremento\n        c--; // Decremento\n        printf(\"Decremento: %d → %d\\n\\n\", c + 1, c); // Mostrar el valor antes y después del decremento\n    }\n    \n    //Operadores de Comparación\n    printf(\"== Operadores de Comparación ==\\n    0 (false) || 1 (true)\\n\");\n    {\n        printf(\"Igualdad: (%d == %d) = %d\\n\", a, b, a == b);\n        printf(\"Diferencia: (%d != %d) = %d\\n\", a, b, a != b);\n        printf(\"Mayor que: (%d > %d) = %d\\n\", a, b, a > b );\n        printf(\"Menor que: (%d < %d) = %d\\n\", a, b, a < b);\n        printf(\"Mayor o igual: (%d >= %d) = %d\\n\", a, b, a >= b);\n        printf(\"Menor o igual: (%d <= %d) = %d\\n\\n\", a, b, a <= b);\n\n        \n}\n    // Operadores Lógicos\n    printf(\"== Operadores Lógicos ==\\n   0 (false) || 1 (true)\\n\");\n    {\n        // AND (&&) - Solo es true si ambas son verdaderas\n        printf(\"¿Ambas son verdaderas? (%d == %d && %d > %d) = %d\\n\", a, c, b, c, a == c && b > c);\n        // OR (||) - Es true si al menos una es verdadera\n        printf(\"¿Alguna es verdadera? (%d == %d || %d < %d) = %d\\n\", b, c, b, a, b == c || b < a);\n        // NOT (!) - Invierte el valor de una condición\n        printf(\"Inverso (a == c); !(%d == %d) = %d\\n\\n\", a, c, !(a == c));\n    }\n    \n    // Operadores de Asignación\n    printf(\"== Operadores de Asignación ==\\n\");\n    {\n        int x = 2; // Variable local\n\n        x = 2;  // Valor inicial de x\n        printf(\"(x = 2) = %d\\n\", x);\n        x += 7; // Equivalente a: x = x + 7\"\n        printf(\"(x += 7) = %d\\n\", x);\n        x -= 3; // Equivalente a: x = x - 3\n        printf(\"(x -= 3) = %d\\n\", x);\n        x *= 5; // Equivalente a: x = x * 5\n        printf(\"(x *= 5) = %d\\n\", x);\n        x /= 10;\n        printf(\"(x /= 10) = %d\\n\", x);\n        x %= 2;\n        printf(\"(x %%= 2) = %d\\n\\n\", x);\n    }\n    // Operadores de Bit\n    printf(\"== Operadores de Bits ==\\n\");\n    {\n        int x = 3; // Variable local\n        // Operaciones de bits con AND, OR, XOR, etc..\n        printf(\"(a & x) = %d\\n\", a & x);\n        printf(\"(a | x) = %d\\n\", a | x);\n        printf(\"(a ^ x) = %d\\n\", a ^ x);\n        printf(\"(~a) = %d\\n\", ~a);\n        printf(\"(x << 1) = %d\\n\", x << 1);\n        printf(\"(x >> 1) = %d\\n\\n\", x >> 1);\n    }\n}\nvoid condicionales() {\n    //estructuras de control\n    //Condicionales\n    printf(\"== Condicionales (if, else) ==\\n\");\n    int age = 20;\n\n    if (age >= 18)\n    {\n     printf(\"Tienes %d, eres mayor de edad\\n\", age);\n    }\n    else\n    {\n     printf(\"Tienes %d, eres menor de edad\\n\", age);\n    }\n\n    if (age >= 1 && age <= 18) { // Entre 1 y 17 años\n     printf(\"¿Cuál es tu videojuego favorito?\\n\\n\");\n    }\n    else if (age < 26) { // Desde los 18 hasta los 25 años\n     printf(\"¿Cuál es tu lenguaje de programación favorito?\\n\\n\");\n    }\n    else { // Desde los 25 años en adelante..\n     printf(\"¿Cuántos años de experiencia tienes programando?\\n\\n\");\n    }\n\n\n        // if-else + switch\n    \n        printf(\"== Condicionales (if-else + switch) ==\\n> Sistema de roles\\n\");\n        int rol = 3; // Cambia el valor manualmente para probar distintos casos\n    \n        if (rol >= 1 && rol <= 3)\n        {\n         printf(\"> Tu rol asignado: %d\\n\", rol);\n        }\n        else\n        {\n         printf(\"> ERROR\\n\");\n        }\n    \n        /* \"switch\" Útil cuando se evalúa una variable contra valores específicos,\n            como enteros o caracteres. Es más legible cuando hay muchas opciones */\n    \n        switch (rol) {\n         case 1:\n              printf(\"¡Bienvenido jugador! Puedes explorar y disfrutar del mundo, ¿quieres ver el tutorial?\\n\\n\");\n              break;\n         case 2:\n              printf(\"Saludos, Moderador. Puedes administrar ciertas funciones y mantener el orden\\n\\n\");\n              break;\n         case 3:\n              printf(\"Guild Master. Tienes control total sobre este mundo\\n\\n\");\n              break;\n         default:\n              printf(\"Error: Rol no reconocido. Verifica el valor asignado\\n\\n\");\n        }\n    }\n    \n    void iterativas() {\n\n        printf(\"== Estructuras Iterativas ==\\n\");\n\n        // Bucle while - Se ejecuta mientras la condición sea verdadera\n        printf(\"> Bucle while:\\n\");\n        int i = 1;\n\n        while (i <= 5) {\n             printf(\"Iteración %d\\n\", i);\n             i++; // Incrementamos i hasta 5 para evitar un bucle infinito\n        }\n        printf(\"\\n\");\n\n        // Bucle for: Utiliza una variable de control con inicio, condición y actualización\n        printf(\"> Bucle for:\\n\");\n        for (int f = 1; f <= 3; f++) {\n             printf(\"Iteración %d\\n\", f);\n        }\n        printf(\"\\n\");\n\n        // Bucle do-while: Garantiza al menos una ejecución antes de comprobar la condición\n        printf(\"> Bucle do-while:\\n\");\n        int d = 10; // Se ejecuta sin importar si la condición es falsa o verdadera al principio\n\n        do {\n             printf(\"Iteración %d\\n\", d);\n             d++;\n        } while (d <= 5);\n        printf(\"\\n\");\n    }\n    void desafio() {\n\n        //\n        printf(\"== Desafio Extra ==\\n\");\n    \n        for (int x = 10; x <= 55; x++) {\n            if (x != 16 && x % 2 == 0 && x % 3 != 0)\n            printf(\"%d. \", x);\n        }\n        printf(\"\\n\");\n    }\n    \n    \n    // FIN. Gracias por ver :p \n    \n    int main(void) {\n        operadores();\n        condicionales();\n        iterativas();\n        desafio();\n    \n        return 0;\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c/JustOrlo.c",
    "content": "#include <stdio.h>\r\n\r\nvoid Operadores();\r\nvoid Estructuras_Condicionales();\r\nvoid Estructuras_Bucles();\r\nvoid Desafio();\r\n\r\nint main(){ \r\n    \r\n    Operadores();\r\n    Estructuras_Condicionales();\r\n    Estructuras_Bucles();\r\n    Desafio();\r\n}\r\n\r\nvoid Operadores(){\r\n     \r\n    //Declaracion de variables globales dela funcion\r\n\r\n     int valor_1 = 5;\r\n     int valor_2 = 8;\r\n     int valor_3 = 3;\r\n\r\n\r\n    printf(\"---->Operadores aritmeticos<----\\n\\n\");\r\n\r\n    /*Los Operadores Aritmeticos en C son:\r\n        Suma            (+)\r\n        Resta           (-)\r\n        Multiplicacion  (*)\r\n        Division        (/) \r\n        Modulo          (%)\r\n        Incremento      (++)\r\n        Decremento      (--)\r\n    */\r\n\r\n    printf(\"El resultado de sumar %d + %d es: %d\\n\",valor_1, valor_3, valor_1 + valor_3);\r\n    printf(\"El resultado de restar %d - %d es : %d\\n\",valor_2, valor_1, valor_2 - valor_1);\r\n    printf(\"El resultad de multiplicar %d * %d es : %d\\n\", valor_1, valor_1, valor_1 * valor_1);\r\n    printf(\"El resultadod de dividir %d / %d es  : %d\\n\", valor_2, valor_3, valor_2 / valor_3);\r\n    printf(\"El Modulo o division exacta entre %d y %d es : %d\\n\", valor_2, valor_3, valor_2 % valor_3);\r\n    valor_3++;\r\n    printf(\"El incremento de %d es : %d\\n\", valor_3 - 1, valor_3);\r\n    valor_1--;\r\n\r\n    printf(\"El decremento de %d es: %d\\n\\n\\n\", valor_1 + 1, valor_1);   \r\n\r\n    printf(\"---->Operadores de comparacion<---- 0(false)  |  1(true)\\n\\n\");\r\n    /*Los Operadores de Comparacion son:\r\n        Mayor que:      (>)\r\n        Menor que:      (<)\r\n        Igual a:        (==)\r\n        Mayor o igaual  (>=)\r\n        Menor o Igual   (<=)\r\n        Diferente de    (!=)   \r\n    */\r\n\r\n    printf(\"¿Es %d mayor que %d?, %d\\n\", valor_1, valor_2, valor_1 > valor_2);\r\n    printf(\"¿Es %d meonr que %d?, %d\\n\", valor_3, valor_2, valor_3 < valor_2);\r\n    printf(\"¿Es %d igual a %d?, %d\\n\", valor_1, valor_1, valor_1 == valor_3);\r\n    printf(\"¿Es %d mayor o igual que %d?, %d\\n\", valor_2, valor_2, valor_2 >= valor_1);\r\n    printf(\"¿Es %d menor o igual que %d?, %d\\n\", valor_1, valor_3, valor_1 <= valor_3);\r\n    printf(\"¿Es %d diferente de %d?, %d\\n\\n\\n\", valor_1, valor_2, valor_1 != valor_2);\r\n    \r\n    printf(\"---->Operadores Logicos<----  0(false)  |  1(true)\\n\\n\");\r\n    /*Los operadores Logicos son:\r\n        NOT     (!)\r\n        AND     (&&)\r\n        OR      (||)\r\n    */\r\n   printf(\"¿Se cumplen las siguientes dos Condiciones?, %d > %d y %d = %d, La respuesta es: %d\\n\", valor_2, valor_1, valor_2, valor_1,(valor_2 > valor_1) && (valor_3 == valor_1));\r\n   printf(\"¿Se cumplen una de las siguientes Condiciones?, %d > %d y %d = %d, La respuesta es: %d\\n\", valor_2, valor_1, valor_2, valor_1, (valor_2 > valor_1) && (valor_3 == valor_1));\r\n   printf(\"Inverso de la condicion %d = %d,  %d\\n\\n\\n\", valor_1, valor_1, !(valor_1 == valor_2));\r\n\r\n\r\n   printf(\"---->Operadores de Asignacion<----\\n\\n\");\r\n\r\n        valor_1 = 2;  // Valor inicial de la variable\r\n        printf(\"(valor_1 = 2) = %d\\n\", valor_1);\r\n        valor_1 += 5; // Equivalente a: valor_1 = valor_1 + 5\"\r\n        printf(\"(valor_1 += 5) = %d\\n\", valor_1);\r\n        valor_1 -= 3; // Equivalente a: valor_1 = valor_1 - 3\r\n        printf(\"(valor_1 -= 3) = %d\\n\", valor_1);\r\n        valor_1 *= 2; // Equivalente a: valor_1 = valor_1 * 2\r\n        printf(\"(valor_1 *= 2) = %d\\n\", valor_1);\r\n        valor_1 /= 10; // Equivalente a: valor_1 = valor_1 / 10\r\n        printf(\"(valor_1 /= 10) = %d\\n\", valor_1);\r\n        valor_1 %= 3; //Equivalente a: valor_1 = valor_1 % 3\r\n        printf(\"(valor_1 %%= 3) = %d\\n\\n\\n\", valor_1);\r\n\r\n\r\n        printf(\"---->Operadores de Bit<----\\n\\n\");\r\n\r\n        printf(\"(valor_1 & valor_2) = %d\\n\", valor_1 & valor_2);\r\n        printf(\"(valor_1 | valor_2) = %d\\n\", valor_1 | valor_2);\r\n        printf(\"(valor_1 ^ valor_2) = %d\\n\", valor_1 ^ valor_2);\r\n        printf(\"(~valor_1) = %d\\n\", ~valor_1);\r\n        printf(\"(valor_1 << 1) = %d\\n\", valor_2 << 1);\r\n        printf(\"(valor_1 >> 1) = %d\\n\\n\", valor_2 >> 1);\r\n}\r\n\r\nvoid Estructuras_Condicionales(){\r\n\r\n    /*Estructura If - Else*/\r\n\r\n    printf(\"if (/*Condicion que debe de Cumplirse*/){\\n\");\r\n    printf(\"\\t /*Sentencia que se debe de Ejecutar de Cumplirse na Condicion*/\\n\");\r\n    printf(\"}\\n\\n\");\r\n    printf(\"else {\\n\");\r\n    printf(\"\\t /*Sentencia que debe de ejecutarse en caso de no ocurrir la condicio expuesya en el if*/\\n\");\r\n    printf(\"}\\n\\n\\n\\n\");\r\n    \r\n    /*Exponiendo Ejemplos*/\r\n    printf(\"---->Ejemplo de Sentencia If<----\\n\\n\");\r\n    printf(\"if (16 > 10) {\\n\");\r\n    printf(\"\\t /*Se cumple que 16 > 10*/;\\n \");\r\n    printf(\"}\\n\\n\");\r\n\r\n    if (16 > 10){\r\n        printf(\"Se cumple que 16 > 10\\n\\n\");\r\n    }\r\n\r\n    printf(\"---->Ejemplo de Sentencia If<----\\n\\n\");\r\n    printf(\"if (16 < 10) {\\n\");\r\n    printf(\"\\t /*Se cumple que 16 > 10*/;\\n \");\r\n    printf(\"}\\n\");\r\n    printf(\"else {\\n\");\r\n    printf(\"\\t /*No se cumple que 16 > 10*/\\n\");\r\n    printf(\"}\\n\\n\");\r\n\r\n    if (16 < 10)\r\n    {\r\n        printf(\"Se cumple la condicion de 16 < 10\");\r\n    }\r\n    else \r\n    {\r\n        printf(\"No se cumple la condicion de 16 < 10\\n\\n\\n\\n\");\r\n    }\r\n    \r\n    /*Estructura Switch*/\r\n\r\n    printf(\"switch (variable)\\n\");\r\n    printf(\"\\t case Contenido1_Variable:\\n\");\r\n    printf(\"\\t\\t Sentencia a ejecutar;\\n\");\r\n    printf(\"\\t\\t break;\\n\");\r\n    printf(\"\\t case Contenido2_Variable\\n:\");\r\n    printf(\"\\t\\t Sentencia a ejecutar;\\n\");\r\n    printf(\"\\t\\t break;\\n\");\r\n    printf(\"\\t etc...\\n\");\r\n    printf(\"\\t default:\\n\");\r\n    printf(\"\\t\\t Sentencia a ejecutar;\\n\\n\\n\\n\");\r\n\r\n    printf(\"---->Ejemplo de Sentencia Switch<----\\n\\n\");\r\n    \r\n    printf(\"int a = 4\\n\\n\");\r\n    printf(\"switch (a)\\n\");\r\n    printf(\"\\t case 1:\\n\");\r\n    printf(\"\\t\\t /*El valor de a es 1*/;\\n\");\r\n    printf(\"\\t\\t break;\\n\");\r\n    printf(\"\\t case 2:\\n\");\r\n    printf(\"\\t\\t /*El valor de a es 2*/;\\n\");\r\n    printf(\"\\t\\t break;\\n\");\r\n    printf(\"\\t default:\\n\");\r\n    printf(\"\\t\\t /*El valor de a no es ninguno de los anteriores*/;\\n\\n\\n\\n\");\r\n     \r\n    int a = 4;\r\n   switch (a)\r\n   {\r\n   case 1:\r\n    printf(\"El valor de a es 1\\n\");\r\n    break;\r\n    case 2:\r\n    printf(\"El valor de a es 2\\n\");\r\n    break;\r\n   \r\n   default:\r\n   printf(\" El valor de a no es ni 1 ni 2\\n\\n\\n\");\r\n    break;\r\n   }\r\n}\r\n\r\nvoid Estructuras_Bucles(){\r\n\r\n    /*Estructura While*/\r\n\r\n    printf(\"---->Estructura While<----\\n\\n\");\r\n    printf(\"while(/*Condicion a Comprobar*/){\\n\");\r\n    printf(\"\\t /*Sentencia a ejecutar mientras se siga cumpliendo la condicion anterior*/\\n\");\r\n    printf(\"}\\n\\n\");\r\n    \r\n    /*Ejemplo de Estructura While*/\r\n\r\n    printf(\"---->Ejemplo de Estructura While<----\\n\\n\");\r\n    printf(\"\\t int a = 5;\\n\\n\");\r\n    printf(\"while(a > 0){\\n\");\r\n    printf(\"\\t /*Escribir a*/;\\n\\t a--;\\n\");\r\n    printf(\"}\\n\\n\");\r\n\r\n    int a = 5;\r\n\r\n    while (a > 0)\r\n    {\r\n        printf(\"El Valor de a es: %d\\n\", a);\r\n        a--;\r\n    }\r\n    \r\n     /*Estructura Do while*/\r\n\r\n     printf(\"\\n\\n\\n---->Estructura Do While<----\\n\\n\");\r\n     printf(\"Do {\\n\");\r\n     printf(\"\\t /*Sentencia a Ejecutar*/;\\n\");\r\n     printf(\"}\\n\");\r\n     printf(\"While (/*Condicion a probar para seguir el Bucle*/)\\n\\n\");\r\n     printf(\"NOTA: En este Caso a diferencia del While, primero eecuta la orden y luego comprueba la condicion\\n\\n\\n\");\r\n     printf(\"---->Ejemplo de Do While<----\\n\\n\");\r\n\r\n     /*Ejemplo de Do While*/\r\n\r\n     printf(\"\\t a = 5;\\n\\n\");\r\n     printf(\"Do {\\n\");\r\n     printf(\"\\t /*Escriir el valor de a*/;\\n\");\r\n     printf(\"\\t a--;\\n\");\r\n     printf(\"}\\n\");\r\n     printf(\"While (a > 0)\\n\\n\");\r\n    \r\n     a = 5;\r\n     do\r\n     {\r\n        printf(\"El valor de a es: %d\\n\", a);\r\n        a--;\r\n     } while (a > 0);\r\n     \r\n     /*Estructura For*/\r\n     printf(\"---->Estructura For<----\\n\\n\");\r\n     printf(\"for (/*Inicio de la iteracion*/;/*Final de la ieracion*/;/*Saltos de la Iteracion*/){\\n\");\r\n     printf(\"\\t /*Sentencias a Ejecutar durante la iteracion*/\\n\");\r\n     printf(\"}\\n\\n\\n\");\r\n     printf(\"---->Ejemplo de Iteracion For<----\\n\\n\");\r\n     printf(\"for( int i = 0; i < 10; i++){\\n\");\r\n     printf(\"\\t /*Escribir valor de i*/;\\n\");\r\n     printf(\"}\\n\\n\");\r\n     \r\n     for (int i = 0; i < 10; i++)\r\n     {\r\n        printf(\"El valor de i es: %d\\n\", i);\r\n     }\r\n     \r\n}\r\n\r\nvoid Desafio(){\r\n        printf(\"\\n\\n\\n---->Desafio Extra<----\\n\\n\");\r\n        printf(\" Digite todos los numeros Comprendido entre 10 y 55\\n\");\r\n        printf(\" Diferentes de 16, que no san pares ni divisibles por 3\\n\");\r\n\r\n        for (int i = 10; i <= 55; i++)\r\n        {\r\n            if ((i != 16) && (i % 2 != 0) && ( i % 3 != 0))\r\n            {\r\n                printf(\"\\t%d\\n\", i);\r\n            }\r\n            \r\n        }\r\n        \r\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c/N0HagoNada.c",
    "content": "#include <stdio.h>\n\nint main()\n{\n    // Operadores aritméticos\n    int suma = 5 + 3;\n    int resta = 5 - 3;\n    int multiplicacion = 5 * 3;\n    double division = 5 / 3.0;\n    int modulo = 5 % 3;\n\n    printf(\"Suma: %d\\n\", suma);\n    printf(\"Resta: %d\\n\", resta);\n    printf(\"Multiplicacion: %d\\n\", multiplicacion);\n    printf(\"Division: %.2f\\n\", division);\n    printf(\"Modulo: %d\\n\", modulo);\n\n    // Operadores lógicos y de comparación\n    int a = 5, b = 3;\n    int mayor = a > b;\n    int menor_o_igual = a <= b;\n    int igual = a == b;\n    int diferente = a != b;\n    int y_logico = (a > b) && (a != 0);\n    int o_logico = (a < b) || (b < 5);\n\n    printf(\"Mayor: %d\\n\", mayor);\n    printf(\"Menor o igual: %d\\n\", menor_o_igual);\n    printf(\"Igual: %d\\n\", igual);\n    printf(\"Diferente: %d\\n\", diferente);\n    printf(\"Y lógico: %d\\n\", y_logico);\n    printf(\"O lógico: %d\\n\", o_logico);\n\n    // Operadores de bits\n    unsigned int and_bits = a & b;\n    unsigned int or_bits = a | b;\n    unsigned int xor_bits = a ^ b;\n    unsigned int not_bits = ~a;\n    unsigned int desplazamiento_izquierda = a << 1;\n    unsigned int desplazamiento_derecha = a >> 1;\n\n    printf(\"AND bits: %u\\n\", and_bits);\n    printf(\"OR bits: %u\\n\", or_bits);\n    printf(\"XOR bits: %u\\n\", xor_bits);\n    printf(\"NOT bits: %u\\n\", not_bits);\n    printf(\"Desplazamiento izquierda: %u\\n\", desplazamiento_izquierda);\n    printf(\"Desplazamiento derecha: %u\\n\", desplazamiento_derecha);\n\n    // Estructuras de control\n    // Condicional: if-else\n    if (a > b)\n    {\n        printf(\"a es mayor que b\\n\");\n    }\n    else\n    {\n        printf(\"a no es mayor que b\\n\");\n    }\n\n    // Iterativa: while\n    int contador = 3;\n    while (contador > 0)\n    {\n        printf(\"Contador: %d\\n\", contador);\n        contador--;\n    }\n\n    // Iterativa: for\n    for (int i = 0; i < 3; i++)\n    {\n        printf(\"For ciclo: %d\\n\", i);\n    }\n\n    // pcional\n    for (int i = 10; i <= 55; i++)\n    {\n        if (i % 2 == 0 && i != 16 && i % 3 != 0)\n        {\n            printf(\"%d\\n\", i);\n        }\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c/SoMaxB.c",
    "content": "#include <stdio.h>\n#include <stdbool.h>\n\nint\tmain(void) {\n\t\t// Operadores Aritméticos\n\t\tint suma = 1 + 1;\n\t\tint resta = 2 - 1;\n\t\tint multiplicacion = 3 * 2;\n\t\tint division = 4 / 2;\n\t\tint modulo = 5 % 2;\n\n\t\tprintf(\"Suma = %d\\n\", suma);\n\t\tprintf(\"Resta = %d\\n\", resta);\n\t\tprintf(\"Multiplicación = %d\\n\", multiplicacion);\n\t\tprintf(\"Division = %d\\n\", division);\n\t\tprintf(\"Modulo = %d\\n\\n\", modulo);\n\n\t\t// Operadores lógicos\n\t\tbool and = 3 && 4;\n\t\tbool or = 3 || 4;\n\t\tbool not = !(3 && 4);\n\n\t\tprintf(\"And = %d\\n\", and);\n\t\tprintf(\"Or = %d\\n\", or);\n\t\tprintf(\"Not = %d\\n\\n\", not);\n\n\t\t// Operadores bit a bit\n\t\tint a = 6;  // 6 en binario es 0000 0110\n\t\tint b = 3;  // 3 en binario es 0000 0011\n    \n\t\tint andBB = a & b;  // 0000 0110 & 0000 0011 = 0000 0010 (2)\n\t\tint orBB = a | b;   // 0000 0110 | 0000 0011 = 0000 0111 (7)\n\t\tint compBB = ~a;    // ~0000 0110 = 1111 1001 (-7 en complemento a 2)\n\t\tint xorBB = a ^ b;  // 0000 0110 ^ 0000 0011 = 0000 0101 (5)\n    \n\t\tprintf(\"And bit a bit: %d\\n\", andBB);    // Imprime 2\n\t\tprintf(\"Or bit a bit: %d\\n\", orBB);      // Imprime 7\n\t\tprintf(\"Complemento a uno: %d\\n\", compBB); // Imprime -7\n\t\tprintf(\"O-exclusiva bit a bit: %d\\n\\n\", xorBB); // Imprime 5\n\n\t\t// Operadores de asignación\n\t\tint uno = 1;\n\t\tprintf(\"Igual = %d\\n\", uno);\n\t\tuno += 1;\n\t\tprintf(\"Mas igual = %d\\n\", uno);\n\t\tuno -= 1;\n\t\tprintf(\"Menos igual = %d\\n\", uno);\n\t\tuno *= 4;\n\t\tprintf(\"Por igual = %d\\n\", uno);\n\t\tuno /= 2;\n\t\tprintf(\"Dividido igual = %d\\n\", uno);\n\t\tuno &= 1;\n\t\tprintf(\"Y igual = %d\\n\", uno);\n\t\tuno++;\n\t\tprintf(\"Incremento = %d\\n\", uno);\n\t\tuno--;\n\t\tprintf(\"Decremento = %d\\n\\n\", uno);\n\n\t\t// Operadores relacionales\n\t\tint mayor = 4 > 3;\n\t\tint menor = 3 < 4;\n\t\tint mayor_o_igual = 4 >= 2;\n\t\tint menor_o_igual = 3 <= 4;\n\t\tint igual = 6 == 6;\n\t\tint diferente = 8 != 5;\n\n\t\tprintf(\"Mayor = %d\\n\", mayor);\n\t\tprintf(\"Menor = %d\\n\", menor);\n\t\tprintf(\"Mayor o igual = %d\\n\", mayor_o_igual);\n\t\tprintf(\"Menor o igual = %d\\n\", menor_o_igual);\n\t\tprintf(\"Igual = %d\\n\", igual);\n\t\tprintf(\"Diferente = %d\\n\\n\", diferente);\n\n\t\t// Operador condicional o ternario\n\t\tint x = 4;\n\n\t\tprintf(\"x >= 5 ? 1 : 0 = %d\\n\\n\", x >= 5 ? 1 : 0);\n\n\t\t//Bonus\n\t\tint i = 10;\n    \n\t\twhile (i < 55) {\n\t\t\t\tif (i % 2 == 0 && i != 16 && i % 3 != 0)\n\t\t\t\t\tprintf(\"%d\\n\\n\", i);\n\t\t\t\ti++;\n\t\t\t\t}\n\t\treturn 0;\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c/SrVariable.c",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n#include <stdio.h>\n\n/* NOTA:\n * C no tiene operadores de identidad ni pertenencia ya que no existen los objetos,\n * tampoco tiene excepciones.\n */\nint    main(void)\n{\n    /* === 1 === */\n    // Operadores aritméticos\n    int n1a = 27;\n    int n2a = 6;\n    printf(\"\\n\\tOperadores aritméticos\\n\");\n    printf(\"Suma: %d + %d = %d\\n\", n1a, n2a, n1a + n2a); // Operador suma '+'\n    printf(\"Resta: %d - %d = %d\\n\", n1a, n2a, n1a - n2a); // Operador resta '-'\n    printf(\"Multiplicación: %d * %d = %d\\n\", n1a, n2a, n1a * n2a); // Operador multiplicación '*'\n    printf(\"División: %d / %d = %d\\n\", n1a, n2a, n1a / n2a); // Operador división '/'\n    printf(\"Resto: %d %% %d = %d\\n\", n1a, n2a, n1a % n2a); // Operador resto '%'\n    printf(\"Post-incremento: %d++\\n\", n1a++); // Operador post-incremento, primero utiliza el valor y luego suma 1 al valor.\n    printf(\"Pre-incremento: ++%d\\n\", ++n2a); // Operador pre-incremento, primero suma 1 al valor y luego utiliza el valor.\n    printf(\"Post-decremento: %d--\\n\", n1a--); // Operador post-decremento, primero utiliza el valor y luego resta 1 al valor.\n    printf(\"Pre-decremento: --%d\\n\", --n2a); // Operador pre-decremento, primero resta 1 al valor y luego utiliza el valor.\n\n    // Operadores lógico\n    int n1l = 1;\n    int n2l = 0;\n    printf(\"\\n\\tOperadores lógicos\\n\");\n    printf(\"AND (lógico): %d && %d = %d\\n\", n1l, n2l, n1l && n2l); // Operador AND lógico\n    printf(\"OR (lógico): %d || %d = %d\\n\", n1l, n2l, n1l || n2l); // Operador OR lógico\n    printf(\"NOT (lógico): !%d = %d\\n\", n1l, !n1l); // Operador NOT lógico\n\n    // Operadores de comparación\n    int n1c = 100;\n    int n2c = 105;\n    printf(\"\\n\\tOperadores de comparación\\n\");\n    printf(\"Menor que: %d < %d = %d\\n\", n1c, n2c, n1c < n2c); // Operador menor que '<'\n    printf(\"Menor o igual que: %d <= %d = %d\\n\", n1c, n2c, n1c <= n2c); // Operador meno o igual que '<='\n    printf(\"Mayor que: %d > %d = %d\\n\", n1c, n2c, n1c > n2c); // Operador mayor que '>'\n    printf(\"Mayor o igual que: %d >= %d = %d\\n\", n1c, n2c, n1c >= n2c); // Operador mayor o igual que '>='\n    printf(\"Igual que: %d == %d = %d\\n\", n1c, n2c, n1c == n2c); // Operador igual que '=='\n    printf(\"Distinto que: %d != %d = %d\\n\", n1c, n2c, n1c != n2c); // Operador distinto que '!='\n\n    // Operadores de asignación\n    int x = 0;\n    printf(\"\\n\\tOperador de asignación\\n\");\n    printf(\"Simple: x = 2024, %d\\n\", x = 2024); // Operador de asignación simple '='\n    printf(\"Suma: x += 1, %d\\n\", x += 1); // Operador de asignación suma '+='\n    printf(\"Resta: x -= 1, %d\\n\", x -= 1); // Operador de asignación resta '-='\n    printf(\"Multiplicación: x *= 1, %d\\n\", x *= 1); // Operador de asignación multiplicación '*='\n    printf(\"División: x /= 1, %d\\n\", x /= 1); // Operador de asignación división '/='\n    printf(\"Resto: x %%= 3, %d\\n\", x %= 3); // Operador de asignación resto '%='\n    printf(\"AND (binario): x &= 15, %d\\n\", x &= 15); // Operador de asignación AND binario '&='\n    printf(\"OR (binario): x |= 1, %d\\n\", x |= 1); // Operador de asignación OR binario '|='\n    printf(\"XOR: x ^= 4, %d\\n\", x ^= 4); // Operador de asignación XOR '^='\n    printf(\"Desplazamiento a la derecha: x >>= 1, %d\\n\", x >>= 1); // Operador de asignación desplazamiento a la derecha '>>='\n    printf(\"Desplazamiento a la izquierda: x <<= 2, %d\\n\", x <<= 2); // Operador de asignación desplazamiento a la izquierda '<<='\n\n    // Operación de bits\n    int\tn1b = 0b1010; // 10 en binario (1 * 2³ + 1 * 2¹ = 8 + 2 = 10)\n    int\tn2b = 0b1111; // 15 en binario (1 * 2³ + 1 * 2² + 1 * 2¹ + 1 * 2⁰ = 8 + 4 + 2 + 1 = 15)\n    printf(\"\\n\\tOperadores de bits\\n\");\n    printf(\"AND (binario): %d & %d = %d\\n\", n1b, n2b, n1b & n2b); // Operador AND binario. 00001010 & 00001111 pasa a ser 00001010\n    printf(\"OR (binario): %d | %d = %d\\n\", n1b, n2b, n1b | n2b); // Operador OR binario. 00001010 | 00001111 pasa a ser 00001111\n    printf(\"NOT (binario): ~%d = %d\\n\", n1b, ~n1b); // Operador NOT binario. ~00001010 pasa a ser 11110101\n    printf(\"XOR: %d ^ %d = %d\\n\", n1b, n2b, n1b ^ n2b); // Operador XOR binario. 00001010 ^ 00001111 pasa a ser 00000101\n    printf(\"Desplazamiento a la derecha (bits): %d >> 1 = %d\\n\", n1b, n1b >> 1); // Desplazamiento a la derecha. 00001010 pasa a ser 00000101, que es 5 en binario.\n    printf(\"Desplazamiento a la izquierda (bits): %d << 1 = %d\\n\", n1b, n1b << 1); // Desplazamiento a la izquierda. 00001010 pasa a ser 00010010, que es 20 en binario.\n\n    /* === 2 === */\n    // Condicional if, else if, else\n    /* La estructura es:\n     * if (condición) { código }\n     * else if (condición) { código }\n     * else { código }*/\n    int\ttemp = 0;\n    printf(\"\\n\\tCondicional if, else if, else\\n\");\n    if (temp < 2)\n    {\n        // Si 5 es menor que 2 se mete aquí\n        printf(\"%d es menor que 2\\n\", temp);\n    }\n    else if (temp == 0)\n    {\n        // Sino si 5 es igual a 0 se mete aquí\n        printf(\"%d es igual a 0\\n\", temp);\n    }\n    else\n    {\n        // Sino se mete aquí\n        printf(\"%d no es menor que 2 ni tampoco es igual a 0\\n\", temp);\n    }\n\n    // Condicional switch\n    /* Se suele utilizar cuando una condición puede tomar varios valores.\n     * Por ejemplo, un menú puede tener 10 opciones, y tener que utilizar\n     * tantos if, else if, else puede resultar tedioso.\n     * La estructura es:\n     * switch (variable)\n     * {\n     *     case <valor de la variable>:\n     *          código\n     *          break;\n     *     default:\n     *          código\n     *          break;\n     * }\n     * \n     * NOTA: El break sirve para que no se ejecute la siguiente condición.\n     */\n    printf(\"\\n\\tCondicional switch\\n\");\n    switch (temp)\n    {\n        case 1:\n            printf(\"%d es 1\\n\", temp);\n            break;\n        case 2:\n        case 3:\n            printf(\"%d es 2 o 3\\n\", temp);\n            break;\n        default:\n            printf(\"%d no es ni 1, ni 2 y tampoco es 3\\n\", temp);\n            break;\n    }\n\n    // Bucle while\n    /* Es el bucle más simple, con este se pueden hacer\n     * los demás.\n     * La estructura es:\n     * while (condicion) { código }\n     */\n    printf(\"\\n\\tBucle while\\n\");\n    temp = 10;\n    while (temp-- > 0)\n    {\n        if (temp != 0)\n            printf(\"%d, \", temp);\n        else\n            printf(\"%d\\n\", temp);\n    }\n\n    // Bucle for\n    /* Es el bucle más sencillo de utilizar.\n     * La estructura es:\n     * for (variable; condición; modificación de la variable) { código }\n     */\n    printf(\"\\n\\tBucle for\\n\");\n    for (int i = 0; i < 100; i += 10)\n    {\n        printf(\"%d \", i);\n    }\n    printf(\"\\n\");\n\n    // Bucle do while\n    /* Es como el while, pero la condición la verifica al final\n     * por lo tanto el código se ejecuta al menos una vez.\n     * La estructura es:\n     * do { código } while (condición);\n     */\n    printf(\"\\n\\tBucle do while\\n\");\n    temp = 200;\n    do\n    {\n        if (temp > 100)\n            temp = 10;\n        printf(\"%d \", temp);\n        temp += 11;\n    } while (temp < 100);\n    printf(\"\\n\");\n\n    /* === DIFICULTAD EXTRA === */\n    printf(\"\\n\\tDificultad extra\\n\");\n    for (int i = 10; i < 56; i++) // Para i igual a 10, menor que 56, aumenta i en uno.\n        if (i % 2 == 0 && i != 16 && i % 3 != 0) // Si el resto de i / 2 (i % 2) es igual a 0 (es par), no es igual a 16 y el resto de i / 3 (i % 3) no es igual a 0.\n            printf(\"%d \", i); // Imprime i.\n    printf(\"\\n\");\n    /* NOTA:\n     * En la sección 2, if (anidación == 1), no es necesario poner llaves,\n     * siempre y cuando se ponga la tabulación adecuada, else, hay que ponerlo.\n     * Por eso en el código he podido anidar dentro del for, un if y luego\n     * hacer el printf, sin necesidad de utilizar llaves.\n     */\n    return (0);\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c/aggranadoss.c",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n\n// Angel Granados alias aggranadoss\n\n#include<stdio.h>\n#include<stdlib.h>\n\nint main(int argc, char* argv[argc+1]){\n\n  // Declaración de Variable\n  int a,b,c;\n  \n  // Operador de asignación\n  a = 17;\n  b = 19;\n  c = 23; \n\n  /*\n\n    Operadores aritméticos\n\n   */\n\n  // Suma\n  printf(\"\\n\\n Suma de tres enteros %d + %d + %d = %d\", a,b,c,a+b+c);\n\n  // Resta\n  printf(\"\\n\\n Resta de dos enteros %d - %d  = %d\", c,a,c-a);\n\n  // Multiplicación\n  printf(\"\\n\\n Multiplicación de dos enteros %d x %d  = %d\", c,a,c*a);\n\n  // Cociente\n  printf(\"\\n\\n Division de dos enteros %d '/' %d  = %f\", c,a,c/a);\n\n  //  Resto\n  printf(\"\\n\\n Resto de dos enteros %d '%' %d  = %d\", c,a,c%a);\n\n    /*\n      \n      Operadores relacionales\n\n   */\n\n   //  Mayor\n   printf(\"\\n\\n Mayor de dos enteros %d '>' %d  = %d\", c,a,c>a);\n\n   //  Menor\n   printf(\"\\n\\n Menor de dos enteros %d '<' %d  = %d\", c,a,c<a);\n\n   //  Mayor o igual\n   printf(\"\\n\\n Mayor o igual  de dos enteros %d '>=' %d  = %d\", c,a,c>=a);\n\n   //  Menor o igual\n   printf(\"\\n\\n Menor o igual de dos enteros %d '<=' %d  = %d\", c,a,c<=a);\n\n   // Igual \n   printf(\"\\n\\n Comparar dos enteros iguales %d '==' %d  = %d\", c,c,c==c);\n\n   // Diferente \n   printf(\"\\n\\n Comparar dos enteros diferentes %d '!=' %d  = %d\", a,c,a!=c);\n\n\n     /*\n      \n      Operadores lógico\n\n     */\n\n   int e = 0, i = 1; // asignación de 0 y 1\n   \n   \n   // Conjunción\n   printf(\"\\n\\n Conjunción dos enteros diferentes %d '&&' %d  = %d\", e,i,e&&i);\n\n   printf(\"\\n\\n Conjunción dos enteros iguales %d '&&' %d  = %d\", i,i,i&&i);\n\n   printf(\"\\n\\n Conjunción dos enteros iguales %d '&&' %d  = %d\", e,e,e&&e);\n\n\n   // Disyunción\n\n   printf(\"\\n\\n Disyunción dos enteros diferentes %d '||' %d  = %d\", e,i,e||i);\n\n   printf(\"\\n\\n  Disyunción dos enteros iguales %d '||' %d  = %d\", i,i,i||i);\n\n   printf(\"\\n\\n  Disyunción dos enteros iguales %d '||' %d  = %d\", e,e,e||e);\n\n   // Negación\n\n   printf(\"\\n\\n Negación dos enteros diferentes %d '!' %d  = %d\", e,i,e!=i);\n\n   printf(\"\\n\\n  Negación dos enteros iguales %d '!' %d  = %d\", i,i,i!=i);\n\n   /*\n    Operadores bit a bit\n   */\n\n   short j = 0xAB00, k = 0xABCD;\n   \n   printf(\"\\n\\n  Operar dos bit en hexadecimales en conjunción %hx '&' %hx  = %hx\", j,k,j&k);\n\n   printf(\"\\n\\n  Operar dos bit en hexadecimales en disyunción %hx '^' %hx  = %hx\", j,k,j^k);\n   \n   printf(\"\\n\\n  Operar dos bit en hexadecimales en disyunción exclusiva %hx '|' %hx  = %hx\", j,k,j|k);\n\n\n   /*\n     Operadores Condicionales \n    */\n\n   \n   printf(\"\\n\\n  Operar con el condicional  x >= %d '?' %d:%d -> %d con x = %d \\n\\n \", a,b,c,a>=5?b:c,a);\n\n\n   /*\n\n     Ciclos \n\n    */\n\n   // while \n\n   int digito = 0;\n   while(digito <= 9){\n     printf(\"\\n Usando el ciclo while hasta llegar a n=9. n = %d\\n\", digito);\n     ++digito; // Operador unario\n   }\n\n   // for\n\n   int n;\n   for(n=0; n <=9; ++n){\n     printf(\"\\n Usando for -> %d\\n\", n);\n   }\n\n   // do - While\n\n   int l=0;\n   do{\n     l +=1;\n      printf(\"\\n Usando do-while -> %d\\n\", l);\n   }while(l <= 9);\n\n\n\n   /*\n     Dificultad Extra\n    */\n   printf(\"\\n Ejercicio de Dificultad Extra \\n\\n\");\n   for(int numero = 10; numero <= 55; numero++) {\n     if(numero % 2 == 0 && numero != 16 && numero % 3 != 0) {\n       printf(\"\\n numero = %d \\n \", numero);\n     }\n   }\n   \n  return EXIT_SUCCESS;\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c/barbafebles.c",
    "content": "\n#include <stdio.h>\n\nint main(void)\n{\n// Declaracion de variables\nint a, b, c, d, i;\n\n// Operadores de asignacion\na = 2; \nb = 3;\nc = 4;\nd = 5;\ni = 0;\n\nprintf(\"Asignacion: %d\\n\", a);\n\n// Operadores aritmeticos\nint suma = a+c;                 // suma\nint resta = a-c;                // resta\nint multiplicacion = c*c;       // multiplicacion\nint division = c/a;             // division\nint modulo = c%a;               // resto de la division\n\nprintf(\"Suma: %d\\n\", suma);\nprintf(\"Resta: %d\\n\", resta);\nprintf(\"Multiplicacion: %d\\n\", multiplicacion);\nprintf(\"Division: %d\\n\", division);\nprintf(\"Modulo: %d\\n\", modulo);\n\n// Operadores logicos\nint y = a && b;                 // Realiza una operación AND lógica entre 'a' y 'b'\nint o = c || d;                 // Realiza una operación OR lógica entre 'c' y 'd'\nint no = !c;                    // Realiza una operación NOT lógica en 'c'\n\nprintf(\"And: %d\\n\", y);\nprintf(\"Or: %dn\", o);\nprintf(\"Not: %d\\n\", no);\n\n// Operradores de comparacion \nint mayor = a > b;              // Verifica si 'a' es mayor que 'b'\nint menor = c < b;              // Verifica si 'c' es menor que 'b'\nint mayorIgual = a >= b;        // Verifica si 'a' es mayor o igual que 'b'\nint menorIgual = c <= d;        // Verifica si 'c' es menor o igual que 'd'\nint igual = a == c;             // Verifica si 'a' es igual a 'c'\nint diferente = a != b;         // Verifica si 'a' es diferente de 'b'\n\nprintf(\"Mayor que: %d\\n\", mayor);\nprintf(\"Menor que: %d\\n\", menor);\nprintf(\"Mayor o igual que: %d\\n\", mayorIgual);\nprintf(\"Menor o igual que: %d\\n\", menorIgual);\nprintf(\"Igual: %d\\n\", igual);\nprintf(\"No existe %d\\n\", diferente);\n\n// Operadores de bits\nint ybits = a & b;              // Realiza una operación AND a nivel de bits entre a y b\nint obits = a | b;              // Realiza una operación OR a nivel de bits entre a y b\nint xorbits = a ^ b;            // Realiza una operación XOR a nivel de bits entre a y b\nint izq = a << 1;               // Desplaza los bits de 'a' una posición a la izquierda\nint der = a >> 1;               // Desplaza los bits de 'a' una posición a la derecha\n\nprintf(\"AND de bits: %d\\n\", ybits);\nprintf(\"OR de bits: %d\\n\", obits);\nprintf(\"XOR de bits: %d\\n\", xorbits);\nprintf(\"Desplazamiento a la izquierda: %d\\n\", izq);\nprintf(\"Desplazamiento a la derecha: %d\\n\", der);\n\n\n// Operadores de incremento\na++;                // Incrementa el valor de a en 1 \nb--;                // Decrementa el valor de b en 1\n/*Otra manera de usarlos*/\n++c;                // Incrementa el valor de c en 1 antes de usarlo en una expresion\n--d;                // Decrementa el valor de d en 1 antes de usarlo en una expresion \n\n\n// Estructuras de control\n\n// Condicionales \nif(a > b){\n    printf(\"a es mayor que b\\n\");\n}\nelse{\n    printf(\"a no es mayor que b\");\n}\n\n// Iteractivas\nfor (i = 0; i <= 14; i++) {\n    if (i % 2 == 0 && i != 16 && i % 3 != 0) {\n        printf(\"%d\\n\", i);\n    }\n}\n\nwhile(d > b){\n    i++;\n    d--;\n}\nprintf(\"El valor final de i es: %d\\n\", i);\n\n/***DIFICULTAD EXTRA***/\n/*Crea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.*/\ni = 10;\n    while(i <= 55)\n    {\n       if(i % 2 == 0 && i != 16 && i % 3 != 0)\n       {\n        printf(\"%d\\n\", i);\n       }\n       i++;\n    }\n    return (0);\n}\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c/cikethebear.c",
    "content": "// CikeTheBear - https://github.com/CikeTheBear/\n\n// Operadores y Estructuras de Control en C\n\n#include <stdio.h>\n\nint main()\n{\n    printf(\"=== OPERADORES EN C ===\\n\");\n\n    // Operadores Artiméticos\n    printf(\"\\n--- Operadores Artimeticos ---\\n\");\n    printf(\"Suma: %d\\n\", 2 + 2);\n    printf(\"Resta: %d\\n\", 10 - 4);\n    printf(\"Multiplicacion: %d\\n\", 5 * 5);\n    printf(\"Division: %d\\n\", 10 / 2);\n    printf(\"Modulo: %d\\n\", 10 % 2);\n\n    // Operadores Logicos\n    printf(\"\\n--- Operadores Logicos ---\\n\");\n    printf(\"Operador Y / AND / &&: %d\\n\", 5 + 5 == 10 && 8 + 2 == 10);\n    printf(\"Operador O / OR / ||: %d\\n\", 5 + 5 == 10 || 8 + 2 == 10);\n    printf(\"Operador Negacion / NOT / !: %d\\n\", !5);\n\n    // Operadores de Comparacion\n    printf(\"\\n--- Operadores de Comparacion ---\\n\");\n    printf(\"Igual a: %d\\n\", 10 == 11);\n    printf(\"Distinto a: %d\\n\", 10 != 11);\n    printf(\"Mayor a: %d\\n\", 10 > 11);\n    printf(\"Mayor o igual a: %d\\n\", 10 >= 11);\n    printf(\"Menor a: %d\\n\", 10 < 11);\n    printf(\"Menor o igual a: %d\\n\", 10 <= 11);\n\n    // Operadores de Asignacion\n    int oA;\n    printf(\"\\n--- Operadores de Asignacion ---\\n\");\n    printf(\"Asignacion basica (=): %d\\n\", oA = 1);\n    printf(\"Suma y asigna (+=): %d\\n\", oA += 1);\n    printf(\"Resta y asigna (+=): %d\\n\", oA -= 1);\n    printf(\"Multiplica y asigna (*=): %d\\n\", oA *= 2);\n    printf(\"Divide y asigna (/=): %d\\n\", oA /= 1);\n    printf(\"Modulo y asigna (%=): %d\\n\", oA %= 1);\n\n    // Operadores de Identidad\n    // En C no existen operadores de identidad, pero podemos lograr algo similar usando los punteros.\n\n    int a = 0;\n    int b = 1;\n    \n    int *pa = &a;\n    int *pb = &b;\n\n    printf(\"\\n--- Operadores de Identidad ---\\n\");\n    printf(\"a es *pa = %d\\n\", a == *pa);\n    printf(\"*pb es b = %d\\n\",*pb == b);\n    printf(\"a es *pb = %d\\n\", a == *pb);\n\n    // Operadores de pertenencia\n    // No existen en C\n\n    // Operadores de Bits\n\n    unsigned bitAND = 10 & 25;\n    unsigned bitOR = 20 | 40;\n    unsigned bitXOR = 55 ^ 44;\n    unsigned bitNOT = ~5;\n    unsigned bitShiftLeft = 3 << 1;\n    unsigned bitShiftRight = 5 >> 2;\n\n    printf(\"\\n--- Operadores de Bits ---\\n\");\n    printf(\"bit to bit AND (&): %d\\n\", bitAND);\n    printf(\"bit to bit OR (|): %d\\n\", bitOR);\n    printf(\"bit to bit XOR (^): %d\\n\", bitXOR);\n    printf(\"bit to bit NOT (~): %d\\n\", bitNOT);\n    printf(\"bit to bit Shift Left (<<): %d\\n\", bitShiftLeft);\n    printf(\"bit to bit Shift Right >>): %d\\n\", bitShiftRight);\n\n    // Estructuras de Control\n    printf(\"\\n=== ESTRUCTURAS DE CONTROL EN C ===\\n\");\n\n    //  Estructuras Condicionales\n    int condA = 3;\n    int condB = 0;\n\n    printf(\"\\n--- Estructuras Condicionales ---\\n\");\n\n    printf(\"\\n--- if ---\\n\");\n    if (condA == 0) {\n        printf(\"condA es 0\\n\");\n    }\n    else if (condA == 1) {\n        printf(\"condA es 1\\n\");\n    }\n    else {\n        printf(\"condA no es ni 0 ni 1\\n\");\n    }\n\n    printf(\"\\n--- switch ---\\n\");\n    switch (condB) {\n        case 0:\n            printf(\"La opcion es 0\\n\");\n            break;\n\n        case 1:\n            printf(\"La opcion es 1\\n\");\n            break;\n\n        case 2:\n            printf(\"La opcion es 2\\n\");\n            break;\n\n        default:\n            printf(\"La opcion se sale del rango\\n\");\n            break;\n    }\n\n    //  Estructuras de Iteracion\n    int iteA = 5;\n    int iteB = 0;\n    int iteC = 0;\n\n    printf(\"\\n--- Estructuras de Iteracion ---\\n\");\n\n    printf(\"\\n--- for ---\\n\");\n    for (int i = 0; i < iteA; i++) {\n        printf(\"Iteracion for: %d\\n\", i);\n    }\n\n    printf(\"\\n--- while ---\\n\");\n    while (iteB < 5) {\n        printf(\"Iteracion while: %d\\n\", iteB);\n        iteB++;\n    }\n\n\n    printf(\"\\n--- do while ---\\n\");\n    do {\n        printf(\"Iteracion do-while: %d\\n\", iteC);\n        iteC++;\n    } while (iteC < 5);\n\n\n    // Dificultad extra\n    printf(\"\\n=== DIFICULTAD EXTRA ===\\n\");\n\n    printf(\"--- Programa que imprime numeros con ciertas condiciones ---\\n\"); \n\n    for (int i = 10; i <= 55; i += 2) {\n        if (i == 16 || i % 3 == 0) continue;\n        printf(\"Numero: %d\\n\", i);\n    }\n\n    return 0;\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c/d1d4cum.c",
    "content": "#include <iso646.h>\n#include <stdio.h>\n\nint main() {\n    //------------------Operadores\n    // Aritméticos\n    int suma = 3 + 3;\n    int resta = 3 - 3;\n    int multiplicacion = 3 * 3;\n    int division = 3 / 3;\n    int resto = 3 % 3;\n    int incremento = ++suma;\n    int decremento = --resta;\n    printf(\"%d\\n\", suma);\n    printf(\"%d\\n\", resta);\n    printf(\"%d\\n\", multiplicacion);\n    printf(\"%d\\n\", division);\n    printf(\"%d\\n\", resto);\n    printf(\"%d\\n\", incremento);\n    printf(\"%d\\n\", decremento);\n\n    // Asignación\n    suma += 5;\n    resta -= 5;\n    multiplicacion *= 5;\n    division /= 5;\n    resto %= 5;\n    int andOperator = 3 & 3;\n    int orOperator = 3 | 3;\n    int xorOperator = 3 ^ 3;\n    int right = 3 >> 3; // desplaza los bits 3 posiciones a la derecha\n    int left = 3 << 3; // desplaza los bits 3 posiciones  a la izquierda\n\n    printf(\"%d\\n\", suma);\n    printf(\"%d\\n\", resta);\n    printf(\"%d\\n\", multiplicacion);\n    printf(\"%d\\n\", division);\n    printf(\"%d\\n\", resto);\n    printf(\"%d\\n\", andOperator);\n    printf(\"%d\\n\", orOperator);\n    printf(\"%d\\n\", xorOperator);\n    printf(\"%d\\n\", right);\n    printf(\"%d\\n\", left);\n\n    // Comparación\n    printf(\"%d\\n\", 1 == 1);\n    printf(\"%d\\n\", 1 != 1);\n    printf(\"%d\\n\", 1 > 1);\n    printf(\"%d\\n\", 1 < 1);\n    printf(\"%d\\n\", 1 >= 1);\n    printf(\"%d\\n\", 1 <= 1);\n\n    // Operadores lógicos\n    int x = 5;\n    printf(\"%d\\n\", x < 5 &&  x < 10); //AND\n    printf(\"%d\\n\", x < 5 || x < 4); //OR\n    printf(\"%d\\n\", !(x < 5 && x < 10)); //NOT\n\n    //--------------------------- Estructuras de control\n    //  If - else\n\n    if (x == 5) {\n        printf(\"X es 5\\n\");\n    } else if (x > 5) {\n        printf(\"X es mayor que 5\\n\");\n    } else {\n        printf(\"X es menor que 5\\n\");\n    }\n\n    // Switch\n    switch (x) {\n        case 5:\n            printf(\"X es 5\\n\");\n            break;\n        case 4:\n            printf(\"X es 4\\n\");\n            break;\n        case 3:\n            printf(\"X es 3\\n\");\n            break;\n        default:\n            printf(\"No es nada\\n\");\n    }\n\n    // While\n    while(x < 7) {\n        printf(\"X vale %d\\n\", x);\n        x++;\n    }\n\n    do {\n        printf(\"X vale %d\\n\", x);\n        x++;\n    } while(x < 10);\n\n    // For\n    for(int i = 0; i <= 5; i++) {\n        if (i == 3){\n            continue;\n        } else if (i == 5) {\n            break;\n        }\n        printf(\"i vale %d\\n\", i);\n    }\n\n    //-------------- Ejercicio\n    printf(\"** Ejercicio **\\n\");\n    for (int i = 10; i <= 55; i++) {\n        if (i % 2 == 0) {\n            if (i != 16 && i % 3 != 0) {\n                printf(\"%d\\n\", i);\n            }\n        }\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c/fefestuve.c",
    "content": "#include <stdio.h>\r\n#include <stdbool.h>\r\n\r\nint main(void){\r\n\r\n    int a = 1;\r\n    int b = 2;\r\n\r\n    //operadores aritmeticos\r\n    int suma = a+b;\r\n    int resta = a-b;\r\n    int multiplicacion = a*b;\r\n    int division = a/b;\r\n    int modulo = a%b; // devuelve el resto de la division a/b\r\n    int incremento = a++; \r\n    int decremento = a--; \r\n   \r\n\r\n    //operadores logicos\r\n    bool AND = a&&b;\r\n    bool OR = a||b;\r\n    bool NOT = !a;\r\n\r\n    //operadores de comparacion\r\n    bool mayor = a>b;\r\n    bool mayor_igual = a>=b;\r\n    bool menor = a<b;\r\n    bool menor_igual = a<=b;\r\n    bool igual = a==b;\r\n    bool distinto = a!=b;\r\n\r\n    //operadores de bits\r\n    a=0b011101;\r\n    b=0b100010;\r\n\r\n    int ANDbits = a&b;\r\n    int ORbits = a|b;\r\n    int NOTbits = ~a;\r\n    int XORbits = a^b;\r\n    int desplazoderecha = a>>1;\r\n    int desplazoizquierda = a<<1;\r\n\r\n    //operadores de asignacion\r\n    a = 1;\r\n    a += b;\r\n    a -=b;\r\n    a *= b;\r\n    a /= b;\r\n    a %= b;\r\n    a &= b;\r\n    a |= b;\r\n    a ^= b;\r\n    a >>= b;\r\n    a <<= b;\r\n\r\n    //condicional if else else-if\r\n\r\n    if(a>b){\r\n        printf(\"a es mayor que b\\n\");\r\n    }else if(a<b){\r\n        printf(\"a es menor que b\\n\");\r\n    }else{\r\n        printf(\"a y b son iguales\\n\");\r\n    }\r\n\r\n    //switch\r\n    switch(a){\r\n\r\n        case 0:\r\n            printf(\"a es 0\\n\");\r\n            break;\r\n        \r\n        case 1:\r\n            printf(\"a es 1\\n\");\r\n            break;\r\n        \r\n        case 2:\r\n            printf(\"a es 2\\n\");\r\n            break;\r\n\r\n    }\r\n\r\n    //while loop\r\n    while(a<b){\r\n        printf(\"a es menor a b\\n\");\r\n        a++;\r\n    }\r\n\r\n    //do while loop\r\n    do{\r\n        printf(\"hola\\n\"); //la diferencia con el while es que se ejecuta y vez si o si y despues verifica la condicion\r\n        a++;\r\n    }while(a<b);\r\n\r\n    //for loop\r\n    for(int i=0; i<=a; i++){\r\n        printf(\"a vale %i e i vale %i\\n\", a, i);\r\n    }\r\n    \r\n\r\n    //desafio\r\n    for(int i=10; i<=55; i++){\r\n        if((i%2) == 0 && i!=16 && (i%3)!=0){\r\n            printf(\"%i\\n\", i);\r\n        }\r\n    }\r\n\r\n\r\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c/fsfigueroa77.c",
    "content": "#include <stdio.h>\n\nint main(){\n    // Ejemplo de operador de asignacion\n    printf(\"\\nOPERADORES DE ASIGNACION\\n\");\n    int variable_entera = 100; // El \"=\" es el operador de asignacion\n    printf(\"El ejemplo de usar un operador de asignacion en una variable es: %d.\\n\", variable_entera);\n    variable_entera += 5;\n    printf(\"El ejemplo de usar un operador de suma y asignacion en una variable es: %d.\\n\", variable_entera);\n    variable_entera -= 45;\n    printf(\"El ejemplo de usar un operador de resta y asignacion en una variable es: %d.\\n\", variable_entera);\n    variable_entera *= 2;\n    printf(\"El ejemplo de usar un operador de multiplicacion y asignacion en una variable es: %d.\\n\", variable_entera);\n    variable_entera /= 3;\n    printf(\"El ejemplo de usar un operador de division y asignacion en una variable es: %d.\\n\", variable_entera);\n    variable_entera %= 9;\n    printf(\"El ejemplo de usar un operador de modulo y asignacion en una variable es: %d.\\n\", variable_entera);\n\n    // Ejemplos de operadores aritmeticos\n    printf(\"\\nOPERADORES DE ARITMETICOS\\n\");\n    variable_entera = 1;\n    printf(\"Usar el operador unario Signo negativo en la variable da como resultado: %d.\\n\", -variable_entera);\n    printf(\"Usar el operador unario Incremento en la variable da como resultado: %d.\\n\", ++variable_entera);\n    printf(\"Usar el operador unario Decremento en la variable da como resultado: %d.\\n\", --variable_entera);\n    printf(\"Uso del operador binario Suma: 2 + 3 = %d.\\n\", 2 + 3);\n    printf(\"Uso del operador binario Resta: 3 - 2 = %d.\\n\", 3 - 2);\n    printf(\"Uso del operador binario Multiplicacion: 10 * 5 = %d.\\n\", 10 * 5);\n    printf(\"Uso del operador binario Division: 24 / 6 = %d.\\n\", 24 / 6);\n    printf(\"Uso del operador binario Modulo: 30 % 11 = %d.\\n\", 30 % 11);\n\n    // Ejemplos de operadores relacionales (C no tiene el tipo de dato booleano. Se representa a True como 1 y False como 0)\n    printf(\"\\nOPERADORES DE RELACIONALES\\n\");\n    int resultado;\n    resultado = (1 < 3); // Menor que\n    printf(\"El resultado de 1 < 3 es: %d.\\n\", resultado);\n    resultado = (1 > 3); // Mayor que\n    printf(\"El resultado de 1 > 3 es: %d.\\n\", resultado);\n    resultado = (1 <= 3); // Menor o igual que\n    printf(\"El resultado de 1 <= 3 es: %d.\\n\", resultado);\n    resultado = (1 >= 3); // Mayor o igual que\n    printf(\"El resultado de 1 >= 3 es: %d.\\n\", resultado);\n    resultado = (1 == 3); // Igual que \n    printf(\"El resultado de 1 == 3 es: %d.\\n\", resultado);\n    resultado = (1 != 3); // Distinto que\n    printf(\"El resultado de 1 != 3 es: %d.\\n\", resultado);\n\n    // Ejemplos de operadores logicos\n    printf(\"\\nOPERADORES DE LOGICOS\\n\");\n    resultado = (5 > 3) && (3 != 7);\n    printf(\"El resultado de (5 > 3) && (3 != 7) es: %d.\\n\", resultado); // Conjuncion\n    resultado = (5 == 1) || (4 >= 10);\n    printf(\"El resultado de (5 == 1) || (4 >= 10) es: %d.\\n\", resultado); // Disyuncion\n    resultado = !(5 > 3);\n    printf(\"El resultado de !(5 > 3) es: %d.\\n\", resultado); // Negacion\n\n    // Ejemplo de operadores con bits\n    printf(\"\\nOPERADORES DE BITS\\n\");\n    unsigned char numero1 = 7, numero2 = 2; // 7 = 111, 2 = 10\n    unsigned char conjuncion = numero1 & numero2; // 111 & 10\n    printf(\"El resultado de 7 & 2 es: %u.\\n\", conjuncion); // 10 = 2\n    unsigned char disyuncion = numero1 | numero2; // 111 | 10\n    printf(\"El resultado de 7 | 2 es: %u.\\n\", disyuncion); // 111 = 7\n    unsigned char disyuncion_ex = numero1 ^ numero2; // 111 ^ 10\n    printf(\"El resultado de 7 ^ 2 es: %u.\\n\", disyuncion_ex); // 101 = 5\n    unsigned char negacion = ~numero1; // ~0000 0111\n    printf(\"El resultado de ~7 es: %u.\\n\", negacion); // 1111 1000 = 248 \n    unsigned char desp_der = numero1 >> 2;\n    printf(\"El resultado de 7 >> 2 es: %u.\\n\", desp_der); // 001 = 1\n    unsigned char desp_izq = numero1 << 2;\n    printf(\"El resultado de 7 << 2 es: %u.\\n\", desp_izq); // 11100 = 28\n\n    // Ejemplos de Condicionales \n    int variable1 = 0, variable2 = 0;\n    printf(\"\\nIngrese un numero entre 1 y 90: \");\n    scanf(\"%d\", &variable1); // Pedir al usuario un numero entre 1 y 90\n    if(variable1 > 0 && variable1 <= 30){ // Uso de if\n        printf(\"Tendras suerte en el trabajo.\\n\");\n    }else if(variable1 > 30 && variable1 <= 60){\n        printf(\"Tendras suerte en el amor.\\n\");\n    }else if(variable1 > 60 && variable1 <= 90){\n        printf(\"Tendras suerte en el dinero.\\n\");\n    }else{\n        printf(\"Tendras mala suerte en todo.\\n\");\n    }\n\n    printf(\"\\nIngresa otro numero: \");\n    scanf(\"%d\", &variable2);\n    printf(\"El numero maximo es: %d.\\n\", ((variable1 > variable2) ? variable1 : variable2)); // Uso del operaperador condicional ?\n\n    unsigned char opcion = 0;\n    printf(\"\\nConsulta de saldos\\n[1] Saldo de minutos.\\n[2] Saldo de datos.\\n[3] Salir.\\nElija una opcion del menu: \");\n    scanf(\"%u\", &opcion);\n    if(!(opcion < 1 || opcion > 3)){\n        switch(opcion){ // Uso de Switch\n            case 1:\n                printf(\"Su salgo de minutos es: 50 minutos.\\n\");\n                break;\n            case 2:\n                printf(\"Su saldo de datos es: 15 gb.\\n\");\n                break;\n            default:\n                printf(\"Gracias por elegir nuestro servicio.\\n\");\n                break;\n        }\n    }else{\n        printf(\"Opcion incorrecta.\\n\");\n    }\n    \n    // Ejemplos de iterativas\n    unsigned char eleccion = 0;    \n    while(eleccion < 1 || eleccion > 3){ // Uso de While\n        printf(\"\\nIngresa un numero del 1 al 3: \");\n        scanf(\"%u\", &eleccion);\n        if(eleccion < 1 || eleccion > 3){\n            printf(\"Opcion incorrecta.\\n\");\n        }\n    }\n\n    int i;\n    for(i = 1; i < 11; i++){ // Uso de For\n        if(i % 2 == 0){\n            printf(\"%d\\n\", i);\n        }\n    }\n\n    // Dificultad Extra\n    printf(\"\\n=====Dificultad Extra=====\\n\");    \n    for(i = 10; i < 56; i+=2){ // Ciclo para empezar en el 10 y terminar en el 56, haciendo saltos de 2 en 2\n        if(!((i % 3) == 0)){ // Condicion para excluir los numeros multiplos de 3\n            if(!(i == 16)){ // Condicion para excluir el numero 16\n                printf(\"%d\\n\", i);\n            }\n        }\n    }\n\n    return(0);\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c/heliercamejo.c",
    "content": "#include <stdio.h>\n#include <string.h>\n\nint main()\n{\n//Inicializacion\n    \n    int a = 20;\n    int b = 1;\n    int c = 0;\n    printf(\"a=%d b=%d\\n\",a,b);\n//Aritmeticos\n    printf(\"Suma(+) \\ta+10=%d\\n\",a + 10);\n    printf(\"Resta(-)\\ta-5=%d\\n\",a - 5);\n    printf(\"Mult(*) \\ta*5=%d\\n\",a * 5);\n    printf(\"División(/)\\ta/5=%d\\n\",a / 5);\n    printf(\"Resto(%%)\\ta%%5=%d\\n\\n\",a % 5);\n    \n//Incremento\n    printf(\"Incremento(a++)\\t%d\\n\",a++); //Primero evalua y luego incrementa\n    printf(\"Incremento(a)\\t%d\\n\",a);\n    printf(\"Incremento(++a)\\t%d\\n\",++a); //Primero incrementa y luego evaluea\n    printf(\"Incremento(a)\\t%d\\n\",a);\n    printf(\"Decremento(a--)\\t%d\\n\",a--); //Primero evalua y luego incrementa\n    printf(\"Decremento(a)\\t%d\\n\",a);\n    printf(\"Decremento(--a)\\t%d\\n\",--a); //Primero incrementa y luego evaluea\n    printf(\"Decremento(a)\\t%d\\n\\n\",a);\n\n//Asignacion\n    a -= 5; // a = a - 5\n    printf(\"Resta e igual(-=)\\ta-=5 a=%d\\n\",a);\n    a += 10; // a = a + 10\n    printf(\"Suma e igual(+=)\\ta+=10 a=%d\\n\",a);\n    a *= b; // a = a * b\n    printf(\"Mult e igual(-=)\\ta*=b a=%d\\n\",a);\n    a /= b; // a = a / b\n    printf(\"Div e igual(-=)\\t\\ta/=b a=%d\\n\",a);\n    a %= b; // a = a % b\n    printf(\"Div_entera e igual(%%=)\\ta%%=b a=%d\\n\",a);\n    a = 20;\n    printf(\"Asignacion(=)\\t\\ta=20 a=%d\\n\",a);\n    b = 18;\n    printf(\"Asignacion(=)\\t\\tb=18 b=%d\\n\\n\",b);\n\n//Operadores binarios\n    printf(\"And(&)\\t\\t\\ta&b=%d\\n\",a&b);\n    printf(\"Or(|)\\t\\t\\ta|b=%d\\n\",a|b);\n    printf(\"Not(~)\\t\\t\\t~a=%d\\n\",~a);\n    printf(\"Xor(^)\\t\\t\\ta^b=%d\\n\",a^b);\n    printf(\"Desplazamiento_der(>>)\\ta>>2=%d\\n\",a >> 2);\n    printf(\"Desplazamiento_izq(<<)\\ta<<2=%d\\n\\n\",a << 2);\n\n//Operadores logicos\n    printf(\"And(&&)\\ta&&b=%d\\n\",a&&b);\n    printf(\"Or(||)\\ta||b=%d\\n\",a||b);\n    printf(\"Not(!)\\ta!b:%d\\n\\n\",!a);\n\n//Operadores de comparacion\n    printf(\"Igualdad(==):\\t\\ta == b:%d\\n\",a==b);\n    printf(\"Desigualdad(!=):\\ta != b:%d\\n\",a!=b);\n    printf(\"Mayor que(>):\\t\\ta > b:%d\\n\",a>b);\n    printf(\"Menor que(<):\\t\\ta < b:%d\\n\",a<b);\n    printf(\"Mayor o igual(>=):\\ta >= b:%d\\n\",a>=b);\n    printf(\"Menor o igual(<=):\\ta <= b:%d\\n\\n\",a<=b);\n\n    /*No tiene operadores de pertenencia, ni de identidad*/\n\n    /**\n     * Estructuras de control\n    */\n   char d[]= \"HelierCamejo\";\n    \n    //Condicionales\n    if (strstr(d,\"heliercamejo\"))\n    {\n        printf(\"No importa si esta en mayuscula\\n\");\n    }\n    else if (strstr(d,\"helier_camejo\"))\n    {\n        printf(\"No importa si esta separado\\n\");\n    }\n    else \n    {   \n        printf(\"Si importa si esta separado o en mayuscula\\n\");\n    }\n    //Con el operador ? tambien se puede realizar una condicional\n    (strstr(d,\"HelierCamejo\"))?printf(\"Esta es una condicion positiva\\n\"):printf(\"Esta es una condicion negativa\\n\"); \n\n    //iterativas \n    int i = 0;\n    printf(\"do{}While\\n\");\n\n    do{\n        printf(\"i=%d\\n\",i);\n        i++;\n    }while(i<10);\n\n    printf(\"While\\n\");\n\n    while (i<30)\n    {\n        printf(\"i=%d\\n\",i);\n        i++;\n    }\n\n    printf(\"For\\n\");\n\n    for (; i < 50; i++)\n    {\n        printf(\"i=%d\\n\",i);\n    }\n    \n    //Expresiones de seleccion switch case\n    i = 3;\n    switch (i)\n    {\n    case 1:\n        printf(\"i=1\\n\");\n        break;\n    case 2:\n        printf(\"i=2\\n\");\n        break;\n    case 3:\n        printf(\"i=3\\n\");\n        break;\n    default:\n        printf(\"Valor por defecto\\n\");\n        break;\n    }\n\n    /*C no tiene excepciones*/\n\n    //Extra\n    printf(\"Ejercicio extra\\n\");\n    for(i = 10; i<=55;i++)\n    {\n        if ((i != 16) && ( i % 3 != 0) && ( i % 2 != 0) )\n        {\n            printf(\"i=%d\\n\",i);\n        }\n    }\n\n    return 0;\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c/jchavescaceres.c",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA:\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n#include <stdio.h>\n\nvoid main () {\n\n\tint a=10;\n\tint b=3;\n\n\n\t/* Dificultad extra */\n\tconst unsigned int C_MIN=10;\n\tconst unsigned int C_MAX=55;\n\tconst unsigned int C_EXCLUDE=16;\n\tconst unsigned int C_EXCLUDE_MULTIPLE = 3;\n\t\n\t/* Operadores artiméticos */\n\tprintf (\"Aritméticos:\\n\");\n\tprintf (\"a=%d, b=%d\\n\", a, b);\n\tprintf (\"Suma a+b : %d\\n\", a+b);\n\tprintf (\"Resta a-b : %d\\n\", a-b);\n\tprintf (\"Multiplicación a*b : %d\\n\", a*b);\n\tprintf (\"Divisioin a/b : %d\\n\", a/b);\n\tprintf (\"Módulo a%% b : %d\\n\", a%b);\n\tprintf (\"Incrementar primero y devolver nuevo valor ++a: %d, a: %d\\n\", ++a, a);\n\tprintf (\"Devolver valor e incrementar luego a++: %d, a: %d\\n\", a++, a);\n\tprintf (\"Decrementar primero y devolver nuevo valor --a: %d, a: %d\\n\", --a, a);\n\tprintf (\"Devolver valor y decrementar luego a--: %d, a: %d\\n\", a--, a);\n\n\t/* Operadores lógicos */\n\tprintf (\"\\nLógicos:\\n\");\n\ta=1;\n\tb=0;\n\tprintf (\"Igualdad: a=%d, b=%d, a==b = %d\\n\", a, b, a==b);\n\tprintf (\"Negación: a=%d, b=%d, !a==b = %d a!=b = %d\\n\", a, b, !a==b, a!=b);\n\tprintf (\"AND: a=%d, b=%d, a && b = %d\\n\", a, b, a&&b);\n\tprintf (\"OR: a=%d, b=%d, a || b = %d\\n\", a, b, a||b);\n\t\n\t/* Operadores comparación */\n\tprintf (\"\\nComparación:\\n\");\n\tprintf (\"a=%d, b=%d\\n\", a, b);\n\tprintf (\"a>b %s\\n\", a>b ? \"true\" : \"false\");\n\tprintf (\"a>=b %s\\n\", a>=b ? \"true\" : \"false\");\n\tprintf (\"a<b %s\\n\", a<b ? \"true\" : \"false\");\n\tprintf (\"a<=b %s\\n\", a<=b ? \"true\" : \"false\");\n\t\n\t/* Operadores asignación */\n\tprintf (\"\\nAsignación:\\n\");\n\tprintf (\"a=%d, b=%d \\n\", a, b);\n\tb=a;\n\tprintf (\"b=a b: %d \\n\", b);\n\ta+=2;\n\tprintf (\"Sumar y asignar nuevo valor a+=2 : %d\\n\", a);\n\ta-=2;\n\tprintf (\"Restar y asignar nuevo valor a-=2 : %d\\n\", a);\n\ta*=2;\n\tprintf (\"Multiplicar y asignar nuevo valor a*=2 : %d\\n\", a);\n\ta/=2;\n\tprintf (\"Dividir y asignar nuevo valor a/=2 : %d\\n\", a);\n\ta%=2;\n\tprintf (\"Módulo y asignar nuevo valor a%%=2 : %d\\n\", a);\n\tprintf (\"Operador ternario (7 > 5 ? 3 : 2) : %d\\n\", (7 > 5 ? 3 : 2));\n\tprintf (\"Operador ternario (7 < 5 ? 3 : 2) : %d\\n\", (7 < 5 ? 3 : 2));\n\n\t/* Operador bits */\n\ta=4;\n\tb=5;\n\tprintf (\"\\nbits:\\n\");\n\tprintf (\"Complemento a 1: a=%X, ~a %X\\n\", a, ~a);\n\tprintf (\"Desplazamiento a la izquierda 2 bits : a=%X, a<<2 %X\\n\", a, a<<2);\n\tprintf (\"Desplazamiento a la derecha 2 bits : a=%X, a>>2 %X\\n\", a, a>>2);\n\tprintf (\"AND: a=%X, b=%X, a&b=%X\\n\", a, b, a&b);\n\tprintf (\"OR: a=%X, b=%X, a|b=%X\\n\", a, b, a|b);\n\tprintf (\"XOR: a=%X, b=%X, a^b=%X\\n\", a, b, a^b);\n\n\t/* Operador sizeof */\n\tprintf (\"\\nOtro:\\n\");\n\tprintf (\"sizeof (a): %lu, sizeof (long): %lu\\n\", sizeof(a), sizeof(long));\n\t\n\t/* Estructuras de control */\n\tprintf (\"\\nEstructuras de control:\\n\");\n\tprintf (\"if, else sif , else :\\n\");\n\tif (a==5) {\n\t\tprintf (\"Dentro de if\\n\");\n\t} \n\telse if (b==2) {\n\t\tprintf (\"Dentro de elsif\\n\");\n\t}\n\telse {\n\t\tprintf (\"Dentro de else\\n\");\n\t};\n\n\ta=3;\n\tprintf (\"do ... while\\n\");\n\tdo {\n\t\tprintf (\"Dentro de do while %d\\n\", --a);\n\t} while (a>1);\n\n\ta=3;\n\tprintf (\"while ... \\n\");\n\twhile (a>1) {\n\t\tprintf (\"Dentro de while %d\\n\", --a);\n\t};\n\n\tprintf (\"for (a=1; a<3; a++)\\n\");\n\tfor (a=1; a<10; a++) {\n\t\tif (a==1) {\n\t\t\tprintf (\"Dentro del for continue\\n\");\n\t\t\tcontinue; \n\t\t}\n\t\telse if (a==3) {\n\t\t\tprintf (\"Dentro del for break\\n\");\n\t\t\tbreak; \n\t\t};\n\t\tprintf (\"Dentro del for %d\\n\", a);\n\t};\n\n\ta=3;\n\tprintf(\"switch .. case\\n\");\n\tswitch (a) {\n\t\tcase 1:\n\t\t\tprintf (\"Dentro de case 1\\n\");\n\t\t\tbreak; /*hay que poner break o ejecutaría código a partir de aquí*/\n\t\tcase 2:\n\t\t\tprintf (\"Dentro de case 2\\n\");\n\t\t\tbreak; /*hay que poner break o ejecutaría código a partir de aquí*/\n\t\tdefault:\n\t\t\tprintf (\"Dentro de default\\n\");\n\t\t\tbreak; /*hay que poner break o ejecutaría código a partir de aquí*/\n\t};\n\n\tprintf (\"Goto, MUY POCO ELEGANTE, NUNCA SE USA\\n\");\n\ta=1;\n\tif (a==2) {\n\t\tetiqueta:\n\t\tprintf (\"Dentro de label goto\\n\");\n\t}\n\telse {\n\t\tgoto etiqueta;\n\t};\n\n\t/* C no tiene excepciones */\n\n\n/*\n * DIFICULTAD EXTRA:\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n*/\nprintf(\"\\nDificultad extra, imprimir por consola todos los números comprendidos entre \\\n%u y %u (incluidos), pares, y que no son ni el %u ni múltiplos de %u \\n\", C_MIN, C_MAX, C_EXCLUDE, C_EXCLUDE_MULTIPLE);\n\n\tfor (unsigned int numero = C_MIN; numero <= C_MAX; numero++) {\n\t\tif ((numero != C_EXCLUDE) && (numero %2 == 0) && (numero %C_EXCLUDE_MULTIPLE != 0)) {\n\t\t\tprintf(\"%u\\n\", numero);\n\t\t};\n\t};\n};\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c/marcosalvarezcalabria.c",
    "content": "\n#include <stdio.h>\n\nint main(void) {\n    int num1 = 1;\n    int num2 = 2;\n    int num3 = 3;\n    int num4 = 4;\n    int *ptr = &num4;\n    /*********VARIABLES DIFICULATD EXTRA***** */\n\n    int i = 10;\n\n\n\n    //*********ARITMÉTICOS :************//\n\n    // suma;\n    int result_suma = num1 + num2;\n    printf(\"Resultado suma num1 + num2 = %d\\n\", result_suma);\n    // resta\n    int result_resta = num1 - num2;\n    printf(\"Resultado resta num1 - num2 = %d\\n\", result_resta);\n    // división\n    int result_div = num1 / num2;\n    printf(\"Resultado div num1 / num2 = %d\\n\", result_div);\n    // multiplicación\n    int result_mult = num1 * num2;\n    printf(\"Resultado mult num1 * num2 = %d\\n\", result_mult);\n    // módulo\n    int result_mod = num1 % num2;\n    printf(\"Resultado mod num1 %% num2 = %d\\n\", result_mod);\n\n    //************RELACIONALES******************* //\n\n    // ==\n    int result_igual = num1 == num2;\n    printf(\"Resultado de num1 == num2 = %d\\n\", result_igual);\n    // !=\n    int result_neg = num1 != num2;\n    printf(\"Resultado de num1 != num2 = %d\\n\", result_neg);\n    // >\n    int result_mayor = num1 > num2;\n    printf(\"Resultado de num1 > num2 = %d\\n\", result_mayor);\n    // <\n    int result_menor = num1 < num2;\n    printf(\"Resultado de num1 < num2 = %d\\n\", result_menor);\n    // >=\n    int result_mayor_igual = num1 >= num2;\n    printf(\"Resultado de num1 >= num2 = %d\\n\", result_mayor_igual);\n    // <=\n    int result_menor_igual = num1 <= num2;\n    printf(\"Resultado de num1 <= num2 = %d\\n\", result_menor_igual);\n\n    //***********************LÓGICOS***********************//\n\n    // &&\n    int result_and = num1 && num2;\n    printf(\"Resultado de num1 && num2 = %d\\n\", result_and);\n    // ||\n    int result_or = num1 || num2;\n    printf(\"Resultado de num1 || num2 = %d\\n\", result_or); \n    // !\n    int result_not = !num1;\n    printf(\"Resultado de !num1 = %d\\n\", result_not);\n\n    /********************ASIGNACIÓN************************/\n\n    // =\n    int result = num1;\n    printf(\"Resultado de result = num1 : %d\\n\", result);\n\n    // +=\n    num3 += num1;\n    printf(\"Resultado de num3 += num1 : %d\\n\", num3);\n\n    // -=\n    num3 -= num1;\n    printf(\"Resultado de num3 -= num1 : %d\\n\", num3);\n\n    // /=\n    num3 /= num1;\n    printf(\"Resultado de num3 /= num1 : %d\\n\", num3);\n\n    // *=\n    num3 *= num1;\n    printf(\"Resultado de num3 *= num1 : %d\\n\", num3);\n\n    // %=\n    num3 %= num1;\n    printf(\"Resultado de num3 %%= num1 : %d\\n\", num3); // Recordatorio: usar %% en printf para mostrar %\n\n    /********************OPERADORES A NIVEL DE BITS************************/\n\n    // &=\n    num3 &= num1;\n    printf(\"Resultado de num3 &= num1 : %d\\n\", num3);\n\n    // >>=\n    num3 >>= num1;\n    printf(\"Resultado de num3 >>= num1 : %d\\n\", num3); // Esto desplaza los bits de num3 hacia la derecha las veces de num1\n\n    // <<=\n    num3 <<= num1;\n    printf(\"Resultado de num3 <<= num1 : %d\\n\", num3); // Esto desplaza los bits de num3 hacia la izquierda las veces de num1\n\n    // ^=\n    num3 ^= num1;\n    printf(\"Resultado de num3 ^= num1 : %d\\n\", num3); // XOR a nivel de bits: establece un bit en 1 si los bits correspondientes son diferentes\n\n    // |=\n    num3 |= num1;\n    printf(\"Resultado de num3 |= num1 : %d\\n\", num3); // OR a nivel de bits: establece un bit en 1 si cualquiera de los bits correspondientes es 1\n\n    /******************************INCREMENTO Y DECREMENTO ************************************/\n\n    // ++\n    num1++;\n    printf(\"El resultado de num1++ es : %d\\n\", num1);\n    // --\n    num1--;\n    printf(\"El resultado de num1-- es : %d\\n\", num1);\n\n    /**********************************CONDICIONALES ***********************************/\n\n    // if else\n    if (num1 > num2) {\n        printf(\"num1 es mayor que num2\\n\");\n    } else if (num1 < num2) {\n        printf(\"num1 es menor que num2\\n\");\n    } else {\n        printf(\"num1 es igual a num2\\n\");\n    }\n\n    // switch\n    switch(num2) {  // Usar num2 en lugar de num1 para diferenciar el ejemplo de if-else\n        case 1:\n            printf(\"El número es 1.\\n\");\n            break;\n        case 2:\n            printf(\"El número es 2.\\n\");\n            break;\n        case 3:\n            printf(\"El número es 3.\\n\");\n            break;\n        default:\n            printf(\"El número no es 1, 2 o 3.\\n\");\n            break;\n    }\n\n    /********************************ITERATIVAS ******************************************************/\n    // for\n    for (size_t i = 0; i < num2; i++) {\n        printf(\"num1 se repetira %d veces\\n\", num2);\n    }\n    // while\n    while (num1 < 3) {\n        printf(\"%d este numero es num1 se repetira 2 veces\\n\", num1);\n        num1++;\n    }\n\n    // do-while\n    do {\n        printf(\"Contador actual: %d\\n\", num1);\n        num1++;\n    } while (num1 <= 5);\n\n    /*******************************TERNARIO*****************************/\n    num1 = (num1 > num2) ? num1 : num2;\n    printf(\"Esto es un ejemplo de operador ternario: num1 = (num1 > num2) ? num1 : num2\\n\");\n    printf(\"Y el resultado es %d\\n\", num1);\n\n    /************************************************PUNTEROS*********************************/\n    printf(\"Sabemos que num4 = 4\\n\");\n    printf(\"También sabemos que ptr es un puntero a num4\\n\");\n    printf(\"Aquí vemos que imprime num4: %d \\n\", num4);\n    printf(\"Aquí vemos que imprime ptr: %p \\n\", ptr);\n    printf(\"ptr nos imprime la dirección de memoria donde se encuentra num4\\n\");\n    printf(\"El valor de num4 usando el puntero es: %d\\n\", *ptr);\n\n    /*****************************SizeOF*****************************/\n    printf(\"Ahora imprimiremos el tamaño en bytes de num1 utilizando el operador sizeof\\n\");\n    printf(\"El tamaño de la variable tipo int num1 es: %lu bytes\\n\", sizeof(num1));\n    printf(\"El tamaño del tipo de dato int es: %lu bytes\\n\", sizeof(int));\n\n    /******************************DIFICULTAD EXTRA ***************************/\n\n    while (i <= 55){\n       \n            if (i %2 == 0 && i != 16 && i % 3 != 0){\n                printf(\"%d,\", i);\n            }\n     i++;   \n\n    };\n\n\n\n\n\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c/miguelex.c",
    "content": "#include <stdio.h>\n\nint main(){\n    // operadores aritmeticos\n\n    int a = 10;\n    int b = 20;\n\n    printf(\"Suma: %d\\n\", a + b);\n    printf(\"Resta: %d\\n\", a - b);\n    printf(\"Multiplicacion: %d\\n\", a * b);\n    printf(\"Division: %d\\n\", a / b);\n    printf(\"Modulo: %d\\n\", a % b);\n\n    // operadores de asignacion\n\n    a = 10;\n\n    printf(\"Asignacion: %d\\n\", a);\n    printf(\"Asignacion con suma: %d\\n\", a += 10);\n    printf(\"Asignacion con resta: %d\\n\", a -= 10);\n    printf(\"Asignacion con multiplicacion: %d\\n\", a *= 10);\n    printf(\"Asignacion con division: %d\\n\", a /= 10);\n    printf(\"Asignacion con modulo: %d\\n\", a %= 10);\n\n    // operadores de incremento y decremento\n    ++a; // a = a\n    printf(\"Incremento: %d\\n\", a);\n    --a; // a = a\n    printf(\"Decremento: %d\\n\", a);\n\n    // operadores de relacion\n    a = 10;\n\n    printf(\"Igualdad: %d\\n\", a == b);\n    printf(\"Desigualdad: %d\\n\", a != b);\n    printf(\"Mayor que: %d\\n\", a > b);\n    printf(\"Menor que: %d\\n\", a < b);\n    printf(\"Mayor o igual que: %d\\n\", a >= b);\n    printf(\"Menor o igual que: %d\\n\", a <= b);\n\n    // operadores logicos\n    a = 10;\n\n    printf(\"AND: %d\\n\", a > 5 && a < 15);\n    printf(\"OR: %d\\n\", a > 5 || a < 15);\n    printf(\"NOT: %d\\n\", !(a > 5 && a < 15));\n\n    // operadores de desplazamiento\n\n    a = 10;\n\n    printf(\"Desplazamiento a la izquierda: %d\\n\", a << 2);\n    printf(\"Desplazamiento a la derecha: %d\\n\", a >> 2);\n\n    // operadores de bits\n\n    a = 10;\n    b = 7;\n    printf(\"Bitwise AND: %d \\n\", a & b);\n    printf(\"Bitwise OR: %d \\n\", a | b);\n    printf(\"Bitwise XOR: %d \\n\", a ^ b);\n    printf(\"Bitwise NOT: %d \\n\", ~a);\n\n    // if else\n\n    if (a > b)\n    {\n        printf(\"a es mayor que b\\n\");\n    }\n    else\n    {\n        printf(\"a es menor que b\\n\");\n    }\n\n    // switch case\n\n    int option = 1;\n    switch (option)\n    {\n        case 1:\n        {\n            printf(\"Realizar el registro de n usuarios\\n\");\n            break;\n        }\n        case 2:\n        {\n            printf(\"Buscar usuario mediante su ID\\n\");\n            break;\n        }\n        default:\n        {\n            printf(\"Este caso no existe!\\n\");\n            break;\n        }\n    }\n\n    // for\n\n    for (int i = 1; i <= 10; i++)\n    {\n        printf(\"%d, \", i);\n    }\n    printf(\"\\n\");\n\n    // do while\n\n    option = 0;\n    do {\n        printf(\"Ingrese 1 para salir del ciclo\\n\");\n        scanf(\"%d\", &option);\n    } while (option != 1);\n    \n\n    // while\n\n    int i = 1;\n\n    while (i <= 10)\n    {\n        printf(\"%d, \", i);\n        i++;\n    }\n    printf(\"\\n\");\n\n    // Extra\n\n    for (int i = 10; i <= 55; i++)\n    {\n        if (i != 16 && i % 2 == 0 && i % 3 != 0)\n        {\n            printf(\"%d, \", i);\n        }\n    }\n    printf(\"\\n\");\n    \n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c#/Alfarog507.cs",
    "content": "using System;\n\nnamespace Alfarog507\n{\n    class Program\n    {\n        static void Main(string[] args)\n        {\n            /*EJERCICIO:\n            * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n            *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n            *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n            * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n            *   que representen todos los tipos de estructuras de control que existan\n            *   en tu lenguaje:\n            *   Condicionales, iterativas, excepciones...\n            * - Debes hacer print por consola del resultado de todos los ejemplos.\n            *\n            * DIFICULTAD EXTRA (opcional):\n            * Crea un programa que imprima por consola todos los números comprendidos\n            * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n            *\n            * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.*/\n\n            //Operadores aritméticos\n            int a = 5;\n            int b = 3;\n            Console.WriteLine(\"Operadores aritméticos\");\n            Console.WriteLine(\"Suma: \" + (a + b));\n            Console.WriteLine(\"Resta: \" + (a - b));\n            Console.WriteLine(\"Multiplicación: \" + (a * b));\n            Console.WriteLine(\"División: \" + (a / b));\n            Console.WriteLine(\"Módulo: \" + (a % b));\n\n            //Operadores lógicos\n            bool c = true;\n            bool d = false;\n            Console.WriteLine(\"\\nOperadores lógicos\");\n            Console.WriteLine(\"AND: \" + (c && d));\n            Console.WriteLine(\"OR: \" + (c || d));\n            Console.WriteLine(\"NOT: \" + (!c));\n\n            //Operadores de comparación\n            Console.WriteLine(\"\\nOperadores de comparación\");\n            Console.WriteLine(\"Igualdad: \" + (a == b));\n            Console.WriteLine(\"Desigualdad: \" + (a != b));\n            Console.WriteLine(\"Mayor que: \" + (a > b));\n            Console.WriteLine(\"Menor que: \" + (a < b));\n            Console.WriteLine(\"Mayor o igual que: \" + (a >= b));\n            Console.WriteLine(\"Menor o igual que: \" + (a <= b));\n\n            //Operadores de asignación\n            Console.WriteLine(\"\\nOperadores de asignación\");\n            Console.WriteLine(\"Asignación: \" + (a = b));\n            Console.WriteLine(\"Suma y asignación: \" + (a += b));\n            Console.WriteLine(\"Resta y asignación: \" + (a -= b));\n            Console.WriteLine(\"Multiplicación y asignación: \" + (a *= b));\n            Console.WriteLine(\"División y asignación: \" + (a /= b));\n            Console.WriteLine(\"Módulo y asignación: \" + (a %= b));\n\n            //Operadores de identidad\n            Console.WriteLine(\"\\nOperadores de identidad\");\n            Console.WriteLine(\"Igualdad: \" + (a == b));\n            Console.WriteLine(\"Desigualdad: \" + (a != b));\n\n            //Operadores de pertenencia\n            Console.WriteLine(\"\\nOperadores de pertenencia\");\n            int[] array = { 1, 2, 3, 4, 5 };\n            Console.WriteLine(\"Pertenece: \" + (Array.IndexOf(array, 3) != -1));\n            Console.WriteLine(\"No pertenece: \" + (Array.IndexOf(array, 6) == -1));\n\n            //Operadores de bits\n            Console.WriteLine(\"\\nOperadores de bits\");\n            Console.WriteLine(\"AND: \" + (a & b));\n            Console.WriteLine(\"OR: \" + (a | b));\n            Console.WriteLine(\"XOR: \" + (a ^ b));\n            Console.WriteLine(\"Desplazamiento a la izquierda: \" + (a << 1));\n            Console.WriteLine(\"Desplazamiento a la derecha: \" + (a >> 1));\n\n            //Estructuras de control\n            Console.WriteLine(\"\\nEstructuras de control\");\n            //Condicionales\n            if (a == b)\n            {\n                Console.WriteLine(\"a es igual a b\");\n            }\n            else if (a > b)\n            {\n                Console.WriteLine(\"a es mayor que b\");\n            }\n            else\n            {\n                Console.WriteLine(\"a es menor que b\");\n            }\n\n            //Iterativas\n            for (int i = 0; i < 5; i++)\n            {\n                Console.WriteLine(\"Iteración \" + i);\n            }\n\n            //Excepciones\n            try\n            {\n                int zero = 0;\n                int division = 5 / zero;\n            }\n            catch (DivideByZeroException e)\n            {\n                Console.WriteLine(\"Error: \" + e.Message);\n            }\n\n            //Dificultad extra\n            Console.WriteLine(\"\\nDificultad extra\");\n            for (int i = 10; i <= 55; i++)\n            {\n                if (i % 2 == 0 && i != 16 && i % 3 != 0)\n                {\n                    Console.WriteLine(i);\n                }\n            }\n\n            Console.ReadKey();\n\n\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c#/Andreavzqz.cs",
    "content": "using System;\n\nclass Program\n{\n    // Variable global para demostración\n    static int globalVariable = 100;\n\n    static void Main(string[] args)\n    {\n        // Operadores aritméticos\n        int a = 10;\n        int b = 3;\n        Console.WriteLine(\"Operadores aritméticos:\");\n        Console.WriteLine($\"a + b = {a + b}\"); // Suma\n        Console.WriteLine($\"a - b = {a - b}\"); // Resta\n        Console.WriteLine($\"a * b = {a * b}\"); // Multiplicación\n        Console.WriteLine($\"a / b = {(double)a / b}\"); // División\n        Console.WriteLine($\"a % b = {a % b}\"); // Módulo\n\n        // Operadores de comparación\n        Console.WriteLine(\"\\nOperadores de comparación:\");\n        Console.WriteLine($\"a == b: {a == b}\"); // Igual a\n        Console.WriteLine($\"a != b: {a != b}\"); // Diferente de\n        Console.WriteLine($\"a > b: {a > b}\"); // Mayor que\n        Console.WriteLine($\"a < b: {a < b}\"); // Menor que\n        Console.WriteLine($\"a >= b: {a >= b}\"); // Mayor o igual que\n        Console.WriteLine($\"a <= b: {a <= b}\"); // Menor o igual que\n\n        // Operadores lógicos\n        bool x = true;\n        bool y = false;\n        Console.WriteLine(\"\\nOperadores lógicos:\");\n        Console.WriteLine($\"x && y: {x && y}\"); // AND\n        Console.WriteLine($\"x || y: {x || y}\"); // OR\n        Console.WriteLine($\"!x: {!x}\"); // NOT\n\n        // Operadores de asignación\n        Console.WriteLine(\"\\nOperadores de asignación:\");\n        int c = 5;\n        Console.WriteLine($\"c = {c}\");\n        c += 3; // Equivalente a c = c + 3\n        Console.WriteLine($\"c += 3: {c}\");\n        c -= 2; // Equivalente a c = c - 2\n        Console.WriteLine($\"c -= 2: {c}\");\n        c *= 2; // Equivalente a c = c * 2\n        Console.WriteLine($\"c *= 2: {c}\");\n        c /= 4; // Equivalente a c = c / 4\n        Console.WriteLine($\"c /= 4: {c}\");\n        c %= 3; // Equivalente a c = c % 3\n        Console.WriteLine($\"c %= 3: {c}\");\n\n        // Operadores de bits\n        Console.WriteLine(\"\\nOperadores de bits:\");\n        int d = 6; // 110 en binario\n        int e = 3; // 011 en binario\n        Console.WriteLine($\"d & e: {d & e}\"); // AND bit a bit\n        Console.WriteLine($\"d | e: {d | e}\"); // OR bit a bit\n        Console.WriteLine($\"d ^ e: {d ^ e}\"); // XOR bit a bit\n        Console.WriteLine($\"~d: {~d}\"); // NOT bit a bit\n        Console.WriteLine($\"d << 1: {d << 1}\"); // Desplazamiento a la izquierda\n        Console.WriteLine($\"d >> 1: {d >> 1}\"); // Desplazamiento a la derecha\n\n        // Operadores de identidad (Referencia y valor)\n        Console.WriteLine(\"\\nOperadores de identidad:\");\n        string s1 = \"Hola\";\n        string s2 = \"Hola\";\n        Console.WriteLine($\"s1 == s2: {s1 == s2}\"); // Comparación de valor\n        Console.WriteLine($\"object.ReferenceEquals(s1, s2): {object.ReferenceEquals(s1, s2)}\"); // Comparación de referencia\n\n        // Operadores de pertenencia (usualmente usando listas o colecciones)\n        Console.WriteLine(\"\\nOperadores de pertenencia:\");\n        int[] array = { 1, 2, 3, 4, 5 };\n        Console.WriteLine($\"array contiene 3: {Array.Exists(array, element => element == 3)}\"); // Usando un método de Array para verificar pertenencia\n\n        // Estructuras de control\n        Console.WriteLine(\"\\nEstructuras de control:\");\n\n        // Condicionales\n        if (a > b)\n        {\n            Console.WriteLine(\"a es mayor que b\");\n        }\n        else\n        {\n            Console.WriteLine(\"a no es mayor que b\");\n        }\n\n        // Switch\n        switch (a)\n        {\n            case 10:\n                Console.WriteLine(\"a es 10\");\n                break;\n            default:\n                Console.WriteLine(\"a no es 10\");\n                break;\n        }\n\n        // Bucles\n        Console.WriteLine(\"\\nBucle for:\");\n        for (int i = 0; i < 5; i++)\n        {\n            Console.WriteLine(i);\n        }\n\n        Console.WriteLine(\"\\nBucle while:\");\n        int j = 0;\n        while (j < 5)\n        {\n            Console.WriteLine(j);\n            j++;\n        }\n\n        Console.WriteLine(\"\\nBucle do-while:\");\n        int k = 0;\n        do\n        {\n            Console.WriteLine(k);\n            k++;\n        } while (k < 5);\n\n        // Excepciones\n        Console.WriteLine(\"\\nExcepciones:\");\n        try\n        {\n            int result = a / 0;\n        }\n        catch (DivideByZeroException e)\n        {\n            Console.WriteLine(\"Excepción: División por cero.\");\n        }\n\n        // Uso de funciones \n        Saludar();\n        int suma = Sumar(5, 7);\n        Console.WriteLine($\"La suma de 5 y 7 es: {suma}\");\n\n        // Variables globales y locales\n        Console.WriteLine(\"\\nVariables globales y locales:\");\n        Console.WriteLine($\"Variable global: {globalVariable}\");\n        int localVariable = 50;\n        Console.WriteLine($\"Variable local: {localVariable}\");\n\n        // Dificultad extra: función FizzBuzz\n        int vecesImpreso = ImprimirNumeros(\"Fizz\", \"Buzz\");\n        Console.WriteLine($\"La función ImprimirNumeros se ejecutó {vecesImpreso} veces.\");\n    }\n\n    // Función sin parámetros ni retorno\n    static void Saludar()\n    {\n        Console.WriteLine(\"¡Hola desde la función Saludar!\");\n    }\n\n    // Función con parámetros y retorno\n    static int Sumar(int a, int b)\n    {\n        return a + b;\n    }\n\n    // Función FizzBuzz\n    static int ImprimirNumeros(string texto1, string texto2)\n    {\n        int vecesImpreso = 0;\n        for (int i = 1; i <= 100; i++)\n        {\n            if (i % 3 == 0 && i % 5 == 0)\n            {\n                Console.WriteLine(texto1 + texto2);\n                vecesImpreso++;\n            }\n            else if (i % 3 == 0)\n            {\n                Console.WriteLine(texto1);\n                vecesImpreso++;\n            }\n            else if (i % 5 == 0)\n            {\n                Console.WriteLine(texto2);\n                vecesImpreso++;\n            }\n            else\n            {\n                Console.WriteLine(i);\n            }\n        }\n        return vecesImpreso;\n    }\n}\n\n\n/*\nExplicación\n\nOperadores:\n\nAritméticos: Suma, resta, multiplicación, división, módulo.\nComparación: Igual a, diferente de, mayor que, menor que, mayor o igual que, menor o igual que.\nLógicos: AND (&&), OR (||), NOT (!).\nAsignación: Asignación simple (=), y combinada (+=, -=, *=, /=, %=).\nBits: AND (&), OR (|), XOR (^), NOT (~), desplazamiento a la izquierda (<<), desplazamiento a la derecha (>>).\nIdentidad: Comparación de valor (==) y de referencia (ReferenceEquals).\nPertenencia: Usando métodos de colecciones, como Array.Exists.\n\nEstructuras de control:\n\nCondicionales: if, else, switch.\nIterativas: for, while, do-while.\nExcepciones: try, catch.\n\nFunciones:\n\nSin parámetros ni retorno (Saludar).\nCon parámetros y retorno (Sumar).\nFizzBuzz (ImprimirNumeros).\n\nVariables globales y locales:\n\nGlobal: globalVariable.\nLocal: localVariable dentro de Main.\n\n*/\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c#/Angel-Delg.cs",
    "content": "using System;\n\nclass Program\n{\n   static void Main()\n   {\n      // Operadores Aritméticos\n      int num1 = 10;\n      int num2 = 5;\n      int suma = num1 + num2;\n      int resta = num1 - num2;\n      int multiplicacion = num1 * num2;\n      int division = num1 / num2;\n      int modulo = num1 % num2;\n      int potencia = (int)Math.Pow(num1, num2);\n\n      Console.WriteLine(\"Operadores Aritméticos:\");\n      Console.WriteLine($\"Suma: {suma}\");\n      Console.WriteLine($\"Resta: {resta}\");\n      Console.WriteLine($\"Multiplicación: {multiplicacion}\");\n      Console.WriteLine($\"División: {division}\");\n      Console.WriteLine($\"Módulo: {modulo}\");\n      Console.WriteLine($\"Potencia: {potencia}\");\n\n      // Operadores de Comparación\n      bool igual = (num1 == num2);\n      bool diferente = (num1 != num2);\n      bool mayorQue = (num1 > num2);\n      bool menorQue = (num1 < num2);\n      bool mayorOIgual = (num1 >= num2);\n      bool menorOIgual = (num1 <= num2);\n\n      Console.WriteLine(\"\\nOperadores de Comparación:\");\n      Console.WriteLine($\"Igual: {igual}\");\n      Console.WriteLine($\"Diferente: {diferente}\");\n      Console.WriteLine($\"Mayor que: {mayorQue}\");\n      Console.WriteLine($\"Menor que: {menorQue}\");\n      Console.WriteLine($\"Mayor o igual: {mayorOIgual}\");\n      Console.WriteLine($\"Menor o igual: {menorOIgual}\");\n\n      // Operadores Lógicos\n      bool andOp = (num1 > 0) && (num2 < 0);\n      bool orOp = (num1 > 0) || (num2 < 0);\n      bool notOp = !(num1 > 0);\n\n      Console.WriteLine(\"\\nOperadores Lógicos:\");\n      Console.WriteLine($\"AND: {andOp}\");\n      Console.WriteLine($\"OR: {orOp}\");\n      Console.WriteLine($\"NOT: {notOp}\");\n\n      // Operadores de Asignación\n      int a = 5;\n      a += 2;  // Equivalente a: a = a + 2\n      int b = 10;\n      b *= 3;  // Equivalente a: b = b * 3\n\n      Console.WriteLine(\"\\nOperadores de Asignación:\");\n      Console.WriteLine($\"a: {a}\");\n      Console.WriteLine($\"b: {b}\");\n\n      // Operadores de Desplazamiento\n      int desplazamientoIzquierda = num1 << 2;\n      int desplazamientoDerecha = num1 >> 2;\n\n      Console.WriteLine(\"\\nOperadores de Desplazamiento:\");\n      Console.WriteLine($\"Desplazamiento Izquierda: {desplazamientoIzquierda}\");\n      Console.WriteLine($\"Desplazamiento Derecha: {desplazamientoDerecha}\");\n\n      // Estructuras de Control - Condicionales\n      if (num1 > num2)\n      {\n         Console.WriteLine(\"\\nCondicionales:\");\n         Console.WriteLine(\"num1 es mayor que num2\");\n      }\n      else if (num1 == num2)\n      {\n         Console.WriteLine(\"num1 es igual a num2\");\n      }\n      else\n      {\n         Console.WriteLine(\"num1 es menor que num2\");\n      }\n\n      // Estructuras de Control - Iterativas (While)\n      Console.WriteLine(\"\\nIterativas (While):\");\n      int contador = 0;\n      while (contador < 5)\n      {\n         Console.Write(contador + \" \");\n         contador++;\n      }\n\n      // Estructuras de Control - Iterativas (Do-While)\n      Console.WriteLine(\"\\nIterativas (Do-While):\");\n      int otroContador = 0;\n      do\n      {\n         Console.Write(otroContador + \" \");\n         otroContador++;\n      } while (otroContador < 5);\n\n      // Estructuras de Control - Iterativas (For)\n      Console.WriteLine(\"\\nIterativas (For):\");\n      for (int i = 0; i < 5; i++)\n      {\n         Console.Write(i + \" \");\n      }\n\n      // Estructuras de Control - Excepciones\n      try\n      {\n         int resultado = num1 / 0;\n      }\n      catch (DivideByZeroException)\n      {\n         Console.WriteLine(\"\\n\\nExcepciones:\");\n         Console.WriteLine(\"Error: División por cero\");\n      }\n\n      \n      // Reto extra...\n      Console.WriteLine(\"Números entre 10 y 55 (incluidos), pares, que no son ni 16 ni múltiplos de 3:\");\n\n      for (int i = 10; i <= 55; i++)\n      {\n         if (i % 2 == 0 && i != 16 && i % 3 != 0)\n         {\n            Console.Write(i + \" \");\n         }\n      }\n   }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c#/Esaens12.cs",
    "content": "﻿using System.Threading.Channels;\r\n\r\nnamespace _01_OPERADORES_Y_ESTRUCTURAS_DE_CONTROL\r\n{\r\n    internal class Program\r\n    {\r\n        static void Main(string[] args)\r\n        {\r\n            /*\r\n   * EJERCICIO:\r\n   * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\r\n   *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\r\n   *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\r\n   * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\r\n   *   que representen todos los tipos de estructuras de control que existan\r\n   *   en tu lenguaje:\r\n   *   Condicionales, iterativas, excepciones...\r\n   * - Debes hacer print por consola del resultado de todos los ejemplos.\r\n   *\r\n   * DIFICULTAD EXTRA (opcional):\r\n   * Crea un programa que imprima por consola todos los números comprendidos\r\n   * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\r\n   *\r\n   * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\r\n   */\r\n\r\n            // Operadores aritméticos\r\n            int a = 10;\r\n            int b = 3;\r\n            Console.WriteLine(\"Operadores aritméticos:\");\r\n            Console.WriteLine($\"Suma: {a + b}\");\r\n            Console.WriteLine($\"Resta: {a - b}\");\r\n            Console.WriteLine($\"Multiplicación: {a * b}\");\r\n            Console.WriteLine($\"División: {a / b}\");\r\n            Console.WriteLine($\"Módulo: {a % b}\");\r\n\r\n            // Operadores lógicos\r\n            bool verdad = true;\r\n            bool falso = false;\r\n            Console.WriteLine(\"\\nOperadores lógicos:\");\r\n            Console.WriteLine($\"AND: {verdad && falso}\");\r\n            Console.WriteLine($\"OR: {verdad || falso}\");\r\n            Console.WriteLine($\"NOT: {!verdad}\");\r\n\r\n            // Operadores de comparación\r\n            Console.WriteLine(\"\\nOperadores de comparación:\");\r\n            Console.WriteLine($\"Igual a: {a == b}\");\r\n            Console.WriteLine($\"Distinto de: {a != b}\");\r\n            Console.WriteLine($\"Mayor que: {a > b}\");\r\n            Console.WriteLine($\"Menor que: {a < b}\");\r\n            Console.WriteLine($\"Mayor o igual que: {a >= b}\");\r\n            Console.WriteLine($\"Menor o igual que: {a <= b}\");\r\n\r\n            // Operadores de asignación\r\n            int c = 5;\r\n            Console.WriteLine(\"\\nOperadores de asignación:\");\r\n            c += 3;\r\n            Console.WriteLine($\"c += 3: {c}\");\r\n            c -= 2;\r\n            Console.WriteLine($\"c -= 2: {c}\");\r\n            c *= 2;\r\n            Console.WriteLine($\"c *= 2: {c}\");\r\n            c /= 4;\r\n            Console.WriteLine($\"c /= 4: {c}\");\r\n            c %= 3;\r\n            Console.WriteLine($\"c %= 3: {c}\");\r\n\r\n            // Operadores de identidad\r\n            object x = new object();\r\n            object y = x;\r\n            object z = new object();\r\n            Console.WriteLine(\"\\nOperadores de identidad:\");\r\n            Console.WriteLine($\"x es y: {ReferenceEquals(x, y)}\");\r\n            Console.WriteLine($\"x es z: {ReferenceEquals(x, z)}\");\r\n\r\n            // Operadores de pertenencia\r\n            int[] array = { 1, 2, 3, 4, 5 };\r\n            Console.WriteLine(\"\\nOperadores de pertenencia:\");\r\n            Console.WriteLine($\"3 en array: {Array.Exists(array, element => element == 3)}\");\r\n            Console.WriteLine($\"6 en array: {Array.Exists(array, element => element == 6)}\");\r\n\r\n            // Operadores de bits\r\n            int bit1 = 6; // 110 en binario\r\n            int bit2 = 3; // 011 en binario\r\n            Console.WriteLine(\"\\nOperadores de bits:\");\r\n            Console.WriteLine($\"AND bit a bit: {bit1 & bit2}\"); // 010\r\n            Console.WriteLine($\"OR bit a bit: {bit1 | bit2}\");  // 111\r\n            Console.WriteLine($\"XOR bit a bit: {bit1 ^ bit2}\"); // 101\r\n            Console.WriteLine($\"NOT bit a bit: {~bit1}\");       // 001...1010\r\n            Console.WriteLine($\"Desplazamiento a la izquierda: {bit1 << 1}\"); // 1100\r\n            Console.WriteLine($\"Desplazamiento a la derecha: {bit1 >> 1}\");   // 11\r\n\r\n            // Estructuras de control: Condicional\r\n            Console.WriteLine(\"\\nEstructuras de control: Condicional\");\r\n            if (a > b)\r\n            {\r\n                Console.WriteLine(\"a es mayor que b\");\r\n            }\r\n            else\r\n            {\r\n                Console.WriteLine(\"a no es mayor que b\");\r\n            }\r\n\r\n            // Estructuras de control: Iterativa (for)\r\n            Console.WriteLine(\"\\nEstructuras de control: Iterativa (for)\");\r\n            for (int i = 0; i < 5; i++)\r\n            {\r\n                Console.WriteLine($\"Iteración for: {i}\");\r\n            }\r\n\r\n            // Estructuras de control: Iterativa (while)\r\n            Console.WriteLine(\"\\nEstructuras de control: Iterativa (while)\");\r\n            int j = 0;\r\n            while (j < 5)\r\n            {\r\n                Console.WriteLine($\"Iteración while: {j}\");\r\n                j++;\r\n            }\r\n\r\n            // Estructuras de control: Iterativa (do-while)\r\n            Console.WriteLine(\"\\nEstructuras de control: Iterativa (do-while)\");\r\n            int k = 0;\r\n            do\r\n            {\r\n                Console.WriteLine($\"Iteración do-while: {k}\");\r\n                k++;\r\n            } while (k < 5);\r\n\r\n            // Estructuras de control: Manejo de excepciones\r\n            Console.WriteLine(\"\\nEstructuras de control: Manejo de excepciones\");\r\n            try\r\n            {\r\n                int divisionPorCero = a / 0;\r\n            }\r\n            catch (DivideByZeroException e)\r\n            {\r\n                Console.WriteLine($\"Excepción atrapada: {e.Message}\");\r\n            }\r\n\r\n            Console.WriteLine(\"\\nCiclo FOR para dificultad extra\");  // Ciclo for para pasar por una lista ENTRE 10 Y 55 (INCLUIDOS) con diferentes condiciones (PAR, DIFERENTE A 16 Y MULTIPLOS DE 3) \r\n\r\n            for(int i = 10; i <= 55; i++)\r\n            {\r\n                if(i % 2 == 0)\r\n                {\r\n                    if(i != 16)\r\n                    {\r\n                        if(i % 3 != 0)\r\n                        {\r\n                            Console.WriteLine(i);\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c#/FreddyASierraj.cs",
    "content": "﻿using System;\n\nnamespace RetosDeProgramacion\n{\n    internal class Operadores\n    {\n        public void aritmetic() {\n\n            // Operadores aritmeticos\n            int suma = 4 + 5;\n            int resta = 4 + 5;\n            suma++;\n            resta--;\n            Console.WriteLine($\"esto es una suma: {4 + 5}\");\n            Console.WriteLine($\"esto es una Resta: {4 - 5}\");\n            Console.WriteLine($\"esto es una Multiplicacion: {4 * 5}\");\n            Console.WriteLine($\"esto es una Division: {10 / 5}\");\n            Console.WriteLine($\"esto es un Modulo: {4 % 5}\");\n            Console.WriteLine($\"esto es un Incremento: {suma}\");\n            Console.WriteLine($\"esto es un Decremento: {resta}\");\n\n\n        }\n        //operadores de asignacion\n        public void assignement()\n        {\n            int x = 5;\n            int y = 5;\n            y ^= 3;\n            x |= 3;\n            Console.WriteLine($\"Operador de asignacion X = 5 {x}\");\n            Console.WriteLine($\"Operador de asignacion X +=3 {x+=3}\");\n            Console.WriteLine($\"Operador de asignacion X -=3 {x -= 3}\");\n            Console.WriteLine($\"Operador de asignacion X *=3 {x *= 3}\");\n            Console.WriteLine($\"Operador de asignacion X /=3 {x /= 3}\");\n            Console.WriteLine($\"Operador de asignacion X %=3 {x %= 3}\");\n            Console.WriteLine($\"Operador de asignacion X &=3 {x &= 3}\");\n            Console.WriteLine($\"Operador de asignacion X |=3 {x}\");\n            Console.WriteLine($\"Operador de asignacion X ^=3 {y}\");\n            Console.WriteLine($\"Operador de asignacion X >>=3 {x >>= 3}\");\n            Console.WriteLine($\"Operador de asignacion X <<=3 {x <<= 3}\");\n\n        }\n        //Operadores de comparacion\n        public void comparison()\n        {\n            int x = 5;\n            int y = 3;\n            Console.WriteLine($\"Operador de asignacion Igual que == {x == y}\");\n            Console.WriteLine($\"Operador de asignacion No Igual  != {x != y}\");\n            Console.WriteLine($\"Operador de asignacion Mayor que > {x > y}\");\n            Console.WriteLine($\"Operador de asignacion Menor que < {x < y}\");\n            Console.WriteLine($\"Operador de asignacion Mayor Igual que >= {x >= y}\");\n            Console.WriteLine($\"Operador de asignacion Menor Igual que <= {x <= y}\");\n\n\n        }\n        //Operadores Logicos\n        public void logicos() {\n\n            int x = 5;\n            int y = 3;\n            Console.WriteLine($\"Operador Logico AND && {x>4 && y<4}\");\n            Console.WriteLine($\"Operador Logico OR || {x > 4 || y < 1}\");\n            Console.WriteLine($\"Operador Logico NOT ! {!(x > 4 && y < 4)}\");\n            Console.WriteLine();\n\n            int a = 1; int b= 2;\n            if (a==1)\n            {\n                Console.WriteLine($\"ejemplo condicinal if {a}\");\n            }\n            else\n            {\n                Console.WriteLine($\"Ejemplo condicional else {b}\");\n            }\n            Console.WriteLine();\n            int diaSemana = 6;\n            switch (diaSemana)\n            {\n                case 0: Console.WriteLine(\"Esto es un switch\");\n                break;\n                case 1: \n                    Console.WriteLine(\"Lunes\");\n                break;\n                case 2:\n                    Console.WriteLine(\"Martes\");\n                    break;\n                case 3:\n                    Console.WriteLine(\"Miercoles\");\n                    break;\n                case 4: \n                    Console.WriteLine(\"Jueves\");\n                    break;\n                case 5:\n                    Console.WriteLine(\"Viernes\");\n                    break;\n                 case 6:\n                    Console.WriteLine(\"Sabado\");\n                    break;\n            }\n            Console.WriteLine(\"Esto es una excepcion \");\n            try\n            {\n                int[] myNumbers = { 1, 2, 3 };\n                Console.WriteLine(myNumbers[10]);\n            }\n            catch (Exception e)\n            {\n                Console.WriteLine(e.Message);\n            }\n\n\n        }\n        public void iteradores() { \n\n            for (int i = 0; i < 5; i++) {\n                Console.WriteLine($\"Esto es un bucle for: {i}\");\n            }\n            Console.WriteLine(\"\");\n            int f = 0;\n            while (f<5) {\n                \n                Console.WriteLine($\"Esto es un bucle While {f}\");\n                f++;\n            }\n            Console.WriteLine();    \n            int g = 0;\n            do { \n                Console.WriteLine($\"Esto es un Bucle Do-While {g}\");\n                g++;\n            } while (g<5);\n\n            Console.WriteLine();\n\n            string[] carros = {\"mazda\",\"renault\",\"Chevrolet\",\"BMW\",\"Mercedes\" };\n            foreach (var car in carros)\n            {\n                Console.WriteLine($\"Este es el bluche ForEach {car}\");\n            }\n            \n        }\n        public void extra() {\n\n            for (int i = 10; i <= 55; i++)\n            {\n                if (i%2==0 && i !=16 && i%3 !=0)\n                {\n                    Console.WriteLine($\"Los numeros pares: {i}\");\n                }\n            }\n        \n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c#/HazartD.cs",
    "content": "using System; //Primero que nada, pense que a lo mejor este seria mas facil,\nusing System.Collections.Generic; // porque el anterior me llevo como 6 horas en hacer.\nusing System.Linq; //Pero cuando busque en el doc los operadores que hay en C#,\nusing System.Text; //la parte de operadores tiene 12 entradas.\nclass Ejercicio1 {\n    public enum TEST{YUCAFRITA, ATOLCHUCO, QUESADILLA, PANCONPOLLO, PUPUSA} // Los enum al ser constantes no pueden ir dentro de metodos, si lo pusieras ahi empezaria a tirar errores por cada linea de la funcion.\n    static void Main(){\n        //descubri que esto es porque los projectos ejecutan de inicio una unica funcion estatica llamada Main\n        //como al crear con consola un proyecto sale un nuevo archivo con ese Main, estube peleando con el vscode por como 2 horas para descubrilo xddd\n    \n    //creare 3 variables de estos 2 para probarlos.\n        byte a = 1;\n        byte b = 2; //los iba a poner como variables publicas arriba\n        byte c = 3; //pero marca errores \n        sbyte d = -1;\n        float fa = 1.1f; //«Se requiere una referencia de objeto para el campo, método o propiedad 'Ejercicio1.a' no estáticos»\n        float fb = 2.2f; //creo que solo es que no puede usar nada no estatico dentro de funciones estaticas\n        float fc = 3.3f; //igual se podrian poner ambas, poner las goblales arriba y luego las locales igualadas\n\n        Console.WriteLine(\"\\nAritmeticos Y Asignacion\\n\\n\");\n        Console.WriteLine($\"\\nIncremento\\nAl poner «a++», se le sumara 1 a «a», pero usarlo dara el valor de antes de la operacion. Valor de a: {a++}\");\n        Console.WriteLine($\"Valor actual de a: {a}\");\n        Console.WriteLine($\"Pero, al poner «++a», se le sumara 1 a «a» y quedara ya como con su valor sumado. Valor de a: {++a}\");\n        Console.WriteLine($\"\\nDecremento\\nPasa lo mismo poniendo «--a» y «a--», solo que esto resta 1 a «a». Valor de a:{a--}\");\n        Console.WriteLine($\"Valor actual de a: {a}\");\n        Console.WriteLine($\"Valor de a con --a:{--a}\");\n        Console.WriteLine(\"\\nEstos 2 son los unicos operadores que cambian el valor almacenado en la variable. Los siguientes no.\");\n\n        Console.WriteLine(\"\\nUnarios\\nEstos son como los signos + y - normales de algebra.\");\n        Console.WriteLine(\"Poner + antes de una variable te dara la variable sin cambios, y ponerle - te dara su opuesto.\");\n        Console.WriteLine(\"Si la variable es positiva te dara negativo y viceversa.\");\n        Console.WriteLine($\"Teniendo el float «fa» con valor:{fa}. Al escribir «+fa» su valor no cambia: {+fa}. Pero poniendole «-fa»: {-fa}. Y a su vez si pongo «-(-fa)»:{-(-fa)}\");\n        /*\n        La doc menciona (y comprobe) que el unico tipo con el que no es compatible el - es el ulong.\n        Interpreto que esto se debe modo de prevenir errores graves si el valor sobrepasa el minimo\n        que puede almacenar el long. De modo que la computadora no podria procesarlo. Yo me entiendo xd.\n        */\n        Console.WriteLine($\"\\nMultiplicacion\\nPoner «*» entre 2 variables o numeros te los multiplica. Teniendo b={b} y fb={fb}. Este es el valor de «b*fb»{b*fb}.\");\n        Console.WriteLine($\"\\nDivicion\\nPoner «/» entre 2 variables o numeros te los divide. Este es el valor de «b/fb»{b/fb}.\");\n        Console.WriteLine($\"La divicion da la precicion mas alta que tengan los valores usados; ya sea float, double o decimal. Usando solo int, se omitiran los decimales. Valor de «b/a»: {b/a}\");\n        Console.WriteLine($\"Valor de «a/b»: {a/b}\");\n        Console.WriteLine($\"Valor de «678.997m/1»: {678.997m/1}.\\nPor algun motivo, la doc quizo omitir que debes poner «d» a final de un double y «m» al final de un decimal.\");\n\n        Console.WriteLine($\"\\nModulo\\nPoniendo «%» entre 2 variables o numeros. Teniendo c={c}, «a%c» da:{a%c} y «c%a» da:{c%a}\");\n        Console.WriteLine(\"Con los decimales float y double, si «x%y» teniendo «z=|x| / |y|» redondeando decimales hacia abajo y siendo del mismo signo que «x», se calculan como «|x| - n * |y|»\");\n        Console.WriteLine($\"Por ejemplo, «fa%fc» da: {fa%fc} y «fc%fa» da:{fc%fa}\");\n        Console.WriteLine($\"Los decimal tienen su propia formula interna para modulos, pero la doc no la especifica\");\n        Console.WriteLine(\"En caso de los double, se pueden calcular tambien con el metodo «Math.IEEERemainder». Ya que la formula mencionada es analoga a la del entero, pero omitiendo la «especificación IEEE 754»\");\n        Console.WriteLine(\"Si se tienen «x/y» el metodo mencionado calcula el modulo asi: «x - (y * Math.Round(x / y))»\");\n        Console.WriteLine($\"Con «-16.3 % 4.1» da: {-16.3 % 4.1}. Y con «Math.IEEERemainder(-16.3, 4.1)» da: {Math.IEEERemainder(-16.3, 4.1)}\");\n\n        Console.WriteLine(\"\\nSuma y Resta\\nPues lo que dice, con + sumas 2 weas y con - las restas\");\n        Console.WriteLine($\"1+1={1+1} y 1-1={1-1}\");\n        Console.WriteLine(\"Pero, el + tambien se puede usar para unir 2 string. La segunda se pone al final de la primera.\");\n        Console.WriteLine(\"Y aqui empieza un problema, que resumire como pueda. Hay variables de referencia llamadas lambda que pueden ser una onda llamada delegados.\");\n        Console.WriteLine(\"Estos delegados son una linea de instruncion de una funcion basicamente. Puede ponerse un «var» que sume las variables delegadas, volviendo esa var otro delegado que ejecuta las iniciales en el orden que lo pones.\");\n        Console.WriteLine(\"Y tambien se pueden restar, segun cierto modo en que lo escribas puede que en realidad no pase nada al cambiarlo, que facilmente me podria quedar a leer y ejemplificar.\");\n        Console.WriteLine(\"Pero ya son las 10 pm y me quiero dormir. No hay un «XD», tengo sueño y la laptop no aguanta VScode y 2 pestañas de google a la vez por mucho tiempo.\");\n\n        Console.WriteLine($\"\\nAsignadores compuestos\\n Son solo poner los operadores mencionados antes del =\");\n        Console.WriteLine($\"Escribir «a+=b» es lo mismo (o incluso mas eficiente) que «a=a+b». Valor de «a*=b»:{a*=b}\");\n        Console.WriteLine($\"Valor de «a/=b»:{a/=b}\");\n\n        Console.WriteLine(\"\\nOtras indicaciones\\n\");\n        Console.WriteLine(\"Puedes poner (*un tipo*) antes de una operacion para que el resultado se convierta a ese tipo o asegurarte de que no cambie el tipo de la variable a la que se asigna.\");\n        Console.WriteLine(\"Ejemplo: «a=(byte)a*fa». Convierte el resultado tipo float a byte, ya que se le tiene que asignar a «a»\");\n        Console.WriteLine(\"Cuando una operacion sobrepasa el numero maximo de un tipo (Ejemplo: «x= int.MaxValue +1») se da una OverflowException, mas adelante se explicara que son las excepciones, que ni yo sé todavia xd\");\n        Console.WriteLine(\"Es importante mencionar que esa excepción y la DivideByZeroException (dividir entre 0) solo afectan a enteros y Decimal\");\n        Console.WriteLine(\"Los float y double no producen estas excepciónes, tienen las constantes .NegativeInfinity y .PositiveInfinity para cuando pasa del maximo, y la constante .NaN para dividir entre 0\");\n        Console.WriteLine(\"Tambien hay errores de redondeo para todos los decimales (limitaciones de representacion). Por ejemplo, «decimal a= 3 (1/3)» deberia ser 1, pero por el error de redondeo equivale a: 0.9999999999999999999999999999\");\n        \n\n        Console.WriteLine(\"\\n\\nLogicos booleanos\\n\\n\");\n        Console.WriteLine($\"Esta el «!», el NOT, un «prefijo unario» que invierte los true a false y asi. Valor de !true: {!true}. Valor de !false: {!false}.\\nEl «!» como posfijo permite valores NULL (lo que sea que signifique).\");\n        Console.WriteLine($\"El «&» es AND. Si los 2 valores son true el resultado es true, pero aunque el primero sea false procesa el segundo, poniendo «&&» se evita el segundo calculo.\\nValor de «true & true»:{true & true}. Valor de «false && true»:{false&&true}.\");\n        Console.WriteLine($\"El «^» es el «OR exclusivo lógica, conocido como operador XOR lógico». Da true si los que opera son distintos y false si son iguales. Valor de «true ^ true»:{true ^ true}. Valor de «false ^ true»:{false^true}.\");\n        Console.WriteLine($\"El «|» es OR, es como el «&» pero dando true si algunos es true. Pasa lo mismo con el «&&» y «||». Valor de «false | false»:{false|false}. Valor de «true || false»:{true||false}.\");\n        Console.WriteLine(\"Los | y & tambien funcionan con los «bool?», pero no pueden operar «null *| o &* null». Puesto que el error que saldria dice que el operador «es ambiguo en operandos del tipo '<NULL>' y '<NULL>'»\");//Para & y | daran null si ambos operandos son null. «null & null»: {null&null}.«null | null»: {null|null}.\");\n        Console.WriteLine($\"Para &, si alguno es false, dara false, para dar null uno tiene que ser true. true & null= {true & null}. null & true= {null & true}.\");\n        Console.WriteLine($\"Para |, si alguno es true, dara true, para dar null uno tiene que ser false. false | null= {false | null}. null | false= {null | false:S}.\");\n        \n        Console.WriteLine(\"\\nAhora, solo para complicarme la vida: el & solito tambien es un «operador relacionado al puntero»\");\n        Console.WriteLine(\"Es una verga llamada «address-of» que te da la direccion en la memoria de una variable.\");\n\n        Console.WriteLine(\"Se supone que si declaras una variable asi «unsafe{byte* pointer = &a;...}» y luego te escribo «(long)pointer:X» saldra esa direccion.\");\n        Console.WriteLine(\"La doc menciona que hay variables fijas (para las que sirve esto) y moviles (para las que no) como los array y objetos. Pero que esas tambien hay modo de fijarlas.\");\n        Console.WriteLine(\"Para ello, pones unas «{}» para hacer un bloque, pones tipo «fixed (byte* pointer = &a)» y te servira solo para ese bloque.\");\n        Console.WriteLine(\"Parece ser importante que la variable de la posicion, la del *, sea del mismo tipo que la que se opera o un void.\");\n        Console.WriteLine(\"Otro punto importante es que para que el compilador ejecute lo que hay en bloques unsafe debes habilitarle una opcion.\");\n        Console.WriteLine(\"De no ser porque no se donde cambiarlo, lo habria mostrado, ya habia terminado de escribirlo cuando vi que no se podia.\");\n\n        \n        Console.WriteLine(\"\\n\\nComparadores e Identidad\\n\\n\");\n        Console.WriteLine(\"\\nLos meti en lo mismo porque crei que eran lo mismo, despues vi que se clasificaban distinto xd.\\n\");\n        Console.WriteLine(\"Es solo son los ya sabidos mayor que, menor que e iguales que ya enseñan en clases:\");\n        Console.WriteLine(\"«<», «<=», «>», «>=». Tambien esta el operador «==» que comprueva si los dos valores son iguales y «!=» que son distintos.\");\n        Console.WriteLine(\"Ejemplos:\");\n        Console.WriteLine($\"a<=c: {a<=c}   a>=c: {a>=c}   a<fa: {a<fa}   a>fa: {a>fa}   a==a: {a==a}   a==b: {a==b}   a!=a: {a!=a}  a!=b: {a!=b}\");\n        Console.WriteLine(\"Operar «x!=y» es lo mismo que«!(x == y)=», ya que este da el boleano opuesto, false si son iguales y true a contrario.\");\n        Console.WriteLine($\"Usar la constante .NaN de cualquier decimal con un comparador siempre dara false, aunque sea «double.NaN == double.NaN»: {double.NaN == double.NaN}\");\n        Console.WriteLine(\"\\nDe ahi para arriba van las igualdades de tipos complejos que no hemos visto, mas o menos he buscado pero no se mucho todavia.\");\n        Console.WriteLine(\"Por ejemplo, como se menciono en el antrior, el == puede dar true a 2 strings con el mismo contenido, pero no el object.ReferenceEquals ya que no refieren al mismo objeto.\");\n        Console.WriteLine(\"Lo mismo pasa con los delegados que mencionamos. Con ambos tambien pasa que dan true en == si las 2 variables son null\");\n            \n            {uint ba = 0b_1111_1111;\n            uint bb =  ba;\n            bb=~bb;\n            Console.WriteLine(\"\\n\\nBit a bit y desplazamiento\\n\\n\");\n            Console.WriteLine(\"Creo, tengo entendido, que los bit a bit se referiere a que operan los propios bits y va mejor el procesador. Esos operadores son validos para los char y los numericos enteros.\");\n            Console.WriteLine(\"Estan hechos para los int, uint, long y ulong. Cualquier otro valor aplicable se convierte a int, el cual tambien es el tipo del resultado. Tambien funcionan con la asignacion compuesta y conversion que mencionamos antes.\");\n            Console.WriteLine(\"Por cierto, los operadores para los que aplica la asignacion compuesta son los «binarios», llamados asi porque los pones entre 2 operandos. Los otros son unarios. En este caso, los operadores de bits se parecen a los logicos.\");\n            Console.WriteLine(\"Para este ejemplo las variables «ba» y «bb» son uint.\");\n            Console.WriteLine($\"\\nComplemento (unario). El NOT. Con «~» inviertes los bits de otra onda. Si el valor de «ba» es: {ba} y en bits: {Convert.ToString(ba, toBase: 2)} y declaro el valor de «bb» es «~ba»: {bb} y en bits: {Convert.ToString(bb, toBase: 2)}. Como el resultado siempre es int, todos los 1 que bb tiene de mas son los 0 que ba no muestra.\");//Complemento. Con «~» inviertes los bits de otra onda. Si el valor de «ba» es:252645132 y declaro el valor de «bb» como «~ba»: 4042322163\n            Console.WriteLine($\"\\nAND &. Compara los bits en la misma posicion de cada operando, si ambos tienen un 1 en una posicion, el resultado tendra 1 en esa posicion, de lo contrario sera 0. Valor de «ba &= 0b_1010_1001»: {ba &= 0b_1010_1001} y en bits: {Convert.ToString(ba, toBase: 2)}.\");\n            Console.WriteLine($\"\\nOR |. Siguiendo el tema, si ambos son 0 el resultado tendra 0 en esa posicion, de lo contrario sea 1. Valor de «ba |= 0b_0101_0101»: {ba |= 0b_0101_0101} y en bits: {Convert.ToString(ba, toBase: 2)}.\");\n            Console.WriteLine($\"\\nXOR ^. Igualmente, si ambos son distintos dara 1 en esa posicion, de lo contrario es true. Valor de «ba ^= bb»: {ba ^= bb} y en bits: {Convert.ToString(ba, toBase: 2)}.\");\n            Console.WriteLine($\"\\n<<. Deplaza el bit de la izquierda la cantidad de pociones que indique el operando de la derecha, reemplazando por 0 las posiciones vacias. Valor de «ba =<< 5»: {ba <<= 5} y en bits: {Convert.ToString(ba, toBase: 2)}.\");\n            Console.WriteLine($\"\\n>>. Lo mismo a la izquierda. Si el numero izquierdo es int o long y es negativo, se rellenan con 1, si es positivo con 0. Si son uint o ulong siempre es 0. Valor de «ba >>= 3»: {ba >>= 3} y en bits: {Convert.ToString(ba, toBase: 2)}.\");\n            Console.WriteLine($\"\\n>>>. Desplazamiento a la izquierda, pero siempre rellena con 0. Valor de «ba >>>= 2»: {ba >>>= 2} y en bits: {Convert.ToString(ba, toBase: 2)}.\");\n            Console.WriteLine($\"\\nLa prioridad que tienen los operadores de bits de mayor(primero) a menor(ultimo): ~, <<, >>, >>>, &, ^ y |.\");}\n\n\n\n        {   Console.WriteLine(\"\\n\\n\\nOtros que me salieron en la doc\\n\\n\\n\");\n            byte[] numeros = new byte[8]{0,1,2,4,8,16,32,64};\n            Console.WriteLine($\"Teniendo el array numeros: {string.Join(\", \",numeros)}\");\n            Console.WriteLine($\"Ya se sabe que con «[]» accedes a un valor de una coleccion, ejemplo «numeros[1]»: {numeros[1]}. Pero con el «^», el valor se toma empezando a contar desde el final, ejemplo «numeros[^1]»: {numeros[^1]}.\");\n            Console.WriteLine($\"Por otro lado, con «..» se accede al intervalo de la coleccion.\\nnumeros[0..3] = {string.Join(\", \",numeros[0..3])}\\nnumeros[3..^1] = {string.Join(\", \",numeros[3..^1])}\\nnumeros[3..^3] = {string.Join(\", \",numeros[3..^3])}\\nnumeros[..3] = {string.Join(\", \",numeros[..3])}\\nnumeros[3..] = {string.Join(\", \",numeros[3..])}\");\n            Console.WriteLine(\"\\nComo se noto, si solo pones un lado se continua al otro hasta donde llega. Y dejando solo el «[..]» da todos los elementos y ya. Cuidando de no poner al revez los numeros del rango, cuanta como que exediste la cantidad que hay y produce una excepción.\");\n           \n            Console.WriteLine($\"Otra funcion que tiene es la de concatenar arreglos. Si declaras un array como «int[] array3= [array0,array1,array2]» dara un error, ya que estas haciedo un array de arrays, debes poner: «int[][]»\");\n            Console.WriteLine($\"Para ponerlos en un solo array debes poner «int[] array3= array0.Concat(array1).Concat(array2).ToArray».\\nO simplemente «int[] array3= [..array0,..array1,..array2]»\");\n            \n            Console.WriteLine(\"\\nEl «is» comprueba si una variable es de un tipo concreto, como se pone el tipo del mismo modo en que se declararia una variable, si es true se puede asignar el mismo valor a una variable.\");\n            Console.WriteLine($\"«numeros[3] is byte»: {numeros[3] is byte}. «numeros[3] is byte numa»: {numeros[3] is byte numa}. «numa»: {numa}\");\n            Console.WriteLine(\"Puede usarse junto al [..] para saber si los valores escritos estan presentes en un array. Tambien da true al comparar una clase con una clase de la que herede.\");\n            \n            Console.WriteLine($\"\\nPara convertir un tipo en otro esta el operador «as» y la exprecion cast, que es la usada en «Otras indicaciones». «Se debe usar con un tipo de referencia o un tipo que acepte valores NULL». Valor de «100.2424m as int?»{100.2424m as int?}\");\n            Console.WriteLine($\"\\nEl «typeof(*tipo*)» regresa como esta en el System el tipo puesto como argumento. No se debe poner una variable o exprecion como argumento, en ese caso se le pone «.GetType()». No se pueden poner «dynamic» y los que aceptan null, se pone «object» y el tipo normal.\");\n            Console.WriteLine($\"typeof(Dictionary<,>): {typeof(Dictionary<,>)}\\nnumeros.GetType(): {numeros.GetType()}\\nnumeros.GetType() == typeof(byte[]): {numeros.GetType() == typeof(byte[])}\");\n            \n            Console.WriteLine(\"\\nAl poner «ref» cuando se asigna un valor en base a una variable, esa nueva variable tiene una referencia a la primera.\");\n            \n            Console.WriteLine(\"\\nSe usa «::» para acceder a los namespace, lo que se pone arriba como using, iria tipo «global::System.Console.WriteLine(\\\"Using global alias\\\")».\");\n            \n            int porDefecto = default;\n            Console.WriteLine($\"\\nCon «default» se saca el valor por defecto de un tipo. default(int): {default(int)}. int porDefecto = default: {porDefecto}.\");\n            \n            Console.WriteLine($\"Con «nameof(*casi lo que sea*)» te genera el nombre de algo en tiempo de compilacion. Los @ al inicios de variables no cuentan.\\nnameof(System.Collections.Generic):{nameof(System.Collections.Generic)}\\nnameof(numeros):{nameof(numeros)}\");\n            \n            Console.WriteLine(\"\\nEsta en la doc por algun motivo el «new» para crear instancias como un operador.\");\n\n            Console.WriteLine($\"\\nEsta para los contextos unsafe el «sizeof(*un tipo*)» que muestra los bytes que ocupa un tipo de dato, tambien se puede usar sin unsafe con los tipos nativos y un nombre de enum.\\nsizeof(byte): {sizeof(byte)}\\nsizeof(TEST):{sizeof(TEST)}.\");\n            Console.WriteLine($\"En este caso, regresa el espacio del tipo que son cada elemento del enum, que por defecto es int. TEST:{TEST.YUCAFRITA}, {TEST.ATOLCHUCO}, {TEST.QUESADILLA}, {TEST.PANCONPOLLO}, {TEST.PUPUSA}.\");\n\n            Console.WriteLine(\"\\nCon «whith» se crea un objeto en base a otro con cambios. «var object2 = object1 whith {propiedadCambiada= \\\"nuevo valor\\\"}»\");\n\n            Console.WriteLine(\"\\nTambien se puede usar las palabras «operator», «implicit» y «explicit» para crear operadores, pero esa madre me va extender mucho mas esto xd.\\n\");}\n        \n        \n        \n        Console.WriteLine(\"\\n\\n\\nEstructuras de Control\\n\\n\\n\"); //los if, else y elif o else if siempre se han hecho muy faciles de comprender\n        \n        \n        \n        Console.WriteLine(\"\\nif, else y else if o elif\\n\"); //no los explicare, si a alguien le da problemas, «if» es tipo «si pasa tal cosa has esto» y «else» es «si no paso, has lo otro»\n        if (a.GetType() == d.GetType()){Console.WriteLine(\"Tanto «a» como «d» son byte o sbyte\");}//1\n        else if (a.GetType() == typeof(sbyte) && d.GetType() == typeof(byte)){Console.WriteLine(\"«a» es un sbyte y «d» un byte\");}//2\n        else if (a is byte && d is sbyte){Console.WriteLine(\"«a» es un byte y «d» un sbyte\");}//3\n        else {Console.WriteLine(\"Ni «a» ni «d» son byte o byte\");}//4\n        Console.WriteLine(\"Cuando en un if usas «&&» para saber si se cumplen mas de una condicion, lo estas volviendo una operacion logica como la vista anteriormente. Esta probando si ambos valores son true.\");\n/*\nALGO (no) MUY IMPORTANTE:\n2 y 3 hacen la misma comprobacion, pero 3 tira el error «warning CS0183: La expresión dada siempre es del tipo proporcionado»\nSi 2 estuviera escrita del mismo modo que 3, tiraria «warning CS0184: La expresión dada nunca es del tipo proporcionado»\nYa que como son variables declaradas con su tipo, hacer esa comprobacion es estupido e innecesario.\nSin embargo, «GetType» se llama en tiempo de ejecucion, por tanto el compilador no sabe que regresara hasta que lo haga.\nPareceria util de saber, pero a menos que uses dynamic o var (que no se si funcionen como creo), es un dato muy inutil.\n\nPor cierto, «typeof» solo acepta tipos, no puedes usarlo para sacar el tipo de una variable.\n*/\n        Console.WriteLine(\"\\nTambien, dentro de los if y else estan los operadores ternarios. No deberian de tenerse muchos, pero cuando solo hay un if y su else, es util.\");\n        Console.WriteLine(\"Al asignar valor a una variable puedes poner entre «()» una condicion, signo «?» y las 2 vertientes separadas por «:». La primera es para true y la segunda para false\");\n        Console.WriteLine(\"Ejemplo «string mensaje = (edad >= 18)?\\\"Mayor de edad\\\":\\\"Menor de edad\\\"»\");\n        {   int edad =18;\n            string mensaje = (edad >= 18)? \"Mayor de edad\":\"Menor de edad\";\n            Console.WriteLine($\"edad: {edad}. mensaje: {mensaje}.\");\n        Console.WriteLine( \"Del mismo modo, puedes usar «?» para no necesitar usar if y else para comprobar que algo no sea null, ya que si el codigo siguiera en caso como ese generaria errores.\");\n           int? na=null,nb=1,nc=0;\n            string?[]? nd=null;\n            Console.WriteLine(\"Si quiero usar el valor de una variable que puede ser un null, en vez de poner «if *variable*!=null» puedes poner «*variable* ?? *valor por defecto*».\");\n            Console.WriteLine($\"Teniendo los valores: «na=null», «nb=1» y «nc». Valor de «nc= na ?? nb»: {nc= na ?? nb}\");\n            Console.WriteLine(\"Igualmente, para usar metodos o propiedades de un objeto que puede ser null o tener un null se pone «?» despues de cada cosa, antes del punto. Segun la doc se le llama «operador elvis» xddd\");\n            Console.WriteLine($\"Teniendo «string?[]? nd= null». Valor de «nd?.Length»: {nd?.Length}.\");\n            Console.WriteLine(\"Ahora, asignandole «nd= new string?[]{null,\\\"Digimon GOD\\\"}»\");\n            nd= new string?[2]{null,\"Digimon GOD\"};\n            Console.WriteLine($\"Valor de «nd?.Length»: {nd?.Length}.\");\n            Console.WriteLine($\"Valor de «nd?[0]?.Length»: {nd?[0]?.Length}. Valor de «nd?[1]?.Length»: {nd?[1]?.Length}.\");}\n\n        Console.WriteLine(\"\\nswitch\\n\");\n            Console.WriteLine(\"Aqui pones una variable o algo que regrese un valor y vas poniendo «case *valor posible*:» y que se ejecute una linea. Tambien el «dafault» para cualquier valor que no coindida\");\n        switch (d.GetType()){ //\n            case Type t when t == typeof(int):// he probado mil formas distintas de poner estos case\n                Console.WriteLine(\"No, «d» no es sbyte, es un int\");\n                break; //al final me funciono esta que es de chat gpt\n            case Type t when t == typeof(long): //y no la entiendo \n                Console.WriteLine(\"No, «d» no es sbyte, es un long\");\n                break;// si quitas el «when t =» y dejas como si fuera variable, el System.tipo correspondiente o solo el metodo no funciona\n            case Type t when t == typeof(sbyte): //Bueno, el punto es que debesponer «case *posible valor constante de la exprecion*:»\n                Console.WriteLine(\"¿Para que compruebas de nuevo, imbecil? «d» es un sbyte\");\n                break;//y de ahi pones el codigo y de ultimo un «break»\n            default://este ultimo se ejecuta cuando no coincide con ninguna opcion de arriba\n                Console.WriteLine(\"No se reconocio el tipo de «d»\");\n                break;}\n            Console.WriteLine(\"Una alternativa a los que dependen de valores numericos, es poner un array de Accions y que acceda a la pociones correspondiente.\");\n            Console.WriteLine(\"¿Que es un accion? no se bien, pero creo que son esos delegados, que son funciones.\");\n            \n\n        Console.WriteLine(\"\\nwhile\\n\");\n        Console.WriteLine(\"El while comprueba condicion, ejecuta codigo, comprueba condicion y repite Hasta que deje de cumplirce.\");\n        Console.WriteLine(\"Cuando la condicion sea false se detendra el bucle y continuara el codigo.\");\n        // este parentesis de llave hace que lo que este dentro exista solo dentro de ahi, no puedes usar las variables fuera. Creo que lo use mas veces arriba, pero lo primero que hize fue esto ultimo.\n        {dynamic[] lista = new dynamic[4] {0.0f,1,false,\"aa\",};\n            Console.WriteLine(\"Lista: {0}\",lista);\n            int n=0; \n        while (lista[n].GetType()!= typeof(string)){\n            Console.WriteLine($\"«n»({n}) no coincide con el indice de una string dentro de «lista»\");\n            n++;}\n        Console.WriteLine($\"«n»({n}) coincide con el indice de una string dentro de «lista»\");\n\n        Console.WriteLine(\"\\ndo while\\n\");\n        Console.WriteLine(\"Esto es lo mismo al revez, ejecuta, comprueba, ejecuta y repite.\");\n        Console.WriteLine(\"Me gusta relacionarlo con cuando te dicen «haz x cosa si pasa y cosa» y ya lo estabas haciendo.\");\n        do {\n            Console.WriteLine($\"«n»({n}) no coincide con el indice de un float dentro de «lista»\");\n            n--;\n        }while(lista[n].GetType()!= typeof(float));\n        Console.WriteLine($\"«n»({n}) coincide con el indice de un float dentro de «lista»\");}\n\n               {Console.WriteLine(\"\\nfor\\n\");\n                Console.WriteLine(\"Los for son bucles mas seguros que los while, ya que estos incluyen en su declaracion la lo que lleva a que se cancele.\");\n                Console.WriteLine(\"Usualmente se declara como «for (int i=0;i<=*cantidad*;i++)». Esto refiere a que se declara una variable local, se pone la condicion que comprobaria un while y la asignacion a esa variable que se ejecuta al final de cada ciclo.\");\n                for (int i = 0; i < 11; i++){Console.WriteLine($\"i:{i}\");};\n\n                Console.WriteLine(\"\\nforeach\\n\");\n                Console.WriteLine(\"Es similar al for, pero afecta a cada elemento de una coleccion.\");\n                Console.WriteLine(\"Teniendo declarado un array de strings con nombres, si quiero hacer un List<string> con los nombres que inicien con A Se puede hacer esto:\");\n                string[] letters = new string[10]{\"Atsuko Kagari\", \"Masaru Daimon\", \"Chaosmon\", \"Aki Maita\", \"Akiyoshi Hongo\", \"Abe Yoshitoshi\", \"Chiaki Juan Konaka\", \"Lain Imakura\", \"Angela Anaconda\", \"Alejandro Jorge De las Mercedes Fernandez\"};\n                List<string> lettersList = new List<string>();\n                foreach (string letter in letters){ if (letter.ToUpper()[0]=='A'){lettersList.Add(letter);};};\n                Console.WriteLine(\"Resultado de «foreach (string letter in letters){ if (letter.ToUpper()=='A'){lettersList.Add(letter)}}»:\");\n                Console.WriteLine(string.Join(\", \",lettersList));\n\n                List<string> lettersList2 = letters.Where(n=>n.ToUpper()[0]!='A').ToList();\n                Console.WriteLine(\"\\nTambien, una alternativa a esto es usar la funcion «Where». Para mostrar los otros nombres:\");\n                Console.WriteLine($\"Valor declarado como: «List<string> lettersList2 = letters.Where(n=>n.ToUpper()[0]!='A').ToList();»:\\n{string.Join(\", \",lettersList2)}\");}\n\n        Console.WriteLine(\"\\nKeyword importantes para los bucles\\n\");\n        Console.WriteLine(\"continue: termina una iteracion y continua la siguiente.\");\n        Console.WriteLine(\"break: termina un bucle y continua la funcion.\");\n        Console.WriteLine(\"return: aplica para toda funcion, la termina y regresa un valor a quien la llamo.\");\n        \n        Console.WriteLine(\"\\ntry catch\\n\");\n        Console.WriteLine(\"Cuando es posible que se produzca un error/excepción puedes poner la operacion o exprecion que lo cause dentro de un «try{*exprecion*} catch{*excepción esperada*}»\");\n        Console.WriteLine(\"Puede haber varios catch seguidos y se pueden hacer mas precisos con la Keyword «when» seguida de una condicion.\");\n        Console.WriteLine(\"Hay mucha mas informacion sobre esto, pero creo que seria extenderme mucho\");\n        Console.WriteLine(\"Esto es el try catch usado por cualquier error posible al intentar mostrar por consola «1/0»\");\n        try{\n            int cero = default;\n            int result = 1/cero;\n            Console.WriteLine($\"Processing succeeded: {result}\");}\n        catch (Exception e) when (e is ArgumentException || e is DivideByZeroException){Console.WriteLine($\"Processing failed: {e.Message}\");}\n        catch (OperationCanceledException) {Console.WriteLine(\"Processing is cancelled.\");}\n        Console.WriteLine(\"\\nUn dato importante de esto es que los try catch son muy lentos, ya que crean objects para funcionar. Por eso son excepciónes, porque se usan en casos excepciónales que no se pueden predecir, como apagones y tal.\");\n        Console.WriteLine(\"Muchos try catch de situaciones previsibles se pueden reemplazar por un if, else que compruebe que no va vaya a producir la excepción y una List que guarde los «mensajes de error» generados.\");\n        /*DOC:\n        Siempre puede usar las siguientes propiedades de solo lectura para examinar\n        y obtener un valor de una variable de tipo de valor que admite valores NULL:\n        Nullable<T>.HasValue indica si una instancia de un tipo que admite valores NULL tiene un\n        valor de su tipo subyacente.\n        Nullable<T>.Value obtiene el valor de un tipo subyacente si HasValue es true.\n        Si HasValue es false, la propiedad Value inicia una excepción InvalidOperationException.\n        */ // Iba a usar eso para el try catch, pero para acortar el tema lo deje.        \n        Console.Write(\"\\n\\n\\nLos numeros del ejercicio extra son: \");//llamar la funcion me dio MUCHISIMOS problemas, pero resulta que para llamar una funcion dentro de una estatica, tambien tiene que ser estatica\n        Extra(10,55,2,3,16);}//creo que la terminal lo decia, pero pense «que se joda la maquina esta, nunca funciona»(cosas de venir de godot) y probe muchas cosas a lo estupido xdd\n    static void Extra(int start, int end, int divisorRequerido, int divisorProibido,int numeroProhibido){for (int i=start;i<=end;i++) {if (i %divisorRequerido==0 && i %divisorProibido!=0 && i!=numeroProhibido){Console.Write(i+\", \");}}}}//yo soy muy de preferir codigo eficiente antes que limpio, pero me gusto la idea de que sea una funcion aparte\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c#/Isj-code.cs",
    "content": "﻿// Operadores\n// Operadores matemáticos\n\nint num1 = 5;\nint num2 = 8;\n\n// Suma\nvar suma = num1 + num2;\n// Resta\nvar resta = num1 - num2;\n// Multiplicación\nvar mult = num1 * num2;\n// Division\nvar division = num1 / num2;\n// Resto\nvar resto = num1 & num2;\n\n// Comparación\nvar igualQue = num1 == num2;\nvar distinto = num1 != num2;\nvar mayorQue = num1 > num2;\nvar mayorIgualQue = num1 >= num2;\nvar menorQue = num1 < num2;\nvar menorIgualQue = num1 <= num2;\nvar yAdemas = num1 <= num2 && num1 != 0;\nvar oEsto = num1 <= num2 || num1 != 0;\n\n// Asignación, suma y resta del número original mas asignación;\n\nnum1 = num2;\nnum1 += num2;\nnum1 -= num2;\n\n// Incremento y decremento\nnum1++;\n++num1;\nnum2--;\n--num2;\n\n\nConsole.WriteLine(\"--------------------------------\");\nConsole.WriteLine(\"Condicionales\");\n// Estructura de control y pertenencia;\n// If, else if, else\nif (num1 < num2)\n{\n    Console.WriteLine($\"El num1: {num1} es menor que el num2: {num2}\");\n} else if (num1 == num2)\n{\n    Console.WriteLine(\"Los números son iguales\");\n}\nelse\n{\n    Console.WriteLine($\"El num1: {num1} es mayor que el num2: {num2}\");\n}\n\n// While\nint xWhile = 0;\n\nwhile (xWhile < 3)\n{\n    Console.WriteLine($\"Estoy dentro del While mientras no valga 3, ahora valgo {xWhile}\");\n    xWhile++;\n}\n\n// Do While\ndo\n{\n    Console.WriteLine($\"Ya valgo 3 pero me ejecuto una vez en do..while\");\n} while (xWhile < 3);\n\n\n// Switch\n\nConsole.WriteLine(\"Ingresa entre a, b, c para probar el switch\");\nstring resp = Console.ReadLine().ToUpper();\nswitch (resp)\n{\n    case \"A\":\n        Console.WriteLine(\"Elegiste a/A\");\n        break;\n    case \"B\":\n        Console.WriteLine(\"Elegiste b/B\");\n        break;\n    case \"C\":\n        Console.WriteLine(\"Elegiste c/C\");\n        break;\n    default:\n        Console.WriteLine(\"Elegiste otra letra!!!!\");\n        break;\n}\nConsole.WriteLine(\"--------------------------------\");\nConsole.WriteLine(\"Iteraciones\");\n// Iterativas\nvar num3 = 4;\nList<int> nums = [1,2,3,4,5,6,7,8,9,10];\n\nConsole.WriteLine($\"El valor de num3 es: {num3} \");\nfor (int i = 0; i < nums.Count; i++)\n{\n    Console.WriteLine($\"Posición de la lista {i} con valor {nums[i]}\");\n    if (nums[i] == num3)\n    {\n        Console.WriteLine(\"Soy igual que num3!!!!\");\n    }\n    else\n    {\n        Console.WriteLine(\"Soy distinto a num3\");\n    }\n}\n\nforeach (var item in nums)\n{\n    Console.WriteLine($\"Tengo el valor {item}\");\n}\nConsole.WriteLine(\"--------------------------------\");\nConsole.WriteLine(\"Excepciones\");\n// Excepciones\ntry\n{\n    if (num1 * num2 > 10_000)\n    {\n        Console.WriteLine(\"Soy verdadero\");  \n    }\n    else\n    {\n        Console.WriteLine(\"Soy falso\");\n    }\n    \n}\ncatch (Exception e)\n{\n    Console.WriteLine($\"En caso de fallar en el try te hablo yo, te puedo dar mas motivos con e: {e}\");\n    throw;\n}\n\n// Opcional, uso del continue\nConsole.WriteLine(\"--------------------------------\");\nConsole.WriteLine(\"Ejercicio Opcional\");\nfor (int i = 10; i <= 55; i++)\n{\n    if (i % 3 == 0 || i == 16)\n    {\n        continue;\n    }\n    Console.WriteLine($\"No soy ni múltiplo de 3 ni el 16, soy el número {i}\");\n}\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c#/IvanCalero04.cs",
    "content": "// Ejercicio #01 Operadores y Estructuras de control.\n\nint myAge = 42;\nint myAge1 = 21;\n\n// Operadores aritmeticos:\nvar sumaEnteros = myAge + myAge1;\nvar restaEnteros = myAge - myAge1;\nvar multiplicacionEnteros = myAge * myAge1;\nvar divisionEnteros = myAge / myAge1;\nvar moduloEnteros = myAge % myAge1;\n\nConsole.WriteLine($\"Esto es una suma de dos varaibles: {sumaEnteros}\");\nConsole.WriteLine($\"Esto es una resta de dos varaibles: {restaEnteros}\");\nConsole.WriteLine($\"Esto es una multiplicación de dos varaibles: {multiplicacionEnteros}\");\nConsole.WriteLine($\"Esto es una division entre dos varaibles: {divisionEnteros}\");\nConsole.WriteLine($\"Esto es el resto de dos varaibles: {moduloEnteros}\");\n\n\n\n// Condicionales y estructura de control:\n            if (myAge < myAge1)\n            {\n                Console.WriteLine($\"La edad {myAge1} es mayor.\");\n            }\n            else if (myAge > myAge1)\n                {\n                    Console.WriteLine($\"La edad {myAge} es mayor.\");\n                }\n            else if (myAge <= 0 && myAge > 100 && myAge1 <= 0 && myAge1 > 100)\n                {\n                    Console.WriteLine($\"La edad debe de ser mayor que 0 y menor que 100.\");\n                }\n            else\n            {\n                Console.WriteLine(\"Las variables (age) deben de tener contenido INT\");\n            }\n\nstring myName = \"Iván\";\nstring myLastname = \"Calero Moreno\";\n\nif (myName == \"Iván\" || myLastname == \"Calero Moreno\")\n{\n    Console.WriteLine(\"Hola Ivan!\");\n}\nelse if (myName != \"Iván\" && myLastname != \"Calero Moreno\")\n{\n    Console.WriteLine($\"Hola {myName} {myLastname} que tengas un buen dia.\");\n}\nelse if (myName == \"\" && myLastname == \"\")\n{\n    Console.WriteLine($\"Las variables deben de tener algun valor.\");\n}\n\n\n// Imprimir por pantalla los numeros comprendidos entre 10 y el 55 que sean pares y que no son ni el 16 ni multiplos de 3\n\nfor (int index = 10; index >= 10 && index <= 55; index++)\n{\n    if (index % 2 == 0 && index != 16 && index % 3 != 0)\n    {\n        Console.WriteLine(index);\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c#/JoseEsmil04.cs",
    "content": "using System;\n\n\nnamespace _01_Operadores_Estructuras\n{\n    internal class Program\n    {\n        static void Main(string[] args)\n        {\n            // Operadores aritméticos\n            int a = 10;\n            int b = 5;\n            Console.WriteLine(\"Operadores aritméticos:\");\n            Console.WriteLine($\"a + b = {a + b}\"); // Suma\n            Console.WriteLine($\"a - b = {a - b}\"); // Resta\n            Console.WriteLine($\"a * b = {a * b}\"); // Multiplicación\n            Console.WriteLine($\"a / b = {a / b}\"); // División\n            Console.WriteLine($\"a % b = {a % b}\"); // Módulo\n\n            // Operadores lógicos\n            bool verdad = true;\n            bool falso = false;\n            Console.WriteLine(\"\\nOperadores lógicos:\");\n            Console.WriteLine($\"verdad && falso = {verdad && falso}\"); // AND\n            Console.WriteLine($\"verdad || falso = {verdad || falso}\"); // OR\n            Console.WriteLine($\"!verdad = {!verdad}\"); // NOT\n\n            // Operadores de comparación\n            Console.WriteLine(\"\\nOperadores de comparación:\");\n            Console.WriteLine($\"a == b = {a == b}\"); // Igualdad\n            Console.WriteLine($\"a != b = {a != b}\"); // Desigualdad\n            Console.WriteLine($\"a > b = {a > b}\"); // Mayor que\n            Console.WriteLine($\"a < b = {a < b}\"); // Menor que\n            Console.WriteLine($\"a >= b = {a >= b}\"); // Mayor o igual que\n            Console.WriteLine($\"a <= b = {a <= b}\"); // Menor o igual que\n\n            // Operadores de asignación\n            Console.WriteLine(\"\\nOperadores de asignación:\");\n            int c = 20;\n            c += a; // Equivalente a c = c + a\n            Console.WriteLine($\"c += a -> c = {c}\");\n            c -= a; // Equivalente a c = c - a\n            Console.WriteLine($\"c -= a -> c = {c}\");\n            c *= a; // Equivalente a c = c * a\n            Console.WriteLine($\"c *= a -> c = {c}\");\n            c /= a; // Equivalente a c = c / a\n            Console.WriteLine($\"c /= a -> c = {c}\");\n            c %= a; // Equivalente a c = c % a\n            Console.WriteLine($\"c %= a -> c = {c}\");\n\n            // Operadores de bits\n            Console.WriteLine(\"\\nOperadores de bits:\");\n            int d = 6; // 110 en binario\n            int e = 3; // 011 en binario\n            Console.WriteLine($\"d & e = {d & e}\"); // AND bit a bit\n            Console.WriteLine($\"d | e = {d | e}\"); // OR bit a bit\n            Console.WriteLine($\"d ^ e = {d ^ e}\"); // XOR bit a bit\n            Console.WriteLine($\"~d = {~d}\"); // NOT bit a bit\n            Console.WriteLine($\"d << 1 = {d << 1}\"); // Desplazamiento a la izquierda\n            Console.WriteLine($\"d >> 1 = {d >> 1}\"); // Desplazamiento a la derecha\n\n            // Operadores de identidad y pertenencia (no nativos en C#, usando métodos de clase)\n            Console.WriteLine(\"\\nOperadores de identidad y pertenencia:\");\n            object obj1 = new object();\n            object obj2 = obj1;\n            Console.WriteLine($\"obj1 es obj2: {object.ReferenceEquals(obj1, obj2)}\"); // Identidad\n            Console.WriteLine($\"'a' pertenece a 'abcd': {\"abcd\".Contains('a')}\"); // Pertenencia\n\n            // Estructuras de control condicionales\n            Console.WriteLine(\"\\nEstructuras de control condicionales:\");\n            if (a > b)\n            {\n                Console.WriteLine(\"a es mayor que b\");\n            }\n            else if (a < b)\n            {\n                Console.WriteLine(\"a es menor que b\");\n            }\n            else\n            {\n                Console.WriteLine(\"a es igual a b\");\n            }\n\n            // Estructuras de control iterativas\n            Console.WriteLine(\"\\nEstructuras de control iterativas:\");\n            for (int i = 0; i < 5; i++)\n            {\n                Console.WriteLine($\"For loop, iteración: {i}\");\n            }\n\n            int[] numeros = { 1, 2, 3 };\n            foreach (var num in numeros)\n            {\n                Console.WriteLine($\"Foreach Loop, iteración: {num}\");\n            }\n\n            int j = 0;\n            while (j < 5)\n            {\n                Console.WriteLine($\"While loop, iteración: {j}\");\n                j++;\n            }\n\n            int k = 0;\n            do\n            {\n                Console.WriteLine($\"Do-while loop, iteración: {k}\");\n                k++;\n            } while (k < 5);\n\n            // Estructuras de control de excepciones\n            Console.WriteLine(\"\\nEstructuras de control de excepciones:\");\n            try\n            {\n                int resultado = a / 0;\n            }\n            catch (DivideByZeroException ex)\n            {\n                Console.WriteLine(\"Excepción capturada: \" + ex.Message);\n            }\n            finally\n            {\n                Console.WriteLine(\"Bloque finally ejecutado.\");\n            }\n\n            // DIFICULTAD EXTRA\n            Console.WriteLine(\"\\nDificultad extra:\");\n            for (int num = 10; num <= 55; num++)\n            {\n                if (num % 2 == 0 && num != 16 && num % 3 != 0)\n                {\n                    Console.WriteLine(num);\n                }\n            }\n        }\n\n    }\n\n}\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c#/JuanPVelasquezR.cs",
    "content": "// Operadores en C#-------------------------------------------------------------------------------------------------------\n\n//Aritmticos\n\nint a = 24, b = 54;\nint suma = a + b;\nint resta = a - b;\nint multiplicacin = a * b;\nfloat divisin = a / b;\nfloat resto = a % b;\n\n\nConsole.WriteLine($@\" a = 24, b = 54...\n            Suma = a + b: {suma}\n            Resta = a + b: {resta}\n            Multiplicacin = a + b: {multiplicacin}\n            Divisin = a + b: {divisin}\n            Resto = a % b: {resto}\");\n\n\n// Operadores de Asignacin\n\n// Operador de asignacin simple\nint x = 78;\n\n// Operador de Suma y Asignacin\nx += 55;\n\n// Operador de Resta y Asignacin\nx -= 10;\n\n// Operador de Multiplicacin y Asignacin\nx *= 10;\n\n// Operador de Divisin y Asignacin\nx /= 10;\n\n\n// Operadores de Comparacin \n\n\n// Es verdadero si ambos valores son iguales\nConsole.WriteLine(a == b);\n\n\n// Es verdadero si los valores son diferentes\nConsole.WriteLine(a != b);\n\n//Devuelve verdadero o falso si se cumple que el indicado sea el mayor o el menor\nConsole.WriteLine(a > b);\nConsole.WriteLine(a < b);\n\n//Devuelve verdadero o falso si se cumple que el indicado sea el mayor, menor o igual\nConsole.WriteLine(a >= b);\nConsole.WriteLine(a <= b);\n\n\n\n// Operadores lgicos\n\nbool c = true;\n\nbool d = false;\n\n// Devuelve verdadero si ambos comparandos son verdaderos, de lo contrario, devuelve falso\nConsole.WriteLine(c && d);\n\n// Devuvelve verdadero de alguno de los dos operandos son verdadedros\nConsole.WriteLine(c || d);\n\n// Es una negacin del operando, si el operando es falso, se vuelve verdadero, y viceversa\nConsole.WriteLine(!c);\n\n\n// Operadores iterativos\n\n// Analiza una condicin dada, en caso de cumplirse aquella condicin, ejecuta el bloque de cdigo que se define entre las llaves, si no se cumple, no se\n// ejecuta, se puede definir que comportamiento tener en caso de no cumplirse\n\nif (c)\n{\n    Console.WriteLine(\"La condicin fue verdadera\");\n}\nelse\n{\n    Console.WriteLine(\"La condicin fue falsa\");\n\n\n}\n\nConsole.WriteLine(\"Esto se ejecutar sin importar el resultado de la condicin\");\n\n/* Es posible generar una cadena de condicionales if, no solamene con una contraparte else, tambin se puede hacer uso del else if, sin  embargo \n * generalmente en los casos en que se presentan varios if anidados, es ms correcto usar un Switch Case*/\n\n//Estructura de contro switch  --  Permite asignar acciones concretas en funcin del valor de una variable.\n//\n\nint productoId = 2;\n\nswitch (productoId)\n{\n\n    case 1:\n        Console.WriteLine(\"Man\");\n        break;\n\n    case 2:\n        Console.WriteLine(\"Chocolate\");\n        break;\n\n    case 3:\n        Console.WriteLine(\"Soda\");\n        break;\n\n}\n\n\n// Estructuras de control iterativas\n\n//Bucle for, es un bucle que se usa para que cierta accion se repita un numero determinado de veces, se usa cuando se conoce cual es el numero de veces que se debe repetir\n\nfor (int i = 0; i < 5; i++)\n{\n\n    Console.WriteLine($\"Esta es la iteracin nmero {i + 1}\");\n}\n\n\n// Bucle ForEach, se usa para realizar una accin determinada, con la diferencia de que este se har hasta que se recorran todos los elementos de la estrcutura utilizada\n// Como un arreglo, una Lista...\n\n\nint[] numeros = { 1, 2, 3, 4, 5, 6, };\n\nforeach (int i in numeros)\n{\n\n\n    Console.WriteLine($\"Acutualmente se est recorriendo el ndice: {i}\");\n}\n\n\n// Estructura do y do while. La estructura do define una accin que se va a ejecutar, luego se aade a un bucle while, la cual puede ejecutarse o no, en funcion de si se cumple una condicin. el do siempre se ejecuta almenos una vez\n\nbool flag = true;\n\ndo\n{\n\n    int i = 0;\n    Console.WriteLine($\"Valor de i: {i}\");\n    i++;\n\n    flag = false;\n\n}\nwhile (flag);\n\n\n\n\n//Excepciones y Control de Excepcin, generalmente se usan, para que al tener un error o un improvisto en la ejecucin del cdigo, no se termine\n// la ejecucin, sino que, se pueda controlar, se pueden as mismo, enviar nosotreos mismos estas excepciones o \"Errores\" cuando pase o se cumpla algo que definimos\n\nfloat h = 0, n = 4;\ntry\n{\n\n    float resultado = n / h;\n\n    Console.WriteLine(resultado);\n\n\n}\n\ncatch (Exception e)\n{\n    Console.WriteLine(\"No se puede dividir entre 0\");\n\n}\n\n// Tambin existe la opcin finally, que se ejecutar sin importar si entra en el cath o no\n\n\n\n\n\n\n\n\n//---------------------------------------------------------------------------------------------------------------------------------------------\n\n//DIFICULTAD EXTRA\n\n\nfor (int i = 10; i <= 55; i++)\n{\n    if (i % 2 == 0 && i != 16 && i % 3 == 0)\n    { Console.WriteLine(i); }\n\n\n}\n\n\n        "
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c#/Kvr0th3c4t.cs",
    "content": "//Operadores aritméticos en C#\n\n//Operadores unarios\n\n//Incremento\nusing System.Collections.Specialized;\nusing System.ComponentModel;\nusing System.Data;\nusing System.Diagnostics;\nusing System.Reflection.Emit;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\nusing System.Runtime.InteropServices.Marshalling;\nusing System.Runtime.Serialization;\nusing System.Text;\n\nvar b = 0;\nb++;\n//Decremento\nvar c = 0;\nc--;\n//Suma y resta\nint sumResult = b + c;\nint resResult = b - c;\n//Multiplicación \nint multResult = b * c;\n//División \nint divResult = b / c;\n//Resto\nint restoResult = b % 0;\n//Asiganción compuesta \nb += 9;\n\n//Operadores de comparación\n\nbool result = b == c;\nbool result2 = b >= c;\nbool result3 = b <= c;\nbool result4 = b < c;\nbool result5 = b > c;\n\n//Operadores lógicos\n\n//Negación \nbool result6 = false;\nConsole.WriteLine(!result6);\n\n//AND &&\nbool SecondOperand()\n{\n    Console.WriteLine(\"Second operand is evaluated.\");\n    return true;\n}\n\nbool a = false && SecondOperand();\nConsole.WriteLine(a);\n\n//OR ||\nbool SecondOperand()\n{\n    Console.WriteLine(\"Second operand is evaluated.\");\n    return true;\n}\n\nbool a = true || SecondOperand();\nConsole.WriteLine(a);\n\n//Operadores de igualdad y desigualdad\n\nif (b == c)\n{\n    Console.WriteLine(\"Son iguales\");\n    return true;\n}\n\nif (b != c)\n{\n    Console.WriteLine(\"Son diferentes\");\n    return false;\n}\n\n//Estructuras de control en C#\n\n//Condicion \n\nif (b > c)\n{\n    Console.WriteLine(\"La condición se cumple\");\n}\nelse\n{\n    Console.WriteLine(\"La condición no se cumple\");\n}\n\n//Switch\n\nswitch (b)\n{\n    case 1:\n\n        Console.WriteLine(\"La variable vale 1\");\n        break;\n\n    case 2:\n        Console.WriteLine(\"La variable vale 2\");\n        break;\n\n    default:\n        ConstraintCollection.WriteLine(\"La variable vale otra cosa\");\n        break;\n}\n\n//While\n\nwhile (b < 10)\n{\n    ConstructorBuilder.WriteLine($\"El valor de b es {b}\");\n    b++;\n}\n\ndo { b++; } while (b < 5);\n\n//For\n\nfor (int i = 0; i < 10; i++)\n{\n    Console.WriteLine(i);\n}\n\n//ForEach\n\nList<int> ejemplo = { 1, 2, 3, 4 };\n\nforeach (var item in ejemplo)\n{\n    Console.WriteLine(item);\n}\n\n\n\n\n//Dificultad extra: Crea un programa que imprima por consola todos los números comprendidos entre 10 y 55, pares, y qu eno son ni el 16 ni múltiplos de 3.\n\nfor (int i = 10; i < 56; i++)\n{\n    if (i % 3 != 0 && i % 2 == 0 && i != 16)\n    {\n        Console.WriteLine(i);\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c#/Lordibzn.cs",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n\nvar int numero = 50;\n\n//operadores aritmeticos\nint a = 10;\nint b = 3;\nConsole.WriteLine$\"a + b = {a + b}\"; // Suma\nConsole.WriteLine$\"a - b = {a - b}\"; // Resta\nConsole.WriteLine$\"a * b = {a * b}\"; // Multiplicación\nConsole.WriteLine$\"a / b = {a / b}\"; // División\nConsole.WriteLine$\"a % b = {a % b}\"; // Módulo\n\n// Operadores de comparación \nConsole.WriteLine(\"\\nOperadores de Comparación:\");\nConsole.WriteLine($\"a == b : {a == b}\"); // Igual\nConsole.WriteLine($\"a != b : {a != b}\"); // Diferente\nConsole.WriteLine($\"a > b : {a > b}\"); // Mayor\nConsole.WriteLine($\"a < b : {a < b}\"); // Menor\nConsole.WriteLine($\"a >= b : {a >= b}\"); // Mayor o igual\nConsole.WriteLine($\"a <= b : {a <= b}\"); // Menor o igual\n\n// Operadores logicos\nbool x = true;\nbool y = false;\nConsole.WriteLine(\"\\nOperadores lógicos\");\nConsole.WriteLine($\"x && y: {x && y}\"); // AND\nConsole.WriteLine($\"x || y: {x || y}\"); // OR\nConsole.WriteLine($\"!x: {!x}\"); // NOT\n\n// Operadores de asignación\nConsole.WriteLine(\"\\Operadores de asignación\");\nint c = 6;\nConsole.WriteLine($\"c = {c}\");\nc += 4; // equivalente a c = c + 4\nConsole.WriteLine($\"c += 4; {c}\");\nc -= 2; // equivalente a c = c - 2\nConsole.WriteLine($\"c -= 2 {c}\");\nc *= 2; // equivalente a c = c * 2\nConsole.WriteLine($\"c *= 2: {c}\");\nc /= 4; // equivalente a c = c / 4\nConsole.WriteLine($\"c /= 4: {c}\");\nc %= 3; // equivalente a c = c % 3\nConsole.WriteLine($\"c %= 3: {c}\");\n\n\n// Operadores de bits\nConsole.WriteLine(\"\\nOperadores de bits:\");\nint d = 6; // 110 en binario\nint e = 3; // 011 en binario\nConsole.WriteLine($\"d & e: {d & e}\"); // AND bit a bit\nConsole.WriteLine($\"d | e: {d | e}\"); // OR bit a bit\nConsole.WriteLine($\"d ^ e: {d ^ e}\"); // XOR bit a bit\nConsole.WriteLine($\"~d: {~d}\"); // NOT bit a bit\nConsole.WriteLine($\"d << 1: {d << 1}\"); // Desplazamiento a la izquierda\nConsole.WriteLine($\"d >> 1: {d >> 1}\"); // Desplazamiento a la derecha\n\n // Operadores de identidad (Referencia y valor)\nConsole.WriteLine(\"\\nOperadores de identidad:\");\nstring msg1 = \"Hola\";\nstring msg2 = \"Hola\";\nConsole.WriteLine($\"msg1 == msg2: {msg1 == msg2); // Comparación de valor\nConsole.WriteLine($\"object.ReferenceEquals(msg1, msg2): {object.ReferenceEquals(msg1, msg2)}\"); // Comparación de referencia\n\n// Operadores de pertenencia (usualmente usando listas o colecciones)\nConsole.WriteLine(\"\\nOperadores de pertenencia\");\nint[] array = {1, 2, 3, 4, 5};\nConsole.WriteLine($\"array contiene 3: {Array.Exists(array, element => element == 3)}\"); // Usando un método de Array para verificar pertenencia\n \n// Estructuras de control \nConsole.WriteLine(\"\\nOperadores de control\");\n\n// Condicionales\nif (a > b)\n{\n    Console.WriteLine(\"a es mayor que b\");\n}\nelse \n{\n    Console.WriteLine(\"a no es mayor que b\");\n}\n\nswitch (a)\n{\n    case 10:\n        Console.WriteLine(\"a es 10\");\n        break;\n    default:\n        Console.WriteLine(\"a no es 10\");\n        break;\n}\n\n// Bucles\nConsole.WriteLine(\"\\Bucles\");\nfor (int i = 0; i < 10; i++)\n{\n    Console.WriteLine(i);\n}\n\nConsole.WriteLine(\"\\nBucle while: \");\nint j = 0;\nwhile (j < 10)\n{\n    Console.WriteLine(j);\n    j++;\n}\n\nConsole.WriteLine(\"\\nBucle do-while:\");\nint k = 0;\n    do\n    {\n        Console.WriteLine(k);\n        k++;\n    } while (k < 5);\n\n// Excepciones\nConsole.WriteLine(\"\\nExcepciones\");\ntry\n{\n    int result = a / 0;\n}\ncatch (DivideByZeroException e)\n{\n    \n     Console.WriteLine(\"Excepción: División por cero.\");\n}\n\n// Uso de funciones\nSaludar();\nint suma = Sumar(5, 7);\nConsole.WriteLine($\"La suma de 5 y 7 es : {suma}\");\n\n//funciones\n\n// Función sin parámetros ni retorno\nstatic void Saludar()\n{\n    Console.WriteLine(\"¡Hola desde la función Saludar!\");\n}\n\n// Función con parámetros y retorno\nstatic int Sumar(int a, int b)\n{\n     return a + b;\n}\n\n// Dificultad extra\nConsole.WriteLine(\\nDifultad extra);\nfor (int i = 10; i <= 55; i++)\n{\n    if (i % 2 == 0 && i != 16 && i % 3 != 0)\n    {\n        Console.WriteLine(i);\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c#/Pakiuh.cs",
    "content": "﻿// Operadores de asignación\r\nint x1 = 10; // asignación\r\nx1 += 5; // suma y asignación\r\nx1 -= 2; // resta y asignación\r\nx1 *= 3; // multiplicación y asignación\r\nx1 /= 2; // división y asignación\r\nx1 %= 3; // módulo y asignación\r\n\r\n// Operadores aritméticos\r\nint y1 = x1 + 5; // suma\r\nint z = x1 - y1; // resta\r\nint a = x1 * y1; // multiplicación\r\nint b = x1 / y1; // división\r\nint c = x1 % y1; // módulo\r\nint d = x1++; // incremento\r\nint e = y1--; // decremento\r\n\r\n// Operadores de comparación\r\nbool isEqual = x1 == y1; // igual a\r\nbool isNotEqual = x1 != y1; // no igual a\r\nbool isGreaterThan = x1 > y1; // mayor que\r\nbool isLessThan = x1 < y1; // menor que\r\nbool isGreaterThanOrEqual = x1 >= y1; // mayor o igual que\r\nbool isLessThanOrEqual = x1 <= y1; // menor o igual que\r\n\r\n// Operadores lógicos\r\nbool and = x1 > 5 && y1 < 10; // y lógico\r\nbool or = x1 > 5 || y1 < 10; // o lógico\r\nbool not = !(x1 == y1); // no lógico\r\n\r\n// Operador ternario\r\nstring result = x1 > y1 ? \"x es mayor que y\" : \"x no es mayor que y\";\r\n\r\n// Operadores de bits\r\nint shiftLeft = x1 << 2; // desplazamiento a la izquierda\r\nint shiftRight = x1 >> 2; // desplazamiento a la derecha\r\nint bitwiseAnd = x1 & y1; // y a nivel de bits\r\nint bitwiseOr = x1 | y1; // o a nivel de bits\r\nint bitwiseXor = x1 ^ y1; // xor a nivel de bits\r\nint bitwiseNot = ~x1; // no a nivel de bits\r\n\r\n// Declaraciones condicionales\r\nint x2 = 10;\r\nif (x2 > 5) {\r\n    Console.WriteLine(\"x es mayor que 5\");\r\n} else if (x2 < 5) {\r\n    Console.WriteLine(\"x es menor que 5\");\r\n} else {\r\n    Console.WriteLine(\"x es igual a 5\");\r\n}\r\n\r\n// Declaración switch\r\nswitch (x2) {\r\n    case 5:\r\n        Console.WriteLine(\"x es 5\");\r\n        break;\r\n    case 10:\r\n        Console.WriteLine(\"x es 10\");\r\n        break;\r\n    default:\r\n        Console.WriteLine(\"x no es ni 5 ni 10\");\r\n        break;\r\n}\r\n\r\n// Bucle for\r\nfor (int i = 0; i < 5; i++) {\r\n    Console.WriteLine(\"El valor de i es: \" + i);\r\n}\r\n\r\n// Bucle while\r\nint j = 0;\r\nwhile (j < 5) {\r\n    Console.WriteLine(\"El valor de j es: \" + j);\r\n    j++;\r\n}\r\n\r\n// Bucle do while\r\nint k = 0;\r\ndo {\r\n    Console.WriteLine(\"El valor de k es: \" + k);\r\n    k++;\r\n} while (k < 5);\r\n\r\n// Manejo de excepciones\r\ntry {\r\n    int y2 = x2 / 0; // Dividir por cero lanzará una excepción\r\n} catch (DivideByZeroException error) {\r\n    Console.WriteLine(\"Ha ocurrido un error: \" + error.Message);\r\n} finally {\r\n    Console.WriteLine(\"Este bloque se ejecuta independientemente de si se produjo una excepción o no\");\r\n}\r\n\r\n// Dificulata Extra\r\nfor (int i = 10; i <= 55; i++) {\r\n    if (i % 2 == 0 && i != 16 && i % 3 != 0) {\r\n        Console.WriteLine(i);\r\n    }\r\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c#/ProTpuS98.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Net.WebSockets;\nusing System.Runtime.CompilerServices;\nusing System.Security.Cryptography;\nusing System.Security.Cryptography.X509Certificates;\nusing System.Security.Policy;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace _01_OPERADORES_Y_ESTRUCTURAS_DE_CONTROL\n{\n    internal class Program\n    {\n        static void Main(string[] args)\n        {\n            //EJERCICIO:\n            //1. Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n            //   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n            //   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n\n            //2. Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n            //   que representen todos los tipos de estructuras de control que existan\n            //   en tu lenguaje:\n            //   Condicionales, iterativas, excepciones... \n\n            //3. Debes hacer print por consola del resultado de todos los ejemplos.\n\n            //4. DIFICULTAD EXTRA(opcional):\n            //   Crea un programa que imprima por consola todos los números comprendidos\n            //   entre 10 y 55(incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\n            //   Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\n            TiposOperadores operadores = new TiposOperadores();\n            Console.WriteLine(operadores.getResultsArimeticos());\n            Console.WriteLine(operadores.getResultsAsignacion());\n\n            operadores.OperadoresDeComparacion();\n            operadores.game();\n            operadores.OperadoresLogicos();\n\n        }\n\n        public class TiposOperadores\n        {\n            private int num1;\n            private int num2;\n\n            private int userNum1;\n            private int userNum2;\n            private int userNum3;\n            private int userNum4;\n            private int userNum5;\n            private int userNum6;\n\n            private int addtraction;\n            private int subtraction;\n            private int multiply;\n            private int divide;\n            private int module;\n\n            private int x;\n            private int num3;\n            private int num4;\n            private int num5;\n            private int num6;\n\n            private int numA;\n            private int numB;\n\n            private string name;\n            private string input;\n            private int age;\n\n            private int numRandom;\n            private int myNum;\n            private int attemps;\n\n            private bool a;\n            private bool b;\n            private bool c1;\n            private bool c2;\n            private bool c3;\n            private bool c4;\n\n            private bool IsRaining;\n            private bool ResultadoIsRaining;\n\n            private int aBit;\n            private int bBit;\n            private int AND;\n            private int OR;\n            private int XOR;\n            private int NOT;\n            private int desplazamientoIzquierda;\n            private int desplazamientoDerecha;\n\n            private int aTernario;\n            private int bTernario;\n            private int resultadoTernario;\n            private object obj;\n            private string word;\n\n            public TiposOperadores()\n            {\n                //EJERCICIO 1\n\n                //1. ARIMETICOS\n                num1 = 10;\n                num2 = 50;\n\n                addtraction = num1 + num2;\n                subtraction = num1 - num2;\n                multiply = num1 * num2;\n                divide = num1 / num2;\n                module = num1 % num2;\n\n                //2. ASIGNACION\n                x = 10;\n                num3 = x += 5;\n                num4 = x -= 5;\n                num5 = x *= 5;\n                num6 = x /= 4;\n\n                //3. COMPARACION\n                name = \"\";\n                input = \"\";\n                age = 0;\n\n                //4. EJEMPLO COMPARACION CON JUEGO\n                Random random = new Random();\n                numRandom = random.Next(0, 100);\n                myNum = 0;\n                attemps = 0;\n\n                //5. OPERADORES LOGICOS\n                a = true;\n                b = false;\n                c1 = a && b;\n                c2 = a || b;\n                IsRaining = true;\n                ResultadoIsRaining = !IsRaining;\n\n                userNum1 = 0;\n                userNum2 = 0;\n\n                //6. OPERADORES bit a bit\n                aBit = 6;\n                bBit = 3;\n                AND = aBit & bBit;\n                OR = aBit | bBit;\n                XOR = aBit ^ bBit;\n                NOT = ~aBit;\n                desplazamientoDerecha = aBit >> 1;\n                desplazamientoIzquierda = bBit << 1;\n\n                //7. OPERADORES MISCELANEOS\n                aTernario = 50;\n                bTernario = 100;\n                obj = \"hello\";\n                word = obj as string;\n            }\n            public string getResultsArimeticos()\n            {\n                return $\"OPERADORES ARIMETICOS EN C#: Adición (+), Sustracción (-), Multiplicación (*), División (/), Módulo (%). Valor Num1 = ({num1}), Valor Num2 = ({num2}).\" + \"\\n\" + \"Addtraction: \" + addtraction + \"\\n\" + \"Subtraction: \" + subtraction + \"\\n\" + \"Multiply: \" + multiply + \"\\n\" + \"Divide: \" + divide + \"\\n\" + \"Module: \" + module + \"\\n\";\n            }\n            public string getResultsAsignacion()\n            {\n                return \"OPERADORES DE ASIGNACION EN C#: valor de X = 10: \" + \"\\n\" + \"(x += 5): \" + num3 + \"\\n\" + \"(x -= 5): \" + num4 + \"\\n\" + \"(x *= 5): \" + num5 + \"\\n\" + \"(x /= 5): \" + num6 + \"\\n\";\n            }\n\n            public void OperadoresDeComparacion()\n            {\n                //OPERADORES DE COMPARACION\n                Console.WriteLine(\"OPERADORES DE COMPARACION:\" + \"\\n\");\n\n                Console.WriteLine(\"Escriba si para saber si puedes conducir\");\n                input = Console.ReadLine();\n\n                if (input == \"si\")\n                {\n                    Console.WriteLine(\"Como te llamas?\");\n                    name = Console.ReadLine();\n                    Console.WriteLine(\"Cuantos años tienes ?\");\n                    age = int.Parse(Console.ReadLine());\n\n                    if (age <= 16)\n                    {\n                        Console.WriteLine(\"Debes tener 18 para poder tener el carnet de conducir\");\n                    }\n                    else if (age >= 18)\n                    {\n                        Console.WriteLine(\"Tienes carnet?\");\n                        input = Console.ReadLine();\n\n                        if (input == \"si\")\n                        {\n                            Console.WriteLine(\"Puedes conducir\");\n                        }\n                        else\n                        {\n                            Console.WriteLine(\"no puedes conducir\");\n                        }\n                    }\n                }\n \n            }\n            //EJEMPLO COMPARACION CON JUEGO\n            public void game()\n            {\n                Console.WriteLine(\"Le gustaria jugar a Adivina el numero oculto? 'si' o 'no'\");\n                input = Console.ReadLine();\n\n                if (input == \"si\")\n                {\n                    Console.WriteLine(\"introduzca un numero del 1 a 100\");\n\n                    //OPERADOR UNARIO Y NEGACION LOGICO\n                    while (myNum != numRandom)\n                    {\n                        myNum = int.Parse(Console.ReadLine());\n                        if (myNum < numRandom)\n                        {\n                            Console.WriteLine(\"El numero oculto es mayor\");\n                        }\n                        else if (myNum > numRandom)\n                        {\n                            Console.WriteLine(\"El numero oculto es menor\");\n                        }\n                        //OPERADOR UNARIO\n                        attemps++;\n                    }\n                    Console.WriteLine($\"¡Felicidades! Total intentos utilizados: {attemps}\");\n                    Console.WriteLine();\n                }\n            }\n            //OPERADORES LOGICOS\n            public void OperadoresLogicos()\n            {\n                Console.WriteLine(\"OPERADORES LOGICOS: bool a = 'true', bool b = 'false'. c1 = a && b., c2 = a||b, c3 = !a\");\n                Console.WriteLine($\"valor de c1: {c1}. El resultado es falso porque b es false\");\n                Console.WriteLine($\"valor de c2: {c2}. el resultado es verdadero porque a es verdadero\");\n                Console.WriteLine($\"valor de c3: {c3}. el resultado es falso porque a es verdadero\");\n                Console.WriteLine();\n\n                Console.WriteLine(\"Le gustaria ver un ejemplo practico? 'si', 'no'\");\n                input = Console.ReadLine();\n\n                //EJEMPLO CON OPERADOR LOGICO &&\n                if (input == \"si\")\n                {\n                    Console.WriteLine(\"OPERADOR LOGICO '&&' DARA RESULTADO TRUE SOLO SI AMBAS CONDICIONES SON VERDADERAS\");\n                    Console.WriteLine(\"Introduzca un numero\");\n                    userNum1 = int.Parse(Console.ReadLine());\n\n                    Console.WriteLine(\"Introduzca otro numero\");\n                    userNum2 = int.Parse(Console.ReadLine());\n\n                    if (userNum1 > 0 && userNum2 > 0)\n                    {\n                        Console.WriteLine($\"el numero {userNum1} y {userNum2} son positivos\");\n                    }\n                    else\n                    {\n                        Console.WriteLine(\"Es falso porque uno de tus numeros es negativo\");\n                    }\n\n                }\n                Console.WriteLine(\"Le gustaria ver un EJEMPLO PRACTICO OPERADOR LOGICO (||)? escriba 'si' o 'no'\");\n                input = Console.ReadLine();\n                if (input == \"si\")\n                {\n                    //EJEMPLO OPERADORES LOGICO (||)\n                    Console.WriteLine(\"EJEMPLO PRACTICO OPERADOR LOGICO (||). solo sera 'true' si al menos uno de los dos numeros es positivo\");\n                    Console.WriteLine(\"Introduzca un numero\");\n                    userNum3 = int.Parse(Console.ReadLine());\n                    Console.WriteLine(\"Introduzca otro numero\");\n                    userNum4 = int.Parse(Console.ReadLine());\n\n                    if (userNum3 > 0 || userNum4 > 0)\n                    {\n                        Console.WriteLine(\"es 'True' porque al menos un numero es positivo\");\n                    }\n                    else\n                    {\n                        Console.WriteLine(\"Es 'False' porque ambos numeros son negativos\");\n                    }\n                    Console.WriteLine(\"\\n\");\n                    //EJEMPLO OPERADOR LOGICO (!)\n                    Console.WriteLine(\"EJEMPLO OPERADOR LOGICO (!) Invierte el valor\");\n                    Console.WriteLine($\"Valor de IsRaining = {IsRaining}\");\n                    Console.WriteLine($\"Valor de ResultadoIsraining = {ResultadoIsRaining}\");\n                }\n\n                //OPERADORES BIT A BIT\n                Console.WriteLine(\"OPERADORES bit a bit\");\n                Console.WriteLine(\"Escriba si para ver ejemplos\");\n                input = Console.ReadLine();\n                Console.WriteLine(\"\\n\");\n                if (input == \"si\")\n                {\n                    Console.WriteLine(\"int a = 5; int b = 3.\");\n                    Console.WriteLine(\"\\n\");\n                    Console.WriteLine($\"AND bit a bit (&). Compara cada bit de los dos números y devuelve 1 solo si ambos bits son 1. RESULTADO: {AND}\");\n                    Console.WriteLine($\"OR bit a bit (|). devuelve 1 si al menos uno de los bits es 1. RESULTADO: {OR}\");\n                    Console.WriteLine($\"XOR bit a bit (^). Este operador devuelve 1 cuando los bits son diferentes entre sí. RESULTADO: {XOR}\");\n                    Console.WriteLine($\"NOT bit a bit (~). Este operador invierte los bits, cambiando los 1 por 0 y viceversa. RESULTADO: {NOT}\");\n                    Console.WriteLine($\"Desplazamiento a la izquierda (<<). Este operador desplaza los bits hacia la izquierda y rellena con ceros. Equivale a multiplicar por 2 por cada desplazamiento. RESULTADO: {desplazamientoIzquierda}\");\n                    Console.WriteLine($\"Desplazamiento a la derecha (>>). Este operador desplaza los bits hacia la derecha. Si el número es positivo, rellena con ceros; si es negativo, rellena con unos. RESULTADO: {desplazamientoDerecha}\");\n                }\n                Console.WriteLine(\"\\n\");\n                //OPERADORES UNARIOS\n                Console.WriteLine(\"OPERADORES UNARIOS: (+) y (-): Indican el signo del número. (++) y (--): Incremento y decremento, tanto en forma pre como post. (!): Negación lógica. (~): Complemento a bit.\");\n                Console.WriteLine(\"Le gustaria ver un ejemplo de incremento y decremento?. 'si' o 'no'\");\n                input = Console.ReadLine();\n                if(input == \"si\")\n                {\n                    Console.WriteLine(\"EJEMPLO INCREMENTO POR CADA VUELTA\");\n                    for (int i = 0; i <= 10; i++)\n                    {\n                        Console.WriteLine(i);\n                    }\n\n                    Console.WriteLine(\"EJEMPLO DECREMENTO POR CADA VUELTA\");\n                    for (int i = 10; i >= 0; i--)\n                    {\n                        Console.WriteLine(i);\n                    }\n\n                }\n                //Operadores misceláneos\n                Console.WriteLine(\"Operadores misceláneos: Incluyen operadores como el operador ternario y el operador de tipo. Ejemplos: ?: (operador ternario), is (verifica el tipo), as (convierte tipos).\");\n                Console.WriteLine(\"Escriba 'si' para ver ejemplo de cada uno\");\n                input= Console.ReadLine();\n\n                if (input == \"si\")\n                {\n                    Console.WriteLine(\"1. Operador ternario (?:) es una forma compacta de una declaracion (if-else)\");\n                    Console.WriteLine($\"valor de ternario aTernario = {aTernario}. valor de ternario bTernario = {bTernario}\");\n                    Console.WriteLine(\"\\n\");\n                    resultadoTernario = aTernario > bTernario ? aTernario : bTernario;\n                    Console.WriteLine(\"el numero mas mayor es: \" + resultadoTernario);\n\n                    Console.WriteLine(\"\\n\");\n\n                    Console.WriteLine(\"2. Operador (is). este operador sirve para verificar de que tipo es un objecto\");\n                    Console.WriteLine(\"Escriba 'si' para mostrar un ejemplo\");\n                    input = Console.ReadLine();\n\n                    if (input == \"si\")\n                    {\n                        Console.WriteLine(\"private object obj = 'hello'\");\n                        if (obj is string)\n                        {\n                            Console.WriteLine(\"obj es un tipo string\");\n                        }\n                        else\n                        {\n                            Console.WriteLine(\"obj no es de tipo string\");\n                        }\n                    }\n\n                    Console.WriteLine(\"3. Operador (as). Este operador se utiliza para convertir un objeto a un tipo específico. Si la conversión no es posible, devuelve (Null) en vez de una exepcion\");\n                    Console.WriteLine(\"Escriba 'si' para mostrar un ejemplo\");\n                    input = Console.ReadLine();\n\n                    if (input == \"si\")\n                    {\n                        if (word != null)\n                        {\n                            Console.WriteLine(\"se a realizado la convercion de manera correcta\");\n                        }\n                    }\n                    Console.WriteLine(\"\\n\");\n                }\n                //4. DIFICULTAD EXTRA(opcional):\n                //Crea un programa que imprima por consola todos los números comprendidos\n                //entre 10 y 55(incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n                Console.WriteLine(\"Crea un programa que imprima por consola todos los números comprendidos entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\");\n                Console.WriteLine(\"escriba si para mostrar\");\n                input = Console.ReadLine();\n\n                if (input == \"si\")\n                {\n                    Console.WriteLine(\"1. Numeros comprendidos entre 10 y 55\");\n                    for (int i = 10; i <= 55; i++)\n                    {\n                        Console.WriteLine(i);\n                    }\n                    Console.WriteLine(\"\\n\");\n                    Console.WriteLine(\"pares, y que no son ni el 16 ni múltiplos de 3.\");\n                    for (int i = 0; i <= 20; i++)\n                    {\n                        if (i%2 == 0 && i != 16 && i%3 != 0)\n                        {\n                            Console.WriteLine(i);\n                        }\n                    }\n                }\n\n                \n            }\n\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c#/RXVLC.cs",
    "content": "﻿using System;\nusing System.Linq;\n\nnamespace R01___2024\n{\n    internal class Program\n    {\n        static void Main(string[] args)\n        {\n            /*\n             * EJERCICIO:\n             * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n             *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n             *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n             * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n             *   que representen todos los tipos de estructuras de control que existan\n             *   en tu lenguaje:\n             *   Condicionales, iterativas, excepciones...\n             * - Debes hacer print por consola del resultado de todos los ejemplos.\n             *\n             * DIFICULTAD EXTRA (opcional):\n             * Crea un programa que imprima por consola todos los números comprendidos\n             * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n             *\n             * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n             */\n\n            //aritméticos\n            int a = 10;\n            int b = 5;\n            int suma = a + b;       // Suma\n            int resta = a - b;      // Resta\n            int multiplicacion = a * b;  // Multiplicación\n            int division = a / b;        // División\n            int modulo = a % b;          // Módulo\n\n            //lógicos\n            bool condicion1 = true;\n            bool condicion2 = false;\n\n            bool resultadoAnd = condicion1 && condicion2;  // AND lógico\n            bool resultadoOr = condicion1 || condicion2;   // OR lógico\n            bool resultadoNot = !condicion1;              // NOT lógico\n\n            //de comparación\n            int x = 5;\n            int y = 10;\n\n            bool igual = x == y;      // Igual a\n            bool diferente = x != y;  // Diferente de\n            bool mayorQue = x > y;    // Mayor que\n            bool menorQue = x < y;    // Menor que\n            bool mayorIgual = x >= y; // Mayor o igual que\n            bool menorIgual = x <= y; // Menor o igual que\n\n            //de asignación\n            int num = 10;\n            num += 5;   // num = num + 5;\n            num -= 3;   // num = num - 3;\n            num *= 2;   // num = num * 2;\n            num /= 4;   // num = num / 4;\n            num %= 2;   // num = num % 2;\n\n            //de momento no controlo identidad\n\n            //de pertenencia\n            int[] array = { 1, 2, 3, 4, 5 };\n            bool contiene = array.Contains(3);      // Verifica si el array contiene el valor 3\n            bool noContiene = !array.Contains(6);   // Verifica si el array no contiene el valor 6\n\n            //de momento no controlo de bits\n\n            //estructuras de control:\n            //if-else\n            int numero = 10;\n\n            if (numero > 0)\n            {\n                Console.WriteLine(\"El número es positivo.\");\n            }\n            else if (numero == 0)\n            {\n                Console.WriteLine(\"El número es cero.\");\n            }\n            else\n            {\n                Console.WriteLine(\"El número es negativo.\");\n            }\n            Console.WriteLine();\n\n            //for\n            for (int i = 0; i < 5; i++)\n            {\n                Console.WriteLine($\"Iteración número: {i}\");\n            }\n            Console.WriteLine();\n\n            //while\n            int contador = 0;\n            while (contador < 3)\n            {\n                Console.WriteLine($\"Contador actual: {contador}\");\n                contador++;\n            }\n            Console.WriteLine();\n\n            //dowhile\n            int j = 0;\n            do\n            {\n                Console.WriteLine($\"El valor de j es: {j}\");\n                j++;\n            } while (j < 2);\n            Console.WriteLine();\n\n            //de momento no controlo muy bien trycatch\n\n            //Dificultad extra:\n            bool primero = true;\n            for (int i = 10; i<=55; i++)\n            {\n                if (i != 16 && i % 2 == 0 && i % 3 != 0)\n                {\n                    if (!primero)\n                    {\n                        Console.Write(\", \");\n                    }\n                    Console.Write(i);\n                    primero = false;\n                }\n            }\n\n            Console.ReadKey();\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c#/SBS24.cs",
    "content": "﻿//Author: Sandra Baigorri Saez\nusing System;\nusing System.Security.Cryptography;\n\n\nnamespace _01OperadoresyEsctructurasDeControl\n{\n    internal class Program\n    {\n        static void Main(string[] args)\n        {      \n            /* Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n             *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n             *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)*/\n            int num = 5, num2 = 3;\n            // ------------------------- ARITMETICOS -------------------------\n            int suma = num + 1; //sumo 1 a un num\n            Console.WriteLine(\"La suma es: \" + suma);\n            int resta = num - 1; //resto 1 a un num\n            Console.WriteLine(\"La resta es: \" + resta);\n            int division = num / 2; //divido num entre 2\n            Console.WriteLine(\"La division es: \" + division);\n            int multiplicacion = num * 2; //multiplico num por 2\n            Console.WriteLine(\"La multiplicacion es: \" + multiplicacion);\n            int resto = num % 2; //% nos da el resto de dividir num entre 2\n            Console.WriteLine(\"El resto es: \" + resto);\n\n            // ------------------------- LOGICOS -------------------------\n            Console.WriteLine(num == num2 && num == num2);//&& se tienen que dar las dos condiciones de los lados para que sea verdadero, con que una no se cumpla es falso\n\n            Console.WriteLine(num == num2 || num == num2);//|| si se cumple una de las dos condiciones de los lados sedría verdadero, cuando no se cumple ninguna de las condiciones es falso\n            Console.WriteLine(!(num == num2));//si num es igual a num2 dara falso porque ! niega la condicion verdadero y se convierte en falso\n                                              //si num es distinto a num2 dara verdadero porque ! niega la condicion false y se convierte en verdadero\n\n            // ------------------------- COMPARACION -------------------------\n            Console.WriteLine(7 < 5);   // MENOR QUE: output: False\n            Console.WriteLine(7 > 5);   // MAYOR QUE: output: True\n            Console.WriteLine(0 <= 5);   // MENOR O IGUAL: output: True\n            Console.WriteLine(0 >= 5);   // MAYOR O IGUAL: output: False\n            Console.WriteLine(0 == 5);   // IGUAL: output: False\n            Console.WriteLine(0 != 5);   // DISTINTO: output: True\n\n            // ------------------------- ASIGNACION -------------------------\n            Console.WriteLine(num = num2); //asigno a num el valor de num3\n            Console.WriteLine(num++); //sumo 1 a un número o num-; le resto 1\n            Console.WriteLine(num -= num2); // le resto num2 a num y con la suma ( num += num2), multiplicación ( num *= num2), division ( num /= num2) y resto ( num %= num2)\n\n\n            // ------------------------- BITS -------------------------\n            uint a = 0b_0000_1111_0000_1111_0000_1111_0000_1100;\n            uint b = ~a;\n            Console.WriteLine(b = a << 2);\n            Console.WriteLine(b = a >> 2);\n            Console.WriteLine(b = a & b);\n            Console.WriteLine(b = a ^ b);\n            Console.WriteLine(b = a | b);\n\n\n            /*Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n             *que representen todos los tipos de estructuras de control que existan\n             *en tu lenguaje:\n             *Condicionales, iterativas, excepciones...*/\n            if(num == num2) \n            { \n                Console.WriteLine(\"Son iguales\");\n            }\n            else \n            {\n                Console.WriteLine(\"Son distintos\");\n            }\n            while(num < 7)\n            {\n                Console.WriteLine(\"El numero del while es: \" + num);\n                num++;\n            }\n\n            do \n            {\n                Console.WriteLine(\"El numero del do while es: \" + num);\n                num--;\n            } \n            while(num!=0);\n\n            switch(num) \n            { \n                case 0:\n                    Console.WriteLine(\"Número del swith es: \" + num);\n                    break;\n                case 1:\n                    Console.WriteLine(\"Número del swith es: \" + num);\n                    break;\n                case 2:\n                    Console.WriteLine(\"Número del swith es: \" + num);\n                    break;\n                default:\n                    Console.WriteLine(\"default\");\n                    break;\n            }\n\n            \n            int[] numeros = new int[5];\n            for (int i = 0; i <= numeros.Length - 1; i++)\n            {\n                numeros[i] = i;\n            }\n            foreach (int i in numeros)\n            {\n                Console.WriteLine(\"Números foreach: \" + numeros[i]);\n            }\n\n\n            /*DIFICULTAD EXTRA(opcional):\n             *Crea un programa que imprima por consola todos los números comprendidos\n             *entre 10 y 55(incluidos), pares, y que no son ni el 16 ni múltiplos de 3.*/\n            for (int i = 10; i <= 55; i++)\n            {\n                if(i%2 == 0)\n                {\n                    if((i != 16) && (i%3!=0))\n                    {\n                        Console.WriteLine(\"Número: \" + i);\n                    }                    \n                }                \n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c#/XPERIARGLUNA.cs",
    "content": "using System;\n\nnamespace Xperiargluna\n{\n    class Program\n    {\n        static void Main(string[] args)\n        {\n            //OPERADORES ARITMÉTICOS\n            Console.WriteLine($\"Suma: 10 + 2 = {10 + 2}\");\n            Console.WriteLine($\"Resta: 10 - 2 = {10 - 2}\");\n            Console.WriteLine($\"Multiplicación: 10 * 2 = {10 * 2}\");\n            Console.WriteLine($\"División: 10/ 2 = {10 / 2}\");\n            Console.WriteLine($\"Módulo: 10 % 2 = {10 % 2}\");\n\n            //OPERADORES DE COMPARACIÓN\n            Console.WriteLine($\"Igualdad: 10 == 2 es {10 == 3}\");\n            Console.WriteLine($\"Desigualdad: 10 != 2 es {10 != 3}\");\n            Console.WriteLine($\"Mayor que: 10 > 2 es {10 > 3}\");\n            Console.WriteLine($\"Menor que: 10 < 2 es {10 < 3}\");\n            Console.WriteLine($\"Mayor o igual que: 10 >= 2 es {10 >= 3}\");\n            Console.WriteLine($\"Menor o igual que: 10 <= 2 es {10 <= 3}\");\n\n            //OPERADORES LÓGICOS\n            Console.WriteLine($\"AND &&: 10 + 2 == 12 and 5 -1 == 4 es {10 + 2 == 12 && 5 - 1 == 4}\");\n            Console.WriteLine($\"OR ||: 10 + 2 == 12 or 5 -1 == 2 es {10 + 2 == 12 || 5 - 1 == 2}\");\n            Console.WriteLine($\"NOT !:  10 + 2 != 10 es {10 + 2 != 10}\");\n\n            //OPERADORES DE ASIGNACIÓN\n            int my_number = 3;      //asignación\n            Console.WriteLine(my_number);\n            my_number += 1;       //suma y asignación\n            Console.WriteLine(my_number);\n            my_number -= 1;      //resta y asignación\n            Console.WriteLine(my_number);\n            my_number *= 2;      //multiplicación y asignación\n            Console.WriteLine(my_number);\n            my_number /= 2;      //división y asignación\n            Console.WriteLine(my_number);\n            my_number %= 2;       //módulo y asignación\n            Console.WriteLine(my_number);\n\n            //OPERADORES DE PERTENENCIA\n            //contains - contiene\n            string texto = \"Hola, c#\";\n            bool contiene = texto.Contains(\"c#\");\n            Console.WriteLine(contiene);\n\n            //OPERADORES DE IDENTIDAD \n            //ReferenceEquals en objetos\n            object obj1 = new object();\n            object obj2 = obj1;\n            object obj3 = new object();\n\n            Console.WriteLine(object.ReferenceEquals(obj1, obj2));\n            Console.WriteLine(object.ReferenceEquals(obj1, obj3));\n\n\n            //OPERADORES DE BIT\n            // 7 = 0111\n            // 4 = 0100\n            Console.WriteLine($\"AND: 7 & 4 = {7 & 4}\"); // 0100\n            Console.WriteLine($\"OR: 7 | 4 = {7 | 4}\"); // 0111\n            Console.WriteLine($\"XOR: 7 ^ 4 = {7 ^ 4}\"); // 0011\n            Console.WriteLine($\"NOT: ~7 = {~7}\"); // invierte los bits de 0111 a 1000 \n            Console.WriteLine($\"Desplazamiento a la derecha: 7 >> 2 = {7 >> 2}\"); // 0001\n            Console.WriteLine($\"Desplazamiento a la izquierda: 7 << 2 = {7 << 2}\"); // 011100\n\n\n            //ESTRUCTURAS DE CONTROL\n\n            //condicionales\n            string my_name = \"Jesús\";\n\n            if (my_name == \"Pepe\")\n            {\n                Console.WriteLine(\"Mi nombre es Pepe\");\n            }\n            else if (my_name == \"Jesús\")\n            {\n               Console.WriteLine(\"Mi nombre es Jesús\");   \n            }\n            else\n            { \n                  Console.WriteLine(\"Mi nombre no es Pepe\");         \n            }\n\n            //iterativas bucle for\n\n            for (int i = 0; i < 6; i++)\n            {\n                Console.WriteLine(i);\n            }\n\n            //bucle while\n            int contador = 1;\n            while (contador <= 5) \n            {\n                Console.WriteLine($\"Número: {contador}\");\n                contador++; //incrementa el contador\n            }\n\n            //bucle do while \n            int contador2 = 2;\n            do\n            {\n                Console.WriteLine($\"Número: {contador2}\");\n                contador2++;\n            }\n            while (contador2 <= 5);\n\n            //excepciones\n            try\n            {\n                int divisor = 0;\n                int resultado = 10 / divisor;\n            }\n            catch (DivideByZeroException error)\n            {\n                Console.WriteLine(\"Se ha producido un error \" + error.Message);\n            }\n            finally \n            {\n                Console.WriteLine(\"Operación finalizada \");           \n            }\n\n            //Ejercicio extra \n            for (int i = 10; i <= 56; i++)\n            {\n                if (i % 2 == 0 && i != 16 && i % 3 != 0 )\n                {\n                    Console.WriteLine(i);\n                }\n            }\n            \n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c#/abrahamraies.cs",
    "content": "// Author: Abraham Raies https://github.com/abrahamraies\n\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritmticos, lgicos, de comparacin, asignacin, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que t quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los nmeros comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni mltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n// Ejercicio 1:\n\ninternal class Program\n{\n    // Variable global\n    static int globalVariable = 70;\n\n    private static void Main(string[] args)\n    {\n        // Operadores aritmticos\n        int a = 20;\n        int b = 4;\n        Console.WriteLine(\"Operadores aritmticos:\");\n        Console.WriteLine($\"a + b = {a + b}\"); // Suma\n        Console.WriteLine($\"a - b = {a - b}\"); // Resta\n        Console.WriteLine($\"a * b = {a * b}\"); // Multiplicacin\n        Console.WriteLine($\"a / b = {(double)a / b}\"); // Divisin\n        Console.WriteLine($\"a % b = {a % b}\"); // Mdulo\n\n        // Operadores lgicos\n        bool x;\n        bool y = false;\n        Console.WriteLine(\"\\nOperadores lgicos:\");\n        Console.WriteLine($\"x && y: {x && y}\"); // AND\n        Console.WriteLine($\"x || y: {x || y}\"); // OR\n        Console.WriteLine($\"!x: {!x}\"); // NOT\n\n        // Operadores de comparacin\n        Console.WriteLine(\"\\nOperadores de comparacin:\");\n        Console.WriteLine($\"a == b: {a == b}\"); // Igual a\n        Console.WriteLine($\"a != b: {a != b}\"); // Diferente de\n        Console.WriteLine($\"a > b: {a > b}\"); // Mayor que\n        Console.WriteLine($\"a < b: {a < b}\"); // Menor que\n        Console.WriteLine($\"a >= b: {a >= b}\"); // Mayor o igual que\n        Console.WriteLine($\"a <= b: {a <= b}\"); // Menor o igual que\n\n        // Operadores de asignacin\n        Console.WriteLine(\"\\nOperadores de asignacin:\");\n        int c = 10;\n        Console.WriteLine($\"c = {c}\");\n        c += 2; // Equivalente a c = c + 2\n        Console.WriteLine($\"c += 3: {c}\");\n        c -= 3; // Equivalente a c = c - 3\n        Console.WriteLine($\"c -= 2: {c}\");\n        c *= 4; // Equivalente a c = c * 4\n        Console.WriteLine($\"c *= 2: {c}\");\n        c /= 5; // Equivalente a c = c / 5\n        Console.WriteLine($\"c /= 4: {c}\");\n        c %= 6; // Equivalente a c = c % 6\n        Console.WriteLine($\"c %= 3: {c}\");\n\n        // Operadores de identidad (Referencia y valor)\n        Console.WriteLine(\"\\nOperadores de identidad:\");\n        string s1 = \"Mate\";\n        string s2 = \"Mate\";\n        Console.WriteLine($\"s1 == s2: {s1 == s2}\"); // Comparacin de valor\n        Console.WriteLine($\"object.ReferenceEquals(s1, s2): {object.ReferenceEquals(s1, s2)}\"); // Comparacin de referencia\n\n        // Estructuras de control\n        Console.WriteLine(\"\\nEstructuras de control:\");\n\n        // Condicionales\n        if (a > b)\n        {\n            Console.WriteLine(\"a es mayor que b\");\n        }\n        else\n        {\n            Console.WriteLine(\"a no es mayor que b\");\n        }\n\n        // Switch\n        switch (a)\n        {\n            case 20:\n                Console.WriteLine(\"a es 20\");\n                break;\n            case 5:\n                Console.WrteLine(\"a es 5\");\n                break;\n            default:\n                Console.WriteLine(\"a no es 20\");\n                break;\n        }\n\n        // Bucles\n        Console.WriteLine(\"\\nBucle for:\");\n        for (int i = 0; i < 5; i++)\n        {\n            Console.WriteLine(i);\n        }\n\n        Console.WriteLine(\"\\nBucle while:\");\n        int j = 0;\n        while (j < 5)\n        {\n            Console.WriteLine(j);\n            j++;\n        }\n\n        Console.WriteLine(\"\\nBucle do-while:\");\n        int k = 0;\n        do\n        {\n            Console.WriteLine(k);\n            k++;\n        } while (k < 5);\n\n        Console.WriteLine(\"\\nBucle foreach:\");\n        int[] numeros = { 1, 2, 3, 4, 5, 6, 7 };\n        foreach (var num in numeros)\n        {\n            Console.WriteLine($\"Este es el bluche ForEach {num}\");\n        }\n\n        // Excepciones\n        Console.WriteLine(\"\\nExcepciones:\");\n\n        try\n        {\n            int x = 3;\n            int y = 0;\n            Console.WriteLine(x / y);\n        }\n        catch (Exception e)\n        {\n            Console.WriteLine(\"Error: \" + e.Message);\n        }\n        finally\n        {\n            Console.WriteLine(\"Finally\");\n        }\n\n        // Ejercicio Extra:\n        Console.WriteLine(\"\\nEjercicio Extra\");\n        ImprimirNumeros();\n    }\n\n    static void ImprimirNumeros()\n    {\n        for (int i = 10; i <= 55; i++)\n        {\n            if (i % 2 == 0 && i != 16 && !(i % 3 == 0))\n            {\n                Console.WriteLine(i);\n            }\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c#/angelsanchezt.cs",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n using System;\n\nclass Roadmap_01\n{\n    static void Main()\n    {\n        // Operadores Aritméticos\n        Console.WriteLine(\"Operadores Aritméticos:\");\n        int a = 5;\n        int b = 3;\n        Console.WriteLine($\"Suma: {a + b}\");\n        Console.WriteLine($\"Resta: {a - b}\");\n        Console.WriteLine($\"Multiplicación: {a * b}\");\n        Console.WriteLine($\"División: {a / b}\");\n        Console.WriteLine($\"Módulo: {a % b}\");\n        Console.WriteLine();\n\n        // Operadores Lógicos\n        Console.WriteLine(\"Operadores Lógicos:\");\n        bool p = true;\n        bool q = false;\n        Console.WriteLine($\"AND lógico: {p && q}\");\n        Console.WriteLine($\"OR lógico: {p || q}\");\n        Console.WriteLine($\"NOT lógico: {!p}\");\n        Console.WriteLine();\n\n        // Operadores de Comparación\n        Console.WriteLine(\"Operadores de Comparación:\");\n        int x = 10;\n        int y = 20;\n        Console.WriteLine($\"Igual: {x == y}\");\n        Console.WriteLine($\"No igual: {x != y}\");\n        Console.WriteLine($\"Mayor que: {x > y}\");\n        Console.WriteLine($\"Menor que: {x < y}\");\n        Console.WriteLine($\"Mayor o igual que: {x >= y}\");\n        Console.WriteLine($\"Menor o igual que: {x <= y}\");\n        Console.WriteLine();\n\n        // Operadores de Asignación\n        Console.WriteLine(\"Operadores de Asignación:\");\n        int z = 7;\n        Console.WriteLine($\"Antes de la asignación: {z}\");\n        z += 3;\n        Console.WriteLine($\"Después de la asignación: {z}\");\n        Console.WriteLine();\n\n        // Estructuras de Control\n        Console.WriteLine(\"Estructuras de Control:\");\n\n        // Condicionales\n        if (a > b)\n        {\n            Console.WriteLine(\"a es mayor que b\");\n        }\n        else\n        {\n            Console.WriteLine(\"a no es mayor que b\");\n        }\n\n        // Iterativas\n        Console.WriteLine(\"Bucle for:\");\n        for (int i = 10; i <= 55; i++)\n        {\n            if (i % 2 == 0 && i != 16 && i % 3 != 0)\n            {\n                Console.WriteLine(i);\n            }\n        }\n\n        // Excepciones\n        Console.WriteLine(\"Manejo de excepciones:\");\n        try\n        {\n            // Simular una excepción (división por cero)\n            int resultado = a / (b - 3);\n            Console.WriteLine($\"Resultado: {resultado}\");\n        }\n        catch (Exception ex)\n        {\n            Console.WriteLine($\"Excepción: {ex.Message}\");\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c#/arkmiguel379.cs",
    "content": "﻿// Operadores Aritmeticos\n\nint num1 = 5;\nint num2 = 2;\n\nint suma = num1 + num2; //Operacion de suma\nint resta = num1 - num2; // Operacion de resta\nint mutiplicacion = num1 * num2; // Operacion de multiplicacion\nint division = num1 / num2; // Operacion de division\nint modulo = num1 % num2; // Operacion de residuo de una division\ndouble potencia = Math.Pow(num1, num2); // Potenciación\n\nConsole.WriteLine(suma);\nConsole.WriteLine(resta);\nConsole.WriteLine(mutiplicacion);\nConsole.WriteLine(division);\nConsole.WriteLine(modulo);\nConsole.WriteLine(potencia);\n\nConsole.WriteLine(\"\\n\");\n\n//Operadores de comparacion \n\nbool igual = num1 == num2; // Valor A igual que valor B\nbool diferente = num1 != num2; // Valor A diferente de valor B\nbool mayor = num1 > num2; // Valor A mayor que valor B\nbool menor = num1 < num2; // Valor A menor que valor B\nbool mayorIgual = num1 >= num2; // Valor A mayor o igual que valor B\nbool menorIgual = num1 <= num2; // Valor A menor o igual que valor B\n\n\nConsole.WriteLine(igual);\nConsole.WriteLine(diferente);\nConsole.WriteLine(mayor);\nConsole.WriteLine(menor);\nConsole.WriteLine(mayorIgual);\nConsole.WriteLine(menorIgual);\n\nConsole.WriteLine(\"\\n\");\n\n// Operadores logicos\n\nbool and = (num1 == num2) && (num1 > num2); // Operador Y (Se tienen que cumplir las dos condiciones para que el valor sea true)\nbool or = (num1 == num2) || (num1 > num2); // Operador O (Se tiene una de las dos condiciones para que el valor sea true)\nbool not = !(num1 == num2); // Operador NO (El valor es el contrario al que realmente es)\n\n\nConsole.WriteLine(and);\nConsole.WriteLine(or);\nConsole.WriteLine(not);\n\n// Operadores de asignacion\n\nint x = 10;\n\nint s = x += 3; // El valor de x se suma con 3\nint r = x -= 3; // El valor de x se resta con 3\nint m = x *= 3; // El valor de x se multiplica con 3\nint d = x /= 3; // El valor de x se divide con 3\nint re = x %= 3; // El valor dado es el residuo de la division de x entre 3\nint y = x &= 3; // Las dos condiciones se cumplen\nint o = x |= 3; // Una de las dos condiciones se cumple\n\nConsole.WriteLine(\"\\n\");\nConsole.WriteLine(s);\nConsole.WriteLine(r);\nConsole.WriteLine(m);\nConsole.WriteLine(d);\nConsole.WriteLine(re);\nConsole.WriteLine(y);\nConsole.WriteLine(o);\n\nConsole.WriteLine(\"\\n\");\n\n// Estructuras condicionales\n\n\nif (num1 == num2)\n{\n    Console.WriteLine($\"{num1} es igual que {num2}\");\n}\nelse if (num1 > num2)\n{\n    Console.WriteLine($\"{num1} es mayor que {num2}\");\n}\nelse if (num1 < num2)\n{\n    Console.WriteLine($\"{num1} es menor que {num2}\");\n}\nelse if (num1 != num2)\n{\n    Console.WriteLine($\"{num1} es diferente de {num2}\");\n}\n\nConsole.WriteLine(\"\\n\");\n\n// Estructuras iterativas (Bucles)\n\n\nwhile (num1 > num2)\n{\n    Console.WriteLine($\"num2 a subido su valor en 1. Ahora es {num2 + 1}\");\n    num2 += 1;\n}\nConsole.WriteLine(\"\\n\");\n\nint contador = 11;\ndo\n{\n    Console.WriteLine(\"Codigo que se ejecuta al menos una vez\");\n    contador++;\n\n} while (contador < 10);\n\n\nConsole.WriteLine(\"\\n\");\n\nfor (int i = 0; i <= num1; i++)\n{\n    Console.WriteLine($\"El valor de num1 es: {num1 + i}\");\n}\n\nConsole.WriteLine(\"\\n\");\n\n// Control de excepciones\n\ntry\n{\n    Console.WriteLine(65 + \"Cadena\");\n}\ncatch\n{\n    Console.WriteLine(\"Se ha producido un error\");\n}\nfinally\n{\n    Console.WriteLine(\"El control de excepciones a finalizado\");\n\n}\n\nConsole.WriteLine(\"\\n\");\n\n//============================================== EJERCICIO EXTRA =======================================================\n\nfor (int i = 10; i <= 55; i++)\n{\n    if (i != 16 && i % 2 == 0 && i % 3 != 0)\n    {\n        Console.WriteLine(i);\n    }\n    \n}\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c#/charlerodriguez3.cs",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n */\n \n \nint num1 = 5;\n int num2 = 3;\n int num3;\n\n // unary operators. Only one variable is in use\n num3 = -num1; //NEGATIVE OPERATOR. Implicity if it's a number is that number times minus one\n Console.WriteLine(\"num3 is {0}\", num3);\n\n bool isSunny = true;\n Console.WriteLine(\"is it sunny? {0}\", !isSunny);//NEGATION OPERATOR IS USED WITH BOOL VARIABLES\n //SO THE NEGATION OF TRUE WILL BE FALSE AND VICEVERSA\n\n // increment operators\n int num = 0;\n num++;\n Console.WriteLine(\"num is {0}\", num);\n Console.WriteLine(\"num is {0}\", num++);// increment operator, first assign or print of the variable and then the decrement operation will take action\n // pre increment\n Console.WriteLine(\"num is {0}\", ++num);//before printing the value the increment will take action\n\n // decrement opertor\n num--;\n Console.WriteLine(\"num is {0}\", num);\n Console.WriteLine(\"num is {0}\", num--);// same as increment in this line\n // pre decrement\n Console.WriteLine(\"num is {0}\", --num); //same as increment\n\n int result;\n\n result = num1 + num2; //SUM\n Console.WriteLine(\"result of num1 + num2 is {0}\", result);\n result = num1 - num2;//SUSTRACTION\n Console.WriteLine(\"result of num1 - num2 is {0}\", result);\n result = num1 / num2; //DIVIDE\n Console.WriteLine(\"result of num1 / num2 is {0}\", result);\n result = num1 * num2; //MULTIPLY\n Console.WriteLine(\"result of num1 * num2 is {0}\", result);\n result = num1 % num2; // MODULE\n Console.WriteLine(\"result of num1 % num2 is {0}\", result);\n\n // relational and type operators\n bool isLower;\n isLower = num1 < num2;// LESS THAN \n Console.WriteLine(\"result of num1 < num2 is {0}\", isLower);\n//OTHER RELATIONAL OPERATORS\n/*\n> GREATER THAN\n<= LESS OR EQUAL THAN\n>= GREATER OR EQUAL THAN\n\n*/\n\n\n // equality operator\n bool isEqual;\n isEqual = num1 == num2;\n Console.WriteLine(\"result of num1 == num2 is {0}\", isEqual);\n\n isEqual = num1 != num2; //DIFFERENT OR NOT EQUAL OPERATOR\n Console.WriteLine(\"result of num1 != num2 is {0}\", isEqual);\n\n // conditional operators\n bool isLowerAndSunny;\n // condition1 AND condition2\n isLowerAndSunny = isLower && isSunny; // AND OPERATOR: BOTH SENTENCES HAVE TO BE TRUE\n Console.WriteLine(\"result of isLower && isSunny is {0}\", isLowerAndSunny);\n\n // condition1 OR condition2\n isLowerAndSunny = isLower || isSunny; // OR OPERATOR: EITHER ONE OR THE OTHER SENTENCES HAS TO BE TRUE SO THAT THE EXPRESSION IT IS TRUE\n Console.WriteLine(\"result of isLower || isSunny is {0}\", isLowerAndSunny);\n Console.ReadKey();\n\n //ternary operator\n// Assigns the variable of side left or right, having as a reference the \":\" symbol. If the condition between parenthesis is true, the left value will be assigned to the variable\n//if not the right value will be the selected.\nnum3 = (num1 > num3) ? num1 : num2;\n\n//CONDITIONALS\n\nisLowerAndSunny = false;\nnum1 = 5;\nnum2 = 3;\n\n//conditional if else\n\n\nif(isLowerAndSunny)\n{\n    num1 = num2;\n}\nelse\n{\n    num2 = num1;\n}\nConsole.WriteLine(\"Values num2: {0} num1: {1}\",num2,num1);\n\n//loop do while\n// do something until the condition express Truth\n// First you do something before checking the condition if it is true or false\ndo\n{\n    num2++;\n} while (num2 >= num1);\nConsole.WriteLine(num2);\n\n//loop while\n//first you check the condition and depends on its result, it will execute the code between the curly brackets\nwhile (num1 > 50)\n{\n    num1 += 5;\n}\nConsole.WriteLine(num1);\n//loop for\n//You decide when to start (paramter 1), when to stop the loop (parameter 2) and how much you will go forward between the beginning\n// and the finish of the loop\nfor (int i = 0; i < num1; i++)\n{\n    Console.WriteLine(\"Number: {0}\", i);\n}\n\n//foreach loop\n// Another way to go over a variable.\n//the expression variable1 IN variable2 decides to divide variable 2 into little pieces and assign them into\n//variable 1 which are going to change their value throughout the loop\nstring word = \"Greetings\";\n\nforeach (char c in word)\n{\n    Console.WriteLine(c);\n}\n\n\nint num3 = 0;\n\n//switch\n//given a value, the switch will validate through all the cases, and the selected case will execute its code\n//until the break statement\n//If none of the cases satisfy the condition, the default case will take action\n\nswitch (num3)\n{\n    case 0:\n        Console.WriteLine(\"The value of num3 is 0\");\n        break;\n    case 1:\n        Console.WriteLine(\"The value of num3 is 0\");\n        break;\n    default:\n        Console.WriteLine(\"Default option. It works as and else condition\");\n        break;\n}\n\n\n          \n//Exception\n//When a error ocurrs and in pro of the direction of not stopping the program.\n//We will throw and exception, which it could be created by us or defined by the programming language\ntry\n{\n    Console.WriteLine(num2 / num3);\n}catch (DivideByZeroException ex) {\n    throw new Exception ($\"You can't divide by zero {ex.Message}\");\n}\n\n /*\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seg\n\n */\n for(int i = 10; i < 56; i++)\n {\n     if(i % 2 == 0 && i != 16 && i % 3 != 0)\n     Console.WriteLine(i);\n }\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c#/cristopherfdev.cs",
    "content": "/* EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n using System;\nusing System.Security.Cryptography;\nclass Retos \n {\n    static void Main () \n    {\n        //Operadores Aritméticos \n\n        int suma = 12 + 5; \n        int resta = 25 - 3; \n        int multiplicacion = 5 * 5; \n        int division = 10 / 2; \n        int modulo = 30 % 3; \n        \n        int incremento = 10; \n        incremento++; \n\n        int decremento = 3; \n        decremento--; \n\n        Console.WriteLine (\"Suma: \" + suma); \n        Console.WriteLine (\"Resta: \" + resta); \n        Console.WriteLine (\"Multiplicación: \" + multiplicacion); \n        Console.WriteLine (\"division: \" + division); \n        Console.WriteLine (\"modulo: \" + modulo);\n        Console.WriteLine (\"Incremento: \" + incremento);\n        Console.WriteLine (\"Decremento: \" + decremento);\n    \n        //Operadores Lógicos\n\n        bool logico = 12 + 3 == 15 && 12 -3 == 9; //AND \n        Console.WriteLine (logico);\n\n        bool logico2 = 10 + 3 == 13 || 10 + 5 == 25; //OR \n        Console.WriteLine (logico2);\n\n        bool logico3 = 12 * 1 == 11; //NOT\n        Console.WriteLine (logico3!);\n\n        //Operadores de Comparación \n\n        int a = 15; \n        int b = 10; \n\n        if (a == b) \n        {\n            Console.WriteLine (\"a es igual a b\");\n        }\n        else if (a != b)\n        {\n             Console.WriteLine (\"a es diferente a b\");\n        }\n\n        if (a > b) \n        {\n            Console.WriteLine (\"a es mayor que b\");\n        }\n        else if (a < b)\n        {\n            Console.WriteLine (\"a es menor que b\");\n        }\n\n        if (a >= b)\n        {\n            Console.WriteLine (\"a es mayor o igual que b\");\n        }\n        if (a <= b)\n        {\n            Console.WriteLine (\"a es menor o igual que b\");\n        }\n            \n        //Operadores de Asignación \n\n        int asignacion = 3; \n        Console.WriteLine (\" \" + (asignacion +=5)); \n        Console.WriteLine (\" \"+ (asignacion -= 1)); \n        Console.WriteLine (\" \"+ (asignacion *= 4)); \n        Console.WriteLine (\" \"+ (asignacion /= 2));\n        Console.WriteLine (\" \"+ (asignacion %= 3));\n\n        //Operadores de Identidad \n        int c = 12; \n        int d = 20; \n\n        Console.WriteLine (\"Igualdad: \"+ (c == d)); \n        Console.WriteLine (\"Desigualdad: \"+ (c != d)); \n        Console.WriteLine (object.ReferenceEquals (c, d));\n\n        //Operadores de Bitwise \n        int e = 20; \n        int f = 8; \n\n        Console.WriteLine (\" \"+ (e & f)); //AND Bitwise \n        Console.WriteLine (\" \"+ (e | f)); //OR Bitwise\n        Console.WriteLine (\" \"+ (e ^ f)); //XOR Bitwise \n        Console.WriteLine (\" \"+ (~ f)); //NOT Bitwise \n        Console.WriteLine (\" \"+ (e << 2)); //Desplazamiento a la izquierda\n        Console.WriteLine (\" \"+ (e >> 3)); //Desplazamiento a la derecha        \n        \n        //Programa \n\n    }\n\nclass Program\n{\n    static void Main()\n    {\n        for (int i = 10; i <= 55; i++)\n        {\n            if (i % 2 == 0 && i != 16 && i % 3 != 0)\n            {\n                Console.WriteLine(i);\n            }\n        }\n    }\n}\n\n    }"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c#/devcherry1.cs",
    "content": "using System;\n\nclass Program\n{\n    static void Main()\n    {\n        int ejemplo1 = 15;\n        int ejemplo2 = 20;\n        int ejemplo3;\n\n        if (ejemplo1 == 15)\n        {\n            ejemplo1 = ejemplo1 + 19;\n            ejemplo2 /= 10;\n            ejemplo3 = ejemplo2 % 3;\n            Console.WriteLine(ejemplo3);\n        }\n        else\n        {\n            ejemplo1 -= 70;\n            ejemplo2 = ejemplo2 * 90;\n            Console.WriteLine(ejemplo1);\n        }\n        for (int i = 10; i <= 55; i++ )\n        {\n            if (i % 2 == 0 && i % 3 != 0 && i != 16)\n            {\n                Console.WriteLine(i);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c#/estuardodev.cs",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\nusing System;\n\nclass Program\n{\n    // Operadores aritméticos\n    private static int asignacion = 0;\n    private static int suma = 4 + 2;\n    private static int resta = 5 - 2;\n    private static int multiplicacion = 5 * 2;\n    private static int division = 0;\n    private static int residuo = 5 % 2;\n\n    public static void Main(string[] args)\n    {\n        Console.WriteLine(\"Resta: \" + resta);\n        Console.WriteLine(\"Residuo: \" + residuo);\n\n        if (suma == 6)\n        {\n            Console.WriteLine(\"Suma es 6\");\n        } else\n        {\n            Console.WriteLine(\"Suma no es 6 :(\");\n        }\n\n        while(asignacion < multiplicacion)\n        {\n            Console.WriteLine(asignacion);\n            asignacion++;\n        }\n\n        try\n        {\n            division = 150 / 120;\n        } catch (Exception e)\n        {\n            Console.WriteLine(\"No se puede dividir por: \" + e);\n        }\n\n        int contador_extra = 10;\n        Console.WriteLine(\"------ DIFICULTAD EXTRA -------\");\n        while (contador_extra <= 55)\n        {\n            if(contador_extra != 16 && contador_extra % 3 != 0)\n            {\n                Console.WriteLine(contador_extra);\n            }\n\n            contador_extra++;\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c#/gomezcamilo9701.cs",
    "content": "using System;\n/*\n* EJERCICIO:\n* - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n*   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n*   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n* - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n*   que representen todos los tipos de estructuras de control que existan\n*   en tu lenguaje:\n*   Condicionales, iterativas, excepciones...\n* - Debes hacer print por consola del resultado de todos los ejemplos.\n*\n* DIFICULTAD EXTRA (opcional):\n* Crea un programa que imprima por consola todos los números comprendidos\n* entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n*\n* Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n*/\nnamespace CeroUno\n{\n    class CeroUno\n    {\n        static void Main(string[] args)\n        {\n            int a = 2; int b = 3; int c = 4;\n\n            //Aritméticos\n            int suma = a + b;\n            int resta = b - a;\n            int multi = a * a;\n            int divi = a / 2;\n            int modulo = c % a;\n            //Asignación\n            int variable = 10;\n            a += 5; //a es igual a 7\n            c -= 1; //c es igual a 3\n            b *= 2; //b es igual a 6\n            c /= a; //b es igual a 2\n            //Comparación\n            bool igual = a == b;\n            bool noIgual = a != b;\n            bool mayorQue = a > b;\n            bool menorQue = b > a;\n            bool mayorIgualQue = a >= b;\n            bool menorIgualQue = a <= b;\n            //Lógicos\n            bool x = true;\n            bool y = false;\n            bool z = true;\n\n            bool yy = (x && x);\n            bool o = (y || x);\n            bool dif = !z;\n\n            if (x == y)\n            {\n                z = true;\n            } else if (y == z)\n            {\n                x = true;\n            } else\n            {\n                x = false;\n            }\n\n            while(variable > c)\n            {\n                variable++;\n            }\n\n            try\n            {\n                if (!igual)\n                {\n                    Console.WriteLine(\"a y b NO SON IGUALES\");\n                }\n            } catch\n            {\n                throw new Exception(\"Son iguales, cuidado!\");\n            }\n\n            //Opcional\n            for (int i = 10; i <= 55; i++)\n            {\n                if (i % 2 == 0 && i != 16 && i % 3 != 0)\n                {\n                    Console.WriteLine(i);\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c#/hequebo.cs",
    "content": "// Operadores Aritméticos\nConsole.WriteLine(\"-----------ARITMETICOS-----------\");\nConsole.WriteLine($\"Suma: 1 + 5 = {1 + 5}\");\nConsole.WriteLine($\"Resta: 1 - 5 = {1 - 5}\");\nConsole.WriteLine($\"Multiplicación: 1 * 5 = {1 * 5}\");\nConsole.WriteLine($\"División: 1 / 5 = {1 / 5.0}\");\nConsole.WriteLine($\"Módulo: 1 % 5 = {1 % 5}\");\n\n// Operadores de Comparación\nConsole.WriteLine(\"-----------COMPARACION-----------\");\nConsole.WriteLine($\"Igualdad: 10 == 5 es {10 == 5}\");\nConsole.WriteLine($\"Desigualdad: 10 != 5 es {10 != 5}\");\nConsole.WriteLine($\"Menor que: 10 < 5 es {10 < 5}\");\nConsole.WriteLine($\"Mayor que: 10 > 5 es {10 >= 5}\");\nConsole.WriteLine($\"Menor o igual que: 10 <= 5 es {10 <= 5}\");\nConsole.WriteLine($\"Mayor o igual que: 10 >= 5 es {10 >= 5}\");\n\n// Operadores Lógicos\nConsole.WriteLine(\"-----------LOGICOS-----------\");\nConsole.WriteLine($\"AND &&: 10 > 3 && 2 < 3 es {10 > 3 && 2 < 3}\");\nConsole.WriteLine($\"OR ||: 10 > 3 || 2 > 3 es {10 > 3 ||2 > 3}\");\nConsole.WriteLine($\"NOT !: !(10 > 3) es {!(10 > 3)}\");\nConsole.WriteLine($\"XOR &&: 10 > 3 ^ 2 < 3 es {10 > 3 ^ 2 < 3}\");\n\n// Operadores de Asignación\nConsole.WriteLine(\"-----------ASIGNACION-----------\");\nint myNum = 1;\nint myNum2 = 15;\nmyNum = myNum2; //Asignación\nConsole.WriteLine(myNum);\nmyNum++; // Suma y asignación\nConsole.WriteLine(myNum);\nmyNum--; // Resta y asignación\nConsole.WriteLine(myNum);\nmyNum *= 2; // Multiplicación y asignación\nConsole.WriteLine(myNum);\nmyNum /= 2; // División y asignación;\nConsole.WriteLine(myNum);\nmyNum %= 2; // Modulo y asignación\nConsole.WriteLine(myNum);\n\n// Estructuras de Control\n// Condicional\nint dayOfTheWeek = (int)DateTime.Today.DayOfWeek;\nif (dayOfTheWeek == (int)DayOfWeek.Monday)\n    Console.WriteLine(\"I hate mondays\");\nelse if (dayOfTheWeek == (int)DayOfWeek.Friday)\n    Console.WriteLine(\"Thank God is friday\");\nelse\n    Console.WriteLine($\"Today is {DateTime.Today.DayOfWeek}\");\n\n// Bucles\n// Bucle for\nfor (int i = 0; i < 10; i++)\n    Console.WriteLine($\"Esta es la iteración {i + 1}\");\n\n// Bucle foreach\n\nstring[] personas = [\"Emilio\", \"Aldo\", \"Luis\", \"Samantha\", \"Ale\"];\n\nforeach (string persona in personas)\n    Console.WriteLine($\"Hola, {persona}\");\n\n// Bucle while\n\nbool salir = false;\nwhile (!salir)\n{\n    Console.WriteLine(\"Estás dentro de un bucle while\");\n    Console.WriteLine(\"Para salir presiona la tecla 'X'\");\n    char tecla = (char)Console.ReadLine()[0];\n    if (tecla == 'x' || tecla == 'X')\n        salir = true;\n}\n\n// Excepciones\n\nConsole.WriteLine(\"Bienvenido al sistema de divisiones\");\ntry\n{\n    Console.WriteLine(\"Ingresa numero a dividir\");\n    int num1 = int.Parse(Console.ReadLine());\n    Console.WriteLine(\"Ingresa número por el cual dividir\");\n    int num2 = int.Parse(Console.ReadLine());\n    decimal res = (decimal)num1 / num2;\n    Console.WriteLine($\"El resultado de la división es: {res}\");\n} \ncatch (Exception ex)\n{\n    Console.WriteLine(\"Ocurrió un error\");\n    Console.WriteLine(ex.Message);\n}\nfinally\n{\n    Console.WriteLine(\"Este es el final del sistema de divisiones\");\n}\n\n/*\n Ejercicio extra: Imprimpir por consola\n todos los números comprendidos entre el\n 10 y 55 (incluidos), pares y que no sean\n el 16 ni múltiplos de 3\n */\nfor (int i = 10; i < 55; i++)\n{\n    if (i % 2 == 0 && i != 16 && i % 3 != 0)\n        Console.WriteLine(i);\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c#/isaacus98.cs",
    "content": "﻿/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\nusing static System.Net.Mime.MediaTypeNames;\n\nnamespace RetosProgramacion2024\n{\n    internal class Reto1\n    {\n        static void Main(string[] args)\n        {\n            uint a = 0b_0000_1111_0000_1111_0000_1111_0000_1100;\n            int x = 1;\n            int y = 2;\n\n            // Operadores de incremento\n            Console.WriteLine(x++); // output: 1\n            Console.WriteLine(++x); // output: 2\n\n            // Operadores de decremento\n            Console.WriteLine(x--); // output: 2\n            Console.WriteLine(--x); // output: 1\n\n            // Operador unario\n            Console.WriteLine(-x); // output: -1\n            Console.WriteLine(+x); // output: 1\n\n            // Operadores aritmeticos\n            Console.WriteLine(x + y); // output: 3\n            Console.WriteLine(x - y); // output: -1\n            Console.WriteLine(x * y); // output: 2\n            Console.WriteLine(x / y); // output: 0\n            Console.WriteLine(x % y); // output: 1\n\n            // Operadores de asignación\n            x = 5;\n            Console.WriteLine(x); // output: 5 \n            x += 9;\n            Console.WriteLine(x); // output: 14\n            x -= 4;\n            Console.WriteLine(x); // output: 10\n            x *= 2;\n            Console.WriteLine(x); // output: 20\n            x /= 4;\n            Console.WriteLine(x); // output: 5\n            x %= 2;\n            Console.WriteLine(x); // output: 1\n            \n            bool myBool = true;\n            myBool &= false;\n            Console.WriteLine(myBool);  // output: False\n\n            myBool |= true;\n            Console.WriteLine(myBool);  // output: True\n\n            myBool ^= false;\n            Console.WriteLine(myBool);  // output: True\n\n            a <<= 4;\n            Console.WriteLine(Convert.ToString(a, toBase: 2)); // output: 11110000111100001111000011000000\n\n            a >>= 2;\n            Console.WriteLine(Convert.ToString(a, toBase: 2).PadLeft(4, '0'),4); // output: 111100001111000011110000110000\n\n            // Operadores de comparación\n            Console.WriteLine(x > y); // output: False\n            Console.WriteLine(x < y); // output: True\n            Console.WriteLine(x >= y); // output: False\n            Console.WriteLine(x <= y); // output: True\n\n            // Operadores lógicos\n            Console.WriteLine(!true); // output: true\n            Console.WriteLine(true & false); // output: False\n            Console.WriteLine(true | false); // output: True\n            Console.WriteLine(true ^ false); // output: True\n            Console.WriteLine(false && true); // output: False\n            Console.WriteLine(true || false); // output: True\n\n            // Operadores de bit\n            Console.WriteLine(Convert.ToString(~a, toBase: 2)); // output: 11110000111100001111000011110011\n\n            a = 0b_1100_1001_0000_0000_0000_0000_0001_0001;\n            Console.WriteLine($\"Before: {Convert.ToString(a, toBase: 2)}\"); // output: 11001001000000000000000000010001\n            a <<= 4;\n            Console.WriteLine($\"After:  {Convert.ToString(a, toBase: 2)}\"); // output: 10010000000000000000000100010000\n\n            a = 0b_1001;\n            Console.WriteLine($\"Before: {Convert.ToString(a, toBase: 2),4}\"); // output: 1001\n            a >>= 2;\n            Console.WriteLine($\"After:  {Convert.ToString(a, toBase: 2).PadLeft(4, '0'),4}\"); // output: 0010\n\n            x = -8;\n            Console.WriteLine($\"Before:    {x,11}, hex: {x,8:x}, binary: {Convert.ToString(x, toBase: 2),32}\"); // output: -8, hex: fffffff8, binary: 11111111111111111111111111111000\n            y = x >> 2;\n            Console.WriteLine($\"After  >>: {y,11}, hex: {y,8:x}, binary: {Convert.ToString(y, toBase: 2),32}\"); // output: -2, hex: fffffffe, binary: 11111111111111111111111111111110\n            int z = x >>> 2;\n            Console.WriteLine($\"After >>>: {z,11}, hex: {z,8:x}, binary: {Convert.ToString(z, toBase: 2).PadLeft(32, '0'),32}\"); // output: 1073741822, hex: 3ffffffe, binary: 00111111111111111111111111111110\n\n            // Operadores de igualdad\n            Console.WriteLine(x == y); // output: False\n            Console.WriteLine(x != y); // output: True\n\n            // Estructuras de control\n            x = 1;\n            y = 2;\n\n            // if\n            if (x == y)\n                Console.WriteLine(\"x es igual a y\");\n            else\n                Console.WriteLine(\"x no es igual a y\");\n\n            // switch\n            switch(x)\n            {\n                case 0: \n                    Console.WriteLine($\"x = {x}\");\n                    break;\n                case 1:\n                    Console.WriteLine($\"x = {x}\");\n                    break;\n                default:\n                    Console.WriteLine(\"x no es 0 ni 1\");\n                    break;\n            }\n            \n            // for\n            for (int i = 0; i < 5; i++)\n                Console.WriteLine(i);\n\n            // while\n            int j = 0;\n            while (j < 5)\n                Console.WriteLine(j++);\n\n            // do while\n            j = 0;\n            do\n                Console.WriteLine(j++);\n            while (j < 5);\n\n            // foreach\n            string[] nombres = {\"Isaac\", \"Sergi\", \"Gerard\", \"Pol\", \"Marc\"};\n            foreach (string nombre in nombres)\n                Console.WriteLine(nombre);\n\n            // try - catch\n            try\n            {\n                x = 5;\n                y = 0;\n                int result = x/y;\n            } \n            catch(DivideByZeroException e)\n            {\n                Console.WriteLine(e.Message);\n            }\n\n            //try - catch - finally\n            try\n            {\n                x = 5;\n                y = 0;\n                int result = x / y;\n            }\n            catch (DivideByZeroException e)\n            {\n                Console.WriteLine(e.Message);\n            }\n            finally\n            {\n                Console.WriteLine(\"Se ejecuta despues de ejecutarse el código del bloque try o del bloque catch si ha saltado una excepción.\");\n            }\n\n            // Reto extra\n            RetoExtra();\n        }\n\n        private static void RetoExtra()\n        {\n            for (int i = 10; i <= 55; i++)\n            {\n                if ((i % 2 == 0) & i != 16 & i % 3 != 0)\n                    Console.WriteLine(i);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c#/isco-mtz.cs",
    "content": "\nusing System;\n\nnamespace retoProgramacion2025\n{\n  \n  internal class reto01\n  {\n      // Variable global\n      static int globalVariable = 70;\n  \n      private static void Main(string[] args)\n      {\n          MostrarOperadoresAritmeticos();\n          MostrarOperadoresLogicos();\n          MostrarOperadoresComparacion();\n          MostrarOperadoresAsignacion();\n          MostrarOperadoresIdentidad();\n          MostrarEstructurasControl();\n  \n          Console.WriteLine(\"\\nEjercicio Extra:\");\n          ImprimirNumeros();\n      }\n  \n      // Operadores aritméticos\n      static void MostrarOperadoresAritmeticos()\n      {\n          Console.WriteLine(\"Operadores aritméticos: \");\n  \n          int a = 5;\n          int b = 2;\n  \n          Console.WriteLine($\"a + b = {a + b}\");\n          Console.WriteLine($\"a - b = {a - b}\");\n          Console.WriteLine($\"a * b = {a * b}\");\n          Console.WriteLine($\"a / b = {(double)a / b}\");\n          Console.WriteLine($\"a % b = {a % b}\");\n      }\n  \n      // Operadores lógicos\n      static void MostrarOperadoresLogicos()\n      {\n          Console.WriteLine(\"\\nOperadores lógicos: \");\n  \n          bool x = true;\n          bool y = false;\n          \n          Console.WriteLine($\"El valor de x es: {x}\");\n          Console.WriteLine($\"El valor de y es: {y}\");\n          Console.WriteLine(\"\\n\");\n          \n          Console.WriteLine($\"x && y = {x && y}\");\n          Console.WriteLine($\"x || y = {x || y}\");\n          Console.WriteLine($\"!x = {!x}\");\n      }\n  \n      // Operadores de comparación\n      static void MostrarOperadoresComparacion()\n      {\n          Console.WriteLine(\"\\nOperadores de comparación: \");\n  \n          int a = 10;\n          int b = 10;\n  \n          Console.WriteLine($\"a == b = {a == b}\");\n          Console.WriteLine($\"a != b = {a != b}\");\n          Console.WriteLine($\"a > b = {a > b}\");\n          Console.WriteLine($\"a < b = {a < b}\");\n          Console.WriteLine($\"a >= b = {a >= b}\");\n          Console.WriteLine($\"a <= b = {a <= b}\");\n      }\n  \n      // Operadores de asignación\n      static void MostrarOperadoresAsignacion()\n      {\n          Console.WriteLine(\"\\nOperadores de asignación: \");\n  \n          int c = 125;\n          Console.WriteLine($\"c = {c}\");\n  \n          c += 10;\n          Console.WriteLine($\"c += 10 = {c}\");\n  \n          c -= 20;\n          Console.WriteLine($\"c -= 20 = {c}\");\n  \n          c *= 30;\n          Console.WriteLine($\"c *= 30 = {c}\");\n  \n          c /= 50;\n          Console.WriteLine($\"c /= 50 = {c}\");\n  \n          c %= 60;\n          Console.WriteLine($\"c %= 60 = {c}\");\n      }\n  \n      // Identidad / referencia\n      static void MostrarOperadoresIdentidad()\n      {\n          Console.WriteLine(\"\\nOperadores de identidad: \");\n  \n          string a1 = \"Arroz\";\n          string a2 = \"Galletas\";\n          \n          Console.WriteLine($\"El valor de a1 es: {a1}\");\n          Console.WriteLine($\"El valor de a2 es: {a2}\");\n          Console.WriteLine($\"a1 == a2 = {a1 == a2}\");\n          Console.WriteLine($\"ReferenceEquals(a1, a2) = {ReferenceEquals(a1, a2)}\");\n      }\n  \n      // Estructuras de control\n      static void MostrarEstructurasControl()\n      {\n          Console.WriteLine(\"\\nEstructuras de control: \");\n  \n          int a = 45;\n          int b = 7;\n  \n          // IF\n          if (a > b)\n              Console.WriteLine(\"a es mayor que b\");\n          else\n              Console.WriteLine(\"a no es mayor que b\");\n  \n          // SWITCH\n          switch (a)\n          {\n              case 35:\n                  Console.WriteLine(\"a es 35\");\n                  break;\n              case 7:\n                  Console.WriteLine(\"a es 7\");\n                  break;\n              default:\n                  Console.WriteLine($\"a no es 35, su valor es: {a}\");\n                  break;\n          }\n  \n          // FOR\n          Console.WriteLine(\"\\nFor:\");\n          for (int i = 0; i < 5; i++)\n              Console.WriteLine(i);\n  \n          // WHILE\n          Console.WriteLine(\"\\nWhile:\");\n          int j = 0;\n          while (j < 5)\n              Console.WriteLine(j++);\n  \n          // DO-WHILE\n          Console.WriteLine(\"\\nDo-While:\");\n          int k = 0;\n          do\n          {\n              Console.WriteLine(k++);\n          } while (k < 5);\n  \n          // FOREACH\n          Console.WriteLine(\"\\nForeach:\");\n          int[] numeros = { 1, 2, 3, 4, 5, 6, 7 };\n          foreach (int num in numeros)\n              Console.WriteLine($\"ForEach número: {num}\");\n  \n          // Excepciones\n          Console.WriteLine(\"\\nExcepciones:\");\n  \n          try\n          {\n              int x = 3;\n              int y = 0;\n              Console.WriteLine(x / y);\n          }\n          catch (Exception e)\n          {\n              Console.WriteLine(\"Error: \" + e.Message);\n          }\n          finally\n          {\n              Console.WriteLine(\"Finally ejecutado\");\n          }\n      }\n  \n      // Ejercicio extra: números pares entre 10 y 55, sin 16 ni múltiplos de 3\n      static void ImprimirNumeros()\n      {\n          for (int i = 10; i <= 55; i++)\n          {\n              if (i % 2 == 0 && i != 16 && i % 3 != 0)\n                  Console.WriteLine(i);\n          }\n      }\n  }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c#/jamerrq.cs",
    "content": "using System;\n\n// Documentación oficial de C#: https://docs.microsoft.com/es-es/dotnet/csharp/\n/*\n* Operadores y expresiones de C#\n* https://learn.microsoft.com/es-es/dotnet/csharp/language-reference/operators/\n*/\nclass OperatorsAndControlStructures\n{\n\n    // https://learn.microsoft.com/es-es/dotnet/csharp/language-reference/operators/arithmetic-operators\n    static void arithmeticOperators()\n    {\n        Console.WriteLine(\"1. Operadores aritméticos\");\n\n        Console.WriteLine(\"1.1 Operador de incremento\");\n\n\n        Console.WriteLine(\"1.1.1 Postfijo\");\n\n        int a = 10;\n        Console.WriteLine(\"a → a++ → a\");\n        Console.WriteLine($\"{a} → {a++} → {a}\");\n\n        Console.WriteLine(\"1.1.2 Prefijo\");\n\n        Console.WriteLine(\"a → ++a → a\");\n        Console.WriteLine($\"{a} → {++a} → {a}\");\n\n        Console.WriteLine(\"1.2 Operador de decremento\");\n\n\n        Console.WriteLine(\"1.2.1 Postfijo\");\n\n        Console.WriteLine(\"a → a-- → a\");\n        Console.WriteLine($\"{a} → {a--} → {a}\");\n\n        Console.WriteLine(\"1.2.2 Prefijo\");\n        Console.WriteLine(\"a → --a → a\");\n\n        Console.WriteLine(\"1.3 Operadores unarios más y menos\");\n\n        Console.WriteLine($\"+4 → {+4}\");     // output: 4\n\n        Console.WriteLine($\"-4 → {-4}\");     // output: -4\n        Console.WriteLine($\"-(-4) → {-(-4)}\");  // output: 4\n\n        uint x = 5;\n        var b = -x;\n        Console.WriteLine(\"uint x = 5; var b = -x; Console.WriteLine(b);\");\n        Console.WriteLine(b);            // output: -5\n        Console.Write(\"b.GetType(): \");  // output: System.Int32\n        Console.WriteLine(b.GetType());  // output: System.Int64\n\n        Console.Write(\"-double.NaN: \");  // output: NaN\n        Console.WriteLine(-double.NaN);  // output: NaN\n\n        Console.Write(\"-double.PositiveInfinity: \");  // output: -Infinity\n        Console.WriteLine(-double.PositiveInfinity);  // output: -Infinity\n\n        Console.Write(\"-double.NegativeInfinity: \");  // output: Infinity\n        Console.WriteLine(-double.NegativeInfinity);  // output: Infinity\n\n        Console.WriteLine(\"1.4 Operadores de multiplicación, división y resto\");\n\n        Console.WriteLine(\"1.4.1 Operador de multiplicación\");\n\n        Console.WriteLine(\"2 * 3 → {0}\", 2 * 3);  // output: 6\n\n        Console.WriteLine(\"1.4.2 Operador de división\");\n\n        Console.WriteLine(\"1.4.2.1 División entera\");\n\n        Console.WriteLine(\"10 / 3 → {0}\", 10 / 3);  // output: 3\n\n        Console.WriteLine(\"1.4.2.2 División real\");\n\n        Console.WriteLine(\"10.0 / 3.0 → {0}\", 10.0 / 3.0);  // output: 3.33333333333333\n\n        Console.WriteLine(\"1.4.3 Operador de resto\");\n\n        Console.WriteLine(\"10 % 3 → {0}\", 10 % 3);  // output: 1\n\n        Console.WriteLine(\"1.5 Operadores de suma y resta\");\n\n        Console.WriteLine(\"1.5.1 Operador de suma\");\n\n        Console.WriteLine(\"2 + 3 → {0}\", 2 + 3);  // output: 5\n\n        Console.WriteLine(\"1.5.2 Operador de resta\");\n\n        Console.WriteLine(\"2 - 3 → {0}\", 2 - 3);  // output: -1\n\n        Console.WriteLine(\"1.6 Asignación compuesta\");\n\n        Console.WriteLine(\"1.6.1 Operador de asignación de suma\");\n\n        Console.WriteLine(\"a += 1 → {0}\", a += 1);  // output: 6\n\n        Console.WriteLine(\"1.6.2 Operador de asignación de resta\");\n\n        Console.WriteLine(\"a -= 1 → {0}\", a -= 1);  // output: 5\n\n        Console.WriteLine(\"1.6.3 Operador de asignación de multiplicación\");\n\n        Console.WriteLine(\"a *= 2 → {0}\", a *= 2);  // output: 10\n\n        Console.WriteLine(\"1.6.4 Operador de asignación de división\");\n\n        Console.WriteLine(\"a /= 2 → {0}\", a /= 2);  // output: 5\n\n        Console.WriteLine(\"1.6.5 Operador de asignación de resto\");\n\n        Console.WriteLine(\"a %= 2 → {0}\", a %= 2);  // output: 1\n\n    }\n\n    // https://learn.microsoft.com/es-es/dotnet/csharp/language-reference/operators/comparison-operators\n    static void comparisonOperators()\n    {\n        Console.WriteLine(\"\\n2. Operadores de comparación\");\n\n        Console.WriteLine(\"2.1 Operador mayor que\");\n\n        Console.WriteLine(\"2 > 2 → {0}\", 2 > 2);  // output: False\n\n        Console.WriteLine(\"2.2 Operador menor que\");\n\n        Console.WriteLine(\"2 < 2 → {0}\", 2 < 2);  // output: False\n\n        Console.WriteLine(\"2.3 Operador mayor o igual que\");\n\n        Console.WriteLine(\"2 >= 2 → {0}\", 2 >= 2);  // output: True\n\n        Console.WriteLine(\"2.4 Operador menor o igual que\");\n\n        Console.WriteLine(\"2 <= 2 → {0}\", 2 <= 2);  // output: True\n    }\n\n    static void logicalOperators()\n    {\n        Console.WriteLine(\"\\n3. Operadores lógicos booleanos\");\n\n        Console.WriteLine(\"3.1 Operador AND lógico booleano\");\n\n        Console.WriteLine(\"true && true → {0}\", true && true);  // output: True\n\n        Console.WriteLine(\"3.2 Operador OR lógico booleano\");\n\n        Console.WriteLine(\"true || false → {0}\", true || false);  // output: True\n\n        Console.WriteLine(\"3.3 Operador NOT lógico booleano\");\n\n        Console.WriteLine(\"!true → {0}\", !true);  // output: False\n\n        Console.WriteLine(\"3.4 Operador IR exclusivo lógico booleano\");\n\n        Console.WriteLine(\"true ^ false → {0}\", true ^ false);  // output: True\n        Console.WriteLine(\"false ^ false → {0}\", false ^ false);  // output: False\n    }\n\n    // https://docs.microsoft.com/es-es/dotnet/csharp/language-reference/operators/bitwise-and-shift-operators\n    static void BitToBitOperators()\n    {\n        Console.WriteLine(\"\\n4. Operadores bit a bit y de desplazamiento\");\n\n        Console.WriteLine(\"4.1 Operador de complemento bit a bit ~\");\n\n        Console.WriteLine(\"~0b00000001 → {0}\", ~0b00000001);  // output: -2\n\n        Console.WriteLine(\"4.2 Operador de desplazamiento izquierdo <<\");\n\n        Console.WriteLine(\"0b00000001 << 2 → {0}\", 0b00000001 << 2);  // output: 4\n\n        Console.WriteLine(\"4.3 Operador de desplazamiento derecho >>\");\n\n        Console.WriteLine(\"0b00000100 >> 2 → {0}\", 0b00000100 >> 2);  // output: 1\n\n        Console.WriteLine(\"4.4 Operador de desplazamiento a la derecha sin signo >>>\");\n\n        Console.WriteLine(\"0b10000000 >>> 2 → {0}\", 0b10000000 >> 2);  // output: 32\n\n        Console.WriteLine(\"4.5 Operador AND bit a bit &\");\n\n        Console.WriteLine(\"0b00000001 & 0b00000010 → {0}\", 0b00000001 & 0b00000010);  // output: 0\n\n        Console.WriteLine(\"4.6 Operador OR bit a bit |\");\n\n        Console.WriteLine(\"0b00000001 | 0b00000010 → {0}\", 0b00000001 | 0b00000010);  // output: 3\n\n        Console.WriteLine(\"4.7 Operador XOR bit a bit ^\");\n\n        Console.WriteLine(\"0b00000001 ^ 0b00000010 → {0}\", 0b00000001 ^ 0b00000010);  // output: 3\n\n        Console.WriteLine(\"Estos operadores también se pueden utilizar con asignación compuesta\");\n    }\n\n    // https://learn.microsoft.com/es-es/dotnet/csharp/language-reference/operators/equality-operators\n    static void equalityOperators()\n    {\n        Console.WriteLine(\"\\n5. Operadores de igualdad\");\n\n        Console.WriteLine(\"5.1 Operador de igualdad\");\n\n        Console.WriteLine(\"2 == 2 → {0}\", 2 == 2);  // output: True\n\n        Console.WriteLine(\"5.2 Operador de desigualdad\");\n\n        Console.WriteLine(\"2 != 2 → {0}\", 2 != 2);  // output: False\n    }\n\n    static void extraExercise()\n    {\n        Console.WriteLine(\"\\nEjercicio extra\");\n        Console.WriteLine(\"Números pares entre 10 y 55 que no sean múltiplos de 3 ni 16:\");\n\n        for (int i = 10; i <= 55; ++i)\n        {\n            if (i % 2 == 0 && i % 3 != 0 && i != 16)\n                Console.WriteLine($\"{i}\");\n        }\n    }\n\n    static void Main()\n    {\n        /*\n        C# proporciona una serie de operadores. Muchos de ellos son compatibles\n        con los tipos integrados y permiten realizar operaciones básicas con\n        valores de esos tipos. Entre estos operadores se incluyen los siguientes\n        grupos:\n        */\n\n        // Operadores aritméticos\n        // Realizan operaciones aritméticas con operandos numéricos.\n        // https://docs.microsoft.com/es-es/dotnet/csharp/language-reference/operators/arithmetic-operators\n        // +, -, *, /, %, ++, --, <<, >>, &, |, ^, ~, !, +=, -=, *=, /=, %=, <<=, >>=, &=, |=, ^=\n        arithmeticOperators();\n\n        // Operadores de comparación\n        // Comparan operandos numéricos.\n        // https://learn.microsoft.com/es-es/dotnet/csharp/language-reference/operators/comparison-operators\n        // ==, !=, >, <, >=, <=\n        comparisonOperators();\n\n        // Operadores lógicos booleanos\n        // Realizan operaciones lógicas con operandos bool.\n        // https://learn.microsoft.com/es-es/dotnet/csharp/language-reference/operators/boolean-logical-operators\n        // &&, ||, !, ^\n        logicalOperators();\n\n        // Operadores bit a bit y de desplazamiento\n        // Realizan operaciones bit a bit o de desplazamiento con operandos de tipos enteros.\n        // https://docs.microsoft.com/es-es/dotnet/csharp/language-reference/operators/bitwise-and-shift-operators\n        // <<, >>, &, |, ^, ~, >>>\n        BitToBitOperators();\n\n        // Operadores de igualdad\n        // Comprueban si sus operandos son iguales o no.\n        // https://learn.microsoft.com/es-es/dotnet/csharp/language-reference/operators/equality-operators\n        // ==, !=\n        equalityOperators();\n\n        // Ejercicio extra\n        extraExercise();\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c#/jcubero12.cs",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n \n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n*/\n\nclass Program\n{\n    public static void Main(string[] args)\n    {\n        //Operadores aritmeticos\n        int a = 10;\n        int b = 20;\n        Console.WriteLine(\"Suma: \" + (a + b));\n        Console.WriteLine(\"Resta: \" + (a - b));\n        Console.WriteLine(\"Multiplicacion: \" + (a * b));\n        Console.WriteLine(\"Division: \" + (a / b));\n        Console.WriteLine(\"Modulo: \" + (a % b));\n        Console.WriteLine(\"Incremento: \" + (++a));\n        Console.WriteLine(\"Decremento: \" + (--a));\n\n        //Operadores logicos\n\n        bool c = true;\n        bool d = false;\n        Console.WriteLine(\"\\nOperadores logicos\");\n        Console.WriteLine(\"NOT: \" + (!c));\n        Console.WriteLine(\"AND: \" + (c && d));\n        Console.WriteLine(\"OR: \" + (c || d));\n\n        //Operadores de comparacion\n        Console.WriteLine(\"\\nOperadores de comparacion\");\n        Console.WriteLine(\"Igual: \" + (a == b));\n        Console.WriteLine(\"Distinto: \" + (a != b));\n        Console.WriteLine(\"Mayor que: \" + (a > b));\n        Console.WriteLine(\"Menor que: \" + (a < b));\n        Console.WriteLine(\"Mayor o igual que: \" + (a >= b));\n        Console.WriteLine(\"Menor o igual que: \" + (a <= b));\n\n        //Operadores de asignacion\n        Console.WriteLine(\"\\nOperadores de asignacion\");\n        Console.WriteLine(\"Asignacion: \" + (a = b));\n        Console.WriteLine(\"Suma y asignacion: \" + (a += b));\n        Console.WriteLine(\"Resta y asignacion: \" + (a -= b));\n        Console.WriteLine(\"Multiplicacion y asignacion: \" + (a *= b));\n        Console.WriteLine(\"Division y asignacion: \" + (a /= b));\n        Console.WriteLine(\"Modulo y asignacion: \" + (a %= b));\n\n        //Operadores de identidad\n        Console.WriteLine(\"\\nOperadores de identidad\");\n        Console.WriteLine(\"Igualdad: \" + \"a es un numero entero? \" + (a is int));\n        Console.WriteLine(\"Desigualdad: \" + \"a no es un numero entero? \" + (a is not int));\n\n        object obj1 = new object();\n        object obj2 = new object();\n        Console.WriteLine(obj1 == obj2); // False, diferentes referencias\n\n        object obj1 = new object();\n        object obj2 = obj1;\n        Console.WriteLine(Object.ReferenceEquals(obj1, obj2)); // True, misma referencias\n\n        //Opertadores de pertenencia\n        Console.WriteLine(\"\\nOperadores de pertenencia no existen de tal manera en C#, hay algunas maneras de lograrlo.\");\n        List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };\n        bool exists = numbers.Contains(3); // true\n\n        string texto = \"Hola mundo\";\n        bool contiene = texto.Contains(\"Hola\"); // True\n\n        //Operadores de bits\n        Console.WriteLine(\"\\nOperadores de bits.\");\n        Console.WriteLine(\"AND: \" + (a & b));\n        Console.WriteLine(\"OR: \" + (a | b));\n        Console.WriteLine(\"XOR: \" + (a ^ b));\n        Console.WriteLine(\"Desplazamiento a la izquierda: \" + (a << 1));\n        Console.WriteLine(\"Desplazamiento a la derecha: \" + (a >> 1));\n\n        //Estructuras de control\n        Console.WriteLine(\"\\nEstructuras de control\");\n        // Condicional \n        if(a == b)\n        {\n            Console.WriteLine(\"A es igual que B\");\n        }\n        else if(a > b)\n        {\n            Console.WriteLine(\"A es mayor que B\");\n        }\n        else\n        {\n            Console.WriteLine(\"A es menor que B\");\n        }\n\n        // Iterativa\n        for(int i = 0; i < 8; i++)\n        {\n            Console.WriteLine(\"Iteracion: \" + i);\n        }\n\n        // Excepcion\n        try\n        {\n            int zero = 0;\n            int division = 5 / zero;\n        }\n        catch(DivideByZeroException ex)\n        {\n            Console.WriteLine(\"Ocurrio una excepcion: \" + ex.Message);\n        }\n\n        // Dificultad extra\n        Console.WriteLine(\"\\nDificultad extra\");\n        for(int i = 10; i <= 55; i++)\n        {\n            if(i % 2 == 0 && i != 16 && i % 3 != 0)\n            {\n                Console.WriteLine(i);\n            }\n        }\n\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c#/kenysdev.cs",
    "content": "// ╔══════════════════════════════════════╗\n// ║ Autor: Kenys Alvarado                ║\n// ║ GitHub: https://github.com/Kenysdev  ║\n// ║ 2024 - C#                            ║\n// ╚══════════════════════════════════════╝\n\nint n;\nConsole.WriteLine(@\"\n1. Imprimir ejemplos utilizando todos los tipos \nde operadores de tu lenguaje:\n-----------------------------------------------\nOperadores aritmeticos:\n***********************\n- Suma:              10 + 5         = \" + (10 + 5) + @\"\n- Resta:             10 - 5         = \" + (10 - 5) + @\"\n- Multiplicacion:    10 * 5         = \" + (10 * 5) + @\"\n- Division: \n  double, float o    5.0 / 2.0      = \" + (5.0 / 2.0) + @\"\n- Division Entera: int o 17 / 4     = \" + (17 / 4) + @\"\n- Residuo:           20 % 7         = \" + (20 % 7) + @\"\n- Potenciacion:      Math.Pow(2, 3) = \" + Math.Pow(2, 3) + @\"\n- Combined:         (4 + 2) * 3 / 2 = \" + ((4 + 2) * 3 / 2) + @\"\n\nOperadores de Comparación:\n**************************\n- igual a       5 == 5 -> \" + (5 == 5) + @\"\n- Diferente de  5 != 5 -> \" + (5 != 5) + @\"\n- Menor que     4 < 5  -> \" + (4 < 5) + @\"\n- Mayor que     4 > 5  -> \" + (4 > 5) + @\"\n- Menor o igual 4 <= 5 -> \" + (4 <= 5) + @\"\n- Mayor o igual 4 >= 5 -> \" + (4 >= 5) + @\"\n\nOperadores de Asignación:\n*************************\n- asigna:          n = 10  = \" + (n = 10) + @\"\n- suma:            n += 2  = \" + (n += 2) + @\"\n- resta:           n -= 2  = \" + (n -= 2) + @\"\n- multiplica:      n *= 2  = \" + (n *= 2) + @\"\n- división:        n /= 2  = \" + (n /= 2) + @\"\n- modulo:          n %= 2  = \" + (n %= 2) + @\"\n- pow:      Math.Pow(n, 2) = \" + Math.Pow(n, 2) + @\"\n\nOperadores Lógicos:\n*******************\nand: 5 == 5 && 6 != 5  -> \" + (5 == 5 && 6 != 5) + @\"\nor:  5 == 5 || 6 != 5  -> \" + (5 == 5 || 6 != 5) + @\"\nnot: !(5 == 6)         -> \" + !(5 == 6) + @\"\n\nOperador de Pertenencia:\n************************\nin: \"\"abcde\"\".Contains(\"\"c\"\") -> \" + \"abcde\".Contains(\"cd\") + @\"\n\nOperadores Bit a Bit:\n**********************\nand:       Convert.ToString(10 & 5)  -> \" + Convert.ToString(10 & 5, 2) + @\"\nor:        Convert.ToString(10 | 5)  -> \" + Convert.ToString(10 | 5, 2) + @\"\nxor:       Convert.ToString(10 ^ 5)  -> \" + Convert.ToString(10 ^ 5, 2) + @\"\nnot_a:     Convert.ToString(~10)     -> \" + Convert.ToString(~10, 2) + @\"\nizquierda: Convert.ToString(10 << 2) -> \" + Convert.ToString(10 << 2, 2) + @\"\nderecha:   Convert.ToString(10 >> 1) -> \" + Convert.ToString(10 >> 1, 2) + @\"\n\n2. Estructuras de control:\n--------------------------\n# condicinal:\n*************\");\nint x = 2;\nif (x == 5)\n{\n    Console.WriteLine(\"Si 5 == 5\");\n}\n// si de lo contrario\nelse if (x == 2)\n{\n    Console.WriteLine(\"Si 2 == 2\");\n}\nelse\n{\n    Console.WriteLine(\"Ninguna\");\n}\n\n//---------------------------------\nConsole.WriteLine(@\"\nOperador ternario:\");\nConsole.WriteLine((15 == 15) ? \"si es igual\" : \"no es igual\");\n\n//---------------------------------\nConsole.WriteLine(@\"\nswitch:\");\nint num = 2;\nswitch (num)\n{\n    case 1:\n        Console.WriteLine(\"Es 1\");\n        break;\n    case 2:\n        Console.WriteLine(\"Es 2\");\n        break;\n    default:\n        Console.WriteLine(\"null\");\n        break;\n}\n\n//---------------------------------\nConsole.WriteLine(@\"\nBucles:\n*******\nBucle for:\");\nfor (int i = 0; i < 3; i++)\n{\n    Console.WriteLine($\"Iteración {i + 1}\");\n}\n\n//---------------------------------\nConsole.WriteLine(@\"\nBucle while:\");\nint j = 0;\nwhile (j < 3)\n{\n    Console.WriteLine($\"Iteración {j + 1}\");\n    j++;\n}\n\n//---------------------------------\nConsole.WriteLine(@\"\nBucle do-while:\");\nint k = 0;\ndo\n{\n    Console.WriteLine($\"Iteración {k + 1}\");\n    k++;\n} while (k < 3);\n\n//---------------------------------\nConsole.WriteLine(@\"\nBucle foreach (para iterar sobre colecciones):\");\nint[] z = { 1, 2, 3 };\nforeach (int num2 in z)\n{\n    Console.WriteLine($\"Número: {num2}\");\n}\n\n//---------------------------------\nConsole.WriteLine(@\"\nbreak & continue:\");\nfor (int i = 1; i <= 3; i++)\n{\n    if (i == 4)\n    {\n        Console.WriteLine($\"Valor 4 encontrado. Break.\");\n        break;\n    }\n    if (i % 2 == 0)\n    {\n        Console.WriteLine($\"Iteración {i} es par. Continue.\");\n        continue;\n    }\n    Console.WriteLine($\"Iteración {i}\");\n}\nConsole.WriteLine($\"Finalizando\");\n\n//---------------------------------\nConsole.WriteLine(@\"\nControl de Excepciones:\");\ntry\n{\n    int nu = 10;\n    Console.WriteLine($\"Resultado: {nu / 0}\");\n}\ncatch (DivideByZeroException e)\n{\n    Console.WriteLine($\"Error división: {e.Message}\");\n}\nfinally\n{\n    Console.WriteLine(\"finally\");\n}\n\n//---------------------------------\nConsole.WriteLine(@\"\n3. Ejercicio:\n-------------\nCrea un programa que imprima por consola todos los números comprendidos\n* entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\");\nfor (int numero = 10; numero <= 55; numero++)\n{\n    if (numero % 2 == 0 && numero != 16 && numero % 3 != 0)\n    {\n        Console.WriteLine(numero);\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c#/kodenook.cs",
    "content": "/*\n    Arithmetic Operators\n*/\n\nConsole.WriteLine(\"Arithmetic Operators\");\nConsole.WriteLine($\"2 + 2 = {2 + 2}\");\nConsole.WriteLine($\"2 - 2 = {2 - 2}\");\nConsole.WriteLine($\"2 * 2 = {2 * 2}\");\nConsole.WriteLine($\"2 / 2 = {2 / 2}\");\nConsole.WriteLine($\"2 % 2 = {2 % 2}\");\n\n/*\n        Bitwise Operators\n    */\n\nConsole.WriteLine($\"Bitwise Operators\");\nConsole.WriteLine($\"&: 5 & 2 = {5 & 2}\");\nConsole.WriteLine($\"|: 5 | 2 = {5 | 2}\");\nConsole.WriteLine($\"^: 5 ^ 2 = {5 ^ 2}\");\nConsole.WriteLine($\">>: 5 >> 2 = {5 >> 2}\");\nConsole.WriteLine($\"<<: 5 << 2 = {5 << 2}\");\n\n/*\n    Assignment Operators\n*/\n\nConsole.WriteLine(\"Assignment Operators\");\nConsole.WriteLine(\"x = 5\");\nConsole.WriteLine(\"x += 5, x = x + 5\");\nConsole.WriteLine(\"x -= 5, x = x - 5\");\nConsole.WriteLine(\"x *= 5, x = x * 5\");\nConsole.WriteLine(\"x /= 5, x = x / 5\");\nConsole.WriteLine(\"x ~/= 5, x = x ~/ 5\");\nConsole.WriteLine(\"x %= 5, x = x % 5\");\nConsole.WriteLine(\"x &= 5, x = x & 5\");\nConsole.WriteLine(\"x |= 5, x = x | 5\");\nConsole.WriteLine(\"x ^= 5, x = x ^ 5\");\nConsole.WriteLine(\"x >>= 5, x = x >> 5\");\nConsole.WriteLine(\"x <<= 5, x = x << 5\");\nConsole.WriteLine(\"x >>>= 5, x = x >>> 5\");\n\n/*\n    Comparison Operators\n*/\n\nConsole.WriteLine(\"Comparison Operators\");\nConsole.WriteLine($\"Equal to 4 == 5, {4 == 5}\");\nConsole.WriteLine($\"Not Equal to 4 != 5, {4 != 5}\");\nConsole.WriteLine($\"Grater Than 4 > 5, {4 > 5}\");\nConsole.WriteLine($\"Less Than 4 < 5, {4 <= 5}\");\nConsole.WriteLine($\"Grater Than Or Equal to 4 >= 5, {4 >= 5}\");\nConsole.WriteLine($\"Less Than Or Equal to 4 <= 5, {4 <= 5}\");\n\n/*\n    Logical Operators\n*/\n\nConsole.WriteLine(\"Logical Operators\");\nConsole.WriteLine($\"&&, 3 < 5 && 3 < 10, {3 < 5 && 3 < 10}\");\nConsole.WriteLine($\"||, 3 < 5 || 3 < 10, {3 < 5 || 3 < 10}\");\nConsole.WriteLine($\"!, !(4 < 5), {!(4 < 5)}\");\n\n/*\n    If\n*/\n\nint time = 22;\nif (time < 10)\n{\n    Console.WriteLine(\"Good morning.\");\n}\nelse if (time < 20)\n{\n    Console.WriteLine(\"Good day.\");\n}\nelse\n{\n    Console.WriteLine(\"Good evening.\");\n}\n\n/*\n    Switch\n*/\n\nint day = 4;\nswitch (day)\n{\n    case 6:\n        Console.WriteLine(\"Today is Saturday.\");\n        break;\n    case 7:\n        Console.WriteLine(\"Today is Sunday.\");\n        break;\n    default:\n        Console.WriteLine(\"Looking forward to the Weekend.\");\n        break;\n}\n\n/*\n    While\n*/\n\nint i = 0;\nwhile (i < 5)\n{\n    Console.WriteLine(i);\n    i++;\n}\n\n/*\n    Do While\n*/\n\ndo\n{\n    Console.WriteLine(i);\n    i--;\n}\nwhile (i > 0);\n\n/*\n    For\n*/\n\nfor (int j = 0; j < 5; j++)\n{\n    Console.WriteLine(j);\n}\n\nstring[] cars = { \"Volvo\", \"BMW\", \"Ford\", \"Mazda\" };\nforeach (string l in cars)\n{\n    Console.WriteLine(l);\n}\n\n/*\n    Exercise\n*/\n\nfor (int e = 10; e < 56; e += 2)\n{\n    if (e % 3 != 0 || e == 16)\n    {\n        continue;\n    }\n    Console.WriteLine(e);\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c#/luterfloyd.cs",
    "content": "using System.Drawing;\n\n// OPERADORES ARITMETICOS, COMPARACION, LOGICOS E IGUALDAD, BIT\nConsole.WriteLine(\"* Operadores aritmeticos:++,--,+,-,*,/,%\");\nint miEntero = 5;\nint miEntero2 = 2;\nint miLong = 10;\ndouble miDoble = 10.5;\nbool miBooleano = true;\nbool miBooleano2 = false;\n\nconst int MICONSTANTE = 5; // las constantes son inalterables y se declaran con const\nconst string MICONSTANTE2 = \"Hola Mundo\";\n\nConsole.WriteLine(miEntero++);\nConsole.WriteLine(miEntero+miDoble);\nConsole.WriteLine(++miDoble);\n\nConsole.WriteLine(miEntero--);\nConsole.WriteLine(miEntero+miDoble);\nConsole.WriteLine(--miDoble);\nConsole.WriteLine(miEntero*miDoble);\nConsole.WriteLine(10/2);\nConsole.WriteLine(10%2);\n\nConsole.WriteLine(\"* Operadores de comparacion: >,<,>=,<=,==,!=\");\nConsole.WriteLine(miEntero>miDoble);\nConsole.WriteLine(miEntero<miDoble);\nConsole.WriteLine(miEntero>=miDoble);\nConsole.WriteLine(miEntero<=miDoble);\nConsole.WriteLine(miEntero==miDoble);\nConsole.WriteLine(miEntero!=miDoble);\n\nConsole.WriteLine(\"* Operadores logicos: !,&,|,^  &&,||\");\nConsole.WriteLine(!miBooleano); // NOT\nConsole.WriteLine(miBooleano&miBooleano2); // AND LOGICO\nConsole.WriteLine(miBooleano|miBooleano2); // OR LOGICO\nConsole.WriteLine(miBooleano^miBooleano2); // XOR LOGICO\nConsole.WriteLine(miBooleano&&miBooleano2); // AND CONDICIONAL\nConsole.WriteLine(miBooleano||miBooleano2); // OR CONDICIONAL\n\nConsole.WriteLine(\"Operadores bit a bit:~\");\nConsole.WriteLine(~miEntero); // \nConsole.WriteLine(miEntero<<miEntero2); // \nConsole.WriteLine(miEntero>>miEntero2); // \nConsole.WriteLine(miEntero>>>miEntero2); // \n\n// CICLOS Y ESTRUCTURAS DE CONTROL\nConsole.WriteLine(\"* Ciclos: for, foreach\");\nfor (int indice=0; indice<10;indice++) // se repite mientras se cumpla la condicion\n{\n    Console.WriteLine(indice);\n}\n\nvar miArray = new string[] {\"rojo\",\"blanco\",\"verde\"}; // recorre un iterable\nforeach (var color in miArray)\n{\n    Console.WriteLine(color);\n}\n\nmiEntero = 15;\nConsole.WriteLine(\"* Estructuras de control de flujo: if-else if-else\");\nif (miEntero < 15) // ejecuta un codigo si se cumple una condicion\n{\n    Console.WriteLine(\"mi entero es menor que 15\");\n}\nelse if (miEntero>15)\n{\n    Console.WriteLine($\"mi entero es mayor que 15\");\n}\nelse\n{\n    Console.WriteLine(\"mi entero es igual a 15\");\n}\n\nswitch(miEntero) // evalua varias condicionales de una misma expresion o variable\n{\n    case < 5:\n        Console.WriteLine(\"menor que 5\");\n        break;\n    case 5:\n        Console.WriteLine(\"igual a 5\");\n        break;\n    case > 5:\n        Console.WriteLine(\"mayor que 5\");\n        break;\n}\n    miEntero = 0;\n    Console.WriteLine($\"ciclo while: {miEntero}\");\n    while (miEntero<10) // se ejecuta mientras se cumpla la condicion\n    {\n        Console.WriteLine(miEntero);\n        miEntero++;\n    }\n\ndo // se ejecuta mientras se cumpla la condicion pero entra al bloque de codigo al menos una vez\n{\n    Console.WriteLine($\"ciclo do-while: {miEntero}\");\n    miEntero--;\n} while (miEntero>10);"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c#/matteozhao98.cs",
    "content": "﻿using System;\n\ninternal class Program\n{\n    static void Main(string[] args)\n    {\n        int a = 100;\n        int b = 2;\n\n        //Operadores aritméticos\n        Console.WriteLine($\"Suma: {a}+{b}={a+b}\");\n        Console.WriteLine($\"Resta:{a}-{b}={a-b} \");\n        Console.WriteLine($\"Multiplicación: {a}*{b}={a*b}\");\n        Console.WriteLine($\"División: {a}/{b}={a/b}\");\n        Console.WriteLine($\"Módulo: {a}%{b}={ab}\");\n\n        //Operadres lógicos\n        Console.WriteLine($\"{a} == {b} ? {a==b}\");\n        Console.WriteLine($\"{a} > {b} ? {a>b}\");\n        Console.WriteLine($\"{a} < {b} ? {a<b}\");\n        Console.WriteLine($\"{a} !< {b} ? {a!<b}\");\n\n        b = 4;\n        if()\n        Console.WriteLine($\"{a} >= {b} ? {a>=b}\");\n\n        //Console.WriteLine($\"{a}{b}{ab}\");\n\n        //Operadores de asignación\n        a = b = 2; //cuando queremos asignar 1 o más variables al mismo valor, podemos asignarlas así\n        a = 4;\n\n        //Operador de identidad\n        int? c = null;\n\n        Console.WriteLine(a is int);\n        Console.WriteLine(c is null);\n\n        //Operador de pertenencia\n        int[] array = [2, 4, 8];\n        Console.WriteLine(b in array);\n\n        //Operación con bits\n        Console.WriteLine(a & b);\n\n        a = 100;\n        b = 2;\n        int resultado = 100;\n\n        //Iterativo, bucles for, while, dowhile y foreach\n        for (int i = 0; i < 10; i++)\n        {\n            resultado = resultado * b;\n        }\n        Console.WriteLine(resultado);\n\n        resultado = 100;\n        while (resultado > 0)\n        {\n            resultado = resultado / b;\n        }\n\n        resultado = 100;\n        do\n        {\n            resultado = resultado / b;\n        } while (resultado > 0);\n\n        foreach (int numero in array)\n        {\n            Console.WriteLine(numero);\n        }\n\n        //Excepciones\n\n        try\n        {\n            resultado = resultado / 0;\n        }\n        catch (Exception ex)\n        {\n            Console.WriteLine(ex);\n        }\n\n        //Dificultad extra\n        for (int i = 10; i <= 55; i++)\n        {\n            if (i % 2 == 0 && i != 16 && i % 3 != 0)\n                Console.WriteLine(i);\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c#/miguelex.cs",
    "content": "class miguelex\n{\n    static void Main(string[] args)\n    {\n        // Operadores de asignación\n        int a = 5;\n        int b = 3;\n\n        Console.WriteLine(\"a + b =  \" + (a+b));\n        Console.WriteLine(\"a - b =  \" + (a-b));\n        Console.WriteLine(\"a * b =  \" + (a*b));\n        Console.WriteLine(\"a / b =  \" + (a/b));\n        Console.WriteLine(\"a % b =  \" + (a%b));\n\n        // Operadores de comparación\n\n        Console.WriteLine(\"a == b =  \" + (a==b));\n        Console.WriteLine(\"a != b =  \" + (a!=b));\n        Console.WriteLine(\"a > b =  \" + (a>b));\n        Console.WriteLine(\"a < b =  \" + (a<b));\n        Console.WriteLine(\"a >= b =  \" + (a>=b));\n        Console.WriteLine(\"a <= b =  \" + (a<=b));\n\n        // Operadores lógicos\n\n        bool c = true;\n        bool d = false;\n\n        Console.WriteLine(\"c && d =  \" + (c&&d));\n        Console.WriteLine(\"c || d =  \" + (c||d));\n        Console.WriteLine(\"!c =  \" + (!c));\n\n        // Operadores de incremento y decremento\n\n        Console.WriteLine(\"a++ =  \" + (a++));\n        Console.WriteLine(\"++a =  \" + (++a));\n        Console.WriteLine(\"a-- =  \" + (a--));\n        Console.WriteLine(\"--a =  \" + (--a));\n\n        // OPeradores bits\n\n        Console.WriteLine(\"a & b =  \" + (a&b));\n        Console.WriteLine(\"a | b =  \" + (a|b));\n        Console.WriteLine(\"a ^ b =  \" + (a^b));\n\n        // Operadores de desplazamiento\n\n        Console.WriteLine(\"a << b =  \" + (a<<b));\n        Console.WriteLine(\"a >> b =  \" + (a>>b));\n\n        // if else\n\n        if (a > b)\n        {\n            Console.WriteLine(\"a es mayor que b\");\n        }\n        else\n        {\n            Console.WriteLine(\"a es menor que b\");\n        }\n\n        // switch\n\n        switch (a)\n        {\n            case 1:\n                Console.WriteLine(\"a es 1\");\n                break;\n            case 2:\n                Console.WriteLine(\"a es 2\");\n                break;\n            default:\n                Console.WriteLine(\"a es mayor que 2\");\n                break;\n        }\n\n        // while\n\n        while (a < 10)\n        {\n            Console.WriteLine(\"a es menor que 10\");\n            a++;\n        }\n\n        // do while\n\n        do\n        {\n            Console.WriteLine(\"a es menor que 10\");\n            a++;\n        } while (a < 10);\n\n        // foreach\n\n        int[] arr = {1, 2, 3, 4, 5};\n        foreach(int i in arr)\n        {\n            Console.WriteLine(i);\n        }\n\n        // Excepciones\n\n        try\n        {\n            int x = 10;\n            int y = 0;\n            Console.WriteLine(x/y);\n        }\n        catch (Exception e)\n        {\n            Console.WriteLine(\"Error: \" + e.Message);\n        }\n        finally\n        {\n            Console.WriteLine(\"Finally\");\n        }\n\n        // Extra\n\n        Console.WriteLine(\"Ejercicio Extra\");\n\n        for (int i = 10; i <= 55; i++)\n        {\n            if (i % 2 == 0 && i != 16 && i % 3 != 0)\n            {\n                Console.WriteLine(i);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c#/mor39a.cs",
    "content": "/*\n--------------------------------------------------------------------------------------------------------\nInstrucciones:\n\n    1. Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n       Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n       (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n    2. Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n       que representen todos los tipos de estructuras de control que existan\n       en tu lenguaje:\n       Condicionales, iterativas, excepciones...\n    3. Debes hacer print por consola del resultado de todos los ejemplos.\n\nDificultad extra:\n    Crea un programa que imprima por consola todos los números comprendidos\n    entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n--------------------------------------------------------------------------------------------------------\n*/\n\n#region Definicion de variables\n\nint a = 1;\nint b = 2;\nbool c = true;\nbool d = false;\nobject e = \"e\";\nstring[] f = { \"1\", \"2\", \"3\", \"4\", \"5\" };\n\n#endregion\n\n#region 1.\n\nConsole.WriteLine(\"Operadores:\\n\");\n\n#region Aritmeticos\n\nConsole.WriteLine(\"Aritmeticos:\");\n\nConsole.WriteLine($\"    Suma: {a + b}\");\nConsole.WriteLine($\"    Resta: {a - b}\");\nConsole.WriteLine($\"    Multiplicacion: {a * b}\");\nConsole.WriteLine($\"    Divicion: {a / b}\");\nConsole.WriteLine($\"    Modulo: {a % b}\");\nConsole.WriteLine($\"    Potenciacion: {Math.Pow(a, b)}\"); //No existe el operador así que se usa Math.Pow()\nConsole.WriteLine($\"    Radicacion: {Math.Pow(a, 1.0 / b)}\"); // No existe operado así que se usa Math.Sqrt() \n                                                        // para raiz cuadrada o elevando a la potencia de 1/n\nConsole.WriteLine($\"    Logaritmacion: {Math.Log(a, b)}\"); //No existe el operador así que se usa Math.Log()\n\n#endregion\n\n#region Logicos\n\nConsole.WriteLine(\"Logicos:\");\n\nConsole.WriteLine($\"    AND: {c && d}\");\nConsole.WriteLine($\"    OR: {c || d}\");\nConsole.WriteLine($\"    NOT: {!c}\");\n\n#endregion\n\n#region Comparacion\n\nConsole.WriteLine(\"Comparacion:\");\n\nConsole.WriteLine($\"    Igualdad: {a == b}\");\nConsole.WriteLine($\"    Diferente: {a != b}\");\nConsole.WriteLine($\"    Mayor que: {a > b}\");\nConsole.WriteLine($\"    Mayor o igual que: {a >= b}\");\nConsole.WriteLine($\"    Menor que: {a < b}\");\nConsole.WriteLine($\"    Menor o igual que: {a <= b}\");\n\n#endregion\n\n#region Asignacion\n\nConsole.WriteLine(\"Asignacion:\");\n\nConsole.WriteLine($\"    Simple: {a = 3}\");\nConsole.WriteLine($\"    Suma y asignacion: {a += 2}\");\nConsole.WriteLine($\"    Suma 1 y asignacion: {a++}\");\nConsole.WriteLine($\"    Resta y asignacion: {a -= 2}\");\nConsole.WriteLine($\"    Resta 1 y asignacion: {a--}\");\nConsole.WriteLine($\"    Multiplicacion y asignacion: {a *= 2}\");\nConsole.WriteLine($\"    Divicion y asignacion: {a /= 2}\");\nConsole.WriteLine($\"    Modulo y asignacion: {a %= 2}\");\n\n#endregion\n\n#region Pertenencia\n\nConsole.WriteLine(\"Pertenencia:\");\n\nConsole.WriteLine($\"    Es: {e is string}\");\nConsole.WriteLine($\"    Como: {e as string}\");\n\n#endregion\n\n#region Bits\n\nConsole.WriteLine(\"Bits:\");\n\nConsole.WriteLine($\"    AND: {c & d}\");\nConsole.WriteLine($\"    OR: {c | d}\");\nConsole.WriteLine($\"    XOR: {c ^ d}\");\nConsole.WriteLine($\"    NOT: {~a}\");\nConsole.WriteLine($\"    Desplazamiento a la izquierda: {a << 2}\");\nConsole.WriteLine($\"    Desplazamiento a la derecha: {a >> 2}\");\n\n#endregion\n\n#endregion\n\n#region 2.\n\nAñadirDivision();\nConsole.WriteLine(\"Estructuras de control:\\n\");\n\n#region Condicionales\n\nConsole.WriteLine(\"Condicionales:\");\n\nif (a == b)\n{\n    Console.WriteLine(\"    Si\");\n}\nelse if (a > b)\n{\n    Console.WriteLine(\"    Si no, si\");\n}\nelse\n{\n    Console.WriteLine(\"    Si no\");\n}\n\nConsole.WriteLine(\"    Switch\");\nswitch (a)\n{\n    case 1:\n        Console.WriteLine(\"        a = 1\");\n        break;\n    case 7:\n        Console.WriteLine(\"        a = 7\");\n        break;\n    default:\n        Console.WriteLine(\"        Default (No esta en ninguno de los casos)\");\n        break;\n}\n\n#endregion\n\n#region Iterativas y control de flujo\n\nConsole.WriteLine(\"Iterativas:\");\n\nConsole.WriteLine(\"    For:\");\nfor (int i = 0; i < f.Length; i++)\n{\n    if (i == 1)\n    {\n        Console.WriteLine(\"«Continue»\");\n        continue;\n    }\n    Console.WriteLine($\"        i = {i}; f[i] = {f[i]}\");    \n}\n\nConsole.WriteLine(\"    Foreach:\");\nforeach (string item in f)\n{\n    if (item == \"3\")\n    {\n        Console.WriteLine(\"«Break»\");\n        break;\n    }\n    Console.WriteLine($\"        Item: {item}\");    \n}\n\nConsole.WriteLine(\"    While:\");\nwhile (a < 8)\n{\n    a++;\n    Console.WriteLine($\"        Aun se cumple la condicion. a = {a}\");\n}\n\nConsole.WriteLine(\"    Do-While:\");\ndo\n{\n    Console.WriteLine($\"        Primero realiza la accion y luego si revisa si lo vuelve a hacer.\");\n} while (false);\n\n#endregion\n\n#region Excepciones\n\nConsole.WriteLine(\"Excepciones:\");\n\ntry\n{\n    Console.WriteLine(\"    Try\");\n    throw new Exception();\n}\ncatch\n{\n    Console.WriteLine(\"    Catch\");\n}\nfinally\n{\n    Console.WriteLine(\"    Finally\");\n}\n\n#endregion\n\n#endregion\n\n#region Extra\n\nAñadirDivision();\nConsole.WriteLine(\"Extra:\\n\");\n\nExtra();\n\n#endregion\n\n#region Funciones\n\nvoid AñadirDivision() => Console.WriteLine(\"\\n\" + new string('-', 75) + \"\\n\");\n\nvoid Extra()\n{\n    /*Crea un programa que imprima por consola todos los números comprendidos\n    entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.*/\n\n    Enumerable.Range(10, 46)\n        .Where(i => !((i % 2) != 0 || i == 16 || (i % 3) == 0))\n        .ToList()\n        .ForEach(i => Console.WriteLine($\"    {i}\"));\n\n}\n\n#endregion"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c#/nicolastapiasanz.cs",
    "content": "// Author: Nicolas Tapia -> https://www.github.com/nicolastapiasanz\n\n// EXERCISE #01\n\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\npublic class Program\n{\n    private const int FirstValue = 10;\n    private const int SecondValue = 5;\n\n    public static void Main(string[] args)\n    {\n        Console.WriteLine(\"Operadores Aritmeticos\");\n\n        var suma = FirstValue + SecondValue;\n        Console.WriteLine($\"Suma {FirstValue} + {SecondValue} = {suma}\"); //15\n\n        var resta = FirstValue - SecondValue;\n        Console.WriteLine($\"Resta {FirstValue} - {SecondValue} = {resta}\"); //5\n\n        var multiplicacion = FirstValue * SecondValue;\n        Console.WriteLine($\"Multiplicación {FirstValue} * {SecondValue} = {multiplicacion}\"); //50\n\n        var division = FirstValue / SecondValue;\n        Console.WriteLine($\"Division {FirstValue} / {SecondValue} = {division}\"); //2\n\n        var resto = 1 % 1;\n        Console.WriteLine($\"Resto {FirstValue} % {SecondValue} = {resto}\"); //0\n\n\n\n        Console.WriteLine($\"\\nOperadores Lógicos\");\n        var and = true && true;\n        Console.WriteLine($\"AND True && True = {and}\"); //True\n\n        var or = true || false;\n        Console.WriteLine($\"OR True || False = {or}\"); //True\n\n        var not = !true;\n        Console.WriteLine($\"NOT !True = {not}\"); //False\n\n\n\n        Console.WriteLine($\"\\nOperadores Comparación\");\n\n        var igual = FirstValue == SecondValue;\n        Console.WriteLine($\"Igual {FirstValue} == {SecondValue} = {igual}\"); //False\n\n        var distinto = FirstValue != SecondValue;\n        Console.WriteLine($\"Distinto {FirstValue} != {SecondValue} = {distinto}\"); //True\n\n        var mayorQue = FirstValue > SecondValue;\n        Console.WriteLine($\"Mayor Que {FirstValue} > {SecondValue} = {mayorQue}\"); //True\n\n        var menorQue = FirstValue < SecondValue;\n        Console.WriteLine($\"Menor Que {FirstValue} < {SecondValue} = {menorQue}\"); //False\n\n        var mayorIgualQue = FirstValue >= SecondValue;\n        Console.WriteLine($\"Mayor O Igual Que {FirstValue} >= {SecondValue} = {mayorIgualQue}\"); //True\n\n        var menorIgualQue = FirstValue <= SecondValue;\n        Console.WriteLine($\"Menor O Igual Que {FirstValue} <= {SecondValue} = {menorIgualQue}\"); //False\n\n\n\n        Console.WriteLine($\"\\nOperadores De Asignación\");\n\n        var asignacion = FirstValue;\n        Console.WriteLine($\"Asignacion {FirstValue} = {asignacion}\"); //10\n\n        var masMas = FirstValue;\n        masMas++;\n        Console.WriteLine($\"Mas Mas Post {FirstValue}++ = {masMas}\"); //11\n        ++masMas;\n        Console.WriteLine($\"Mas Mas Prev ++{FirstValue} = {masMas}\"); //12\n\n        var menosMenos = FirstValue;\n        menosMenos--;\n        Console.WriteLine($\"Menos Menos Post {FirstValue}-- = {menosMenos}\"); //9\n        --menosMenos;\n        Console.WriteLine($\"Menos Menos Prev --{FirstValue} = {menosMenos}\"); //8\n\n        var masIgual = FirstValue;\n        masIgual += 1;\n        Console.WriteLine($\"Mas Igual {FirstValue}+= 1 = {masIgual}\"); //11\n\n        var menosIgual = FirstValue;\n        menosIgual -= 1;\n        Console.WriteLine($\"Menos Igual {FirstValue}-= 1 = {menosIgual}\"); //9\n\n        var multIgual = FirstValue;\n        multIgual *= 2;\n        Console.WriteLine($\"Mult. Igual {FirstValue}*= 2 = {multIgual}\"); //20\n\n        var divIgual = FirstValue;\n        divIgual /= 2;\n        Console.WriteLine($\"Div. Igual {FirstValue}/= 2 = {divIgual}\"); //5\n\n        var restIgual = FirstValue;\n        restIgual %= 2;\n        Console.WriteLine($\"Rest. Igual {FirstValue}%= 2 = {restIgual}\"); //0\n\n\n\n        Console.WriteLine($\"\\nOperadores De Identidad\");\n        var firstValue1 = FirstValue;\n        var firstValue2 = FirstValue;\n        var porValor = firstValue1 == firstValue2;\n        Console.WriteLine($\"Comp. por valor: {firstValue1} == {firstValue2} = {porValor}\"); //True\n\n        var porReferencia = object.ReferenceEquals(firstValue1, firstValue2);\n        Console.WriteLine($\"Comp. por valor: {firstValue1}.Equals({firstValue2}) = {porReferencia}\"); //False\n\n\n        //OPERADORES DE BITS\n        Console.WriteLine($\"\\nOperadores Binarios\");\n        var a = 75; // 0100 1011\n        var b = 28; // 0001 1100\n\n        var andOperation = a & b;\n        Console.WriteLine($\"AND {a} & {b} = {andOperation}\"); //8 = 0000 1000\n\n        var orOperation = a | b; //95 = 1010 1111\n        Console.WriteLine($\"OR {a} | {b} = {orOperation}\"); //95 = 1010 1111\n\n        var xorOperation = a ^ b;\n        Console.WriteLine($\"XOR {a} ^ {b} = {xorOperation}\"); //87 = 0101 0111\n\n        var notOperation = ~a;\n        Console.WriteLine($\"NOT ~{a} = {notOperation}\"); //-76 = 1011 0100\n\n        var despIzqOperation = a << 2;\n        Console.WriteLine($\"Desp. a la izquierda {a} << 2 = {despIzqOperation}\"); //300 = 0001 0010 1100\n\n        var despDerOperation = a >> 2;\n        Console.WriteLine($\"Desp. a la derecha {a} >> 2 = {despDerOperation}\"); //18 = 0001 0010\n\n\n        Console.WriteLine($\"\\nCondicionales\");\n        if (a > b)\n        {\n            Console.WriteLine($\"a > b\");\n        }\n        else if( b < a)\n        {\n            Console.WriteLine($\"b < a\");\n            \n        }\n        else\n        {\n            Console.WriteLine($\"b == a\");\n        }\n\n        switch (a)\n        {\n            case 75:\n                Console.WriteLine($\"a == 75\");\n                break;\n            default:\n                Console.WriteLine($\"a != 75\");\n                break;\n        }\n\n        Console.WriteLine($\"\\nIterativos\");\n        var i = 0;\n        do\n        {\n            Console.Write($\"{i} \");\n            i++;\n        } while (i != 10);\n\n        Console.WriteLine();\n\n        var f = 0;\n        while(f != 10)\n        {\n            Console.Write($\"{f} \");\n            f++;\n        }\n\n        Console.WriteLine();\n\n        for (var j = 0; j < 10; j++)\n        {\n            Console.Write($\"{j} \");\n        }\n\n        Console.WriteLine();\n\n        var values = Enumerable.Range(0, 10).ToList();\n        foreach (var value in values)\n        {\n            Console.WriteLine($\"{value}\");\n        }\n\n\n        Console.WriteLine($\"\\nExcepciones\");\n        try\n        {\n            if (a != 75)\n                throw new Exception($\"EXCEPTION: a != 75\");\n        }\n        catch (Exception e)\n        {\n            Console.WriteLine(e);\n        }\n\n\n        //EJERCICIO EXTRA\n\n        //NORMAL\n        for (var x = 10; x < 56; x++)\n            Console.Write($\"{(x % 2 == 0 && x != 16 && x % 3 != 0 ? $\"{x.ToString()}\\n\" : string.Empty)}\");\n\n        Console.WriteLine();\n\n        //LINQ\n        Enumerable.Range(10, 56 - 10)\n            .Where(x => x % 2 == 0 && x != 16 && x % 3 != 0).ToList()\n            .ForEach(Console.WriteLine);\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c#/tebaah.cs",
    "content": "internal class Program\n{\n    /*\n    * EJERCICIO:\n    * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n    *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n    *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n    * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n    *   que representen todos los tipos de estructuras de control que existan\n    *   en tu lenguaje:\n    *   Condicionales, iterativas, excepciones...\n    * - Debes hacer print por consola del resultado de todos los ejemplos.\n    *\n    * DIFICULTAD EXTRA (opcional):\n    * Crea un programa que imprima por consola todos los números comprendidos\n    * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n    *\n    * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n    */   \n    private static void Main(string[] args)\n    {\n        int a = 10;\n        int b = 5;\n        int suma = a + b; // adición\n        int diferencia = a - b; // substracción\n        int producto = a * b; // multiplicación\n        int cociente = a / b; // división\n        int remanente = a % b; // modulo\n\n        bool esMayor = a > b; // mayor que\n        bool esMenor = a < b; // menor que\n        bool esIgual = a == b; // igual a\n        bool noEsIgual = a != b; // no es igual a\n        bool esMayorOIgual = a >= b; // mayor o igual a\n        bool esMenorOIgual = a <= b; // menor o igual a\n        bool yLogico = esMayor && esMenor; // y logico\n        bool oLogico = esMayor || esMenor; // o logico\n        bool noLogico = !esMayor; // no logico\n\n        int x = 10;\n        int y = 10;\n\n     \n        bool mismoValorOperador = x == y; // revisa si x e y tienen el mismo valor usando el operador de igualdad\n        bool diferenteValorOperador = x != y; // revisa so x e y tienen diferente valor usando el operador de desigualdad\n\n        // condicional\n        if (a > b)\n        {\n            Console.WriteLine(\"a es mayor que b\");\n        }\n        else if (a < b)\n        {\n            Console.WriteLine(\"a es menor que b\");\n        }\n        else\n        {\n            Console.WriteLine(\"a es igual que b\");\n        }\n\n        // iterativo\n        for (int i = 0; i < 5; i++)\n        {\n            Console.WriteLine($\"iteracion {i}\");\n        }\n\n        // exepcion\n        try\n        {\n            int result = a / 0;\n            Console.WriteLine($\"resultado: {result}\");\n        }\n        catch (DivideByZeroException ex)\n        {\n            Console.WriteLine(\"no se permite la division por cero\");\n        }\n\n        for (int i = 10; i <= 55; i++)\n        {\n            if (i % 2 == 0 && i != 16 && i % 3 != 0)\n            {\n                Console.WriteLine(i);\n            }\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c#/vasilealexandru02.cs",
    "content": "﻿public class vasilealexandru02\n{\n    public vasilealexandru02()\n    {\n\n        /*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n        /*\n            Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n             Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n            (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n         */\n\n        // Operadores aritmeticos\n        int suma = 1 + 2;\n        int resta = 1 - 2;\n        int multiplicacion = 1 * 2;\n        double division = 1 / 2;\n        double modulo = 10 % 2;\n\n        int operadorIncremento = 0;\n        int operadorDecremento = 1;\n\n        ++operadorIncremento;\n        operadorIncremento++;\n        --operadorDecremento;\n        operadorDecremento--;\n\n        // Operadores lógicos booleanos\n        bool operadorAnd = true && false;\n\n        bool operadorOr = true || false;\n\n        bool operadorNegacion = !true;\n\n        bool operadorIR = false ^ true;\n\n        bool operadorComparacion = true == true;\n        bool operadorComparacionDistinto = true != false;\n\n        bool test = true;\n\n        test &= true; // Output: True\n\n        test |= false; // Output: True\n\n        test ^= true; // Output: False\n\n\n        // Operadores de desplazamiento y bit a bit\n\n        uint valor = 0b_1100_1001_0000_0000_0000_0000_0001_0001;\n        uint desplazamientoIzquierda = valor << 4;\n        uint desplazamientoDerecha = valor >> 4;\n\n\n        /*\n         *  - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n            que representen todos los tipos de estructuras de control que existan\n            en tu lenguaje:\n            Condicionales, iterativas, excepciones...\n         */\n\n        // Condicionales\n        if (true)\n        {\n            Console.WriteLine(\"Verdadero!\");\n\n        }\n        else if (false && false)\n        {\n            Console.WriteLine(\"Verdadero también!\");\n        }\n        else\n        {\n            Console.WriteLine(\"No me queda más que entrar aquí...\");\n        }\n\n        string diaSemana = \"Lunes\";\n        switch (diaSemana)\n        {\n\n            case \"Lunes\":\n                Console.WriteLine(\"Primer dia de la semana!\");\n                break;\n            case \"Martes\":\n                Console.WriteLine(\"Seguimos fuertes con este martes lluvioso!\");\n                break;\n            case \"Miércoles\":\n                Console.WriteLine(\"Miércoles de ser productivo!\");\n                break;\n            case \"Jueves\":\n                Console.WriteLine(\"Ya casi estamos... último empujón!\");\n                break;\n            case \"Viernes\":\n                Console.WriteLine(\"Día de positividad y comienzo del weekend\");\n                break;\n            case \"Sabado\":\n            case \"Domingo\":\n                Console.WriteLine(\"No me molestes estoy de weekend total!\");\n                break;\n\n            default:\n                Console.WriteLine(\"No sé que dia es este :/\");\n                break;\n\n        }\n\n\n        List<int> numeros = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };\n        // Iterativas\n        int numeroTotal = 0;\n        for (int i = 0; i < 10; i++)\n        {\n            numeroTotal += i;\n        }\n\n        foreach (int numero in numeros)\n        {\n            Console.WriteLine(\"Numero: \" + numero);\n        }\n\n        int numeroDoWhile = 10;\n        do\n        {\n            Console.WriteLine(\"Dentro del bucle do while!\", numeroDoWhile);\n            numeroDoWhile--;\n\n        } while (numeroDoWhile > 0);\n\n\n        int numeroWhile = 0;\n        while (numeroWhile < 10)\n        {\n            Console.WriteLine(\"Esto es un bucle while normal\");\n            numeroWhile++;\n        }\n\n        // Try catch finally \n        try\n        {\n            Console.WriteLine(\"Este es el codigo que se va a intentar ejecutar\");\n\n        }\n        catch (Exception e)\n        {\n            Console.WriteLine(\"Esta es la excepcion a controlar\", e);\n\n        }\n\n        finally\n        {\n            Console.WriteLine(\"Código que se ejecuta al final de nuestro bloque try catch\");\n        }\n\n        /* DIFICULTAD EXTRA (opcional):\n        * Crea un programa que imprima por consola todos los números comprendidos\n        * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.*/\n        int numeroEjercicio = 10;\n\n        while (numeroEjercicio <= 55)\n        {\n            if (numeroEjercicio % 2 == 0 && !(numeroEjercicio == 16 || numeroEjercicio % 3 == 0))\n            {\n                Console.WriteLine(numeroEjercicio);\n            }\n\n            numeroEjercicio++;\n        }\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c#/vicgallego.cs",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Roadmap_01\n{\n    internal class Program\n    {\n        static void Main(string[] args)\n        {\n            int a = 4; int b = 9;\n           \n\n            Console.WriteLine(a + b);\n            Console.WriteLine(a - b);\n            Console.WriteLine(a * b);   \n            Console.WriteLine(a / b);\n            Console.WriteLine(a % b);\n            Console.WriteLine(\"\\n\");\n\n\n            // Lógicos\n            bool x = true;\n            bool y = false;\n\n         bool resultado_and = x && y;\n         bool resultado_or = x || y;         \n         bool resultado_not = !x;\n\n            Console.WriteLine(resultado_not);\n            Console.WriteLine(resultado_or);\n            Console.WriteLine(resultado_and);\n\n            Console.WriteLine(\"\\n\");\n\n            // Asignación\n            int c = 5;\n\n            c += 2;  // Equivalente a: a = a + 2\n            Console.WriteLine(c);\n\n            c -= 3;  // Equivalente a: a = a - 3\n            Console.WriteLine(c);\n\n            c *= 4;  // Equivalente a: a = a * 4\n            Console.WriteLine(c);\n\n            c /= 2;  // Equivalente a: a = a / 2\n            Console.WriteLine(c);\n\n            Console.WriteLine(\"\\n\");\n\n            int num1 =10 ; int num2 = 55;\n\n            for(int i = 10; i <= num2 ; i++)\n            {\n                if (i % 2 == 0 && i != 16 && i % 3 != 0)\n                {\n                    Console.WriteLine(i);\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c#/victormugo.cs",
    "content": "﻿namespace _01_operadores\n{\n    internal class Program\n    {\n        static void Main(string[] args)\n        {\n            /*\n             * EJERCICIO:\n             * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n             *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n             *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n             * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n             *   que representen todos los tipos de estructuras de control que existan\n             *   en tu lenguaje:\n             *   Condicionales, iterativas, excepciones...\n             * - Debes hacer print por consola del resultado de todos los ejemplos.\n             *\n             * DIFICULTAD EXTRA (opcional):\n             * Crea un programa que imprima por consola todos los números comprendidos\n             * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n             *\n             * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n             */\n\n\n            // Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n            // Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n\n            // 1. Operadores Aritmeticos\n            //  1.1a - Incremento \n            Console.WriteLine(\"------- Incremento A ---------------\");\n            int example = 0;\n\n            Console.WriteLine($\"example = {example}\");\n            Console.WriteLine($\"example++ = {example++}\");\n            Console.WriteLine($\"example = {example}\");\n\n            // 1.1b - Incremento\n            Console.WriteLine(\"------- Incremento B ---------------\");\n            example = 0;\n            Console.WriteLine($\"example = {example}\");\n            Console.WriteLine($\"++example = {++example}\");\n            Console.WriteLine($\"example = {example}\");\n\n            // 1.2a - Decremento\n            Console.WriteLine(\"------- Decremento A ---------------\");\n            example = 0;\n            Console.WriteLine($\"example = {example}\");\n            Console.WriteLine($\"example-- = {example--}\");\n            Console.WriteLine($\"example = {example}\");\n\n            // 1.2b - Decremento\n            Console.WriteLine(\"------- Decremento B ---------------\");\n            example = 0;\n            Console.WriteLine($\"example = {example}\");\n            Console.WriteLine($\"--example = {--example}\");\n            Console.WriteLine($\"example = {example}\");\n\n            // 1.3 - Unarios\n            Console.WriteLine(\"------- Unario ---------------\");\n            example = 1;\n            Console.WriteLine($\"example = {example}\");\n            Console.WriteLine($\"+example = {+example}\");\n            Console.WriteLine($\"-example = {-example}\");\n            Console.WriteLine($\"-(-example) = {-(-example)}\");\n\n            // 1.4 - Multiplicación\n            Console.WriteLine(\"------- Multiplicación ---------------\");\n            int exampleA = 3;\n            int exampleB = 4;\n            Console.WriteLine($\"{exampleA} * {exampleB} = {exampleA * exampleB}\");\n\n            // 1.5 - División\n            Console.WriteLine(\"------- División ---------------\");\n            exampleA = 3;\n            exampleB = 4;\n            Console.WriteLine($\"{exampleA} / {exampleB} = {(double)exampleA / exampleB}\");\n\n            // 1.6 - Resto\n            Console.WriteLine(\"------- Resto ---------------\");\n            exampleA = 3;\n            exampleB = 4;\n            Console.WriteLine($\"{exampleA} % {exampleB} = {exampleA % exampleB}\");\n\n            // 1.7 - Suma\n            Console.WriteLine(\"------- Suma ---------------\");\n            exampleA = 3;\n            exampleB = 4;\n            Console.WriteLine($\"{exampleA} + {exampleB} = {exampleA + exampleB}\");\n\n            // 1.8 - Resta\n            Console.WriteLine(\"------- Resta ---------------\");\n            exampleA = 3;\n            exampleB = 4;\n            Console.WriteLine($\"{exampleA} - {exampleB} = {exampleA - exampleB}\");\n\n            // 1.9 - Asignación compuesta\n            Console.WriteLine(\"------- Asignación compuesta ---------------\");\n            example = 5;\n            Console.WriteLine($\"example = {example}\");\n\n            example += 9;\n            Console.WriteLine($\" += 9 = {example}\");\n\n            example -= 4;\n            Console.WriteLine($\" -= 4 = {example}\");\n\n            example *= 2;\n            Console.WriteLine($\"*= 2 = {example}\");\n\n            example /= 4;\n            Console.WriteLine($\" /= 4 = {example}\");\n\n            example %= 3;\n            Console.WriteLine($\" %= 3 = {example}\");\n\n\n            Console.WriteLine(\"----------------------------------------------\");\n            Console.WriteLine(\"----------------------------------------------\");\n\n\n            // 2. Operadores de Comparación\n            //  2.1 - Menor que (<)\n            Console.WriteLine(\"------- Menor que (<) ---------------\");\n            Console.WriteLine($\"{7.0} < {5.1} = {7.0 < 5.1}\");\n            Console.WriteLine($\"{5.0} < {5.1} = {5.0 < 5.1}\");\n\n            //  2.2 - Mayor que (>)\n            Console.WriteLine(\"------- Mayor que (>) ---------------\");\n            Console.WriteLine($\"{7.0} > {5.1} = {7.0 > 5.1}\");\n            Console.WriteLine($\"{5.0} > {5.1} = {5.0 > 5.1}\");\n\n            //  2.3 - Menor o igual que (<=)\n            Console.WriteLine(\"------- Menor o igual que (<=) ---------------\");\n            Console.WriteLine($\"{7.0} <= {5.1} = {7 <= 5.1}\");\n            Console.WriteLine($\"{5.0} <= {5.0} = {5 <= 5}\");\n\n            //  2.4 - Mayor o igual que (>=)\n            Console.WriteLine(\"------- Mayor o igual que (>=) ---------------\");\n            Console.WriteLine($\"{7.0} >= {5.1} = {7 >= 5.1}\");\n            Console.WriteLine($\"{5.0} >= {5.0} = {5 >= 5}\");\n\n\n            Console.WriteLine(\"----------------------------------------------\");\n            Console.WriteLine(\"----------------------------------------------\");\n\n\n            // 3. Operadores de Comparación\n            //  3.1 - Operador de negación lógico !\n            Console.WriteLine(\"------- Operador de negación lógico ! ---------------\");\n            bool passed = false;\n            Console.WriteLine($\"!passed = {!passed}\");\n            Console.WriteLine($\"!true = {!true}\");\n\n            //  3.2 - Operador lógico AND &\n            Console.WriteLine(\"------- Operador de negación lógico & ---------------\");\n            bool a = false & true;\n            Console.WriteLine($\"false & true = {a}\");\n\n            bool b = true & true;\n            Console.WriteLine($\"true & true = {b}\");\n\n            //  3.3 - Operador IR exclusivo lógico ^\n            Console.WriteLine(\"------- Operador IR exclusivo lógico ^ ---------------\");\n            Console.WriteLine($\"true ^ true = {true ^ true}\");\n            Console.WriteLine($\"true ^ false = {true ^ false}\");\n            Console.WriteLine($\"false ^ true = {false ^ true}\");\n            Console.WriteLine($\"false ^ false = {false ^ false}\");\n\n            //  3.4 - Operador lógico OR |\n            Console.WriteLine(\"------- Operador lógico OR | ---------------\");\n            a = false | true;\n            Console.WriteLine($\"false | true = {a}\");\n\n            b = true | true;\n            Console.WriteLine($\"true | true = {b}\");\n\n            //  3.5 - Operador lógico condicional AND &&\n            Console.WriteLine(\"------- Operador lógico condicional AND && ---------------\");\n            a = false && true;\n            Console.WriteLine($\"false && true = {a}\");\n\n            b = true && true;\n            Console.WriteLine($\"true && true = {b}\");\n\n            //  3.6 - Operador OR lógico condicional ||\n            Console.WriteLine(\"------- Operador OR lógico condicional || ---------------\");\n            a = false || true;\n            Console.WriteLine($\"false || true = {a}\");\n\n            b = true || true;\n            Console.WriteLine($\"true || true = {b}\");\n\n\n            Console.WriteLine(\"----------------------------------------------\");\n            Console.WriteLine(\"----------------------------------------------\");\n\n\n            // 4. Operadores de desplazamiento y bit a bit\n            //  4.1 - Operador de complemento bit a bit ~\n            Console.WriteLine(\"------- Operador de complemento bit a bit ~ ---------------\");\n            uint ae = 0b_0000_1111_0000_1111_0000_1111_0000_1100;\n            uint be = ~ae;\n            Console.WriteLine($\"{~ae} = {Convert.ToString(be, toBase: 2)}\");\n\n            //  4.2 - Operador de desplazamiento izquierdo <<\n            Console.WriteLine(\"------- Operador de desplazamiento izquierdo << ---------------\");\n            uint x = 0b_1100_1001_0000_0000_0000_0000_0001_0001;\n            Console.WriteLine($\"Before: {Convert.ToString(x, toBase: 2)}\");\n\n            uint y = x << 4;\n            Console.WriteLine($\"After:  {Convert.ToString(y, toBase: 2)}\");\n\n            //  4.3 - Operador de desplazamiento a la derecha >>\n            Console.WriteLine(\"------- Operador de desplazamiento a la derecha >> ---------------\");\n            x = 0b_1001;\n            Console.WriteLine($\"Before: {Convert.ToString(x, toBase: 2),4}\");\n\n            y = x >> 2;\n            Console.WriteLine($\"After:  {Convert.ToString(y, toBase: 2).PadLeft(4, '0'),4}\");\n\n            //  4.4 - Operador de desplazamiento a la derecha sin signo >>>\n            Console.WriteLine(\"------- Operador de desplazamiento a la derecha sin signo >>> ---------------\");\n            int xa = -8;\n            Console.WriteLine($\"Before:    {xa,11}, hex: {xa,8:x}, binary: {Convert.ToString(xa, toBase: 2),32}\");\n\n            int ya = xa >> 2;\n            Console.WriteLine($\"After  >>: {ya,11}, hex: {ya,8:x}, binary: {Convert.ToString(ya, toBase: 2),32}\");\n\n            int za = xa >>> 2;\n            Console.WriteLine($\"After >>>: {za,11}, hex: {za,8:x}, binary: {Convert.ToString(za, toBase: 2).PadLeft(32, '0'),32}\");\n\n\n            Console.WriteLine(\"----------------------------------------------\");\n            Console.WriteLine(\"----------------------------------------------\");\n\n\n            // 5. Operadores de igualdad\n            //  5.1 - Operador de igualdad ==\n            Console.WriteLine(\"------- Operador de igualdad == ---------------\");\n            int au = 1 + 2 + 3;\n            int bu = 6;\n            Console.WriteLine($\"{au} == {bu} = {au == bu}\");  // output: True\n\n            char c1 = 'a';\n            char c2 = 'A';\n            Console.WriteLine($\"{c1} == {c2} = {c1 == c2}\");  // output: False\n            Console.WriteLine($\"{c1} == {char.ToLower(c2)} = {c1 == char.ToLower(c2)}\");  // output: True\n\n            //  5.2 - Operador de desigualdad !=\n            Console.WriteLine(\"------- Operador de desigualdad != ---------------\");\n            int a2 = 1 + 1 + 2 + 3;\n            int b2 = 6;\n            Console.WriteLine($\"{a2} != {b2} = {a2 != b2}\");  // output: True\n\n            string s1 = \"Hello\";\n            string s2 = \"Hello\";\n            Console.WriteLine($\"{s1} != {s2} = {s1 != s2}\");  // output: False\n\n            object o1 = 1;\n            object o2 = 1;\n            Console.WriteLine($\"{o1} != {o2} = {o1 != o2}\");  // output: True\n\n\n            Console.WriteLine(\"----------------------------------------------\");\n            Console.WriteLine(\"----------------------------------------------\");\n\n\n            // 1. Estructuras de Control\n            //  1.1 - if\n            int a5 = 5;\n            int a6 = 6;\n            if (a5 == 5)\n            {\n                Console.WriteLine(\"Son iguales\");\n            } else\n            {\n                Console.WriteLine(\"No son iguales\");\n            }\n\n            if (a5 != a6)\n            {\n                Console.WriteLine(\"Son iguales\");\n            }\n            else\n            {\n                Console.WriteLine(\"No son iguales\");\n            }\n\n            //  1.2 - switch\n            switch(a5)\n            {\n                case 1: \n                    Console.WriteLine(\"1\");\n                    break;\n\n                case 2: \n                    Console.WriteLine(\"2\");\n                    break;\n\n                case 3: \n                    Console.WriteLine(\"3\");\n                    break;\n\n                 case 4:\n                    Console.WriteLine(\"4\");\n                    break;\n\n                 case 5: \n                    Console.WriteLine(\"5\");\n                    break;\n\n                default:\n                    Console.WriteLine(\"Es otro valor\");\n                    break;\n            }\n\n            //  1.3 - while\n            int aWhile = 0;\n            while (aWhile != 10)\n            {\n                aWhile++;\n                Console.WriteLine($\"aWhile: {aWhile}\");\n            }\n\n            //  1.4 - for\n            for(int j = 0; j < 10; j++)\n            {\n                Console.WriteLine($\"j: {j}\");\n            }\n\n            //  1.5 - foreach\n            string[] matriz = { \"rojo\", \"verde\", \"azul\", \"blanco\" };\n            foreach(string elemento in matriz)\n            {\n                Console.WriteLine($\"elemento: {elemento}\");\n            }\n\n            //  1.6 - do while\n            aWhile = 0;\n            do {\n                aWhile++;\n                Console.WriteLine($\"aWhile: {aWhile}\");\n\n            } while (aWhile != 10);\n\n\n\n\n            Console.WriteLine(\"----------------------------------------------\");\n            Console.WriteLine(\"----------------------------------------------\");\n            Console.WriteLine(\"------ Ejercicio ---------------\");\n\n            // Crea un programa que imprima por consola todos los números:\n            //  - comprendidos entre 10 y 55(incluidos)\n            //  - pares\n            //  - no son ni el 16\n            //  - ni múltiplos de 3\n            for (int i = 10; i < 56; i++)\n            {\n                if (i % 2 == 0 && i != 16 && i % 3 == 0) \n                { \n                    Console.WriteLine(i);\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c#/vixxtory.cs",
    "content": "using System;\nusing System.Diagnostics.Metrics;\nusing System.Reflection;\nusing System.Runtime.InteropServices.Marshalling;\n\nclass Hello\n{\n\n    static void Main()\n    {\n        //Operadores\n\n        byte x = 15;\n        bool y = false;\n        byte z = 3;\n        bool t = true;\n\n        // Operadores de Asignacin (unarios)\n        Console.WriteLine($\"x = 15 => +x = {+x}\");\n        Console.WriteLine($\"x = 15 => -x = {-x}\");\n        Console.WriteLine($\"y = false => !y = {!y}\");\n        Console.WriteLine($\"x = 15 => ++x = {++x}\");\n\n        // Operadores Aritmticos\n        Console.WriteLine($\"x = 15 y z = 3 => x * z = {x * z}\");\n        Console.WriteLine($\"x = 15 y z = 3 => x / z = {x / z}\");\n        Console.WriteLine($\"x = 15 y z = 3 => x % z = {x % z}\");\n        Console.WriteLine($\"x = 15 y z = 3 => x + z = {x + z}\");\n        Console.WriteLine($\"x = 15 y z = 3 => x - z = {x - z}\");\n\n        // Operadores Lgicos\n        Console.WriteLine($\"t = true y y = false => t && y = {y && t}\");\n        Console.WriteLine($\"t = true y y = false => t || y = {y || t}\");\n        Console.WriteLine($\"t = true => !t = {!t}\");\n\n        // Operadores de Comparacin o Relacionales\n        Console.WriteLine($\"x = 15 y z = 3 => x == z = {x == z}\");\n        Console.WriteLine($\"x = 15 y z = 3 => x != z = {x != z}\");\n        Console.WriteLine($\"x = 15 y z = 3 => x << z = {x << z}\"); //Desplazar bits a la izquierda.\n        Console.WriteLine($\"x = 15 y z = 3 => x >> z = {x >> z}\"); //Desplazar bits a la derecha.7\n        Console.WriteLine($\"x = 15 y z = 3 => x < z = {x < z}\");\n        Console.WriteLine($\"x = 15 y z = 3 => x > z = {x > z}\");\n        Console.WriteLine($\"x = 15 y z = 3 => x >= z = {x >= z}\");\n        Console.WriteLine($\"x = 15 y z = 3 => x <= z = {x <= z}\");\n\n        // Operadores de incremento y decremento\n\n        Console.WriteLine(\"x++ =  \" + (x++)); //Devuelve el valor de x y luego incrementa\n        Console.WriteLine(\"++x =  \" + (++x)); //Incrementa el valor de x y luego devuelve x\n        Console.WriteLine(\"x-- =  \" + (x--));\n        Console.WriteLine(\"--x =  \" + (--x));\n\n        //Operador condicional\n\n        Console.WriteLine(\"x ? y : z\" + (y ? x : t)); //Evala / devuelve x si y es verdadero; De lo contrario, evala t\n\n        //Operador de fusin nula\n\n        Console.WriteLine(x ?? y); //Devuelve x si no es nulo, De lo contrario, devuelve y .\n\n        /**ESTRUCTURAS DE CONTROL**/\n\n        //if - else:  Permite ejecutar un bloque de cdigo si se cumple una condicin, y otro bloque de cdigo si la condicin no se cumple.\n        if (x > 5)\n        {\n            Console.WriteLine(\"x es mayor que 5\");\n        }\n        else\n        {\n            Console.WriteLine(\"x no es mayor que 5\");\n        }\n\n        //switch-case: Permite seleccionar uno de varios bloques de cdigo para ejecutar, dependiendo del valor de una expresin.\n        int opcion = 2;\n        switch (opcion)\n        {\n            case 1:\n                Console.WriteLine(\"Opcin 1 seleccionada\");\n                break;\n            case 2:\n                Console.WriteLine(\"Opcin 2 seleccionada\");\n                break;\n            default:\n                Console.WriteLine(\"Opcin no vlida\");\n                break;\n        }\n\n        //for: Permite ejecutar un bloque de cdigo un nmero especfico de veces, controlando el ciclo mediante una variable de iteracin.\n        for (int i = 0; i < 5; i++)\n        {\n            Console.WriteLine(\"El valor de i es: \" + i);\n        }\n\n        //while: Ejecuta un bloque de cdigo mientras se cumple una condicin especificada.\n        int j = 0;\n        while (j < 5)\n        {\n            Console.WriteLine(\"El valor de j es: \" + j);\n            j++;\n        }\n\n        //do-while: Similar al bucle while, pero garantiza que el bloque de cdigo se ejecute al menos una vez antes de verificar la condicin.\n        int num;\n        do\n        {\n            Console.Write(\"Introduce un nmero positivo: \");\n            num = int.Parse(Console.ReadLine());\n        } while (num <= 0);\n        Console.WriteLine(\"Has introducido: \" + num);\n\n        //foreach: Se utiliza para iterar sobre los elementos de una coleccin o arreglo.\n        int[] numeros = { 1, 2, 3, 4, 5 };\n\n        foreach (int numero in numeros)\n        {\n            Console.WriteLine(numero);\n        }\n\n        //break: Se utiliza para salir de un bucle o de un bloque switch antes de que se complete su ejecucin.\n        for (int i = 1; i <= 10; i++)\n        {\n            Console.WriteLine(\"Nmero: \" + i);\n\n            if (i == 5)\n            {\n                Console.WriteLine(\"Se ha encontrado el nmero 5! Saliendo del bucle.\");\n                break;\n            }\n        }\n\n        //continue: Se utiliza para omitir el resto del cdigo en un bucle y pasar a la siguiente iteracin.\n        for (int i = 1; i <= 5; i++)\n        {\n            if (i == 3)\n            {\n                Console.WriteLine(\"Saltando la iteracin para el nmero 3.\");\n                continue;\n            }\n\n            Console.WriteLine(\"Nmero: \" + i);\n        }\n\n        //return: Se utiliza para devolver un valor de una funcin y salir de ella.\n        static int Sumar(int a, int b)\n        {\n            int suma = a + b;\n\n            return suma;\n        }\n\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c++/0pio.cpp",
    "content": "#include <iostream>\nusing namespace std;\n\nint main() {\n    int a = 5;\n    int b = 9;\n    //primero los operadores arigmeticos\n    //estos sirven para hacer operaciones matematicas y cambiar valores de las variables \n    cout << \"suma a + b = \" << a + b << \"\\n\";\n    cout << \"resta a - b =\" << a - b << \"\\n\";\n    cout << \"multiplicacion a * b = \" << a * b << \"\\n\";\n    cout << \"division a / b = \" << a / b << \"\\n\";\n    cout << \"modulo a % b = \" << a % b << \"\\n\";\n    cout << \"incremento a++ = \" << a++ << \"\\n\";\n    cout << \"decremento a-- = \" << a-- << \"\\n\";\n\n    //ahora operadores racionales\n    //estos son para comparar valores y determinar si es cierto o falso \n    cout << \"igual a 5 == 5 \\n\";\n    cout << \"noigual a 5 != 7 \\n\";\n    cout << \"mayor a 7 > 5 \\n\";\n    cout << \"menor a 5 < 7 \\n\";\n    cout << \"mayor o igual a 7 >= 5 \\n\";\n    cout << \"menor o igual a 5 <= 7 \\n\";\n\n    //operadores logicos\n    //estos son para añadir condiciones a las comparaciones\n    cout << \"and a > 2 && b < 14 \\n\";\n    cout << \"or a > 2 || b < 3 \\n\";\n    cout << \"not !(a > 2) \\n\";\n\n    //operadores de asignacion\n    int numero = 11;\n    cout << \"asignacion numero = 11 \\n\";\n    cout << \"suma y asignacion numero += 3 = \" << (numero += 3) << \"\\n\";\n    cout << \"resta y asignacion numero -= 3 = \" << (numero -= 3) << \"\\n\";\n    cout << \"multiplicacion y asignacion numero *= 3 = \" << (numero *= 3) << \"\\n\";\n    cout << \"division y asignacion numero /= 3 = \" << (numero /= 3) << \"\\n\";\n    cout << \"modulo y asignacion numero %= 3 = \" << (numero %= 3) << \"\\n\";\n    cout << \"desplazamiento de bits a la izquierda  numero <<= 3 = \" << (numero <<= 3) << \"\\n\";\n    cout << \"desplazamiento de bits a la derecha  numero >>= 3 = \" << (numero >>= 3) << \"\\n\";\n    cout << \"declaramos variable de bits AND numero2 &= 3 = \" << (numero &= 3) << \"\\n\";\n    cout << \"declaramos variable de bits OR numero2 |= 3 = \" << (numero |= 3) << \"\\n\";\n    cout << \"declaramos variable de bits XOR numero2 ^= 3 = \" << (numero ^= 3) << \"\\n\";\n   \n    // Operadores de bits en C++\n    //son usados para ahcer operaciones de un bit en integrers para lenguajes de bajo nivel \n    cout << \"Desplazamiento de bits a la izquierda: 1 << 3 = \" << (1 << 3) << \"\\n\";\n    cout << \"Desplazamiento de bits a la derecha: 8 >> 2 = \" << (8 >> 2) << \"\\n\";\n    cout << \"AND a nivel de bits: 5 & 3 = \" << (5 & 3) << \"\\n\";\n    cout << \"OR a nivel de bits: 5 | 3 = \" << (5 | 3) << \"\\n\";\n    cout << \"XOR a nivel de bits: 5 ^ 3 = \" << (5 ^ 3) << \"\\n\";\n    cout << \"NOT a nivel de bits: ~5 = \" << (~5) << \"\\n\";\n\n    /** los operadores de los siguientes comentarios no existen en c++ pero si en python\n    //operadores de identidad\n    //se usa para comparar si dos objetos son iguales\n    este tipo de operadores no existen en c++ y no se simula con == porque ==compara solo el numero y el is\n    compara en memoria también\n    int otro_numero = 1;\n    cout << \"es numero igual a otro_numero: \" << (numero is otro_numero) << \"\\n\";\n    cout << \"es numero diferente a otro_numero: \" << (numero is not otro_numero) << \"\\n\";\n\n\n    //operadores de pertenencia\n    //se usa para saber si un objeto esta en otro objeto pero tampoco existen en c++\n    cout << \"hay i en pio \" << (\"i\" in \"pio\") << \"\\n\";\n    cout << \"no hay i en pio \" << (\"i\" not in \"pio\") << \"\\n\"; \n\n    **/\n\n    //ahora estos operadores solo existen en c y c++ \n    cout << \"sizeof(a) = \" << sizeof(a) << \"\\n\";\n    cout << \"adress of operator &a = \" << &a << \"\\n\";\n    cout << \"pointer operator *a = \" << *(&a) << \"\\n\";\n    cout << \"reference operator a = \" << a << \"\\n\";\n\n    //vamos ahora a ver las estructuras de control \n    int a2 = 5;\n    int b2 = 9;\n    if (a2 > b2) {\n        cout << \"a es mayor que b \\n\";\n    } \n    else if  (a2 == b2) {\n        cout << \"a es igual que b \\n\";\n    }\n    else {\n        cout << \"a es menor que b \\n\";\n    }\n \n    //vamos a ver el switch\n    switch (a){\n        case 1:\n            cout << \"a es 1 \\n\";\n            break;\n        case 2:\n            cout << \"a es 2 \\n\";\n            break;\n        case 3:\n            cout << \"a es 3 \\n\";\n            break;\n        default:\n            cout << \"a no es 1, 2 o 3 \\n\";\n    }\n\n    //vamos a ver el bucle for\n    for (int i = 0; i < 5; i++) {\n        cout << \"i = \" << i << \"\\n\";\n    }\n\n    //vamos a ver el bucle while\n    int i = 0;\n    while (i < 5) {\n        cout << \"i = \" << i << \"\\n\";\n        i++;\n    }\n\n    //vamos a ver el bucle do while\n    int i2 = 0;\n    do {\n        cout << \"i = \" << i2 << \"\\n\";\n        i2++;\n    } while (i2 < 5);\n\n    \n    //ahora las declaraciones para manejar excepciones\n    //es el mage try que use para tiro parabolico \n    try {\n        throw 20;\n    }\n    catch (int e) {\n        cout << \"an exception occurred. Exception number is: \" << e << \"\\n\";\n    }\n\n    //ahora tenemos que imprimir los numeros entre 10 y 55 pares que nos son el 16 ni multiplos de 3\n    for (int o = 10; o <= 55; o++) {\n        if (o == 16 || o % 3 == 0) {\n            continue;\n        }\n        cout << o << \"\\n\";\n    }\n   \n\n    return 0;\n} "
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c++/Aldroide.cpp",
    "content": "//Operadores y extructuras de control\n// Ejercicio crea ehemplos utilizando los tipos de operadores en tu lenguaje\n// Aritmetico, lógicos, comparativos, asignación, identidad, pertenencia, bits.\n\n#include <iostream>\n#include <conio.h>\n\nusing namespace std;\n\n\nint main(){\n    // Ejemplos de operadores de asignación\n    cout<<\"Operadores de asignación\"<<endl;\n    int var =20;\n    cout<<\"Operador de asignación var = 20, \"<<var<<endl;\n    var +=5;\n    cout<<\"Suma 5 a la variable  var += 5, \"<<var<<endl;\n    var -= 10;\n    cout<<\"Resta 10 a la variable var -= 10, \"<<var<<endl;\n    var *= 2;\n    cout<<\"Multiplica 2 a la variable var *= 10, \"<<var<<endl;\n    var /= 5;    \n    cout<<\"Divide entre 5 a la variable var /= 5, \"<<var<<endl;\n    var %= 2;\n    cout<<\"Modulo entre 2 a la variable var = 2, \"<<var<<endl;\n\n     // Ejemplos de operadores aritmeticos\n    cout<<\"Operadores aritmeticos\"<<endl;\n    var = 10;\n    cout<<\"operador Signo negativo: \"<< -var<<endl;\n    cout<<\"operador Incremento: \"<< ++var<<endl;\n    cout<<\"operador Decremento: \"<< --var<<endl;\n    cout<<\"operador Suma: 2 + 3 = \"<< 2 + 3<<endl;\n    cout<<\"operador Resta: 3 - 2 = \"<< 3 - 2<<endl;\n    cout<<\"operador Multiplicacion: 10 * 5 = \"<< 10 * 5<<endl;\n    cout<<\"operador Division: 24 / 6 = \"<< 24 / 6<<endl;\n    cout<<\"operador  Modulo: 30 % 11 = \"<< 30 % 11<<endl;\n\n    // Ejemplos de operadores relacionales\n    cout<<endl<<\"Operadores relacionales\"<<endl;\n    int a=10, b=20;\n    cout<<\"resultado a<b: \"<<(a<b)<<endl;\n    cout<<\"resultado a>b: \"<<(a>b)<<endl;\n    cout<<\"resultado de igualdad a==b: \"<<(a==b)<<endl;\n    cout<<\"resultado de desigualdad a!=b: \"<<(a!=b)<<endl;\n    cout<<\"resultado de mayor o igual que a>=b:\"<<(a>=b)<<endl;\n    cout<<\"resultado de menor o igual que a<=b: \"<<(a<=b)<<endl;\n\n    // Ejemplos de operadores lógicos\n    cout<<endl<<\"Operadores lógicos\"<<endl;\n    a = 13;\n\n    cout<<\"AND a > 5 && a < 15: \"<<(a > 5 && a < 15)<<endl;\n    cout<<\"OR a > 5 || a < 15: \"<<(a > 5 || a < 15)<<endl;\n    cout<<\"NOT !(a > 5 && a < 15): \"<< (!(a > 5 && a < 15)) <<endl;\n\n// If and Else\n    cout<<endl<<\"Condicional if-else a>b\"<<endl;\n    if(a>b){\n        cout<<\"a es mayor que b\"<<endl;\n    }\n    else{\n        cout<<\"a es menor que b\"<<endl;\n    }\n\n// switch case\n    cout<<endl<<\"Switch Case\"<<endl;\n    int option = 2;\n    switch (option)\n    {\n    case 1:\n        cout<<\"Realizar acción 1\"<<endl;\n        break;\n    case 2:\n        cout<<\"Realizar acción 2\"<<endl;\n        break;    \n    default:\n        cout<<\"No hay mas acciones\"<<endl;\n        break;\n    }\n    \n\n    // for\n    cout<<endl<<\"Estructura for\"<<endl;\n    for(int i=0; i<=10;i++)\n        cout<<i<<\" \";\n\n    // do While\n    cout<<endl<<\"Estructura do while\"<<endl;\n    do\n    {\n        cout<<\"Ingresar 1 para salir\"<<endl;\n        cin>>option;\n    } while (option!=1);\n    \n\n    // While\n    cout<<endl<<\"estructura while\"<<endl;\n    int c=1;\n    while(c<=10){\n        cout<<c<<\" \";\n        c++;\n    }\n\n\n// Dificultad Extra\n    cout<<endl<<\"Dificultad extra\"<<endl;\n    for (int i=1; i<=25; i++)\n        if(i!=16 && i%2 ==0 && i%3 != 0)\n            cout<<i<<\" \";\n    \n    getch();\n    return 0;\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c++/AlejandroDave.cpp",
    "content": "// Ejercicio 01\n#include <iostream>\nusing namespace std;\n\nint main(){\n    //============ Operaciones Aritmeticas ================\n    int a,b,c,d;\n    cin>>a>>b;   // a y b seran declaradas por el usuario\n    c = 20; d = 54 ; // c y d seran declaradas por el programa\n\n    cout<<a<<\" + \"<<b<<\" = \"<<a+b<<endl;\n    cout<<a<<\" - \"<<b<<\" = \"<<a-b<<endl;\n    cout<<a<<\" * \"<<b<<\" = \"<<a*b<<endl;\n    if(b!=0)cout<<a<<\" / \"<<b<<\" = \"<<a/b<<endl;\n\n    //============ Operaciones logicas ===============\n    /*\n    para las operaciones logicas tenemos las siguientes operaciones\n    && representa la operacion AND\n    || representa la operacion OR\n    ! representa la operacion NOT\n    > representa mayor que\n    < representa menor que\n    == representa igualdad\n\n    las operaciones booleanas nos devolveran un 1 si es true, y un 0 si es false\n    */\n    bool b1,b2,b3;\n    b1 = (a>b)&&(c==d);\n    b2 = (a==c)||(b>=d);\n    b3 = !(a>b);\n    cout<<b1<<b2<<b3;\n    cout<<endl;\n    //============= Operaciones condicionales ==================\n    /*\n    Los comandos condicionales se activan cuando se cumplen algun tipo de parametro establecido en el programa, como se vio en la representacion\n    de la division, se genero una condicion donde se efectuara el siguiente codigo siempre y cuando se cumpla que b sea diferente de 0\n\n    la condicional if/else se ejecuta cuando se cumple un parametro y en caso de no cumplirse se ejecutara el siguiente codigo\n    la condicional while se ejecutara mientras el parametro se cumpla\n    la condicional for se ejecutara de igual forma que el while, cuando se cumpla un parametro.\n    */\n\n    if(a>b) cout<<a<<\" es mayor que \"<<b<<endl;\n    else cout<<a<<\" es menor que \"<<b<<endl;\n    while(a>0){cout<<a<<\" \";a--;}\n    cout<<endl;\n    for(int i = 0; i<b;i++){cout<<i<<\" \";}\n    cout<<endl;\n    // Ejercicio extra\n\n    for(int i=10;i<56;i++){\n        if(i%2==0){\n            if(i%3==1){\n                if(i!=16){\n                    cout<<i<<endl;\n                }\n            }\n        }\n    }\n\n    return 0;\n    }\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c++/CesarCarmona30.cpp",
    "content": "#include <iostream>\n#include <stdexcept> \n#include <typeinfo>\nusing namespace std;\n\nint main(int argc, char const *argv[]) {\n  // Operadores Aritméticos\n  cout << \"(+)Suma: 8 + 5 = \" << 8 + 5 << endl;\n  cout << \"(-)Resta: 8 - 5 = \" << 8 - 5 << endl;\n  cout << \"(*)Multiplicacion: 8 * 5 = \" << 8 * 5 << endl;\n  cout << \"(/, si uno de los datos es float o se convierte a float)Division: 8 / 5 = \" << (float) 8 / 5 << endl;\n  cout << \"(/)Division entera: 8 / 5 = \" << 8 / 5 << endl;\n  cout << \"(%)Modulo: 8 % 5 = \" << 8 % 5 << endl;\n  int a = 5, b, c;\n  b = ++a;\n  cout << \"(++n)Pre-incremento: a = 5, b = ++a \" << \"(a: \" <<  a << \", b: \" << b << ')' << endl;\n  a = 5;\n  c = a++;\n  cout << \"(n++)Pos-incremento: a = 5, c = a++ \" << \"(a: \" <<  a << \", c: \" << c << ')' << endl;\n  a = 10;\n  b = --a;\n  cout << \"(--n)Pre-decremento: a = 10, b = --a \" << \"(a: \" <<  a << \", b: \" << b << ')' << endl;\n  a = 10;\n  c = a--;\n  cout << \"(n--)Pos-decremento: a = 10, c = a-- \" << \"(a: \" <<  a << \", c: \" << c << ')' << endl;\n  \n  // Operador Ternario\n  cout << \"Expresion a evaluar ? resultado si es verdadero : Resultado si es falso\" << endl;\n  cout << \"5 > 10 ? \\\"Verdadero\\\" : \\\"Falso\\\" = \" << (5 > 10 ? \"Verdadero\" : \"Falso\") << endl;\n\n  // Operadores Lógicos\n  cout << \"AND (&&):\" << endl;\n  cout << \"true && true = \" << (true && true ? \"true\" : \"false\") << endl;\n  cout << \"true && false = \" << (true && false ? \"true\" : \"false\") << endl;\n  cout << \"false && false = \" << (false && false ? \"true\" : \"false\") << endl;\n  cout << \"OR (||):\" << endl;\n  cout << \"true || true = \" << (true || true ? \"true\" : \"false\") << endl;\n  cout << \"true || false = \" << (true || false ? \"true\" : \"false\") << endl;\n  cout << \"false || false = \" << (false || false ? \"true\" : \"false\") << endl;\n  cout << \"NOT (!):\" << endl;\n  cout << \"!true = \" << (!true ? \"true\" : \"false\") << endl;\n  cout << \"!false = \" << (!false ? \"true\" : \"false\") << endl;\n  \n  //Operadores de Comparación\n  cout << \"Igualdad: 15 == 5 es \" << (15 == 5 ? \"true\" : \"false\") << endl;\n  cout << \"Desigualdad: 15 != 5 es \" << (15 != 5 ? \"true\" : \"false\") << endl;\n  cout << \"Mayor que: 15 > 5 es \" << (15 > 5 ? \"true\" : \"false\") << endl;\n  cout << \"Menor que: 15 < 5 es \" << (15 < 5 ? \"true\" : \"false\") << endl;\n  cout << \"Mayor o igual que: 15 >= 155 es \" << (15 >= 155 ? \"true\" : \"false\") << endl;\n  cout << \"Menor o igual que: 155 <= 155 es \" << (155 <= 155 ? \"true\" : \"false\") << endl;\n\n  //Operadores de Asignación\n  int number = 50;\n  cout << \"Asignacion: numero = \" << number << endl;\n  number += 1;\n  cout << \"Suma y asignacion: numero += 1 \" << '(' << number << ')' << endl;\n  number -= 3;\n  cout << \"Resta y asignacion: numero -= 3 \" << '(' << number << ')' << endl;\n  number *= 3;\n  cout << \"Division y asignacion: numero *= 3 \" << '(' << number << ')' << endl;\n  number /= 4;\n  cout << \"Multiplicacion y asignacion: numero /= 4 \" << '(' << number << ')' << endl;\n  number %= 5;\n  cout << \"Modulo y asignacion: numero %= 5 \" << '(' << number << ')' << endl;\n\n  //Operadores bit a bit\n  cout << \"AND: 10 & 12 = \" << (10 & 12) << endl;\n  cout << \"OR: 10 | 12 = \" << (10 | 12) << endl;\n  cout << \"XOR: 10 ^ 12 = \" << (10 ^ 12) << endl;\n  cout << \"NOT: ~12 = \" << (~2) << endl;\n  cout << \"Desplazamiento a la derecha: 10 >> 2 = \" << (10 >> 2) << endl;\n  cout << \"Desplazamiento a la izquierda: 10 << 2 = \" << (10 << 2) << endl;\n  \n  //Condicionales\n  string mi_lenguaje = \"C++\";\n  cout << \"Ejecutando estructura if: \" << endl;\n  if (mi_lenguaje == \"JavaScript\") {\n    cout << \"Estoy programando en JavaScript\" << endl;\n  } else if (mi_lenguaje == \"Python\") {\n    cout << \"Estoy programando en Python\" << endl;\n  } else {\n    cout << \"Estoy programando en \" << mi_lenguaje << endl;\n  }\n\n  int dia = 5;\n  cout << \"Ejecutando estructura switch: \" << endl;\n  switch (dia) {\n  case 1:\n    cout << \"Lunes\" << endl;\n    break;\n  case 2:\n    cout << \"Martes\" << endl;\n    break;\n  case 3:\n    cout << \"Miercoles\" << endl;\n    break;\n  case 4:\n    cout << \"Jueves\" << endl;\n    break;\n  case 5:\n    cout << \"Viernes\" << endl;\n    break;\n  case 6:\n    cout << \"Sabado\" << endl;\n    break;\n  case 7:\n    cout << \"Domingo\" << endl;\n    break;          \n  default:\n    cout << \"No existe el dia\" << endl;\n    break;\n  }\n\n  //Iterativas\n\n  cout << \"Ejecutando estructura for: \" << endl;\n  for (int i = 1; i <= 10; i++) {\n    cout << i << \", \";\n  }\n  cout << endl;\n  string name = \"cesar\";\n  int index = 0;\n  cout << \"Ejecutando estructura while: \" << endl;\n  while (index < name.length()) {\n    cout << name[index] << \"-\";\n    index++;\n  }\n  cout << \"Ejecutando estructura do-while: \" << endl;\n  string alphabet = \"ABCDEFGHIJKJLMNOPQRSTUVWXYZ\", text = \"\";\n  int letter = 0;\n  do {\n    text += alphabet[letter];\n    cout << text << endl;\n    letter++;\n  } while (text.length() != alphabet.length());\n\n  // Manejo de Excepciones\n  class ZeroDivisionExcept : public std::exception {\n    public:\n      ZeroDivisionExcept(const char* message) : errorMessage(message) {}\n      virtual const char* what() const noexcept override {\n        return errorMessage;\n      }\n    private:\n      const char* errorMessage;\n  };\n  cout << \"Ejecutando estructura try-catch\" << endl;\n  cout << \"5 / 0 = ...\" << endl;\n  try {\n    throw ZeroDivisionExcept(\"Division por cero.\");\n  } catch (const ZeroDivisionExcept& err) {  \n    cout << \"Se produjo un error de tipo: \" << typeid(err).name() << endl;\n    cout << err.what() << endl;\n    cout << \"*Nota: Recuerda que la division por cero no esta definida.\" << endl;\n  }\n\n  /*\n    EXTRA\n  */\n\n  for (int number = 10; number <= 55; number++) {\n    if ((number % 2 != 0) || (number == 16) || (number % 3 == 0)){\n      continue;\n    }\n    cout << number << \" \";\n  }\n  return 0;\n\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c++/CrisVigas.cpp",
    "content": "/**\n * ESTANDAR MINIMO C++20\n * (Se debe usar -std=c++20 con soporte para <format>)\n */\n\n#include <bitset>\n#include <cstdint>\n#include <format>\n#include <iostream>\n#include <string>\n#include <vector>\n\nstatic std::string binario(const uint8_t num) {\n  return std::bitset<8>(num).to_string();\n}\n\nint main() {\n  constexpr int32_t a{10'000};\n  constexpr int32_t b{99};\n  int32_t c{10'000};\n\n  uint8_t m{0B1001'1001};\n  uint8_t n{0B1010'1100};\n\n  std::cout << \"Ejecutando Operadores Aritmeticos:\\n\";\n  std::cout << std::format(\"a = {}\\n\", a);\n  std::cout << std::format(\"b = {}\\n\", b);\n  std::cout << std::format(\"a + b = {}\\n\", (a + b));\n  std::cout << std::format(\"a - b = {}\\n\", (a - b));\n  std::cout << std::format(\"a * b = {}\\n\", (a * b));\n  std::cout << std::format(\"a / b = {}\\n\", (a / b));\n  std::cout << std::format(\"a % b = {}\\n\", (a % b));\n\n  std::cout << \"\\nEjecutando Operadores de Bit:\\n\";\n  std::cout << std::format(\"m\\t= {}\\n\", ::binario(m));\n  std::cout << std::format(\"n\\t= {}\\n\", ::binario(n));\n  std::cout << std::format(\"m | n\\t= {}\\n\", ::binario(m | n));\n  std::cout << std::format(\"m & n\\t= {}\\n\", ::binario(m & n));\n  std::cout << std::format(\"m ^ n\\t= {}\\n\", ::binario(m ^ n));\n  std::cout << std::format(\"~m\\t= {}\\n\", ::binario(~m));\n  std::cout << std::format(\"~n\\t= {}\\n\", ::binario(~n));\n  std::cout << std::format(\"n << 2\\t= {}\\n\", ::binario(n << 2));\n  std::cout << std::format(\"n >> 3\\t= {}\\n\", ::binario(n >> 3));\n\n  std::cout << \"\\nEjecutando Operadores de Comparacion:\\n\";\n  std::cout << std::format(\"a = {}, b = {}, c = {}\\n\", a, b, c);\n  std::cout << std::format(\"(a == b)\\t= {}\\n\", a == b);\n  std::cout << std::format(\"(a == c)\\t= {}\\n\", a == c);\n  std::cout << std::format(\"(a != b)\\t= {}\\n\", a != b);\n  std::cout << std::format(\"(a != c)\\t= {}\\n\", a != c);\n  std::cout << std::format(\"(a < b)\\t\\t= {}\\n\", a < b);\n  std::cout << std::format(\"(a < c)\\t\\t= {}\\n\", a < c);\n  std::cout << std::format(\"(a > b)\\t\\t= {}\\n\", a > b);\n  std::cout << std::format(\"(a > c)\\t\\t= {}\\n\", a > c);\n  std::cout << std::format(\"(a <= b)\\t= {}\\n\", a <= b);\n  std::cout << std::format(\"(a <= c)\\t= {}\\n\", a <= c);\n  std::cout << std::format(\"(a >= b)\\t= {}\\n\", a >= b);\n  std::cout << std::format(\"(a >= c)\\t= {}\\n\", a >= c);\n\n  std::cout << \"\\nEjecutando Operadores Logicos:\\n\";\n  std::cout << std::format(\"!true\\t\\t= {}\\n\", !true);\n  std::cout << std::format(\"!false\\t\\t= {}\\n\", !false);\n  std::cout << std::format(\"true && true\\t= {}\\n\", true && true);\n  std::cout << std::format(\"true && false\\t= {}\\n\", true && false);\n  std::cout << std::format(\"false && false\\t= {}\\n\", false && false);\n  std::cout << std::format(\"true || true\\t= {}\\n\", true || true);\n  std::cout << std::format(\"true || false\\t= {}\\n\", true || false);\n  std::cout << std::format(\"false || false\\t= {}\\n\", false || false);\n\n  std::cout << \"\\nEjecutando Operadores de Asignacion:\\n\";\n  std::cout << \"Creamos una variable V sin inicializar:\\tint32_t v;\\n\";\n  int32_t v;\n  std::cout << std::format(\"v = {}\\n\", v);\n  std::cout << \"El valor de v es indeterminado y pude ser cualquier cosa.\\n\";\n  std::cout << \"Asignamos el valor 42 a la variable V:\\tv = 42;\\n\";\n  v = 42;\n  std::cout << std::format(\"v = {}\\n\", v);\n\n  std::cout << \"\\nEjecutando Estructuras de Control (if):\\n\";\n  if (true) {\n    std::cout << \"\\tDentro de un if\\n\";\n  }\n\n  std::cout << \"\\nEjecutando Estructuras de Control (if/else):\\n\";\n  if (false) {\n    std::cout << \"\\tAhora esto no se ejecutara\\n\";\n  } else {\n    std::cout << \"\\tDentro de un else con condicion falsa\\n\";\n  }\n\n  std::cout << \"\\nEjecutando Estructuras de Control (switch):\\n\";\n  switch (b) {\n    case 98:\n      std::cout << \"\\tEl valor es 98\\n\";\n      break;\n    case 99:  // la opcion correcta\n      std::cout << \"\\tEl valor es 99\\n\";\n      break;\n    case 100:\n      std::cout << \"\\tEl valor es 100\\n\";\n      break;\n    default:\n      std::cout << \"\\tEl valor no es ninguno de los anteriores\\n\";\n      break;\n  }\n\n  std::cout << \"\\nEjecutando Estructuras de Control (while sin break):\\n\";\n  while (c != 10'005) {\n    std::cout << std::format(\"\\tc = {}\\n\", c);\n    ++c;\n  }\n\n  std::cout << \"\\nEjecutando Estructuras de Control (while con break):\\n\";\n  while (true) {\n    std::cout << std::format(\"\\tc = {}\\n\", c);\n    if (c == 10'010) {\n      std::cout << \"\\t\\tAhora se ejecutara un break que terminara el while\\n\";\n      break;\n    }\n    ++c;\n  }\n\n  std::cout << \"\\nEjecutando Estructuras de Control (for):\\n\";\n  for (auto i{c}; i != 10'015; ++i) {\n    std::cout << std::format(\"\\ti = {}\\n\", i);\n  }\n\n  std::cout << \"\\nEjecutando Estructuras de Control (for con break):\\n\";\n  for (auto i{c}; true; ++i) {\n    std::cout << std::format(\"\\ti = {}\\n\", i);\n    if (i == 10'015) {\n      std::cout << \"\\t\\tAhora se ejecutara un break que terminara el for\\n\";\n      break;\n    }\n  }\n\n  std::cout << \"\\nEjecutando Estructuras de Control (for con continue):\\n\";\n  std::cout << \"\\tAhora nos saltaremos miles de pasos, nos vemos en el futuro\";\n  for (auto i{c}; i != 10'000'005; ++i) {\n    if (i < 10'000'000) {\n      continue;\n    }\n\n    std::cout << std::format(\"\\ti = {}\\n\", i);\n  }\n\n  std::cout << \"\\nEjecutando Estructuras de Control (for con iterable):\\n\";\n  std::vector<char> vec{'H', 'o', 'l', 'a', '!', '*', 'e', 'r', 'r', 'o', 'r'};\n  for (const auto& element : vec) {\n    if (element == '*') {\n      break;\n    }\n    std::cout << element;\n  }\n  std::cout << '\\n';\n\n  std::cout << \"\\nEjecutando excepcion con captura definida:\\n\";\n  try {\n    std::cout << \"\\tIntentaremos acceder fuera de rango en un vector\\n\";\n    auto e{vec.at(50'000)};\n    std::cout << \"\\tEsta linea solo se ejecutara si no hubo errores.\\n\";\n  } catch (const std::out_of_range& error) {\n    std::cout << std::format(\"\\tError: {}\\n\", error.what());\n    std::cout << \"\\tYa que sabemos el tipo de error, podemos tomar medidas\\n\";\n    auto e{vec.back()};\n  }\n\n  std::cout << \"\\nEjecutando excepcion con captura generica:\\n\";\n  try {\n    int32_t e{std::stoi(\"F\")};\n    std::cout << e;\n  } catch (...) {\n    std::cout << \"\\tAlgo raro ha pasado!\";\n  }\n\n  // DIFICULTAD EXTRA\n  std::cout << \"\\n== DIFICULTAD EXTRA ==\\n\";\n  for (int32_t i{10}; i <= 55; ++i) {\n    if (((i % 2) == 0) && (i != 16) && ((i % 3) != 0)) {\n      std::cout << i << '\\n';\n    }\n  }\n\n  return EXIT_SUCCESS;\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c++/Fravelz.cpp",
    "content": "#include <iostream>\n\nusing namespace std;\n\nint main() {\n    cout << endl;\n\n    // **************** Operadores **************** //\n    int a = 10, b = 20;\n\n    // Operadores Aritmeticos\n    cout << \" > Incremento: \" << a++ << '\\n';\n    cout << \" > Decremento: \" << a-- << '\\n';\n    \n    cout << '\\n';\n    \n    cout << \" > Suma: \"           << 20 + 10  << '\\n';\n    cout << \" > Resta: \"          << 20 - 10  << '\\n';\n    cout << \" > Multiplicacion: \" << 20 * 10  << '\\n';\n    cout << \" > Division: \"       << 625 / 25 << '\\n';\n    cout << \" > Resto: \"          << 101 % 2  << '\\n';\n    cout << endl;\n\n    // Operadores de Asignacion\n    int res = 0;\n\n    res += a; // Suma (0 + 10 = 10) \n    res -= 8; // Resta (10 - 8 = 2)\n    res *= 4; // Multipricacion (2 * 4 = 8)\n    res /= 2; // Division (8 / 2 = 4)\n    res %= 3; // Modulo o Resto (4 % 3 = 1)\n\n    cout << \" > El Resultado es: \" << res << '\\n';\n    cout << endl;\n    \n    // Operadores Logicos de Comparacion \n    cout << \" > Mayor que: \"       << (a > b)   << '\\n';\n    cout << \" > Menor que: \"       << (a < b)   << '\\n';\n    cout << \" > Igual que: \"       << (a == b)  << '\\n';\n    cout << \" > Mayor igual que: \" << (a >= b)  << '\\n';\n    cout << \" > Menor igual que: \" << (a <= b)  << '\\n';\n    cout << \" > Diferente que: \"   << !(a == b) << '\\n';\n    cout << endl;\n\n    // Operadores de Bit a Bit\n    cout << \"> OR: \"                            << (a | b)  << '\\n';\n    cout << \"> AND: \"                           << (a & b)  << '\\n';\n    cout << \"> XOR: \"                           << (a ^ b)  << '\\n';\n    cout << \"> NOT: \"                           << (~a)     << '\\n';\n    cout << \"> Desplazamiento a la izquierda: \" << (a << 2) << '\\n';\n    cout << \"> Desplazamiento a la derecha: \"   << (a >> 3) << '\\n';\n\n    // **************** Bucles, Condicionales y Exepciones **************** //\n    \n    // Numeros Impares hasta el 11 (Bucle for, y Operador Ternario)\n    for (int x = 1; x <= 11; x += 2) { \n        cout << x << (x != 11) ? \", \" : \".\";\n    }\n\n    cout << endl;\n\n    // Suma de Numeros Pares (Bucle while y condicionales)\n    int sum = 0, iter = 0;\n\n    while (iter <= 10) {\n        if (iter != 10) {\n            cout << sum << \", \";\n\n        } else {\n            cout << sum << \". \";\n        }\n        \n        sum += iter;\n        iter++;\n    }\n    \n    cout << endl;\n    \n    // Factorial de 5 (Bucle do while y condicionales) \n    // [Mucha cosa inesesaria se puede obtimizar :v]\n\n    int factorial = 0, iter2 = 0;\n\n    do {        \n        factorial *= iter2;\n        iter2++;\n\n        if (iter2 != 10 && factorial != 0) {\n            \n            if (iter2 % 5 == 1 && iter2 != 0) {\n                cout << factorial << \". \";\n                break;\n            } \n\n            else {\n                cout << factorial << \", \";\n\n            }\n            \n        \n        } else if (factorial == 0) {\n            factorial = 1;\n            continue;\n\n        } else {\n            cout << factorial << \". \";\n        }\n        \n    } while (iter2 <= 10);\n\n    cout << endl;\n\n    try { // Código que puede lanzar una excepción\n        throw \"Ocurrió un error\";  // Lanzar excepción\n\n    } catch (const char* msg) {\n        cout << \"\\nError404: \" << msg << \" :v\" << endl;\n    }\n    \n    cout << endl;\n\n    //* DIFICULTAD EXTRA (opcional):\n    //* Crea un programa que imprima por consola todos los números comprendidos\n    //* entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n    //*\n    //* Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\n    cout << \" [+] Reto de la dificultad Extra: \";\n    \n    for (int y = 10; y <= 55; y += 2) {\n\n        if (y != 16 && y % 3 != 0) {\n            cout << y << ( (y < 52) ? \", \": \".\" );\n        }\n        \n    }\n\n    cout << endl;\n\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c++/Gallitofast.cpp",
    "content": "// #include <iomanip>\n#include <iostream>\nint main() {\n  float a{10}, b{6};\n  // float result;\n  //  Operadores aritmeticos\n  std::cout<< \"\\n\\n=================================================================\"<< std::endl;\n  std::cout << \"Operadores aritmeticos\" << std::endl;\n  std::cout << \"variable a vale: \" << a << \" Variable b vale : \" << b << std::endl;\n  std::cout << \"Suma a +b: \" << a + b << \"\\n\";\n  std::cout << \"resta a-b: \" << a - b << \"\\n\";\n  std::cout << \"Multiplicacion de a*b: \" << a * b << \"\\n\";\n  std::cout << \"Division de a/b: \" << a / b << \"\\n\";\n  std::cout << \"Incremento de a\" << a++ << std::endl;\n  std::cout << \"Decremento de a \" << a-- << std::endl;\n  // Operaciones de comparacion\n  // estos resultados se imprimiran en booleanos, 0 es falso y 1 verdadero, o\n  // usar la funcion de showbool\n  std::cout<< \"\\n\\n=================================================================\"<< std::endl;\n  std::cout << \"Comparadores\" << std::endl;\n  std::cout <<\"Los resultados booleanos por defecto se imprimen como 0=false y 1=true (existe std::boolaplha para imprimirlos en alfanumerico)\\n\";\n  std::cout << \"igual a: (a==b)-->\" << (a == b) << std::endl;\n  std::cout << \"desigual a: (a!=b)\" << (a != b) << std::endl;\n  std::cout << \"Mayor que (a>b)\" << (a > b) << std::endl;\n  std::cout << \"Menor que (a<b)\" << (a < b) << std::endl;\n  std::cout << \"Mayor o igual que (a>=b)\" << (a >= b) << std::endl;\n  std::cout << \"Menor o igual que (a<=b)\" << (a <= b) << std::endl;\n\n  std::cout << \"\\n\\n=================================================================\"<< std::endl;\n  std::cout << \"Operadores logicos\\n\";\n  std::cout << \"Los operadores logicos se representan asi; \\nOR=|| \\nAND=&& NOT=!\"<< std::endl;\n  std::cout << \"and sirve para juntar dos condiciones, como las siguientes:\"<< std::endl;\n  std::cout << \"a>5 %% b<<3: (\" << (a > 5 && b < 3)<< \") (Como las dos se cumplieron dan 1 que significa true)\\n\";\n  std::cout << \"Or da true si una de las condiciones da verdad como la siguiente:\"<< std::endl;\n  std::cout << \"a>15 (Falso) || b>2 (Verdadero): (\" << (a > 15 || b > 1) << \")\"<< std::endl;\n  std::cout << \"Not invierte los valores, si es false da true y si es true da false\\n\";\n  std::cout << \"!a>5 (es true pero dara false por el not): (\" << (!(a > 5))<< \")\" << std::endl;\n  std::cout << \"b>100 (es falso asi que dara true): (\" << (!(b > 100)) << \")\"<< std::endl;\n\n  std::cout << \"\\n\\n=================================================================\"<< std::endl;\n  std::cout << \"Operadores de asignacion\\n\" << std::endl;\n  int numero{11};\n  std::cout << \"Operador de asignacion, puedes asignar a una variable con {} o = al declarar la variable o al modificarla\"<< std::endl;\n  std::cout << \" todos son el signo del operador, seguidos de un =\"<< std::endl;\n  std::cout << \"Operador de suma y asignacion +=3: ->\" << (numero += 3)<< std::endl;\n  std::cout << \"Operador de resta y asignacion -=3: ->\" << (numero -= 4)<< std::endl;\n  std::cout << \"Multiplicamos y asignacion de numero *=3: ->\" << (numero *= 3)<< std::endl;\n  std::cout << \"Division y asignacion de numero /=3: ->\" << (numero /= 3)<< std::endl;\n  std::cout << \"Modulo y asignacion de numero %=3: ->\" << (numero %= 3)<< std::endl;\n  std::cout << \"Hasta aqui los operadores de asignacion que yo conozco\"<<std::endl;\n  std::cout << \"\\n\\n=================================================================\"<< std::endl;\n  std::cout<<\"Condicionales\"<<std::endl;\n  int condicionales{4};\n  if (condicionales>2){\n    std::cout<<\"Este texto acaba de ejecutarse a traves de una condicional if\\n\";\n  }\n  //Else\n  if(condicionales>10){\n    std::cout<<\"Esta condicional no se cumplira\";\n  }else{std::cout<<\"Esta condicional es el else asi que como no se cumplio el if, esto se imprimira\\n\";}\n  //else if \n  if(condicionales>100){\n    std::cout<<\"Esta condicional de nuevo no se cumplira\\n\";\n  }else if(condicionales==4){std::cout<<\"else if paso\\n\\n\";}\n\n  //switch\n  switch(condicionales){\n    //aca puedes poner los casos que gustes pero por fines practicos usaremos union\n    case 4:\n      std::cout<<\"Este caso se va a cumplir por que el 4 iguala el valor de la variable que es la condicion\\n\";\n    break;\n    default:\n      std::cout<<\"En caso que ningun caso se cumpla o exista algun error recomiendo usar el default para caso por omision\\n\";\n    break;\n  }\n  std::cout<<\"\\n====================================================================================\\n\\n\";\n  std::cout<<\"Operaciones iterativas\"<<std::endl;\n  int contador=10;\n  for (;contador > 0;contador--){\n       std::cout<<contador<<\": Numero de iteracion con ciclo for\\n\";\n  }\n  contador=10; //Volvemos a darle valor al contador\n  while(contador>0){\n    std::cout<<contador<<\": Numero de itaracion con ciclo while\\n\";\n    contador--;\n\n  }\n\n  //Dificultad extra \n  for (int i=10; i<56; i++){\n    if(i%2==0 && i!=16 && i%3!=0){\n      std::cout<<\"Numero: \"<<i<<std::endl;\n    }\n  }\n  return 0;\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c++/ItsThemasii.cpp",
    "content": "#include <iostream>\n#include <string>\n#include <cmath>\n\nusing namespace std;\n\n// Operadores !!!\nint main () {\n   // Operadores Aritmeticos\n   cout << \"Suma 16 + 7 = 23 \\n\";\n\n   int a,b;\n   cout << \"Valor de a: \";\n   cin >> a;\n   cout << \"Valor de b: \";\n   cin >> b;\n\n   int suma = a + b;\n   cout << \"La suma de a y b es: \" << suma << endl;\n   cout << \"Suma: \" << 23 + 6;\n   cout << \"\\nResta: \" << 23 - 6;\n   cout << \"\\nProducto: \" << 23*6;\n   cout << \"\\nDivision: \" << 23/6;\n   double division = 23.0/6.0;\n   cout << \"\\nDivision corregido: \" << division;\n   long potencia = pow(23,3);\n   cout << \"\\nPotencia de 23^3: \" << potencia << endl;\n   cout << \"--------------------------------------------------------------\" << endl; \n\n   // Operadores de comparacion\n   cout << boolalpha; \n   cout << \"Igualdad: 15 == 5 es \" << (15 == 5) << endl;\n   cout << \"Desigualdad: 16 != 4*4 es \" << (16 != 4*4) << endl;\n   cout << \"Desigualdad: 153 != 234 es \" << (153 != 234) << endl;\n   cout << \"Mayor: 15 > 6 es \" << (15 > 6) << endl;\n   cout << \"Mayor o igual: 15 >= 15 es \" << (15 >= 15) << endl;\n   cout << \"Menor o igual: 15 <= 17 es \" << (15 >= 17) << endl;\n   cout << \"--------------------------------------------------------------\" << endl;\n\n   // Operadores logicos\n   // Ejemplos de edad \n   cout << \"Que edad tienes?\"<< endl;\n   int edad;\n   cin >> edad;\n   if (edad >= 18 && edad < 50) {\n      cout << \"Tiene permiso de entrar al club.\" ;\n   } else {\n      cout << \"No tiene permiso de entrar :(\" << endl;\n   } \n   // Ejemplos simple\n   cout << \"Es verdadero decir que 16!=5? Rpta: \" << !(16!=5) << endl;\n   cout << \"Es verdadero decir que  30>14 o 32<33? Rpta: \" << (30>14 or 32<33) << endl;\n   cout << \"Es Falso decir que 13 > 8 y 15 < 16? Rpta: \" << !(13 > 8 and 15 < 16) << endl;\n   // Operadores de identidad\n   // cout << boolalpha; \n\n   int my_number = 10;\n   int &my_new_number = my_number; // creamos una referencia (mismo objeto)\n   int other_number = 10; /// Mismo valor pero otro objeto\n\n   // is es como comparar las dirreciones de memoria (&)\n   cout << \"my_number is my_new_number es \" << (&my_number == &my_new_number) << endl;\n   // is not es como comparar que las dirreciones sean distintas\n   cout << \"my_number is not other_number es \" << (&my_number != &other_number) << endl;\n\n   // Operadores de pertenencia\n   cout << boolalpha;\n   string palabra = \"massito\";\n   char letra = 'l';\n\n   if (palabra.find(letra) != string::npos){\n      cout << \"La letra \" << letra << \" SI pertenece a la palabra: \" << palabra << endl;\n   } else {\n      cout << \"La letra \" << letra << \" NO pertenece a la palabra: \" << palabra << endl;\n   }\n   // Operadores de bit\n   \n   int x = 11; // 1011\n   int y = 2; // 0010\n\n   cout << \"AND (11 & 2): \" << (x & y) << endl; // 0010 = 2\n   cout << \"OR (11 | 2): \" << (x | y) << endl; //  1011 = 11\n   cout << \"XOR (11 ^ 2): \" << (x ^ y) << endl; // 1001 = 9\n   cout << \"NOT (11): \" << (~x) << endl; \n   cout << \"Desplazamiento a la derecha: 11 >> 2 es \" << (x >> 2) << endl; // 0010 = 2 \n\n   // ___Estructura de control___\n\n   // Condicionales\n\n   string my_name = \"Massito\" ; // Definimos variable\n   if (my_name == \"massi\") {\n      cout << \"my_name es 'massi'\" << endl;\n   }else if (my_name == \"Massito\") {\n      cout << \"my_name es 'Massito'\" << endl;\n   } else {\n      cout << \"No es ni 'massi' ni 'Massito'\" << endl;\n   }\n\n   // Iterativas\n   \n   for(int i=0 ; i<15; i++) {\n      cout << i << endl;\n   }\n\n   int i = 0;\n   while(i <= 9) {\n      cout << i << endl;\n      i++;\n\n   } \n\n   // Manejo de excepciones\n   int numerador = 10;\n   int denominador = 0;\n   \n   try {\n      if (denominador == 0){\n         throw runtime_error(\"Error, no se puede dividir entre 0\");\n\n      }\n      int resultado = numerador / denominador;\n      cout << \"Resultado: \" << resultado << endl;\n   }\n   catch (const runtime_error& e) {\n      cout << \"Se produjo una excepcion: \" << e.what() << endl; //capturamos el error y mostramos el mensaje\n   } catch(...) {\n      cout << \"Ocurrio un error desconocido.\" << endl; // bloque opcional para cualquier tipo de error\n   }\n\n   // Ejercicio adicional!!!\n\n   cout << \"El programa sigue ejecutandose...\" << endl; \n\n   for(int i = 10; i <=55; i++){\n      if (i % 2 != 0) {\n         continue; \n      }\n      if (i == 16) {\n         continue;\n      }\n      if (i % 3 == 0) {\n         continue;\n      }\n      cout << i << endl;\n\n   }\n\n   return 0;\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c++/MaviGareli.cpp",
    "content": "#include <iostream>\r\n\r\nusing namespace std;\r\n\r\nint main()\r\n{\r\n    //Tipos de operadores en C++\r\n    \r\n    //Aritmeticos\r\n    \r\n    float num1 = 10;\r\n    float num2 = 3;\r\n    float res = 0;\r\n    bool resBool = false;\r\n\r\n        //Suma\r\n        res = num1 + num2;\r\n        cout << \"Suma: \" << res << endl;\r\n\r\n        //Resta\r\n        res = num1 - num2;\r\n        cout << \"Resta:\" << res << endl;\r\n\r\n        //Multiplicacion\r\n        res = num1 * num2;\r\n        cout << \"Multiplicacion:\" << res << endl;\r\n\r\n        //Division\r\n        res = num1 / num2;\r\n        cout << \"Division:\" << res << endl;\r\n\r\n        //Modulo\r\n        res = (int)num1 % (int)num2;\r\n        cout << \"Modulo:\" << res << endl;\r\n\r\n        //Incremento\r\n        res = num1++;\r\n        cout << \"Incremento:\" << res << endl;\r\n\r\n        //Decremento\r\n        res = num1--;\r\n        cout << \"Decremento:\" << res << endl;\r\n\r\n    //Logicos\r\n\r\n        //AND\r\n        resBool = (num1 > num2) && (num1 < num2);\r\n        cout << \"AND:\" << resBool << endl;\r\n\r\n        //OR\r\n        resBool = (num1 > num2) || (num1 < num2);\r\n        cout << \"OR:\" << resBool << endl;\r\n\r\n        //NOT\r\n        resBool = !(num1 > num2);\r\n        cout << \"NOT:\" << resBool << endl;\r\n\r\n    //Comparacion\r\n        resBool = num1 == num2;\r\n        cout << \"Comparacion:\" << resBool << endl;\r\n\r\n        resBool = num1 != num2;\r\n        cout << \"Comparacion:\" << resBool << endl;\r\n\r\n        resBool = num1 > num2;\r\n        cout << \"Comparacion:\" << resBool << endl;\r\n\r\n        resBool = num1 < num2;\r\n        cout << \"Comparacion:\" << resBool << endl;\r\n\r\n        resBool = num1 >= num2;\r\n        cout << \"Comparacion:\" << resBool << endl;\r\n\r\n        resBool = num1 <= num2;\r\n        cout << \"Comparacion:\" << resBool << endl;\r\n\r\n    //Asignacion\r\n\r\n        num1 = num2;\r\n        cout << \"Asignacion:\" << num1 << endl;\r\n\r\n        num1 += num2;\r\n        cout << \"Asignacion:\" << num1 << endl;\r\n\r\n        num1 -= num2;\r\n        cout << \"Asignacion:\" << num1 << endl;\r\n        \r\n        num1 *= num2;\r\n        cout << \"Asignacion:\" << num1 << endl;\r\n\r\n        num1 /= num2;\r\n        cout << \"Asignacion:\" << num1 << endl;\r\n\r\n        //Con %= se necesita que las variables sean enteros explicitamente, cast no funciona\r\n        //num1 %= num2;\r\n\r\n    //Bits\r\n        res = (int)num1 & (int)num2;\r\n        cout << \"Bitwise AND:\" << res << endl;\r\n\r\n        res = (int)num1 | (int)num2;\r\n        cout << \"Bitwise OR:\" << res << endl;\r\n\r\n        res = (int)num1 ^ (int)num2;\r\n        cout << \"Bitwise XOR:\" << res << endl;\r\n\r\n        res = (int)num1 << (int)num2;\r\n        cout << \"Bitwise Shift Left:\" << res << endl;\r\n\r\n        res = (int)num1 >> (int)num2;\r\n        cout << \"Bitwise Shift Right:\" << res << endl;\r\n\r\n        res = ~(int)num1;\r\n        cout << \"Bitwise NOT:\" << res << endl;\r\n    \r\n    //Identidad\r\n\r\n        /*Se usan para verificar la identidad de los punteros.\r\n        is ---> Para comprobar el tipo */\r\n\r\n    //Operador ternario\r\n\r\n    \r\n        int a = 10;\r\n        int b = 20;\r\n        int c = 0;\r\n\r\n        c = (a > b) ? a : b;\r\n        cout << \"Operador ternario:\" << c << endl;\r\n\r\n    //Operadores de punteros\r\n\r\n        int *ptr = &a;\r\n        cout << \"Valor del puntero:\" << *ptr << endl;\r\n        cout << \"Direccion de memoria del puntero:\" << ptr << endl;\r\n\r\n    //Operadores de miembro\r\n    \r\n        /*Se usan para acceder a los miembros de una clase o estructura.\r\n        . ---> Para acceder a los miembros de una clase o estructura\r\n        -> ---> Para acceder a los miembros de una clase o estructura a través de un puntero*/\r\n\r\n    //Estructuras de control\r\n\r\n    //If\r\n    if (a > b)\r\n    {\r\n        cout << \"a es mayor que b\" << endl;\r\n    }\r\n    else\r\n    {\r\n        cout << \"b es mayor que a\" << endl;\r\n    }\r\n\r\n    //Switch\r\n    int numero = 0;\r\n    switch (numero)\r\n    {\r\n    case 0:\r\n        cout << \"Cero\" << endl;\r\n        break;\r\n    case 1:\r\n        cout << \"Uno\" << endl;\r\n        break;\r\n    \r\n    default:\r\n        cout << \"Numero no reconocido\" << endl;\r\n        break;\r\n    }\r\n\r\n    //For\r\n    for (int i = 0; i < 2; i++)\r\n    {\r\n        cout << i << endl;\r\n    }\r\n\r\n    //While\r\n    bool i = false;\r\n    while (i)   //Mientras i sea verdadero\r\n    {\r\n        //Do something\r\n    }\r\n\r\n    //Do-While\r\n    do\r\n    {\r\n        //Do something\r\n    } while (i);   //Mientras i sea verdadero\r\n\r\n\r\n/*Crea un programa que imprima por consola todos los números comprendidos\r\n entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3*/\r\n\r\n   for (int i = 10; i <= 55; i++)\r\n   {\r\n    if (i == 16 || i % 3 == 0)\r\n    {\r\n        continue;\r\n    }\r\n    else\r\n    {\r\n         cout << i << endl;\r\n    }\r\n   } \r\n\r\n    return 0;   //0 indica que el programa se ejecuto correctamente\r\n\r\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c++/Porto1090.cpp",
    "content": "#include <iostream>\nusing namespace std;\n\nint main()\n{\n    /*\n        OPERADORES EN C++\n    */\n\n    //== Operadores aritméticos en C++\n    cout << \"Suma: 22 + 13 = \" << 22 + 13 << endl;\n    cout << \"Resta: 22 - 13 = \" << 22 - 13 << endl;\n    cout << \"Multiplicación: 22 * 13 = \" << 22 * 13 << endl;\n    cout << \"División: 22 / 13 = \" << 22 / 13 << endl;\n    cout << \"Módulo: 22 % 13 = \" << 22 % 13 << endl;\n    // NOTE: Operadores de incremento y decremento exiten en C++ y tienen formato ++n, n++, --n, n-- respectivamente;\n\n    //== Operadores de comparación en C++\n    cout << \"Igualdad: 22 == 13 es \" << (22 == 13) << endl;\n    cout << \"Desigualdad: 22 != 13 es \" << (22 != 13) << endl;\n    cout << \"Mayor que: 22 > 13 es \" << (22 > 13) << endl;\n    cout << \"Menor que: 22 < 13 es \" << (22 < 13) << endl;\n    cout << \"Mayor o igual que: 22 >= 13 es \" << (22 >= 13) << endl;\n    cout << \"Menor o igual que: 22 <= 13 es \" << (22 <= 13) << endl;\n\n    //== Operadores lógicos en C++\n    cout << \"AND (&&): 22 + 3 == 25 && 22 - 3 == 19 es \"\n    << ([]() { return (22 + 3 == 25 && 22 - 3 == 19); }() ? \"Verdadero\" : \"Falso\") << endl;\n    cout << \"OR (||): 22 + 3 == 25 || 22 - 3 == 19 es \" \n    << ([]() { return (22 + 3 == 25 || 22 - 3 == 19); }() ? \"Verdadero\" : \"Falso\") << endl;\n    cout << \"NOT (!): !(22 + 3 == 25) es \" \n    << ([]() { return !(22 + 3 == 25); }() ? \"Verdadero\" : \"Falso\") << endl;\n\n    //== Operadores de asignación en C++\n    int number= 42;\n    cout << \"Asignación: number = \" << number << endl;\n    number += 1;\n    cout << \"Suma y asignación: number += 1 \" << '(' << number << ')' << endl;\n    number -= 3;\n    cout << \"Resta y asignación: number -= 3 \" << '(' << number << ')' << endl;\n    number *= 3;\n    cout << \"Multiplicación y asignación: number *= 3 \" << '(' << number << ')' << endl;\n    number /= 3;\n    cout << \"División y asignación: number /= 3 \" << '(' << number << ')' << endl;\n    number %= 3;\n    cout << \"Módulo y asignación: number %= 3 \" << '(' << number << ')' << endl;\n\n    //Funciones integradas en C++\n    cout << \"El valor absoluto de -13 es \" << abs(-13) << endl;\n    cout << \"El valor máximo entre 13 y 42 es \" << max(13, 42) << endl;\n    cout << \"El valor mínimo entre 13 y 42 es \" << min(13, 42) << endl;\n\n    //Otros operadores en C++\n    cout << \"El tamaño de un int en bytes es \" << sizeof(int) << endl;\n    cout << \"El tamaño de un char en bytes es \" << sizeof(char) << endl;\n    cout << \"El tamaño de un float en bytes es \" << sizeof(float) << endl;\n    cout << \"El tamaño de un double en bytes es \" << sizeof(double) << endl;\n\n    //Operadores de bits en C++\n    cout << \"Desplazamiento de bits a la izquierda: 1 << 3 = \" << (1 << 3) << endl;\n    cout << \"Desplazamiento de bits a la derecha: 8 >> 2 = \" << (8 >> 2) << endl;\n    cout << \"AND a nivel de bits: 5 & 3 = \" << (5 & 3) << endl;\n    cout << \"OR a nivel de bits: 5 | 3 = \" << (5 | 3) << endl;\n    cout << \"XOR a nivel de bits: 5 ^ 3 = \" << (5 ^ 3) << endl;\n    cout << \"NOT a nivel de bits: ~5 = \" << (~5) << endl;\n\n    /*\n        ESTRUCTURAS DE CONTROL EN C++\n    */\n\n    //== Estructura condicional if en C++\n    int age = 18;\n    if (age >= 18) {\n        cout << \"Eres mayor de edad\" << endl;\n    } else if (age >= 60){\n        cout << \"Eres un adulto mayor\" << endl;\n    } else {\n        cout << \"Eres menor de edad\" << endl;\n    }\n\n    //== Estructura condicional switch en C++\n    int day = 3;\n    switch (day) {\n        case 1:\n            cout << \"Lunes\" << endl;\n            break;\n        case 2:\n            cout << \"Martes\" << endl;\n            break;\n        case 3:\n            cout << \"Miércoles\" << endl;\n            break;\n        case 4:\n            cout << \"Jueves\" << endl;\n            break;\n        case 5:\n            cout << \"Viernes\" << endl;\n            break;\n        case 6:\n            cout << \"Sábado\" << endl;\n            break;\n        case 7:\n            cout << \"Domingo\" << endl;\n            break;\n        default:\n            cout << \"Día no válido\" << endl;\n            break;\n    }\n\n    //== Estructura de repetición for en C++\n    for (int i = 0; i < 5; i++) {\n        cout << \"Iteración (for) \" << i << endl;\n    }\n\n    //== Estructura de repetición while en C++\n    int i = 0;\n    while (i < 5) {\n        cout << \"Iteración (while) \" << i << endl;\n        i++;\n    }\n\n    //== Estructura de repetición do-while en C++\n    int j = 0;\n    do {\n        cout << \"Iteración (do-while) \" << j << endl;\n        j++;\n    } while (j < 5);\n\n    //== Manejo de excepciones en C++\n    // haz un try de 10/0 y si hay except se ejecuta el catch imprimiendo error\n    try {\n        int result = 10 / 0;\n    } catch (const exception& e) {\n        cout << \"Error: \" << e.what() << endl;\n    }\n    \n    /*\n        DIFICULTAD EXTRA\n    */\n\n    //== Ejercicio extra\n    cout << \"Ejercicio extra: La lista de números es \";\n    for (int i = 10; i <= 55; i++) {\n        if (i % 2 == 0 && i % 3 != 0 && i != 16) {\n            cout << i << \" \";\n        }\n    }\n    cout << endl;\n\n    return 0;\n}   "
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c++/RoniPG.cpp",
    "content": "// @RoniPG\n\n#include <iostream>\n//#include <sstream>\n\nusing namespace std;\n\nint main() {\n\n\tcout << \"Tipo de operadores.\" << endl;\n\n\tcout << \"Operadores Aritmeticos.\" << endl;\n\n\tcout\n\t\t\t<< \"Suma +, Resta -, Division /, Multiplicacion *, Resto % (En la division inexacta = lo que sobra)\"\n\t\t\t<< endl;\n\n\tcout << \"Ejemplos\" << endl;\n\n\tint a = 2;\n\tint b = 3;\n\n\tint suma = a + b;\n\tcout << a << \" - \" << b << \" = \" << suma << endl;\n\n\tint resta = a - b;\n\tcout << a << \" - \" << b << \" = \" << resta << endl;\n\n\tint division = a / b;\n\tcout << a << \" / \" << b << \" = \" << division << endl;\n\n\tint multiplicacion = a * b;\n\tcout << a << \" * \" << b << \" = \" << multiplicacion << endl;\n\n\tint resto = a % b;\n\tcout << a << \" % \" << b << \" = \" << resto << endl;\n\n\tcout << \"Operadores de Asignacion.\" << endl;\n\n\tcout << \" = para asignar el valor sobrescirbiendolo\" << endl;\n\tcout << \"+= sumar a la variable el valor dedicidido\" << endl;\n\tcout << \"-= restar a la variable el valor dedicidido\" << endl;\n\tcout << \"*= mutilpicar a la variable el valor dedicidido\" << endl;\n\tcout << \"/= dividir a la variable el valor dedicidido\" << endl;\n\n\tcout << \"Ejemplos\" << endl;\n\n\tcout << a << endl;\n\tcout << a << \" += 2 \" << endl;\n\ta += 2;\n\tcout << a << endl;\n\tcout << a << \" -= 2 \" << endl;\n\ta -= 2;\n\tcout << a << endl;\n\tcout << a << \" *= 2 \" << endl;\n\ta *= 2;\n\tcout << a << endl;\n\tcout << a << \" /= 2 \" << endl;\n\ta /= 2;\n\tcout << a << endl;\n\n\tcout << \"Operadores de comparacion\" << endl;\n\n\tcout << \"== igual a (para objetos equals(), != difente de, < menor que,\"\n\t\t\t<< endl;\n\n\tcout << \"<= menor o igual que, >= mayor o igual que, > mayor que.\" << endl;\n\n\tcout << \"Todos estos valores devuelven un booleano true o false\" << endl;\n\n\tcout << \"Ejemplos\" << endl;\n\n\tbool comparacion;\n\n\tcout << std::boolalpha;\n\tcout << a << \" | \" << b << endl;\n\tcomparacion = a == b;\n\tcout << a << \" es igual a \" << b << \": \" << comparacion << endl;\n\tcomparacion = a != b;\n\tcout << a << \" no es igual a \" << b << \": \" << comparacion << endl;\n\tcomparacion = a < b;\n\tcout << a << \" es menor que \" << b << \": \" << comparacion << endl;\n\tcomparacion = a <= b;\n\tcout << a << \" es menor o igual que \" << b << \": \" << comparacion << endl;\n\tcomparacion = a >= b;\n\tcout << a << \" es mayor o igual que \" << b << \": \" << comparacion << endl;\n\tcomparacion = a > b;\n\tcout << a << \" es mayor que \" << b << \": \" << comparacion << endl;\n\n\tcout << \"Operadores logicos.\" << endl;\n\n\tcout << \"|| operador OR (devuelve true si una de las variables se cumple)\"\n\t\t\t<< endl;\n\tcout << \"&& operador AND (devuelve true si todas las variables se cumplen)\"\n\t\t\t<< endl;\n\tcout\n\t\t\t<< \"! operador NOT (invierte el valor de la condicion, de true a false y viceversa)\"\n\t\t\t<< endl;\n\n\tcout << \"Ejemplos\" << endl;\n\n\tbool logico = true;\n\tcomparacion = false;\n\n\tcout << \"Operador OR: \" << comparacion << \" || \" << logico << endl;\n\tif (comparacion || logico) {\n\t\tcout << logico << endl;\n\t} else {\n\t\tcout << comparacion << endl;\n\t}\n\tcout << \"Operador AND: \" << comparacion << \" && \" << logico << endl;\n\tif (comparacion && logico) {\n\t\tcout << logico << endl;\n\t} else {\n\t\tcout << comparacion << endl;\n\t}\n\tcout << \"Operador NOT: !\" << comparacion << endl;\n\tif (!comparacion) {\n\t\tcout << logico << endl;\n\t} else {\n\t\tcout << comparacion << endl;\n\t}\n\n\tcout <<\"Operadores de incremento y decremento.\" << endl;\n\n\tcout <<\"++ Incrementa en uno la variable.\" << endl;\n\tcout <<\"-- Incrementa en uno la variable.\" << endl;\n\n\tcout <<\"Ejemplos\" << endl;\n\n\ta = 2;\n\tcout <<a << endl;\n\tcout <<\" ++ \" << a << endl;\n\ta++;\n\tcout <<a << endl;\n\tcout <<\" -- \" << a << endl;\n\ta--;\n\tcout <<a << endl;\n\n\tcout << \"Operadores ternarios\" << endl;\n\n\tcout << \"Tienen la forma condicion ? valor_si_verdadero : valor_si_falso.\"\n\t\t\t<< endl;\n\n\tcout << \"Ejemplos\" << endl;\n\n\tbool ternario = false;\n\n\tternario = (comparacion || logico) ? logico : comparacion;\n\tcout << \"Operador OR en ternario: \" << comparacion << \" || \" << logico\n\t\t\t<< \" ternario = \" << ternario << endl;\n\tternario = (comparacion && logico) ? logico : comparacion;\n\tcout << \"Operador AND en ternario: \" << comparacion << \" && \" + logico\n\t\t\t<< \" ternario = \" << ternario << endl;\n\tternario = (!comparacion) ? logico : comparacion;\n\tcout << \"Operador NOT en ternario: !\" << comparacion << \" ternario = \"\n\t\t\t<< ternario << endl;\n\tcout << \"Operadores de concatenacion\" << endl;\n\n\tcout << \"+ Unir diferentes strings a uno solo.\" << endl;\n\n\tcout << \"Ejemplos\" << endl;\n\n\tstring texto1 = \"Hola, \";\n\tcout << texto1 << endl;\n\tstring texto2 = \"Java!\";\n\tcout << texto2 << endl;\n\tstring textoFinal = texto1 + texto2;\n\tcout << textoFinal << endl;\n\n\tcout << \"Operadores de conversion de tipo\" << endl;\n\n\tcout << \"Para covertir a numero se puede utlizar: stoi (texto_a_convertir) mediante la libreria <string>, \\n \"\n\t\t\t\" o tambien mediante la libreria <sstream> creando un objeto que realizara la conversion\" << endl;\n\n\tcout << \"Para covertir a texto se puede utlizar: to_string (texto_a_convertir) mediante la libreria <string>, \\n \"\n\t\t\t\" o tambien mediante la libreria <sstream> creando un objeto que realizara la conversion\" << endl;\n\n\tcout << \"Para covertir a flotante se puede utlizar: stof (texto_a_convertir) mediante la libreria <string>, \\n \"\n\t\t\t\" o tambien mediante la libreria <sstream> creando un objeto que realizara la conversion\" << endl;\n\n\tcout << \"Ejemplos\" << endl;\n\n\ttexto1 = \"2\";\n\tcout << \"Dato en texto = \" << texto1 << endl;\n\t/*stringstream convert;\n\t convert << texto1;\n\t convert >> a;*/\n\ta = stoi(texto1);\n\tcout << \"Dato convertido a entero = \" << a << endl;\n\t/*stringstream convert;\n\t convert << a;\n\t convert >> texto1;*/\n\ttexto1 = to_string(a);\n\tcout << \"Dato convertido a texto = \" << texto1 << endl;\n\tfloat ft;\n\t/*stringstream convert;\n\t convert << texto1;\n\t convert >> ft;*/\n\tft = stof(texto1);\n\tcout << \"Dato convertido a flotante = \" << ft << endl;\n\n\tcout << \"Tipo de estucturas.\" << endl;\n\n\tcout << \"Estructura if\" << endl;\n\n\tcout << \"Se ejecuta el bolque si se cumple la condicion.\" << endl;\n\n\tcout << \"Ejemplos\" << endl;\n\n\ta = 2;\n\tb = 2;\n\n\tcout << \"Si \" << a << \" = \" << b << endl;\n\tif (a == b) {\n\t\tcout << \"Se ejecuta el bloque\" << endl;\n\t}\n\n\tcout << \"Estructura if-else\" << endl;\n\n\tcout <<\n\t\t\t\"Se ejecuta el bloque if si se cumple la condicion, si no se cumple se ejecuta el else.\" << endl;\n\n\tcout << \"Ejemplos\" << endl;\n\n\tcout << \"Si \" << a << \" < (menor que) \" << b << endl;\n\tif (a < b) {\n\t\tcout << \"Se ejecuta el bloque if\" << endl;\n\t} else {\n\t\tcout << \"Se ejecuta el bloque else\" << endl;\n\t}\n\n\tcout << \"Estructura if else-if else\" << endl;\n\n\tcout << \"Se ejecuta el bloque if si se cumple la condicion.\" << endl;\n\tcout <<\n\t\t\t\"Si no se cumple se ejecuta la siguiente condicion else if(asi sucesivamente).\" << endl;\n\tcout << \"Si no se cumple niguna condicion se ejecuta el else.\" << endl;\n\n\tcout << \"Ejemplos\" << endl;\n\n\tcout <<\n\t\t\t\"if \" << a << \" < (menor que) \" << b << \"\\n\"\n\t\t\t\"else if \" << a << \" = (igula a) \" << b << endl;\n\tif (a < b) {\n\t\tcout << \"Se ejecuta el bloque if\" << endl;\n\t} else if (a == b) {\n\t\tcout << \"Se ejecuta el bloque else if\" << endl;\n\t} else {\n\t\tcout << \"Se ejecuta el bloque else\" << endl;\n\t}\n\n\tcout << \"Estructura switch\" << endl;\n\n\tcout <<\n\t\t\t\"Se pasa una variable para luego indicar los casos en los que se ejecutaria.\" << endl;\n\tcout <<\n\t\t\t\"Dentro de cada caso se añade 'break;'(opcional), para salir del switch despues de ejecutar el bloque de codigo.\" << endl;\n\tcout <<\n\t\t\t\"Tambien se puede añadir 'default:' para ejecutar el codigo si no se cumple ningun case.\" << endl;\n\n\tcout << \"Ejemplos\" << endl;\n\n\ta = 1;\n\tb = 2;\n\tint c = 3;\n\n\tcout <<\n\t\t\t\"Case 1 = \" << a << \",caso 2 = \" << b << \",caso 3 = \" << c\n\t\t\t\t\t<< \",si no = \" << endl;\n\tswitch (a) {\n\tcase 1:\n\t\tcout << \"Se ejecuta el primer caso\" << endl;\n\t\tbreak;\n\tcase 2:\n\t\tcout << \"Se ejecuta el segundo caso\" << endl;\n\t\tbreak;\n\tcase 3:\n\t\tcout << \"Se ejecuta el tecero caso\" << endl;\n\t\tbreak;\n\tdefault:\n\t\tcout << \"No se ejecuta ningun caso\" << endl;\n\t\tbreak;\n\t}\n\n\tcout << \"Estructura de bucles\" << endl;\n\n\tcout << \"Bucle for\" << endl;\n\n\tcout <<\n\t\t\t\"Se ejecuta un bloque de codigo mientras la condicion sea verdadera.\" << endl;\n\tcout <<\n\t\t\t\"Esto se controla mediante un iterador que se ira modificando por cada ejecucion del bucle.\" << endl;\n\n\tcout << \"Ejemplos\" << endl;\n\n\tfor (int i = 0; i < c; i++) {\n\t\tcout << i << endl;\n\t}\n\n\tcout << \"Bucle while\" << endl;\n\n\tcout <<\n\t\t\t\"Se ejecuta un bloque de codigo mientras la condicion sea verdadera.\" << endl;\n\tcout <<\n\t\t\t\"El bucle se ejecutara hasta que se modifique la condicion.\" << endl;\n\n\tcout << \"Ejemplos\" << endl;\n\n\tcout << \"Condicion: \" << a << \" distito de \" << c << endl;\n\n\twhile (a != c) {\n\t\tcout << \"La condicion es verdera\" << endl;\n\t\ta++;\n\t\tcout << a << endl;\n\t}\n\tcout << \"Bucle do-while\" << endl;\n\n\tcout <<\n\t\t\t\"Primero se ejecuta un bloque de codigo, luego se comprueba que la condicion sea verdadera.\" << endl;\n\tcout <<\n\t\t\t\"El bucle se ejecutara hasta que se modifique la condicion.\" << endl;\n\n\tcout << \"Ejemplos\" << endl;\n\n\ta = 0;\n\n\tdo {\n\t\tcout << \"Condicion: \" << a << \" distinto \" << c << endl;\n\t\tcout << \"La condicion es verdera\" << endl;\n\t\ta++;\n\t} while (a != c);\n\n\tcout << \"DIFICULTAD EXTRA (opcional):\" << endl;\n\tcout <<\n\t\t\t\"Crea un programa que imprima por consola todos los números comprendidos\" << endl;\n\tcout <<\n\t\t\t\"entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\" << endl;\n\n\tfor (int i = 10; i <= 55; i++) {\n\t\tif (i % 2 != 0) {\n\n\t\t} else if ((i == 16) || (i % 3 == 0)) {\n\n\t\t} else {\n\t\t\tcout << i << endl;\n\t\t}\n\t}\n\treturn 0;\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c++/VictorJaimesR.cpp",
    "content": "#include<iostream>\n\nusing namespace std;\n\nint main(){\n\n//Operadores aritméticos\nint suma=10+3; cout<<suma<<endl;\nint resta=10-3; cout<<resta<<endl;\nint multiplicacion=10*3; cout<<multiplicacion<<endl;\nint a=10;\nfloat b=3;\nfloat division = a/b; cout<<division<<endl;\nint residuo=10%3; cout<<residuo<<endl;\n\n//Operadores de comparación \n\nbool igualdad=10==10; cout<<\"Igualdad es: \"<< igualdad<<endl;\nbool diferencia=10!=3; cout<<\"Diferencia es: \"<< diferencia<<endl;\nbool mayorque=10>3; cout<<\"Mayor que es: \"<< mayorque<<endl;\nbool menorque=10<3; cout<<\"Menor que es: \"<< menorque<<endl;\nbool mayor_o_igual_que=10>=3; cout<<\"Mayor o igual que es: \"<< mayor_o_igual_que<<endl;\nbool menor_o_igual_que=10<=3; cout<<\"Menor o igual que es: \"<< menor_o_igual_que<<endl;\n\n//Operadores Lógicos\n\nbool y= 10 >= 3 && 3<=10; cout<<\"y es: \"<<y<<endl;\nbool o= 10 >= 3 || 3<=10; cout<<\"o es: \"<<o<<endl;\nbool no= !(10 >= 3 && 3<=10); cout<<\"no es: \"<<no<<endl;\n\n//Operadores de asignación\n\nint numero=15;\nnumero+=2;cout<<numero<<endl;\nnumero-=2;cout<<numero<<endl;\nnumero*=2;cout<<numero<<endl;\nnumero/=2;cout<<numero<<endl;\nnumero%=2;cout<<numero<<endl;\n\n\n//Operadores de bits\nnumero<<=2;cout<<numero<<endl;\nnumero>>=2;cout<<numero<<endl;\nint x=5;\nint k=3;\nint z= x & k;cout<<\"El numero es: \"<<z<<endl;\nint m=x|k;cout<<\"El numero es: \"<<m<<endl;\nint p=~x;cout<<\"El numero es: \"<<p<<endl;\n \n//Operadores de identidad no existen en c++\n//Operadores de pertenencia no existen en c++\n\n//estructuras de control\n\n//condicionales\n\nstring nombre=\"victor\";\n\nif (nombre==\"victor\"){\n    cout<<\"Mi nombre es: \"<<nombre<<endl;\n}\nelse if (nombre==\"Andres\")\n{\n    cout<<\"Mi nombre es\"<<nombre;\n}\n\nelse{\n    cout<<\"Ese no es tu nombre\";\n}\n\nint opcion;\ncout<<\"Ingrese la opcion: \"; \ncin>>opcion;\n\nswitch (opcion)\n{\ncase 1:\n    cout<<\"Usted escogió la opcion 1\";\n    break;\ncase 2:\n    cout<<\"Usted escogió la opcion 2\";\n    break;\ncase 3:\n    cout<<\"Usted escogió la opcion 3\";\n    break;\ndefault:\n    cout<<\"Usted escogió una opcion incorrecta\";\n    break;\n}\n\ncout<<endl;\n//iterativas\n\nfor (int i = 0; i < 11; i++)\n{\n    cout<<i<<endl;\n}\n\nint j=0;\nwhile (j<=10)\n{\n    cout<<j<<endl;\n    j++;\n    \n}\n\n\ncout<<endl;\n\n//EJERCICIO DE DIFICULTAD EXTRA\nfor (int ks  = 10; ks <= 55; ks++)\n{\n    if((ks%2==0) && !(ks%3==0) && ks!=16)\n    cout<<\"[\"<<ks<<\"]\";\n}\n/*\ncout<<endl;\n\n\n\nfor (int ki = 10; ki <=55; ki++)\n{\n    if (!(ki%3==0) && ki!=16)\n    {\n       cout<<\"[\"<<ki<<\"]\";\n    }\n    \n}\n\n\n*/\n\n\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c++/Vid92.cpp",
    "content": "\n#include <iostream>\nusing namespace std;\n\nint main()\n{\n  //operadores aritmeticos(+,-,*,/,%)\n  cout<<endl<<\"------Operadores aritmeticos--------\"<<endl;\n  cout<<\"Suma: \"<<(12+5)<<endl;\n  cout<<\"Resta: \"<<(12-5)<<endl;\n  cout<<\"Multiplicación: \"<<(12*5)<<endl;\n  cout<<\"División: \"<<(12/5)<<endl;\n  cout<<\"Modulo: \"<<(12%5)<<endl;\n  \n  //Operadores comparación (==,!=,>,<,>=,<=)\n  cout<<endl<<\"------Operadores comparacion--------\"<<endl;\n  cout<<\"10 igual a 5: \"<<(10==5)<<endl;\n  cout<<\"5 diferente a 5: \"<<(5!=5)<<endl;\n  cout<<\"10 mayor a 5: \"<<(10>5)<<endl;\n  cout<<\"5 menor a 1: \"<<(5<1)<<endl;\n  cout<<\"8 mayor o igual a 5: \"<<(8>=5)<<endl;\n  cout<<\"8 menor o igual a 5: \"<<(8<=5)<<endl;\n  \n  //operadores asignacion (+=,-=,*=,/=,%=,>>=,<<=,&=,^=,|=)\n  int y = 10;\n  cout<<endl<<\"------Operadores asignacion--------\"<<endl;\n  cout<<\" (y+=2)=  \"<<(y+=2)<<endl;\n  cout<<\" (y-=5)=  \"<<(y-=5)<<endl;\n  cout<<\" (y*=3)=  \"<<(y*=3)<<endl;\n  cout<<\" (y/=3)=  \"<<(y/=3)<<endl;\n  cout<<\" (y%=4)=  \"<<(y%=4)<<endl;\n  cout<<\" (y>>=1)= \"<<(y>>=1)<<endl;\n  cout<<\" (y<<=2)= \"<<(y<<=2)<<endl;\n  cout<<\" (y&=1)=  \"<<(y&=1)<<endl;\n  cout<<\" (y^=3)=  \"<<(y^=3)<<endl;\n  cout<<\" (y|=4)=  \"<<(y|=4)<<endl;\n  \n  //logicos (!,&&,||)\n  cout<<endl<<\"------Operadores logicos--------\"<<endl;\n  cout<<\"!(5==5)= \"<<!(5==5)<<endl;\n  cout<<\"!(5<4)= \"<<!(5<4)<<endl;\n  cout<<\"!(5>4)= \"<<!(5>4)<<endl;\n  cout<<\"!true= \"<<!true<<endl;\n  cout<<\"!false= \"<<!false<<endl;\n  cout<<\"((5<4)&&(6==6))= \"<<((5<4)&&(6==6))<<endl;\n  cout<<\"((9>3)&&(6!=4))= \"<<((9>3)&&(6!=4))<<endl;\n  cout<<\"((1<6)&&(6>4))= \"<<((1<6)&&(6>4))<<endl;\n  cout<<\"((7>10)||(6!=8))= \"<<((7>10)||(6!=8))<<endl;\n  cout<<\"((3>5)||(5==1))= \"<<((3>5)||(5==1))<<endl;\n  cout<<\"((7<12)||(9>=2))= \"<<((7<12)||(9>=2))<<endl;\n  \n //operadores bit (&,|,^,~,<<,>>)\n  cout<<endl<<\"------Operadores bit--------\"<<endl;\n  cout<<\"AND (12&6)= \"<<(12&6)<<endl;\n  cout<<\"OR (12|6)= \"<<(12|6)<<endl;\n  cout<<\"XOR (12^6)= \"<<(12^6)<<endl;\n  cout<<\"NOT (~12)= \"<<(~12)<<endl;\n  cout<<\"SHL (12<<6)= \"<<(12<<6)<<endl;\n  cout<<\"SHR (12>>6)= \"<<(12>>6)<<endl;\n  \n  //operadores ternarios condicionales (?)\n  cout<<endl<<\"------Operadores ternarios condicionales--------\"<<endl;\n  cout<<\"7==5 ? 4:3= \"<<(7==5?4:3)<<endl;\n  cout<<\"7>=5 ? 4:3= \"<<(7>=5?4:3)<<endl;\n  cout<<\"7>7 ? 4:3= \"<<(7<5?4:3)<<endl;\n  cout<<\"7<=7 ? 4:3= \"<<(7<=7?4:3)<<endl;\n  cout<<\"7<7 ? 4:3= \"<<(7<5?4:3)<<endl;\n  cout<<\"a==b ? s:n= \"<<('a'=='b'?'s':'n')<<endl;\n  \n  //Estructuras de control: condicional\n  cout<<endl<<\"------if else--------\"<<endl;\n  int numero = 5;\n  if(numero%2==0)\n    cout<<\"El numero es par\"<<endl;\n  else if(numero%3!=0)\n    cout<<\"El numero es impar\"<<endl;\n  else\n    cout<<\"El numero no es par ni impar\"<<endl;\n \n    \n  //Estructuras de control: While\n  cout<<endl<<\"------While--------\"<<endl;\n  \n  int a = 0;\n  \n  while(a<5){\n    cout<<\"Valor de a: \"<<a<<endl;\n    a++;\n  }\n  \n  //Estructuras de control: Do-While\n  cout<<endl<<\"------Do-While--------\"<<endl;\n  int x = 0;\n  do{\n    cout<<\"Valor de x es: \"<<x<<endl;\n    x++;  \n  }while(x<5);\n  \n  //Estructuras de control: For\n  cout<<endl<<\"------For--------\"<<endl;\n  \n  for(int n=0;n<5;n++){\n    cout<<\"Valor de n es: \"<<n<<endl;\n  }\n  \n  //Estructuras de control: Switch\n  cout<<endl<<\"------Switch--------\"<<endl;\n  int dia = 5;\n  switch(dia){\n    case 1:\n    cout<<\"Dia 1 de la semana, Lunes\"<<endl;\n    break;\n    case 2:\n    cout<<\"Dia 2 de la semana, Martes\"<<endl;\n    break;\n    case 3:\n    cout<<\"Dia 3 de la semana, Miercoles\"<<endl;\n    break;\n    case 4:\n    cout<<\"Dia 4 de la semana, Jueves\"<<endl;\n    break;\n    case 5:\n    cout<<\"Dia 5 de la semana, Viernes\"<<endl;\n    break;\n    case 6:\n    cout<<\"Dia 6 de la semana, Sabado\"<<endl;\n    break;\n    case 7:\n    cout<<\"Dia 7 de la semana, Domingo\"<<endl;\n    break;\n    default:\n    cout<<\"No se encuentra\"<<endl;\n    break;\n  }\n  \n  //Estructuras de control: Excepcion\n  cout<<endl<<\"------Excepcion--------\"<<endl;\n  \n  try{\n    int edad = 10;\n    if (edad>=18)\n        cout<<\"Eres mayor de edad, tienes \"<<edad<<\" años\"<<endl;\n    else\n        throw edad;\n  }\n  catch (int num) {\n    cout<<\"Eres menor de edad, tienes \"<<num<<\" años\"<<endl;\n  }\n  \n  //Ejercicio extra\n  cout<<endl<<\"------Ejercicio Extra--------\"<<endl;\n  \n  for(int i=10;i<56;i++){\n    if((i%2==0)&&(i%3!=0)&&(i!=16))\n        cout<<i<<endl;\n  }\n  \n  return 0;\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c++/carZep09.cpp",
    "content": "#include <iostream>\n#include <ctime> \nusing namespace std; \n\nint main()\n{\n    // Operador de asignacion\n    int num_1 = 50, num_2 = 30; // operador , separa dos objetos del mismo tipo en la llamada al entero \n    int asig_1; \n    asig_1 = 30 + (num_2 = 4); \n    cout <<\"asig_1 = \" <<  asig_1 << '\\n';\n\n    cout << endl; \n     \n    // Operaciones aritmeticas\n    cout << \"Suma: \" << num_1 + num_2 << '\\n';\n    cout << \"Resta: \" << num_1 - num_2  << '\\n'; \n    cout << \"Multiplicacion: \" << num_1 * num_2 << '\\n'; \n    cout << \"Division: \" << num_1 / num_2 << '\\n';\n    cout << \"Módulo: \" << num_1 % num_2 << '\\n';\n\n    cout << endl; \n   // Operaciones de comparacion \n    \n   cout << \"Igual a: \" << (num_1 == num_2) << '\\n'; \n   cout << \"No es igual a: \" << (num_1 != num_2) << '\\n'; \n   cout << \"Mayor o igual a: \" << (num_1 >= num_2) << '\\n'; \n   cout << \"Mayor a: \" << (num_1 > num_2) << '\\n'; \n   cout << \"Menor o igual a: \" << (num_1 <= num_2) << '\\n'; \n   cout << \"Menor a: \" << (num_2 <  num_1) << '\\n'; \n\n    cout << endl;\n     \n    // Operador de logica \n    cout << \"Logica Y: \" << ((num_1 + 20) && (num_2 + 20)) << '\\n'; \n    cout << \"Logica O: \" <<  ((num_1 / 2) || (num_2 / 2)) << '\\n'; \n    cout << \"Logica NO: \" << (!(!num_1 * 1.5) && !(num_2) || !(!(!num_1 / 2))) << '\\n';\n\n    cout << endl; \n\n    // Asignación compuesta \n    cout << \"Numero 2 = Numero 2 + Numero 1: \" << (num_2 += num_1) << '\\n';\n    cout << \"Numero 2 = Numero 2 - Numero 1: \" << (num_2 -= num_1) << '\\n'; \n    cout << \"Numero 2 = Numero 2 * Numero 1: \" << (num_2 *= num_1) << '\\n';  \n    cout << \"Numero 2 = Numero 2 / Numero 1: \" << (num_2 /= num_1) << '\\n';\n    cout << \"Numero 2 = Numero 2 % Numero 1: \" << (num_2 %= num_1) << '\\n'; \n    cout << \"Numero 2 = Numero 2 >> Numero 1: \" << (num_2 >>= num_1) << '\\n';\n    cout << \"Numero 2 = Numero 2 << Numero 1: \" << (num_2 <<= num_1) << '\\n';\n    cout << \"Numero 2 = Numero 2 Y  Numero 1: \" << (num_2 &= num_1) << '\\n'; \n    cout << \"Numero 2 = Numero 2 XOR  Numero 1: \" << (num_2 ^= num_1) << '\\n';\n    cout << \"Numero 2 = Numero 2 O Numero 1: \" << (num_2 |= num_1) << '\\n';\n\n    cout << endl; \n\n    // Incremento y Decremento \n    cout << \"Incremento (prefijo): \" <<  (num_2 = ++num_1 + 3) << '\\n'; \n    cout << \"Incremento (postfijo: \" << (num_2 = num_1++ + 3) << '\\n'; \n    cout << \"Decremento (prefijo): \" << (num_1 = --num_2 + 5) << '\\n'; \n    cout << \"Decremento (postfijo): \" << (num_1 = num_2-- + 5) << '\\n';\n\n    cout << endl;\n\n    // Operadores de bits \n    cout << \"Desplazar 4 bits a la derecha: \"  << (num_1 >> 4) << '\\n';\n    cout << \"Desplazar 4 bits a la izquierda: \" << (num_1 << 4) << '\\n';  \n    cout << \"Bit Y: \" << (num_1 & (num_1 + 2)) << '\\n'; \n    cout << \"Bit XOR: \" << (num_1 ^ (num_1 + 2)) << '\\n'; \n    cout << \"Bit O: \" << (num_1 | (num_1 + 2)) << '\\n'; \n    cout << \"Bit NO: \" <<  (~(num_1 + 2)) << '\\n'; \n\n    cout << endl;\n\n    // Operador ternario condicional\n    cout << \"Operador ternario condicional: \" << (num_1 == num_1 * 4 / (2*2) ? \"si\" : \"no\") << '\\n';\n    cout << \"Operador ternario condicional 2: \" << (num_1 >= num_2 * 4.5 ? \"si\" : \"no\") << '\\n';\n\n    cout << endl;\n\n    // operador explicito de conversion de tipos\n    cout << \"Convertire numero 1 a una variable float: \"; \n    float flota = 3.42; \n    num_1 = (int) flota; \n    cout << flota << '\\n';\n\n    cout << endl;\n\n    // switch\n    srand(time(0)); \n    int opciones = (rand() % 3) + 1; \n    cout << \"Una comida elegida al azar: \";\n    switch (opciones)\n    {\n        case 1: \n            cout << \"Pancakes!\" << '\\n'; \n            break;\n        case 2: \n            cout << \"Huevos y tocino!\" << '\\n'; \n            break; \n        case 3: \n            cout << \"Cereal!\" << '\\n'; \n            break; \n    \n        default:\n            cout << \"No elegiste nada :( !)\" << '\\n'; \n            break;\n    }\n    cout << endl;\n\n    // buqle\n    for (int i = 0; i < 5; i++)\n    {\n        cout << \"Se imprimara numeros en intervalos de 10: \" << i * 10 << endl; \n    }\n    cout << endl;\n\n    // condicionales\n    int x = 5, y = 20;\n\n    if (x + 3 == 20){\n        cout << \"¡Funciono!\" << '\\n';  \n    } \n    else if (x + 15 == y){\n        cout << \"¡No! ¡esta funcion es la correcta!\" << '\\n'; \n    }\n    else {\n        cout << \"por si salen mal las cosas\" << '\\n'; \n    }\n\n    cout << endl;\n\n    // Dificulta extra: \n\n    for (int i = 10; i < 55; i++)\n    {\n        if((i % 2 == 0) && (i != 16) && (i % 3 != 0)){ \n            cout << i << \" \"; \n        }\n        \n    }\n\n    return 0;  \n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c++/carlosguariglia.cpp",
    "content": "/* # #01 OPERADORES Y ESTRUCTURAS DE CONTROL\n> #### Dificultad: Fácil | Publicación: 02/01/24 | Corrección: 08/01/24\n\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n/* # #01 OPERADORES Y ESTRUCTURAS DE CONTROL\n> #### Dificultad: Fácil | Publicación: 02/01/24 | Corrección: 08/01/24\n\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje: Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n   */\n// generado por Chatgpt\n\n\n#include <iostream>\nusing namespace std;\n\nint main() {\n    // Operadores aritméticos\n    int a = 10;\n    int b = 3;\n    cout << \"Operadores aritméticos:\" << endl;\n    cout << \"Suma: \" << a + b << endl;\n    cout << \"Resta: \" << a - b << endl;\n    cout << \"Multiplicación: \" << a * b << endl;\n    cout << \"División: \" << a / b << endl;\n    cout << \"Módulo: \" << a % b << endl;\n\n    // Operadores lógicos\n    bool x = true;\n    bool y = false;\n    cout << \"\\nOperadores lógicos:\" << endl;\n    cout << \"AND: \" << (x && y) << endl;\n    cout << \"OR: \" << (x || y) << endl;\n    cout << \"NOT: \" << !x << endl;\n\n    // Operadores de comparación\n    cout << \"\\nOperadores de comparación:\" << endl;\n    cout << \"a == b: \" << (a == b) << endl;\n    cout << \"a != b: \" << (a != b) << endl;\n    cout << \"a > b: \" << (a > b) << endl;\n    cout << \"a < b: \" << (a < b) << endl;\n    cout << \"a >= b: \" << (a >= b) << endl;\n    cout << \"a <= b: \" << (a <= b) << endl;\n\n    // Operadores de asignación\n    cout << \"\\nOperadores de asignación:\" << endl;\n    int c = 5;\n    cout << \"c = 5: \" << c << endl;\n    c += 3; // c = c + 3\n    cout << \"c += 3: \" << c << endl;\n    c *= 2; // c = c * 2\n    cout << \"c *= 2: \" << c << endl;\n    c -= 4; // c = c - 4\n    cout << \"c -= 4: \" << c << endl;\n\n    // Operadores de bits\n    cout << \"\\nOperadores de bits:\" << endl;\n    int d = 5;  // 0101 en binario\n    int e = 3;  // 0011 en binario\n    cout << \"AND binario (d & e): \" << (d & e) << endl;\n    cout << \"OR binario (d | e): \" << (d | e) << endl;\n    cout << \"XOR binario (d ^ e): \" << (d ^ e) << endl;\n    cout << \"Shift izquierdo (d << 1): \" << (d << 1) << endl;\n    cout << \"Shift derecho (d >> 1): \" << (d >> 1) << endl;\n\n    // Estructuras de control\n    // Condicionales\n    cout << \"\\nEstructuras de control - Condicionales:\" << endl;\n    if (a > b) {\n        cout << \"a es mayor que b\" << endl;\n    } else {\n        cout << \"a no es mayor que b\" << endl;\n    }\n\n    // Bucle for\n    cout << \"\\nEstructuras de control - Bucle for:\" << endl;\n    for (int i = 0; i < 5; i++) {\n        cout << \"i: \" << i << endl;\n    }\n\n    // Bucle while\n    cout << \"\\nEstructuras de control - Bucle while:\" << endl;\n    int count = 0;\n    while (count < 3) {\n        cout << \"count: \" << count << endl;\n        count++;\n    }\n\n    // Bucle do-while\n    cout << \"\\nEstructuras de control - Bucle do-while:\" << endl;\n    int num = 5;\n    do {\n        cout << \"num: \" << num << endl;\n        num--;\n    } while (num > 0);\n\n    // DIFICULTAD EXTRA: imprimir los números pares entre 10 y 55 que no sean 16 ni múltiplos de 3\n    cout << \"\\nDificultad extra: Números pares entre 10 y 55, excluyendo 16 y múltiplos de 3\" << endl;\n    for (int i = 10; i <= 55; i++) {\n        if (i % 2 == 0 && i != 16 && i % 3 != 0) {       \n            cout << i << \" \";\n        }\n    }\n    cout << endl;\n\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c++/cesar-ch.cpp",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n#include <iostream>\nusing namespace std;\n\nint main()\n{\n    // Operadores aritméticos\n    int a = 10, b = 5;\n    int suma = a + b;\n    int resta = a - b;\n    int multiplicacion = a * b;\n    int division = a / b;\n    int modulo = a % b;\n\n    cout << \"Operadores aritméticos:\" << endl;\n    cout << \"Suma: \" << suma << endl;\n    cout << \"Resta: \" << resta << endl;\n    cout << \"Multiplicación: \" << multiplicacion << endl;\n    cout << \"División: \" << division << endl;\n    cout << \"Módulo: \" << modulo << endl;\n\n    // Operadores lógicos\n    bool x = true, y = false;\n    bool and_logico = x && y;\n    bool or_logico = x || y;\n    bool not_logico = !x;\n\n    cout << \"\\nOperadores lógicos:\" << endl;\n    cout << \"AND lógico: \" << and_logico << endl;\n    cout << \"OR lógico: \" << or_logico << endl;\n    cout << \"NOT lógico: \" << not_logico << endl;\n\n    // Operadores de comparación\n    bool igualdad = (a == b);\n    bool desigualdad = (a != b);\n    bool mayor_que = (a > b);\n    bool menor_que = (a < b);\n    bool mayor_igual = (a >= b);\n    bool menor_igual = (a <= b);\n\n    cout << \"\\nOperadores de comparación:\" << endl;\n    cout << \"Igualdad: \" << igualdad << endl;\n    cout << \"Desigualdad: \" << desigualdad << endl;\n    cout << \"Mayor que: \" << mayor_que << endl;\n    cout << \"Menor que: \" << menor_que << endl;\n    cout << \"Mayor o igual: \" << mayor_igual << endl;\n    cout << \"Menor o igual: \" << menor_igual << endl;\n\n    // Operadores de asignación\n    int c = 10;\n    c += 5;\n    cout << \"\\nOperador de asignación:\" << endl;\n    cout << \"Valor de c después de c += 5: \" << c << endl;\n    c -= 5;\n    cout << \"Valor de d después de c -= 5: \" << c << endl;\n    c *= 5;\n    cout << \"Valor de c después de c *= 5: \" << c << endl;\n    c /= 5;\n    cout << \"Valor de c después de c /= 5: \" << c << endl;\n    c %= 5;\n    cout << \"Valor de c después de c %= 5: \" << c << endl;\n\n    // Operadores a nivel de bits\n    cout << \"\\nOperadores a nivel de Bits: \\n\";\n    cout << \"a & b = \" << (a & b) << endl; // AND a nivel de bits\n    cout << \"a | b = \" << (a | b) << endl; // OR a nivel de bits\n    cout << \"a ^ b = \" << (a ^ b) << endl; // XOR a nivel de bits\n\n    // Estructuras de control (Condicionales)\n    cout << \"\\nEstructura de Control - Condicional: \\n\";\n    if (a > b)\n    {\n        cout << \"a es mayor que b\\n\";\n    }\n    else\n    {\n        cout << \"a no es mayor que b\\n\";\n    }\n\n    // Estructuras de control (Iterativas)\n    cout << \"\\nEstructura de Control - Bucle For: \\n\";\n    for (int i = 0; i < 5; i++)\n    {\n        cout << \"i = \" << i << endl;\n    }\n\n    // Manejo de excepciones\n    cout << \"\\nEstructura de Control - Manejo de Excepciones: \\n\";\n    try\n    {\n        if (b == 0)\n            throw \"Error: División por cero\";\n        cout << \"a / b = \" << a / b << endl;\n    }\n    catch (const char *msg)\n    {\n        cout << msg << endl;\n    }\n\n    // DIFICULTAD EXTRA\n    cout << \"\\nDificultad Extra:\\n\";\n    for (int i = 10; i <= 55; i++)\n    {\n        if (i % 2 == 0 && i != 16 && i % 3 != 0)\n        {\n            cout << i << \" \";\n        }\n    }\n    cout << endl;\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c++/davidvela-306.cpp",
    "content": "#include <iostream>\n#include <string>\n/*\n * TYPES OF OPERATORS \n * */\n\nint main(){\n\nint n1=2, n2 = 2;\nint res = n1 + n2;\n\n// Arithmetics\nstd::cout<< \"SUM: \" << n1+n2 <<std::endl;\nstd::cout<< \"SUBSTACT: \" << n1-n2 <<std::endl;\nstd::cout<< \"MULTIPLICATION: \" << n1*n2 <<std::endl;\nstd::cout<< \"DIVISION: \" << n1/n2 <<std::endl;\nstd::cout<< \"MODULE: \" << n1%n2 <<std::endl;\n\n// Assignment:\n\n\nstd::cout << \"n1: \" << n1 << \"n2: \" << n2 << std::endl;\nn1 += 1; // sum\nstd::cout << \"n1 +=1: \" << n1 << std::endl;\nn2 -= 1; // substract\nstd::cout << \"n2 -=1: \" << n2 << std::endl;\nn1 *= 2; //multiplication\nstd::cout << \"n1 *=2 : \" << n1 << std::endl;\nn1 /= 3; //multiplication\nstd::cout << \"n1 /=3: \" << n1 << std::endl;\nn1 %= 3; //multiplication\nstd::cout << \"n1%3: \" << n1<< std::endl;\n\n// Comparison - Is a boolean value (true or false)\n\n\n// std::cout << n1==n2 << std::endl; in this case << is left associative and has higher precedence than ==, 0 is equal false and 1 is equal true.\nstd::cout << (n1==n2) << std::endl;\nstd::cout << (n1!=n2) << std::endl;\nstd::cout << (n1>n2) << std::endl;\nstd::cout << (n1<n2) << std::endl;\nstd::cout << (n1>=n2) << std::endl;\nstd::cout << (n1<=n2) << std::endl;\n\n// Logics\nbool boolean = true;\n\nif(boolean == true && n1 == 0){\n\tstd::cout << \"AND\" << std::endl;\n}else{\n\n\tstd::cout << \"is not a statment AND\" << std::endl;\n}\n\n\nif(boolean == true || n1 == 0){\n\tstd::cout << \"OR\" << std::endl;\n}else{\n\n\tstd::cout << \"is not a statment OR\" << std::endl;\n}\n\nif(!boolean){\n\tstd::cout <<\"NOT - boolean is false\"<< std::endl;\n}else{\n\n\tstd::cout << \"NOT - boolean is true\" << std::endl;\n}\n// Increase - Decreace\n\nstd::cout << \"n1: \" << n1 << \"n2: \" << n2 << std::endl;\nn1++;\nstd::cout << n1<< std::endl;\nn1--;\nstd::cout << n1<< std::endl;\n\n//Bitwise bit to bit\n/*\n *These operators works with individual bits that make up the integers numbers. (0-1) \n * */\nunsigned int n =  2; // (0010)\nunsigned int t = 5; // (0101)\nstd::cout << \"n & t |\" << (n & t) << \"|  0010 & 0101 = 0000\" << std::endl; //AND STATMENT\n\nstd::cout << \"n | t |\" << (n | t) << \"|  0010 & 0101 = 0111 (7)\" << std::endl; // OR STATMENT\n\nunsigned int y = 7; // 0111\nstd::cout << \"n ^ t |\" << (n ^ y) << \"|  0010 ^ 0111 = 0101 (5)\" << std::endl; // XOR STATMENT\nstd::cout << \"~(n ^ t) |\" << (~(n ^ y)) << \"|  0010 ^ 0111 = 0101 => ~0101 => 1010 (10)\" << std::endl; // NOT STATMENT\n\nstd::cout << \"|\"<< (n<<2) << \"|  DISPLACEMENT 2 BITS: n=2 => n=0010 => 1000 (8)\"<< std::endl; // LEFT DISPLACEMENT\t\t\t\t\t\t\t\t\t\t\t\nstd::cout << \"|\"<< (y>>3) << \"|  DISPLACEMENT 3 BITS: y=7 => y=0111 => 0000 (0)\"<< std::endl; // RIGHT DISPLACEMENT\n\n\n/* SIZEOF : \n * Is an unitary operator that return the size in bytes of a variable or type of data**/\n    int miNumero;\n    double miDecimal;\n\n    std::cout << \"Tamano de int: \" << sizeof(int) << \" bytes\" << std::endl;\n    std::cout << \"Tamano de miNumero: \" << sizeof(miNumero) << \" bytes\" << std::endl;\n    std::cout << \"Tamano de double: \" << sizeof(double) << \" bytes\" << std::endl;\n    std::cout << \"Tamano de miDecimal: \" << sizeof(miDecimal) << \" bytes\" << std::endl;\n\n    /*\n     * Ternary operator:\n     * It is an abbreviated form of the if statement\n     * */\n\n    std::string msg;\n    int age = 8;\n\n    msg = (age >= 18)? \"Adult\": \"Underage\";\n    std::cout << \" You´re \" << msg << std::endl;\n\n\n    /*\n     * CONTROL STRUCTURES\n     * */\n\n// Conditionals\n// if statment\nbool vehicle=true;\n    if(vehicle){\n\t    std::cout <<\"It starts\"<<std::endl;\n}\n\nif(n%2==0){\n\n\t    std::cout <<\"The number is even\"<<std::endl;\n}else{\n\n\t    std::cout <<\"The number is odd\"<<std::endl;\n}\nstd::string trafficLight;\n\ntrafficLight = \"Yellow\";\n\nif(trafficLight == \"Green\"){\n\tstd::cout << \"You can go\"<<std::endl;\n}else if(trafficLight == \"Yellow\"){\n\tstd::cout << \"You coud wait\"<<std::endl;\n\n}else if(trafficLight ==\"Red\"){\n\tstd::cout << \"Stop\"<<std::endl;\n}else{\n\tstd::cout << \"Something is wrong\"<<std::endl;\n}\n\n// switch statment:\nint number_s = 3;\nswitch(number_s){\n\tcase 1:\n\tstd::cout << \"SWITCH: You can go\"<<std::endl;\n\tbreak;\n\tcase 2:\n\tstd::cout << \"SWITCH: You could wait\"<<std::endl;\n\tbreak;\n\tcase 3:\n\tstd::cout << \"SWITCH: Stop\"<<std::endl;\n\tbreak;\n\tdefault:\n\tstd::cout << \"Something is wrong\"<<std::endl;\n}\n\n// REPETITION STRUCTURES (BUCLES):\nint arr[10][2];\n// For statment\nint bn=1;\nfor (int i = 0 ; i<10 && i>=0;i++){\n\tfor (int j=0; j<2 && j>=0;j++){\n\tarr[i][j]=bn++;\n\t\t\t\n\tstd::cout <<\"| pos: x:\" << i << \"y:\" << j <<\"|  value: \"<< arr[i][j] << std::endl;\n\n\t}\n}\nstd::cout << arr << std::endl;\n//while statment\nstd::cout << \"WHILE\" << std::endl;\nbool sleap = true;\nint time = 0;\nwhile(sleap){\n\tstd::cout <<\"zzz\"<<std::endl;\nif(time == 7){\nsleap = false;\n}\ntime++;\n}\nstd::cout << \"Already up\" << std::endl;\n\nstd::cout << \"DO WHILE\" << std::endl;\nbool program = true;\ndo{\n\tstd::cout<< \"Continue learning\" <<std::endl;\n\tbreak;\n}while(program);\nstd::string days[7] = {\"Mon\", \"Tue\", \"Wed\", \"Thu\",\"Fri\", \"Sat\", \"Sun\"};\n\nfor (int i = 0; i<7;i++){\nif(days[i] == \"Sat\" || days[i] == \"Sun\"){\n\t// will not run this iterations\ncontinue;\n}\n\tstd::cout <<\"Today we work: \"<< days[i] << std::endl;\n}\n\n/*\n ** Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n * */\n// A number is even when the remainded in the division is 0\n// A number is multiple of 3 when this number divided by 3 the remainded is 0\n// no include the integer 16\n\n\n\tstd::cout << \"EXERCISE\" << std::endl;\nfor (int i = 10; i<56; i++){\n\n\tif((i%2==0)&&(i%3==0)&&(i!=16)){\n\tstd::cout << i << std::endl;\n}\n}\nreturn 0;\n\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c++/dotero-dciencia.cpp",
    "content": "#include<iostream>\n#include<string>\n\nusing namespace std;\n\nint main()\n{\n    // Todos los operadores\n    // Aritméticos\n    int a = 5 + 3;\n    int b = a - 5;\n    int c = a * b / 2;\n    c ++;\n    int d = c%a;\n    \n    // Comparación\n    bool c1 = a==b; // false\n    bool c2 = c!=d; // true\n    bool c3 = a>b; // true\n    bool c4 = b<c; // true\n    bool c4 = d>=4; // true\n    bool c5 = c<=8; // false\n    \n    // Asignación\n    string a1 = \"simple\";\n    int a2 = 3;\n    a2 += 4;\n    a2 -= 6;\n    a2 *= 3;\n    a2 /= 3;\n    a2 %= 2;\n    \n    // Bit a bit\n    string b1 = \"hola\";\n    string b2 = \"hola\";\n    bool b3 = b1&b2;\n    bool b4 = b1^b2;\n    \n    // Dificultad EXTRA\n    for (int i = 10; i <= 55; i += 2){\n        if (i%3 != 0 && i != 16){\n            cout << i << endl;\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c++/hectorio23.cpp",
    "content": "#include <iostream>\n#include <string>\n\n// Las siguinetes variables se ocuparan para imprimir en console la separacion de las distintas partes del codigo\n// y que las estructuras como los if, bucles y las excepcion sea visibles \nconst std::string separator = \"\\n##################RESULTADO DEL EJERCICIO BONUS##########################\\n\\n\";\nconst std::string separatorIf = \"\\n##################Estructura IF##########################\\n\\n\";\nconst std::string separatorSwitch = \"\\n##################Estructura Switch##########################\\n\\n\";\nconst std::string separatorFor = \"\\n##################Estructura FOR##########################\\n\\n\";\nconst std::string separatorWhile = \"\\n##################Estructura While##########################\\n\\n\";\nconst std::string separatorDoWhile = \"\\n##################Estructura DO While##########################\\n\\n\";\nconst std::string separatorTrowErrorHandle = \"\\n##################Estructura Manejadora de Errores##########################\\n\\n\";\n\n// Funcion que se llamara despues\nvoid imprimirNumeros(short , short, short, short);\n\n// Funcion principal\nint main() {\n    // Operadores aritméticos\n    short multiplicacion = 2 * 4; // Multiplicación 2 * 4 = 8\n    short division = 20 / 5; // División 20 / 5 = 4\n    short suma = 4 + 2; // Suma 4 + 2 = 6\n    short resta = 4 - 2; // Resta 4 - 2 = 2\n\n    // Operadores de bits\n    short desplazamientoBitsDerecha = 4 << 2; // Desplazamiento de bits hacia la derecha 4 << 2 = 16\n    short desplazamientoBitsIzquierda = 4 >> 2; // Desplazamiento de bits hacia la izquierda 4 >> 2 = 1\n    short orExclusivo = 4 ^ 2; // Operador XOR 4 ^ 2 = 6\n\n    // Operadores lógicos\n    bool operadorAnd = true && false; // AND true && false = false\n    bool operadorOR = true || false; // OR true || false = true\n    bool operadorNegacion = !true; // Negación !true = false\n\n    // Operadores de comparación\n    bool operadorIGUAL = 6 == 6; // Igualdad 6 == 6 = true\n    bool operadorDISTINTO = 6 != 9; // Desigualdad 6 != 9 = true\n    bool operadorMayorQUE = 6 > 9; // Mayor que 6 > 9 = false\n    bool operadorMayorIgualQUE = 6 >= 6; // Mayor o igual que 6 >= 6 = true\n    bool operadorMenorQUE = 6 < 9; // Menor que 6 < 9 = true\n    bool operadorMenorIgualQUE = 6 <= 6; // Menor o igual que 6 <= 6 = true\n\n    // Impresiones con comentarios\n    std::cout << \"Multiplicación 2 * 4 = \" << multiplicacion << '\\n';\n    std::cout << \"División 20 / 5 = \" << division << '\\n';\n    std::cout << \"Suma 4 + 2 = \" << suma << '\\n';\n    std::cout << \"Resta 4 - 2 = \" << resta << '\\n';\n    std::cout << \"Desplazamiento de bits hacia la Derecha 4 << 2 = \" << desplazamientoBitsDerecha << '\\n';\n    std::cout << \"Desplazamiento de bits hacia la Izquierda 4 >> 2 = \" << desplazamientoBitsIzquierda << '\\n';\n    std::cout << \"Operador AND true && false = \" << operadorAnd << '\\n';\n    std::cout << \"Operador OR true || false = \" << operadorOR << '\\n';\n    std::cout << \"Operador de igualdad 6 == 6 = \" << operadorIGUAL << '\\n';\n    std::cout << \"Operador de desigualdad 6 != 9 = \" << operadorDISTINTO << '\\n';\n    std::cout << \"Operador mayor que 6 > 9 = \" << operadorMayorQUE << '\\n';\n    std::cout << \"Operador mayor o igual que 6 >= 6 = \" << operadorMayorIgualQUE << '\\n';\n    std::cout << \"Operador menor que 6 < 9 = \" << operadorMenorQUE << '\\n';\n    std::cout << \"Operador menor o igual que 6 <= 6 = \" << operadorMenorIgualQUE << '\\n';\n    std::cout << \"Operador de negación !true = \" << operadorNegacion << '\\n';\n\n\n    /*************************************************************\n    **********Zona de Estructuras de Control**************\n    *************************************************************/\n    \n    \n    /**********CONDICIONAL IF**********/\n    std::cout << separatorIf;\n    \n    short numero = 10;\n    if (numero > 0) {\n        std::cout << \"Estructura IF (10 es mayor a 0) :El número es positivo.\" << '\\n';\n    } else if (numero < 0) {\n        std::cout << \"Estructura IF (10 es menor a 0):El número es negativo.\" << '\\n';\n    } else {\n        std::cout << \"Estructura IF (10 es igual a 0):El número es cero.\" << '\\n';\n    }\n\n    std::cout << separatorSwitch;\n    char operacion = '*';\n    int a = 5, b = 2, resultado;\n\n    /**********CONDICIONAL SWITCH**********/\n    switch (operacion) {\n        case '+':\n            resultado = a + b;\n            break;\n        case '-':\n            resultado = a - b;\n            break;\n        case '*':\n            resultado = a * b;\n            break;\n        case '/':\n            resultado = a / b;\n            break;\n        default:\n            std::cout << \"Operación no válida.\" << '\\n';\n            return 1;\n    }\n\n    std::cout << \"Estructura SWITCH: El resultado es: \" << resultado << '\\n';\n\n    /**********BUCLE FOR**********/\n    std::cout << separatorFor;\n    for (int i = 1; i <= 5; ++i) {\n        std::cout << \"Iteración (for) \" << i << '\\n';\n    }\n\n    /**********BUCLE WHILE**********/\n    std::cout << separatorWhile;\n    short contadorWhile = 1;\n    while (contadorWhile <= 5) {\n        std::cout << \"Iteración (while) \" << contadorWhile << '\\n';\n        ++contadorWhile;\n    }\n\n    /**********BUCLE DO WHILE**********/\n    std::cout << separatorDoWhile;\n    short contadorDoWhile = 1;\n    do {\n        std::cout << \"Iteración (do-while) \" << contadorDoWhile << '\\n';\n        ++contadorDoWhile;\n    } while (contadorDoWhile <= 5);\n\n    /**********EXCEPCIONES**********/\n    std::cout << separatorTrowErrorHandle;\n    short divisor = 0;\n    try {\n        if (divisor == 0) {\n            throw std::runtime_error(\"División por cero.\");\n        }\n\n        int resultadoDivision = 10 / divisor;\n        std::cout << \"El resultado de la división es: \" << resultadoDivision << '\\n';\n    } catch (const std::exception& e) {\n        std::cerr << \"Error: \" << e.what() << '\\n';\n    }\n\n\n    std::cout << separator;\n\n    std::cout << \"Numeros que cumplen con la condicion: \";\n    imprimirNumeros(10, 55, 16, 3);\n    return 0;\n}\n\n/*************************************************************\n**********Funcion que resuelve el problema bonus**************\n*************************************************************/\n\n// Esta funcion sera la encargada de imprimir los valores que el\n// ejercicio del bonus lo demanda \nvoid imprimirNumeros(short valorInicio, short valorFinal, short multiplo1, short multiplo2) {\n\n    // Recorre todos los numeros del ´valorInicio´ a ´valorFinal´ y verifica que n no sea multiplo de \n    // <<multiplo1>> y <<multiplo2>>, en caso de ser cierto imprime por Termina el numero \n    for (short i = valorInicio; i <= valorFinal; i+=2) {\n        // Verifica que i no sea multiplo de <<multiplo1>> y <<multiplo2>>\n        if (i % 3 != 0 && i != 16) std::cout << i << \", \";\n        // std::cout << i << \", \";\n    }\n}\n\n\n/********************************************************************************************\n**********Nota: En los resultados de las operaciones booleanas en caso de ser true == 1,*****\n**********************caso contrario, en caso de ser false == 0******************************\n********************************************************************************************/\n\n/*************************************************************\n**********Resultado en Terminal**************\n*************************************************************/\n\n/*\nMultiplicación 2 * 4 = 8\nDivisión 20 / 5 = 4\nSuma 4 + 2 = 6\nResta 4 - 2 = 2\nDesplazamiento de bits hacia la Derecha 4 << 2 = 16\nDesplazamiento de bits hacia la Izquierda 4 >> 2 = 1\nOperador AND true && false = 0\nOperador OR true || false = 1\nOperador de igualdad 6 == 6 = 1\nOperador de desigualdad 6 != 9 = 1\nOperador mayor que 6 > 9 = 0\nOperador mayor o igual que 6 >= 6 = 1\nOperador menor que 6 < 9 = 1\nOperador menor o igual que 6 <= 6 = 1\nOperador de negación !true = 0\n\n##################Estructura IF##########################\n\nEstructura IF (10 es mayor a 0) :El número es positivo.\n\n##################Estructura Switch##########################\n\nEstructura SWITCH: El resultado es: 10\n\n##################Estructura FOR##########################\n\nIteración (for) 1\nIteración (for) 2\nIteración (for) 3\nIteración (for) 4\nIteración (for) 5\n\n##################Estructura While##########################\n\nIteración (while) 1\nIteración (while) 2\nIteración (while) 3\nIteración (while) 4\nIteración (while) 5\n\n##################Estructura DO While##########################\n\nIteración (do-while) 1\nIteración (do-while) 2\nIteración (do-while) 3\nIteración (do-while) 4\nIteración (do-while) 5\n\n##################Estructura Manejadora de Errores##########################\n\nError: División por cero.\n\n##################RESULTADO DEL EJERCICIO BONUS##########################\n\nNumeros que cumplen con la condicion: 10, 14, 20, 22, 26, 28, 32, 34, 38, 40, 44, 46, 50, 52, ⏎ \n*/"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c++/jhoshmc.cpp",
    "content": "#include <iostream>\nusing namespace std;\nint main(){\n  int a = 6;\n  int b = 5;\n\n  //! aritmeticos :\n  int suma = a + b;\n  int resta = a - b;\n  int multiplicacion = a *b;\n  float divicion = a / b;\n  float modulo = a % b;\n  cout << \"\\t aritmeticos \"<<endl;\n  cout<<a << \" + \" <<b<<\" = \"<< suma << endl;\n  cout<<a << \" - \" <<b<<\" = \"<< resta << endl;\n  cout<<a << \" * \" <<b<<\" = \"<< multiplicacion << endl;\n  cout<<a << \" / \" <<b<<\" = \"<< divicion << endl;\n  cout<<a << \" % \" <<b<<\" = \"<< modulo << endl;\n\n  //! lógico:\n  bool x = true;\n  bool y = false;\n  bool and_logico = x && y;\n  bool or_logico = x || y;\n  bool negacion = !x;\n  cout << \"\\t logicos \" << endl;\n  cout << \"verdadero: \" << x << endl;\n  cout << \"falso: \" << y << endl;\n  cout<<x << \" && \" <<y<<\" = \"<< and_logico << endl;\n  cout<<x << \" || \" <<y<<\" = \"<< or_logico << endl;\n  cout << \"!\" <<x<<\" = \"<< negacion << endl;\n\n  //! comparacion\n  bool igualdad = a == b;\n  bool mayor = a > b;\n  bool menor = a < b;\n  bool mayor_igual = a >= b;\n  bool menor_igual = a <= b;\n  bool diferentes = a != b;\n  cout << \"\\t comparacion \" << endl;\n  cout << a << \" == \" << b << \" = \" << igualdad << endl;\n  cout << a << \" > \" << b << \" = \" << mayor << endl;\n  cout << a << \" < \" << b << \" = \" << menor << endl;\n  cout << a << \" >= \" << b << \" = \" << mayor_igual << endl;\n  cout << a << \" <= \" << b << \" = \" << menor_igual << endl;\n  cout << a << \" != \" << b << \" = \" << diferentes << endl;\n\n  //! asignacion:\n  int n = 0;\n  cout << \"numero original: \" << n << endl;\n  cout << \"asignar a esa variable el numero 5: \" << endl;\n  cout << \"n: \" << n << endl;\n  n = 5;\n cout<< \"ahora n = 5: \" << n  << endl;\n\n //! operadores bits\n\n cout << \"\\t operadores a nivel de bits: \" << endl;\n cout<<\"AND: \" << a << \" & \"<<b<<\" = \" << (a & b) << endl;\n cout<<\"OR: \" << a << \" | \"<<b<<\" = \" << (a | b) << endl;\n cout<<\"XOR: \" << a << \" ^ \"<<b<<\" = \" << (a ^ b) << endl;\n\n //! operaciones con operadores\n //? condicional if(si) else(si no)\n cout << \"\\t if else clasico: \" << endl;\n if (modulo >= 1)\n {\n   cout << \"es verdad que el resto es mayor a 1\"<<endl;\n  }else{\n    cout << \"es mentira que el resto es menor a 1\" << endl;\n  }\n  //? ternario\n  cout << \"\\t if else ternrio: \" << endl;\n  bool c;\n  c = (a == b) ? x : y;\n  cout << \" respuesa al ternario : a==b: \" << c<<endl;\n\n  //? iteraciones (ciclos , repeticiones)\n  //* ciclo for\n  cout << \"\\t ciclo for: \" << endl;\n  for (int i = 0; i < b; i++)\n  {\n    cout <<i<< \", \";\n  }\n  cout << endl;\n  cout << \"\\t ciclo while: \" << endl;\n  //* ciclo while\n  while (n>= 1)\n  {\n    cout << \"n: \" << n << endl;\n    n--;\n  }\n  cout << endl;\n  cout << \"\\t ciclo doWhile \" << endl;\n  //* ciclo doWhile\n  do\n  {\n    cout << \"n: \"<< n << endl;\n    n++;\n  } while (n< a);\n\n  cout << endl;\n  //! manejo de ecepciones\n\n  try\n  {\n    /* no se que poner , pero es manejo de errores */\n  }\n  catch(const std::exception& e)\n  {\n    std::cerr << e.what() << '\\n';\n  }\n\n  int base = 10;\n  int final = 55;\n\n  for (base; base <= final; base++)\n  {\n    if ((base% 2 == 0)&& (base != 16) && (base%3!= 0) || (base == final))\n    {\n      cout << \"numero: \" << base << endl;\n    }\n    \n  }\n  \n\n  return 0;\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c++/m-doce.cpp",
    "content": "#include <iostream>\r\n\r\nint main()\r\n{\r\n    //Operadores aritméticos\r\n    printf(\"%d \\n\", 5 + 7); //Suma\r\n    printf(\"%d \\n\", 15 - 8); //Resta\r\n    printf(\"%d \\n\", 3 * 9); //Multiplicación\r\n    printf(\"%.3f \\n\", 99 / 7.0); //División\r\n    printf(\"%d \\n\", 18 % 5); //Módulo - Devuelve el resto de la división (en este caso, 3)\r\n\r\n    //Operadores de asignación y comparación\r\n    int num = 100; //El '=' se usa para asignar valores\r\n    num == 50? printf(\"Yes\\n\") : printf(\"No\\n\"); //El '==' se usa para comparar la igualdad entre valores\r\n    num != 50? printf(\"Yes\\n\") : printf(\"No\\n\"); //El '!=' se usa para comparar la desigualdad entre valores\r\n    num < 50? printf(\"Yes\\n\") : printf(\"No\\n\"); //El '<' devuelve true cuando el valor a su izq es menor\r\n    num > 50? printf(\"Yes\\n\") : printf(\"No\\n\"); //El '>' devuelve true cuando el valor a su izq es mayor\r\n\r\n    //Operadores lógicos\r\n    ((10 % 2) == 0) and ((20 % 3) == 0)? printf(\"Yes\\n\") : printf(\"No\\n\"); //El 'and' o '&&' se usa para evaluar que dos o más condiciones se cumplan \r\n    ((10 % 3) == 0) or ((20 % 3) == 0)? printf(\"Yes\\n\") : printf(\"No\\n\"); //El 'or' o '||' se usa para evaluar que al menos una condición se cumpla\r\n    not ((10 % 3) == 0) and not ((20 % 3) == 0)? printf(\"Yes\\n\") : printf(\"No\\n\"); //El 'not' o '!' se usa para invertir la evaluación de una condición\r\n\r\n    //Estructuras de control\r\n\r\n    //If-Else, se usa para bifurcar el código en base a una condición\r\n    if(4 > 5)\r\n    printf(\"Se cumple la condicion\\n\");\r\n    else\r\n    printf(\"No se cumple la condicion\\n\");\r\n\r\n    //Switch, se usa para ejecutar una acción en base al valor de una variable (útil para los menúes)\r\n    int diaDeLaSemana = 5;\r\n    switch(diaDeLaSemana)\r\n    {\r\n        case 1:\r\n        printf(\"Lunes\\n\");\r\n        break;\r\n\r\n        case 2:\r\n        printf(\"Martes\\n\");\r\n        break;\r\n\r\n        case 3:\r\n        printf(\"Miércoles\\n\");\r\n        break;\r\n\r\n        case 4:\r\n        printf(\"Jueves\\n\");\r\n        break;\r\n\r\n        case 5:\r\n        printf(\"Viernes\\n\");\r\n        break;\r\n\r\n        case 6:\r\n        printf(\"Sábado\\n\");\r\n        break;\r\n\r\n        case 7:\r\n        printf(\"Domingo\\n\");\r\n        break;\r\n    }\r\n\r\n    //Estructuras de repetición\r\n\r\n    //For, sirve para ejecutar instrucciones en bucle una cantidad de veces determinada\r\n    for(int i=0; i<10; i++)\r\n    {\r\n        printf(\"%d\\n\", i);\r\n    }\r\n\r\n    //While, sirve para ejecutar instrucciones en bucle una cantidad de veces indeterminada (por lo general hasta cumplir cierta condición)\r\n    int userInput = 0;\r\n    printf(\"Ingrese un numero para ver su doble, o '0' para finalizar: \");\r\n    scanf(\"%d\", &userInput);\r\n    while(userInput != 0)\r\n    {\r\n        printf(\"%d x 2 = %d\\n\", userInput, (userInput*2));\r\n        printf(\"Ingrese un numero para ver su doble, o '0' para finalizar: \");\r\n        scanf(\"%d\", &userInput);\r\n    }\r\n\r\n    // - - - - - SEGUNDO EJERCICIO - - - - -\r\n    printf(\"\\n\\n [*] Ejercicio extra [*]\\n\\n\");\r\n\r\n    for(int i=10; i<56; i++)\r\n    {\r\n        if(((i % 2) == 0) and ((i % 3) != 0) and (i != 16))\r\n        {\r\n            printf(\"[+] %d\\n\", i);\r\n        }\r\n    }\r\n\r\n    return 0;\r\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c++/oixild.cpp",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritmticos, lgicos, de comparacin, asignacin, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que t quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n \n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n\n#include <iostream>\n#include <vector>\n#include <exception> // Para manejo de excepciones\n\nusing namespace std;\n\nint main() {\n    // ** Operadores aritmticos **\n    int a = 10;\n    int b = 3;\n\n    cout << \"Operadores aritmticos:\" << endl;\n    cout << \"Suma: \" << a + b << endl;         // Suma\n    cout << \"Resta: \" << a - b << endl;        // Resta\n    cout << \"Multiplicacin: \" << a * b << endl; // Multiplicacin\n    cout << \"Divisin: \" << a / b << endl;     // Divisin\n    cout << \"Mdulo: \" << a % b << endl;       // Mdulo\n    cout << \"Incremento: \" << ++a << endl;     // Incremento\n    cout << \"Decremento: \" << --b << endl;     // Decremento\n\n    // ** Operadores de asignacin **\n    cout << \"\\nOperadores de asignacin:\" << endl;\n    a = 5;\n    cout << \"a = 5 -> \" << a << endl;\n    a += 2;\n    cout << \"a += 2 -> \" << a << endl;\n    a -= 1;\n    cout << \"a -= 1 -> \" << a << endl;\n    a *= 3;\n    cout << \"a *= 3 -> \" << a << endl;\n    a /= 2;\n    cout << \"a /= 2 -> \" << a << endl;\n    a %= 3;\n    cout << \"a %= 3 -> \" << a << endl;\n\n    // ** Operadores de comparacin **\n    cout << \"\\nOperadores de comparacin:\" << endl;\n    cout << \"a == b: \" << (a == b) << endl; // Igualdad\n    cout << \"a != b: \" << (a != b) << endl; // Diferente\n    cout << \"a < b: \" << (a < b) << endl;   // Menor que\n    cout << \"a > b: \" << (a > b) << endl;   // Mayor que\n    cout << \"a <= b: \" << (a <= b) << endl; // Menor o igual que\n    cout << \"a >= b: \" << (a >= b) << endl; // Mayor o igual que\n\n    // ** Operadores lgicos **\n    cout << \"\\nOperadores lgicos:\" << endl;\n    bool x = true;\n    bool y = false;\n    cout << \"x && y: \" << (x && y) << endl; // AND lgico\n    cout << \"x || y: \" << (x || y) << endl; // OR lgico\n    cout << \"!x: \" << !x << endl;           // NOT lgico\n\n    // ** Operadores de bits **\n    cout << \"\\nOperadores de bits:\" << endl;\n    int c = 5;  // 0101 en binario\n    int d = 9;  // 1001 en binario\n    cout << \"c & d: \" << (c & d) << endl;   // AND a nivel de bits\n    cout << \"c | d: \" << (c | d) << endl;   // OR a nivel de bits\n    cout << \"c ^ d: \" << (c ^ d) << endl;   // XOR a nivel de bits\n    cout << \"~c: \" << ~c << endl;           // NOT a nivel de bits\n    cout << \"c << 1: \" << (c << 1) << endl; // Desplazamiento a la izquierda\n    cout << \"c >> 1: \" << (c >> 1) << endl; // Desplazamiento a la derecha\n\n    // ** Estructuras de control: Condicionales **\n    cout << \"\\nEstructuras de control - Condicionales:\" << endl;\n    if (a > b) {\n        cout << \"a es mayor que b\" << endl;\n    }\n    else {\n        cout << \"a no es mayor que b\" << endl;\n    }\n\n    // ** Estructuras de control: Iterativas **\n    cout << \"\\nEstructuras de control - Iterativas:\" << endl;\n    cout << \"Bucle for:\" << endl;\n    for (int i = 0; i < 3; i++) {\n        cout << \"i = \" << i << endl;\n    }\n\n    cout << \"Bucle while:\" << endl;\n    int i = 0;\n    while (i < 3) {\n        cout << \"i = \" << i << endl;\n        i++;\n    }\n\n    cout << \"Bucle do-while:\" << endl;\n    i = 0;\n    do {\n        cout << \"i = \" << i << endl;\n        i++;\n    } while (i < 3);\n\n    // ** Estructuras de control: Manejo de excepciones **\n    cout << \"\\nEstructuras de control - Excepciones:\" << endl;\n    try {\n        int divisor = 0;\n        if (divisor == 0) {\n            throw runtime_error(\"Error: Divisin entre cero\");\n        }\n        int resultado = 10 / divisor;\n        cout << \"Resultado: \" << resultado << endl;\n    }\n    catch (const exception& e) {\n        cout << e.what() << endl;\n    }\n\n    // ** Dificultad Extra **\n    cout << \"\\nDificultad Extra:\" << endl;\n\n    int num = 10;\n    while (num <= 55) {\n        if (num % 2 == 0 && num % 3 != 0 && num % 16 != 0) {\n            cout << num << \" \" << endl;\n            num++;\n        }\n        num++;\n    }\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c++/skala2301.cpp",
    "content": "#include <iostream>\n#include <cstdint>\n#include <stdio.h>\n#include <compare>\n#include <typeinfo>\n#include <numeric>\n\n#include <vector>\n#include <array>\n#include <string>\n#include <bitset>\n\n/*****************************************************************************************************************************************************\nEl siguiente es un programa de ejemplo que muestra conceptos de operaciones en cpp y structuras de control, el codigo se divide de la siguiente forma\n**primera seccion:\n******Formado por los forward declaration de las funciones a utilizar, se declaran antes de definirce para que el compilador sepa que existen\n**segunda seccion:\n******Declaracion de variables y punteros\n**tercer seccion:\n******Definicion de Clases, estructuras y enumeradores\n******respecto al enumerador se define para uso de un menu de opciones e incluye un overload del operador de entrada de datos >>\n**cuarta seccion:\n******la cuarta seccion es donde corre el programa, comienza con main y luego va a la funcion runMenu() que corre todo\n**quinta seccion:\n******la quinta seccion es donde se encuentran todos los ejemplos de operadores, aqui se debe referir si se quieren ver los ejemplos\n***NOTA: Falta agregar iteradores, es un tema muy amplio, por lo que se agregara luego\n******************************************************************************************************************************************************/\n\n\n/********************\n**FUNCION PRINCIPAL**\n********************/\nvoid runMenu();\n\n\n\n\n/********************************************\n**FUNCION QUE MUESTRA OPERADORES ARITMETICOS*\n********************************************/\nvoid showArith();\n/*****************************************\n**FUNCION QUE MUESTRA OPERADORES LOGICOS**\n*****************************************/\nvoid showLogic();\n/*****************************************\n**FUNCION QUE MUESTRA OPERADORES DE BITS**\n*****************************************/\nvoid showBits();\n/*********************************************************\n**FUNCION QUE MUESTRA OPERADORES DE ASIGNACION COMPUESTOS*\n*********************************************************/\nvoid showAssign();\n/***********************************************************\n**FUNCION QUE MUESTRA OPERADORES DE RELACION Y COMPARACION**\n***********************************************************/\nvoid showComp();\n/*******************************************************\n**FUNCION QUE MUESTRA OPERADORES DE ACCESO A MIEMBROS **\n*******************************************************/\nvoid showAcces();\n/**************************************\n**FUNCION QUE MUESTRA EJEMPLO DE FOR **\n**************************************/\nvoid showFor();\n/**************************************\n**FUNCION QUE MUESTRA EL RETO EXTRA **\n**************************************/\nvoid retoExtra();\n\nstd::string compResult(const auto x);//FUNCION COMPLEMENTARIA PARA MUESTRA DE UNO DE LOS EJEMPLOS EN OPERADORES DE COMPARACION\n\n\n/**************************\n**DECLARACION DE VARIABLES*\n**************************/\nconstexpr int numConst{20};\nconstexpr int SIZE_INIT{10};\nconstexpr int SIZE_FINAL{55};\nconstexpr int nSize{(SIZE_FINAL+1)-SIZE_INIT};\nint numA{2};\nint numB{5};\nint numResult{0};\ndouble realA{4};\ndouble realB{8};\ndouble realResult{0};\n\ndouble matrixA[2][2]={  {12.4,20.6},\n                        {3.5,10.1}};\n\nbool boolA{true};\nbool boolB{false};\nbool boolC{true};\nbool boolResult{false};\n\nstd::bitset<8> inputA{0b0000'1000};\nstd::bitset<8> inputB{0b0000'0010};\nstd::bitset<8> inputC{0b0000'1111};\nstd::bitset<8> outputR{0b0000'0000};\n\nstd::vector<int> rangoN(nSize);\n\n/**********\n**PUNTEROS*\n**********/\n\nint* pointerA{new int{20}};\nint* pointerB{new int{30}};\nint* pointerC{nullptr};\n\n\n\n/**********************************************************************\n*****************************ESTRUCTURAS Y CLASES**********************\n**********************************************************************/\nstruct myStruct{\n    int x{};\n    int y{};\n    void print(){\n        std::cout<<\"member x= \"<<x<<'\\n';\n        std::cout<<\"member y= \"<<y<<'\\n';\n    }\n\n};\n\nclass myClass{\n    private:\n        std::bitset<8>* mInputB{new std::bitset<8>{0b0000'1000}};\n        std::bitset<8> mInputA{0b0001'1000};\n    public:\n        static std::bitset<8> mInputS;\n\n    public:\n        myClass(std::bitset<8> inputA=0b0001'1000){\n            mInputA=inputA;\n            mInputS<<=1;\n        }\n        ~myClass(){\n            delete mInputB;\n            std::cout<<\"\\nmInputB deleted\\n\";\n            mInputB=nullptr;\n        }\n        void print(){\n            std::cout<<\"member mInputA= \"<<mInputA<<'\\n';\n            std::cout<<\"member mInputB= \"<<*mInputB<<'\\n';\n        }\n        static void staticPrint(){\n            std::cout<<\"member mInputS= \"<<mInputS<<'\\n';\n        }\n};\nstd::bitset<8> myClass::mInputS=0b0000'0001;\n\n/******************************************************************************************\n*********************ENUMERADOR LLAMADO Options********************************************\n******************************************************************************************/\nenum class Options\n{\n    aritmetic,\n    logic,\n    bits,\n    asign,\n    comp,\n    acces,\n    ejemplofor,\n    retopluss,\n    si,\n    no,\n    invalido,\n    limit\n};\n//se hace overload de operador de input >> para aceptar Options\nstd::istream& operator>> (std::istream& in, Options& op)\n{\n    std::string input{};\n    in>>input;\n    /****************************************\n    *ESTRUCTURA DE CONTROL IF, ELSE IF, ELSE*\n    ****************************************/\n        if(input == \"ari\"){\n            op = Options::aritmetic;\n        }else if(input == \"log\"){\n            op = Options::logic;\n        }else if(input == \"bit\"){\n            op = Options::bits;\n        }else if(input == \"asi\"){\n            op = Options::asign;\n        }else if(input == \"com\"){\n            op = Options::comp;\n        }else if(input == \"acc\"){\n            op = Options::acces;\n        }else if(input == \"for\"){\n            op = Options::ejemplofor;\n        }else if(input == \"ext\"){\n            op = Options::retopluss;\n        }else if(input == \"si\"){\n            op = Options::si;\n        }else if(input == \"no\"){\n            op = Options::no;\n        }else if(input == \"lim\"){\n            op = Options::limit;\n        }else{\n            op = Options::invalido;\n        }\n\n    return in;\n}\n/*********AQUI FINALIZA LO REFERENTE A Options*************/\n\n\n\nmyClass xObject{};\nmyClass* xObjectPrt{new myClass{inputC}};\n\n\n\nint main(){\n\n    std::iota(rangoN.begin(), rangoN.end(), SIZE_INIT);\n\n    runMenu();//corre menu, es donde se corre todo lo referente a los ejemplos\n\n    //para todo puntero se debe liberar la memoria reservada con delete\n    delete pointerA;\n    delete pointerB;\n    delete pointerC;\n    delete xObjectPrt;\n\n    //una vez liberada la memoria de los punteros se debe asignar puntero nulo como buena practica\n    pointerA=nullptr;\n    pointerB=nullptr;\n    pointerC=nullptr;\n    xObjectPrt=nullptr;\n\n    return 0;\n}\n\nvoid runMenu(){\n\n\n\n    Options selected{Options::limit};\n\n    /****************************\n    ***ESTE ES UN BUCLE DO WHILE*\n    ****************************/\n    do{\n        std::cout<<\"TE MOSTRAMOS LOS DIFERENTES OPERADORES EN C++\\n \\\n            selecciona entre las siguientes secciones para ver ejemplos:\\n \\\n            codigo: | tema:...............................\\n \\\n            ari     | OPERADORES ARITMETICOS              \\n \\\n            log     | OPERADORES LOGICOS                  \\n \\\n            bit     | OPERADORES DE BITS                  \\n \\\n            asi     | OPERADORES DE ASIGNACION COMPUESTOS \\n \\\n            com     | OPERADORES DE RELACION Y COMPARACION\\n \\\n            acc     | OPERADORES DE ACCESO A MIEMBROS\\n \\\n            for     | ESTRUCTURA DE CONTROL FOR, ES PARA ITERAR\\n \\\n            ext     | entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3\\n\\\n                        \\nIngresa el codigo para la opcion deseada\\n\";\n        std::cin>>selected;\n\n        /**********************************\n        *ESTRUCTURA DE CONTROL SWITCH CASE*\n        **********************************/\n        switch(selected){\n            case Options::aritmetic:\n                std::cout<<\"Has seleccionado aritmeticos\\n\";\n                showArith();\n            break;\n            case Options::logic:\n                std::cout<<\"Has seleccionado logicas\\n\";\n                showLogic();\n            break;\n            case Options::bits:\n                std::cout<<\"Has seleccionado bits\\n\";\n                showBits();\n            break;\n            case Options::asign:\n                std::cout<<\"Has seleccionado asignasion\\n\";\n                showAssign();\n            break;\n            case Options::comp:\n                std::cout<<\"Has seleccionado comparacion\\n\";\n                showComp();\n            break;\n            case Options::acces:\n                std::cout<<\"Has seleccionado acceso\\n\";\n                showAcces();\n            break;\n            case Options::ejemplofor:\n                std::cout<<\"Has seleccionado Ejemplo de bucle for\\n\";\n                showFor();\n            break;\n            case Options::retopluss:\n                std::cout<<\"Has seleccionado El reto extra\\n\";\n                retoExtra();\n            break;\n            case Options::limit:\n                std::cout<<\"estas fuera de rango\\n\";\n            break;\n            default:\n                std::cout<<\"Invalido\\n\";\n            break;\n        }\n        /******************************\n        ***ESTE ES OTRO BUCLE DO WHILE*\n        ******************************/\n        do{\n            std::cout<<\"Deseas correr otro ejemplo? selecciona: \\n\\\n            --si\\n\\\n            --no\\n\";\n            std::cin>>selected;\n            if((selected != Options::si) && (selected != Options::no)) {\n                selected=Options::invalido;\n                std::cout<<\"Invalido\\n\";\n            }\n        }while(selected == Options::invalido);//SIEMPRE QUE SE CUMPLA LA CONDICION selected == Options::invalido EL BUCLE SE REPITE\n\n    }while(selected == Options::si);//SIEMPRE QUE SE CUMPLA LA CONDICION selected == Options::si EL BUCLE SE REPITE\n\n\n\n}\n\nvoid showArith(){\n    /*************************\n    **OPERADORES ARITMETICOS\n    *************************/\n\n    //Variables y constantes a utilizar\n    std::cout<<\"numConst = \"<<numConst<<'\\n';\n    std::cout<<\"numA: \"<<numA<<'\\n';\n    std::cout<<\"numB: \"<<numB<<\"\\n\\n\";\n\n    //operador de asignacion =\n    std::cout<<\"operador =\"<<'\\n';\n    numResult = numConst;\n    std::cout<<\"numResult =  numConst \\n\"<<\"= \"<<numResult<<\"\\n\\n\";\n\n    //operador de adision\n    std::cout<<\"operador +\"<<'\\n';\n    std::cout<<\"numA + numB = numResult\\n\";\n    numResult = numA + numB;\n    std::cout<<numA<<\" + \"<<numB<<\" = \"<<numResult<<\"\\n\\n\";\n\n    //operador de substraccion\n    std::cout<<\"operador -\"<<'\\n';\n    std::cout<<\"numA - numB = numResult\\n\";\n    numResult = numA - numB;\n    std::cout<<numA<<\" - \"<<numB<<\" = \"<<numResult<<\"\\n\\n\";\n\n    //operador de multiplicacion\n    std::cout<<\"operador *\"<<'\\n';\n    std::cout<<\"numA * numB = numResult\\n\";\n    numResult = numA * numB;\n    std::cout<<numA<<\" * \"<<numB<<\" = \"<<numResult<<\"\\n\\n\";\n\n    //operador de division\n    std::cout<<\"operador /\"<<'\\n';\n    std::cout<<\"realA / realB = realResult\\n\";\n    realResult = realA / realB;\n    std::cout<<realA<<\" / \"<<realB<<\" = \"<<realResult<<\"\\n\\n\";\n\n    //operador modulo\n    std::cout<<\"operador %\"<<'\\n';\n    std::cout<<\"realA % realB = realResult\\n\";\n    realResult = (static_cast<int>(realB)) % (static_cast<int>(realA));\n    std::cout<<realB<<\" % \"<<realA<<\" = \"<<realResult<<\"\\n\\n\";\n\n\n};\nvoid showLogic(){\n\n    /**********************\n    **OPERADORES LOGICOS**\n    **********************/\n\n    //operador OR || con boolean\n    std::cout<<\"operador ||\"<<'\\n';\n    std::cout<<\"boolA || boolB = boolResult\\n\";\n    boolResult = boolA || boolB;\n    std::cout<<boolA<<\" || \"<<boolB<<\" = \"<<boolResult<<\"\\n\\n\";\n\n    //operador AND && con boolean\n    std::cout<<\"operador &&\"<<'\\n';\n    std::cout<<\"boolA && boolB = boolResult\\n\";\n    boolResult = boolA && boolB;\n    std::cout<<boolA<<\" && \"<<boolB<<\" = \"<<boolResult<<\"\\n\\n\";\n\n    //operador NOT ! con boolean\n    std::cout<<\"operador !\"<<'\\n';\n    std::cout<<\"!boolA = boolResult\\n\";\n    boolResult = !boolA;\n    std::cout<<\" !\"<<boolA<<\" = \"<<boolResult<<\"\\n\\n\";\n};\n\nvoid showBits(){\n    /**********************\n    **OPERADORES DE BITS**\n    **********************/\n\n    //operador OR |\n    std::cout<<\"operador |\"<<'\\n';\n    std::cout<<\"inputA | inputB = outputR\\n\";\n    outputR = inputA | inputB;\n    std::cout<<inputA<<\" | \"<<inputB<<\" = \"<<outputR<<\"\\n\\n\";\n\n    //operador AND &\n    std::cout<<\"operador &\"<<'\\n';\n    std::cout<<\"inputA & inputB = outputR\\n\";\n    outputR = inputA & inputB;\n    std::cout<<inputA<<\" & \"<<inputB<<\" = \"<<outputR<<\"\\n\\n\";\n\n    //operador NOT ~\n    std::cout<<\"operador ~\"<<'\\n';\n    std::cout<<\"~inputA = outputR\\n\";\n    outputR = ~inputA;\n    std::cout<<\" ~\"<<inputA<<\" = \"<<outputR<<\"\\n\\n\";\n\n    //operador XOR ^\n    std::cout<<\"operador ^\"<<'\\n';\n    std::cout<<\"inputA ^ inputC = outputR\\n\";\n    outputR = inputA ^ inputC;\n    std::cout<<inputA<<\" ^ \"<<inputC<<\" = \"<<outputR<<\"\\n\\n\";\n\n    //operador  dezplazamiento logico a izquierda (left shift) <<\n    std::cout<<\"operador <<\"<<'\\n';\n    std::cout<<\"inputC << numA = outputR\\n\";\n    outputR = inputC << numA;\n    std::cout<<inputC<<\" << \"<<numA<<\" = \"<<outputR<<\"\\n\\n\";\n\n    //operador  dezplazamiento logico a derecha (right shift) >>\n    std::cout<<\"operador >>\"<<'\\n';\n    std::cout<<\"inputC >> numA = outputR\\n\";\n    outputR = inputC >> numA;\n    std::cout<<inputC<<\" >> \"<<numA<<\" = \"<<outputR<<\"\\n\\n\";\n\n};\nvoid showAssign(){\n    /*************************************\n    **OPERADORES DE ASIGNACION COMPUESTOS*\n    *************************************/\n\n    std::cout<<\"operador +=\"<<'\\n';\n    std::cout<<\"realA += realB =\\n\";\n    std::cout<<realA<<\" += \"<<realB<<\" = \"<<(realA += realB, realA)<<\"\\n\\n\";\n\n    std::cout<<\"operador -=\"<<'\\n';\n    std::cout<<\"realA -= realB =\\n\";\n    std::cout<<realA<<\" -= \"<<realB<<\" = \"<<(realA -= realB, realA)<<\"\\n\\n\";\n\n    std::cout<<\"operador *=\"<<'\\n';\n    std::cout<<\"realA *= realB =\\n\";\n    std::cout<<realA<<\" *= \"<<realB<<\" = \"<<(realA *= realB, realA)<<\"\\n\\n\";\n\n    std::cout<<\"operador /=\"<<'\\n';\n    std::cout<<\"realA /= realB =\\n\";\n    std::cout<<realA<<\" /= \"<<realB<<\" = \"<<(realA /= realB, realA)<<\"\\n\\n\";\n\n    std::cout<<\"operador %=\"<<'\\n';\n    std::cout<<\"numB %= numA =\\n\";\n    std::cout<<numB<<\" %= \"<<numA<<\" = \"<<(numB %= numA, numB)<<\"\\n\\n\";\n\n    std::cout<<\"operador |= usando bits\"<<'\\n';\n    std::cout<<\"inputA |= inputB =\\n\";\n    std::cout<<inputA<<\" |= \"<<inputB<<\" = \"<<(inputA |= inputB, inputA)<<\"\\n\\n\";\n\n    std::cout<<\"operador |= usando booleanos\"<<'\\n';\n    std::cout<<\"boolA |= boolB =\\n\";\n    std::cout<<boolA<<\" |= \"<<boolB<<\" = \"<<(boolA |= boolB, boolA)<<\"\\n\\n\";\n\n    std::cout<<\"operador &= usando bits\"<<'\\n';\n    std::cout<<\"inputA &= inputB =\\n\";\n    std::cout<<inputA<<\" &= \"<<inputB<<\" = \"<<(inputA &= inputB, inputA)<<\"\\n\\n\";\n\n    std::cout<<\"operador &= usando booleanos\"<<'\\n';\n    std::cout<<\"boolA &= boolB =\\n\";\n    std::cout<<boolA<<\" &= \"<<boolB<<\" = \"<<(boolA &= boolB, boolA)<<\"\\n\\n\";\n\n    std::cout<<\"operador ^= usando bits\"<<'\\n';\n    std::cout<<\"inputA ^= inputC =\\n\";\n    std::cout<<inputA<<\" ^= \"<<inputC<<\" = \"<<(inputA ^= inputC, inputA)<<\"\\n\\n\";\n\n    std::cout<<\"operador ^= usando booleanos\"<<'\\n';\n    std::cout<<\"boolA ^= boolC =\\n\";\n    std::cout<<boolA<<\" ^= \"<<boolC<<\" = \"<<(boolA ^= boolC, boolA)<<\"\\n\\n\";\n\n    std::cout<<\"operador <<= usando bits\"<<'\\n';\n    std::cout<<\"inputA <<= numA =\\n\";\n    std::cout<<inputA<<\" <<= \"<<numA<<\" = \"<<(inputA <<= numA, inputA)<<\"\\n\\n\";\n\n    std::cout<<\"operador >>= usando bits\"<<'\\n';\n    std::cout<<\"inputA >>= numB =\\n\";\n    std::cout<<inputA<<\" >>= \"<<numB<<\" = \"<<(inputA >>= numB, inputA)<<\"\\n\\n\";\n};\nvoid showComp(){\n\n    /***************************************\n    **OPERADORES DE RELACION Y COMPARACION**\n    ***************************************/\n\n    //operador igual a ==\n    std::cout<<\"operador ==\"<<'\\n';\n    std::cout<<\"numA == numB = numResult\\n\";\n    boolResult = numA == numB;\n    std::cout<<numA<<\" == \"<<numB<<\" = \"<<boolResult<<\"\\n\\n\";\n\n    //operador diferente de !=\n    std::cout<<\"operador !=\"<<'\\n';\n    std::cout<<\"numA != numB = numResult\\n\";\n    boolResult = numA != numB;\n    std::cout<<numA<<\" != \"<<numB<<\" = \"<<boolResult<<\"\\n\\n\";\n\n    //operador menor que <\n    std::cout<<\"operador <\"<<'\\n';\n    std::cout<<\"numA < numB = numResult\\n\";\n    boolResult = numA < numB;\n    std::cout<<numA<<\" < \"<<numB<<\" = \"<<boolResult<<\"\\n\\n\";\n\n    //operador mayor que >\n    std::cout<<\"operador >\"<<'\\n';\n    std::cout<<\"numA > numB = numResult\\n\";\n    boolResult = numA > numB;\n    std::cout<<numA<<\" > \"<<numB<<\" = \"<<boolResult<<\"\\n\\n\";\n\n    //operador menor o igual que <=\n    std::cout<<\"operador <=\"<<'\\n';\n    std::cout<<\"numA <= numB = numResult\\n\";\n    boolResult = numA <= numB;\n    std::cout<<numA<<\" <= \"<<numB<<\" = \"<<boolResult<<\"\\n\\n\";\n\n    //operador mayor o igual que >=\n    std::cout<<\"operador >=\"<<'\\n';\n    std::cout<<\"numA >= numB = numResult\\n\";\n    boolResult = numA >= numB;\n    std::cout<<numA<<\" >= \"<<numB<<\" = \"<<boolResult<<\"\\n\\n\";\n\n    //operador de tres vias <=>, no lo entendi bien, queda de tarea investigar mas\n\n    std::cout<<\"operador <=>\"<<'\\n';\n    std::cout<<\"realA <=> numB = numResult\\n\";\n    {\n        auto x = realA <=> numB;\n        std::cout<<realA<<\" <=> \"<<numB<<\" = \"<<realA<<compResult(x)<<numB<<\"\\n\\n\";\n    }\n\n\n    std::cout<<\"realA <=> realB = numResult\\n\";\n    {\n        auto x = numA <=> numB;\n        std::cout<<realA<<\" <=> \"<<realB<<\" = \"<<realA<<compResult(x)<<realB<<\"\\n\\n\";\n    }\n};\nvoid showAcces(){\n    /***********************************\n    **OPERADORES DE ACCESO A MIEMBROS **\n    ***********************************/\n\n    //operador de subscripcion []\n    std::cout<<\"operador [](subscripcion)\"<<'\\n';\n    std::cout<<\"Suponiendo que se tiene la siguiente matriz:\\n double matrixA[2][2]={  {12.4,20.6},{3.5,10.1}};\\n\";\n    std::cout<<\"Se puede acceder a primera columna primera fila de la siguiente forma matrixA[0][0]\\n\"<<matrixA[0][0]<<'\\n';\n    std::cout<<\"Se puede acceder a segunda columna primera fila de la siguiente forma matrixA[0][1]\\n\"<<matrixA[0][1]<<'\\n';\n    std::cout<<\"\\n\\n\";\n\n\n    //operador  direccion de &\n    std::cout<<\"operador &(direccion de)\"<<'\\n';\n    pointerC = new int{0};\n    std::cout<<\"Para pointerC inicialmente:\\n\";\n    std::cout<<*pointerC<<\" es el valor \"<<pointerC<<\" la direccion \"<<\"\\n\\n\";\n    std::cout<<\"pointerC = &numResult ---> pointerC apunta a direccion de numResult\\n\";\n    delete pointerC;\n    pointerC = &numResult;\n    std::cout<<\"Para pointerC:\\n\";\n    std::cout<<*pointerC<<\" es el valor \"<<pointerC<<\" la direccion \"<<\"\\n\\n\";\n    std::cout<<\"Para numResult:\\n\";\n    std::cout<<numResult<<\" es el valor \"<<&numResult<<\" la direccion \"<<\"\\n\";\n    std::cout<<\"\\n\\n\";\n    //operador  de dereferencia *\n    std::cout<<\"operador * (de dereferencia)\"<<'\\n';\n    pointerC = new int{0};\n    std::cout<<\"*pointerC = *pointerA ---> pointerC apunta a direccion diferente de pointerA, pero a copiado el valor\\n\";\n    *pointerC = *pointerA;\n    std::cout<<\"Para pointerC:\\n\";\n    std::cout<<*pointerC<<\" es el valor \"<<pointerC<<\" la direccion donde apunta \"<<&pointerC<<\" la direccion del puntero C\"<<\"\\n\\n\";\n    std::cout<<\"Para pointerA:\\n\";\n    std::cout<<*pointerA<<\" es el valor \"<<pointerA<<\" la direccion donde apunta \"<<&pointerA<<\" la direccion del puntero A\"<<\"\\n\\n\";\n\n\n    //operador  miembro de objeto .\n    std::cout<<\"operador . (acceso a miembro de objeto)\"<<'\\n';\n    std::cout<<\"se instancia objeto xObject clase myClass y accedemos a metodo print con xObject.print()\\n\";\n    xObject.print();\n    std::cout<<\"\\n\\n\";\n\n    //operador  miembro de puntero ->\n    std::cout<<\"operador -> (acceso a miembro de puntero)\"<<'\\n';\n    std::cout<<\"puntero xObjectPrt apunta a objeto clase myClass, accedemos a metodo print con xObjectPrt->print()\\n\";\n    xObjectPrt->print();\n    std::cout<<\"\\n\\n\";\n\n    //operador  puntero a miembro de objeto .*\n    std::cout<<\"operador .* (puntero a miembro de objeto)\"<<'\\n';\n    std::cout<<\"print es metodo de clase myClass, se puede hacer puntero al metodo asi: void (myClass::*printPtr)() = &myClass::print;\\n\";\n    void (myClass::*printPtr)() = &myClass::print;\n    std::cout<<\"llamamos al metodo con cualquier objeto de la clase de la siguiente forma (xObject.*printPtr)();\\n\";\n    (xObject.*printPtr)();\n    std::cout<<\"\\n\\n\";\n\n    //operador  puntero a miembro de puntero ->*\n    std::cout<<\"operador ->* (puntero a miembro de puntero)\"<<'\\n';\n    std::cout<<\"tambien podemos llamar al metodo con cualquier puntero apuntando a la clase de la siguiente forma (xObjectPrt->*printPtr)();\\n\";\n    (xObjectPrt->*printPtr)();\n    std::cout<<\"\\n\\n\";\n\n    printPtr=nullptr;\n};\n\nvoid showFor(){\n    /******************************************\n    *ESTRUCTURA DE CONTROL FOR, ES PARA ITERAR*\n    ******************************************/\n    for(int i=0;i<=1;++i){\n        for(int j=0;j<=1;++j) std::cout<<\"columna: \"<<i+1<<\" fila: \"<<j+1<<\" : \"<<matrixA[i][j]<<'\\n';\n    }\n}\nvoid retoExtra(){\n    /***********************\n    **ESTE ES EL RETO EXTRA*\n    ***********************/\n    for(auto elementN : rangoN){\n        if(!(elementN%2) && elementN!=16 && (elementN%3)){\n            std::cout<<elementN<<'\\n';\n        }\n    }\n}\n\n\n\nstd::string compResult(const auto x){\n    /****************************************\n    *ESTRUCTURA DE CONTROL IF, ELSE IF, ELSE*\n    ****************************************/\n    if(typeid(x) == typeid(std::strong_ordering)){\n        if(x<0){\n            return \" + menor que \";\n        }else if(x>0){\n            return \" + mayor que \";\n        }else if(x==0){\n            return \" + igual valor que \";\n        }else{\n            return \" tipo incompatible \";\n        }\n    }else if(typeid(x) == typeid(std::partial_ordering)){\n        if(x<0){\n            return \" - menor que \";\n        }else if(x>0){\n            return \" - mayor que \";\n        }else if(x==0){\n            return \" - igual valor que \";\n        }else{\n            return \" tipo incompatible \";\n        }\n    }else{\n        return \"No valido\";\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c++/tomytsa.cpp",
    "content": "#include <iostream>\nusing namespace std;\nint main()\n{\n// TODOS LOS OPERADORES DE C++\n\n    // Operadores aritmeticos\n    cout << 3 + 2 << endl; // Suma\n    cout << 10 - 2 << endl; // Resta\n    cout << 1 * 2 << endl; // Multiplicacion\n    cout << float(1) / 2 << endl; // Division\n    cout << 10 % 4 << endl; // Modulo (resto o residuo)\n    \n    // Operadores logicos\n    cout << (true && false) << endl; // and\n    cout << (true || false) << endl; // or\n    cout << (!true) << endl; // not\n\n    // Operadores de comparacion\n\n    cout << (5 > 2) << endl; // Mayor que\n    cout << (5 < 2) << endl; // Menor que\n    cout << (5 == 5) << endl; // Igual que\n    cout << (5 >= 2) << endl; // Mayor o igual que\n    cout << (5 <= 2) << endl; // Menor o igual que\n    cout << (5 != 2) << endl; // Distinto que\n\n    // Operadores de asignacion\n    int a = 5;    // Asignacion basica   \n    cout << (a += 3) << endl; // Asignacion de suma\n    cout << (a -= 3) << endl; // Asignacion de resta\n    cout << (a *= 3) << endl; // Asignacion de multiplicacion\n    cout << (a /= 3) << endl; // Asignacion de division\n    cout << (a %= 3) << endl; // Asignacion de modulo\n  \n    // Operadores bit a bit\n    int c = 4;\n    int b = 2;\n    cout << (c & b) << endl; // AND binario\n    cout << (c | b) << endl; // OR binario\n    cout << (c ^ b) << endl; // XOR binario\n    cout << (c >> b) << endl; // Desplazamiento a la derecha\n    cout << (c << b) << endl; // Desplazamiento a la izquierda\n\n// ESTRUCTURAS DE CONTROL\n\n    // Condicionales\n\n    string contraseña = \"pepe123\";\n    if (contraseña == \"pepe123\")\n    {\n        cout << \"Bienvenido!\" << endl; \n    }\n    else\n    {\n        cout << \"Contraseña incorrecta\" << endl;\n    }\n    \n    cout << \"Ingrese una opcion: \" << endl;\n    char opcion; \n    cin >> opcion; \n    \n    switch (opcion)\n    {\n    case 'a':\n        cout << \"Usted ingreso la opcion a. \" << endl;\n        break;\n    case 'b':\n        cout << \"Usted ingreso la opcion b. \" << endl;\n        break;\n    case 'c':\n        cout << \"Usted ingreso la opcion c. \" << endl;\n        break;   \n    default:\n        cout << \"Usted ingreso una opcion incorrecta\" << endl; \n        break;\n    }\n    \n    // Iterativas\n    int i = 0;\n    while (i <= 5)\n    {\n        cout << i << endl;\n        i++;\n    }\n    for (int x = 0; x < 5; x++)\n    {\n        cout << x << endl;\n    }\n    \n    // EJERCICIO DE DIFICULTAD EXTRA\n\n    int a = 10;\n    while (a <= 56)\n    {\n        if (a % 2 == 0 && a != 16 && a % 3 != 0)\n    {\n        cout << a << endl;\n    }\n        a++;\n    }\n    \n\n\n\n    return 0;\n}\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c++/whiterunjarl.cpp",
    "content": "#include <iostream>\nusing namespace std;\n\n// operadores aritméticos\n\nint suma = 1 + 2; // 3\nint resta = 4 - 2; // 2\nint multiplicar = 4 * 2; // 8\nint division = 80 / 2; // 40\nint modulo = 10 % 4; // resto es 2\n\n\n// Conjunción (&&) chequeo de dos condiciones que se deben cumplir simultaneamente\n// no olvidarse el camelCase al declarar\nvoid mostrarValidacion()\n{\n\tcout << \"Esto es valido, ha funcionado\";\n}\n\n// negación !\nbool esFalso = !true; // false\n\n\nint c = 1;\n// Disyunción(|| ) : es igual al OR (si una de las dos se cumple, ejecuta)\nbool opcionValida = (c == 1) || (c == 2); // true si c es 1 o 2\n\n\n\n\nint main()\n{\n\tcout << \"esto funciona\" << endl;\n\tcout << suma << endl;\n\tcout << resta << endl;\n\tcout << multiplicar << endl;\n\tcout << division << endl;\n\tcout << modulo << endl;\n\tcout << opcionValida << endl;\n\tif (multiplicar < 10 && modulo > 0)\n\t{\n\t\tmostrarValidacion();\n\t}\n\n\n\n\treturn 0;\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c++/xooseph.cpp",
    "content": "// Operadores\n\n#include <iostream>\n\nusing namespace std;\n\nvoid printNumbers() {\n    /* EJERCICIO EXTRA\n        Imprimir todos los números entre 10 y 55 (incluidos), pares, y que no \n        son ni el 16 ni múltiplos de 3.\n    */\n    cout << \"Números del 10 al 55:\\n\";\n\n    for (int i = 10; i <= 55; i++) {\n        if (((i % 2) == 0) && (i != 16) && ((i % 3) != 0)) {\n            cout << i << \"\\n\";\n        }\n    }\n}\n\nint main() {\n    int a = 10;\n    int b = 5;\n\n    cout << \"OPERADORES ARITMÉTICOS\\n\\n\";\n    cout << \"Suma: 10 + 5 = \" << (a + b) << \"\\n\";\n    cout << \"Resta: 10 - 5 = \" << (a - b) << \"\\n\";\n    cout << \"Multiplicación: 10 * 5 = \" << (a * b) << \"\\n\";\n    cout << \"División: 10 / 5 = \" << (a / b) << \"\\n\";\n    cout << \"Módulo: 10 % 5 = \" << (a % b) << \"\\n\";\n    cout << \"Incremento: +1 a 10 = \" << ++a << \"\\n\";\n    cout << \"Decremento: -1 a 5 = \" << --b << \"\\n\\n\";\n\n    a = 3;\n    b = 5;\n\n    cout << \"OPERADORES LÓGICOS\\n\\n\";\n    cout << \"a = 3\\n\";\n    cout << \"a > 2 and a < 5: \" << (a > 2 && a < 5) << \"\\n\";\n    cout << \"a > 2 or a > 10: \" << (a > 2 || a > 10) << \"\\n\";\n    cout << \"not a > 2: \" << !(a > 2) << \"\\n\\n\";\n    \n    cout << \"OPERADORES DE COMPARACIÓN\\n\\n\";\n\n    cout << \"a = 3, b = 5\\n\";\n    cout << \"a == b: \" << (a == b) << \"\\n\";\n    cout << \"a != b: \" << (a != b) << \"\\n\";\n    cout << \"a > b: \" << (a > b) << \"\\n\";\n    cout << \"a < b: \" << (a < b) << \"\\n\";\n    cout << \"a >= b: \" << (a >= b) << \"\\n\";\n    cout << \"a <= b: \" << (a <= b) << \"\\n\\n\"; \n\n    cout << \"OPERADORES DE ASIGNACIÓN Y DE BIT\\n\\n\";\n\n    cout << \"a = 8: \" << (a = 8) << \"\\n\";\n    cout << \"a = a + 2: \" << (a += 2) << \"\\n\";\n    cout << \"a = a - 3: \" << (a -= 3) << \"\\n\";\n    cout << \"a = a * 4: \" << (a *= 4) << \"\\n\";\n    cout << \"a = a / 3: \" << (a /= 3) << \"\\n\";\n    cout << \"a = a % 2: \" << (a %= 2) << \"\\n\";\n    // AND bit a bit\n    cout << \"a = a & 3: \" << (a &= 3) << \"\\n\";\n    // OR inclusivo bit a bit\n    cout << \"a = a | 2: \" << (a |= 2) << \"\\n\";\n    // OR exclusivo bit a bit\n    cout << \"a = a ^ 5: \" << (a ^= 5) << \"\\n\";\n    // Cambia el valor del primer operando a la derecha el número de bits \n    // especificado por el valor del segundo operando\n    cout << \"a = a >> 2: \" << (a >>= 2) << \"\\n\";\n    // Cambia el valor del primer operando a la izquierda del número de bits \n    // especificado por el valor del segundo operando\n    cout << \"a = a << 2: \" << (a <<= 2) << \"\\n\\n\"; \n\n    cout << \"ESTRUCTURAS DE CONTROL\\n\\n\";\n    cout << \"IF-ELSE:\\n\\n\";\n\n    a = 5;\n\n    if (a == 5) {\n        cout << \"a es 5\" << \"\\n\";\n    } \n\n    else {\n        cout << \"a no es 5\" << \"\\n\";\n    }\n\n    cout << \"SWITCH:\\n\\n\";\n\n    switch (a){\n        case 5:\n            cout << \"a es 5\" << \"\\n\";\n            break;\n\n        default:\n            cout << \"a no es 5\" << \"\\n\";\n            break;\n    }\n\n    cout << \"WHILE:\\n\\n\";\n\n    while (a > 0) {\n        cout << a << \"\\n\\n\";\n        --a;\n    }\n\n    cout << \"DO-WHILE:\\n\\n\";\n\n    a = 5;\n\n    do {\n        cout << a << \"\\n\\n\";\n        --a;\n    } while (a > 0);\n\n    cout << \"FOR:\\n\\n\";\n\n    for (int i = 0; i < 5; i++) {\n        cout << i << \"\\n\\n\";\n    }\n\n    cout << \"EXCEPCIONES:\\n\\n\";\n\n    try {\n        throw 12;\n    }\n    catch (int) {\n        cout << \"Se ha generado una excepción de tipo int.\\n\\n\"; \n    }\n\n    printNumbers();\n\n    return 0;\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/c++/yeisonagm.cpp",
    "content": "#include <iostream>\n#include <random>\n\nusing namespace std;\n\nint main() {\n    // Declaración de variables\n    int num1 = 57;\n    int num2 = 23;\n    cout << \"Número 1: \" << num1 << endl;\n    cout << \"Número 2: \" << num2 << endl << endl;\n\n    // Operadores aritméticos\n    int suma = num1 + num2;\n    int resta = num1 - num2;\n    int producto = num1 * num2;\n    int divicion = num1 / num2;\n    int modulo = num1 % num2;\n    cout << \"Operadores aritméticos\" << endl;\n    cout << \"Suma: \" << suma << endl;\n    cout << \"Resta: \" << resta << endl;\n    cout << \"Producto: \" << producto << endl;\n    cout << \"División: \" << divicion << endl;\n    cout << \"Módulo: \" << modulo << endl;\n\n    // Operadores lógicos\n    bool orLogico = true || false;\n    bool andLogico = false && true;\n    bool esMayor = 38 > 17;\n    bool esMenor = 1027 <= 243;\n    bool negacion = !(5 <= 12);\n    bool igual = suma == producto;\n    bool noIgual = modulo != resta;\n\n    cout << endl << \"Operadores lógicos\" << endl;\n    cout << \"Or: \" << orLogico << endl;\n    cout << \"And: \" << andLogico << endl;\n    cout << \"38 > 17: \" << esMayor << endl;\n    cout << \"1027 <= 243: \" << esMenor << endl;\n    cout << \"Negación de (5 <= 12): \" << negacion << endl;\n    cout << \"La suma es igual a la multiplicación: \" << igual << endl;\n    cout << \"El módulo no es igual a la resta: \" << noIgual << endl;\n\n    // Asignación\n    cout << endl << \"Asignación\" << endl;\n    int numero = num2 + 2;\n    cout << \"Número: \" << numero << endl;\n    numero += 5; // Suma y asignación\n    numero -= 3; // Resta y asignación\n    num2 *= 7; // Multiplicación y asignación\n    num1 /= 3; // División y asignación\n    cout << \"Número 1: \" << num1 << endl;\n    cout << \"Número 2: \" << --num2 << endl;\n    cout << \"Número: \" << numero++ << endl;\n\n    // Generar un número aleatorio entre 1 y 7\n    random_device rd;\n    uniform_int_distribution<int> dist(0, 7);\n    int numAleatorio = dist(rd);\n    int numPar = numAleatorio % 2 == 0 ? numAleatorio : ++numAleatorio;\n    cout << \"Numero par: \" << numPar << endl;\n\n    // Manipulación de bits\n    cout << endl << \"Manipulación de bits\" << endl;\n    int a = 60;  // 60 = 0011 1100\n    int b = 13;  // 13 = 0000 1101\n    cout << \"a = \" << a << \", b = \" << b << endl;\n    int result;\n\n    // AND bit a bit\n    result = a & b;  // 12 = 0000 1100\n    cout << \"Resultado de a & b: \" << result << endl;\n\n    // OR bit a bit\n    result = a | b;  // 61 = 0011 1101\n    cout << \"Resultado de a | b: \" << result << endl;\n\n    // XOR bit a bit\n    result = a ^ b;  // 49 = 0011 0001\n    cout << \"Resultado de a ^ b: \" << result << endl;\n\n    // NOT bit a bit\n    result = ~a;  // -61 = 1100 0011\n    cout << \"Resultado de ~a: \" << result << endl;\n\n    // Desplazamiento a la izquierda\n    result = a << 2;  // 240 = 1111 0000\n    cout << \"Resultado de a << 2: \" << result << endl;\n\n    // Desplazamiento a la derecha\n    result = a >> 2;  // 15 = 0000 1111\n    cout << \"Resultado de a >> 2: \" << result << endl;\n\n    // Condicionales\n    cout << endl << \"Condicionales\" << endl;\n    if (num1 > num2) {\n        cout << \"num1 es mayor que num2\" << endl;\n    } else if (num1 < num2) {\n        cout << \"num1 es menor que num2\" << endl;\n    } else {\n        cout << \"num1 es igual a num2\" << endl;\n    }\n\n    int dia = dist(rd);\n    cout << \"Número aleatorio: \" << dia << \" -> \";\n    switch (dia) {\n        case 1:\n            cout << \"Lunes\" << endl;\n            break;\n        case 2:\n            cout << \"Martes\" << endl;\n            break;\n        case 3:\n            cout << \"Miércoles\" << endl;\n            break;\n        case 4:\n            cout << \"Jueves\" << endl;\n            break;\n        case 5:\n            cout << \"Viernes\" << endl;\n            break;\n        case 6:\n            cout << \"Sábado\" << endl;\n            break;\n        case 7:\n            cout << \"Domingo\" << endl;\n            break;\n        default:\n            cout << \"Día no válido\" << endl;\n    }\n\n    // Bucles e iteraciones\n    cout << endl << \"Bucles e iteraciones\" << endl;\n    cout << \"Números impares menores a 39: \";\n    for (int i = 1; i < 39; i += 2) {\n        cout << i << \", \";\n    }\n    cout << endl;\n\n    ++numero;\n    bool esPrimo = true;\n    int divisor = 2;\n    while (divisor < numero) {\n        if (numero % divisor == 0) {\n            esPrimo = false;\n            break;\n        }\n        divisor++;\n    }\n    string mensaje = esPrimo ? \" es primo.\" : \" no es primo.\";\n    cout << \"El número \" << numero << mensaje << endl;\n\n    int entrada;\n    do {\n        cout << \"Ingresa un número impar: \";\n        cin >> entrada;\n    } while (entrada % 2 == 0);\n    cout << \"Correcto \" << entrada << \" es impar.\" << endl;\n\n    // Excepciones\n    cout << endl << \"Excepciones\" << endl;\n    cout << \"Ingresa un número para dividir 17: \";\n    cin >> divisor;\n    try {\n        if (divisor == 0) {\n            throw invalid_argument(\"División por cero.\");\n        }\n        cout << \"Resultado: \" << 17 / divisor << endl;\n    } catch (const invalid_argument &e) {\n        cout << \"Error: \" << e.what() << endl;\n    }\n\n    // Dificulta extra\n    /* Crea un programa que imprima por consola todos los números comprendidos\n       entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3 */\n    cout << endl << \"Dificulta extra\" << endl;\n    for (int i = 10; i < 56; i += 2) {\n        // Saltar el 16\n        if (i == 16) continue;\n\n        // Filtrar los múltiplos de 3\n        if (i % 3 == 0) continue;\n\n        cout << i << \", \";\n    }\n\n    return 0;\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/cobol/any7dev.cbl",
    "content": "     /*\n      *    EJERCICIO:\n      *    - Crea ejemplos utilizando todos los tipos de operadores de\n      *    tu lenguaje:\n      *    Aritméticos, lógicos, de comparación, asignación, identidad,\n      *     pertenencia, bits...\n      *    Ten en cuenta que cada lenguaje puede poseer unos diferentes\n      *    - Utilizando las operaciones con operadores que tú quieras,\n      *     crea ejemplos\n      *    que representen todos los tipos de estructuras de control\n      *    que existan en tu lenguaje:\n      *    Condicionales, iterativas, excepciones...\n      *    - Debes hacer print por consola del resultado\n      *     de todos los ejemplos.\n      *\n      *    DIFICULTAD EXTRA (opcional):\n      *    Crea un programa que imprima por consola todos los números\n      *    comprendidos entre 10 y 55 (incluidos), pares, y que no son\n      *    ni el 16 ni múltiplos de 3.\n      *\n      *    Seguro que al revisar detenidamente las posibilidades has\n      *    descubierto algo nuevo.\n      */\n\n       IDENTIFICATION DIVISION.\n       PROGRAM-ID. RETO-02.\n       DATA DIVISION.\n       FILE SECTION.\n       WORKING-STORAGE SECTION.\n           77 RESULTADO PIC 9(3).\n           77 NUM1 PIC 99 VALUE 10.\n           77 NUM2 PIC 99 VALUE 2.\n           77 NUM3 PIC 99 VALUE 25.\n           77 NUM-SALUDO PIC 99 VALUE 5.\n           77 NUM-EXTRA PIC 99.\n           77 RESTO PIC 99.\n      *    Una variable diferente a las anteriores y que no estaba\n      *    incluida en el ejercicio 00\n           01 NUMERO PIC 9(6).\n               88 UNA-CIFRA VALUE 0 THRU 9.\n               88 DOS-CIFRAS VALUE 10 THRU 99.\n               88 TRES-CIFRAS VALUE 100 THRU 999.\n       PROCEDURE DIVISION.\n       OPERADORES.\n      *    -OPERACIONES ARITMETICAS CON COMPUTE\n      *    Suma\n           COMPUTE RESULTADO = NUM1 + NUM2.\n           DISPLAY RESULTADO.\n\n      *    Resta\n           COMPUTE RESULTADO = NUM1 - NUM2.\n           DISPLAY RESULTADO.\n\n      *    Multiplicacion\n           COMPUTE RESULTADO = NUM1 * NUM2.\n           DISPLAY RESULTADO.\n\n      *    Division\n           COMPUTE RESULTADO = NUM1 / NUM2.\n           DISPLAY RESULTADO.\n\n      *    Potencia\n           COMPUTE RESULTADO = NUM1 ** NUM2.\n           DISPLAY RESULTADO.\n\n      *    -OPERACIONES ARITMETICAS CON VERBOS\n      *    Suma\n           ADD NUM1 TO NUM2 GIVING RESULTADO.\n           DISPLAY RESULTADO.\n\n      *    Resta\n           SUBTRACT NUM1 FROM NUM2 GIVING RESULTADO.\n           DISPLAY RESULTADO.\n\n      *    Multiplicacion\n           MULTIPLY NUM1 BY NUM2 GIVING RESULTADO.\n           DISPLAY RESULTADO.\n\n      *    Division\n           DIVIDE NUM1 BY NUM2 GIVING RESULTADO.\n           DISPLAY RESULTADO.\n\n      *    -OPERACIONES LOGICAS\n      *    And\n           IF NUM1 > NUM2 AND NUM2 < NUM3\n               DISPLAY \"Se cumple\"\n\n      *    Or\n           IF NUM1 > NUM2 OR NUM2 < NUM3\n               DISPLAY \"Se cumple\"\n\n      *    Is not\n           IF NUM1 IS NOT > 19\n               DISPLAY \"Se cumple\"\n\n      *    -OPERACIONES DE COMPARACION\n      *    Igual con varias opciones\n           IF NUM1 = 2\n               DISPLAY \"Se cumple\"\n           IF NUM1 EQUAL TO 2\n               DISPLAY \"Se cumple\"\n           IF NUM1 EQUAL 2\n               DISPLAY \"Se cumple\"\n\n      *    Menor que\n           IF NUM1 < 2\n               DISPLAY \"Se cumple\"\n\n      *    Menor o igual\n           IF NUM1 <= 2\n               DISPLAY \"Se cumple\"\n\n      *    Mayor que\n           IF NUM1 > 2\n               DISPLAY \"Se cumple\"\n\n      *    Mayor o igual\n           IF NUM1 >= 2\n               DISPLAY \"Se cumple\"\n\n      *    -ASIGNACION\n           MOVE 7 TO NUM2.\n           DISPLAY NUM2.\n\n       ESTRUCTURAS-CONTROL.\n      *    -CONDICIONALES\n      *    If\n           IF NUM1 = NUM3\n               DISPLAY \"Numeros iguales\".\n      *    Se puede finalizar con un punto o con END-IF\n\n      *    If con else\n           IF NUM1 = NUM2\n               DISPLAY \"Numeros iguales\"\n           ELSE\n               DISPLAY \"Numeros diferentes\".\n\n      *    Anidaciones\n           IF NUM1 = NUM3\n               DISPLAY \"Numeros iguales\"\n                   IF NUM1 = NUM2\n                       DISPLAY \"Todos los numeros iguales\"\n                   ELSE\n                       DISPLAY \"Numeros 1 y 3 iguales pero diferentes \"-\n                       \"con 2\"\n           ELSE\n               DISPLAY \"Numeros 1 y 3 diferentes\".\n\n      *    Evaluate\n           EVALUATE NUM1\n\n               WHEN 1 THRU 5\n               DISPLAY \"Numero entre los primeros 5\"\n\n               WHEN 6 THRU 10\n               DISPLAY \"Numero entre 6 y 10\"\n\n               WHEN OTHER\n               DISPLAY \"Numero fuera de rango\"\n\n           END-EVALUATE.\n\n      *    Evaluate true\n           DISPLAY \"Introduce un numero\".\n           ACCEPT NUMERO.\n\n           EVALUATE TRUE\n\n               WHEN UNA-CIFRA\n               DISPLAY \"El numero tiene una cifra\"\n\n               WHEN DOS-CIFRAS\n               DISPLAY \"El numero tiene dos cifras\"\n\n               WHEN TRES-CIFRAS\n               DISPLAY \"El numero tiene tres cifras\"\n\n               WHEN OTHER\n               DISPLAY \"El numero tiene mas de tres cifras\"\n\n           END-EVALUATE.\n\n      *    -ITERATIVAS\n      *    Perform times\n       REPETIR.\n           PERFORM 3 TIMES\n               DISPLAY \"Hola\"\n           END-PERFORM.\n\n      *    Necesario para los siguientes ejemplos\n       SALUDO.\n           DISPLAY \"Hola \" NUM-SALUDO.\n           ADD 1 TO NUM-SALUDO.\n           STOP-RUN.\n\n       SALUDO2.\n           DISPLAY \"Hola \" NUM-SALUDO.\n\n      *    While\n       WHILE.\n           PERFORM SALUDO WITH TEST BEFORE UNTIL NUM-SALUDO = 10.\n\n      *    Do-While\n           MOVE 7 TO NUM-SALUDO.\n       DO-WHILE.\n           PERFORM SALUDO WITH TEST AFTER UNTIL NUM-SALUDO = 10.\n\n      *    For\n           PERFORM SALUDO2 VARYING NUM-SALUDO FROM 0 BY 1 UNTIL\n           NUM-SALUDO = 10.\n           STOP-RUN.\n\n       EXTRA.\n           DIVIDE NUM-EXTRA BY 3 GIVING RESULTADO REMAINDER RESTO.\n           IF NUM-EXTRA NOT EQUAL 16 AND RESTO NOT EQUAL 0\n               DISPLAY NUM-EXTRA.\n\n       BUCLE.\n           DISPLAY \"Los numeros comprendidos entre 10 y 55(incluidos),\"-\n           \"pares, y que no son ni el 16 ni multiplos de 3 son:\"\n           PERFORM EXTRA VARYING NUM-EXTRA FROM 10 BY 2 UNTIL\n           NUM-EXTRA = 54.\n           STOP-RUN.\n\n       END PROGRAM RETO-02.\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/cobol/keltoi-dev.cbl",
    "content": "      * EJERCICIO:\n      * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n      *   Aritmticos, lgicos, de comparacin, asignacin, identidad, pertenencia, bits...\n      *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n      * - Utilizando las operaciones con operadores que t quieras, crea ejemplos\n      *   que representen todos los tipos de estructuras de control que existan\n      *   en tu lenguaje:\n      *   Condicionales, iterativas, excepciones...\n      * - Debes hacer print por consola del resultado de todos los ejemplos.\n      *\n      * DIFICULTAD EXTRA (opcional):\n      * Crea un programa que imprima por consola todos los nmeros comprendidos\n      * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni mltiplos de 3.\n\n       IDENTIFICATION DIVISION.\n       PROGRAM-ID. RETO-01.\n       DATA DIVISION.\n       FILE SECTION.\n       WORKING-STORAGE SECTION.\n       77  A PIC 99 VALUE 10.\n       77  B PIC 99 VALUE 5.\n       77  C PIC 99 VALUE 2.\n       77  resultado PIC 9(4) VALUE ZERO.\n       77  decimales PIC 99V99 VALUE ZERO.\n       77  I PIC 99 VALUE ZERO.\n       77  signo PIC S99 VALUE -15.\n\n       PROCEDURE DIVISION.\n       Aritmeticos.\n      * Suma\n           ADD A TO B GIVING resultado.\n           DISPLAY A \" + \" B \" = \" resultado.\n      * Resta\n           SUBTRACT A FROM B GIVING resultado.\n           DISPLAY A \" - \" B \" = \" resultado.\n      * Multiplicacion\n           MULTIPLY A BY C GIVING resultado.\n           DISPLAY A \" * \" C \" = \" resultado.\n      * Division\n           DIVIDE B BY C GIVING decimales.\n           DISPLAY B \" / \" C \" = \" decimales.\n      * Division entera\n           DIVIDE B BY C GIVING resultado.\n           DISPLAY \"El valor entero de \" B \" / \" C \" = \" resultado.\n      * Modulo (Resto)\n           DIVIDE A BY 3 GIVING resultado REMAINDER decimales.\n           DISPLAY \"El resto de \" A \" / 3 = \" decimales.\n      * Calculos varios\n           COMPUTE resultado = (A + B - C) * 4 / C.\n           DISPLAY \"(\" A \" + \" B \" - \" C \") * 4 / \" C \" = \" resultado.\n\n      * Operadores de asigancion\n           MOVE A TO resultado.\n           DISPLAY \"Ahora resultado vale: \" resultado.\n      * Operadores de comparacion\n      * A IS EQUAL TO 10 o A = 10\n      * A IS NOT EQUAL TO 10 o A <> 10\n      * A IS GREATER TO 10 o A > 10\n      * A IS LESS TO 10 o A < 10\n      * A IS EQUAL OR GREATER TO 10 o A >= 10\n      * A IS EQUAL OR LESS TO 10 o A <=  10\n\n      * Operadores logicos\n      * AND\n      * OR\n\n      * Estructuras de control\n       Condicionales.\n      * IF ... ELSE\n           DISPLAY \"IF ... ELSE\".\n           IF A IS EQUAL TO 10\n               DISPLAY \"Es igual a 10\"\n           ELSE\n               DISPLAY \"No es igual a 10\"\n           END-IF.\n\n      * IF anidados\n           DISPLAY \"IF anidados\".\n           IF A > 9 AND B < 9\n               DISPLAY \"Se cumplen las dos condiciones\"\n           ELSE\n               IF A > 9 OR C > 9\n                   DISPLAY \"Se cumple al menos una de las opciones\"\n               ELSE\n                   DISPLAY \"No se cumple ninguna de las opciones\"\n               END-IF\n           END-IF.\n\n      * IF de signos\n           DISPLAY \"IF de signos\".\n           IF C IS POSITIVE\n               DISPLAY \"El valor es positivo\".\n\n      * IF de clase\n           DISPLAY \"IF de clase\".\n           IF B IS NUMERIC\n               DISPLAY \"El valor es numerico\".\n\n           IF A IS ALPHABETIC OR A IS ALPHABETIC-LOWER\n               OR A IS ALPHABETIC-UPPER\n               DISPLAY \"El valor es una letra\"\n           ELSE\n               DISPLAY \"El valor es un numero\".\n\n      * Evaluate\n           DISPLAY \"Evaluate\".\n           EVALUATE signo\n\n               WHEN > 1\n                   DISPLAY \"El valor es positivo\"\n\n               WHEN < 0\n                   DISPLAY \"El valor es negativo\"\n\n               WHEN OTHER\n                   DISPLAY \"El valor es cero\"\n\n           END-EVALUATE.\n\n\n      * Bucles\n      * Equivalente al for en otros lenguajes\n           PERFORM 10 TIMES\n               DISPLAY \"-*\" WITH NO ADVANCING\n           END-PERFORM.\n\n           DISPLAY \" \".\n           DISPLAY \"Perform Varying\".\n\n           PERFORM Bucle VARYING I FROM 1 BY 1 UNTIL I > 9.\n\n           MOVE 0 to I.\n           DISPLAY \" \".\n           DISPLAY \"While\".\n\n      * While\n           PERFORM Bucle-While WITH TEST BEFORE\n           UNTIL I = 10.\n\n           MOVE 0 to I.\n           DISPLAY \" \".\n           DISPLAY \"Do while\".\n\n      * Do Ahile\n           PERFORM Bucle-While WITH TEST AFTER\n           UNTIL I = 10.\n\n\n      * DIFICULTAD EXTRA\n       Dificultad-extra.\n           DISPLAY \" \"\n           DISPLAY \"----- DIFICULTAD EXTRA -----\".\n           PERFORM Calculo VARYING I FROM 10 BY 2 UNTIL I > 55.\n\n           STOP RUN.\n\n       Calculo.\n           DIVIDE I BY 3 GIVING B REMAINDER C.\n           IF C NOT = 0 AND I NOT = 16\n               DISPLAY I.\n\n\n      * Rutinas para bucles varios\n       Bucle.\n           DISPLAY I \" \" WITH NO ADVANCING.\n\n       Bucle-While.\n           ADD 1 TO I.\n           DISPLAY I \" \" WITH NO ADVANCING.\n\n\n       END PROGRAM RETO-01.\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/cobol/llonardo798.cbl",
    "content": "      * TEST: https://www.jdoodle.com/execute-cobol-online CAMBIAR ESPACIOS AL\n      * INICIO POR TABULACIONES\n      * EJERCICIO:\n      * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n      *   Aritméticos, lógicos, de comparación, asignación, identidad, \n      *   pertenencia, bits... (Ten en cuenta que cada lenguaje puede poseer \n      *   unos diferentes)\n      * - Utilizando las operaciones con operadores que tú quieras, crea \n      *   ejemplos que representen todos los tipos de estructuras de control que\n      *   existan en tu lenguaje:\n      *   Condicionales, iterativas, excepciones...\n      * - Debes hacer print por consola del resultado de todos los ejemplos.\n      *\n      *DIFICULTAD EXTRA (opcional):\n      *Crea un programa que imprima por consola todos los números comprendidos\n      *entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3\n\n       IDENTIFICATION DIVISION.\n       PROGRAM-ID. ROADMAP-MIDUDEV-01.\n       AUTHOR. LLONARDO798.\n       DATA DIVISION.\n       FILE SECTION.\n       WORKING-STORAGE SECTION.\n\n       01 NUMEROS.\n           03 NUM1 PIC 99 VALUE 10.\n           03 NUM2 PIC 9 VALUE 5.\n           03 NUM3 PIC 9 VALUE 3.\n           03 COPIA PIC 9.\n           03 TOTAL PIC 99.\n           03 TOTALEXP PIC 999999.\n\n       01 OTROS.\n           03 COPIA PIC 9(3).\n           03 MENSAJE PIC X(50).\n\n       01 I PIC 99.\n    \n         \n\n       PROCEDURE DIVISION.\n       MAIN-PROCEDURE.\n      *1. Operadores Aritméticos\n           COMPUTE TOTAL = NUM1 + NUM2. *> Operador de suma\n           DISPLAY \"SUMA: \" TOTAL. *> 15\n\n           COMPUTE TOTAL = NUM1 - NUM2. *> Operador de resta\n           DISPLAY \"RESTA: \" TOTAL. *> 5\n\n           COMPUTE TOTAL = NUM1 * NUM2. *> Operador de multiplicación\n           DISPLAY \"MULTIPLICACIÓN: \" TOTAL. *> 50\n\n           COMPUTE TOTAL = NUM1 / NUM2. *> Operador de división\n           DISPLAY \"DIVISIÓN: \" TOTAL. *> 2\n\n           COMPUTE TOTALEXP = NUM1 ** NUM2. *> Operador de exponenciación\n           DISPLAY \"EXPONENCIACIÓN: \" TOTALEXP. *> 100000\n\n           *> No es una operación aritmética, pero como función se puede usar\n           *> para obtener el resto de una división\n           COMPUTE TOTAL = FUNCTION MOD(NUM1, NUM3). \n            DISPLAY \"RESTO: \" TOTAL. *> 1\n\n      *2. Operadores Relacionales - Ejemplos usando IF\n\n           IF NUM1 = NUM2 THEN\n               DISPLAY \"NUM1 es igual a NUM2\"\n           ELSE\n                DISPLAY \"NUM1 no es igual a NUM2\"\n           END-IF.\n\n           IF NUM1 > NUM2 THEN\n               DISPLAY \"NUM1 es mayor que NUM2\"\n           ELSE\n                DISPLAY \"NUM1 no es mayor que NUM2\"\n           END-IF.\n\n           IF NUM1 < NUM2 THEN\n             DISPLAY \"NUM1 es menor que NUM2\"\n           ELSE\n              DISPLAY \"NUM1 no es menor que NUM2\"\n           END-IF.\n\n           IF NUM1 >= NUM2 THEN\n               DISPLAY \"NUM1 es mayor o igual que NUM2\"\n           ELSE\n                DISPLAY \"NUM1 no es mayor o igual que NUM2\"\n           END-IF.\n\n           IF NUM1 <= NUM2 THEN\n           DISPLAY \"NUM1 es menor o igual que NUM2\"\n           ELSE\n               DISPLAY \"NUM1 no es menor o igual que NUM2\"\n           END-IF.\n\n           IF NUM1 <> NUM2 THEN\n           DISPLAY \"NUM1 es distinto de NUM2\"\n           ELSE\n               DISPLAY \"NUM1 no es distinto de NUM2\"\n           END-IF.\n\n      *3. Operadores Lógicos\n           \n           IF NUM1 = NUM2 AND NUM1 > NUM3 THEN\n             DISPLAY \"NUM1 es igual a NUM2 y mayor que NUM3\"\n           ELSE\n              DISPLAY \"NUM1 no es igual a NUM2 y mayor que NUM3\"\n           END-IF.\n    \n           IF NUM1 = NUM2 OR NUM1 > NUM3 THEN\n             DISPLAY \"NUM1 es igual a NUM2 o mayor que NUM3\"\n           ELSE\n              DISPLAY \"NUM1 no es igual a NUM2 o mayor que NUM3\"\n           END-IF.\n\n           IF NOT NUM2 = 1  *> Se niega la condición\n             DISPLAY \"NUM 2 no es igual a 1\"\n           ELSE\n             DISPLAY \"NUM 2 es igual a 1\"\n           END-IF.\n           \n\n      *4. Otros Operadores\n           \n           MOVE 30 TO NUM1. *> Asignación usando MOVE\n           DISPLAY \"NUM1 Despues del MOVE: \" NUM1.\n           COMPUTE TOTAL = 25*2. *> Se calcula el valor usando COMPUTE\n           DISPLAY \"NUM1 Despues del COMPUTE: \" NUM1.\n\n           MOVE 17 TO COPIA OF OTROS.    \n           *> Aunque se tienen dos variables con el mismo nombre en diferentes\n           *> grupos, se puede acceder a la variable COPIA del grupo OTROS\n\n\n      * DIFICULTAD EXTRA - Crea un programa que imprima por consola todos los \n      * números comprendidos entre 10 y 55 (incluidos) pares, y que no son ni el\n      * 16 ni múltiplos de 3.\n\n           PERFORM PRINT-NUMBERS VARYING I FROM 10 BY 2 UNTIL I > 55.\n\n\n           STOP RUN.\n\n       PRINT-NUMBERS.\n           IF I <> 16 AND FUNCTION MOD(I, 3) <> 0 THEN\n             DISPLAY I.\n\n       END PROGRAM ROADMAP-MIDUDEV-01."
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/d/ElHacedorDeCosas.d",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\nvoid main()\n{\n    import std.stdio: writeln;\n\n    // - Operadores - //\n    writeln(\"\\n___Operadores___\");\n\n    float a = 70f;\n    float b = 30f;\n    writeln(\"a = \", a, \", b = \", b);\n\n    // Operadores aritmeticos\n    writeln(\"Suma: a + b = \", (a + b));\n    writeln(\"Resta: a - b = \", (a - b));\n    writeln(\"Multiplicación: a * b = \", (a * b));\n    writeln(\"División: a / b = \", (a / b));\n    writeln(\"Resto: a % b = \", (a % b));\n    writeln(\"Exponencial: a^^b = \", cast(int)(a^^b));\n    writeln(\"Exponencial: a^^b = \", (a^^b));\n    writeln(\"Incremento: ++a = \", (++a));\n    writeln(\"Decremento: --b = \", (--b));\n\n    // Operadores de comparación\n    writeln(\"Igual: a == b = \", (a == b));\n    writeln(\"Distinto: a != b = \", (a != b));\n    writeln(\"Mayor: a > b = \", (a > b));\n    writeln(\"Menor: a < b = \", (a < b));\n    writeln(\"Mayor o igual: a >= b = \", (a >= b));\n    writeln(\"Menor o igual: a <= b = \", (a <= b));\n\n    // Operadores logicos\n    writeln(\"and: a > 12 && b > 100 = \", (a > 12 && b > 100));\n    writeln(\"or: a > 12 || b > 100 = \", (a > 12 || b > 2));\n    writeln(\"not: !(a < b) = \", !(a < b));\n\n    // Operadores de asignación\n    writeln(\"a += b ; a = \", (a += b));\n    writeln(\"a -= b ; a = \", (a -= b));\n    writeln(\"a *= b ; a = \", (a *= b));\n    writeln(\"a /= b ; a = \", (a /= b));\n    writeln(\"a %= b ; a = \", (a %= b));\n    writeln(\"a ^^= b ; a = \", (a ^^= b));\n\n\n    // - Control de flujo - //\n    writeln(\"\\n___Control de flujo___\");\n\n    // Condicionales (if, else if, else)\n    if (b < 10)\n    {\n        writeln(\"b es mayor que c\");\n    }\n    else if (a > b)\n    {\n        writeln(\"a es mayor que b\");\n    }\n    else\n    {\n        writeln(\"Nada de lo anterior se cumple\");\n    }\n\n    // Bucle for\n    for (int e = 0; e < b; e++)\n    {\n        writeln(\"\\'e\\' en este momento vale: \", e);\n    }\n\n    // Bucle while\n    int q = 0;\n    while (q != 10)\n    {\n        writeln(\"q = \", q);\n        q += 1; // en este caso es lo mismo que hacer q++;\n    }\n\n    // Bucle do while\n    int p = 0;\n    do\n    {\n        writeln(\"p aún no es igual a 10\");\n    }while (++p != 10);\n\n    // Bucle switch\n    string z = \"D\";\n    switch (z)\n    {\n    case \"C\":\n        writeln(\"\\'C\\' Un buen lenguaje\");\n        break;\n    case \"C++\":\n        writeln(\"\\'C++\\' Un horrible lenguaje\");\n        break;\n    case \"D\":\n        writeln(\"\\'D\\' El mejor lenguaje\");\n        break;\n    default:\n        break;\n    }\n\n    // Bucle foreach\n    string saludo = \"Hola\";\n    foreach (letra; saludo)\n    {\n        writeln(letra);\n    }\n\n\n    // - Ejercicio extra - //\n    writeln(\"\\n___Ejercicio Extra___\");\n    extra();\n}\n\nvoid extra()\n{\n    import std.stdio: writeln; // En D se prefiere la importación de librerias a nivel local (de función)\n                               // en lugar de importaciones globales, además de importar especificamente\n                               // los simbolos que se van a utilizar, aunque esto solo es preferencia y no es obligatorio\n\n    for (int i = 10; i < 56; i++)\n    {\n        if (i == 16)\n        {\n            continue;\n        }\n        else if ((i % 3) == 0)\n        {\n            continue;\n        }\n        else if ((i % 2) == 0)\n        {\n            writeln(i);\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/dart/D3rk1us.dart",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\nvoid main() {\n  \n  var a, b, c, f, g;\n  bool d, e;\n\n  // Asignación\n\n  a = 14;\n  b = 40;\n\n  d = true;\n  e = false;\n\n  f = Object();\n  g = Object();\n\n  // Aritméticos\n\n  c = a + b;\n  print(c);\n\n  c = b - a;\n  print(c);\n\n  c = a / b;\n  print(c);\n\n  c = a % b;\n  print(c);\n\n  // Lógicos\n\n  c = !d;\n  print(c);\n\n  c = d || e;\n  print(c);\n\n  c = e && d;\n  print(c);\n\n  // Comparación\n\n  c = a > b;\n  print(c);\n\n  c = a < b;\n  print(c);\n\n  c = a == b;\n  print(c);\n\n  c = a != b;\n  print(c);\n\n  c = a <= b;\n  print(c);\n\n  c = a >= b;\n  print(c);\n\n  // Identidad\n\n  print(f is int);\n  print(g is! Object);\n  \n  // Condicionales\n\n    c = a < b ? \"True\" : \"False\";\n    print(c);\n\n    c = a ?? b; // Si el valor de \"a\" fuera null, devuelve el valor de \"b\".\n    print(c);\n\n\n  /*\n    * DIFICULTAD EXTRA (opcional):\n    * Crea un programa que imprima por consola todos los números comprendidos\n    * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n  */\n\n  print(\"-------------------------------------------------\");\n\n  for (var i = 10; i <= 55; i++ ) {\n\n    if (i % 2 == 0 && i != 16 && i % 3 != 0) {\n      print(i);\n    }\n  }\n\n}\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/dart/Lia-M3dusa.dart",
    "content": "void main() {\n  // Operadores Aritméticos\n  int a = 10, b = 3;\n  print(\"Aritméticos:\");\n  print(\"Suma: \\${a + b}\");\n  print(\"Resta: \\${a - b}\");\n  print(\"Multiplicación: \\${a * b}\");\n  print(\"División: \\${a / b}\");\n  print(\"División Entera: \\${a ~/ b}\");\n  print(\"Módulo: \\${a % b}\");\n\n  // Operadores Lógicos\n  bool x = true, y = false;\n  print(\"\\nLógicos:\");\n  print(\"AND: \\${x && y}\");\n  print(\"OR: \\${x || y}\");\n  print(\"NOT: \\${!x}\");\n\n  // Operadores de Comparación\n  print(\"\\nComparación:\");\n  print(\"Igualdad: \\${a == b}\");\n  print(\"Desigualdad: \\${a != b}\");\n  print(\"Mayor que: \\${a > b}\");\n  print(\"Menor que: \\${a < b}\");\n  print(\"Mayor o igual: \\${a >= b}\");\n  print(\"Menor o igual: \\${a <= b}\");\n\n  // Operadores de Asignación\n  int c = 5;\n  print(\"\\nAsignación:\");\n  print(\"Inicial: \\${c}\");\n  c += 3;\n  print(\"Suma y asigna: \\${c}\");\n  c *= 2;\n  print(\"Multiplica y asigna: \\${c}\");\n\n  // Operadores de Identidad\n  print(\"\\nIdentidad:\");\n  print(\"Idéntico: \\${a == 10}\");\n  print(\"No Idéntico: \\${b != 10}\");\n\n  // Operadores de Bits\n  print(\"\\nBits:\");\n  print(\"AND binario: \\${a && b}\");\n  print(\"OR binario: \\${a || b}\");\n  print(\"XOR binario: \\${a ^ b}\");\n  print(\"Desplazamiento izquierda: \\${a << 1}\");\n  print(\"Desplazamiento derecha: \\${a >> 1}\");\n\n  // Estructuras de Control: Condicionales\n  print(\"\\nCondicionales:\");\n  if (a > b) {\n    print(\"a es mayor que b\");\n  } else {\n    print(\"a no es mayor que b\");\n  }\n\n  // Estructuras de Control: Iterativas\n  print(\"\\nIterativas:\");\n  print(\"Bucle For:\");\n  for (int i = 0; i < 5; i++) {\n    print(\"i: \\${i}\");\n  }\n\n  print(\"Bucle While:\");\n  int count = 0;\n  while (count < 3) {\n    print(\"count: \\${count}\");\n    count++;\n  }\n\n  print(\"Bucle Do-While:\");\n  int num = 0;\n  do {\n    print(\"num: \\${num}\");\n    num++;\n  } while (num < 2);\n\n  // Estructuras de Control: Excepciones\n  print(\"\\nExcepciones:\");\n  try {\n    int result = a ~/ 0;\n    print(\"Resultado: \\${result}\");\n  } catch (e) {\n    print(\"Error: División por cero\");\n  } finally {\n    print(\"Bloque finally ejecutado\");\n  }\n\n  // Dificultad Extra\n  print(\"\\nNúmeros entre 10 y 55 (pares, no 16 ni múltiplos de 3):\");\n  for(int i = 10; i<=55;i++){\n    if(i == 16 || i % 3 == 0){\n      continue;\n    }\n    if(i.isEven){\n      print(\"\\${i}\");\n    }   \n  }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/dart/angelsanchezt.dart",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\nvoid main() {\n  // Operadores\n  // Aritméticos\n  int suma = 5 + 3;\n  int resta = 8 - 2;\n  double division = 10 / 2;\n  int multiplicacion = 4 * 6;\n  int modulo = 15 % 4;\n\n  // Lógicos\n  bool and = true && false;\n  bool or = true || false;\n  bool not = !true;\n\n  // De comparación\n  bool igual = 5 == 5;\n  bool noIgual = 5 != 3;\n  bool mayorQue = 8 > 3;\n  bool menorQue = 4 < 7;\n  bool mayorIgual = 10 >= 10;\n  bool menorIgual = 3 <= 5;\n\n  // De asignación\n  int x = 10;\n  x += 5; // x = x + 5\n\n  // De identidad\n  String texto1 = \"Hola\";\n  String texto2 = \"Hola\";\n  bool identico = identical(texto1, texto2);\n\n  // De pertenencia\n  List<int> lista = [1, 2, 3, 4, 5];\n  bool contiene = lista.contains(3);\n\n  // Bits\n  int a = 5; // Representado en binario como 0101\n  int b = 3; // Representado en binario como 0011\n  int resultadoBits = a & b; // AND bits: 0001\n\n  print(\"Operadores:\");\n  print(\"Aritméticos: $suma, $resta, $division, $multiplicacion, $modulo\");\n  print(\"Lógicos: $and, $or, $not\");\n  print(\"De comparación: $igual, $noIgual, $mayorQue, $menorQue, $mayorIgual, $menorIgual\");\n  print(\"De asignación: $x\");\n  print(\"De identidad: $identico\");\n  print(\"De pertenencia: $contiene\");\n  print(\"Bits: $resultadoBits\");\n\n  // Estructuras de control\n  // Condicionales\n  if (x > 12) {\n    print(\"x es mayor que 12\");\n  } else if (x == 12) {\n    print(\"x es igual a 12\");\n  } else {\n    print(\"x es menor que 12\");\n  }\n\n  // Iterativas\n  for (int i = 10; i <= 55; i++) {\n    if (i % 2 == 0 && i != 16 && i % 3 != 0) {\n      print(\"Número válido: $i\");\n    }\n  }\n\n  // Excepciones\n  try {\n    int resultadoDivisionPorCero = 5 ~/ 0; // Intento de división por cero\n    print(\"Este mensaje no se imprimirá $resultadoDivisionPorCero\");\n  } catch (e) {\n    print(\"Error: $e\");\n  }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/dart/bluefeatherdev.dart",
    "content": "// ignore_for_file: unnecessary_type_check, dead_code, unnecessary_null_comparison\n\n/*\n* EJERCICIO:\n* - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n*   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n*   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n* - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n*   que representen todos los tipos de estructuras de control que existan\n*   en tu lenguaje:\n*   Condicionales, iterativas, excepciones...\n* - Debes hacer print por consola del resultado de todos los ejemplos.\n*\n* DIFICULTAD EXTRA (opcional):\n* Crea un programa que imprima por consola todos los números comprendidos\n* entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n*\n* Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n*/\n\nvoid main() {\n  /// ------- [Operadores] del lenguaje Dart -------\n  \n  // Operadores aritméticos\n  num a = 2;\n  num b = 3;\n\n  num miSuma = a + b;\n  num miResta = a - b;\n  num miReverso = -a;\n  num miProducto = a * b;\n  num miDivision = a / b;\n  num miDivisionEntera = a ~/ b;\n  num miModulo = a % b;\n\n  print('Suma: $miSuma');\n  print('Resta: $miResta');\n  print('Reverso: $miReverso');\n  print('Producto: $miProducto');\n  print('División: $miDivision');\n  print('División entera: $miDivisionEntera');\n  print('Módulo: $miModulo');\n\n  // Operadores prefix y profix\n  int x;\n  int y;\n\n  x = 0;\n  y = ++x;  // Incrementa x ANTES de asignar valor y\n  print(x == y);  // 1 == 1\n\n  x = 0;\n  y = x++;  // Incrementa x DESPUÉS de asignar valor y\n  print(x == y);  // 1 != 0\n\n  x = 0;\n  y = --x;  // Decrementa x ANTES de asignar valor y\n  print(x == y);  // -1 == -1\n\n  x = 0;\n  y = x--;  // Decrementa x DESPUÉS de asignar valor y\n  print(x == y);  // 0 == -1\n\n  // Operadores de igualdad y relacionales\n  print(a == b);  // Igual que\n  print(a != b);  // Diferente que\n  print(a > b); // Mayor que\n  print(a < b); // Menor que\n  print(a >= b);  // Mayor o igual que\n  print(a <= b);  // Menor o igual que\n\n  // Operadores de testeo de tipos\n  dynamic miValor = 46;\n\n  print(miValor is int);      // true\n  print(miValor is double);   // false\n  print(miValor is num);      // true\n  print(miValor is String);   // false\n\n  print(miValor is! int);      // false\n  print(miValor is! double);   // true\n  print(miValor is! num);      // false\n  print(miValor is! String);   // true\n\n  var miNumero = miValor as int;  /// `as` para casting seguro\n  print(miNumero + 10); // 56\n\n  // Operadores de asignación\n  int miInt = 1;\n  num miNum = 1;\n\n  print(miNum = 2);    /// `=` : miNum = value : asignación simple\n  print(miNum += 2);   /// `+=` : miNum = miNum + value : asignación con suma\n  print(miNum -= 2);   /// `-=` : miNum = miNum - value : asignación con resta\n  print(miNum *= 2);   /// `*=` : miNum = miNum * value : asignación con multiplicación\n  print(miNum /= 2);   /// `/=` : miNum = miNum / value : asignación con división\n  print(miNum %= 2);   /// `%=` : miNum = miNum % value : asignación con módulo\n  print(miInt ^= 2);   /// `^=` : miInt = miInt ^ value : asignación con XOR \n  print(miInt >>>= 2); /// `>>>=` : miInt = miInt >>> value : asignación con shift sin signo a la derecha\n  print(miInt <<= 2);  /// `<<=` : miInt = miInt << value : asignación con desplazamiento a la izquierda\n  print(miInt >>= 2);  /// `>>=` : miInt = miInt >> value : asignación con desplazamiento a la derecha\n  print(miInt &= 2);   /// `&=` : miInt = miInt & value : asignación con AND\n  print(miInt |= 2);   /// `|=` : miInt = miInt | value : asignación con OR\n  print(miNum ~/= 2);  /// `~/=` : miNum = miNum ~/ value : asignación con división entera\n\n  // Operadores lógicos\n  bool c = true;\n  bool d = false;\n\n  print(!c);      /// `!` : Invertir valor booleano\n  print(c || d);  /// `||` : OR\n  print(c && d);  /// `&&` : AND\n\n  // Operadores de bits y shifts\n  final miValorBit = 0x22;\n  final miMascaraBit = 0x0f;\n\n  print(miValorBit & miMascaraBit);  /// `&` : AND\n  print(miValorBit & ~miMascaraBit); /// `& ~` : AND NOT\n  print(miValorBit | miMascaraBit);  /// `|` : OR\n  print(miValorBit ^ miMascaraBit);  /// `^` : XOR\n\n  print(miValorBit << 4);  /// `<<` : Shift left\n  print(miValorBit >> 4);  /// `>>` : Shift right\n  print(miValorBit >>> 4); /// `>>>` : Unsigned shift right\n  print(-miValorBit >>> 4);  /// `>>>` : Unsigned shift right\n\n  // Operadores para expresiones condicionales\n\n  /// condition `?` true `:` false\n  var esPublico = true;\n  var visibilidad = esPublico ? 'public' : 'private';\n  print(visibilidad); // Imprime: 'public'\n\n  /// expr1 `??` expr2\n  String userName(String? name) => name ?? 'Guest';\n  print(userName('Jesús')); // Imprime: Jesús\n  print(userName(null));  // Imprime: Guest\n\n  /// Un poco más verboso con `?` y `:`\n  String userName2(String? name) =>\n    name != null ? name : 'Guest';\n  print(userName2('Jesús')); // Imprime: Jesús\n  print(userName2(null));  // Imprime: Guest\n\n  // Operadores de notación cascada\n  var miBuffer = StringBuffer();\n  miBuffer.write('¡Hola');  /// Sin operadores\n  miBuffer.write(', ');     /// de\n  miBuffer.write('Dart!');  /// notación cascada\n  print(miBuffer);  // Imprime: ¡Hola, Dart!\n\n  var miOtroBuffer = StringBuffer()\n    ..write('¡Hola')  /// `..`\n    ..write(', ')\n    ..write('Dart!');\n  print(miOtroBuffer);  // Imprime: ¡Hola, Dart!\n\n  StringBuffer? miNullableBuffer;\n  miNullableBuffer\n    ?..write('¡Hola') /// `?..`\n    ..write(', ')\n    ..write('Dart!');\n  print(miNullableBuffer);  // Imprime: null\n\n  // Operadores de propagación\n  var e = [10, 20, 30];\n  var f = [40, 50, 60];\n  print([...e + f]);  // [10, 20, 30, 40, 50, 60]\n\n  // Operadores de identidad (no existen, es una función de alto nivel)\n  var g = [1, 2, 3];\n  var h = g;\n  var i = [1, 2, 3];\n\n  print(identical(g, h)); // true : misma instancia\n  print(identical(g, i)); // false : mismo contenido, instancia distinta\n  print(g == i);  // true : igualdad de contenido\n\n  // Operadores de pertenencia (no existen, son métodos de colecciones)\n  var miLista = [10, 20, 30];\n  var miMapa = {'a': 1, 'b': 2};\n\n  print(miLista.contains(20));  // true\n  print(miMapa.containsKey('a')); // true\n  print(miMapa.containsValue(3)); // false\n\n  /// ------- [Estructuras de control] de lenguaje Dart -------\n  \n  // For loop\n  for (var i = 0; i < 5; i++) {\n    print('i: $i');\n  }\n\n  var frutas = ['manzana', 'banana', 'naranja'];\n  for (var fruta in frutas) print(fruta);\n\n  // ForEach\n  var miColeccion = [1, 2, 3];\n  miColeccion.forEach(print);\n\n  // While loop\n  var j = 0;\n  while (j < 5) {\n    print('j: $j');\n    j++;\n  }\n\n  var k = 0;\n  while (k < frutas.length) {\n    print(frutas[k]);\n    k++;\n  }\n\n  // Do while loop\n  var l = 0;\n  do {\n    print('l: $l');\n    l++;\n  } while (l < 5);\n\n  var m = 0;\n  do {\n    print(frutas[m]);\n    m++;\n  } while (m < frutas.length);\n\n  // if\n  var isRaining = true;\n  if (isRaining) {\n    print('Está lloviendo ☔');\n  }\n\n  // if else\n  var userAge = 15;\n  if (userAge >= 18) {\n    print('¡Puedes conducir!');\n  } else {\n    print('Debes ser mayor de edad');\n  }\n\n  // if else if \n  isRaining = false;\n  var isSnowing = true;\n  if (isRaining) {\n    print('Está lloviendo ☔');\n  } else if (isSnowing) {\n    print('Está nevando ❄️');\n  } else {\n    print('Cielo despejado ⛅');\n  }\n\n  // if case\n  var par = [1, 2];\n  if (par case [int x, int y]) {\n    print('$x, $y');\n  }\n\n  // Switch\n  bool? nullableBool = null;\n  switch (nullableBool) {\n    case true:\n      print('yes');\n    case false:\n      print('no');\n    default:\n      print('null accepted');\n  }\n\n  /// Throw\n  /// ```dart\n  /// throw FormatException('Some text');\n  /// throw 'Out of llamas!';\n  /// ``` \n  \n  /// Try\n  /// ```dart\n  /// try {\n  ///   dynamic foo = true;\n  ///   print(foo++);\n  /// } catch (e) {\n  ///   print('Error: $e');\n  /// } finally {\n  ///   print('It\\'s done');\n  /// }\n  /// ```\n  \n  // assert\n  var myText = 'abc';\n  assert(myText != null, 'Text must be not null');\n  print(myText != null);  // true\n\n  /// ------- [Programa extra] en Dart -------\n  \n  /// Números pares entre 10 y 55 incluidos,\n  /// Sin el 16 y sin múltiplos de 3:\n  for (var i = 10; i < 56; i++) {\n    if ((i % 2 == 0 && !(i % 3 == 0)) || i == 55) {\n      if (i != 16) {\n        print(i);\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/dart/cristiansystem.dart",
    "content": "/*\n * #01 - Operadores y estructruas de control\n * https://dart.dev/language/operators\n*/\n\nvoid main() {\n  print('Arithmetic Operations\\n');\n  arithmeticOperators();\n  print('- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\\n');\n\n  print('Increment/Decrement Operations\\n');\n  incrementDecrementOperators();\n  print('- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\\n');\n\n  print('Equality And Relational Operations\\n');\n  equalityAndRelationalOperators();\n  print('- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\\n');\n\n  print('Type Operators\\n');\n  typesOperators();\n  print('- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\\n');\n\n  print('Logic Operators\\n');\n  logicalOperators();\n  print('- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\\n');\n\n  print('Conditional Expressions\\n');\n  conditionalExpressions();\n  print('- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\\n');\n\n  print('Cascade Notation\\n');\n  cascadeNotation();\n  print('- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\\n');\n\n  print('Conditional Structures\\n');\n  conditionalStructures();\n  print('- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\\n');\n\n  print('Loops\\n');\n  loops();\n  print('- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\\n');\n\n  print('Switch\\n');\n  switchFn();\n  print('- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\\n');\n\n  print('Specific Control Loops\\n');\n  specificControlLoops();\n  print('- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\\n');\n\n  print('Dificultad Extra (Optional)\\n');\n  dificultadExtra();\n  print('- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\\n');\n}\n\nvoid arithmeticOperators() {\n  assert(5 + 5 == 10);\n  print('Assert ( + ) passed successfully: 5 + 5 = ${5 + 5}');\n  assert(5 - 5 == 0);\n  print('Assert ( - ) passed successfully: 5 - 5 = ${5 - 5}');\n  assert(2 - 5 == -3);\n  print('Assert ( -expr ) passed successfully: 2 - 5 = ${2 - 5}');\n  assert(5 * 5 == 25);\n  print('Assert ( * ) passed successfully: 5 * 5 = ${5 * 5}');\n  assert(25 / 5 == 5);\n  print('Assert ( / ) passed successfully: 25 / 5 = ${25 / 5}');\n  assert(5 ~/ 5 == 1);\n  print('Assert ( ~/ ) passed successfully: 5 ~/ 5 = ${5 ~/ 5}');\n  assert(5 % 5 == 0);\n  print('Assert ( % ) passed successfully: 5 % 5 = ${5 % 5}');\n}\n\nvoid incrementDecrementOperators() {\n  int a = 0;\n  print('a = 0');\n  ++a;\n  assert(a == 1);\n  print('Increment Operator ( ++var ) passed successfully: a = ${a}');\n  a++;\n  assert(a == 2);\n  print('Increment Operator ( var++ ) passed successfully: a = ${a}');\n  --a;\n  assert(a == 1);\n  print('Decrement Operator ( --var ) passed successfully: a = ${a}');\n  a--;\n  assert(a == 0);\n  print('Decrement Operator ( var-- ) passed successfully: a = ${a}');\n}\n\nvoid equalityAndRelationalOperators() {\n  assert(2 == 2);\n  print('Assert ( == ) passed successfully: 2 == 2 = ${2 == 2}');\n  assert(2 != 3);\n  print('Assert ( != ) passed successfully: 2 != 2 = ${2 != 3}');\n  assert(3 > 2);\n  print('Assert ( > ) passed successfully: 2 > 2 = ${3 > 2}');\n  assert(2 < 3);\n  print('Assert ( < ) passed successfully: 2 < 2 = ${2 < 3}');\n  assert(3 >= 3);\n  print('Assert ( >= ) passed successfully: 2 == 2 = ${3 >= 3}');\n  assert(2 <= 3);\n  print('Assert ( <= ) passed successfully: 2 == 2 = ${2 <= 3}');\n}\n\nvoid typesOperators() {\n  print(\n      '1) Create instances of different animal types: animal1, animal2, animal3');\n  Animal animal1 = Cat();\n  Animal animal2 = Dog();\n  Animal animal3 = Animal();\n\n  // Using 'as' for type conversion\n  print('2) Use \"as\" for type conversion');\n  Cat cat = animal1 as Cat;\n  Dog dog = animal2 as Dog;\n\n  print('3) Use \"is\" to check type');\n  // ignore: unnecessary_type_check\n  if (animal1 is Cat) {\n    print('animal1 is a Cat');\n  }\n\n  print(\"4) Using 'is!' to check that it's not of a specific type\");\n  if (animal3 is! Dog) {\n    print('animal3 is not an Animal');\n  }\n\n  print(\"5) Invoking methods specific to subtypes\");\n  cat.meow();\n  dog.bark();\n}\n\nvoid logicalOperators() {\n  print(\"Create 'a' variable with value is 0\");\n  int a = 0;\n  if (!(a == 1)) {\n    int b = 0;\n    print(\"A is different from 0 using logical operator ( !expr )\");\n    a++;\n\n    if ((a == 1) || (a == 2)) {\n      print(\"A is 1 or 2 using logical operator ( || )\");\n      a++;\n    }\n\n    if (b == 0 && a == 2) {\n      print(\"A is 2 and b is 0 using logical operator ( && )\");\n    }\n  }\n}\n\nvoid conditionalExpressions() {\n  print(\"Create variable isPublic as bool false\");\n  bool isPublic = false;\n  // ignore: dead_code\n  print(\"Create variable visibility as String\");\n  String visibility = '';\n  print(\"Executing conditional expression using ? and :\");\n  // ignore: dead_code\n  visibility = isPublic ? \"public\" : \"private\";\n  print(\"visibility is $visibility\");\n}\n\nvoid cascadeNotation() {\n  print(\n      \"Create a new variable 'paint' of type 'Paint' with properties (color, height, width, backgroundColor, strokeWidth)\");\n  Paint paint = Paint()\n    ..color = 'blue'\n    ..height = 5\n    ..width = 5\n    ..backgroundColor = 'black'\n    ..strokeWidth = 1;\n\n  print(\"Assigning values to the 'paint' object using cascade notation\");\n  print(\n      \"$paint = Color: ${paint.color}, Height: ${paint.height}, Width: ${paint.width}, BackgroundColor: ${paint.backgroundColor}, StrokeWidth: ${paint.strokeWidth}\");\n}\n\nvoid conditionalStructures() {\n  bool condition = true;\n  print(\"Executes a block of code if a condition is true\");\n  if (condition) {\n    print(\"Condition is true\");\n    // ignore: dead_code\n  } else {\n    print(\"Executes a block of code when the condition is not true\");\n    print(\"Condition is false\");\n  }\n\n  print(\"Evaluates multiple conditions in sequence\");\n  int number = 42;\n  if (number > 50) {\n    print(\"Number is greater than 50\");\n  } else if (number > 30) {\n    print(\"Number is greater than 30\");\n  } else {\n    print(\"Number is less than or equal to 30\");\n  }\n}\n\nvoid loops() {\n  print(\"Iterates over a range of values or a specific sequence.\");\n  for (int i = 0; i < 5; i++) {\n    print(\"Iteration $i\");\n  }\n\n  print(\"while: Executes a block of code while a condition is true.\");\n  int count = 0;\n  while (count < 3) {\n    print(\"Count is $count\");\n    count++;\n  }\n\n  print(\n      \"do-while: Similar to while but guarantees at least one execution before checking the condition.\");\n  int value = 0;\n  do {\n    print(\"Value is $value\");\n    value++;\n  } while (value < 3);\n}\n\nvoid switchFn() {\n  print(\n      \"Switch: Directs the execution of code based on the value of an expression. Parameter is 'Monday'\");\n  String day = \"Monday\";\n  switch (day) {\n    case \"Monday\":\n      print(\"It's the start of the week\");\n      break;\n    case \"Friday\":\n      print(\"It's almost the weekend\");\n      break;\n    default:\n      print(\"It's a regular day\");\n  }\n}\n\nvoid specificControlLoops() {\n  print(\"break: Exits a loop or a control structure.\");\n  for (int i = 0; i < 5; i++) {\n    if (i == 3) {\n      break;\n    }\n    print(\"Breaking at $i\");\n  }\n\n  print(\"continue: Skips to the next iteration of a loop.\");\n  for (int i = 0; i < 5; i++) {\n    if (i == 2) {\n      continue;\n    }\n    print(\"Iteration $i\");\n  }\n}\n\nvoid dificultadExtra() {\n  print(\n      \"Program that prints even numbers between 10 and 55 (inclusive), excluding 16 and multiples of 3:\");\n  for (int number = 10; number <= 55; number++) {\n    if (number % 2 == 0 && number != 16 && number % 3 != 0) {\n      print(number);\n    }\n  }\n}\n\nclass Animal {\n  void makeSound() {\n    print('Generic sound');\n  }\n}\n\nclass Cat extends Animal {\n  void meow() {\n    print('Meow!');\n  }\n}\n\nclass Dog extends Animal {\n  void bark() {\n    print('Woof!');\n  }\n}\n\nclass Paint {\n  String color = '';\n  int height = 0;\n  int width = 0;\n  String backgroundColor = '';\n  double strokeWidth = 0;\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/dart/evelynnobile.dart",
    "content": "/*\n\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n\n\n import '../../00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO/dart/kodenook.dart';\n\nvoid main(){\n/*- Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...*/\n\n//aritméticos:\nvar suma = 2+2;\nprint(suma);\n\nvar resta = 10 - 5;\nprint(resta);\n\nint multiplicacion = 5 * 8;\nprint(multiplicacion);\n\ndouble division = 5 / 2;\nprint(division);\n\nvar intDivision = 5 ~/ 2;\nprint(intDivision);\n\nvar modulo = 20 % 4;\nprint(modulo);\n\n// Lógicos\n\n//OR\nvar verdadero = true && true;\nvar verdaderoEjemplo2 = false || true;\n//var verdaderoEjemplo3 = true || false;\nvar falso = false || false; \n\nprint(verdadero);\nprint(verdaderoEjemplo2);\nprint(falso);\n\n//AND\nvar verdaderoAnd = true && true;\n//var falseAnd1= false && true;\nvar falseAnd2= true && false;\n//var falseAnd3= false && false;\n\nprint(verdaderoAnd);\nprint(falseAnd2);\n\n//negación\n\nvar ejemploNegacion = !false;\nprint(ejemploNegacion);\n\n\n// De comparación\nvar ejemplo1= 2 == 2;\nvar ejemplo2= 2 != 4;\nvar ejemplo3= 5 > 10;\nvar ejemplo4= 5 < 2;\nvar ejemplo5= 5 >= 5;\nvar ejemplo6= 10 <= 20;\n\nprint(ejemplo1);\nprint(ejemplo2);\nprint(ejemplo3);\nprint(ejemplo4);\nprint(ejemplo5);\nprint(ejemplo6);\n\n// De asignación\n var a = 2;\n var b;\n\n var c = b ??= 5;\n\nvar d = 4;\nvar e = a += d;\n\nprint(a);\nprint(c);\nprint(e);\n\n\n // De identidad\nint num1 = 4;\nint num2 = 4;\nbool resultadoIdentical = identical(num1, num2);\n\n  // De pertenencia\n  var lista = [1, 2, 3, 4, 5];\n  bool resultadoContains = lista.contains(3);\n\nprint(resultadoContains);\nprint(resultadoIdentical);\n\n// Bits\n//And\nvar bit1= 5;\nvar bit2= 10;\n\nvar resultado = bit1 & bit2;\nvar resultado2 = bit1 | bit2;\n\nprint(resultado);\n print(resultado2);\n\n\n /* * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n */\n\nfor (var i =0; i<5; i++){\n  print(i);\n}\n\nvar i = 0;\nwhile( i < 5){\n  print(i);\n  i++;\n};\n\nvar num = 10;\n\nif (num > 20){\n  print(\"es mayor\");\n  }\nelse {\n  print(\"es menor\");\n}\n\n\nvar command = 'OPEN';\nswitch (command) {\n  case 'CLOSED':\n    print(\"CLOSED\");\n    break;\n  case 'PENDING':\n    print(\"PENDING\");\n    break;\n  case 'APPROVED':\n print(\"APPROVED\");\n    break;\n  case 'DENIED':\n   print(\"DENIED\");\n    break;\n  case 'OPEN':\n   print(\"OPEN\");\n    break;\n  default:\n    print(\"PENDING\");\n}\n\n for (int i = 10; i <= 55; i++){\n  if (i % 2 == 0 && i != 16 && i % 3 != 0){\n    print(i);\n  }\n }\n\n\n}\n "
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/dart/kodenook.dart",
    "content": "void main() {\n    /*\n        Arithmetic Operators\n    */\n\n    print('Arithmetic Operators\\n');\n    print('2 + 2 = ${2 + 2}');\n    print('2 - 2 = ${2 - 2}');\n    print('2 * 2 = ${2 * 2}');\n    print('2 / 2 = ${2 / 2}');\n    print('2 ~/ 2 = ${2 ~/ 2}'); // return an integer\n    print('2 % 2 = ${2 % 2}');\n\n    /*\n        Bitwise Operators\n    */\n\n    print('\\nBitwise Operators\\n');\n    print('&: 5 & 2 = ${5 & 2}');\n\tprint('|: 5 | 2 = ${5 | 2}');\n\tprint('^: 5 ^ 2 = ${5 ^ 2}');\n\tprint('>>: 5 >> 2 = ${5 >> 2}');\n\tprint('<<: 5 << 2 = ${5 << 2}');\n\n    /*\n        Assignment Operators\n    */\n\n    print('\\nAssignment Operators\\n');\n    print('x = 5');\n    print('x += 5, x = x + 5');\n    print('x -= 5, x = x - 5');\n    print('x *= 5, x = x * 5');\n    print('x /= 5, x = x / 5');\n    print('x ~/= 5, x = x ~/ 5');\n    print('x %= 5, x = x % 5');\n    print('x &= 5, x = x & 5');\n    print('x |= 5, x = x | 5');\n    print('x ^= 5, x = x ^ 5');\n    print('x >>= 5, x = x >> 5');\n    print('x <<= 5, x = x << 5');\n    print('x >>>= 5, x = x >>> 5');\n\n    /*\n        Comparison Operators\n    */\n\n    print('\\nComparison Operators\\n');\n    print('Equal to 4 == 5, ${4 == 5}');\n    print('Not Equal to 4 != 5, ${4 != 5}');\n    print('Grater Than 4 > 5, ${4 > 5}');\n    print('Less Than 4 < 5, ${4<= 5}');\n    print('Grater Than Or Equal to 4 >= 5, ${4 >= 5}');\n    print('Less Than Or Equal to 4 <= 5, ${4 <= 5}');\n\n    /*\n        Logical Operators\n    */\n\n    print('\\nLogical Operators\\n');\n    print('&&, 3 < 5 && 3 < 10, ${3 < 5 && 3 < 10}');\n    print('||, 3 < 5 || 3 < 10, ${3 < 5 || 3 < 10}');\n    print('!, !(4 < 5), ${!(4 < 5)}');\n\n    /*\n        If\n    */\n\n    if (6 > 5) {\n        print('6 is grater than 5');\n    } else if (5 < 6) {\n        print('5 is less than 6');\n    } else {\n        print('Good Bye');\n    }\n\n    /*\n        Switch\n    */\n\n    switch (10) {\n        case 2:\n            print('The case is 2');\n        case 5 when (5 < 10):\n            print('The case is 5');\n        case 8:\n            print('The case is 8');\n        default:\n            print('The case is not here');\n    }\n\n    /*\n        For loop\n    */\n\n    for (var i = 0; i < 5; i++) {\n        print(i);\n    }\n\n    var collection = [1, 2, 3];\n\n    for(final c in collection) {\n        print(c);\n    }\n\n    collection.forEach(print);\n\n    /*\n        While Loop\n    */\n\n    int i = 5;\n    while (i > 0) {\n        print(i);\n        i--;\n    }\n\n    do {\n        print(i);\n        i++;\n    } while (i < 5);\n\n    /*\n        Exercise\n    */\n\n    for(var i = 10; i < 56; i += 2) {\n        if(i == 16 || i % 3 != 0) {\n            continue;\n        }\n        print(i);\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/dart/marinaortells.dart",
    "content": "/// URL del sitio web oficial: https://dart.dev/\n\n/// #01 - Operadores y estructruas de control\n\n/// Ejemplos con los tipos de operadores\n\nimport 'dart:io';\n\nvoid main() {\n\n  int a = 20;\n  int b = 4;\n  int c = 3;\n\n  /// Operadores aritméticos\n\n  print(a + b); // Suma\n  b = ++a; // Incrementa el valor de \"a\" antes de asignárselo a \"b\"\n  print(b);\n\n  c = a++; //Incremente el valor de \"a\" después de asigárselo a \"b\"\n  print(c);\n\n  print(a - b); // Resta\n\n  print(a * b); // Multiplicación\n\n  print(a / c); // División (devuelve con parte decimal)\n  \n  print(a ~/ c); // División (devuelve sin la parte decimal)\n  \n  print(a % c); // Develve el módulo de una división\n\n  /// Operadores lógicos\n  \n  bool hola = true;\n  bool adios = false;\n\n  print(!hola); // Invierte el valor del booleano\n\n  print(adios || hola); // Operador lógico OR\n\n  print(hola && adios); // Operador lógico AND\n\n  /// Operadores de comparación\n  \n  print(10 == 10); // Igual -  Devuelve booleano\n  print(10 == 9); // Igual - Devuelve booleano\n\n  print(10 != 10); // No igual - Devuelve booleano\n  print(10 != 9); // No igual - Devuelve booleano\n\n  print(10 > 9); // Mayor que\n  print(9 < 10); // Menor que\n  print(10 >= 8); // Mayor o igual que\n  print(7 <= 29); // Menor o igual que\n\n  /// Operadores \"type test\"\n  \n\n  if (adios is bool) {\n    print(adios);\n  } // Es verdadero si el objeto tiene ese tipo\n\n  /// El código siguiente es una alternativa para ello.\n  /// La diferencia es que si el anterior adios no es bool, no hace nada\n  /// pero si en el siguiente no es, lanza una excepción.\n  (adios as bool) = adios; \n  /// Ambos ejercicios anteriores no se utilizan con esos tipos, se suele hacer\n  /// con tipos creados\n\n\n  if (adios is! int) {\n    print(hola);\n  } // Es verdadero si el objeto no tiene ese tipo\n\n  /// Operadores de asignación\n  \n  String edificio = \"blanco\"; // asigna el valor\n  print(edificio);\n\n  /// String n ??= \"negro\" //Esto asigna el valor a n si esta es null, sino, se queda como está (DA ERROR)\n  \n  /// Operadores de \"bitwise\" y desplazamiento\n  /// En Dart se puede trabajar con bits\n  \n  int valor = 0x22;\n  int hexadecimal = 0x0d;\n\n  print(valor & hexadecimal); // Operador AND\n  print(valor & ~hexadecimal); // Operador AND NOT\n  print(valor | hexadecimal); // Operador OR\n  print(valor ^ hexadecimal); // Operador XOR\n\n  print(valor << 4); // Desplazamiento a la izquierda\n  print(valor >> 4); // Desplazamiento a la derecha\n\n  print(hexadecimal >>> 4); // Triple desplazamiento a la derecha\n  /// El triple desplazamiento a la izquierda da error\n  \n  /// Expresiones condicionales\n  \n  /// Si la condición es verdadera, entonces se ejecuta la primera expresión\n  /// si es falso, se ejecuta la segunda\n  (3 == 2) ? print(\"Es verdad\") : print(\"Es falso\"); \n\n  a ?? b; // Si \"a\" no es null, devuelve el valor de \"b\", sino, devuelve el de \"a\"\n\n  /// Estructuras de control\n\n  /// For loops\n  \n  /// Este primer ejemplo es un for loop que concatena un String\n  var reto = StringBuffer(\"Reto 01\");\n  for (int i = 0; i < 10; i++) {\n    reto.write(\"!\");\n  }\n  print(reto);\n  /// StringBuffer se utiliza para poder concatenar Strings de forma más eficiente\n  /// En vez de hacer (\"String\" + \"Otro string\"), se concatena con el método write\n\n  /// UN EJEMPLO DE LA DOCMENTACIÓN:\n  /// Otro for loop que añade valores a una lista\n  var lista = [];\n  for (var i = 0; i < 5; i++) {\n    lista.add(() => print(i));\n  }\n\n  for (final c in lista) {\n    c();\n  }\n\n  /// While loops: evalúa la condición (add !=10) antes del bucle\n  \n  var suma= 5;\n  while(suma != 10) {\n    suma++;\n  }\n  print(\"El valor ha llegado a 10\");\n\n  /// Do while loops: evalúa la condición antes del bucle\n  \n  var resta = 10;\n  do {\n    resta--;\n  } while (resta != 5);\n  print(\"El valor ha llegado a 5\");\n\n  /// Break\n  /// ESTÁ COMENTADO PORQUE PARALIZA TODA LA EJECUCIÓN\n  /** \n  var multiplicador = 2;\n\n  while (true) {\n    if (multiplicador == 4) {\n      print(multiplicador);\n      break;\n    }\n    multiplicador * 2;\n  }\n  */\n\n  /// El continue se utiliza para pasar al siguiente bucle\n  /// Ejemplo inspirado en la documentación\n  \n  var edades = [10, 11, 50, 23, 98, 7, 76];\n\n  for (int i = 0; i < edades.length; i++) {\n    var ed = edades[i];\n    if (ed > 18) {\n      continue;\n    }\n    print(\"$ed: Es mayor de edad\"); // El $ se utiliza para poder concatenar elementos de distintos tipos\n  }\n  \n  /// Branching\n  \n  /// if statements\n  \n  print(\"¿Cuántos años tienes? \");\n  int? edad = int.parse(stdin.readLineSync()!);\n\n  if (edad >= 18) { print(\"Eres mayor de edad\"); }\n  else { print(\"Eres menor de edad\"); }\n\n  /// switch\n  \n  print(\"Escribe un color: \"); \n  var color = stdin.readLineSync();\n\n  switch(color) {\n    case \"NEGRO\": {\n      print(\"Color negrp\");\n    }\n    case \"BLANCO\": {\n      print(\"Color blanco\");\n    }\n    default: {\n      print(\"No es ni blanco ni negro\");\n    }\n  }\n\n  ///Exceptions\n  \n \n    int x = 12;\n    int y = 0;\n\n  ///Try - on\n\n  try {\n    var res = x ~/ y;\n    print(res);\n\n  } on UnsupportedError {\n    print(\"Cannot dive by zero\");\n  }\n\n  ///Try - catch\n\n    try {\n      var res = x ~/ y;\n      print(res);\n\n    } catch(e) {\n      print(e);\n    }\n  \n  /// Ambos juntos + finally\n  \n  try {\n      var res = x ~/ y;\n      print(res);\n\n    } on UnsupportedError {\n      print(\"Cannot dive by zero\");\n    } catch(e) {\n      print(e);\n    } finally {\n      print(\"Gracias :)\");\n    }\n\n  /// DIFICULTAD EXTRA\n  \n  int limiteInferior = 10;\n  int limiteSuperior  = 55;\n\n  for (int i = limiteInferior; i <= limiteSuperior; i++) {\n    if (((i == 16) || ((i % 2) != 0)) || ((i % 3) == 0) ){\n      continue;\n    }\n    print(i);\n  }\n}\n\n  \n  \n  \n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/dart/misaelbentperez.dart",
    "content": "void main(List<String> arguments) {\n  //Funcion dificultad extra!!!\n  printNumbers(10, 55);\n\n  //OPERACIONES ESTRUCTURAS DE CONTROL\n\n  //Condicionales:\n\n  //Establezco un valor para realizar las operaciones\n  int control = 10;\n\n  if (3 < control) {\n    print('El numero 3 es inferior a $control');\n  } // condicional if\n\n  if (20 < control) {\n    print('El numero 20 es inferior a $control');\n  } else {\n    print('El numero 20 es superior a $control');\n  } // condicional if/else\n\n  if (20 < control) {\n    print('El numero 20 es inferior a $control');\n  } else if (20 == control) {\n    print('El numero 20 es igual a $control');\n  } else {\n    print('El numero 20 no es inferior, ni igual a $control es superior');\n  } // condicional else if\n\n  Dias festivo = Dias.lunes;\n  switch (festivo) {\n    case Dias.lunes:\n      print('El festivo es el lunes');\n    case Dias.miercoles:\n      print('El festivo es el miercoles');\n    case Dias.viernes:\n      print('El festivo es el viernes');\n  } //condicional Switch\n\n  //Bucles\n\n  for (var i = 1; i <= control; i++) {\n    print('Contando ... $i');\n  } // Bucle for\n\n  for (var kid in kids) {\n    print(kid);\n  } // Bucle for in\n\n  while (counter < control) {\n    print('La cuenta va en: $counter');\n    counter++;\n  } //Bucle while\n\n  counter = 0;//Limpio el counter para no tener otra var\n\n  do {\n    print('Nueva cuenta en : $counter');\n    counter++;\n  } while (counter <= 0);// Bucle do while\n} // Fin del Main\n\n//Contador para el while\nint counter = 0;\n\n// List para que funcione el For in\nList<String> kids = ['Andres', 'Julian', 'Federico'];\n\n//Enum para que funcione el switch\nenum Dias { lunes, miercoles, viernes }\n\n//Operadores aritmeticos\nint sumResult = 1 + 1; //Suma\nint restResult = 1 - 1; //Resta\nint multiResult = 1 * 1; //Multiplicacion\ndouble divResult = 4 / 2; //Division\ndouble moduloResult = 4 % 2; // Modulo\ndouble expo = 4 * 2; //Revisar\n\n//Operadoores de comparacion\n//Utilizo funciones tipo flecha para retornar un bool haciendo comparaciones\nbool isEqual(int a, int b) => a == b; //Igualdad ==\nbool isNotSame(int a, int b) => a != b; //Desigualdad !=\nbool isGreaterThan(int a, int b) => a > b; //Mayor que >\nbool isLessThan(int a, int b) => a < b; //Menor que <\nbool isGreaterEqualThan(int a, int b) => a >= b; //Menor o igual que >=\nbool isLessEqualThan(int a, int b) => a <= b; //Menor o igual que <=\n\n//Operadores logicos\nbool isJustPrice(int value) => value > 0 && value < 2.50; // y logico &&\nbool isInjustPrice(int value) => value < 2.50 || value > 5.50; // o logico ||\n\n//Operadores asignacion\n//Coloco ejemplo con funciones tipo flecha\nint x = 1; // Asignacion\nassignPlus(int a) => a += 3; // Suma y asignacion +=\nassignRest(int a) => a -= 3; // Resta y asignacion -=\nassignMulti(int a) => a *= 3; // Multiplicacion y asignacion *=\nassignDiv(double a) => a /= 3; //Division y asigancion /=\nassignIntDiv(int a) => a ~/= 3; //Division entera y asignacion ~/=\nassignModulo(int a) => a %= 3; //Modulo y asignacion %=\n\n//Operadores desplazamiento\n//Aun no entiendo a cabalidad estos operadores.\ndisplaceRight(int a) => a >> 3;\ndisplaceLeft(int a) => a << 3;\n\n//Operadores de Cadenas de texto\nString getFullName(String name, String lastName) =>\n    name + lastName; // Concatenar +\nString getEco(String word) => word * 5; //Repetir *\n\n//opedarores de incremento/drecremento\nint increment(int a) => a++; // Incrementa de 1 en 1\nint decrease(int a) => a--; // Decrementa de 1 en 1\n\n// Funcion que hace que se impriman los numeros solicitados en el Extra!!\nvoid printNumbers(int min, int max) {\n  //Esta funcion evalua si un numero es multiplo de otro\n  bool isMultipleOf(int a, int multiple) => a % multiple == 0;\n  List<int> list = [];\n  for (var i = min; i < max; i++) {\n    if (isMultipleOf(i, 2) && !isMultipleOf(i, 3) && i != 16) {\n      list.add(i);\n    }\n  }\n  list.add(max);\n\n  print(list);\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/dart/raulfauli.dart",
    "content": "/// 01 - OPERADORES Y ESTRUCTURAS DE CONTROL\n\nvoid main() {\n  // Variables\n  int a = 10;\n  int b = 4;\n\n  // Operadores aritméticos\n  print('Suma $a + $b = ${a + b}');\n  print('Resta $a - $b = ${a - b}');\n  print('Multiplicación $a * $b = ${a * b}');\n  print('División $a / $b = ${a / b}');\n  print('División sin decimal $a ~/ $b = ${a ~/ b}');\n  print('Resto $a % $b = ${a % b}');\n\n  // Operadores de comparación\n  print(\"¿$a es == $b? ${a == b}\");\n  print(\"¿$a es != $b? ${a != b}\");\n  print(\"¿$a es > $b? ${a > b}\");\n  print(\"¿$a es < $b? ${a < b}\");\n  print(\"¿$a es >= $b? ${a >= b}\");\n  print(\"¿$a es <= $b? ${a <= b}\");\n\n  // Operadores lógicos\n  print('AND: ¿$a es > 0 y $b es > 0? ${a > 0 && b > 0}');\n  print('OR: ¿$a es > 0 o $b es > 0? ${a > 0 || b > 0}');\n  print('NOT: ¿$a es lo contrario < 0? ${!(a > 0)}');\n\n  // Operadores de asignación\n  int number = 1;\n  print(number);\n  number += 1;\n  print(number);\n  number -= 1;\n  print(number);\n  number *= 2;\n  print(number);\n  number ~/= 2;\n  print(number);\n  number %= 2;\n  print(number);\n\n  double decimal = 3.0;\n  decimal /= 3;\n  print(decimal);\n\n  // Operadores de identidad\n  print('¿$a es int? ${a is int}');\n  print('¿$a no es int? ${a is! int}');\n  int c = a;\n  int d = null ?? a;\n  print('¿$c es $d son iguales? ${c == d}');\n\n  // Operadores de bits\n  print('AND: $a & $b = ${a & b}'); // 1010 & 0100 = 0000\n  print('OR: $a | $b = ${a | b}'); // 1010 | 0100 = 1110\n  print('XOR: $a ^ $b = ${a ^ b}'); // 1010 ^ 0100 = 1110\n  print('NOT: ~$a = ${~a}'); // ~1010 = 0101\n\n  print('Desplazamiento izquierda 10 << 2 = ${a << 2}'); // 1010 << 2 = 101000\n  print('Desplazamiento derecha 10 >> 2 = ${a >> 2}'); // 1010 >> 2 = 0010\n\n  // Condicionales\n  if (a > b) {\n    print('$a es mayor que $b');\n  } else if (a < b) {\n    print('$a es menor que $b');\n  } else {\n    print('$a es igual que $b');\n  }\n\n  switch (a) {\n    case 1:\n      print('$a es 1');\n      break;\n    case 2:\n      print('$a es 2');\n      break;\n    default:\n      print('$a No es 1 ni 2');\n  }\n\n  // Iterativas\n  for (int i = 0; i < 10; i++) {\n    print(i);\n  }\n\n  int i = 0;\n  while (i < 10) {\n    print(i);\n    i++;\n  }\n\n  i = 0;\n  do {\n    print(i);\n    i++;\n  } while (i < 10);\n\n  List<int> numbers = [1, 2, 3, 4, 5];\n  for (int number in numbers) {\n    print(number);\n  }\n\n  // Excepciones\n\n  try {\n    double result = a / 0;\n    print(result);\n  } on UnsupportedError {\n    print('No se puede dividir por 0');\n  } catch (e) {\n    print(e);\n  } finally {\n    print('Ha finalizado la operación');\n  }\n\n  print('\\n# EXTRA');\n  /*\n    Extra: Crea un programa que imprima por consola todos los números comprendidos\n    entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n  */\n  for (int i = 10; i <= 55; i++) {\n    if (((i == 16) || ((i % 2) != 0)) || ((i % 3) == 0)) {\n      continue;\n    }\n    print(i);\n  }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/dart/sitnestic.dart",
    "content": "import 'dart:math';\n\nvoid main() {\n//* - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n// Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n// (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n// https://dart.dev/language/operators\n\n//* - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n//que representen todos los tipos de estructuras de control que existan en tu lenguaje:\n//Condicionales, iterativas, excepciones...\n\n//* - Debes hacer print por consola del resultado de todos los ejemplos.\n\n  int a = 5;\n  int b = 7;\n\n  /// Operadores aritméticos\n  print(\"\"\"\n\n  Operadores aritméticos\"\"\");\n  print('a = $a; b = $b');\n  var add = a + b;\n  print('Add $a + $b =  $add');\n  assert(a + b == add);\n  var subtract = a - b;\n  print('Subtract $a - $b =  $subtract');\n  assert(a - b == subtract);\n  var reverse = -subtract;\n  print(\n      'Unary minus, also known as negation (reverse the sign of the expression) -$subtract =  $reverse');\n  var multiply = a * b;\n  print('Multiply $a * $b =  $multiply');\n  assert(a * b == multiply);\n  var divide = b / a;\n  print('Divide $b / $a =  $divide');\n  assert(b / a == divide); // Result is a double\n  var divideInteger = b ~/ a;\n  print('Divide, returning an integer result $b ~/ $a =  $divideInteger');\n  assert(b ~/ a == divideInteger); // Result is an int\n  var modulo = b % a;\n  print('Get the remainder of an integer division (modulo) $b % $a =  $modulo');\n  assert(b % a == modulo); // Remainder\n\n  /// Igualdad y operadores relacionales\n  print(\"\"\"\n\n  Igualdad y operadores relacionales\"\"\");\n  print('a = $a; b = $b');\n  var greaterThan = a > b;\n  print('Greater than >: $b > $a es $greaterThan');\n  assert(b > a);\n  var lessThan = a < b;\n  print('Less than <: $a < $b es $lessThan');\n  assert(a < b);\n  var greaterThanOrEqual = a >= b;\n  print('Greater than or equal to >=: $a >= $b es $greaterThanOrEqual');\n  assert(b >= a);\n  var lessThanOrEqual = a <= b;\n  print('Less than or equal to <=: $a <= $b es $lessThanOrEqual');\n  assert(a <= b);\n  var equal = a == b;\n  print('Equal; see discussion below ==: $a == $b es $equal');\n  assert(a == a);\n  var notEqual = a != b;\n  print('Not equal !=: $a != $b es $notEqual');\n  assert(a != b);\n\n  /// Operadores de prueba de tipo\n  print(\"\"\"\n\n  Operadores de prueba de tipo\"\"\");\n  String typeString = 'GSF';\n  // Using is to compare\n  print(typeString is String);\n\n  double typeDouble = 3.3;\n  // Using is! to compare\n  print(typeDouble is! int);\n\n  /// Operadores de asignación\n  print(\"\"\"\n\n  Operadores de asignación\"\"\");\n  print('a = $a; b = $b');\n  var assignment = a * b; //\n  print('=(Simple Assignment ) $assignment = $a * $b');\n  var nullAssignment = null;\n  nullAssignment ??= a + b;\n  print(\n      '??=(Assign the value only if the variable is null) $nullAssignment ??= $a + $b');\n  nullAssignment ??= a * b;\n  print(\n      '??=(Assign the value only if the variable is null) $nullAssignment ??= $a * $b ===> Not assigned because is not null');\n  a += 10; //\n  print('a += 10  == $a');\n  a -= 5; //\n  print('a -= 5  == $a');\n  a *= 2; //\n  print('a *= 2  == $a');\n  nullAssignment /= 2; //\n  print('d /= 2  == $nullAssignment');\n  a %= 3; //\n  print('a %= 3  == $a');\n\n  /// Operadores lógicos\n  print(\"\"\"\n\n  Operadores  lógicos\"\"\");\n  print('a = $a; b = $b');\n  var foo = a + b;\n  var bar = b - a;\n  print(\n      'logical AND: $a + $b == $foo && $b - $a == $bar es ${a + b == foo && b - a == bar}');\n  print(\n      'logical OR: $a + $b == $foo || $b - $a == $bar es ${a + b == foo || b - a == bar}');\n  print(\n      'inverts the following expression (changes false to true, and vice versa): !true es ${!true}');\n\n  /// Expresiones condicionales\n  print(\"\"\"\n\n  Expresiones condicionales\"\"\");\n  bool isPublic = Random().nextBool();\n  var visibility = isPublic ? 'public' : 'private';\n  print(visibility);\n\n  String nameNull(String? name) => name ?? 'Guest';\n  print(nameNull(null));\n\n  // Slightly longer version uses ?: operator.\n  String nameLongNull(String? name) => name != null ? name : 'Guest';\n  print(nameLongNull(null));\n\n// Very long version uses if-else statement.\n  String nameVeryLongNull(String? name) {\n    if (name != null) {\n      return name;\n    } else {\n      return 'Guest';\n    }\n  }\n\n  print(nameVeryLongNull(null));\n\n  /// Iterativas\n  /// for\n  for (var i = 0; i < 10; i++) {\n    print(i);\n  }\n\n  /// while\n  int j = 0;\n  while (j <= 10) {\n    print(j);\n    j += 1;\n  }\n\n  // Excepciones\n  int x = 12;\n  int y = 0;\n\n  ///Try - on\n  try {\n    var res = x ~/ y;\n    print(res);\n  } on UnsupportedError {\n    print(\"Cannot dive by zero\");\n  }\n\n  ///Try - catch\n  try {\n    var res = x ~/ y;\n    print(res);\n  } catch (e) {\n    print(e);\n  }\n\n  /// Ambos juntos + finally\n\n  try {\n    var res = x ~/ y;\n    print(res);\n  } on UnsupportedError {\n    print(\"Cannot dive by zero\");\n  } catch (e) {\n    print(e);\n  } finally {\n    print(\"finally try\");\n  }\n\n  /// bit a bit\n  final value = 0x22;\n  final bitmask = 0x0f;\n\n  assert((value & bitmask) == 0x02); // AND\n  assert((value & ~bitmask) == 0x20); // AND NOT\n  assert((value | bitmask) == 0x2f); // OR\n  assert((value ^ bitmask) == 0x2d); // XOR\n\n  assert((value << 4) == 0x220); // Shift left\n  assert((value >> 4) == 0x02); // Shift right\n\n  // Shift right example that results in different behavior on web\n  // because the operand value changes when masked to 32 bits:\n  assert((-value >> 4) == -0x03);\n\n  assert((value >>> 4) == 0x02); // Unsigned shift right\n  assert((-value >>> 4) > 0); // Unsigned shift right\n\n  /// Other operators\n  print(\"\"\"\n\n  Operadores ...\"\"\");\n  print('a = $a; b = $b');\n  // Performing Bitwise AND on a and b\n  var bitwiseAND = a & b;\n  print('Bitwise AND $bitwiseAND = $a & $b');\n\n  // Performing Bitwise OR on a and b\n  var bitwiseOR = a | b;\n  print('Bitwise OR $bitwiseOR = $a | $b');\n\n  // Performing Bitwise XOR on a and b\n  var bitwiseXOR = a ^ b;\n  print('Bitwise XOR $bitwiseXOR = $a ^ $b');\n\n  // Performing Bitwise NOT on a\n  var bitwiseNOT = ~a;\n  print('Bitwise NOT $bitwiseNOT = ~$a');\n\n  // Performing left shift on a\n  var leftShift = a << b;\n  print('left shift $leftShift = $a << $b');\n\n  // Performing right shift on a\n  var rightShift = a >> b;\n  print('right shift $rightShift = $a >> $b');\n\n//*! DIFICULTAD EXTRA (opcional):\n//Crea un programa que imprima por consola todos los números comprendidos\n//entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n  int opcional10 = 10;\n  int opcional55 = 55;\n  for (int i = opcional10; i <= opcional55; i++) {\n    if ((i % 2 == 0) & (i != 16) & (i % 3 != 0)) {\n      print(i);\n    }\n  }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/delphi/fduron.dpr",
    "content": "(*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritmticos, lgicos, de comparacin, asignacin, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que t quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los nmeros comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni mltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n *)\n\nprogram fduron;\n\n{$APPTYPE CONSOLE}\n\n{$R *.res}\n\n\nuses\n  System.SysUtils;\n\ntype\n  TElementos = (Elemento1, Elemento2, Elemento3, Elemento4, Elemento5, Elemento6);\n  TConjuntoElementos = set of TElementos;\nconst\n  IntA = 20;\n  IntB = 11;\n  BoolA = True;\n  BoolB = False;\n  UnConjunto: TConjuntoElementos = [Elemento1, Elemento3, Elemento5];\n  OtroConjunto: TConjuntoElementos = [Elemento2, Elemento6];\nvar\n  VariableEntera: Integer;\n  VariableString: String;\n  VariableConjunto: TConjuntoElementos;\n  UnObjeto: TObject;\n  I: Integer;\n  R: Real;\n\nprocedure MostrarElementosDelConjunto(const UnConjuntoLocal: TConjuntoElementos);\nbegin\n  //Ejemplo de ciclo FOR con elementos de un conjunto\n  for var Elemento in UnConjuntoLocal do\n    case Elemento of\n      Elemento1: Write('Elemento1 ');\n      Elemento2: Write('Elemento2 ');\n      Elemento3: Write('Elemento3 ');\n      Elemento4: Write('Elemento4 ');\n      Elemento5: Write('Elemento5 ');\n      Elemento6: Write('Elemento6 ');\n    end;\n    WriteLn;\nend;\n\nbegin\n  WriteLn('*** Operadores Aritmticos ***');\n  WriteLn('Suma: ', IntA + IntB);\n  WriteLn('Resta: ', IntA - IntB);\n  WriteLn('Multiplicacin: ', IntA * IntB);\n  WriteLn('divisin real: ', IntA / IntB);\n  WriteLn('divisin entera: ', IntA div IntB);\n  WriteLn('residuo: ', IntA mod IntB);\n  WriteLn;\n  WriteLn('*** Operadores lgicos ***');\n  WriteLn('NOT lgico (Negacin):', not BoolA);\n  WriteLn('AND lgico (Conjuncin):', BoolA and BoolB);\n  WriteLn('OR lgico (Disyuncin):', BoolA or BoolB);\n  WriteLn('XOR lgico (Disyuncin exclusiva):', BoolA xor BoolB);\n  WriteLn;\n  WriteLn('*** Operadores de comparacion ***');\n  WriteLn('Es mayor que: ', IntA > IntB);\n  WriteLn('Es menor que: ', IntA < IntB);\n  WriteLn('Es mayor o igual que: ', IntA >= IntB);\n  WriteLn('Es menor o igual que: ', IntA <= IntB);\n  WriteLn('Es igual a: ', IntA = IntB);\n  WriteLn('Es diferente a: ', IntA <> IntB);\n  WriteLn;\n  WriteLn('*** Asignacion ***');\n  VariableEntera := 12;\n  VariableString := 'Valor string';\n  VariableConjunto := [Elemento1, Elemento2];\n  WriteLn;\n  WriteLn('*** Operadores de identidad ***');\n  WriteLn('La variable es de la clase TObject: ', UnObjeto is TObject);\n  WriteLn;\n  WriteLn('*** Operadores de pertenencia ***');\n  WriteLn('El elemento pertenece a un conjunto: ', Elemento4 in UnConjunto);\n  WriteLn('El elemento NO pertenece a un conjunto: ', not(Elemento4 in UnConjunto));\n  WriteLn;\n  WriteLn('*** Operadores de bits ***');\n  {IntA es un valor entero de 64Bits, su valor (20) en binario es:\n   0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0001 0100\n  al invertir todos los bits (not IntA) se convierte en\n  1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 1011\n  que es -21 entero}\n  WriteLn('NOT a nivel de bits (invertir): ', not IntA);\n  WriteLn('AND a nivel de bits: ', IntA and IntB);\n  WriteLn('OR a nivel de bits: ', IntA or IntB);\n  WriteLn('XOR a nivel de bits: ', IntA xor IntB);\n  WriteLn('Desplazamiento de X bits a la izquierda: ', IntA shl 2);\n  WriteLn('Desplazamiento de X bits a la derecha: ', IntA shr 2);\n  WriteLn;\n  WriteLn('*** Operadores de conjuntos ***');\n  Write('Union: ');\n  MostrarElementosDelConjunto(UnConjunto + OtroConjunto);\n  Write('Diferencia: ');\n  MostrarElementosDelConjunto(UnConjunto - OtroConjunto);\n  Write('Interseccin: ');\n  MostrarElementosDelConjunto(UnConjunto * OtroConjunto);\n  WriteLn('Es subconjunto de: ', UnConjunto <= OtroConjunto);\n  WriteLn('Es sperconjunto de: ', UnConjunto >= OtroConjunto);\n  WriteLn('Igualdad: ', UnConjunto = OtroConjunto);\n  WriteLn('Diferencia: ', UnConjunto <> OtroConjunto);\n  WriteLn('Pertenencia de ordinal en un conjunto: ', Elemento1 in OtroConjunto);\n  WriteLn;\n  WriteLn('*** Apuntadores ***');\n  var x := @VariableEntera; //Apuntador a la direccin de memoria que ocupa la variable\n  WriteLn('Dereferenciar un apuntador: ', Integer(^x));\n  WriteLn;\n  WriteLn('*** Estructuras de control ***');\n  if IntA > IntB then\n  begin\n    WriteLn('IntA es mayor que IntB')\n  end\n  else\n  begin\n    WriteLn('IntA no es mayor que IntB')\n  end;\n\n  case IntA of\n    10: WriteLn('IntA es igual a 10');\n    20: WriteLn('IntA es igual a 20');\n    30: WriteLn('IntA es igual a 30');\n    31..40: WriteLn('IntA esta entre 31 y 40');\n  else\n    WriteLn('IntA es igual a otro valor');\n  end;\n\n  WriteLn('Numeros del 1 al 10 en un ciclo FOR:');\n  for I := 1 to 10 do\n  begin\n    Write(I, ' ');\n  end;\n\n  WriteLn;\n  WriteLn('Numeros del 1 al 10 en un ciclo WHILE:');\n  I := 1;\n  while I <= 10 do\n  begin\n    Write(I, ' ');\n    I := I + 1;\n  end;\n\n  WriteLn;\n  WriteLn('Numeros del 1 al 10 en un ciclo REPEAT:');\n  I := 1;\n  repeat\n    Write(I, ' ');\n    I := I + 1;\n  until I > 10;\n\n  WriteLn;\n  try\n    WriteLn('Prueba de finally');\n    VariableEntera := IntA + IntB;\n    R := IntB * 2.25;\n  finally\n    WriteLn('''\n      Esta lnea se imprimir independientemente de lo que ocurra\n      en el cdigo del bloque T R Y\n      ''');\n  end;\n\n  WriteLn;\n  WriteLn('''\n    ******************************************************************\n    **  DIFICULTAD EXTRA                                            **\n    ******************************************************************\n    ''');\n  WriteLn('Nmeros del 10 al 55, excluyendo el 16 y multiplos de 3');\n  for I := 10 to 55 do\n    if (I <> 16) and ((I mod 3) <> 0) then\n      Write(I, ', ');\n  WriteLn;\n\n  try\n    writeLn('Prueba de excepciones');\n    I := 1;\n    while I <= 1 do\n    begin\n      R := IntA div I; //Provocar una Division por 0\n      I := I - 1;\n    end;\n  except\n    on E: Exception do\n      WriteLn('Ocurrio el error: ', E.Message);\n  end;\n\n  ReadLn;\n\nend.\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/ejercicio.md",
    "content": "# #01 OPERADORES Y ESTRUCTURAS DE CONTROL\n> #### Dificultad: Fácil | Publicación: 02/01/24 | Corrección: 08/01/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/elixir/juandbc.exs",
    "content": "# Operadores aritméticos\nIO.puts(\"# Operadores aritméticos\")\nIO.puts(\"Suma 5 + 5 = #{5 + 5}\")\nIO.puts(\"Resta 5 - 5 = #{5 - 5}\")\nIO.puts(\"Multiplicación 5 * 5 = #{5 * 5}\")\nIO.puts(\"División 5 / 5 = #{5 / 5}\")\n# No hay operador % para el modulo cómo en otros lenguajes, pero si una función llamada rem(n,m)\nIO.puts(\"Módulo 31 % 3 = #{rem(31, 3)}\")\n# Operadores de asignación\nIO.puts(\"# Operadores de asignación\")\nx = \"asignación\"\nIO.puts(\"x = #{x}\")\n[head, middle | tail] = [\"cabeza\", :middle, \"cola\"]\nEnum.join([head, middle, tail], \",\") |> IO.puts()\n\n# Operadores lógicos\nIO.puts(\"# Operadores lógicos\")\n# and, or y not son operadores de corto circuito y deben usarse con Booleans\nop_or_corto_circuito = true or false\nop_and_corto_circuito = true and nil\nIO.puts(\"Operador or (true or false) -> #{op_or_corto_circuito}\")\nIO.puts(\"Operador and (true and nil) -> #{op_and_corto_circuito}\")\nIO.puts(\"Operador not (not true) -> #{not true}\")\n# Para valores no booleanos\nop_or = true || false\nop_and = true && false\nIO.puts(\"Operador || (true || false) -> #{op_or}\")\nIO.puts(\"Operador && (true && false) -> #{op_and}\")\nIO.puts(\"Operador ! (!true) -> #{!true}\")\n\n# Operadores de comparación\nIO.puts(\"# Operadores de comparación\")\nIO.puts(\"1 < 1.0 -> #{1 < 1.0}\")\nIO.puts(\"1 > 2.0 -> #{1 > 2.0}\")\nIO.puts(\"1 <= 1.0 -> #{1 <= 1.0}\")\nIO.puts(\"1 >= 2.0 -> #{1 >= 2.0}\")\nIO.puts(\"1 == 1.0 -> #{1 == 1.0}\")\nIO.puts(\"1 != 1.0 -> #{1 != 1.0}\")\nIO.puts(\"1 === 1.0 -> #{1 === 1.0}\")\nIO.puts(\"1 !== 1.0 -> #{1 !== 1.0}\")\n\n# Operador de pertenencia\nIO.puts(\"# Operadores de comparación\")\nlist_has_fives = 5 in [1, 2, 3, 4, 5]\nlist_hasnt_fives = 5 in [1, 2, 3, 4]\nIO.puts(\"5 in [1, 2, 3, 4, 5] -> #{list_has_fives}\")\nIO.puts(\"5 not in [1, 2, 3, 4] -> #{list_hasnt_fives}\")\n\n# Estructuras de control\n# A difererencia de otros lenguajes, no son estructuras de control nativas sino macros (if/2, case/2, cond/1)\nIO.puts(\"# Estructuras de control (aunque no son nativas, sino macros)\")\n# if\nIO.puts(\"- if else\")\nif String.valid?(\"H\") do\n  IO.puts(\"Válido!\")\nelse\n  IO.puts(\"No válido\")\nend\n# unless (deprecada)\nIO.puts(\"- unless\")\nunless is_atom(\"test\"), do: IO.puts(\"No es átomo\")\n# case/switch\nIO.puts(\"- case/switch\")\ncase {:ok, \"Hola mundo\"} do\n  {:ok, result} -> result\n  {:error} -> \"Error!\"\n  _ -> \"Este es el default\"\nend\n# cond\nIO.puts(\"- Cond como: elsif/elseif\")\ncond do\n  2 + 2 == 5 -> IO.puts(\"Este no se imprimirá porque 2 + 2 no es igual 5\")\n  2 + 2 == 4 -> IO.puts(\"Este también siempre se imprimirá porque 2 + 2 = 4\")\n  true -> IO.puts(\"Este no se imprimirá porque se cumplió el anterior\")\nend\n\n# Excepciones\nIO.puts(\"- Try/Rescue/After\")\ntry do\n  1 = x\nrescue\n  e in MatchError -> IO.puts(\"Excepción capturada [#{Exception.message(e)}]\")\nafter\n  IO.puts(\"Este es como el finally en Java o ensure en Ruby\")\nend\nIO.puts(\"- Try/Catch\")\ntry do\n  e = \"Throws error\"\n  throw(e)\ncatch\n  e -> IO.puts(\"Excepción capturada [#{e}]\")\nend\n# Ejercicio extra:  números comprendidos\n# entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\nlista = 10..55\n\nEnum.filter(lista, fn i -> i !== 16 and rem(i, 3) != 0 end)\n|> Enum.join(\",\")\n|> IO.puts()\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/erlang/edalmava.erl",
    "content": "% https://www.erlang.org/doc/reference_manual/expressions\n% https://www.erlang.org/doc/man/lists.html\n\n-module(edalmava).\n-export([imprimir/0, operadorMatch/0, operadoresA/0, operadoresL/0]).\n\nextra([]) ->\n    ok;\nextra([H | T]) ->\n    io:format(\"~p~n\", [H]), extra(T).\n\n% Operador de Coincidencia =\noperadorMatch() ->\n    {A, B} = T = {answer, 42},\n    io:format(\"{A, B} = T = {answer, 42}.~n\", []),\n    io:format(\"A: ~w~n\", [A]),\n    io:format(\"B: ~w~n\", [B]),\n    io:format(\"T: ~w~n\", [T]).\n\noperadoresA() ->\n    % Aritméticos: +, -, *, / (División en punto flotante), div (división entera), rem (resto de la división entera - módulo)\n    io:format(\"Operadores Aritméticos~n\", []),\n    io:format(\"Uso de (+, -, *, / (División de punto flotante)) -> ((12+21-3)*3/9): ~w~n\", [(12+21-3)*3/9]), % Se espera como resultado 10.0 (división en punto flotante - /)\n    io:format(\"División entera(div) -> ((12+21-3)*3 div 9]): ~w~n\", [(12+21-3)*3 div 9]), % Se espera como resultado 10 (división entera - div)\n    io:format(\"Resto de la división entera -> (6 rem 2): ~w~n\", [6 rem 2]), % Se espera como resultado 0 - Resto de la división entera entre 6 y 2\n    io:format(\"Operadores de Lista~n\", []),\n    io:format(\"Expr1 ++ Expr2 -> ([1,2,3]++[4,5]): ~w~n\", [[1,2,3]++[4,5]]), % Se espera [1, 2, 3, 4, 5]\n    io:format(\"Expr1 -- Expr2 -> ([1,2,3,2,1,2]--[2,1,2]): ~w~n\", [[1,2,3,2,1,2]--[2,1,2]]). % Se espera [3, 1, 2]\n\noperadoresL() ->\n    % Lógicos: not, and, or y xor\n    io:format(\"Operadores Lógicos~n\", []),\n    io:format(\"Not -> (not true): ~w - (not false): ~w~n\", [not true, not false]),\n    io:format(\"And ->(true and false): ~w - (true and true): ~w - (false and true): ~w - (false and false): ~w~n\", \n               [true and false, true and true, false and true, false and false]),\n    io:format(\"Or -> (true or false): ~w - (true or true): ~w - (false or true): ~w - (false or false): ~w~n\", \n               [true or false, true or true, false or true, false or false]),\n    io:format(\"Xor -> (true xor false): ~w - (true xor true): ~w - (false xor true): ~w - (false xor false): ~w~n\", \n               [true xor false, true xor true, false xor true, false xor false]).\n\nimprimir() ->\n    io:format(\"Imprime por consola los números del 10 al 55 (incluidos) que son pares y que no son ni el 16 ni los múltiplos de 3~n\", []),\n    extra([X || X <- lists:seq(10, 55), \n                         (X rem 2 =:= 0) \n                         and (X =/= 16) \n                         and (X rem 3 =/= 0)]).\n\n% erl\n% 1> c(edalmava). % Compila el código\n% {ok,edalmava}   % Si la compilación es exitosa\n% 2> edalmava:operadorMatch(). % Para mostrar la sección correspondiente al operador de coincidencia o de match\n% 3> edalmava:operadoresA().   % Para mostrar la sección de los operadores aritméticos incluyendo operaciones con listas\n% 4> edalmava:operadoresL().   % Para mostrar la sección de los operadores lógicos\n% 5> edalmava:imprimir().      % Para mostrar el ejercicio extra "
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/fortran/LeandroCFD.f90",
    "content": "program OPERADORES_ESTRUCTURAS\n    implicit none\n    \n    !Se declaran las variables a utilizar en el programa\n    integer   :: a,aa,ab \n    real      :: b,ba,bb\n    complex   :: c,ca,cb\n    logical   :: d,da,db\n    character (len=60):: e,ea,eb,ec\n\n    !El operador más basico de Fortran es el operador de asignación de valor, tiene la siguiente sintaxis.\n    a=1\n    b=2.1\n    c=(1,2)\n    d=.true.\n    e='Esto es una prueba'\n    print*,a,b,c,d,e\n\n    !OPERACIONES ARITMÉTICAS\n    !Fortran tiene operadores aritmeticos de adicción, sustracción, multiplicación, división, potenciación y cambio de signo.\n    !Las operaciones aritmeticas solo son permitidas para variables de tipo integer, real y complex\n    print*,''\n    print*,'***********************'\n    print*,'OPERACIONES ARITMETICAS'\n    print*,'***********************'\n    !Operaciones aritmeticas entre numeros enteros\n    print*,''\n    print*,'1)Operaciones numeros enteros'\n    aa=2;ab=5\n    print*,'Entero aa es igual a:',aa,'Entero ab es igual a:',ab\n    a=aa+ab !Operador aritmetico de adicción\n    print*,'La suma de aa y ab es igual a:',a\n    a=aa-ab !Operador aritmetico de sustracción\n    print*,'La resta de aa y ab es igual a:',a\n    a=aa*ab !Operador aritmetico de multiplicación\n    print*,'La multiplicacion de aa y ab es igual a:',a\n    a=ab/aa !Operador aritmetico de división\n    print*,'La division de aa y ab es igual a:',a\n    a=aa**ab !Operador arimetico de potenciación\n    print*,'La potenciacion de aa y ab es igual a:',a\n    a=-a    !Operador arimetico de cambio de signo\n    print*,'El cambio de signo de a es igual a:',a\n\n    !Operaciones aritmeticas entre numeros reales\n    print*,''\n    print*,'2)Operaciones numeros reales'\n    ba=4.3;bb=3.1\n    print*,'Entero ba es igual a:',ba,'Entero bb es igual a:',bb\n    b=ba+bb !Operador aritmetico de adicción\n    print*,'La suma de ba y bb es igual a:',b\n    b=ba-bb !Operador aritmetico de sustracción\n    print*,'La resta de ba y bb es igual a:',b\n    b=ba*bb !Operador aritmetico de multiplicación\n    print*,'La multiplicacion de ba y bb es igual a:',b\n    b=ba/bb !Operador aritmetico de división\n    print*,'La division de ba y bb es igual a:',b\n    b=ba**bb !Operador arimetico de potenciación\n    print*,'La potenciacion de ba y bb es igual a:',b\n    b=-b    !Operador arimetico de cambio de signo\n    print*,'El cambio de signo de b es igual a:',b\n\n    !Operaciones aritmeticas entre numeros complejos\n    print*,''\n    print*,'3)Operaciones numeros complejos'\n    ca=(4.3,1);cb=(3.1,2)\n    print*,'Entero ca es igual a:',ca,'Entero cb es igual a:',cb\n    c=ca+cb !Operador aritmetico de adicción\n    print*,'La suma de ca y cb es igual a:',c\n    c=ca-cb !Operador aritmetico de sustracción\n    print*,'La resta de ca y cb es igual a:',c\n    c=ca*cb !Operador aritmetico de multiplicación\n    print*,'La multiplicacion de ca y cb es igual a:',c\n    c=ca/cb !Operador aritmetico de división\n    print*,'La division de ca y cb es igual a:',c\n    c=ca**cb !Operador arimetico de potenciación\n    print*,'La potenciacion de ca y cb es igual a:',c\n    c=-c    !Operador arimetico de cambio de signo\n    print*,'El cambio de signo de c es igual a:',c\n\n    !Existe la posibilidad de convertir tipos de variables en otros.\n    b=a !Se convierte un número entero (a) en un número real (b), aunque el caso contrario es permitido NO es aconsejable.\n    print*,b\n    c=b !Se convierte un número real (b) en un número complejo (c)\n    print*,c\n\n    !Las operaciones aritmeticas en Fortran tienen un orden de solución:\n    !1) Operaciones entre parentesis\n    !2) Operaciones de potenciación\n    !3) Operaciones de multiplicación y división, yendo de izquierda a derecha\n    !4) Operaciones de cambio de signo\n    !5) Operaciones de adicción y sustracción, yendo de izquierda a derecha\n\n    !OPERACIONES DE COMPARACIÓN\n    !Las operaciones de comparación en Fortran tienen dos sintaxis, una para las versiones 90 o posteriores y una para la versión 77\n    !Las expresiones a comparar deben ser de tipo numerico (integer, real o complex) y el resultado es de tipo logical.\n    print*,''\n    print*,'**************************'\n    print*,'OPERACIONES DE COMPARACION'\n    print*,'**************************'\n    print*,''\n    d=ab==aa !Operación de comparación 'es igual a', sintaxis Fortran 90\n    d=ab.eq.aa !Operación de comparación 'es igual a', sintaxis Fortran 77\n    print*,'ab es igual a aa:',d\n    d=ab/=aa !Operación de comparación 'no es igual a', sintaxis Fortran 90\n    d=ab.ne.aa !Operación de comparación 'no es igual a', sintaxis Fortran 77\n    print*,'ab NO es igual a aa:',d\n    d=ab>aa !Operación de comparación 'es estrictamente mayor a', sintaxis Fortran 90\n    d=ab.gt.aa !Operación de comparación 'es estrictamente mayor a', sintaxis Fortran 77\n    print*,'ab es estrictamente mayor a aa:',d\n    d=ab>=aa !Operación de comparación 'es mayor o igual a', sintaxis Fortran 90\n    d=ab.ge.aa !Operación de comparación 'es mayor o igual a', sintaxis Fortran 77\n    print*,'ab es mayor o igual a aa:',d\n    d=ab<aa !Operación de comparación 'es estrictamente menor a', sintaxis Fortran 90\n    d=ab.lt.aa !Operación de comparación 'es estrictamente menor a', sintaxis Fortran 77\n    print*,'ab es estrictamente menor a aa:',d\n    d=ab<=aa !Operación de comparación 'es menor o igual a', sintaxis Fortran 90\n    d=ab.le.aa !Operación de comparación 'es menor o igual a', sintaxis Fortran 77\n    print*,'ab es menor o igual a aa:',d\n\n    !En este punto aprendí a representar acentos desde la terminal (Se debe cambiar la pagina de codigos a UTF-8, se puede desde \n    !vscode o desde la terminal ejecutando el comando \"chcp 65001\")\n\n    !OPERACIONES LÓGICAS\n    !Las operaciones lógicas solo admiten expresiones de tipo logical y el resultado también es de tipo logical.\n    print*,''\n    print*,'*******************'\n    print*,'OPERACIONES LÓGICAS'\n    print*,'*******************'\n    print*,''\n    d=.false.\n    db=.true.\n    print*,'d es igual a:',d,'y db es igual a:',db\n    da=.not.d !Operador de negación, cambia el valor de la expresión lógica a su opuesto, necesita de una sola expresión.\n    print*,'La negacion de d es igual a:',da\n    da=d.and.db !Operador de conjunción (y), verdadero si ambas expresiones son verdaderas \n    print*,'d y db es igual a:',da\n    da=d.or.db !Operador de disyunción inclusiva (o), verdadero si una de las expresiones es verdadera\n    print*,'d o db es igual a:',da\n    da=d.eqv.db !Operador de equivalencia (eqv), verdadero si ambas expresiones tienen el mismo valor \n    print*,'d eqv db es igual a:',da\n    da=d.neqv.db !Operador de no equivalencia o de disyunción inclusiva (neqv o xor), verdadero si ambas expresiones no tienen el\n    !mismo valor \n    print*,'d neqv db es igual a:',da\n\n    !OPERADORES CON CARACTERES\n    !Fortran tiene diferentes operaciones con caracteres como los operadores binarios de concatenación y comparación\n    print*,''\n    print*,'**************************'\n    print*,'OPERACIONES CON CARACTERES'\n    print*,'**************************'\n    print*,''\n    ea='   Bogotá,   '\n    eb=' 2600 metros más cerca de las estrellas'\n    e=adjustl(ea) !Operador que permite eliminar todos los espacios al inicio de la cadena de caracteres\n    print*,'Comparación de el operador adjustl: sin adjustl:',ea,'con adjustl:',e\n    e=adjustr(ea) !Operador que permite eliminar todos los espacios al final de la cadena de caracteres\n    print*,'Comparación de el operador adjustr: sin adjustr:',ea,' con adjustr:',e\n    ec=trim(ea) !Operador que permite eliminar todos los espacios al final de la cadena de caracteres de forma temporal\n    print*,'Comparación de el operador trim: con trim:',trim(ea),' sin trim:',ea\n    e=trim(ea)//trim(eb) !Operador de concatenación\n    print*,e\n    e=adjustl(trim(ea)//trim(eb)) !Combinación de operadores\n    print*,e\n    e=ea(5:8) !Parte de candena de caracteres, en este caso \"e\" queda con los caracteres desde la posición 5 hasta la 8 de \"ea\"\n    print*,e\n    e=ea(:6)  !Parte de candena de caracteres, en este caso \"e\" queda con los caracteres desde el inicio hasta la posición 6 de ea\n    print*,e\n    e=ea(6:)  !Parte de candena de caracteres, en este caso \"e\" queda con los caracteres desde 6 hasta el final de \"ea\"\n    print*,e\n\n    !Fortran no tiene operadores de pertenencia como \"in\" o de identidad como \"is\".\n\n    !ESTRUCTURAS DE CONTROL\n    !CONDICIONALES\n    !Fortran permite los condicionales con la función IF, la sintaxis es la siguiente.\n    print*,''\n    print*,'*************'\n    print*,'CONDICIONALES'\n    print*,'*************'\n    print*,''\n    if (ba>bb) aa=10  !Es posible utilizar condicionales en una sola linea de codigo si las instrucciones son sencillas.\n    print*,\"Resultado condicional una sola linea de codigo:\",aa\n\n    if (ba>bb) then   !O en varias lineas de codigo si son varias instrucciones.\n        aa=a*5\n        print*,\"Resultado condicional varias lineas de codigo:\",aa        \n    end if\n\n    if (bb>ba) then\n        aa=a/2\n        print*,\"Este resultado se imprimira si bb es mayor que ba:\",aa\n    else              !La instrucción else permite ejecutar instrucciones si la condición del if no se cumple.\n        aa=a*2\n        print*,\"Este resultado se imprimira si bb es menor que ba:\",aa        \n    end if\n\n    if (bb>ba) then\n        aa=a**2\n    else if (bb<ba) then  !La instrucción else if permite adicionar un condicional si el primer if no se cumple\n        aa=a+ab\n        print*,\"Este resultado se imprimira si bb es menor que ba (else if):\",aa\n    else              \n        aa=a*2\n        print*,\"Este resultado se imprimira si bb es igual que ba:\",aa   \n    end if\n\n    Prueba : if (ba>bb) then   !Se le puede agregar un nombre al if para dar mayor claridad, en este caso \"Prueba\"\n        aa=a*5\n        print*,\"Resultado condicional varias lineas de codigo:\",aa        \n    end if Prueba\n\n    !BUCLES O CICLOS\n    !Fortran permite diferentes tipos de bucles con la función DO, permite bucles infinitos, bucles while y bucles con \n    !numero finito de iteraciones.\n    print*,''\n    print*,'******'\n    print*,'BUCLES'\n    print*,'******'\n    print*,''\n    !BUCLE INFINITO\n    do        \n        print*,\"Bucle infinito do\"\n        exit  !Se debe utilizar la instrucción exit para detener el ciclo, exit pasara a la siguiente instrucción luego del end do\n    end do\n    aa=9    \n    bucle : do !También es posible darle un nombre al bucle como un identificador\n        !Se llega aquí con la instrucción cycle bucle\n        print*,\"Bucle infinito do con nombre 'bucle'\"\n        bucle_dos : do !Es posible anidar bucles infinitos\n            !Se llega aquí con la instrucción cycle\n            aa=aa+1\n            print*,\"Bucle infinito do con nombre 'bucle_dos'\"\n            if (aa==10) cycle !La instrucción cycle obliga al programa a regresar al inicio de las instrucciones del bucle\n            if (aa==11) cycle bucle !Cycle se puede asosciar al nombre de un bucle\n            if (aa==12) exit bucle_dos !Exit se puede asosciar al nombre de un bucle\n            if (aa==13) exit bucle\n        end do bucle_dos\n        print*,\"Se llega aquí con la instrucción exit bucle_dos\"\n    end do bucle\n    print*,\"Se llega aquí con la instrucción exit bucle\"\n\n    !BUCLE DO WHILE\n    do while (aa>10) !Este ciclo continua hasta que aa sea menor o igual a 10\n        print*,\"Bucle do while, valor de aa es igual a:\",aa\n        aa=aa-1\n    end do\n\n    !BUCLE CON NÚMERO FIJO DE ITERACIONES\n    aa=0\n    do a = 1,6,2 !Este bucle va desde 1 hasta 6 con un incremento de 2, por lo que solo seran 3 iteraciones.\n        aa=aa+1\n        print*,\"Iteración número:\",aa,\"El valor de a es igual a:\",a\n    end do\n    print*,\"Segundo bucle con número fijo de iteraciones\"\n    aa=0\n    do a = 1,6 !Si no se le asigna ningún incremento este será de 1.\n        aa=aa+1\n        print*,\"Iteración número:\",aa,\"El valor de a es igual a:\",a\n    end do\n\n    !ESTRUCTURA CASE\n    !La estructura de control case permite seleccionar un bloque de instrucciones a ser ejecutada, la sintaxis es la siguiente. \n    print*,''\n    print*,'***************'\n    print*,'ESTRUCTURA CASE'\n    print*,'***************'\n    print*,''\n    \n    print*,\"Digita un valor del 1 hasta el 10:\"\n    read*,aa\n    select case (aa) !La variable entre parentesis puede ser de tipo integer, logical o character\n        case (1) \n            print*,\"Seleccionaste el valor 1\"\n        case (2:5) \n            print*,\"Seleccionaste un valor del 2 al 5\"\n        case (6:9) \n            print*,\"Seleccionaste un valor del 6 al 9\"\n        case (10) \n            print*,\"Seleccionaste el valor 10\"\n    end select\n\n    print*,''\n    print*,'****************'\n    print*,'DIFICULTAD EXTRA'\n    print*,'****************'\n    print*,''\n    \n    do a = 10, 55\n        aa=mod(a,2)   !La función mod devuelve el resto de una división con resto, si mod es cero la división es exacta.\n        Impresion : if (aa==0 .or. a==55) then\n            aa=mod(a,3)\n            if (aa==0) exit Impresion\n            if (a==16) exit Impresion\n            print*,a            \n        end if Impresion  \n    end do\n\nend program OPERADORES_ESTRUCTURAS"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/fortran/edalmava.f90",
    "content": "program operadores\n    implicit none        \n    integer :: a, b, n, mes\n    real :: radio   \n\n    print *, 'Estructuras de Control en Fortran'\n    print *, 'Estructuras Alternativas'\n    print *, 'Estructura Alternativa Simple (if-then)'\n    \n    a = 5; b = 10\n    if (a < b) then\n        print *, a, ' es menor que ', b\n    end if\n\n    print *, 'Estructura Alternativa Doble (if-then-else)'\n\n    b = 4\n    if (a < b) then\n        print *, b, ' es menor que ', a\n    else \n        print *, a, ' es mayor que ', b\n    end if\n\n    print *, 'Estructura Multialternativa (case)'\n    print *, 'Digite el número del mes: '\n    read *, mes\n    print *, 'El mes digitado tiene '\n    select case (mes)\n        case (1, 3, 5, 7, 8, 10, 12)\n            print *, '31'\n        case (4, 6, 9, 11)\n            print *, '30'\n        case (2)\n            print *, '28'\n        case default\n            print *, 'Mes incorrecto'\n    end select\n    \n    print *, ''\n    print *, '***********************'\n    print *, 'Estructuras Repetitivas'\n    print *, '***********************'\n    print *, ''\n    print *, 'Estructura desde hasta (do)'\n    do n = 1, 10, 2\n        print *, n\n    end do\n    print *, 'Estructura Mientras (do-while)'\n    radio = -1\n    do while (radio < 0) ! Se solicita el radio hasta que sea positivo\n        print *, 'Digite Radio?(Debe ser positivo)'\n        read  *, radio\n    end do\n    \n    print *, ''\n    print *, '**********'\n    print *, 'RETO EXTRA'\n    print *, '**********'\n    print *, ''\n    do n = 10, 55, 1\n        if (mod(n, 2) == 0 .and. n /= 16 .and. mod(n, 3) /= 0) then \n            print *, n\n        end if\n    end do     \nend program operadores\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/gdscript/ElHacedorDeCosas.gd",
    "content": "# Operadores\n\n#en GDscript todo script tiene que estar asociado a una escena o nodo para poder ejecutarlo\n\n#Operadores Aritméticos\nextends Node\nfunc _ready(): #la función _ready hace que la función se ejecute al momento de iniciar la ecena y solo puede ser usada una vez por script\n    #suma\n    print(10 + 3)\n    #resta\n    print(10 - 3)\n    #multiplicación\n    print(10 * 3)\n    #división\n    print(10 / 3.0) #si no se especifica que uno de los dos numeros es flotante te dará siempre como resultado un entero\n    print(10 / float(3)) #se puede hacer de estas dos formas\n    #modulo o resto\n    print(10 % 3)\n    #potencia\n    print(10 ** 3)\n\n#Operadores de comparación\nextends Node\nfunc _ready():\n    var x = 2\n    print (\"x = \" + str(x)) #para poder hacer print a una variable de tipo texto y una de tipo booleano a la vez\n    #Igualdad               # tienes que convertir esta a texto\n    print(\"x == 10 = \" + str(x == 10))\n    #Desigualdad\n    print(\"x != 10 = \" + str(x != 10))\n    #Mayor que\n    print(\"x > 10 = \" + str(x > 10))\n    #Menor que\n    print(\"x < 10 = \" + str(x < 10))\n    #Mayor o igual que\n    print(\"x >= 10 = \" + str(x >= 10))\n    #Menor o igual que\n    print(\"x <= 10 = \" + str(x <= 10))\n\n#Operadores lógicos\nextends Node\nfunc _ready():\n    # \"and\" o \"&&\"\n    print(\"(2 > 3 and 4 + 3 = 7)= \" + str(2 > 3 and (4 + 3 == 7)))\n    # \"or\" o \"||\"\n    print(\"(2 > 3 or 4 + 3 = 7)= \" + str(2 > 3 or (4 + 3 == 7)))\n    # \"not\" o \"!\"\n    print(\"not 3 > 2 = \" + str(not 3 > 2))\n\n#Operadores de asignación\n#Las asignaciones en GDScript no pueden estar dentro de expreciones \nextends Node\nfunc _ready():\n    #Asignación\n    var y = 7\n    #Suma y asignación\n    y += 2\n    print(y)\n    #Resta y asignación\n    y -= 2\n    print(y)\n    #Multiplicación y asignación\n    y *= 2\n    print(y)\n    #División y asignación\n    y /= 2\n    print(y)\n    #Resto y asignación\n    y %= 2\n    print(y)\n    #Exponente y asignación\n    y **= 2\n    print(y)\n\n#Operadores de pertenencia\nextends Node\nfunc _ready():\n\t# in\n    print(\"u in pablo = \" + str(\"u\" in \"pablo\"))\n    print(\"a in pablo = \" + str(\"a\" in \"pablo\"))\n    # not in\n    print(\"u not in pablo = \" + str(\"u\" not in \"pablo\"))\n    print(\"a not in pablo = \" + str(\"a\" not in \"pablo\"))\n\n#Operadores de bit\nextends Node\nfunc _ready():\n    var numero_uno = 10 #1010\n    var numero_dos = 5  #0101\n    # \"&\" o \"AND\"\n    print(\"10 & 5 = \" + str(numero_uno & numero_dos)) #0  = 0000\n    # \"^\" o \"XOR\"\n    print(\"10 ^ 5 = \" + str(numero_uno ^ numero_dos)) #15 = 1111\n    # \"|\" o \"OR\"\n    print(\"10 | 5 = \" + str(numero_uno | numero_dos)) #15 = 1111\n    # \"~\" o \"NOT\"\n    print(\"~10 = \" + str(~numero_uno)) #-11\n    # Desplazamiento a la derecha o \">>\"\n    print(\"10 >> 3 = \" + str(numero_uno >> 3)) #1  = 0000001\n    # Desplazamiento a la izquierda o \"<<\"\n    print(\"10 << 3 = \" + str(numero_uno << 3)) #80 = 1010000\n\n#Estructuras de control\n\n#Condicionales\nextends Node\nvar edad = 21\nfunc _ready():\n    #Condicional \"si\" o \"if\"\n    if (edad < 18):\n        print (\"eres menor de edad\")\n    #Condicional \"sino, si\" o \"elif\"\n    elif (edad > 29):\n        print(\"eres un adulto\")\n    #Condicional \"sino\" o \"else\"\n    else: print(\"eres un joven adulto\")\n\n#Iterativas\nextends Node \nfunc _ready():\n    for i in 7:\n        print(i)\n    for i in range(7):\n        print(i)\n    #while\n    var i = 0\n    while (i< 12):\n        print(i)\n        i += 2\n    \n#Excepciones\n#GDScript no maneja execpriones y la explicaciñon sacada de la pagina de GDScript es la siguiente:\n#\"Creemos que los juegos no deben fallar no importa la situación. Si una situación inesperada sucede,\n#Godot mostrara un error (el cual puede incluso llevarte al script),\n#pero seguidamente intentara recuperarse lo mejor posible y continuar en la medida de lo posible.\"\n\n\n#Ejercicio extra\nextends Node\nfunc _ready():\n    for numero in range(10, 56, 2): #en el rango entre 10 y 56 avanza cada 2 numeros\n        if numero != 16 and numero % 3 != 0:\n            print(numero)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/go/Aldroide.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc main(){\n\t// Operadores aritmeticos\n\tfmt.Printf(\"La suma de 2 + 3 es: %d \\n\", 2+3)\n\tfmt.Printf(\"La suma de 2 - 3 es: %d \\n\", 2-3)\n\tfmt.Printf(\"La suma de 2 * 3 es: %d \\n\", 2*3)\n\tfmt.Printf(\"La suma de 6 / 3 es: %d \\n\", 2/3)\n\tfmt.Printf(\"La suma de 6 %% 3 es: %d \\n\", 2%3)\n\t\n\t// Operaciones relacionales\n\tfmt.Printf(\"5 == 4\\n\", 5==4)\n\tfmt.Printf(\"5 != 4\\n\", 5!=4)\n\tfmt.Printf(\"5 < 4\\n\", 5<4)\n\tfmt.Printf(\"5 <= 4\\n\", 5<=4)\n\tfmt.Printf(\"5 > 4\\n\", 5>4)\n\tfmt.Printf(\"5 >= 4\\n\", 5>=4)\n\n\t// Operadores logicos\n\tfmt.Printf(\"(5 > 4) && (5 == 3) es: %t \\n\", (5 > 3) && (5 == 3))\n\tfmt.Printf(\"(5 >= 4) || (5 < 3) es: %t \\n\", (5 >= 3) || (5 < 3))\n\tfmt.Printf(\"!(5 != 4) es: %t \\n\", !(5 != 3))\n\n\t// Operadores bit a bit\n\tvar x int = 8\n\tvar y int = 4\n\n\tfmt.Printf(\"El resultado de 8 & 4 es: %d \\n\", x&y)\n\tfmt.Printf(\"El resultado de 8 | 4 es: %d \\n\", x|y)\n\tfmt.Printf(\"El resultado de 8 ^ 4 es: %d \\n\", x^y)\n\tfmt.Printf(\"El resultado de 8 << 2 es: %d \\n\", x<<2)\n\tfmt.Printf(\"El resultado de 8 >> 2 es: %d \\n\", x>>2)\n\n\t// Estructuras de Control\n\n\t// Ejemplo de if.. else\n\n\tif 5 > 3 {\n\t\tfmt.Println(\"5 es mayor que 3\")\n\t} else {\n\t\tfmt.Println(\"5 no es mayor que 3\")\n\t}\n\n\t// Ejemplo de switch\n\n\tswitch 5 {\n\tcase 1:\n\t\tfmt.Println(\"El numero es 1\")\n\tcase 2:\n\t\tfmt.Println(\"El numero es 2\")\n\tcase 3:\n\t\tfmt.Println(\"El numero es 3\")\n\tcase 4:\n\t\tfmt.Println(\"El numero es 4\")\n\tcase 5:\n\t\tfmt.Println(\"El numero es 5\")\n\tdefault:\n\t\tfmt.Println(\"El numero es mayor que 5\")\n\t}\n\n\t// Ejemplo de for\n\n\tfor i := 0; i < 5; i++ {\n\t\tfmt.Println(i)\n\t}\n\n\t// Ejemplo de for con range\n\n\tmy_array := []int{1, 2, 3, 4, 5}\n\n\tfor index, value := range my_array {\n\t\tfmt.Printf(\"El valor en la posicion %d es %d \\n\", index, value)\n\t}\n\n\t// while\n\n\tj := 0\n\tfor j < 5 {\n\t\tfmt.Println(j)\n\t\tj++\n\t}\n\n\t// do while\n\n\tk := 0\n\tfor {\n\t\tfmt.Println(k)\n\t\tk++\n\t\tif k == 5 {\n\t\t\tbreak\n\t\t}\n\t}\n\n\t// Extra\n\n\tfor i := 10; i <= 55; i++ {\n\t\tif i%2 == 0 && i != 16 && i%3 != 0 {\n\t\t\tfmt.Println(i)\n\t\t}\n\t}\n\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/go/AmadorQuispe.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"math/rand\"\n)\n\n//#01 OPERADORES Y ESTRUCTURAS DE CONTROL\n\nfunc main() {\n\tfmt.Println(\"OPERADORES ARITMÉTICOS\")\n\tfmt.Println(\"--------------------\")\n\t// Operadores aritméticos.\n\n\tvar number1 = 10\n\tvar number2 = 3\n\tfmt.Printf(\"SUMA DE %d Y %d ES %d \\n\", number1, number2, number1+number2)\n\tfmt.Printf(\"RESTA DE %d Y %d ES %d \\n\", number1, number2, number1-number2)\n\tfmt.Printf(\"DIVISIÓN DE %d Y %d ES %v \\n\", number1, number2, number1/number2)\n\tfmt.Printf(\"MULTIPLICACIÓN DE %d Y %d ES %d \\n\", number1, number2, number1*number2)\n\tfmt.Printf(\"MODULO DE %d Y %d ES %d \\n\", number1, number2, number1%number2)\n\n\tfmt.Println(\"OPERADORES DE COMPARACIÓN\")\n\tfmt.Println(\"--------------------\")\n\t//Operadores de comparación\n\tfmt.Printf(\"(==) El número %d es igual a %d ? : %v \\n\", number1, number2, number1 == number2)\n\tfmt.Printf(\"(!=) El número %d es diferente de %d ? : %v \\n\", number1, number2, number1 != number2)\n\tfmt.Printf(\"(<) El número %d es menor que %d ? : %v \\n\", number1, number2, number1 < number2)\n\tfmt.Printf(\"(>) El número %d es mayor que %d ? : %v \\n\", number1, number2, number1 > number2)\n\tfmt.Printf(\"(<=) El número %d es menor o igual que %d ? : %v \\n\", number1, number2, number1 <= number2)\n\tfmt.Printf(\"(>=) El número %d es mayor o igual que %d ? : %v \\n\", number1, number2, number1 >= number2)\n\n\tfmt.Println(\"OPERADORES LÓGICOS\")\n\tfmt.Println(\"--------------------\")\n\t//Operadores de comparación\n\tfmt.Printf(\"(&&) El número %d y %d es mayor a CERO ? : %v \\n\", number1, number2, number1 > 0 && number2 > 0)\n\tfmt.Printf(\"(||) El número %d ó %d es mayor a CERO ? : %v \\n\", number1, number2, number1 > 0 || number2 > 0)\n\tfmt.Printf(\"(!) El número %d es mayor a CERO (negación) ? : %v \\n\", number1, !(number1 > 0))\n\n\tfmt.Println(\"OPERADORES UNARIOS\")\n\tfmt.Println(\"--------------------\")\n\t//Operadores unarios\n\tfmt.Printf(\"(+) El número %d en positivo\\n\", +number1)\n\tfmt.Printf(\"(-) El número %d en negativo\\n\", -number1)\n\tnumber1++\n\tfmt.Printf(\"(++) El número %v\\n\", number1)\n\tnumber1--\n\tfmt.Printf(\"(--) El número %v\\n\", number1)\n\n\tfmt.Println(\"OPERADORES DE ASIGNACIÓN\")\n\tfmt.Println(\"--------------------\")\n\t//operadores de asignación\n\t//Declarar una variable\n\tvar num1 uint\n\tnum1 = 120\n\tfmt.Println(\"El valor asignado de la variable 'num1' es \", num1)\n\tnum1 += 10\n\tfmt.Println(\"El valor de la variable 'num1' incrementado en 10 es \", num1)\n\tnum1 -= 4\n\tfmt.Println(\"El valor de la variable 'num1' decrementado en 4 es \", num1)\n\tnum1 *= 2\n\tfmt.Println(\"El valor de la variable 'num1' multiplicado por 2 es \", num1)\n\tnum1 /= 2\n\tfmt.Println(\"El valor de la variable 'num1' dividido en 2 es \", num1)\n\tnum1 %= 2\n\tfmt.Println(\"El resto de dividir en 2 de la variable 'num1' es \", num1)\n\n\tfmt.Println(\"OPERADORES LÓGICOS A NIVEL DE BITS\")\n\tfmt.Println(\"--------------------\")\n\t//operadores lógicos a nivel de Bits\n\n\t// Declarar dos variables de tipo entero\n\tvar a int = 10\n\tvar b int = 7\n\n\tvar resultado int = a & b\n\tfmt.Println(\"El resultado de la operación AND a nivel de bits es:\", resultado)\n\n\tresultado = a | b\n\tfmt.Println(\"El resultado de la operación OR a nivel de bits es:\", resultado)\n\n\tresultado = a ^ b\n\tfmt.Println(\"El resultado de la operación XOR a nivel de bits es:\", resultado)\n\n\tresultado = a << 2\n\tfmt.Println(\"El resultado del desplazamiento a la izquierda es:\", resultado)\n\n\tresultado = a >> 2\n\tfmt.Println(\"El resultado del desplazamiento a la derecha es:\", resultado)\n\n\tresultado = ^a\n\tfmt.Println(\"El resultado de la operación NOT a nivel de bits es:\", resultado)\n\n\tfmt.Println(\"FLUJOS DE CONTROL\")\n\tfmt.Println(\"-------------------\")\n\n\tfmt.Println(\"IF \")\n\tfmt.Println(\"-------------------\")\n\tvar valor = rand.Int()\n\tif valor%2 == 0 {\n\t\tfmt.Println(\"El número \", valor, \" es par\")\n\t}\n\n\tfmt.Println(\"IF ELSE\")\n\tfmt.Println(\"-------------------\")\n\tif valor%2 == 0 {\n\t\tfmt.Println(\"El número \", valor, \" es par\")\n\t} else {\n\t\tfmt.Println(\"El número \", valor, \" no es par\")\n\t}\n\n\tfmt.Println(\"ELSE IF\")\n\tfmt.Println(\"-------------------\")\n\tqualification := 75\n\tif qualification >= 90 {\n\t\tfmt.Println(\"Excelente\")\n\t} else if qualification >= 80 {\n\t\tfmt.Println(\"Muy bien\")\n\t} else if qualification >= 70 {\n\t\tfmt.Println(\"Bien\")\n\t} else {\n\t\tfmt.Println(\"Regular\")\n\t}\n\n\tfmt.Println(\"SWITCH SIN CONDICIÓN\")\n\tfmt.Println(\"-------------------\")\n\tswitch {\n\tcase qualification >= 90:\n\t\tfmt.Println(\"Excelente\")\n\tcase qualification >= 80:\n\t\tfmt.Println(\"Muy bien\")\n\tcase qualification >= 70:\n\t\tfmt.Println(\"Bien\")\n\tdefault:\n\t\tfmt.Println(\"Regular\")\n\t}\n\n\tfmt.Println(\"SWITCH CASE\")\n\tfmt.Println(\"-------------------\")\n\tweekday := 2\n\tswitch weekday {\n\tcase 1:\n\t\tfmt.Println(\"Lunes\")\n\tcase 2:\n\t\tfmt.Println(\"Martes\")\n\tcase 3:\n\t\tfmt.Println(\"Miércoles\")\n\tcase 4:\n\t\tfmt.Println(\"Jueves\")\n\tcase 5:\n\t\tfmt.Println(\"Viernes\")\n\tcase 6:\n\t\tfmt.Println(\"Sábado\")\n\tcase 7:\n\t\tfmt.Println(\"Domingo\")\n\tdefault:\n\t\tfmt.Println(\"Día no valido\")\n\t}\n\n\tfmt.Println(\"FOR COMÚN\")\n\tfmt.Println(\"-------------------\")\n\tfor i := 0; i < 10; i++ {\n\t\tfmt.Println(i)\n\t}\n\n\tfmt.Println(\"FOR ESTILO WHILE\")\n\tfmt.Println(\"-------------------\")\n\tvar i = 0\n\tfor i < 10 {\n\t\tfmt.Println(i)\n\t\ti++\n\t}\n\n\tfmt.Println(\"FOR RANGE\")\n\tfmt.Println(\"-------------------\")\n\tfor i, letter := range \"amsoft.dev\" {\n\t\tfmt.Println(i, string(letter))\n\t}\n\n\tfmt.Println(\"FOR FOREVER (for infinito)\")\n\tfmt.Println(\"-------------------\")\n\tfor {\n\t\tfmt.Print(\"Salir? (s/n): \")\n\t\tvar c rune\n\t\tfmt.Scanf(\"%c\\n\", &c)\n\t\tif c == 'S' || c == 's' {\n\t\t\tbreak\n\t\t}\n\t}\n\n\tfmt.Println(\"EXTRA\")\n\t/* \t* Crea un programa que imprima por consola todos los números comprendidos\n\t* entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3. */\n\tfor i := 10; i <= 55; i++ {\n\t\tif !(i == 16 || i%3 == 0) {\n\t\t\tfmt.Println(i)\n\t\t}\n\t}\n\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/go/DiegoKarabin.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc main() {\n\tprintln(\"Operadores Aritmeticos\")\n\tprintln(\"suma (+): 3 + 2 =\", 3 + 2)\n\tprintln(\"resta (-): 3 - 2 =\", 3 - 2)\n\tprintln(\"producto (*): 3 * 2 =\", 3 * 2)\n\tprintln(\"cociente entero (/): 3 / 2 =\", 3 / 2)\n\tprintln(\"cociente flotante (/): 3 / 2. =\", 3 / 2.)\n\tprintln(\"residuo (%): 3 % 2 =\", 3 % 2)\n\n\tprintln(\"\\nOperadores Logicos\")\n\tprintln(\"and (&&): true && false =\", true && false)\n\tprintln(\"or (||): true || false =\", true || false)\n\tprintln(\"not (!): !true =\", !true)\n\n\tprintln(\"\\nOperadores de comparacion\")\n\tprintln(\"es igual que (==): 2 == 2 =\", 2 == 2)\n\tprintln(\"no es igual que / es distinto que (!=): 3 != 2 =\", 3 != 2)\n\tprintln(\"es menor que (<): 2 < 3 =\", 2 < 3)\n\tprintln(\"es menor o igual que (<=): 3 <= 3 =\", 3 <= 3)\n\tprintln(\"es mayor que (>): 3 > 2 =\", 3 > 2)\n\tprintln(\"es mayor o igual que (>=): 4 >= 4 =\", 4 >= 4)\n\n\tprintln(\"\\nOperadores de asignacion\")\n\tfoo := 42\n\tprintln(\"Para declaracion y asignacion con inferencia del tipo de dato (:=): foo := 42; foo; //\", foo)\n\tfoo = 43\n\tprintln(\"Asignacion (=): foo = 43; foo; //\", foo)\n\n\tprintln(\"\\nOperadores aritmeticos y de asignacion combinados\")\n\tfoo += 2\n\tprintln(\"aumentar (+=): foo += 2; foo; //\", foo)\n\tfoo -= 2\n\tprintln(\"disminuir (-=): foo -= 2; foo; //\", foo)\n\tfoo *= 2\n\tprintln(\"multiplicar (*=): foo *= 2; foo; //\", foo)\n\tfoo /= 2\n\tprintln(\"dividir (/=): foo /= 2; foo; //\", foo)\n\tfoo %= 2\n\tprintln(\"residuo (%=): foo %= 2; foo; //\", foo)\n\n\tprintln(\"\\nOperadores de incremento y decremento\")\n\tfoo++\n\tprintln(\"incremento (++): foo++; //\", foo)\n\tfoo--\n\tprintln(\"decremento (--): foo--; //\", foo)\n\n\tprintln(\"\\nOperadores a nivel de bits\")\n\tconst uint8_a uint8 = 0b0011\n\tconst uint8_b uint8 = 0b0101\n\tfmt.Printf(\"and (&): %08b & %08b = %08b\\n\", uint8_a, uint8_b, uint8_a & uint8_b)\n\tfmt.Printf(\"or (|): %08b & %08b = %08b\\n\", uint8_a, uint8_b, uint8_a | uint8_b)\n\tfmt.Printf(\"xor (^): %08b ^ %08b = %08b\\n\", uint8_a, uint8_b, uint8_a ^ uint8_b)\n\tfmt.Printf(\"not (^): ^%08b = %08b\\n\", uint8_b, ^uint8_b)\n\tfmt.Printf(\"and not (&^): %08b &^ %08b = %08b\\n\", uint8_a, uint8_b, uint8_a &^ uint8_b)\n\tfmt.Printf(\"left shift (<<(uint)): %08b<<2 = %08b\\n\", uint8_a, uint8_a<<2)\n\tfmt.Printf(\"right shift (>>(uint)): %08b>>2 = %08b\\n\", uint8_a, uint8_a>>2)\n\n\tprintln(\"\\nOperadores de direccion\")\n\tvar my_variable int = 123\n\tvar pointer *int = &my_variable\n\tprintln(\"retorna un puntero (&): &my_variable = \", &my_variable)\n\tprintln(\"va al puntero y devuelve el valor al que refiere (*): *pointer = \", *pointer)\n\n\n\tprintln(\"\\nEstructuras de control\")\n\tprintln(\"if\")\n\n\tvar condition bool = true\n\n\tif condition {\n\t\tprintln(\"Se cumple la condicion y se entra al bloque if.\")\n\t}\n\n\tother_condition := false\n\tprintln(\"\\nif/else\")\n\n\tif other_condition {\n\t\tprintln(\"Se cumple la condicion y se entra al bloque if.\")\n\t} else {\n\t\tprintln(\"No se cumple la condicion y se entra al bloque else.\")\n\t}\n\n\tmy_value := 1\n\tprintln(\"\\nswitch\")\n\n\tswitch my_value {\n\tcase 1: println(\"Uno\")\n\tcase 2: println(\"Dos\")\n\tcase 3: println(\"Tres\")\n\tdefault: println(\"Número desconocido\")\n\t}\n\n\tprintln(\"\\nfor\")\n\tfor i := 1; i <= 5; i++ {\n\t\tprint(i, \" \")\n\t}\n\tprintln()\n\n\tprintln(\"\\nExtra\")\n\tfor i := 10; i <= 55; i += 2 {\n\t\tif (!(i == 16 || i % 3 == 0)) {\n\t\t\tprintln(i)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/go/FreyFonseca117.go",
    "content": "// # #01 OPERADORES Y ESTRUCTURAS DE CONTROL\n// > #### Dificultad: Fácil | Publicación: 02/01/24 | Corrección: 08/01/24\n\n// ## Ejercicio\n\n// ```\n// /*\n//  * EJERCICIO:\n//  * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n//  *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n//  *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n//  * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n//  *   que representen todos los tipos de estructuras de control que existan\n//  *   en tu lenguaje:\n//  *   Condicionales, iterativas, excepciones...\n//  * - Debes hacer print por consola del resultado de todos los ejemplos.\n//  *\n//  * DIFICULTAD EXTRA (opcional):\n//  * Crea un programa que imprima por consola todos los números comprendidos\n//  * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n//  *\n//  * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n//  */\n// ```\n// #### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\n// Sigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n// > Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n\npackage main\n\nimport \"fmt\"\n\n// variables universales\nvar a int = 5\nvar b int = 10\n\nfunc aritmeticos() {\n\t// Operadores aritméticos\n\tsuma := a + b\n\tresta := a - b\n\tmultiplicacion := a * b\n\tdivision := a / b\n\tmodulo := a % b\n\tfmt.Printf(\"La suma de %d + %d es: %d \\n\", a, b, suma)\n\tfmt.Printf(\"La resta de %d - %d es: %d \\n\", a, b, resta)\n\tfmt.Printf(\"La multiplicación de %d * %d es: %d \\n\", a, b, multiplicacion)\n\tfmt.Printf(\"El módulo de %d %% %d es: %d \\n\", a, b, modulo)\n\tfmt.Printf(\"La división de %d / %d es: %d \\n\", a, b, division)\n}\n\nfunc logicos() {\n\t// Operadores lógicos\n\tfmt.Printf(\"(3 < 5) && (5 > 3) es: %t \\n\", 3 < 5 && 5 > 3)\n\tfmt.Printf(\"(3 < 5) || (5 > 3) es: %t \\n\", 3 < 5 || 2 > 3)\n\tfmt.Printf(\"(3 != 5) es: %t \\n\", 3 != 5)\n\tfmt.Printf(\"(3 == 5) es: %t \\n\", 5 == 5)\n}\n\nfunc operadoresAsignacion() {\n\t// Operadores de asignación\n\ta += b\n\tfmt.Printf(\"a += b es: %d \\n\", a) // 15\n\ta -= b\n\tfmt.Printf(\"a -= b es: %d \\n\", a) // 5\n\ta *= b\n\tfmt.Printf(\"a *= b es: %d \\n\", a) // 50\n\ta /= b\n\tfmt.Printf(\"a /= b es: %d \\n\", a) // 5\n\ta %= b\n\tfmt.Printf(\"a %%= b es: %d \\n\", a) // 5\n\n}\nfunc condicionales() {\n\t// Condicionales if\n\tif a > b {\n\t\tfmt.Printf(\"%d es mayor que %d \\n\", a, b)\n\t} else if a == b {\n\t\tfmt.Printf(\"%d es igual a %d \\n\", a, b)\n\t} else {\n\t\tfmt.Printf(\"%d es menor que %d \\n\", a, b)\n\t}\n\n\t// Condicionales switch\n\tswitch a == b {\n\tcase true:\n\t\tfmt.Println(\"a es igual a b\")\n\tcase false:\n\t\tfmt.Println(\"a no es igual a b\")\n\t}\n}\n\nfunc iterativas() {\n\t// Iterativas\n\n\t// for con inicialización y condición\n\tfor i := 0; i < 10; i++ {\n\t\tfmt.Printf(\"Iteracion %d \\n\", i)\n\t}\n\t// for con condición\n\ti := 0\n\tfor i < 10 {\n\t\tfmt.Printf(\"Iteración %d \\n\", i)\n\t\ti++\n\t}\n\t// for infinito\n\ti = 0\n\tfor {\n\t\tfmt.Printf(\"Iteración %d \\n\", i)\n\t\ti++\n\t\tif i == 10 {\n\t\t\tbreak\n\t\t}\n\t}\n}\n\n// actividad extra\nfunc funcionExtra() {\n\tfor i := 10; i <= 55; i++ {\n\t\tif i%2 == 0 && i != 16 && i%3 != 0 {\n\t\t\tfmt.Printf(\"El numero %d es una salida del for \\n\", i)\n\t\t}\n\t}\n}\nfunc main() {\n\taritmeticos()\n\tlogicos()\n\toperadoresAsignacion()\n\tcondicionales()\n\titerativas()\n\tfuncionExtra()\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/go/MiguelP-Dev.go",
    "content": "package main\n\nimport \"fmt\"\n\nvar a, b, c = 4, 7, 9\n\nfunc main() {\n\t/*\n\t   Debemos Respetar y tener en cuenta en nuestra lógica; la gerarquía de operadores.\n\t*/\n\n\t// Operadores aritméticos y su gerarquía\n\t/*\n\t\t() las operaciones entre parentesis siempre operan primero\n\t\t* Las multiplicaciones son las siguientes en la gerarquía\n\t\t/ Le siguen las diviones\n\t\t% El módulo\n\t\t+ La suma\n\t\t- Y al final la resta\n\t*/\n\tfmt.Println(\"(2 + 3) * 3: \", (a+b)*c) // El resultado sería 15 porque la operación entre parentesis opera primero\n\tfmt.Println(\"2 + 3 * 3: \", a+b*c)     // El resultado sería 11 porque la multiplicación opera antes que la suma.\n\tfmt.Println(\"2 * 3: \", a*b)           // 6\n\tfmt.Println(\"2 / 3: \", a/b)           // 0,666666666666666\n\tfmt.Println(\"2 % 3: \", a%b)           // 0,06\n\tfmt.Println(\"2 + 3: \", a+b)           // 5\n\tfmt.Println(\"2 - 3: \", a-b)           // -1\n\n\t// Operadores de asignación\n\t/*\n\t\t= Operador de asignación\n\t\t+= Opercador de asignación con suma para adicionar un valor a la variable\n\t*/\n\n\t// b Variable para uso de los ejemplos con operadores\n\tvar b uint8 = 5\n\tfmt.Println(\"Valor de b: \", b)\n\tb = b + 2\n\tfmt.Println(\"b + 2: \", b)\n\t// Combinando los operadores aritméticos con el de asignación\n\tb += 2\n\tfmt.Println(\"b + 2: \", b)\n\tb -= 2\n\tfmt.Println(\"b - 2\", b)\n\tb *= 2\n\tfmt.Println(\"b * 2: \", b)\n\tb /= 2\n\tfmt.Println(\"b / 2: \", b)\n\tb %= 2\n\tfmt.Println(\"b % 2: \", b)\n\n\t// Operadores de Incremento(++) y Decremento(--)\n\t/*\n\t\tEstos operadores son declaraciones, no expresiones:\n\t\tLas expresiones producen un valor a partir de sus operaciones.\n\t\tlas declaraciones son instrucciones del lenguaje que realizan una acción.\n\t*/\n\n\t// incre Variable para el ejemplo correcto en go sobre el incremento\n\tincre := 7\n\tincre++\n\tfmt.Println(incre)\n\n\t// decre Variable para el ejemplo correcto en go sobre el decremento\n\tdecre := 10\n\tdecre--\n\tfmt.Println(decre)\n\t/*\n\t   Nota: Golang no permite el uso de estos operadores de decremento e incremento dentro de Print.\n\t   Es obligaorio operar fuera de esta y luego entregar el resultado o hacer lo que sea para lo que se use el valor reultante de la operación.\n\t*/\n\n\t// Operadores lógicos y de comparación.\n\t/*\n\t\t> Mayor que\n\t\t< Menor que\n\t\t== Operador de igualdad exacta\n\t\t!= Operador de diferencia\n\t\t>= Mayor o igual que\n\t\t<= Menor o igual que\n\t*/\n\n\t// mayor variable entera con número mayor para operar en los ejemplos.\n\tmayor := 21\n\n\t// menor variable entera con número menor para operar en los ejemplos.\n\tmenor := 15\n\n\t// Impresion de los ejemplos de operadores de comparación.\n\tfmt.Println(mayor, \"¿es mayor que? \", menor, \": \", mayor > menor)\n\tfmt.Println(mayor, \"¿es menor que? \", menor, \": \", mayor < menor)\n\tfmt.Println(mayor, \"¿es diferente? \", menor, \": \", mayor != menor)\n\tfmt.Println(mayor, \"¿es igual que? \", menor, \": \", mayor == menor)\n\tfmt.Println(mayor, \"¿es mayor o igual que? \", menor, \": \", mayor >= menor)\n\tfmt.Println(mayor, \"¿es menor o igual que? \", menor, \": \", mayor <= menor)\n\n\t// Operadores lógicos\n\t/*\n\t   && Operador (Y): Usado con otros operadores para comparar más de una condición o comprobación.\n\t   || Operador (O): Usado con otros operadores para comparar si se cumple alguna de las condiciones o comprobaciones.\n\t   ! Operador de negación(Unario): Se usa para negar un resultado o más bien convertir a falso un resultado aunque este sea verdadero.\n\t*/\n\n\t// Operador (O)\n\tfmt.Println(\"My es mayor que MN o Mn es Mayor que My\", mayor > menor || menor > mayor)\n\tfmt.Println(\"My es mayor que MN o Mn es Mayor que My\", menor <= menor || menor <= mayor)\n\n\t// Operador (Y)\n\tfmt.Println(\"My es mayor que MN o Mn es Mayor que My\", mayor > menor && menor < mayor)\n\tfmt.Println(\"My es mayor que MN o Mn es Mayor que My\", mayor > menor && menor == mayor)\n\n\t// Operador (!) Unario\n\tfmt.Println(\"My es mayor que MN o Mn es Mayor que My\", !(mayor > menor && menor == mayor))\n\tfmt.Println(\"My es mayor que MN o Mn es Mayor que My\", !(mayor > menor && menor != mayor))\n\n\t// Operadores bit a bit\n\tba := 12 // 1100 en binario\n\tbb := 10 // 1010 en binario\n\n\t// Operador AND(&): Compara cada bit de los números. Si ambos son 1, el resultado es 1,\n\t// de lo contrario, es 0\n\tresult := ba & bb\n\tfmt.Printf(\"%d & %d = %d\\n\", ba, bb, result) //  8 o 1000 en binario.\n\n\t// Operador OR(|): Compara cada bit de dos números. S al menos 1 de los bits es 1, el resultado es 1,\n\t// de lo contrario será 0.\n\tresult = ba | bb\n\tfmt.Printf(\"%d | %d = %d\\n\", ba, bb, result) // 14 o 1110 en binario.\n\n\t// Operador XOR(^): Compara cada bit de dos números. Si los bits son diferentes, el resuktado es 1,\n\t// si son iguales, es 0.\n\tresult = ba ^ bb\n\tfmt.Printf(\"%d & %d = %d\\n\", ba, bb, result) // 6 o 0110 en binario.\n\n\t// Operador NOT(^): Este operador Invierte cada bit del número. Convierte los 1 en 0 y viceversa.\n\t// El resultado puede parecer extraño porque los número negativos usan una técnica llamada:\n\t// Complemento a dos, pero la idea principal es que cada bit se invierta.\n\tresult = ^bb\n\tfmt.Printf(\"^%d = %d\\n\", bb, result) // -11 o 0101 en binario.\n\n\t// Operador Desplazamientos a la izquierda(<<): Este operador a la derecha los bits en base al valor seleccionado:\n\t// para este ejemplo 2 posiciones a la izquierda, rrellenando los espacios vacios con 0.\n\t// Esta equivale a multiplicar el número por el valor asignado.\n\tresult = bb << 2\n\tfmt.Printf(\"%d << 2 = %d\\n\", bb, result) // 40 o 101000 en binario.\n\n\t// Operador Desplazamientos a la derecha(>>): Este operador desplaza los bits del número a la derecha,\n\t// eliminando los bits desplazados y rellenando los espacios vacios con 0(Para números positivos).\n\t// Cada Desplazamiento a la derecha equivale a dividir el número por el valor asignado\n\tresult = ba >> 2\n\tfmt.Printf(\"%d >> 2 = %d\\n\", ba, result) // 3 o 0011 en binario.\n\n\t// Estructuras de control\n\n\t//  Condicionales  If y Switch\n\t/*\n\t\tEn go es posible declarar la variable en la misma comprobación del if, así queda aislada si se necesita así.\n\t\tLos if son muy adecuados a la hora de controlar errores o como estructura de control para casos sencillos.\n\t\tPara casos donde las condiciones son muchas y es complicado anidar bien los if, es mejor switch\n\t*/\n\n\tif num := 80; num > 90 {\n\t\tfmt.Println(\"Es mayor de noventa\")\n\t} else if num < 90 && num > 80 {\n\t\tfmt.Println(\"Es menor que noventa y mayor que 80\")\n\t} else {\n\t\tfmt.Println(\"Es 80 o menor\")\n\t}\n\n\t// name Variable usada en el switch\n\tname := \"Miguel\"\n\n\t/*\n\t\tLas estructuras Switch puede crearse sin pasarle una expresion para la\n\t\tcomprobación y realizar la comprobación directamente en casa case, esto por si queremos evaluar\n\t\tdistintas condiciones con parametros distintos cada vez.\n\t\tNota: En golang no es necesario usar la palabra reservada \"Break\" para finalizar el switch\n\t\teste se detendrá al cumplirse cualquier condición o la condicion default.\n\t*/\n\t//  Este es una estrucutura de control ideal para concantenar multiples condiciones.\n\tswitch name {\n\tcase \"Alejandro\":\n\t\tfmt.Println(\"El nombre es Alejandro\")\n\tcase \"Miguel\":\n\t\tfmt.Println(\"El nombre es Miguel\")\n\tdefault:\n\t\tfmt.Println(\"El nombre es Desconocido\")\n\n\t}\n\n\t// Fallthrough de switch.\n\t// En la declaración switch de go, cada rama no cae automaticamente al siguiente caso,\n\t// a menos que se utilice la palabra reservada fallthrough: en el siguiente caso;\n\t// aunque el primer case coincide,\n\t// debido a la presencia de la palabra falltrough, este seguirá al siguiente caso e imprimirá\n\t// la frase del caso 2.\n\tswitch name {\n\tcase \"Miguel\":\n\t\tfmt.Println(\"EL nombre es Miguel.\")\n\t\tfallthrough\n\tcase \"Alejandro\":\n\t\tfmt.Println(\"El nombre es Alejandro.\")\n\tdefault:\n\t\tfmt.Println(\"El nombre no coincide.\")\n\t}\n\n\t/*\n\t\tRamificación por tipo y ramificación perzonalizada\n\t\tLa declaración switch también admite ramificación en tipos de variables,\n\t\tconocida como ramificación por tipo. Además, podemos crear condiciones\n\t\tde ramificación personalizadas más complejas.\n\n\t\tNota: las ramificaciones personalizadas se pueden escribir para realizar\n\t\tjuicios condicionales más complejos según sea necesario.\n\t*/\n\t// i Variable de uso en ejemplo de switch.\n\tvar i interface{} = 1\n\n\tswitch i.(type) {\n\tcase int:\n\t\tfmt.Println(\"i es un entero\")\n\tcase float64:\n\t\tfmt.Println(\"i es un float64\")\n\tdefault:\n\t\tfmt.Println(\"i es otro tipo\")\n\t}\n\n\t// Ciclo for\n\tfor i := 0; i < 5; i++ {\n\t\tfmt.Println(\"El valor de i es: \", i)\n\t}\n\n\t// Ciclo infinito: se omite la inicializacion, la expresion de condición y la declaración post del bucle.\n\t// Creando un bucle infinito que solo se detendrá con la palabra reservada break o un valor de retorno de una función.\n\tfor {\n\t\tn := 0\n\t\tif n == 5 {\n\t\t\tbreak\n\t\t}\n\t\tfmt.Println(\"El valor de n es: \", n)\n\t\tn++\n\t}\n\n\t// Llamada a la función para usar defer\n\tcallDefer()\n\n\t// Llamada a la función de divisón para uso de panic y Recover\n\tdivision(12, 2)\n\tdivision(50, 2)\n\tdivision(5, 0)\n\tdivision(10, 3)\n\n\t// Extra\n\t/*\n\t\tfor i := 10;\t\tInicializo el buclue con i teniendo valor de 10.\n\t\ti <= 55; \t\t\tComparo que i sea menor o igual que 55.\n\t\ti++ \t\t\t\tLe aumento a i en 1 con cada iteración.\n\t\tif i != 16\t\t\tCompruebo que i no sea igual a 16.\n\t\t&& i*3 != 0\t\t\tComprueba que i no sea divisible por 3, con el operador % calculo el resto de i,\n\t\t\t\t\t\t\tdivido por 3, si i es divisible por 3, i%3 será 0.\n\t\tfmt.Println(i)\t\tImprimo todo el proceso en cada iteración.\n\t*/\n\tfor i := 10; i <= 55; i++ {\n\t\tif i != 16 && i*3 != 0 {\n\t\t\tfmt.Println(i)\n\t\t}\n\t}\n\n}\n\nfunc callDefer() {\n\t// Defer: Esta función sirve para atrasar la ejecución de alguna funcion hasta que la funcion desde donde fue llamada retorne.\n\tnf := 5                                             // Declararamos y asignamos valor a la variable nf\n\tdefer fmt.Println(\"Impresión de la variable: \", nf) // Usamos defer para retrasar la impresion de la variable nf\n\tnf = 10                                             // Reasignamos el valor de la variable nf\n\tfmt.Println(\"Reimpresión de la variable: \", nf)     // Reimprimimos la variable nf (Se imprime esta primero)\n\n}\n\n// Panic: Nos permite detener nuestro programa.\n// Recover: nos permite seguir con el programa a pesar del panic(Se recupera del panic)\nfunc division(dividend, divisor int) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tfmt.Println(\"Me recuperé del panic\")\n\t\t}\n\t}()\n\n\tvalidateZero(divisor)\n\tfmt.Println(dividend / divisor)\n}\n\nfunc validateZero(divisor int) {\n\tif divisor == 0 {\n\t\tpanic(\"No se puede dividir por 0\")\n\t}\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/go/allanoscoding.go",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\npackage main\n\nimport \"fmt\"\n\nfunc defer_example() {\n\tdefer fmt.Println(\"Mundo!\")\n\tfmt.Println(\"Hola\")\n\treturn\n}\nfunc is_multiple_of(num int, multiple int) bool {\n\treturn num % multiple == 0\n}\n\nfunc main() {\n\t// Operadores aritmeticos\n\tmy_sum := 3 + 4\n\tmy_diff := 5 - 3\n\tmy_mult := 2 * 2\n\tmy_division := 6 / 3\n\tmy_modulo := 10 % 2\n\n\tfmt.Printf(\"Suma: 3 + 4 = %d \\n\", my_sum)\n\tfmt.Printf(\"Resta: 5 - 3 = %d \\n\", my_diff)\n\tfmt.Printf(\"Multiplicacion: 2 * 2 = %d \\n\", my_mult)\n\tfmt.Printf(\"Division: 6 / 3 = %d \\n\", my_division)\n\tfmt.Printf(\"Resto: 10 %% 2 = %d \\n\", my_modulo)\n\n\t// Operadores relacionales\n\tmy_op_1 := 5 == 3\n\tmy_op_2 := 5 != 3\n\tmy_op_3 := 5 < 3\n\tmy_op_4 := 5 <= 3\n\tmy_op_5 := 5 > 3\n\tmy_op_6 := 5 >= 3\n\n\tfmt.Printf(\"Operador ==: 5 == 3 -> %t \\n\", my_op_1)\n\tfmt.Printf(\"Operador !=: 5 != 3 -> %t \\n\", my_op_2)\n\tfmt.Printf(\"Operador <: 5 < 3 -> %t \\n\", my_op_3)\n\tfmt.Printf(\"Operador <=: 5 <= 3 -> %t \\n\", my_op_4)\n\tfmt.Printf(\"Operador >: 5 > 3 -> %t \\n\", my_op_5)\n\tfmt.Printf(\"Operador >=: 5 >= 3 -> %t \\n\", my_op_6)\n\n\t// Operadores logicos\n\tmy_op_7 := my_op_5 && my_op_1\n\tmy_op_8 := my_op_6 || my_op_3\n\tmy_op_9 := !my_op_2\n\n\tfmt.Printf(\"Resultado: (5 > 3) && (5 == 3) = %t \\n\", my_op_7)\n\tfmt.Printf(\"Resultado: (5 >= 3) && (5 < 3) = %t \\n\", my_op_8)\n\tfmt.Printf(\"Resultado: !(5 != 3) = %t \\n\", my_op_9)\n\n\t// Operadores bit a bit\n\ta := 55\n\tb := 11\n\n\tfmt.Printf(\"Bitwise AND: a & b = %d \\n\", a & b)\n\tfmt.Printf(\"Bitwise OR: a | b = %d \\n\", a | b)\n\tfmt.Printf(\"Bitwise XOR: a ^ b = %d \\n\", a ^ b)\n\tfmt.Printf(\"Desplazamiento a la izq: a << 1 = %d \\n\", a << 1)\n\tfmt.Printf(\"Desplazamiento a la dcha: a >> 1 = %d \\n\", a >> 1)\n\tfmt.Printf(\"Bitwise AND NOT(clear): a &^ b = %d \\n\", a &^ b)\n\n\t// Operadores miscelaneos\n\tc := 22\n\td := &c\n\n\tfmt.Printf(\"La direccion en memoria de c es %v \\n\", &c)\n\tfmt.Printf(\"El valor de c es %v \\n\", *d)\n\n\t// Estructuras de control\n\tif e := a + b; e > c {\n\t\tfmt.Println(\"e > a + b\")\n\t} else {\n\t\tfmt.Println(\"e < a + b\")\n\t}\n\n\tfor i := 0; i < 10; i++ {\n\t\tfmt.Println(i)\n\t}\n\n\tswitch name := \"Angel\"; name {\n\tcase \"Angel\":\n\t\tfmt.Println(\"Es Angel\")\n\tdefault:\n\t\tfmt.Println(\"Es otra persona\")\n\t}\n\n\tdefer_example()\n\n\t// PROBLEMA EXTRA\n\tfmt.Println(\"Problema EXTRA\")\n\tfmt.Println(\"-------------------------------\")\n\tfor i := 10; i <= 55; i++ {\n\t\tif is_multiple_of(i, 2) && !is_multiple_of(i, 3) && i != 16 {\n\t\t\tfmt.Println(i)\n\t\t}\n\t}\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/go/edalmava.go",
    "content": "package main\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n)\n\nfunc prueba() (string, error) {\n\treturn \"\", errors.New(\"Ha ocurrido un error\")\n}\n\nfunc main() {\n\t// Operadore aritméticos\n\tfmt.Println(\"Sean a = 10, b = 3 y c = 20.0\")\n\ta := 10\n\tb := 3\n\tc := 20.0\n\tsuma := a + b\n\tfmt.Println(\"Suma de a + b: \", suma)\n\tresta := a - b\n\tfmt.Println(\"Resta de a - b: \", resta)\n\tmultiplicacion := a * b\n\tfmt.Println(\"Multiplicación de a * b: \", multiplicacion)\n\tdivisionEntera := a / b\n\tfmt.Println(\"División entera de a / b: \", divisionEntera)\n\tdivision := c / 3\n\tfmt.Println(\"División de a / c: \", division)\n\tmodulo := a % 2\n\tfmt.Println(\"Módulo de a % 2: \", modulo)\n\n\t// Operadores lógicos\n\tfmt.Println(\"Sean x = true and y = false\")\n\tx := true\n\ty := false\n\tfmt.Println(\"AND lógico x && y: \", x && y)\n\tfmt.Println(\"OR lógico x || y: \", x || y)\n\tfmt.Printf(\"NOT lógico !x = %t y !y = %t\\n\", !x, !y)\n\n\t// Operadores relacionales\n\tfmt.Println(\"Sean num1 = 5 y num2 = 10\")\n\tnum1 := 5\n\tnum2 := 10\n\tesIgual := num1 == num2\n\tfmt.Println(\"Es igual num1 == num2: \", esIgual)\n\tesDiferente := num1 != num2\n\tfmt.Println(\"Es diferente num1 != num2: \", esDiferente)\n\tesMayor := num1 > num2\n\tfmt.Println(\"Es mayor num1 > num2: \", esMayor)\n\tesMenorIgual := num1 <= num2\n\tfmt.Println(\"Es menor num1 <= num2: \", esMenorIgual)\n\n\t// Alterar el orden de evaluación con el uso de parentesis\n\tresultado1 := num1 + num2*num1 - num2\n\tfmt.Println(\"Resultado usando precedencia de operadores: \", resultado1)\n\tresultado2 := (num1 + num2) * (num1 - num2)\n\tfmt.Println(\"Resultado realizando primero la suma y la resta y luego la multiplicación: \", resultado2)\n\n\t// Estructuras de Control\n\n\t// Estructura if - else if - else\n\tif num1 < num2 && num1 != 0 {\n\t\tfmt.Println(\"num1 es menor que num2 y num1 es diferente de cero\")\n\t}\n\n\tif num1 > num2 {\n\t\tfmt.Println(\"El número uno es mayor que el dos\")\n\t} else if num1 == num2 {\n\t\tfmt.Println(\"Los números son iguales\")\n\t} else {\n\t\tfmt.Println(\"El número dos es mayor que el uno\")\n\t}\n\n\tif _, err := prueba(); err != nil {\n\t\tfmt.Println(err)\n\t}\n\n\t// Estructura Switch\n\topcion := '1'\n\tswitch opcion {\n\tcase '1':\n\t\tfmt.Println(\"Valor seleccionado 1\")\n\tcase '2':\n\t\tfmt.Println(\"Valor seleccionado 2\")\n\tdefault:\n\t\tfmt.Println(\"Valor seleccionado no válido\")\n\t}\n\n\t// Bucle for\n\n\t// for clásico\n\tfor i := 0; i < 10; i++ {\n\t\tfmt.Printf(\"%d\\t\", i)\n\t}\n\tfmt.Printf(\"\\n\")\n\n\t// for como bucle while\n\tj := 0\n\tfor j < 10 {\n\t\tfmt.Printf(\"%d\\t\", j)\n\t\tj++\n\t}\n\tfmt.Printf(\"\\n\")\n\n\t// Bucle infinito\n\tfor {\n\t\t// Tareas a ejecutar\n\t\tbreak\n\t}\n\n\t// for para iterar sobre secuencias\n\tnumeros := []int{10, 20, 30}\n\tfor indice, valor := range numeros {\n\t\tfmt.Printf(\"Índice: %d, Valor: %d\\n\", indice, valor)\n\t}\n\t// El índice puede ser descartado usando el identificador de blanco _\n\tfor _, valor := range numeros {\n\t\tfmt.Println(valor)\n\t}\n\t// Uso de for en strings\n\ttext := \"Hola, mundo\"\n\tfor index, runeValue := range text {\n\t\tfmt.Printf(\"Índice: %d, Runa: %c\\n\", index, runeValue)\n\t}\n\t// Uso de for en mapas\n\tedades := map[string]int{\"Juan\": 30, \"Ana\": 25}\n\tfor clave, valor := range edades {\n\t\tfmt.Printf(\"%s tiene %d años\\n\", clave, valor)\n\t}\n\n\t// RETO EXTRA\n\tfmt.Println(\"RETO EXTRA\")\n\tfor i := 10; i <= 55; i += 2 {\n\t\tif i != 16 && i%3 != 0 {\n\t\t\tfmt.Println(i)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/go/gabrielmoris.go",
    "content": "/*\n * EXERCISE:\n * - Create examples using all types of operators in your language:\n *   Arithmetic, logical, comparison, assignment, identity, membership, bitwise...\n *   (Keep in mind that each language may have different ones)\n * - Using operations with operators of your choice, create examples\n *   that represent all types of control structures that exist\n *   in your language:\n *   Conditionals, iterative, exceptions...\n * - You must print the result of all examples to the console.\n *\n * EXTRA DIFFICULTY (optional):\n * Create a program that prints to the console all numbers between\n * 10 and 55 (inclusive), even, and that are neither 16 nor multiples of 3.\n *\n * Surely by carefully reviewing the possibilities you have discovered something new.\n */\n\npackage main\n\nimport (\n\t\"fmt\"\n\t\"os\"\n)\n\n\nfunc main() {\n\toperators()\n\tstructuresControl()\n\texceptionsHandling()\n\tpanichHandling()\n\tchallenge()\n}\n\nfunc operators(){\n\ta := 10\n\tb := 5\n\t\n\t// Arithmetic Operators:\n\tvar addition = a+b\n\tvar substraction = addition-1;\n\tvar multiplication= substraction *10;\n\tvar division= multiplication/2;\n\tvar module = division %2;\n\tmodule++\n\tmodule--\n\n\t// Logical Operators:\n\tfmt.Println(a > 0 && b > 0)   // Output: true\n\tfmt.Println(a > 0 || b < 0)   // Output: true\n\n\t// Assignment Operators:\n\ta += b\n\tfmt.Println(a)   // Output: 15\n\ta -= b\n\tfmt.Println(a)   // Output: 10\n\ta /= b\n\tfmt.Println(a)   // Output: 2\n\ta*=b\n\tfmt.Println(a)   // Output: 10\n\ta |= b\n\tfmt.Println(a)  // Output: 15\n\ta ^= b\n\tfmt.Println(a)  // Output: 10\n\n\t // Identity operators\n\t c := a\n\t fmt.Println(a == c)   // Output: true\n\t d := &a\n\t e := &a\n\t fmt.Println(d == e) \n\t fmt.Println(&a) // This is the memory address \n\n\t  // Membership operators\n\t  fruits := []string{\"apple\", \"banana\", \"orange\"}\n\t  fmt.Println(\"apple\" == fruits[0])   // Output: true\n\t  fmt.Println(\"grape\" == fruits[0])   // Output: false\n\n\t    // Bitwise operators\n        x := 10\n        y := 5\n        fmt.Println(x & y)   // Output: 2\n        fmt.Println(x | y)   // Output: 15\n        fmt.Println(x ^ y)   // Output: 13\n        fmt.Println(^x)   // Output: -11\n        fmt.Println(x << 2)   // Output: 40\n        fmt.Println(x >> 2)   // Output: 2\n}\n\nfunc structuresControl(){\n\tx:=0;\n\n\t// if-else\n\tif x > 0 {\n\t\tfmt.Println(\"x is positive\")\n\t} else if x == 0 {\n\t\tfmt.Println(\"x is zero\")\n\t} else {\n\t\tfmt.Println(\"x is negative\")\n\t}\n\n\t// switch\n\tday:= \"Monday\"\n\tswitch day {\n\tcase \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\":\n\t\tfmt.Println(\"Weekday\")\n\tcase \"Saturday\", \"Sunday\":\n\t\tfmt.Println(\"Weekend\")\n\tdefault:\n\t\tfmt.Println(\"Invalid day\")\n\t}\n\n\t// for loop\n\tfor i := 0; i < 2; i++ {\n\t\tfmt.Println(i)\n\t}\n\n\t// Range loop\n\tfruits := []string{\"apple\", \"banana\", \"orange\"}\n\tfor index, fruit := range fruits {\n\t\tfmt.Println(index, fruit)\n\t}\n\n\t// While loop\n\ti := 0\n\tfor i < 3 {\n\t\tfmt.Println(i)\n\t\ti++\n\t}\n}\n\nfunc divide(a, b int) int {\n    if b == 0 {\n        panic(\"Division by zero\")\n    }\n    return a / b\n}\n\nfunc exceptionsHandling(){\n\tfile, err := os.Open(\"file.txt\")\n\tif err != nil {\n\t\tfmt.Println(\"Error opening file:\", err)\n\t\treturn\n\t}\n\tdefer file.Close()\n}\n\nfunc panichHandling(){\n\t// this function in defer would recover from the error of ttrying dividing by 0\n\tdefer func() {\n        if err := recover(); err != nil {\n            fmt.Println(\"Recovered  from panic:\", err)\n        }\n    }()\n    result := divide(10, 0)\n    fmt.Println(result)\n}\n\nfunc challenge(){\n\tfmt.Println(\"================ CHALLENGE ================\")\n\t// Create a program that prints to the console all numbers between\n\t// 10 and 55 (inclusive), even, and that are neither 16 nor multiples of 3.\n\n\ti := 10\n\tfor i < 56 {\n\t\tif(i%2 ==0 && i != 16 && i%3 !=0){\n\t\t\tfmt.Println(i)\n\t\t}\n\t\ti++\n\t}\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/go/gugliio.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc main() {\n\t// Defer\n\tdefer fmt.Println(\"\\nfinal\")\n\n\tx := 10\n\ty := 5\n\n\t// Operadores Aritméticos\n\tfmt.Println(\"Operadores Aritméticos\")\n\tfmt.Println(\"Suma\", x+y)\n\tfmt.Println(\"Resta\", x-y)\n\tfmt.Println(\"Multiplicación\", x*y)\n\tfmt.Println(\"División\", x/y)\n\tfmt.Println(\"Módulo\", x%y)\n\tx--\n\tfmt.Println(\"Decremento\", x)\n\tx++\n\tfmt.Println(\"Incremento\", x)\n\n\t// Operadores de Comparacion\n\tfmt.Println(\"\\nOperadores de Comparación\")\n\tfmt.Println(\"Igualdad\", x == y)\n\tfmt.Println(\"Distinto a\", x != y)\n\tfmt.Println(\"Mayor que\", x > y)\n\tfmt.Println(\"Menor que\", x < y)\n\tfmt.Println(\"Mayor o igual que\", x >= y)\n\tfmt.Println(\"Menor o igual que\", x <= y)\n\n\t// Operadores Logicos\n\tfmt.Println(\"\\nOperadores Logicos\")\n\tfmt.Println(\"AND\", x == 10 && y == 5)\n\tfmt.Println(\"OR\", x == 10 || y == 5)\n\tfmt.Println(\"NOT\", !(x == 10))\n\n\t// Operadores de Bits\n\tfmt.Println(\"\\nOperadores de Bits\")\n\tfmt.Println(\"AND\", x&y)\n\tfmt.Println(\"OR\", x|y)\n\tfmt.Println(\"XOR\", x^y)\n\tfmt.Println(\"NOT\", ^x)\n\tfmt.Println(\"Desplazamiento a la izquierda\", x<<1)\n\tfmt.Println(\"Desplazamiento a la derecha\", x>>1)\n\n\t// Operadores de asignacion\n\tfmt.Println(\"\\nOperadores de asignacion\")\n\tz := 10\n\tfmt.Println(\"Valor inicial\", z)\n\tz = 5\n\tfmt.Println(\"Asignacion\", z)\n\tz += 5\n\tfmt.Println(\"Incremento y asignacion\", z)\n\tz -= 5\n\tfmt.Println(\"Decremento y asignacion\", z)\n\tz *= 5\n\tfmt.Println(\"Multiplicación y asignacion\", z)\n\tz /= 5\n\tfmt.Println(\"División y asignacion\", z)\n\tz %= 5\n\tfmt.Println(\"Módulo y asignacion\", z)\n\tz &= 5\n\tfmt.Println(\"AND y asignacion\", z)\n\tz |= 5\n\tfmt.Println(\"OR y asignacion\", z)\n\tz ^= 5\n\tfmt.Println(\"XOR y asignacion\", z)\n\tz <<= 1\n\tfmt.Println(\"Desplazamiento a la izquierda y asignacion\", z)\n\tz >>= 1\n\tfmt.Println(\"Desplazamiento a la derecha y asignacion\", z)\n\n\t// Operadores de punteros\n\tfmt.Println(\"\\nOperadores de punteros\")\n\tj := 1\n\tk := &j\n\tfmt.Println(\"Direccion en memoria\", &k)\n\tfmt.Println(\"Puntero\", *k)\n\n\t//Condicionales\n\tfmt.Println(\"\\nCondicionales\")\n\tif x == 10 {\n\t\tfmt.Println(\"x es igual a 10\")\n\t} else {\n\t\tfmt.Println(\"x no es igual a 10\")\n\t}\n\n\t//Iterativas\n\tfmt.Println(\"\\nIterativas\")\n\tfor i := 0; i < 10; i++ {\n\t\tfmt.Println(i)\n\t}\n\n\tfmt.Println(\"\\nFor Range\")\n\tfor indice, letra := range \"hola mundo\" {\n\t\tfmt.Println(indice, string(letra))\n\t}\n\n\t// Switch\n\tfmt.Println(\"\\nSwitch\")\n\tx = 1\n\tswitch x {\n\tcase 1:\n\t\tfmt.Println(\"x es igual a 1\")\n\tcase 2, 3:\n\t\tfmt.Println(\"x es igual a 2 o 3\")\n\tdefault:\n\t\tfmt.Println(\"x no es ninguno de los valores anteriores\")\n\t}\n\n\tprintNumber()\n}\n\nfunc printNumber() {\n\tfmt.Println(\"\\nImprime los numeros comprendidos entre 10 y 55 (pares, no 16 ni multiplos de 3)\")\n\tfor i := 10; i <= 55; i++ {\n\t\tif i%2 == 0 && i != 16 && i%3 != 0 {\n\t\t\tfmt.Println(i)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/go/hozlucas28.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc main() {\n\t/*\n\t\tType of operators...\n\t*/\n\n\t// Arithmetic\n\tconst addition int = 1 + 1\n\tfmt.Printf(\"Addition: 1 + 1 --> %d\\n\", addition)\n\n\tconst subtraction int = 1 - 1\n\tfmt.Printf(\"Subtraction: 1 - 1 --> %d\\n\", subtraction)\n\n\tconst Multiplication int = 2 * 3\n\tfmt.Printf(\"Multiplication: 2 * 3 --> %d\\n\", Multiplication)\n\n\tconst quotient int = 8 / 2\n\tfmt.Printf(\"Quotient: 8 / 2 --> %d\\n\", quotient)\n\n\tconst remainder int = 13 % 3\n\tfmt.Printf(\"Remainder: 13 %% 3 --> %d\\n\", remainder)\n\n\t// Comparison\n\tconst equal bool = 1 == 1\n\tfmt.Printf(\"\\nEqual: 1 == 1 --> %t\\n\", equal)\n\n\tconst notEqual bool = 1 != 2\n\tfmt.Printf(\"Not equal: 1 != 2 --> %t\\n\", notEqual)\n\n\tconst greaterThan bool = 2 > 2\n\tfmt.Printf(\"Greater than: 2 > 2 --> %t\\n\", greaterThan)\n\n\tconst lessThan bool = -1 < 0\n\tfmt.Printf(\"Less than: -1 < 0 --> %t\\n\", lessThan)\n\n\tconst greaterThanOrEqualTo bool = 2 >= 2\n\tfmt.Printf(\"Greater than or equal to: 2 >= 2 --> %t\\n\", greaterThanOrEqualTo)\n\n\tconst lessThanOrEqualTo bool = -1 <= -0.5\n\tfmt.Printf(\"Less than or equal to: -1 <= -0.5 --> %t\\n\", lessThanOrEqualTo)\n\n\t// Logical\n\tfmt.Printf(\"\\nAnd: true && false --> %t\\n\", true && false)\n\n\tfmt.Printf(\"Or: false || true --> %t\\n\", false || true)\n\n\tfmt.Printf(\"Not: !true --> %t\\n\", !true)\n\n\t// Address\n\tvar number int8 = 16\n\tfmt.Printf(\"\\nAddress / Pointer: < const number int8 > --> %p\\n\", &number)\n\n\t/*\n\t\tControl structures...\n\t*/\n\n\t// < if > and < if else >\n\tif true {\n\t\tfmt.Printf(\"\\nIf: True statement\\n\")\n\t}\n\n\tif false {\n\t\tfmt.Printf(\"If else: False --> True statement\\n\")\n\t} else {\n\t\tfmt.Printf(\"If else: False --> False statement\\n\")\n\t}\n\n\t// < switch >\n\tconst letter string = \"A\"\n\n\tswitch letter {\n\tcase \"D\":\n\t\tfmt.Printf(\"Switch: 'A' --> Case 1 ('D')\\n\")\n\n\tcase \"C\":\n\t\tfmt.Printf(\"Switch: 'A' --> Case 2 ('C')\\n\")\n\n\tcase \"B\":\n\t\tfmt.Printf(\"Switch: 'A' --> Case 3 ('B')\\n\")\n\n\tdefault:\n\t\tfmt.Printf(\"Switch: 'A' --> Default case ('A')\\n\")\n\t}\n\n\t// < for (while version) >\n\tvar i int8 = 5\n\n\tfmt.Println(\"\")\n\tfor i > 0 {\n\t\tif i == 2 {\n\t\t\ti--\n\t\t\tcontinue\n\t\t}\n\n\t\tfmt.Printf(\"For (while version): i > 0 --> %d iteration\\n\", i)\n\t\ti--\n\t}\n\n\t// < for >\n\tfmt.Println(\"\")\n\tfor j := 1; j < 11; j++ {\n\t\tif j == 5 {\n\t\t\tbreak\n\t\t}\n\n\t\tfmt.Printf(\"For: j > 0 --> %d iteration\\n\", j)\n\t}\n\n\t/*\n\t   Additional challenge...\n\t*/\n\n\tfmt.Println(\"\")\n\tfor k := 10; k < 56; k++ {\n\t\tif k != 16 && k%2 == 0 && k%3 != 0 {\n\t\t\tfmt.Printf(\"%d\\n\", k)\n\t\t}\n\n\t}\n\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/go/kodenook.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n)\n\nfunc main() {\n\n\t/*\n\t\tArithmetic Operators\n\t*/\n\n\tfmt.Println(\"\\nArithmetic Operators\\n\")\n\tfmt.Printf(\"Addition: 1 + 1 = %d\\n\", 1 + 1)\n\tfmt.Printf(\"Subtraction: 1 - 1 = %d\\n\", 1 - 1)\n\tfmt.Printf(\"Multiplication: 1 * 1 = %d\\n\", 1 * 1)\n\tfmt.Printf(\"Division: 1 / 1 = %d\\n\", 1 / 1)\n\tfmt.Printf(\"Modulus: 1 % 1 = %d\\n\", 1 % 1)\n\n\t/*\n\t\tBitwise Operators\n\t*/\n\n\tfmt.Println(\"\\nBitwise Operators\\n\")\n\tfmt.Printf(\"&: 5 & 2 = %d\\n\", 5 & 2)\n\tfmt.Printf(\"|: 5 | 2 = %d\\n\", 5 | 2)\n\tfmt.Printf(\"^: 5 ^ 2 = %d\\n\", 5 ^ 2)\n\tfmt.Printf(\">>: 5 >> 2 = %d\\n\", 5 >> 2)\n\tfmt.Printf(\"<<: 5 << 2 = %d\\n\", 5 << 2)\n\n\t/*\n\t\tAssignment Operators\n\t*/\n\n\tfmt.Println(\"\\nAssignment Operators\\n\")\n\tfmt.Println(\"x = 5\")\n\tfmt.Println(\"x += 5, x = x + 5\")\n\tfmt.Println(\"x -= 5, x = x - 5\")\n\tfmt.Println(\"x *= 5, x = x * 5\")\n\tfmt.Println(\"x /= 5, x = x / 5\")\n\tfmt.Println(\"x %= 5, x = x % 5\")\n\tfmt.Println(\"x &= 5, x = x & 5\")\n\tfmt.Println(\"x |= 5, x = x | 5\")\n\tfmt.Println(\"x ^= 5, x = x ^ 5\")\n\tfmt.Println(\"x >>= 5, x = x >> 5\")\n\tfmt.Println(\"x <<= 5, x = x << 5\")\n\n\t/*\n\tComparison Operators\n\t*/\n\n\tfmt.Println(\"\\nComparison Operators\\n\")\n\tfmt.Printf(\"Equal to 4 == 4, %t\\n\", 4 == 4)\n\tfmt.Printf(\"Not Equal to 4 != 4, %t\\n\", 4 != 4)\n\tfmt.Printf(\"Greater Than 4 > 5, %t\\n\", 4 >= 5)\n\tfmt.Printf(\"Less Than 4 < 5, %t\\n\", 4 <= 5)\n\tfmt.Printf(\"Greater Than Or Equal To 4 >= 5, %t\\n\", 4 >= 5)\n\tfmt.Printf(\"Less Than Or Equal To 4 <= 5, %t\\n\", 4 <= 5)\n\n\t/*\n\t\tLogical Operators\n\t*/\n\n\tfmt.Println(\"\\nLogical Operators\\n\")\n\tfmt.Printf(\"&&, 3 < 5 && 3 < 10, %t\\n\", 3 < 5 && 3 < 10)\n\tfmt.Printf(\"||, 3 < 5 || 3 < 10, %t\\n\", 3 < 5 || 3 < 4)\n\tfmt.Printf(\"!, !(4 < 5), %t\\n\", !(4 < 5))\n\n\t/*\n\t\tIf\n\t*/\n\n\tif 6 > 5 {\n\t\tfmt.Println(\"6 Is grater than 5\")\n\t} else if 5 < 6 {\n\t\tfmt.Println(\"5 Is less than 6\")\n\t} else {\n\t\tfmt.Println(\"Good Bye\")\n\t}\n\n\t/*\n\t\tSwitch\n\t*/\n\n\tswitch 5 + 5 {\n\t\tcase 2:\n\t\t\tfmt.Println(\"the case is 2\")\n\t\tcase 5:\n\t\t\tfmt.Println(\"the case is 5\")\n\t\tcase 8, 10:\n\t\t\tfmt.Println(\"the case is 8 or 10\")\n\t\tdefault:\n\t\t\tfmt.Println(\"the case is not here\")\n\t}\n\n\t/*\n\t\tFor Loop\n\t*/\n\n\tfor i := 0; i < 5; i++ {\n\t\tfmt.Println(i)\n\t}\n\n\tfruits := [3]string{\"apple\", \"orange\", \"banana\"}\n\n\tfor idx, value := range fruits {\n\t\tfmt.Printf(\"the index is %d and the value is %s\\n\", idx, value)\n\t}\n\n\t/*\n\t\tExercise\n\t*/\n\n\tfor i := 10; i < 56; i += 2 {\n\t\tif i == 16 || i % 3 == 0 {\n\t\t\tcontinue;\n\t\t}\n\t\tfmt.Println(i)\n\t}\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/go/lestaat.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc main() {\n\n\tfmt.Println(\"Aritmeticos\")\n\tfmt.Printf(\"suma de 1 + 2 es: %d \\n\", 1+2)\n\tfmt.Printf(\"resta de 2 - 1 es: %d \\n\", 2-1)\n\tfmt.Printf(\"multiplicacion de 2 * 2 es: %d \\n\", 2*2)\n\tfmt.Printf(\"division de 2 / 1 es: %d \\n\", 2/2)\n\tfmt.Printf(\"modulo de 7 %% 3 es: %d \\n\", 7%3)\n\n\tfmt.Println(\"Logicos\")\n\tfmt.Println(\" AND (2 >= 1) && (2 <= 3)\", (2 >= 1) && (2 <= 3))\n\tfmt.Println(\" OR (2 <= 1) && (2 <= 3)\", (2 <= 1) || (2 <= 3))\n\tfmt.Println(\" NOT (2 <=1)\", !(2 <= 1))\n\n\tfmt.Println(\"Bit a bit\")\n\tvar x int = 8\n\tvar y int = 4\n\tfmt.Printf(\"and de 8 & 4 es: %d \\n\", x&y)\n\tfmt.Printf(\"or de 8 | 4 es: %d \\n\", x|y)\n\tfmt.Printf(\"xor de 8 ^ 4 es: %d \\n\", x^y)\n\tfmt.Printf(\"izquierda de 8 << 2 es: %d \\n\", x<<2)\n\tfmt.Printf(\"derecha de 8 >> 2 es: %d \\n\", x>>2)\n\n\tfmt.Println(\"Comparacion\")\n\tfmt.Printf(\"igual que 2 == 2 \\n\", 2 == 2)\n\tfmt.Printf(\"mayor que 2 > 1 \\n\", 2 > 1)\n\tfmt.Printf(\"menor que 2 < 4 \\n\", 2 < 4)\n\tfmt.Printf(\"desiguales 2 != 4 \\n\", 2 != 4)\n\n\tfmt.Println(\"Asignacion\")\n\tvar myVar int = 10\n\tfmt.Printf(\"inicializacion de %d \\n\", myVar)\n\tmyVar += 10\n\tfmt.Printf(\"asignacion de %d \\n\", myVar)\n\tmyVar -= 5\n\tfmt.Printf(\"resta y asignacion de %d \\n\", myVar)\n\tmyVar *= 2\n\tfmt.Printf(\"multiplicacion y asignacion de %d \\n\", myVar)\n\tmyVar /= 2\n\tfmt.Printf(\"division y asignacion de %d \\n\", myVar)\n\tmyVar %= 4\n\tfmt.Printf(\"modulo y asignacion de %d \\n\", myVar)\n\n\tfmt.Println(\"Condicionales\")\n\tvar myNewVar int = 5\n\tif myNewVar > 5 {\n\t\tfmt.Println(\"myVar es mayor que 5\")\n\t} else if myNewVar < 5 {\n\t\tfmt.Println(\"myVar es menor que 5\")\n\t} else {\n\t\tfmt.Println(\"myVar es igual a 5\")\n\t}\n\n\tswitch myNewVar {\n\tcase 1:\n\t\tfmt.Println(\"myVar es 1\")\n\tcase 2:\n\t\tfmt.Println(\"myVar es 2\")\n\tcase 3:\n\t\tfmt.Println(\"myVar es 3\")\n\tdefault:\n\t\tfmt.Println(\"myVar es 5\")\n\t}\n\n\tfmt.Println(\"Loops\")\n\ti := 0\n\tfor i < 5 {\n\t\tfmt.Println(i)\n\t\ti++\n\t}\n\n\tfmt.Println(\"Extra\")\n\tfor n := 10; n <= 55; n++ {\n\t\tif n != 16 && n%3 != 0 {\n\t\t\tfmt.Println(n)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/go/miguelex.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc main() {\n\n\t// Operadores aritmeticos\n\n\tfmt.Printf(\"La suma de 3 + 4 es: %d \\n\", 3+4)\n\tfmt.Printf(\"La resta de 5 - 3 es: %d \\n\", 5-3)\n\tfmt.Printf(\"El producto de 6 * 7 es: %d \\n\", 6*7)\n\tfmt.Printf(\"La division de 10 / 2 es: %d \\n\", 10/2)\n\tfmt.Printf(\"El modulo de 10 %% 3 es: %d \\n\", 10%3)\n\n\t// Operadores relacionales\n\n\tfmt.Printf(\"5 == 3 es: %t \\n\", 5 == 3)\n\tfmt.Printf(\"5 != 3 es: %t \\n\", 5 != 3)\n\tfmt.Printf(\"5 < 3 es: %t \\n\", 5 < 3)\n\tfmt.Printf(\"5 <= 3 es: %t \\n\", 5 <= 3)\n\tfmt.Printf(\"5 > 3 es: %t \\n\", 5 > 3)\n\tfmt.Printf(\"5 >= 3 es: %t \\n\", 5 >= 3)\n\n\t// Operadores logicos\n\n\tfmt.Printf(\"(5 > 3) && (5 == 3) es: %t \\n\", (5 > 3) && (5 == 3))\n\tfmt.Printf(\"(5 >= 3) || (5 < 3) es: %t \\n\", (5 >= 3) || (5 < 3))\n\tfmt.Printf(\"!(5 != 3) es: %t \\n\", !(5 != 3))\n\n\t// Operadores bit a bit\n\tvar x int = 8\n\tvar y int = 4\n\n\tfmt.Printf(\"El resultado de 8 & 4 es: %d \\n\", x&y)\n\tfmt.Printf(\"El resultado de 8 | 4 es: %d \\n\", x|y)\n\tfmt.Printf(\"El resultado de 8 ^ 4 es: %d \\n\", x^y)\n\tfmt.Printf(\"El resultado de 8 << 2 es: %d \\n\", x<<2)\n\tfmt.Printf(\"El resultado de 8 >> 2 es: %d \\n\", x>>2)\n\n\t// Ejemplo de if.. else\n\n\tif 5 > 3 {\n\t\tfmt.Println(\"5 es mayor que 3\")\n\t} else {\n\t\tfmt.Println(\"5 no es mayor que 3\")\n\t}\n\n\t// Ejemplo de switch\n\n\tswitch 5 {\n\tcase 1:\n\t\tfmt.Println(\"El numero es 1\")\n\tcase 2:\n\t\tfmt.Println(\"El numero es 2\")\n\tcase 3:\n\t\tfmt.Println(\"El numero es 3\")\n\tcase 4:\n\t\tfmt.Println(\"El numero es 4\")\n\tcase 5:\n\t\tfmt.Println(\"El numero es 5\")\n\tdefault:\n\t\tfmt.Println(\"El numero es mayor que 5\")\n\t}\n\n\t// Ejemplo de for\n\n\tfor i := 0; i < 5; i++ {\n\t\tfmt.Println(i)\n\t}\n\n\t// Ejemplo de for con range\n\n\tmy_array := []int{1, 2, 3, 4, 5}\n\n\tfor index, value := range my_array {\n\t\tfmt.Printf(\"El valor en la posicion %d es %d \\n\", index, value)\n\t}\n\n\t// while\n\n\tj := 0\n\tfor j < 5 {\n\t\tfmt.Println(j)\n\t\tj++\n\t}\n\n\t// do while\n\n\tk := 0\n\tfor {\n\t\tfmt.Println(k)\n\t\tk++\n\t\tif k == 5 {\n\t\t\tbreak\n\t\t}\n\t}\n\n\t// Extra\n\n\tfor i := 10; i <= 55; i++ {\n\t\tif i%2 == 0 && i != 16 && i%3 != 0 {\n\t\t\tfmt.Println(i)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/go/n0hagonada.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc main() {\n\t// Operadores Aritméticos\n\ta := 5 + 3  // Suma\n\tb := 10 - 4 // Resta\n\tc := 7 * 3  // Multiplicación\n\td := 20 / 4 // División\n\te := 9 % 4  // Módulo\n\tfmt.Println(a, b, c, d, e)\n\t// Operadores Lógicos\n\tx := true\n\ty := false\n\tfmt.Println(x && y) // AND lógico\n\tfmt.Println(x || y) // OR lógico\n\tfmt.Println(!x)     // NOT lógico\n\t// Operadores de Comparación\n\tfmt.Println(a == b) // Igual a\n\tfmt.Println(a != b) // Diferente de\n\tfmt.Println(a > b)  // Mayor que\n\tfmt.Println(a < b)  // Menor que\n\t// Operadores de Asignación\n\ta += 2 // Equivalente a a = a + 2\n\tb -= 3 // Equivalente a b = b - 3\n\t// Operadores de bits\n\tf := 3 << 2  // Desplazamiento a la izquierda\n\tg := 16 >> 2 // Desplazamiento a la derecha\n\th := 5 & 2   // AND de bits\n\ti := 5 | 2   // OR de bits\n\tj := 5 ^ 2   // XOR de bits\n\tk := ^5      // NOT de bits\n\tfmt.Println(f, g, h, i, j, k)\n\t// Condicionales\n\tif a > 5 {\n\t\tfmt.Println(\"a es mayor que 5\")\n\t} else if a == 5 {\n\t\tfmt.Println(\"a es igual a 5\")\n\t} else {\n\t\tfmt.Println(\"a es menor que 5\")\n\t}\n\t// iterativas\n\tfor i := 70; i < 75; i++ {\n\t\tfmt.Println(i)\n\t}\n\tfmt.Println(\"*************************** Extra ******************************************\")\n\textra()\n}\nfunc extra() {\n\tfor i := 10; i <= 55; i++ {\n\t\tif i != 16 && i%2 == 0 && 1%3 != 0 {\n\t\t\tfmt.Println(i)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/go/qwik-zgheib.go",
    "content": "package main\n\nimport \"fmt\"\n\n// types of operators\nfunc typesOperators() {\n\t// aritmetics\n\tvar a int = 10\n\tvar b int = 20\n\tvar c int\n\tc = a + b\n\ta += b\n\tfmt.Println(\"sum: \", c)\n\n\t// logical\n\tvar x bool = true\n\tvar y bool = false\n\tif x && y {\n\t\tprintln(\"logical: True\")\n\t}\n\n\t// comparison\n\tif a == b {\n\t\tfmt.Println(\"comparison: True\")\n\t}\n\n\t// assignment\n\ta = b\n\tfmt.Println(\"assignment: \", a)\n\n\t/* identity */\n\tvar m int = 10\n\tvar n int = 10\n\tif m == n {\n\t\tfmt.Println(\"identity: True\")\n\t}\n\n\t// pertenence\n\tvar numbers = [3]int{1, 2, 3}\n\tvar number = 2\n\tfor _, n := range numbers {\n\t\tif n == number {\n\t\t\tfmt.Println(\"pertenece: True\")\n\t\t}\n\t}\n\n\t// bits\n\tvar d int = 60\n\tvar e int = 13\n\tc = d & e\n\tfmt.Println(\"bits: \", c)\n}\n\n// control structures\nfunc controlStructures() error {\n\t// conditional\n\tvar a int = 10\n\tif a > 5 {\n\t\tfmt.Println(\"conditional: True\")\n\t}\n\n\t// iterative\n\tfor i := 0; i < 5; i++ {\n\t\tfmt.Println(\"iterative: \", i)\n\t}\n\n\t// exception\n\tvar b int = 0\n\tif b == 0 {\n\t\treturn fmt.Errorf(\"exception: Error division by zero\")\n\t}\n\n\treturn nil\n}\n\nfunc exercise() {\n\tfor i := 10; i <= 55; i++ {\n\t\tif i != 16 && i%3 != 0 {\n\t\t\tfmt.Println(\"exercise: \", i)\n\t\t}\n\t}\n}\n\nfunc main() {\n\ttypesOperators()\n\n\t// exeption error\n\terr := controlStructures()\n\tif err != nil {\n\t\tfmt.Println(err)\n\t}\n\n\texercise()\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/go/raynerpv2022.go",
    "content": "package main\n\nimport \"fmt\"\n\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\nfunc main() {\n\n\t//  aritmeticos\n\tfmt.Println(\"*** Operadores Aritmeticas ***\")\n\tfmt.Printf(\"suma %d + %d = %d \\n\", 4, 9, 4+9)\n\tfmt.Printf(\"resta %d - %d = %d \\n\", 4, 9, 4-9)\n\tfmt.Printf(\"multiplicacion %d * %d = %d \\n\", 4, 9, 4*9)\n\tfmt.Printf(\"division %d / %d = %d \\n\", 9, 4, 9/4)\n\tfmt.Printf(\"division %d / %d = %.3f \\n\", 9, 4, 9/4.) // div siempre es entera\n\tfmt.Printf(\"MOdulo %d %% %d = %d \\n\", 9, 4, 9%4)\n\n\t//  comparacion\n\tfmt.Println(\"*** Operadores comparacion ***\")\n\tfmt.Printf(\"igual que %d == %d , %t \\n\", 4, 9, 4 == 9)\n\tfmt.Printf(\"mayor que %d > %d , %t \\n\", 4, 9, 4 > 9)\n\tfmt.Printf(\"menor que %d < %d , %t \\n\", 4, 9, 4 < 9)\n\tfmt.Printf(\"desiguales  %d != %d , %t \\n\", 4, 9, 4 != 9)\n\n\t//  logicos\n\tfmt.Println(\"*** Operadores logicos ***\")\n\tfmt.Println(\" AND (4 >= 2) && (9 <= 19)\", (4 >= 2) && (9 <= 19))\n\tfmt.Println(\" OR (4 <= 2) && (9 <= 19)\", (4 <= 2) || (9 <= 19))\n\tfmt.Println(\" NOT (4 <=2)\", !(4 <= 2))\n\n\t// asignacion\n\tfmt.Println(\"*** Operadores asignacion ***\")\n\ta := 1\n\tfmt.Println(\" inicializacion  a:= 1\", a)\n\ta = 2\n\tfmt.Println(\" asignacion cambio valor a = 1\", a)\n\ta += 3\n\tfmt.Println(\" suma  y asignacion a += 3\", a)\n\tfmt.Println(\" resta  y asignacion a -= 1\", a)\n\tfmt.Println(\" multip y asignacion a *= 1\", a)\n\tfmt.Println(\" division  y asignacion a /= 1\", a)\n\ta++\n\tfmt.Println(\" incremento a++\", a)\n\ta--\n\tfmt.Println(\" decremento a--\", a)\n\n\t// operadores con bit\n\tfmt.Println(\"*** Operadores con bits ***\")\n\tvar s, d uint8 = 10, 3\n\tfmt.Println(\" and s & d \", s&d)\n\tfmt.Println(\" or s | d \", s|d)\n\tfmt.Println(\" xor s ^ d \", s^d)\n\tfmt.Println(\" izquierda  s << 2 \", s<<2)\n\tfmt.Println(\" derecha  s >> 2 \", s>>2)\n\n\t// condicionales\n\tfmt.Println(\"*** Extructuras de control condicionales ***\")\n\n\tif s > d {\n\t\tfmt.Printf(\" %d es mayor que %d \\n\", s, d)\n\t} else if s < d {\n\t\tfmt.Printf(\"%d es menor que %d \\n\", s, d)\n\t} else {\n\t\tfmt.Printf(\"%d y %d son iguales \\n\", s, d)\n\t}\n\n\tswitch s {\n\tcase 10:\n\t\tfmt.Println(\"s es igual a 10\")\n\tcase 5:\n\t\tfmt.Println(\"n es igual a 5\")\n\tdefault:\n\t\tfmt.Println(\"n no es igual a 10 ni a 5\")\n\t}\n\n\tfmt.Println(\"*** EXTRA ***\")\n\n\tfor i := 10; i < 56; i++ {\n\t\tif i%2 == 0 && i != 16 && i%3 != 0 {\n\t\t\tfmt.Println((i))\n\t\t}\n\n\t}\n\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/go/thegera4.go",
    "content": "package main\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n)\n\nfunc main() {\n\t//operadores aritmeticos\n\tvar a, b int = 10, 5\n\tvar c int = a + b\n\tfmt.Println(\"suma: \", c)\n\tc = a - b\n\tfmt.Println(\"resta: \", c)\n\tc = a * b\n\tfmt.Println(\"multiplicacion: \", c)\n\tc = a / b\n\tfmt.Println(\"division: \", c)\n\tc = a % b\n\tfmt.Println(\"modulo: \", c)\n\ta++\n\tfmt.Println(\"incremento: \", a)\n\tb--\n\tfmt.Println(\"decremento: \", b)\n\n\t//operadores de asignacion\n\tvar d int = 10\n\td += 5\n\tfmt.Println(\"suma: \", d)\n\td -= 5\n\tfmt.Println(\"resta: \", d)\n\td *= 5\n\tfmt.Println(\"multiplicacion: \", d)\n\td /= 5\n\tfmt.Println(\"division: \", d)\n\td %= 5\n\tfmt.Println(\"modulo: \", d)\n\n\t//operadores de comparacion\n\tvar e, f int = 10, 5\n\tfmt.Println(\"e == f: \", e == f)\n\tfmt.Println(\"e != f: \", e != f)\n\tfmt.Println(\"e > f: \", e > f)\n\tfmt.Println(\"e < f: \", e < f)\n\tfmt.Println(\"e >= f: \", e >= f)\n\tfmt.Println(\"e <= f: \", e <= f)\n\n\t//operadores logicos\n\tvar g, h bool = true, false\n\tfmt.Println(\"g && h: \", g && h)\n\tfmt.Println(\"g || h: \", g || h)\n\tfmt.Println(\"!g: \", !g)\n\tfmt.Println(\"!h: \", !h)\n\n\t//operadores de bits\n\tvar i, j uint8 = 10, 5\n\tfmt.Println(\"i & j: \", i&j)\n\tfmt.Println(\"i | j: \", i|j)\n\tfmt.Println(\"i ^ j: \", i^j)\n\tfmt.Println(\"i << 1: \", i<<1)\n\tfmt.Println(\"i >> 1: \", i>>1)\n\n\t//operadores de punteros\n\tvar k int = 10\n\tvar l *int\n\tl = &k\n\tfmt.Println(\"k: \", k)\n\tfmt.Println(\"l: \", l)\n\tfmt.Println(\"*l: \", *l)\n\n\t//operadores de canales\n\tvar m chan int = make(chan int, 1)\n\tm <- 10\n\tfmt.Println(\"m: \", m)\n\tfmt.Println(\"<-m: \", <-m)\n\n\t//condicionales\n\tif(10 > 5) {\n\t\tfmt.Println(\"10 es mayor que 5\")\n\t} else if (10 < 5) {\n\t\tfmt.Println(\"10 es menor que 5\")\n\t} else {\n\t\tfmt.Println(\"10 es igual a 5\")\n\t}\n\n\tvar n int = 10\n\tswitch n {\n\t\tcase 10:\n\t\t\tfmt.Println(\"n es igual a 10\")\n\t\tcase 5:\n\t\t\tfmt.Println(\"n es igual a 5\")\n\t\tdefault:\n\t\t\tfmt.Println(\"n no es igual a 10 ni a 5\")\n\t}\n\n\t//ciclos\n\tfor i := 0; i < 10; i++ {\n\t\tfmt.Println(\"i: \", i)\n\t}\n\n\tvar o int = 0\n\tfor o < 10 {\n\t\tfmt.Println(\"o: \", o)\n\t\to++\n\t}\n\n\tvar p int = 0\n\tfor {\n\t\tif p == 10 {\n\t\t\tbreak\n\t\t}\n\t\tfmt.Println(\"p: \", p)\n\t\tp++\n\t}\n\n\tvar q int = 0\n\tfor q < 10 {\n\t\tif q == 5 {\n\t\t\tq++\n\t\t\tcontinue\n\t\t}\n\t\tfmt.Println(\"q: \", q)\n\t\tq++\n\t}\n\n\tvar r int = 0\n\tfor r < 10 {\n\t\tif r == 5 {\n\t\t\terrors.New(\"r es igual a 5\")\n\t\t}\n\t\tfmt.Println(\"r: \", r)\n\t\tr++\n\t}\n\n\tdificultadExtra()\n}\n\nfunc dificultadExtra() {\n\tfor i := 10; i <= 55; i++ {\n\t\tif i % 3 == 0 {\n\t\t\tcontinue\n\t\t} else if i == 16 {\n\t\t\tcontinue\n\t\t} else {\n\t\t\tfmt.Println(i)\n\t\t}\n\t}\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/go/zerpajose.go",
    "content": "package main\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"math\"\n)\n\nfunc Accounting(f int, b int) (n int, err error) {\n\tif f < 0 {\n\t\treturn 0, errors.New(\"Error\")\n\t} else {\n\t\treturn b, nil\n\t}\n}\n\nfunc main() {\n\t// EJERCICIO\n\ta := 1\n\tb := 2\n\t// ARIMETICOS\n\tfmt.Println(\"SUMA\", a+b)\n\tfmt.Println(\"RESTA\", a-b)\n\tfmt.Println(\"MULTIPLICACION\", a*b)\n\tfmt.Println(\"DIVISION\", a/b)\n\tfmt.Println(\"RESTO\", a%b)\n\n\t// BITWISE\n\tfmt.Println(\"AND\", 3&5)\n\tfmt.Println(\"OR\", 3|5)\n\tfmt.Println(\"XOR\", 3^5)\n\tfmt.Println(\"NOT\", ^5)\n\tfmt.Println(\"AND NOT\", 3&^5)\n\tfmt.Println(\"LEFT SHIFT\", 53<<2)\n\tfmt.Println(\"LEFT SHIFT\", 53>>2)\n\n\t// COMPARACION\n\tfmt.Println(\"IGUAL\", 0 == 0)\n\tfmt.Println(\"DIFERENTE\", 1 == 0)\n\tfmt.Println(\"MENOR QUE\", 2 < 5)\n\tfmt.Println(\"MENOR O IGUAL\", 2 <= 2)\n\tfmt.Println(\"MAYOR QUE\", 5 > 2)\n\tfmt.Println(\"MAYOR O IGUAL\", 5 >= 5)\n\n\t// LOGICOS\n\tfmt.Println(\"AND\", true && true)\n\tfmt.Println(\"OR\", true || false)\n\tfmt.Println(\"NOT\", !false)\n\n\t// CONCATENACION DE STRINGS\n\ts := \"hi \" + \"world\"\n\ts += \" and good bye\"\n\tfmt.Println(s)\n\n\t// DECISION\n\tif s == \"HI\" {\n\t\tfmt.Println(\"HOLA\")\n\t} else if s == \"BYE\" {\n\t\tfmt.Println(\"BYE\")\n\t} else {\n\t\tfmt.Println(\"DEFAULT\")\n\t}\n\n\t// SWITCH\n\tswitch {\n\tcase s == \"hi world and good bye\":\n\t\tfmt.Println(\"HOLA\")\n\tcase s == \"HI\":\n\t\tfmt.Println(\"HI\")\n\tcase s == \"BYE\":\n\t\tfmt.Println(\"BYE\")\n\tdefault:\n\t\tfmt.Println(\"DEFAULT\")\n\t}\n\n\t// FOR\n\tprints := [5]int{1, 2, 3, 4, 5}\n\tfor i := 5; i >= 0; i-- {\n\t\tfmt.Println(i)\n\t}\n\n\t// FOR RANGE\n\tfor _, p := range prints {\n\t\tfmt.Println(p)\n\t}\n\n\t// DIRECCION\n\tfmt.Println(\"POINTER ADDRESS\", &s)\n\tvar x *string = &s\n\tfmt.Println(\"POINTER VALUE\", *x)\n\n\t// ERROR\n\tnum1, err1 := Accounting(-1, 0)\n\tfmt.Println(err1, num1)\n\tnum2, err2 := Accounting(1, 5)\n\tfmt.Println(err2, num2)\n\n\t// DIFICULTAD EXTRA\n\tfmt.Println(\"DIFICULTAD EXTRA\")\n\tvar count = 56\n\n\tfor i := 10; i < count; i++ {\n\t\tvar j float64 = float64(i)\n\t\tif (i%2 != 0) || (i == 16) || (math.Mod(j/3, 1) == 0) {\n\t\t\tcontinue\n\t\t}\n\t\tfmt.Print(i, \" \")\n\t}\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/haskell/SalazarProgrammer.hs",
    "content": "{-\n  EJERCICIO:\n  - Operadores: Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n  - Estructuras de control: Condicionales, iterativas, excepciones...\n  - Debes hacer print por consola del resultado de todos los ejemplos.\n-}\n\nmodule Main where\n\n-- Operadores Aritméticos\noperadoresAritmeticos :: IO ()\noperadoresAritmeticos = do\n    putStrLn \"\\n--- OPERADORES ARITMÉTICOS ---\"\n    putStrLn $ \"5 + 3 = \" ++ show (5 + 3)      -- Suma: 8\n    putStrLn $ \"5 - 3 = \" ++ show (5 - 3)      -- Resta: 2\n    putStrLn $ \"5 * 3 = \" ++ show (5 * 3)      -- Multiplicación: 15\n    putStrLn $ \"10 / 3 = \" ++ show (10 / 3)    -- División: 3.333...\n    putStrLn $ \"10 `div` 3 = \" ++ show (10 `div` 3)  -- División entera: 3\n    putStrLn $ \"10 `mod` 3 = \" ++ show (10 `mod` 3)  -- Módulo: 1\n    putStrLn $ \"2 ^ 3 = \" ++ show (2 ^ 3)      -- Potencia: 8\n\n-- Operadores de Comparación\noperadoresComparacion :: IO ()\noperadoresComparacion = do\n    putStrLn \"\\n--- OPERADORES DE COMPARACIÓN ---\"\n    putStrLn $ \"5 == 3 = \" ++ show (5 == 3)    -- Igualdad: False\n    putStrLn $ \"5 /= 3 = \" ++ show (5 /= 3)    -- Desigualdad: True\n    putStrLn $ \"5 > 3 = \" ++ show (5 > 3)      -- Mayor que: True\n    putStrLn $ \"5 < 3 = \" ++ show (5 < 3)      -- Menor que: False\n    putStrLn $ \"5 >= 5 = \" ++ show (5 >= 5)    -- Mayor o igual: True\n    putStrLn $ \"5 <= 3 = \" ++ show (5 <= 3)    -- Menor o igual: False\n\n-- Operadores Lógicos\noperadoresLogicos :: IO ()\noperadoresLogicos = do\n    putStrLn \"\\n--- OPERADORES LÓGICOS ---\"\n    putStrLn $ \"True && False = \" ++ show (True && False)  -- AND: False\n    putStrLn $ \"True || False = \" ++ show (True || False)  -- OR: True\n    putStrLn $ \"not True = \" ++ show (not True)            -- NOT: False\n\n-- Operadores a Nivel de Bits\noperadoresBits :: IO ()\noperadoresBits = do\n    putStrLn \"\\n--- OPERADORES A NIVEL DE BITS ---\"\n    putStrLn $ \"5 .&. 3 = \" ++ show (5 .&. 3)  -- AND bit a bit: 1\n    putStrLn $ \"5 .|. 3 = \" ++ show (5 .|. 3)  -- OR bit a bit: 7\n    putStrLn $ \"5 `xor` 3 = \" ++ show (5 `xor` 3)  -- XOR: 6\n    putStrLn $ \"complement (5 :: Int) = \" ++ show (complement (5 :: Int))  -- Complemento: -6\n\n-- En Haskell no hay operadores de asignación como en lenguajes imperativos\n-- Las variables son inmutables por defecto\n\n-- Estructuras de Control Condicionales\nestructurasCondicionales :: IO ()\nestructurasCondicionales = do\n    putStrLn \"\\n--- ESTRUCTURAS CONDICIONALES ---\"\n\n    -- If-Then-Else\n    let resultado1 = if 5 > 3 then \"Mayor\" else \"Menor\"\n    putStrLn $ \"If-Then-Else: \" ++ resultado1\n\n    -- Guardas (Guards)\n    let clasificar x\n            | x > 10   = \"Grande\"\n            | x > 5    = \"Mediano\"\n            | otherwise = \"Pequeño\"\n    putStrLn $ \"Guardas (7): \" ++ clasificar 7\n\n    -- Pattern Matching\n    let factorial 0 = 1\n        factorial n = n * factorial (n - 1)\n    putStrLn $ \"Pattern Matching (factorial 5): \" ++ show (factorial 5)\n\n-- Estructuras Iterativas (Haskell usa recursión en lugar de bucles)\nestructurasIterativas :: IO ()\nestructurasIterativas = do\n    putStrLn \"\\n--- ESTRUCTURAS ITERATIVAS ---\"\n\n    -- Recursión\n    let sumaLista [] = 0\n        sumaLista (x:xs) = x + sumaLista xs\n    putStrLn $ \"Recursión (suma [1,2,3,4]): \" ++ show (sumaLista [1,2,3,4])\n\n    -- Map (transformación)\n    let duplicar = map (*2)\n    putStrLn $ \"Map (duplicar [1,2,3]): \" ++ show (duplicar [1,2,3])\n\n    -- Filter (filtrado)\n    let pares = filter even\n    putStrLn $ \"Filter (pares [1,2,3,4,5]): \" ++ show (pares [1,2,3,4,5])\n\n    -- Fold (acumulación)\n    let producto = foldl (*) 1\n    putStrLn $ \"Fold (producto [1,2,3,4]): \" ++ show (producto [1,2,3,4])\n\n-- Manejo de Excepciones\nestructurasExcepciones :: IO ()\nestructurasExcepciones = do\n    putStrLn \"\\n--- MANEJO DE EXCEPCIONES ---\"\n\n    -- Usando Maybe\n    let divisionSegura _ 0 = Nothing\n        divisionSegura a b = Just (a / b)\n\n    case divisionSegura 10 2 of\n        Just resultado -> putStrLn $ \"División segura (10/2): \" ++ show resultado\n        Nothing -> putStrLn \"Error: división por cero\"\n\n    case divisionSegura 10 0 of\n        Just resultado -> putStrLn $ \"División segura: \" ++ show resultado\n        Nothing -> putStrLn \"Error: división por cero (manejado con Maybe)\"\n\n{-\n  DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n-}\n\n-- DIFICULTAD EXTRA\ndificultadExtra :: IO ()\ndificultadExtra = do\n    putStrLn \"\\n--- DIFICULTAD EXTRA ---\"\n    putStrLn \"Números entre 10 y 55 (pares, no 16, no múltiplos de 3):\"\n\n    let numeros = [x | x <- [10..55], even x, x /= 16, x `mod` 3 /= 0]\n    mapM_ (putStrLn . show) numeros\n    putStrLn $ \"Total: \" ++ show (length numeros) ++ \" números\"\n\n-- Función principal\nmain :: IO ()\nmain = do\n    operadoresAritmeticos\n    operadoresComparacion\n    operadoresLogicos\n    operadoresBits\n    estructurasCondicionales\n    estructurasIterativas\n    estructurasExcepciones\n    dificultadExtra\n\n-- FIN\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/AFOXJONES.java",
    "content": "\npublic class AFOXJONES{\n\n     public static void main(String[] args) {\n        // 1. Operadores\n        System.out.println(\"=== Operadores ===\");\n        operadoresAritmeticos();\n        operadoresLogicos();\n        operadoresComparacion();\n        operadoresAsignacion();\n        operadoresBits();\n\n        // 2. Estructuras de Control\n        System.out.println(\"\\n=== Estructuras de Control ===\");\n        condicionales();\n        iterativas();\n        manejoExcepciones();\n\n\n        // 3. Dificultad Extra\n        System.out.println(\"\\n=== Dificultad Extra ===\");\n        extra();\n    }\n\n    // Métodos para operadores\n    private static void operadoresAritmeticos() {\n        System.out.println(\"-> Operadores Aritméticos\");\n        int suma = 5 + 3;\n        int resta = 10 - 4;\n        int multiplicacion = 7 * 2;\n        double division = 10.0 / 3.0;\n        int modulo = 10 % 3;\n        System.out.printf(\"Suma: %d, Resta: %d, Multiplicación: %d, División: %.2f, Módulo: %d%n\", \n                          suma, resta, multiplicacion, division, modulo);\n    }\n\n    private static void operadoresLogicos() {\n        System.out.println(\"-> Operadores Lógicos\");\n        boolean a = true, b = false;\n        System.out.println(\"AND: \" + (a && b));\n        System.out.println(\"OR: \" + (a || b));\n        System.out.println(\"NOT: \" + (!a));\n    }\n\n    private static void operadoresComparacion() {\n        System.out.println(\"-> Operadores de Comparación\");\n        int x = 5, y = 10;\n        System.out.println(\"Igualdad: \" + (x == y));\n        System.out.println(\"Mayor que: \" + (x > y));\n        System.out.println(\"Menor que: \" + (x < y));\n        System.out.println(\"Mayor o igual: \" + (x >= 5));\n        System.out.println(\"Menor o igual: \" + (y <= 10));\n    }\n\n    private static void operadoresAsignacion() {\n        System.out.println(\"-> Operadores de Asignación\");\n        int z = 10;\n        z += 5;\n        System.out.println(\"z += 5: \" + z);\n        z -= 3;\n        System.out.println(\"z -= 3: \" + z);\n        z *= 2;\n        System.out.println(\"z *= 2: \" + z);\n        z /= 4;\n        System.out.println(\"z /= 4: \" + z);\n    }\n\n    private static void operadoresBits() {\n        System.out.println(\"-> Operadores de Bits\");\n        int bitA = 5; // 0101 en binario\n        int bitB = 3; // 0011 en binario\n        System.out.println(\"AND: \" + (bitA & bitB)); // 0001\n        System.out.println(\"OR: \" + (bitA | bitB));  // 0111\n        System.out.println(\"XOR: \" + (bitA ^ bitB)); // 0110\n        System.out.println(\"Desplazamiento Izquierda: \" + (bitA << 1)); // 1010\n        System.out.println(\"Desplazamiento Derecha: \" + (bitA >> 1)); // 0010\n    }\n\n    // Métodos para estructuras de control\n    private static void condicionales() {\n        System.out.println(\"-> Condicionales\");\n        int valor = 7;\n        if (valor > 5) {\n            System.out.println(\"El valor es mayor que 5\");\n        } else {\n            System.out.println(\"El valor no es mayor que 5\");\n        }\n\n        // Switch\n        switch (valor) {\n            case 5:\n                System.out.println(\"El valor es 5\");\n                break;\n            case 7:\n                System.out.println(\"El valor es 7\");\n                break;\n            default:\n                System.out.println(\"El valor no es ni 5 ni 7\");\n        }\n    }\n\n    private static void iterativas() {\n        System.out.println(\"-> Iterativas\");\n\n        // For Loop\n        System.out.println(\"Bucle For:\");\n        for (int i = 1; i <= 5; i++) {\n            System.out.println(\"i = \" + i);\n        }\n\n        // While Loop\n        System.out.println(\"Bucle While:\");\n        int j = 1;\n        while (j <= 3) {\n            System.out.println(\"j = \" + j);\n            j++;\n        }\n\n        // Do-While Loop\n        System.out.println(\"Bucle Do-While:\");\n        int k = 5;\n        do {\n            System.out.println(\"k = \" + k);\n            k--;\n        } while (k > 0);\n    }\n\n    private static void manejoExcepciones() {\n        System.out.println(\"-> Manejo de Excepciones\");\n        try {\n            int resultado = 10 / 0;\n            System.out.println(\"Resultado: \" + resultado);\n        } catch (ArithmeticException e) {\n            System.out.println(\"Error: División por cero\");\n        } finally {\n            System.out.println(\"Bloque finally ejecutado\");\n        }\n    }\n\n    // punto extra\n    private static void extra(){\n\n        for(int i=10; i<=55; i++){\n            if(i%2==0 && i%3!=0 && i!=16)\n                System.out.println(i);\n        };\n    }\n\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/ARHL2023.java",
    "content": "package Number001Java;\n\npublic class ARHL2023 {\n    public static void main(String[] args) {\n\n        //Operadores Aritméticos:\n        int a = 10;\n        int b = 5;\n        System.out.println(\"\\nOperadores Aritméticos: \");\n        System.out.println(\"Suma: \" + (a + b));\n        System.out.println(\"Resta: \" + (a - b));\n        System.out.println(\"Multiplicación: \" + (a * b));\n        System.out.println(\"División: \" + (a / b));\n        System.out.println(\"Módulo: \" + (a % b));\n        System.out.println(\"Incremento: \" + (++a));\n        System.out.println(\"Decremento: \" + (--b));\n\n        //Operadores Lógicos:\n        boolean x = true;\n        boolean y = false;\n        System.out.println(\"\\nOperadores Lógicos:\");\n        System.out.println(\"AND lógico: \" + (x && y));\n        System.out.println(\"OR lógico: \" + (x || y));\n        System.out.println(\"NOT lógico: \" + (!x));\n\n        //Operadores de Asignación:\n        int c = 5;\n        c += 3;\n        System.out.println(\"\\nOperadores de Asignación:\");\n        System.out.println(\"Asignación con suma: \" + c);\n        c -= 2;\n        System.out.println(\"Asignación con resta: \" + c);\n        c *= 4;\n        System.out.println(\"Asignación con multiplicación: \" + c);\n        c /= 2;\n        System.out.println(\"Asignación con división: \" + c);\n        c %= 3;\n        System.out.println(\"Asignación con módulo: \" + c);\n\n        //Operadores de Identidad:\n        System.out.println(\"\\nOperadores de Identidad:\");\n        String str = \"Hola\";\n        Integer num = 0;\n        System.out.println(\"¿Es una instancia de String? \" + (str instanceof String));\n        System.out.println(\"¿Es una instancia de int? \" + (num instanceof Integer));\n\n        //Operadores de Pertenencia:\n        System.out.println(\"\\nOperadores de Pertenencia:\");\n        int[] arr = {1, 2, 3, 4, 5};\n        int val = 3;\n        boolean pertenece = false;\n        for (int i : arr) {\n            if (i == val) {\n                pertenece = true;\n                break;\n            }\n        }\n        System.out.println(\"¿El valor \" + val + \" está en el array? \" + pertenece);\n\n        //Operadores de Bits:\n        System.out.println(\"\\nOperadores de Bits:\");\n        int d = 5; // Representación binaria: 101\n        int e = 3; // Representación binaria: 011\n        System.out.println(\"AND a nivel de bits: \" + (d & e));\n        System.out.println(\"OR a nivel de bits: \" + (d | e));\n        System.out.println(\"XOR a nivel de bits: \" + (d ^ e));\n        System.out.println(\"Desplazamiento a la izquierda: \" + (d << 1));\n        System.out.println(\"Desplazamiento a la derecha: \" + (e >> 1));\n        System.out.println(\"Desplazamiento sin signo a la derecha: \" + (e >>> 1));\n\n        System.out.println(\"\\n\\tEjemplos de estructuras de control:\");\n\n        //Condicionales (if-else):\n        System.out.println(\"\\nCondicionales (if-else):\");\n        int numCondicional = 10;\n        if (numCondicional > 0) {\n            System.out.println(\"El número es positivo\");\n        } else if (numCondicional < 0) {\n            System.out.println(\"El número es negativo\");\n        } else {\n            System.out.println(\"El número es cero\");\n        }\n\n\n        //Estructuras iterativas (for, while, do-while):\n        System.out.println(\"\\nEstructuras iterativas (for, while, do-while):\");\n\n        // Ciclo for\n        for (int i = 1; i <= 5; i++) {\n            System.out.println(\"Iteración #\" + i);\n        }\n\n// Ciclo while\n        int j = 0;\n        while (j < 5) {\n            System.out.println(\"Iteración en while #\" + j);\n            j++;\n        }\n\n// Ciclo do-while\n        int k = 0;\n        do {\n            System.out.println(\"Iteración en do-while #\" + k);\n            k++;\n        } while (k < 5);\n\n        //RETO\n//DIFICULTAD EXTRA (opcional):\n//Crea un programa que imprima por consola todos los números comprendidos\n//entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\n\n        System.out.println(\"\\nReto: \");\n\n        int inicio = 10;\n        int fin = 55;\n\n        for (int i = inicio; i <= fin; i++){\n            if( (i>=inicio && i<=fin) && (i%2==0) && !(i%3==0) && (i!=16)  ){\n                System.out.print(i+\"-\");\n            }\n        }\n\n    }//main\n}//class\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/AbelADE.java",
    "content": "/**\n * Solución del reto #01 OPERADORES Y ESTRUCTURAS DE CONTROL.\n *\n * @author AbelADE\n */\npublic class AbelADE {\n\n    /**\n     * @param args the command line arguments\n     */\n    public static void main(String[] args) {        \n        /**\n         * Operadores aritméticos: actúan sobre números enteros y en punto flotante (decimales). \n         * Hay dos tipos:\n         *      -- Operadores binarios.\n         *      -- Operadores unarios.\n         */\n        \n            /**\n             * Operadores binarios: aplican sobre dos operandos.\n             * Tipos:\n             *      -- Suma (+)\n             *      -- Resta (-)\n             *      -- Multiplicación (*)\n             *      -- División (/)\n             *      -- Módulo (%)\n             */\n            \n            int a = 5;\n            int b = 1;\n            \n            System.out.println(\"Operadores binarios: aplican sobre dos operandos.\");\n            \n            System.out.println(\"Suma: \" + (a+b));\n            System.out.println(\"Resta: \" + (a-b));\n            System.out.println(\"Multiplicación: \" + (a*b));\n            System.out.println(\"División: \" + (a/b));\n            System.out.println(\"Módulo: \" + (a%b));\n            \n            System.out.println();\n            \n            /**\n             * Operadores unarios: aplican a un operando.\n             * Tipos:\n             *      -- Mantiene el signo del operando (+)\n             *      -- Cambia el signo del operando (-)\n             *      -- Autoincremento (++)\n             *      -- Autodecremento (--)\n             */\n            \n            int c = 10;\n            \n            System.out.println(\"Operadores unarios: aplican a un operando.\");\n            \n            System.out.println(\"Mantiene el signo: \" + (+c));\n            System.out.println(\"Cambia el signo: \" + (-c));\n            System.out.println(\"Autoincremento e impresión: \" + (++c)); //Se incrementa y se imprime\n            System.out.println(\"Impresión y autoincremento: \" + (c++)); //Se imprime y se incrementa\n            System.out.println(\"Autodecremento e impresión: \" + (--c)); //Se decrementa y se imprime\n            System.out.println(\"Impresión y autodecremento: \" + (c--)); //Se imprime y se decrementa\n            \n            System.out.println();\n            \n        \n        /**\n         * Operadores relacionales: para hacer comparaciones. \n         * Tipos:\n         *      -- Mayor que (>)\n         *      -- Mayor o igual que (>=)\n         *      -- Menor que (<)\n         *      -- Menor o igual que (<=)\n         *      -- Igual que (==)\n         *      -- Distinto de (!=)\n         */\n        \n        int d = 20;\n        int e = 50;\n        \n        System.out.println(\"Operadores relacionales: para hacer comparaciones.\");\n        \n        System.out.println(\"¿20 es mayor que 50? : \" +(d>e));\n        System.out.println(\"¿20 es mayor o igual que 50? : \" +(d>=e));\n        System.out.println(\"¿20 es menor que 50? : \" +(d<e));\n        System.out.println(\"¿20 es menor o igual que 50? : \" +(d<=e));\n        System.out.println(\"¿20 es igual que 50? : \" + (d==e));\n        System.out.println(\"¿20 es distinto de 50? : \" + (d!=e));\n            \n        System.out.println();\n        \n        /**\n         * Operadores lógicos: Operan con valores lógicos para devolver nuevos valores lógicos.\n         * Tipos:\n         *      -- AND (&): Evalúa si las dos expresiones son verdaderas.\n         *      -- AND en curtocircuíto (&&): No evalúa la segunda expresión si la primera es falsa.\n         *      -- OR (|): Evalúa si alguna de las expresiones es verdadera.\n         *      -- OR en curtocircuíto (||): No evalúa la segunda expresión si la primera es verdadera.\n         *      -- NOT (!): Cambia el valor de la variable lógica.\n         */\n        \n        boolean v = true;\n        boolean f = false;\n        \n        System.out.println(\"Operadores lógicos: Operan con valores lógicos para devolver nuevos valores lógicos.\");\n        \n        System.out.println(\"¿true es igual a false? : \" + (v&f));\n        System.out.println(\"¿true es igual a false? (cortocircuíto) : \" + (v&&f));\n        System.out.println(\"¿true o false son verdaderas? : \" + (v|f));\n        System.out.println(\"¿true o false son verdaderas? (cortocircuíto) : \" + (v||f));\n        System.out.println(\"Cambiamos el valor de true : \" + (!v));\n        \n        System.out.println();\n        \n        /**\n         * Operador sobre cadenas de caracteres (+): Para concatenar cadenas de caracteres.\n         */\n        \n        String text1 = \"¡Hola, \";\n        String text2 = \"Mundo!\";\n        \n        System.out.println(\"Operador sobre cadenas de caracteres:\");\n        \n        System.out.println(text1+text2);\n        \n        System.out.println();\n        \n        /**\n         * Operadores de asignación: Para asignar un valor a una variable.\n         * Tipos: \n         *      -- +=: Suma a la variable y sobrescribe el valor de la variable con el resultado.\n         *      -- -=: Resta a la variable y sobrescribe el valor de la variable con el resultado.\n         *      -- *=: Multiplica a la variable y sobrescribe el valor de la variable con el resultado.\n         *      -- /=: Divide a la variable y sobrescribe el valor de la variable con el resultado.\n         *      -- %=: Realiza el módulo a la variable y sobrescribe el valor de la variable con el resultado.\n         *      -- &=: Realiza un AND lógico a la variable y sobrescribe el valor de la variable con el resultado.\n         *      -- |=: Realiza un OR lógico a la variable y sobrescribe el valor de la variable con el resultado.\n         */\n        \n        int i;\n        boolean t = true;\n        \n        System.out.println(\"Operadores de asignación: Para asignar un valor a una variable.\");\n        \n        System.out.println(\"Asignamos valor a la variable i = \" + (i = 1));\n        System.out.println(\"Suma y asigna: \" + (i+=5));\n        System.out.println(\"Resta y asigna: \" + (i-=5));\n        System.out.println(\"Multiplica y asigna: \" + (i*=5));\n        System.out.println(\"Divide y asigna: \" + (i/=5));\n        System.out.println(\"Módulo y asigna: \" + (i/=5));\n        System.out.println(\"AND lógico y asigna: \" + (t&=true));\n        System.out.println(\"OR lógico y asigna: \" + (t|=false));\n        \n        System.out.println();\n        \n        /**\n         * Operadores a nivel de bits: operan con cada bit del operando, ofreciendo un control más granular sobre los datos. \n         * Tipos:\n         *      -- AND (&): Operador AND a nivel de bits (1 y 1 = 1).\n         *      -- OR (|): Operador OR a nivel de bits (1 o 1 = 1).\n         *      -- XOR (^): Operador XOR a nivel de bits (1 y 1 = 0).\n         *      -- Complemento (~): Invierte el valor de cada bit.\n         *      -- >> : Desplaza bits a la derecha.\n         *      -- << : Desplaza bits a la izquierda.\n         *      -- >>> : Desplaza bits a la derecha sin signo.\n         */\n        \n        int x = 10;\n        int y = 7;\n\n        System.out.println(\"Operadores a nivel de bits: operan con cada bit del operando, ofreciendo un control más granular sobre los datos.\");\n        \n        System.out.println();\n        \n        System.out.println(\"x : \" + Integer.toBinaryString(x));\n        System.out.println(\"y : \" + Integer.toBinaryString(y));\n        \n        System.out.println();\n        \n        System.out.println(\"X AND y : \" + Integer.toBinaryString(x & y));\n        System.out.println(\"x OR y : \" + Integer.toBinaryString(x | y));\n        System.out.println(\"x XOR y : \" + Integer.toBinaryString(x ^ y));\n        System.out.println(\"Complemento de x = \" + Integer.toBinaryString(~x));\n        System.out.println(\"Complemento de y = \" + Integer.toBinaryString(~y));\n        System.out.println(\"Desplazamiento de bits de x a la izquierda de y: \" + Integer.toBinaryString(x<<y));\n        System.out.println(\"Desplazamiento de bits de x a la derecha de y: \" + Integer.toBinaryString(x>>y));\n        System.out.println(\"Desplazamiento de bits de x a la derecha de y (sin signo): \" + Integer.toBinaryString(x>>>y));\n        \n        System.out.println();\n        \n        /*Crea un programa que imprima por consola todos los números comprendidos\n        * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.*/\n        \n        System.out.println(\"DIFICULTAD EXTRA \\n\");\n\n        System.out.println(\"Los números son: \");\n\n        for (int j = 10; j <= 55; j++) {\n            //Compruebo si son pares, distintos de 16 y no son múltiplos de 3\n            if (j%2==0 && j!= 16 && j%3!=0) {\n                System.out.println(j);\n            }\n        }\n        \n        \n    }\n\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/Ainoaran.java",
    "content": "//#Reto #01 OPERADORES Y ESTRUCTURAS DE CONTROL\n\npublic class Ainoaran {\n\n    public static void main(String[] args) {\n\n        //Operadores Aritméticos:\n\n        System.out.println(\"Operadores Aritméticos: \");\n\n        int a = 10, b = 5;\n        System.out.println(\"Suma: \" + (a + b));\n        System.out.println(\"Resta: \" + (a - b));\n        System.out.println(\"Multiplicación: \" + (a * b));\n        System.out.println(\"División: \" + (a / b));\n        System.out.println(\"Módulo: \" + (a % b));\n        System.out.println(\"Incremento: \" + (++a));\n        System.out.println(\"Decremento: \" + (--b));\n\n        System.out.println(\"--------------------------------------------------------------------------------\");\n\n        // Operadores Lógicos\n\n        System.out.println(\"Operadores Lógicos: \");\n\n        boolean x = true, y = false;\n        // AND (&&) - Devuelve true si ambas condiciones son verdaderas.\n        System.out.println(\"AND: \" + (x && y));\n        // OR (||) - Devuelve true si al menos una condición es verdadera.\n        System.out.println(\"OR: \" + (x || y));\n        // NOT (!) - invierte el valor de una condición, es decir, cambia true a false y viceversa.\n        System.out.println(\"NOT: \" + (!x));\n\n        System.out.println(\"--------------------------------------------------------------------------------\");\n\n\n        // Operadores de Comparación\n\n        System.out.println(\"Operadores de comparación: \");\n\n        System.out.println(\"Igualdad: \" + (a == b));\n        System.out.println(\"Diferente: \" + (a != b));\n        System.out.println(\"Mayor que: \" + (a > b));\n        System.out.println(\"Menor que: \" + (a < b));\n        System.out.println(\"Mayor o igual que: \" + (a >= b));\n        System.out.println(\"Menor o igual que: \" + (a <= b));\n\n        System.out.println(\"--------------------------------------------------------------------------------\");\n\n        // Operadores de Asignación:\n\n        System.out.println(\"Operadores de Asignación: \");\n\n        int c = 3;\n        System.out.println(\"Suma y asigna: \" + (c+=4));\n        System.out.println(\"Resta y asigna: \" + (c-=8));\n        System.out.println(\"Multiplica y asigna: \" + (c*=10));\n        System.out.println(\"Divide y asigna: \" + (c/=20));\n        System.out.println(\"Módulo y asigna: \" + (c%=6));\n\n        System.out.println(\"--------------------------------------------------------------------------------\");\n\n        // Operadores de Identidad\n\n        System.out.println(\"Operadores de Identidad: \");\n\n        String s1 = \"Hola\", s2 = \"こんにちは\";\n        System.out.println(\"Compara referencias: \" + (s1 == s2));\n        System.out.println(\"Compara contenido: \" + s1.equals(s2));\n\n        System.out.println(\"--------------------------------------------------------------------------------\");\n\n        //Operadores binarios:\n\n        System.out.println(\"Operadores Binarios: \");\n\n        int d = 6, e = 12;\n        System.out.println(\"Valor de 6 en binario: \" + Integer.toBinaryString(d));\n        System.out.println(\"Valor de 12 en binario: \" + Integer.toBinaryString(e));\n\n\n        System.out.println(\"d AND e : \" + Integer.toBinaryString(d & e));\n        System.out.println(\"d OR e : \" + Integer.toBinaryString(d | e));\n        System.out.println(\"d XOR e : \" + Integer.toBinaryString(d ^ e));\n        System.out.println(\"Complemento de d = \" + Integer.toBinaryString(~d));\n        System.out.println(\"Complemento de e = \" + Integer.toBinaryString(~e));\n        System.out.println(\"Desplazamiento de bits de d a la izquierda de e: \" + Integer.toBinaryString(d<<e));\n        System.out.println(\"Desplazamiento de bits de d a la derecha de e: \" + Integer.toBinaryString(d>>e));\n        System.out.println(\"Desplazamiento de bits de d a la derecha de e (sin signo): \" + Integer.toBinaryString(d>>>e));\n\n        System.out.println(\"--------------------------------------------------------------------------------\");\n\n        //Estructuras de control:\n\n        System.out.println(\"Condicionales: \");\n        int f= 10, g = 5;\n        if(f>g) {\n            System.out.println(\"f es mayor que g\");\n        } else {\n            System.out.println(\"g es mayor que f\");\n        }\n\n        System.out.println(\"Bucle for:\");\n        for (int i = 1; i <= 10; i++) {\n            System.out.println(i);\n        }\n\n        System.out.println(\"Bucle while\");\n        int num = 1;\n        while (num <= 10) {\n            System.out.println(num);\n            num++;\n        }\n\n        System.out.println(\"--------------------------------------------------------------------------------\");\n\n        System.out.println(\"Ejercicio extra: \");\n\n        /*Crea un programa que imprima por consola todos los números comprendidos\n        entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.*/\n\n        for (int i = 10; i <= 55; i++) {\n            if (i % 2 == 0 && i != 16 && i % 3 != 0) {\n                System.out.println(i);\n            }\n        }\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/AlexisDiaz000.java",
    "content": "public class AlexisDiaz000{\n    public static void main(String[] args) {\n        /*Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n        Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...*/\n\n        int a = 10, b = 5;\n        double x = 10.5, y = 5.5;\n        //suma\n        System.out.println(\"valores Enteros: a = 10 y b = 5 - valores decimales: x = 10.5 y y = 5.5\");\n        int sumaEteros = a + b;\n        double sumaDecimales = x + y;\n        System.out.println(\"Sumas Enteros: \" + sumaEteros + \"\\nSumas Decimales: \" + sumaDecimales);\n        //resta\n        System.out.println(\"Restas Enteros : \" + (a - b));\n        //divición\n        System.out.println(\"divicion entre enteros y decimales a/y: \" + (a / y));\n        //multiplicación\n        var multiplicador = a * b;\n        System.out.println(\"multiplicación de enteros: \" + multiplicador);\n        // Módulo o residuo (%)\n        int moduloEnteros = a % b;\n        System.out.println(\"Módulo de enteros: \" + moduloEnteros + \" y modulos de decimales: \" + (x % y));\n        // Incremento (++)\n        int incremento = a;\n        incremento++;\n        System.out.println(\"Incremento (++): \" + incremento);\n        // Decremento (--)\n        b--;\n        System.out.println(\"Decremento (--): \" + b);\n\n        //OPERADORES LOGICOS\n        boolean and = (2 > 5) && (10 < 3);\n        boolean or = (10 > 8) || (8 < 3);\n        boolean not = !(10 > 15);\n        System.out.println(\"\\nOperadores Lógicos:\");\n        System.out.println(\"OPERADOR AND: \" + and + \",OPERADOR OR: \" + or + \", OPERADOR NOT: \" + not);\n\n        //OPERADORES DE COMPARACIÓN\n\n        boolean mayor = 10 > 5;\n        boolean menor = 10 < 5;\n        boolean igual = 10 == 10;\n        boolean diferente = 10 != 5;\n        System.out.println(\"\\nOperadores de Comparación:\");\n        System.out.println(\"10 > 5: \" + mayor + \", 10 < 5: \" + menor + \", 10 == 10: \" + igual + \", 10 != 5: \" + diferente);\n\n\n        //OPERADORES DE ASIGNACIÓN\n        int numero = 10;\n\n        numero = 30;\n        System.out.println(numero);\n        numero += 10;\n        System.out.println(numero);\n        numero -= 10;\n        System.out.println(numero);\n        numero /= 2;\n        System.out.println(numero);\n        numero *= 10;\n        System.out.println(numero);\n        numero %= 2;\n        if (numero == 0) {\n            System.out.println(\"es par\");\n        } else {\n            System.out.println((\"no es par\"));\n        }\n\n        // If-Else\n        int edad = 18;\n        if (edad >= 18) {\n            System.out.println(\"\\nEres mayor de edad\");\n        } else {\n            System.out.println(\"\\nEres menor de edad\");\n        }\n\n        // Switch\n        int opcion = 1;\n        switch (opcion) {\n            case 1:\n                System.out.println(\"\\nOpción 1 seleccionada\");\n                break;\n            case 2:\n                System.out.println(\"\\nOpción 2 seleccionada\");\n                break;\n            default:\n                System.out.println(\"\\nOpción no válida\");\n        }\n\n        // Bucle While\n        int contador = 3;\n        System.out.println(\"\\nBucle While:\");\n        while (contador > 0) {\n            System.out.println(\"Contador: \" + contador);\n            contador--;\n        }\n\n        // Bucle For\n        System.out.println(\"\\nBucle For:\");\n        for (int i = 1; i <= 3; i++) {\n            System.out.println(\"Iteración: \" + i);\n        }\n\n        // Try-Catch (Manejo de Excepciones)\n        try {\n            int resultado = 10 / 0; // Error: División por cero\n            System.out.println(resultado);\n        } catch (ArithmeticException e) {\n            System.out.println(\"\\nError: División por cero no permitida\");\n\n        }\n        //Crea un programa que imprima por consola todos los números comprendido\n        // entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3\n\n        System.out.println(\"Números pares entre 10 y 55, excluyendo 16 y múltiplos de 3:\");\n\n        for (int i = 10; i <= 55; i++) {\n            // Verificar si el número es par, no es 16 y no es múltiplo de 3\n            if (i % 2 == 0 && i != 16 && i % 3 != 0) {\n                System.out.print(i + \" \");\n            }\n        }\n    }\n\n}    \n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/Alextc35.java",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\npublic class Alextc35 {\n        public static void main(String[] args) {\n\n                // \\n <- Salto de línea\n                // \\t <- Tabulación\n\n                // 1. 2. 3.\n\n                // Operadores Aritméticos\n                System.out.println(\"-------------------------------------------------------------\");\n                System.out.println(\"\\tOPERADORES ARITMÉTICOS\");\n                System.out.println(\"-------------------------------------------------------------\");\n\n                int x = 7;\n                int y = 5;\n\n                // Suma\n                int z = x + y;\n                System.out.println(\"\\nSuma de \" + x + \" + \" + y + \" = \" + z);\n\n                // Resta\n                z = x - y;\n                System.out.println(\"\\nResta de \" + x + \" - \" + y + \" = \" + z);\n\n                // Multiplicación\n                z = x * y;\n                System.out.println(\"\\nMultiplicación de \" + x + \" * \" + y + \" = \" + z);\n\n                // División (entera)\n                z = x / y;\n                System.out.println(\"\\nDivisón entera de \" + x + \" / \" + y + \" = \" + z);\n\n                // División (real)\n                double j = (double) x / y;\n                System.out.println(\"\\nDivisón real de \" + x + \" / \" + y + \" = \" + j);\n\n                // Resto\n                z = x % y;\n                System.out.println(\"\\nResto de \" + x + \" % \" + y + \" = \" + z);\n\n                // Incrementos\n                System.out.println(\"\\n-------------------------------------------------------------\");\n                System.out.println(\"\\tINCREMENTOS\");\n                System.out.println(\"-------------------------------------------------------------\");\n\n                // x++\n                System.out.println(\"\\n\\t\\tx++\");\n                System.out.println(\"Sin incremento x = \" + x);\n                z = x++; // z tiene el valor de x sin incrementar\n                System.out.println(\"Con incremento x = \" + x + \"\\nz = \" + z);\n\n                // ++x\n                System.out.println(\"\\n\\t\\t++x\");\n                x = 7;\n                System.out.println(\"Sin incremento x = \" + x);\n                z = ++x;\n                System.out.println(\"Con incremento x = \" + x + \"\\nz = \" + z);\n\n                // Decrementos\n                System.out.println(\"-------------------------------------------------------------\");\n                System.out.println(\"\\tDECREMENTOS\");\n                System.out.println(\"-------------------------------------------------------------\");\n\n                // x--\n                System.out.println(\"\\n\\t\\tx--\");\n                x = 7;\n                System.out.println(\"Sin decremento x = \" + x);\n                z = x--;\n                System.out.println(\"Con decremento x = \" + x + \"\\nz = \" + z);\n\n                // --x\n                System.out.println(\"\\n\\t\\t--x\");\n                x = 7;\n                System.out.println(\"Sin decremento x = \" + x);\n                z = --x;\n                System.out.println(\"Con decremento x = \" + x + \"\\nz = \" + z);\n\n                // Asignación\n                System.out.println(\"\\n-------------------------------------------------------------\");\n                System.out.println(\"\\tASIGNACIÓN\");\n                System.out.println(\"-------------------------------------------------------------\");\n\n                x = 20;\n                System.out.println(\"\\tx = 20\");\n\n                // x = x + 5\n                x += 5;\n                System.out.println(\"x += 5 -> x = \" + x);\n\n                // x = x - 3\n                x -= 3;\n                System.out.println(\"x -= 3 -> x = \" + x);\n\n                // x = x * 2\n                x *= 2;\n                System.out.println(\"x *= 2 -> x = \" + x);\n\n                // x = x / 4\n                x /= 4;\n                System.out.println(\"x /= 4 -> x = \" + x);\n\n                // x = x % 3\n                x %= 3;\n                System.out.println(\"x %= 3 -> x = \" + x);\n\n                // Operadores de Pertenencia (simulación)\n                System.out.println(\"\\n-------------------------------------------------------------\");\n                System.out.println(\"\\tOPERADOR DE PERTENENCIA\");\n                System.out.println(\"-------------------------------------------------------------\\n\");\n\n                int[] array = {1, 2, 3, 4, 5};\n                boolean isInArray = false;\n                for (int i : array) {\n                        if (i == 3) {\n                                isInArray = true;\n                                break;\n                        }\n                }\n                System.out.println(\"¿3 está en el array?: \" + isInArray);\n\n                // Operadores a nivel de Bits\n                System.out.println(\"\\n-------------------------------------------------------------\");\n                System.out.println(\"\\tOPERADORES A NIVEL DE BITS\");\n                System.out.println(\"-------------------------------------------------------------\");\n\n                int bitmask = 0b0011;\n                int val = 0b1111;\n\n                // AND\n                int res = val & bitmask;\n                System.out.println(\"\\n1111 AND 0011 = \" + Integer.toBinaryString(res));\n\n                // OR exclusivo\n                res = val ^ bitmask;\n                System.out.println(\"\\n1111 OR exclusivo 0011 = \" + Integer.toBinaryString(res));\n\n                // OR inclusivo\n                res = val | bitmask;\n                System.out.println(\"\\n1111 OR inclusivo 0011 = \" + Integer.toBinaryString(res));\n\n                System.out.println(\"\\n-------------------------------------------------------------\");\n                // 0b1111\n                System.out.println(\"\\n\\t1111\");\n\n                // Desplazamiento a la izquierda\n                res = val << 1; // 11110\n                System.out.println(\"\\nDesplazamiento a la izquierda = \" + Integer.toBinaryString(res));\n\n                // Desplazamiento a la derecha con signo\n                res = val >> 2; // 0011\n                System.out.println(\"\\nDesplazamiento a la derecha con signo = \" + Integer.toBinaryString(res));\n\n                // Desplazamiento a la derecha con el signo en el negativo\n                res = (-val) >> 2; // 11111111111111111111111111111100\n                System.out.println(\"\\nDesplazamiento a la derecha con Signo (Negativo) = \"\n                                + Integer.toBinaryString(res));\n\n                // Desplazamiento a la derecha sin signo\n                res = val >>> 1; // 111\n                System.out.println(\"\\nDesplazamiento a la derecha sin signo = \" + Integer.toBinaryString(res));\n\n                // Inverso o Commplementario a 1\n                res = ~val; // 11111111111111111111111111110000\n                System.out.println(\"\\nInverso o Complementario a 1 = \" + Integer.toBinaryString(res));\n\n                // Operadores Lógicos Condicionales\n                System.out.println(\"\\n-------------------------------------------------------------\");\n                System.out.println(\"\\tOPERADORES LÓGICOS CONDICIONALES\");\n                System.out.println(\"-------------------------------------------------------------\\n\");\n\n                int valor1 = 1;\n                int valor2 = 2;\n\n                // AND\n                if ((valor1 == 1) && (valor2 == 2)) {\n                        System.out.println(\"(valor1 es 1) AND (valor2 es 2)\");\n                }\n\n                // OR\n                if ((valor1 == 1) || (valor2 == 1)) {\n                        System.out.println(\"\\n(valor1 es 1) OR (valor2 es 1)\");\n                }\n\n                // NOT\n                if (valor1 != 2) {\n                        System.out.println(\"\\n(valor1 es distinto de 2)\");\n                }\n\n                // Operador de Identidad\n                System.out.println(\"\\n-------------------------------------------------------------\");\n                System.out.println(\"\\tOPERADOR DE IDENTIDAD\");\n                System.out.println(\"-------------------------------------------------------------\\n\");\n\n                Integer int1 = 100;\n                Integer int2 = 100;\n\n                System.out.println(\"int1 == int2: \" + (int1 == int2)); // Identidad (valores)\n                System.out.println(\"num1.equals(int2): \" + (int1.equals(int2))); // Comparación de contenido\n                System.out.println(\"num1 != num2: \" + (int1 != int2)); // Diferente identidad (valores)\n\n                // Operador Ternario\n                System.out.println(\"\\n-------------------------------------------------------------\");\n                System.out.println(\"\\tOPERADOR TERNARIO\");\n                System.out.println(\"-------------------------------------------------------------\\n\");\n\n                int result;\n                boolean someCondition = false;\n\n                System.out.println(\"valor1: \" + valor1 \n                        + \"\\nvalor2: \" + valor2\n                        + \"\\n\\tSi es true: valor1\"\n                        +\"\\n\\tSi es false: valor2\");\n\n                // La condición es falsa, por lo tanto result = valor2 = 2\n                result = someCondition ? valor1 : valor2; // variable = (condición) ? valorSiVerdadero : valorSiFalso\n\n                System.out.println(\"\\nEs false: \" + result);\n\n                // Operadores Lógicos Relacionales\n                System.out.println(\"\\n-------------------------------------------------------------\");\n                System.out.println(\"\\tOPERADORES LÓGICOS RELACIONALES\");\n                System.out.println(\"-------------------------------------------------------------\");\n\n                // Igual\n                if (valor1 == valor2)\n                        System.out.println(\"\\nvalor1 == valor2\"); // valor1 igual a valor2\n\n                // Distinto\n                if (valor1 != valor2)\n                        System.out.println(\"\\nvalor1 != valor2\"); // valor1 distinto de valor2\n\n                // Mayor que\n                if (valor1 > valor2)\n                        System.out.println(\"\\nvalor1 > valor2\"); // valor1 mayor que valor2\n\n                // Menor que\n                if (valor1 < valor2)\n                        System.out.println(\"\\nvalor1 < valor2\"); // valor1 menor que valor2\n\n                // Menor o Igual que\n                if (valor1 <= valor2)\n                        System.out.println(\"\\nvalor1 <= valor2\"); // valor1 menor o igual que valor2\n\n                // Mayor o Igual que\n                if (valor1 >= valor2)\n                        System.out.println(\"\\nvalor1 >= valor2\"); // valor1 mayor o igual que valor2\n\n                // Casting\n                System.out.println(\"\\n-------------------------------------------------------------\");\n                System.out.println(\"\\tCASTING\");\n                System.out.println(\"-------------------------------------------------------------\\n\");\n\n                int adiv = 5; // Divisor\n                int bden = 9; // Denominador\n\n                System.out.println(adiv + \" / \" + bden + \" = \" + (double) adiv / bden);\n\n                System.out.println(\"\\n-------------------------------------------------------------\");\n                \n                // Sentencia\n                int numero; // También llamado línea de código\n\n                // Expresiones\n                System.out.println(\"\\tEXPRESIONES\");\n                System.out.println(\"-------------------------------------------------------------\");\n\n                numero = 1 + 2; // Expresión\n                System.out.println(\"\\nLa suma de 1 + 2 es: \" + numero);\n\n                numero = (1 + 2) * 3; // Expresión compuesta\n                System.out.println(\"\\nLa operación de (1 + 2) * 3 es: \" + numero);\n\n                // Bloque de Código\n                System.out.println(\"\\n-------------------------------------------------------------\");\n                System.out.println(\"\\tBLOQUE DE CÓDIGO\");\n                System.out.println(\"-------------------------------------------------------------\");\n\n                boolean condicion = true;\n\n                if (condicion) {\n                        System.out.println(\"\\nLa condición es verdadera\");\n                } else {\n                        System.out.println(\"\\nLa condición es falsa\");\n                }\n\n                // Estructura de Decisión\n                System.out.println(\"\\n-------------------------------------------------------------\");\n                System.out.println(\"\\tESTRUCTURA DE DECISIÓN\");\n                System.out.println(\"-------------------------------------------------------------\\n\");\n                \n                // Esctructura if-then\n                System.out.println(\"\\tESTRUCTURA IF-THEN\");\n                int num1 = 5, num2 = 4;\n                if (num1 > num2) {\n                        System.out.println(\"num1 es mayor que num2\\n\");\n                }\n\n                // Estructura if-else\n                System.out.println(\"\\tESTRUCTURA IF-ELSE\");\n                num1 = 25;\n                num2 = 21;\n                if (num1 > num2) {\n                        System.out.println(\"El número mayor es \" + num1 + \"\\n\");\n                } else {\n                        System.out.println(\"El número mayor es \" + num2 + \"\\n\");\n                }\n\n                // Estructura if-else-if\n                System.out.println(\"\\tESTRUCTURA IF-ELSE-IF\");\n                float puntuacion = 5.6f;\n                if (puntuacion >= 9) {\n                        System.out.println(\"Tienes un SOBRESALIENTE\\n\");\n                } else if (puntuacion >= 7) {\n                        System.out.println(\"Tienes un NOTABLE\\n\");\n                } else if (puntuacion >= 5) {\n                        System.out.println(\"Tienes un APROBADO\\n\");\n                } else {\n                        System.out.println(\"Tienes un SUSPENSO\\n\");\n                }\n\n                // Estructura switch\n                System.out.println(\"\\tESTRUCTURA SWITCH\");\n                int mes = 8;\n                String mesString;\n                switch (mes) {\n                        case 1:\n                                mesString = \"Enero\"; // mes == 1 -> True\n                                break;\n                        case 2:\n                                mesString = \"Febrero\";\n                                break;\n                        case 3:\n                                mesString = \"Marzo\";\n                                break;\n                        case 4:\n                                mesString = \"Abril\";\n                                break;\n                        case 5:\n                                mesString = \"Mayo\";\n                                break;\n                        case 6:\n                                mesString = \"Junio\";\n                                break;\n                        case 7:\n                                mesString = \"Julio\";\n                                break;\n                        case 8:\n                                mesString = \"Agosto\";\n                                break;\n                        case 9:\n                                mesString = \"Septiembre\";\n                                break;\n                        case 10:\n                                mesString = \"Octubre\";\n                                break;\n                        case 11:\n                                mesString = \"Noviembre\";\n                                break;\n                        case 12:\n                                mesString = \"Diciembre\";\n                                break;\n                        default:\n                                mesString = \"Mes no válido\";\n                                break;\n                }\n                System.out.println(mesString + \"\\n\");\n\n                // Otra estructura switch\n                System.out.println(\"\\tOTRA ESTRUCTURA SWITCH\");\n                mes = 2;\n                int numDias = 0;\n                switch (mes) {\n                        case 1:\n                        case 3:\n                        case 5:\n                        case 7:\n                        case 8:\n                        case 10:\n                        case 12:\n                                numDias = 31;\n                                break;\n                        case 4:\n                        case 6:\n                        case 9:\n                        case 11:\n                                numDias = 30;\n                                break;\n                        case 2:\n                                numDias = 28;\n                                break;\n                        default:\n                                System.out.println(\"Mes no válido\\n\");\n                                break;\n                }\n                System.out.println(\"Número de días = \" + numDias + \"\\n\");\n\n                // Bucles\n                System.out.println(\"\\n-------------------------------------------------------------\");\n                System.out.println(\"\\tBUCLES\");\n                System.out.println(\"-------------------------------------------------------------\\n\");\n\n                // Bucle while\n                System.out.println(\"\\tBUCLE WHILE\");\n                int contador = 1;\n                while (contador < 11) {\n                        System.out.println(\"Contador vale: \" + contador);\n                        contador++;\n                }\n\n                // Bucle do-while\n                System.out.println(\"\\n\\tBUCLE DO-WHILE\");\n                contador = 1;\n                do {\n                        System.out.println(\"Contador vale: \" + contador);\n                        contador++;\n                } while (contador < 11);\n\n                // Bucle for\n                System.out.println(\"\\n\\tBUCLE FOR\");\n                for (int auxiliar = 1; auxiliar < 11; auxiliar++) {\n                        System.out.println(\"Contador vale: \" + auxiliar);\n                }\n\n                // Excepciones\n                System.out.println(\"\\n-------------------------------------------------------------\");\n                System.out.println(\"\\tEXCEPCIONES\");\n                System.out.println(\"-------------------------------------------------------------\\n\");\n                \n                // try-catch\n                System.out.println(\"\\tTRY-CATCH\");\n                try {\n                        result = 10 / 0;\n                } catch (ArithmeticException e) {\n                        System.out.println(\"Error: División por cero.\");\n                }\n\n                // try-finally\n                System.out.println(\"\\n\\tTRY-FINALLY\");\n                try {\n                        System.out.println(\"Código a probar\");\n                } finally {\n                        System.out.println(\"Siempre se ejecuta `finally`\");\n                }\n\n                // Opcional\n                System.out.println(\"\\n-------------------------------------------------------------\");\n                System.out.println(\"\\tOPCIONAL\");\n                System.out.println(\"-------------------------------------------------------------\\n\");\n\n                /* i comienza siendo 10 y el 56 pibota cortando el bucle cuando llegue a i = 55,\n                /* por cada vuelta se suma +1 a i.\n                 */\n                for (int i = 10; i <= 55; i++) {\n                        // i tiene que ser par, distinto de 16 y que no sea múltiplo de 3.\n                        if ((i % 2 == 0) && (i != 16) && (i % 3 != 0)) {\n                                System.out.print(i + \" \");\n                        }\n                }\n                System.out.println();\n        }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/AmadorQuispe.java",
    "content": "public class AmadorQuispe {\n\n    public static void main(String[] args) {\n        assignmentOperator();\n        arithmeticOperators();\n        unaryOperators();\n        equalityRelationalOperators();\n        conditionalOperators();\n        bitwiseOperators();\n        System.out.println(\"FLUJOS DE CONTROL\");\n        System.out.println(\"-------------------\");\n\n        // if else\n        String name = \"Alex\";\n        int age = 20;\n        // con podemos imprimir por pantalla si Alex es mayor de edad (se considera\n        // mayor de edad, tine mas de 18 años )\n        if (age > 18) {\n            System.out.println(name + \" es mayor de edad\");\n        }\n        // if else\n        // en el ejemplo anterior podemos imprimir por pantall si no es mayor de edad\n        if (age > 18) {\n            System.out.println(name + \" es mayor de edad\");\n        } else {\n            System.out.println(name + \" no es mayor de edad\");\n        }\n        // While, ejecuta un bloque hasta que la condición sea falta\n        // ejemplo: imprimimos la multiplicacion del numero 2 hasta 12\n        int number = 0;\n        while (number <= 12) {\n            System.out.println(\"2 x \" + number + \" = \" + 2 * number);\n            number++;\n        }\n        // do while, por lo menos se ejecuta una vez, y luego comprueba la condición y\n        // repita que la condición sea\n        // falsa\n\n        int j = 1;\n        do {\n            System.out.println(j);\n            j++;\n        } while (j <= 10);\n\n        // for, utilizado cuando se quiere ejecutar un determinado de veces (se conoce\n        // inicio y fin)\n        // imprimir tabla de 5\n        for (int i = 0; i < 10; i++) {\n            System.out.println(\"5 x \" + i + \" = \" + 5 * i);\n        }\n        // switch,permite ejecutar diferentes bloques de código según el valor de una\n        // variable\n        int dayWeek = 3;\n        switch (dayWeek) {\n            case 1:\n                System.out.println(\"Lunes\");\n                break;\n            case 2:\n                System.out.println(\"Martes\");\n                break;\n            case 3:\n                System.out.println(\"Miércoles\");\n                break;\n            default:\n                System.out.println(\"Día no válido\");\n                break;\n        }\n\n        // break y continue, se utilizan dentro de los bucles y modifican el flujo\n        // natural de los mismos.\n\n        // continue, finaliza la iteración que en ese momento se está ejecutando\n\n        for (int i = 1; i <= 5; i++) {\n            // Saltar la iteración si el número es par\n            if (i % 2 == 0) {\n                System.out.println(\"Número par encontrado: \" + i);\n                continue; // Salta al siguiente valor de i sin ejecutar el código restante en el bucle\n            }\n\n            // Este código solo se ejecutará para números impares\n            System.out.println(\"Número impar: \" + i);\n        }\n\n        // Exception\n        try {\n            String[] students = { \"Alex\", \"Pedro\", \"Juan\", \"Marco\" };\n            System.out.println(students[5]);\n        } catch (Exception e) {\n            System.out.println(e.getMessage());\n        }\n        /*\n         * Crea un programa que imprima por consola todos los números comprendidos\n         * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n         */\n        for (int i = 10; i <= 55; i++) {\n            if (i % 2 == 0 && i != 16 && i % 3 != 0) {\n                System.out.println(i);\n            }\n        }\n\n    }\n\n    /*\n     * OPERADOR ASIGNACIÓN\n     */\n    private static void assignmentOperator() {\n        System.out.println(\"OPERADOR ASIGNACIÓN\");\n        System.out.println(\"-----------------\");\n        // El operador asignación =, es un operador binario que asigna el valor del\n        // término de la derecha al operando de la izquierda.\n        int n;\n        // (=) asignación\n        n = 10;\n        System.out.println(\"i = \" + n);\n        System.out.println(\"ASIGNACIÓN COMBINADO CON OPERADORES ARITMÉTICOS\");\n        System.out.println(\"-----------------------------\");\n        // (+=) suma en asignación.\n        n += 2;//\n        System.out.println(\"El valor de n es: \" + n);\n        // (-=) resta en asignación.\n        n -= 2;//\n        System.out.println(\"El valor de n es: \" + n);\n        // (*=) producto en asignación.\n        n *= 2;//\n        System.out.println(\"El valor de n es: \" + n);\n        // (/=) división en asignación.\n        n /= 2;//\n        System.out.println(\"El valor de n es: \" + n);\n        // (%=) módulo en asignación.\n        n %= 2;//\n        System.out.println(\"El valor de n es: \" + n);\n    }\n\n    /*\n     * OPERADORES ARITMÉTICOS\n     */\n    private static void arithmeticOperators() {\n        System.out.println(\"OPERADORES ARITMÉTICOS\");\n        System.out.println(\"--------------------\");\n        // Operadores aritméticos.\n\n        float number1 = 10;\n        float number2 = 3;\n        // + Operador de suma (también utilizado para la concatenación de cadenas)\n        System.out.println(\"SUMA\");\n        System.out.println(\"La suma de :\" + number1 + \" y \" + number2 + \" es: \" + (number1 + number2));\n        // - Operador de resta\n        System.out.println(\"RESTA\");\n        System.out.println(\"La resta de :\" + number1 + \" y \" + number2 + \" es: \" + (number1 - number2));\n        // '* Operador de multiplicación\n        System.out.println(\"MULTIPLICACION\");\n        System.out.println(\"La multiplicación de :\" + number1 + \" y \" + number2 + \" es: \" + (number1 * number2));\n        // / Operador de división\n        System.out.println(\"DIVISION\");\n        System.out.println(\"La división de :\" + number1 + \" y \" + number2 + \" es: \" + (number1 / number2));\n        // % Operador de resto\n        System.out.println(\"MODULO\");\n        System.out.println(\"El resto de :\" + number1 + \" y \" + number2 + \" es: \" + (number1 % number2));\n    }\n\n    /*\n     * OPERADORES UNARIOS.\n     */\n    private static void unaryOperators() {\n        System.out.println(\"OPERADORES UNARIOS\");\n        System.out.println(\"--------------------\");\n\n        int value = +5;\n\n        // Operador unario más(+) ; Representa un valor positivo (sin embargo, los\n        // números son positivos sin esto)\n        System.out.println(\"El valor de 'value' es: \" + value);\n\n        // Operador de incremento (++); incrementa un valor en 1\n        value++; // incrementa 1, value = 6\n        System.out.println(\"El valor de 'value' luego de 'value++' es: \" + value);\n\n        ++value; // incrementa 1, value = 7\n        System.out.println(\"El valor de 'value' luego de '++value' es: \" + value);\n\n        // Operador de decremento (--); decrementa un valor en 1\n        value--; // decrementa 1, value = 6\n        System.out.println(\"El valor de 'value' luego de 'value--' es: \" + value);\n\n        --value; // decrementa 1, value = 5\n        System.out.println(\"El valor de 'value' luego de '--value' es: \" + value);\n\n        // Operador menos unario (- ); Representa un valor\n        int negative = -value;\n        System.out.println(\"El valor de  'value' es: \" + negative);\n\n        // Operador de complemento lógico (!). Invierte el valor de un booleano\n        boolean isJava = true;\n        System.out.println(\"valor inicial: \" + isJava + \" valor invertido: \" + !isJava);\n\n    }\n\n    /*\n     * OPERADORES RELACIONALES Y IGUALDAD\n     */\n\n    public static void equalityRelationalOperators() {\n        System.out.println(\"OPERADORES RELACIONALES Y IGUALDAD\");\n        System.out.println(\"--------------------------\");\n\n        int value1 = 1;\n        int value2 = 2;\n\n        if (value1 == value2) // igual a : compara si son iguales\n            System.out.println(\"value1 == value2\");\n        if (value1 != value2) // diferente a : compara si son diferentes\n            System.out.println(\"value1 != value2\");\n        if (value1 > value2) // mayor que : compara si value1 es mayor que value2\n            System.out.println(\"value1 > value2\");\n        if (value1 >= value2) // mayor o igual que : compara si value1 es mayor o igual que value2\n            System.out.println(\"value1 >= value2\");\n        if (value1 < value2) // menor que : compara si value1 es menor que value2\n            System.out.println(\"value1 < value2\");\n        if (value1 <= value2) // menor o igual que : compara si value1 es menor o igual que value2\n            System.out.println(\"value1 <= value2\");\n    }\n    /*\n     * OPERADORES CONDICIONALES U OPERADORES LÓGICOS\n     */\n\n    public static void conditionalOperators() {\n        System.out.println(\"OPERADORES CONDICIONALES\");\n        System.out.println(\"--------------------------\");\n\n        int value1 = 1;\n        int value2 = 2;\n        System.out.println(\"int value1 = \" + value1);\n        System.out.println(\"int value2 = \" + value2);\n\n        if (value1 > 0 && value2 > 0)// condicional AND: es 'true' si ambos operandos son 'true'\n            System.out.println(\"value1 > 0 && value2 > 0\");\n        if (value1 > 0 || value2 == 0)// condicional OR: es 'true' si al menos un operandos es 'true'\n            System.out.println(\"value1 > 0 || value2 == 0\");\n        // TERNARIO\n        // Si el resultado de evaluar la expresión lógica es verdadero, devuelve el\n        // valor de la primera expresión,\n        // y en caso contrario, devuelve el valor de la segunda expresión\n        String result = value1 < value2 ? \"value1 si es menor a value2\" : \"value1 no es menor a value2\";\n        System.out.println(\"value1 < value2? :\" + result);\n    }\n\n    /*\n     * OPERADORES BIT A BIT\n     */\n    public static void bitwiseOperators() {\n        System.out.println(\"OPERADORES BIT A BIT\");\n        System.out.println(\"--------------------------\");\n        int x = 5;\n        int y = 3;\n        // Operador & (AND bit-a-bit)\n        int resultAND = x & y;\n        System.out.println(resultAND); // imprimirá 1\n        // Operador | (OR bit-a-bit)\n        int resultOR = x | y;\n        System.out.println(resultOR); // imprimirá 7\n        // Operador ^ (XOR bit-a-bit)\n        int resultXOR = x ^ y;\n        System.out.println(resultXOR); // imprimirá 6\n        // Operador ~ (complemento a uno)\n        int resultCOM = ~x;\n        System.out.println(resultCOM); // imprimirá -6\n        // Operador << (desplazamiento a la izquierda)\n        int desplazamiento = 2;\n        int resultIzq = x << desplazamiento;\n        System.out.println(resultIzq);\n        // Operador >> (desplazamiento a la derecha)\n        int resultDer = x >> desplazamiento;\n        System.out.println(resultDer);\n        // Operador >>> (desplazamiento a la derecha sin signo)\n        int resultD = x >>> desplazamiento;\n        System.out.println(resultD);\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/AnaLauraDB.java",
    "content": "public class AnaLauraDB {\n    public static void main(String[] args) {\n        // Operadores aritmeticos\n        int a = 10;\n        int b = 3;\n\n        int suma = a + b;\n        int resta = a - b;\n        int multiplicacion = a * b;\n        int division = a / b;\n        int modulo = a % b;\n\n        System.out.println(\"Suma: \" + suma);\n        System.out.println(\"Resta: \" + resta);\n        System.out.println(\"Multiplicación: \" + multiplicacion);\n        System.out.println(\"División: \" + division);\n        System.out.println(\"Módulo: \" + modulo);\n        System.out.println();\n        // Operadores de comparación\n        boolean esIgual = (a == b);\n        boolean esDiferente = (a != b);\n        boolean esMayor = (a > b);\n        boolean esMenor = (a < b);\n        boolean esMayorOIgual = (a >= b);\n        boolean esMenorOIgual = (a <= b);\n        System.out.println(\"Es igual: \" + esIgual);\n        System.out.println(\"Es diferente: \" + esDiferente);\n        System.out.println(\"Es mayor: \" + esMayor);\n        System.out.println(\"Es menor: \" + esMenor);\n        System.out.println(\"Es mayor o igual: \" + esMayorOIgual);\n        System.out.println(\"Es menor o igual: \" + esMenorOIgual);\n        System.out.println();\n        // Operadores lógicos\n        boolean x = true;\n        boolean y = false;\n        boolean and = x && y;\n        boolean or = x || y;\n        boolean not = !x;\n        System.out.println(\"AND: \" + and);\n        System.out.println(\"OR: \" + or);\n        System.out.println(\"NOT: \" + not);\n        System.out.println();\n        // Operadores de asignación\n        int c = 5;\n        c += 4;\n        System.out.println(\"Asignación con suma: \" + c);\n        c -= 2;\n        System.out.println(\"Asignación con resta: \" + c);\n        c *= 3;\n        System.out.println(\"Asignación con multiplicación: \" + c);\n        c /= 2;\n        System.out.println(\"Asignación con división: \" + c);\n        c %= 3;\n        System.out.println(\"Asignación con módulo: \" + c);\n        System.out.println();\n        // Operadores de identidad\n        String str1 = new String(\"Hola\");\n        String str2 = new String(\"Hola\");\n        boolean sonIdenticos = (str1 == str2);\n        boolean sonIguales = str1.equals(str2);\n        System.out.println(\"Son idénticos: \" + sonIdenticos);\n        System.out.println(\"Son iguales: \" + sonIguales);\n        System.out.println();\n        // Operadores de bits\n        int x1 = 5; // 0101 en binario\n        int x2 = 3; // 0011 en binario\n        int andBit = x1 & x2; // 0001 en binario\n        int orBit = x1 | x2; // 0111 en binario\n        int xorBit = x1 ^ x2; // 0110 en binario\n        int notBit = ~x1; // 1010 en binario (complemento a 1)\n        int desplazamientoIzq = x1 << 1; // 1010 en binario (desplazamiento a la izquierda)\n        int desplazamientoDerecha = x1 >> 1; // 0010 en binario (desplazamiento a la derecha)\n        System.out.println(\"AND bit a bit: \" + andBit);\n        System.out.println(\"OR bit a bit: \" + orBit);\n        System.out.println(\"XOR bit a bit: \" + xorBit);\n        System.out.println(\"NOT bit a bit: \" + notBit);\n        System.out.println(\"Desplazamiento a la izquierda: \" + desplazamientoIzq);\n        System.out.println(\"Desplazamiento a la derecha: \" + desplazamientoDerecha);\n        System.out.println();\n        // Operadores de pertenencia\n        String[] frutas = { \"manzana\", \"banana\", \"naranja\" };\n        boolean contieneManzana = false;\n        for (String fruta : frutas) {\n            if (fruta.equals(\"manzana\")) {\n                contieneManzana = true;\n                break;\n            }\n        }\n        // Estructuras de control\n\n        // Condicionales\n        if (suma > resta) {\n            suma += c;\n            System.out.println(\"Suma actual: \" + suma);\n        } else if (suma < resta) {\n            resta -= c;\n            System.out.println(\"Resta actual: \" + resta);\n        } else {\n            System.out.println(\"Laura ha creado un reto de programación.\");\n        }\n\n        // Iterativas\n        System.err.println(\" \");\n        for (b = 0; b < 10; b++) {\n            System.out.println(\"Iteración: \" + b);\n        }\n\n        System.err.println(\" \");\n        while (b <= 10) {\n            System.out.println(\"B es menor o igual a 10: \" + b);\n            b++;\n        }\n\n        System.err.println(\" \");\n        // Do-While\n        do {\n            System.out.println(\"B es menor o igual a 10: \" + b);\n            b--;\n        } while (b > 0);\n\n        // Manejo de excepciones\n        try {\n            int resultado = a / 0; // Esto generará una excepción de división por cero\n        } catch (ArithmeticException e) {\n            System.out.println(\"Error: División por cero no permitida.\");\n        } finally {\n            System.out.println(\"Bloque finally ejecutado.\");\n        }\n\n        // Extra\n        for (int i = 10; i <= 55; i++) {\n            if (i % 2 == 0 && i != 16 && i % 3 != 0) {\n                System.out.println(i);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/Anaroncero.java",
    "content": "/*\n        * EJERCICIO:\n        * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n        * Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia,\n        * bits...\n        * (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n        * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n        * que representen todos los tipos de estructuras de control que existan\n        * en tu lenguaje:\n        * Condicionales, iterativas, excepciones...\n        * - Debes hacer print por consola del resultado de todos los ejemplos.\n        *\n        * DIFICULTAD EXTRA (opcional):\n        * Crea un programa que imprima por consola todos los números comprendidos\n        * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n        *\n        * Seguro que al revisar detenidamente las posibilidades has descubierto algo\n        * nuevo.\n\n*/\npublic class Anaroncero {\n    public static void main(String[] args) {\n\n        /* Variables */\n        int num1 = 2, num2 = 4;\n        int resultado = 0;\n\n        // Operaciones Aritmeticas\n        System.out.println(\"-----Operaciones Aritmeticas----\");\n\n        System.out.println(\"Suma: \" + (num1 + num2));\n        System.out.println(\"Resta: \" + (num1 - num2));\n        System.out.println(\"Multiplicacion: \" + (num1 * num2));\n        System.out.println(\"Division: \" + (num1 / num2));\n        System.out.println(\"Resto: \" + (num1 % num2));\n\n        // Operaciones Logicas\n        System.out.println(\"-----Operaciones Logicas----\");\n        boolean verdadero = true;\n        boolean falso = false;\n\n        // AND y\n        System.out.println(\"AND\"); // SE TIENEN QUE CUMPLIR AMBAS CONDICIONES\n        System.out.println(false && false); // falso\n        System.out.println(false && true); // falso\n        System.out.println(true && true); // verdadero\n        System.out.println(true && false); // falso\n\n        // OR\n        System.out.println(\"OR\"); // SE TIENE QUE CUMPLIR UNA U OTRA CONDICION O AMBAS\n        System.out.println(false || false); // falso\n        System.out.println(false || true); // verdadero\n        System.out.println(true || true); // verdadero\n        System.out.println(true || false); // verdadero\n\n        // NOT\n        System.out.println(\"OR\"); // AL REVES\n        System.out.println(!true); // (!si no es verdadero) es falso\n        System.out.println(!false); // (!si no es falso) es verdadero\n\n        // Comparacion\n        System.out.println(\"Comparacion\");\n        System.out.println(num1 == num2); // si son iguales\n        System.out.println(num1 != num2); // si son diferentes\n        System.out.println(num1 > num2); // si es mayor que\n        System.out.println(num1 > num2); // menor que\n        System.out.println(num1 > num2); // si es mayor o igual que\n        System.out.println(num1 > num2); // si es menor o igual que\n\n        // Asignacion\n        System.out.println(\"Asignacion\");\n        System.out.println(\"Asignacion: \" + (num1 = num2)); // el valor del numero 2 se pone tambien en el numero 1\n        System.out.println(\"Suma y asignacion: \" + (num1 += num2)); // num1 = num1 + num2;\n        System.out.println(\"Resta y asignacion: \" + (num1 -= num2)); // num1 = num1 - num2;\n        System.out.println(\"Multiplicación y asignación: \" + (num1 *= num2)); // num1 = num1 * num2;\n        System.out.println(\"Division y asignación: \" + (num1 /= num2)); // num1 = num1 / num2;\n        System.out.println(\"Resto y asignación: \" + (num1 %= num2)); // num1 = num1 % num2;\n\n        System.out.println(\"AND y asignación: \" + (num1 &= num2)); // hace la operacion AND en binario de num1 y num2 y\n                                                                   // se lo asigna a num1\n        System.out.println(\"OR y asignación: \" + (num1 |= num2)); // hace la operacion OR en binario de num1 y num2 y se\n                                                                  // lo asigna a num1\n        System.out.println(\"XOR y asignación: \" + (num1 ^= num2)); // hace la operacion XOR en binario de num1 y num2 y\n                                                                   // se lo asigna a num1\n        System.out.println(\"Desplazamiento a la izquierda y asignación: \" + (num1 <<= num2)); // hace desplazamiento a\n                                                                                              // la izquierda en binario\n                                                                                              // de num1 y num2 y se lo\n                                                                                              // asigna a num1\n        System.out.println(\"Desplazamiento a la derecha y asignación aritmetico: \" + (num1 >>= num2)); // hace\n                                                                                                       // desplazamiento\n                                                                                                       // a la derecha\n                                                                                                       // manteniendo\n                                                                                                       // signo en\n                                                                                                       // binario de\n                                                                                                       // num1 y num2 y\n                                                                                                       // se lo asigna a\n                                                                                                       // num1\n        System.out.println(\"Desplazamiento a la derecha logico: \" + (num1 >>>= num2)); // hace desplazamiento a la\n                                                                                       // derecha en binario de num1 y\n                                                                                       // num2 y se lo asigna a num1\n\n        // Operaciones BIT a BIT\n        int a = 2; // En binario: 0010\n        int b = 4; // En binario: 0100\n        /*\n         * AND: Si coinciden dos 1 retorna 1, si no retorna 0.\n         \n          0010 (2 en binario)\n          &\n          0100 (4 en binario)\n          ------\n          0000 (0 en decimal)\n          \n         * OR: Almenos 1 debe ser un 1 para retornar un 1.\n          \n          0010 (2 en binario)\n          |\n          0100 (4 en binario)\n          ------\n          0110 (6 en decimal)\n          \n         * XOR: compara y si son diferentes retorna 1.\n          0010 (2 en binario)\n          ^\n          0100 (4 en binario)\n          ------\n          0110 (6 en decimal)\n          \n         * NOT:\n          1. Invierte todos los bits del número. 1 se convierte en 0 y cada 0 se\n          convierte en 1.\n          (numero 2)\n          ~0000 0010\n          ----------\n          1111 1101\n          \n          2. Invertimos los bits del resultado (1111 1101) para obtener el complemento\n          a uno\n          y le sumamos 1:\n          0000 0010\n          +\n          ----------\n          0000 0011 (3 en decimal)\n         \n          3.Aplicamos el signo negativo\n          -3\n          \n         * AHORA CON EL NUMERO 4\n          1. Invierte todos los bits del número. 1 se convierte en 0 y cada 0 se\n          convierte en 1.\n          (numero 4)\n          \n          ~0000 0100\n          ----------\n          1111 1011\n          \n          2. Invertimos los bits del resultado (1111 1101) para obtener el complemento\n          a uno\n          y le sumamos 1:\n          \n          0000 0100\n          + 1\n          ----------\n          0000 0101\n          \n          3.Aplicamos el signo negativo\n          -5\n          \n          \n         * DESPLAZAMIENTO A LA IZQUIERDA (<<):\n          Los bits se desplazan dos posiciones a la izquierda, y se rellenan con ceros\n          a la derecha.\n          00000101 (5 en binario)\n          << 2\n          -----------\n          00010100 (20 en decimal)\n          \n          \n         * DESPLAZAMIENTO A LA DERECHA ARITMETICO (>>)\n          Los bits se desplazan dos posiciones a la derecha, y se rellena con ceros a\n          la izquierda.\n          Mantiene el signo.\n          \n          00010100 (20 en binario)\n          >> 2\n          -----------\n          00000101 (5 en decimal)\n          \n          \n         * DESPLAZAMIENTO A LA DERECHA LOGICO (>>>)\n          los bits se desplazan dos posiciones a la derecha, y se rellena con ceros a\n          la izquierda.\n          Siempre inserta 0.\n          \n          11110100 (-12 en binario en complemento a dos)\n          >>> 2\n          -----------\n          00111101 (1073741813 en decimal, para un entero de 32 bits)\n          \n         */\n\n        System.out.println(\"2 & 4 = \" + (a & b)); // AND Bit a Bit\n        System.out.println(\"2 | 4 = \" + (a | b)); // OR Bit a Bit\n        System.out.println(\"2 ^ 4 = \" + (a ^ b)); // XOR Bit a Bit\n        System.out.println(\"~2 = \" + (~a)); // NOT Bit a Bit\n        System.out.println(\"2 << 2 = \" + (a << 2)); // Desplazamiento a la Izquierda\n        System.out.println(\"4 >> 2 = \" + (b >> 2)); // Desplazamiento a la Derecha Aritmético\n        System.out.println(\"4 >>> 2 = \" + (b >>> 2)); // Desplazamiento a la Derecha Lógico\n\n\n        // Estructuras de control\n        System.out.println(\"Ternarios: \");\n        int edad = 18;\n        String comprobacion = edad >= 18 ? \"Es mayor de edad \" : \"NO es mayor de edad\";\n        System.out.println(comprobacion);\n\n        System.out.println(\"IF ELSE, SWITCH\");\n        System.out.println(\"ejemplo IF ELSE\");\n        if (edad >= 18) {\n            System.out.println(\"es mayor de edad\");\n        } else if (edad >= 99) {\n            System.out.println(\"esta persona problablemente este muerta\");\n        } else {\n            System.out.println(\"es menor de edad\");\n        }\n\n\n        System.out.println(\"Ejemplo switch\");\n        switch (num1) {\n            case 1:\n                System.out.println(\"num1 es un 1\");\n                break;\n            case 2:\n                System.out.println(\"num1 es un 2\");\n                break;\n\n            default:\n                System.out.println(\"el num1 no es 1 ni es 2 es otro numero\");\n        }\n\n\n    \n        System.out.println(\"Bucles\");\n        System.out.println(\"For\"); /* Bucle que se repite x numero de veces */\n        for (int i = 0; i < 10; i++) { // se va a repetir 10 veces desde 0-9 incrementandose\n            System.out.println(\"i = \" + i);\n        }\n\n        System.out.println(\"While\"); /* Bucle que se repite hasta se cumpla la condicion */\n        int contador = 0;\n        while (contador < 10) { // se va a ejecutar mietras contador sea menor que 10\n            System.out.println(\"i = \" + contador);\n            contador++; // al poner que el contador se incremente en cada interaccion el valor de\n                        // contador ira cambiando y cuando llegue a 10 se rompera el bucle\n        }\n\n        System.out.println(\" do while\"); // Haz esto(do) hasta que(while)\n        do {\n            System.out.println(\"i = \" + contador); /* incrementa la varibale en cada vuelta */\n            contador++;\n        } while (contador < 2); /* cuando llega al 2 se para */\n\n        System.out.println(\"Break y continue se usan en for, while y do-while\");\n        System.out.println(\"Break es para romper un bucle\");\n\n        int numero_indicado = 4;\n        for (int i = 0; i < 10; i++) {\n            if (i == numero_indicado) {\n                break; /*\n                        * Cuando llega al numero indicado el buqle\n                        * se rompe y no muestra la siguiente interaccion\n                        */\n            }\n            System.out.println(\"i = \" + i);\n        }\n\n        System.out.println(\"Continue es para continuar con la siguiente interaccion y dejar la actual\");\n        for (int i = 0; i < 10; i++) {\n            if (i == numero_indicado) {\n                continue; /*\n                           * Cuando llega al numero indicado el buqle se rompe\n                           * y continua con la siguiente interaccion\n                           */\n            }\n            System.out.println(\"i = \" + i);\n        }\n\n\n\n        System.out.println(\"Manejar excepciones try-catch\");\n        try {\n            resultado = num1 / 0; // 0/0\n            System.out.println(\"Resultado: \" + resultado);\n        } catch (ArithmeticException e) {\n            System.out.println(\"Error: Division por cero\");\n        }\n\n\n\n        // ejercicio extra\n        for (int i = 10; i < 55; i++) {\n            // si es par\n            if (i % 2 == 0) {\n                // y no es 16 ni multiplo de 3\n                if (i != 16 && i % 3 != 0) {\n                    System.out.println(i);\n                }\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/AndrewCodev.java",
    "content": "public class AndrewCodev {\n    public static void main(String args[]) {\n\n\t\tint num1 = 100;\n\t\tint num2 = 5;\n\n\t\tSystem.out.println(\"OPERADORES ARITMETICOS\");\n\t\tint suma = num1 + num2;\n\t\tSystem.out.println(\"(+): \" + num1 + \" + \" + num2 + \" = \" + suma);\n\n\t\tint resta = num1 - num2;\n\t\t;\n\t\tSystem.out.println(\"(-): \" + num1 + \" - \" + num2 + \" = \" + resta);\n\n\t\tint multip = num1 * num2;\n\t\tSystem.out.println(\"(*): \" + num1 + \" * \" + num2 + \" = \" + multip);\n\t\tint division = num1 / num2;\n\t\tSystem.out.println(\"(/): \" + num1 + \" / \" + num2 + \" = \" + division);\n\n\t\tint resto = num1 % 2;\n\n\t\tif (resto == 0) {\n\t\t\tSystem.out.println(\"(%) El numero: \" + num1 + \" es par\");\n\t\t} else {\n\t\t\tSystem.out.println(\"(%) El número: \" + num1 + \" es impar\");\n\t\t}\n\n\t\tSystem.out.println(\"\\nOPERADORES DE COMPARACION\");\n\t\tboolean esIgual = (num1 == num2); // Igual a\n\t\tboolean esMayor = (num1 > num2); // Mayor que\n\t\tboolean esMenorIgual = (num1 <= num1); // Menor o igual que\n\n\t\tif (esIgual) {\n\t\t\tSystem.out.println(\"(==) Los numeros: \" + num1 + \" y \" + num2 + \" Son iguales\");\n\t\t} else {\n\t\t\tSystem.out.println(\"(!=) Los numeros: \" + num1 + \" y \" + num2 + \" Son diferentes\");\n\t\t}\n\n\t\tif (esMayor) {\n\t\t\tSystem.out.println(\"(>): \" + num1 + \" > \" + num2 + \" Es mayor\");\n\t\t} else if (esMenorIgual) {\n\t\t\tSystem.out.println(\"(<=): \" + num1 + \" <= \" + num2 + \" es menor o igual\");\n\t\t}\n\n\t\tSystem.out.println(\"\\nOPERADORES DE ASIGNACION\");\n\t\tint edad = 25; // Operador de asignación simple\n\t\tSystem.out.println(\"Asignación simple: int edad = \" + edad + \";\");\n\t\tedad += 5; // Operador de asignación compuesta (edad = edad + 5)\n\t\tSystem.out.println(\"Asignación compusta: int edad += 5; (edad = edad + 5) = \" + edad);\n\n\t\tSystem.out.println(\"\\nOPERADORES DE LOGICOS\");\n\t\tboolean resultadoAnd = (true && false); // Operador AND\n\t\tSystem.out.println(\"AND (&&): resultadoAnd = (true && false); - \" + resultadoAnd);\n\t\tboolean resultadoOr = (true || false); // Operador OR\n\t\tSystem.out.println(\"OR (||): resultadoOr = (true || false); - \" + resultadoOr);\n\t\tboolean resultadoNot = !true; // Operador NOT\n\t\tSystem.out.println(\"NOT (!): resultadoNot = !true; - \" + resultadoNot);\n\n\t\tSystem.out.println(\"\\nOPERADORES DE INCREMENTO Y DECREMENTO\");\n\t\tint contador = 0;\n\t\tSystem.out.println(\"int contador= \" + contador);\n\t\tcontador++; // Operador de incremento (equivale a contador = contador + 1)\n\t\tSystem.out.println(\"INCREMENTO (++): contador++ = \" + contador);\n\t\tcontador--; // Operador de decremento (equivale a contador = contador - 1)\n\t\tSystem.out.println(\"DECREMENTO (--): contador-- = \" + contador);\n\n\t\t// DIFICULTAD EXTRA\n        System.out.println(\"\\nEste código imprimirá todos los números pares entre 10 y 55 (incluidos), que no sean 16 y no sean múltiplos de 3\");\n\t\tfor (int i = 10; i <= 55; i++) {\n\t\t\tif(i % 2 == 0 && i != 16 && i % 3 != 0 ) {\n\t\t\t\tSystem.out.println(i);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/AngelOro.java",
    "content": "public class AngelOro {\n\n    public static void cicloFor(){\n        System.out.println(\"Números par del 0 al 300\");\n        for (int i = 0; i <= 300; i+=2){\n            System.out.println(i);\n        }\n    }\n\n    public static void cicloWhile(int a){\n        System.out.println(\"Ciclo while\");\n        while (a > 0){\n            System.out.println(a);\n            a--;\n        }\n    }\n\n    public static void main(String[] args) {\n        /*\n         * Operadores aritméticos\n         */\n        int num1 = 20;\n        int num2 = 9;\n\n        System.out.println(\"Operadores aritméticos\");\n        //Suma\n        int resultado = num1 + num2;\n        System.out.println(num1 + \" + \" + num2 + \" = \" + resultado );\n\n        //Resta\n        resultado = num1 - num2;\n        System.out.println(num1 + \" - \" + num2 + \" = \" + resultado);\n\n        //Multiplicación\n        resultado = num1 * num2;\n        System.out.println(num1 + \" * \" + num2 + \" = \" + resultado);\n\n        //División\n        resultado = num1 / num2;\n        System.out.println(num1 + \" / \" + num2 + \" = \" + resultado);\n\n        //Residuo\n        resultado = num1 % num2;\n        System.out.println(num1 + \" % \" + num2 + \" = \" + resultado);\n\n        /*\n         *Operadores combinados\n         */\n\n\n        System.out.println(\"Operadores combinados\");\n        //num1 = num1 + num2\n        num1+=num2;\n        System.out.println(num1);\n\n        //num1 = num1 - num2\n        num1-=num2;\n        System.out.println(num1);\n\n        //num1 = num1 * num2\n        num1*=num2;\n        System.out.println(num1);\n\n        //num1 = num1 / num2\n        num1/=num2;\n        System.out.println(num1);\n\n        //num1 = num1 % num2\n        num1%=num2;\n        System.out.println(num1);\n\n        /*\n         * Operadores de relación\n         */\n\n        System.out.println(\"Operadores de relación\");\n        //Igual que\n        boolean relacion = num1 == num2;\n        System.out.println(num1+\" == \"+num2+\" = \"+relacion);\n\n        //Distinto que\n        relacion = num1 != num2;\n        System.out.println(num1+\" != \"+num2+\" = \"+relacion);\n\n        //Menor que\n        relacion = num1 < num2;\n        System.out.println(num1+\" < \"+num2+\" = \"+relacion);\n\n        //Mayor que\n        relacion = num1 > num2;\n        System.out.println(num1+\" > \"+num2+\" = \"+relacion);\n\n        //Menor o Igual que\n        relacion = num1 <= num2;\n        System.out.println(num1+\" <= \"+num2+\" = \"+relacion);\n\n        //Mayor o Igual que\n        relacion = num1 >= num2;\n        System.out.println(num1+\" >= \"+num2+\" = \"+relacion);\n\n        /*\n         * Operadore lógicos\n         */\n\n        System.out.println(\"Operadores lógicos\");\n        //Negación NOT\n        relacion = !(num1 == num2);\n        System.out.println(\"!(\"+num1+\" == \"+num2+\") = \"+relacion);\n\n        //OR\n        relacion = (num1 < num2) | (num1 == num2);\n        System.out.println(\"(\"+num1+\" < \"+num2+\") | ( \"+num1+\" == \"+num2+\") = \"+relacion);\n\n        //XOR\n        relacion = (num1 > num2) ^ (num1 == num2);\n        System.out.println(\"(\"+num1+\" > \"+num2+\") ^ ( \"+num1+\" == \"+num2+\") = \"+relacion);\n\n        //AND\n        relacion = (num1 < num2) & (num1 != num2);\n        System.out.println(\"(\"+num1+\" < \"+num2+\") & ( \"+num1+\" != \"+num2+\") = \"+relacion);\n\n        //||\n        relacion = (num1 <= num2) || (num1 == num2);\n        System.out.println(\"(\"+num1+\" <= \"+num2+\") || ( \"+num1+\" == \"+num2+\") = \"+relacion);\n\n        //&&\n        relacion = (num1 <= num2) && (num1 == num2);\n        System.out.println(\"(\"+num1+\" <= \"+num2+\") && ( \"+num1+\" == \"+num2+\") = \"+relacion);\n\n        /*\n         * Operadores de bit\n         */\n\n        System.out.println(\"Operadores bit\");\n        num1 = 14;\n        num2 = 18;\n        //~ : Negación\n        System.out.println(\"~\"+num1 + \" = \" + ~num1 );\n\n        //| : Suma lógica binaria\n        System.out.println(num1 + \" | \" + num2 +\" = \" + (num1|num2) );\n\n        //^ : Suma lógica exclusiva\n        System.out.println(num1 + \" ^ \" + num2 +\" = \" + (num1^num2) );\n\n        //& : Producto lógico binario\n        System.out.println(num1 + \" & \" + num2 +\" = \" + (num1&num2) );\n\n        //<<:\n        System.out.println(num1 + \" << \" + num2 +\" = \" + (num1<<num2) );\n\n        //>>:\n        System.out.println(num1 + \" >> \" + num2 +\" = \" + (num1>>num2) );\n\n        //Ciclos\n        cicloFor();\n        cicloWhile(10);\n\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/AngelSanchezT.java",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n/*\n    Como ejecutar la siguiente clase de Java: \n    1. Instalación el JDK.\n\n    2. Validar que este instalado con el comando: java -version\n\n    3. Posicionar la terminal en la carpeta: \n    cd C:\\DESARROLLO\\git\\roadmap-retos-programacion\\Roadmap\\00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\\java\n\n    4. Compilación de la clase Java, el proceso genera un archivo AngelSanchezT.class\n        javac AngelSanchezT.java\n\n    5. Ejecución de la clase Java: (Ejecución del archivo sin la extensión .class)\n        java AngelSanchezT\n */\n\npublic class AngelSanchezT {\n    public static void main(String[] args) {\n        // Ejemplos de operadores\n        // Aritméticos\n        int suma = 5 + 3;\n        int resta = 10 - 4;\n        int multiplicacion = 6 * 2;\n        int division = 8 / 4;\n        int modulo = 10 % 3;\n\n        // Lógicos\n        boolean and = true && false;\n        boolean or = true || false;\n        boolean not = !true;\n\n        // De comparación\n        boolean igual = (5 == 5);\n        boolean noIgual = (4 != 7);\n        boolean mayorQue = (10 > 5);\n        boolean menorQue = (3 < 9);\n\n        // De asignación\n        int x = 10;\n        x += 5; // Equivalente a x = x + 5;\n\n        // De identidad\n        String cadena1 = \"Hola\";\n        String cadena2 = new String(\"Hola\");\n        boolean mismaReferencia = (cadena1 == cadena2);\n\n        // De pertenencia\n        int[] arreglo = {1, 2, 3, 4, 5};\n        boolean contiene = contieneNumero(arreglo, 3);\n\n        // De bits\n        int a = 5;\n        int b = 3;\n        int resultadoAnd = a & b;\n        int resultadoOr = a | b;\n        int resultadoXor = a ^ b;\n        int resultadoDesplazamiento = a << 1;\n\n        System.out.println(\"Ejemplos de operadores:\");\n        System.out.println(\"Suma: \" + suma);\n        System.out.println(\"Resta: \" + resta);\n        System.out.println(\"Multiplicación: \" + multiplicacion);\n        System.out.println(\"División: \" + division);\n        System.out.println(\"Módulo: \" + modulo);\n        System.out.println(\"AND lógico: \" + and);\n        System.out.println(\"OR lógico: \" + or);\n        System.out.println(\"NOT lógico: \" + not);\n        System.out.println(\"Igual: \" + igual);\n        System.out.println(\"No igual: \" + noIgual);\n        System.out.println(\"Mayor que: \" + mayorQue);\n        System.out.println(\"Menor que: \" + menorQue);\n        System.out.println(\"De asignación (x += 5): \" + x);\n        System.out.println(\"De identidad: \" + mismaReferencia);\n        System.out.println(\"De pertenencia: Contiene 3 en el arreglo: \" + contiene);\n        System.out.println(\"De bits AND: \" + resultadoAnd);\n        System.out.println(\"De bits OR: \" + resultadoOr);\n        System.out.println(\"De bits XOR: \" + resultadoXor);\n        System.out.println(\"Desplazamiento a la izquierda: \" + resultadoDesplazamiento);\n\n        // Estructuras de control\n        System.out.println(\"\\nEjemplos de estructuras de control:\");\n\n        // Condicionales\n        int numero = 30;\n        if (numero > 20) {\n            System.out.println(\"El número es mayor que 20.\");\n        } else if (numero == 20) {\n            System.out.println(\"El número es igual a 20.\");\n        } else {\n            System.out.println(\"El número es menor que 20.\");\n        }\n\n        // Iterativas\n        System.out.println(\"\\nNúmeros entre 10 y 55 (pares, no 16 ni múltiplos de 3):\");\n        for (int i = 10; i <= 55; i++) {\n            if (i % 2 == 0 && i != 16 && i % 3 != 0) {\n                System.out.print(i + \" \");\n            }\n        }\n\n        // Excepciones (simulación de una división por cero)\n        try {\n            int resultadoDivisionCero = 10 / 0;\n        } catch (ArithmeticException e) {\n            System.out.println(\"\\nExcepción atrapada: \" + e.getMessage());\n        }\n    }\n\n    // Método auxiliar para verificar si un número está en un arreglo\n    private static boolean contieneNumero(int[] arreglo, int numero) {\n        for (int elemento : arreglo) {\n            if (elemento == numero) {\n                return true;\n            }\n        }\n        return false;\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/AriasLopez.java",
    "content": "public class AriasLopez01 {\n\n    /**\n     * @param args\n     */\n    public static void main(String[] args) {\n\n\n        /*\n         * OPERADORES ARITMETICOS\n         */\n        System.out.println(\"Esta es una suma, 5 + 2 = \" + (5 + 2));\n        System.out.println(\"Esta es una resta, 5 - 2 = \" + (5 - 2));\n        System.out.println(\"Esta es una multiplicacion, 5 * 2 = \" + (5 * 2));\n        System.out.println(\"Esta es una division, 5 / 2 = \" + (5 / 2));\n        System.out.println(\"Esto es un modulo, 5 % 2 = \" + (5 % 2));\n        \n        // OPERADORES RELACIONALES\n\n        System.out.println(\"5 IGUAL 10 = \" + (5 == 10));\n        System.out.println(\"5 DESIGUALDAD 10 = \" + (5 != 10));\n        System.out.println(\"5 MENOR QUE 10 = \" + (5 < 10));\n        System.out.println(\"5 MAYOR QUE 10 = \" + (5 > 10));\n        System.out.println(\"5 MAYOR O IGUAL QUE 10 = \" + (5 >= 10));\n        System.out.println(\"5 MENOR O IGUAL QUE 10 = \" + (5 <= 10));\n        System.out.println(\"10 MAYOR O IGUAL QUE 10 = \" + (10 >= 10));\n\n        // OPERADORES LOGICOS\n\n        System.out.println(\"&& AND: 3 < 8 AND 5 < 7 (\" + ((3 < 8) && (5 < 7)) + \")\");\n        System.out.println(\"&& AND: 3 <= 3 AND 5 == 7 (\" + (3 <= 3  && 5 == 7) + \")\");\n        System.out.println(\"|| OR: 3 + 3 = 8 || 2 < 4 (\" + (3 + 3 == 8 || 2 < 4) + \")\");\n        System.out.println(\"|| OR: 3 + 3 = 8 || 2 > 7 (\" + (3 + 3 == 8 || 2 > 7) + \")\");\n        System.out.println(\"! NOT: 3 + 7 = 8 (\" + !(3 + 7 == 8 ) + \")\");\n        System.out.println(\"! NOT: 3 < 8 (\" + !(3 < 8 ) + \")\");\n\n\n        // OPERADORES DE ASIGNACION\n\n        int numero1 = 10;\n        System.out.println(numero1);\n\n        numero1 += 2;\n        System.out.println(numero1);\n\n        numero1 -= 1;\n        System.out.println(numero1);\n\n        numero1 *= 10;\n        System.out.println(numero1);\n        \n        numero1 %= 8;\n        System.out.println(numero1);\n        \n        numero1 /= 2;\n        System.out.println(numero1);\n\n        numero1 ^= 10;\n        System.out.println(numero1);\n\n\n        /* \n         * ESTRUCTURAS DE CONTROL\n         */\n          \n         int edad = 6;\n\n        if (edad >= 18 ) {\n            System.out.println(\"Es mayor de edad, puede viajar solo.\");\n        } else if (edad <=5) {\n            System.out.println(\"Aun es un bebe, debe ir acompañado y no paga el pasaje.\");  \n        } else {\n            System.out.println(\"El pasajero debe ir acompañado.\");\n        }\n\n\n\n        for (int i = 0; i <= 18; i++){\n            System.out.println(i);   \n        }\n\n        \n        for (int i = 0; i <= 56; i++){\n            if (i %2 == 0 && i != 16 && i %3 == 0 ) {\n                System.out.println(i);\n            } \n        }\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/B3nkos.java",
    "content": "public class B3nkos {\n    public static void main(String[] args) {\n        // assignment operators\n        int numberOne = 2;\n        int numberTwo = 6;\n        int numberThree = 9;\n\n        System.out.printf(\"numberOne = %d\\n\", numberOne);\n        System.out.printf(\"numberTwo = %d\\n\", numberTwo);\n        System.out.printf(\"numberThree = %d\\n\", numberThree);\n\n        System.out.println();\n\n        // arithmetic operator\n        System.out.printf(\"numberOne + numberTwo = %d\\n\", numberOne + numberTwo);\n        System.out.printf(\"numberThree - numberOne = %d\\n\", numberThree - numberOne);\n        System.out.printf(\"numberOne * numberThree = %d\\n\", numberOne * numberThree);\n        System.out.printf(\"numberThree / numberOne = %d\\n\", numberThree / numberOne);\n        System.out.printf(\"numberThree %% numberOne = %d\\n\", numberThree % numberOne);\n        numberOne++;\n        numberThree--;\n        System.out.printf(\"numberOne++ = %d\\n\", numberOne);\n        System.out.printf(\"numberThree-- = %d\\n\", numberThree);\n        System.out.printf(\"numberThree+=3 = %d\\n\", numberThree+=3);\n\n        System.out.println();\n\n        // comparison operators\n        System.out.printf(\"numberThree > numberOne = %b\\n\", numberThree > numberOne);\n        System.out.printf(\"numberThree <= numberOne = %b\\n\", numberThree <= numberOne);\n        System.out.printf(\"numberThree >= numberOne = %b\\n\", numberThree >= numberOne);\n\n        System.out.println();\n\n        // logic operators\n        System.out.printf(\"true and false = %b\\n\", true && false);\n        System.out.printf(\"true and true = %b\\n\", true && true);\n        System.out.printf(\"true or false = %b\\n\", true || false);\n        System.out.printf(\"false or true = %b\\n\", false || true);\n        System.out.printf(\"!true = %b\\n\", !true);\n        System.out.printf(\"!false = %b\\n\", !false);\n        System.out.printf(\"true is equals to true = %b\\n\", true == true);\n\n        System.out.println();\n\n        // bits operators\n        System.out.printf(\"numberThree >> 2 = %d\\n\", numberThree >> 2);\n        System.out.printf(\"numberOne << 1 = %d\\n\", numberOne << 1);\n\n        System.out.println();\n\n        // if control structure\n\n        if (numberThree > numberOne) {\n            System.out.printf(\"%d is greater than %d\\n\", numberThree, numberOne);\n        }\n\n        // switch control structure\n        String animal = \"Lion\";\n        switch (animal) {\n            case \"Dog\" -> System.out.println(\"The animal is a Dog\");\n            case \"Lion\" -> System.out.println(\"The animal is a Lion\");\n            case \"Cat\" -> System.out.println(\"The animal is a Cat\");\n            default -> System.out.println(\"Number not found\");\n        }\n\n        // while loop\n        int c = 1;\n        while (c <= 5) {\n            System.out.printf(\"While Loop iteration number #%d\\n\", c);\n            c++;\n        }\n\n        System.out.println();\n\n        int k = 0;\n        do {\n            k++;\n            System.out.printf(\"Do-While loop iteration #%d\\n\", k);\n        } while (k < 5);\n\n        System.out.println();\n\n        // for loop\n        for (int i = 1; i <= 5; i++) {\n            System.out.printf(\"For Loop iteration number #%d\\n\", i);\n        }\n\n        System.out.println();\n\n        // EXTRA\n        for (int i = 10; i <= 55; i++) {\n            if (i == 16 || i % 3 == 0 || i % 2 != 0) {\n                continue;\n            }\n\n            System.out.println(i);\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/BertoMP.java",
    "content": "public class BertoMP {\n    public static void main(String[] args) {\n        // OPERADORES ARITMÉTICOS\n        System.out.println(\"OPERADORES ARITMÉTICOS\");\n        int firstNumber = 7;\n        int secondNumber = 2;\n        int result;\n\n        // Operador suma (+)\n        result = firstNumber + secondNumber;\n        System.out.println(\"El resultado de sumar \" + firstNumber + \" y \" + secondNumber + \" es: \" + result);\n\n        // Operador resta (-)\n        result = firstNumber - secondNumber;\n        System.out.println(\"El resultado de restar \" + firstNumber + \" y \" + secondNumber + \" es: \" + result);\n\n        // Operador multiplicación (*)\n        result = firstNumber * secondNumber;\n        System.out.println(\"El resultado de multiplicar \" + firstNumber + \" y \" + secondNumber + \" es: \" + result);\n\n        // Operador división (/)\n        result = firstNumber / secondNumber;\n        System.out.println(\"El resultado de dividir \" + firstNumber + \" y \" + secondNumber + \" es: \" + result);\n\n        // Operador módulo (%)\n        result = firstNumber % secondNumber;\n        System.out.println(\"El resto de la división entre \" + firstNumber + \" y \" + secondNumber + \" es: \" + result);\n\n        // OPERADORES LÓGICOS\n        System.out.println(\"\\nOPERADORES LÓGICOS\");\n        boolean firstBool = true;\n        boolean secondBool = false;\n\n        // Operador lógico AND (&&)\n        boolean logicAnd = firstBool && secondBool;\n        System.out.println(\"AND lógico: \" + logicAnd); // Imprime false.\n\n        // Operador lógico OR (||)\n        boolean logicOr = firstBool || secondBool;\n        System.out.println(\"OR lógico: \" + logicOr); // Imprime true.\n\n        // Operador lógico NOT (!)\n        boolean logicNot = !firstBool;\n        System.out.println(\"NOT lógico: \" + logicNot); // Imprime false.\n\n        // OPERADORES DE COMPARACIÓN\n        System.out.println(\"\\nOPERADORES DE COMPARACIÓN\");\n        // Operador de igualdad (==)\n        boolean equal = (firstNumber == secondNumber);\n        System.out.println(\"¿Es igual el número \" + firstNumber + \" y el número \" + secondNumber + \"? -> \" + equal);\n\n        // Operador de diferencia (!=)\n        boolean diff = (firstNumber != secondNumber);\n        System.out.println(\"¿Es distinto el número \" + firstNumber + \" del número \" + secondNumber + \"? ->\" + diff);\n\n        // Operador de mayor que (>)\n        boolean greaterThan = (firstNumber > secondNumber);\n        System.out.println(\"¿Es \" + firstNumber + \" mayor que \" + secondNumber + \"? -> \" + greaterThan);\n\n        // Operador de menor que (<)\n        boolean lessThan = (firstNumber < secondNumber);\n        System.out.println(\"¿Es \" + firstNumber + \" menor que \" + secondNumber + \"? -> \" + lessThan);\n\n        // Operador de mayor o igual que (>=)\n        boolean greaterOrEqual = (firstNumber >= secondNumber);\n        System.out.println(\"¿Es \" + firstNumber + \" mayor o igual que \" + secondNumber + \"? -> \" + greaterOrEqual);\n\n        // Operador de menor o igual que (<=)\n        boolean lessOrEqual = (firstNumber <= secondNumber);\n        System.out.println(\"¿Es \" + firstNumber + \" menor o igual que \" + secondNumber + \"? -> \" + lessOrEqual);\n\n        // OPERADORES DE ASIGNACIÓN\n        System.out.println(\"\\nOPERADORES DE ASIGNACIÓN\");\n        int number = 10;\n\n        // Operador de asignación simple (=): Asigna el valor a la variable.\n        int assignedValue = number;\n        System.out.println(\"Valor asignado: \" + assignedValue);\n\n        // Operador de asignación y suma (+=): Añade un valor a la variable existente.\n        number += 5; // Equivalente a: number = number + 5;\n        System.out.println(\"Después de +=: \" + number);\n\n        // Operador de asignación y resta (-=): Resta un valor de la variable existente.\n        number -= 3; // Equivalente a: number = number - 3;\n        System.out.println(\"Después de -=: \" + number);\n\n        // Operador de asignación y multiplicación (*=): Multiplica la variable existente por un valor.\n        number *= 2; // Equivalente a: number = number * 2;\n        System.out.println(\"Después de *=: \" + number);\n\n        // Operador de asignación y división (/=): Divide la variable existente por un valor.\n        number /= 4; // Equivalente a: number = number / 4;\n        System.out.println(\"Después de /=: \" + number);\n\n        // Operador de asignación y módulo (%=): Obtiene el resto de la división de la variable existente por un valor.\n        number %= 4; // Equivalente a: number = number % 4;\n        System.out.println(\"Después de %=: \" + number);\n\n        // OPERADORES DE IDENTIDAD\n        System.out.println(\"\\nOPERADORES DE IDENTIDAD\");\n        String firstString = \"Hola\"; // Crea una cadena en la memoria de Java\n        String secondString = \"Hola\"; // Utiliza la misma cadena que 'str1' (mismo objeto en la memoria)\n        String thirdString = new String(\"Hola\"); // Crea una nueva cadena (objeto distinto en la memoria)\n\n        // Operador de identidad (==): Compara si dos referencias apuntan al mismo objeto en la memoria.\n        boolean sameObject = (firstString == secondString);\n\n        // Operador de identidad (!=): Compara si dos referencias no apuntan al mismo objeto en la memoria.\n        boolean differentObjects = (firstString != thirdString);\n        System.out.println(\"¿El primero y el tercer strings no apuntan al mismo objeto? -> \" + differentObjects);\n\n        // OPERADORES PERTENENCIA\n        System.out.println(\"\\nOPERADORES DE PERTENENCIA\");\n        boolean instanceOfString = firstString instanceof String;\n        System.out.println(\"¿Es la variable firstString una instancia de la clase String? -> \" + instanceOfString);\n\n        // OPERADORES BITS\n        System.out.println(\"\\nOPERADORES DE BITS\");\n        int firstBit = 5; // Representación binaria: 0000 0101\n        int secondBit = 3; // Representación binaria: 0000 0011\n\n        // Operador AND a nivel de bits (&)\n        int resultadoAND = firstBit & secondBit;\n        System.out.println(\"Resultado AND: \" + resultadoAND);\n        // Imprime: Resultado AND: 1 (representación binaria: 0000 0001)\n\n        // Operador OR a nivel de bits (|)\n        int resultadoOR = firstBit | secondBit;\n        System.out.println(\"Resultado OR: \" + resultadoOR);\n        // Imprime: Resultado OR: 7 (representación binaria: 0000 0111)\n\n        // Operador XOR a nivel de bits (^)\n        int resultadoXOR = firstBit ^ secondBit;\n        System.out.println(\"Resultado XOR: \" + resultadoXOR);\n        // Imprime: Resultado XOR: 6 (representación binaria: 0000 0110)\n\n        // Operador de desplazamiento a la derecha (>>)\n        int resultadoDesplazamientoDerecha = firstBit >> 1;\n        System.out.println(\"Resultado desplazamiento a la derecha: \" + resultadoDesplazamientoDerecha);\n        // Imprime: Resultado desplazamiento a la derecha: 2 (representación binaria: 0000 0010)\n\n        // Operador de desplazamiento a la izquierda (<<)\n        int resultadoDesplazamientoIzquierda = firstBit << 1;\n        System.out.println(\"Resultado desplazamiento a la izquierda: \" + resultadoDesplazamientoIzquierda);\n        // Imprime: Resultado desplazamiento a la izquierda: 10 (representación binaria: 0000 1010)\n\n        // ESTRUCTURAS DE CONTROL CONDICIONAL\n        System.out.println(\"\\nESTRUCTURAS DE CONTROL CONDICIONAL\");\n        // if-else\n        System.out.println(\"if-else\");\n        int num = 10;\n\n        if (num > 0) {\n            System.out.println(\"El número es positivo.\");\n        } else {\n            System.out.println(\"El número es cero o negativo.\");\n        }\n\n        // Operador ternario\n        System.out.println(\"\\nOperador ternario\");\n        System.out.println((num > 0) ? \"El número es positivo.\" : \"El número es cero o negativo.\");\n\n        // switch-case\n        System.out.println(\"\\nSwitch-Case\");\n        int opcion = 2;\n        String resultado;\n\n        switch (opcion) {\n            case 1 -> System.out.println(\"Opción 1\");\n            case 2 -> System.out.println(\"Opcion 2\");\n            default:\n                System.out.println(\"Opcion por defecto\");\n        }\n\n        // ESTRUCTURAS DE CONTROL ITERATIVAS\n        System.out.println(\"\\nESTRUCTURAS DE CONTROL ITERATIVAS\");\n        // while\n        System.out.println(\"Bucle while\");\n        int contador = 0;\n        while (contador < 5) {\n            System.out.println(\"Iteración: \" + contador);\n            contador++;\n        }\n\n        // do-while\n        System.out.println(\"\\nBucle do-while\");\n        contador = 0;\n        do {\n            System.out.println(\"Iteración: \" + contador);\n            contador++;\n        } while (contador < 5);\n\n        // for\n        System.out.println(\"\\nBucle for\");\n        for (int i = 0; i < 5; i++) {\n            System.out.println(\"Iteración: \" + i);\n        }\n\n        // for-each\n        System.out.println(\"\\nBucle for-each\");\n        int[] arrayInt = {1, 2, 3, 4};\n        for (int numberInArray : arrayInt) {\n            System.out.println(\"Número: \" + numberInArray);\n        }\n\n        // MANEJO DE EXCEPCIONES\n        System.out.println(\"\\nMANEJO DE EXCEPCIONES\");\n        try {\n            int valor = arrayInt[10];\n        } catch (ArrayIndexOutOfBoundsException e) {\n            System.out.println(\"¡Error! Índice fuera del rango del arreglo.\");\n        } finally {\n            System.out.println(\"Bloque finally siempre se ejecuta.\");\n        }\n\n        // DIFICULTAD EXTRA\n        System.out.println(\"\\nEJERCICIO EXTRA\");\n        /*  Crea un programa que imprima por consola todos los números comprendidos entre 10 y 55 (incluidos), pares, y\n         *  que no son ni el 16 ni múltiplos de 3.*/\n        for (int i = 10; i <= 55; i++) {\n            if ((i % 2 == 0) && (i != 16) && (i % 3 != 0)) {\n                System.out.println(\"Iteración: \" + i);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/BlasBarragan.java",
    "content": "/**\n *  * EJERCICIO #01 - OPERADORES Y ESTRUCTURAS DE CONTROL\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * @version v1\n * \n * @since 07/01/2024\n * \n * @author Blas Barragán\n * \n */\npublic class BlasBarragan {\n    public static void main(String[] args) {\n    // ### OPERADORES ###\n\n        // OPERADORES ARITMETICOS\n        int valorA = 10;\n        int valorB = 5;\n        \n        int suma = valorA + valorB;\n        int resta = valorA - valorB;\n        int multiplicacion = valorA * valorB;\n        int division = valorA / valorB;\n        int restoDeLaDivision = valorA % valorB;\n\n        System.out.println(\"<=Operadores Aritmeticos=>\\n\");\n        System.out.println(\"Suma: \" + suma);\n        System.out.println(\"Resta: \" + resta);\n        System.out.println(\"Multiplicación: \" + multiplicacion);\n        System.out.println(\"División: \" + division);\n        System.out.println(\"Resto de la división: \" + restoDeLaDivision);\n\n        // OPERADORES DE ASIGNACIÓN\n        System.out.println(\"\\n<=Operadores de Asignación=>\\n\"); // Realizan la operación antes de la asignación.\n        System.out.println(\"ValorA = \" + valorA + \" Asignación = 5\");\n        valorA += 5;\n        System.out.println(\"Suma: valorA = \" + valorA);   \n        System.out.println(\"ValorA = \" + valorA + \" Asignación = 5\");\n        valorA -= 5;\n        System.out.println(\"Resta: valorA = \" + valorA);  \n        System.out.println(\"ValorA = \" + valorA + \" Asignación = 5\");\n        valorA *= 5;\n        System.out.println(\"Multiplicación: valorA = \" + valorA);\n        System.out.println(\"ValorA = \" + valorA + \" Asignación = 5\");\n        valorA /= 5;\n        System.out.println(\"División: valorA = \" + valorA);\n        System.out.println(\"ValorA = \" + valorA + \" Asignación = 5\");\n        valorA %= 5;\n        System.out.println(\"Resto de la división: \" + valorA);\n\n        // OPERADORES RELACIONALES\n        System.out.println(\"\\n<=Operadores de Asignación=>\\n\"); // Responden true o false.\n        System.out.println(\"Es \" + valorA + \" Mayor que (>) \" + valorB + \" ? : \" + (valorA>valorB));\n        System.out.println(\"Es \" + valorA + \" Menor que (<) \" + valorB + \" ? : \" + (valorA<valorB));\n        System.out.println(\"Es \" + valorA + \" Igual a (==) \" + valorB + \" ? : \" + (valorA==valorB));\n        System.out.println(\"Es \" + valorA + \" Distinto de (!=) \" + valorB + \" ? : \" + (valorA!=valorB));\n        System.out.println(\"Es \" + valorA + \" Mayor o Igual que (>) \" + valorB + \" ? : \" + (valorA>=valorB));\n        System.out.println(\"Es \" + valorA + \" Menor o Igual que (>) \" + valorB + \" ? : \" + (valorA<=valorB));\n\n        // OPERADORES LÓGICOS\n        System.out.println(\"\\n<=Operadores Lógicos=>\\n\"); // Responden true o false.\n        boolean and = (valorA>valorB)&&(valorA<valorB);\n        boolean or = (valorA==valorB)||(valorA!=valorB);\n        boolean not = (!and);\n        System.out.println( valorA + \" es mayor que (>) \" + valorB + \" y (&&) \" + valorA + \" menor que (<) \" + valorB + \" ? : \" + and);\n        System.out.println( valorA + \" es igual a (==) \" + valorB + \" o (||) \"  + valorA + \" es distinto de (!=) \" + valorB + \" ? : \" + or);\n        System.out.println(\"Si negamos la operacion and (&&), el resultado es: \" + not);\n        \n        // OPERADORES DE CONCATENACIÓN\n        System.out.println(\"\\n<=Operadores Lógicos=>\\n\");\n        System.out.println(\"Para concatenar valores, siempre usamos el caracter '+' como hemos hecho en las sentencias anteriores.\");\n                \n        // OPERADORES INCREMENTALES\n        System.out.println(\"\\n<=Operadores Incrementales=>\\n\");\n        System.out.println(\"ValorA = \" + (valorA = 2));\n        valorA ++;\n        System.out.println(\"ValorA incrementado en 1 usando ++: \" + valorA);\n        valorA --;\n        System.out.println(\"ValorA decrementado en 1 usando --: \" + valorA);         \n\n        // OPERADOR CONDICIONAL\n        System.out.println(\"Este condicional, es la forma abreviada de la estructura \\\"if-else\\\"\");\n        valorA = 5;\n        String resultado = (valorA > 0) ? \"Positivo\" : \"Negativo\";\n        System.out.println(resultado); // Si la condicion (valorA>0) es cierta, se asigna el valor \"Positivo\" a la variable resultado.\n\n    // ### ESTRUCTURAS DE CONTROL ###\n        \n        // ESTRUCTURA SECUENCIAL\n            // Todas las sentencias de codigo en Java se ejecutan de forma secuencial, una después de otra en el orden en que están escritas.\n            valorA = 10;\n            System.out.println(\"valorA = 10\");\n            valorA = valorA + 3;\n            System.out.println(\"ValorA + 3 = \" + valorA);\n        \n        // ESTRUCTURAS DE SELECCIÓN\n            // Selección simple (if...)\n            if (valorA == 13){\n                System.out.println(\"valora vale 13 en la selección if simple\");\n            }\n            // Selección doble (if...else...)\n            if (valorA == 13){\n                System.out.println(\"Agarramela que me crece\");\n            }else {\n                System.out.println(\"valorA no es igual a 13\");\n            }\n            // Selección múltiple (if...else if...else...) Anidamos sentencias\n            if (valorA == 13){\n                System.out.println(\"valorA es igual a 13 en la selección multiple anidando if...else\");\n            }else if (valorA == 5){ \n                System.out.println(\"jejeje\");\n            }else {\n                System.out.println(\"valorA no es ni 13 ni 5\");\n            }\n            //Selección múltiple (switch) La usamos para seleccionar 1 entre multiples opciones\n            switch (valorA) { // Indicamos la variable que nos dará el valor de la opción a tratar\n                case 1: // Si valorA vale 1\n                    System.out.println(\"valorA vale 1\");\n                    break; // Sale del switch\n                case 2: // Si valorA vale 2\n                    System.out.println(\"valorA vale 2\");\n                    break;\n                case 3:\n                    System.out.println(\"valorA vale 3\"); \n                    break;\n                case 13:\n                    System.out.println(\"valorA vale 13 en el switch\");\n                    break;\n                default: // Opción por defecto (si el valor de valorA no coincide con ninguna opción(case))\n                    System.out.println(\"Error, opción no disponible\");\n                    break;\n            }\n\n        // ESTRUCTURAS DE REPETICIÓN\n            // Bucle while\n            while (valorA <= 13){ // ojo los bucles infinitos\n                System.out.println(\"valorA no vale 13 y lo voy a repetir hasta que lo sea\");\n                valorA ++;\n            }\n            // Bucle do-while\n            do {\n                System.out.println(\"Le sumo 1 a valorA si es menor que 25\");\n                valorA ++;\n                System.out.println(valorA);\n            }while (valorA < 25);\n            // Bucle For\n            for (int i = 0; i <= valorA; i++){\n                System.out.println(\"i vale \" + i + \" y se incrementa en 1 hasta igualar a valorA que vale \" + valorA);\n            }\n            // Bucle Foreach\n            String [] semana = {\"lunes\",\"martes\",\"miercoles\",\"jueves\",\"viernes\",\"sabado\",\"domingo\"};\n            for (String dia : semana){\n                System.out.println(dia);\n            }\n\n            //EXTRA\n\n            for (int i = 10; i<55; i++){\n                if ((i%2 == 0)&&(i==16)&&(i%3!=0)){\n                }\n                System.out.println(i);\n            }\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/Chakerr.java",
    "content": "/**\n * EJERCICIO: - Crea ejemplos utilizando todos los tipos de operadores de tu\n * lenguaje: Aritméticos, lógicos, de comparación, asignación, identidad,\n * pertenencia, bits... (Ten en cuenta que cada lenguaje puede poseer unos\n * diferentes) - Utilizando las operaciones con operadores que tú quieras, crea\n * ejemplos que representen todos los tipos de estructuras de control que\n * existan en tu lenguaje: Condicionales, iterativas, excepciones... - Debes\n * hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional): Crea un programa que imprima por consola todos\n * los números comprendidos entre 10 y 55 (incluidos), pares, y que no son ni el\n * 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo\n * nuevo.\n */\npublic class Chakerr {\n\n    public static void main(String[] args) {\n        //Operadores aritmeticos\n        int a = 5;\n        int b = 8;\n        //Suma\n        System.out.println(a + b);\n        //Resta\n        System.out.println(a - b);\n        //Multiplicación\n        System.out.println(a * b);\n        //Divicion\n        System.out.println(a / b);\n        //Módulo\n        System.out.println(a % b);\n\n        //Operadores Unarios\n        //Positivo\n        int c = 5;\n        System.out.println(+c);\n        //Negativo\n        System.out.println(-c);\n        //Incremento\n        c++;\n        System.out.println(c);\n        ++c;\n        System.out.println(c);\n        //Decremento\n        c--;\n        System.out.println(c);\n        --c;\n        System.out.println(c);\n\n        //Operadores Relacionales\n        //Igual a\n        if (5 == 5) {\n            System.out.println(\"5 si es igual a 5\");\n        }\n        //Diferente de\n        if (5 != 3) {\n            System.out.println(\"5 es diferente de 3\");\n        }\n        //Mayor que\n        if (5 > 3) {\n            System.out.println(\"5 es mayor que tres\");\n        }\n        //Menor que\n        if (5 < 10) {\n            System.out.println(\"5 es menor que tres\");\n        }\n        //Mayor o igual que\n        if (5 >= 5) {\n            System.out.println(\"5 es igual a 5\");\n        }\n        //Menor o igual que\n        if (3 <= 5) {\n            System.out.println(\"3 es menor a 5\");\n        }\n\n        //Operadores Logicos\n        //AND ( devuelve verdadero si ambos operandos son verdaderos)\n        if (true && false) {\n            System.out.println(\"verdadero\");\n        } else {\n            System.out.println(\"falso\");\n        }\n        //OR ( devuelve true si al menos uno de los operandos es verdadero)\n        if (true || false) {\n            System.out.println(\"verdadero\");\n        } else {\n            System.out.println(\"falso\");\n        }\n        //NOT (invierte el valor booleano)\n        if (!true) {\n            System.out.println(\"false\");\n        }\n\n        //Operadores de asignación\n        //Asignación simple\n        int d = 10;\n        System.out.println(d);\n        //Asignación con suma\n        d += 3;\n        System.out.println(d);\n        //Asignación con resta\n        d -= 2;\n        System.out.println(d);\n        //Asignación con multiplicación\n        d *= 2;\n        System.out.println(d);\n        //Asignación con division\n        d /= 2;\n        System.out.println(d);\n        //Asignación con módulo\n        d %= 2;\n    }\n\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/Clarancedev.java",
    "content": "/**\n * #01 OPERADORES Y ESTRUCTURAS DE CONTROL\n * @author clarancedev\n * @version 1.0\n * @date 2025-04-05\n */\n\npublic class Clarancedev {\n\n    public static void main(String[] args) {\n\n        //VARIABLES\n        double double1 = 7.0;\n        double double2 = 9.0;\n        double double3 = 13.0;\n        int int1 = 5;\n        int int2 = 10;\n        String str = \"Hola\";\n\n        //OPERADORES\n\n            //ARITMETICOS\n            System.out.println(\"Suma: \" + double1 + \" + \" + double2 + \" = \" + (double1 + double2));\n            System.out.println(\"Resta: \" + double1 + \" - \" + double2 + \" = \" + (double1 - double2));\n            System.out.println(\"Multiplicación: \" + double1 + \" * \" + double2 + \" = \" + (double1 * double2));\n            System.out.println(\"División: \" + double1 + \" / \" + double2 + \" = \" + (double1 / double2));\n            System.out.println(\"Módulo: \" + double1 + \" % \" + double2 + \" = \" + (double1 % double2));\n\n            //LÓGICOS\n            System.out.println(\"AND: \" + double1 + \" > \" + double2 + \" && \" + double1 + \" < \" + double3 + \" = \" + (double1 > double2 && double1 < double3));\n            System.out.println(\"OR: \" + double1 + \" > \" + double2 + \" || \" + double1 + \" < \" + double3 + \" = \" + (double1 > double2 || double1 < double3));\n            System.out.println(\"NOT: !\" + double1 + \" > \" + double2 + \" = \" + !(double1 > double2));\n\n            //DE COMPARACIÓN\n            System.out.println(\"Mayor que: \" + double1 + \" > \" + double2 + \" = \" + (double1 > double2));\n            System.out.println(\"Menor que: \" + double1 + \" < \" + double2 + \" = \" + (double1 < double2));\n            System.out.println(\"Mayor o igual que: \" + double1 + \" >= \" + double2 + \" = \" + (double1 >= double2));\n            System.out.println(\"Menor o igual que: \" + double1 + \" <= \" + double2 + \" = \" + (double1 <= double2));\n            System.out.println(\"Igual a: \" + double1 + \" == \" + double2 + \" = \" + (double1 == double2));\n            System.out.println(\"Diferente de: \" + double1 + \" != \" + double2 + \" = \" + (double1 != double2));\n\n            //INSTANCEOF\n            boolean esString = str instanceof String;\n            System.out.println(\"El objeto str \\\"\" + str + \"\\\" es una instancia de String? \" + esString);\n\n            //DE ASIGNACION\n            System.out.println(\"Asignación simple: \" + double1 + \" = \" + double2 + \" = \" + (double1 = double2));\n            System.out.println(\"Asignación suma: \" + double1 + \" += \" + double2 + \" = \" + (double1 += double2));\n            System.out.println(\"Asignación resta: \" + double1 + \" -= \" + double2 + \" = \" + (double1 -= double2));\n            System.out.println(\"Asignación multiplicación: \" + double1 + \" *= \" + double2 + \" = \" + (double1 *= double2));\n            System.out.println(\"Asignación división: \" + double1 + \" /= \" + double2 + \" = \" + (double1 /= double2));\n            System.out.println(\"Asignación módulo: \" + double1 + \" %= \" + double2 + \" = \" + (double1 %= double2));\n            System.out.println(\"Asignación AND: \" + int1 + \" &= \" + int2 + \" = \" + (int1 &= int2));\n            System.out.println(\"Asignación OR: \" + int1 + \" |= \" + int2 + \" = \" + (int1 |= int2));\n            System.out.println(\"Asignación XOR: \" + int1 + \" ^= \" + int2 + \" = \" + (int1 ^= int2));\n            System.out.println(\"Asignación desplazamiento a la izquierda: \" + int1 + \" <<= \" + int2 + \" = \" + (int1 <<= int2));\n            System.out.println(\"Asignación desplazamiento a la derecha: \" + int1 + \" >>= \" + int2 + \" = \" + (int1 >>= int2));\n            System.out.println(\"Asignación desplazamiento a la derecha sin signo: \" + int1 + \" >>>= \" + int2 + \" = \" + (int1 >>>= int2));\n\n            //RESETEANDO VALORES\n            double1 = 7.0;\n            int1 = 5;\n\n            //UNARIOS\n            System.out.println(\"Unario positivo: +\" + double1 + \" = \" + (+double1));\n            System.out.println(\"Unario negativo: -\" + double1 + \" = \" + (-double1));\n            System.out.println(\"Incremento: ++\" + double1 + \" = \" + (++double1));\n            System.out.println(\"Decremento: --\" + double1 + \" = \" + (--double1));\n            System.out.println(\"Incremento postfijo: \" + double1 + \"++ (cambio aplicado después de la operación)\");\n            System.out.println(\"Decremento postfijo: \" + double1 + \"-- (cambio aplicado después de la operación)\");\n\n            //DE TIPO BITWISE\n            System.out.println(\"AND bitwise: \" + int1 + \" & \" + int2 + \" = \" + (int1 & int2));\n            System.out.println(\"OR bitwise: \" + int1 + \" | \" + int2 + \" = \" + (int1 | int2));\n            System.out.println(\"XOR bitwise: \" + int1 + \" ^ \" + int2 + \" = \" + (int1 ^ int2));\n            System.out.println(\"Complemento bitwise: ~\" + int1 + \" = \" + (~int1));\n\n            //DE DESPLAZAMIENTO\n            System.out.println(\"Desplazamiento a la izquierda: \" + int1 + \" << \" + int2 + \" = \" + (int1 << int2));\n            System.out.println(\"Desplazamiento a la derecha: \" + int1 + \" >> \" + int2 + \" = \" + (int1 >> int2));\n            System.out.println(\"Desplazamiento a la derecha sin signo: \" + int1 + \" >>> \" + int2 + \" = \" + (int1 >>> int2));\n\n            //TERNARIO\n            String resultado = (double1 > double2) ? \"es true\" : \"es false\";\n            System.out.println(\"Resultado: \" + resultado);\n\n\n        //ESTRUCTURAS DE CONTROL\n\n            //CONDICIONALES (if, if-else, if-else-if, switch)\n            if (int1 > 0) {\n                System.out.println(\"La condición int1 > 0 se cumple.\");\n            }\n\n            if (int1 > 0) {\n                System.out.println(\"La condición int1 > 0 se cumple.\");\n            } else {\n                System.out.println(\"La condición int1 > 0 no se cumple.\");\n            }\n\n            if (int1 > 0) {\n                System.out.println(\"La condición int1 > 0 se cumple.\");\n            } else if (int1 < 0) {\n                System.out.println(\"La condición int1 < 0 se cumple.\");\n            } else {\n                System.out.println(\"Ninguna de las condiciones anteriores se cumple.\");\n            }\n\n            switch (int1) {\n                case 0:\n                    System.out.println(\"La condición int1 = 0 se cumple.\");\n                    break;\n                case 1:\n                    System.out.println(\"La condición int1 = 1 se cumple.\");\n                    break;\n                default:\n                    System.out.println(\"Ninguna de las condiciones anteriores se cumple.\");\n                    break;\n            }\n\n            //ITERATIVAS / BUCLES (for, while, do-while)\n            for (int i = 1; i < 5; i++) {\n                System.out.println(\"Iteración for: \" + (i));\n            }\n\n            int1 = 0;\n            while (int1 < 5) {\n                System.out.println(\"Iteración while: \" + int1);\n                int1++;\n            }\n\n            int1 = 0;\n            do {\n                System.out.println(\"Iteración do-while: \" + int1);\n                int1++;\n            } while (int1 < 5);\n\n            //EXCEPCIONES (try-catch-finally)\n            try {\n                int division = int1 / 0;\n            } catch (ArithmeticException e) {\n                System.out.println(\"Error: La división por 0 es matemáticamente imposible.\");\n            } finally {\n                System.out.println(\"Ejecutando el bloque finally.\");\n            }\n\n            //BREAK\n            for (int i = 1; i < 10; i++) {\n                if (i == 5) {\n                    System.out.println(\"Se ha alcanzado el valor 5, saliendo del bucle.\");\n                    break;\n                }\n                System.out.println(\"Iteración for con break: \" + (i));\n            }\n\n            //CONTINUE\n            for (int i = 1; i < 10; i++) {\n                if (i == 5) {\n                    System.out.println(\"Se ha alcanzado el valor 5, saltando esta iteración.\");\n                    continue;\n                }\n                System.out.println(\"Iteración for con continue: \" + (i));\n            }\n\n        //DIFICULTAD EXTRA\n            System.out.println(\"Entre el rango de números del 10 al 55, estos son los números pares (excluyendo el 16) que no son múltiplos de 3:\");\n            for (int i = 10; i < 56; i++) {\n                if ((i % 2 == 0) && (i != 16) && (i % 3 != 0)) {\n                    System.out.println(i);\n                }\n            }\n\n\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/CoronelSam.java",
    "content": "public class CoronelSam {\n    public static void main(String[] args) {\n        // Operadores aritméticos\n        int a = 10;\n        int b = 5;\n        System.out.println(\"Suma: \" + (a + b));\n        System.out.println(\"Resta: \" + (a - b));\n        System.out.println(\"Multiplicación: \" + (a * b));\n        System.out.println(\"División: \" + (a / b));\n        System.out.println(\"Módulo: \" + (a % b));\n\n        // Operadores lógicos\n        boolean c = true;\n        boolean d = false;\n        System.out.println(\"AND: \" + (c && d));\n        System.out.println(\"OR: \" + (c || d));\n        System.out.println(\"NOT: \" + (!c));\n\n        // Operadores de comparación\n        System.out.println(\"Igualdad: \" + (a == b));\n        System.out.println(\"Desigualdad: \" + (a != b));\n        System.out.println(\"Mayor que: \" + (a > b));\n        System.out.println(\"Menor que: \" + (a < b));\n        System.out.println(\"Mayor o igual que: \" + (a >= b));\n        System.out.println(\"Menor o igual que: \" + (a <= b));\n\n        // Operadores de asignación\n        int e = 10;\n        e += 5;\n        System.out.println(\"Suma y asignación: \" + e);\n        e -= 5;\n        System.out.println(\"Resta y asignación: \" + e);\n        e *= 5;\n        System.out.println(\"Multiplicación y asignación: \" + e);\n        e /= 5;\n        System.out.println(\"División y asignación: \" + e);\n        e %= 5;\n        System.out.println(\"Módulo y asignación: \" + e);\n\n        // Operadores de identidad\n        System.out.println(\"Igualdad de objetos: \" + (a == b));\n        System.out.println(\"Desigualdad de objetos: \" + (a != b));\n\n        // Operadores de pertenencia\n        int[] f = {1, 2, 3, 4, 5};\n        System.out.println(\"Pertenece: \" + (f instanceof int[]));\n\n        // Operadores de bits\n        int g = 60; // 60 = 0011 1100\n        int h = 13; // 13 = 0000 1101\n        System.out.println(\"AND a nivel de bits: \" + (g & h)); // 12 = 0000 1100\n        System.out.println(\"OR a nivel de bits: \" + (g | h)); // 61 = 0011 1101\n        System.out.println(\"XOR a nivel de bits: \" + (g ^ h)); // 49 = 0011 0001\n        System.out.println(\"Complemento a nivel de bits: \" + (~g)); // -61 = 1100 0011\n        System.out.println(\"Desplazamiento a la izquierda: \" + (g << 2)); // 240 = 1111 0000\n        System.out.println(\"Desplazamiento a la derecha: \" + (g >> 2)); // 15 = 0000 1111\n        System.out.println(\"Desplazamiento a la derecha sin signo: \" + (g >>> 2)); // 15 = 0000 1111\n        \n        // Estructuras de control\n        // Condicionales\n        if (a > b) {\n            System.out.println(\"a es mayor que b\");\n        } else {\n            System.out.println(\"a no es mayor que b\");\n        }\n\n        // Iterativas\n        for (int i = 0; i < 5; i++) {\n            System.out.println(\"Iteración \" + i);\n        }\n\n        // Excepciones\n        try {\n            int j = 1 / 0;\n        } catch (ArithmeticException ex) {\n            System.out.println(\"División por cero\");\n        }\n\n        // Números entre 10 y 55, pares y no múltiplos de 3 ni 16\n        System.out.println(\"Los numeros son: \");\n        for (int k = 10; k <= 55; k++) {\n            if (k % 2 == 0 && k != 16 && k % 3 != 0) {\n                System.out.println(k);\n            }\n        }\n\n\n    }    \n}\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/DanielBelenguer.java",
    "content": "public class DanielBelenguer {\n/*\n* EJERCICIO:\n* - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n*   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n*   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n* - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n*   que representen todos los tipos de estructuras de control que existan\n*   en tu lenguaje:\n*   Condicionales, iterativas, excepciones...\n* - Debes hacer print por consola del resultado de todos los ejemplos.\n*\n* DIFICULTAD EXTRA (opcional):\n* Crea un programa que imprima por consola todos los números comprendidos\n* entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n*\n* Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n*/ \npublic static void main(String[] args) {\n    int num1 = 10;\n    int num2 = 5;\n    \n    // Operadores\n\n    // Aritméticos:\n\n    int resultado = num1 + num2;\n    System.out.println(\"Suma: \" + resultado);\n    resultado = num1 - num2;\n    System.out.println(\"Resta: \" + resultado);\n    resultado = num1 * num2;\n    System.out.println(\"Multiplicación: \" + resultado);\n    resultado = num1 / num2;\n    System.out.println(\"División: \" + resultado);\n    resultado = num1 % num2;\n    System.out.println(\"Potencia: \");\n    System.out.println(\"Módulo: \" + resultado);\n    resultado = num1++;\n    System.out.println(\"Incremento: \" + resultado);\n    resultado = num1--;\n    System.out.println(\"Decremento: \" + resultado);\n    \n    // Lógicos:\n\n    System.out.println(\"AND && 5==5 && 6<10: \" + (5 == 5 && 6 < 10));\n    System.out.println(\"OR || 5==1 && 6<10: \" + (5 == 1 || 6 < 10));\n    System.out.println(\"NOT ! !false\" + (!false));\n\n    // Asignación:\n\n    num1 = 15;\n    System.out.println(num1);\n    num1 += 5;\n    System.out.println(num1);\n    num1 -= 3;\n    System.out.println(num1);\n    num1 *= 2;\n    System.out.println(num1);\n    num1 /= 2;\n    System.out.println(num1);\n    num1 %= 3;\n    System.out.println(num1);\n    num1 ^= 2;\n    System.out.println(num1);\n\n    // Comparación:\n\n    System.out.println(\"Es igual 15 = 5: \" + (15 == 5));\n    System.out.println(\"Es diferente 15 != 5: \" + (15 != 5));\n    System.out.println(\"Es mayor 15 > 5: \" + (15 > 5));\n    System.out.println(\"Es menor 15 < 5: \" + (15 < 5));\n    System.out.println(\"Es mayor o igual 15 >= 5: \" + (15 >= 5));\n    System.out.println(\"Es menor o igual 15 <= 5: \" + (15 <= 5));\n\n    // Bits:\n    num1 = 10;\n    num2 = 5;\n    System.out.println(\"Operador AND &: \" + (num1 & num2));\n    System.out.println(\"Operador OR |: \" + (num1 | num2));\n    System.out.println(\"Operador XOR ^: \" + (num1 ^ num2));\n    System.out.println(\"Desplazamiento a la izquierda <<: \" + (num1 << num2));\n    System.out.println(\"Desplazamiento a la derecha >>: \" + (num1 >> num2));\n\n    // Estructuras de control\n\n    // Condicionales:\n\n    int numeroif = 50;\n\n    if (numeroif == 50) {\n        System.out.println(\"Entro en el If\" + numeroif);\n    } else if (numeroif == 60) {\n        System.out.println(\"Entro en el Else If\" + numeroif);\n    } else {\n        System.out.println(\"Entro en el Else\" + numeroif);        \n    }\n\n    // Switch:\n    int numerocase = 10;\n    switch (numerocase) {\n        case 10:\n            System.out.println(\"Entro en el case 10\" + numerocase);\n            break;\n        case 20:\n            System.out.println(\"Entro en el case 20\" + numerocase);\n            break;\n        default:\n            System.out.println(\"Entro en el default\" + numerocase);\n            break;\n    }\n\n    // Case que se almacena en una variable\n    String resultadoSwitch = switch (numerocase) {\n        case 10 -> \"Entro en el case 10\" + numerocase;\n        case 20 -> \"Entro en el case 20\" + numerocase;\n        default -> \"Entro en el default\" + numerocase;\n    };\n    System.out.println(\"El resultado del switch es: \" + resultadoSwitch);\n\n    // Iterativas:\n\n    // Bucle for:\n    for (int i = 0; i < 10; i++) {\n        System.out.println(\"Iteración: \" + i);\n    }\n\n    // Bucle for each:\n    int[] array = {1, 2, 3, 4, 5};\n    for (int i : array) {\n        System.out.println(\"Iteración: \" + i);\n    }\n\n    // Bucle while:\n    int i = 0;\n    while (i < 10) {\n        System.out.println(\"Iteración: \" + i);\n        i++;\n    }\n\n    // Bucle do while:\n    // Este bucle se ejecuta primero el bloque do y luego ejecuta la condición\n    i = 0;\n    do {\n        System.out.println(\"Iteración: \" + i);\n        i++;\n    } while (i < 10);\n\n    // Excepciones:\n\n    // Esta estructura de control se utiliza para capturar errores en tiempo de ejecución\n    // Lo que esta comprobando que el indice que estas intentando mostrar esta fuera del rango del array\n    try {\n        int[] arrayExcepcion = {1, 2, 3, 4, 5};\n        System.out.println(arrayExcepcion[10]);\n    } catch (ArrayIndexOutOfBoundsException e) {\n        System.out.println(\"Error: \" + e);\n    }\n\n    // Ejercicio extra:\n    /*Crea un programa que imprima por consola todos los números comprendidos\n    entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3. */\n\n    for (int j = 10; j <= 55; j++) {\n        if (j % 2 == 0 && j != 16 && j % 3 != 0) {\n            System.out.println(\"Número: \" + j);\n        }\n    }\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/Danymarsan1.java",
    "content": "public class Danymarsan1 {\n    public static void main(String[] args) {\n        int a = 4;\n        int b = 2;\n        System.out.println(\"Operadores binarios\");\n        System.out.println(\"Suma: \" + (a + b));\n        System.out.println(\"Resta: \" + (a - b));\n        System.out.println(\"Multiplicación: \" + (a * b));\n        System.out.println(\"División: \" + (a / b));\n        System.out.println(\"Modulo: \" + (a % b));\n        System.out.println();\n\n        System.out.println(\"Operadores unarios\");\n        System.out.println(\"Signo positivo: \" + (+a));\n        System.out.println(\"Signo negativo: \" + (-a));\n        System.out.println(\"Preincremento: \" + (++a));\n        System.out.println(\"Postincremento: \" + (a++));\n        System.out.println(\"Predecremento: \" + (--a));\n        System.out.println(\"Postdecremento: \" + (a--));\n        System.out.println();\n\n        System.out.println(\"Operadores de comparación\");\n        System.out.println(\"¿4 es mayor que 2? : \" +(a>b));\n        System.out.println(\"¿4 es mayor o igual que 2? : \" +(a>=b));\n        System.out.println(\"¿4 es menor que 2? : \" +(a<b));\n        System.out.println(\"¿4 es menor o igual que 2? : \" +(a<=b));\n        System.out.println(\"¿4 es igual que 2? : \" + (a==b));\n        System.out.println(\"¿4 es distinto de 2? : \" + (a!=b));\n        System.out.println();\n\n        boolean v = true;\n        boolean f = false;        \n        System.out.println(\"Operadores lógicos\");\n        \n        System.out.println(\"¿true es igual a false? : \" + (v&f));\n        System.out.println(\"¿true es igual a false? : \" + (v&&f));\n        System.out.println(\"¿true o false son verdaderas? : \" + (v|f));\n        System.out.println(\"¿true o false son verdaderas? : \" + (v||f));\n        System.out.println(\"Contrario de true : \" + (!v));\n        System.out.println();\n\n        int c;\n        System.out.println(\"Operadores de asignación\");\n        \n        System.out.println(\"Asignamos valor a la variable i = \" + (c = 1));\n        System.out.println(\"Suma y asigna: \" + (c+=5));\n        System.out.println(\"Resta y asigna: \" + (c-=5));\n        System.out.println(\"Multiplica y asigna: \" + (c*=5));\n        System.out.println(\"Divide y asigna: \" + (c/=5));\n        System.out.println();\n\n\n        System.out.println(\"Los números del ejercicio de dificultad extra:\");\n        //Bucle\n        for(int i = 10; i < 56; i++){\n            //Condicional\n            if(i != 16 && i % 3 != 0 && i % 2 == 0){\n            System.out.println(i);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/Deathbat00.java",
    "content": "//DeathbatO \nimport java.util.Scanner;\n\npublic class Reto1 {\n    public static void main(String[] args) {\n        // Declaracion de variables que se usaran en el codigo\n        Scanner sc = new Scanner(System.in);\n        int a, b, c, d, t, x, k, num;\n        boolean bite1, bite2;\n        char vocal;\n\n        ////-------- Operadores ---------////\n\n        //-- Aritmeticos --//\n        a = 5;\n        b = 10;\n        int sum = a + b;\n        int res = a - b;\n        int mult = a * b;\n        int div = a / b;\n        int mod = a % b;\n        /* Con el siguiente print se podra visualizar el resultado de cualquier\n        operacion realizada en esta seccion reemplazando la que esta como ejemplo*/\n        System.out.println(\"Ejemplo de Operador Aritmetico: \"+mult);\n\n\n        //-- Comparacion --//\n        c = 5;\n        d = 9;\n        boolean OpIgual = c == d;\n        boolean OpDesigualdad = c != d;\n        boolean OpMayorQue = c > d;\n        boolean OpMenorQue = c < d;\n        boolean OpMayoroIgual = c >= d;\n        boolean OpMenoroIgual = c <= d;\n        /* Con el siguiente print se podra visualizar el resultado de cualquier\n        operacion realizada en esta seccion reemplazando la que esta como ejemplo*/\n        System.out.println(\"Ejemplo de Operdaor de Comparacion (Mayor)\"+OpMayorQue);\n\n\n         //-- Logicos --//\n        bite1 = true;\n        bite2 = false;\n        boolean OperadorAnd = bite1 && bite1;\n        boolean OperdorOr = bite1 || bite2;\n        boolean OperdaorNot = !bite1;\n        /* Con el siguiente print se podra visualizar el resultado de cualquier\n        operacion realizada en esta seccion reemplazando la que esta como ejemplo*/\n        System.out.println(\"Ejemplo de Operador Logico (Not): \"+OperdaorNot);\n\n\n        //-- Asignacion --//\n        //Asignacion simple\n        t = 100; // se asigna un valor de 100 a la variable 't'\n        //Asignacion de suma\n        t += 2; // Toma el valor que ya tenia y le suma 2\n        //Asignacion de resta\n        t -= 2; // Toma el valor que ya tenia y le resta 2\n        //Asignacion de multiplicacion\n        t *= 2; //Toma el valor que ya tenia y le multiplica 2\n        //Asignacion de division\n        t /= 2; // Toma el valor que ya tiene y lo divide entre 2\n        //Asignacion de modulo\n        t %= 2; // Toma el valor que ya tiene y hace la operacion de modulo\n        //Asignacion de multiplicacion exponencial\n        t <<= 2; //Toma el valor que ya tiene y multiplica por 2 elevado a la 2\n\n\n\n        //-- Bits --//\n        boolean OpBitAnd = bite1 & bite2;\n        boolean OpBitOr = bite1 | bite2;\n        boolean OpBitXor = bite1 ^ bite2;\n        boolean OpBitNot = !bite1;\n        /* Con el siguiente print se podra visualizar el resultado de cualquier\n        operacion realizada en esta seccion reemplazando la que esta como ejemplo*/\n        System.out.println(\"Ejemplo de Operador de Bits (Xor): \"+OpBitXor);\n\n\n        ////-------- Estructuras de Control ---------////\n\n        //-- Condicionales --//\n        System.out.print(\"Por favor digita un numero entero para compararlo con 20: \");\n        x = sc.nextInt(); sc.nextLine();\n        if(x > 20){\n            System.out.print(\"\\nEl numero es mayor a 20\");\n        }else if(x < 20){\n            System.out.print(\"\\nEl numero es menor a 20\");\n        }else{\n            System.out.print(\"\\nEl numero es 20\");\n        }\n\n\n        System.out.println(\"\\nAhora por favor digita una volcal: \");\n        vocal = sc.nextLine().toUpperCase().charAt(0);\n\n        switch(vocal){\n            case 'A':\n                System.out.println(\"Vocal A\");\n                break;\n            case 'E':\n                System.err.println(\"Vocal E\");\n                break;\n            case 'I':\n                System.out.println(\"Vocal I\");\n                break;\n            case 'O':\n                System.out.println(\"Vocal O\");\n                break;\n            case 'U':\n                System.out.println(\"Vocal U\");\n                break;\n            default:\n                System.out.println(\"Eso no es una vocal\");\n                break;\n        }\n\n        //-- Iterativas --//\n        \n        //Imprime los numero pares desde el 0 hasta el 12\n        for(int i = 0; i <= 12; i++){\n            if(i % 2 == 0){\n                System.out.print(i+\" \");\n            }\n        }\n        System.out.println(\"\");\n        //Imprime los numeros multiplos de 3 desde el 0 hasta el 15\n        k = 0;\n        while(k <= 15){\n            if(k % 3 == 0){\n                System.out.print(k+\" \");\n            }\n            k++;\n        }\n        System.out.println(\"\");\n\n        //-- Excepciones --//\n        \n        try{\n            System.out.print(\"Por favor ingrese un numero entero: \");\n            num = sc.nextInt(); \n            System.out.print(\"\\nEl numero que ingreso es la mitad de: \"+(num*2)+\"\\n\");\n        }catch(Exception e){\n            System.out.println(\"ERROR---. Eso no era un numero\\n\");\n        }finally{\n            sc.close();\n        }\n\n        ////-------- Reto Extra ---------////\n\n        //-- Ejercicio con For --//\n\n        System.out.println(\"Ejercicio con For\");\n\n        for(int i = 10; i < 56; i++){\n            if(i % 2 == 0 && i != 16 && i % 3 == 0){\n                System.out.print(i+\" \");\n            }\n        }\n        System.out.println(\"\");\n\n        //-- Ejercicio con while --//\n\n        System.out.println(\"ejercicio con while\");\n        k = 10;\n        while(k <= 55){\n            if(k % 2 == 0 && k != 16 && k % 3 == 0){\n                System.out.print(k+\" \");\n            }\n            k++;\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/DiegoIBB.java",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\npackage javaExample_;\nimport java.util.Scanner;\n\npublic class Operadores_Estructuras_de_Control_01 {\n\t\n\t//Excepción Customizada\n\tstatic void largo_cadena(String nombre) {\n\t\tString identidad = nombre;\n\t\tint cadena = identidad.length();\n\t\tSystem.out.println(cadena);\n\n\t\tif(cadena > 3) {\n\t\t\tthrow new ArithmeticException(\"La cadena excede la cantidad de caracteres\");\n\t\t}else {\n\t\t\tSystem.out.println(\"Largo de cadena correcto\");\n\t\t}\n\t\t}\n\t\n\tpublic static void main(String args[]) {\n\t\t\n\t\t//OPERADORES\n\t\t/* Asignación: =, +=, -=, *=, /=, %=, **=, etc..\n\t\t * Aritméticos: +, -, *, /, %, **, etc..\n\t\t * Comparasión: <, >, <=, >=, ==, !=\n\t\t * Lógicos:&&(and),||(or), !(not)\n\t\t * */\n\t\t\n\t\t//OPERADORES_ARITMETICOS\n\t\tSystem.out.println(\"--- Operadores Aritméticos ---\");\n\n\t\tint x = 23;\n\t\tint y = 34;\n\t\t\n\t\tint Suma = x + y;\n\t\tint Resta = x - y;\n\t\tint Multiplicacion = x * y;\n\t\tint Division = x / y;\n\t\tint Modulo = x % y;\n\t\tint Incremento = x ++;\n\t\tint Decremento = y --;\n\n\n\t\tSystem.out.println(\"Resultado: \"+ x + \" + \"+ y + \"= \"+ Suma);\n\t\tSystem.out.println(\"Resultado: \"+ x + \" - \"+ y + \"= \"+ Resta);\n\t\tSystem.out.println(\"Resultado: \"+ x + \" * \"+ y + \"= \"+ Multiplicacion);\n\t\tSystem.out.println(\"Resultado: \"+ x + \" / \"+ y + \"= \"+ Division);\n\t\tSystem.out.println(\"Resultado: \"+ x + \" % \"+ y + \"= \"+ Modulo);\n\t\tSystem.out.println(\"Resultado incremento de: \"+ x + \"= \"+ Incremento);\n\t\tSystem.out.println(\"Resultado decremento de: \"+ y + \"= \"+ Decremento);\n\t\t\n\t\t\n\t\t//OPERADORES DE ASIGNACION\n\t\tSystem.out.println(\"--- Operadores de asignación ---\");\n\t\t\n\t\tint num_1 = 4;\n\t\tint num_2 = 6;\n\t\tint num_3 = 7;\n\t\tint num_4 = 5;\n\t\tint num_5 = 4;\n\t\tint num_6 = 9;\n\t\t\n\t\tnum_1 = 6; //Se le asigna un nuevo valor a num_1\n\t\tnum_2 += 2; // Se le suma 2 unidades a num_1\n\t\tnum_3 -= 4; // Se le restan 4 unidades a num_1\n\t\tnum_4 *= 3; // Se multiplica num_1 por 3\n\t\tnum_5 /= 2; // Se divide num_1 entre 2\n\t\tnum_6 %= 3; // Se obtiene el modulo de num_1 entre 3 \n\n\t\tSystem.out.println(\"Re-asignación de num_1: \"+ num_1);\n\t\tSystem.out.println(\"Suma de 2 a num_2: \"+ num_2);\n\t\tSystem.out.println(\"Se le resta 4 a num_3: \"+ num_3);\n\t\tSystem.out.println(\"Se multiplica num_4 por 3: \"+ num_4);\n\t\tSystem.out.println(\"Se divide num_5 entre 2: \"+ num_5);\n\t\tSystem.out.println(\"Se obtiene el modulo de 9 entre 3: \"+ num_6);\n\n\t\t//OPERADORES_COMPARACION\n\t\t\n\t\tSystem.out.println(\"--- Operadores de Comparación ---\");\n\t\tint num_7 = 45;\n\t\tint num_8 = 55;\n\t\t\n\t\tSystem.out.println(num_7 == num_8); //Operador igualdad\n\t\tSystem.out.println(num_7 != num_8); //Operador desigualdad\n\t\tSystem.out.println(num_7 > num_8); //Operador igualdad\n\t\tSystem.out.println(num_7 < num_8); //Operador igualdad\n\t\tSystem.out.println(num_7 >= num_8); //Operador igualdad\n\t\tSystem.out.println(num_7 <= num_8); //Operador igualdad\n\n\t\t\n\t\t\n\t\t//EXCEPCIONES\n\t\tSystem.out.println(\"--- Excepciones ---\");\n\t\tfloat number_1 = 4;\n\t\tfloat number_2 = 3;\n\t\t\t\t\n\t\ttry {\n\t\t\tfloat number_3 = number_1 / number_2;\n\t\t\tSystem.out.println(number_3);\n\t\t}catch(Exception e) {\n\t\t\tSystem.out.println(\"Los valores son incorrectos\");\n\t\t}finally {\n\t\t\tSystem.out.println(\"Programa terminado\");\n\t\t}\n\t\t\n\t\t// Excepciones_Customizadas\n\t\t\n\t\t//largo_cadena(\"Nombre de persona\"); //Código para probar excepción customizada (método en la cabezera))\n\t\t\n\t\t\n\t\t\t\n\t\t//ESTRUCTURA_DE_CONTROL_DE_SELECCION_O_TOMA_DE_DESICION\n\t\tSystem.out.println(\"--- Estructuras de control ---\");\n\t\tint a = 34;\n\t\tint b = 56;\n\t\t\n\t\t//Estructura_IF_ELSE-IF_ELSE\n\t\tif(a >= b){\n\t\t\tSystem.out.println(\"A is major than B: \" +  a + \" > \" + b);\n\t\t}\n\t\telse if(a <= b){\n\t\t\tSystem.out.println(\"B is major than A: \" +  b + \" > \" + a);\n\t\t}\n\t\telse{\n\t\t\tSystem.out.println(\"Numbers are Equal\");\n\t\t}\n\t\t\n\t\t//Estructura_SWITCH\n\t\tSystem.out.println(\"--- Estructura Switch ---\");\n\t\tint option = 8;\n\t\tswitch(option){\n\t\tcase 1:\n\t\t\tSystem.out.println(\"Number selected is 1\");\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tSystem.out.println(\"Number selected is 2\");\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\tSystem.out.println(\"Number selected is 3\");\n\t\t\tbreak;\n\t\tcase 4:\n\t\t\tSystem.out.println(\"Number selected is 4\");\t\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tSystem.out.println(\"Number not recognized\");\t\n\t\t}\n\t\t\n\t\t//ESTRUCTURA_DE_CONTROL_DE_REPETICION\n\t\t\n\t\t//Bucle_FOR\n\t\t\n\t\t\n\t\tSystem.out.println(\"--- Bucle For ---\");\n\t\tfor(int i=1; i <= 10; i++) {\n\t\t\tSystem.out.println(i);\n\t\t}\n\t\t\n\t\t//Bucle_WHILE\n\t\tint f = 0;\n\t\tSystem.out.println(\"--- Bucle While ---\");\n\t\twhile(f < 10) {\n\t\t\tf += 1;\n\t\t\tSystem.out.println(x);\n\t\t}\n\n\t}\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/DjSurgeon.java",
    "content": "public class Java01 {\n  /*\n   * EJERCICIO:\n   * - Crea ejemplos de funciones básicas que representen las diferentes\n   *   posibilidades del lenguaje:\n   *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n   * - Comprueba si puedes crear funciones dentro de funciones.\n   * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n   * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n   * - Debes hacer print por consola del resultado de todos los ejemplos.\n   *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n   *\n   * DIFICULTAD EXTRA (opcional):\n   * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n   * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n   *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n   *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n   *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n   *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n   *\n   * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n   * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n   */\n\n  // Constante global\n  public static final int EDAD = 42;\n\n  /**\n   * Saludos!!\n   */\n  public static void saluda() {\n    System.out.println(\"Hola, Java!!\");\n  }\n\n  /**\n   * Saluda a una persona por su nombre.\n   * @param nombre El nombre de la persona.\n   */\n  public static void nombra(String nombre) {\n    System.out.printf(\"Hola, %s!!\\n\", nombre);\n  }\n\n  /**\n   * Realiza una suma de dos números enteros.\n   * @param sum1 El primer sumando.\n   * @param sum2 El segundo sumando.\n   * @return La suma total.\n   */\n  public static int suma(int sum1, int sum2) {\n    int total;\n\n    total = sum1 + sum2;\n    return (total);\n  }\n\n  /*\n  En Java no se pueden crear funciones dentro de funciones. Todos los metodos deben ser miembros de\n  una clase.\n   */\n\n  /*\n  En este ejemplo se estan usando funciones predefinidas del sistema como son println() y printf().\n   */\n\n  /*\n    EJERCICIO EXTRA\n   */\n\n  public static int extra(String s1, String s2) {\n    int total;\n\n    total = 0;\n    for (int i = 0; i < 100; i++) {\n      if (i % 5 == 0 && i % 3 == 0) {\n        System.out.println(s1 + \" \" + s2);\n      } else if (i % 5 == 0) {\n        System.out.println(s1);\n      } else if (i % 3 == 0) {\n        System.out.println(s2);\n      } else {\n        total++;\n      }\n    }\n    return (total);\n  }\n\n  public static void main(String[] args) {\n    int result;\n\n    result = suma(3, 3);\n    saluda();\n    nombra(\"Sergio\");\n    System.out.printf(\"La suma de 3 + 3 es: %d.\\n\", result);\n    System.out.printf(\"Mi edad es %d años.\\n\", EDAD);\n    result = extra(\"Hola\", \"Java\");\n    System.out.printf(\"El total es: %d.\\n\", result);\n  }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/DomingoAndres.java",
    "content": "public class DomingoAndres {\n\n    public static void main(String[] args) {\n\n        //-------------OPERADORES----------------\n\n        //Operadores Aritmeticos\n        int a = 10; //variables para usar \n        int b = 5; //en las operaciones\n\n        System.out.println(\"Suma: 10 + 5 = \" + (a+b));\n        System.out.println(\"Resta: 10 - 5 = \" + (a-b));\n        System.out.println(\"Division: 10 / 5 = \" + (a/b));\n        System.out.println(\"Modulo: 10 % 5 = \" + (a%b));\n        \n        //Operadores de comparacion\n        System.out.println(\"Mayor que: 10 > 5: \" + (a>b));\n        System.out.println(\"Menor que: 10 < 5: \" + (a<b));\n        System.out.println(\"Igualdad: 10 = 5: \" + (a==b));\n        System.out.println(\"Desigualdad: 10 != 5: \" + (a!=b));\n        System.out.println(\"Mayor o igual que: 10 >= 5: \" + (a>=b));\n        System.out.println(\"Menor o igual que: 10 <= 5: \" + (a<=b));\n\n        //Operadores Logicos\n        System.out.println(\"AND &&: 10 + 5 == 15 && 10 - 5 == 5: \" + (a + b == 15 && a - b == 5));\n        System.out.println(\"OR ||: 10 + 5 == 15 && 10 - 5 == 5: \" + (a + b == 15 || a - b == 5));\n        System.out.println(\"NOT !: 10 + 3 == 14: \" + (a + b != 14));\n\n        //Operadores de asignacion\n         a = 7; // Un solo signo = es asignacion\n         a += 3; //suma y asinacion\n         a -= 4; //resta y asgnacion\n         a *= 2; //multiplicacion y asignacion\n         a /= 2; //Division y asignacion\n         a %= 2; //Modulo y asignacion\n\n         //Operadores de bit\n        System.out.println(\"AND: 10 & 5: \" + (a & b));\n        System.out.println(\"OR: 10 | 5: \" + (a | b));\n        System.out.println(\"XOR: 10 ^ 5: \" + (a ^ b));\n        \n\n         //------------ESTRUCTURAS DE CONTROL--------------\n\n         //Condicionales (IF)\n        if (b > 0){\n            System.out.println(\"Se cumplio la condicion\");\n        }\n\n        // Iteracion con ciclo for\n        for (int i = 0; i < b; i++){\n            System.out.println(\"Iteracion \" + i);\n        }\n\n        // Iteracion con ciclo while\n        while (b < 10){\n            System.out.println(\"Estoy dentro del ciclo\");\n            b ++;\n        }\n\n        //Iteracion con ciclo do-while\n        do{\n            System.out.println(\"Aca tambien estoy dentro del ciclo\");\n            b --;\n        } while (b > 5);\n\n        //usando switch\n        switch(b){\n            case 3:\n                System.out.println(\"No me voy a ejcutar porque b vale 5\");\n            case 4:\n                System.out.println(\"Tampoco me voy a ejecutar\");\n            case 5:\n                System.out.println(\"Me ejecuto porque b vale 5\");\n        }\n\n        //Manejo de excepciones con try-catch\n        try {\n            System.out.println(10 / 0);\n        } catch (Exception e) {\n            System.out.println(\"Ocurrio un error y lo controle\");\n        } finally{\n            System.out.println(\"Esta parte siempre se ejecuta en el manejo de expciones.\");\n        }\n\n        \n        //-----------EJERCICIO DE DIFICULTAD EXTRA----------------\n        for (int i = 1; i < 55; i ++){\n            if (i % 2 == 0 && i != 16 && i % 3 != 0){\n                System.out.println(i);\n            }\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/Dredux2.java",
    "content": "/*\r\n * EJERCICIO:\r\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\r\n *   Aritmeticos, logicos, de comparacion, asignacion, identidad, pertenencia, bits...\r\n *   (Ten en cuenta cada lenguaje puede poseer unos diferentes)\r\n * - Utilizando las operaciones con operadores tú quieras, crea ejemplos\r\n *   representen todos los tipos de estructuras de control existan\r\n *   en tu lenguaje:\r\n *   Condicionales, iterativas, excepciones...\r\n * - Debes hacer print por consola del resultado de todos los ejemplos.\r\n */\r\npackage org.example;\r\nclass Dredux {\r\n    public static void main(String[] args) {\r\n        //1)\r\n        // Operadores aritmeticos\r\n        int a = 10;\r\n        int b = 5;\r\n        System.out.println(\"Suma: \" + (a + b));\r\n        System.out.println(\"Resta: \" + (a - b));\r\n        System.out.println(\"Multiplicacion: \" + (a * b));\r\n        System.out.println(\"Division: \" + (a / b));\r\n        System.out.println(\"Modulo: \" + (a % b));\r\n        System.out.println();\r\n\r\n        // Operadores logicos\r\n        boolean c = true;\r\n        boolean d = false;\r\n        System.out.println(\"AND: \" + (c && d));\r\n        System.out.println(\"OR: \" + (c || d));\r\n        System.out.println(\"NOT: \" + (!c));\r\n        System.out.println();\r\n\r\n        // Operadores de comparacion\r\n        System.out.println(\"Igualdad: \" + (a == b));\r\n        System.out.println(\"Desigualdad: \" + (a != b));\r\n        System.out.println(\"Mayor: \" + (a > b));\r\n        System.out.println(\"Menor: \" + (a < b));\r\n        System.out.println(\"Mayor o igual: \" + (a >= b));\r\n        System.out.println(\"Menor o igual: \" + (a <= b));\r\n        System.out.println();\r\n\r\n        // Operadores de asignacion\r\n        System.out.println(\"Asignacion: \" + (a = b));\r\n        System.out.println(\"Suma y asignacion: \" + (a += b));\r\n        System.out.println(\"Resta y asignacion: \" + (a -= b));\r\n        System.out.println(\"Multiplicacion y asignacion: \" + (a *= b));\r\n        System.out.println(\"Division y asignacion: \" + (a /= b));\r\n        System.out.println(\"Modulo y asignacion: \" + (a %= b));\r\n        System.out.println();\r\n\r\n        // Operadores unitarios\r\n        System.out.println(\"Incremento: \" + (++a));\r\n        System.out.println(\"Decremento: \" + (--a));\r\n        System.out.println(\"Negacion\" + (~a));\r\n        System.out.println(\"Positivo: \" + (+a));\r\n        System.out.println();\r\n\r\n        // Operadores de Ternario\r\n        System.out.println(\"Ternario: \" + (a > b ? \"a es mayor que b\" : \"a es menor o igual que b\"));\r\n        System.out.println();\r\n\r\n        // Operadores de instancia\r\n        String s = \"Hola\";\r\n        System.out.println(\"Instancia: \" + (s instanceof String));\r\n        System.out.println();\r\n\r\n        // Operadores de bits\r\n        System.out.println(\"AND: \" + (a & b));\r\n        System.out.println(\"OR: \" + (a | b));\r\n        System.out.println(\"XOR: \" + (a ^ b));\r\n        System.out.println();\r\n\r\n\r\n\r\n        // 2)\r\n        // Condicionales\r\n        if (a > b) {\r\n            System.out.println(\"a es mayor que b\");\r\n        } else {\r\n            System.out.println(\"a es menor o igual que b\");\r\n        }\r\n        System.out.println();\r\n\r\n        // Iterativas\r\n        for (int i = 0; i < 5; i++) {\r\n            System.out.println(\"Iteracion \" + i);\r\n        }\r\n        System.out.println();\r\n\r\n        // Excepciones\r\n        try {\r\n            int x = 1 / 0;\r\n        } catch (ArithmeticException e) {\r\n            System.out.println(\"Division por cero\");\r\n        }\r\n        System.out.println();\r\n\r\n        // DIFICULTAD EXTRA (opcional):\r\n        // Crea un programa imprima por consola todos los números comprendidos\r\n        // entre 10 y 55 (incluidos), pares, y no son ni el 16 ni múltiplos de 3.\r\n\r\n        // 3)\r\n        System.out.println(\"Numeros pares entre 10 y 55 que no son 16 ni multiplos de 3:\");\r\n        for (int i = 10; i <= 55; i++) {\r\n            if (i % 2 != 0 || i == 16 || i % 3 == 0) {\r\n                continue;\r\n            }\r\n            System.out.println(i);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/EspinoLeandroo.java",
    "content": "public class EspinoLeandroo {\n    public static void main(String[] args) {\n        // Operadores Aritméticos\n        int a = 10, b = 5;\n        System.out.println(\"Suma: \" + (a + b));\n        System.out.println(\"Resta: \" + (a - b));\n        System.out.println(\"Multiplicación: \" + (a * b));\n        System.out.println(\"División: \" + (a / b));\n        System.out.println(\"Módulo: \" + (a % b));\n\n        // Operadores de Comparación\n        System.out.println(\"Igual a: \" + (a == b));\n        System.out.println(\"No igual a: \" + (a != b));\n        System.out.println(\"Mayor que: \" + (a > b));\n        System.out.println(\"Menor que: \" + (a < b));\n        System.out.println(\"Mayor o igual que: \" + (a >= b));\n        System.out.println(\"Menor o igual que: \" + (a <= b));\n\n        // Operadores Lógicos\n        boolean x = true, y = false;\n        System.out.println(\"AND lógico: \" + (x && y));\n        System.out.println(\"OR lógico: \" + (x || y));\n        System.out.println(\"NOT lógico: \" + (!x));\n\n        // Operadores de Asignación\n        int c = 15;\n        c += 5; // Equivalente a c = c + 5\n        System.out.println(\"Operador de Asignación: \" + c);\n\n        // Estructuras de Control Condicionales\n        if (a > b) {\n            System.out.println(\"a es mayor que b\");\n        } else if (a < b) {\n            System.out.println(\"a es menor que b\");\n        } else {\n            System.out.println(\"a es igual a b\");\n        }\n\n        // Estructuras de Control Iterativas\n        System.out.println(\"Bucle For:\");\n        for (int i = 0; i < 5; i++) {\n            System.out.println(i);\n        }\n\n        System.out.println(\"Bucle While:\");\n        int contador = 0;\n        while (contador < 5) {\n            System.out.println(contador);\n            contador++;\n        }\n\n        // Estructuras de Control de Excepciones\n        try {\n            int resultado = a / 0; // División por cero, lanza ArithmeticException\n        } catch (ArithmeticException e) {\n            System.out.println(\"¡Error! División por cero.\");\n        }\n\n        // Opcional\n        for (int i = 10; i <= 55; i++) {\n            if (i % 2 == 0 && i != 16 && i % 3 != 0) {\n                System.out.println(i);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/Fluna29.java",
    "content": "package practicas;\n\npublic class Main {\n    public static void main(String[] args) {\n        \n\n        //Operadores aritméticos\n\n        int a = 10;\n        int b = 5;\n\n        System.out.println(\"\\nOperadores aritméticos\");\n        System.out.println(\"Suma: \" + (a + b));\n        System.out.println(\"Resta: \" + (a - b));\n        System.out.println(\"Multiplicación: \" + (a * b));\n        System.out.println(\"División: \" + (a / b));\n        System.out.println(\"Módulo: \" + (a % b));\n        System.out.println(\"Incremento: \" + (++a));\n        System.out.println(\"Decremento: \" + (--b));\n\n\n        //Operadores lógicos\n\n        boolean falso = false;\n        boolean verdadero = true;\n\n        System.out.println(\"\\nOperadores lógicos\");\n        System.out.println(\"AND: \" + (falso && verdadero));\n        System.out.println(\"OR: \" + (falso || verdadero));\n        System.out.println(\"NOT: \" + (!falso));\n\n\n        //Operadores de comparación\n\n        int comp1 = 100;\n        int comp2 = 200;\n\n        System.out.println(\"\\nOperadores de comparación\");\n        System.out.println(\"Igual a: \" + (comp1 == comp2));\n        System.out.println(\"Diferente de: \" + (comp1 != comp2));\n        System.out.println(\"Mayor que: \" + (comp1 > comp2));\n        System.out.println(\"Menor que: \" + (comp1 < comp2));\n        System.out.println(\"Mayor o igual que: \" + (comp1 >= comp2));\n        System.out.println(\"Menor o igual que: \" + (comp1 <= comp2));\n\n\n        //Operadores de asignación\n\n        int asig = 1;\n\n\n        System.out.println(\"\\nOperadores de asignación\");\n        System.out.println(\"Asignación: \" + (asig = 2));\n        System.out.println(\"Suma: \" + (asig += 2));\n        System.out.println(\"Resta: \" + (asig -= 2));\n        System.out.println(\"Multiplicación: \" + (asig *= 2));\n        System.out.println(\"División: \" + (asig /= 2));\n        System.out.println(\"Módulo: \" + (asig %= 2));\n\n\n        //Operadores de identidad\n\n        System.out.println(\"\\nOperadores de identidad\");\n        String txt = \"Buenos dias\";\n        Integer num = 100;\n        System.out.println(\"¿Es una instancia de String? \" + (txt instanceof String));\n        System.out.println(\"¿Es una instancia de Integer? \" + (num instanceof Integer));\n\n\n        //Operadores de pertenencia\n\n        int[] numeros = {1, 2, 3, 4, 5};\n        int num1 = 3;\n        System.out.println(\"\\nOperadores de pertenencia\");\n        for (int numero : numeros) {\n            if (numero == num1) {\n                System.out.println(\"El número \" + num1 + \" está en el array\");\n            }\n        }\n\n\n        //Operadores de Bits\n\n        int bit1 = 60; /* 60 = 0011 1100 */\n        int bit2 = 13; /* 13 = 0000 1101 */\n\n        System.out.println(\"\\nOperadores de Bits\");\n        System.out.println(\"AND: \" + (bit1 & bit2)); /* 12 = 0000 1100 */\n        System.out.println(\"OR: \" + (bit1 | bit2)); /* 61 = 0011 1101 */\n        System.out.println(\"XOR: \" + (bit1 ^ bit2)); /* 49 = 0011 0001 */\n        System.out.println(\"NOT: \" + (~bit1)); /* -61 = 1100 0011 */\n        System.out.println(\"Desplazamiento a la izquierda: \" + (bit1 << 2)); /* 240 = 1111 0000 */\n        System.out.println(\"Desplazamiento a la derecha: \" + (bit1 >> 2)); /* 15 = 0000 1111 */\n        System.out.println(\"Desplazamiento a la derecha sin signo: \" + (bit1 >>> 2)); /* 15 = 0000 1111 */\n        \n\n        //Operador condicional ternario\n        int op1 = 10;\n        int op2 = 5; \n\n        System.out.println(\"\\nOperador condicional ternario\");\n        System.out.println(\"El mayor es: \" + ((op1 > op2) ? op1 : op2));\n\n        //Condicionales (if-else)\n\n        int edad = 18;\n\n        System.out.println(\"\\nCondicionales (if-else)\");\n        if (edad >= 18) {\n            System.out.println(\"Eres mayor de edad\");\n        } else {\n            System.out.println(\"Eres menor de edad\");\n        }\n\n\n        //Estructuras Iterativas (for, while, do-while)\n\n        System.out.println(\"\\nEstructuras Iterativas (for, while, do-while)\");\n\n        System.out.println(\"\\nFor:\");\n        for (int i = 0; i < 5; i++) {\n            System.out.println(\"Iteración: \" + i);\n        }\n\n        System.out.println(\"\\nWhile:\");\n        int j = 0;\n        while (j < 5) {\n            System.out.println(\"Iteración: \" + j);\n            j++;\n        }\n\n        System.out.println(\"\\nDo-While:\");\n        int k = 0;\n        do {\n            System.out.println(\"Iteración: \" + k);\n            k++;\n        } while (k < 5);\n\n\n        /**\n         * DIFICULTAD EXTRA (opcional):\n         * Crea un programa que imprima por consola todos los números comprendidos\n         * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n         */\n\n        System.out.println(\"\\nNúmeros comprendidos entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3:\");\n        int numMin = 10;\n        int numMax = 55;\n\n        for(int i = numMin; i<=numMax; i++){\n            if(i % 2 == 0 && i != 16 && i / 3 != 0){\n                System.out.println(i);\n            }\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/FranDev200.java",
    "content": "public class FranDev200 {\n\n    static void main() {\n\n        System.out.println(\"===== OPERADORES =====\");\n\n        // ---------------- ARITMÉTICOS ----------------\n        int a = 10, b = 3;\n        System.out.println(\"Suma: \" + (a + b));\n        System.out.println(\"Resta: \" + (a - b));\n        System.out.println(\"Multiplicación: \" + (a * b));\n        System.out.println(\"División: \" + (a / b));\n        System.out.println(\"Módulo: \" + (a % b));\n        System.out.println(\"Incremento: \" + (++a));\n        System.out.println(\"Decremento: \" + (--b));\n\n        // ---------------- COMPARACIÓN ----------------\n        System.out.println(\"a == b: \" + (a == b));\n        System.out.println(\"a != b: \" + (a != b));\n        System.out.println(\"a > b: \" + (a > b));\n        System.out.println(\"a < b: \" + (a < b));\n        System.out.println(\"a >= b: \" + (a >= b));\n        System.out.println(\"a <= b: \" + (a <= b));\n\n        // ---------------- LÓGICOS ----------------\n        boolean x = true, y = false;\n        System.out.println(\"x && y: \" + (x && y));\n        System.out.println(\"x || y: \" + (x || y));\n        System.out.println(\"!x: \" + (!x));\n\n        // ---------------- ASIGNACIÓN ----------------\n        int c = 5;\n        c += 3;\n        System.out.println(\"c += 3 → \" + c);\n        c -= 2;\n        System.out.println(\"c -= 2 → \" + c);\n        c *= 2;\n        System.out.println(\"c *= 2 → \" + c);\n        c /= 2;\n        System.out.println(\"c /= 2 → \" + c);\n\n        // ---------------- IDENTIDAD ----------------\n        String s1 = new String(\"Hola\");\n        String s2 = new String(\"Hola\");\n        System.out.println(\"s1 == s2: \" + (s1 == s2));\n        System.out.println(\"s1.equals(s2): \" + s1.equals(s2));\n\n        // ---------------- PERTENENCIA (instanceof) ----------------\n        Object obj = \"Texto\";\n        System.out.println(\"obj instanceof String: \" + (obj instanceof String));\n\n        System.out.println(\"\\n===== ESTRUCTURAS DE CONTROL =====\");\n\n        // ---------------- CONDICIONALES ----------------\n        int numero = 7;\n\n        if (numero > 5) {\n            System.out.println(\"If: El número es mayor que 5\");\n        } else {\n            System.out.println(\"If: El número no es mayor que 5\");\n        }\n\n        if (numero > 10) {\n            System.out.println(\"Else if: Mayor que 10\");\n        } else if (numero > 5) {\n            System.out.println(\"Else if: Mayor que 5\");\n        } else {\n            System.out.println(\"Else if: Menor o igual a 5\");\n        }\n\n        switch (numero) {\n            case 1:\n                System.out.println(\"Switch: número 1\");\n                break;\n            case 7:\n                System.out.println(\"Switch: número 7\");\n                break;\n            default:\n                System.out.println(\"Switch: otro número\");\n        }\n\n        // ---------------- ITERATIVAS ----------------\n        System.out.println(\"\\nFor:\");\n        for (int i = 0; i < 3; i++) {\n            System.out.println(\"i = \" + i);\n        }\n\n        System.out.println(\"\\nWhile:\");\n        int j = 0;\n        while (j < 3) {\n            System.out.println(\"j = \" + j);\n            j++;\n        }\n\n        System.out.println(\"\\nDo-While:\");\n        int k = 0;\n        do {\n            System.out.println(\"k = \" + k);\n            k++;\n        } while (k < 3);\n\n        System.out.println(\"\\nFor-each:\");\n        int[] array = {1, 2, 3};\n        for (int valor : array) {\n            System.out.println(\"valor = \" + valor);\n        }\n\n        // ---------------- EXCEPCIONES ----------------\n        System.out.println(\"\\nExcepciones:\");\n\n        try {\n            int resultado = 10 / 0;\n            System.out.println(resultado);\n        } catch (ArithmeticException ex) {\n            System.out.println(\"Error: División por cero\");\n        } finally {\n            System.out.println(\"Bloque finally ejecutado\");\n        }\n\n        // ---------------- CONTROL DE SALTO ----------------\n        System.out.println(\"\\nBreak y Continue:\");\n\n        for (int i = 0; i < 5; i++) {\n            if (i == 2) continue;\n            if (i == 4) break;\n            System.out.println(\"i = \" + i);\n        }\n\n        System.out.println(\"** EJERCICIO EXTRA **\");\n\n        for(int i = 10; i <= 55; i++){\n\n            if( (i%2) == 0 && (i%3) != 0 && i != 16){\n                System.out.println(i);\n            }\n\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/FrancoFMV.java",
    "content": "public class FrancoFMV{\n\n    public static void main(String[] args) {\n        \n        //Operadores de asignación\n        System.out.println(\"---Operadores de asignación---\");\n        int num1 = 5;\n        int num2 = 2;\n        int num3 = 5;\n        int x = 10;\n        System.out.println(\"num1 = \"+ num1);\n        System.out.println(\"num2 = \"+ num2);\n        System.out.println(\"num3 = \"+ num3);\n        System.out.println(\"x = \"+ x);\n\n        //Operadores arimetricos (+; -; *; /; %; ++; --) \n        System.out.println(\"---Operadores arimetricos (+; -; *; /; %; ++; --) ---\");\n        int suma= num1+num2; \n        int resta= num1-num2;\n        int multipli= num1*num2;\n        int divid= num1/num2;\n        double mod= num1%num2;\n        int sum1=  num1++;\n        int rest1=  num1--;\n        \n        System.out.println(\"El resultado de \" + num1 +\" + \"+ num2+\" es: \"+suma);\n        System.out.println(\"El resultado de \"+ num1 +\" - \"+ num2+\" es: \"+resta);\n        System.out.println(\"El resultado de \"+ num1 +\" * \"+ num2+\" es: \"+multipli);\n        System.out.println(\"El resultado de \"+ num1 +\" / \"+ num2+\" es: \"+divid);\n        System.out.println(\"El resultado de \"+ num1 +\" % \"+ num2+\" es: \"+mod);\n        System.out.println( \"El valor de \"+ num1 +\" incrementado en 1 es: \"+sum1);\n        System.out.println( \"El valor de \"+ num1 +\" decrementado en 1 es: \"+rest1);\n\n        //Operador de comparación (==; !=; >; <; >=; <=) \n        System.out.println(\"---Operador de comparación (==; !=; >; <; >=; <=) ---\");\n        System.out.println(num1 + \" == \" + num3 + \"? \" + (num1==num3)); \n        System.out.println(num1 + \" != \" + num3 + \"? \" + (num1!=num3));\n        System.out.println(num1 + \" < \" + num2 + \"? \" + (num1<num2));\n        System.out.println(num2 + \" > \" + num3 + \"? \" + (num1>num2));\n        System.out.println(num1 + \" >= \" + num2 + \"? \" + (num1>=num2));\n        System.out.println(num1 + \" <= \" + num2 + \"? \" + (num1<=num2));\n\n        //Operadores logicos (&&; ||; !)\n        System.out.println(\"---Operadores logicos (&&; ||; !)---\");\n        System.out.println( x > 5 &&  x <= 10 ); // && = and\n        System.out.println( x < 5 || x < 4 ); // || = or\n        System.out.println( !(x < 5 && x < 10) ); // ! = not\n\n        System.out.println(\"---Ejercicio Extra---\");\n        ejExtra();\n    }\n\n    public static void ejExtra(){\n        for (int i = 10; i < 56; i++) {\n            if((i!=16) && (i%3!=0) && (i%2==0)){\n                System.err.println(i);\n            }\n        }\n    }\n\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/FreedAInew.java",
    "content": "\nimport java.util.Scanner;\n\nimport java.util.Set;\n\npublic class FreedAInew {\n    public static void main(String[] args) throws Exception {\n\n        //operators\n        //Arithmetic operators\n\n        var A= 10;\n        int B= 5;\n\n        System.out.println(\"Sum: \" + (A + B)); \n        System.out.println(\"Remainder: \" + (A - B)); \n        System.out.println(\"Multiplication: \" + (A * B)); \n        System.out.println(\"Division: \" + (A / B)); \n        System.out.println(\"Module: \" + (A % B));\n\n\n\n        //Assignment Operators\n\n        // Prefix increment \n        System.out.println(\"A++: \" + (A++)); // Print 10, then increment x to 11 \n        // Postfix increment \n        System.out.println(\"A++: \" + (A++)); // Print 11, then increment x to 12 \n        System.out.println(\"A: \" + A); // Print 12\n\n        // Decrement prefix \n        System.out.println(\"B--: \" + (B--)); // Print 5, then decrement y to 4 \n        // Postfix decrement \n        System.out.println(\"B--: \" + (B--)); // Print 4, then decrement y to 3 \n        System.out.println(\"B: \" + B); // Print 3\n\n\n\n\n        //Comparison Operators or Relational Operators \n\n        System.out.println(\"A == B: \" + (A == B)); // Output: false\n        System.out.println(\"A != B: \" + (A != B)); // Output: true\n        System.out.println(\"A < B: \" + (A < B)); // Output: false\n        System.out.println(\"A <= B: \" + (A <= B)); // Output: false\n        System.out.println(\"A > B: \" + (A > B)); // Output: true\n        System.out.println(\"A >= B: \" + (A >= B)); // Output: true\n\n\n\n        //Logical Operators\n\n        boolean isSunny = true;\n        boolean hasUmbrella = false;\n\n        // AND (&&) - Both conditions must be true\n        System.out.println(\"Need umbrella (sunny && !hasUmbrella): \" + (isSunny && !hasUmbrella)); // Output: true (sunny and no umbrella)\n\n        // OR (||) - At least one condition must be true\n        int age = 20;\n        boolean isStudent = true;\n        System.out.println(\"Can vote (age >= 18 || isStudent): \"+ (age >= 18 || isStudent)); // Output: true (either age or student status qualifies)\n\n        // NOT (!) - Negates the condition\n        boolean isOnline = false;\n        boolean isOffline = true;\n        System.out.println(\"Is offline (!isOnline): \" + (!isOnline)); // Output: true (not online)\n        System.out.println(\"Is offline (!isOnline): \" + (!isOffline)); // Output: false (not online)\n\n\n        //Identity Operators\n\n        System.out.println(A == B); //Output: false (reference inequality)\n\n\n\n        //Membership Operators\n\n\n        // Create a Set of animals\n        Set<String> animals = Set.of(\"manatee\", \"Beluga\", \"Quokka\");\n\n        // Check if a specific animal is present (corrected comment)\n        boolean isManateePresent = animals.contains(\"manatee\");\n        System.out.println(\"Is manatee present: \" + isManateePresent); // Output: true\n\n\n        // Check if a non-existent animal is present (corrected comment)\n        boolean isQuokkaPresent = animals.contains(\"Quokka\");\n        System.out.println(\"Is Quokka present: \" + isQuokkaPresent); // Output: false\n\n\n         //Bitwise Operators\n\n        int a = 6; // 0b110\n        int b = 3; // 0b011\n\n         // AND\n        int resultAND = a & b;\n        System.out.println(\"AND: \" + resultAND); // 2\n\n        // OR\n        int resultOR = a | b;\n        System.out.println(\"OR: \" + resultOR); // 7\n\n        // XOR\n        int resultXOR = a ^ b;\n        System.out.println(\"XOR: \" + resultXOR); // 5\n\n        // NOT\n        int resultNOT = ~a;\n        System.out.println(\"NOT: \" + resultNOT); // -7\n\n        // Left shift\n        int resultLeftShift = a << 2;\n        System.out.println(\"Left shift: \" + resultLeftShift); // 24\n\n        // Right shift\n        int resultRightShift = a >> 2;\n        System.out.println(\"Right shift: \" + resultRightShift); // 1\n\n        //Extended range operator\n\n        int lowerBound = 5;\n        int upperBound = 15;\n        boolean excludeUpperBound = true;\n\n        for (int i = lowerBound; i < (excludeUpperBound ? upperBound : upperBound + 1); i++){ \n            System.out.println(i);}\n\n\n         //Control Structures\n\n\n         //Simple Sequential Structure\n\n         // Initialize variables\n        int num1 = 10;\n        int num2 = 20;\n\n        \n        int sum = num1 + num2;// Calculate the sum\n\n        \n        System.out.println(\"The sum of \" + num1 + \" and \" + num2 + \" is: \" + sum); // Print the sum\n\n         //Conditional structures\n\n         boolean peopleCareAboutWars = false; // Assuming people don't care about wars\n         boolean peopleEvadeTaxes = true; // Assuming people evade taxes\n\n        // Check if people care about wars\n\n        if (peopleCareAboutWars) {\n            System.out.println(\"Since people care about wars, they should never pay taxes.\");\n        } else {\n            System.out.println(\"Since people don't seem to care about wars, they might pay taxes.\");\n\n        // Check if people evade taxes\n        if (peopleEvadeTaxes) {\n            System.out.println(\"Despite their apathy towards wars, people are still evading taxes.\");\n        } else {\n            System.out.println(\"If people don't care about wars and they pay taxes honestly, there could be positive outcomes.\");\n        } }\n    \n\n\n\n         //Repetitive Control Structure\n\n         Scanner scanner = new Scanner(System.in); // Create Scanner for user input\n\n         System.out.print(\"Enter body type (Ectomorph, Mesomorph, Endomorph): \");\n         String bodyType = scanner.nextLine().toUpperCase(); // Get user input and convert to uppercase\n \n         // Display information based on user input\n         switch (bodyType) {\n             case \"ECTOMORPH\":\n                 System.out.println(\"**Body Type: Ectomorph**\");\n                 System.out.println(\"Characteristics:\");\n                 System.out.println(\"- Slender frame\");\n                 System.out.println(\"- Thin limbs\");\n                 System.out.println(\"- Fast metabolism\");\n                 System.out.println(\"- Difficulty gaining muscle mass\");\n                 break;\n             case \"MESOMORPH\":\n                 System.out.println(\"**Body Type: Mesomorph**\");\n                 System.out.println(\"Characteristics:\");\n                 System.out.println(\"- Athletic build\");\n                 System.out.println(\"- Well-defined muscles\");\n                 System.out.println(\"- Balanced metabolism\");\n                 System.out.println(\"- Responds well to both strength and endurance training\");\n                 break;\n             case \"ENDOMORPH\":\n                 System.out.println(\"**Body Type: Endomorph**\");\n                 System.out.println(\"Characteristics:\");\n                 System.out.println(\"- Rounded physique\");\n                 System.out.println(\"- Higher body fat percentage\");\n                 System.out.println(\"- Slower metabolism\");\n                 System.out.println(\"- Prone to storing fat\");\n                 break;\n             default:\n                 System.out.println(\"Invalid body type.\");\n         }\n \n         scanner.close(); // Close Scanner after use\n\n         \n\n         //Exception Handling:\n\n         try {\n            int result = 10 / 0; // Division by zero (ArithmeticException)\n\n            System.out.println(\"Result: \" + result);\n          } catch (ArithmeticException e) {\n            System.out.println(\"Error: Division by zero.\");\n          } finally {\n            System.out.println(\"Program execution complete.\"); // Always executes\n          }\n\n\n        System.out.println(\"see you tomorrow!\");\n\n\n    }\n}\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/Gerthai08.java",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n *\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n *\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\npublic class Gerthai08 {\n    public static void main(String[] arg) {\n\n        // ASIGNACIÓN\n        int a = 5;\n        int b = 10;\n        System.out.println(a += 2);\n        System.out.println(a -= 2);\n        System.out.println(a /= 2);\n        System.out.println(a *= 2);\n        System.out.println(++a);\n        System.out.println(--a);\n\n        // ARITMÉTICOS\n        System.out.println(a + b);\n        System.out.println(a - b);\n        System.out.println(a * b);\n        System.out.println(a / b);\n        System.out.println(a % b);\n\n        // RELACIONALES\n        System.out.println(a == b);\n        System.out.println(a <= b);\n        System.out.println(a >= b);\n        System.out.println(a < b);\n        System.out.println(a > b);\n        System.out.println(a != b);\n\n\n        // LÓGICOS\n        System.out.println(a + a == b && b - a == a);\n        System.out.println(a + a == b || b - a == a);\n        System.out.println(a + a == b & b - a == a);\n        System.out.println(a + a == b | b - a == a);\n        System.out.println(!(a + a == b || b - a == a));\n\n   /*\n   ESTRUCTURAS SELECTIVAS\n   */\n\n        // CICLO IF\n\n        if (a > b) {\n            System.out.println(\"La variable A es igual a: \" + a);\n            System.out.println(\"La variable B es igual a: \" + b);\n            System.out.println(\"La variable A es mayor que B\");\n        }\n\n        // CICLO ELSE IF\n        else if (a == b) {\n            System.out.println(\"Las variables A y B son iguales\");\n        }\n\n        // CICLO ELSE\n        else {\n            System.out.println(\"La variable A es igual a: \" + a);\n            System.out.println(\"La variable B es igual a: \" + b);\n            System.out.println(\"La variable B es mayor que A\");\n        }\n\n        // CICLO SWITCH\n\n        switch (a) {\n            case 1:\n                System.out.println(\"La variable A es igual a 1\");\n                break;\n            case 2:\n                System.out.println(\"La variable A es igual a 2\");\n                break;\n            case 3:\n                System.out.println(\"La variable A es igual a 3\");\n                break;\n            case 4:\n                System.out.println(\"La variable A es igual a 4\");\n                break;\n            case 5:\n                System.out.println(\"La variable A es igual a 5\");\n                break;\n            case 6:\n                System.out.println(\"La variable A es igual a 6\");\n                break;\n            case 7:\n                System.out.println(\"La variable A es igual a 7\");\n                break;\n            default:\n                System.out.println(\"La variable A es mayor a 7\");\n                break;\n        }\n\n\n    /*\n   ESTRUCTURAS REPETITIVAS\n   */\n\n        //ESTRUCTURA WHILE\n\n        while (b == 10) {\n            System.out.println(\"La variable B es igual a: \" + b);\n            --b;\n\n        }\n\n\n        //ESTRUCTURA DO-WHILE\n\n        do {\n            System.out.println(\"La variable A es igual a: \" + a + \" y es mayor que 0\");\n            a--;\n        } while (a > 0);\n\n\n        //ESTRCUTURA FOR\n        for (a = 0; a < 5; a++) {\n            System.out.println(\"La variable a es igual a: \" + a + \" y es menor a 5\");\n        }\n\n        // EJERCICIO EXTRA\n        int c = 10;\n        for (c = 10; c >= 10 && c <= 55; c++) {\n            if (c % 2 == 0 && c % 3 != 0 && c != 16) {\n                System.out.println(c);\n            }\n\n        }\n\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/Guillermo-Munoz.java",
    "content": "public class GuillermoMunoz {\n    \n//Usuario GitHub: Guillermo-Muñoz\n\npublic static void main(String[] args) {\n\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\nint a = 10;\nint b = 5;\n// Operadores Aritméticos\nSystem.out.println(\"Operadores Aritméticos:\");\nSystem.out.println(\"Suma: \" + (a + b)); \nSystem.out.println(\"Resta: \" + (a - b));\nSystem.out.println(\"Multiplicación: \" + (a * b ));\nSystem.out.println(\"Division: \" + (a / b));\nSystem.out.println(\"Modulo: \" + (a % b ));;\n\n// Operadores de asignación\nSystem.out.println(\"\\nOperadores de Asignación:\");\nSystem.out.println(\"Asignación: \" + (a = b));\nSystem.out.println(\"Suma y asignación: \" + (a += b));\nSystem.out.println(\"Resta y asignación: \" + (a -= b));\nSystem.out.println(\"Multiplicación y asignación: \" + (a *= b));     \nSystem.out.println(\"División y asignación: \" + (a /= b));\nSystem.out.println(\"Módulo y asignación: \" + (a %= b));\n\n// Operadores de comparación\nSystem.out.println(\"\\nOperadores de Comparación:\");\nSystem.out.println(\"Igual a: \" + (a == b));\nSystem.out.println(\"Distinto de: \" + (a != b));\nSystem.out.println(\"Mayor que: \" + (a > b));\nSystem.out.println(\"Menor que: \" + (a < b));\nSystem.out.println(\"Mayor o igual que: \" + (a >= b));\nSystem.out.println(\"Menor o igual que: \" + (a <= b));\n\n// Operadores lógicos\nSystem.out.println(\"\\nOperadores Lógicos:\");\nSystem.out.println(\"AND lógico: \" + ((a > b) && (a != b)));\nSystem.out.println(\"OR lógico: \" + ((a > b) || (a == b)));\nSystem.out.println(\"NOT lógico: \" + !(a == b));\n\n// Estructuras de control\nSystem.out.println(\"\\nEstructuras de Control:\");\n\n// Condicionales\n \n   // Estructura if-else\n    if (a > b) {\n        System.out.println(\"a es mayor que b\");\n    }else if(a == b){\n        System.out.println(\"a es igual a b\");\n    } \n    else {\n        System.out.println(\"a no es mayor que b\" );\n    }\n\n    // Estructura switch-case\n    int c = 10;\n    switch (c) {\n        case 5:\n            System.out.println(\"c es 5\");\n            break;\n        case 10:\n            System.out.println(\"c es 10\");\n            break;\n        default:\n            System.out.println(\"c no es ni 5 ni 10\");\n    }\n\n    // Estructuras while, do-while y for\n    int d = 0;\n    while (d < 5) {\n        System.out.println(\"While: \" + d);\n        d++;\n    }\n\n    int e = 0;\n    do {\n        System.out.println(\"Do-While: \" + e);\n        e++;\n    } while (e < 5);\n\n    for (int i = 0; i < 5; i++) {\n        System.out.println(\"For: \" + i);\n\n    }\n    // Ejercicio extra\n\n    System.out.println(\"Ejercicio extra: Crea un programa que imprima por consola todos los números comprendidos\\r\\n\" + //\n                \" entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\");\n    for( int f = 10 ; f <=55; f++){\n        if (f % 2 == 0 && \n            f % 3 != 0 && \n            f != 16){\n            System.out.println(\"Numero: \" + f);\n        }\n    }\n\n\n\n}\n\n\n\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/GustavoGomez19.java",
    "content": "public class GustavoGomez19 {\n    public static void main(String[] args){\n        //Punto 1: Ejemplos con operadores de Java\n        //Operador de asignación (=)\n        String nombre = \"Gustavo\";\n\n        //Operadores aritméticos (+, -, *, /, %, ++, --, unario(+), unario(-))\n        int num1 = 5;\n        int num2 = 10;\n        int resultado;\n        boolean resultado2;\n        //suma (+)\n        resultado = num1 + num2;\n        System.out.println(\"resultado = \" + resultado);\n        //resta (-)\n        resultado = num1 - num2;\n        System.out.println(\"resultado = \" + resultado);\n        //multiplicación (*)\n        resultado = num1 * num2;\n        System.out.println(\"resultado = \" + resultado);\n        //división (/)\n        resultado = num1 / num2;\n        System.out.println(\"resultado = \" + resultado);\n        //modulo (%)\n        resultado = num1 % num2;\n        System.out.println(\"resultado = \" + resultado);\n        //incremento (++)\n        num1++;\n        System.out.println(\"resultado = \" + resultado);\n        //decremento (--)\n        num2--;\n        //unario (+). Si el número es negativo su valor pasa a ser positivo\n        int num3 = -20;\n        resultado= +num3;\n        System.out.println(\"num3 = \" + num3);\n        //unario (-). Si el número es positivo su valor pasa a ser negativo\n        int num4 = 30;\n        resultado = -num4;\n        System.out.println(\"num4 = \" + num4);\n\n        //Operadores de comparación (==, !=, <, >, <=, >=)\n        //Igualdad (==)\n        resultado2 = num1 == num2;\n        System.out.println(\"resultado2 = \" + resultado2);\n        //No igualdad (!=)\n        resultado2 = num4 != num3;\n        System.out.println(\"resultado2 = \" + resultado2);\n        //Menor que (<)\n        resultado2 = num1 < num4;\n        System.out.println(\"resultado2 = \" + resultado2);\n        //Mayor que >\n        resultado2 = num2 > num3;\n        System.out.println(\"resultado2 = \" + resultado2);\n        //Menor igual que <=\n        resultado2 = num1 <= num3;\n        System.out.println(\"resultado2 = \" + resultado2);\n        //Mayot igual que (>=)\n        resultado2 = num2 >= num4;\n        System.out.println(\"resultado2 = \" + resultado2);\n\n        //Operadores lógicos (&&, ||, !)\n        boolean condicion1 = true;\n        boolean condicion2 = false;\n        boolean resultado3;\n        //Operador AND (&&). Devuelve TRUE si las 2 condiciones son verdaderas\n        resultado3 = condicion1 && condicion2;\n        System.out.println(\"resultado3 = \" + resultado3);\n        //Operdor OR (||). Devuelve TRUE si una de las 2 condiciones es verdadera\n        resultado3 = condicion1 || condicion2;\n        System.out.println(\"resultado3 = \" + resultado3);\n        //Operador NOT (!). Invierte el valor de una condición\n        resultado3 = !condicion2;\n        System.out.println(\"resultado3 = \" + resultado3);\n\n        //Punto 2: Ejemplos de estructuras de control\n        //Estructura de control ciclo for\n        for (int i = 0; i <= 10; i++){\n            System.out.println(\"Numero \" + i);\n        }\n        //Estructura de control ciclo while\n        int num5 = 0;\n        while(num5 < 10){\n            System.out.println(\"Numero \" + num5);\n            num5++;\n        }\n        //Estructura de control do-while\n        do {\n            System.out.println(num1);\n            num2--;\n        }while (num3 > num2);\n        //Estructura de control condicional if-else\n        if (num5 == num2){\n            System.out.println(\"Los nuúmeros son iguales\");\n        } else {\n            System.out.println(\"Los números son diferentes\");\n        }\n        //Estructura de control switch case\n        int diaSemana = 5;\n        switch (diaSemana){\n            case 1:\n            case 2:\n            case 3:\n            case 4:\n            case 5:\n                System.out.println(\"Es un día laboral\");\n                break;\n            case 6:\n            case 7:\n                System.out.println(\"Es un día no laboral\");\n                break;\n            default:\n                System.out.println(\"No es un día de la semana\");\n        }\n\n        //Punto 4: Ejercicio dificultad extra\n        for (int i = 10; i <= 55; i++){\n            if (!(i %3 == 0) && (i %2 == 0) && (i != 16)){\n                System.out.println(\"Número \" + i);\n            }\n        }\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/Hersac.java",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\npublic class reto01 {\n    public static void main(String[] args) {\n        for (int i = 10; i <= 55; i++) {\n            if (i % 2 == 0 && i % 3 != 0 && i != 16) {\n                System.out.println(i);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/IsidroJNG.java",
    "content": "public class IsidroJNG {\n\n\tpublic static void main(String[] args) {\n\t\t// Operadores aritméticos\n        int a = 10;\n        int b = 20;\n        System.out.println(\"Suma: \" + (a + b));\n        System.out.println(\"Resta: \" + (a - b));\n        System.out.println(\"Multiplicación: \" + (a * b));\n        System.out.println(\"División: \" + (a / b));\n        System.out.println(\"Módulo: \" + (a % b));\n\n        // Operadores de comparación\n        System.out.println(\"Mayor que: \" + (a > b));\n        System.out.println(\"Menor que: \" + (a < b));\n        System.out.println(\"Igual a: \" + (a == b));\n        System.out.println(\"No igual a: \" + (a != b));\n\n        // Operadores lógicos\n        boolean x = true;\n        boolean y = false;\n        System.out.println(\"AND lógico: \" + (x && y));\n        System.out.println(\"OR lógico: \" + (x || y));\n        System.out.println(\"NOT lógico: \" + (!x));\n\n        // Operadores de asignación\n        int c = a;\n        System.out.println(\"Asignación: \" + c);\n\n        // Operadores de bits\n        System.out.println(\"AND bit a bit: \" + (a & b));\n        System.out.println(\"OR bit a bit: \" + (a | b));\n        System.out.println(\"XOR bit a bit: \" + (a ^ b));\n        System.out.println(\"Desplazamiento a la izquierda: \" + (a << 2));\n        System.out.println(\"Desplazamiento a la derecha: \" + (a >> 2));\n        \n        // Operadores combinados de asignación\n        a += b;\n        System.out.println(\"Suma y asignación: \" + a);\n        a -= b;\n        System.out.println(\"Resta y asignación: \" + a);\n        a *= b;\n        System.out.println(\"Multiplicación y asignación: \" + a);\n        a /= b;\n        System.out.println(\"División y asignación: \" + a);\n        a %= b;\n        System.out.println(\"Módulo y asignación: \" + a);\n\n        // Estructuras de control\n        // Condicionales\n        if (a > b) {\n            System.out.println(\"a es mayor que b\");\n        } else {\n            System.out.println(\"a no es mayor que b\");\n        }\n\n        // Iterativas\n        for (int i = 0; i < 5; i++) {\n            System.out.println(\"Iteración: \" + i);\n        }\n\n        // Excepciones\n        try {\n            int[] myNumbers = {1, 2, 3};\n            System.out.println(myNumbers[4]);\n        } catch (Exception e) {\n            System.out.println(\"Algo salió mal.\");\n        }\n\t\t\n\t\t// Concatenar cadenas\n\t\tString cadena1 = \"Operadores\";\n\t\tString cadena2 = \"estructuras de control\";\n\t\t\n\t\tSystem.out.println(cadena1 + \" y \" + cadena2);\n\t\t\n\t\t/*\n\t\t * Crea un programa que imprima por consola todos los números comprendidos\n\t\t * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\t\t */\n\t\tSystem.out.println(\"Números pares excepto 16 y múltiplos de 3:\");\n\t\tfor (int i = 10; i <= 55; i++) {\n\t\t\tif ((i % 2 == 0) && i !=16 && (i % 3 != 0)) {\n\t\t\t\tSystem.out.println(i);\n\t\t\t}\n\t\t}\n\t\t\n\t}\n\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/Ismx17.java",
    "content": "public class Ismx17 {\n    public static void main(String[] args) {\n        \n        //Operadores Aritmeticos\n        int num1 = 5;\n        int num2 = 2;\n\n        System.out.println(\"Operadores Aritmeticos\");\n        System.out.println(\"Suma: \" + (num1 + num2));\n        System.out.println(\"Resta: \" + (num1 - num2));\n        System.out.println(\"Multiplicacion: \" + (num1 * num2));\n        System.out.println(\"Division: \" + (num1 / num2));\n        System.out.println(\"Modulo: \" + (num1 % num2));\n        System.out.println(\"Incremento: \" + (++num1));\n        System.out.println(\"Decremento: \" + (--num2));\n        System.out.println();\n\n        //Operadores Logicos\n        boolean a = true;\n        boolean b = false;\n\n        System.out.println(\"Operadores Logicos\");\n        System.out.println(\"AND: \" + (a&&b));\n        System.out.println(\"OR: \" + (a||b));\n        System.out.println(\"NOT: \" + (!a));\n        System.out.println();\n\n        //Operadores de Comparacion\n        System.out.println(\"Operadores de Comparacion\");\n        System.out.println(\"Igualdad: \" + (num1 == num2));\n        System.out.println(\"Desigualdad: \" + (num1 != num2));\n        System.out.println(\"Mayor que: \" + (num1 > num2));\n        System.out.println(\"Menor que:\" + (num1 < num2));\n        System.out.println(\"Mayor o igual que: \" + (num1 >= num2));\n        System.out.println(\"Menor o igual que: \" + (num1 <= num2));\n        System.out.println();\n\n        //Operadores de Asignacion\n        System.out.println(\"Operadores de Asignacion\");\n        System.out.println(\"Asignacion: \" + (num1 = num2));\n        System.out.println(\"Suma y asignacion: \" + (num1 += num2));\n        System.out.println(\"Resta y asignacion: \" + (num1 -= num2));\n        System.out.println(\"Multiplicacion y asignacion: \" + (num1 *= num2));\n        System.out.println(\"Division y asignacion: \" + (num1 /= num2));\n        System.out.println(\"Modulo y asignacion: \" + (num1 %= num2));\n        System.out.println();\n\n        //Ejemplos de estructuras de control\n        System.out.println(\"Ejemplos de estructuras de control\");\n\n        //IF - ELSE IF - ELSE\n        if (num1 < num2) {\n            System.out.println(\"El numero es mayor\");\n        } else if (num1 > num2){\n            System.out.println(\"El numero es menor\");\n        } else {\n            System.out.println(\"El numero es igual\");\n        }\n        System.out.println();\n\n        // DO - WHILE\n        int i = 0;\n        do {\n            System.out.println(\"Iteracion\" + i);\n            i++;\n        } while (i < 5);\n        System.out.println();\n\n        //WHILE\n        int j = 5;\n        while (j <= 5 && j > 0) {\n            System.out.println(\"Iteracion \" + i);\n            i--;\n        }\n\n        //EJERCICIO EXTRA\n        System.out.println(\"EJERCICIO EXTRA\");\n        for (int k = 10; k <= 55; k++) {\n            if (k != 16 && k % 3 != 0 && k % 2 == 0) {\n                System.out.println(k);\n            }\n            if (k == 55) {\n                break;\n            }\n            else {\n                System.out.println(k);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/JcKnot.java",
    "content": "package RoadMap;\r\n/*\r\n * @author JcKnot\r\n */\r\npublic class JcKnot {\r\n    public static void main(String[] args) {\r\n        \r\n        // Operadores aritméticos\r\n        int a = 10;\r\n        int b = 55;\r\n        System.out.println(\"Suma: \" + (a + b));\r\n        System.out.println(\"Resta: \" + (a - b));\r\n        System.out.println(\"Multiplicación: \" + (a * b));\r\n        System.out.println(\"División: \" + (a / b));\r\n        System.out.println(\"Módulo: \" + (a % b));\r\n\r\n        // Operadores lógicos\r\n        boolean x = true;\r\n        boolean y = false;\r\n        System.out.println(\"AND lógico: \" + (x && y));\r\n        System.out.println(\"OR lógico: \" + (x || y));\r\n        System.out.println(\"NOT lógico: \" + (!x));\r\n\r\n        // Operadores de asignación\r\n        int c = a;\r\n        System.out.println(\"Asignación: \" + c);\r\n        // Operadores combinados de asignación\r\n        a += b;\r\n        System.out.println(\"Suma y asignación: \" + a);\r\n        a -= b;\r\n        System.out.println(\"Resta y asignación: \" + a);\r\n        a *= b;\r\n        System.out.println(\"Multiplicación y asignación: \" + a);\r\n        a /= b;\r\n        System.out.println(\"División y asignación: \" + a);\r\n        a %= b;\r\n        System.out.println(\"Módulo y asignación: \" + a);\r\n        \r\n        // Operadores de comparación\r\n        System.out.println(\"Mayor que: \" + (a > b));\r\n        System.out.println(\"Menor que: \" + (a < b));\r\n        System.out.println(\"Igual a: \" + (a == b));\r\n        System.out.println(\"No igual a: \" + (a != b));\r\n\r\n        // Operadores de bits\r\n        System.out.println(\"AND bit a bit: \" + (a & b));\r\n        System.out.println(\"OR bit a bit: \" + (a | b));\r\n        System.out.println(\"XOR bit a bit: \" + (a ^ b));\r\n        System.out.println(\"Desplazamiento a la izquierda: \" + (a << 2));\r\n        System.out.println(\"Desplazamiento a la derecha: \" + (a >> 2));\r\n        \r\n        // Estructuras de control\r\n        // Condicionales\r\n        if (a > b) {\r\n            System.out.println(\"a es mayor que b\");\r\n        } else {\r\n            System.out.println(\"a no es mayor que b\");\r\n        }\r\n\r\n        // Iterativas\r\n        for (int i = 0; i < 5; i++) {\r\n            System.out.println(\"Iteración: \" + i);\r\n        }\r\n\r\n        // Excepciones\r\n        try {\r\n            int[] myNumbers = {1, 2, 3};\r\n            System.out.println(myNumbers[4]);\r\n        } catch (Exception e) {\r\n            System.out.println(\"Algo salió mal.\");\r\n        }\r\n        \r\n        // Extra\r\n        \r\n        int numIni = 10, numFin = 55;\r\n        \r\n        while (numIni <= numFin){\r\n            \r\n            if (numIni != 16 && numIni %2 == 0 && !(numIni %3 == 0 )){\r\n                System.out.println(numIni);\r\n            }\r\n            numIni = numIni + 1;            \r\n        }                \r\n    }\r\n}\r\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/Jeigar2.java",
    "content": "import java.util.Arrays;\nimport java.util.List;\nimport java.util.stream.IntStream;\n\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\npublic class Jeigar2 {\n    public static void main(String[] args) throws Exception {\n        testOperadoresAritmeticos();\n        testOperadoresLogicos();\n        testOperadoresComparacion();\n        testOperadoresAsignacion();\n        testOperadoresIdentidad();\n        testOperadoresPertenencia();\n        testOperadoresBits();\n        testCondicionales();\n        testIterativas();\n        testExcepciones();\n        extra();\n    }\n\n    private static void testExcepciones() {\n        try {\n            throw new RuntimeException(\"prueba\");\n        } catch (RuntimeException e){\n            System.out.println(\"capturado Error: \" + e.getMessage());\n        } finally {\n            System.out.println(\"Parte finally\");\n        }\n    }\n\n    private static void testIterativas() {\n        List<Integer> numeros = Arrays.asList(3,2,9,4);\n        System.out.println(\"for each\");\n        for (Integer numero : numeros){\n            System.out.println(\"numero: \" + numero);\n        }\n\n        System.out.println(\"for i\");\n        for (int i = 0; i < numeros.size(); i++) {\n            System.out.println(\"numero: \" + numeros.get(i));\n        }\n\n        System.out.println(\"Iterable stream\");\n        numeros.stream().forEach(System.out::println);\n\n        System.out.println(\"do...while\");\n        if (numeros.size()>0) {\n            int i = 0;\n            System.out.println(\"numero:\" + numeros.get(i));\n            do {\n                System.out.println(\"numero:\" + numeros.get(++i));\n            } while (i < numeros.size()-1);\n        }\n        System.out.println(\"while\");\n        int j = 0;\n        while (j < numeros.size()){\n            System.out.println(numeros.get(j++));\n        }\n\n    }\n\n    private static void testCondicionales() throws Exception {\n        if(true){\n            System.out.println(\"Es TRUE\");\n        }\n        if(!true){\n\n        } else {\n            System.out.println(\"Es FALSE\");\n        }\n        enum DiaSemana { LUNES, MARTES, MIERCOLES, JUEVES, VIERNES, SABADO, DOMINGO }\n\n        DiaSemana dia = DiaSemana.MIERCOLES;\n\n        String nombreDia = switch (dia){\n            case LUNES -> \"lunes\";\n            case MARTES -> \"martes\";\n            case MIERCOLES -> \"miercoles\";\n            case JUEVES -> \"jueves\";\n            case VIERNES -> \"viernes\";\n            case SABADO, DOMINGO -> \"festivo\";\n            default -> throw new Exception(\"no es un día de la semana\");\n        };\n        System.out.println(\"hoy es \" + nombreDia);\n    }\n\n    public static void extra(){\n        System.out.println(\"Extra\\n----------\");\n        IntStream.range(10,55)\n                .filter(n -> n % 2 == 0 && n != 16)\n                .forEach(System.out::println);\n    }\n\n    public static void assertEquals(int expected, int actual, String message) {\n        if (expected != actual) {\n            throw new RuntimeException(String.format(\"ERROR: %s. Se esperaba %d y ha dado %d\", message, expected, actual));\n        } else {\n            System.out.println(String.format(\"Resultado correcto %s se esperaba %d y ha dado %d\", message, expected, actual));\n        }\n    }\n\n    public static void assertTrue(boolean condition, String message) {\n        if (!condition) {\n            throw new RuntimeException(String.format(\"ERROR: %s, ha dado FALSE\", message));\n        } else {\n            System.out.println(String.format(\"Resultado correcto %s, ha dado TRUE\", message));\n        }\n    }\n\n    public static void testOperadoresAritmeticos() {\n        int a = 10;\n        int b = 5;\n        assertEquals(15, Operadores.suma(a, b), \"en la operación de suma\");\n        assertEquals(5, Operadores.resta(a, b), \"en la operación de resta\");\n        assertEquals(50, Operadores.multiplicacion(a, b), \"en la operación de multiplicacion\");\n        assertEquals(2, Operadores.division(a, b), \"en la operación de division\");\n        assertEquals(0, Operadores.modulo(a, b) , \"en la operación de modulo\");\n    }\n\n    public static void testOperadoresLogicos() {\n        assertTrue(Operadores.and(true, true), \"en la operación lógica AND\");\n        assertTrue(Operadores.or(true, false), \"en la operación lógica OR\");\n        assertTrue(!Operadores.not(true), \"en la operación lógica NOT\");\n    }\n\n    public static void testOperadoresComparacion() {\n        assertTrue(Operadores.igualdad(5, 5), \"en la operación de igualdad\");\n        assertTrue(Operadores.diferencia(5, 10), \"en la operación de diferencia\");\n        assertTrue(Operadores.mayorQue(10, 5), \"en la operación mayorQue\");\n        assertTrue(Operadores.menorIgualQue(5, 10), \"en la operación menorQue\");\n    }\n\n    public static void testOperadoresAsignacion() {\n        assertEquals(15, Operadores.asignacionSuma(10, 5) , \"en la operación de asignación\");\n    }\n\n    public static void testOperadoresIdentidad() {\n        Integer obj1 = Integer.valueOf(10);\n        Integer obj2 = Integer.valueOf(10);\n        assertTrue(Operadores.identidad(obj1, obj2), \"no tienen la misma identidad\");\n    }\n\n    public static void testOperadoresPertenencia() {\n        int[] array = {1, 2, 3, 4, 5};\n        assertTrue(Operadores.pertenencia(array, 3),\"el valor buscado no pertenece\");\n        assertTrue(!Operadores.pertenencia(array, 6), \"el valor buscado si pertenece\");\n    }\n\n    public static void testOperadoresBits() {\n        assertEquals(1,Operadores.andBit(5, 3),\"en el operado and de Bit\");\n        assertEquals(7,Operadores.orBit(5, 3), \"en el operador or de Bit\");\n        assertEquals(10, Operadores.desplazamientoIzquierda(5), \"en el desplazamiento a la Izquierda\");\n        assertEquals(2, Operadores.desplazamientoDerecha(5), \"en el desplazamiento a la derecha\");\n    }\n\n    class Operadores {\n        public static int suma(int a, int b) {\n            return a + b;\n        }\n\n        public static int resta(int a, int b) {\n            return a - b;\n        }\n\n        public static int multiplicacion(int a, int b) {\n            return a * b;\n        }\n\n        public static int division(int a, int b) {\n            return a / b;\n        }\n\n        public static int modulo(int a, int b) {\n            return a % b;\n        }\n\n        public static boolean and(boolean x, boolean y) {\n            return x && y;\n        }\n\n        public static boolean or(boolean x, boolean y) {\n            return x || y;\n        }\n\n        public static boolean not(boolean x) {\n            return !x;\n        }\n\n        public static boolean igualdad(int num1, int num2) {\n            return num1 == num2;\n        }\n\n        public static boolean diferencia(int num1, int num2) {\n            return num1 != num2;\n        }\n\n        public static boolean mayorQue(int num1, int num2) {\n            return num1 > num2;\n        }\n\n        public static boolean menorIgualQue(int num1, int num2) {\n            return num1 <= num2;\n        }\n\n        public static int asignacionSuma(int a, int b) {\n            return a += b;\n        }\n\n        public static boolean identidad(Integer obj1, Integer obj2) {\n            return obj1 == obj2;\n        }\n\n        public static boolean pertenencia(int[] array, int search) {\n            for (int i : array) {\n                if (i == search) {\n                    return true;\n                }\n            }\n            return false;\n        }\n\n        public static int andBit(int m, int n) {\n            return m & n;\n        }\n\n        public static int orBit(int m, int n) {\n            return m | n;\n        }\n\n        public static int desplazamientoIzquierda(int m) {\n            return m << 1;\n        }\n\n        public static int desplazamientoDerecha(int m) {\n            return m >> 1;\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/JerrySantana.java",
    "content": "public class JerrySantana {\n    public static void main(String[] args) {\n        unarios(10);\n        aritmeticos(5, 8);\n        cambioShift(-8, 2);\n        relacionales(7, 2);\n        bitAbit();\n        logicos();\n        System.out.println(ternario(true));\n        System.out.println(ternario(false));\n        asignacion();\n        System.out.println(\"------> Extra <------\");\n        extra();\n    }\n\n    public static void unarios(int value) {\n        // Operadores unarios\n        System.out.println(\"------ Operadores unarios.\");\n        System.out.println(\"El valor es: \" + value);\n        System.out.println(\"valor++: \" + value++); // imprime el valor y después le suma 1 (posfijo)\n        System.out.println(\"++valor: \" + ++value); // le suma 1 al valor y después lo imprime (prefijo)\n        System.out.println(\"~valor: \" + ~value); // si el valor es positivo, le resta el valor a 0, si es negativo lo suma a 0\n    }\n\n    public static void aritmeticos(int a, int b) {\n        // Operadores aritmeticos\n        System.out.println(\"------ Operadores aritmeticos.\");\n        System.out.println(\"a: \" + a + \", b: \" + b);\n        System.out.println(\"a + b = \" + (a + b)); // realizar la suma a + b\n        System.out.println(\"a - b = \" + (a - b)); // realiza la resta a - b\n        System.out.println(\"a * b = \" + (a * b)); // realiza la multiplicacion a * b\n        System.out.println(\"a / b = \" + (a / b)); // realiza la division a / b\n        System.out.println(\"a % b = \" + (a % b)); // realiza la operación módulo a % b\n    }\n\n    public static void cambioShift(int value, int power) {\n        // Operadores de shift o cambio\n        System.out.println(\"------ Operadores shift o de cambio.\");\n        System.out.println(\"Valor: \" + value + \", potencia: \" + power);\n        System.out.println(\"valor << potencia: \" + (value << power)); // multiplica el valor por 2 elveado a la potencia\n        System.out.println(\"valor >> potencia: \" + (value >> power)); // divide el valor entre 2 elveado a la potencia\n        System.out.println(\"valor >>> potencia: \" + (value >>> power)); // divide el valor entre 2 elveado a la potencia, sin considerar el signo\n    }\n\n    public static void relacionales(int a, int b) {\n        // Operadores relacionales de comparación\n        System.out.println(\"------ Operadores relacionales.\");\n        System.out.println(\"a: \" + a + \", b: \" + b);\n        System.out.println(\"¿a < b? \" + (a < b)); // Verifica si el valor a es menor que el valor b\n        System.out.println(\"¿a > b? \" + (a > b)); // Verifica si el valor a es mayor que el valor b\n        System.out.println(\"¿a <= b? \" + (a <= b)); // Verifica si el valor a es menor o igual al valor b\n        System.out.println(\"¿a >= b? \" + (a >= b)); // Verifica si el valor a es mayor o igual al valor b\n        String cadena = \"Esto es un objeto, instancia de la clase String.\";\n        System.out.println(\"cadena: \" + cadena);\n        System.out.println(\"¿cadena es una instancia de la clase String? \" + (cadena instanceof String)); // Verifica si el objeto es una instancia de cierta clase\n        // Operadores relacionales de igualdad\n        System.out.println(\"¿a == b? \" + (a == b)); // Verifica si el valor a es igual al valor b\n        System.out.println(\"¿a != b? \" + (a != b)); // Verifica si el valor a es diferente al valor b\n    }\n\n    public static void bitAbit() {\n        // Operadores bitwise\n        System.out.println(\"------ Operadores bitwise.\");\n        System.out.println(\"false & true : \" + (false&true)); // Bitwise And, verifica ambos valores sin importar si el primer valor es falso o verdadero\n        System.out.println(\"true | true : \" + (true|true)); // Bitwise Or inclusivo, verifica ambos valores sin importar si el primer valor es falso o verdadero\n        System.out.println(\"true ^ false : \" + (true^false)); // Bitwise Or exclusivo o XOR, verifica si los valores son diferentes\n    }\n\n    public static void logicos() {\n        // Operadores lógicos\n        System.out.println(\"------ Operadores logicos.\");\n        System.out.println(\"false && true: \" + (false&&true)); // Logic And, si el primer valor es falso ya no comprueba el segundo valor\n        System.out.println(\"true || false: \" + (true||false)); // Logic Or, si el primer valor es verdadero ya no comprueba el segundo valor\n    }\n\n    public static String ternario(boolean bool) {\n        // Operador ternario\n        System.out.println(\"------ Operador ternario.\");\n        String verdadero = \"Este es el resultado verdadero de un operador ternario.\";\n        String falso = \"Este es el resultado falso de un operador ternario.\";\n        return bool?verdadero:falso; // Es una forma simplificada de un condicional if - else\n        // Se evalua la condición a la izquierda del signo de interrogación\n        // Si se cumple la condición se ejecuta el código a la izquierda de los dos puntos\n        // Si no se cumple la condición se ejcuta el código a la derecha de los dos puntos\n    }\n\n    public static void asignacion() {\n        // Operadores de asignación\n        System.out.println(\"-> Operadores de asignacion.\");\n        int a;\n        boolean b;\n        System.out.println(\"a = 5, a = \" + (a = 5)); // Le asigna el valor de 5 a la variable a\n        System.out.println(\"a += 2, a = \" + (a += 2)); // Le suma 2 a la variable a y el resultado lo asigna a si misma\n        System.out.println(\"a -= 10, a = \" + (a -= 10)); // Le resta 10 a la variable a y el resultado lo asigna a si misma\n        System.out.println(\"a *= 4, a = \" + (a *= 4)); // Multiplica por 4 a la variable a y el resultado lo asigna a si misma\n        System.out.println(\"a /= 3, a = \" + (a /= 3)); // Divide entre 3 a la variable a y el resultado lo asigna a si misma\n        System.out.println(\"a %= 6, a = \" + (a %= 6)); // Realiza la operación módulo de a módulo 6 y el resultado lo asigna a si misma\n        System.out.println(\"a <<= 2, a = \" + (a<<=2)); // Multiplica a por 2 elevado a la 2 y el resultado lo asigna a si misma\n        System.out.println(\"a >>= 2, a = \" + (a>>=2)); // Divide a entre 2 elevado a la 2 y el resultado lo asigna a si misma\n        System.out.println(\"a >>>= 2, a = \" + (a>>>=2)); // Divide a entre 2 elevado a la 2, sin tener en cuenta el signo, y el resultado lo asigna a si misma\n        System.out.println(\"b = true \" + (b = true)); // Asigna el valor true a la variable b\n        System.out.println(\"b &= b, b = \" + (b &= b)); // Verifica el valor de b & b, y el resultado lo asigna a si misma\n        System.out.println(\"b ^= b, b = \" + (b ^= b)); // Verifica el valor de b ^ b, y el resultado lo asigna a si misma\n        System.out.println(\"b |= b, b = \" + (b |= b)); // Verifica el valor de b | b, y el resultado lo asigna a si misma\n    }\n    \n    public static void extra() {\n        for(int i = 10; i < 56; i++) {\n            if((i != 16) && (i % 3 != 0) && (i % 2 == 0)) {\n                System.out.println(i);\n            }\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/JesusAntonioEEscamilla.java",
    "content": "/** #01 - Java -> Jesus Antonio Escamilla */\n\npublic class JesusAntonioEEscamilla {\n    public static void main(String[] args) {\n    //---EJERCIÓ---\n    System.out.println(\"---EJERCIÓ---\\n\");\n\n    /*\n     * Tipos de Operadores\n     */\n\n        /*\n         * ARITMÉTICAS\n         * Se utilizan para realizar cálculos matemáticos.\n         */\n\n        int a = 10;\n        int b = 5;\n\n        System.out.println(\"---Operaciones Aritméticas---\\n\");\n\n        System.out.println(\"a:\" + a);\n        System.out.println(\"b:\" + b);\n        System.out.println(\"\\nSuma: a + b = \" + (a + b)); // Suma\n        System.out.println(\"Resta: a - b = \" + (a - b)); // Resta\n        System.out.println(\"Multiplicar: a * b = \" + (a * b)); // Multiplicar\n        System.out.println(\"Exponente a ^ b\" + (a ^ b));\n        System.out.println(\"Division: a / b = \" + (a / b)); // Division\n        System.out.println(\"Modulo: a % b =\" + (a % b)); // Modulo\n\n        /*\n         * ASIGNACIONES\n         * Se utilizan para asignar valores a las variables.\n         */\n\n        System.out.println(\"\\n---Operaciones Asignación---\\n\");\n        \n        int c = 10; // Asignación simple\n        c += 5; // Suma y asigna\n        c -= 3; // Resta y asigna\n        c *= 2; // Multiplica y asigna\n        c /= 4; // Divide y asigna\n        c %= 3; // Calcula el modulo y asigna\n        System.err.println(\"Asignación simple: c = 5 - 10\");\n        System.err.println(\"Suma y asigna: c += 5 - 15\");\n        System.err.println(\"Suma y asigna: c -= 3 - 12\");\n        System.err.println(\"Suma y asigna: c *= 2 - 24\");\n        System.err.println(\"Suma y asigna: c /= 4 - 6\");\n        System.err.println(\"Suma y asigna: c %= 3 - 0\");\n        System.out.println(\"Resultado de Agnación: \" + c);\n\n        /*\n         * RELACIONALES\n         * Se utilizan para comparar dos valores.\n         */\n\n        System.out.println(\"\\n---Operaciones Relacional---\\n\");\n\n        int x = 10;\n        int y = 20;\n\n        System.out.println(\"Es Igual: x == y - \" + (x == y));\n        System.out.println(\"Es Diferente: x != y - \" + (x != y));\n        System.out.println(\"Es Mayor: x > y - \" + (x > y));\n        System.out.println(\"Es Menor: x < y - \" + (x < y));\n        System.out.println(\"Es Mayor o Igual: x >= y - \" + (x >= y));\n        System.out.println(\"Es Menor o Igual: x <= y - \" + (x <= y));\n\n        /*\n         * LÓGICOS\n         * Se utilizan para combinar expresiones booleanas.\n         */\n\n        System.out.println(\"\\n---Operaciones Lógicos---\\n\");\n\n        boolean i = true;\n        boolean k = false;\n\n        System.out.println(\"Operador i && k: \" + (i && k));\n        System.out.println(\"Operador i || k: \" + (i || k));\n        System.out.println(\"Operador !k: \" + (!k));\n\n        /*\n         * UNARIAS\n         * Se aplican a un solo operando.\n         */\n\n        System.out.println(\"\\n---Operaciones Unarias---\\n\");\n        \n        int d = 5;\n        System.out.println(\"Incremento: \" + d++);\n        System.out.println(\"Decremento: \" + d--);\n        System.out.println(\"Negativo: \" + (-d));\n        System.out.println(\"Positivo: \" + (+d));\n\n        /*\n         * BIT A BIT\n         * Se utilizan para realizar operaciones a nivel de bits.\n         */\n\n        System.out.println(\"\\n---Operaciones Unarias---\\n\");\n\n        int e = 6;\n        int f = 3;\n        System.out.println(\"AND bir a bit: e & f - \" + (e & f));\n        System.out.println(\"OR bir a bit: e | f - \" + (e | f));\n        System.out.println(\"XOR bir a bit: e ^ f - \" + (e ^ f));\n        System.out.println(\"Complemento bir a bit: ~e - \" + (~e));\n        System.out.println(\"Desplazamiento a la izquierda: e << f - \" + (e << f));\n        System.out.println(\"Desplazamiento a la derecha: e >> f - \" + (e >> f));\n        System.out.println(\"Desplazamiento a la derecha sin singo: e >>> f - \" + (e >>> f));\n\n        \n    /*\n    * Estructuras de controles\n    */\n\n        /*\n         * IF - ELSE If - ELSE\n         */\n        System.out.println(\"\\n---Estructuras de controles---\\n\");\n\n        System.out.println(\"\\nSentiría IF-ELSE IF-ELSE\");\n        int num = 10;\n        if (num > 0) {\n            System.out.println(\"El número es Positivo\");\n        } else if (num < 0) {\n            System.out.println(\"El número es Negativo\");\n        } else {\n            System.out.println(\"El número es Cero\");\n        }\n        \n        /*\n         * SWITCH\n         */\n        System.out.println(\"\\nSentiría SWITCH\");\n        int day = 3;\n        switch (day) {\n            case 1:\n                System.out.println(\"Lunes\");\n                break;\n            case 2:\n                System.out.println(\"Martes\");\n                break;\n            case 3:\n                System.out.println(\"Miércoles\");\n                break;\n            default:\n                System.out.println(\"Otro dia\");\n                break;\n        }\n\n        /*\n         * FOR\n         */\n        System.out.println(\"\\nBucle FOR\");\n        for (int j = 0; j < 5; j++) {\n            System.out.println(\"Iteración: \" + j);\n        }\n\n        /*\n         * WHILE\n         */\n        System.out.println(\"\\nBucle WHILE\");\n        int g = 0;\n        while (g < 5) {\n            System.out.println(\"Iteración: \" + g);\n            g++;\n        }\n\n        /*\n         * DO-WHILE\n         */\n        System.out.println(\"\\nBucle DO-WHILE\");\n        int l = 0;\n        do {\n            System.out.println(\"Iteración: \" + l);\n            l++;\n        } while (l < 5);\n\n        /*\n         * TRY-CATCH-FINALLY\n         */\n        System.out.println(\"\\nBucle TRY-CATCH-FINALLY\");\n        try {\n            int division = 10 / 0;\n            System.out.println(division);\n        } catch (ArithmeticException error) {\n            System.out.println(\"Error: Division por cero\");\n        } finally{\n            System.out.println(\"Este bloque se ejecuta siempre\");\n        }\n\n    /**-----DIFICULTAD EXTRA-----*/\n\n        System.out.println(\"\\n-----EXTRA-----\\n\");\n\n        for(int m = 10; m < 55; m++){\n            if ((m % 2 == 0) && (m != 16) && (m % 3 == 0)) {\n                System.out.println(m);\n            }\n        }\n\n    /**-----DIFICULTAD EXTRA-----*/\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/JesusEs1312.java",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\nimport java.util.List;\n\npublic class JesusEs1312 {\n\n        public static void main(String[] args) {\n                int a = 10;\n                int b = 5;\n                String aString = String.valueOf(a);\n                String bString = String.valueOf(b);\n\n                // --- Operadores Aritmeticos\n                System.out.println(\"===Operadores Aritmeticos===\");\n                // Suma\n                System.out.println(\n                                \"Suma de \".concat(aString)\n                                                .concat(\" + \")\n                                                .concat(bString)\n                                                .concat(\": \")\n                                                .concat(String.valueOf(a + b)));\n                // Resta\n                System.out.println(\n                                \"Resta de \".concat(aString)\n                                                .concat(\" - \")\n                                                .concat(bString)\n                                                .concat(\": \")\n                                                .concat(String.valueOf(a - b)));\n                // Multiplicación\n                System.out.println(\n                                \"Multiplicación de \".concat(aString)\n                                                .concat(\" * \")\n                                                .concat(bString)\n                                                .concat(\": \")\n                                                .concat(String.valueOf(a * b)));\n                // División\n                System.out.println(\n                                \"División de \".concat(aString)\n                                                .concat(\" / \")\n                                                .concat(bString)\n                                                .concat(\": \")\n                                                .concat(String.valueOf(a / b)));\n                // Residuo\n                System.out.println(\n                                \"Residuo de \".concat(aString)\n                                                .concat(\" % \")\n                                                .concat(bString)\n                                                .concat(\": \")\n                                                .concat(String.valueOf(a % b)));\n                // Exponenciación\n                double exponente = Math.pow(b, a);\n                System.out.println(\"Exponenciación de b a la a: \".concat(String.valueOf(exponente)));\n\n                // --- Operadores de Igualdad o Relación\n                System.out.println(\"===Operadores de igualdal o Relelación===\");\n                // Igual a\n                System.out.println(\n                                aString.concat(\" == \")\n                                                .concat(bString)\n                                                .concat(\": \")\n                                                .concat(String.valueOf(aString.equals(bString))));\n                // Diferente de\n                System.out.println(\n                                aString.concat(\" != \")\n                                                .concat(bString)\n                                                .concat(\": \")\n                                                .concat(String.valueOf(!aString.equals(bString))));\n                // Mayor que\n                System.out.println(\n                                aString.concat(\" > \")\n                                                .concat(bString)\n                                                .concat(\": \")\n                                                .concat(String.valueOf(a > b)));\n                // Menor que\n                System.out.println(\n                                aString.concat(\" < \")\n                                                .concat(bString)\n                                                .concat(\": \")\n                                                .concat(String.valueOf(a < b)));\n                // Mayor o igual que\n                System.out.println(\n                                aString.concat(\" >= \")\n                                                .concat(bString)\n                                                .concat(\": \")\n                                                .concat(String.valueOf(a >= b)));\n                // Menor o igual que\n                System.out.println(\n                                aString.concat(\" <= \")\n                                                .concat(bString)\n                                                .concat(\": \")\n                                                .concat(String.valueOf(a <= b)));\n                // --- Operadores Aritméticos Incrementales\n                System.out.println(\"===Operadores Aritméticos Incrementales===\");\n                // Incremento\n                System.out.println(\n                                \"Incremento de ++\".concat(aString)\n                                                .concat(\": \")\n                                                .concat(String.valueOf(++a)));\n                // Decremento\n                System.out.println(\n                                \"Decremento de --\".concat(String.valueOf(a))\n                                                .concat(\": \")\n                                                .concat(String.valueOf(--a)));\n\n                // --- Operadores Aritméticos Combinados\n                System.out.println(\"===Operadores Aritméticos Combinados===\");\n                // Suma combinada\n                System.out.println(\n                                \"Suma combinada \".concat(aString)\n                                                .concat(\"+=\")\n                                                .concat(bString)\n                                                .concat(\": \")\n                                                .concat(String.valueOf(a += b)));\n                // Resta combinada\n                System.out.println(\n                                \"Resta combinada \".concat(aString)\n                                                .concat(\"-=\")\n                                                .concat(bString)\n                                                .concat(\": \")\n                                                .concat(String.valueOf(a -= b)));\n                // Producto combinado\n                System.out.println(\n                                \"Suma combinada \".concat(aString)\n                                                .concat(\"*=\")\n                                                .concat(bString)\n                                                .concat(\": \")\n                                                .concat(String.valueOf(a *= b)));\n                // División combinada\n                System.out.println(\n                                \"Suma combinada \".concat(aString)\n                                                .concat(\"/=\")\n                                                .concat(bString)\n                                                .concat(\": \")\n                                                .concat(String.valueOf(a /= b)));\n                // Residuo combinada\n                System.out.println(\n                                \"Residuo combinado \".concat(aString)\n                                                .concat(\"%=\")\n                                                .concat(bString)\n                                                .concat(\": \")\n                                                .concat(String.valueOf(a %= b)));\n                a = 5;\n\n                // --- Operadores Lógicos\n                // Negación NOT\n                System.out.println(\"===Operadores Lógicos===\");\n                System.out.println(\n                                \" !(\".concat(bString)\n                                                .concat(\"==\")\n                                                .concat(aString)\n                                                .concat(\"): \")\n                                                .concat(String.valueOf(!(a == b))));\n                // OR\n                System.out.println(\"(5==10) || (10 > 5): \".concat(String.valueOf((a == b) || (b > a))));\n\n                // AND\n                System.out.println(\"(5==10) && (10 > 5): \".concat(String.valueOf((a == b) && (b > a))));\n\n                // --- Operador condicional o ternario\n                System.out.println(\"===Operador condicional o ternario===\");\n                System.out.println(\"(10 > 5): \".concat(b > a ? \"true\" : \"false\"));\n\n                // --- Operadores de Bit\n                System.out.println(\"===Operadores de Bit===\");\n                // Negación\n                System.out.println(\"Negación (~5): \".concat(String.valueOf(~a)));\n                // Suma lógica binaria\n                System.out.println(\"Suma binaria (5|10): \".concat(String.valueOf(a | b)));\n                // Suma lógica exclusiva\n                System.out.println(\"Suma exclusiva (5^10): \".concat(String.valueOf(a ^ b)));\n                // Producto lógico binario\n                System.out.println(\"Producto lógico (5&10): \".concat(String.valueOf(a & b)));\n                // Desplaza a la izquierda los bits\n                System.out.println(\"Desplaza a la izquierda los bits (10 << 5): \".concat(String.valueOf(b << a)));\n                // Desplaza a la derecha los bits\n                System.out.println(\"Desplaza a la izquierda los bits (10 >> 5): \".concat(String.valueOf(b >> a)));\n\n                // --- Estructuras de Control\n                // if, else if, else\n                System.out.println(\"===Estructura de control if, else if y else===\");\n                if (b > a) {\n                        System.out.println(\"b es mayor que a\");\n                } else if (a == b) {\n                        System.out.println(\"a es igual a b\");\n                } else {\n                        System.out.println(\"a es mayor que b\");\n                }\n\n                // For\n                System.out.println(\"===Estructura de control (for)===\");\n                String[] arrayOne = { \"hola \", \"mundo \", \"desde \", \"Java\" };\n                for (int i = 0; i < arrayOne.length; i++) {\n                        System.out.print(arrayOne[i]);\n                }\n                System.out.println(\"\");\n                // while\n                System.out.println(\"===Estructura de control (While)===\");\n                int i = 0;\n                while (i < arrayOne.length) {\n                        System.out.print(arrayOne[i]);\n                        i++;\n                }\n                System.out.println(\"\");\n                // Do while\n                System.out.println(\"===Estructura de control (do while)===\");\n                do {\n                        System.out.println(arrayOne[i - 1]);\n                } while (i < arrayOne.length);\n                // switch\n                System.out.println(\"===Estructura de control (switch)===\");\n                switch (a) {\n                        case 5:\n                                System.out.println(\"Entro en caso 5\");\n                                break;\n                        case 10:\n                                System.out.println(\"Entro en caso 10\");\n                                break;\n                        default:\n                                System.out.println(\"No entro en ningun caso \" + String.valueOf(a));\n                                break;\n                }\n\n                // ---Ejercicio Extra\n                System.out.println(\"===Ejercicio Extra===\");\n                int[] arraySecond = new int[46];\n                int k = 10;\n                for (int j = 0; j < arraySecond.length; j++) {\n                        arraySecond[j] = k;\n                        k++;\n                }\n\n                for (int l : arraySecond) {\n                        if ((l % 2 == 0) && (l % 3 != 0) && (l != 16)) {\n                                System.out.println(l);\n                        }\n                }\n        }\n\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/JimsimroDev.java",
    "content": "public class JimsimroDev {\n  public static void main(String[] args) {\n\n    // Operadores aritmeticos\n    System.out.println(\"Operadores aritmeticos\");\n    System.out.printf(\"Suma 12 + 12 = %d\", (12 + 12));\n    System.out.printf(\"\\n Resta 12 - 10 = %d\", (12 - 10));\n    System.out.printf(\"\\n Multiplicación 2 * 5 = %d\", (2 * 5));\n    System.out.printf(\"\\n División 24 / 2 = %d\", (24 / 2));\n    System.out.println(\"\\nResiduo 10 % 6 = \" + (10 % 6));\n    System.out.println(\"Residuo 10^6 = \" + (10 ^ 2));\n\n    // Operadores De Asignacion\n    System.out.println(\"Operadores de asignación\");\n    int numero = 20;// asignacion\n    System.out.println(numero);\n    numero += 1; // suma y asignacion\n    System.out.println(numero);\n    numero -= 1; // resta y asignacion\n    System.out.println(numero);\n    numero *= 2; // Multiplicación y asignacion\n    System.out.println(numero);\n    numero %= 1; // modulo y asignacion\n    System.out.println(numero);\n    numero /= 2;// División y asignacion\n    System.out.println(numero);\n\n    // Operadores de comparacion\n    System.out.println(\"Operadores de comparacion\");\n    System.out.println(\"Igualdad: 10 == 3\" + (10 == 3));\n    System.out.println(\"Desigualdad 10 != 3 \" + (10 != 3));\n    System.out.println(\"Mayor que 10 > 3 \" + (10 > 3));\n    System.out.println(\"Menor que 10 < 3 \" + (10 < 3));\n    System.out.println(\"Menor igual que 10 <= 10 \" + (10 <= 10));\n    System.out.println(\"Mayor igual que 10 >= 3 \" + (10 >= 3));\n\n    // Operadore de pertenencia\n    System.out.println(\"Operador de pertenencia\");\n    System.out.println(\"jimsimroDev\".contains(\"j\"));\n    System.out.println(!\"jimsimroDev\".contains(\"a\"));\n\n    // Operadores logicos\n    System.out.println(\"Operadores Lógicos\");\n    // Operador \"and\" se representa pro && ambas afirmaciones deben ser verdaderas\n    int num = 10;\n    int num1 = 12;\n    if (num == 10 && num1 == 12) {\n      System.out.println(true);\n    } else {\n      System.out.println(false);\n    }\n    // Operador \"or\" se representa por || y se evalua como tru si alguna de las\n    // afirmaciones es verdadera es decir que solo es falso si ambas afirmaciones\n    // son falsas\n    if (num == 10 || num1 == 23) {\n      System.out.println(true);\n    } else {\n      System.out.println(false);\n    }\n\n    // Operador Lógico \"not\" se representa ! es la espresion negada es decir si la\n    // exprexion es true\n    // el Operador devuelve false\n    boolean a = true;\n    boolean b = false;\n    System.out.println(!a);// devuelve false\n    System.out.println(!b);// devuelve true\n\n    // Operadores Lógicos binarios\n    System.out.println(\"Operadores binarios\");\n    // Operador \"and binaro\" se representa por &\n\n    System.out.println(\"10 & 12 \" + (num & num1));// salida 8 por que analiza bit por bit\n\n    // Operador \"or binario\" se representa por |\n    System.out.println(\"10 | 12 \" + (num | num1));// salida 14 por que analiza bit por bit\n\n    // Operador \"not binario\" se representa por ~\n    System.out.println(\"not ~ \" + ~num);\n\n    // Corrimiento de bits\n    // << shift left Corrimiento a l izquierda\n    System.out.println(-15 >> 3);\n    System.out.println(-15 >>> 3);\n    // >> shift right Corrimiento al a derecha\n\n    // Condicinales\n    String name = \"JimsimroDev\";\n    if (name.equals(\"JimsimroDev\")) {\n      System.out.println(\"Mi nombre es JimsimroDev \");\n    } else if (name.equals(\"jhoan\")) {\n      System.out.println(\"My nombre es Jhoan\");\n    } else {\n      System.out.println(\"Mu nombre no es JimsimroDev ni jhoan\");\n    }\n\n    // Iterativas\n    for (int i = 0; i < 15; i++) {\n      System.out.println(i);\n    }\n    int i = 0;\n    while (i <= 10) {\n      System.out.println(i);\n      i++;\n    }\n    // Manejo de excepcines\n    try {\n      System.out.println(10 / 0);\n    } catch (Exception e) {\n      System.out.println(\"Se ha producido un error\");\n    } finally {\n      System.out.println(\"Ha finalizado correctamente\");\n    }\n    int inicio = 10;\n    int fin = 55;\n    while (inicio <= fin) {\n      if (inicio % 3 != 0 && inicio % 2 == 0 && inicio != 16) {\n        System.out.println(inicio);\n      }\n      inicio++;\n    }\n  }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/Jony-English22.java",
    "content": "public class Jony_English22 {\n\n    public static void main(String[] args) {\n\n        //Operadores Artmeticos\n        System.out.println(\"10 + 4 = \" + (10 + 4));\n        System.out.println(\"10 - 4 = \" + (10 - 4));\n        System.out.println(\"10 * 4 = \" + (10 * 4));\n        System.out.println(\"10 / 4 = \" + (10 / 4));\n        System.out.println(\"10 % 4 = \" + (10 % 4));\n\n        //Operadores logicos\n        boolean x = true;\n        boolean y = false;\n        System.out.println(\"AND Lógico: \" + (x && y));\n        System.out.println(\"OR Lógico: \" + (x || y));\n        System.out.println(\"NOT Logico: \" + (!x));\n\n        //Operador de asignación\n        int num = 15;\n        System.out.println(num);\n        num += 5;\n        System.out.println(num);\n        num -= 5;\n        System.out.println(num);\n        num *= 2;\n        System.out.println(num);\n        num /= 2;\n        System.out.println(num);\n        num %= 3;\n        System.out.println(num);\n\n        //Operadores de comparación\n        System.out.println(\"10 > 5 = \" + (10 > 5));\n        System.out.println(\"10 < 5 = \" + (10 < 5));\n        System.out.println(\"5 >= 3 = \" + (5 >= 3));\n        System.out.println(\"5 <= 3 = \" + (5 <= 3));\n        System.out.println(\"10 == 20 = \" + (10 == 20));\n        System.out.println(\"20 != 10 = \" + (20 != 10));\n\n        //Operadores unarios\n        int valor = 3;\n        System.out.println(+valor);\n        System.out.println(-valor);\n\n        //Operadores de incremento y decremento\n        System.out.println(++num);\n        System.out.println(--num);\n\n        //Operadores de bits\n        int a = 5;  // Representación binaria: 0101\n        int b = 3;  // Representación binaria: 0011\n        System.out.println(\"AND a nivel de bits \" + (a & b));\n        System.out.println(\"OR a nivel de bits \" + (a | b));\n        System.out.println(\"XOR a nivel de bits \" + (a ^ b));\n        System.out.println(\"NOT a nivel de bits \" + (~a));\n        System.out.println(\"Desplazamiento a la izquierda: \" + (a << 2));\n        System.out.println(\"Desplazamiento a la derecha: \" + (a >> 2));\n        System.out.println(\"Desplazamiento a la derecha sin signo: \" + (a >>> 2));\n\n        /*\n          Estructuras de control\n         */\n\n        for (int i = 1; i <= 5; i++) {\n            System.out.println(i);\n        }\n\n        int j = 11;\n\n        if (j > 5) {\n            System.out.println(\"Hola Java\");\n        } else {\n            System.out.println(\"Hola Mundo\");\n        }\n\n        String luz = \"Amarillo\";\n\n        if (luz == \"Verde\") {\n            System.out.print(\"Puede Continiue\");\n        } else if (luz == \"Amarillo\") {\n            System.out.println(\"Alto parcial\");\n        } else {\n            System.out.println(\"Alto total\");\n        }\n\n        int n = 2;\n\n        switch(n) {\n            case 0:\n                System.out.println(\"n es cero.\");\n                break;\n            case 1:\n                System.out.println(\"n es uno.\");\n                break;\n            case 2:\n                System.out.println(\"n es dos.\");\n                break;\n            case 3:\n                System.out.println(\"n es tres.\");\n                break;\n            default:\n                System.out.println(\"n es mayor a tres.\");\n        }\n\n        int contador = 1;\n        while (contador <= 5) {\n            System.out.println(contador);\n            contador++;\n        }\n\n        int m = 1;\n        do {\n            System.out.println(m);\n            m++;\n        } while (m <= 3);\n\n        try {\n            System.out.println(10/ 0);\n        } catch (ArithmeticException e) {\n            System.out.println(\"Error\");\n        } finally {\n            System.out.println(\"Continue con el programa\");\n        }\n\n        /*\n         * Dificultad Extra:\n         * Crea un programa que imprima por consola todos los números comprendidos\n         * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n         */\n\n        for (int i = 10; i <= 55; i++) {\n            if ((i % 2 == 0 && i == 55) || (i != 16 && i % 3 != 0)) {\n                System.out.println(i);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/JoseEsmil04.java",
    "content": "public class JoseEsmil04 {\n    public static void main(String[] args) {\n        int num1 = 45;\n        int num2 = 13;\n        boolean a;\n        boolean b;\n\n        System.out.println(\"*-*-* Operadores Aritmeticos *-*-*\\n\");\n        // Suma\n        System.out.println(\"Suma (+): \" + (num1 + num2));\n        // Resta\n        System.out.println(\"Resta (-): \" + (num2 - num1));\n        // Multiplicacion\n        System.out.println(\"Multiplicacion (*): \" + (num1 * num2));\n        // Division\n        System.out.println(\"Division (/): \" + (num1 / num2));\n        // Resto\n        System.out.println(\"Resto (%): \" + (num1 % num2));\n\n        System.out.println(\"\\n*-*-* Operadores de Asignacion *-*-*\\n\");\n        // Asignacion basico\n        num1 = 500;\n        num2 = 1000;\n        System.out.println(\"Despues de usar la asignacion(=) el num1: \" + num1);\n        // Asignacion compuesto con Suma\n        System.out.println(\"Asignacion con suma (+=): \" + (num1 += num2));\n        // Asignacion compuesto con Resta\n        System.out.println(\"Asignacion con resta (-=): \" + (num1 -= num2));\n        // Asignacion compuesto con Multiplicacion\n        System.out.println(\"Asignacion con multiplicacion (*=): \" + (num2 *= num1));\n        // Asignacion compuesto con Division\n        System.out.println(\"Asignacion con division (/=): \" + (num2 /= num1));\n        // Asignacion compuesto con Resto\n        System.out.println(\"Asignacion con resto (%=): \" + (num1 %= num2));\n\n        System.out.println(\"\\n*-*-* Operadores de Identidad *-*-*\\n\");\n        // Operador de igualdad\n        System.out.println(\"Igualdad: \" + (\"Esmil\" == \"Esmil\"));\n        // Operador de desigualdad\n        System.out.println(\"Desigualdad: \" + (23 != 44));\n\n        System.out.println(\"\\n*-*-* Operadores Logicos *-*-*\\n\");\n        a = true;\n        b = true;\n        // Operador AND\n        System.out.println(\"AND(&&): \" + (a && b));\n        // Operador OR\n        a = true;\n        b = false;\n        System.out.println(\"OR(||): \" + (a || b));\n        // Operador NOT\n        System.out.println(\"NOT(!): \" + (!b));\n\n        System.out.println(\"\\n*-*-* Operadores de Comparacion *-*-*\\n\");\n        num1 = 70;\n        num2 = 43;\n        // Mayor que\n        System.out.println(\"Mayor que: \" + (num1 > num2));\n        // Menor que\n        System.out.println(\"Menor que: \" + (num2 < num1));\n        // Mayor o Igual que\n        System.out.println(\"Mayor o igual que: \" + (num1 >= num1));\n        // Menor o Igual que\n        System.out.println(\"Menor o igual que: \" + (num2 <= num1));\n\n        System.out.println(\"\\n*-*-* Operadores de Bits *-*-*\\n\");\n        int num3 = 5; // 0000 0101\n        int num4 = 3; // 0000 0011\n        // AND bit\n        System.out.println(\"AND bit a bit: \" + (num3 & num4));\n        // OR bit\n        System.out.println(\"OR bit a bit: \" + (num3 | num4));\n        // NOT bit\n        System.out.println(\"NOT bit a bit de m: \" + (~num4));\n\n        System.out.println(\"\\n*-*-* Estructuras de control *-*-*\\n\");\n        // Condicionales if, else if, else\n        num1 = 100;\n        num2 = 99;\n        num3 = 101;\n\n        if (num1 > num2) {\n            System.out.println(num1 + \" es mayor que \" + num2);\n        } else if (num2 <= num3){\n            System.out.println(num2 + \" a es menor o igual que \" + num3);\n        } else {\n            System.out.println(\"Si lo de arriba no se cumple, llegamos aqui!\");\n        }\n\n        // Condicional switch\n        int opcion = 2;\n\n        switch (opcion) {\n            case 1:\n                System.out.println(\"La opción es 1\");\n                break;\n            case 2:\n                System.out.println(\"La opción es 2\");\n                break;\n            case 3:\n                System.out.println(\"La opción es 3\");\n                break;\n            default:\n                System.out.println(\"Opción no válida\");\n        }\n\n        // Iterativa While\n        int vuelta = 0;\n\n        while(vuelta < 5) {\n            System.out.println(\"Vuelta! \" + vuelta);\n\n            vuelta++;\n        }\n\n        // Iterativa for\n        for (int i = 0; i < 10; i++) {\n            System.out.println(\"FOR \" + i);\n        }\n\n        // Excepcion try catch\n        try {\n            int resultado = 10 / 0; // Intenta dividir por cero\n            System.out.println(\"El resultado es: \" + resultado);\n        } catch (ArithmeticException e) {\n            System.out.println(\"Error: División por cero\");\n        }\n\n        // DIFICULTAD EXTRA (opcional):\n        // Crea un programa que imprima por consola todos los números comprendidos\n        // entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n        for(int i = 10; i <= 55; i++) {\n            if(i != 16 && (i % 3 != 0) && (i % 2 == 0)) {\n                System.out.println(i);\n            }\n\n            if(i == 55) System.out.println(i);\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/Josegs95.java",
    "content": "import java.awt.*;\n\npublic class Josegs95 {\n    public static void main(String[] args) {\n        //Operadores\n        //Operadores aritméticos\n\n        int miSuma = 3 + 8; //Suma\n        System.out.println(\"3 + 8 = \" + miSuma);\n\n        int miResta = 17 - 5; //Resta\n        System.out.println(\"17 - 5 = \" + miResta);\n\n        int miMultiplicacion = 2 * 3; //Multiplicación\n        System.out.println(\"2 * 3 = \" + miMultiplicacion);\n\n        int miDivision = 15 / 3; //División\n        System.out.println(\"15 / 3 = \" + miDivision);\n\n        int miModulo = 13 % 2; //Módulo (Resto de la división)\n        System.out.println(\"El módulo de 13 / 2 es \" + miModulo);\n\n        //Operadores de asignación\n        int miEntero = 10;\n        miEntero += 5; //Equivalente a 'miEntero = miEntero + 5;'\n        System.out.println(\"Valor de miEntero: \" + miEntero);\n        miEntero -= 5; //Equivalente a 'miEntero = miEntero - 5;'\n        System.out.println(\"Valor de miEntero: \" + miEntero);\n        miEntero *= 2; //Equivalente a 'miEntero = miEntero * 2;'\n        System.out.println(\"Valor de miEntero: \" + miEntero);\n        miEntero /= 2; //Equivalente a 'miEntero = miEntero / 2;'\n        System.out.println(\"Valor de miEntero: \" + miEntero);\n        miEntero %= 8; //Equivalente a 'miEntero = miEntero % 8;'\n        System.out.println(\"Valor de miEntero: \" + miEntero);\n        miEntero++; // Equivalente a 'miEntero = miEntero + 1;'\n        System.out.println(\"Valor de miEntero: \" + miEntero);\n        miEntero--; // Equivalente a 'miEntero = miEntero - 1;'\n        System.out.println(\"Valor de miEntero: \" + miEntero);\n\n        /*\n        También existe la variante con el operador después del signo igual.\n        Por ejemplo miEntero =+ 5; La diferencia es el orden en el que se hacen las\n        operaciones. Si se usa +=, primero se suma y luego se asigna el valor.\n\n        Para los últimos dos ejemplos, también existe la variante ++miEntero, sumando 1\n        a la variable y, después de usar la variable, asignandola a la variable. Por ejemplo,\n        si miEntero vale 5 y se usa un método calcularCuadrado(int), si se le pasa ++miEntero\n        se le estaría pasando un 6 (y devolvería 36 como resultado) y si se usa miEntero++\n        se le estaría pasando un 5, devolvería 25 y miEntero pasaría a valer 6.\n         */\n\n        //Operadores de comparación\n        int a = 5;\n        int b = 9;\n        System.out.println(\"¿a es > 5?: \" + (a > b)); //Compara si a es mayor que b\n        System.out.println(\"¿a es >= 5?: \" + (a >= b)); //Compara si a es mayor o igual que b\n        System.out.println(\"¿a es < 5?: \" + (a < b)); //Compara si a es menor que b\n        System.out.println(\"¿a es <= 5?: \" + (a <= b)); //Compara si a es menor o igual que b\n        System.out.println(\"¿a es = 5?: \" + (a == b)); //Compara si a es igual que b\n        System.out.println(\"¿a es != 5?: \" + (a != b)); //Compara si a es distinto que b\n\n        //Operadores lógicos\n        boolean bTrue = true;\n        boolean bFalse = false;\n            //Operador AND: Es true si en ambos lados del operador es true, si no devuelve false.\n        System.out.println(\"bTrue && bFalse: \" + (bTrue && bFalse));\n            //Operador OR: Es true si en algunos de los lados del operador es true, si no\n            //devuelve false.\n        System.out.println(\"bTrue || bFalse: \" + (bTrue || bFalse));\n            //Operador NOT: Devuelve el valor contrario; true si el valor es false, si no devuelve false.\n        System.out.println(\"!bTrue: \" + (!bTrue));\n\n        //Operadores de bits\n        int num1 = 10; // 1010\n        int num2 = 6;  // 0110\n            //AND: Pone un 1 si ambos bits son 1, si no pone un 0\n        System.out.println(\"num1 & num2: \" + (num1 & num2)); // 2 -> 0010\n            //OR: Pone un 1 si alguno de los bits son 1, si no pone un 0\n        System.out.println(\"num1 | num2: \" + (num1 | num2)); // 14 -> 1110\n            //XOR: Pone un 1 si ambos bits son diferentes, si no pone un 0\n        System.out.println(\"num1 ^ num2: \" + (num1 ^ num2)); // 12 -> 1100\n            //Complemento: Pone un 1 si en el original vale 0, o 0 si vale 1.\n        System.out.println(\"~num1: \" + (~num1)); // 5 -> 0101\n            //Desplazamiento a la izqda: Desplaza el '1' mas a la izqda varias posiciones a hacia la izqda\n            //rellenando con 0 los huecos\n        System.out.println(\"num2 << 2: \" + (num2 << 2)); // 24 -> 0001 1000\n            //Desplazamiento a la dcha: Desplaza el '1' mas a la izqda varias posiciones a hacia la dcha\n        System.out.println(\"num2 >> 2: \" + (num2 >> 2)); // 1 -> 0001\n            //Desplazamiento a la dcha sin signo: Desplaza el '1' mas a la izqda varias posiciones a hacia\n            //la dcha, obviando el signo\n        System.out.println(\"num2 >>> 2: \" + (num2 >>> 2)); // 1 -> 0001\n\n        //Operadores de objetos\n        String miString = new String(\"Valor de la cadena\"); //El operador 'new' se encarga de crear objetos\n        boolean esString = miString instanceof String; //'instanceof' comprueba si un objeto es de una clase específica\n\n        //Estructuras de control\n\n            //If, else-if, else\n        a = 8;\n        b = 5;\n        if (a > b){\n            //Si a es mayor que b, haz algo...\n        } else if (a < b) { //Se pueden encadenar todos los else-if que se quiera.\n            //Si no se ha cumplido lo anterior, y a es menor que b, haz esto...\n        } else {\n            //Si todo lo anterior no se ha cumplido, haz esto otro...\n        }\n\n            //Operador ternario. Equivalente a if (a>b) -> a, else-> b.\n        int numMayor = a > b ? a : b;\n\n            //Switch-case\n        int diasEnUnMes = 28;\n        switch (diasEnUnMes){\n            case 28, 29:\n                System.out.println(\"El mes es Febrero\");\n                break; //Se usa el break para salir de la estructura de control, en este caso del switch.\n            case 30:\n                System.out.println(\"El mes puede ser Enero, Abril, Junio, Septiembre o Noviembre\");\n                break;\n            case 31:\n                System.out.println(\"El mes puede ser Marzo, Mayo, Julio, Agosto o Diciembre\");\n                break;\n            default:\n                System.out.println(\"No existe ningún mes con esa cantidad de días.\");\n        }\n\n            //Bucle for: Se inicializa una variable, se comprueba la condición, y si es true, se ejecuta el\n            //código. Luego se hace el incremento.\n        for (int i = 0; i < 10; i++){\n            System.out.print(\"El valor de i es \" + i);\n            if (i % 2 == 0){\n                System.out.println(\" y es par\");\n                continue; //Sirve para salir de esta iteración pero no del for, como sería con el break.\n            }\n            System.out.println(\" y es impar\");\n        }\n        //El for puede estar completamente o parcialmente vacio\n        int contador = 0;\n        for (;;){\n            if (contador == 5){\n                System.out.println(\"La variable contador vale: \" + contador + \" y se sale del bucle\");\n                break;\n            }\n            contador++;\n        }\n\n            //Bucle for-each. Sirve para recorrer colecciones. Las colecciones tienen que ser iterables, es decir,\n            //implementar la interfaz 'Iterable'. La clase Array lo hace.S\n        String[] arrayString = {\"Lunes\", \"Martes\", \"Miércoles\", \"Jueves\", \"Viernes\", \"Sábado\", \"Domingo\"};\n        for (String cadena : arrayString){\n            System.out.println(\"Día de la semana: \" + cadena);\n        }\n\n            //Bucle while. Equivalente a for (;expr;){}\n        contador = 0;\n        while (contador < 3){\n            System.out.println(\"La variable contador (\" + contador + \") es menor que 3\");\n            contador++;\n        }\n            //Bucle do-while. Es igual que un while, pero siempre entra una vez, es decir, siempre se ejecuta\n            //lo que hay dentro al menos la primera vez\n        do{\n            System.out.println(\"La variable contador vale \" + contador + \" y ha entrado al bucle\");\n        }while(contador > 1000); //Importante el ';' aquí.\n\n            //Try-catch-finally. Se usa para manejar excepciones. Todas las excepciones derivan de 'Exception'\n        try{\n            System.out.println(\"Introduzca dos números para dividirlos entre sí\");\n            int dividendo = 12;\n            int divisor = 0;\n            int resultado = dividendo / divisor;\n            System.out.println(\"El resultado de \" + dividendo + \"/\" + divisor + \" es \" + resultado);\n        } catch (Exception e) { //Se puede 'atrapar' todos los tipos de excepciones que se quiera.\n            System.out.println(\"Se ha producido un error, abortando la operación\");\n        } finally { //Se ejecuta siempre, salte excepción o no\n            System.out.println(\"¿Quieres seguir dividiendo números?\");\n        }\n\n        retofinal();\n    }\n\n    public static void retofinal(){\n        System.out.print(\"\\nReto: \");\n        for (int i = 10; i < 56; i++){\n            if (i % 2 == 0){\n                if (i % 3 != 0){\n                    if (i != 16){\n                        System.out.print(\"[\" + i + \"]\");\n                    }\n                }\n            }\n        }\n        System.out.println();\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/JuanGuzmanG.java",
    "content": "import java.util.List;\nimport java.util.stream.Collectors;\nimport java.util.stream.IntStream;\n\npublic class JuanGuzmanG {\n\n    public static void main(String args[]) {\n        //arithmetic\n        int additive = 1 + 1;\n        int subtraction = 1 - 1;\n        int multiplication = 1 * 1;\n        float division = 1 / 2;\n        float remainder = 1 / 2;\n        \n        /*\n        Unary\n        + indica valores positivos\n        - indica negativos\n        ++ incremente de 1 en 1\n        -- decrementa de 1 en 1\n\n        */\n        \n        //Operadores logicos\n        /*\n        || or\n        && and\n        ^ xor\n        */\n        \n        //operadores de comparación\n        /*\n        == igual a\n        != distinto\n        > mayor que\n        < menos que\n        => igual o mayor que\n        <= igual o menor que\n        */\n        \n        /*\n        = asignacion\n        += suma el valor asignado a la variable\n        -= resta el valor asignado a la variable\n        int b = 9;\n        b<<=3;\n        System.out.print(b);        \n        */\n        //condicionales\n        int condicion = 1;\n        if(condicion==1){\n            System.out.print(1);\n        } else if(condicion==2){\n            System.out.print(2);\n        } else{\n            System.out.print(\"mas de 2\");\n        }\n        switch (condicion){\n            case 1 -> System.out.print(1);\n            case 2 -> System.out.print(2);\n        }\n        switch (condicion){\n            case 1 -> { \n                System.out.println(1);\n                System.out.println(\"fin\");\n            }\n        }\n        //iterativas\n        System.out.println(\"while:\");\n        int count = 2;\n        while(count<3){\n            count+=1;\n            System.out.println(\"while: \"+ count);\n        }\n        System.out.println(\"===============\");\n        int countdo = 6;\n        do{\n            System.out.println(\"dowhile: \"+ countdo);\n            countdo++;\n        }while(countdo<6);\n        \n        //for\n        System.out.println(\"for:\");\n        int i;\n        for(i=0; i<2;i++){\n            System.out.println(i);\n        }\n        System.out.println(\"foreach:\");\n        int[] numbers = {1,2,3,4,5};\n        for(int num : numbers){\n            System.out.println(num);\n            if(num == 3){\n                break;\n            }\n        }\n        \n        System.out.println(\"try catch:\");\n        double trydivision;\n        try{\n            trydivision = 20/0;\n            System.out.println(trydivision);\n        } catch(ArithmeticException e){\n            System.out.println(\"no se puede dividir por 0\");\n        } finally{\n            System.out.println(\"fin de division\");\n        }\n         \n        System.out.println(\"dificultad extra\");\n        List<Integer> lista = IntStream.rangeClosed(10, 55)\n                .boxed()\n                .collect(Collectors.toList());\n        for(Integer num : lista){\n            if (num % 2 == 0 && num != 16 && num % 3 != 0) {\n              System.out.println(num);\n            }\n        }\n        System.out.println(\"con streams\");\n        IntStream.rangeClosed(10,55)\n                .filter(n -> n % 2 == 0)\n                .filter(n -> n % 3 != 0)\n                .filter(n -> n != 16)\n                .forEach(System.out::println);\n        \n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/Julian98789.java",
    "content": "package MauroDevRetos;\n\npublic class reto_1 {\n    \n        public static void main(String[] args) {\n            // Operadores Aritméticos\n            int a = 10;\n            int b = 3;\n            System.out.println(\"Suma: \" + (a + b));\n            System.out.println(\"Resta: \" + (a - b));\n            System.out.println(\"Multiplicación: \" + (a * b));\n            System.out.println(\"División: \" + (a / b));\n            System.out.println(\"Módulo: \" + (a % b));\n\n            // Operadores Lógicos\n            boolean x = true;\n            boolean y = false;\n            System.out.println(\"AND lógico: \" + (x && y));\n            System.out.println(\"OR lógico: \" + (x || y));\n            System.out.println(\"NOT lógico: \" + (!x));\n\n            // Operadores de Comparación\n            System.out.println(\"Igual: \" + (a == b));\n            System.out.println(\"No igual: \" + (a != b));\n            System.out.println(\"Mayor que: \" + (a > b));\n            System.out.println(\"Menor que: \" + (a < b));\n            System.out.println(\"Mayor o igual que: \" + (a >= b));\n            System.out.println(\"Menor o igual que: \" + (a <= b));\n\n            // Operadores de Asignación\n            int c = 5;\n            c += 3; // c = c + 3\n            System.out.println(\"Suma asignación: \" + c);\n            c -= 2; // c = c - 2\n            System.out.println(\"Resta asignación: \" + c);\n            c *= 4; // c = c * 4\n            System.out.println(\"Multiplicación asignación: \" + c);\n            c /= 3; // c = c / 3\n            System.out.println(\"División asignación: \" + c);\n            c %= 3; // c = c % 3\n            System.out.println(\"Módulo asignación: \" + c);\n\n            // Operadores de Identidad\n            Integer d = Integer.valueOf(5);\n            Integer e = Integer.valueOf(5);\n            System.out.println(\"Igualdad de referencia: \" + (d == e)); // false\n            System.out.println(\"Igualdad de valor: \" + (d.equals(e))); // true\n\n            // Operadores a Nivel de Bits\n            int f = 5; // 0101 en binario\n            int g = 3; // 0011 en binario\n            System.out.println(\"AND a nivel de bits: \" + (f & g)); // 0001\n            System.out.println(\"OR a nivel de bits: \" + (f | g)); // 0111\n            System.out.println(\"XOR a nivel de bits: \" + (f ^ g)); // 0110\n            System.out.println(\"Complemento a nivel de bits: \" + (~f)); // 1010 (en complemento a dos)\n            System.out.println(\"Desplazamiento a la izquierda: \" + (f << 1)); // 1010\n            System.out.println(\"Desplazamiento a la derecha: \" + (f >> 1)); // 0010\n            System.out.println(\"Desplazamiento a la derecha sin signo: \" + (f >>> 1)); // 0010\n\n            // Estructuras Condicionales\n            if (a > b) {\n                System.out.println(\"a es mayor que b\");\n            } else {\n                System.out.println(\"a no es mayor que b\");\n            }\n\n            int dia = 3;\n            switch (dia) {\n                case 1:\n                    System.out.println(\"Lunes\");\n                    break;\n                case 2:\n                    System.out.println(\"Martes\");\n                    break;\n                case 3:\n                    System.out.println(\"Miércoles\");\n                    break;\n                case 4:\n                    System.out.println(\"Jueves\");\n                    break;\n                case 5:\n                    System.out.println(\"Viernes\");\n                    break;\n                case 6:\n                    System.out.println(\"Sábado\");\n                    break;\n                case 7:\n                    System.out.println(\"Domingo\");\n                    break;\n                default:\n                    System.out.println(\"Día inválido\");\n                    break;\n            }\n\n            // Estructuras Iterativas\n            // for loop\n            for (int i = 0; i < 5; i++) {\n                System.out.println(\"for loop: \" + i);\n            }\n\n            // while loop\n            int j = 0;\n            while (j < 5) {\n                System.out.println(\"while loop: \" + j);\n                j++;\n            }\n\n            // do-while loop\n            int k = 0;\n            do {\n                System.out.println(\"do-while loop: \" + k);\n                k++;\n            } while (k < 5);\n\n            // foreach loop\n            int[] array = { 1, 2, 3, 4, 5 };\n            for (int num : array) {\n                System.out.println(\"foreach loop: \" + num);\n            }\n\n            // Manejo de Excepciones\n            try {\n                int resultado = 10 / 0;\n                System.out.println(\"Resultado: \" + resultado);\n            } catch (ArithmeticException i) {\n                System.out.println(\"Error: División por cero\");\n            } finally {\n                System.out.println(\"Bloque finally ejecutado\");\n            }\n            /*\n             * Crea un programa que imprima por consola todos los números comprendidos\n             * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n             */\n\n            for (int i = 10; i <= 55; i++) {\n                if (i % 2 == 0 && i != 16 && i % 3 != 0) {\n                    System.out.println(\"numero\" + i);\n                }\n\n            }\n        }\n    }\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/JulianJRA.java",
    "content": "\npublic class JulianJRA {\n\n    public static void main(String[] args) {\n\n        // Operadores aritméticos\n        int a = 10, b = 3;\n\n        System.out.println(\"Suma: \" + (a + b)); // 13\n        System.out.println(\"Resta: \" + (a - b)); // 7\n        System.out.println(\"Multiplicación: \" + (a * b)); // 30\n        System.out.println(\"División: \" + (a / b)); // 3 (división entera)\n        System.out.println(\"Módulo: \" + (a % b)); // 1 (resto)\n        System.out.println(\"Incremento: \" + (++a)); // 11 (preincremento)\n        System.out.println(\"Decremento: \" + (--b)); // 2 (predecremento)\n\n        // Operadores lógicos\n        boolean x = true, y = false;\n\n        System.out.println(\"AND (&&): \" + (x && y)); // false\n        System.out.println(\"OR (||): \" + (x || y)); // true\n        System.out.println(\"NOT (!): \" + (!x)); // false\n\n        // Operadores de comparación\n        System.out.println(\"Igual a: \" + (a == b)); // false\n        System.out.println(\"No igual: \" + (a != b)); // true\n        System.out.println(\"Mayor que: \" + (a > b)); // true\n        System.out.println(\"Menor que: \" + (a < b)); // false\n        System.out.println(\"Mayor o igual: \" + (a >= b)); // false\n        System.out.println(\"Menor o igual: \" + (a <= b)); // false\n\n        // Operadores de asignación\n        a += 5; // a = a + 5\n        System.out.println(\"Suma y asigna: \" + a); // 15\n\n        a -= 3; // a = a - 3\n        System.out.println(\"Resta y asigna: \" + a); // 12\n\n        a *= 2; // a = a * 2\n        System.out.println(\"Multiplica y asigna: \" + a); // 24\n\n        a /= 4; // a = a / 4\n        System.out.println(\"Divide y asigna: \" + a); // 6\n\n        a %= 5; // a = a % 5\n        System.out.println(\"Módulo y asigna: \" + a); // 1\n\n        // Operadores a nivel de bits\n        int c = 5; // 0101 en binario\n        int d = 3; // 0011 en binario\n\n        System.out.println(\"AND (&): \" + (c & d)); // 1 (0001 en binario)\n        System.out.println(\"OR (|): \" + (c | d)); // 7 (0111 en binario)\n        System.out.println(\"XOR (^): \" + (c ^ d)); // 6 (0110 en binario)\n        System.out.println(\"NOT (~): \" + (~c)); // -6 (inversión de bits)\n        System.out.println(\"Shift izquierda (<<): \" + (c << 1)); // 10 (1010 en binario)\n        System.out.println(\"Shift derecha (>>): \" + (c >> 1)); // 2 (0010 en binario)\n        System.out.println(\"Shift derecha sin signo (>>>): \" + (c >>> 1)); // 2\n\n        // ESTRUCTURAS CONDICIONALES\n        // if-else\n        int edad = 20;\n\n        if (edad >= 18) {\n            System.out.println(\"Eres mayor de edad.\");\n        } else {\n            System.out.println(\"Eres menor de edad.\");\n        }\n\n        // if-elseif-else\n        int calificacion = 85;\n\n        if (calificacion >= 90) {\n            System.out.println(\"Excelente\");\n        } else if (calificacion >= 70) {\n            System.out.println(\"Aprobado\");\n        } else {\n            System.out.println(\"Suspenso\");\n        }\n\n        // Switch\n        int dia = 3;\n\n        switch (dia) {\n            case 1:\n                System.out.println(\"Lunes\");\n                break;\n            case 2:\n                System.out.println(\"Martes\");\n                break;\n            case 3:\n                System.out.println(\"Miércoles\");\n                break;\n            default:\n                System.out.println(\"Día no válido\");\n        }\n\n        // ESTRUCTURAS ITERATIVAS\n        // for\n        for (int i = 1; i <= 5; i++) {\n            System.out.println(\"Iteración: \" + i);\n        }\n\n        // while\n        int contador = 0;\n\n        while (contador < 3) {\n            System.out.println(\"Contador: \" + contador);\n            contador++;\n        }\n\n        // do-while\n        int numero = 0;\n\n        do {\n            System.out.println(\"Número: \" + numero);\n            numero++;\n        } while (numero < 3);\n\n        // for-each\n        int[] numeros = { 1, 2, 3, 4, 5 };\n\n        for (int num : numeros) {\n            System.out.println(\"Número: \" + num);\n        }\n\n        // ESTRUCTURAS DE EXCEPCIONES\n        // try-catch-finally\n        try {\n            int resultado = 10 / 0; // Genera una excepción (división por cero)\n            System.out.println(\"Resultado: \" + resultado);\n        } catch (ArithmeticException e) {\n            System.out.println(\"Error: División por cero no permitida.\");\n        } finally {\n            System.out.println(\"Bloque 'finally' siempre se ejecuta.\");\n        }\n\n        // throw y throws\n        try {\n            dividir(10, 0);\n        } catch (ArithmeticException e) {\n            System.out.println(\"Error: \" + e.getMessage());\n        }\n\n        // EJERCICIO OPCIONAL\n        for(int i = 10; i < 56; i++){\n            if((i%2==0) && (i!=16) && (i%3!=0)){\n                System.out.println(\"Numero ejercicio: \"+i);\n            }\n        }\n\n    }\n\n    public static void dividir(int a, int b) throws ArithmeticException {\n        if (b == 0) {\n            throw new ArithmeticException(\"División por cero no permitida.\");\n        }\n        System.out.println(\"Resultado:  \" + (a / b));\n    }\n\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/Karolle.java",
    "content": "public class Karolle {\n    public static void main(String[] args) {\n        // Arithmetic operators\n        int a = 10, b = 5;\n        System.out.println(\"Arithmetic Operators:\");\n        System.out.println(\"Addition: \" + (a + b));\n        System.out.println(\"Subtraction: \" + (a - b));\n        System.out.println(\"Multiplication: \" + (a * b));\n        System.out.println(\"Division: \" + (a / b));\n        System.out.println(\"Modulus: \" + (a % b));\n\n        // Logical operators\n        boolean x = true, y = false;\n        System.out.println(\"\\nLogical Operators:\");\n        System.out.println(\"Logical AND: \" + (x && y));\n        System.out.println(\"Logical OR: \" + (x || y));\n        System.out.println(\"Logical NOT: \" + (!x));\n\n        // Comparison operators\n        System.out.println(\"\\nComparison Operators:\");\n        System.out.println(\"Equal: \" + (a == b));\n        System.out.println(\"Not Equal: \" + (a != b));\n        System.out.println(\"Greater Than: \" + (a > b));\n        System.out.println(\"Less Than: \" + (a < b));\n        System.out.println(\"Greater Than or Equal To: \" + (a >= b));\n        System.out.println(\"Less Than or Equal To: \" + (a <= b));\n\n        // Assignment operators\n        int c = 15;\n        System.out.println(\"\\nAssignment Operators:\");\n        c += 5;\n        System.out.println(\"+= Operator: \" + c);\n\n        // Conditional statements\n        System.out.println(\"\\nConditional Statements:\");\n        if (a > b) {\n            System.out.println(\"a is greater than b\");\n        } else {\n            System.out.println(\"b is greater than or equal to a\");\n        }\n\n        // Iterative structure\n        System.out.println(\"\\nIterative Structure:\");\n        for (int i = 10; i <= 55; i++) {\n            if (i % 2 == 0 && i != 16 && i % 3 != 0) {\n                System.out.print(i + \" \");\n            }\n        }\n\n        // Exception handling\n        System.out.println(\"\\n\\nException Handling:\");\n        try {\n            int result = a / 0; // Division by zero\n            System.out.println(\"Result: \" + result);\n        } catch (ArithmeticException e) {\n            System.out.println(\"Error: Division by zero\");\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/Kine-jdf.java",
    "content": "public class Kine_jdf {\n    public static void main(String args[]) {\n     \n     //Operadores Aritméticos:\n     // Suma +\nint suma = 5 + 3;          // suma = 8\n\n// Resta -\nint resta = 10 - 4;         // resta = 6\n\n// Multiplicación *\nint multiplicacion = 2 * 6; // multiplicacion = 12\n\n// División  /\nint division = 15 / 3;      // division = 5\n\n// Módulo (resto de la división. siempre tengo que googlear que es) %\nint modulo = 17 % 4;        // modulo = 1\n\nint a = 5, b = 10;\nSystem.out.println(\"Operadores Aritmeticos(ver codigo)\");\nSystem.out.println(\"Suma \" + suma +\"\\nResta \"+resta+\"\\nMultiplicacion \"+multiplicacion+\"\\nDivision \"+division);\n      \n//Operadores de Comparación:\n// Igual a ==\nboolean igual = (a == b);   // igual = false\n\n// No igual a  !=\nboolean noIgual = (a != b); // noIgual = true\n\n// Mayor que    >\nboolean mayorQue = (a > b);  // mayorQue = false\n\n// Menor que  <\nboolean menorQue = (a < b);  // menorQue = true\n\n// Mayor o igual que >=\nboolean mayorIgualQue = (a >= b); // mayorIgualQue = false\n\n// Menor o igual que  <=\nboolean menorIgualQue = (a <= b); // menorIgualQue = true\nSystem.out.println(\"\\nOperadores de Comparacion \");\nSystem.out.println(\"A vale \"+ a+\"\\nB vale \"+b);\nSystem.out.println(\"Igual \"+igual+\"\\nNoIgual \"+noIgual+\"\\nMayor que \"+mayorQue+\"\\nMenor que \"+menorQue\n+\"\\nMayor o igual que \"+mayorIgualQue+\"\\nMenor o igual que \"+menorIgualQue);\n\nint num = 5;\nSystem.out.println(\"\\nOperadores de Inc / Dec\");\nSystem.out.println(\"Numero inicial vale 5\");\nSystem.out.println(\"incremento ++ :\" + num);\n      \n//Operadores de Incremento y Decremento:\n// Incremento ++\nnum++;       // num = 6\nSystem.out.println(\"incremento ++ :\" + num);\n// Decremento --\nnum--;       // num = 5\nSystem.out.println(\"decremento -- :\" + num);\n      \n//Operadores Lógicos:\n\nboolean x = true, y = false;\n\n// AND lógico &&\nboolean andLogico = x && y;  // andLogico = false\n\n// OR lógico  ||\nboolean orLogico = x || y;   // orLogico = true\n\n// NOT lógico !\nboolean notLogico = !x;      // notLogico = false\n\nSystem.out.println(\"\\nOperadores Logivos \");\nSystem.out.println(\"X es true, Y es false \");\nSystem.out.println(\"x && y \" +andLogico);\nSystem.out.println(\"x || y \" +orLogico);\nSystem.out.println(\"x != y \" +notLogico);\n\nint c = 10;\n      \n//Operadores de Asignación:\n// Asignación simple =\nint d = c;    // d = 10\n// Asignación con operación +=\na += 5;       // a = a + 5 (a ahora es 10)\nSystem.out.println(\"\\nOperadores de asignacion \");\nSystem.out.println(\"Simple : c = 10, d=c\");\nSystem.out.println(\"Con operacion += (o -=)\");\nSystem.out.println(\"a +=5 :\"+ a);\n      \n//Operadores de Identidad:\nString str = \"Hola\";\nint test = 0;\nSystem.out.println(\"Es un String? \" + (str instanceof String)); //true\nSystem.out.println(\"Esto es un Integer?(wrapper obj para primitivo)\" + (test instanceof Integer)); //CREO que deberia ser true, aunque use un wrapper\n\n\n      \n//Repeticion - Ciclos\n\n // Ciclo for\n for (int i = 1; i <= 5; i++) {\n System.out.println(\"Ciclo #\" + i);\n        }\n\n// Ciclo while\n  int j = 0;\n  while (j < 5) {\n  System.out.println(\"Ciclo en while #\" + j);\n       j++;\n        }\n\n// Ciclo do-while\n int k = 0;\n   do {\n  System.out.println(\"Ciclo en do-while #\" + k);\n     k++;\n        } while (k < 5);\n\n\n     \n      \n      elMetodo();\n    }\n    \n    public static void elMetodo(){\n      int start = 10;\n      int end = 55;\n      int count = start;\n      System.out.println(\"\\n             ||    EJERCICIO EXTRA    ||\");\n      System.out.println(\"○*:;;;:*○*: Fancy numeritos thing by Kine ○*:;;;:*○*:\" +\"\\n\");\n          System.out.print(start+\",\");\n          while(count <end) {\n               \n              if(count%2==0 && count !=16 && count%3!=0) {\n                   \n                    System.out.print(count+\",\");\n                     \n              }\n              count+=2;\n          }\n            System.out.print(end);\n      }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/KingSaul22.java",
    "content": "import java.util.Scanner;\n\npublic class KingSaul22 {\n\n    public static void main(String[] args) {\n\n        //OPERADORES de ASIGNACIÓN\n        operadoresAsignacion();\n\n        //OPERADORES de INCREMENTO y DECREMETO\n        operadoresIncreDecremento();\n\n        //OPERADORES ARITMETICOS\n        operadoresAritmeticos();\n\n        //OPERADOR TERNARIO\n        operadorTernario();\n\n        //OPERADORES de COMPARACIÓN\n        operadoresComparacion();\n\n        //OPERADORES LÓGICOS\n        operadoresLogicos();\n\n        //OPERADORES de BITs\n        operadoresBits();\n\n        //CONTROL con CONDICIONALES\n        controlCondicionales();\n\n        //CONTROL con BUCLES\n        controlIterativas();\n\n        //CONTROL con EXCEPCIONES\n        controlExcepciones();\n\n        //DIFICULTAD EXTRA\n        dificultadExtra();\n    }\n\n    private static void operadoresAsignacion() {\n        int numeroA;\n        int numeroB = 2;\n\n        //Asignación basica:\n        numeroA = 4;\n        System.out.println(\"\\nLa variable numeroA tendrá el valor:\\nnumeroA = \" + numeroA);\n        /*\n        Operadores de asiganción compuesto, realiza una operacion\n        entre el valor de la variable previa al signo\n        y guarda el resultado en la misma variable.\n        */\n        //Suma entre si mismo y otro valor:\n        numeroB += numeroA;\n        System.out.printf(\"\"\"\n\n                Al valor que tenia numeroB, '2', le hemos sumado numeroA:\n                2 + %d = %d\n                \"\"\", numeroA, numeroB\n        );\n        //Resta entre si mismo y otro valor:\n        numeroA -= numeroB;\n        System.out.printf(\"\"\"\n                                \n                Al valor de numeroA, '4', le restamos NumeroB:\n                4 - %d = %d\n                \"\"\", numeroB, numeroA\n        );\n        //Multiplicación entre si mismo y otro valor:\n        numeroB *= numeroB;\n        System.out.printf(\"\"\"\n                                \n                Al valor de numeroB, '6', le multiplicamos NumeroB:\n                4 * 4 = %d\n                \"\"\", numeroB\n        );\n        //División entre si mismo y otro valor:\n        numeroB /= numeroA;\n        System.out.printf(\"\"\"\n                                \n                Al valor de numeroB, '36', le dividimos NumeroA:\n                36 / %d = %d\n                \"\"\", numeroA, numeroB\n        );\n    }\n\n    private static void operadoresIncreDecremento() {\n        /*\n        Estos operadores nos permiten aumentar o disminuir en uno\n        la variable en cuestión. Usando dos signos de más o menos.\n         */\n        int numeroA = 2;\n        int numeroB = 2;\n\n        //Incremento:\n        numeroA++;\n        System.out.println(\"\\nEl valor previo al incremento era de '2', después su valor es: \" + numeroA);\n        //Decremento:\n        numeroB--;\n        System.out.println(\"\\nEl valor previo al decremento era de '2', después su valor es: \" + numeroB);\n\n        /*\n        Un uso interesante que podemos darles consiste en usarlos en operaciones\n        en las que la variable empleada vaya a cambiar en una unidad.\n\n        Siendo posible que en la operación se utilice el valor sin variar y tras realizarse, se cambie\n        o variar el valor y usarlo en la misma operación.\n         */\n        numeroA = 2;\n        numeroB = 2;\n\n        //Se cambia el valor antes de la operación:\n        //Preincremento\n        numeroA = numeroA + ++numeroB;\n        System.out.println(\"\\nSiendo que numeroA y numeroB valen '2', 2 + (2+1) = \" + numeroA);\n        //Predecremento\n        numeroA = numeroA + --numeroB;\n        System.out.println(\"\\nnumeroA + --numeroB, 5 + (3-1) = \" + numeroA);\n        //Se cambia el valor después de la operación:\n        //Postincremento\n        numeroA = numeroA - numeroB++;\n        System.out.println(\"\\nnumeroA - numeroB++, 7 - 2 = \" + numeroA);\n        //Postdecremento\n        numeroA = numeroA + numeroB--;\n        System.out.println(\"\\nnumeroA - numeroB--, 5 - 1 = \" + numeroA);\n        System.out.println(\"Tras la operación numeroB valdrá: \" + numeroB);\n\n    }\n\n    private static void operadoresAritmeticos() {\n        int numeroA = 5;\n        int numeroB = 7;\n        //Suma de dos números:\n        int suma = numeroA + numeroB;\n        System.out.printf(\"\\n%d + %d = %d\\n\", numeroA, numeroB, suma);\n        //Resta de dos numeros:\n        int resta = suma - numeroA;\n        System.out.printf(\"\\n%d - %d = %d\\n\", suma, numeroA, resta);\n        //Multiplicación de dos números:\n        int producto = resta * numeroB;\n        System.out.printf(\"\\n%d * %d = %d\\n\", resta, numeroB, producto);\n        //División de dos números:\n        int division = producto / numeroA;\n        System.out.printf(\"\\n%d / %d = %d\\n\", producto, numeroA, division);\n        //Recoger el resto de una división usando el módulo:\n        int resto = producto % numeroA;\n        System.out.printf(\"\\n%d %s %d = %d\\n\", producto, \"%\", numeroA, resto);\n    }\n\n    private static void operadorTernario() {\n        //Los operadores ternarios son una manera de asignar un valor u otro teniendo en cuenta una condición\n        //Esto es, en caso de que la condición sea TRUE se devuelve un valor A, en caso de que sea FALSE se devuelve B\n        //La estructura que usa es la siguiente: condicion ? valorA : valorB\n        boolean condicion = false;\n        int numero = condicion ? 2 : 4;\n        System.out.println(\"En este caso la condición es 'False', por ello se usará el segundo valor que está ubicado a la derecha\\n\" + numero);\n    }\n\n    private static void operadoresComparacion() {\n        /*\n        Estos operadores compararán los valores indicados y\n        devolverán un booleano en funición del resultado.\n         */\n\n        int numeroA = -1;\n        int numeroB = 4;\n        boolean cumpleCondicion;\n\n        //Igual que:\n        cumpleCondicion = numeroA == numeroB;\n        System.out.println(\"\\nnumeroA es igual a numeroB: \" + cumpleCondicion);\n        //Distinto que:\n        cumpleCondicion = numeroA != numeroB;\n        System.out.println(\"\\nnumeroA es distinto a numeroB: \" + cumpleCondicion);\n        //Mayor que:\n        cumpleCondicion = numeroA > numeroA;\n        System.out.println(\"\\nnumeroA es mayor a numeroA: \" + cumpleCondicion);\n        //Menor que:\n        cumpleCondicion = numeroA < numeroB;\n        System.out.println(\"\\nnumeroA es menor a numeroB: \" + cumpleCondicion);\n        //Mayor o igual que:\n        cumpleCondicion = numeroA >= numeroB;\n        System.out.println(\"\\nnumeroA es igual o mayor a numeroB: \" + cumpleCondicion);\n        //Menor o igual que:\n        cumpleCondicion = numeroA <= numeroA;\n        System.out.println(\"\\nnumeroA es menor o igual a numeroA: \" + cumpleCondicion);\n\n    }\n\n    private static void operadoresLogicos() {\n        boolean cumpleCondicion;\n\n        //Operador &\n        cumpleCondicion = (2 == 2) && (3 == 1);\n        System.out.println(\"\"\"\n                                \n                Pese a que '2' es igual a '2' (true),\n                '3' es distinto de '1' (false),\n                por lo que globalmente se devuelve false:\n                \"\"\" + cumpleCondicion\n        );\n        //Operador |\n        cumpleCondicion = (2 == 2) || (3 == 1);\n        System.out.println(\"\"\"\n                                \n                Pese a que '3' es distinto de '1' (false),\n                '2' es igual a '2' (true),\n                por lo que globalmente se devuelve true:\n                \"\"\" + cumpleCondicion\n        );\n        //Operador !\n        cumpleCondicion = (2 == 2) != (3 == 1);\n        System.out.println(\"\"\"\n                                \n                '2' es igual a '2' (true),\n                '3' es distinto de '1' (false),\n                por lo que, al ser distintos, globalmente se devuelve true:\n                \"\"\" + cumpleCondicion\n        );\n    }\n\n    private static void operadoresBits() {\n        int numA = 11, numB = 9;\n        System.out.println(numA + \" a binario: \" + Integer.toBinaryString(numA));\n        System.out.println(numB + \" a binario: \" + Integer.toBinaryString(numB));\n\n        //Operador ~ (NOT)\n        //Este operador cambiara los 1 por 0 y los 0 por 1\n        System.out.println(\"NOT \" + numA + \": \" + Integer.toBinaryString(~numA));\n\n        //Operador & (AND)\n        //Este operador comparará los bits individuales de ambos numeros y devolverá 1 en la posición cuando ambos sean 1\n        System.out.println(numA + \" AND \" + numB + \": \" + Integer.toBinaryString(numA & numB));\n\n        //Operador | (OR)\n        //Este operador hace lo mismo que el anterior pero con que uno de los dos valores sea 1 colocará 1\n        System.out.println(numA + \" OR \" + numB + \": \" + Integer.toBinaryString(numA | numB));\n\n        //Operador ^ (XOR)\n        //Este operador comparará los bits de dos números y devolverá 1 en la posición donde no coincidan entre los dos números\n        System.out.println(numA + \" XOR \" + numB + \": \" + Integer.toBinaryString(numA ^ numB));\n\n        //También podemos desplazar bitsa un lado u otro(teniendo en cuenta de que se pueden perder si los desplazamos demasiado)\n        //Usamos el operador << para desplazarlos a la izquierda y >> para la derecha.\n        //En este caso usaremos 2 como el número de posiciones desplazadas\n        System.out.println(numA + \" << 2: \" + Integer.toBinaryString(numA << 2));\n        System.out.println(numB + \" >> 2: \" + Integer.toBinaryString(numA >> 2));\n    }\n\n    private static void controlCondicionales() {\n        //Se usa una condición (true o false) para determinar si se hace una cosa u otra\n        int numA = 2, numB = 5;\n        if (numA < numB) {\n            System.out.println(numA + \" es menor que \" + numB);\n        } else {\n            System.out.println(numA + \" no es menor que \" + numB);\n        }\n\n        //También puedes usar 'if' anidados con distintas condiciones\n        if (numA > numB) {\n            System.out.println(numA + \" es mayor que \" + numB);\n        } else if (numA == numB) {\n            System.out.println(numA + \" es igual que \" + numB);\n        } else {\n            System.out.println(numA + \" es menor que \" + numB);\n        }\n    }\n\n    private static void controlIterativas() {\n        //Bucles for\n        //Se repetirá un código un determinado número de veces\n        //Imprimimos los números desde el 0 al 9\n        for (int i = 0; i < 10; i++) {\n            System.out.println(i);\n        }\n\n        //Bucles while\n        //Se repetirá un código hasta que la condición se cumpla\n        int numA = 0, numB = 2;\n        boolean condicion = true;\n        while (condicion) {\n            System.out.println(\"Condición es \" + condicion + \". Se continua la ejecución del while\");\n            if (numA == numB){\n                condicion = false;\n            }else if (numA > numB) {\n                numB += 2;\n            } else {\n                numA += 3;\n            }\n\n            if (condicion) {\n                System.out.println(\"Condición es \" + condicion + \". Se continuará la ejecución del while\");\n            } else {\n                System.out.println(\"Condición es \" + condicion + \". Se terminará la ejecución del while\");\n            }\n        }\n    }\n\n    private static void controlExcepciones() {\n        //Hay acciones que pueden provocar fallos en un proceso\n        //para solucionar esto se usa un controlador que captura ese fallo y continua con la ejecución del programa\n        Scanner sc = new Scanner(System.in);\n        //Si se conoce que una parte puede dar un error, lo incluimos en un try\n        try {\n            int numA = sc.nextInt();\n            System.out.println(\"No ha surgido un error\");\n            //En caso de que surja el error, se captura\n        } catch (Exception e) {\n            System.out.println(\"Ha surgido un error\");\n            //finally es algo que siempre se ejecutará\n        } finally {\n            System.out.println(\"Este código se ejecutará siempre\");\n            sc.close();\n        }\n    }\n\n    private static void dificultadExtra() {\n        //Empezando por 10 y hasta llegar a 55\n        for (int i = 10; i <= 55; i += 2) {\n            //Se imprimirá los números pares siempre que no sea 16 o multiplo de 3\n            if (i % 2 == 0 && i != 16 && i % 3 != 0) System.out.println(i);\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/Kronstadt-Lambda.java",
    "content": "/**\n * @author KronstadtLambda\n * @version 1.0\n */\n\n// package roadmap.java.r01;\n\npublic class KronstadtLambda {\n\n    public static int suma(int a, int b) {\n        return a + b; // Return the sum of a and b\n    }\n    public static void main(String[] args) {\n        \n        // Initialize variables\n        float float_a = 2.0f;\n        float float_b = 2.0f;\n        int bit_a = 0b01000001;\n        int bit_b = 0b01010011;\n        String day = \"Monday\";\n        int edad = 1;\n        boolean isBool;\n        int[] numbers = {1, 2, 3, 4, 5};\n\n        /*\n         * Operators in Java\n         */\n        // Arithmetic operators\n        System.out.println(\"float_a + float_b = \" + (float_a + float_b));\n        System.out.println(\"float_a - float_b = \" + (float_a - float_b));\n        System.out.println(\"float_a * float_b = \" + (float_a * float_b));\n        System.out.println(\"float_a / float_b = \" + (float_a / float_b));\n        System.out.println(\"float_a % float_b = \" + (float_a % float_b)); // Remainder of the division\n        System.out.println(\"float_a++ = \" + (float_a++)); // Post-increment\n        System.out.println(\"float_a-- = \" + (float_a--)); // Post-decrement\n        System.out.println(\"++float_a = \" + (++float_a)); // Pre-increment\n        System.out.println(\"--float_a = \" + (--float_a)); // Pre-decrement\n\n        // Assignment operators\n        System.out.println(\"float_a += float_b -> \" + (float_a += float_b)); // float_a = float_a + float_b\n        System.out.println(\"float_a -= float_b -> \" + (float_a -= float_b)); // float_a = float_a - float_b\n        System.out.println(\"float_a *= float_b -> \" + (float_a *= float_b)); // float_a = float_a * float_b\n        System.out.println(\"float_a /= float_b -> \" + (float_a /= float_b)); // float_a = float_a / float_b\n        System.out.println(\"float_a %= float_b -> \" + (float_a %= float_b)); // float_a = float_a % float_b\n        System.out.println(\"bit_a &= bit_b -> \" + (bit_a &= bit_b)); // bit_a = bit_a & bit_b (bitwise AND)\n        System.out.println(\"bit_a |= bit_b -> \" + (bit_a |= bit_b)); // bit_a = bit_a | bit_b (bitwise OR)\n        System.out.println(\"bit_a ^= bit_b -> \" + (bit_a ^= bit_b)); // bit_a = bit_a ^ bit_b (bitwise XOR)\n        System.out.println(\"bit_a >>= 1 -> \" + (bit_a >>= 1)); // bit_a = int_a >> 1 (bitwise right shift)\n        System.out.println(\"bit_a <<= 1 -> \" + (bit_a <<= 1)); // bit_a = int_a << 1 (bitwise left shift)\n\n        // Comparison operators\n        System.out.println(\"float_a == float_b -> \" + (float_a == float_b)); // Equal to \n        System.out.println(\"float_a != float_b -> \" + (float_a != float_b)); // Not equal to \n        System.out.println(\"float_a > float_b -> \"  + (float_a > float_b)); // Greater than \n        System.out.println(\"float_a < float_b -> \"  + (float_a < float_b)); // Less than \n        System.out.println(\"float_a >= float_b -> \" + (float_a >= float_b)); // Greater than or equal to \n        System.out.println(\"float_a <= float_b -> \" + (float_a <= float_b)); // Less than or equal to \n\n        // Logical operators\n        System.out.println(\"float_a == float_b && float_a != 0 -> \" + (float_a == float_b && float_a != 0)); // Logical AND\n        System.out.println(\"float_a == float_b || float_a != 0 -> \" + (float_a == float_b || float_a != 0)); // Logical OR\n        System.out.println(\"!(float_a == float_b) -> \" + !(float_a == float_b)); // Logical NOT\n\n        // Bitwise operators\n        System.out.println(\"bit_a & bit_b -> \" + (bit_a & bit_b)); // Bitwise AND\n        System.out.println(\"bit_a | bit_b -> \" + (bit_a | bit_b)); // Bitwise OR\n        System.out.println(\"bit_a ^ bit_b -> \" + (bit_a ^ bit_b)); // Bitwise XOR\n        System.out.println(\"~bit_a -> \" + (~bit_a)); // Bitwise NOT\n        System.out.println(\"bit_a >> 1 -> \" + (bit_a >> 1)); // Bitwise right shift\n        System.out.println(\"bit_a << 1 -> \" + (bit_a << 1)); // Bitwise left shift\n        System.out.println(\"bit_a >>> 1 -> \" + (bit_a >>> 1)); // Bitwise right shift with zero fill\n        \n        // Java don't have identity and membership operators\n\n        /*\n         * Control structures in Java\n         */\n        // If, if-else, else statement\n        if (float_a == float_b) {\n            System.out.println(\"float_a is equal to float_b\");\n        } else if (float_a > float_b) {\n            System.out.println(\"float_a is greater than float_b\");\n        } else {\n            System.out.println(\"float_a is less than float_b\");\n        }\n        // Switch statement\n        switch (day) {\n            case \"Monday\":\n                System.out.println(\"Today is Monday\");\n                break; // Exit the switch statement to avoid fall-through\n            case \"Tuesday\":\n                System.out.println(\"Today is Tuesday\");\n                break; // Exit the switch statement to avoid fall-through\n            case \"Wednesday\":\n                System.out.println(\"Today is Wednesday\");\n                break; // Exit the switch statement to avoid fall-through\n            case \"Thursday\":\n                System.out.println(\"Today is Thursday\");\n                break; // Exit the switch statement to avoid fall-through\n            case \"Friday\":\n                System.out.println(\"Today is Friday\");\n                break; // Exit the switch statement to avoid fall-through\n            case \"Saturday\":\n                System.out.println(\"Today is Saturday\");\n                break; // Exit the switch statement to avoid fall-through\n            case \"Sunday\":\n                System.out.println(\"Today is Sunday\");\n                break; // Exit the switch statement to avoid fall-through\n            default: // if none of the above cases are true\n                System.out.println(\"Invalid day\");\n                break; // Exit the switch statement to avoid fall-through\n        }\n        // For loop\n        for (int i = 10; i >= 0; i--) {\n            System.out.println(\"The loop end in ... \" + i);\n        }\n        // While loop\n        while (edad < 18) {\n            System.out.println(\"You are \" + edad + \" years old\");\n            edad++;\n        }\n        // do-while loop\n        do {\n            isBool = false;\n            System.out.println(\"At least one execution\");\n        } while (isBool);\n        // For-each loop\n        for (int number : numbers) {\n            System.out.println(\"Square of \" + number + \" is \" + number * number);\n        }\n        // break statement\n        for (int i = 0; i < 10; i++) {\n            if (i == 5) {\n                System.out.println(\"Break in i = \" + i);\n                break; // Exit the loop\n            }\n            System.out.println(\"i = \" + i);\n        }\n        // continue statement\n        for (int i = 0; i < 10; i++) {\n            if (i == 5) {\n                System.out.println(\"Continue (skip) in i = \" + i);\n                continue; // Skip the rest of the loop\n            }\n            System.out.println(\"Cube of \" + i + \" is \" + i * i * i);\n        }\n        // return statement\n        System.out.println(\"The sum of 5 and 7 is \" + suma(5, 7));\n        // try-catch\n        try {\n            int[] array = {1, 2, 3};\n            System.out.println(array[3]); // ArrayIndexOutOfBoundsException\n        } catch (ArrayIndexOutOfBoundsException e) {\n            System.out.println(\"Array index out of bounds\");\n        }\n        // try-catch-finally\n        try {\n            int[] array = {1, 2, 3};\n            System.out.println(array[3]); // ArrayIndexOutOfBoundsException\n        } catch (ArrayIndexOutOfBoundsException e) {\n            System.out.println(\"Array index out of bounds\"); // Execute if an exception is thrown\n        } finally {\n            System.out.println(\"Finally block executed\"); // Necesary for close resources or other actions\n        }\n        // throw statement\n        try {\n            throw new ArithmeticException(\"Arithmetic exception\"); // Intentionally throw an exception\n            /* \n             * It is useful for testing the behavior of the program when an exception is thrown like error handling.\n             */\n        } catch (ArithmeticException e) {\n            System.out.println(e.getMessage());\n        }\n        \n        /*\n         * Extra exercise\n         * Create a program that prints to the console all numbers between 10 and 55 (inclusive), even, and that are neither 16 nor multiples of 3\n         */\n        for (int i = 10; i <= 55; i++) {\n            if (i % 2 == 0 && i != 16 && i % 3 != 0) {\n                System.out.println(\"The solution is \" + i);\n            }\n        }\n\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/Ldre3.java",
    "content": "import java.util.stream.IntStream;\n\npublic class Ldre3 {\n    public static void main(String[] args) {\n        // EJERCICIO:\n        // * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n        // *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n        // *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n\n        // Operador de suma y asignacion\n        int suma = 1 + 2;\n        System.out.println(suma);\n        // Operador logico\n        System.out.println(true && false);\n        System.out.println(true || false);\n        // Operador de comparacion\n        System.out.println(1 == 2);\n        System.out.println(1 != 2);\n        // Operador de identidad\n        System.out.println(\"Hola\" instanceof String);\n\n\n        // * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n        // *   que representen todos los tipos de estructuras de control que existan\n        // *   en tu lenguaje:\n        // *   Condicionales, iterativas, excepciones...\n        // * - Debes hacer print por consola del resultado de todos los ejemplos.\n\n        // Estructura condicional\n        if (1 == 2) {\n            System.out.println(\"1 es igual a 2\");\n        } else {\n            System.out.println(\"1 no es igual a 2\");\n        }\n        // Estructura iterativa\n        for (int i = 0; i < 10; i++) {\n            System.out.println(i);\n        }\n        while (true) {\n            System.out.println(\"Hola\");\n            break;\n        }\n\n        // Excepciones\n        try {\n            int a = 1 / 0;\n        } catch (Exception e) {\n            System.out.println(\"No se puede dividir entre 0\");\n        }\n        // switch case\n        int x = 1;\n        switch (x) {\n            case 1:\n                System.out.println(\"x es 1\");\n                break;\n            case 2:\n                System.out.println(\"x es 2\");\n                break;\n            default:\n                System.out.println(\"x no es ni 1 ni 2\");\n                break;\n        }\n\n\n\n        // Imprimir numeros comprendidos entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n        IntStream.range(10, 56).filter(v -> v%2 == 0 && v!=16 && v%3!=0)\n                .forEach(System.out::println);\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/LucasAG01.java",
    "content": "import static java.lang.Math.pow;\nimport static java.lang.Math.round;\n\npublic class LucasAG01 {\n\n    public static void main(String[] args) {\n\n\n\n        //OPERADORES\n\n        System.out.println(\"Suma: 10 + 3 = \" + (10 + 3));\n        System.out.println(\"Resta: 10 - 3 = \" + (10 - 3));\n        System.out.println(\"Multiplicacion: 10 * 3 = \" + (10 * 3));\n        System.out.println(\"Division: 10 / 3 = \" + (10 / 3));\n        System.out.println(\"Resto: 10 % 5 = \" + (10 % 5));\n        System.out.println(\"Exponente: 12 a la 3 = \" + (int) pow(12,3));\n        System.out.println(\"Exponente: 10 ^ 3 = \" + (10 ^ 3));\n        System.out.println(\"Raiz cuadrada: √64 = \"+(int)(Math.sqrt(64)));\n\n        System.out.println(\"*****************************************************\");\n\n        //OPERADORES COMPARACION\n\n        System.out.println(\"Igualdad: 10==10 ? \" +(10==10));\n        System.out.println(\"Desigualdad: 10!=3 ? \"+(10!=3));\n        System.out.println(\"Mayor que : 10 > 3 = \" + (10 > 3));\n        System.out.println(\"Menor que : 10 < 3 = \" + (10 < 3));\n\n        System.out.println(\"*****************************************************\");\n\n        //OPERADORES UNARIOS\n\n        int c = 10;\n\n        System.out.println(\"Mantiene el signo: \" + (+c));\n        System.out.println(\"Cambia el signo: \" + (-c));\n        System.out.println(\"Autoincremento e impresión: \" + (++c)); //Se incrementa y se imprime\n        System.out.println(\"Impresión y autoincremento: \" + (c++)); //Se imprime y se incrementa\n        System.out.println(\"Autodecremento e impresión: \" + (--c)); //Se decrementa y se imprime\n        System.out.println(\"Impresión y autodecremento: \" + (c--)); //Se imprime y se decrementa\n\n        System.out.println(\"*****************************************************\");\n\n\n        //OPERADORES LÓGICOS\n\n        boolean v = true;\n        boolean f = false;\n\n\n        System.out.println(\"¿true es igual a false? : \" + (v&f));\n        System.out.println(\"¿true es igual a false? (cortocircuíto) : \" + (v&&f));\n        System.out.println(\"¿true o false son verdaderas? : \" + (v|f));\n        System.out.println(\"¿true o false son verdaderas? (cortocircuíto) : \" + (v||f));\n        System.out.println(\"Cambiamos el valor de true : \" + (!v));\n\n        System.out.println(\"*****************************************************\");\n\n\n        /*OPERADORES ASIGNACIÓN\n        ipos:\n         *      -- +=: Suma a la variable y sobrescribe el valor de la variable con el resultado.\n         *      -- -=: Resta a la variable y sobrescribe el valor de la variable con el resultado.\n         *      -- *=: Multiplica a la variable y sobrescribe el valor de la variable con el resultado.\n         *      -- /=: Divide a la variable y sobrescribe el valor de la variable con el resultado.\n         *      -- %=: Realiza el módulo a la variable y sobrescribe el valor de la variable con el resultado.\n         *      -- &=: Realiza un AND lógico a la variable y sobrescribe el valor de la variable con el resultado.\n                -- |=: Realiza un OR lógico a la variable y sobrescribe el valor de la variable con el resultado.\n        */\n\n        int a;\n        boolean t = true;\n\n        System.out.println(\"Operadores de asignación: Para asignar un valor a una variable.\");\n\n        System.out.println(\"Asignamos valor a la variable i = \" + (a = 1));\n        System.out.println(\"Suma y asigna: \" + (a+=5));\n        System.out.println(\"Resta y asigna: \" + (a-=5));\n        System.out.println(\"Multiplica y asigna: \" + (a*=5));\n        System.out.println(\"Divide y asigna: \" + (a/=5));\n        System.out.println(\"Módulo y asigna: \" + (a/=5));\n        System.out.println(\"AND lógico y asigna: \" + (t&=true));\n        System.out.println(\"OR lógico y asigna: \" + (t|=false));\n\n        System.out.println(\"*****************************************************\");\n\n        /*Operadores a nivel de bits: operan con cada bit del operando, ofreciendo un control más granular sobre los datos.\n                * Tipos:\n         *      -- AND (&): Operador AND a nivel de bits (1 y 1 = 1).\n         *      -- OR (|): Operador OR a nivel de bits (1 o 1 = 1).\n         *      -- XOR (^): Operador XOR a nivel de bits (1 y 1 = 0).\n         *      -- Complemento (~): Invierte el valor de cada bit.\n         *      -- >> : Desplaza bits a la derecha.\n         *      -- << : Desplaza bits a la izquierda.\n         *      -- >>> : Desplaza bits a la derecha sin signo.\n         */\n        int x = 10;\n        int y = 7;\n\n        System.out.println(\"Operadores a nivel de bits: operan con cada bit del operando, ofreciendo un control más granular sobre los datos.\");\n\n        System.out.println();\n\n        System.out.println(\"x : \" + Integer.toBinaryString(x));\n        System.out.println(\"y : \" + Integer.toBinaryString(y));\n\n        System.out.println();\n\n        System.out.println(\"X AND y : \" + Integer.toBinaryString(x & y));\n        System.out.println(\"x OR y : \" + Integer.toBinaryString(x | y));\n        System.out.println(\"x XOR y : \" + Integer.toBinaryString(x ^ y));\n        System.out.println(\"Complemento de x = \" + Integer.toBinaryString(~x));\n        System.out.println(\"Complemento de y = \" + Integer.toBinaryString(~y));\n        System.out.println(\"Desplazamiento de bits de x a la izquierda de y: \" + Integer.toBinaryString(x<<y));\n        System.out.println(\"Desplazamiento de bits de x a la derecha de y: \" + Integer.toBinaryString(x>>y));\n        System.out.println(\"Desplazamiento de bits de x a la derecha de y (sin signo): \" + Integer.toBinaryString(x>>>y));\n\n\n        System.out.println(\"*****************************************************\");\n\n        /*EL EJERCICIO EXTRA\n        Crea un programa que imprima por consola todos los números comprendidos\n        entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n        */\n\n        for (int i = 10; i <56 ; i++) {\n            if(i%2==0 && i!=16 && i%3 != 0){\n                System.out.println(i);\n            }\n        }\n\n        /* en el for ponemos de donde a donde vamos a analizar los numeros\n        y dentro un if con las condiciones en el orden propuesto separados por &&\n         */\n\n\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/LuisK0706.java",
    "content": "public class Ejercicio01{\n\n    public static void main(String[] args) {\n        \n\n        // Operadores aritméticos \n        int num1 = 4, num2 = 2, i = 0, contador = 0;\n        Integer num3 = 0;\n        String cadena = \"\";\n\n        // Operador + para una suma\n        System.out.println(\"Operadores aritméticos\");\n        System.out.println(\"Suma de 4 + 2 es: \" + (num1 + num2));\n        // Operador - para una resta\n        System.out.println(\"Resta de 4 - 2 es: \" + (num1 - num2));\n        // Operador * para una multiplicacion\n        System.out.println(\"Multiplicacion de 4 * 2 es: \" + (num1 * num2));\n        // Operador / para un division \n        System.out.println(\"Division de 4 / 2 es: \" +  (num1 / num2));\n        // Operador % para una division entera\n        System.out.println(\"Modulo de 4 % 2 es: \" + (num1 % num2));\n        // Doble signo ++ para incrementar una variable\n        System.out.println(\"Incrementando la variable num1: \" + (++num1));\n        // Doble signo -- para decrementar una variable\n        System.out.println(\"Decrementando la variable num1: \" + (--num1) + \"\\n\");\n\n\n        // Operadores lógicos\n\n        System.out.println(\"Operadores lógicos\");\n        // Operador and (&&)\n        System.out.println(\"5 > 2 and 5 < 10 es: \" + (5 > 2 && 5 < 10));\n        // Operador or (|)\n        System.out.println(\"5 > 2 or 5 < 1 es: \" + (5 > 2 | 5 < 1));\n        //  Operador not (!)\n        System.out.println(\"not 5 > 2 es: \" + (!(5 > 2)));\n\n\n        // Operadores de comparacion\n\n        System.out.println(\"Operadores de comparación\");\n        // Operador mayor que >\n        System.out.println(\"8 mayor que 4 es: \" + (8 > 4));\n        // Operador menor que <\n        System.out.println(\"8 menor que 4 es: \" + (8 < 4));\n        // Operador igual ==\n        System.out.println(\"8 igual que 4 es: \" + (8 == 4));\n        // Operador de diferencia != \n        System.out.println(\"8 es diferente que 4 es: \" + (8 != 4));\n        // Operador mayor o igual que >=\n        System.out.println(\"8 mayor o igual que 8 es: \" + (8 >= 8));\n        // Operador menor o igual que <=\n        System.out.println(\"8 menor o igual que 10 es: \" + (8 <= 10) + \"\\n\"); \n\n\n        // Operadores de asignación\n\n        System.out.println(\"Operadores de Asignación\");    \n        // Suma y asignacion\n        num1 += 5;\n        System.out.println(\"num1 + 5 con suma y asignacion es: \" + (num1));\n        // Resta y asignacion\n        num1 -= 5;\n        System.out.println(\"num1 - 5 usando resta y asignación es: \" + (num1));\n        // Multiplicacion y asignacion \n        num1 *= 5;\n        System.out.println(\"num1 * 5 usando multiplicacion y asignacion es: \" + (num1));\n        // Division y asignacion \n        num1 /= 5;\n        System.out.println(\"num1 / 5 usando division y asignacion es: \" + (num1) + \"\\n\");\n        \n\n        // Operadores de identidad\n\n        System.out.println(\"Operadores de identidad\");\n        // Operador == \n        System.out.println(\"Operador (==): \" + (num1 == num2));\n\n        //Operador != \n        System.out.println(\"Operador (!=): \" + (num1 != num2) + \"\\n\");\n        \n\n        //Operadores de pertenencia\n\n        //Para verificar pertenencia utilizamos instanceof\n        System.out.println(\"Operadores de pertenencia\");\n        System.out.println(\"Es una instancia de un entero: \" + (num3 instanceof Integer));\n        System.out.println(\"Es una instancia de una cadena: \" + (cadena instanceof String) + \"\\n\");\n\n\n        //Operadores de bits\n\n        System.out.println(\"Operadores de bits\");\n        //Operador AND (&)\n        System.out.println(\"Operador AND: \" + (num1 & num2));\n        //Operador OR (|)\n        System.out.println(\"Operador OR: \" + (num1 | num2) + \"\\n\");\n        \n        //Estructuras de control \n\n        //Condicionales (if, else if, else)\n\n        System.out.println(\"Estructuras condicionales\");\n        if (num1 == num2){\n            System.out.println(\"Los dos numeros son iguales\");\n        }\n        else if (num1 > num2){\n            System.out.println(\"El primer numero es mayor\");\n        }\n        else{\n            System.out.println(\"El segundo numero es mayor\");\n        }\n\n        //Iterativas (for, while, do whie)\n\n        //Ciclo for\n        for (int j = 0; j < 10; j++){\n            System.out.println(i);\n        }\n\n        //Ciclo while\n        while(i < 10){\n            System.out.println(i);\n            i ++;\n        }\n\n        //Ciclo do while\n        do {\n            System.out.println(\"Hola que tal\");\n            contador ++;\n        }while(contador < 10);\n\n        //Manejo de excepciones \n        try {\n            float division = 10/0;\n            System.out.println(\"El resultado de la división es: \" + division);\n        } catch (ArithmeticException e) {\n            System.out.println(\"Se produjo un error aritmético: \" + e.getMessage());\n        }\n\n\n        /* Reto extra\n         * Crea un programa que imprima por consola todos los números comprendidos\n         * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n         */\n\n\n        for (int numero = 10; numero < 56; numero++){\n            if (numero % 3 == 0 || numero == 16){\n                continue;\n            }\n            else{\n                System.out.println(numero);\n            }\n        }\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/Marianoemir.java",
    "content": "   class Auto {\n        \n    }\n    \n    class Toyota extends Auto{\n        \n    }\n\n\n\npublic class Marianoemir{\n/*\n *@author Marianoemir\n    \n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n    \n \n    public static void main(String [] args){\n        int a = 10, b = 2;\n        \n        //Operadores Aritmeticos:\n       \n        System.out.println(\"El resultado de la suma es: \"+(a + b)+\".\");\n        System.out.println(\"El resultado de la resta es: \"+(a - b)+\".\");\n        System.out.println(\"El resultado de la multiplicaciòn es: \"+(a * b)+\".\");\n        System.out.println(\"El resultado de la divisiòn es: \"+(a / b)+\".\");\n        System.out.println(\"El resultado de la modulo es: \"+(a % b)+\".\");\n        System.out.println(\"\");\n        \n        //Operadores Logicos:\n        \n        boolean T=true, F=false;\n        System.out.println(\"Operador Logico && Y: \"+(T&&F)+\".\");\n        System.out.println(\"Operador Logico || O: \"+(T||F)+\".\");\n        System.out.println(\"Operador Logico !not: \"+(!T)+\".\");\n        System.out.println(\"\");\n        \n        //Operadores Relacionales:\n        \n        System.out.println(\"El resultado de 10 > 2 es: \"+(a > b)+\".\");\n        System.out.println(\"El resultado de 10 < 2 es: \"+(a < b)+\".\");\n        System.out.println(\"El resultado de 10 == 2 es :\"+(a == b)+\".\");\n        System.out.println(\"El resultado de 10 != 2 es :\"+(a != b)+\".\");\n        System.out.println(\"El resultado de 10 <= 2 es :\"+(a <= b)+\".\");\n        System.out.println(\"El resultado de 10 >= 2 es :\"+(a >= b)+\".\");\n        System.out.println(\"\");\n        \n        //Operadores de Asignación:\n        \n        short c = 60; //Asignaciòn Simple.\n        System.out.println(\"Asignaciòn Simple: \"+c+\".\");\n        System.out.println(\"Asignaciòn con Suma: \"+(c += 20)+\".\"); \n        System.out.println(\"Asignaciòn con Resta: \"+(c -= 5)+\".\"); \n        System.out.println(\"Asignaciòn con Multiplicación: \"+(c *= 2)+\".\"); \n        System.out.println(\"Asignaciòn con División: \"+(c /= 5)+\".\"); \n        System.out.println(\"Asignaciòn con Modulo: \"+(c %= 5)+\".\"); \n        System.out.println(\"\");\n        \n        //Operadores bit a bit:\n        \n        int d=5 ,  e = -8, f=3 , resultbitAnd = 0, resultbitOr = 0 , resultbitXor = 0 , resultbitNot = 0;\n        int desplaizquieda = 0 , despladerecha = 0, desplaDconExtensióndeCero = 0;\n        \n        resultbitAnd = d & f;\n        String binario1 = String.format(\"%4s\", Integer.toBinaryString(resultbitAnd)).replace(' ', '0');\n        System.out.println(\"Operador AND de bit a bit: \"+binario1+\".\");\n        \n        /*\n          0101 (5)\n        & 0011 (3)\n          --------\n          0001 (1)  El AND & evalua todos los numeros y si los 2 son 1 osea verdadero sale verdadero el 1;\n        */ \n        \n        resultbitOr = d | f;\n        String binario2 = String.format(\"%4s\", Integer.toBinaryString(resultbitOr)).replace(' ', '0');\n        System.out.println(\"Operador OR de bit a bit: \"+binario2+\".\");\n        \n        /*\n          0101 (5)\n        | 0011 (3)\n          --------\n          0111 (7) El | O evalua todos los numeros y si al menos hay un solo 1 o un 1 solo verdadero sale 1;\n        */ \n        \n        resultbitXor = d ^ f;\n        String binario3 = String.format(\"%4s\", Integer.toBinaryString(resultbitXor)).replace(' ', '0');\n        System.out.println(\"Operador XOR de bit a bit: \"+binario3+\".\");\n        \n        /*\n          0101 (5)\n        ^ 0011 (3)\n          --------\n          0110 (6) El XOR ^ evalua todos los numeros y si el 1 o el 0 se repiten la saluda es 0 falso;\n        */\n        \n        resultbitNot = ~d;\n        String binario4 = String.format(\"%4s\", Integer.toBinaryString(resultbitNot)).replace(' ', '0');\n        System.out.println(\"Operador XOR de bit a bit: \"+binario4+\".\");\n    \n        /*\n        d = 5;\n        00000000000000000000000000000101  (5 en binario)\n        --------------------------------\n        11111111111111111111111111111010  (Resultado de ~5 en binario)\n        \n        La representación binaria 11111111111111111111111111111010 es -6 en decimal. Este es el resultado de la operación ~5 en complemento a dos.\n        */\n        \n        desplaizquieda = d << 1;\n        String binario5 = String.format(\"%4s\", Integer.toBinaryString(desplaizquieda)).replace(' ', '0');\n        System.out.println(\"Desplazamiento a la Izquierda (<<): \"+binario5+\".\");\n        \n        /*\n        0101(5) << 1 = 1010 se le agrega un 0 al final.\n        */\n        \n        despladerecha = d >> 1;\n        String binario6 = String.format(\"%4s\", Integer.toBinaryString(despladerecha)).replace(' ', '0');\n        System.out.println(\"Desplazamiento a la Derecha (>>): \"+binario6+\".\");\n        \n        /*\n        0101(5) >> 0010 se agrega un 0 a la izquierda al principio.\n        */\n        \n        desplaDconExtensióndeCero = e >>> 2;\n        String binario7 = String.format(\"%4s\", Integer.toBinaryString(desplaDconExtensióndeCero)).replace(' ', '0');\n        System.out.println(\"Desplazamiento a la Derecha (>>>): \"+binario7+\".\");\n        System.out.println(\"\");\n        \n        //Operadores Ternarios\n        \n        int max = (a > b) ? a : b;\n        System.out.println(\"Uso de condicional 'Ternario': El numero mayor es: \"+max);\n        System.out.println(\"\");\n        \n        //Operadores de Instancia\n        \n        Auto autogenerico = new Auto();\n        Toyota tcorolla = new Toyota();\n        System.out.println(\"Operador de Instancia da False porque autogenerico no herada de Toyota: \"+(autogenerico instanceof Toyota));\n        System.out.println(\"Operador de Instancia da True porque tcorolla herada de Auto: \"+(tcorolla instanceof Auto));\n        System.out.println(\"\");\n        \n        //Estructuras de Control\n        \n        if(a < b){\n            System.out.println(\"b es mayor que a\");\n        }\n        else {\n            System.out.println(\"a es mayor que b\");\n        }\n        System.out.println(\"\");\n        int day = 2;\n        switch (day) {\n        case 1:\n        System.out.println(\"Lunes\");\n        break;\n        case 2:\n        System.out.println(\"Martes\");\n        break;\n        case 3:\n        System.out.println(\"Miércoles\");\n        break;\n        default:\n        System.out.println(\"Día no válido\");\n        break;\n        }\n        System.out.println(\"\");\n        for(int i=10;i>=0;i--){\n            System.out.println(\"Bucle que decrece: \"+i);\n        }\n        \n        System.out.println(\"\");\n        \n        int w=0;\n        \n        while (w<=10){\n            System.out.println(\"Bucle normal: \"+w);\n            w++;\n        }\n        \n        System.out.println(\"\");\n        \n        int dow= 10 ;\n        \n        do {\n            System.out.println(\"bucle do while: \"+dow);\n            dow+=10;\n        }while(dow <=100);\n        \n        System.out.println(\"\");    \n        \n        //Excepciones\n       \n        try {\n            int resultex = 10 / 0;\n        } catch (ArithmeticException t) {\n            System.out.println(\"Error: División por cero.\");\n        }\n        System.out.println(\"\");\n        /* DIFICULTAD EXTRA (opcional):\n        * Crea un programa que imprima por consola todos los números comprendidos\n        * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.*/\n        \n        for(int i=10;i<=55;i++){\n            if(i%2==0 && i!=16 && i%3!=0 ){\n                System.out.println(i);\n            }\n            \n        }    \n        \n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/MarioYellowy.java",
    "content": "import java.io.FileWriter;\nimport java.io.IOException;\nimport java.io.PrintWriter;\nimport java.util.Scanner;\n\npublic class YellowDev {\n    public static void main(String[] args) {\n        int value = 1;\n        //Operadores\n\n        //Sufijo\n        value++;\n        System.out.println(value); //Ahora vale dos\n        value--;\n        System.out.println(value); //Vuelve a valer uno\n        //Unario\n        value = -value;\n        System.out.println(value); //Como solamente se aplica a un valor no es una resta sino una negacion, negar 1 es igual a -1\n        value = +value;\n        System.out.println(value); //No cambiara su valor debido a que si seguimos las leyes de los signos negativo mas positivo es negativo\n        value = --value;\n        System.out.println(value); //Ahora si relaiza el decremento pero solamente en uno dando como resultado -2\n        value = ++value;\n        System.out.println(value); //Ahora se realiza el aumento en uno\n        value = ~value;\n        System.out.println(value); //Como este valor utiliza los bits del valor qu3 en este caso es -1 al invertirlos se obtiene el 0 en binario.Por ello muestra 0\n\n        //Multiplicativo\n\n        value = 2;\n        //Multiplicacion\n        value = value * value;\n        System.out.println(value); //Se obtiene 4 de multiplicar 2 * 2\n        //Division\n        value = value / value;\n        System.out.println(value); //Se obtiene 1 de dividir 1 / 1\n        //Modulo\n        value = value % value;\n        System.out.println(value); //Se obtiene 0 ya que es el resto de dividir 1/1\n\n        //Aditivo\n\n        int value2 = 5;\n        //Suma\n        int result = value2 + value;\n        System.out.println(result); //Se obtiene 5 de sumar 0 de value y 5 de value2\n        //Resta\n        result = result - 3;\n        System.out.println(result); //Se obtiene 2 de restarle 3 a 5\n\n        //Cambio\n\n        value = 2; //El valor en binario de 2 es 0000 0010\n        value = value << 2;\n        System.out.println(value); //En este caso el valor binario se recorre hacia la izquierda dos veces, dando como resultado 0000 1000 que es 8\n        value = value >> 3;\n        System.out.println(value); //Ahora recorrimos 3 a la derecha entonces es 0000 0001 que es 1\n        //En caso del signo >>> la diferencia resalta en que se recorre la n cantidad de veces y llena de 0 a la izquierda\n\n        //Relacional\n\n        //Mayor que\n        int value1 = 5;\n        value2 = 8;\n        System.out.println(value1 > value2); //Hace la comparacion de los valores y devuelve un valor booleanos, en este caso es false porque 5 no es mayor que 8\n        //Menor que\n        System.out.println(value1 < value2); //En este caso si es true debido a que 5 si es menor que 8\n        int value3 = 5;\n        //Menor igual\n        System.out.println(value1 <= value3); //Aqui se hace una verificacion doble en donde verifica si el primer valor es menor o igual que el segundo valor, en este caso no es menor pero si es igual\n        //Mayor igual\n        System.out.println(value2 >= value3); //Y aqui aunque no son igual el value2 si es mayor que value3\n        //Intanceof, en este caso se puede usar para comparar instancias de diferentes objetos, nos devuelve valores booleanos con respecto si una isntancia se encuentra o no\n\n        //Igualdad\n\n        System.out.println(value == value2); //value=1, value2=8, como no son iguales devuelve un valor false\n        System.out.println(value != value2); //Devuelve un valor true ya que si son valores diferentes\n        //AND bit a bit\n        int value4 = 5;\n        int value5 = 8;\n        System.out.println(value5 & value4);\n        //Imprime 0 porque no hay ninguna coincidencia del numero 1 en la misma posicion\n        /*Lo que pasa en esta ocasion es que compara todos los digitos del numero binario\n          entonces si ambos son 1 el resultado sera 1 pero si hay un 0 el resultado sera sero, al final se saca\n          el valor generado de la comparacion de los binarios y surge un nuevo binario y ese es el resultado, solamente\n          se hace la conversion*/\n        //OR exclusivo bit a bit\n        System.out.println(value5 ^ value4); //Lo mismo que el anterior pero si hay al menos un numero entonces el valor es 1, dando como resultado 13\n        //OR inclusivo |\n        System.out.println(value5 | value4); //Retorna un 1 si y solo si uno de los valores en 1, pero si ambos son 1 devuelve un 0, en este caso imprime 13 nuevamente\n        //Y logico\n        //Su uso mas comun en las condicionales en donde el valor debe de cumplir una serie de reglas para que sea verdadera la condicional y sesguir con el flujo del codigo\n        if (value2 < 2 && value3 > 5) {\n            System.out.println(\"Yiyi\");\n        } else {\n            System.out.println(\"No yiyi\");\n        }\n        //OR logico\n        //Este es como el Y logico pero la diferencia radica en que si al menos un valor es verdadera la condicional se vuelve true\n        if (value2 < 2 || value3 > 5) {\n            System.out.println(\"Siu yiyi\");\n        } else {\n            System.out.println(\"Nou yiyi\");\n        }\n\n        /*\n         * Ternario\n         * EL uso de este se asemeja a la condicional if, donde se evalua una condicion y en base a si es true o false se brinda un resultado:\n         * */\n\n        boolean seraTrue = false;\n        value = 1;\n        value1 = 2;\n        result = seraTrue ? value : value1;\n        System.out.println(result);\n\n        //Asignacion\n\n        //igual\n        int newValue = 52;\n        System.out.println(newValue);\n        //Mas igual\n        newValue += 52;\n        System.out.println(newValue); //Le suma la cantidad y luego le agrega el valor si lo ponemos al reves no se refleja el cambio debido a que la suma no ocurre\n        //Menos igual\n        newValue -= 2;\n        System.out.println(newValue); //Le resta la cantidad y luego le asigna el valor\n        //Multiplicar igual\n        newValue *= 2;\n        System.out.println(newValue); //Le multiplica y asigna el valor\n        //Dividir igual\n        newValue /= 4;\n        System.out.println(newValue); //Le divide y asigna el valor\n        //Modulo igual\n        newValue %= 4;\n        System.out.println(newValue); //Le saca el modulo y asigna el valor\n        //&=, ^=, |=, <<=, >>=, >>>= estos operadores usan los ejemplos anteriores con los bits, entonces hace la funcion y asigna valor en una sola accion\n\n        //Estructuras de control\n        //Selectivas de seleccion o condicionales\n        //if\n        boolean moving = false;\n        if (moving) {\n            System.out.println(\"Stop\");  //Selectiva simple\n        } else if (moving == false) {    //Selectiva doble\n            System.out.println(\"god\");\n        } else {\n            System.out.println(\"God job\");\n        }\n        //Iterativas, de iteracion, de repeticion o repetitivas\n        //while\n        int contador = 5;\n        while (contador <= 8) {\n            System.out.println(\"Si\");\n            contador++;\n        }\n\n        //Do while\n        contador = 3;\n        do {\n            System.out.println(\"Yiyi\");\n            contador++;\n        } while (contador <= 5);\n\n        //for\n        int result10 = 1;\n        for (int i = 0; i < 10; i++) {\n            result10++;\n            System.out.println(result10); //Dato curioso se pueden hacer un ciclo infinito si se dejan los parametros del for vacios\n        }\n\n        //for each\n        int[] numbers = {1, 2, 3, 4, 5};\n        for (int numeber : numbers) {\n            System.out.println(numeber);\n        }\n        //Declaracion Break\n        int MyVariable = 6;\n        for (int i = 0; i < 10; i++) {\n            if (i != MyVariable) {\n                System.out.println(i);\n            } else {\n                break; //Terminar bucles\n            }\n        }\n        //Declaracion continue\n        int MyVariable2 = 6;\n        for (int i = 0; i < 10; i++) {\n            if (i != MyVariable2) {\n                System.out.println(i);\n            } else {\n                continue;  //Saltar el flujo en el punto que sea 6\n            }\n        }\n        //Declaracion return\n       /*\n       *  int Myvariable3 = 5;\n        if (Myvariable3 < 10) {\n            return Myvariable3 + 3;\n        }\n        System.out.println(Myvariable3);\n        return 0;\n       * */\n\n        //Declaracion yield\n        String weekDay = \"Thursday\";\n        int dayNumber = switch (weekDay) {\n            case \"MONDAY\", \"FRIDAY\", \"SUNDAY\" -> 1;\n            case \"TUESDAY\" -> 2;\n            case \"THURSDAY\", \"SATURDAY\" -> {\n                System.out.println(\"It's either Thursday or Saturday!\");\n                yield 3; // Usamos yield para devolver un valor después de ejecutar más instrucciones\n            }\n            case \"WEDNESDAY\" -> 4;\n            default -> {\n                System.out.println(\"Invalid day: \" + weekDay);\n                yield -1; // Usamos yield para devolver un valor predeterminado en caso de un día no válido\n            }\n        };\n        System.out.println(dayNumber);\n        //Switch case\n        String subject = \"Maths\";\n        switch (subject) {\n            case \"Maths\" -> System.out.println(\"Maths\");\n            case \"Sunny\" -> System.out.println(\"Sunny\");\n            case \"Algebraic\" -> System.out.println(\"Algebraic\");\n        }\n        //Try catch\n        PrintWriter out = null;\n/*\n        try {\n            System.out.println(\"Entering\" + \" try statement\");\n\n            out = new PrintWriter(new FileWriter(\"OutFile.txt\"));\n            for (int i = 0; i < SIZE; i++) {\n                out.println(\"Value at: \" + i + \" = \" + list.get(i));\n            }\n        } catch (IndexOutOfBoundsException e) {\n            System.err.println(\"Caught IndexOutOfBoundsException: \"\n                    +  e.getMessage());\n\n        } catch (IOException e) {\n            System.err.println(\"Caught IOException: \" +  e.getMessage());\n\n        } finally {\n            if (out != null) {\n                System.out.println(\"Closing PrintWriter\");\n                out.close();\n            }\n            else {\n                System.out.println(\"PrintWriter not open\");\n            }\n        }\n\n */\n        //Ejercicio extra\n        for (int i = 10; i <=  55; i++) {\n            if (i == 16 || (i % 3 == 0)) {\n                continue;\n            }\n            System.out.println(i);\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/Markayala13.java",
    "content": "public class RoadRamp02 {\n    public static void main(String[] args) {\n\n//        /*Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n//         Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n//          (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n//          */\n//        int a=15;\n//        int b=8;\n//\n//        System.out.println(\"Suma :\" + (a + b));\n//        System.out.println(\"resta :\" + (a - b));\n//        System.out.println(\"multiplicacion :\" + (a * b));\n//        System.out.println(\"modulo :\" + (a % b));\n//        System.out.println(\"Division :\" + (a / b));\n//\n////Operadores de comparacion\n//        int c = 5;\n//        int d = 7;\n//\n//        boolean igual = (c == d); // Comprueba si a es igual a b (igual será false).\n//        boolean noIgual = (c != d); // Comprueba si a no es igual a b (noIgual será true).\n//        boolean mayorQue = (c > d); // Comprueba si a es mayor que b (mayorQue será false).\n//        boolean menorIgual = (c <= d); // Comprueba si a es menor o igual que b (menorIgual será true).\n//\n////operadores de asignacion\n//        int x=10;\n//        x=10;\n//        x-=10;\n//        x+=10;\n//        x%=10;\n//        x/=10;\n//\n//        //Operadores logicos\n////        boolean z = true;\n////        boolean r= false;\n////        boolean result=z && r;\n////        boolean result=z || r;\n////        //boolean result=z !=r;\n//\n//        /*\n//        Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n// *   que representen todos los tipos de estructuras de control que existan\n// *   en tu lenguaje:\n// *   Condicionales, iterativas, excepciones...\n// * - Debes hacer print por consola del resultado de todos los ejemplos.\n//         */\n//\n//        int f=5;\n//        int o=9;\n//        boolean igual2 = (f == o);\n//        boolean noIgual2 = (f != o);\n//        boolean mayorQue2 = (f > o);\n//        boolean menorIgual2 = (f <= o);\n//\n//        System.out.println(igual2);\n//        System.out.println(noIgual2);\n//        System.out.println(mayorQue2);\n//        System.out.println(menorIgual2);\n//\n//\n//\n//        int a2=15;\n//        int b2=8;\n//\n//        System.out.println(\"Suma :\" + (a2 + b2));\n//        System.out.println(\"resta :\" + (a2 - b2));\n//        System.out.println(\"multiplicacion :\" + (a2 * b2));\n//        System.out.println(\"modulo :\" + (a2 % b2));\n//        System.out.println(\"Division :\" + (a2 / b2));\n//\n//        /*\n//        DIFICULTAD EXTRA (opcional):\n// * Crea un programa que imprima por consola todos los números comprendidos\n// * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n//         */\n//\n        for (int i = 10; i <= 55; i++) {\nint numero=i;\n            if (numero==16){\n                continue;\n            }else if(numero %3==0) {\n                continue;\n            }else if(numero %2 !=0) {\n                continue;\n            }\n\n            System.out.println(\"numero : \" + i);\n            }\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/Natalinacn.java",
    "content": "package com.example.headfirstjava;\n\nimport org.springframework.boot.SpringApplication;\n\npublic class Natalinacn {\n\n    public static void main(String[] args) {\n        SpringApplication.run(HeadFirstjavaApplication.class, args);\n\n        //#01-OPERADORES Y ESTRUCTURAS DE CONTROL\n\n        //Operador de Asignación (=)\n\n        int numero = 1;\n\n        System.out.println(\"La variable número tiene asignado el valor \" + numero);\n\n        //Operadores Aritméticos\n        //Suma (+)\n        int suma = 1 + 2;\n        System.out.println(\"El resultado de la suma es \" + suma);\n\n        //Resta (-)\n        int resta = 7 - 2;\n        System.out.println(\"El resultado de la resta es \" + resta);\n\n        //Multiplicación (*)\n        int multi = 5*5;\n        System.out.println(\"El resultado de la multiplicación es \" + multi);\n\n        //División (/)\n        int div = 8/4;\n        System.out.println(\"El resultado de la división es \" + div);\n\n        //Resto (%)\n        int resto = 4%2;\n        System.out.println(\"El resultado del resto es \" + resto);\n\n\n        /*Operadores unarios: Los operadores unarios sólo requieren un operando; realizan diversas operaciones,\n        como incrementar/decrementar un valor en uno, negar una expresión o invertir el valor de un booleano.*/\n\n        //+ Operador de más unario; indica un valor positivo (los números son positivos sin este operador)\n            int result = +1;\n            System.out.println(\"El valor de result es positivo \" + result);\n\n        //- Operador de menos unario; niega una expresión\n            result = -result;\n            System.out.println(\"El valor de resultado ahora es negativo \" + result);\n\n        //++ Operador de incremento; incrementa un valor en 1\n            result++;\n           System.out.println(\"El valor de result ahora se incrementó en 1\" + result);\n\n        //-- Operador de decremento; decrementa un valor en 1\n        result--;\n        System.out.println(\"El valor de result ahora se decrementó en 1\" + result);\n\n        //! Operador de complemento lógico; invierte el valor de un booleano\n        boolean exitoso = false;\n        System.out.println(\"Exitoso es falso \" + exitoso);\n        System.out.println(\"Exitoso con el operador ! cambia de valor a verdadero \" + !exitoso);\n\n\n        //Operadores de Igualdad y Relacionales\n        //== Igual a\n        int num1 = 1;\n        int num2 = 8;\n\n        if(num1 == num2){\n            System.out.println(\"Los números son iguales\");\n        }\n\n        //!= No igual a\n        if(num1 != num2 ){\n            System.out.println(\"Los números son diferentes\");\n        }\n\n        //> Mayor que\n        if(num1>num2){\n            System.out.println(\"El número 1 \" + num1 + \"es mayor al número 2\" + num2);\n        }\n\n        //>= Mayor o igual que\n        if(num1>=num2){\n            System.out.println(\"El número 1 \" + num1 + \"es mayor o igual al número 2\" + num2);\n        }\n\n        //< Menor que\n        if(num1<num2){\n            System.out.println(\"El número 1 \" + num1 + \"es menor al número 2\" + num2);\n        }\n\n        //<= Menor o igual que\n        if(num1<num2){\n            System.out.println(\"El número 1 \" + num1 + \"es menor o igual al número 2\" + num2);\n        }\n\n        //Operadores Condicionales\n        //&& AND condicional\n        //|| OR condicional\n\n        int value1 = 5;\n        int value2 = 2;\n\n        if(value1 == 5 && value2 ==2){\n            System.out.println(\"El value1 es 5 y el value 2 es 2\");\n        }\n\n        if(value1 == 5 || value2 == 5){\n            System.out.println(\"El value1 es 5 o el value2 es 5\");\n        }\n\n        //?: Ternario (abreviatura para una declaración if-then-else)\n        String ternario = (value1>0) ? \"El valor es mayor a 0\" : \"El valor es menor a 0\";\n        System.out.println(ternario);\n\n        //Operador de Comparación de Tipo\n\n        //instanceof Compara un objeto con un tipo especificado\n        Dog dog1 = new Dog();\n\n        System.out.println(\"El objeto dog1 es instancia de Dog? \" + (dog1 instanceof Dog));\n\n        //Operadores Bitwise y de Desplazamiento de Bits\n        //\n        //~ Complemento bitwise unario\n        //<< Desplazamiento a la izquierda con signo\n        //>> Desplazamiento a la derecha con signo\n        //>>> Desplazamiento a la derecha sin signo\n        //& AND bitwise\n        //^ OR exclusivo bitwise\n        //| OR inclusivo bitwise\n\n        int g = 5; // 5 en binario es 00000101\n\n        int bitwiseComplement = ~g; // bitwiseComplement es -6 (en binario 11111010)\n        int leftShift = g << 2; // leftShift es 20 (00010100)\n        int rightShift = g >> 1; // rightShift es 2 (00000010)\n        int unsignedRightShift = g >>> 1; // unsignedRightShift es 2 (00000010)\n\n        int h = 3; // 3 en binario es 00000011\n        int bitwiseAnd = g & h; // bitwiseAnd es 1 (00000001)\n        int bitwiseOr = g | h; // bitwiseOr es 7 (00000111)\n        int bitwiseXor = g ^ h; // bitwiseXor es 6 (00000110)\n\n\n\n        //ESTRUCTURAS DE CONTROL\n        //1. Estructuras Condicionales\n        //If\n        int edad = 18;\n        if(edad > 18){\n            System.out.println(\"Eres un adulto\");\n        }\n\n        //if-else\n        if(edad > 18){\n            System.out.println(\"Eres un adulto\");\n        }else{\n            System.out.println(\"No eres un adulto\");\n        }\n\n        //if-else if-else\n\n        int puntaje = 40;\n\n        if(puntaje>=85){\n            System.out.println(\"Eres muy inteligente\");\n        } else if (puntaje >= 60) {\n            System.out.println(\"Vas bien encaminado, sigue estudiando\");\n        } else if (puntaje >= 40) {\n            System.out.println(\"No seas vago, estudia más\");\n        }else{\n            System.out.println(\"No vas a aprender nada si sigues sin estudiar\");\n        }\n\n        //switch\n        int dia = 2;\n\n        switch (dia){\n            case 1:\n                System.out.println(\"El día es Lunes\");\n                break;\n            case 2:\n                System.out.println(\"El día es Martes\");\n                break;\n            case 3:\n                System.out.println(\"El día es Miércoles\");\n                break;\n                case 4:\n                System.out.println(\"El día es Jueves\");\n                break;\n            default:\n                System.out.println(\"Es otro día\");\n                break;\n        }\n\n        //2. Bucles\n        //for\n        for (int i = 0; i < 5; i++) {\n            System.out.println(\"Iteracion: \" + i);\n        }\n\n        //for-each\n\n        int[] arrayNumeros = {1, 5, 8, 9, 22};\n\n        for (int num : arrayNumeros) {\n            System.out.println(\"Número \" + num);\n        }\n\n        //while\n        int count = 0;\n        while (count < 5){\n            System.out.println(\"Count en el while \" + count);\n            count++;\n        }\n\n        //do-while\n        int countDoWhile = 0;\n        do {\n            System.out.println(\"Count en el do-while: \" + countDoWhile);\n            countDoWhile++;\n        }while(countDoWhile < 5);\n\n        //3. Estructuras de Control de Salto\n        //break\n        for (int i = 0; i < 10; i++) {\n            if (i == 5) {\n                break; // Salir del bucle cuando i es 5\n            }\n            System.out.println(\"Con el break: i: \" + i);\n        }\n\n\n        //continue\n        for (int i = 0; i < 10; i++) {\n            if (i % 2 == 0) {\n                continue; // Saltar la iteración actual si i es par\n            }\n            System.out.println(\"Con el continue: i: \" + i);\n        }\n\n        //yield: El yield se usa dentro de un bloque switch para devolver un valor después de realizar algún cálculo o lógica adicional.\n        //En este caso, se usa para devolver el número de días laborales restantes en la semana después de calcularlo.\n\n        Day diaYield = Day.MONDAY;\n        System.out.println(\"Días laborales restantes: \" + calculateRemainingWorkDays(diaYield));\n\n\n        //return\n                System.out.println(\"Sum con return: \" + add(5, 3));\n\n        //* DIFICULTAD EXTRA (opcional):\n        // * Crea un programa que imprima por consola todos los números comprendidos\n        // * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\n        for (int i = 10; i < 56; i++) {\n            if (i % 2 == 0 && i != 16 && i % 3 != 0) {\n                System.out.println(i);\n            }\n        }\n\n\n\n\n\n    }\n    //Método para return\n            public static int add(int a, int b) {\n                return a + b; // Terminar el método y devolver un valor\n\n        }\n\n        //Método para yield\n        // Método que utiliza switch con yield\n        public static int calculateRemainingWorkDays(Day d) {\n            return switch (d) {\n                case SATURDAY, SUNDAY -> 0;\n                default -> {\n                    int remainingWorkDays = 5 - d.ordinal();\n                    yield remainingWorkDays;\n                }\n            };\n        }\n\n    // Enumeración de días de la semana\n    enum Day {\n        MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY\n    }\n\n\n    }"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/Pakiuh.java",
    "content": "public class Pakiuh {\r\n    public static void main(String[] args) {\r\n        // Operadores aritméticos\r\n        int a = 10;\r\n        int b = 20;\r\n        System.out.println(\"a + b = \" + (a + b)); // Suma\r\n        System.out.println(\"a - b = \" + (a - b)); // Resta\r\n        System.out.println(\"a * b = \" + (a * b)); // Multiplicación\r\n        System.out.println(\"b / a = \" + (b / a)); // División\r\n        System.out.println(\"b % a = \" + (b % a)); // Módulo\r\n\r\n        // Operadores de asignación\r\n        int c = a;\r\n        System.out.println(\"c = a: \" + c); // Asignación\r\n        c += a;\r\n        System.out.println(\"c += a: \" + c); // Suma y asignación\r\n        c -= a;\r\n        System.out.println(\"c -= a: \" + c); // Resta y asignación\r\n\r\n        // Operadores de comparación\r\n        System.out.println(\"a == b: \" + (a == b)); // Igual a\r\n        System.out.println(\"a != b: \" + (a != b)); // No igual a\r\n        System.out.println(\"a > b: \" + (a > b)); // Mayor que\r\n        System.out.println(\"a < b: \" + (a < b)); // Menor que\r\n        System.out.println(\"b >= a: \" + (b >= a)); // Mayor o igual que\r\n        System.out.println(\"a <= b: \" + (a <= b)); // Menor o igual que\r\n\r\n        // Estructuras de control\r\n        // if-else\r\n        if (a < b) {\r\n            System.out.println(\"a es menor que b\");\r\n        } else {\r\n            System.out.println(\"a no es menor que b\");\r\n        }\r\n\r\n        // for loop\r\n        for(int i = 0; i < 5; i++) {\r\n            System.out.println(\"Número: \" + i);\r\n        }\r\n\r\n        // while loop\r\n        int i = 0;\r\n        while(i < 5) {\r\n            System.out.println(\"Número (while): \" + i);\r\n            i++;\r\n        }\r\n\r\n        // do-while loop\r\n        i = 0;\r\n        do {\r\n            System.out.println(\"Número (do-while): \" + i);\r\n            i++;\r\n        } while(i < 5);\r\n\r\n        // try-catch\r\n        try {\r\n            int sum = a + b;\r\n            if(sum > 30) {\r\n                throw new Exception(\"La suma es mayor que 30\");\r\n            }\r\n            System.out.println(\"La suma es: \" + sum);\r\n        } catch(Exception e) {\r\n            System.out.println(\"Ha ocurrido un error: \" + e.getMessage());\r\n        } finally {\r\n            System.out.println(\"Siempre se ejecuta el bloque finally\");\r\n        }\r\n\r\n        // Imprimir números pares entre 10 y 55 que no son 16 ni múltiplos de 3\r\n        for(i = 10; i <= 55; i++) {\r\n            if(i % 2 == 0 && i != 16 && i % 3 != 0) {\r\n                System.out.println(i);\r\n            }\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/Password1989.java",
    "content": "package org.roadmap.java.ejercicio.uno;\r\n\r\npublic class Password1989 {\r\n\r\n\tpublic static void dificultadExtra()\r\n\t{\r\n\t\t/*\r\n\t\t * Crea un programa que imprima por consola todos los números comprendidos\r\n\t\t * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3\r\n\t\t * \r\n\t\t */\r\n\t\t\r\n\t\tint min = 10;\r\n\t\tint max = 55;\r\n\t\t\r\n\t\tfor (int i = 10; i <= max; i++)\r\n\t\t{\r\n\t\t\tif( (i%2==0) && (i!=16) && (i%3!= 0))\r\n\t\t\t{\r\n\t\t\t\tSystem.out.println(String.format(\"El numero %s cumple las condiciones\",i));\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\tpublic static void main(String[] args) {\r\n\t\t/*\r\n\t\t * EJERCICIO:\r\n\t\t * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\r\n\t\t *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\r\n\t\t *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\r\n\t\t * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\r\n\t\t *   que representen todos los tipos de estructuras de control que existan\r\n\t\t *   en tu lenguaje:\r\n\t\t *   Condicionales, iterativas, excepciones...\r\n\t\t * - Debes hacer print por consola del resultado de todos los ejemplos.\r\n\t\t *\r\n\t\t * DIFICULTAD EXTRA (opcional):\r\n\t\t * Crea un programa que imprima por consola todos los números comprendidos\r\n\t\t * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\r\n\t\t *\r\n\t\t * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\r\n\t\t */\r\n\t\t\r\n\t\t/*\r\n\t\t * Operadores: \r\n\t\t * Aritmeticos: Suma, Resta, Division, Producto\r\n\t\t */\r\n\t\t\r\n\t\tSystem.out.println(String.format(\"Suma 10+3= %s\", 10+3));\r\n\t\tSystem.out.println(String.format(\"Resta 10-3= %s\", 10-3));\r\n\t\tSystem.out.println(String.format(\"Division 10/3= %s\", 10/3));\r\n\t\tSystem.out.println(String.format(\"Producto 10 x 3= %s\", 10*3));\r\n\t\tSystem.out.println(String.format(\"Resto 10/3= %s\", 10%3));\r\n\t\t//System.out.println(String.format(\"Exponente 10/3= %s\", 10^3));\r\n\t\t\r\n\t\t/*\r\n\t\t * Operadores: \r\n\t\t * Lógicos: disruptivos && || sin disrupción & | ^\r\n\t\t * \r\n\t\t * && AND Logico\r\n\t\t * || OR Logico\r\n\t\t * Los operadores sin disrupción ejecutan todas las expresiones aun cuando el resultado sea claramente false o true.\r\n\t\t * \r\n\t\t */\r\n\t\t\r\n\t\t/*\r\n\t\t * Operadores: \r\n\t\t * Comparativos: < > <= >= == !=\r\n\t\t * < menor\t\t\ta < b\r\n\t\t * > mayor\t\t\ta > b\r\n\t\t * <= menor igual\ta <= b\r\n\t\t * >= mayor igual\ta >= b\r\n\t\t * == igual\t\t\ta == b\r\n\t\t * != distinto\t\ta != b\r\n\t\t */\r\n\t\t\r\n\t\t/*\r\n\t\t * Operadores: \r\n\t\t * Asignación: = --= += *= %= /= >= <=>>= <<= >>>= <<<=\r\n\t\t * =\tAsignación\t\t\t\t\ta = b\r\n\t\t * +=\tSuma y asignación\t\t\ta += b (a=a + b)\r\n\t\t * -=\tResta y asignación\t\t\ta -= b (a=a - b)\r\n\t\t * *=\tMultiplicación y asignación\ta *= b (a=a * b)\r\n\t\t * /=\tDivisión y asignación\t\ta / b (a=a / b)\r\n\t\t * %=\tMódulo y asignación\t\t\ta % b (a=a % b)\r\n\t\t */\r\n\t\t\r\n\t\tint a = 5;\r\n\t\tint b = 8;\r\n\t\t\r\n\t\tint ejemploAsignacion = 0;\r\n\t\t\r\n\t\tejemploAsignacion += a;\r\n\t\t\r\n\t\tSystem.out.println(String.format(\"Resultado ejemplo: %s\",ejemploAsignacion));\r\n\t\t\r\n\t\t\r\n\t\tejemploAsignacion -= b;\r\n\t\t\r\n\t\tSystem.out.println(String.format(\"Resultado ejemplo: %s\",ejemploAsignacion));\r\n\t\t\r\n\t\tejemploAsignacion *= a;\r\n\t\t\r\n\t\tSystem.out.println(String.format(\"Resultado ejemplo: %s\",ejemploAsignacion));\r\n\t\t\r\n\t\tejemploAsignacion /= b;\r\n\t\t\r\n\t\tSystem.out.println(String.format(\"Resultado ejemplo: %s\",ejemploAsignacion));\r\n\t\t\r\n\t\tejemploAsignacion %= a;\r\n\t\t\r\n\t\tSystem.out.println(String.format(\"Resultado ejemplo: %s\",ejemploAsignacion));\r\n\t\t\r\n\t\t/*\r\n\t\t * Operadores: \r\n\t\t * Incremento: a++ (postincremento) y ++a (preincremento)\r\n\t\t * Decremento: a-- (postdecremento) y --a (predecremento)\r\n\t\t * \r\n\t\t */\r\n\t\t\r\n\t\tint j = 0;\r\n\t\t\r\n\t\tSystem.out.println(String.format(\"EjemploIncremento: %s\",j));\r\n\r\n\t\tSystem.out.println(String.format(\"J vale: %s, EjemploPOSTIncremento: %s\",j,j++));\r\n\t\tSystem.out.println(String.format(\"J vale: %s, EjemploPREIncremento: %s\",j,++j));\r\n\t\tSystem.out.println(String.format(\"J vale: %s, EjemploPOSTDecremento: %s\",j,j--));\r\n\t\tSystem.out.println(String.format(\"J vale: %s, EjemploPREDecremento: %s\",j,--j));\r\n\t\t\r\n\t\t/*\r\n\t\t * Operadores: \r\n\t\t * Ternario: x == y ? x: y;\r\n\t\t * \r\n\t\t * Si se cumple la primera parte, x valdrá x si no, valdrá y\r\n\t\t */\r\n\t\t\r\n\t\tint x = 10;\r\n\t\tint y = 20;\r\n\t\t\r\n\t\tSystem.out.println(x == y ? x: y);\r\n\t\t\r\n\t\t/*\r\n\t\t * Operadores: \r\n\t\t * Bit: ^ ! & ~ << >> <<< >>>\r\n\t\t * \r\n\t\t */\r\n\t\t\r\n\t\t/*\r\n\t\t * Estructuras de control: Condicionales, iterativas, excepciones\r\n\t\t * IF:\r\n\t\t * La sentencia if permite llevar a cabo la ejecución condicional de sentencias. \r\n\t\t * Se ejecutan las sentencias si al evaluar la expresión se obtiene un valor booleano true.\r\n\t\t * \r\n\t\t */\r\n\t\t\r\n\t\tboolean condicion = true;\r\n\t\tif (condicion)\r\n\t\t{\r\n\t\t\tSystem.out.println(\"True\");\r\n\t\t}\r\n\t\telse \r\n\t\t\tSystem.out.println(\"False\");\r\n\t\t\r\n\t\t/*\r\n\t\t * SWITCH:\r\n\t\t * La sentencia switch en la que se indican los posibles valores que puede tomar la variable y las sentencias que se tienen que ejecutar\r\n\t\t * sí es que la variable coincide con alguno de dichos valores.\r\n\t\t * Cada case ejecutará las sentencias correspondientes, con base en el valor de la variable, que deberá de evaluarse con valores de tipo byte, char, short o int.\r\n\t\t * Si el valor de la variable no coincide con ningún valor, entonces se ejecutan las sentencias por default, sí es que las hay.\r\n\t\t * La sentencia break al final de cada case transfiere el control al final de la sentencia switch; de esta manera, cada vez que se ejecuta un case todos los enunciados case restantes son ignorados y termina la operación del switch.\r\n\t\t * \r\n\t\t *\r\n\t\t */\r\n\t\t\r\n\t\tString cadena = \"salir\";\r\n\t\t\r\n\t\tswitch (cadena)\r\n\t\t{\r\n\t\tcase \"salir\":\r\n\t\t\tSystem.out.println(cadena);\r\n\t\t\tbreak;\r\n\t\tdefault:\r\n\t\t\tSystem.out.println(\"default\");\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\t\r\n\t\t/*\r\n\t\t * FOR:\r\n\t\t * \r\n\t\t */\r\n\t\t\r\n\t\tfor (int iterador=0; iterador < 5; iterador++)\r\n\t\t{\r\n\t\t\tSystem.out.println(iterador);\r\n\t\t}\r\n\t\t\r\n\t\t/* \r\n\t\t * WHILE:\r\n\t\t * \r\n\t\t */\r\n\t\t\r\n\t\tboolean condicionWhile = true;\r\n\t\twhile (condicionWhile) {\r\n\t\t\tSystem.out.println(condicionWhile);\r\n\t\t\tcondicionWhile = false;\r\n\t\t}\r\n\t\t\r\n\t\t/*\r\n\t\t * DO WHILE:\r\n\t\t * \r\n\t\t */\r\n\t\t\r\n\t\tdo {\r\n\t\t\tSystem.out.println(condicionWhile);\r\n\t\t\tcondicionWhile = false;\r\n\t\t} while (condicionWhile);\r\n\t\t\r\n\t\t/*\r\n\t\t * BREAK; CONTINUE; RETURN;\r\n\t\t * \r\n\t\t */\r\n\t\t\r\n\t\t//dificultadExtra();\r\n\t}\r\n\r\n}\r\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/Pbjmg.java",
    "content": "public class Pbjmg {\n    public static void main(String[] args){\n\n        // Operadores aritmeticos\n        int suma = 24 + 5;  //29\n        double resta = 3.2 - 1.1;   //2.1\n        double division = 5 / 2;    //2.5\n        int modulo = 6 % 2;     //0\n        int multiplicacion = 10 * 2;    //20\n\n        // Operadores logicos\n        boolean andLogico = (5 > 3 && 8 > 4);   //true\n        boolean notLogico = !(8>2);     //false\n\n        // Operadores de asignacion\n        int x = 8; //8\n        x += 2;     //10\n        x -= 5;     //5\n        x *= 4;     //20\n        x /= 2;     //10\n        x %= 2;     //0\n\n        // Operadores de comparacion\n        boolean esIgual = (5 == 5); //true\n        boolean esDiferente = (5 != 3); //true\n        boolean mayor = (4 > 2);  //true\n        boolean menor = (1 < 6); //true\n        boolean mayorIgual = (9 >= 9); //true\n        boolean menorIgual = (8<=8); //true\n\n        // Operadores de incremento y decremento\n        int a =  5; \n        a ++; //6\n        int b = 4;\n        b--; //3\n        int preIncremento = ++a + --b; //9 (incrementa o decrece el valor antes de devolverlo)\n        System.out.println(a);\n        System.out.println(b);\n        System.out.println(preIncremento);\n\n        // Operador ternario\n        int edad = 38;\n        String mensaje = (edad >= 25) ? \"Viejo\" : \"Joven\"; //Viejo\n        System.out.println(mensaje);\n        //------------------------------------------------\n\n        // Estructuras Condicionales\n        //if-else\n        edad = 18;\n        if (edad>=18) {\n            System.out.println(\"Eres mayor de edad\");\n        }else {\n            System.out.println(\"Eres menor de edad\");\n        }\n\n        //if-else if-else\n        int nota = 75;\n        if(nota>=90) {\n            System.out.println(\"Sobresaliente\");\n        }else if(nota>=70){\n            System.out.println(\"Notable\");\n        }else {\n            System.out.println(\"Aprobado\");\n        }\n\n        //Switch\n        int dia = 5;\n        String resultado = switch (dia) {\n            case 1 -> \"Lunes\";\n            case 2 -> \"Martes\";\n            case 3 -> \"Miercoles\";\n            case 4 -> \"Jueves\";\n            case 5 -> \"Viernes\";\n            case 6 -> \"Sabado\";\n            case 7 -> \"Domingo\";\n            default -> \"No valido\";\n        };\n        System.out.println(resultado);\n\n        //Estructuras repetitivas, Bucles\n        //While\n        int i = 0;\n        while(i <= 5) {\n            System.out.println(i);\n            i++;\n        }\n\n        //do-while\n        int j = 0;\n        do {\n            System.out.println(j);\n            j++;\n        }while(j<=5);\n\n        //for\n        for(int k = 0; k <=5; k++) {\n            System.out.println(\"Iteracion: \" + k);\n        }\n\n        //for-each\n        int[] lista = {1,2,3,4,5};\n        for(int num : lista) {\n            System.out.print(num);\n        }\n\n        // Estructuras de control, interrupcion\n        //break\n        for(i = 0; i < 10; i++) {\n            if(i == 5) { \n                break; // Se detiene la iteracion en 5\n            }\n            System.out.println(i);\n        }\n\n        //continue\n        for(i = 0; i < 10; i++) {\n            if(i == 5) {\n                continue; // Se salta el numero 5\n            }\n            System.out.println(i);\n        }\n\n        //return\n        System.out.println(sumar(10,25));\n        System.out.println();\n        \n        //------------------ Opcional\n        /*\n        Imprimimos por pantalla los numeros comprendidos del 10 al 55 incluidos\n        que sean pares, saltandonos el 16 y que no sean multiplos de 3\n         */ \n        for(i = 10; i <= 55; i++) {\n            if(i%2==0 && i != 16 && i %3 != 0){\n                System.out.println(i);\n            }\n        }\n\n        \n    }\n\n    //return\n    public static int sumar (int num1,int num2) {\n        return num1 + num2;\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/Peeanoot.java",
    "content": "import java.util.Scanner;\n\npublic class Peeanoot {\n\n    public static void main(String[] args) {\n        // Operadores Aritméticos\n        int a = 10, b = 5;\n        int suma = a + b;\n        int resta = a - b;\n        int multiplicacion = a * b;\n        int division = a / b;\n        int modulo = a % b;\n\n        System.out.println(\"Operadores Aritméticos:\");\n        System.out.println(\"Suma: \" + suma);\n        System.out.println(\"Resta: \" + resta);\n        System.out.println(\"Multiplicación: \" + multiplicacion);\n        System.out.println(\"División: \" + division);\n        System.out.println(\"Módulo: \" + modulo);\n\n        // Operadores Lógicos\n        boolean condicion1 = true, condicion2 = false;\n        boolean andLogico = condicion1 && condicion2;\n        boolean orLogico = condicion1 || condicion2;\n        boolean notLogico = !condicion1;\n\n        System.out.println(\"\\nOperadores Lógicos:\");\n        System.out.println(\"AND Lógico: \" + andLogico);\n        System.out.println(\"OR Lógico: \" + orLogico);\n        System.out.println(\"NOT Lógico: \" + notLogico);\n\n        // Operadores de Comparación\n        int num1 = 10, num2 = 20;\n        boolean igual = (num1 == num2);\n        boolean noIgual = (num1 != num2);\n        boolean mayorQue = (num1 > num2);\n        boolean menorQue = (num1 < num2);\n\n        System.out.println(\"\\nOperadores de Comparación:\");\n        System.out.println(\"Igual: \" + igual);\n        System.out.println(\"No Igual: \" + noIgual);\n        System.out.println(\"Mayor Que: \" + mayorQue);\n        System.out.println(\"Menor Que: \" + menorQue);\n\n        // Operadores de Asignación\n        int x = 5;\n        x += 3;\n        System.out.println(\"\\nOperadores de Asignación:\");\n        System.out.println(\"Valor de x después de la asignación: \" + x);\n\n        // Operadores de Identidad\n        String cadena1 = \"Hola\";\n        String cadena2 = \"Hola\";\n        boolean sonIguales = (cadena1 == cadena2);\n\n        System.out.println(\"\\nOperadores de Identidad:\");\n        System.out.println(\"Son Iguales (Identidad): \" + sonIguales);\n\n        // Operadores de Pertenencia\n        int[] arreglo = {1, 2, 3, 4, 5};\n        boolean contieneTres = contains(arreglo, 3);\n\n        System.out.println(\"\\nOperadores de Pertenencia:\");\n        System.out.println(\"Contiene el número 3 (Pertenencia): \" + contieneTres);\n\n        // Operadores de Bits\n        int numeroBits = 5; // Representación binaria: 101\n        int operacionAND = numeroBits & 3; // Resultado: 1 (1 en binario)\n\n        System.out.println(\"\\nOperadores de Bits:\");\n        System.out.println(\"Operación AND Bit a Bit: \" + operacionAND);\n\n        // Estructuras de Control Condicionales\n        int edad = 18;\n        if (edad >= 18) {\n            System.out.println(\"\\nEstructuras de Control Condicionales:\");\n            System.out.println(\"Es mayor de edad.\");\n        } else {\n            System.out.println(\"\\nEstructuras de Control Condicionales:\");\n            System.out.println(\"Es menor de edad.\");\n        }\n\n        // Estructuras de Control Iterativas\n        System.out.println(\"\\nEstructuras de Control Iterativas:\");\n        for (int i = 1; i <= 3; i++) {\n            System.out.println(\"Iteración \" + i);\n        }\n\n        // Estructuras de Control de Excepciones\n        Scanner scanner = new Scanner(System.in);\n        try {\n            System.out.println(\"\\nEstructuras de Control de Excepciones:\");\n            System.out.print(\"Ingrese un número entero: \");\n            int numeroIngresado = scanner.nextInt();\n            System.out.println(\"Número ingresado: \" + numeroIngresado);\n        } catch (Exception e) {\n            System.out.println(\"Error: Ingrese un número válido.\");\n        } finally {\n            scanner.close();\n        }\n\n        // Imprimir números entre 10 y 55 (pares, no 16 ni múltiplos de 3)\n        System.out.println(\"\\nNúmeros entre 10 y 55 (pares, no 16 ni múltiplos de 3):\");\n        for (int num = 10; num <= 55; num++) {\n            if (num % 2 == 0 && num != 16 && num % 3 != 0) {\n                System.out.print(num + \" \");\n            }\n        }\n    }\n\n    // Método para verificar la pertenencia en un array\n    private static boolean contains(int[] array, int target) {\n        for (int element : array) {\n            if (element == target) {\n                return true;\n            }\n        }\n        return false;\n    }\n}\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/RighelCH.java",
    "content": "package retos;\n\npublic class Uno {\n\n\tpublic static void main(String[] args) {\n\tint a=5, b=7;               \n\tboolean x = true, y = false;\n\tOperacionesAritméticas(a,b);\n\tOperadoresLógicos(x,y);\n\tOperadorComparación(a,b);\n\tAsignación(a);\n\tOperadorBit(a,b); //5 en binario=0101    7 en binario=111\n\tCondicional(a,b);\n\tIterativas(a);\n\t//Excepciones\n\ttry {\n\t     //operación aritmética que podría generar una excepción\n\t    int resultado = 10 / 0; // Esto generará una ArithmeticException\n\t} catch (ArithmeticException e) {\n\t    //  Si se genera una excepción, captura y maneja la excepción aquí\n\t    System.out.println(\"Error aritmético: \" + e.getMessage());\n\t}\n//--------------EJERCICIO EXTRA---------------------------------------------------\n\t\t/*Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.*/\n\t\tfor(int i=10;i<=55;i+=2) {\n\t\t\tif(i!=16 && i%3!=0)\n\t\t\t\tSystem.out.print(i+ \" \");\n\t\t}\n\t}\n\t\n\t\tstatic void OperacionesAritméticas (int a, int b) {\n\t\t\t int suma = a + b;\n\t\t        int resta = a - b;\n\t\t        int multiplicacion = a * b;\n\t\t        int division = a / b;\n\t\t        int modulo = a % b;\n\n\t\t        System.out.println(\"Suma: \" + suma);\n\t\t        System.out.println(\"Resta: \" + resta);\n\t\t        System.out.println(\"Multiplicación: \" + multiplicacion);\n\t\t        System.out.println(\"División: \" + division);\n\t\t        System.out.println(\"Módulo: \" + modulo);\n\t\t}\n\t\tstatic void OperadoresLógicos(boolean x, boolean y) {\n\t\n\t\t\tboolean and = x && y;\n\t\t\tboolean or = x || y;\n\t\t\tboolean not = !x;\n\n\t\t\tSystem.out.println(\"AND: \" + and);\n\t\t\tSystem.out.println(\"OR: \" + or);\n\t\t\tSystem.out.println(\"NOT: \" + not);\n\t\t}\n\t\tstatic void OperadorComparación(int a, int b) {\n\t\t\t\n\t\t\tboolean igual = (a == b);\n\t\t\tboolean noIgual = (a != b);\n\t\t\tboolean mayor = (a > b);\n\t\t\tboolean menor = (a < b);\n\n\t\t\tSystem.out.println(\"Igual: \" + igual);\n\t\t\tSystem.out.println(\"No Igual: \" + noIgual);\n\t\t\tSystem.out.println(\"Mayor: \" + mayor);\n\t\t\tSystem.out.println(\"Menor: \" + menor);\n\n\t\t}\n\t\tstatic void Asignación(int a) {\n\t\t\tSystem.out.println(\"Variable: \" + a);\n\t\t\ta += 10;\n\t\t\tSystem.out.println(\"Variable: \" + a);\n\t\t\ta -= 7;\n\t\t\tSystem.out.println(\"Variable: \" + a);\n\t\t}\n\t\tstatic void OperadorBit(int a, int b) {\n\t\n\t\t\tint andBits = a & b;\n\t\t\tint orBits = a | b;\n\t\t\tint xorBits = a ^ b;\n\t\t\tint complemento = ~a;\n\n\t\t\tSystem.out.println(\"AND Bits: \" + andBits);\n\t\t\tSystem.out.println(\"OR Bits: \" + orBits);\n\t\t\tSystem.out.println(\"XOR Bits: \" + xorBits);\n\t\t\tSystem.out.println(\"Complemento: \" + complemento);\n\n\t\t}\n\t\tstatic void Condicional(int edad,int numero) {\n\t\t\t\n\t\t\tif (edad >= 18) {\n\t\t\t    System.out.println(\"Es mayor de edad\");\n\t\t\t} else {\n\t\t\t    System.out.println(\"Es menor de edad\");\n\t\t\t}\n\t\t\tswitch(numero) {\n\t\t\tcase 1,2,3,4,5,6: System.out.println(\"Es un numero menor que 7\");\n\t\t\tcase 7: System.out.println(\"El número es 7\");\n\t\t\tdefault: System.out.println(\"Es un numero mayor que 7\");\n\t\t\t}\n\n\t\t}\n\t\tstatic void Iterativas(int a) {\n\t\t\tfor (int i = 0; i < a; i++) {\n\t\t\t    System.out.println(\"Iteración: \" + i);\n\t\t\t}\n\n\t\t\tint j = 0;\n\t\t\twhile (j < a) {\n\t\t\t    System.out.println(\"Iteración while: \" + j);\n\t\t\t    j++;\n\t\t\t}\n\n\t\t}\n\t\n\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/RodrigoGit87.java",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\npublic class RodrigoGit87 {\n    public static void main(String[] args){\n    //operadores aritmeticos\n    int num1 = 2;\n    int num2 = 5;\n\n    int suma = num1 + num2;\n    int resta = num2 - num1;\n    int multiplicacion = num1 * num2;\n    double division = num1 / num2;\n    double restoDivision = num1 % num2;\n    double potencia = Math.pow(num1, num2);\n\n    IO.println (\" suma: \" + suma + \"\\n resta:\" + resta+ \" \\n multiplicacion: \"+multiplicacion+ \"\\n division: \"\n            + division + \"\\n resto: \"+ restoDivision+ \"\\npotencia: \" + potencia);\n\n    //ASignacion\n    num1 = num2;\n        IO.println( num1); //ahora num1 vale num2 (5)\n\n    num1 = num2 * 2; //num1 sigue valiendo 5\n        IO.println( num1 ); //  ahora vale 10 por que num2 + 2 =  '5 x 2' = 10\n\n    //se puede asignar el valor resultante a la variable declarada, simplemente añadiendo el operador aritmetico al signo igual\n    num1 += 69;\n    num1 -= 69;\n    num1 *= num2; // num1= 10 * num2= 5\n         IO.println(num1); //ahora num1=50\n    num1 /= 2;\n         IO.println(num1);//ahjora num1 = 25\n    num2 %= 5;\n         System.out.println(num2); //num2 ahora valdra el resultado del resto de la division. (num2 = 0)\n\n\n    //Comparacion\n    int a, b;\n    a= 33;\n    b= 3;\n\n        IO.println(\"a == b: \" + (a == b)); // Es falso por que el  valor que se asigno a 'a' fue 33 y 'b' vale 3\n    // lo comprobamos->\n        IO.println(\"a == 33: \" + (a == 33));// imprime un true por que comparar 33 con 33, efectivamente es 33\n\n        IO.println(\" a != b:\" + (a != b)); // a es distinto de b? true\n\n        IO.println(\"\\notros comparadores(faciles de entender a simple vista)\");\n        IO.println(\" a > b:\" + (a > b)); // 33 mayor q 3? true\n        IO.println(\" a >= b:\" + (a >= b)); // 33 mayor o igual q 3? true\n        IO.println(\" a < b:\" + (a < b)); //....\n        IO.println(\" a <= b:\" + (a <= b));\n\n\n    // Lógicos\n        IO.println(\"\\nLógicos\");\n    // Y (AND)\n        IO.println(\"\\nTabla de verdad con el operador Y &&\");\n    // Solo es verdad cuando los dos valores son verdad\n        IO.println(\"true && true: \" + (true && true));\n        IO.println(\"true && false: \" + (true && false));\n        IO.println(\"false && true: \" + (false && true));\n        IO.println(\"false && false: \" + (false && false));\n\n        IO.println(\"Ejemplo, 2 > 0 && 2 == 2: \" + (2 > 0 && 2 == 2)); // ambas son ciertas, true\n\n    // O (OR)\n        IO.println(\"\\nTabla de verdad con el operador O ||\");\n    // Solo es falso cuando los dos valores son falsos\n        IO.println(\"true || true: \" + (true || true));\n        IO.println(\"true || false: \" + (true || false));\n        IO.println(\"false || true: \" + (false || true));\n        IO.println(\"false || false: \" + (false || false));\n        IO.println(\"Ejemplo, 3 > 1 || 5 == 8: \" + (3 > 1 || 5 == 8)); // 3>1? si(true) O 5 es lo mismo que 8? no (false). REsultado final true\n    //por que una condicion si es verdadera.\n\n    // NO (NOT)\n    // Se usa el signo de admiracion\n        IO.println(\"\\nEl operador NOT ! Niega algo q es verdad, por tanto será falso y viceversa\");\n        IO.println(\"Ejemplo, (!(3 > 1) || 5 == 8): \" + (!(3 > 1) || 5 == 8));\n\n    // Unarios\n        IO.println(\"\\nUnarios, valor de b=3\");\n\n        IO.println(\"+b: \" + (+b));// lo hace positivo\n        IO.println(\"-b: \" + (-b));// lo hace negativo\n        IO.println(\"++b: \" + (++b));// PreIncremento; si esta delante va a incrementar el valor antes de imprimirlo\n        IO.println(\"b++: \" + (b++));/*\n     * Si el incremento va detrás, se imprime el valor actual y el valor final queda\n     * guardado hasta la proxima iteracion.\n     */\n        IO.println(\"Valor de b despues de la iteracion b++: \" + (b));\n        IO.println(\"--b: \" + (--b));// Decremento, igual q con el incremento\n\n        //ESTRUCTURAS DE CONTROL\n        //condicionales\n        int x= 10;\n        int y = 13;\n        int numMayor, numMenor; //declarar variables fuera del bucle si queremos usarlas fuera de él.\n           // IF, ELSE IF\n            if ( x > y){ //lo q va dentro de las llaves se conoce como scope o ámbito. variables declaradas aqui dejan de existir fuera de él.\n                        //por eso se declaran las variables fuera del scope, para q sigan existiendo uan vez asignados los valores.\n                 numMayor = x;\n                 IO.println(\"numero mayor: \" + numMayor);\n            } else if ( x < y){\n                numMayor = y;\n                IO.println(\"numero mayor: \" + numMayor);\n            } else IO.println(\" Son iguales \");\n\n            //BUCLES\n            //for\n            System.out.println(\" -ciclo for-\");\n            for (int i=0; i <= 10; i+=2){\n            IO.println(\"\\n numeros pares: \" + i);\n            }\n            //while\n            System.out.println(\" -ciclo while-\");\n               int i = 0;\n                while(i <= 10){\n                    IO.println(\"\\n numeros pares: \" + i);\n                    i+=2;\n                }\n            //do while\n            i = 0; // reset de i al valor 0\n            System.out.println(\"\\n -ciclo  Do while-\");\n                do{\n                    i += 2;\n                    IO.println(\"numeros pares: \" + i);\n                }while(i <= 10);\n\n            // EXCEPCIONES - try-catch-finally\n        try {\n            var resultado = 10 / 0;\n        } catch (ArithmeticException e) {\n            System.err.println(\"\\nNo se puede dividir por 0 :P\");\n        } finally {\n            System.out.println(\" el codigo continua...\");\n        }\n        System.out.println(\" \");\n            //throw (Crear una clase y su metodo throw fuera del main)\n            /*EJemplo:\n            *public class ClaseThrow (){\n            * public void verificarEdad (int edad) throws IllegalArgumentException {\n                if (edad < 18)System.out.println(\" Tienes q ser mayor de edad\");\n                else if (edad >= 65 ) System.out.println(\" Demasiado mayor \" );\n                else System.out.println(\" En el prime \");\n        *       }\n        *     }*/\n\n        //EJERCICIO EXTRA\n        System.out.println(\"\\nNumeros pares del 10 al 55\");\n        for ( i = 10; i <= 55; i+=2){\n            if (i % 3 == 0 || i ==16) continue;\n            System.out.println(\" numero par: \" + i);\n        }\n    }\n}\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/RoniPG.java",
    "content": "\n// @Roni\n\npublic class OPERADORES_Y_ESTRUCTURAS_DE_CONTROL_01 {\n\n\tpublic static void main(String[] args) {\n\t\t// TODO Auto-generated method stub\n\t\t\n\t\tSystem.out.println(\"Tipo de operadores.\");\n\t\t\n\t\tSystem.out.println(\"Operadores Aritmeticos.\");\n\t\t\n\t\tSystem.out.println(\"Suma +, Resta -, Division /, Multiplicacion *, Resto % (En la division inexacta = lo que sobra)\"); \n\t\t\n\t\tSystem.out.println(\"Ejemplos\");\n\t\t\n\t\tint a = 2;\n\t\tint b = 3;\n\t\t\n\t\tint suma = a + b;\n\t\tSystem.out.println(a + \" + \" + b + \" = \" + suma);\n\t\t\n\t\tint resta = a - b;\n\t\tSystem.out.println(a + \" - \" + b + \" = \" + resta);\n\t\t\n\t\tint division = a / b;\n\t\tSystem.out.println(a + \" / \" + b + \" = \" + division);\n\t\t\n\t\tint multiplicacion = a * b;\n\t\tSystem.out.println(a + \" * \" + b + \" = \" + multiplicacion);\n\t\t\n\t\tint resto = a % b;\n\t\tSystem.out.println(a + \" % \" + b + \" = \" + resto);\n\t\t\n\t\tSystem.out.println(\"Operadores de Asignacion.\");\n\t\t\n\t\tSystem.out.println(\" = para asignar el valor sobrescirbiendolo\");\n\t\tSystem.out.println(\"+= sumar a la variable el valor dedicidido\");\n\t\tSystem.out.println(\"-= restar a la variable el valor dedicidido\");\n\t\tSystem.out.println(\"*= mutilpicar a la variable el valor dedicidido\");\n\t\tSystem.out.println(\"/= dividir a la variable el valor dedicidido\");\n\t\t\n\t\tSystem.out.println(\"Ejemplos\");\n\t\t\n\t\tSystem.out.println(a);\n\t\tSystem.out.println(a + \" += 2 \");\n\t\ta += 2;\n\t\tSystem.out.println(a);\n\t\tSystem.out.println(a + \" -= 2 \");\n\t\ta -= 2;\n\t\tSystem.out.println(a);\n\t\tSystem.out.println(a + \" *= 2 \");\n\t\ta *= 2;\n\t\tSystem.out.println(a);\n\t\tSystem.out.println(a + \" /= 2 \");\n\t\ta /= 2;\n\t\tSystem.out.println(a);\n\t\t\n\t\tSystem.out.println(\"Operadores de comparacion\");\n\t\t\n\t\tSystem.out.println(\"== igual a (para objetos equals(), != difente de, < menor que,\"); \n\t\tSystem.out.println(\"<= menor o igual que, >= mayor o igual que, > mayor que.\"); \n\t\tSystem.out.println(\"Todos estos valores devuelven un booleano true o false\");\n\t\t\n\t\tSystem.out.println(\"Ejemplos\");\n\t\t\n\t\tboolean comparacion;\n\t\t\n\t\tSystem.out.println(a + \" | \" + b);\n\t\tcomparacion = a == b;\n\t\tSystem.out.println(a + \" es igual a \" + b + \": \" + comparacion);\n\t\tcomparacion = a != b;\n\t\tSystem.out.println(a + \" no es igual a \" + b + \": \" + comparacion);\n\t\tcomparacion = a < b;\n\t\tSystem.out.println(a + \" es menor que \" + b + \": \" + comparacion);\n\t\tcomparacion = a <= b;\n\t\tSystem.out.println(a + \" es menor o igual que \" + b + \": \" + comparacion);\n\t\tcomparacion = a >= b;\n\t\tSystem.out.println(a + \" es mayor o igual que \" + b + \": \" + comparacion);\n\t\tcomparacion = a > b;\n\t\tSystem.out.println(a + \" es mayor que \" + b + \": \" + comparacion);\n\t\t\n\t\tSystem.out.println(\"Operadores logicos.\");\n\t\t\n\t\tSystem.out.println(\"|| operador OR (devuelve true si una de las variables se cumple)\");\n\t\tSystem.out.println(\"&& operador AND (devuelve true si todas las variables se cumplen)\");\n\t\tSystem.out.println(\"! operador NOT (invierte el valor de la condici├│n, de true a false y viceversa)\");\n\t\t\n\t\tSystem.out.println(\"Ejemplos\");\n\t\t\n\t\tboolean logico= true;\n\t\tcomparacion=false;\n\t\t\n\t\tSystem.out.println(\"Operador OR: \" + comparacion + \" || \" + logico);\n\t\tif (comparacion || logico) {\n\t\t\tSystem.out.println(logico);\n\t\t}else {\n\t\t\tSystem.out.println(comparacion);\n\t\t}\n\t\tSystem.out.println(\"Operador AND: \" + comparacion + \" && \" + logico);\n\t\tif (comparacion && logico) {\n\t\t\tSystem.out.println(logico);\n\t\t}else {\n\t\t\tSystem.out.println(comparacion);\n\t\t}\n\t\tSystem.out.println(\"Operador NOT: !\" + comparacion);\n\t\tif (!comparacion) {\n\t\t\tSystem.out.println(logico);\n\t\t}else {\n\t\t\tSystem.out.println(comparacion);\n\t\t}\n\t\t\n\t\tSystem.out.println(\"Operadores de incremento y decremento.\");\n\t\t\n\t\tSystem.out.println(\"++ Incrementa en uno la variable.\");\n\t\tSystem.out.println(\"-- Incrementa en uno la variable.\");\n\t\t\n\t\tSystem.out.println(\"Ejemplos\");\n\t\t\n\t\ta = 2;\n\t\tSystem.out.println(a);\n\t\tSystem.out.println(\" ++ \" + a);\n\t\ta ++;\n\t\tSystem.out.println(a);\n\t\tSystem.out.println(\" -- \" + a);\n\t\ta --;\n\t\tSystem.out.println(a);\n\t\t\n\t\tSystem.out.println(\"Operadores ternarios\");\n\t\t\n\t\tSystem.out.println(\"Tienen la forma condicion ? valor_si_verdadero : valor_si_falso.\");\n\t\t\n\t\tSystem.out.println(\"Ejemplos\");\n\t\t\n\t\tboolean ternario = false;\n\t\t\n\t\tternario = (comparacion || logico) ? logico : comparacion;\n\t\tSystem.out.println(\"Operador OR en ternario: \" + comparacion + \" || \" + logico + \" ternario = \" + ternario);\n\t\tternario = (comparacion && logico) ? logico : comparacion;\n\t\tSystem.out.println(\"Operador AND en ternario: \" + comparacion + \" && \" + logico + \" ternario = \" + ternario);\n\t\tternario = (!comparacion) ? logico : comparacion;\n\t\tSystem.out.println(\"Operador NOT en ternario: !\" + comparacion + \" ternario = \" + ternario);\n\t\t\n\t\tSystem.out.println(\"Operadores de concatenacion\");\n\t\t\n\t\tSystem.out.println(\"+ Unir diferentes strings a uno solo.\");\n\t\t\n\t\tSystem.out.println(\"Ejemplos\");\n\t\t\n\t\tString texto1 = \"Hola, \";\n\t\tSystem.out.println(texto1);\n\t\tString texto2 = \"Java!\";\n\t\tSystem.out.println(texto2);\n\t\tString textoFinal = texto1 + texto2;\n\t\tSystem.out.println(textoFinal);\n\t\t\n\t\tSystem.out.println(\"Operadores de conversion de tipo\");\n\t\t\n\t\tSystem.out.println(\"Para covertir a numero (int), o tambien Integer.parseInt()\");\n\t\tSystem.out.println(\"Para convertir a texto (String), o tambien String.valueOf()\");\n\t\tSystem.out.println(\"Para convertir a float (float), o tambien Float.parseFloat()\");\n\t\t\n\t\tSystem.out.println(\"Ejemplos\");\n\t\t\n\t\ttexto1 = \"2\";\n\t\tSystem.out.println(\"Dato en texto = \" + texto1);\n\t\ta = Integer.parseInt(texto1);\n\t\tSystem.out.println(\"Dato convertido a entero = \" + a);\n\t\ttexto1 = String.valueOf(a);\n\t\tSystem.out.println(\"Dato convertido a texto = \" + texto1);\n\t\tfloat ft;\n\t\tft = Float.parseFloat(texto1);\n\t\tSystem.out.println(\"Dato convertido a flotante = \" + ft);\n\t\t\n\t\tSystem.out.println(\"Tipo de estucturas.\");\n\t\t\n\t\tSystem.out.println(\"Estructura if\");\n\t\t\n\t\tSystem.out.println(\"Se ejecuta el bolque si se cumple la condicion.\");\n\t\t\n\t\tSystem.out.println(\"Ejemplos\");\n\t\t\n\t\ta = 2;\n\t\tb = 2;\n\t\t\n\t\tSystem.out.println(\"Si \" + a + \" = \" + b);\n\t\tif (a == b) {\n\t\t\tSystem.out.println(\"Se ejecuta el bloque\");\n\t\t}\n\t\t\n\t\tSystem.out.println(\"Estructura if-else\");\n\t\t\n\t\tSystem.out.println(\"Se ejecuta el bloque if si se cumple la condicion, si no se cumple se ejecuta el else.\");\n\t\t\n\t\tSystem.out.println(\"Ejemplos\");\n\t\t\n\t\tSystem.out.println(\"Si \" + a + \" < (menor que) \" + b);\n\t\tif (a < b) {\n\t\t\tSystem.out.println(\"Se ejecuta el bloque if\");\n\t\t}\n\t\telse {\n\t\t\tSystem.out.println(\"Se ejecuta el bloque else\");\n\t\t}\n\t\t\n\t\tSystem.out.println(\"Estructura if else-if else\");\n\t\t\n\t\tSystem.out.println(\"Se ejecuta el bloque if si se cumple la condicion.\");\n\t\tSystem.out.println(\"Si no se cumple se ejecuta la siguiente condicion else if(asi sucesivamente).\");\n\t\tSystem.out.println(\"Si no se cumple niguna condicion se ejecuta el else.\");\n\t\t\n\t\tSystem.out.println(\"Ejemplos\");\n\t\t\n\t\tSystem.out.println(\"if \" + a + \" < (menor que) \" + b + \"\\n\" + \n\t\t\t\t\t\t   \"else if \" + a + \" = (igula a) \" + b);\n\t\tif (a < b) {\n\t\t\tSystem.out.println(\"Se ejecuta el bloque if\");\n\t\t}\n\t\telse if (a == b ) {\n\t\t\tSystem.out.println(\"Se ejecuta el bloque else if\");\n\t\t}\n\t\telse {\n\t\t\tSystem.out.println(\"Se ejecuta el bloque else\");\n\t\t}\n\t\t\n\t\tSystem.out.println(\"Estructura switch\");\n\t\t\n\t\tSystem.out.println(\"Se pasa una variable para luego indicar los casos en los que se ejecutaria.\");\n\t\tSystem.out.println(\"Dentro de cada caso se a├▒ade 'break;'(opcional), para salir del switch despues de ejecutar el bloque de codigo.\");\n\t\tSystem.out.println(\"Tambien se puede a├▒adir 'default:' para ejecutar el codigo si no se cumple ningun case.\");\n\t\t\n\t\tSystem.out.println(\"Ejemplos\");\n\t\t\n\t\ta = 1;\n\t\tb = 2;\n\t\tint c = 3;\n\t\t\n\t\tSystem.out.println(\"Case 1 = \" + a + \",caso 2 = \" + b + \",caso 3 = \" + c + \",si no = \");\n\t\tswitch (a) {\n\t\tcase 1:\n\t\t\tSystem.out.println(\"Se ejecuta el primer caso\");\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tSystem.out.println(\"Se ejecuta el segundo caso\");\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\tSystem.out.println(\"Se ejecuta el tecero caso\");\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tSystem.out.println(\"No se ejecuta ningun caso\");\n\t\t\tbreak;\n\t\t}\n\t\t\n\t\tSystem.out.println(\"Estructura de bucles\");\n\t\t\n\t\tSystem.out.println(\"Bucle for\");\n\t\t\t\t\n\t\tSystem.out.println(\"Se ejecuta un bloque de codigo mientras la condicion sea verdadera.\");\n\t\tSystem.out.println(\"Esto se controla mediante un iterador que se ira modificando por cada ejecucion del bucle.\");\n\t\t\t\t\n\t\tSystem.out.println(\"Ejemplos\");\n\t\t\n\t\tfor (int i = 0; i < c; i++) {\n\t\t\tSystem.out.println(i);\n\t\t}\n\t\t\n\t\tSystem.out.println(\"Bucle while\");\n\t\t\n\t\tSystem.out.println(\"Se ejecuta un bloque de codigo mientras la condicion sea verdadera.\");\n\t\tSystem.out.println(\"El bucle se ejecutara hasta que se modifique la condicion.\");\n\t\t\t\t\n\t\tSystem.out.println(\"Ejemplos\");\n\t\t\n\t\tSystem.out.println(\"Condicion: \" + a + \" distito de \" + c);\n\t\twhile (a != c) {\n\t\t\tSystem.out.println(\"La condicion es verdera\");\n\t\t\ta++;\n\t\t\tSystem.out.println(a);\n\t\t}\n\t\t\n\t\tSystem.out.println(\"Bucle do-while\");\n\t\t\n\t\tSystem.out.println(\"Primero se ejecuta un bloque de codigo, luego se comprueba que la condicion sea verdadera.\");\n\t\tSystem.out.println(\"El bucle se ejecutara hasta que se modifique la condicion.\");\n\t\t\t\t\n\t\tSystem.out.println(\"Ejemplos\");\n\t\t\n\t\ta = 0;\n\t\t\n\t\tdo {\n\t\t\tSystem.out.println(\"Condicion: \" + a + \"distinto \" + c);\n\t\t\tSystem.out.println(\"La condicion es verdera\");\n\t\t\ta++;\n\t\t} while (a != c);\n\t\t\n\t\tSystem.out.println(\"DIFICULTAD EXTRA (opcional):\");\n\t\tSystem.out.println(\"Crea un programa que imprima por consola todos los n├║meros comprendidos\");\n\t\tSystem.out.println(\"entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni m├║ltiplos de 3.\");\n\t\t\n\t\tfor (int i = 10; i <= 55; i++) {\n\t\t\tif( i%2 != 0){\n\t\t\t\t\n\t\t\t}else if ((i == 16) || (i%3 == 0)){\n\t\t\t\t\n\t\t\t}else {\n\t\t\tSystem.out.println(i);\n\t\t\t}\n\t\t}\n\t}\n\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/Rubioj17.java",
    "content": "public class Rubioj17 {\n    public static void main(String[] args) {\n        /*\n         * EJERCICIO:\n         * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n         *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n         *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n         * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n         *   que representen todos los tipos de estructuras de control que existan\n         *   en tu lenguaje:\n         *   Condicionales, iterativas, excepciones...\n         * - Debes hacer print por consola del resultado de todos los ejemplos.\n         *\n         * DIFICULTAD EXTRA (opcional):\n         * Crea un programa que imprima por consola todos los números comprendidos\n         * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n         *\n         * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n         */\n\n        //Operadores Aritméticos\n        System.out.println(\"* * Operadores Aritmeticos * *\");\n        System.out.println(\"Suma: 6+2=\" + (6+2));\n        System.out.println(\"Resta: 6-2=\" + (6-2));\n        System.out.println(\"Multiplicación: 6*2=\" + (6*2));\n        System.out.println(\"Division: 6/2=\" + (6/2));\n        System.out.println(\"Residuo: 6%2=\" + (6%2));\n        System.out.println();\n\n        //Operadores de Comparación\n        System.out.println(\"* * Operadores de Comparación * *\");\n        System.out.println(\"Igual que: 6==2 \" + (6==2));\n        System.out.println(\"Diferente a: 6!=2 \" + (6!=2));\n        System.out.println(\"Mayor que: 6>2 \" + (6>2));\n        System.out.println(\"Menor que: 6<2 \" + (6<2));\n        System.out.println(\"Mayor igual que: 6>=2 \" + (6>=2));\n        System.out.println(\"Menor igual que: 6<=2 \" + (6<=2));\n        System.out.println();\n\n        //Operadores Logicos\n        System.out.println(\"* * Operadores Logicos * *\");\n        System.out.println(\"And &&: 5+5 == 2*5 && 10+5 == 25*5 \" + (5+5 == 2*5 && 10+5 == 25*5));\n        System.out.println(\"Or ||: 5+5 == 2*5 || 10+5 == 25*5 \" + (5+5 == 2*5 || 10+5 == 25*5));\n        System.out.println(\"Not !: 5+5 == 2*5 && 10-5 == 25/5 \" + !(5+5 == 2*5 && 10-5 == 25/5));\n        System.out.println();\n\n        //Operadores de Asignación\n        int a = 10;\n        System.out.println(\"* * Operadorres de Asignación * *\");\n        System.out.println(\"+=: a+=5 \" + (a+=5));\n        System.out.println(\"-=: a-=5 \" + (a-=5));\n        System.out.println(\"*=: a*=5 \" + (a*=5));\n        System.out.println(\"/=: a/=5 \" + (a/=5));\n        System.out.println();\n\n        //Operadores Ternarios\n        System.out.println(\"* * Operadores Ternarios * *\");\n        System.out.println(\"Condición ? true : false ejemplo: 5>2 \" + (5>2 ? \"Mayor\" : \"Menor\"));\n        System.out.println();\n\n        //Estructura de Control\n        System.out.println(\"* * Estructura de Control * *\");\n        //Condicionales\n        System.out.println(\"* * Condicionales * *\");\n        int n1 = 2, n2 = 4;\n        if (n1 > n2) {\n            System.out.println(n1 + \" Es Mayor que \" + n2);\n        }else{\n            System.out.println(n1 + \" No es Mayor que \" + n2);\n        }\n        System.out.println();\n\n        //Iterativas\n        System.out.println(\"* * Iterativas * *\");\n        System.out.println(\"* Usando For *\");\n        for (int i = 1; i <= 10; i++) {\n            System.out.print(i + \",\");\n        }\n        System.out.println(\"\\b\");\n        System.out.println(\"* Usando While *\");\n        int c = 1;\n        while (c<=10) {\n            System.out.print(c + \",\");\n            c++;\n        }\n        System.out.println(\"\\b\");\n        System.out.println();\n\n        //Excepciones\n        System.out.println(\"* * Excepciones * *\");\n        try {\n            System.out.println(\"Dividir 2/0 \" + (2/0));\n        }catch (Exception e) {\n            System.out.println(\"No se puede Dividir por 0 \" + e.getMessage());\n        }finally {\n            System.out.println();\n        }\n\n        //Dificultad Extra\n        System.out.println(\"* * Dificultad Extra * *\");\n        for (int i = 10; i <= 35; i++) {\n            if (i % 2 == 0 && i != 16 && i % 3 != 0) {\n                System.out.print(i + \",\");\n            }\n        }\n        System.out.println(\"\\b\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/Ruthmp.java",
    "content": "//Operadores aritméticos\n        int a = 5;\n        int b = 3;\n        System.out.println(\"OPERADORES LÓGICOS:\");\n        System.out.println(\"Suma: a + b = \" + (a + b));\n        System.out.println(\"Resta: a - b = \" + (a - b));\n        System.out.println(\"Multiplicación: a * b = \" + (a * b));\n        System.out.println(\"División: a / b = \" + (a / b));\n        System.out.println(\"Modulo: a % b = \" + (a % b));\n        System.out.println(\"Incremento: b++ = \" + b++);\n        System.out.println(\"Decremento: a-- = \" + a--);\n\n//Operadores de asignación\n        System.out.println(\"OPERADORES DE ASIGNACIÓN\");\n        int c = 3;\n        c += 3;\n        System.out.println(\"con suma: \" + \" c+=3 \" + c);\n        c -= 2;\n        System.out.println(\"con resta: \" + \" c-=2 \" + c);\n        c *= 2;\n        System.out.println(\"multiplicación: \" + \" c*=2 \" + c);\n        c /= 5;\n        System.out.println(\"división: \" + \" c/=5 \" + c);\n        c %= 2;\n        System.out.println(\"modulo: \" + \" c%=2 \" + c);\n\n//Operadores de comparación\n        System.out.println(\"OPERADORES DE COMPARACIÓN: \");\n        System.out.println(\"Igualdad: a == b\");\n        System.out.println(\"Desigualdad: a!= b\");\n        System.out.println(\"Mayor que : a>b\");\n        System.out.println(\"Menor que : b<a\");\n        System.out.println(\"Mayor o igual: a>=3\");\n        System.out.println(\"Menor o igual: b<= 6\");\n\n//Operadores lógicos\n        System.out.println(\"OPERADORES LÓGICOS:\");\n        System.out.println(\"And = &&\");\n        System.out.println(\"Or = || \");\n        System.out.println(\"Not = !\");\n//Operadores por bits\n\n//CONDICIONALES:\n        System.out.println(\"CONDICIONALES:\");\n        if (c >= b) {\n            System.out.println(\"C es mayor o igual que b\");\n        } else {\n            System.out.println(\"C es menor que b\");\n        }\n//ITERATIVAS:\n        System.out.println(\"ITERATIVAS:\");\n        System.out.println(\"FOR\");\n        for (int i = 0; b <= 7; b++) {\n            System.out.println(\"i\");\n        }\n\n        System.out.println(\"SWITCH\");\n\n        int dia = 2;\n        switch (dia) {\n            case 1:\n                System.out.println(\"Lunes\");\n                break;\n            case 2:\n                System.out.println(\"Martes\");\n                break;\n            case 3:\n                System.out.println(\"Miércoles\");\n                break;\n            case 4:\n                System.out.println(\"Jueves\");\n                break;\n            case 5:\n                System.out.println(\"Viernes\");\n                break;\n            case 6:\n                System.out.println(\"Sábado\");\n                break;\n            case 7:\n                System.out.println(\"Domingo\");\n                break;\n        }\n        System.out.println(\"WHILE\");\n        int f = 0;\n        while (f < 10) {\n            System.out.println(\"El valor es menor de 10\");\n            f++;\n        }\n        System.out.println(\"Do-While\");\n        int num = 0;\n        do {\n            System.out.println(\"El valor es menor de 10\");\n            num++;\n        } while (num < 10);\n        \n        //EXCEPCIONES:\n        System.out.println(\"EXCEPTION\");\n        \n        try {\n            int h = 2/0;\n        }\n        catch (ArithmeticException ex) {\n            System.out.println(\"División por 0\");\n        }\n\n        //El Bucle while, primero comprueba la condición y luego ejecuta la orden. Puede no ejecutarse ninguna vez.\n        //El bucle Do-While primero ejecuta la orden y luego comprueba la condición, por ello siempre se ejecutará, al menos, 1 vez.\n        //------EXTRA-------\n        for (int x = 10; x <= 55; x++) {\n            if ((x%2==0) && !(x==16) && !(x%3 ==0)){\n            System.out.println(x);\n        }\n        }\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/Switchdays.java",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\npublic class Switchdays {\n\n    public static void main(String[] args) {\n\n        // aritmeticos: suma (+), resta (-), multiplicación (*), división (/)\n\n        int number1 = 5;\n        int number2 = 10;\n        int suma = number1 + number2;\n        System.out.println(suma);\n        int resta = number1 - number2;\n        System.out.println(resta);\n        int multiplicacion = number1 * number2;\n        System.out.println(multiplicacion);\n        double division = (double) number1 / number2;\n        System.out.println(division);\n\n        // comparadores: igual (==), mayor (>), menor (<), mayor o igual (>=), menor o igual (<=)\n\n        boolean result1 = number1 == number2;\n        System.out.println(result1);\n        boolean result2 = number1 <= number2;\n        System.out.println(result2);\n        boolean result3 = number1 >= number2;\n        System.out.println(result3);\n        boolean result4 = number1 > number2;\n        System.out.println(result4);\n        boolean result5 = number1 < number2;\n        System.out.println(result5);\n\n        // lógicos: and(&&), or (||), not (!)\n\n        int edad = 14;\n        boolean carnetJoven1 = edad < 25 && edad > 15;\n        System.out.println(carnetJoven1);\n        boolean carnetJoven2 = edad < 25 || edad == 15;\n        System.out.println(carnetJoven2);\n        boolean carnetJoven3 = !carnetJoven2;\n        System.out.println(carnetJoven3);\n\n        // Estructuras de control:\n\n        //if\n        boolean esMayorDeEdad = edad >= 18;\n        boolean esMenorDeEdad = edad < 18;\n        if (esMayorDeEdad) {\n            System.out.println(\"Es mayor de edad\");\n        }\n        if (esMenorDeEdad) {\n            System.out.println(\"Es menor de edad\");\n        }\n\n        //ifElse\n        if (edad >= 18) {\n            System.out.println(\"Es mayor de edad\");\n        } else {\n            System.out.println(\"Es menor de edad\");\n        }\n\n        //ifElseif\n        String dia = \"Sabado\";\n        if (dia.equals(\"Lunes\")) {\n            System.out.println(\"animo con la semana maquina monstruous\");\n        } else if (\"dia\".equals(\"Martes\")) {\n            System.out.println(\"Martes con M de me besas bb\");\n        } else if (\"dia\".equals(\"Miercoles\")) {\n            System.out.println(\"Puto miercoles\");\n        } else if (\"dia\".equals(\"Jueves\")) {\n            System.out.println(\"Venga que ya queda poco\");\n        } else if (\"dia\".equals(\"Viernes\")) {\n            System.out.println(\"Hoy no es jueves mamawevo, HOY ES VIERNESSS!!!!\");\n        }else if (\"dia\".equals(\"Sabado\")) {\n            System.out.println(\"Buen finde\");\n        } else if (\"dia\".equals(\"Domingo\")) {\n            System.out.println(\"Buen finde\");\n        } else {\n            System.out.println(\"El día introducido no es válido\");\n        }\n\n        //switch\n        switch (dia) {\n            case \"Lunes\":\n                System.out.println(\"animo con la semana maquina monstruous\");\n                break;\n            case \"Martes\":\n                System.out.println(\"Martes con M de me besas bb\");\n                break;\n            case \"Miercoles\":\n                System.out.println(\"Puto miercoles\");\n                break;\n            case \"Jueves\":\n                System.out.println(\"Venga que ya queda poco\");\n                break;\n            case \"Viernes\":\n                System.out.println(\"Hoy no es jueves mamawevo, HOY ES VIERNESSS!!!!\");\n                break;\n            case \"Sabado\":\n                System.out.println(\"Buen finde\");\n                break;\n            case \"Domingo\":\n                System.out.println(\"Buen finde\");\n                break;\n            default:\n                System.out.println(\"El día introducido no es válido\");\n        }\n\n        // while\n        int contador = 0;\n        while (contador < 10) {\n            System.out.println(contador);\n            contador++;\n            if (contador == 5) {\n                break;\n            }\n        }\n\n        //doWhile\n        int contador2 = 10;\n        do {\n            System.out.println(contador2);\n            contador2--;\n        } while (contador2 > 10);\n\n        //for\n        for (int i = 0; i < 10; i++) {\n            System.out.println(\"El valor de i es \" + i);\n        }\n\n        //forEach\n        String[] names = {\"Víctor\", \"Natalia\", \"Miliki\"};\n        for (String name : names) {\n            System.out.println(name);\n        }\n\n\n        //Ejercicio opcional: Crea un programa que imprima por consola todos los números comprendidos\n        //entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\n        for (int i = 10; i <=55; i++) {\n\n            if (i != 16 && i % 2 == 0 && i % 3 != 0) {\n                System.out.println(i);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/TofeDev.java",
    "content": "public class TofeDev {\n     public static void main(String[] args) {\n\n        //Asignaciones\n        int a = 20;\n        short b = 10;\n\n    \n        //Operadores Aritméticos\n        int suma = a + b;\n        System.out.println(\"Suma: \" + suma);\n        int resta = a - b;\n        System.out.println(\"Resta: \" + resta);\n        int multiplicacion = a * b;\n        System.out.println(\"Multiplicación: \" + multiplicacion);\n        int division = a / b;\n        System.out.println(\"División: \" + division);\n        int resto = a % b ;\n        System.out.println(\"Resto: \" + resto);\n\n    \n        //Asignación compuesta\n        suma += a;\n        System.out.println(\"a + a = \" + suma);\n        resta -= a;\n        System.out.println(\"a - a = \" + resta);\n        multiplicacion *= a;\n        System.out.println(\"a * a = \" + multiplicacion);\n        division /= a;\n        System.out.println(\"a / a = \" + division);\n        resto %= a;\n        System.out.println(\"a % a = \" + resto);\n\n    \n        // Operadores lógicos\n        boolean and = (a < b) && (b == 0);\n        System.out.println(\"¿Es a menor que b, Y b igual a 0?: \" + and);\n        boolean or = (a > b) || (b == 0);\n        System.out.println(\"¿Es a mayor que b, O b igual a 0?: \" + or);\n        boolean not = !(a < b);\n        System.out.println(\"Negación a menor que b: \" + not);\n\n    \n        // Operadores de comparación\n        boolean igual = (a == b);\n        System.out.println(\"Es igual: \" + igual);\n        boolean distinto = (a != b);\n        System.out.println(\"Es distinto: \" + distinto);\n        boolean mayor = (a > b);\n        System.out.println(\"Es mayor: \" + mayor);\n        boolean mayorIgual = (a >= b);\n        System.out.println(\"Es mayor o igual: \" + mayorIgual);\n        boolean menor = (a < b);\n        System.out.println(\"Es menor: \" + menor);\n        boolean menorIgual = (a <= b);\n        System.out.println(\"Es menor o igual: \" + menorIgual);\n\n\n        //Operadores de bits\n        int aBit = 01001;\n        int bBit = 00111;\n        System.out.println(\"a como bits: \" + aBit + \" y b como bits: \" + bBit);\n        int desplazamientoIzq = a << 2;\n        System.out.println(\"Desplazar a la izquierda: \" + desplazamientoIzq);\n        int desplazamientoDer = a >> 2;\n        System.out.println(\"Desplazar a la derecha: \" + desplazamientoDer);\n        int andBit = a & b;\n        System.out.println(\"AND en bits: \" + andBit);\n        int orBit = a | b;\n        System.out.println(\"OR en bits: \" + orBit);\n\n\n        //Estructuras condicionales\n        int c = 150;\n        int d = 52;\n        int f = 7;\n        \n        \n        if (c < 200) {\n            System.out.println(\"c es menor que 200\");\n        }\n        \n          \n        if (d < 10) {\n            System.out.println(\"d es menor que 10\");\n        } else {\n            System.out.println(\"d es mayor que 10\");\n        }\n        \n          \n        if (f > 8 && f < 15) {\n            System.out.println(\"f es mayor que 8 y menor que 15\");\n        } else if (f < 5) {\n            System.out.println(\"f es menor que 5\");\n        } else {\n            System.out.println(\"f está fuera de nuestro rango\");\n        }\n          \n        \n        switch (f) {\n        case 2:\n            System.out.println(\"f es 2\");\n            break;\n        \n        case 5:\n            System.out.println(\"f es 5\");\n            break;\n        \n        case 7:\n            System.out.println(\"f es 7\");\n            break;\n        \n        case 10:\n            System.out.println(\"f es 10\");\n            break;\n        }\n        \n        // Estructuras iterativas\n        int g = 250;\n        for (int i = 1; i <= 5; i++) {\n            g+=2;\n            System.out.println(g);\n        }\n        \n          \n        while (g < 300) {\n            g+=5;\n            System.out.println(g);\n        }\n        \n          \n        do {\n            g+=10;\n            System.out.println(g);\n        } while (g < 350);\n        \n          \n        //Estructuras excepcionales\n        try {\n            int[] numeros = {1, 2, 3};\n            System.out.println(numeros[10]);\n        } catch (Exception e) {\n            System.out.println(\"Error\");\n        } finally {\n            System.out.println(\"Sistema finalizado\");\n        }\n        \n        \n         /*\n          * DIFICULTAD EXTRA (opcional):\n          * Crea un programa que imprima por consola todos los números comprendidos\n          * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n          */\n\n    \n        for (int h = 10; h <= 50; h++) {\n            if (h != 16 && h % 3 != 0 && h % 2 == 0) {\n                System.out.println(h);\n            }\n        }\n        \n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/Verschlingendenacht.java",
    "content": "import java.util.Scanner;\n\npublic class Verschlingendenacht {\n\n    public static void main(String[] args){\n        Operadores();\n        Estructuras();\n        Extra();\n    }\n\n    static void Operadores(){\n        //REQUISITO 1: OPERADORES EN JAVA\n\n        int x = 2;\n        int y = 3;\n\n        //OPERADORES ARITMETICOS\n        System.out.println(x + y); //Suma\n        System.out.println(x - y); //Resta\n        System.out.println(x * y); //Multiplicacion\n        System.out.println(x / y); //Division\n        System.out.println(x % y); //Modulo\n\n        //EXTRA\n        System.out.println(\"hola\" + \"mundo!\"); //Concatenacion\n\n        //OPERADORES UNARIOS\n        System.out.println(-x); //Conversion negativa\n        System.out.println(+x); //Conversion positiva\n        System.out.println(x++); //Post-incremento\n        System.out.println(++x); //Pre-incremento\n\n        System.out.println(x--); //Post-decremento\n        System.out.println(--x); //Pre-decremento\n\n        System.out.println(!true); //Negacion o Inversion de booleano\n\n        //OPERADORES DE ASIGNACION\n        int z = 4;\n        System.out.println(\"En Java, usamos el operador \\\"=\\\" para asignar un valor a una variable\");\n\n        z += 2;\n        System.out.println(z);\n\n        z -= 2;\n        System.out.println(z);\n\n        z *= 2;\n        System.out.println(z);\n\n        z /= 2;\n        System.out.println(z);\n\n        z %= 2;\n        System.out.println(z);\n\n        //OPERADORES RELACIONALES\n        int a = 1;\n        int b = 2;\n\n        System.out.println(a == b); //Igualdad\n        System.out.println(a != b); //Diferencia\n        System.out.println(a < b); //Menor que\n        System.out.println(a > b); //Mayor que\n        System.out.println(a <= 1); //Menor o igual que\n        System.out.println(b >= 2); //Mayor o igual que\n\n        //OPERADORES LOGICOS\n        System.out.println(a == 1 && b == 2); //Y (and)\n        System.out.println(a != 1 || b == 2); //O (or)\n\n        //OPERADOR TERNARIO\n        System.out.println(a == 1 ? a : 0);\n\n        //OPERADORES BITWISE\n        int c = 3;\n        int d = 4;\n        int f = -9;\n\n        System.out.println(c & d); //(AND) Retorna 1 cuando ambos bits son 1\n        System.out.println(c | d); //(OR) Retorna 1 si uno de ambos bits es 1\n        System.out.println(c ^ d); //(XOR) Retorna 1 si ambos bits son diferentes del otro\n        System.out.println(~d); //(Complemento Bitwise) Invierte los bits del valor\n\n        //OPERADORES DE DESPLAZAMIENTO\n        System.out.println(c >> 3); //(Desplazamiento de bits hacia la izquierda) multiplica el derecho por 2 elevado al izquierdo\n        System.out.println(d << 4); //(Desplazamiento de bits hacia la derecha respetando su signo) bit signo\n        System.out.println(f >>> 2); //(Desplazamiento de bits hacia la derecha ignorando su signo) rellena con 0s\n\n    }\n\n    static void Estructuras(){\n        //REQUISITO 2: ESTRUCTURAS DE CONTROL EN JAVA\n\n        //Estructuras Condicionales\n            Scanner scanner = new Scanner(System.in);\n            System.out.println(\"Ingresa una edad\");\n            int edad = scanner.nextInt();\n\n            //if\n                if(edad > 17){\n                    System.out.println(\"Esta persona es adulta!\");\n                }\n\n            //if-else\n                if(edad > 17){\n                    System.out.println(\"Esta persona es adulta!\");\n                }else{\n                    System.out.println(\"Esta persona es menor de edad!\");\n                }\n\n            //if-else-if\n                if(edad > 17) {\n                    System.out.println(\"Esta persona es adulta!\");\n                }else if(edad > 11){\n                    System.out.println(\"Esta persona es adolescente!\");\n                }else{\n                    System.out.println(\"Esta persona es un niño!\");\n                }\n\n            //switch case\n            System.out.println(\"Ingresa un dia del 1 al 7\");\n            int dia = scanner.nextInt();\n                switch(dia){\n                    case 1:\n                        System.out.println(\"Lunes\");\n                        break;\n                    case 2:\n                        System.out.println(\"Martes\");\n                        break;\n                    case 3:\n                        System.out.println(\"Miercoles\");\n                        break;\n                    case 4:\n                        System.out.println(\"Jueves\");\n                        break;\n                    case 5:\n                        System.out.println(\"Viernes\");\n                        break;\n                    case 6:\n                        System.out.println(\"Sabado\");\n                        break;\n                    case 7:\n                        System.out.println(\"Domingo\");\n                        break;\n                    default:\n                        System.out.println(\"Dia no valido.\");\n                }\n\n        //Estructuras Iterativas\n            //for\n            int[] numeros = {1,2,3,5,7,11,13};\n                for(int i = 0; i < numeros.length; i++){\n                    System.out.println(numeros[i]);\n                }\n\n            //for-each\n            String[] frutas = {\"Banano\", \"Piña\", \"Pera\", \"Sandia\", \"Manzana\"};\n                for(String fruta : frutas){\n                    System.out.println(fruta);\n                }\n\n            //while\n            System.out.println(\"En un bucle While, la cantidad de iteraciones es determinada en la ejecucion\");\n            int iteraciones = scanner.nextInt();\n            int iterador = 1;\n                while(iterador <= iteraciones){\n                    System.out.println(iterador);\n                    iterador++;\n                }\n\n            //do-while\n            int opcion = 0;\n                do{\n                    System.out.println(\"Bienvenido al menu de inicio\");\n                    System.out.println(\"1- Imprmimir \\\"Hola Mundo\\\"\");\n                    System.out.println(\"2- Mostrar la suma de 2+1\");\n                    System.out.println(\"3- Cerrar menu\");\n\n                    opcion = scanner.nextInt();\n\n                    switch(opcion){\n                        case 1:\n                            System.out.println(\"Hola Mundo!\");\n                            break;\n                        case 2:\n                            System.out.println(2+1);\n                            break;\n                    }\n                }while(opcion != 3);\n\n        //Estructuras de Salto\n            //break\n            //La sentencia break permite romper el hilo activo, podemos implementarlo tanto en bucles como en estructuras tipo switch\n            for(int i = 0; i <= 10; i++){\n                if(i==9){\n                    break;\n                }\n                System.out.println(i);\n            }\n\n            //continue\n            //La sentencia continue permite saltarse el hilo activo de un bucle\n            for(int i = 0; i < 20; i++){\n                if(i % 2 == 0){\n                    continue;\n                }\n                System.out.println(i);\n            }\n\n        //Estructuras de Excepciones\n            //Try-Catch\n            int resultado = 0;\n            try{\n                System.out.println(\"Vamos a sumar, ingresa el primer operando\");\n                int x = scanner.nextInt();\n\n                System.out.println(\"Ingresa el segundo operando\");\n                int y = scanner.nextInt();\n\n                resultado = x + y;\n\n            } catch (Exception e){\n                System.out.println(\"Ingresaste un numero invalido:\");\n                System.out.println(e);\n            } finally {\n                if(resultado != 0){\n                    System.out.println(\"Resultado: \" + resultado);\n                }\n        }\n    }\n\n    static void Extra(){\n        /*\n            DIFICULTAD EXTRA (opcional):\n            Crea un programa que imprima por consola todos los números comprendidos\n            entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n        */\n\n        for(int i = 10; i <= 55; i++){\n            if( (i % 2 == 0) && (i != 16) && (i % 3 != 0) ){\n                System.out.println(i);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/VictorPolo28.java",
    "content": "import java.util.Scanner;\n\npublic class VictorPolo28 {\n    public static void main(String[] args) {\n\n        //operadores arimeticos\n\n        int numberA = 10;\n        int numberB = 55;\n        int suma = numberA + numberB;\n        int resta = numberA -numberB ;\n        int multiplicacion = numberA * numberB;\n        int divisio = numberA /numberB;\n        int sobrante = numberA % numberB ;\n\n        //operadores  de asignación \n        numberA = 15;\n        numberB += 25;\n        numberA -= 10;\n        numberB *= 25;\n        numberA /= 2 ;\n        numberB %= 5;\n\n        //oepradores de Incremento  y  Decremento\n        numberA ++;\n        numberB --;\n\n        //operadores Realcionles  o de  Comparacion \n          boolean  igualdad = (numberA == numberB );\n          boolean   desigualdad = (numberB != numberA);\n          boolean   mayorQue = (numberA > numberB); \n          boolean   menorQue = (numberA < numberB);\n          boolean   mayorIgualQue = (numberA >= numberB);\n          boolean   menorIgualQue = (numberB <= numberA);\n\n\n        //operadores logicos\n\n        boolean a =true ;\n        boolean b = false;\n        boolean resultado = a && b ;\n        boolean resultado2 = a || b ;\n        boolean resultado3 = a != true  ;\n\n       \n\n    //operadores  Bit a  Bit \n    int c = 5;\n    int d = 85;\n    int prueba = c & d;\n    int prueba2 = c | d;\n    int prueba3 = d  ^ c;\n    int prueba4 = ~c;\n    int prueba5 = d << 2;\n    int prueba6 = c>> 2 ;\n    int prueba7 = d >>> 2;\n    \n\n     //operador terniario\n     if (numberA < numberB) {\n        System.out.println( numberA + \"es menor  que  \" + numberB);\n    } else {\n        System.out.println( numberA + \"es mayor que  \" + numberB );\n    }\n\n    //Ejemplos de  los tipos de estructuras  de   control\n\n    //Estructuras de Control de Selección (Condicionales)\n\n    int ageM = 28  ;\n    int ageF = 31 ;\n\n    if (ageF > ageM ){\n        System.out.println(\"La diferencia de edad es: \" + (ageF -ageM)  + \" años\");\n    }\n\n    String  pokemon =\"fuego\";\n    String pokemon2 = \"planta\";\n    String  pokemon3  = \"agua\" ;\n    \n\n    if (pokemon == \"fuego\") {\n        System.out.println(\"Yo soy de agua   y mela pelas \");\n    } else {\n        System.out.println(\"Ya  valiste verga perro...!\");\n    }\n    \n    \n\n    if (pokemon == pokemon2){\n        System.out.println(\"Quemado perro\");\n    } else if (pokemon != pokemon2) {\n        System.out.println(\"F perdiste perro... \");\n    }  else {\n        System.out.println(\"Aqui que paso?\");\n    }\n\n    Scanner menu = new Scanner (System.in);\n\n    System.out.println(\"/n elija su opcion\");\n    System.out.println(\"1. pokemon de planta\");\n    System.out.println(\"2.pokemon de fuego\");\n    System.out.println(\"3 pokemon de agua\");\n    int opcion = menu.nextInt();\n    menu.nextLine();\n    \n\n    switch (opcion) {\n        case 1: \n        System.out.println(\"Soy  fugo  ya valiste\");\n            \n            break;\n        case 2: \n        System.out.println(\"Soy agua  ya valiste\");\n            \n            break;\n        case 3: \n        System.out.println( \"Soy planta   ya valiste\");\n            \n            break;\n    \n        default:\n        System.out.println(\"Elieje  algo valido  pendejo\");\n            break;\n    }\n\n\n        // Estructuras de Control de Iteración (Bucles)\n\n    for (int i= 0;  i < 1000; i++){\n        System.out.println( \"ahora  tu cantidad de sorinsas es:  \" +  +i );\n    }\n\n    int smile = 0;\n\n    while (smile < 10) {\n       System.out.println( \"Aun debese  sonreir  mas: \" + smile + \" Sonrisas no es  suficiente\");\n       smile++;\n        \n    }\n\n    do {\n        System.out.println( \"Aun debese  sonreir  mas: \" + smile + \" Sonrisas no es  suficiente\");\n        smile++; \n    }while (smile < 10) ;\n\n\n    // Estructuras de Control de Salto\n\n    for (int i = 0; i < 101; i++){\n        if ( i == 16) {\n            break;\n            \n        }\n        System.out.println(i);\n    }\n\nfor (int i = 0; i < 101; i++){\n        if ( i == 16 || i == 40) {\n            continue;\n            \n        }\n        System.out.println(i);\n    }\n\n for (int i = 0; i <= 55; i ++){\n    if (i == 16 || i%3 == 0){\n        continue;\n    }\n    System.out.println(i);\n }\n\n}\n\n\n\n\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/VolumiDev.java",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\nimport java.io.*;\npublic class VolumiDev {\n\n\tpublic static void extra() {\n\t\tSystem.out.println();\n\t\tSystem.out.println(\"A continuacion mostramos el programa extra, que nos muestra los numeros pares, distintos de 16 y que no sean multiplos de 3\");\n\t\tSystem.out.println();\n\t\tfor(int i=10; i<=55; i++) {\n\t\t\tif(i%2==0 && i!=16) {\n\t\t\t\tif(i%3!=0) {\n\t\t\t\tSystem.out.print(i+\"\\t\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t\n\tpublic static void main(String[] args) {\n\t\t// TODO Auto-generated method stub\n\t\tint a=48;\n\t\tint b=26;\n\t\tString cad1=\"cho\";\n\t\tString cad2=\"co\";\n\t\tString cad3=\"la\";\n\t\tString cad4=\"te\";\n\t\tint c, d;\n\t\tboolean andlog;\n\t\tboolean orlog;\n\t\tboolean notlog;\n\t\tboolean bitand;\n\t\tboolean bitor;\n\t\tboolean bitxor;\n\t\tboolean bitnot;\n\t\t\n\t\t//operadores de asignacion\n\t\tc=8;\n\t\td=8;\n\t\t\n\t\t//operadores aritméticos\n\t\tSystem.out.println(a+b);\t//suma \n\t\tSystem.out.println(cad1+cad2+cad3+cad4);\t//concatenación de cadenas\n\t\tSystem.out.println(a-b);\t//resta\n\t\tSystem.out.println(a*b);\t//multiplicación\n\t\tSystem.out.println(a/b);\t//división\n\t\tSystem.out.println(a%b);\t//resto de la división\n\t\t\n\t\t//operadores aritmeticos incrementales\n\t\tSystem.out.println(\"Primero 'a' vale \"+a+\" despues de incremetarlo en 1 vale \"+a++);\t//incrementador\n\t\tSystem.out.println(\"Primero 'b' vale \"+b+\" despues de decrementarlo en 1 vale \"+b--);\t//decrementador\n\t\t\n\t\t//operadores aritmeticos combinados aritmeticos y asignacion\n\t\tSystem.out.println(\"El resultado de a=a+b es: \"+(a+=b));\t//suma combinada -> a=a+b\n\t\tSystem.out.println(\"El resultado de a=a-b es: \"+(a-=b));\t//resta combinada -> a=a-b\n\t\tSystem.out.println(\"El resultado de a=a*b es: \"+(a*=b));\t//multiplicacion combianda -> a=a*b\n\t\tSystem.out.println(\"El resultado de a=a/b es: \"+(a/=b));\t//multiplicacion combinada -> a=a/b\n\t\tSystem.out.println(\"El resultado de a=a%b es: \"+(a%=b));\t//restos de division combianda -> a=a%b;\n\t\t\n\t\t//operadores de comparacion\n\t\tSystem.out.println(\"Igualdad, c es igual a d: \"+(c==d));\t//igualdad\n\t\tSystem.out.println(\"Distinto, a es destinto de b: \"+(a!=b));\t//distinto\n\t\tSystem.out.println(\"Mayor que, a es mayor que b: \"+(a>b));\t//mayor que\n\t\tSystem.out.println(\"Menor que, b es menor que a: \"+(b<a));\t//menor que \n\t\tSystem.out.println(\"Mayor o igual, a es meyor o igual que c: \"+(a>=c));\t//mayor o igual\n\t\tSystem.out.println(\"Menor o igual, c es menor o igual que d: \"+(c<=d));\t//menor o igual\n\t\t\n\t\t//operadores logicos\n\t\tandlog=(c==8 && d==8);\t//operador and\n\t\tSystem.out.println(\"Operador logico AND \"+andlog);\t\n\t\torlog=(c==0 || d==11);\t//operador or\n\t\tSystem.out.println(\"Operador logico OR \"+orlog);\n\t\tnotlog=!(andlog);\t//operador not\n\t\tSystem.out.println(\"Lo contrario al operador logico AND \"+notlog);\n\t\t\n\t\t//operadores ternarios\n\t\tSystem.out.println((a>b)?\"'a' es mayor que 'b'\":\"'b' es mayor que 'a'\");\n\t\t\n\t\t//operadores de bits para operaciones a nivel de bit en numeros enteros\n\t\t\n\t\t//desplazamientos\n\t\tSystem.out.println(\"Desplaza los bits de 45 a la izquierda 2 posiciones para combertirlo en: \"+(a<<2));\t//desplazamiento a la izq\n\t\t\n\t\tSystem.out.println(\"Desplaza los bits de 45 a la izquierda 2 posiciones para combertirlo en: \"+(a>>2)); //desplazamiento a la der\n\t\t\n\t\t\t//logicos\n\t\tbitand=(c==8 & d==8);\n\t\tSystem.out.println(\"Operador logico a nivel de bit AND \"+bitand);\n\t\tbitor=(c==8 | a==8);\n\t\tSystem.out.println(\"Operador logico a nivel de bit OR \"+bitor);\n\t\t\n\t\t//operadores de conversion\n\t\tSystem.out.println(\"El numero a es un entero \"+a+\" y lo casteamos a real \"+(double)a);\n\t\t\n\t\textra();\n\t}\n\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/Worlion.java",
    "content": "import java.util.logging.ConsoleHandler;\nimport java.util.logging.LogRecord;\nimport java.util.logging.Logger;\nimport java.util.logging.SimpleFormatter;\n\npublic class Worlion {\n\n    private static Logger log = Logger.getLogger(Worlion.class.getName());\n    \n    static {\n        log.setUseParentHandlers(false);\n        ConsoleHandler consoleHandler = new ConsoleHandler();\n        consoleHandler.setFormatter(new SimpleFormatter() {\n            @Override\n            public String format(LogRecord record) {\n                return record.getMessage() + \"\\n\";\n            }\n        });\n        log.addHandler(consoleHandler);\n    }\n    \n    public static void main(String[] args) {\n        \n        log.info(\" \\nTipos de operadores en JAVA:\\n\");\n        arithmetics();\n        logicals();\n        comparision();\n        assignment();\n        identity();\n        bitwise();\n\n        log.info(\" \\nEstructuaras de control en JAVA:\\n\");\n        conditionals();\n        loops();\n        exceptions();\n\n        log.info(\" \\n ---- 🌩 DIFICULTAD EXTRA 🌩 ----\\n\");\n        extra();\n    }\n\n    // Tipos de operadores:\n\n    public static void arithmetics() {\n\n        log.info(\" - Operadores aritméticos:\");\n    \n        // addition (+)\n        log.info(\"\\tsuma: 2+2=\"+ (2+2));\n\n        // Subtraction (-)\n        log.info(\"\\tresta: 5-2=\"+ (5-2));\n\n        // Multiplication (*)\n        log.info(\"\\tproducto (*): 3x2=\"+ (3*2));\n\n        // Division (/)\n        log.info(\"\\tdivision (/): 25/5=\"+ (25/5));\n\n        // Modulus (%)\n        log.info(\"\\tmódulo (%): 12%5=\"+ (12%5));\n\n        // Increment (++)\n        int n = 5;\n        log.info(\"\\tincremento (++): \"+ (n++) + \"++ = \"+n);\n\n        // Decrement (--)\n        log.info(\"\\tdecremento (--): \"+ (n--) + \"++ = \"+n);\n\n    }\n\n    public static void logicals() {\n\n        log.info(\"\\n - Operadores lógicos:\");\n    \n        // AND (&&)\n        log.info(\"\\tAnd: Verdadero Y Verdadero=\" + (true && true));\n        log.info(\"\\tAnd: Verdadero Y Falso=\" + (true && false));\n            \n        // OR (||)\n        log.info(\"\\tOr: Falso O Verdadero=\" + (false || true));\n        log.info(\"\\tOr: Falso O Falso=\" + (false || false));\n            \n        // NOT (!)\n        log.info(\"\\tNot: No(Verdadero)=\" + (!true));\n        log.info(\"\\tNot: No(Falso)=\" + (!false));\n\n        // XOR (^)\n        log.info(\"\\tXOR: Verdadero XOR Verdadero=\" + (true ^ true));\n        log.info(\"\\tXOR: Verdadero XOR Falso=\" + (true ^ false));\n    }\n\n    public static void comparision(){\n        log.info(\"\\n - Operadores comparacióin:\");\n\n        // Equal (==)\n        log.info(\"\\tIgual: 5==5=\" + (5==5));\n\n        // Not equal (!=)   \n        log.info(\"\\tNo igual: 5!=5=\" + (5!=5));\n\n        // Greater than (>)\n        log.info(\"\\tMayor que: 5>3=\" + (5>3));\n\n        // Less than (<)\n        log.info(\"\\tMenor que: 5<3=\" + (5<3));\n\n        // Greater than or equal to (>=)\n        log.info(\"\\tMayor o igual que: 5>=5=\" + (5>=5));\n\n        // Less than or equal to (<=)\n        log.info(\"\\tMenor o igual que: 5<=5=\" + (5<=5));\n\n        // instanceof\n        Object obj = new String(\"Hello\");\n        log.info(\"\\tInstancia de: obj instanceof String = \" + (obj instanceof String));\n    }\n\n    public static void assignment(){\n        log.info(\"\\n - Operadores asisgnación:\");\n\n        int n = 10;\n        \n        // Igualdad\n        log.info(\"\\tIgualdad: n=10=\"+n);\n        \n        // Suma y asignación\n        log.info(\"\\tSuma y asignación: n+=5 -> \"+ (n+=5));\n        \n        // Resta y asignación\n        log.info(\"\\tResta y asignación: n-=5 -> \"+ (n-=5));\n        \n        // Multiplicación y asignación\n        log.info(\"\\tMultiplicación y asignación: n*=5 -> \"+ (n*=5));\n        \n        // División y asignación\n        log.info(\"\\tDivisión y asignación: n/=5 -> \"+ (n/=5));\n        \n        // Modulo y asignación\n        log.info(\"\\tModulo y asignación: n%=5 -> \"+ (n%=5));\n    }\n\n    public static void identity(){\n        log.info(\"\\n - Operadores identidad:\");\n\n        int n = 10;\n        int m = 10;\n        \n        // Igualdad\n        log.info(\"\\tIgualdad: n==m -> \"+ (n==m));\n\n        // Diferente\n        log.info(\"\\tDiferente de: n!=m -> \"+ (n!=m));\n    }\n\n    public static void bitwise(){\n        log.info(\"\\n - Operadores de bit:\");\n\n        int n = 10;\n        int m = 5;\n        String nBinary = Integer.toBinaryString(n);\n        String mBinary = Integer.toBinaryString(m);\n        log.info(\"\\t -> n = \"+n +\"(\"+ nBinary+\")\");\n        log.info(\"\\t -> m = \"+m +\"(\"+ mBinary+\")\");\n\n\n        // AND bit\n        log.info(\"\\tAND bit: n(\"+nBinary+\") & m(\"+mBinary+\") -> \"+ (n&m) +\"(\" +Integer.toBinaryString(n&m)+\")\");\n\n        // OR bit\n        log.info(\"\\tOR bit: n(\"+nBinary+\")|m(\"+mBinary+\") -> \"+ (n|m) +\"(\" +Integer.toBinaryString(n|m)+\")\");\n\n        // XOR bit\n        log.info(\"\\tXOR bit: n(\"+nBinary+\")^m(\"+mBinary+\") -> \"+ (n^m) +\"(\" +Integer.toBinaryString(n^m)+\")\");\n\n        // NOT bit\n        log.info(\"\\tNOT bit: ~n(\"+nBinary+\") -> \"+ (~n) +\"(\" +Integer.toBinaryString(~n)+\")\");\n\n        // desplazamiento a la izquierda\n        log.info(\"\\tDesplazamiento a la izquierda: n(\"+nBinary+\")<<2 -> \"+ (n<<2) +\"(\" +Integer.toBinaryString(n<<2)+\")\");\n\n        // desplazamiento a la derecha\n        log.info(\"\\tDesplazamiento a la derecha: n(\"+nBinary+\")>>2 -> \"+ (n>>2) +\"(\" +Integer.toBinaryString(n>>2)+\")\");\n    }\n\n    // Estructuras de control:\n    public static void conditionals(){\n        \n        // if - else if - else\n        int n = 10;\n        if (n > 5) {\n            log.info(\"El número es mayor que 5\");\n        } \n        else if(n < 5) {\n            log.info(\"El número es menor que 5\");\n        }\n        else {\n            log.info(\"El número es igual a 5\");\n        }\n\n        int dia = 3;\n        String diaString = null;\n        switch (dia) {\n            case 1: \n                diaString = \"Lunes\"; \n                break;\n            case 2: \n                diaString = \"Martes\"; \n                break;\n            case 3: \n                diaString = \"Miércoles\"; \n                break;\n            case 4: \n                diaString = \"Jueves\"; \n                break;\n            case 5: \n                diaString = \"Viernes\"; \n                break;\n            case 6: \n                diaString = \"Sábado\"; \n                break;\n            case 7: \n                diaString = \"Domingo\"; \n                break;\n            \n            default: log.info(\"Día no válido\"); break;\n        }\n        if(diaString!=null) {\n            log.info(\"El día '\"+ dia+\"' de la semana es: \" + diaString);\n        }\n    }\n\n    public static void loops(){\n    \n        // for\n        log.info(\" - Iterando con el for:\");\n        for (int i = 0; i < 5; i++) {\n            log.info(\"\\t -Iteración: \"+i);\n        }\n\n        // while\n        log.info(\" - Iterando con el while:\");\n        int i = 0;\n        while (i < 5) {\n            log.info(\"\\t -Iteración: \"+i);\n            i++;\n        }\n\n        // do-while\n        log.info(\" - Iterando con el do-while:\");\n        i = 0;\n        do {\n            log.info(\"\\t -Iteración: \"+i);\n            i++;\n        } while (i < 5);\n    }\n    \n    public static void exceptions(){\n        try {\n            int n = 5/0;\n        } catch (ArithmeticException e) {\n            log.info(\"Error: \"+e.getMessage());\n        } finally {\n            log.info(\"Finalizando el programa\");\n        }\n    }\n\n/* \n *DIFICULTAD EXTRA (opcional):\n */\n\n    private static void extra() {\n        for( int i = 10; i <= 55; i+=2) {\n            if(i != 16 || i % 3 != 0) {\n                System.out.println(i);\n            }\n        }\n    \n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/Zugarramurdi.java",
    "content": "/**\n * Clase Zugarramurdi donde se implementara la solucion al ejercicio #01 - OPERADORES Y ESTRUCTURAS DE CONTROL\n * @author Zugarramurdi\n * @version 1.0\n * @date 05/04/2025\n */\n\npublic class Zugarramurdi {\n    public static void main(String[] args) {\n\n        // Definicion de variables\n        int num1 = 10;\n        int num2 = 2;\n        int num3 = 45;\n        int num4 = 5;\n\n        // Operaciones aritmeticas asignadas a variables\n        System.out.println(\"\\nOperaciones Aritmeticas:\\n\");\n        int suma = num1 + num2;\n        int resta = num1 - num3;\n        int multiplicacion = num1 * num2;\n        double division = num3 / num2;\n        double modulo = num3 % num2;\n        System.out.println(\"Suma: \" + num1 + \" + \" + num2 + \" = \" + suma);\n        System.out.println(\"Resta: \" + num1 + \" - \" + num3 + \" = \" + resta);\n        System.out.println(\"Multiplicacion: \" + num1 + \" * \" + num2 + \" = \" + multiplicacion);\n        System.out.println(\"Division: \" + num3 + \" / \" + num2 + \" = \" + division);\n        System.out.println(\"Modulo: \" + num3 + \" % \" + num2 + \" = \" + modulo);\n\n        // Operaciones de incremento y decremento asignadas a variables\n        System.out.println(\"\\nOperaciones de Incremento y Decremento: \\n\");\n        int incremento = ++num1;\n        int decremento = --num2;\n        --num1; // Devuelvo el valor original de num1\n        ++num2; // Devuelvo el valor original de num2\n        System.out.println(\"Incremento: 10\" + \" ++ = \" + incremento);\n        System.out.println(\"Decremento: 2\" + \" -- = \" + decremento);\n\n        // Operaciones de comparacion asignadas a variables\n        System.out.println(\"\\nOperaciones de Comparacion:\\n\");\n        boolean mayorQue = num1 > num2;\n        boolean menorQue = num2 < num1;\n        boolean igualQue = num1 == num2;\n        boolean diferenteDe = num1 != num2;\n        System.out.println(num1+ \" es mayor que \" + num2 + \"? \" + mayorQue);\n        System.out.println(num2 + \" es menor que \" + num1 + \"? \" + menorQue);\n        System.out.println(num1 + \" es igual que \" + num2 + \"? \" + igualQue);\n        System.out.println(num1 + \" es diferente de \" + num2 + \"? \" + diferenteDe);\n\n        // Operadores logicos asignados a variables\n        System.out.println(\"\\nOperadores Logicos:\\n\");\n        boolean and = (num1 > num2) && (num1 < num3);\n        boolean or = (num1 > num2) || (num1 < num3);\n        boolean not = (num1 != num2);\n        System.out.println(\"AND: \" + num1 + \" > \" + num2 + \" AND \" + num1 + \" < \" + num3 + \" = \" + and);\n        System.out.println(\"OR: \" + num1 + \" > \" + num2 + \" OR \" + num1 + \" < \" + num3 + \" = \" + or);\n        System.out.println(\"NOT: \" + num1 + \" IS NOT \" + num2 + \" = \" + not);\n\n        // Operadores de asignacion\n        System.out.println(\"\\nOperadores de Asignacion:\\n\");\n        System.out.println(\"Asignacion: \" + num4 + \"+=5 = \" + (num4 += 5));\n        num4-=5; // Devuelvo el valor original de num4\n        System.out.println(\"Asignacion: \" + num4 + \"-=3 = \" + (num4 -= 3));\n        num4+=3; // Devuelvo el valor original de num4\n        System.out.println(\"Asignacion: \" + num4 + \"*=2 = \" + (num4 *= 2));\n        num4/=2; // Devuelvo el valor original de num4\n        System.out.println(\"Asignacion: \" + num4 + \"/=2 = \" + (num4 /= 2));\n        num4*=2; // Devuelvo el valor original de num4\n        System.out.println(\"Asignacion: \" + num4 + \"%=2 = \" + (num4 %= 2));\n        num4+=5; // Devuelvo el valor original de num4\n\n        // Operadores ternarios\n        System.out.println(\"\\nOperadores Ternarios:\\n\");\n        //Sintaxis - (condicion) ? valorSiVerdadero : valorSiFalso;\n        String resultado = (num1 > num2) ? \"num1 es mayor que num2\" : \"num2 es mayor que num1\";\n        System.out.println(\"Resultado: \" + resultado);\n\n        // Operadores de bits\n        System.out.println(\"\\nOperadores de Bits:\\n\");\n        String num1Binary = Integer.toBinaryString(num1);\n        String num2Binary = Integer.toBinaryString(num2);\n        System.out.println(\"num1: \" + num1 + \" (\" + num1Binary + \")\");\n        System.out.println(\"num2: \" + num2 + \" (\" + num2Binary + \")\");\n        System.out.println(\"AND: \" + num1 + \" & \" + num2 + \" = \" + (num1 & num2) + \" (\" + Integer.toBinaryString(num1 & num2) + \")\");\n        System.out.println(\"OR: \" + num1 + \" | \" + num2 + \" = \" + (num1 | num2) + \" (\" + Integer.toBinaryString(num1 | num2) + \")\");\n        System.out.println(\"XOR: \" + num1 + \" ^ \" + num2 + \" = \" + (num1 ^ num2) + \" (\" + Integer.toBinaryString(num1 ^ num2) + \")\");\n        System.out.println(\"NOT: ~\" + num1 + \" = \" + (~num1) + \" (\" + Integer.toBinaryString(~num1) + \")\");\n        System.out.println(\"Desplazamiento a la izquierda: \" + num1 + \" << 2 = \" + (num1 << 2) + \" (\" + Integer.toBinaryString(num1 << 2) + \")\");\n        System.out.println(\"Desplazamiento a la derecha: \" + num1 + \" >> 2 = \" + (num1 >> 2) + \" (\" + Integer.toBinaryString(num1 >> 2) + \")\");\n\n        // Estructuras de control\n        System.out.println(\"\\nEstructuras de Control:\\n\");\n        // if - else if - else\n        if (num1 > num2) {\n            System.out.println(\"El número \" + num1 + \" es mayor que \" + num2);\n        } else if (num1 < num2) {\n            System.out.println(\"El número \" + num1 + \" es menor que \" + num2);\n        } else {\n            System.out.println(\"El número \" + num1 + \" es igual a \" + num2);\n        }\n        // switch\n        int dia = 3;\n        switch (dia) {\n            case 1:\n                System.out.println(\"Lunes\");\n                break;\n            case 2:\n                System.out.println(\"Martes\");\n                break;\n            case 3:\n                System.out.println(\"Miércoles\");\n                break;\n            case 4:\n                System.out.println(\"Jueves\");\n                break;\n            case 5:\n                System.out.println(\"Viernes\");\n                break;\n            case 6:\n                System.out.println(\"Sábado\");\n                break;\n            case 7:\n                System.out.println(\"Domingo\");\n                break;\n            default:\n                System.out.println(\"Día inválido\");\n        }\n        // bucles\n        System.out.println(\"\\nBucles:\\n\");\n        // while\n        int i = 0;\n        while (i < 5) {\n            System.out.println(\"While: \" + i);\n            i++;\n        }\n        // do while\n        int j = 0;\n        do {\n            System.out.println(\"Do While: \" + j);\n            j++;\n        } while (j < 5);\n        // for\n        for (int k = 0; k < 5; k++) {\n            System.out.println(\"For: \" + k);\n        }\n        // for each\n        int[] numeros = {1, 2, 3, 4, 5};\n        for (int numero : numeros) {\n            System.out.println(\"For Each: \" + numero);\n        }\n\n       // Identidad\n        System.out.println(\"\\nOperador Identidad:\\n\");\n        String cadena = \"Hola Mundo\";\n        if (cadena instanceof String){\n            System.out.println(\"La variable cadena es un String\");\n        } else {\n            System.out.println(\"La variable cadena no es un String\");\n        }\n\n        // Excepciones\n        System.out.println(\"\\nExcepciones:\\n\");\n        try {\n            int resultadoDivision = num3 / 0;\n            System.out.println(\"Resultado de la división: \" + resultadoDivision);\n        } catch (ArithmeticException e) {\n            System.out.println(\"Error: División por cero\");\n        } finally {\n            System.out.println(\"Bloque finally ejecutado\");\n        }\n\n        // Dificultad Extra\n        System.out.println(\"\\nDificultad Extra:\\n\");\n        for (int l = 10; l <=55; l++){\n            if (l!=16 && l%3!=0 && l%2==0){\n                System.out.println(l);\n            }\n        }\n\n\n\n\n\n\n\n\n\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/adrs1166ma.java",
    "content": "public class adrs1166ma {\n    public static void main(String[] args) {\n        // Operando1 = a\n        // Operando2 = b\n        // Respuesta = r\n        int a = 5, b = 3, r = 0;\n        System.out.println(\"Numero 1: \"+a+\" |  Numero 2:\"+b);\n\n        // ----------------------------------------------\n        System.out.println(\"/* -- Aritmeticos -- */\");\n        System.out.println(\"Suma: \"+(a+b));\n        System.out.println(\"Resta: \"+(a-b));\n        System.out.println(\"Multiplicacion: \"+(a*b));\n        System.out.println(\"Division: \"+(a/b));\n        System.out.println(\"Residuo: \"+(a%b));\n\n        // ----------------------------------------------\n        System.out.println(\"/* -- Logicos -- */\");\n        boolean t = true;\n        boolean f = false;\n        System.out.println(\" -- Y [AND] -- \");\n        System.out.println(\"false && false = \" + (f && f));\n        System.out.println(\"false && true  = \" + (f && t));\n        System.out.println(\"true  && false = \" + (t && f));\n        System.out.println(\"true  && true  = \" + (t && t));\n\n        System.out.println(\" -- O  [OR] -- \");\n        System.out.println(\"false || false = \" + (f || f));\n        System.out.println(\"false || true  = \" + (f || t));\n        System.out.println(\"true  || false = \" + (t || f));\n        System.out.println(\"true  || true  = \" + (t || t));\n\n        System.out.println(\" -- Negacion [NOT] -- \");\n        System.out.println(\"!true  = \" + (!t));\n        System.out.println(\"!false = \" + (!f));\n\n        // ----------------------------------------------\n        System.out.println(\"/* -- Comparacion -- */\");\n        System.out.println(\"a == b = \" + (a == b));\n        System.out.println(\"a != b = \" + (a != b));\n        System.out.println(\"a > b = \" + (a > b));\n        System.out.println(\"a < b = \" + (a < b));\n        System.out.println(\"a >= b = \" + (a >= b));\n        System.out.println(\"a <= b = \" + (a <= b));\n\n\n        // ----------------------------------------------\n        System.out.println(\" -- Asignacion -- \");\n        System.out.println(\"Asignación: \" + (a = b));\n        System.out.println(\"Suma y asignación: \" + (a += b));\n        System.out.println(\"Resta y asignación: \" + (a -= b));\n        System.out.println(\"Multiplicación y asignación: \" + (a *= b));\n        System.out.println(\"División y asignación: \" + (a /= b));\n        System.out.println(\"Resto y asignación: \" + (a %= b));\n        System.out.println(\"AND y asignación: \" + (a &= b));\n        System.out.println(\"OR y asignación: \" + (a |= b));\n        System.out.println(\"XOR y asignación: \" + (a ^= b));\n        System.out.println(\"Desplazamiento a la izquierda y asignación: \" + (a <<= b));\n        System.out.println(\"Desplazamiento a la derecha y asignación: \" + (a >>= b));\n        System.out.println(\"Desplazamiento a la derecha sin signo y asignación: \" + (a >>>= b));\n\n        // ----------------------------------------------\n\n        /* NO IDENTIDAD  |  NO PERTENCIA */\n\n        // ----------------------------------------------\n\n        System.out.println(\" -- Bits -- \");\n        System.out.println(\"5 & 2 = \" + (a & b));\n        System.out.println(\"5 | 2 = \" + (a | b));\n        System.out.println(\"5 ^ 2 = \" + (a ^ b));\n        System.out.println(\"~5 = \" + (~a));\n        System.out.println(\"5 << 2 = \" + (a << 2));\n        System.out.println(\"5 >> 2 = \" + (a >> 2));\n        System.out.println(\"5 >>> 2 = \" + (a >>> 2));\n\n        // ----------------------------------------------\n\n        /*\n         * Estructuras de control\n         */\n\n        System.out.println(\" -- Ternarios -- \");\n        int mayorEdad = 18;\n        String msg = mayorEdad >= 18 ? \"Eres mayor de edad\" : \"Eres menor de Edad\";\n        System.out.println(msg);\n\n        System.out.println(\" -- if | else -- \");\n        boolean miCondicion = false;\n        if (miCondicion == true) {\n            System.out.println(\" Mi condición es verdadera \");\n        } else if (miCondicion == false) {\n            System.out.println(\" Mi condicion es reconocida \");\n        } else {\n            System.out.println(\" Mi condicion es reconocida \");\n        }\n\n        System.out.println(\" -- for -- \");\n        for (int i = 0; i < 10; i++){\n            System.out.println(\"i = \"+i);\n        }\n\n        int i = 0;\n        System.out.println(\" -- while -- \");\n        while (i < 10){\n            System.out.println(\"i = \"+i);\n            i++;\n        }\n\n        System.out.println(\" -- do while -- \");\n        do {\n            System.out.println(\"i = \"+i);\n            i++;\n        } while (i < 5);\n\n        System.out.println(\" -- switch -- \");\n        switch (a) {\n            case 1:\n                System.out.println(\"a es 1\");\n                break;\n            case 2:\n                System.out.println(\"a es 2\");\n                break;\n            case 3:\n                System.out.println(\"a es 3\");\n                break;\n            default:\n                System.out.println(\"a no es 1, 2 o 3\");\n                break;\n        }\n\n        System.out.println(\" -- break -- \");\n        for (int j=0;j<5;j++){\n            if (j==3){\n                break;\n            }\n            System.out.println(\"j = \"+j);\n        }\n\n        System.out.println(\" -- continue -- \");\n        for (int j=0;j<5;j++){\n            if (j==3){\n                continue;\n            }\n            System.out.println(\"j = \"+j);\n        }\n\n        try {\n            int resultado = a/0;\n            System.out.println(\"Resultado: \"+resultado);\n        } catch (ArithmeticException e){\n            System.out.println(\"Error: Division por cero\");\n        }\n\n        /*\n        * Extra\n        */\n\n        for (int x=10;x<=55;x++){\n            if (x==16){\n                continue;\n            } else if ((x%3)==0) {\n                continue;\n            } else {\n                System.out.println(x);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/agusrosero.java",
    "content": "public class agusrosero {\n    public static void main(String[] args) {\n        int a = 10;\n        int b = 20;\n        boolean c = true;\n        boolean d = false;\n\n        // aritméticos\n        var suma = a + b;\n        var resta = a - b;\n        var multiplicacion = a * b;\n        var division = a / b;\n        var modulo = a % b;\n\n        // lógicos\n        var or = c || d;\n        var and = c && d;\n        var not = !c;\n\n        // comparación\n        var igual = a == b;\n        var mayor = a > b;\n        var mayorIgual = a >= b;\n        var menor = a < b;\n        var menorIgual = a <= b;\n\n        // asignación\n        a += b;\n        a -= b;\n        a /= b;\n        a *= b;\n        a %= b;\n\n        // estructuras de control\n        int number = 10;\n\n        for (int i = 0; i < number; i++) {\n            System.out.println(i);\n        }\n\n        if (number == 10) {\n            System.out.println(\"Numero 10!\");\n        } else {\n            System.out.println(\"No es numero 10.\");\n        }\n\n        switch (number) {\n            case 10:\n                System.out.println(\"Numero 10!\");\n                break;\n            default:\n                System.out.println(\"Se ejecuto correctamente...\");\n                break;\n        }\n\n        while (number <= 10) {\n            System.out.println(number++);\n        }\n\n        do {\n            System.out.println(\"Ejecutando 10 veces...\");\n            number++;\n        } while (number <= 20);\n\n        // DIFICULTAD EXTRA (opcional):\n        /*\n         * Crea un programa que imprima por consola todos los números comprendidos\n         * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n         */\n        for (int i = 10; i <= 55; i++) {\n            if (i % 2 == 0 && i != 16 && i % 3 != 0) {\n                System.out.println(i);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/albertovf.java",
    "content": "/**\n * albertovf\n */\npublic class albertovf {\n\n\tpublic static void main(String[] args) {\n\t\tfor (int i = 10; i <= 55; i += 2) {\n\t\t\tif (i != 16 & i % 3 != 0) {\n\t\t\t\tSystem.out.println(i);\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/alvarofernandezavalos.java",
    "content": "public class alvarofernandezavalos {\n  public static final int START=10;\n  public static final int END=55;\n  public static void main(String[] args) {\n    System.out.println(\"Operadores Aritméticos\");\n    int suma=0;\n    for(int x=0;x<3;x++) suma=suma+x;\n    System.out.println(\"Suma Total: \"+suma);\n    while (suma<END) suma++;\n    System.out.println(\"Suma Total: \"+suma);\n    do {\n      suma++;\n    } while (suma<END*2);\n    System.out.println(\"Suma Total: \"+suma);\n    int array[] = {1,2,3,4,5};\n    for (int x : array) System.out.println(x);\n    try {\n      Integer.parseInt(\"S\");\n    } catch (Exception e) {\n      System.err.println(\"No se puede convertir a Integer\");\n    }\n    System.out.println(\"Operadores Lógicos\");\n    int a = 10; int b = 20; int c = 15; int d = 23;\n    System.out.println(a+\" es menor que \"+b+\" AND \"+c+\" es mayor que \"+d+\" ? \"+ (a<b && c>d));\n    System.out.println(a+\" es menor que \"+b+\" OR \"+c+\" es mayor que \"+d+\" ? \"+ (a<b || c>d));\n    System.out.println(a+\" es menor que \"+b+\" NOT \"+c+\" es mayor que \"+d+\" ? \"+ !(a<b && c>d));\n    System.out.println(\"Operadores Comparación\");\n    System.out.println(\"A es mayor que B \"+(a>b));\n    System.out.println(\"A es igual a B \"+(a==b));\n    System.out.println(\"A es mayor o igual a B \" + (a>=b));\n    System.out.println(\"A es diferente a B \"+(a!=b));\n    System.out.println(\"Operadores Asignación\");\n    System.out.println(\"El valor de suma es \"+suma);\n    suma=suma+1;\n    System.out.println(\"He sumado 1 a suma, su nuevo valor es\"+suma);\n    suma+=1;\n    System.out.println(\"He sumado 1 a suma, su nuevo valor es \"+suma);\n    suma-=1;\n    System.out.println(\"He restado 1 a suma, su nuevo valor es \"+suma);\n    suma*=2;\n    System.out.println(\"He multiplicado el valor de suma por 2, su nuevo valor es \"+suma);\n    suma/=2;\n    System.out.println(\"He dividido el valor de suma entre 2, su nuevo valor es \"+suma);\n    System.out.println(\"Operadores Identidad\");\n    //cosultamos si el objeto apunta al mismo puntero.\n    //no estamos comprobando si las cadena son iguales.\n    String string1 = new String(\"Alvaro\");\n    String string2 = new String(\"Alvaro\");\n    System.out.println(string1==string2);\n    System.out.println(\"Operador Ternario\");\n    suma = (a>b ? 10: 20);\n    System.out.println(\"El Valor de suma es \"+suma);\n    System.out.println(\"Operadores Bits\");\n    int puerta1 = 6; //(0110)\n    int puerta2 = 5; //(0101)\n    int result = puerta1|puerta2;\n    System.out.println(\"Puerta 1 OR Puerta 2 \"+result+\" Binary: \" + Integer.toString(result,2));\n    result = puerta1 & puerta2;\n    System.out.println(\"Puerta 1 AND Puerta 2 \"+result+\" Binary: \" + Integer.toString(result,2));\n    result = puerta1 ^ puerta2;\n    System.out.println(\"Puerta 1 XOR Puerta 2 \"+result+\" Binary: \" + Integer.toString(result,2));\n    System.out.println(\"Parte Opctional:\");\n    for(int x=START;x<=END;x++) {\n      if(x%2==0 && x!=16 && x%3!=0) System.out.println(x);\n    }\n  }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/andresmendozaf.java",
    "content": "\npublic class andresmendozaf {\n\n    public static void main(String[] args) {\n\n        /*\n         * Operadores \n         */\n        // Operadores aritméticos\n        int a = 10;\n        int b = 3;\n        int suma = 10 + 5;\n        System.out.println(suma);\n        System.out.println(\"Suma: 10 + 3 = \" + (a + b));\n        System.out.println(\"Resta: 10 - 3 = \" + (a - b));\n        System.out.println(\"Multiplicación: 10 * 3 = \" + (a * b));\n        System.out.println(\"División: 10 / 3 = \" + (double) a / b);\n        System.out.println(\"Módulo: 10 % 3 = \" + (a % b));\n        System.out.println(\"Exponente: Math.pow(10, 3) = \" + Math.pow(a, b));\n        System.out.println(\"División exacta: 10 / 3 = \" + (a / b));\n\n        // Operadores de comparación # devuelve un valor True o False\n        System.out.println(\"Igual a: 10 == 3 es \" + (10 == 3));\n        System.out.println(\"No es igual: 10 != 3 es \" + (10 != 3));\n        System.out.println(\"Es mayor que: 10 > 3 es \" + (10 > 3));\n        System.out.println(\"Es menor que: 10 < 3 es \" + (10 < 3));\n        System.out.println(\"Es mayor o igual que: 10 >= 10 es \" + (10 >= 10));\n        System.out.println(\"Es menor o igual que: 10 <= 8 es \" + (10 <= 8));\n\n        // Operadores lógicos\n        int c = 5;\n        int d = 1;\n\n        System.out.println(\"AND: (10 + 3 == 13) && (5 - 1 == 4) es: \" + ((a + b == 13) && (c - d == 4)));\n        System.out.println(\"OR: (10 + 9 == 19) || (5 - 1 == 6) es: \" + ((10 + 9 == 19) || (c - d == 6)));\n        System.out.println(\"NOT: 20 + 7 != 24 es: \" + (20 + 7 != 24));\n\n        // Operadores de asigmación\n        int numero = 12; // = asignación\n        System.out.println(\"Mi número es: \" + numero);\n        numero += 5; // + suma y asignación\n        System.out.println(numero);\n        numero -= 5; // - resta y asignación\n        System.out.println(numero);\n        numero *= 5; // * multiplicación y asignación\n        System.out.println(numero);\n        numero /= (double) 4; // / división y asignación\n        System.out.println(numero);\n        numero %= 2; // % módulo y asignación\n        System.out.println(numero);\n        numero = (int) Math.pow(numero, 8); // ** exponente y asignación\n        System.out.println(numero);\n        numero /= 3; //= 12 # división exacta y asignación \n        System.out.println(numero);\n\n        // Operadores de identidad\n        int nuevo_numero = 0;\n        System.out.println(\"numero == nuevo_numero es: \" + (numero == nuevo_numero)); //referencia al valor\n        System.out.println(\"numero != nuevo_numero es: \" + (numero != nuevo_numero));\n        String str1 = \"Hola\";\n        String str2 = \"hola\";\n        System.out.println(\"str1.equals(str2) es: \" + (str1.equals(str2)));\n\n        // Operadores unarios\n        int positivo = +a;\n        System.out.println(\"Positivo (+a): \" + positivo);\n        int negativo = -a;\n        System.out.println(\"Negativo (-a): \" + negativo);\n        a++;\n        System.out.println(\"Incremento (a++): \" + a);\n        a--;\n        System.out.println(\"Decremento (a--): \" + a);\n\n        boolean verdadero = true;\n        boolean negado = !verdadero;\n        System.out.println(\"Negación lógica (!verdadero): \" + negado);\n\n        // Operadores bit a bit\n        int x = 10; //1010\n        int y = 3; //0011\n        System.out.println(\"AND (&): \" + (x & y)); //0010\n        System.out.println(\"OR (|): \" + (x | y)); //1011\n        System.out.println(\"XOR (^): \" + (x ^ y)); //1001\n        System.out.println(\"COMPLEMENTO (~): \" + (~y)); //1111 1100 da vuelta los 0 y 1\n        System.out.println(\"Desplazamiento a la derecha (>>): \" + (8 >> 2)); //0000 0010\n        System.out.println(\"Desplazamiento a la izquierda (<<): \" + (3 << 2)); //0000 1100\n\n        // Operador ternario\n        String ternario = (a > (b += 15)) ? \"a es mayor que b\" : \"a no es mayor que b\";\n        System.out.println(ternario);\n\n        boolean esString = ternario instanceof String;\n        System.out.println(\"¿ternario es una instancia de String? \" + esString);\n        Integer prueba = 42;\n        boolean esInteger = prueba instanceof Integer;\n        System.out.println(\"¿numero es una instancia de Integer? \" + esInteger);\n\n        /*\n         * Estrucuras de Control \n         */\n        //Condicionales\n        String mi_cadena = \"AndresMendoza\";\n        if (mi_cadena == \"AndresMendoza\") {\n            System.out.println(\"mi_cadena es 'AndresMendoza'\");\n        } else if (mi_cadena == \"Figueroa\") {\n            System.out.println(\"mi_cadena es 'Figueroa'\");\n        } else {\n            System.out.println(\"mi_cadena no es ni 'AndresMendoza' ni tampoco 'Figueroa'\");\n        }\n\n        int dia = 3;\n        String nombreDia;\n\n        switch (dia) {\n            case 1:\n                nombreDia = \"Lunes\";\n                break;\n            case 2:\n                nombreDia = \"Martes\";\n                break;\n            case 3:\n                nombreDia = \"Miércoles\";\n                break;\n            case 4:\n                nombreDia = \"Jueves\";\n                break;\n            case 5:\n                nombreDia = \"Viernes\";\n                break;\n            case 6:\n                nombreDia = \"Sábado\";\n                break;\n            case 7:\n                nombreDia = \"Domingo\";\n                break;\n            default:\n                nombreDia = \"Día inválido\";\n                break;\n        }\n        System.out.println(\"El día seleccionado es: \" + nombreDia);\n\n        // Iterativas\n        for (int i = 1; i <= 10; i++) {\n            System.out.print(i + \" - \");\n        }\n\n        System.out.println();\n        int k = 1;\n        while (k <= 7) {\n            System.out.print(k + \" - \");\n            k++;\n        }\n\n        System.out.println();\n        for (int i = 1; i <= 8; i++) {\n            if (i == 5) {\n                break; // Sale del bucle cuando i es igual a 5\n            }\n            System.out.print(i + \" \");\n        }\n\n        System.out.println();\n        for (int i = 1; i <= 10; i++) {\n            if (i % 2 == 0) {\n                continue; // Omite la impresión para números pares\n            }\n            System.out.print(i + \" \");\n        }\n        System.out.println();\n        System.out.println();\n        // Excepciones \n\n        try {\n            int resultado = dividir(10, 5);\n            System.out.println(\"Resultado: \" + resultado);\n        } catch (ArithmeticException e) {\n            System.out.println(\"Error: \" + e.getMessage());\n        } finally {\n            System.out.println(\"Este bloque se ejecuta siempre.\");\n        }\n\n        try {\n            lanzarExcepcion();\n        } catch (Exception e) {\n            System.out.println(\"Excepción capturada: \" + e.getMessage());\n        }\n\n        /*\n         * Ejercicio extra \n         */\n\n         for (int i = 10; i <= 55; i++) {\n            if (i % 2 == 0 && i != 16 && i % 3 != 0){\n                System.out.print(i + \" \");\n            }\n        }\n    }\n\n    public static int dividir(int numerador, int divisor) {\n        if (divisor == 0) {\n            throw new ArithmeticException(\"No se puede dividir por cero.\");\n        }\n        return numerador / divisor;\n    }\n\n    public static void lanzarExcepcion() throws Exception {\n        throw new Exception(\"Excepción lanzada explícitamente.\");\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/asjordi.java",
    "content": "public class Main {\n\n    public static void main(String[] args) {\n        operadoresAritmeticos();\n        operadoresLogicos();\n        operadoresComparacion();\n        operadoresAsignacion();\n        operadoresUnarios();\n        operadoresBits();\n\n        System.out.println(\"Estructuras de control\");\n\n        System.out.println(\"if\");\n        int n1 = 10;\n        int n2 = 20;\n        // Verifica si n1 es mayor a n2\n        if (n1 > n2) {\n            System.out.println(\"n1 es mayor a n2\");\n        }\n        System.out.println(\"Estructura if-else\");\n        // Verifica si n1 es mayor a n2\n        if (n1 > n2) {\n            System.out.println(\"n1 es mayor a n2\");\n        } else {\n            System.out.println(\"n1 es menor o igual a n2\");\n        }\n        System.out.println(\"Estructura if-else if-else\");\n        // Verifica si n1 es mayor a n2\n        if (n1 > n2) {\n            System.out.println(\"n1 es mayor a n2\");\n        } else if (n1 < n2) {\n            System.out.println(\"n1 es menor a n2\");\n        } else {\n            System.out.println(\"n1 es igual a n2\");\n        }\n\n        System.out.println(\"switch\");\n        int dia = 1;\n        // Verifica el valor de la variable dia\n        switch (dia) {\n            case 1:\n                System.out.println(\"Lunes\");\n                break;\n            case 2:\n                System.out.println(\"Martes\");\n                break;\n            default:\n                System.out.println(\"No es lunes ni martes\");\n                break;\n        }\n\n        System.out.println(\"while\");\n        int i = 0;\n        // Mientras i sea menor a 10\n        while (i < 10) {\n            System.out.println(\"i = \" + i);\n            i++;\n        }\n\n        System.out.println(\"do-while\");\n        int j = 0;\n        // Mientras j sea menor a 10\n        do {\n            System.out.println(\"j = \" + j);\n            j++;\n        } while (j < 10);\n\n        System.out.println(\"for\");\n        // Mientras i sea menor a 10\n        for (int k = 0; k < 10; k++) {\n            System.out.println(\"k = \" + k);\n        }\n\n        System.out.println(\"for-each\");\n        // Crea un arreglo de números\n        int[] numeros = {1, 2, 3, 4, 5};\n        // Recorre el arreglo de números\n        for (int numero : numeros) {\n            System.out.println(\"numero = \" + numero);\n        }\n\n        System.out.println(\"break\");\n        // Mientras i sea menor a 10\n        for (int k = 0; k < 10; k++) {\n            // Si k es igual a 5\n            if (k == 5) {\n                // Detiene el ciclo\n                break;\n            }\n            System.out.println(\"k = \" + k);\n        }\n\n        System.out.println(\"continue\");\n        // Mientras i sea menor a 10\n        for (int k = 0; k < 10; k++) {\n            // Si k es igual a 5\n            if (k == 5) {\n                // Continua con la siguiente iteración\n                continue;\n            }\n            System.out.println(\"k = \" + k);\n        }\n\n        // Control de excepciones\n        System.out.println(\"Control de excepciones\");\n        try {\n            // Intenta ejecutar el código\n            int resultado = 10 / 0;\n            System.out.println(\"resultado = \" + resultado);\n        } catch (Exception e) {\n            // Si ocurre una excepción, ejecuta el código\n            System.out.println(\"Ocurrió un error\");\n        } finally {\n            // Siempre se ejecuta el código\n            System.out.println(\"Se ejecuta el finally\");\n        }\n\n        /**\n         * Crea un programa que imprima por consola todos los números comprendidos\n         * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n         */\n\n        for (int k = 10; k <= 55 ; k++) {\n            if (k % 2 == 0 && k != 16 && k % 3 != 0) System.out.println(\"k = \" + k);\n        }\n    }\n\n    static void operadoresAritmeticos() {\n        System.out.println(\"Operadores aritméticos\");\n        int n1 = 10;\n        int n2 = 5;\n        // Suma dos valores con el operador +\n        int suma = n1 + n2;\n        System.out.println(\"Suma: \" + suma);\n        // Resta dos valores con el operador -\n        int resta = n1 - n2;\n        System.out.println(\"Resta: \" + resta);\n        // Multiplica dos valores con el operador *\n        int multiplicacion = n1 * n2;\n        System.out.println(\"Multiplicación: \" + multiplicacion);\n        // Divide dos valores con el operador /\n        int division = n1 / n2;\n        System.out.println(\"División: \" + division);\n        // Módulo dos valores con el operador %\n        int modulo = n1 % n2;\n        System.out.println(\"Módulo: \" + modulo);\n    }\n\n    static void operadoresLogicos() {\n        System.out.println(\"Operadores lógicos\");\n        int n1 = 10;\n        int n2 = 20;\n        // Verifica si n1 y n2 son mayores a 0 con el operador && -> AND\n        if (n1 > 0 && n2 > 0) {\n            System.out.println(\"n1 y n2 son mayores a 0\");\n        }\n        // Verifica si n1 o n2 son mayores a 0 con el operador || -> OR\n        if (n1 > 0 || n2 > 0) {\n            System.out.println(\"n1 o n2 son mayores a 0\");\n        }\n        // Verifica si n1 es diferente a 0 con el operador != -> NOT\n        if (n1 != 0) {\n            System.out.println(\"n1 es diferente a 0\");\n        }\n    }\n\n    static void operadoresComparacion() {\n        System.out.println(\"Operadores de comparación\");\n        int n1 = 10;\n        int n2 = 20;\n        // Verifica si n1 es mayor a n2 con el operador >\n        if (n1 > n2) {\n            System.out.println(\"n1 es mayor a n2\");\n        }\n        // Verifica si n1 es menor a n2 con el operador <\n        if (n1 < n2) {\n            System.out.println(\"n1 es menor a n2\");\n        }\n        // Verifica si n1 es mayor o igual a n2 con el operador >=\n        if (n1 >= n2) {\n            System.out.println(\"n1 es mayor o igual a n2\");\n        }\n        // Verifica si n1 es menor o igual a n2 con el operador <=\n        if (n1 <= n2) {\n            System.out.println(\"n1 es menor o igual a n2\");\n        }\n        // Verifica si n1 es igual a n2 con el operador ==\n        if (n1 == n2) {\n            System.out.println(\"n1 es igual a n2\");\n        }\n        // Verifica si n1 es diferente a n2 con el operador !=\n        if (n1 != n2) {\n            System.out.println(\"n1 es diferente a n2\");\n        }\n    }\n\n    static void operadoresAsignacion() {\n        System.out.println(\"Operador de asignación\");\n        int n;\n        // Asigna un valor a n con el operador de asignación =\n        n = 10;\n        System.out.println(\"n = \" + n);\n        // Asigna un valor a n con el operador de asignación +=\n        n += 5;\n        System.out.println(\"n = \" + n);\n        // Resta un valor a n con el operador -=\n        n -= 5;\n        System.out.println(\"n = \" + n);\n        // Multiplica un valor a n con el operador *=\n        n *= 5;\n        System.out.println(\"n = \" + n);\n        // Divide un valor a n con el operador /=\n        n /= 5;\n        System.out.println(\"n = \" + n);\n        // Módulo un valor a n con el operador %=\n        n %= 5;\n        System.out.println(\"n = \" + n);\n    }\n\n    static void operadoresUnarios() {\n        System.out.println(\"Operadores unarios\");\n        // Operador unario + -> Representa un valor positivo, por defecto los valores son positivos\n        int n = +10;\n        System.out.println(\"n = \" + n);\n        // Operador de incremento ++ -> Incrementa en 1 el valor de la variable\n        n++;\n        System.out.println(\"n = \" + n);\n        // Operador de decremento -- -> Decrementa en 1 el valor de la variable\n        n--;\n        System.out.println(\"n = \" + n);\n        --n; // Decrementa en 1 el valor de la variable\n        System.out.println(\"n = \" + n);\n        ++n; // Incrementa en 1 el valor de la variable\n        System.out.println(\"n = \" + n);\n        // Operador unario - -> Representa un valor negativo\n        n = -n;\n        System.out.println(\"n = \" + n);\n        // Operador de negación ! -> Niega el valor de una variable booleana\n        boolean b = !true;\n        System.out.println(\"b = \" + b);\n    }\n\n    static void operadoresBits() {\n        System.out.println(\"Operadores de bits\");\n        int n1 = 10;\n        int n2 = 20;\n        // Operador de desplazamiento a la izquierda << -> Desplaza los bits de un valor a la izquierda\n        int desplazamientoIzquierda = n1 << 2;\n        System.out.println(\"Desplazamiento a la izquierda: \" + desplazamientoIzquierda);\n        // Operador de desplazamiento a la derecha >> -> Desplaza los bits de un valor a la derecha\n        int desplazamientoDerecha = n1 >> 2;\n        System.out.println(\"Desplazamiento a la derecha: \" + desplazamientoDerecha);\n        // Operador de desplazamiento a la derecha sin signo >>> -> Desplaza los bits de un valor a la derecha sin signo\n        int desplazamientoDerechaSinSigno = n1 >>> 2;\n        System.out.println(\"Desplazamiento a la derecha sin signo: \" + desplazamientoDerechaSinSigno);\n        // Operador AND a nivel de bits & -> Realiza la operación AND a nivel de bits\n        int and = n1 & n2;\n        System.out.println(\"AND: \" + and);\n        // Operador OR a nivel de bits | -> Realiza la operación OR a nivel de bits\n        int or = n1 | n2;\n        System.out.println(\"OR: \" + or);\n        // Operador XOR a nivel de bits ^ -> Realiza la operación XOR a nivel de bits\n        int xor = n1 ^ n2;\n        System.out.println(\"XOR: \" + xor);\n        // Operador de complemento a nivel de bits ~ -> Realiza la operación de complemento a nivel de bits\n        int complemento = ~n1;\n        System.out.println(\"Complemento: \" + complemento);\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/bladi23.java",
    "content": "public class bladi23 {\n    public static void main(String[] args) {\n\n        // Tipos de operadores en java\n\n        // Operadores aritmeticos\n        int a = 2, b = 4;\n        System.out.println(\"a + b = \" + (a + b));\n        System.out.println(\"a - b = \" + (a - b));\n        System.out.println(\"a * b = \" + (a * b));\n        System.out.println(\"b / a = \" + (b / a));\n        System.out.println(\"b % a = \" + (b % a));\n        System.out.println(\"a++ = \" + (a++));\n        System.out.println(\"b-- = \" + (b--));\n        // Operadores de asignacion\n        a += 2;\n        System.out.println(\"a += 2 = \" + a);\n\n        // Operadores de comparacion\n        System.out.println(\"a == b: \" + (a == b));\n        System.out.println(\"a != b: \" + (a != b));\n        System.out.println(\"a > b: \" + (a > b));\n        System.out.println(\"a < b: \" + (a < b));\n        System.out.println(\"b >= a: \" + (b >= a));\n        System.out.println(\"b <= a: \" + (b <= a));\n        // Operadores logicos\n        System.out.println(\"(a == b) && (a < b): \" + ((a == b) && (a < b)));\n        System.out.println(\"(a == b) || (a < b): \" + ((a == b) || (a < b)));\n        System.out.println(\"!(a == b): \" + !(a == b));\n\n        // Operadores de incremento y decremento\n        a++; // incremento\n        a--; // decremento\n\n        // Operadores de concatenacion\n        String texto1 = \"Hola, \";\n        String texto2 = \"¿cómo estás?\";\n        System.out.println(texto1 + texto2);\n\n        // Operadores ternarios\n        String result = (a > b) ? \"a es mayor que b\" : \"b es mayor o igual que a\";\n        System.out.println(result);\n        // Operadores de instancia\n        String texto = \"Hola\";\n        if (texto instanceof String) {\n            System.out.println(\"texto es una instancia de String\");\n        }\n\n        // Tipos de estructura de control en java\n\n        // Estructura if\n        if (a > b) {\n        } else if (a == b) {\n        } else {\n            System.out.println(\"a es menor que b\");\n        }\n\n        // Estructura switch\n        switch (a) {\n            case 1:\n                System.out.println(\"a es igual a 1\");\n                break;\n            case 2:\n                System.out.println(\"a es igual a 2\");\n                break;\n            default:\n                System.out.println(\"a no es igual a 1 ni a 2\");\n                break;\n        }\n\n        // Estructura while\n        while (a < b) {\n            System.out.println(\"a es menor que b\");\n            a++;\n        }\n\n        // Estructura do while\n        do {\n            System.out.println(\"a es menor que b\");\n            a++;\n        } while (a < b);\n\n        // Estructura for\n        for (int i = 0; i < 10; i++) {\n            System.out.println(\"i es igual a \" + i);\n        }\n\n        // Estructura for each\n        int[] numeros = { 1, 2, 3, 4, 5 };\n        for (int numero : numeros) {\n            System.out.println(\"numero es igual a \" + numero);\n        }\n\n        // Estructura break\n        for (int i = 0; i < 10; i++) {\n            if (i == 5) {\n                break;\n            }\n            System.out.println(\"i es igual a \" + i);\n        }\n        // Estructura continue\n        for (int i = 0; i < 10; i++) {\n            if (i == 5) {\n                continue;\n            }\n            System.out.println(\"i es igual a \" + i);\n        }\n\n        /*\n         * DIFICULTAD EXTRA (opcional):\n         * Crea un programa que imprima por consola todos los números comprendidos\n         * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n         */\n\n        for (int i = 10; i <= 55; i++) {\n            if (i % 2 == 0 && i != 16 && i % 3 != 0) {\n                System.out.println(i);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/cesar-ch.java",
    "content": "public class Main {\n    public static void main(String[] args) {\n        // Operadores Aritméticos\n        int a = 5;\n        int b = 2;\n        System.out.println(\"Suma: \" + (a + b));\n        System.out.println(\"Resta: \" + (a - b));\n        System.out.println(\"Multiplicación: \" + (a * b));\n        System.out.println(\"División: \" + (a / (double) b));\n        System.out.println(\"Módulo: \" + (a % b));\n        System.out.println(\"Incremento: \" + (++a));\n        System.out.println(\"Decremento: \" + (--b));\n\n        // Operadores de Comparación\n        int x = 10;\n        String y = \"10\";\n        System.out.println(\"Igualdad: \" + (x == Integer.parseInt(y)));\n        System.out.println(\"Igualdad estricta: \" + (x == Integer.parseInt(y)));\n        System.out.println(\"Desigualdad: \" + (a != b));\n        System.out.println(\"Mayor que: \" + (a > b));\n        System.out.println(\"Menor que o igual: \" + (a <= b));\n\n        // Operadores Lógicos\n        boolean p = true;\n        boolean q = false;\n        System.out.println(\"AND lógico: \" + (p && q));\n        System.out.println(\"OR lógico: \" + (p || q));\n        System.out.println(\"NOT lógico: \" + (!p));\n\n        // Operadores de Asignación\n        int c = 3;\n        c += 2;\n        System.out.println(\"Asignación con adición: \" + c);\n\n        // Operadores de Identidad\n        System.out.println(\"Identidad: \" + (x == 10));\n        System.out.println(\"No identidad: \" + (Integer.parseInt(y) != 10));\n\n        // Operadores de Pertenencia\n        int[] arreglo = {1, 2, 3};\n        System.out.println(\"Pertenece al arreglo: \" + (contains(arreglo, 2)));\n\n        // Operadores de Bits\n        int num1 = 5; // Representación binaria: 0101\n        int num2 = 3; // Representación binaria: 0011\n        System.out.println(\"AND a nivel de bits: \" + (num1 & num2)); // Resultado: 0001 (1 en binario)\n        System.out.println(\"OR a nivel de bits: \" + (num1 | num2)); // Resultado: 0111 (7 en binario)\n        System.out.println(\"Desplazamiento a la izquierda: \" + (num1 << 1)); // Resultado: 1010 (10 en binario)\n        System.out.println(\"Desplazamiento a la derecha: \" + (num1 >> 1)); // Resultado: 0010 (2 en binario)\n\n        // Estructuras de Control\n        // Condicionales\n        int edad = 18;\n        if (18 <= edad && edad <= 125) {\n            System.out.println(\"Eres mayor de edad\");\n        } else if (edad < 18) {\n            System.out.println(\"Eres menor de edad\");\n        } else {\n            System.out.println(\"Edad no válida\");\n        }\n\n        // Excepciones\n        try {\n            double resultado = 10 / 0;\n            System.out.println(\"Resultado: \" + resultado);\n        } catch (ArithmeticException e) {\n            System.out.println(\"Error: \" + e.getMessage());\n        } finally {\n            System.out.println(\"Finalizado el bloque try-catch\");\n        }\n\n        // Programa\n        for (int i = 10; i <= 55; i++) {\n            if (i % 2 == 0 && i != 16 && i % 3 != 0) {\n                System.out.println(i);\n            }\n        }\n    }\n\n    private static boolean contains(int[] array, int targetValue) {\n        for (int value : array) {\n            if (value == targetValue) {\n                return true;\n            }\n        }\n        return false;\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/chartypes.java",
    "content": "class chartypes{\n  public static void main(String[] args){\n    operations();\n    conditions();\n    loops();\n    iterNumbers();\n\n\n\n  }\n\n  public static void operations(){\n    // Asignacion\n    int number = 1;\n    String phrase = \"Hello World\";\n\n    // Aritmeticos\n    int sum = 1 + 1;\n    int sub = 1 - 1;\n    int mul = 1 * 1;\n    int div = 1 / 1;\n    int mod = 1 % 1;\n\n    // Logicos\n    boolean isTrue = true;\n    boolean isFalse = false;\n    boolean and = isTrue && isFalse;\n    boolean or = isTrue || isFalse;\n    boolean not = !isTrue;\n\n    // Comparacion\n    boolean equal = 1 == 1;\n    boolean notEqual = 1 != 1;\n    boolean greater = 1 > 1;\n    boolean less = 1 < 1;\n    boolean greaterEqual = 1 >= 1;\n    boolean lessEqual = 1 <= 1;\n\n  }\n\n  public static void conditions(){\n    int number = 1;\n    // If Else\n    if(true){\n      System.out.println(\"Is True\");\n    }else{\n      System.out.println(\"Is False\");\n    }\n\n    // Switch\n    switch(number){\n      case 1:\n        System.out.println(\"Is 1\");\n        break;\n      case 2:\n        System.out.println(\"Is 2\");\n        break;\n      default:\n        System.out.println(\"Is not 1 or 2\");\n    }\n  }\n\n  public static void loops(){\n    // For\n    for(int i = 0; i < 10; i++){\n      System.out.println(i);\n    }\n\n    // For each\n    int[] numbers = {1,2,3,4,5};\n    for(int numb : numbers){\n      System.out.println(numb);\n    }\n\n    // While\n    int i = 0;\n    while(i < 10){\n      System.out.println(i);\n      i++;\n    }\n\n    // Do While\n    i = 0;\n    do{\n      System.out.println(i);\n      i++;\n    }while(i < 10);\n\n  }\n\n  public static void iterNumbers(){\n    for(int i=10; i<=55; i++){\n\n      if (i % 2 == 0 && i % 3 != 0 && i != 16){\n        System.out.println(i);\n      }\n\n    }\n  }\n\n}\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/curtobrull.java",
    "content": "public class curtobrull {\n    public static void main(String[] args) {\n\n        // Ejemplos con todos los tipos de operadores\n        int a = 10;\n        int b = 5;\n\n        // Operadores aritméticos\n        int sum = a + b;\n        int sub = a - b;\n        int prod = a * b;\n        int div = a / b;\n        int mod = a % b;\n\n        System.out.println(\"Suma: \" + a + \"+\" + b + \"=\" + sum);\n        System.out.println(\"Resta: \" + a + \"-\" + b + \"=\" + sub);\n        System.out.println(\"Producto: \" + a + \"*\" + b + \"=\" + prod);\n        System.out.println(\"División: \" + a + \"/\" + b + \"=\" + div);\n        System.out.println(\"Módulo: \" + a + \"%\" + b + \"=\" + mod);\n\n        // Operadores de asignación\n        int c = 10;\n        c += 5;\n        System.out.println(\"Suma y asignación c += 5:\" + c);\n\n        c = 10;\n        c -= 5;\n        System.out.println(\"Resta y asignación c -= 5:\" + c);\n\n        c = 10;\n        c *= 5;\n        System.out.println(\"Producto y asignación c *= 5:\" + c);\n\n        c = 10;\n        c /= 5;\n        System.out.println(\"División y asignación c /= 5:\" + c);\n\n        c = 10;\n        c %= 5;\n        System.out.println(\"Módulo y asignación c %= 5:\" + c);\n\n        // Operadores de comparación\n        System.out.println(\"a == b: \" + (a == b));\n        System.out.println(\"a != b: \" + (a != b));\n        System.out.println(\"a > b: \" + (a > b));\n        System.out.println(\"a < b: \" + (a < b));\n        System.out.println(\"a >= b: \" + (a >= b));\n        System.out.println(\"a <= b: \" + (a <= b));\n\n        // Operadores lógicos\n        boolean trueBool = true;\n        boolean falseBool = false;\n\n        System.out.println(\"trueBool && f: \" + (trueBool && falseBool));\n        System.out.println(\"trueBool || f: \" + (trueBool || falseBool));\n        System.out.println(\"!trueBool: \" + (!trueBool));\n\n        // Operadores de incremento y decremento\n        int d = 10;\n        d++;\n        System.out.println(\"d = 10 Incremento d++: \" + d);\n\n        d = 10;\n        d--;\n        System.out.println(\"d = 10 Decremento d--: \" + d);\n\n        // Operadores de desplazamiento\n        int e = 10;\n        System.out.println(\"e << 1: \" + (e << 1));\n        System.out.println(\"e >> 1: \" + (e >> 1));\n\n\n        // Operadores de condicional\n        int f = (a > b) ? a : b;\n        System.out.println(\"f = (a > b) ? a : b: \" + f);\n\n        // Ejemplos que representen todos los tipos de estructuras de control\n\n        // Estructura de control if\n        System.out.println(\"Estructura de control if\");\n        if (a > b) {\n            System.out.println(\"a es mayor que b\");\n        } else {\n            System.out.println(\"a no es mayor que b\");\n        }\n\n        // Estructura de control switch (mejorado)\n        System.out.println(\"Estructura de control switch\");\n        int dayNum = 7;\n\n        String day = switch (dayNum) {\n            case 1 -> \"Lunes\";\n            case 2 -> \"Martes\";\n            case 3 -> \"Miércoles\";\n            case 4 -> \"Jueves\";\n            case 5 -> \"Viernes\";\n            case 6 -> \"Sábado\";\n            case 7 -> \"Domingo\";\n            default -> \"Día no válido\";\n        };\n\n        System.out.println(\"El día es: \" + day);\n\n        // Estructura de control for\n        System.out.println(\"Estructura de control for\");\n        for (int i = 0; i < 10; i++) {\n            System.out.println(\"i: \" + i);\n        }\n\n        // For mejorado\n        System.out.println(\"For mejorado\");\n        int[] numbers = {1, 2, 3};\n        for (int number : numbers) {\n            System.out.println(\"number: \" + number);\n        }\n\n        // Estructura de control while\n        System.out.println(\"Estructura de control while\");\n        int numWhile = 0;\n        while (numWhile < 3) {\n            System.out.println(\"numWhile: \" + numWhile);\n            numWhile++;\n        }\n\n        // Estructura de control do-while\n        System.out.println(\"Estructura de control do-while\");\n        int numDoWhile = 0;\n        do {\n            System.out.println(\"i: \" + numDoWhile);\n            numDoWhile++;\n        } while (numDoWhile < 3);\n\n        // Estructura de control con break\n        System.out.println(\"Estructura de control con break\");\n        for (int j = 0; j < 10; j++) {\n            if (j == 3) {\n                break;\n            }\n            System.out.println(\"Break. j: \" + j);\n        }\n\n        // Estructura de control con continue\n        System.out.println(\"Estructura de control con continue\");\n        for (int j = 0; j < 5; j++) {\n            if (j == 3) {\n                continue;\n            }\n            System.out.println(\"Continue. j: \" + j);\n        }\n\n        // Ejercicio extra\n        /*\n        Imprimir por consola todos los números comprendidos entre 10 y 55 (incluidos), pares,\n        y que no son ni el 16 ni múltiplos de 3.\n         */\n\n        System.out.println(\"Ejercicio extra\");\n        for (int i = 10; i <= 55; i++) {\n            if (i == 16 || i % 3 == 0) {\n                continue;\n            }\n            if (i % 2 == 0) {\n                System.out.print(i + \" \");\n            }\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/daeduol.java",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\npublic class Main {\n\n\n    public static void main(String[] args) {\n        int num1 = 73;\n        int num2 = 42;\n        double num3 = 9.0;\n        double nume4 = 7.0;\n        String var1 = \"coca \";\n        String var2 = \"- cola\";\n        boolean verdadero = true;\n        boolean falso = false;\n        int a = 73, b = 73, c = 3, d = 5;\n\n        /*\n        Operacioes aritméticos\n         */\n        // Concatenación de cadenas y/o suma \t+\n        System.out.println(num1 + num2);\n        System.out.println(var1 + var2);\n        // Resta\n        System.out.println(num1 - num2);\n        //División entera\n        System.out.println(num1 / num2);\n        // División real\n        System.out.println(num3 / nume4);\n        // Resto o residuo\n        System.out.println(num1 % num2);\n        // Potencia Math,pow(base, exponente)\n        System.out.println(Math.pow(num3, nume4));\n        // Incremento ++\n        System.out.println(\"42 incremento en 1 =\" + (++ num2));\n        // Decremento --\n        System.out.println(\"73 Decremento en 1 =\" + (-- num1));\n        /*\n        Operadores de Negación y Comparación\n        */\n        // Negación !\n        System.out.println(\"Negacion \" + (!verdadero));\n        // Igualdad ==\n        System.out.println(\"Igualdad, b igual que a \" + (b == a));\n        // Desigualdad \t!=\n        System.out.println(\"Desigualdad, 73 no es igual 74 \" + (a != num1));\n        // Mayor que \t>\n        System.out.println(\"73 mayor que 43 \" + (num1 > num2));\n        // Menor que \t<\n        System.out.println(\"43 menor que 73 \" + (num2 < num1));\n        // Mayor o igual que \t>=\n        System.out.println(\"73 mayor o igual que 73 \" + (a >= num1));\n        // Menor o igual que \t<=\n        System.out.println(\"73 menor o igual que 73 \" + (num1 <= b));\n        /*\n        Operadores Lógicos\n        */\n        // AND lógico \t&&\n        System.out.println(\"ambos son verdaderos?: \" + (verdadero && falso));\n        // OR lógico \t||\n        System.out.println(\"uno es verdader?: \" + (verdadero || falso));\n        /*\n        Operadores Bit a Bit\n        */\n        // AND bit a bit \t&\n        System.out.println(\"\\\"5 binario = 101, 3 binari0 = 011\\\"\");\n        System.out.println(\"Resultado: 001 (equivalente a 1 en decimal ) \" + (c & d));\n        // OR bit a bit \t|\n        System.out.println(\"Resultado: 111 (equivalente a 7 en decimal )\" + (c | d));\n        // XOR bit a bit \t^\n        System.out.println(\"Resultado: 110 (equivalente a 6 en decimal )\" + (c ^ d));\n        // Complemento bit a bit    ~\n        System.out.println(\"Complemento bit a bit: \" + (~c));\n        // Desplazamiento izquierdo     <<\n        System.out.println(\"Desplazamiento izquierdo: \" + (d << 1));\n        // Desplazamiento derecho    >>\n        System.out.println(\"Desplazamiento derecho: \" + (d >> 1));\n        // Desplazamiento sin signo \t>>>\n        System.out.println(\"Desplazamiento sin signo: \" + (c >>> 1));\n        /*\n        Operadores de Asignación\n         */\n        // Asignación    =\n        System.out.println(\"asignacion \" +(a = b));\n        // Asignación con suma\t +=\n        System.out.println(\"Asignación con suma: \" + (b += c));\n        // Asignación con resta  -=\n        System.out.println(\"Asignación con resta: \" + (a -= c));\n        // Asignación con multiplicación \t*=\n        System.out.println(\"Asignación con multiplicacion: \" + (a *= c));\n        // Asignación con división \t/=\n        System.out.println(\"Asignación con división: \" + (a /= c));\n        // Asignación con resto \t%=\n        System.out.println(\"Asignación con resto: \" + (a %= c));\n        // Asignación con desplazamiento izquierdo \t<<=\n        System.out.println(\"Asignación con desplazamiento izquierdo: \" + (a <<= c));\n        // Asignación con desplazamiento derecho \t>>=\n        System.out.println(\"Asignación con desplazamiento derecho: \" + (a >>= c));\n        // Asignación con desplazamiento sin signo \t>>>=\n        System.out.println(\"Asignación con desplazamiento sin signo: \" + (b >>>= c));\n        // Asignación con AND bit a bit \t&=\n        System.out.println(\"Asignación con AND bit a bit: \" + (a &= c));\n        // Asignación con OR bit a bit \t|=\n        System.out.println(\"Asignación con OR bit a bit: \" + (a |= c));\n        //    Asignación con XOR bit a bit \t^=\n        System.out.println(\"Asignación con XOR bit a bit: \" + (b ^= c));\n        /*\n        Otros Operadores\n         */\n        // Operador ternario \t? :\n        int valor = (a > b) ? a : b;\n        System.out.println(\"Operador ternario: \" + valor);\n        // Condicionales\n        int myInt1 = 5;\n        int myInt2 = 5;\n        int myInt3 = 4;\n        // if\n        if (myInt1 == myInt2) {\n            System.out.println(\"ok\");\n        }\n\n        //if-else\n        if (myInt1 == myInt3) {\n            System.out.println(\"ok\");\n        } else {\n            System.out.println(\"error\");\n        }\n        // if-else-if\n        if (myInt1 == myInt2) {\n            System.out.println(\"ok\");\n        } else {\n            System.out.println(\"error\");\n        }\n        if (myInt2 >= myInt3) {\n            System.out.println(\"es mayor\");\n        }\n        // switch\n        int opcion = 2;\n\n        switch (opcion) {\n            case 1:\n                System.out.println(\"Seleccionaste la opción 1\");\n                break;\n            case 2:\n                System.out.println(\"Seleccionaste la opción 2\");\n                break;\n            case 3:\n                System.out.println(\"Seleccionaste la opción 3\");\n                break;\n            default:\n                System.out.println(\"Opción no válida\");\n        }\n        // Iterativas\n\n        // for\n        for (int i = 0; i <= 10; i++) {\n            System.out.print(i);\n        }\n        int contador = 0;\n        while (contador < 6) {\n            System.out.println(\"numero \" + contador);\n            contador++;\n        }\n        // do while\n        do {\n            int num5 = 5;\n            num5++;\n            System.out.println(num5);\n            if (num5 >= 6) {\n                break;\n            }\n        } while (true);\n        // try catch\n        try {\n            int dividendo = 10;\n            int divisor = 0;\n\n            int resultado = dividendo / divisor;\n            System.out.println(\"Resultado de la división: \" + resultado);\n        } catch (ArithmeticException e) {\n            System.out.println(\"Error: División por cero no permitida. Mensaje de la excepción: \" + e.getMessage());\n\n        }\n        // try catch finally\n        try {\n            int di = 10;\n            int divis = 0;\n\n            int result = di / divis;\n            System.out.println(\"Resultado de la división: \" + result);\n        } catch (ArithmeticException e){\n            System.out.println(\"Error2: División por cero no permitida. Mensaje de la excepción: \" + e.getMessage());\n        }\n        finally {\n            System.out.println(\"java Dev\");\n        }\n\n    }\n        /*\n        reto extra\n         */\n        for (int i = 10; i <= 55; i++){\n            if (i % 2 == 0 && i != 16 && i % 3 != 0)\n                System.out.println(i);\n        }\n\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/danhingar.java",
    "content": "import java.util.ArrayList;\nimport java.util.List;\n\npublic class danhingar {\n\n    public static void main(String[] args) {\n\n        int numero1 = 2;\n        int numero2 = 6;\n        float numero3 = 8.5f;\n        byte numero4 = 3;\n\n        // OPERADORAS ARITMÉTICOS\n        int suma = numero1 + numero2;\n        System.out.println(\"Resultado suma: \" + suma);\n        int resta = numero4 - numero1;\n        System.out.println(\"Resultado resta: \" + resta);\n        float multiplicacion = numero3 * numero1;\n        System.out.println(\"Resultado multiplicacion: \" + multiplicacion);\n        double division = numero3 / numero1;\n        System.out.println(\"Resultado division: \" + division);\n        int divisionEntera = (int) (numero3 / numero1);\n        System.out.println(\"Resultado divisionEntera: \" + divisionEntera);\n        int modulo = numero2 % numero1;\n        System.out.println(\"Resultado modulo: \" + modulo);\n        double exponente = Math.pow(numero1, 2);\n        System.out.println(\"Resultado exponente: \" + exponente);\n\n        // OPERADORES COMPARACIÓN\n        boolean esIgual = numero1 == numero2;\n        System.out.println(\"Igualdad: \" + esIgual);\n        boolean noIgual = numero2 != numero3;\n        System.out.println(\"Desigualdad: \" + noIgual);\n        boolean mayorQue = numero1 > numero2;\n        System.out.println(\"Mayor que: \" + mayorQue);\n        boolean menorQue = numero2 < numero3;\n        System.out.println(\"Menor que: \" + menorQue);\n        boolean mayorIgualQue = numero4 >= numero1;\n        System.out.println(\"Mayor o igual que: \" + mayorIgualQue);\n        boolean menorIgualQue = numero2 <= numero1;\n        System.out.println(\"Menor o igual que: \" + menorIgualQue);\n\n        // OPERADORES LÓGICOS\n        boolean and = numero1 > numero2 && numero2 < numero3;\n        System.out.println(\"Operador &&: \" + and);\n        boolean or = numero1 > numero2 || numero2 < numero3;\n        System.out.println(\"Operador ||: \" + or);\n        boolean negacion = !or;\n        System.out.println(\"Negacion !: \" + negacion);\n\n        // OPERADORES DE ASIGNACIÓN\n        int myNumber = 10;\n        System.out.println(\"myNumber \" + myNumber);\n        myNumber += 3;\n        System.out.println(\"myNumber \" + myNumber);\n        myNumber -= 1;\n        System.out.println(\"myNumber \" + myNumber);\n        myNumber *= 4;\n        System.out.println(\"myNumber \" + myNumber);\n        myNumber /= 8;\n        System.out.println(\"myNumber \" + myNumber);\n        myNumber ^= 7;\n        System.out.println(\"myNumber \" + myNumber);\n        myNumber %= 1;\n        System.out.println(\"myNumber \" + myNumber);\n        myNumber >>= 1;\n        System.out.println(\"myNumber \" + myNumber);\n        myNumber <<= 1;\n        System.out.println(\"myNumber \" + myNumber);\n        myNumber |= 1;\n        System.out.println(\"myNumber \" + myNumber);\n        myNumber &= 1;\n        System.out.println(\"myNumber \" + myNumber);\n\n        // Condicionales\n        String nombre = \"Daniel\";\n        if (nombre == \"Daniel\") {\n            System.out.println(\"nombre es 'Daniel'\");\n        } else if (nombre == \"Pepe\") {\n            System.out.println(\"nombre es 'Pepe'\");\n        } else {\n            System.out.println(\"nombre es indefinido\");\n        }\n\n        switch (nombre) {\n            case \"Daniel\":\n                System.out.println(\"Hola Daniel\");\n                break;\n            case \"Pepe\":\n                System.out.println(\"Hola Pepe\");\n                break;\n            default:\n                System.out.println(\"Hola desconocido\");\n        }\n\n        String saludo = nombre.equals(\"Daniel\") ? \"Hola Daniel\" : \"Hola desconocido\";\n        System.out.println(saludo);\n\n        // Iterativas\n        for (int i = 0; i < 12; i++) {\n            System.out.println(i);\n        }\n\n        List<String> names = List.of(\"Daniel\", \"Paco\", \"Pepe\", \"Luis\");\n        // Itera todas una colección\n        for (String name : names) {\n            System.out.println(name);\n        }\n\n        while (numero2 > 1) {\n            System.out.println(numero2);\n            numero2--;\n        }\n\n        // Excepciones\n        try {\n            int divisionError = 10 / 0;\n        } catch (ArithmeticException e) {\n            System.out.println(\"Error aritmetico\");\n        } finally {\n            System.out.println(\"Finalizado el manejo de excepciones\");\n        }\n\n        // EJERCICIO EXTRA\n        for (int j = 10; j < 56; j++) {\n            if (j != 16 && j % 2 == 0 && j % 3 != 0) {\n                System.out.println(j);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/david-quinones.java",
    "content": "import java.sql.SQLException;\n\npublic class david-quinones {\n\n    public static void main(String[] args) {\n        david-quinones lopez = new david-quinones();\n        lopez.operadores();\n    }   \n\n    public void operadores() {\n        arithmetic();\n        assignment();\n        comparison();\n        logical();\n        terario();\n        bits();\n        condicionales();\n        iterativas();\n        excepciones();\n        // excepcionesTrows();\n        jumpStructure();\n        additionalExercice();\n    }\n\n    public void arithmetic() {\n        System.out.println(\"Suma 20 + 3: \" + (20 + 3));\n        System.out.println(\"Resta 20 - 3: \" + (20 - 3));\n        System.out.println(\"Multiplicacion 20 * 3: \" + (20 * 3));\n        System.out.println(\"Division 20 / 3: \" + (20 / 3));\n        System.out.println(\"Modulo 20 % 3: \" + (20 % 3));\n        System.out.println(\"Potencia 20 ^ 3: \" + (20 ^ 3));\n        int i = 1;\n        System.out.println(\"Incrementar i assignar variable i --> 2: \" + ++i);\n        System.out.println(\"Decrementar i assignar variable i --> 1: \" + --i);\n        int i2 = 20;\n        System.out.println(\"Assignar i incrementar variable i2 --> 20: \" + i2++);\n        System.out.println(\"Mostrar variable incrementada i2 --> 21: \" + i2);\n        System.out.println(\"Assignar i decremntar variable i2 --> 21: \" + i2--);\n        System.out.println(\"Mostrar variable decrementada i2 --> 20: \" + i2);\n    }\n\n    public void assignment() {\n        int i = 10; // asignacion\n        System.out.println(i);\n        i += 10; // suma y asignacion\n        System.out.println(i);\n        i -= 3; // resta y asignacion\n        System.out.println(i);\n        i *= 3; // multiplica y asignacion\n        System.out.println(i);\n        i /= 1; // divide y asigna\n        System.out.println(i);\n        i %= 5; // modulo y asignacion\n        System.out.println(i);\n        i ^= 2; // potencia y asignacion\n        System.out.println(i);\n    }\n\n    public void comparison() {\n        System.out.println(\"Igualdad 10 = 5? \" + (10 == 5));\n        System.out.println(\"Diferente 10 != 5? \" + (10 != 5));\n        System.out.println(\"Mas grande 10 > 5? \" + (10 > 5));\n        System.out.println(\"Mas pequeño 10 < 5? \" + (10 < 5));\n        System.out.println(\"Igual o mas grande 10 >= 5? \" + (10 >= 5));\n        System.out.println(\"Igual o mas pequeño 10 <= 5? \" + (10 <= 5));\n    }\n\n    public void logical() {\n        System.out.println(\"AND && 5==5 && 6<10:\" + (5 == 5 && 6 < 10));\n        System.out.println(\"OR || 5==1 && 6<10:\" + (5 == 1 || 6 < 10));\n        System.out.println(\"NOT ! !false\" + (!false));\n    }\n\n    public void terario() {\n        System.out.println(\"Operador ternario--> 1 = 1\" + (1 == 1 ? \"si es igual\" : \"no es diferente\"));\n    }\n\n    public void bits() {\n        int a = 5;\n        int b = 10;\n        System.out.println(\"Operador AND &: \" + (a & b));\n        System.out.println(\"Operador OR |: \" + (a | b));\n        System.out.println(\"Operador XOR ^: \" + (a ^ b));\n        System.out.println(\"Desplazamiento izquierda <<: \" + (a << b));\n        System.out.println(\"Desplazamiento derecha >>: \" + (a >> b));\n    }\n\n    /*\n     * \n     * Estructuras de control\n     * \n     * \n     */\n\n    public void condicionales() {\n        int david = 9;\n\n        if (david == 11) {\n            System.out.println(\"Entro el el If\" + david);\n        } else if (david == 12) {\n            System.out.println(\"Entro en el Else If\" + david);\n        } else {\n            System.out.println(\"Entro en el Else\" + david);\n        }\n\n        // swith de toda la vida\n        switch (david) {\n            case 5:\n                break;\n            case 17:\n                break;\n            case 10: // no puede tener multiples casos\n                System.out.println(\"Entro en el caso\" + david);\n                break; // para que pare y no siga\n            default:\n                System.out.println(\"Entro en el caso default, el valor es:\" + david);\n                break;\n        }\n\n        // switch Expressivo (Java 14) IDentico pero sin break -> se ejecuta el\n        // siguiente\n        switch (david) {\n            case 5 -> System.out.println(\"Entro en el caso \" + david);\n            case 17, 9 -> System.out.println(\"Entro en el caso 17 o 9 \" + david);\n            case 10 -> System.out.println(\"Entro en el caso \" + david);\n            default -> System.out.println(\"Entro en el default \" + david);\n        }\n\n        // switch expressions (Podemos assignar el resultado a una variable)\n        String result = switch (david) {\n            case 5 -> \"Entro en el caso \" + david;\n            case 17, 9 -> \"Entro en el caso 17, 9 \" + david;\n            case 10 -> \"Entro en el caso \" + david;\n            default -> \"Entro en el default \" + david;\n        };\n\n        System.out.println(\"Result: \" + result);\n\n        // Podemos usar bloque de codigo\n        switch (david) {\n            case 1 -> {\n                //\n                // yield 1; --> esto es para devolver el resultado a case (si feura a una\n                // variable)\n            }\n            default -> {\n            }\n        }\n\n    }\n\n    public void iterativas() {\n        // for\n        for (int i = 0; i < 10; i++) {\n            System.out.println(\"For: \" + i);\n        }\n\n        // for each\n        for (String name : new String[] { \"David\", \"Quinones\" }) {\n            System.out.println(\"palabras con forEach: \" + name);\n        }\n\n        // while\n        int i = 0;\n        while (i < 10) { // comprueba la condicion y luego ejecuta el codigo\n            System.out.println(\"While point: \" + i);\n            i++;\n        }\n\n        // do while\n        int j = 0;\n        do { // ejecutor el codigo en primer lugar y luego comprueba la condicion\n            System.out.println(\"Do While point: \" + j);\n            j++;\n        } while (j < 10); // si es true vuelve a ejecutar el codigo\n\n    }\n\n    public void excepciones() {\n        // try catch\n        try {\n            // realiza codigo, si algo sale mal como por ejemplo dividir entre zero,\n            // la aplicacion no finalizarà capturarà el error y lo mandara al catch,\n            // siguiendo su ejecucion\n        } catch (Exception e) {\n            System.out.println(e.getCause());\n        } finally {\n            // siempre se ejecutarà tanto si captura un error como si funciona todo ok\n        }\n\n        // podemos hacer lanzar una excepcion si nos interesa\n        try {\n            throw new SQLException(\"Message de error en excepcion lanzada\");\n        } catch (Exception e) {\n            System.out.println(\"Error capturado: \" + e.getMessage());\n        }\n    }\n\n    // declaramos un metodo e indicamos que puede lanzar una excepcion del tipos\n    // mencionado\n    public void excepcionesTrows() throws Exception {\n        // quin llame este metodo tiene que manejar esta excepcion, ya sea con try_catch\n        // o declarandose con throws (eccpecion)\n    }\n\n    // controles utilizados en todo lo anterior (continue, break, return)\n    /* estructura de saltos */\n    public void jumpStructure(){\n        //break\n        for(int i = 0; i < 5; i++){\n            if(i == 3){\n                break; // controlaremos si i = 3, si se cumple salimos del bucle for\n            }\n            System.out.println(i);\n        }\n\n        // continue\n        for (int i = 0; i < 5 ; i++) {\n            if(i == 3) {\n                continue; // Si i = 3, saltmos a la sigiente iteracion sin seguir con nada que siga dentro del for\n            }\n            System.out.println(i);\n        }\n\n        // return \n        System.out.println(returnMetodo(0));\n    }\n\n    public int returnMetodo(int numero){\n        if(numero == 3){\n            return numero; //si es igual, retorno numero\n        }\n        return -1; // sino quadra, retorna valor \n    }\n\n    public void additionalExercice(){\n        /* ADDICIONAL */\n        for(int i = 10; i < 56; i++){\n            if(i == 16 || i % 2 != 0 || i % 3 == 0){ \n\n                continue;\n            }\n            System.out.println(i);\n        }\n\n    }\n\n\n\n\n\n\n\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/davidSorroche.java",
    "content": "import java.util.Optional;\n\npublic class OperadoresEstructurasDeControl {\n    public final int CINCO = 5;\n    public final String JAVA = \"Java\";\n    \n    /*  Métodos para cálculos de operadores aritméticos:\n            - Suma (+).\n            - Resta (-).\n            - Multiplicación (*).\n            - División (/).\n            - Módulo (%).\n    */\n    \n    public int suma(int num1, int num2) {\n        return num1 + num2;\n    }\n    \n    public int resta(int num1, int num2) {\n        return num1 - num2;\n    }\n    \n    public int multiplicacion(int num1, int num2) {\n        return num1 * num2;\n    }\n    \n    public Optional<Double> division(int num1, int num2) { \n        if(num2 == 0) {\n            return Optional.empty();\n        }\n        return Optional.of((double) num1 / num2);\n    }\n    \n    public Optional<Integer> divisionEntera(int num1, int num2) {\n        if(num2 == 0) {\n            return Optional.empty();\n        }\n        return Optional.of(num1 / num2);\n    }\n    \n    public Optional<Integer> modulo(int num1, int num2) {\n        if(num2 == 0) {\n            return Optional.empty();\n        }\n        return Optional.of(num1 % num2);\n    }\n    \n    /*  Métodos para cálculos usando operadores unarios.\n            - Más Unario (+).\n            - Menos Unario (-).\n            - Incremento (++). * Corrección posterior y corrección anterior.\n            - Decremento (--). * Corrección posterior y corrección anterior.\n            - Complemento Lógico (!).\n    */\n    \n    public int masUnario(int num) {\n        return + num;\n    }\n    \n    public int menosUnario(int num) {\n        return - num;\n    }\n    \n    public int incrementoPosterior(int num) {\n        return num++;\n    }\n    \n    public int incrementoAnterior(int num) {\n        return ++num;\n    }\n\n    public int decrementoPosterior(int num) {\n        return num--;\n    }\n    \n    public int decrementoAnterior(int num) {\n        return --num;\n    }\n    \n    public boolean complementoLogico(boolean booleano) {\n        return !booleano;\n    }\n    \n    /*  Métodos para usos de las unidades de asignación.\n            - Asignación (=)\n            - Suma y Asignación (+=)\n            - Resta y Asignación (-=)\n            - Multiplicación y Asignación (*=)\n            - División y Asignación (/=)\n            - Módulo y Asignación (%=)\n    */\n    \n    public Object asignacion(Object valor) {     \n        Optional<Object> nuevoValor = Optional.ofNullable(valor);        \n        return nuevoValor.isPresent() ? nuevoValor : \"Lo siento, no has introducido ningún valor para asignárselo a la variable \\\"nuevoValor\\\"\";\n    }\n    \n    public int sumaAsignacion(int num1, int num2) {\n        return num1 += num2;    \n    }\n    \n    public String anadidoAsignacion(String cad1, String cad2) {\n        return cad1 += cad2;\n    }\n    \n    public int restaAsignacion(int num1, int num2) {\n        return num1 -= num2;\n    }\n    \n    public int multiplicacionAsignacion(int num1, int num2) {\n        return num1 *= num2;\n    }\n    \n    public double divisionAsignacion(int num1, int num2) {\n        return num1 /= (double)num2;\n    }\n    \n    public int divisionAsignacionEntera(int num1, int num2) {\n        return num1 /= num2;\n    }\n    \n    public int moduloAsignacion(int num1, int num2) {\n        return num1 %= num2;\n    }\n    \n    /*  Métodos para usos de operadores relacionales.\n            - Igual a (==).\n            - Distinto a(!=).\n            - Mayor que (>).\n            - Mayor o igual que (>=).\n            - Menor que (<).\n            - Menor o igual que (<=).\n    */\n    \n    public boolean igualdad (Object valor1, Object valor2) {\n        return valor1 == valor2;\n    }\n    \n    public boolean desigualdad(Object valor1, Object valor2) {\n        return valor1 != valor2;\n    }\n    \n    public boolean mayor(int num1, int num2) {\n        return num1 > num2;\n    }\n    \n    public boolean mayorIgual(int num1, int num2) {\n        return num1 >= num2;\n    }\n    \n    public boolean menor(int num1, int num2) {\n        return num1 < num2;\n    }\n    \n    public boolean menorIgual(int num1, int num2) {\n        return num1 <= num2;\n    }\n    \n    /*  Métodos para usos de operadores condicionales.\n            - condicional AND (&&).\n            - condicional OR (||).\n            - ternario(?:).\n    */\n    \n    public boolean and (int num1, int num2) {\n        return num1 == this.CINCO && num2 == this.CINCO;\n    }\n    \n    public boolean or (String cad1, String cad2) {\n        return cad1.equalsIgnoreCase(this.JAVA) || cad2.equalsIgnoreCase(this.JAVA);\n    }\n    \n    public String ternario(String lenguaje) {\n        return lenguaje.equalsIgnoreCase(this.JAVA) ? \"Estás estudiando lenguaje \".concat(JAVA) : \"No estás estudiando el lenguaje\".concat(lenguaje);\n    }\n    \n    /*  Métodos para usos de operadores de bits en números enteros.\n            - desplazamiento izquierda (<<).\n            - desplazamiento derecha (>>).\n            - invertir (~).\n            - operacion AND (&).\n            - operación OR exclusivo (^).\n            - operación OR inclusivo (|).\n    */\n    \n    public int desplazamientoIzquierda (int num, int pos) {\n        return num << pos;\n    }\n    \n    public int desplazamientoDerecha (int num, int pos) {\n        return num >> pos;\n    }\n    \n    public int inversion (int num) {\n        return ~ num;\n    }\n    \n    public int operadorAND (int num1, int num2) {\n        return num1 & num2;\n    }\n    \n    public int operadorORExclusivo (int num1, int num2) {\n        return num1 ^ num2;\n    }\n    \n    public int operadorORInclusivo (int num1, int num2) {\n        return num1 | num2;\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/deathwing696.java",
    "content": "/*\n * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license\n * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template\n */\n\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n/**\n *\n * @author death\n */\n\npublic class deathwing696 {\n    public static void main(String[] args)\n    {\n        for(int i = 10; i <= 55; i++)\n        {\n            if(i % 2 == 0 && i != 16)\n            {\n                if (i % 3 != 0)\n                {\n                    System.out.println(i);\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/eulogioep.java",
    "content": "public class eulogioep {\n    public static void main(String[] args) {\n        // Ejemplos de operadores en Java\n\n        // 1. Operadores Aritméticos\n        System.out.println(\"--- Operadores Aritméticos ---\");\n        System.out.println(\"Suma: 5 + 3 = \" + (5 + 3));\n        System.out.println(\"Resta: 10 - 4 = \" + (10 - 4));\n        System.out.println(\"Multiplicación: 6 * 2 = \" + (6 * 2));\n        System.out.println(\"División: 15 / 3 = \" + (15 / 3));\n        System.out.println(\"Módulo: 17 % 5 = \" + (17 % 5));\n        System.out.println(\"Incremento: int a = 5; a++; a = \" + (new Object() { int run() { int a = 5; a++; return a; }}.run()));\n        System.out.println(\"Decremento: int b = 8; b--; b = \" + (new Object() { int run() { int b = 8; b--; return b; }}.run()));\n\n        // 2. Operadores de Asignación\n        System.out.println(\"\\n--- Operadores de Asignación ---\");\n        int x = 10;\n        System.out.println(\"Asignación simple: x = 10; \" + x);\n        x += 5;\n        System.out.println(\"Suma y asignación: x += 5; \" + x);\n        x *= 2;\n        System.out.println(\"Multiplicación y asignación: x *= 2; \" + x);\n\n        // 3. Operadores de Comparación\n        System.out.println(\"\\n--- Operadores de Comparación ---\");\n        System.out.println(\"Igualdad: 5 == 5 es \" + (5 == 5));\n        System.out.println(\"Desigualdad: 5 != 6 es \" + (5 != 6));\n        System.out.println(\"Mayor que: 7 > 5 es \" + (7 > 5));\n        System.out.println(\"Menor o igual que: 10 <= 10 es \" + (10 <= 10));\n\n        // 4. Operadores Lógicos\n        System.out.println(\"\\n--- Operadores Lógicos ---\");\n        System.out.println(\"AND lógico: true && false es \" + (true && false));\n        System.out.println(\"OR lógico: true || false es \" + (true || false));\n        System.out.println(\"NOT lógico: !true es \" + (!true));\n\n        // 5. Operadores de Tipo\n        System.out.println(\"\\n--- Operadores de Tipo ---\");\n        System.out.println(\"instanceof: \\\"\\\" instanceof String es \" + (\"\" instanceof String));\n\n        // 6. Operadores de Bits\n        System.out.println(\"\\n--- Operadores de Bits ---\");\n        System.out.println(\"AND a nivel de bits: 5 & 3 = \" + (5 & 3));\n        System.out.println(\"OR a nivel de bits: 5 | 3 = \" + (5 | 3));\n        System.out.println(\"XOR a nivel de bits: 5 ^ 3 = \" + (5 ^ 3));\n        System.out.println(\"Desplazamiento a la izquierda: 5 << 1 = \" + (5 << 1));\n\n        // Ejemplos de estructuras de control\n\n        // 1. Estructura Condicional: if-else\n        System.out.println(\"\\n--- Estructura Condicional: if-else ---\");\n        int numero = 15;\n        if (numero > 10) {\n            System.out.println(\"El número es mayor que 10\");\n        } else if (numero < 10) {\n            System.out.println(\"El número es menor que 10\");\n        } else {\n            System.out.println(\"El número es igual a 10\");\n        }\n\n        // 2. Estructura Condicional: switch\n        System.out.println(\"\\n--- Estructura Condicional: switch ---\");\n        String dia = \"Lunes\";\n        switch (dia) {\n            case \"Lunes\":\n                System.out.println(\"Hoy es Lunes\");\n                break;\n            case \"Martes\":\n                System.out.println(\"Hoy es Martes\");\n                break;\n            default:\n                System.out.println(\"Es otro día de la semana\");\n        }\n\n        // 3. Estructura Iterativa: for\n        System.out.println(\"\\n--- Estructura Iterativa: for ---\");\n        for (int i = 0; i < 5; i++) {\n            System.out.println(\"Iteración for: \" + i);\n        }\n\n        // 4. Estructura Iterativa: while\n        System.out.println(\"\\n--- Estructura Iterativa: while ---\");\n        int contador = 0;\n        while (contador < 3) {\n            System.out.println(\"Iteración while: \" + contador);\n            contador++;\n        }\n\n        // 5. Estructura Iterativa: do-while\n        System.out.println(\"\\n--- Estructura Iterativa: do-while ---\");\n        int j = 0;\n        do {\n            System.out.println(\"Iteración do-while: \" + j);\n            j++;\n        } while (j < 3);\n\n        // 6. Manejo de Excepciones: try-catch\n        System.out.println(\"\\n--- Manejo de Excepciones: try-catch ---\");\n        try {\n            throw new Exception(\"Este es un error de ejemplo\");\n        } catch (Exception e) {\n            System.out.println(\"Error capturado: \" + e.getMessage());\n        } finally {\n            System.out.println(\"Este bloque siempre se ejecuta\");\n        }\n\n        // DIFICULTAD EXTRA\n        System.out.println(\"\\n--- DIFICULTAD EXTRA ---\");\n        for (int num = 10; num <= 55; num++) {\n            if (num % 2 == 0 && num != 16 && num % 3 != 0) {\n                System.out.println(num);\n            }\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/francescvm8.java",
    "content": "public class francescvm8 {\n    public static void main(String[] args) {\n        int a=10,b=5;\n        // Operadores aritméticos\n        System.out.println(\"Operadores aritméticos\");\n        System.out.println(\"Suma: \"+(a+b)); \n        System.out.println(\"Resta: \"+(a-b));\n        System.out.println(\"Multiplicación: \"+(a*b));\n        System.out.println(\"División: \"+(a/b)); \n        System.out.println(\"Módulo: \"+(a%b));\n        System.out.println(\"Incremento: \"+(++a));\n        System.out.println(\"Decremento: \"+(--b));\n        System.out.println(\"Negación: \"+(-a));\n        System.out.println(\"Complemento a 1: \"+(~a));\n        System.out.println(\"Desplazamiento a la izquierda: \"+(a<<1));\n        System.out.println(\"Desplazamiento a la derecha: \"+(a>>1));\n        System.out.println(\"Desplazamiento a la derecha sin signo: \"+(a>>>1));\n        System.out.println(\"AND: \"+(a&b));\n        System.out.println(\"OR: \"+(a|b));\n        System.out.println(\"XOR: \"+(a^b));\n\n        // Operadores de comparación\n        System.out.println(\"\\nOperadores de comparación\");\n        System.out.println(\"Igualdad: \"+(a==b));\n        System.out.println(\"Desigualdad: \"+(a!=b));\n        System.out.println(\"Mayor que: \"+(a>b));\n        System.out.println(\"Menor que: \"+(a<b));\n        System.out.println(\"Mayor o igual que: \"+(a>=b));\n        System.out.println(\"Menor o igual que: \"+(a<=b));\n\n        // Operadores lógicos\n        System.out.println(\"\\nOperadores lógicos\");\n        System.out.println(\"AND lógico: \"+(a>b && a<b));\n        System.out.println(\"OR lógico: \"+(a>b || a<b));\n        System.out.println(\"NOT lógico: \"+!(a>b));\n\n        // Operadores de asignación\n        System.out.println(\"\\nOperadores de asignación\");\n        System.out.println(\"Asignación: \"+(a=b));\n        System.out.println(\"Suma y asignación: \"+(a+=b));\n        System.out.println(\"Resta y asignación: \"+(a-=b));\n        System.out.println(\"Multiplicación y asignación: \"+(a*=b));\n        System.out.println(\"División y asignación: \"+(a/=b));\n        System.out.println(\"Módulo y asignación: \"+(a%=b));\n        System.out.println(\"Desplazamiento a la izquierda y asignación: \"+(a<<=b));\n        System.out.println(\"Desplazamiento a la derecha y asignación: \"+(a>>=b));\n        System.out.println(\"Desplazamiento a la derecha sin signo y asignación: \"+(a>>>=b));\n        System.out.println(\"AND y asignación: \"+(a&=b));\n        System.out.println(\"OR y asignación: \"+(a|=b));\n        System.out.println(\"XOR y asignación: \"+(a^=b));\n\n        // Operadores de identidad\n        System.out.println(\"\\nOperadores de identidad\");\n        System.out.println(\"Igualdad de objetos: \"+(a==b));\n        System.out.println(\"Desigualdad de objetos: \"+(a!=b));\n\n        // Operadores de pertenencia\n        System.out.println(\"\\nOperadores de pertenencia\");\n        System.out.println(\"Pertenece: \"+(a instanceof Integer));\n        \n        // Estructuras de control\n        System.out.println(\"\\nEstructuras de control\");\n        \n        // Condicionales\n        if(a>b) {\n            System.out.println(\"a es mayor que b\");\n        } else {\n            System.out.println(\"a es menor que b\");\n        }\n        \n        // Iterativas\n        for(int i=0;i<5;i++) {\n            System.out.println(\"Iteración \"+i);\n        }\n\n        // Excepciones\n        try {\n            int c = a/0;\n        } catch(ArithmeticException e) {\n            System.out.println(\"No se puede dividir por 0\");\n        }\n        \n        // Números entre 10 y 55, pares y no múltiplos de 3 ni 16\n        System.out.println(\"\\nNúmeros entre 10 y 55, pares y no múltiplos de 3 ni 16\");\n        for(int i=10;i<=55;i++) {\n            if(i%2==0 && i!=16 && i%3!=0) {\n                System.out.println(i);\n            }\n            \n        }\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/h4ckxel.java",
    "content": "/** #01 - Java -> h4ckxel */\n\npublic class h4ckxel {\n    public static void main(String[] args) {\n    System.out.println(\"---EJERCIÓ---\\n\");\n        /*\n         * ARITMÉTICAS\n         * Se utilizan para realizar cálculos matemáticos.\n         */\n\n        int a = 10;\n        int b = 5;\n\n        System.out.println(\"---Operaciones Aritméticas---\\n\");\n\n        System.out.println(\"a:\" + a);\n        System.out.println(\"b:\" + b);\n        System.out.println(\"\\nSuma: a + b = \" + (a + b)); // Suma\n        System.out.println(\"Resta: a - b = \" + (a - b)); // Resta\n        System.out.println(\"Multiplicar: a * b = \" + (a * b)); // Multiplicar\n        System.out.println(\"Exponente a ^ b\" + (a ^ b));\n        System.out.println(\"Division: a / b = \" + (a / b)); // Division\n        System.out.println(\"Modulo: a % b =\" + (a % b)); // Modulo\n\n        /*\n         * ASIGNACIONES\n         * Se utilizan para asignar valores a las variables.\n         */\n\n        System.out.println(\"\\n---Operaciones Asignación---\\n\");\n        \n        int c = 10; // Asignación simple\n        c += 5; // Suma y asigna\n        c -= 3; // Resta y asigna\n        c *= 2; // Multiplica y asigna\n        c /= 4; // Divide y asigna\n        c %= 3; // Calcula el modulo y asigna\n        System.err.println(\"Asignación simple: c = 5 - 10\");\n        System.err.println(\"Suma y asigna: c += 5 - 15\");\n        System.err.println(\"Suma y asigna: c -= 3 - 12\");\n        System.err.println(\"Suma y asigna: c *= 2 - 24\");\n        System.err.println(\"Suma y asigna: c /= 4 - 6\");\n        System.err.println(\"Suma y asigna: c %= 3 - 0\");\n        System.out.println(\"Resultado de Agnación: \" + c);\n\n        /*\n         * RELACIONALES\n         * Se utilizan para comparar dos valores.\n         */\n\n        System.out.println(\"\\n---Operaciones Relacional---\\n\");\n\n        int x = 10;\n        int y = 20;\n\n        System.out.println(\"Es Igual: x == y - \" + (x == y));\n        System.out.println(\"Es Diferente: x != y - \" + (x != y));\n        System.out.println(\"Es Mayor: x > y - \" + (x > y));\n        System.out.println(\"Es Menor: x < y - \" + (x < y));\n        System.out.println(\"Es Mayor o Igual: x >= y - \" + (x >= y));\n        System.out.println(\"Es Menor o Igual: x <= y - \" + (x <= y));\n\n        /*\n         * LÓGICOS\n         * Se utilizan para combinar expresiones booleanas.\n         */\n\n        System.out.println(\"\\n---Operaciones Lógicos---\\n\");\n\n        boolean i = true;\n        boolean k = false;\n\n        System.out.println(\"Operador i && k: \" + (i && k));\n        System.out.println(\"Operador i || k: \" + (i || k));\n        System.out.println(\"Operador !k: \" + (!k));\n\n        /*\n         * UNARIAS\n         * Se aplican a un solo operando.\n         */\n\n        System.out.println(\"\\n---Operaciones Unarias---\\n\");\n        \n        int d = 5;\n        System.out.println(\"Incremento: \" + d++);\n        System.out.println(\"Decremento: \" + d--);\n        System.out.println(\"Negativo: \" + (-d));\n        System.out.println(\"Positivo: \" + (+d));\n\n        /*\n         * BIT A BIT\n         * Se utilizan para realizar operaciones a nivel de bits.\n         */\n\n        System.out.println(\"\\n---Operaciones Unarias---\\n\");\n\n        int e = 6;\n        int f = 3;\n        System.out.println(\"AND bir a bit: e & f - \" + (e & f));\n        System.out.println(\"OR bir a bit: e | f - \" + (e | f));\n        System.out.println(\"XOR bir a bit: e ^ f - \" + (e ^ f));\n        System.out.println(\"Complemento bir a bit: ~e - \" + (~e));\n        System.out.println(\"Desplazamiento a la izquierda: e << f - \" + (e << f));\n        System.out.println(\"Desplazamiento a la derecha: e >> f - \" + (e >> f));\n        System.out.println(\"Desplazamiento a la derecha sin singo: e >>> f - \" + (e >>> f));\n\n        \n    /*\n    * Estructuras de controles\n    */\n\n        /*\n         * IF - ELSE If - ELSE\n         */\n        System.out.println(\"\\n---Estructuras de controles---\\n\");\n\n        System.out.println(\"\\nSentiría IF-ELSE IF-ELSE\");\n        int num = 10;\n        if (num > 0) {\n            System.out.println(\"El número es Positivo\");\n        } else if (num < 0) {\n            System.out.println(\"El número es Negativo\");\n        } else {\n            System.out.println(\"El número es Cero\");\n        }\n        \n        /*\n         * SWITCH\n         */\n        System.out.println(\"\\nSentiría SWITCH\");\n        int day = 3;\n        switch (day) {\n            case 1:\n                System.out.println(\"Lunes\");\n                break;\n            case 2:\n                System.out.println(\"Martes\");\n                break;\n            case 3:\n                System.out.println(\"Miércoles\");\n                break;\n            default:\n                System.out.println(\"Otro dia\");\n                break;\n        }\n\n        /*\n         * FOR\n         */\n        System.out.println(\"\\nBucle FOR\");\n        for (int j = 0; j < 5; j++) {\n            System.out.println(\"Iteración: \" + j);\n        }\n\n        /*\n         * WHILE\n         */\n        System.out.println(\"\\nBucle WHILE\");\n        int g = 0;\n        while (g < 5) {\n            System.out.println(\"Iteración: \" + g);\n            g++;\n        }\n\n        /*\n         * DO-WHILE\n         */\n        System.out.println(\"\\nBucle DO-WHILE\");\n        int l = 0;\n        do {\n            System.out.println(\"Iteración: \" + l);\n            l++;\n        } while (l < 5);\n\n        /*\n         * TRY-CATCH-FINALLY\n         */\n        System.out.println(\"\\nBucle TRY-CATCH-FINALLY\");\n        try {\n            int division = 10 / 0;\n            System.out.println(division);\n        } catch (ArithmeticException error) {\n            System.out.println(\"Error: Division por cero\");\n        } finally{\n            System.out.println(\"Este bloque se ejecuta siempre\");\n        }\n\n    /**-----DIFICULTAD EXTRA-----*/\n\n        System.out.println(\"\\n-----EXTRA-----\\n\");\n\n        for(int m = 10; m < 55; m++){\n            if ((m % 2 == 0) && (m != 16) && (m % 3 == 0)) {\n                System.out.println(m);\n            }\n        }\n\n    /**-----DIFICULTAD EXTRA-----*/\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/inmortalnight.java",
    "content": "//#01 - Java\n\npublic class inmortalnight {\n    public static void main(String[] args) {\n        int num1 = 0;\n        int num2 = 1;\n        //Operadores\n        //Aritmeticos\n        int suma = num1 + num2;  \n        System.out.println(num1 + \"+\" + num2 + \"=\" + suma);\n        int resta = num1 - num2;  \n        System.out.println(num1 + \"-\" + num2 + \"=\" + resta);\n        int multiplicacion = num1 * num2;  \n        System.out.println(num1 + \"*\" + num2 + \"=\" + multiplicacion);\n        int division = num1 / num2;  \n        System.out.println(num1 + \"/\" + num2 + \"=\" + division);\n\n        //Logico\n        boolean and = num1 > 0 && num2 > 0; //AND\n        System.out.println(num1 + \" y \" + num2 + \" son mayores que 0? \" + and);\n        boolean or = num1 > 0 || num2 > 0; //OR\n        System.out.println(num1 + \" o \" + num2 + \" son mayores que 0? \" + or);\n        boolean not = !(num1 > 0); //NOT\n        System.out.println(num1 + \" no es mayor que 0? \" + not);\n\n        //Comparacion\n        boolean igual = num1 == num2;\n        System.out.println(num1 + \" y \" + num2 + \" son iguales? \" + igual);\n        boolean diferente = num1 != num2;\n        System.out.println(num1 + \" y \" + num2 + \" son diferentes? \" + diferente);\n        boolean mayor = num1 > num2;\n        System.out.println(num1 + \" es mayor que \" + num2 + \"? \" + mayor);\n        boolean menor = num1 < num2;\n        System.out.println(num1 + \" es menor que \" + num2 + \"? \" + menor);\n        boolean mayorIgual = num1 >= num2;\n        System.out.println(num1 + \" es mayor o igual que \" + num2 + \"? \" + mayorIgual);\n        boolean menorIgual = num1 <= num2;\n        System.out.println(num1 + \" es menor o igual que \" + num2 + \"? \" + menorIgual);\n\n        //Asignacion\n        num1 += num2; //num1 = num1 + num2\n        System.out.println(\"Nuevo valor de num1 al sumar num2 es \" + num1);\n        num1 -= num2;\n        System.out.println(\"Nuevo valor de num1 al restar num2 es \" + num1);\n        num1 *= num2;\n        System.out.println(\"Nuevo valor de num1 al multiplicar num2 es \" + num1);\n        num1 /= num2;\n        System.out.println(\"Nuevo valor de num1 al dividir num2 es \" + num1);\n        num1 %= num2;\n        System.out.println(\"Nuevo valor de num1 al sacar el modulo de num2 es \" + num1);\n        \n        //Bits\n        int a = 60; //60 = 0011 1100\n        int b = 13; //13 = 0000 1101\n        int c = 0;\n        c = a & b; //12 = 0000 1100, escoge los bits que son 1 en ambos numeros\n        System.out.println(\"a & b = \" + c);\n        c = a | b; //61 = 0011 1101, escoge los bits que son 1 en alguno de los dos numeros\n        System.out.println(\"a | b = \" + c);\n        c = a ^ b; //49 = 0011 0001, escoge los bits que son 1 en uno de los dos numeros, pero no en ambos\n        System.out.println(\"a ^ b = \" + c);\n        c = ~a; //-61 = 1100 0011, invierte los bits\n        System.out.println(\"~a = \" + c);\n        c = a << 2; //240 = 1111 0000, desplaza los bits a la izquierda\n        System.out.println(\"a << 2 = \" + c);\n        c = a >> 2; //15 = 0000 1111, desplaza los bits a la derecha\n        System.out.println(\"a >> 2 = \" + c);\n        \n        //Estructuras de control\n        //Condicional para elegir entre dos opciones\n        if (num1 > num2) { \n            System.out.println(\"num1 is greater than num2\");\n        } else if (num1 < num2) {\n            System.out.println(\"num1 is less than num2\");\n        } else {\n            System.out.println(\"num1 is equal to num2\");\n        }\n        //Iterativa que imprime los numeros del 1 al 10\n        for (int i = 1; i < 11; i++) { \n            System.out.println(i);\n        }\n        //Excepcion que imprime un mensaje si se produce un error\n        try {\n            int[] myNumbers = {1, 2, 3};\n            System.out.println(myNumbers[3]);\n        } catch (Exception e) {\n            System.out.println(\"Ocurrio un error\");\n        }\n        //Extra: imprimir números del 10 al 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n        for(int i = 10; i <= 55; i++){\n            if(i != 16 && i % 2 == 0 && i % 3 != 0){\n                System.out.println(i);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/jcrodmir.java",
    "content": "\npublic class Main {\n    public static void main(String[] args) {\n        //Assignment\n\n        System.out.println(\"***** Simple Assigment Operatos/Einfacher Zuweisungsoperator ***** \\n\");\n        int speed=50;\n        speed +=5; //55\n        System.out.println(speed);\n        speed -=5; //50\n        System.out.println(speed);\n        speed *=3; //150\n        System.out.println(speed);\n        speed /=3; //50\n        System.out.println(speed);\n        speed %= 4; // 0 modulo\n        System.out.println(speed + \"\\n\");\n\n        //Bits\n\n        int comparation1= 5;\n        int comparation2=3;\n        System.out.println(\"***** Bits Assigment Operatos /Bits-Zuweisungsoperator***** \\n\");\n        comparation1 &= comparation2;//AND Binary operation 0101 and 0011 is equals 0001 ->1\n        System.out.println(comparation1);\n        comparation1 ^= comparation2; //XOR Binary operation 0001 ,0011 is equals 0010 -> 2\n        System.out.println(comparation1);\n        comparation1 |= comparation2; //OR Binary operation 0010 ,0011 is equals 0011 -> 3\n        System.out.println(comparation1);\n        comparation1 <<= 1; //move left with sign  Binary operation 0011 ,1 is equals 0110 -> 6\n        System.out.println(comparation1);\n        comparation1 >>= 1; //move right with sign Binary operation 0110 ,1 is equals 0011 -> 3\n        System.out.println(comparation1);\n        comparation1 >>>= 1; //move right without sign change the last 1  for a 0 Binary operation 0011 ,1 is equals 0001 -> 1\n        System.out.println(comparation1 + \"\\n\");\n\n        //Arithmetic\n        int number1=8;\n        int number2=2;\n        int result=0;\n        System.out.println(\"***** Aritmetics Operatos/Aritmetischer Operatoren\\n ****\\n\");\n        result= number1 + number2;\n        System.out.println(result);\n        result= number1 - number2;\n        System.out.println(result);\n        result= number1 * number2;\n        System.out.println(result);\n        result= number1 / number2;\n        System.out.println(result);\n        result= number1 % number2;\n        System.out.println(result);\n        result= number1 + number2;\n        System.out.println(result + \"\\n\");\n\n        //Unary\n        int unary=8;\n        System.out.println(\"***** Unary Operator/\\n\" +\n                \"Unärer Operatoren ****\\n\");\n        System.out.println(++unary);//plus one\n        System.out.println(--unary);//minus one\n        System.out.println(-unary);//transform negative number\n        System.out.println(+unary);//transform positive number\n        System.out.println(~unary);//transform all binary numbers 1 <-> 0 in 32 bits for that 8 is -9\n        System.out.println(!(unary==8) + \"\\n\");//only with boolean you became the opposite\n        //Equality\n        System.out.println(\"***** Equality Operatos/Gleichheitsoperatoren ****\\n\");\n        int equal1=1;\n        int equal2=2;\n        System.out.println(equal1==equal2);//False\n        System.out.println(equal1!=equal2);//True\n        System.out.println(equal1>equal2);//False\n        System.out.println(equal1<equal2);//True\n        System.out.println(equal1>=equal2);//False\n        System.out.println(equal1<=equal2);//True\n        //Conditional\n        System.out.println(\"***** Conditional Operatos/\\n\" +\n                \"Bedingte Operatoren ****\\n\");\n        System.out.println(equal1!=equal2&&equal1<=equal2);//True\n        System.out.println(equal1>equal2||equal1!=equal2);//True\n        System.out.println(\"\\n\");\n\n        //Conditionals statements\n        System.out.println(\"***** Conditional Statements/\\n\" +\n                \"Bedingte Anweisungen ****\\n\");\n        System.out.println(\"***** IF ****\\n\");\n        // IF\n        if(5 > 3){\n            System.out.println(\"5 is more than 3\");\n        }\n        //IF-ELSE\n        System.out.println(\"***** IF-ELSE ****\\n\");\n        System.out.println(\"\\n\");\n        if(5 < 3){\n            System.out.println(\"5 es mayor que 3\");\n        }\n        else {\n            System.out.println(\"5 is more than 3\");\n        }\n        System.out.println(\"\\n\");\n        //SWITCH\n        System.out.println(\"***** SWITCH ****\\n\");\n        int day= 5;\n        switch (day){\n            case 1:\n                System.out.println(\"Monday\");\n                break;\n            case 2:\n                System.out.println(\"Tuesday\");\n                break;\n            case 3:\n                System.out.println(\"Wednesday\");\n                break;\n            case 4:\n                System.out.println(\"Thursday\");\n                break;\n            case 5:\n                System.out.println(\"Friday\");\n                break;\n            case 6:\n                System.out.println(\"Saturday\");\n                break;\n            case 7:\n                System.out.println(\"Sunday\");\n                break;\n            default:\n                System.out.println(\"Invalid day\");\n                break;\n        }\n        //Loop statements\n        System.out.println(\"\\n\");\n        System.out.println(\"***** Loop statements/Schleifen Anweisungen ****\\n\");\n        //WHILE\n        System.out.println(\"\\n\");\n        System.out.println(\"***** WHILE ****\\n\");\n        int count=1;\n        while(count < 5) {\n            System.out.println(\"Count from while: \" + count);\n            count++;\n        }\n        //DO-WHILE, executed once at least\n        System.out.println(\"\\n\");\n        System.out.println(\"***** DO-WHILE ****\\n\");\n        int count2=11;\n        do {\n            System.out.println(\"Count from do while: \" + count2);\n            count2 --;\n        }while (count2 > 1 && count2 < 11);\n\n        //FOR\n        System.out.println(\"\\n\");\n        System.out.println(\"***** FOR ****\\n\");\n        for (int i = 0; i < 5; i++) {\n            System.out.println(\"Count from for:\" + i );\n        }\n        System.out.println(\"\\n\");\n        System.out.println(\"***** FOR EACH ****\\n\");\n        int[] arrayNumbers ={1,2,3,4,5,6};\n        for(int item:arrayNumbers){\n            System.out.println(\"Count from Array \" + item);\n        }\n\n        //FOR EACH\n        //Jump statements\n        System.out.println(\"\\n\");\n        System.out.println(\"***** JUMPS STATEMENTS/SPRÜNGE ANWEISUNGEN ****\\n\");\n        //break\n        System.out.println(\"***** BREAK ****\\n\");\n        for(int item:arrayNumbers){\n            if(item == 3){\n                break;//break the for statements\n            }\n            System.out.println(\"Count from break \" + item);\n        }\n        //continue\n        System.out.println(\"\\n\");\n        System.out.println(\"***** CONTINUE ****\\n\");\n        for(int item:arrayNumbers){\n            if(item == 3){\n                continue;//continue the for statements but not print \"3\"\n            }\n            System.out.println(\"Count from continue \" + item);\n        }\n        System.out.println(\"\\n\");\n\n        //Exceptions\n        System.out.println(\"***** EXCEPTIONS ****\\n\");\n        try {\n            System.out.println(\"Number of array\" + arrayNumbers[10]);\n        }catch (IndexOutOfBoundsException e){\n            System.out.println(e.getMessage());\n        }\n\n        //EXTRA\n        System.out.println(\"\\n Extra Exercise \");\n        for(int i=10 ; i<=55;i++){\n            if(i % 2 ==0 && i!=16 && i % 3 !=0){\n                System.out.println(\"Number \" + i);\n            }\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/juanca2805.java",
    "content": "public class juanca2805 {\n\n    public static void main(String[] args) {\n        /*\n         Operadores logicos\n         */\n        int Numero1 = 5;\n        int Numero2 = 7;\n\n        // operadores  arigmeticos usados con variables y sin variables\n        System.out.println( \"LA SUMA DEl \" + Numero1 + \" + \"  + Numero2 + \" es\");\n        System.out.println(Numero1 + Numero2);\n        System.out.println(\"LA Resta DEl \" + Numero1 + \" + \"  + Numero2 + \" es\");\n        System.out.println(Numero1 - Numero2);\n        System.out.println(20 / 3);\n        System.out.println(20 * 3);\n        System.out.println(20 % 10);\n\n        //Operaciones de comparacion\n        System.out.println(20 == 10);\n        System.out.println(20 != 10);\n        System.out.println(Numero1 > Numero2);\n        System.out.println(Numero1 >= Numero2);\n\n        //operadores logicos\n        boolean a;\n        boolean b;\n\n        a = false;\n        b = true;\n        // Operador AND\n        System.out.println(\"AND(&&): \" + (a && b));\n        // Operador OR\n        a = true;\n        b = false;\n        System.out.println(\"OR(||): \" + (a || b));\n        // Operador NOT\n        System.out.println(\"NOT(!): \" + (!b));\n      \n        //operador ternario \n        int edad = 18;\n        String mensaje = (edad >= 18) ? \"Eres mayor de edad\" : \"Eres menor de edad\";\n        System.out.println(mensaje);\n\n         //operadores de asignacion\n    Numero1 += 10;\n    System.out.println(Numero1);\n        //OPERADOR DE BITS \n          System.out.println(\"Operadores de bits -------------------------------\");\n\n        int cinco = 5;                      // 0101 en binario\n        int tres =3;                        // 0011 en binario\n        \n        int bitAnd = cinco & tres;          // 0001 (1) Operación lógica AND \n        System.out.println(bitAnd);\n        int bitOr = cinco | tres;           // 0111 (7) Operción lógica OR  \n\n        System.out.println(bitOr);\n        int bitXor = cinco ^ tres;          // 0110 (6) Operación OR exclusiva \n        System.out.println(bitXor);\n\n        /*Estructuras de control\n         * \n         * Condicionales\n         * \n         * \n        */\n\n    String Nombre = \"camilo\";\n\n    if (Nombre == \"camilo\") {\n        System.out.println(\"Pase señor \" + Nombre );\n    }\n    if (Nombre == \"pepe\") {\n        System.out.println(\"usted no es bienvenido señor \" + Nombre );\n    } \n    else{\n        System.out.println(\"Usted no es el señor \" + Nombre);\n    }\n    \n    // Iterativos\n\n    for(int i = 1; i <= 10 ; i++){\n        System.out.print(\" \"+ i );\n    };\n    \n    extra();\n\n\n    /* * DIFICULTAD EXTRA (opcional):\n     Crea un programa que imprima por consola todos los números comprendidos\n      entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n     */\n    \n    \n\n    }\n    public static void extra() {\n        for(int i = 10; i < 56; i++) {\n            if((i != 16) && (i % 3 != 0) && (i % 2 == 0)) {\n                System.out.println(i);\n            }\n        }\n    }\n\n    \n    \n\n    }\n\n   \n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/kilianhc.java",
    "content": "package retosProgramacion;\n\npublic class RetoDos {\n\n    public static void main(String[] args) {\n        \n        //Ejercicio de dificultad extra\n        for (int num = 10; num <= 55; num++) {\n            if (num != 16 && num%2 == 0 && num%3 != 0){        \n            System.out.println(num);\n            }\n        }\n\n        //operadores aritméticos\n        int a = 15;\n        int b = 3;\n        System.out.println(\"Suma de a + b = \" + (a + b));\n        System.out.println(\"Resta de a - b = \" + (a - b));\n        System.out.println(\"Multiplicación de a * b = \" + (a * b));\n        System.out.println(\"División de a/b = \" + (a / b));\n        System.out.println(\"Módulo de a % b = \" + (a % b));\n\n        //Operadores de asignación\n        int miNumero = 10; //Asignación simple\n        System.out.println(miNumero);\n        miNumero += 2; //Suma y asignación\n        System.out.println(miNumero);\n        miNumero -= 3; //Resta y asignación\n        System.out.println(miNumero);\n        miNumero *= 4; //Multiplicación y asignación\n        System.out.println(miNumero);\n        miNumero /= 5; //División y asignación\n        System.out.println(miNumero);\n        miNumero %= 6; //Módulo y asignación\n        System.out.println(miNumero);\n\n        //Operadores unarios\n        System.out.println(\"Mantiene el signo: \" + (+a));\n        System.out.println(\"Cambia el signo: \" + (-a));\n        System.out.println(\"Autoincremento e impresión: \" + (++a));\n        System.out.println(\"Impresión y autoincremento: \" + (a++));\n        System.out.println(\"Autodecremento e impresión: \" + (--a));\n        System.out.println(\"Impresión y autodecremento: \" + (a--));\n\n        //Operadores Relacionales\n        System.out.println(\"Los dos números son iguales: \" + (a == b)); //igualdad\n        System.out.println(\"Los dos números son iguales: \" + (a != b)); //desigualdad\n        System.out.println(\"A es mayor que B: \" + (a > b)); //mayor que\n        System.out.println(\"A es menor que B: \" + (a < b)); //menor que\n        System.out.println(\"A es mayor o igual a B: \" + (a >= b)); //mayor o igual que\n        System.out.println(\"A es menor o igual a B: \" + (a <= b)); //menor o igual que\n\n        //Operadores Lógicos\n        System.out.println(\"A es mayor y menor que B: \" + (a > b && a < b)); //AND lógico\n        System.out.println(\"A es mayor o menor que B: \" + (a > b || a < b)); //OR lógico\n        System.out.println(\"A es mayor que B: \" + !(a > b));//NOT lógico, Invierte el true o false\n        System.out.println(\"A es mayor o igual que B: \" + (a > b ^ a < b));//XOR lógico, devuelve true si sólo una lo es\n\n        //Operadores Bit a Bit\n        System.out.println(\"AND bit a bit: \" + (a & b));\n        System.out.println(\"OR bit a bit: \" + (a | b));\n        System.out.println(\"XOR bit a bit: \" + (a ^ b));\n        System.out.println(\"NOT bit a bit: \" + (~a));\n        System.out.println(\"Desplazamiento a la izquierda: \" + (a << 1));\n        System.out.println(\"Desplazamiento a la derecha: \" + (a >> 1));\n        System.out.println(\"Desplazamiento a la derecha sin signo: \" + (a >>> 1));\n\n        //Operador ternario (Condicional)\n        int c = (a > 10) ? 2 : 5;\n        System.out.println(\"El valor de c será: \" + c);\n\n        //Operador de instancia (Instanceof)\n        String s = \"Hola\";\n        boolean objetoTipo = s instanceof String;\n        System.out.println(\"El objeto c es de tipo String: \" + objetoTipo);\n\n        //Operadores de tipo (Cast)\n        double d = 10.5;\n        int i = (int) d;\n        System.out.println(\"El número double 10.5 es el número entero: \" + i);\n\n        //Estructuras de control de decisión (Condicionales) \n        if (a >= 15) { //If\n            System.out.println(\"A es igual o mayor a 15\");\n        }\n\n        if (a >= 15) { //Else\n            System.out.println(\"A es igual o mayor a 15\");\n        } else {\n            System.out.println(\"A es menor que 15\");\n        }\n\n        if (a > 15) { //else if\n            System.out.println(\"A es  mayor a 15\");\n        } else if (a < 15) {\n            System.out.println(\"A es menor a 15\");\n        } else {\n            System.out.println(\"A es igual a 15\");\n        }\n\n        switch (b) { //Switch\n            case 1:\n                System.out.println(\"B es igual a 1\");\n                break;\n            case 2:\n                System.out.println(\"B es igual a 2\");\n                break;\n            case 3:\n                System.out.println(\"B es igual a 3\");\n                break;\n            default:\n                System.out.println(\"B no tiene valor\");\n        }\n\n        //Estructuras de control de repeticion (Bucles)\n        for (int ini = 1; ini <= 5; ini++) { //For\n            System.out.println(\"Iteración: \" + ini);\n        }\n\n        int contador = 0;\n        while (contador < 5) { //While\n            System.out.println(\"Contador: \" + contador);\n            contador++;\n        }\n\n        int contador2 = 0;\n        do {\n            System.out.println(\"Contador: \" + contador2); //do-while\n            contador2++;\n        } while (contador2 < 3);\n\n        String[] lista = {\"Rodri\", \"Vinicius\", \"Bellingham\", \"Kroos\", \"Lamine\", \"Carvajal\"}; //for-each(Mejorado para Arrays y Colecciones)\n        for (String list : lista) {\n            System.out.println(\"El nombre del juagador es: \" + list);\n        }\n\n        //Estructuras de control de salto\n        for (int k = 0; k < 5; k++) {\n            if (k == 2) {\n                break; //BREAK\n            }\n            System.out.println(k);\n        }\n\n        for (int k = 0; k < 5; k++) {\n            if (k == 2) {\n                continue; //CONTINUE\n            }\n            System.out.println(k);\n        }\n\n        for (int k = 0; k < 5; k++) {\n            if (k == 2) {\n                return; //RETURN\n            }\n            System.out.println(k);\n        }\n\n        //Control de manejo de excepciones\n        try {\n            System.out.println(10 / 0);\n        } catch (Exception e) {\n            System.out.println(\"Se ha producido un error\");\n        } finally {\n            System.out.println(\"Ha finalizado correctamente\");\n        }\n       \n    }\n}\n\n\n\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/kleyner098.java",
    "content": "\npublic class kleyner098 {\n\n    public static void main(String[] args) {\n        \n        /*\n        * EJERCICIO:\n        * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n        *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n        *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n        * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n        *   que representen todos los tipos de estructuras de control que existan\n        *   en tu lenguaje:\n        *   Condicionales, iterativas, excepciones...\n        * - Debes hacer print por consola del resultado de todos los ejemplos.\n        *\n        * DIFICULTAD EXTRA (opcional):\n        * Crea un programa que imprima por consola todos los números comprendidos\n        * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n        *\n        * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n        */\n\n        //Operador de asignación (=)\n        System.out.println(\"Operador de asignación-------------------------------\");\n        int num1 = 1;                               //Asigna un valor o expresión a una variable\n        System.out.println(num1);\n\n        // Operadores aritméticos (+,-,*,/,%)\n        System.out.println(\"Operadores aritméticos-------------------------------\");\n        int suma = 6+1;                             //Suma \n        System.out.println(suma);\n        int resta = 10-2;                           //Resta\n        System.out.println(resta);\n        //El operador - tambien sirve para cambiar el signo de la expresión\n        int numPositivo = 43;\n        int numNegatvo = -numPositivo;\n        System.out.println(numNegatvo);\n        int multipilcacion = 4*5;                   //Multiplicación\n        System.out.println(multipilcacion);\n        int division = 50/5;                        //División\n        System.out.println(division);\n        int modulo = 7%3;                           //Módulo. Devuelve el resto de una división. Ej: 7/3 = 2 y el resto es 1\n        System.out.println(modulo);\n\n        //Operadores aritméticos incrementales (++,--);\n        System.out.println(\"Operadores incrementales-------------------------------\");\n        int incremento = 1;\n        incremento++;                                        //Incrementa el valor de la variable en 1\n        System.out.println(incremento);\n        int decremento = 1;\n        decremento--;                                        //Decrementa el valor de la variable en 1\n        System.out.println(decremento);              \n        //La expresión a++ y b-- equivalen a: (a = a + 1) y (b = b - 1) respectivamente\n        //Los operadores ++ y -- se pueden utilizar como prefijo (++a) o posfijo (a++) y cambia su comportamiento.\n        //Si se utilizan como prefijo los operadores ++ o -- tendrá precedencia sobre otros operadores de la expresión.\n        //Si se utilizan como posfijo, se realizará cualquier operación antes que la operación incremento o decremento.\n        //Ejemplo:\n        int a = 1;\n        System.out.println(a);\n        System.out.println(++a);\n        System.out.println(a);\n        \n        int b = 1;\n        System.out.println(b);\n        System.out.println(b++);\n        System.out.println(b);\n\n        //Operadores relacionales (==,!=,<,>,<=,>=)\n        //Producen un resultado lógico o booleano a partir de comparaciones entre valores numéricos, caracteres o boolenao \n        System.out.println(\"Operadores relacionales -------------------------------\");\n        int numero = 1;\n        int numero2 = 1;\n        int numero3 = 3;\n        Boolean igual = numero == numero2; // Devuelve un valor booleano dependiendo si las dos expresiones son iguales \n        System.out.println(igual);\n        Boolean distinto = 1+2 != numero3; // Devuelve un valor boolenao dependiendo si las expresiones son diferentes\n        System.out.println(distinto);\n        Boolean menor = numero < numero3; // Devuelve un valor booleano si expresión de la izquierda es menor que la expresión de la derecha \n        System.out.println(menor);\n        Boolean mayor = 7+23 > numero;    // Devuelve un valor booleano si expresión de la izquierda es mayor que la expresión de la derecha\n        System.out.println(mayor);\n        Boolean menorIgual = numero + numero3 <= 5; // Devuelve un valor booleano si expresión de la izquierda es menor o igual que la expresión de la derecha\n        System.out.println(menorIgual);\n        Boolean mayorIgual = numero + numero3 >= 4; // // Devuelve un valor booleano si expresión de la izquierda es mayor o igual que la expresión de la derecha\n        System.out.println(mayorIgual);\n\n        //Operadores lógicos(&&,||,!)\n        //Producen un resultado lógico o booleano a partir de otros valores booleanos\n        System.out.println(\"Operadores lógicos -------------------------------\");\n        Boolean verdadero = true;\n        Boolean falso = false;\n        int c = 4;\n        Boolean and = verdadero && c != 7;              // El operador (&&) and delvuelve true si todas las expresiones son verdaderas\n        System.out.println(and);\n        Boolean or = falso || c < 1 || verdadero;       //El operador or (||) delvuelve true si una de las expresiones es verdadera   \n        System.out.println(or);\n        Boolean not = !(falso) && verdadero;            // El operador not (!) cambia el valor de la expresión a sus contrario\n        System.out.println(not);\n\n        //Operadores asignación combinados (+=,-=,*=,/=,%=)\n        //Se trata del operdor asignación combinado con los ariméticos\n        System.out.println(\"Operadores aignacion y aritméticos -------------------------------\");\n        int z = 4;\n        int y = 7;\n        int x = 1;\n        int w = 8;\n        int v = 9;\n        z += 3;                             //Suma el valor de la derecha y se asigna a la variable\n        System.out.println(z);\n        y -= 2;                             //Resta el valor de la derecha y se asigna a la variable\n        System.out.println(y);\n        x *= 6;                             //Multiplica el valor de la derecha y se asigna a la variable\n        System.out.println(x);\n        w /= 4;                             //Divide por valor de la derecha y se asigna a la variable\n        System.out.println(w);\n        v %= 2;                             //Se realiza el módulo por la expresión indicada a la izquierda y la asigna a la variable\n        System.out.println(v);\n\n        //Operador ternario o condicional (?:)\n        //Devuelve el valor entre dos posibles. Si la expresión es verdadera develve el valor1 (expresion condicional ? valor1 : valor2)\n        System.out.println(\"Operadores ternario -------------------------------\");\n        int k = 9;\n        int j = k >= 4 ? 18 : 1;\n        int l = k >= 20 ? 18 : 1;\n        System.out.println(j);\n        System.out.println(l);\n\n        //Operadores de bit(&,|,^,~,<<,>>)\n        //Sirve para realizar operaciones con número en bit, el resultado que devuelve es int \n        System.out.println(\"Operadores de bits -------------------------------\");\n\n        int cinco = 5;                      // 0101 en binario\n        int tres =3;                        // 0011 en binario\n        \n        int bitAnd = cinco & tres;          // 0001 (1) Operación lógica AND \n        System.out.println(bitAnd);\n        int bitOr = cinco | tres;           // 0111 (7) Operción lógica OR  \n        System.out.println(bitOr);\n        int bitXor = cinco ^ tres;          // 0110 (6) Operación OR exclusiva \n        System.out.println(bitXor);\n        int bitNot = ~cinco;                // Operación NOT\n        System.out.println(bitNot);\n\n        int cuatro = 4;                     // 0100 en binario\n        int deplazarIzq = cuatro << 1;      // 1000 (8) Desplazada x posiciones a las izquierda \n        System.out.println(deplazarIzq);\n        int deplazarDer = cuatro >> 1;      // 0010 (2) Desplaza x posiciones a la derecha\n        System.out.println(deplazarDer);\n\n        //Operador de concatenación (+)\n        //Sirve para concatenar(unir) strings\n        System.out.println(\"Operador de concatenación-------------------------------\");\n        String cadena = \"Hola\";\n        System.out.println(cadena + \" Mundo\");\n\n        //Estrucutas de control \n        //Condición simple (If). Ejecuta un bloque de código si se cumple una condición\n        /* \n        if (condition) {\n            bloque de código\n        }\n        */\n        System.out.println(\"Estructura de control (IF)-------------------------------\");\n        int r = 17;\n\n        if (r > 10 && 5+1 != r){\n            System.out.println(\"Se ejecuta porque la condicio es true\");\n        }\n\n        //Condicional doble (if-else). Se especifican dos bloques de código y mediante la condición si es true se ejecuta un bloque o si es false se ejecuta el otro bloque.\n         /* \n        if (condición) {\n            bloque de código\n        }else{\n            bloque de código\n        }\n        */\n        System.out.println(\"Estructura de control (if-esle)-------------------------------\");        \n        if(r < 10){\n            System.out.println(\"Este es el bloque que se ejecuta si la condición es true\");\n        }else{\n            System.out.println(\"Este es el bloque que se ejecuta si la condición es false\");\n        }\n\n        //Anidación de condicionales if-else if-else. Se puede hacer varias condiciones que ejecutaran diferentes bloques de códigos\n        /* \n        if (condición) {\n            bloque de código\n        }else if (condición){\n            bloque de código\n        }else {\n            bloque de código\n        }\n        */\n        System.out.println(\"Estructura de control (if anidados)-------------------------------\");\n        if (r < 17 ){\n            System.out.println(\"Es menor a 17\");\n        } else if ( r == 17){\n            System.out.println(\"Es igual a 17\");\n        } else {\n            System.out.println(\"Es mayor a 17\");\n        }\n\n        //Switch. Se utiliza en codiciones multiples.\n        /*switch (expresión) {\n            case value:\n                \n                break;\n            \n            ...\n\n            default:\n                break;\n        }*/\n        System.out.println(\"Estructura de control (switch)-------------------------------\");\n        String saludo = \"hola\";\n        switch (saludo) {\n            case \"hola\":\n                System.out.println(\"Bloque 1\");\n                break;\n            case \"adios\":\n                System.out.println(\"Bloque 2\");\n                break;\n            default:\n                System.out.println(\"Bloque por defecto (Opcional)\");\n                break;\n        }\n\n        //La estructura switch necesita de la sentencia break para parar la ejecución del siguieten bloque.\n        System.out.println(\"Estructura de control (switch sin break)-------------------------------\");\n        switch (saludo) {\n            case \"hola\":\n                System.out.println(\"Bloque 1\");\n            case \"adios\":\n                System.out.println(\"Bloque 2\");\n            default:\n                System.out.println(\"Bloque por defecto (Opcional)\");\n                break;\n        }\n        \n        //En las útimas versiones de switch tiene otra sintaxis en la que no es necesario utilizar la sentencia break para parar la ejecución del bloque\n        // y si el bloque a ejecutar solo contiene una línea no es necesario escribir {}\n        /*switch (expresión) {\n            case valor -> Una línea de código \n            case valor2->{\n                Bloque de código\n            }\n            default->{\n                Bloque de código\n            }   \n        }\n        */\n        System.out.println(\"Estructura de control (switch con otra sintaxis)-------------------------------\");\n        int g = 2;\n        switch (g){\n            case 1,2,3 -> System.out.println(\"Se ejecutará en el caso de 1,2,3\");\n            case 4 -> {\n                System.out.println(\"Se ejecutará en el caso de 4\");\n                System.out.println(\"Nesecita {} porque hay más de una línea de código\");\n            }\n        }\n\n        //También se puede utilizar como una expresión, es decir toda la sentencia switch se sustituira por un valor.\n        //En caso de que el bloque de código de un caso tenga más de una línea de código necesitaremos de la sentencia yield para devolver un valor\n        //Si switch se utiliza como una expresión necesitaremos un caso delfault obligatoriamente\n        /*tipoVarible nombreVariable = switch (expresión) {\n            case valor -> valor devuelto \n            case valor2->{\n                Bloque de código\n                yield valor devuelto\n            }\n            default->{\n                Bloque de código\n                yield valor devuelto\n            }   \n        }\n        */\n        System.out.println(\"Estructura de control (switch como expresión)-------------------------------\");\n        int numMes = 13;\n        int diasMes = switch(numMes){\n            case 1, 3, 5, 7, 8, 10, 12 -> 31;\n            case 2 -> 28;\n            case 4, 6, 9, 11 -> 30;\n            default -> {\n                System.out.println(\"Error, solo hay doce meses\");\n                yield -1;\n            }\n        };\n        System.out.println(\"El mes \" + numMes + \" tiene \" + diasMes + \" dias\");\n\n        //Estrutura de control while. Es un bucle controlado por una condición\n        /*\n        while (condición) {\n          bloque de código  \n        }\n        */\n        System.out.println(\"Estructura de control (while)-------------------------------\");\n        int s = 1;\n        while (s <= 10){\n            System.out.print(\" \" + s);\n            s++;\n        }\n\n        //Estrutura de control do-while. Es un bucle controlado por una condición y a diferencia de while, el bloque dentro de bucle se ejecuata al menor una vez\n        /* \n        do{\n            bloque de código\n        }while(condición);\n        */\n        System.out.println(\"Estructura de control (while)-------------------------------\");\n        int t = 10;\n        do{\n            System.out.print(\" \" + t);\n            t--;\n        } while (t >= 1);\n\n        //El bucle while se puede ejecutar de 0 a infinitas veces y el bucle do while de 1 a infinitas veces\n\n        //Estrutura de control for. Es un bucle controlado por una variable que incrementa o decrementa.\n        /* \n        for(inicialización de variable; condición; incremento/decremento){\n            bloque de código\n        }\n        */\n        System.out.println(\"Estructura de control (for)-------------------------------\");\n        for(int i = 1; i <= 10 ; i++){\n            System.out.print(\" \"+ i);\n        }\n\n        //Ejercicio opcional\n        for(int i = 10; i <=55; i++){\n            if( i % 2 == 0 && i != 16 && i % 3 != 0){\n                System.out.print( \" \" + i);\n            }\n        }\n\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/kuroz00.java",
    "content": "/* \n* - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n*/\n\n\n/*\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n*/\n\n/*\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n*/\n\nimport java.util.ArrayList;\n\npublic class kuroz00{\n    public static void aritmetics(int numero_a,int numero_b){\n        System.out.println(numero_a + numero_b);\n        System.out.println(numero_a - numero_b);\n        System.out.println(numero_a * numero_b);\n        System.out.println(numero_a / numero_b);\n        System.out.println(numero_a % numero_b);\n\n        System.out.println(\"---------\"); //Tambien se puede trabajar de la sig forma:\n        \n      //  System.out.println(numero_a += numero_b);\n      //  System.out.println(numero_a -= numero_b);\n      //  System.out.println(numero_a *= numero_b);\n      //  System.out.println(numero_a /= numero_b);\n      //  System.out.println(numero_a %= numero_b);\n    }\n\n    public static void logics(boolean bool_a,boolean bool_b){\n        if (bool_a && bool_b == true){\n            System.out.println(\"Resultado segun parametros otorgados: AND\");\n        }  else if(bool_a || bool_b != true ){\n            System.out.println(\"Resultado segun parametros otorgados: OR\");\n        } //Tambien esta el NOT, cuya funcion es negar el booleano entregado.\n    }\n\n    public static void compareishon(int num1, int num2){      \n        if (num1 > num2){\n            System.out.println(\"Numero1: \" + num1 + \" > \" + \"Numero 2:\" + num2);             \n        } \n        else{\n            System.out.println(\"Numero1: \" + num1 + \" < \" + \"Numero 2:\" + num2);              \n        }     \n    }\n    public static void teneichon(){\n        try{\n            String[] days = {\"lunes\", \"martes\", \"miercoles\", \"jueves\", \"sabado\", \"domingo\" }; //List cn dias de la semana, sin el viernes\n            System.out.println(days[6]); //Intero imprimir el indice del ultimo dia (sup que son 7)\n        } catch(Exception e){\n            System.out.println(\"Excepcion detectada\");\n        }\n    }\n\n    public static void biteichon(){\n        int x = 25; //11001\n        int a = 5; //0101\n        int b = 9; //1001\n        //Desplazamiento a la izquierda\n        System.out.println(x << 2);\n        //Desplazamiento a la derecha\n        System.out.println(x >> 2);\n        //AND\n        System.out.println(a & b);\n        //OR\n        System.out.println(a | b);\n        //XOR\n        System.out.println(a ^ b);\n        //NOT\n        System.out.println(~a);\n        System.out.println(~b);\n    }\n\n    public static void main(String[] args){\n        //Aritmeticos\n        int numero_a = 5;\n        int numero_b = 2;\n        System.out.println(\"°°°°°°°°°°°°°°°°.-.-Aritmetics-.-°°°°°°°°°°°°°°°°°\");\n        aritmetics(numero_a, numero_b);\n\n        //Logicos\n        System.out.println(\"°°°°°°°°°°°°°°°-.-Logicos-.-°°°°°°°°°°°°°°°°°°\");\n        logics(false, false);\n\n        //Comparacion y asignacion\n        System.out.println(\"°°°°°°°°°°°°°°°-.-Comparacion.-°°°°°°°°°°°°°°°°°°\");\n        compareishon(numero_a, numero_b);\n\n        //Pertenencia\n        System.out.println(\"°°°°°°°°°°°°°°°-.-Pertenencia.-°°°°°°°°°°°°°°°°°°\");\n        teneichon();\n\n        //Bits\n        System.out.println(\"°°°°°°°°°°°°°°°-.-Bits.-°°°°°°°°°°°°°°°°°°\");\n        biteichon();\n\n\n        //Dificultad extra ¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬\n        System.out.println(\"°°°°°°°°°°°°°°°-.-D.F.-°°°°°°°°°°°°°°°°°°\");\n        for(int i = 0; i < 50; i++){\n            if ((i % 2 == 0) && (i % 3 != 0) && (i != 16)){\n                System.out.print(i + \" \");\n            } \n        }\n\n\n    }\n}\n\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *~`^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/lautarorisso.java",
    "content": "public class LogicaJava01 {\n    \n    public static void main(String[] args) {\n    \n        // 1.\n        int a = 10; // Asignación\n        a += 2; // Asignación (se puede combinar con cualquier operador aritmético)\n        int b = 3;\n        \n        System.out.println(a + b); // suma\n        System.out.println(a - b); // resta\n        System.out.println(a * b); // multiplicación\n        System.out.println(a / b); // división\n        System.out.println(a % b); // módulo\n        \n        System.out.println(a == b);\n        System.out.println(a != b);\n        System.out.println(a > b);\n        System.out.println(a < b);\n        System.out.println(a >= b);\n        System.out.println(a <= b);\n        \n        boolean t = true;\n        boolean f = false;\n        \n        System.out.println(t && f); // AND\n        System.out.println(t || f); // OR\n        System.out.println(!t);     // NOT\n        \n        String s1 = \"Java\";\n        String s2 = \"Java\";\n        \n        System.out.println(a == b);        // false (distintas referencias)\n        System.out.println(s1.equals(s2));   // true (mismo contenido)\n        \n        Object obj = \"Hola\";\n        \n        System.out.println(obj instanceof String);\n        System.out.println(obj instanceof Integer);\n        \n        int m = 5;  // 0101\n        int n = 3;  // 0011\n\n        System.out.println(m & n);  // AND\n        System.out.println(m | n);  // OR\n        System.out.println(m ^ n);  // XOR\n        System.out.println(m << 1); // desplazamiento izquierda\n        System.out.println(m >> 1); // desplazamiento derecha\n        \n        // 2.\n        if (a > b) {\n            System.out.println(\"a es mayor que b\");\n        } else {\n            System.out.println(\"b es mayor o igual que a\");\n        }\n\n        int dia = 2;\n        switch (dia) {\n            case 1 -> System.out.println(\"Lunes\");\n            case 2 -> System.out.println(\"Martes\");\n            default -> System.out.println(\"Otro día\");\n        }\n\n        for (int i = 0; i < 3; i++) {\n            System.out.println(i);\n        }\n\n        int contador = 0;\n        while (contador < 3) {\n            System.out.println(contador);\n            contador++;\n        }\n        \n        // EXTRA\n        for (int i=10;i<56;i++) {\n            if (i%2==0 && i!=16 && i%3!=0) {\n                System.out.println(i);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/llonardo798.java",
    "content": "public class llonardo798 {\n\n    public static void main(String[] args) {\n        // 1. Tipos de operadores por categoría:\n\n        // 1. Operadores Aritméticos:\n\n        int suma = 5 + 5 + 5; // Suma\n        System.out.println(suma); // Imprime 15\n        int resta = 10 - 5; // Resta\n        System.out.println(resta); // Imprime 5\n        int multiplicacion = 5 * 5; // Multiplicación\n        System.out.println(multiplicacion); // Imprime 25\n        int division = 10 / 2; // División\n        System.out.println(division); // Imprime 5\n        int modulo = 10 % 3; // Módulo (resto o sobrante de la división) 10 % 3 = 1 se puede considerar como\n                             // 10/3 = 3 y sobra 1\n        System.out.println(modulo); // Imprime 1\n        suma++; // Incremento en 1\n        System.out.println(suma); // Imprime 16\n        resta--; // Decremento en 1\n        System.out.println(resta); // Imprime 4\n\n        // 2. Operadores de Asignación:\n\n        String nombre = \"Leonardo\"; // Asignación simple: =\n        System.out.println(nombre); // Imprime \"Leonardo\"\n        suma += 5; // Suma y asignación\n        System.out.println(suma); // Imprime 21\n        resta -= 5; // Resta y asignación\n        System.out.println(resta); // Imprime -1\n        multiplicacion *= 5; // Multiplicación y asignación\n        System.out.println(multiplicacion); // Imprime 125\n        division /= 2; // División y asignación\n        System.out.println(division); // Imprime 2 - el valorse recorta en el decimal porque es int y no float\n        modulo %= 3; // Módulo y asignación\n        System.out.println(modulo); // Imprime 1 porque 10 % 3 = 0.99999... y se redondea a 1 por ser int\n\n        // 3. Operadores de Comparación:\n\n        boolean igual = 5 == 5; // Igual a\n        System.out.println(igual); // Imprime true - 5 es igual a 5\n        boolean diferente = 5 != 5; // Diferente de\n        System.out.println(diferente); // Imprime false - 5 no es diferente de 5\n        boolean mayor = 10 > 5; // Mayor que\n        System.out.println(mayor); // Imprime true - 10 es mayor que 5\n        boolean menor = 5 < 10; // Menor que\n        System.out.println(menor); // Imprime true - 5 es menor que 10\n        boolean mayorIgual = 10 >= 5; // Mayor o igual que\n        System.out.println(mayorIgual); // Imprime true - 10 es mayor o igual que 5\n        boolean menorIgual = 5 <= 10; // Menor o igual que\n        System.out.println(menorIgual); // Imprime true - 5 es menor o igual que 10\n\n        // 4. Operadores Lógicos:\n\n        boolean and = true && true; // AND lógico - ambas condiciones deben ser verdaderas\n        System.out.println(and); // Imprime true\n        boolean or = true || false; // OR lógico - al menos una condición debe ser verdadera\n        System.out.println(or); // Imprime true\n        boolean not = !true; // NOT lógico - niega la condición\n        System.out.println(not); // Imprime false\n\n        // 5. Operadores Bit a Bit (a nivel de bits):\n\n        // AND bit a bit & - valida los numeros bit a bit como un AND.\n        // Si compara 0 y 0 = 0, 0 y 1 = 0, 1 y 0 = 0, 1 y 1 = 1\n        int a = 60; // En binario: 0011 1100\n        int b = 13; // En binario: 0000 1101\n        int resultadoAnd = a & b;\n        System.out.println(resultadoAnd); // Resultado: 0000 1100 (Imprime 12 en decimal)\n        // Explicación:\n        // 0011 1100 - Valor a\n        // 0000 1101 - Valor b\n        // --------- & (AND)\n        // 0000 1100 - 12 en decimal\n\n        // OR bit a bit: | - valida los numeros bit a bit como un OR.\n        // Si compara 0 y 0 = 0, 0 y 1 = 1, 1 y 0 = 1, 1 y 1 = 1\n        int resultadoOr = a | b;\n        System.out.println(resultadoOr); // Resultado: 0011 1101 (Imprime 61 en decimal)\n        // Explicación:\n        // 0011 1100\n        // 0000 1101\n        // --------- | (OR)\n        // 0011 1101 - 61 en decimal\n\n        // XOR bit a bit: ^ - valida los numeros bit a bit como un XOR.\n        // Si compara 0 y 0 = 0, 0 y 1 = 1, 1 y 0 = 1, 1 y 1 = 0\n        int resultadoXor = a ^ b;\n        System.out.println(resultadoXor); // Resultado: 0011 0001 (Imprime 49 en decimal)\n        // Explicación:\n        // 0011 1100\n        // 0000 1101\n        // --------- ^ (XOR)\n        // 0011 0001\n\n        // Complemento bit a bit: ~ - cambia los bits de 0 a 1 y de 1 a 0\n        a = 60; // En binario: 0011 1100\n        int resultadoComplemento = ~a;\n        System.out.println(resultadoComplemento); // Resultado: 1100 0011 (Imprime 195 en decimal)\n        // Explicación:\n        // 0011 1100 - Valor a = 60\n        // --------- ~ (Complemento)\n        // 1100 0011 - 195 en decimal\n\n        // Desplazamiento a la izquierda: << - desplaza los bits a la izquierda\n        a = 33; // En binario: 0010 0001\n        int resultadoDesplazamientoIzquierda = a << 2;\n        System.out.println(resultadoDesplazamientoIzquierda); // Resultado: 1000 0100 (132 en decimal)\n        // Mover el número 33 dos posiciones a la izquierda.\n        // moviendo los bits en 1 dos posiciones a la izquierda\n        // Explicación:\n        // 0010 0001 - Valor a = 33\n        // --------- << (Desplazamiento a la izquierda)\n        // 1000 0100 - 132 en decimal\n\n        // Desplazamiento a la derecha: >> - desplaza los bits a la derecha\n        a = 33; // En binario: 0010 0001\n        int resultadoDesplazamientoDerecha = a >> 2;\n        System.out.println(resultadoDesplazamientoDerecha); // Resultado: 0000 1000 (8 en decimal)\n        // Mover el número 33 dos posiciones a la derecha.\n        // moviendo los bits en 1 dos posiciones a la derecha\n        // Explicación:\n        // 0010 0001 - Valor a = 33\n        // --------- >> (Desplazamiento a la derecha)\n        // 0000 1000 - 8 en decimal\n\n        // Desplazamiento a la derecha sin signo: >> - desplaza los bits a la derecha\n        // sin importar si el numero es positivo o negativo para lo cual agrerga 0 a\n        // la izquierda\n        a = -10; // En binario (complemento a dos): 1111 1111 1111 1111 1111 1111 1111 0110\n        int resultadoDesplazamientoIzquierdaSinSigno = a >>> 1;\n        System.out.println(resultadoDesplazamientoIzquierdaSinSigno); // Resultado: 0111 1111 1111 1111 1111 1111 1111\n                                                                      // 1011 (2147483643 en decimal)\n\n        // 6. Operadores Ternarios:\n\n        // Operador condicional ternario: ?:\n        a = 5;\n        int edad = (a == 10) ? 10 : 20; // Si a es igual a 10, entonces edad es igual a 10, de lo contrario, edad es\n                                        // igual a 20\n        System.out.println(edad); // Imprime 20\n\n        // 7. Otros Operadores:\n\n        String nombreCompleto = \"Leonardo \" + \"Aedo\"; // Concatenación de cadenas\n        System.out.println(nombreCompleto); // Imprime \"Leonardo Aedo\"\n        byte[] bytes = nombreCompleto.getBytes(); // Operador de acceso a miembros de clase \".\"\n        System.out.println(bytes); // Imprime [B@6d06d69c\n        int[] numeros = { 1, 3, 7, 2, 5 };\n        int numero = numeros[2]; // Operador de acceso a elementos de arreglo \"[]\"\n        System.out.println(numero); // Imprime 7\n        double numeroDecimal = 10.5;\n        int numeroEntero = (int) numeroDecimal; // Operador de cast (conversión de tipos)\n        System.out.println(numeroEntero); // Imprime 10 - se recorta el decimal porque se convierte de double a int\n        boolean esInstancia = nombre instanceof String; // Operador instanceof (verifica si un objeto es una instancia\n        // de una clase) esInstancia devuelve true si nombre es una instancia de la\n        // clase String, de lo contrario, devuelve false\n        System.out.println(esInstancia); // Imprime true ya que nombre es una instancia de la clase String\n\n        // DIFICULTAD EXTRA - Crea un programa que imprima por consola todos los números\n        // comprendidos entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni\n        // múltiplos de 3.\n        System.out.println(\"Números pares entre 10 y 55 que son pares, que no son 16 y no es múltiplos de 3:\");\n        for (int i = 10; i < 56; i++) {\n            if ( i % 2 == 0 && i != 16 && i % 3 != 0) {\n                System.out.println(i);\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/marce1084.java",
    "content": "public class marce1084 {\n    public static void main(String[] args) {\n        int a = 3;\n        int b = 7;\n        boolean c = true;\n        boolean d = false;\n\n        //Operadores Aritméticos\n        System.out.println(\"Suma: \" + (a + b));\n        System.out.println(\"Resta: \" + (a - b));\n        System.out.println(\"Multiplicacion: \" + (a * b));\n        System.out.println(\"Division: \" + (a / b));\n        System.out.println(\"Modulo: \" + (a % b));\n\n        //Operadores Lógicos\n        System.out.println(\"AND &&: \" + (c && d));\n        System.out.println(\"OR ||: \" + (c || d));\n        System.out.println(\"Not !c: \" + !c);\n        System.out.println(\"Not !d: \" + !d);\n\n        //Operadores de Comparación\n        System.out.println(\"Igual a: \" + (a == b));\n        System.out.println(\"Mayor que: \" + (a > b));\n        System.out.println(\"Menor que: \" + (a < b));\n        System.out.println(\"Distinto a: \" + (a != b));\n        System.out.println(\"Mayor o igual a: \" + (a >= b));\n        System.out.println(\"Menor o igual a: \" + (a <= b));\n\n        //Operadores de asignación\n        System.out.println(\"Asignación y suma: \" + (a += 1));\n        System.out.println(\"Asignación y resta: \" + (b -= 1));\n        System.out.println(\"Asignación y multiplicación: \" + (a *= 2));\n        System.out.println(\"Asignación y division: \" + (a /= 2));\n        System.out.println(\"Asignación y modulo: \" + (a %= 2));\n        System.out.println(\"Asignación: \" + (a = 5));\n        System.out.println(\"Asignación y AND bit a bit: \" + (a &= 3));\n        System.out.println(\"Asignación y OR bit a bit: \" + (a |= 3));\n\n        //Operadores Bits\n        System.out.println(\"AND BIT: \" + (c & d));\n        System.out.println(\"OR BIT: \" + (c | d));\n        System.out.println(\"XOR BIT: \" + (c ^ d));\n        System.out.println(\"NOT BIT: \" + ~a);\n        System.out.println(\"Desplazamiento izquierda: \" + (a << 1 ));\n        System.out.println(\"Desplazamiento derecha: \" + (a >> 1 ));\n\n        //Operadores indentidad\n        String str1 = new String(\"Hola\");\n        String str2 = new String(\"Hola\");\n        System.out.println(\"Referencia de igualdad: \" + (str1 == str2));\n        System.out.println(\"Referencia de desigualdad: \" + (str1 != str2));\n        System.out.println(\"Comparacion de contenido: \" + (str1.equals(str2)));\n\n        /*Estructuras de control*/\n\n        //Condicionales\n        int edad = 17;\n        if (edad > 18) {\n            System.out.println(\"Es mayor de edad\");\n        } else System.out.println(\"La edad debe ser mayor o igual a 18\");\n\n        //Iterativas\n        for (int i = 0; i <= 10; i++) {\n            System.out.println(\"Numero: \" + i);\n        }\n\n        int i = 11;\n        while (i > 0){\n            System.out.println(\"Numero: \" + i);\n            i--;\n        }\n\n        //Excepciones\n        try {\n            System.out.println(10/0);\n        } catch (ArithmeticException e) {\n            System.out.println(\"Se produjo error por la división\");\n        } finally {\n            System.out.println(\"Finalizó el manejo de excepciones\");\n        }\n\n        //Ramificación\n        for (int j = 0; j <= 7 ; j++) {\n            if (j == 3 ){\n                break;\n            }\n            System.out.println(\"Numero: \" + j);\n        }\n\n        //EXTRA\n        /*Crea un programa que imprima por consola todos los números comprendidos\n        entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n        Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.*/\n\n        for (int j = 10; j <= 55 ; j++) {\n            if (j %2 == 0 && j != 16 && j%3 != 0){\n                System.out.println(\"Number: \" + j);\n            }\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/mariovelascodev.java",
    "content": "public class mariovelascodev {\n        public static void main(String[] args) {\n\n            int number1 = 10;\n            int number2 = 43;\n\n            //Operadores aritméticos\n            System.out.println(\"Operadores Aritméticos\");\n            System.out.println(\"-----------------------\");\n\n            int sum = number1 + number2;\n            int subtract = number1 - number2;\n            int multiplication = number1 * number2;\n            int division = number2 / number1;\n            int modulus = number2 % number1;\n\n            System.out.println(\"Suma: \" + sum);\n            System.out.println(\"Resta: \" + subtract);\n            System.out.println(\"Multiplicación: \" + multiplication);\n            System.out.println(\"División: \" + division);\n            System.out.println(\"Módulo: \" + modulus);\n            System.out.println(\"Incremento se utiliza poniendo ++ delante de la variable: \"+ ++sum);\n            System.out.println(\"Decremento se utiliza poniendo -- delante de la variable: \"+ --sum);\n\n            System.out.println(\"-----------------------\\n\");\n\n            //Operadores de comparación\n            System.out.println(\"Operadores de Comparación\");\n            System.out.println(\"---------------------------\");\n\n            System.out.println(\"Operador de Igualdad se representa con ==: 10 == 43: \"+(number1 == number2));\n            System.out.println(\"Operador de Distinto de se representa con !=: 10 != 43: \"+(number1 != number2));\n            System.out.println(\"Operador de Mayor que se representa con >: 10 > 43: \"+(number1 > number2));\n            System.out.println(\"Operador de Mayor o Igual que se representa con >=: 10 >= 43: \"+(number1 >= number2));\n            System.out.println(\"Operador de Menor que se representa con z: 10 < 43: \"+(number1 < number2));\n            System.out.println(\"Operador de Menor o Igual que se representa con <=: 10 > 43: \"+(number1 <= number2));\n\n\n            System.out.println(\"-----------------------\\n\");\n\n            //Operadores lógicos\n            System.out.println(\"Operadores Lógicos\");\n            System.out.println(\"---------------------------\");\n\n            System.out.println(\"El operador AND se representa con &&: number1 > 10 && number2 < 40: \"\n                    + (number1 > 10 && number2 <= 40));\n\n            System.out.println(\"El operador OR se representa con ||: number1 >= 10 || number2 < 40: \"\n                    + (number1 >= 10 || number2 <= 40));\n\n            System.out.println(\"El operador NOT se representa con !: !(number1 > 10 && number2 < 40): \"\n                    + !(number1 > 10 && number2 <= 40));\n\n            System.out.println(\"-----------------------\\n\");\n\n            //Operadores de asignación\n            System.out.println(\"Operadores de asignación\");\n            System.out.println(\"---------------------------\");\n\n            System.out.println(\"El operador de Asignación se representa con el signo =: number1 = 10\");\n            System.out.println(\"El operador de Asignación con suma se representa +=: number1 += 1 da por salida: \"\n                    +(number1 += 1));\n            System.out.println(\"El operador de Asignación con resta se representa -=: number1 -= 1 da por salida: \"\n                    +(number1 -= 1));\n            System.out.println(\"El operador de Asignación con multiplicación se representa *=: number1 *= 5 da por salida: \"\n                    +(number1 *= 5));\n            System.out.println(\"El operador de Asignación con división se representa /=: number1 /= 5 da por salida: \"\n                    +(number1 /= 5));\n\n            System.out.println(\"-----------------------\\n\");\n\n            //Operadores Bitwise (bit a bit)\n            System.out.println(\"Operadores Bitwise (Bit a Bit)\");\n            System.out.println(\"---------------------------\");\n\n            System.out.println(\"El operador AND se representa con &: 5 & 3: \"\n                    + (5 & 3)+ \". El resultado es 1 si solo ambos bits son 1\");\n\n            System.out.println(\"El operador OR se representa con |: 5 | 3: \"\n                    + (5 | 3)+\". El resultado es 1 si al menos uno de los bits es 1\");\n\n            System.out.println(\"El operador XOR se representa con ^: 5 ^ 3: \"\n                    + (5 ^ 3)+\". El resultado es 1 si los bits son diferentes\");\n\n            System.out.println(\"El operador NOT se representa con ~: ~5: \"\n                    + ~5+\". Invierte todos los bits\");\n\n            System.out.println(\"El operador Desplazamiento a la Izquierda se representa con <<: 5 << 2: \"\n                    + (5 << 2)+\". Desplaza los bits n posiciones a la izquierda, rellenando con ceros a la derecha\");\n\n            System.out.println(\"El operador Desplazamiento a la Derecha con signo se representa con >>: -8 >> 2: \"\n                    + (-8 >> 2)+\". Desplaza los bits n posiciones a la derecha, replicando el signo\");\n\n            System.out.println(\"El operador Desplazamiento a la Derecha sin signo se representa con >>>: -8 >>> 2: \"\n                    + (-8 >>> 2)+\". Desplaza los bits n posiciones a la derecha, rellenando con ceros a la izquierda\");\n\n            System.out.println(\"-----------------------\\n\");\n\n            //Operador Ternario\n            System.out.println(\"Operador Ternario\");\n            System.out.println(\"---------------------------\");\n            System.out.println(\"condición ? valorSiEsTrue : valorSiEsFalse. Ejemplo number1 > number2 ? number1 : number2 = \"\n                    +(number1 > number2 ? number1 : number2));\n\n            System.out.println(\"-----------------------\\n\");\n\n            //Estructuras de control\n            System.out.println(\"Estructuras de control\");\n            System.out.println(\"---------------------------\");\n\n            System.out.println(\"Condicionales\");\n            System.out.println(\"---------------------------\");\n\n            System.out.println(\"if...else\");\n            System.out.println(\"---------------------------\");\n\n            if (number1 > number2) {\n                System.out.println(\"El numero de la variable number2 es mayor\");\n            } else if (number1 < number2) {\n                System.out.println(\"El numero de la variable number2 es menor\");\n            }else{\n                System.out.println(\"Ambos son iguales\");\n            }\n\n            System.out.println(\"-----------------------\\n\");\n\n            System.out.println(\"switch\");\n            System.out.println(\"---------------------------\");\n\n            int dayOfWeek = 3;\n\n            switch (number1) {\n                case 0:\n                    System.out.println(\"Lunes\");\n                    break;\n                case 1:\n                    System.out.println(\"Martes\");\n                    break;\n                case 2:\n                    System.out.println(\"Miercoles\");\n                    break;\n                case 3:\n                    System.out.println(\"Jueves\");\n                    break;\n                case 4:\n                    System.out.println(\"Viernes\");\n                    break;\n                case 5:\n                    System.out.println(\"Sabado\");\n                    break;\n                case 6:\n                    System.out.println(\"Domingo\");\n                    break;\n                default:\n                    System.out.println(\"No se puede establecer la opción\");\n            }\n\n            System.out.println(\"-----------------------\\n\");\n\n            System.out.println(\"Iterativas\");\n            System.out.println(\"---------------------------\");\n\n            System.out.println(\"for\");\n            System.out.println(\"---------------------------\");\n\n            for (int i = 1; i <= 10; i++) {\n                System.out.println(i);\n            }\n\n            System.out.println(\"-----------------------\\n\");\n\n            System.out.println(\"for each\");\n            System.out.println(\"---------------------------\");\n\n            String[] fruits = {\"Manzana\", \"Plátano\", \"Naranja\", \"Fresa\"};\n            for(String fruit :  fruits ){\n                System.out.println(fruit);\n            }\n\n            System.out.println(\"-----------------------\\n\");\n\n            System.out.println(\"while\");\n            System.out.println(\"---------------------------\");\n\n            while(number1 >= 0){\n                System.out.println(number1);\n                number1--;\n            }\n\n            System.out.println(\"-----------------------\\n\");\n\n            System.out.println(\"do while\");\n            System.out.println(\"---------------------------\");\n\n            do {\n                System.out.println(number2);\n                number2--;\n            }while (number2 < 40);\n\n            System.out.println(\"-----------------------\\n\");\n\n            //Excepciones\n            System.out.println(\"Excepciones\");\n            System.out.println(\"---------------------------\");\n\n            try{\n                int result = 10 / 0;\n                System.out.println(result);\n            }catch(Exception e){\n                System.out.println(\"Error: \"+e);\n            }finally {\n                System.out.println(\"--------------------------\\n\");\n            };\n\n            System.out.println(\"Extra\");\n            System.out.println(\"---------------------------\");\n\n            for (int index = 10; index <= 55; index++) {\n                if(index % 2 == 0 && index != 16 && index % 3 != 0){\n                    System.out.println(index);\n                }\n            }\n\n            System.out.println(\"-----------------------\\n\");\n\n        }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/martinbohorquez.java",
    "content": "/**\n * 01 - OPERADORES Y ESTRUCTURAS DE CONTROL\n *\n * @author martinbohorquez\n */\npublic class martinbohorquez {\n\n    public static void main(String[] args) {\n        /*\n         * Operadores aritméticos: actúan sobre números enteros y en punto flotante (decimales).\n         * Hay dos tipos:\n         *      -- Operadores binarios.\n         *      -- Operadores unarios.\n         */\n\n        /*\n         * Operadores unarios: aplican a un operando.\n         * Tipos:\n         *      -- Mantiene el signo del operando (+)\n         *      -- Cambia el signo del operando (-)\n         *      -- Autoincremento (++)\n         *      -- Autodecremento (--)\n         */\n\n        int a = 10;\n\n        System.out.println(\"Operadores unarios: aplican a un operando.\");\n\n        System.out.println(\"Mantiene el signo: a => \" + (+a));\n        System.out.println(\"Cambia el signo: a => \" + (-a));\n        System.out.println(\"Autoincremento e impresión: a => \" + (++a)); //Se incrementa y se imprime\n        System.out.println(\"Impresión y autoincremento: a => \" + (a++)); //Se imprime y se incrementa\n        System.out.println(\"Autodecremento e impresión: a => \" + (--a)); //Se decrementa y se imprime\n        System.out.println(\"Impresión y autodecremento: a => \" + (a--)); //Se imprime y se decrementa\n\n        System.out.println();\n\n        /*\n         * Operadores binarios: aplican sobre dos operandos.\n         * Tipos:\n         *       -- Suma (+)\n         *       -- Resta (-)\n         *       -- Multiplicación (*)\n         *       -- División (/)\n         *       -- Módulo (%)\n         */\n\n        int b = 5;\n        int c = 2;\n\n        System.out.println(\"Operadores binarios: aplican sobre dos operandos: \");\n\n        System.out.println(\"Suma: \" + b + \" + \" +  c + \" = \" + (b + c));\n        System.out.println(\"Resta: \" + b + \" - \" +  c + \" = \" + (b - c));\n        System.out.println(\"Multiplicación: \" + b + \" * \" +  c + \" = \" + (b * c));\n        System.out.println(\"División: \" + b + \" / \" +  c + \" = \" + (b / c));\n        System.out.println(\"Módulo: \" + b + \" % \" +  c + \" = \" + (b % c));\n\n        System.out.println();\n\n        /*\n         * Operadores relacionales: para hacer comparaciones.\n         * Tipos:\n         *      -- Mayor que (>)\n         *      -- Mayor o igual que (>=)\n         *      -- Menor que (<)\n         *      -- Menor o igual que (<=)\n         *      -- Igual que (==)\n         *      -- Distinto de (!=)\n         */\n\n        int d = 20;\n        int e = 50;\n\n        System.out.println(\"Operadores relacionales: para hacer comparaciones.\");\n\n        System.out.println(\"¿20 es mayor que 50? : \" + (d > e));\n        System.out.println(\"¿20 es mayor o igual que 50? : \" + (d >= e));\n        System.out.println(\"¿20 es menor que 50? : \" + (d < e));\n        System.out.println(\"¿20 es menor o igual que 50? : \" + (d <= e));\n        System.out.println(\"¿20 es igual que 50? : \" + (d == e));\n        System.out.println(\"¿20 es distinto de 50? : \" + (d != e));\n\n        System.out.println();\n\n        /*\n         * Operadores lógicos: Operan con valores lógicos para devolver nuevos valores lógicos.\n         * Tipos:\n         *      -- AND (&): Evalúa si las dos expresiones son verdaderas.\n         *      -- AND en curtocircuíto (&&): No evalúa la segunda expresión si la primera es falsa.\n         *      -- OR (|): Evalúa si alguna de las expresiones es verdadera.\n         *      -- OR en curtocircuíto (||): No evalúa la segunda expresión si la primera es verdadera.\n         *      -- NOT (!): Cambia el valor de la variable lógica.\n         */\n\n        boolean v = true;\n        boolean f = false;\n\n        System.out.println(\"Operadores lógicos: Operan con valores lógicos para devolver nuevos valores lógicos.\");\n\n        System.out.println(\"¿true es igual a false? : \" + (v & f));\n        System.out.println(\"¿true es igual a false? (cortocircuíto) : \" + (v && f));\n        System.out.println(\"¿true o false son verdaderas? : \" + (v | f));\n        System.out.println(\"¿true o false son verdaderas? (cortocircuíto) : \" + (v || f));\n        System.out.println(\"Cambiamos el valor de true : \" + (!v));\n\n        System.out.println();\n\n        /*\n         * Operador sobre cadenas de caracteres (+): Para concatenar cadenas de caracteres.\n         */\n\n        String text1 = \"¡Hola, \";\n        String text2 = \"Mundo!\";\n\n        System.out.println(\"Operador sobre cadenas de caracteres:\");\n\n        System.out.println(text1 + text2);\n\n        System.out.println();\n\n        /*\n         * Operadores de asignación: Para asignar un valor a una variable.\n         * Tipos:\n         *      -- +=: Suma a la variable y sobrescribe el valor de la variable con el resultado.\n         *      -- -=: Resta a la variable y sobrescribe el valor de la variable con el resultado.\n         *      -- *=: Multiplica a la variable y sobrescribe el valor de la variable con el resultado.\n         *      -- /=: Divide a la variable y sobrescribe el valor de la variable con el resultado.\n         *      -- %=: Realiza el módulo a la variable y sobrescribe el valor de la variable con el resultado.\n         *      -- &=: Realiza un AND lógico a la variable y sobrescribe el valor de la variable con el resultado.\n         *      -- |=: Realiza un OR lógico a la variable y sobrescribe el valor de la variable con el resultado.\n         */\n\n        int i;\n        boolean t = true;\n\n        System.out.println(\"Operadores de asignación: Para asignar un valor a una variable.\");\n\n        System.out.println(\"Asignamos valor a la variable i = \" + (i = 2));\n        System.out.println(\"Suma y asigna: \" + (i += 4));\n        System.out.println(\"Resta y asigna: \" + (i -= 3));\n        System.out.println(\"Multiplica y asigna: \" + (i *= 5));\n        System.out.println(\"Divide y asigna: \" + (i /= 3));\n        System.out.println(\"Módulo y asigna: \" + (i %= 3));\n        System.out.println(\"AND lógico y asigna: \" + (t &= true));\n        System.out.println(\"OR lógico y asigna: \" + (t |= false));\n\n        System.out.println();\n\n        /*\n         * Operadores a nivel de bits: operan con cada bit del operando, ofreciendo un control más granular sobre los datos.\n         * Tipos:\n         *      -- AND (&): Operador AND a nivel de bits (1 y 1 = 1).\n         *      -- OR (|): Operador OR a nivel de bits (1 o 1 = 1).\n         *      -- XOR (^): Operador XOR a nivel de bits (1 y 1 = 0).\n         *      -- Complemento (~): Invierte el valor de cada bit.\n         *      -- >> : Desplaza bits a la derecha.\n         *      -- << : Desplaza bits a la izquierda.\n         *      -- >>> : Desplaza bits a la derecha sin signo.\n         */\n\n        int x = 10;\n        int y = 7;\n\n        System.out.println(\"Operadores a nivel de bits: operan con cada bit del operando, ofreciendo un control más granular sobre los datos.\");\n\n        System.out.println();\n\n        System.out.println(\"x : \" + Integer.toBinaryString(x));\n        System.out.println(\"y : \" + Integer.toBinaryString(y));\n\n        System.out.println();\n\n        System.out.println(\"x AND y : \" + Integer.toBinaryString(x & y));\n        System.out.println(\"x OR y : \" + Integer.toBinaryString(x | y));\n        System.out.println(\"x XOR y : \" + Integer.toBinaryString(x ^ y));\n        System.out.println(\"Complemento de x = \" + Integer.toBinaryString(~x));\n        System.out.println(\"Complemento de y = \" + Integer.toBinaryString(~y));\n        System.out.println(\"Desplazamiento de bits de x a la izquierda de 2: \" + Integer.toBinaryString(x << 2));\n        System.out.println(\"Desplazamiento de bits de x a la derecha de 1: \" + Integer.toBinaryString(x >> 1));\n        System.out.println(\"Desplazamiento de bits de x a la derecha de 2 (sin signo): \" + Integer.toBinaryString(x >>> 1));\n\n        System.out.println();\n\n        /*\n         * Excepciones\n         * uso del try - catch\n         */\n        try {\n            throw new Exception(\"Este es un ejemplo de excepción!\");\n        } catch (Exception error) {\n            System.out.println(\"Exception: \" + error.getMessage());\n        }\n\n        System.out.println();\n\n        /*\n         * Crea un programa que imprima por consola todos los números comprendidos\n         * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n         */\n\n        System.out.println(\"DIFICULTAD EXTRA \\n\");\n\n        System.out.println(\"Los números son: \");\n\n        for (int j = 10; j <= 55; j++) {\n            //Compruebo si son pares, distintos de 16 y no son múltiplos de 3\n            if (j % 2 == 0 && j != 16 && j % 3 != 0) {\n                System.out.println(j);\n            }\n        }\n\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/miguelex.java",
    "content": "public class miguelex {\n    public static void main(String[] args) {\n        \n        // Operadores aritmeticos\n\n        int a = 5;\n        int b = 2;\n\n        System.out.println(\"Operadores aritmeticos\");\n        System.out.println(\"Suma de 5 + 2 = \" + (a + b));\n        System.out.println(\"Resta de 5 - 2 = \" + (a - b));\n        System.out.println(\"Multiplicacion de 5 * 2 = \" + (a * b));\n        System.out.println(\"Division de 5 / 2 = \" + (a / b));\n        System.out.println(\"Modulo de 5 % 2 = \" + (a % b));\n\n        // Operadores de asignacion\n\n        System.out.println(\"Operadores de asignacion\");\n        System.out.println(\"a = \" + a);\n        System.out.println(\"a += 2 = \" + (a += 2));\n\n        // Operadores de comparacion\n\n        System.out.println(\"Operadores de comparacion\");\n        System.out.println(\"a == b = \" + (a == b));\n        System.out.println(\"a != b = \" + (a != b));\n        System.out.println(\"a > b = \" + (a > b));\n        System.out.println(\"a < b = \" + (a < b));\n        System.out.println(\"a >= b = \" + (a >= b));\n        System.out.println(\"a <= b = \" + (a <= b));\n\n        // Operadores logicos\n\n        boolean x = true;\n        boolean y = false;\n\n        System.out.println(\"Operadores logicos\");\n        System.out.println(\"true && false = \" + (x && y));\n        System.out.println(\"true || false = \" + (x || y));\n        System.out.println(\"!true = \" + (!x));\n\n        // Operadores a nivel de bit\n\n        System.out.println(\"Operadores a nivel de bit\");\n        System.out.println(\"5 & 2 = \" + (a & b));\n        System.out.println(\"5 | 2 = \" + (a | b));\n        System.out.println(\"5 ^ 2 = \" + (a ^ b));\n        System.out.println(\"~5 = \" + (~a));\n        System.out.println(\"5 << 2 = \" + (a << 2));\n        System.out.println(\"5 >> 2 = \" + (a >> 2));\n        System.out.println(\"5 >>> 2 = \" + (a >>> 2));\n\n        // if ... else\n\n        System.out.println(\"if ... else\");\n        if (a > b) {\n            System.out.println(\"a es mayor que b\");\n        } else {\n            System.out.println(\"b es mayor que a\");\n        }\n\n        // switch\n\n        System.out.println(\"switch\");\n        switch (a) {\n            case 1:\n                System.out.println(\"a es 1\");\n                break;\n            case 2:\n                System.out.println(\"a es 2\");\n                break;\n            case 3:\n                System.out.println(\"a es 3\");\n                break;\n            default:\n                System.out.println(\"a no es 1, 2 o 3\");\n                break;\n        }\n\n        // for\n\n        System.out.println(\"for\");\n        for (int i = 0; i < 5; i++) {\n            System.out.println(\"i = \" + i);\n        }\n\n        // while\n\n        System.out.println(\"while\");\n        int i = 0;\n        while (i < 5) {\n            System.out.println(\"i = \" + i);\n            i++;\n        }\n\n        // do ... while\n\n        System.out.println(\"do ... while\");\n        i = 0;\n        do {\n            System.out.println(\"i = \" + i);\n            i++;\n        } while (i < 5);\n\n        // break\n\n        System.out.println(\"break\");\n        for (int j = 0; j < 5; j++) {\n            if (j == 3) {\n                break;\n            }\n            System.out.println(\"j = \" + j);\n        }\n\n        // continue\n\n        System.out.println(\"continue\");\n        for (int j = 0; j < 5; j++) {\n            if (j == 3) {\n                continue;\n            }\n            System.out.println(\"j = \" + j);\n        }\n\n        // try ... catch\n\n        System.out.println(\"try ... catch\");\n        try {\n            int result = a / 0;\n            System.out.println(\"Resultado: \" + result);\n        } catch (ArithmeticException e) {\n            System.out.println(\"Error: Division por cero\");\n        }\n\n        // Extra\n\n        System.out.println(\"Extra\");\n\n        for (i = 10; i <= 55; i++) {\n            if (i % 2 == 0 && i != 16 && i % 3 != 0) {\n                System.out.println(i);\n            }\n        }\n\n        \n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/mtirador.java",
    "content": "import java.util.Scanner;\n\npublic class mtirador {\n    public static void main(String[] args) {\n\n    int a=5,b=4;\n     //operadores aritméticos\n    \n     int resta=a-b;\n     int suma=a+b;\n     int mult=a*b;\n     int div=a/b;\n     int resto=a%b;\n\n     System.out.println(\"Resta: \"+resta+\"\\nSuma: \"+suma+\"\\nMultiplicación: \"+ mult\n     +\"\\nDivisión: \"+ div+\"\\nResto: \"+resto);\n\n     //Operadores comparación\n    \n     \n     System.out.println(\"Distinto: \"+ (a!=b));\n     System.out.println(\"Igual: \"+(a==b));\n     System.out.println(\"Menor que: \"+ (a<b));\n     System.out.println(\"Mayor que: \"+ (a>b));\n    \n     //Operadores Asignación\n     a+=9;\n     System.out.println(\"Valor de a ahora: \"+ a);\n     //Identidad\n     String frase= \"Hola Mundo\";\n     System.out.println(\"Cadena: \"+ frase);\n\n    // Operadores de Bits\n    int numBits = 5; // Representación binaria: 101\n    int opAnd = numBits & 3; // Resultado: 1 (1 en binario)\n\n    System.out.println(\"\\nOperadores de Bits:\");\n    System.out.println(\"Operación AND Bit a Bit: \" + opAnd);\n\n    /*Estructuras de control */\n    //Condicionales\n\n    if(a>b){\n        System.out.println(a+\" es mayor que \"+ b);\n    }else{\n        System.out.println(a +\" es menor que \"+ b);\n    }\n\n    //Iterativas\n\n    for(int i=0;i<b;i++){\n        System.out.println(\"Resultado del For: \"+ i);\n\n    }\n\n    //control excepciones\n    Scanner scanner = new Scanner(System.in);\n\n        try {\n            System.out.print(\"Ingrese el numerador: \");\n            int numerador = scanner.nextInt();\n\n            System.out.print(\"Ingrese el denominador: \");\n            int denominador = scanner.nextInt();\n\n            double resultado = dividir(numerador, denominador);\n            System.out.println(\"Resultado de la división: \" + resultado);\n        } catch (ArithmeticException e) {\n            System.out.println(\"Error: División por cero no permitida\");\n        } catch (Exception e) {\n            System.out.println(\"NO HA INGRESADO UN NÚMERO: \" + e.getMessage());\n        } finally {\n            scanner.close();\n        }\n\n\n/** Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */ //OPCIONAL\n        for(int i=10;i<=55;i++){\n            if(i%2==0 && i%3!=0 && i!=16){\n                System.out.println(i);\n\n            }\n\n        }\n      \n\n    }//fin main\n\n    // Método para realizar la división y lanzar una excepción si se intenta dividir por cero\n    private static double dividir(int numerador, int denominador) {\n        if (denominador == 0) {\n            throw new ArithmeticException(\"Intento de división por cero\");\n        }\n        return (double) numerador / denominador;\n    }\n\n\n    }//fin class\n\n   \n   \n    \n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/nicoloboo02.java",
    "content": "public class nicoloboo02{\n\n\n    public static void bucleWhile(int i,int y){\n        while (i<y){\n            System.out.println(\"Los números no son iguales\");\n            i++;\n        }\n        System.out.println(\"Los números ya son iguales\");\n\n    }\n\n    public static void bucleIfElseFor(int i,int y){\n        for (int z = 0;z<=5;z++){\n            if(i>y){\n                System.out.println(\"El primer numero es mayor que el segundo\");\n                y++;\n            }else if(i<y){\n                System.out.println(\"El segundo numero es mayor que el primero\");\n                i=i+3;\n            }else{\n                System.out.println(\"Los numeros son iguales\");\n                break;\n            }\n        }\n    }\n\n    public static void extra(){\n        for(int i = 10;i<=55;i++){\n            if (i%2==0 && i!=16 && !(i%3==0 )){\n                System.out.println(i);\n            }\n        }\n    }\n       \n    public static void main(String[] args) {\n        int a = 5;\n        int b = 6;\n        int suma = a+b;\n        int resta = a-b;\n        int multipilcacion = a*b;\n        int division = a/b;\n        int modulo = a%b;\n        int incremento = a++;\n        int decremento = b--;\n        boolean igual = a==b;\n        boolean diferente = a!=b;\n        boolean mayor = a>b;\n        boolean menor = a<b;\n        boolean mayorigual = a>=b;\n        boolean menorigual = a<=b;\n        boolean and = menor && mayor;\n        boolean or = menor || mayor;\n        System.out.println(\"Operadores Aritméticos\");\n        System.out.println(\"Suma: \"+suma);\n        System.out.println(\"Resta: \"+resta);\n        System.out.println(\"Multiplicacion: \"+multipilcacion);\n        System.out.println(\"Division: \"+division);\n        System.out.println(\"Módulo: \"+modulo);\n        System.out.println(\"Incremento: \"+incremento);\n        System.out.println(\"Decremento: \"+decremento);\n        System.out.println(\"\\nOperadores relacionales\");\n        System.out.println(\"Son a y b iguales? \" + igual);\n        System.out.println(\"Son a y b diferentes? \"+diferente);\n        System.out.println(\"Es a mayor que b? \"+mayor );\n        System.out.println(\"Es a menor que b? \"+menor );\n        System.out.println(\"Es a mayor o igual que b? \"+mayorigual );\n        System.out.println(\"Es a menor o igual que b? \"+menorigual );\n        System.out.println(\"\\nOperadores lógicos\");\n        System.out.println(and);\n        System.out.println(or);\n        System.out.println(\"\\n Estructuras condicionales\");\n        int c = 5;\n        int d = 7;\n        System.out.println(\"Bucle while:\");\n        bucleWhile(c, d);\n        System.out.println(\"Bucles for y if-else\");\n        bucleIfElseFor(c, d);\n        System.out.println(\"\\n Ejercicio extra\");\n        extra();\n\n       \n\n\n         \n\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/nwpablodeveloper.java",
    "content": "// #01 OPERADORES Y ESTRUCTURAS DE CONTROL\n\npublic class nwpablodeveloper {\n\n    public static void main(String[] args) {\n        \n        int a, b, edad, contador;\n        String texto, texto2;\n\n        /*\n            OPERADOR DE CONCATENACIÓN\n\n            Utilizaremos el signo + para unir cadenas de textos u otras variables. \n        */\n        titulo(\"Operador de concatenacion ( + ) \");\n        String nombre = \"Pablo\";\n        edad = 35;\n        String concatenar = \"Mi nombre es: \" + nombre + \" y tengo \" + edad + \" pirulos\";\n        System.out.println(concatenar);\n\n\n\n        /*\n            OPERADOR DE ASIGNACIÓN\n\n            El operador de asignación va a evaluar todo lo que esta a la derecha\n            del signo = y se lo va a asignar a la variable que esta a su izquierda\n        */\n        titulo(\"Operador de asignacion ( = )\");\n        texto = \"Este contenido va pá la variable\";\n        System.out.println(texto);\n\n\n\n        /* \n            OPERADORES ARITMETICOS\n\n            sumar\n            restar\n            multiplicar\n            dividir\n            resto de la división \n        */\n        titulo(\"Operadores Aritmeticos ( + , - , *, /, % )\");\n        a = 15;\n        b = 7;\n        int suma            = a + b;\n        int resta           = a - b;\n        int multiplicacion  = a * b;\n        int division        = a / b;\n        int resto           = a % b;\n        System.out.println( \"suma:              15 + 7 ---> \" + suma );\n        System.out.println( \"resta:             15 - 7 ---> \" + resta );\n        System.out.println( \"multiplicacion:    15 * 7 ---> \" + multiplicacion );\n        System.out.println( \"division:          15 / 7 ---> \" + division );\n        System.out.println( \"resto:             15 % 7 ---> \" + resto );\n\n\n        /* \n            OPERADORES DE ASIGNACIÓN COMPUESTA\n\n            Se juntaron el operador de aritmetico con el de asignación. \n            Este atajo se puede realizar para otras operaciones además de la suma. \n            Es útil cuando la operación contiene como primer operando al \n            valor de la misma variable en la que se almacena el resultado.\n        */\n        titulo(\"Operador de asignacion compuesta ( signo= )\");\n\n        a = 35; b = 6;\n        System.out.println(\"a = 35; b = 6 \\n\");\n\n        System.out.println(\"a += b: ---> \" + ( a += b ) );   // a = a + b  \n\n        a = 35; b = 6;\n        System.out.println(\"a -= b: ---> \" + ( a -= b ) );   // a = a - b  \n\n        a = 35; b = 6;\n        System.out.println(\"a *= b: ---> \" + ( a *= b ) );   // a = a + b  \n\n        a = 35; b = 6;\n        System.out.println(\"a /= b: ---> \" + ( a /= b ) );   // a = a + b  \n\n        a = 35; b = 6;\n        System.out.println(\"a %= b: ---> \" + ( a %= b ) );   // a = a % b  \n\n\n        /*\n            OPERADORES UNARIOS\n            \n        */\n        titulo(\"Operadores unarios ( -, --, ++ )\");\n\n        // Operador unario, para cambiar el signo\n        System.out.println(\"Operador unario para cambiar el signo Ej: \\na = 35\");\n        a = 35;\n        b = -a;\n        System.out.println(\"b = -a \");\n        System.out.println(\"b = \"+ b + \"\\n\"); \n        System.out.println(\"a = \"+ a + \"\\n\"); \n        \n        // Suma pre-incremento\n        // 1ro hace el incremento al suendo operando y luego lo asigna a la variable\n        System.out.println(\"Suma unaria Ej: \\na = 35\");\n        a = 35;\n        b = ++a;\n        System.out.println(\"b = ++a \");\n        System.out.println(\"b = \"+ b + \"\\n\"); \n        System.out.println(\"a = \"+ a + \"\\n\"); \n\n        // Resta pre-decremento\n        // 1ro hace el decremento al sugundo operando y leugo lo asigna a la variable\n        System.out.println(\"Resta unaria Ej: \\na = 35\");\n        a = 35;\n        b = --a;\n        System.out.println(\"b = --a \");\n        System.out.println(\"b = \"+ b + \"\\n\");  \n        System.out.println(\"b = \"+ b + \"\\n\"); \n\n        // Operador post-incremento\n        // 1ro asigna el valor del sugundo operando a la variable y luego hace el incremento\n        System.out.println(\"post-incremento Ej: \\na = 35\");\n        a = 35;\n        b = a++;\n        System.out.println(\"b = a++ \");\n        System.out.println(\"b = \"+ b  );  \n        System.out.println(\"a = \"+ a + \"\\n\");  \n\n        // Operador post-decremento\n        // 1ro asigna el valor del sugundo operando a la variable y luego hace el decremento\n        System.out.println(\"post-decremento Ej: \\na = 35\");\n        a = 35;\n        b = a--;\n        System.out.println(\"b = a++ \");\n        System.out.println(\"b = \"+ b  );  \n        System.out.println(\"a = \"+ a );  \n\n\n        /* \n            OPERADORES RELACIONALES\n            Devuelven un valor booleano ( true o false ) a partir de una comparación de 2 variables.\n        */\n        titulo(\"Operadores relacionales ( ==, !=, <, >, <=, >= ) \");\n        a = 38;             \n        b = 17;    \n        texto = \"Pablo\";    \n        texto2 = \"Javier\";        \n        System.out.println(\"Invertir condicion          \" + ( !true )); \n        System.out.println(\"38 es igual a 17 ?          \" + ( a == b ));\n        System.out.println(\"Pablo es igual a Javier?    \" + ( texto == texto2 ) );\n        System.out.println(\"38 es distinto a 17?        \" + ( a != b ) );\n        System.out.println(\"38 es menor a 17?           \" + ( a < b ) );\n        System.out.println(\"38 es mayor a 17?           \" + ( a > b ) );\n\n\n        /*\n            OPERADORES CONDICIONALES \n            Realiza la comparación entre datos booleanos y da \n            como resultado otro valor booleano\n        */\n        titulo(\"Operadores condicionales ( ||, && )\");\n        a = 38;             \n        b = 17;             \n        texto = \"Pablo\";    \n        texto2 = \"Javier\";  \n        boolean ressultado;\n\n        // || ( OR ) Una de las 2 o mas evaluaciones tiene que ser verdadera Ej. 1\n        ressultado = (a == b) || ( texto == texto2 );\n        System.out.println(\"38 es igual a 17 ? o Pablo es igual a Javier ? \"+  ressultado);\n\n        // || ( OR ) Una de las 2 o mas evaluaciones tiene que ser verdadera Ej. 2\n        ressultado = (a == 38 ) || ( texto == texto2 );\n        System.out.println(\"38 es igual a 38 ? o Pablo es igual a Javier ? \"+  ressultado);\n\n        // && ( AND )Las 2 o mas evaluaciones tiene que ser verdadera Ej. 1\n        ressultado = (a == 38 ) && ( texto == \"Pablo\" );\n        System.out.println(\"38 es igual a 38 ? y Pablo es igual a Pablo ? \"+  ressultado);\n\n        // && ( AND ) Las 2 o mas evaluaciones tiene que ser verdadera Ej. 2\n        ressultado = (a == 38 ) && ( texto == texto2 );\n        System.out.println(\"38 es igual a 38 ? y Pablo es igual a Javier ? \"+  ressultado);\n\n\n        /*\n            OPERADOR TERNARIO \n            Si el resultado a a evaluar es verdadero devuelve un resultado luego de\n            la primera expresión o caso contrario luego de la segunda expresión\n        */\n        titulo(\"Operador ternario ( ?: )\");\n        edad = 17; \n        var resultado = ( edad >= 18 )? \"Es mayorcito\" : \"todavia no tiene preocupaciones\";\n        System.out.println(resultado);\n\n\n        /*\n            SENTENCIAS DE CONTROL\n            Las sentencias de control se utilizan para ejecutar ciertos bloques de \n            codigo respecto a un resultado anterior \n        */\n        // Sentencia de control If-Else\n        titulo(\"Sentencia If-Else\");\n        \n        if ( edad >= 18 ) {\n            System.out.println(\"Es mayor de edad\");\n        } else {\n            System.out.println(\"Todavia te falta para ser mayorcito\");\n        }\n\n        // Sentencia de control Switch\n        titulo(\"Sentencia de control switch\");\n        \n        String mensaje;\n        int numero = 8;\n        \n        // Ejemplo 1, si se cumple una condición se ejecuta cierto codigo, el breack le da finalización al Switch\n        switch ( numero ) {\n            case 1:\n                mensaje = \"Es uno\";\n                break;\n            case 2:\n                mensaje = \"Es dos\";\n                break;\n            case 5:\n                mensaje = \"Es cinco\";\n                break;\n            case 8:\n                mensaje = \"Es ocho\";\n                break;\n            default:\n                mensaje = \"No hay coincidencias\";\n                break;\n        }\n        System.out.println(\"Ejemplo 1: \" + mensaje);\n        \n        // Ejemplo 2, pueden se pueden convinar combinaciones de Case para ejecutar cierto codigo\n        numero = 13;\n        switch ( numero ) {\n            case 1:\n            case 3:\n            case 5:\n                mensaje = \"El numero puede ser uno, tres o cinco\";\n                break;\n            case 6:\n            case 7:\n            case 8:\n                mensaje = \"El numero puede ser seis, siete u ocho\";\n                break;\n            default:\n                mensaje = \"El numero no es ni uno, tres, cinco, seis, siete u ocho\";\n                break;\n        }\n        System.out.println(\"Ejemplo 2: \" + mensaje);\n\n\n        /*\n            SENTENCIA DE CONTROL CICLO While\n            El ciclo while 1ro va a evualer que la condición que sea verdadera \n            para ejecutar el codigo de su interior, lo va a hacer \n            todas las veces necesarias hasta que la condición cambie a false\n        */\n        titulo(\"Sentencia de control While\");\n        \n        contador = 0;\n        while ( contador <= 4 ) {\n            System.out.println( \"Contador While: \" + contador );\n            contador++;\n        }\n\n        /*\n            SENTENCIA DE CONTROL DO-WHILE\n            1ro ejecuta el codigo dentro del bucle y luego verifica\n            si la condición booleana es true, en caso que sea false\n            se termina el bucle pero ya logramos almenos 1 vez\n            el bloque de codigo\n        */\n        titulo(\"Sentencia Do-While\");\n\n        contador = 3;\n        do {\n            System.out.println(\"Contador Do-While: \" + contador);\n        } while ( contador > 5 ); \n\n\n        /*\n            SENENTENCIA DE CONTROL FOR\n            El ciclo for repite un codigo todas las veces que nosotros\n            se lo indiquemos, el mismo recibe 3 parametros que son\n            el 1ro, el contador\n            2do la condición booleana\n            3ro el incrementador del contador\n        */\n        titulo(\"sentencia ciclo For\");\n        \n        // Ejemplo 1\n        for (contador = 0; contador <= 8; contador++) {\n            System.out.println(\"Ej. 1 - contador ciclo For: \" + contador);    \n        }\n        \n        System.out.println();\n        // Ejemplo 2\n        for (contador = 0; contador <= 9 ; contador += 2 ) {\n            System.out.println(\"Ej. 2 - contador ciclo For: \" + contador);    \n        }\n\n        /*\n            USO DE LA PALABRA CONTINUE\n            Cuando se encuentra la palabra CONTINUE dentro de un bucle\n            la misma finaliza esa vuelta de bucle y pasa a la que sigue \n        */\n        \n        System.out.println();\n        // Ejemplo 3\n        for (contador = 0; contador <= 9 ; contador += 2 ) {\n            if ( contador == 4 ) {\n                System.out.println(\"Saltear cuatro\");\n                continue;\n            }\n            System.out.println(\"Ej. 3 - contador ciclo For: \" + contador);    \n        }\n\n        /*\n            USO DE LA PALABRA BREK\n            Cuando se encuentra la palabra BREAK dentro de un bucle\n            la misma da por finalizado todo el bucle sin importar\n            si se cumple su condición final\n        */\n        \n        System.out.println();\n        // Ejemplo 4\n        for (contador = 0; contador <= 9 ; contador += 2 ) {\n            if ( contador == 6 ) {\n                System.out.println(\"finalizar bucle\");\n                break;\n            }\n            System.out.println(\"Ej. 4 - contador ciclo For: \" + contador);    \n        }\n\n        /*\n            SENTENCIA DE CONTROL TRYCATCH\n            Se utiliza para atrapar errores \n        */\n        titulo(\"Sentencia de control TRYCATCH\");\n        try {\n            System.out.println(\"Si todo va bien entro por aquí\");\n        } catch (Exception error) {\n            System.out.println(\"Si hay errores entro por aquí\");\n            System.out.println(\"Ver error: \" + error);\n            // Por ejemplo conectar a un DB con una contraseña incorrecta\n        } finally {\n            // El finally es opcional\n            System.out.println(\"Me voy a ejecutar siempre que use el FINALLY\");\n        }\n\n\n        /*\n            DIFICULTAD EXTRA (opcional):\n            Crea un programa que imprima por consola todos los números comprendidos\n            entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3. \n        */\n        titulo(\"Dificultad extra\");\n\n        for(int i = 10; i <= 55; i++ ) {\n            if ( i == 55 ) System.out.println(i);\n            if ( i % 2 != 0 ) continue;\n            if ( i % 3 == 0 ) continue;\n            if ( i == 16 )  continue;\n            System.out.println(i);\n        }\n\n        System.out.println();\n    }\n\n    /*\n        Un metodo para generar un linda vista para los titulos 🤘🤘🤘\n    */\n    public static void titulo(String titulo) {\n        System.out.println(\"\");\n        System.out.println(\"==================================================\");\n        System.out.println(titulo);\n        System.out.println(\"--------------------------------------------------\");\n\n    }\n\n }"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/oixild.java",
    "content": "\n/*\n*   Suma + o +=\n*   Resta - o -=\n*   Multiplicación * o *=\n*   División / o /=\n*   Módulo % o %=\n*   Incremento ++\n*   Decremento --\n*   Igual a ==\n*   Distinto de !=\n*   Mayor que >\n*   Menor que <\n*   Mayor o igual a >=\n*   Menor o igual a <=\n*   Y &&\n*   O ||\n*/\n\npublic class oixild {\n    public static void main(String[] args) {\n\n        int num1 = 10, num2 = 10, num3 = 5, num4 = 15;\n\n        System.out.println(num1 + num2);\n        System.out.println(num1 - num3);\n        System.out.println(num1 * num2);\n        System.out.println(num1 / num2);\n\n        System.out.println(num1 % num4 + \"\\n\");\n\n        ++num1;\n        --num2;\n        System.out.println(num1);\n        System.out.println(num2 + \"\\n\");\n\n        int num5 = 10, num6 = 10;\n\n        if (num5 == num6)\n            System.out.println(\"num5 y num6 son iguales\");\n        if (num5 != num1)\n            System.out.println(\"num5 y num1 son diferentes\");\n        if (num5 > num1)\n            System.out.println(\"num5 es mayor que num1\");\n        if (num1 < num5)\n            System.out.println(\"num1 es menor que num5\");\n        if (num5 >= num6)\n            System.out.println(\"num5 es mayor o igual num6\");\n        if (num6 <= num5)\n            System.out.println(\"num6 es menor o igual num5\\n\");\n        if (num1 == 11 && num5 == 10)\n            System.out.println(\"num1 es igual a 11 y num5 es igual a 10\");\n        if (num1 != 13 && num5 != 13)\n            System.out.println(\"num1 no es igual a 13 y num5 no es igual a 13\\n\");\n\n        for (int i = 0; i <= 5; i++)\n            System.out.println(\"i = \" + i);\n        System.out.println(\"\\n\");\n\n        // DIFICULTAD EXTRA (OPCIONAL)\n\n        int start = 10, end = 55;\n\n        while (start < end && start >= 10) {\n            if (start == 16 || start % 3 == 0)\n                ++start;\n            if (start <= end)\n                System.out.println(start);\n            ++start;\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/pguillo02.java",
    "content": "class pguill02{\n\n    public static void main(String[] args) {\n        //En java encontramos los operadores aritméticos y booleanos básicos\n\n        //Operadores aritméticos\n\n        int a = 10;\n        int b = 23;\n\n        System.out.println(\"Suma: \" + (a+b));\n        System.out.println(\"Resta: \" + (a-b));\n        System.out.println(\"Multiplicación: \" + (a*b));\n        System.out.println(\"División: \" + (a/b));\n        System.out.println(\"Resto: \" + (a%b));\n\n        //Operadores booleanos\n\n        boolean t = true;\n        boolean f = false;\n\n        System.out.println(\"AND: \" + (t && f));\n        System.out.println(\"OR: \" + (t || f));\n        System.out.println(\"NOT: \" + (!t));\n\n        //Operadores de comparación\n\n        System.out.println(\"Igual: \" + (a == b));\n        System.out.println(\"Distinto: \" + (a != b));\n        System.out.println(\"Mayor: \" + (a > b));\n        System.out.println(\"Menor: \" + (a < b));\n        System.out.println(\"Mayor o igual: \" + (a >= b));\n        System.out.println(\"Menor o igual: \" + (a <= b));\n        \n        //Operadores de asignación\n\n        System.out.println(\"Asignación: \" + (a = b));\n        System.out.println(\"Suma y asignación: \" + (a += b));\n        System.out.println(\"Resta y asignación: \" + (a -= b));\n        System.out.println(\"Multiplicación y asignación: \" + (a *= b));\n        System.out.println(\"División y asignación: \" + (a /= b));\n        System.out.println(\"Resto y asignación: \" + (a %= b));\n        System.out.println(\"AND y asignación: \" + (a &= b));\n        System.out.println(\"OR y asignación: \" + (a |= b));\n        System.out.println(\"XOR y asignación: \" + (a ^= b));\n        System.out.println(\"Desplazamiento a la izquierda y asignación: \" + (a <<= b));\n        System.out.println(\"Desplazamiento a la derecha y asignación: \" + (a >>= b));\n        System.out.println(\"Desplazamiento a la derecha sin signo y asignación: \" + (a >>>= b));\n\n        //Operadores de incremento y decremento\n\n        System.out.println(\"Pre-incremento: \" + (++a));\n        System.out.println(\"Post-incremento: \" + (a++));\n        System.out.println(\"Pre-decremento: \" + (--a));\n        System.out.println(\"Post-decremento: \" + (a--));\n        \n        //Operadores ternarios\n\n        System.out.println(\"Ternario: \" + (a > b ? a : b));\n        \n        //Estructuras de control\n\n        //Estructura if\n\n        if(a > b){\n            System.out.println(\"a es mayor que b\");\n        }else if(a < b){\n            System.out.println(\"a es menor que b\");\n        }else{\n            System.out.println(\"a es igual que b\");\n        }\n\n        //Bucle for\n\n\n        for(int i = 0; i < 10; i++){\n            System.out.println(\"i vale: \" + i);\n        }\n\n        //Bucle while\n\n        int i = 0;\n\n        while(i < 10){\n            System.out.println(\"i vale: \" + i);\n            i++;\n        }\n\n        for (int j = 10; j <= 55; j++) {\n            if(j % 2 == 0){\n                if(j%3 == 0){\n                    if (j != 16){\n                        System.out.println(j);\n                    }\n            }\n        }\n    }\n}\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/qv1ko.java",
    "content": "class Qv1ko {\n\n    public static void main(String[] args) {\n\n        double a = 3;\n        double b = 4;\n\n        System.out.println(\"Number A: \" + a);\n        System.out.println(\"Number B: \" + b);\n\n        double sum = a + b;\n        System.out.println(\"a + b = \" + sum);\n\n        double sub = a - b;\n        System.out.println(\"a - b = \" + sub);\n\n        double mul = a * b;\n        System.out.println(\"a * b = \" + mul);\n\n        double div = a / b;\n        System.out.println(\"a / b = \" + div);\n\n        double res = a % b;\n        System.out.println(\"a % b = \" + res);\n\n        a += b;\n        System.out.println(\"a += b\\t Number A: \" + a);\n\n        a -= b;\n        System.out.println(\"a -= b\\t Number A: \" + a);\n\n        a *= b;\n        System.out.println(\"a *= b\\t Number A: \" + a);\n\n        a /= b;\n        System.out.println(\"a /= b\\t Number A: \" + a);\n\n        a %= b;\n        System.out.println(\"a %= b\\t Number A: \" + a);\n\n        a++;\n        System.out.println(\"a++\\t Number A: \" + a);\n\n        b--;\n        System.out.println(\"b--\\t Number B: \" + b);\n\n        if (a == b) {\n            System.out.println(\"Number A equals number B\");\n        }\n\n        if (a == b) {\n            System.out.println(\"Number A equals number B\");\n        } else {\n            System.out.println(\"The number A is not equal to the number B\");\n        }\n\n        System.out.println((a != b) ? \"The number A is different from the number B\" : \"The number A is not different from the number B\");\n\n        if (a > b) {\n            System.out.println(\"The number A is greater than the number B\");\n        } else if (a < b) {\n            System.out.println(\"The number A is less than the number B\");\n        } else {\n            System.out.println(\"Number A equals number B\");\n        }\n\n        while (a > 0 && b > 0) {\n            System.out.println(\"Loop while\");\n            a--;\n        }\n\n        do {\n            System.out.println(\"Loop do while\");\n            a++;\n            b++;\n        } while (a < 3 || b < 0);\n\n        switch ((int)b) {\n            case 1:\n                System.out.println(\"Number B is 1\");\n                break;\n\n            case 2:\n                System.out.println(\"Number B is 2\");\n                break;\n\n            case 3:\n                System.out.println(\"Number B is 3\");\n                break;\n\n            case 4:\n                System.out.println(\"Number B is 4\");\n                break;\n\n            case 5:\n                System.out.println(\"Number B is 5\");\n                break;\n        \n            default:\n                break;\n\n        }\n\n        for (int i = 1; i <= 3; i++) {\n            System.out.println(\"Loop for \" + i);\n        }\n\n        for (Integer num : new int[]{1, 2, 3}) {\n            System.out.println(\"Loop for each \" + num);\n        }\n\n        try {\n            double z[] = new double[2]; \n            z[4] = a;\n        } catch (Exception e) {\n            System.out.println(\"Exception caught\");\n        }\n\n        program();\n\n    }\n\n    private static void program() {\n        System.out.println(\"\\nProgram:\\n\");\n        for (int i = 10; i <= 55; i++) {\n            if (i % 2 == 0 && i != 16 && i % 3 != 0) {\n                System.out.println(i);\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/rantamhack.java",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n */ \n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n*/\n\npublic class rantamhack01 {\n\n    public static void main(String[] args){\n\n\n    // OPERADORES ARITMETICOS\n    //toman los operadores que se le indican y realizan un cálculo matemático\n    \n    int suma = 3 + 5;\n    int resta = 5 - 3;\n    int multiplicacion = 5 * 3; \n    double division = 5 / 2;\n    double modulo = 10 % 3;  // Modulo es el resto que nos queda de la división en éste caso es 1\n    \n    // java no tiene sintaxis para elevar a una potencia. Lo hacemos usando la funcion math.pown\n\n    double potencia = Math.pow(10, 3);\n\n    System.out.println(suma);\n    System.out.println(resta);\n    System.out.println(multiplicacion);\n    System.out.println(division);\n    System.out.println(modulo);\n    System.out.println(potencia);\n\n    System.out.print(\"\\n\\n=======================================================================\\n\\n\");\n\n    // OPERADORES RELACIONALES\n    // Son los que relacionan dos elementos entre sí\n    \n    boolean compara = (5 > 3);      // Devuelve True si es verdadero \n    boolean compara1 = (5 >= 3);    // Devuelve True si es verdadero\n    boolean compara2 = (5 < 3);     // Devuelve True si es verdadero\n    boolean compara3 = (5 <= 3);     // Devuelve True si es verdadero\n    boolean compara4 = (5 == 3);     // Devuelve True solo si los dos operandos son iguales\n    boolean compara5 = (5 != 3);     // Devuelve True solo si los dos operandos son diferentes\n\n    System.out.println(compara);\n    System.out.println(compara1);\n    System.out.println(compara2);\n    System.out.println(compara3);\n    System.out.println(compara4);\n    System.out.println(compara5);\n\n    System.out.print(\"\\n\\n=======================================================================\\n\\n\");\n\n    // OPERADORES LOGICOS\n    // Se usan basandonos en condiciones\n\n    // El operando \"and\" devuelve True siempre que los dos operandos sean correctos\n    \n    System.out.println((3 + 2 == 5) && (7 * 2 == 14));\n    \n    // El operando \"or\" devuelve True siempre que uno de los dos operandos sea correcto\n    \n    System.out.println((3 + 2 == 5) || (7 * 2 == 10));\n    \n    // El operando \"not\" devuelve True siempre que uno de los dos operandos sea falso\n    \n    System.out.println(!(10 + 3 == 14));\n\n\n    System.out.print(\"\\n\\n=======================================================================\\n\\n\");\n\n\n    // OPERADORES DE ASIGNACION\n    // Son los que se usan para dar valor a una variable por ejemplo\n    \n   \n    double my_variable = 5;        // Asignación    \n    System.out.println(my_variable);\n\n    my_variable += 1 ;       // Suma y Asignación\n    System.out.println(my_variable);      \n\n    my_variable -= 1;        // Resta y Asignación\n    System.out.println(my_variable);      \n    \n    my_variable *= 2;        // Multiplicación y Asignación\n    System.out.println(my_variable);      \n\n    my_variable /= 2;        // División y Asignación\n    System.out.println(my_variable);      \n    \n    my_variable %= 3;        // Mòdulo y aAsignación\n    System.out.println(my_variable);    \n    \n    \n    System.out.println(\"\\n\\n=======================================================================\\n\\n\");\n\n\n    // ESTRUCTURAS DE CONTROL \n    // CONDICIONALES \n\n    String my_name = \"juan\";\n\n    if (my_name == \"luis\"){\n        System.out.println(\"mi nombre es luis\");\n    }\n    else if (my_name == \"juan\"){\n        System.out.println(\"mi nombre es juan\");\n    }\n    else{\n        System.out.println(\"mi nombre no sale en el programa\");\n    }\n\n    System.out.println(\"\\n\\n=======================================================================\\n\\n\");\n\n    // Condicional switch\n\n    String login = \"juan\";\n\n    switch(login) { \n        case \"luis\":\n            System.out.println(\"mi nombre es luis\");\n            break;\n        case \"juan\":\n            System.out.println(\"mi nombre es juan\");\n            break;\n        case \"\":\n            System.out.println(\"Por favor escribe un nombre valido\");\n            break;\n        default:\n            System.out.println(\"respuesta no valida\");\n            break;\n    }\n    \n    System.out.println(\"\\n\\n=======================================================================\\n\\n\");\n\n    // ESTRUCTURAS DE CONTROL \n    // ITERATIVAS\n\n    for (int i = 0; i < 10; i++){\n        System.out.println(i);\n    }\n    \n    System.out.println(\"\\n\\n=======================================================================\\n\\n\");\n\n    int n = 0;\n\n    while(n < 11){\n        System.out.println(n);\n        n++;\n    }\n\n    System.out.println(\"\\n\\n=======================================================================\\n\\n\");\n\n    int x = 0;\n    \n    do{\n        System.out.println(x);\n        x++;\n    }\n\n    while(x < 15);\n\n    \n    System.out.println(\"\\n\\n=======================================================================\\n\\n\");   \n    \n    \n    // ESTRUCTURAS DE CONTROL \n    // MANEJO DE EXCEPCIONES (simulacion dvision por cero)\n\n    int numerador = 10;\n    int denominador = 0;\n\n\n    try{\n        division = numerador / denominador;\n    }\n    catch (ArithmeticException ex){\n        division = 0;\n        System.out.println(\"Excepcion encontrada\"+ ex.getMessage());\n    }\n    finally{\n        System.out.println(\"No se puede hacer la division\");\n    }\n \n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/ricarditodev.java",
    "content": "public class ricarditodev {\n    public static void main(String[] args) {\n        //ejemplos utilizando todos los operadores de Java\n        //operadores aritméticos\n\n        //operador suma (adición)\n        int suma = 1 + 1;\n\n        //operador resta (sustracción)\n        int resta = 2 - 1;\n\n        //operador multiplicación\n        int multi = 2 * 2;\n\n        //operador división\n        int division = 10 / 5;\n\n        //operador módulo o resto (resto de la división)\n        double modulo = 11 % 5;\n\n        //operador incremento - incrementa el valor en 1\n        int incremento = ++suma;\n\n        //operador decremento - decrementa el valor en 1\n        int decremento = --suma;\n\n        //----------------------------------------------------------------------------\n\n        //operadores de asignación\n        //operador de asignación simple - asigna un valor o dato a una variable\n        double x = 5;\n\n        //operador suma y asigna - suma el valor de la variable con lo que está después del += y lo asigna a la misma variable\n        x += 3;\n\n        //operador resta y asigna - resta el valor de la variable con lo que está después del -= y lo asigna a la misma variable\n        x -= 1;\n\n        //operador múltiplica y asigna - ídem\n        x *= 5;\n\n        //operador división y asigna - ídem\n        x /=  2;\n\n        //operador módulo y asigna - ídem\n        x %= 5;\n\n        //----------------------------------------------------------------------------//\n\n        //operadores relacionales o de comparación - devuelve siempre un boolean (true o false)\n        //operador igual a\n        System.out.println(x == suma);\n\n        //operador diferente de\n        System.out.println(x != suma);\n\n        //operador mayor que\n        System.out.println(x > suma);\n\n        //operador menor que\n        System.out.println(x < suma);\n\n        //operador mayor o igual que\n        System.out.println(x >= suma);\n\n        //operador menor o igual que\n        System.out.println(x <= suma);\n\n        //----------------------------------------------------------------------------//\n\n        //operadores lógicos - siempre devuelve un boolean (true o false)\n        //operador AND (&&) retorna true solo si ambas condiciones son true\n        System.out.println(suma < 10 && resta < 10);\n\n        //operador OR (||) retorna true si al menos una condicion es true\n        System.out.println(suma > 0 || suma > 10);\n\n        //operador NOT (!) invierte el valor booleano\n        System.out.println(!(multi == 4 || multi > 0));\n\n        //----------------------------------------------------------------------------//\n\n        //operadores bit a bit (bitwise) - operan sobre los bits de enteros (no variables double ni float)\n        //operador AND (&) - compara cada bit de dos números, si ambos bits son 1 devuelve 1, sino devuelve 0\n        int a = 6; //110\n        int b = 3; //011\n        int c = a & b;\n        System.out.println(c);\n\n        //operador OR (|) - compara cada bit de dos números, si al menos un bit es 1 devuelve 1, si ambos son 0 devuelve 0\n        int aa = 6; //110\n        int bb = 3; //011\n        int cc = aa | bb;\n        System.out.println(cc); // 7 (111)\n\n        //operador XOR (^) (OR exclusivo) - compara cada bit de dos números y devuelve 1 si los bits son diferentes\n        int aaa = 6; //110\n        int bbb = 3; //011\n        int ccc = aaa ^ bbb;\n        System.out.println(ccc); // 5 (101)\n\n        //operador NOT (~) - invierte todos los bits de un número - para cualquier entero n lo converte en su opuesto menos 1 / -(n + 1)\n        int aNegativo = ~a; // 00000000 00000000 00000000 00000110 --> 11111111 11111111 11111111 11111001\n        // ~6 = -(6 + 1) = -7\n        System.out.println(aNegativo);\n\n        /*operador desplazamiento a la izquierda (<<)\n        mueve todos los bits de un número hacia la izquierda un número determinado de posiciones\n        los bits que se “abren” a la derecha se llenan con 0.\n        cada desplazamiento hacia la izquierda equivale a multiplicar por 2\n        n << 1  → n * 2\n        n << 2  → n * 4\n        n << 3  → n * 8\n        */\n\n        int tres = 3; // 3 en binario = 00000011\n        int ejemplo = tres << 2; // desplazamos 2 posiciones a la izquierda --> 00001100\n        System.out.println(ejemplo); // 00001100 == 12\n\n        /*operador desplazamiento a la derecha con signo (>>)\n        desplaza todos los bits hacia la derecha un número determinado de posiciones, el bit de signo (MSB) se mantiene y se copia a la izquierda\n        es decir, extiende el signo\n        matemáticamente, equivale a dividir entre 2^n y redondear hacia abajo (pero manteniendo el signo)\n         */\n\n        int veinte = 20; //20 = 00010100 en binario\n        int ejemploVeinte = veinte >> 2; // desplazamos 2 posiciones a la derecha --> 00000101\n        System.out.println(ejemploVeinte); //00000101 == 5\n\n        int veinteNegativo = -20; //-20 = 11101100 en binario\n        int  ejemploVeinteNegativo = veinteNegativo >> 2; //desplazamos 2 posiciones a la derecha --> 11111011\n        System.out.println(ejemploVeinteNegativo); //11111011 == -5\n\n        /*operador desplazamiento a la derecha sin signo (>>>)\n        desplaza todos los bits hacia la derecha un número determinado de posiciones\n        rellena con ceros a la izquierda, sin importar el signo\n        no conserva el bit de signo\n        eso significa que, si el número era negativo, se convierte en un número muy grande positivo\n        porque el bit más a la izquierda deja de ser 1 (negativo) y pasa a ser 0 (positivo)\n         */\n\n        int veinteNegativoSinSigno = -20; //11111111 11111111 11111111 11101100   → -20\n        int ejemploVeinteNegativoSinSigno = veinteNegativoSinSigno >>> 2; //desplazamos 2 posiciones a la derecha --> 00111111 11111111 11111111 11111011\n        System.out.println(ejemploVeinteNegativoSinSigno); //ya no representa un número negativo, sino un positivo muy grande = 00111111 11111111 11111111 11111011 == 1073741819\n\n        //----------------------------------------------------------------------------//\n\n        //operador condicional (ternario) - Una forma compacta de un if-else\n        //condicion ? valorSiTrue : valorSiFalse\n        int velocidad = 60;\n        String mensaje = velocidad > 100 ? \"reduce la velocidad\" : \"continúa manejando\";\n        System.out.println(mensaje);\n\n        //----------------------------------------------------------------------------//\n\n        //operadores instanceof y new\n        //instanceof → verifica si un objeto es de cierta clase\n        //new → crea un nuevo objeto\n        String s = new String(\"Hola\");\n        System.out.println(s instanceof String);\n\n        //----------------------------------------------------------------------------//\n\n        //ejemplos utilizando todas las estructuras de control de java\n        //estructuras condicionales\n        //estructura if\n        boolean estoyAprendiendo = true;\n\n        if (estoyAprendiendo) {\n            System.out.println(\"no pares de aprender\");\n        }\n\n        //estructura else\n        boolean noEstoyAprendiendo = true;\n\n        if (noEstoyAprendiendo) {\n            System.out.println(\"ponte a aprender ya!\");\n        } else {\n            System.out.println(\"no pares de aprender\");\n        }\n\n        //estructura else-if\n        boolean estoyAprendiendoPHP = false;\n        boolean estoyAprendiendoJava = true;\n\n        if (estoyAprendiendoPHP) {\n            System.out.println(\"mejor ponte a aprender Java :P\");\n        } else if (estoyAprendiendoJava) {\n            System.out.println(\"continúa aprendiendo Java\");\n        } else {\n            System.out.println(\"aprende algún lenguaje\");\n        }\n\n        //estructura switch\n        int dayOfTheWeek = 5;\n        switch (dayOfTheWeek) {\n            case 1:\n                System.out.println(\"Monday\");\n                break;\n            case 2:\n                System.out.println(\"Tuesday\");\n                break;\n            case 3:\n                System.out.println(\"Wednesday\");\n                break;\n            case 4:\n                System.out.println(\"Thursday\");\n                break;\n            case 5:\n                System.out.println(\"Friday\");\n                break;\n            case 6:\n                System.out.println(\"Saturday\");\n                break;\n            case 7:\n                System.out.println(\"Sunday\");\n                break;\n            default:\n                System.out.println(false);\n        }\n\n        //----------------------------------------------------------------------------//\n\n        //estructura iterativas\n        //estructura for\n        for (int i = 0; i < 5; i++) {\n            System.out.println(i);\n        }\n\n        //estructura while\n        int num = 5;\n        while (num > 0) {\n            System.out.println(num);\n            num--;\n        }\n\n        //estructura do-while - ejecuta el loop una vez antes de comprobar si la condición es verdadera\n        //si es verdadera sigue ejecutando el bucle hasta que sea falsa, y si al inicio es falsa de igual manera se ejecuta una vez\n        int n = 0;\n        do {\n            System.out.println(n);\n            n++;\n        } while (n <= 5);\n\n        //estructura for-each - para recorrer arrays o estructuras de datos\n        String[] seniority = {\"Junior\", \"Semi-Senior\", \"Senior\"};\n        for (String i : seniority) {\n            System.out.println(i);\n        }\n\n        //----------------------------------------------------------------------------//\n\n        //estructuras de salto\n        //estructura break - interrumpe un bucle o un switch\n        for (int i = 0; i <= 5; i++) {\n            if (i == 3) {\n                break;\n            }\n            System.out.println(i);\n        }\n\n        //estructura continue - salta a la siguiente iteración de un bucle, omitiendo el resto del código en la iteración actual\n        for (int i = 0; i <= 5; i++) {\n            if (i == 1) {\n                continue;\n            }\n            System.out.println(i);\n        }\n\n        //estructura return - termina la ejecución de un método y, opcionalmente, devuelve un valor\n\n\n        //----------------------------------------------------------------------------//\n\n        //programa que imprime por consola todos los números comprendidos\n        //entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\n        for (int i = 10; i <= 55; i++) {\n            if (i % 3 == 0) {\n                continue;\n            }\n\n            if (i == 16) {\n                continue;\n            }\n\n            if (i % 2 == 0) {\n                System.out.println(i);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/rocha30.java",
    "content": "/**\n * Solución del reto #01 #01 OPERADORES Y ESTRUCTURAS DE CONTROL\n * \n * @author rocha30\n */\n\npublic class rocha30 {\n\n    \n    public static void main(String[] args) {\n        /*Operadores aritméicos: estos pueden ser aplicados sobre números enteros o decimales (float)\n         * De estos hay dos tipos, que son los binarios y los unarios\n        */\n\n        //Operadores aritméticos binarios. \n        /*\n         * Suma (+)\n         * Resta (-)\n         * Multiplicación (*)\n         * División (/)\n         * Módulo (%) (Valor absoluto |x|)\n         */\n\n         int a = 10; \n         int b = 3; \n\n         System.out.println(\"Operadores aritméticos en binario.\");\n         System.out.println(\"Suma: \" + (a+b));\n         System.out.println(\"Resta: \"+ (a-b));\n         System.out.println(\"Multiplicación: \" + (a*b));\n         System.out.println(\"División: \" + (a/b));\n         System.out.println(\"Modulo (valor absoluto): \" + (a%b));\n\n         System.out.println();\n\n         /*\n          * Operadores unarios: \n          * Mantiene el signo del operando (+)\n          * Le cambia el signo del operando (-)\n          * Autoincremento de valor (++)\n          * Autodrcremento de valor (--)\n          */\n\n          System.out.println(\"\\nOperadores unarios. \");\n          System.out.println(\"Mantener el signo: \" + (+b));\n          System.out.println(\"Cambiar el signo : \"+ (-b));\n         System.out.println(\"Autoincremento : \" + (++b));\n         System.out.println(\"Autodecremento : \" + (--b));\n         System.out.println();\n\n\n\n         /*Operadores relacionales: para hacer comparaciones. \n          * Mayor que (>)\n          * Mayor igual que (>=)\n          * Menor que (<)\n          * Menor igual que <=\n          * Igual que (==)\n          * Distinto de (!=)\n          */\n\n          System.out.println(\"\\nOperadores relacionales: \");\n          System.out.println(\"¿3 es mayor que 10?\" + (b>a));\n          System.out.println(\"¿3 es mayor o igual que 10?\" + (b>=a));\n          System.out.println(\"¿3 es menor que 10?\" + (b<a));\n          System.out.println(\"¿3 es menor o igual que 10?\" + (b<a));\n          System.out.println(\"¿3 es menor o igual que 10?\" + (b<=a));\n          System.out.println(\"¿3 es igual que 10?\" + (b==a));\n          System.out.println(\"¿3 es distino de 10?\"+ (b!=a));\n          \n\n        /*\n         * Operador sobre cadena de caractéres (+): Sirven para concatenar cadenas de caracteres. \n         * \n         */\n\n         String txt1 = \"Hola \"; \n         String txt2 = \"Mundo\"; \n\n         System.out.println(\"\\nOperadores sobre cadena de caractáres: \");\n         System.out.println(txt1+txt2);\n\n\n         /*\n          * Operadores de asignación y lógicos: para darle un valor a una variable: \n          * +=: Suma la variable y sobre escirbe el valor de la variable con el resultado \n          * -=: Resta la variable y sobre escribe el valor de la variable con el resultado\n          * *=: Multiplica la variable y sobre escrible el valor de la variable con el resultado\n          * /=: Divide la variable y sobre escribe el valor de la variable con el resultado\n          * %=: hace el modulo de la variable y sobre escribe el valor de la variable con el resultado \n          * &=: Hace un AND lógico a la variable y sobre escribe el valor de la variable con el resultado. tambien se puede usar (x && y:)\n          * |=: Hace un OR lógico a la variable y sobre escribe el valor de la variable con el resultado. tambien se puede usar (x || y:)\n          * !=: Hace un NOT lógico a a la variable y sobre escribe el valor de la variable con el resultado. tambien se puede usar (!x:)\n          */\n\n          int i; \n          boolean t = true; \n\n          System.out.println(\"Operadores de asignación: para darle un valor a una variable:\");\n          System.out.println(\"Se le da un valor a la variable i = \" + (i=1));\n          System.out.println(\"Sumar y asignar: \" + (i+=2));\n          System.out.println((\"Resta y asignar: \" + (i-=2)));\n          System.out.println(\"Multiplicar y asignar: \" + (i*=2));\n          System.out.println((\"Dividir y asignar: \" + (i/=2)));\n          System.out.println(\"Modulo y asigna \" + (i%=2));\n          System.out.println(\"AND logico \" + (t&=true));\n          System.out.println(\"OR logico \"+ (t|=false));\n          System.out.println(\"NOT logico y asignar \" + (t!=true));\n\n        \n\n          /*Operadores de bits \n           * Tipos: \n           * AND(&): Operador AND a nivel de bits (1 y 1 = 1 )\n           * OR (|): Operador OR a nivel de bits (1 ó 1 = 1)\n           * XOR (^): Operador XOR a nivel de bits (1 y 1 = 0 )\n           * Complemento (~): Invierte el valor de cada bit \n           * >>: Desplaza cada bit a la derecha \n           * <<: Desplaza bits a la izquierda \n           * >>>: Desplaza bits a la derecha sin signo\n           */\n\n           System.out.println(\"\\nOperadores de bits \");\n\n           System.out.println(\"a : \" + Integer.toBinaryString(a));\n           System.out.println(\"b : \" + Integer.toBinaryString(b));\n\n           System.out.println(\"\\n b AND a: \" + Integer.toBinaryString(a&b));\n           System.out.println(\" b OR a : \" + Integer.toBinaryString(a|b));\n           System.out.println(\" b XOR a: \" + Integer.toBinaryString(a^b));\n           System.out.println(\"Complemento de a = \" + Integer.toBinaryString(~a));\n           System.out.println(\"Complemento de b = \" + Integer.toBinaryString(~b));\n           System.out.println(\"Desplazamiento de bits de a a la derecha de b : \" + Integer.toBinaryString(a>>b));\n           System.out.println(\"Desplazamiento de bits de a a la izquierda de b: \" + Integer.toBinaryString(a<<b));\n           System.out.println(\"Desplazamieto de bits de a a la derecha de b (sin signo): \" + Integer.toBinaryString(a>>>b));\n\n\n\n           /*\n            * Estructura switch \n            * sirve para verificar cada caso dependiendo de la variable que se le ingrese \n            */\n\n            int dia = 3; \n            switch (dia) {\n                case 1:\n                    System.out.println(\"\\nLunes \");\n                    \n                    break;\n                case 2: \n                    System.out.println(\"\\nMartes\");\n                    break; \n                case 3 : \n                    System.out.println(\"\\nMiercoles\");\n                    break; \n                case 4: \n                    System.out.println(\"\\nJueves\");\n                    break; \n                case 5: \n                    System.out.println(\"\\nViernes\");\n                    break; \n                case 6: \n                    System.out.println(\"\\nSabado\");\n                    break; \n                case 7: \n                    System.out.println(\"\\nDomingo\");\n                    break; \n            \n                default:\n                    System.out.println(\"\\nEl numero del dia de la semana no es valido\");\n                    break;\n            }\n           /* DIFICULTAD EXTRA (opcional):\n           * Crea un programa que imprima por consola todos los números comprendidos\n           * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n           *\n           * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n           */\n           System.out.println(\"\\n--------------------------\");\n           System.out.println(\" \\n Programa extra: \");\n           System.out.println(\"---------------------------\");\n           System.out.println(\"\\n Estos son los numeros: \");\n\n           for (int h = 10; h<=55; h++){\n            if (h%2==0 && h!= 16 && h%3!=0){\n                System.out.println(h);\n            }\n           }\n\n\n\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/rumacar05.java",
    "content": "public class rumacar05 {\n    /*\n    * EJERCICIO:\n    * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n    *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n    *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n    * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n    *   que representen todos los tipos de estructuras de control que existan\n    *   en tu lenguaje:\n    *   Condicionales, iterativas, excepciones...\n    * - Debes hacer print por consola del resultado de todos los ejemplos.\n    *\n    * DIFICULTAD EXTRA (opcional):\n    * Crea un programa que imprima por consola todos los números comprendidos\n    * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n    *\n    * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n    */\n\n    public static void main(String[] args) {\n        // Operadores aritméticos\n        System.out.println(\"Suma: 4 + 5 = \" + (4 + 5));\n        System.out.println(\"Resta: 10 - 5 = \" + (10 -5));\n        System.out.println(\"Division: 4 / 2 = \" + (4 / 2));\n        System.out.println(\"Multiplicación: 8 * 2 = \" + (8 * 2));\n        System.out.println(\"Resto: 7 % 2 \" + (7 % 2));\n\n        // Operadores de comparación\n        System.out.println(\"Igualdad: 20 == 5 es \" + (20 ==5));\n        System.out.println(\"Desigualdad: 20 != 5 es \" + (20 != 5));\n        System.out.println(\"Mayor que: 20 > 5 es \" + (20 > 5));\n        System.out.println(\"Menor que: 20 < 5 es \" + (20 < 5));\n        System.out.println(\"Mayor o igual que: 20 >= 5 es \" + (20 >= 5));\n        System.out.println(\"Menor o igual que: 20 <= 5 es \" + (20 <= 5));\n\n        // Operadores lógicos\n        System.out.println(\"AND &&: 20 + 2 == 22 && 4 - 2 == 2 es \" + (20 + 2 == 22 && 4 - 2 == 2));\n        System.out.println(\"OR ||: 20 + 2 == 22 || 4 - 2 == 2 es \" + (20 + 2 == 22 || 4 - 2 == 2));\n        System.out.println(\"NOT !: 20 + 2 == 22 es \" + !(20 + 2 == 22));\n\n        // Operadores de asignación\n        int myNumber = 10; // Asignación\n        System.out.println(myNumber);\n        myNumber += 2; // Suma y asignación\n        System.out.println(myNumber);\n        myNumber -= 4; // Resta y asignación\n        System.out.println(myNumber);\n        myNumber *= 4; // Multiplicación y asignación\n        System.out.println(myNumber);\n        myNumber /= 2; // División y asignación\n        System.out.println(myNumber);\n        myNumber %= 2; // Resto y asignación\n        System.out.println(myNumber);\n\n        // Operadores de bits\n        int a = 5;\n        int b = 3;\n        System.out.println(\"AND: 5 & 3 = \" + (a & b));\n        System.out.println(\"XOR: 5 ^ 3 = \" + (a ^ b));\n        System.out.println(\"OR: 5 | 3 = \" + (a | b));\n        System.out.println(\"NOT: ~5 = \" + (~a));\n        System.out.println(\"Desplazamion a la izquierda: 5 << 3 = \" + (5 << 3));\n        System.out.println(\"Desplazamion a la derecha: 5 >> 3 = \" + (5 >> 3));\n\n        // Condicionales\n        myNumber = 10;\n\n        if (myNumber == 0) {\n            System.out.println(\"myNumber es 0\");\n        } else if (myNumber % 2 == 0) {\n            System.out.println(\"myNumber es par\");\n        } else {\n            System.out.println(\"myNumber no es par ni 0\");\n        }\n\n        // Ternarios\n        System.out.println(myNumber % 2 == 0 ? \"Es un número par\" : \"Es un número impar\");\n\n        // Iterativos\n        for (int i = 0; i <= 10; i++) {\n            System.out.println(i);\n        }\n\n        int i = 0;\n        while (i <= 10) {\n            System.out.println(i);\n            i++;\n        }\n\n        i = 0;\n        do {\n            System.out.println(i);\n            i++;\n        } while (i <= 10);\n\n\n        // Excepciones\n        try {\n            System.out.println(10 / 0);\n        } catch (Exception ex) {\n            System.out.println(\"Se ha producido una excepción\");\n        } finally {\n            System.out.println(\"Ha terminado el manejo de la excepción\");\n        }\n\n        // Dificultad extra\n        for (int i = 10; i <= 55; i++) {\n            if (i % 2 == 0 && i != 16 && i % 3 != 0) {\n                System.out.println(i);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/sergiopq.java",
    "content": "public class sergiopq {\n    public static void main(String[] args) {\n\n        // Arithmetic operations (Sum, Subtract, Multiplication, Division, Remainder)\n        System.out.println(\"=== Arithmetic operations ===\");\n        int a = 10;\n        int b = 5;\n    \n        // Sum\n        int sum = a + b;\n            System.out.println(\"The sum is: \" + sum);\n    \n        // Subtract\n        int subtract = a - b;\n            System.out.println(\"The subtract is: \" + subtract);\n    \n        // Multiplication\n        int multiplication = a * b;\n            System.out.println(\"The multiplication is: \" + multiplication);\n    \n        // Division\n        int division = a / b;\n            System.out.println(\"The division is: \" + division);\n    \n        // Remainder\n        int remainder = a % b;\n            System.out.println(\"The remainder is: \" + remainder);\n\n\n\n        // Logical operations (AND, OR, NOT)\n        System.out.println(\"\\n=== Logical operations ===\");\n\n        // AND\n        boolean and = true && false;\n            System.out.println(\"The AND is: \" + and);\n\n        // OR\n        boolean or = true || false;\n            System.out.println(\"The OR is: \" + or);\n\n        // NOT\n        boolean not = !true;\n            System.out.println(\"The NOT is: \" + not);\n\n\n\n        // Comparison operations (Equal, Not equal, Greater than, Less than, Greater than or equal, Less than or equal)\n        System.out.println(\"\\n=== Comparison operations ===\");\n\n        // Equal\n        boolean equal = a == b;\n            System.out.println(\"The equal is: \" + equal);\n\n        // Not equal\n        boolean notEqual = a != b;\n            System.out.println(\"The not equal is: \" + notEqual);\n\n        // Greater than\n        boolean greaterThan = a > b;\n            System.out.println(\"The greater than is: \" + greaterThan);\n\n        // Less than\n        boolean lessThan = a < b;\n            System.out.println(\"The less than is: \" + lessThan);\n\n        // Greater than or equal\n        boolean greaterThanOrEqual = a >= b;\n            System.out.println(\"The greater than or equal is: \" + greaterThanOrEqual);\n\n        // Less than or equal\n        boolean lessThanOrEqual = a <= b;\n            System.out.println(\"The less than or equal is: \" + lessThanOrEqual);\n\n\n\n        // Bitwise operations (AND, OR, XOR, NOT, Right shift, Left shift, Unsigned right shift)\n        System.out.println(\"\\n=== Bitwise operations ===\");\n\n        // Bitwise AND\n        int bitwiseAnd = a & b;\n            System.out.println(\"The bitwise AND is: \" + bitwiseAnd);\n\n        // Bitwise OR\n        int bitwiseOr = a | b;\n            System.out.println(\"The bitwise OR is: \" + bitwiseOr);\n\n        // Bitwise XOR\n        int bitwiseXor = a ^ b;\n            System.out.println(\"The bitwise XOR is: \" + bitwiseXor);\n\n        // Bitwise NOT\n        int bitwiseNot = ~a;\n            System.out.println(\"The bitwise NOT is: \" + bitwiseNot);\n\n        // Right shift\n        int rightShift = a >> 2;\n            System.out.println(\"The right shift is: \" + rightShift);\n\n        // Left shift\n        int leftShift = a << 2;\n            System.out.println(\"The left shift is: \" + leftShift);\n\n        // Unsigned right shift\n        int unsignedRightShift = a >>> 2;\n            System.out.println(\"The unsigned right shift is: \" + unsignedRightShift);\n\n\n\n        // Assignment operations (Simple, Sum, Subtraction, Multiplication, Division, Remainder, Bitwise AND, Bitwise OR, Bitwise XOR, Right shift, Left shift, Unsigned right shift)\n        System.out.println(\"\\n=== Assignment operations ===\");\n\n        // Simple assignment\n        int simpleAssignment = a;\n            System.out.println(\"The simple assignment is: \" + simpleAssignment);\n\n        // Sum assignment\n        int sumAssignment = a;\n        sumAssignment += 3;\n            System.out.println(\"The sum assignment is: \" + sumAssignment);\n\n        // Subtraction assignment\n        int subtractionAssignment = a;\n        subtractionAssignment -= 2;\n            System.out.println(\"The subtraction assignment is: \" + subtractionAssignment);\n\n        // Multiplication assignment\n        int multiplicationAssignment = a;\n        multiplicationAssignment *= 2;\n            System.out.println(\"The multiplication assignment is: \" + multiplicationAssignment);\n\n        // Division assignment\n        int divisionAssignment = a;\n        divisionAssignment /= 2;\n            System.out.println(\"The division assignment is: \" + divisionAssignment);\n\n        // Remainder assignment\n        int remainderAssignment = a;\n        remainderAssignment %= 2;\n            System.out.println(\"The remainder assignment is: \" + remainderAssignment);\n\n        // Bitwise AND assignment\n        int bitwiseAndAssignment = a;\n        bitwiseAndAssignment &= 2;\n            System.out.println(\"The bitwise AND assignment is: \" + bitwiseAndAssignment);\n\n        // Bitwise OR assignment\n        int bitwiseOrAssignment = a;\n        bitwiseOrAssignment |= 2;\n            System.out.println(\"The bitwise OR assignment is: \" + bitwiseOrAssignment);\n\n        // Bitwise XOR assignment\n        int bitwiseXorAssignment = a;\n        bitwiseXorAssignment ^= 2;\n            System.out.println(\"The bitwise XOR assignment is: \" + bitwiseXorAssignment);\n\n        // Right shift assignment\n        int rightShiftAssignment = a;\n        rightShiftAssignment >>= 2;\n            System.out.println(\"The right shift assignment is: \" + rightShiftAssignment);\n\n        // Left shift assignment\n        int leftShiftAssignment = a;\n        leftShiftAssignment <<= 2;\n            System.out.println(\"The left shift assignment is: \" + leftShiftAssignment);\n\n        // Unsigned right shift assignment\n        int unsignedRightShiftAssignment = a;\n        unsignedRightShiftAssignment >>>= 2;\n            System.out.println(\"The unsigned right shift assignment is: \" + unsignedRightShiftAssignment);\n\n\n\n        // Operators\n        System.out.println(\"\\n=== Operators ===\");\n\n        // if\n        if (a > b) {\n            System.out.println(\"a is greater than b\");\n        }\n\n        // if else\n        if (a > b) {\n            System.out.println(\"a is greater than b\");\n        } else {\n            System.out.println(\"a is less than b\");\n        }\n\n        // switch\n        int day = b ;\n        switch (day) {\n            case 1:\n                System.out.println(\"Monday\");\n                break;\n            case 2:\n                System.out.println(\"Tuesday\");\n                break;\n            case 3:\n                System.out.println(\"Wednesday\");\n                break;\n            case 4:\n                System.out.println(\"Thursday\");\n                break;\n            case 5:\n                System.out.println(\"Friday\");\n                break;\n            default:\n                System.out.println(\"Invalid day\");\n                break;\n        }\n\n        // for\n        for (int i = 0; i < b; i++) {\n            System.out.println(\"The value of i is \" + i);\n        }\n\n        // while\n        int num = 0;\n        while (num < b) {\n            System.out.println(num);\n            num++;\n            if (num == 5) {\n                break;\n            }\n        }\n\n        // do while\n        int num2 = a;\n        do {\n            System.out.println(num2);\n            num2--;\n        } while (num2 > 10);\n\n\n\n        // Extra difficulty\n        System.out.println(\"\\n=== Extra difficulty ===\");\n\n        for(int i = 10; i <= 55; i++) {\n            if (i % 2 == 0 && i != 16 && i % 3 != 0) {\n                System.out.println(i);\n            }\n        }\n    } \n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/simonguzman.java",
    "content": "import java.util.List;\n\npublic class simonguzman {\n    public static void main(String[] args){\n     \n        int number1 = 10;\n        int number2 = 2;\n        int i = 3;\n        int result = +1;\n        int bitMask = 0x000F;\n        int val = 0x2222;\n        String firstString = \"This is\";\n        String secondString = \" a concatenated string.\";\n        String thirdString = firstString + secondString;\n\n        //Aritmetics operators\n        System.out.println(\"10 + 2 = \"+ (number1 + number2));\n        System.out.println(\"10 - 2 = \"+ (number1 - number2));\n        System.out.println(\"10 * 2 = \"+ (number1 * number2));\n        System.out.println(\"10 % 2 = \"+ (number1 % number2));\n        System.out.println(\"10 / 2 = \"+ (number1 / number2));\n        System.out.println(\"firstString + secondString = \"+thirdString);\n\n        //Unary operators\n        //Result is 1\n        System.out.println(result);\n        result--;\n        //Result is 0\n        result++;\n        //Result is 1\n        System.out.println(result);\n        result = -result;\n        //Result is -1\n        System.out.println(result);\n\n        boolean success = false;\n        //false\n        System.out.println(success);\n        //true\n        System.out.println(!success);\n        i++;\n        // prints 4\n        System.out.println(i);\n        ++i;\n        // prints 5\n        System.out.println(i);\n        // prints 6\n        System.out.println(++i);\n        // prints 6\n        System.out.println(i++);\n        // prints 7\n        System.out.println(i);\n\n        //Equality and relational operators\n        boolean equal = number1 == number2;\n        System.out.println(\"The equaly is: \"+ equal);\n        boolean notEqual = number1 != number2;\n        System.out.println(\"the not equaly is: \"+ notEqual);\n        boolean greaterThan = number1 > number2;\n        System.out.println(\"the greater than is: \"+ greaterThan);\n        boolean greaterThanOrEqual = number1 >= number2;\n        System.out.println(\"The greater than or equal is: \"+ greaterThanOrEqual);\n        boolean lessThan = number1 < number2;\n        System.out.println(\"The less than is: \"+ lessThan);\n        boolean lessThanOrEqual = number1 <= number2;\n        System.out.println(\"The less than or equal is: \"+ lessThanOrEqual);\n\n        //Conditional operators\n        boolean ConditionalAnd = number1 == 10 && number2 == 2;\n        System.out.println(ConditionalAnd);\n        boolean ConditionalOr = number1 == 9 || number2 ==2;\n        System.out.println(ConditionalOr);\n        boolean ConditionalNot = !ConditionalOr;\n        System.out.println(ConditionalNot);\n\n        //Bitwise and Bit Shift operators\n        // print 2\n        System.out.println(val & bitMask);\n\n\n        //Control structures\n        //if\n\n        int testScore = 76;\n        if(testScore >= 70){\n            System.out.println(\"Aproved test score\");\n        }\n\n        //ifelse\n        if(testScore >= 70){\n        System.out.println(\"Aproved test score\");\n        }else{\n            System.out.println(\"Disaproved test\");\n        }\n\n        //ifelseif\n        char grade;\n        if (testScore >= 90){\n            grade = 'A';\n        }else if (testScore >= 80){\n            grade = 'B';\n        }else if (testScore >= 70){\n            grade = 'C';\n        }else if (testScore >= 60){\n            grade = 'D';\n        }else{\n            grade = 'F';\n        }\n        System.out.println(\"Grade of the test is: \" + grade);\n       \n        //While\n        int count = 1;\n        while(count < 11){\n            System.out.println(\"Number: \"+count);\n            count++;\n        }\n\n        //DoWhile\n        int count2 = 1;\n        do{\n            System.out.println(\"Count is: \"+count2);\n            count2++; \n        }while(count2 < 11);\n\n        //For\n        for (int j = 0; j < 11; j++){\n            System.out.println(\"Count is: \"+j);\n        }\n\n        //Alternatives to for\n        int[] numbers =\n             {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};\n         for (int item : numbers) {\n             System.out.println(\"Count is: \" + item);\n         }\n\n         //For each\n         List<String> names = List.of(\"Jack\", \"Paula\", \"Kate\", \"Peter\");\n         for(String name:names){\n            System.out.println(name);\n         }\n\n         //Switch\n         int month = 8;\n         String futureMonths;\n         switch (month) {\n            case 0: System.out.println(\"January\"); break;\n            case 1: System.out.println(\"February\"); break;\n            case 2: System.out.println(\"March\"); break;\n            case 3: System.out.println(\"April\"); break;\n            case 4: System.out.println(\"May\"); break;\n            case 5: System.out.println(\"June\"); break;\n            case 6: System.out.println(\"July\"); break;\n            case 7: System.out.println(\"August\"); break;\n            case 8: System.out.println(\"September\"); break;\n            case 9: System.out.println(\"October\"); break;\n            case 10: System.out.println(\"November\"); break;\n            case 11: System.out.println(\"December\"); break;\n            default:\n            System.out.println(\"Invalid month\");\n                break;\n         }\n\n\n         /*Ejercicio practico\n          * Crea un programa que imprima por consola todos los números comprendidos\n          * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n         */\n\n         for (int n = 10; n < 56; n++){\n            if( ((n % 2) == 0 ) && (n != 16) && (n % 3 != 0)){\n                System.out.println(n);\n            }\n         }\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/sniker1223.java",
    "content": "import java.util.Arrays;\nimport java.util.List;\n\npublic class sniker1223 {\n\n  public static void main(String[] args) {\n    int i = 10;\n    int x = 12;\n    String name = \"Sara\";\n\n    // Arithmetic Operators\n    System.out.println(\"Arithmetic Operators\");\n    System.out.println(\"+ Addition: \" + (1 + 2));\n    System.out.println(\"- Substraction: \" + (1 - 2));\n    System.out.println(\"* Multiplication: \" + (1 * 2));\n    System.out.println(\"/ Division: \" + (1 / 2));\n    System.out.println(\"% Modulus: \" + (1 % 2));\n    System.out.println(\"++ Increment: \" + (++i));\n    System.out.println(\"-- Decrement: \" + (--i));\n\n    // Assignment Operators\n    System.out.println(\"\\nAssignment Operators\");\n    System.out.println(\"= Assigment: i = \" + i);\n    System.out.println(\"+= Addition assigment: i += \" + (i += 2));\n    System.out.println(\"-= Substraction assigment: i -= \" + (i -= 2));\n    System.out.println(\"*= Multiplication assigment: i *= \" + (i *= 2));\n    System.out.println(\"/= Division assigment: i /= \" + (i /= 2));\n    System.out.println(\"%= Modulus assigment: i %= \" + (i %= 7));\n    System.out.println(\"&= Bitwise AND assigment: i &= \" + (i &= 12));\n    System.out.println(\"|= Bitwise OR assigment: i |= \" + (i |= 4));\n    System.out.println(\"^= Bitwise XOR assigment: i ^= \" + (i ^= 8));\n    System.out.println(\">>= right shift assigment: i >>= \" + (i >>= 1));\n    System.out.println(\"<<= left shift assigment: i <<= \" + (i <<= 1));\n\n    // Comparison Operators\n    System.out.println(\"\\nComparison Operators\");\n    System.out.println(\"> Greater than: \" + i + \"  > \" + x + \" = \" + (i > x));\n    System.out.println(\"> Less than: \" + i + \"  < \" + x + \" = \" + (i < x));\n    System.out.println(\"== Equal to: \" + i + \"  == \" + x + \" = \" + (i == x));\n    System.out.println(\"!= Equal to: \" + i + \"  != \" + x + \" = \" + (i != x));\n    System.out.println(\">= Greater than: \" + i + \"  >= \" + x + \" = \" + (i >= x));\n    System.out.println(\"<= Less than: \" + i + \"  <= \" + x + \" = \" + (i <= x));\n\n    // Logical Operators\n    System.out.println(\"\\nLogical Operators\");\n    System.out.println(\"&& Logical AND: \" + x + \" < 5 && \" + x + \" < 10\" + \" = \" + (x < 5 && x < 10));\n    System.out.println(\"||  Logical OR: \" + x + \" < 5 || \" + x + \" < 20\" + \" = \" + (x < 5 || x < 20));\n    System.out.println(\"!  Logical NOT: !(\" + x + \" < 5 && \" + x + \" < 10)\" + \" = \" + !(x < 5 || x < 10));\n\n    // Miscellaneous Operators\n    System.out.println(\"\\nMiscellaneous Operators\");\n    System.out.println(\"?: Ternary operator: (\" + i + \" == 1 ? 20 : 30 value of i is : \" + ((i == 1) ? 20 : 30));\n    System.out.println(\"instanceof Instanceof operator: \" + name + \" instanceof String  = \" + (name instanceof String));\n\n    // CONTROL STRUCTURES\n    System.out.println(\"\\nCONTROL STRUCTURES\");\n    // If/Else/Else If\n    System.out.println(\"If/Else/Else If\");\n    if (i > 2) {\n      System.out.println(i + \" is higher than 2\");\n    } else {\n      System.out.println(i + \" is lower or equal than 2\");\n    }\n    // Switch\n    System.out.println(\"\\nSwitch\");\n    i = 3;\n    switch (i) {\n      case 0:\n        System.out.println(i + \" is equal to 0\");\n        break;\n      case 1:\n        System.out.println(i + \" is equal to 1\");\n        break;\n      default:\n        System.out.println(i + \" is either negative, or higher than 1\");\n        break;\n    }\n\n    // Loops\n    System.out.println(\"\\nLoops\");\n    System.out.println(\"for\");\n    for (int a = 1; a <= 10; a++) {\n      System.out.println(a);\n    }\n    System.out.println(\"\\nwhile\");\n    while (i <= 10) {\n      System.out.println(i);\n      i++;\n    }\n\n    // Break with foreach\n    System.out.println(\"\\nBreak\");\n    List<String> names = Arrays.asList(\"Sara\", \"Selena\");\n    String nameBreak = \"Sara\";\n    for (String cadena : names) {\n      if (cadena.equals(nameBreak)) {\n        System.out.println(cadena);\n        break;\n      }\n\n    }\n\n    // Challenge. Print numbers between 10 and 55(included), even and odd but not\n    // print 16 and multiple of 3.\n    int n;\n    for (n = 0; n <= 55; n++) {\n      if (n >= 10 && n % 2 == 0 && n != 16 && !(n % 3 == 0) || n == 55) {\n        System.out.println(n);\n      }\n    }\n  }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/swifty0705.java",
    "content": "package com.mouredev.retosprogramacion.roadmap.uno;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class swifty0705 {\n    public static void main(String[] args) {\n        int a = 1;\n        int b = 2;\n        int c = 2;\n\n        //comparación\n        System.out.println( \"a es igual a b?: \" + (a == b));\n        System.out.println( \"a es diferente de b?: \" + (a != b));\n\n        System.out.println( \"a es mayor a b?: \" + (a > b));\n        System.out.println( \"a es menor a b?: \" + (a < b));\n\n        System.out.println( \"b es mayor o igual a c?: \" + (b >= c));\n        System.out.println( \"b es menor o igual a c?: \" + (b <= c));\n\n        //Aritmeticos\n        a +=b;\n        System.out.println(\"la suma de a + b es\" +a);\n        a -= b;\n        System.out.println(\"la resta de a - b es\" +a);\n        a *=b;\n        System.out.println(\"la multiplicación de a * b es\" +a);\n        a /= c;\n        System.out.println(\"la division de a / c es\" +a);\n        a %= c;\n        System.out.println(\"el modulo de a % c es\" +a);\n\n        //logicos\n        System.out.println(\"Ambas son verdad?\" + ( (a == b) && (a != b) ) );\n        System.out.println(\"Alguna es verdadera\" + ( (a == b) || (a != b) ) );\n        System.out.println(\"Esta es de verdad?\" + ( (a == b) ) );\n        System.out.println(\"y con este cambio\" + ( !(a == b) ) );\n\n        //Asignación\n        System.out.println(\"el valor actual de c es \"+ c);\n        c++;\n        System.out.println(\"el valor actual de c es \"+ c);\n\n        //identidad\n        /*\n         instanceof se puede usar\n         el operador de comparación == tambien\n         */\n\n        //pertinencia, no existe tal cual pero con librerias es posible usarlo. es \"contains\" en List\n\n        List<String> frutas = new ArrayList<>();\n        frutas.add(\"manzana\");\n        frutas.add(\"naranja\");\n        frutas.add(\"pera\");\n\n        System.out.println(frutas.contains(\"manzana\")); // Imprime \"true\"\n        System.out.println(frutas.contains(\"uva\")); // Imprime \"false\"\n\n        //\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/vixxtory.java",
    "content": "import org.w3c.dom.ls.LSOutput;\n\nimport java.util.InputMismatchException;\nimport java.util.Scanner;\n\npublic class vixxtory {\n    /**\n     * OPERADORES EN JAVA\n     * Permiten realizar diversas operaciones y manipulaciones de datos y variables como:\n     * Cálculos matemáticos\n     * Evaluaciones de condiciones lógicas\n     * Manipulación de datos a nivel de bits.\n     * **/\n\n    public static void main(String[] args) {\n\n        /** Los operadores aritméticos permiten realizar cálculos matemáticos.\n         * Fundamental para aplicaciones financieras, científicas o de ingeniería.\n         * **/\n\n        /** OPERADORES ARITMETICOS **/\n        byte suma = 10 + 10;\n        byte resta = 10 - 8;\n        byte multiplicacion = 10 - 8;\n        byte division = 15 / 5;\n        byte modulo = 10 % 2;\n        System.out.println(\"Suma 10 + 10 \" + suma);\n        System.out.println(\"Resta 10 - 8 = \" + resta);\n        System.out.println(\"Multiplicación 10 * 10 = \" + multiplicacion);\n        System.out.println(\"División 15 / 5 = \" + division);\n        System.out.println(\"Modulo 10 % 2 = \" + modulo);\n\n        /** Los operadores de asignación permiten asignar valores a variables y actualizarlos,\n         * lo que facilita la manipulación de datos y el seguimiento de estados. **/\n\n        /** OPERADORES DE ASIGNACION **/\n        System.out.println(\"Igualdad = \");\n        //Compuestos\n        System.out.println(\" Suma y asignación += \");\n        System.out.println(\" Resta y asignación -= \");\n        System.out.println(\" Multiplicación y asignación *= \");\n        System.out.println(\" Division y asignación /= \");\n        System.out.println(\" Modulo y asignacion %/ \");\n\n        /** Los operadores de comparación y lógicos son esenciales para tomar decisiones basadas en condiciones.\n         *  Estos operadores permiten crear lógica condicional, fundamental para el flujo de un programa. **/\n\n        /** OPERADORES DE COMPARACIÓN\n         * Devuelven verdadero o falso\n         * **/\n        System.out.println(\" Igual a == \");\n        System.out.println(\" Diferente de != \");\n        System.out.println(\" Mayor que > \");\n        System.out.println(\" Menor que < \");\n        System.out.println(\" Mayor o igual que >= \");\n        System.out.println(\" Menor o igual que <= \");\n\n        /** OPERADORES LOGICOS\n         * Evalúan una expresión de uno o dos operandos con valor de tipo boolean y devuelven otro boolean\n         * **/\n        System.out.println(\" AND && \");\n        System.out.println(\" OR || \");\n        System.out.println(\" NOT ! \");\n\n        /** Las operaciones sobre bits son útiles en situaciones donde se necesita manipular o extraer\n         * datos específicos de un número entero representado en bits.\n         * Por ejemplo, para manipular colores en gráficos o para realizar cálculos en algoritmos de criptografía.\n         **/\n\n        System.out.println(\" Desplazamiento a la izquierda << \");\n        System.out.println(\" Desplazamiento a la derecha >> \");\n        System.out.println(\" AND a nivel de bits & \");\n        System.out.println(\" OR a nivel de bits | \");\n\n        /** ESTRUCTURAS DE CONTROL\n         * Se usan para modificar el flujo secuencial de un programa.**/\n\n        //CONDICIONALES\n\n        byte x = 0;\n\n        if (x == 1) System.out.println(\"x es igual a 1\");\n        else if (x == 0) System.out.println(\"x es igual a 0\");\n        else System.out.println(\"x no es ni 0 ni 1\");\n\n\n        // SWITCH: compara una variable con una lista y ejecuta el código correspondiente al caso que coincida\n        switch (x) {\n            case 1:\n                System.out.println(\"La variale tiene valor 1\");\n                break; //sale de un bucle o estructura de control de selección antes de que se complete\n            case 2:\n                System.out.println(\"La variale tiene valor 2\");\n                break;\n            case 3:\n                System.out.println(\"La variable tiene valor 3\");\n                break;\n            default:\n                System.out.println(\"La variable tiene un valor desconocido\");\n        }\n\n        //ITERATIVAS O BUCLES\n        for(int i = 1; i <= 4; i++)\n        {\n            if( i == 3 ) continue; //salta a la siguiente iteración de un bucle\n            System.out.println(x);\n            x ++;\n        }\n\n        x = 1;\n        while( x <= 5){\n            System.out.println(\"Iterado \"+ x +\" Veces\");\n            x++;\n        }\n\n        x = 1;\n        do{\n            System.out.println(\"Iterado \"+ x + \"veces\");\n            x++;\n        } while(x <= 5);\n\n        //MANEJO DE EXCEPCIONES\n        Scanner scanner = new Scanner(System.in);\n        int num1,num2, div;\n        try{\n            System.out.println(\"Primer número, debe ser un valor entero \");\n            num1=scanner.nextInt();\n            System.out.println(\" Divisor, un valor entero \");\n            num2=scanner.nextInt();\n            div= num1/num2;\n            System.out.println(division);}\n        catch(InputMismatchException excepcion){\n\n            System.err.println(\"Se ingresó un tipo de dato incorrecto\");\n        }\n        catch(ArithmeticException excepcion){\n            System.err.println(\"Se intentó dividir por cero\");\n        }\n        finally{\n            System.out.println(\"Ha finalizado el ejemplo\");}\n\n        //DIFICULTAD EXTRA: Crea un programa que imprima por consola todos los números comprendidos\n        // * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\n\n        for(int num = 10; num <= 55; num++){\n            if( num%2 == 0 && num != 16 && esMultiploDeTres(num))\n            System.out.println(num);\n        }\n    }\n    public static boolean esMultiploDeTres(int numero) {// Función para determinar si un número es múltiplo de 3\n        int sumaDigitos = 0;\n        while (numero > 0) {\n            sumaDigitos += numero % 10; // Obtenemos el último dígito y lo sumamos\n            numero /= 10; // Eliminamos el último dígito\n        }\n        // Comprobamos si la suma de los dígitos es divisible por 3\n        return sumaDigitos % 3 == 0;\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/xurxogz.java",
    "content": "public class xurxogz {\n    public static void main(String[] args) {\n        // #01 OPERADORES Y ESTRUCTURAS DE CONTROL\n\n        // ASIGNACION\n        int num1 = 10;\n        System.out.println(num1);\n\n        int num2 = 5;\n        System.out.println(num2);\n\n        int num3 = num1 += num2;\n        System.out.println(num3);\n\n        int num4 = num1 -= num2;\n        System.out.println(num4);\n\n        int num5 = num1 *= num2;\n        System.out.println(num5);\n\n        int num6 = num1 /= num2;\n        System.out.println(num6);\n\n        int num7 = num1 %= num2;\n        System.out.println(num7);\n\n        // ARITMETICOS\n        int suma = num1 + num2;\n        System.out.println(suma);\n\n        int resta = num1 - num2;\n        System.out.println(resta);\n\n        int multiplicacion = num1 * num2;\n        System.out.println(multiplicacion);\n\n        int division = num1 / num2;\n        System.out.println(division);\n\n        int modulo = num1 % num2;\n        System.out.println(modulo);\n\n        // COMPARACION E IDENTIDAD\n        boolean resultado1 = num1 > num2;\n        System.out.println(resultado1);\n\n        boolean resultado2 = num1 >= num2;\n        System.out.println(resultado2);\n\n        boolean resultado3 = num1 < num2;\n        System.out.println(resultado3);\n\n        boolean resultado4 = num1 <= num2;\n        System.out.println(resultado4);\n\n        boolean resultado5 = num1 == num2;\n        System.out.println(resultado5);\n\n        boolean resultado6 = num1 != num2;\n        System.out.println(resultado6);\n\n        // LOGICOS\n        int edad = 15;\n        boolean esMayorDeEdad = edad == 18 || edad > 18;\n        System.out.println(esMayorDeEdad);\n\n        boolean esMenorDeEdad = edad < 18 && esMayorDeEdad == false;\n        System.out.println(esMenorDeEdad);\n\n        boolean esVerdadero = true;\n        boolean esFalso = !esVerdadero;\n        System.out.println(esFalso);\n\n        // CONDICIONAL - IF\n        if (num1 < num2) {\n            System.out.println( num1 + \" es mayor que \" + num2);\n        }\n        else if (num1 > num2) {\n            System.out.println(num1 + \" es menor que \" + num2);\n        }\n        else {\n            System.out.println(num1 + \" es igual que \" + num2);\n        }\n\n        // CONDICIONAL - SWITCH\n        String diasDeLaSemana = \"Martes\";\n        switch (diasDeLaSemana) {\n            case \"Lunes\":\n                System.out.println(\"Hoy es Lunes\");\n                break;\n            case \"Martes\":\n                System.out.println(\"Hoy es Martes\");\n                break;\n            case \"Miercoles\":\n                System.out.println(\"Hoy es Miércoles\");\n                break;\n            case \"Jueves\":\n                System.out.println(\"Hoy es Jueves\");\n                break;\n            case \"Viernes\":\n                System.out.println(\"Hoy es Viernes\");\n                break;\n            default:\n                System.out.println(\"Hoy es fin de semana\");\n                break;\n        }\n\n        // BUCLE -  DOWHILE\n        int contador1 = 10;\n        do {\n            System.out.println(contador1);\n            contador1 --;\n        } while (contador1 >= 0);\n\n        // BUCLE WHILE\n        int contador2 = 1;\n        while (contador2 >= 10) {\n            System.out.println(contador2);\n            contador2++;\n        }\n\n        // BUCLE FOR\n        int contador3;\n        for (contador3 = 0; contador3 <= 10; contador3++) {\n            System.out.println(contador3);\n        }\n\n        // DIFICULTAD EXTRA (OPCIONAL)\n        int var;\n        for (var = 10; var <= 55; var++ ) {\n            if (var % 2 == 0 && var != 16 && var % 3 == 1) {\n                System.out.println(var);\n            }\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/yaretzyrb.java",
    "content": "public static void main(String[] args) {\n\n    // Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n    \n    // ASIGNACIÓN\n    int a = 5;\n    int b = 10;\n    System.out.println(a += 2);\n    System.out.println(a -= 2);\n    System.out.println(a /= 2);\n    System.out.println(a *= 2);\n    System.out.println(++a);\n    System.out.println(--a);\n    \n    // ARITMÉTICOS\n    System.out.println(a + b);\n    System.out.println(a - b);\n    System.out.println(a * b);\n    System.out.println(a / b);\n    System.out.println(a % b);\n    \n    // RELACIONALES\n    System.out.println(a == b);\n    System.out.println(a <= b);\n    System.out.println(a >= b);\n    System.out.println(a < b);\n    System.out.println(a > b);\n    System.out.println(a != b);\n    \n    \n    // LÓGICOS\n    System.out.println(a+a==b && b-a==a);\n    System.out.println(a+a==b || b-a==a);\n    System.out.println(a+a==b & b-a==a);\n    System.out.println(a+a==b | b-a==a);\n    System.out.println(!(a+a==b || b-a==a));\n        \n   /* \n   ESTRUCTURAS SELECTIVAS\n   */\n\n    // CICLO IF\n    \n    if(a > b){\n        System.out.println(\"La variable A es igual a: \" + a);\n        System.out.println(\"La variable B es igual a: \" + b);\n        System.out.println(\"La variable A es mayor que B\");\n    }\n    \n    // CICLO ELSE IF\n    else if(a == b){\n        System.out.println(\"Las variables A y B son iguales\");\n    }\n    \n    // CICLO ELSE\n    else{\n        System.out.println(\"La variable A es igual a: \" + a);\n        System.out.println(\"La variable B es igual a: \" + b);\n        System.out.println(\"La variable B es mayor que A\");\n    }\n\n    // CICLO SWITCH\n\n    switch (a) {\n        case 1:\n            System.out.println(\"La variable A es igual a 1\");\n            break;\n        case 2:\n            System.out.println(\"La variable A es igual a 2\");\n            break;\n        case 3:\n            System.out.println(\"La variable A es igual a 3\");\n            break;\n        case 4:\n            System.out.println(\"La variable A es igual a 4\");\n            break;\n        case 5:\n            System.out.println(\"La variable A es igual a 5\");\n            break;\n        case 6:\n            System.out.println(\"La variable A es igual a 6\");\n            break;\n        case 7:\n            System.out.println(\"La variable A es igual a 7\");\n            break;\n        default:\n        System.out.println(\"La variable A es mayor a 7\");\n            break;\n    }\n\n\n    /* \n   ESTRUCTURAS REPETITIVAS\n   */\n\n    //ESTRUCTURA WHILE\n\n    while(b == 10){\n        System.out.println(\"La variable B es igual a: \" + b);\n        --b;\n\n    }\n\n    \n    //ESTRUCTURA DO-WHILE\n\n    do{\n       System.out.println(\"La variable A es igual a: \" + a + \" y es mayor que 0\");\n       a--;\n    } while(a > 0);\n\n\n\n    //ESTRCUTURA FOR\n    for(a=0;a<5;a++){\n        System.out.println(\"La variable a es igual a: \" + a + \" y es menor a 5\");\n    }\n\n    // EJERCICIO EXTRA\n    int c = 10;\n    for (c=10;c >= 10 && c <= 55;c++){\n        if(c%2 == 0 && c%3 != 0 && c != 16){\n            System.out.println(c);\n    }\n    \n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/yowcloud.java",
    "content": "public class yowcloud {\n    public static void main(String[] args) {\n        int a = 10, b = 5;\n        boolean x = true, y = false;\n        System.out.println(\"Arithmetical operators:\");\n        arithmetical(a, b);\n\n        System.out.println(\"Logical operators:\");\n        logical(x, y);\n\n        System.out.println(\"Assignment operators:\");\n        assignment(a, b);\n\n        System.out.println(\"Comparison operators:\"); \n        comparison(a, b);\n\n        System.out.println(\"Bits operators:\");\n        bits(a, b);\n\n        System.out.println(\"Conditionals:\");\n        conditionals(a, b);\n\n        System.out.println(\"Iteratives:\");\n        iteratives(a, b);\n        \n        System.out.println(\"Exceptions:\");\n        exceptions();\n        \n        System.out.println(\"DIFICULTAD EXTRA:\");\n        extra(10, 55);\n    }\n    private static void arithmetical(int a, int b) {\n        System.err.println(\"a = \" + a + \" b = \" + b);\n        System.out.println(\"Add -> a + b = \" + (a + b));\n        System.out.println(\"Sub -> a - b = \" + (a - b));\n        System.out.println(\"Product -> * b = \" + (a * b));\n        System.out.println(\"Div -> a / b = \" + (a / b));\n        System.out.println(\"Mod ->a % b = \" + (a % b));\n    }\n    private static void logical(boolean x, boolean y) {\n        System.err.println(\"x = \" + x + \" y = \" + y);\n        System.out.println(\"AND lógico: x= true && y = false : \" + (x && y));\n        System.out.println(\"OR lógico: true || y = false : \" + (x || y));\n        System.out.println(\"NOT lógico: !true, : \" + (!x));\n    }\n    private static void assignment(int a, int b){\n        System.err.println(\"a = \" + a + \" b = \" + b);\n        a = b;\n        a += b; \n        System.out.println(\"Asignación:a(10) = b(5), a+=b -> \" + a);\n    }\n    private static void comparison(int a, int b) {\n        System.err.println(\"a = \" + a + \" b = \" + b);\n        System.out.println(\"Equal -> a == b = \" + (a == b));\n        System.out.println(\"Not equal -> a != b = \" + (a != b));\n        System.out.println(\"Greater than -> a > b = \" + (a > b));\n        System.out.println(\"Less than -> a < b = \" + (a < b));\n        System.out.println(\"Greater than or equal to -> a >= b = \" + (a >= b));\n        System.out.println(\"Less than or equal to -> a <= b = \" + (a <= b));\n    }\n    private static void bits(int a, int b) {\n        System.out.println(\"a = \" + a + \" b = \" + b);\n        System.out.println(\"AND bit a & b = \" + (a & b));\n        System.out.println(\"OR bit a | b = \" + (a | b));\n        System.out.println(\"XOR bit a ^ b = \" + (a ^ b));\n        System.out.println(\"NOT bit ~a = \" + (~a));\n        System.out.println(\"Desplazamiento a << 2 = \" + (a << 2));\n        System.out.println(\"Desplazamiento a >> 2 = \" + (a >> 2));\n    }\n    private static void conditionals(int a, int b) {\n        System.out.println(\"a = \" + a + \" b = \" + b);\n        System.out.println(\"if-else or if:\");\n        if (a > b) {\n            System.out.println(\"a > b\");\n        } else {\n            System.out.println(\"a < b\");\n        }\n        System.out.println(\"switch:\");\n        switch (a) {\n            case 10:\n                System.out.println(\"a = 10\");\n                break;\n            case 5:\n                System.out.println(\"a = 5\");\n                break;\n            default:\n                System.out.println(\"a != 10 && a != 5\");\n                break;\n        }\n    }\n\n    private static void iteratives(int a, int b) {\n        System.out.println(\"a = \" + a + \" b = \" + b);\n        System.out.println(\"for:\");\n        for (int i = 0; i < a; i++) {\n            System.out.println(\"i = \" + i);\n        }\n        \n        System.out.println(\"while:\");\n        while (b > 0) {\n            System.out.println(\"b = \" + b);\n            b--;\n        }\n        \n        System.out.println(\"do while:\");\n        do {\n            System.out.println(\"a = \" + a);\n            a--;\n        } while (a > 0);\n    }\n\n    private static void exceptions() {\n        try {\n            int[] arr = new int[5];\n            System.out.println(arr[5]); // This will throw an exception\n        } catch (ArrayIndexOutOfBoundsException e) {\n            System.out.println(\"Caught exception: \" + e);\n        }\n    }\n    private static void extra(int a, int b) {\n        System.out.println(\"a = \" + a + \" b = \" + b);\n        for (int pos = a; pos <= b; pos++) {\n            if (pos % 2 == 0 && pos != 16 && pos % 3 != 0) {\n                System.out.println(\"i = \" + pos);\n            }\n        }\n    }\n}/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/java/zemanue.java",
    "content": "\n// EJERCICIO #01: OPERADORES Y ESTRUCTURAS DE CONTROL\n\npublic class zemanue {\n    public static void main(String[] args) {\n        \n        int a = 10, b = 2;\n        System.out.println(\"Variables: a = \" + a + \", b = \" + b);\n\n        System.out.println(\"OPERADORES ARITMÉTICOS/ALGEBRAICOS:\");\n        System.out.println(\"- Suma: a + b = \" + (a + b));\n        System.out.println(\"- Resta: a - b = \" + (a - b));\n        System.out.println(\"- Multiplicación: a * b = \" + (a * b));\n        System.out.println(\"- División: a / b = \" + (a / b));\n        System.out.println(\"- Módulo/resto: a % b = \" + (a % b));\n\n        System.out.println(\"OPERADORES DE INCREMENTO y DECREMENTO:\");\n        a++;\n        System.out.println(\"- Incremento: a++ = \" + a);\n        a--;\n        System.out.println(\"- Decremento: a-- = \" + a);\n\n        System.out.println(\"OPERADORES DE ASIGNACIÓN:\");\n        b = 5;\n        System.out.println(\"- Asignación: b = 5 --> b = \" + b);\n        b += 10;\n        System.out.println(\"- Suma y asignación: b += 10 --> b = \" + b);\n        b -= 3;\n        System.out.println(\"- Resta y asignación: b -= 3 --> b = \" + b);\n        b *= 2;\n        System.out.println(\"- Multiplicación y asignación: b *= 2 --> b = \" + b);\n        b /= 8;\n        System.out.println(\"- División y asignación: b /= 8 --> b = \" + b);\n\n        System.out.println(\"OPERADORES RELACIONALES/DE COMPARACIÓN:\");\n        System.out.println(\"- Igualdad: a == b = \" + (a == b));\n        System.out.println(\"- Desigualdad: a!= b = \" + (a != b));\n        System.out.println(\"- Mayor que : a > b = \" + (a > b));\n        System.out.println(\"- Menor que : b < a = \" + (a < b));\n        System.out.println(\"- Mayor o igual a: a >= 11 = \" + (a >= 11));\n        System.out.println(\"- Menor o igual a: b <= 3 = \"+ (b <= 3));\n\n        System.out.println(\"OPERADORES LÓGICOS:\");\n        System.out.println(\"- && (AND): (a < 100 && a > 1) = \" + (a < 100 && a > 1));\n        System.out.println(\"- || (OR): (a < 10 || b > 1) = \" + (a < 10 || b > 1));\n        System.out.println(\"- ! (NOT): !(b == 30) = \" + !(b == 30));\n\n        System.out.println(\"OPERADOR TERNARIO: \\\"?\\\" y \\\":\\\" \");\n        int mayor = (a > b) ? a : b;\n        System.out.println(\"int mayor = (a > b) ? a : b --> \" + mayor);\n\n\n        System.out.println(\"ESTRUCTURAS DE CONTROL\");\n        System.out.println(\"CONDICIONALES\");\n        System.out.println(\"- IF-ELSE: \");\n        String resultado;\n        if (a > b) {\n            resultado = \"a es mayor que b\";\n        } else if (a < b) {\n            resultado = \"b es mayor que a\";\n        } else {\n            resultado = \"a y b son iguales\";\n        }\n        System.out.println(resultado);\n        \n        System.out.println(\"ITERATIVAS (BUCLES)\");\n        System.out.println(\"- FOR:\");\n        for (int i = 0; i < 10; i++) {\n            System.out.print(i);\n        }\n        System.out.println(\"\");\n\n        System.out.println(\"- FOR EACH:\");\n        String[] cuatroLetras = new String[] {\"a\", \"b\", \"c\", \"d\"};\n        for (String string : cuatroLetras) {\n            System.out.print(string);\n        }\n        System.out.println(\"\");\n\n        System.out.println(\"- WHILE:\");\n        int c = 15;\n        while (c > a) {\n            System.out.print(c + \"-\");\n            c--;\n        }\n        System.out.println(\"\");\n\n        System.out.println(\"- DO WHILE: \");\n        do {\n            System.out.println(\"Se imprime al menos una vez\");\n        } while (a < b);\n\n        System.out.println(\"EXCEPCIONES: \");\n        System.out.println(\"Try-catch:\");\n        try {\n            c /= 0;\n        } catch (ArithmeticException divisionEntre0) {\n            System.out.println(\"No se puede dividir entre 0\");\n        }\n\n        System.out.println(\"EJERCICIO OPCIONAL:\");\n        for (int i = 10; i < 56; i++) {\n            if ((i % 2 != 0)\n                    && i != 16\n                    && i % 3 != 0) {\n                System.out.println(i);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/08BLL.js",
    "content": "//OPERADORES DE ASIGNACIÓN (Los más usados):\n\n// Asigna un valor a su operando izquierdo \nlet valor1=5; //(Asignación) Asigna a la variable valor, el valor de 5\nconsole.log(valor1 += 2); //(Adición) Esto es igual a valor1 = valor1 + 2\nconsole.log(valor1 -= 2); //(Resta) Esto es igual a valor1 = valor1 - 2\nconsole.log(valor1 *= 2); //(Multiplicación) Esto es igual a valor1 = valor1 * 2\nconsole.log(valor1 /= 2); //(División) Esto es igual a valor1 = valor1 / 2\nconsole.log(valor1 %= 2); //(Residuo|Resto) Esto es igual a valor1 = valor1 % 2\nconsole.log(valor1 **= 2); //(Exponenciación) Esto es igual a valor1 = valor1 ** 2\n\n//OPERADORES DE COMPARACIÓN (Los más usados) = Compara sus operandos y devuelve un valor lógico \n// Si la comparación es verdadera, devuelve (true) y si es falsa devuelve (false)\n\nlet numero1 = 1;\nlet numero2 = 2;\nlet numero3 = \"1\";\n\n//¿ Es igual en cuanto a número ?\nconsole.log(numero1==numero2); //False\nconsole.log(numero1==numero3); //True\n\n//¿ Es igual en cuanto a número y tipo ?\nconsole.log(numero1===numero2); //False\nconsole.log(numero1===numero3); //False //Son el mismo número pero, el tipo, numero1 es integer y numero3 string\n\n//¿ Es distinto en cuanto a número ?\nconsole.log(numero1!=numero2); //True\nconsole.log(numero1!=numero3); //False\n\n//¿ Es distinto en cuanto a número y tipo ?\nconsole.log(numero1!==numero2); //True\nconsole.log(numero1!==numero3); //True\n\n//¿ Es Mayor o Mayor o igual ?\nconsole.log(numero1>numero2); //False\nconsole.log(numero1>=numero3); //False\n\n//¿ Es Menor o Menor o igual ?\nconsole.log(numero1<numero2); //True\nconsole.log(numero1<=numero3); //True\n\n// OPERADORES ARITMÉTICOS (Los más usados):\n\nlet numero4 = 4;\nlet numero5 = 2;\n\n//+ (Suma) Suma dos números\nlet suma = numero4+numero5;\nconsole.log(suma);\n\n//- (Resta) Resta dos números\nlet resta = numero4-numero5;\nconsole.log(resta);\n\n//++ (Incremento) Suma 1 al valor de la variable\nlet incremento = numero4++; // incremento ahora será 5\nconsole.log(incremento);\n\n//-- (Decremento) Resta 1 al valor de la variable\nlet decremento = numero4--; // decremento ahora será 3\nconsole.log(decremento);\n\n//% (Residuo | Resto) Devuelve el resto de la división de dos operandos\nlet resto = numero4%2; // (el resto de dividir 4 entre 2 es 0)\nconsole.log(resto);\n\n//** (Exponenciación) Devuelve la base elevada a la potencia del exponente\nlet exponenciacion = numero4 ** 2; // (4 elevado a la potencia de 2 es 16)\nconsole.log(exponenciacion);\n\n//OPERADORES LÓGICOS (Los más usados):\n\n/* \n&& (AND Lógico)\n|| (OR Lógico)\n! (NOT Lógico)\nLos operadores lógicos funcionan con valores booleanos, pero también con expresiones que devuelven valores booleanos \na partir de comparaciones o cualquier tipo de expresión que sea evaluada con true false\n*/\n\nlet numero6 = 6\nlet numero7 = 4\n\n//&& (AND Lógico)\nlet resultado1 = (numero6 > numero7) && (numero6>0);\nconsole.log(resultado1); //Equivale a true ya que la variable numero 6 es mayor a la variable numero 7 y la variable numero6 es mayor a 0\n\n//|| (OR Lógico)\nlet resultado2 = (numero6 < numero7) || (numero6==6);\nconsole.log(resultado2); //La variable numero 6 no es menor a la variable numero 7 (esto es false), pero como la variable numero6 es igual a 6, entonces como se cumple una de las dos, es true\n\n//! (NOT Lógico)\nlet resultado3 = !(numero7>10)\nconsole.log(resultado3); //La variable resultado3 sería false, pero como le hemos puesto el ! al principio la convertimos a true\n\n//OPERADORES DE CADENA (Los más usados):\n/* \nTenemos + y tenemos `${}`\n*/\n\nlet saludo=\"Hola, mi nombre es: \";\nlet nombre=\"Pedro\";\n\nlet juntar1=saludo+nombre; //Concatenamos una variable con otra con un +\nlet juntar2=`Hola, mi nombre es: ${nombre}`; //Concatenamos una variable un texto con los caracteres especiales ` y la variable dentro de ${}\n\nconsole.log(juntar1);\nconsole.log(juntar2);\n\n//OPERADORES CONDICIONALES:\n\n//Condicional: Se usa para evaluar si una condición es verdadera o falsa y ejecutar diferentes bloques de código según el resultado.\nlet numeroCondicional=2;\n\nif(numeroCondicional>10){\n    console.log(\"El numero es mayor a 10\"); \n}else{\n    console.log(\"El numero es menor a 10\");\n}\n\n//Bucle for: Se usa cuando se conoce de antemano cuántas veces se debe ejecutar el bloque de código, normalmente para iterar sobre números o arrays.\nlet contarHastaCinco=5;\nfor(let i=0;i<=contarHastaCinco;i++){\n    console.log(i);\n} \n\n//Bucle foreach: Se usa para iterar sobre los elementos de un array y ejecutar una función para cada uno de ellos.\nlet animales=[\"Perro\",\"Gato\",\"Oso\"];\nanimales.forEach(animal=>console.log(animal));\n\n//Bucle for of: Se usa para iterar sobre los valores de un objeto iterable (como arrays, cadenas, etc).\nfor(animal of animales){\n    console.log(animal);\n}\n\n//Bucle while: Ejecuta el bloque de código mientras que la condición sea verdadera. \n// Es útil cuando no se sabe cuántas veces se debe iterar de antemano, tenemos que ir modificando la variable, si no se quedaría en un bucle infinito.\nlet contarHastaDiez=0;\nwhile(contarHastaDiez<=10){\n    console.log(contarHastaDiez);\n    contarHastaDiez++;\n}\n\n//Bucle do While: Ejecuta el bloque de código al menos una vez antes de evaluar la condición (aunque la condición sea falsa), y continuará ejecutando mientras la condición sea verdadera.\nlet i=0;\ndo {\n    console.log(i);\n    i++;\n} while (i>5);\n\n//Switch: Se usa para evaluar varias opciones posibles para una sola variable, de manera más limpia y eficiente que usando múltiples if...else.\nlet operacion=\"sumar\";\nswitch (operacion) {\n    case \"sumar\":\n        console.log(\"Vas a sumar\");\n        break;\n    case \"restar\":\n        console.log(\"Vas a restar\");\n        break;\n    case \"multiplicar\":\n        console.log(\"Vas a multiplicar\");\n        break;\n    case \"dividir\":\n        console.log(\"Vas a dividir\");\n        break;\n    default:\n        console.log(\"Esa operación no está disponible\");\n        break;\n}\n\n//OPERADOR CONDICIONAL(TERNARIO):\n\nlet edad=18;\nlet comprobarEdad=edad>=18?\"Es mayor de edad\":\"Es menor de edad\";  \n\nconsole.log(comprobarEdad);\n\n/* \nSi la edad es mayor o igual a 18,\nla variable comprobarEdad será igual a \"Es mayor de edad\" ,\nsi es menor a 18 la variable comprobarEdad será igual a \"Es menor de edad\"   \n*/\n\n/*\n    EJERCICIO EXTRA\n    Crea un programa que imprima por consola todos los números comprendidos\n    entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n*/\n\nfor(let i=10;i<=55;i++){ //Le digo que empiece con el número 10 y que cuente hasta el número 55 incluido\n    if(i%2==0 && !(i%3==0) && i!=16){ //Aquí compruebo primero que sean pares, que no sea multiplo de 3 y que no sea = al numero 16\n        console.log(i);\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/1Nonamed.js",
    "content": "// OPERADORES\n\nconsole.log(`------------------ Asignación ------------------`);\nlet num = 10;\nconsole.log(`num: ${num}\\n`);\n\n// Asignación suma\nconsole.log(`num: ${num} || num += 2 => ${(num += 2)}`);\n// Asignación resta\nconsole.log(`num: ${num} || num -= 1 => ${(num -= 1)}`);\n// Asignación multiplicación\nconsole.log(`num: ${num} || num *= 2 => ${(num *= 2)}`);\n// Asignación exponencial\nconsole.log(`num: ${num} || num **= 2 => ${(num **= 2)}`);\n// Asignación división\nconsole.log(`num: ${num} || num /= 2 => ${(num /= 2)}`);\n// Asignación residuo\nconsole.log(`num: ${num} || num %= 2 => ${(num %= 2)}\\n`);\n\nconsole.log(`------------------ Comparación ------------------`);\nlet num1 = 20;\nlet num2 = 27;\nconsole.log(`num1: ${num1}    num2: ${num2}\\n`);\n\n// Igual\nconsole.log(`num1 == num2? => ${num1 == num2}`);\nconsole.log(\n  `'27' == num2? => ${\"27\" == num2} | Convierte tipos, comparación débil`\n);\n// No igual\nconsole.log(`num1 != num2? => ${num1 != num2}`);\nconsole.log(\n  `'27' != num2? => ${\"27\" != num2} | Convierte tipos, comparación débil`\n);\n// Estricta\nconsole.log(`num1 === num2? => ${num1 === num2}`);\nconsole.log(\n  `'27' === num2? => ${\"27\" === num2} | No convierte tipos, comparación fuerte`\n);\n// No igual estricto\nconsole.log(`num1 !== num2? => ${num1 !== num2}`);\nconsole.log(\n  `'27' !== num2? => ${\"27\" !== num2} | No convierte tipos, comparación fuerte`\n);\n// Mayor que\nconsole.log(`num1 > num2? => ${num1 > num2}`);\n// Mayor o igual que\nconsole.log(`num1 >= num2? => ${num1 >= num2}`);\n// Menor que\nconsole.log(`num1 < num2? => ${num1 < num2}`);\n// Menor o igual que\nconsole.log(`num1 <= num2? => ${num1 <= num2}`);\n\nconsole.log(`------------------ Aritméticos ------------------`);\n// Adicional a las operaciones +, -, *, **, / y %, JavaScript también tiene las siguientes operaciones:\nlet x = 2;\nlet y;\nconsole.log(`x: ${x}    y: ${y}\\n`);\n\n// Incrementar\nconsole.log(`++x => x = ${x}; y = ${++x}`);\n// Decrementar\nconsole.log(`--x => x = ${x}; y = ${--x}`);\n// Unary negation => Regresa la negación del operando\nconsole.log(`x => -x || x = ${x} => -x = ${-x}`);\n// Unary plus => Intenta convertir el operando en número\nconsole.log(`+x => x || x = ${-x} => +x = ${+x}`);\nconsole.log(`+'x' => x || x = '27' => +x = ${+\"27\"}\\n`);\n\nconsole.log(`------------------ Lógicos ------------------`);\nconst a = 10;\nconst b = 15;\nconsole.log(`a: ${a}    b: ${b}\\n`);\n\n// Y (and -- &&)\nconsole.log(`a < b && b >= 15 => ${a < b && b >= 15}`);\n// O (Or -- ||)\nconsole.log(`a < b || b > 15 => ${a < b || b > 15}`);\n// No (Not -- !)\nconsole.log(`!(a < b && b >= 15) => ${!(a < b && b >= 15)}`);\nconsole.log(`!!(a < b && b >= 15) => ${!!(a < b && b >= 15)}`); // Negación doble\n// Nullish coalescing operator (??) => Devuelve el valor de la derecha sí el de la izquierda es null o undefined\nconsole.log(`null ?? a => ${null && a}`);\nconsole.log(`10 ?? a => ${10 && a}`);\nconsole.log(`10 ?? undefined => ${10 && undefined}`);\n\nconsole.log(`------------------ Strings ------------------`);\nlet msj = \"Hello,\";\nmsj += \" World!\";\n\nconsole.log(msj);\n\nconsole.log(`\\n------------------ Ternary ------------------`);\nlet age = 28;\nconsole.log(`age: ${age}\\n`);\n\nconsole.log(`${age > 20 ? \"Allowed to enter\" : \"Not allowed to enter\"}`);\n\n// ESTRUCTURAS DE CONTROL\n\nconsole.log(`\\n------------------ Condicionales: If Else ------------------`);\nlet grade = 3;\nlet color = \"red\";\nconsole.log(`grade: ${grade}   color: ${color}\\n`);\n\nif (grade >= 3) console.log(\"Aprobaste\");\n\nif (color === \"yellow\") {\n  console.log(\"El color es el mismo\");\n} else {\n  console.log(\"El color no es el mismo\");\n}\n\nconsole.log(`\\n------------------ Condicionales: Switch ------------------`);\nlet grade2 = 2;\nconsole.log(`grade: ${grade2}\\n`);\n\nswitch (grade2) {\n  case 5:\n    finalGrade = \"Excelente\";\n    break;\n  case 4:\n    finalGrade = \"Sobresaliente\";\n    break;\n  case 3:\n    finalGrade = \"Suficiente\";\n    break;\n  case 2:\n  case 1:\n  case 0:\n    finalGrade = \"Insuficiente\";\n    break;\n\n  default:\n    finalGrade = \"Nota erronea\";\n    break;\n}\nconsole.log(`Mi nota final es ${finalGrade}\\n`);\n\nconsole.log(`------------------ Bucles: While ------------------`);\nlet i = 0;\n\nwhile (i <= 3) {\n  console.log(`While => i: ${i}`);\n  i = i + 1;\n}\n\nconsole.log(\"\\ndo While from here:\");\n// do while se ejecuta al menos UNA vez\ndo {\n  console.log(`do While => i: ${i}`);\n  i = i + 1;\n} while (i < 8);\n\nconsole.log(`------------------ Bucles: For ------------------`);\nfor (let j = 0; j < 3; j++) {\n  console.log(`Log #${j} from loop for (Incremental)\\n`);\n}\n\nfor (let k = 5; k > 2; k--) {\n  console.log(`Log #${k} from loop for (Decremental)`);\n}\n\nconsole.log(`\\n------------------ Extra ------------------`);\n// Crea un programa que imprima por consola todos los números comprendidos entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\nconst arr = [];\nconst arrMultiplesOf3 = [];\n\nfor (let i = 10; i <= 55; i++) {\n  if (i % 3 === 0) {\n    arrMultiplesOf3.push(i);\n  }\n}\nconsole.log(\"Multiples of 3:\");\nconsole.log(arrMultiplesOf3);\n\nfor (let i = 10; i <= 55; i++) {\n  if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n    arr.push(i);\n  }\n}\n\n\nconsole.log('\\nFinal Array:')\nconsole.log(arr);\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/7R0N1X.js",
    "content": "let n1 = 3\nlet n2 = 6\n\n// Operadores de comparación\nconsole.log(3 == n1); // Igual\nconsole.log(n1 != 4); // No es igual\nconsole.log('3' === n1); // Estrictamente igual\nconsole.log(n1 !== '3'); // Desigualdad estricta\nconsole.log(n1 > n2); // Mayor que\nconsole.log(n1 >= n1); // Mayor o igual que\nconsole.log(n1 > n2); // Menor que\nconsole.log(n1 <= n2); // Menor o igual que\n\n// Operadores aritméticos\nconsole.log(n1 + n2); // Suma\nconsole.log(n1 - n2); // Resta\nconsole.log(n1 * n2); // Multiplicación\nconsole.log(n1 / n2); // División\nconsole.log(n1 % n2); // Residuo\nconsole.log(n1++); // Incremento\nconsole.log(n1--); // Decremento\n\n// Operadores bit a bit\nlet a = 6;  // 0110 en binario\nlet b = 3;  // 0011 en binario\n\nconsole.log(a & b);  // AND bit a bit: 0010 (salida: 2)\nconsole.log(a | b);  // OR bit a bit: 0111 (salida: 7)\nconsole.log(a ^ b);  // XOR bit a bit: 0101 (salida: 5)\nconsole.log(~a);     // NOT bit a bit: 1001 (en complemento a dos, salida: -7)\nconsole.log(a << 1); // Desplazamiento a la izquierda: 1100 (salida: 12)\nconsole.log(a >> 1); // Desplazamiento a la derecha con signo: 0011 (salida: 3)\nconsole.log(a >>> 1); // Desplazamiento a la derecha sin signo: 0011 (salida: 3)\n\n// Operadores lógicos\nlet p = 8;\nlet q = 3;\n\nlet resultado1 = (p > q) && (q > 0);  // true && true => true\nconsole.log(resultado1);  // Salida: true\n\nlet resultado2 = (p < q) || (q > 0);  // false || true => true\nconsole.log(resultado2);  // Salida: true\n\nlet resultado3 = !(p < q);  // !false => true\nconsole.log(resultado3);  // Salida: true\n\nlet m = false;\nlet n = true;\nlet o = false;\n\nlet resultado4 = m || n && o;  // false || true && false => false || false => false\nconsole.log(resultado4);  // Salida: false\n\nlet resultado5 = !(m || (n && o));  // !(false || (true && false)) => !(false || false) => !false => true\nconsole.log(resultado5);  // Salida: true\n\n// Operadores de cadena\nlet r = 'JavaScript'\nconsole.log(\"Hola mundo desde \" + r); // Operador de concatenación\n\nlet s = 'Java'\ns += 'Script' // Operador de concatenación abreviada\nconsole.log(s);\n\n// Operador condicional (Ternario)\nlet edad = 18\nlet resultado = edad >= 18 ? 'Es mayor de edad.' : 'Es menor de edad.'\nconsole.log(resultado);\n\n/*\n  Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n  que representen todos los tipos de estructuras de control que existan\n  en tu lenguaje:\n  Condicionales, iterativas, excepciones...\n*/\n\n// Condicional\nif (edad >= 18) {\n  console.log('Eres mayor de edad.');\n} else {\n  console.log('Eres menor de edad.');\n}\n\n// Bucle for\nlet mult = 5;\nfor (let n = 1; n <= 12; n++) {\n  console.log(`${mult} x ${n} = ${mult * n}`);\n}\n\n// Bucle forEach\nlet frutas = ['manzana', 'banana', 'cereza', 'durazno', 'fresa', 'kiwi', 'mango', 'naranja', 'pera', 'piña'];\nconsole.log('########## forEach ##########');\nfrutas.forEach(fruta => {\n  console.log(fruta);\n})\n\n// Bucle for...in\nconsole.log('########## for...in ##########');\nfor (let fruta in frutas) {\n  console.log(frutas[fruta]);\n}\n\n// Bucle for...of\nconsole.log('########## for...of ##########');\nfor (let fruta of frutas) {\n  console.log(fruta);\n}\n\n// Bucle while\nlet num = 1\nwhile (num <= 10) {\n  if (num % 2 === 0) {\n    console.log(`${num} es par.`);\n  }\n  num++\n}\n\n// Bucle Do While\nnum = 1\ndo {\n  if (num % 2 === 0) {\n    console.log(`${num} es par.`);\n  }\n  num++\n} while (num <= 10);\n\n// Switch\nlet mes = new Date().getMonth() + 1\n\nswitch (mes) {\n  case 1:\n    console.log('Enero');\n    break;\n  case 2:\n    console.log('Febrero');\n    break;\n  case 3:\n    console.log('Marzo');\n    break;\n  case 4:\n    console.log('Abril');\n    break;\n  case 5:\n    console.log('Mayo');\n    break;\n  case 6:\n    console.log('Junio');\n    break;\n  case 7:\n    console.log('Julio');\n    break;\n  case 8:\n    console.log('Agosto');\n    break;\n  case 9:\n    console.log('Septiembre');\n    break;\n  case 10:\n    console.log('Octubre');\n    break;\n  case 11:\n    console.log('Noviembre');\n    break;\n  case 12:\n    console.log('Diciembre');\n    break;\n  default:\n    nombreDelMes = 'Número de mes no válido';\n}\n\n/*\n  Crea un programa que imprima por consola todos los números comprendidos\n  entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n*/\n\nfor (let n = 10; n <= 55; n++) {\n  if (n % 2 === 0 && n !== 16 && n % 3 !== 0) {\n    console.log(n);\n  }\n}\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/AChapeton.js",
    "content": "// *** OPERADORES DE ASIGNACION ***\n//Asignacion\nvar x = 5;\nvar y = 10;\nconsole.log('Asignacion:', x, y);\n\n//Asignacion de Adicion\nx = x + y;\nconsole.log('Adicion 1:', x);\n\nx += y;\nconsole.log('Adicion 2:', x);\n\n//Asignacion de Resta\nx = x - y;\nconsole.log('Resta 1:', x);\n\nx -= y;\nconsole.log('Resta 2:', x);\n\n//Asignacion de Multiplicacion\nx = x * y;\nconsole.log('Multiplicacion 1:', x);\nx *= y;\nconsole.log('Multiplicacion 2:', x);\n\n//Asignacion de Division\nx = x / y;\nconsole.log('Division 1:', x);\nx /= y;\nconsole.log('Division 2:', x);\n\n//Asignacion de Residuo\nx = x % y;\nconsole.log('Residuo 1:', x);\nx %= y;\nconsole.log('Residuo 2:', x);\n\n//Asignacion de Exponente\nx = Math.pow(x, y);\nconsole.log('Exponente 1:', x);\nx = Math.pow(x, y);\nconsole.log('Exponente 2:', x);\n\n//Asignacion AND logico\nx = x && (x = y);\nconsole.log('AND logico 1:', x);\nx && (x = y);\nconsole.log('AND logico 2:', x);\n\n//Asignacion OR logico\nx = x || (x = y);\nconsole.log('OR logico 1:', x);\nx || (x = y);\nconsole.log('OR logico 2:', x);\n\n//Asignacion Anulacion logico\nx = x !== null && x !== void 0 ? x : (x = y);\nconsole.log('Anulacion logico 1:', x);\nx !== null && x !== void 0 ? x : (x = y);\nconsole.log('Anulacion logico 2:', x);\n\n\n// *** OPERADORES DE COMPARACION ***\nvar a = 4;\nvar b = 8;\n//Igual\nconsole.log('Igual: ', a == b);\n\n//No es igual\nconsole.log('No es igual: ', a != b);\n\n//Igualdad estricta\nconsole.log('Igualdad estricta: ', a === b);\n\n//Desigualdad estricta\nconsole.log('Desigualdad estricta: ', a !== b);\n\n//Mayor que\nconsole.log('Mayor que: ', a > b);\n\n//Mayor o igual que\nconsole.log('Mayor o igual que: ', a >= b);\n\n//Menor que\nconsole.log('Menor que: ', a < b);\n\n//Menor o igual que\nconsole.log('Menor o igual que: ', a <= b);\n\n\n// *** OPERADORES ARITMETICOS ***\nvar num1 = 10;\nvar num2 = 4;\n//Residuo\nconsole.log('Residuo: ', num1 % num2);\n\n//Incremento\nconsole.log('Incremento antes de imprimir: ', ++num1);\nconsole.log('Incremento despues de imprimir: ', num1++); //Se vuelve 12 luego de imprimir\n\n//Decremento\nconsole.log('Decremento antes de imprimir: ', --num1);\nconsole.log('Decremento despues de imprimir: ', num1--); //Se vuelve 10 luego de imprimir\n\n//Negacion unitaria\nconsole.log('Negacion unitaria: ', -num1);\n\n//Positivo unitaria\nconsole.log('Negacion unitaria: ', +num1);\n//Exponenciacion\n\nconsole.log('Exponenciacion: ', Math.pow(num1, num2));\n\n\n// *** OPERADORES BIT A BIT ***\nvar bit1 = 6;\nvar bit2 = 8;\n\n//Desplazamiento a la izquierda\nconsole.log('Desplazamiento a la izquierda:', bit1 << bit2);\n\n//Desplazamiento a la derecha\nconsole.log('Desplazamiento a la derecha:', bit1 >> bit2);\n\n//AND\nconsole.log('AND bit a bit:', bit1 & bit2);\n\n//OR\nconsole.log('AND bit a bit:', bit1 | bit2);\n\n//XOR\nconsole.log('AND bit a bit:', bit1 ^ bit2);\n\n//NOT\nconsole.log('AND bit a bit:', bit1, ~bit2);\n\n\n// *** OPERADORES LOGICOS ***\nvar exp1 = true;\nvar exp2 = false;\n\n//AND logico\nconsole.log('AND Logico: ', exp1 && exp2);\n\n//OR logico\nconsole.log('OR Logico: ', exp1 || exp2);\n\n//NOT logico\nconsole.log('NOT Logico: ', !exp1);\n\n\n// *** OPERADORES DE CADENA ***\nconsole.log(\"mi \" + \"cadena\");\n\n\n// *** OPERADOR CONDDICIONAL TERNARIO ***\n\nvar result = true ? true : false;\nconsole.log(result);\nvar user = {\n    id: '1',\n    name: 'Andres',\n    age: 86\n};\n\nconsole.log('Existe \"age\" en el objeto user?: ', 'age' in user);\nconsole.log('Existe \"country\" en el objeto user?: ', 'country' in user);\n\n\n// *** ESTRUCTURAS DE CONTROL ***\n\n// * CONDICIONAL *\n\nvar num = 25;\n// IF-ELSE\nif (num > 18) {\n    console.log('Es mayor de edad');\n}\nelse {\n    console.log('Es menor de edad');\n}\n\n//SWITCH\nswitch (num) {\n    case 20:\n        console.log('Es 20');\n        break;\n    case 25:\n        console.log('Es 25');\n        break;\n    case 30:\n        console.log('Es 30');\n        break;\n    default:\n        console.log('Default');\n        break;\n}\n\n\n// * BUCLES *\nvar i = 10;\nvar w = 15;\n\n//WHILE\nwhile (i < w) {\n    i++;\n    console.log('Nuevo valor de i:', i);\n}\n\n//DO-WHILE\ni = 10;\ndo {\n    i++;\n    console.log('Nuevo valor de i:', i);\n} while (i < w);\n\n//FOR\nfor (var i_1 = 0; i_1 < 10; i_1++) {\n    console.log('Nuevo valor de i:', i_1);\n}\n\n\n// *** EJERCICIO EXTRA ***\nconsole.log('EJERCICIO EXTRA');\n\nfor (var i_2 = 10; i_2 <= 55; i_2++) {\n    if (i_2 % 2 === 0) {\n        if (i_2 === 16) {\n            console.log('Ignorar');\n        }\n        else if (i_2 % 3 === 0) {\n            console.log('Multiplo de 3');\n        }\n        else {\n            console.log(i_2);\n        }\n    }\n    else {\n        console.log('No es par');\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/AgusBelP.js",
    "content": "/* \n\n#01  OPERADORES Y ESTRUCTURAS DE CONTROL\n\nCrea ejemplos utilizando todos los tipos de operadores de tu lenguaje: Aritméticos, lógicos, de comparación asignación, identidad, pertenencia, bits...(Ten en cuenta que cada lenguaje puede poseer unos diferentes).\nUtilizando las operaciones con operadores que tú quieras, crea ejemplos que representen todos los tipos de estructuras de control que existan en tu lenguaje: Condicionales, iterativas, excepciones...\nDebes hacer print por consola del resultado de todos los ejemplos.\n \nDIFICULTAD EXTRA (opcional):\nCrea un programa que imprima por consola todos los números comprendidos entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n \nSeguro que al revisar detenidamente las posibilidades has descubierto algo nuevo. */\n\n// --------------------------------------- RESOLUCIÓN --------------------------------------- //\n\n// <<<---------------------->>> Tipos de operadores <<<---------------------->>>\n\n/* En Javascript existen 10 tipos de operadores */\n\n// ---------------> 1. Operadores aritméticos <---------------\n\nlet suma = 1 + 1;\nlet resta = 5 - 2;\nlet multiplicación = 2 * 3;\nlet división = 4 / 2;\nlet modulo = 4 % 2; // Devuelve el resto de la división de 4 entre 2\nlet exponenciacion = 2 ** 3; // eleva 2 a la potencia de 3\n\n// ---------------> 2. Operadores de asignación <---------------\n\nlet x = 2; //operador de asignación\nx += 1; // operador de adición, simboliza x = x + 1\nx -= 1; // operador de resta, simboliza x = x - 1\nx *= 1; // operador de multiplicación, simboliza x = x * 1\nx /= 2; // operador de división, simboliza x = x / 2\nx %= 2; // operador de resto, simboliza x = x % 2 y a x se le adigna el resto de la división\nx **= 2; // operador de exponenciación, simboliza x = x ** 2 (x a la potencia de 2)\n\n// ---------------> 3. Operadores de comparación <---------------\n// Se mostrarán ejemplos que proporcionen un resultado true\n\nlet y = 4;\nlet z = 5;\nlet w = 1;\nconsole.log(y == '4'); // Comprobación de igualdad de valores sin verificar el tipo de dato\nconsole.log(y != 3); // Comprobación de la diferencia de lavalores sin verificar el tipo de dato\nconsole.log(y === 4); // Comprobación de igualdad de valores y tipo de dato\nconsole.log(y !== 3); // Comprobación de la diferencia de valores o tipo de dato\nconsole.log(z > y); // Comprobación si el valor de z es estrictamente mayor al de y\nconsole.log(z >= y); // Comprobación si el valor de z es mayor o igual al de y\nconsole.log(w < y); // Comprobación si el valor de w es estrictamente menor al de y\nconsole.log(w <= y); // Comprobación si el valor de w es menor o igual al de y\n\n// ---------------> 4. Operadores de cadena <---------------\n\nlet nombre = 'My' + 'GitHub';\nconsole.log(nombre);\n\n// ---------------> 5. Operadores lógicos <---------------\n\n// Operador condicional(ternario)\n\nlet edad = 15;\n\nedad > 18 ? console.log('Soy mayor de edad') : console.log('No soy mayor de edad');\n\n// AND (&&)\n\nconsole.log(true && true); // Cuando se usa con valores booleanos, && devuelve verdadero si ambos operandos son verdaderos; de lo contrario, devuelve falso.\nconsole.log(0 && true); // Considerando la forma \"expr1 && expr2\" el operador && devuelve expr1 si se puede convertir a false; de lo contrario, devuelve expr2. Ejemplos de expresiones que se pueden convertir a false son aquellos que se evalúan como null, 0, NaN, la cadena vacía (\"\") o undefined. En el ejemplo el log imprime 0\n\n// OR (||)\n\n// El operador lógico OR establece una condición donde devolverá el primer valor si es true, o el segundo valor si el primero es false. Esto se puede leer de forma que «devuelve a (si es verdadero), o si no, b».\n\nconsole.log(false || false); // devuelve false\nconsole.log(true || false); // devuelve true\nconsole.log(false || true); // devuelve true\nconsole.log(true || true); // devuelve true\n\n// Considerando que cualquier valor superior a 0 es considerado como true y que cualquier valor que sea 0 o falsy se considera false:\n\nconsole.log(0 || null); // devuelve false, se considera como false || false\nconsole.log(44 || undefined); // devuelve true, se considera como true || false\nconsole.log(0 || 17); // devuelve true, se considera como false || true\nconsole.log(4 || 10); // devuelve true, se considera como true || true\n\n// Nullish coalescing (??)\n\n// el operador a ?? b devuelve b sólo cuando a es undefined o null. Al contrario que el operador OR, con valores como false, 0 o \"\", no devuelve b.\n\nconsole.log(42 || 50); // devulve 42\nconsole.log(42 ?? 50); // devulve 42\nconsole.log(false || 50); // devulve 50\nconsole.log(false ?? 50); // devulve false\nconsole.log(0 || 50); // devulve 50\nconsole.log(0 ?? 50); // devulve 0\nconsole.log(null || 50); // devulve 50\nconsole.log(null ?? 50); // devulve 50\nconsole.log(undefined || 50); // devulve 50\nconsole.log(undefined ?? 50); // devulve 50\n\n// Operador de asignación lógica nula (??=)\n\n// Especialmente útil en los casos en que una variable tiene el valor null o undefined y se desea cambiar su valor\n\n// Sin asignación lógica nula\nlet t = null;\nif (t === null || t === undefined) {\n    t = 120;\n}\n\n// Con asignación lógica nula\nt ??= 120;\n\n// Encadenamiento opcional (?)\n\n// Este operador permite acceder a propiedades aunque su elemento padre no exista de forma de evitar un error.\n\n//Ejemplo: Suponiendo que se tiene un objeto usuario:\n\nconst user = {\n    name: 'Moure',\n    role: 'streamer',\n    attributes: {\n        life: 100,\n        power: 25,\n    },\n};\n\n// Si intento acceder a sus propiedades:\n\nuser.attributes.life;\nuser.attributes.power;\n\n// Suponiendo que la propiedad attributes del objeto user aún no exite (pero existirá), si se intenta acceder a las propiedades sin que attributes exista ocurrirá un error. Para evitar eos se puede utilizar el optional chainig:\n\nuser.attributes?.life;\nuser.attributes?.power;\n\n// En el caso de que la propiedad attribte del objeto user aún no exista el optionan chainig devuelve \"undefined\" pero no salta un error\n\n// Operador NOT (!)\n\n// Se trata de un operador utilziado para negar el valor (invertir) de una variable. Si una variable vale true, al negarla valdrá false y si una variable vale false, al negarla, valdrá false.\n\nconsole.log(!true); // devuelve false\nconsole.log(!false); // devuelve true\nconsole.log(!!true); // devuelve true\nconsole.log(!44); // devuelve false\nconsole.log(!0); // devuelve true (el 0 se evalua como false)\nconsole.log(!(10 || 23)); // devuelve false\n\n// ---------------> 6. Operadores de bits <---------------\n\n// Se trata de una serie de operadores que nos permiten realizar operaciones básicas trabajando a nivel binario, donde los operandos solo pueden tomar valores de 0 o 1:\n\n// x & y\tRealiza una operación AND binaria. Devuelve 1 en las posiciones de bit dónde las posiciones de los dos operadores tienen un 1.\n// x | y\tRealiza una operación OR binaria. Devuelve un cero en las posiciones de bit dónde las posiciones de los dos operadores tienen un 0.\n// x ^ y\tRealiza una operación XOR binaria. Devuelve un cero en las posiciones dónde el bit es el mismo y un 1 dónde las posiciones son diferentes.\n// ~ x\tRealiza una operación NOT binaria.\n// x << y\tRealiza un desplazamiento de bits a la izquierda.\n// x >> y\tRealiza un desplazamiento de bits a la derecha.\n// x >>> y\tRealiza un desplazamiento de bits a la derecha rellenando con ceros. */\n\nlet a = 9; // en bits: 1001\nlet b = 12; // en bits: 1100\n\nconsole.log(a & b); // Devuelve 1000 - 8\nconsole.log(a | b); // Devuelve 1101 - 13\nconsole.log(a ^ b); // Devuelve 0101 - 5\n\n// Para ver las operaciones de desplazamiento de bits se npuede calcular las potencias de 2:\n\nlet c = 2; // en bits: 000010\n\nconsole.log(c << 1); // Devuelve 000100 - 4\nconsole.log(c << 2); // Devuelve 001000 - 8\nconsole.log(c << 3); // Devuelve 010000 - 16\nconsole.log(c << 4); // Devuelve 100000 - 32\n\n// <<<---------------------->>> Estructuras de control <<<---------------------->>>\n\n// ---------------> Condicionales if/else <---------------\n\n// Condicional if\nlet nota1 = 7;\nconsole.log('He realizado mi examen.');\n\n// Condición (si la nota es mayor o igual a 5)\nif (nota1 >= 5) {\n    console.log('¡Estoy aprobado!');\n}\n\n// Condicional if-else\n\nlet nota2 = 7;\nconsole.log('He realizado mi examen. Mi resultado es el siguiente:');\n\nif (nota2 < 5) {\n    // Acción A: nota es menor que 5\n    calificacion = 'suspendido';\n} else {\n    // Acción B: Cualquier otro caso diferente a A (nota es mayor o igual que 5)\n    calificacion = 'aprobado';\n}\n\nconsole.log('Estoy', calificacion);\n\n// ---------------> Condicional switch <---------------\n\n// La estructura de control switch permite definir casos específicos a realizar cuando la variable expuesta como condición sea igual a los valores que se especifican a continuación mediante cada case. En el caso de que no se encuentre una coincidencia entre las opciones el resultado del switch será lo establecido en el case default\n\nlet instrumento = 'oboe';\n\nswitch (instrumento) {\n    case 'trompeta':\n        console.log('Toco la trompeta');\n        break;\n    case 'flauta':\n        console.log('Toco la flauta');\n        break;\n    case 'oboe':\n        console.log('Toco el oboe');\n        break;\n    default:\n        console.log('No toco un instrumento. Lo siento');\n        break;\n}\n\n// ---------------> Ciclos, bucles o loops <---------------\n\n// Ciclo for\n\n//  El bucle FOR se utiliza para repetir una o más instrucciones un determinado número de veces. De entre todos los bucles, el FOR se suele utilizar cuando sabemos seguro el número de veces que queremos que se ejecute. La sintaxis del bucle for se muestra a continuación:\n\n/* for (inicialización; condición; actualización) {\n    //sentencias a ejecutar en cada iteración\n} */\n\n// Ejemplo:\n\nfor (var i = 0; i < 5; i++) {\n    console.log(i);\n}\n\nconsole.log(' Final del bucle for');\n\n// Ciclo for...of\n\n// La sentencia sentencia for...of ejecuta un bloque de código para cada elemento de un objeto iterable, como lo son: String, Array, objetos similares a array,TypedArray, Map (en-US), Set e iterables definidos por el usuario. Su sintaxis es:\n\n/* for (variable of iterable) {\n    statement;\n} */\n\n//Ejemplo:\n\nlet iterable = ['trenes', 'camiones', 'tractores'];\n\nfor (let value of iterable) {\n    console.log(value);\n}\n\nconsole.log(' Final del bucle for...of');\n\n// Ciclo for...in\n\n// La instrucción for-in itera sobre todas las propiedades enumerables de un objeto que está codificado por cadenas (ignorando los codificados por Símbolos, incluidas las propiedades enumerables heredadas). Su sintaxis es:\n\n/* for (variable in objeto) instrucción; */\n\n// Ejemplo:\n\nconst object = { auto: 'mercedes', deporte: 'natacion', trabajo: 'backend' };\n\nfor (const property in object) {\n    console.log(`${property}: ${object[property]}`);\n}\n\nconsole.log(' Final del bucle for...in');\n\n// Ciclo while\n\n// El bucle while empieza por evaluar la condición. Si la condición es verdadera (devuelve true), entonces las sentencias son ejecutadas. Si la condición es falsa (devuelve false), entonces las sentencias no son ejecutadas. Luego el bucle finaliza. Su sintaxis es:\n\n/* while (condicion) {\n    sentencia(s);\n} */\n\n// Ejemplo:\n\nvar i = 1;\nwhile (i < 5) {\n    console.log(i);\n    i++; // i=i+1 esto sería lo mismo\n}\n\nconsole.log(' Final del bucle while');\n\n// Ciclo do-while\n\n// El bucle  do...while está cercanamente relacionado al bucle while . En el bucle  do...while , la condición se evalúa al final. La sintaxis para este bucle es:\n\n/*  do {\n\n   *Sentencias;*\n\n} while (*condicion*); */\n\n// Ejemplo:\n\nvar i = 0;\ndo {\n    i = i + 1;\n    console.log(i);\n} while (i < 5);\n\nconsole.log(' Final del bucle do-while');\n\n// <<<---------------------->>> Ejercicio extra <<<---------------------->>>\n\nfor (let m = 10; m < 56; m++) {\n    if (m % 2 == 0 && m != 16 && m % 3 !== 0) {\n        console.log(m);\n    }\n}\n\n/*El resultado del ejercicio es:\n10\n14\n20\n22\n26\n28\n32\n34\n38\n40\n44\n46\n50\n52 \n*/\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/Ahinar.js",
    "content": "/*Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\nAritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...*/\n\nlet a = 5; //Asignación\nlet b = 18;\nlet c = 5;\nlet d = 5.0;\n\nsuma = a + b; //Operador aritmético de suma\nconsole.log(\"el resultado de sumar \" + a, \"+ \" + b, \"es: \" + suma);\nresta = a - b; // Operador aritmetico resta\nconsole.log(\"El resultado de restar\",a, \"-\", b,\" es :\" + resta);\nmultiplicacion = a * b; //Operador aritmetico multiplicación\nconsole.log(\"El resultado de\", a, \"x\", b, \"es : \" + multiplicacion);\ndivision = a / b; //Operador  aritmetico de la division\nconsole.log(\"El resultado de\", a, \"/\", b, \"es: \" + division);\nmodulo = a % b; //Operador aritmetico modulo\nconsole.log(\"El residuo es:\" + modulo);\npotencia = a ** b; //Operador aritmetico potenciaciado\nconsole.log(a, \"elevado a la potencia\",b ,\"es: \" + potencia);\n\n//logicos\nverdadero = true;\nfalso = false;\n\n//and devuelve verdadero solo si las dos condiciones son verdadderas de lo contrario es falso\nconsole.log(\"\")\nconsole.log(\"Tabla verdad AND\");\nconsole.log(verdadero && verdadero);//verdadero\nconsole.log(verdadero && falso);//falso\nconsole.log(falso && verdadero);//falso\nconsole.log(falso && falso);//falso\n\n//or devuelve verdadero si al menos una de las condiciones es verdadera\nconsole.log(\"\")\nconsole.log(\"Tabla verdad OR\");\nconsole.log(verdadero || verdadero);//verdadero\nconsole.log(verdadero || falso);//verdadero\nconsole.log(falso || verdadero);//verdadero\nconsole.log(falso || falso);//falso\nconsole.log(!false)// negacion devuelve verdadero\nconsole.log(!true)// negación devuelve falso\nconsole.log(!!false)//doble negacion devuelve false\n\n//comparacion\nconsole.log(\"\")\nconsole.log(\"COMPARACIONES\");\nconsole.log(a>b);//devuelve falso porque a no es mayor que b\nconsole.log(a<b);//devuelve verdadero \nconsole.log(a==b);//devuelve falso porque a y b tienen valores diferentes\nconsole.log(a!=b);//devuelve verdadero porque a es distinto de b\nconsole.log(a>=b);//devuelve falso porqueno es mayor o igual que b\nconsole.log(a<=b);//devuelve verdadero porque a es menor o igual a b\nconsole.log(a===b);//devuelve falso \nconsole.log(a===d);//devuelve verdadero porque son iguales y del mismo tipo\nconsole.log(a!==b); //devuelve verdadero porque son distintos\n\n//pertenencia\nconsole.log(\"\")\nconsole.log(\"PERTENENCIA\");\nconst lista = [10,20,30];\nconst string =  \"Hola; javascript\";\nconsole.log(lista.includes (10));// devuelve true\nconsole.log(lista.includes(40))//devuelve false\nconsole.log (string.includes('o'));//devuelve true\nconsole.log (string.includes('e'));//devuelve false\nconsole.log(string.includes(\"hola\")); //devuelve false porque distingue entre mayusculas y minusculas\n\n//estructuras de control condicional if\nconsole.log(\"\")\npuntaje=300;\npuntajeNecesario=500;\n\nif(puntaje >= puntajeNecesario){//calcula si el puntaje sacado  es mayor o igual al necesario para ganar\n    console .log (\"Ganaste el premio!\");\n}else{\n   console.log(\"No ganaste el premio\");  \n}\n\nclima = \"nublado\";\nif (clima === \"soleado\"){\n    console.log(\"Es un dia hermoso para salir.\");\n} else if (clima ===\"lluvioso\" || clima==\"nublado\") {\n    console.log(\"Vamos a llevar un paraguas.\")\n} else {\n    console.log(\"no tenemos datos exactos del clima.\")\n}\n\n//estructura de control repetitiva\nnumero = 0;\nwhile (numero <= 5){\n    console.log(numero);\n    numero= numero +1 ;\n}\n\n//estructura de control iterativa\nfor (i=0;i < string.length;i++){//recorre  cada letra de la cadena de texto e imprime cada caracter\n    console.log(string[i]);\n}\n\n/*DIFICULTAD EXTRA (opcional):\nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3 */\n\nfor (let i = 10; i<=55; i++) {\n    if (i % 2===0 && i !== 16 && i %  3!==0) {\n        console.log(i);\n    }        \n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/Airesesteban.js",
    "content": "let num1 = 2\nlet num2 = 5\n\nconsole.log (\"Operadores de comparación\")\n\nconsole.log(2 == num1)//igual\nconsole.log(num1 != 3)//No es Igual\nconsole.log(\"2\" === num1)//Estrictamente igual\nconsole.log(\"2\" !== num1)//Desigualdad estricta\nconsole.log(num2 > num1)//Mayor que\nconsole.log(num2 >= num1)//Mayor o igual que\nconsole.log(num1 < num2)//Menor que\nconsole.log(num1 <= num2)//Menor o igual que\n\nconsole.log (\"Operadores aritméticos\")\n\nconsole.log(num1 + num2) // Suma\nconsole.log(num1 - num2) // Resta\nconsole.log(num1 * num2) // Multiplicación\nconsole.log(num1 / num2) // División\nconsole.log(num1 % num2) // Resto\nconsole.log(num1 ++)// Incremento\nconsole.log(num1 --) // Decremento\n\n\nconsole.log (\"Operadores bit a bit\")\n\nlet a = 10\nlet b = 2\n\nconsole.log(a & b) // AND bit a bit\nconsole.log(a | b) // OR bit a bit\nconsole.log(a ^ b) // XOR bit a bit\nconsole.log(~a)    // NOT bit a bit\nconsole.log(a << 1) // Desplazamiento a la izquierda\nconsole.log(a >> 1) // Desplazamiento a la derecha\nconsole.log(a >>> 1)// Desplazamiento a la derecha sin signo\n\nconsole.log (\"Operadores lógicos\")\n\nlet myNumber = 8\nlet myNumber2 = 5\n\nlet resultado = (myNumber > myNumber2) && (myNumber2 > 0)\nconsole.log(resultado) // Salida: true\n\nlet resultado1 = (myNumber < myNumber2) || (myNumber2 >0)\nconsole.log(resultado1)  // Salida: true\n\nlet resultado2 = !(myNumber < myNumber2)\nconsole.log(resultado2)  // Salida: true\n\nconsole.log(\"Operadores de cadena\")\n\nlet word = \"javascript\"\nconsole.log(\"Hola desde\" + \" \" + word) // Operador de concatenación\n\nconsole.log(\"Operador condicional (Ternario)\")\n\nlet edad = 18\nlet result = edad >= 18 ? \"Es mayor de edad\" : \"Es menor de edad\"\nconsole.log(result)\n\n/*\nUtilizando las operaciones con operadores que tú quieras, crea ejemplos\nque representen todos los tipos de estructuras de control que existan\nen tu lenguaje:\nCondicionales, iterativas, excepciones...\n*/\n\n// Condicional\n\nif (edad >= 18){\n    console.log(\"Eres mayor de edad\")\n}else{\n    console.log(\"Eres menor de edad\")\n}\n\n// Bucle for\n\nlet mult = 5\nfor (let i = 1; i <=10; i++){\n    console.log(`${mult} x ${i} = ${mult * i}`)\n}\n\n// Bucle forEach\nlet paises = [\"Argentina\", \"España\", \"Noruega\", \"Luxemburgo\"]\npaises.forEach(pais => {\n    console.log(pais)\n})\n\n// Bucle for...in\nfor (let pais in paises) {\n    console.log(paises[pais])\n}\n\n// Bucle while\n\nlet num = 1\nwhile ( num >= 10){\n    if (num% 2 == 0){\n        console.log(`${num} es par`)\n    }\n    num++\n}\n\n// Bucle Do While\nnum = 1\ndo{\n    if(num % 2 == 0){\n        console.log(`${num} es par`)\n    }\n    num++\n}while(num >=10)\n\n// Switch\nlet mes = 4\n\nswitch (mes){\n    case 1:\n        console.log(\"Enero\")\n        break;\n    case 2:\n        console.log(\"Febrero\")\n        break;\n    case 3:\n        console.log(\"Marzo\")\n        break;\n    case 4:\n        console.log(\"Abril\")\n        break;\n    default:\n        console.log(\"Numero de mes no válido\")\n}\n\n/*\n  Crea un programa que imprima por consola todos los números comprendidos\n  entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n*/\n\nfor (let i = 10; i <= 55; i++){\n    if(i % 2 ==0 && i != 16 && i % 3 !== 0){\n        console.log(i)\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/AitorLcom.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n//Operador de asiganción\nlet a = 1;\nlet b = 2;\n//Operadores de comparación\nlet igual = a == b;\nlet diferente = a != b;\nlet mayorQue = a > b;\nlet menorQue = a < b;\nlet mayorIgualQue = a >= b; // igual para <=\nlet estrictamenteIgual = a === b; //Compara valor y tipo\nlet estrictamenteDiferente = a !== b; //Compara valor y tipo\n//Operadores aritmeticos\nlet suma = a + b;\nlet resta = a - b;\nlet multiplicacion = a * b;\nlet division = a / b;\nlet moudlo = a % b; //Devuelve el resto de la división\nlet exponete = a ** b;\nlet incremento = a++;\nlet decremento = a--;\n//Operadores lógicos\nlet and = a && b;\nlet or = a || b;\nlet negacion = a != b;\n//Operador ternario (condicional)\nlet ternario = a >= b ? \"es mayor\" : \"es menor\";\n//Existen operadores unarios, que operan con un solo operandor. Ademas de los de incremento y decremento y el de asiganción hay algunos especiales:\n/*Operadores unarios especiales:\n    - delete (elimina una propiedad de un objeto)\n    - typeof (devuelve el tipo de dato)\n    - void (ejecuta la expresion pero no devuelve nada, se usa para ejecutar funciones que devuelven algo y no queremos ese valor)\n    - in (devuelve true si el operando es propiedad del objeto)\n    - instanceof (devuelve true si el operando es instancia de la clase o constructor)\n*/\n//Ejemplos de tipos de estructuras de control de JavaScript\n//Condicionales\nif (a === b) {\n  console.log(\"a y b son iguales\");\n} else if (a > b) {\n  console.log(\"a es mayor que b\");\n} else {\n  console.log(\"b es mayor que a\");\n}\n\nswitch (a) {\n  case \"uno\":\n    console.log(\"a es uno\");\n    break;\n  case 1:\n    console.log(\"a es 1\");\n    break;\n  case b:\n    console.log(\"a es igual q b\");\n    break;\n}\n\n//Bucles\nfor (let i = 0; i < 2; i++) {\n  console.log(\"el valor de i en este bucle for es = \" + i);\n}\n\nwhile (a < 3) {\n  console.log(\"el valor de a en este bucle while es = \" + a);\n  a++;\n}\n\ndo {\n  console.log(\"el valor de b en este do while es = \" + b);\n  b++;\n} while (b < 5);\n\n//Función que imprime en consola todos los numeros entre 10 y 55 que no son multiplos de 3 ni el numero 16\n\nlet impDel10Al55 = function(){\n    for (let i = 10; i <= 55; i++){\n        if (i % 3 !== 0 && i !== 16){\n            console.log(i);\n        }\n    }\n}\nimpDel10Al55();"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/Akzorla.js",
    "content": "/* 01 - OPERADORES Y ESTRUCTURAS DE CONTROL\nCrea ejemplos utilizando todos los tipos de operadores de tu lenguaje: Aritméticos, lógicos, de comparación asignación, identidad, pertenencia, bits...(Ten en cuenta que cada lenguaje puede poseer unos diferentes).\nUtilizando las operaciones con operadores que tú quieras, crea ejemplos que representen todos los tipos de estructuras de control que existan en tu lenguaje: Condicionales, iterativas, excepciones...\nDebes hacer print por consola del resultado de todos los ejemplos.\n \nDIFICULTAD EXTRA (opcional):\nCrea un programa que imprima por consola todos los números comprendidos entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n*/\n\n//------------> OPERADORES ARITMETICOS \n\nlet suma = 5 + 5;               // SUMA\nlet resta = 3 - 1;              // RESTA\nlet multiplicación = 2 * 2;     // MULTIPLICACION\nlet division = 2 / 2;           // DIVISION\nlet resto = 7 % 2;              // RESTO\nlet potencia = 1 ** 5;          // POTENCIA\ni++;                            // SUMA 1 AL VALOR DE i Y RETORNA i\ni--;                            // RESTA 1 AL VALOR DE i Y RETORNA i\n++i;                            // SUMA 1 AL VALOR DE i RETORNA EL RESULTADO DE LA OPERACION POSTERIOR\n--i;                            // RESTA 1 A AL VALOR DE i Y RETORNA EL RESULTADO DE LA OPERACION POSTERIOR\n\n\n//------------> OPERADORES LOGICOS\nlet valorFalse = false;\nlet valorTrue = true;\n\n//---> AND \n// DEBE CUMPLIR AMBAS CONDICIONES\nlet andA = valorTrue && valorTrue;      // DEVUELVE TRUE\nlet andB = valorTrue && valorFalse;     // DEVUELVE FALSE\nlet andC = valorFalse && valorTrue;     // DEVUELVE FALSE\nlet andD = valorFalse && valorFalse;    // DEVUELVE FALSE\n\n//---> OR \n// DEBE CUMPLIR AL MENOS UNA DE LAS CONDICIONES \nlet orA valorTrue || valorTrue;         // DEVUELVE TRUE\nlet orB valorTrue || valorFalse;        // DEVUELVE TRUE\nlet orC valorFalse || valorTrue;        // DEVUELVE TRUE\nlet orD valorFalse || valorFalse;       // DEVUELVE FALSE\n\n//---> !(NOT)\n// INVIERTE EL VALOR\nlet notA = !valorTrue;                  // DEVUELVE FALSE\nlet notB = !valorFalse;                 // DEVUELVE TRUE\n\n\n//------------> OPERADORES DE COMPARACION E IDENTIDAD\nlet A = 1\nlet B = 2\n\nlet comparacionA = A == B;      // ES \"false\", DEVUELVE \"true\" SI LOS VALORES SON IGUALES\nlet comparacionB = A != B;      // ES \"true\",  DUEVELVE \"true\" SI LOS VALORES SON DIFERENTES\nlet comparacionC = A === B;     // ES \"false\", DEVUELVE \"true\" SI LOS VALORES SON IGUALES Y DEL MISMO TIPO\nlet comparacionD = A !== B;     // ES \"true\",  DEVUELVE \"true\" SI LOS VALORES SON DIFERENTES Y DEL MISMO TIPO\nlet comparacionE = A > B;       // ES \"false\", DEVUELTE \"true\" SI EL VALOR DE A ES MAYOR QUE EL DE B\nlet comparacionF = A >= B;      // ES \"false\", DEVUELVE \"true\" SI EL VALOR DE A ES MAYOR O IGUAL QUE EL DE B\nlet comparacionG = A < B;       // ES \"true\",  DEVUELVE \"true\" SI EL VALOR DE A ES MENOR QUE EL DE B\nlet comparacionH = A <= B;      // ES \"true\",  DEVUELVE \"true\" SI EL VALOR DE A ES MENOR O IGUAL QUE EL DE B\n\n\n//------------> OPERADORES DE ASIGNACION\nlet x = 2;\nlet y = 6;\n\nlet asignaciónA = x += y;     // ES IGUAL A X = X + Y\nlet asignacionB = x -= y;     // ES IGUAL A X = X - Y\nlet asignacionC = x *= y;     // ES IGUAL A X = X * Y\nlet asignacionD = x /= y;     // ES IGUAL A X = X / y\nlet asignacionE = x %= y;     // ES IGUAL A X = X % Y\nlet asignacionF = x **= y;    // ES IGUAL A X = X ** Y\nlet asignacionG = x &&= y;    // ES IGUAL A X = X && Y\nlet asignacionH = x ||= y;    // ES IGUAL A X = X || Y\n\n\n//------------> OPERADORES DE PERTENECIA\nlet arr = [0,1,2];\n\nconst resA = 1 in arr;      // DEVUELVE \"true\" EL VALOR DE 1 ESTA EN EL ARRAY\nconst resB = 5 in arr;      // DEVUELVE \"fasle\" EL VALOR DE 5 NO ESTA EN ARRAY\n\n\n//------------> OPERADORES DE TIPO DE DATO\n//USANDO typeof DEVUELVE EL TIPO DE DATO QUE SE ESTA EVALUANDO\nlet datoA = 5;\nlet datoB = \"hola\";\nlet datoC = true;\nlet datoD = undefined;\n\nlet tipoDatoA = typeof(datoA); //DEVUELVE \"number\"\nlet tipoDatoB = typeof(datoB); //DEVUELVE \"string\"\nlet tipoDatoC = typeof(datoC); //DEVUELVE \"boolean\"\nlet tipoDatoD = typeof(datoD); //DEVUELVE \"undefined\"\n\n\n//------------> OPERADOR CONCATENACION\nlet textoA = \"Hola \";\nlet textoB = \"MUNTO!\";\n\nlet textoCompleto = (textoA + textoB);\n\n\n//HAY VARIOS MAS, PERO ESTOS SON LOS PRINCIPALES\n\n\n//--------------------> ESTRUCTURA DE CONTROL\n//IF - ELSE    \n\nlet edad = 17;\n\nif (edad < 16 ){\n    console.log(\"La entrada solo esta permitida a mayores de 16 años\");\n} else if (edad >= 16 && edad < 18) {\n    console.log(\"Puede entrar pero no consumir bebidas alcoholicas\");\n} else {\n    console.log(\"Puede pasar\")\n}\n\n\n// SWITCH\n\nlet mesDelAño = 7;\n\nswitch(mesDelAño){\n    case 1:\n        console.log('Enero');\n        break;    \n\n    case 2:\n        console.log('Febrero');\n        break;\n\n    case 3:\n        console.log('Marzo');\n        break;\n\n    case 4:\n        console.log('Abril');\n        break;\n    \n    case 5:\n        console.log('Mayo');\n        break;\n\n    case 6:\n        console.log('Junio');\n        break;\n\n    case 7:\n        console.log('Julio');\n        break;\n\n    case 8: \n        console.log('Agosto');\n        break;\n    \n    case 9:\n        console.log('Septiembre');\n        break;\n    \n    case 10:\n        console.log('Octubre');\n        break;\n\n    case 11:\n        console.log('Noviembre');\n        break;\n    \n    case 12:\n        console.log('Diciembre');\n        break;\n    \n    default\n        console.log('Debe indicar un numero entre el 1 y el 12');\n\n}\n\n// FOR\n\nfor(let i = 0; i < 5; i++){\n    console.log(i);\n}\n\n\n//FOREACH \n\nlet animales = ['perro', 'gato', 'tigre', 'elefante', 'leon', 'mono'];\n\nanimales.forEach(animal => console.log(animal));\n\n\n//FOR OF\n\nlet animales = ['perro', 'gato' , 'tigre'];\n\nfor (let animal of animales){\n    console.log(animal);\n}\n\n\n//FOR IN\n\nlet user = {\n    id: 1;\n    nombre: 'uno';\n}\n\nfor(let valor in user){\n    console.log(valor);\n}\n\n\n//WHILE\n\nlet i = 0;\n\nwhile(i < 5){\n    i++\n    console.log(i);\n}\n\n\n//DO WHILE\n\nlet i = 0\n\ndo {\n    console.log(i);\n    i++;\n} while (i < 5);\n\n\n/*\n    DIFICULTAD EXTRA:\n    Crea un programa que imprima por consola todos los números comprendidos\n    entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3\n*/\n\nfor (let i = 10; i <= 55, i++){\n    if(i % 2 === 0 && i !== 16){\n        if(i % 3 !== 0){\n            console.log(i);\n        }\n    }\n        \n}\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/Alanox1.js",
    "content": "\n// Operadores Aritméticos\n\nlet a = 10;\nlet b = 5;\n\nconsole.log(\"Suma:\", a + b);         // 15\nconsole.log(\"Resta:\", a - b);        // 5\nconsole.log(\"Multiplicación:\", a * b); // 50\nconsole.log(\"División:\", a / b);     // 2\nconsole.log(\"Módulo:\", a % b);       // 0\nconsole.log(\"Exponenciación:\", a ** b); // 100000\n\n\n\n\n\n\n\n// Operadores Lógicos\n\nlet x = true;\nlet y = false;\n\nconsole.log(\"AND lógico:\", x && y); // false\nconsole.log(\"OR lógico:\", x || y);  // true\nconsole.log(\"NOT lógico:\", !x);     // false\n\n\n\n\n\n\n// Operadores de Comparación\nlet p = 10;\nlet q = 20;\n\nconsole.log(\"Igual a:\", p == q);        // false\nconsole.log(\"No igual a:\", p != q);     // true\nconsole.log(\"Mayor que:\", p > q);       // false\nconsole.log(\"Menor que:\", p < q);       // true\nconsole.log(\"Mayor o igual que:\", p >= q); // false\nconsole.log(\"Menor o igual que:\", p <= q); // true\n\n\n\n\n\n\n\n// Operadores de Asignación\nlet n = 5;\n\nn += 3; // n = n + 3\nconsole.log(\"Asignación de suma:\", n); // 8\n\nn -= 2; // n = n - 2\nconsole.log(\"Asignación de resta:\", n); // 6\n\nn *= 4; // n = n * 4\nconsole.log(\"Asignación de multiplicación:\", n); // 24\n\nn /= 3; // n = n / 3\nconsole.log(\"Asignación de división:\", n); // 8\n\nn %= 2; // n = n % 2\nconsole.log(\"Asignación de módulo:\", n); // 0\n\n\n\n\n\n\n\n\n// Operadores de Identidad\n\nlet r = 5;\nlet s = \"5\";\n\nconsole.log(\"Identidad (igual):\", r === s); // false\nconsole.log(\"Identidad (no igual):\", r !== s); // true\n\n\n\n\n\n\n\n\n\n// Operadores de Pertenencia\n\nlet arr = [1, 2, 3, 4, 5];\n\nconsole.log(\"Pertenencia (en array):\", arr.includes(3)); // true\nconsole.log(\"Pertenencia (no en array):\", arr.includes(6)); // false\n\n\n\n\n\n\n\n// Operadores de Bits\n\nlet m = 5;  // 0101 en binario\nlet ñ = 3;  // 0011 en binario\n\nconsole.log(\"AND bit a bit:\", m & ñ); // 1 (0001 en binario)\nconsole.log(\"OR bit a bit:\", m | ñ);  // 7 (0111 en binario)\nconsole.log(\"XOR bit a bit:\", m ^ ñ); // 6 (0110 en binario)\nconsole.log(\"Complemento bit a bit:\", ~m); // -6 (invertido en binario)\nconsole.log(\"Desplazamiento a la izquierda:\", m << 1); // 10 (1010 en binario)\nconsole.log(\"Desplazamiento a la derecha:\", m >> 1); // 2 (0010 en binario)\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n// Condicionales\n\nlet age = 20;\n\nif (age < 18) {\n    console.log(\"Eres menor de edad.\");\n} else if (age >= 18 && age < 65) {\n    console.log(\"Eres adulto.\");\n} else {\n    console.log(\"Eres mayor de edad.\");\n}\n\n\n\n\n\n// Iterativas\n\n\n// Bucle for\nfor (let i = 0; i < 5; i++) {\n    console.log(\"Bucle for, iteración:\", i);\n}\n\n// Bucle while\nlet j = 0;\nwhile (j < 5) {\n    console.log(\"Bucle while, iteración:\", j);\n    j++;\n}\n\n// Bucle do-while\nlet k = 0;\ndo {\n    console.log(\"Bucle do-while, iteración:\", k);\n    k++;\n} while (k < 5);\n\n\n\n\n\n// Excepciones\n\ntry {\n    let result = 10 / 0;\n    if (!isFinite(result)) {\n        throw new Error(\"División por cero\");\n    }\n    console.log(\"Resultado:\", result);\n} catch (error) {\n    console.log(\"Error capturado:\", error.message);\n} finally {\n    console.log(\"Bloque finally ejecutado.\");\n}\n\n\n\n\n\n\n\n\n\n// * DIFICULTAD EXTRA (opcional):\n//   * Crea un programa que imprima por consola todos los números comprendidos\n//   * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n//   *\n//   * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\n    \nfunction imprimir_numeros(){\n    for ( let x = 10; x < 56; x++){\n        if (x >= 10 && x <=55 && x % 2 === 0 && x != 16 && x % 3 != 0) {\n          console.log(x)\n        }\n    }\n    \n}\nimprimir_numeros()\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/Aleoe01.js",
    "content": "// Operadores aritméticos\nlet suma = 5 + 3;\nlet resta = 6 - 2;\nlet division = 10 / 2;\nlet multiplicacion = 7 * 8;\nlet resto = 15 % 2;\n\n// Operadores de asignacion\nlet x = 1;\nx = x + 4; // adición x=5\nx = x - 2; // sustración x=3\nx = x * 3; // multiplicacion x=9\nx = x / 3; // division x=3\nx = x % 2; // resto x=1\n\n// pre incremento\nlet a = 4;\nlet b = ++a * 2;\nconsole.log(b); // Imprime 10 y establece a=5\n// post incremento\nlet c = 4;\nlet d = c++ * 2;\nconsole.log(d); // Imprime 8 y establece c=5\n// pre decremento\nlet e = 5;\nlet f = --e * 2;\nconsole.log(f); // Imprime 8 y establece e=4\n// post decremento\nlet g = 5;\nlet h = g-- * 2;\nconsole.log(h); // Imprime 10 y establece g=4\n\n// Operadores de comparacion\nlet num1 = 5;\nlet num2 = 2;\nlet bool1 = num1 > num2; // bool1 = true\nlet bool2 = num1 < num2; // bool2 = false\nlet bool3 = num1 <= num2; // bool3 = flase\nlet bool4 = num1 >= num2; // bool3 = false\nlet bool5 = num1 === num2; // bool5 = false\nlet bool6 = num1 !== num2; // bool6 = true\n\n// Operadores logicos\n//AND\nlet and1 = true && true; // log1 = true\nlet and2 = true && false; // log2 = false\nlet and3 = false && true; // log3 = false\n//OR\nlet or1 = true || true; // or1 = true\nlet or2 = true || false; // or2 = true\nlet or3 = false || true; // or3 = true\nlet or4 = false || false; // or3 = false\n\n// Operadores de Negacion\nlet verdadero = true;\nlet falso = false;\nconsole.log(!verdadero); // Imprime false\nconsole.log(!falso); // Imprime true\nconsole.log(!!verdadero); // Imprime true\n\n// Operadores de identidad o igualdad\nlet igual1 = 2 === 2; // igual1 = true\nlet igual2 = 2 === \"2\"; // igual2 = false\nlet igual3 = 2 !== 2; // igual3 = false\nlet igual4 = 2 !== 3; // igual4 = true\n\n// Operador typeof\nlet type1 = 5;\nlet type2 = \"alejandro\";\nlet type3 = true;\nlet type4 = undefined;\nconsole.log(typeof type1); // Imprime \"number\"\nconsole.log(typeof type2); // Imprime \"string\"\nconsole.log(typeof type3); // Imprime \"boolean\"\nconsole.log(typeof type4); // Imprime \"undefined\"\n\n// Operador de concatenacion\nlet cad1 = \"Hola\";\nlet cad2 = \"JavaScript\";\nconsole.log(cad1 + \" \" + cad2); // Imprime \"Hola JavaScript\"\n\n// Estructuras de control\n\n// if...else\nlet nota = 8;\nif (nota >= 6) {\n  console.log(\"materia apobada con \" + nota);\n} else {\n  console.log(\"desaprobó con un \" + nota);\n}\n\n// Switch\nlet numeroMes = 3;\nswitch (numeroMes) {\n  case 1:\n    console.log(\"Enero\");\n    break;\n  case 2:\n    console.log(\"Febrero\");\n    break;\n  case 3:\n    console.log(\"Marzo\");\n    break;\n  case 4:\n    console.log(\"Abril\");\n    break;\n  case 5:\n    console.log(\"Mayo\");\n    break;\n  case 6:\n    console.log(\"Junio\");\n    break;\n  case 7:\n    console.log(\"Julio\");\n    break;\n  case 8:\n    console.log(\"Agosto\");\n    break;\n  case 9:\n    console.log(\"Septiembre\");\n    break;\n  case 10:\n    console.log(\"Octubre\");\n    break;\n  case 11:\n    console.log(\"Noviembre\");\n    break;\n  case 12:\n    console.log(\"Diciembre\");\n    break;\n  default:\n    console.log(\"el numero ingresado no corresponde a un mes\");\n}\n\n// For\nfor (let x = 0; x < 5; x++) {\n  console.log(x + 1); // 1,2,3,4,5\n}\n\n// ForEach\nlet numeros = [0, 1, 2, 3, 4, 5];\nnumeros.forEach(function (numero) {\n  console.log(numero);\n});\n\n// While\nlet contador = 1;\nwhile (contador <= 5) {\n  console.log(contador); // 1,2,3,4,5\n  contador++;\n}\n\n// Do While\nlet cuentaRegresiva = 5;\ndo {\n  console.log(cuentaRegresiva); // 5,4,3,2,1\n  cuentaRegresiva--;\n} while (cuentaRegresiva !== 0);\n\n/*\n    DIFICULTAD EXTRA:\n    Crea un programa que imprima por consola todos los números comprendidos\n    entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3\n*/\n\nfor (let i = 10; i <= 55; i++) {\n  if (i % 2 == 0 && i !== 16) {\n    if (i % 3 !== 0) {\n      console.log(i);\n    }\n  }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/AlexanderTejedor.js",
    "content": "// Operadores de asignación \n\n/**Asignación */\nvar x = 5; // x = y;\nvar y = 10;\nconsole.log(x);\n/**Asignación de adición */\nx += y; // x = x + y;\nconsole.log(x);\n/**Asignación de resta */\nx -= y; // x = x - y;\nconsole.log(x);\n/**Asignación de multiplicación */\nx *= y; // x = x * y;\nconsole.log(x);\n/**Asignación de división */\nx /= y; // x = x / y;\nconsole.log(x);\n/**Asignación de residuo */\nx %= y; // x = x % y;\nconsole.log(x);\n/**Asignación de exponenciación */\nx **= y; // x = x ** y;\nconsole.log(x);\n/**Asignación de desplazamiento a la izquierda */\nx <<= y; // x = x << y;\nconsole.log(x);\n/**Asignación de desplazamiento a la derecha */\nx >>= y; // x = x >> y;\nconsole.log(x);\n/**Asignación de desplazamiento a la derecha sin signo*/\nx >>>= y; //x = x >>> y\nconsole.log(x);\n/**Asignación AND bit a bit*/\nx &= y; // x = x & y;\nconsole.log(x);\n/**Asignación XOR bit a bit*/\nx ^= y; // x = x ^ y;\nconsole.log(x);\n/**Asignación OR bit a bit*/\nx |= y; // x = x | y;\nconsole.log(x);\n/**Asignación AND lógico*/\nx &&= y; // x && (x = y);\nconsole.log(x);\n/**Asignación OR lógico*/\nx ||= y; // x || (x = y);\nconsole.log(x);\n/**Asignación de anulación lógica */\nx ??= y; // x ?? (x = y)\nconsole.log(x);\n\n// Operadores de comparación \nvar x = 10;\nvar y = 15;\nvar var1 = true;\nvar var2 = false;\n\n/**Igualdad */\nvar z = var1 == var2;\nconsole.log(z);\n/**No es igual */\nvar z = var1 != var2;\nconsole.log(z);\n/**Estrictamente igual */\nvar z = x === y;\nconsole.log(z);\nvar a = var1 === var2;\nconsole.log(a);\n/**Desigualdad estricta */\nvar z = var1 !== var2;\nconsole.log(z);\n/**Mayor que */\nvar z = x > y;\nconsole.log(z);\n/**Mayor o igual que */\nvar z = x >= y;\nconsole.log(z);\n/**Menor que */\nvar z = x < y;\nconsole.log(z);\n/**Menor o igual que */\nvar z = x <= y;\nconsole.log(z)\n\n//Operadores aritméticos\nvar x = 12;\nvar y = 5;\n\n/**Residuo */\nvar z = x % y;\nconsole.log(z);\n/**Incremento */\nvar z = x++;\nconsole.log(z);\nvar b = ++x;\nconsole.log(b);\n/**Decremento */\nvar z = x--;\nconsole.log(z);\nvar b = --x;\nconsole.log(b);\n/**Negación Unitaria */\nvar z = -x;\nconsole.log(z);\n/**Positivo Unitario */\nvar z = +\"3\";\nconsole.log(z, typeof(z));\n/**Operador de exponenciación */\nvar z = x ** y;\nconsole.log(z);\n\n//Operadores bit a bit\nvar a = 1;\nvar b = 0;\n\n/**AND a nivel de bits */\nvar z = a & b;\nconsole.log(z);\n/**OR a nivel de bits */\nvar z = a | b;\nconsole.log(z);\n/**XOR a nivel de bits */\nvar z = a ^ b;\nconsole.log(z);\n/**NOT a nivel de bits */\nvar z = ~ a;\nconsole.log(z);\n/**Desplazamiento a la izquierda */\nvar z = a << b;\nconsole.log(z);\n/**Desplazamiento a la derecha de propagación de signo */\nvar z = a >> b;\nconsole.log(z);\n/**Desplazamiento a la derecha de relleno cero */\nvar z = a >>> b;\nconsole.log(z);\n\n//Operador de desplazamiento de bits\nvar a = 9;\nvar b = 2;\n\n/**Desplazamiento a la izquierda */\nconsole.log(a << b);\n/**Desplazamiento a la derecha de propagación de signo */\nconsole.log(a >> b);\n/**Desplazamiento a la derecha de relleno cero */\nconsole.log(a >>> b);\n\n//Operadores Lógicos\nlet expr1 = true;\nlet expr2 = false;\n\n/**AND lógico */\nconsole.log(expr1 && expr2);\n/**OR Lógico */\nconsole.log(expr1 || expr2);\n/**NOT Lógico */\nconsole.log(!expr1);\nconsole.log(!expr2);\n\n//Operador de Cadena\nconsole.log('Hola ' + 'JavaScript' );\n\nlet hello = 'Hola ';\nconsole.log(hello += 'JavaScript');\n\n//Operador condicional (ternario)\nlet val1 = 20;\nlet val2 = 15;\n\nlet isAdult = val2 >= 18 ? 'Adult' : 'Minor';\nconsole.log(isAdult);\n\n//Operador unarios\n\n/**DELETE */\nx = 42;\nvar o = 43;\nvar myObj = { h:4, }\n\nconsole.log(delete x);\nconsole.log(delete o);\nconsole.log(delete Math.PI);\nconsole.log(delete myObj.h);\n\n/**typeof */\nlet myFun = new Function('5 + 2');\nlet myName = 'Alexander';\nvar age = 26;\nlet fruit = ['apple', 'wathermelon', 'Banana'];\n\nconsole.log(typeof(myFun));\nconsole.log(typeof(myName));\nconsole.log(typeof(age));\nconsole.log(typeof(fruit));\nconsole.log(typeof(true));\n\n//Estructuras de control en JavaScript\n\n/** Condicionales\n * if - else if\n * Confirmar si una persona es mayor de edad \n * */\nvar age = 10;\nif (age >= 18 ){\n    console.log('Eres mayor de edad, puedes pasar')\n} else if (age < 18) {\n    console.log('Lo sentimos, pero no puedes pasar')\n} else if (age != Number) {\n    console.log('Por favor ingresa un dato valido')\n}\n/**Swith\n * Mensaje dependiendo del día\n */\nlet day = 'lunes';\nswitch (day) {\n    case 'lunes':\n        console.log(`perfecto hoy es ${day}`)\n        break;\n    case 'martes':\n        console.log(`perfecto hoy es ${day}`)\n        break;\n    case 'miercoles':\n        console.log(`perfecto hoy es ${day}`)\n        break;\n    case 'jueves':\n        console.log(`perfecto hoy es ${day}`)\n        break;\n    case 'viernes':\n        console.log(`perfecto hoy es ${day}`)\n        break;\n    default:\n        console.log(`Perfectooo es Fin de Semana`)\n}\n\n/**Bucles (Iteraciones)\n * for\n */\nfor (let i = 0; i < 5; i++ ){\n    console.log(i)\n}\n\n/**Recorrido de un array */\nlet food = ['Meat','Beans','Milk','Potatos','Tomatos','Eggs'];\n\nfor (let i = 0; i < food.length; i++ ){\n    let list = food[i]\n    console.log(`The food in your list is ${list}`)\n}\n\n/**While */\nlet suma = 0;\nlet numero = 1;\n\nwhile (numero <= 10){\n    console.log('Suma ', suma += numero);\n    console.log('Numero ', numero++);\n}\n\n/**do while */\n\nlet result = '';\nlet i = 0;\n\ndo {\n    i = i + 1;\n    result = result + i;\n} while (i < 5);\nconsole.log(result);\n\n/**for in */\nconst object = {a:1, b:2, c:3}\n\nfor (const property in object){\n    console.log(`${property}: ${object[property]}`);\n}\n\n/**for of */\nconst array1 = [\"a\", \"b\", \"c\"];\n\nfor (const element of array1) {\n    console.log(element);\n}\n\nlet persona = { nombre: \"Alexander\", edad: 26, ciudad: \"Colombia\" };\n\nfor (let clave in persona) {\n    console.log(clave + \": \" + persona[clave]);\n}\n\n/**Control de excepciones\n * try catch\n */\n\ntry {\n    let resultado = 10 / 0;\n    console.log(resultado);\n} catch (error) {\n    console.log(\"Se ha producido un error: \" + error.message);\n}\n\n/**throw */\n\nfunction verificarEdad(edad) {\n    if (edad < 18) {\n        throw new Error(\"No puedes acceder, eres menor de edad.\");\n    }\n    return \"Acceso permitido.\";\n}\n\n/**finally */\n\ntry {\n    console.log(\"Intentando ejecutar código...\");\n} catch (error) {\n    console.log(\"Error encontrado: \" + error.message);\n} finally {\n    console.log(\"Este código se ejecuta siempre.\");\n}\n\n/**\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n */\n\nfor (i = 10; i <= 55; i++){\n    let result = i / 3;\n    if (i % 2 === 0 && Number.isInteger(result) === false){\n        if (i === 16){ continue };\n        console.log(i);\n    };\n};\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/Alvaro-Neyra.js",
    "content": "// Tipos de operadores en JavaScript:\n\n// Operadores de Asignacion:\n\n// Operador de asignacion (=):\n// Asignando un valor a una variable con =:\nlet miVariable = \"Soy una variable\";\nconsole.log(miVariable);\n// Operador Asignacion de adicion (+=):\nlet numeroASumar = 20;\nnumeroASumar += 1;\nconsole.log(numeroASumar); // 21\n// Operador Asignacion de resta (-=):\nlet numeroARestar = 70;\nnumeroARestar -= 10;\nconsole.log(numeroARestar); // 60\n// Operador Asignacion de multiplicacion (*=):\nlet numeroAMultiplicar = 60;\nnumeroAMultiplicar *= 5;\nconsole.log(numeroAMultiplicar); // 300\n// Operador Asignacion de division (/=):\nlet numeroADividir = 40;\nnumeroADividir /= 2;\nconsole.log(numeroADividir); // 20\n// Operador Asignacion de residuo (%=):\nlet numeroAModular = 30;\nnumeroAModular %= 3;\nconsole.log(numeroAModular); // 0\n// Operador Asignacion de exponenciacion (**=):\nlet numeroAExponenciar = 12;\nnumeroAExponenciar **= 5;\nconsole.log(numeroAExponenciar);\n// Operador Asignacion de desplazamiento a la izquierda (<<=):\nlet numeroABinario = 5; // En binario: 101\nlet vecesADesplazarIzquierda = 3;\nnumeroABinario <<= vecesADesplazarIzquierda; /* 101000 --> 40 // Los numeros del extremo derecho se pasan a la izquierda y el lugar en donde \n                                    estaban los numeros que se han desplazado se reemplazan por ceros */\nconsole.log(numeroABinario);\n// Operador Asignacion de desplazamiento a la derecha (>>=):\nlet numeroABinario1 = 8; // En binario: 1000\nlet vecesADesplazarDerecha = 2;\nnumeroABinario1 >>= vecesADesplazarDerecha; /* 0010  --> 2 // Los numeros del extremo izquierdo se pasan a la derecha y el lugar en donde\n                                            estaban los numeros que se han desplazado se reemplazan por ceros*/\nconsole.log(numeroABinario1)\n// Operador Asignacion de desplazamiento a la derecha sin signo (>>>=):\nlet numeroABinarioNegativo = -8;\nlet vecesADesplazarDerechaSinSigno = 2;\nnumeroABinarioNegativo >>>= vecesADesplazarDerechaSinSigno; /* 0b00111111111111111111111111111110 --> 1073741822 // Realiza el desplazamiento\n                                                            sin importar el signo */\nconsole.log(numeroABinarioNegativo);\n// Operador Asignacion AND bit a bit (&=):\nlet convertirABinarioAND = 8; // --> 0b1000\nconvertirABinarioAND &= 2; // --> 0b1000 & (AND) 0b0010 --> 00000 --> 0 // Si 0 AND 0 es 0, 1 AND 0 es 0 (Se compara cada bit con AND)\nconsole.log(convertirABinarioAND);\n// Operador Asignacion OR bit a bit (|=):\nlet convertirABinarioOR = 9; // --> 0b1001\nconvertirABinarioOR |= 3;  // --> 0b1001 | (OR) 0b0011 --> 1011 --> 11 // Si 0 OR 1 es 1, 1 OR 1 es 1 y 0 OR 0 es 0 (Se compara cada bit con OR)\nconsole.log(convertirABinarioOR);\n// Operador Asignacion XOR bit a bit (^=):\nlet convertirABinarioXOR = 11; // --> 0b1011\nconvertirABinarioXOR ^= 5; // --> 0b1011 ^ (XOR) 0b0101 --> 1110 --> 14 // Si son iguales es 0 y sin diferentes es 1 (Se compara cada bit con XOR)\nconsole.log(convertirABinarioXOR);\n// Operador Asignacion OR logico (||=):\nlet booleanoAAsignar = true;\nbooleanoAAsignar |= false; // true, Esta comparando con OR: true = true || false --> true\nconsole.log(booleanoAAsignar);\n// Operador Asignacion de anulacion logica (??=) // ESTE OPERADOR FUE INTRODUCIDO EN ECMAScript 11, si usas NodeJS tendrias que actualizar a la version MAS RECIENTE\n// El operador ?? verifica si el primero operando se undefined o null, si lo es retorna el otro operando. De lo contrario retorna el primer operando\nlet variableUndefined = undefined;\nvariableUndefined ??= 4; // -> 4 // Esta comparando si el primer operando es undefined o null si lo es reasignalo con el otro operando que es 4\nconsole.log(variableUndefined);\n\n// Operadores Aritmeticos:\n\n// Suma (+)\nlet operandoSuma1 = 20;\nlet operandoSuma2 = 10;\nresultadoDeLaSuma = operandoSuma1 + operandoSuma2;\nconsole.log(resultadoDeLaSuma);\n\n// Resta (-)\nlet operandoResta1 = 30;\nlet operandoResta2 = 20;\nresultadoDeLaResta = operandoResta1 - operandoResta2;\nconsole.log(resultadoDeLaResta);\n\n// Multiplicacion (*)\nlet operandoMultiplicacion1 = 20;\nlet operandoMultiplicacion2 = 3;\nresultadoDeLaMultiplicacion = operandoMultiplicacion1 * operandoMultiplicacion2;\nconsole.log(resultadoDeLaMultiplicacion);\n\n// Division (/)\nlet operandoDivision1 = 40;\nlet operandoDivision2 = 5;\nresultadoDeLaDivision = operandoDivision1 / operandoDivision2;\nconsole.log(resultadoDeLaDivision);\n\n// Residuo o Modulo (%):\nlet dividendo = 20;\nlet divisor = 4;\nlet residuo = dividendo % divisor;\nconsole.log(residuo);\n\n// Incremento (++):\nlet numeroAIncrementar = 20;\nnumeroAIncrementar++;\nconsole.log(numeroAIncrementar); // 21\n\n// Decremento (--):\nlet numeroADecrementar = 24;\nnumeroADecrementar--;\nconsole.log(numeroADecrementar); // 23\n\n// Negacion Unaria (-): // Niega su operando\nlet numeroANegar = 3;\nlet numeroNegado = -numeroANegar;\nconsole.log(numeroNegado); // -3\n\n// Positivo Unario (+): // Convierte el operando a Number, si el operando no se puede convertir a Number devolvera NaN\nlet stringANumero = \"20\";\nlet numeroPositivo = +stringANumero;\nconsole.log(numeroPositivo); // 20\n\n// Exponenciacion (**):\nlet numeroAExponenciar2 = 13;\nresultadoDeLaExponenciacion = 13 ** 3;\nconsole.log(resultadoDeLaExponenciacion); // 2197\n\n// Operadores de comparacion: \n\n// Igual (==): // Este operador convierte los operandos a un tipo comun antes de realizar la comparacion\nlet valorBooleano = \"3\" == 3;\nconsole.log(valorBooleano); // Por eso nos devuelve true, ya que convierte el String a Number\n\n// Estrictamente Igual (===): // Este operador no convierte los operandos los compara con sus respectivos tipos de datos (mas recomendable)\nlet valorEstrictoBooleano = null === undefined;\nconsole.log(valorEstrictoBooleano); // false\n\n// No es igual (No estricto): // Este operador convierte los operandos a un tipo comun antes de comparar si no son iguales\nlet valorNoEstrictoAlComparar = 4 != \"4\"; // false, ya que si son iguales, recuerden no es una comparacion estricta\nconsole.log(valorNoEstrictoAlComparar); // false\n\n// Desigualdad Estricta: // Este no convierte a los operandos para hayar desigualdad\nlet valorEstrictoAlComparar = undefined !== null;\nconsole.log(valorEstrictoAlComparar); // true\n\n// Mayor que (>):\nlet mayorQue = 20 > 3;\nconsole.log(mayorQue); // true\n\n// Mayor o igual que (>=)\nlet mayorOIgualQue = 20 >= 20;\nconsole.log(mayorOIgualQue); // true\n\n// Menor que (<):\nlet menorQue = 10 < 20;\nconsole.log(menorQue) // true\n\n// Menor o igual que (<=):\nlet menorOIgualQue = 20 <= 10;\nconsole.log(menorOIgualQue); // false\n\n// Operadores bit a bit:\n\n// AND a nivel de bits (&):\nresultadoAND = 10 & 15; // Convierte los operandos a binarios y compara cada bit con AND (1010 AND 1111 => 1010 -> 10)\nconsole.log(resultadoAND); // 10\n\n// OR a nivel de bits (|):\nresultadoOR = 20 | 100; // Convierte los operandos a binarios y compara cada bit con OR (0010100 OR 1100100 => 1110100 -> 116)\nconsole.log(resultadoOR); // 116\n\n// XOR a nivel de bits (^):\nresultadoXOR = 30 ^ 10; // Convierte los operandos a binarios y compara cada bit con XOR (11110 XOR 01010 => 10100 -> 20)\nconsole.log(resultadoXOR); // 20\n\n// NOT a nivel de bits (~):\nresultadoNOT = ~20; // Convierte el operando a binario y invierte sus bits\nconsole.log(resultadoNOT); // -21\n\n// Desplazamiento a la izquierda (<<):\nresultadoDesplazamientoALaIzquierda = 8 << 2; /* Convierte el primer operando a binario y desplaza cada bit n (segundo operando) \n                                                veces a la izquierda y donde estaban estos bits se reemplazan por 0 -->\n                                                00001000 << 2 --> 00100000 --> 32*/\nconsole.log(resultadoDesplazamientoALaIzquierda); // 32\n\n// Desplazamiento a la derecha de propagancion de signo (>>)\nresultadoDesplazamientoALaDerecha = 7 >> 3; /* Convierte el primer operando a binario y desplaza cada bit n (segundo operando) \n                                                veces a la derecha y donde estaban estos bits se reemplazan por 0 -->\n                                                00000111 >> 3 --> 00000000 --> 0*/\nconsole.log(resultadoDesplazamientoALaDerecha);\n\n// Desplazamiento a la derecha de relleno cero (>>>)\nresultadoDesplazamientoALaDerechaDeRellenoCero = 5 >>> 7; // 00000101 >>> 7 --> 00000000\nconsole.log(resultadoDesplazamientoALaDerechaDeRellenoCero);\n\n// OPERADORES LOGICOS \n\n// (&&): AND\n\nresultadoLogicoAND = \"Hola\" && true;\nconsole.log(resultadoLogicoAND); // true\n\n// (||): OR\n\nresultadoOR = false || true;\nconsole.log(resultadoOR); // true\n\n// (!): NOT\nresultadoNOT = !\"Hola, mundo!\";\nconsole.log(resultadoNOT) // false // Una string con caracteres se de valor booleano true y si usamos el operador NOT lo convierte a false\n\n// OPERADORES DE PERTENENCIA O RELACIONALES:\n\n// in : este operador devuelve true si la propiedad especificada esta en el objeto especificado.\narboles = ['redwood', 'bay', 'cedar', 'oak', 'maple'];\nestaRedWoodEnArboles = 2 in arboles; // En este caso se tiene que especificar el indice, no el valor del elemento.\nconsole.log(estaRedWoodEnArboles); // true\n\n\n// ESTRUCTURAS DE CONTROL\n\n// Condicionales\n// if, else if, else\nedad = 16\nif (edad >= 18) {\n    console.log(\"Eres mayor de edad!\");\n} else if (edad < 18 && edad > 15) {\n    console.log(\"Te falta poco para ser mayor de edad!\");\n} else {\n    console.log(\"Eres menor de edad!!\")\n}\n//switch\n\nlet nota = 4;\nconsole.log(\"He realizado un examen. Mi resultado es: \");\n\nswitch(nota) {\n    case 10:\n        calificacion = \"He aprobado con un sobresaliente!!\";\n        break;\n    case 9:\n    case 8:\n        calificacion = \"Un notable, que bien!!\";\n        break;\n    case 7:\n    case 6:\n        calificacion = \"Un bien, nada mal!\";\n        break;\n    case 4:\n    case 3:\n    case 2:\n    case 1:\n    case 0:\n        calificacion = \"Insuficiente!!\"\n        break;\n    default:\n        calificacion = \"Nota invalida!\"\n        break;\n}\n\nconsole.log(`He obtenido un ${calificacion}`);\n\n\n// Bucles\n// while (se ejecuta siempre que la condicion se a true)\nlet i = 0\nwhile (i <= 10) {\n    console.log(\"Valor de i: \" + i);\n    i++;\n}\n\n// do while (se ejecuta al menos una vez)\nlet numero = 1;\ndo {\n    console.log(\"Numero es: \" + numero);\n    numero++;\n} while (numero === 10); // Solo se ejecutara una vez, ya que la condicion no se cumple\n\nlet array = [3, 5, 20, 100];\n\n// for loop\nfor (let i = 0; i < array.length; i++) {\n    array[i] *= 2;\n}\n\nconsole.log(array)\n\n// Excepciones\n\ntry {\n    try {\n        throw new Error('my error');\n    } catch(err) {\n        console.error('inner try', err.message);\n        throw err;\n    } finally {\n        console.log('inner finally')\n    }\n} catch (err) {\n    console.error('outer try', err.message)\n}\n\n// EJERCICIO OPCIONAL\nfor (let i = 10; i <= 55; i++) {\n    if (i % 2 === 0 && i !== 16 && i % 3 != 0) {\n        console.log(i)\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/AndNikDev.js",
    "content": "\"use strict\";\n\nlet num1 = 10;\nlet num2 = 2;\nlet num3;\nlet num4 = 1;\n\n// Operadores aritméticos\nlet suma = num1 + num2; // 12\nlet resta = num1 - num2; // 8\nlet multiplicacion = num1 * num2; // 20\nlet division = num1 / num2; // 5\nlet modulo = num1 % num2; // 0\nlet incremento = num1++; // 11\nlet decremento = num1--; // 10\n\n// Operadores de asignación\nlet igual = (num3 = num2); // 2\nnum3 += num2; // 4\nnum3 -= num2; // 2\nnum3 *= num2; // 4\nnum3 /= num2; // 2\nnum3 %= num2; // 0\n\n// Operadores de comparación\nlet igualdad = num1 == num2; // false\nlet desigualdad = num1 != num2; // true\n// Son de comparación pero también son operadores de identidad\nlet igualdadEstricta = num1 === num2; // false\nlet desigualdadEstricta = num1 !== num2; // true\nlet mayorQue = num1 > num2; // true\nlet menorQue = num1 < num2; // false\nlet mayorIgualQue = num1 >= num2; // true\nlet menorIgualQue = num1 <= num2; // false\n\n// Operadores lógicos\nlet and = num1 > num2 && num1 < num2; // false\nlet or = num1 > num2 || num1 < num2; // true\nlet not = !num1; // false\n\n// Operadores de pertenencia\nlet inArray = num1 in [1, 2, 3]; // false\nlet instanceCheck = num1 instanceof Number;\n\n//! Estructuras de Control en JS\n// Condicionales\nif (num1 > num2) {\n  console.log(\"num1 es mayor que num2 \\n\");\n} else if (num1 < num2) {\n  console.log(\"num1 es menor que num2 \\n\");\n} else {\n  console.log(\"num1 es igual a num2 \\n\");\n}\n\nswitch (num1) {\n  case 1:\n    console.log(\"num1 es 10 \\n\");\n    break;\n  case 2:\n    console.log(\"num1 es 2 \\n\");\n    break;\n  default:\n    console.log(\"num1 no es 1 ni 2 \\n\");\n}\nconsole.log(\"+-----+\");\n// Iterativas\nfor (let i = 0; i < 10; i++) {\n  console.log(i);\n}\n\nconsole.log(\"+-----+\");\nconst map = { a: 1, b: 2, c: 3 };\nfor (let key in map) {\n  console.log(key);\n}\n\nconsole.log(\"+-----+\");\nconst arr = [1, 2, 3, 4, 5];\nfor (let element of arr) {\n  console.log(element);\n}\n\n// Excepciones\ntry {\n  throw \"Error\";\n} catch (error) {\n  console.log(\"Error: \" + error);\n} finally {\n  console.log(\"Bloque final ejecutado\");\n}\n\n// Funciones\nfunction sumar(a, b) {\n  return a + b;\n}\n\nconst restar = (a, b) => a - b;\n\n// Operador ternario\n\nconst mayor = num1 > num2 ? console.log(num1) : console.log(num2);\n\nconst ejemploAdicional = () => {\n  for (let i = 0; i <= 55; i++) {\n    if (i % 2 === 0 && i % 3 !== 0 && i !== 16) {\n      console.log(i);\n    }\n  }\n};\n\nejemploAdicional();\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/AndresMCardenas.js",
    "content": "// Operadores y Estructuras de Control\n\n//Operadores aritméticos\n\n//Suma\nlet suma = 5 + 5;// se asigna el valor de la suma a la variable suma\nconsole.log(suma); // se imprime el valor de la variable suma\n\n//Resta\nlet resta = 10 - 5;// se asigna el valor de la resta a la variable resta\nconsole.log(resta); // se imprime el valor de la variable resta\n\n//Multiplicación\nlet multiplicacion = 5 * 5;// se asigna el valor de la multiplicacion a la variable multiplicacion\nconsole.log(multiplicacion); // se imprime el valor de la variable multiplicacion\n\n//División\nlet division = 10 / 5;\nconsole.log(division);\n\n//Módulo\nlet modulo = 10 % 5;\nconsole.log(modulo);\n\n//Incremento\nlet incremento = 10;\nincremento++;// incremento se le suma 1\nconsole.log(incremento);\n\n//Decremento\nlet decremento = 10;\ndecremento--;// decremento se le resta 1\nconsole.log(decremento);\n\n//Operadores de asignación\n\n//Asignación\nlet asignacion = 10;\nconsole.log(asignacion);\n\n//Suma y asignación\nlet sumaAsignacion = 10;\nsumaAsignacion += 5;//sumaAsignacion = sumaAsignacion + 5\nconsole.log(sumaAsignacion); // se imprime el valor de la variable sumaAsignacion\n\n//Resta y asignación\nlet restaAsignacion = 10;\nrestaAsignacion -= 5;//restaAsignacion = restaAsignacion - 5\nconsole.log(restaAsignacion); // se imprime el valor de la variable restaAsignacion\n\n//Multiplicación y asignación\nlet multiplicacionAsignacion = 10;\nmultiplicacionAsignacion *= 5;//multiplicacionAsignacion = multiplicacionAsignacion * 5\nconsole.log(multiplicacionAsignacion); // se imprime el valor de la variable multiplicacionAsignacion\n\n//División y asignación\nlet divisionAsignacion = 10;\ndivisionAsignacion /= 5;//divisionAsignacion = divisionAsignacion / 5\nconsole.log(divisionAsignacion); // se imprime el valor de la variable divisionAsignacion\n\n// Módulo y asignación\nlet moduloAsignacion = 10;\nmoduloAsignacion %= 5;//moduloAsignacion = moduloAsignacion % 5\nconsole.log(moduloAsignacion); // se imprime el valor de la variable moduloAsignacion\n\n//Operadores de comparación\n\n//Igualdad\nlet igualdad = 10 == 10;\nconsole.log(igualdad);// se imprime true el valor de la variable igualdad\n\n//Igualdad estricta\nlet igualdadEstricta = 10 === 10;\nconsole.log(igualdadEstricta);// se imprime true el valor de la variable igualdadEstricta\n\nlet igualdadEstricta2 = 10 === '10';\nconsole.log(igualdadEstricta2);// se imprime false el valor de la variable igualdadEstricta2\n\n//Desigualdad\nlet desigualdad = 10 != 10;\nconsole.log(desigualdad);// se imprime false el valor de la variable desigualdad\n\n//Desigualdad estricta  \nlet desigualdadEstricta = 10 !== 10;\nconsole.log(desigualdadEstricta);// se imprime false el valor de la variable desigualdadEstricta\n\nlet desigualdadEstricta2 = 10 !== '10';\nconsole.log(desigualdadEstricta2);// se imprime true el valor de la variable desigualdadEstricta2\n\n//Mayor que \nlet mayorQue = 10 > 5;  \nconsole.log(mayorQue);// se imprime true el valor de la variable mayorQue\n\n//Menor que\nlet menorQue = 10 < 5;\nconsole.log(menorQue);// se imprime false el valor de la variable menorQue\n\n//Mayor o igual que \nlet mayorOIgualQue = 10 >= 10;\nconsole.log(mayorOIgualQue);// se imprime true el valor de la variable mayorOIgualQue\n\n//Menor o igual que\nlet menorOIgualQue = 10 <= 5;\nconsole.log(menorOIgualQue);// se imprime false el valor de la variable menorOIgualQue\n\n//Operadores lógicos\n\n//AND\nlet and = (10 > 5) && (10 < 20);\nconsole.log(and);// se imprime true el valor de la variable and\n\n//OR\nlet or = (10 > 5) || (10 > 20);\nconsole.log(or);// se imprime true el valor de la variable or\n\n//NOT\nlet not = !(10 > 5);\nconsole.log(not);// se imprime false el valor de la variable not\n\n//Operadores de concatenación\n\n//Concatenación\nlet concatenacion = 'Hola ' + 'Mundo';\nconsole.log(concatenacion);// se imprime Hola Mundo el valor de la variable concatenacion\n\n//Concatenación y asignación\nlet concatenacion2 = 'Hola '; \nconcatenacion2 += 'Mundo';//concatenacion2 = concatenacion2 + 'Mundo'\nconsole.log(concatenacion2);// se imprime Hola Mundo el valor de la variable concatenacion2\n\n//Operadores ternarios\n// Ejemplo 1: Asignar un valor a una variable basado en una condición\nlet edad = 15;\nlet tipo = edad >= 18 ? 'Adulto' : 'Menor';\nconsole.log(tipo); // Se imprime 'Menor'\n\n// Ejemplo 2: Elegir qué función ejecutar basado en una condición\nlet saludable = true;\nsaludable ? console.log('Puedes salir a correr') : console.log('Deberías descansar');\n\n// Ejemplo 3: Elegir qué valor retornar en una función\nfunction obtenerPrecio(tieneDescuento) {\n  return tieneDescuento ? 9.99 : 19.99;\n}\nconsole.log(obtenerPrecio(true)); // Se imprime 9.99\n\n// Operadores de flujo\n\n//If\nlet edad2 = 15;\nif (edad2 >= 18) {\n  console.log('Eres mayor de edad');\n}\n\n//If...else\nlet edad3 = 15;\nif (edad3 >= 18) {\n  console.log('Eres mayor de edad');\n} else {\n  console.log('Eres menor de edad');\n}\n\n//If...else if...else\nlet edad4 = 15;\nif (edad4 >= 18) {\n  console.log('Eres mayor de edad');\n} else if (edad4 >= 13) {\n  console.log('Eres un adolescente');\n} else {\n  console.log('Eres un niño');\n}\n\n//Switch\nlet dia = 3;\nswitch (dia) {\n  case 1:\n    console.log('Lunes');\n    break;\n  case 2:\n    console.log('Martes');\n    break;\n  case 3:\n    console.log('Miércoles');\n    break;\n  case 4:\n    console.log('Jueves');\n    break;\n  case 5:\n    console.log('Viernes');\n    break;\n  case 6:\n    console.log('Sábado');\n    break;\n  case 7:\n    console.log('Domingo');\n    break;\n  default:\n    console.log('Día inválido');\n}// se imprime Miércoles el valor de la variable dia\n\n//For se ejecuta un número determinado de veces\nfor (let i = 0; i < 5; i++) {\n  console.log(i);\n}// se imprime 0 1 2 3 4\n\n//While se ejecuta prieramente si la condición es verdadera, y se detiene cuando la condición es falsa\nlet i = 0;\nwhile (i < 5) {\n  console.log(i);\n  i++;\n}// se imprime 0 1 2 3 4\n\n//Do...while se ejecuta al menos una vez, y luego se ejecuta mientras la condición sea verdadera\nlet i2 = 0;\ndo {\n  console.log(i2);\n  i2++;\n} while (i2 < 5);// se imprime 0 1 2 3 4\n\n/*\n DIFICULTAD EXTRA(opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n  * entre 10 y 55(incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n*/\n\nconsole.log('DIFICULTAD EXTRA(opcional):');\n\nfor (let i = 10; i <= 55; i++) {//extra inicia en 10 y se ejecuta mientras extra sea menor que 56\n  if (i % 2 === 0 && i !== 16 && i % 3 !== 0) { //si el numero es par y no es 16 y no es multiplo de 3\n    console.log(i); //imprime el numero en extra\n  }\n}\n\nconsole.log('Ejericio con While');\n\nlet extra = 10; //extra inicia en 10\nwhile (extra <= 55) { //se ejecuta mientras extra sea menor que 56\n  if (extra % 2 === 0 && extra !== 16 && extra % 3 !== 0) { //si el numero es par y no es 16 y no es multiplo de 3\n    console.log(extra); //imprime el numero en extra\n  }\n  extra++; //extra se incrementa en 1\n}\n\nconsole.log('FIN');\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/Andresargote.js",
    "content": "let n1 = 1;\nlet n2 = 10;\n\n// Operadores de comparación\n\n// Las comparaciones entre valores retornan un booleano como resultado\nconsole.log(n1 > n2); // Mayor que\nconsole.log(n1 < n2); // Menor que\nconsole.log(n1 >= n2); // Mayor o igual que\nconsole.log(n1 <= n2); // Menor o igual que\nconsole.log(n1 == n2); // Igual\nconsole.log(n1 != n2); // No es igual\n\n// Operadores aritméticos\nconsole.log(n1 + n2); // Suma\nconsole.log(n1 - n2); // Resta\nconsole.log(n1 * n2); // Multiplicación\nconsole.log(n1 / n2); // División\nconsole.log(n1 % n2); // Residuo de una división\nconsole.log(n1 ** n2); // Potenciación\nconsole.log(n1++); // Incremento\nconsole.log(n1--); // Decremento\n\n// Operadores a nivel de bits\nconsole.log(n1 & n2); // AND\nconsole.log(n1 | n2); // OR\nconsole.log(n1 ^ n2); // XOR\nconsole.log(~n1); // NOT\nconsole.log(n1 << n2); // Desplazamiento a la izquierda\nconsole.log(n1 >> n2); // Desplazamiento a la derecha\nconsole.log(n1 >>> n2); // Desplazamiento a la derecha sin signo\n\n// Operadores lógicos\nconst result1 = n1 > n2 && n2 > 0; // AND\nconsole.log(result1); // Salida: false\nconst result2 = n1 < n2 || n2 > 0; // OR\nconsole.log(result2); // Salida: true\nconst result3 = !(n1 < n2); // NOT\nconsole.log(result3); // Salida: true\nconst result4 = n1 ?? n2; // Nullish coalescing\nconsole.log(result4); // Salida: 1\n\n// Operadorer de cadena\nconst string1 = 'Hola';\nconst string2 = 'Mundo';\nconsole.log(string1 + ' ' + string2); // Concatenación de cadenas\n\nlet message = 'Hola';\nmessage += ' Mundo'; // Concatenación de cadenas\nconsole.log(message); // Salida: Hola Mundo\n\nlet text = 'JavaScript';\nconsole.log(text[0]); // Salida: J\nconsole.log(text[1]); // Salida: a\n\n// Spread operator o operador de propagación\n// Permite expandir elementos de un iterable como arrays, strings objetos, etc.\n\n// expandir un array\nlet arr = [1, 2, 3];\nlet arr2 = [...arr, 4, 5, 6];\n\n// copiar un array de forma superficial\nlet arr3 = [...arr];\n\n// copiar un objeto de forma superficial\nlet obj = { a: 1, b: 2, c: 3 };\nlet obj2 = { ...obj };\n\n// de forma superficial significa que solo se copia la referencia de los elementos esto es, si los elementos son objetos o arrays, estos no se copian, sino que se hace una referencia al objeto original.\n\n// Operador ternario\nlet age = 18;\nlet message2 = age >= 18 ? 'Eres mayor de edad' : 'Eres menor de edad';\nconsole.log(message2); // Salida: Eres mayor de edad\n\n// Operador de asignación\nlet a = 1;\nlet b = 2;\nlet c = 3;\n\n// Estructuras de control\n\n// Condicionales\n\n// if\n// Nos permite ejecutar un bloque de código si una condición es verdadera\nif (age >= 18) {\n  console.log('Eres mayor de edad');\n} else {\n  // este bloque se va a ejectuar si la condición previa es falsa\n  console.log('Eres menor de edad');\n}\n\n// else if\n// Nos permite evaluar una nueva condición si la condición anterior es falsa\nif (age >= 18) {\n  console.log('Eres mayor de edad');\n} else if (age >= 15) {\n  console.log('Eres adolescente');\n} else {\n  console.log('Eres un niño');\n}\n\n// switch\n// Nos permite evaluar una expresión multiples veces (es decir, con diferentes condiciones) y ejecutar un bloque de código dependiendo del valor de la expresión\nlet day = 3;\nswitch (day) {\n  case 1:\n    console.log('Lunes');\n    break;\n  case 2:\n    console.log('Martes');\n    break;\n  case 3:\n    console.log('Miércoles');\n    break;\n  case 4:\n    console.log('Jueves');\n    break;\n  case 5:\n    console.log('Viernes');\n    break;\n  default:\n    console.log('Fin de semana');\n}\n\n// Iterativas\n// Bucles:\n// Nos permiten ejecutar un bloque de código múltiples veces mientras la condición de la expresión sea verdadera\n\n// for: ideal para cuando sabemos cuántas veces queremos que se ejecute el bucle\n// for (inicialización; condición; incremento)\nfor (let i = 0; i < 5; i++) {\n  console.log(i); // Salida: 0, 1, 2, 3, 4\n}\n\n// while: ideal para cuando no sabemos cuántas veces queremos que se ejecute el bucle y queremos que se ejecute mientras una condición sea verdadera\nlet winner = false;\nlet counter = 0;\nconst randomNumberBetween0And10 = Math.floor(Math.random() * 11);\n\nwhile (!winner) {\n  counter++;\n\n  if (counter === randomNumberBetween0And10) {\n    winner = true;\n  }\n}\n\n// do while: similar al bucle while, pero la diferencia es que el bloque de código se ejecuta al menos una vez antes de evaluar la condición\nlet num = 1;\n\ndo {\n  if (num % 2 === 0) {\n    console.log(`${num} es par.`);\n  }\n  num++;\n} while (num <= 10);\n\n// for in: se usa para iterar sobre las propiedades de un objeto\nconst person = {\n  name: 'John',\n  age: 30,\n};\n\nfor (let key in person) {\n  console.log(key, person[key]); // Salida: name John, age 30\n}\n\n// for of: se usa para iterar sobre los elementos de arrays, strings, maps, sets, etc.\nlet numbers = [1, 2, 3, 4, 5];\n\nfor (let number of numbers) {\n  console.log(number); // Salida: 1, 2, 3, 4, 5\n}\n\n// Control de excepciones\n\ntry {\n  // Bloque de código a probar\n  let x = y + 10; // y no está definido por lo que se lanzará un error\n} catch (error) {\n  // Bloque de código a ejecutar si hay un error\n  console.log(error); // Salida: ReferenceError: y is not defined\n} finally {\n  // Bloque de código a ejecutar siempre\n  console.log('Este bloque siempre se ejecutará');\n}\n\n// break y continue\n// break: se usa para salir de un bucle\n// continue: se usa para saltar la iteración actual de un bucle y continuar con la siguiente iteración\nfor (let i = 0; i < 10; i++) {\n  if (i === 5) {\n    break; // Salir del bucle cuando i es 5\n  }\n  console.log(i);\n}\n\nfor (let i = 0; i < 5; i++) {\n  if (i === 3) {\n    continue; // Saltar la iteración cuando i es 3\n  }\n  console.log(i);\n}\n\n// return\n// Nos permite devolver un valor de una función y finalizar su ejecución\n\n/*\nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3 */\n\nfor (let i = 10; i <= 55; i++) {\n  if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n    console.log(i);\n  }\n}\n\n// podriamos hacerlo con un while\nlet i = 10;\nlet limit = 55;\n\nwhile (i <= limit) {\n  if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n    console.log(i);\n  }\n  i++;\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/AndrewCodev.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n//Operadores aritmeticos\nlet a = 10;\nlet b = 3;\n\nconsole.log(a + b); // 13  (suma)\nconsole.log(a - b); // 7   (resta)\nconsole.log(a * b); // 30  (multiplicación)\nconsole.log(a / b); // 3.333... (división)\nconsole.log(a % b); // 1   (módulo o residuo)\nconsole.log(a ** b); // 1000 (exponente: 10^3)\n\n// Operadores de asignación\nlet x = 5;\nx += 2; // x = x + 2\nx -= 1; // x = x - 1\nx *= 3; // x = x * 3\nx /= 2;\nx %= 3;\nx **= 2;\n\n//Operadores de comparación\nconsole.log(5 == \"5\"); // true (igualdad débil)\nconsole.log(5 === \"5\"); // false (igualdad estricta)\nconsole.log(5 != \"5\"); // false\nconsole.log(5 !== \"5\"); // true\nconsole.log(3 < 5); // true\nconsole.log(3 <= 3); // true\nconsole.log(6 > 4); // true\nconsole.log(6 >= 7); // false\n\n//Operadores lógicos\nlet p = true;\nlet q = false;\n\nconsole.log(p && q); // false (AND)\nconsole.log(p || q); // true (OR)\nconsole.log(!p); // false (NOT)\n\n//Operadores de identidad\nlet obj1 = { nombre: \"Ana\" };\nlet obj2 = { nombre: \"Ana\" };\nlet obj3 = obj1;\n\nconsole.log(obj1 === obj2); // false (contenido igual, pero diferentes referencias)\nconsole.log(obj1 === obj3); // true  (misma referencia en memoria)\n\n//Operadores de pertenencia\nlet persona = { nombre: \"Luis\", edad: 30 };\n\nconsole.log(\"nombre\" in persona); // true\nconsole.log(persona.hasOwnProperty(\"edad\")); // true\n\n//Operadores Bits\nlet m = 5; // 0101\nlet n = 3; // 0011\n\nconsole.log(m & n); // 1 (AND)\nconsole.log(m | n); // 7 (OR)\nconsole.log(m ^ n); // 6 (XOR)\nconsole.log(~m); // -6 (NOT)\nconsole.log(m << 1); // 10 (desplazamiento a la izquierda)\nconsole.log(m >> 1); // 2  (desplazamiento a la derecha)\n\n//Estructuras de control\n\n//Condicionales\n//if - else if -else\nlet edad = 20;\n\nif (edad < 18) {\n  console.log(\"Menor de edad\");\n} else if (edad < 65) {\n  console.log(\"Adulto\");\n} else {\n  console.log(\"Adulto mayor\");\n}\n\n//switch\nlet dia = \"lunes\";\n\nswitch (dia) {\n  case \"lunes\":\n    console.log(\"Inicio de semana\");\n    break;\n  case \"viernes\":\n    console.log(\"¡Por fin viernes!\");\n    break;\n  default:\n    console.log(\"Día normal\");\n}\n\n//Bucles\n//for\nfor (let i = 0; i < 5; i++) {\n  console.log(\"Iteración:\", i);\n}\n\n//while\nlet i = 0;\nwhile (i < 3) {\n  console.log(\"i:\", i);\n  i++;\n}\n\n//do while\nlet j = 0;\ndo {\n  console.log(\"j:\", j);\n  j++;\n} while (j < 2);\n\n//Bucles para arrays\n//for of\nconst FRUTAS = [\"manzana\", \"pera\", \"uva\"];\nfor (const fruta of FRUTAS) {\n  console.log(fruta);\n}\n\n//for in\nconst PERSONA = { nombre: \"Ana\", edad: 25 };\nfor (const clave in PERSONA) {\n  console.log(clave, \":\", PERSONA[clave]);\n}\n\n//Operador ternario\nlet miEdad = 17;\nlet mensaje = miEdad >= 18 ? \"Adulto\" : \"Menor\";\nconsole.log(mensaje);\n\n//Manejo de excepciones\n//try catch\ntry {\n  let resultado = 10 / 0;\n  console.log(\"Resultado:\", resultado);\n} catch (error) {\n  console.log(\"Ocurrió un error:\", error.message);\n}\n\n//try catch finally\ntry {\n  // código que puede fallar\n} catch (e) {\n  console.log(\"Error capturado\");\n} finally {\n  console.log(\"Esto se ejecuta siempre\");\n}\n\n//Dificultad extra Ejercicio\nconst miFuncion = () => {\n  for (let i = 10; i <= 55; i++) {\n    const esPar = i % 2 === 0;\n    const noEs16 = i !== 16;\n    const noEsMultiploDe3 = i % 3 !== 0;\n\n    if (esPar && noEs16 && noEsMultiploDe3) {\n      console.log(i);\n    }\n  }\n};\n\nmiFuncion();\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/Angel-Delg.js",
    "content": "// Operador de asignación \" = \" para asignar cada fruta\nconst Pineapple = '🍍'\nconst Apple = '🍎'\nconst Grapes = '🍇'\n\n// podemos usar \" + \" para concatenar strings\nconst Apples = Apple + '🍎'\nconst Pineapples = Pineapple + '🍍'\n\nconsole.log(Apples) // output: '🍎🍎'\nconsole.log(Pineapples) // output: '🍍🍍'\nconsole.log(Grapes) // output: '🍇'\n\n// Podemos realizar operaciones matemáticas usando + , -, / and  *\n\nconst amountApples = 2\nlet amountPeoples = 1\n\n// Podemos usar \" - \" para restar elementos de tipos numbers\nconsole.log(amountApples - amountPeoples);  // output: 1\n\n// Tambien podemos multiplicar el numero de manzanas por el numero de personas\nconsole.log(amountApples * amountPeoples); // output: 2\n\n// Y dividir el numero de manzanas por la cantidad de personas que hay.\nconsole.log(amountApples / amountPeoples); // output: 2\n\n// podemos usar operador de modulo para saber el reciduo de una divisió \" % \"\nlet ram = Math.ceil(Math.random() * 10);\n(ram % 2 === 0) ? console.log(\"Par\") : console.log(\"Impar\");\n\n/* \n   ====================================================================\n      Operadores logicos : and, or, not\n   ====================================================================\n*/\n\nlet and = true && false // output: false\nlet or = false || true // output: true\nlet negacion = !false // output: true\n!!negacion // true\n!![]; // true\n![]; // false\n// Tambien podemos realizar condiciónes rapidas\n\nconst response = '🍉'\nresponse === '🍏' && true // output: false \nresponse === '🍉' || false // output: false\n\n/* \n   ====================================================================\n      podemos realizar estructuras de control selectiva o condicional.\n   ====================================================================\n*/\n\nconst seasons = {\n   Summer: '🍉',\n   Spring: '🍓',\n   Winter: '🥝',\n   Autumn: '🍑'\n}\n\n// podemos realizar una operación selectiva para saber que comer dependiendo de la estación del año\nconst currentSeason = \"Summer\"\n\nif(seasons[currentSeason]){\n   console.log(`Hora de comer ${seasons[currentSeason]}`);\n}\n\n/* \n   ====================================================================\n      Tambien puede existir un caso else\n   ====================================================================\n*/\n\nconst FruitBox = {\n   Pineapple: 10,\n   Apples: 5,\n   Tangerine: 14,\n   Kiwi: 20\n}\n\n// podemos verificar si hay frutas para todos en la playa\n\nconst Peoples = 9\n\nif(FruitBox[\"Pineapple\"] >= Peoples){\n   console.log(\"Hay piñas para todos\");\n}\nelse {\n   console.log(\"Ohh no alguien no alcanzo a comer piña\")\n}\n\n/* \n   ====================================================================\n      Tambien podemos realizar multiples casos usando switch, case\n   ====================================================================\n*/\n\nconst day = new Date().getDay();\n\nswitch(day){\n   case 0:{\n      console.log(\"Sunday\")\n      break;\n   }\n   case 1:{\n      console.log(\"Monday\");\n      break;\n   }\n   case 2:{\n      console.log(\"Tuesday\");\n      break;\n   }\n   case 3:{\n      console.log(\"Wednesday\");\n      break\n   }\n   case 4:{\n      console.log(\"Thursday\")\n      break\n   }\n   case 5:{\n      console.log(\"Friday\");\n      break\n   }\n   case 6:{\n      console.log(\"Saturday\");\n      break;\n   }\n   default:{\n      console.log(\"This day is incorrect!\");\n   }\n}\n// como puedes observar tiene varios caso en dependencia del dia de la semana que te encuentres\n\n/* \n   ====================================================================\n      Estructura de control repetitiva o ciclica: for, do while, while, for of, for in\n   ====================================================================\n*/\n\n// la estructura del for(variable inicializada; condición ; proceso de incremento)\nfor(let i = 0; i < Math.ceil(Math.random() * 40); i++){\n   console.log(i);\n}\n/*\n   Math.ceil(Math.random() * 40) => numero aleatorio 0 - 40\n   por lo que puede terminar en cualquier número que se encuentre en ese rango\n*/\n\nlet counter = 0;\n\ndo{\n   // realizar proceso\n   console.log(counter);\n   counter++;\n}while(counter != 10);\n\n\n// tambien podemos usar while\ncounter = 0\n\n// en este caso primero evalua la condición para ver si entra en el ciclo, por lo tanto en un \n// do while primero realiza un proceso y luego evalua la condición\nwhile(counter != 10){\n   console.log(counter)\n   counter++;\n}\n\n/*\n   Algunas abreviaciones.\n\n   \"counter++\" = \"counter += 1\" = \"counter = counter + 1\"\n   \"counter--\" = \"counter -= 1\" = \"counter = counter - 1\"\n\n   \"counter *= 2\" = \"counter = counter * 2\"\n   \"counter /= 2\" = \"counter = counter / 2\"\n*/\n\n/* DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n */\n\nfor(let i = 10; i <= 55; i+=1){\n   if(i % 2 === 0 && i !== 16 && i % 3 !== 0){\n      console.log(i);\n   }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/AngelVelasco1.js",
    "content": "//! Variables usadas */\nconst apples = true\nconst bananas = false;\n// ---\nconst number = 10;\nconst number2 = \"10\";\nconst number3 = \"10\";\nlet owner = \"Juan\"\nlet employee = \"David\"\n\n//? 1. Tipos de operadores\n\n/* Aritmeticos */\nconst sum = 5 + 5;\nconst susb = 10 - 4;\nconst mult = 25 * 1;\nconst div = 5 / 2;\nconst exp = 5 ** 2;\n\n/* Logicos */\nif (apples && bananas) { // And\n    console.log(\"We have bananas and apples\");\n} else if (apples || bananas) { // Or\n    console.log('We only have one of the two fruits');\n\n} else if (!apples) { // Not\n    console.log('We only have bananas');\n\n}\n\n/* Comparacion */\nconst comp = number != number2 // Diferente a (No estricto)\nconst comp2 = number !== number3 // Diferente a (Estricto)\nconst comp3 = number == number2 // Igual a (No estricto)\nconst comp4 = number === number3 // Igual a (Estricto)\nconst greaterThan = number > number2 // Mayor a\nconst lowerThan = number < number2 // Menor a\nconst lowerOrEqualThan = number <= number2 // Menor o igual a\n\n/* Asignacion */\nowner = employee // Owner is assinged employee value\nconsole.log(owner); // David\nconsole.log(employee);\n\n//? 2. Estructuras de control\nconst numbers = [1, 4, 5, 2, 24, 10, 12]\n\n/* for */\nfor (let i = 0; i < numbers.length; i++) {\n    const number = numbers[i];\n\n    if (number % 2 === 0) {\n        console.log(number);\n        continue;\n    } else {\n        continue;\n    }\n}\n/* switch */\nconst month = 10;\nswitch (true) {\n    case (month > 0 && month <= 4):\n        console.log('Its Spring');\n        break;\n    case (month > 4 && month <= 6):\n        console.log('Its Summer');\n        break;\n    case (month > 6 && month <= 10):\n        console.log('Its Autum');\n        break;\n    case (month > 10 && month <= 12):\n        console.log('Its Winter');\n        break;\n    default:\n        console.log(\"Its not a month\")\n}\n/* if */\nconst age = 18\nconst password = \"1524\"\nif (age >= 18 && password === \"1524\") {\n    console.log('You can pass');\n} else {\n    console.log('You cant pass');\n}\n\n/* While */\nlet result = 1;\nlet counter = 0;\nwhile (counter < 10) {\n    result = result * 2\n    counter += 1\n}\nconsole.log(result);\n\n/* Do while */\nlet letter;\ndo {\n     letter = prompt(\"Enter the letter A\")\n} while(letter != 'A') {\n    alert('Congratulations');\n}\n\nlet evenOrOdd;\ndo {    \n    evenOrOdd = Number(prompt(\"Insert a number\"))\n    if(evenOrOdd < 0 || evenOrOdd > 100) {\n        alert('The number must be between 0 and 100')\n        \n    }\n\n} while (evenOrOdd < 0 || evenOrOdd > 100 || (evenOrOdd % 2 === 0));\nif (evenOrOdd % 2 !== 0) {\n    alert(\"It's an odd number\");\n}\n\n//? Ejercicio Extra\nconst limit = 10\nconst limit2 = 55;\nconst isMultOf3 = (number) => {\n    let sum = 0;\n    const numberString = number.toString();\n    for (let digit in numberString) {\n        sum += parseInt(numberString[digit])\n    }\n    if(sum % 3 === 0) {\n        return true\n    } else {\n        return false\n    }\n}\n\nfor(let i = limit; i <= limit2; i++) {\n    if(i % 2 === 0 && (isMultOf3(i) && i !== 16)) {\n        console.log(i);\n    } else {\n        continue;\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/ArliumDev.js",
    "content": "// Operadores aritméticos\n\nlet suma = 1 + 1;\nlet resta = 2 - 1;\nlet division = 6 / 2;\nlet multiplicacion = 5 * 9;\nlet resto = 15 % 3;\n\n\n// Operadores de asignación\n\nlet z = 1;\nz += 5; // Adición\nz -= 1; // Sustracción\nz *= 5; // Multiplicación\nz /= 2; // División\nz %= 2; // Resto\n\n\n// Incremento y decremento\n\nlet sumRes = 2;\nsumRes++;\nsumRes--;\n\n\n// Operadores de comparación\n\nlet num1 = 6;\nlet num2 = 8;\nlet comp1 = num1 > num2;\nlet comp2 = num1 < num2;\nlet comp3 = num1 >= num2;\nlet comp4 = num1 <= num2;\nlet comp5 = num1 === num2;\nlet comp6 = num1 !== num2;\n\n\n// Operadores lógicos\n\nlet and = true && true;\nlet or = true || false;\n\n\n// Operadores de negación\n\nlet truthy = true;\nlet falsy = false;\nconsole.log(!truthy);\nconsole.log(!falsy);\nconsole.log(!!truthy);\n\n\n// Operadores de igualdad o identidad\n\nlet same1 = 5 === 5;\nlet same2 = 5 === \"5\";\nlet same3 = 5 !== 5;\n\n\n// typeof\n\nlet typeNumber = 7;\nlet typeString = \"I'm a string\";\nlet typeBoolean = true;\nlet typeUndef = undefined;\nlet typeNull = null;\nconsole.log(typeof typeNumber);\nconsole.log(typeof typeString);\nconsole.log(typeof typeBoolean);\nconsole.log(typeof typeUndef);\nconsole.log(typeof typeNull);\n\n\n// Operador de concatenación\n\nlet start = \"Hola, \";\nlet end = \"Javascript\";\nconsole.log(start + end);\n\n\n/* Estructuras de control */\n\n// if...else\n\nlet language = \"Javascript\";\nif (language !== \"Javascript\") {\n  console.log(\"Te equivocas de carpeta, amigo\");\n} else {\n  console.log(\"Estás en la carpeta correcta\");\n}\n\n\n// Switch\n\nlet monthNum = 7;\nswitch (monthNum) {\n  case 1:\n    console.log(\"January\");\n    break;\n  case 2:\n    console.log(\"February\");\n    break;\n  case 3:\n    console.log(\"March\");\n    break;\n  case 4:\n    console.log(\"April\");\n    break;\n  case 5:\n    console.log(\"May\");\n    break;\n  case 6:\n    console.log(\"June\");\n    break;\n  case 7:\n    console.log(\"July\");\n    break;\n  case 8:\n    console.log(\"August\");\n    break;\n  case 9:\n    console.log(\"September\");\n    break;\n  case 10:\n    console.log(\"October\");\n    break;\n  case 11:\n    console.log(\"November\");\n    break;\n  case 12:\n    console.log(\"December\");\n    break;\n  default:\n    console.log(\"The number doesn't match any month\");\n}\n\n\n// For \n\nfor (let i = 0; i < 3; i++) {\n    console.log(i);\n}\n\n\n// While \n\nlet counter = 10;\nwhile (counter > 0) {\n    console.log(counter);\n    counter--;\n}\n\n\n// Do While\nlet countUp = 0;\ndo {\n    console.log(countUp);\n    countUp++;\n} while (countUp <= 5);\n\n\n// forEach\n\nlet numbers  = [1,2,3,4,5,6,7,8];\nnumbers.forEach((number) => {\n    number++;\n    console.log(number);\n});"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/ArticKun.js",
    "content": "\n\n// Operadores Aritmeticos -----\n\nlet num1 = 35;\nlet num2 = 35;\n\nconsole.log( `Suma:     ${num1} + ${num2} = ${ num1 + num2 }` );\nconsole.log( `Resta:    ${num1} - ${num2} = ${ num1 - num2 }` );\nconsole.log( `Multi:    ${num1} * ${num2} = ${ num1 * num2 }` );\nconsole.log( `Division: ${num1} / ${num2} = ${ num1 / num2 }` );\nconsole.log( `Modulo:   ${num1} % ${num2} = ${ num1 % num2 }` );\nconsole.log( `Expo:     ${num1} ^ ${num2} = ${ num1 ** num2 }` );\n\n// Operadores Comparación -----\n\nlet numb1 = 27;\nlet numb2 = 35;\n\nconsole.log(`Igualdad:             ${numb1} == ${numb2} = ${numb1 == numb2}`);\nconsole.log(`Igualdad Estricta:    ${numb1} === ${numb2} = ${numb1 === numb2}`);\nconsole.log(`Desigualdad:          ${numb1} != ${numb2} = ${numb1 != numb2}`);\nconsole.log(`Desigualdad Estricta: ${numb1} !== ${numb2} = ${numb1 !== numb2}`);\nconsole.log(`Mayor que:            ${numb1} > ${numb2} = ${numb1 > numb2}`);\nconsole.log(`Mayor Igual que:      ${numb1} >= ${numb2} = ${numb1 >= numb2}`);\nconsole.log(`Menor que:            ${numb1} < ${numb2} = ${numb1 < numb2}`);\nconsole.log(`Menor Igual que:      ${numb1} <= ${numb2} = ${numb1 <= numb2}`);\n\n\n// Operadores Lógicos -----\n\n// AND (&&)\nlet x = 5;\nlet y = 10;\n\nif (x > 0 && y > 0) {\n    console.log(\"Ambas condiciones son verdaderas\");\n} else {\n    console.log(\"Al menos una condición es falsa\");\n};\n\n//ORD (||)\nlet edad = 25;\nlet tieneLicencia = false;\n\nif (edad >= 18 || tieneLicencia) {\n    console.log(\"Puede conducir\");\n} else {\n    console.log(\"No puede conducir\");\n};\n\n//NOT (!)\nlet llueve = true;\n\nif (!llueve) {\n    console.log(\"No está lloviendo\");\n} else {\n    console.log(\"Está lloviendo\");\n};\n\n\n//Operadores de asignacion -----\n\n//Simple\nlet a = 10;\nconsole.log(a);  // 10\n//Con Adicion\nlet b = 5;\nb += 3;          // Esto es equivalente b = b + 3;\nconsole.log(b);  // 8\n// Con Sustraccion\nlet c = 8;\nc -= 2;          // Esto es equivalente c = c - 2;\nconsole.log(c);  // 6\n// Con Multiplicacion\nlet d = 4;\nd *= 3;          // Esto es equivalente d = d * 3;\nconsole.log(d);  // 12\n//Con Division\nlet e = 15;\ne /= 5;          // Esto es equivalente e = e / 5;\nconsole.log(e);  // 3\n// Con Modulo\nlet f = 17;\nf %= 4;          // Esto es equivalente f = f % 4;\nconsole.log(f);  // 1\n// Con Potencia\nlet g = 2;\ng **= 3;         // Esto es equivalente g = g ** 3;\nconsole.log(g);  // 8\n\n\n// Operadores de Pertenencia ----- \n\n/*\nEl operador in se utiliza para verificar si una \npropiedad está presente en un objeto.\n*/\n\nlet persona = { nombre: 'Juan', edad: 25 };\n\nconsole.log('nombre' in persona);    // true\nconsole.log('apellido' in persona);  // false\n\n/*el operador in también se puede usar con arreglos \npara verificar si un índice está presente en el arreglo\n*/\n\nlet arreglo = [1, 2, 3];\n\nconsole.log(0 in arreglo);  // true\nconsole.log(5 in arreglo);  // false\n\n\n/*El operador instanceof se utiliza para verificar \nsi un objeto es una instancia de una clase o constructor específico.\n*/\n\nclass Animal {\n    constructor(nombre) {\n        this.nombre = nombre;\n    }\n}\n\nlet perro = new Animal('Buddy');\nconsole.log(perro instanceof Animal);  // true\n\n\n// Operadores de Bits ----- \n\nconsole.log(3 & 4);   // AND -> 0\nconsole.log(3 | 4);   // OR -> 7\nconsole.log(3 ^ 4);   // XOR -> 7\nconsole.log(~3);      // NOT -> -4\nconsole.log(3 << 4);  // Desplazamiento a izquierda -> 48\nconsole.log(3 >> 4);  // Desplazamiento a derecha -> 0\n\n\n// Sentencias de Control -----\n\n// 1. Condicionales \n\n// If else\nlet numero = 10;\n\nif ( numero > 0 ) {\n    console.log(\"El número es positivo\");\n} else {\n    console.log(\"El número es cero o negativo\");\n};\n\n// else if\nlet calificacion = 85;\n\nif (calificacion >= 90) {\n    console.log(\"A - Excelente\");\n} else if (calificacion >= 80) {\n    console.log(\"B - Bueno\");\n} else if (calificacion >= 70) {\n    console.log(\"C - Aceptable\");\n} else if (calificacion >= 60) {\n    console.log(\"D - Necesita mejorar\");\n} else {\n    console.log(\"F - Insuficiente\");\n};\n\n//Switch\nlet diaSemana = 3;\nlet nombreDia;\n\nswitch ( diaSemana ) {\n    case 1:\n        nombreDia = \"Lunes\";\n        break;\n    case 2:\n        nombreDia = \"Martes\";\n        break;\n    case 3:\n        nombreDia = \"Miercoles\";\n        break;\n    case 4:\n        nombreDia = \"Jueves\";\n        break;\n    case 5:\n        nombreDia = \"Viernes\";\n        break;\n    case 6:\n        nombreDia = \"Sábado\";\n        break;\n    case 7:\n        nombreDia = \"Domingo\";\n        break;\n    // ... otros casos ...\n    default:\n        nombreDia = \"Día no válido\";\n};\n\nconsole.log( \"Hoy es \" + nombreDia );\n\n\n// 2. Ciclos o Bucles\n\n// For\nfor ( let i = 1; i <= 5; i++ ) {\n    console.log( \"Iteración número : \" + (i) );\n};\n\n//While\nlet contador = 0;\n\nwhile ( contador < 5 ) {\n    console.log( \"Iteración número \" + ( contador + 1) );\n    contador++;\n};\n\n//Do While\nlet contador2 = 0;\n\ndo {\n    console.log(\"Iteración número \" + ( contador2 + 1) );\n    contador2++;\n} while ( contador2 < 5 );\n\n\n// 3. Ciclos para Objetos y Arrays\n// For in\n//se utiliza para iterar sobre las propiedades enumerables de un objeto.\n//Si se utiliza sobre un array este iterara solo las posiciones del indice\nlet person = {\n    nombre: \"Fabian\",\n    edad: 35,\n    pais: \"Colombia\"\n};\n\nfor ( let propiedad in person ) {\n    console.log( propiedad + \": \" + person[propiedad] );\n};\n\n// For of\n// itera sobre cada elemento del array\nlet frutas = [\"Manzana\", \"Banana\", \"Uva\"];\n\nfor ( let fruta of frutas ) {\n    console.log( fruta );\n};\n\n\n// 4. Manejo de errores o Excepciones\n//Try Catch\ntry {\n// Código que podría lanzar una excepción\n// Intentando dividir por cero\n    let resultado = 10 / 0; \n// Esta línea nunca se ejecutará si hay una excepción\n    console.log(resultado); \n} catch (error) {\n// Bloque de código que se ejecuta en caso de excepción\n    console.error(\"Ha ocurrido un error:\", error.message);\n} finally {\n// Bloque de código opcional que siempre se ejecuta, independientemente de si hay una excepción o no\n    console.log(\"Este bloque siempre se ejecuta\");\n};\n\n// El programa sigue ejecutándose después del manejo de la excepción\nconsole.log(\"El programa continúa después del bloque try...catch\");\n\n\n// Ejercicio Extra\n/*\nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3\n*/\n\n//Version 1\nfor ( let i = 10; i <= 55; i++ ) {\n    if ( i !== 16 && i % 3 !== 0 && i % 2 === 0 ) {\n        console.log( i );\n    }\n};\n\n\n//Version 2\nfor (let i = 10; i <= 55; i++) {\n    if ( i === 16 || i % 3 === 0 ) {\n        continue;\n    }\n    if (i % 2 === 0) {\n        console.log( i );\n    }\n};"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/BertoMP.js",
    "content": "// OPERADORES ARITMÉTICOS\nconsole.log('OPERADORES ARITMÉTICOS');\nconst firstNumber = 7;\nconst secondNumber = 2;\nlet result;\n\n// Operador suma (+)\nresult = firstNumber + secondNumber;\nconsole.log(`La suma de ${firstNumber} + ${secondNumber} es ${result}`);\n\n// Operador resta (-)\nresult = firstNumber - secondNumber;\nconsole.log(`La resta de ${firstNumber} - ${secondNumber} es ${result}`);\n\n// Operador multiplicación (*)\nresult = firstNumber * secondNumber;\nconsole.log(`La multiplicación de ${firstNumber} * ${secondNumber} es ${result}`);\n\n// Operador división (/)\nresult = firstNumber / secondNumber;\nconsole.log(`La división de ${firstNumber} / ${secondNumber} es ${result}`);\n\n// Operador módulo (%)\nresult = firstNumber % secondNumber;\nconsole.log(`El resto de la división de ${firstNumber} / ${secondNumber} es ${result}`);\n\n// OPERADORES LÓGICOS\nconsole.log('\\nOPERADORES LÓGICOS');\nconst firstBool = true;\nconst secondBool = false;\n\n// Operador lógico AND (&&)\nconst logicAnd = (firstBool && secondBool);\nconsole.log(`AND lógico: ${logicAnd}`);\n\n// Operador lógico OR (||)\nconst logicOr = (firstBool || secondBool);\nconsole.log(`OR lógico: ${logicOr}`);\n\n// Operador lógico NOT (!)\nconst logicNot = !firstBool;\nconsole.log(`NOT lógico: ${logicNot}`);\n\n// OPERADORES DE COMPARACIÓN\nconsole.log('\\nOPERADORES DE COMPARACIÓN');\n// Operador de igualdad (==)\nconst equalComp = (5 == '5');\nconsole.log(`¿Es 5 igual a '5'? -> ${equalComp}`); // Devuelve true porque JS hace una conversión del String a int.\n\n// Operador de desigualdad (!=)\nconst diffComp = (5 != '5');\nconsole.log(`¿Es 5 diferente de '5'? -> ${diffComp}`); // Devuelve false por la misma razón que antes.\n\n// Operador mayor que (>)\nconst greatThan = (5 > 10);\nconsole.log(`¿Es 5 mayor que 10? -> ${greatThan}`);\n\n// Operador menor que (>)\nconst lessThan = (5 < 10);\nconsole.log(`¿Es 5 menor que 10? -> ${lessThan}`);\n\n// Operador mayor o igual que (>=)\nconst greatOrEqual = (5 >= 10);\nconsole.log(`¿Es 5 mayor o igual que 10? -> ${greatOrEqual}`);\n\n// Operador menor o igual que (<=)\nconst lessOrEqual = (5 <= 10);\nconsole.log(`¿Es 5 menor o igual que 10? -> ${lessOrEqual}`);\n\n// OPERADORES DE ASIGNACIÓN\nconsole.log('\\nOPERADORES DE ASIGNACIÓN');\n// Operador de asignación simple (=)\nlet number = 10;\nconsole.log(`Valor asignado: ${number}`);\n\n// Operador de suma y asignación (+=)\nnumber += 5; // 10 + 5 = 15\nconsole.log(`Valor del resultado de suma y asignación: ${number}`);\n\n// Operador de resta y asignación (-=)\nnumber -= 5; // 15 - 5 = 10\nconsole.log(`Valor del resultado de resta y asignación: ${number}`);\n\n// Operador de multiplicación y asignación (+=)\nnumber *= 5; // 10 * 5 = 50\nconsole.log(`Valor del resultado de multiplicación y asignación: ${number}`);\n\n// Operador de división y asignación (/=)\nnumber /= 5; // 50 / 5 = 10\nconsole.log(`Valor del resultado de división y asignación: ${number}`);\n\n// Operador de módulo y asignación (%=)\nnumber %= 5; // 10 % 5 = 0\nconsole.log(`Valor del resultado de módulo y asignación: ${number}`);\n\n// OPERADORES DE IDENTIDAD\nconsole.log('\\nOPERADORES IDENTIDAD');\n// Operador de igualdad estricta\nconst strictEqualComp = (5 === '5');\nconsole.log(`¿Es 5 estrictamente igual a '5'? -> ${strictEqualComp}`);\n\n// Operador de desigualdad estricta (!==)\nconst strictDiffComp = (5 !== '5');\nconsole.log(`¿Es 5 estrictamente diferente a '5'? -> ${strictDiffComp}`);\n\n// OPERADORES DE PERTENENCIA\nconsole.log('\\nOPERADORES DE PERTENENCIA')\nconst intArray = [1, 12, 5, 643, 3];\nconst firstCheck = 3 in intArray; // Devolverá true\nconst secondCheck = 65 in intArray; // Devolverá false\n\nconsole.log(`¿Está el número 3 en el array de números? -> ${firstCheck}`);\nconsole.log(`¿Está el número 65 en el array de números? -> ${secondCheck}`);\n\n// OPERADORES DE BITS\nconsole.log('\\nOPERADORES DE BITS')\nconst firstBit = 5; // Representación binaria: 0000 0101\nconst secondBit = 3 // Representación binaria: 0000 0011\n\n// Operador AND a nivel de bits (&)\nconst bitAnd = firstBit & secondBit; // Devuelve 1 (representación binaria: 0000 0001)\nconsole.log(`Resultado AND bit a bit -> ${bitAnd}`);\n\n// Operador OR a nivel de bits (|)\nconst bitOr = firstBit | secondBit; // Devuelve 7 (representación binaria: 0000 0111)\nconsole.log(`Resultado OR bit a bit -> ${bitOr}`);\n\n// Operador XOR a nivel de bits (^)\nconst bitXor = firstBit ^ secondBit; // Devuelve 6 (representación binaria: 0000 0110)\nconsole.log(`Resultado OR bit a bit -> ${bitXor}`);\n\n// Operador NOT a nivel de bits (~)\nconst bitNot = ~firstBit; // Devuelve -6 (representación binaria: 1111 1010)\nconsole.log(`Resultado NOT bit a bit -> ${bitNot}`);\n\n// Operador de desplazamiento hacia la derecha (>>)\nconst toRightBit = firstBit >> 1; // Devuelve 2 (representación binaria: 0000 0010)\nconsole.log(`Desplazamiento hacia la derecha -> ${toRightBit}`);\n\n// Operador de desplazamiento hacia la izquierda (>>)\nconst toLeftBit = firstBit << 1; // Devuelve 10 (representación binaria: 0000 1010)\nconsole.log(`Desplazamiento hacia la derecha -> ${toLeftBit}`);\n\n// ESTRUCTURAS DE CONTROL CONDICIONAL\nconsole.log('\\nESTRUCTURAS DE CONTROL CONDICIONAL')\n// if-else\nconsole.log('if-else')\nconst num = 10;\n\nif (num > 0) {\n    console.log('El número es positivo.');\n} else if (num === 0) {\n    console.log('El número es cero.');\n} else {\n    console.log('El número es negativo.');\n}\n\n// Operador ternario\nconsole.log('\\nOperador ternario');\nconsole.log((num > 0) ? 'El número es positivo.' : 'El número es cero o negativo.');\n\n// switch-case\nconsole.log('\\nSwitch-Case');\nlet option = 1;\n\nswitch (option) {\n    case 1:\n        console.log('Se ha seleccionado la opción 1.');\n        break;\n    case 2:\n        console.log('Se ha seleccionado la opción 2.');\n        break;\n    default:\n        console.log('Opción por defecto.');\n}\n\n// ESTRUCTURAS DE CONTROL ITERATIVAS\nconsole.log('\\nESTRUCTURAS DE CONTROL ITERATIVAS')\n// while\nconsole.log('Bucle While');\nlet counter = 0;\nwhile (counter < 5) {\n    console.log(`Iteración: ${counter}`);\n    counter++;\n}\n\n// do-while\nconsole.log('\\nBucle do-while');\ncounter = 0;\ndo {\n    console.log(`Iteración: ${counter}`);\n    counter++;\n} while (counter < 5);\n\n// for\nconsole.log('\\nBucle for');\nfor (let counter = 0; counter < 5; counter++) {\n    console.log(`Iteración: ${counter}`);\n}\n\n// for ... of\nconsole.log('\\nBucle for ... of');\nconst arrNumbers = [1, 2, 5, 2, 7, 9];\nfor (const number of arrNumbers) {\n    console.log(`Número -> ${number}`);\n}\n\n// for ... in\nconsole.log('\\nBucle for ... in');\nconst persona = { name: 'Alberto', edad: 33 };\nfor (const att in persona) {\n    console.log(`${att} -> ${persona[att]}`);\n}\n\n// MANEJO DE EXCEPCIONES\nconsole.log('\\nMANEJO DE EXCEPCIONES');\nconsole.log('Bloque try-catch');\nconst errNumber = 10;\n\ntry {\n    if (errNumber === 10) {\n        throw new Error('El número es igual a 10.');\n    }\n    console.log('El número es distinto de 10.');\n} catch (error) {\n    console.log(`Se ha producido un error debido a -> ${error.message}`);\n}\n\nconsole.log('\\nBloque try-catch-finally');\ntry {\n    if (errNumber === 10) {\n        throw new Error('El número es igual a 10.');\n    }\n    console.log('El número es distinto de 10.');\n} catch (error) {\n    console.log(`Se ha producido un error debido a -> ${error.message}`);\n} finally {\n    console.log('Bloque finally. Esto siempre se ejecuta haya o no excepción.');\n}\n\n// DIFICULTAD EXTRA\nconsole.log(\"\\nEJERCICIO EXTRA\");\n/*  Crea un programa que imprima por consola todos los números comprendidos entre 10 y 55 (incluidos), pares, y\n *  que no son ni el 16 ni múltiplos de 3.*/\nfor (let i = 10; i <= 55; i++) {\n    if ((i % 2 === 0) && (i !== 16) && (i % 3 !== 0)) {\n        console.log(\"Iteración: \" + i);\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/Carles11.js",
    "content": "/*\n * EJERCICIO 1:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes) */\n\nvar suma = 1 + 2;\nvar resta = 1 - 2;\nvar multiplica = 1 * 2;\nvar divide = 1 / 2;\nvar modulo = 1 % 2;\nvar exponente = 1 ** 2;\n\nvar estrictamenteIgualA = 1 === '2';\nvar distintoA = 1 !== \"2\";\nvar mayorQue = 1 > 2;\nvar menorQue = 1 < 2;\nvar mayorOigualQue = 1 >= 2;\nvar menorOigualQue = 1 <= 2;\n\nvar andY = 1 && 2;\nvar orO = 1 || 2;\nvar notNo = !!true;\n\nvar array = [1,2,3];\nvar object = {a: 1, b: 2, c: 3};\n\nvar isArray = Array.IsArray(array);\n\nvar belongsToArray = array.includes(3);\nvar belongsToObject = \"a\" in object;\n\n\n\n\n/*\n * EJERCICIO 2: * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n */\n\n // Condicionales\nif (2 < 1) {\n    console.log(\"no way...\");\n} else {\n    console.log(\"2 is not less than 1\");\n}\n\nlet num = 3;\nswitch (num) {\n    case 1:\n        console.log(\"Number is 1\");\n        break;\n    case 2:\n        console.log(\"Number is 2\");\n        break;\n    case 3:\n        console.log(\"Number is 3\");\n        break;\n    default:\n        console.log(\"Number is not 1, 2 or 3\");\n        break;\n}\n\n// Iterativas\nvar array = [1, 2, 3, 4, 5];\n\nvar doblaForEach = array.forEach(num => console.log(\"doblaForEach:\", num * 2)); \nvar doblaMap = array.map(num => num * 2);\nconsole.log(\"Dobla con map:\", doblaMap);\n\nfor (let i = 0; i < array.length; i++) {\n    console.log(\"forLoop:\", array[i]);\n}\n\nvar filtra = array.filter(num => num !== 4);\nconsole.log(\"Filtra:\", filtra);\n\nlet counter = 0;\nwhile (counter < 3) {\n    console.log(\"While loop:\", counter);\n    counter++;\n}\n\ncounter = 0;\ndo {\n    console.log(\"doWhileLoop:\", counter);\n    counter++;\n} while (counter < 3);\n\n// Excepciones\ntry {\n    // Intenta ejecutar este código\n    let resultado = 10 / 0;\n    if (!isFinite(resultado)) {\n        throw new Error(\"División por cero no permitida\");\n    }\n} catch (error) {\n    // Maneja cualquier error que ocurra\n    console.error(\"Error capturado:\", error.message);\n} finally {\n    // Este bloque siempre se ejecuta\n    console.log(\"Operación de división intentada\");\n}\n\n /*\n * EJERCICIO 3:* - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * \n *  */\n console.log(\"Suma:\", suma); // 3\n console.log(\"Resta:\", resta); // -1\n console.log(\"Multiplica:\", multiplica); // 2\n console.log(\"Divide:\", divide); // 0.5\n console.log(\"Modulo:\", modulo); // 1\n console.log(\"Exponente:\", exponente); // 1\n \n console.log(\"Estrictamente igual a:\", estrictamenteIgualA); // false\n console.log(\"Distinto a:\", distintoA); // true\n console.log(\"Mayor que:\", mayorQue); // false\n console.log(\"Menor que:\", menorQue); // true\n console.log(\"Mayor o igual que:\", mayorOigualQue); // false\n console.log(\"Menor o igual que:\", menorOigualQue); // true\n \n console.log(\"AND (&&):\", andY); // 2\n console.log(\"OR (||):\", orO); // 1\n console.log(\"NOT (!!):\", notNo); // true\n \n console.log(\"Es array:\", isArray); // true\n \n console.log(\"Pertenece al array:\", belongsToArray); // true\n console.log(\"Pertenece al objeto:\", belongsToObject); // true\n\n\n  /*\n  * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n\nconst programa = () => {\n    const min = 10\n    const max = 55\n    const noPrint = 16\n\n    for (let i = min; i <= max; i++){\n\n        if(i !== noPrint && i % 2 === 0 && i % 3 !== 0)\n        console.log(\"este cumple los requisitos: \", i)\n    }\n}\n\nprograma()"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/CarlosMqz969.js",
    "content": "// * EJERCICIO:\n\n/* - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes) */\n\n\n\n// Operadores aritméticos\n\nlet num1 = 7\nlet num2 = 3\n\n//Suma\nconsole.log(`La suma de ${num1} + ${num2} es igual a: ${num1 + num2}`)\n\n//Resta\nconsole.log(`La resta de ${num1} - ${num2} es igual a: ${num1 - num2}`)\n\n//Multiplicación\nconsole.log(`La multiplicación de ${num1} * ${num2} es igual a: ${num1 * num2}`)\n\n//División\nconsole.log(`La división de ${num1} / ${num2} es igual a: ${num1 / num2}`)\n\n//Incremento\nlet num3 = 6\nconsole.log(`El número original es ${num3}`)\n\nnum3++\nconsole.log(`Si incrementamos en 1 el número resultante es: ${num3}`)\n\n//Decremento\nnum3 = 6\nnum3--\nconsole.log(`Si decrementamos en 1 el número resultante es: ${num3}`)\n\n// Operadores de asignación\n\nlet num4 = 5\nconsole.log(`El número original es :${num4}`)\nnum4 += 2\nconsole.log(`Si le añadimos 2 sería igual a: ${num4}`)\nnum4 -= 2\nconsole.log(`Si le restamos 2 sería igual a: ${num4}`)\nnum4 *= 2\nconsole.log(`Si lo multiplicamos *2 sería igual a: ${num4}`)\nnum4 /= 2\nconsole.log(`Si le dividimos / 2 sería igual a: ${num4}`)\nnum4 **= 2\nconsole.log(`Si lo elevamos al cuadrado nos da como resultado: ${num4}`)\nnum4 %= 2\nconsole.log(`El resto de 2 es igual a: ${num4}`)\n\n// Operadores de comparación\n\nlet num5 = 9\nconsole.log(`El primer número es: ${num5}`)\nlet num6 = 7\nconsole.log(`El segundo número es: ${num6}`)\n\nconsole.log(`El número ${num5} es mayor que ${num6}: ${num5 > num6}`)\nconsole.log(`El número ${num5} es menor que ${num6}: ${num5 < num6}`)\nconsole.log(`El número ${num5} es mayor o igual que ${num6}: ${num5 >= num6}`)\nconsole.log(`El número ${num5} es menor o igual que ${num6}: ${num5 <= num6}`)\nconsole.log(`El número ${num5} es igual que ${num6}: ${num5 == num6}`) // Igualdad por valor\nconsole.log(`El número ${num6} es igual que ${num6}: ${num6 === num6}`) // Igualdad por identidad\nconsole.log(`El número ${num5} es igual que \"9\": ${num5 === \"9\"}`) \nconsole.log(`El número ${num5} es igual que 9: ${num5 === 9}`) \nconsole.log(`El número ${num5} es diferente que 9: ${num5 != 9}`) \n\n//Operadores lógicos\n\n\n//AND (&&)\n\nconsole.log(5>3 && 7>4)\nconsole.log(5 < 10 && 15 < 20)\nconsole.log(5 < 10 && 15 > 20)\nconsole.log(5 < 10 && 15 > 20 && 30 > 40)\n\n\n//OR (||)\n\nconsole.log(5 > 10 || 15 > 20)\nconsole.log(5 < 10 || 15 < 20)\nconsole.log(5 < 10 || 15 > 20)\n\nconsole.log(5 < 10 && 15 > 20 || 30 < 40)\n\n// not (!)\nconsole.log(!true)\nconsole.log(!false)\nconsole.log(!(5 < 10 && 15 >20))\n\n\n// Operadores ternarios\n\nconst tenemosAgua = true\n\ntenemosAgua ? console.log(\"Nos bañamos\") : console.log(\"Pura colonia y sale jajajaja!\")\n\nlet num7 = 7 // 0111\nlet num8 = 8 // 1000\nlet num9 = 9 // 1001\nlet num10 = -9\nlet resultado = 0\n\n// Operadores bitwise\n\n//Operador &\nconsole.log(resultado=(num7 & num8))\nconsole.log(resultado=(num9 & num8))\n\n//Operador |\nconsole.log(resultado=(num7 | num8))\n\n// Operador ^\nconsole.log(resultado =(num7 ^ num8))\nconsole.log(resultado =(num9 ^ num8))\n\n// Operador NOT ~\nconsole.log(~num7)\n\n//Operadores de desplazamiento\n\n//Operador de desplazamiento de izquierda\nconsole.log(resultado=(num7 << 2))\n\n//Operador de desplazamiento de derecha\nconsole.log(resultado=(num7 >> 2))\n\n//Operador de desplazamiento a la derecha con relleno cero \nconsole.log(resultado=(num10 >>> 2))\n\n//Operador typeof\nlet var1 = \"Palabra\"\nconsole.log(typeof(var1))\nconsole.log(typeof(num1))\nconsole.log(typeof(true))\n\nclass Person{\n    constructor(name, age, alias){\n        this.name = name\n        this.age = age\n        this.alias = alias\n\n    }\n}\nconsole.log(typeof(Person))\n\nlet person = new Person(\"Carlos\", 33, \"CarlosMqz969\")\nconsole.log(typeof(person))\n\n\n//Operador instanceof\nconsole.log(person instanceof Person)\nconsole.log(person instanceof Object)\nconsole.log(person instanceof Array)\n\n// Operador in\n\nconsole.log(\"name\" in person)\nconsole.log(\"alias\" in person)\nconsole.log(\"country\" in person)\n\n// Operador de función nula\n// Ideal para valores que pueden ser null o undefined \nlet bebida = null\nlet resultadoBebida = bebida ?? \"Agua\"\nconsole.log(resultadoBebida)\n\n// Operador coma ,\n// Evalua varias expresiones y devuelve la última\n\nlet x = (console.log(\"Uno\"), console.log(\"Dos\"), 3)\nconsole.log(x)\n\n/*\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n\n*/\n\n// Condicionales\n\n// if \n// else \n// if else\n\nlet edad = 20\n\nif(edad == 18){\n    console.log(`Acabas de cumplir la mayoria de edad tienes: ${edad} años de edad, bienvenido!`)\n} else if(edad < 18){\n    console.log(`Lo lamento no eres mayor de edad tienes: ${edad} años y debes superar los 18 años de edad para poder ingresar`)\n} else{\n    console.log(`Tienes: ${edad} años de edad, bienvenido!`)\n}\n\n// switch\n\nlet idioma = 9\nlet saludo\n\nswitch(idioma){\n    case 0:\n        saludo = \"Hola y bienvenido al mundo de la programación\" // Español\n        break\n        case 1:\n        saludo =\"Hello and welcome to the world of programming\" // Ingles\n        break\n        case 2:\n        saludo =\"Hallo und willkommen in der Welt des Programmierens\" // Aleman\n        break\n        case 3:\n        saludo = \"Bonjour et bienvenue dans le monde de la programmation\" // Frances\n        break\n        case 4:\n        saludo = \"こんにちは、プログラミングの世界へようこそ\" // Japones\n        break\n        case 5:\n        saludo = \"Olá e bem-vindo ao mundo da programação\" // Portugues\n        break\n        case 6:\n        saludo = \"你好，歡迎來到程式設計世界\" // Chino\n        break\n        default:\n        saludo = \"您沒有添加正確的語言\" // Error en chino jajajaja\n\n}\nconsole.log(saludo)\n\n/*\nIterativas (bucles)\n\nfor\n\nwhile\n\ndo...while\n\nfor...of (para recorrer arrays)\n\nfor...in (para recorrer propiedades de objetos)\n\n*/\n\n// Bucle for\n\nfor (i = 1; i<= 20; i++){\n    console.log(`Vamos en el número: ${i}`)\n}\nconsole.log(\"Felicidades saliste del bucle for! :D\")\n\n// Bucle while\n\nlet numeros = [5, 3, 2, 7, 3, 0]\nlet iterable = 0\nlet sumatoria = 0\n\nwhile (numeros[iterable] !== 0) {\n    sumatoria += numeros[iterable]\n    iterable ++\n}\n\nconsole.log(\"La suma total es: \" + sumatoria)\n\n// do while\n\nlet iterable1 = 10\n\ndo {\n    console.log(`Contemos del 10 al 1: ${iterable1}`)\n    iterable1 --\n} while (iterable1 >= 1)\n    console.log(\"Cuenta regresiva terminada :D\")\n\n//for...of (para recorrer arrays)\n\nlet myArray = new Array(5)\nmyArray = [1, 2, 3, 4, 5]\n\nfor (let array_valor of myArray){\n    console.log(array_valor)\n}\n\n//for...in (para recorrer propiedades de objetos)\n\nlet account = {\n    name: \"Carlos\",\n    surname: \"Marquez\",\n    age: 33\n}\n\nfor (let object_valor in account) {\n    console.log(`${object_valor}: ${account[object_valor]}`)\n}\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n * */\n\nfor (let range = 10; range <= 55; range ++){\n    if(range %2 == 0 && range != 16 && range %3 != 0){\n        console.log(`numero: ${range}`)\n    } \n}\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/CaveroBrandon.js",
    "content": "/*\nEJERCICIO:\n - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n */\n\n// Arithmetics operators \nconst first_num = 5;\nconst second_num = 6;\n\nlet sum = first_num + second_num;   // Addition\nlet subs = second_num - first_num;  // Substraction\nlet mul = first_num * second_num;   // Multiplication\nlet div = second_num / 2;           // Division\nlet rem = second_num % 2;           // Remainder\n\n// Logical operators\nconst first_bool = true;\nconst second_bool = false;\n\nlet and_operator = first_bool && second_bool;   // AND\nlet or_operator = first_bool || second_bool;    // OR\nlet not_operator = !(first_bool);               // NOT\n\n// Comparison operators, identity operators\nlet equal_to = first_bool == 5;                 // Equal to\nlet equal_value = first_bool === '5';           // Equal value\nlet not_equal = first_bool != 5;                // Not equal to\nlet not_equal_value = first_bool !== '5';       // Not equal value\nlet greater_than = first_bool > second_bool;    // Greater than\nlet less_than = first_bool < second_bool;       // Less than\nlet greater_or_equal = first_bool >= 5;         // Greater than or equal to\nlet less_or_equal = first_bool <= 5;            // Less than or equal to\n\n\n// Assignment operators\nlet simple_assignment = 5;      // Simple assignment\nlet addition_assignment = 5;\naddition_assignment += 10;      // Addition assignment\nlet substraction_assignment = 10;\nsubstraction_assignment -= 5;   // Substraction assignment\nlet multiplication_assignment = 10;\nmultiplication_assignment *= 5; // Multiplication assignment\nlet exponential_assignment = 10;\nexponential_assignment **= 2;   // Exponential assignment\nlet division_assignment = 10;\ndivision_assignment /= 5;       // Division assignment\nlet remainder_operator = 10;\nremainder_operator %= 2;        // Remainder assignment\n\n// Bitwise operators\nlet and_bit_operator = first_bool & second_bool;    // And\nlet or_bit_operator = first_bool | second_bool;     // Or\nlet xor_bit_operator = first_bool ^ second_bool;    // Xor\n\nlet bit_const = 7\nlet zero_fill_left =  bit_const << 1;       // Zero fill left shift\nlet signed_right_shift = bit_const >> 1;    // Signed right shift\n\n /*\n- Utilizando las operaciones con operadores que tú quieras, crea ejemplos\nque representen todos los tipos de estructuras de control que existan\nen tu lenguaje:\n- Condicionales, iterativas, excepciones...\n- Debes hacer print por consola del resultado de todos los ejemplos.\n */\nconsole.log('*********** If ***********');\nlet condition = true;\nif (condition) {\n    console.log('The condition is \"true\" so this will be printed');\n}\nelse if (condition == false) {\n    console.log('This should be printed if the condition is \"false\"');\n}\nelse if (condition == '0') {\n    console.log('This condition should be printed if the value of condition is \"0\"');\n}\n\nconsole.log('*********** For ***********');\nfor (let i = 0; i < 5; i++) {\n    console.log('Counting using a for loop: ' + i);\n}\n\nconsole.log('*********** While ***********');\nlet while_condition = 5;\nwhile (while_condition > 0) {\n    console.log('Counting using a while loop: ' + while_condition);\n    while_condition -= 1;\n}\n\nconsole.log('*********** Try - Catch ***********');\ntry {\n    nonExistingFunction();\n}\ncatch (error) {\n    console.error('This is being printed because of the error: '+ error)\n}\n\n /*\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n for (i = 10; i < 56; i++) {\n    if (! (i == 16 || i % 3 == 0) && (i % 2 == 0) || (i == 55)) {\n        console.log(i)\n    }\n }\n "
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/CesarCarmona30.js",
    "content": "\"use strict\";\n\n/*\n* EJERCICIO:\n*/\n\n// Operadores aritméticos\nconsole.log(\"******** OPERADORES ARITMÉTICOS ********\");\nconsole.log(\"SUMA: 4 + 5 =\", 4 + 5);\nconsole.log(\"RESTA: 4 - 5 =\", 4 - 5);\nconsole.log(\"MULTIPLICACIÓN: 4 * 5 =\", 4 * 5);\nconsole.log(\"DIVISIÓN: 4 / 5 =\", 4 / 5);\nconsole.log(\"MÓDULO: 4 % 5 =\", 4 % 5);\nconsole.log(\"POTENCIA: 4 ** 5 =\", 4 ** 5);\n\n// Operadores de comparación\nconsole.log(\"******** OPERADORES DE COMPARACIÓN ********\");\nconsole.log(\"IGUAL QUE: 4 == 5:\", 4 == 5);\nconsole.log(\"DIFERENTE DE: 4 != 5:\", 4 != 5);\nconsole.log(\"ESTRICTAMENTE IGUAL QUE: 4 === 5:\", 4 === 5);\nconsole.log(\"ESTRICTAMENTE DIFERENTE DE: 4 !== 5:\", 4 !== 5);\nconsole.log(\"MAYOR QUE: 4 > 5:\", 4 > 5);\nconsole.log(\"MENOR QUE: 4 < 5:\", 4 < 5);\nconsole.log(\"MAYOR O IGUAL QUE: 4 >= 5:\", 4 >= 5);\nconsole.log(\"MENOR O IGUAL QUE: 4 <= 5:\", 4 <= 5);\n\n// Operadores lógicos\nconsole.log(\"******** OPERADORES LÓGICOS ********\");\nconsole.log(\"AND: true && false:\", true && false);\nconsole.log(\"OR: true || false:\", true || false);\nconsole.log(\"NOT: !true:\", !true);\n\n// Operadores de asignación\nconsole.log(\"******** OPERADORES DE ASIGNACIÓN ********\");\nlet x = 5;\nconsole.log(\"x =\", x);\nx += 2;\nconsole.log(\"x += 2 ->\", x);\nx -= 1;\nconsole.log(\"x -= 1 ->\", x);\nx *= 3;\nconsole.log(\"x *= 3 ->\", x);\nx /= 2;\nconsole.log(\"x /= 2 ->\", x);\nx %= 4;\nconsole.log(\"x %= 4 ->\", x);\nx **= 2;\nconsole.log(\"x **= 2 ->\", x);\n\n// Operadores de identidad\nconsole.log(\"******** OPERADORES DE IDENTIDAD ********\");\nlet a = [1, 2, 3];\nlet b = a;\nconsole.log(\"a === b:\", a === b);\nlet c = [...a];\nconsole.log(\"a === c:\", a === c);\nconsole.log(\"a == c:\", a == c);\n\n// Operadores a nivel de bits\nconsole.log(\"******** OPERADORES A NIVEL DE BITS ********\");\nconsole.log(\"AND: 4 & 5 =\", 4 & 5);\nconsole.log(\"OR: 4 | 5 =\", 4 | 5);\nconsole.log(\"XOR: 4 ^ 5 =\", 4 ^ 5);\nconsole.log(\"NOT: ~4 =\", ~4);\nconsole.log(\"Desplazamiento a la izquierda: 4 << 1 =\", 4 << 1);\nconsole.log(\"Desplazamiento a la derecha: 4 >> 1 =\", 4 >> 1);\n\n// Estructuras de control condicionales\nconsole.log(\"******** ESTRUCTURAS DE CONTROL CONDICIONALES ********\");\nif (x > 2) {\n    console.log(\"x es mayor que 2\");\n} else if (x == 2) {\n    console.log(\"x es igual a 2\");\n} else {\n    console.log(\"x es menor que 2\");\n}\n\n// Estructuras de control iterativas\nconsole.log(\"******** ESTRUCTURAS DE CONTROL ITERATIVAS ********\");\nconsole.log(\"Bucle for:\");\nfor (let i = 0; i < 3; i++) {\n    console.log(\"i =\", i);\n}\n\nconsole.log(\"Bucle while:\");\nlet n = 3;\nwhile (n > 0) {\n    console.log(\"n =\", n);\n    n--;\n}\n\n// Manejo de excepciones\nconsole.log(\"******** MANEJO DE EXCEPCIONES ********\");\ntry {\n    let resultado = 10 / 0;\n} catch (e) {\n    console.log(\"No se puede dividir por cero\");\n} finally {\n    console.log(\"Bloque finally ejecutado\");\n}\n\n/* \n* DIFICULTAD EXTRA\n*/\nconsole.log(\"******** DIFICULTAD EXTRA ********\");\nlet values = \"[ \";\nfor (let num = 10; num <= 55; num++) {\n    if (num % 2 === 0 && num !== 16 && num % 3 !== 0) {\n        values += num + \", \";\n    }\n}\n\nconsole.log(values + \"]\");"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/DAVstudy.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n// Operadores aritmeticos\nlet x = 10;\nlet y = 5;\n\nconsole.log(`Suma: ${x + y}`);\nconsole.log(`Resta: ${x - y}`);\nconsole.log(`Multiplicacion: ${x * y}`);\nconsole.log(`Division: ${x / y}`);\nconsole.log(`Modulo: ${x % y}`);\nconsole.log(`Potencia: ${x ** y}`);\n\n// Operadores de comparacion\nconsole.log(`Igualdad: ${x == y}`);\nconsole.log(`Estrictamente igual: ${x === y}`);\nconsole.log(`Mayor que ${x > y}`);\nconsole.log(`Menor que ${x < y}`);\nconsole.log(`Mayor o igual que ${x >= y}`);\nconsole.log(`Menor o igual que ${x <= y}`);\nconsole.log(`Distinto: ${x != y}`);\n\n// Operadores de asignacion\nlet z = 2;\nconsole.log(`Suma: ${(z += 1)}`);\nconsole.log(`Resta: ${(z -= 1)}`);\nconsole.log(`Multiplicacion: ${(z *= 2)}`);\nconsole.log(`Division: ${(z /= 1)}`);\nconsole.log(`Modulo: ${(z %= 3)}`);\nconsole.log(`Potencia: ${(z **= 2)}`);\n\n// Operadores de bit a bit\nconsole.log(`Desplazamiento a la izq: ${(z <<= 8)}`);\nconsole.log(`Desplazamiento a la der: ${(z >>= 3)}`);\nconsole.log(`Desplazamiento a la der sin signo: ${(z >>>= 1)}`);\nconsole.log(`Asignación AND bit a bit ${(x &= y)}`);\nconsole.log(`Asignación XOR bit a bit ${(x ^= y)}`);\nconsole.log(`Asignación OR bit a bit ${(x |= y)}`);\nconsole.log(`Asignación AND lógico ${(x &&= y)}`);\nconsole.log(`Asignación OR lógico ${(x ||= y)}`);\nconsole.log(`Asignación de anulación lógica ${(x ??= y)}`);\n\n// Operadores lógicos\n\n// AND &&\nconsole.log(5 > 10 && 15 > 20); // false\nconsole.log(5 < 10 && 15 > 20); // false\nconsole.log(5 > 10 && 15 < 20); // false\nconsole.log(5 < 10 && 15 < 20); // true\n\n// OR ||\nconsole.log(5 > 10 || 15 > 20); // false\nconsole.log(5 < 10 || 15 > 20); // true\nconsole.log(5 > 10 || 15 < 20); // true\nconsole.log(5 < 10 || 15 < 20); // true\n\nconsole.log(5 < 10 || (15 < 20 && 30 > 30)); // true\n\n// NOT !\nconsole.log(!(5 > 10 && 15 > 20)); // true\nconsole.log(!(5 > 10 || 15 > 20)); // true\n\n// Operadores ternarios\nconst isRaining = true;\n\nisRaining ? console.log(\"Esta lloviendo\") : console.log(\"No esta lloviendo\");\n\n// Estructuras de control o condicionales\n\n// if\nlet myVariable = \"Diego\";\n\nif (myVariable === \"Diego\") {\n  console.log(\"Diego\");\n}\n\n// if else\nlet number = -2;\n\nif (number > 0) {\n  console.log(\"Numero positivo\");\n} else {\n  console.log(\"El numero no es positivo\");\n}\n\n// if else if else\nif (number > 0) {\n  console.log(\"Numero positivo\");\n} else if (number < 0) {\n  console.log(\"Numero negativo\");\n} else {\n  console.log(\"El numero es cero\");\n}\n\n// Switch\nlet lenguage = \"it\";\n\nswitch (lenguage) {\n  case \"es\":\n    console.log(\"hola\");\n    break;\n  case \"en\":\n    console.log(\"Otoño\");\n    break;\n  case \"it\":\n    console.log(\"achiao\");\n  default:\n    break;\n}\n\n// Estructuras iterativas\n\n// for\nfor (let i = 0; i < 21; i++) {\n  console.log(i);\n}\n\n// for of\nlet myArray = [\"Ana\", \"Carlos\", \"Lucía\", \"Pedro\", \"Marta\"];\nfor (const name of myArray) {\n  console.log(name);\n}\n\n// for in\nlet car = {\n  color: \"red\",\n  model: \"sedan\",\n  wheels: 4,\n};\n\nfor (const key in car) {\n  if (car.hasOwnProperty.call(car, key)) {\n    const element = car[key];\n    console.log(key, element);\n  }\n}\n\n// forEach\nmyArray.forEach((element) => {\n  console.log(element);\n});\n\n// while\nconst word = \"arroz\";\nconst lengthWord = word.length;\nlet result8 = \"\";\ncount = 0;\nwhile (count < lengthWord) {\n  result8 = result8 + word[lengthWord - 1 - count];\n  count++;\n}\nconsole.log(result8);\n\n// do while\ni = 6\ndo {\n    console.log(`Hola ${i}`)\n    i++\n} while (i < 5)\n\n\n// excepciones\n\n// try - catch - finally\nlet a = 0\ntry {\n  console.log(...a);\n} catch (error) {\n  console.log(`Error: ${error.message}`);\n} finally {\n  console.log(\"Fin de la funcion\");\n}\n\n\n/*\n* DIFICULTAD EXTRA (opcional):\n* Crea un programa que imprima por consola todos los números comprendidos\n* entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n*\n* Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n*/\n\nfor (let i = 10; i < 56; i++) {\n  if (i % 2 === 0 && i !== 16 && (i % 3 !== 0)) console.log(i) \n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/DHBellini.js",
    "content": "/*\n * EJERCICIO:\n * 1- Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n\n//Aritmeticos\n\nlet valor1 = 5;\nlet valor2 = 8;\nlet valor3 = 12;\n\nlet suma = valor2 + valor3;\nlet resta = valor3 - valor1;\nlet multiplicar = valor1 * valor2;\nlet dividir = valor3 / valor1;\nlet modulo = valor3 % valor2;\nlet exponencial = valor1 ** valor2;\n\nconsole.log(suma);\nconsole.log(resta);\nconsole.log(multiplicar);\nconsole.log(dividir);\nconsole.log(modulo);\nconsole.log(exponencial);\n\n\n//Logicas\nlet a = 4\nlet b = 8\n\nlet and = (a > 2) && (b > 2);\nlet or = (a > 5) || (b > 5);\n\nconsole.log(and);\nconsole.log(or);\n\n\n//Comparación\nlet c = 2\nlet d = 5\n\nif (c >= d){\n    console.log(c + \" es mayor o igual que \" + d)       \n    }else {\n        console.log(c + \" es menor que \" + d);       \n    };  \n\n\n//Operador de concatenación \nlet name = \"John\";\nlet lastName = \"Connor\";\nlet fullName = name + \" \" + lastName;\nconsole.log(fullName);\n\n\n//Condicionales\nlet e = 7\nlet f = 3\nif (e > f){\n    console.log(\"it's large than\");  \n}\n\n\n//Ternario\nlet age = 20\nlet message = (age >= 18) ? \"you are adult\" : \"Under age\";\nconsole.log(message);\n\n\n//Switch es para evaluar una expresión y ejecute el bloque de codigo correspondiente al valor que coincide\nlet days = 6 //Saturday\n\nswitch (days) {\n    case 1:\n        console.log(\"Monday\");\n        break;\n    case 2:\n        console.log(\"Tuesday\");\n        break;\n    case 3:\n        console.log(\"Wednesday\");\n        break;\n    case 4:\n        console.log(\"Thursday\");\n        break;\n    case 5:\n        console.log(\"Friday\");\n        break;\n    case 6:\n        console.log(\"Saturday\");\n        break;\n    case 7: \n        console.log(\"Sunday\");\n        break;\n    default:\n        console.log(\"number to day invalid\");\n}\n\n\n//Manejo de excepcion\ntry {\n    let multiplicacion = 8 * 4;\n    console.log(\"El resultado es: \" + multiplicacion);\n} catch (error) {\n    console.log(\"Se ha producido un error: \" + error.message);\n}\n\n\n//Ejercicio extra\nfor (let i = 10; i <= 55; i++){\n    if(i % 2 === 0 && i !== 16 && i % 3 !== 0)\n    console.log(i); \n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/Dan-Corbo.js",
    "content": "/*\n* EJERCICIO:\n* 1- Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n*   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n*   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n* 2- Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n*   que representen todos los tipos de estructuras de control que existan\n*   en tu lenguaje:\n*   Condicionales, iterativas, excepciones...\n* 3- Debes hacer print por consola del resultado de todos los ejemplos.\n*\n* DIFICULTAD EXTRA (opcional):\n* Crea un programa que imprima por consola todos los números comprendidos\n* entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n*\n* Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n*/\n\n/* Soluciones */\n\n/* 1 - 3 */\n\n/* Aritméticos */\n\nlet a = 5;\nlet b = 2;\n\nconsole.log(\"Suma:\", a + b);       // Suma: 7\nconsole.log(\"Resta:\", a - b);      // Resta: 3\nconsole.log(\"Multiplicación:\", a * b); // Multiplicación: 10\nconsole.log(\"División:\", a / b);   // División: 2.5\nconsole.log(\"Módulo:\", a % b);     // Módulo: 1\nconsole.log(\"Incremento:\", ++a);   // Incremento: 6\nconsole.log(\"Decremento:\", --b);   // Decremento: 1\n\n/* Lógicos */\n\nlet x = true;\nlet y = false;\n\nconsole.log(\"AND:\", x && y);   // AND: false\nconsole.log(\"OR:\", x || y);    // OR: true\nconsole.log(\"NOT:\", !x);       // NOT: false\n\n/* Comparación */\n\nlet num1 = 10;\nlet num2 = \"10\";\n\nconsole.log(\"Igualdad:\", num1 == num2);      // Igualdad: true\nconsole.log(\"Igualdad estricta:\", num1 === num2); // Igualdad estricta: false\nconsole.log(\"Desigualdad:\", num1 != num2);    // Desigualdad: false\nconsole.log(\"Desigualdad estricta:\", num1 !== num2); // Desigualdad estricta: true\nconsole.log(\"Mayor que:\", num1 > num2);       // Mayor que: false\nconsole.log(\"Menor que:\", num1 < num2);       // Menor que: false\n\n/* Asignación */\n\nlet variable = 10;\n\nvariable += 5;\nconsole.log(\"Suma y asignación:\", variable); // Suma y asignación: 15\n\nvariable *= 2;\nconsole.log(\"Multiplicación y asignación:\", variable); // Multiplicación y asignación: 30\n\n/* Identidad */\n\nlet obj1 = { name: \"John\" };\nlet obj2 = { name: \"John\" };\n\nconsole.log(\"Igualdad de identidad:\", obj1 === obj2); // Igualdad de identidad: false\n\n/* Pertenencia */\n\nlet array = [1, 2, 3, 4, 5];\n\nconsole.log(\"Pertenece al array:\", 3 in array); // Pertenece al array: true\n\n/* Bits */\n\nlet num3 = 5; // Representación binaria: 101\nlet num4 = 3; // Representación binaria: 011\n\nconsole.log(\"AND a nivel de bits:\", num3 & num4); // AND a nivel de bits: 1\nconsole.log(\"OR a nivel de bits:\", num3 | num4);  // OR a nivel de bits: 7\n\n/* 2 - 3 */\n\n/* Estructuras de Control */\n\n/* Condicionales */\n\nlet edad = 18;\n\nif (edad >= 18) {\n    console.log(\"Puedes beber alcohol xD.\");\n} else {\n    console.log(\"No puedes beber alcohol :'(.\");\n}\n\n/* Iterativas */\n\nfor (let i = 1; i <= 5; i++) {\n    console.log(\"Iteración:\", i);\n}\n\nlet arrayIterativo = [10, 20, 30, 40, 50];\nfor (let elemento of arrayIterativo) {\n    console.log(\"Elemento:\", elemento);\n}\n\n/* Excepciones */\n\ntry {\n    // Código que puede generar una excepción\n    let resultado = 10 / 0;\n    console.log(\"Resultado:\", resultado);\n} catch (error) {\n    console.error(\"Error:\", error.message);\n} finally {\n    console.log(\"Bloque finally ejecutado siempre.\");\n}\n\n/* Extra - Switch */\n\nlet diaDeLaSemana = \"Lunes\";\n\nswitch (diaDeLaSemana) {\n    case \"Lunes\":\n        console.log(\"Es el primer día de la semana.\");\n        break;\n    case \"Martes\":\n    case \"Miércoles\":\n    case \"Jueves\":\n        console.log(\"Estamos a mitad de semana.\");\n        break;\n    case \"Viernes\":\n        console.log(\"¡Viernes! Fin de la semana laboral.\");\n        break;\n    case \"Sábado\":\n    case \"Domingo\":\n        console.log(\"Fin de semana, tiempo para descansar.\");\n        break;\n    default:\n        console.log(\"Día no reconocido.\");\n}\n\n\n/* Opcional */\n\nfor (let i = 10; i <= 55; i++) {\n    if (\n        i % 2 === 0 && i !== 16 && i % 3 !== 0\n    ) {\n        console.log(\"Número\", i );\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/DanielBustos342.js",
    "content": "let a = 5;\nlet b = 2;\n\n//! Operadores aritmeticos: ESTOS OPERADORES REALIZAN OPERACIONES MATEMATICAS SOBRE NUMEROS\nconsole.log(`Operadores aritmeticos:`);\n//* suma\nlet suma = a + b;\nconsole.log(`Operador suma ${a} + ${b} = ${suma}`);\n//* resta\nlet resta = a - b;\nconsole.log(`Operador resta ${a} - ${b} = ${resta}`);\n//* multiplicacion\nlet multiplicacion = a * b;\nconsole.log(`Operador multiplicacion ${a} * ${b} = ${multiplicacion}`);\n//* division\nlet division = a / b;\nconsole.log(`Operador division ${a} / ${b} = ${division}`);\n//* modulo\nlet modulo = a % b;\nconsole.log(`Operador modulo ${a} % ${b} = ${modulo}`);\n//* exponente\nlet exponente = a ** b;\nconsole.log(`Operador exponente ${a} ^ ${b} = ${exponente}`);\n//* incremento\nlet incremento = a;\nconsole.log(`Operador incremento ${a} = ${++incremento}`);\n//* decremento\nlet decremento = a;\nconsole.log(`Operacion decremento ${a} = ${--decremento}`);\n//! Operadores de asignacion : ASIGNAN VALORES A LAS VARIABLES\nconsole.log(`Operadores de asignacion:`);\n//* asignacion\nlet c = 10;\nconsole.log(`Asignacion ( = ) ${c}`);\n//* asignacion de adicion\nc += 3;\nconsole.log(`Asignacion de adicion ( += ) ${c}`);\n//* asignacion de resta\nlet d = 20;\nd -= 5;\nconsole.log(`Asignacion de resta ( -= ) ${d}`);\n//* asignacion de multiplicacion\nd *= 2;\nconsole.log(`Asignacion de multiplicacion ( *= ) ${d}`);\n//* asignacion de division\nd /= 2;\nconsole.log(`Asignacion de division ( /= ) ${d}`);\n//* asignacion de modulo\nd %= 2;\nconsole.log(`Asignacion de modulo ( %= ) ${d}`);\n//* asignacion de explonente\nlet e = 5;\ne **= 2;\nconsole.log(`Asignacion de exponente ( **= ) ${e}`);\n//! Operadores de comparacion: COMPARAN DOS VALORES Y DEVUELVEN UN VALOR BOOLEANO\nconsole.log(`Operadores de comparacion:`);\n//* igual\nlet x = 5;\nlet y = 5;\nlet z = 10;\nconsole.log(`Igual ( == ) ${x} == ${y} = ${x == y}`);\n//* no igual\nconsole.log(`No igual ( != ) ${x} != ${z} = ${x != z}`);\n//* estrictamente igual\nconsole.log(`Estrictamente igual ( === ) ${x} === '5' = ${x === \"5\"}`);\n//* estrictamente no igual\nconsole.log(`Estrictamente no igual ( !== ) ${x} !== '5' = ${x !== \"5\"}`);\n//! Operadores de relacion: COMPARAN DOS VALORES Y DEVUELVEN UN VALOR BOOLEANO\nconsole.log(`Operadores de relacion:`);\n//* mayor que\nconsole.log(`Mayor que ( > ) ${x} > ${z} = ${x > z}`);\n//* mayor o igual que\nconsole.log(`Mayor o igual que ( >= ) ${x} >= ${z} = ${x >= z}`);\n//* menor que\nconsole.log(`Menor que ( < ) ${x} < ${z} = ${x < z}`);\n//* menor o igual que\nconsole.log(`Menor o igual que ( <= ) ${x} <= ${z} = ${x <= z}`);\n//! Operadores logicos\nconsole.log(`Operadores logicos:`);\n//* AND\nconsole.log(`Operador AND ${true} && ${false} = ${true && false}`);\n//* OR\nconsole.log(`Operador OR ${true} || ${false} = ${true || false}`);\n//* NOT\nconsole.log(`Operador NOT !${true} = ${!true}`);\n//! Otros operadores\nconsole.log(`Otros operadores:`);\n//* Operador Condicional (ternario) (`? :`) Asigna un valor basado en una condicion\nconsole.log(\n  `Operador Condicional (ternario): a=${a} > b=${b} ${\n    a > b ? \"a es mayor que b\" : \"a no es mayor que b\"\n  }`\n);\n//* Operador tipo: devuelve el tipo de dato de una variable\nconsole.log(`Operador tipo: typeof ${a} = ${typeof a}`);\n//* Operador de eliminacion: elimina una propiedad de un objeto\nlet obj = { name: \"Miguel\", age: 25 };\nconsole.log(obj);\nconsole.log(`Operador de eliminacion: delete ${obj.name} = ${delete obj.name}`);\nconsole.log(obj);\n\n//! DIFICULTAD EXTRA (opcional): Crea un programa que imprima por consola todos los números comprendidos entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3\n\nfor (let i = 10; i <= 55; i++) {\n  if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n    console.log(i);\n  }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/DannyMarperOne.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n\n\n/* OPERADORES */\n\n// Operadores de asignación\nlet x = 3; //Asignación\nx += 2; //Suma y asignación\nconsole.log(x);\nx *= 2; //Multiplicación y asignación\nconsole.log(x);\nx -= 2; //Resta y asignación\nconsole.log(x);\nx /= 2; //División y asignación\nconsole.log(x);\nx %= 2; //Residuo y asignación\nconsole.log(x);\nx **= 2; //Exponenciación y asignación\nconsole.log(x);\n\n// Operadores de comparación\n\nlet var1 = 3,\n    var2 = 4;\n\n// Los siguientes ejemplos siempre retornarn true\n3 == var1; //Igual\n\"3\" == var1; //Igual\n3 == '3'; //Igual\nvar1 != 4; //No es igual\nvar2 != '3'; //No es igual\n3 === var1; //Estrictamente igual\nvar1 !== \"3\"; //Estrictamente desigual\n3 !== '3'; //Estrictamente desigual\nvar2 > var1; //Mayor que\n\"12\" > 2; //Mayor que\nvar2 >= var1; //Mayor o igual que\nvar1 >= 1; //Mayor o igual que \nvar1 < var2; //Menor que\n\"2\" < 12; //Menor que\nvar1 <= var2; //Menor o igual que\nvar2 <= \"5\"; //Menor o igual que\n\n\n// Operadores aritmeticos\n\n12 % 5; //Residuo\n++3; //Incremento prefijo\n3++; //Incremento sufijo\n--3; //Decremento prefijo\n3--; //Decremento sufijo\n-\n3; //Negación unaria\n+\n4; //Positivo unario (Intenta convertir al operando en un número si aún no lo es)\n2 ** 3; //Operador de exponenciación\n\n\n// Operadores Bit\n\na & b; //AND a nivel bits\na | b; //OR a nivel bits\na ^ b; //XOR a nivel bits\n~a //NOT a nivel bits\n\n\n//Operadores Logicos\n\n// AND\nvar a1 = true && true; // t && t devuelve true\nvar a2 = true && false; // t && f devuelve false\nvar a3 = false && true; // f && t devuelve false\nvar a4 = false && 3 == 4; // f && f devuelve false\nvar a5 = \"Cat\" && \"Dog\"; // t && t devuelve Dog\nvar a6 = false && \"Cat\"; // f && t devuelve false\nvar a7 = \"Cat\" && false; // t && f devuelve false\n\n// OR\nvar o1 = true || true; // t || t devuelve true\nvar o2 = false || true; // f || t devuelve true\nvar o3 = true || false; // t || f devuelve true\nvar o4 = false || 3 == 4; // f || f devuelve false\nvar o5 = \"Cat\" || \"Dog\"; // t || t devuelve Cat\nvar o6 = false || \"Cat\"; // f || t devuelve Cat\nvar o7 = \"Cat\" || false; // t || f devuelve Cat\n\n// NOT\nvar n1 = !true; // !t devuelve false\nvar n2 = !false; // !f devuelve true\nvar n3 = !\"Cat\"; // !t devuelve false\n\n// Operadores de cadena\n\nconsole.log(\"Hola\" + \"Javascript\"); //Devuelve la concatenación de la cadena \"Hola Javascript\"\n\n// Operador condicional (Ternario)\nlet status = edad >= 18 ? \"adulto\" : \"joven\"; //Devuelve el valor de la condición\n\n//Operador coma\nfor (var i = 0, j = 9; i <= j; i++, j--); //Permite que se evaluen múltiples variable a la vez\n\n\n\n\n\n/* ESTRUCTURAS DE CONTROL */\n\n// IF - ELSE\nconst mayorEdad = 18;\nif (mayorEdad >= 18) {\n    console.log(`La persona tiene ${mayorEdad} años y puede conducir beber alcohol`);\n} else {\n    console.log(`Esta persona aún tiene ${mayorEdad} años y no tiene permitido beber alcohol`);\n}\n\n// Operador ternario\nlet hi = \"Hola a todos\";\nlet hola = hi === \"Hola a todos\" ? console.log(\"Saludo de bienvenida\") : console.log(\"Cualquier otra cosa\");\n\nlet domir = true ? console.log(\"A mimir\") : console.log(\"Aún es temprano\");\n\n// Switch\nnumber = 10;\nswitch (number) {\n    case 25:\n        console.log(\"FIRST CASE\");\n        break;\n    case 11:\n        console.log(\"SECOND CASE\");\n        break;\n    default:\n        console.log(\"NONE\");\n        break;\n}\n\n// While\nlet i = 0;\nwhile (i < 20) {\n    if (i % 2 == 0) {\n        console.log(i)\n    }\n    i++\n}\n\n// Do-While\nlet o = 40;\ndo {\n    console.log(\"Hola Javascript\");\n    o++\n} while (o <= 45);\n\n\n// For\nfor (i = 1; i < 10; i++) {\n    console.log(`El valor de i es ${i}`)\n}\n\n// Try - Catch\ntry {\n    console.log('Inicio de ejecuciones try'); // (1) <--\n    lalala; // error, variable no está definida!\n    console.log('Fin de try (nunca alcanzado)'); // (2)\n} catch (err) {\n    console.log(`¡Un error ha ocurrido!`); // (3) <--\n}\n\n\n// Ejercicio extra\n/* \nCrea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n*/\n\nlet i = 10;\nfor (i; i <= 55; i++) {\n    if (i % 2 === 0 && i % 3 !== 0 && i !== 16) {\n        console.log(`${i}`);\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/DavidMoralesDeveloper.js",
    "content": "/*\n * EJERCICIO:\n * 1- Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n\n//1 Operadores \nconst a = 1\n const b = 2\n const c = 3\n//Aritméticos \n// suma+, resta-, multiplicasion*, division/, modulo(resto)%\n// exponenciación **, incremento ++, decremento  --\n\n const suma = a + b\n const resta = a - b\n const multiplicasion = a * b\n const division = a / b\n const modulo = a % b\n const exponecia = a ** b \n\n//  lógicos\n// || or si una es true , &&  si las dos son true !true diferente de \n\nconsole.log(a || b)\nconsole.log(a && b)\nconsole.log(!true);\n\n//asignación\n// = asignacion de un valor, +=sumar , -= para restar el operando derecho  *= , /=, %=\nlet x = 10;\nx += 5; // x = 15\nx -= 2; // x = 13\nx *= 3; // x = 39\nx /= 2; // x = 19.5\nx %= 4; // x = 3.5\n\n\n//De comparación:\nconsole.log(2 === 2); // Igualdad estricta: true\nconsole.log(2 == 2); // Igualdad no estricta: true\nconsole.log(2 > 1); // Mayor que: true\nconsole.log(2 >= 2); // Mayor o igual que: true\nconsole.log(1 < 2); // Menor que: true\nconsole.log(1 <= 2); // Menor o igual que: true\n\n//Identidad:\nconst d = 10;\nconst e = 10;\nconsole.log(d === e); // true (mismo valor y tipo)\nconst f = \"10\";\nconsole.log(d === f); // false (mismo valor, diferente tipo) \n\n\n//Pertenencia:\nconst lista = [\"a\", \"b\", \"c\"];\nconsole.log(\"a\" in lista); // true\nconsole.log(\"d\" in lista); // false\n\n//Bits\nconsole.log(1 | 2); // OR a nivel de bits: 3\nconsole.log(1 & 2); // AND a nivel de bits: 0\nconsole.log(1 ^ 2); // XOR a nivel de bits: 3\nconsole.log(~1); // NOT a nivel de bits: -2\n\n\n//Estructuras de Control\n//OPERADOR TERNARIO\n//expresión ? \"si es true\" : \"si es false\";\nlet edad = 16;\nlet acceso = edad > 17 ? \"Permitir acceso\" : \"Denegar acceso\";\nconsole.log(acceso);\n\n//Condicional\nconst g = 19\nif(g > 18 ) {\n    console.log('Es mayor de edad') \n}else{console.log('es menor de edad') }\n\n//Iterativas:\n// Bucle for\nfor (let i = 0; i = 100; i++){\n  console.log(i + 'bucle for')\n}\n  // Bucle while\n\n  let i = 0;\nlet j = 0;\nwhile (n < 3) {\n  i++;\n  j += i;\n}\n\n    // Bucle do-while\n      // let j = 0; do{i+1; console.log(i)}; wile{i <5}\n    let z = 3;\n\n// do...while loop\ndo {\n    console.log(z);\n    z--;\n} while (z > 0);\n\n    //for of for in\n    const arr = [3, 5, 7];\narr.foo = \"hola\";\n\nfor (let i in arr) {\n  console.log(i); // logs \"0\", \"1\", \"2\", \"foo\"\n}\n\nfor (let i of arr) {\n  console.log(i); // logs 3, 5, 7\n}\n\n\n// * DIFICULTAD EXTRA (opcional):\n// * Crea un programa que imprima por consola todos los números comprendidos\n// * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\nfor (let i = 10; i < 55; i++){\n  if(i%2 === 0 && i !=16 && i % 3 != 0)\n  console.log(i)\n}\n\n// 10, 14, 20, 22, 26, 28, 32, 34, 38, 40, 44, 46, 50, 52\n//i%2 === 0 = 10 12 14 16 18 20\n//i !=16 = 12 14 18 20\n//modulo de tres es distinto a 0 4 / 3 = 0.12  (!=)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/DaxterDEV.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\nlet asignación = 5; // Asignación\nlet suma = 5 + 3; // Aritmético\nlet resta = 10 - 2; // Aritmético\nlet multiplicacion = 4 * 2; // Aritmético\nlet division = 8 / 4; // Aritmético\nlet modulo = 10 % 3; // Aritmético, resto de la división\nlet mayorQue = 5 > 3; // Comparación\nlet menorQue = 2 < 4; // Comparación\nlet igualQue = 5 == 5; // Comparación\nlet identidad = 5 === 5; // Identidad\nlet noIgualQue = 5 != 3; // Comparación\nlet pertenencia = [1, 2, 3].includes(2); // Pertenencia\nlet bits = 5 & 3; // Operador bit a bit AND\n\nconsole.log(\"Asignación:\", asignación);\nconsole.log(\"Suma:\", suma);\nconsole.log(\"Resta:\", resta);\nconsole.log(\"Multiplicación:\", multiplicacion);\nconsole.log(\"División:\", division);\nconsole.log(\"Módulo:\", modulo);\nconsole.log(\"Mayor que:\", mayorQue);\nconsole.log(\"Menor que:\", menorQue);\nconsole.log(\"Igual que:\", igualQue);\nconsole.log(\"Identidad:\", identidad);\nconsole.log(\"No igual que:\", noIgualQue);\n\n//Operadores Lógicos\nlet yLogico = true && false; // Lógico\nlet oLogico = true || false; // Lógico\nlet noLogico = !true; // Lógico\n\nconsole.log(\"Y lógico:\", yLogico);\nconsole.log(\"O lógico:\", oLogico);\nconsole.log(\"No lógico:\", noLogico);\n\n// Estructuras de control\n// Condicional\nif (mayorQue) {\n  console.log(\"5 es mayor que 3\");\n}\n// Condicional con else\nif (menorQue) {\n  console.log(\"2 es menor que 4\");\n} else {\n  console.log(\"2 no es menor que 4\");\n}\n// Condicional con else if\nif (igualQue) {\n  console.log(\"5 es igual a 5\");\n} else if (noIgualQue) {\n  console.log(\"5 no es igual a 3\");\n}\n// Iterativa for\nfor (let i = 0; i < 5; i++) {\n  console.log(\"Iteración:\", i);\n}\n// Iterativa while\nlet j = 0;\nwhile (j < 5) {\n  console.log(\"Iteración while:\", j);\n  j++;\n}\n// Excepción\ntry {\n  let errorPrueba = 5 / 0; // Esto no generará un error, pero es un ejemplo de manejo de excepciones\n} catch (error) {\n  console.error(\"Error:\", error);\n}\n// DIFICULTAD EXTRA\nconsole.log(\n  \"Números comprendidos entre 10 y 55, pares, no son 16 ni múltiplos de 3:\"\n);\nfor (let num = 10; num <= 55; num++) {\n  if (num % 2 === 0 && num !== 16 && num % 3 !== 0) {\n    console.log(num);\n  }\n}\n// Fin del ejercicio\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/DerlingR.js",
    "content": "//Operadores\n\n/*\nOperadores aritméticos\n*/\n\n//Suma\nlet n1 = 10;\nlet n2 = 15;\nlet suma = n1 + n2;\nconsole.log(\"La suma de\", n1, \"y\", n2, \"es:\", suma);\n\n//Resta\nlet n3 = 10;\nlet n4 = 15;\nlet resta = n3 - n4;\nconsole.log(\"La resta de\", n3, \"y\", n4, \"es\", resta);\n\n//Multiplicación\nlet n5 = 10;\nlet n6 = 15;\nlet multiplicacion = n5 * n6;\nconsole.log(\"La multiplicación de\", n5, \"y\", n6, \"es\", multiplicacion);\n\n//División\nlet n7 = 10;\nlet n8 = 15;\nlet division = n7 / n8;\nconsole.log(\"La división de\", n5, \"y\", n6, \"es\", division);\n\n//Módulo\nlet n9 = 10;\nlet n10 = 15;\nlet modulo = n9 % n10;\nconsole.log(\"El módulo de\", n9, \"y\", n10, \"es\", modulo);\n\n//Exponente\nlet n11 = 10;\nlet n12 = 15;\nlet exponente = n11 ** n12;\nconsole.log(\"El exponente de\", n11, \"y\", n12, \"es\", exponente);\n\n//Incremento\nlet n13 = 10;\nlet incremento = ++n13;\nconsole.log(\"El incremento de\", n13, \"es\", incremento);\n\n//Decremento\nlet n15 = 10;\nlet decremento = --n15;\nconsole.log(\"El decremento de\", n15, \"es\", decremento);\n\n\n\n/*\nOperadores de asignación\n*/\n\nlet numero = 10;\nconsole.log(\"Valor inicial:\", numero);\n\n//Asignación con suma\nnumero += 5;\nconsole.log(\"Después de += 5:\", numero); //15\n\n//Asignación con resta\nnumero -= 3;\nconsole.log(\"Después de -= 3:\", numero); //12\n\n//Asignación con multiplicación\nnumero *= 2;\nconsole.log(\"Después de *= 2:\", numero); //24\n\n//Asignación con división\nnumero /= 4;\nconsole.log(\"Después de /= 4:\", numero); //6\n\n//Asignación con módulo\nnumero %= 4;\nconsole.log(\"Después de %= 4:\", numero); //2\n\n//Asignación con exponente\nnumero **= 3;\nconsole.log(\"Después de **=3:\", numero); //8\n\nlet a= 10;\nlet b = 5;\nlet c= \"10\";\n\nconsole.log(\"a =\", a, \", b =\", b, \", c=\", c);\n\n//Igualdad (==) Compara valores sin importar el tipo\nconsole.log(\"a == c:\", a== c); //true\n\n//Estrictamente igual (===) -> Compara valores y tipos de datos\nconsole.log(\"a === c:\", a === c); //false\n\n//Desigualdad (!=) -> Compara valores sin importar el tipo\nconsole.log(\"a != b:\", b); //true\n\n//Estrictamente desigual (!==) -> Compara valores y tipos de datos\nconsole.log(\"a !== c:\", a !== c); //true\n\n//Mayor que (>) -> Compara si el valor de la izquierda es mayor que el de la derecha\nconsole.log(\"a > b:\", a > b); //true\n\n//Menor que (<) -> Compara si el valor de la izquierda es menor que el de la derecha\nconsole.log(\"a < b:\", a < b); //false\n\n//Mayor o igual que (>=) -> Compara si el valor de la izquierda es mayor o igual que el de la derecha\nconsole.log(\"a >= 10:\", a >= 10); //true\n\n//Menor o igual que (<=) -> Compara si el valor de la izquierda es menor o igual que el de la derecha\nconsole.log(\"b <= 5:\",  b <= 5); //false\n\n\n/* Operadores lógicos*/\n\nlet a1 = true;\nlet b1 = false;\n\nconsole.log(\"a1 =\", a,  \", b1 =\", b1);\n\n//AND lógico (&&) -> Devuelve true si ambos operandos son verdaderos\nconsole.log(\"a && b:\", a && b); //false\n\n//OR lógico (||) -> Devuelve true si al menos uno de los operandos es verdadero\nconsole.log(\"a || b:\", a || b); //true\n\n//OR lógico (!) Inverte el valor booleano\nconsole.log(\"!a:\", !a); //false\nconsole.log(\"!b:\", !b); //true\n\n/*\n&& devuelve true solo si ambas condiciones son true.\n\n|| devuelve true si al menos una condición es true.\n\n! invierte el valor (true se vuelve false y viceversa).\n*/\n\n/* Opereradores bit a bit */\nlet x = 5;  //  0101 en binario\nlet y = 3;  //  0011 en binario\n\nconsole.log(\"x =\", x, \", y =\", y);\n\n// AND bit a bit (&) -> Compara bit a bit y devuelve 1 solo si ambos bits son 1\nconsole.log(\"x & y:\", x & y);  // 1 (0001 en binario)\n\n// OR bit a bit (|) -> Devuelve 1 si al menos un bit es 1\nconsole.log(\"x | y:\", x | y);  // 7 (0111 en binario)\n\n// XOR bit a bit (^) -> Devuelve 1 si los bits son diferentes\nconsole.log(\"x ^ y:\", x ^ y);  // 6 (0110 en binario)\n\n// Desplazamiento a la izquierda (<<) -> Mueve los bits a la izquierda y multiplica por 2\nconsole.log(\"x << 1:\", x << 1);  // 10 (1010 en binario)\n\n// Desplazamiento a la derecha (>>) -> Mueve los bits a la derecha y divide por 2\nconsole.log(\"x >> 1:\", x >> 1);  // 2 (0010 en binario)\n\nlet valor = 10;\n\n//Uso de if, else if y else\n\nif ( valor > 10) {\n    console.log(\"El número es mayor que 10.\");\n\n} else if (valor === 10) {\n    console.log(\"El número es igual a 10.\");\n\n} else {\n    console.log(\"El número es menor que 10.\");\n}\n\n//Usando Switch\n\nlet operacion = \"+\";\nswitch (operacion) {\n    case \"+\":\n        console.log(\"Has elegido suma.\");\n        break;\n    case \"-\":\n        console.log(\"Has elegido resta.\");\n        break;\n    default:\n        console.log(\"Operación no válida.\");\n        break;\n}\n\n\n// For: Imprimir los primeros 5 múltiplos de 3\n\nfor (let i = 1; i <= 5; i++) {\n    console.log('3 x $ {i} = $ (3 * i}');\n}\n\n// While: Contar hacia atrás desde 5\nlet contador = 5;\nwhile (contador > 0) {\n    console.log(\"Contador:\", contador);\n    contador--;\n}\n\n// Do-While: Se ejecuta al menos una vez\n\nlet n = 0;\ndo {\n    console.log(\"Valor de n:\", n);\n    n++;\n} while (n < 5);\n\n// ForEach: Itera sobre los elementos de un array\n\nlet numeros = [2, 4, 6, 8];\nnumeros.forEach(num => console.log(\"Número:\", num));\n\n// Map: Crea un nuevo array con los números duplicados\n\nlet duplicados = numeros.map(num => num * 2);\nconsole.log(\"Duplicados:\", duplicados);\n\n\nfunction dividir(a, b) {\n    try {\n        if (b === 0) throw \"No se puede dividir entre 0\";\n        console.log('Resultado: ${a / b}');\n    } catch (error) {\n        console.log(\"Error:\", error);\n    } finally {\n        console.log(\"Operación finalizada.\");\n    }\n\n}\n\ndividir(10, 2); //Correcto\ndividir (10, 0); //Error\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/Deyvid-10.js",
    "content": "// Todos los tipos de operadores de JavaScript\n\n// Aritméticos\nconsole.log(\"Suma: \", 2 + 2);\nconsole.log(\"Resta: \", 3 - 1);\nconsole.log(\"Multiplicación: \", 6 * 6);\nconsole.log(\"División: \", 4 / 2);\nconsole.log(\"Módulo: \", 6 % 3);\n\n// De comparación\nconsole.log(\"Igualdad: \", 5 == '5');\nconsole.log(\"Desigualdad: \", 2 != 8);\nconsole.log(\"Mayor que: \", 5 > 4);\nconsole.log(\"Menor que: \", 2 < 6);\nconsole.log(\"Menor o igual: \", 2 <= 4);\nconsole.log(\"Mayor o igual: \", 3 >= 2);\n\n// De asignación\nlet asignacion = 2\nconsole.log(\"Asignación: \", asignacion);\nconsole.log(\"Asignación con suma: \", asignacion += 1);\nconsole.log(\"Asignación con resta: \", asignacion -=1);\nconsole.log(\"Asignación con multiplicación: \", asignacion *= 2);\nconsole.log(\"Asignación con división: \", asignacion /= 2);\nconsole.log(\"Asignación con módulo: \", asignacion %= 2);\nconsole.log(\"Asignación con exponente: \", asignacion **= 2);\n\n// De identidad\nconsole.log(\"Es idéntico: \", 5 === 5);\nconsole.log(\"No es idéntico: \", 5 !== '5');\n\n// De pertenencia\nconsole.log(\"Pertenencia: \", 2 in [2,3,4,5,6]);\nconsole.log(\"No pertenencia: \", !(7 in [2,3,4,5,6]));\n\n// De bits\nconsole.log(\"AND bit a bit: \", 5 & 5);\nconsole.log(\"OR bit a bit: \", 4 | 4);\nconsole.log(\"XOR bit a bit: \", 6 ^ 6);\nconsole.log(\"NOT bit a bit: \", ~2);\nconsole.log(\"Desplazamiento a la izquierda: \", 10 << 7);\nconsole.log(\"Desplazamiento a la derecha: \", -7 >> 7);\nconsole.log(\"Desplazamiento a la derecha sin signo: \", -9 >>> 9);\n\n// Estructuras de control con operadores lógicos\n\n// Condicional if else\nlet condicion = 1\nlet condicion2 = 2\n\nif(condicion == 1 && condicion2 == 2)\n{\n\n    console.log(true);\n}\nelse\n{\n\n    console.log(false);\n}\n\n// Condicional switch case\nlet animal = \"Perro\"\nswitch (animal) {\n    case \"Gato\": \n        console.log(\"Es un gato\");\n        break;\n\n    case \"Perro\": \n        console.log(\"Es un perro\");\n        break;\n\n    default:\n        console.log(\"No es un animal\");\n        break;\n}\n\n// Iterativas \n// Loop for\nfor(let i = 0; i<= 5; i++)\n{\n\n   console.log(i); \n}\n\n// Iterar en un array\nlet array = [0,1,2,3,4,5]\nfor(a of array)\n{\n\n    console.log(a); \n}\n\n// Iterar en un objeto\nlet objeto = {nombre: 'Juan', edad: 30, ciudad: 'Madrid'}\n\nfor(o in objeto)\n{\n\n    console.log(`${o}: ${objeto[o]}`); \n}\n\n// Loop while\nlet condicion3 = 1\nlet condicion4 = 15\n\nwhile(condicion3 < 5|| condicion4 > 10 )\n{\n\n    console.log(condicion3);\n    console.log(condicion4);\n    condicion3++\n    condicion4--\n}\n\n// Loop do while\nlet condicion5 = false\nlet contador = 0\n\ndo{\n\n    console.log(contador);\n\n    if(contador >= 5)\n    {\n\n        condicion5 = true\n    }\n\n    contador++\n} while(!condicion5)\n\n// Excepciones \ntry{\n\n    let x\n    x = 5 + 5\n    console.log(x);\n} catch(error){\n\n    console.error(\"Se produjo un error: \", error);\n} finally{\n\n    console.log(\"Este mensaje se muestra alla error o no\");\n}\n\n\n// DIFICULTAD EXTRA\nfor(let i=10; i<=55; i++)\n{\n\n    if(i%2 == 0 && i!=16 && i%3 !=0)\n    {\n\n        console.log(i);\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/DjSurgeon.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n/* == Operadores de asignación == */\n\n/* Un operador de asignación asigna un valor a su operando izquierdo basándose \nen el valor de su operando derecho. El operador de asignación simple es igual (=), \nque asigna el valor de su operando derecho a su operando izquierdo. */\n\nconsole.log(`=== Operadores de asignación ===`);\nlet x = 1;\nlet y = 1;\n/* Asignación */\nx = y;\nx = y;\nlet asignacion = \"Hola Mundo!\";\nlet nuevaAsignacion = asignacion;\nconsole.log(`Operador de asignacion: ${nuevaAsignacion}`);\nlet operando1 = 5;\nlet operando2 = 2;\nconsole.log(`Operandos: ${operando1} y ${operando2}`);\n\n/* Asignación de adición */\nx += y;\nx = x + y;\nconsole.log(`=> Suma: ${(operando1 += operando2)}`);\nconsole.log(`Operandos: ${operando1} y ${operando2}`);\n\n/* Asignación de resta */\nx -= y;\nx = x - y;\nconsole.log(`=> Resta: ${(operando1 -= operando2)}`);\nconsole.log(`Operandos: ${operando1} y ${operando2}`);\n\n/* Asignación de multiplicación */\nx *= y;\nx = x * y;\nconsole.log(`=> Multiplicación: ${(operando1 *= operando2)}`);\nconsole.log(`Operandos: ${operando1} y ${operando2}`);\n\n/* Asignación de división */\nx /= y;\nx = x / y;\nconsole.log(`=> Division: ${(operando1 /= operando2)}`);\nconsole.log(`Operandos: ${operando1} y ${operando2}`);\n\n/* Asignación de residuo */\nx %= y;\nx = x % y;\nconsole.log(`=> Resto: ${(operando1 %= operando2)}`);\nconsole.log(`Operandos: ${operando1} y ${operando2}`);\n\n/* Asignación de exponenciación */\nx **= y;\nx = x ** y;\nconsole.log(`=> Exponenciación: ${(operando1 **= operando2)}`);\nconsole.log(`Operandos: ${operando1} y ${operando2}`);\n\n/* Asignación de desplazamiento a la izquierda */\n/* El operador << devuelve un número o BigInt cuya representación binaria \nes el primer operando desplazado el número especificado de bits hacia la izquierda. \nLos bits sobrantes desplazados hacia la izquierda se descartan \ny los bits cero se desplazan hacia la derecha. */\nx <<= y;\nx = x << y;\nconsole.log(`=> Desplazamiento a la izquierda: ${(operando1 <<= operando2)}`);\nconsole.log(`Operandos: ${operando1} y ${operando2}`);\n\n/* Asignación de desplazamiento a la derecha */\nx >>= y;\nx = x >> y;\nconsole.log(`=> Desplazamiento a la derecha: ${(operando1 >>= operando2)}`);\nconsole.log(`Operandos: ${operando1} y ${operando2}`);\n\n/* Asignación de desplazamiento a la derecha sin signo */\nx >>>= y;\nx = x >>> y;\nconsole.log(\n  `=> Desplazamiento a la derecha sin signo: ${(operando1 >>>= operando2)}`\n);\nconsole.log(`Operandos: ${operando1} y ${operando2}`);\n\n/* Asignación AND bit a bit */\n/* El operador &= realiza AND en los dos operandos \ny asigna el resultado al operando izquierdo. */\nx &= y;\nx = x & y;\nconsole.log(`=> AND bit a bit: ${(operando1 &= operando2)}`);\nconsole.log(`Operandos: ${operando1} y ${operando2}`);\n\n/* Asignación XOR bit a bit */\n/* El operador ^= realiza XOR en los dos operandos \ny asigna el resultado al operando izquierdo.*/\nx ^= y;\nx = x ^ y;\nconsole.log(`=> XOR bit a bit: ${(operando1 ^= operando2)}`);\nconsole.log(`Operandos: ${operando1} y ${operando2}`);\n\n/* Asignación OR bit a bit */\nx |= y;\nx = x | y;\nconsole.log(`=> OR bit a bit: ${(operando1 |= operando2)}`);\nconsole.log(`Operandos: ${operando1} y ${operando2}`);\n\n/* Asignación AND lógico */\n/* El operador &&= solo evalúa el operando derecho y \nlo asigna al izquierdo si el operando izquierdo es truthy. */\nx &&= y;\nx = x && y;\nconsole.log(`=> AND lógico: ${(operando1 &&= operando2)}`);\nconsole.log(`Operandos: ${operando1} y ${operando2}`);\n\n/* Asignación OR lógico */\n/* El operador ||= solo evalúa el operando derecho y \nlo asigna al izquierdo si el operando izquierdo es falsy. */\nx ||= y;\nx = x || y;\nconsole.log(`=> OR lógico: ${(operando1 ||= operando2)}`);\nconsole.log(`Operandos: ${operando1} y ${operando2}`);\n\n/* Asignación de anulación lógica */\n/* El operador de asignación de anulación lógica (??=), \ntambién conocido como operador de asignación nula lógica, \nsolo evalúa el operando derecho y asigna al izquierdo \nsi el operando izquierdo es nulo o indefinido. */\nx ??= y;\nx = x ?? y;\nconsole.log(`=> Anulación lógica: ${(operando1 ??= operando2)}`);\n\n/* == Operadores de comparación == */\n\n/* Un operador de comparación compara sus operandos y \ndevuelve un valor lógico en función de si la comparación \nes verdadera (true) o falsa (false). \nLos operandos pueden ser valores numéricos, de cadena, lógicos u objetos. \nLas cadenas se comparan según el orden lexicográfico estándar, \nutilizando valores Unicode. En la mayoría de los casos, \nsi los dos operandos no son del mismo tipo, JavaScript \nintenta convertirlos a un tipo apropiado para la comparación. \nEste comportamiento generalmente resulta en comparar los operandos numéricamente. \nLas únicas excepciones a la conversión de tipos dentro de las comparaciones \ninvolucran a los operadores === y !==, que realizan comparaciones estrictas \nde igualdad y desigualdad. Estos operadores no intentan convertir los operandos \na tipos compatibles antes de verificar la igualdad. */\n\nconsole.log(`=== Operadores de comparación ===`);\noperando1 = 8;\nlet texto1 = \"tipo num.\";\noperando2 = 5;\nlet operando3 = \"5\";\nlet texto2 = \"tipo string.\";\nconsole.log(\n  `Operandos: ${operando1} y ${operando2} como números y ${operando3} como cadena de texto.`\n);\n\n/* Igual */\nconsole.log(`${operando1} ${texto1} es igual a ${operando2} ${texto1}`);\nconsole.log(operando1 == operando2);\nconsole.log(`${operando1} ${texto1} es igual a ${operando1} ${texto1}`);\nconsole.log(operando1 == operando1);\nconsole.log(`${operando2} ${texto1} es igual a ${operando3} ${texto2}`);\nconsole.log(operando2 == operando3);\n\n/* No es igual */\nconsole.log(`${operando1} ${texto1} no es igual a ${operando2} ${texto1}`);\nconsole.log(operando1 != operando2);\nconsole.log(`${operando1} ${texto1} no es igual a ${operando1} ${texto1}`);\nconsole.log(operando1 != operando1);\nconsole.log(`${operando2} ${texto1} no es igual a ${operando3} ${texto2}`);\nconsole.log(operando2 != operando3);\n\n/* Estrictamente igual */\nconsole.log(\n  `${operando1} ${texto1} es estrictamente igual a ${operando2} ${texto1}`\n);\nconsole.log(operando1 === operando2);\nconsole.log(\n  `${operando1} ${texto1} es estrictamente igual a ${operando1} ${texto1}`\n);\nconsole.log(operando1 === operando1);\nconsole.log(\n  `${operando2} ${texto1} es estrictamente igual a ${operando3} ${texto2}`\n);\nconsole.log(operando2 === operando3);\n\n/* Desigualdad estricta */\nconsole.log(\n  `${operando1} ${texto1} no es estrictamente igual a ${operando2} ${texto1}`\n);\nconsole.log(operando1 !== operando2);\nconsole.log(\n  `${operando1} ${texto1} no es estrictamente igual a ${operando1} ${texto1}`\n);\nconsole.log(operando1 !== operando1);\nconsole.log(\n  `${operando2} ${texto1} no es estrictamente igual a ${operando3} ${texto2}`\n);\nconsole.log(operando2 !== operando3);\n\n/* Mayor que */\nconsole.log(`${operando1} ${texto1} es mayor que ${operando2} ${texto1}`);\nconsole.log(operando1 > operando2);\nconsole.log(`${operando1} ${texto1} es mayor que ${operando1} ${texto1}`);\nconsole.log(operando1 > operando1);\nconsole.log(`${operando1} ${texto1} es mayor que ${operando3} ${texto2}`);\nconsole.log(operando1 > operando3);\n\n/* Mayor o igual que */\nconsole.log(\n  `${operando1} ${texto1} es mayor o igual que ${operando2} ${texto1}`\n);\nconsole.log(operando1 >= operando2);\nconsole.log(\n  `${operando1} ${texto1} es mayor o igual que ${operando1} ${texto1}`\n);\nconsole.log(operando1 >= operando1);\nconsole.log(\n  `${operando1} ${texto1} es mayor o igual que ${operando3} ${texto2}`\n);\nconsole.log(operando1 >= operando3);\n\n/* Menor que */\nconsole.log(`${operando1} ${texto1} es menor que ${operando2} ${texto1}`);\nconsole.log(operando1 < operando2);\nconsole.log(`${operando1} ${texto1} es menor que ${operando1} ${texto1}`);\nconsole.log(operando1 < operando1);\nconsole.log(`${operando1} ${texto1} es menor que ${operando3} ${texto2}`);\nconsole.log(operando1 < operando3);\n\n/* Menor o igual */\nconsole.log(\n  `${operando1} ${texto1} es menor o igual que ${operando2} ${texto1}`\n);\nconsole.log(operando1 <= operando2);\nconsole.log(\n  `${operando1} ${texto1} es menor o igual que ${operando1} ${texto1}`\n);\nconsole.log(operando1 <= operando1);\nconsole.log(\n  `${operando1} ${texto1} es menor o igual que ${operando3} ${texto2}`\n);\nconsole.log(operando1 <= operando3);\n\n/* == Operadores de aritméticos == */\n/* Un operador aritmético toma valores numéricos (ya sean literales o variables) \ncomo sus operandos y devuelve un solo valor numérico. \nLos operadores aritméticos estándar son suma (+), resta (-), multiplicación (*) y división (/). \nEstos operadores funcionan como lo hacen en la mayoría de los otros lenguajes de programación \ncuando se usan con números de punto flotante. */\nconsole.log(`=== Operadores de comparación ===`);\noperando1 = 10;\noperando2 = 3;\nconsole.log(`Operandos: ${operando1} y ${operando2}`);\n/* Suma */\nconsole.log(`=> Suma: ${operando1 + operando2}`);\nconsole.log(`Operandos: ${operando1} y ${operando2}`);\n\n/* Resta */\nconsole.log(`=> Resta: ${operando1 - operando2}`);\nconsole.log(`Operandos: ${operando1} y ${operando2}`);\n\n/* Multiplicación */\nconsole.log(`=> Multiplicación: ${operando1 * operando2}`);\nconsole.log(`Operandos: ${operando1} y ${operando2}`);\n/* División */\nconsole.log(`=> División: ${operando1 / operando2}`);\nconsole.log(`Operandos: ${operando1} y ${operando2}`);\n/* Resto */\nconsole.log(`=> Resto: ${operando1 % operando2}`);\nconsole.log(`Operandos: ${operando1}`);\n/* Incremento */\nconsole.log(`=> Incremento: ${++operando1}`);\nconsole.log(`Operandos: ${operando1}`);\n/* Decremento */\nconsole.log(`=> Decremento: ${--operando1}`);\nconsole.log(`Operandos: ${operando1}`);\n/* Negación unaria */\nconsole.log(`=> Negación unaria: ${-operando1}`);\nconsole.log(`Operandos: ${operando1}`);\n/* Positivo unario */\nconsole.log(`=> Positivo unario: ${+operando1}`);\nconsole.log(`Operandos: ${operando1} y ${operando2}`);\n/* Operador de exponenciación */\nconsole.log(`=> Exponenciación: ${operando1 ** operando2}`);\n\n/* == Operadores bit a bit == */\n/* Un operador bit a bit trata a sus operandos como un conjunto de 32 bits \n(ceros y unos), en lugar de números decimales, hexadecimales u octales. \nPor ejemplo, el número decimal nueve tiene una representación binaria de 1001. \nLos operadores bit a bit realizan sus operaciones en tales representaciones binarias, \npero devuelven valores numéricos estándar de JavaScript. */\n\nconsole.log(`=== Operadores bit a bit ===`);\noperando1 = 15;\noperando2 = 9;\nconsole.log(`Operandos en formato decimal: ${operando1} y ${operando2}`);\nconsole.log(\n  `Operandos en formato binario: ${operando1.toString(\n    2\n  )} y ${operando2.toString(2)}`\n);\nlet resultado;\n\n/* AND a nivel de bits */\n/* Devuelve un uno en cada posición del bit para los que los bits correspondientes de ambos operandos son unos. */\nresultado = operando1 & operando2;\nconsole.log(`=> AND: ${resultado.toString(2)}`);\n\n/* OR a nivel de bits*/\n/* Devuelve un cero en cada posición de bit para el cual los bits correspondientes de ambos operandos son ceros.*/\nconsole.log(\n  `Operandos en formato binario: ${operando1.toString(\n    2\n  )} y ${operando2.toString(2)}`\n);\nresultado = operando1 | operando2;\nconsole.log(`=> OR: ${resultado.toString(2)}`);\n\n/* XOR a nivel de bits*/\n/* Devuelve un cero en cada posición de bit para la que los bits correspondientes son iguales. \n[Devuelve uno en cada posición de bit para la que los bits correspondientes son diferentes]. */\nconsole.log(\n  `Operandos en formato binario: ${operando1.toString(\n    2\n  )} y ${operando2.toString(2)}`\n);\nresultado = operando1 ^ operando2;\nconsole.log(`=> XOR: ${resultado.toString(2)}`);\n\n/* NOT a nivel de bits */\n/* Invierte los bits de su operando. */\nconsole.log(`Operando en formato binario: ${operando1.toString(2)}`);\nresultado = ~operando1;\nconsole.log(`=> NOT: ${resultado.toString(2)}`);\n\n/* Desplazamiento a la izquierda */\n/* Desplaza a en representación binaria b bits hacia la izquierda, desplazándose en ceros desde la derecha. */\nconsole.log(\n  `Operandos en formato binario: ${operando1.toString(\n    2\n  )} y ${operando2.toString(2)}`\n);\nresultado = operando1 << operando2;\nconsole.log(`=> Desplazamiento a la izquierda: ${resultado.toString(2)}`);\n\n/* Desplazamiento a la derecha de propagación de signo */\n/* Desplaza a en representación binaria b bits a la derecha, descartando los bits desplazados. */\nconsole.log(\n  `Operandos en formato binario: ${operando1.toString(\n    2\n  )} y ${operando2.toString(2)}`\n);\nresultado = operando1 >> operando2;\nconsole.log(`=> Desplazamiento a la derecha: ${resultado.toString(2)}`);\n\n/* Desplazamiento a la derecha de relleno cero */\n/* Desplaza a en representación binaria b bits hacia la derecha, \ndescartando los bits desplazados y desplazándose en ceros desde la izquierda.*/\nconsole.log(\n  `Operandos en formato binario: ${operando1.toString(\n    2\n  )} y ${operando2.toString(2)}`\n);\nresultado = operando1 >>> operando2;\nconsole.log(\n  `=> Desplazamiento a la derecha de relleno cero: ${resultado.toString(2)}`\n);\n\n/* == Operadores lógicos == */\n/* Los operadores lógicos se utilizan normalmente con valores booleanos (lógicos); \ncuando lo son, devuelven un valor booleano. \nSin embargo, los operadores && y || en realidad devuelven el valor \nde uno de los operandos especificados, por lo que si estos operadores se utilizan \ncon valores no booleanos, pueden devolver un valor no booleano. */\nconsole.log(`=== Operadores lógicos ===`);\noperando1 = true;\noperando2 = false;\noperando3 = true;\n\n/* AND lógico */\nconsole.log(\"AND\");\nconsole.log(`Operandos booleanos: ${operando1} y ${operando2}.`);\nconsole.log(operando1 && operando2);\nconsole.log(`Operandos booleanos: ${operando1} y ${operando3}.`);\nconsole.log(operando1 && operando3);\n/* OR lógico */\nconsole.log(\"OR\");\nconsole.log(`Operandos booleanos: ${operando1} y ${operando2}.`);\nconsole.log(operando1 || operando2);\nconsole.log(`Operandos booleanos: ${operando1} y ${operando3}.`);\nconsole.log(operando1 || operando3);\n\n/* NOT lógico */\nconsole.log(\"NOT\");\nconsole.log(`Operandos booleanos: ${operando1}.`);\nconsole.log(!operando1);\nconsole.log(`Operandos booleanos: ${operando2}.`);\nconsole.log(!operando2);\n\n/* == Operadores de concatenación == */\n/* Además de los operadores de comparación, que se pueden usar en valores de cadena, \nel operador de concatenación (+) concatena dos valores de cadena, \ndevolviendo otra cadena que es la unión de los dos operandos de cadena. */\nconsole.log(`=== Operadores de concatenación ===`);\nlet str1 = \"Hola\";\nlet str2 = \"Javascript\";\nconsole.log(str1);\nconsole.log(str2);\nconsole.log(\"Concatenado: \" + str1 + \" \" + str2);\n\n/* == Operador condicional o ternario == */\n/* El operador condicional es el único operador de JavaScript que toma tres operandos. \nEl operador puede tener uno de dos valores según una condición. */\nconsole.log(`=== Operador ternario ===`);\nlet edad = 20;\nconsole.log(`Si tengo ${edad} años.`);\nlet estado = edad >= 18 ? \"adulto\" : \"menor\";\nconsole.log(`Soy ${estado}.`);\n\nedad = 5;\nconsole.log(`Si tengo ${edad} años.`);\nestado = edad >= 18 ? \"adulto\" : \"menor\";\nconsole.log(`Soy ${estado}.`);\n\n/* === Control de flujo y manejo de errores === */\n/* == Expresiones condicionales == */\n/* If ... else */\n/* Utiliza la expresión if para ejecutar una instrucción si una condición lógica es true. \nUtiliza la cláusula opcional else para ejecutar una instrucción si la condición es false. */\nconsole.log(`=== Control de flujo y manejo de errores ===`);\nconsole.log(`== If...else ==`);\n\nedad = 40;\n\nif (edad === 40) {\n  console.log(\"Estas en la flor de la vida.\");\n} else {\n  console.log(\"O te has pasado o no llegas ;).\");\n}\n// Imprime la primera declaración ya que la condicion es true.\n\nedad = 50;\n\nif (edad === 40) {\n  console.log(\"Estas en la flor de la vida.\");\n} else if (edad < 40) {\n  console.log(\"Necesitas madurar.\");\n} else if (edad > 40) {\n  console.log(\"Disfruta de la vida.\");\n}\n// Imprime la ultima declaración ya que es la condición true.\n\n/* Switch */\n/* Una instrucción switch permite que un programa evalúe una expresión \ne intente hacer coincidir el valor de la expresión con una etiqueta case. \nSi la encuentra, el programa ejecuta la declaración asociada. */\nconsole.log(`== Switch ==`);\nedad = 65;\nswitch (edad) {\n  case 18:\n    console.log(\"Has alcanzado la mayoría de edad.\");\n    break;\n  case 40:\n    console.log(\"Estas en la flor de la vida.\");\n    break;\n  case 65:\n    console.log(\"Vamos a ver si nos podemos jubilar.\"); //Estas es la condición a imprimir.\n}\n\n/* == Bucles e iteración == */\n/* Los bucles ofrecen una forma rápida y sencilla de hacer algo repetidamente. */\n/* Declaración for */\nconsole.log(`== Bucles e iteración ==`);\nconsole.log(`== for ==`);\n\nfor (let i = 0; i < 10; i++) {\n  console.log(i);\n}\n\nconsole.log(`== do...while ==`);\nlet i = 5;\ndo {\n  console.log(i);\n  i++;\n} while (i < 10);\n\nconsole.log(`== while ==`);\ni = 5;\nwhile(i < 10) {\n  i++\n  console.log(i);\n}\n\n/* == Manejo de excepciones == */\nconsole.log(`== Manejo de excepciones ==`);\nconsole.log(`== Try-cath ==`);\nconst errNum = 1;\n\ntry {\n  if (errNum === 1) {\n    throw new Error('número 1.');\n  }\n  else {\n    console.log(\"El error no es el número 1.\");\n  } \n} catch (error) {\n  console.log(`El problema proviene del error: ${error.message}`);\n}\n\n\n/* Ejercicio Extra */\nconsole.log(`== Ejercicio extra ==`);\n\nfor (i = 10; i <= 55; i++) {\n  if (i % 2 === 0 && i !== 16 && i % 3 === 0) {\n    console.log(i);\n  }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/DobleDJ.js",
    "content": "/**\n * Retos de programación - 01 -\n * Autor: Yoandy Doble Herrera\n * Fecha: 05/12/2024\n */\n\n/**\n * Ejercicio 1 tipos de operadores\n */\n\nlet numeroUno = 25.6\nlet numeroDos = 8\n\n//Operadores aritméticos\nlet suma = numeroUno + numeroDos //operador suma\nconsole.log(suma)\nlet resta = numeroUno - numeroDos //operador resta\nconsole.log(resta)\nlet multiplicacion = numeroUno * numeroDos //operador multiplicación\nconsole.log(multiplicacion)\nlet division = numeroUno / numeroDos //operador division\nconsole.log(division)\nlet resto = numeroUno % numeroUno //operador resto\nconsole.log(resto)\nlet exponenciacion = 2 ** 3 //operador exponenciación\nconsole.log(exponenciacion)\nlet incremento = numeroDos //8\nincremento++ //operador incrementoconsole.log()\nconsole.log(incremento)\nlet decremento = numeroUno //25.6\ndecremento-- //operador decremento\nconsole.log(decremento)\nlet cantidad = 22\nlet valorNegativo = -cantidad //Operador negativo, resultado esperado -22\nconsole.log(valorNegativo)\n\n//asignación\nlet enteroNumero = 65897\nconsole.log(enteroNumero)\nlet asigSuma = (enteroNumero += 1)\nconsole.log(asigSuma)\nlet asigResta = (enteroNumero -= 1)\nconsole.log(asigResta)\nlet asigMultiplo = (enteroNumero *= 2)\nconsole.log(asigMultiplo)\nlet asigDivisor = (enteroNumero /= 2)\nconsole.log(asigDivisor)\nlet asigExponente = (enteroNumero **= 3)\nconsole.log(asigExponente)\nlet asigResto = (enteroNumero %= 6)\nconsole.log(asigResto)\nlet xorBit = (enteroNumero ^= 365)\nconsole.log(xorBit)\nlet andBit = (enteroNumero &= 3256)\nconsole.log(andBit)\nlet andClassic = (enteroNumero &&= 3256)\nconsole.log(andClassic)\nlet orBitwise = (enteroNumero |= 3256)\nconsole.log(orBitwise)\nlet orClassic = (enteroNumero ||= 3256)\nconsole.log(orClassic)\n\n// Operadores lógicos\nlet andLogico = 11 > 5 && 3654 < 12\nconsole.log(andLogico)\nlet orLogico = 12 + 55 > 33 || 9987.2 < 254\nconsole.log(orLogico)\nlet testNull = 12 / 22 ?? 12\nconsole.log(testNull)\nlet negar = !isNaN(12212)\nconsole.log(negar)\n\n//Operadores de comparación\nlet mayorQue = 45 > 80\nconsole.log(mayorQue)\nlet menorQue = 10 < 100000\nconsole.log(menorQue)\nlet mayorIgual = 35.7 >= 10.8\nconsole.log(mayorIgual)\nlet menorIgual = 99 <= 35\nconsole.log(menorIgual)\nlet igualdad = 1254 == \"1254\" //compara por valor\nconsole.log(igualdad)\nlet fullTest = 1254 === \"1254\" //compara por valor y tipo\nconsole.log(fullTest)\nlet noIgual = 687 != 3587\nconsole.log(noIgual)\nlet estrictoNot = 68 !== 3525487\nconsole.log(estrictoNot)\n\n//String operadores\nlet nameUser = \"Yerlany\"\nlet lastname = \"Double\"\nlet fullname = nameUser + lastname //concatenar string\nconsole.log(fullname)\n\nlet value1 = 56\nlet value2 = 3698\n\n//Bitwise operadores\nlet andOperador = value1 & value2 //and\nconsole.log(andOperador)\nlet orOperador = value1 | value2 //or\nconsole.log(orOperador)\nlet xor = value1 ^ value2 //Xor\nconsole.log(xor)\nlet notOperador = ~value1 //Not\nconsole.log(notOperador)\n\n//Ternario Operador\nlet age = 28\nlet isAdult = age > 18 ? true : false\nconsole.log(isAdult)\n\n/**\n * Ejercicio 2 estructuras de control\n */\n\nlet saltoA = 2.45\nlet saltoB = 2.32\n\n// Estructura if\nif (saltoA > 3) {\n  console.log(\"No es record olímpico\")\n}\n\n//Estructura if - else\nif (saltoA > saltoB) {\n  console.log(\"Ha ganado el primer saltador\")\n} else {\n  console.log(\"Ha ganado el segundo saltador\")\n}\n\nlet cuentaFin = 10\nlet inicio = 0\n\nwhile (inicio <= cuentaFin) {\n  console.log(`Faltan: ${cuentaFin - inicio} para terminar`)\n  inicio++\n}\n\n/*let paso = 0\ndo {\n  console.log(\"¡Welcome to JavaScript roadmap!\")\n} while (paso < 2)\n*/\nlet result = []\nlet paso = 0\n\ndo {\n  paso++\n  result.push(paso)\n} while (paso < 5)\n\nconsole.log(result)\n// Expected output: \"12345\"\n\n//switch\nlet estacion = \"verano\"\n\nswitch (estacion) {\n  case \"otoño\":\n    console.log(\"Estación Otoño\")\n    break\n  case \"verano\":\n    console.log(\"Estación Verano\")\n    break\n  case \"invierno\":\n    console.log(\"Estación Invierno\")\n    break\n  case \"primavera\":\n    console.log(\"Estación Primavera\")\n    break\n  default:\n    console.log(\"Tipo de estación no encontrada\")\n}\n\n// for\n\nfor (let index = 0; index < 10; index++) {\n  //iteracion clasica\n  console.log(index)\n}\n\n// for of  (objetos y array)\nlet animales = [\"tigre\", \"tiburón\", \"oso\", \"leon\"]\nfor (let values of animales) {\n  console.log(`Animales del zoológico ${values}`)\n}\n\n//foreach array\nlet miPropiedad = { name: \"Yoandy\", profession: \"front-end\", code: \"leon\" }\n\nlet listaAnimales = animales.forEach((element) => {\n  if (element == miPropiedad[\"code\"]) {\n    console.log(\"found\")\n  } else {\n    console.log(\"No found\")\n  }\n})\n\n/**\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n */\n\nfunction parEjercicio() {\n  for (let index = 10; index <= 55; index++) {\n    if (index !== 16 && index % 2 === 0 && index % 3 !== 0) {\n      console.log(\"Numero par, no es 16 y no es múltiplo de 3: \", index)\n    }\n  }\n}\nparEjercicio()\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/DouglasDiazR.js",
    "content": "/*Operadores Aritméticos */\n\n//Suma +\nvar suma = 4 + 5;\nconsole.log(\"suma: \" + suma);\n\n//Resta -\nvar resta = 5 - 2;\nconsole.log(\"resta: \" + resta);\n\n// Multiplicación *\nvar multiplica = 5 * 5;\nconsole.log(\"multiplicación: \" + multiplica);\n\n//División /\nvar divide = 10 / 2;\nconsole.log(\"División: \" + divide);\n\n//Módulo o Resto\nvar resto = 20 % 2;\nconsole.log(\"Resto: \" + resto);\n\n/*Operadores de Asignación */\n\n//Asignación =\nvar variable = \"VALOR ASIGNADO\";\nconsole.log(\"este es un \" + variable);\n\n//Asignación con Operación += , -= , *= , /= , %=\nvar a = 3;\na += 5; // ésto es igual a hacer a = a + 5. Igual para los otros operadores aritméticos\nconsole.log(a);\n\n\n/*Operadores de Comparación*/\n\n//Igualdad Estricta ===\nvar igualdadEstricta = ( 3 === 3);//true\n\n//igualdad \nvar igualdad = (3 == \"3\"); //true\n\n//Desigualdad Estricta !==\nvar desigualdadEstricta = (2 !== \"2\"); //true\n\n//Desigualdad\nvar desigualdad = (4 != \"4\"); //false\n\n//Mayor que >\nvar mayor = (5 > 3); //true\n\n//Menor que <\nvar menor = (3 < 5); //true \n\n//Mayor o Igual que >=\nvar mayorIgual = (5 >= 5); //true\n\n//Menor o ------igual que <=\nvar menorIgual = (3 <= 10); //true\n\n\n/*Operadores Lógicos*/\n\n//AND &&\nvar and = (true && false) //si todas las condiciones son true, devuelve true, si no retorna false\n\n//OR ||\nvar or = (true && false) //si alguna de las condiciones son true, devuelve true, si no retorna false\n\n//NOT !\nvar not = !true; //false\n\n\n/*OPERADORES DE INCREMENTO Y DECREMENTO*/\n\n//Incremento ++\nvar incremento = 5;\nincremento++; // ésto es igual a hacer (incremento = incremento + 1)\nconsole.log(\"incremento: \" + incremento);\n\n//Decremento --\nvar decremento = 5;\ndecremento --; //éstp es igual a hacer (decremento = decremento - 1)\nconsole.log(\"decremento: \" + decremento);\n\n/*ESTRUCTURAS DE CONTROL CONDICIONALES*/\n\n//if\nvar a = 5;\nvar b = 3;\nif(a > b){\n    console.log(a + \" es mayor que \" + b );\n}\n\n//if-else\nvar edad = 18;\nif(edad >= 18){\n    console.log(\"Es Mayor de Edad\");\n}\nelse{\n    console.log(\"Es Menor de Edad\");\n}\n\n//if-else if\nvar semaforo = \"verd\";\nif(semaforo === \"verde\"){\n    console.log(\"Siga\");\n}\nelse if(semaforo === \"amarillo\"){\n    console.log(\"precaución\");\n}\nelse if(semaforo === \"rojo\"){\n    console.log(\"Pare\");\n}\nelse{\n    console.log(\"error\");\n}\n\n\n//Switch\nvar numero = 5;\nswitch(numero){\n    case numero % 2 == 0:\n        console.log(numero + \" Es un número par\");\n        break;\n    case numero % 3 == 0:\n        console.log(numero + \" Es un multiplo de 3\");\n        break;\n    default:\n        console.log(numero + \" No es multiplo de 2 ni de 3\");\n}\n\n\n/*ESTRUCTURAS DE CONTROL ITERATIVAS */\n\n//For\nfor(i = 0; i <= 10; i++){\n    console.log(\"el valor de i es: \" + i);\n}\n\nvar numero = 2;\nwhile( numero % 2 ===0 && numero < 10 ){\n    console.log(\"número par: \" + numero);\n    numero += 2;\n    }\n\n\n//do-while  \nvar numero = 3;\ndo{\n    console.log(numero + \" Es Múltiplo de 3\");\n    numero += 3;\n}\nwhile( numero % 3 ===0 && numero < 10 );\n\n//for in\nvar jugadores = {\n    nombre: 'Juan',\n    numero: 9,\n    posicion: 'Delantero'\n};\n\nfor (var jugador in jugadores) {\n    console.log(jugador + ': ' + jugadores[jugador]);\n}\n\n//for of\nvar colores = ['rojo', 'verde', 'azul'];\nfor (var color of colores) {\n    console.log(color);\n}\n\n//break\nfor(i = 0; i <= 10; i++){\n    console.log(i);\n    if(i === 5){\n        break;\n    }\n}\n    \n\n//continue\nnumero = 0;\nwhile(numero <= 20){\n    numero ++;\n    if(numero % 3 === 0){\n        continue;\n    }\n    console.log(numero + \" No es Múltiplo de 3\");\n}\n\n\n/*DIFICULTAD EXTRA*/\n\nfor(i = 10; i < 55; i ++){\n    if( i % 2 === 0 && i != 16 && i % 3 !== 0){\n        console.log(i)\n    }\n}\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/EdgarMedranoA.js",
    "content": "/*   - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n    Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n    (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n   Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n    que representen todos los tipos de estructuras de control que existan\n    en tu lenguaje:\n    Condicionales, iterativas, excepciones...\n   Debes hacer print por consola del resultado de todos los ejemplos.\n \n  DIFICULTAD EXTRA (opcional):\n  Crea un programa que imprima por consola todos los números comprendidos\n  entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n \n  Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo. */\n\n// aritmeticos\n\nlet x = 5;\nlet y = 3;\n\nconsole.log(x + y); //suma\nconsole.log(x - y); //resta\nconsole.log(x / y); //division\nconsole.log(x * y); //multiplicacion\nconsole.log(x % y); //modulo\n\n// asignacion\n\nlet a = 10;\na += 5; //equivale a: a = a = + 5\nconsole.log(a);\n\n//comparacion\n\nlet b = 20;\nlet c = 10;\n\nconsole.log(b == c); // igualdad\nconsole.log(b === c); // igualdad estricta\nconsole.log(b != c); // desigualdad\nconsole.log(b !== c); // desigualdad estricta\nconsole.log(b > c); // mayor\nconsole.log(b < c); // menor\nconsole.log(b >= c); // mayor igual\nconsole.log(b <= c); // menor igual\n\n//logicos\n\nlet frio = true;\nlet calor = true;\n\nconsole.log(frio && calor);\nconsole.log(frio || calor);\nconsole.log(! calor);\n\n//incremento y decremento \n\nlet contador = 5;\n\ncontador++; //incrementar en 1\nconsole.log(contador);\n\n//concatenacion\n\nlet nombre = \"Edgar\";\nlet apellido = \"Medrano\";\n\nconsole.log(nombre + \" \" + apellido);\n\n// ternario\n\nlet edad = 38;\nlet permitido = (edad >= 18) ? \"si\" : \"no\";\n\nconsole.log(\"esta permitido? \" + permitido);\n\n//tipo de dato\n\nlet variable = 20;\n\nconsole.log(typeof variable); //tipo int\n\nvariable = \"Hola mundo\";\n\nconsole.log(typeof variable); //tipo string\n\n/*   DIFICULTAD EXTRA (opcional):\n  Crea un programa que imprima por consola todos los números comprendidos\n  entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3. */\n\nfor (let i = 10; i <= 55; i++) {\n    if(numero !== 16 && numero % 2 === 0 && numero % 3 !== 0) {\n        console.log(i);\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/EliMejiaP.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n// operadores aritmeticos JavaScript\nlet suma = 5 + 5;\nlet resta = 5 - 5;  \nlet multiplicacion = 5 * 5;\nlet division = 5 / 5;\nlet modulo = 5 % 5;\nlet incremento = 5;\nincremento++;   \nlet decremento = 5;\ndecremento--;\nlet exponenciacion = 5 ** 2;\nlet asignacion = 5;\nasignacion += 4;\nconsole.log(suma, resta, multiplicacion, division, modulo, incremento, decremento, exponenciacion, asignacion);\n\n// estructuras de control JavaScript\n\n// condicional if: Ejecuta un bloque de código si una condición es verdadera.\nconst edad = 18;\n\nif (edad>=18) {\n  console.log('Eres mayor de edad');\n}\n// condicional else: Ejecuta un bloque de código si la condicion if es falsa.\nconst mayorDeEdad = 16;\nif (mayorDeEdad>=18) {\n  console.log('Puedes conducir');\n}\nelse {\nconsole.log('No puedes conducir');\n}\n// condicional else if: permite evaluar múltiples condiciones.\nif (mayorDeEdad>=18) {\n  console.log('Eres mayor de edad');\n}\nelse if (mayorDeEdad>=16) {\n  console.log('Eres adolescente');\n}\nelse { \n    console.log('Eres un niño');\n}\n// switch: Evalúa una expresión, comparando el valor de esa expresión con una instancia case, y ejecuta declaraciones asociadas a ese case.\nlet canalesDeTv = 2;\nswitch (canalesDeTv) {\n  case 1:\n    console.log(\"canal2\");\n    break;\n  case 2:\n    console.log(\"tvNoticias\");\n    break;\n  default:\n    console.log(\"televisor apagado\");\n}\n//estructura de bucles.\n// bucle for: ejecuta un bloque de código un numero determinado de veces.\nfor (let i = 0; i < 6; i++) {\n  console.log(i);\n}\n// bucle while: ejecuta un bloque de código mientras la condición especificada sea verdadera.\nlet i = 6;\nwhile (i < 5) {\n  console.log(i);\n  i++;\n}\nconsole.log(i);\n// do while: ejecuta un bloque de código al menos uma vez, y luego repite el bucle mientras la condición especificada sea verdadera.\nlet a = 0;\ndo {\n  console.log(a);\n  a++;\n} while (a < 5);\n//for in: recorre las propiedades de un objeto.\nconst persona = {nombre: 'Eli', edad: 40};\nfor(let edad in persona) {\n  console.log(edad, persona[edad]);\n}\n//for of: crea un bucle que itera sobre objetos iterables.\nconst colores = ['rojo', 'azul', 'verde'];  \nfor (let color of colores) \n  console.log(color);\n//try catch: permite manejar errores.\ntry {\n  console.log('Hola');\n  console.log(x);\n  console.log('Mundo');\n}\ncatch(err) {\n  console.log('Ha ocurrido un error');\n}\n/*DIFICULTAD EXTRA (opcional):\nCrea un programa que imprima por consola todos los números\ncomprendidos entre 10 y 55 (incluidos), pares,\ny que no son ni el 16 ni múltiplos de 3.\nSeguro que al revisar detenidamente las posibilidades\nhas descubierto algo nuevo.*/\nfor (let i = 10; i <= 55; i++) {\n   if (i%2===0 && i != 16 && i%3 !== 0) {\n     console.log(i)\n        }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/EliTeDev-44.js",
    "content": "/*\n_____________________________________\nhttps://github.com/JDesing\n2025 - JavaScript\n_______________________________________\n01 OPERADORES Y ESTRUCTURAS DE CONTROL\n---------------------------------------\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n*/\n\n// _______________________\n// Referencias:\n// https://developer.mozilla.org/es/docs/Web/JavaScript/Reference\n// https://developer.mozilla.org/es/docs/Web/JavaScript/Guide\n\n// _______________________\n// Tipos de operadores\n// https://developer.mozilla.org/es/docs/Learn/Getting_started_with_the_web/JavaScript_basics#operadores\n\n// _______________________\n// Concatenación\nconsole.log(\"===============================\")\nconsole.log(\"Concatenación\")\n\nlet saludo = \"🙋🏻 Hola \" + \"JavaScript!!!\"\nconsole.log(saludo)\n\nlet numero = 2025\nconsole.log(\"Año: \" + numero)\n\nlet mezcla = saludo + \" \" + \"Estamos en \" + numero + \" ✅\"\nconsole.log(mezcla)\n\n// _______________________\n// Operador de asignación \"=\":\nconsole.log(\"===============================\")\nconsole.log(\"Operador de asignación '='\")\n\nlet miString = 'JDesing'\nconsole.log(miString) // \"JDesing\"\n\nlet b = 3\nb += 2 // Aplicable a todos los operadores aritméticos.\nconsole.log(b) // 5\n\n// _______________________\n// Operadores aritméticos:\n// https://developer.mozilla.org/es/docs/Web/JavaScript/Guide/Expressions_and_Operators#arithmetic_operators\n\nconsole.log(\"===============================\")\nconsole.log(\"Operadores aritméticos\")\nconsole.log(\"Suma (+), Resta (-), Multiplicación (*), División (/), Resto (%), Potenciación (**), Incremento (++), Decremento (--)\")\n\nlet suma = 10 + 34\nconsole.log(suma) // 44\n\nlet resta = 10 - 6\nconsole.log(resta); // 4\n\nlet multiplicacion = 7 * 2\nconsole.log(multiplicacion) // 14\n\nlet division = 12 / 3\nconsole.log(division) // 4\n\nlet resto = 20 % 7\nconsole.log(resto) // 6\n\nlet potenciacion = 2 ** 3\nconsole.log(potenciacion) // 8\n\n// Incremento\nlet incremento = 5\nconsole.log(++incremento) // 6\n\n// Decremento\nlet decremento = 5\nconsole.log(--decremento) // 4\n\n// _______________________\n// Operadores de Comparación:\nconsole.log(\"===============================\")\nconsole.log(\"Operadores de Comparación\")\nconsole.log(\"Igual a (==),Estrictamente igual (===),  Diferente de (!=), No estrictamente igual (!==), Menor que (<), Mayor que (>), Menor o igual (<=), Mayor o igual (>=)\")\n\nlet igual = 5 == \"5\" // Igual a\nconsole.log(`5 == 5 -> ${igual}`) // true\n\nlet estrictamenteIgual = 5 === 5 // Estrictamente igual\nconsole.log(`5 === 5 -> ${estrictamenteIgual}`) // true\n\nlet noIgual = 5 != 5 // Diferente de\nconsole.log(`5 != 5 -> ${noIgual}`) // false\n\nlet menorQue = 4 < 5 // Menor que\nconsole.log(`4 < 5 -> ${menorQue}`) // true\n\nlet mayorQue = 4 > 5 // Mayor que\nconsole.log(`4 > 5 -> ${mayorQue}`) // false\n\nlet menorOIgual = 4 <= 5 // Menor o igual\nconsole.log(`4 <= 5 -> ${menorOIgual}`) // true\n\nlet mayorOIgual = 4 >= 5 // Mayor o igual\nconsole.log(`4 >= 5 -> ${mayorOIgual}`) // false\n\n// _______________________\n// Operadores Lógicos:\nconsole.log(\"===============================\")\nconsole.log(\"Operadores Lógicos\")\nconsole.log(\"AND (&&), OR (||), NOT (!)\")\n\nlet operadorAnd = (5 < 10) && (10 > 5) // AND lógico\nconsole.log(`(5 < 10) && (10 > 5) -> ${operadorAnd}`) // true\n\nlet operadorO = (5 < 10) || (10 < 5) // OR lógico\nconsole.log(`(5 < 10) || (10 < 5) -> ${operadorO}`) // true\n\nlet operadorNo = !(5 < 10) // NOT lógico\nconsole.log(`!(5 < 10) -> ${operadorNo}`) // false\n\n// _______________________\n// Operadores a nivel de bits:\nconsole.log(\"===============================\")\nconsole.log(\"Operadores a nivel de bits\")\nconsole.log(\"AND (&), OR (|), XOR (^), Desplazamiento a la izquierda (<<), Desplazamiento a la derecha (>>), Desplazamiento a la derecha sin signo (>>>)\")\n\nlet bitAnd = 5 & 3 // AND a nivel de bits\nconsole.log(`5 & 3 -> ${bitAnd}`) // 1\n\nlet bitOr = 5 | 3; // OR a nivel de bits\nconsole.log(`5 | 3 -> ${bitOr}`); // 7\nlet bitXor = 5 ^ 3; // XOR a nivel de bits\nconsole.log(`5 ^ 3 -> ${bitXor}`); // 6\nlet leftShift = 5 << 1; // Desplazamiento a la izquierda\nconsole.log(`5 << 1 -> ${leftShift}`); // 10\nlet rightShift = 5 >> 1; // Desplazamiento a la derecha\nconsole.log(`5 >> 1 -> ${rightShift}`); // 2\n\n// Estructuras de control\n// _______________________\nconsole.log(\"===============================\")\nconsole.log(\"Estructuras de control\")\nconsole.log(\"Condicionales: if-else\")\n\n// Condicionales:\nif (5 == 5) { // Aplicable a todos los operadores de Comparación.\n    console.log(\"Si lo es.\")\n} else if (5 == 6) {\n    console.log(\"Si no, si es.\")\n}else {\n    console.log(\"Si no lo es.\")\n}\n\n// Con operadores lógicos:\nif (5 == 5 && 7 < 10) { // Equivalente a 'and'\n    console.log(\"Ambas condiciones son verdaderas.\");\n} else {\n    console.log(\"Al menos una condición es falsa.\");\n}\n\n// _______________________\n// Estructura condicional: switch\nconsole.log(\"===============================\")\nconsole.log(\"Estructura condicional: switch\")\n\nlet dia = 3\nswitch (dia) {\n    case 1:\n        console.log(\"Lunes\")\n        break\n    case 2:\n        console.log(\"Martes\")\n        break\n    \n    default:\n        console.log(\"Otro día\")\n        break\n}\n\n// _______________________\n// Estructuras iterativas (Bucles):\n// https://developer.mozilla.org/es/docs/Web/JavaScript/Guide/Loops_and_iteration\n\nconsole.log(\"===============================\")\nconsole.log(\"Estructuras iterativas (Bucles)\")\nconsole.log(\"for, while, do-while\")\n\n// Bucle for\nconsole.log(\"Bucle for:\")\nfor (let contar = 0; contar < 5; contar++) {\n    console.log(`i = ${contar}`)\n}\n\n// Bucle while\nconsole.log(\"Bucle while:\")\nlet contar = 4\nwhile (contar > 0) {\n    console.log(`Contar = ${contar}`)\n    contar--\n}\n\n// Bucle do-while\nconsole.log(\"Bucle do-while:\")\nlet numero2 = 0\ndo {\n    console.log(`num = ${numero2}`)\n    numero2++\n} \nwhile (numero2 < 3)\n\nconsole.log(\"===============================\")\nconsole.log(\"Fin del programa\")\nconsole.log(\"===============================\")\n// _______________________\n// Fin del programa\n//\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/EloyChavezDev.js",
    "content": "// Operadores \n//Aritméticos:\nconsole.log(2 + 3); // Suma: 5\nconsole.log(5 - 2); // Resta: 3\nconsole.log(4 * 3); // Multiplicación: 12\nconsole.log(12 / 3); // División: 4\nconsole.log(10 % 3); // Resto: 1\n\n// Exponenciación (a partir de ES7)\nconsole.log(2 ** 3); // 8\n\n//Lógicos:\nJavaScript\nconsole.log(true && true); // AND: true\nconsole.log(true || false); // OR: true\nconsole.log(!true); // NOT: false\n\n//De comparación:\nconsole.log(2 === 2); // Igualdad estricta: true\nconsole.log(2 == 2); // Igualdad no estricta: true\nconsole.log(2 > 1); // Mayor que: true\nconsole.log(2 >= 2); // Mayor o igual que: true\nconsole.log(1 < 2); // Menor que: true\nconsole.log(1 <= 2); // Menor o igual que: true\n\n//Asignación:\nlet x = 10;\nx += 5; // x = 15\nx -= 2; // x = 13\nx *= 3; // x = 39\nx /= 2; // x = 19.5\nx %= 4; // x = 3.5\n\n//Identidad:\nconst a = 10;\nconst b = 10;\nconsole.log(a === b); // true (mismo valor y tipo)\nconst c = \"10\";\nconsole.log(a === c); // false (mismo valor, diferente tipo)\n\n//Pertenencia:\nconst lista = [\"a\", \"b\", \"c\"];\nconsole.log(\"a\" in lista); // true\nconsole.log(\"d\" in lista); // false\n\n//Bits\nconsole.log(1 | 2); // OR a nivel de bits: 3\nconsole.log(1 & 2); // AND a nivel de bits: 0\nconsole.log(1 ^ 2); // XOR a nivel de bits: 3\nconsole.log(~1); // NOT a nivel de bits: -2\n\n//Estructuras de Control\n//Condicionales:\nconst numero = 10;\nif (numero > 0) {\n  console.log(\"El número es positivo\");\n} else {\n  console.log(\"El número es negativo\");\n}\n\n//Iterativas:\n// Bucle for\nfor (let i = 10; i <= 55; i++) {\n    if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n      console.log(i);\n    }\n  }\n  \n  // Bucle while\n  let j = 10;\n  while (j <= 55) {\n    if (j % 2 === 0 && j !== 16 && j % 3 !== 0) {\n      console.log(j);\n    }\n    j++;\n  }\n  \n  // Bucle do-while\n  let k = 10;\n  do {\n    if (k % 2 === 0 && k !== 16 && k % 3 !== 0) {\n      console.log(k);\n    }\n    k++;\n  } while (k <= 55);\n\n  //Excepciones:\n  try {\n    throw new Error(\"Error personalizado\");\n  } catch (error) {\n    console.log(error.message);\n  }\n\n  /*\n  Dificultad Extra:\n  * Crea un programa que imprima por consola todos los números comprendidos\n  * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n  */\n  for (let i = 10; i <= 55; i++) {\n    if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n      console.log(i);\n    }\n  }"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/EloyParga.js",
    "content": "//OPERADORES\n\n\n//Operadores Aritmeticos\nconsole.log(`Suma: ${7 + 5}`) //Suma\nconsole.log(`Resta: ${7 - 5}`) //Resta\nconsole.log(`Multiplicación: ${7 * 5}`) //Multiplicación\nconsole.log(`División: ${7 / 5}`) //División\nconsole.log(`División: ${7 / 5}`) //División\nconsole.log(`Módulo: ${7 % 5}`) //Resto de Division\nconsole.log(`Exponenciación: ${7 ** 5}`) //Potencia\n\n//Operadores de comparacion\nconsole.log(`Mayor que: ${7 > 5}`)\nconsole.log(`Menor que: ${5 < 7}`)\nconsole.log(`Igual que: ${7 === 7}`)\nconsole.log(`Distinto que: ${5 !== 7}`)\nconsole.log(`Mayor o igual que: ${5 >= 5}`)\nconsole.log(`Menor o igual que: ${7 <= 7}`)\n\n//Operadores Lógicos\nlet a = true\nlet b = false\n\nconsole.log(\"a AND b\", a && b)\nconsole.log(\"a OR b\", a || b)\nconsole.log(\"NOT a\", !a )\n\n//Operadores de Assignación\n\nlet c = 4   // Asignacion\nc += 5      // Suma y Asignacion\nc -= 5      // Resta y Asignacion\nc *= 5      // Multiplicacion y Asignacion\nc /= 5      // Division y Asignacion\nc %= 5      // Resto y Asignacion\nc **= 5     // Potencia y Asignacion\n\n\n//Operadores de bits\nconsole.log(`5 AND 3: ${5 & 3}`) // 0101 & 0011 =  0001\nconsole.log(`5 OR 3: ${5 | 3}`) // 0101 | 0011 =  0111\nconsole.log(`5 XOR 3: ${5 ^ 3}`) // 0101 ^ 0011 =  0110\nconsole.log(`5 shift left 1: ${5 << 1}`) // 0101  =  1010\nconsole.log(`5 shift rigth 1: ${5 >> 1}`) // 0101 =  0010\n\n//ESTRUCTURAS DE CONTROL\nlet edad =18\n\n//Condicional: if-else\nif (edad >= 18) {\n    console.log(\"Eres Mayor de edad\")\n}else if (edad <=3){\n    console.log(\"Eres un bebe\")\n}else{\n    console.log(\"Eres menor de edad\")\n}\n\n//Condicional: Switch\nlet fruta =\"kiwi\"\n\nswitch (fruta) {\n    case \"kiwi\" :\n        console.log(\"Es un kiwi\")\n        break;\n    case \"naranja\" :\n        console.log(\"Eres una naranja\")\n        break;\n    case \"piña\" :\n        console.log(\"Eres una piña\")\n        break;\n    default:\n        console.log(\"No se que fruta eres\")\n}\n\n//Bucle for\nfor (let i = 1; i <= 10; i++) {\n    console.log(\"Numero: \", i)\n}\n\n//Bucle while\nlet cont = 10\nwhile (cont >= 1) {\n    console.log(\"Numero: \", cont)\n    cont --;\n}\n\n//Manejo de excepciones try-catch\ntry {\n    let resultado = 10/0 // Error Logico\n    console.log(\"Resultado: \", resultado)\n}catch(error){\n    console.log(\"¡Error atrapado! \" , error.message)\n}\n\n//DIFICULTAD EXTRA:números entre 10 y 55 , pares, ni 16 ni múltiplos de 3.\nconsole.log(\"=== DIFICULTAD EXTRA ===\")\nfor (let i = 10; i <= 55; i++) {\n    if(i % 2 === 0 && i !== 16 && i % 3 !==0) {\n        console.log(\"Numero: \", i)\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/EmilioRDev.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n//**Tipos de operadores en javascript */\n\n//*Operadores aritméticos */\n// Suma\nlet suma = 5 + 4;\nconsole.log({ suma });\n\n// Resta\nlet resta = 10 - 7;\nconsole.log({ resta });\n\n// Multiplicación\nlet multiplicacion = 6 * 4;\nconsole.log({ multiplicacion });\n\n// División\nlet division = 20 / 5;\nconsole.log({ division });\n\n// Módulo\nlet modulo = 17 % 4; // Proporciona el resto de dividir el primero número con el segundo.\nconsole.log({ modulo });\n\n// Incremento\nlet numInc = 6;\nnumInc++; // Incrementa numero en 1.\nconsole.log({ numInc });\n\n// Decremento\nlet numDec = 6;\nnumDec--; // Decrementa numero en 1.\nconsole.log({ numDec });\n\n//**Operadores lógicos */\n\n// Operador AND (&&)\nlet opAND = 5 > 2 && 2 < 10; // Devuelve true en caso de que ambas condiciones sean verdaderas, sino devuelve false.\nconsole.log({ opAND });\n\n// Operador OR (||)\nlet opOR = 8 == 4 || 7 < 10; // Devuelve true si al menos una de las condiciones es verdadera, solo devuelve false cuando todas las condiciones son falsas.\nconsole.log({ opOR });\n\nlet opNOT = !(6 > 1); // Si la expresión orginal es verdadera, ! la convierte en falsa y viceversa.\nconsole.log({ opNOT });\n\n//**Operadores de comparación */\nlet a = 4;\nlet b = 9;\n\n// Igualdad\nlet igualdad = a == b;\nconsole.log({ igualdad });\nlet igualdadEstricta = a === b; // Tambien es un operador de identidad\nconsole.log({ igualdadEstricta });\n\n// Desigualdad\nlet desigualdad = a != b;\nconsole.log({ desigualdad });\nlet desigualdadEstricta = a !== b; // Tambien es un operador de identidad\nconsole.log({ desigualdadEstricta });\n\n// Mayor que y menor que\nlet mayor = a > b;\nconsole.log({ mayor });\nlet menor = a < b;\nconsole.log({ menor });\n\n// Mayor o igual que y menor o igual que\nlet mayorIgual = a >= b;\nconsole.log({ mayorIgual });\nlet menorIgual = a <= b;\nconsole.log({ menorIgual });\n\n//**Operadores de asignación */\n// Asignación basica =\nlet basica = 3;\nconsole.log({ basica });\n\n// Asignación con adición *=\nlet adicion = 6;\nadicion += 9; // Equivale a adicion = adicion + 9\nconsole.log({ adicion });\n\n// Asignación con sustracción -=\nlet sustraccion = 6;\nsustraccion -= 9; // Equivale a sustraccion = sustraccion - 9\nconsole.log({ sustraccion });\n\n// Asignación con multiplicación *=\nlet multiplicacionAsig = 6;\nmultiplicacionAsig *= 9; // Equivale a multiplicacionAsig = multiplicacionAsig * 9\nconsole.log({ multiplicacionAsig });\n\n// Asignación con multiplicación /=\nlet divisionAsig = 6;\ndivisionAsig /= 9; // Equivale a divisionAsig = divisionAsig / 9\nconsole.log({ divisionAsig });\n\n//**Operadores de pertenencia */\n\n// Operador de pertenencia en array\nlet arr = [1, 2, 3, 4, 5];\n\nconsole.log('Operador de pertencia arr 1: ' + arr.includes(3)); // Devuelve true, ya que 3 se encuentra en el array\nconsole.log('Operador de pertencia arr 2: ' + arr.includes(8)); // Devuelve false, ya que 8 no se encuentra en el array\n\n// Operador de pertencia en string\nlet cadena = '!Hola, mundo';\n\nconsole.log('Operador de pertencia string 1: ' + cadena.includes('Hola'));\nconsole.log('Operador de pertencia string 2: ' + cadena.includes('javascript'));\n\n// Operador de pertencia in para verificar si una propiedad esta presente en un objeto\nlet persona = {\n\tname: 'José',\n\tedad: 24,\n\tciudad: 'Sevilla',\n};\n\nconsole.log('Operador de pertencia objeto 1: ' + ('name' in persona));\nconsole.log('Operador de pertencia objeto 2: ' + ('trabajo' in persona));\n\n//**Operador de concatenación */\nlet msg1 = 'Hola';\nlet msg2 = 'mundo';\n\nconsole.log('¡' + msg1 + ', ' + msg2 + '!'); // Para concatenar se hace uso de +\n\n//**Operador de tipos de datos */\n\nlet td1 = 5;\nlet td2 = 'Hola';\nlet td3 = true;\nlet obj1 = { name: 'Ejemplo' };\n\nconsole.log('Operador de tipos de datos');\nconsole.log(typeof td1); // Devuelve \"number\"\nconsole.log(typeof td2); // Devuelve \"string\"\nconsole.log(typeof td3); // Devuelve \"boolean\"\nconsole.log(typeof obj1); // Devuelve \"object\"\nconsole.log('-----------------------');\n\n//**Operadores de instancia */\n\nclass Persona {\n\tconstructor(nombre) {\n\t\tthis.nombre = nombre;\n\t}\n}\n\nlet persona1 = new Persona('Juan');\n\nconsole.log('Operador de instancia');\nconsole.log(persona1 instanceof Persona); // Devuelve true, persona1 es una instancia de la clase Persona\nconsole.log(persona1 instanceof Object); // Devuelve true, todas las instancias son también objetos\nconsole.log(persona1 instanceof Array); // Devuelve false, persona1 no es una instancia de Array\nconsole.log('-----------------------');\n\n//**Tipos de esctructura en javascript */\n\n//**Estructura de control de flujo */\n// Operador ternario\n10 === 10 ? console.log('Ternaria respuesta 1') : console.log('Ternaria respuesta 2'); // Si la condicion es verdadera se ejecuta la primera expresión sino se ejecuta la segunda\n\n// if...else, es como el operador ternario, pero se ve de manera diferente, depende de para que se vaya a usar se recomienda usar uno o el otro\nif (10 === 10) {\n\tconsole.log('if respuesta');\n} else {\n\tconsole.log('else respuesta');\n}\n\n// switch\n\nlet diaSemana = 'Lunes';\n\nswitch (diaSemana) {\n\tcase 'Lunes':\n\t\tconsole.log('Es Lunes');\n\t\tbreak;\n\tcase 'Martes':\n\t\tconsole.log('Es Martes');\n\t\tbreak;\n\tcase 'Miercoles':\n\t\tconsole.log('Es Miercoles');\n\t\tbreak;\n\tcase 'Jueves':\n\t\tconsole.log('Es Jueves');\n\t\tbreak;\n\tcase 'Viernes':\n\t\tconsole.log('Es Viernes');\n\t\tbreak;\n\tcase 'Sabado':\n\t\tconsole.log('Es Sabado');\n\t\tbreak;\n\tcase 'Domingo':\n\t\tconsole.log('Es Domingo');\n\t\tbreak;\n\n\tdefault:\n\t\tconsole.log('El dia de la semana introducido no existe');\n\t\tbreak;\n}\n\n//**Bucles */\n//for\nconsole.log('Ciclo for');\nfor (let i = 0; i < 5; i++) {\n\tconsole.log(i);\n}\n\n//while\nlet num = 0;\nconsole.log('Ciclo while');\nwhile (num < 5) {\n  console.log(num);\n  num++;\n}\n\n//do...while\nlet count = 0;\nconsole.log('Ciclo do...while');\ndo {\n  console.log(count);\n  count++;\n} while (count < 5);\n\n//for...of\nconst array = [1, 2, 3, 4, 5];\nconsole.log('Ciclo for...of');\nfor (let elemento of array) {\n  console.log(elemento);\n}\n\n//for...in\nconst objeto = { a: 1, b: 2, c: 3 };\nconsole.log('Ciclo for...in');\nfor (let propiedad in objeto) {\n  console.log(propiedad + \": \" + objeto[propiedad]);\n}\n\n/*\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n */\nconsole.log('Números comprendidos entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3');\nfor (let i = 10; i < 55; i++) {\n   if(i % 2 == 0){\n      if (i != 16){\n         if (i % 3 != 0) {\n            console.log(i);\n         }\n      }\n   }\n   \n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/EricJoel-code.js",
    "content": "// Tipos de operadores en JavaScript\n\n//Operadores Aritméticos\n\nlet number = 10;\nlet number2 = 5;\n\nconsole.log(\"Suma: \" + (number + number2));\nconsole.log(\"Resta: \" + (5 - 3));\nconsole.log(\"Multiplicación: \" + (6 * 7));\nconsole.log(\"División: \" + (20 / 4));\nconsole.log(\"Módulo: \" + (10 % 3));\nconsole.log(\"Incremento: \" + (++number));\nconsole.log(\"Decremento: \" + (--number2));\nconsole.log(\"Potenciación: \" + (2 ** 3));\n\n//Operadores de Comparación\n\nconsole.log(\"Igualdad: \" + (2 == 2));\nconsole.log(\"Desigualdad: \" + (3 != 3))\nconsole.log(\"Mayor que: \" + (5 > 8));\nconsole.log(\"Menor que: \" + (8 < 10));\nconsole.log(\"Mayor o igual que: \" + (7 >= 7));\nconsole.log(\"Menor o igual que: \" + (4 <= 6));\n\n// Operadores Lógicos\n\nconsole.log(\"AND lógico: \" + (10 > 3 && 5 < 2));\nconsole.log(\"OR lógico: \" + (10 > 3 || 5 < 2));\nconsole.log(\"NOT lógico: \" + (!10 < 3));\n\n// Operadores de asignación\n\nlet x = 15;\n\nx += 5;\nconsole.log(\"Asignación con suma: \" + x);\n\nx -= 3;\nconsole.log(\"Asignación con resta: \" + x);\n\nx *= 2;\nconsole.log(\"Asignación con multiplicación: \" + x);\n\nx /= 4;\nconsole.log(\"Asignación con división: \" + x);\n\nx %= 6;\nconsole.log(\"Asignación con módulo: \" + x);\n\nconsole.log(\"Asignación con potenciación: \" + (x **= 2));\n\n// Operadores de cadena\n\nlet saludo = \"Hola, \";\nlet nombre = \"Mundo!\";\nlet mensajeCompleto = saludo + nombre;\nconsole.log(\"Concatenación de cadenas: \" + mensajeCompleto);\n\n// Operadores ternarios\n\nlet edad = 20;\nlet esAdulto = (edad >= 18) ? \"Sí, es adulto.\" : \"No, es menor de edad.\";\nconsole.log(\"Operador ternario: \" + esAdulto);\n\n// Operadores de tipo de dato\n\nconsole.log(\"Tipo de dato de '13': \" + (typeof 13));\nconsole.log(\"Tipo de dato de 'mensajeCompleto': \" + (typeof mensajeCompleto));\nconsole.log(\"Tipo de dato de 'true': \" + (typeof true));\n\n// Operadores de incremento y decremento\n\nlet contador = 0;\nconsole.log(\"Contador inicial: \" + contador);\ncontador++;\nconsole.log(\"Contador después de incrementar: \" + contador);\ncontador--;\nconsole.log(\"Contador después de decrementar: \" + contador);\n\n// Operadores de identidad\n\nlet a = 5;\nlet b = '5';\nlet identidad = a === b;\nconsole.log(\"¿a es idéntico a b?: \" + identidad);\n\n// Operadores de pertenencia\n\nlet arreglo = [1, 2, 3, 4, 5];\nconsole.log(\"¿El arreglo contiene el número 3?: \" + arreglo.includes(3));\nconsole.log(\"¿El arreglo contiene el número 6?: \" + arreglo.includes(6));\n\n// Operadores bit a bit\n\nlet bitA = 5;  // En binario: 0101\nlet bitB = 3;  // En binario: 0011\nconsole.log(\"AND bit a bit: \" + (bitA & bitB)); // Resultado: 0001 (1 en decimal)\nconsole.log(\"OR bit a bit: \" + (bitA | bitB)); // Resultado: 0111 (7 en decimal)\nconsole.log(\"XOR bit a bit: \" + (bitA ^ bitB)); // Resultado: 0110 (6 en decimal)  \n\n// Desplazamiento a la izquierda\nconsole.log(\"Desplazamiento a la izquierda: \" + (bitA << 1)); // Resultado: 1010 (10 en decimal)\n// Desplazamiento a la derecha\nconsole.log(\"Desplazamiento a la derecha: \" + (bitA >> 1)); // Resultado: 0010 (2 en decimal)\n// Desplazamiento a la derecha sin signo\nconsole.log(\"Desplazamiento a la derecha sin signo: \" + (bitA >>> 1)); // Resultado: 0010 (2 en decimal)    \n// Operador NOT bit a bit\nconsole.log(\"NOT bit a bit: \" + (~bitA)); // Resultado: 1010 (en complemento a dos, -6 en decimal)\n// Operador de negación bit a bit\nconsole.log(\"Negación bit a bit: \" + (~bitB)); // Resultado: 1100 (en complemento a dos, -4 en decimal)\n\n\n// Estructuras de control\n\n// Condicionales\n\nlet num = 7;\n\nif (num > 0) {\n    console.log(num + \" es un número positivo.\");\n} else if (num < 0) {\n    console.log(num + \" es un número negativo.\");\n} else {\n    console.log(\"El número es cero.\");\n}\n\n// Condicional switch\n\nlet dia = 3;\n\nswitch (dia) {\n    case 1:\n        console.log(\"Lunes\");\n        break;\n    case 2:\n        console.log(\"Martes\");\n        break;\n    case 3:\n        console.log(\"Miércoles\");\n        break;\n    case 4:\n        console.log(\"Jueves\");\n        break;\n    case 5:\n        console.log(\"Viernes\");\n        break;\n    case 6:\n        console.log(\"Sábado\");\n        break;\n    case 7:\n        console.log(\"Domingo\");\n        break;\n    default:\n        break;\n}\n\n// Bucles\n\n// Bucle for\n\nfor (let i = 1; i <= 5; i++) {\n    console.log(\"Iteración número: \" + i);\n}\n\n// Bucle while\n\nlet count = 1;\nwhile (count <= 5) {\n    console.log(\"Cuenta: \" + count);\n    count++;\n}\n\n// Bucle do...while\n\nlet conteo = 1;\ndo {\n    console.log(\"Conteo: \" + conteo);\n    conteo++;\n} while (conteo <= 3);\n\n// Bucle for...of\n\nlet frutas = [\"Manzana\", \"Platano\", \"Mango\"];\nfor (let fruta of frutas) {\n    console.log(\"Fruta: \" + fruta);\n}\n\n// Bucle for...in\n\nlet persona = { nombre: \"Joel\", edad: 23, ciudad: \"San Francisco\" };\nfor (let clave in persona) {\n    console.log(clave + \": \" + persona[clave])\n}\n\n// Manejo de Excepciones\ntry {\n    let resultado = 10 / 0;\n    if (!isFinite(resultado)) {\n        throw new Error(\"División por cero no permitida.\");\n    }\n    console.log(\"Resultado: \" + resultado);\n} catch (error) {\n    console.error(\"Error: \" + error.message);\n}\n\n/* \nCrea un programa que imprima por consola todos los números comprendidos entre 10 y 55 (incluidos) pares, y que no son ni el 16 ni múltiplos de 3.\n*/\n\nfor (let i = 10; i <= 55; i++) {\n    if (i % 2 == 0 && i != 16 && i % 3 != 0)\n        console.log(i);\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/Erysnell.js",
    "content": "// Aritméticos\nconsole.log(5 + 3);     \nconsole.log(7 - 2);      \nconsole.log(4 * 6);    \nconsole.log(9 % 4);      \n\n// Lógicos\nlet x = true;\nlet y = false;\n\nconsole.log(x && y);    \nconsole.log(x || y);    \nconsole.log(!x);         \n\n// Comparación\nconsole.log(5 > 3);      \nconsole.log(3 < 5);       \nconsole.log(5 >= 3);      \nconsole.log(3 <= 5);      \nconsole.log(5 == 3);      \nconsole.log(5 != 3);     \nconsole.log(5 === 3);     \nconsole.log(5 !== 3);     \n\n// Asignación\nlet z = 0;\nz += 5;              \nz -= 3;              \nz *= 2;              \nz /= 2;                \n\n// Identidad\nconsole.log(z === z);     \n\n// Pertenencia\nconst array = [1, 2, 3, 4, 5];\nconsole.log(array.includes(3)); \n\n// Bits\nconsole.log(5 & 3);       \nconsole.log(5 | 3);    \nconsole.log(~5);          \n\n// Condicionales\nif (true) {\n    console.log(\"Esta es una condición verdadera\");\n} else {\n    console.log(\"Esta es una condición falsa\");\n}\n\nswitch (2) {\n    case 1:\n        console.log(\"Es 1\");\n        break;\n    case 2:\n        console.log(\"Es 2\");\n        break;\n    default:\n        console.log(\"No es 1 ni 2\");\n}\n\n// Iterativas\nfor (let i = 0; i < 5; i++) {\n    console.log(i);\n}\n\nwhile (true) {\n    console.log(\"Este bucle mientras sea cierto\");\n    break;  // Para evitar un bucle infinito\n}\n\ndo {\n    console.log(\"Este bucle se ejecuta al menos una vez\");\n} while (false);\n\n// Excepciones\ntry {\n    throw new Error(\"Excepción lanzada intencionalmente\");\n} catch (error) {\n    console.error(error.message);\n}\n\nfunction isEven(num) {\n    return num % 2 === 0;\n}\n\nfunction isNotMultipleOfThree(num) {\n    return num % 3 !== 0;\n}\n\nfunction isNotSixteen(num) {\n    return num !== 16;\n}\n\nfor (let i = 10; i <= 55; i++) {\n    if (isEven(i) && isNotMultipleOfThree(i) && isNotSixteen(i)) {\n        console.log(i);\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/FabianRpv.js",
    "content": "// Tipos de operadores\n\n// Operadores aritméticos\n\nlet a = 2;\nlet b = 5;\n\nlet suma = a + b; // Suma\nconsole.log( a + \" + \" + b + \" = \" + suma);\n\nlet resta = a - b; // Resta\nconsole.log( a + \" - \" + b + \" = \" + resta);\n\nlet multiplicacion = a * b; // Multiplicación\nconsole.log( a + \" * \" + b + \" = \" + multiplicacion);\n\nlet division = a / b; // División\nconsole.log( a + \" / \" + b + \" = \" + division);\n\nlet modulo = a % b; // Módulo\nconsole.log( a + \" % \" + b + \" = \" + modulo);\n\nlet potencia = a ** b; // Potencia\nconsole.log( a + \" ** \" + b + \" = \" + potencia);\n\nlet incremento = a; // Incremento\nincremento++\nconsole.log(a + \"++ = \" + incremento);\n\nlet decremento = a; // Decremento\ndecremento--\nconsole.log( a + \"-- = \" + decremento);\n\n\n\n// Operadores lógicos\n\nconsole.log(true && true); // AND\nconsole.log(true && false);\n\nconsole.log(true || false); // OR\nconsole.log(false || false);\n\nconsole.log(!true); // NOT\nconsole.log(!false);\n\n\n\n// Operadores de comparacion\n\nconsole.log(a == b); // es igual a\nconsole.log(a != b); // es diferente a\nconsole.log(a > b); // es mayor que\nconsole.log(a >= b); // es mayor o igual que\nconsole.log(a < b); // es menor que\nconsole.log(a <= b); // es menor o igual que\n\n\n\n// Operadores de asignacion\n\nlet variable = 5; // Se asigna un valor de 5 a la variable\nconsole.log(\"variable = \" + variable);\n\nvariable += 5; // Se suma 5 a la variable\nconsole.log(\"variable más 5 = \" + variable);\n\nvariable -= 5; // Se resta 5 a la variable\nconsole.log(\"variable menos 5 = \" + variable);\n\nvariable *= 5; // Se multiplica por 5 a la variable\nconsole.log(\"variable por 5 = \" + variable);\n\nvariable /= 5; // Se divide por 5 a la variable\nconsole.log(\"variable entre 5 = \" + variable);\n\nvariable %= 5; // Se obtiene el módulo de la variable\nconsole.log(\"variable módulo 5 = \" + variable);\n\nvariable **= 5; // Se obtiene la potencia de la variable\nconsole.log(\"variable elevado a 5 = \" + variable);\n\n\n\n// Operadores de Identidad \n\nconsole.log(a === b); // es estrictamente igual a\nconsole.log(a !== b); // es estrictamente diferente a\n\n\n\n// Operadores de Pertenencia\n\nlet persona = {\n    nombre: \"Fabian\", \n    edad: 20\n};\n\nconsole.log(\"nombre\" in persona); // la propiedad existe en el objeto\nconsole.log(\"apellido\" in persona); // la propiedad no existe en el objeto\n\n\n\n// Operadores de Bits\n\nconsole.log(a & b); // AND\nconsole.log(a | b); // OR\nconsole.log(a ^ b); // XOR\nconsole.log(~a); // NOT\nconsole.log(a << b); // Desplazamiento a la izquierda\nconsole.log(a >> b); // Desplazamiento a la derecha\n\n\n\n// Operador Ternario\n\nlet edad = 20;\nedad >= 18 ? console.log(\"Eres mayor de edad\") : console.log(\"Eres menor de edad\");\n\n\n\n// Estructuras de control\n\n// Condicionales (if, else, else if, switch)\n\nlet condicion = true;\nlet condicion2 = false;\n\nif(condicion){\n\n    console.log(\"La primera condicion se cumple\");\n\n} else if(condicion2){\n\n    console.log(\"La segunda condicion se cumple\");\n\n} else {\n\n    console.log(\"Ninguna condicion se cumple\");\n\n}\n\nlet dia = 3;\n\nswitch(dia){\n\n    case 1:\n        console.log(\"Lunes\");\n        break;\n    case 2:\n        console.log(\"Martes\");\n        break;\n    case 3:\n        console.log(\"Miercoles\");\n        break;\n\n}\n\n\n// Iterativas (for, while, do while, for of, for in)\n\nfor(let i = 0; i <= 5; i++){\n\n    console.log(i);\n\n}\n\n\nlet i = 5;\n\nwhile(i >= 0){\n\n    console.log(i);\n    i--;\n\n}\n\n\ndo {\n\n    i++;\n    console.log(i);\n\n} while(i < 5);\n\n\nlet array = [1, 2, 3, 4, 5];\n\nfor (let numero of array){\n\n    console.log(numero);\n\n}\n\n\nfor(let datos in persona){\n\n    console.log(datos + \" : \" + persona[datos]);\n\n}\n\n\n// Excepciones(try, catch, throw,  finally)\n\ntry {\n    \n    if(edad < 18){\n\n        throw new Error(\"Eres menor de edad\");\n\n    }\n\n    console.log(\"Eres mayor de edad\");\n\n} catch (error) {\n   \n    console.log(error.message);\n    \n} finally {\n\n    console.log(\"Fin del bloque try-catch\");\n\n}\n\n\n/*\nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3. \n*/\n\nfor(let i = 10; i <= 55; i++){\n\n    if(i == 16){\n        continue;\n    }\n\n    if(i % 2 == 0 && i % 3 != 0){\n\n        console.log(i);\n\n    }\n\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/Facundo-Muoio.js",
    "content": "// Operador de asinacion (=)\nlet nombre = \"Facundo\";\nconsole.log(\"operador de asignacion\", nombre);\nconsole.log(\"operador de asignación de adición\", \"x += 1\");\nconsole.log(\"operador de asignación de resta\", \"x -= 1\");\nconsole.log(\"operador de asignación de multiplicacion\", \"x *= 2\");\nconsole.log(\"operador de asignación de division\", \"x /= 5\");\nconsole.log(\"operador de asignación de residuo\", \"x %= 2\");\nconsole.log(\"operador de asignación de exponenciación\", \"x **= 3\");\nconsole.log(\"operador de asignación de AND lógico\", \"x &&= y\");\nconsole.log(\"operador de asignación de division\", \"x ||= y\");\nconsole.log(\"operador de asignación de division\", \"x ??= y\");\n\n//operadores de comparación\nconsole.log(\"operador de igualdad\", 5 == 5);\nconsole.log(\"operador de desigualdad\", 4 != 5);\nconsole.log(\"operador de igualdad estricta\", 5 === \"5\");\nconsole.log(\"operador de desigualdad estricta\", 4 !== 3);\nconsole.log(\"operador mayor que\", 12 > 1);\nconsole.log(\"operador menor que\", 5 < 3);\nconsole.log(\"operador mayor igual que\", 15 >= 12);\nconosole.log(\"operador menor igual que\", 15 <= 12);\n\n//operadores aritméticos (+ - / * %)\nconsole.log(\"sum\", 5 + 5);\nconsole.log(\"rest\", 5 - 5);\nconsole.log(\"division\", 10 / 2);\nconsole.log(\"multiplication\", 10 * 2);\nconsole.log(\"power\", 10 ** 2);\nconsole.log(\"residue\", 10 % 2);\n\n//operadores lógicos\nconsole.log(\"AND\", true && true);\nconsole.log(\"OR\", true && false);\nconsole.log(\"NOT\", !true);\n\n//operador ternario\nconsole.log(\"operador ternario\", true ? true : false);\n\n//operadores uniarios\nconsole.log(\"operador unario typeof\", typeof \"Hola Mundo!\");\n\n//estucturas de control\nif (true) {\n\tconsole.log(\n\t\t\"esta condicion es true y por eso se ejectuca lo que esta dentro de este bloque\"\n\t);\n} else {\n}\n\nswitch (number) {\n\tcase 1:\n\t\tconsole.log(\n\t\t\t\"si la expresion evaluada es igual a uno se ejecuta este código\"\n\t\t);\n\t\tbreak;\n\tcase 20:\n\t\tconsole.log(\n\t\t\t\"si la expresion evaluada es igual a veinte se ejecuta este código\"\n\t\t);\n\t\tbreak;\n\tdefault:\n\t\tconsole.log(\n\t\t\t\"se ejecuta cuando la expresión evaluado no coincide con ninguno de los casos\"\n\t\t);\n}\n\n//bucles\nwhile (number < 10) {\n\tconsole.log(\n\t\t\"mientras la condicion evaluada sea verdadera ejecuta este código\"\n\t);\n}\n\ndo {\n\tlet i = 0;\n\ti++;\n\tconsole.log(\n\t\t\"realiza esta operacion hasta que la condicon while posterior se evalue como false\"\n\t);\n} while (number < 5);\n\nfor (var i = 0; i < 9; i++) {\n\tn += i;\n\tconsole.log(n);\n}\n\nfor (const property in object) {\n\tconsole.log(`${property}: ${object[property]}`);\n}\n\nfor (variable of iterable) {\n\tconsole.log(variable);\n}\n\n//extra point\n\nfor (let i = 10; i <= 55; i++) {\n\tif (i % 2 === 0 && i % 3 !== 0 && i !== 16) {\n\t\tconsole.log(i);\n\t}\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/FranciscoCuminiLondero.js",
    "content": "/*\n----------\nOPERADORES\n----------\n*/\n\n// Operadores Aritméticos (+,-,*,/,%)\nlet num1 = 15;\nlet num2 = 5;\n\nlet suma = num1 + num2;\nlet resta = num1 - num2;\nlet multiplicacion = num1 * num2;\nlet division = num1 / num2;\nlet resto = num1 % num2;\nlet exponencial = num1 ** num2;\n\nconsole.log(`Operadores Aritméticos:\n  Suma: ${num1} + ${num2} = ${suma}\n  Resta: ${num1} - ${num2} = ${resta}\n  Multiplicación: ${num1} * ${num2} = ${multiplicacion}\n  División: ${num1} / ${num2} = ${division}\n  Resto de ${num1} dividido ${num2} es ${resto}\n  Exponencial: ${num1} ** ${num2} = ${exponencial}\n  `);\n// Operadores Lógicos (||, &&, !)\nlet x = true;\nlet y = false;\nlet z = true;\n\nlet logico1 = x && y && z;\nlet logico2 = x || y || z;\nlet logico3 = ((x || !y) && z) || (!x && z);\n\nconsole.log(`Operadores Lógicos:\n  Ejemplo 1: ${x} AND ${y} AND ${z} = ${logico1}\n  Ejemplo 2: ${x} OR ${y} OR ${z} = ${logico2}\n  Ejemplo 3: (${x} OR NOT ${y}) AND ${z} OR (NOT ${x} AND ${z}) = ${logico3}\n  `);\n\n// Operadores de Comparación (<, <=, >=, >, ==, ===, !=, !==)\nlet n1 = 16;\nlet n2 = 8;\nlet n3 = \"16\";\n\nlet comparacion1 = n1 > n2;\nlet comparacion2 = n1 < n2;\nlet comparacion3 = n1 >= n2;\nlet comparacion4 = n1 <= n2;\nlet comparacion5 = n1 == n3;\nlet comparacion6 = n1 != n3;\nlet comparacion7 = n1 === n3;\nlet comparacion8 = n1 !== n3;\n\nconsole.log(`Operadores de comparación:\n  ${n1} > ${n2} → ${comparacion1}\n  ${n1} < ${n2} → ${comparacion2}\n  ${n1} >= ${n2} → ${comparacion3}\n  ${n1} <= ${n2} → ${comparacion4}\n  ${n1} == \"${n3}\" → ${comparacion5}\n  ${n1} != \"${n3}\" → ${comparacion6}\n  ${n1} === \"${n3}\" → ${comparacion7}\n  ${n1} !== \"${n3}\" → ${comparacion8}\n  `);\n\n// Operadores de Asignación (=, +=, -=, *=, /=, %=, **=)\nconsole.log(\"Operadores de asignación: \");\nlet mi_asignacion = 11; // = → asignación\nconsole.log(`  Asignación '=' => ${mi_asignacion}`);\n\nmi_asignacion += 1; // += → suma y asiganción\nconsole.log(`  Suma y Asignación '+=' => ${mi_asignacion}`);\n\nmi_asignacion -= 5; // -= → resta y asignación\nconsole.log(`  Resta y asignación '-=' => ${mi_asignacion}`);\n\nmi_asignacion *= 2; // *= → multiplicación y asignación\nconsole.log(`  Multiplicación y asignación '*=' => ${mi_asignacion}`);\n\nmi_asignacion /= 2; // /= → división y asignación\nconsole.log(`  División y asignación '/=' => ${mi_asignacion}`);\n\nmi_asignacion %= 2; // %= → módulo y asignación\nconsole.log(`  Módulo y asignación '%=' => ${mi_asignacion}`);\n\nmi_asignacion **= 2; // **= → exponente y asignación\nconsole.log(`  Exponente y asignación '**=' => ${mi_asignacion}`);\n\nconsole.log(\" \");\n\n// Operadores bit a bit\nlet var1 = 10; // 1010\nlet var2 = 3; // 0011\n\nlet opeacionBit1 = var1 & var2; // 0010 - Si ambos son 1\nlet opeacionBit2 = var1 | var2; // 1011 - Si almenos 1 es 1\nlet opeacionBit3 = var1 ^ var2; // 1001 -  Si los bits son diferentes 0 si son iguales 1\nlet opeacionBit4 = ~var1; // 0101 -  Invierte el valor bit a bit\nlet opeacionBit5 = var1 >> 2; // 1010 → 0101 → 0010\nlet opeacionBit6 = var1 << 2; // 1010 → 101000\n\nconsole.log(`Operadores bit a bit\n  AND: ${var1} & ${var2} = ${opeacionBit1}\n  OR: ${var1} | ${var2} = ${opeacionBit2}\n  XOR: ${var1} ^ ${var2} = ${opeacionBit3}\n  NOT: ~${var1} = ${opeacionBit4}\n  Desplazamiento a la derecha: ${var1} >> 2= ${opeacionBit5}\n  Desplazamiento a la izquierda: ${var1} << 2 = ${opeacionBit6}\n  `);\n\n/*\n----------------------\nESTRUCTURAS DE CONTROL\n----------------------\n*/\n\n//Estructuras de control: condicionales (if - if/else - if/else if/else), bucles (for - while - do while, switch)\n\n//Condicionales\nconsole.log(\"Condicionales If - Else If - Else\");\nconst MAYORIA_EDAD = 18;\nlet edad_persona = 23;\n\nif (edad_persona < 0 || edad_persona > 120) {\n  console.log(`Edad inexistene, ingrese un valor correcto`);\n} else if (edad_persona < MAYORIA_EDAD) {\n  console.log(`Con ${edad_persona} años sos menor de edad`);\n} else {\n  console.log(`Con ${edad_persona} años sos mayor de edad`);\n}\n\n//Switch\nconsole.log(\" \");\nconsole.log(\"Switch\");\n\nlet opcion = 2;\n\nswitch (opcion) {\n  case 1:\n    console.log(\"Opción 1\");\n    break;\n  case 2:\n    console.log(\"Opción 2\");\n    break;\n  case 3:\n    console.log(\"Opción 3\");\n    break;\n\n  default:\n    console.log(\"Debes ingresar una de las 3 opciones\");\n    break;\n}\n\n//Bucle For\nconsole.log(\" \");\nconsole.log(\"Bucle For\");\nfor (let i = 0; i < 10; i++) {\n  console.log(`i = ${i}`);\n}\n\n//Bucle While\nconsole.log(\" \");\nconsole.log(\"Bucle While\");\nlet j = 10;\nwhile (j > 5) {\n  console.log(`j = ${j}`);\n  j--;\n}\n\n//Bucle Do-while\nconsole.log(\" \");\nconsole.log(\"Bucle Do-While\");\nlet tiene_permiso = false;\n\ndo {\n  console.log(\"No tienes permiso\");\n  //Usando variables anteriormente creadas\n  if (edad_persona > MAYORIA_EDAD) {\n    tiene_permiso = true;\n    console.log(\"Ahora si tienes permiso\");\n  }\n} while ((tiene_permiso = false));\n\n// DIFICULTAD EXTRA\nconsole.log(\" \");\nconsole.log(\"EJERCICIO EXTRA:\");\nfor (let i = 10; i <= 55; i++) {\n  if (i % 2 === 0 && i != 16 && i % 3 !== 0) {\n    console.log(i);\n  }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/Gianbordon.js",
    "content": "/********************************\n**** OPERADORES ARITMETRICOS ****\n*********************************/\n\n// Suma \nconsole.log(`La suma de 4 + 4 es igual a: ${4+4}`);\n// Resta \nconsole.log(`La resta de 10 - 7 es igual a: ${10-7}`);\n// Multiplicacion \nconsole.log(`La multiplicacion de 3 * 9 es igual a: ${3 * 9}`);\n// Division \nconsole.log(`La division de 25 / 5 es igual a: ${25 / 5}`);\n// Resto \nconsole.log(`El resto de la division de 36 / 4 es igual a: ${36 % 4}`);\n// Incremento \nlet num = 4;\nconsole.log(`El incremento de 4 es: ${++num}`);\n// Decremento\nlet numII = 8;\nconsole.log(`El decremento de 8 es: ${--numII}`);\n\n/**********************************\n**** OPERADORES de comparación ****\n***********************************/\n\n// Igualdad \nconsole.log(`El numero 25 es igual a 15 ? ${25==15}`);\n// Desigualdad \nconsole.log(`El numero 25 no es igual a 15 ? ${25!=15}`);\n// Mayor que  \nconsole.log(`El numero 25 es mayor que 15 ? ${25>15}`);\n// Mayor o Igual que  \nconsole.log(`El numero 25 es mayor o Igual que 15 ? ${25>=15}`);\n// Menor que  \nconsole.log(`El numero 25 es menor que 25 ? ${25<15}`);\n// Menor o Igual que  \nconsole.log(`El numero 25 es menor o igual que 15 ? ${25<=15}`);\n\n/*******************************\n****** OPERADORES LOGICOS ******\n********************************/\n\n// AND \nconsole.log(`true && false : ${true && false}`);\nconsole.log(`true && true : ${true && true}`),\nconsole.log(`false && true : ${false && true}`);\nconsole.log(`false && false : ${false && false}`);\n// OR \nconsole.log(`true || false : ${true || false}`);\nconsole.log(`true || true : ${true || true}`);\nconsole.log(`false || true : ${false || true}`);\nconsole.log(`false || false : ${false || false}`);\n// NOT \nconsole.log(`!false : ${!false}`);\nconsole.log(`!true : ${!true}`);\n\n/*************************************\n****** OPERADORES de ASIGNACION ******\n**************************************/\n\nlet numIII = 10;\n\n// Asignacion de sumna\nconsole.log(`Le sumo 1 a mi numIII: ${numIII += 1}`);\n// Asignacion de resto\nconsole.log(`Ahora le resto 2 a mi numIII: ${numIII -= 2}`);\n// Asignacion de multiplicacion\nconsole.log(`Seguido lo multiplico * 4 a mi numIII: ${numIII *= 4}`);\n// Asignacion de division\nconsole.log(`Tambien lo divido por 2 a mi numIII: ${numIII /= 2}`);\n// Asignacion de resto\nconsole.log(`Por ultimo busco el resto de mi numIII por 4: ${numIII %= 4}`);\n\n/*************************************\n****** OPERADORES de IDENTIDAD *******\n**************************************/\n\nlet a = \"4\";\nlet b = 4;\n\nconsole.log(`La varibale a es igual a la variable b: ${a===b}`);\nconsole.log(`La variable a es distinta a la variable b: ${a !==b}`);\n\n/***************************************\n****** OPERADORES de PERTENENCIA *******\n****************************************/\n\nconsole.log(`El numero 8 esta en [0,1,2,3,4,5,6,7,8,9] : ${8 in [0,1,2,3,4,5,6,7,8,9]}`);\nconsole.log(`El numero 10 esta en [0,1,2,3,4,5,6,7,8,9] : ${10 in [0,1,2,3,4,5,6,7,8,9]}`);\n\n/*******************************\n****** OPERADORES de BIT *******\n********************************/\n\nlet c = 8;\nlet d = 12;\n\nconsole.log(`AND : 8 & 12 = ${8 & 12}`)\nconsole.log(`OR : 8 | 12 = ${8 | 12}`)\nconsole.log(`XOR : 8 ^ 12 = ${8 ^ 12}`)\nconsole.log(`NOT : ~8 = ${~8}`)\nconsole.log(`Desplazamiento a la derecha  : 8 >> 12 = ${8 >> 12}`)\nconsole.log(`Desplazamineto a la izquierda : 8 << 12 = ${8 << 12}`)\n\n/***********************************\n****** ESTRUCTURA DE CONTROL *******\n***********************************/\n\n/*---------------------------------\n--------------- IF ----------------\n----------------------------------*/\n\nlet clima = \"lluvia\";\n\nif (clima == \"sol\"){\n    console.log(\"El clima de hoy es soleado\")\n} else if (clima == \"lluvia\"){\n    console.log(\"El clima para hoy es de lluvia\")\n}\n\n\n/*-------------------------------------\n--------------- SWITCH ----------------\n-------------------------------------*/\n\nlet estacion = \"primavera\";\n\nswitch(estacion){\n    case \"otoño\": \n        console.log(\"Estamos en Otoño todo parece mas marron\");\n        break;\n    case \"invierno\":\n        console.log(\"Llego el invierno el azul nos predomina\");\n        break;\n    case \"primavera\" :\n        console.log(\"Momento de floreces con el color amarillo\");\n        break;\n    case \"verano\":\n        console.log(\"El verano esta aqui y con él el naranja se apodera del cielo\");\n        break;\n    default:\n        console.log(\"No conozco esa estacion, creo que esta un poco gris\");\n        break;\n}\n\n/*-------------------------------------\n--------------- FOR -------------------\n-------------------------------------*/\n\nlet array = [0,1,2,3,4,5,6,7,8,9];\n\nfor (let index = 0; index < array.length; index++) {\n    const element = array[index];\n    console.log (`Elemento = ${element}`);\n};\n\n\n/*-------------------------------------\n--------------- WHILE -----------------\n-------------------------------------*/\n\nlet cant = 0;\n\nwhile (cant < 3) {\n    console.log(\"La cantidad es\", cant)\n    cant++;\n}\n\n\n/*-------------------------------------\n--------------- DO WHILE --------------\n-------------------------------------*/\n\nlet cont = 0\n\ndo {\n    console.log(\"La cantidad es\", cont)\n    cont++;\n} while (cont < 3);\n\n/*-------------------------------------\n--------------- TRY CATCH -------------\n-------------------------------------*/\n\ntry {\n    let resultado = 10 / 0;\n    console.log(\"El resultado es\", resultado);\n} catch (error) {\n    console.log(\"Ocurrió un error:\", error.message);\n} finally {\n    console.log(\"Esto se ejecuta siempre, haya o no error\");\n}\n\n// ------------- EJERCICIO EXTRA ---------------- //\n\nfor (let i = 10; i <= 55; i++) {\n    if ((i % 2 == 0) && (i !== 16) &&(i % 3 !== 0)) {\n        console.log(i)\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/Glitzypanic.js",
    "content": "// OPERADORES ARITMÉTICOS\nvar a = 2;\nvar b = 3;\n\nconsole.log(a + b); // Suma\nconsole.log(a - b); // Resta\nconsole.log(a * b); // Multiplicación\nconsole.log(a / b); // División\nconsole.log(a % b); // Módulo\nconsole.log(a ** b); // Potencia\nconsole.log(++a); // Incremento\nconsole.log(--a); // Decremento\n\n// OPERADORES DE ASIGNACIÓN\nvar numero = 5;\nconsole.log(numero); // Asignación\n\nnumero += 3;\nconsole.log(numero); // Asignación de suma\n\nnumero -= 3;\nconsole.log(numero); // Asignación de resta\n\nnumero *= 3;\nconsole.log(numero); // Asignación de multiplicación\n\nnumero /= 3;\nconsole.log(numero); // Asignación de división\n\nnumero %= 3;\nconsole.log(numero); // Asignación de módulo\n\nnumero **= 3;\nconsole.log(numero); // Asignación de potencia\n\n// OPERADORES DE CADENAS DE STRING\nvar nombreCompleto = \"José\" + \" \" + \"Daniel\" + \" \" + \"Farías\" + \" \" + \"Cordoba\";\nconsole.log(nombreCompleto); // Concatenación\n\n// OPERADORES DE COMPARACIÓN\nconsole.log(2 == 3); // False\nconsole.log(\"2\" == 2); // True\n\nconsole.log(2 != 4); // True\nconsole.log(2 != \"2\"); // False\n\nconsole.log(2 === 2); // True\nconsole.log(2 === \"2\"); // False\n\nconsole.log(1 !== 2); // True\nconsole.log(2 !== \"2\"); // True\n\nconsole.log(2 > 3); // False\nconsole.log(5 > 6); // False\n\nconsole.log(2 >= 3); // False\nconsole.log(2 >= 2); // True\n\nconsole.log(2 < 3); // True\nconsole.log(2 < 2); // False\n\nconsole.log(2 <= 3); // True\nconsole.log(2 <= 2); // True\n\n// OPERADORES LÓGICOS\nconsole.log(true && true); // True\nconsole.log(true && false); // False\n\nconsole.log(true || true); // True\nconsole.log(true || false); // True\n\nconsole.log(!true); // False\nconsole.log(!false); // True\n\n// OPERADORES BITWISE\nvar num1 = 5; // 101\nvar num2 = 3; // 011\nconsole.log(num1 & num2); // 001\nconsole.log(num1 | num2); // 111\nconsole.log(num1 ^ num2); // 110\nconsole.log(~num1); // 010\nconsole.log(num1 << 1); // 1010\nconsole.log(num1 >> 1); // 10\n\n// OPERADORES ESPECIALES\nlet result = 200 > 100 ? \"Es mayor\" : \"Es menor\";\nconsole.log(result); // Es mayor\n\nconsole.log(typeof 2); // Number\nconsole.log(typeof \"2\"); // String\nconsole.log(typeof true); // Boolean\nconsole.log(typeof {}); // Object\nconsole.log(typeof []); // Object\nconsole.log(typeof null); // Object\nconsole.log(typeof undefined); // Undefined\nconsole.log(typeof function () {}); // Function\n\n// OPERADOR OBJETO\nvar persona = {\n  nombre: \"José\",\n  apellido: \"Farías\",\n  edad: 25,\n};\nconsole.log(persona.edad); // 25\nconsole.log(persona.nombre); // José\n\n// ESTRUCTURAS DE CONTROL\nvar edad = 25;\n\nif (edad >= 18) {\n  console.log(\"Acceso permitido\");\n} else if (edad >= 18) {\n  console.log(\"Acceso permitido\");\n} else {\n  console.log(\"Acceso denegado\");\n}\n\nvar i = 0;\n\nwhile (i <= 10) {\n  console.log(i);\n  i++;\n}\n\nfor (var i = 0; i <= 11; i++) {\n  console.log(i);\n}\n\n// EJERCICIO\nfor (var i = 10; i <= 56; i++) {\n  if (i % 2 == 0 && i != 16 && i % 3 != 0) {\n    console.log(i);\n  }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/HaryBlanco20.js",
    "content": "let x = 10;\nlet y = 5;\n\nlet suma = x + y; // Suma: 15\nlet resta = x - y; // Resta: 5\nlet multiplicacion = x * y; // Multiplicación: 50\nlet division = x / y; // División: 2\nlet modulo = x % y; // Módulo: 0\nlet incremento = ++x; // Incremento: 11\nlet decremento = --y; // Decremento: 4\n\n// Estructura de control: if-else\nif (x > y) {\n    console.log(\"x es mayor que y\");\n} else {\n    console.log(\"x no es mayor que y\");\n}\n\n// Estructura de control: switch\nlet day = \"Monday\";\nswitch (day) {\n    case \"Monday\":\n        console.log(\"Today is Monday\");\n        break;\n    case \"Tuesday\":\n        console.log(\"Today is Tuesday\");\n        break;\n    case \"Wednesday\":\n        console.log(\"Today is Wednesday\");\n        break;\n    default:\n        console.log(\"Today is not Monday, Tuesday, or Wednesday\");\n}\n\n// Estructura de control: for loop\nfor (let i = 0; i < 5; i++) {\n    console.log(\"Iteration: \" + i);\n}\n\n// Estructura de control: while loop\nlet i = 0;\nwhile (i < 5) {\n    console.log(\"Iteration: \" + i);\n    i++;\n}\n\n// Estructura de control: do-while loop\nlet j = 0;\ndo {\n    console.log(\"Iteration: \" + j);\n    j++;\n} while (j < 5);\n\n// Estructura de control: for...in loop\nconst person = {\n    name: \"Hary\",\n    age: 34,\n    city: \"New York\"\n};\nfor (let key in person) {\n    console.log(key + \": \" + person[key]);\n}\n\n// Estructura de control: for...of loop\nconst fruits = [\"manzana\", \"pera\", \"naranja\"];\nfor (let fruit of fruits) {\n    console.log(fruit);\n}\n\n// Estructura de control: try-catch\ntry {\n    // Code that may throw an error\n    throw new Error(\"Tienes un error\");\n} catch (error) {\n    console.log(\"Error: \" + error.message);\n}\n\n// Estructura de control: try-catch-finally\ntry {\n    // Code that may throw an error\n    throw new Error(\"Tienes un error\");\n} catch (error) {\n    console.log(\"Error: \" + error.message);\n} finally {\n    console.log(\"El bloque de código ha finalizado\");\n}\n\n\n//Dificultad extra\n\nfor(let i= 10; i<=55;i++){\n    if(i % 2 === 0 && i !== 16 && i % 3 !== 0){\n        console.log(i)\n    }\n}\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/HectorIglesias.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n//OPERADORES ARITMÉTICOS\nlet x = 5\nlet y = 5\nlet resultado = 0\n\n//Operador de asignación  =\n//Operador de suma +\nresultado = x + y \nconsole.log(x +\"+\"+ y +\"=\"+resultado)\n//Operador de resta -\nresultado = x - y\nconsole.log(x +\"-\"+ y +\"=\"+resultado)\n//Operador de multiplicación * \nresultado = x * y\nconsole.log(x +\"*\"+ y +\"=\"+resultado)\n//Operador de división (/) y del resto de la división(%)\nresultado = x / y\nconsole.log(x +\"-\"+ y +\"=\"+resultado)\nresultado = x % y\nconsole.log(\"El resto de esta división es \"+resultado)\n//Operador de exponenciación\nresultado = x**y\nconsole.log(x +\" elevado a \"+ y +\" es \"+resultado)\n\n//OPERADORES DE COMPARACIÓN\n\n//Operadores de igualdad == != === !==\nconsole.log(x == y)\nconsole.log(x != y)\nconsole.log(x === y)\nconsole.log(x !== y)\n//Operador mayor que >\nconsole.log(x > y)\n//Operador mayor o igual que >=\nconsole.log(x >= y)\n//Operador menor que <\nconsole.log(x < y)\n//Operador menor o igual que <=\nconsole.log(x <= y)\n\n//OPERADORES DE BITS\n\n//Operador AND a nivel de bits &\nresultado = x & y\nconsole.log(x +\"&\"+ y + \" a nivel de BITS es \"+resultado)\n//Operador OR a nivel de bits |\nresultado = x | y\nconsole.log(x +\"|\"+ y + \" a nivel de BITS es \"+resultado)\n//Operador XOR a nivel de bits ^\nresultado = x ^ y\nconsole.log(x +\"^\"+ y + \" a nivel de BITS es \"+resultado)\n//Operador NOT a nivel de bits ~\nresultado =  ~y\nconsole.log(\"~\"+ y + \" a nivel de BITS es \"+resultado)\n//Operador de desplazamiento hacia la derecha\nresultado = x >> 1\nconsole.log(\"Desplazamiento hacia la derecha \"+resultado)\n//Operador de desplazamiento hacia la derecha\nresultado = x << 1\nconsole.log(\"Desplazamiento hacia la izquierda \"+resultado)\n\n//OPERADORES LÓGICOS \nlet bool1 = true\nlet bool2 = false\n//AND lógico &&\nconsole.log(bool1 && bool2)\n//OR lógico ||\nconsole.log(bool1 || bool2)\n//NOT lógico !\nconsole.log(!bool1, !bool2)\n\n//OPERADORES DE PERTENENCIA\nlet array = [0, 1, 2, 3, 4, 5]\nlet found = 3 in array\nconsole.log(found)\nlet not_found = 9 in array\nconsole.log(not_found)\n\n\n//ESCTRUCTURAS DE CONTROL\n\n//IF-ELSE\nlet num = 1\n\nif(num > 0)\n    console.log(\"El número \" +num+ \" es mayor que 0\")\nelse if (num < 0)\n    console.log(\"El número \" +num+ \" es menor que 0\")\nelse\nconsole.log(\"El número es 0\")\n\n//SWITCH\nswitch(num){\n    case 1:\n        console.log(\"El número es 1\")\n    case 2:\n        console.log(\"El número es 2\")\n    case 3:\n        console.log(\"El número es 3\")\n    default:\n        console.log(\"El número es distinto a 1, 2 o 3\")\n}\n\n//FOR\nlet array2 = [\"hola\", \" \", \"mundo\"]\nfor(let i=0; i<array2.length; i++){\n    console.log(array2[i])\n}\n\n//WHILE\nlet num2 = 0\n\nwhile(num2 < 5){\n    console.log(num2)\n    num2 = num2 + 1\n}\n\n//DO WHILE\nlet num3 = 0\n\ndo{\n    console.log(num3)\n    num3 = num3 + 1\n}while (num3 < 5)\n\n//EXCEPCIONES\nlet var3 = 5\n\ntry {\n    if (var3 === 5) {\n        throw new Error(\"El número es igual a 5\")\n    }\n    console.log('El número es distinto de 5')\n} catch (error) {\n    console.log(`Se ha producido un error debido a -> ${error.message}`)\n}\n\nconsole.log('\\nBloque try-catch-finally')\ntry {\n    if (var3 === 5) {\n        throw new Error(\"El número es igual a 5\")\n    }\n    console.log(\"El número es distinto de 5\")\n} catch (error) {\n    console.log(\"Se ha producido un error debido a \"+error.message)\n} finally {\n    console.log(\"Bloque finally. Esto siempre se ejecuta haya o no excepción\")\n}\n\n//DIFICULTAD EXTRA\nfor(let i= 10; i <= 55; i++){\n    if (i % 2 == 0){\n        if((i != 16) && (i % 3 != 0)){\n            console.log(i)\n        }\n    }\n    if(i == 55){\n            console.log(i)\n        }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/HugoLuquePerez.js",
    "content": "\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n// Aritméticos\nconsole.log(5 + 3);     \nconsole.log(7 - 2);      \nconsole.log(4 * 6);    \nconsole.log(9 % 4);      \n\n// Lógicos\nlet x = true;\nlet y = false;\n\nconsole.log(x && y);    \nconsole.log(x || y);    \nconsole.log(!x);         \n\n// Comparación\nconsole.log(5 > 3);      \nconsole.log(3 < 5);       \nconsole.log(5 >= 3);      \nconsole.log(3 <= 5);      \nconsole.log(5 == 3);      \nconsole.log(5 != 3);     \nconsole.log(5 === 3);     \nconsole.log(5 !== 3);     \n\n// Asignación\nlet z = 0;\nz += 5;              \nz -= 3;              \nz *= 2;              \nz /= 2;                \n\n// Identidad\nconsole.log(z === z);     \n\n// Pertenencia\nconst array = [1, 2, 3, 4, 5];\nconsole.log(array.includes(3)); \n\n// Bits\nconsole.log(5 & 3);       \nconsole.log(5 | 3);    \nconsole.log(~5);          \n\n// Condicionales\nif (true) {\n    console.log(\"Esta es una condición verdadera\");\n} else {\n    console.log(\"Esta es una condición falsa\");\n}\n\nswitch (2) {\n    case 1:\n        console.log(\"Es 1\");\n        break;\n    case 2:\n        console.log(\"Es 2\");\n        break;\n    default:\n        console.log(\"No es 1 ni 2\");\n}\n\n// Iterativas\nfor (let i = 0; i < 5; i++) {\n    console.log(i);\n}\n\nwhile (true) {\n    console.log(\"Este bucle mientras sea cierto\");\n    break;  // Para evitar un bucle infinito\n}\n\ndo {\n    console.log(\"Este bucle se ejecuta al menos una vez\");\n} while (false);\n\n// Excepciones\ntry {\n    throw new Error(\"Excepción lanzada intencionalmente\");\n} catch (error) {\n    console.error(error.message);\n}\n\nfunction isEven(num) {\n    return num % 2 === 0;\n}\n\nfunction isNotMultipleOfThree(num) {\n    return num % 3 !== 0;\n}\n\nfunction isNotSixteen(num) {\n    return num !== 16;\n}\n\nfor (let i = 10; i <= 55; i++) {\n    if (isEven(i) && isNotMultipleOfThree(i) && isNotSixteen(i)) {\n        console.log(i);\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/JELozanoV.js",
    "content": "\n//Operadores aritmeticos \n\nlet suma = 1 + 1;\nlet resta = 1 - 1;\nlet multiplicacion = 1 * 1;\nlet division = 1 / 1;\nlet resto = 2 % 2;\nconsole.log(suma);\nconsole.log(resta);\nconsole.log(multiplicacion);\nconsole.log(division);\nconsole.log(resto);\n\n// Operadores logicos \n\n//      &&\nlet esVerdadreoAND = true && true\nlet esFalsoAND = true && false\nlet esFalsoAND2 = false && true;\nlet esFalsoAND3 = false && false;\nconsole.log(esVerdadreoAND);\nconsole.log(esFalsoAND);\nconsole.log(esFalsoAND2);\nconsole.log(esFalsoAND3);\n//     || \nlet esVerdaderoOR = true || true;\nlet esFalsoOR = true || false;\nlet esFalsoOR2 = false || true;\nlet esFalsoOR3 = false || false;\nconsole.log(esVerdaderoOR);\nconsole.log(esFalsoOR);\nconsole.log(esFalsoOR2);\nconsole.log(esFalsoOR3);\n//     ! \nlet falsoInvertido = !true;\nlet verdaderoInvertido = !false\nconsole.log(falsoInvertido);\nconsole.log(verdaderoInvertido);\n\n//De comparacion\n\n/* Igualdad (==) */\nconsole.log(5 == 5);       // true\nconsole.log('5' == 5);     // true (coerción de tipo)\nconsole.log(5 == '5');     // true (coerción de tipo)\nconsole.log(5 == 10);      // false\n\n/* Igualdad estricta (===) */\nconsole.log(5 === 5);      // true\nconsole.log('5' === 5);    // false\nconsole.log(5 === '5');    // false\n\n/* Desigualdad (!=) */\nconsole.log(5 != 10);      // true\nconsole.log(5 != '5');     // false (coerción de tipo)\n\n\n/* Desigualdad estricta (!==) */\nconsole.log(5 !== '5');    // true\nconsole.log(5 !== 5);      // false\n\n/* Mayor que (>) */\nconsole.log(10 > 5);       // true\n\n/* Menor que (<) */\nconsole.log(5 < 10);       // true\n\n/* Mayor o igual que (>=) */\nconsole.log(10 >= 10);     // true\n\n/* Menor o igual que (<=) */\nconsole.log(5 <= 10);      // true\n\n\n/* De asignacion (=) */\nvar variableVar = \"Variable\" // asigna una variable string \nvariableVar = 1 // Reasigna a una variable number \n\n//Suma y asignacón \nvariableVar += 1 // === variableVar = variableVar + 1\n\n//Resta y asignacion \nvariableVar -= 1\n\n/* De identidad */\nconst objeto1 = { nombre: 'Juan' };\nconst objeto2 = { nombre: 'Juan' };\nconst objeto3 = objeto1;\n\nconsole.log(objeto1 === objeto2);\nconsole.log(objeto1 === objeto3);\n\n\n/* De pertenencia */\n\n//Operador (in) en objetos \nconst persona1 = {\n  nombre: \"Sofia\",\n  edad: 30\n}\nconsole.log('nombre' in persona1);  // true\nconsole.log('apellido' in persona1);  // false\nconsole.log(!('nombre' in persona1));   // false, ya que 'nombre' sí está presente en persona1\nconsole.log(!('apellido' in persona1)); // true, ya que 'apellido' no está presente en persona1\n\n//operador (in) en arrays \nconst deportes = [\"F1\", \"Moto Gp\", \"Motocross\"]\nconsole.log(0 in deportes); //true\nconsole.log(!(0 in deportes)); //false\nconsole.log(3 in deportes); //false\nconsole.log(!(3 in deportes)); //true\n// operador instanceof \nclass Animal {\n  sonido() {\n    console.log('Hace algún sonido');\n  }\n}\n\nclass Perro extends Animal {\n  ladrar() {\n    console.log('Guau guau');\n  }\n}\n\nconst miPerro = new Perro();\n\nconsole.log(miPerro instanceof Perro);  // true\nconsole.log(miPerro instanceof Animal);  // true\nconsole.log(miPerro instanceof Object);  // true, ya que todos los objetos son instancias de Object\n\n/* Operadores de bits */\n\n// AND     & \nvar num1 = 5; // Representación binaria: 0101\nvar num2 = 3; // Representación binaria: 0011\nvar resultado = num1 & num2; // Resultado: 0001 (1 en decimal)\nconsole.log(resultado); // Imprime 1\n\n// OR     |\nvar num3 = 5; // Representación binaria: 0101\nvar num4 = 3; // Representación binaria: 0011\nvar resultado = num3 | num4; // Resultado: 0111 (7 en decimal)\nconsole.log(resultado); // Imprime 7\n\n// XOR     ^\nvar num5 = 5; // Representación binaria: 0101\nvar num6 = 3; // Representación binaria: 0011\nvar resultado = num5 ^ num6; // Resultado: 0110 (6 en decimal)\nconsole.log(resultado); // Imprime 6\n\n// NOT     ~\nvar num = 5; // Representación binaria: 0000 0000 0000 0000 0000 0000 0000 0101\nvar resultado = ~num; // Resultado: 1111 1111 1111 1111 1111 1111 1111 1010 (-6 en decimal)\nconsole.log(resultado); // Imprime -6\n\n// Desplazamiento derecha e izquierda     <<    >>\nvar num = 5; // Representación binaria: 0101\nvar resultadoIzquierda = num << 1; // Desplazamiento a la izquierda por 1: 1010 (10 en decimal)\nvar resultadoDerecha = num >> 1; // Desplazamiento a la derecha por 1: 0010 (2 en decimal)\nconsole.log(resultadoIzquierda); // Imprime 10\nconsole.log(resultadoDerecha); // Imprime 2\n\n/* Extructuras de control */\n\n// if - else\nlet edad = 20;\n\nif (edad >= 18) {\n  console.log(\"Eres mayor de edad\");\n} else {\n  console.log(\"Eres menor de edad\");\n}\n\n// if - else if - else \nlet nota = 85;\n\nif (nota >= 90) {\n  console.log(\"Excelente\");\n} else if (nota >= 70) {\n  console.log(\"Aprobado\");\n} else {\n  console.log(\"Reprobado\");\n}\n\n//Bucle while \nlet contador = 0\nwhile (contador < 10) {\n  console.log(`El contador es ${contador}`);\n  contador++;\n}\n\n// Bucle DO While \nlet contador2 = 0\ndo {\n  console.log(`El contador es ${contador2}`);\n  contador2++;\n} while (contador2 < 5);\n\n// Sentencia break y continue \nfor (let i = 0; i < 10; i++) {\n  if (i === 3) {\n    continue; // Saltar la iteración actual si i es igual a 3\n  }\n  if (i === 7) {\n    break; // Salir del bucle si i es igual a 7\n  }\n  console.log(\"El valor de i es: \" + i);\n}\n\n\n\n\n/*  DIFICULTAD EXTRA (opcional):\n Crea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3. */\n\nfor (let i = 10; i <= 55; i++) {\n  if(i === 55 ){\n    console.log(i);\n  }\n  if (i % 2 === 1 || (i === 16 || i % 3 === 0)) {\n      continue;\n  }\n  console.log(i);\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/Jalivur.js",
    "content": "/*\r\nEJERCICIO:\r\n- Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\r\n    Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\r\n    (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\r\n- Utilizando las operaciones con operadores que tú quieras, crea ejemplos\r\n    que representen todos los tipos de estructuras de control que existan\r\n    en tu lenguaje:\r\n    Condicionales, iterativas, excepciones...\r\n- Debes hacer print por consola del resultado de todos los ejemplos.\r\n\r\nDIFICULTAD EXTRA (opcional):\r\n    Crea un programa que imprima por consola todos los números comprendidos\r\n    entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\r\n\r\n    Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\r\n */\r\n\r\n//OPERADORES:\r\n/*\r\n-Operadores de ASIGNACIÓN:\r\nUn operador de asignación asigna un valor a su operando izquierdo basándose en el valor de su operando derecho. \r\nEl operador de asignación simple es igual (=), que asigna el valor de su operando derecho a su operando izquierdo. Es decir, x = y asigna el valor de y a x.\r\nTambién hay operadores de asignación compuestos que son una abreviatura de las operaciones siguientes.\r\n*/\r\n\r\n//Asignacion Basica: --> =\r\nconsole.log('========================');\r\nconsole.log('ASIGNACION BASICA variable 1 = variable 2');\r\nlet operator1; //-->no inicializado, undefined o indefinido.\r\nlet asingValue = 5;\r\nconsole.log(operator1+\" sin asignarle nada a la variable\");\r\nconsole.log(`asignamo valor a \"variable = ${operator1=asingValue}\": ${operator1=asingValue}`); \r\nconsole.log('========================');\r\n\r\n//Asignacion suma: --> +=\r\nconsole.log('========================');\r\nconsole.log('ASIGNACION SUMA variable1 += variable2');\r\nlet operator2; //-->no inicializado, undefined o indefinido.\r\nasingValue = 10;\r\nconsole.log(operator2 +\" SIN INICIALIZAR\"); \r\nconsole.log(`${operator2} += ${asingValue} = ${operator2 += asingValue}`); //--> no se puede operar con valores undefined. \r\noperator2 = 2; //-->inicializar para que no devuelva NaN.\r\nconsole.log(operator2 +\" INICIALIZADA\");\r\nconsole.log(`${operator2} += ${asingValue} = ${operator2 += asingValue}`); //--> al valor inicializado suma el valor de asignaicon y reasigna valor sumado.\r\nconsole.log(`Al valor inicializado suma el valor de asignaicon,\r\ny reasigna valor sumado a la variable.`);\r\nconsole.log('========================');\r\n\r\n//Asignacion resta: --> -=\r\nconsole.log('========================');\r\nconsole.log('ASIGNACION RESTA variable 1 -= variable 2');\r\nlet operator3; //-->no inicializado, undefined o indefinido.\r\nasingValue = 10;\r\nconsole.log(operator3 +\" SIN INICIALIZAR\");\r\nconsole.log(`${operator3} -= ${asingValue} = ${operator3 -= asingValue}`); //--> no se puede operar con valores undefined. \r\noperator3 = 2; //-->inicializar para que no devuelva NaN.\r\nconsole.log(operator3 +\" INICIALIZADA\");\r\nconsole.log(`${operator3} -= ${asingValue} = ${operator3 -= asingValue}`); //--> al valor inicializado resta el valor de asignaicon y reasigna valor restado.\r\nconsole.log(`Al valor inicializado se resta el valor de asignaicon,\r\ny reasigna valor restado.`);\r\nconsole.log('========================');\r\n\r\n//Asignacion de multiplicación: --> *=\r\nconsole.log('========================');\r\nconsole.log('ASIGNACION MULTIPLICACIÓN variable 1 *= variable 2');\r\nlet operator4 = 5; //Declaracion e Inicialización.\r\nasingValue = 10;\r\nconsole.log(`Al igual que con suma y resta,\r\nla variable deve tener valor, \r\npara poder operar con ella.\r\n${operator4} *= ${asingValue} = ${operator4 *= asingValue}`);//--> el valor inicializado se multiplica por el valor de asignaicon y reasigna valor multiplicado.\r\nconsole.log(`El valor inicializado se multiplica por el valor de asignaicon,\r\ny reasigna valor multiplicado.`);\r\nconsole.log('========================');\r\n\r\n//Asignacion de división: --> /=\r\nconsole.log('========================');\r\nconsole.log('ASIGNACION DIVISIÓN variable 1 /= variable 2');\r\nlet operator5 = 5; //Declaracion e Inicialización.\r\nasingValue = 10;\r\nconsole.log(`La variable deve tener valor, \r\npara poder operar con ella.\r\n${operator5} /= ${asingValue} = ${operator5 /= asingValue}`);//--> el valor inicializado se divde por el valor de asignaicon y reasigna valor dividido.\r\nconsole.log(`El valor inicializado se divde por el valor de asignaicon, \r\ny reasigna valor dividido.`);\r\nconsole.log('========================');\r\n\r\n//Asignacion de residuo o resto: --> %=\r\nconsole.log('========================');\r\nconsole.log('ASIGNACION RESTO variable 1 %= variable 2');\r\nlet operator6 = 10; //Declaracion e Inicialización.\r\nasingValue = 7;\r\nconsole.log(`La variable deve tener valor, \r\npara poder operar con ella.\r\n${operator6} %= ${asingValue} = ${operator6 %= asingValue}`);//--> el valor inicializado se divde por el valor de asignaicon y reasigna valor del resto de la division.\r\nconsole.log(`El valor inicializado se divde por el valor de asignaicon, \r\ny reasigna valor del resto de la division.`);\r\nconsole.log('========================');\r\n\r\n//Asignacion de exponenciación: --> **=\r\nconsole.log('========================');\r\nconsole.log('ASIGNACION POTENCIA variable 1 **= variable 2');\r\nasingValue = 5;\r\nconsole.log(`La variable deve tener valor, \r\npara poder operar con ella.\r\n${operator6} **= ${asingValue} = ${operator6 **= asingValue}`);//--> el valor del operador6 se eleva al exponente de asignacion y reasigna valor del exponente.\r\nconsole.log(`El valor actual de operator6 se eleva al valor de asignaicon, \r\ny reasigna valor de la potencia.`);\r\nconsole.log('========================');\r\n\r\n//Asignación de desplazamiento de bits a la izquierda: --> <<=\r\nconsole.log('========================');\r\nconsole.log('ASIGNACION DESPLAZAMEINTO BIT A BIT A LA IZQUIERDA variable 1 <<= variable 2');\r\nasingValue = 3;\r\nconsole.log(` ${operator4} (${operator4.toString(2).padStart(32,\"0\")}) \r\n<<= ${asingValue}\r\n${operator4 <<= asingValue} (${operator4.toString(2).padStart(32,\"0\")})`);// al valor binario (ejm: 50 = 00000000000000000000000000110010) del operador agrega n (valor de asignacion) ceros a la izquierda, y reasigna valor binario resultante en decimal.\r\nconsole.log(`El valor de la variable en formato binario de 32bits,\r\nes desplazado a la izquierda tastas posiciones segun valor de asignaicon, \r\ny reasigna valor resultante de binario de 32bits a decimal,\r\nlas posiciones que se desplazan toman valor 0.`);\r\nconsole.log('========================');\r\n\r\n//Asignación de desplazamiento de bits a la derecha: --> >>= combierte en binarios de 32 bits\r\nconsole.log('========================');\r\nconsole.log('ASIGNACION DESPLAZAMEINTO BIT A BIT A LA DERECHA CON SIGNO variable 1 >>= variable 2');\r\noperator4 = -243;\r\nasingValue = 2;\r\nconsole.log(`${operator4} (${(operator4>>>0).toString(2).padStart(32,\"0\")}) \r\n>>= ${asingValue}\r\n ${operator4 >>= asingValue} (${(operator4>>>0).toString(2).padStart(32,\"0\")})`);// Desplaza hacia la derecha los bits de una variable el número de bits especificados en el valor de la expresión, manteniendo el signo, y asigna el resultado a la variable.\r\nconsole.log('========================');\r\noperator4 = 243;\r\nasingValue = 2;\r\nconsole.log(`${operator4} (${(operator4>>>0).toString(2).padStart(32,\"0\")}) \r\n>>= ${asingValue}\r\n ${operator4 >>= asingValue} (${(operator4>>>0).toString(2).padStart(32,\"0\")})`);// Desplaza hacia la derecha los bits de una variable el número de bits especificados en el valor de la expresión, manteniendo el signo, y asigna el resultado a la variable.\r\nconsole.log('========================');\r\nconsole.log(`El valor de la variable en formato binario de 32bits,\r\nes desplazado a la derecha tastas posiciones segun valor de asignaicon, \r\ny reasigna valor resultante de binario de 32bits a decimal, manteniendo el signo,\r\nlas posiciones que se desplazan toman valor 0 si es decimal pisitivo, \r\ny 1 si el decimal negativo.`)\r\n console.log('========================');\r\n\r\n //Asignación de desplazamiento a la derecha sin signo: --> >>>=\r\nconsole.log('========================');\r\nconsole.log('ASIGNACION DESPLAZAMEINTO BIT A BIT A LA DERECHA SIN SIGNO variable 1 >>>= variable 2');\r\noperator4 = -243;\r\nasingValue = 2;\r\nconsole.log(`      ${operator4} (${(operator4>>>0).toString(2).padStart(32,\"0\")}) \r\n>>>= ${asingValue}\r\n${operator4 >>>= asingValue} (${operator4.toString(2).padStart(32,\"0\")})`);// Desplaza hacia la derecha los bits de una variable el número de bits especificados en el valor de la expresión, sin mantener el signo, y asigna el resultado a la variable.\r\nconsole.log('========================');\r\noperator4 = 243;\r\nasingValue = 2;\r\nconsole.log(`${operator4} (${(operator4>>>0).toString(2).padStart(32,\"0\")}) \r\n>>= ${asingValue}\r\n ${operator4 >>= asingValue} (${(operator4>>>0).toString(2).padStart(32,\"0\")})`);// Desplaza hacia la derecha los bits de una variable el número de bits especificados en el valor de la expresión, manteniendo el signo, y asigna el resultado a la variable.\r\nconsole.log('========================');\r\nconsole.log(`El valor de la variable en formato binario de 32bits,\r\nes desplazado a la derecha tastas posiciones segun valor de asignaicon, \r\ny reasigna valor resultante de binario de 32bits a decimal, sin mantener el signo,\r\nlas posiciones que se desplazan toman valor 0.`);\r\nconsole.log('========================');\r\nconsole.log('========================');\r\nconsole.log(`En ambos desplacamientos a la dercha, \r\nlos bit que quedna mas ala derecha de posision 0,\r\npierden el valor.`);\r\nconsole.log('========================');\r\n\r\n//Asignación AND bit a bit: --> &=\r\nconsole.log('========================');\r\nconsole.log('ASIGNACION AND BIT A BIT variable 1 &= variable 2');\r\nlet operatorbit1 = 3;\r\nasingValue = 4;\r\nconsole.log(operatorbit1); // ahora es 3\r\nconsole.log(`${operatorbit1} (${(operatorbit1).toString(2).padStart(32,\"0\")}) AND, \r\n${asingValue} (${(asingValue).toString(2).padStart(32,\"0\")}) bit a bit es igual a, \r\n${operatorbit1&=asingValue} (${(operatorbit1).toString(2).padStart(32,\"0\")})`);\r\nconsole.log(operatorbit1); // ahora es 0\r\nconsole.log('========================');\r\nconsole.log('========================');\r\noperatorbit1 = 6;\r\nasingValue = 4;\r\nconsole.log(operatorbit1); // ahora es 6\r\nconsole.log(`${operatorbit1} (${(operatorbit1).toString(2).padStart(32,\"0\")}) AND, \r\n4 (${(4).toString(2).padStart(32,\"0\")}) bit a bit es igual a, \r\n${operatorbit1&=4} (${(operatorbit1).toString(2).padStart(32,\"0\")})`);\r\nconsole.log(operatorbit1); // ahora es 4\r\nconsole.log('========================');\r\nconsole.log(`AND, \r\nsolo si los dos bit de los operadores es 1\r\nel bit del resultado sera 1,\r\nsi uno o ambos bit son 0 sera 0.`);\r\nconsole.log('========================');\r\n\r\n//Asignación XOR bit a bit: --> ^= or exclusiva.\r\nconsole.log('========================');\r\nconsole.log('ASIGNACION XOR BIT A BIT variable 1 ^= variable 2');\r\nlet operatorbit2 = 6;\r\nasingValue=55;\r\nconsole.log(operatorbit2); // ahora es 6\r\nconsole.log(` ${operatorbit2} (${(operatorbit2).toString(2).padStart(32,\"0\")}) XOR, \r\n${asingValue} (${(asingValue).toString(2).padStart(32,\"0\")}) bit a bit es igual a, \r\n${operatorbit2^=asingValue} (${(operatorbit2).toString(2).padStart(32,\"0\")})`);\r\nconsole.log(operatorbit2); // ahora es 49\r\nconsole.log('========================');\r\nconsole.log('========================');\r\noperatorbit2 = 4;\r\nasingValue=10;\r\nconsole.log(operatorbit2); // ahora es 4\r\nconsole.log(` ${operatorbit2} (${(operatorbit2).toString(2).padStart(32,\"0\")}) XOR, \r\n${asingValue} (${(asingValue).toString(2).padStart(32,\"0\")}) bit a bit es igual a, \r\n${operatorbit2^=asingValue} (${(operatorbit2).toString(2).padStart(32,\"0\")})`);\r\nconsole.log(operatorbit2); // ahora es 4\r\nconsole.log('========================');\r\nconsole.log(`XOR es or exlusiva, \r\nsolo si uno de los dos bit de los operadores es 1,\r\nel bit del resultado sera 1,\r\nsi ambos bit son 1 sera 0,\r\nal igual que si ambos son 0.`);\r\nconsole.log('========================');\r\n\r\n//Asignación OR bit a bit: --> |= \r\nconsole.log('========================');\r\nconsole.log('ASIGNACION OR BIT A BIT variable 1 |= variable 2');\r\nlet operatorbit3 = 5896;\r\nasingValue = 4589; \r\nconsole.log(operatorbit3); // ahora es 5896\r\nconsole.log(`${operatorbit3} (${(operatorbit3).toString(2).padStart(32,\"0\")}) OR, \r\n${asingValue} (${(asingValue).toString(2).padStart(32,\"0\")}) bit a bit es igual a, \r\n${operatorbit3|=asingValue} (${(operatorbit3).toString(2).padStart(32,\"0\")})`);\r\nconsole.log(operatorbit3); // ahora es 6125\r\nconsole.log('========================');\r\nasingValue = 6126;\r\nconsole.log(operatorbit3); // ahora es 6125\r\nconsole.log(`${operatorbit3} (${(operatorbit3).toString(2).padStart(32,\"0\")}) OR, \r\n${asingValue} (${(asingValue).toString(2).padStart(32,\"0\")}) bit a bit es igual a, \r\n${operatorbit3|=asingValue} (${(operatorbit3).toString(2).padStart(32,\"0\")})`);\r\nconsole.log(operatorbit3); // ahora es 6127\r\nconsole.log('========================');\r\nconsole.log(`OR, \r\nsolo si uno o ambos bit de los operadores es 1,\r\nel bit del resultado sera 1,\r\nsi ambos bit son 0 sera 0.`);\r\nconsole.log('========================');\r\n\r\n//Asignación AND lógico: --> &&=\r\nconsole.log('========================');\r\nconsole.log('ASIGNACION AND LOGICO variable 1 &&= variable 2');\r\nlet operatorLogic1 = true;\r\nlet operatorLogic2 = true;\r\nconsole.log(`${operatorLogic1} AND ${operatorLogic2}`);\r\noperatorLogic1 &&= operatorLogic2; //si ambos operadorres son true asigna al operador 1 true\r\nconsole.log(`operador izda = ${operatorLogic1}`); \r\noperatorLogic2 = false;\r\nconsole.log(`${operatorLogic1} AND ${operatorLogic2}`);\r\noperatorLogic1 &&= operatorLogic2; // si alguno de los opreadores, o ambos son false asigna false \r\nconsole.log(`operador izda = ${operatorLogic1}`);\r\nconsole.log('========================');\r\nconsole.log(`AND logico, \r\nsolo si los dos operadores es 1\r\nel resultado sera 1 y se reasignara al operador de la izquierda,\r\nsi uno o ambos son 0 sera 0 y se reasignara al operador de la izquierda.`);\r\nconsole.log('========================');\r\n\r\n//Asignación OR lógico: --> ||=\r\nconsole.log('========================');\r\nconsole.log('ASIGNACION OR LOGICO variable 1 ||= variable 2');\r\nlet operatorLogic3 = true;\r\nlet operatorLogic4 = false;\r\nconsole.log(`${operatorLogic3} OR ${operatorLogic4}`);\r\noperatorLogic3 ||= operatorLogic4; //si uno o los dos operadorres son true asigna al operador 3 true\r\nconsole.log(`operador izda = ${operatorLogic3}`); \r\noperatorLogic3 = false;\r\nconsole.log(`${operatorLogic3} OR ${operatorLogic4}`);\r\noperatorLogic3 ||= operatorLogic4; // si abmos opreadores son false, asigna false \r\nconsole.log(`operador izda = ${operatorLogic3}`);\r\nconsole.log('========================');\r\nconsole.log(`OR logico, \r\nsolo si uno o ambos operadores es 1,\r\nresultado sera 1 y se reasignara al operador de la izquierda,\r\nsi ambos son 0 sera 0 y se reasignara al operador de la izquierda.`);\r\nconsole.log('========================');\r\n\r\n//Asignación anulacion lógica: --> ??=\r\nconsole.log('========================');\r\nconsole.log('ASIGNACION ANULACION LOGICA variable 1 ??= variable 2');\r\nlet operatorLogic5;\r\nlet operatorLogic6 = false;\r\nconsole.log(`${operatorLogic5} ANULACION ${operatorLogic6}`);\r\noperatorLogic5 ??= operatorLogic6; // si el operador a la izquierda no esta definido, se arigna el valor de operador de la derecha.\r\nconsole.log(`operador izda = ${operatorLogic5}`);\r\noperatorLogic5 = true;\r\nconsole.log(`${operatorLogic5} ANULACION ${operatorLogic6}`);\r\noperatorLogic5 ??= operatorLogic6; // si el operador de la izquierda esta definido, se queda con el valor que tenia.\r\nconsole.log(`operador izda = ${operatorLogic5}`);\r\nconsole.log('========================');\r\nconsole.log(`ANULACION logica, \r\nsi el operador de la izquierda no esta inicializado,\r\nse reasigna el valor del derecho,\r\npero si esta inicializado, se queda con su valor.`);\r\nconsole.log('========================');\r\n\r\n/*\r\n-Operadores de COMPARACION:\r\nUn operador de comparación compara sus operandos y devuelve un valor lógico en función de si la comparación es verdadera (true) o falsa (false). \r\nLos operandos pueden ser valores numéricos, de cadena, lógicos u objetos. \r\nLas cadenas se comparan según el orden lexicográfico estándar, utilizando valores Unicode.\r\nEn la mayoría de los casos, si los dos operandos no son del mismo tipo, JavaScript intenta convertirlos a un tipo apropiado para la comparación. \r\nEste comportamiento generalmente resulta en comparar los operandos numéricamente. \r\nLas únicas excepciones a la conversión de tipos dentro de las comparaciones involucran a los operadores === y !==, que realizan comparaciones estrictas de igualdad y desigualdad. \r\nEstos operadores no intentan convertir los operandos a tipos compatibles antes de verificar la igualdad.\r\n*/\r\n\r\n//IGUAL: --> ==\r\nconsole.log('========================');\r\nconsole.log('COMPARACION IGUALDAD resultado = (variable 1 == variable 2)');\r\nlet upshot;\r\nupshot = (operator3 == operator2);\r\nconsole.log(\"es \"+(operator3)+\" igual a \"+(operator2)+\": \"+ (upshot));\r\noperator3 = 5; \r\noperator2 = 5;\r\nupshot = (operator3 == operator2);\r\nconsole.log(\"es \"+(operator3)+\" igual a \"+(operator2)+\": \"+ (upshot));\r\noperator3 = \"alberto\"; \r\noperator2 = \"alberto\";\r\nupshot = (operator3 == operator2);\r\nconsole.log(\"es \"+(operator3)+\" igual a \"+(operator2)+\": \"+ (upshot));\r\noperator3 = \"alberto\";\r\noperator2 = \"Alberto\";\r\nupshot = (operator3 == operator2);\r\nconsole.log(\"es \"+(operator3)+\" igual a \"+(operator2)+\": \"+ (upshot));\r\noperator3 = 1.0; \r\noperator2 = 1;\r\nupshot = (operator3 == operator2);\r\nconsole.log(`es ${operator3} igual a ${operator2}: ${upshot}`);\r\noperator3 = 50; \r\noperator2 = 50n;\r\nupshot = (operator3 == operator2);\r\nconsole.log(`es ${operator3} int igual a ${operator2} bigint: ${upshot}`);\r\nupshot = (operatorLogic1 == operatorLogic2);\r\nconsole.log(`es ${operatorLogic1} igual a ${operatorLogic2}: ${upshot}`);\r\noperatorLogic1 = true;\r\nupshot = (operatorLogic1 == operatorLogic3);\r\nconsole.log(`es ${operatorLogic1} igual a ${operatorLogic3}: ${upshot}`);\r\noperator1 = undefined;\r\noperator2 = null;\r\nupshot = (operator1 == operator2);\r\nconsole.log(`es ${operator1} igual a ${operator2}: ${upshot}`);\r\nupshot = (operator1 == 0);\r\nconsole.log(`es ${operator1} igual a ${0}: ${upshot}`);\r\nupshot = (operator2 == 0);\r\nconsole.log(`es ${operator2} igual a ${0}: ${upshot}`);\r\nupshot = (operatorLogic1 == 1);\r\nconsole.log(`es ${1} igual a ${operatorLogic1}: ${upshot}`);\r\nupshot = (operatorLogic2 == 0);\r\nconsole.log(`es ${0} igual a ${operatorLogic2}: ${upshot}`);\r\nupshot = (operatorLogic2 == operator1);\r\nconsole.log(`es ${operator1} igual a ${operatorLogic2}: ${upshot}`);\r\nupshot = (operatorLogic2 == operator2);\r\nconsole.log(`es ${operator2} igual a ${operatorLogic2}: ${upshot}`);\r\nconsole.log('========================');\r\n\r\n//NO IGUAL: --> !=\r\nconsole.log('========================');\r\nconsole.log('COMPARACION DESIGUALDAD resultado = (variable 1 != variable 2)');\r\nupshot = (operator1 != operator2);\r\nconsole.log(`${operator1} no es igual a ${operator2}: ${upshot}`);\r\nupshot = (operatorLogic1 != operatorLogic2);\r\nconsole.log(`${operatorLogic1} no es igual a ${operatorLogic2}: ${upshot}`);\r\noperator3 = \"alberto\";\r\noperator2 = \"Alberto\";\r\nupshot = (operator3 != operator2);\r\nconsole.log((operator3)+\" no es igual a \"+(operator2)+\": \"+ (upshot));\r\nconsole.log('========================');\r\n\r\n//EXTRICTAMENTE IGUAL: --> ===\r\nconsole.log('========================');\r\nconsole.log('COMPARACION IGUALDAD EXTRICTA resultado = (variable 1 === variable 2)');\r\noperator1 = undefined;\r\noperator2 = null;\r\nupshot = (operator1 === 0);\r\nconsole.log(`es ${operator1} extrictamente igual a ${operator2}: ${upshot}`);\r\nupshot = (operator1 === operator2);\r\nconsole.log(`es ${operator1} extrictamente igual a ${0}: ${upshot}`);\r\nupshot = (operator2 === 0);\r\nconsole.log(`es ${operator2} extrictamente igual a ${0}: ${upshot}`);\r\nupshot = (operatorLogic1 === 1);\r\nconsole.log(`es ${1} extrictamente igual a ${operatorLogic1}: ${upshot}`);\r\nupshot = (operatorLogic2 === 0);\r\nconsole.log(`es ${0} extrictamente igual a ${operatorLogic2}: ${upshot}`);\r\nconsole.log('========================');\r\n\r\n//DESIGUALDAD EXTRICTA: --> !==\r\nconsole.log('========================');\r\nconsole.log('COMPARACION DESIGUALDAD EXTRICTA resultado = (variable 1 !== variable 2)');\r\nupshot = (operator1 !== operator2);\r\nconsole.log(`${operator1} no es igual a ${operator2} extricatemente: ${upshot}`);\r\nupshot = (operatorLogic1 !== operatorLogic2);\r\nconsole.log(`${operatorLogic1} no es igual a ${operatorLogic2} extrictamente: ${upshot}`);\r\noperator3 = \"alberto\";\r\noperator2 = \"Alberto\";\r\nupshot = (operator3 !== operator2);\r\nconsole.log((operator3)+\" no es igual a \"+(operator2)+\" extrictamente: \"+ (upshot));\r\nconsole.log('========================');\r\n\r\n//MAYOR QUE: --> >\r\nconsole.log('========================');\r\nconsole.log('COMPARACION MAYOR QUE resultado = (variable 1 > variable 2)');\r\noperator1 = 1;\r\noperator2 = 5;\r\nupshot = (operator1 > operator2);\r\nconsole.log(`es ${operator1} mayor que ${operator2}: ${upshot}`);\r\nupshot = (operator2 > operator1);\r\nconsole.log(`es ${operator2} mayor que ${operator1}: ${upshot}`);\r\noperator3 = \"alberto\";\r\noperator2 = \"Alberto\";\r\nupshot = (operator3.length > operator2.length);\r\nconsole.log(`es \"${operator3}\" mayor que \"${operator2}\": ${upshot}\r\nen longiturd no.`);\r\nupshot = (operator3 > operator2);\r\nconsole.log(`es \"${operator3}\" mayor que \"${operator2}\": ${upshot}\r\ncomo cadenas si porque el valor ASCII de las minusculas en mayor que el de las mayusculas.`);\r\nconsole.log('========================');\r\n\r\n//MAYOR O IGUAL: --> >=\r\nconsole.log('========================');\r\nconsole.log('COMPARACION MAYOR O IGUAL QUE resultado = (variable 1 >= variable 2)');\r\nlet value = 5;\r\nlet otherValue = 5;\r\nupshot = (value >= otherValue);\r\nconsole.log(`es ${value} mayor o igual que ${otherValue}: ${upshot}`);\r\nvalue = 5;\r\notherValue = 3;\r\nupshot = (value >= otherValue);\r\nconsole.log(`es ${value} mayor o igual que ${otherValue}: ${upshot}`);\r\nvalue = 5;\r\notherValue = 6;\r\nupshot = (value >= otherValue);\r\nconsole.log(`es ${value} mayor o igual que ${otherValue}: ${upshot}`);\r\nlet name1 = \"alberto\";\r\nlet name2 = \"Alberto\";\r\nupshot = (name1.length>=name2.length);\r\nconsole.log(`es ${name1} (${name1.length}) mayor o igual que ${name2} (${name2.length}): ${upshot}`);\r\nname1=\"albertooo\";\r\nname2=\"Alberto   \";\r\nupshot = (name1.length>=name2.length);\r\nconsole.log(`es ${name1} (${name1.length}) mayor o igual que ${name2}(${name2.length}): ${upshot} por logitud`);\r\nupshot = (name1>=name2);\r\nconsole.log(`es ${name1} (${name1.length}) mayor o igual que ${name2}(${name2.length}): ${upshot} por cadena`);\r\nconsole.log('========================');\r\n\r\n//MENOR QUE: --> <\r\nconsole.log('========================');\r\nconsole.log('COMPARACION MENOR QUE resultado = (variable 1 < variable 2)');\r\nvalue = 1;\r\notherValue = 5;\r\nupshot = (value < otherValue)\r\nconsole.log(`es ${value} menor que ${otherValue}: ${upshot}`);\r\nvalue = 5;\r\notherValue = 1;\r\nupshot = (value < otherValue)\r\nconsole.log(`es ${value} menor que ${otherValue}: ${upshot}`);\r\nvalue = 5;\r\notherValue = 5;\r\nupshot = (value < otherValue)\r\nconsole.log(`es ${value} menor que ${otherValue}: ${upshot}`);\r\nconsole.log('========================');\r\n\r\n//MENOR O IGUAL: --> <=\r\nconsole.log('========================');\r\nconsole.log('COMPARACION MENOR O IGUAL QUE resultado = (variable 1 <= variable 2)');\r\nvalue = 5;\r\notherValue = 5;\r\nupshot = (value <= otherValue)\r\nconsole.log(`es ${value} menor o igual que ${otherValue}: ${upshot}`);\r\nvalue = 5;\r\notherValue = 3;\r\nupshot = (value <= otherValue)\r\nconsole.log(`es ${value} menor o igual que ${otherValue}: ${upshot}`);\r\nvalue = 5;\r\notherValue = 6;\r\nupshot = (value <= otherValue)\r\nconsole.log(`es ${value} menor o igual que ${otherValue}: ${upshot}`);\r\nname1 = \"alberto\";\r\nname2 = \"Alberto\";\r\nconsole.log(`es ${name1}(${name1.length}) menor o igual que ${name2}(${name2.length}): ${name1.length<=name2.length}`);\r\nname1=\"albertooo\";\r\nname2=\"alberto   \";\r\nupshot = (name1.length<=name2.length)\r\nconsole.log(`es ${name1}(${name1.length}) menor o igual que ${name2}(${name2.length}): ${upshot}`);\r\nconsole.log('========================');\r\n\r\n/* OPERADORES ARITMETICOS:\r\nUn operador aritmético toma valores numéricos (ya sean literales o variables) como sus operandos y devuelve un solo valor numérico. \r\nLos operadores aritméticos estándar son suma (+), resta (-), multiplicación (*) y división (/). \r\nEstos operadores funcionan como lo hacen en la mayoría de los otros lenguajes de programación cuando se usan con números de punto flotante (en particular, ten en cuenta que la división entre cero produce Infinity).\r\n*/\r\n\r\n//RESIDUO O RESTO: --> % actua como en el de asignacion, pero no asigna valor al operador de la izquierda.\r\nconsole.log('========================');\r\nconsole.log('OPERADOR ARITMETICO RESIDUO O RESTO %');\r\nlet num1 = 5;\r\nlet num2 = 3;\r\nconsole.log(`El resto de ${num1} entre ${num2} es = ${upshot=(num1%num2)}`);//2\r\nnum1 = 550;\r\nnum2 = 10;\r\nconsole.log(`El resto de ${num1} entre ${num2} es = ${upshot=(num1%num2)}`);//0, 550 es multiplo de 10.\r\nupshot = num1%num2\r\nconsole.log('========================');\r\nconsole.log(`Un operador aritmetico solo no asigna,\r\npor lo que si queremos trabajar con el valor de la operacion\r\nse deve almacenar en una variable \r\n{\r\nlet upshot; \r\nupshot=num1%num2;\r\n}.`)\r\nconsole.log('========================');\r\n\r\n//INCREMENTO: --> ++\r\nconsole.log('========================');\r\nconsole.log('OPERADOR ARITMETICO INCREMENTO ++');\r\nvalue = 100;\r\nconsole.log(`Incremento de ++(${value}) = ${upshot=(++value)}`); //inclementa 1 al valor de value\r\nconsole.log('========================');\r\nconsole.log(`Incrementa en 1 el valor actual de la variable.\r\nUn operador aritmetico solo no asigna,\r\npor lo que si queremos trabajar con el valor de la operacion\r\nse deve almacenar en una variable ejem: upshot = ${upshot}.`)\r\nconsole.log('========================');\r\n\r\n//DECREMENTO: --> --\r\nconsole.log('========================');\r\nconsole.log('OPERADOR ARITMETICO DECREMENTO --');\r\nconsole.log(`Incremento de --(${value}) = ${upshot=(--value)}`); //decrementa 1 al valor de value\r\nconsole.log('========================');\r\nconsole.log(`Decrementa en 1 el valor actual de la variable.\r\nUn operador aritmetico solo no asigna,\r\npor lo que si queremos trabajar con el valor de la operacion\r\nse deve almacenar en una variable ejem: upshot = ${upshot}.`)\r\nconsole.log('========================');\r\n\r\n//NEGACION UNARIA: --> - \r\nconsole.log('========================');\r\nconsole.log('OPERADOR ARITMETICO NEGACION UNARIA -');\r\nvalue = -59;\r\nconsole.log(`Negacion unaria de -(${value}) = ${upshot=(-value)}`); //inclementa 1 al valor de value\r\nconsole.log('========================');\r\nconsole.log(`Decrementa en 1 el valor actual de la variable.\r\nUn operador aritmetico solo no asigna,\r\npor lo que si queremos trabajar con el valor de la operacion\r\nse deve almacenar en una variable ejem: upshot = ${upshot}.`)\r\nconsole.log('========================');\r\n\r\n\r\n//POSITIVO UNARIO: --> +\r\nconsole.log('========================');\r\nconsole.log('OPERADOR ARITMETICO POSITIVO UNARIO +');\r\nvalue = false;\r\nconsole.log(`Inicialmente la variable es ${value}, de tipo ${typeof(value)},\r\npero con el operador, resultado = (+variable), este pasa a ser ${upshot=(+value)}, que es de tipo ${typeof(upshot)}.`);\r\nvalue=\"2\";\r\nconsole.log(`Ahora la variable es ${value}, de tipo ${typeof(value)},\r\npero con el operador, resultado = (+variable), este pasa a ser ${upshot=(+value)}, que es de tipo ${typeof(upshot)}.`);\r\nvalue=\"alberto\";\r\nconsole.log(`Ahora la variable es ${value}, de tipo ${typeof(value)},\r\npero con el operador, resultado = (+variable), este pasa a ser ${upshot=(+value)}, que es de tipo ${typeof(upshot)}.`);\r\nconsole.log('========================');\r\n\r\n\r\n//EXPONECIACION, EXPONENTE: --> **\r\nconsole.log('========================');\r\nconsole.log('OPERADOR ARITMETICO EXPONENCIACION resultado = (variable 1 ** variable 2)');\r\nvalue = 5;\r\notherValue = 6;\r\nupshot = (value ** otherValue);\r\nconsole.log(`${value} elevado a ${otherValue} es = ${upshot}`);\r\nvalue = 2;\r\notherValue = 8;\r\nupshot = (value ** otherValue);\r\nconsole.log(`${value} elevado a ${otherValue} es = ${upshot}`);\r\nconsole.log('========================')\r\n\r\n/* OPERADORES BIT A BIT:\r\nUn operador bit a bit trata a sus operandos como un conjunto de 32 bits (ceros y unos), en lugar de números decimales, hexadecimales u octales. \r\nPor ejemplo, el número decimal nueve tiene una representación binaria de 1001. \r\nLos operadores bit a bit realizan sus operaciones en tales representaciones binarias, pero devuelven valores numéricos estándar de JavaScript.\r\n*/\r\n\r\n//AND bit a bit: --> & sin asignacion.\r\nconsole.log('========================')\r\nconsole.log(`OPERADOR BIT A BIT AND resultado = (variable 1 & variable 2)`)\r\noperatorbit1 = -3;\r\nlet andValue = -5\r\nupshot = (operatorbit1 & andValue);\r\nconsole.log(`${operatorbit1} AND ${andValue} bit a bit es igual a ${upshot}`);\r\nconsole.log(`${operatorbit1} \r\n= \r\n${(operatorbit1>>>0).toString(2).padStart(32,\"0\")},\r\n${andValue} \r\n= \r\n${((andValue)>>>0).toString(2).padStart(32,\"0\")},\r\ncon and solo quedan a 1 los que coniciden en abmos por eso queda: \r\n${upshot} \r\n= \r\n${((upshot)>>>0).toString(2).padStart(32,\"0\")}.`);\r\nconsole.log('========================')\r\n\r\n//XOR bit a bit: --> ^ or exclusiva.\r\nconsole.log('========================')\r\nconsole.log(`OPERADOR BIT A BIT AND resultado = (variable 1 & variable 2)`)\r\noperatorbit1 = -559;\r\nlet xorValue=632;\r\nupshot = (operatorbit1 ^ xorValue);\r\nconsole.log(`${operatorbit1} XOR ${xorValue} bit a bit es igual a ${upshot}`);\r\nconsole.log(`${operatorbit1} \r\n= \r\n${(operatorbit1>>>0).toString(2).padStart(32,\"0\")}, \r\n${xorValue} \r\n= \r\n${(xorValue>>>0).toString(2).padStart(32,\"0\")},\r\ncon xor solo quedan a 1 los que son 1 en uno u otro operador, pero no si coiciden en abmos por eso queda: \r\n${upshot} \r\n=\r\n${((upshot)>>>0).toString(2).padStart(32,\"0\")}.`);\r\nconsole.log('========================')\r\n\r\n//OR bit a bit: --> | \r\nconsole.log('========================')\r\nconsole.log(`OPERADOR BIT A BIT OR resultado = (variable 1 | variable 2)`)\r\noperatorbit1 = -559;\r\nlet orValue=632;\r\nupshot = (operatorbit1 | orValue);\r\nconsole.log(`${operatorbit1} XOR ${orValue} bit a bit es igual a ${upshot}`);\r\nconsole.log(`${operatorbit1} \r\n= \r\n${(operatorbit1>>>0).toString(2).padStart(32,\"0\")}, \r\n${orValue} \r\n= \r\n${(orValue>>>0).toString(2).padStart(32,\"0\")},\r\ncon or quedan a 1 los que son 1 en uno u otro operador y si coiciden en abmos por eso queda: \r\n${upshot} \r\n=\r\n${((upshot)>>>0).toString(2).padStart(32,\"0\")}.`);\r\nconsole.log('========================')\r\n\r\n//NOT bit a bit: --> ~\r\nconsole.log('========================')\r\nconsole.log(`OPERADOR BIT A BIT NOT resultado = (~variable)`)\r\noperatorbit1 = 598;\r\nupshot = (~operatorbit1);\r\nconsole.log(`not ${operatorbit1} bit a bit es igual a ${upshot}`);\r\nconsole.log(`${operatorbit1} \r\n= \r\n${(operatorbit1>>>0).toString(2).padStart(32,\"0\")}, \r\ncon not se invierten los valores de los bits: \r\n${upshot} \r\n=\r\n${((upshot)>>>0).toString(2).padStart(32,\"0\")}.`);\r\nconsole.log('========================')\r\n\r\n//IZQUIERDA bit a bit: --> <<\r\nconsole.log('========================')\r\nconsole.log(`OPERADOR BIT A BIT IZQUIERDA resultado = (variable 1 << variable 2)`)\r\noperatorbit1 = -559;\r\nlet moveValue =3;\r\nupshot = (operatorbit1 << moveValue);\r\nconsole.log(`${operatorbit1} << ${moveValue} bit a bit es igual a ${upshot}`);\r\nconsole.log(`${operatorbit1}\r\n= \r\n${(operatorbit1>>>0).toString(2).padStart(32,\"0\")}, \r\ncon desplazamiento a la izquierda, desplazamos tantos bits a la izquierda como valor entre 0 y 31\r\nque asignemos la variable de movimiento. los bit desplazados son remplazados por 0: \r\n${upshot} \r\n=\r\n${((upshot)>>>0).toString(2).padStart(32,\"0\")}.`);\r\nconsole.log('========================')\r\n\r\n//DERECHA bit a bit CON SIGNO: --> >> \r\nconsole.log('========================')\r\nconsole.log(`OPERADOR BIT A BIT DERECHA MANTENIENDO SIGNO resultado = (variable 1 >> variable 2)`)\r\noperatorbit1 = -559;\r\nmoveValue =5;\r\nupshot = (operatorbit1 >> moveValue);\r\nconsole.log(`${operatorbit1} >> ${moveValue} bit a bit es igual a ${upshot}`);\r\nconsole.log(`${operatorbit1} \r\n= \r\n${(operatorbit1>>>0).toString(2).padStart(32,\"0\")}, \r\ncon desplazamiento a la derecha manteniendo el signo, desplazamos tantos bits a la derecha como valor entre 0 y 31\r\nque asignemos la variable de movimiento. los bit desplazados son remplazados por 0 si la variable tienen un valor positivo,\r\ny si la variable tiene un valor negativo se reemplazan con 1, para mantener el signo, lo valores mas a la derecha de posicion 0 se pierden.:  \r\n${upshot} \r\n=\r\n${((upshot)>>>0).toString(2).padStart(32,\"0\")}.`);\r\nconsole.log('========================')\r\n\r\n//DERECHA bit a bit SIN SIGNO: --> >>>\r\nconsole.log('========================')\r\nconsole.log(`OPERADOR BIT A BIT DERECHA SIN MANTENER SIGNO resultado = (variable 1 >>> variable 2)`)\r\noperatorbit1 = -559;\r\nmoveValue =0;\r\nupshot = (operatorbit1 >>> moveValue);\r\nconsole.log(`${operatorbit1} >>> ${moveValue} bit a bit es igual a ${upshot}`);\r\nconsole.log(`${operatorbit1} \r\n= \r\n${(operatorbit1>>>0).toString(2).padStart(32,\"0\")}, \r\ncon desplazamiento a la derecha sin mantener el signo, desplazamos tantos bits a la derecha como valor entre 0 y 31\r\nque asignemos la variable de movimiento. los bit desplazados son remplazados por 0 , por lo que el signo se pierde.:  \r\n${upshot} \r\n=\r\n${((upshot)>>>0).toString(2).padStart(32,\"0\")}.`);\r\nconsole.log('========================')\r\n\r\n//OPERADOR TERNARIO\r\n//expresión ? \"si es true\" : \"si es false\";\r\nconsole.log('========================')\r\nconsole.log(`OPERADOR TERNIARIO expresión ? \"si es true\" : \"si es false\"`)\r\nlet edad;\r\nlet acceso;\r\nconsole.log(`${edad=32} ${acceso = edad >= 18 ? \"Permitir acceso\" : \"Denegar acceso\"}`);\r\nconsole.log('========================')\r\n\r\n//ESTRUCTURAS DE CONTROL:\r\n\r\n//CONDICIONALES:\r\n\r\n//if else:\r\nconsole.log('========================')\r\nconsole.log(`Estructura de control condicional: if...else`);\r\noperator1 = 56;\r\noperator2 = 54;\r\nif (operator1 == operator2){\r\n    console.log(`${operator1} es  igual a ${operator2}`);\r\n}\r\nelse if (operator1 > operator2){\r\n    console.log(`${operator1} mayor que ${operator2}`);\r\n}\r\nelse {\r\n    console.log(`${operator1} menor que ${operator2}`);\r\n}\r\nconsole.log('========================')\r\n\r\n//switch\r\nconsole.log('========================')\r\nconsole.log(`Estructura de control switch:`);\r\nlet operacion =\"**\";\r\noperator1 = 2;\r\noperator2 = 256;\r\nswitch (operacion) {\r\n    case \"+\":\r\n        upshot = operator1 + operator2\r\n        console.log(`${operator1} + ${operator2} = ${upshot}`);\r\n        break;\r\n    case \"-\":\r\n        upshot = operator1 - operator2\r\n        console.log(`${operator1} - ${operator2} = ${upshot}`);\r\n        break;\r\n    case \"*\":\r\n        upshot = operator1 * operator2\r\n        console.log(`${operator1} * ${operator2} = ${upshot}`);\r\n        break;\r\n    case \"/\":\r\n        upshot = operator1 / operator2\r\n        console.log(`${operator1} / ${operator2} = ${upshot}`);\r\n        break;\r\n    case \"**\":\r\n        upshot = operator1 ** operator2\r\n        console.log(`${operator1} ** ${operator2} = ${upshot}`);\r\n        break;\r\n    case \"%\":\r\n        upshot = operator1 % operator2\r\n        console.log(`${operator1} % ${operator2} = ${upshot}`);\r\n        break;\r\n    default:\r\n        console.log(`Lo sentimos, la operacion ${operacion} no es valida.`);\r\n}\r\nconsole.log('========================')\r\n\r\n//BUCLES E ITERACIONES:\r\n\r\n//WHILE:\r\nconsole.log('========================')\r\nconsole.log(`Bucle while:`);\r\nlet whileCounter = 20;\r\nwhile (whileCounter < 20) {\r\n    console.log(`Iteración: ${whileCounter}`);\r\n    whileCounter++;\r\n}\r\nconsole.log(`Se ejecuta mientras la condicion se cumple,\r\nen este caso mientras contador < 20, como contador hemos establecido en 20,\r\nno ejecuta nada, porque primero comprueba estado contador.`);\r\nconsole.log('========================')\r\n\r\n\r\n//DO WHILE\r\nconsole.log('========================')\r\nconsole.log(`Bucle do while:`);\r\nlet contadorDoWhile = 20;\r\ndo {\r\n    console.log(`Iteración: ${contadorDoWhile}`);\r\n    contadorDoWhile++;\r\n} while (contadorDoWhile < 20);\r\nconsole.log(`Se ejecuta hasta que la ocndicion deja de cumplirse,\r\nen este caso hasta que contador < 20, como contador hemos establecido en 20,\r\nejecuta una vez y compreba estado.`);\r\nconsole.log('========================')\r\n\r\n//FOR\r\nconsole.log('========================')\r\nconsole.log(`Bucle for:`);\r\nfor (let i = 0; i <= 100; i++) {\r\n    console.log(`Vuelta: ${i}`);\r\n}\r\nconsole.log('========================')\r\nfor (let i = 0; i <= 100; ++i) {\r\n    console.log(`Vuelta: ${i}`);\r\n}\r\nconsole.log('========================')\r\n\r\n//FOR OF\r\nconsole.log('========================')\r\nconsole.log(`Bucle for of:`);\r\nlet arrayForOf = [10, 20, 30, 40, 50];\r\nfor (let valor of arrayForOf) {\r\n    console.log(`Valor elemento arrayForOf: ${valor}`);\r\n}\r\nconsole.log('========================')\r\n//FOR IN\r\nconsole.log('========================')\r\nconsole.log(`Bucle for in:`);\r\nlet objetoForIn = { a: 1, b: 2, c: 3, d: 4, e: 5};\r\n\r\nfor (let propiedad in objetoForIn) {\r\n    console.log(`Propiedad ${propiedad} = ${objetoForIn[propiedad]}`);\r\n}\r\nconsole.log('========================')\r\n\r\n//FOR EACH\r\nconsole.log('========================')\r\nconsole.log(`Bucle for each:`);\r\nlet arrayForEach = [1, 2, 3, 4, 5, 6];\r\n\r\narrayForEach.forEach(function (elemento) {\r\n    console.log(`Elemento: ${elemento}`);\r\n});\r\nconsole.log('========================')\r\n\r\n//EXCEPCIONES\r\n//Try catch:\r\nconsole.log('========================')\r\nconsole.log(`Try catch`);\r\nvalue = \"5\";\r\n\r\ntry {\r\n    if (value === 5) {\r\n        throw new Error(\"El número es igual a 5\")\r\n    }\r\n    console.log('Esto se imprime Si El número es distinto de 5')\r\n} catch (error) {\r\n    console.log(`Se ha producido un error poque ${error.message}`)\r\n}\r\nconsole.log('========================')\r\nvalue = 5;\r\n\r\ntry {\r\n    if (value === 5) {\r\n        throw new Error(\"El número es igual a 5\")\r\n    }\r\n    console.log('Esto se imprime si El número es distinto de 5')\r\n} catch (error) {\r\n    console.log(`Se ha producido un error poeque ${error.message}`)\r\n}\r\nconsole.log('========================')\r\n\r\n//Try catch con bloque finally:\r\nconsole.log('========================')\r\nconsole.log('try-catch-finally')\r\nvalue = \"5\";\r\ntry {\r\n    if (value === 5) {\r\n        throw new Error(\"El número es igual a 5\")\r\n    }\r\n    console.log(\"El número es distinto de 5\")\r\n} catch (error) {\r\n    console.log(\"Se ha producido un error porque \"+error.message)\r\n} finally {\r\n    console.log(\"Bloque finally. Esto siempre se ejecuta haya o no excepción\")\r\n}\r\nconsole.log('========================')\r\nvalue = 5;\r\ntry {\r\n    if (value === 5) {\r\n        throw new Error(\"El número es igual a 5\")\r\n    }\r\n    console.log(\"El número es distinto de 5\")\r\n} catch (error) {\r\n    console.log(\"Se ha producido un error porque \"+error.message)\r\n} finally {\r\n    console.log(\"Bloque finally. Esto siempre se ejecuta haya o no excepción\")\r\n}\r\nconsole.log('========================')\r\n\r\n\r\n//DIFICULTAD EXTRA:\r\n/*\r\nCrea un programa que imprima por consola todos los números comprendidos\r\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\r\n*/\r\nconsole.log('========================')\r\nconsole.log(`Crea un programa que imprima por consola todos los números comprendidos\r\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\r\nfor (let i = 10; i<=58; i++ ){\r\n  if (i%2===0 && i !== 16 && i%3!==0){\r\n    console.log(i)\r\n  }\r\n}`)\r\nfor (let i = 10; i<=55; i++ ){\r\n  if (i%2===0 && i !== 16 && i%3!==0){\r\n    console.log(i)\r\n  }\r\n}\r\nconsole.log('========================')\r\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/JanuarAsprilla.js",
    "content": "/* Tipos de operadores logicos */\n\n// Valores iniciales\nlet dato1 = 15;\nlet dato2 = 30\n//Operadores\n\nlet asg = dato1;\n\n/*Problemas para Practicar Operadores de Asignación */\n\nconsole.log(`**********Actualiza el precio de un producto aplicando impuestos dinámicos**********\\n\\n1- Tienes un producto con un precio base. El porcentaje de impuesto puede variar según la región.\\nUsa el operador correcto para actualizar el precio del producto tras aplicar el impuesto.\\n\\nImpuesto: 19%\\nPrecio de producto: $80.000\\n`)\n//datos de entrada\nlet precioProducto = 80000;\nconst impuestoRegion = 0.19; \n\nlet precioTotal = precioProducto *= (1 + impuestoRegion);\n\nconsole.log(`EL precio total del producto, incluyendo el impuesto es de $${precioTotal.toFixed(2)}\\n\\n`)\n\n\nconsole.log(`**********Reduce el tiempo restante en un temporizador**********\\n\\n 2-Estás desarrollando una app de productividad.\\n Tienes un temporizador que empieza en cierto número de minutos.\\n Cada ciclo reduce el tiempo en 5 minutos.\\n`)\nlet tiempoRestante = 30; // minutos\nconst duracionCiclo = 5; // minutos\n\ntiempoRestante -= duracionCiclo\n\nconsole.log(`El temporizador, tras el ciclo queda en ${tiempoRestante} minutos\\n\\n`)\n\nconsole.log(`**********Escala un puntaje entre 0 y 100 a una escala de 0 a 10**********\\n\\n3-Un sistema devuelve puntajes del 0 al 100, pero necesitas convertirlos a una escala del 0 al 10 para mostrarlos en una interfaz amigable.\\n`)\nlet puntajeOriginal = 75;\nlet puntajeConvertido = puntajeOriginal /= 10\nconsole.log(`EL puntaje convertido es de ${puntajeConvertido}\\n\\n`)\n\nconsole.log(`**********Convierte segundos totales en minutos**********\\n\\n4-Tienes una variable con la cantidad total de segundos transcurridos y necesitas convertirla a minutos.\\n`)\nlet segundosTotales = 360;\nlet minutosTotales = segundosTotales /= 60\n\nconsole.log(`Los ${segundosTotales} segundos son equivalentes a ${minutosTotales} minutos\\n\\n`)\n\nconsole.log(`**********Alterna entre modos claro y oscuro usando XOR bit a bit**********\\n\\n5-En una aplicación de configuración, tienes una bandera (modoOscuro) que indica si está activado el modo oscuro.\\n Usa el operador adecuado para alternar su valor entre true y false.\\n`)\nlet modoOscuro = true;\nmodoOscuro ^= true \nconsole.log(`¿El modo oscuro esta activado?: ${modoOscuro}\\n\\n`)\n\nconsole.log(`**********Calcula el crecimiento exponencial de usuarios**********\\n\\n6-Una startup tiene 1000 usuarios iniciales y experimenta un crecimiento del 20% mensual. Usa el operador correcto para calcular cuántos usuarios tendrán después de 6 meses.\\n`)\nlet usuarios = 1000;\nconst tasaCrecimiento = 1.2;\nconst meses = 6\nlet usuariosFinales = usuarios *= Math.pow(tasaCrecimiento, meses);\n\nconsole.log(`Los usuarios obtenidos despues de haber transcurrido 6 meses, la cifra es de ${usuariosFinales} usuarios\\n`)\n\n\nconsole.log(`**********Establece una configuración predeterminada solo si no está definida**********\\n\\n7-Tienes una variable que puede venir desde una API o no estar definida. Usa el operador lógico correcto para establecer un valor por defecto solo si es necesario.\\n`)\nlet idiomaUsuario = undefined;\nidiomaUsuario ??= 'Español'\nconsole.log(`El idioma del usuario es: ${idiomaUsuario}\\n`)\n\nconsole.log(`**********Filtra permisos de usuario usando AND bit a bit**********\\n\\n8-Tienes un sistema de roles basado en máscaras de bits. Usa el operador correcto para verificar si el usuario tiene permiso de administrador.`)\nconst PERMISO_ADMIN = 4; // 100 en binario\nlet permisosUsuario = 5; // 101 en binario\nlet tienePermisoAdmin = (permisosUsuario & PERMISO_ADMIN) !== 0;\nconsole.log(`¿El usuario cuenta con permiso de administrador?: ${permisosUsuario ? 'si' : 'no'}\\n`)\n\nconsole.log(`Combina colores RGB usando OR bit a bit**********\\n\\n9-Tienes tres variables que representan componentes de color rojo, verde y azul. Usa el operador correcto para combinarlos en un único valor entero que represente el color completo.`)\nlet rojo = 255 << 16;\nlet verde = 128 << 8;\nlet azul = 0;\nlet combinacion = rojo | verde | azul;\nconsole.log(`El color representativo es: ${combinacion} \\n`)\n\n//Aritmeticos\nconst numero1=10\nconst numero2=55\n\n\nconsole.log(`**********OPERADORES ARITMETICOS**********\\n\\n`)\nlet suma=numero1+numero2\nconsole.log(`La suma de 10 + 55 = ${suma} `)\nlet resta=numero1-numero2\nconsole.log(`La resta de 10 - 55 = ${resta}`)\nlet multiplicacion=numero1*numero2\nconsole.log(`La multiplicacion de 10 * 55 =${multiplicacion}`)\nlet division=numero2/numero1\nlet modulo=numero2%numero1\nconsole.log(`La division de 55 / 10 = ${division}\\n y el residuo de esta division es: ${modulo}`)\nlet elevacion=numero1**numero2\nconsole.log(`Eleva el numero 10 a 55 = ${elevacion}`)\n\n\n\nconsole.log(`**********ESTRUCTURAS DE CONTROL**********\\n\\n`)\n\nconsole.log(`1-Escribe un programa que determine si una persona puede votar. Para votar, debe ser mayor de edad (18 años o más) y estar registrada.`)\nlet edad = 20;\nlet registrada = true;\nif (edad >= 18){\n    console.log(\"Estas habilitado para votar, ya que cumples con la mayoria de edad\")\n}else{\n    console.log(\"No puedes votar, no eres mayor de 18 años\")\n}\n\nconsole.log(`Dado un puntaje entre 0 y 100, imprime la calificación equivalente:\\n\n90-100 → A\\n\n80-89 → B\\n\n70-79 → C\\n\n60-69 → D\\n\nMenos de 60 → F`)\nlet puntaje = \"85\";\nif (puntaje >= 90 && puntaje <= 100){\n    console.log(\"El resultado de la calificacion es: A\")\n}else if (puntaje >= 80 && puntaje <= 89){\n    console.log(\"El resultado de la calificacion es: B\")\n}else if (puntaje >= 70 && puntaje <= 79){\n    console.log(\"El resultado de la calificacion es: C\")\n}else if(puntaje >= 60 && puntaje <= 69){\n    console.log(\"El resultado de la calificacion es: D\")\n}else if(puntaje <= 59 ){\n    console.log(\"El resultado de la calificacion es: F\")\n}else{\n    console.log(\"El puntaje a evaluar es invalido; No se encuentra entre el rango de 0 a 100\")\n}\n\n\nconsole.log(`\\n\\nCrea un sistema que, dado un día de la semana (como número), muestre su nombre en español.`)\n\nlet dia = 3;\nswitch (dia) {\n    case 1 :\n        console.log(\"Lunes\")\n    break\n    case 2 :\n        console.log(\"Martes\")\n        break\n    case 3 :\n        console.log(\"Miercoles\")\n        break\n    case 4 :\n        console.log(\"Jueves\")\n        break\n    case 5 :\n        console.log(\"Viernes\")\n        break\n    case 6 :\n        console.log(\"Sabado\")\n        break\n    case 7 :\n        console.log(\"Domingo\")\n        break\n    default:\n        console.log(\"La opcion selecionada no es valida\")\n        break\n}\n\nconsole.log(`\\n\\nImprime los primeros 10 números dependiendo si se ingresa la palabra Par o Impar`)\nlet condicion=\"par\"\nif (condicion == \"par\"){\n    for (let num = 0; num < 10; num += 2){\n        console.log(`Los numeros son: ${num}`)\n    }\n}else{\n    for (let num = 1; num < 10; num += 2 ){\n        console.log(`los numeros son: ${num}`)\n    }\n}\n\nconsole.log(`\\n\\nSimula un cajero automático que pregunta por una contraseña hasta que sea correcta (usa while para repetir)`)\n\nimport { access } from 'fs';\n// Importar módulo readline\nimport { createInterface } from 'readline';\n\n// Crear interfaz para entrada/salida\nconst rl = createInterface({\n  input: process.stdin,\n  output: process.stdout\n});\n\nconst claveCorrecta = \"1234\";\n\nfunction pedirClave() {\n  rl.question(\"Ingrese su contraseña: \", (intento) => {\n    if (intento === claveCorrecta) {\n      console.log(\"¡Acceso permitido!\");\n      rl.close(); // Cierra la conexión\n    } else {\n      console.log(\"Contraseña incorrecta. Intente nuevamente.\");\n      pedirClave(); // Vuelve a preguntar\n    }\n  });\n}\n\n// Iniciar proceso\npedirClave();\n\n//Comparacion\n\nconsole.log(`**********OPERADORES COMPARACION**********\\n\\n`)\n\nlet Igual = dato1 == dato2\nlet NotIgual = dato1 != dato2\nlet IgualdaEstric = dato2 === dato2\nlet NotIgualdaEstric = dato1 !== dato1\nlet Mayor = dato1 > dato2\nlet MayorIgual= dato2 >= dato1\nlet Menor = dato1 < dato2\nlet MenorIgual= dato1 <= dato2\n\nconsole.log(`/********OPERADORES DE COMPARACION********/`)\nconsole.log(`Verifiquemos si el numero ${dato1} es igual(==) a el numero ${dato2}, el resultado es: ${Igual}.`)\nconsole.log(`Verifiquemos si el numero ${dato1} no es igual(!=) al numero ${dato2} el resutado es: ${NotIgual}`)\nconsole.log(`Verifiquemos si el numero ${dato2} es estrictamente igual(===) al numero ${dato2} el resutado es: ${IgualdaEstric}`);\nconsole.log(`Verifiquemos si el numero ${dato1} no es estrictamente igual(!==) al numero ${dato1} el resutado es: ${NotIgualdaEstric}`)\nconsole.log(`El numero ${dato1} es mayor que(>) el numero ${dato2} : ${Mayor}`)\nconsole.log(`El numero ${dato2} es mayor que o igual(>=) el numero ${dato1} : ${MayorIgual}`)\nconsole.log(`El numero ${dato1} es menor que(<) el numero ${dato2} :${Menor}`)\nconsole.log(`El numero ${dato1} es menor que o igual(<=) el numero ${dato2} :${MenorIgual}`)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/JeisonRedondo.js",
    "content": "/*\n######################33 Operadores en Javascript \n*/\n\n// ------------------------------> Operadores Aritmeticos\n\nlet suma = 34 + 12; // Este operador nos permite sumar dos valores de tipo númerico.\nconsole.log(\"Result - Suma: \", suma);\n\nlet saludo = \"Hola gente\" + \" ¿Como están?\"; // Cuando es usado con strings los concatena (los une)\nconsole.log(\"Result - Saludo: \", saludo);\n\nconst resta = 100 - 80; // Genera una resta de los valores involucrados en la operacion.\nconsole.log(\"Result - Resta: \", resta);\n\nconst yoPuedoMultiplicar = 12 * 24; // Este simboolo de manera unica genera una multiplicación.\nconsole.log(\"Result - Multiplicación: \", yoPuedoMultiplicar);\n\nlet operacionDeExponentes = 2 ** 3; // Usando el simbolo anterior dos veces podemos hacer una exponenciación.\nconsole.log(\"Result - Exponenciación: \", operacionDeExponentes);\n\nconst paraDividir = 36 / 12; // Con este obtenemos el resultado de la operación de división.\nconsole.log(\"Result - División: \", paraDividir);\n\nlet estoSeLlamaUnResiduo = 36 % 6; // El operador de modulo, nos permite conocer sí y cuál es el entero de una división.\nconsole.log(\"Result - Residuo: \", estoSeLlamaUnResiduo);\n\n/*\n * Aca podemos ver aplicaciones interesantes con estos operadores que si no se tiene cuidado pueden confidir,\n * cuando se ejecuta el codigo normalmente se va de izquierda a derecha.\n * Al usar algunas de las  ventajas de los operadores aritmeticos podemos obtener resultados inesperados\n * si no manejamos esto con cuidado, recuerda siempre tener presente que si quieres aplicar el cambio\n * en esa misma operación debes usar las ventajas de ++variable y --variable desde el lado izquierdo al derecho,\n * pues podrias llegar a ver el resultado en la siguiente lectura del valor y no en la inmediata.\n **/\n\nlet a = 3;\n// Value of a=4 and returns 4\nconsole.log(++a);\n// Value of a=5 and returns 4\nconsole.log(a++);\n// Value of a=5 and returns 5\nconsole.log(a);\n\nlet b = 3;\n// Value of b=2 and returns 2\nconsole.log(--b);\n// Value of b=1 and returns 2\nconsole.log(b--);\n// Value of b=1 and returns 1\nconsole.log(b);\n\n// Recurso obtenido :https://ifgeekthen.nttdata.com/es/tipos-de-datos-y-operadores-en-javascript\n\n// ------------------------------> Operadores de Asignación\n\nconst asignandoUnHola = \"Hola\"; // Lo hemos usado para asignar desde el reto pasado pero, no ahi que olvidarlo.\nconsole.log(\"Result - Asignación: \", asignandoUnHola);\n\nlet asignaUnaSuma = 34;\nasignaUnaSuma += 5; // Aqui estamos generando una asignación con una suma dentro tal como: a = a+b\nconsole.log(\"Result - Asignación y sumale 5: \", asignaUnaSuma);\n\nlet asignaUnaResta = 52;\nasignaUnaResta -= 12; // Aqui estamos generando una asignación con una resta dentro tal como: a = a-b\nconsole.log(\"Result - Asignación y restale 12: \", asignaUnaResta);\n\nlet asignaUnaMultiplicacion = 12;\nasignaUnaMultiplicacion *= 4; // Aqui estamos generando una asignación con una multiplicación dentro tal como: a = a*b\nconsole.log(\n  \"Result - Asignación y multiplica por 4: \",\n  asignaUnaMultiplicacion,\n);\n\n// Puedes aplicarlo tal cuál para la división, modulo y exponenciación.\n\n// ------------------------------> Operadores de Comparación.\n\nconsole.log(\"Igualdad No estricto: \", 4 == \"4\"); // Operador de igualdad NO estricto. Este operador compara el valor pero ignora el tipo R/=True.\n\nconsole.log(\"Desigualdad NO Estricto: \", 4 != \"4\"); // Operador de desigualdad NO estricto. Este operador compara el valor y ignora el tipo R/=False.\n\nconsole.log(\"Igualdad Estricto: \", 4 === \"4\"); // Operador de igualdad Estricto. Este operador compara el valor y el tipo R/=False.\n\nconsole.log(\"Desigualdad Estricto: \", 4 !== \"4\"); // Operador de desigualdad Estricto. Este operador compara el valor y el tipo R/=True.\n\nconsole.log(\"Mayor que: \", 32 > 12); // Operador \"Mayor que\", compara si la primera expresión es mayor que la segunda R/=True.\n\nconsole.log(\"Menor que: \", 12 < 34); // Operador \"Menor que\", compara si la primera expresión es menor que la segunda R/=True.\n\nconsole.log(\"Mayor o igual que: \", 12 >= 14); // Operador \"Mayor o igual que\", compara si la primera expresión es mayor o igual que la segunda R/=False.\n\nconsole.log(\"Menor o igual que\", 12 <= 14); // Operador \"Menor o igual que\", compara si la primera expresión es menor o igual que la segunda R/=True.\n\n// ------------------------------> Operadores Logicos.\n\n/*\n * La interpretación que reciben los valores con estos operadores tiene unas caracteristicas que tenemos que\n * tener en cuenta. Para empezar, si estás comparando valores no binarios (que no son ni 0 ó 1, ni True ó false)estos\n * operadores intepretaran en base al tipo de valor si se puede convertir en un false o true por ellos mismos\n * y ejecutaran la comparación si se da el caso.\n *\n */\n\nconsole.log(\"AND Logico => &&: \", true && false); // Este operador necesita que los dos operadores sean true para dar True.\n\nconsole.log(\"Or Logico => || : \", true || false); // Este operador necesita que haya un operador true para dar True.\n\nconsole.log(\"NOT Logico, !: \", !true); // Este operador devuleve falso si la expresión se puede interpretar como True.\n\n// ------------------------------> Operadores bitwise.\n/*Bitwise se puede interpretar como una operación bit a bit, lo cuál es lo que sucede aqui.\n * Estos operadores generan una acción primitiva sobre los los bits individuales de los numeros binarios.\n */\n\nconsole.log(\"Bitwise AND &: \", 4 & 1); // Esta operación compara con el and y da un resultado de tipo binario R/= 0 (False).\n\nconsole.log(\"Bitwise OR |: \", 4 | 1); // Esta operación compara con el or y da un resultado de tipo binario R/= 5 (True).\n\nconsole.log(\"Bitwise XOR ^: \", 4 ^ 1); // Esta operación compara con el or de forma exclusiva en cada operando R/= 5 (True).\n\nconsole.log(\"Bitwise NOT ~: \", ~4); // Esta operación invierte los bits del operando.\n\nconsole.log(\"Bitwise << : \", 4 << 1); // Este operador desplaza los bits del primer número a la izquierda la cantidad del segundo.\n\nconsole.log(\"Bitwise >> : \", 4 >> 1); // Este operador desplaza los bits del primer número a la derecha la cantidad del segundo.\n\n// ------------------------------> Operadores Especiales\n\n// Operador Ternario.\nconst edadDelChacho = 17;\nlet siEsMenorDeEdad =\n  edadDelChacho < 18 ? \"No puedes pasar, !!MOCOS0¡¡\" : \"Pase Adelante Señor...\";\nconsole.log(\"Que edad tienes joven?: \", siEsMenorDeEdad); // Este es un if abreviado, usarlo encadenado requiere cuidado.\n\n// Operador typeof.\nconst queSeraEstaVariable = \"Soy un String sumerce\";\nconsole.log(\n  \"!!He descubierto el tipo de la variable¡¡ JAJAJAJA, es... : \",\n  typeof queSeraEstaVariable,\n);\n//Este operador nos permite identifica el tipo de dato que contiene uan variable, en JS con su libertad de lenguaje,\n//podemos a veces perderle la pista a este tipo de cosas, por eso es necesario usarlo.\n\n// -------------------------> Estructuras de Control.\n\n// ---------->> IF/ELSE\nlet soyLaCondicion = true;\n\nif (soyLaCondicion === true) {\n  // La estructura if verifica una condición y en base a la misma ejecuta o pasa de largo.\n  console.log(\"!! He entrado¡¡\");\n} else if (soyLaCondicion === false) {\n  // Esta es otra medida en este sistema de manejo de condiciones que nos permite controlar mas\n  // las opciones requeridas en el programa.\n  console.log(\"Ja soy falso, noooo\");\n} else {\n  // Esta estructura nos permite controlar el rechazo de un if con el cuál podemos manejar las negativas de la\n  //condicion.\n  console.log(\"!!NO eh entrado¡¡\");\n}\n\n// ------------>> WHILE/DO-WHILE\n//\nlet soyElContadorDelWhile = 0;\nwhile (soyElContadorDelWhile < 10) {\n  // La estructura del while se define por el hecho de iterar, de generar una ejecución\n  // continua de el codigo que contiene hasta que se cumple la condición que procesa.\n  console.log(`Estamos contando en el while vamos en ${soyElContadorDelWhile}`);\n  soyElContadorDelWhile++;\n}\n\ndo {\n  // Esta estructura mantiene las mismas base de el while pero se ejecutara al menos uan vez.\n  console.log(\"Pooooor lo menos una vez, ejecuuuutame.\");\n  soyElContadorDelWhile++;\n} while (soyElContadorDelWhile === 10);\n\n// ------------->> SWITCH\nlet diaDeDescanso = \"Martes\";\nswitch (\n  diaDeDescanso // El switch obtiene una variable a traves de la cuál puede selecionar la opcion a ejecutar.\n) {\n  case \"Lunes\":\n    console.log(\"Pues el lunes sera.\");\n    break;\n  case \"Martes\":\n    console.log(\"Uy si, el martes\");\n    break;\n  default:\n    console.log(\"Pues no se man...\");\n    break;\n}\n\n// -------------->> FOR\n\nfor (let index = 10; index > 0; index--) {\n  // For nos permite controlar la cantidad de ejecuciones que queremos tener\n  // de un codigo en especifico.\n  console.log(`Despegando en ${index}`);\n}\n\n// -------------------------> Programa NoSoyNiInparNiMultiploDeTres.\n\nfunction NoSoyNiInparNiMultiploDeTres(startLine = 10, FinalLIne = 55) {\n  for (let index = startLine; index <= FinalLIne; index++) {\n    if (index % 2 == 0 && index % 3 != 0 && index != 16) {\n      console.log(\"No soy ni inpar, ni multiplo de tres, ni 16: \", index);\n    }\n  }\n}\n\nNoSoyNiInparNiMultiploDeTres();\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #01 - JavaScript ->Jesus Antonio Escamilla */\n/**\n * -----TIPOS DE OPERADORES-----\n * Dentro operadores empezaremos con\n * Aritméticos\n * Lógicos\n * Asignación\n * Comparación\n */\n\n/**\n * ---ARITMÉTICOS---\n * Dentro de estos hay están las operaciones básicas\n * de las cuales derivan la suma, resta, division o multiplicación.\n*/\n    console.log(2 + 3); // La suma el resultado es 5\n    console.log(5 - 3); // La resta en la cual el resultado es 2\n    console.log(16 / 4); // La division en donde el resultado es 4\n    console.log(5 * 7); // La multiplicación por el cual el resultado es 35\n\n\n/**\n * ---LÓGICOS---\n * Los cuales dan solo una respuesta si VERDADERO o FALSO.\n */\n\n// El && es una comparación que solo vuelve si los dos son TRUE\n    console.log(true && true); //TRUE\n    console.log(false && true); //FALSE\n    console.log(false && false); //FALSE\n\n// El || hace una comparación solo cuando los dos sean FALSE\n    console.log(true || true); //TRUE\n    console.log(false || true); //TRUE\n    console.log(false || false); //FALSE\n\n// El ! es lo contrario de uno ya sea TRUE o FALSE\n    console.log(!true);  //FALSE\n    console.log(!false); //TRUE\n\n\n/**\n * ---ASIGNACIÓN---\n * Son operadores que se asignan a valores\n * que ya existen en las variables,\n * también la sintaxis en como se escribe.\n*/\n// El = es para asignar un valor a la variable\nvar x = 10;\nconsole.log(x); // 10\n\n// El += es una asignación con una adicción\nvar num1 = 6\nconsole.log(num1 += 5); // 11\n\n// El -= es de restar a la asignación\nvar num2 = 4;\nconsole.log(num2 -= 3); // 1\n\n// El *= es para multiplicar la asignación\nvar z = 4;\nconsole.log(z *= 7); // 28\n\n// El /= es la división la asignación\nvar y = 64;\nconsole.log(y /= 2); // 32\n\n// El %= es el residuo de la asignación\nvar residuo = 100;\nconsole.log(residuo %= 11); // 11\n\n// El **= es el exponente de una asignación \nvar expo = 4;\nconsole.log(expo **= 2); // 16\n\n// Estos operadores no se utilizan ya que todo el proceso es a nivel bit\n\n// El <<= es decir que los bits de una asignación se recorran los bits del segundo valor y se convierte en el bit existente a decimal\nvar izquierda = 2;\nconsole.log(izquierda <<= 1); // 4\n\n// El >>= es decir que los bits de una asignación se recorran los bits del segundo valor y se convierte en el bit existente a decimal\nvar derecha = 2;\nconsole.log(derecha >>= 1); // 1\n\n\n\n/**\n * ---COMPARACIÓN---\n * Estos sirven para comprar diferentes fuentes\n * o variables en las cuales se utilizan,\n * sirven también si un proceso se realiza o no.\n*/\nvar variable1 = 3;\nvar variable2 = 4;\n\n//El == vuelve true si son iguales\nconsole.log(variable1 == \"3\"); //true\nconsole.log(variable1 == 3); //true\n\n//El != vuelve true no son iguales\nconsole.log(variable2 != \"3\"); //true\nconsole.log(variable1 != 4); //true\n\n//El === vuelve true si son iguales y son del mismo tipo\nconsole.log(variable1 === 3); //true\n\n//El < vuelve true si  es menor que\nconsole.log(variable1 < variable2); //true\n\n//El <= vuelve true si  es menor que o igual que\nconsole.log(variable1 <= 3); //true\n\n//El > vuelve true si es mayor que\nconsole.log(variable1 > variable2); //false\n\n//El >= vuelve true si  es menor que o igual que\nconsole.log(variable1 >= 4); //false\n\n\n\n\n/**\n * -----TIPO DE ESTRUCTURA DE CONTROL-----\n * Dentro de las estructuras de control existen estos:\n * If-Else\n * Switch\n * While\n * Do while\n * For\n * Try Catch\n */\n\n//---IF - ELSE---\nvar edad = 19;\nif (edad >= 18) {\n    console.log(\"Es mayor de edad, puede votar\");\n} else {\n    console.log(\"No es mayor de edad, regrese cuando tenga 18 años cumplidos\");\n}\n\n//---SWITCH---\nvar hoy = new Date();\nvar nombreMes;\nvar mes=hoy.getMonth();\nswitch (mes) {\n    case 0 :\n        nombreMes = \"Enero\";\n        break;\n    case 1 :\n        nombreMes = \"Febrero\";\n        break;\n    case 2 :\n        nombreMes = \"Marzo\";\n        break;\n    case 3 :\n        nombreMes = \"Abril\";\n        break;\n    case 4 :\n        nombreMes = \"Mayo\";\n        break;\n    case 5 :\n        nombreMes = \"Junio\";\n        break;\n    case 6 :\n        nombreMes = \"Julio\";\n        break;\n    case 7 :\n        nombreMes = \"Agosto\";\n        break;\n    case 8 :\n        nombreMes = \"Septiembre\";\n        break;\n    case 9 :\n        nombreMes = \"Octubre\";\n        break;\n    case 10 :\n        nombreMes = \"Noviembre\";\n        break;\n    case 11 :\n        nombreMes = \"Diciembre\";\n        break;\n    default:\n        nombreMes = \"No existe el mes\"\n        break;\n}\nconsole.log(\"El mes es \" + nombreMes);\n\n//---WHILE---\nvar i = 0;\nwhile (i <= 9) {\n    console.log(i);\n    i++;\n}\n/* Entro imprime en la consola\n0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n */\n\n//---DO WHILE---\nvar numero = 1;\nvar resultado = 2;\ndo {\n    numero++;\n    resultado = resultado * numero;\n    console.log(resultado);\n} while (numero < 5);\n/* Entro imprime en la consola\n4\n12\n48\n240\n*/\n\n//---FOR---\nfor (let i = 0; i <= 10; i++) {\n    console.log(i);\n}\n/* Entro imprime en la consola\n0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10*/\n\n//---TRY - CATCH---\ntry {\n    throw new Error('Si funciona');\n} catch (error) {\n    console.error(error.message);\n}\n/**\n * En este caso cuando se ejecuta si es\n * correcto la operación pasara por el try-catch,\n * en dado caso de causar conflicto se ira directo al error\n*/ \n\n\n\n/**-----DIFICULTAD EXTRA-----*/\nfor (let i = 10; i < 55; i++) {\n    if((i % 2 == 0) && (i !== 16) && (i % 3 !== 0)){\n        console.log(i);\n    }\n}\n/**-----DIFICULTAD EXTRA-----*/"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/JheisonQuiroga.js",
    "content": "/*\n# Author: Jheison Duban Quiroga Quintero\n# Github: https://github.com/JheisonQuiroga\n\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n * */\n\n// Operadores\n\n// 1.1. Operadores Aritméticos\nlet a = 10;\nlet b = 5;\n\nconsole.log(a + b)\nconsole.log(a - b)\nconsole.log(a * b)\nconsole.log(a / b)\nconsole.log(a % 2)\nconsole.log(a ** 2)\n\n// 1.2. Operadores lógicos\n\nconsole.log(true && false) // AND\nconsole.log(false || true)  // OR\nconsole.log(!true)  // NOT\n\n// 1.3. Operadores de asignación\n\nconsole.log(a == \"10\") // Igualdad por valor y no identidad = true\nconsole.log(a === \"10\") // Igualdad por valor e identidad = false \nconsole.log(a > b)\nconsole.log(a < b)\nconsole.log(a >= b)\nconsole.log(a <= b)\n// Distinto\nconsole.log(a != 10) // Distinto por valor\nconsole.log(a !== \"10\") // Distinto por valor e igualdad\n\n// 1.4. Operadores de asignación\nlet c = 10;\nc += 10; // c = c + 10\nconsole.log(c)\nc -= 10; // c = c - 10\nconsole.log(c)\nc *= 10; // c = c * 10\nconsole.log(c)\nc /= 10; // c = c / 10\nconsole.log(c)\nc %= 10; // c = c % 10\nconsole.log(c)\nc = 10\nconsole.log(c)\nc **= 2 // c = c ** 2\nconsole.log(c)\n\n// 1.5. Operadores de identidad\n\nconsole.log(5 === 5)\nconsole.log(5 === \"5\")\n\n// 1.6. Operadores de pertenencia\n\nlet myArray = [1, 2, 3, 4, 5]\nconsole.log(myArray.includes(5))\nconsole.log(myArray.includes(6))\n\nlet obj = {key: \"value\"}\nconsole.log(\"key\" in obj)\n\n// 1.7. Operadores Bitwise\nconsole.log(\"\\n=== Operadores Bitwise ===\");\nlet d = 5, e = 3;  // 0101 & 0011\nconsole.log(\"AND:\", d & e);   // 0001 = 1\nconsole.log(\"OR:\", d | e);    // 0111 = 7\nconsole.log(\"XOR:\", d ^ e);   // 0110 = 6\nconsole.log(\"NOT:\", ~d);      // 11111010 (complemento a 2)\nconsole.log(\"Left shift:\", d << 1);  // 1010 = 10\nconsole.log(\"Right shift:\", d >> 1); // 0010 = 2\n\n// 2. Estructuras de control\n\n// 2.1. if, else if, else\n\na = 10, b = 5\n\nif (a > b) {\n    console.log(`${a} es mayor que ${b}`)\n} else if (a < b) {\n    console.log(`${a} es menor que ${b}`)\n} else {\n    console.log(`${a} es igual que ${b}`)\n}\n\n// 2.2. Operador ternario\n\nlet message = a >= b ? `${a} es mayor o igual que ${b}` : `${a} es menor que ${b}`\nconsole.log(message)\n\n// 2.3. switch case\n\nlet numberDay = 1\nswitch (numberDay) {\n    case 1:\n    case 2:\n    case 3:\n        console.log(\"Entre semana\")\n        break\n    case 4:\n    case 5:\n        console.log(\"Ya casi es fin de semana\")\n        break\n    case 6:\n    case 7:\n        console.log(\"Fin de semana, yupi!\")\n        break\n    default:\n        console.log(\"No es un día de la semana\")\n}\n\n// 2.4. for Loop\n\nfor (let i = 0; i < 5; i++) {\n    console.log(i)\n}\n\n\n// For para iterables, accediendo por su indice\n\nlet names = [\"Duban\", \"Jheison\", \"Anderson\"]\n\n\nfor (let i = 0; i < names.length; i++) {\n    console.log(names[i])\n}\n\n// 2.4.1 For ... of (para iterables)\n\n\nfor (let name of names) {\n    console.log(name)\n}\n\n// 2.4.2 For ... in (para objetos)\n\nlet obj2 = {\n    name: \"Duban\", \n    lastname: \"Quiroga\",\n    age: 26\n}\n\nfor (let key in obj2) {\n    console.log(key, obj2[key])\n}\n\n// 2.4.3 ForEach (para iterables)\n\nnames.forEach((value, index) => {\n    console.log(`${++index} - ${value}`)\n})\n\n// 2.5. while\n\nlet i = 0\n\nwhile (i < 5) {\n    console.log(i)\n    i++\n}\n\ni = 5\n\n// 2.5.1. do ... while\n\ndo {\n    console.log(i)\n    i++\n} while (i < 5)\n\n\n// 3. Excepciones\n\ntry {\n    throw Error(\"Este es un mensaje de error\") // Genera una excepcion\n} catch (e) {\n    console.log(e.message)\n} finally {\n    console.log(\"Finally siempre se ejecuta\")\n}\n\n/* \n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n*/\n\nfor (let i = 10; i <= 55; i++) {\n    if (i % 2 == 0 && i != 16 && i % 3 != 0) {\n        console.log(i)\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/Joanfv-git.js",
    "content": "//Operadores Aritméticos\nconsole.log(\"Suma:\" + 5 + 5);\nconsole.log(\"Resta:\" + 5 - 5);\nconsole.log(\"Multiplicación:\" + 5 * 5);\nconsole.log(\"División:\" + 5 / 5);\nconsole.log(\"Módulo:\" + 5 % 5);\nconsole.log(\"Incremento:\" + 5++);\nconsole.log(\"Decremento:\" + 5--);\n\n//Operadores Logicos\nconsole.log(\"AND:\" + (true && true));\nconsole.log(\"OR:\" + (true || false));\nconsole.log(\"NOT:\" + !true);\n\n//Operadores de comparación\nconsole.log(\"Igualdad:\" + (5 == 5));\nconsole.log(\"Desigualdad:\" + (5 != 5));\nconsole.log(\"Mayor que:\" + (5 > 5));\nconsole.log(\"Menor que:\" + (5 < 5));\nconsole.log(\"Mayor o igual que:\" + (5 >= 5));\nconsole.log(\"Menor o igual que:\" + (5 <= 5));\n\n//Operdaores de asignación\nlet a = 5;\nconsole.log(\"Asignación:\" + a);\na += 5;\nconsole.log(\"Suma:\" + a);\na -= 5;\nconsole.log(\"Resta:\" + a);\na *= 5;\nconsole.log(\"Multiplicación:\" + a);\na /= 5;\nconsole.log(\"División:\" + a);\na %= 5;\nconsole.log(\"Módulo:\" + a);\n\n//Operadores de identidad\nconsole.log(\"Igualdad de valor y tipo:\" + (5 === 5));\nconsole.log(\"Desigualdad de valor y tipo:\" + (5 !== 5));\n\n//Operadores de pertenencia\nlet b = [1, 2, 3, 4, 5];\nconsole.log(\"Incluido:\" + (5 in b));\nconsole.log(\"No incluido:\" + (6 in b));\n\n//Estructuras de control\n\n//Estructuras de control de condicionales\n//If\nlet c = 5;\nif (c == 5) {\n    console.log(\"Es 5\");\n} else if (c == 6) {\n    console.log(\"No es 5\");\n}   else {\n    console.log(\"No es 5 ni 6\");\n}\n//Switch\nlet d = 5;\nswitch (d) {\n    case 5:\n        console.log(\"Es 5\");\n        break;\n    case 6:\n        console.log(\"Es 6\");\n        break;\n    default:\n        console.log(\"No es 5 ni 6\");\n}\n\n//Estructuras de control de iteración\n//While\nlet e = 5;\nwhile (e > 0) {\n    console.log(e);\n    e--;\n}\n//Do-While\nlet f = 5;\ndo {\n    console.log(f);\n    f--;\n}\nwhile (f > 0);\n//Break\nlet l = 0;\nwhile (l < 5) {\n    console.log(l);\n    l++;\n    if (l == 3) {\n        break;\n    }\n}\n//Continue\nlet m = 0;\nwhile (m < 5) {\n    m++;\n    if (m == 3) {\n        continue;\n    }\n    console.log(m);\n}\n//For\nfor (let g = 0; g < 5; g++) {\n    console.log(g);\n}\n//For-In\nlet h = [1, 2, 3, 4, 5];\nfor (let i in h) {\n    console.log(h[i]);\n}\n//For-Of\nlet j = [1, 2, 3, 4, 5];\nfor (let k of j) {\n    console.log(k);\n}\n\n//Estructuras de control de excepciones\ntry {\n    throw \"Error\";\n}\ncatch (error) {\n    console.log(error);\n}\nfinally {\n    console.log(\"Fin\");\n}\n\n//Ejericio extra\nlet array = [];\nfor (let n = 10; n < 56; n++) {\n    if (n % 2 == 0 && n!=16 && n % 3 != 0) {\n        array.push(n);\n    }\n    \n}\nconsole.log(array);\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/JoaquinLopez14.js",
    "content": "/*\n * EJERCICIO:\n\n * 1 Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n        Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n        (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * 2 Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n        que representen todos los tipos de estructuras de control que existan\n        en tu lenguaje: Condicionales, iterativas, excepciones...\n * 3 Debes hacer print por consola del resultado de todos los ejemplos.\n \n * DIFICULTAD EXTRA (opcional):\n\n 1.1 Crea un programa que imprima por consola todos los números comprendidos\n  entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n \n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n  // 1\n    // Operadores Aritmeticos\nlet suma = 6 + 7;\nlet resta = 6 - 7;\nlet multiplicacion = 6 * 7;\nlet division = 6 / 7;\nlet sobrante = 6 % 7;\n\nconsole.log(suma);\nconsole.log(resta);\nconsole.log(multiplicacion);\nconsole.log(division);\nconsole.log(sobrante);\n\n    // Operador de Incremento y Decremento\nlet numero = 6\nnumero++ // 7\nnumero-- // 6\n\nconsole.log('Numero despues del incremento y el decremento', numero)\n\n    // Operadores de Asignación \nlet a = 6;\n\na += 7; // a = 13\nconsole.log('a += 7:', a);\n\na -= 7; // a = 6\nconsole.log('a -= 7:', a);\n\na *= 7; // a = 42\nconsole.log('a *= 7:', a);\n\na /= 7; // a = 6\nconsole.log('a /= 7:', a);\n\n    // Operadores de Comparacion\nlet numero1 = 2\nlet numero2 = 4\n\nconsole.log('numero1 === numero2:', numero1 === numero2); // Comprueba si ambos valores son iguales\nconsole.log('numero1 !== numero2:', numero1 !== numero2); // Comprueba si ambos valores no son iguales\nconsole.log('numero1 < numero2:', numero1 < numero2); // Comprueba si el valor izquierdo es menor que el derecho\nconsole.log('numero1 > numero2:', numero1 > numero2); // Comprueba si el valor izquierdo es mayor que el derecho\nconsole.log('numero1 <= numero2:', numero1 <= numero2); // Comprueba si el valor izquierdo es menor o igual que el derecho\nconsole.log('numero1 >= numero2:', numero1 >= numero2); // Comprueba si el valor izquierdo es mayor o igual que el derecho\n\n    // Operadores Logicos\nlet logica1 = 2\nlet logica2 = 3\n\nconst resultado1 = (logica1 === logica2)\nconst resultado2 = (logica1 !== logica2)\nconst resultado3 = (logica1 > logica2)\nconst resultado4 = (logica1 < logica2)\n\n// && => Ambos valores deben ser verdaderos\n\nconsole.log('resultado2 && resultado4:', resultado2 && resultado4); // true\nconsole.log('resultado1 && resultado4:', resultado1 && resultado4); // false\nconsole.log('resultado3 && resultado4:', resultado3 && resultado4); // false\nconsole.log('resultado1 && resultado3:', resultado1 && resultado3); // false\n\n// || => Uno de los 2 valores debe ser verdadero\n\nconsole.log('resultado2 || resultado4:', resultado2 || resultado4); // true\nconsole.log('resultado1 || resultado4:', resultado1 || resultado4); // true\nconsole.log('resultado3 || resultado4:', resultado3 || resultado4); // true\nconsole.log('resultado1 || resultado3:', resultado1 || resultado3); // false\n\n    // Operadores de Cadena \n\nlet nombre = \"Joaquin\"\nlet apellido = \"Lopez\"\nlet nombreCompleto = \"Joaquin\" + \" \" + \"Lopez\"\n\nconsole.log('Nombre Completo:', nombreCompleto);\n\n// 2\n\n    // if, else\nlet valor = 5\n if ( valor === 5) {\n  console.log(valor)\n } else {\n  console.log(\"el valor no es compatible\")\n }\n\n  // while\nlet valor2 = 1\n  while( valor2 < 10) {\n    console.log(valor2)\n    valor2++\n }\n\nconsole.log(valor2)\n\n\n\n// 1.1 Dificultad Extra\n\nfunction printNumbers() {\n    for ( let i = 10; i <= 55; i++) {\n      if ( i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n            console.log(i)\n        }\n    }\n}\n\nprintNumbers()\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/Jorge186414.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n//* Opearadores de Asignacion\nvar x\nvar y = x\n// Asignacion de adicion\nconsole.log(x += y)\n// Asignacion de resta\nconsole.log(x -= y)\n// Asignacion de multiplicacion\nconsole.log(x *= y)\n// Asignacion de division\nconsole.log(x /= y)\n// Asignacion de residuo\nconsole.log(x %= y)\n// Asignacion de exponenciacion\nconsole.log(x **= y)\n\n//* Operadores de Comparacion\nvar numero1 = 10\nvar numero2 = 8\n// Igual\nconsole.log(numero1 == numero2)\n// No es igual\nconsole.log(numero1 != numero2)\n// Estrictamente igual\nconsole.log(numero1 === numero2)\n// Desigualdad estricta\nconsole.log(numero1 !== numero2)\n// Mayor que\nconsole.log(numero1 > numero2)\n// Mayor o igual que\nconsole.log(numero1 >= numero2)\n// Menor que\nconsole.log(numero1 < numero2)\n// Menor o igual que\nconsole.log(numero1 <= numero2)\n\n//* Operadores Aritmeticos\n// Residuo\nconsole.log(numero1 % numero2)\n// Suma\nconsole.log(numero1 + numero2)\n// Resta \nconsole.log(numero1 - numero2)\n// Division\nconsole.log(numero1 / numero2)\n// Multitplicacion\nconsole.log(numero1 * numero2)\n// Decremento\nconsole.log(numero1--)\n// Incremento\nconsole.log(numero2++)\n\n//* Operadores bit a bit \nvar var1 = 8\nvar var2 = 4\n// AND\nconsole.log(var1 & var2)\n// OR\nconsole.log(var1 | var2)\n// XOR \nconsole.log(var1 ^ var2)\n// NOT\nconsole.log(~var1);\n// Desplazamiento a la derecha\nconsole.log(var1 >> 1)\n// Desplazamiento a la izquierda\nconsole.log(var1 << 1)\n// Desplazamiento a la derecha sin signo\nconsole.log(var1 >>> 1)\n\n//* Operadores Logicos\nvar x = 19\nvar y = 87\nlet and = (x < y) && (y > 70)\nlet or = (x == y) || (x < y)\nlet not = !(x > y)\nconsole.log(`AND: ${and}`)\nconsole.log(`OR: ${or}`)\nconsole.log(`NOT: ${not}`)\n\n//* Operadores de cadena\n// Concatenacion \nlet nombre = 'Jorge'\nconsole.log(\"Hola \" + nombre);\n// Concatenacion Abreviado\nnombre += ' Miranda'\nconsole.log(nombre);\n\n// Operador condicional (Ternario)\nlet edad = 22\nlet resultado = edad >= 18 ? 'Es mayor de edad.' : 'Es menor de edad.'\nconsole.log(resultado);\n\n/*\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n*/\n\n//! Condicionales\nif ((edad > 10) && (edad < 15)) {\n  console.log('Eres un ninio')\n} else if ((edad > 15) && edad < 18) {\n  console.log('Eres un adolescente')\n} else {\n  console.log('Eres un universitario')\n}\n\n//! Bucle for\nfor (let i = 0; i < 10; i++) {\n  let siguiente = i + 1\n  console.log(`${i} * ${siguiente} = ${siguiente * i}`)\n}\n\n//! Bucle for of\nlet mangas = ['Dragon Ball', 'One Piece', 'Hunter X Hunter', 'BTOOM']\nfor (manga of mangas) {\n  console.log(manga)\n}\n//! Bucle for in\nconst datos_manga = {\n  autor: 'Eichiro Oda',\n  nombre: 'One Piece',\n  tomos: 108,\n  editorial: 'Panini Mexico'\n}\n\nfor (dato in datos_manga) {\n  console.log(dato)\n}\n\nfor (dato in datos_manga) {\n  console.log(`${dato}: ${datos_manga[dato]}`)\n}\n\n//! Bucle while\nlet contador = 0\nwhile (contador < 10) {\n  console.log(`contador desde while: ${contador}`)\n  contador++\n}\n\n//! Bucle do while\nlet contador2 = 0\ndo {\n  console.log(`contador desde do while: ${contador2}`)\n  contador2++\n} while (contador2 < 10)\n\n//! Switch\nvar nombre1 = 'Julio'\nswitch (nombre1.length) {\n  case 4:\n    console.log('Tu nombre tiene 4 letras')\n    break\n  case 5:\n    console.log('Tu nombre tiene 5 letras')\n    break\n  case 6:\n    console.log('Tu nombre tiene 6 letras')\n    break\n}\n\n/* \n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n*/\nfor (i = 10; i <= 55; i++) {\n  if (i % 2 === 0 && i !== 16 && i % 3 === 0) {\n    console.log(i)\n  }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/JoseAndresGC.js",
    "content": "// Aritméticos:\n\nlet sumaA = 1;\nlet sumaB = 1;\n\nconsole.log(sumaA + sumaB); // sumaA + sumaB = 2\n\nlet restaA = 4;\nlet restaB = 2;\n\nconsole.log(restaA - restaB); // 4 - 2 = 2\n\nlet multiplicacionA = 5;\nlet multiplicacionB = 2;\n\nconsole.log(multiplicacionA * multiplicacionB); // 5 * 2 = 10\n\nlet divisionA = 4;\nlet divisionB = 2;\n\nconsole.log(divisionA / divisionB); // 4 / 2 = 2\n\nlet incremento = 0\nincremento++\nconsole.log(incremento); // 1\n\nlet decremento = 1\ndecremento--\nconsole.log(decremento); // 0\n\n// Lógicos:\n\nlet expr1 = true;\nlet expr2 = false;\n\nconsole.log(expr1 && expr2); // AND: Si una de las dos expresiones es false se devuelve siempre false. Ambas expresiones deben ser true para devolver true\n\nlet expr_A = false;\nlet expr_B = false;\n\nconsole.log(expr_A || expr_B); // OR: Devuelve true si al menos una de las expresiones es true, de lo contrario devuelve false\n\nlet expr_C = true;\n\n// NOT: vuelve true al valor booleano que sea false, y vuelve false al valor que sea true. Los invierte básicamente\nconsole.log(!expr_C); // devuelve false\n\n// Comparación:\n\nlet comparacion1 = 100;\nlet comparacion2 = 10;\n\n// mayor que\nconsole.log(comparacion1 > comparacion2); // true\n// mayor o igual que\nconsole.log(comparacion1 >= comparacion2); // true\n// menor que\nconsole.log(comparacion1 < comparacion2); // false\n// menor o igual que\nconsole.log(comparacion1 <= comparacion2); // false\n// igual\nconsole.log(comparacion1 == comparacion2); // false\n// exactamente igual\nconsole.log(comparacion1 === comparacion2); // false\n// No es igual\nconsole.log(comparacion1 != comparacion2); // true\n// Estrictamente desigual\nconsole.log(comparacion1 !== comparacion2); // true\n\n// ternario\n\nlet edad = 25\nlet acceso = edad > 17 ? 'Permitir ingreso' : 'No puede ingresar';\n\nconsole.log(acceso); // 'Permitir Ingreso'\n\n// Estructuras repetitivas:\n\n// for:\n\nlet array = [\"juan\", \"juanito juan\", \"juanito el golondrina\", \"amigo de los gallos\", \"y de las gallinas\"];\nlet array2 = [];\n\nfor (let index = 0; index < array.length; index++) {\n    console.log(array[index]);\n}\n\nfor (let index = 0; index < 10; index++) {\n    array2[index] = index;\n    console.log(array2[index]);\n}\n\n// for in:\n\nconst objeto = {a: 1, b: 2, c: 3};\n\n\nfor (let propiedad in objeto) {\n    console.log(`${propiedad} : ${objeto[propiedad]}`);\n}\n\n// for of:\n\nfor (let cancionLetra of array) {\n    console.log(cancionLetra);\n}\n\n// while:\n\nlet cont = 0;\n\nwhile (cont <= 5) {\n    console.log(cont);\n    cont++;\n}\n\n// do-while\n\nlet cont2 = 0;\n\ndo {\n    console.log(cont2);\n    cont2++;\n} while (cont2 < 5);\n\n// Condicionales:\n\n// if:\n\nconst condicion = 10;\n\nif (condicion > 1) {\n    console.log(true);\n}\n\n// if else:\n\nlet condicion2 = 10\n\nif (condicion2 > 100) {\n    console.log(true);\n} else {\n    console.log(false);    \n}\n\n// switch:\n\nlet dia\nlet diaNum = 6\nswitch (diaNum) {\n    case 1:\n        dia = 'Lunes!';\n        break;\n    case 2:\n        dia = 'Martes!';\n        break;\n    case 3:\n        dia = 'Miércoles!';\n        break;\n    case 4:\n        dia = 'Jueves!';\n        break;\n    case 5:\n        dia = 'Viernes!';\n        break;\n    case 6:\n        dia = 'Sábado!';\n        break;\n    case 7:\n        dia = 'Domingo!';\n        break;\n    default:\n        dia = \"Valor indefinido\"\n        break;\n    }\n    console.log(dia);\n   \n// DIFICULTAD EXTRA:\n\nfor (let numero = 10; numero <= 55 ; numero++) {\n    if ((numero % 2 === 0 || numero === 55) && numero !== 16 && numero % 3 !== 0) {\n        console.log(numero);\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/JoseFuentes-Dev.js",
    "content": "let x   = 3;\nlet y = 2;\nconsole.log(\"los numeros son x = 3 y y = 2\");\n\n//****OPERADORES ARITMETICOS****\n//SUMA\nconsole.log(\"SUMA = \"  +(x+y));\n//RESTA\nconsole.log(\"RESTA = \"  +(x-y));\n//MULTIPLICACION\nconsole.log(\"MULTIPLICACION = \"  +(x*y));\n//DIVISION\nconsole.log(\"DIVISION = \"  +(x/y));\n//MODULAR\nconsole.log(\"MODULAR = \"  +(x%y));\n//EXPONENCIAL\nconsole.log(\"EXPONENCIAL = \"  +(x**y));\n//INCREMENTO  x++\nconsole.log(\"INCREMENTO = \" +(x++));//devuelve x=3 luego incrementa\n//DECREMENTO  x--\nconsole.log(\"DECREMENTO = \" +(x--)); //devuelve x=4 luego decrementa\n//INCREMENTO ++x\nconsole.log(\"INCREMENTO = \" +(++x));//incrementa luego devuelve el valor de x\n//DECREMENTO   --x\nconsole.log(\"DECREMENTO = \" +(--x)); //decrementa luego devuelve el valor de x\n\n//****OPERADORES DE ASIGNACION****\n//ASIGNACION SIMPLE\nconsole.log(\"ASIGNACION SIMPLE = \" + (x=x));\n//ASIGNACION CON SUMA\nconsole.log(\"ASIGNACION CON SUMA = \" + (x+=x));\n//ASIGNACION CON RESTA\nconsole.log(\"ASIGNACION CON RESTA = \" + (y-=x));\n//ASIGNACION CON MULTIPLICACION\nconsole.log(\"ASIGNACION CON MULTIPLICACION = \" + (x*=x));\n//ASIGNACION CON DIVISION\nconsole.log(\"ASIGNACION CON DIVISION = \" + (x/=x));\n//ASIGNACION CON MODULO\nconsole.log(\"ASIGNACION CON MODULO = \" + (x%=x));\n//ASIGNACION CON EXPONENCIAL\nconsole.log(\"ASIGNACION CON EXPONENCIAL = \" + (x**=x));\n\n//****OPERADORES DE COMPARACION****\n//IGUALDAD\nconsole.log(\"IGUALDAD = \" + (x==y));//compara valores\n//IGUALDAD ESTRICTA\nconsole.log(\"IGUALDAD ESTRICTA= \" + (x===y));//compara valores y tipos estrictamente iguales\n//DESIGUALDAD\nconsole.log(\"IGUALDAD ESTRICTA= \" + (x!=y));//compara valores \n//DESIGUALDAD ESTRICTA\nconsole.log(\"DESIGUALDAD ESTRICTA= \" + (x!==y));//compara valores y tipos estrictamente desiguales\n//MAYOR QUE \nconsole.log(x+\" ES MAYOR QUE \"+y+ \"=\"+ (x>y));//devuelve valores true o false depende si x es mayor que y\n//MAYOR QUE \nconsole.log(x+\" ES MAYOR IGUAL QUE  \"+y+ \"=\"+ (x>=y));\n//MENOR QUE \nconsole.log(x+\" ES MENOR QUE \"+y+ \"=\"+ (x<y));//devuelve valores true o false depende si x es menor que y\n//MENOR QUE \nconsole.log(x+\" ES MENOR IGUAL QUE \"+y+ \"=\"+ (x<=y));\n\n//****OPERADORES DE LOGICOS****\n//AND LOGICO(Y)\nconsole.log(\"OPERADOR x&&y = \"+(x&&y));\n\n//NOT LOGICO(NO)\nconsole.log(\"OPERADOR x!y  SIGNIFICA NOT\");\n\n//****OPERADORES BIT A BIT****\n//AND \nconsole.log(\"OPERADOR x&y = \"+(x&y));\n//OR \nconsole.log(\"OPERADOR x|y = \"+(x|y));\n//XOR OR EXCLUSIVO\nconsole.log(\"OPERADOR x^y = \"+(x^y));\n//NOT A BIT\nconsole.log(\"OPERADOR x~y \");\n//DESPLAZAMIENTO A LA IZQUIERDA\nconsole.log(\"DESPLAZAMIENTO A LA IZQUIERDA = \" + (x<<1));\n//DESPLAZAMIENTO A LA DERECHA\nconsole.log(\"DESPLAZAMIENTO A LA DERECHA = \" + (x>>2));\n//DESPLAZAMIENTO A LA DERECHA SIN SIGNO\nconsole.log(\"DESPLAZAMIENTO A LA DERECHA SIN SIGNO = \" + (x>>>3));\n\n//****OPERADORES TERNARIOS****\nlet w = true;\nlet z =false;\nconsole.log(x<=y  ?  z : w);// devuelve el valor de z si la condicion es correcta, de lo contrario devuelve w\n\n//****OPERADORES DE TIPOS****\n//TIPO DE UNA VARIABLE\nconsole.log(\"TIPEOF TIPO DE UNA VARIABLE  = \" + (typeof(x)));\n//INSTANCIA DE UNA CLASE\nlet color=\"blue\"\nconsole.log(\"INSTANCEOF TIPO DE UNA VARIABLE  = \" + (color  instanceof  String));\nlet color2 = new String(\"red\");\nconsole.log(\"INSTANCEOF TIPO DE UNA VARIABLE  = \" + (color2  instanceof  String));\n//IN  : Verifica si una propiedad existe en un objeto\nconsole.log(0 in color2);\nlet array ={persona:\"hola\", saludando:\"como estas\"};\nconsole.log(\"persona\" in array);\n\n//****OPERADORES DE DESTRUCTURACION****\n//EJEMPLO DE DESTRUCTURACION CON ARRAY\nconst frutas  = ['banana', 'melon', 'mango'];\n\nconst fruta=[fruta1, fruta2, fruta3] = frutas;\n\nconsole.log(fruta1, fruta2, fruta3);\n\n//EJEMPLO DE DESTRUCTURACION CON OBJETO\nconst objeto={\n    nombre: \"Juan\",\n    apellido: \"Perez\",\n    edad: 30\n}\n\nconst {nombre, apellido, edad} = objeto;\n\nconsole.log(nombre, apellido, edad);\n\n//EJEMPLO DE DESTRUCTURACION CON VALORES PREDETERMINADOS\n\nconst colores=[ 'rojo'];\n\nconst [color1, color5='azul'] = colores;\n\nconsole.log(color1);\nconsole.log(color5);\n\n//EJEMPLO DE DESTRUCTURACION EN OBJETOS ANIDADOS\n\nconst persona = {\n    nombre: \"Juan\",\n    apellido: \"Perez\",\n    edad: 30,\n    direccion: {\n        ciudad: \"Madrid\",\n        pais: \"España\"\n    }\n}\n\nconst { direccion: {ciudad, pais} } = persona;\n\nconsole.log(ciudad, pais);\n\n//EJEMPLO DE DESTRUCTURACION CON ELEMENTO SPREAD\n\nconst [primero, ...resto] = [1,2,3,4,5];\n\nconsole.log(primero);\nconsole.log(resto);\n\n\n//***ESTRUCTURAS DE CONTROL\n//CONDICIONALES (if, else if, else)\n/*if(condicion){\n  si la primera condicion es verdadera\n}else if(otra condicion){\n si la otra condicion es verdadera \n}else{\n si ninguna de las dos condiciones anteriores son verdaderas\n}*/\nlet condicion = 10;\nif(condicion > 5){\n  console.log(\"La condicion es verdadera\");\n}else if(condicion<5){\n    console.log(\"La segunda condicion es verdadera\");\n}\nelse{\n  console.log(\"La condicion es falsa\");\n}\n\n//CONDICIONAL TERNARIO\n//condicion ? exp1 : exp2\n\nconst esMayorDeEdad = edad >= 18 ? \"Sí\" : \"No\";\nconsole.log(esMayorDeEdad); // Sí\n\n//SWITCH\n\nlet dia = 2;\nswitch(dia){\n  case 1:\n    console.log(\"Lunes\");\n    break;\n  case 2:\n    console.log(\"Martes\");\n    break;\n  case 3:\n    console.log(\"Miércoles\");\n    break;\n  case 4:\n    console.log(\"Jueves\");\n    break;\n  case 5:\n    console.log(\"Viernes\");\n    break;\n  case 6:\n    console.log(\"Sábado\");\n    break;\n  case 7:\n    console.log(\"Domingo\");\n    break;\n  default:\n    console.log(\"Día inválido\");\n}\n\n//BUCLES FOR, WHILE, DO WHILE\n//FOR\n\nfor(let i=0; i<5; i++){\n  console.log(i);\n}\n\n//WHILE \n\nlet j = 0;\nwhile(j<5){\n  console.log(j);\n  j++;\n}\n\n//DO WHILE\n\nlet k = 0;\ndo{\n  console.log(k);\n  k++;\n}while(k<5);\n\n//BUCLES CON INTERRUPCIONES BREAK, CONTINUE\n//BREAK\n\nfor(let i=0; i<5; i++){\n  if(i===2){\n    break;\n  }\n  console.log(i);\n}\n\n//CONTINUE\n\nfor(let i=0; i<5; i++){\n  if(i===2){\n    continue;\n  }\n  console.log(i);\n}\n\n//BUCLES CON ITERADORES FOR IN, FOR OFF\n//FOR IN\nlet persona1 = {\n  nombre: \"Juan\",\n  apellido: \"Perez\",\n  edad: 30\n}\n\nfor(let propiedad in persona1){\n  console.log(propiedad, persona1[propiedad]);\n}\n\n//FOR OFF\n\nlet numeros = [1, 2, 3, 4, 5];\n\nfor (const numero of numeros) {\n    console.log(numero);\n}\n\n//***TRY CATCH FINALLY\n\ntry {\n  //codigo que puede generar excepciones\n  let numero = 10 / 0;\n} catch (error) {\n  //codigo que se ejecuta cuando se produce una excepcion\n  console.error(\"Hubo un error: \", error);\n} finally {\n  //codigo que se ejecuta siempre, independientemente de si hubo excepcion o no\n  console.log(\"Este codigo siempre se ejecuta\");\n}\n\n//***FOR EACH\n\nlet numeros2 = [1, 2, 3, 4, 5];\n\nnumeros2.forEach(function(numero){\n  console.log(numero);\n});\n\n//***MAP\n\nlet numeros3 = [1, 2, 3, 4, 5];\n\nlet numerosMultiplicados = numeros3.map(num=>num*2);\n\nconsole.log(numerosMultiplicados);\n\n//***FILTER\n\nlet caramelos=['rojos','azul','rojos', 'verde','rojos','verde'];\n\nlet caramelosRojos = caramelos.filter(caramelo=>caramelo==='rojos');\n\nconsole.log(caramelosRojos);\n\n//***FIND\n\nlet caramelosVerdes = caramelos.find(caramelo=>caramelo==='verde');\n\nconsole.log(caramelosVerdes);\n\n\n//***REDUCE\n\nlet numeros4 = [1, 2, 3, 4, 5];\n\nlet suma = numeros4.reduce((total, numero) => total + numero, 0);\n\nconsole.log(suma);\n\n//***SORT\n\nlet numeros5 = [5, 2, 8, 1, 3];\n\nnumeros5.sort((a, b) => a - b);\n\nconsole.log(numeros5);\n\n\n//***DIFICULTAD EXTRA****\n\nfor (let i = 10; i <= 55; i++) {\n    if ((i % 2 == 0 || i===55)&& i !== 16 && i % 3 !== 0) {\n      console.log(i);\n    }\n  }\n  "
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/JosueVH07.js",
    "content": "// Tipos de Operadores \n\n// Aritmeticos\n\nlet a = 5\nlet b = 2\n\nlet suma = a + b\nlet resta = a - b\nlet multiplicacion = a * b\nlet division = a / b\nlet modulo = a % b\nlet incremento = a++\nlet decremento = a--\n\nconsole.log(suma)\nconsole.log(resta)\nconsole.log(multiplicacion)\nconsole.log(division)\nconsole.log(modulo)\nconsole.log(incremento)\nconsole.log(decremento)\n\n// Asignacion\nlet name = 'Josue'\nlet age = 20\nlet city = 'CDMX'\n\nname += 'VH07'\nage -= 5\ncity *= 2\n\nconsole.log(name)\nconsole.log(age)\nconsole.log(city)\n\n// Comparacion\n\nlet num1 = 5\nlet num2 = 5\n\nlet resultado = num1 == num2\nlet resultado2 = num1 === num2\nlet resultado3 = num1 != num2\nlet resultado4 = num1 !== num2\nlet resultado5 = num1 < num2\nlet resultado6 = num1 > num2\nlet resultado7 = num1 <= num2\nlet resultado8 = num1 >= num2\n\nconsole.log(resultado)\nconsole.log(resultado2)\nconsole.log(resultado3)\nconsole.log(resultado4)\nconsole.log(resultado5)\nconsole.log(resultado6)\n\n// Logicos\n\nlet valor1 = true\nlet valor2 = false\n\nlet resultado9 = valor1 && valor2\nlet resultado10 = valor1 || valor2\nlet resultado11 = !valor1\n\nconsole.log(resultado9)\nconsole.log(resultado10)\nconsole.log(resultado11)\n\n// Bitwise\n\nlet num3 = 5\nlet num4 = 2\n\nlet resultado12 = num3 & num4\nlet resultado13 = num3 | num4\nlet resultado14 = num3 ^ num4\nlet resultado15 = ~num3\nlet resultado16 = num3 << num4\nlet resultado17 = num3 >> num4\nlet resultado18 = num3 >>> num4\n\nconsole.log(`AND: 5 & 2 = ${resultado12}`)\nconsole.log(`OR: 5 | 2 = ${resultado13}`)\nconsole.log(`XOR: 5 ^ 2 = ${resultado14}`)\nconsole.log(`NOT: ~5 = ${resultado15}`)\nconsole.log(`Desplazamiento a la izquierda: 5 << 2 = ${resultado16}`)\nconsole.log(`Desplazamiento a la derecha: 5 >> 2 = ${resultado17}`)\nconsole.log(`Desplazamiento sin signo: 5 >>> 2 = ${resultado18}`)\n\n\n// Operador ternario\n\nlet valor3 = true\nlet valor4 = false\n\nlet resultado19 = valor3 ? 'Verdadero' : 'Falso'\nlet resultado20 = valor4 ? 'Verdadero' : 'Falso'\n\nconsole.log(resultado19)\nconsole.log(resultado20)\n\n// Concatenacion\n\nlet string1 = 'Hola'\nlet string2 = 'Mundo'\n\nlet resultado21 = string1 + ' ' + string2\n\nconsole.log(resultado21)\n\n// Typeof\n\nlet variable = 'JosueVH07'\nlet variable2 = 7\nlet variable3 = 7.7\nlet variable4 = true\nlet variable5 = null\nlet variable6 = undefined\n\nconsole.log(typeof variable)\nconsole.log(typeof variable2)\nconsole.log(typeof variable3)\nconsole.log(typeof variable4)\nconsole.log(typeof variable5)\n\n\n// Operadores de instancia\n\nconst person = {\n    name: 'Josue',\n    age: 20,\n    city: 'CDMX',\n    country: 'Mexico'\n}\n\nlet resultado22 = 'name' in person\nconsole.log(resultado22)\n\n\n\n// Dificukltad extra \n\nfor (let i = 10; i <= 55; i++) {\n    if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n        console.log(i)\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/Josueeeee.js",
    "content": "/* \n ---------------------\n    OPERADORES\n --------------------\n */\n\n// Operadores Aritméticos\nconsole.log(`Suma: 10 + 20 = ${10 + 20}`);\nconsole.log(`Resta: 10 - 20 = ${10 - 20}`);\nconsole.log(`multiplicación: 10 * 20 = ${10 * 20}`);\nconsole.log(`división: 10 / 20 = ${10 / 20}`);\nconsole.log(`Modulo 10 % 20 = ${10 % 20}`);\nconsole.log(`Exponente 10 ** 2 = ${10 ** 2} `);\n\n// Operadores de comparación\nconsole.log(`Igual: 10 == \"10\" es ${10 == \"10\"}`);\nconsole.log(`Disigual: 10 != \"10\" es ${10 != \"10\"}`);\nconsole.log(`Mayor que: 19 > 10 es ${19 > 10}`);\nconsole.log(`Menor que: 19 < 10 es ${19 < 10}`);\nconsole.log(`Mayor o igual que: 19 >= 10 es ${19 >= 10}`);\nconsole.log(`Menor o igual que: 19 <= 10 es ${19 <= 19}`);\n\n// Operadores lógico\nconsole.log(\n  `AND &&: 10 + 10 == 20 && 30 + 3 == 33 es ${10 + 10 == 20 && 30 + 3 == 33}`\n);\n\nconsole.log(\n  `OR ||: 10 + 10 == 20 || 30 + 3 == 33 es ${10 + 10 == 20 || 30 + 40 == 33}`\n);\n\n// Operadores de asignación\nvar number = 10; //asignación\nconsole.log(number);\nnumber += 1; //suma y asignación\nconsole.log(number);\nnumber -= 3; //resta y asignación\nconsole.log(number);\nnumber *= 3; //multipliación y asignación\nconsole.log(number);\nnumber /= 2; // división y asignación\nconsole.log(number);\nnumber **= 2; //exponente y asignación\nconsole.log(number);\nnumber %= 3; // modulo y asiganicón\nconsole.log(number);\n\n// operadores de identidad\nconsole.log(`Igualdad estricta: 10 === 10  es${10 === \"10\"}`);\nconsole.log(`Disigual estricta: 10 !== \"10\" es ${10 !== \"10\"}`);\n\n// Operadore de pertenencia\nconst person = {\n  name: \"Jeffrey\",\n  age: 23,\n  gender: \"male\",\n};\nconsole.log(`Name esta en el objeto Person? ${\"name\" in person}`);\n\n// operadores en bit\nlet bitnum1 = 10;\nlet bitnum2 = 3;\nconsole.log(`AND: 10 & 3 = ${bitnum1 & bitnum2}`);\nconsole.log(`OR: 10 | 3 = ${bitnum1 | bitnum2}`);\nconsole.log(`xOR: 10 ^ 3 = ${bitnum1 ^ bitnum2}`);\nconsole.log(`NOT: ~10 = ${~bitnum1}`);\nconsole.log(`DESPLAZAMMIENTO  A LA DERECHA: 10 >> 3 = ${bitnum1 >> bitnum2}`);\nconsole.log(`DESPLAZAMMIENTO  A LA IZQUIERDA: 10 << 3 = ${bitnum1 << bitnum2}`);\n\n// MÁS OPERADORES DE JAVASCRIPT\n\n// Operadores ternarios\nconst val1 = true;\nconst val2 = false;\nconsole.log(`Imprime el valor verdadero:  ${true ? val1 : val2}`);\n\n//OPERADORES DE STRING\nconsole.log(\"Mi \" + \"edad es: \" + 23);\n\n/*\n --------------------------\n   ESTRUCUTRAS DE CONTROL\n --------------------------\n*/\n\n// estructura de control condicional\n\nconst namePerson = \"ha\";\n\nif (namePerson == \"Jeffrey\") {\n  console.log(\"El nombre es Jeffrey\");\n} else if (namePerson == \"Josue\") {\n  console.log(\"El nombre es Josue\");\n} else {\n  console.log(\"El mombre no es Jeffrey ni Josue \");\n}\n\nconst interruptor = 3;\nswitch (interruptor) {\n  case 0:\n    console.log(\"El bombillo esta en off\");\n    break;\n  case 1:\n    console.log(\"El bombillio esta on\");\n    break;\n  default:\n    console.log(\"Ya no funciona\");\n    break;\n}\n\n// iterativas\n\nfor (let i = 0; i <= 10; i++) {\n  console.log(i);\n}\n\nconsole.log(`Estructura con while`);\nlet i = 0;\nwhile (i <= 10) {\n  console.log(i);\n  i++;\n}\n\n/*\n --------------------------\n    DIFICULTAD EXTRA \n --------------------------\n*/\n\nfor (let i = 10; i <= 55; i++) {\n  if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n    console.log(i);\n  }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/JuPerDev.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n// Assignment\n\nlet cohete = '🚀';\n\n// Arithmetics Operators\nlet add = 1 + 2; // 3\nlet substract = 5-3; // 2\nlet multiply = 2*2; // 4\nlet division = 4/2; // 2\nlet modulus = 8%2; // 0\n\nlet increment = 0;\n++increment; // 1\n\nlet decrement = 5;\n--decrement; //4\n\n// Comparison Operators\nlet greaterThan = 5 > 1; // True\nlet lessThan = 1 < 5; // True\nlet greaterThanOrEqualTo = 3 >= 3; // True\nlet lessThanOrEqualTo = 1 <= 2; // True\nlet notEqual = 1 != '2'; // true\nlet notEqualValueOrType = 2 !== '2'; // true \nlet equalValue = 2 === '2'; // true\nlet equalValueAndEqualType = 2 === '2'; //false\nlet ternaryOperator = (1 > 0) ? 'True':'false'; // true\n\n// Logical Operators\n// And &&\nlet andOne = true && true // true\nlet andTwo = true && false // false\n// Or ||\nlet orOne = true || true // true\nlet orTwo = true || false //true\nlet orThree = false || false //false\n// Denial\nconsole.log(!true); // false\n\n// Type Operators\ntypeof 'Juan'; // String\ntypeof 4; // Number\ntypeof NaN; // Number\ntypeof true; // Boolean\ntypeof [1,1,2,3]; // Object\ntypeof {name:'juan', lastName: 'Perez'}; // Object\ntypeof new Date(); // Object\ntypeof function hola(){}; // Function \ntypeof varTest; // Undefined\ntypeof null; // Object\n\n// Conditional Assignment\n\n// IF, ELSE, IF ELSE\nif(true){\n    console.log('true');\n} else if(false){\n    console.log('false')\n} else {\n    console.log('Else')\n}\n\n// Switch\nlet variable = 2;\nswitch (variable){\n    case 1:\n        console.log('Monday')\n        break\n    case 2:\n        console.log('Tuesday')\n        break\n    case 3:\n        console.log('Wednesday')\n        break\n    default:\n        console.log('Hola :D!')\n}\n\n// for\n\nfor(let i = 0; i < 5; i++){\n    console.log(i);\n}\n\n// for in\nconst object = { name: 'Juan', lastName: 'Pérez'};\nfor (let i in object){\n    console.log(object[i])\n}\n\n// for of\nconst array = ['Juan', 'Pedro', 'Javier'];\nfor(let i of array){\n    console.log(i);\n}\n\n// while\nlet x = 0;\nwhile( x <= 3 ){\n    console.log(`While -> ${x}`);\n    x++;\n}\n\n// do-while\nlet d = 0;\ndo{\n    console.log(`do-while --> ${d}`);\n    d++;\n}while(d <= 5);\n\n// EXTRA\n/*\n* Crea un programa que imprima por consola todos los números comprendidos\n* entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n*/\nfor(let i = 10; i <= 55; i++){\n    if(i%2 === 0 && i%3 !== 0 && i !== 16){\n        console.log(i)\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/JuSeRDev.js",
    "content": "//  ! EJERCICIO:\n//  * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje: Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...(Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n\n// asignacion\n\nlet a = 11\nlet b = 3\n\n\nconsole.log(a += b)\nconsole.log(a -= b)\nconsole.log(a *= b)\nconsole.log(a /= b)\nconsole.log(a %= b)\nconsole.log(a **= b)\nconsole.log(a <<= b)\nconsole.log(a >>= b)\nconsole.log(a >>>= b)\nconsole.log(a &= b)\nconsole.log(a |= b)\nconsole.log(a ||= b)\nconsole.log(a ??= b)\n\n//  * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos que representen todos los tipos de estructuras de control que existan en tu lenguaje: Condicionales, iterativas, excepciones...\n//  * - Debes hacer print por consola del resultado de todos los ejemplos.\n\nlet igual\n\nconsole.log(igual = a == b)\nconsole.log(igual = a === b)\nconsole.log(igual = a < b)\nconsole.log(igual = a > b)\nconsole.log(igual = a <= b)\nconsole.log(igual = a >= b)\nconsole.log(igual = a != b)\n\n\n//  * DIFICULTAD EXTRA (opcional):\n//  * Crea un programa que imprima por consola todos los números comprendidos entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\nfor (let i = 10; i <= 55; i++) {\n    if (i % 2 === 0 && i !== 16 && i % 3 !== 0 ) {\n        console.log(i);\n    }   \n}\n\n\n//  * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/JuanCaicedo1024.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * \n */\n\nlet a = 1;\nlet b = 2;\n\n//incrementar \na ++\nb++\n\n//operadores Aritméticos \nconsole.log (`suma:${a + b}`);\nconsole.log (`resta:${a - b}`);\nconsole.log (`Multiplicacion:${a * b}`);\nconsole.log (`divions:${a / b}`);\nconsole.log (`modulo:${a % b}`);\nconsole.log (`Exponente:${a ** b}`);\n\n// Operadores logicos \nconsole.log (`And ${a == b & b == a}`)\nconsole.log (`Or ${a == b || b == a}`)\nconsole.log (`Or ${ a!=b }`)\n\n//Operadores de comparacion \nconsole.log (`Igual ${a == b }`)\nconsole.log (`Mayor ${a > b }`)\nconsole.log (`Menor ${a < b }`)\nconsole.log (`Mayor y igual ${a >= b }`)\nconsole.log (`menor y igual ${a <= b }`)\nconsole.log (`desigual ${a != b }`)\n\n//Operadores de asignacion \nvar X = 20\n\nconsole.log(`Asigancion ${X = 10}`)\nconsole.log(`Asignación de adición\t ${X += 10}`)\nconsole.log(`Asignación de resta ${X -= 10}`)\nconsole.log(`Asignación de multiplicación\t ${X *= 10}`)\nconsole.log(`Asigancion de division ${X %= 10}`)\n\n\n// Operadores de Cadena \n\nlet nombre = \"Joaquin\"\nlet apellido = \"Lopez\"\nlet nombreCompleto = \"Joaquin\" + \" \" + \"Lopez\"\n\nconsole.log('Nombre Completo:', nombreCompleto);\n\n\n//Identidad var num = 0;\nvar obj = new String(\"0\");\nvar str = \"0\";\nvar Xwwww = false;\n\nconsole.log(num === num); // true\nconsole.log(obj === obj); // true\nconsole.log(str === str); // true\n\nconsole.log(num === obj); // false\nconsole.log(num === str); // false\nconsole.log(obj === str); // false\nconsole.log(null === undefined); // false\nconsole.log(obj === null); // false\nconsole.log(obj === undefined); // false\n\n// estructura de control condicional\n\nconst namePerson = \"ha\";\n\nif (namePerson == \"Jeffrey\") {\n  console.log(\"El nombre es Jeffrey\");\n} else if (namePerson == \"Josue\") {\n  console.log(\"El nombre es Josue\");\n} else {\n  console.log(\"El mombre no es Jeffrey ni Josue \");\n}\n\nconst interruptor = 3;\nswitch (interruptor) {\n  case 0:\n    console.log(\"El bombillo esta en off\");\n    break;\n  case 1:\n    console.log(\"El bombillio esta on\");\n    break;\n  default:\n    console.log(\"Ya no funciona\");\n    break;\n}\n\n// iterativas\n\nfor (let i = 0; i <= 10; i++) {\n  console.log(i);\n}\n\nconsole.log(`Estructura con while`);\nlet i = 0;\nwhile (i <= 10) {\n  console.log(i);\n  i++;\n}\n\n\n// */DIFICULTAD EXTRA (opcional):\n//  * Crea un programa que imprima por consola todos los números comprendidos\n//  * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n//  *\n//  * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo./*\n\nfor (let i= 10 ; i <= 55 ; i += 2) {\n    if (i === 16 || i %3 === 0 ){\n        continues\n    }\n    console.log(i);\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/Juancamilo3821.js",
    "content": "//Operadores Js//\n/*Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)*/\n\n//Operadores Aritmeticos//\n//operador de asignacion//\nlet n = 4\nlet z = 88\n\nlet k = 10;\nk += 5;\nk -= 2; \nk *= 3;\nk /= 3;\nk %= 5;\nconsole.log(\"k:\", k);\n\nconsole.log( `Suma:     ${n} + ${z} = ${ n + z }` );\nconsole.log( `Resta:     ${n} - ${z} = ${ n - z }` );\nconsole.log( `Multiplicacion:     ${n} * ${z} = ${ n * z }` );\nconsole.log( `Division:     ${n} / ${z} = ${ n / z }` );\nconsole.log( `Residuo:     ${n} % ${z} = ${ n % z }` );\nconsole.log( `Exponenciacion:     ${n} ** ${z} = ${ n ** z }` );\n\n//Suma de cadenas//\nlet firstName = \"Juan Camilo \";\nlet lastName = \"Gomez Armenta\";\n\nlet fullName = firstName + lastName;\n\nconsole.log(fullName)\n\n//Suma de Cadenas y numeros//\nlet nom = \"Juan\";\nlet number = 5;\nlet concat = \"6\" + 7;\nlet x = \"hola\" + 33;\n\n\nconsole.log(number)\nconsole.log(nom)\nconsole.log(concat)\nconsole.log(nom, concat)\nconsole.log(x)\n\n//Operadores Logicos//\n\nlet a = 6;\nlet b = 3;\nlet c = (a < 10 && b > 0 );\nlet d = (a < 10 || b < 0);\nlet e = (5 == 8);\nlet f = !(5 == 8);\n\n\nlet hablar = null;\nlet talk = \"missing\";\nlet result = hablar ?? talk;\n\n\nconsole.log(c)\nconsole.log(d)\nconsole.log(e)\nconsole.log(f)\nconsole.log(result)\n\n//Operadores de Comparacion//\nlet yz = (10 == 3)\nconsole.log(\"10 == 3 es\", yz)\n\nlet yx = (10 != 3)\nconsole.log(\"10 != 3 es\", yx)\n\nlet yy = (10 > 3 )\nconsole.log(\"10 > 3 es\", yy)\n\nlet ya = (10 < 3 )\nconsole.log(\"10 < 3 es\", ya)\n\nlet yb = (10 >= 3 )\nconsole.log(\"10 >= 3 es\", yb)\n\nlet yc = (10 <= 3 )\nconsole.log(\"10 <= 3 es\", yc)\n\n//Operadores de Identidad//\n// Identidad (===)\nlet n1 = 44;\nlet n2 = 44;\nconsole.log(\"n1 === n2:\", n1 === n2); // true (primitivos por valor)\n\nlet obj1 = { valor: 44 };\nlet obj2 = { valor: 44 };\nconsole.log(\"obj1 === obj2:\", obj1 === obj2); // false (objetos por referencia)\n\nlet obj3 = obj1;\nconsole.log(\"obj3 === obj1:\", obj3 === obj1); // true\n\n\n\n// Operadores de pertenencia\nconst obj = { valor: 44 };\nconsole.log(\"'valor' in obj:\", 'valor' in obj); // true\n\nconst arr = [1, 2, 3];\nconsole.log(\"arr includes 2:\", arr.includes(2)); // true (no es operador, pero es pertenencia práctica)\n\nconsole.log(\"arr instanceof Array:\", arr instanceof Array); // true\n\n\n//Operadores bit a bit\n//AND a nivel de bits\nlet j = (11 & 12);\nconsole.log(\"esto es j: \", j)\n\n//OR a nivel de bits\nlet l = (11 | 12);\nconsole.log(\"esto es l: \", l)\n\n//XOR a nivel de bits\nlet m = (11 ^ 12);\nconsole.log(\"esto es m: \", m)\n\n//NOT a nivel de bits\nlet o = ~11;\nconsole.log(\"esto es o: \", o)\n\n//Desplazamiento a la izquierda\nlet p = (11 << 12);\nconsole.log(\"esto es p: \", p)\n\n//Desplazamiento a la derecha de propagación de signo\nlet q = (11 >> 12);\nconsole.log(\"esto es q: \", q)\n\n//Desplazamiento a la derecha de relleno cero\nlet r = (11 >>> 12);\nconsole.log(\"esto es r: \", r)\n\n\n/*Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...*/\n\n//Estructuras de control\n//Condicionales \n//if/else\n\nlet nota = 70;\n    if (nota < 80) {\n        console.log(\"No aprobo\");\n    } else {\n        console.log(\"Aprobo\")\n    }\n\nlet edad = 17;\n\n    if(edad < 18 ) console.log(\"Menor\");\n    else if (edad < 65) console.log(\"Adulto\");\n    else console.log(\"Abuelo\");\n\nlet dia = 4;\n\nswitch (dia) {\n    case 1: console.log(\"Lunes\"); break;\n    case 2: console.log(\"Martes\"); break;\n    case 3: console.log(\"Miercoles\"); break;\n    default: console.log(\"Otro\");\n}\n\n//Iterativas(Bucles)\n\nfor (let i = 1; i <= 10; i++){\n    console.log(\"for i=\", i)\n}\n\nlet i = 1;\nwhile (i<=10){\n    console.log(\"while i =\", i);\n    i++;\n}\n\nlet s = 1;\ndo {\n  console.log(\"do-while s =\", s);\n  s++;\n} while (s <= 3);\n\n//Excepciones/Try/Catch/Finally\n\ntry {\n  let x = JSON.parse(\"esto no es json\");\n  console.log(x);\n} catch (error) {\n  console.log(\"Error atrapado:\", error.message);\n} finally {\n  console.log(\"Esto siempre se ejecuta\");\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/Kronstadt-Lambda.js",
    "content": "/**\n * @author: Kronstadt-Lambda\n * @version: 1.0\n */\n\n// Initialize variables\nlet float_a = 2.0;\nlet float_b = 2.0;\nlet bit_a = 0b00000101;\nlet bit_b = 0b00000110;\nconst day = \"Wendesday\";\nlet edad = 1;\nlet isBool;\nconst person = { name: \"Jhon\", age: 30 };\nconst numbers = [1, 2, 3];\n\n/**\n * Operators in JavaScript\n */\n// Arithmetic operators\nconsole.log(\"Addition:\", float_a + float_b);\nconsole.log(\"Subtraction:\", float_a - float_b);\nconsole.log(\"Multiplication:\", float_a * float_b);\nconsole.log(\"Division:\", float_a / float_b);\nconsole.log(\"Exponentiation:\", float_a ** float_b);\nconsole.log(\"Modulus:\", float_a % float_b);\nconsole.log(\"Pre-Increment:\", ++float_a);\nconsole.log(\"Pre-Decrement:\", --float_a);\nconsole.log(\"Post-increment:\", float_a++);\nconsole.log(\"Post-decrement:\", float_a--);\n\n// Assignment operators\nconsole.log(\"Simple Assignment:\", float_a = float_b);\nconsole.log(\"Addition Assignment:\", float_a += float_b);\nconsole.log(\"Subtraction Assignment:\", float_a -= float_b);\nconsole.log(\"Multiplication Assignment:\", float_a *= float_b);\nconsole.log(\"Division Assignment:\", float_a /= float_b);\nconsole.log(\"Exponentiation Assignment:\", float_a **= float_b);\nconsole.log(\"Modulus Assignment:\", float_a %= float_b);\nconsole.log(\"Bitwise AND Assignment:\", bit_a &= bit_b);\nconsole.log(\"Bitwise OR Assignment:\", bit_a |= bit_b);\nconsole.log(\"Bitwise XOR Assignment:\", bit_a ^= bit_b);\nconsole.log(\"Left Shift Assignment:\", bit_a <<= bit_b);\nconsole.log(\"Right Shift Assignment:\", bit_a >>= bit_b);\n\n// Comparison operators\nconsole.log(\"Equal to:\", float_a == float_b);\nconsole.log(\"Not equal to:\", float_a != float_b);\nconsole.log(\"Strict equal (value and type) to:\", float_a === float_b);\nconsole.log(\"Strict not equal (value and type) to:\", float_a !== float_b);\nconsole.log(\"Greater than:\", float_a > float_b);\nconsole.log(\"Less than:\", float_a < float_b);\nconsole.log(\"Greater than or equal to:\", float_a >= float_b);\nconsole.log(\"Less than or equal to:\", float_a <= float_b);\n\n// Logical operators\nconsole.log(\"Logical AND:\", true && false);\nconsole.log(\"Logical OR:\", true || false);\nconsole.log(\"Logical NOT:\", !true);\n\n// Bitwise operators\nconsole.log(\"Bitwise AND:\", bit_a & bit_b);\nconsole.log(\"Bitwise OR:\", bit_a | bit_b);\nconsole.log(\"Bitwise XOR:\", bit_a ^ bit_b);\nconsole.log(\"Bitwise NOT:\", ~bit_a);\nconsole.log(\"Left Shift:\", bit_a << 1);\nconsole.log(\"Right Shift:\", bit_a >> 1);\nconsole.log(\"Zero-fill Right Shift:\", bit_a >>> 1);\n\n// Identity operators\nconsole.log(\"Equal value and type:\", float_a === float_b);\nconsole.log(\"Not equal value or not equal type:\", float_a !== float_b);\n\n// Membership operators\nconsole.log(\"Is in:\", 'name' in person); // Verify if the property exists in the object\nconsole.log(\"Is not in:\", 'lastname' in person); // Verify if the property does not exist in the object\nconsole.log(\"Is in:\", numbers.includes(2)); // Verify if the value exists in the array\n\n/**\n * Control structures in JavaScript\n */\n// If, if-else, else statement\nif (float_a === float_b) {\n  console.log(\"The numbers are equal.\");\n} else if (float_a > float_b) {\n  console.log(\"float_a is greater than float_b.\");\n} else {\n  console.log(\"float_a is less than float_b.\");\n}\n// Switch statement\nswitch (day) {\n    case \"Monday\":\n        console.log(\"Today is Monday.\");\n        break; // Exit the switch statement to avoid executing the next cases\n    case \"Tuesday\":\n        console.log(\"Today is Tuesday.\");\n        break; // Exit the switch statement to avoid executing the next cases\n    case \"Wednesday\":\n        console.log(\"Today is Wednesday.\");\n        break; // Exit the switch statement to avoid executing the next cases\n    case \"Thursday\":\n        console.log(\"Today is Thursday.\");\n        break; // Exit the switch statement to avoid executing the next cases\n    case \"Friday\":\n        console.log(\"Today is Friday.\");\n        break; // Exit the switch statement to avoid executing the next cases\n    default: // If no case matches\n        console.log(\"It's the weekend.\");\n        break; // Exit the switch statement to avoid executing the next cases\n}\n// For loop\nfor (let i = 10; i >= 0; i--) {\n    console.log(\"The loop end in ...\", i);\n}\n// While loop\nwhile (edad < 18) {\n    console.log(\"I am \", edad, \" years old.\");\n    edad++;\n}\n// Do-while loop\ndo {\n    isBool = false;\n    console.log(\"At least one execution.\");\n} while (isBool);\n// For-in loop: Usefull for objects\nfor (let key in person) {\n    console.log(key, \":\", person[key]);\n}\n// For-of loop: Usefull for arrays\nfor (let number of numbers) {\n    console.log(\"Number:\", number);\n}\n// Break statement\nfor (let i = 0; i < 10; i++) {\n    if (i === 5) {\n        console.log(\"Break at:\", i);\n        break; // Exit the loop\n    }\n    console.log(\"i = :\", i);\n}\n// Continue statement\nfor (let i = 0; i < 10; i++) {\n    if (i === 5) {\n        console.log(\"Continue (skip) at:\", i);\n        continue; // Skip the current iteration\n    }\n    console.log(\"Cube of\", i, \"is\", i ** 3);\n}\n// Label statement: Exit an outer loop\nouterloop: for (let i = 0; i < 5; i++) {\n    console.log(\"Outerloop:\", i);\n    innerloop: for (let j = 0; j < 5; j++) {\n        if (j === 3) {\n            break outerloop; // Exit the outer loop\n        }\n        console.log(\"Innerloop:\", j);\n    }\n}\n// Return statement: Exit a function\nfunction add(a, b) {\n  return a + b;\n}\n// try-catch-finally statement: Handle exceptions\ntry {\n  console.log(numbers[3]);\n} catch (error) {\n  console.error(\"An error occurred:\", error);\n} finally {\n  console.log(\"Finally block.\");\n}\n\n/**\n * Extra exercises\n * Create a program that prints to the console all numbers between 10 and 55 (inclusive), even, and that are neither 16 nor multiples of 3\n */\n\nfor (let i = 10; i <= 55; i++) {\n    if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n        console.log(\"The solution is: \", i);\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/LMedina96.js",
    "content": "/*\n# #01 OPERADORES Y ESTRUCTURAS DE CONTROL\n> #### Dificultad: Fácil | Publicación: 02/01/24 | Corrección: 08/01/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\nconst number1 = 20\nconst number2 = 4\nlet result\nlet booleanResult\nlet asignationResult\n\n//Operadores aritmeticos\nconsole.log('OPERADORES ARITMETICOS:')\nconst operadoresAritmeticos = [\n    {operador: 'Suma', simbolo: '+'},\n    {operador: 'Resta', simbolo: '-'},\n    {operador: 'Multiplicacion', simbolo: '*'},\n    {operador: 'Division', simbolo: '/'},\n    {operador: 'Resto', simbolo: '%'},\n    {operador: 'Exponencial', simbolo: '**'},\n]\n\nfor (const operador of operadoresAritmeticos) {\n    result = eval(`${number1} ${operador.simbolo} ${number2}`)\n    console.log(`Resultado del operador aritmetico ${operador.operador}: ${number1} ${operador.simbolo} ${number2} = ${result}`)\n}\nconsole.log('')\nconsole.log('OPERADORES DE COMPARACIÓN:')\n//Operadores de comparación\nconst operadoresComparacion = [\n    {operador: 'Mayor que', simbolo: '>'},\n    {operador: 'Menor que', simbolo: '<'},\n    {operador: 'Mayor o igual que', simbolo: '>='},\n    {operador: 'Menor o igual que', simbolo: '<='},\n    {operador: 'Igualdad', simbolo: '=='},\n    {operador: 'Igualdad Estricta', simbolo: '==='},\n    {operador: 'Desigualdad', simbolo: '!='},\n    {operador: 'Desigualdad Estricta', simbolo: '!=='},\n]\n\nfor (const operador of operadoresComparacion) {\n    booleanResult = eval(`${number1} ${operador.simbolo} ${number2}`)\n    console.log(`Resultado del operador de comparación ${operador.operador}: ¿${number1} ${operador.simbolo} ${number2}? ${booleanResult}`)\n}\n\nlet asign1 = 20;\nlet asign2 = 40;\n\nconsole.log('')\nconsole.log('OPERADORES DE ASIGNACIÓN:')\n// Operadores de asignación\nconst operadoresAsignacion = [\n    { operador: 'Asignacion', simbolo: '=' },\n    { operador: 'Asignacion de adicion', simbolo: '+=' },\n    { operador: 'Asignacion de resta', simbolo: '-=' },\n    { operador: 'Asignacion de multiplicacion', simbolo: '*=' },\n    { operador: 'Asignacion de division', simbolo: '/=' },\n    { operador: 'Asignacion de exponenciacion', simbolo: '**=' },\n];\n\nfor (const operador of operadoresAsignacion) {\n    let newAsign1 = asign1\n    let result;\n\n    switch (operador.simbolo) {\n        case '=':\n            newAsign1 = asign2;\n            result = newAsign1\n            console.log(`${operador.operador}: (${asign1} ${operador.simbolo} ${asign2}) = ${result}`)\n            break;\n        case '+=':\n            result = newAsign1 += asign2;\n            console.log(`${operador.operador}: (${asign1} ${operador.simbolo} ${asign2}) = ${result}`)\n            break;\n        case '-=':\n            result = newAsign1 -= asign2;\n            console.log(`${operador.operador}: (${asign1} ${operador.simbolo} ${asign2}) = ${result}`)\n            break;\n        case '*=':\n            result = newAsign1 *= asign2;\n            console.log(`${operador.operador}: (${asign1} ${operador.simbolo} ${asign2}) = ${result}`)\n            break;\n        case '/=':\n            result = newAsign1 /= asign2;\n            console.log(`${operador.operador}: (${asign1} ${operador.simbolo} ${asign2}) = ${result}`)\n            break;\n        case '**=':\n            result = newAsign1 **= asign2;\n            console.log(`${operador.operador}: (${asign1} ${operador.simbolo} ${asign2}) = ${result}`)\n            break;\n        default:\n            result = 'Operador no reconocido';\n    }\n}\n\n//Tipos de condicionales\nconst cond1 = 10\nconst cond2 = 20\nconst cond3 = 30\n\nconsole.log('')\nconsole.log('CONDICIONALES:')\n\n//Condicional IF...ELSE\nconsole.log(`Condición 1: ${cond1}`)\nconsole.log(`Condición 2: ${cond2}`)\nconsole.log(`Condición 3: ${cond3}`)\n\nconsole.log(\"CONDICIÓN IF:\")\nconsole.log('Chequeamos si la condición 2 es mayor a la condición 1')\n\nif (cond2 > cond1) {\n    console.log(`¿${cond2} > ${cond1}?`, cond2 > cond1)\n}\n\nconsole.log('CONDICION IF...ELSE')\nconsole.log('Chequeamos si la condición 2 es menor a la condición 1')\n\nif (cond2 < cond1) {\n    console.log(`¿${cond2} > ${cond1}?`, cond2 > cond1)\n} else {\n    console.log('La condición no se cumple')\n}\n\nconsole.log('CONDICION IF...ELSE IF...ELSE')\nconsole.log('Chequeamos si la condición 2 es menor a la condición 1, en caso de no cumplirse chequeamos si la condición 3 es mayor a la condición 2')\n\nif (cond2 < cond1) {\n    console.log(`¿${cond2} > ${cond1}?`, cond2 > cond1)\n} else if (cond3 > cond2) {\n    console.log(`¿${cond3} > ${cond2}?`, cond3 > cond2)\n}\nelse {\n    console.log('No se cumple ninguna condición')\n}\n\n//Condicional Switch\n\nconsole.log('')\nconsole.log('CONDICION SWITCH:')\n\nlet diaDeLaSemana = \"Lunes\";\n\nconsole.log(\"Condicional Switch en caso de mandarle un día de semana correcto\")\n\nswitch (diaDeLaSemana) {\n    case \"Lunes\":\n        console.log(\"Hoy es lunes.\");\n        break;\n    case \"Martes\":\n        console.log(\"Hoy es martes.\");\n        break;\n    case \"Miércoles\":\n        console.log(\"Hoy es miércoles.\");\n        break;\n    case \"Jueves\":\n        console.log(\"Hoy es jueves.\");\n        break;\n    case \"Viernes\":\n        console.log(\"Hoy es viernes.\");\n        break;\n    case \"Sábado\":\n    case \"Domingo\":\n        console.log(\"¡Es fin de semana!\");\n        break;\n    default:\n        console.log(\"Día no reconocido. ¿Estamos en una dimensión diferente?\");\n}\n\nconsole.log(\"Condicional Switch en caso de mandarle un día de semana INcorrecto, en este caso el día 'PEPE'\")\n\nlet diaDeLaSemanaIncorrecto = \"Pepe\"\n\nswitch (diaDeLaSemanaIncorrecto) {\n    case \"Lunes\":\n        console.log(\"Hoy es lunes.\");\n        break;\n    case \"Martes\":\n        console.log(\"Hoy es martes.\");\n        break;\n    case \"Miércoles\":\n        console.log(\"Hoy es miércoles.\");\n        break;\n    case \"Jueves\":\n        console.log(\"Hoy es jueves.\");\n        break;\n    case \"Viernes\":\n        console.log(\"Hoy es viernes.\");\n        break;\n    case \"Sábado\":\n    case \"Domingo\":\n        console.log(\"¡Es fin de semana!\");\n        break;\n    default:\n        console.log(`El dia de la semana '${diaDeLaSemanaIncorrecto}' no es reocnocido en nuestro calendario`);\n}\n\n//Operaciones Iterativas\n\nconsole.log('')\nconsole.log('OPERACIONES ITERATIVAS:')\n\n//Do...While\n\nlet i = 0\nlet max = 5\n\nconsole.log('Ciclo Do...While:')\n\ndo {\n    i++\n    console.log(`Valor de i: ${i}`)\n} while(i < max)\n\n//While\nconsole.log('Ciclo While:')\n\nlet j = 0\nwhile (j < max) {\n    j++\n    console.log(`Valor de i: ${j}`)\n}\n\n//FOR\nconsole.log('Ciclo FOR:')\n\nfor(let i = 0; i < max; i++) {\n    console.log(`Valor de i: ${i}`)\n}\n\nlet marcasDeAutos = ['Ford', 'Porche', 'Audi', 'Bmw']\nconsole.log('Array a analizar: ', marcasDeAutos)\n//For...in\n\nconsole.log('Ciclo For...in')\n\n\nfor (const marca in marcasDeAutos) {\n    console.log(`Conteo de marcas de autos: ${marca}`)\n}\n\n//For...of\nconsole.log('Ciclo For...of')\n\nfor (const marca of marcasDeAutos) {\n    console.log(`Marca de auto: ${marca}`)\n}\n\n//DIFICULTAD EXTRA:\n\nconsole.log('')\nconsole.log('EJERCICIO EXTRA:')\n\nlet nMin = 10\nlet nMax = 55\nlet conteo = []\n\nfor (nMin; nMin <= nMax; nMin++) {\n    if (nMin % 2 === 0) {\n        if (nMin !== 16) {\n            if (nMin % 3 !== 0) {\n                conteo.push(nMin)\n            }\n        }\n    }\n}\nconsole.log(conteo)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/LauraCastrillonMp.js",
    "content": "// Operadores Aritméticos\nlet num1 = 5 + 3; // Suma\nlet num2 = 5 - 3; // Resta\nlet num3 = 5 * 3; // Multiplicación\nlet num4 = 5 / 3; // División\nlet num5 = 5 % 3; // Módulo\n\nconsole.log(num1, num2, num3, num4, num5);\n\n// Operadores Lógicos\nlet bool1 = true && false; // AND\nlet bool2 = true || false; // OR\nlet bool3 = !true; // NOT\n\nconsole.log(bool1, bool2, bool3);\n\n// Operadores de Comparación\nlet comp1 = 5 > 3; // Mayor que\nlet comp2 = 5 < 3; // Menor que\nlet comp3 = 5 >= 3; // Mayor o igual que\nlet comp4 = 5 <= 3; // Menor o igual que\nlet comp5 = 5 === 3; // Igual que\nlet comp6 = 5 !== 3; // No igual que\n\nconsole.log(comp1, comp2, comp3, comp4, comp5, comp6);\n\n// Operadores de Asignación\nlet assign1 = 5;\nassign1 += 3; // Suma y asignación\nlet assign2 = 5;\nassign2 -= 3; // Resta y asignación\nlet assign3 = 5;\nassign3 *= 3; // Multiplicación y asignación\nlet assign4 = 5;\nassign4 /= 3; // División y asignación\nlet assign5 = 5;\nassign5 %= 3; // Módulo y asignación\n\nconsole.log(assign1, assign2, assign3, assign4, assign5);\n\n// Operadores de Identidad\nlet ident1 = 5 === \"5\"; // Igualdad estricta\nlet ident2 = 5 !== \"5\"; // Desigualdad estricta\n\nconsole.log(ident1, ident2);\n\n// Operadores de Pertenencia\nlet arr1 = [1, 2, 3, 4, 5];\nlet belong1 = 3 in arr1; // Verifica si el índice existe en el array\nlet belong2 = 6 in arr1;\n\nconsole.log(belong1, belong2);\n\n// Operadores de Bits\nlet bit1 = 5 & 3; // AND a nivel de bits\nlet bit2 = 5 | 3; // OR a nivel de bits\nlet bit3 = 5 ^ 3; // XOR a nivel de bits\nlet bit4 = ~5; // NOT a nivel de bits\nlet bit5 = 5 << 2; // Desplazamiento hacia la izquierda\nlet bit6 = 5 >> 2; // Desplazamiento hacia la derecha\n\nconsole.log(bit1, bit2, bit3, bit4, bit5, bit6);\n\n// Estructura de control: if-else\nlet num = 10;\nif (num > 5) {\n  console.log(\"El número es mayor que 5\");\n} else {\n  console.log(\"El número es menor o igual que 5\");\n}\n\n// Estructura de control: switch\nlet option = 2;\nswitch (option) {\n  case 1:\n    console.log(\"Opción 1 seleccionada\");\n    break;\n  case 2:\n    console.log(\"Opción 2 seleccionada\");\n    break;\n  default:\n    console.log(\"Opción no reconocida\");\n}\n\n// Estructura de control: while\nlet i = 0;\nwhile (i < 5) {\n  console.log(i);\n  i++;\n}\n\n// Estructura de control: do-while\nlet j = 0;\ndo {\n  console.log(j);\n  j++;\n} while (j < 5);\n\n// Estructura de control: for\nfor (let k = 0; k < 5; k++) {\n  console.log(k);\n}\n\n// Estructura de control: for...in\nlet obj = { a: 1, b: 2, c: 3 };\nfor (let prop in obj) {\n  console.log(prop + \": \" + obj[prop]);\n}\n\n// Estructura de control: for...of\nlet arr2 = [1, 2, 3, 4, 5];\nfor (let element of arr2) {\n  console.log(element);\n}\n\n// Estructura de control: try-catch\ntry {\n  throw new Error(\"Esto es una excepción\");\n} catch (error) {\n  console.log(error.message);\n}\n\n// Estructura de control: try-catch-finally\ntry {\n  throw new Error(\"Esto es otra excepción\");\n} catch (error) {\n  console.log(error.message);\n} finally {\n  console.log(\"Fin del bloque try-catch\");\n}\n\n// Ejercicio Extra\nfor (let i = 10; i <= 55; i++) {\n  if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n    console.log(i);\n  }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/Leonardo291024.js",
    "content": "// Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n\n//Operadores aritmeticos:\nconst suma = 10 + 5;\nconst resta = 10 - 5;\nconst multiplicacion = 10 * 5;\nconst divicion = 10 / 5;\n\nconsole.log(suma, resta, multiplicacion, divicion);\n\n//Operadores de comparacion:\nconst igualdad = 10 == 10;\nconst desigualdad = 10 !== 10;\nconst menorQue = 10 < 6;\nconst menorOIgual = 10 <= 6;\nconst mayorQue = 10 > 16;\nconst mayorOIgual = 10 >= 6;\n\n\nconsole.log(igualdad, desigualdad, menorQue, menorOIgual, mayorQue, mayorQue);\n\n//Operadores logicos\nconst and = a && b;\nconst or = a || b;\nconst not = !a;\n\n//operador de asignacion\nconst name = \"Leonardo\";\n\n\n//Utilizando las operaciones con operadores que tú quieras, crea ejemplos que representen todos los tipos deestructuras de control que existan en tu lenguaje:Condicionales, iterativas, excepciones...\n\nlet a = 18;\nlet b = 5;\n\nif(a === 10){\n    console.log(a + b);\n}else{\n    console.log(\"El numero a no es 10\");\n}\n\nfor(let i = 0; i <= 10; i++){\n    console.log(i);\n}\n\nlet num = 0;\n\nwhile(num <= 10){\n    console.log(num);\n    num++\n}\n\n//Crea un programa que imprima por consola todos los números comprendidos entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\nfor(let i = 0; i <= 55; i++){\n    if(i %2 === 0 && i !== 16 && i %3 != 0){\n        console.log(i);\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/MBBellini.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\nlet numInt = 8; \nlet numFloat = 5.870;\n\n// Operadores aritméticos \nlet num1 = 4;  \nlet num2 = 10;\nlet suma = num1 + num2;        \nlet resta = num2 - num1;\nlet multiplicar = num1 * num2;\nlet division = num2 / num1;\nlet modulo = num2 % num1;\nlet exponencial = num2 ** num1;\n\nconsole.log(suma);\nconsole.log(resta);\nconsole.log(multiplicar);\nconsole.log(division);\nconsole.log(modulo);\nconsole.log(exponencial);\n\n\n//operadores lógicos \nlet l = 8;\nlet k = 10;\nlet j = 3;\n\nlet and = (l > 5) && (k > 7)\nlet or = (l < 5) || (j < 10)\n\nconsole.log(and);\nconsole.log(or);\n\n\n//operador de comparación \nlet a = 5;\nlet b = 10;\n\nif (a >= b){\n    console.log(a + \" es mayor o igual que \" + b)       \n    }else {\n        console.log(a + \" es menor que \" + b);       \n    };  \n\n\n\n//Operador de concatenación \nlet name = \"Jane\";\nlet lastName = \"Doe\";\nlet fullName = name + \" \" + lastName;\nconsole.log(fullName);\n\n\n//Condicionales\nvar c = 7\nvar d = 3\nif (c > d){\n    console.log(\"it's large than\");  \n}\n\n\n//Ternario\nlet age = 21\nlet message = (age >= 21) ? \"you are adult\" : \"Under age\";\nconsole.log(message);\n\n\n//Switch es para evaluar una expresión y ejecute el bloque de codigo correspondiente al valor que coincide\nlet month = 10 //Octubre\n\nswitch (month) {\n    case 1:\n        console.log(\"January\");\n        break;\n    case 2:\n        console.log(\"February\");\n        break;\n        case 3:\n        console.log(\"March\");\n        break;\n        case 4:\n        console.log(\"April\");\n        break;\n        case 5:\n        console.log(\"May\");\n        break;\n        case 6:\n        console.log(\"June\");\n        break;\n        case 7: \n        console.log(\"July\");\n        break;\n        case 8:\n        console.log(\"August\");\n        break;\n        case 9:\n        console.log(\"September\");\n        break;\n        case 10:\n        console.log(\"October\");\n        break;\n        case 11:\n        console.log(\"November\");\n        break;\n        case 12:\n        console.log(\"December\");\n        break\n    default:\n        console.log(\"number to month invalid\");\n}\n\n\n//Manejo de excepcion\ntry {\n    let division = 12 / 2;\n    console.log(\"El resultado es: \" + division);\n} catch (error) {\n    console.log(\"Se ha producido un error: \" + error.message);\n}\n\n\n//Ejercicio extra\nfor (let i = 10; i <= 55; i++){\n    if(i % 2 === 0 && i !== 16 && i % 3 !== 0)\n    console.log(i); \n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/Magupe09.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n\n\n\n// tipos de operadores\n\n/* ARITMETICOS\n    suma,\n    resta,\n    multiplicacion,\n    division,\n    modulo,\n    incremento,decremento.\n    exponenciacion \n  */ \n\n\nlet suma = 2 + 5; // 7\nconsole.log(suma);\nlet resta = 2 - 5; // -3\nconsole.log(resta);\nlet multiplicacion = 2*5; // 10\nconsole.log(multiplicacion);\nlet division = 2 /5;\nconsole.log(division);\nlet modulo = 5 % 3; // modulo es 2\nconsole.log(modulo);\nlet a = 5;\na++; // a es 6\nconsole.log(a);\nlet b = 5;\nb--; // b es 4\nconsole.log(b);\nlet exponenciacion = 2 ** 3; // exponenciacion es 8\nconsole.log(exponenciacion);\n\n\n\n\n//  Operadores logicos  ------------- AND - OR - NOT LOGICO - NULLISH--\n\n// AND lógico (&&): Devuelve true si ambos operandos son true\n\nlet c = true;\nlet d = false;\nlet and = c && d; // and es false\nconsole.log(and)\n// OR lógico (||): Devuelve true si al menos uno de los operandos es true.\n\nlet e = true;\nlet f = false;\nlet or = a || b; // or es true\nconsole.log(or)\n// NOT lógico (!): Invierte el valor booleano del operando.\n\nlet g = true;\nlet resultado = !a; // resultado es false\nconsole.log(resultado)\n// Nullish Coalescing (??): Devuelve el operando de la derecha si el operando de la izquierda es null o undefined, de lo contrario, devuelve el operando de la izquierda.\n\nlet h = null;\nlet i = \"valor por defecto\";\nlet resultado2 = a ?? b; // resultado2 es \"valor por defecto\"\nconsole.log(resultado2)\n\n\n\n\n\n\n// A NIVEL DE BITS ------------- AND A NIVEL DE BITS - OR A NIVEL DE BITS---\n\n//AND a nivel de bits (&): Compara cada bit de sus dos operandos. Si ambos bits son 1, el bit resultante es 1. De lo contrario, el bit resultante es 0.\n\nlet j = 5;  // (en binario: 0101)\nlet k = 3;  // (en binario: 0011)\nlet resultado3 = a & b; // resultado3 es 1 (en binario: 0001)\nconsole.log(resultado3)\n// OR a nivel de bits (|): Compara cada bit de sus dos operandos. Si al menos uno de los bits es 1, el bit resultante es 1. De lo contrario, el bit resultante es 0.\n\nlet l = 5;  // (en binario: 0101)\nlet m = 3;  // (en binario: 0011)\nlet resultado4 = l | m; // resultado4 es 7 (en binario: 0111)\nconsole.log(resultado4)\n\n\n\n\n\n// operadores de comparacion ----- \n/* \n  igualdad,\n  igualdad estricta,\n  desigualdad,\n  desigualdad estricta,\n  mayor que ,\n  menor que,\n  menor o igual,\n  mayor o igual\n*/\n\n\n// Igualdad (==): Compara dos valores para ver si son iguales, realizando conversión de tipos si es necesario.\n\nlet n = 5;\nlet o = \"5\";\nconsole.log(n == o); // true\n\n// Igualdad estricta (===): Compara dos valores para ver si son iguales en valor y tipo.\n\nlet p = 5;\nlet q = \"5\";\nconsole.log(p === q); // false\n\n// Desigualdad (!=): Compara dos valores para ver si son diferentes, realizando conversión de tipos si es necesario.\n\nlet r = 5;\nlet s = \"5\";\nconsole.log(r != s); // false\n\n// Desigualdad estricta (!==): Compara dos valores para ver si son diferentes en valor o tipo.\n\n\nlet t = 5;\nlet u = \"5\";\nconsole.log(t !== u); // true\n\n//Mayor que (>): Verifica si el valor de la izquierda es mayor que el de la derecha.\n\nlet v = 5;\nlet w = 3;\nconsole.log(v > w); // true\n\n//Mayor o igual que (>=): Verifica si el valor de la izquierda es mayor o igual que el de la derecha.\n\nlet x = 5;\nlet y = 5;\nconsole.log(x >= y); // true\n\n\n//Menor que (<): Verifica si el valor de la izquierda es menor que el de la derecha.\n\nlet z = 3;\nlet aa = 5;\nconsole.log(z < aa); // true\n\n\n//Menor o igual que (<=): Verifica si el valor de la izquierda es menor o igual que el de la derecha.\n\nlet bb = 5;\nlet cc = 5;\nconsole.log(bb <= cc); // true\n\n\n\n\n\n// Operadores de asignaciòn----\n/*\n    Asignación simple (=): Asigna el valor del operando de la derecha a la variable de la izquierda.\n    Asignación de adición (+=): Suma el valor del operando de la derecha al operando de la izquierda y asigna el resultado a la variable de la izquierda.\n    Asignación de sustracción (-=): Resta el valor del operando de la derecha del operando de la izquierda y asigna el resultado a la variable de la izquierda.\n    Asignación de multiplicación (*=): Multiplica el valor del operando de la derecha por el operando de la izquierda y asigna el resultado a la variable de la izquierda.\n    Asignación de división (/=): Divide el operando de la izquierda por el valor del operando de la derecha y asigna el resultado a la variable de la izquierda.\n    Asignación de módulo (%=): Calcula el resto de dividir el operando de la izquierda por el operando de la derecha y asigna el resultado a la variable de la izquierda.\n    Asignación de exponenciación (=)**: Eleva el operando de la izquierda a la potencia del operando de la derecha y asigna el resultado a la variable de la izquierda.\n\n*/\n// Asignación simple\nlet x1 = 10;\nconsole.log(x1)\n\n// Asignaciòn de adiciòn \nlet x2= 10;\nx2 += 5; // x2 ahora es 15\nconsole.log(x2)\n\n//Asignación de sustracción\nlet x3 = 10;\nx3 -= 5; // x3 ahora es 5\nconsole.log(x3)\n\n//Asignación de multiplicación\nlet x4 = 10;\nx4 *= 5; // x4 ahora es 50\nconsole.log(x4)\n\n\n//  Asignación de división \nlet x5 = 10;\nx5 /= 5; // x5 ahora es 2\nconsole.log(x5)\n\n\n\n// Asignación de módulo\nlet x6 = 10;\nx6 %= 3; // x6 ahora es 1\nconsole.log(x6)\n\n\n//Asignación de exponenciación\nlet x7 = 2;\nx7 **= 3; // x7 ahora es 8\nconsole.log(x7)\n\n\n// Operadores de identidad -\n/* En JavaScript, los operadores de identidad se refieren principalmente a los operadores que comparan tanto el valor como el tipo de los operandos. Estos son:\n\n   Igualdad estricta (===):\n   Desigualdad estricta (!==): \n*/\n\n\n\n// igualdad estricta\nlet a1 = 5;\nlet b1 = 5;\nlet c1 = \"5\";\nconsole.log(a1 === b1); // true\nconsole.log(a1 === c1); // false\n\n\n//desigualdad estricta\nlet a2 = 5;\nlet b2 = 5;\nlet c2= \"5\";\nconsole.log(a2 !== b2); // false\nconsole.log(a2 !== c2); // true\n\n\n\n\n//En JavaScript, los operadores de pertenencia se utilizan para comprobar si una propiedad o un elemento existe dentro de un objeto o una estructura de datos. Los operadores de pertenencia más comunes son:\n/*\n   Operador in: Este operador se utiliza para verificar si una propiedad existe en un objeto. Devuelve true si la propiedad está en el objeto especificado.\n   Método hasOwnProperty: Este método se utiliza para verificar si una propiedad es una propiedad directa del objeto (no heredada). Devuelve true si la propiedad es una propiedad directa del objeto.\n   Operador instanceof: Este operador se utiliza para verificar si un objeto es una instancia de una clase o de una función constructora específica. Devuelve true si el objeto es una instancia de la clase especificada.\n\n\n\n\n */\n\n// operador in\nlet obj = { name: \"Alice\", age: 25 };\nconsole.log(\"name\" in obj); // true\nconsole.log(\"address\" in obj); // false\n\n//Método hasOwnProperty\nlet obj1 = { name: \"Alice\", age: 25 };\nconsole.log(obj1.hasOwnProperty(\"name\")); // true\nconsole.log(obj1.hasOwnProperty(\"toString\")); // false (heredado del prototipo)\n\n// Operador instanceof:\n\nfunction Person(name) {\n    this.name = name;\n  }\n  \n  let alice = new Person(\"Alice\");\n  console.log(alice instanceof Person); // true\n  console.log(alice instanceof Object); // true\n  \n\n\n//Estructuras de Control Condicionales\n/* \n   if: Ejecuta un bloque de código si la condición especificada es verdadera.\n   if...else: Ejecuta un bloque de código si la condición es verdadera y otro bloque si la condición es falsa.\n   else if: Permite comprobar múltiples condiciones.\n   switch: Ejecuta uno de varios bloques de código según el valor de una expresión.\n\n */\n\n//if\nlet xy = 10;\nif (xy > 5) {\n  console.log(\"xy es mayor que 5\");\n}\n\n// if...else:\nlet xa = 10;\nif (xa > 5) {\n  console.log(\"xa es mayor que 5\");\n} else {\n  console.log(\"xa no es mayor que 5\");\n}\n\n\n//else if: \nlet xb = 10;\nif (xb > 10) {\n  console.log(\"xb es mayor que 10\");\n} else if (xb == 10) {\n  console.log(\"xb es igual a 10\");\n} else {\n  console.log(\"xb es menor que 10\");\n}\n\n//switch:\nlet color = \"rojo\";\nswitch (color) {\n  case \"rojo\":\n    console.log(\"El color es rojo\");\n    break;\n  case \"azul\":\n    console.log(\"El color es azul\");\n    break;\n  default:\n    console.log(\"Color no reconocido\");\n}\n\n// Estructuras de Control de Bucles\n/* for: Repite un bloque de código un número específico de veces.\n   while: Repite un bloque de código mientras una condición especificada sea verdadera.\n   do...while: Similar a while, pero garantiza que el bloque de código se ejecute al menos una vez.\n   for...in: Itera sobre las propiedades enumerables de un objeto.\n   for...of: Itera sobre objetos iterables (como arrays, cadenas de texto, mapas, conjuntos, etc.).\n\n\n\n\n\n\n */\n\n// for:\nfor (let ii = 0; ii < 5; ii++) {\n    console.log(ii);\n  }\n  \n\n//while\nlet i2 = 0;\nwhile (i2 < 5) {\n  console.log(i2);\n  i2++;\n}\n\n//do...while:\nlet i3 = 0;\ndo {\n  console.log(i3);\n  i3++;\n} while (i3 < 5);\n\n\n//for...in: \nlet obj5 = { a: 1, b: 2, c: 3 };\nfor (let key in obj5) {\n  console.log(key + \": \" + obj5[key]);\n}\n\n// for of\nlet arr = [1, 2, 3, 4, 5];\nfor (let value of arr) {\n  console.log(value);\n}\n\n\n//Estructuras de Control de Salto\n/* break: Termina el bucle actual o la declaración switch.\n   continue: Salta a la siguiente iteración del bucle.\n   return: Finaliza la ejecución de una función y opcionalmente devuelve un valor.\n   throw: Lanza una excepción definida por el usuario.\n\n\n\n\n\n */\n\n//break:\nfor (let i = 0; i < 10; i++) {\n    if (i === 5) {\n      break;\n    }\n    console.log(i);\n  }\n  \n\n// continue\nfor (let i = 0; i < 10; i++) {\n    if (i === 5) {\n      continue;\n    }\n    console.log(i);\n  }\n  \n\n// return\nfunction sumaf(a, b) {\n    return a + b;\n  }\n  console.log(sumaf(5, 3)); // 8\n  \n//  throw:\nfunction verificaEdad(edad) {\n    if (edad < 18) {\n      throw new Error(\"No permitido para menores de edad\");\n    }\n    return \"Acceso permitido\";\n  }\n  \n  try {\n    console.log(verificaEdad(15));\n  } catch (error) {\n    console.log(error.message); // No permitido para menores de edad\n  }\n\n\n//  ---------------------- Plus \n\n/*\n  DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n*/\n\nfor(let i=10 ; i<=55;i++){\n    if(i % 2 === 0 && i !== 16 && i % 3 !==0 ){\n        console.log(i);\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/MarcosLombardo.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\nconst num1 = 10;\nconst num2 = 5;\n\n// Operadores aritméticos\nconsole.log(\"Operadores aritméticos:\");\n\nlet suma = num1 + num2;\nlet resta = num1 - num2;\nlet multiplicacion = num1 * num2;\nlet division = num1 / num2;\nlet modulo = num1 % num2;\nlet exponenciacion = num1 ** num2;\n\nconsole.log(\"Suma:\", suma);\nconsole.log(\"Resta:\", resta);\nconsole.log(\"Multiplicación:\", multiplicacion);\nconsole.log(\"División:\", division);\nconsole.log(\"Resto:\", modulo);\nconsole.log(\"Exponenciación:\", exponenciacion);\n\n// Operadores de asignación\nconsole.log(\"Operadores de asignación:\");\n\nlet x = num1; // Asignación\nx += division;\nconsole.log(\"Asignación de adición:\", x);\n\nlet y = num2;\ny -= 1;\nconsole.log(\"Asignación de resta:\", y);\n\nlet z = num1;\nz *= y;\nconsole.log(\"Asignación de multiplicación:\", z);\n\nlet a = multiplicacion;\na /= resta;\nconsole.log(\"Asignación de división:\", a);\n\nlet b = exponenciacion;\nb %= x;\nconsole.log(\"Asignación de resto:\", b);\n\n// Operadores de comparación\nconsole.log(\"Operadores de comparación:\");\n\nlet igualdad = y == \"4\";\nconsole.log(igualdad);\n\nlet igualdadEstricta = z === 40;\nconsole.log(igualdadEstricta);\n\nlet desigualdad = num1 != resta;\nconsole.log(desigualdad);\n\nlet desigualdadEstricta = 4 !== \"4\";\nconsole.log(desigualdadEstricta);\n\nlet mayorQue = num1 > num2;\nconsole.log(mayorQue);\n\nlet mayorIgualQue = 10 >= 10;\nconsole.log(mayorIgualQue);\n\nlet menorQue = suma < z;\nconsole.log(menorQue);\n\nlet menorIgualQue = multiplicacion <= 50;\nconsole.log(menorIgualQue);\n\n// Operadores lógicos\nconsole.log(\"Operadores lógicos:\");\n\nlet and = true && true;\nconsole.log(\"Operador AND lógico: && =>\", and);\n\nlet or = true || false;\nconsole.log(\"Operador OR lógico: || =>\", or);\n\nlet not = !false;\nconsole.log(\"Operador NOT lógico: ! =>\", not);\n\n// Dificultad extra\n\nfor (let i = 10; i <= 55; i++) {\n  if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n    console.log(i);\n  }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/MatiTC.js",
    "content": "//Operadores de Js\n\n//Aritméticos\nlet a = 7;\nlet b = 3;\nconsole.log(a + b); //suma. 7 + 3 = 10\nconsole.log(a - b); //resta. 7 - 3 = 4\nconsole.log(a * b); //multiplicación. 7 * 3 = 21\nconsole.log(a / b); //division. 7 / 3 = 2.33333335\nconsole.log(a % b); //modulo. 7 % 3 = 1\nconsole.log(++a); // incremento. 7 + 1 = 8 \nconsole.log(--b); // decremento. 3 - 1 = 2\n\n//Comparación (==)\nlet x = 10\nlet y = \"10\" \nconsole.log(x == y);  // 10 == \"10\" true (coerción de tipo)\nconsole.log(x === y); // 10 == \"10\" false (sin coerción de tipo)\nconsole.log(x != y);  // 10 != \"10\" false (coerción de tipo)\nconsole.log(x !== y); // 10 != \"10\" true (sin coerción de tipo)\nconsole.log(x > 5); // true\nconsole.log(y < 5); // false\n\n//Lógicos AND(&&) OR(||) NOT(!)\nlet p = true;\nlet q = false;\nconsole.log(p && q); // false (y lógico)\nconsole.log(p || q); // true (o lógico)\nconsole.log(!p);     // false (no lógico)\n\n//Asignación \nlet num = 10; //equivalente x = y\nnum += 5; // equivalente a num = num + 5;\nnum -= 3; // equivalente a num = num - 3;\nnum *= 2; // equivalente a num = num * 2;\nnum /= 4; // equivalente a num = num / 4;\nnum **= 4; // equivalente a num = num ** 4;\nnum %= 2; // equivalente a num = num % 2;\nconsole.log(num);\n\n//Identidad\nlet m = 10;\nlet n = \"10\";\nconsole.log(m == n); // true (comparación estricta)\nconsole.log(m != n); // false (comparación estricta)\nconsole.log(m === n); // false (comparación estricta)\nconsole.log(m !== n); // true (comparación estricta)\n\n//Pertenencia\nlet obj = { prop: \"valor\" }; //Objeto(Estructura de datos que agrupa propiedades y métodos)\nconsole.log(\"prop\" in obj); // true (verifica si la propiedad está en el objeto)\n\n//Operadores a nivel de bits(Esto si lo copie)\nlet c = 5;   // Representación binaria: 0101\nlet d = 3;   // Representación binaria: 0011\n\nconsole.log(c & d);  // 1 (AND a nivel de bits: 0101 & 0011 = 0001)\nconsole.log(c | d);  // 7 (OR a nivel de bits: 0101 | 0011 = 0111)\nconsole.log(c ^ d);  // 6 (XOR a nivel de bits: 0101 ^ 0011 = 0110)\nconsole.log(~c);     // -6 (NOT a nivel de bits: ~0101 = 1010, considerando el complemento a 2)\nconsole.log(c << 1); // 10 (desplazamiento a la izquierda: 0101 << 1 = 1010)\nconsole.log(d >> 1); // 1  (desplazamiento a la derecha con signo: 0011 >> 1 = 0001)\nconsole.log(d >>> 1);// 1  (desplazamiento a la derecha sin signo: 0011 >>> 1 = 0001)\n\n/* - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n * que representen todos los tipos de estructuras de control que existan\n * en tu lenguaje:\n*/\n\nconsole.log(`.........................................`)\n//Condicionales (if-else):\n\nlet miEdad = 24;\nlet tuEdad = 31;\n\nif (miEdad > tuEdad){\n    console.log(`Si soy mayor ${miEdad}`)\n}else{\n    console.log(`No, soy soy menor que tu. Tengo ${miEdad}`)\n}\n\nif (miEdad > tuEdad){\n    console.log(`Si soy mayor ${miEdad}`)\n}else if ( miEdad == tuEdad){\n    console.log(`Tenemos la misma edad, yo tengo ${miEdad} y tu también tienes ${tuEdad}`);\n} else {\n    console.log(\"Entonces yo soy el menor\");\n}\n\nconsole.log(`.........................................`)\n//Iterativas \n//For clásico. Interactúa 5 veces\nfor (let i = 0; i < 5; i++) {\n    console.log(\"Iteración \" + (i + 1));\n}\n\nconsole.log(`.........................................`)\n//For..in\n//Utilizado sobre propiedades de un objeto.\nconst persona = {\n    nombre: \"Juan\",\n    edad: 25,\n    ciudad: \"Ejemplo\"\n};\n\nfor (let propiedad in persona) {\n    console.log(propiedad + \": \" + persona[propiedad]);\n}\n\nconsole.log(`.........................................`)\n\n\n//for...of:\n//Utilizado para iterar sobre objetos iterables\nconst numeros = [1, 2, 3, 4, 5];\n\nfor (let numero of numeros) {\n    console.log(numero);\n}\nconsole.log(`.........................................`)\n\n//forEach\n//Método específico de los Arrays \nconst colores = [\"rojo\", \"verde\", \"azul\"];\n\ncolores.forEach(function(color, indice) {\n    console.log(\"Color en posición \" + indice + \": \" + color);\n});\n\nconsole.log(`.........................................`)\n//Iterativas (while) \n//Comprueba la condición lógica y después ejecuta\nlet contador = 0;\n\nwhile (contador < 3) {\n    console.log(\"While \" + (contador + 1));\n    contador++;\n}\nconsole.log(`.........................................`)\n\n////Iterativas (while) \n//Ejecuta el algoritmo y después hace la comprobación\nlet j = 0;\n\ndo {\n    console.log(\"Do While \" + (j + 1));\n    j++;\n} while (j < 2);\nconsole.log(`.........................................`)\n\n//Manejo de Excepciones (try-catch):\nfunction dividirNumeros(a, b) {\n    try {\n        if (b === 0) {\n            throw new Error(\"No se puede dividir por cero.\");\n        }\n        let resultado = a / b;\n        console.log(\"Resultado: \" + resultado);\n        return resultado;\n    } catch (error) {\n        console.error(\"Error: \" + error.message);\n    }\n}\nconsole.log(dividirNumeros(10, 2)) // Resultado: 5\nconsole.log(dividirNumeros(8, 0)) // Error: No se puede dividir por cero.\n\nconsole.log(`.........................................`)\n\n//Switch \nlet diaDeLaSemana = 3;\nlet mensaje;\n\nswitch (diaDeLaSemana) {\n    case 1:\n        mensaje = \"Lunes\";\n        break;\n    case 2:\n        mensaje = \"Martes\";\n        break;\n    case 3:\n        mensaje = \"Miércoles\";\n        break;\n    case 4:\n        mensaje = \"Jueves\";\n        break;\n    case 5:\n        mensaje = \"Viernes\";\n        break;\n    case 6:\n        mensaje = \"Sábado\";\n        break;\n    case 7:\n        mensaje = \"Domingo\";\n        break;\n    default:\n        mensaje = \"Día no válido\";\n}\n\nconsole.log(\"Hoy es \" + mensaje);\n\n/*\n * EJERCICIO:\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n */\n\nfunction imprimirNumerosPares(inicio, fin) {\n    for (let i = inicio; i <= fin; i++) {\n        if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n            console.log(i);\n        }\n    }\n}\n\nimprimirNumerosPares(10, 55);\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/Matiascba27.js",
    "content": "// Reto numero 1: Operadores\n// 1. Operadores aritmeticos\nlet a = 10;\nlet b = 5;\nconsole.log(`Suma: ${a} + ${b} = ${a + b}`);\nconsole.log(`Resta: ${a} - ${b} = ${a - b}`);\nconsole.log(`Multiplicacion: ${a} * ${b} = ${a * b}`);\nconsole.log(`Division: ${a} / ${b} = ${a / b}`);\nconsole.log(`Modulo: ${a} % ${b} = ${a % b}`);\nconsole.log(`Exponensiacion: ${a} ** ${b} = ${a ** b}`);\nconsole.log(`Incremento: ${a}++ = ${++a}`);\nconsole.log(`Decremento: ${b}-- = ${--b}`);\n\n// 2. Operadores de Asignacion\nlet c = 10;\nc += 2;  console.log(\"+=:\", c);\nc -= 5;  console.log(\"-=:\", c);\nc *= 10;  console.log(\"*=:\", c);\nc /= 4;  console.log(\"/=:\", c);\nc %= 8;  console.log(\"%=:\", c);\nc **= 12; console.log(\"**=:\", c);\n\n// 3. Operadores de Comparacion\nconsole.log(\"Igual valor: \", 5 == \"5\");\nconsole.log(\"Igual valor y tipo: \", 5 === \"5\");\nconsole.log(\"No igual: \", 5 != \"6\");\nconsole.log(\"No igual valor o tipo: \", 5 !== \"5\");\nconsole.log(\"Mayor que: \", 7 > 3);\nconsole.log(\"Menor que: \", 3 < 7);\nconsole.log(\"Mayor o igual: \", 7 >= 7);\nconsole.log(\"Menor o igual: \", 5 <= 7);\n\n// 4. Operadores logicos\nconsole.log(\"AND:\", true && false);\nconsole.log(\"OR:\", true || false);\nconsole.log(\"NOT:\", !true); \n\n// 5. Operadores de cadena\nconsole.log(\"Concatenacion:\", \"Hola\" + \" \" + \"Mundo\");\n\n// 6. Opreador condicional (Ternario)\nlet edad = 20;\nlet mensaje = (edad >= 18) ? 'Adulto' : 'Menor';\nconsole.log(\"Ternario:\", mensaje);\n\n// 7. Operador de tipo\nconsole.log(\"Tipo de dato: \", typeof 10);\nconsole.log(\"Tipo de dato: \", typeof \"Hola\");\nconsole.log(\"Tipo de dato: \", typeof true);\nconsole.log(\"Tipo de dato: \", typeof null);\nconsole.log(\"Tipo de dato: \", typeof undefined);\nconsole.log(\"Tipo de dato: \", typeof [1, 2, 3]);\nconsole.log(\"Tipo de dato: \", typeof function() {});\nconsole.log(\"Tipo de dato: \", typeof Symbol('id'));\n\n// 8. Operador de propagacion (Spread)\nlet array1 = [1, 2, 3];\nlet array2 = [...array1, 4, 5, 6];\nconsole.log(\"Spread:\", array2);\n\n// Reto numero 2: Estructuras de control\n\n// 1. Estructura condicionales\n\n// if-else\nlet edad1 = 18;\nif (edad >= 18) {\n    console.log(\"Eres mayor de edad\");\n} else {\n    console.log(\"Eres menor de edad\");\n}\n\n// if-else if-else\nlet nota = 75;\nif (nota >= 90) {\n    console.log(\"Sobresaliente\");\n} else if (nota >= 70) {\n    console.log(\"Notable\");\n} else if (nota >= 50) {\n    console.log(\"Aprobado\");\n} else {\n    console.log(\"Reprobado\");    \n}\n\n// Switch\nlet dia = \"Lunes\";\nswitch (dia) {\n    case \"Lunes\":\n        console.log(\"Inicio de semana\");\n        break;\n    case \"Viernes\":\n        console.log(\"Fin de semana laboral\");\n        break;\n    case \"Sabado\":\n        console.log(\"Fin de semana\");\n        break;\n    default:\n        console.log(\"Dia entre semana\");\n}\n\n// 2. Estructuras Iterativas\n// for\nfor (let i = 0; i < 10; i++) {\n    console.log(\"Iteracion for:\", i);\n}\n\n// while\nlet contador = 0;\nwhile (contador < 10) {\n    console.log(\"Iteracion while:\", contador);\n    contador++;\n}\n\n// do while\nlet contador2 = 0;\ndo {\n    console.log(\"Iteracion do while:\", contador2);\n    contador2++;\n} while (contador2 < 10);\n\n// for...of (Ietarar sobre arreglos)\nlet frutas = [\"Manzana\", \"Pera\", \"Naranja\"];\nfor (let fruta of frutas) {\n    console.log(\"Fruta:\", fruta);\n}\n\n// for...in (Ietarar sobre objetos)\nlet persona = {\n    nombre : \"Juan\",\n    edad : 30,\n    ciudad : \"Barcelona\"\n};\nfor (let propiedad in persona) {\n    console.log(propiedad + \": \" + persona[propiedad]);\n}\n\n// 3. Manejo de excepciones\ntry {\n    // Código que puede fallar\n    let resultado = 10 / 0;\n    console.log(\"Resultado:\", resultado);\n\n    // Forzar un error\n    throw new Error(\"Este es un error forzado\");\n} catch (error) {\n    // Capturar y manejar la excepcion\n    console.log(\"Se produjo un error:\", error.message);\n} finally {\n    // Código que se ejecutara siempre haya error o no\n    console.log(\"Esto se ejecuta siempre\");\n}\n\n// DIFICULTAD EXTRA\nconsole.log(\"------- Dificultad Extra-------- \\n\");\n\n// Solucion 1: Usando un bucle for y condicionales\nfor (let i = 10; i <= 55; i++) {\n    if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n        console.log(i);\n    }\n}\n\n// Solucion 2: Usando un bucle while\nlet num = 10;\nwhile ( num <= 55) {\n    if (num % 2 === 0 && num !== 16 && num % 3 !== 0) {\n        console.log(num);\n    }\n    num++;\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/MiguelAngelMTZ.js",
    "content": "// Operadores Aritmeticos - JavaScript\nconsole.info(\"------(◉◉∖____/◉◉)------ Operadores Aritméticas (+, -, *, /, %, ++, --) ------(OO∖____/OO)------\")\nlet Numero = 17 // Dividiendo\nlet numero = 5 // Divisor\n// Suma\nconsole.log(`Sumando: ${Numero} + ${numero}, da como resultado:`, Numero + numero)\n// Resta\nconsole.log(\"Restando:\", Numero, \"-\", numero, \", da como resultado:\",   Numero - numero)\n// Multiplicación\nconsole.log(`Multiplicando: ${Numero} x ${numero}, da como resultado: ` + Numero * numero)\n// Division\nconsole.log(`Dividiendo: ${Numero} / ${numero}, da como resultado:`, Numero / numero)\n// Modulo\nconsole.log(`Modulo: ${Numero} % ${numero}, da como resultado:`, Numero % numero + `. \n    Porque dividiendo ${Numero} entre ${numero} obtenemos ${Math.floor(Numero/numero)} como cociente (porque ${numero} * ${Math.floor(Numero/numero)} = ${numero * Math.floor(Numero/numero)}) y un residuo de:`, Numero % numero)\n/////////////////////////////////////\nconsole.log(`Modulo: ${24} % ${2}, da como resultado: ${24 % 2}. \n    Porque dividiendo ${24} entre ${2} obtenemos ${Math.floor(24/2)} como cociente (porque ${2} * ${Math.floor(24/2)} = ${2 * Math.floor(24/2)}) y un residuo de: ${24 % 2}`)\n// Incremento ++\nconsole.log(\"Incremento:\", \"++\" + numero, \"=\", ++numero)\n// Descremento --\nconsole.log(`Descremento: --${Numero} =`, --Numero)\n// Exponente\n\n// Operadores de asignación - JavaScript\nconsole.log(\"------(◉◉∖____/◉◉)------ Operadores de Asignación (=, +=, -=, *=, /=, **=/ %=) ------(OO∖____/OO)------\")\nlet variableNum = 10\nconsole.log(`Asignar valor a (variableNum =):`, variableNum)\nconsole.log(`Suma con asignación: variableNum (${variableNum}) += 35:`, variableNum += 35)\nconsole.log(`Resta con asignación: variableNum (${variableNum}) -= 5:`, variableNum -= 5)\nconsole.log(`Multiplicación con asignación: variableNum (${variableNum}) *= 12:`, variableNum *= 12)\nconsole.log(`División con asignación: variableNum (${variableNum}) /= 2:`, variableNum /= 2)\nconsole.log(`Exponente con asignación: variableNum (${variableNum}) **= 2:`, variableNum **= 2)\nconsole.log(\"---------------------------------------------------------------------\")\nconsole.log(`${variableNum} % ${42}: ${(variableNum % 42)}\n    Dividiendo ${variableNum} entre ${42} obtenemos ${Math.floor(variableNum/42)} como cociente, (porque ${Math.floor(variableNum/42)} * ${42} = ${42 * Math.floor(variableNum/42)}) y un residuo de: ${variableNum % 42}.\n    (${variableNum % 42}) más (${42 * Math.floor(variableNum/42)}) da como resultado: ${(variableNum % 42) + (42 * Math.floor(variableNum/42))}`)\nconsole.log(\"---------------------------------------------------------------------\")\nconsole.log(`Módulo con asignación: variableNum (${variableNum}) %= 42:`, variableNum %= 42)\n\n// Operadores de Comparación - JavaScript\nconsole.log(\"------(◉◉∖____/◉◉)------ Operadores de Comparación (>, >=, <, <=, == , ===, !=, !==) ------(OO∖____/OO)------\")\nconsole.log(\"Operador Lógico (Mayor que), 4 > 2:\", 4 > 2)\nconsole.log(\"Operador Lógico (Mayor que), 4 > 8:\", 4 > 8)\nconsole.log(\"Operador Lógico (Mayor o igual que), 4 >= 8:\", 4 >= 8)\nconsole.log(\"Operador Lógico (Mayor o igual que), 4 >= 4:\", 4 >= 4)\nconsole.log(\"Operador Lógico (Mayor o igual que), 4 >= 3:\", 4 >= 3)\n\nconsole.log(\"---------------------------------------------------------------------\")\nconsole.log(\"Operador Lógico (Menor que), 4 < 50:\", 4 < 50)\nconsole.log(\"Operador Lógico (Menor que), 50 < 50:\", 50 < 50)\nconsole.log(\"Operador Lógico (Menor o igual que), 51 <= 50:\", 51 <= 50)\nconsole.log(\"Operador Lógico (Menor o igual que), 50 <= 50:\", 50 <= 50)\nconsole.log(\"Operador Lógico (Menor o igual que), 49 <= 50:\", 49 <= 50)\n\nconsole.log(\"---------------------------------------------------------------------\")\nlet VeintiCuatro = 24\nconsole.log(\"Operador Lógico (Igual a), VeintiCuatro == 24:\", VeintiCuatro == 24) // Igualdad por valor\nconsole.log(\"Operador Lógico (Igual a), 24 == 24:\", 24 == 24) // Igualdad por valor\nconsole.log(`Operador Lógico (Igual a), 24 == \"24\":`, 24 == `24`) // Igualdad por valor\nconsole.log(\"Operador Lógico (Igual a), 24 == 25:\", 24 == 25) // Igualdad por valor\nconsole.log(\"Operador Lógico (Igual a), 24 == '25':\", 24 == \"25\") // Igualdad por valor\nconsole.log(\"Operador Lógico (Igual a), true == true:\", true == true) // Igualdad por valor\nconsole.log(\"Operador Lógico (Igual a), true == !true:\", true == !true) // Igualdad por valor\nconsole.log(\"Operador Lógico (Igual a), false == false:\", false == false) // Igualdad por valor\nconsole.log(\"Operador Lógico (Igual a), false == !false:\", false == !false) // Igualdad por valor\nconsole.log(\"Operador Lógico (Igual a), 0 == true:\", 0 == true) // Igualdad por valor\nconsole.log(\"Operador Lógico (Igual a), 0 == false:\", 0 == false) // Igualdad por valor\nconsole.log(\"Operador Lógico (Igual a), 0 == ' ':\", 0 == \"\") // Igualdad por valor\nconsole.log(\"Operador Lógico (Igual a), null == null:\", null == null) // Igualdad por valor\nconsole.log(\"Operador Lógico (Igual a), 0 == null:\", 0 == null) // Igualdad por valor\nconsole.log(\"Operador Lógico (Igual a), 0 == !null:\", 0 == !null) // Igualdad por valor\nconsole.log(\"Operador Lógico (Igual a), 0 == !!null:\", 0 == !!null) // Igualdad por valor\nconsole.log(\"Operador Lógico (Igual a), undefined == undefined:\", undefined == undefined) // Igualdad por valor\nconsole.log(\"Operador Lógico (Igual a), 0 == undefined:\", 0 == undefined) // Igualdad por valor\nconsole.log(\"Operador Lógico (Igual a), 0 == !undefined:\", 0 == !undefined) // Igualdad por valor\nconsole.log(\"Operador Lógico (Igual a), 0 == !!undefined:\", 0 == !!undefined) // Igualdad por valor\nconsole.log(\"Operador Lógico (Igual a), 0 == 'Hola':\", 0 == \"Hola\") // Igualdad por valor\nconsole.log(\"Operador Lógico (Igual a), 'HOla' == 'Hola':\", \"HOla\" == \"Hola\") // Igualdad por valor\nconsole.log(\"Operador Lógico (Igual a), 'Hola' == 'Hola':\", \"Hola\" == \"Hola\") // Igualdad por valor\nconsole.log(\"Operador Lógico (Igual a), 'Hola' == 'McLaren':\", \"Hola\" == \"McLaren\") // Igualdad por valor\nconsole.log(\"Operador Lógico (Igual a), object == object:\", Object == Object) // Igualdad por valor\n\nconsole.log(\"---------------------------------------------------------------------\")\nlet cinco = 5\nconsole.log(\"Operador Lógico (Estrictamente igual), cinco === 5:\", cinco === 5) // Igualdad por identidad (por tipo y valor) o igualdad estricta\nconsole.log(\"Operador Lógico (Estrictamente igual), 5 === 5:\", 5 === 5) // Igualdad por identidad (por tipo y valor) o igualdad estricta\nconsole.log(\"Operador Lógico (Estrictamente igual), '5' === 5:\", \"5\" === 5) // Igualdad por identidad (por tipo y valor) o igualdad estricta\nconsole.log(\"Operador Lógico (Estrictamente igual), 1 === 10:\", 1 === 10) // Igualdad por identidad (por tipo y valor) o igualdad estricta\nconsole.log(\"Operador Lógico (Estrictamente igual), -10 === 10:\", -10 === 10) // Igualdad por identidad (por tipo y valor) o igualdad estricta\nconsole.log(\"Operador Lógico (Estrictamente igual), 'Porsche' === 'PorschE':\", \"Porsche\" === \"PorschE\") // Igualdad por identidad (por tipo y valor) o igualdad estricta\nconsole.log(\"Operador Lógico (Estrictamente igual), null === null:\", null === null) // Igualdad por identidad (por tipo y valor) o igualdad estricta\nconsole.log(\"Operador Lógico (Estrictamente igual), ' ' === 0:\", \" \" === 0) // Igualdad por identidad (por tipo y valor) o igualdad estricta\nconsole.log(\"---------------------------------------------------------------------\")\nconsole.log(\"Operador Lógico (No igual a), 24 != 24:\", 24 != 24) // Desigualdad por valor\nconsole.log(\"Operador Lógico (No igual a), '24' != 24:\", \"24\" != 24) // Desigualdad por valor\nconsole.log(\"Operador Lógico (No igual a), '24' != '24':\", \"24\" != \"24\") // Desigualdad por valor\nconsole.log(\"Operador Lógico (No igual a), 25 != 24:\", 25 != 24) // Desigualdad por valor\nconsole.log(\"Operador Lógico (No igual a), 24 != '25':\", 24 != \"25\") // Desigualdad por valor\nconsole.log(\"Operador Lógico (No igual a), 25 != 'Volkswagen':\", 25 != \"Volkswagen\") // Desigualdad por valor\nconsole.log(\"Operador Lógico (No igual a), true != true:\", true != true) // Desigualdad por valor\nconsole.log(\"Operador Lógico (No igual a), true != false:\", true != false) // Desigualdad por valor\n\nconsole.log(\"---------------------------------------------------------------------\")\nconsole.log(\"Operador Lógico (Estrictamente no igual), 12 !== '13':\", 12 !== '13') // Desigualdad por identidad (por tipo y por valor) o desigualdad estricta\nconsole.log(\"Operador Lógico (Estrictamente no igual), 12 !== '12':\", 12 !== '12') // Desigualdad por identidad (por tipo y por valor) o desigualdad estricta\nconsole.log(\"Operador Lógico (Estrictamente no igual), 12 !== 12:\", 12 !== 12) // Desigualdad por identidad (por tipo y por valor) o desigualdad estricta\nconsole.log(\"Operador Lógico (Estrictamente no igual), '11' !== '11':\", 11 !== 11) // Desigualdad por identidad (por tipo y por valor) o desigualdad estricta\nconsole.log(\"Operador Lógico (Estrictamente no igual), 'Doce' !== 12:\", \"Doce\" !== 12) // Desigualdad por identidad (por tipo y por valor) o desigualdad estricta\nconsole.log(\"Operador Lógico (Estrictamente no igual), 'Doce' !== 'Doce':\", \"Doce\" !== \"Doce\") // Desigualdad por identidad (por tipo y por valor) o desigualdad estricta\n\n// Operadores Logicos - JavaScript\nconsole.log(\"------(◉◉∖____/◉◉)------ Operadores Lógicos (&&, ||, !) ------(OO∖____/OO)------\")\nconsole.log(\"----------------------------------- (y && ADD) ----------------------------------\")\nconsole.log(\"24 > 24 && 24 > 24:\", 24 > 24 && 24 > 24)\nconsole.log(\"24 > 0 && 24 > 23:\", 24 > 0 && 24 > 23)\nconsole.log(\"23 > 24 && 24 > 23:\", 23 > 24 && 24 > 23)\nconsole.log(\"23 < 24 && 24 > 23:\", 23 < 24 && 24 > 23)\nconsole.log(\"23 < 24 && 23 > 24:\", 23 < 24 && 23 > 24)\nconsole.log(\"'Ford GT' != 40 && 5 !== '5':\", 'Ford GT' != 40 && 5 !== '5')\n\nconsole.log(\"----------------------------------- (o || OR) ----------------------------------\")\nconsole.log(\"23 >= 23 || McLaren == McLaren:\", 23 >= 23 || \"McLaren\" == \"McLaren\")\nconsole.log(\"23 < 100 || McLaren == McLaren:\", 23 < 100 || \"McLaren\" == \"McLaren\")\nconsole.log(\"Lamborghini == McLaren || 512 < 100:\", \"Lamborghini\" == \"McLaren\" || 512 < 100 )\nconsole.log(\"'Ford GT' != 40 || 5 !== '5':\", 'Ford GT' != 40 || 5 !== '5')\n\nconsole.log(\"----------------------------------- (no ! NOT) ----------------------------------\")\nconsole.log(\"!true:\", !true)\nconsole.log(\"!false:\", !false)\nconsole.log(\"!null:\", !null)\nconsole.log(\"null:\", null)\nconsole.log(\"!undefined:\", !undefined)\nconsole.log(\"undefined:\", undefined)\nconsole.log(\"!(100 < 50) && 'Nissan' == 45:\", !(100 < 50) && \"Nissan\" == 45)\nconsole.log(\"!(100 < 50) && 'Nissan' != 45:\", !(100 < 50) && \"Nissan\" != 45)\nconsole.log(\"!(100 < 50) && '45' !== '45':\", !(100 < 50) && \"45\" !== \"45\")\nconsole.log(\"!(100 < 50) && 45 !== '45':\", !(100 < 50) && 45 !== \"45\")\n\n// Operadores de bit - JavaScript\nconsole.log(\"------(◉◉∖____/◉◉)------ Operadores de Bit (&, |, ^, ~, ~~, <<, >>, >>>) ------(OO∖____/OO)------\")\nconsole.log(\"Operador AND, 1 & 0:\", 1 & 0) // Devuelve 1 si ambos operados son 1.\nconsole.log(\"Operador AND, 1 & 1:\", 1 & 1) // Devuelve 1 si ambos operados son 1.\nconsole.log(\"Operador OR, 0 | 1:\", 0 | 1) // Devuelve 1 si al menos un operador es 1.\nconsole.log(\"Operador OR, 1 | 1:\", 1 | 1) // Devuelve 1 si al menos un operador es 1.\nconsole.log(\"Operador OR, 0 | 0:\", 0 | 0) // Devuelve 1 si al menos un operador es 1.\nconsole.log(\"Operador XOR (OR exclusivo), 1 ^ 1:\", 1 ^ 1) // Devuelve 1 si ambos operadores son diferentes\nconsole.log(\"Operador XOR (OR exclusivo), 0 ^ 1:\", 0 ^ 1) // Devuelve 1 si ambos operadores son diferentes\nconsole.log(\"Operador NOT (unario), ~0:\", ~0) // Invierte los bits del operador. Trunca a 32 bits.\nconsole.log(\"Operador NOT (unario), ~1:\", ~1) // Invierte los bits del operador. Trunca a 32 bits.\nconsole.log(\"Operador NOT (unario), ~9:\", ~9) // Invierte los bits del operador. Trunca a 32 bits.\nconsole.log(\"Operador NOT (unario), ~-9:\", ~-9) // Invierte los bits del operador. Trunca a 32 bits.\nconsole.log(\"Operador double NOT (unario), ~~0:\", ~~0) // Trunca los decimales del numero, convirtiendolo en entero. Solo 32 bits.\nconsole.log(\"Operador double NOT (unario), ~~1:\", ~~1) // Trunca los decimales del numero, convirtiendolo en entero. Solo 32 bits.\nconsole.log(\"Operador double NOT (unario), ~~1.52:\", ~~1.52) // Trunca los decimales del numero, convirtiendolo en entero. Solo 32 bits.\nconsole.log(\"Operador double NOT (unario), ~~5.68:\", ~~5.68) // Trunca los decimales del numero, convirtiendolo en entero. Solo 32 bits.\nconsole.log(\"Operador double NOT (unario), ~~-5.68:\", ~~-5.68) // Trunca los decimales del numero, convirtiendolo en entero. Solo 32 bits.\nconsole.log(\"Operador LEFT SHIFT, 9 << 2:\", 9 << 2) // Desplazamiento de bits hacia la izquierda\nconsole.log(\"Operador RIGHT SHIFT, 9 >> 2:\", 9 >> 2) // Desplazamiento de bits hacia la derecha\nconsole.log(\"Operador  RIGHT SHIFT sin signo, 19 >>> 2:\", 19 >>> 2) // Desplazamiento de bits hacia la derecha, como un operador sin signo\n\n// Condicionales - JavaScript\nconsole.log(\"------(◉◉∖____/◉◉)------ Condicionales-JavaScript ------(OO∖____/OO)------\")\nconsole.log(\"----------------------------------- (if, else if, else) ----------------------------------\")\nlet dividiendo = 24\nlet divisor = 2\nif (dividiendo == 0 && divisor == 0) {\n    console.log(`No se puede hacer la división, porque: ${dividiendo} / ${divisor} es 0.`)\n} else if (dividiendo == 0) {\n    console.log(\"No se puede dividir entre: \" + dividiendo + \"/\" + divisor)\n} else if (divisor == 0){\n} else {\n    console.log(`El resultado de la división: ${dividiendo}/${divisor} = ${dividiendo/divisor}`)\n}\n\nconsole.log(\"----------------------------------- (switch) ----------------------------------\")\n// Switch\nconst a = 12\nconst b = 10\nlet operación = \"Suma\"\n\nswitch (operación) {\n    case \"Suma\":\n        console.log(`Sumando ${a} + ${b}:`, a+b)\n        break\n    case \"Resta\":\n        console.log(`Restando ${a} - ${b}:`, a-b)\n        break\n    case \"Multiplicación\":\n        console.log(`Multiplicando ${a} x ${b}:`, a*b)\n        break\n    case \"Modulo\":\n        console.log(`Modulo ${a} % ${b}:`, a%b)\n        break\n    case \"Exponente\":\n        console.log(`Exponente ${a}**${b}:`, a**b)\n        break\n    default:\n        console.log(\"default\")\n        break\n}\n\n// Iterativas - JavaScript\nconsole.log(\"------(◉◉∖____/◉◉)------ Iterativas-JavaScript ------(OO∖____/OO)------\")\nconsole.log(\"----------------------------------- (Ciclo For) ----------------------------------\")\nlet i\nfor (let i = 1; i <= 10; i++) {\n    console.log(\"-. \" + i)\n}\nconsole.log(\"----------------------------------- (For Of) ----------------------------------\")\nconst animales = [\"🦉\", \"🐧\", \"🦆\", \"🐓\", \"🐌\", \"🦔\", \"🐿\", \"🐠\", \"🐕‍🦺\", \"🐈\"]\nfor (const value of animales) {\n    console.log(value)\n}\nlet numeros = [1, 3, 5, 7, 9]\nfor (let value of numeros) {\n    value += 1\n    console.log(value)\n}\n\nconsole.log(\"----------------------------------- (Ciclo while) ----------------------------------\")\nlet num = 1\nwhile (num <= 10) {\n    console.log(\"Número: \" + num)\n    num ++\n}\n\nconsole.log(\"----------------------------------- (Ciclo do-while) ----------------------------------\")\nlet contador = 1\ndo {\n    console.log(\"Nº: \" + contador);\n    contador ++\n} while (contador <= 10);\n\nconsole.log(\"------(◉◉∖____/◉◉)------ Excepciones-JavaScript ------(OO∖____/OO)------\")\nconsole.log(\"----------------------------------- (Excepción try-catch, finally) ----------------------------------\")\nlet VarUndefined\ntry {\n    console.log(VarUndefined.Hola_Yo_No_Estoy_Definido)\n} catch (error) {\n    console.log(\"Se ha producido un error dentro del catch:\", error.message)\n} finally {\n    console.log(\"Este código se ejecuta siempre\")\n}\n\nconsole.log(\"------(◉◉∖____/◉◉)------ Ejercio extra - JavaScript ------(OO∖____/OO)------\")\nconsole.log(`Creando un programa que imprima por consola todos los números empezando\ndel 10 al 55, pares, que no imprima el 16 ni múltiplos de 3.`)\nfunction ejercicio() {\n    for (let i = 10; i <= 55; i++) {\n        if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n            console.log(`N° ${i}`);\n        }\n    }\n}\nejercicio();\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/MiguelP-Dev.js",
    "content": "// 1. Operadores\n\n// Operadores Aritméticos\nlet suma = 5 + 5;\nlet resta = 5 - 5;\nlet multiplicacion = 5 * 5;\nlet division = 5 / 5;\nlet módulo = 5 % 5;\nlet potencia = 5 ** 6;\nconsole.log(\"suma; \" + suma);\nconsole.log(\"resta: \" + resta);\nconsole.log(\"multiplicacion: \" + multiplicacion);\nconsole.log(\"division: \" + division);\nconsole.log(\"módulo: \" + módulo);\nconsole.log(\"potencia: \" + potencia);\n\n// Operadores Lógicos\nlet and = true && true;\nlet or = true || false;\nlet not = !true;\nconsole.log(\"and: \" + and);\nconsole.log(\"or: \" + or);\nconsole.log(\"not: \" + not);\n\n// Operadores de Comparación\nlet igual = 5 == 5;\nlet diferente = 5 != 5;\nlet mayor = 5 > 5;\nlet menor = 5 < 5;\nlet mayorIgual = 5 >= 5;\nlet menorIgual = 5 <= 5;\nconsole.log(\"igual: \" + igual);\nconsole.log(\"diferente: \" + diferente);\nconsole.log(\"mayor: \" + mayor);\nconsole.log(\"menor: \" + menor);\nconsole.log(\"mayorIgual: \" + mayorIgual);\nconsole.log(\"menorIgual: \" + menorIgual);\n\n// Operadores de Asignación\nlet asignacion = 5;\nlet asignacionSuma = asignacion += 5;\nlet asignacionResta = asignacion -= 5;\nlet asignacionMultiplicacion = asignacion *= 5;\nlet asignacionDivision = asignacion /= 5;\nlet asignacionMódulo = asignacion %= 5;\nlet asignacionPotencia = asignacion **= 5;\nconsole.log(\"asignacion: \" + asignacion);\nconsole.log(\"asignacionSuma: \" + asignacionSuma);\nconsole.log(\"asignacionResta: \" + asignacionResta);\nconsole.log(\"asignacionMultiplicacion: \" + asignacionMultiplicacion);\nconsole.log(\"asignacionDivision: \" + asignacionDivision);\nconsole.log(\"asignacionMódulo: \" + asignacionMódulo);\nconsole.log(\"asignacionPotencia: \" + asignacionPotencia);\n\n// Operadores de Identidad\nlet igualDiferente = 5 == \"5\"; // true: solo compara el valor\nlet igualIdentidad = 5 === \"5\"; // false: compara tanto el valor como el tipo de dato\nlet diferenteIdentidad = 5 !== \"5\";\nconsole.log(\"igualIdentidad: \" + igualIdentidad);\nconsole.log(\"diferenteIdentidad: \" + diferenteIdentidad);\nconsole.log(\"igualDiferente: \" + igualDiferente);\n\n// Operadores de Pertenencia\nlet cadena = \"Hola Mundo\";\nlet pertenece = cadena.includes(\"Mundo\");\nconsole.log(\"pertenece: \" + pertenece);\nconsole.log(\"includes: \" + cadena.includes(\"Mundo\"));\n\n// Operadores de Bits\nlet bitAnd = 5 & 3;\nlet bitOr = 5 | 3;\nlet bitXor = 5 ^ 3;\nlet bitNot = ~5;\nlet bitLeftShift = 5 << 2;\nlet bitRightShift = 5 >> 2;\nlet bitUnsignedRightShift = 5 >>> 2;\nconsole.log(\"bitAnd: \" + bitAnd);\nconsole.log(\"bitOr: \" + bitOr);\nconsole.log(\"bitXor: \" + bitXor);\nconsole.log(\"bitNot: \" + bitNot);\nconsole.log(\"bitLeftShift: \" + bitLeftShift);\nconsole.log(\"bitRightShift: \" + bitRightShift);\nconsole.log(\"bitUnsignedRightShift: \" + bitUnsignedRightShift);\n\n// 2. Estructuras de control\n\n// 2.1 Condicionales: Estas estructuras de control permiten ejecutar un bloque de código\n// en función de la evaluación de una condición.\n\n// IF/ELSE: Usa if/else para condiciones simples o multiples caminos claros.\nlet condicion = true;\nif (condicion) {\n  console.log(\"Condición verdadera\");\n} else {\n  console.log(\"Condición falsa\");\n}\n\nlet numero = 10;\nif (numero > 0) {\n  console.log(\"El número es positivo\");\n} else if (numero < 0) {\n  console.log(\"El número es negativo\");\n} else {\n  console.log(\"El número es cero\");\n}\n\n// SWITCH: Usa switch para condiciones múltiples en una unica entidad con varios valores posibles.\n// siempre usar break para finalizar cada caso de un switch.\n// Usar default para cualquier valor no contemplado en los casos. \nlet color = \"red\";\nswitch(color) {\n    case \"red\":\n        console.log(\"El color es rojo\")\n        break\n    case \"blue\":\n        console.log(\"El color es azul\")\n        break\n    case \"green\":\n        console.log(\"El color es verde\")\n        break\n    default:\n        console.log(\"El color no es rojo, azul o verde\")\n        break\n}\n\n\n\n// 2.2 Iterativas: Estas estructuras de control permiten ejecutar un bloque de código\n// mientras se cumpla una condición.\n\n\n// Ciclo FOR: Se usa cuando se conoce el número de iteraciones que se van a realizar.\nfor (let i = 0; i < 5; i++) {\n    console.log(\"Iteración \" + i);\n}\n\n// Ciclo WHILE: Se usa cuando no se conoce el número de iteraciones que se van a realizar.\nlet contador = 0;\nwhile (contador < 5) {\n    console.log(\"Iteración \" + contador);\n    contador++;\n}\n\n// Ciclo DO WHILE: Se usa cuando se conoce el número de iteraciones que se van a realizar y es necesario ejecutar la iteracion al menos una vez.\nlet contador2 = 0;\ndo {\n    console.log(\"Iteración \" + contador2);\n    contador2++;\n} while (contador2 < 5);\n\n// 2.3 Excepciones: Estas estructuras de control permiten manejar errores en el código.\n\n// DIFICULTAD EXTRA (opcional):\n// Crea un programa que imprima por consola todos los números comprendidos\n// entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\nfor (let i = 10; i <= 55; i++) {\n    if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n        console.log(i)\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/N1sek.js",
    "content": "// OPERADORES ARITMÉTICOS\nconsole.log(\"Suma: \" + ( 3 + 4 )) // Suma -> 7\nconsole.log(\"Resta: \" + ( 3 - 4 )) // Resta -> -1\nconsole.log(\"División: \" + ( 3 / 4 )) // División -> 0.75\nconsole.log(\"Multiplicación: \" + ( 3 * 4 )) // Multiplicación -> 12\nconsole.log(\"Módulo: \" + ( 3 % 4 )) // Módulo -> 3\nconsole.log(\"Potencia: \" + ( 3 ** 4 )) // Potencia -> 81\n\n// OPERADORES LÓGICOS\nlet and = true && true // Devuelve true ya que ambas son verdaderas\nlet or = true || false // Devuelve true porque UNA es verdadera\nlet not = !true // Devuelve false\n\nconsole.log(\"AND: \" + and)\nconsole.log(\"OR: \" + or)\nconsole.log(\"NOT: \" + not)\n\n// OPERADORES DE COMPARACIÓN\nlet mayorQue = 5>2\nlet menorQue = 3<8\nlet mayorIgualQue = 6>=4\nlet menorIgualQue = 1<=12\n/* No es lo mismo == que ===, doble igual comprueba si el valor es el mismo \ny el triple igual comprueba si el valor y el tipo son lo mismo\n Ejemplo:\n\n let x = 5\n let y = \"5\"\n console.log(x == y) //Es true porque al convertirse la variable 'y' de texto a numero es 5\n\n console.log(x === y) //Es false porque la variable 'y' es tipo texto\n */\n\nlet igualQue = 2===2\nlet noEsIgual = 2!=3\n\n// OPERADORES DE ASIGNACIÓN\n\nlet asignacionAdicion = 5\nasignacionAdicion += 3\nconsole.log(\"Adicion: \" + asignacionAdicion)\n\nlet asignacionResta = 12\nasignacionResta -= 4\nconsole.log(\"Resta: \" + asignacionResta)\n\nlet asignacionMultiplicacion = 7\nasignacionMultiplicacion *= 2\nconsole.log(\"Multiplicación: \" + asignacionMultiplicacion)\n\nlet asignacionDivision = 7\nasignacionDivision /= 2\nconsole.log(\"División: \" + asignacionDivision)\n\nlet asignacionModulo = 7\nasignacionModulo %= 2\nconsole.log(\"Modulo: \" + asignacionModulo)\n\nlet asignacionExponencial = 2\nasignacionExponencial **= 3\nconsole.log(\"Exponencial: \" + asignacionExponencial)\n\nlet asignacionDesplazamientoIzquierda = 5\nasignacionDesplazamientoIzquierda <<= 1\nconsole.log(\"Desplazamiento a la izquierda: \" + asignacionDesplazamientoIzquierda)\n\nlet asignacionDesplazamientoDerecha = 5\nasignacionDesplazamientoDerecha >>= 1\nconsole.log(\"Desplazamiento a la derecha: \" + asignacionDesplazamientoDerecha)\n\nlet asignacionDesplazamientoDerechaSinSigno = -5\nasignacionDesplazamientoDerechaSinSigno >>>= 1\nconsole.log(\"Desplazamiento a la derecha sin signo: \" + asignacionDesplazamientoDerechaSinSigno)\n\nlet asignacionAndBit = 5\nasignacionAndBit &= 3\nconsole.log(\"AND bit a bit: \" + asignacionAndBit)\n\nlet asignacionXorBit = 5\nasignacionXorBit ^= 1\nconsole.log(\"XOR bit a bit: \" + asignacionXorBit)\n\nlet asignacionOrBit = 5\nasignacionOrBit |= 2\nconsole.log(\"OR bit a bit: \" + asignacionOrBit)\n\n// OPERADORES DE IDENTIDAD\nlet identidadEstricta = 5 === \"5\"\nlet desigualdadEstricta = 5 !== \"5\"\nconsole.log(\"Identidad estricta: \" + identidadEstricta)\nconsole.log(\"Desigualdad estricta: \" + desigualdadEstricta)\n\n// OPERADORES DE PERTENENCIA ARRAY\nlet array = [1, 2, 3, 4, 5]\nlet prueba1 = 3 in array\nlet prueba2 = 6 in array\nconsole.log(\"Pertenencia: \" + prueba1)\nconsole.log(\"No pertenencia: \" + prueba2)\n\n// OPERADORES DE BITS\nlet bitAnd = 5 & 3\nlet bitOr = 5 | 3\nlet bitXor = 5 ^ 3\nlet bitNot = ~5\nlet bitDesplazamientoIzquierda = 5 << 1\nlet bitDesplazamientoDerecha = 5 >> 1\nlet bitDesplazamientoDerechaSinSigno = -5 >>> 1\n\nconsole.log(\"AND bit a bit: \" + bitAnd)\nconsole.log(\"OR bit a bit: \" + bitOr)\nconsole.log(\"XOR bit a bit: \" + bitXor)\nconsole.log(\"NOT bit a bit: \" + bitNot)\nconsole.log(\"Desplazamiento a la izquierda: \" + bitDesplazamientoIzquierda)\nconsole.log(\"Desplazamiento a la derecha: \" + bitDesplazamientoDerecha)\nconsole.log(\"Desplazamiento a la derecha sin signo: \" + bitDesplazamientoDerechaSinSigno)\n\n// ESTUCTURAS DE CONTROL\n\n// IF-ELSE\nif (5 > 3) {\n    console.log(\"5 es mayor que 3\")\n} else {\n    console.log(\"5 no es mayor que 3\")\n}\n\n// SWITCH\nlet opt = 2\nswitch (opt) {\n    case 1:\n        console.log(\"Se ha seleccionado la opcion 1\")\n        break\n    case 2:\n        console.log(\"Se ha seleccionado la opcion 2\")\n        break\n    case 3:\n        console.log(\"Se ha seleccionado la opcion 3\")\n        break\n    case 4:\n        console.log(\"Se ha seleccionado la opcion 4\")\n        break\n    case 5:\n        console.log(\"Se ha seleccionado la opcion 5\")\n        break\n    default:\n        console.log(\"No es ninguno de los anteriores\")\n}\n\n// WHILE\nlet i = 0\nwhile (i < 5) {\n    console.log(\"While: \"+i)\n    i++\n}\n\n// DO-WHILE\nlet j = 0\ndo {\n    console.log(\"DO-WHILE: \"+j)\n    j++\n}while (j < 5)\n\n// FOR\nfor (let k = 0; k < 5; k++) {\n    console.log(\"FOR: \"+k)\n}\n\n// FOR-IN\nconst automovil = {\n    marca: 'Toyota',\n    modelo: 'GR YARIS',\n    anio: 2021,\n    color: 'Blanco'\n};\n\nfor (const propiedad in automovil) {\n    console.log(propiedad + \": \" + automovil[propiedad]);\n}\n\n// FOR-OF\nconst colores = ['Rojo', 'Azul', 'Verde', 'Amarillo'];\n\nfor (const color of colores) {\n    console.log(color);\n}\n\n// TRY-CATCH-FINALLY\ntry {\n    if(5>3){\n        throw new Error(\"Esto es una excepción\")\n    }\n    console.log(\"No se ha lanzado la excepción\") // Si se lanza la excepción, esta parte no se ejecutará.\n}catch (error) {\n    console.log(error.message)\n}finally { // Esta parte se puede omitir, el finally no es obligatorio. Aqui se puede poner codigo que se ejecutara siempre haya o no excepción\n    console.log(\"Fin del bloque try-catch-finally. Esto se ejecuta siempre\")\n}\n\n// EJERCICIO EXTRA\nfor(let i = 10; i<55; i++){\n    if(i % 2 == 0 && i != 16 && i % 3 != 0){\n        console.log(i)\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/NathaliaMF.js",
    "content": "\nlet a=9\nlet b=12\n\n\nconsole.log(`Operadores Aritmeticos`);\nconsole.log(`La suma de ${a} + ${b} es igual a ${a+b}`);\nconsole.log(`La resta de ${b} - ${a} es igual a ${b-a}`);\nconsole.log(`La multiplicacion de ${b} * ${a} es igual a ${b*a}`);\nconsole.log(`La division de ${b} / ${b} es igual a ${b/b}`);\nconsole.log(`Operadores de Asignacion`);\nconsole.log(`La asignacion de adicion es ${b +=a}`);\nconsole.log(`La asignacion de resta es ${b -=a}`);\nconsole.log(`La asignacion de multiplicacion es ${b *=a}`);\nconsole.log(`La asignacion de division es ${b /=a}`);\nconsole.log(`Operadores de comparacion`);\nconsole.log(`El resultado de si ${b} es igual a ${b} es  ${b===b}`);\nconsole.log(`El resultado de si ${b} es diferente de ${b} es  ${b!=b}`);\nconsole.log(`El resultado de si ${b} es menor o igual${a} es  ${b<=a}`);\nconsole.log(`El resultado de si ${b} es mayor o igual ${a} es  ${b>=a}`);\nconsole.log(`Operadores logicos bit a bit`);\nconsole.log(`La operacion AND binaria de ${a} y ${b} es  ${a & b}`);\nconsole.log(`La operacion OR binaria de ${a} y ${b} es  ${a | b}`);\nconsole.log(`La operacion XOR binaria de ${a} y ${b} es  ${a ^ b}`);\nconsole.log(`Estructuras de control`);\n/**Estructura condicional if else */\nif (a<=b) {\n    console.log(`El valor ${a} es menor o igual a ${b} `);\n    \n} else {\n    console.log(`El valor ${b} es menor o igual a ${a} `);\n\n}\n/**Estructura condicional switch */\nswitch (b>a) {\n    case true:\n        console.log(`El valor ${b} es mayor que ${a} `);\n\n        break;\n    \n\n    default:\n        console.log(`El valor ${a} es menor o igual a ${b} `);\n\n        break;\n}\n/**Estructura condicional for */\nfor (let i=10 ; i>=0; i--) {\n    console.log(`El valor de i es ${i} `);\n\n}\n/**Estructura condicional while */\nlet j = 0;\nwhile (j<9) { \nalert (j); \nj++;\nconsole.log(`El valor de j es ${j} `);\n\n}\n/**Estructura condicional try catch */\n\nfunction doSomething() {\n    throw new Error('something terrible happened');\n  }\n  try {\n    doSomething();\n  } catch (e) {\n    console.log(e); // Logs the error\n  }\n\nconsole.log('Los numeros comprendidos entre 10 y 55: ');\n\nfor (let k =10; k<=55; k++) {\n    if ( (k!==16 && !(k%3 ===0 ) && k%2 === 0 ) || k===55) {\n        console.log(k);\n\n    }\n    \n}\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/NightAlchemist.js",
    "content": "//Operadores de asignación\n//Asignacion\nconsole.log('//Operadores de asignación');\n   const x = 'asignacion';\n   console.log(\"Resultado de la asignacionde. Operacion -> (x = 'asignacion'):\"+ x);\n// Asignacion de Adicion\n    let y = 0;\n    y += 2;\n    console.log(\"Resultado de la asignacionde de adicion, Operqacion -> (y += 2):\"+ y);\n    //Asignacion de resta\n    let e = 0;\n    e -= 4;\n    console.log('Resultado de la asignacionde Resto. Operacion -> (e -= 4):'+ e);\n\n//Operadores con Desestructuración\n//Sin desestructuracion\n let comida = ['pera','manzana','azucar'];\n //Con desestructuracion\n let [pera,manzana,azucar] = comida;\n \n console.log(`let comida = ['pera','manzana','azucar']; \n    //Sin desestructuracion\n    La comida[0]=${comida[0]}\n    La comida[1]=${comida[1]}\n    La modida[2]=${comida[2]}\n\n    //Con desestructuracion\n    let [pera,manzana,azucar] = comida;\n    La comida en la posicion 0 es: ${pera};\n    La comida en la posicion 1 es: ${manzana};\n `);\n\n //Operadores de comparación\n let var1 = 1;\n let var2 = 3;\n console.log('Operadores de comparación');\n \n console.log(` \n let var1 = 1;\n let var2 = 3;\n var1 == 1:${var1 == 1};\n var2 != 3:${var2 != 3};\n var1 >= 2:${var1 >= 2};\n var1 <= 2:${var1 <= 2};\n `)\n \n\n\n//Operadores aritmeticos\nconsole.log('Operadores aritmeticos');\nlet suma = 2 + 4;\nconsole.log(`La suma  de 2 + 4 es:${suma}`);\n\n let resta= 2-1;\nconsole.log(`La resta de 2-1 es:${resta}`);\n\nlet multiplicacion = 2*5;\nconsole.log(`La multiplicacion de 2*5 es:${multiplicacion}`);\n\nlet divicion = 10 / 2;\nconsole.log(`La divicion de 10/2 es:${divicion}`);\n\nlet residuo = 12 / 5;\nconsole.log(`El residuo de 12/5 es:${residuo}`);\n\n\n//Operadores lógicos\nconsole.log('Operadores lógicos');\nlet num1 = true;\nlet num2 = false;\nconsole.log(`\nlet num1 = true;\nlet num2 = false;\n console.log(num1 && num2); // Se espera un false ->: ${(num1 && num2)}\n console.log(num1 || num2);// Se espera un true ->: ${(num1 || num2)} \n console.log(!num1);// Se espera un false ->: ${(!num1)}\n `);\n\n //Estructura de Control\n //Condicional if\n console.log(\"//Estructura de Control\");\n console.log(\" //Condicional if\");\n let auto = 'fiat'\nif( auto == 'ford'){\n    console.log(`Mi aunto es un:${auto}`);\n}else if(auto == 'fiat'){\n    console.log(`Mi aunto es un:${auto}`);\n}else{\n    console.log('No es ni uno u otro');\n}\n//operador ternario\nconsole.log(\"//operador ternario\");\nauto === \"ford\"? console.log(`Mi auto es un: ${auto}`): console.log(\"Tu auto no es Ford\");\n\n//switch\nconsole.log(\"//Switch case\");\nlet piso = 5;\nconsole.log(\"Quiero ir a mi apartamento que esta en el piso:\"+piso);\n\nswitch (piso){\n  case 10:\n    calificacion = \"PenHouse\";\n    break;\n    case 8:\n    calificacion = \"No es tu piso\";\n    break;\n  case 7:\n  case 5:\n    calificacion = \"Llegamos a tu Piso:\"+piso+\", por favor bajase aquí\";\n    break;\n  case 5:\n  case 4:\n  case 3:\n  case 2:\n  case 1:\n  case 0:\n    calificacion = \"Pisos bajos\";\n    break;\n  default:\n    // Cualquier otro caso\n    calificacion = \"Emergencia se ha ido la electricidad\";\n    break;\n}\nconsole.log(calificacion);\n\n//Esctructura de Control\n//While\nconsole.log(\"//Esctructura de Control - While\");\nlet numero = 0;\nwhile(numero <= 4){\n  console.log(\"El numero actual es:\"+numero);\n  numero +=1;\n}\n//Do While\nconsole.log(\"Do-While\");\ndo{\n  console.log(\"Me ejecute con el Do While aun y que la condicion no sea True\")\n  numero += 2;\n}\nwhile(numero < 0);\n\n//For\nconsole.log(\"Bucle For\")\nfor(let i = 20;i > 9; --i){\n  console.log(`Soy for en:${i}`);\n}\n\nfor (let i = 0; i < 11; i++) {\n  if (i == 5) {\n    continue; // Para saltar en esta condicion\n  }\n  console.log(\"Valor de i:\", i);\n}\n\n\n//Dificultad Extra\nconsole.log(\"Dificultad Extra\");\nfor (let a = 55; a >= 10; a--){\n  if(a%2 == 0 && a != 16 && a%3 !=0){\n    console.log(a);\n  }  \n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/Nightblockchain30.js",
    "content": "// Operadores aritméticos\nlet suma = 5 + 3;\nlet resta = 6 - 2;\nlet division = 10 / 2;\nlet multiplicacion = 7 * 8;\nlet resto = 15 % 2;\n\n// Operadores de asignacion\nlet x = 1;\nx = x + 4; // adición x=5\nx = x - 2; // sustración x=3\nx = x * 3; // multiplicacion x=9\nx = x / 3; // division x=3\nx = x % 2; // resto x=1\n\n// pre incremento\nlet a = 4;\nlet b = ++a * 2;\nconsole.log(b); // Imprime 10 y establece a=5\n// post incremento\nlet c = 4;\nlet d = c++ * 2;\nconsole.log(d); // Imprime 8 y establece c=5\n// pre decremento\nlet e = 5;\nlet f = --e * 2;\nconsole.log(f); // Imprime 8 y establece e=4\n// post decremento\nlet g = 5;\nlet h = g-- * 2;\nconsole.log(h); // Imprime 10 y establece g=4\n\n// Operadores de comparacion\nlet num1 = 5;\nlet num2 = 2;\nlet bool1 = num1 > num2; // bool1 = true\nlet bool2 = num1 < num2; // bool2 = false\nlet bool3 = num1 <= num2; // bool3 = flase\nlet bool4 = num1 >= num2; // bool3 = false\nlet bool5 = num1 === num2; // bool5 = false\nlet bool6 = num1 !== num2; // bool6 = true\n\n// Operadores logicos\n//AND\nlet and1 = true && true; // log1 = true\nlet and2 = true && false; // log2 = false\nlet and3 = false && true; // log3 = false\n//OR\nlet or1 = true || true; // or1 = true\nlet or2 = true || false; // or2 = true\nlet or3 = false || true; // or3 = true\nlet or4 = false || false; // or3 = false\n\n// Operadores de Negacion\nlet verdadero = true;\nlet falso = false;\nconsole.log(!verdadero); // Imprime false\nconsole.log(!falso); // Imprime true\nconsole.log(!!verdadero); // Imprime true\n\n// Operadores de identidad o igualdad\nlet igual1 = 2 === 2; // igual1 = true\nlet igual2 = 2 === \"2\"; // igual2 = false\nlet igual3 = 2 !== 2; // igual3 = false\nlet igual4 = 2 !== 3; // igual4 = true\n\n// Operador typeof\nlet type1 = 5;\nlet type2 = \"alejandro\";\nlet type3 = true;\nlet type4 = undefined;\nconsole.log(typeof type1); // Imprime \"number\"\nconsole.log(typeof type2); // Imprime \"string\"\nconsole.log(typeof type3); // Imprime \"boolean\"\nconsole.log(typeof type4); // Imprime \"undefined\"\n\n// Operador de concatenacion\nlet cad1 = \"Hola\";\nlet cad2 = \"JavaScript\";\nconsole.log(cad1 + \" \" + cad2); // Imprime \"Hola JavaScript\"\n\n// Estructuras de control\n\n// if...else\nlet nota = 8;\nif (nota >= 6) {\n  console.log(\"materia apobada con \" + nota);\n} else {\n  console.log(\"desaprobó con un \" + nota);\n}\n\n// Switch\nlet numeroMes = 3;\nswitch (numeroMes) {\n  case 1:\n    console.log(\"Enero\");\n    break;\n  case 2:\n    console.log(\"Febrero\");\n    break;\n  case 3:\n    console.log(\"Marzo\");\n    break;\n  case 4:\n    console.log(\"Abril\");\n    break;\n  case 5:\n    console.log(\"Mayo\");\n    break;\n  case 6:\n    console.log(\"Junio\");\n    break;\n  case 7:\n    console.log(\"Julio\");\n    break;\n  case 8:\n    console.log(\"Agosto\");\n    break;\n  case 9:\n    console.log(\"Septiembre\");\n    break;\n  case 10:\n    console.log(\"Octubre\");\n    break;\n  case 11:\n    console.log(\"Noviembre\");\n    break;\n  case 12:\n    console.log(\"Diciembre\");\n    break;\n  default:\n    console.log(\"el numero ingresado no corresponde a un mes\");\n}\n\n// For\nfor (let x = 0; x < 5; x++) {\n  console.log(x + 1); // 1,2,3,4,5\n}\n\n// ForEach\nlet numeros = [0, 1, 2, 3, 4, 5];\nnumeros.forEach(function (numero) {\n  console.log(numero);\n});\n\n// While\nlet contador = 1;\nwhile (contador <= 5) {\n  console.log(contador); // 1,2,3,4,5\n  contador++;\n}\n\n// Do While\nlet cuentaRegresiva = 5;\ndo {\n  console.log(cuentaRegresiva); // 5,4,3,2,1\n  cuentaRegresiva--;\n} while (cuentaRegresiva !== 0);\n\n/*\n    DIFICULTAD EXTRA:\n    Crea un programa que imprima por consola todos los números comprendidos\n    entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3\n*/\n\nfor (let i = 10; i <= 55; i++) {\n  if (i % 2 == 0 && i !== 16) {\n    if (i % 3 !== 0) {\n      console.log(i);\n    }\n  }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/OmarLand.js",
    "content": "// #01 - OPERADORES Y ESTRUCTURAS DE CONTROL\n/*\n    * EJERCICIO:\n    * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n    *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n    *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n    * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n    *   que representen todos los tipos de estructuras de control que existan\n    *   en tu lenguaje:\n    *   Condicionales, iterativas, excepciones...\n    * - Debes hacer print por consola del resultado de todos los ejemplos.\n*/\n\n// Inicialización de variables:\nlet numA = 10;\nlet numB = 5;\nlet x = 1;\nlet result;\n\n// Operadores aritméticos:\nconsole.log(\"Suma: numA + numB \",  numA + numB  );\nconsole.log(\"Resta: numA - numB\", numA - numB  );\nconsole.log(\"Multiplicación: numA * numB \", numA * numB  );\nconsole.log(\"Divisón: numA / numB\", numA / numB  );\nconsole.log(\"Módulo: numA % numB\",  numA % numB  );\nconsole.log(\"Autoincrementable: result = x++: (Comunmente lo usamos con un for/while)\", x = x++);\nconsole.log(\"Autoincrementable: result = ++x:\", x = ++x);\n\n// Operadores Lógicos:\nlet isActive    = true;\nlet isNotActive = false;\n\n// Operadores and(&&) y or(||)\nconsole.log(\"Operador AND (&&): isActive && isNotActive\", isActive && isNotActive);\nconsole.log(\"Operador OR (||): isActive || isNotActive\",  isActive || isNotActive);\n\n// Operadores de comparación:\nconsole.log( \"Mayor que: 5 > 1\", 5 > 1 );\nconsole.log( \"Menor que: 10 < 35\", 10 < 35 );\nconsole.log( \"Mayor o igual que: 10 >= 10\", 10 >= 10 );\nconsole.log( \"Menor o igual que: 10 <= 35\", 10 <= 35 );\n\n// Operadores de asignación o identidad:\n let nombre = \"Omar\" // Asignación e identidad\n\n console.log(\"Comparación o igualdad estricta: 5 === 5\", 5 === 5);\n console.log(\"Comparación o igualdad estricta: 5 === 4\", 5 === 4);\n console.log(\"Comparación o desigualdad estricta: 5 !== 4\", 5 !== 5);\n console.log(\"Comparación o desigualdad estricta: 5 !== 4\", 5 !== 4);\n\n// Estructuras condicionales simple y doble:\n// Simple\nlet edadA = 15;\nlet edadB = 18;\n\nif(edadA < 18){\n    console.log(\"Estructura condicional Simple\");\n    console.log(\"Eres menor de edad\");\n}\n\n// Condicional Doble:\nif( edadB > 18 ){\n    console.log(\"Estructura condicional Doble\");\n    console.log(\"Es menor de edad\");\n} else {\n    console.log(\"Estructura condicional Doble\");\n    console.log( \"Es Mayor de edad\");\n}\n\n// Condicional multiple ( Switch )\nlet opcion = 1;\nswitch (opcion) {\n    case 1:\n        console.log(\"Has elegido la opción 1\");\n        break;\n    case 2:\n        console.log(\"Has elegido la opción 2\");\n        break;\n    case 3:\n        console.log(\"Has elegido la opción 3\");\n        break;\n    default:\n        console.log(\"No ha seleccionado una opción válida\");;\n}\n\n// Estructuras iterativas:\n// for\nlet repetir = 5;\nfor( let i = 0; i <= repetir; i++ ){\n    console.log(\"Repitiendo FOR desde: i = 0\", i);\n}\n\n// While y manejo de excepciones\ntry {\n    while (repetir <= 10) {\n        console.log(\"Recorriendo While: \", +repetir);\n        repetir++;\n    }       \n} catch (error) {\n    console.warn(error);\n}\n\n/*\n    *\n    * DIFICULTAD EXTRA (opcional):\n    * Crea un programa que imprima por consola todos los números comprendidos\n    * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n    *\n*/\n\ntry {\n    let numeros = 100;\n    console.log(\"### ¡DIFICULTAD EXTRA! ###\");\n    for(let i=0; i<=numeros; i++){\n        if( i >= 10 && i <= 55 ){\n            if( i % 2 === 0 && i !== 16 && i % 3 !== 0){\n                console.log(\">>>: \", i);\n            }\n        }\n    }\n} catch (error) {\n    console.warn( error );\n}\n\n// Aprobado por Chayanne! xD"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/Pancratzia.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n * LAURA ORTEGA - 02/01/2024\n */\n\n/***************************************************************************/\n/* 1-OPERADORES DEL LENGUAJE */\n\nconsole.log('OPERADORES DE ASIGNACIÓN');\nconsole.log('Para asignar un valor a una variable, se utiliza el signo de igual (=)');\nlet numero = 10; //Asignación\n\nnumero +=2; //Asignación de adición\nconsole.log('Existe la asignación de adición, donde se suma el valor de una variable con otro. El signo utilizado es (+=). Por ejemplo, si el valor de la variable es 10, el resultado de (10+2) es ' + numero);\n\nnumero-=2; //Asignación de resta\nconsole.log('Opuesto a ella está la asignación de resta, donde se resta el valor de una variable con otro. El signo utilizado es (-=). Por ejemplo, si el valor de la variable es 12, el resultado de (12-2) es ' + numero);\n\nnumero*=3; //Asignación de multiplicación\nconsole.log('Tenemos también la asignación de multiplicación, donde se multiplica el valor de una variable con otro. El signo utilizado es (*=). Por ejemplo, si el valor de la variable es 10, el resultado de (10*3) es ' + numero);\n\nnumero/=3; //Asignación de división\nconsole.log('Y  asignación de división, donde se divide el valor de una variable con otro. El signo utilizado es (/=). Por ejemplo, si el valor de la variable es 30, el resultado de (30/3) es ' + numero);\nlet resto = numero;\n\nresto %=3; //Asignación de residuo\nconsole.log('Contamos además con la asignación de residuo (o resto), donde se obtiene el residuo de una división. El signo utilizado es (%=). Por ejemplo, si el valor de la variable es 30, el resultado de (30%3) es ' + resto);\n\nnumero**=2; //Asignación de potencia\nconsole.log('La asignación de potencia, donde se obtiene la potencia de un número. El signo utilizado es (**=). Por ejemplo, si el valor de la variable es 10, el resultado de (10**2) es ' + numero);\n\nnumero = 10;\nnumero>>=2; //Asignación de desplazamiento a la derecha - 10/(2*2) = 2  \nconsole.log('La asignación de desplazamiento, donde se desplaza un número. El signo utilizado es (>>=). Esto equevale a dividir por 2^n. Por ejemplo, si el valor de la variable es 10, el resultado de (10>>2) es ' + numero);\n\nnumero = 10;\n\nnumero<<=2; //Asignación de desplazamiento a la izquierda - 10*(2*2) = 40\nconsole.log('Funciona igual que la anterior, pero se desplaza a la izquierda. El signo utilizado es (<<=). Esto equevale a multiplicar por 2^n. Por ejemplo, si el valor de la variable es 10, el resultado de (10<<2) es ' + numero);\n\nnumero = 10;\n\nnumero >>>=2; //Asignación de desplazamiento a la derecha sin signo - 10/(2*2) = 2\n\nconsole.log('Igual a la anterior, pero sin mantener el signo. El signo utilizado es (>>>=). Esto equevale a dividir por 2^n. Por ejemplo, si el valor de la variable es 10, el resultado de (10>>>2) es ' + numero);\n\nnumero = 1;\n\nnumero&='soy un string'; //Asignación de AND\nconsole.log(\"AND: \"+numero); // El operador AND bit a bit compara cada bit de su primer operando con el bit correspondiente de su segundo operando. Si ambos bits son 1, el bit del resultado correspondiente se establece en 1. De lo contrario, el bit del resultado correspondiente se establece en 0.\n\nnumero = 1;\n\nnumero^=1; //Asignación de XOR\nconsole.log(\"XOR: \"+numero); //El operador XOR compara los bits de ambos operandos. Si ambos bits son iguales, el bit del resultado es 0. Si uno de los dos bits es 1, el bit del resultado es 1.\n\nnumero = 1;\n\nnumero |= 1; //Asignación de OR\nconsole.log(\"OR: \"+numero); //El operador OR compara los bits de ambos operandos. Si ambos bits son 0, el bit del resultado es 0. Si uno de los dos bits es 1, el bit del resultado es 1.\n\nnumero = 1;\n\nnumero &&= '1';\nconsole.log(\"AND: \"+numero); //El operador AND compara los bits de ambos operandos. Si ambos bits son 1, el bit del resultado es 1. Si uno de los dos bits es 0, el bit del resultado es 0.\n\nnumero = 1;\n\nnumero ||= '1'; //Asignación de OR\nconsole.log(\"OR: \"+numero); //El operador OR compara los bits de ambos operandos. Si ambos bits son 0, el bit del resultado es 0. Si uno de los dos bits es 1, el bit del resultado es 1.\n\n\nnumero = 1;\n\nnumero ??= '1'; //Asignación de OR\nconsole.log(\"OR: \"+numero); //El operador OR compara los bits de ambos operandos. Si ambos bits son 0, el bit del resultado es 0. Si uno de los dos bits es 1, el bit del resultado es 1.\n\nconsole.log('OPERADORES DE COMPARACIÓN');\n\nconsole.log('El operador de igualdad (==) compara el valor de dos operandos. El signo utilizado es (==). Por ejemplo, si el valor de la variable es 10, el resultado de (10==10) es ' + (10==10));\nconsole.log('El operador de desigualdad (!=) compara el valor de dos operandos. El signo utilizado es (!=). Por ejemplo, si el valor de la variable es 10, el resultado de (10!=10) es ' + (10!=10));\nconsole.log('El operador de igualdad estricta (===) compara el valor y el tipo de dos operandos. El signo utilizado es (===). Por ejemplo, si el valor de la variable es 10, el resultado de (10===10) es ' + (10===10) + ' y (10===\"10\") es ' + (10===\"10\"));\nconsole.log('El operador de desigualdad estricta (!==) devuelve true si los operandos son del mismo tipo pero no iguales, o son de diferente tipo. El signo utilizado es (!==). Por ejemplo, si el valor de la variable es 10, el resultado de (10!==10) es ' + (10!==10) + ' y (10!==\"10\") es ' + (10!==\"10\"));\nconsole.log('El operador de mayor que (>) compara el valor de dos operandos. El signo utilizado es (>). Por ejemplo, si el valor de la variable es 10, el resultado de (10>10) es ' + (10>10));\nconsole.log('El operador de menor que (<) compara el valor de dos operandos. El signo utilizado es (<). Por ejemplo, si el valor de la variable es 10, el resultado de (10<10) es ' + (10<10));\nconsole.log('El operador de mayor o igual que (>=) compara el valor de dos operandos. El signo utilizado es (>=). Por ejemplo, si el valor de la variable es 10, el resultado de (10>=10) es ' + (10>=10));\nconsole.log('El operador de menor o igual que (<=) compara el valor de dos operandos. El signo utilizado es (<=). Por ejemplo, si el valor de la variable es 10, el resultado de (10<=10) es ' + (10<=10));\n\nconsole.log('OPERADORES ARITMETICOS');\n\nconsole.log('El operador de suma (+) compara el valor de dos operandos. El signo utilizado es (+). Por ejemplo, si el valor de la variable es 10, el resultado de (10+10) es ' + (10+10));\nconsole.log('El operador de resta (-) compara el valor de dos operandos. El signo utilizado es (-). Por ejemplo, si el valor de la variable es 10, el resultado de (10-10) es ' + (10-10));\nconsole.log('El operador de multiplicación (*) compara el valor de dos operandos. El signo utilizado es (*). Por ejemplo, si el valor de la variable es 10, el resultado de (10*10) es ' + (10*10));\nconsole.log('El operador de división (/) compara el valor de dos operandos. El signo utilizado es (/). Por ejemplo, si el valor de la variable es 10, el resultado de (10/10) es ' + (10/10));\nconsole.log('El operador de residuo (%) compara el valor de dos operandos. El signo utilizado es (%). Por ejemplo, si el valor de la variable es 10, el resultado de (10%10) es ' + (10%10));\nconsole.log('El operador de potencia (**) compara el valor de dos operandos. El signo utilizado es (**). Por ejemplo, si el valor de la variable es 10, el resultado de (10**10) es ' + (10**10));\n\nnumero = 10;\nnumero++;\nconsole.log('El operador de incremento (++). El signo utilizado es (++). Por ejemplo, si el valor de la variable es 10, el resultado de (++10) es ' + numero);\n\nnumero = 10;\nnumero--;\nconsole.log('El operador de decremento (--). El signo utilizado es (--). Por ejemplo, si el valor de la variable es 10, el resultado de (--10) es ' + numero);\n\nconsole.log('El operador de negación unitaria (~). El signo utilizado es (~). Por ejemplo, si el valor de la variable es 10, el resultado de (~10) es ' + (~10));\nconsole.log('El operador de negación unaria (!). El signo utilizado es (!). Por ejemplo, si el valor de la variable es 10, el resultado de (!10) es ' + (!10));\n\n\nconsole.log('OPERADORES LÓGICOS');\n\nconsole.log('El operador de conjuncio (&&) compara el valor de dos operandos. El signo utilizado es (&&). Por ejemplo, si el valor de la variable es 10, el resultado de (10&&10) es ' + (10&&10));\nconsole.log('El operador de disyuncio (||) compara el valor de dos operandos. El signo utilizado es (||). Por ejemplo, si el valor de la variable es 10, el resultado de (10||10) es ' + (10||10));\nconsole.log('El operador de XOR (XOR) compara el valor de dos operandos. El signo utilizado es (XOR). Por ejemplo, si el valor de la variable es 10, el resultado de (10^10) es ' + (10^10));\nconsole.log('El operador de NOT lógico (!) compara el valor de dos operandos. El signo utilizado es (!). Por ejemplo, si el valor de la variable es 10, el resultado de (!10) es ' + (!10));\n\n/**Por la extensa cantidad de operadores, se anexa el link para leer más sobre ellos: https://developer.mozilla.org/es/docs/Web/JavaScript/Guide/Expressions_and_Operators**/\n/***************************************************************************/\n/* 2-ESTRUCTURAS DE CONTROL */\n\nlet index = 1;\n\nwhile(index <= 10) { //Ciclo while. Puede no ser ejecutado.\n    console.log(index);\n    index++;\n}\n\ndo{ //Ciclo do while. Se ejecuta al menos una vez.\n    index--;\n    console.log(index);\n}while(index > 1);\n\nconst edad = 19;\n\nif(edad <18){ // If. Revisa las condiciones\n    console.log(\"No eres mayor de edad\");\n}else{ // Else. Si no se cumple la condición del if, se ejecuta\n    console.log(\"Eres mayor de edad\");\n}\n\nconst opcion = 2;\n\nswitch(opcion){ // Switch. Revisa las opciones y ejecuta la correspondiente al caso\n    case 1:\n        console.log(\"Opcion 1\");\n        break;\n    case 2:\n        console.log(\"Opcion 2\");\n        break;\n    case 3:\n        console.log(\"Opcion 3\");\n        break;\n    default:\n        console.log(\"Opcion no encontrada\");\n        break;\n}\n\nfor(let i = 1; i <= 10; i++){ // For. Se ejecuta hasta que no se cumpla la condición\n    console.log(i);\n}\nconst constante = 10;\ntry{ // Try. Intenta ejecutar el bloque de código\n    constante = 20;\n}catch(error){ // Catch. Se ejecuta si hay un error sin interrupir la ejecución del programa\n    console.log(error);\n}\n\n\n/***************************************************************************/\n/* 3-EXTRA */\n\n/*Crea un programa que imprima por consola todos los números comprendidos entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.*/\n\nlet n = 10;\n\nwhile(n <= 55){\n    if(n!==16 && (n%3!==0 && n%2===0)){\n        console.log(n);\n    }\n    n++;\n}\n\n/***************************************************************************/"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/Pogo182028.js",
    "content": "let a = 5;\nlet b = 4;\nlet resultadoA;\n// Operadores aritméticos\nresultado = a + b;\nconsole.log(resultado);\n\nresultado = a - b;\nconsole.log(resultado);\n\nresultado = a * b;\nconsole.log(resultado);\n\nresultado = a / b;\nconsole.log(resultado);\n\nresultado = a % b; // Módulo\nconsole.log(resultado);\n\nresultado = a ** b; // Exponente\nconsole.log(resultado);\n\nb++; // Incremento\nconsole.log(b);\n\nb--; // Decremento\nconsole.log(b);\n\n// Operadores lógicos\nlet t = true,\n  f = false;\nlet resultadoL;\nresultadoL = t && f; // false\nconsole.log(resultadoL);\n\nresultadoL = t || f; // true\nconsole.log(resultadoL);\n\nresultadoL = !t; // false\nconsole.log(resultadoL);\n\n// Operadores de comparación\nlet n1,\n  n2 = 0;\nn1 = n2; // 0\nconsole.log(n1);\n\nn1 += n2; // 0\nconsole.log(n1);\n\nn1 -= n2; // 0\nconsole.log(n1);\n\nn1 /= n2; // 0\nconsole.log(n1);\n\nn1 %= n2; // 0\nconsole.log(n1);\n\nn1 **= n2; // 1\nconsole.log(n1);\n\n// Operadores de identidad\nlet x = 5,\n  y = 6;\nlet resultadoI;\nresultadoI = a === b; // identidad estricta\nconsole.log(resultadoI);\n\nresultadoI = a !== b; // no identidad estricta\nconsole.log(resultadoI);\n\n// Operadores de pertenencia\nlet z = 4,\n  w = [1, 2, 6, 3, 5, 4, 10];\nlet resultadoP;\nresultadoP = z in w; // Verifica si una propiedad existe en un objeto\nconsole.log(resultadoP);\n\nfunction persona(nombre, edad) {\n  this.nombre = nombre;\n  this.edad = edad;\n}\nlet niño = new persona(\"Juan\", 10);\nconsole.log(niño instanceof persona); // Verifica si un objeto es instancia de otro\n\n// Operadores de bit a bit\nlet b1 = 5,\n  b2 = 3; // 5 (00000101) ; 3 (00000011)\nlet resultadoB;\nresultadoB = b1 & b2; // 1 (00000001)\nconsole.log(resultadoB);\n\nresultadoB = b1 | b2; // 7 (00000111)\nconsole.log(resultadoB);\n\nresultadoB = b1 ^ b2; // 6 (00000110)\nconsole.log(resultadoB);\n\nresultadoB = ~b1; // -6 (11111010)\nconsole.log(resultadoB);\n\nresultadoB = b1 << 2; // 20 (00010100)\nconsole.log(resultadoB);\n\nresultadoB = 20 >> 2; // 5 (00000101)\nconsole.log(resultadoB);\n\nresultadoB = -20 >>> 2; // 1073741823 (01111111 11111111 11111111 11111011)\nconsole.log(resultadoB);\n\n// Condicionales\nlet edad = 19;\nif (edad >= 18) {\n  console.log(\"Usted es mayor de edad\");\n} else {\n  console.log(\"Usted no es mayor de edad\");\n}\n\nlet dia = \"viernes\";\nswitch (dia) {\n  case \"lunes\":\n    console.log(\"Hoy es lunes\");\n  case \"martes\":\n    console.log(\"Hoy es martes\");\n  default:\n    console.log(\"Hoy no es lunes ni martes\");\n}\n\n// Iterativas\nlet i = 0;\nwhile (i <= 3) {\n  console.log(i);\n  i++;\n}\n\ni = 1;\ndo {\n  console.log(i);\n  i += 2;\n} while (i <= 7);\n\nfor (let i = 2; i <= 8; i += 2) {\n  console.log(i);\n}\n\nlet objeto = { a: 12, b: 14, c: 16 };\nfor (let propiedad in objeto) {\n  // for-in\n  console.log(objeto[propiedad]);\n}\n\nlet arreglo = [11, 12, 13, 14, 15];\nfor (let elemento of arreglo) {\n  // for-of\n  console.log(elemento);\n}\n\ntry {\n  // Código que puede generar un error\n  let nro = null;\n  nro.length();\n} catch (error) {\n  // Código que se ejecuta si se produce un error\n  console.log(\"Error\");\n} finally {\n  // Código que se ejecuta siempre\n  console.log(\"Ejecución finalizada\");\n}\n\n// Ejercicio Extra\nfor (let i = 10; i <= 55; i += 2) {\n  if (i % 16 !== 0 && i % 3 !== 0) {\n    console.log(i);\n  }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/RaquelTejada.js",
    "content": "// Operadores de asignación\nlet x = 10; // Asignación\nx += 5; // Suma y asignación\nx -= 5; // Resta y asignación\nx *= 5; // Multiplicación y asignación\nx /= 5; // División y asignación\nx %= 5; // Módulo y asignación\n\n// Operadores aritméticos\nlet y = 2; // Asignación\nconst sum = x + y; // Suma\nconst rest = x - y; // Resta\nconst multi = x * y; // Multiplicación\nconst division = x / y; // División\nconst module = x % y; // Módulo\nconst exponent = x ** y; // Exponente\n\nconsole.log(\"console log Raquel ~ sum:\", sum);\nconsole.log(\"console log Raquel ~ rest:\", rest);\nconsole.log(\"console log Raquel ~ multi:\", multi);\nconsole.log(\"console log Raquel ~ division:\", division);\nconsole.log(\"console log Raquel ~ module:\", module);\nconsole.log(\"console log Raquel ~ exponent:\", exponent);\n\n// Operadores de comparación\nconst equals = x == y; // Igual\nconst notEquals = x !== y; // Desigual\nconst extrictEqual = x === y; // Igual estricto\nconst extrictNotEqual = x !== y; // Desigual estricto\nconst greaterThan = x > y; // Mayor qué\nconst greaterThanOrEqual = x >= y; // Mayor o igual qué\nconst lessThan = x < y; // Menor qué\nconst isLessThanOrEqual = x <= y; // Menor o igual qué\n\nconsole.log(\"console log Raquel ~ equals:\", equals);\nconsole.log(\"console log Raquel ~ notEquals:\", notEquals);\nconsole.log(\"console log Raquel ~ extrictEqual:\", extrictEqual);\nconsole.log(\"console log Raquel ~ extrictNotEqual:\", extrictNotEqual);\nconsole.log(\"console log Raquel ~ greaterThan:\", greaterThan);\nconsole.log(\"console log Raquel ~ greaterThanOrEqual:\", greaterThanOrEqual);\nconsole.log(\"console log Raquel ~ lessThan:\", lessThan);\nconsole.log(\"console log Raquel ~ isLessThanOrEqual:\", isLessThanOrEqual);\n\n// Operadores lógicos\nconst and = x < 5 && y < 5; // Y\nconst or = x || y; // O\nconst nullish = x ?? y; // Nullish\n\n// Estructuras de control\n\n// If-else\nif (x != y) {\n  console.log(\"x no es igual a y\");\n} else {\n  console.log(\"x es igual a y\");\n}\n\n// Ternario\nx === 5 ? \"x es igual a 5\" : \"x no es igual a 5\";\n\n// Switch\nswitch (x) {\n  case 1:\n    console.log(\"x es igual a 1\");\n    break;\n  case 2:\n    console.log(\"x es igual a 2\");\n    break;\n  default:\n    console.log(\"x no es igual a 1 ni 2\");\n    break;\n}\n\n// For loop\nfor (let i = 0; i < 10; i++) {\n  console.log(\"i vale: \" + i);\n}\n\n// While\nwhile (x != 5) {\n  let i = 0;\n  console.log(\"x vale: \" + x);\n  i++;\n}\n\n// Do... while\nlet doWhile = 0;\ndo {\n  console.log(\"Ejecutanto...\");\n  doWhile++;\n} while (doWhile != 5);\n\n// For... in\nlet countries = { Spain, Portugal, Germany };\nfor (let key in countries) {\n  console.log(\"País: \" + countries[key]);\n}\n\n// Try catch\ntry {\n  let result = 20 / 5;\n  console.log(\"The result is: \", result);\n} catch (error) {\n  console.error(\"Error: \" + error.message);\n}\n\n// Throw\nfunction divider(a, b) {\n  if (b === 0) {\n    throw new Error(\"Can't divide by zero\");\n  }\n  return a / b;\n}\n\n// Extra optional\nfor (let i = 10; i <= 55; i++) {\n  if (i % 2 === 0 && i !== 16 && i % 3 === 0) {\n    console.log(i);\n  }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/RaulDoezon.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n*/\n\n// +++++++++ OPERADORES DE ASIGNACIÓN +++++++++\nx = y; // Asignación.\nx += y; // Asignación de adición: x = x + y\nx -= y; // Asinación de resta: x = x - y\nx *= y; // Asignación de multiplicación: x = x * y\nx /= y; // Asignación de multiplicación: x = x / y\nx %= y; // Asignación de residuo: x = x % y\nx **= y; // Asignación de exponenciación: x = x ** y\nx <<= y; // Asignación de desplazamiento a la izquierda: x = x << y\nx >>= y; // Asignación de desplazamiento a la derecha: x = x >> y\nx >>>= y; // Asignación de desplazamiento a la derecha sin signo: x = x >>> y\nx &= y; // Asignación AND bit a bit: x = x & y\nx ^= y; // Asignación XOR bit a bit\nx |= y; // Asignación OR bit a bit: x = x | y\nx && y; // Asignación AND lógico: x && (x = y)\nx ||= y; // Asignación OR lógico: x || (x = y)\nx ??= y; // Asignación de anulación lógica: x ?? (x = y)\n\n// +++++++++ OPERADORES DE COMPARACIÓN +++++++++\nx == y; // Igual\nx != y; // No es igual\nx === y; // Estrictamente igual\nx !== y; // Desigualdad estricta\nx > y; // Mayor que\nx >= y; // Mayor o igual que\nx < y; // Menor que\nx <= y; // Menor o igual que\n\n// +++++++++ OPERADORES ARITMÉTICOS +++++++++\nx + y; // Suma\nx - y; // Resta\nx * y; // Multiplicación\nx / y; // División\nx % y; // Residuo\nx++; // Incremento\nx--; // Decremento\n-x; // Negación unario\n+\"3\"; // Positivo unario\nx ** y; // Operador de exponenciación\n\n// +++++++++ OPERADORES BIT A BIT +++++++++\na & b; // AND a nivel de bits\na | b; // OR a nivel de bits\na ^ b; // XOR a nivel de bits\n~ a; // NOT a nivel de bits\na << b; // Desplazamiento a la izquierda\na >> b; // Desplazamiento a la derecha de propagación de signo\na >>> b; // Desplazamiento a la derecha de relleno de cero\n\n// +++++++++ OPERADORES LÓGICOS +++++++++\ntrue && x == x; // AND lógico\ntrue || x == y; // OR lógico\n!true; // NOT lógico\n\n// +++++++++ OPERADORES DE CADENA +++++++++\nvar myString = \"Ra\";\nmyString + \"úl\"; // Concatenación\nmyString += \"úl\"; // Concatenación por asignación abreviada\n\n// +++++++++ OPERADOR CONDICIONAL (TERNARIO) +++++++++\nvar status = age >= 18 ? \"Adult\" : \"Minor\";\n\n// +++++++++ OPERADOR COMA +++++++++\nvar x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];\nvar a = [x, x, x, x, x];\n\nfor (var i = 0, j = 9; i <= j; i++, j--) {\n  console.log(\"a[\" + i + \"][\" + j + \"]= \" + a[i][j]);\n}\n\n// +++++++++ OPERADORES UNARIOS +++++++++\nz = 33;\ndelete z; // Devuelve true si z se crea implícitamente\ntypeof myString; // Devuelve \"string\"\nvoid (2 === \"2\"); // Devuelve undefined\n\n//  +++++++++ OPERADORES RELACIONALES +++++++++\n\"PI\" in Math; // Operador in\nvar theDay = new Date(1995, 12, 17);\nif (theDay instanceof Date) { // Operador intanceof\n  console.log(\"Si theDay es un objeto Date, las instrucciones de la expresión if se ejecutan.\");\n}\n\n// +++++++++ ESTRUCTURAS DE CONTROL +++++++++\n\n// if / else if / else\nvar firstName = \"Samus\";\n\nif (firstName == \"Samus\") {\n  console.log(\"Su nombre es Samus Aran.\");\n} else if (firstName == \"Adam\") {\n  console.log(\"Su nombre es Adam Malkovich.\")\n} else {\n  console.log(\"No hay registro del nombre.\");\n}\n\n// switch\nswitch (2 + 2 === 4) {\n  case true:\n    console.log(\"La suma es correcta.\");\n    break;\n\n  case false:\n    console.log(\"La suma es incorrecta.\");\n\n  default:\n    console.log(\"Error en la operación.\");\n    break;\n}\n\n// while\nvar iterationCount = 0;\n\nwhile(iterationCount < 5) {\n  iterationCount++;\n  console.log(\"Número \" + iterationCount);\n}\n\n// do...while\nvar iterationCount = 0;\n\ndo {\n  iterationCount++;\n  console.log(\"Número \" + iterationCount);\n} while (iterationCount < 10);\n\n// for\nfor (let index = 0; index < 7; index++) {\n  console.log(\"Número \" + index);\n}\n\n\n// DIFICULTAD EXTRA\nfor(index = 10; index <= 55; index++) {\n\tif (index !== 55) {\n  \tif (index  === 16 || index % 3 === 0 || index % 2 !== 0) {\n      continue;\n    }\n  }\n\n\tconsole.log(\"Número \" + index);\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/RicJDev.js",
    "content": "//EJERCICIO\n//**OPERADORES**\n//-Aritmeticos-\nlet num1 = 4;\nlet num2 = 2;\n\nconsole.log(num1 + num2); //suma\nconsole.log(num1 - num2); //resta\nconsole.log(num1 * num2); //multiplicacion\nconsole.log(num1 / num2); //division\nconsole.log(num1 % num2); //resto\nconsole.log(num1 ** num2); //potencia\n\n//-De asignacion-\nlet a = 20;\n\nconsole.log((a += 2)); //igual a si mismo mas\nconsole.log((a -= 1)); //igual a... menos\nconsole.log((a *= 2)); //igual a... multiplicado por\nconsole.log((a /= 4)); //igual a... entre\n\n///-De comparacion-\nlet firstValue = 10;\nlet secondValue = '10';\n\nconsole.log(firstValue == secondValue); //equivalente\nconsole.log(firstValue === secondValue); //igual\nconsole.log(firstValue != secondValue); //no equivalente\nconsole.log(firstValue !== secondValue); //no igual\n\nlet num3 = 4;\nlet num4 = 2;\n\nconsole.log(num3 > num4); //mayor que\nconsole.log(num3 < num4); //menor que\nconsole.log(num3 >= num4); //mayor o igual que\nconsole.log(num3 <= num4); //menor o igual que\n\n//-Logicos-\nconst myBool1 = true;\nconst myBool2 = false;\nconst myBool3 = true;\n\nconsole.log(myBool1 && myBool3); //And\nconsole.log(myBool1 || myBool2); //Or\nconsole.log(!myBool2); //Negacion\n\n//-De incremento y decremento-\nlet count = 0;\nconsole.log(++count);\nconsole.log(count); //pre-incremento\n\nlet count2 = 0;\nconsole.log(count2++);\nconsole.log(count2); //post-incremento\n\nlet count3 = 0;\nconsole.log(--count3);\nconsole.log(count3); //pre-decremento\n\nlet count4 = 0;\nconsole.log(count4--);\nconsole.log(count4); //post-decremento\n\n//-Operadores ternarios-\nlet num5 = 7;\n\nnum5 > 0 ? console.log('Numero positivo') : console.log('Numero negativo');\n\nnum5 = -5;\n\nnum5 > 0 ? console.log('Numero positivo') : console.log('Numero negativo');\n\n//**ESTRUCTURAS DE CONTROL**\n\n//-Condicionales-\n//if\nlet totalPoints = 5003;\n\nconsole.log('Nivel completado!');\nif (totalPoints > 5000) {\n\tconsole.log('Logro desbloqueado: maestro espadachin');\n}\n\n//if else\nfunction checkEvenNum(n) {\n\tif (typeof n === 'number') {\n\t\tif (n % 2 === 0) {\n\t\t\tconsole.log(`${n} es par`);\n\t\t} else {\n\t\t\tconsole.log(`${n} no es par`);\n\t\t}\n\t} else {\n\t\tconsole.log('Valor invalido');\n\t}\n}\n\ncheckEvenNum(7);\n\n//Switch\nlet clima = 'nublado';\nswitch (clima) {\n\tcase 'lluvioso':\n\t\tconsole.log('Usa impermeable');\n\t\tbreak;\n\tcase 'nublado':\n\t\tconsole.log('Usa abrigo. Puede que llueva');\n\t\tbreak;\n\tcase 'soleado':\n\t\tconsole.log('Sal tranquilo');\n\t\tbreak;\n\tdefault:\n\t\tconsole.log('No necesitas impermeable');\n}\n\n//-Bucles-\n//For\nfor (let i = 0; i <= 5; i++) {\n\tconsole.log(i);\n}\n\n//While\nlet n = 5;\n\nwhile (n < 10) {\n\tconsole.log(n);\n\tn++;\n}\n\n//Do/While\nlet m = 10;\n\ndo {\n\tconsole.log(m);\n\tm--;\n} while (m > 0);\n\n//EXTRA\nfor (let i = 10; i <= 55; i++) {\n\tif (i !== 55) {\n\t\tif (i !== 16 && i % 3 !== 0 && i % 2 === 0) {\n\t\t\tconsole.log(i);\n\t\t}\n\t} else {\n\t\tconsole.log(i);\n\t}\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/Rikar2o.js",
    "content": "let numeroX = 5;\nlet numeroY = 8;\nlet numeroP = \"5\";\n\nlet resultadoOperacion;\n\nconsole.log('----------------------')\nconsole.log('OPERADORES MATEMATICOS');\nconsole.log('----------------------')\n\n//Suma \"+\"\n\nresultadoOperacion = numeroX + numeroY\nconsole.log('\\nSUMA');\nconsole.log(`El resultado de la suma es ${resultadoOperacion}`);\n\n//Resta \"-\"\nresultadoOperacion = numeroY - numeroX;\nconsole.log('RESTA');\nconsole.log(`El resultado de la resta es ${resultadoOperacion}`);\n\n//Multiplicación \"*\"\nconsole.log('MULTIPLICACIÓN');\nresultadoOperacion = numeroX * numeroY;\nconsole.log(`El resultado de la multiplicación es ${resultadoOperacion}`);\n\n//División \"/\"\nresultadoOperacion = numeroY / numeroX;\nconsole.log('DIVISIÓN');\nconsole.log(`El resultado de la División es ${resultadoOperacion}`);\n\n//Resto \"%\"\nresultadoOperacion = numeroY % numeroX;\nconsole.log('RESTO');\nconsole.log(`El resultado  es ${resultadoOperacion}`);\n\nconsole.log('----------------------')\nconsole.log('OPERADORES LOGICOS Y DE COMPARACIÓN');\nconsole.log('----------------------')\n\n//(==)igual a \nconsole.log('\\n(==)igual a ');\nresultadoOperacion = numeroX == numeroY;\nconsole.log(`El numero ${numeroX} y el numero ${numeroY} son iguales?`);\nconsole.log(resultadoOperacion);\n\nresultadoOperacion = numeroX == numeroX;\nconsole.log(`El numero ${numeroX} y el numero ${numeroX} son iguales?`);\nconsole.log(resultadoOperacion);\n\n\n//(===)valor igual y tipo\n\nconsole.log('\\n(===)valor igual y tipo');\nresultadoOperacion = numeroX === numeroX;\nconsole.log(`El numero ${numeroX} y el numero ${numeroX} son iguales?`);\nconsole.log(resultadoOperacion);\n\nresultadoOperacion = numeroX === numeroP;\nconsole.log(`El numero ${numeroX} y el numero ${numeroP}(string) son iguales?`);\nconsole.log(resultadoOperacion);\n\n//(!=)No igual\nconsole.log('\\n(!=)No igual');\nresultadoOperacion = numeroX != numeroY;\nconsole.log(`El numero ${numeroX} y el numero ${numeroY} son iguales?`);\nconsole.log(resultadoOperacion);\n\n//(!==)no igual en valor o tipo diferente \nconsole.log('\\n(!==)no igual en valor o tipo diferente');\nresultadoOperacion = numeroX !== numeroP;\nconsole.log(`El numero ${numeroX} y el numero ${numeroP}(string) son iguales?`);\nconsole.log(resultadoOperacion);\n\n//(>) Mayor Que\nconsole.log('\\n(>) Mayor Que');\nresultadoOperacion = numeroX > numeroY;\nconsole.log(`El numero ${numeroX} es mayor que el numero ${numeroY} ?`);\nconsole.log(resultadoOperacion);\n\n//(<) Menor Que\nconsole.log('\\n(<) Menor Que');\nresultadoOperacion = numeroX < numeroY;\nconsole.log(`El numero ${numeroX} es menor que el numero ${numeroY} ?`);\nconsole.log(resultadoOperacion);\n\n//(>=) Mayor Que o igual a\nconsole.log('\\nMayor Que o igual a');\nresultadoOperacion = numeroX >= numeroY;\nconsole.log(`El numero ${numeroX} es mayor o igual que el numero ${numeroY} ?`);\nconsole.log(resultadoOperacion);\n\n//(<=) Menor Que o igual a\nconsole.log('\\n(<) Menor Que o igual a');\nresultadoOperacion = numeroX <= numeroY;\nconsole.log(`El numero ${numeroX} es menor o igual que el numero ${numeroY} ?`);\nconsole.log(resultadoOperacion);\n\n//(&&) y\nconsole.log('\\n(&&) y');\nresultadoOperacion = (numeroX < 100 && numeroY > 10);\nconsole.log(`El numero ${numeroX} es menor que 100 y el numero ${numeroY} es mayor 10 ?`);\nconsole.log(resultadoOperacion);\n\n\n//(!) no\nconsole.log('\\n(!) no');\nresultadoOperacion = !(numeroX == numeroY);\nconsole.log(`El numero ${numeroX} es igual que el numero ${numeroY} ?`);\nconsole.log(resultadoOperacion);\n\n//(?) operador ternario\nconsole.log('\\noperador ternario');\nresultadoOperacion = (numeroX == numeroY)? \"verdadero\" : \"falso\";\nconsole.log(`El numero ${numeroX} es igual que el numero ${numeroY} ?`);\nconsole.log(resultadoOperacion);\n\nconsole.log('\\n----------------------');\nconsole.log('Condicionales, iterativas, excepciones');\nconsole.log('----------------------');\n\n/*Condicionales, iterativas, excepciones*/\n\n//ciclo for\nconsole.log('\\n-------Ciclo For--------');\nfor(i = 0; i <= 9; i++ ){\n    console.log(i);\n}\n\n//switch\nconsole.log('\\n-------Switch--------');\nlet fruta = \"Manzana\";\nswitch (fruta){\n    case \"Manzana\":\n        console.log(\"Es Mazana\");\n        break;\n\n    case \"Pera\":\n        console.log(\"Es Pera\");\n        break;\n\n    case \"Mango\":\n        console.log(\"Es Mango\");\n        break;\n\n    default:\n    console.log(\"No es manzana\");\n    break;\n}\n\n//while\nconsole.log('\\n-------while--------');\nlet contador = 0;\nwhile (contador <= 10) {\n  console.log(\"número \" + contador);\n  contador++;\n}\n\n// Do while\nconsole.log('\\n-------Do while--------');\ncontador = 0;\ndo {\n  console.log(\"número \" + contador);\n  contador++;\n} while (contador <= 10);\n\n\n\n/*\n DIFICULTAD EXTRA (opcional):\n Crea un programa que imprima por consola todos los números comprendidos\n entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n*/\n\nconsole.log('\\n------Ejercicio Extra-----------');\n\nlet numeroEntre = 10;\nfor (numeroEntre ; numeroEntre <= 55; numeroEntre++) {\n    if((numeroEntre % 2 === 0) && (numeroEntre !== 16) && (numeroEntre % 3 !== 0)){\n        console.log(numeroEntre);\n    }\n}\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/Robindev1812.js",
    "content": "/*\r\nEjercicios:\r\n*/\r\n\r\n\r\n/*\r\n1. Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje: Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits... (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\r\n*/\r\n\r\n// Operadores de cadenas:\r\nlet mensaje = 'Hola,'\r\nmensaje += ' Robinson.' // 'Hola, Robinson.'\r\nmensaje += ' Estás aprendiendo JS' // 'Hola, Robinson. Estás aprendiendo JS'\r\n\r\n// Operadores Aritméticos:\r\nlet suma = 5 + 3; // 8\r\nlet resta = 7 - 2; // 5\r\nlet multiplicacion = 4 * 6; // 24\r\nlet division = 10 / 2; // 5\r\nlet modulo = 17 % 3; // 2 (el resto de la división de 17 por 3)\r\n\r\n// Operadores de Asignación:\r\nlet num = 10;\r\nnum += 5 // 15\r\nnum -= 3 // 12\r\nnum /= 2 // 6\r\nnum **= 2 // 36\r\nnum %= 6 // 0\r\n\r\n// Operadores de comparacion \r\nlet a = 10;\r\nlet b = 5;\r\nlet c = '10';\r\n\r\n// El signo == solo compara si los valores son iguales sin importar rl tipo de dato.\r\na == b // false\r\na != b // true\r\na == c // true\r\na != c  // false\r\n\r\n// El signo === compara el valor y el tipo de dato.\r\na === b // false\r\na !== b // true\r\na === c // false\r\na !== c  // true\r\n\r\na > b // true\r\na < b // false\r\na >= c // true\r\na <= c  // false\r\n\r\n\r\n// Operadores lógicos: AND (&&), OR (||) y NOT (!)\r\nlet x = true;\r\nlet y = false;\r\n\r\nx && y // false. Devuelve true si ambas expresiones booleanas son true, de lo contrario devuelve false.\r\nx || y // true. Devuelve true si al menos una de las expresiones booleanas es true. De lo contrario, devuelve false.\r\n!y // true. Invierte el valor booleano de la expresión a la que se aplica. Si la expresión es true, devuelve false, y viceversa.\r\n\r\n\r\n// Operadores de incremento y decremento\r\nlet incremento = 10;\r\n++incremento // 11. Incrementa el valor de la variable en 1 y devuelve el valor incrementado.\r\nincremento++ // Devuelve 11, aunque incremento vale 12.  Incrementa el valor de la variable en 1 y devuelve el valor original de la variable antes del incremento.\r\nincremento // 12\r\n\r\n--incremento // 11\r\nincremento-- // 11\r\nincremento // 10\r\n\r\n\r\n// Operador ternario: condicion ? expresionSiTrue : expresionSiFalse;\r\n// let edad = 25;\r\nlet mensaje1 = edad >= 18 ? 'Eres mayor de edad.' : 'Eres menor de edad.';\r\nconsole.log(mensaje); // Imprime 'Eres mayor de edad.'\r\n\r\n\r\n\r\n/*\r\n2. Utilizando las operaciones con operadores que tú quieras, crea ejemplos que representen todos los tipos de estructuras de control que existan en tu lenguaje:\r\nCondicionales, iterativas, excepciones...\r\nDebes hacer print por consola del resultado de todos los ejemplos.\r\n*/\r\n\r\n// Estructuras de control condicionales:\r\n\r\n// if...else\r\nlet edad = 18;\r\nif (edad >= 18) {\r\n  console.log(\"Eres mayor de edad\");\r\n} else {\r\n  console.log(\"Eres menor de edad\");\r\n}\r\n\r\n// else if\r\nlet hora = 14;\r\nif (hora < 12) {\r\n  console.log(\"Buenos días\");\r\n} else if (hora < 18) {\r\n  console.log(\"Buenas tardes\");\r\n} else {\r\n  console.log(\"Buenas noches\");\r\n}\r\n\r\n// Switch\r\nlet dia = 2;\r\nswitch (dia) {\r\n  case 1:\r\n    console.log(\"Lunes\");\r\n    break;\r\n  case 2:\r\n    console.log(\"Martes\"); // Martes\r\n    break;\r\n  case 3:\r\n    console.log(\"Miércoles\");\r\n    break;\r\n  default:\r\n    console.log(\"Día no válido\");\r\n}\r\n\r\n// Estructuras de control iterativas (bucles):\r\n\r\n//For\r\nfor (let i = 0; i < 5; i++) {\r\n  console.log(\"Iteración \" + (i + 1)); // Interacion 1... Iteracion 5\r\n}\r\n\r\n// While\r\nlet contador = 0;\r\nwhile (contador < 5) {\r\n  console.log(\"Contador: \" + contador); // Contador 0 ... Contador 4\r\n  contador++;\r\n}\r\n\r\n// Do while\r\nlet r = 0;\r\ndo {\r\n  console.log(\"Número: \" + r); // 0, 1, 2\r\n  r++;\r\n} while (r < 3);\r\n\r\n//Estructuras de control de salto:\r\n\r\n// Breack\r\nfor (let i = 0; i < 10; i++) {\r\n  if (i === 5) {\r\n    break; // Sale del bucle cuando i es igual a 5\r\n  }\r\n  console.log(i);\r\n}\r\n\r\n// Continue\r\nfor (let i = 0; i < 5; i++) {\r\n  if (i === 2) {\r\n    continue; // Salta la iteración cuando i es igual a 2\r\n  }\r\n  console.log(i);\r\n}\r\n\r\n// Return\r\nfunction sumar(a, b) {\r\n  if (typeof a !== \"number\" || typeof b !== \"number\") {\r\n    return \"Error: Ambos argumentos deben ser números\";\r\n  }\r\n  return a + b;\r\n}\r\nconsole.log(sumar(3, 5)); // Devuelve 8\r\nconsole.log(sumar(3, \"5\")); // Devuelve \"Error: Ambos argumentos deben ser números\""
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/Rolo27s.js",
    "content": "// Reto #01 -> OPERADORES Y ESTRUCTURAS DE CONTROL\n// Fuente con más información: https://www.w3schools.com/js/js_operators.asp\n\n/** Recordar que para usar la terminal con javascript es necesaria la instalación de NodeJS.\n *  En mi caso, para ejecutar el código y que se muestren los console.log ejecutaré este comando en mi ruta relativa de este código.\n *  .\\roadmap-retos-programacion\\Roadmap\\01 - OPERADORES Y ESTRUCTURAS DE CONTROL\\javascript> node Rolo27s.js\n */\n\n// Defino un par de variables\nlet num1 = 27;\nlet num2 = 4;\n\n// Operadores aritméticos:\nconsole.log(\"**** Operadores aritméticos ****\");\nconsole.log(`Suma de ${num1} con ${num2} = ${num1 + num2}`);\nconsole.log(`Resta de ${num1} con ${num2} = ${num1 - num2}`);\nconsole.log(`Multiplicación de ${num1} con ${num2} = ${num1 * num2}`);\nconsole.log(`División de ${num1} con ${num2} = ${num1 / num2}`);\nconsole.log(`Resto o módulo de ${num1} con ${num2} = ${num1 % num2}`);\nconsole.log(`Potencia de ${num1} a la ${num2} = ${num1 ** num2}`);\n\nconsole.log(`Incremento de ${num1} en 1: ${++num1}`); // Para mostrar el valor de num1 sumado 1 tengo que usar el operador ++ antes de la variable. Es decir, primero opero y luego muestro. Si escribiese num1++, el valor de num1 se aumentaría pero no saldría reflejado en ese console log, ya que primero se mostraría y luego se ejecutaría la operación. En ese caso, se podría ver luego el valor de num1 que aumentó.\n\nconsole.log(`Decremento de ${num2} en 1: ${--num2}`); // Misma lógica que el caso de arriba con num1.\n\nconsole.log(\"\\n\\n**** Operadores de asignación ****\");\n// Operadores de asignación:\nlet newNumber = 7;\nconsole.log(`The new number is ${newNumber}`);\nnewNumber = num1;\nconsole.log(`Now the new number is ${newNumber}, like our num1 variable`); // Me acabo de dar cuenta que mezcle el ingles...\nnewNumber = 7; // Restart newNumber to 7\n\n// Se pueden hacer todas la operaciones aritméticas explicadas al comienzo del código y luego asignarlas a otra variable con '='. Generalmente se usan expresiones simplificadas cuando se quiere hacer una operación aritmética y guardar el resultado sobrescribiendo el valor de alguna variable. Por ejemplo en lugar de escribir x = x + y (lo cual es válido), se suele usar x += y.\n\nconsole.log(\"\\n\\n**** Operadores de comparación ****\"); // Se utilizan para implementar lógica a nuestro programa. Se resolverá con True o False.\n\nlet comparacion1 = num1 > num2; // comparacion1 en este caso valdrá true.\nconsole.log(comparacion1);\n\nlet comparacion2 = num1 < num2; // comparacion2 en este caso valdrá false.\nconsole.log(comparacion2);\n\nlet comparacion3 = num1 == \"28\"; // comparacion3 en este caso valdrá true porque se compara de manera no estricta.\nconsole.log(comparacion3);\n\nlet comparacion4 = num1 === \"28\"; // comparacion4 en este caso valdrá false porque se compara de manera estricta.\nconsole.log(comparacion4);\n\nlet comparacion5 = num1 != \"Real\"; // Sera true, porque num1 es 28, que es diferente del string \"Real\".\nconsole.log(comparacion5);\n\nconsole.log(\"\\n\\n**** Operadores lógicos ****\"); // Se utilizan para implementar lógica a nuestro programa. Se resolverá con True o False.\n// Existe 3: &&, || y ! (AND, OR, NOT)\nlet condicion1 = num1 == 28 && num2 == 3; // sera true, porque num1 es 28 y num2 es 3.\nconsole.log(condicion1);\n\nlet condicion2 = num1 == 28 || num2 == 2; // sera true, porque num1 es 28, aunque num2 no sea 2.\nconsole.log(condicion2);\n\nlet condicion3 = num1 == 22 || num2 == 2; // Aquí si sera false, porque no es verdad ninguna de las dos condiciones.\nconsole.log(condicion3);\n\nconsole.log(\"\\n\\n**** Control de tipo ****\");\nconsole.log(typeof num1); // Tipo de variable de num1\nconsole.log(typeof condicion1); // Tipo de variable de num1\n\n// También existe instaceof, que sirve para saber si un objeto es una instancia de ese tipo de objeto. Devuelve un booleano.\n\nconsole.log(\"\\n\\n**** Operadores Bitwise ****\"); // No he usado esto en mi vida.\n// &, |, ~, ^, <<, >>, >>>.\n// AND, OR, NOT, XOR, left shift, right shift, unsigned right shift.\n\n// ------------ DIFICULTAD EXTRA ---------\nconsole.log(\"\\n\\n**** Dificultad extra ****\");\nfor (let i = 10; i <= 55; i++) {\n\tif (i % 2 == 0 && i != 16 && i % 3 != 0) console.log(\"Valores filtrados:\", i);\n}\n// Pues miré mas o menos y no vi ningún resultado raro. ¿Cual era la peculiaridad?\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/SRSURY.js",
    "content": "//ejemplos tipos de operadores en javascript\n// Operadores aritméticos\nlet sum  = 5 + 3;\nlet res = 5 - 3;\nlet mul = 5 * 3;\nlet div  = 5 / 3;\nlet mod = 5 % 3;\nlet exp = 5 ** 3; // Exponente (5 elevado a la potencia de 3)\n//ejemplos\nlet suma = 10 + 5; // Suma\nconsole.log(suma); // 15\nlet resta = 10 - 5; // Resta\nconsole.log(resta); // 5\nlet multiplicacion = 10 * 5; // Multiplicación\nconsole.log(multiplicacion); // 50\n\n// Operados logicos\nlet and = true && false;\nlet or = true || false;\nlet not = !true;\n//ejemplos \nlet andLogico = true && false; // AND lógico\nconsole.log(andLogico); // false\nlet orLogico = true || false; // OR lógico\nconsole.log(orLogico); // true\nlet notLogico = !true; // NOT lógico\nconsole.log(notLogico); // false\n\n// Operadores de comparación\nlet igualdad = 5 == 5; // Igualdad (valor)\nlet igualdadEstricta = 5 === 5; // Igualdad estricta (valor y tipo)\nlet desigualdad = 5 != 3; // Desigualdad (valor)\nlet desigualdadEstricta = 5 !== \"5\"; // Desigualdad estricta (valor y tipo)\nlet mayorQue = 5 > 3; // Mayor que\nlet menorQue = 5 < 3; // Menor que\nlet mayorIgualQue = 5 >= 3; // Mayor o igual que\nlet menorIgualQue = 5 <= 3; // Menor o igual que\n//ejemplos \nlet igualdadValor = 5 == 5; // Igualdad (valor)\nconsole.log(igualdadValor); // true\nlet igualdadEstrictaValor = 5 === 5; // Igualdad estricta (valor y tipo)\nconsole.log(igualdadEstrictaValor); // true\nlet desigualdadValor = 5 != 3; // Desigualdad (valor)\nconsole.log(desigualdadValor); // true\n\n\n\n// Operadores de asignación\nlet asignacion = 5;\nlet asignacionSuma = 5; // Asignación simple\nasignacionSuma += 3; // Asignación con suma\nlet asignacionResta = 5; // Asignación con resta\nasignacionResta -= 3; // Asignación con resta\nlet asignacionMulti = 5; // Asignación con multiplicación\nasignacionMulti *= 3; // Asignación con multiplicación\nlet asignacionDiv = 5; // Asignación con división\nasignacionDiv /= 3; // Asignación con división\nlet asignacionMod = 5; // Asignación con módulo\nasignacionMod %= 3; // Asignación con módulo\nlet asignacionExp = 5; // Asignación con exponente\nasignacionExp **= 3; // Asignación con exponente\n//ejemplos \nlet asignacionSimple = 10; // Asignación simple\nasignacionSimple += 5; // Asignación con suma\nconsole.log(asignacionSimple); // 15\nlet asignacionRestaSimple = 10; // Asignación con resta\nasignacionRestaSimple -= 5; // Asignación con resta\nconsole.log(asignacionRestaSimple); // 5\n\n\n// Operadores de bits\nlet andBit = 5 & 3; // AND bit a bit\nlet orBit = 5 | 3; // OR bit a bit\nlet xorBit = 5 ^ 3; // XOR bit a bit\nlet notBit = ~5; // NOT bit a bit\nlet desplazamientoIzq = 5 << 1; // Desplazamiento a la izquierda\nlet desplazamientoDer = 5 >> 1; // Desplazamiento a la derecha\nlet desplazamientoSinSigno = 5 >>> 1; // Desplazamiento a la derecha sin signo\n//ejemplos\nlet andBitwise = 5 & 3; // AND bit a bit\nconsole.log(andBitwise); // 1 (0101 & 0011 = 0001)\n\n\n// Operadores de cadena\nlet concaten = \"Hola\" + \" \" + \"Mundo\"; // Concatenación de cadenas\nlet concatAsignacion = \"Hola\"; // Asignación de cadena\nconcatAsignacion += \" Mundo\"; // Concatenación con asignación\n//ejemplos\nlet concatenacion = \"Hola\" + \" \" + \"Mundo\"; // Concatenación de cadenas\nconsole.log(concatenacion); // \"Hola Mundo\"\nlet concaten2 = \"Hola\";\nconcaten2 +=  \" Mouredev\";\nconsole.log(concaten2); // \"Hola Mouredev\"\n\n\n\n// Operadores de tipo\n\nlet tipoNumero = typeof 5; // Tipo de dato número\nlet tipoCadena = typeof \"Hola\"; // Tipo de dato cadena\nlet instancia = 5 instanceof Number; // Verifica si es una instancia de Number\nlet instanciaCadena = \"Hola\" instanceof String; // Verifica si es una instancia de String\n//ejemplos\nlet tipoDatoNumero = typeof 5; // Tipo de dato número\nconsole.log(tipoDatoNumero); // \"number\"\n\n// Operadores de incremento y decremento\n\nlet incremento = 5; // Incremento\nincremento++; // Incremento en 1\nlet decremento = 5; // Decremento\ndecremento--; // Decremento en 1\nlet preIncremento = ++incremento; // Incremento antes de usar el valor\nlet preDecremento = --decremento; // Decremento antes de usar el valor\n//ejemplos\nlet incrementoSimple = 5; // Incremento\nincrementoSimple++; // Incremento en 1\nconsole.log(incrementoSimple); // 6\n\n// Operadores condicionales (ternarios)\nlet condicion = true;\nlet resultado = condicion ? \"Es verdadero\" : \"Es falso\"; // Operador ternario\n//ejemplos\nlet condicionTernaria = true;\nlet resultadoTernario = condicionTernaria ? \"Es verdadero\" : \"Es falso\"; // Operador ternario\nconsole.log(resultadoTernario); // \"Es verdadero\"\n\n\n//Operadores de control\nif (true) {\n    console.log(\"Es verdadero\");\n} else {\n    console.log(\"Es falso\");\n}\n// Operadores de control de flujo\nlet numero = 5;\nif (numero > 0) {\n    console.log(\"El número es positivo\");\n}\n// Operadores de control de flujo con switch\nlet dia = 3;\nswitch (dia) {\n    case 1:\n        console.log(\"Lunes\");\n        break;\n    case 2:\n        console.log(\"Martes\");\n        break;\n    case 3:\n        console.log(\"Miércoles\");\n        break;\n    default:\n        console.log(\"Otro día\");\n}\n//bucle for\nfor (let i = 0; i < 5; i++) {\n    console.log(\"Iteración: \" + i);\n}\n// Bucle while\nlet contador = 0;\nwhile (contador < 5) {\n    console.log(\"Contador: \" + contador);\n    contador++;\n}\n// Bucle for...of\nlet arreglo = [1, 2, 3, 4, 5];\nfor (let numero of arreglo) {\n    console.log(\"Número: \" + numero);\n}\n// Bucle for...in\nlet objeto = { a: 1, b: 2, c: 3 };\nfor (let clave in objeto) {\n    console.log(\"Clave: \" + clave + \", Valor: \" + objeto[clave]);\n}\n\n// Bucle do-while\nlet contadorDoWhile = 0;\ndo {\n    console.log(\"Contador do-while: \" + contadorDoWhile);\n    contadorDoWhile++;\n} while (contadorDoWhile < 5);\n\n//excepciones\ntry {\n    // Código que puede generar una excepción\n    let resultado = 10 / 0; // División por cero\n}\ncatch (error) {\n    // Manejo de la excepción\n    console.error(\"Se ha producido un error: \" + error.message);\n}\n\n\n// Reto extra Numeros compredidos desde 10 hasta 55 pares, ni que son el 16 ni multiplos de 3\nlet numeros = [];\nfor (let i = 10; i<=55; i++){\n    if(i % 2 === 0 && i !== 16 && i % 3 !== 0){\n        numeros.push(i);\n    }\n}\nconsole.log(numeros); // Imprime los números pares comprendidos entre 10 y 55, excluyendo el 16 y los múltiplos de 3\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/Sac-Corts.js",
    "content": "// Exercise //\n\n// Arithmetic Operators\nlet addition = 5 + 3;\nconsole.log(\"Addition: 5 + 3 = \", addition);\n\nlet subtraction = 10 - 5;\nconsole.log(\"Subtraction: 10 - 5 = \", subtraction);\n\nlet multiplication = 10 * 5;\nconsole.log(\"Multiplication: 10 * 5 = \", multiplication);\n\nlet division = 100 / 5;\nconsole.log(\"Division: 10 / 5 = \", division);\n\nlet _module = 8 % 2;\nconsole.log(\"Module: 8 % 2 = \", _module);\n\nlet power = 4 ** 2;\nconsole.log(\"Power: 4 ** 2 = \", power);\n\n// Assignment Operators\nlet a = 10;\n\na += 2;\nconsole.log(\"Addition assignment +=: \", a);\n\na -= 2;\nconsole.log(\"Subtraction assignment -=: \", a);\n\na *= 4;\nconsole.log(\"Multiplication assignment *=: \", a);\n\na /= 2;\nconsole.log(\"Division assignment /=: \", a);\n\na %= 2;\nconsole.log(\"Remainder assignment %=: \", a);\n\na **= 2;\nconsole.log(\"Exponentiation assignment **=: \", a);\n\n// Comparison Operators\nconsole.log(\"Equality == : \", 5 == \"5\");\nconsole.log(\"Strict equality == : \", 5 === \"5\");\nconsole.log(\"Inequality != : \", 5 != \"5\");\nconsole.log(\"Strict inequality !== : \", 5 !== \"5\");\nconsole.log(\"Greater than > : \", 10 > 5);\nconsole.log(\"Less than < : \", 10 < 5);\nconsole.log(\"Greater than or equal >= : \", 5 >= 7);\nconsole.log(\"Less than or equal <= : \", 5 <= 7);\n\n// Logical Operators\nconsole.log(\"Logical AND (&&):\", true && false);\nconsole.log(\"Logical OR (||):\", true || false);\nconsole.log(\"Logical NOT (!):\", !false);\n\n// Identity Operators\nlet obj1 = { name: \"Isaac\" };\nlet obj2 = { name: \"Isaac\" };\nlet obj3 = obj1;\nconsole.log(\"Identity (===):\", obj1 === obj2);\nconsole.log(\"Identity (===):\", obj1 === obj3);\n\n// Membership Operators\nlet array = [1, 2, 3, 4, 5];\nconsole.log(\"Membership (in):\", 3 in array);\nconsole.log(\"Membership (includes):\", array.includes(3));\n\nlet obj = { name: \"Bob\", age: 25 };\nconsole.log(\"Membership (in):\", \"name\" in obj);\nconsole.log(\"Membership (in):\", \"height\" in obj);\n\n// Bits Operators\nconsole.log(\"Bitwise AND (&):\", 5 & 1); // 101 & 001 = 001 (1)\nconsole.log(\"Bitwise OR (|):\", 5 | 1); // 101 | 001 = 101 (5)\nconsole.log(\"Bitwise XOR (^):\", 5 ^ 1); // 101 ^ 001 = 100 (4)\nconsole.log(\"Bitwise NOT (~):\", ~5); // ~101 = 010 (complemento)\nconsole.log(\"Bitwise Left Shift (<<):\", 5 << 1); // 101 << 1 = 1010 (10)\nconsole.log(\"Bitwise Right Shift (>>):\", 5 >> 1); // 101 >> 1 = 010 (2)\nconsole.log(\"Bitwise Zero-fill Right Shift (>>>):\", 5 >>> 1); // 101 >>> 1 = 010 (2)\n\n// Control Structures //\n\n// Conditionals\nlet num = 10;\nif (num > 0) {\n    console.log(\"The number is positive\");\n} else if (num < 0) {\n    console.log('The number is negative');\n} else {\n    console.log('The number is cero');\n}\n\nswitch (num) {\n    case 1:\n        console.log('The number is 1');\n        break;\n    case 10:\n        console.log('The numer is 10')\n        break;\n        default:\n            console.log('The number is not 1 or 10');\n}\n\n// Iterative\nfor (let i = 0; i < 5; i++) {\n    console.log('For loop, i = ', i);\n}\n\nlet count = 0;\nwhile (count < 5) {\n    console.log('While loop, i = ', count);\n    count++;\n}\n\nlet index = 0;\ndo {\n    console.log('Do loop, index = ', index);\n    index++;\n} while (index < 5);\n\nlet arrayForOf = ['a', 'b', 'c'];\nfor (let item of arrayForOf) {\n    console.log('For-of loop, item = ', item);\n}\n\nlet objForIn = { name: 'Alice', age: 25};\nfor (let key in objForIn) {\n    console.log('For-in loop, key = ', key, ', value = ', objForIn[key]);\n}\n\n// Exceptions \ntry {\n    let result = 10 / 0;\n    console.log('Result: ', result);\n    throw new Error('This is a custom exception');\n} catch (error) {\n    console.log('An exception was caught: ', error.message);\n} finally {\n    console.log('This block is always executed');\n}\n\n// Extra Exercise // \n\nfor (let i = 10; i <= 55 ; i++) {\n    if (i % 2 === 0 && i % 3 !== 0 && i !== 16) {\n        console.log(i);\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/SalazarProgrammer.js",
    "content": "// #01 OPERADORES Y ESTRUCTURAS DE CONTROL\n// Dificultad: Fácil | Publicación: 02/01/24 | Corrección: 08/01/24\n\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n/*\n * RESPUESTAS:\n * - Operadores y estructuras de control\n */\n\nconsole.log('=== OPERADORES EN JAVASCRIPT ===');\n\n// 1. OPERADORES ARITMÉTICOS\nconsole.log('\\n1. OPERADORES ARITMÉTICOS:');\nlet a = 15;\nlet b = 4;\n\nconsole.log('a =', a, ', b =', b);\nconsole.log('Suma (a + b):', a + b);\nconsole.log('Resta (a - b):', a - b);\nconsole.log('Multiplicación (a * b):', a * b);\nconsole.log('División (a / b):', a / b);\nconsole.log('Módulo (a % b):', a % b);\nconsole.log('Exponenciación (a ** b):', a ** b);\nconsole.log('Incremento (a++):', a++); // Post-incremento\nconsole.log('Decremento (--b):', --b); // Pre-decremento\n\n// 2. OPERADORES DE COMPARACIÓN\nconsole.log('\\n2. OPERADORES DE COMPARACIÓN:');\nconsole.log('Igualdad (a == 15):', a == 15);\nconsole.log(\"Igualdad estricta (a === '15'):\", a === '15');\nconsole.log('Desigualdad (a != 15):', a != 15);\nconsole.log('Desigualdad estricta (a !== 15):', a !== 15);\nconsole.log('Mayor que (a > 10):', a > 10);\nconsole.log('Menor que (a < 20):', a < 20);\nconsole.log('Mayor o igual (a >= 15):', a >= 15);\nconsole.log('Menor o igual (a <= 15):', a <= 15);\n\n// 3. OPERADORES LÓGICOS\nconsole.log('\\n3. OPERADORES LÓGICOS:');\nlet x = true;\nlet y = false;\n\nconsole.log('AND (x && y):', x && y);\nconsole.log('OR (x || y):', x || y);\nconsole.log('NOT (!x):', !x);\nconsole.log(\"Nullish Coalescing (null ?? 'default'):\", null ?? 'default');\nconsole.log('Optional Chaining (obj?.prop):', {}.prop?.nested);\n\n// 4. OPERADORES DE ASIGNACIÓN\nconsole.log('\\n4. OPERADORES DE ASIGNACIÓN:');\nlet c = 10;\nconsole.log('Asignación (=): c =', c);\nc += 5;\nconsole.log('Suma y asignación (+=):', c);\nc -= 3;\nconsole.log('Resta y asignación (-=):', c);\nc *= 2;\nconsole.log('Multiplicación y asignación (*=):', c);\nc /= 4;\nconsole.log('División y asignación (/=):', c);\nc %= 3;\nconsole.log('Módulo y asignación (%=):', c);\n\n// 5. OPERADORES DE BITS\nconsole.log('\\n5. OPERADORES DE BITS:');\nlet num1 = 5; // 0101 en binario\nlet num2 = 3; // 0011 en binario\n\nconsole.log('AND (&):', num1 & num2); // 0001 = 1\nconsole.log('OR (|):', num1 | num2); // 0111 = 7\nconsole.log('XOR (^):', num1 ^ num2); // 0110 = 6\nconsole.log('NOT (~num1):', ~num1); // Complemento a 2\nconsole.log('Desplazamiento izquierda (num1 << 1):', num1 << 1); // 1010 = 10\nconsole.log('Desplazamiento derecha (num1 >> 1):', num1 >> 1); // 0010 = 2\n\n// 6. OPERADORES DE IDENTIDAD/TIPO\nconsole.log('\\n6. OPERADORES DE IDENTIDAD/TIPO:');\nconsole.log('typeof 42:', typeof 42);\nconsole.log(\"typeof 'hello':\", typeof 'hello');\nconsole.log('instanceof ([] instanceof Array):', [] instanceof Array);\nconsole.log(\"in ('length' in []):\", 'length' in []);\n\n// 7. OPERADORES DE PERTENENCIA (para arrays y objetos)\nconsole.log('\\n7. OPERADORES DE PERTENENCIA:');\nconst array = [1, 2, 3, 4, 5];\nconst objeto = { nombre: 'Juan', edad: 30 };\n\nconsole.log(\"in operator ('edad' in objeto):\", 'edad' in objeto);\nconsole.log('Array includes (array.includes(3)):', array.includes(3));\n\nconsole.log('\\n=== ESTRUCTURAS DE CONTROL ===');\n\n// 1. CONDICIONALES\nconsole.log('\\n1. ESTRUCTURAS CONDICIONALES:');\n\n// if-else\nif (a > 10) {\n\tconsole.log('if: a es mayor que 10');\n} else {\n\tconsole.log('if: a no es mayor que 10');\n}\n\n// if-else if-else\nif (a > 20) {\n\tconsole.log('a > 20');\n} else if (a > 15) {\n\tconsole.log('15 < a <= 20');\n} else {\n\tconsole.log('a <= 15');\n}\n\n// switch\nlet dia = 3;\nswitch (dia) {\n\tcase 1:\n\t\tconsole.log('switch: Lunes');\n\t\tbreak;\n\tcase 2:\n\t\tconsole.log('switch: Martes');\n\t\tbreak;\n\tcase 3:\n\t\tconsole.log('switch: Miércoles');\n\t\tbreak;\n\tdefault:\n\t\tconsole.log('switch: Otro día');\n}\n\n// Operador ternario\nlet resultado = a > 10 ? 'Mayor que 10' : 'Menor o igual a 10';\nconsole.log('Ternario:', resultado);\n\n// 2. ESTRUCTURAS ITERATIVAS\nconsole.log('\\n2. ESTRUCTURAS ITERATIVAS:');\n\n// for\nconsole.log('For loop:');\nfor (let i = 0; i < 5; i++) {\n\tconsole.log('  Iteración:', i);\n}\n\n// while\nconsole.log('While loop:');\nlet contador = 0;\nwhile (contador < 3) {\n\tconsole.log('  Contador:', contador);\n\tcontador++;\n}\n\n// do-while\nconsole.log('Do-while loop:');\ncontador = 0;\ndo {\n\tconsole.log('  Contador:', contador);\n\tcontador++;\n} while (contador < 3);\n\n// for...of (arrays)\nconsole.log('For...of (arrays):');\nfor (const elemento of array) {\n\tconsole.log('  Elemento:', elemento);\n}\n\n// for...in (objetos)\nconsole.log('For...in (objetos):');\nfor (const clave in objeto) {\n\tconsole.log(`  ${clave}: ${objeto[clave]}`);\n}\n\n// 3. MANEJO DE EXCEPCIONES\nconsole.log('\\n3. MANEJO DE EXCEPCIONES:');\n\ntry {\n\tconsole.log('Intentando operación...');\n\tlet division = 10 / 0;\n\tif (!isFinite(division)) {\n\t\tthrow new Error('División por cero o resultado infinito');\n\t}\n\tconsole.log('Resultado:', division);\n} catch (error) {\n\tconsole.log('Error capturado:', error.message);\n} finally {\n\tconsole.log('Bloque finally ejecutado');\n}\n\n// 4. CONTROL DE FLUJO\nconsole.log('\\n4. CONTROL DE FLUJO:');\n\n// break\nconsole.log('Break en loop:');\nfor (let i = 0; i < 10; i++) {\n\tif (i === 5) break;\n\tconsole.log('  i =', i);\n}\n\n// continue\nconsole.log('Continue en loop:');\nfor (let i = 0; i < 5; i++) {\n\tif (i === 2) continue;\n\tconsole.log('  i =', i);\n}\n\n// return (en función)\nfunction ejemploReturn() {\n\tconsole.log('Esta línea se ejecuta');\n\treturn 'Valor retornado';\n}\nconsole.log('Return:', ejemploReturn());\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Números entre 10 y 55, pares, que no son 16 ni múltiplos de 3\n */\nconsole.log('\\n=== DIFICULTAD EXTRA ===');\n\nfunction numerosEspeciales() {\n\tlet count = 0;\n\n\tfor (let i = 10; i <= 55; i++) {\n\t\tif (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n\t\t\tconsole.log(i);\n\t\t\tcount++;\n\t\t}\n\t}\n\n\treturn count;\n}\n\nconst total = numerosEspeciales();\nconsole.log(`\\nTotal de números encontrados: ${total}`);\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/SantiagoCuevas2003.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n//------------------------------- aritmeticos --------------------------------------\n///////////////////////////////////////////////////////////\n//suma\nconsole.log(\"la suma de 15 + 10 es :\"+(15 + 10));\n\n//resta \nconsole.log(\"la resta de 15 - 10 es :\"+(15 - 10));\n\n//multiplicacion \nconsole.log(\"la multiplicacion de 15 * 10 es :\"+(15 * 10));\n\n//division\nconsole.log(\"la division de 15 / 10 es :\"+(15 / 10));\n\n//modulo o residuo de la division\nconsole.log(\"el modulo de 15 % 10 es :\"+(15 % 10));\n\n//Exponenciacion \nconsole.log(\"la Exponenciacion de 15 ** 10 es :\"+(2 ** 4));\n\n//incremento \n\nfor (let i = 0 ; i < 4 ; i++ ){\n    console.log(i)\n};\n\n//decremento \n\nfor (let i = 5 ; i > 0  ; i-- ){\n    console.log(i)\n};\n\n//------------------------------operadores de compracion---------------------------------\n\n//igual \n\nlet igual = 10 \n\nif (igual == 10){\nconsole.log(\"el numero dado es igual a :\" + igual)\n};\n\n//estrictamente igual\n\nlet estrictamenteIgual = 10 \n\nif (estrictamenteIgual === 10){\nconsole.log(\"el numero dado es igual a :\" + estrictamenteIgual)\n};\n\n//No es igual \n\nlet noEsIgual = 5;\n\nif (noEsIgual != 10){\nconsole.log(\"el numero dado no es igual \" );\n};\n\n//estrictamenteNoEsIgual\n\nlet estrictamenteNoEsIgual = 5;\n\nif (estrictamenteNoEsIgual !== 10){\nconsole.log(\"el numero dado no es igual \" );\n};\n\n//mayor que \n\nlet a = 20;\nlet b = 70;\n\nconsole.log(a > b);\n\n//menor que \n\nconsole.log(a < b);\n\n//mayor o igual \nconsole.log(a >= b);\n\n//menor o igual \nconsole.log(a <= b);\n\n//--------------------------operadores logicos----------------------------------------- \n\n//and \n\nlet numero = 20;\nlet numero1 = 30;\nlet numero2 = 30;\n\n\nconsole.log((numero > numero1) && (numero < numero2));//false\n\n//(OR)\n\nconsole.log((numero > numero1) || (numero < numero2));//true \n\n//negacion logica !\n\nlet esHombre = true;\n\nif (!esHombre){\n    console.log(\"el ususario es hombre\");\n}else{\n    console.log(\"el usuario es mujer\");//imprimira el usuario es mujer ya que la negacion cambia un valor booleano a un valor contrario\n};\n\n//-----------------------operadores de asignacion---------------------------------\n\n//asignacion simple\n\nlet asignacionSimple = 20;\n\n//asignacion adicion\n\nasignacionSimple += 5;\n\nconsole.log(asignacionSimple)//asignacionSimple es 25 (20 + 5)\n\n//de sustraccion\n\nlet sustracion = 10;\n\nsustracion -= 4;\n\nconsole.log(sustracion)//asignacionSimple es 25 (20 + 5)\n\n//multiplicacion\n\nlet multiplicacion = 10;\n\nmultiplicacion *= 4;\n\nconsole.log(multiplicacion)//asignacionSimple es 25 (20 + 5)\n\n\n//asignacion de division \n\nlet division = 10;\n\ndivision /= 4;\n\nconsole.log(division)//asignacionSimple es 25 (20 + 5)\n\n//asignacion de modulo \n\nlet modulo = 10;\n\nmodulo %= 4;\n\nconsole.log(modulo)//asignacionSimple es 25 (20 + 5)\n\n//asignacion de exponenciacion\n\nlet exponenciacion = 10;\n\nexponenciacion **= 4;\n\nconsole.log(exponenciacion)//asignacionSimple es 25 (20 + 5)\n\n\n//asignacion de  desplazamiento a la izquierda \n\nlet x = 5;\n\nx <<= 1;\n\nconsole.log(x)\n\n//asignacion de  desplazamiento a la derecha\n\nlet y = 5;\n\ny >>= 1;\n\nconsole.log(y);\n\n//asignacion de  desplazamiento a la derecha con relleno cero \n\n\nlet y1 = 5;\n\ny1 >>>= 1;\n\nconsole.log(y1);\n\n//asignacion and a nivel de bits\n\n\nlet y2 = 5;\n\ny2 &= 1;\n\nconsole.log(y2);\n\n//asignacion OR a nivel de bits\n\n\nlet y3 = 5;\n\ny3 |= 6;\n\nconsole.log(y3);\n\n//asignacion XOR a nivel de bits\n\n\nlet y4 = 5;\n\ny4 ^= 6;\n\nconsole.log(y4);\n\n//---------------------operadores de identidad-----------------------------\n\n\n//igualdad estricta\n\nlet igual1 = 15;\nlet igual2 = 13;\n\nif (igual1 === igual2){\n    console.log(\"son iguales\");\n}else{\n    console.log(\"no es igual\");//no son iguales \n};\n\n//desigualdad estricta\n\nlet desigualdad = 15;\nlet desigualdad1 = 13;\n\nif (igual1 !== igual2){\n    console.log(\"son iguales\");//son iguales \n}else{\n    console.log(\"no es igual\");\n};\n\n//-----------------------------operadores de pertenencia-----------------------------\n\n//in\n// se usa para verificar una propiedad en un array u objeto \n\nconst persona = {\nnombre: \"juan carlos\",\nedad:56\n};\n\nif (`nombre` in persona){\n    console.log(\"la propiedad nombre si existe\")\n}else{\n    console.log(\"la propiedad nombre no existe\")\n};\n\n//intanceof \n\n//se usa para verificar si un objeto es una instancia de una clase o contructor especifico \n\nlet fecha = new Date();\nlet esFecha = fecha instanceof  Date;\n\nconsole.log(esFecha);\n\n//------------------------------operadores de bits---------------------------------------------------------------\n\n\nlet a2 = 5;  // 0101 en binario\nlet b2 = 3;  // 0011 en binario\n\nlet andBits = a2 & b2;  // AND de bits (0001 -> 1)\nlet orBits = a2 | b2;   // OR de bits (0111 -> 7)\nlet xorBits = a2 ^ b2;  // XOR de bits (0110 -> 6)\nlet notBits = ~a2;     // NOT de bits (complemento de 2, 1010 -> -6)\nlet desplazaIzquierda = a2 << 1; // Desplazamiento a2 la izquierda (1010 -> 10)\nlet desplazaDerecha = a2 >> 1;   // Desplazamiento a la derecha (0010 -> 2)\n\n\n\n//---------- --------------------------dificultad--------------------------------------------------\n\n/* DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n\nfor (let i = 10; i < 56 ; i++){//usamos  un  ciclo for creamos la variable indice igualando a 10, si i e menor a 56 , i aumentara hasta 55\n    if(i === 16){//si i es igual a 16\n        continue;//se salta ese numero \n    }if(i % 3 === 0){//si i es multiplo de 3 \n        continue;//se salta el numero\n    }\n    console.log(i)\n};\n\n//gracias por su atencion\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/SergioGI99.js",
    "content": "/*\nEJERCICIO:\n- Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n  Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n  (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n- Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n  que representen todos los tipos de estructuras de control que existan\n  en tu lenguaje:\n  Condicionales, iterativas, excepciones...\n- Debes hacer print por consola del resultado de todos los ejemplos.\nDIFICULTAD EXTRA (opcional):\nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n*/\n\n//Ejercicio\n\n    //Operadores\n    console.log('OPERADORES')\n\n    //Aritméticos\nconsole.log('- Operadores aritméticos');\n\nconsole.log(`${2 + 2}`);\nconsole.log(`${2 - 1}`);\nconsole.log(`${2 * 3}`);\nconsole.log(`${6 / 2}`);\nconsole.log(`${5 % 2}`);\nconsole.log(`${2 ** 3}`);\n\n    //Lógicos\nconsole.log('- Operadores lógicos');\n\nconsole.log(`${2 || true || false}`); //or (devuelve el primer true (En este caso 2))\nconsole.log(`${true && false}`); //and\nconsole.log(`${!true}`); //not\n\n    //Comparación\nconsole.log('- Operadores de comparación');\n\nconsole.log(`${2 < 5}`);\nconsole.log(`${2 <= 5}`);\nconsole.log(`${5 > 3}`);\nconsole.log(`${5 >= 3}`);\nconsole.log(`${2 == '2'}`);\nconsole.log(`${3 === \"3\"}`);\nconsole.log(`${2 != \"2\"}`);\nconsole.log(`${3 !== \"3\"}`);\n\n    //Asignación e identidad\nconsole.log('- Operadores de asignación e identidad');\n\nvar a = 2;\nvar b = 3;\nconsole.log(`${a}`); //a = 2\nconsole.log(`${a += b}`); //2 + 3 = 5 = a\nconsole.log(`${a -= b}`); //5 - 3 = 2 = a\nconsole.log(`${a *= b}`); //2 * 3 = 6 = a\nconsole.log(`${a /= b}`); //6 / 3 = 2 = a\nconsole.log(`${b %= a}`); //3 % 2 = 1 = a\nb = 3;\nconsole.log(`${a **= b}`); //2 ** 3 = 8 = a\nconsole.log(`${a === 8}`) // Identidad\n\n    //Cadena\nconsole.log('- Operador de cadena');\n\nconsole.log('Sergio' + ' ' + 'García');\n\n    //Ternario\nconsole.log('- Operador ternario');\n\nconsole.log((20 < 10) ? \"20 es menor que 10\" : \"20 no es menor que 10\");\n\n    //Pertenencia\nconsole.log('- Operador de pertenencia')\n\nvar myArray = [1, 2, 3, 4, 5]\nconsole.log(3 in myArray)\n\n    //Tipos\nconsole.log('- Operadores de tipos');\n\nvar myVariable = [\"Sergio\", \"David\"];\nconsole.log(typeof myVariable);\nconsole.log(myVariable instanceof Array); //True si un objeto es una instancia de otro objeto\n\n    //Bits\nconsole.log('- Operadores de bits');\n\nconsole.log(5 & 3); //AND a nivel de bits: 1\nconsole.log(5 | 3); //OR a nivel de bits: 7\nconsole.log(5 ^ 3); //XOR a nivel de bits: 6\n\n//Estructuras de control\nconsole.log('ESTRUCTURAS DE CONTROL');\n\n    //Condicionales\nconsole.log('- Condicionales');\n\nlet myName = \"Sergio\";\n\nif (myName == \"Jose\") {\n    console.log('Me llamo Jose');\n} else if (myName == \"Sergio\") {\n    console.log('Me llamo Sergio');\n} else {\n    console.log('No me llamo Jose ni Sergio');\n};\n\n    //Switch\nconsole.log(\"- Switch\");\n\nswitch (myName) {\n    case \"Jose\":\n        console.log(\"Me llamo Jose\");\n    case \"Sergio\":\n        console.log(\"Me llamo Sergio\");\n};\n\n    //Bucles For\nconsole.log(\"- Bucles for\");\n\nfor (let i = 1; i <= 5; i++) {\n    console.log(i);\n};\n\nconsole.log(\"- Bucles for/of\");\n\nfor (item of myArray) {\n    console.log(item);\n};\n\nconsole.log(\"- Bucle for/in\");\nlet myPerson = {\n    name: \"Sergio\",\n    surname: \"García\",\n    age: 24,\n    languages: [\n        \"Python\",\n        \"JavaScript\"\n    ]\n};\n\nfor (item in myPerson) {\n    console.log(`${item}: ${myPerson[item]}`);\n};\n\nconsole.log(\"- Bucle forEach\");\n\nmyArray.forEach(element => {\n    console.log(element);\n});\n\n    //Bucles while\nconsole.log(\"- Bucle while\");\n\nlet i = 0;\nlet max = 5;\n\nwhile (i <= max) {\n    console.log(i);\n    i += 1;\n};\n\nconsole.log(\"- Bucle do/while\")\n\nlet e = 0;\n\ndo {\n    console.log(e)\n    e++;\n} while (e <= max);\n\n//Extra\nconsole.log(\"EXTRA\");\n\nfor (let i = 10; i <= 55; i++) {\n    if (i % 2 == 0 & i != 16 & i % 3 != 0) {\n        console.log(i);\n    }\n};"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/SingularPigeon.js",
    "content": "let a = 15\nlet b = 7\n\n//operadores aritméticos\nlet suma = a + b;\nlet resta = a - b;\nlet multiplicacion = a * b;\nlet division = a / b;\nlet modulo = a % b;\nlet exponente = a ** b;\nlet raizCuadrada = Math.sqrt(a);\nlet raizCubica = Math.pow(a, 1/3);\n\nconsole.log(suma);\nconsole.log(resta);\nconsole.log(multiplicacion);\nconsole.log(division);\nconsole.log(modulo);  // 5\n\n// operadores de comparación\n\nconsole.log (a == b); // comparador de igualdad\nconsole.log (a === b); // comparador extrictamente igual\nconsole.log (a != b); // comparador de desigualdad\nconsole.log (a > b );// mayor que\nconsole.log (a < b );// menor que\nconsole.log (a >= b); // mayor o igual que\nconsole.log (a <= b); // menor o igual que\n\n\n// operadores lógicos\n\nconsole.log(a + b == 22 && 22 > 7); // and &&\nconsole.log((a + b ) > 10 || (a - b) > 30) ;// or ||\nconsole.log(!(a + b == 22));// not !\n\n// operadores de asignación\nlet c = 6\nlet d = 4\nc = d; // asignación\nconsole.log(c)\nc += d; // suma y asignación\nconsole.log(c)\nc -= d; // resta y  asignación\nconsole.log(c)\nc *= d; // multiplicación y asignación\nconsole.log(c)\nc /= d; // división y asignación\nconsole.log(c)\nc %= d; // módulo y asignación\nconsole.log(c)\nc **= d; //exponente y asignación\nconsole.log(c)\n\n\n// operadores de bit a bit\nconsole.log(a & b); // AND Devuelve un uno en cada posición del bit para los que los bits correspondientes de ambos operandos son unos \nconsole.log(a | b); // OR Devuelve un cero en cada posición de bit para el cual los bits correspondientes de ambos operandos son ceros.\nconsole.log(a ^ b); // XOR Devuelve un cero en cada posición de bit para la que los bits correspondientes son iguales. [Devuelve uno en cada posición de bit para la que los bits correspondientes son diferentes].\nconsole.log(~a); // NOT Invierte los bits de su operando.\nconsole.log(a << 2); // Desplaza a en representación binaria b bits hacia la izquierda, desplazándose en ceros desde la derecha.\nconsole.log(a >> 2); // Desplaza a en representación binaria b bits a la derecha, descartando los bits desplazados.\nconsole.log(a >>> 2); // Desplaza a en representación binaria b bits hacia la derecha, descartando los bits desplazados y desplazándose en ceros desde la izquierda.\n\n\n\n// operadores de cadena\nlet nombre = \"Singular\";\nlet apellido = \"Pigeon\";\nconsole.log(\"Singular\" + \"Pigeon\");\n\nlet frase = \"Super\"\nfrase += \"califragilistico\"\nconsole.log(frase);\n\n//operador condicional ternario\nlet x = a > b ? \"a es mayor que b\" : \"a es menor o igual que b\";\nconsole.log(x);\n\n// devuelve una cadena que indica el tipo de operando\nconsole.log(typeof 35); // number\nconsole.log(typeof \"cadena\"); // string\n\n/*\nCrea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n */\nfor ( let i = 10; i <= 55; i++) {\n  if ( i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n    console.log(i);\n    //\n  }\n   \n}\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/Sjho-406.js",
    "content": "//#1\n\nlet x = 10\nlet y = 5\n\n//Operaciones aritméticas\nlet suma = x + y //15\nlet resta = x - y // 5\nlet multiplicacion = x * y //50\nlet division = x / y // 2\nlet modulo = x % y // 0\n\n//Operaciones de comparacion\nlet esMayor = x > y // True\nlet esMenor = x < y // False\n\n//Operadores lógicos\nlet ambosVerdaderos = esMayor && esMenor // False\nlet algunoVerdadero = esMayor || esMenor // True\n\n//operador ternario\nlet mensaje = x > y ? 'x es mayor que y' : 'y es mayor o igual que x'\n\n//#2\n\n//if - else if - else\nlet edad = 18\n\nif (edad > 18) {\n    console.log('Puedes pasar')\n} else if (edad == 17) {\n    console.log('Podemos hacer una exepción')\n} else {\n    console.log('No puedes pasar')\n}\n\n//switch\nlet dia = 'viernes'\n\nswitch (dia) {\n    case 'lunes':\n    case 'martes':\n    case 'miercoles':\n    case 'jueves':\n    case 'viernes':\n        console.log('Dia laborable');\n        break;\n    case 'sabado':\n    case 'domingo':\n        console.log('Fin de semana');\n        break;\n}\n\n//Bucle while\nlet i = 0\n\nwhile(i < 10){\n    console.log(i)\n    i++\n}\n\n//Bucle do while\nlet I = 0\n\ndo{\n    console.log(I)\n    i++\n}while(I < 5)\n\n//Bucle for\nfor(let i = 0; i < 7; i++){\n    console.log(i)\n}\n\n//Ejercicio EXTRA\nfor (let i = 10; i <= 55; i++) {\n    if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n        console.log(i)\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/Sve-nnN.js",
    "content": "//Declaracion de variables\nlet a = 1;\nconst b = 5;\nvar c = 10;\nlet num = 55;\n//Esctructuras de control\nwhile(a < b){\n  //Mientras que A sea menor que B, imprime A\n  console.log(a);\n  a++;\n}\nfor(var i=0;i<=b;i++){\n  //Imprime del 0 al 5\n  console.log(i);\n}\nif(b%2==0){\n  //Si B es Par, imprime que es par\n  console.log(\"B es par\");\n}else {\n  //Si B es impar, imprime que es impar\n  console.log(\"B es impar\");\n}\n//Dificultad extra\nfor(var i=10;i<=num;i++){\n  if(i%2==0 && i!=16 && i%3!=0){\n    console.log(i);\n  }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/TasyMed.js",
    "content": "// #01 OPERADORES Y ESTRUCTURAS DE CONTROL\n\n// Numeros usados en las operaciones\nlet numero1 = 10;\nlet numero2 = 5;\n\n// Operadores Aritméticos\nlet suma = numero1 + numero2; // Suma\nconsole.log(\"Suma:\", suma); // 15\n\nlet resta = numero1 - numero2; // Resta\nconsole.log(\"Resta:\", resta); // 5\n\nlet multiplicacion = numero1 * numero2; // Multiplicación\nconsole.log(\"Multiplicación:\", multiplicacion); // 50\n\nlet division = numero1 / numero2; // División\nconsole.log(\"División:\", division); // 2\n\nlet modulo = numero1 % numero2; // Módulo - Da el residuo  de una divicion\nconsole.log(\"Módulo:\", modulo); // 0\n\nnumero1++; // Incremento\nconsole.log(\"Incremento de numero1:\", numero1); // 11\n\nnumero2--; // Decremento\nconsole.log(\"Decremento de numero2:\", numero2); // 4\n\n// Operadores de Asignación\n\nnumero1 += numero2; // Suma y asigna\nconsole.log(numero1); // 15\n\nnumero1 -= numero2; // Resta y asigna\nconsole.log(numero1); // 10\n\nnumero1 *= numero2; // Multiplica y asigna\nconsole.log(numero1); // 50\n\nnumero1 /= numero2; // Divide y asigna\nconsole.log(numero1); // 10\n\nnumero1 %= numero2; // Módulo y asigna\nconsole.log(numero1); // 0\n\n// Operadores de Comparación\n\nlet igual = numero1 == numero2; // Igual a\nconsole.log(igual); // false\n\nlet estrictoIgual = numero1 === numero2; // Igual estricto a\nconsole.log(estrictoIgual); // false\n\nlet distinto = numero1 != numero2; // Distinto a\nconsole.log(distinto); // true\n\nlet estrictoDistinto = numero1 !== numero2; // Distinto estricto a\nconsole.log(estrictoDistinto); // true\n\nlet mayor = numero1 > numero2; // Mayor que\nconsole.log(mayor); // false\n\nlet menor = numero1 < numero2; // Menor que\nconsole.log(menor); // false\n\nlet mayorIgual = numero1 >= numero2; // Mayor o igual que\nconsole.log(mayorIgual); // true\n\nlet menorIgual = numero1 <= numero2; // Menor o igual que\nconsole.log(menorIgual); // true\n\n// ---- Operadores ----\n\n/*\nUsamos los mismos numeros\nlet numero1 = 10;\nlet numero2 = 5;\n*/\n\n// 1. Condicionales (if, else if, else)\nif (numero1 > numero2) {\n    console.log(\"numero1 es mayor que numero2\");\n} else if (numero1 < numero2) {\n    console.log(\"numero1 es menor que numero2\");\n} else {\n    console.log(\"Ambos números son iguales\");\n}\n\n// 2. Switch-case\nlet operacion = \"+\";\nswitch (operacion) {\n    case \"+\":\n        console.log(\"Suma:\", numero1 + numero2);\n        break;\n    case \"-\":\n        console.log(\"Resta:\", numero1 - numero2);\n        break;\n    default:\n        console.log(\"Operación no reconocida\");\n}\n\n// 3. Bucle while\nlet contador = 0;\nwhile (contador < 3) {\n    console.log(contador); //El numero en el que va\n    contador++;\n}\n\n// 4. Bucle do-while\ncontador = 0;\ndo {\n    console.log(contador); //El numero en el que va\n    contador++;\n} while (contador < 3);\n\n// 5. Bucle for\nfor (let i = 0; i < 3; i++) {\n    console.log(i); //El numero en el que va\n}\n\n// ---- RETO ----\n\nlet NumeroReto1 = 10;\nlet NumeroReto2 = 55;\n\nfor (let x = NumeroReto1; x <= NumeroReto2; x++) {\n    if (x % 2 !== 0) {  \n        continue;  // Salta los impares\n    } else if (x === 16) {  \n        continue;  // Salta el 16\n    } else if (x % 3 === 0) {  \n        continue;  // Salta los múltiplos de 3\n    } else {  \n        console.log(x);  // Imprime los números que cumplen las condiciones\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/TizoG.js",
    "content": "// Ejemplos de Operadores\n\nconsole.log(1 + 1) // Suma\nconsole.log(1 - 1) // Resta\nconsole.log(2 * 2) // Multiplicacion\nconsole.log(2 / 2) // Division\nconsole.log(5 % 2) // Modulo\nconsole.log(2 ** 2) // Potenciacion\n\n// Operaciones con enteros\n\nconsole.log(3 < 2)\nconsole.log(3 <= 2)\nconsole.log(3 > 2)\nconsole.log(3 >= 2)\nconsole.log(3 == 2)\nconsole.log(3 === 2)\nconsole.log(3 != 2)\n\n// Operadores logicos\nconsole.log(3 < 2 && \"hola\" < \"mundo\")\nconsole.log(3 < 2 || \"hola\" < \"mundo\")\nconsole.log(!false)\n\n// Operadores de asignacion\nlet myNumber = 1\nconsole.log(myNumber)\nmyNumber += 1\nconsole.log(myNumber)\nmyNumber -= 1\nconsole.log(myNumber)\nmyNumber *= 1\nconsole.log(myNumber)\nmyNumber /= 1\nconsole.log(myNumber)\nmyNumber %= 1\nconsole.log(myNumber)\nmyNumber **= 1\nconsole.log(myNumber)\n\n\n// Incremento\nmyNumber++\n// Decremento\nmyNumber--\n\n/*\nEstructuras de control\n*/\n// Condicionales\nlet myName = \"TizoG\"\nif (myName == \"TizoG\") {\n    console.log(\"myName es 'TizoG'\")\n} else if(myName == \"tizog\"){\n    console.log(\"myName es 'tizog'\")\n} else{\n    console.log(\"miName no es 'TizoG' ni 'tizog'\")\n}\n\n// Iteracion\nfor (let i = 0; i < 10; i++){\n    console.log(`El valor actual de i es ${i}`)\n}\n\n// Manejo de excepciones\ntry{\n    console.log(\"Primero se ejecutara este bloque\")\n}catch{\n    console.log(\"Este bloque se ejecutara si en el bloque primero ocurre un error\")\n}finally{\n    console.log(\"Finalmente se ejecutara este bloque de codigo\")\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/TofeDev.js",
    "content": "//Asignaciones\nlet a = 200\nlet b = 40\n\n//Operadores aritméticos\nsuma = a + b\nconsole.log(\"Suma a + b: \" + suma)\nresta = a - b\nconsole.log(\"Resta a - b: \" + resta)\nmultiplicacion = a * b\nconsole.log(\"Multiplicación a * b: \" + multiplicacion)\ndivision = a / b\nconsole.log(\"División a / b: \" + division)\nresto = a % b\nconsole.log(\"Resto a % b: \" + resto)\n\n//Asignación compuesta\nsuma += a \nconsole.log(\"suma = suma + a: \" + suma)\nresta -= a \nconsole.log(\"resta = resta - a: \" + resta)\nmultiplicacion *= a \nconsole.log(\"multiplicacion = multiplicacion * a: \" + multiplicacion)\ndivision /= a \nconsole.log(\"division = division / a: \" + division)\nresto %= a \nconsole.log(\"resto = resto % a: \" + resto)\n\n//Operadores lógicos\nAND = (a < b) && (b === 0)\nconsole.log(\"¿Es a menor que b, Y b igual a 0?: \" + AND)\nOR = (a > b) || (b === 0)\nconsole.log(\"¿Es a mayor que b, O b igual a 0?: \" + OR)\nNOT = !(a < b)\nconsole.log(\"Negación a menor que b: \" + NOT)\n\n//Operadores de comparación \nigual = (a === b)\nconsole.log(\"Es igual: \" + igual)\ndistinto = (a !== b)\nconsole.log(\"Es distinto: \" + distinto)\nmayor = (a > b)\nconsole.log(\"Es mayor: \" + mayor)\nmayorIgual = (a >= b)\nconsole.log(\"Es mayor o igual: \" + mayorIgual)\nmenor = (a < b)\nconsole.log(\"Es menor: \" + menor)\nmenorIgual = (a <= b)\nconsole.log(\"Es menor o igual: \" + menorIgual)\n\n//Estructuras condicionales\n//IF - ELSE \nlet edad = 18\n\nif (edad >= 18) {\n  console.log(\"Eres mayor de edad\")\n} else {\n  console.log(\"Eres menor de edad\")\n}\n\n// IF ELSE \nif (edad > 18) {\n  console.log(\"Eres mayor de edad\")\n} else if (edad === 18) { \n  console.log(\"Tienes la edad justa\")\n} else {\n  console.log(\"Eres menor de edad\")\n}\n\n//SWITCH \nlet comision = \"A\"\nswitch (comision) {\n  case 'A':\n    console.log(\"Eres de la comisión A\")\n    break;\n  case \"B\":\n    console.log(\"Eres de la comisión B\")\n    break;\n  case \"C\":\n    console.log(\"Eres de la comisión C\")\n    break;\n  default:\n    console.log(\"Comisión inválida\")\n}\n\n//Estructuras iterativas\nlet num = 200\n\n// FOR\nfor (i = 1; i <= 5; i++) {\n    num+=2\n    console.log(num)\n}\n\n//WHILE\nwhile (num < 300) {\n    num+=5\n    console.log(num)\n}\n\n// DO WHILE\ndo {\n    num+=10\n    console.log(num)\n} while (num < 350);\n\n// Try catch\ntry {\n    let divError = 5 / 0;\n    console.log(\"Resultado: \", divError);\n} catch (error) {\n    console.log(\"Error: \", error.message);\n} finally {\n    console.log(\"Se finalizó la ejecución, con error o no\");\n}\n\n/* DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\nfor (i = 10; i <= 55; i++) {\n    if ((i % 2 == 0) && (i !== 16) &&(i % 3 !== 0)) {\n        console.log(i)\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/TomasMarquez81.js",
    "content": "/*\r\n * EJERCICIO:\r\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\r\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\r\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\r\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\r\n *   que representen todos los tipos de estructuras de control que existan\r\n *   en tu lenguaje:\r\n *   Condicionales, iterativas, excepciones...\r\n * - Debes hacer print por consola del resultado de todos los ejemplos.\r\n *\r\n * DIFICULTAD EXTRA (opcional):\r\n * Crea un programa que imprima por consola todos los números comprendidos\r\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\r\n *\r\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\r\n */\r\n\r\n/**** OPERADORES ****/\r\n\r\n// Operadores aritméticos\r\nconsole.log(`Suma: 10 + 3 = ${10 + 3}`);\r\nconsole.log(`Resta: 10 - 3 = ${10 - 3}`);\r\nconsole.log(`Multiplicación: 10 X 3 = ${10 * 3}`);\r\nconsole.log(`Division: 9 / 3 = ${9 / 3}`);\r\nconsole.log(`Módulo: 10 % 3 = ${10 % 3}`);\r\nconsole.log(`Exponente: 10 ** 3 = ${10 ** 3}`);\r\n\r\n// Operadores de comparación\r\nconsole.log(`Igualdad: 10 == 3: ${10 == 3}`);\r\nconsole.log(`Igualdad: 10 == 10: ${10 == 10}`);\r\nconsole.log(`Desigualdad: 10 != 3: ${10 != 3}`);\r\nconsole.log(`Desigualdad: 10 != 10: ${10 != 10}`);\r\nconsole.log(`Mayor que: 10 > 3: ${10 > 3}`);\r\nconsole.log(`Menor que: 10 < 3: ${10 < 3}`);\r\nconsole.log(`Mayor o igual que: 10 >= 3: ${10 >= 3}`);\r\nconsole.log(`Menor o igual que: 10 <= 3: ${10 <= 3}`);\r\n\r\n// Operadores lógicos\r\nconsole.log(\r\n  `AND &&: 10 + 3 == 13 && 5 - 1 == 4: ${10 + 3 == 13 && 5 - 1 == 4}`\r\n);\r\nconsole.log(`OR ||: 10 + 3 == 13 || 5 - 2 == 4: ${10 + 3 == 13 || 5 - 2 == 4}`);\r\nconsole.log(`NOT !: !10 + 4 == 13: ${!(10 + 4 == 13)}`);\r\n\r\n// Operadores de asignación\r\nlet my_number = 11; // Asignación\r\nconsole.log(my_number);\r\nmy_number += 1; // Suma y asignación\r\nconsole.log(my_number);\r\nmy_number -= 1; // Resta y asignación\r\nconsole.log(my_number);\r\nmy_number *= 2; // Multiplicación y asignación\r\nconsole.log(my_number);\r\nmy_number /= 2; // División y asignación\r\nconsole.log(my_number);\r\nmy_number %= 2; // Módulo y asignación\r\nconsole.log(my_number);\r\nmy_number **= 3; // Exponente y asignación\r\nconsole.log(my_number);\r\n\r\n// Operadores de identidad\r\nlet my_new_number = 1;\r\nconsole.log(\r\n  `my_number es estrictamente igual a my_new_number es: ${\r\n    my_new_number === my_number\r\n  }`\r\n); // Compara no solo el valor también el tipo de dato\r\nmy_number = \"1\";\r\nconsole.log(\r\n  `my_number es estrictamente igual a my_new_number es: ${\r\n    my_new_number === my_number\r\n  }`\r\n); // Compara no solo el valor tambien el tipo de dato\r\n\r\nconsole.log(\r\n  `my_number es estrictamente desigual a my_new_number es: ${\r\n    my_new_number !== my_number\r\n  }`\r\n); // Compara no solo el valor tambien el tipo de dato\r\nmy_number = 1;\r\nconsole.log(\r\n  `my_number es estrictamente desigual a my_new_number es: ${\r\n    my_new_number !== my_number\r\n  }`\r\n); // Compara no solo el valor tambien el tipo de dato\r\n\r\n// Operadores de bit\r\nlet a = 10; // 1010\r\nlet b = 3; // 0011\r\nconsole.log(`AND: 10 & 3 = ${a & b}`); // 0010\r\nconsole.log(`OR: 10 | 3 = ${a | b}`); // 1011\r\nconsole.log(`XOR: 10 ^ 3 = ${a ^ b}`); // 1001\r\nconsole.log(`NOT: ~10 = ${~a}`); // 0101\r\nconsole.log(`Desplazamiento a la derecha: 10 >> 2  ${a >> 2}`); // 0010\r\nconsole.log(`Desplazamiento a la izquierda: 10 << 2  ${a << 2}`); // 101000\r\n\r\n// Estructura de control\r\n\r\n// Condicionales\r\n\r\nlet my_string = \"Raton\";\r\nif (my_string == \"Raton\") {\r\n  console.log(my_string);\r\n} else if (my_string == \"Gato\") {\r\n  console.log(my_string);\r\n} else {\r\n  console.log(\"Perro\");\r\n}\r\n\r\n// Iterativas\r\n\r\nfor (let i = 0; i < 11; i++) {\r\n  console.log(i);\r\n}\r\n\r\ni = 0;\r\nwhile (i <= 10) {\r\n  console.log(i);\r\n  i++;\r\n}\r\n\r\n// Manejo de excepciones\r\n\r\ntry {\r\n  console.lot(10 / 0);\r\n} catch (error) {\r\n  console.log(\"Error en el programa\");\r\n} finally {\r\n  console.log(\"Se ha finalizado el manejo de excepciones\");\r\n}\r\n\r\n// DIFICULTAD EXTRA\r\n\r\n/*Crea un programa que imprima por consola todos los números comprendidos\r\n  entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.*/\r\n\r\nfor (let i = 10; i < 56; i++) {\r\n  if (i % 2 == 0 && i != 16 && i % 3 != 0) {\r\n    console.log(i);\r\n  }\r\n}\r\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/UserMatthew.js",
    "content": "// #01 OPERADORES Y ESTRUCTURAS DE CONTROL\n\n// ## Ejercicio\n\n// Asignacion de varialbes\n\nlet num1 = 25;\nlet num2 = 5;\n\nconsole.group(\"Operadores Aritméticos\");\n// Operadores Aritméticos de JavaScript\n// Operador de Suma\nconst suma = num1 + num2;\nconsole.log(`La suma de los numeros ${num1} + ${num2} es igual a ${suma}`);\n// Operador de Resta\nconst resta = num1 - num2;\nconsole.log(`La resta de los numeros ${num1} - ${num2} es igual a ${resta}`);\n// Operador de Multiplicación\nconst multiplicacion = num1 * num2;\nconsole.log(\n  `La multiplicacion de los numeros ${num1} x ${num2} es igual a ${multiplicacion}`\n);\n// Operador de division\nconst division = num1 / num2;\nconsole.log(\n  `La division de los numeros ${num1} / ${num2} es igual a ${division}`\n);\n// Operador de modulo o resto\nconst modulo = num1 % num2;\nconsole.log(`El resto de la division de ${num1} entre ${num2} es ${modulo}`);\n// Operador de exponencial\nconst exp = num1 ** 2;\nconsole.log(`El numero ${num1} elevado a la ${num2} es igual a ${exp}`);\n// (Las varibales deben estar guardadas en let de lo contrario no podra incrementar o decrementar al ser constante)\n// Operador de incremento\nnum1++;\nconsole.log(`El numero incrementado +1 es ${num1}`);\n// Operador de decremento\nnum2--;\nconsole.log(`El numero decrementado -1 es ${num2}`);\n\nconsole.groupEnd(\"Operadores Aritméticos\");\n\nconsole.group(\"Operadores de asignación\");\n// Operadores de asignación de JavaScript\n// Operador de asignación\nlet i = 5;\nnum1 = 45;\nconsole.log(` Asignacion ${num1}`);\n// Operador de asignacion de adición\nnum1 = num1 + i; // Forma significativa\nconsole.log(`Asignacion de suma significativa${num1}`);\nnum1 += i; // Forma abrevidada\nconsole.log(`Asignacion de suma abrevidada${num1}`);\n// Operador de asignacion de resta\nnum1 = num1 - i; // Forma significativa\nconsole.log(`Asignacion de resta significativa${num1}`);\nnum1 -= i; // Forma abrevidada\nconsole.log(`Asignacion de resta abreviada${num1}`);\n// Operador de asignacion de multiplicación\nnum1 = num1 * i; // Forma significativa\nconsole.log(`Asignacion de multiplicacion significativa${num1}`);\nnum1 *= i; // Forma abrevidada\nconsole.log(`Asignacion de multiplicacion abreviada${num1}`);\n// Operador de asignacion de division\nnum1 = num1 / i; // Forma significativa\nconsole.log(`Asignacion de division significativa${num1}`);\nnum1 /= i; // Forma abrevidada\nconsole.log(`Asignacion de division abreviada${num1}`);\n// Operador de asignacion de módulo o resto\nnum1 = num1 % i; // Forma significativa\nconsole.log(`Asignacion de módulo significativa${num1}`);\nnum1 %= i; // Forma abrevidada\nconsole.log(`Asignacion de módulo abreviada${num1}`);\n// Operador de asignacion de exponente\nnum1 = num1 ** i; // Forma significativa\nconsole.log(`Asignacion de exponente significativa${num1}`);\nnum1 *= i; // Forma abreviada\nconsole.log(`Asignacion de exponente abreviada${num1}`);\n\nconsole.groupEnd(\"Operadores de Asignación\");\n\nconsole.group(\"Operadores de comparación\");\n// Operadores de comparación\nlet a = 25;\nlet b = \"25\";\n\n// Operador de igualdad\nconsole.log(a == b); // Devuelve true si es igual en dato o valor\n// Operador de igualdad estrictamente\nconsole.log(a === b); // Devuelve true si es igual en dato y valor\n// operador de desigualdad\nconsole.log(a != b); // Devuelve true si es desigual en dato o valor\n// Operador de desigualdad estrictamente\nconsole.log(a !== b); //Devuelve true si es desigualdad en dato y valor\n// Operador de mayor que\nconsole.log(a > b); // Devuelve true si a es mayor que b\n// Operador de menor que\nconsole.log(a < b); // Devuelve true si a es mayor que b\n// operador de mayor o igual que\nconsole.log(a >= b); // Devuelve true si a es mayor o igual que b\n// Operador de menor o igual que\nconsole.log(a <= b); // Devuelve true si a es menor o igual que b\nconsole.groupEnd(\"Operadores de comparación\");\n\nconsole.group(\"Operadores logicos\");\n// Operador AND &&\nconsole.log(5 === 5 && 5 === 5); // Devuelve true si ambas condiciones son verdad\n// Operador OR ||\nconsole.log(5 === 6 || 7 === 7); // Devuelve true si una de las dos condiciones es verdad\n// Operador NOT !\nlet c = true;\nconsole.log(!c); // Devuelve false si c es true, y true si c es false\nconsole.groupEnd(\"Operadores logicos\");\n\nconsole.group(\"Operador condeicional ternario \");\n\nlet d = 5;\nconsole.log(d % 2 === 0 ? \"Par\" : \"Impar\");\n\nconsole.groupEnd(\"Operador condeicional ternario \");\n\n// Estructura de control\n// Estructura iterativa for\nfor (i = 1; i < 11; i++) {\n  console.log(` 2 x ${i} = ${i * 2}`);\n}\n\n// Estructura iterativa FOR mezclada con estura condeicional IF\nfor (i = 1; i < 101; i++) {\n  if (i % 2 === 0) {\n    console.log(`El numero ${i} es par`);\n  } else if (i % 2 !== 0) {\n    console.log(`El numero ${i} es impar`);\n  }\n}\n\n// Estructura iterativa WHILE\nlet j = 1;\nwhile (j < 101) {\n  console.log(`El numero es ${j}`);\n  j++;\n}\n\n/* EJERCICIO EXTRA\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n */\n\nlet array = [];\nfunction numerosComprendidos(base, limite) {\n  for (let i = base; i < limite; i++) {\n    if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n      array.push(i);\n    }\n  }\n}\n\nnumerosComprendidos(10, 55);\nconsole.log(array);\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/VictorSschz.js",
    "content": "let suma = 2+2;\nconsole.log('La suma es ' + suma)\nlet resta = 2-2;\nconsole.log('La resta es ' + resta)\nlet mult = 2*2;\nconsole.log('La mult es ' + mult)\nlet division = 2/2;\nconsole.log('La division es ' + division)\nlet resto = 2%2;\nconsole.log('La resto es ' + resto)\n\nlet mayor = 10 > 9;\nconsole.log('Es mayor =' + mayor)\nlet menor = 10 < 11;\nconsole.log('Es menor =' + menor)\nlet menorOigual = 10 <= 11;\nconsole.log('Es menorOigual =' + menorOigual)\nlet mayorOigual = 10 >= 1;\nconsole.log('Es mayorOigual =' + mayorOigual)\n\nlet comparativo = 10 == \"10\";\nconsole.log('Es comparativo (no restrictivo )=' + comparativo)\nlet comparativo2 = 10 === \"10\";\nconsole.log('Es comparativo (no restrictivo )=' + comparativo2)\nlet distino = 10 != \"10\";\nconsole.log('Es distino (no restrictivo )=' + distino)\nlet distinto2 = 10 !== \"10\";\nconsole.log('Es distinto (resctrictivo)=' + distinto2)\n\nlet y = 10 === 10 && 2===2;\nconsole.log('Condicion && =' + y)\nlet o = 10 === 10 || 2===2;\nconsole.log('Condicion  || =' + o)\n\nlet x = 2;\nconsole.log('asignacion compuesta suma ' + (x+=2))\nlet r = 2;\nconsole.log('asignacion compuesta resta ' + (r-=2))\nlet m= 2;\nconsole.log('asignacion compuesta multiplicacion ' + (m=2))\nlet d= 2;\nconsole.log('asignacion compuesta division ' + (d*=2))\nlet restoC= 2;\nconsole.log('asignacion compuesta resto ' + (restoC*=2))\n\nfor(let i=10; i<=55;i++){\n    if(i%2 ===0){\n        if(i=== 16 || i%3 === 0){\n            continue;\n        }\n        console.log(i);\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/Vixito.js",
    "content": "console.log(\"OPERADORES\");\n\n\nconsole.log(\"De asignación\\n\");\n\nlet a=2; let b=4; c=null; d=undefined; // asignación\nconsole.log(a+=b); // asignación de adición\nconsole.log(a-=b); // asignación de resta\nconsole.log(a&b); // asignación AND bit a bit\nconsole.log(a||b); // asignación OR lógico\nconsole.log(a??=b); // asignación de anulación lógica\nconsole.log(c, d);\n\nconsole.log(\"\\nDe comparación\\n\");\n\nconsole.log(\"Igualdad: \" + (a == b));\nconsole.log(\"Igualdad estricta: \" + (a === b));\nconsole.log(\"Diferente: \" + (a != b));\nconsole.log(\"Mayor o igual que: \" + (a >= b));\nconsole.log(\"Mayor que: \" + (a > b));\nconsole.log(\"Menor o igual que: \" + (a <= b));\nconsole.log(\"Menor que: \" + (a < b));\n\nconsole.log(\"\\nAritméticos\\n\");\n\nconst suma = a + b;\nconst resta = a - b;\nconst multiplicacion = a * b;\nconst division = a / b;\nconst potenciacion = a ** b;\nconst residuo = a % b;\nconsole.log(\"Suma: \"+suma+\"\\nResta: \"+resta+\"\\nMulitplicación \"+multiplicacion+\"\\nDivisión: \"+division+\"\\nPotenciación: \"+potenciacion+\"\\nResiduo: \"+residuo);\n\nconsole.log(\"\\nBit a bit\\n\");\n\nconsole.log(\"AND a nivel de bits: \"+(a & b));\nconsole.log(\"OR a nivel de bits: \"+(a | b));\nconsole.log(\"XOR a nivel de bits: \"+(a ^ b));\nconsole.log(\"NOT a nivel de bits: \"+(~ a));\nconsole.log(\"Desplazamiento a la izquierda: \"+(a << b));\nconsole.log(\"Desplazamiento a la derecha de propagación de signo: \"+(a >> b));\nconsole.log(\"Desplazamiento a la derecha de relleno 0: \"+(a >>> b));\n\nconsole.log(\"\\nLógicos\\n\");\n\nconsole.log(\"AND Lógico: \"+(b && a));\nconsole.log(\"OR Lógico: \"+(b || a));\nconsole.log(\"NOT Lógico: \"+(!b));\n\nconsole.log(\"\\nDe cadena\\n\");\n\nlet cadena = \"Ejemplo de \" + \"cadena\"; \nconsole.log(cadena);\ncadena += \" combinada\";\nconsole.log(cadena);\n\nconsole.log(\"\\nCondicional (ternario)\\n\");\n\n(a != b) ? console.log(a) : console.log(b);\n\nconsole.log(\"\\nComa\\n\");\n\nlet coma = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];\nconsole.log(coma);\n\nconsole.log(\"\\nUnarios\\n\");\n\nconsole.log(typeof a);\nconsole.log(typeof cadena);\nconsole.log(typeof null); // xd\n\nconsole.log(\"\\nRelacionales\\n\");\n\nconsole.log('PI' in Math); // in\n\n// ESTRUCTURAS DE DATOS\n\nif (cadena != null){\n    console.log(\"\\n\"+(a+b)+\"\\n\");\n} else{\n    console.log(\"\\n\"+(a-b)+\"\\n\");\n}\n\nwhile (b>=4 && b<=10){\n    console.log(`4 x ${b} = ${4*b}`);\n    b++;\n    // Tabla de multiplicar del 4 multiplicado por el rango del while\n}\n\nswitch (typeof a === 'number') {\n    case (true):\n        console.log(\"\\na es un número\\n\");\n        break;\n\n    default:\n        console.log(\"\\nNo lo es\\n\");\n        break;\n}\n\ntry{\n    zzz(\"Prueba del comando zzz\");\n} catch(error){\n    console.log(error.message);\n} finally{\n    console.log(\"Error diligenciado.\\n\");\n}\n\n// EJERCICIO EXTRA\nfor (let index = 10; index <= 55; index++) {\n    if (index % 2 === 0 && index != 16 && index % 3 !== 0) {\n        console.log(index);\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/VolumiDev.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n// ✅ Operadores aritméticos\nvar result = 2 + 2 // suma\nresult = 3 - 2// resta\nresult = 3 * 2// multiplicación\nresult = 6 / 2// división\nresult = 2 % 2// resto\nresult = 4 ** 2// exponenciación\nresult++// Incremeto\nresult--// decremento\n\n// ✅ Operadiores lógicos\nvar bol = true && false// Operador AND\nbol = true || false// Operador OR\nbol = !true// Operador de negación\n\n// ✅ Operadores de comparación\nbol = 3 == 3// igualdad\nbol = 3 != 4// desigual\nbol = 3 === '3'// igualdad estricta o de identidad\nbol = 3 !== '3'// desigualdad estricta\nbol = 4 < 5// menor que\nbol = 3 > 2// mayor que\nbol = 3 <= 3//menor o igual\nbol = 3 >= 3// mayor o igual\n\n// ✅ Operadores de asignación\nvar n1 = 2\nvar n2 = 5\nn1 = n2// asignacion\nn1 += n2// asignacion de adicion\nn2 -= n2// asignación de resta\nn1 *= n2// asignación de multiplicación\nn1 /= n2// asignación de división\nn1 %= n2// asignación de resto\nn1 **=// asignación de eexponenciación \nn1 <<= n2// asignación de desplazamiento a la izquierda\nn1 >>= n2// asignación de desplazamiento a la derecha\nn1 >>>= n2// asignación de desplazamiento a la izquierda sin signo\nn1 &= n2// asignación AND bit bit\nn1 ^= n2// asignación XOR bit a bit\nn1 |= n2// asignación OR bit a bit\nbol &&= bol// asignación AND lógico\nbol ||= bol// asignación OR lógico\nbol ??= bol// asignación de anulación lógica\nconsole.log(bol)\n\n// ✅  If:\nbol = true\nif (bol){\n  console.log('verdadero')\n}else {\n  console.log('falso')\n}\n\n// ✅ switch\nvar option = 3\nswitch (option) {\n  case 1:\n    console.log('Esta es la opcion 1')\n    break;\n  case 2:\n    console.log('Esta es la opcion 2')\n    break;\n  case 3:\n      console.log('Esta es la opcion 3')\n      break;\n  default:\n    console.log('Esta es la opcion cuando no es ninguna de las anteriores.')\n    break;\n}\n\n// ✅ while\nvar rep = 0 \nwhile (rep < 5){\n  console.log(`Estamos en la ronda ${rep}`)\n  rep ++\n}\n\n// ✅ do..while\ndo {\n  console.log(`Estamos en la ronda ${rep}`)\n  rep --\n} while (rep > 0);\n\n// ✅ for \nfor (let i = 0; i < 10; i++) {\n  console.log(`Estamos en un for en la iteracion ${i}`)\n}\n\n/**\n *  * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n * \n */\n\nvar num = 10 \nwhile(num <= 55){\n  if (num % 2 == 0 && num != 16 && num % 3 != 0){\n    console.log('Resultado: ',num)\n  }\n  num++\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/YgriegaSB.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n// Aritméticos\nlet a = 1;\nlet b = 2;\nlet suma = a + b;\nlet resta = a - b;\nlet multiplicacion = a * b;\nlet division = a / b;\nlet modulo = a % b;\nlet incremento = a++;\nlet decremento = a--;\n\nconsole.log('Suma = '+ suma);\nconsole.log('Resta = '+ resta);\nconsole.log('Multiplicación = '+ multiplicacion);\nconsole.log('División = '+ division);\nconsole.log('Módulo = '+ modulo);\nconsole.log('Incremento = '+ incremento);\nconsole.log('Decremento = '+ decremento);\n\n// Asignacion\n\na = b;\nconsole.log('a = b = '+ a);\na += 2;\nconsole.log('Suma a = '+ a);\na -= 2;\nconsole.log('Resta a = '+ a);\na *= 2;\nconsole.log('Multiplicación a = '+ a);\na /= 2;\nconsole.log('División a = '+ a);\n\n// Comparación e identidad\n\nconsole.log('a = '+a+' | b = '+ b);\nlet c = a > b;\nconsole.log('a mayor que b -> '+c);\nc = a < b;\nconsole.log('a menor que b -> '+c);\nc = a >= b;\nconsole.log('a mayor o igual que b -> '+c);\nc = a <= b;\nconsole.log('a menor o igual que b -> '+c);\nc = a == b;\nconsole.log('a igual que b -> '+c);\nc = a === b;\nconsole.log('a estrictamente igual que b -> '+c);\nc = a != b;\nconsole.log('a diferente que b -> '+c);\nc = a !== b;\nconsole.log('a estrictamente diferente que b -> '+c);\n\n// logicos\n\nlet combined = true && false;\nconsole.log('AND -> '+ combined);\ncombined = true || false;\nconsole.log('OR -> '+ combined);\ncombined = !true;\nconsole.log('NOT -> '+ combined);\n\n// Concatenar\n\nlet cadena1 = \"Hola \";\nlet cadena2 = \"mundo!\";\nlet concatenada = cadena1 + cadena2;\nconsole.log('Concatenación -> '+ concatenada);\n\n// operadores ternarios\n\nconsole.log(combined);\nlet resultado = combined===true? \"Si\" : \"No\";\nconsole.log('Operador ternario -> '+ resultado);\n\n// Tipos de datos\nconsole.log(typeof(combined));\nconsole.log(typeof(resultado));\n\n\n// propagacion \nconst numeros = [1, 2, 3, 4, 5];\nconsole.log(...numeros); // Salida: 1 2 3 4 5\n\nconst numeros2 = [6, 7, 8];\nconst numerosCombinados = [...numeros, ...numeros2];\nconsole.log(numerosCombinados); // Salida: [1, 2, 3, 4, 5, 6, 7, 8]\n\n\n// membresia\n\n    //in\n    const persona = { nombre: 'Juan', edad: 30 };\n\n    console.log('nombre' in persona); // true\n    console.log('apellido' in persona); // false\n\n    //instanceof\n    class Persona {\n        constructor(nombre) {\n            this.nombre = nombre;\n        }\n    }\n    \n    const juan = new Persona('Juan');\n\n    console.log(juan instanceof Persona); // true\n    console.log(juan instanceof Array); // false\n    \n// exponenciacion\nlet potencia = a ** 4;\nconsole.log(potencia);\n\n// bits \nlet x = 5; // Representación binaria: 0101\n\n// Operador &= (AND a nivel de bits y asignación)\nx &= 3; // Equivalente a: x = x & 3\n// 0101 & 0011 = 0001 (resultado: 1)\nconsole.log(x); // Salida: 1\n\n// Operador |= (OR a nivel de bits y asignación)\nx |= 8; // Equivalente a: x = x | 8\n// 0001 | 1000 = 1001 (resultado: 9)\nconsole.log(x); // Salida: 9\n\n// Operador ^= (XOR a nivel de bits y asignación)\nx ^= 12; // Equivalente a: x = x ^ 12\n// 1001 ^ 1100 = 0101 (resultado: 5)\nconsole.log(x); // Salida: 5\n\n// Operador <<= (desplazamiento a la izquierda y asignación)\nx <<= 2; // Equivalente a: x = x << 2\n// 0101 << 2 = 010100 (resultado: 20)\nconsole.log(x); // Salida: 20\n\n// Operador >>= (desplazamiento a la derecha y asignación)\nx >>= 1; // Equivalente a: x = x >> 1\n// 010100 >> 1 = 001010 (resultado: 10)\nconsole.log(x); // Salida: 10\n\n// Operador >>>= (desplazamiento a la derecha sin signo y asignación)\nx >>>= 1; // Equivalente a: x = x >>> 1\n// 001010 >>> 1 = 000101 (resultado: 5)\nconsole.log(x); // Salida: 5\n\n// Estructuras de control\n\n//if\nlet z = 26, y = 28;\nif(z < y) {\n    console.log('z es menor que y');\n} else {\n    console.log('No es menor que el');\n}\n\n// for\n\nconst animals = ['dog', 'cat', 'bird', 'horse']\nfor (let mascotas of animals) {\n    //console.log(mascotas);\n}\n\nfor (let i = 0; i <= animals.length; i++) {\n    //console.log(animals[i]);\n}\n\nfor (let name in animals) {\n    //console.log('Indice '+name);\n}\n\n// while\nlet i = 0;\nwhile(i < animals.length) {\n    //console.log(animals[i]);\n    i++;\n}\n\n// do while\nlet q = 0;\nconst nums = [29.8748, 30.1234, 30.1234, 3, 4, 5, 6, 7, 8, 9, 10]\ndo {\n    //console.log(nums[q]);\n    q++;\n} while (q < nums.length);\n\n// switch\nlet verdader = true;\nlet falso = false;\nlet input = undefined;\n\nswitch (input) {\n    case verdader:\n        console.log('Verdadero');\n        break;\n    case falso:\n        console.log('Falso');\n        break;\n    default:\n        console.log('No aplica');\n        break;\n}\n\n// try/catch\n\ntry {\n    let result = 10 / 0;\n    console.log(result);\n} catch (error) {\n    console.log(error.message); // Mostrará \"Division by zero\"\n} finally {\n    console.log('Final');\n}\n\n// DIFICULTAD EXTRA (opcional):\n// Crea un programa que imprima por consola todos los números comprendidos\n// entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\nconsole.log('\\nSTART PROGRAM\\n');\nconst output = [];\nconst programa = (i) => (i !== 16 && i % 3 !== 0 && i % 2 === 0) ? output.push(i) : null;\n\nfor (let i = 10; i <= 55; i++) programa(i);\n\nconsole.log(output);\nconsole.log('\\nEND PROGRAM\\n');\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/Younes0-0.js",
    "content": "//Operadores de asignación\nlet x  = 5\nx = x + 5   // abreviado x += 5\nx = x - 5   // abreviado x -= 5\nx = x * 5   // abreviado x *= 5\nx = x / 5   // abreviado x /= 5\nx = x ** 5  // abreviado x **= 5\nx = x % 5   // abreviado x %= 5\n\n\n// Desestructuración \nlet identidad  = {\n    nombre : \"Younes\",\n    apellido : \"Ozux\",\n    edad : 30,\n    ciudad : \"Almería\",\n    pais : \"España\",\n    hobby : \"Programar\"\n}\n\nlet {nombre, apellido} = identidad\n\n//Operadores de comparación\nlet operacion \n// Igualdad\noperacion = (10 == 10)      \n// Distinto\noperacion = (10 != 10)      \n// Estrictamente igual\noperacion = (10 === 10)     \n// Estrictamente desigual\noperacion = (10 !== 10)     \n// Mayor que\noperacion = (10 > 10)       \n// Menor que\noperacion = (10 < 10)       \n// Mayor o igual que\noperacion = (10 >= 10)      \n// Menor o igual que\noperacion = (10 <= 10)      \n\n//Operadores aritméticos\n// Residuo de la división\nlet residuo = 10 % 3\n// Incremento\nlet incremento = 10\nincremento++\n// Decremento\nlet decremento = 10\ndecremento--\n// Negación unaria\t\nlet negacion = 10\nnegado = -negacion\n// Operador de exponenciación\nlet exponenciacion = 10\nexponenciacion **= 2\n\n//Operadores bit a bit\nlet a = 15 // 1111 \nlet b = 9 // 1001  \nlet resultado\n//AND\nresultado = a & b // 1001 \n//OR\nresultado = a | b // 1111 \n//XOR\nresultado = a ^ b // 0110 \n//NOT\nresultado = ~a // 0000  \n//Desplazamiento a la derecha\nresultado = b >> 2 // 0010  \n//Desplazamiento a la izquierda\nresultado = b << 2 // 100100 \n\n//Operadores lógicos\nlet p = true\nlet q = false\np && q      //AND lógico\np || q      //OR lógico\n!p          //NOT lógico\n\n//Operadores de cadena\nlet s = \"Hola\"\nlet t = \"Mundo\"\nsaludo = s + \" \" + t //Concatenación\n\n//Operador condicional (ternario)\nsaludo = (a > b) ? \"a es mayor que b\" : \"a es menor que b\"\n\n//Operador coma\nvar w = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\nvar h = [w, w, w, w, w]\n\nfor (var i = 0, j = 9; i <= j; i++, j--)\n  //                              ^\n  console.log(\"a[\" + i + \"][\" + j + \"]= \" + h[i][j]);\n\n\n//Operadores unarios es una operación con un solo operando.\n\n// delete -> elimina la propiedad de un objeto.\nlet property = {name: \"Younes\"}\ndelete property.name \n/*Si el operador delete tiene éxito, elimina la propiedad del objeto. Intentar acceder a él después dará como resultado undefined. \nEl operador delete devuelve true si la operación es posible; devuelve false si la operación no es posible.*/\n\n// typeof -> devuelve una cadena que indica el tipo de operando\ntypeof property\nconsole.log(typeof property, property.name)\n\n// void -> especifica una expresión que se evaluará sin devolver un valor.\nresultado = void( 10 > 5)\nresultado = void 10\n\n//Operadores relacionales\n\n// in -> devuelve true si la propiedad existe en el objeto.\nlet object = {name: \"Younes\"}\nconsole.log(\"name\" in object)\n\n// instanceof -> devuelve true si el objeto es una instancia de una clase.\nclass Persona {}\nlet persona = new Persona()\nconsole.log(persona instanceof Persona)\n\n// Expresiones -> es cualquier unidad de código válida que se resuelve en un valor.\n\n// Expresiones primarias -> Palabras clave básicas y expresiones generales en JavaScript.\n\n// this -> es el contexto donde se ejecuta el código.(dueño de la función)\n// Función tradicional\nfunction getName() {\n    console.log(this.nick);\n}\n\n// Función de flecha\nvar getAge = () => console.log(this.nick)\n\n\n// global === globalThis === window === this\nglobal.nick = \"younes\"\ngetName() // imprime \"younes\" porque el dueño de la función es el objeto global\n\nvar younes = {\n    nick : \"yuyu\",\n    getName : getName,\n    getAge : getAge,\n    age : 36\n}\nyounes.getName() // imprime \"yuyu\" porque el dueño de la función es el objeto younes\n    \n// En las funciones de flecha no pueden ser dueñas por lo tanto no tiene contexto de ejecución \nyounes.getAge() // imprime \"undefined\" \n\n// Expresiones del lado izquierdo\n\n// new -> crea una nueva instancia de un tipo de objeto definido.\nfunction Car(make, model, year) {\n    this.make = make;\n    this.model = model;\n    this.year = year;\n}\n  \nconst car1 = new Car('Eagle', 'Talon TSi', 1993);\n\n// super -> es usada para acceder y llamar funciones del padre de un objeto.class Rectangle {\n\nclass Rectangle {\n    constructor() {}\n    static logNbSides() {\n      return \"Tengo 4 lados\";\n    }\n}\n  \nclass Square extends Rectangle {\n    constructor() {}\n    static logDescription() {\n      return super.logNbSides() + \" que son todos iguales\";\n    }\n}\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/Zunigaj1101.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n*/\n\n// Aritmeticos\nlet a = 3\nlet b = 2\nconsole.log (a / b) // Division\nconsole.log (a * b) // Multipilicación\nconsole.log (a - b) // Resta\nconsole.log (a + b) // Suma\nconsole.log (a % b) // Modulo\nconsole.log (a ** b) //Exponente\na++ // Incremento\nb-- // Decremento\nconsole.log (b)\nconsole.log (a)\n\n// logicos\n let x = true \n let y = false\n\n console.log (x && y) // AND Lógico\n console.log (x || y) // OR lógico\n console.log (!x) // NOT lógico\n\n// Comparacion\n\nlet c = 5\nlet d = 10\n\nconsole.log (c == d) // Igualdad\nconsole.log(c !== d); // Desigualdad estricta\nconsole.log(c > d); // Mayor que\nconsole.log(c < d); // Menor que\nconsole.log(c >= d); // Mayor o igual que\nconsole.log(c <= d); // Menor o igual que\n\n// Asigncación\nlet e \ne += 5; // Asignación de suma\ne -= 3; // Asignación de resta\ne *= 2; // Asignación de multiplicación\ne /= 2; // Asignación de división\ne %= 3; // Asignación de módulo\ne **= 2; // Asignación de exponenciación\n\n// Identidad\n\nlet f = 5;\nlet g = '5';\n\nconsole.log(f === g); // Igualdad estricta\nconsole.log(f !== g); // Desigualdad estricta\n\n// Pertenencia\n\nlet myArray = [1,2,3,4,5]\n\nconsole.log (3 in myArray) // Verifica si el indice 3 existe en el array\nconsole.log ('Hola' in myArray) // Verifica si la propiedad 'length' existe en el array\n\nlet h = 5; // 0101 en binario\nlet i = 3; // 0011 en binario\n\nconsole.log(h & i); // AND bit a bit\nconsole.log(h | i); // OR bit a bit\nconsole.log(h ^ i); // XOR bit a bit\nconsole.log(~h); // NOT bit a bit\nconsole.log(h << 1); // Desplazamiento a la izquierda\nconsole.log(h >> 1); // Desplazamiento a la derecha\nconsole.log(h >>> 1); // Desplazamiento a la derecha sin signo\n\n// Condicionales\na = 2\nb = 3\nlet text\nif (a == b) {\n    text = \"a es igual a b\"\n} else if (a > b) {\n    text = 'a es mayor que b'\n} else {\n    text = \"a es menor que b\"\n}\nconsole.log (text)\n\ntext = (text == \"a es mayor que b\") ? true :  false\nconsole.log (text)\n\nlet myName = \"Luiss\"\n\nswitch (myName) {\n    case \"Jose\":\n        console.log (`Hola, ${myName}`)\n        break;\n    case \"Luis\":\n        console.log (`Hola, ${myName}`)\n        break;\n    default:\n        console.log (`Hola, ${myName}`)\n        break;\n}\n\n// Iterativas\n\nfor (let i = 0; i < myArray.length; i++) { \n    console.log (myArray[i])\n}\n\nfor (let value of myArray) {\n    console.log (value)\n}\n\nlet myMap = {b: 'canada', a: 'Korea', c: \"Venezuela\"}\n\nfor (let key in myMap) {\n    console.log (`${key}: ${myMap[key]}`)\n}\n\ni = 0\nwhile (i < myArray.length) {\n    console.log (myArray[i])\n    i++\n}\ni = 1\ndo {\n    console.log (\"Contador \" + i)\n    i++\n} while (i <= 10);\n\n// Exepciones\n\nfunction Contador(i) {\n    if (typeof i == \"number\") {\n        let a = 1\n        while (a <= i){\n            console.log ('Contador: ', a)\n            a++\n        }\n    } else {\n        throw new Error (\"la variable no es un numero\")\n    }\n}\ntry {\n    Contador (6)\n} catch (error) {\n    console.log ('Se ha producido un error : ', error.message)\n} finally {\n    console.log (\"Bloque Finalizado\")\n}\n\n// * Crea un programa que imprima por consola todos los números comprendidos\n// * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\nmyArray = []\nfunction AddNumberArray (valor, limite) {\n    while (valor <= limite) {\n        if (valor % 2 === 0 && valor !== 16 && valor % 3 !== 0) {\n            myArray.push (valor)\n        }\n        valor++;\n    }\n}\n\nAddNumberArray(10, 55)\nconsole.log(myArray)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/aarxnmendez.js",
    "content": "// Operadores ----------------------------------------\r\n\r\n// Operadores Aritméticos\r\nlet a = 10, b = 3;\r\nconsole.log(\"Suma:\", a + b);\r\nconsole.log(\"Resta:\", a - b);\r\nconsole.log(\"Multiplicación:\", a * b);\r\nconsole.log(\"División:\", a / b);\r\nconsole.log(\"Módulo:\", a % b);\r\nconsole.log(\"Potenciación:\", a ** b);\r\n\r\n// Operadores de Comparación\r\nconsole.log(\"Mayor que:\", a > b);\r\nconsole.log(\"Menor o igual:\", a <= b);\r\nconsole.log(\"Igualdad estricta:\", a === b);\r\nconsole.log(\"Desigualdad estricta:\", a !== b);\r\n\r\n// Operadores Lógicos\r\nlet x = true, y = false;\r\nconsole.log(\"AND:\", x && y);\r\nconsole.log(\"OR:\", x || y);\r\nconsole.log(\"NOT:\", !x);\r\n\r\n// Operadores de Asignación\r\nlet c = 5;\r\nc += 2; // c = c + 2\r\nconsole.log(\"Asignación Suma:\", c);\r\nc *= 3; // c = c * 3\r\nconsole.log(\"Asignación Multiplicación:\", c);\r\n\r\n// Operadores de Identidad (strict equality)\r\nlet d = \"10\";\r\nconsole.log(\"Igualdad estricta:\", a === d); // Compara valor y tipo\r\nconsole.log(\"Igualdad no estricta:\", a == d); // Compara solo valor\r\n\r\n// Operadores de Pertenencia\r\nlet arr = [1, 2, 3];\r\nconsole.log(\"Elemento en array (2):\", arr.includes(2));\r\n\r\n// Operadores a Nivel de Bits\r\nlet e = 5, f = 1; // e = 0101, f = 0001 en binario\r\nconsole.log(\"AND a nivel de bits:\", e & f); // 0001\r\nconsole.log(\"OR a nivel de bits:\", e | f); // 0101\r\nconsole.log(\"XOR a nivel de bits:\", e ^ f); // 0100\r\nconsole.log(\"Desplazamiento a la izquierda:\", e << 1); // 1010\r\nconsole.log(\"Desplazamiento a la derecha:\", e >> 1); // 0010\r\n\r\n\r\n// Estructuras de control ----------------------------------------\r\n\r\n// Condicionales\r\nlet age = 18;\r\nif (age >= 18) {\r\n    console.log(\"Eres mayor de edad.\");\r\n} else {\r\n    console.log(\"Eres menor de edad.\");\r\n}\r\n\r\n// Iterativas (for, while, do-while)\r\nconsole.log(\"Bucle for:\");\r\nfor (let i = 0; i < 5; i++) {\r\n    console.log(\"i =\", i);\r\n}\r\n\r\nconsole.log(\"Bucle while:\");\r\nlet count = 3;\r\nwhile (count > 0) {\r\n    console.log(\"count =\", count);\r\n    count--;\r\n}\r\n\r\nconsole.log(\"Bucle do-while:\");\r\nlet num = 0;\r\ndo {\r\n    console.log(\"num =\", num);\r\n    num++;\r\n} while (num < 3);\r\n\r\n// Excepciones\r\ntry {\r\n    console.log(\"Intentando dividir por cero...\");\r\n    let result = 10 / 0;\r\n    if (!isFinite(result)) throw new Error(\"División por cero no permitida.\");\r\n    console.log(\"Resultado:\", result);\r\n} catch (error) {\r\n    console.log(\"Error:\", error.message);\r\n} finally {\r\n    console.log(\"Bloque finally ejecutado.\");\r\n}\r\n\r\n// Ejercicio Extra --------------------------------------------------------\r\nfor (let i = 10; i < 56; i++) {\r\n    if (i % 2 == 0 && i != 16 && i % 3 != 0) {\r\n        console.log(i);\r\n    }\r\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/adant11235.js",
    "content": "\n//Operadores aritmeticos\n\nconsole.log(\"La suma de 10 + 5 es: \", 10 + 5);\n\n\nconsole.log(\"La resta de 10 - 5 es: \", 10 - 5);\n\n\nconsole.log(\"La multip de 10 * 5 es: \" + 10 * 5);\n\n\nconsole.log(\"La div de 10 entre 5 es: \" + 10 / 5);\n\nlet mod = 10 % 3;\nconsole.log(`El residuo de 10 % 3 es: ${mod}`);\n\nconsole.log(\"El exponente de 2**2 es: \", 2 ** 2);\n\nconsole.log(\"<br>\");\n\n\n//Unarios\n\nlet inc = 5;\nconsole.log(\"Operador unario de incremento devolviendo 5 + 1\", ++inc);\nconsole.log(\"Operador unario de incremento que devuelve el valor de inc y luego suma\", inc++);\nconsole.log(`${inc}`);\n\nlet dec = 5;\nconsole.log(\"Operador unario de decremento devolviendo 5 -1 \", --dec);\nconsole.log(\"Operador unario de decremento que devuelve el valor de dec y luego resta\", dec--);\nconsole.log(`${dec}`);\n\nlet unNeg = 4\nconsole.log(\"la negación unaria negativa es: \", -unNeg);\nconsole.log(`el positivo unario es: ${+unNeg}`);\nconsole.log(+\"3\");\nconsole.log(+true);\n\nconsole.log(\"<br>\");\n\n\n//Operadores comparación\n\nconsole.log(\"Es 2 = a 10 ? \", 2 == 10);\n\nconsole.log(\"Es 2 = a 2 ? \", 2 == 2);\n\nconsole.log(\"Es 2 diferente de 10 ? \", 2 != 10);\n\nconsole.log(\"Es 2 < a 10 ? \", 2 < 10);\n\nconsole.log(\"Es 2 > a 10 ? \", 2 > 10);\n\nconsole.log(\"Es 2 < o = a 10 ? \", 2 <= 10);\n\nconsole.log(\"Es 2 < o = a 10 ? \", 2 >= 10);\n\n//con objetos === !== se comportan como en Python\nconsole.log(\"Es 2 diferente de `2` ? \", 2 === \"2\");\n\nconsole.log(\"Es 2 diferente de `2` ? \", 2 !== \"2\");\n\nconsole.log(\"<br>\");\n\n\n//Operadores logicos\n\n// && and\nconsole.log(\"Es 2 + 2 = 4 y(&&) 2 - 2 = a 0? \", (2 + 2 == 4) && (2 - 2 == 0));\n\n// || or\nconsole.log(\"Es 2 + 2 = 4 o(||) 2 - 2 = a 0? \", (2 + 2 == 4) || (2 - 2 == 2)); \n//una cond es true = true\n\nconsole.log(\"Es 2 + 2 = 4 y(&&) 2 - 2 = a 0? \", (2 + 2 == 2) || (2 - 2 == 2));\n\n// Not\nconsole.log(\"No es 2 + 2 = 3? \", !(2 + 2 == 3)); //true\n\nconsole.log(\"<br>\");\n\n\n//Operadores de asignación\n\nlet myVar = 20;\nconsole.log(myVar);\n\nconsole.log(myVar += 1);\n\nconsole.log(myVar -= 1);\n\nconsole.log(myVar *= 2);\n\nconsole.log(myVar /= 2);\n\nconsole.log(myVar %= 3);\n\nconsole.log(myVar **= 3);\n\nconsole.log(\"<br>\");\n\n\n//Operadores relacionales (pertenencia)\n\n//con arrays\nconsole.log([1,2,3] .includes (3));\nconsole.log([1,2,3] .includes (4));\n\n//con strings\nconsole.log(\"abc\" .includes (\"a\"));\n\n//con objetos\nlet obj = {a : 1, b : 2};\nconsole.log(\"a\" in obj);\nconsole.log(\"c\" in obj);\n\nconsole.log(\"<br>\");\n\n\n//Operadores de bits\nconsole.log(5 & 3); // 0101 & 0011 = 0001  (1)\nconsole.log(5 | 3);  //0101 | 0011 = 0111  (7)\nconsole.log(5 ^ 3);  //0101 ^ 0011 = 0110  (6) \nconsole.log(~5);    // -0101 = 1010 = -6\nconsole.log(5 << 1); // 0101 << 1 = 1010 = 10\nconsole.log(5 >> 1); // 0101 >> 1 = 0010 = 2\nconsole.log(-5 >>> 1);\n\nconsole.log(\"<br>\");\n\n\n//Operador ternario\n\nlet age = 18;\nvar status = age >= 18 ? \"adulto\" : \"menor\";\n\nconsole.log(status);\n\n\nconsole.log(\"<br>\");\nconsole.log(\"<br>\");\nconsole.log(\"<br>\");\n\n\n//ESTRUCTURAS DE CONTROL\n\n//Condicionales\n\nlet edad = 18;\n\nif(edad > 18) {\n  console.log(\"Eres mayor de edad\");\n} else if (edad = 18) {\n  console.log(\"Tienes justo 18 años\");\n} else {\n  console.log(\"Eres menor de edad\")\n}\n\n\nlet food = \"meat\";\nlet menu;\n\nswitch (food) {\n  case \"meat\":\n    menu = \"La carne está en su punto\";\n    break;\n  case \"fish\":\n    menu = \"El pescado es de hoy\";\n    break;\n  case \"fruit\":\n    menu = \"La fruta es de temporada\";\n    break;\n  default:\n    menu = \"Lo siento, no tenemos\";\n    \n}\nconsole.log(menu);\n\n\nlet total = 0;\nwhile (total <= 10) {\n  console.log(total);\n  total++;\n}\n\n\nlet numero = 10;\ndo {\n  console.log(`tenemos un ${numero}`);\n  numero--;\n} while (numero > 0);\n\n\nfor(let num = 0; num <= 7; num++) {\n  console.log(`Hola ${num}`);\n}\n\n\nmyArra = [1, 2, 3, 4, 5];\nfor(val of myArra) {\n  console.log(val);\n}\n\n\nlet frase = \"Hello Mouredev!\";\nfor(let l in frase) {\n  console.log(l);\n}\n\nlet frase2 = \"Hello Mouredev!\";\nfor(let l in frase2) {\n  console.log(frase2[l]);\n}\n\n\n//Dificultad EXTRA\n\n/*\nfor(let number = 10; number <= 55; number ++) {\n  if(number == 16) {\n    continue;\n  }else if(number % 3 == 0) {\n    continue;\n  }else if(number % 2 != 0) {\n    continue;\n  }\n  console.log(`${number}`);\n}\nconsole.log(\"55\");\n*/\n\nfor (let number = 10; number <= 55; number++) {\n  if (((number % 2 == 0 && number != 16) && number % 3 != 0) || number == 55) {\n    console.log(`${number}`);\n  }\n}\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/adrs1166ma.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n// 🔥 Aritméticos\nlet suma = 10 + 5;\nlet resta = 10 - 5;\nlet multiplicacion = 10 * 5;\nlet division = 10 / 5;\nlet modulo = 10 % 5;\n\n// 🔥 Lógicos\nlet and = true && false; // false\nlet or = true || false; // true\nlet not = !true; // false\n\n// 🔥 De comparación\nlet igual = 10 == 5; // false\nlet diferente = 10 != 5; // true\nlet mayorQue = 10 > 5; // true\nlet menorQue = 10 < 5; // false\nlet mayorOIgualQue = 10 >= 5; // true\nlet menorOIgualQue = 10 <= 5; // false\n\n// 🔥 Asignación\nlet asignacion = 10;\nasignacion += 5; // 10 + 5 = 15\nasignacion -= 5; // 10 - 5 = 5\nasignacion *= 5; // 10 * 5 = 50\nasignacion /= 5; // 10 / 5 = 2\nasignacion %= 5; // 10 % 5 = 0\n\n// 🔥 Identidad\nlet igualEstricto = 10 === 10; // true\nlet diferenteEstricto = 10 !== 10; // false\n\n// 🔥 Pertenencia\nlet array = [1, 2, 3];\nlet pertenece = 2 in array; // true\n\n// 🔥 Bits\nlet andBits = 10 & 5; // 0\n// 1010 (10) AND \n// 0101 (5)\n// ----\n// 0000 (0) , Si ambos bits son 1, es = 1, sino es 0.\n\nlet orBits = 10 | 5; // 15\n// 1010 (10) OR \n// 0101 (5)\n// ----\n// 1111 (15) , Si al menos uno de los bits es 1, es = 1, sino es 0.\n\nlet xorBits = 10 ^ 5; \n// 1010 (10) XOR\n// 0101 (5)\n// ----\n// 1111 (15) , Si los bits son diferentes, es = 1, si son iguales es 0.\n\nlet notBits = ~10; \n// 0000 1010 NOT(10)\n// ---------\n// 1111 0101 (-11), 0 se convierte en 1 y 1 se convierte en 0. \n\nlet desplazamientoIzquierda = 10 << 2; // 40\n// 0000 1010 (10) << 2 \n// ---------\n// 0010 1000 (40) , Desplaza los bits del número hacia la izquierda, y deja un 0\n\nlet desplazamientoDerecha = 10 >> 2; // 2\n// 0000 1010 (10) >> 2\n// ---------\n// 0000 0010 (2) , Desplaza los bits del número hacia la derecha, los de la derecha se descartan.\ndesplazamientoDerecha = -10 >> 2; // -3\n// 1111 0110 (-10) >> 2\n// ---------\n// 1111 1101 (-3) , Al desplazar a la derecha, este bit de signo se copia en las nuevas posiciones a la izquierda.\nlet desplazamientoDerechaSinSigno = 10 >>> 2; // 2\n// 0000 1010 (10) >>> 2\n// ---------\n// 0000 0010 (2) , \n\n// Similar al desplazamiento a la derecha, \n// pero en lugar de copiar el bit de signo, \n// se añaden ceros por la izquierda.\n\ndesplazamientoDerechaSinSigno = -10 >>> 2; // 61\n// 11110110 (-10) >>> 2\n// ---------\n// 00111101 (61)\n// \n// En el desplazamiento a la derecha sin signo, \n// Se añaden ceros a la izquierda en lugar de copiar el bit de signo.\n\n\n// 🔥 Condicionales\nif (10 > 5) {\n    console.log(\"10 es mayor que 5\");\n} else {\nconsole.log(\"10 no es mayor que 5\");\n}\n\n// 🔥 Iterativas\nfor (let i = 0; i < 10; i++) {\nconsole.log(i);\n}\n\nlet i = 0;\nwhile (i < 10) {\nconsole.log(i);\ni++;\n}\n\n// 🔥 Excepciones\ntry {\nlet resultado = 10 / 0;\n} catch (error) {\nconsole.log(\"Se capturo error: división por cero\");\n}\n\n\n// 🔥 Extra\nfor (let i = 10; i <= 55; i++) {\n    //   (pares)  Y  (ni 16) Y  (ni multi de 3) O (el extremo 55)\n    if ( (i%2==0) && (i!=16) && ( i % 3 !== 0 ) || (i == 55) ){\n        console.log(i)\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/agusrosero.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n// EJERCICIO:\n// Aritméticos\nconsole.log(2 + 2);\nconsole.log(2 - 2);\nconsole.log(2 * 2);\nconsole.log(2 / 2);\nconsole.log(2 % 2);\nconsole.log(2 ** 2);\n\n// Lógicos\nconsole.log(true && true);\nconsole.log(true || true);\nconsole.log(!true);\n\n// Comparación\nconsole.log(2 === 2);\nconsole.log(2 !== 2);\nconsole.log(2 > 2);\nconsole.log(2 < 2);\nconsole.log(2 >= 2);\nconsole.log(2 <= 2);\n\n// Asignación\nlet a = 2;\na += 2;\nconsole.log(a);\na -= 2;\nconsole.log(a);\na *= 2;\nconsole.log(a);\na /= 2;\nconsole.log(a);\na %= 2;\nconsole.log(a);\na **= 2;\nconsole.log(a);\n\n// Incremento - Decremento\nlet b = 2;\nb++;\nconsole.log(b);\nb--;\nconsole.log(b);\n\n// Estructuras de control\nif (true) {\n  console.log(\"Ejecutando el if\");\n} else {\n  console.log(\"Ejecutando el else\");\n}\n\nwhile (true) {\n  console.log(\"Ejecutando el while\");\n  break;\n}\n\nfor (let i = 0; i < 10; i++) {\n  console.log(\"Ejecutando el for\");\n  break;\n}\n\n// do {\n//   console.log(\"Ejecutando el do\");\n// } while (true);\n\ntry {\n  console.log(\"Ejecutando el try\");\n} catch (error) {\n  console.log(\"Ejecutando el catch\");\n} finally {\n  console.log(\"Ejecutando el finally\");\n}\n\n// DIFICULTAD EXTRA:\nfor (let i = 10; i <= 55; i++) {\n  if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n    console.log(i);\n  }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/alexdevrep.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n//Operadores aritméticos\n    //Suma \n    let suma = 1 + 2\n    //Resta \n    let resta = 7 - 8\n    //Multiplicación\n    let multiplicacion = 2 * 2\n    //División\n    let division = 10 / 2\n    //Módulo (es el resto de la división)\n    let modulo = 9 % 2\n    //Exponente \n    let exponente = 3**3\n    // Incremento (el resultado es 1 + la variable )\n    let incremento = 6 \n    incremento++\n    // Decremento (el resultado es la variable - 1)\n    let decremento = 8\n    decremento--\n\n// Operadores lógicos (vamos a declarar constantes para este apartado)\n    const valorTrue = true\n    const valorFalse = false\n    //Operación AND (la salida será True cuando todas las variables sean true)\n    let AND = valorFalse && valorTrue\n    //Operación OR (la salida será True cuando alguna variable sea true)\n    let OR = valorFalse || valorTrue\n    //Devuelve false si su único operando es true, de lo contrario devuelve true\n    let NOT = !valorTrue\n\n//Operadores de comparación\n    //Igualdad \n    let igualdad = 3==3\n    //No igualdad\n    let noIgualdad = 4 !=56\n    //Estrictamente igual (a diferencia del de igualdad este tambien compara el tipo de dato\n    let estrictamenteIgual = 2===2\n    //Desigualdad estricta (devulve true cuando los valores son iguales pero no del mismo tipo de dato)\n    let desigualdadEstricta = 3 !== '3' // en este caso comparamos un número con una cadena de texto\n    //Mayor que \n    let mayorQue = 23 > 18\n    //Menor que\n    let menorQue = 12 < 34\n    //Mayor o igual que \n    let mayorOIgual = 33 >= 33\n    //Menor o igual que \n    let menorOIgual = 12 <= 13\n\n//Operadores de asignación\n    let numero1 = 3\n    let numero2 = 5\n    //Operador suma\n    numero1 += numero2 // numero1 = numero1 + numero 2\n    //Operador resta \n    numero2 -= numero1 //numero2 = numero2 - numero1\n    //Operador multiplicación\n    numero1 *= numero2 // numero1 = numero1 * numero2\n    //Operador división\n    numero1 /= numero2 // numero1 = numero1 / numero2\n    //Operador módulo\n    numero2 %= numero1 // numero2 = resto de la división entre numero 2 y numero 1\n    //Operador exponente \n    numero1 **= numero2 //numero1 = numero1 ** numero2\n\n//Operadores de identidad\n    let numero3 = 7\n    let numero4 = 9\n    //Operador de igualdad esctricta\n    numero3 === numero4 //En caso de que sean estrictamente iguales el terminal devolverá true\n    //Operador de desigualdad estricta\n    numero3 !== numero4 //Si son desiguales en algo el ternimal devuelve true\n\n//Operadores de pertenencia\n    let myArray = [1,2,3,4,5,6]\n    const pertTrue = 3 in myArray //Devuelve true\n    const pertFalse = 33 in myArray //Devuelve false\n\n//Operadores bit a bit (Los números se convierten a numeros binarios y se hacen las operaciones lógicas correspondientes bit a bit)\n    let numero5 = 15\n    let numero6 = 9\n    //AND a nivel de bits (Devuelve un uno en cada posición del bit para los que los bits correspondientes de ambos operandos son unos)\n    let bitAnd = numero5 & numero6 // 1111 (15) & 1001 (9)= 1001, la operación AND devuelve 1 cuando ambos bits sean 1 y 0 para el resto de los casos\n    //OR a nivel de bits (Devuelve un uno en cada posición del bit para los que los bits correspondientes de ambos operandos no sean 0)\n    let bitOr = numero5 | numero6 // 1111 (15) & 1001 (9)= 1111, la operación OR devuelve 1 cuando ambos bits sean 1 o 0 y 0 para el resto de los casos\n    //XOR a nivel de bits\n    let bitXor = numero5 ^ numero6 // 1111 (15) & 1001 (9)= 0110, la operación XOR devuelve 1 cuando ambos bits sean distintosy 0 para cuando sean iguales\n    //NOT a nivel de bits\n    let bitNot = ~numero5 //Convierte los bits los que son 1 pasan a 0 y vicerversa \n    //Desplazamiento a la izquierda\n    let bitIzq = numero6<< 3 // 9<<3 desplaza el numero6 3 ceros a la izquierda y da resultado 1001000\n    //Desplazamiento a la derecha \n    let bitDcha = numero6 >> 3// 9>>3 desplaza el numero6 3 ceros a la derecha y da resultado 1\n\n//Estructuras de control\n\n    //Sentencia IF si se cumple la condición se ejecuta el bloque de código que hay dentro de la sentencia, en caso contrario se ejecuta otro código\n    console.log(\"Resultado Sentencia IF:\")\n    if (numero1 < numero2){\n\n        console.log(\"Número 1 es mayor que número 2\")\n    \n    }\n    else {\n\n        console.log(\"Número 2 es mayor que número 1\")\n    }\n    \n    //Sentencia SWITCH ejecuta un bloque de código en función de un valor predeterminado\n    console.log(\"Resultado Sentencia SWITCH:\")\n    const prompt = require('prompt-sync')()\n    let nuevoNumero = parseInt(prompt('Escribe un número del 1 al 3:'))\n    switch(nuevoNumero){\n        case 1:\n            console.log(\"Has escogido el número 1\")\n            break\n        case 2:\n            console.log(\"Has escogido el número 2\")\n            break\n        case 3:\n            console.log(\"Has escogido el número 3\") \n            break\n        default:\n            console.log(\"No has escogido ningún número\")\n            break\n    }\n\n    // Bucle WHILE la acción se ejecuta hasta que la condición deja de cumplirse (ideal para cuando no sabemos el número de iteraciones del bucle)\n    console.log(\"Resultado Bucle WHILE:\")\n        let numero7 = 1\n        while (numero7 <= 9){\n            console.log(numero7)\n            numero7++\n            \n        }\n    \n    // Bucle FOR la acción se ejecuta hasta que se cumple con el número máximo de iteraciones\n    console.log(\"Resultado Bucle FOR:\")\n        for(let i = 0; i < 5; i++){\n            console.log(\"Es mi primer bucle for en JavaScript\")\n        }\n    \n    //Bucle DO WHILE  a diferencia del bucle while este se ejecuta una vez al menos, despues se comprueba si la condición es true\n    console.log(\"Resultado Bucle DO WHILE:\")\n        let numero10= 3\n        do {\n            console.log(\"Este es mi primer bucle Do en JavaScript\")\n            numero10++\n        }\n        while (numero10 < 5)\n\n//DIFICULTAD EXTRA \nconsole.log(\"Resultado Dificultad EXTRA:\")\nfor (let numero = 10;numero<=55;numero++){\n    if (numero % 2 === 0 && numero !== 16 && numero % 3 !== 0){  \n        console.log(numero)\n    }\n    \n}\n/* en la primera condición filtramos para que los números sean pares , en la segunda quitamos el 16\ny en la tercera quitamos los multiplos de 3 */\n\n\n\n    "
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/andresgcastillo.js",
    "content": "// Operadores Aritméticos\nconsole.log(\"Operadores Aritméticos:\");\nlet a = 10;\nlet b = 3;\nconsole.log(\"a + b =\", a + b); // Suma\nconsole.log(\"a - b =\", a - b); // Resta\nconsole.log(\"a * b =\", a * b); // Multiplicación\nconsole.log(\"a / b =\", a / b); // División\nconsole.log(\"a % b =\", a % b); // Módulo\nconsole.log(\"a ** b =\", a ** b); // Exponente\n\n// Operadores de Comparación\nconsole.log(\"\\nOperadores de Comparación:\");\nconsole.log(\"a == b:\", a == b); // Igual\nconsole.log(\"a != b:\", a != b); // No igual\nconsole.log(\"a > b:\", a > b); // Mayor que\nconsole.log(\"a < b:\", a < b); // Menor que\nconsole.log(\"a >= b:\", a >= b); // Mayor o igual que\nconsole.log(\"a <= b:\", a <= b); // Menor o igual que\n\n// Operadores Lógicos\nconsole.log(\"\\nOperadores Lógicos:\");\nconsole.log(\"true && false:\", true && false); // AND lógico\nconsole.log(\"true || false:\", true || false); // OR lógico\nconsole.log(\"!true:\", !true); // NOT lógico\n\n// Operadores de Asignación\nconsole.log(\"\\nOperadores de Asignación:\");\na = 10;\nconsole.log(\"a = 10:\", a);\na += 5;\nconsole.log(\"a += 5:\", a);\na -= 2;\nconsole.log(\"a -= 2:\", a);\na *= 3;\nconsole.log(\"a *= 3:\", a);\na /= 2;\nconsole.log(\"a /= 2:\", a);\n\n// Operadores de Identidad\nconsole.log(\"\\nOperadores de Identidad:\");\nconsole.log(\"a === b:\", a === b);\nconsole.log(\"a !== b:\", a !== b);\n\n// Operadores de Bits\nconsole.log(\"\\nOperadores de Bits:\");\na = 60; // 60 = 0011 1100\nb = 13; // 13 = 0000 1101\nconsole.log(\"a & b =\", a & b); // AND bit a bit\nconsole.log(\"a | b =\", a | b); // OR bit a bit\nconsole.log(\"a ^ b =\", a ^ b); // XOR bit a bit\nconsole.log(\"~a =\", ~a); // NOT bit a bit\nconsole.log(\"a << 2 =\", a << 2); // Desplazamiento a la izquierda\nconsole.log(\"a >> 2 =\", a >> 2); // Desplazamiento a la derecha\n\n// Estructuras de Control\nconsole.log(\"\\nEstructuras de Control:\");\n// Condicional\nlet x = 10;\nif (x > 5) {\n  console.log(\"x es mayor que 5\");\n} else {\n  console.log(\"x es menor o igual a 5\");\n}\n\n// Iterativa\nfor (let i = 0; i < 5; i++) {\n  console.log(i);\n}\n\n// Excepciones\nfunction performDivision(a, b) {\n  if (b === 0) {\n    throw new Error(\"No se puede dividir por cero\");\n  }\n  return a / b;\n}\n\ntry {\n  console.log(performDivision(10, 0));\n} catch (e) {\n  console.log(\"\\nOcurrió un error:\", e.message);\n}\n\n//Dificultad extra\nconsole.log(\"\\nDificultad extra\");\nfor (let i = 10; i <= 55; i++) {\n  if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n    console.log(i);\n  }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/andyfg0289.js",
    "content": "/*\n * EJERCICIO:\n * 1- Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n *2 - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n *3 - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n// 1 \n\n//Operadores Aritmeticos\n\nlet adicion = 6 + 4;\nconsole.log(adicion);\nlet sustraccion = 9 - 3;\nconsole.log(sustraccion);\nlet multiplicacion = 7 * 3;\nconsole.log(multiplicacion);\nlet division = 4 / 2;\nconsole.log(division);\nlet modulo = 10 % 3;\nconsole.log(modulo);\nlet incremento = 10;\nincremento++;\nconsole.log(incremento);\nlet decremento = 10;\ndecremento--;\nconsole.log(decremento);\nlet exponenciacion = 3 ** 4;\nconsole.log(exponenciacion);\n\n//Operadores de asignacion \n\nlet asignacion = 12;\nconsole.log(asignacion);\nlet adicionAsignacion = 30;\nadicionAsignacion += 5;\nconsole.log(adicionAsignacion);\nlet sustraccionAsignacion = 20;\nsustraccionAsignacion -= 5;\nconsole.log(sustraccionAsignacion);\nlet multiplicacionAsignacion = 2;\nmultiplicacionAsignacion *= 2;\nconsole.log(multiplicacionAsignacion);\nlet divisionAsignacion = 10;\ndivisionAsignacion /= 2;\nconsole.log(divisionAsignacion);\nlet moduloAsignacion = 15;\nmoduloAsignacion %= 3;\nconsole.log(moduloAsignacion);\nlet expAsignacion = 2;\nexpAsignacion **= 8;\nconsole.log(expAsignacion);\n\n\n//Operadores de comparacion \n\nlet igualdad = 5;\nconsole.log(igualdad == 5);//true\n\nlet igualdadExtricto = 10;\nconsole.log(igualdadExtricto === '10')//false\nconsole.log(igualdadExtricto === 10)//true\n\nlet desigualdad = 15;\nconsole.log(desigualdad != 15) //false\nconsole.log(desigualdad != 5) //true\n\nlet desigualEstricto = 20;\nconsole.log(desigualEstricto !== 20)//false\nconsole.log(desigualEstricto !== '20')//true\n\nlet mayorque = 25;\nconsole.log(mayorque > 20)//true\nconsole.log(mayorque > 30)//false\n\nlet mayorOigual = 25;\nconsole.log(mayorOigual >= 25)//true\nconsole.log(mayorOigual >= 30)//false\n\nlet menorque = 25;\nconsole.log(menorque < 35)//true\nconsole.log(menorque < 15)//false\n\nlet menorOigual = 25;\nconsole.log(menorOigual <= 25)//true\nconsole.log(menorOigual <= 15)//false\n\n//Operadoresm logicos \n\nconsole.log(true && false); //false   AND logico  &&\nconsole.log(true || false); //true OR logico ||\nconsole.log(!true); //false NOT logico !\nlet nulo = null ?? 'Es nulo o undefined';\nconsole.log(nulo);// Es nulo o undefined\nlet NotNull = 200 ?? '200';\nconsole.log(NotNull);// 200\n\n\n//Operadores bit a bit\n\nlet and = 5 & 3; // 1 (0101 & 0011 = 0001)\nlet or = 5 | 3; // 7 (0101 | 0011 = 0111)\nlet xor = ~5; // -6 (~0101 = 1010)\nlet despIzquierda = 5 << 1; // 10 (0101 << 1 = 1010)\nlet despDerecha = 5 >> 1; // 2 (0101 >> 1 = 0010)\nlet despDerechaNoSigno = -5 >>> 1; // 2147483645\n\n//Operadores de cadena\n\n//concatenacion +\nlet nombre = 'Andy ';\nlet apellido = 'Fernandez ';\nlet edad = 35;\n\nlet concatenacion = nombre + apellido;\nconsole.log(`Mi nombre es ${concatenacion}`);//Mi nombre es Andy Fernandez\n\n//concatenacion de asignacion +=\nnombre += apellido;\nlet nombreCompleto = nombre;\nconsole.log(nombreCompleto);//Andy Fernandez\n\n//Operadores de tipo\n\n//typeof\n\nconsole.log(typeof edad);//number\nconsole.log(typeof nombre);//string\n\n//instanceof\n\nlet miarray = [];\nif (miarray instanceof Array) {\n    console.log('True');\n}\n\n//in\n\nlet myObj = { candy: 150 }\nconsole.log(\"candy\" in myObj); //true\n\n//Operador ternario\n\nlet age = 35;\n\nlet acces = (age <= 17) ? \"Eres menor, acceso deneagado\" : \"Puedes entrar\";\nconsole.log(acces); //Puedes entrar \n\n// operador coma \nlet a = 1, b = 2, c = 3;\n\n//Operador de agrupacion ()\n\nlet sumaFirst = (5 + 5) * 2;\nconsole.log(sumaFirst);\n\nfor (let index = 0; index < array.length; index++) {\n    const element = array[index];\n\n}\n\n/* *2 - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n*   que representen todos los tipos de estructuras de control que existan\n*   en tu lenguaje:\n*   Condicionales, iterativas, excepciones...\n */\n\n//Estructuras de control de flujo\n\n//(if,elseif,else)\nlet access = false;\nlet pass = 123456;\nlet keys = 3;\n\nfunction checkUser() {\n    let password = prompt(\"Introduce el password\");\n    if (pass == password && password !== \"\" && keys >= 0) {\n        access = true;\n        console.log(\"Puedes acceder\");\n        alert(\"Puedes acceder\");\n    } else if (keys === 0) {\n        console.log(\"Agotado el máximo de intentos, vuelva a intentarlo más tarde\");\n        return alert(\"Agotado el máximo de intentos, vuelva a intentarlo más tarde\");\n    } else {\n        alert(\"Password incorrecto\");\n        console.log(\"Acceso denegado, Password incorrecto\");\n        keys--;\n        console.log(keys);\n        checkUser();\n    }\n}\n\ncheckUser();\n\n\n//switch\n\nlet fruit = \"apple\";\n\nswitch (fruit) {\n    case \"banana\":\n        console.log(\"Es una banana.\");\n        break;\n    case \"apple\":\n        console.log(\"Es una manzana.\");\n        break;\n    case \"orange\":\n        console.log(\"Es una naranja.\");\n        break;\n    default:\n        console.log(\"No es una fruta conocida.\");\n}\n\n//for\nfor (let i = 0; i < 5; i++) {\n    console.log(i);\n}\n\n//while\n\nlet count = 0;\n\nwhile (count < 5) {\n    console.log(count);\n    count++;\n}\n\n//do... wile\n\ndo {\n    console.log(count);\n    count++;\n} while (count < 5);\n\n//for in (iterar sobre propiedades)\n\nlet person = { name: \"John\", age: 30, city: \"New York\" };\n\nfor (let key in person) {\n    console.log(key + \": \" + person[key]);\n}\n\n//for of (iterar sobre elementos)\nlet numbers = [15, 23, 36, 42, 544];\nfor (let number of numbers) {\n    console.log(number);\n}\n\n\n//try, catch, finally \n\ntry {\n    let result = noexisto();\n  } catch (error) {\n    console.log(\"Se ha producido un error: \" + error.message);\n  } finally {\n    console.log(\"Esto se ejecuta siempre, haya error o no.\");\n  }\n\n\n/* DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n * */\n\nfor (let i = 10; i <= 55; i++) {\n    if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n        console.log(i)\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/angelsanchezt.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n/*\nOperadores\n*/\n\n// Operadores aritméticos\nconsole.log(`Suma: 10 + 3 = ${10 + 3}`);\nconsole.log(`Resta: 10 - 3 = ${10 - 3}`);\nconsole.log(`Multiplicación: 10 * 3 = ${10 * 3}`);\nconsole.log(`División: 10 / 3 = ${10 / 3}`);\nconsole.log(`Módulo: 10 % 3 = ${10 % 3}`);\nconsole.log(`Exponente: 10 ** 3 = ${10 ** 3}`);\n\n// Operadores de comparación\nconsole.log(`Igualdad: 10 == 3 es ${10 == 3}`);\nconsole.log(`Desigualdad: 10 != 3 es ${10 != 3}`);\nconsole.log(`Mayor que: 10 > 3 es ${10 > 3}`);\nconsole.log(`Menor que: 10 < 3 es ${10 < 3}`);\nconsole.log(`Mayor o igual que: 10 >= 10 es ${10 >= 10}`);\nconsole.log(`Menor o igual que: 10 <= 3 es ${10 <= 3}`);\n\n// Operadores lógicos\nconsole.log(`AND &&: 10 + 3 == 13 and 5 - 1 == 4 es ${10 + 3 == 13 && 5 - 1 == 4}`);\nconsole.log(`OR ||: 10 + 3 == 13 or 5 - 1 == 4 es ${10 + 3 == 14 || 5 - 1 == 4}`);\nconsole.log(`NOT !: not 10 + 3 == 14 es ${!(10 + 3 == 14)}`);\n\n// Operadores de asignación\nlet my_number = 11;  // asignación\nconsole.log(my_number);\nmy_number += 1;  // suma y asignación\nconsole.log(my_number);\nmy_number -= 1;  // resta y asignación\nconsole.log(my_number);\nmy_number *= 2;  // multiplicación y asignación\nconsole.log(my_number);\nmy_number /= 2;  // división y asignación\nconsole.log(my_number);\nmy_number %= 2;  // módulo y asignación\nconsole.log(my_number);\nmy_number **= 1;  // exponente y asignación\nconsole.log(my_number);\nmy_number //= 1;  // división entera y asignación\nconsole.log(my_number);\n\n// Operadores de identidad\nlet my_new_number = my_number;\nconsole.log(`my_number is my_new_number es ${my_number === my_new_number}`);\nconsole.log(`my_number is not my_new_number es ${my_number !== my_new_number}`);\n\n\n// Operadores de bits\nlet a = 10;  // 1010\nlet b = 3;   // 0011\nconsole.log(`AND: 10 & 3 = ${a & b}`);   // 0010\nconsole.log(`OR: 10 | 3 = ${a | b}`);    // 1011\nconsole.log(`XOR: 10 ^ 3 = ${a ^ b}`);   // 1001\nconsole.log(`NOT: ~10 = ${~a}`);\nconsole.log(`Desplazamiento a la derecha: 10 >> 2 = ${a >> 2}`);   // 0010\nconsole.log(`Desplazamiento a la izquierda: 10 << 2 = ${a << 2}`);  // 101000\n\n/*\nEstructuras de control\n*/\n\n// Condicionales\nlet my_string = \"Brais\";\n\nif (my_string === \"MoureDev\") {\n    console.log(\"my_string es 'MoureDev'\");\n} else if (my_string === \"Brais\") {\n    console.log(\"my_string es 'Brais'\");\n} else {\n    console.log(\"my_string no es 'MoureDev' ni 'Brais'\");\n}\n\n// Iterativas\nfor (let i = 0; i <= 10; i++) {\n    console.log(i);\n}\n\nlet j = 0;\nwhile (j <= 10) {\n    console.log(j);\n    j++;\n}\n\n// Manejo de excepciones\ntry {\n    console.log(variable_no_definida);\n} catch (error) {\n    console.log(\"Se ha producido un error\");\n} finally {\n    console.log(\"Ha finalizado el manejo de excepciones\");\n}\n\n/*\nExtra\n*/\n\nfor (let number = 10; number <= 55; number++) {\n    if (number % 2 === 0 && number !== 16 && number % 3 !== 0) {\n        console.log(number);\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/angelurrutdev.js",
    "content": "// Operadores de concatenación  Backsticks se hacen utilizando ALT + 96\n\nlet saludo = \"¡Hola, \";\nlet nombre = \"Juan!\";\n\nlet saludoCompleto = saludo + nombre;\nconsole.log(`Saludo completo: ${saludoCompleto}`);\n\n// Operadores aritméticos \n\nlet numero1 = 10;\nlet numero2 = 5;\n\n// Suma\nlet suma = numero1 + numero2;\nconsole.log(`Suma: ${numero1} + ${numero2} = ${suma}`);\n\n// Resta\nlet resta = numero1 - numero2;\nconsole.log(`Resta: ${numero1} - ${numero2} = ${resta}`);\n\n// Multiplicación\nlet multiplicacion = numero1 * numero2;\nconsole.log(`Multiplicación: ${numero1} * ${numero2} = ${multiplicacion}`);\n\n// División\nlet division = numero1 / numero2;\nconsole.log(`División: ${numero1} / ${numero2} = ${division}`);\n\n// Módulo (resto de la división)\nlet modulo = numero1 % numero2;\nconsole.log(`Módulo: ${numero1} % ${numero2} = ${modulo}`);\n\n// Exponenciación\nlet exponenciacion = numero1 ** numero2;\nconsole.log(`Exponenciación: ${numero1} ** ${numero2} = ${exponenciacion}`);\n\n// División entera (descarta la parte decimal)\nlet divisionEntera = Math.floor(numero1 / numero2);\nconsole.log(`División entera: ${numero1} // ${numero2} = ${divisionEntera}`);\n\n// Operadores de asignación en \n\nlet resultado = 0;\n\n// Asignación simple\nresultado = 10;\nconsole.log(`Resultado después de asignación simple: ${resultado}`);\n\n// Asignación con suma\nresultado += 5; // Equivalente a: resultado = resultado + 5;\nconsole.log(`Resultado después de asignación con suma: ${resultado}`);\n\n// Asignación con resta\nresultado -= 3; // Equivalente a: resultado = resultado - 3;\nconsole.log(`Resultado después de asignación con resta: ${resultado}`);\n\n// Asignación con multiplicación\nresultado *= 2; // Equivalente a: resultado = resultado * 2;\nconsole.log(`Resultado después de asignación con multiplicación: ${resultado}`);\n\n// Asignación con división\nresultado /= 4; // Equivalente a: resultado = resultado / 4;\nconsole.log(`Resultado después de asignación con división: ${resultado}`);\n\n// Asignación con módulo\nresultado %= 3; // Equivalente a: resultado = resultado % 3;\nconsole.log(`Resultado después de asignación con módulo: ${resultado}`);\n\n// Asignación con exponenciación\nresultado **= 2; // Equivalente a: resultado = resultado ** 2;\nconsole.log(`Resultado después de asignación con exponenciación: ${resultado}`);\n\n\n\n// Operadores Logicos\n\nconsole.log(5 > 4) // True\nconsole.log(5 < 4) // False\n\n\nlet edad = 25;\nlet tieneLicencia = true;\nlet esEstudiante = false;\nlet tieneTrabajo = true;\n\n// Operador AND (&&)\nconsole.log(\"Puede conducir legalmente:\", edad >= 18 && tieneLicencia); // Puede conducir legalmente:, true\n\n// Operador OR (||)\nconsole.log(\"Cumple con alguna condición para algo:\", esEstudiante || tieneTrabajo); // Cumple con alguna condición para algo: true\n\n// Combinación de operadores\nconsole.log(\"Cumple con alguna de las condiciones combinadas:\", (edad >= 18 && tieneLicencia) || esEstudiante); //  Cumple con alguna de las condiciones combinadas: true\n\n// Definimos algunas variables para ejemplificar\nedad = 25;\ntieneLicencia = true;\nesEstudiante = false;\ntieneTrabajo = true;\n\n// Operador de negación (!)\nlet esFalso = !esEstudiante;\nconsole.log(\"¿Es falso?\", esFalso); // Devuelve true\n\n// Operador de incremento (++)\nlet contador = 5;\ncontador++;\nconsole.log(\"Contador después del incremento:\", contador); // Devuelve 6\n\n// Operador de decremento (--)\nlet otroContador = 8;\n--otroContador;\nconsole.log(\"Contador después del decremento:\", otroContador); // Devuelve 7\n\n// Operador de tipo (typeof)\nlet miNombre = \"Juan\";\nconsole.log(\"Tipo de dato de miNombre:\", typeof miNombre); // Devuelve \"string\"\n\n// Operador de negación binaria (~)\nlet numeroBinario = 5; // Representación binaria: 00000101\nlet resultadoNegacionBinaria = ~numeroBinario; // Representación binaria: 11111010\nconsole.log(\"Resultado de la negación binaria:\", resultadoNegacionBinaria); // Devuelve -6\n\n/** \n *  El operador ! invierte el valor de verdad de una expresión.\n *  El operador ++ incrementa una variable en 1. \n * El operador -- decrementa una variable en 1.\n * El operador typeof devuelve el tipo de dato de una expresión.\n * El operador ~ realiza la negación binaria de un número.\n */\n\n// Operadores ternarios ? Verdadero. : Falso.\n\nedad = 20;\ntieneLicencia = true;\n\n// Operador ternario para asignar un valor\nesMayorDeEdad = edad >= 18 ? \"Sí\" : \"No\";\nconsole.log(\"¿Es mayor de edad?\", esMayorDeEdad); // Devuelve \"Sí\"\n\n\n// EXTRA\n\nfor (let numero = 10;\n    numero <= 55; numero += 2) {\n    if (numero !== 16 && numero % 3 !== 0) {\n        console.log(numero);\n    }\n}\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/anjamape1972.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n// Operadores\n\n    // Aritméticos\n    console.log (\"*** OPERADORES ARITMÉTICOS ***\")\n    console.log (`Suma 10 + 3 = ${10+3}`);\n    console.log (`Resta 10 - 3 = ${10-3}`);\n    console.log (`Multiplicación 10 * 3 = ${10*3}`);\n    console.log (`División 10 / 3 = ${10/3}`);\n    console.log (`Módulo ó resto 10 // 3 = ${10%3}`);\n    console.log (`Potencia 10 ^ 3 = ${10**3}`);\n    console.log (\"\");\n\n    // Asignación\n    console.log (\"*** OPERADORES DE ASIGNACIÓN ***\")\n    let a = 10;\n    console.log (`Se asigna a la variable a un valor = ${a}`);\n    a += 3;\n    console.log (`Con += se incrementa la variable a en el valor que se indique: a+=3 es ${a}`);\n    a -= 3;\n    console.log (`Con -= se disminuye la variable a en el valor que se indique: a-=3 es ${a}`);\n    a *= 3;\n    console.log (`Con *= se multiplica la variable a por el valor que se indique: a*=3 es ${a}`);\n    a /= 3;\n    console.log (`Con /= se divide la variable a por el valor que se indique: a/=3 es ${a}`);\n    a **= 3;\n    console.log (`Con **= se eleva la variable a el número de veces que el valor nos indique: a**=3 es ${a}`);\n    console.log (\"\");\n\n    // Comparación\n    console.log (\"*** OPERADORES DE COMPARACIÓN ***\")\n    console.log (`Con == se comprueba si hay igualdad solo de valor, no de tipo. Por ejemplo, para comparar si 5 (número) y 5 (string) es lo mismo en cuanto a valor sería ${5 == \"5\"}`); // true (compara solo el valor)\n    console.log (`Con === se comprueba si hay igualdad tanto de valor como de tipo. Por ejemplo, para comparar si 5 (número) y 5 (string) es lo mismo en cuanto a valor y tipo sería ${5 === \"5\"}`); // false (compara valor y tipo)\n    console.log (`Con != se comprueba si hay diferencia solo de valor, no de tipo. Por ejemplo, para comparar si 5 (número) y 5 (string) es diferente solo en cuanto a valor ${5 != \"5\"}`); // false (compara solo el valor)\n    console.log (`Con !== se comprueba si hay diferencia tanto de valor como de tipo. Por ejemplo, para comparar si 5 (número) y 5 (string) es diferente en cuanto a valor y tipo sería ${5 !== \"5\"}`); // true (compara valor y tipo)\n    console.log (`Con > se comprueba si el valor de la izquierda es mayor que el de la derecha. Por ejemplo en 10 > 5 nos da ${10 > 5}`); // true\n    console.log (`Con < se comprueba si el valor de la izquierda es menor que el de la derecha. Por ejemplo en 10 < 5 nos da ${10 < 5}`); // false\n    console.log (`Con >= se comprueba si el valor de la izquierda es mayor o igual que el de la derecha. Por ejemplo en 10 >= 5 nos da ${10 >= 5}`); // true\n    console.log (`Con <= se comprueba si el valor de la izquierda es menor o igual que el de la derecha. Por ejemplo en 10 <= 5 nos da ${10 <= 5}`); // false\n    console.log (\"\");\n\n    // Lógicos\n    console.log (\"*** OPERADORES LÓGICOS ***\")\n    let x = true, y = false;\n    console.log (`Con el operador && indicamos que si las dos condiciones que pongamos deben ser verdaderas. En este caso x = ${x} e y = ${y}, por lo tanto si las comparamos con && nos debe dar ${x && y}`); // false\n    console.log (`Con el operador || indicamos que una de las dos condiciones que pongamos debe ser verdadera. En este caso x = ${x} e y = ${y}, por lo tanto si las comparamos con || nos debe dar ${x || y}`); // true\n    console.log (`Con el operador ! antes de una variable hacemos que la nos devuelva el valor contrario de la variable. En este caso x = ${x}, por lo tanto hacer !x nos dará ${!x}`); // false\n    console.log (\"\");\n\n    // Incremento y decremento\n    console.log (\"*** OPERADORES DE INCREMENTO Y DECREMENTO ***\")\n    let z = 5;\n    console.log (`El valor de la variable z ahora es de: ${z}`);\n    console.log (`Si a la variable le añadimos detrás ++ le indicamos que incremente su valor después de usarla. Si lo hacemos ahora mostrará su valor y luego se incrementará: ${z++}`); // Muestra 5 (pero x ahora es 6)\n    console.log (`Ahora se incrementa su valor y la variable z vale: ${z}`);\n    console.log (`Si a la variable le añadimos delante ++ le indicamos que incremente su valor antes de usarla. Si lo hacemos ahora incrementará su valor antes de empezar a trabajar con ella: ${++z}`); // Muestra 7 (x se incrementa antes de mostrar)\n    console.log (\"\");\n\n    // Tipo\n    console.log (\"*** OPERADORES DE TIPO ***\")\n    console.log (`Con typeof comprobamos el tipo de dato que le indicamos justo después: typeof \"Hola\" nos debe dar string. Lo comprobamos: ${typeof \"Hola\"}`); // \"string\"\n    console.log (`En el caso de typeof 10 nos debe dar number. Veamos: ${typeof 10}`); // \"number\"\n    console.log (`Con instanceof comprobamos si un objeto es de un tipo de dato específico. En este ejemplo creamos un objeto con new Date () de tipo dato y luego preguntamos si ese objeto es instanceof Date. Veamos: escribimos console.log (new Date () instanceof Date): ${new Date() instanceof Date}`);\n    console.log (\"\");\n\n// Estructuras de control\n\n    // Condicionales\n    console.log (\"*** OPERADORES CONDICIONALES ***\")\n        // if, else if, else\n        console.log (\"*** if, else if, else ***\")\n        let miEdad = 52;\n        if (miEdad >= 14 && miEdad <16) {\n            console.log (`Puedes conducir ciclomotores.`);\n        } else if (miEdad >= 16 && miEdad < 18) {\n            console.log (`Próximamente podrá tener el permiso A1.`);\n        } else {\n            console.log (`Puedes sacarte el carnet de conducir con A2.`);\n        }\n        console.log (\"\");\n\n        // switch\n        console.log (\"*** switch ***\")\n        let nombre = `Juan`\n        switch (nombre) {\n            case `Pepe`:\n                console.log (`Hola Pepe.`);\n                break;\n            case `Antonio`:\n                console.log (`Hola Antonio.`);\n                break;\n            case `Ana`:\n                console.log (`Hola Ana`);\n                break;\n            default:\n                console.log (`Hola ${nombre}.`)\n        }\n        console.log (\"\");\n        \n        // Ternarios\n        console.log (\"*** OPERADORES TERNARIOS ***\")\n        console.log (`Los operadores ternarios son ? y : y se usan para expresar condiciones. Se comprueba si se cumple una condición o no. Si se cumple se ejecuta lo que haya despues de la ? y antes de : y si no se cumple la condición se ejecuta solo lo que hay detrás de :`)\n        let edad = 18;\n        let mensaje = (edad >= 18) ? \"Eres mayor de edad\" : \"Eres menor de edad\";\n        console.log (mensaje);\n        console.log (\"\");\n\n    // Iterativas (bucles)\n        // for\n        console.log (\"*** for ***\");\n        console.log (\"Con `for` hacemos que se repita algo un número controlado de veces.\");\n        console.log (\"Vamos a escribir los números pares que hay del 1 al 50.\");\n        for (let i = 1; i <= 50; i++) {\n            if (i % 2 === 0) {\n                console.log (i);\n            }\n        }\n        console.log (\"\");\n\n        // while\n        console.log (\"*** while ***\");\n        console.log (\"Con `while` hacemos que se repita algo un número indeterminado de veces, hasta que se cumpla alguna condición.\");\n        console.log (\"Vamos a escribir un programa que pida un número y no pare hasta que le demos el número correcto (será el 1234).\");\n        let clave = 1234;\n        let contraseña;\n        while (contraseña !== clave) {\n            contraseña = parseInt (prompt (\"Escriba un número de 4 cifras: \"));\n        }\n        console.log (\"ENHORABUENA. Has dado con la contraseña.\");\n        console.log (\"\");\n\n        // do... while\n        console.log (\"*** do... while ***\");\n        console.log (\"Con `do... while` hacemos que primero se ejecute alguna acción y luego se repita algo un número indeterminado de veces, hasta que se cumpla alguna condición.\");\n        console.log (\"Hagamos el mismo programa de antes pero usando el `do... while`.\")\n        let key = 1234;\n        let password;\n        do {\n            password = parseInt (prompt (\"Escriba un número de 4 cifras: \"));\n        }\n        while (password !== key);\n        console.log (\"ENHORABUENA. Has dado con la contraseña.\");\n        console.log (\"\");\n\nconsole.log (\"Ejemplo de programa: números pares, no divisibles por 3 ni igual a 16\")\nfor (let number = 10; number <= 55; number++) {\n    if (number % 2 === 0 && number !== 16 && number % 3 !== 0) {\n        console.log (number);\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/ant000o.js",
    "content": "// Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje: Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n\n\n\n// Operadores de Asignación y Aritméticos\nlet x = 12; // Asignación simple\nx += 1; // Suma\nx -= 2; // Resta\nx *= 2; // Multiplicación\nx /= 2; // División\nx %= 2; // Residuo\nx **= 3 // Exponencial\nx++ // Incremento\nx--; // Decremento\nconsole.log(x);\n\nconsole.log('----------------------------------------------------------------------------')\n\n// Operadores Lógicos de Asignación\nx = true;\nx &&= 10; // Se asigna 10 a x solo si x es truthy.\nconsole.log(x);\nx = false;\nx ||= 5; // Se asigna 5 a x solo si x es falsy.\nconsole.log(x);\nx = null;\nx ??= 20; // Se asigna 20 a x solo si x es null o undefined.\nconsole.log(x);\n\nconsole.log('----------------------------------------------------------------------------')\n\n// Operadores de Comparación\nlet y = (x == 8); // Igual a.\nconsole.log(y);\ny = (x === '5'); // Igual valor y tipo de dato.\nconsole.log(y);\ny = (x != 8) // Distinto de.\nconsole.log(y);\ny = x !== 8; // Distinto valor o tipo de dato\nconsole.log(y);\ny = x >= 8; // Mayor o igual a\nconsole.log(y);\ny = x <= 8; // Menor o igual a\nconsole.log(y);\n\n\nconsole.log('----------------------------------------------------------------------------')\n\n//  Utilizando las operaciones con operadores que tú quieras, crea ejemplos que representen todos los tipos de estructuras de control que existan en tu lenguaje: Condicionales, iterativas, excepciones...\n//  Debes hacer print por consola del resultado de todos los ejemplos.\n\n// Estructuras de Control\n\n// Condicionales:\n\n// if else:\nlet juegos = 10;\nif (juegos > 10) {\n    console.log(\"Más de 10 juegos\")\n} else {\n    console.log(\"Menos de 10 juegos\")\n};\n// if else en ternario\njuegos = 20\nlet cantidad = juegos > 10 ? \"Más\" : \"Menos\";\nconsole.log(cantidad);\n\nconsole.log('----------------------------------------------------------------------------')\n\n// switch\nlet dia = \"Sábado\"\nswitch(dia){\n    case \"Viernes\":\n        console.log('Mañana es Sábado');\n        break;\n    case \"Domingo\":\n        console.log('Ayer fue Sábado');\n        break;\n    default:\n        console.log('Hoy es ' + dia);\n}\n\nconsole.log('----------------------------------------------------------------------------')\n\n// Iterativas\n\n// for\nlet i;\nfor (i = -2 ; i < 5 ; i++){\n    console.log(\"El número es \"+ i);\n};\n\nconsole.log('----------------------------------------------------------------------------')\n\n// while\nwhile (i < 10){\n    i++;\n    console.log(i);\n};\n\nconsole.log('----------------------------------------------------------------------------')\n\n// do while\ni = 0;\ndo {\n    i++;\n    console.log(i);\n} while (i < 15);\n\nconsole.log('----------------------------------------------------------------------------')\n\n// for of\nfor (const letra of \"hola\"){\n    console.log(letra);\n};\n\nconsole.log('----------------------------------------------------------------------------')\n\n// for in\nconst user = {nombre: \"ant000o\", edad: 21}\nfor (const x in user){\n    console.log(x, user[x]);\n}\n\nconsole.log('----------------------------------------------------------------------------')\n\n// Excepciones\n\n// break\nfor (i = 0; i < 10; i++){\n    if (i === 3) {break}\n    console.log(i);\n}\n\nconsole.log('----------------------------------------------------------------------------')\n\n// continue\nfor (i = 0; i < 10; i++){\n    if (i === 2) continue;\n    console.log(i);\n}\n\nconsole.log('----------------------------------------------------------------------------')\n\n// Errores\nx = 20;\ntry{\n    x = z + 20;\n}catch(error){\n    console.log(\"Error:\", error.message);\n}finally{\n    console.log(\"Siempre se ejecuta\");\n}\n\nconsole.log('----------------------------------------------------------------------------')\nconsole.log('----------------------------------------------------------------------------')\n\n\n//  * DIFICULTAD EXTRA (opcional):\n//  * Crea un programa que imprima por consola todos los números comprendidos entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n//  * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\nfor (let i = 10; i <= 55; i++){\n    if (i % 2 === 0 && i != 16 && i % 3 != 0){\n    console.log(i);\n}}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/arbenisacosta.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n */\n\n\n/**\n  En JavaScript encontramos cinco tipos de operadores:\n  * Aritméticos\n  * Lógicos\n  * De comparación\n  * Binarios\n  * De asignación\n  * Otros\n */\n\n// ---- tipos de operadores ----\n\nconsole.log(\"---- TIPOS DE OPERADORES ----\");\n\n// ---- Aritméticos\nconsole.log(\"---- Aritméticos ----\");\n\nlet num1 = 2, num2 = 2;\n\nlet mult = num1 * num2; // Multiplicación\nconsole.log(mult);\n\nlet divi = num1 / num2; // División\nconsole.log(divi);\n\nlet suma = num1 + num2; // Suma\nconsole.log(suma);\n\nlet rest = num1 - num2; // Resta\nconsole.log(rest);\n\nlet mod = num1 % num2; // modulo\nconsole.log(mod);\n\n// ---- Lógicos\nconsole.log(\"---- Lógicos ----\");\n\nlet facil = true, dificil = false;\n\nconsole.log(!dificil); //Negación lógica ! (Not). Establece una negación lógica en una expresión\n\nconsole.log(facil && dificil); //Conjunción lógica && (And). Establece una conjunción lógica de dos expresiones\n\nconsole.log(facil || dificil); // Disyunción lógica || (Or). Establece una disyunción lógica de dos expresiones\n\nconsole.log(facil ^ dificil); //Exclusión lógica ^ (Xor). Establece una exclusión lógica de dos expresiones\n\n// ---- De comparación\nconsole.log(\"---- De comparación ----\");\n\nconsole.log(1 < 2); //Menor que (<)\n\nconsole.log(7 <= 8); //Menor o igual que (>=)\n\nconsole.log(5 > 2); //Mayor que (>)\n\nconsole.log(7 >= 8); //Mayor o igual que (>=)\n\nconsole.log( 2 == \"2\"); //Igualdad (==) Verifica la igualdad de dos expresiones sin tener en cuenta el tipo de dato.\n\nconsole.log(2 === \"2\"); //Igualdad estricta (===) Hace lo mismo que el anterior, pero verificando también que coincidan los tipos de datos.\n\nconsole.log(2 != \"2\"); //Desigualdad (!=) Funciona de la misma forma que la igualdad, pero negándola.\n\nconsole.log(2 !== \"2\"); //Desigualdad estricta (!==) Lo mismo que la igualdad estricta, pero negándola.\n\n// ---- De asignación\nconsole.log(\"---- De asignación ----\");\n// Asignación simple (=) Asigna un contenido a una variable o a un objeto.\n/*\nEn JavaScript el operador de asignación tiene la\nparticularidad de que puede combinarse con algunos de\nlos operadores aritméticos, dando lugar a toda una\nfamilia de nuevos operadores:\n*/\n\nlet asign = 10;\nconsole.log(\"asign = 10:\", asign);\nasign += 7;\nconsole.log(\"asign += 7:\", asign);\nasign -= 4;\nconsole.log(\"asign -= 4:\", asign);\nasign *= 4;\nconsole.log(\"asign *= 2:\", asign);\nasign /= 2;\nconsole.log(\"asign /= 2:\", asign);\n\nasign %= 4;\nconsole.log(\"asign %= 4:\", asign);\nasign ^= 4;\nconsole.log(\"asign ^= 2:\", asign);\nasign &= 2;\nconsole.log(\"asign &= 2:\", asign);\nasign |= 2;\nconsole.log(\"asign |= 2:\", asign);\n\n\n\n// ---- Binarios\nconsole.log(\"---- Binarios ----\");\n\n// Bitwise logical operators\n//  &  ->  AND\n//  |  ->  OR\n//  ^  ->  XOR\n\nlet x = 6, y = 12, z = 0;\n\n// x -> 6 = 00000110\n// y -> 12 = 00001100\n// z -> 0 = 00000000\n\nz = x & y;\nconsole.log(\"AND = \",z);\n\nz = x | y;\nconsole.log(\"OR = \",z);\n\nz = x ^ y;\nconsole.log(\"XOR = \",z);\n\n// Bitwise shift operators\n//  <<\n//  >>\n//  >>>\n\nz = x << 2;\nconsole.log(\"<< = \",z);\n\nz = x >> 2;\nconsole.log(\">> = \",z);\n\n\nconsole.log(\"---- ESTRUCTURA DE CONTROL ----\");\n\n\nconsole.log(\"---- CONDICIONALES\");\n// Los condicionales nos permiten evaluar si una condición cumple o no con lo que estemos evaluando.\n\nconsole.log(\"if else\");\nlet mayorEdad = 18;\n\nif (mayorEdad >= 18) {\n  console.log(\"Es Mayor de Edad\");\n} else {\n  console.log(\"Es Menor de Edad\");\n}\n\nif (mayorEdad >= 18) {\n  console.log(\"Es Mayor de Edad\");\n} else if(mayorEdad > 18 && mayorEdad < 25) {\n  console.log(\"Es un adulto Joven\");\n} else {\n  console.log(\"Es menor de edad\");\n}\n\nconsole.log(\"---- Ciclos, Bucles o Loops\");\n// Se le pueden llamar, ciclos, bucles o loops, en ellos se evalua una condición n veces hasta que esta se cumpla.\n\nconsole.log(\"For\");\n// Un bucle for se repite como mencione hasta que la condición que se esta evaluando se cumpla.\n\nlet pasos = 5;\nfor (let paso = 0; paso <= pasos; paso++) {\n  console.log(\"Estoy dando el siguiente paso \" + paso);\n}\n\nconsole.log(\"while\");\n// Ejecuta una sentencia mientras la condición que se este evaluando sea verdadera.\n\nlet contador = 0;\nwhile (contador < 3) {\n  contador++;\n  console.log(\"Contador es igual a: \", contador);\n}\n\nconsole.log(\"Switch\");\n// Permite evaluar una expresión e intenta igual el valor de esa expresión a una etiqueta llamada case, que es el caso a evaluar.\n\nlet tipoFrutas = \"Manzana\"\n\nswitch (tipoFrutas) {\n  case \"Naranja\":\n    console.log(\"Precio de la Naranja: 5$\");\n    break;\n  case \"Manzana\":\n    console.log(\"Precio de la Manzana: 10$\");\n    break;\n  case \"Fresa\":\n    console.log(\"Precio de la Fresa: 15$\");\n    break;\n\n  default:\n    console.log(\"No tenemos ese tipo de fruta\");\n    break;\n}\n\nconsole.log(\"---- EXTRA ----\");\n\n/**\n *  DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\nlet numero = 10;\n\nwhile (numero <= 55) {\n    if (numero % 2 === 0 && numero !== 16 && numero % 3 !== 0) {\n        console.log(numero);\n    }\n    numero++;\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/asaelz.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n/********************************\n ** TIPOS DE OPERADORES EN JS\n * 1. Operadores de asignación\n * 2. Operadores de comparación\n * 3. Operadores aritméticos \n * 4. Operadores lógicos \n * 5. Operadores de cadena\n * 6. Operador condicional ternario\n * 7. Operadores coma \n * 8. Operadores unitarios \n * 9. Operadores relacionales \n *********************************/\n\n/* 1. Operadores de asignación */\n/**\n *  Es utilizado para asignar un valor a su operando izquierdo basándose en el valor de \n *  su operando derecho.\n *  Ejemplo: x=y, x ahora tiene el valor de y asignado.\n *  Existen algunas variantes tales como: \n *  Asignación de adición: x += y esto se refiere a x = x + y\n *  Asignación de resta: x -= y esto se refiere a x = x - y\n */\nlet x = 1, y = 2\nx += 1\ny -= 2\n\n/* 2. Operadores de comparación */\n/**\n * Compara sus operandos y devuelve un valor lógico en función de su la comparación es verdadera (true) \n * o falsa (false).\n */\nlet ItemsSolicitados = 1, Stock = \"1\"\n/**\n * Igual (=) -> Devuelve true si los operadores son iguales, sin importar el tipo, como vemos en el ejemplo:\n * ItemsSolicitados es Number y Stock es String pero ambos contienen el numero 1\n */\nlet resultado = ItemsSolicitados == Stock // true \n/**\n * No es igual (!=) Devuelve true si los operadores no son iguales\n */\nresultado = ItemsSolicitados != stock // false\n/**\n * Estrictamente igual (===) Devuelve true si los operadores y tipos son iguales\n */\nresultado = ItemsSolicitados === stock\n/**\n * Mayor que (>)\n * Menor que (<)\n * Mayor o igual que (>=)\n * Menor o igual que (<=)\n */\nStock = 5\nconsole.log(ItemsSolicitados > Stock) //false \nconsole.log(ItemsSolicitados < Stock) //true\nconsole.log(ItemsSolicitados >= Stock) // false \nconsole.log(ItemsSolicitados <= Stock) // true\n\n/**\n * 3. OPERADORES ARITMETICOS\n * Residuo %\n * Incremento ++\n * Decremento --\n * Negación Unitaria -\n * Positivo Unitario +\n * Exponenciación **\n */\nconsole.log(12 % 5) // 2\n++Stock // 6\n--Stock // 5\n-Stock // -5\n+Stock // 5\nconsole.log(2 ** 3) // 8  \n\n/**\n * 4. OPERADORES LOGICOS\n * && AND\n * || OR\n * -! NOT\n*/\nconsole.log(true && true) //true \nconsole.log(true || true) //true \nconsole.log(!true) //false \n\n/**\n *  5. OPERADORES DE CADENA\n */\nconsole.log(\"esto\" + \"es un ejemplo\")\n/**\n * 6. OPERADOR TERNARIO \n */\nlet edad = 15\nconsole.log(edad >= 18 ? \"puede votar\": \"no puede votar xd\")\n/**\n * 7. OPERADOR COMA\n */\nfor (let i=0, j=2; i<=j; i++, j--){\n    console.log(i, j)\n}\n/**\n * 8.OPERADORES UNITARIOS\n * delete\n * typeof\n */\nconsole.log(typeof true)\n/**\n * 9.OPERADORES RELACIONES\n * IN \n */\nlet prueba = ['prueba', 'de', 'operador', 'in']\nconsole.log(0 in prueba) // true porque el indice 0 si esta contenido\n/**\n * ESTRUCTURAS DE CONTROL\n */\nif (edad >=18)\n{\n    console.log(\"Sos mayor de edad xd\")\n} \nelse {\n    console.log(\"Sorry, todavia estas peque\")\n}\n\n/** BUCLE FOR*/\nconst etapa = 2\nfor (let index = 0; index < etapa; index++) {\n    console.log(\"Etapa: \" +etapa) \n}\n/**WHILE */\nlet etapas = 1\nwhile (etapas <= 2) {\n    etapas++\n}\nconsole.log(\"Etapa actual: \" +etapas)\n/*SWITCH*/\nswitch (\"Lunes\") {\n    case \"Lunes\":\n        console.log(\"Es Lunes, te toca levantarte antes\")\n        break;\n\n    default:\n        console.log(\"No es Lunes, puedes dormir más\")\n        break;\n}\n\n/* DIFICULTAD EXTRA */\nfor (let index = 10; index <= 55; index++) {\n    \n    if (index%2===0 && index != 16 && index%3!=0){\n        console.log(index)\n    }\n    \n}\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/balta16.js",
    "content": "//pagina web de JavaScript: https://developer.mozilla.org/en-US/docs/Web/javascript\n\n//comentario simple\n\n/*comentario\nmultiple*/\n\nlet nombre\nconst apellido\n\nlet string = \"esto es un string\"\nlet entero = 8\nlet decimal = 3.14\nlet boolean = true\nlet nulo = null\nlet indefinido = undefined\nlet numeroGrande = 951919198984844848481515611n\n\nlet nombreLenguaje = JavaScript\nconsole.log(\"Hola, \" + nombreLenguaje + \"!\");\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/bernatcs.js",
    "content": "// -1-\n\n// Operadores aritméticos: Realizar operaciones matemáticas\n\nlet suma = 4 + 4 // También es un operador de cadenas y se puede usar para enlazar cadenas\nconsole.log(suma)\n\nlet resta = 12 - 4\nconsole.log(resta)\n\nlet multiplicación = 2 * 4\nconsole.log(multiplicación)\n\nlet división = 40 / 5\nconsole.log(división)\n\nlet módulo = 35 % 9\nconsole.log(módulo)\n\nlet exponenciacion = 2.82842712475 ** 2\nconsole.log(exponenciacion)\n\nlet incremento = 7\nincremento++\nconsole.log(incremento)\n\nlet decremento = 9\ndecremento--\nconsole.log(decremento)\n\n// Operadores de Bits: Realizar operaciones a nivel de bits (hay más pero estos son los que me interesaban)\n\nlet DesplazamientoIzquierda = 2 << 2\nconsole.log(DesplazamientoIzquierda)\n\nlet DesplazamientoDerecha = 32 >> 2\nconsole.log(DesplazamientoDerecha)\n\n// Operadores de asignación: Asignar valores a las variables\n\nlet asignación = '8 = 8'\nconsole.log(asignación)\n\nlet asignaciónDeSuma = 6\nasignaciónDeSuma += 2\nconsole.log(asignaciónDeSuma)\n\nlet asignaciónDeResta = 10\nasignaciónDeResta -= 2\nconsole.log(asignaciónDeResta)\n\nlet asignaciónDeMultiplicacion = 4\nasignaciónDeMultiplicacion *= 2\nconsole.log(asignaciónDeMultiplicacion)\n\nlet asignaciónDeDivision = 16\nasignaciónDeDivision /= 2\nconsole.log(asignaciónDeDivision)\n\nlet asignaciónDeModulo = 35\nasignaciónDeModulo %= 9\nconsole.log(asignaciónDeModulo)\n\nlet asignaciónDeExponenciacion = 2.82842712475\nasignaciónDeExponenciacion **= 2\nconsole.log(asignaciónDeExponenciacion)\n\nlet asignaciónDeDesplazamientoIzquierda = 2\nasignaciónDeDesplazamientoIzquierda <<= 2\nconsole.log(asignaciónDeDesplazamientoIzquierda)\n\nlet asignaciónDeDesplazamientoDerecha = 32\nasignaciónDeDesplazamientoDerecha >>= 2\nconsole.log(asignaciónDeDesplazamientoDerecha)\n\n// Operadores de Comparación: Comparar dos variables\n\nlet igualA = '8'\nigualA == 8\n\nlet estrictamenteIgualA = 8\nestrictamenteIgualA === 8\n\nlet noIgualA = '-8'\nnoIgualA != 8\n\nlet estrictamenteNoIgualA = -8\nestrictamenteNoIgualA != 8\n\nlet mayorQue = 9\nmayorQue > 8\n\nlet menorQue = 7\nmenorQue < 8\n\nlet mayorOIgualQue = 8\nmayorOIgualQue >= 8\n\nlet menorOIgualQue = 8\nmenorOIgualQue <= 8\n\n// Operadores Lógicos: Realizar operaciones lógicas\n\nlet AND = 8\nif (AND == 8 && AND !== 8) {\n    console.log('Mucho 8')\n}\n\nlet OR = 8\nif (OR == 8 || OR > 8) {\n    console.log('O 8 o mayor')\n}\n\nlet NOT = false\n!NOT //= true\nconsole.log()\n\n// Operadores de Tipo: determinan el tipo de una variable u objeto\n\nlet value = 8\nfunction object(){\n}\n\nconsole.log(typeof(value)) // number\n\nconsole.log(value instanceof object); // false\n\n// Operadores Unarios: Operan en un solo operando (hay más pero estos son los que me interesaban)\n\nlet string = '8'\n\nlet convertirANumero = +string\nconsole.log()\n\nlet convertirANumeroNegativo = -string\nconsole.log()\n\n// -2-\n\n// Estructuras de Control Condicional: Tomar decisiones basadas en condiciones\n\nif (value == 8) {\n    console.log('Es 8')\n} else if (value == 40320) {\n    console.log('Es 8!')\n} else {\n    console.log('No es 8')    \n} \n\nlet resultado = (value == 8) ? \"Es 8\" : \"No es 8\"\n\nswitch (value) {\n    case 8:\n        console.log('Es 8')\n      break;\n    case 40320:\n        console.log('Es 8!')\n      break;\n    default:\n        console.log('No es 8')    \n  }\n\n// Estructuras de Control de Bucles: Repetir bloques de código varias veces\n\nfor (var forVar = 0; forVar <= 8; forVar++) {\n    console.log(forVar) // 0, 1, 2, 3, 4, 5, 6, 7, 8\n  }\n\nwhile (value == 8) {\n    console.log('Es 8')\n    break;\n}\n\ndo {\n    console.log('Es 8')\n    break;\n} while (value == 8)\n\n// Estructuras de Control de Saltos (representadas por el código de este archivo)\n\n/*\n\nbreak --> Sale del bucle\ncontinue --> Omite el resto del código del bucle y continúa\nreturn --> Sale de la función y devuelve el valor de la función\nthrow --> Lanza una función definida por el usuario\n\n*/\n\n// Estructuras de Control de Excepciones: Manejar errores y excpeciones\n\ntry {\n    if (value == 8) {\n        throw new Error('Demasiado igualación a 8, estoy harto')\n    }\n  } catch (error) {\n    console.error(`Se produjo el error: ${error.message}`)\n  } finally {\n    console.log('Operación finalizada')\n  }\n\n\n// -3- Dificultad extra\n\nfor (var ejercicioExtra = 10; ejercicioExtra <= 55; ejercicioExtra++) {\n    if (ejercicioExtra % 2 || ejercicioExtra == 16 || !(ejercicioExtra % 3)) {\n        continue;\n    }\n    console.log(ejercicioExtra)\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/blancowilson.js",
    "content": "let cadena = 'String';\nlet bool = true;\nlet nothing = null;\nlet array = [1, 2, 3, 4];\nlet number = -4;\nconst PI = 3.1416;\nlet lenguaje = 'JavaScript';\nlet counter = 1;\nlet objeto = {\n  name: 'Wilson',\n  edad: 41,\n};\n\nif (number < 0) {\n  console.log('El numero es negativo');\n} else {\n  console.log('El nuemro es positivo');\n}\n\nswitch (objeto.edad) {\n  case 1:\n    console.log('El numero es 1');\n    break;\n  default:\n    console.log('Eligiste otro numero diferente ');\n}\n\nfor (let i = 1; i <= 5; i++) {\n  console.log('Numero ', i);\n}\n\nwhile (counter <= 10) {\n  console.log('El contador vale ', counter);\n  counter++;\n}\n\n\nfor (const property in objeto) {\n  console.log(\n    `la propiedad ${property} tiene un valor de: ${objeto[property]}`\n  );\n}\n\ntry {\n  console.log('Antes del error');\n  throw new TypeError('oops');\n} catch ({ name, message }) {\n  console.log(name); // \"TypeError\"\n  console.log(message); // \"oops\"\n}\n\ntry {\n  throw 'Oops; this is not an Error object';\n} catch (e) {\n  if (!(e instanceof Error)) {\n    e = new Error(e);\n  }\n  console.log(e);\n  console.error(e.message);\n}\n\n// ejercicio\n// Crea un programa que imprima por consola todos los números comprendidos\n//  * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\nfor (let i = 10; i <= 55; i++) {\n  if (i % 2 === 0) {\n    if (i % 3 !== 0 && i !== 16) {\n      console.log(i);\n    }\n  }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/bmayo08.js",
    "content": "/* Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n */\n\nlet resta = `resta de 10 -5 igual a ${10 - 5}`\nlet suma = ` suma de 10 + 5 igual a ${10 + 5}`\nlet division = `division de 10/5 igual a${10 / 5}`\nlet multiplicaion = `multiplicacion de 10/5 igual a ${10 * 5} `\nlet modulo = `modulo de 10%5 igual a ${10 % 5} `\nlet exponente = `exponente de 10**5 igual a ${10 ** 5} `\n\nlet mayorQue = 5 > 1;\nlet menorQue = 5 < 1;\nlet mayorOIgualQue = 5 >= 1;\nlet menorOIgualQue = 5 <= 1;\nlet iguales = 5 === '5';\nlet igualesNoEsticto = 5 == '5';\nlet desigual = 5 != '5';\nlet desigualEstricto = 5 !== '5';\n\nlet and_operator = first_bool && second_bool;   // AND\nlet or_operator = first_bool || second_bool;    // OR\nlet not_operator = !(first_bool);   \n\nconsole.log(exponente)\n\n /*\n- Utilizando las operaciones con operadores que tú quieras, crea ejemplos\nque representen todos los tipos de estructuras de control que existan\nen tu lenguaje:\n- Condicionales, iterativas, excepciones...\n- Debes hacer print por consola del resultado de todos los ejemplos.\n */\nlet nota1 = 3\nlet nota2 = 4\nlet nota3 = 2\nlet promedio = (nota1 + nota2 + nota3) / 5\n\n\nif (promedio >= 3) {\n    console.log(` aprobo la materia-su promedio es:${promedio}`)\n} else if (promedio < 3 && promedio > 2) {\n    console.log(`puede rescuperar la mareteria ${promedio}`)\n\n} else {\n    console.log(`reprobo la materia-su promedio es:${promedio}`)\n}\n\nlet edad = 17\nlet mayor_menor = edad >= 18 ? `eres mayor de edad:${edad}` : `eres menor de edad :${edad}`\nconsole.log(mayor_menor)\n\nfor (let index = 0; index < 20; index++) {\n    console.log(`numeros: ${index}`);\n\n}\nlet i = 0\nwhile (i < 20) {\n    i++\n    console.log(`numeros ${i}`)\n}\ndo {\n    i++\n    console.log(`numeros ${i}`)\n\n} while (i < 20);\n\n\nlet animal = \"loro\";\n\nswitch (animal) {\n    case \"perro\":\n        console.log(`tu mascota es un perro`);\n        break;\n    case \"gato\":\n        console.log(\"tu mascota es un gato\")\n        break;\n    default:\n        console.log(`ingresa si es gato o perro`);\n        break;\n}\ntry {\n    console.log(nombre); // Error: 'nombre' no está definido\n} catch (error) {\n    console.log(\"  hubo un error:\", error.message);\n}\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\nfor (let i = 10; i <= 55; i++) {\n    if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n        console.log(i);\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/caterinarodriguezdev.js",
    "content": "// Operadores Aritméticos\nlet suma = 1 + 1;\nlet resta = 1 - 1;\nlet multi = 1 * 1;\nlet division = 1 / 1;\nlet modulo = 10 % 3;\nlet exponente = 4 ** 2;\nlet leftShift = 5 << 2;\nlet rightShift = 5 >> 2;\nlet rightShiftNoSign = 5 >>> 2;\nlet andBit = 5 & 4;\n\n\nlet incremento = suma++;\nlet decremento = resta--;\n\n// Operadores de asignación\nlet normal = 1;\nsuma += 1;\nresta -= 1;\nmulti *= 1;\ndivision /= 1;\nmodulo %= 1;\nexponente **= 2;\nleftShift <<= 2;\nrightShift >>= 1;\nrightShiftNoSign >>>= 1;\nandBit &= 3;\nnormal &&= 5;\nnormal ||= 3;\nnormal ??= 2;\n\n// Operadores de comparación\nlet mayorQue = 5 > 1;\nlet menorQue = 5 < 1;\nlet mayorOIgualQue = 5 >= 1;\nlet menorOIgualQue = 5 <= 1;\nlet iguales = 5 === '5';\nlet igualesNoEsticto = 5 == '5';\nlet desigual = 5 != '5';\nlet desigualEstricto = 5 !== '5';\n\n// Estructuras de control: CONDICIONALES\n\n// IF ELSE IF ELSE\nlet variable = 1;\nif (variable) {\n    console.log(1);\n} else if (variable) {\n    console.log(2);\n} else {\n    console.log(0);\n}\n\n// OPERADOR TERNARIO\nlet nuevaVar = variable > 1 ? console.log('es mayor que uno') : console.log('es menor que uno');;\n\n// SWITCH\nswitch(variable) {\n    case 1:\n        console.log('switch dice que es 1');\n        break;\n    case 2:\n        console.log('switch dice que es 2');\n        break;\n    default:\n        console.log('no hay concidencias');\n        break;\n}\n\n// Estructuras de control: BUCLES\n\n// FOR\nfor (let i = 1; i <= 10; i++) {\n    console.log('FOR - i es ', i);\n}\n\n// WHILE\nlet i = 1;\nwhile (i <= 10) {\n    console.log('WHILE - i es ', i);\n    i++;\n}\n\n// DO WHILE\nlet j = 1;\ndo {\n    console.log('DO WHILE - j es ', j);\n    j++;\n} while (j <= 10);\n\n// FOR OF\nlet array = ['apple', 'banana', 'mango'];\n\nfor (fruta of array) {\n    console.log('la fruta del momento es ', fruta);\n}\n\n// FOR IN\nlet grace = {\n    genero: 'f',\n    edad: 25,\n    carrera: 'medicina',\n    hobbies: ['escalada', 'repostería', 'bucear'],\n    mascota: 'Loki'\n}\n\nfor (prop in grace) {\n    console.log('Props de Grace', prop);\n}\n\n// Estructuras de control: MANEJO DE ERRORES\n\ntry {\n    let x = y;\n} catch (error) {\n    console.log(`Ha ocurrido el siguiente error: ${error}`);\n} finally {\n    console.log('Acabas de intentar ejecutar un código con errores pero el catch te ha salvado');\n}\n\n/**\n * Resumen de estructuras de control en JavaScript:\n * Condicionales: if, else if, else, switch, operador ternario.\n * Bucles: for, while, do...while, for...of, for...in.\n * Manejo de excepciones: try...catch...finally, throw.\n * Control de flujo: break, continue.\n * Declaraciones de salto: return y throw.\n */\n\n/* DIFICULTAD EXTRA (opcional):\nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3. */\n\nconst programa = () => {\n    for (let i = 10; i <= 55; i++) {\n        if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n            console.log(i);\n        }\n    }\n}\n\nprograma();"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/ceciliarava1.js",
    "content": "// 01-Javascript\n\n\n// Arithmetic operators\nlet number_one = 10\nlet number_two = 3\n\nlet sum = number_one + number_two\nconsole.log(`Sum: ${sum}`)\n\nlet substract = number_one - number_two\nconsole.log(`Substract: ${substract}`)\n\nlet multiply = number_one * number_two\nconsole.log(`Multiply: ${multiply}`)\n\nlet division = (number_one / number_two).toFixed(2)\nconsole.log(`Division: ${division}`)\n\n\n// Control structures\nif (sum != 0) {\n    console.log('The sum is different than zero')\n} else {\n    console.log('The sum is zero')\n}\n\nlet count = 0\nwhile (count < 3) {\n    console.log(sum)\n    count ++\n}\n\ncount = 1\ndo {\n    console.log('Hello') \n    count ++\n} while (count != 3)\n\n\n// Exercise\nfor (let i = 0; i <= 55; i++) {\n    if (i != 16 && i % 3 != 0 && i % 2 == 0) {\n        console.log(i)\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/cesar-ch.js",
    "content": "﻿// Operadores Aritméticos\nlet a = 5;\nlet b = 2;\nconsole.log(\"Suma:\", a + b);\nconsole.log(\"Resta:\", a - b);\nconsole.log(\"Multiplicación:\", a * b);\nconsole.log(\"División:\", a / b);\nconsole.log(\"Módulo:\", a % b);\nconsole.log(\"Incremento:\", ++a);\nconsole.log(\"Decremento:\", --b);\n\n// Operadores de Comparación\nlet x = 10;\nlet y = \"10\";\nconsole.log(\"Igualdad:\", x == y);\nconsole.log(\"Igualdad estricta:\", x === y);\nconsole.log(\"Desigualdad:\", a !== b);\nconsole.log(\"Mayor que:\", a > b);\nconsole.log(\"Menor que o igual:\", a <= b);\n\n// Operadores Lógicos\nlet p = true;\nlet q = false;\nconsole.log(\"AND lógico:\", p && q);\nconsole.log(\"OR lógico:\", p || q);\nconsole.log(\"NOT lógico:\", !p);\n\n// Operadores de Asignación\nlet c = 3;\nc += 2;\nconsole.log(\"Asignación con adición:\", c);\n\n// Operadores de Identidad\nconsole.log(\"Identidad:\", x === 10);\nconsole.log(\"No identidad:\", y !== 10);\n\n// Operadores de Pertenencia\nlet arreglo = [1, 2, 3];\nconsole.log(\"Pertenece al arreglo:\", 2 in arreglo);\n\n// Operadores de Bits\nlet num1 = 5; // Representación binaria: 0101\nlet num2 = 3; // Representación binaria: 0011\nconsole.log(\"AND a nivel de bits:\", num1 & num2); // Resultado: 0001 (1 en binario)\nconsole.log(\"OR a nivel de bits:\", num1 | num2); // Resultado: 0111 (7 en binario)\nconsole.log(\"Desplazamiento a la izquierda:\", num1 << 1); // Resultado: 1010 (10 en binario)\nconsole.log(\"Desplazamiento a la derecha:\", num1 >> 1); // Resultado: 0010 (2 en binario)\n\n// Estructuras de Control\n// Condicionales\nlet edad = 18;\nif (edad >= 18 && edad <= 125) {\n    console.log(\"Eres mayor de edad\");\n} else if (edad < 18) {\n    console.log(\"Eres menor de edad\");\n} else {\n    console.log(\"Edad no valida\");\n\n}\n\n// Excepciones\ntry {\n    let resultado = 10 / 0;\n    console.log(\"Resultado:\", resultado);\n} catch (error) {\n    console.log(\"Error:\", error.message);\n} finally {\n    console.log(\"Finalizado el bloque try-catch\");\n}\n\n// Programa\nfor (let i = 10; i <= 55; i++) {\n    if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n        console.log(i);\n    }\n}\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/cesarocbu.js",
    "content": "//Operadores\nconsole.log(\"OPERADORES\")\n\nconsole.log(\"------------------------\")\n\nconsole.log(\"Aritmeticos:\")\nlet a = 10\nlet b = 5\nlet suma = a + b\nlet resta = a - b\nlet multiplicacion = a * b\nlet division = a / b\nlet modulo = a % b\nconsole.log(\"Numero 1: \" + a, \"Numero 2: \" + b)\nconsole.log(\"Suma:\" + suma)\nconsole.log(\"Resta: \" + resta)\nconsole.log(\"Multiplicación: \" + multiplicacion)\nconsole.log(\"Division: \" + division)\nconsole.log(\"Modulo: \" + modulo)\na++\nb--\nconsole.log(\"Incremento(10): \" + a)\nconsole.log(\"Decremento(5) : \" + b)\n\nconsole.log(\"------------------------\")\n\nconsole.log(\"Lógicos:\")\n\nlet p = true\nlet q = false\nconsole.log(p && q)\nconsole.log(p || q)\nconsole.log(!p)\nconsole.log(\"------------------------\")\n\nconsole.log(\"Comparación:\")\n\nlet num1 = 10\nlet num2 = 5\nconsole.log(\"Num1: \" + num1)\nconsole.log(\"Num2: \" + num2)\n\nconsole.log('==: ')\nconsole.log(num1 == num2)\nconsole.log(\"===: \")\nconsole.log(num1 === num2)\nconsole.log(\"!=: \")\nconsole.log(num1 != num2)\nconsole.log(\"!==: \")\nconsole.log(num1 !== num2)\nconsole.log(\">: \")\nconsole.log(num1 > num2)\nconsole.log(\"<: \")\nconsole.log(num1 < num2)\nconsole.log(\">=: \")\nconsole.log(num1 >= num2)\nconsole.log(\"<=: \")\nconsole.log(num1 <= num2)\n\nconsole.log(\"------------------------\")\n\nconsole.log(\"Asignación:\")\n\nlet x = 10;\nconsole.log(\"x: \" + x)\nx += 5; // x ahora es 15\nconsole.log(\"x += 5: \" + x)\nlet y = 20;\nconsole.log(\"y: \" + y)\ny -= 3; // y ahora es 17\nconsole.log(\"y -= 3: \" + y)\n\nconsole.log(\"------------------------\")\n\nconsole.log(\"Pertenencia:\")\n\nlet persona = {nombre: \"Juan\", edad: 30};\nconsole.log(persona)\nconsole.log('nombre in persona');\nconsole.log(\"nombre\" in persona); //true\nconsole.log('apellido in persona');\nconsole.log(\"apellido\" in persona); //false\n\nconsole.log(\"------------------------\")\n\nconsole.log(\"Bit\");\nlet m = 5; // Representación binaria: 101\nlet n = 3; // Representación binaria: 011\n\nconsole.log(m & n); // 1 (AND bit a bit)\nconsole.log(m | n); // 7 (OR bit a bit)\nconsole.log(m ^ n); // 6 (XOR bit a bit)\nconsole.log(m << 1); // 10 (Desplazamiento a la izquierda)\nconsole.log(n >> 1); // 1 (Desplazamiento a la derecha)\n\nconsole.log(\"------------------------\")\n\nconsole.log(\"Estructuras de control:\");\n\nconsole.log(\"if-else\");\n\nlet numero = 200\nif (numero === 200) {\n    console.log(\"Es el mismo número!\")\n} else {\n    console.log(\"No es el mismo número :C\")\n}\n\nconsole.log(\"For\")\nfor (let i = 0; i < 5; i++) {\n    console.log(\"Iteración número: \" + i);\n}\n\nconsole.log(\"While\")\nlet i = 0\nwhile (i < 5) {\n    console.log(\"Iteración número: \" + i);\n    i++;\n}\n\nconsole.log(\"Switch\")\nlet dia = 2\nswitch (dia) {\n    case 1:\n        console.log(\"Lunes\");\n        break;\n    case 2:\n        console.log(\"Martes\");\n        break;\n    default:\n        console.log(\"Día no válido\");\n}\n\nconsole.log(\"Ejercicio extra:\");\nconsole.log(\"Números entre 10 y 55, pares, y que no son ni el 16 ni múltiplos de 3.\");\nfor (let i = 10; i <= 55; i++) {\n    if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n        console.log(i);\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/christian-jfr.js",
    "content": "// #01 - Operadores y estructuras de control\n\n/* \n * 1. Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n * Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n * (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n*/\n\n// Operadores Aritméticos\nconst num1 = 10; \nconst num2 = 5;\nconst string1 = '10';\n\nconsole.log('Suma: ', num1 + num2); // -> Suma: 15\nconsole.log('Resta: ', num1 - num2); // -> Resta: 5\nconsole.log('Multiplicación: ', num1 * num2); // -> Multiplicación: 50\nconsole.log('División: ', num1 / num2); // -> División: 2\nconsole.log('Módulo: ', num1 % num2); // -> Módulo: 0\nconsole.log('Potencia: ', num1 ** num2); // -> Potencia: 100000\n\nconsole.log('Incremento Postfijo: ', num1++);\nconsole.log('Incremento Prefijo: ', ++num1);\nconsole.log('Decremento Postfijo: ', num2--);\nconsole.log('Decremento Prefijo: ', --num2);\n\n// Operadores de Asignación\n// = Asignación\nlet as = 10;\nconsole.log(as); // -> 10\n// += Suma y asignación\nlet as1 = 10;\nas1 += 2;\nconsole.log(as1); // -> 12\n// -= Resta y asignación\nlet as2 = 10;\nas2 -= 2;\nconsole.log(as2); // -> 8\n// *= Multiplicación y asignación\nlet as3 = 10;\nas3 *= 2;\nconsole.log(as3); // -> 20\n// /= División y asignación\nlet as4 = 10;\nas4 /= 2;\nconsole.log(as4); // -> 5\n// %= Módulo y asignación\nlet as5 = 10;\nas5 %= 2;\nconsole.log(as5); // -> 0\n// **= Potencia y asignación\nlet as6 = 10;\nas6 **= 2;\nconsole.log(as6); // -> 100\n// <<= Desplazamiento a la izquierda y asignación\nlet as7 = 10;\nas7 <<= 2;\nconsole.log(as7); // -> 40\n// >>= Desplazamiento a la derecha y asignación\nlet as8 = 10;\nas8 >>= 2;\nconsole.log(as8); // -> 2\n// >>>= Desplazamiento a la derecha y asignación sin signo\nlet as9 = 2;\nas9 >>>= 2;\nconsole.log(as9); // -> 0\n// &= Bitwise AND y asignación\nlet as10 = 10;\nas10 &= 2;\nconsole.log(as10); // -> 2\n// ^= Bitwise XOR y asignación\nlet as11 = 10;\nas11 ^= 2;\nconsole.log(as11); // -> 8\n// |= Bitwise OR y asignación\nlet as12 = 10;\nas12 |= 2;\nconsole.log(as12); // -> 10\n// &&= logico AND y asignación\nlet as13 = 10;\nas13 &&= 2;\nconsole.log(as13); // -> 2\n// ||= logico OR y asignación\nlet as14 = 10;\nas14 ||= 2;\nconsole.log(as14); // -> 10\n// ??= Asignación de coalescencia nula\nlet as15 = 10;\nas15 ??= 2;\nconsole.log(as15); // -> 10\n\n// Operadores de Comparación\n// Relacionales\nconsole.log('Mayor que: ', num1 > num2); // -> Mayor que: true\nconsole.log('Menor que: ', num1 < num2); // -> Menor que: false\nconsole.log('Mayor o igual que: ', num1 >= num2); // -> Mayor o igual que: true\nconsole.log('Menor o igual que: ',num1 <= num2); // -> Menor o igual que: false\n// Igualdad\nconsole.log('Igualdad: ', num1 == num2); // -> Igualdad: false\nconsole.log('Desigualdad: ', num1 != num2); // -> Desigualdad: true\n// Igualdad estricta\nconsole.log('Igualdad estricta: ', num1 === string1); // -> Igualdad estricta: false\nconsole.log('Desigualdad estricta: ', num1 !== string1); // -> Desigualdad estricta: true\n\n// Operadores Lógicos ! - && - || \nlet opNot = !true;\nlet opAnd = true && false;\nlet opOr = true || false;\n\nconsole.log(opNot, opAnd, opOr); // -> false, false, true\n\n// Operadores Bitwise\nconsole.log('Bitwise AND: ', 3 & 5); // Bitwise AND: 1\nconsole.log('Bitwise OR: ', 1 | 4); // Bitwise OR: 5\nconsole.log('Bitwise XOR: ', 3 ^ 5); // Bitwise XOR: 6\nconsole.log('Bitwise NOT: ', ~3); // Bitwise NOT: -4\nconsole.log('Bitwise LEFT SHIFT: ', 3 << 2); // Bitwise LEFT SHIFT: 12\nconsole.log('Bitwise RIGHT SHIFT: ', 3 >> 2); // Bitwise RIGHT SHIFT: 0\nconsole.log('Bitwise ZERO FILL RIGHT SHIFT: ', 2 >>> 3); // Bitwise ZERO FILL RIGHT SHIFT: 0\n\n// Operadores Unarios\n// delete\nlet myObject = {a: 1, b: 2};\ndelete myObject.a;\nconsole.log(myObject); // -> {b: 2}\n// typeof\nconsole.log(typeof num1); // -> number\n// void\nconst vacio = void 10;\nconsole.log(vacio); // -> undefined\n\n// Operadores relacionales\n// in\nlet numbers = [7, 8, 9];\nconsole.log('a' in numbers); // -> false\nconsole.log(0 in numbers); // -> true\nconsole.log(9 in numbers); // -> false\nconsole.log(length in numbers); // -> true\n// instanceof\nlet myArray = [1, 2, 6];\nconsole.log(myArray instanceof Array); // -> true\nconsole.log(myArray instanceof Object); // -> true\nconsole.log(myArray instanceof String); // -> false\n\n// Operadores de agrupación\n// ()\nconsole.log((1 + 2) * 3); // -> 9\nconsole.log(1 + 2 * 3); // -> 7\n// new\nlet myArray2 = new Array(1, 2, 3);\nconsole.log(myArray2); // -> [1, 2, 3]\n\n/* \n * 2. Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n * que representen todos los tipos de estructuras de control que existan\n * en tu lenguaje.\n * Debes hacer print por consola del resultado de todos los ejemplos.\n*/\n\n// Operador ternario\nlet ternario = 10 > 5 ? 'Mayor' : 'Menor';\nconsole.log(ternario); // -> Mayor\n\n// if/else\nlet condicion = 10 > 5;\nif (condicion) {\n  console.log('10 es mayor que 5'); // Si la condicion es true\n} else {\n  console.log('10 no es mayor que 5'); // Si la condicion es false\n}\n\n// switch\nlet dia = 'lunes';\nswitch (dia) {\n  case 'lunes':\n    console.log('Inicia la semana');\n    break;\n  case 'viernes':\n    console.log('Fin de semana');\n    break;\n  default:\n    console.log('Día intermedio');\n    break;\n}\n\n// try-catch-finally\nlet probar = 'PRUEBA';\ntry {\n    probar = noExiste;  // ReferenceError -> noExiste no existe\n} catch (error) {\n    console.log('Hubo un error'); // -> Hubo un error\n} finally {\n    console.log('Esto es un finally'); // -> Esto es un finally\n}\nconsole.log(probar); // -> PRUEBA\n\n// while\nlet fruits = ['apple', 'banana', 'orange', 'pineapple'];\nlet i = 0;\n\nwhile (i < fruits.length) {\n  console.log(fruits[i]); // Imprime los elementos del array fruits\n  i++;\n}\n\n// do while\nlet j = 0;\ndo {\n  console.log(fruits[j]); // Imprime solo el primer elemento del array fruits\n  j++;\n} while (j < 1);\n\n// for\nfor (let contador = 10; contador >= 0; contador--) {\n  console.log(contador); // Imprime los numeros del 10 al 0\n}\n\n// for of\nfor (let fruit of fruits) {\n  console.log(fruit); // Imprime cada elemento del array fruits\n}\n\n// for in\nlet user = {\n  name: 'John',\n  age: 30,\n  isAdmin: true,\n  email: 'John@example.com'\n};\n\nfor (let prop in user) {\n  console.log(prop); // Imprime las propiedades del objeto user\n  console.log(user[prop]); // Imprime los valores de las propiedades del objeto user\n}\n\n/*\n * 3. DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n*/\nfor (let extra = 10; extra <= 55; extra++) {\n  if (extra % 2 === 0 && extra !== 16 && extra % 3 !== 0) {\n    console.log(extra);\n  }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/christianhernandezb.js",
    "content": "//Ejemplo utilizando todos los tipos de operadores de javascript\n\n//Operadorores aritmeticos\n//Suma\nconst var1 = 2;\nconst var2 = 2;\nconst suma = var1 + var2;\nconsole.log(`suma: ${suma}`);\n\n//Resta\nconst resta = var1 - var2;\nconsole.log(`resta: ${resta}`);\n\n//Multiplicacion\nconst multiplicacion = var1 * var2;\nconsole.log(`multiplicacion: ${multiplicacion}`);\n\n//Division\nconst division = var1 / var2;\nconsole.log(`division: ${division}`);\n\n//Modulo\nconst modulo = var1 % var2;\nconsole.log(`modulo: ${modulo}`);\n\n//Operadores de asignacion\n//Asignacion\nlet varAsig = 2;\nconsole.log(`Asignacion: ${varAsig}`);\n\n//Suma y asigna\nvarAsig += 2;\nconsole.log(`Suma y asigna: ${varAsig}`);\n\n//Resta y asigna\nvarAsig -= 2;\nconsole.log(`Resta y asigna: ${varAsig}`);\n\n//Multiplica y asigna\nvarAsig *= 2;\nconsole.log(`Multiplica y asigna: ${varAsig}`);\n\n//Divide y asigna\nvarAsig /= 2;\nconsole.log(`Divide y asigna: ${varAsig}`);\n\n//Modulo y asigna\nvarAsig %= 2;\nconsole.log(`Modulo y asigna: ${varAsig}`);\n\n//Operadores de comparacion\n//Igualdad debil\nif (1 == 1) {\n  console.log('Igualdad debil');\n}\n\n//Igualdad estricta\nif (1 === 1) {\n  console.log('Igualdad estricta');\n}\n\n//desigualdad debil\nif (2 != 1) {\n  console.log('Desigualdad debil');\n}\n\n//desigualdad estricta\nif (2 !== 1) {\n  console.log('Desigualdad estricta');\n}\n\n//Mayor que\nif (2 > 1) {\n  console.log('Mayor que');\n}\n\n//Menor que\nif (1 < 2) {\n  console.log('Menor que');\n}\n\n//Mayor o igual que\nif (2 >= 2) {\n  console.log('Mayor o igual que');\n}\n\n//Menor o igual que\nif (2 <= 2) {\n  console.log('Menor o igual que');\n}\n\n//Operadores Logicos\n//OR\nif (1 + 1 === 2 || 2 + 2 === 4) {\n  console.log('Operador logico OR');\n}\n\n//AND\nif (1 + 1 === 2 && 2 + 2 === 4) {\n  console.log('Operador logico AND');\n}\n\n//NOT\nconst adulto = false;\n\nif (!adulto) {\n  console.log('Eres menor de edad');\n}\n\n//Operadores de tipo\n//typeof\nconst tipoDeVariable = 1;\nconsole.log(typeof tipoDeVariable);\n\n//Operadores bit a bit\n//AND Bit a Bit\nconst a = 5;\nconst b = 3;\nconst resultadoAB = a&b;\nconsole.log(`Bit a bit: ${resultadoAB}`);\n\n//Estructuras de control\n//Condicional if\nconst edad = 18;\n\nif (edad >= 18) {\n  console.log('Eres mayor de edad');\n}else {\n  console.log('Eres menor de edad');\n}\n\n//Bucle for\nfor (let i = 0; i <= 5; i++) {\n  console.log(`Bucle for: ${i}`);\n}\n\n//Bucle while\nlet contador = 0;\nwhile (contador <= 5) {\n  console.log(`Bucle while: ${contador}`);\n  contador++;\n}\n\n//Bucle do while\nlet contador1 = 0\ndo {\n  console.log(`Bucle do while: ${contador1}`);\n  contador1++;\n} while (contador1 <= 5);\n\n//Dificultad Extra\nconsole.log('Ejercicio de con dificultad extra:');\nfor (let i = 10; i <= 55; i++) {\n  if (i === 55) {\n    console.log(i);\n  }\n\n  if (i%2 === 0 && i !== 16 && i%3 !== 0) {\n    console.log(i);\n  }\n}\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/christianumb.js",
    "content": "// OPERADORES\n\n//Operadores de asignación\n\ny = 1\nx = y //Asignación\nconsole.log (x)\n\n//Operadores Bit a Bit\n\nx = x << y //Asignación de desplazamiento a la izquierda: Desplaza x\n// en representación binaria y bits hacia la izquierda, desplazándose en ceros desde la derecha.\nconsole.log (x)\nx = x >> y //Asignación de desplazamiento a la derecha: Desplaza x\n// en representación binaria y bits hacia la derecha, descartando los bits desplazados.\nconsole.log (x)\nx = x >>> y //Asignación de desplazamiento a la derecha sin signo: Desplaza x\n// en representación binaria y bits hacia la derecha, descartando los bits desplazados y desplazándose en ceros desde la izquierda.\nconsole.log (x)\nx = x & y //Asignación AND bit a bit: Devuelve 1 cuando los bits de cada número es 1, sino es 0.\nconsole.log (x)\nx = x ^ y //Asignación XOR bit a bit: Devuelve 0 para bits iguales y 1 para bits diferentes de los números evaluados.\nconsole.log (x)\nx = x | y //Asignación OR bit a bit: Devuelve 1 si uno de los bits de los números es 1, sino es 0.\nconsole.log (x)\nx = ~x //Invierte los bits del operando.\nconsole.log (x)\n\n//Operadores aritmeticos\n\na = 1 + 2 //Adición \nconsole.log (a)\nb = 2 - 1 //Resta\nconsole.log (b)\nc = 2 * 1 //Multiplicación\nconsole.log (c)\nd = 2 / 1 //División\nconsole.log (d)\nf = 2 % 1 //Residuo\nconsole.log (f)\ng = 2 ** 2 //Exponenciación\nconsole.log (g)\ng++ //Incremento en uno\nconsole.log (g)\ng-- //Decremento en uno\nconsole.log (g)\ng = -g //Negación unaria: Coloca en negativo el número\nconsole.log (g)\ng = \"3\"\ng = +g //Positivo unario: convierte operador en un número\nconsole.log (g)\n\n//Operadores de comparación\nz = 3\ny = 4\np = z == y //True si los operadores son iguales\nconsole.log (p)\np = z != y //True si los operadores son diferentes\nconsole.log (p)\np = z === y //True si los operadores son iguales y del mismo tipo\nconsole.log (p)\np = z !== y //True si los operadores son del mismo tipo pero no iguales\nconsole.log (p)\np = z > y\nconsole.log (p)\np = z >= y\nconsole.log (p)\np = z < y\nconsole.log (p)\np = z <= y\nconsole.log (p)\n\n//Operadores Lógicos\nvar1 = true\nvar2 = false\nvar3 = var1 && var2 //AND lógico: Para booleanos, devuelve true \n//si ambos operandos son true; de lo contrario, devuelve false\nconsole.log (var3)\nvar3 = var1 || var2 // OR Lógico: devuelve true \n//si alguno de los operandos es true; de lo contrario, devuelve false\nconsole.log (var3)\nvar3 = !var3\nconsole.log (var3)\n\n//Operador de concatenación\n\nconsole.log (\"yo soy \" + \"Batman\")\n\n//Operador Condicional Ternario\n\nprecio = 3000\nvar valor = precio >= 30000 ? \"Costoso\" : \"Barato\" \n//Operador que asigna un valor a la variable inicial dependiendo del resutado de la comparación.\n//Si la condición es true, asigma el valor costoso, de lo contrario es barato.\nconsole.log (valor)\n\n//Operadores unarios\n\nx = 4\nvar prueba = {p: 2}\nvar5 = delete x //operador delete: elimina la propiedad de un objeto.\n//Si la puede elimiar devuelve true, sino false.\nvar6 = delete prueba.p\nconsole.log (var5)\nconsole.log (var6)\n\nvar7= typeof x //Indica el tipo de dato de la variable\nconsole.log (var7)\n\n//Operadores relacionales\n\nvar animales = [\"Leon\", \"Conejo\", \"Serpiente\", \"Aguila\"]\nvar refIn = 2 in animales //In: Indica si la propiedad especificada existe en el\n//objeto especificado. En este caso, valida si existe un objeto en la posición 2.\nconsole.log (refIn)\n\n//ESTRUCTURAS DE CONTROL\n\n//Bucles\n\n//While\nvar contador = 1\nwhile (contador > 0){ //Mientras se cumpla la condición se ejecuta el bucle\n    console.log (contador)\n    contador--\n}\n\n//do-while\nvar contador1 = 1\ndo { //Do lo que permite es que la función dentro del bucle se ejecute al menos\n    //una vez y luego se repita si cumple la condición.\n    console.log (contador1)\n    contador1--\n    } while (contador > 0);\n\n//For\nvar contador2 = 3\nfor (i = 0; i <= contador2; i++){//Se ejecuta el código mientras se cumpla la condición\n    console.log (i)\n}\n\n//Condicionales\n\n //If-else\n    var numero = -1\n    if (numero >= 0) { //Si se cumple la condición ejecute el siguiente código\n        console.log(\"Número positivo\")\n        }\n    else console.log (\"Número negativo\") //Sino, ejecuta este código\n\n//Switch\nvar animo = 3;\nswitch (animo) {//Dependiendo del valor indicado en la variable animo, se ejecuta\n    //el segmento de código asociado al valor y se sale del switch\ncase 1:\nconsole.log (\"Estoy feliz\");\nbreak;\ncase 2:\nconsole.log (\"Estoy triste\");\nbreak;\ncase 3:\nconsole.log (\"Estoy Ansioso\");\nbreak;\ndefault:\nconsole.log(\"No se como me siento\");\n}\n\n//Manejo de excepciones\n\n//Try...catch: Try permite ejecutar una sección de código para encontrar errores\n//catch permite manejar los errores encontrados\n\ntry {\n    console.log (\"Probemos el código\"); //Se ejecuta está sección\n    fallo; //Variable fallo no definida, genera error\n    console.log (\"El código fue exitoso\"); //Sección que no se ejecuta\n}//Para que try and catch funciones el código debe ser ejecutable, sin errores de sintaxis\ncatch (err){\n    console.log ('Se encontro el error:' + err); //Catch captura error y lo muestra\n}\n//Finally: permite ejecutar código posterior a try and catch, a pesar del resultado\nfinally {\n    console.log (\"Está sección siempre se ejecuta\")\n}\n\n//Crea un programa que imprima por consola todos los números comprendidos\n// * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n//var number = 55\nfor (var i = 10; i <= 55; i++) {\n    var j = i % 2\n    var h = i % 3\n    if (i === 16 || h === 0 || j != 0){\n        i++\n        }\n    else {\n        console.log (i)\n        i++\n         }\n    }\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/cmejiajulian.js",
    "content": "/*\n* #01 OPERADORES Y ESTRUCTURAS DE CONTROL\n*/\n\n/*\n *   Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n*/ \n\n//OPERADORES ARITMETICOS \n\nlet num1 = 8;\nlet num2 = 2;\n//Suma: +\nconsole.log(num1+num2);\n//Resta: -\nconsole.log(num1-num2);\n//Multiplicacion: *\nconsole.log(num1*num2);\n//Division: /\nconsole.log(num1/num2);\n//Modulo: %\nconsole.log(num1%num2);\n//Exponenciación: **\nconsole.log(num1**num2);\n//Incremento: ++\nconsole.log(num1++);\nconsole.log(num1);\n//Decremento: --\nconsole.log(num2--);\nconsole.log(num2);\n\n\n//OPERADORES DE ASIGNACION \n\nlet a = 9;\n\n// Asignación: =\nconsole.log (a);\n// Asignación de adición: +=\na+=2;\nconsole.log(a);\n// Asignación de sustracción: -=\na-=2;\nconsole.log (a);\n// Asignación de multiplicación: *=\na*=2;\nconsole.log (a);\n// Asignación de módulo: %=\na%=2;\nconsole.log(a);\n//Asignación de exponenciación: **=\na**=2;\nconsole.log(a);\n\n// OPERADORES DE COMPARACION \n\nlet x = 1\nlet y = 1 \n// Igualdad: ==\nconsole.log( x == y );\n// Desigualdad: !=\nconsole.log( x != y );\n// Desigualdad estricta: !==\nconsole.log( x !== y );\n// Mayor que: >\nconsole.log(5>3);\n// Mayor o igual que: >=\nconsole.log(5>=9);\n// Menor que: <\nconsole.log(7<3);\n// Menor o igual que: <=\nconsole.log(2<=2);\n\n// OPERADORES LOGICOS \n let ope1 = true;\n let ope2 = false;\n\n// AND lógico: &&\n\nconsole.log(ope1 && ope1);\nconsole.log(ope1 && ope2);\nconsole.log(ope2 && ope2);\nconsole.log(ope2 && ope1);\n  \n// OR lógico: ||\n\nconsole.log(ope2 || ope2);\nconsole.log(ope1 || ope2);\nconsole.log(ope1 || ope1);\nconsole.log(ope2 || ope1);\n\n// NOT lógico: !\n\nconsole.log(!ope1);\nconsole.log(!ope2);\n\n//OPERADORES DE CADENA \n\n//Concatenación: (+)\n\nlet name1 = 'Peter';\nlet lastName = ' Parker';\n\nconsole.log( name1 +\"\"+ lastName);\n\n// OPERADORES RELACIONALES\n\n// En: in (verifica si una propiedad está en un objeto)\n\nlet marvel = { superHero : 'Spiderman', power:'Escalar' };\n\nconsole.log( 'superHero' in marvel);\nconsole.log( 'Villano' in marvel);\n\n\n// OPERADORES DE BIT\nlet first = 11;\nlet second = 5;\n\n// AND bit a bit: &\nconsole.log( first & second);\n\n// OR bit a bit: |\nconsole.log( first|second);\n\n// XOR bit a bit: ^\nconsole.log( first ^ second);\n\n// NOT bit a bit: ~\nconsole.log( ~first);\n\n// Desplazamiento a la izquierda: <<\nconsole.log(first <<2);\n\n// Desplazamiento a la derecha: >>\nconsole.log(second >>2);\n\n// Desplazamiento a la derecha sin signo: >>>\nconsole.log(second >>>1);\n\n/*\n*   Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n*   que representen todos los tipos de estructuras de control que existan\n*   en tu lenguaje:\n*   Condicionales, iterativas, excepciones...\n*/\n\n\n//CONDICIONALES\n\n// if y else\n\n//*\nlet book = 'EL DIOS DE LA GUERRA';\n\nif (book == 'EL DIOS DE LA GUERRA') \n    \n    {console.log( 'Si, es el libro recomendado')}\n\nelse\n    {console.log('Es el libro para estar mejor')}\n\n//else if \n\n//*\nlet personaje = 'SuperMan'\n\nif (personaje === 'Tanos')\n    {console.log('Es el Dios de la destruccion')}\n\nelse if (personaje === 'SuperMan')\n    {console.log('Es el salvador')}\n\nelse\n    {console.log('Es una farsa')};\n\n//for \n\nfor (let i = 0; i<=10; i++) {\n    console.log(i);\n  }\n\nlet j = 0 \n\n//while\n\nwhile (j<=10){\n    console.log(j);\n    j++\n}\n\n//Control de excepciones\n\n//try, catch, finally\n\ntry {\n    console.log(50/0);\n  } catch (error)  {\n    console.log('Ocurrió un error:',error.mesage);\n  } finally {\n    console.log('Esta sección se ejecuta siempre');\n  };\n  \n\ntry {\n    let resultado = 50/0;\n    console.log(resultado);\n  } catch (error) {\n    console.log('Ocurrió un error:', error.message);\n  } finally {\n    console.log('Esta sección se ejecuta siempre');\n  }\n\n  \n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n */\n\n//Primero creamos una ciclo for que inicia en i = 10 y termina en i<=5 con un incremento de i++ \n\nfor (let i = 10; i<=55; i++ )\n\n/*luego usamos la condicion if para determinar los pares y sacar el numero 16 y los multiplos de 3 \n  como lo hacemos \n  1) Usamos el operador de asignacion del modulo, teniendo en cuenta que si el modulo es 0 es multiplo\n  de 2,  cabe resaltar que hacemos la igualdad == a 0 para que sea multiplo valga la redundancia \n\n  2) luego usamos el operador logico and (&&) para asignar otra condicion \n\n  3) usamos el operador de COMPARACION de Desigualdad estricta: !== para extraer el numero 16 de la lista\n\n  4) continuando con la secuencia de operadores logicos colocamos el modulo de 3 para que sea distinto de cero\n  y asi determinar los que no son multiplos de tres\n  */\n\n    if(i%2==0 && i!==16 && i%3!=0 )\n    {\n    console.log(i);\n}\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/cpcarlosprieto.js",
    "content": "//Carlos Arturo Prieto  @cpcarlosprieto\r\n\r\nconsole.log(\"Reto #01 OPERADORES Y ESTRUCTURAS DE CONTROL \" + \"\\n\");\r\n\r\n// Ejemplos de operadores\r\nconsole.log(\"EJEMPLOS DE OPERADORES:\" + \"\\n\");\r\n\r\n// Aritméticos\r\nlet suma = 5 + 10;\r\nlet resta = 20 - 8;\r\nlet multiplicacion = 4 * 6;\r\nlet division = 30 / 5;\r\nlet modulo = 15 % 7;\r\n\r\nconsole.log(\"Suma:\", suma);\r\nconsole.log(\"Resta:\", resta);\r\nconsole.log(\"Multiplicación:\", multiplicacion);\r\nconsole.log(\"División:\", division);\r\nconsole.log(\"Módulo:\", modulo);\r\n\r\n// Lógicos\r\nlet and = true && false;\r\nlet or = true || false;\r\nlet not = !true;\r\n\r\nconsole.log(\"AND:\", and);\r\nconsole.log(\"OR:\", or);\r\nconsole.log(\"NOT:\", not);\r\n\r\n// Comparación\r\nlet igual = 10 == \"10\";\r\nlet estrictamenteIgual = 10 === \"10\";\r\nlet diferente = 5 != \"5\";\r\nlet mayorQue = 15 > 10;\r\nlet menorQue = 8 < 12;\r\n\r\nconsole.log(\"Igual:\", igual);\r\nconsole.log(\"Estrictamente Igual:\", estrictamenteIgual);\r\nconsole.log(\"Diferente:\", diferente);\r\nconsole.log(\"Mayor Que:\", mayorQue);\r\nconsole.log(\"Menor Que:\", menorQue);\r\n\r\n// Asignación\r\nlet x = 5;\r\nx += 3;\r\nlet y = 10;\r\ny -= 2;\r\n\r\nconsole.log(\"x después de suma:\", x);\r\nconsole.log(\"y después de resta:\", y);\r\n\r\n// Identidad\r\nlet identidad = 5 === 5 ? \"igual\" : \"diferente\";\r\nconsole.log(\"Identidad:\", identidad);\r\n\r\n// Pertenencia\r\nlet arr = [1, 2, 3];\r\nlet pertenencia = 2 in arr ? \"perteneciente\" : \"no perteneciente\";\r\nconsole.log(\"Pertenencia:\", pertenencia);\r\n\r\n// Bits\r\nlet bitwiseAnd = 5 & 3;\r\nlet bitwiseOr = 5 | 3;\r\nlet bitwiseXor = 5 ^ 3;\r\nlet bitwiseNot = ~5;\r\n\r\nconsole.log(\"Bitwise AND:\", bitwiseAnd);\r\nconsole.log(\"Bitwise OR:\", bitwiseOr);\r\nconsole.log(\"Bitwise XOR:\", bitwiseXor);\r\nconsole.log(\"Bitwise NOT:\", bitwiseNot);\r\n\r\n// Estructuras de control\r\nconsole.log(\"\\nEJEMPLOS DE ESTRUCTURAS DE CONTROL:\");\r\n\r\n// Condicionales\r\nlet edad = 18;\r\nif (edad >= 18) {\r\n  console.log(\"Eres mayor de edad\");\r\n} else {\r\n  console.log(\"Eres menor de edad\");\r\n}\r\n\r\n// Iterativas\r\nconsole.log(\"Números del 10 al 55 (pares, no 16 ni múltiplos de 3):\");\r\nfor (let i = 10; i <= 55; i++) {\r\n  if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\r\n    console.log(i);\r\n  }\r\n}\r\n\r\n// Excepciones\r\ntry {\r\n  throw new Error(\"Este es un error de ejemplo\");\r\n} catch (error) {\r\n  console.error(\"Excepción:\", error.message);\r\n}\r\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/crisscde.js",
    "content": "// * MARK: OPERADORES\nlet myNumber = 5; // => Assignment Operator\nconsole.log(myNumber) // -> 5\n\n// ** MARK: Operadores de Asignacion Aritmética\nmyNumber += 15; // => myNumber + 15 -> 5 + 15\nconsole.log(myNumber) // => 20\nmyNumber -= 4; // => myNumber - 4 -> 20 - 4\nconsole.log(myNumber) // => 16\nmyNumber *= 8; // => myNumber * 8 -> 16 * 8\nconsole.log(myNumber) // => 128\nmyNumber /= 4; // => myNumber / 4 -> 128 / 4\nconsole.log(myNumber) // => 32\nmyNumber **= 4; // => myNumber ** 4 -> 32 ** 4 -> 32 * 32 * 32 * 32\nconsole.log(myNumber) // => 1048576\nmyNumber <<= 1; // => myNumber << 1 ->  1048576 << 1 -> 100000000000000000000 << 1\nconsole.log(myNumber) // => 2097152\nconsole.log(myNumber.toString(2)) // => 1000000000000000000000\nmyNumber >>= 6; // => myNumber >> 6 -> 2097152 >> 6 -> 1000000000000000000000 >> 6\nconsole.log(myNumber) // => 32768\nconsole.log(myNumber.toString(2)) // => 1000000000000000\nmyNumber >>>= 3; // => myNumber >>> 3 -> 32768 >>> 3 -> 0001000000000000 >>> 3 \nconsole.log(myNumber) // => 4096\nconsole.log(myNumber.toString(2)); // -> 1000000000000\n\n// ** MARK: Operadores de Asignación Bit a Bit\nlet myNumber2 = 9321; /// => 10010001101001\n\nmyNumber2 &= 7982; // => myNumber2 & 7982 -> 9321 & 7982 -> 10010001101001 & 01111100101110 \nconsole.log(myNumber2); // => 1064\nconsole.log(myNumber2.toString(2)); // => 10000101000\n\nmyNumber2 ^= 1840; // => myNumber2 ^ 1840 -> 1064 ^ 1840 -> 10000101000 ^ 11100110000\nconsole.log(myNumber2); // => 792\nconsole.log(myNumber2.toString(2)); // => 1100011000\n\nmyNumber2 |= 974; // => myNumber2 | 974 -> 792 | 974 -> 1100011000 | 1111001110\nconsole.log(myNumber2); // => 990\nconsole.log(myNumber2.toString(2)); // => 1111011110\n\n/* \n  Antes de ver los operadores lógicos, me gustaria mencionar que los valores se manejan a base de\n  booleanos, entonces todo valor es pasado a booleano, por ejemplo \"false\" es pasado a true, mientras que \"\"\n  es pasado a false.\n  A esto hay otra forma de llamarle, true se les trata también como Truthy y false como Falsy\n    Valores Falsy\n    Existen 9 valores Falsy:\n      - null\n      - undefined\n      - false\n      - NaN\n      - 0\n      - -0\n      - 0n\n      - \"\"\n      - document.all\n      ! Antes de continuar, debes de saber que null y undefined también se les llega a conocer como Nullish\n    Todos los demas valores serán tratados como Truthy  \n*/\n\n// ** MARK: Operadores de Asignación Lógicos\nlet canGoToNightClub = true;\nlet isOlder = false;\ncanGoToNightClub &&= isOlder; // => canGoToNightClub && isOlder -> true && false\nconsole.log(canGoToNightClub); // => false\n\nlet notValue = \"\";\nnotValue ||= \"defaultValue\"; // => \"\" || \"defaultValue\" => \"\" is Falsy, \"defaultValue\" is assigned\nconsole.log(notValue); /// => \"defaultValue\"\n\nlet user = null;\nuser ??= {userID: 1, username: \"GuestUser\"} // => (user === null || user === undefined) ? {userID: 1, username: \"GuestUser\"} : user;\nconsole.log(user); // => {userID: 1, username: \"GuestUser\"}\n\n/* \n  ** MARK: Operadores de Comparación\n  En JS comparar strings con números se puede hacer.\n  Para evitar esto trata de usar los operadores de comparación estrictos (===, !==)\n*/\nconsole.log(`'20' == 20: ${ '20' == 20 }`); // => true - Permite coerción de tipos (LOOSE EQUALITY)\nconsole.log(`'20' === 20: ${ '20' === 20 }`); // => false - No permite coerción de tipos (STRICT EQUALITY)\n\nconsole.log(`'20' != 20: ${ '20' != 20 }`); // => false - Permite coerción de tipos (LOOSE EQUALITY)\nconsole.log(`'20' !== 20: ${ '20' !== 20 }`); // => true - No permite coerción de tipos (STRICT EQUALITY)\n\nconsole.log(`21 > 30: ${ 21 > 30 }`); // => false\nconsole.log(`32 >= 30: ${ 32 >= 30 }`); // => true\nconsole.log(`40 < 30: ${ 40 < 30 }`); // => false\nconsole.log(`21 <= 21: ${ 21 <= 21 }`); // => true\n\n// ** MARK: Operadores Aritméticos\nconsole.log(`20 + 30: ${20 + 30}`); // => 20 + 30: 50\nconsole.log(`20 - 7: ${20 - 7}`); // => 20 - 7: 13\nconsole.log(`20 * 6: ${20 * 6}`); // => 20 * 6: 120\nconsole.log(`20 / 8: ${20 / 8}`); // => 20 / 8: 2.5\nconsole.log(`20 % 7: ${20 % 7}`); // => 20 % 7: 6\nconsole.log(`20 ** 8: ${20 ** 8}`); // => 20 ** 8: 25600000000\n\n// ** MARK: Operadores unarios\nlet myNumber3 = 12;\nconsole.log(`++12: ${++myNumber3}`, `myNumber3: ${myNumber3}`); // => ++12: 13, myNumber3: 13\nconsole.log(`13++: ${myNumber3++}`, `myNumber3: ${myNumber3}`); // => 13++: 13, myNumber3: 14\nconsole.log(`--13: ${--myNumber3}`, `myNumber3: ${myNumber3}`); // => --14: 13, myNumber3: 13\nconsole.log(`12--: ${myNumber3--}`, `myNumber3: ${myNumber3}`); // => 13--: 13, myNumber3: 12\nconsole.log(`+false: ${+false}`); // +false: 0\nconsole.log(`-('3'): ${-('3')}`); // -('3'): -3\n\n/* \n  ** MARK: Operadores Bit a Bit\n  Todo los operadores bit a bit (Bitwise Operators), tratan a los números a 32 bits\n*/\nconsole.log(`98 & 42: ${98 & 42}`) // => 1100010 & 0101010 -> 0100010 -> 34\nconsole.log(`98 | 42: ${98 | 42}`) // => 1100010 | 0101010 -> 1101010 -> 106\nconsole.log(`98 ^ 42: ${98 ^ 42}`) // => 1100010 ^ 0101010 -> 1001000 -> 72\nconsole.log(`~98: ${~98}`) // => 1100010 -> 0011101 -> -99\nconsole.log(`98 << 2`) // =>  392\nconsole.log(`42 >> 2`) // => 10 \nconsole.log(`42 >>> 2`) // => 10\n\n// ** MARK: Operadores lógicos\nconsole.log(`true && false: ${true && false}` ) // => false\nconsole.log(`\"\" || [] || 0: ${\"\" || 0 || []}`) // => []\nconsole.log(`null ?? []: ${null ?? []}`) // => []\nconsole.log(`!false: ${!false}`) // => true\n\n// ** MARK: Ternario (Operador Condicional)\nlet age = 22;\nconsole.log(age >= 18 ? \"Yes, he has an ID\" : \"No, he doesn't have an ID\"); // => \"Yes, he has an ID\"\nage = 12;\nconsole.log(age >= 18 ? \"Yes, he has an ID\" : \"No, he doesn't have an ID\"); // => \"No, he doesn't have an ID\"\n\n\n// * MARK: If...else\nlet number = 3;\nif(number % 2 === 0) {\n  console.log(\"Your number is even\");\n} else {\n  console.log(\"Your number is odd\");\n}\n\n// * MARK: If...If else...else\nlet value;\nif((value === null) || (value === undefined)) {\n  console.log(\"Nullish Value\");\n} else if( !value) {\n    console.log(\"Falsy Value\");\n} else {\n    console.log(\"Truthy Value\");\n}\n\n// * MARK: Switch\nlet color = \"Red\";\nswitch(color) {\n  case \"Crimson\":\n    console.log(\"rgb(205, 92, 92)\");\n    break;\n  case \"HotPink\":\n    console.log(\"rgb(255, 105, 180)\");\n    break;\n  case \"Coral\": \n    console.log(\"rgb(255, 127, 80)\");\n    break;\n  case \"LemonChiffon\": \n    console.log(\"rgb(255, 250, 205)\");\n    break;\n  case \"RebeccaPurple\": \n    console.log(\"rgb(102, 51, 153)\");\n    break;\n  case \"Olive\": \n    console.log(\"rgb(128, 128, 0)\");\n    break;\n  case \"MediumSlateBlue\": \n    console.log(\"rgb(123, 104, 238)\");\n    break;\n  default: \n    console.log(\"rgb(0, 0, 0)\");\n}\n\n/* \n  * MARK: Try...Catch (Excepciones)\n  Algunas ocasiones observarás que un código ejecutado lanzara un error, esto si lo ejecuta el usuario\n  ocasionara un grave error, para detener esto, deberás de ver ese error a tiempo y hacer algo para \n  notificar al usuario del error.\n  Para hacer esto se lanza un try{} catch(error){}\n*/\n\n// * MARK: Try...Catch (Excepciones)\nfunction divide(a, b) {\n  if (b === 0) {\n    // Throw an error\n    throw new Error(\"You can't divide by zero!\");\n  }\n  return a / b;\n}\n\ntry {\n  let result = divide(10, 0);\n  console.log(\"Result: \", result);\n} catch (error) {\n  console.log(\"An error occurred: \", error.message);\n} finally {\n  console.log(\"Execution finished.\");\n}\n\n\n// * MARK: For Loop\nfor ( let i = 1; i <= 10; i++ ) {\n  console.log(i);\n}\n\n// * MARK: While Loop\nlet numberWhile = 1;\nwhile ( numberWhile <= 10 ) {\n  console.log(numberWhile);\n  numberWhile++;\n}\n\n// * MARK:Do-While Loop\nlet numberDoWhile = 10;\ndo {\n  console.log(numberDoWhile)\n  numberDoWhile++;\n} while(numberDoWhile <= 10);\nconsole.log(numberDoWhile);\n\n\n// * EXTRA\nfor(let i = 10; i <= 55; i++) {\n  if((i % 2 === 0) && !(i % 3 === 0) && i != 16) {\n    console.log(i);\n  }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/cristophher087.js",
    "content": "//Operadores aritmeticos\n\n//Suma (+)\n\nlet a = 1;\nlet b = 2;\n\nconsole.log(\"Los operadores logicos son los siguientes:\");\nconsole.log(`a + b = ${a + b}     suma`);\nconsole.log(`a - b = ${a - b}     resta`);\nconsole.log(`a * b = ${a * b}     multiplicación`);\nconsole.log(`a / b = ${a / b}     divición`);\nconsole.log(`a % b = ${a % b}     `);\nconsole.log(`a ** b = ${a ** b}   potencia`);\nconsole.log(`a++ = ${a++}       incremento`);\nconsole.log(`b-- = ${b--}       decremento`);\n\n//operadores de asignación\n\nlet x = 5; // Asignación simple\nx += 3;    // Equivale a x = x + 3\nconsole.log(x); //  8\n\nx -= 2;    // Equivale a x = x - 2\nconsole.log(x); //  6\n\nx *= 4;    // Equivale a x = x * 4\nconsole.log(x); //  24\n\nx /= 6;    // Equivale a x = x / 6\nconsole.log(x); //  4\n\nx %= 3;    // Equivale a x = x % 3\nconsole.log(x); //  1\n\nx **= 3;   // Equivale a x = x ** 3\nconsole.log(x); //  1\n\n//Operadores de asignación [true, false]\n\nlet m = 10;     //entero\nlet n = '10';   //cadena de caracteres\n\nconsole.log(m == n);  //(compara solo el valor)\nconsole.log(m === n); //(compara valor y tipo)\nconsole.log(m != n);  //false\nconsole.log(m !== n); //true\n\nconsole.log(m > 5);\nconsole.log(m >= 10);\nconsole.log(m < 15);\nconsole.log(m <= 9);\n\n//Operadores logicos\n\nlet p = true;\nlet q = false;\n\n// Operador AND\nconsole.log(p && q);\n\n// Operador OR\nconsole.log(p || q);\n\n// Operador NOT\nconsole.log(!p);\nconsole.log(!q);\n\n//Operadores de cadena\n\nlet saludo = \"Hola\";\nlet quienSaluda = \"Cristopher\";\n\nlet mensajeUno = saludo + \", \" + quienSaluda + \"!\";\nconsole.log(mensajeUno);\n\n// Con plantillas literales\nlet mensajeTemplate = `${saludo}, ${nombre}!`;\nconsole.log(mensajeTemplate);\n\nlet r = 5;  // En binario: 0101\nlet s = 3;  // En binario: 0011\n\nconsole.log(r & s); //      1   (0001)\nconsole.log(r | s); //      7   (0111)\nconsole.log(r ^ s); //      6   (0110)\nconsole.log(~r);    //      -6  (inverso de 0101 es 1010 en complemento a dos)\nconsole.log(r << 1); //     10  (0101 << 1 = 1010)\nconsole.log(r >> 1); //     2   (0101 >> 1 = 0010)\nconsole.log(r >>> 1); //    2   (0101 >>> 1 = 0010)\n\n/*\nOperador ternario\nEs una forma abreviada de una declaración if-else. Evalúa una condición y retorna un valor según sea verdadera o falsa.\n(condición ? valor_si_verdadero : valor_si_falso)\n*/\nlet edad = 18;\n\nlet mensaje = (edad >= 18) ? \"Eres mayor de edad.\" : \"Eres menor de edad.\";\nconsole.log(mensaje); // Eres mayor de edad.\n\n// Uso con asignación\nlet acceso = (edad >= 18) ? true : false;\nconsole.log(acceso); //  true\n\n/*\nDeterminan el tipo de una variable o valor.\n-typeof: Retorna una cadena indicando el tipo de una variable.\n-instanceof: Verifica si un objeto es una instancia de una determinada clase o constructor.\n-new: Crea una instancia de un objeto.\n-delete: Elimina una propiedad de un objeto.\n*/\nlet texto = \"Hola\";\nlet numero = 42;\nlet objeto = { nombre: \"Juan\" };\nlet arreglo = [1, 2, 3];\nlet funcion = function () { };\n\nconsole.log(typeof texto);    //  string\nconsole.log(typeof numero);   //  number\nconsole.log(typeof objeto);   //  object\nconsole.log(typeof arreglo);  //  object\nconsole.log(typeof funcion);  //  function\n\n// Uso de instanceof\nconsole.log(arreglo instanceof Array); //       true\nconsole.log(objeto instanceof Object); //       true\nconsole.log(funcion instanceof Function); //    true\n\n// Uso de delete\ndelete objeto.nombre;\nconsole.log(objeto); //  {}\n\n/* \nOperador Spread (...)\nExpande elementos de un arreglo u objeto en lugares donde se esperan múltiples elementos.\n*/\n// En arreglos\nlet frutas = [\"manzana\", \"banana\"];\nlet masFrutas = [...frutas, \"naranja\"];\nconsole.log(masFrutas); // Output: [\"manzana\", \"banana\", \"naranja\"]\n\n// En objetos\nlet persona = { nombre: \"Ana\", edad: 25 };\nlet nuevaPersona = { ...persona, ciudad: \"Madrid\" };\nconsole.log(nuevaPersona); // Output: { nombre: \"Ana\", edad: 25, ciudad: \"Madrid\" }\n/*\nOperador Rest (...)\nRecopila múltiples elementos y los agrupa en un solo arreglo o objeto.\n*/\n// En funciones\nfunction sumar(a, b, ...resto) {\n    return a + b + resto.reduce((acc, val) => acc + val, 0);\n}\n\nconsole.log(sumar(1, 2, 3, 4, 5)); // Output: 15\n\n// En destructuración de objetos\nlet { nombre, ...otrosDatos } = persona;\nconsole.log(nombre);      // Output: \"Ana\"\nconsole.log(otrosDatos);  // Output: { edad: 25 }\n\n/*\nOtros operadores\nOperador in\nVerifica si una propiedad existe en un objeto.\n*/\nlet coche = { marca: \"Toyota\", modelo: \"Corolla\" };\nconsole.log(\"marca\" in coche); // Output: true\nconsole.log(\"color\" in coche); // Output: false\n\n/*\nOperador ? (Nullish Coalescing Operator ??)\nRetorna el valor del operando derecho si el operando izquierdo es null o undefined.\n*/\nlet valor = null;\nlet resultado = valor ?? \"Valor por defecto\";\nconsole.log(resultado); // Output: \"Valor por defecto\"\n\nvalor = 0;\nresultado = valor ?? \"Valor por defecto\";\nconsole.log(resultado); // Output: 0\n\n/*\nOperador ?. (Optional Chaining Operator)\nPermite acceder a propiedades de objetos que podrían ser null o undefined sin causar errores.\n*/\nlet usuario = {\n    nombre: \"Luis\",\n    direccion: {\n        ciudad: \"Barcelona\"\n    }\n};\n\nconsole.log(usuario.direccion?.ciudad); // Output: \"Barcelona\"\nconsole.log(usuario.contacto?.telefono); // Output: undefined\n\n/*\nEjercicio extra\n*/\n\nlet cuenta = 10;\n\nfor (let cuenta = 10; cuenta <= 55; cuenta++) {\n    if (cuenta % 3 === 0 || cuenta != 16) {\n        console.log(`La cuenta es: ${cuenta}`);\n    }\n    else {\n        console.log(\"---\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/d4-n1.js",
    "content": "// Operadores aritméticos básicos\nlet add = 9 + 7\nlet sub = 2 - 1\nconst mult = 2 * 2\nconst div = 5 / 2\nconst rem = 6 % 2\nconst exp = 2 ** 3\n\n// Aritmética para strings\nconst name = \"d4\" + \"-\" + \"n1\"\n\n// Atajos aritméticos\nconst addShort = add++\nconst subShort = sub--\n\n// Operadores de comparación\nconst equal = add == 9\nconst notEqual = sub != 4\nconst strictEqual = mult === \"multiplicación\"\nconst strictNotEqual = div !== \"2.5\"\nconst greater = 3 > 2\nconst greaterEqual = 3 >= 3\nconst less = 2 < 3\nconst lessEqual = 2 <= 3\n\n// Operadores lógicos\nconst and = true && true\nconst or = true || false\nconst not = !true\n\n// Operadores condicionales\nconst age = 21\nconst readyToDrive = age >= 18 ? \"Listo para conducir 🚗\" : \"Debes esperar un poco ⏳\"\n\n// Estructuras de control\nif (age >= 18) {console.log(\"Listo para conducir 🚗\")}\nelse if(age == 17){console.log(\"Ya mismo puedes conducir 😎\")}\nelse {console.log(\"Debes esperar un poco ⏳\")}\n\nconst fruit = \"naranja\"\nswitch (fruit) {\n  case \"naranja\": \n    console.log(\"Me encanta la naranja 🍊\")\n    break\n  case \"mango\":\n    console.log(\"No me gusta el mango 🥭\")\n    break\n  case \"limón\":\n    console.log(\"También me gusta el limón 🍋\")\n    break\n}\n\nlet number = 0\nwhile (number <= 3) {\n  console.log(number)\n  number++\n}\n\ndo {\n  console.log(\"do se ejectuta al menos una vez\")\n} while (number <= 3)\n\nfor (let x = 0; x <= 3; x++) {\n  console.log(x)\n}\n\nconsole.log(`\nOperadores aritméticos básicos\n${add}, ${sub}, ${mult}, ${div}, ${rem}, ${exp}\n\nAritmética para strings\n${name}\n\nAtajos aritméticos\n${addShort}, ${subShort}\n\nOperadores de comparación\n${equal}, ${notEqual}, ${strictEqual}, ${strictNotEqual}, ${greater}, ${greaterEqual}, ${less}, ${lessEqual}\n\nOperadores lógicos\n${and}, ${or}, ${not}\n\nOperadores condicionales\n${age}, ${readyToDrive}\n`)\n\n/* \nDificultad extra\nCrea un programa que imprima por consola todos los números comprendidos entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n*/\nfor (let x = 10; x <= 55; x++) {\n  if (x % 2 != 0){   \n  } else if (x == 16){\n  } else if (x % 3 == 0) {\n  } else {console.log(x)}\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/daniback95.js",
    "content": "/* \nOperadores\n*/\n\n/* \nBinarios: El operador es aplicado a dos operandos\n*/\n// Aritméticos\nconsole.log(`Suma 3 + 2 = ${3 + 2}`);\nconsole.log(`Resta 3 - 2 = ${3 - 2}`);\nconsole.log(`Multiplicación 3 * 2 = ${3 * 2}`);\nconsole.log(`División 3 / 2 = ${3 / 2}`);\nconsole.log(`Módulo o resto 3 % 2 = ${3 % 2}`);\nconsole.log(`Exponenciación 3 ** 2 = ${3 ** 2}`);\n\n/* \nOperador de concatenación +\nCuando se aplica el oprador + a dos operandos de \ntipo string los une.\n*/\nlet text = 'My' + 'string';\nconsole.log(text);\n/* \nSi uno de los operandos es una cadena, el otro operando\ntambién es convertido en una cadena\n*/\nconsole.log(1 + '2'); // '12'\nconsole.log('2' + 1); // '21'\nconsole.log(1 + 2 + '3'); // primero: 1 + 2 = 3 luego: 3 + '3' = '33'\nconsole.log('1' + 2 + 3); // primero '1' + 2 = '12' luego '12' + 3 = '123'\n/* \nPara tener en cuenta:\nEl operador binario + es el unico que soporta cadenas \ncomo las anteriormente vistas, otros operadores como la resta\nla multiplicación, división... trabajan sólo con números\ny convierte sus operandos a números\n*/\nconsole.log(3 - '1'); // 2\nconsole.log('3' * 2); // 6\nconsole.log(3 ** '2'); // 9\nconsole.log('9' / '3'); //3\n\n/* \nUnarios: El operador es aplcado a un solo operando\n*/\n/* \nUnario +: este operador no hace nada cuando se aplica a números, pero \ncuando se palica a operandos que son número, los convierte en números\n*/\nlet a = '9';\nconsole.log(+a); // 9\nlet b = '';\nconsole.log(+b); // 0\nlet c = true;\nconsole.log(+c); // 1\nlet d = false;\nconsole.log(+d); // 0\nlet f = true;\nconsole.log(-f); // -1\n/* \nLo que se hizo anteriormente con el operador \nunario + hace lo mismo que la función Number()\n*/\nlet apples = '2';\nlet oranges = '5';\nconsole.log(apples + oranges); // '25'\nconsole.log(+apples + +oranges); // 7\nconsole.log(+apples + -oranges); // -3\n\n/* \nOperadores de incremento/decremento\nEs una manera de incrementar o decrementar valores de manera acortada\n*/\nlet counter = 0;\n// incremento usando la forma tradicional\ncounter = counter + 1; \nconsole.log(counter); // 1\n// incremento de manera acortada\ncounter++;\nconsole.log(counter); // 2\ncounter--;\nconsole.log(counter); // 1\n/* \nExiste dos formas de usar el incremento/decremento\nComo prefijo: devuelve inmendiatamente el nuevo valor\nComo sufijo: develve el valor anterior antes de realizar el\nincremento/decremento.\nImportante: Ambas formas hacen los mismo, incrementar/decrementar,\npara poder ver su sutil diferencia debemos usar inmediatamente su\nvalor\n*/\n// Prefijo\nlet counter2 = 1;\n++counter; // 2\nconsole.log(counter);\n// Sufijo\ncounter++;\nconsole.log(counter); // 3\n/* \nLo anterior hace lo mismo, ahora veamos su sutil\ndiferencia\n*/\nlet counter3 = 1;\nconsole.log(++counter3); // nuevo valor: 2\nlet counter4 = 0;\nconsole.log(counter4++); // devueve su valor anterior: 0 \nconsole.log(counter4); // tenemos el nuevo valor: 1\n\n/* \nOperadores de asignación:\nson operadores cortos que modifican y asignan al mismo tiempo, \nson aplicables a todos los operadores aritméticos\n*/\nlet x = 1;\nx += 2;\nconsole.log(x); // 3\nx *= 3;\nconsole.log(x); // 9\nx -= 2;\nconsole.log(x); // 7\nx **= 2;\nconsole.log(x); // 49\nx /= 7;\nconsole.log(x); // 7\n\n/* \nOperadores de comparación\nEl resultado de este tipo de operaciones es un valor booleno \n*/\nconsole.log(`Mayor que: 5 > 3 es ${5 > 3}`); // true\nconsole.log(`Menor que: 5 < 3 es ${5 < 3}`); // false\nconsole.log(`Mayor o igal que: 5 >= 5 es ${5 >= 3}`); // true\nconsole.log(`Menor o igaual que: 5 <= 3 es ${5 <= 3}`); // false\nconsole.log(`Igual que: 3 == 3 es ${3 == 3}`); // true\nconsole.log(`Diferente que: 5 != 3 ${5 != 3}`); //true\n/* \nIgualdad regular:\nEste operador corresponde al de doble igual ==\nEste operador realiza primero una coerción de tipo si los valores\nson diferentes, convertirlos a un tipo común antes de realizar\nla comparción.\nEsto también aplica para la diferencia regular !=\n*/\nconsole.log(1 == false); // convierte false a 0 \nconsole.log(1 == true); // convierte true a 1\nconsole.log('' == false); // true, cadena vacía la pasa a 0 y false a 0\nconsole.log(null == undefined) // true, se consideran iguales\nconsole.log(1 != true); // false\n/* \nIgualda estricta:\nCompara los operandos tanto en valor como en tipo, \nno realiza ninguna coerción de tipo\nEsto también aplica para la diferencia estricta !==\n*/\nconsole.log(null === undefined); // false\nconsole.log(1 === '1'); // false\nconsole.log(1 === true) // false\nconsole.log(1 !== true) // true\n\n// Operadores lógicos\n// OR\nconsole.log(`OR ||: 3 > 5 || 3 + 2 == 5 es ${3 > 5 || 3 + 2 == 5}`);\nconsole.log(`1 || 0 es ${ 1 || 0 }`);\nconsole.log(`null || 1 es ${ null || 1 }`);\nconsole.log(`null || 0 || 3 es ${ null || 0 || 3 }`);\nconsole.log(`undefined || 0 || null es ${ undefined || 0 || null}`);\nlet firstName = '';\nlet lastName = '';\nlet nickName = 'SuperCoder';\nconsole.log(firstName || lastName || nickName || 'Anonymous');\nnickName || console.log('Esto no se ejecuta');\nfirstName || console.log(`Ejecutando nickname: ${ nickName }`);\n\n//AND\nconsole.log(`AND &&: 3 < 5 && 3 + 2 == 5 es ${ 3 < 5 && 3 + 2 == 5 }`);\nconsole.log(`1 && 0 es ${ 1 && 0 }`);\nconsole.log(`true && true es ${ true && true }`);\nconsole.log(`null && 1 && '' es ${ null && 1 && '' }`);\nconsole.log(`1 && undefined && null es ${ 1 && undefined && null }`);\nconsole.log(`1 && 0 && null es ${ 1 && 0 && null }`);\nconsole.log(`1 && '0' && null es ${ 1 && '0' && null }`);\nconsole.log(`1 && '' && null es ${ 1 && '' && null }`);\nconsole.log(`1 && 2 && null es ${ 1 && 2 && null }`);\nconsole.log(`0 && 1 && 3 es ${ 0 && 1 && 3 }`);\nconsole.log(`1 && 2 && 3 es ${ 1 && 2 && 3 }`);\n1 > 0 && console.log('1 es mayor que cero');\n\n// !NOT\nconsole.log(`NOT !: !true es ${ !true }`);\nconsole.log(`!false es ${ !false }`);\nconsole.log(`!null es ${ !null }`);\nconsole.log(`!!null es ${ !!null }`);\n\n// Operadores Bit\nconsole.log(\"AND: \", 9 & 7);\nconsole.log(\"OR: \", 9 | 7);\nconsole.log(\"XOR: \", 9 ^ 7);\nconsole.log(\"NOT: \", ~9);\nconsole.log(\"Left shift: \", 9 << 7);\nconsole.log(\"Right shift: \", 9 >> 7);\nconsole.log(\"Zero-fill right shift: \", 9 >>> 3);\n\n/* \nOperador nullish coalescing\n*/\nlet nombre;\nlet apellido;\nlet nombrePorDefecto = 'Anónimo';\nlet user = nombre ?? apellido ?? nombrePorDefecto;\nconsole.log(`Saludando a user: ${user}`);\nconsole.log(nombre ?? apellido ?? nickName);\nlet heigth = 0\nconsole.log('heitg es: ', heigth || 100); // 100\nconsole.log('heitg es: ', heigth ?? 100); // 0 \n/* \nCondicionales\n*/\n\n// if / else\nlet ageUser = 23;\nlet minimunAge = 18;\nif(ageUser >= 18) {\n  console.log('Es mayor de edad, puede ingresar');\n} else {\n  console.log('Es menor de edad, no puede ingresar');\n}\n\nlet num = -2;\nif(num > 0) {\n  console.log(1);\n} else if(num < 0) {\n  console.log(-1);\n} else {\n  console.log(0);\n}\n\n// Ternario\nlet age = 25;\nlet message = (age < 18) ? 'Hola niño' : \n  (age < 25) ? '!Hola¡' :\n  (age < 50) ? '!Qué tal¡' : 'Saludos';\n\nconsole.log(message);\n\n/* \nCondicionales\n*/\n// while\nlet i = 0;\nwhile(i < 3) {\n  console.log(i);\n  i++;\n}\nwhile(i != 0) {\n  console.log(i);\n  i--;\n}\n// do while\ndo {\n  console.log(i);\n  i++\n} while(i < 3)\n\n// for\nfor (let j = 0; j<=5; j++) {\n  console.log('el valor de j es', j)\n}\nlet k = 0;\nfor (k; k <= 10; k++) {\n  let result = 3 * k;\n  console.log(`3 * ${k} = ${result}`);\n}\n\nfor (num = 10; num <= 55; num++) {\n  if(num % 2 == 0 && num != 16 && num % 3 != 0) {\n    console.log(num);\n  }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/dariorfm.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n\n// OPERADORES ARITMETICOS\nlet a, b, c;\n\na = 5;\nb = 3;\nc = 2;\n\nlet suma = a + b;\n\nlet resta = b - c;\n\nlet multiplicacion = a * b *c;\n\nlet division = b / c;\n\nlet modulo = b % c;\n\n\nconsole.log( `\\nSuma de a + b = ${suma}\\nResta de b - c = ${resta}\\nMulplicación de a * b * c = ${multiplicacion}\\n...etc.\\n`, )\n\n\n// OPERADORES DE INCREMENTO Y DECREMENTO\nconsole.log(a,`\\n`);\n\n++a;\nconsole.log(a,` incrementa de 1\\n`);\n\n--a;\nconsole.log(a,` decrementa de 1\\n`);\n\n// * Recuerda que que el navegador devuelve el valor actual y luego incrementa la variable. \n// * Puedes ver que se ha incrementado si devuelves el valor variable nuevamente\na++;\nconsole.log(a,` incrementa de 1\\n`);\n\na--;\nconsole.log(a,` decrementa de 1\\n`);\n\n\n// OPERADORES DE ASIGNACION\n\na = 1; // Asigna o reasigna un valor\n\n// --> toma el valor de la variable y ejecuta la operación y asigna el resultado a la misma variable.\nconsole.log(a += 3); // Adición asignación\nconsole.log(a -= 2); // Resta asignación   \nconsole.log(a *= 4); // Mulitplicación asignación\nconsole.log(a /= 2); // División asignación\nconsole.log(a %= 3); // Modulo asiganción\n\n\n\n// OPERADORES DE COMPARACION\n\n// --> Los resultados de estos pueden ser true o false.\n\nconsole.log(a == b);    // Compruebas valores pero no el tipo de dato\nconsole.log( a === b);  // Comprueba si los valores izquierdo y derecho son idénticos entre sí\nconsole.log( a !== b);  // Comprueba si los valores izquierdo y derecho NO son idénticos entre sí\nconsole.log( a < b);    // Comprueba si el valor izquierdo es menor que el derecho\nconsole.log( a > b);    // Comprueba si el valor izquierdo es mayor que el derecho\nconsole.log( a <= b);   // Comprueba si el valor izquierdo es mayor que el derecho\nconsole.log( a >= b);   // Comprueba si el valor izquierdo es mayor o igual que el derecho\n\n\n// OPERDADORES LOGICOS\n\n// Operador lógico AND &&\nconsole.log(true && true);   // → true\nconsole.log(true && false);  // → false\nconsole.log(false && false); // → false\n\n//Operador lógico OR ||\nconsole.log(true || true);   // → true\nconsole.log(true || false);  // → true\nconsole.log(false || false); // → false\n\n//Operador lógico NOT !\nconsole.log(!true);  // → false\nconsole.log(!false); // → true\n\n\n// ESTRUCTURAS DE CONTROL DE FLUJO\n\n/*\n‌Las estructuras de control de flujo, son intrucciones que nos permiten evaluar si se puede \ncumplir una condición o no, incluso nos puede ayudar a evaluarla n cantidad de veces.\n*/\n\n\n\n// Condicional if\n\n/*\n    ===> if (condición) {\n\n        Si condicón verdadera\n        ejecuta este código.\n\n    }\n*/\nlet edad = 19;\n\nif (edad < 18) {\n    console.log(\"Es menor de edad\")\n};\n\n\n// Condicional if...else\n\n/*\n    ===> if (condición) {\n\n        Si condicón verdadera\n        ejecuta este código.\n\n    } else {\n\n        Si condicón falsa\n        ejecuta este código.\n    }\n*/\nif (edad >= 18) {\n    console.log(\"Tiene 18 o más\")\n} else {\n    console.log(\"Es menor de edad\")\n};\n\n\n// Condicional else if\n\n/*\n    ===> if (condición) {\n\n        Si condicón verdadera ejecuta este código\n        caso contrario evalua siguiente condición.\n\n    } else if (condición2) {\n\n        Si condicón verdadera\n        ejecuta este código.\n\n    } else {\n        Si no cumple con niguna condición\n        anterior ejecuta este código.\n    }\n*/\n\nif (edad >= 25) {\n    console.log(\"Tiene mas de 25\")\n} else if ( edad > 18 && edad < 25) {\n    console.log(\"Entre 18 y 25, no incluidos\")\n} else {\n    console.log(\"Tiene menos de 18\")\n};\n\n\n// LOOPS, CICLOS O BUCLES\n\n// Sirven para evaluar una condición repetidamente hasta que se cumpla.\n\n/*  ===> for (expresiónInicial; expresiónCondicional; expresiónDeActualización) {\n             instrucción o código a ejecutar\n            }\n*/\n\nfor (let numero = 1; numero <= 10; numero++) {\n    console.log(numero)\n};\n\n\nfor (let x = 1, y = 5; x < 5; x++, y--) {\n    console.log(x, y)\n};\n\n// for...of recorre los valores de un objeto iterable.\n\n/*  ===> for (variable of iterable) {\n            Codigo a ser ejecutado\n        }\n*/\n\nconst autos = [\"BMW\", \"Volvo\", \"Mercedez\", \"Toyota\", \"Nissan\"];\n\nfor (let auto of autos) {\n    console.log(auto)\n};\n\n// for...in recorre las propiedades de un objeto.\n\n/*\n\n    for (propiedad in objeto) {\n    // codigo a ejecutar \n    }\n\n*/\n\nconst persona = {\n    nombre: \"Raul\",\n    apellido: \"Cruz\",\n    edad: 45\n};\n\nfor (propiedad in persona) {\n    console.log(propiedad, persona[propiedad])\n};\n\n\n//  WHILE\n//  Ejecuta un bloque de código siempre que una condición especificada sea verdadera.\n\n/*\n\nwhile (condition) {\n  // code block to be executed\n}\n*/\n\nlet i = 3;\n\n// mientras i sea menor de 10, se segurirá ejecutando el códgo entre llaves.\nwhile (i < 10) {\n    i++;\n    console.log(\"El numero es \" + i);\n};\n\nconsole.log(\"Fin de bucle while.\")\n\n// DO WHILE\n// Si la condición no se cumple el código se ejecuta una sola vez.\n\ndo {\n    console.log('El número es ' + i);\n    i--;\n}\nwhile (i > 0);\n\n\n// Switch \n\nlet palabra = 'Python';\n\nswitch (palabra) {\n    case 'Python':\n        console.log(`Me gusta ${palabra}`);\n        break;\n    case 'Java':\n        console.log(`Me gusta ${palabra}`);\n        break;\n    case 'Código':\n        console.log(`Me gusta el ${palabra}`);\n        break;\n    default:\n        console.log('No sé programar.');\n        break;\n};\n\n\n// BREAK y CONTINUE\n\n// Delcaración de Ruptura BREAK, se usa para salir de un bucle.\n\n\nlet num2 = 0;\n\nwhile (num2 < 10) {\n\n    num2++;\n    if (num2 === 5) continue;  // Cuando num sea igual a 5 no ejcutara esa iteracion y continuara con el resto \n    \n    console.log(num2);\n};\n\n\nlet num = 0;\n\nwhile (num < 10) {\n\n    num++;\n    if (num === 5) break;  // Cuando num sea igual a 5 el bucle dejara de ejecutarse. \n    console.log(num);\n};\n\n\n/*\nDIFICULTAD EXTRA (opcional):\nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n*/\n\n\nfor(let number = 10; number <= 55; number++) {\n    \n    if(number%2==0 && number%3!==0 && number!==16){\n    console.log(number);\n    }\n};\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/darkhouselab08.js",
    "content": "\nconsole.log(\"--- OPERADORES ---\");\n\n// 1. Aritméticos\nconsole.log(\"Aritméticos:\");\nlet a = 10;\nlet b = 5;\nconsole.log(\"Suma: 10 + 5 =\", a + b);\nconsole.log(\"Resta: 10 - 5 =\", a - b);\nconsole.log(\"Multiplicación: 10 * 5 =\", a * b);\nconsole.log(\"División: 10 / 5 =\", a / b);\nconsole.log(\"Módulo (Resto): 10 % 3 =\", 10 % 3);\nconsole.log(\"Exponenciación: 10 ** 2 =\", a ** 2);\n\n// 2. Lógicos\nconsole.log(\"\\nLógicos:\");\nlet esVerdadero = true;\nlet esFalso = false;\nconsole.log(\"AND (&&): true && false =\", esVerdadero && esFalso); // false\nconsole.log(\"OR (||): true || false =\", esVerdadero || esFalso);   // true\nconsole.log(\"NOT (!): !true =\", !esVerdadero);                    // false\n\n// 3. De Comparación\nconsole.log(\"\\nDe Comparación:\");\nconsole.log(\"Mayor que (>): 10 > 5 =\", a > b);\nconsole.log(\"Menor que (<): 10 < 5 =\", a < b);\nconsole.log(\"Mayor o igual (>=): 10 >= 10 =\", a >= 10);\nconsole.log(\"Menor o igual (<=): 5 <= 10 =\", b <= a);\n\n// 4. De Asignación\nconsole.log(\"\\nDe Asignación:\");\nlet c = 10; // Asignación básica\nc += 5;     // c = c + 5\nconsole.log(\"Asignación de suma (+= 5):\", c); // 15\nc -= 3;     // c = c - 3\nconsole.log(\"Asignación de resta (-= 3):\", c); // 12\nc *= 2;     // c = c * 2\nconsole.log(\"Asignación de multiplicación (*= 2):\", c); // 24\n\n// 5. De Identidad (Comparación Estricta vs. Abstracta)\nconsole.log(\"\\nDe Identidad (Estricta vs. Abstracta):\");\nlet numCinco = 5;\nlet strCinco = \"5\";\n// Abstracta (==): Compara solo el valor, no el tipo. (NO RECOMENDADO)\nconsole.log(\"Abstracta (==): 5 == '5' es\", numCinco == strCinco); // true\n// Estricta (===): Compara valor Y tipo. (RECOMENDADO)\nconsole.log(\"Estricta (===): 5 === '5' es\", numCinco === strCinco); // false\n\n// 6. De Pertenencia (in)\nconsole.log(\"\\nDe Pertenencia (in / .includes()):\");\nlet miArray = [1, 2, 3, 4];\nlet miObjeto = { nombre: \"Franco\", pais: \"Colombia\" };\nconsole.log(\"¿Está el 3 en el array? (.includes()):\", miArray.includes(3)); // true\nconsole.log(\"¿Está 'nombre' en el objeto? (in):\", \"nombre\" in miObjeto); // true\n\n// 7. De Bits (Avanzado)\nconsole.log(\"\\nDe Bits:\");\nconsole.log(\"AND a nivel de bits (5 & 1):\", 5 & 1); // 1\nconsole.log(\"OR a nivel de bits (5 | 1):\", 5 | 1);  // 5\n\nconsole.log(\"\\n--- ESTRUCTURAS DE CONTROL ---\");\n\n// 1. Condicionales (if, else if, else)\nconsole.log(\"\\nCondicional (if):\");\nlet edad = 18;\nif (edad > 18) {\n  console.log(\"Es mayor de 18\");\n} else if (edad === 18) {\n  console.log(\"Tiene 18 años\");\n} else {\n  console.log(\"Es menor de 18\");\n}\n\n// Condicional (switch)\nconsole.log(\"\\nCondicional (switch):\");\nlet dia = \"Lunes\";\nswitch (dia) {\n  case \"Lunes\":\n    console.log(\"¡Ánimo, es Lunes!\");\n    break;\n  case \"Viernes\":\n    console.log(\"¡Hoy es Viernes!\");\n    break;\n  default:\n    console.log(\"Es un día de la semana.\");\n}\n\n// 2. Iterativas (Bucles)\nconsole.log(\"\\nIterativa (for):\");\n// El bucle 'for' es el clásico: (inicio; condición; incremento)\nfor (let i = 0; i < 3; i++) {\n  console.log(\"Número de bucle 'for':\", i);\n}\n\nconsole.log(\"\\nIterativa (while):\");\nlet contador = 0;\nwhile (contador < 3) {\n  console.log(\"Número de bucle 'while':\", contador);\n  contador++; // ¡Importante incrementar para no hacer un bucle infinito!\n}\n\nconsole.log(\"\\nIterativa (forEach):\");\n// 'forEach' es la forma moderna de recorrer un array\nmiArray.forEach(function(numero) {\n  console.log(\"Número en miArray:\", numero);\n});\n\n// 3. Excepciones (try, catch)\nconsole.log(\"\\nExcepciones (try...catch):\");\ntry {\n  // Intentamos ejecutar un código que fallará\n  let resultado = 10 / variableInexistente;\n} catch (error) {\n  // Si falla, \"atrapamos\" el error aquí y el programa no se detiene\n  console.log(\"¡Ups, ocurrió un error!\");\n  console.log(\"Mensaje de error:\", error.message);\n} finally {\n  console.log(\"El bloque 'try...catch' ha finalizado.\");\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/davhage.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\nlet a = 5;\nlet b = 1;\nlet verdad = true;\nlet falso = false;\n\n//? Operadores de asignación\n\nconsole.log(a = b);//asignación\nconsole.log(a += b);//asignación de adición\nconsole.log(a -= b);//asignación de resta\nconsole.log(a /= b);//asignación de multiplicación\nconsole.log(a %= b);//asignación de residuo\nconsole.log(a **= b);//asignación de exponencia\nconsole.log(a <<= b);//asignación de desplazamiento a la izquierda\nconsole.log(a >>= b);//asignación de desplazamiento a la derecha\nconsole.log(a >>>= b);//asignación de desplazamiento a la derecha sin signo\nconsole.log(a &= b);//asignación de AND bit a bit\nconsole.log(a ^= b);//asignación de XOR bit a bit\nconsole.log(a |= b);//asignación de OR bit a bit\nconsole.log(a &&= b);//asignación de AND lógico\nconsole.log(a ||= b);//asignación de OR lógico\nconsole.log(a ??= b);//asignación de anulación lógica\n\n//? Comparación\n\nconsole.log(a == b);//igual\nconsole.log(a != b);//no es igual\nconsole.log(a === b);//estrictamente igual\nconsole.log(a !== b);//desigualdad estricta\nconsole.log(a > b);//mayor que\nconsole.log(a >= b);//mayar o igual\nconsole.log(a < b);//menor que\nconsole.log(a <= b);//menor o igual\n\n//? Operadores aritméticos\n\nconsole.log(a % b);//residuo\nconsole.log(a++);//incremento\nconsole.log(a--);//decremento\nconsole.log(a - b);//resta\nconsole.log(a + b);//suma\nconsole.log(a ** b);//exponenciación\n\n//? Operadores bit a bit\n\nconsole.log(a & b);//AND a nivel de bits\nconsole.log(a | b);//OR a nivel de bits\nconsole.log(a ^ b);//XOR a nivel de bits\nconsole.log(a << b);//desplazamiento a la izquierda\nconsole.log(a >> b);//desplazamiento a la derecha de propagación de signo\nconsole.log(a >>> b);//desplazamiento a la derecha de relleno cero\n\n//? Operaderes lógicos\n\nconsole.log(a && b);//AND lógico\nconsole.log(a || b);//OR lógico\nconsole.log(!b);//NOT lógico\n\n//? Operadores condicional (ternario)\nconsole.log(a > b ? 'yes' : 'no');\n\n//? Estructuras de control\n//* For\nfor(let i = 0; i < 10; i++){\n    console.log(i);\n}\n//* While\n\nlet i = 2;\nwhile(i < 10){\n    if(i % 2 == 0) {\n        console.log('Número par', i);\n    }\n    i++;\n}\n\n//* Do While\n\ndo {\n    if(i % 2 == 0){\n        console.log('Número par', i)\n    }\n    i++;\n} while (1 < 2);\n\n//* If, else if else\nif(i < 2){\n    console.log('menor que 2');\n} else if(i === 2){\n    console.log('2');\n} else {\n    console.log('mayor que 2')\n}\n\nlet accion = 'actualizar';\n\nswitch(accion) {\n    case 'listar':\n        console.log('Acción de listar');\n        break;\n    case 'guardar':\n        console.log('Acción de guardar');\n        break;\n    default:\n        console.log('Acción no reconocida');\n}\n\n//! Ejercicio extra\n\nconst extra = () => {\n    for(let i = 10; i <= 55; i++){\n        if(i % 2 === 0 && i % 3 !== 0 && i !== 16){\n            console.log(i);\n        }\n    }\n}\nextra();"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/davidb313.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n//Operadores aritmeticos\nlet suma = `Suma,  ${1 + 2}`;\nlet resta = `Resta,  ${12 - 2}`;\nlet multi = `Multi,  ${3 * 2}`;\nlet division = `Division, ${5 / 2}`;\nlet residuo = `Residuo, ${10 % 2}`;\n\n//Operadores logicos\nlet operadorAnd = true && false; // en && si ambos son true, da resultado true, si uno llegara a ser falso, el resultado es falso\nlet operadorOr = true || false; // en || si alguna variable es true, el resultado sera true, si todas son falsas, el rsultado sera falso\nlet operadorNot = \"2\" !== 2;\n\n//Operadores de comparacion -> estos operadores devuelven un valor booleano si se cumple o no la igualdad o la comparacion\nlet comparacionEstricta = \"3\" === 3; // el resultado será false, ya que diferencia un string de un numero\nlet comparacionBasica = \"3\" == 3; // el resultado sera true, la comparacion no diferencia un string de un numero\n\nlet mayorQue = 5 > 3; //el resultado sera true\nlet menorQue = 6 < 1; // el resultado sera falso\n\nlet mayorOIgualQue = 5 >= 6; //el resultado es falso 5 no es mayor o igual a 6\nlet menorOIgualQue = 5 <= 6; //el resultado es true 5 es menor o igual a 6, se cumple la condicion de ser menor\n\n//Estructuras de control\n//estructura if - else\nif (mayorOIgualQue) {\n  console.log(\"5 es mayor o igual 6\");\n} else {\n  console.log(\"5 no es mayor o igual a 6\"); // la comprobacion tomará este camino, debido a que la expresion mayorOIgualQue es falsa\n}\n\n//estructura for -> aqui hara varios ciclos depende de las instrucciones, en el ejemplo i inicia en 0, mientras i sea menor o igual a 10, i aumentara en 1, y esto se hara hasta que se cumpla la instruccion de que i sea menor o igual a 10\nfor (let i = 0; i <= 10; i++) {\n  console.log(i);\n}\n\n//estructura while -> hara el ciclo mientras se cumpla la condicion\nlet numeroInicial = 0;\nwhile (numeroInicial < 8) {\n  numeroInicial++;\n  console.log(numeroInicial);\n}\n\nconsole.log(\n  suma,\n  resta,\n  multi,\n  division,\n  residuo,\n  operadorAnd,\n  operadorOr,\n  operadorNot,\n  comparacionEstricta,\n  comparacionBasica,\n  mayorQue,\n  menorQue,\n  mayorOIgualQue,\n  menorOIgualQue\n);\n\n// DIFICULTAD EXTRA (opcional)\nconst numeros = () => {\n  for (i = 10; i <= 55; i++) {\n    if (i !== 16 && i % 3 !== 0 && i % 2 === 0) {\n      console.log(i);\n    }\n  }\n};\nnumeros();\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/davidgar42.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * \n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\nlet num1 = 3\nlet num2 = 6\nlet resultado\n\n//Operadores Aritmeticos\nconsole.log(\"Operadores Aritmeticos\")\nconsole.log(num1 + num2)\nconsole.log(num1 - num2)\nconsole.log(num1 * num2)\nconsole.log(num2 / num1)\nconsole.log(num2 % num1)\nconsole.log(num1 ** num2)\nnum1++\nconsole.log(num1)\nnum1--\nconsole.log(num1)\n\n//Operadores Lógicos\nconsole.log(\"Operadores Logicos\")\n\nconsole.log(num1 > 0 && num2 > 0)\nconsole.log(num1 > 0 || num2 < 5)\nconsole.log(!(num1 > 0) || num2 < 0)\n\n//Operadores de comparación\nconsole.info(\"Operadores de comparación\")\nconsole.log(num1)\nconsole.log(num1 == \"3\")\nconsole.log(num1 === num2)\nconsole.log(num1 != num2)\nconsole.log(num1 !== num2)\nconsole.log(num1 > num2)\nconsole.log(num1 < num2)\nconsole.log(num1 >= num2)\nconsole.log(num1 <= num2)\n\n//Operadores de asignación\nconsole.info(\"Operadores de asignación\")\n\nconsole.log(num1 = num2)\nconsole.log(num1 += 2)\nconsole.log(num1 -= 3)\nconsole.log(num1 *= 4)\nconsole.log(num1 /= 4)\nconsole.log(num1 %= 4)\nconsole.log(num1 **= 4)\n\n//Pertenencia\nconsole.info(\"Operadores de Pertenencia\")\n\nlet cadena = \"Hola mundo\"\nconsole.log(cadena.includes(\"Hola\"))\nconsole.log(cadena.includes(\"hola\"))\n\n//Condicionales, iterativas, excepciones...\n\nif ( 5 > 4){\n    console.log(\"5 es mayor que 4\")\n}else if (6 > 5){\n    console.log(\"seis es mayor que cinco\")\n}else{\n    console.log(\"todos los demas casos\")\n}\n\nfor(let j = 0; j < 10; j++){\n    console.log(j)\n}\n\nlet myArray = [1,\"lunes\",3,true,8]\n\nfor (let i of myArray){\n    console.log(i)\n}\n\nlet myObjet = {\n    name: \"David\",\n    surname: \"Garcia\",\n    age: 38,\n    city: \"Madrid\",\n}\nfor (let a in myObjet){\n    console.log(a +  \": \"+ myObjet[a])\n}\n\n//While\nlet contador = 0\nwhile(contador < 10){\n    contador++\n    console.log(contador)\n}\n\n//Do-While\n\ncontador = 0\nconsole.log(\"Do - While\")\ndo{\n    console.log(contador)\n    contador++\n}while(contador < 10)\n\n//Excepciones\nconsole.log(\"Probando Excepciones\")\ntry{\n    console.log(5/a);\n}\ncatch(error){\n    console.log(`El tipo de Error es: ${error}`);\n}\nfinally{\n    console.log(\"Esto se ejecuta siempre pase lo que pase\")\n}\n\n/*DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3. */\n\nfor (let numero = 10; numero < 56; numero+=2){\n    if (numero != 16 && numero % 3 != 0){\n        console.log(numero)\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/dev-marco-dev.js",
    "content": "//OPERADORES ARITMETICOS\nlet suma = 5 + 5;\nlet resta = 15 - 10;\nlet multiplicacion = 5 * 5;\nlet division = 20 / 4;\nlet exponente = 2 ** 2;\nlet modulo = 4 % 4;\nlet x = 5;\nx++; // console.log(x) da como resultado 6\nx--; // console.log(x) vuelve a dar como resultado 5\n\n//Acortadores\n/*Estos acortadores hacen dos cosas a la vez primero hacen la operacion \ny a la vez asigna a la variable*/\n\n//Ejemplos\n// x += y ---> x = x + y\n// x -= y ---> x = x - y\n// x *= y ---> x = x * y\n// x /= y ---> x = x / y\n// x %= y ---> x = x % y\n// x **= y ---> x = x ** y\n\n//OPERADORES LOGICOS\n\n// && and para que devuelva true ambos tiene que ser true\n// || or  devuelve true si al menos uno de los operandos es true devuelve false si ambos son false\n// ! not niega el operando si es false ahora sera true y visceversa\n// ?? devuelve el valor del operando de la izquierda siempre y cuando no sea ni null ni undefined\n\n// OPERADORES DE COMPARACION\n//igualdad de valor\n10 == 10;\n\n// igualdad de valor\n\n10 === 10;\n\n// diferente de\n\n3 != 3;\n\n// diferencia estricta\n\n3 !==\n  // mayor que\n\n  30 > 15;\n\n// menor que\n\n15 < 30;\n\n// mayor o igual que\n\n30 >= 30;\n\n// menor o igual que\n\n15 <= 15;\n\n/* operadores de pertenencia\noperador in verifica si una propiedad o clave existe dentro de un objeto\n\n*/\n\nlet animal = {\n  nombre: \"negra\",\n  edad: 4,\n};\n\nconsole.log(\"nombre\" in animal); //true\n\n//tambien se puede para un arreglo\n\nlet array = [1, 2, 4, 5, 6];\n\nconsole.log(4 in array); //true\n\n/* el metodo inludes tambien se utiliza para verificar si algun elemento esta dentro\nde un array*/\n\nlet array1 = [2, 4, 5, 6, 7];\nconsole.log(array1.includes(9)); //false\n\n//Ejercicio\n/*Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.*/\n\nfor (let i = 10; i <= 55; i++) {\n  if (i % 2 == 0 && i !== 16 && i % 3 !== 0) {\n    console.log(i);\n  }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/dieswae.js",
    "content": "/* Operadores Aritmeticos */\n\nlet a = 5;\nlet b = 7;\n\nlet suma = a + b; // Suma\nlet resta = a - b; // Resta\nlet multiplicación = a * b; // Multiplicación\nlet división = a / b; // División\nlet modulo = a % b; // Módulo\nlet potencia = a ** b; // Potencia\n\n// incremento\nconsole.log(++a);\nconsole.log(a++);\n// decrementar\nconsole.log(--a);\nconsole.log(a--);\n\n/* Operadores de Asignación */\n\nlet x = 5;\nx += 5; // Suma\nx -= 5; // Resta\nx *= 5; // Multiplicación\nx /= 5; // División\nx %= 5; // Módulo\nx **= 5; // Potencia\n\n/* Operadores de Comparación */\n\n//Relacionales\nlet n1 = 10;\nlet n2 = 5;\nlet comp1 = n1 > n2;\nlet comp2 = n1 >= n2;\nlet comp3 = n1 < n2;\nlet comp4 = n1 <= n2;\n\n//Igualdad\nlet comp5 = n1 === n2;\nlet comp6 = n1 !== n2;\n\n/* Operadores Lógicos */\n\n// AND\nlet and = true && true; // true\nlet and2 = false && true; // false\n\n// OR\nlet or = true || false // true\nlet or2 = false || false; // false\n\n// NOT\nlet verdadero = true;\nlet falso = false;\nlet not = !verdadero; // false\nlet not2 = !falso; // true\n\n/* Operadores de Bitwise */\n\n// Operador Bitwise de AND\nlet bitwise = 1 | 3; // 00000011 = 3\nlet bitwise2 = 1 | 4; // 00000101 = 5\nlet bitwise3 = 3 | 5; // 00000111 = 7\n\n//Operador Bitwise de OR\nlet bitwise4 = 1 & 3; // 000000001 = 1\nlet bitwise5 = 1 & 4; // 000000000 = 0\nlet bitwise6 = 3 & 5; // 000000001 = 1\n\n\n/* if - else - else if */\nlet edad = 15;\n\nif (edad > 17) {\n  console.log('Usuario mayor de edad');\n} else if (edad >= 13) {\n  console.log('Usuario necesita estar acompañado');\n} else {\n  console.log('Usuario menor de edad');\n}\n\n/* switch */\nlet accion = 'listar';\n\nswitch (accion) {\n  case 'listar':\n    console.log('Acción de listar');\n    break;\n  case 'guardar':\n    console.log('Acción de guardar');\n    break\n  default:\n    console.log('Accion no reconocida');\n}\n\n/* while */\n// cuales son los numeros pares\nlet i = 0;\nwhile (i < 10) {\n  if (i % 2 == 0) {\n    console.log('Número par', i);\n  }\n  i++;\n}\n\n/* do while */\ndo {\n  if (i % 2 == 0) {\n    console.log('Número par', i);\n  }\n  i++;\n} while (i < 10)\n\n/* for */\nfor (let i = 2; i < 8; i++) {\n  if (i % 2 == 0) {\n    console.log('Número par', i);\n  }\n}\n\n/* for of */\nlet animales = ['dragon', 't-rex', 'cobra'];\n\nfor (let animal of animales) {\n  console.log(animal);\n}\n\n/* for in */\nlet user = {\n  id: 1,\n  name: 'diego',\n  age: 22,\n};\n\nfor (let prop in user) {\n  console.log(prop, user.prop);\n}\n\n/* DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3. */\n\nfor (let x = 10; x <= 55; x ++) {\n  if (x % 2 === 0 && x !== 16 && x % 3 !== 0) {\n    console.log(x);\n  }\n}\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/doblea74.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n// EJERCICIO:\nlet a = 1;\nlet b = 1;\nlet c = 1;\n\n\n//Operadores aritmeticos\n\nlet suma = a + b;\nlet resta = a - b;\nlet multiplicacion = a * b;\nlet division = a / b;\nlet modulo = a % c;\nlet exponente2 = a **2;\n\n//Operadores de comparacion\n\nconsole.log(a == b);//comprobacion de igualdad\nconsole.log(a != b); //comprobacion de desigualdad\nconsole.log(a > b); //comprobacion de q es mayor\nconsole.log(a < b); //comprobacion de q es menor\nconsole.log(a >= b); //comprobacion de q es mayor igual\nconsole.log(a <= b); //comprobacion de q es menor igual\n\n//operadores logicos\nconsole.log(\"logica 1 \" + (10 + 3 == 13 && 5 - 1 == 4));\nconsole.log(\"logica 2 \" + (10 + 3 == 14 || 5 - 1 == 4));\nconsole.log(\"logica 3 \" + (10 + 3 != 14 ));\n\n//operadores de asignacion\n\nlet myNumber = 11;\n\nmyNumber += 1;\nmyNumber -= 1;\nmyNumber *= 1;\nmyNumber /= 1;\nmyNumber %= 1;\nmyNumber **= 1;\n\n//Operadores de identidad\n\nlet myNewNumber = myNumber;\nconsole.log(myNumber == myNewNumber);\nconsole.log(myNumber != myNewNumber);\n\n//Operadores de pertenencia\nlet string = \"estos es un string\"\nconsole.log(string.includes('e'));\n\n//Operadores de bit\nlet num1 = 10;\nlet num2 = 3;\n\nconsole.log(\"and: \"+ (num1 & num2));\nconsole.log(\"or: \"+ (num1 | num2));\nconsole.log(\"xor: \"+ (num1 ^ num2));\n\n//Estructuras de control\n\n//condicionales\n\nlet edad = 18;\nif (edad >=18) {\n    console.log(\"podes manejar\");\n}else{\n    console.log(\"no podes manejar\");\n}\n\n// iterativas\n\nfor (let i = 0; i < 11 ; i++) {\n    console.log(i);;\n}\n\n//dificultad extra\n\nfor (let num = 10; num < 56; num++) {\n    if (num % 2 == 0 &&\n        num !== 16 &&\n        num %3 !== 0\n        ) {\n        console.log(num);\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/domo2pdev.js",
    "content": "/*\nEJERCICIO:\n- Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n- Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n   que representen todos los tipos de estructuras de control que existan\n   en tu lenguaje:\n   Condicionales, iterativas, excepciones...\n- Debes hacer print por consola del resultado de todos los ejemplos.\n\nDIFICULTAD EXTRA (opcional):\nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\nSeguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n// Operators (Operadores)\n\n// Arithmetic Operators\n\n// Addition Operator (+) \nlet ageOne = 15;\nlet ageTwo = 20;\nlet ageAddition = ageOne + ageTwo;\nconsole.log(`The age addition is ${ageAddition}`);\n\n// Subtraction Operator (-)\nlet fathersAge = 42;\nlet daughtersAge = 8;\nlet ageDifference = fathersAge - daughtersAge;\nconsole.log(`The age difference is ${ageDifference}`);\n\n// Multiplication Operator (*)\nlet applesPerBox = 3;\nlet numberOfBoxes = 43;\nlet totalApples = applesPerBox * numberOfBoxes;\nconsole.log(`The total amount of apples is ${totalApples}`);\n\n// Exponentiation Operator (**)\nlet myBase = 2;\nlet myExponent = 3;\nlet myExponentiationResult = myBase ** myExponent;\nconsole.log(`The result of the exponentiation is ${myExponentiationResult}`);\n\n// Division Operator (/)\nlet myDividend = 540;\nlet myDivisor = 9;\nlet divisionResult = myDividend / myDivisor;\nconsole.log(`The result of the dividion is ${divisionResult}`);\n\n// Modulus Operator (%)\nlet myModulusDividend = 369;\nlet myModulusDivisor = 6;\nlet myModulusResult = myDividend % myDivisor;\nconsole.log(`The modulus of this division is ${myModulusResult}`);\n\n// Increment Operator (++)\nlet incrementalVariable = 0;\nlet incrementResult = ++incrementalVariable;\nconsole.log(`The increment of this variable is ${incrementResult}`);\n\n// Decrement Operator (--)\nlet decrementalVariable = 12;\nlet decrementResult = --decrementalVariable;\nconsole.log(`The decrement of the variable is ${decrementResult}`)\n\n// Assignment Operators\n// (=) assigns a  value to a variable\nlet myShoes = \"a pair of shoes\";\nlet mySize = 42;\nconsole.log(`I have ${myShoes} size ${mySize}`);\nconsole.log(`Addition assignment operator (+=) size: ${mySize += 1}`);\nconsole.log(`Subtraction assignment operator (-=) size: ${mySize -= 2}`);\nconsole.log(`Multiplication assignment operator (*=) size: ${mySize *= 3}`);\nconsole.log(`Division assignment operator (/=) size: ${mySize /= 3}`);\nconsole.log(`Modulus assignment operator (%=) size: ${mySize %= 6}`);\nconsole.log(`Exponentiation assignment operator (**=) size: ${mySize **= 2}`);\n\n// Comparison Operators\nlet coordinateX = 2;\nlet errorMessage = \"2\"\nlet coordinateY = 7;\nconsole.log(`Comparison Equal to (==). Is coordinateX equal to errorMessage: ${coordinateX == errorMessage}`); //allows type coercion (it converts operands to a common type before comparing)\nconsole.log(`Comparison Equal value and equal type (===) ${coordinateX === coordinateY}`); //requires both the value and type to be the same.\nconsole.log(`Comparison Not Equal (!=) ${coordinateX != coordinateY}`);\nconsole.log(`Comparison Not equal value or not equal type (!==) ${coordinateX !== coordinateY}`);\nconsole.log(`Comparison Greater than (>) ${coordinateX > coordinateY}`);\nconsole.log(`Comparison Less than (<) ${coordinateX < coordinateY}`);\nconsole.log(`Comparison Greater than or equal to (>=) ${coordinateX >= coordinateY}`);\nconsole.log(`Comparison less than or equal to (<=) ${coordinateX <= coordinateY}`);\nconsole.log(`Comparison ternary operator (?) Is it less? ${coordinateX < coordinateY ? \"Yes it is\" : \"No it is not\"}`);\n\n// Logical Operators\nconst x = 3;\nconst y = 6;\nconst z = 9;\nconsole.log(`Logical AND - This expresion is: ${(x < y) && (y < z)}`);\nconsole.log(`Logical OR - This expresion is: ${(x < y) || (y > z)}`);\nconsole.log(`Logical Not - This expresion is ${! (x > y)}`);\n\n//Type Operators\nconsole.log(typeof (x >= y));\n\nclass Vehicle{}\nclass Honda extends Vehicle{}\nconst myHonda = new Honda();\n\nconsole.log(myHonda instanceof Honda);\nconsole.log(myHonda instanceof Vehicle);\nconsole.log(myHonda instanceof Object);\n\n// Bitwise Operators\nlet myNumberX = 10;\nlet myNumberY = 3;\nconsole.log(`Bitwise AND (&) ${myNumberX & myNumberY}`);\nconsole.log(`Bitwise OR (|) ${myNumberX | myNumberY}`);\nconsole.log(`Bitwise NOT (~) ${~ myNumberX}`);\nconsole.log(`Bitwise XOR (^) ${myNumberX ^ myNumberY}`);\nconsole.log(`Left shift (<<) ${myNumberX << myNumberY}`);\nconsole.log(`Right shift (>>) ${myNumberX >> myNumberY}`);\nconsole.log(`Unsigned right shift (>>>) ${myNumberX >>> myNumberY}`);\n\n/* Control statements */\n\n// if statements\nlet cupOfCoffee = \"empty\";\nlet coffeMakerStatus = \"off\";\n\nif(cupOfCoffee === \"full\"){\n   console.log(\"You can drink some coffee\");\n} else if (coffeMakerStatus === \"off\"){\n   console.log(\"Turn on the coffee maker, right now!\");\n} else {\n   console.log(\"Don't worry Everything is ok\");\n}\n\n// Switch Statement\nlet carStatus = \"iddle\";\nswitch(carStatus) {\n   case \"moving\":\n     console.log(\"You will get home\");\n     break;\n   case \"stopped\":\n     console.log(\"You are not moving\");\n     break;\n   default:\n     console.log(\"Try to start your car\");\n } \n\n // for loop\n let cars = [\"Honda\", \"Chevrolet\", \"Mercedes Benz\", \"Renault\"];\n for (let i = 0; i < cars.length; i ++){\n   console.log(cars[i]);\n }\n\n // while loop\n let i = 0;\n while(i < cars.length){\n   console.log(cars[i]);\n   i++;\n }\n\n // do while loop\n let j = 0;\n do {\n   console.log(cars[j]);\n   j++;\n } while(j < cars.length);\n\n// try catch statement\ntry {\n   let i = 0;\n   while(i < cars.length){\n     console.log(cars[i]);\n     i++;\n   }\n } catch (error) {\n   console.log(error.message);\n } finally {\n   console.log(\"The loop has finished\");\n }\n\n/* Extra \nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\nSeguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n*/\nfor (i = 10; i <= 55;   i++){\n  if (i % 2 === 0){\n    if (i !== 16 && i % 3 !== 0){\n      console.log(i);\n    }\n  }\n  }"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/duendeintemporal.js",
    "content": "/* { RETOS DE PROGRAMACIÓN }  #1 OPERADORES Y ESTRUCTURAS DE CONTROL */\n//Note: I use Matt Frisbie book \"Professional JavaScript for Web Developers\" as a reference to give accurate additional information about the use of some operantors\n//I also serch some tips in JavaScript Notes for Professionals from the beautiful people of StackOverflow. You can get it for free in GoalKicker.com\n\n//short for console.log\nlet log = console.log.bind(console);\n\n/*  OPERATORS  */\n//Unary Operators \n        \n        //Unary Plus and Minus\n/*  When the unary plus is applied to a nonnumeric value, it performs the same conversion as the\nNumber() casting function: the Boolean values of false and true are converted to 0 and 1, string\nvalues are parsed according to a set of specific rules, and objects have their valueOf() and/or\ntoString() method called to get a value to convert. */\n\n    let str1 = \"03\";\n    str1 = +str1;\n    log(str1) // value becomes numeric 3\n\n    let str2 = \"1.4\";\n    log(str1 + +str2)// 4.4\n\n    str2 = +str2; \n    log(str2) // value becomes numeric 1.4\n\n    let str3 = \"zaz\";\n    str3 = +str3; \n    log(str3) // value becomes NaN\n\n    let bool = true;\n    bool = +bool; \n    log(bool) // value becomes numeric 1\n\n    let f_num = 2.8;\n    f_num = +f_num; \n    log(f_num) // no change, still 2.8\n\n    let obj = {\n        valueOf() {\n            return -5;\n        }\n    };\n    obj = +obj; \n    log(obj) // value becomes numeric -5\n\n/* The unary minus operator’s primary use is to negate a numeric value, such as converting 1 into –1. The simple case is illustrated here: */\n\n    let g_actions=50;\n    g_actions= -g_actions;\n    log(g_actions) // value becomes -50\n\n/* When used on a numeric value, the unary minus simply negates the value. When used on non numeric values, unary minus applies all of the same rules as unary plus and then negates the result */\n\n    str1 = -str1;\n    log(str1) // value becomes numeric -3\n\n    str2 = -str2; \n    log(str2) // value becomes numeric -1.4\n\n    str3 = -str3; \n    log(str3) // value becomes NaN\n\n    bool = -bool; \n    log(bool) // value becomes numeric -1\n\n    f_num = -f_num; \n    log(f_num) // no change, still -2.8\n\n    obj = -obj; \n    log(obj) // value becomes numeric 5\n\n\n     //Increment/Decrement ++ --\n     let num1 = 10, num2 = 5, num3, num4;\n     num3 = num1++;\n     log(num3); // 10\n     log(num1); // 11\n     num3 = ++num1;\n     log(num3); // 12\n     log(num1); // 12\n     num4 = num2--;\n     log(num4); // 5\n     log(num2); // 4\n     num4 = --num2;\n     log(num4); // 3\n     log(num2); // 3\n     num4++;\n     log(num4); // 4\n\n\n    //Bitwise Operators\n/* The next set of operators works with numbers at their very base level, with the bits that represent them in memory. \nWhen you apply bitwise operators to numbers in ECMAScript, a conversion takes place behind the scenes: the 64-bit number is converted into a 32-bit number, the operation is performed, and then the 32-bit result is stored back into a 64-bit number. */\n\n//Bitwise NOT  ~\n//The bitwise NOT is represented by a tilde (~) and simply returns the one’s complement of the number.\nlet n1 = 25; //  binary 00000000000000000000000000011001\nlet n2 = ~n1; // binary 11111111111111111111111111100110\nlog(n2); // -26   it negates the number and subtracts 1\n//same to say\nn2 = -n1 -1;\n//but bitwise operation performs faster cause it works at the lowest lavel of numeric representation.\n\n//Bitwise AND &\n//A bitwise AND operation returns 1 if both bits are 1. It returns 0 if any bits are 0.\n\nlet n3 = 25 & 3;\nlog(n3) /* logs: 1 cause the comparation of both binary codes is : \n    25 = 0000 0000 0000 0000 0000 0000 0001 1001\n     3 = 0000 0000 0000 0000 0000 0000 0000 0011\n    ---------------------------------------------\n   AND = 0000 0000 0000 0000 0000 0000 0000 0001   */\n\n//Bitwise OR |\n//A bitwise OR operation returns 1 if at least one bit is 1. It returns 0 only if both bits are 0.\n\nn3 = 25 | 3; \nlog(n3) /* Logs: 27 cause the comparation of both binary codes is :\n    25 = 0000 0000 0000 0000 0000 0000 0001 1001\n     3 = 0000 0000 0000 0000 0000 0000 0000 0011\n    ---------------------------------------------\n    OR = 0000 0000 0000 0000 0000 0000 0001 1011   */\n\n//Bitwise XOR\n//Bitwise XOR is different from bitwise OR in that it returns 1 only when exactly one bit has a value of 1 (if both bits contain 1, it returns 0).\n\nn3 = 25 ^ 3;\nlog(n3); /* Logs: 26 cause the comparation of both binary codes is :\n    25 = 0000 0000 0000 0000 0000 0000 0001 1001\n     3 = 0000 0000 0000 0000 0000 0000 0000 0011\n    ---------------------------------------------\n   XOR = 0000 0000 0000 0000 0000 0000 0001 1010   */\n\n//Left Shift\n//The left shift is represented by two less-than signs (<<) and shifts all bits in a number to the left by the number of positions given\n\nlet number = 2; // 10 in binary code\nlet new_number = number << 6; // 10000000 in binary code wich is decimal 128\nlog(new_number)// 128\n\n/*  |1|         |0|       |0|       |0|       |0|        |0|       |0|      |0|\n(2^7x1)  +  (2^6x0) + (2^5x0) + (2^4x0) + (2^3x0) + (2^2x0) + (2^1x0) + (2^0x0) //here ^ is a powder\n 128     +     0    +    0    +    0    +   0     +    0    +    0    +   0    = 128   */\n\n//Signed Right Shift\n//The signed right shift is represented by two greater-than signs (>>) and shifts all bits in a 32-bitnumber to the right while preserving the sign (positive or negative). \n\nnumber = 128; // 10000000 in binary code\nnew_number = number >> 6 // 10 in binary code wich is decimal 2\nlog(new_number)// 2\n\n\n//Unsigned Right Shift\n/* The unsigned right shift is represented by three greater-than signs (>>>) and shifts all bits in a 32-bit number to the right. For numbers that are positive, the effect is the same as a signed right shift. For negative numbers unlike signed right shift, the empty bits get filled with zeros regardless of the sign of the number.*/\n\nnumber = -64; // equal to binary 11111111111111111111111111000000\nnew_number = number >>> 5; // equal to decimal 134217726\nlog(new_number)// 134217726\n/* because the unsigned right shift treats this as a positive number, it considers the value to be\n4294967232. When this value is shifted to the right by five bits, it becomes 00000111111111111111\n111111111110, which is 134217726. */\n\n\n/* Boolean operators */\n//Logical NOT ! \n//can be used in any value. This operator always returns a Boolean value, regardless of the data type it’s used on. The logical NOT operator first converts the operand to a Boolean value and then negates it,\n\nlog(!false); // true\nlog(!\"shadow\"); // false\nlog(!0); // true\nlog(!NaN); // true\nlog(!\"\"); // true\nlog(!57344); // false\nlog(!null) // true\nlog(!undefined) // true\n\n//it can be used to transform a value into it's boolean equivalent by using two NOT operators in a row\n\nlet name = 'Angy';\n//name = !!name;\n//log(name); // Logs: true\n\n//Note: see that the first negate the value after covert it, the second just convert it to boolean.\n\n//Logical ADN &&\n//it operates over two values and return true if both values are true, false otherwise\nlog(true && name)// Angy\nlog(false && 'Angy')// false\nlog(4 < 5 && 8 >6)// true\n/* Logical AND can be used with any type of operand, not just Boolean values. When either operand is\nnot a primitive Boolean, logical AND does not always return a Boolean value; instead, it does one of the following:\n➤➤ If the first operand is an object, then the second operand is always returned.\n➤➤ If the second operand is an object, then the object is returned only if the first operand evalu-\nates to true.\n➤➤ If both operands are objects, then the second operand is returned.\n➤➤ If either operand is null, then null is returned.\n➤➤ If either operand is NaN, then NaN is returned.\n➤➤ If either operand is undefined, then undefined is returned. */\n\n\n\n//Logical OR ||\n//it operates over two values and return true if both or one of both values are true, false other wise\nlet empty = '';\nlog(false || empty)// Logs: <empty string>\nlog(name || empty)// Angy\nlog(4 >= 5 || 8 >6)// true \n\n/* Just like logical AND, if either operand is not a Boolean, logical OR will not always return a Boolean value; instead, it does one of the following:\n➤➤ If the first operand is an object, then the first operand is returned.\n➤➤ If the first operand evaluates to false, then the second operand is returned.\n➤➤ If both operands are objects, then the first operand is returned.\n➤➤ If both operands are null, then null is returned.\n➤➤ If both operands are NaN, then NaN is returned.\n➤➤ If both operands are undefined, then undefined is returned. */\n\n//Note: Both AND and OR are short-circuit operants, this means sometimes only the first operator is evaluated\n\n//Multiplicative Operators\n/* There are three multiplicative operators in ECMAScript: multiply, divide, and modulus. These operators work in a manner similar to their counterparts in languages such as Java, C, and Perl, but they also include some automatic type conversions when dealing with nonnumeric values. */\n\n//Multiple Operator *\nnumber = 4 * '8';\nlog(number)// Logs: 32 cause the above explanation\n\n//Divide Operator /\nnumber = 10 / 5;\nlog(number)// Logs: 2\nnumber = 4 / 40;\nlog(number)// Logs: 0.1 \n\n//Modulus (remainder) Operator %\nnumber = 41 % 5;\nlog(number)// Logs: 1\n\n//Exponentiation Operator **\nnumber = 4 ** 2;\nlog(number)// Logs: 16\n//same as\nlog(Math.pow(4,2))// 16\n\n//Add Operator +\nnumber = 76 + 78;\nlog(number)// 154\nlog('76' + '78')// 7678 on strings performs as a concatenator\n\nnumber = BigInt(767867686876876) + BigInt(6757575755);\nlog(number)// 767874444452631n\n\n//Subtract -\nnumber = 48 - 3;\nlog(number)// 45\n\n//Note: These operators has a particulary behavior in some cases when are used with Infinity, 0, NaN or a non numeric values, you should search if you want more information.\n\n\n/* Relatioanl Operators */\n/* The less-than (<), greater-than (>), less-than-or-equal-to (<=), and greater-than-or-equal-to (>=) relational operators perform comparisons between values in the same way that you learned in math class. */\nlet computation = 76 < 4;\nlog(computation)// false\ncomputation = 87 > 32;\nlog(computation)// true\ncomputation = 43 <= 43;\nlog(computation)// true\ncomputation = 44 >= 85;\nlog(computation)// false\n\nlet user ={\n    name: 'Clavin & Hobbes'\n}\n\nlog(user <= 4)// false\n\nlog(\"43\" < \"8\")// true\nlog(\"43\" < 8)// false\n\nlog('DeepState' < 'real people')// true not only cause are more real people, but when we talk about strings the upper characters has lower codes than the regulars ones\nconsole.log('DeepState'.toLowerCase() < 'real people'.toLocaleLowerCase())// true again ... well ummm sometimes we win \n\n/* As with other operators in ECMAScript, there are some conversions and other oddities that happen\nwhen using different data types. They are as follows:\n➤➤ If the operands are numbers, perform a numeric comparison.\n➤➤ If the operands are strings, compare the character codes of each corresponding character in\nthe string.\n➤➤ If one operand is a number, convert the other operand to a number and perform a numeric\ncomparison.\n➤➤ If an operand is an object, call valueOf() and use its result to perform the comparison\naccording to the previous rules. If valueOf() is not available, call toString() and use that\nvalue according to the previous rules.\n➤➤ If an operand is a Boolean, convert it to a number and perform the comparison */\n\n//Equality operators\n//Determining whether two variables are equivalent is one of the most important operations in programming.\n\n//equal or Equality Operator ==\nlog(2 == '2')// true\n//deep comparation, also comapare types. identically equal or Strict Equality Operator ===\nlog(2 === '2')// false\n//not-equal or Inequality Operator !=\nlog(2 != '2')// false\n//deep comparation, also compare types. identically not-equal or Strict Inequality Operator !==\nlog(2 !== '2')// true\n\n/* When performing conversions, the equal and not-equal operators follow these basic rules:\n➤➤ If an operand is a Boolean value, convert it into a numeric value before checking for\nequality. A value of false converts to 0, whereas a value of true converts to 1.\n➤➤ If one operand is a string and the other is a number, attempt to convert the string into a\nnumber before checking for equality.\n➤➤ If one of the operands is an object and the other is not, the valueOf() method is called on\nthe object to retrieve a primitive value to compare according to the previous rules.\n\nThe operators also follow these rules when making comparisons:\n➤➤ Values of null and undefined are equal.\n➤➤ Values of null and undefined cannot be converted into any other values for\nequality checking.\n➤➤ If either operand is NaN, the equal operator returns false and the not-equal operator\nreturns true. Important note: even if both operands are NaN, the equal operator returns\nfalse because, by rule, NaN is not equal to NaN.\n➤➤ If both operands are objects, then they are compared to see if they are the same object. If\nboth operands point to the same object, then the equal operator returns true. Otherwise,\nthe two are not equal. */\n\nlog(NaN != NaN)// true\nlog(true == 1)// true\nlog(null==undefined)// true\nlog(null===undefined)// false\n\n//Conditional Operator (condition)? true : false;\n/* This basically allows a conditional assignment to a variable depending on the evaluation of the\nboolean_expression. If it’s true, then true_value is assigned to the variable; if it’s false, then\nfalse_value is assigned to the variabl */\n\n\nlet login = (user.name == 'Nixon')? `Succesfull login, Wellcome ${user.name}` : \"Sorry we don't have any user with that name\";\nlog(login)// Sorry we don't have any user with that name\n\n//Assignment Operators\n\nlet a = 'a';\na = a + a;\nlog(a)// aa\n\nnumber = 8;\n\n/* Compound assignment is done with one of the multiplicative, additive, or bitwise–shift operators\nfollowed by an equal sign (=). These assignments are designed as shorthand for such common situa-\ntions as: */\n\nnumber *= number;\nlog(number)// 64\n\nnumber -= 4;\nlog(number)// 60\n\n/* Compound-assignment operators exist for each of the major mathematical operations and a few\nothers as well. They are as follows:\n➤➤ Multiply/assign (*=)\n➤➤ Divide/assign (/=)\n➤➤ Modulus/assign (%=)\n➤➤ Add/assign (+=)\n➤➤ Subtract/assign (-=)\n➤➤ Left shift/assign (<<=)\n➤➤ Signed right shift/assign (>>=)\n➤➤ Unsigned right shift/assign (>>>=)\nThese operators are designed specifically as shorthand ways of achieving operations. They do not\nrepresent any performance improvement. */\n\n// Membership Operators\n// the in operator\nlet Crows = {\n    description: \"Mutant fat man lives beyond the margins of the known universe...\",\n    age: 600,\n}\n\nlog('description' in Crows)// true\nlog('location' in Crows)// false\n\n// instanceof operator\n\nclass User {\n    constructor(name, age, email) {\n        this.name = name;\n        this.age = age;\n        this.email = email;\n    }\n\n    greeting() {\n        return `Hi ${this.name}. Wellcome to Roadmap Exercise #01.`;\n    }\n}\n\nconst niko_zen = new User('Niko', 41, 'duendeintemporal@hotmail.com');\nlog(niko_zen.greeting())// 'Hi Niko. Wellcome to Roadmap Exercise #01';\n\nlog(niko_zen instanceof User) // true\nlog(niko_zen instanceof Object) // true\nlog(4 instanceof Number) // false cause 4 is a primitive value\nlet four = new Number(4)\nlog( four instanceof Number)// true\n\n// Type Operators\n// we can use instanceof or typeof\nlog(typeof true)// boolean\nlog(typeof NaN)// number\nlog(typeof niko_zen)// object \n\n//Destructuring Operatorations   spread operator ...\n// on arrays\nlet books = ['Dune', 'Shibumi', 'El Maestro de Esgrima', 'El Perfume'];\nlet books2 = ['Elocuent javascript', 'You Don’t Know JS ES6 Beyond', 'Linux Command Line An Admin Beginners Guide', 'Learn Bash the Hard Way', 'Programming Algorithms', 'MATLAB Notes for Professionals']\nconst mix_books = [...books, ...books2];\nconst [frank_herbert, trevanian] = books;\nlog(trevanian)//Logs: Shibumi\n\n// on objects\nconst { email } = niko_zen;\nlog(email)// duendeintemporal@hotmail.com\n\nconst niko_zen_settings ={\n    mode: 'dark',\n    avatar: 'moebius.svg',\n    interfaz: 'compact',\n}\n\nconst niko_zen_data = { ...niko_zen, ...niko_zen_settings };\nlog(niko_zen_data)//Logs both objects niko_zen instance and niko_zen_settings\n\nfunction showUser({name, age, email}){\n    log(`User name: ${name}, age: ${age}, email: ${email}`);\n}\n\nshowUser(niko_zen)// Logs: User name: Niko, age: 41, email: duendeintemporal@hotmail.com\n\n// we can also asign default values in destructuring\n\nconst config = { font: 'monospace' };\nconst { font, mode = 'dark' } = config;\n\nlog(font, mode)// monospace dark\n\n//you can use destructuring for exchange values on two or more variables\nlet ninja1 = 'Hiroshi';\nlet ninja2 = 'Neko';\nlet ninja3 = 'Kage';\n\n[ninja1, ninja2, ninja3] = [ninja2, ninja3, ninja1];\nlog(ninja1)// Neko\n\n// you can copy objects or arrays without modifing the original\nconst shinobi = {\n    skills: ['fast', 'quick', 'precise', 'lethal', 'computational thinking'],\n    location: 'no found',\n}\n\nconst trix = { ...shinobi };\ntrix.location = 'Bangkok, Thailand';\n\nlog(shinobi.location)// no found\nlog(trix.location)// Bangkok, Thailand\n\n// you can also use spread operator to pass array elements as arguments in functions or methods\nnums = [1,3,4,5,6,]\nlog(Math.max(...nums))// logs: 6\n\n// or to create an array of arguments\nconst calculateAverage = (...numbers)=> {\n    const total = numbers.reduce((sum, num) => sum + num, 0);\n    return total / numbers.length;\n}\n\n// see that when we call the function all the arguments get holded in numbers\nconst average = calculateAverage(90, 76, 45, 23, 67);\nconsole.log(average); // 60.2\n\n// you can also use it to convert a string into an array of its individual characters\n\nlet maximum = 'in a society that has abolish every kind of adventure, the only adventure that remains is abolish the society'\n\nlet maxim_arr = [...maximum];\nlog(maxim_arr)//  [ \"i\", \"n\", \" \", \"a\", \" \", \"s\", \"o\", \"c\", \"i\", \"e\", … ]\n\n//Comma Operator\n//The comma operator allows execution of more than one operation in a single statement, as illustrated here:\n\nlet number1 = 1, number2 = 2, number3 = 3, number4;\nlog(number1, number2, number3, number4)// 1 2 3 undefined\n\n/*Most often, the comma operator is used in the declaration of variables; however, it can also be used to assign values. When used in this way, the comma operator always returns the last item in the\nexpression, as in the following example: */\nnumber = (225, 14, 40, 8, 220); // num becomes 220\nlog(number)// 220\n/*There aren’t many times when commas are used in this way; however, it is helpful to understand that this behavior exists. */\n\n//Flow Control Statements\n//the if statement\nif(number){\n    number+=4;\n    log(number)// 224\n}\n\n//the else statement\nif(number){\n    number+=4;\n    log(number)// 228\n}else{\n   // what ever\n}\n\n//the else if statement\nif(number > 300){\n    number+=4;\n    log(number)\n}else if(number > 200){\n    number+=4;\n    log(number)// Logs: 232\n}\nelse{\n   //do something\n}\n\n// the do-while statement\n/* The do-while statement is a post-test loop, meaning that the escape condition is evaluated only after the code inside the loop has been executed. */\nlet count = 0;\ndo {\n    log(\"I'm learning a lot in this roadmap for coders, even with these basic exercises\")\n    count++;\n} while (count < 1);\n\n// the while statement\n//while(true){\n    //do something\n    //create an infinite loop cause always evaluate to true\n//}\n\n// the for statement\nnumber = 0;\nfor(let i = 1; i <= 100; i++){\n    number += i;\n}\nlog(number)// Logs: 5050\n\n//Nothing can be done with a for loop that can’t be done using a while loop. The for loop simply encapsulates the loop-related code into a single location.\n\n// the for-in statement\n// let us iterate over the properties of object elements\nlet user2 = {\n    name: 'Nikita',\n    age: 32,\n    location: 'No Found',\n}\n\nfor(let data in user2){\n    log(data) // logs only the property \n    log(data, user2[data]) // logs the property and the value\n    log(data, eval('user2.' + data)) // the same as before \n}\n\n/* Object properties in ECMAScript are unordered, so the order in which property names are returned\nin a for-in statement cannot necessarily be predicted. All enumerable properties will be returned\nonce, but the order may differ across browsers. */\n\n// the for-of statement\n// is thinked to iterate over array elements\nlet oddNums = [1,3,5,7,9]\n\nfor(let num of oddNums){\n    log(num)// logs each num\n}\n\n/* we can use Object.entries(), Object.keys(), Object.values() to iterate over object f. e.\n\nObject.entries(user2) result in: \n [\n    [ \"name\", \"Nikita\" ]\n    [ \"age\", 32 ]\n    [ \"location\", \"No Found\" ]\n ] */\n// so we can just\nfor(let [key, val] of Object.entries(user2)){\n    log(`${key}: ${val}`);\n}\n\n// Label statements\nouter_loop:for(let i = 0; i <= 10; i++){\n    inner_loop:for(let y = 0; y < 5; y++){\n             if((i==2) && (y == 4)) break outer_loop;\n             if(y==4) break inner_loop;\n             log('Is there anybody outthere?')\n    }\n}\n\n// break and continue statements\n/* The break and continue statements provide stricter control over the execution of code in a loop.\nThe break statement exits the loop immediately, forcing execution to continue with the next state-\nment after the loop. The continue statement, on the other hand, exits the loop immediately, but\nexecution continues from the top of the loop. Here’s an example: */\nnumber = 0;\nwhile(number < 5){\n    if(number == 3) break;\n      log(number);\n      number++;\n}// Logs: number value three times: 0 1 2\n\nnumber = 0;\nwhile(number < 5){\n    if(number == 3){\n        number++;\n        continue;  \n     }\n    log(number);\n     number++;\n}// Logs: number value four times: 0 1 2 4\n\n//The with Statement\n\n/* The with statement was created as a convenience for times when a single object was being coded to over and over again, as in this example: \n\nlet qs = location.search.substring(1);\nlet hostName = location.hostname;\nlet url = location.href;\n\nHere, the location object is used on every line. This code can be rewritten using the with statement\nas follows: \n\nwith(location) {\nlet qs = search.substring(1);\nlet hostName = hostname;\nlet url = href;\n} */\n\n//example\nwith(user){\n    log(name)// Clavin & Hobbes\n//    log(age)// thow an error cause age is undefined\n}\n\n//Note: the with statement is generally discouraged in modern JavaScript because it can lead to code that is difficult to read and maintain, and it can also cause performance issues.\n\n// The Switch Statement\n\nswitch(user.name){\n    case 'Nikita': \n        log('Wellcome agent');\n        break;\n    case 'Calvin &' + 'Hobbes': \n        log('Bring me some cookies');\n        break;\n    default: \n        log('Turn off that TV'); //log this cause is missing and space in the second case                                  \n}\n\n//we can also use an expression that evaluates a string concatenation in a case. The ability to have case expressions also allows you to do things like this:\n/*\nlet num = 25;\nswitch (true) {\n    case num < 0:\n        console.log(\"Less than 0.\");\n        break;\n    case num >= 0 && num <= 10:\n        console.log(\"Between 0 and 10.\");\n        break;\n    case num > 10 && num <= 20:\n        console.log(\"Between 10 and 20.\");\n        break;\n    default:\n        console.log(\"More than 20.\");\n} */\n\n// Extra dificulty: Create a program that prints the even numbers from 10 to 55 inclusive and avoids printing the numbers if they are equal to 16 or multiples of 3\n\nfor(let i = 10; i <= 55; i++ ){\n    if(i % 3 == 0 || i == 16) continue;\n    if(i % 2 == 0) log(i);\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/dumbnoxx.js",
    "content": "// Operaciones con los tipos de operadores\n\n// Operadores de asignacion\n\n//asignacion \nlet uno = 1; // uno = 1;\n// Asignacion de adiccion\nuno += 2; // uno = uno + 2;\n// Asignacion de sustraccion\nuno -= 3; // uno = uno - 3;\n// Asignacion de multiplicacion\nuno *= 4; // uno = uno * 4;\n// Asignacion de division\nuno /= 5; // uno = uno / 5;\n// Asignacion de residuo\nuno %= 6; // uno = uno % 6;\n// Asignacion de exponenciacion\nuno **= 7; // uno = uno ** 7;\n// Asignacion de desplazamiento hacia la izquierda\nuno <<= 8; // uno = uno << 8;\n// Asignacion de desplazamiento hacia la derecha\nuno >>= 9; // uno = uno >> 9;\n// Asignacion de desplazamiento hacia la derecha sin signo\nuno >>>= 10; // uno = uno >>> 10;\n// Asignacion de AND bit a bit\nuno &= 11; // uno = uno & 11;\n// Asignacion de XOR bit a bit\nuno ^= 12; // uno = uno ^ 12;\n// Asignacion de OR bit a bit\nuno |= 13; // uno = uno | 13;\n// Asignacion de AND logico\nuno &&= 14; // uno = uno && (uno = 14);\n// Asignacion de OR logico\nuno ||= 15; // uno = uno || (uno = 15);\n// Asignacion de anulacion logica\nuno ??= 16; // uno = uno ?? (uno = 16);\n\n// Operadores de Comparacion\n\nconst dos = 1;\n// Operador de igualdad\ndos == uno; // 1 == uno -> devuelve true si es true si son iguales (pueden ser 1 == \"1\" y aun asi devolver true);\n// Operador de desigualdad\ndos != uno; // 1 != uno -> Devuelve true si los operandos no son iguales (Tambien pueden ser 1 != '2' y aun asi devolver true);\n// Operador de igualdad estricta\ndos === uno; // Devuelve true si los operando son iguales y del mismo tipo.\n// Operador de desigualdad estricta\ndos !== uno; // Devuelve true si los operando son del mismo tipo pero no iguales, o si son de diferente tipo\n// Operador mayor que\ndos > uno; // Devuelve true si el operando izquierdo es mayor que el operado derecho, de lo contrario devuelve false\n// Operador menor que\ndos < uno; // Devuelve true si el operando derecho es mayor que el operando izquierdo, de lo contrario devuelve false\n// Operador mayor o igual que\ndos >= uno; // Devuelve true si el operando izquiero es mayor o igual que el operado derecho, de lo contrario devuelve false\n// Operador menor o igual que\ndos <= uno; // Devuelve true si el operando derecho es mayor o igual que el operando izquierdo, de lo contrario devuelve false\n\n// Operadores aritmeticos\n\nlet tres = 0;\n// Operador de adiccion\ntres + 1; // tres = 1\n// Operador de sutraccion\ntres - 2; // tres = -1\n// Operador de multiplicacion\ntres * 3; // tres = -3\n// Operador de division\ntres / 4; // tres = -0.75\n// Operador de modulo\ntres % 5; // tres = 4.25\n// Operador de incremento\ntres++; // tres = 5.25\n// Operador de decremento\ntres--; // tres = 4.25\n// Operador de negacion unitaria\n-tres; // Devuelve la negacion de su operando\n// Operador positivo unitario\n+tres; // Intenta convertir su operando en un numero si aun no lo es\n// Operador de exponenciacion\ntres ** dos; // Calcula la base a la potencia del exponente, es decir baseexponente\n/*\n  * Tener en cuenta que los operadores apartir de los de incremento y decremento se pueden\n  * Colocar en diferente posicion si quieres que se haga\n  * Ante o despues --tres, ++tres el decremento y el incremento se hara antes de cualquier operacion con el numero\n  * Ejemplo: tres = dos - ++uno -> tres = 1 - 2 : tres = dos + uno++ -> tres = 1 + 1, uno = 2\n*/\n\n// Operadores Bit a Bit\n// And a nivel de bit\nlet cuatro = tres & dos; // Devuelve un uno en cada posicion de bit para los que bits correspondientes de ambos operando son unos\n// OR a nivel de bit\ncuatro = tres | dos; // Devuelve un cero en cada posicion de bit para los cual los bits correspondientes  de ambos operando  son ceros\n// XOR a nivel de bit\ncuatro = tres ^ dos; // Devuelve un cero en cada posicion de bit para que los bits correspondientes son iguales, y uno cuando son diferentes\n// NOT a nivel de bit\ncuatro = ~tres; // Invierte los bits de su operando\n// Desplazamiento a la izquierda\ncuatro = tres << dos; // Desplaza 'tres' en representacion binaria 'dos' bits a la izquierda, desplazando en ceros desde la derecha\n// Desplazamiento a la derecha propagacion de signo\ncuatro = tres >> dos; // Desplaza 'tres' en representacion binaria 'dos' bits a la derecha, descatando los bits desplazados\n// Desplazamiento a la derecha de relleno cero\ncuatro = tres >>> dos; // Desplaza 'tres' en representacion binaria 'dos' bits a la derecha, descartado los los bits desplazados y desplazandose en ceros desde la izquierda\n\n// Operadores logicos\n\n// Operador AND\nlet cinco = tres > uno && tres > dos; // Devuelve true si las dos expresiones se cumplen\n// Operador OR\ncinco = tres > uno || dos > uno; // Devuelve true si una de las dos expresiones se cumple\n// Operador NOT\ncinco = !(tres > uno); // Devuelve el valor contrario al resultado de la expresion si tres > uno era true !(tres > uno) es false y viceversa\n\n// Operador ternario\nconst seis = cinco > cuatro ? \"Si es mayor\" : \"No es mayor\"; // Si la condicion es true, el operador devuelve el primer valor proporcionado despues del signo ? si es false devuelve el valor despues de :\n\n// Control de flujo\n\n// Condicionales\n\n// If - else\nconst siete = tres > dos;\nif (siete) {\n  console.log(siete);\n} else {\n  console.log(siete);\n}\n\n// Switch\nswitch (siete) {\n  case true:\n    console.log(siete);\n    break;\n  default:\n    console.log(siete);\n    break;\n}\n\n// Iterativas\n\n// for - for-in - for-of - for-each\nfor (let i = 0; i < 11; i++) {\n  console.log(i); // Imprime los numeros del 0 al 10, se pone que i < 11 porque la i comienza en 0;\n};\n\nconst ocho = [\"uno\", \"dos\", \"tres\"];\nfor (const element of ocho) {\n  console.log(element); // \"uno\", \"dos\", \"tres\"\n}\n\nconst nueve = {\n  a: \"uno\",\n  b: \"dos\",\n  c: \"tres\"\n}\nfor (const property in nueve) {\n  console.log(`${property} : ${nueve[property]}`); // \"a\": \"uno\", \"b\" : \"dos\", \"c\" : \"tres\"\n}\n\nconst diez = {\n  a: 1,\n  b: 2,\n  c: 3\n}\ndiez.forEach(number => console.log(number)); // 1, 2, 3\n\n\n// While - do-while\nlet condition = 1;\nwhile (condition < 10) {\n  console.log(condition);\n  condition++;\n  // Output 1, 2, 3, 4, 5, 6, 7, 8, 9\n}\n\ndo {\n  console.log(condition);\n  condition++;\n} while (condition < 5); // 1,2,3,4,5\n\n// Exception\n\n// Try-catch-finally\n\ntry {\n  console.log(\"No ha ocurrido errores\");\n} catch (err) {\n  console.log(\"Ha ocurrido un error: \", err);\n} finally {\n  console.log(\"Exception termined\");\n}\n\n\n// Retor extra\n// * Crea un programa que imprima por consola todos los números comprendidos\n// * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\nfor (let i = 10; i <= 55; i++) {\n  if (i % 2 === 0 && !(i % 3 === 0) && i !== 16) console.log(i);\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/edalmava.js",
    "content": "console.log('Operadores')\nconsole.log('')\n\n// Operadores matemáticos\n\nconst x = 5, y = 10\nconsole.log('Operadores Matemáticos')\nconsole.log(`Dado los valores x = ${x}, y = ${y}`)\nconsole.log(`La suma de ${x} + ${y} = ${x + y}`)\nconsole.log(`La resta de ${x} - ${y} = ${x - y}`)\nconsole.log(`La multiplicación de ${x} * ${y} = ${x * y}`)\nconsole.log(`La división de ${x} / ${y} = ${x / y}`)\nconsole.log(`El resto de la división entera entre ${x} % ${y} = ${x % y}`)\nconsole.log(`La exponenciación: ${y} ** ${x} = ${y ** x}`)\n\nconsole.log('Operador de Incremento y Decremento')\nlet z = 5, w = 6\nconsole.log(`Dado los  valores z = ${z} y w = ${w}`)\nz++, w--\nconsole.log(`z++ = ${z}`)\nconsole.log(`w-- = ${w}`)\n\nconsole.log('Operadores a nivel de bit')\nconst a = 5, b = 3\nconsole.log(`Dado los valores a = ${a} y b = ${b}`)\nconsole.log(`AND bit a bit: ${a} & ${b} = ${a & b}`)\nconsole.log(`OR bit a bit: ${a} | ${b} = ${a | b}`)\nconsole.log(`XOR bit a bit: ${a} ^ ${b} = ${a ^ b}`)\nconsole.log(`NOT bit a bit: ~${a} y ~-${b} = ${~a} y ${~-b}`)  // -(x + 1)\nconsole.log(`Left Shift: ${a} << ${b} = ${a << b}`)\nconsole.log(`Right Shift: ${a} >> ${2} = ${a >> 2}`)\nconsole.log(`Unsigned Right Shift: ${a} >>> ${2} = ${a >>> 2}`)\n\nconsole.log('Operador coma')\n/*\n  El operador coma nos permite evaluar varias expresiones, \n  separándolas con una coma ,. Cada expresión se evalúa, \n  pero sólo se devuelve el resultado de la última.\n*/\nlet c = (1 + 2, 3 + 4);\nconsole.log(c)   // 7 (el resultado de 3 + 4)\n\nconsole.log('Operadores de Comparación')\nconst d = 10, e = 15\nconsole.log(`Dado los valores d = ${d} y e = ${e}`)\nconsole.log(`Mayor que: ${d} > ${e} = ${d > e}`)\nconsole.log(`Menor que: ${d} < ${e} = ${d < e}`)\nconsole.log(`Igual que: ${d} == ${e} = ${d == e}`)\nconsole.log(`Distinto que: ${d} != ${e} = ${d != e}`)\nconsole.log(`Igualdad: 0 === false = ${0 == false}`)\nconsole.log(`Igualdad estricta: 0 === false = ${0 === false}`)\n\nconsole.log('Operador Ternario')\nconst age = 20\nconsole.log((age > 18) ? true : false)\n\nconsole.log('Operadores Lógicos')\nconsole.log(`OR: true || false = ${true || false}`)\nconsole.log(`OR: false || false = ${false || false}`)\nconsole.log(`AND: true && false = ${true && false}`)\nconsole.log(`AND: true && true = ${true && true}`)\nconsole.log(`NOT: !true = ${!true}`)\nconsole.log(`NOT: !false = ${!false}`)\n\nconsole.log(\"Operador Nullish Coalescing '??'\")\n/*\n  Una expresión es “definida” cuando no es null ni undefined.\n\n  El resultado de a ?? b:\n      si a está “definida”, será a,\n      si a no está “definida”, será b.\n*/\nlet user\nconsole.log(user ?? \"Anonymous\")\n\nconsole.log('')\nconsole.log('Bucles o ciclos')\nconsole.log('')\n\nconsole.log('Bucle while')\nlet i = 0\nwhile (i < 3) {\n    console.log(i)\n    i++\n}\n\nconsole.log('Bucle do..while')\n/*\n  Esta sintaxis solo debe ser usada cuando quieres que el \n  cuerpo del bucle sea ejecutado al menos una vez sin importar \n  que la condición sea verdadera. \n*/\ni = 0\ndo {\n    console.log(i)\n    i++\n} while (i < 3)\n\nconsole.log('Bucle for')\nfor (let i = 0; i < 3; i++) {\n    console.log(i)\n}\n\nconsole.log('Bucle for..in')\n/*\n  Para recorrer todas las claves de un objeto \n*/\nuser = {\n  name: \"John\",\n  age: 30,\n  isAdmin: true\n}\n\nfor (let key in user) {\n  // claves\n  console.log( key ) // name, age, isAdmin\n  // valores de las claves\n  console.log( user[key] ) // John, 30, true\n}\n// Recorrer todas las letras de una cadena\nlet cadena = \"Hola, JavaScript\"\nfor (let l in cadena) {\n    console.log(cadena[l])\n}\n\nconsole.log('Bucle for..of')\n/*\n  Para iterar sobre los elementos de un array\n*/\nlet fruits = [\"Apple\", \"Orange\", \"Plum\"]\n\n// itera sobre los elementos del array\nfor (let fruit of fruits) {\n  console.log( fruit )\n}\n// Recorrer todas las letras de una cadena\ncadena = \"Hola, JavaScript\"\nfor (let l of cadena) {\n    console.log(l)\n}\n\nconsole.log('')\nconsole.log('Sentencia switch')\nlet res = 2 + 2;\n\nswitch (res) {\n  case 3:\n    console.log( 'Muy pequeño' );\n    break;\n  case 4:\n    console.log( '¡Exacto!' );\n    break;\n  case 5:\n    console.log( 'Muy grande' );\n    break;\n  default:\n    console.log( \"Desconozco estos valores\" );\n}\n\nconsole.log('')\nconsole.log('RETO EXTRA')\nconsole.log('')\n\nArray.from({ length: 55 - 10 + 1 }\n           , (_, i) => 10 + i)\n    .filter(n => n % 2 === 0 && n !== 16 && n % 3 !== 0)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/edisplai.js",
    "content": "let num1 = 20;\nlet num2 = 12;\n\nconsole.log(num1 + num2);\nconsole.log(num1 - num2);\nconsole.log(num1 * num2);\nconsole.log(num1 / num2);\nconsole.log(num1 % num2);\nconsole.log(num1 > num2);\nconsole.log(num1 < num2);\nconsole.log(num1 === num2);\nconsole.log(num1 == num2);\nconsole.log(num1 !== num2);\nconsole.log(num1 != num2);\n\nif(num1 > num2){\n    console.log(\"si es mayor que num2\")\n}else if (num1 < num2){\n    console.log(\"es menor que num2\")\n}else {\n    console.log(\"son iguales\")\n}\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/elianisdev.js",
    "content": "//Ejemplos de tipos de operadores\n\n//Operadores aritméticos\n//Suma\nlet number1 = 10\nlet number2 = 5\nlet result = number1 + number2\nconsole.log(result)\n\n//Resta\nresult = number1 - number2\nconsole.log(result)\n\n//Multiplicación\nresult = number1 * number2\nconsole.log(result)\n\n//División\nresult = number1 / number2\nconsole.log(result)\n\n//Módulo\nresult = number1 % number2\nconsole.log(result)\n\n//Incremento\nnumber1++\nconsole.log(number1)\n\n//Decremento\nnumber2--\nconsole.log(number2)\n\n//Operadores de asignación\nlet number3 = 10\nlet number4 = 5\n\n//Asignación\nresult = number3\nconsole.log(result)\n\n//Suma y asignación\nresult += number4\nconsole.log(result)\n\n//Resta y asignación\nresult -= number4\nconsole.log(result)\n\n//Multiplicación y asignación\n\nresult *= number4\nconsole.log(result)\n\n//División y asignación\nresult /= number4\nconsole.log(result)\n\n//Módulo y asignación\nresult %= number4\nconsole.log(result)\n\n//Operadores de comparación\nlet number5 = 10\nlet number6 = 5\n\n//Igualdad\nresult = number5 === number6\nconsole.log(result)\n\n//Desigualdad\nresult = number5 !== number6\nconsole.log(result)\n\n//Estrictamente igual\nresult = number5 === number6\nconsole.log(result)\n\n//Estrictamente desigual\nresult = number5 !== number6\nconsole.log(result)\n\n//Mayor que\nresult = number5 > number6\nconsole.log(result)\n\n//Menor que\nresult = number5 < number6\nconsole.log(result)\n\n//Mayor o igual que\n\nresult = number5 >= number6\nconsole.log(result)\n\n//Menor o igual que\n\nresult = number5 <= number6\nconsole.log(result)\n\n//Operadores lógicos\nlet isTrue = true\nlet isFalse = false\n\n//AND\nresult = isTrue && isFalse\nconsole.log(result)\n\n//OR\nresult = isTrue || isFalse\nconsole.log(result)\n\n//NOT\nresult = !isTrue\nconsole.log(result)\n\n//Operadores de concatenación\nlet name = \"Mia\"\nlet lastName = \"Sanchez\"\n\n//Concatenación\nresult = name + \" \" + lastName\nconsole.log(result)\n\n//Concatenación y asignación\nresult += \" es mi nombre\"\nconsole.log(result)\n\n//Operadores de tipo\nlet number7 = 10\nlet string = \"10\"\n\n//Igualdad\nresult = number7 === string\nconsole.log(result)\n\n//Estrictamente igual\nresult = number7 === string\nconsole.log(result)\n\n//Operador ternario\nlet age = 18\nresult = age >= 18 ? \"Eres mayor de edad\" : \"Eres menor de edad\"\nconsole.log(result)\n\n//Estructuras de control\n//If\nlet number8 = 10\nif (number8 > 5) {\n    console.log(\"El número es mayor que 5\")\n}\n\n//If else\nif (number8 > 15) {\n    console.log(\"El número es mayor que 15\")\n}\n\nelse {\n    console.log(\"El número es menor que 15\")\n}\n\n//Else if\n\nif (number8 > 15) {\n    console.log(\"El número es mayor que 15\")\n}\n\n  else if (number8 < 15) {\n      console.log(\"El número es menor que 15\")\n  }\n\n  else {\n      console.log(\"El número es igual a 15\")\n  }\n\n  //Switch\n  let color = \"red\"\n\n  switch (color) {\n      case \"blue\":\n          console.log(\"El color es azul\")\n          break\n      case \"red\":\n          console.log(\"El color es rojo\")\n          break\n      case \"green\":\n          console.log(\"El color es verde\")\n          break\n      default:\n          console.log(\"El color no es azul, rojo o verde\")\n  }\n\n  //While\n  let number9 = 0\n  while (number9 < 5) {\n      console.log(number9)\n      number9++\n  }\n\n  //Do while\n  let number10 = 0\n  do {\n      console.log(number10)\n      number10++\n  } while (number10 < 5)\n\n  //For\n  for (let i = 0; i < 5; i++) {\n      console.log(i)\n  }\n\n  //For in\n  let colors = [\"red\", \"blue\", \"green\"]\n  for (let index in colors) {\n      console.log(colors[index])\n  }\n\n  //For of\n  for (let color of colors) {\n      console.log(color)\n  }\n\n  //Break\n  for (let i = 0; i < 5; i++) {\n      if (i === 3) {\n          break\n      }\n      console.log(i)\n  }\n\n  //Continue\n\n  for (let i = 0; i < 5; i++) {\n      if (i === 3) {\n          continue\n      }\n      console.log(i)\n\n  }\n\n  //Funciones\n  function myFunction() {\n      console.log(\"¡Hola, JavaScript!\")\n  }\n  myFunction()\n\n  //Funciones con parámetros\n  function myFunction2(name) {\n      console.log(`¡Hola, ${name}!`)\n  }\n  myFunction2(\"JavaScript\")\n\n//Crea un programa que imprima por consola todos los números comprendidos\n//  * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\nfor (let i = 10; i <= 55; i++) {\n    if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n        console.log(i)\n    }\n\n}\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/emaenriquez.js",
    "content": "\n\n// OPERADORES ARITMÉTICOS\n\nconsole.log(3 + 4);     // Suma -> 7\nconsole.log(3 - 4);     // Resta -> -1\nconsole.log(3 / 4);     // División -> 0.75\nconsole.log(3 * 4);     // Multiplicación -> 12\nconsole.log(3 % 4);     // Módulo -> 3\nconsole.log(3 ** 4);    // Potencia -> 81\n\n\n// OPERADORES LÓGICOS\n\nconsole.log(true && false);     // AND -> false\nconsole.log(true || false);     // OR -> true\nconsole.log(!true);             // NOT -> false\n\n\n// OPERADORES DE COMPARACIÓN\n\nconsole.log(3 > 4);     // Mayor que -> false\nconsole.log(3 < 4);     // Menor que -> true\nconsole.log(3 >= 4);    // Mayor o igual que -> false\nconsole.log(3 <= 4);    // Menor o igual que -> true\n\nconsole.log(3 == '3');  // Igual que -> true\nconsole.log(3 != '3');  // Diferente a -> false\nconsole.log(3 == 4);    // false\nconsole.log(3 != 4);    // true\n\nconsole.log(3 === '3'); // Igual que (estricta) -> false\nconsole.log(3 !== '3'); // Diferente a (estricta) -> true\n\n\n// OPERADORES DE ASIGNACIÓN\n\n// OPERADORES DE ASIGNACIÓN\n\nlet asignarSuma = 7;\nasignarSuma += 3;                     // Suma y asignación\nconsole.log(asignarSuma);             // 10\n\nlet asignarResta = 7;\nasignarResta -= 4;                // Resta y asignación\nconsole.log(asignarResta);        // 3\n\nlet asignarMultiplicacion = 7;\nasignarMultiplicacion *= 2;          // Multiplicación y asignación\nconsole.log(asignarMultiplicacion);  // 14\n\nlet asignarDivision = 7;\nasignarDivision /= 2;                // División y asignación\nconsole.log(asignarDivision);        // 3.5\n\nlet asignarModulo = 7;\nasignarModulo %= 2;                  // Módulo y asignación\nconsole.log(asignarModulo);          // 1\n\nlet asignarPotencia = 7;\nasignarPotencia **= 2;                    // Potencia y asignación\nconsole.log(asignarPotencia);             // 49\n\n\n// OPERADORES DE PERTENENCIA\n\nlet arreglo = [0, 1, 2, 3, 4];\nconsole.log(3 in arreglo);      // true\nconsole.log(11 in arreglo);     // false\n\n// OPERADORES DE BITS\n\nconsole.log(3 & 4);         // AND -> 0\nconsole.log(3 | 4);         // OR -> 7\nconsole.log(3 ^ 4);         // XOR -> 7\nconsole.log(~3);            // NOT -> -4\nconsole.log(3 << 4);        // Desplazamiento a izquierda -> 48\nconsole.log(3 >> 4);        // Desplazamiento a derecha -> 0\n\n\n// ESTRUCTURA DE CONTROL: if - else if - else\n\nlet puntuacion = 8;\n\nif (puntuacion >= 5) {\n    console.log('Has aprobado el examen!');\n} else if (puntuacion < 5) {\n    console.log('No has aprobado el examen...');\n} else {\n    console.log('Las puntuaciones aún no están disponibles.');\n}\n\n\n// ESTRUCTURA DE CONTROL: switch\n\nlet mes = 1;\nlet nombreMes = '';\n\nswitch (mes) {\n    case 1:\n        nombreMes = 'Enero';\n        break;\n    case 2:\n        nombreMes = 'Febrero';\n        break;\n    case 3:\n        nombreMes = 'Marzo';\n        break;\n    case 4:\n        nombreMes = 'Abril';\n        break;\n    case 5:\n        nombreMes = 'Mayo';\n        break;\n    case 6:\n        nombreMes = 'Junio';\n        break;\n    case 7:\n        nombreMes = 'Julio';\n        break;\n    case 8:\n        nombreMes = 'Agosto';\n        break;\n    case 9:\n        nombreMes = 'Septiembre';\n        break;\n    case 10:\n        nombreMes = 'Octubre';\n        break;\n    case 11:\n        nombreMes = 'Noviembre';\n        break;\n    case 12:\n        nombreMes = 'Diciembre';\n        break;\n    default:\n        nombreMes = 'Número de mes no válido';\n}\nconsole.log(`Mes: ${nombreMes}`);    // Mes: Enero\n\n\n// ESTRUCTURA DE CONTROL: for\n\nfor (let i = 0; i < 5; i++) {\n    console.log(i);\n}\n/* Se imprimen los siguientes números:\n    0, 1, 2, 3, 4\n*/\n\n\n// ESTRUCTURA DE CONTROL: for-in\n\nconst person = {\n    name: 'Naia',\n    username: 'nlarrea',\n    age: 25\n};\n\nfor (let key in person) {\n    // Se imprimen las claves:\n    console.log(key);\n\n    // Si quisiéramos imprimir los valores:\n    // console.log(person[key]);\n}\n/* Se imprimen los siguientes strings:\n    name, username, age\n*/\n\n\n// ESTRUCTURA DE CONTROL: for-of\n\nconst numArr = ['hola', true, 7, ['a', 'b', 'c']]\n\nfor (let item of numArr) {\n    console.log(item);\n}\n/* Se imprime:\n    'hola'\n    true\n    7\n    [ 'a', 'b', 'c' ]\n*/\n\n\n// ESTRUCTURA DE CONTROL: while\n\nlet i = 0;\nwhile (i < 5) {\n    console.log(i);\n    i++;\n}\n/* Se imprimen los siguientes números:\n    0\n    1\n    2\n    3\n    4\n*/\n\n\n// ESTRUCTURA DE CONTROL: do-while\n\nlet j = 'Not empty';\ndo {\n    console.log(j);\n} while (j === '');\n\n/* Se imprime el mensaje 'Not empty' 1 vez aunque no se cumpla la condición del\nwhile, porque siempre se va a ejecutar aunque sea una vez.\n\nCUIDADO: si la condición del while se cumpliera, sería un bucle infinito\n*/\n\n\n// ESTRUCTURA DE CONTROL: try-catch\n\ntry {\n    throw new Error('This is an error');\n    console.log('This is not printed');\n} catch (error) {\n    console.log(error);                     // [Error: This is an error]\n}\n\n\n// ESTRUCTURA DE CONTROL: try-catch-finally\ntry {\n    throw new Error('This is an error');\n    console.log('This is not printed');\n} catch (error) {\n    console.log(error);                     // [Error: This is an error]\n} finally {\n    console.log('This is always printed');  // This is always printed\n}\n\n\n// EJERCICIO EXTRA\n\n/* DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n */\n\nfor (let num = 10; num <= 55; num++) {\n    if (\n        num % 2 === 0 &&\n        num !== 16 &&\n        num % 3 !== 0\n    ) {\n        console.log(num);\n    }\n}\n/* Se imprimen los siguientes números:\n    10 \n    14 \n    20 \n    22 \n    26 \n    28 \n    32 \n    34 \n    38 \n    40 \n    44 \n    46 \n    50 \n    52\n*/"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/emedevelopa.js",
    "content": "// OPERADORES ARITMÉTICOS:\n\nlet a = 5;\nlet b = 3;\n\nconsole.log (a + b); //Suma\nconsole.log (a - b); //Resta\nconsole.log (a * b); //Multiplicación\nconsole.log (a / b); //División\nconsole.log (a % b); //Módulo\nconsole.log (a ** b); //Potencia\n\nconsole.log (++a); //Incremento\nconsole.log (--a); //Decremento\n\n//OPERADORES DE ASIGNACIÓN:\na += 2; //Igual que a = a + 2;\na -= 2;\na *= 2;\na /= 2;\na %= 2;\na **= 2;\n\n//OPERADORES DE COMPARACIÓN:\na > 2;\na < 2;\na >= 2;\na <= 2;\n\na == 5; //True. Evalúa el valor\na != 5; //False\na === 5; // Evalúa valor y tipo de dato.\na !== 5; // False\n\n//OPERADORES LÓGICOS:\nlet c = true;\nlet d = false;\nlet e = true;\nlet f = false;\n\n    //AND &&\nconsole.log(c && e);// Ambos son true, devuelve true.\nconsole.log(c && d); //Devuelve false.\n\n    //OR ||\nconsole.log (c || d); //Devuelve true por que al menos un valor es true.\nconsole.log (d || f); //Devuelve false porque ambos valores son false.\n\n    //NOT !\nconsole.log (c, !d); //Devuelve true por que c no es igual a d.\n\n\n//OPERADOR TERNARIO\n//expresión ? \"si es true\" : \"si es false\";\nlet edad = 16;\nlet acceso = edad > 17 ? \"Permitir acceso\" : \"Denegar acceso\";\nconsole.log(acceso);\n\n\n//ESTRUCTURAS DE CONTROL\n\n//If\nif (edad >= 16) {\n    console.log(\"Mayor de 16\");\n}\n\n//If Else\nif (edad < 17) {\n    console.log(\"Menor de 17\")\n} else {\n    console.log(\"Mayor de 17\")\n}\n\n//While\nlet i = 0;\nwhile (i < 10) {\n    console.log(i);\n    i++\n}\n\n//Do While\ndo {\n    console.log(i);\n    i++;\n} while(i < 3); \n\n//For\nfor (let i = 0; i < 3; i++) {\n    console.log(i);\n}\n\n//For of\nlet nameList = [\"Marea\", \"León\", \"Roberto\"];\nfor (let name of nameList) {\n    console.log(name);\n}\n\n//For in\nlet user = {\n    name: \"Marea\",\n    age: 9,\n    color: \"blue\",\n};\n\nfor (let prop in user) {\n    console.log(user[\"color\"]);\n    \n}\n\n// Switch\nlet nota = 8;\nswitch(nota) {\n    case 10:\n        calificacion = \"Sobresaliente\";\n        break;\n    case 9:\n    case 8:\n        calificacion = \"Notable\";\n        break;\n    case 7:\n    case 6:\n        calificacion = \"Bien\";\n        break;\n    case 5:\n        calificacion = \"Suficiente\";\n        break;\n    case 4:\n    case 3:\n    case 2:\n    case 1:\n    case 0:\n        calificacion = \"Suspenso\";\n        break;\n    default:\n        calificacion = \"Nota errónea\";\n        break;\n}\n\nconsole.log(\"He sacado un \" + calificacion);\n\n//Ejercicio Extra \n\nfor (let i = 10; i <= 55; i++) {\n    if (i % 2 == 0 && i != 16 && i % 3 !== 0);\n    console.log(i);\n} "
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/eonOzux.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\nlet x = 0\nlet y = 0\n/* Asignación */\t\n    x = y\n    x = y \n\n/* Asignación de adición */\t\n    x += y\n    x = x + y\n\n/* Asignación de resta */\n\tx -= y\n\tx = x - y\n\n/* Asignación de multiplicación */\n\tx *= y\n\tx = x * y\n\n/* Asignación de división */\t\n    x /= y\t\n    x = x / y\n\n/* Asignación de residuo */\n    x %= y\t\n    x = x % y\n\n/* Asignación de exponenciación */\n    x **= y\n    x = x ** y\n\n/* Asignación de desplazamiento a la izquierda */\n    x <<= y\t\n    x = x << y\n\n/* Asignación de desplazamiento a la derecha */\n    x >>= y\t\n    x = x >> y\n\n/* Asignación de desplazamiento a la derecha sin signo */\n\tx >>>= y\t\n    x = x >>> y\n\n/* Asignación AND bit a bit */\n\tx &= y\t\n    x = x & y\n\n/* Asignación XOR bit a bit */\n\tx ^= y\t\n    x = x ^ y\n\n/* Asignación OR bit a bit */\n\tx |= y\t\n    x = x | y\n\n/* Asignación AND lógico */\n\tx &&= y\t\n    x && (x = y)\n    \n/* Asignación OR lógico */\n\tx ||= y\t\n    x || (x = y)\n\n/* Asignación de anulación lógica */\t\n    x ??= y\t\n    x ?? (x = y);\n\nconsole.log (\"Probando consola con NodeJs\")\n\n\n// * DIFICULTAD EXTRA (opcional):\n//* Crea un programa que imprima por consola todos los números comprendidos\n//* entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n//*\n//* Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\n\nfor (let a = 10; a <= 55 ;a ++){\n// Evaluar si el valor de a es un numero par\nif (a % 2 === 0){\n    console.log(a + \"par\")\n    //Evaluar si el valor es igual a 16 o multiplo de 3\n    if (a === 16 && a % 3 !== 0) {\n    // Mostrar el valor en la consola. \n    console.log(a + \"**\")\n    }\n}\nconsole.log(a);\n} ;"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/erikayeah.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n// Operadores\nlet a = 10;\nlet b = 5;\nlet c = 15;\nlet d = 3;\n\n// Aritméticos\nconsole.log(a + b);\nconsole.log(a - b);\nconsole.log(a * b);\nconsole.log(a / b);\nconsole.log(a % b);\nconsole.log(a ** b);\n\n// Lógicos\nconsole.log(a && b);\nconsole.log(a || b);\nconsole.log(!a);\n\n// De comparación\nconsole.log(a === b);\nconsole.log(a !== b);\nconsole.log(a < b);\nconsole.log(a > b);\nconsole.log(a <= b);\nconsole.log(a >= b);\n\n// De asignación\nconsole.log((a += b));\nconsole.log((a -= b));\nconsole.log((a *= b));\nconsole.log((a /= b));\nconsole.log((a %= b));\nconsole.log((a **= b));\n\n// De identidad\nconsole.log(a === b);\nconsole.log(a !== b);\n\n// De pertenencia\nlet arr = [1, 2, 3, 4, 5];\nconsole.log(1 in arr);\nconsole.log(6 in arr);\n\n// Bits\nconsole.log(a & b);\nconsole.log(a | b);\nconsole.log(a ^ b);\nconsole.log(~a);\nconsole.log(a << b);\nconsole.log(a >> b);\nconsole.log(a >>> b);\n\n// Estructuras de control\n\n// Condicionales\nlet x = 10;\nlet y = 5;\n\nif (x > y) {\n  console.log(\"x es mayor que y\");\n} else {\n  console.log(\"x es menor que y\");\n}\n\n// Iterativas\nlet i = 0;\nwhile (i < 5) {\n  console.log(i);\n  i++;\n}\n\n// Excepciones\ntry {\n  throw \"Error\";\n} catch (error) {\n  console.log(error);\n}\n\n// Programa extra\n\nlet program = () => {\n  for (let i = 10; i <= 55; i++) {\n    if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n      console.log(i);\n    }\n  }\n};\n\nprogram();\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/esdras-josue.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n// operadores\nlet numeroUno = 10;\nlet  numeroDos = 25;\nlet suma =  `Resultado Suma: ${numeroUno + numeroDos}`;\nconsole.log(suma); \n\nconsole.log();\n\nlet restarNumero = 25;\nlet restarnumeroDos = 21;\nlet resultadoResta = `Resultado resta: ${restarNumero - restarnumeroDos}`;\nconsole.log(resultadoResta);\n\nconsole.log();\n\nlet multiplicarNumero = 5;\nlet multiplcarNumeroDos = 10;\nlet resultadoMultiplicacion = `Resultado Multiplicacion: ${multiplicarNumero * multiplcarNumeroDos}`;\nconsole.log(resultadoMultiplicacion);\n\nconsole.log();\n\nlet dividirNumero = 5;\nlet dividirNumeroDos = 10;\nlet resultadodivicion = `Resultado Division: ${dividirNumero / dividirNumeroDos}`;\nconsole.log(resultadodivicion);\n\nconsole.log();\n\nlet moduloUno = 20;\nlet moduloDs = 10;\nlet resultadoModulo = `Resultado Modulo: ${moduloUno % moduloDs}`;\nconsole.log(resultadoModulo);\n\nconsole.log();\nconsole.log(`Exponente 10**3: ${10**3}`)\n\n// Operadores de comparacion\nconsole.log();\nconsole.log(`Igualdad: 10 es igual a 2 ${20===2}`);\nconsole.log(`Desigualdad: 10 es distinto de 5 ${10 != 5}`);\nconsole.log(`Mayor: 20 mayor a 10 ${20 > 10}`);\nconsole.log(`Menor: 25 menor a 21 ${25 < 21}`);\nconsole.log(`Mayor o igual: 25 mayor o igual a 21: ${25 >=21}`);\nconsole.log(`Menor o igual: 25 menor o igual a 21: ${25 >= 21}`);\n\n// Operadores logicos\nconsole.log();\nconsole.log(`AND &&: 10 + 10 == 20 and 5 + 5 == 10 es: ${10 + 10 == 20 && 5 + 5 == 10}`); // ambos condiciones deben ser verdadera para que sea true\nconsole.log(`or ||: 10 + 10 || 20 and 5 + 5 == 10 es: ${10 + 10 == 22 || 5 + 5 == 11}`); // por lo menos una condicion debe ser verdadera para que sea true\nconsole.log(`NOT !: not 10 + 10 == 20 es: ${!10 + 10 == 20}`); // negacion\n\n// operadores de asignacion\nconsole.log();\nlet number = 14; // asiganacion\nconsole.log(`Asignacion: ${number}`);\n\nnumber +=5; // suma y asignacion\nconsole.log(`suma y asigancion: ${number}`);\n\nnumber -= 2; // resta y asignacion\nconsole.log(`Resta y asigancion: ${number}`);\n\nnumber *= 5; // multiplicacion y asignacion\nconsole.log(`Multiplicacion y asignacion: ${number}`);\n\nnumber %= 6; // modulo y asignacion\nconsole.log(`Modulo y asignacion: ${number}`);\n\nnumber /= 2; //Division y asignacion\nconsole.log(`Division y asignacion: ${number}`); \n\n/*\nestructuras de control\n*/\n\n// condicionales \nlet edad = 10;\nif(edad >= 18)\n    console.log(\"puede votar\");\nelse{\n    console.log(\"No puede votar\");\n}\n\nvar myName = \"Esdras\";\nif(myName == \"Esdras\"){\n    console.log(`Hola mi nombre es ${myName}`);\n}\nelse{\n    console,log(`Mi nombre no es ${myName}`);\n}\n\n// Iterativas\n\nfor(let i = 10; i<=55; i++){\n    if(i % 2 == 0 && i % 3 != 0 && i !=16){\n        console.log(i)\n    }\n}\n\n// manejos de errores\ntry{\n    let resultado = 10/0;\n    if(!isFinite(resultado)){\n\n        throw new Error(\"no se puede dividir por cero\")\n    }\n    console.log(resultado);\n\n} catch(error){\n    console.error(\"Ocurrio un error \" + error.message);\n}\n\n\n\n\n \n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/eugeniasoria.js",
    "content": "/*\r\n * EJERCICIO:\r\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\r\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\r\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\r\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\r\n *   que representen todos los tipos de estructuras de control que existan\r\n *   en tu lenguaje:\r\n *   Condicionales, iterativas, excepciones...\r\n * - Debes hacer print por consola del resultado de todos los ejemplos.\r\n *\r\n * DIFICULTAD EXTRA (opcional):\r\n * Crea un programa que imprima por consola todos los números comprendidos\r\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\r\n *\r\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\r\n */\r\n\r\n//Ejemplos utilizando todos los tipos de operadores del lenguaje\r\n// Assignment operators\r\nlet variable = 5;\r\nconsole.log(\">>>Operadores de Asignación\");\r\nconsole.log(\"Assignment 'variable = 5' =>\", variable);\r\nconsole.log(\"Addition Assignment 'variable += 3' =>\", (variable += 3));\r\nconsole.log(\"Subtraction Assignment 'variable -= 1' =>\", (variable -= 1));\r\nconsole.log(\"Multiplication Assignment 'variable *= 2' =>\", (variable *= 2));\r\nconsole.log(\"Division Assignment 'variable /= 2' =>\", (variable /= 2));\r\nconsole.log(\"Remainder Assignment 'variable %= 4' =>\", (variable %= 4));\r\nconsole.log(\"Exponentiation Assignment 'variable **= 3' =>\", (variable **= 3));\r\nconsole.log(\"Left Shift Assignment 'variable <<= 2' =>\", (variable <<= 2));\r\nconsole.log(\"Right Shift Assignment 'variable >>= 2' =>\", (variable >>= 2));\r\nconsole.log(\"Unsigned Right Shift Assignment 'variable >>>= 2' =>\", (variable >>>= 2));\r\nconsole.log(\"Bitwise AND assignment 'variable &= 3' =>\", (variable &= 3));\r\nconsole.log(\"Bitwise XOR assignment 'variable ^= 5' =>\", (variable ^= 5));\r\nconsole.log(\"Logical AND assignment  'variable &&= 1' =>\", (variable &&= 1));\r\nconsole.log(\"Logical OR assignment  'variable ||= 0' =>\", (variable ||= 0));\r\nconsole.log(\"Nullish coalescing assignment  'variable ??= 0' =>\", (variable ??= 15));\r\nconsole.log(\"\\n\")\r\nconsole.log(\">>>Operadores de Comparación\");\r\nconsole.log(\"Equal '1 == 2' => \", 1 == 2);\r\nconsole.log(\"Not equal '1 != 2' => \", 1 != 2);\r\nconsole.log(`Strict equal '1 === \\\"2\\\"' => `, 1 === \"2\");\r\nconsole.log(`Strict not equal '1 !== \\\"2\\\"' => `, 1 === \"2\");\r\nconsole.log(\"Greater than '1 > 2' => \", 1 > 2);\r\nconsole.log(\"Less than '1 < 2' => \", 1 < 2);\r\nconsole.log(\"Greater than or equal '1 >= 2' => \", 1 >= 2);\r\nconsole.log(\"Less than or equal '1 <= 2' => \", 1 <= 2);\r\n\r\nlet x=10;\r\nconsole.log(\"\\n\")\r\nconsole.log(\">>>Operadores Aritméticos\");\r\nconsole.log(\"Remainder 'x=10; x % 3' =>\", (x % 3));\r\nx=10; x++;\r\nconsole.log(\"Increment 'x=10; x++' =>\", (x));\r\nx=10; x--;\r\nconsole.log(\"Decrement 'x=10; x--' =>\", (x));\r\nx=10;\r\nconsole.log(\"Unary negation 'x=10; -x' =>\", (-x));\r\nx=\"10\"\r\nconsole.log(\"Unary plus 'x=\\\"10\\\"; +x' =>\", (+x));\r\nconsole.log(\"Exponentiation operator 'x=10; x**2' =>\", (x**2));\r\n\r\nconsole.log(\"\\n\")\r\nconsole.log(\">>>Operadores Bitwise\");\r\nlet a = 5;\r\nlet b = 3; \r\nconsole.log(\"a = 5 => 00000000000000000000000000000101\");\r\nconsole.log(\"b = 3 => 00000000000000000000000000000011\");\r\nconsole.log(\"Bitwise AND 'a & b' => 00000000000000000000000000000001 =>\", a & b);\r\nconsole.log(\"Bitwise OR 'a | b' => 00000000000000000000000000000111 =>\", a | b);\r\nconsole.log(\"Bitwise XOR 'a ^ b' => 00000000000000000000000000000110 =>\", a ^ b);\r\nconsole.log(\"Left shift 'a << b' => 00000000000000000000000000101000 =>\", a << b);\r\nb = 2;\r\nlet c = -5;\r\nconsole.log(\"a = 5 => 00000000000000000000000000000101\");\r\nconsole.log(\"b = 2 => 00000000000000000000000000000010\");\r\nconsole.log(\"c = -5 => 11111111111111111111111111111011\");\r\nconsole.log(\"Right shift 'a >> b' => 00000000000000000000000000000001 =>\", a >> b);\r\nconsole.log(\"Right shift 'c >> b' => 00000000000000000000000000000000 =>\", c >> b);\r\nconsole.log(\"Unsigned Right shift 'a >> b' => 00000000000000000000000000000001 =>\", a >>> b);\r\nconsole.log(\"Unsigned Right shift 'c >> b' => 00111111111111111111111111111110 =>\", c >>> b);\r\n\r\nconsole.log(\"\\n\")\r\nconsole.log(\">>>Operadores Bitwise Lógicos\");\r\na = 15;\r\nb = 9;\r\nconsole.log(\"a = 15 => 00000000000000000000000000001111\");\r\nconsole.log(\"b = 9 => 00000000000000000000000000001001\");\r\nconsole.log(\"a & b => 1001\", a & b);\r\nconsole.log(\"a | b => 1111\", a | b);\r\nconsole.log(\"a ^ b => 0110\", a ^ b);\r\nconsole.log(\"~a => 11111111111111111111111111110000\", ~a);\r\nconsole.log(\"~b => 11111111111111111111111111110110\", ~b);\r\n\r\nconsole.log(\"\\n\")\r\nconsole.log(\">>>Operadores Lógicos\");\r\nconst exprTrue = true;\r\nconst exprFalse = false;\r\nconsole.log(\"Logical AND\");\r\nconsole.log(\"exprTrue && exprTrue => \", exprTrue && exprTrue);\r\nconsole.log(\"exprTrue && exprFalse => \", exprTrue && exprFalse);\r\nconsole.log(\"exprFalse && exprFalse => \", exprFalse && exprFalse);\r\nconsole.log(\"Logical OR\");\r\nconsole.log(\"exprTrue || exprTrue => \", exprTrue || exprTrue);\r\nconsole.log(\"exprTrue || exprFalse => \", exprTrue || exprFalse);\r\nconsole.log(\"exprFalse || exprFalse => \", exprFalse || exprFalse);\r\nconsole.log(\"Logical NOT\");\r\nconsole.log(\"!exprTrue => \", !exprTrue);\r\nconsole.log(\"!exprFalse => \", !exprFalse);\r\n\r\nconsole.log(\"\\n\")\r\nconsole.log(\">>>Operadores BigInt\");\r\nconsole.log(\"Son los mismos que para Number, pero no se puede mezclar números de distinto tipo. Ambos deben ser BigInt\")\r\nconst aBigInt = BigInt(123654789321456);\r\nconst bBigInt = 999999999999999n;\r\nconsole.log(\"Operador + (por citar un ejemplo)\");\r\nconsole.log(\"aBigInt = BigInt(123654789321456)\");\r\nconsole.log(\"bBigInt = 999999999999999n\"); \r\nconsole.log(\"aBigInt + bBigInt => \", aBigInt + bBigInt );\r\n\r\nconsole.log(\"\\n\")\r\nconsole.log(\">>>Operadores String\");\r\nconst aString = 'Carpe';\r\nconst bString = 'Diem';\r\nconsole.log(\"aString = 'Carpe';\")\r\nconsole.log(\"bString = 'Diem'\")\r\nconsole.log(\"Operador +\");\r\nconsole.log(\"'aString + bString' =>\", aString + bString);\r\n\r\nconsole.log(\"\\n\")\r\nconsole.log(\">>>Operadores Condicional Ternario\");\r\nconst edad = 100;\r\nconsole.log(\"condicion ? val1 : val2\");\r\nconsole.log(\"edad = 100 => \", edad > 100 ? 'en serio?' : 'todavia joven :)');\r\n\r\nconsole.log(\"\\n\")\r\nconsole.log(\">>>Operador Coma\");\r\nconsole.log(\"for (let a = 0, b =5; a <= 5; a++, b--) { \"+\r\n            \"\\n    console.log(a, b); '\"+\r\n            \"\\n}\")\r\n\r\nfor (let a = 0, b =5; a <= 5; a++, b--) { \r\n  console.log(a, b); \r\n}\r\n\r\nconsole.log(\"\\n\");\r\nconsole.log(\">>>Operadores Unarios\");\r\nconsole.log(\"Operador delete\")\r\nconst developer = {\r\n  name: 'Luna',\r\n  apellido: 'Margarita'\r\n};\r\nconsole.log(\"const developer = { name: 'Luna', apellido: 'Margarita' }; => \", developer);\r\ndelete developer.name;\r\nconsole.log(\"delete developer.name => \", developer);\r\n\r\n\r\nconsole.log('\\nOperador typeof')\r\nconst unaFuncion = new Function(2 + 5);\r\nconst unaString = \"palabra\";\r\nconst unNumero = 159;\r\nconst unArray = [4, 8, 15, 16, 23, 42, 108];\r\nconst unaFecha = new Date();\r\n\r\nconsole.log(\"const unaFuncion = new Function(2 + 5);\");\r\nconsole.log('const unaString = \"palabra\";');\r\nconsole.log(\"const unNumero = 159;\");\r\nconsole.log(\"const unArray = [4, 8, 15, 16, 23, 42, 108];\");\r\nconsole.log(\"const unaFecha = new Date();\");\r\n\r\nconsole.log(\"typeof unaFuncion => \", typeof unaFuncion);\r\nconsole.log(\"typeof unaString => \", typeof(unaString));\r\nconsole.log(\"typeof unNumero => \", typeof(unNumero));\r\nconsole.log(\"typeof unArray => \", typeof(unArray));\r\nconsole.log(\"typeof unaFecha => \", typeof(unaFecha));\r\n\r\nconsole.log(\"\\nOperador void\")\r\nconsole.log(\"void (4 ===\\\"4\\\") => \", void (4 ===\"4\"));\r\n\r\nconsole.log(\"\\n\");\r\nconsole.log(\">>>Operadores Relacionales\");\r\nconsole.log('\\nOperador in');\r\nconst perritos = ['Ash', 'Luna', 'Alma', 'Dana', 'Sami', 'Camila', 'Priscila'];\r\nconsole.log('perritos = ', perritos);\r\nconsole.log(\"'Firulais' in perritos => \", 'Firulais' in perritos);\r\nconsole.log(\"'Ash' in perritos => \", 'Ash' in perritos);\r\nconsole.log(\"4 in perritos => \", 4 in perritos);\r\n\r\nconsole.log('\\nOperador instanceof')\r\nconst dia = new Date();\r\nconsole.log(\"dia = new Date();\");\r\nconsole.log(\"dia instanceof Date => \", dia instanceof Date);\r\nconsole.log(\"dia instanceof BigInt => \", dia instanceof BigInt);\r\n\r\n\r\nconsole.log(\"\\n-----------------------------------------------\")\r\nconsole.log(\">>>Estructuras de Control\");\r\n\r\nconsole.log('Loops and Iteration');\r\nconsole.log(\"\\nfor statement\");\r\nconsole.log('for (let i=5; i>0; i--){'+\r\n'\\n    console.log(\\\"Cuenta regresiva: \\\", i);'+\r\n'\\n}');\r\nfor (let i=5; i>0; i--){\r\n  console.log(\"Cuenta regresiva: \", i);\r\n}\r\n\r\nconsole.log(\"\\ndo...while statement\");\r\nconsole.log('let i = 0;'+\r\n'\\nlet valorMaximo = 10;'+\r\n'\\ndo {'+\r\n'\\n    console.log(`Valor de i: ${i});'+\r\n'\\n    i++;'+\r\n'\\n} while (i <= valorMaximo);');\r\nlet i = 0;\r\nlet valorMaximo = 10;\r\ndo {\r\n  console.log(`Valor de i: ${i}, <= ${valorMaximo}`);\r\n  i++;\r\n} while (i <= valorMaximo);\r\n\r\nconsole.log(\"\\nwhile statement\");\r\nconsole.log('i = 0;' + \r\n'\\nwhile (i <= valorMaximo) {' +\r\n'\\n  console.log(`Valor de i: ${i}, <= ${valorMaximo}`);' +\r\n'\\n  i++;' +\r\n'\\n}');\r\ni = 0;\r\nwhile (i <= valorMaximo) {\r\n  console.log(`Valor de i: ${i}, <= ${valorMaximo}`);\r\n  i++;\r\n}\r\n\r\nconsole.log(\"\\nlabeled statement\");\r\n\r\nconsole.log('let sum = 0, a = 1;' + \r\n'\\n// Label for outer loop' +\r\n'\\nouterloop: while (true) {' + \r\n'\\n    a = 1;' + \r\n'\\n ' + \r\n'\\n    // Label for inner loop' + \r\n'\\n    innerloop: while (a < 3) {' + \r\n'\\n        sum += a;' + \r\n'\\n        if (sum > 12) {' + \r\n'\\n ' + \r\n'\\n            // Break outer loop from inner loop' + \r\n'\\n            break outerloop;' + \r\n'\\n        }' + \r\n'\\n        console.log(\"sum = \" + sum);' + \r\n'\\n        a++;' + \r\n'\\n    }' + \r\n'\\n}');\r\nlet sum = 0, aLabel = 1;\r\n// Label for outer loop\r\nouterloop: while (true) {\r\n  aLabel = 1;\r\n \r\n    // Label for inner loop\r\n    innerloop: while (aLabel < 3) {\r\n        sum += aLabel;\r\n        if (sum > 12) {\r\n \r\n            // Break outer loop from inner loop\r\n            break outerloop;\r\n        }\r\n        console.log(\"sum = \" + sum);\r\n        aLabel++;\r\n    }\r\n}\r\n\r\nconsole.log(\"\\nbreak statement\");\r\nconsole.log('for (let i = 0; i < 10; i++) {'+\r\n'\\n    console.log(\"foor loop de 1 a 10, valor: \", i);'+\r\n'\\nif (i === 3) {'+\r\n'\\n    console.log(\"break\");'+\r\n'\\n    break;'+\r\n'\\n}');\r\nfor (let i = 0; i < 10; i++) {\r\n  console.log(\"foor loop de 1 a 10, valor: \", i);\r\n  if (i === 3) {\r\n    console.log(\"break\");\r\n    break;\r\n  }\r\n}\r\n\r\nconsole.log(\"\\ncontinue statement\");\r\nconsole.log('i = 0; valorMaximo = 10' +\r\n'\\nwhile (i <= valorMaximo) {  ' + \r\n'\\n  i++;' + \r\n'\\n  if (i > 3) {' + \r\n'\\n    console.log(\"continue\");' + \r\n'\\n    continue;' + \r\n'\\n  }  ' + \r\n'\\n  console.log(`while loop de 1 a 10, valor ${i}`);' + \r\n'\\n}');\r\ni = 0;\r\nwhile (i <= valorMaximo) {  \r\n  i++;\r\n  if (i > 3) {\r\n    console.log(\"continue\");\r\n    continue;\r\n  }  \r\n  console.log(`while loop de 1 a 10, valor ${i}`);\r\n}\r\n\r\nconsole.log(\"\\nfor...in statement\");\r\nconsole.log('const gato = { color: \\'blanco\\', nombre: \\'Ele\\', descripcion: \\'hermosa\\'};' + \r\n'\\nfor (const g in gato)' + \r\n'\\n    console.log(`${g}: ${gato[g]}`);' + \r\n'\\n');\r\nconst gato = { color: 'blanco', nombre: 'Ele', descripcion: 'hermosa'};\r\nfor (const g in gato)\r\n  console.log(`${g}: ${gato[g]}`);\r\n\r\n\r\nconsole.log(\"\\nfor...of statement\");\r\nconsole.log(\"const arr = [a', 'b', 'c', 'd'];\" + \r\n'\\nfor (const letra of arr) ' + \r\n'\\n    console.log(letra)');\r\nconst arr = ['a', 'b', 'c', 'd'];\r\nfor (const letra of arr) \r\n  console.log(letra)\r\n\r\n\r\nconsole.log(\"\\n-----------------------------------------------\")\r\nconsole.log(\">>>Estructuras Condicionales\");\r\n\r\nconsole.log(\"\\nif...else statement\");\r\nconsole.log(\"let color = 'blanco';\" +\r\n\"\\nif (color === 'blanco') \" + \r\n'\\n{' + \r\n\"\\n   console.log('Esto es blanco');\" + \r\n'\\n} else {' + \r\n\"\\n   console.log('Esto es negro');\" + \r\n'\\n}');\r\nconsole.log('OUTPUT: ');\r\nlet color = 'blanco';\r\nif (color === 'blanco') \r\n{\r\n  console.log('Esto es blanco');\r\n} else {\r\n  console.log('Esto es negro');\r\n}\r\n\r\n\r\nconsole.log(\"\\nswitch statement\");\r\nconsole.log(\"let eleccion = 2;\" + \r\n\"\\nlet respuesta = '';\" + \r\n\"\\nswitch(eleccion) {\" + \r\n\"\\n  case 1: \" + \r\n\"\\n    respuesta = 'uno'\" + \r\n\"\\n    break;\" + \r\n\"\\n  case 2: \" + \r\n\"\\n    respuesta = 'dos'\" + \r\n\"\\n    break;\" + \r\n\"\\n  case 3: \" + \r\n\"\\n    respuesta = 'tres'\" + \r\n\"\\n    break;\" + \r\n\"\\n  default:\" + \r\n\"\\n    console.log('No conozco ese valor');\" + \r\n\"\\n}\");\r\nconsole.log('OUTPUT: ');\r\nlet eleccion = 2;\r\nlet respuesta = '';\r\nswitch(eleccion) {\r\n  case 1: \r\n    respuesta = 'uno'\r\n    break;\r\n  case 2: \r\n    respuesta = 'dos'\r\n    break;\r\n  case 3: \r\n    respuesta = 'tres'\r\n    break;\r\n  default:\r\n    console.log('No conozco ese valor');\r\n}\r\nconsole.log(`Tu elección ${eleccion} es ${respuesta}`);\r\n\r\n\r\nconsole.log(\"\\n-----------------------------------------------\")\r\nconsole.log(\">>>Manejo de Excepciones\");\r\n\r\nconsole.log(\"\\nthrow\");\r\nconsole.log('Solo muestro código porque si arrojo la excepción, la ejecución se detiene');\r\nconsole.log('throw \"Error2\"; // String type' + \r\n'\\nthrow 42; // Number type' + \r\n'\\nthrow true; // Boolean type' + \r\n'\\nthrow {' + \r\n'\\n  toString() {' + \r\n'\\n    return \"Soy un objeto\";' + \r\n'\\n  },' + \r\n'\\n};')\r\n\r\nconsole.log('\\ntry...catch statement');\r\nconsole.log('let valor1=0, valor2=0;' + \r\n'\\nlet resultado =0;' + \r\n'\\ntry {' + \r\n\"\\n  if (valor2 === 0) throw 'Division por cero'\" + \r\n'\\n  resultado = valor1/valor2;' + \r\n'\\n  console.log(resultado);' + \r\n'\\n} catch (error) {' + \r\n'\\n  console.log(error);' + \r\n'\\n}');\r\nconsole.log('OUTPUT: ');\r\nlet valor1=0, valor2=0;\r\nlet resultado =0;\r\ntry {\r\n  if (valor2 === 0) throw 'Division por cero'\r\n  resultado = valor1/valor2;\r\n  console.log(resultado);\r\n} catch (error) {\r\n  console.log(error);\r\n}\r\n\r\nconsole.log('\\nfinally block');\r\nconsole.log('let valor1=0, valor2=0;' + \r\n'\\nlet resultado =0;' + \r\n'\\ntry {' + \r\n\"\\n  if (valor2 === 0) throw 'Division por cero'\" + \r\n'\\n  resultado = valor1/valor2;' + \r\n'\\n  console.log(resultado);' + \r\n'\\n} catch (error) {' + \r\n'\\n  console.log(error);' + \r\n'\\n} finally {' +\r\n\"\\n  console.log('Este bloque se ejecuta haya o no error');\" +\r\n'\\n}');\r\nconsole.log('OUTPUT: ');\r\ntry {\r\n  if (valor2 === 0) throw 'Division por cero'\r\n  resultado = valor1/valor2;\r\n  console.log(resultado);\r\n} catch (error) {\r\n  console.log(error);\r\n} finally {\r\n  console.log('Este bloque se ejecuta haya o no error');\r\n}\r\n\r\n\r\nconsole.log(\"\\n-----------------------------------------------\")\r\nconsole.log(\">>>DIFICULTAD EXTRA\");\r\n\r\nlet numero = 10;\r\nwhile (numero >= 10 && numero <=55) {\r\n\r\n  if (numero % 2 === 0) {\r\n    if (numero %3 != 0) {\r\n      if (numero !=16) {        \r\n        console.log(numero);\r\n      }\r\n    }\r\n  }\r\n  numero++;\r\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/eulogioep.js",
    "content": "// Ejemplos de operadores en JavaScript\n\n// 1. Operadores Aritméticos\nconsole.log(\"--- Operadores Aritméticos ---\");\nconsole.log(\"Suma: 5 + 3 =\", 5 + 3);\nconsole.log(\"Resta: 10 - 4 =\", 10 - 4);\nconsole.log(\"Multiplicación: 6 * 2 =\", 6 * 2);\nconsole.log(\"División: 15 / 3 =\", 15 / 3);\nconsole.log(\"Módulo: 17 % 5 =\", 17 % 5);\nconsole.log(\"Exponenciación: 2 ** 3 =\", 2 ** 3);\nconsole.log(\"Incremento: let a = 5; a++; a =\", (() => { let a = 5; a++; return a; })());\nconsole.log(\"Decremento: let b = 8; b--; b =\", (() => { let b = 8; b--; return b; })());\n\n// 2. Operadores de Asignación\nconsole.log(\"\\n--- Operadores de Asignación ---\");\nlet x = 10;\nconsole.log(\"Asignación simple: x = 10;\", x);\nx += 5;\nconsole.log(\"Suma y asignación: x += 5;\", x);\nx *= 2;\nconsole.log(\"Multiplicación y asignación: x *= 2;\", x);\n\n// 3. Operadores de Comparación\nconsole.log(\"\\n--- Operadores de Comparación ---\");\nconsole.log(\"Igualdad: 5 == '5' es\", 5 == '5');\nconsole.log(\"Igualdad estricta: 5 === '5' es\", 5 === '5');\nconsole.log(\"Desigualdad: 5 != '6' es\", 5 != '6');\nconsole.log(\"Mayor que: 7 > 5 es\", 7 > 5);\nconsole.log(\"Menor o igual que: 10 <= 10 es\", 10 <= 10);\n\n// 4. Operadores Lógicos\nconsole.log(\"\\n--- Operadores Lógicos ---\");\nconsole.log(\"AND lógico: true && false es\", true && false);\nconsole.log(\"OR lógico: true || false es\", true || false);\nconsole.log(\"NOT lógico: !true es\", !true);\n\n// 5. Operadores de Tipo\nconsole.log(\"\\n--- Operadores de Tipo ---\");\nconsole.log(\"typeof 42 es\", typeof 42);\nconsole.log(\"instanceof: [] instanceof Array es\", [] instanceof Array);\n\n// 6. Operadores de Bits\nconsole.log(\"\\n--- Operadores de Bits ---\");\nconsole.log(\"AND a nivel de bits: 5 & 3 =\", 5 & 3);\nconsole.log(\"OR a nivel de bits: 5 | 3 =\", 5 | 3);\nconsole.log(\"XOR a nivel de bits: 5 ^ 3 =\", 5 ^ 3);\nconsole.log(\"Desplazamiento a la izquierda: 5 << 1 =\", 5 << 1);\n\n// Ejemplos de estructuras de control\n\n// 1. Estructura Condicional: if-else\nconsole.log(\"\\n--- Estructura Condicional: if-else ---\");\nlet numero = 15;\nif (numero > 10) {\n    console.log(\"El número es mayor que 10\");\n} else if (numero < 10) {\n    console.log(\"El número es menor que 10\");\n} else {\n    console.log(\"El número es igual a 10\");\n}\n\n// 2. Estructura Condicional: switch\nconsole.log(\"\\n--- Estructura Condicional: switch ---\");\nlet dia = \"Lunes\";\nswitch (dia) {\n    case \"Lunes\":\n        console.log(\"Hoy es Lunes\");\n        break;\n    case \"Martes\":\n        console.log(\"Hoy es Martes\");\n        break;\n    default:\n        console.log(\"Es otro día de la semana\");\n}\n\n// 3. Estructura Iterativa: for\nconsole.log(\"\\n--- Estructura Iterativa: for ---\");\nfor (let i = 0; i < 5; i++) {\n    console.log(\"Iteración for:\", i);\n}\n\n// 4. Estructura Iterativa: while\nconsole.log(\"\\n--- Estructura Iterativa: while ---\");\nlet contador = 0;\nwhile (contador < 3) {\n    console.log(\"Iteración while:\", contador);\n    contador++;\n}\n\n// 5. Estructura Iterativa: do-while\nconsole.log(\"\\n--- Estructura Iterativa: do-while ---\");\nlet j = 0;\ndo {\n    console.log(\"Iteración do-while:\", j);\n    j++;\n} while (j < 3);\n\n// 6. Manejo de Excepciones: try-catch\nconsole.log(\"\\n--- Manejo de Excepciones: try-catch ---\");\ntry {\n    throw new Error(\"Este es un error de ejemplo\");\n} catch (error) {\n    console.log(\"Error capturado:\", error.message);\n} finally {\n    console.log(\"Este bloque siempre se ejecuta\");\n}\n\n// DIFICULTAD EXTRA\nconsole.log(\"\\n--- DIFICULTAD EXTRA ---\");\nfor (let num = 10; num <= 55; num++) {\n    if (num % 2 === 0 && num !== 16 && num % 3 !== 0) {\n        console.log(num);\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/evaristojs.js",
    "content": "/*Operadores aritmeticos*/\nlet suma = 10 + 5\nlet resta = 10 - 5\nlet multiplicacion = 10 * 5\nlet division = 10 / 5\nlet modulo = 10 % 3 //esto me dio especial curiosidad porque no sabia que existia\nlet incremento = 1\nincremento++ // incremento = incremento + 1\nlet decremento = 1\ndecremento-- // decremento = decremento - 1\n\n/*Operadores de asignacion en especial estos operadores hasta ahora le veo como utilidad que te hacen escribir menos codigo*/\n\nlet x = 10\nx += 5 // x = x + 5\nx -= 5 // x = x - 5\nx *= 5 // x = x * 5\nx /= 5 // x = x / 5\nx %= 3 // x = x % 3\n\n/*Operadores de comparacion*/\n\nlet a = 10\nlet b = '10'\n\nconsole.log(a == b) // true (solo compara el valor y puede causar muchos problemas)\nconsole.log(a === b) // false (compara valor y tipo de dato este te salva de muchos problemas porque no solo compara valores, tambien compara tipos de datos)\nconsole.log(a != b) // false (solo compara el valor se puede usar pero no es recomendable)\nconsole.log(a !== b) // true (compara valor y tipo de dato)\nconsole.log(a > 5) // true\nconsole.log(a < 5) // false\nconsole.log(a >= 10) // true\nconsole.log(a <= 10) // true\n\n/*Operadores logicos*/\n\nlet c = 5\nlet d = 10\n\nconsole.log(c > 0 && d > 0) // true (AND)\nconsole.log(c > 0 || d < 0) // true (OR)\nconsole.log(!(c > 0)) // false (NOT)\n\n/*Estructuras de control*/\n\n// Estructura condicional if...else\nlet edad = 18\n\nif (edad < 18) {\n    console.log('Menor de edad')\n} else if (edad === 18) {\n    console.log('Recién mayor de edad') /*se aplica === en vez de == para evitar errores en el codigo*/\n} else {\n    console.log('Mayor de edad')\n} \n/* resumen en estas 3 condiciones es que si la edad es menor a 18 imprime menor de edad, si la edad es exactamente 18 imprime recien mayor de edad y si no se cumple ninguna de las dos condiciones anteriores imprime mayor de edad*/\n\n// Estructura condicional switch\nlet color = 'rojo'\n\nswitch (color) {\n    case 'rojo':\n        console.log('El color es rojo')\n        break\n    case 'azul':\n        console.log('El color es azul')\n        break\n    case 'verde':\n        console.log('El color es verde')\n        break\n    default:\n        console.log('Color no reconocido')\n        break\n} /*esta estructura switch es como un if pero mas ordenado y facil de leer cuando se tienen muchas condiciones, en este caso si el color es rojo imprime \"El color es rojo\", si es azul imprime \"El color es azul\", si es verde imprime \"El color es verde\" y si no es ninguno de esos colores imprime \"Color no reconocido\" puede parecer que nunca se usara algo como esto en la vida real pero creeme si se usa*/\n\n// Estructura de bucle for\nfor (let i = 0; i < 5; i++) {\n    console.log('Iteración número ' + i)\n} /*esta madre siempre me dio problemas entenderlo por alguna razon ancestral que desconozco, pero ya lo entendi por fin y es muy util, en este caso imprime \"Iteración número \" seguido del numero de la iteracion desde 0 hasta 4 (5 no se incluye porque la condicion es i < 5)*/\n\n// Estructura de bucle while\nlet j = 0\nwhile (j < 5) {\n    console.log('Iteración número ' + j)\n    j++ /*no olvidar incrementar j para evitar un bucle infinito y dato curioso: ++ siempre suma 1 por si te preguntas porque no se pone de manera explicita, es raro porque la programacion a veces hay que ser sumanete especificos pero en este caso donde magicamente ++ suma 1 sin nadie construir esa funcion (al menos no de manera manual porque luego busque y resulta que si esta construida y es el mismo lenguaje que la tiene dentrod de el mismo supongo que es para ahorranos tiempo como devs)*/}\n\n// Estructura de bucle do...while\nlet k = 0\ndo {\n    console.log('Iteración número ' + k)\n    k++\n} while (k < 5) \n    /*esta estructura es similar a while pero la diferencia es que do...while siempre ejecuta el bloque de codigo al menos una vez antes de verificar la condicion, en este caso imprime \"Iteración número \" seguido del numero de la iteracion desde 0 hasta 4 (5 no se incluye porque la condicion es k < 5) util en validaciones, menus y demas cosas que deben pasar al menos una vez y luego ejecutadas si las condiciones se dan otra vez*/ \n\n// https://developer.mozilla.org/es/docs/Web/JavaScript\n\n// Esta es la forma de representar un comentario en una sola línea\n\n/* Esta es la forma de representar un comentario en varias líneas */\n\n// Variables y Constantes\nvar name = 'Pedro' /*no se recomienda usar var porque tiene un scope global y puede causar problemas en el codigo como por ejemplo que la re declares sin querer mas adelante, que llames la variable sin declararla no es prohibido usarla pero tiene sus usos especificos*/\nlet name = 'Juan' /*Let es mas recomendable usarla porque tiene un scope de bloque y no puede ser redeclarada en el mismo scope*/ \nconst ten = 10\n\n// Datos primitivos\nlet lastname = 'López' // String\nlet age = 25 // Numero\nlet isMale = true // Boolean\n\nlet address // Indefinido se usa cuando una variable no tiene valor asignado\n\nlet stockAvailble = null /* Nulo se usa para representar la ausencia intencional de cualquier valor*/\n\nlet myBigInt = 2343n /* BigInt se usa en numeros muy grandes que superan el limite de los numeros normales en JS */\n\nlet mySymbol = Symbol('unique') /* Symbol se usa para crear identificadores unicos para propiedades de objetos */"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/faga01.js",
    "content": "//#01 OPERADORES Y ESTRUCTURAS DE CONTROL\n\n//Punto 1\n//Operador de asignacion\nlet a = 8;\nlet b = 3;\n// Operadores Aritméticos\n//Operador de suma\nlet suma = a + b;\n//Operador de resta\nlet resta = a - b;\n//Operador de multiplicación\nlet multiplicacion = a * b;\n//Operador de división\nlet division = a / b;\n//Operador de exponenciación\nlet exponenciacion = a ** 3;\n//Operador de resto de la división\nlet modulo = a % b;\n//Operador de incremento\nlet incremento = ++a;\n//Operador de decremento\nlet decremento = --b;\n\n//Operadores de Asignación\nnum = 5;\nasigSuma = 10; \nasigSuma += num;\nasigSuma -= num;\nasigSuma *= num;\nasigSuma /= num;\nasigSuma %= num;\nasigSuma **= num;\n\n//Operadores de comparación. Se utilizan para comprobar TRUE(verdadero) o FALSE(falso)\n\nlet x = 20;\nlet y = \"20\";\n// Operador igual\nlet comp1 = x == y;\n// Operador igual valor igual tipo\nlet comp2 = x === y;\n// Operador no igual o diferente\nlet comp3 = x != y;\n// Operador no igual valor y tipo o diferente tipo y valor\nlet comp4 = x !== y;\n// Operador mayor que\nlet comp5 = x > y;\n// Operador menor que\nlet comp6 = x < y;\n// Operador mayor o igual que\nlet comp7 = x >= y;\n// Operador menor que\nlet comp8 = x <= y;\n\n\n//Operadores de cadena\nlet palabra1 = \"nombre1\";\nlet palabra2 = \"nombre2\";\n\nlet cadena1 = palabra1 == palabra2;\nlet cadena2 = palabra1 > palabra2;\nlet cadena3 = palabra1 >= palabra2;\n\nlet cadena4 = palabra1 + palabra2;\nlet cadena5 = palabra1 + \" \" + palabra2;\nlet cadena6 = palabra1 + \" \" + 10;\n\n\n//Operadores lógicos. Se utliza para determinar la logica entre variables o valores\nlet c = 30;\nlet d = 20;\n\n// && Relación de lógica que se deben cumplir todas las operaciones para TRUE de lo contrario FALSE\nlet rta1 = (c > 10) && (d < 25);\nlet rta2 = (c > 10) && (d < 25);\n\n// || Relación de lógica que se deben cumplir tan solo una de las operaciones para TRUE de lo contrario FALSE\nlet rta3 = (c == 10) || (d < 25);\nlet rta4 = (c > 40) || (d == 25);\n\n// Negacion de la operacion\nlet rta5 = !(c == 10)\nlet rta6 = !(d == 20)\n\n\n//Punto 2\n// Estructuras de Control\n// Condicional if. Ejecuta el bloque de código si la respuesta de la condicioón es verdadera\nlet hora = 2;\n\nif (hora < 12 ) {\n    console.log(\"Buenos días\");\n}\n\nif (hora >= 12 && hora < 19 ) {\n    console.log(\"Buenas tardes\");\n}\n\nif (hora >= 19 ) {\n    console.log(\"Buenas noches\");\n}\n\n/* Condicional else if. Ejecuta el bloque de código si la respuesta de la condicioón es verdadera. \nHay varios bloques, si no se genera un bloque pasa al otro hasta que se ejecuta alguno.*/\n\nlet hora2 = 12;\n\nif(hora2 < 12){\n    console.log(\"Buenos días\");\n} else if (hora2 >= 12 && hora2 < 19 ) {\n    console.log(\"Buenas tardes\");\n} else {\n    console.log(\"Buenas noches\");\n}\n\n/* Condicional switch. Ejecuta el bloque de código si la respuesta de la condicioón es verdadera. \nHay varios bloques, si no se genera un bloque pasa al otro hasta que se ejecuta alguno.*/\nlet jornada = \"tarde\";\n\nswitch(jornada) {\n    case \"mañana\":        \n        console.log(\"Buenos días\");\n    break;\n    case \"tarde\":    \n        console.log(\"Buenas tardes\");\n    break;\n    default:        \n        console.log(\"Buenas noches\");        \n}\n\n\n// Blucle for. Es útil para ejecutar el mismo código varias veces\nlet conteo = \"\";\n\nfor (let i = 5; i > 0; i--) {\n    conteo = \"conteo regresivo en\" + \" \" + i + \" \"+\"segundos\";\n    console.log();\n}\n\n// Blucle for in. Recorre las propiedades de un objeto o podría tambien de una matriz\n\nconst semana = {1 : \"Lunes\", 2: \"Martes\", 3: \"Miercoles\", 4: \"Jueves\", 5: \"Viernes\", 6: \"Sabado\", 7 : \"Domingo\"}\n\nlet dia = \"\";\nfor (let x in semana) {\n    dia = \"Día\" + \" \"+ x + \" \" + semana[x];\n    console.log(dia);\n}\n\nconst numeros = [77, 53, 62, 9, 1, 20, 40];\n\nlet enteros = \"\";\nfor (let x in numeros) {\n    enteros = numeros[x]\n    console.log(enteros);\n}\n\n\n// Blucle for of. Recorre las valores de un iterable como arrays o matrices, strings, maps, etc..\n\nconst motos = [\"Yamaha\", \"Suzuki\", \"Honda\", \"Kawasaki\", \"Bmw\"];\n\nlet moto = \"\";\nfor (let x of motos) {\n    moto = x;\n    console.log(moto);\n}\n\n\n// Bucle While. Ejecutan un bloque de código siempre que una condición especificada sea verdadera\n\nlet increment= \"\";\nlet i = 1;\n\nwhile (i <= 5) {\n    increment = \"Número incrementando en\" + \" \" + i;\n    console.log(increment);\n    i++;\n}\n\nconsole.log(\"\\n\");\n\n\n/* Bucle do While. Ejecutará el bloque de código una vez, antes de verificar si la condición es verdadera,\n luego repetirá el bucle mientras la condición sea verdadera. Se ejecuta el código al menos 1 vez*/\nlet decrement = \"\";\nlet j = 5;\n\ndo {    \n     \n    decrement = \"Número decrementa en\" + \" \" + j; \n    console.log(decrement);\n    j--;\n       \n} \nwhile (j >= 1);\n\n// for each. El método forEach llama a una función para cada elemento de un arrary o arreglo.\n\nlet frutero = \"\";\n\nconst frutas = [\"pera\", \"manzana\", \"banano\", \"uva\"];\n\n//frutas.forEach((myFunction) => console.log(myFunction));\n\nfrutas.forEach(myFunction);\n\nfunction myFunction(item, i) {\n    frutero +=  console.log(i +  \".\" + item + \" \");\n}\n\n//console.log(frutero);\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/farthaz.js",
    "content": "let x = prompt(\"Ingrese un número\")\r\na = parseInt(x)\r\nlet y = prompt(\"Ingrese otro número\")\r\nb = parseInt(y)\r\n\r\nconst sum = a + b\r\nconst sub = a - b\r\nconst factor = a * b\r\nconst div = a / b\r\nconst mod = a % b\r\n\r\nconsole.log(\"La suma es\", sum, \"La resta es\", sub, \"La multiplicacion es\", factor, \"El resto de la divison es\", div, \"El modulo es\", mod)\r\n\r\n//Los siguientes ejercicios aplican operadores de igualdad\r\n\r\n\r\n//Cuenta y lista los números comprendidos entre a y b usando bucles if y for. En cao de que A sea menor que B, la lista es ascendente\r\nif (a < b) {\r\n    console.log(\"a es menor a b\")\r\n    for (let i = a; i <= b; i++) {\r\n        console.log(i)\r\n    }\r\n} else if (a === b) {\r\n    console.log(\"a es igual a b\")\r\n}\r\n\r\n//Cuenta y lista los números comprendidos entre a y b usando bucles while. En caso de que A sea mayor que B, la lista es descendiente\r\nif (a > b) {\r\n    console.log(\"a es mayor a b\")\r\n    do {\r\n        console.log(a)\r\n        a--\r\n    } while(a > b);\r\n}\r\n\r\n// Operadores logicos \r\n\r\nif (a != b) {\r\n    console.log(\"A es diferente a b\")\r\n} if (a <= 10 && a >= 1) {\r\n    console.log(\"A esta entre 10 y 1\")\r\n} else if (a <= 10 || a >= 1) {\r\n    console.log(\"A puede estar fuera del rango del 1 al 10\")\r\n}\r\n\r\n/* Crea un programa que imprima por consola todos los números comprendidos\r\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3 */\r\n\r\nfor (let i = 10; i <= 55; i++) {\r\n    if (i % 2 === 0 && i != 16 && i % 3 != 0) {\r\n        console.log(i)\r\n    }\r\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/fdcorreadev.js",
    "content": "/**\n * Realizo el ejercicio leyendo todo sobre los operadores en javascript para con ellos poder interpretar y programarlos\n * fuente: https://developer.mozilla.org/es/docs/Web/JavaScript/Guide/Expressions_and_operators#Asignación\n */\n\nlet x = 8;\nlet y = 9;\n//Asignación\nx = y\nconsole.log(`Asignación ${x}`)\n// Asignación de adicion y abreviación\nx = 8\ny = 9\nconsole.log(`valores de entrada para las operaciones ${x}, ${y}`)\nx = x + y\nconsole.log(`Asignación de adicion ${x}`)\n// abreviación\nx += y\n// Asignación de resta y abreviación\nx = 8\ny = 9\n\nx = x - y\nconsole.log(`Asignación de resta ${x}`)\nx -= y\n\n// Asignación de multiplicación y abreviación\nx = 8\ny = 9\n\nx = x * y\nconsole.log(`Asignación de multiplicación ${x}`)\nx *= y\n// Asignación de división y abreviación\nx = 8\ny = 9\n\nx = x / y\nconsole.log(`Asignación de división  ${x}`)\nx /= y\n// Asignación de residuo y abreviacion\nx = 8\ny = 9\n\nx = x % y\nconsole.log(`Asignación de residuo  ${x}`)\nx %= y\n\n// Asignación de exponenciación y abreviacion\nx = 8\ny = 9\n\nx = x ** y\nconsole.log(`Asignación de exponenciación  ${x}`)\nx **= y\n// Asignación de desplazamiento a la izquierda y abreviacion\n/* \nREALIZO ESTA ACLARACIÓN PORQUE NO SABIA QUE SIGNIFICABAN\n\nEn JavaScript, los operadores << y <<= son operadores de desplazamiento de bits (bitwise shift).\n- ejemplo:\nEl valor de x es 8 (en binario: 00000000000000000000000000001000).\nEl valor de y es 9.\nx << y significa que los bits de x (que es 8) se desplazan 9 posiciones a la izquierda.\n8 en binario es 00000000000000000000000000001000.\nDespués de desplazarlo 9 posiciones a la izquierda: 00000000000000000001000000000000 (que en decimal es 4096).\nAhora, x toma el valor de 4096. \n*/\nx = 8\ny = 9\n\nx = x << y\nconsole.log(`Asignación de desplazamiento a la izquierda ${x}`)\nx <<= y\n\n// Asignación de desplazamiento a la derecha y abreviacion\nx = 8\ny = 9\n\nx = x >> y\nconsole.log(`Asignación de desplazamiento a la derecha ${x}`)\nx >>= y\n\n// Asignación de desplazamiento a la derecha sin signo y abreviación\nx = 8\ny = 9\n\nx = x >>> y\nconsole.log(`Asignación de desplazamiento a la derecha sin signo ${x}`)\nx >>>= y\n\n// Asignación AND bit a bit y abreviación\nx = 8\ny = 9\n\nx = x & y\nconsole.log(`Asignación AND bit a bit ${x}`)\nx &= y\n\n// Asignación XOR bit a bit y abreviación\nx = 8\ny = 9\n\nx = x ^ y\nconsole.log(`Asignación XOR bit a bit ${x}`)\nx ^= y\n// Asignación OR bit a bit y abreviación\nx = 8\ny = 9\n\nx = x | y\nconsole.log(`Asignación OR bit a bit ${x}`)\nx |= y\n// Asignación AND logico y abreviación\nx = 8\ny = 9\n\nx && (x = y)\nconsole.log(`Asignación AND logico ${x}`)\nx &&= y\n\n// Asignación OR logico y abreviación\nx = 8\ny = 9\n\nx || (x = y)\nconsole.log(`Asignación OR logico  ${x}`)\nx ||= y\n// Asignación de anulación lógica y abreviación\nx = 8\ny = 9\n\nx ?? (x = y)\nconsole.log(`Asignación de anulación lógica ${x}`)\nx ??= y\n\n//ESTRUCTURA DE CONTROL PARA JAVASCRIPT\n\n// condicional IF permite elvaluar si cumple una codicion\nlet mayorEdad = 24\n\nif (mayorEdad >= 18) {\n    console.log(`es mayor de edad ${mayorEdad}`)\n} else if (mayorEdad > 18 & mayorEdad <= 25) {\n    console.log(`es adulto joven ${mayorEdad}`)\n} else {\n    console.log(`es manor de edad ${mayorEdad}`)\n}\n\n// bluce for se ejecuta hasta que la codicion de se cumpla\n\nconst pasos = 5\n\nfor (let paso = 0; paso <= pasos; paso++) {\n    console.log(`estoy dando el paso: ${paso}`)\n}\n\n\n// while ejecuta la sentencia mientras la codicion que se esta evaluando sea verdadera\nlet contador = 0\nwhile (contador < 4) {\n    contador++;\n    console.log(`el contador va en ${contador}`)\n}\nconsole.log(\"Contador es igual a \", contador)\n\n// la sentencia \"hacer mientras\" esto se va ejecutar hasta la condicion del while se cumpla\nlet result = '';\nlet cont = 0;\ndo {\n    cont++;\n    result = result + cont;\n    console.log(`sigo haciendo esto ${result}`)\n} while (cont < 5);\n\nconsole.log(`finalice cumpli la condicion ${result}`);\n\n// switch permite evaluar una expresion item a item o valor de entrada para decidir en que proceso debe correr segun el case\nlet fruitType = 'naranja'\n\nswitch (fruitType) {\n    case \"manzana\":\n        console.log(`la Manzana vale 10`)\n        break;\n    case \"naranja\":\n        console.log(`la naranja vale 5`)\n        break;\n    case \"pera\":\n        console.log(`la pera vale 8`)\n        break;\n\n    default:\n        break;\n}\n\ntry {\n    let operation  =  10 / 0;\n    if(!isFinite(operation)){\n        throw new Error(\"Resultado es Infinity, operacion no valida\");\n    }\n} catch (error) {\n    console.log(`Esta operacion no es valida ${error.message}`)\n}\n\n// este es un ejemplo  donde combinamos un blucle y un array con datos para ver como funciona de mejor manera.\nlet fruta = [{ fruit: \"manzana\", value: 10 }, { fruit: \"naranja\", value: 5 }, { fruit: \"pera\", value: 8 }]\n\nfruta.forEach((fruitType) => {\n    switch (fruitType.fruit) {\n        case \"manzana\":\n            console.log(`la Manzana vale ${fruitType.value}`)\n            break;\n        case \"naranja\":\n            console.log(`la naranja vale ${fruitType.value}`)\n            break;\n        case \"pera\":\n            console.log(`la pera vale ${fruitType.value}`)\n            break;\n\n        default:\n            break;\n    }\n})\n\n\n//ejercicio para practicar lo visto \n/**\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3. \n */\n\nconsole.log(`-----------------------------------------Ejercicio practico-----------------------------------------------------------------`)\n\n\nfor(let num = 10; num <= 55; num++){\n    if(num % 2 === 0 && num !== 16 && num % 3 !== 0) console.log(num)\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/fernandog25.js",
    "content": "//Operadores aritméticos\n\nvar  a = 3\nvar  b = 2\n\nsuma = a + b\nresta = a - b\nmult = a * b\ndiv = a / b\nmod = a % b\nincr = ++a\ndecr = a--\nneg= -a\nexp = b**a\n\nconsole.log(\"Operadores aritméticos: \\n\")\nconsole.log(\"La suma de 3 y 2 es igual a \" + suma)\nconsole.log(\"La diferencia entre 3 y 2 es igual a \" + resta)\nconsole.log(\"La multiplicacion entre 3 y 2 es igual a \" + mult)\nconsole.log(\"La division entre 3 y 2 es igual a \" + div)\nconsole.log(\"El resto entre 3 y 2 es igual a \" + mod)\nconsole.log(\"El incremento de 3 es \" + incr)\nconsole.log(\"La negacion de 3 es \" + neg)\nconsole.log(\"2 elevado al cubo es igual a\" + exp)\n\n\n\n//Operadores lógicos\n\nvar  c = true\nvar  d = false\n\nand = c && d\nor  = c || d\nnot = !c\n\nconsole.log(\"\\nOperadores lógicos: \\n\")\nconsole.log(\"True and false da \" + and)\nconsole.log(\"True or false da \" + or)\nconsole.log(\"La negacion de true es \" + not)\n\n\n\n//Operadores de comparación\n\n\nconsole.log(\"\\nOperadores de comparación: \\n\")\nconsole.log(\"2 es igual a 3: \", a==b )\nconsole.log(\"2 no es igual a 3:\", a!=b)\nconsole.log(\"2 es estrictamente igual a 3:\", a===b)\nconsole.log(\"2 es estrictamente desigual a 3:\", a!==b)\nconsole.log(\"2 es mayor a 3:\", a>3)\nconsole.log(\"2 es mayor o igual a 3:\", a>=b)\nconsole.log(\"2 es menor a 3:\", a<b)\nconsole.log(\"2 es menor o igual a 3:\", + a<=b)\n\n\n\n//Operadores de asignación\n\nconsole.log(\"\\nOperadores de asignación \\n\")\n\na = b // asignación\nconsole.log(\"asignacion: a = \" + a + \", b = \" + b)\n\na += b // asignación de adicion\nconsole.log(\"asignacion de adicion: a = \" + a + \", b = \" + b)\n\na -= b // asignación de resta\nconsole.log(\"asignacion de resta: a = \" + a + \", b = \" + b)\n\na *= b // asignación de multiplicación\nconsole.log(\"asignacion de multiplicacion: a = \" + a + \", b = \" + b)\n\na /= b // asignación de división\nconsole.log(\"asignacion de division: a = \" + a + \", b = \" + b)\n\na %= b // asignación de residuo\nconsole.log(\"asignacion de residuo: a = \" + a + \", b = \" + b)\n\na **= b // asignación de exponenciación\nconsole.log(\"asignacion de exponenciacion: a = \" + a + \", b = \" + b)\n\na <<= b // asignación de desplazamiento a la izquierda\nconsole.log(\"asignacion de desplazamiento a la izquierda: a = \" + a + \", b = \" + b)\n\na >>= b // asignación\nconsole.log(\"asignacion: a = \" + a + \", b = \" + b)\n\na = b // asignación de desplazamiento a la derecha\nconsole.log(\"asignacion de desplazamiento a la derecha: a = \" + a + \", b = \" + b)\n\na >>>= b // asignación de desplazamiento a la derecha sin cargo\nconsole.log(\"asignacion de desplazamiento a la derecha sin cargo: a = \" + a + \", b = \" + b)\n\na &= b // asignación and bit a bit\nconsole.log(\"asignacion and bit a bit: a = \" + a + \", b = \" + b)\n\na ^= b // asignación xor bit a bit\nconsole.log(\"asignacion xor bit a bit: a = \" + a + \", b = \" + b)\n\na |= b // asignación or bit a bit\nconsole.log(\"asignacion or bit a bit: a = \" + a + \", b = \" + b)\n\na &&= b // asignación and logico\nconsole.log(\"asignacion and logico: a = \" + a + \", b = \" + b)\n\na ||= b // asignación or logico\nconsole.log(\"asignacion or logico: a = \" + a + \", b = \" + b)\n\na ??= b // asignación de anulación lógica\nconsole.log(\"asignacion de anulacion logica: a = \" + a + \", b = \" + b)\n\n\n\n//Operadores bit a bit\n\nvar e = 4 //100\nvar f = 6 //110\n\nconsole.log(\"\\nOperadores bit a bit \\n\")\nconsole.log(\"and: \", e & f)\nconsole.log(\"or: \", e | f)\nconsole.log(\"xor: \", e ^ f)\nconsole.log(\"not: \", e % f) //acomodar\nconsole.log(\"desplazamiento a la izquierda: \", e << f)\nconsole.log(\"desplazamiento a la derecha de propagacion de signo: \", e >> f)\nconsole.log(\"desplazamiento a la derecha de relleno cero: \", e >>> f)\n\n\n\n//Estructuras de control\n\nnum1 = 1;\nnum2 = 2;\n\nconsole.log(\"\\nif\\n\")\nif (num1 == num2)\nconsole.log(\"Los numeros son iguales\")\nelse if (num1 > num2)\nconsole.log(\"num1 es mayor a num2\")\nelse\nconsole.log(\"num 1 es menor a num2\")\n\nconsole.log(\"\\nswitch\\n\")\n\nanimal = \"perro\"\n\nswitch (animal)\n{\ncase \"gato\":\n    console.log(\"El animal es un gato\")\n    break\ncase \"perro\":\n    console.log(\"El animal es un perro\")\n    break\ncase \"oso\":\n        console.log(\"El animal es un oso\")\n        break\ncase \"gallina\":\n    console.log(\"El animal es una gallina\")\nbreak\ndefault:\n    console.log(\"No se encuentra el animal\")\n}\n\nconsole.log(\"\\nfor\\n\")\n\nfor(var i = 0; i<=10; i++)\n{\n    console.log(i)\n}\n\nconsole.log(\"\\nwhile\\n\")\n\nnumero = 0\nconsole.log(\"Numeros pares\")\nwhile(numero < 11)\n{\n    if (!(numero % 2))\n        console.log(numero)\n    numero++\n}\n\n\n\n/*Ejercicio extra \nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.*/\n\n\n\nconsole.log(\"\\nEjercicio extra\\n\")\n\n\nfor(var i = 10; i<56; i++)\n{\n    if (!(i % 3) || i == 16)\n    {\n\n    }\n        else if (i % 2 == 0)\n    console.log(i)\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/fidelysla.js",
    "content": "\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * \n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n*/\n\n//? TIPOS DE OPERADORES\n\n// **Operadores Aritmeticos**\nlet num1 = 3\nnum1 + num1\nnum1 - 1\nnum1++\nnum1++\nnum1--\n++num1\n--num1\n++num1\n// console.log(num1);\n\nnum1 * num1\nnum1 ** num1\nnum1 / num1\n12 % 5\n\n// **Operador de asignacion**\nlet num2 = 20\nnum2 += 1\nnum2 -= 1\nnum2 *= 1\nnum2 /= 2\nnum2 **= 2\n\n// **Operadores de comparacion**\n3 == \"3\" //true\n3 === \"3\" //false\n4 != \"4\" //false\n4 !== \"4\" //true\n3 > 2 //true\n4 < 5 //true\n6 >= 5 //true\n\n// **Operadores Logicos**\nlet isString = true;\nlet isNum = false;\n\nconsole.log(isString && isNum);\nconsole.log(isString || isNum);\nconsole.log(!isNum);\n\n// **Operadores Bit a Bit**\nlet a = 5;  // Representación binaria: 0101\nlet b = 3;  // Representación binaria: 0011\n\nconsole.log(a & b);  // 1 (AND a nivel de bits)\nconsole.log(a | b);  // 7 (OR a nivel de bits)\n\n\n\n// ? Ejemplos de tipos de estructuras de control\n\n// **Condicionales**\n\n// If-else\nif (isString && isNum) {\n    console.log(\"Son tipos de datos verdaderos\");\n} else if (isString || isNum) {\n    console.log(\"Por lo menos uno es tipo de dato verdadero\");\n}\n\nif ( 15 > 16 ) {\n    console.log(\"Consola 1\");\n} else if (15 < 16) {\n    console.log(\"Consola 2\");\n}\n\n// Switch\nlet day = new Date().getDay()\nswitch (day) {\n    case 0:\n        console.log(\"Hoy es Domingo\");\n        break;\n    case 1:\n        console.log(\"Hoy es Lunes\");\n        break;\n    case 2:\n        console.log(\"Hoy es Martes\");\n        break;\n    case 3:\n        console.log(\"Hoy es Miercoles\");\n        break;\n    case 4:\n        console.log(\"Hoy es Jueves\");\n        break;\n    case 5:\n        console.log(\"Hoy es Viernes\");\n        break;\n    default:\n        console.log(\"Hoy es Sabado\");\n        break;\n};\n\n// **Ciclos**\n\n// For\nfor (let index = 0; index <= 10; index++) {\n    (index % 2 === 0)\n        ? console.log(index)\n        : \"\";\n};\n\n// for in\nlet abc = { a: 1, b: 2, c: 3 };\nfor (const key in abc) {\n    if (Object.hasOwnProperty.call(abc, key)) {\n        const element = abc[key];\n        console.log(element);\n    }\n};\n\n// for of\nlet arr1 = [\"a\",\"b\",\"c\",\"d\",\"e\"]\nfor (const iterator of arr1) {\n    console.log(iterator);\n};\n\n// forEach\narr1.forEach( (v, i) => {\n    console.log(`Index: ${i}, Value: ${v}`);\n});\n\n// While\n// Numeros entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\nlet num3 = 10\nwhile (num3 <= 55) {\n    if (num3 === 10) {\n        console.log(num3);\n    } else if (num3 % 3 === 0 || num3 === 16) {\n\n    } else {\n        console.log(num3);\n    }\n    num3++\n    num3++\n};\n\n// do-while\ndo {\n    console.log(num3);\n    num3++\n} while (num3 <= 20);\n\n\n// **Manejo de Errores**\n\ntry {\n    noExiste;\n    console.log(\"*\")\n} catch (error) {\n    console.log(error)\n} finally {\n    console.log(\"*\")\n};\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/fiedri.js",
    "content": "// Tipos de operadores\n/*\n=========================\n operadores de asignacion\n=========================\n*/\nlet x = 10// (=) asignacion\nx += 10 //20, (+=) asignacion de adicion\nx -= 5 //15, (-=) asignacion de resta\nx *= 2 //30, (*=) asignacion multplicacion\nx /= 2 //15, (/=) asignacion de division\nx **= 2//225, (**=) asignacion de exponenciacion\nx %= 2//1, (%=) asignacion de resto\n\n\nx <<= 6//64, desplazamiento a la izquierda\n// x <<= n  es lo mismo que  x = x << n\n// 1. Convierte x a binario (32 bits).\n// 2. Mueve los bits 'n' posiciones a la izquierda.\n// 3. Rellena los huecos de la derecha con CEROS.\n// 4. Equivale a multiplicar x por 2 elevado a n.\nconsole.log(x)\n\nx >>= 6// desplazamiento a la derecha con signo\n// 2. mueve 'n' posiciones a la derecha\n// 3. Si el numero es positivo rellena con 0, si es negativo con 1\n// Equivale a dividir x entre 2^n y redondea hacia abajo\nconsole.log(x)\n\n// Asinacion bit a bit\nx &= 10//(AND)\n// 1 &= 1, es igual a 1\n//Si en la misma posición ambos tienen un 1 el resultado es 1 Si no es 0\nx  ^= 10 //(XOR)\n// devuelve 1 si los bits en esa posicion son distintos\nx |= 10 // (OR)\n// devuelve 1 si x o y (o ambos) son 1\nconsole.log(x)\n\n// asignacion logica\n// &&= (AND), Solo asigna el valor de la derecha si el de la izquierda ya es verdadero\nlet usuario = true\nusuario &&= \"Juan\"\n\nlet invitado = false\ninvitado &&= \"Pedro\"\nconsole.log(usuario, invitado)// \"Juan\" false\n\n// ||= (OR), asigna el valor de la derecha si el de la izquierda es falso\nlet nickname = \"\"; \nnickname ||= \"Anónimo\"; \nconsole.log(nickname);// \"Anonimo\"\n\nlet puntos = 10;\npuntos ||= 100;\nconsole.log(puntos);// 10\n\n// ??= (anulacion) asigna si el valor de la izquierda es estrictamente null o undefined\nlet nombre;\nnombre ??= \"Sin nombre\";\nconsole.log(nombre); // \"Sin nombre\"\n\n\n/*\n=========================\n operadores de comparacion\n=========================\n*/\nconsole.log(10 == \"10\");// true (igualdad debil)\nconsole.log(10 === \"10\");// false (igualdad fuerte, tambien compara tipo)\nconsole.log(10 != 5)// true (desigualdad)\nconsole.log(10 !== \"10\"); // true (Desigualdad fuerte)\nconsole.log(10 > 5, 10 < 20, 10 >= 10, 10 <= 10);\n/*\n=========================\n operadores aritmeticos\n=========================\n*/\nconsole.log(10+5) // suma\nconsole.log(10-5)// resta\nconsole.log(10*5)// multiplicacion\nconsole.log(10/2)// division\nconsole.log(10 % 3)// Módulo\nconsole.log(2**3)// potencia\nlet i=1; i++; i--; //incremento y decremento \n\n/*\n=========================\n operadores logicos bit a bit\n=========================\n*/\n// AND (&): Devuelve 1 si ambos bits son 1.\nconsole.log(5 & 1); // 0101 & 0001 = 0001 (1)\n\n// OR (|): Devuelve 1 si al menos uno de los bits es 1.\nconsole.log(5 | 1); // 0101 | 0001 = 0101 (5)\n\n// XOR (^): Devuelve 1 si los bits son diferentes.\nconsole.log(5 ^ 1); // 0101 ^ 0001 = 0100 (4)\n\n// NOT (~): Invierte todos los bits (operador unario).\nconsole.log(~5);    // ~0101 = ...1010 (-6 en complemento a dos)\n\n\n/*\n=========================\noperadores de desplazamiento bit a bit\n=========================\n*/\n// Desplazamiento a la izquierda (<<): Mueve bits a la izquierda y rellena con ceros.\nconsole.log(5 << 1); // 0101 -> 1010 (10)\n\n// Desplazamiento a la derecha con signo (>>): Mueve bits a la derecha manteniendo el signo.\nconsole.log(5 >> 1); // 0101 -> 0010 (2)\n\n// Desplazamiento a la derecha sin signo (>>>): Rellena con ceros sin importar el signo.\nconsole.log(-5 >>> 1); // Un número muy grande (32-bit unsigned)\n\n/*\n=========================\n operadores logicos\n=========================\n*/\nconsole.log(true && false);// AND\nconsole.log(true || false);// OR\nconsole.log(!true);// NOT\n/*\n=========================\n operadores de cadena\n=========================\n*/\nconsole.log(\"Hola \" + \"JavaScript\");// Concatenación\n/*\n=========================\n operadores de ternario\n=========================\n*/\nlet resultado = (10 > 5) ? \"Es mayor\" : \"Es menor\";\nconsole.log(resultado);\n/*\n=========================\n operadores de relacionales\n=========================\n*/\nconsole.log(\"name\" in {name: \"Friedrich\"}); // in: comprueba propiedad en objeto\nconsole.log([1, 2] instanceof Array);      // instanceof: comprueba tipo de objeto\n\n\n\n/*\n=====================\nEstructura de control\n=====================\n*/\n//condicionales\nif(true){} else if(false){} else{}\nswitch(1){case 1: break; default: break;}\n\n// iterativas\nwhile(false){}\ndo{} while(false)\nfor(let i = 1; i!=1; i++){}\nfor (let item of [1,2]) {} // for ... of\nfor (let key in {a:1}) {} // for in\n\n// Excepciones (Manejo de errores)\ntry { throw new Error(\"Error de sistema\"); } \ncatch (e) { console.log(e.message); } \nfinally { console.log(\"Finalizado\"); }\n\n//DIFICULTAD EXTRA\nconsole.log('DIFICULTAD EXTRA')\nfor(let i = 10; i<=55; i+=2){\n    if(i != 16 && i%3 !=0){\n        console.log(i)\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/franciscoRocha.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n// OPERADORES ARITMÉTICOS\nconst suma = 5 + 5;\nconst resta = 9 - 5;\nconst multiplicacion = 2 * 5;\nconst division = 10 / 2;\nconst modulo = 10 % 3;\nconsole.log(\"Aritméticos:\", suma, resta, multiplicacion, division, modulo);\n\n// OPERADORES LÓGICOS\nconst and = true && false;\nconst or = true || false;\nconst not = !true;\nconsole.log(\"Lógicos:\", and, or, not);\n\n// OPERADORES DE COMPARACIÓN\nconst igual = 4 == 4;\nconst diferente = 4 != 5;\nconst mayor = 5 > 4;\nconst menor = 4 < 5;\nconst mayorIgual = 5 >= 4;\nconst menorIgual = 4 <= 5;\nconst estricto = 4 === '4';\nconst noEstricto = 4 !== '4';\nconsole.log(\"Comparación:\", igual, diferente, mayor, menor, mayorIgual, menorIgual, estricto, noEstricto);\n\n// OPERADORES DE ASIGNACIÓN\nlet x = 5;\nx += 9;\nx -= 4;\nx *= 2;\nx /= 3;\nx %= 5;\nconsole.log(\"Asignación:\", x);\n\n// OPERADORES DE PERTENENCIA\nconst persona = { nombre: \"Juan\", edad: 25 };\nconsole.log(\"Pertenencia:\", \"nombre\" in persona, \"apellido\" in persona);\n\nclass Animal {}\nclass Perro extends Animal {}\nconst dog = new Perro();\nconsole.log(\"Instanceof:\", dog instanceof Perro, dog instanceof Animal, dog instanceof Object, dog instanceof Array);\n\n// OPERADORES DE BITS\nlet a = 5;   // 00000101\nlet b = 3;   // 00000011\nconsole.log(\"Bits:\", a & b, a | b, a ^ b, ~a, a << 1, a >> 1, a >>> 1);\n\n// CONDICIONALES\nlet edad = 18;\nif (edad >= 18) {\n    console.log(\"Eres mayor de edad\");\n} else {\n    console.log(\"Eres menor de edad\");\n}\n\n// SWITCH\nlet dia = 3;\nswitch (dia) {\n    case 1: console.log(\"Lunes\"); break;\n    case 2: console.log(\"Martes\"); break;\n    case 3: console.log(\"Miércoles\"); break;\n    default: console.log(\"Día no válido\");\n}\n\n// BUCLE FOR\nfor (let i = 1; i <= 5; i++) {\n    console.log(\"Número:\", i);\n}\n\n// BUCLE WHILE\nlet contador = 3;\nwhile (contador > 0) {\n    console.log(\"Contador:\", contador);\n    contador--;\n}\n\n// BUCLE DO WHILE\nlet num = 0;\ndo {\n    console.log(\"Número en do-while:\", num);\n    num++;\n} while (num < 3);\n\n// ITERANDO UN ARRAY CON forEach\nconst numeros = [10, 20, 30];\nnumeros.forEach(num => console.log(\"forEach:\", num));\n\n// USANDO MAP\nconst dobles = numeros.map(num => num * 2);\nconsole.log(\"Map:\", dobles);\n\n// MANEJO DE EXCEPCIONES\ntry {\n    let resultado = 10 / 0;\n    if (!isFinite(resultado)) {\n        throw new Error(\"División por cero detectada\");\n    }\n} catch (error) {\n    console.log(\"Error:\", error.message);\n} finally {\n    console.log(\"Fin del bloque try-catch\");\n}\n\n//Crea un programa que imprima por consola todos los números comprendidos\n//entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\nfor ( let i = 10; i <= 55; i++){\n    if( i % 2 === 0 && i !== 16 && i % 3 !== 0){\n        console.log(`${i}`);\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/frankqv.js",
    "content": "// #01 Javasript  \n// 🌐 EJEMPLO DE OPERADORES Y ESTRUCTURAS DE CONTROL EN JAVASCRIPT\n\nconsole.log(\"🌐 OPERADORES Y ESTRUCTURAS DE CONTROL EN JAVASCRIPT\\n\")\n\n// 🌟 Operadores\n/*\n * - Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits.\n */\n// 1. Operadores Aritméticos\nconsole.log(\"\\n1. Operadores aritméticos\")\nlet a = 19, b= 37;\nconsole.log(`\nSuma:            ${a} + ${b} = ${a + b}\nResta:           ${a} - ${b} = ${a - b}\nMultiplicacion:  ${a} * ${b} = ${a * b}\nDivisión:        ${a} / ${b} = ${a / b}\nMódulo(residuo): ${a} % ${b} = ${a % b}\nExponente:       ${a} ^ ${b} = ${a ** b}\n`);\n\n\n// 2. Operadores Lógicos\nconsole.log(\"\\n2. Operadores Lógicos:\");\nlet x = true, y = false;\nconsole.log(\"x = true, y = false;\");\nconsole.log(`AND (&&):  ${x} AND ${y} =`, x && y);   // false, porque uno de los valores es false\nconsole.log(`OR (||):   ${x} OR ${y} =`, x || y);    // true, porque al menos uno de los valores es true\nconsole.log(`NOT (!):  NOT ${x} =`, !x);        // false, invierte el valor de x\n\n\n// 3. Operadores de Comparación\nconsole.log(\"\\n4. Operadores de Comparación:\");\nconsole.log(`Igual a (==): ${a} == ${b}=`, a == b);   // Igualdad\nconsole.log(`Diferente a (!=): ${a} != ${b}`, a != b); // Desigualdad\nconsole.log(`Mayor que (>): ${a} > ${b}`, a > b);    // Mayor que\nconsole.log(`Menor que (<): ${a} < ${b}`, a < b);    // Menor que\nconsole.log(`Mayor o igual que (>=): ${a} >= ${b}`, a >= b); // Mayor o igual\nconsole.log(`Menor o igual que (<=): ${a} <= ${b}`, a <= b); // Menor o igual\n\n\n// 4. Operadores de Asignación Aritméticos\nconsole.log(\"\\n 4. Operadores de Asignación Aritméticos:\");\nlet z = 7; \nz += 3; console.log(\"z += 3:\", z); // z = 10\nz -= 2; console.log(\"z -= 2:\", z); // z = 8\nz *= 2; console.log(\"z *= 2:\", z); // z = 16\nz /= 4; console.log(\"z /= 4:\", z); // z = 4\nz %= 3; console.log(\"z %= 3:\", z); // z = 1\nz **= 3; console.log(\"z **= 3:\", z); // z = 1\n\n\n// Operadores bit a bit y asignación\nconsole.log(\"\\nOperadores bit a bit y asignación:\");\nlet bitX = 5; // 5 en binario: 0101\nbitX &= 6; console.log(\"bitX &= 6:\", bitX); // AND\n/* 6 en binario es 0110\n * Operación AND bit a bit: 0101 & 0110 = 0100 (en decimal, 4) */\nbitX = 4; bitX |= 2; console.log(\"bitX |= 2:\", bitX); // OR\n/* 4 en binario es 0100\n * 2 en binario es 0010\n * Operación OR bit a bit: 0100 | 0010 = 0110 (en decimal, 6) */\nbitX = 6; bitX ^= 3; console.log(\"bitX ^= 3:\", bitX); // XOR\n/* 6 en binario es 0110\n * 3 en binario es 0011\n * Operación XOR bit a bit: 0110 ^ 0011 = 0101 (en decimal, 5) */\nbitX = 5; bitX <<= 2; console.log(\"bitX <<= 2:\", bitX); // Shift Left\n/* 5 en binario es 0101\n * Desplanumber_Xar 2 posiciones a la inumber_Xquierda: 0101 << 2 = 10100 (en decimal, 20) */\nbitX = 20; bitX >>= 2; console.log(\"bitX >>= 2:\", bitX); // Shift Right\n/* 20 en binario es 10100\n * Desplanumber_Xar 2 posiciones a la derecha: 10100 >> 2 = 0101 (en decimal, 5) */\nbitX = -20; bitX >>>= 2; console.log(\"bitX >>>= 2:\", bitX); // Shift Right sin signo\n/* En binario (32 bits), -20 es representado como 11111111111111111111111111101100\n * Desplanumber_Xar 2 posiciones a la derecha sin signo: 00111111111111111111111111111011 (en decimal, 1073741819) */\n\n\n\n// 5. Operadores de Identidad\nconsole.log(\"\\n 5. Operadores de Identidad:\");\nlet obj1 = {a: 1};\nlet obj2 = {a: 1};\n\n// Verifica si tienen el mismo valor\nconsole.log(`Igualdad (==): obj1 == obj2 = `, obj1 == obj2);     // false, también porque son dos objetos distintos\n\n// Verifica si son el mismo objeto\nconsole.log(`Identidad (===): obj1 === obj2 =`, obj1 === obj2);  // false, porque son dos objetos distintos\n\n\n\n\n//6. Operadores de Pertenencia\nlet obj = {a: 1};\n// Verifica si una propiedad existe en un objeto\nconsole.log(\"'a' in obj:\", \"a\" in obj);  // true, porque la propiedad 'a' existe en obj\n\nlet arr = [1, 2, 3];\nconsole.log(\"arr.includes(2):\", arr.includes(2)); // true, porque 2 está en el arreglo\n\n\n//7. Operadores de Bits\nlet p = 5, q = 3; // 5 es 0101 en binario, 3 es 0011\nconsole.log(\"AND (&):\", p & q); // 0101 & 0011 = 0001 (1 en decimal)\nconsole.log(\"OR (|):\", p | q);  // 0101 | 0011 = 0111 (7 en decimal)\nconsole.log(\"XOR (^):\", p ^ q); // 0101 ^ 0011 = 0110 (6 en decimal)\n\n\n// 8. Operador Ternario (forma corta de un if-else)\nlet edad = 18;\nlet resultado = edad >= 18 ? \"Mayor de edad\" : \"Menor de edad\";\nconsole.log(resultado);  // \"Mayor de edad\"\n\n\n\n\n\n// 🌟 Estructuras de Control\n/*\n * - Condicionales (if, else if, else), Condicional con operadores lógicos, \n *   Switch, Bucles (for, while), Excepciones (try, catch, throw)\n */\n\n// 1. Condicionales (if, else if, else)\nconsole.log(\"\\nEstructuras Condicionales (if, else if, else) - Tu Destino Numerado:\");\nlet numero = Math.floor(Math.random() * 5) + 1; // Asigna un número aleatorio entre 1 y 5.\nconsole.log(`Tu número del destino es: ${numero}`);\nif (numero === 1) {\n    console.log(\"✨ Has recibido la bendición de un sabio. Tu camino está iluminado por estrellas eternas.\");\n} else if (numero === 2) {\n    console.log(\"⚔️ Encontraste una espada antigua enterrada en la roca. Ahora eres el elegido para liderar una guerra legendaria.\");\n} else if (numero === 3) {\n    console.log(\"🌊 Un barco pirata aparece y te invita a una aventura en alta mar. ¡Cuidado con los tiburones!\");\n} else if (numero === 4) {\n    console.log(\"🔥 El suelo tiembla y un volcán emerge frente a ti. Solo el más valiente puede cruzarlo.\");\n} else if (numero === 5) {\n    console.log(\"🌌 Una puerta dimensional se abre ante ti. ¿Te atreverás a entrar y explorar lo desconocido?\");\n} else {\n    console.log(\"🤔 Parece que tu destino es incierto. El universo espera que tomes una decisión pronto.\");\n}\n\n\n// 2. Estructura de control condicional (switch)\nconsole.log(\"\\nEestructura de control condicional Switch - Tu día de la semana:\");\nlet dia = Math.floor(Math.random() * 7) + 1; // Asigna un número aleatorio entre 1 y 7 para simular los días de la semana.\nswitch(dia) {\n    case 1: console.log(\"☀️ Hoy es Lunes. El inicio de una nueva semana llena de oportunidades.\");\n        break;\n    case 2: console.log(\"🌱 Hoy es Martes. El día perfecto para sembrar las semillas de tus sueños.\");\n        break;\n    case 3: console.log(\"🌞 Hoy es Miércoles. La mitad de la semana, sigue avanzando.\");\n        break;\n    case 4: console.log(\"🌟 Hoy es Jueves. El día ideal para planear la última parte de la semana.\");\n        break;\n    case 5: console.log(`🎉 Hoy es Viernes. El cuerpo lo sabe, no lo sabe hay que decirle que el cuerpo no se manda solo 💅🏻 Jajaja`);\n        break;\n    case 6: console.log(\"🌙 Hoy es Sábado. El día perfecto para descansar y recargar energías.\");\n        break;\n    case 7: console.log(\"🌌 Hoy es Domingo. Un día para reflexionar y prepararse para la semana que viene.\");\n        break;\n    default:\n        console.log(\"❗ Error: Día inválido.\");\n}\n\n\n// 3. Iterativas (for, while, do-while)\nconsole.log(\"\\nEstructuras Iterativas:\");\n// Bucle FOR\nfor (let i = 0; i < 5; i++) {\n    console.log(\"Iteración con FOR:\", i);\n}\n\n// Bucle WHILE\nlet contador = 0;\nwhile (contador < 3) {\n    console.log(\"Iteración con WHILE:\", contador);\n    contador++;\n}\n\n// Bucle DO-WHILE\nlet num = 0;\ndo {\n    console.log(\"Iteración con DO-WHILE:\", num);\n    num++;\n} while (num < 2);\n\n// 4. Manejo de excepciones\nconsole.log(\"\\nManejo de Excepciones:\");\nconsole.log(\"\\nExcepciones:\");\ntry {\n    let resultado = 10 / 0; // Aunque no genera error, podemos lanzar uno manual\n    if (!isFinite(resultado)) {\n        throw new Error(\"¡No se puede dividir por cero!\");\n    }\n} catch (error) {\n    console.error(\"Error capturado:\", error.message);\n} finally {\n    console.log(\"Esto siempre se ejecuta.\");\n}\n\n\n\n\n // 🌟 DIFICULTAD EXTRA: Imprimir números entre 10 y 55 (incluidos), pares, que no sean 16 ni múltiplos de 3\nconsole.log(`\\nDIFICULTAD EXTRA: Imprimir números entre 10 y 55 (incluidos), pares, que no sean 16 ni múltiplos de 3\nNúmeros entre 10 y 55 (pares, excluyendo el 16 y múltiplos de 3):\n`);\nfor (let num = 10; num <= 55; num++) {\n    if (num % 2 === 0 && num !== 16 && num % 3 !== 0) {\n        console.log(num);\n    }\n}\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/fravelz.js",
    "content": "/** OPERADORES ****************************************************************/\n\n// Operadores Aritméticos (+,-,*,/,%)\nlet num1 = 15;\nlet num2 = 5;\n\nlet suma = num1 + num2;\nlet resta = num1 - num2;\nlet multiplicacion = num1 * num2;\nlet division = num1 / num2;\nlet resto = num1 % num2;\nlet exponencial = num1 ** num2;\n\n// Operadores Lógicos (||, &&, !)\n/*\n * Operadores Lógicos (||, &&, !)\n * || → OR → Si al menos una de las condiciones es verdadera, el resultado es verdadero.\n * && → AND → Si todas las condiciones son verdaderas, el resultado es verdadero.\n * ! → NOT → Invierte el valor lógico de una expresión. Si la expresión es verdadera, se vuelve falsa, y viceversa.\n */\n\nlet x = true;\nlet y = false;\nlet z = true;\n\nlet logico1 = x && y && z;\nlet logico2 = x || y || z;\nlet logico3 = ((x || !y) && z) || (!x && z);\n\n\n// Operadores de Comparación (<, <=, >=, >, ==, ===, !=, !==)\nlet n1 = 16;\nlet n2 = 8;\nlet n3 = \"16\";\n\nlet comparacion1 = n1 > n2;\nlet comparacion2 = n1 < n2;\nlet comparacion3 = n1 >= n2;\nlet comparacion4 = n1 <= n2;\nlet comparacion5 = n1 == n3;\nlet comparacion6 = n1 != n3;\nlet comparacion7 = n1 === n3;\nlet comparacion8 = n1 !== n3;\n\n// Operadores de Asignación (=, +=, -=, *=, /=, %=, **=)\nlet a = 10;\na += 5; // a = a + 5 → a = 10 + 5 → a = 15\na -= 3; // a = a - 3 → a = 15 - 3 → a = 12\na *= 2; // a = a * 2 → a = 12 * 2 → a = 24\na /= 4; // a = a / 4 → a = 24 / 4 → a = 6\na %= 4; // a = a % 4 → a = 6 % 4 → a = 2\na **= 3; // a = a ** 3 → a = 2 ** 3 → a = 8\n\n--a; // a = a - 1 → a = 8 - 1 → a = 7\na--; // a = a - 1 → a = 7 - 1 → a = 6\n++a; // a = a + 1 → a = 6 + 1 → a = 7\na++; // a = a + 1 → a = 7 + 1 → a = 8\n\n// Operadores bit a bit\nlet var1 = 10; // 1010\nlet var2 = 3; // 0011\n\nlet opeacionBit1 = var1 & var2; // 0010 - Si ambos son 1\nlet opeacionBit2 = var1 | var2; // 1011 - Si almenos 1 es 1\nlet opeacionBit3 = var1 ^ var2; // 1001 -  Si los bits son diferentes 0 si son iguales 1\nlet opeacionBit4 = ~var1; // 0101 -  Invierte el valor bit a bit\nlet opeacionBit5 = var1 >> 2; // 1010 → 0101 → 0010\nlet opeacionBit6 = var1 << 2; // 1010 → 101000\n\n/** ESTRUCTURAS DE CONTROL ****************************************************/\n\n// Condicionales\nconst MAYORIA_EDAD = 18;\nlet edad_persona = 23;\n\nif (edad_persona < 0 || edad_persona > 120) {\n    console.log(`Edad inexistene, ingrese un valor correcto`);\n\n} else if (edad_persona < MAYORIA_EDAD) {\n    console.log(`Con ${edad_persona} años sos menor de edad`);\n\n} else {\n    console.log(`Con ${edad_persona} años sos mayor de edad`);\n}\n\n//Switch\n\nlet opcion = 2;\n\nswitch (opcion) {\n    case 1:\n        console.log(\"Opción 1\");\n        break;\n\n    case 2:\n        console.log(\"Opción 2\");\n        break;\n\n    case 3:\n        console.log(\"Opción 3\");\n        break;\n\n    default:\n        console.log(\"Debes ingresar una de las 3 opciones\");\n        break;\n}\n\n//Bucle For\n\nfor (let i = 0; i < 10; i++) {\n    console.log(`i = ${i}`);\n}\n\n//Bucle While\n\nlet j = 10;\nwhile (j-- > 5) {\n    console.log(`j = ${j}`);\n}\n\n//Bucle Do-while\nlet tiene_permiso = false;\n\ndo {\n    console.log(\"No tienes permiso\");\n\n    //Usando variables anteriormente creadas\n    if (edad_persona > MAYORIA_EDAD) {\n        tiene_permiso = true;\n        console.log(\"Ahora si tienes permiso\");\n    }\n\n} while ((tiene_permiso = false));\n\n// DIFICULTAD EXTRA\nfor (let i = 10; i <= 55; i++) {\n    if (!(i&1) && i != 16 && i % 3 !== 0) {\n        console.log(i);\n    }\n}\n\n// > Autor: Fravelz\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/garos01.js",
    "content": "// operadores aritmeticos\nlet a = 5;\nlet b = 3;\nlet suma = a + b;\nlet resta = a - b;\nlet multiplicacion = a * b;\nlet division = a / b;\nlet modulo = a % b;\nlet potencia = a ** b;\n\nconsole.log(suma, resta, multiplicacion, division, modulo, potencia);\n\n// Operadores de comparación\nlet igual = a == b;\nlet diferente = a != b;\nlet mayor_que = a > b;\nlet menor_que = a < b;\n\n// Operadores lógicos\nlet and_logico = a > b && a < 20;\nlet or_logico = a < b || b > 0;\nlet not_logico = !(a == b);\n\nconsole.log(\n  igual,\n  diferente,\n  mayor_que,\n  menor_que,\n  and_logico,\n  or_logico,\n  not_logico\n);\n\n// Operadores de asignacion\nlet c = 5;\nc += 3;\nconsole.log(c);\n\nlet array1 = [1, 2, 3];\nlet array2 = [1, 2, 3];\n\n// Operadores de identidad\nlet identidad = array1 === array2;\nlet no_identidad = array1 !== array2;\n\n// Operadores de pertenencia\nlet pertenece = 1 in array1;\nlet no_pertenece = !(4 in array1);\n\nconsole.log(identidad, no_identidad, pertenece, no_pertenece);\n\n// Operadores a nivel de bits\nlet bitwise_and = a & b;\nlet bitwise_or = a | b;\nlet bitwise_xor = a ^ b;\nlet bitwise_not_a = ~a;\nlet left_shift = a << 1;\nlet right_shift = a >> 1;\n\nconsole.log(\n  bitwise_and,\n  bitwise_or,\n  bitwise_xor,\n  bitwise_not_a,\n  left_shift,\n  right_shift\n);\n\n// Estructuras de control\n// Condicional\nlet edad = 18;\n\nif (edad >= 18) {\n  console.log(\"Eres mayor de edad\");\n} else {\n  console.log(\"Eres menor de edad\");\n}\n\n// Iterativas\nfor (let i = 0; i < 5; i++) {\n  console.log(i);\n}\n\nwhile (edad < 21) {\n  console.log(\"Eres menor de 21 años\");\n  edad++;\n}\n\n// Excepciones\ntry {\n  let resultado = 10 / 0;\n} catch (error) {\n  console.log(\"Error: División por cero\");\n} finally {\n  console.log(\"Este bloque se ejecuta siempre\");\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/gerardovguzman.js",
    "content": "// BASIC OPERATORS\n// Arithmetic Operators\nconsole.log(`Suma: 10 + 3 = ${10 + 3}`)\nconsole.log(`Resta: 10 - 3 = ${10 - 3}`)\nconsole.log(`Multiplicación: 10 * 3 = ${10 * 3}`)\nconsole.log(`División: 10 / 3 = ${10 / 3}`)\nconsole.log(`Módulo: 10 % 3 = ${10 % 3}`)\nconsole.log(`Exponente: 10 ** 3 = ${10 ** 3}`)\n\n// Assignment Operators\nmyNumber = 11\nconsole.log(myNumber)\nmyNumber += 1  // adds and assigns\nconsole.log(myNumber)\nmyNumber -= 1  // subtracts and assigns\nconsole.log(myNumber)\nmyNumber *= 1  // multiplies and assigns\nconsole.log(myNumber)\nmyNumber / 2  // divides and assigns\nconsole.log(myNumber)\nmyNumber %= 3  // module and assigns\nconsole.log(myNumber)\nmyNumber **= 2 // exponent and assigns\nconsole.log(myNumber)\n\n// Unary Operators\nmyVariable = 3\nconsole.log(myVariable)\nmyVariable ++ // uses the value, and then increments\nconsole.log(myVariable)\nmyVariable -- // uses the value, and then decrements\nconsole.log(myVariable)\n++ myVariable // increments the value and then uses it\nconsole.log(myVariable)\n-- myVariable // decrements the value and then uses it\nconsole.log(myVariable)\n- myVariable // changes sign (denies) to \n\n\n// COMPARISON OPERATORS\n// Equality Operators\nconsole.log(`Igualdad: 10 == 3 = ${10 == 3}`) // checks equal value, not data type \nconsole.log(`Desigualdad: 10 != 3 = ${10 != 3}`) // checks if the value of a is not equal to that of b, does not check data type\nconsole.log(`Igualdad: 10 > 3 = ${10 > 3}`) // checks if the value of a is greater than that of b\nconsole.log(`Igualdad: 10 >= 3 = ${10 >= 3}`) // checks if the value of a is greater than or equal to that of b\nconsole.log(`Igualdad: 10 < 3 = ${10 < 3}`) // check if the value of a is less than that of b\nconsole.log(`Igualdad: 10 <= 3 = ${10 <= 3}`) // checks if the value of a is less than or equal to that of b\n\n// Identity Operators\nmyNewNumber = 1.0\nconsole.log(`My number is myNewNumber es ${myNumber === myNewNumber}`)  // checks if the value and data type of a is equal to that of b\nconsole.log(`My number is not myNewNumber es ${myNumber !== myNewNumber}`)  // checks if the value and data type of a is not equal to that of b\n\n\n// LOGICAL OPERATORS\nconsole.log(`AND: 10 + 3 = 13 && 5 - 1 = 4 ${10 + 3 == 13 && 5 - 1 == 4}`)\nconsole.log(`OR: 10 + 3 = 13 || 5 - 1 = 2 ${10 + 3 == 13 || 5 - 1 == 2}`)\nconsole.log(`NOT: 10 + 3 = 14 ${10 + 3 != 14}`)\n\n// IN - NOT IN OPERATOR\nlet myName = \"gera\";\nconsole.log(`g in gera: ${myName.includes(\"g\")}`) // true\n\nlet myName2 = \"gera\";\nconsole.log(`x not in gera: ${!myName2.includes(\"x\")}`) // true, because \"x\" is not in \"gera\"\n\n// BIT OPERATORS\na = 10  // 1010\nb = 3   // 0011\nconsole.log(`AND: 10 & 3: ${10 & 3}`)  // # 0010  this equals to 2\nconsole.log(`OR: 10 | 3: ${10 | 3}`)   // # 1022  this equals to 11\nconsole.log(`XOR: 10 ^ 3: ${10 ^ 3}`)  // # 1001  this equals to 9\nconsole.log(`NOT: ~10: ${~10}`)  // #             this equals to -11\nconsole.log(`Desplazamientoa a la derecha: 10 >> 2: ${10 >> 2}`)  // # 0010       this equals to 2\nconsole.log(`Desplazamientoa a la izquierda: 10 << 2: ${10 << 2}`)  // # 101000   this equals to 40\n\n\n/***************************\n * ESTRUCTURAS DE CONTROL  *\n ***************************/\n// CONDICIONALES\n// IF\nlet myString = \"gerardov\"\n\nif (myString == \"gerardov\"){\n    console.log(\"myStrins es 'gerardov'\")\n} else if (myString == \"guzman\"){\n    console.log(\"myString también es 'guzman'\")\n} else{\n    console.log(\"myString no es 'gerardov'\")\n}\n\n// ITERATIVAS\n// FOR\nfor (let i = 0; i < 5; i++) {\n    console.log(i);\n}\n\n// WHILE\nfor (let i = 0; i < 7; i++) {\n    console.log(i);\n}\n\n// MANEJO DE EXCEPCIONES\ntry {\n    console.log(3/d)\n} catch (error) {\n    console.log(\"Se ha producido un error, revisa la operación nuevamente.\")\n} finally {\n    console.log(\"Ha finalizado el informe de estado.\")\n}\n\n\n// EXTRA\nfor (let i = 10; i <= 55; i++){\n    if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n        console.log(i);\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/giovanyosorio.js",
    "content": "\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n// Arithmetic operators\n\n// Addition\nconsole.log(1 + 2); // 3\n\n// Subtraction\nconsole.log(1 - 2); // -1\n\n// Multiplication\nconsole.log(1 * 2); // 2\n\n// Division\nconsole.log(1 / 2); // 0.5\n\n// Modulus\nconsole.log(1 % 2); // 1\n\n// Increment\nlet a = 1;\nconsole.log(++a); // 2\n\n// Decrement\nlet b = 1;\nconsole.log(--b); // 0\n\n// Logical operators\n\n// AND\nconsole.log(true && true); // true\nconsole.log(true && false); // false\nconsole.log(false && false); // false\n\n// OR\nconsole.log(true || true); // true\nconsole.log(true || false); // true\nconsole.log(false || false); // false\n\n// NOT\nconsole.log(!true); // false\nconsole.log(!false); // true\n\n// Comparison operators\nconsole.log(1 == 1); // true\nconsole.log(1 != 1); // false\nconsole.log(1 === 1); // true\nconsole.log(1 !== 1); // false\nconsole.log(1 > 1); // false\nconsole.log(1 >= 1); // true\nconsole.log(1 < 1); // false\nconsole.log(1 <= 1); // true\n\n// Assignment operators\nlet c = 1;\nc += 1;\nconsole.log(c); // 2\n\n// Identity operators\nconsole.log(1 === 1); // true\nconsole.log(1 !== 1); // false\n\n// Membership operators\nconsole.log(1 in [1, 2, 3]); // true\nconsole.log(4 in [1, 2, 3]); // false\n\n// Bitwise operators\nconsole.log(1 & 1); // 1\nconsole.log(1 | 1); // 1\n\n// Conditional statements\nif (1 === 1) {\n  console.log(\"1 is equal to 1\");\n}\nelse {\n  console.log(\"1 is not equal to 1\");\n}\n\n// bits\nlet d = 1;\nd <<= 1;\nconsole.log(d); // 2\n\n// Iterative statements\nfor (let i = 0; i < 10; i++) {\n  console.log(i);\n}\n\n// Exception statements\ntry {\n  throw \"Error\";\n}\ncatch (e) {\n  console.log(e);\n}\nfinally {\n  console.log(\"Finally\");\n}\n\n// Extra\nfor (let i = 10; i <= 55; i++) {\n  if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n    console.log(i);\n  }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/glaboryp.js",
    "content": "let numero = 1\nconsole.log(numero++) // Operador de incremento sufijo\nconsole.log(++numero) // Operador de incremento prefijo\nconsole.log(numero--) // Operador de decremento sufijo\nconsole.log(--numero) // Operador de decremento prefijo\n\nlet numero1 = 3\nlet numero2 = 6\nconsole.log(numero1 + numero2) // Operador de adición o suma\nconsole.log(numero1 - numero2) // Operador de sustracción o resta\nconsole.log(numero1 / numero2) // Operador de división\nconsole.log(numero1 * numero2) // Operador de multiplicación\nconsole.log(numero1 % numero2) // Operador de residuo\nconsole.log(numero1 ** numero2) // Operador de exponenciación\n\nconsole.log(numero1 < numero2) // Operador menor que\nconsole.log(numero1 <= numero2) // Operador menor o igual que\nconsole.log(numero1 > numero2) // Operador mayor que\nconsole.log(numero1 >= numero2) // Operador mayor o igual que\nconsole.log(numero1 == numero2) // Operador igualdad\nconsole.log(numero1 === numero2) // Operador igualdad estricta\nconsole.log(numero1 != numero2) // Operador desigualdad\nconsole.log(numero1 !== numero2) // Operador desigualdad estricta\n\nlet booleano = true\nconsole.log(!booleano) // Operador NOT lógico\n\nlet booleano1 = true\nlet booleano2 = true\nconsole.log(booleano1 && booleano2) // Operador AND lógico\nconsole.log(booleano1 || booleano2) // Operador OR lógico\n\nconst objeto = { nombre: 'Gloria', apellidos: 'Labory' }\nconsole.log('nombre' in objeto) // El operador in determina si un objeto tiene una determinada propiedad\n\nconst dia = new Date(1996, 7, 25)\nconsole.log(dia instanceof Date) // El operador instanceof determina si un objeto es una instancia de otro objeto\n\nconsole.log(booleano1 ? 'Es verdadero' : 'Es falso')\n\nif (booleano1) {\n  console.log('booleano1 es verdadero')\n} else if (booleano2) {\n  console.log('booleano2 es verdadero y booleano1 es falso')\n} else {\n  console.log('Tanto booleano1 como booleano2 son falsos')\n}\n\nconst ejemplo = 'perro'\nswitch (ejemplo) {\n  case 'perro':\n    console.log('Es un perro')\n    break;\n\n  case 'gato':\n    console.log('Es un gato')\n    break;\n\n  case 'pez':\n    console.log('Es un pez')\n    break;\n\n  case 'tigre':\n    console.log('Es un tigre')\n    break;\n\n  default:\n    console.log('No se sabe que es')\n    break;\n}\n\nconst lista = [1, 5, 33, 4, 51, 9, 1, 82, 3]\nlet suma = 0\nfor (let index = 0; index < lista.length; index++) {\n  suma += lista[index]\n}\nconsole.log(suma)\n\nsuma = 0\nlista.forEach(element => {\n  suma += element\n})\nconsole.log(suma)\n\nlet n = 0\nlet x = 0\nwhile (n < 3) {\n  n++\n  x += n\n}\nconsole.log(n)\nconsole.log(x)\n\n/* \n  Crea un programa que imprima por consola todos los números comprendidos \n  entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n*/\nfor (let index = 10; index <= 55; index++) {\n  if(index !== 16 && index % 3 !== 0) {\n    console.log(index)\n  }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/gonzadev28.js",
    "content": "//Tipos de oparadores en javascript\n\n//Arimeticos\n\nlet num1 = 5;\nlet num2 = 2;\n\nconsole.log('OPERADORES ARITMETICOS');\nlet suma = (num1 + num2);\nconsole.log('El resultado de la suma es:', suma);//SUMA\nlet resta = (num1 - num2);\nconsole.log('El resultado de la resta es:', resta);//RESTA\nlet division = (num1 / num2);\nconsole.log('El resultado de la division es:', division);//DIVISION\nlet multiplicacion = (num1 * num2);\nconsole.log('El resultado de la multiplicacion es:', multiplicacion);//MULTIPLICACION\nlet resto = (num1 % num2);\nconsole.log('El resultado del resto es:', resto);//RESTO O MODULO\nlet potencia = (num1 ** num2);\nconsole.log('El resultado de la potencia es:', potencia);//POTENCIA\n\n//Logicos\n\nlet estudiante = true;\nlet programador = true;\n\nconsole.log('OPERADORES LOGICOS');\n//And \nconsole.log('Operador and', estudiante && programador); //Ambos deben ser true para que se cumpla \n//Or\nconsole.log('Operador Or', estudiante || programador); //Al menos una variable debe ser true \n//Not\nconsole.log('Operador Not', !estudiante); //Invierte el valor de la variable \n\n//Comparacion \n\nlet a = 10;\nlet b = 5\n\nconsole.log('OPERADORES DE COMPARACION');\nconsole.log(a > b); //Mayor que...\nconsole.log(a < b); //Menor que...\nconsole.log(a >= b); //Mayor o igual que...\nconsole.log(a <= b); //Menor o igual que...\nconsole.log(a == b); //Igual a...\nconsole.log(a != b); //Distinto que...\nconsole.log(a === 'numero'); //Compara con un string\nconsole.log(a !== 'numero'); //Compara con un string distinto \n\n//Asignacion\n\na += 5; //Aumenta valor en 5\na -= 3; //Disminuye valor en 3\nconsole.log('OPERADORES DE ASIGNACION');\nconsole.log(a);\n\n//Operadores de control de flujo\n\nconsole.log('OPERADOR IF');\n//IF\nif(num1 > num2){\n    console.log('Numero1 es mayor a Numero2')\n}\nconsole.log('OPERADOR ELSE');\n//ELSE\nif(num1 > num2){\n    console.log('Numero1 es mayor a Numero2');\n}else{\n    console.log('Numero1 es menor a Numero2');\n}\nconsole.log('OPERADOR ELSE IF');\n//ELSE IF \nif(num1 > num2){\n    console.log('Numero1 es mayor a Numero2');\n}else if(num1 < num2){\n    console.log('Numero1 es menor a Numero2');\n}else{\n    console.log('Numero1 es igual a Numero2');\n}\nconsole.log('OPERADOR WHILE');\n//WHILE\nlet contador = 1; //Declaracion de variable \n\nwhile(contador <= 5){\n    console.log(contador);\n    contador++;\n}\nconsole.log('OPERADOR DO WHILE');\n//DO WHILE\nlet contador2 = 1;\ndo{\n    console.log(contador2);\n    contador2++;\n}while(contador2 <= 3);\nconsole.log('OPERADOR FOR');\n//FOR\nlet numero = 9;\nfor(i=1; i <= numero; i++){\n    console.log(i);\n}\n\n/*DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.*/\n\nconsole.log('EJERCICIO EXTRA');\n\nfor(let j = 10; j <= 55; j++){\n    if(j % 2 === 0 && j !== 16 && j % 3 !== 0){\n        console.log(j);\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/gpinedaoviedo.js",
    "content": "/*-----Operadores Aritmeticos------ */\nlet num1, num2;\nnum1 = 88;\nnum2 = 12;\n\n//suma\nlet suma = num1 + num2;\nconsole.log(suma);\n\n//resta\nlet resta = num1 - num2;\nconsole.log(resta);\n\n//multiplicacion\nlet multi = num1 * num2;\nconsole.log(multi);\n\n//division\nlet division = num1 / num2;\nconsole.log(division);\n\n//modulo (resto de la division)\nlet restoDivision = num1 % num2;\nconsole.log(restoDivision);\n\n//incremento\nlet incremento = num2++;\nconsole.log(incremento);\n\n//dencremento\nlet dencremento = num1--;\nconsole.log(dencremento);\n\n//exponensiacion\nlet expo = num1**num2;\nconsole.log(expo);\n\n/*------Operadores de Asignacion-------- */\n\n//asignacion (=)\nlet num3 = num2;\nconsole.log(num3);\n\n//asignacion de suma (+=)\nconsole.log(num1+=num3);\n\n//asignacion de resta (-=)\nconsole.log(num1-=10);\n\n//asignacion de multiplicacion (*=)\nconsole.log(num1*=num3);\n\n//asignacion de division (/=)\nconsole.log(num1/num3);\n\n//asignacion de modulo (%=)\nconsole.log(num1%=num3);\n\n//asignacion de exponenciacion (**=)\nconsole.log(num1**=num3);\n\n/*------operadores de comparacion----- */\n\nlet text1 = \"Hello World!\";\nlet text2 = \"hello world!\";\nlet text3 = \"HELLO WORLD!\";\n\n//igualdad (==)\nconsole.log(text1==text2);\n\n//desigualdad (!=)\nconsole.log(text1!=text2);\n\n//estrictamente igual\nconsole.log(text1===text2);\n\n//estrictamente desigual\nconsole.log(text1!==text2);\n\n///////////////////////////\nlet num4 = 24;\nlet num5 = 20;\n\n//mayor que\nconsole.log(num4 > num5);\n\n//mayor o igual que\nconsole.log(num4 > num5);\n\n//menor que\nconsole.log(num4 < num5);\n\n//menor o igual que\nconsole.log(num4 <= num5);\n\n/*----Operadores Logicos----- */\n\n//AND\nconsole.log(text1&&text2);\n\n//OR\nconsole.log(text1||text2);\n\n//NOT\nconsole.log(!text1 === text2);\n\n/*-----Operadores de pertencia----- */\n\nconst persona = {\n    \"nombre\" : \"Alex\",\n    \"edad\" : 20\n};\n\n//in: prop in obj (devuelve verdadero si el objeto tiene la propiedad especificada)\nconsole.log(persona.edad in(persona));\n\n//instanceof: obj instanceof Tipo (devuelve verdadero si el objeto es una instancia del tipo especificado)\nconsole.log(persona instanceof(Object));\n\n\n/*---Estructuras de control---- */\n\n//if, else if, else\n\nnum1 > num2 ? console.log(`${num1} es menor que ${num2}`) \n? num1 < num2 : console.log(`${num1} es mayor que ${num2}`)\n: console.log('operacion no completada');\n\n//switch\nlet dia = ['lunes',\"martes\",\"miercoles\",\"jueves\",\"viernes\",\"sabado\",\"domingo\"];\n\nswitch (dia[1]) {\n    case 'lunes':\n        console.log(`Hoy es ${dia[0]}`);\n        break;\n\n    case 'martes' : \n    console.log(`Hoy es ${dia[1]}`);\n    break;\n\n    case 'martes' : \n    console.log(`Hoy es ${dia[2]}`);\n    break;\n\n    default:\n        break;\n}\n\n//bucles: for\n\nfor (let i = 0; i < 8; i++) {\n    if (i === 5) {\n        continue;\n    }  \n    console.log(\"Iteracion numero de for: \" + i);  \n}\n\n//bucles: while\nlet num = 0;\nwhile (num < 5) {\n    console.log(\"Iteracion numero de while:\" + num);\n    num++;\n}\n\n//bucles: do while\nlet n = 0;\ndo {\n    console.log(\"Iteracion numero de do-while:\" + n);\n    n++;\n} while (n <= 10);\n\n//bucles: for...in\n\nconst listNumber = [\"alex\",2,3,4,5,6];\nfor (numero in listNumber) {\n    console.log(\"iTERACION BUCLE FOR...in: \" + numero);\n}\n\n//bucles: for...of\n\nconst listName = [\"alex\",\"kevin\",\"marino\",\"esteban\",\"cesar\"];\nfor (nombre of listName) {\n    console.log(\"iTERACION BUCLE FOR...OF: \" + nombre);\n}\n\n//exeptions try...catch\n\ntry {\n    let op = dividir(10,0);\n} catch (error) {\n    console.log(`Se ha producido un error: ${error}`);\n} finally {\n    console.log(\"Se ejecuta siempre.\");\n}\n\n\n/*Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3. */\n\nconst operacion = () => {\n    for (let i = 10; i <= 55 ; i++) {\n        if (i !== 16 && i % 2 === 0 && i % 3 !== 0 ){\n            console.log(\"Numero: \" + i);\n        } \n    }\n}\noperacion();\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/h4ckxel.js",
    "content": "\n// Operadores Aritméticos\n\nlet a = 10;\nlet b = 5;\n\nconsole.log(\"Suma:\", a + b);         // 15\nconsole.log(\"Resta:\", a - b);        // 5\nconsole.log(\"Multiplicación:\", a * b); // 50\nconsole.log(\"División:\", a / b);     // 2\nconsole.log(\"Módulo:\", a % b);       // 0\nconsole.log(\"Exponenciación:\", a ** b); // 100000\n\n\n\n\n\n\n\n// Operadores Lógicos\n\nlet x = true;\nlet y = false;\n\nconsole.log(\"AND lógico:\", x && y); // false\nconsole.log(\"OR lógico:\", x || y);  // true\nconsole.log(\"NOT lógico:\", !x);     // false\n\n\n\n\n\n\n// Operadores de Comparación\nlet p = 10;\nlet q = 20;\n\nconsole.log(\"Igual a:\", p == q);        // false\nconsole.log(\"No igual a:\", p != q);     // true\nconsole.log(\"Mayor que:\", p > q);       // false\nconsole.log(\"Menor que:\", p < q);       // true\nconsole.log(\"Mayor o igual que:\", p >= q); // false\nconsole.log(\"Menor o igual que:\", p <= q); // true\n\n\n\n\n\n\n\n// Operadores de Asignación\nlet n = 5;\n\nn += 3; // n = n + 3\nconsole.log(\"Asignación de suma:\", n); // 8\n\nn -= 2; // n = n - 2\nconsole.log(\"Asignación de resta:\", n); // 6\n\nn *= 4; // n = n * 4\nconsole.log(\"Asignación de multiplicación:\", n); // 24\n\nn /= 3; // n = n / 3\nconsole.log(\"Asignación de división:\", n); // 8\n\nn %= 2; // n = n % 2\nconsole.log(\"Asignación de módulo:\", n); // 0\n\n\n\n\n\n\n\n\n// Operadores de Identidad\n\nlet r = 5;\nlet s = \"5\";\n\nconsole.log(\"Identidad (igual):\", r === s); // false\nconsole.log(\"Identidad (no igual):\", r !== s); // true\n\n\n\n\n\n\n\n\n\n// Operadores de Pertenencia\n\nlet arr = [1, 2, 3, 4, 5];\n\nconsole.log(\"Pertenencia (en array):\", arr.includes(3)); // true\nconsole.log(\"Pertenencia (no en array):\", arr.includes(6)); // false\n\n\n\n\n\n\n\n// Operadores de Bits\n\nlet m = 5;  // 0101 en binario\nlet ñ = 3;  // 0011 en binario\n\nconsole.log(\"AND bit a bit:\", m & ñ); // 1 (0001 en binario)\nconsole.log(\"OR bit a bit:\", m | ñ);  // 7 (0111 en binario)\nconsole.log(\"XOR bit a bit:\", m ^ ñ); // 6 (0110 en binario)\nconsole.log(\"Complemento bit a bit:\", ~m); // -6 (invertido en binario)\nconsole.log(\"Desplazamiento a la izquierda:\", m << 1); // 10 (1010 en binario)\nconsole.log(\"Desplazamiento a la derecha:\", m >> 1); // 2 (0010 en binario)\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n// Condicionales\n\nlet age = 20;\n\nif (age < 18) {\n    console.log(\"Eres menor de edad.\");\n} else if (age >= 18 && age < 65) {\n    console.log(\"Eres adulto.\");\n} else {\n    console.log(\"Eres mayor de edad.\");\n}\n\n\n\n\n\n// Iterativas\n\n\n// Bucle for\nfor (let i = 0; i < 5; i++) {\n    console.log(\"Bucle for, iteración:\", i);\n}\n\n// Bucle while\nlet j = 0;\nwhile (j < 5) {\n    console.log(\"Bucle while, iteración:\", j);\n    j++;\n}\n\n// Bucle do-while\nlet k = 0;\ndo {\n    console.log(\"Bucle do-while, iteración:\", k);\n    k++;\n} while (k < 5);\n\n\n\n\n\n// Excepciones\n\ntry {\n    let result = 10 / 0;\n    if (!isFinite(result)) {\n        throw new Error(\"División por cero\");\n    }\n    console.log(\"Resultado:\", result);\n} catch (error) {\n    console.log(\"Error capturado:\", error.message);\n} finally {\n    console.log(\"Bloque finally ejecutado.\");\n}\n\n\n\n\n\n\n\n\n\n// * DIFICULTAD EXTRA (opcional):\n//   * Crea un programa que imprima por consola todos los números comprendidos\n//   * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n//   *\n//   * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\n    \nfunction imprimir_numeros(){\n    for ( let x = 10; x < 56; x++){\n        if (x >= 10 && x <=55 && x % 2 === 0 && x != 16 && x % 3 != 0) {\n            console.log(x)\n        }\n    }\n    \n}\nimprimir_numeros()\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/hatorob.js",
    "content": "const { error } = require(\"console\");\n\n//! Operadores aritmeticos\nlet number = 1;\n\nlet sum = 2 + 2;\nconsole.log(`sum - ${sum}`);\nlet res = 5 - 2;\nconsole.log(`res - ${res}`);\nlet mult = 5 * 2;\nconsole.log(`mult - ${mult}`);\nlet div = 9 / 2;\nconsole.log(`div - ${div}`);\nlet exp = 2 ** 2;\nconsole.log(`exp - ${exp}`);\nlet resid = 21 % 2;\nconsole.log(`resid - ${resid}`);\nlet incrementOptionOne = number++;\nconsole.log(`increment - ${incrementOptionOne}`);\nlet incrementOptionTwo = ++number;\nconsole.log(`increment - ${incrementOptionTwo}`);\nlet decrementOptionOne = number--;\nconsole.log(`decrement - ${decrementOptionOne}`);\nlet decrementOptionTwo = --number;\nconsole.log(`decrement - ${decrementOptionTwo}`);\n\n//! Operadores lógicos\n\n//!AND\nif( true && true ) console.log(\"si cumple ambas condiciones entro aquí\");\n//!OR\nif( false || true ) console.log(\"si cumple al menos una condicion entro aquí\");\n//! Negation\nif(!false) console.log(\"niego un boolean, si es falso estoy entrando\");\n\n\n//! comparación\nif( 20 < 30) console.log(`Si el num1 es menor a num2`);\nif( 20 <= 30) console.log(`Si el num1 es menor o igual a num2`);\nif( 20 > 10) console.log(`Si el num1 es mayor a num2`);\nif( 10 >= 10) console.log(`Si el num1 es mayor o igual a num2`);\nif( 10 == \"10\") console.log(`Si el num1 es igual a num2`);\nif( 10 === 10) console.log(`Si el num1 es identico a num2`);\nif( \"20\" != 10) console.log(`Si el num1 es diferent a num2`);\nif( \"20\" !== 20) console.log(`Si el num1 es diferente estricto a num2`);\n\n//! asignacion\n//! suma\nlet asig1 = 1;\nasig1 += 1\nconsole.log(asig1);\n//! resta\nlet asig2 = 1;\nasig2 -= 1\nconsole.log(asig2);\n//! multiplicacion\nlet asig3 = 1;\nasig3 *= 2\nconsole.log(asig3);\n//! division\nlet asig4 = 8;\nasig4 /= 2\nconsole.log(asig4);\n//! residuo\nlet asig5 = 8;\nasig5 %= 2\nconsole.log(asig5);\n//! Concatena string\nlet asig6 = \"hola\";\nasig6 += \" Mundo\"\nconsole.log(asig6);\n\n\n//! Estrcutura de control\n//! if\nif(2 == \"2\") {\n    // if con llavers\n}\n//! if de una sola linea\nif(2 == \"2\") console.log(\"entro al if de una sola linea\");\n//! if else\nif(2 > 10 ) {\n    close.log(\"entro al if 2\");\n} else {\n    console.log(\"entro al else\");\n}\n\n//! if, if else, else\n\nif(2 > 10) {\n    //! si cumple entro aqui\n} else if(4 == 4) {\n    console.log(\"entro al else if\");\n} else if( 6 == 7 ) {\n    //! otro else if\n} else {\n    //! else\n}\n\n//! if ternario\n(\"spiderman\" == \"spiderman\") ? console.log(\"user active\") : console.log(\"user inactive\");;\n\n//! switch\nlet search = \"hulk\";\nswitch (search) {\n    case \"hulk\":\n        console.log(`welcome hero ${search}`);\n        break;\n    case \"spiderman\":\n        console.log(`welcome hero ${search}`);\n    default:\n        console.log(`welcome to hero`);\n}\n\n\n//! iterativas\n\n//? for\nfor(let i = 0; i < 4; i++) {\n    console.log(`recorriendo un for ${i}`);\n}\n\n//! while\nlet j = 0;\nwhile( j <= 2 ) {\n    console.log(\"recorriendo un while, hasta que se cumpla una condicion\"); \n    j++;   \n}\nj = 0;\ndo {\n    console.log(\"recorriendo un do while, se ejecuta al menos una primera vez\");\n    j++;\n} while(j < 0)\n\n//! excepciones\n//* Dejo comentando throw new Error para que no saque el código\nlet brand = \"nike\";\ntry {\n    if( brand != \"adidas\" ) //throw new Error(`the brand ${brand} is not exists`)\n    //! si pasa el if sigo mi lógica\n    console.log(`the brand ${brand} is ok`);\n} catch (error) {\n    console.log(error);\n}\n\n\n\n//! EJERCICIO OPCIONAL\n/*\n* Crea un programa que imprima por consola todos los números comprendidos\n* entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n*/\n\nlet start = 10;\nlet limit = 55;\nfor( let i = start; i <= limit; i++ ){\n    if( (i % 2 == 0) && (i != 16) && (i % 3 != 0) ) console.log(i);\n}\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/hectorio23.js",
    "content": "// Autor: Héctor Adán \n// GitHub: https://github.com/hectoiro23\n\n\"use strict\";\n\n/*\n* EJERCICIO:\n* - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n*   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n*   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n* - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n*   que representen todos los tipos de estructuras de control que existan\n*   en tu lenguaje:\n*   Condicionales, iterativas, excepciones...\n* - Debes hacer print por consola del resultado de todos los ejemplos.\n*\n* DIFICULTAD EXTRA:\n* Crea un programa que imprima por consola todos los números comprendidos\n* entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n*\n* Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n*/\n\n// Operadores aritméticos\nconsole.log(\"******** OPERADORES ARITMÉTICOS ********\");\nconsole.log(\"SUMA: 4 + 5 =\", 4 + 5);\nconsole.log(\"RESTA: 4 - 5 =\", 4 - 5);\nconsole.log(\"MULTIPLICACIÓN: 4 * 5 =\", 4 * 5);\nconsole.log(\"DIVISIÓN: 4 / 5 =\", 4 / 5);\nconsole.log(\"DIVISIÓN ENTERA: 4 // 5 =\", Math.floor(4 / 5));\nconsole.log(\"MÓDULO: 4 % 5 =\", 4 % 5);\nconsole.log(\"POTENCIA: 4 ** 5 =\", 4 ** 5);\n\n// Operadores de comparación\nconsole.log(\"******** OPERADORES DE COMPARACIÓN ********\");\nconsole.log(\"IGUAL QUE: 4 == 5:\", 4 == 5);\nconsole.log(\"DIFERENTE DE: 4 != 5:\", 4 != 5);\nconsole.log(\"ESTRICTAMENTE IGUAL QUE: 4 === 5:\", 4 === 5);\nconsole.log(\"ESTRICTAMENTE DIFERENTE DE: 4 !== 5:\", 4 !== 5);\nconsole.log(\"MAYOR QUE: 4 > 5:\", 4 > 5);\nconsole.log(\"MENOR QUE: 4 < 5:\", 4 < 5);\nconsole.log(\"MAYOR O IGUAL QUE: 4 >= 5:\", 4 >= 5);\nconsole.log(\"MENOR O IGUAL QUE: 4 <= 5:\", 4 <= 5);\n\n// Operadores lógicos\nconsole.log(\"******** OPERADORES LÓGICOS ********\");\nconsole.log(\"AND: true && false:\", true && false);\nconsole.log(\"OR: true || false:\", true || false);\nconsole.log(\"NOT: !true:\", !true);\n\n// Operadores de asignación\nconsole.log(\"******** OPERADORES DE ASIGNACIÓN ********\");\nlet x = 5;\nconsole.log(\"x =\", x);\nx += 2;\nconsole.log(\"x += 2 ->\", x);\nx -= 1;\nconsole.log(\"x -= 1 ->\", x);\nx *= 3;\nconsole.log(\"x *= 3 ->\", x);\nx /= 2;\nconsole.log(\"x /= 2 ->\", x);\nx %= 4;\nconsole.log(\"x %= 4 ->\", x);\nx **= 2;\nconsole.log(\"x **= 2 ->\", x);\nx //= 3; // En JavaScript no hay operador de asignación para la división entera\n\n// Operadores de identidad\nconsole.log(\"******** OPERADORES DE IDENTIDAD ********\");\nlet a = [1, 2, 3];\nlet b = a;\nconsole.log(\"a === b:\", a === b);\nlet c = [...a];\nconsole.log(\"a === c:\", a === c);\nconsole.log(\"a == c:\", a == c);\n\n// Operadores de pertenencia\nconsole.log(\"******** OPERADORES DE PERTENENCIA ********\");\nconsole.log(\"1 in [1, 2, 3]:\", 1 in [1, 2, 3]); // Esto no funciona en JavaScript\nconsole.log(\"4 not in [1, 2, 3]:\", !(4 in [1, 2, 3])); // Esto tampoco funciona\n\n// Operadores a nivel de bits\nconsole.log(\"******** OPERADORES A NIVEL DE BITS ********\");\nconsole.log(\"AND: 4 & 5 =\", 4 & 5);\nconsole.log(\"OR: 4 | 5 =\", 4 | 5);\nconsole.log(\"XOR: 4 ^ 5 =\", 4 ^ 5);\nconsole.log(\"NOT: ~4 =\", ~4);\nconsole.log(\"Desplazamiento a la izquierda: 4 << 1 =\", 4 << 1);\nconsole.log(\"Desplazamiento a la derecha: 4 >> 1 =\", 4 >> 1);\n\n// Estructuras de control condicionales\nconsole.log(\"******** ESTRUCTURAS DE CONTROL CONDICIONALES ********\");\nif (x > 2) {\n    console.log(\"x es mayor que 2\");\n} else if (x == 2) {\n    console.log(\"x es igual a 2\");\n} else {\n    console.log(\"x es menor que 2\");\n}\n\n// Estructuras de control iterativas\nconsole.log(\"******** ESTRUCTURAS DE CONTROL ITERATIVAS ********\");\nconsole.log(\"Bucle for:\");\nfor (let i = 0; i < 3; i++) {\n    console.log(\"i =\", i);\n}\n\nconsole.log(\"Bucle while:\");\nlet n = 3;\nwhile (n > 0) {\n    console.log(\"n =\", n);\n    n--;\n}\n\n// Manejo de excepciones\nconsole.log(\"******** MANEJO DE EXCEPCIONES ********\");\ntry {\n    let resultado = 10 / 0;\n} catch (e) {\n    console.log(\"No se puede dividir por cero\");\n} finally {\n    console.log(\"Bloque finally ejecutado\");\n}\n\n// DIFICULTAD EXTRA\nconsole.log(\"******** DIFICULTAD EXTRA ********\");\nlet values = \"[ \";\nfor (let num = 10; num <= 55; num++) {\n    if (num % 2 === 0 && num !== 16 && num % 3 !== 0) {\n        values += num + \", \";\n    }\n}\n\nconsole.log(values + \"]\");\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/herwingx-dev.js",
    "content": "/*\n\nOPERADORES EN JAVASCRIPT\n\n\n*/\n\n// OPERADORES ARITMETICOS\nlet a = 5;\nlet b = 2;\n\nconsole.log(a + b); // 7\nconsole.log(a - b); // 3\nconsole.log(a * b); // 10\nconsole.log(a / b); // 2.5\nconsole.log(a % b); // 1\n\n// OPERADORES DE ASIGNACION\nlet c = 10;\nlet d = 5;\n\nc += d; // c = c + d\nconsole.log(c); // 15\n\nc -= d; // c = c - d\n\nc *= d; // c = c * d\n\nc /= d; // c = c / d\n\nc %= d; // c = c % d\n\n// OPERADORES DE COMPARACION\n\nlet e = 5;\n\nconsole.log(e == 5); // true\nconsole.log(e == \"5\"); // true\nconsole.log(e === \"5\"); // false\nconsole.log(e != \"5\"); // false\nconsole.log(e !== \"5\"); // true\nconsole.log(e > 5); // false\nconsole.log(e >= 5); // true\nconsole.log(e < 5); // false\n\n// OPERADORES LOGICOS\n\nlet f = 5;\nlet g = 10;\n\nconsole.log(f == 5 && g == 10); // true\nconsole.log(f == 5 && g == 5); // false\nconsole.log(f == 5 || g == 5); // true\nconsole.log(f == 5 || g == 10); // true\nconsole.log(f == 10 || g == 5); // false\nconsole.log(f == 10 || g == 10); // false\nconsole.log(!true); // false\nconsole.log(!false); // true\n\n// OPERADORES DE CONCATENACION\n\nlet h = \"Hola\";\nlet i = \"Mundo\";\n\nconsole.log(h + \" \" + i); // Hola Mundo\n\n// OPERADORES DE INCREMENTO Y DECREMENTO\n\nlet j = 5;\n\nconsole.log(j++); // 5\n\nconsole.log(j); // 6\n\nconsole.log(++j); // 7\n\nconsole.log(j); // 7\n\nconsole.log(j--); // 7\n\nconsole.log(j); // 6\n\nconsole.log(--j); // 5\n\n\n// ESTRUCTURAS DE CONTROL\n\n// IF \n\nlet k = 5;\n\nif (k == 5) {\n\n  console.log(\"k es igual a 5\");\n\n}\n\n// IF ELSE\n\nlet l = 10;\n\nif (l == 5) {\n\n  console.log(\"l es igual a 5\");\n\n}\n\nelse {\n\n  console.log(\"l no es igual a 5\");\n\n}\n\n// IF ELSE IF\n\nlet m = 10;\n\nif (m == 5) {\n\n  console.log(\"m es igual a 5\");\n\n}\n\n\nelse if (m == 10) {\n\n  console.log(\"m es igual a 10\");\n\n}\n\nelse {\n\n  console.log(\"m no es igual a 5 ni a 10\");\n\n}\n\n// SWITCH\n\n\nlet n = 5;\n\nswitch (n) {\n\n  case 5:\n\n    console.log(\"n es igual a 5\");\n    break;\n\n  case 10:\n\n    console.log(\"n es igual a 10\");\n    break;\n\n  default:\n\n    console.log(\"n no es igual a 5 ni a 10\");\n    break;\n\n}\n\n// FOR\n\nfor (let o = 0; o < 5; o++) {\n\n  console.log(o);\n\n}\n\n// WHILE\n\nlet p = 0;\n\nwhile (p < 5) {\n\n  console.log(p);\n  p++;\n\n}\n\n// DO WHILE\n\nlet q = 0;\n\ndo {\n\n  console.log(q);\n  q++;\n\n} while (q < 5);\n\n// BREAK\n\n\nfor (let r = 0; r < 5; r++) {\n\n  if (r == 3) {\n\n    break;\n\n  }\n\n  console.log(r);\n\n}\n\n// CONTINUE\n\nfor (let s = 0; s < 5; s++) {\n\n  if (s == 3) {\n\n    continue;\n\n  }\n\n  console.log(s);\n\n}\n\n// FUNCIONES\n\nfunction suma(t, u) {\n\n  return t + u;\n\n}\n\nconsole.log(suma(5, 10)); // 15 \n\n// FUNCIONES ANONIMAS\n\nlet suma2 = function (t, u) {\n\n  return t + u;\n\n}\n\nconsole.log(suma2(5, 10)); // 15\n\n// FUNCIONES FLECHA\n\nlet suma3 = (t, u) => t + u;\n\nconsole.log(suma3(5, 10)); // 15\n\n\n// FUNCIONES CON PARAMETROS POR DEFECTO\n\nfunction suma4(t = 0, u = 0) {\n\n  return t + u;\n\n}\n\nconsole.log(suma4(5)); // 5  \n\n// FUNCIONES CON PARAMETROS REST\n\nfunction suma5(t, u, ...v) {\n\n  let w = t + u;\n\n  v.forEach(x => w += x);\n\n  return w;\n\n}\n\nconsole.log(suma5(5, 10, 15, 20)); // 50\n\n// FUNCIONES CON PARAMETROS SPREAD\n\nfunction suma6(t, u, v, w) {\n\n  return t + u + v + w;\n\n}\n\nlet x = [5, 10, 15, 20];\n\n\nconsole.log(suma6(...x)); // 50\n\n\n// FUNCIONES CON OBJETOS COMO PARAMETROS\n\nfunction suma7(t) {\n\n  return t.a + t.b;\n\n}\n\nlet y = { a: 5, b: 10 };\n\nconsole.log(suma7(y)); // 15\n\n// FUNCIONES CON OBJETOS COMO PARAMETROS Y DESTRUCTURACION\n\n\nfunction suma8({ a, b }) {\n\n  return a + b;\n\n}\n\nlet z = { a: 5, b: 10 };\n\nconsole.log(suma8(z)); // 15\n\n// FUNCIONES CON OBJETOS COMO PARAMETROS Y DESTRUCTURACION Y PARAMETROS REST\n\nfunction suma9({ a, b, ...c }) {\n\n  let d = a + b;\n\n  Object.values(c).forEach(e => d += e);\n\n  return d;\n\n}\n\nlet obj1 = { a: 5, b: 10, c: 15, d: 20 };\n\nconsole.log(suma9(obj1)); // 50\n\n\nconsole.log(\"Numeros pares del 10 al 55\");\n\n\n/* \n DIFICULTAD EXTRA (opcional):\nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\nSeguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\n*/\nfor (let i = 10; i <= 55; i++) {\n  if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n    console.log(i);\n  }\n}\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/isaias-alt.js",
    "content": "\n//* Operadores aritméticos\nlet adition = 1 + 1\nlet subtraction = 2 - 1\nlet multiplication = 2 * 2\nlet division = 10 / 2\nlet module = 4 % 2 // <- retorna el resto de la division\nlet exponentiation = 2 ** 2 // <- eleva 2 a la potencia de dos\n\n//* Operadores de asignación\nlet a = 2\na += 2 // a = a + 2\na -= 2 // a = a - 2\na *= 2 // a = a * 2\na /= 2 // a = a / 2\na %= 2 // a = a % 2 <- se le asigna el resto de la division entre los dos\na **= 2 // a = a ** 2 <- a elevado a la potencia de 2\n\n//* Operadores de comparación\nlet y = 3;\nlet z = 2;\nlet w = 1;\nconsole.log(y == '4'); // igualdad de valores sin verificar el tipo\nconsole.log(y != 3); // diferencia de valores sin verificar el tipo\nconsole.log(y === 4); // igualdad de valores verificando el tipo\nconsole.log(y !== 3); // difierencia de valores verificando el tipo\nconsole.log(z > y); // comprueba si z es mayor que y\nconsole.log(z >= y); // comprueba si z es mayor o igual que y\nconsole.log(w < y); // comprueba si w es menor que y\nconsole.log(w <= y); // comprueba si w es mejor o igual que y\n\n//* Operadores lógicos\nlet age = 24;\nage > 18 ? console.log('Soy mayor de edad, una cerveza, por favor') : console.log('No soy mayor de edad'); // Operador condicional o ternario\n\n// AND (&&)\nconsole.log(true && true); // && devuelve verdadero si ambos operandos son verdaderos; de lo contrario, devuelve falso\n\n// OR (||) -> devuelve verdadero si almenos uno de los operandos es verdadero\nconsole.log(false || false); // devuelve false\nconsole.log(true || false); // devuelve true\nconsole.log(false || true); // devuelve true\nconsole.log(true || true); // devuelve true\n\n// Operador NOT (!) -> utilzado para el invertir (negar) valor de una variable. Si una variable vale true, al negarla valdrá false\nconsole.log(!true); // devuelve false\nconsole.log(!false); // devuelve true\n\n//* Condicionales y bucles (entructuras de control)\n\n//Condicionales \nlet edad = 18;\n\nif (edad >= 18) {\n  console.log(\"Puedes beber cerveza\");\n} else {\n  console.log(\"No puedes beber cerveza... aun\");\n}\n\n// Iterativas\nfor (let i = 1; i <= 5; i++) {\n  console.log(\"Iteración:\", i);\n}\n\nlet arrayIterativo = [1, 2, 3, 4, 5];\nfor (let elemento of arrayIterativo) {\n  console.log(\"Elemento:\", elemento);\n}\n\n// Excepciones\ntry {\n  let result = 10 / 0;\n  console.log(\"Resultado:\", result);\n} catch (error) {\n  console.error(\"Error:\", error.message);\n} finally {\n  console.log(\"Bloque finally ejecutado siempre.\");\n}\n\n// Switch\nlet diaDeLaSemana = \"Viernes\";\nswitch (diaDeLaSemana) {\n  case \"Lunes\":\n    console.log(\"Es el primer día de la semana. Hay que laburar lpm\");\n    break;\n  case \"Martes\":\n  case \"Miércoles\":\n  case \"Jueves\":\n    console.log(\"Estamos a mitad de semana.\");\n    break;\n  case \"Viernes\":\n    console.log(\"Fin de la semana laboral. Cerveza\");\n    break;\n  case \"Sábado\":\n  case \"Domingo\":\n    console.log(\"Proyectos propios, pelis y más cerveza\");\n    break;\n  default:\n    console.log(\"El dia no es valido.\");\n}\n\n\n//* Dificultad opcional\nfor (let i = 10; i <= 55; i++) {\n  if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n    console.log(\"Número\", i);\n  }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/jacarrillob.js",
    "content": "/* OPERADORES ARITMÉTICOS */\nconsole.log('*** OPERADORES ARITMÉTICOS ***\\n')\n\nlet num1 = 20\nlet num2 = 10\n\n// Addition (+)\nlet sum = num1 + num2\nconsole.log(`La SUMA de ${num1} y ${num2} es: ${sum}`)\n\n// Subtraction (-)\nlet difference  = num1 - num2\nconsole.log(`La RESTA de ${num1} y ${num2} es: ${difference}`)\n\n// Multiplication (*)\nlet product  = num1 * num2\nconsole.log(`La MULTIPLICACIÓN de ${num1} y ${num2} es: ${product}`)\n\n// Division (/)\nlet division = num1 / num2\nconsole.log(`La DIVISIÓN de ${num1} y ${num2} es: ${division}`)\n\n// Modulus (%)\nlet modulo = num1 % num2\nconsole.log(`El MÓDULO de ${num1} y ${num2} es: ${modulo}`)\n\n// Increment (++)\nnum1++\nconsole.log(`El valor despues del incremento es: ${num1}`)\n\n// Decrement (--)\nnum2--\nconsole.log(`El valor despues del decremento es: ${num2}`)\n\n// Exponentiation (**)\nlet result = num1 ** num2\nconsole.log(`El resultado es: ${result}`)\n\n// Unary negation (-)\nlet negation = -num1\nconsole.log(`La NEGACIÓN es: ${negation}`)\n\n/* OPERADORES DE ASIGNACIÓN */\nconsole.log('\\n*** OPERADORES DE ASIGNACIÓN ***\\n')\n\n// Asignación básica (=)\nlet numAssignmentExample1  = 5\nconsole.log(`Asignación básica (=), el valor es: ${numAssignmentExample1}`)\n\n// Asignación con suma (+=)\nlet numAssignmentExample2 = 5\nnumAssignmentExample2 += 3\nconsole.log(`Asignación con suma (+=), el valor es: ${numAssignmentExample2}`)\n\n// Asignación con resta (-=)\nlet numAssignmentExample3 = 5\nnumAssignmentExample3 -= 3\nconsole.log(`Asignación con resta (-=), el valor es: ${numAssignmentExample3}`)\n\n// Asignación con multiplicación (*=)\nlet numAssignmentExample4 = 5\nnumAssignmentExample4 *= 3\nconsole.log(`Asignación con multiplicación (*=), el valor es: ${numAssignmentExample4}`)\n\n// Asignación con división (/=)\nlet numAssignmentExample5 = 15\nnumAssignmentExample5 /= 3\nconsole.log(`Asignación con división (/=), el valor es: ${numAssignmentExample5}`)\n\n// Asignación con módulo (%=)\nlet numAssignmentExample6 = 7\nnumAssignmentExample6 %= 3\nconsole.log(`Asignación con módulo (%=), el valor es: ${numAssignmentExample6}`)\n\n// Asignación con exponenciación (**=)\nlet numAssignmentExample7 = 5\nnumAssignmentExample7 **= 3\nconsole.log(`Asignación con exponenciación (**=), el valor es: ${numAssignmentExample7}`)\n\n/* OPERADORES DE COMPARACIÓN */\nconsole.log('\\n*** OPERADORES DE COMPARACIÓN ***\\n')\n// Igual a (==)\nlet comparisonOperator1 = 5\nlet comparisonOperator1y = \"5\"\nconsole.log(`Igual a (==), el valor es: ${comparisonOperator1 == comparisonOperator1y}`)\n\n// No igual a (!=)\nlet comparisonOperator2 = 5\nlet comparisonOperator2y = \"5\"\nconsole.log(`No igual a (!=), el valor es: ${comparisonOperator2 != comparisonOperator2y}`)\n\n// Estrictamente igual a (===)\nlet comparisonOperator3 = 5\nlet comparisonOperator3y = \"5\"\nconsole.log(`Estrictamente igual a (===), el valor es: ${comparisonOperator3 === comparisonOperator3y}`)\n\n// Estrictamente no igual a (!==)\nlet comparisonOperator4 = 5\nlet comparisonOperator4y = \"5\"\nconsole.log(`Estrictamente no igual a (!==), el valor es: ${comparisonOperator4 !== comparisonOperator4y}`)\n\n// Mayor que (>)\nlet comparisonOperator5 = 5\nlet comparisonOperator5y = 10\nconsole.log(`Mayor que (>), el valor es: ${comparisonOperator5 > comparisonOperator5y}`)\n\n// Menor que (<)\nlet comparisonOperator6 = 5\nlet comparisonOperator6y = 10\nconsole.log(`Menor que (<), el valor es: ${comparisonOperator6 < comparisonOperator6y}`)\n\n// Mayor o igual que (>=)\nlet comparisonOperator7 = 5;\nlet comparisonOperator7y = 10;\nconsole.log(`Mayor o igual que (>=), el valor es: ${comparisonOperator7 >= comparisonOperator7y}`)\n\n// Menor o igual que (<=)\nlet comparisonOperator8 = 5;\nlet comparisonOperator8y = 10;\nconsole.log(`Menor o igual que (<=), el valor es: ${comparisonOperator8 <= comparisonOperator8y}`)\n\n\n/* OPERADORES LÓGICOS */\nconsole.log('\\n*** OPERADORES LÓGICOS ***\\n')\n\n// AND (&&)\nlet xAnd = true\nlet yAnd = false\nlet resultAnd = xAnd && yAnd\nconsole.log(`AND (&&), el valor es: ${resultAnd}`)\n\n// OR (||)\nlet xOr = true\nlet yOr = false\nlet resultOr = xOr || yOr\nconsole.log(`OR (||), el valor es: ${resultOr}`)\n\n// NOT (!)\nlet xNot = true\nlet resultNot = !xNot\nconsole.log(result)\nconsole.log(`NOT (!), el valor es: ${resultNot}`)\n\n/* OPERADORES DE CADENAS */\nconsole.log('\\n*** OPERADORES DE CADENAS ***\\n')\n\n// Concatenación de cadenas con el operador suma (+)\nlet text1 = 'Hola'\nlet text2 = 'Mundo'\nlet mensaje1 = text1 + ', ' + text2 + '!'\nconsole.log(`${mensaje1}`)\n\n// Concatenación de cadenas con el operador de asignación con suma (+=\nlet mensaje2 = '¡Felicitaciones'\nconsole.log(`- ${mensaje2}`)\nmensaje2 += ', has ganado';\nconsole.log(`-- ${mensaje2}`)\nmensaje2 += ' el primer lugar!'\nconsole.log(`--- ${mensaje2}`)\n\n/* OPERADORES DE INCREMENTO Y DECREMENTO */\nconsole.log('\\n*** OPERADORES DE INCREMENTO Y DECREMENTO ***\\n')\n\n// Incremento (++)\n// - Incremento de prefijo (++variable)\nlet contador1 = 5\nlet resultadoIncrement1 = ++contador1\nconsole.log(`Contador es: ${contador1}, Resultado es: ${resultadoIncrement1}`)\n\n\n// Incremento (++)\n// - Incremento de sufijo (variable++)\nlet contador2 = 5\nlet resultadoIncrement2 = contador2++\nconsole.log(`Contador es: ${contador2}, Resultado es: ${resultadoIncrement2}`)\n\n// Decremento (--)\n// - Decremento de prefijo (--variable)\nlet contador3 = 5\nlet resultadoDecrement1 = --contador3\nconsole.log(`Contador es: ${contador3}, Resultado es: ${resultadoDecrement1}`)\n\n// Decremento (--)\n// - Decremento de sufijo (variable--)\n\nlet contador4 = 5\nlet resultadoDecrement2 = contador4--\nconsole.log(`Contador es: ${contador4}, Resultado es: ${resultadoDecrement2}`)\n\n/* OPERADORES TERNARIOS  */\nconsole.log('\\n*** OPERADORES TERNARIO ***\\n')\nlet age = 25\nlet finalMessage = age >= 18 ? 'Eres mayor de edad.' : 'Eres menor de edad.'\nconsole.log(`Ternario (condicion ? expresionSiTrue : expresionSiFalse), el valor es: ${finalMessage}`)\n\n/* OPERADORES DE TIPO  */\nconsole.log('\\n*** OPERADORES DE TIPO ***\\n')\n\n// typeof\nlet number = 42\nconsole.log(`El tipo es, ${typeof number}`)\n\nlet cadena1 = 'Hola, mundo!' \nconsole.log(`El tipo es, ${typeof cadena1}`)\n\nlet funcion = function () {}\nconsole.log(`El tipo es, ${typeof funcion}`)\n\n\n// Conversiones de tipo explícitas (parseInt, parseFloat, String, Number, y Boolean)\nlet numStr = '42'\nlet entero = parseInt(numStr)\nconsole.log(`El tipo es, ${typeof entero} y el valor es ${entero}`)\n\nlet cadena2 = 42 \nlet text = String(cadena2); \nconsole.log(`El tipo es, ${typeof text} y el valor es ${text}`)\n\n/* BIT  */\nconsole.log('\\n*** BIT ***\\n')\n\n// Operador AND (&)\n/*En este ejemplo, la operación AND se realiza bit a bit en los números aAnd y bAnd. El resultado es 1, ya que ambos bits en la posición 1 son 1.*/\nlet aAnd = 5 // binario: 0101\nlet bAnd = 3 // binario: 0011\nlet resultadoAnd = aAnd & bAnd\nconsole.log(`Operador AND (&), el resultado es: ${resultadoAnd}`)\n\n\n// Operador OR (|)\n/*En este ejemplo, la operación OR se realiza bit a bit en los números aOr y bOr. El resultado es 7, ya que al menos uno de los bits en las posiciones 1 y 2 es 1.*/\nlet aOr = 5 // binario: 0101\nlet bOr = 3 // binario: 0011\nlet resultadoOr = aOr | bOr\nconsole.log(`Operador OR (|), el resultado es: ${resultadoOr}`)\n\n// Operador XOR (^)\n/*En este ejemplo, la operación XOR se realiza bit a bit en los números aXor y bXor. El resultado es 6, ya que los bits en las posiciones 2 y 3 son diferentes.*/\nlet aXor = 5 // binario: 0101\nlet bXor = 3 // binario: 0011\nlet resultadoXor = aXor ^ bXor\nconsole.log(`Operador XOR (^), el resultado es: ${resultadoXor}`)\n\n// Operador NOT (~)\n/*En este ejemplo, la operación NOT invierte todos los bits del número aNot. El resultado es -6. */\nlet aNot = 5 // binario: 0101\nlet resultadoNot = ~aNot\nconsole.log(`Operador NOT (~), el resultado es: ${resultadoNot}`)\n\n// Desplazamiento a la izquierda (<<)\n/*En este ejemplo, los bits del número a se desplazan 2 posiciones a la izquierda. El resultado es 20. */\nlet adi = 5 // binario: 0000 0101\nlet resultadodi = adi << 2\nconsole.log(`Desplazamiento a la izquierda (<<), el resultado es: ${resultadodi}`)\n\n// Desplazamiento a la derecha (>>)\n/*El resultado es 5 porque cada desplazamiento a la derecha divide el número por 2. */\nlet add = 20 // binario: 0001 0100\nlet resultadodd = add >> 2\nconsole.log(`Desplazamiento a la derecha (>>), el resultado es: ${resultadodd}`)\n\n// Desplazamiento a la derecha sin signo (>>>)\n/*El resultado es 1073741820 porque el desplazamiento a la derecha sin signo siempre llena los bits vacíos con 0, lo que da como resultado es un número positivo. */\nlet xdds = -20 // 11101100 en binario (número negativo)\nlet resultdds = xdds >>> 2 // 00101100 en binario (desplazamiento 2 posiciones a la derecha sin signo)\nconsole.log(`Desplazamiento a la derecha sin signo (>>>), el resultado es: ${resultdds}`)\n\n/* ESTRUCTURAS DE CONTROL  */\nconsole.log('\\n*** ESTRUCTURAS DE CONTROL ***\\n')\n\n// If-else\nlet iFElse = 10\nif(iFElse > 5){\n    console.log(`(If-else), El valor de ${iFElse} es mayor a 5`)\n} else {\n    console.log(`(If-else), El valor de  ${iFElse} es menor a 5`)\n}\n\n// Switch\nlet nSwitch = 10\nswitch(nSwitch){\n    case 10:\n        console.log(`(Switch), El valor de ${nSwitch} es igual a 10`)\n        break\n    case 20:\n        console.log(`(Switch), El valor de ${nSwitch} es igual a 20`)\n        break\n    default:\n        console.log('No se cumplió ningún caso')\n        break\n}\n\n// While\nlet iWhile = 0\nwhile(iWhile <= 10){\n    if(iWhile % 2 == 0) {\n        console.log('(While), ', iWhile)\n        }\n    iWhile ++\n}\n\n// Do-while\nlet iDoWhile = 5\ndo {\n    console.log('(Do-while), example')\n    iDoWhile ++\n} while(iDoWhile < 10)\n\n// For\nlet forExample = 5\nfor (let i = 1; i <= 10; i++) {\n    console.log(`${forExample} x ${i} = ${forExample * i}`);\n}\n\n// Try-catch\ntry{\n    ejemplo()\n}\ncatch(error){\n    console.log('(Try-catch), Error: ' +  error)\n}\n\n/* EXTRA  */\nconsole.log('\\n*** EXTRA ***\\n')\n\nfor (let i = 10; i <= 55; i++) {\n    if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n        console.log(i);\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/jaimemunozdev.js",
    "content": "// OPERADORES JAVASCRIPT\n\n    // Asignacióm\n\n        // Operador de asignación (=)\n        let asignacionSimple = 'Soy igual a este string'\n        console.log(asignacionSimple) // 'Soy igual a este string'\n\n        // Asignación de adicióm (+=)\n        let asignaAdicion = 10\n        asignaAdicion += 5\n        console.log(asignaAdicion) // 15\n\n        // Asignación de resta (-=)\n        let asignaResta = 10\n        asignaResta -= 5\n        console.log(asignaResta) // 5\n\n        // Asignación de multiplicación (*=)\n        let asignaMultiplica = 5\n        asignaMultiplica *=5\n        console.log(asignaMultiplica) // 25\n\n        // Asignación de división (/=)\n        let asignaDivide = 10\n        asignaDivide /= 2\n        console.log(asignaDivide) // 5\n\n        // Asignación de módulo (%=)\n        let asignaModulo = 18\n        asignaModulo %= 2\n        console.log(asignaModulo) // 0\n\n        // Asignación de exponenciación (**=)\n        let asignaExponencia = 2\n        asignaExponencia **= 3  // Sería como decir: \"2 al cubo\"\n        console.log(asignaExponencia) // 8\n\n    // Aritméticos\n\n        // Operador de suma (+)\n        let sumando1 = 20,\n        sumando2 = 10;\n        let suma = sumando1 + sumando2\n        console.log(suma) // 30\n\n        // Operador de resta (-)\n        let minuendo = 50,\n        sustraendo = 20;\n        let resta = minuendo - sustraendo\n        console.log(resta) // 30\n\n        // Operador de multiplicación (*)\n        let multiplo1 = 5,\n        multiplo2 = 10;\n        let multiplicacion = multiplo1 * multiplo2\n        console.log(multiplicacion) // 50\n\n        // Operador de división (/)\n        let dividendo = 60,\n        divisor = 15;\n        let division = dividendo / divisor\n        console.log(division) // 4\n\n        // Exponenciación (**)\n        let numeroExponenciar = 5,\n        alCubo = 3;\n        let exponenciado = numeroExponenciar ** alCubo\n        console.log(exponenciado) // 125\n\n        // Operador de módulo (%)\n        let modulo1 = 10,\n        modulo2 = 3;\n        let moduloResto = modulo1 % modulo2\n        console.log(moduloResto) // 1\n\n        // Operador de incremento (++)\n        let aIncrementar = 20\n        let incrementado = ++aIncrementar\n        console.log(incrementado) // 21\n\n        // Operador de decremento (--)\n        let aDecrementar = 24\n        let decrementado = --aDecrementar\n        console.log(decrementado) // 23\n\n        // Negación Unaria (-'variable')\n        let aNegar = 10\n        let negado = -aNegar\n        console.log(negado) // -10\n        \n        // Positivo Unario (+'variable')\n        let stringNumero = '100'\n        console.log(stringNumero)\n        let ahoraNumber = +stringNumero\n        console.log(ahoraNumber) // 100 como Number\n\n    // De Comparación\n\n        // Igualdad no estricta (==)\n        let cincoCinco = 5 + 5,\n        diez = 10;\n        let igualdad = cincoCinco == diez\n        console.log(igualdad) // true\n\n        // Igualdad estricta (===)\n        let valorEstrictoBooleano = diez === '10'\n        console.log(valorEstrictoBooleano) // false\n\n        // Desigualdad no estricta (!=)\n        let valorNoEstricto = cincoCinco != diez\n        console.log(valorNoEstricto) // false\n        \n        // Desigualdad estricta (!==)\n        let desigualEstricto = cincoCinco !== 11\n        console.log(desigualEstricto) // true\n\n        // Mayor que (>)\n        let mayorQue = 5 > 4\n        console.log(mayorQue) // true\n\n        // Menor que (<)\n        let menorQue = 10 < 30\n        console.log(menorQue) // true\n\n        // Mayor o igual que (>=)\n        let mayorIgualQue = cincoCinco >= diez\n        console.log(mayorIgualQue) // true\n\n        // Menor o igual que (<=)\n        let menorIgualQue = cincoCinco <= 8\n        console.log(menorIgualQue) // false\n    \n    // Operadores Lógicos\n\n        // Operador \"Y\" (&&)\n        let y = 10 < 20 && 5 > 4\n        console.log(y) // true\n\n        // Operador \"O\" / (||)\n        let o = 10 < 5 || 20 < 30\n        console.log(o) // true\n\n        // Operador de negación\n        let verdadero = true\n        let loNiego = !verdadero\n        console.log(loNiego) //false\n\n    // Operadores de Concatenación\n\n        // Operador concatenador (+)\n        let soy = 'Soy'\n        let miNombre = 'Jaime'\n        console.log(soy + ' ' + miNombre) // Soy Jaime\n\n        // Operador concatenador asignador\n        let concatenaAsigna = soy += ' también Jaime'\n        console.log(concatenaAsigna) // Soy también Jaime\n\n    // Operadores condicionales\n        \n        // Operador ternario (? :)\n        let soyDelMalaga = true\n        let mensaje = soyDelMalaga = true ? \"Si, eres del Málaga\" : \"No, eres un chaquetero\"\n        console.log(mensaje) // \"Si, eres del Málaga\"\n    \n    // Operadores de tipo\n    \n        // typeof\n        let soyString = 'Qué soy?'\n        let soyNumber = 15\n        let soyBooleano = true\n        let soyObjeto = {nombre: 'Jaime',\n                        apellido: 'Muñoz'}\n        console.log(typeof soyString) // string\n        console.log(typeof soyNumber) // number\n        console.log(typeof soyBooleano) // boolean\n        console.log(typeof soyObjeto) // object\n\n        // instanceof\n        console.log(soyObjeto instanceof Object) // true\n        console.log(soyString instanceof String) // false -> esto funciona con objetos\n\n    // Operadores de bits\n\n        // AND a nivel de bits (&)\n        let primero = 5 // 101 binario\n        let segundo = 3 // 011 binario\n        let ANDbits = primero & segundo\n        console.log(ANDbits) // 1\n\n        // OR a nivel de bits (|)\n        let ORbits = primero | segundo\n        console.log(ORbits) // 7 (binario 111)\n\n        // XOR a nivel de bits (^)\n        let XORbits = primero ^ segundo\n        console.log(XORbits) // 6 (binario 110)\n\n        // NOT a nivel de bits (~)\n        let NOTbits = ~primero\n        console.log(NOTbits) // -6\n\n        // Desplazamiento a la izquierda (<<)\n        let lefteo = primero << 1\n        console.log(lefteo) // 10 (binario 1010)\n\n        // Desplazamiento a la derecha (>>)\n        let righteo = primero >> 1\n        console.log(righteo) // 2 (binario 10)\n\n        // Desplazamiento a la derecha sin signo\n        let sinSigno = -primero >>> 1\n        console.log(sinSigno) // 2147483645 (binario 01111111111111111111111111111101)\n        \n\n// EXTRA\n\nfor (let i = 10; i <= 55; i++) {\n    if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n        console.log(i);\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/jaxi86.js",
    "content": "//operadores.\n\nlet a = 2;\nlet b =4;\n\n//operadores de incremento y decremento\na++;\nconsole.log(a);\nb--;\nconsole.log(b);\n\n//operadores aritmeticos\nconsole.log(a + b, 'suma');\nconsole.log(a - b, 'resta');\nconsole.log(a / b, 'division');\nconsole.log(a * b, 'multiplicacion');\nconsole.log(a % b), 'modulo';\nconsole.log(a ** b, 'potencia');\n//operadores de asignacion.\na +=5;\na -=5;\na /=5;\na *=5;\na %=5;\na **=5;\nconsole.log(a)\n//operadores de comparacion.\nconsole.log(a>b);\nconsole.log(a>=b);\nconsole.log(a<b);\nconsole.log(a<=b);\n//operadores de igualdad y desigualdad\nconsole.log(a == b);\nconsole.log(a != b);\nconsole.log(a === b);\nconsole.log(a !== b);\n//operadores logicos.\nlet mayor = true;\nlet suscrito = false;\n\n//AND\nconsole.log( mayor && suscrito );\n\n//OR\nconsole.log( mayor || suscrito );\n\n//NOT\nconsole.log( !suscrito );\n\n//operador ternario\nlet edad = 25;\nlet acceso = edad > 17 ? 'permitir acceso' : 'no permitir acceso';\nconsole.log(acceso);\n\n//operador de pertenencia\nlet array = [7, 2, 4, 9, 8];\nlet confir = 2 in array;\nconsole.log(confir);\n\n//operador bitwise\nlet and = a & b;\nconsole.log(and);\n\nlet or = a | b;\nconsole.log(or);\n\nlet xor = a ^ b;\nconsole.log(xor);\n\nconsole.log(~a);//el operador not en bitwise\n\nlet despla_dere = a >> 1;\nconsole.log(despla_dere);\n\nlet despla_izq = a << 1;\nconsole.log(despla_izq);\n\n//estructura de control\n\n//if y else y while\n\nlet d = 5\n\nwhile ( d < 15){\n    if( d % 2 == 0 ){\n        console.log ('numero par', d);\n    }else if ( d % 2 != 0){\n    console.log( 'numero impar', d);\n}else { console.log( 'error');};\n++d;\n}\n\n//operador switch\n\nlet c =10;\n\nswitch (c){\n  case 10 :\n    console.log('correcto');\n    break;\n  case 15 :\n    console.log('incorrecto');\n    break;\n  default:\n    console.log('accion no definida');\n}\n\n//operador do while.\n\nlet e = 0;\n\ndo {\n    if (e % 2 == 0){\n        console.log( 'numero par', e);\n    }\n    ++e;\n}while(e < 10)\n\n// for.\n\nfor (let f = 2; f < 20; f++){\n  if ( f % 2 == 0){\n    console.log( 'numero par2', f );\n}\n}\n\n//for of.\n\nlet array2 = [2, 3, 1, 7, 9, 6];\nfor( numero of array){\n  console.log(numero);\n}\n\n// for in.\n\nlet persona ={\n  nombre:'josue',\n  edad:15,\n  colo_cabe:'negro',\n};\nfor ( rasgos in persona){\n  console.log(rasgos, persona[rasgos]);\n};\n\n//ejersicio dificultad extra\nlet z = 10;\nwhile(z <= 55){\n    ++z;\n    if (z === 16){\n        continue;\n    }else if (z % 3 === 0){\n        continue;\n    }else if (z % 2 === 0){\n        console.log('numero par', z);\n    }\n\n};\n  \n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/jeronimocardu.js",
    "content": "let a = 2;\nlet b = 3;\n\n// OPERADORES ARITMETICOS\nlet suma = a + b;           // Suma\nlet resta = a - b;          // Resta\nlet multiplicacion = a * b; // Multiplicacion\nlet division = a / b;       // Division\nlet exponente = a ** b;     // Potenciacion\nlet residuo = b % a;        // Resiudo\n// ejemplo\nif((a+b) > 0){\n    console.log('La suma da un numero natural')\n}\n\n// OPERADORES LOGICOS\n\na === b                     // Igualdad estricta\na == b                      // Igualdad pero no incluye el tipo de dato\na !== b                     // Desigualdad estricta\na != b                      // Desiguldad\na > b                       // Mayor que..\na >= b                      // Mayor o igual que..\na < b                       // Menor que..\na <= b                      // Menor o igual que..\na && b                      // AND\na || b                      // OR\n!a                          // Negacion\nif(a === b){\n    console.log('Son iguales');\n} else if(a > b){\n    console.log('A mayor que B');\n} else{\n    console.log('B mayor que A');\n}\n\n\n// OPERADORES DE ASIGNACION\n\nlet variable = 'Hola mundo';\nconst texto = variable;\na += 1;                     // Asignacion y suma\na -= 1;                     // Asignacion y resta\nfor(let i=0; i<5; i++){\n    console.log(variable[i]);\n}\n\n// OPERADORES DE IDENTIDAD\n\nconst objeto1 = {nombre: 'Jeronimo'};\nif('nombre' in objeto1){\n    console.log('LA PERSONA TIENE NOMBRE Y ES', objeto1.nombre)\n}\n\n// OPERADORES DE PERTENENCIA\n\nconst persona = {\n    nombre: 'Jeronimo',\n    edad: 19,\n}\nif(persona.edad > 17){\n    console.log(persona.nombre, 'es mayor de edad')\n}\n\n// EXTRA\nfor(let i=10; i<55; i++){\n    if(i%2 === 0 && i !== 16 && i%3 !== 0){\n        console.log(i)\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/jesusWay69.js",
    "content": "console.clear()\n\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\nconst myName = \"Jesus\" // Asignación de constante\nlet myNum = 5 // Asignación de variable tipo number y valor 5\nlet myStringNum = \"5\" // Asignación de variable tipo string y valor 5\nconsole.log(myName == \"Jesus\") \nconsole.log(myNum == myStringNum) // Compara valores\nconsole.log(myNum === myStringNum) // Compara valores y tipos\n\n//Asignación de mismo valor para 3 variables con let\nlet one = two = three = 1 \n// de esta manera 1 se asigna a three, three se asigna a two y two se asigna a one en ese orden\n\nconsole.log(one, two, three, four) //four no está inicializada aun pero al declararse con var posteriormente devuelve undefined\n//let two = 2, esto me da error porque no puedo reasignar otro valor a las variables asignadas en bloque con let \n// volviéndola a declarar como let\n\n//Asignación de mismo valor para 3 variables de manera individual en una línea con var\nvar four = 4, five = 4, six = 4 \nconsole.log(four, five, six)\n\n// Reasignación de todas las variables y asignación de nuevas (seven, eight, nine) en una sola línea, todas se asignan como let\nzero = 0, two = 2, three = 3, five = 5, six = 6, seven = 7, eight = 8, nine = 9 \n\n// Asignación de variables let con valores diferentes por desectructuración\nlet [ten, eleven, twelve] = [10, 11, 12]\n\nconsole.log(zero, one, two, three, four, five, six, seven, eight, nine, ten, eleven, twelve)\n\nif (four + one == myNum){ // condicional en base a una operación con variables de tipo number\n    console.log(`El resultado es ${five}`)\n}\n\nlet myNumbers = [zero, one, two, three, four, five, six, seven, eight, nine, ten, eleven, twelve]\n\nconsole.log(typeof(myNumbers)) // JS interpreta un array como un tipo object\n\nlet printBuilder = ''\nfor (num of myNumbers){ // For each que recorre cada elemento del array\n    printBuilder += num + ' ' //concatenación con un espacio para formar el string\n}\nconsole.log(printBuilder) // para hacer una impresión sin saltos de línea se puede \"construir\" un string\n\ntry{\n    console.log(twelve / two) // La operación es correcta e imprime el resultado\n    console.log(twelve / zero) // La operación es incorrecta por división entre 0 pero imprime Infinity\n    console.log(\"twelve\" / \"zero\") // La operación es incorrecta al intentar dividir entre 2 strings pero imprime NaN\n    console.log(thirteen * fourteen) //En este caso al intentar operar con 2 variables no declaradas la ejecución se va al catch\n}catch{\n    console.error(\"Error de operación\") \n}\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n */\n\nprintBuilder = ''\nfor (let i = 10; i < 56; i++){\n    if (i % 3 == 0 ||i % 2 != 0 || i == 16){ // For por índices\n        continue\n    }\n    printBuilder += i + ' '\n    \n}\nconsole.log(printBuilder.trim() + \"\\n\")\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/jfigueroa24.js",
    "content": "/*OPERADORES*/\n// Operadores aritmeticos\nconsole.log(`Suma: 10 + 3 = ${10 + 3}`);\nconsole.log(`Resta: 10 - 3 = ${10 - 3}`);\nconsole.log(`Producto: 10 * 3 = ${10 * 3}`);\nconsole.log(`Cociente: 10 / 3 = ${10 / 3}`);\nconsole.log(`Residuo: 10 % 3 = ${10 % 3}`);\nconsole.log(`Exponenciacion: 10 ^ 3 = ${10 ** 3}`);\nlet num = 10;\nnum++;\nconsole.log(`Incremento: 10 ++ 3 = ${num}`);\nnum--;\nconsole.log(`Decremento: 10 -- 3 = ${num}`);\n\n//Operadores de asignación\n\nlet nombre = \"Julian Figueroa\";\nlet x = 20; // Asignacion simple\nlet y = 10;\nconsole.log((x += y)); // Asignacion con suma\nconsole.log((x -= y)); // Asignacion con resta\nconsole.log((x *= y)); // Asignacion con multiplicacion\nconsole.log((x /= y)); // Asignacion con division\nconsole.log((x %= y)); // Asignacion con modulo\n\n//Operadores de comparación\n\nconsole.log(x == y); // Igualdad\nconsole.log(\"Hola\" === 25); // estricta\nconsole.log(x != y); // diferente\nconsole.log(\"Hola\" !== 25); // diferente estricta\nconsole.log(x > y); // mayor que\nconsole.log(x < y); // menor que\nconsole.log(x >= y); // mayor o igual que\nconsole.log(x <= y); // menor o igual que\n\n//Operadores de logicos\n\nconsole.log(\"Cat\" && \"Dog\");\nconsole.log(\"Cats\" && \"Cat\");\n\n// Operadores de tipo\n\nconsole.log(typeof 2.5);\n\n// Operador ternario\n\npar = 4;\nimpar = 5;\nesPar = impar % 2 == 0 ? \"Par\" : \"Impar\";\nconsole.log(esPar);\n\n// ESTRUCTURAS DE CONTROL EN JAVASCRIPT\n// Condicionales\n\nvalue = true;\nif (value) {\n  console.log(\"Es verdadero\");\n} else if (null) {\n  console.log(\"Es nulo\");\n} else {\n  console.log(\"Es falso\");\n}\n\n// Switch\ngeneroPersona = \"masculino\";\nswitch (generoPersona) {\n  case \"masculino\":\n    console.log(\"El genero es masculino\");\n    break;\n  case \"femenino\":\n    console.log(\"El genero es masculino\");\n    break;\n  default:\n    console.log(\"El genero no está especificado\");\n    break;\n}\n\n// Bucles\n//for\nsuma = 0;\nfor (let i = 0; i <= 10; i++) {\n  // Suma de los numeros hasta el 10\n  suma += i;\n}\nconsole.log(\"For: \", suma);\n\n// while\nsuma = 0;\ni = 0;\nwhile (i <= 10) {\n  suma += i;\n  i++;\n}\nconsole.log(\"While: \", suma);\n\n//do-while\n\nsuma = 0;\ni = 0;\ndo {\n  suma += i;\n  i++;\n} while (i <= 10);\nconsole.log(\"Do while: \", suma);\n\n// Condicionales sobre colecciones\n//for ... of\n\nconst frutas = [\"Manzana\", \"Pera\", \"Mango\", \"Fresa\"];\n\nfor (const fruta of frutas) {\n  console.log(`Fruta: ${fruta}`);\n}\n\n//for ... in\n\nconst persona = {\n  nombre: \"Juan\",\n  edad: 30,\n  ciudad: \"Bogotá\",\n};\n\nfor (const clave in persona) {\n  console.log(`${clave}: ${persona[clave]}`);\n}\n\n// try - catch\n\ntry {\n  dividendo = 10;\n  divisor = 1;\n\n  if (divisor === 0) {\n    throw new Error(\"No es posible dividir entre cero.\");\n  }\n  console.log(dividendo / divisor);\n} catch (error) {\n  console.error(\"Error: \", error.message);\n} finally {\n  (\"Operacion finalizada\");\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/jhonf1992.js",
    "content": "// OPERADORES EN JAVASCRIPT //\n\n// OPERADOR DE ASIGNACION ( = )\n\nlet x = 1;\nlet y = 2;\nlet a = y;\nlet b = x;\nconsole.log(x);\nconsole.log(y);\nconsole.log(a);\nconsole.log(b);\n// Asginacion de adicion ( += )\n\nx += y;\ny += a;\nconsole.log(x);\nconsole.log(y);\n\n// Asginacion resta ( -= )\n\nx -= y;\na -= b;\nconsole.log(x);\nconsole.log(a);\n\n\n// Asginacion de multiplicacion ( *= )\n\nx *= x;\nb *= a;\nconsole.log(x);\nconsole.log(b);\n\n// Asginacion de division ( /= )\n\nlet numDiv1 = 15;\nlet numDiv2 = 3;\nnumDiv1 /= numDiv2;\n\nconsole.log(numDiv1);\n// Asignacion Residuo ( %= ) \nlet numResiduo = 20;\nlet numeResiduo2 = 2;\nnumResiduo %= numeResiduo2;\n\nconsole.log(numResiduo);\n\n// Asignacion exponenciacion \n\nlet numExpo = 2;\nlet numExpo2 = 10;\nnumExpo2 **= numExpo;\n\nconsole.log(numExpo2);\n\n// OPERADORES DE COMPARACION \n\n// Operador de igualdad ( == ) \nlet numeroComparacion = 5;\nlet numeroComparacion2 = 7;\n\nlet comparacionResultado = numeroComparacion == numeroComparacion2;\nconsole.log(comparacionResultado); //False\n\n// operador de desigualdad ( != )\n\nlet numDesigual1 = 15;\nlet numDesigual2 = 20;\n\nlet desigual = numDesigual1 != numDesigual2;\nconsole.log(desigual); // True \n\n// Estrictamente igual ( === )\n\nlet strinEstricto = \"Hola Mundo\";\nlet strinEstricto2 = \"hola mundo\";\n\nlet compararEstricto = strinEstricto === strinEstricto2;\nconsole.log(compararEstricto); // False \n\n// Desigualdad estricta ( !== )\n\nlet desEstricta = 5;\nlet desEstricta2 = \"5\";\n\nlet comDesigEstric = desEstricta !== desEstricta2;\nconsole.log(comDesigEstric);\n\n// Mayor igual ( > )\n\nlet numMenor = 5;\nlet numMayor = 20;\n\nlet respMayor = numMayor > numMenor;\nconsole.log(respMayor);\n\n// Menor igual ( < )\n\nlet resMenor = numMayor < numMenor;\nconsole.log(resMenor);\n\n// menor igual ( <= )\n\nlet menorIgual = numMayor <= numMenor;\nconsole.log(menorIgual);\n\n// Mayor igual ( >= )\n\nlet mayorIgual = numMayor >= numMenor;\nconsole.log(mayorIgual);\n\n// OPERADORS ARITMETICOS  SUMA (+) RESTA ( - ) MULTIPLICACION (*) DIVISION (/)\n\nlet num1 = 5;\nlet num2 = 10;\n\n// Suma (+)\n\nlet suma = num1 + num2;\nconsole.log(suma);\nlet resta = num1 - num2;\nconsole.log(resta);\nlet mult = num1 * num2;\nconsole.log(mult);\nlet div = num1 / num2;\nconsole.log(div);\n\n// OPERADORES UNARIOS INCREMENTO, DECREMENTO\n\nlet numUnario = 15;\nnumUnario ++;\nconsole.log(numUnario);\nnumUnario --;\nconsole.log(numUnario);\n\n// OPERADOR UNARIO NEGATIVO\nlet unarioNeg = 10;\nconsole.log(-unarioNeg);\n\n// UNARIO POSITIVO\n\nlet unarioPost = \"10\";\nconsole.log(+unarioPost);\n\n// POTENCIA UNARIA\n\nlet numPot = 15;\nlet potenciaUnaria = numPot**2;\nconsole.log(potenciaUnaria);\n\n\n// OPERADORES LOGICOS  AND OR NOT\n\nlet numComparacion1 = 10;\nlet numComparacion2 = 25;\nlet numComparacion3 = 18;\n\nlet and = (numComparacion1 == numComparacion2 && numComparacion3 > numComparacion1);\nlet or = (numComparacion1 == numComparacion2 || numComparacion3 > numComparacion1);\nlet not = !or;\n\nconsole.log(and);\nconsole.log(or);\nconsole.log(not);\n\n\n// OPERADOR CONCATENACION \n\nlet string1 = \"Hola me llamo \";\nlet string2 = \"Juan Fernandez\";\n\nconsole.log(string1 + string2);\n\n\n// OPERADOR CONDICIONAL TERNARIO\n\n// condition ? val1 : val2\n\nlet tern = 50;\n\nlet resTern = tern > 18 ? \"Es mayor de edad\": \"Es menor de edad\";\nconsole.log(resTern);\n\n//OPERADOR TYPEOF\n\nlet cadena = \"Hola\";\nlet numero = 1215;\nlet booleano =  4 < 6;\n\nconsole.log(typeof(cadena));\nconsole.log(typeof(numero));\nconsole.log(typeof(booleano));\n\n// Operadores logicos BIT a BIT\n\nlet bitAnd = 20 & 15;\nlet bitOR = 25 | 20;\nlet bitXor = 10 ^ 5;\nlet bitNot = ~ 15;\nconsole.log(bitAnd);\nconsole.log(bitOR);\nconsole.log(bitXor);\nconsole.log(bitNot);\n\n// Operadores de desplazamiento de BITS\n\nlet desplazamientoIzq = 20 << 2;\nlet desplazamientoDer = 25 >> 5;\nconsole.log(desplazamientoIzq);\nconsole.log(desplazamientoDer);\n\n// Operador In\n\nlet array = [\"Uva\", \"Naranja\", \"Manzana\", \"Pera\"];\nlet validar = 1 in array\nconsole.log(validar); // Valida si el indice esta en ese array\n\n\n// Estructuras de control\nlet numer1If = 2;\nlet numer2If = 5;\nif (numer1If > numer2If) {  // Estructura de control If\n    console.log(\"Si es mayor\");\n}else{\n    console.log(\"Es menor\");\n}\n\n// Condicionales if - else - else if\n\nnumer1If = 10;\nnumer2If = 10;\n\nif (numer1If < numer2If) \n{\n    console.log(\"Es menor\");\n\n}else if(numer1If > numer2If){\n    console.log(\"Es mayor\");\n} else {\n    console.log(\"Es igual\");\n}\n\n\n// Iteradores \n// while\nlet iterador = 0;\nlet contador = 0;\nwhile (iterador < 15) {\n    contador += 2;\n    iterador++;\n    console.log(contador);\n}\n\n// For\n\ncontador = 0;\n\nfor (let i = 0; i < 15; i++) {\n    contador += 3;\n    console.log(contador);\n    \n};\n\n// Foreach\nlet arrayFrutas = [\"Manzana\",\"Pera\",\"Naranja\",\"Uva\", \"Kiwi\",\"Mandarina\",\"Limon\"];\ncontador = 0;\narrayFrutas.forEach(fruta => {\n    contador ++\n    console.log(`${contador} : ${fruta}`);\n});\n\n// For in\nfor (const indexFruta in arrayFrutas) {\n    console.log(indexFruta);\n}\n\n\n// Programa para imprimir por consola los numero del 10 al 55 (incluidos)\n// pares, y que no sean nu el 16 ni multiplos de 3\n\nlet number = 10;\n\nfor (let i = 10; i <= 55; i++) {\n    \n    if (((number % 3) === 0) || (number === 16)) {\n        number++\n    }else\n    {\n        console.log(number);\n        number++;\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/jhoshmc.js",
    "content": "let a = 6;\nlet b = 4;\nconst verdadero = true;\nconst falso = false;\n//* aritmeticos\nfunction operaciones_aritmeticas() {\n  let multiplicacion = a * b;\n  let divicion = a / b;\n  let suma = a + b;\n  let resta = a - b;\n  let resto = a % b;\n  console.log(\"\\t aritmeticos: \");\n  console.log(a + \" + \" + b + \" = \" + suma);\n  console.log(a + \" - \" + b + \" = \" + resta);\n  console.log(a + \" * \" + b + \" = \" + multiplicacion);\n  console.log(a + \" / \" + b + \" = \" + divicion);\n  console.log(a + \" % \" + b + \" = \" + resto);\n}\n\n//*operaciones logicos\nfunction logicos() {\n  let and_logico = a && b;\n  let or_logico = a || b;\n  let not_logico = !verdadero;\n  console.log(\"\\t operaciones logicas\");\n  console.log(\"verdadero o 1 \" + \" = \" + verdadero);\n  console.log(\"falso o 0 = \" + falso);\n  console.log(a + \" && \" + b + \" = \" + and_logico);\n  console.log(a + \" || \" + b + \" = \" + or_logico);\n  console.log(\"!\" + verdadero + \" = \" + not_logico);\n}\n\n//* operaciones de comparacion\nfunction comparacion() {\n  let a_cadena = a.toString(); // convirte el nuemero en una cadena\n  let igualdad_media = a == a_cadena; // no toma en cuenta el tipo de la variable\n  let igualdad_estricta = a === a_cadena;\n  let mayor = a > b;\n  let menor = a < b;\n  let mayor_igual = a >= b;\n  let menor_igual = a <= b;\n  let diferentes_medio = a != a_cadena; // no toma en cuenta el tipo de dato\n  let diferentes_estricto = a !== a_cadena; // toma en cuenta el tipo de dato\n  console.log(\"\\t comparacion\");\n  console.log(a + \" == \" + a_cadena + \" = \" + igualdad_media);\n  console.log(a + \" === \" + a_cadena + \" = \" + igualdad_estricta);\n  console.log(a + \" > \" + b + \" = \" + mayor);\n  console.log(a + \" < \" + b + \" = \" + menor);\n  console.log(a + \" >= \" + b + \" = \" + mayor_igual);\n  console.log(a + \" <= \" + b + \" = \" + menor_igual);\n  console.log(a + \" != \" + a_cadena + \" = \" + diferentes_medio);\n  console.log(a + \" !== \" + a_cadena + \" = \" + diferentes_estricto);\n}\n\n//*asignacion\nfunction asignacion() {\n  let n = 0;\n  console.log(\" n == \" + n);\n  console.log(\"n ahora le asignamos 5; n=5\");\n  n = 5;\n  console.log(\"n= \" + n);\n}\n//* pertenencia\nfunction pertenencia() {\n  let arr = [1, 2, 3, 4, 5, 6];\n  console.log(arr.includes(5));\n  console.log(arr.includes(8));\n}\n//* operadodes bit a bit\nfunction bit() {\n  let A = \"1010\";\n  let B = \"1011\";\n  console.log(A + \" & \" + B + \" = \" + (A & B));\n  console.log(A + \" | \" + B + \" = \" + (A | B));\n  console.log(A + \" XOR \" + B + \" = \" + (A ^ B));\n}\n//* estructuas de control\nfunction control() {\n  //* condicionales\n  if (4 == \"4\") {\n    console.log(\"es verdad porque == no ve el tipo del dato\");\n  }\n\n  let c = 4 === \"4\" ? \" \" : \"es falsa porque === si ve el tipo de dato\";\n  console.log(c);\n\n  //* bucles\n  console.log(\"for\");\n  for (let i = 0; i < 5; i++) {\n    console.log(i);\n  }\n  console.log(\"while\");\n  while (a > 1) {\n    console.log(a);\n    a--;\n  }\n  console.log(\"doWhile\");\n  do {\n    console.log(a);\n    a++;\n  } while (a <= 6);\n}\n//* excepciones (manejo de errores)\nfunction excepciones() {\n  try {\n    throw \"Error\";\n  } catch (error) {\n    console.log(error);\n  } finally {\n    console.log(\"Fin\");\n  }\n}\n\n//* dificultad extra\nfunction extra() {\n  let i = 10;\n  let fin = 55;\n  for (i; i <= 55; i++) {\n    if ((i % 2 === 0 && i !== 16 && i % 3 !== 0) || i === fin) {\n      console.log(i);\n    }\n  }\n}\n\noperaciones_aritmeticas();\nlogicos();\ncomparacion();\nasignacion();\npertenencia();\nbit();\ncontrol();\n// excepciones()\nextra();\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/joapalobael.js",
    "content": "// Operadores aritmeticos\nconst suma = (2 + 5);\nconst resta = (suma - 10);\nconst multiplicación = (suma * (-resta));\nconst divison = multiplicación / suma;\nlet sobrante = 12 % 5;\nconst exponente = 3 ** 9;\n\nlet x = 5;\nlet y = 5;\nx++; // aumentador\ny--; // disminuidor\n\n\n\n\n//Estructuras de control\n// If\nif (suma === 7) {\n    console.log(`La suma de 2+5 es igual a ${suma}`);\n}\n\n// If else\nif (suma === 5) {\n    console.log(`La suma de 2+5 es igual a ${suma}`)\n} else {\n    console.log(`5 es el resultado de sumar 2+3`);\n}\n\n// For\nfor (let index = 0; index < sobrante; index++) {\n    console.log(`Voy a contar del 0 al 1. ${index}/1`);\n}\n\n//while\n\nwhile (sobrante < suma) {\n    sobrante++;\n    console.log(\"Me encuentro dentro de un while\", sobrante);\n}\n\n//switch\n\nconst TipoDeFruta = \"anana\";\nswitch (TipoDeFruta) {\n    case \"naranja\":\n        console.log(\"Las naranjas cuestan $1200 por kg\")\n        break;\n    case \"pera\":\n        console.log(\"Las peras cuestan $2200 por kg\")\n        break;\n    case \"manzana\":\n        console.log(\"Las manzanas cuestan $2800 por kg\")\n        break;\n    default:\n        console.log(`Disculpa, no tenemos stock de ${TipoDeFruta} en este momento`)\n        break;\n}\n\n\n\n/*ABASTRACCIÓN DEL EJERCICIO*/\n/* inicio\n        Para los numeros entre 10 y 55 {\n            Si (el resto al dividir por 2 es 0 Y el numero es diferente a 16 Y el numero al dividirlo por 3 es diferente a 0){\n                mostrar por pantalla el número\n            }\n        }\nfin */\n\n//Resolución ejercicio extra\nconsole.log(\"#Resolución ejercicio extra\");\nfor (let index = 10; index <= 55; index++) {\n    if (index % 2 === 0 && index !== 16 && index % 3 !== 0)\n        console.log(`Numero: ${index}`);\n}\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/jolimadev2.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\nconst suma = a + b;\nconst resta = a - b\nconst division = a / b\nconst multiplicacion = a * b\nconst a = 23\nconst c= ++a\nconst b = --a\n//Asignación:\nconst x = x + y\nconst y = x | y\n//logicos AND\ntrue && true\ntrue && false\n//logicos OR\ntrue || true\ntrue || false\n'abc' || null\nundefined || 'abc'\n// bit a bit\na |= b // a = a |b\n\n\n//BONUS\n\nlet num1 = 10\nlet num2 = 55\nfor (let i = num1; num1 <= num2; num1++) {\n    if(i %2 === 0 && i !==16 && i % 3 !== 0){\n        console.log(i)\n    }\n    \n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/joshbaez.js",
    "content": "// OPERADORES \n\n// OPERADORES ARITMETICOS \n\nlet number1 = 15 \nlet number2 = 10\n\n//  SUMA (+) RESTA (-) MULTIPLICACION (*) DIVISION (/) MODULO (%)\n\nlet suma = number1 + number2; \nconsole.log(suma);\nlet resta = number1 - number2;\nconsole.log(resta);\nlet multi = number1 * number2;\nconsole.log(multi);\nlet divi = number1 / number2;\nconsole.log(divi);\nlet modu = number1 % number2;\nconsole.log(modu);\nlet expo = number1 ** number2;\nconsole.log(expo);\n\n// INCREMENTO (++)\n\nlet x = 5; \nconsole.log(x); // valor inicial de x: 5\n\nx++;\nconsole.log(x); // despues de incremento valor de x: 6\n\n// DECREMENTO (--) \n\nlet a = 10; \nconsole.log(a); // valor inicial de a: 10\n\na--;\nconsole.log(a); // despues de decremento valor de a: 9\n\n// INCREMENTO Y DECREMNETO CON OPERADORES PREFIJO Y SUFIJO\n\nlet c = 5; \nconsole.log(c); // valor inicial de c: 5 \n\nconsole.log(++c); // prefijo (++c) Incrementa c a 6 y devuelve 6\nconsole.log(c++); // sufijo (c++) Devuelve 6 y luego incrementa c a 7\n\nlet z = 10;\nconsole.log(z);\n\nconsole.log(--z); // Decrementa d a 9 y devuelve 9\nconsole.log(z--); // Devuelve 9 y luego decrementa d a 8\n\n// OPERADORES DE ASIGNACION \n\nlet ope = 10;\nconsole.log(ope); // 10 \n\n// Asignación de Suma (+=)\n\nope += 3; \nconsole.log(ope);\n\n// Asignación de Resta (-=)\n\nope -=  4;\nconsole.log(ope);\n\n// Asignación de Multiplicación (*=) \n\nope *= 20;\nconsole.log(ope);\n\n// Asignación de División (/=)\n\nope /= 7;\nconsole.log(ope);\n\n// Asignación de Módulo (%=)\n\nope %= 14;\nconsole.log(ope);\n\n// Asignación de Exponenciación (**=) \n\nope **= 50;\nconsole.log(ope);\n\n// OPERADORES DE COMPARACION \n\n// Igualdad ('==')\n\nconsole.log(5 == '5'); // true \nconsole.log(5 == 5); // true\nconsole.log(5 ==  6); // false \n\n// Desigualdad (!=)\n\nconsole.log(5 != '5'); // false debido a tipos diferentes\nconsole.log(5 != 6); // true \n\n// Identidad (===)\n\nconsole.log(5 === '5'); // false, no hay conversión de tipo\nconsole.log(5 === 5); // true \n\n// No identidad (!==)\n\nconsole.log(5 !== 5); // true \nconsole.log(5 !== 5); // false \n\n// Mayor que (>)\n\nconsole.log(10 > 5); // true \nconsole.log(5 > 10); // false \n\n// Mayor o igual que (>=)\n\nconsole.log(10 >= 5); // true \nconsole.log(5 >= 5); // false\nconsole.log(10 >= 10); // true \n\n// Menor que (<)\n\nconsole.log(5 < 10); // true\nconsole.log(10 < 5); // false \n\n// Menor o igual que (<=)\n\nconsole.log(5 <= 10); //true\nconsole.log(10 <= 5); // false\nconsole.log(5 <= 5); // ture \n\n// Operadores logicos\n\n// and logico \n\nconsole.log(true && true); // true\nconsole.log(true && false); // false \nconsole.log(false && true); // false\nconsole.log(false && false); // false \n\n// or logico \n\nconsole.log(true || true); // true\nconsole.log(true || false); // true \nconsole.log(false || true); // true \nconsole.log(false || false); // false\n\n// not logico \n\nconsole.log(!true); // false\nconsole.log(!false); // true \n\n// Operadores Bit a Bit\n\n// and bit a bit (&) \n\nlet j = 5;  // 0101 en binario\nlet b = 3;  // 0011 en binario\n\nconsole.log(a & b);  // 1 (0001 en binario)\n\n// OR bit a bit (|)\n\nlet g = 5;  // 0101 en binario\nlet t = 3;  // 0011 en binario\n\nconsole.log(a | b);  // 7 (0111 en binario)\n\n// XOR bit a bit (^)\n\nlet w = 5;  // 0101 en binario\nlet u = 3;  // 0011 en binario\n\nconsole.log(a ^ b);  // 6 (0110 en binario)\n\n// Operadores de cadena \n\n// concatenacion (+)\n\nlet nombre = \"josh\";\nlet apellido = \"baez\";\nlet nombreCompleto = nombre + \" \" +  apellido;\n\nconsole.log(nombreCompleto); // \"josh baez\"\n\n// asignacion (+=) \n\nlet mensaje = \"hola\"; \nmensaje += \"como estas\";\n\nconsole.log(mensaje); // \"hola como estas\"\n\n// plantillas literales \n\nlet apoodo = \"yandel\";\nlet edad = 22;\n\nlet saludo = `Hola, mi apodo es ${apoodo} y tengo ${edad} años.`;\nconsole.log(saludo); // hola mi apodo es yandel y tengo 22 anos \n\n// metodo concat()\n\nlet str1 = \"hola\";\nlet str2 = \"mundo\";\nlet resultado = str1.concat(\" \", str2 );\n\nconsole.log(resultado); // hola mundo\n\n// metodo slice() \n\nlet texto = \"me gusta javascript\";\nlet parte = texto.slice(0, 10);\n\nconsole.log(parte); // javascript\n\n// metodo toUpperCase() y toLowerCase()\n\nlet str = \"hola mundo\";\n\nconsole.log(str.toUpperCase()); // HOLA MUNDO \nconsole.log(str.toLowerCase()); // hola mundo\n\n// metodo replace() \n\nlet frase = \"me gusta mucho javascript\";\nlet nuevafrase = frase.replace(\"javascript\", \"programar\");\n\nconsole.log(nuevafrase); // me gusta programar \n\n// operadores tipo \n\n// typeof devuelve el tipo \n\nconsole.log(typeof 42);          // \"number\"\nconsole.log(typeof 'hello');     // \"string\"\nconsole.log(typeof true);        // \"boolean\"\nconsole.log(typeof undefined);   // \"undefined\"\nconsole.log(typeof {a: 1});      // \"object\"\nconsole.log(typeof [1, 2, 3]);   // \"object\" (en JavaScript, los arrays son objetos)\nconsole.log(typeof function(){});// \"function\"\nconsole.log(typeof null);        // \"object\" (esto es un error histórico en JavaScript)\n\n// instanceof \n\nfunction Person(name) {\n    this.name = name;\n}\n\nlet john = new Person('John');\n\nconsole.log(john instanceof Person); // true\nconsole.log(john instanceof Object); // true (en JavaScript, todos los objetos son instancias de Object)\nconsole.log([] instanceof Array);    // true\nconsole.log([] instanceof Object);   // true\n\n// operador condicional ternario \n\nlet edad1 = 18;\nlet mensaje1 = (edad >= 18) ? \"Es mayor de edad\" : \"Es menor de edad\";\nconsole.log(mensaje1);  // \"Es mayor de edad\"\n\n// dificulta extra: \n\nfor (let i = 10; i <= 55; i++) {\n    if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n        console.log(i);\n    }\n}\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/jrcoste6.js",
    "content": "/*Operadores aritméticos\n\n    **\n    Operador de Exponenciación.\n\n    *\n    Operador de multiplicación.\n\n    /\n    Operador de división.\n\n    %\n    Operador de residuos.\n\n    + \n    Operador de suma.\n\n    -\n    Operador de resta.\n\n*/\n\nconsole.log(5 ** 4);\nconsole.log(3 * 2);\nconsole.log(20 / 4);\nconsole.log(15 % 5);\nconsole.log(2 + 3);\nconsole.log(365 - 65);\n\n/*Operadores lógicos\n\n    &&\n    Operador lógico AND.\n\n    ||\n    Operador lógico OR.\n\n*/\n\nlet a =  4;\nlet b = -6;\n\nconsole.log(a > 0 && b > 0);\n\nlet a1 = 28;\nlet b2 = -12;\n\nconsole.log(a1 > 0 || b2 > 0);\n\n/*Operadores de comparación\n\n==\nComprueba si sus 2 operandos son iguales y retorna un valor booleano.\n\n!=\nOperador de desigualdad.\n\n===\nOperador de igualdad estricta.\n\n!==\nOperador de desigualdad estricta.\n\n*/\n\nlet X = 256;\nlet Y = 256;\n\nconsole.log(X == Y);\n\nlet number = 128;\nlet letter = \"128\";\n\nconsole.log(number != letter);\n\nlet valor = 0;\nlet booleano = false;\n\nconsole.log(valor === booleano);\n\nlet value = '1';\nlet bool = 1;\n\nconsole.log(value !== bool);\n\n//Operadores de asignación\n\n//Asignación\nlet numberA = 2;\nconsole.log(numberA);\n\n//Adición\nlet numberB = 4;\nlet numberC = 6;\nconsole.log(numberB += numberC); /* ==>Esto es X = X + Y*/\n\n//Resta\nlet numberD = 5;\nlet numberE = 3;\nconsole.log(numberD -= numberE); /* ==>Esto es X = X - Y*/\n\n//Multiplicación\nconsole.log(numberA *= numberB); /* ==>Esto es X = X * Y*/\n\n//División\nlet numberX = 10;\nlet numberY = 5;\nconsole.log(numberX /= numberY); /* ==>Esto es X = X / Y*/\n\n/*Operadores lógicos*/\n//AND lógico &&\nconsole.log(true && true);\nconsole.log(true && false);\nconsole.log(false && false);\nconsole.log(false && true);\n\n//OR lógico ||\nconsole.log(true || false);\nconsole.log(false || true);\nconsole.log(true || true);\n\n//NOT lógico !\nconsole.log(!true);\nconsole.log(!false);\n\n//Operador condicional (Ternario)\nlet numero = 10;\nlet resultado = numero % 2 === 0 ? \"Par\" : \"Impar\";\nconsole.log(resultado); // Imprime \"Par\"\n\n//Dificultad extra\nfor (let i = 10; i <= 55; i++) {\n    if (i % 2 === 0 && i !== 16 && i % 3 == 0) {\n        console.log(i);\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/juangomezn.js",
    "content": "/*-----------\n * OPERADORES\n-------------\n*/\n\n//Operadores Aritmeticos\nlet a = 8\nlet b = 5\n\n//Suma\nsuma = a + b\nconsole.log(suma)\n\n//Resta\nresta = a - b\nconsole.log(resta)\n\n//Multiplicación\nmultiplicación = a * b\nconsole.log(multiplicación)\n\n//División \ndivision = a / b\nconsole.log(division)\n\n//Módulo\nmodulo = a % b\nconsole.log(modulo)\n\n//Potenciación\npotenciacion = a ** 2\nconsole.log(potenciacion)\n\n\n//Operadores de Asignación \n\n//Asignación\nc = 5 // Se le da el valor de 5 a x\nconsole.log(c)\n\n//Asignación con Suma\nc = 5\nc += 5 // Se le da el valor de 5 a x y se suma 5 lo que da un valor de 10\nconsole.log(c)\n\n//Asignación con Resta\nc = 5\nc -= 5 // Se le da el valor de 5 a x y al restarle 5 da un valor de 0\nconsole.log(c)\n\n//Asignación con multiplicación\nc = 5 \nc *= 5 // Se le da un valor de 5 a x y al multiplicarle 5 da un valor de 25\nconsole.log(c)\n\n//Asignación con división \nc = 5\nc /= 5 //Se le da un valor de 5 a x y al dividirlo entre 5 da un valor de 1\nconsole.log(c)\n\n//Asignación con módulo\nc = 5\nc %= 5 // Se le da el valor de 5 a x y al dividirlo entre 5 el rsultado del modulo seria 0\nconsole.log(c)\n\n//Asignación con Potenciación\nc = 5\nc **= 2 //Se le da un valor de 5 a x y al potenciarlo por 2 da un resultado de 25\nconsole.log(c)\n\n\n//Operadores de Comparación\n\nlet d = 10\nlet e = 5\n\nconsole.log(d == e) //(Este operador representa \"igual a\")\nconsole.log(d === e) //(Este operador representa \"igual a con tipo\")\nconsole.log(d != e) //(Este operador representa \"no igual a\")\nconsole.log(d !== e) //(No igual a con tipo)\nconsole.log(d > e) //Mayor que\nconsole.log(d < e) // Menor que\nconsole.log(d >= e) //Mayor o igual que\nconsole.log(d <= e) // Menor o igual que\n\n\n//Operadores Logicos\n\nf = true\ng = false\n\nconsole.log(f && g) // Este operador representa Y Logico \nconsole.log(f || g) // Este operador representa O Logico \nconsole.log(!f) // Este operador representa Negación Logica\n\n\n//Operadores de Cadena (String)\n\nstr1 = \"Hola\"\nstr2 = \"Mundo\"\n\nconsole.log(str1 + \" \" + str2) // Concatenación = Hola Mundo\nconsole.log(str1 + \" \" + \"Amigo\") //Concatenación con Asignación = Hola Amigo\n\n\n//Operadores Ternarios\n\nedad = 18\nesAdulto = (edad >= 18) ? \"Adulto\" : \"Menor\";\nconsole.log(esAdulto)\n\n\n//Operadores de Tipo\n\nnumber = 42\ntext = \"Hola\"\n\nconsole.log(typeof number) //Operador utilizao para identificar el tipo de dato en este caso es number\nconsole.log(typeof text) //Operador utilizado para identificat el tipo de dato en este caso es string\nconsole.log(number instanceof Number) // False ya que \"number\" no es una instancia de \"Number\"\n\n//Operadores de Desestructuración\n\nlet arr = [1,2,3];\nlet [first, second] = arr\nconsole.log(first,second); \n\nlet obj = {name : \"Juan\", age : 25}\nlet{name, age} = obj\nconsole.log(name, age);\n\n\n/* \n * ----------------------\n * Estructuras de Control\n * ----------------------    \n */\n \n//Condicionales\n\nlet myString = \"\";\n\nif (myString == \"JuanG\") {\n    console.log(\"My String es JuanG\");\n}else if (myString == \"DavidG\") {\n    console.log(\"My String es DavidG\");\n} else {\nconsole.log('My String no es \"JuanG\" ni \"DavidG\"');\n}\n    \n //Iterativas\n\n for (let i = 0; i < 11; i++) {\n    console.log(i)\n}\n\n//Manejo de excepciones\n\ntry {\n    print(10/0)\n} catch (error) {\n    console.log(\"Se ha producido un error\")\n} finally{\nconsole.log(\"Ha finalizado el manejo de excepciones\")\n}\n\n/* \n * ----------------\n * Dificultad Extra\n * ----------------\n */\n\nfor (let i = 10; i <= 55; i++) {\n    if (i % 2 === 0 && i !==16 && i % 3 !== 0){\n    console.log(i)\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/julianbuitragocharry-dev.js",
    "content": "//✔️OPERADORES\n//✔️OPERADORES ARITMETICOS\nlet a = 5;\n\n//1️⃣=============================== PRE INCREMENTO\nlet preIncremento = ++a;\nconsole.log(preIncremento); // 6\nconsole.log(a); // 6\n\n//2️⃣=============================== POST INCREMENTO\nlet postIncremento = a++;\nconsole.log(postIncremento); // 6\nconsole.log(a); // 7\n\n//3️⃣=============================== PRE DECREMENTO                              \nlet preDecremento = --a;\nconsole.log(preDecremento); // 6\nconsole.log(a); // 6\n\n//4️⃣=============================== POST DECREMENTO\nlet postDecremento = a--;\nconsole.log(postDecremento); // 6\nconsole.log(a); // 5\n\n//✔️OPERADORES DE ASIGNACIÓN\nlet x = 7;\nlet y = 12; \n\n//1️⃣=============================== ASIGNACIÓN BÁSICA\nx = y;\nconsole.log(x); // 12\n\n//2️⃣=============================== ASIGNACIÓN DE ADICIÓN\nx += y; //x = x + y\nconsole.log(x); // 24 \n\n//3️⃣=============================== ASIGNACIÓN DE RESTA\nx -= y; //x = x - y\nconsole.log(x); // 12\n\n//4️⃣=============================== ASIGNACIÓN DE MULTIPLICACIÓN\nx *= y; //x = x * y\nconsole.log(x); // 144\n\n//5️⃣=============================== ASIGNACIÓN DE DIVISIÓN\nx /= y; //x = x / y\nconsole.log(x); // 12\n\n//6️⃣=============================== ASIGNACIÓN DE RESIDUO\nx %= y; //x = x % y\nconsole.log(x); // 0\n\n//7️⃣=============================== ASIGNACIÓN DE EXPONENTE\nx = 2;\ny = 3;\nx **= y; //x = x ** y;\nconsole.log(x); // 8\n\n//8️⃣=============================== ASIGNACIÓN DE DESPLAZAMIENTO A LA IZQUIERDA\nx <<= y; //x = x << y\nconsole.log(x); // 64 \n\n//9️⃣=============================== ASIGNACIÓN DE DESPLAZAMIENTO A LA DERECHA\nx >>= y; //x = x >> y\nconsole.log(x); // 8 \n\n//🔟=============================== ASIGNACIÓN DE DESPLAZAMIENTO A LA DERECHA SIN SIGNO\nx >>>= y; //x = x >>> y\nconsole.log(x); // 1 \n\n//1️⃣1️⃣=============================== ASIGNACIÓN AND BIT A BIT\nx &= y; //x = x & y\nconsole.log(x); // 1\n\n//1️⃣2️⃣=============================== ASIGNACIÓN XOR BIT A BIT\nx ^= y; //x = x ^ y\nconsole.log(x); // 2\n\n//1️⃣3️⃣=============================== ASIGNACIÓN OR BIT A BIT\nx |= y; //x = x | y\nconsole.log(x); // 3\n\n//1️⃣4️⃣=============================== ASIGNACIÓN AND LÓGICO\nlet z = null;\nx &&= z; //x = x && z\nconsole.log(x); // null (La asignación no se realiza porque la condición es falsa)\n\n//1️⃣5️⃣=============================== ASIGNACIÓN OR LÓGICO\nlet w = \"Valor\";\nx ||= w; //x = x || w\nconsole.log(x); // Valor (La asignación se realiza porque la condición es falsa)\n\n//1️⃣6️⃣=============================== ASIGNACIÓN DE ANULACIÓN\nlet u;\nx ??= u; // Equivalente a: x = x ?? u\nconsole.log(x); // Valor (La asignación se realiza porque x es null o undefined)\n\n\n//✔️OPERADORES DE COMPARACIÓN\n\n//1️⃣=============================== IGUAL\nconsole.log(6 == '6'); // true\nconsole.log(2 == '3'); // false\n\n//2️⃣=============================== NO ES IGUAL \nconsole.log(6 != '2'); // true\nconsole.log(2 != '2'); // false\n\n//3️⃣=============================== ESTRICTAMENTE IGUAL\nconsole.log(6 == '6'); // true\nconsole.log(2 == '3'); // false\n\n//4️⃣=============================== DESIGUALDAD ESTRICTA \nconsole.log(6 != '2'); // true\nconsole.log(2 != '2'); // false\n\n//5️⃣=============================== MAYOR QUE\nconsole.log(6 > 3); // true\nconsole.log(3 > 6); // false\n\n//6️⃣=============================== MAYOR O IGUAL QUE\nconsole.log(4 >= 4); // true\nconsole.log(7 >= 0); // false\n\n//7️⃣=============================== MENOR QUE\nconsole.log(2 <= 10); // true\nconsole.log(10 <= 2); // false\n\n//8️⃣=============================== MENOR O IGUAL QUE\nconsole.log(8 <= 8); // true\nconsole.log(7 <= 2); // false\n\n\n//✔️OPERADORES LOGICOS\n//Son utilizados para obtener booleanos, son equivalentes a las tablas de verdad.\n\n//1️⃣=============================== AND LOGICO\nconsole.log (true && true); // true\nconsole.log (false && true); // false\nconsole.log (true && false); // false\nconsole.log (false && false); // false\n\n//2️⃣=============================== OR LOGICO\nconsole.log (true || true); // true\nconsole.log (false || true); // true\nconsole.log (true || false); // true\nconsole.log (false || false); // false\n\n//3️⃣=============================== NOT LOGICO\nconsole.log(!false); // true\nconsole.log(!true); // false\n\n//✔️OPERADOR TERNIARIO\n// Se evalua como una condicion equivalente a un if {} else {}.\nconst age = 18;\nvar status = age >= 18 ? \"adult\" : \"minor\";\nconsole.log(`Operador Terniario ?: ${status}`); // adult\n\n//✔️OPERADOR UNITARIO DELETE\n//Elimina propiedades de objetos.\n\nlet persona = {nombre: \"Juan\", edad: 30, ciudad: \"Argentina\"};\nconsole.log(`Objeto original: ${persona}`); // { nombre : 'Juan', edad: 30 , ciudad : 'Argentina' }\n\n//=============================== Eliminando la propiedad 'ciudad' del objeto\nlet deleteSuccess = delete persona.ciudad;\nconsole.log(`Después de eliminar 'ciudad': ${persona}`); // { nombre : 'Juan', edad: 30 }\nconsole.log(`Operación 'delete' exitosa: ${deleteSuccess}`); // true\n\n//✔️OPERADOR DE RELACIÓN IN\n// Verificando si 'nombre' y 'apellido' son propiedades del objeto 'persona'\nconsole.log(\"¿'nombre' en persona?\", \"nombre\" in persona); // true\nconsole.log(\"¿'apellido' en persona?\", \"apellido\" in persona); // false\n\n\n//✔️ESTRUCTURAS DE CONTROL\n//✔️WHILE\nlet contadorWhile = 0;\nwhile (contadorWhile < 5) {\n    console.log(`Iteración: ${contadorWhile}`);\n    contadorWhile++;\n}\n\n//✔️DO WHILE\nlet contadorDoWhile = 0;\n\ndo {\n    console.log(`Iteración: ${contadorDoWhile}`);\n    contadorDoWhile++;\n} while (contadorDoWhile < 5);\n\n//✔️FOR\nfor (let i = 0; i < 5; i++) {\n    console.log(`Iteración: ${i}`);\n}\n\n//✔️FOR OF\nlet arrayForOf = [10, 20, 30];\n\nfor (let valor of arrayForOf) {\n    console.log(`Valor elemento arrayForOf: ${valor}`);\n}\n\n//✔️FOR IN\nlet objetoForIn = { a: 1, b: 2, c: 3 };\n\nfor (let propiedad in objetoForIn) {\n    console.log(`Propiedad ${propiedad} = ${objetoForIn[propiedad]}`);\n}\n\n//✔️FOR EACH\nlet arrayForEach = [1, 2, 3];\n\narrayForEach.forEach(function (elemento) {\n    console.log(`Elemento: ${elemento}`);\n});\n\n//✔️SWITCH\nlet opcion = 2;\n\nswitch (opcion) {\n    case 1:\n        console.log(\"Opción 1\");\n        break;\n    case 2:\n        console.log(\"Opción 2\");\n        break;\n    default:\n        console.log(\"Opción por defecto\");\n}\n\n\n//✔️IF ELSE\nlet numero = 7;\n\nif (numero > 0) {\n    console.log(\"Número positivo\");\n} else if (numero < 0) {\n    console.log(\"Número negativo\");\n} else {\n    console.log(\"Número es cero\");\n}\n\n//✔️TRY CATCH\nfunction dividirNumeros(a, b) {\n    try {\n        if (b === 0) {\n            throw new Error(\"¡División por cero no permitida!\");\n        }\n\n        let resultado = a / b;\n        console.log(`Resultado de la división: ${resultado}`);\n    } catch (error) {\n        console.error(`Error: ${error.message}`);\n    }\n}\n\ndividirNumeros(10, 2);  // 5\ndividirNumeros(8, 0);   // Error: ¡División por cero no permitida!\ndividirNumeros(12, 3);  // 4\n\n/*🧑‍💻DIFICULTAD EXTRA:\n Crea un programa que imprima por consola todos los números comprendidos\n entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n*/\n\nfor (let number = 10; number <= 55; number += 2) {\n    if (number == 16){\n        continue;\n    } else if (number % 3 == 0) {\n        continue;\n    } else {\n        console.log(number);\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/k3nvd.js",
    "content": "//DIFERENTS OPERATORS\n\n// COMPARATORS\n\nlet num1 = 10;\nlet num2 = 10;\n\nlet newtype = '10';\n\nconsole.log(num2 == newtype);       //True\nconsole.log(num2 === newtype);       //False\n\nconsole.log(num1 != num2);          //False\nconsole.log(num1 !== newtype);      //True for the data Type   \n\nconsole.log(num1 < 10);             //False\nconsole.log(num1 <= 10);            //True\n\nconsole.log(num1 > 10);              //False\nconsole.log(num1 >= 10);            //True\n\nif (num1 == num2 ){\n    console.log('EQUAL')            //EQUAL\n}\n\n\n// COMPARATOR FOR VALUE AND REFERENCE\n\n\n//VALUE\n\nlet x = 10;\nlet y = 10;\n\nconsole.log(x == y);    //True\n\n//reference, we make reference to the memory\n\nlet a = {value : 10};\nlet b = {value : 10};\n\nconsole.log(a == b );       //False\nconsole.log(a === b );       //False\n\nlet c = x;\n\nconsole.log(c == x);        //True\nconsole.log(c === x);       //True\n\n//ARIMETICS\n\nconsole.log(4+4);   //8\nconsole.log(4-4);   //0\nconsole.log(4/4);   //1\nconsole.log(4*4);   //16\nconsole.log(4%4);   //0\n\n//LOGICS OPERATORS  && || !\n\nlet txt1 = 'JS';\nlet txt2 = 'C++';\nlet txt3 = 'Python';\n\nconsole.log(txt1 === 'JS' && txt1 ==='JS');     //True\nconsole.log(txt1 === 'JS' && txt1 ==='js');     //False\n\nconsole.log(txt1 === 'JS' || txt1 ==='js');     //True\nconsole.log(txt1 === 'Python' || txt1 ==='js');     //False\n\nconsole.log(txt1 ==='JS' && txt2 === 'C++' || txt1 === 'Python' && txt3 === 'Python')       //True\n\nlet isSunny = false;\nif (!isSunny) {\n    console.log('It is not sunny');     //It is not sunny\n}\n\nconsole.log(!isSunny);          //True\n\n\n\n\n//CONDITIONALS\n//WITH          else if\nlet minAge = 18\nlet user1  = 18;\nlet user2 = 15;\nlet user3 = 22;\n\nif (user1 => 18){\n    console.log('Acces allowed', 'Age is: ' + user1);\n}else if (user1 < 18){\n    console.log('Sorry, Not Allowed');\n}else if (user3 > 18){\n    console.log('Allowed');\n}else {\n    console.log('There is an Error')\n}\n\n//CONDITIONALS\n//WITH          SWITCH\n\nlet administrator = 'Kevin';\n\nswitch (administrator)  {\n    case 'Peter':\n        console.log('Not Allowed');\n        break\n    case 'Kevin':\n        console.log('Congratulations, You are', administrator);\n        break\n    default:\n        console.log('There is an Error here.');\n}\n\n//TERNARY OPERATOR\n\nlet password = 1234;\nlet fulacces = password =='1234' ? 'That is correct' : 'The password is not correct';\n\nconsole.log(fulacces);\n\n//EXEPTIONS \n\nlet id = 12112;\n\n\ntry {\n    if(id != 1212) {\n        throw \"That is not correct,Please try again\";\n    }\n    console.log('That is correct');\n}catch (error){\n    console.error ('Errorrrrr', error);\n}\n\n\n//EXTRA\n\nlet iter = 10;\n\nwhile (iter <= 55) {\n    // console.log(iter);\n    iter +=1;\n    if (iter % 2 ==0 ) {\n        console.log('Is even', iter);\n    }else if (iter %3 ==0){\n        console.log('This is multiple 3',iter)\n    } else if (iter ==16 ) {\n        console.log('This numer is 6')\n\n    }\n}\n//Ouput\n/*\nIs even 12\nIs even 14\nThis is multiple 3 15\nIs even 16\nIs even 18\nIs even 20\nThis is multiple 3 21\nIs even 22\nIs even 24\nIs even 26\nThis is multiple 3 27\nIs even 28\nIs even 30\nIs even 32\nThis is multiple 3 33\nIs even 34\nIs even 36\nIs even 38\nThis is multiple 3 39\nIs even 40\nIs even 42\nIs even 44\nThis is multiple 3 45\nIs even 46\nIs even 48\nIs even 50\nThis is multiple 3 51\nIs even 52\nIs even 54\nIs even 56\n*/\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/k4rv3r.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n///////////////////////////////////////////////////////////////////////////\n\n// --  OPERADORES  --\n/*\n    Indice:\n        - 01.Operadores de asignación\n        - 02.Operadores de comparación\n        - 03.Operadores de aritméticos\n        - 04.Operadores bit a bit (bitwise)\n        - 05.Operadores lógicos\n        - 06.Operadores de cadena (string)\n        - 07.Operadores condicional (ternario)\n        - 08.Operadores coma \n        - 09.Operadores unarios\n        - 10.Operadores relacionales\n*/\n\n// -- 01 OPERADORES DE ASIGNACIÓN --\nlet x = 4;\nlet y = 3;\n// Asignación\nconsole.log(x = y); // x = 3\n\n// Asignación de adición\nconsole.log(x += y); // x + y => 4 + 3 = 7\n\n// Asignación de resta\nconsole.log(x -= y); // x - y => 4 - 3 = 1\n\n// Asignación de multiplicación\nconsole.log(x *= y); // x * y => 4 * 3 = 12\n\n// Asignación de división\nconsole.log(x /= y); // x / y => 4 / 3 = 1.333333....\n\n// Asignación de residuo (modulo/module)\nconsole.log(x %= y); // x % y => 4 % 3 = 1\n\n// Asignación de exponenaciación\nconsole.log(x **= y); // x ** y => 4 ** 3 = 64\n\n// Asignación de desplazamientos a la izquierda\nconsole.log(x <<= y); /* Aplica en binario:\n    let a = 5; (5 = 00000000000000101)\n    a <<= 2; (00000000000010100 = 20)\n*/\n\n// Asignación de desplazamientos a la derecha\nconsole.log(x >>= y); /* Aplica en binario:\n    let a = 20; (20 = 00000000000010100)\n    a >>= 2; (00000000000000101 = 5)\n*/\n\n// Asignación de desplazamiento a la derecha sin signo\nconsole.log(x >>>= y); /* Aplica en binario:\n    let a = 5; (5 = 00000000000000101)\n    a >>>= 2; (00000000000000001 = 1)\n\n    let b = -5 (-00000000000000000000000000000101)\n    b >>>= 2; (00111111111111111111111111111110)\n*/\n\n// Asignación AND bit a bit (bitwise)\nconsole.log(x &= y); // x & y => 1 & 1 = 1 => true & true = true\n\n// Asignación XOR bit a bit (bitwise)\nconsole.log(x ^= y); /* \nx ^ y => 1 ^ 1 = 0 => true ^ true = false \nx ^ y => 1 ^ 0 = 1 => true ^ false = true \n00101 ^ 00011 = 00110 (5 ^ 3 = 6)\n*/ \n\n// Asignación OR bit a bit (bitwise)\nconsole.log(x |= y); /*\nx | y => 1 | 1 = 1 => true | true = true \nx | y => 1 | 0 = 1 => true | false = true \nx | y => 0 | 0 = 0 => false | false = false \n00101 | 00011 = 00111 (5 | 3 = 7)\n*/ \n\n// Asignación AND lógico\n/*\n    Este evalua el operando de la derecha y lo asigna a la izquierda \n    SOLO si el operando de la izquierda es VERDADERO (Truthy).\n\n    Un valor VERDADERO (Truthy) es aquel que es considerado como \"true\"\n    en una operacion booleana.\n\n    Todos los valores se consideran VERDADEROS (Truthy) si\n    no son considerados \"Falsy\".\n\n    Los valores \"Falsy\" son:\n    false, 0, -0, 0n, \"\", null, undefined, Nan (Not A Number) y document.all\n*/ \nconsole.log(x &&= y); /*\nlet a = 1;\nlet b = 0;\n\na &&= 2; => Aqui a se convierte en 2.\nb &&= 2 => Aqui b NO se convierte en 2 y permanece en 0\n*/\n\n// Asignación OR lógico\nconsole.log(x ||= y); /* \nconst a = { duracion: 50, titulo: '' };\n\na.duracion ||= 10;\nconsole.log(a.duracion);\n    -Resultado: 50 (Porque a.duracion = true)\n\na.titulo ||= 'No hay titulo';\nconsole.log(a.tirulo);\n    -Resultado: 'No hay titulo' (Porque a.titulo = false)\n*/\n\n// Asignación de anulación lógica\nconsole.log(x ??= y); /*\nconst a = { duration: 50 };\n\na.speed ??= 25;\nconsole.log(a.speed);\n    -Resultado: 25 (Porque el valor \"speed\" es nulo.)\n\na.duration ??= 10;\nconsole.log(a.duration);\n    -Resultado: 50 (Porque el valor \"duration\" existe.)\n*/\n\n/////////////////////////////////////\n\n// -- 02 OPERADORES DE COMPARACIÓN --\n\nlet igual = (x == y); // Devuelve true si los operandos son iguales.\nlet noEsIgual = (x != y); // Devuelve true si los operandos NO son iguales.\nlet estrictamenteIgual = (x === y); // Devuelve true si los operandos son iguales y del mismo tipo.\nlet desigualdadEstricta = (x !== y); // Devuelve true si los operandos son del mismo tipo pero no iguales, o son de diferente tipo.\nlet mayorQue = (x > y); // Devuelve true si el operando izquierdo es mayor que el operando derecho.\nlet mayorIgualQue = (x >= y); // Devuelve true si el operando izquierdo es mayor o igual que el operando derecho.\nlet menorQue = (x < y); // Devuelve true si el operando izquierdo es menor que el operando derecho.\nlet menorIgualQue = (x =< y); // Devuelve true si el operando izquierdo es menor o igual que el operando derecho.\n\n/////////////////////////////////////\n\n// -- 3 OPERADORES ARITMÉTICOS --\n\nlet residuo = \"%\" // Operador binario. Devuelve el resto entero de dividir los dos operandos. (12 % 5 = 2)\n\nlet incremento = \"++\" /* Operador unario. Agrega uno a su operando.\n    Si se usa como operador prefijo (++x), devuelve el valor de su operando después de agregar uno; \n    si se usa como operador sufijo (x++), devuelve el valor de su operando antes de agregar uno.\n*/\n\nlet decremento = \"--\" /* Operador unario. Resta uno de su operando. \n    El valor de retorno es análogo al del operador de incremento.\n*/\n\nlet negacionUnaria = \"-\" /* Operador unario. Devuelve la negación de su operando. \n    Si x es 3, entonces -x devuelve -3.\n*/\n\nlet positivoUnario = \"+\" /* Operador unario. Intenta convertir el operando en un número, si aún no lo es. \n    +\"3\" devuelve 3. +true devuelve 1.\n*/\n\nlet operadorExponencial = \"**\" /* Calcula la base a la potencia de exponente, es decir, baseexponente.\n    2 ** 3 devuelve 8. 10 ** -1 devuelve 0.1.\n*/\n\n/////////////////////////////////////\n\n// -- 4 OPERADORES BIT A BIT (BITWISE) --\n\n// AND a nivel de bits:\nlet and = a & b; /* Devuelve un uno en cada posición del bit para los que los bits correspondientes de ambos operandos son unos.\n    00101\n    01101\n    -----\n    00101\n*/\n\n// OR a nivel de bits:\nlet or = a | b; /* Devuelve un cero en cada posición de bit para el cual los bits correspondientes de ambos operandos son ceros.\n    00101\n    01101\n    -----\n    01101\n*/\n\n// XOR a nivel de bits:\nlet xor = a ^ b; /* Devuelve un cero en cada posición de bit para la que los bits correspondientes son iguales. \n[Devuelve uno en cada posición de bit para la que los bits correspondientes son diferentes].\n    00101\n    01101\n    -----\n    01000\n*/\n\n// NOT a nivel de bits:\nlet not = ~ a; /* Invierte los bits de su operando.\n    00101\n    -----\n    11010\n*/\n\n// Desplazamiento a la izquierda:\nlet leftShift = a << b; /* Desplaza a en representación binaria b bits hacia la izquierda, desplazándose en ceros desde la derecha.\n    let a = 6 (0000110)\n    let b = 2\n    a << b = 24 (0011000)\n*/\n\n// Desplazamiento a la derecha de propagación de signo\nlet rightShift = a >> b; /* Desplaza a en representación binaria b bits hacia la izquierda, desplazándose en ceros desde la derecha.\n    let a = 6 (0000110)\n    let b = 2\n    a >> b = 1 (00001)\n*/\n\n// Desplazamiento a la derecha de relleno cero\nlet rightZeroFillShift = a >>> b; /* Desplaza a en representación binaria b bits hacia la derecha, descartando los bits desplazados y desplazándose en ceros desde la izquierda.\n    let a = 6 (0000110)\n    let b = 2\n    a >>> b = 1 (0000001)\n*/\n\n/////////////////////////////////////\n\n// -- 5 OPERADORES LOGICOS --\n\n// AND Lógico (&&)\nlet a1 = true && true; // t && t devuelve true\nlet a2 = true && false; // t && f devuelve false\nlet a3 = false && true; // f && t devuelve false\nlet a4 = false && 3 == 4; // f && f devuelve false\nlet a5 = \"Cat\" && \"Dog\"; // t && t devuelve Dog\nlet a6 = false && \"Cat\"; // f && t devuelve false\nlet a7 = \"Cat\" && false; // t && f devuelve false\n\n// OR Lógico (||)\nlet o1 = true || true; // t || t devuelve true\nlet o2 = false || true; // f || t devuelve true\nlet o3 = true || false; // t || f devuelve true\nlet o4 = false || 3 == 4; // f || f devuelve false\nlet o5 = \"Cat\" || \"Dog\"; // t || t devuelve Cat\nlet o6 = false || \"Cat\"; // f || t devuelve Cat\nlet o7 = \"Cat\" || false; // t || f devuelve Cat\n\n// NOT Lógico (!)\nlet n1 = !true; // !t devuelve false\nlet n2 = !false; // !f devuelve true\nlet n3 = !\"Cat\"; // !t devuelve false\n\n// -- 6 OPERADORES DE CADENA (STRING) --\n/*\n    Además de los operadores de comparación, que se pueden usar en valores de cadena, \n    el operador de concatenación (+) concatena dos valores de cadena, \n    devolviendo otra cadena que es la unión de los dos operandos de cadena.\n*/\n\nconsole.log(\"mi \" + \"cadena\"); // la consola registra la cadena \"mi cadena\".\n\nvar mystring = \"alpha\";\nmystring += \"bet\"; // se evalúa como \"alphabet\" y asigna este valor a mystring.\n\n// -- 7 OPERADOR CONDICIONAL (TERNARIO) --\n/*\n    El operador condicional es el único operador de JavaScript que toma tres operandos. \n    El operador puede tener uno de dos valores según una condición. \n    La sintaxis es:\n*/\ncondition ? val1 : val2\n\nlet status = age >= 18 ? \"adult\" : \"minor\";\n\n// -- 8 OPERADOR COMA --\nlet x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];\nlet a = [x, x, x, x, x];\n\nfor (var i = 0, j = 9; i <= j; i++, j--)\n  //                              ^\n  console.log(\"a[\" + i + \"][\" + j + \"]= \" + a[i][j]);\n\n  // -- 9 OPERADORES UNARIOS --\n  // Una operación unaria es una operación con un solo operando.\n\ndelete object.property;\ndelete object[propertyKey];\ndelete objectName[index];\ndelete property; // legal solo dentro de una declaración with\n\n// -- 10  OPERACIONES RELACIONALES --\n// Un operador relacional compara sus operandos y devuelve un valor Boolean basado en si la comparación es verdadera.\npropNameOrNumber in objectName;\n// -----------------------------\n\n// Arreglos (Arrays)\nvar trees = ['redwood', 'bay', 'cedar', 'oak', 'maple'];\n0 in trees;        // devuelve true\n3 in trees;        // devuelve true\n6 in trees;        // devuelve false\n'bay' in trees;    // devuelve false (debes especificar el número del índice,\n                   // no el valor en ese índice)\n'length' in trees; // devuelve true (la longitud es una propiedad de Array)\n\n// objetos integrados\n'PI' in Math;          // devuelve true\nvar myString = new String('coral');\n'length' in myString;  // devuelve true\n\n// Objetos personalizados\nvar mycar = { make: 'Honda', model: 'Accord', year: 1998 };\n'make' in mycar;  // devuelve true\n'model' in mycar; // devuelve true\n\n// instanceof\n// El operador instanceof devuelve true si el objeto especificado es del tipo de objeto especificado.\n//La sintaxis es:\nobjectName instanceof objectType\n\nvar theDay = new Date(1995, 12, 17);\nif (theDay instanceof Date) {\n  // instrucciones a ejecutar\n}\n\n///////////////////////////////////////////////////////////////////////////\n\n// -- ESTRUCTURAS DE CONTROL --\n/*\n    ‌Las estructuras de control de flujo,\n    son intrucciones que nos permiten evaluar si se puede cumplir una condición o no,\n    incluso nos puede ayudar a evaluarla n cantidad de veces.\n*/\n\n// --  CONDICIONALES  --\n\nconst mayorEdad = 18;\nif (mayorEdad >= 18) {\n    HTMLFormControlsCollection.log (\"Es mayor de edad\");\n}else{\n    console.log (\"Es menor de edad\");\n} \n\nconst mayorEdad = 18;\nif (mayorEdad >= 18) {\n    HTMLFormControlsCollection.log (\"Es mayor de edad\");\n}else if (mayorEdad > 18 && mayorEdad < 25){\n    console.log (\"Es joven adulto.\");\n}else{\n    console.log (\"Es menor de edad\");\n} \n\n// --  CICLOS, BUCLES O LOOPS  --\n/*\n    Se le pueden llamar, ciclos, bucles o loops, en ellos se evalua una condición n veces hasta que esta se cumpla.\n    En estos podemos encontrar los for, while, entre otros.‌\n*/\n\n// for\nconst pasos = 5;\nfor(let paso = 0; paso <= pasos; paso++){\n    console.log(\"Estoy dando el siguiente paso: \" + paso);\n}\n\n// while\nconst contador = 0;\nwhile(contador < 3) {\n    contador++;\n}\nconsole.log(\"Contador es igual a: \", contador);\n\n// switch\nswitch(tipoFrutas) {\n    case \"Naranjas\":\n        console.log(\"Las naranjas cuestan 4€\");\n        break;\n    case \"Manzanas\":\n        console.log(\"Las manzanas cuestan 2€\");\n        break;\n    case \"Cerezas\":\n        console.log(\"Las cerezas cuestan 7€\");\n        break;\n    case \"default\":\n        console.log(\"Las tenemos\", tipoFruta);\n        break;\n}\n\n\n///////////////////////////////////////////////////////////////\n// DIFICULTAD EXTRA:\nlet i = 10;\nwhile (i >= 10 && i <=55 && i) {\n    if (i % 2 == 0 && i % 3 != 0 && i != 16) {\n        console.log(i, \"Es par, no es multiplo de 3 y no es 16\");\n    }\n    i++;\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/kaesar84.js",
    "content": "/*\n# #01 OPERADORES Y ESTRUCTURAS DE CONTROL\n> #### Dificultad: Fácil | Publicación: 02/01/24 | Corrección: 08/01/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n/*```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n*/\n\nconsole.log(\"** OPERADORES **\")\nconsole.log(\"--------------------------------------\")\n// Operadores aritméticos\nlet a = 10\nlet b = 25\n\nconsole.log(\"** Operadores aritméticos **\")\nconsole.log(`Suma: a + b = ${a + b}`)\nconsole.log(`Resta:  a - b =  ${a - b}`)\nconsole.log(`Multiplicación:  a * b = ${a + b}`)\nconsole.log(`División:  a / b = ${a + b}`)\nconsole.log(`Módulo:  a % b = ${a % b}`)\nconsole.log(`Potencia:  a ** b = ${a ** b}`)\n\nconsole.log(\"** Auto increment - Auto decremento **\")\n\na++ //auto-incremento\nconsole.log(`a++ // auto-incremento -> ${a}`)\na-- //auto-decremento\nconsole.log(`a-- // auto-incremento -> ${a}`)\nconsole.log(\"--------------------------------------\")\n\n// Operadores de asignación\nconsole.log(\"** Operadores de asignación **\")\nlet c = 15\nconsole.log(`c=${c} -> ${c}`)\nc += 5 // c = c + 5\nconsole.log(`c+=5 // c = c + 5 -> ${c}`)\nc -= 5 // c = c - 5\nconsole.log(`c-=5 // c = c - 5 -> ${c}`)\nc *= 5 // c = c * 5\nconsole.log(`c*=5 // c = c * 5 -> ${c}`)\nc /= 5 // c = c / 5\nconsole.log(`c/=5 // c = c / 5 -> ${c}`)\nconsole.log(\"--------------------------------------\")\n\n// Operadores Relacionales\nconsole.log(\"** Operadores relacionales **\")\na = 55\nb = 69\nconsole.log(\"a = \" + a)\nconsole.log(\"b = \" + b)\n\nconsole.log(`a === b // estrictamente igual -> ${a === b}`) // estrictamente igual\nconsole.log(`a == b //  igual -> ${a == b}`) // igual\nconsole.log(`a != b //  distinto -> ${a != b}`) // distinto\nconsole.log(`a > b //  mayor que -> ${a > b}`) // mayor\nconsole.log(`a >= b //  mayor o igual que -> ${a > b}`) // mayor o igual\nconsole.log(`a < b //  menor que -> ${a < b}`) // menor\nconsole.log(`a <= b //  menor o igual que -> ${a <= b}`) // menor o igual\nconsole.log(\"--------------------------------------\")\n\n// Truthy (valores verdaderos determinados por el lenguaje)\n// Todos los números, excepto 0\n// Todos los strings, excepto \"\" (vacío)\n// Todos los booleans, excepto false\nconsole.log(`** Valores Truthy **\n// Todos los números, excepto 0\n// Todos los strings, excepto \"\" (vacío)\n// Todos los booleans, excepto false\\n`)\n\n// Falsy (valores falsos determinados por el lenguaje)\n// 0 (número)\n// \"\" (string vacío)\n// false (boolean)\n// null\n// undefined\n// NaN (número no numérico)\nconsole.log(` ** Valores Falsy **\n// Falsy (valores falsos determinados por el lenguaje)\n// 0 (número)\n// \"\" (string vacío)\n// false (boolean)\n// null\n// undefined\n// NaN (número no numérico)`)\nconsole.log(\"--------------------------------------\")\n\n// Operadores lógicos\nconsole.log(\"** Operadores lógicos **\")\na = 55\nb = 76\nconsole.log(\"a = \" + a)\nconsole.log(\"b = \" + b)\n\nconsole.log(`AND -> a > b && a > b -> ${a > b && a > b}`) //AND\nconsole.log(`OR -> a < b || a > b -> ${a < b || a > b}`) //OR\nconsole.log(`NOT -> !(a > b && a > b) -> ${!(a > b && a > b)}`) //NOT\nconsole.log(\"--------------------------------------\")\n\n// Operadores ternarios\nconsole.log(\"** Operador ternario **\")\nlet isIce = 0\nconsole.log(`isIce = 0`)\nconsole.log(\n  `isIce == 0 ? console.log(\"Agua Congelada\") : console.log(\"Agua líquida\")`\n)\nisIce == 0 ? console.log(\"Agua Congelada\\n\") : console.log(\"Agua líquida\\n\")\nisIce = 10\nconsole.log(`isIce = 10`)\nconsole.log(\n  `isIce == 10 ? console.log(\"Agua Congelada\") : console.log(\"Agua líquida\")`\n)\nisIce == 0 ? console.log(\"Agua Congelada\\n\") : console.log(\"Agua líquida\\n\")\nconsole.log(\"--------------------------------------\")\n\nconsole.log(\"** ESTRUCTURAS DE CONTROL **\")\nconsole.log(\"--------------------------------------\")\n\nconsole.log(\"** if **\")\nc = \"js\"\nconsole.log(`c=${c}`)\nconsole.log(`\n    if(c==\"js\"){\n    console.log(\"El lenguaje seleccionado es JavaScript\\n\")\n}\n    `)\nconsole.log(\"-- Respuesta:\")\nif (c == \"js\") {\n  console.log(\"El lenguaje seleccionado es JavaScript\\n\")\n}\nconsole.log(\"---------\")\nconsole.log(\"** if else **\")\nc = \"other\"\nconsole.log(`c=${c}`)\nconsole.log(`\n    if(c==\"other\"){\n    console.log(\"El lenguaje seleccionado es JavaScript\\n\")\n}else{\n    console.log(\"El lenguajes NO es Javascript\\n\")\n}\n    `)\nconsole.log(\"-- Respuesta:\")\nif (c == \"js\") {\n  console.log(\"El lenguaje seleccionado es JavaScript\\n\")\n} else {\n  console.log(\"El lenguajes NO es Javascript\\n\")\n}\nconsole.log(\"---------\")\nconsole.log(\"** if - else if - else **\")\nc = \"python\"\nconsole.log(`c=${c}`)\nconsole.log(`\nif(c==\"js\"){\n    console.log(\"El lenguaje seleccionado es JavaScript\\n\")\n}\nelse if(c==\"python\"){\n    console.log(\"El lenguaje seleccionado es Python\\n\")\n}\nelse{\n    console.log(\"El lenguajes NO es Javascript ni Python\\n\")\n}\n    `)\nconsole.log(\"-- Respuesta:\")\n\nif (c == \"js\") {\n  console.log(\"El lenguaje seleccionado es JavaScript\\n\")\n} else if (c == \"python\") {\n  console.log(\"El lenguaje seleccionado es Python\\n\")\n} else {\n  console.log(\"El lenguajes NO es Javascript ni Python\\n\")\n}\nconsole.log(\"--------------------------------------\")\n\nconsole.log(\"** switch **\")\n// switch\nlet colorSemaforo = \"verde\"\nconsole.log(`colorSemaforo=${colorSemaforo}`)\n\nconsole.log(`\n   switch (colorSemaforo) {\n  case \"rojo\":\n    console.log(\"Prohibido el paso\")\n    break\n  case \"verde\":\n    console.log(\"Puedes pasar\")\n    break\n  case \"amarillo\":\n    console.log(\"Precaución\")\n    break\n  default:\n    console.log(\"El color no es reconocido\")\n}`)\n\nconsole.log(\"-- Respuesta:\")\n\nswitch (colorSemaforo) {\n  case \"rojo\":\n    console.log(\"Prohibido el paso\")\n    break\n  case \"verde\":\n    console.log(\"Puedes pasar\")\n    break\n  case \"amarillo\":\n    console.log(\"Precaución\")\n    break\n  default:\n    console.log(\"El color no es reconocido\")\n}\n\nconsole.log(\"--------------------------------------\")\nconsole.log(\"** LOOPS **\")\nconsole.log(\"** for **\")\nconsole.log(`-- Bucle que imprime los números del 1 al 10\\n\nfor (let i = 1; i <= 10; i++) {\n    console.log(\"Valor: \" + i)\n}\\n`)\n\nconsole.log(\"-- Respuesta:\")\nfor (let i = 1; i <= 10; i++) {\n  console.log(\"Valor: \" + i)\n}\n\nconsole.log(\"--------------------------------------\")\n\nconsole.log(\"** while **\")\nconsole.log(`-- Bucle que imprime mientras la rotación sea menor que 5\\n\nlet d=0\n    while(d<5){\n        console.log(\"Rotación núm: \" + (d+1))\n        d++\n    }\\n`)\n\nconsole.log(\"-- Respuesta:\")\nlet d = 0\nwhile (d < 5) {\n  console.log(\"Rotación núm: \" + (d + 1))\n  d++\n}\n\nconsole.log(\"--------------------------------------\")\nconsole.log(\"** do while **\")\nconsole.log(`-- Buecle que se ejecuta mínimo una vez\\n\nen este caso la condición es ejecutarse en números positivos\nd=-1\n    do{\n        console.log(\"Ejecución forzada\")\n    }while(d>0)\\n`)\n\nconsole.log(\"-- Respuesta:\")\nd = -1\ndo {\n  console.log(\"Ejecución forzada\")\n} while (d > 0)\nconsole.log(\"--------------------------------------\")\n\nconsole.log(\"** EXCEPCIONES **\")\nconsole.log(\"--------------------------------------\")\n\nconsole.log(\"** try catch **\")\nconsole.log(` Producimos error, se intenta ejecutar el try, en caso de error aplica el catch\\n\n    try{\n        g>10\n    }catch{\n        console.log(\"La variable no existe\")\n    }\n    `)\n\nconsole.log(\"-- Respuesta:\")\ntry {\n  g > 10\n} catch {\n  console.log(\"La variable no existe\")\n}\nconsole.log(\"--------------------------------------\")\n\nconsole.log(\"** try catch - Captura de errores**\")\nconsole.log(`Producimos error y capturamos mensaje a traves del objeto error\\n\n    try {\n    g > 10\n  } catch (error) {\n    console.log(\"¡Se ha producido un error:! \", error.message)\n  }\n    `)\n\nconsole.log(\"-- Respuesta:\")\ntry {\n  g > 10\n} catch (error) {\n  console.log(\"¡Se ha producido un error:! \", error.message)\n}\n\nconsole.log(\"--------------------------------------\")\n\nconsole.log(\"** try catch finally **\")\nconsole.log(`El bloque finally se ejecuta siempre\\n\n    try {\n  console.log(g > 69)\n} catch (error) {\n  console.log(\"Se ha producido un error:\", error.message)\n} finally {\n  console.log(\"Este código se ejecuta siempre\")\n}\n    `)\n\nconsole.log(\"-- Respuesta:\")\ntry {\n  console.log(g > 69)\n} catch (error) {\n  console.log(\"Se ha producido un error:\", error.message)\n} finally {\n  console.log(\"Este código se ejecuta siempre\")\n}\nconsole.log(\"--------------------------------------\")\n\nconsole.log(\"** throw - Lanzamiento de errores **\")\nconsole.log(`\nthrow new Error(\"Error Lanzado\")\n    `)\n// throw new Error(\"Error Lanzado\")\nconsole.log(\"--------------------------------------\")\n\nconsole.log(\"** throw - Personalizado **\")\nconsole.log(\n  `try {\n        throw new ErrorPersonalizado(\"Se ha producido un error\")\n      } catch (error) {\n        console.log(\n          \"Error personalizado:\" + \"***\" + error.name + \"***\\n\" + error.message\n        )\n      }\n      `\n)\n\nconsole.log(\"-- Respuesta:\")\n\ntry {\n  throw new ErrorPersonalizado(\"Se ha producido un error\")\n} catch (error) {\n  console.log(\n    \"Error personalizado:\" + \"***\" + error.name + \"***\\n\" + error.message\n  )\n}\n\n// EXTRA\n// Crea un programa que imprima por consola todos los números comprendidos\n// entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\nconsole.log(\"--------------------------------------\")\nconsole.log(\"--------------------------------------\")\nconsole.log(\"** EXTRA **\")\nconsole.log(\"--------------------------------------\")\n\nfor (let i = 10; i <= 55; i++) {\n  if ((i % 2 == 0) && (i!=16) & (!(i%3==0))) {\n    console.log(i)\n  }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n_______________________________________\n01 OPERADORES Y ESTRUCTURAS DE CONTROL\n---------------------------------------\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n*/\n\n// Tipos de operadores\n// https://developer.mozilla.org/es/docs/Learn/Getting_started_with_the_web/JavaScript_basics#operadores\n\n// concatena\nlet greeting = \"Hola \" + \"mundo!\";\nconsole.log(greeting) // \"Hola mundo!\"\n\n// _______________________\n// Operadores aritmeticos:\nlet sumResult = 6 + 9;\nconsole.log(sumResult); // 15\n\nlet subtractResult = 9 - 3;\nconsole.log(subtractResult); // 6\n\nlet multiplicationResult = 8 * 2;\nconsole.log(multiplicationResult); // 16\n\nlet divisionResult = 9 / 3;\nconsole.log(divisionResult); // 3\n\nlet remainder = 20 % 7;\nconsole.log(remainder); // 6\n\nlet power = 2 ** 3;\nconsole.log(power); // 8\n\n// _______________________\n// Operador de asignación:\nlet myString = 'Ken';\nconsole.log(myString); // \"Bob\"\n\nlet b = 3;\nb += 2; // Aplicable a todos los operadores aritméticos.\nconsole.log(b) // 5\n\n// _______________________\n// Operadores de Comparación:\nlet equal = 5 == 5; // Igual a\nconsole.log(`5 == 5 -> ${equal}`); // true\n\nlet notEqual = 5 != 5; // Diferente de\nconsole.log(`5 != 5 -> ${notEqual}`); // false\n\nlet lessThan = 4 < 5; // Menor que\nconsole.log(`4 < 5 -> ${lessThan}`); // true\n\nlet greaterThan = 4 > 5; // Mayor que\nconsole.log(`4 > 5 -> ${greaterThan}`); // false\n\nlet lessThanOrEqual = 4 <= 5; // Menor o igual\nconsole.log(`4 <= 5 -> ${lessThanOrEqual}`); // true\n\nlet greaterThanOrEqual = 4 >= 5; // Mayor o igual\nconsole.log(`4 >= 5 -> ${greaterThanOrEqual}`); // false\n\n// Estructuras de control\n// _______________________\n// condicinal:\n// https://developer.mozilla.org/es/docs/Learn/JavaScript/Building_blocks/conditionals\n\nif (5 == 5) { // Aplicable a todos los operadores de Comparación.\n    console.log(\"si lo es.\");\n} else {\n    console.log(\"No lo es.\");\n}\n\n// Con operadores lógicos:\nif (5 == 5 && 7 < 10) { // Equivalente a 'and'\n    console.log(\"si lo son.\");\n}\n\nif (5 == 5 || 7 < 10) { // Equivalente a 'or'\n    console.log(\"Uno de los dos es 'true'.\");\n}\n\nif (!(5 == 6)) { // Equivalente a 'not'\n    console.log(\"No lo es.\");\n}\n\n// Declaraciones con switch\nlet day = 1;\nswitch (day) {\n    case 1:\n        console.log(\"Lunes\");\n        break;\n    case 2:\n        console.log(\"Martes\"); \n        break;\n    \n    default:\n        console.log(\"Día no válido\");\n}\n\n// Operador Ternario\nlet age = 17;\nlet msg = (age >= 18) ? \"Eres mayor de edad\" : \"Eres menor de edad\";\nconsole.log(msg);\n\n// _______________________\n// Bucles\n// https://developer.mozilla.org/es/docs/Learn/JavaScript/Building_blocks/Looping_code\n\n// For Loop\nfor (let i = 1; i <= 5; i++) {\n    console.log(i); // 1, 2, 3, 4, 5\n}\n\n// For...of Loop\nconst fruits = [\"Apple\", \"Banana\", \"Cherry\"];\nfor (const fruit of fruits) {\n  console.log(fruit); // Apple, Banana, Cherry\n}\n\n// Acceder mediante el índice.\nconst colors = [\"Red\", \"Green\", \"Blue\"];\nfor (let i = 0; i < colors.length; i++) {\n  console.log(colors[i]); // Red, Green, Blue\n}\n\n// While Loop\nlet count = 1;\nwhile (count <= 3) {\n  console.log(count); // 1, 2, 3\n  count++;\n}\n\n// Do...While Loop\nlet num = 1;\ndo {\n  console.log(num); // 1, 2, 3\n  num++;\n} while (num <= 3);\n\n// Break Statement\nfor (let i = 1; i <= 5; i++) {\n    if (i === 3) break; // detenerse\n    console.log(i); // 1, 2\n}\n\n// Continue Statement\nfor (let i = 1; i <= 5; i++) {\n    if (i === 3) continue; // omitir\n    console.log(i); // 1, 2, 4, 5\n }\n\n// _______________________\n// Manejo de excepciones\n// https://developer.mozilla.org/es/docs/Web/JavaScript/Guide/Control_flow_and_error_handling#expresiones_de_manejo_de_excepciones\n\ntry {\n    throw \"Error\"; // Lanza una excepción\n  } catch (e) {\n    console.error(e); // Maneja la excepción\n  } finally {\n    console.log(\"Este bloque siempre se ejecuta.\");\n}\n\n/*\nEJERCICIO:\n* Crea un programa que imprima por consola todos los números comprendidos\n* entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n*/\n\nfor (let num = 10; num < 56; num++) {\n    if (num % 2 === 0 && num !== 16 && num % 3 !== 0) {\n        console.log(num);\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/kodenook.js",
    "content": "\nlet num1 = 3\nlet num2 = 4\n\n/*\n    Arithmetics Operators\n*/\n\n// addition\nconsole.log(`sum: ${num1 + num2}`)\n// subtraction\nconsole.log(`subtraction: ${num1 - num2}`)\n// multiplication\nconsole.log(`multiplication: ${num1 * num2}`)\n// division\nconsole.log(`division: ${num1 / num2}`)\n// modulus\nconsole.log(`modulus: ${num1 % num2}`)\n// exponentation\nconsole.log(`exponentation: ${num1 ** num2}`)\n\n\n/*\n    Assignment Operators\n*/\n\nconsole.log(num3 = 2) // assignment\nconsole.log(num3 += 3) // addition\nconsole.log(num3 -= 1) // subtraction\nconsole.log(num3 *= 2) // multiplication\nconsole.log(num3 /= 3) // division\nconsole.log(num3 %= 2) // modulus\nconsole.log(num3 **= 2) // exponentation\n\n/*\n    Comparison Operators\n*/\n\nconsole.log(num1 == num2) // equal\nconsole.log(num1 != num2) // not equal\nconsole.log(num1 === num2) // equal value and type\nconsole.log(num1 !== num2) // not equal value and type\nconsole.log(num1 > num2) // greater than\nconsole.log(num1 < num2) // less than\nconsole.log(num1 >= num2) // greater than or equal than\nconsole.log(num1 <= num2) // less than or equal than\n\n/*\n    Logical Operators\n*/\n\nconsole.log(num1 && num2) // true if both are true\nconsole.log(num1 || num2) // true if either are true\nconsole.log(!num1) // true if not true\n\n/*\n    Bitwise Operators\n*/\n\nconsole.log(6 & 3) // compare each bit and set it to 1 if both are 1, otherwise it is set to 0\nconsole.log(6 | 3) // compare each bit and set it to 1 if one or both are 1, otherwise it is set to 0\nconsole.log(6 ^ 3) // compare each bit and set it to 1 if only one is 1, otherwise it is set to 0\nconsole.log(~3) // inverts each bit, 0 becomes 1 and 1 becomes 0\nconsole.log(3 << 2) // insert the specified numbers of 0's (in this case 2) from the right\nconsole.log(8 >> 2) // insert the specified numbers of 0's (in this case 2) from the left\nconsole.log(8 >>> 2) // insert the specified numbers of 0's (in this case 2) from the left, result unsigned\n\n/*\n    Conditional Assignment\n*/\n\nlet num4\n\nconsole.log(true ? 'true' : 'false')\nconsole.log(num4 ?? 'false')\n\n/*\n    If\n*/\n\nif (false) {\n    console.log('true')\n} else if (false) {\n    console.log('true')\n} else {\n    console.log('true')\n}\n\n/*\n    Switch\n*/\n\nswitch (new Date().getDay()) {\n    default:\n        day = 'Sunday'\n    case 1:\n        day = 'Monday'\n        break\n    case 2:\n        day = 'Tuesday'\n        break\n    case 3:\n        day = 'Wednesday'\n        break\n    case 4:\n        day = 'Thursday'\n        break\n    case 5:\n        day = 'Friday'\n        break\n    case 6:\n        day = 'Saturday'\n}\n\nconsole.log(day)\n\n/*\n    Loop For\n*/\n\nfor (let i = 0; i < 5; i++) {\n    console.log(i)\n}\n\nconst person = { fname: 'John', lname: 'Doe', age: 25 };\n\nfor (let x in person) {\n    console.log(person[x])\n}\n\nconst cars = ['BMW', 'Volvo', 'Mini']\n\nfor (let x of cars) {\n    console.log(x)\n}\n\n/*\n    Loop While\n*/\n\nlet i = 0\n\nwhile (i < 10) {\n    console.log('The number is ' + i)\n    i++\n}\n\n/*\n    Loop Do-While\n*/\n\ndo {\n    console.log('The number is ' + i)\n    i--\n}\nwhile (i > 1);\n\n/*\n    Exercise\n*/\n\nfor (let i = 10; i < 56; i++) {\n    if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n        console.log(i)\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/legs30011.js",
    "content": "//operadores logicos\n\nconst a=5;\nconst b=123;\nconst c= 12;\n//suma resta multi y division\nconsole.log(\"suma de a + b =\",a+b);\nconsole.log(\"resta de a - b =\",a-b);\nconsole.log(\"multi de a * b =\",a*b);\nconsole.log(\"division de a / b =\",a/b);\nlet modulo = 5 % 3;        // 2\nlet incremento = 5;\nincremento++;              // 6\nlet decremento = 5;\ndecremento--;              // 4\n//Operadores de comparacion\nlet igual = 5 == '5';      // true (comparación no estricta)\nlet estrictamenteIgual = 5 === '5'; // false (comparación estricta)\nlet estrictamenteDiferente = 5 !== '5'; // true (comparación estricta)\nlet mayorQue = 5 > 3;      // true\nlet menorQue = 5 < 3;      // false\nlet mayorOIgual = 5 >= 3;  // true\nlet menorOIgual = 5 <= 3;  // false\nconsole.log(igual, estrictamenteIgual, estrictamenteDiferente, mayorQue, menorQue, mayorOIgual, menorOIgual);\n\nlet compaacion = a === b;\nlet diferente = a!= b;\nconsole.log(compaacion,diferente);\n\n //comparacion estrcita con triple ===  !==\n\nlet prueba = a !== b ;\nconsole.log(prueba)\n\n//Operadores de identidad\n// comparon valor en memoria \nlet y = 5;\nlet z = '5';\nconsole.log(y === z); // false (comparación estricta)\nconsole.log(y == z);  // true (comparación no estricta)\nconsole.log(y !== z); // true (comparación estricta)\nconsole.log(y != z);  // false (comparación no estricta)\n\n// Operadores de pertenencia\n//conjuntos estructuras se aplica\nlet objeto = { clave: \"valor\" };\nconsole.log(\"clave\" in objeto); // true\n\nlet arreglo = [1, 2, 3];\nconsole.log(0 in arreglo); // true (0 es un índice válido)\n\nclass Clase {}\nlet instancia = new Clase();\nconsole.log(instancia instanceof Clase); // true\n//Operadores a nivel de bit\n\nlet bitwiseAnd = 5 & 3;   // 1 (0101 & 0011 = 0001)\nlet bitwiseOr = 5 | 3;    // 7 (0101 | 0011 = 0111)\nlet bitwiseXor = 5 ^ 3;   // 6 (0101 ^ 0011 = 0110)\nlet bitwiseNot = ~5;      // -6 (~0101 = 1010)\nlet bitwiseShiftLeft = 5 << 1;  // 10 (0101 << 1 = 1010)\nlet bitwiseShiftRight = 5 >> 1; // 2 (0101 >> 1 = 0010)\nlet bitwiseShiftRightZeroFill = 5 >>> 1; // 2 (0101 >>> 1 = 0010)\n\nconsole.log(bitwiseAnd, bitwiseOr, bitwiseXor, bitwiseNot, bitwiseShiftLeft, bitwiseShiftRight, bitwiseShiftRightZeroFill);\n\nfor(i=10;i<=55;i++){\n    if(i % 2 === 0 && i !== 16 && i % 3 !== 0 )\n    console.log(i);\n};\nlet v = 2;\nlet g = 7;\nconsole.log(v%=g);\n\n\n//Residuo (%)\tOperador binario. Devuelve el resto entero de dividir los dos operandos.\t12 % 5 devuelve 2."
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/levsistemas.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\nlet suma = 2 + 2\nlet resta = 2 - 1\nlet multiplicar = 2 * 2\nlet dividir = 2 / 2\nlet potenciacion = 2 ** 2\nlet raiz = Math.sqrt(9)\nlet modulo = 6 % 2\nlet adicionar=0\n\nconsole.log(\"Suma: 2 + 2\", suma)\nconsole.log(\"Resta: 2 - 1\", resta)\nconsole.log(\"Multiplicar: 2 * 2\", multiplicar)\nconsole.log(\"Dividir: 2 / 2\", dividir)\nconsole.log(\"Potenciacion: 2 ** 2\", potenciacion)\nconsole.log(\"Raiz: 9\", raiz)\nconsole.log(\"Modulo: 6 % 2\", modulo)\n\nadicionar++\n\nconsole.log(adicionar)\n\nadicionar--\n\nconsole.log(adicionar)\n\nlet verdadero = true\n\nconsole.log(verdadero)\n\nlet falso = false\n\nconsole.log(falso)\n\nif(1+1==2 && 6-5==1) {\n    console.log(\"Comparador AND &&\")\n}\n\nif(2+2==4 || 5-5==1) {\n    console.log(\"Comparador OR ||\")\n}\n\nif (!false) {\n    console.log(\"Esta condición también es válida!\")\n}\n\nif(true!==(!true)) {\n    console.log(\"Condicion donde es diferente y se cumple.\")\n}\n\nif(2 + 2 === 4) {\n    console.log(\"Condición donde la triple comparacion funciona por valor y tipo.\")\n}\n\nif(1 + 1 == \"2\") {\n    console.log(\"Condición que se cumple a modo de valor\")\n}\n\nif(1 + 1 === \"2\") {\n    console.log(\"Este mensaje no se va a imprimir\")\n} else {\n    console.log(\"Este mensaje pasando por ELSE si se imprimirá\")\n}\n\nconst miArreglo = [100, 200, 300, 400]\nconsole.log(0 in miArreglo, \"Funciona\")\nconsole.log(1 in miArreglo, \"Funciona\")\nconsole.log(2 in miArreglo, \"Funciona\")\nconsole.log(3 in miArreglo, \"Funciona\")\nconsole.log(4 in miArreglo, \"No Funcionará\")\n\nconst persona = {\n    nombre: \"Leandro\",\n    edad: 38\n};\n\nconsole.log(\"nombre\" in persona)\nconsole.log(\"hobbies\" in persona)\n\n// DIFICULTAD EXTRA\n\nfor ( let i=10 ; i<=55 ; i++ ) {\n    \n    if(i % 2 == 0) {\n        console.log(\"Los números Pares: \", i)\n    }\n    \n    if(i!==16){\n        console.log(\"Los números distintos a 16... \", i)\n    }\n    \n    if(i % 3!==0){\n        console.log(\"Los números no múltiplos de 3...\", i)\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/llonardo798.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n// Tipos de operadores en JavaScript\n\n// 1. Operadores Aritméticos\nconsole.log(\"1. Operadores Aritméticos\");\n\nlet suma = 5 + 5;                                   // Operador de suma (+)\nconsole.log(\"Suma: \" + suma);                       // 10\n\nlet resta = suma - 5;                               // Operador de resta (-)\nconsole.log(\"Resta:\" + resta);                      // 5\n\nlet multiplicacion = suma * 5;                      // Operador de multiplicación (*)\nconsole.log(\"Multiplicación: \" + multiplicacion);   // 50\n\nlet division = suma / 5                             // Operador de división (/)\nconsole.log(\"División: \" + division);               // 2\n\nlet modulo = suma % 3;                              // Operador de módulo (%) - Módulo (resto o sobrante de la división) 10 % 3 = 1 se puede considerar como 10/3 = 3 y sobra 1\nconsole.log(\"Modulo: \" + modulo);                   // 1\n\nlet incremento = suma++;                            // Operador de incremento (++)\nconsole.log(\"Incremento: \" + incremento);           // 6\n\nlet decremento = suma--;                            // Operador de decremento (--)\nconsole.log(\"Decremento: \" + decremento);           // 5\n\nlet exponenciacion = 2 ** 3;                        // Operador de exponenciación (**)\nconsole.log(\"Exponenciación\" + exponenciacion);     // 8\n\n// Ejemplo de uso de operadores aritméticos \nlet numero1 = 5;\nlet numero2 = 3;\nlet resultado = (((numero1 + numero2) * (numero1 - numero2)) / numero2) % numero2 + numero1++ - --numero2 + numero1 ** numero2\nconsole.log(\"Uso de todos los operadores aritmeticos: \" + resultado);         // 41.333....\n\n\n\n// 2. Operadores Bit a Bit\nconsole.log(\"2. Operadores Bit a Bit\");\n\nlet operadorA = 60;  // 60 = 0011 1100\nlet operadorB = 13;  // 13 = 0000 1101\nlet operadorC = -10; // -10 = 1111 1111 1111 1111 1111 1111 1111 0110\n\nlet operadorAnd = operadorA & operadorB; // Operador de AND bit a bit (&)\nconsole.log(\"AND: \" + operadorAnd);       // 12\n// Explicación con binarios:\n// 0011 1100 -> 60\n// 0000 1101 -> 13\n// ------------ & (AND)\n// 0000 1100 -> 12\n\nlet operadorOr = operadorA | operadorB;   // Operador de OR bit a bit (|)\nconsole.log(\"OR: \" + operadorOr);         // 61\n// Explicación con binarios:\n// 0011 1100 -> 60\n// 0000 1101 -> 13\n// ------------ | (OR)\n// 0011 1101 -> 61\n\nlet operadorXor = operadorA ^ operadorB;  // Operador de XOR bit a bit (^)\nconsole.log(\"XOR: \" + operadorXor);       // 49\n// Explicación con binarios:\n// 0011 1100 -> 60\n// 0000 1101 -> 13\n// ------------ ^ (XOR)\n// 0011 0001 -> 49\n\nlet operadorNot = ~operadorA;             // Operador de NOT bit a bit (~)\nconsole.log(\"NOT: \" + operadorNot);       // -61\n// Explicación con binarios:\n// 0011 1100 -> 60\n// ------------ ~ (NOT)\n// 1100 0011 -> -61\n\nlet operadorDesplazamientoIzquierda = operadorA << 2; // Operador de desplazamiento a la izquierda (<<)\nconsole.log(\"Desplazamiento a la izquierda: \" + operadorDesplazamientoIzquierda); // 240\n// Explicación con binarios:\n// 0011 1100 -> 60\n// --------- << (Desplazamiento a la izquierda de 2 bits)\n// 1111 0000 -> 240\n\nlet operadorDesplazamientoDerecha = operadorA >> 2; // Operador de desplazamiento a la derecha (>>)\nconsole.log(\"Desplazamiento a la derecha: \" + operadorDesplazamientoDerecha); // 15\n// Explicación con binarios:\n// 0011 1100 -> 60\n// --------- >> (Desplazamiento a la derecha de 2 bits)\n// 0000 1111 -> 15\n\nlet operadorDesplazamientoDerechaSinSigno = operadorC >>> 2; // Operador de desplazamiento a la derecha sin signo (>>>)\nconsole.log(\"Desplazamiento a la derecha sin signo: \" + operadorDesplazamientoDerechaSinSigno); // 1073741821\n// Explicación con binarios:\n// 1111 1111 1111 1111 1111 1111 1111 0110 -> -10\n// --------- >>> (Desplazamiento a la derecha sin signo de 2 bits)\n// 0011 1111 1111 1111 1111 1111 1111 1101 -> 1073741821\n\n\n\n// 3. Operadores de Asignación.\nconsole.log(\"3. Operadores de Asignación\");\n\nlet asignacion = 5;                                         // Operador de asignación (=)\nconsole.log(\"Asignación: \" + asignacion);                   // 5\n\nasignacion += 5;                                            // Operador de suma y asignación (+=)\nconsole.log(\"Suma y asignación: \" + asignacion);            // 10\n\nasignacion -= 5;                                            // Operador de resta y asignación (-=)\nconsole.log(\"Resta y asignación: \" + asignacion);           // 5\n\nasignacion *= 5;                                            // Operador de multiplicación y asignación (*=)\nconsole.log(\"Multiplicación y asignación: \" + asignacion);  // 25\n\nasignacion /= 5;                                            // Operador de división y asignación (/=)\nconsole.log(\"División y asignación\" + asignacion);          // 5\n\nasignacion %= 3;                                            // Operador de módulo y asignación (%=)\nconsole.log(\"Modulo y asignación: \" + asignacion);          // 2\n\nasignacion **= 3;                                           // Operador de exponenciación y asignación (**=)\nconsole.log(\"Exponenciación y asignación: \" + asignacion);  // 8\n\nasignacion <<= 5;                                           // Operador de desplazamiento a la izquierda y asignación (<<=)\nconsole.log(\"Desplazamiento a izquierda: \" + asignacion);   // 256\n// Explicación con binarios:\n// 0000 0000 1000 -> 8\n// --------- <<= (Desplazamiento a la izquierda de 5 bits)\n// 0001 0000 0000 -> 256\n\n// let desplazamient = suma >> resta;\n\nasignacion >>= 2;                                           // Operador de desplazamiento a la derecha y asignación (>>=)\nconsole.log(\"Desplazamiento a derecha: \" + asignacion);      // 64\n// Explicación con binarios:\n// 0001 0000 0000 -> 256\n// --------- >>= (Desplazamiento a la derecha de 2 bits)\n// 0000 0100 0000 -> 64\n\n// Operador de desplazamiento a la derecha sin signo y asignación (>>>=) desplaza los bits a la derecha \n// sin importar si el numero es positivo o negativo para lo cual agrerga 0 a la izquierda\nlet a = -10;\na >>>= 2;                                                   // Operador de desplazamiento a la derecha sin signo y asignación (>>>=)\nconsole.log(\"Despolazamient a derecha sin signo: \" + a);    // 1073741821\n// Explicación con binarios:\n// 1111 1111 1111 1111 1111 1111 1111 0110 -> -10\n// --------- >>>= (Desplazamiento a la derecha sin signo de 2 bits)\n// 0011 1111 1111 1111 1111 1111 1111 1101 -> 1073741821\n\nlet num1 = 60;\nnum1 &= 13;                                                         // Operador de AND bit a bit y asignación (&=)\nconsole.log(\"Operador de AND bit a bit y asignación: \" + num1);     // 12\n// Explicación con binarios:\n// 0011 1100 -> 60\n// 0000 1101 -> 13\n// ------------ & (AND)\n// 0000 1100 -> 12\n\nnum1 = 60;\nnum1 |= 13;                                                         // Operador de OR bit a bit y asignación (|=)\nconsole.log(\"Operador de OR bit a bit y asignación: \" + num1);      // 61\n// Explicación con binarios:\n// 0011 1100 -> 60\n// 0000 1101 -> 13\n// ------------ | (OR)\n// 0011 1101 -> 61\n\nnum1 = 60;\nnum1 ^= 13;                                                         // Operador de XOR bit a bit y asignación (^=)\nconsole.log(\"Operador de XOR bit a bit y asignación\" + num1);       // 49\n// Explicación con binarios:\n// 0011 1100 -> 60\n// 0000 1101 -> 13\n// ------------ ^ (XOR)\n// 0011 0001 -> 49\n\n\n\n// 4. Operadores de Comparación\nconsole.log(\"4. Operadores de Comparación\");\n\nlet comparacionIgual = 5 == 5;                                          // Operador de igualdad (==)\nconsole.log(\"Igualdad: \" + comparacionIgual);                           // true\n\nlet comparacionEstrictamenteIgual = 5 === 5;                            // Operador de igualdad estricta (===), no solo compara el valor sino también el tipo de dato\nconsole.log(\"Igualdad estricta: \" + comparacionEstrictamenteIgual);     // true\n\nlet comparacionDistinto = 5 != 5;                                       // Operador de distinto (!=)\nconsole.log(\"Distinto: \" + comparacionDistinto);                        // false\n\nlet comparacionEstrictamenteDistinto = 5 !== 5;                         // Operador de distinto estricto (!==), no solo compara el valor sino también el tipo de dato\nconsole.log(\"Distinto estricto: \" + comparacionEstrictamenteDistinto);  // false\n\nlet comparacionMayorQue = 5 > 3;                                        // Operador de mayor que (>)\nconsole.log(\"Mayor que: \" + comparacionMayorQue);                       // true\n\nlet comparacionMenorQue = 5 < 3;                                        // Operador de menor que (<)\nconsole.log(\"Menor que: \" + comparacionMenorQue);                       // false\n\nlet comparacionMayorIgualQue = 5 >= 5;                                  // Operador de mayor o igual que (>=)\nconsole.log(\"Mayor o igual que: \" + comparacionMayorIgualQue);          // true\n\nlet comparacionMenorIgualQue = 5 <= 3;                                  // Operador de menor o igual que (<=)\nconsole.log(\"Menor o igual que: \" + comparacionMenorIgualQue);          // false\n\n\n\n// 5. Operadores Lógicos\n\nlet logicoAnd = true && false;                  // Operador AND lógico (&&) - Devuelve true si ambos operandos son true\nconsole.log(\"AND lógico: \" + logicoAnd);        // false\n\nlet logicoOr = true || false;                   // Operador OR lógico (||) - Devuelve true si al menos uno de los operandos es true\nconsole.log(\"OR lógico: \" + logicoOr);          // true\n\nlet logicoNot = !true;                          // Operador NOT lógico (!) - Devuelve true si el operando es false y viceversa\nconsole.log(\"NOT lógico: \" + logicoNot);        // false\n\n// Ejemplo de uso de operadores lógicos\n\nlet edad = 16;\nlet estaAcompanado = false;\n\nlet puedeVerPelicula = edad >= 18 || (edad >= 16 && estaAcompanado);\nconsole.log(puedeVerPelicula);\n// Cambiamos el valor de la variable estaAcompanado a valor contrario por diversión.\nif (!puedeVerPelicula) {\n    console.log(\"Puedes ver la película\");\n} else {\n    console.log(\"No puedes ver la película\");\n}\n\n\n\n// 6. Operadores de Cadena\nconsole.log(\"6. Operadores de Cadena\");\n\nlet cadena1 = \"Hola, la suma de: \" + suma + \" y \" + resta + \" es \" + (suma + resta);       // Concatenación (+)\nconsole.log(cadena1);                                                                       // Hola, la suma de: 5 y 5 es 10\n\n\n// 7. Operador Condicional (Ternario)\nconsole.log(\"7. Operador Condicional (Ternario)\");\n\nlet puedeVerPelicula2 = edad >= 18 ? \"Puede ver la película\" : \"No puede ver la película\";  // Operador condicional (Ternario)\nconsole.log(puedeVerPelicula2);                                                             // No puede ver la película\n\n// 8. Otros Operadores\nconsole.log(\"8. Otros Operadores\");\n\n// Se crea el objeto persona\nlet persona = {\n    nombre: \"Leonardo\",\n    edad: 26\n};\n\nlet operadorTypeof = typeof persona;                                // Operador typeof - Devuelve el tipo de dato de una variable\nconsole.log(\"Tipo de dato de suma: \" + operadorTypeof);             // object\n\nlet operadorDelete = delete persona.edad;                           // Operador delete - Elimina una propiedad de un objeto\nconsole.log(\"Propiedad eliminada: \" + operadorDelete);              // true\n\nlet operadorIn = \"nombre\" in persona;                               // Operador in - Devuelve true si una propiedad existe en un objeto\nconsole.log(\"Propiedad en el objeto: \" + operadorIn);               // true\n\nlet operadorInstanceOf = persona instanceof Object;                 // Operador instanceof - Devuelve true si un objeto es una instancia de otro\nconsole.log(\"Es una instancia de Object: \" + operadorInstanceOf);   // true\n\nlet operadorNew = new Date();                                       // Operador new - Crea una nueva instancia de un objeto\nconsole.log(\"Nueva instancia de Date: \" + operadorNew);             // Fecha actual\n\n\n// DIFICULTAD EXTRA - Crea un programa que imprima por consola todos los números comprendidos entre 10 y 55 (incluidos)\n// pares, y que no son ni el 16 ni múltiplos de 3.\n\nconsole.log(\"DIFICULTAD EXTRA\");\n\nfor (let i = 10; i < 56; i++) {\n    if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n        console.log(i);\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/lrpeset.js",
    "content": "//  Initialize variables\nconsole.log(\"**   Initialize variables:   **\");\n\nlet a = 1;\nlet b = 2;\n\nconsole.log(\"let a = \" + a);\nconsole.log(\"let b = \" + b);\n\n//  Arithmetic operators\nconsole.log(\"**   Arithmetic operators:   **\");\n\nlet addition = a + b;\nlet increment = a++;\nlet substraction = a - b;\nlet decrement = a --;\nlet multiplication = a * b;\nlet division = a / b;\nlet remainder = a % b;\nlet exponentiation = a ** b;\n\nconsole.log(\"Addition operator: \", addition);\nconsole.log(\"Increment operator: \", increment);\nconsole.log(\"Substraction operator: \", substraction);\nconsole.log(\"Decrement operator: \", decrement);\nconsole.log(\"Multiplication operator: \", multiplication);\nconsole.log(\"Division operator: \", division);\nconsole.log(\"Remainder operator: \", remainder);\nconsole.log(\"Exponentiation operator: \", exponentiation);\n\n// Assignment operators\nconsole.log(\"**   Assignment operators:   **\");\n\nlet additionAssignment = a += b;\nlet substractionAssignment = a -= b;\nlet multiplicationAssignment = a *= b;\nlet divisionAssignment = a /= b;\nlet remainderAssignment = a %= b;\nlet exponentiationAssignment = a **= b\n\nconsole.log(\"Addition assignment: \", additionAssignment);\nconsole.log(\"Substraction assignment: \", substractionAssignment);\nconsole.log(\"Multiplication assignment: \", multiplicationAssignment);\nconsole.log(\"Division assignment: \", divisionAssignment);\nconsole.log(\"Remainder assignment: \", remainderAssignment);\nconsole.log(\"Exponentiation Assignment: \", exponentiationAssignment);\n\n//  Comparison operators\nconsole.log(\"**   Comparison operators:   **\");\n\nlet equality = a == 1;\nlet strictEquality = a === 1;\nlet inequality = a != 1;\nlet strictInequality = a !== 1;\nlet graterThan = a > b;\nlet graterThanOrEqual = a >= b;\nlet lessThan = a < b;\nlessThanOrEqual = a <= b;\n\nconsole.log(\"Equality operator: \", equality);\nconsole.log(\"Strict equality operator: \", equality);\nconsole.log(\"Inequality operator: \", inequality);\nconsole.log(\"Strict inequality operator: \", inequality);\nconsole.log(\"Greater than operator: \", graterThan);\nconsole.log(\"Greater than or equal operator: \", graterThanOrEqual);\nconsole.log(\"Less than operator: \", lessThan);\nconsole.log(\"Less than or equal operator: \", lessThanOrEqual);\n\n//  Logical operators\nconsole.log(\"**   Logical operators:   **\");\n\nlet and = true && true;\nlet andAssignment = true;\nandAssignment &&= true;\nlet or = true || false;\nlet orAssignment = true;\norAssignment ||= false;\nlet not = !false;\n\nconsole.log(\"AND operator: \", and);\nconsole.log(\"AND assignment operator: \", andAssignment);\nconsole.log(\"OR operator: \", or);\nconsole.log(\"OR assignment operator: \", orAssignment);\nconsole.log(\"NOT operator: \", not);\n\n//  Control structures examples\nconsole.log(\"**   Example of control structures:   **\")\n\n//  Conditional statements\n//  if\nlet c = 10;\nlet d = 20;\n\nif (c < d) {\n  console.log(\"c is less than d\");\n} else if (c < d) {\n  console.log(\"c is greater than d\");\n} else {\n  console.log(\"c is equal to d\");\n}\n\n//  switch\nlet day = 1;\n\nswitch (day) {\n  case 1:\n    console.log(\"Monday\");\n    break;\n  case 2:\n    console.log(\"Tuesday\");\n    break;\n  case 3:\n    console.log(\"Wednesday\");\n    break;\n  case 4:\n    console.log(\"Thursday\");\n    break;\n  case 5:\n    console.log(\"Friday\");\n    break;\n  case 6:\n    console.log(\"Saturday\");\n    break;\n  case 7:\n    console.log(\"Sunday\");\n    break;\n}\n\n//  Loops\n//  for\nlet countdown = 10;\n\nfor (i = 0; countdown > i; countdown--) {\n  console.log(countdown, \"seconds left to launch!\");\n}\n\n//  while\nlet count = 1;\n\nwhile (count <= 5) {\n  console.log(\"Count is: \", count);\n  count++;\n}\n\n//  do...while\nlet carOnSale = 3;\n\ndo {\n  console.log(carOnSale, \"last units available!\");\n  carOnSale--;\n} while (carOnSale > 0);\n\n//  for...in\nconst obj = { a: 1, b: 2, c: 3 };\n\nfor (let key in obj) {\n  console.log(key, \":\", obj[key]);\n}\n\n//  for...of\nconst array = [1, 2, 3];\n\nfor (let value of array) {\n  console.log(\"Value:\", value);\n}\n\n//  Flow control\n//  break and continue\nfor (let i = 0; i < 10; i++) {\n  if (i === 5) {\n    console.log(\"Interruption on i loop:\", i);\n    break;\n  }\n  if (i % 2 === 0) {\n    continue;\n  }\n  console.log(i);\n}\n\n//  return\nfunction sum(a, b) {\n  if (a < 0 || b < 0) {\n    return \"Numbers must be positives\";\n  }\n  return a + b;\n}\n\n//  try...catch...finally and throw\nfunction divide(a, b) {\n    if (b === 0) {\n        throw new Error(\"Can't divide by 0\");\n    }\n    return a / b;\n}\n\ntry {\n    let result = divide(10, 0);\n    console.log(\"Result:\", result);\n} catch (error) {\n    console.error(\"Error:\", error.message);\n} finally {\n    console.log(\"Operation complete.\");\n}\n\n// Extra difficulty\nfor (let i = 10; i <= 55; i++) {\n  if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n    console.log(i);\n  }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/marcode24.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n// Operadores aritméticos\nconst suma = 5 + 3;\nconst resta = 10 - 4;\nconst multiplicacion = 6 * 7;\nconst division = 20 / 4;\nconst modulo = 15 % 4;\n\nconsole.log('Operadores Aritméticos:');\nconsole.log('Suma:', suma);\nconsole.log('Resta:', resta);\nconsole.log('Multiplicación:', multiplicacion);\nconsole.log('División:', division);\nconsole.log('Módulo:', modulo);\n\n// Operadores lógicos\nconst and = true && false;\nconst or = true || false;\nconst not = !true;\n\nconsole.log('\\nOperadores Lógicos:');\nconsole.log('AND:', and);\nconsole.log('OR:', or);\nconsole.log('NOT:', not);\n\n// Operadores de comparación\n// eslint-disable-next-line eqeqeq\nconst igual = 5 == '5';\nconst estrictamenteIgual = 5 === '5';\nconst diferente = 10 !== 5;\nconst mayorQue = 15 > 10;\nconst menorQue = 7 < 12;\n\nconsole.log('\\nOperadores de Comparación:');\nconsole.log('Igual (==):', igual);\nconsole.log('Estrictamente Igual (===):', estrictamenteIgual);\nconsole.log('Diferente (!=):', diferente);\nconsole.log('Mayor Que (>):', mayorQue);\nconsole.log('Menor Que (<):', menorQue);\n\n// Operadores de asignación\nlet x = 10;\nx += 5; // equivalente a x = x + 5\nlet y = 20;\ny *= 2; // equivalente a y = y * 2\n\nconsole.log('\\nOperadores de Asignación:');\nconsole.log('x:', x);\nconsole.log('y:', y);\n\n// Operadores bitwise\nconst bitwiseAnd = 5 & 3; // AND\nconst bitwiseOr = 5 | 3; // OR\nconst bitwiseXor = 5 ^ 3; // XOR\nconst bitwiseNot = ~5; // NOT\nconst leftShift = 5 << 1; // Left Shift\nconst rightShift = 5 >> 1; // Right Shift\nconst zeroFillRightShift = 5 >>> 1; // Zero-fill Right Shift\n\nconsole.log('\\nOperadores Bitwise:');\nconsole.log('Bitwise AND (&):', bitwiseAnd);\nconsole.log('Bitwise OR (|):', bitwiseOr);\nconsole.log('Bitwise XOR (^):', bitwiseXor);\nconsole.log('Bitwise NOT (~):', bitwiseNot);\nconsole.log('Left Shift (<<):', leftShift);\nconsole.log('Right Shift (>>):', rightShift);\nconsole.log('Zero-fill Right Shift (>>>):', zeroFillRightShift);\n\n// Estructuras de control\n// Condicionales\nconst edad = 18;\nif (edad >= 18) {\n  console.log('\\nEres mayor de edad.');\n} else {\n  console.log('\\nEres menor de edad.');\n}\n\n// Iterativas\nconsole.log('\\nNúmeros entre 10 y 55 (pares, no 16 ni múltiplos de 3):');\nfor (let i = 10; i <= 55; i++) {\n  if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n    console.log(i);\n  }\n}\n\n// Excepciones\ntry {\n  throw new Error('Este es un ejemplo de excepción.');\n} catch (error) {\n  console.error('\\nExcepción:', error.message);\n}\n\n// Visita mi repo en GitHub para ver y correr los tests de este código --> https://github.com/marcode24/weekly-challenges\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/mariovelascodev.js",
    "content": "//Operadores de asignación\nconsole.log(`Operadores de asignación`)\nlet a = 5;\nlet b = 10;\n\nconsole.log(`Operador =: a = 5`);\nconsole.log(`Operador =: b = 10`);\nconsole.log(`Operador +=: a += b = ${a += b}`)\nconsole.log(`Operador -=: a -= b = ${a -= b}`)\nconsole.log(`Operador *=: a *= b = ${a *= b}`)\nconsole.log(`Operador /=: a /= b = ${a /= b}`)\nconsole.log(`Operador %=: a %= b = ${a %= b}`)\nconsole.log(`Operador **=: a **= b = ${a **= b}`)\nconsole.log(`Operador >>=: a >>= b = ${a >>= b}`)\nconsole.log(`Operador <<=: a <<= b = ${a <<= b}`)\nconsole.log(`Operador >>>=: a >>>= b = ${a >>>= b}`)\nconsole.log(`Operador &=: a &= b = ${a &= b}`)\nconsole.log(`Operador ^=: a ^= b = ${a ^= b}`)\nconsole.log(`Operador |=: a |= b = ${a |= b}`)\nconsole.log(`Operador &&=: a &&= b = ${a &&= b}`)\nconsole.log(`Operador ||=: a ||= b = ${a ||= b}`)\nconsole.log(`Operador ??=: a ??= b = ${a ??= b}`)\nconsole.log(`.........................................`)\n\n//Operadores aritméticos\nconsole.log(`Operadores aritméticos`);\nlet num1 = 18;\nlet num2 = 2;\nlet num3 = \"5\"\n\nconsole.log(`Suma: ${num1} + ${num2} = ${num1 + num2}`);\nconsole.log(`Resta: ${num1} - ${num2} = ${num1 - num2}`);\nconsole.log(`Multiplicación: ${num1} * ${num2} = ${num1 * num2}`);\nconsole.log(`División: ${num1} / ${num2} = ${num1 / num2}`);\nconsole.log(`Modulo: ${num1} % ${num2} = ${num1 % num2}`);\nconsole.log(`Exponente: ${num1} ** ${num2} = ${num1 ** num2}`);\nconsole.log(`Incrementa en 1 y devuelve  el operando: ++num1 = ${++num1}`);\nconsole.log(`Devuelve  el operando e incrementa en 1: num1++ = ${num1++}`);\nconsole.log(`Decrementa en 1 y devuelve  el operando: ++num1 = ${--num1}`);\nconsole.log(`Devuelve  el operando y decrementa en 1: num1++ = ${num1--}`);\nconsole.log(`Invierte el valor del operando: -num1 = ${-num1}`);\nconsole.log(`Convierte el operando en un número: +num3 = ${typeof (+num3)}`);\nconsole.log(`.........................................`);\n\n//Operadores lógicos\nconsole.log(`Operadores lógicos`);\nconsole.log(`&&: false && false = ${false && false}`);\nconsole.log(`||: true || false = ${true || false}`);\nconsole.log(`!: !num2 = ${!num2}`);\nconsole.log(`.........................................`);\n\n//Operadores de comparación\nconsole.log(`Operadores de comparación`);\nconsole.log(`Operador ==: num1 == num2 = ${num1 == num2}`);\nconsole.log(`Operador ===: num1 === num2 = ${num1 === num2}`);\nconsole.log(`Operador !=: num1 != num2 = ${num1 != num2}`);\nconsole.log(`Operador !==: num1 !== num2 = ${num1 !== num2}`);\nconsole.log(`Operador >: num1 > num2 = ${num1 > num2}`);\nconsole.log(`Operador >=: num1 >= num2 = ${num1 >= num2}`);\nconsole.log(`Operador <: num1 < num2 = ${num1 < num2}`);\nconsole.log(`Operador <=: num1 <= num2 = ${num1 <= num2}`);\nconsole.log(`.........................................`);\n\n//Operadores de bit\nconsole.log(`Operadores de bit`);\nlet x = 9;\nlet y = 12\nconsole.log(`Operador &: x & y = ${x & y}`);\nconsole.log(`Operador |: x | y = ${x | y}`);\nconsole.log(`Operador ^: x & y = ${x ^ y}`);\nconsole.log(`Operador ~: ~x = ${~x}`);\nconsole.log(`Operador <<: x << y = ${x << y}`);\nconsole.log(`Operador >>: x >> y = ${x >> y}`);\nconsole.log(`Operador >>>: x >>> y = ${x >>> y}`);\nconsole.log(`.........................................`);\n\n//Estructuras de control\nconsole.log(`Estructuras de control`);\n\nconsole.log(`Condicional if`);\nif (num1 < num2) {\n    console.log(`${num1} es menor que ${num2}`);\n} else if (num1 > num2) {\n    console.log(`${num1} es mayor que ${num2}`);\n} else {\n    console.log(`${num1} es igual que ${num2}`);\n}\n\nconsole.log(`.........................................`);\n\nconsole.log(`Declaración switch`);\nlet nota = 3;\n\nswitch(nota) {\n    case 5:\n        console.log(`Enhorabuena has obtenido un sobresaliente`);\n        break;\n    case 4:\n        console.log(`Buen trabajo pero podrías haberlo echo mejor`);\n        break;\n    case 3:\n        console.log(`Has obtenido un suficiente`);\n        break;\n    case 2:\n        console.log(`No has aprobado por poco`);\n        break;\n    case 1:\n        console.log(`No has estudiado nada, trabaja un poquito más para la próxima`);\n        break;\n    default:\n        console.log(`Error, introduce una nota entre 1 y el 5`);\n}\n\nconsole.log(`.........................................`);\n\n//Bucle for\nconsole.log(`Bucle for`);\nfor (let i = 0; i < 10; i++) {\n    console.log(i);\n}\n\nconsole.log(`.........................................`);\n\n//Estructura for...of\nlet lista = [1, 4, 6, 2, 3, 7, 10, 12];\nconsole.log(`Estructura for...of`);\nfor (let valor of lista) {\n    console.log(valor);\n}\n\nconsole.log(`.........................................`);\n\n//Estructura forEach\nconsole.log(`Estructura forEach`);\nlista.forEach(valor => {\n    console.log(valor);\n});\n\nconsole.log(`.........................................`);\n\n//Estructura for...in\nlet persona = {\n    nombre: \"Mario\",\n    apellido: \"Velasco\",\n    edad: 34,\n    idDeveloper: true\n};\n\nconsole.log(`Estructura for...in`);\nfor(let propiedad in persona) {\n    console.log(`Muestra la clave del objeto -> ${propiedad}`);\n    console.log(`Muestra el valor de cada propiedad del objeto ${persona[propiedad]}`);\n};\n\nconsole.log(`.........................................`);\n\n//Bucle while\nlet i = 0;\nlet max = 10;\n\nconsole.log(`Bucle while`);\n\nwhile (i < max) {\n    console.log(`El valor de i es: ${i}`);\n    i++;\n}\n\nconsole.log(`.........................................`);\n\n//Do...while\nconsole.log(`Bucle Do...while`);\nlet j = 0\ndo {\n    console.log(`El valor de j es: ${j}`);\n    j++\n}while (j < max);\n\nconsole.log(`.........................................`);\n\n//Excepciones\nconsole.log(`Excepciones`);\nconst miConstante = 30;\n\ntry {\n    miConstante = 20;   \n}catch (error){\n    console.error(`Ha habido una excepción ${error}`);\n}\n\nconsole.log(`.........................................`);\n\n//EXTRA\nconsole.log(`DIFICULTAD EXTRA`);\nfor(let i = 10; i <= 55; i++) {\n    if (i % 2 == 0 && i != 16 && i % 3 != 0){\n        console.log(i);\n        \n        if (i == 52) {\n            i+=3;\n            console.log(i);\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/martinbohorquez.js",
    "content": "/*\n Operadores aritméticos: actúan sobre números enteros y en punto flotante (decimales).\n Hay dos tipos:\n      -- Operadores binarios.\n      -- Operadores unarios.\n */\n/*\n * Operadores unarios: aplican a un operando.\n * Tipos:\n *      -- Mantiene el signo del operando (+)\n *      -- Cambia el signo del operando (-)\n *      -- Autoincremento (++)\n *      -- Autodecremento (--)\n */\nlet a = 10;\nconsole.log(\"Operadores unarios: aplican a un operando.\");\nconsole.log(\"Mantiene el signo: \" + (+a));\nconsole.log(\"Cambia el signo: \" + (-a));\nconsole.log(\"Autoincremento e impresión: \" + (++a)); //Se incrementa y se imprime\nconsole.log(\"Impresión y autoincremento: \" + (a++)); //Se imprime y se incrementa\nconsole.log(\"Autodecremento e impresión: \" + (--a)); //Se decrementa y se imprime\nconsole.log(\"Impresión y autodecremento: \" + (a--)); //Se imprime y se decrementa\nconsole.log(\"\");\n/*\n * Operadores binarios: aplican sobre dos operandos.\n * Tipos:\n *       -- Suma (+)\n *       -- Resta (-)\n *       -- Multiplicación (*)\n *       -- División (/)\n *       -- Módulo (%)\n */\nconst b = 5;\nconst c = 2;\nconsole.log(\"Operadores binarios: aplican sobre dos operandos: \");\nconsole.log(\"Suma: \" + b + \" + \" + c + \" = \" + (b + c));\nconsole.log(\"Resta: \" + b + \" - \" + c + \" = \" + (b - c));\nconsole.log(\"Multiplicación: \" + b + \" * \" + c + \" = \" + (b * c));\nconsole.log(\"División: \" + b + \" / \" + c + \" = \" + (b / c));\nconsole.log(\"Módulo: \" + b + \" % \" + c + \" = \" + (b % c));\nconsole.log(\"\");\n/*\n * Operadores relacionales: para hacer comparaciones.\n * Tipos:\n *      -- Mayor que (>)\n *      -- Mayor o igual que (>=)\n *      -- Menor que (<)\n *      -- Menor o igual que (<=)\n *      -- Igual que (==)\n *      -- Distinto de (!=)\n */\nconst d = 20;\nconst e = 50;\nconsole.log(\"Operadores relacionales: para hacer comparaciones.\");\nconsole.log(\"¿20 es mayor que 50? : \" + (d > e));\nconsole.log(\"¿20 es mayor o igual que 50? : \" + (d >= e));\nconsole.log(\"¿20 es menor que 50? : \" + (d < e));\nconsole.log(\"¿20 es menor o igual que 50? : \" + (d <= e));\nconsole.log(\"¿20 es igual que 50? : \" + (d == e));\nconsole.log(\"¿20 es distinto de 50? : \" + (d != e));\nconsole.log(\"\");\n/*\n * Operadores lógicos: Operan con valores lógicos para devolver nuevos valores lógicos.\n * Tipos:\n *      -- AND (&&): Evalúa si las dos expresiones son verdaderas.\n *      -- OR (||): Evalúa si alguna de las expresiones es verdadera.\n *      -- NOT (!): Cambia el valor de la variable lógica.\n */\nconst v = true;\nconst f = false;\nconsole.log(\"Operadores lógicos: Operan con valores lógicos para devolver nuevos valores lógicos.\");\nconsole.log(\"¿true es igual a false? : \" + (v && f));\nconsole.log(\"¿true o false son verdaderas? : \" + (v || f));\nconsole.log(\"Cambiamos el valor de true : \" + (!v));\nconsole.log(\"\");\n/*\n * Operador sobre cadenas de caracteres (+): Para concatenar cadenas de caracteres.\n */\nconst text1 = \"¡Hola, \";\nconst text2 = \"TypeScript!\";\nconsole.log(\"Operador sobre cadenas de caracteres:\");\nconsole.log(text1 + text2);\nconsole.log(\"\");\n/*\n * Operadores de asignación: Para asignar un valor a una variable.\n * Tipos:\n *      -- +=: Suma a la variable y sobrescribe el valor de la variable con el resultado.\n *      -- -=: Resta a la variable y sobrescribe el valor de la variable con el resultado.\n *      -- *=: Multiplica a la variable y sobrescribe el valor de la variable con el resultado.\n *      -- /=: Divide a la variable y sobrescribe el valor de la variable con el resultado.\n *      -- %=: Realiza el módulo a la variable y sobrescribe el valor de la variable con el resultado.\n *      -- *=: Potencia a la variable y sobrescribe el valor de la variable con el resultado.\n *      -- &&=: Realiza un AND lógico a la variable y sobrescribe el valor de la variable con el resultado.\n *      -- ||=: Realiza un OR lógico a la variable y sobrescribe el valor de la variable con el resultado.\n */\nlet i;\nlet t = true;\nconsole.log(\"Operadores de asignación: Para asignar un valor a una variable.\");\nconsole.log(\"Asignamos valor a la variable i = \" + (i = 2));\nconsole.log(\"Suma y asigna: \" + (i += 4));\nconsole.log(\"Resta y asigna: \" + (i -= 3));\nconsole.log(\"Multiplica y asigna: \" + (i *= 5));\nconsole.log(\"Divide y asigna: \" + (i /= 3));\nconsole.log(\"Módulo y asigna: \" + (i %= 3));\nconsole.log(\"Potencia y asigna: \" + (i = Math.pow(i, 3)));\nconsole.log(\"AND lógico y asigna: \" + (t && (t = true)));\nconsole.log(\"OR lógico y asigna: \" + (t || (t = false)));\nconsole.log(\"\");\n/*\n * Operadores a nivel de bits: operan con cada bit del operando, ofreciendo un control más granular sobre los datos.\n * Tipos:\n *      -- AND (&): Operador AND a nivel de bits (1 y 1 = 1).\n *      -- OR (|): Operador OR a nivel de bits (1 o 1 = 1).\n *      -- XOR (^): Operador XOR a nivel de bits (1 y 1 = 0).\n *      -- Complemento (~): Invierte el valor de cada bit.\n *      -- >> : Desplaza bits a la derecha.\n *      -- << : Desplaza bits a la izquierda.\n *      -- >>> : Desplaza bits a la derecha sin signo.\n */\nconst x = 10; // 1010\nconst y = 7; // 0111\nconsole.info(\"Operadores a nivel de bits: operan con cada bit del operando, ofreciendo un control más granular sobre los datos.\");\nconsole.log(\"x AND y : \" + (x & y));\nconsole.log(\"x OR y : \" + (x | y));\nconsole.log(\"x XOR y : \" + (x ^ y));\nconsole.log(\"Complemento de x = \" + +~x);\nconsole.log(\"Complemento de y = \" + +~y);\nconsole.log(\"Desplazamiento de bits de x a la izquierda de 2: \" + (x << 2));\nconsole.log(\"Desplazamiento de bits de y a la derecha de 1: \" + (y >> 1));\nconsole.log(\"Desplazamiento de bits de y a la derecha de 1 (sin signo): \" + (y >>> 1));\nconsole.log(\"\");\n/*\n * Excepciones\n * uso del try - catch\n */\ntry {\n    throw new Error('Este es un ejemplo de excepción.');\n}\ncatch (error) {\n    console.error('Excepción:', error.message);\n}\nconsole.log(\"\");\n/*\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n */\nconsole.log(\"DIFICULTAD EXTRA \\n\");\nconsole.log(\"Los números son: \");\nfor (let j = 10; j <= 55; j++) {\n    //Compruebo si son pares, distintos de 16 y no son múltiplos de 3\n    if (j % 2 == 0 && j != 16 && j % 3 != 0) {\n        console.log(j);\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/mateo423.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n// Operadores Aritmeticos;\nlet a = 5;\nlet b = 4;\nconsole.log(`Suma: ${a} + ${b} =  ${a + b}`);\nconsole.log(`Resta: ${a} - ${b} = ${a - b}`);\nconsole.log(`Multiplicacion: ${a} * ${b} = ${a * b}`);\nconsole.log(`Division : ${a} / ${b} =  ${a / b}`);\nconsole.log(`Potenciacion: ${a} ** ${b} =  ${a ** b}`);\nconsole.log(`Modulo: ${a} % ${b} = ${a % b}`);\nconsole.log(`Incrementa en 1 y devuelve  el operando: ++num1 = ${++a}`);\nconsole.log(`Devuelve  el operando e incrementa en 1: num1++ = ${b++}`);\nconsole.log(`Decrementa en 1 y devuelve  el operando: ++num1 = ${--a}`);\nconsole.log(`Devuelve  el operando y decrementa en 1: num1++ = ${b--}`);\nconsole.log(`Invierte el valor del operando: -num1 = ${-a}`);\nconsole.log(`Convierte el operando en un número: +num3 = ${typeof (+b)}`);\nconsole.log('######################')\n\n// Operadores Logicos;\nconsole.log('Operadores Logicos');\nconst and = true && true;\nconst or = true || true;\nconst not = !true;\n\nconsole.log(and);\nconsole.log(or);\nconsole.log(not);\nconsole.log('######################')\n\n// Operadores de Comparacion;\nconsole.log('Operadores de Comparacion');\nconst igual = 5 == '5';\nconst estrictamenteIgual = 5 === '5';\nconst diferente = 10 !== 5;\nconst mayorQue = 15 > 10;\nconst menorQue = 7 < 12;\nconst mayorIgualQue = 8 >= 20;\nconst menorIgualQue = 9 <= 8;\n\nconsole.log(igual);\nconsole.log(estrictamenteIgual);\nconsole.log(diferente);\nconsole.log(mayorQue);\nconsole.log(menorQue);\nconsole.log(mayorIgualQue);\nconsole.log(menorIgualQue);\nconsole.log('################################')\n// Operadores de bit a bit;\nlet x = 9;\nlet y = 14;\n\nconsole.log(`Operador &: x & y = ${x & y}`);\nconsole.log(`Operador |: x | y = ${x | y}`);\nconsole.log(`Operador ^: x & y = ${x ^ y}`);\nconsole.log(`Operador ~: ~x = ${~x}`);\nconsole.log(`Operador <<: x << y = ${x << y}`);\nconsole.log(`Operador >>: x >> y = ${x >> y}`);\nconsole.log(`Operador >>>: x >>> y = ${x >>> y}`);\nconsole.log('######################');\n\n// Estructura de control\nconsole.log('Estructura de control');\nlet num1 = 5;\nlet num2 = 4;\n\nif (num1 < num2) {\n  console.log(`El numero ${num1} es menor que el numero ${num2}`);\n} else if (num1 > num2) {\n  console.log(`El numero ${num1} es mayor que el numero ${num2}`);\n} else {\n  console.log(`El numero ${num1} es igual al numero ${num2}`);\n}\nconsole.log('#####################');\n// Bucle foor ;\n\nfor (let i = 0; i <= 10; i++) {\n  console.log(`Numero: ${i}`)\n};\nconsole.log('##################');\n\n// Bucle while;\nlet i = 1;\nwhile (i <= 10) {\n  let resultado = 12 * i;\n  if (resultado === 48) {\n    console.log(\"Yuju... ya llegamos a 48 Flecidades. \")\n  } else {\n    console.log(`12*${i} = ${resultado}`)\n  }\n  i++;\n}\n// switch\nlet day = 'friday';\nlet dia;\n\nswitch (day) {\n  case \"monday\":\n    dia = 'lunes';\n    break;\n  case \"tuesday\":\n    dia = 'martes';\n    break;\n  case \"wednesday\":\n    dia = 'miércoles';\n    break;\n  case \"thursday\":\n    dia = 'jueves';\n    break;\n  case \"friday\":\n    dia = 'viernes';\n    break;\n  case 'saturday':\n    dia = 'sábado';\n    break;\n  default:\n    dia = 'Domingo';\n}\nconsole.log(`El día es ${dia}`);\n\n// Blue for of\nlet lista = [1, 4, 6, 2, 3, 7, 10, 12];\nconsole.log(`Estructura for...of`);\nfor (let valor of lista) {\n  console.log(valor);\n}\n\n// Excepciones\nconsole.log(`Excepciones`);\nconst miConstante = 30;\n\ntry {\n  miConstante = 20;\n} catch (error) {\n  console.error(`Ha habido una excepción ${error}`);\n}\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\nconsole.log('DIFICULTAD EXTRA');\nfor (let i = 10; i <= 55; i++) {\n  if (i % 2 == 0 && i != 16 && i % 3 != 0) {\n    console.log(`Numero ${i}`);\n  }\n\n}\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/matiasFarfan89.js",
    "content": "// Operadores\n\n//Operadores Aritmeticos\n\nlet suma = 5 + 3;          // 8\nlet resta = 5 - 3;         // 2\nlet multiplicacion = 5 * 3; // 15\nlet division = 5 / 3;      // 1.6666666666666667\nlet modulo = 5 % 3;        // 2\nlet incremento = 5;\nincremento++;              // 6\nlet decremento = 5;\ndecremento--;              // 4\n\nconsole.log(suma, resta, multiplicacion, division, modulo, incremento, decremento);\n\n//Operadores logicos\n\nlet and = true && false;   // false\nlet or = true || false;    // true\nlet not = !true;           // false\n\nconsole.log(and, or, not);\n\n//Operadores de comparacion\n\nlet igual = 5 == '5';      // true (comparación no estricta)\nlet estrictamenteIgual = 5 === '5'; // false (comparación estricta)\nlet diferente = 5 != '5';  // false (comparación no estricta)\nlet estrictamenteDiferente = 5 !== '5'; // true (comparación estricta)\nlet mayorQue = 5 > 3;      // true\nlet menorQue = 5 < 3;      // false\nlet mayorOIgual = 5 >= 3;  // true\nlet menorOIgual = 5 <= 3;  // false\n\nconsole.log(igual, estrictamenteIgual, diferente, estrictamenteDiferente, mayorQue, menorQue, mayorOIgual, menorOIgual);\n\n//Operadores de Asignacion\n\nlet x = 10;\nx += 5; // x = x + 5\nx -= 3; // x = x - 3\nx *= 2; // x = x * 2\nx /= 2; // x = x / 2\nx %= 3; // x = x % 3\n\nconsole.log(x);\n\n//Operadores de identidad\n\nlet a = 5;\nlet b = '5';\nconsole.log(a === b); // false (comparación estricta)\nconsole.log(a == b);  // true (comparación no estricta)\nconsole.log(a !== b); // true (comparación estricta)\nconsole.log(a != b);  // false (comparación no estricta)\n\n// Operadores de pertenencia\n\nlet objeto = { clave: \"valor\" };\nconsole.log(\"clave\" in objeto); // true\n\nlet arreglo = [1, 2, 3];\nconsole.log(0 in arreglo); // true (0 es un índice válido)\n\nclass Clase {}\nlet instancia = new Clase();\nconsole.log(instancia instanceof Clase); // true\n\n//Operadores a nivel de bit\n\nlet bitwiseAnd = 5 & 3;   // 1 (0101 & 0011 = 0001)\nlet bitwiseOr = 5 | 3;    // 7 (0101 | 0011 = 0111)\nlet bitwiseXor = 5 ^ 3;   // 6 (0101 ^ 0011 = 0110)\nlet bitwiseNot = ~5;      // -6 (~0101 = 1010)\nlet bitwiseShiftLeft = 5 << 1;  // 10 (0101 << 1 = 1010)\nlet bitwiseShiftRight = 5 >> 1; // 2 (0101 >> 1 = 0010)\nlet bitwiseShiftRightZeroFill = 5 >>> 1; // 2 (0101 >>> 1 = 0010)\n\nconsole.log(bitwiseAnd, bitwiseOr, bitwiseXor, bitwiseNot, bitwiseShiftLeft, bitwiseShiftRight, bitwiseShiftRightZeroFill);\n\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/matrix-miguel.js",
    "content": "/*\n* EJERCICIO:\n* - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n*   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n*   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n* - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n*   que representen todos los tipos de estructuras de control que existan\n*   en tu lenguaje:\n*   Condicionales, iterativas, excepciones...\n* - Debes hacer print por consola del resultado de todos los ejemplos.\n*\n* DIFICULTAD EXTRA (opcional):\n* Crea un programa que imprima por consola todos los números comprendidos\n* entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n*\n* Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n*/\n\n// declaracion de variables \nlet a = 1;\nlet b = 2;\nlet c = '2';\nlet d = 3;\n\n// Operadores Arítméticos \nlet incremento = a++\nlet decremento = b--\nlet suma = a + b;\nlet resta = b - a;\nlet multiplicacion = a * b;\nlet division = d / a;\nlet resto = d % a;\nlet potencia = d**b\nconsole.log('----- Operadores Arítméticos -----');\nconsole.log('incremento:', incremento);\nconsole.log('decremento: ', decremento);\nconsole.log('suma: ', suma);\nconsole.log('resta: ', resta);\nconsole.log('multiplicacion: ', multiplicacion);\nconsole.log('division: ', division);\nconsole.log('resto: ', resto);\nconsole.log('potencia: ', potencia);\n\n//Operadores Comparación y Lógicos\nconsole.log('----- Operadores Comparación y Lógicos ------');\nlet mayorQ = 6 > 4\nlet menorQ = 6 < 7\nlet mayorIgualQ = 10 >= 25  \nlet menorIgualQ = 30 <= 200  \nlet and = 2 < 3 && 3 > 1;\nlet or = 2 < 2 || 3 < 7;\nlet negación = 5 != '5';\nlet negaciónEstricta = 5 !== '5';\nlet igualdad = 6 == '6';\nlet igualdadEstricta = 6 === '6';\n\n\nconsole.log('Operadores Lógicos y Comparación: ');\nconsole.log('mayorQ: ', mayorQ);\nconsole.log('menorQ: ', menorQ);\nconsole.log('mayorIgualQ: ', mayorIgualQ);\nconsole.log('menorIgualQ: ', menorIgualQ);\nconsole.log('and: ', and);\nconsole.log('or: ', or);\nconsole.log('negación: ', negación);\nconsole.log('negación Estricta: ', negaciónEstricta);\nconsole.log('negación2: ', !mayorQ);\nconsole.log('igualdad: ', igualdad);\nconsole.log('igualdad estricta: ', igualdadEstricta);\n\n\n//DIFICULTAD EXTRA\nconsole.log('----- DIFICULTAD EXTRA -----');\nfor (let i = 10; i <= 55; i++) {\n\n    if (i !== 16 && !(i % 3 == 0) && i % 2 == 0 ) {\n    console.log(i);\n}\n};\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/maximiliano1997.js",
    "content": "/*\r\n# #01 OPERADORES Y ESTRUCTURAS DE CONTROL\r\n    > #### Dificultad: Fácil | Publicación: 02 /01 / 24 | Corrección: 08 /01 / 24\r\n\r\n## Ejercicio\r\n\r\n    ```\r\n/*\r\n * EJERCICIO:\r\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\r\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\r\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\r\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\r\n *   que representen todos los tipos de estructuras de control que existan\r\n *   en tu lenguaje:\r\n *   Condicionales, iterativas, excepciones...\r\n * - Debes hacer print por consola del resultado de todos los ejemplos.\r\n *\r\n * DIFICULTAD EXTRA (opcional):\r\n * Crea un programa que imprima por consola todos los números comprendidos\r\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\r\n *\r\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\r\n */\r\n\r\n\r\nlet dev = 'Gracias'\r\n\r\n\r\n// Operadores Aritmeticos: retornan el resultado de esas operaciones aritm.\r\n\r\nlet suma = 5 + 2\r\nlet resta = 11 - 10\r\nlet multiplicacion = 5 * 5\r\nlet division = 10 / 2\r\nlet resto = 10 % 2\r\nlet exponenciacion = 5 ** 5\r\nlet incremento = 5; incremento++\r\nlet decremento = 5; decremento--\r\nlet negativo = -1\r\nlet conversion_de_string_a_numero = +'1'\r\n\r\n\r\n// Operadores de Asignacion:\r\n\r\nx = 10      /* Asignacion simple */\r\nx += 10     /* Suma y Asigna */\r\nx -= 10     /* Resta y Asigna */\r\nx *= 10     /* Multiplica y Asigna */\r\nx /= 10     /* Divide y Asigna */\r\nx %= 10     /* Saca el resto y Asigna */\r\nx **= 10    /* Potencia y Asigna */\r\n\r\n\r\n// OPERADORES DE COMPARACION: retornan boleanos true o false\r\n\r\n10 == '10'      // Igualdad \"compara valor\" */\r\n10 != '10'     // Desigualdad \"compara valor\" */\r\n10 === '10'     // Igualdad estricta \"compara valor y tipo\"\r\n10 !== '10'     // Desigualdad estricta \"compara valor y tipo\"\r\n10 > 10     // Mayor que\r\n10 < '10'     // Menor que\r\n10 >= '10'     // Mayor o igual que\r\n10 <= '10'     // Menor o igual que\r\n\r\n// Operadores Logicos:  para loops/condiciones\r\n\r\ntrue && false  // AND logico\r\ntrue || false  // AND logico\r\n!true          // NOT logico\r\ntrue ?? false; // null o undefined para condicionales\r\n\r\n// Operador Ternario:\r\n\r\ndev ? true : false      // Condicional\r\n\r\n\r\n// Comprobacion en consola de todos los EJEMPLOS:\r\nconsole.log(`\r\n    Operadores Aritmeticos:\r\n\r\n    suma: ${suma}\r\n    resta: ${resta}\r\n    multiplicacion: ${multiplicacion}\r\n    division: ${division}\r\n    resto: ${resto}\r\n    exponenciacion: ${exponenciacion}\r\n    incremento: ${incremento}\r\n    decremento: ${decremento}\r\n    negativo: ${negativo}\r\n\r\n    Operadores de Aisgnacion:\r\n   ${x = 10}      <-- Asignacion simple\r\n   ${x += 10}     <-- Suma y Asigna\r\n   ${x -= 10}     <-- Resta y Asigna\r\n   ${x *= 10}     <-- Multiplica y Asigna\r\n   ${x /= 10}     <-- Divide y Asigna\r\n   ${x %= 10}     <-- Saca el resto y Asigna\r\n   ${x **= 10}    <-- Potencia y Asigna\r\n\r\n    Operadores de Comparacion:\r\n\r\n    ${10 == '10'}      <-- Igualdad \"compara valor\" */\r\n    ${10 != '10'}     <-- Desigualdad \"compara valor\" */\r\n    ${10 === '10'}     <-- Igualdad estricta \"compara valor y tipo\"\r\n    ${10 !== '10'}     <-- Desigualdad estricta \"compara valor y tipo\"\r\n    ${10 > 10}        <-- Mayor que\r\n    ${10 < '10'}     <-- Menor que\r\n    ${10 >= '10'}     <-- Mayor o igual que\r\n    ${10 <= '10'}     <-- Menor o igual que\r\n\r\n    Operadores Logicos:\r\n\r\n    ${true && false}  <-- AND logico\r\n    ${true || false}  <-- AND logico\r\n    ${!true}          <-- NOT logico\r\n    ${dev ?? false}   <-- null o undefined para condicionales\r\n\r\n    Operador Ternario:\r\n    ${dev ? true : false}    < --Condicional\r\n    `)\r\n\r\n\r\n//DIFICULTAD EXTRA(opcional):\r\n/*Crea un programa que imprima por consola todos los números comprendidos\r\nentre 10 y 55(incluidos), pares, y que no son ni el 16 ni múltiplos de 3.*/\r\n\r\nfor (let i = 10; i <= 55; i++) {\r\n    if (i == 16 || i % 3 == 0 || i % 2 !== 0) {\r\n        continue;\r\n    }\r\n    console.log(i)\r\n}\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/memoGV.js",
    "content": "\nlet suma = 2 + 2    \nlet resta = suma -2\nlet multiplicacion = suma * 2   \nlet division = multiplicacion / 2   \nlet resto = division % 2    \nlet incrementa = suma++\nlet decrementa = resta-- \nlet exponente = 2 ** 3\n\nlet asignacion = 2 = 2\nlet asignacionSuma = 2 += 2\nlet asignacionResta = 2 -= 2\nlet asignacionMultiplicacion = 2 *= 2\nlet asignacionDivision = 2 /= 2\nlet asignacionResto = 2 %= 2\nlet asignacionExponente = 2 **= 2\n\nlet igualdad = 2 == 2\nlet igualdadEstricta = 2 === 2\nlet desigualdad = 2 != 2    \nlet desigualdadEstricta = 2 !== 2\nlet mayorQue = 2 > 2\nlet menorQue = 2 < 2\nlet menorQueOIgual = 2 <= 2\nlet mayorQueOIgual = 2 >= 2\nlet and = 2 && 2\nlet or = 2 || 2\nlet not = !2\n\nif(suma > 2){\n    console.log(\"Es mayor\")\n}else{\n    console.log(\"Es menor\")}\n\nswitch(suma){\n    case 1: console.log(\"Es 1\");\n    break;\n    default: console.log(\"Es otro valor\")   \n}\n\nfor(let i = 0; i<10; i++){\n    console.log(i)\n}\n\nwhile(suma < 10){\n    console.log(suma)\n    suma++\n}\n\ndo{\n    console.log(suma)\n    i++\n}while(i<5)\n\n    // Programa para imprimir por consola\n\nconst printNumbers =(num1, num2)=>{\n\n    while(num1 < num2){\n\n        if(num1 === 16 || num1%3 === 0){\n            num1++\n            continue\n        }\n        \n        if(num1 >= 10 && num1 <=55){\n            console.log(num1)\n        }else if(num1%2 === 0){\n            console.log(num1)\n        }\n        num1++\n    }\n}\n\nprintNumbers(4, 90);\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/mickel-arroz.js",
    "content": "// #01 - OPERADORES Y ESTRUCTURAS DE CONTROL\n\nlet x = 0;\nlet y = 1;\n\n// OPERADORES\nconsole.clear();\nconsole.log(`\\nx:${x} \\ny: ${y} \\n\\n`);\nconsole.log(\"OPERADORES EN JS:\\n\");\nconsole.log(\"x=y:\", (x = y));\nx = 0;\nconsole.log(\"Operador de adición\");\nconsole.log(\"x+y:\", x + y);\nconsole.log(\"Operador de incremento\");\nconsole.log(\"x++:\", x++);\nx = 0;\nconsole.log(\"Operador de resta\");\nconsole.log(\"x-y:\", x - y);\nconsole.log(\"Operador de decremento\");\nconsole.log(\"x--:\", x--);\nx = 0;\nconsole.log(\"Operador de multiplicación\");\nconsole.log(\"x*y:\", x * y);\nconsole.log(\"Operador de división\");\nconsole.log(\"x/y:\", x / y);\nconsole.log(\"Operador de residuo\");\nconsole.log(\"x%y:\", x % y);\nconsole.log(\"Operador de exponenciación\");\nconsole.log(\"x**y:\", x ** y);\n\nconsole.log(\"Operador de desplazamiento a la izquierda\");\nconsole.log(\"x<<y:\", x << y);\n\nconsole.log(\"Operador de desplazamiento a la derecha\");\nconsole.log(\"x>>y:\", x >> y);\n\nconsole.log(\"Operador de desplazamiento a la derecha sin signo\");\nconsole.log(\"x>>>y:\", x >>> y);\n\nconsole.log(\"Operador AND bit a bit\");\nconsole.log(\"x&y:\", x & y);\n\nconsole.log(\"Operador XOR bit a bit\");\nconsole.log(\"x^y:\", x ^ y);\n\nconsole.log(\"Operador OR bit a bit\");\nconsole.log(\"x|y:\", x | y);\n\nconsole.log(\"Operador AND lógico\");\nconsole.log(\"x&&y:\", x && y);\n\nconsole.log(\"Operador OR lógico\");\nconsole.log(\"x||y:\", x || y);\n\nconsole.log(\"Operador de anulación lógica\");\nconsole.log(\"x??y:\", x ?? y);\n\n// EJEMPLOS CON ESTRUCTURAS DE CONTROL\nconsole.log(\"\\n\\nEJEMPLOS CON ESTRUCTURAS DE CONTROL\\n\\n\");\nconsole.log(\"CONDICIONALES\\n\");\n\nconst condicional = (x, y) => {\n  if (x > y) {\n    return \"x>y\";\n  } else if (x == y) {\n    return \"x==y\";\n  } else {\n    return \"x<y\";\n  }\n};\n\nconsole.log(\n  \"if(x>y){\\nreturn 'x>y'\\n} else if(x==y){\\nreturn 'x==y'\\n} else {\\nreturn 'x<y'\\n}\\n\\n Resultado: \",\n  condicional(x, y)\n);\n\n// SWITCH\n\nconsole.log(\"\\n\\nSWITCH\");\nswitch (x) {\n  case 1:\n    console.log(\"x es 1\");\n    break;\n  case 2:\n    console.log(\"x es 2\");\n    break;\n  default:\n    console.log(\"x es otro valor\");\n}\n\nconsole.log(\"\\n\\nFOR\");\n\nfor (let i = 0; i < 10; i++) {\n  console.log(i);\n}\n\nconsole.log(\"\\n\\nWHILE \");\n\nwhile (x < 10) {\n  console.log(x);\n  x++;\n}\n\nx = 0;\n\nconsole.log(\"\\n\\nDO WHILE \");\n\ndo {\n  console.log(x);\n  x++;\n} while (x < 5);\n\nx = 0;\n\nconsole.log(\"\\n\\nEJECICIO EXTRA\\n\");\n\nfor (let i = 10; i <= 55; i++) {\n  if (i != 16 && !(i % 3 == 0) && i % 2 == 0) console.log(i);\n}\n\nconsole.log(\n  \"\\n\\nGracias por su tiempo.\\nSi lees esto vas a tener una vida muy exitosa. \\nBendiciones <3\"\n);\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/miguelRejon96.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n//Operadores Aritméticos\nlet x = 10;\nlet y = 5;\nconsole.log(\"Suma: \", x + y); //Suma\nconsole.log(\"Resta: \", x - y); //Resta\nconsole.log(\"Multiplicación: \", x * y); //Multiplicación\nconsole.log(\"División\", x / y); //División\nconsole.log(\"Residuo\", x % y); //Residuo\nconsole.log(\"Exponenciación: \", x ** y); //Exponenciación\n\n//Operadores de asignación\nlet a = 10;\na += 3; // a = a +3\nconsole.log(\"a += 3: \", a);\na -= 3; // a = a - 3\nconsole.log(\"a -= 3: \", a);\na *= 3; // a = a * 3\nconsole.log(\"a *= 3: \", a);\na /= 3; // a = a / 3\nconsole.log(\"a /= 3: \", a);\na %= 3; // a = a % 3\nconsole.log(\"a %= 3: \", a);\na **= 3; // a = a ** 3\nconsole.log(\"a **= 3: \", a);\n\n//Operadores de comparación\nlet b = 5;\nconsole.log(\"a == b: \", a == b); //Igualdad\nconsole.log(\"a === b: \", a === b); //Igualdad estricta\nconsole.log(\"a != b: \", a != b); //Desigualdad\nconsole.log(\"a !== b: \", a !== b); //Desigualdad estricta\nconsole.log(\"a > b: \", a > b); //Mayor que\nconsole.log(\"a < b: \", a < b); //Menor que\nconsole.log(\"a >= b: \", a >= b); //Mayor o igual que\nconsole.log(\"a <= b: \", a <= b); //Menor o igual que\n\n//Operadores lógicos\nconsole.log(\"true && false: \", true && false); // AND\nconsole.log(\"true || false: \", true || false); // OR\nconsole.log(\"!true: \", !true); //NOT\n\n//Operadores de Bits\nconsole.log(x << y); //Desplazamiento a la izquierda\nconsole.log(x >> y); //Desplazamiento a la derecha\nconsole.log(x >>> y); //Desplazamiento a la derecha sin signo\nconsole.log(x & y); //Asignación AND bit a bit\nconsole.log(x ^ y); //Asignación XOR bit a bit\nconsole.log(x | y); //Asignación OR bit a bit\nconsole.log(x && (x = y)); //Asignación AND lógico\nconsole.log(x || (x = y)); //Asignación OR lógico\nconsole.log(x ?? (x = y)); //Asignación de anulación lógica\n\n//Estucturas de control\n\n// Condicionales\n\nif (x > y) {\n  console.log(\"x es mayor que y\");\n} else {\n  console.log(\"x no es mayor que y\");\n}\n\nlet z = 3;\nswitch (z) {\n  case 1:\n    console.log(\"Z es 1\");\n    break;\n  case 2:\n    console.log(\"Z es 2\");\n    break;\n  case 3:\n    console.log(\"z es 3\");\n    break;\n  default:\n    console.log(\"z no es 1,2 o 3\");\n}\n\n//Iterativas\nfor (let i = 0; i < 5; i++) {\n  console.log(\"For loop i: \", i);\n}\nlet j = 0;\nwhile (j < 5) {\n  console.log(\"while loop j: \", j);\n  j++;\n}\nlet k = 0;\ndo {\n  console.log(\"do while loop k: \", k);\n  k++;\n} while (k < 5);\n\n//Excepciones\ntry {\n  throw new error(\"Error\");\n} catch (error) {\n  console.log(\"Mensaje: \", error.message);\n} finally {\n  console.log(\"Finally\");\n}\n\n//Ejercicio Extra\nfunction extraExercise() {\n  for (let i = 10; i <= 55; i++) {\n    if (i % 2 == 0 && i !== 16 && i % 3 !== 0) {\n      console.log(i);\n    }\n  }\n}\n\nextraExercise();\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/miguelex.js",
    "content": "// Ejemplo de operadores aritméticos\n\n\nlet a = 10;\nlet b = 2;\nconsole.log(\"La suma es: \" + (a+b));\nconsole.log(\"La resta es: \" + (a-b));\nconsole.log(\"La multiplicación es: \" + (a*b));\nconsole.log(\"La división es: \" + (a/b));\nconsole.log(\"El resto es: \" + (a%b));\nconsole.log(\"El incremento es: \" + (++a));\nconsole.log(\"El decremento es: \" + (--b));\nconsole.log(\"El negativo es: \" + (-a));\n\n// Operadores de asignación\n\nconsole.log(\"La suma es: \" + (a+=b));\nconsole.log(\"La resta es: \" + (a-=b));\nconsole.log(\"La multiplicación es: \" + (a*=b));\nconsole.log(\"La división es: \" + (a/=b));\nconsole.log(\"El resto es: \" + (a%=b));\n\n// Operadores de comparación\n\nconsole.log(\"Igual: \" + (a==b));\nconsole.log(\"Identico: \" + (a===b));\nconsole.log(\"Distinto: \" + (a!=b));\nconsole.log(\"No identico: \" + (a!==b));\nconsole.log(\"Menor: \" + (a<b)); \nconsole.log(\"Mayor: \" + (a>b));\nconsole.log(\"Menor o igual: \" + (a<=b));\nconsole.log(\"Mayor o igual: \" + (a>=b));\n\n// Operadores lógicos\n\nconsole.log(\"AND: \" + (a<b && a>b));\nconsole.log(\"OR: \" + (a<b || a>b));\nconsole.log(\"NOT: \" + !(a<b));\n\n// Operadores nivel bit\n\nconsole.log(\"AND: \" + (a&b));\nconsole.log(\"OR: \" + (a|b));\nconsole.log(~a);     \nconsole.log(a << 1); \nconsole.log(a >> 1); \nconsole.log(b >>> 1)\n\n// Ejemplo bucle For\n\nfor (let i = 0; i < 10; i++) {\n    console.log(i);\n}\n\n// Ejemplo bubcle for in\n\nlet cadena = \"Hola mundo\";\nfor (let i in cadena) {\n    console.log(cadena[i]);\n}\n\n// Ejemplo bucle for of\n\nfor (let i of cadena) {\n    console.log(i);\n}\n\n// Ejemplo switch\n\nlet dia = 1;\n\nswitch (dia) {\n    case 1:\n        console.log(\"Lunes\");\n        break;\n    case 2:\n        console.log(\"Martes\");\n        break;\n    default:\n        console.log(\"Otro día\");\n        break;\n}\n\n// Ejemplo while\n\nlet i = 0;\n\nwhile (i < 10) {\n    console.log(i);\n    i++;\n}\n\n// Ejemplo do while\n\nlet j = 0;\n\ndo {\n    console.log(j);\n    j++;\n} while (j < 10);\n\n// Manejo de excepciones\n\ntry {\n    let x = 10;\n    let y = 0;\n    if (y == 0) {\n        throw(\"División por cero\");\n    }\n    let z = x / y;\n    console.log(z);\n} catch (error) {\n    console.log(error);\n} finally {\n    console.log(\"Terminado\");\n}\n\n// Ejercicio extra\n\nfunction ejercicioExtra() {\n    for (let i = 10; i <= 55; i++) {\n        if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n            console.log(i);\n        }\n    }\n}\n\nejercicioExtra();\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/migueltfangche.js",
    "content": "/**\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n \n */\n\nlet a =1;\nlet b =2;\n//**aritmeticos */\nconsole.log(a + b); // suma \nconsole.log(a - b); // resta\nconsole.log(a * b); // multiplicacion\nconsole.log(a / b); // division\nconsole.log(a % b); //modulo\nconsole.log(a ** b); //potencia\n//**comparacion */\nconsole.log(a == b); // igual \nconsole.log(a >= b); // mayor o igual\nconsole.log(a <= b); // menor o igual\nconsole.log(a =! b); // diferente\n//*asignacion/**\na = 5;\na = a + 5;\n\na += 5; \na -= 5;\na *= 5;\na /= 5;\na &= 5;\na **= 5;\nconsole.log(a);\n//*bits/*\n/**\n * 0 es 00000000\n * 1 es 00000001\n * 2 es 00000010\n * 3 es 00000011\n * 4 es 00000100\n * 5 es 00000101\n * 6 es 00000110\n * 7 es 00000111\n * 8 es 00001000\n * 9 es 00001001\n */\n/**or */\n\nconsole.log(1 | 7); //*00000111 seria 7\nconsole.log(2 | 6); //*00000110 seria 6\nconsole.log(3 | 5); //*00000111 seria 7\n/** and */\nconsole.log(1 & 7); //*00000001 seria 1\nconsole.log(2 & 6); //*00000010 seria 2\nconsole.log(3 & 5); //*00000001 seria 1\n//*** estructuras de control \n//* condicionales\n\nlet numero = 3;\nif (numero < 10) {\n        console.log('el numero es menor a 10');        \n    } else {\n        console.log('No es un numero menor a 10');\n    }\n\n//* iterativas\nlet user = {\n    id : 1,\n    nombre : 'Miguel',\n    edad : 39,\n};\nfor (let datos in user) {\n    console.log(datos, user[datos]);\n}\n\nlet numero1 = 1;\n    while (numero1 < 10) {\n    console.log('el numero es menor a 10');\n    numero1++;\n    \n}\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/misterdan100.js",
    "content": "// #01 OPERADORES Y ESTRUCTURAS DE CONTROL\n\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_operators\n// most common assignament symbols\nlet x = 100\nx = 200 // asigna un valor\nx += 100 // suma un valor\nx -= 100 // resta un valor\nx *= 100 // multiplica un valor\nx /= 100 // divide un valor\nx %= 100 // devulve el residuo de un division\nx **= 100 // asigna una exponenciacion\n\n// comparison operators\nlet equal = '==' // return true if the operands are equal\nlet notEqual = '!=' // return true if the operands are not equal\nlet strictEqual = '===' // return true if the operators are equal value and type\nlet strictNotEqual = '!==' // return true if the operators are not equal value and type\nlet greaterThan = '>' // return true if the first value if greater than the second\nlet greaterThanOrEqual = '>=' // return true if first value is greater or equal thant the second\nlet lessThan = '<' // return true if the first value if less than the second\nlet lessThanOrEqual = '<=' // return true if first value is less or equal thant the second\n\n// Control flow structures\n//* if ... else\n// validate if a condion is true if no do another thing\nif (true) {\n    console.log('condition is true')\n} else {\n    console.log('condition is false')\n}\n\n//* if ... else if ... else \n// allow validate several condicions\nif (true) {\n    console.log('condition is true')\n} else if (true) {\n    console.log('second condition as true')\n} else if (true) {\n    console.log('third condition as true')\n} else {\n    console.log('condition is false')\n}\n\n//* switch\n// allows avaluate defferents cases where the condicion can be true\nswitch (true) {\n    case true:\n        console.log('first case is true')\n        break;\n    case true:\n        console.log('first case is true')\n        break;\n    // …\n    default:\n        console.log('default result if anycase is true')\n}\n\n//* while\n// allows execute a code block while a condition is true\nlet condition = true\nwhile(condition) {\n    // code block\n}\n\n//* do ... while\n// allows execute a code block at least one time and the rest while a condition is true\ncondition = true\ndo {\n    // code block\n} while(condition)\n\n//* try... catch\n// if there is some error while the execution 'catch' capture the error without break the application\ntry {\n    // some fetch process\n} catch (error) {\n    console.log(error)\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/monicavaquerano.js",
    "content": "// 01 OPERADORES Y ESTRUCTURAS DE CONTROL\n// Monica Vaquerano\n//  https://monicavaquerano.dev\n\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n\n// Assignment\nlet x = 5;\nlet y = 10;\n\n// Arithmetic\nconsole.log(\"suma: 5 + 10 =\", x + y);\nconsole.log(\"resta: 5 - 10 =\", x - y);\nconsole.log(\"multiplicacion: 5 * 10 =\", x * y);\nconsole.log(\"exponencial: 5 ** 10 =\", x ** y);\nconsole.log(\"division: 5 / 10 =\", x / y);\nconsole.log(\"modulo: 10 % 5 =\", y % x);\n\n// Assignment Operators\nconsole.log(\"suma: x += y \", x += y);\nconsole.log(\"resta: x -= y \", x -= y);\nconsole.log(\"multiplicacion: x *= y \", x *= y);\nconsole.log(\"exponencial: x **= y \", x **= y);\nconsole.log(\"division: x /= y \", x /= y);\nconsole.log(\"modulo: y /= x \", y %= x);\n\n// Comparison Operators\nx = 12;\ny = 6;\n\nconsole.log(\"x == 12 :\", x == 12);\nconsole.log(\"x === '12' :\", x === '12');\nconsole.log(\"y != 6 :\", y != 6);\nconsole.log(\"y !== '6' :\", y !== '6');\nconsole.log(\"x > y :\", x > y);\nconsole.log(\"x < y :\", x < y);\nconsole.log(\"x >= 12 :\", x >= 12);\nconsole.log(\"x <= 11 :\", x <= 11);\nconsole.log(\"x >= y ? 'x es mayor o igual' : 'x no es mayor o igual' =>\", x >= y ? 'x es mayor o igual' : 'x no es mayor o igual');\n\n\n// Logical Operators\nconsole.log(\"x > y && x == 12 :\", x > y && x == 12);\nconsole.log(\"x != 12 || y == 6 :\", x != 12 || y == 6);\nconsole.log(\"!(x != 12 && y != 6) :\", !(x != 12 && y != 6));\n\n// Type Operators\nconsole.log(\"typeof x :\", typeof x);\nconsole.log(\"typeof 'Soy una string' :\", typeof 'Soy una string');\ncadena = new String('Soy una string');\nnumero = new Number(8);\nconsole.log(\"numero instanceof Number :\", (numero instanceof Number));\nconsole.log(\"cadena instanceof String :\", (cadena instanceof String));\n\n// Shift Assignment Operators\nconsole.log(\"x <<= y :\", x <<= y);\nconsole.log(\"x >>= y :\", x >>= y);\nconsole.log(\"x >>>= y :\", x >>>= y);\n\n// Bitwise Assignment Operators\nx = 2, y = 2;\nconsole.log(\"x &= y :\", x &= y);\nconsole.log(\"x ^= y :\", x ^= y);\nconsole.log(\"x |= y :\", x |= y);\n\n// Operadores de Pertenencia\n\nconst car = { make: 'Honda', model: 'Accord', year: 1998 };\n\nconsole.log('make' in car);\n// Expected output: true\n\ndelete car.make;\nif ('make' in car === false) {\n    car.make = 'Suzuki';\n}\n\nconsole.log(car.make);\n// Expected output: \"Suzuki\"\n\n\n// # - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n// # que representen todos los tipos de estructuras de control que existan\n// # en tu lenguaje:\n// # Condicionales, iterativas, excepciones...\n// # Debes hacer print por consola del resultado de todos los ejemplos.\n\nconsole.log(\"\\nEstructuras de Control Condicional:\");\n\nlet list = [-3, 0, 1, 6];\n\n// Loop For If\nfor (let item in list) {\n    list[item] *= 2;\n    if (list[item] < 0) {\n        console.log(\"Soy un número negativo:\", list[item])\n    } else if (list[item] == 0) {\n        console.log(\"Soy cero!\")\n    } else if (0 < list[item] && list[item] < 4) {\n        console.log(\"Soy un número entre 0 y 5:\", list[item])\n    } else {\n        console.log(\"Soy un número mayor a 5:\", list[item])\n    }\n}\n\n// Loop For Of - parecido más a pyhton\nfor (let item of list) {\n    if (item < 0) {\n        console.log(item, \"bajo cero\")\n    } else if (item > 0) {\n        console.log(item, \"sobre cero\")\n    } else {\n        console.log(\"Soy ceroooo!\")\n    }\n}\n\nconsole.log(\"\\nEstructuras de Control Ternario:\");\n\n// Loop For\nfor (let i = 0; i < list.length; i++) {\n\n    // Conditional (ternary) operator / Operador condicional (ternario)\n    console.log(list[i] <= 0 ? \"Soy un número negativo\" : \"Soy un número positivo\");\n}\n\nconsole.log(\"\\nEstructuras de Control Iterativas:\");\n\n// While loop\nlet counter = 0;\nwhile (counter < 3) {\n    console.log(\"Counter es menor a 3: counter =\", counter)\n    counter++\n}\n\n//Do-While loop\ncounter = 3;\ndo {\n    console.log(\"Counter es mayor a 0: counter =\", counter)\n    counter--\n}\nwhile (counter > 0);\n\n// For Loop\nfor (let i = 10; i >= 0; i--) {\n    if (i == 0) {\n        console.log(\"Boom!\");\n    } else {\n        console.log(i);\n    }\n}\n\n// Switch\nlet day;\nswitch (new Date().getDay()) {\n    case 0:\n        day = \"Sunday\";\n        break;\n    case 1:\n        day = \"Monday\";\n        break;\n    case 2:\n        day = \"Tuesday\";\n        break;\n    case 3:\n        day = \"Wednesday\";\n        break;\n    case 4:\n        day = \"Thursday\";\n        break;\n    case 5:\n        day = \"Friday\";\n        break;\n    case 6:\n        day = \"Saturday\";\n        break;\n    default:\n        day = \"I don't know\";\n        break;\n}\nconsole.log(day)\n\n// For In loop in Object\nlet contactos = {\n    \"Alice\": { \"telefono\": \"0123456\" },\n    \"Bob\": { \"telefono\": \"0123456\" },\n    \"Charlie\": { \"telefono\": \"0123456\" },\n}\nfor (let i in contactos) {\n    console.log(i, contactos[i])\n}\n\n// For Of Loop in Objects\n\n// Loop over keys\nfor (let key of Object.keys(contactos)) {\n    console.log(key)\n}\n\n// Loop over values\nfor (let value of Object.values(contactos)) {\n    console.log(value)\n}\n\n// Loop over entries\nfor (let [key, value] of Object.entries(contactos)) {\n    console.log(`${key.toUpperCase()}: ${Object.values(value)}`)\n}\n\n\nconsole.log(\"\\nExcepciones:\");\n// Try and except\nx = 0;\ntry {\n    if (x == 0) {\n        throw new Error(\"Ocurrió una excepción :P\");\n    }\n} catch (error) {\n    console.error(error.message);\n}\n\n// Muchas excepciones\ntry {\n    if (x == 0) throw \"No es cero\";\n    if (x < 0) throw \"Es menor que cero\";\n    if (x > 0) throw \"Es mayor que cero\";\n\n} catch (error) {\n    console.log(\"Ocurrió una excepción:\", error)\n}\n\n// Error: Name of Error and Message\ntry {\n    throw new TypeError(\"oops\");\n} catch ({ name, message }) {\n    console.log(name); // \"TypeError\"\n    console.log(message); // \"oops\"\n}\n\n\n// Excepciones Anidadas\ntry {\n    try {\n        throw new Error('mi error');\n    } catch (err) {\n        console.error('interno', err.message);\n        throw err;\n    } finally {\n        console.log('finally interno');\n    }\n} catch (err) {\n    console.error('externo', err.message);\n}\n\n// Output:\n// interno mi error\n// finally interno\n// externo mi error\n\n\n// Excepciones con Finally\ntry {\n    if (x == 0) {\n        throw (new Error(\"ERROR\"));\n    }\n} catch (err) {\n    console.error('Catch:', err.message);\n} finally {\n    console.log(\"Finally!!!!!\");\n}\n\n\n// DIFICULTAD EXTRA (opcional):\n// Crea un programa que imprima por consola todos los números comprendidos\n// entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3:\n// \"\"\"\nconsole.log(\"DIFICULTAD EXTRA\")\n\nlet result = \"\";\nfor (let i = 10; i <= 55; i++) {\n    if (i % 2 == 0 && !(i % 3 == 0) && i != 16) {\n        result += `${i}, `\n    }\n}\nconsole.log(result.slice(0, -2));"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/murquisdev.js",
    "content": "// https://developer.mozilla.org/es/docs/Web/JavaScript/Guide/Expressions_and_operators\r\n\r\n/* \r\n    JS tiene tres tipos de operadores, unarios, binarios y condicional (ternario)\r\n    Unario requiere un solo operando: operador operando (u operando operador) --> x++ \"o\" ++x\r\n    Binario requerie dos operandos: operando1 operador operando2 --> 3 + 4, 5 * 3\r\n    \r\n*/\r\n\r\n// Los principales operadores que tiene JS son los de comparación, aritméticos, lógicos, asignación y de cadenas, aunque también\r\n// tiene de bit a bit.\r\n\r\n// ASIGNACIÓN\r\n// Le da el valor del operando derecho al operando izquierdo\r\n/*\r\n    ASIGNACIÓN ( = )\r\n    x = 3\r\n    y = 5\r\n    x = y // x tiene el valor 5\r\n\r\n    Se puede añadir una operación matemática antes de asignar el valor\r\n    x += y // 8\r\n    x *= y // 15\r\n*/\r\n\r\n// COMPARACIÓN --> Devuelve TRUE o FALSE\r\nlet var1 = 3\r\nlet var2 = 4\r\n/*\r\n    JS tiene dos operadores diferentes para comparar la igualdad (y la desigualdad) con unas características particulares de\r\n    este lenguaje.\r\n\r\n    IGUAL ( == ): Devuelve TRUE si los operandos son iguales\r\n    Con el comparador igual JS intenta convertir el tipo de dato primitivo si no son iguales para hacer la comparación.\r\n\r\n    3 == var1 // TRUE var1 tiene el valor NUMÉRICO 3 y lo compara con el número 3\r\n    \"3\" == var1 // TRUE var1 tiene el valor NUMÉRICO 3 y la cadena de texto la convierte al número 3\r\n    3 == '3' // TRUE compara el número 3 con la cadena de texto '3' que la convierte para la comparación\r\n\r\n    IGUAL ESTRICTO ( === ): Devuelve TRUE si los operandos son iguales y del mismo tipo.\r\n\r\n    3 === var1 // TRUE var1 tiene el valor NUMÉRICO 3 y se está comparando con el NÚMERO 3\r\n    \"3\" === var1 // FALSE var1 es de tipo númerico y \"3\" es un STRING, no se pueden comparar.\r\n    \r\n    DESIGUAL ( != ): Devuelve TRUE cuando los operandos no son iguales.\r\n\r\n    5 != var1 // TRUE\r\n    var2 != \"3\" // TRUE\r\n\r\n    DESIGUAL ESTRICTO ( !== ): Devuelve TRUE sin los operandos son de diferente tipo y si son del mismo tipo, sino no son iguales.\r\n    \r\n    var2 !== 5 // TRUE\r\n    var2 !== 4 // FALSE\r\n    var2 !==\"5\" //TRUE\r\n\r\n    Mayor que ( > ), menor que ( < ), mayor o igual que ( >= ) y menor o igual que ( <= ): Devuelve TRUE cuando se cumple la condición\r\n    \"5\" > var2 // TRUE 5 es mayor que 4\r\n    4 >= var2 // TRUE 4 es igual a 4\r\n    3 > var2 // FALSE\r\n    3 < var2 // TRUE\r\n */\r\n\r\n// ARITMÉTICOS (operaciones matemáticas) \r\n// Como característica de JS, la división entre cero produce infinito.\r\n/*\r\n    + suma // 3 + 5\r\n    - resta // 5 - 3\r\n    * multiplicación // 5 * 10\r\n    / división // 10 / 2\r\n    % módulo (devuelve el resto de una división) // 10 % 2 --> 0\r\n    ** potencia o exponente // 3**2 --> 9\r\n    ++ incremento // 4++ --> 5\r\n    -- decremento // 4-- --> 3\r\n*/\r\n\r\n// LÓGICOS\r\n// Son los operadores que se utilizan con valores booleanos (TRUE o FALSE), y devuelven el resultado de la comparación lógica, aunque\r\n// si se utilizan sin valores boleanos pueden devolver valores no booleanos.\r\n\r\n/*\r\n    Y lógico ( && ): Devuelve TRUE si ambos operandos son TRUE\r\n\r\n    (3 < 4) && ( 5 > 4) --> TRUE\r\n    (4 < 4) && (4 > 3) --> FALSE\r\n\r\n    O lógico ( || ) --> Devuelve FALSE cuando los dos operandos son FALSE, sino devuelve TRUE.\r\n\r\n    (3 < 4) || ( 5 > 4) --> TRUE\r\n    (4 < 4) || (4 > 3) --> TRUE (se cumple 4 > 3)\r\n    (4 < 4) || (7 < 3) --> FALSE (no se cumple ninguna comparación)\r\n\r\n    NO lógico ( ! ): Invierte el valor de una expresión.\r\n\r\n    !(3 < 4) && ( 5 > 4) --> FALSE, invierto la primera expresión: (3 < 4) es TRUE, aplico la negación (!TRUE), es FALSE, y se hace la comparación\r\n                             FALSE && TRUE --> FALSE \r\n    \r\n    !(4 < 4) && (4 > 3) --> TRUE\r\n*/\r\n\r\n// CADENA (CONCATENACIÓN)\r\n// Se utiliza para unir cadenas de texto (Strings)\r\n/*\r\n    CONCATENACIÓN ( + )\r\n\r\n    \"La cadena \" + \" está separada\" // \"La cadena está separada\"\r\n    \r\n    let cadena = \"Vamos a unir una cadena usando un \"\r\n    cadena += \" operador de asignación\" // \"Vamos a unir una cadena usando un operador de asignación\"\r\n*/\r\n\r\n// CONDICIONAL (ternario)\r\n// Este operador se utiliza para obtener un valor de dos posibles ante una condición.\r\n/*\r\n    condition ? val1 : val2\r\n    Si condición es TRUE se obtiene el val1, sino val2\r\n\r\n    let age = 22\r\n    let tipo = age >= 18 ? \"adulto\" : \"menor\" // tipo = adulto\r\n    \r\n    Si la variable age es mayor o igual a 18 tomo el valor adulto, sino menor\r\n\r\n*/\r\n\r\n// TYPEOF\r\n// Operador unario que sirve para identificar el tipo de dato.\r\n// Se utiliza mucho para saber el tipo de dato con el que está trabajando una variable.\r\n\r\n/*\r\n    let x = 1\r\n    typeof x // number\r\n    let x = \"1\"\r\n    typeof(x) // string (se puede poner entre paréntesis o no)\r\n    let x = TRUE\r\n    typeof x // boolean\r\n*/\r\n\r\n// NOTA\r\n/* Indicar que las expresiones se pueden anidar unas dentro de otras y modificar el orden en el que se quieren que se hagan comparaciones con ().\r\n\r\n    No es lo mismo 5 + 3 * 5 // 20\r\n    que (5 + 3) * 5 // 40\r\n\r\n    Tampoco es lo mismo (3 > 4) || (4 > 3) && (4 === 4) --> TRUE (se lee de izquierda a derecha)\r\n    que  (3 > 4) || ( (4 < 3)  && (4 === 4) ) --> FALSE: (4 < 3) --> FALSE al comparar con el operador Y --> FALSE y (3 > 4) FALSE en el operador O\r\n*/\r\n\r\n// Los operadores de tipo bits los puedes revisar en https://developer.mozilla.org/es/docs/Web/JavaScript/Guide/Expressions_and_operators#bit_a_bit\r\n// Se utilizan para hacer modificaciones bit a bit en expresiones binarias.\r\n\r\n// EXPRESIONES\r\n/*  Una expresión es cualquier unidad de código que resuelve un valor, hay 2 tipos, las que asignan un valor y las que resuelven un valor.\r\n    x = 7 asigna un valor, 3 + 4 resuelve el valor 3 + 4 (7)  \r\n*/\r\n\r\n// ESTRUCTURAS DE CONTROL\r\n\r\n// CONDICIONALES --> https://developer.mozilla.org/es/docs/Learn/JavaScript/Building_blocks/conditionals\r\n\r\n/* \r\n    Las estructuras condicionales se utilizan para decir que camino debe seguir el programa \r\n    según el resultado de los operadores que le indiquemos\r\n\r\n    Hay dos estructuras para esto:\r\n    Estructura IF (else y else if)\r\n    Estructura SWITCH\r\n\r\n*/\r\n\r\n// IF\r\nlet x = 25\r\nif(x > 25){\r\n    console.log(\"La variable X es mayor de 25\")\r\n}else if( x < 25 ){\r\n    console.log(\"La variable X es menor de 25\")   \r\n}else{\r\n    console.log(\"La variable X es igual a 25\")\r\n}\r\n\r\n// Este código de arriba se podría leer así:\r\n// Si es mayor de 25 muestro un mensaje, sino, si es menor de 25, muestro otro mensaje diferente, sino muestro otro mensaje.\r\n\r\n// Se pueden meter IF dentro de otros (u otras estructuras), aunque hay que evitarlo en la medida de lo posible\r\nif(x === 25){\r\n    if((x % 5) === 0){ // Se pueden realizar operaciones, comparaciones lógicas...\r\n        console.log(\"X es múltiplo de 5\")\r\n    }else{\r\n        console.log (\"X no es múltiplo de 5\")\r\n    } \r\n}\r\n\r\n// Una mejor forma de escribir el código anterior sería introducción las condiciones en el mismo IF utilizando los operadores\r\n// lógicos\r\nif(x === 25 && ((x % 5) === 0)){ // Si X es estrictamente igual a 25 Y al dividir entre 5 obtengo un resto de 0\r\n    console.log(\"X es múltiplo de 5\")\r\n}else{\r\n    console.log (\"X no es múltiplo de 5\")\r\n}\r\n\r\n// La condición puede ser tan larga como se necesite\r\nif(x == 5 || x == 7 || x == 1 || x == 2 || x == 3){\r\n    console.log(\"X es un número primo\")\r\n}\r\n\r\n// SWITCH\r\n/*\r\n    switch (expresion){\r\n    case opcion1:\r\n        ejecuta este código\r\n        break;\r\n\r\n    case opcion2:\r\n        ejecuta este código\r\n        break;\r\n\r\n    // Se pueden incluir todos los casos que quieras\r\n\r\n    default:\r\n        Si no se cumple ningún caso\r\n        ejecuta este código\r\n    }\r\n    ES NECESARIO UTILIZAR LA PALABRA RESERVADA BREAK, sino no sale del SWITCH cuando ejecuta el caso y sigue buscando ejecutar más código\r\n*/\r\n\r\nlet dia = 4\r\nswitch(dia){\r\n    case 1:\r\n        console.log(\"Lunes\")\r\n        break;\r\n    case 2:\r\n            console.log(\"Martes\")\r\n            break;\r\n    case 3:\r\n        console.log(\"Miércoles\")\r\n        break;\r\n    case 4:\r\n            console.log(\"Jueves\")\r\n            break;\r\n    case 5:\r\n            console.log(\"Vienres\")\r\n            break;\r\n    case 6:\r\n        console.log(\"Sábado\")\r\n        break;\r\n    case 7:\r\n            console.log(\"Domingo\")\r\n            break;\r\n    default:\r\n        console.log(\"El número no se corresponde con un día de la semana\")\r\n        // En la última opción no es necesario el break\r\n}\r\n\r\nlet tiempo = \"soleado\"\r\nswitch(tiempo){\r\n    case \"nublado\":\r\n        console.log(\"Está nublado\")\r\n        break;\r\n    case \"soleado\":\r\n        console.log(\"Está soleado\")\r\n        break;\r\n    case \"lluvioso\":\r\n        console.log(\"Está lluvioso\")\r\n}\r\n\r\n// ITERACIONES (BUCLES) --> https://developer.mozilla.org/es/docs/Learn/JavaScript/Building_blocks/Looping_code\r\n\r\n/* \r\n    La estructuras iterativas (o bucles) se utilizan para repetir código una cantidad determinada de veces.\r\n    El número de repeticiones va a venir determinado por una condición, que va indicar el fin. Es necesario\r\n    tener mucho cuidado con esto, porque si nunca se cumple esa condición se crea un bucle infinito y nunca\r\n    se sale de él, creando un fallo en el programa.\r\n*/\r\n\r\n// FOR\r\n/*\r\n    // Se suele utilizar cuando sabemos la canitdad de veces que es necesario repetir el bucle\r\n    for (inicializador; condición; operación){\r\n        código a ejecutar\r\n    }\r\n\r\n*/\r\nfor(let x = 5; x < 9; x++){ // Para x = 5; mientras x menor que 9; sumar uno a X\r\n    console.log(x) // 5,6,7,8\r\n}\r\n\r\n// WHILE\r\n/*\r\n    // Se suele utilizar cuando hay una condición de salida, por ejemplo en una búsqueda al encontrar el elemento.\r\n    inicializador\r\n    while(condición) {\r\n        // código a ejecutar\r\n\r\n        operación\r\n    }\r\n*/\r\nlet encontrado = false // Inicializador\r\nlet numero = 1\r\nwhile(!encontrado){ // condición\r\n    if(numero === 10){\r\n        encontrado = true // operación\r\n        console.log(numero)\r\n    }else{\r\n        numero++ \r\n    }\r\n}\r\n\r\n// DO WHILE\r\n/*\r\n    // Igual que WHILE, con la diferencia que al menos se ejecuta siempre una vez\r\n    inicializador\r\n    do {\r\n        // código a ejecutar\r\n\r\n        operación\r\n    } while (condición)\r\n*/\r\ndo{\r\n    if(numero === 10){\r\n        encontrado = true // operación\r\n        console.log(numero)\r\n    }else{\r\n        numero++\r\n    }\r\n}while(!encontrado) // condición\r\n\r\n// EJERCICIO PROPUESTO\r\n/*\r\n    Crea un programa que imprima por consola todos los números comprendidos\r\n    entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\r\n    -------------------------------------------------------------------------\r\n    Analizamos el problema\r\n        - Utilizamos el bucle FOR, sabemos cuantas repeticiones va a tener, empezamos en 10\r\n          y terminamos en 55\r\n        - Hay 3 condiciones para imprimir\r\n            - Numeros pares ( usando el módulo de 2 = 0 sabemos si es par)\r\n            - El número 16 no se debe de imprimir\r\n            - Los multiplos de 3 no se deben imprimir ( usando el módulo 3 ! 0 sé que no es múltiplo)\r\n*/\r\n\r\nfor(let cont = 10; cont <= 55;cont++){\r\n    if((cont%2===0) && (cont!==16) && (cont%3!==0)){ // Si cont es par Y NO es 16 Y NO es múltiplo de 3\r\n        console.log(cont)\r\n    }\r\n}\r\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/natalyjoanna.js",
    "content": "\n// Operador Asignacion\n\nlet x = 10\nlet y = 20\nconsole.log(\"Valor de x: \" + x + \" Valor de y: \" + y)\n// Asignacion de adicion\nlet adicion = x += y\nconsole.log(\"Adicion: \" + adicion)\n// Asignacion de resta\nlet resta = x -= y\nconsole.log(\"Resta: \" + resta)\n// Asignacion de multiplicacion\nlet multiplicacion = x *= y\nconsole.log(\"Multiplicacion: \" + multiplicacion)\n// Asignacion de division\nlet division = x /= y\nconsole.log(\"Division: \" + division)\n// Asignacion de residuo\nlet residuo = x %= y\nconsole.log(\"Residuo: \" + residuo)\n// Asignacion de exponenciacion\nlet exponenciacion = x **= y\nconsole.log(\"Exponenciacion: \" + exponenciacion)\n\n\n\n// Operador Comparacion\n\n// Igual\nlet igual = x == y\nconsole.log(\"el valor de x y el valor de y, son iguales?\", igual)\n// No es igual\nlet noigual = x != y\nconsole.log(\"el valor de x y el valor de y, son diferentes?\", noigual)\n// Mayor que\nlet mayor = x > y\nconsole.log(\"el valor de x es mayor que el valor de y?\", mayor)\n// Menor que\nlet menor = x < y\nconsole.log(\"el valor de x es menor que el valor de y?\", menor)\n// Mayor o igual\nlet mayorigual = x >= y\nconsole.log(\"el valor de x es mayor o igual a el valor de y?\", mayorigual)\n// Menor o igual\nlet menorigual = x <= y\nconsole.log(\"el valor de x es menor o igual a el valor de y\", menorigual)\n\n// Operadores Aritmeticos\n\n// incremento\nlet incremento = x++\nconsole.log(\"Incremento: \", incremento)\n// decremento\nlet decremento = x--\nconsole.log(\"Decremento: \", decremento)\n\n// Operadores logicos \n\n// AND\nx && y\n// OR\nx || y\n// NOT\n!x\n\n\n// ESTRUCTURAS DE CONTROL\n\n// condicionales\nif (x >= y) {\n  console.log(\"El valor de x es mayor o igual a el valor de y\")\n} else {\n  console.log(\"El valor de x es menor a y\")\n}\n\n// bucle for\nfor(i=0; i<5; i++) {\n  console.log(\"Resultado: \" + i)\n}\n\n// bucle for con arrays\nlet animales = [\"Perro\", \"Gato\", \"Pato\", \"Caballo\"]\nfor (const animal of animales){\n  console.log(\"Animal: \", animal)\n}\n\nlet libro = {\n  title: \"1984\",\n  author: \"George Owell\",\n  genre: \"Fiction\",\n  yearPublished: 1949\n}\nfor (i in libro) {\n  console.log(`${i}: ${libro[i]}`)\n}\n\n// bucle while\nlet count = 0\nwhile(count<5){\n  console.log(\"count:\" + count)\n  count++\n}\n\n// bucle do while\ndo {\nconsole.log(\"count: \" + count)\ncount++\n} while(count<5)\n\n// switch\nlet color = \"Azul\"\nswitch(color) {\n  case \"Morado\":\n    console.log(\"Tu color favorito es el morado\")\n    break;\n  case \"Azul\":\n    console.log(\"Tu color favorito es el azul\")\n    break;\n  case \"Verde\":\n    console.log(\"Tu color favorito es el verde\")\n    break;\n  default:\n    console.log(\"Ninguna de las opciones anteriores es tu color favorito\")\n}\n\n\n// DIFICULTAD EXTRA\n\nfor(let i=10; i<=55;i++) {\n  if (i%2==0 && i!==16 && i%3!==0){\n    console.log(i)\n  }\n}\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/nestord23.js",
    "content": "/*\n * OPERADORES Y ESTRUCTURAS DE CONTROL EN JAVASCRIPT\n * https://developer.mozilla.org/es/docs/Web/JavaScript\n */\n\nconsole.log(\"=== Operadores en Javascript=====\");\n// ==========================================\n// 1. OPERADORES ARITMÉTICOS\n// ==========================================\nconsole.log(\"----Operadores Arimeticos ------\");\nlet a = 10;\nlet b = 3;\n\nconsole.log(`Suma: ${a} + ${b} = ${a + b}`);\nconsole.log(`Resta: ${a} - ${b} = ${a - b}`);\nconsole.log(`Multiplicación: ${a} * ${b} = ${a * b}`);\nconsole.log(`División: ${a} / ${b} = ${a / b}`);\nconsole.log(`Módulo (resto): ${a} % ${b} = ${a % b}`);\nconsole.log(`Exponenciación: ${a} ** ${b} = ${a ** b}`);\n\nlet x = 5;\nconsole.log(`incremento x++ = ${x++}, ahora x= ${x}`);\nlet y = 5;\nconsole.log(`Pre-incremento: ++y = ${++y}, ahora y = ${y}`);\nlet z = 5;\nconsole.log(`Decremento: z-- = ${z--}, ahora z = ${z}`);\n\n// ==========================================\n// 2. OPERADORES DE ASIGNACIÓN\n// ==========================================\nconsole.log(\"\\n--- OPERADORES DE ASIGNACIÓN ---\");\nlet num = 10;\nconsole.log(`asignacion simple: num ${num}`);\nnum += 5;\nconsole.log(`Suma y asigna (+=): num = ${num}`);\n\nnum -= 3;\nconsole.log(`Resta y asigna (-=): num = ${num}`);\n\nnum *= 2;\nconsole.log(`Multiplica y asigna (*=): num = ${num}`);\n\nnum /= 4;\nconsole.log(`Divide y asigna (/=): num = ${num}`);\n\nnum %= 5;\nconsole.log(`Módulo y asigna (%=): num = ${num}`);\n\nnum **= 2;\nconsole.log(`Exponenciación y asigna (**=): num = ${num}`);\n\n// ==========================================\n// 3. OPERADORES DE COMPARACIÓN\n// ==========================================\n\nconsole.log(\"\\n--- OPERADORES DE COMPARACIÓN ---\");\nlet p = 5;\nlet q = \"5\";\nconsole.log(`${p} == ${q}:${p == q}(igualdad debil)`);\nconsole.log(`${p} === ${q}:${p === q}(igualdad estricta)`);\nconsole.log(`${p} != ${q}: ${p != q} (desigualdad débil)`);\nconsole.log(`${p} !== ${q}: ${p !== q} (desigualdad estricta)`);\nconsole.log(`${p} > 3:${p > 3}`);\nconsole.log(`${p}< 10 : ${p < 10}`);\nconsole.log(`${p} >= 5: ${p >= 5}`);\nconsole.log(`${p} <= 4: ${p <= 4}`);\n\n// ==========================================\n// 4. OPERADORES LÓGICOS\n// ==========================================\nconsole.log(\"\\n --- Operadores Logicos ---\");\nlet Verdaderos = true;\nlet falso = false;\nconsole.log(`true && false : ${Verdaderos && falso} (AND logico)`);\nconsole.log(`true || false : ${Verdaderos || falso} (OR logico)`);\nconsole.log(`!true: ${!Verdaderos} (NOT logico)`);\n\n// Cortocircuito\nconsole.log(`Cortocircuito &&: ${0 && \"no se evalúa\"}`);\nconsole.log(`Cortocircuito ||: ${0 || \"se evalúa\"}`);\n\n// ==========================================\n// 5. OPERADORES DE BITS (BITWISE)\n// ==========================================\nconsole.log(\"\\n--- OPERADORES DE BITS ---\");\nlet bit1 = 5; // 0101 en binario\nlet bit2 = 3; // 0011 en binario\n\nconsole.log(`${bit1} & ${bit2} = ${bit1 & bit2} (AND bit a bit)`);\nconsole.log(`${bit1} | ${bit2} = ${bit1 | bit2} (OR bit a bit)`);\nconsole.log(`${bit1} ^ ${bit2} = ${bit1 ^ bit2} (XOR bit a bit)`);\nconsole.log(`~${bit1} = ${~bit1} (NOT bit a bit)`);\nconsole.log(`${bit1} << 1 = ${bit1 << 1} (desplazamiento izquierda)`);\nconsole.log(`${bit1} >> 1 = ${bit1 >> 1} (desplazamiento derecha)`);\nconsole.log(`-${bit1} >>> 1 = ${-bit1 >>> 1} (desplazamiento sin signo)`);\n\n// ==========================================\n// 6. OPERADORES DE CADENA (STRING)\n// ==========================================\nconsole.log(\"\\n--- OPERADORES DE CADENA ---\");\nlet str1 = \"Hola\";\nlet str2 = \"Mundo\";\nconsole.log(\n  `Concatenación: \"${str1}\" + \" \" + \"${str2}\" = \"${str1 + \" \" + str2}\"`\n);\n\n// ==========================================\n// 7. OPERADOR TERNARIO (CONDICIONAL)\n// ==========================================\nconsole.log(\"\\n--- OPERADOR TERNARIO ---\");\nlet edad = 18;\nlet mensaje = edad >= 18 ? \"Mayor de edad\" : \"Menor de edad\";\nconsole.log(`Edad ${edad}: ${mensaje}`);\n\n// ==========================================\n// 8. OPERADORES DE TIPO\n// ==========================================\nconsole.log(\"\\n -- operadores de tipo --\");\nlet variable = \"texto\";\nconsole.log(`typeof \"${variable}\": ${typeof variable}`);\nconsole.log(`typeof 42: ${typeof 42}`);\nconsole.log(`typeof true: ${typeof true}`);\n\nlet arr = [1, 2, 3];\nconsole.log(`[1,2,3] instanceof Array: ${arr instanceof Array}`);\n\n// ==========================================\n// 9. OPERADOR IN (PERTENENCIA)\n// ==========================================\nconsole.log(\"\\n--- OPERADOR IN (PERTENENCIA) ---\");\nlet objeto = { nombre: \"Juan\", edad: 30 };\nconsole.log(`\"nombre\" in objeto: ${\"nombre\" in objeto}`);\nconsole.log(`\"apellido\" in objeto: ${\"apellido\" in objeto}`);\n\nlet lista = [\"a\", \"b\", \"c\"];\nconsole.log(`1 in abcd : ${1 in lista}(indice existe)`);\nconsole.log(`5 in  abcd : ${5 in lista}(indice no existe)`);\n\n// ==========================================\n// 10. OPERADOR DELETE\n// ==========================================\nconsole.log(\"\\n--- OPERADOR DELETE ---\");\nlet obj = { prop1: \"valor1\", prop2: \"valor2\" };\nconsole.log(\"Antes de delete:\", obj);\ndelete obj.prop1;\nconsole.log(\"Después de delete obj.prop1:\", obj);\n\n// ==========================================\n// 11. OPERADORES DE COALESCENCIA Y OPCIONALES\n// ==========================================\nconsole.log(\"\\n--- OPERADORES MODERNOS ---\");\nlet valor = null;\nconsole.log(\n  `null ?? \"predeterminado\": ${valor ?? \"predeterminado\"} (Nullish coalescing)`\n);\n\nlet usuario = { nombre: \"Ana\", direccion: { ciudad: \"Madrid\" } };\nconsole.log(`Optional chaining: ${usuario?.direccion?.ciudad}`);\nconsole.log(`Optional chaining (no existe): ${usuario?.telefono?.numero}`);\n\n// ==========================================\n// 12. OPERADOR SPREAD Y REST\n// ==========================================\nconsole.log(\"\\n--- OPERADORES SPREAD Y REST ---\");\nlet arr1 = [1, 2, 3];\nlet arr2 = [...arr1, 4, 5];\nconsole.log(`Spread en array: [1,2,3] -> [...arr, 4, 5] = [${arr2}]`);\n\nfunction sumar(...numeros) {\n  return numeros.reduce((acc, n) => acc + n, 0);\n}\nconsole.log(`Rest en función: sumar(1,2,3,4,5) = ${sumar(1, 2, 3, 4, 5)}`);\n\nconsole.log(\"\\n\\n=== ESTRUCTURAS DE CONTROL ===\\n\");\n\n// ==========================================\n// 1. CONDICIONALES\n// ==========================================\nconsole.log(\"--- CONDICIONALES ---\");\n\n// IF / ELSE IF / ELSE\nconsole.log(\"\\nIF / ELSE IF / ELSE:\");\nlet nota = 85;\nif (nota >= 90) {\n  console.log(`Nota ${nota}: Excelente`);\n} else if (nota >= 70) {\n  console.log(`Nota ${nota}: Aprobado`);\n} else {\n  console.log(`Nota ${nota}: Reprobado`);\n}\n\n// SWITCH\nconsole.log(\"\\nSWITCH:\");\nlet dia = 3;\nswitch (dia) {\n  case 1:\n    console.log(\"Lunes\");\n    break;\n  case 2:\n    console.log(\"Martes\");\n    break;\n  case 3:\n    console.log(\"Miércoles\");\n    break;\n  default:\n    console.log(\"Otro día\");\n}\n\n// ==========================================\n// 2. BUCLES (ITERATIVAS)\n// ==========================================\nconsole.log(\"\\n--- ESTRUCTURAS ITERATIVAS ---\");\n\n// FOR\nconsole.log(\"\\nFOR:\");\nfor (let i = 0; i < 5; i++) {\n  console.log(`Iteración ${i}`);\n}\n\n// WHILE\nconsole.log(\"\\nWHILE:\");\nlet contador = 0;\nwhile (contador < 3) {\n  console.log(`Contador: ${contador}`);\n  contador++;\n}\n\n// DO WHILE\nconsole.log(\"\\nDO WHILE:\");\nlet num2 = 0;\ndo {\n  console.log(`Número: ${num2}`);\n  num2++;\n} while (num2 < 3);\n\n// FOR...OF (itera sobre valores)\nconsole.log(\"\\nFOR...OF (valores):\");\nlet frutas = [\"manzana\", \"pera\", \"uva\"];\nfor (let fruta of frutas) {\n  console.log(`Fruta: ${fruta}`);\n}\n\n// FOR...IN (itera sobre propiedades/índices)\nconsole.log(\"\\nFOR...IN (propiedades):\");\nlet persona = { nombre: \"Carlos\", edad: 25, ciudad: \"Lima\" };\nfor (let propiedad in persona) {\n  console.log(`${propiedad}: ${persona[propiedad]}`);\n}\n\n// FOREACH (método de arrays)\nconsole.log(\"\\nFOREACH:\");\nlet numeros = [10, 20, 30];\nnumeros.forEach((num, index) => {\n  console.log(`Índice ${index}: ${num}`);\n});\n\n// ==========================================\n// 3. CONTROL DE FLUJO\n// ==========================================\nconsole.log(\"\\n--- CONTROL DE FLUJO ---\");\n\n// BREAK\nconsole.log(\"\\nBREAK:\");\nfor (let i = 0; i < 10; i++) {\n  if (i === 5) {\n    console.log(\"Break en i = 5\");\n    break;\n  }\n  console.log(`i = ${i}`);\n}\n\n// CONTINUE\nconsole.log(\"\\nCONTINUE:\");\nfor (let i = 0; i < 5; i++) {\n  if (i === 2) {\n    console.log(\"Continue salta i = 2\");\n    continue;\n  }\n  console.log(`i = ${i}`);\n}\n\n// LABEL (etiquetas)\nconsole.log(\"\\nLABEL:\");\nbucleExterno: for (let i = 0; i < 3; i++) {\n  for (let j = 0; j < 3; j++) {\n    if (i === 1 && j === 1) {\n      console.log(`Break externo en i=${i}, j=${j}`);\n      break bucleExterno;\n    }\n    console.log(`i=${i}, j=${j}`);\n  }\n}\n\n// ==========================================\n// 4. MANEJO DE EXCEPCIONES\n// ==========================================\nconsole.log(\"\\n--- MANEJO DE EXCEPCIONES ---\");\n\n// TRY / CATCH / FINALLY\nconsole.log(\"\\nTRY / CATCH / FINALLY:\");\ntry {\n  console.log(\"Intentando ejecutar código...\");\n  let resultado = 10 / 0;\n  console.log(`Resultado: ${resultado}`);\n\n  // Forzar un error\n  throw new Error(\"Error intencional\");\n} catch (error) {\n  console.log(`Error capturado: ${error.message}`);\n} finally {\n  console.log(\"Bloque finally siempre se ejecuta\");\n}\n\n// TRY / CATCH con tipos de error\nconsole.log(\"\\nDiferentes tipos de errores:\");\ntry {\n  JSON.parse(\"json inválido\");\n} catch (error) {\n  if (error instanceof SyntaxError) {\n    console.log(`SyntaxError: ${error.message}`);\n  }\n}\n\nconsole.log(\"\\n\\n=== DIFICULTAD EXTRA ===\\n\");\n\n/*\n * Números entre 10 y 55 (incluidos)\n * que sean PARES\n * y que NO sean 16\n * y que NO sean múltiplos de 3\n */\n\nconsole.log(\n  \"Números entre 10 y 55 (incluidos), pares, sin 16 y sin múltiplos de 3:\\n\"\n);\n\nfor (let i = 10; i <= 55; i++) {\n  // Verificar todas las condiciones\n  if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n    console.log(i);\n  }\n}\n\nconsole.log(\"\\n¡Reto completado! 🎉\");\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/nlarrea.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n// OPERADORES ARITMÉTICOS\n\nconsole.log(3 + 4);     // Suma -> 7\nconsole.log(3 - 4);     // Resta -> -1\nconsole.log(3 / 4);     // División -> 0.75\nconsole.log(3 * 4);     // Multiplicación -> 12\nconsole.log(3 % 4);     // Módulo -> 3\nconsole.log(3 ** 4);    // Potencia -> 81\n\n\n// OPERADORES LÓGICOS\n\nconsole.log(true && false);     // AND -> false\nconsole.log(true || false);     // OR -> true\nconsole.log(!true);             // NOT -> false\n\n\n// OPERADORES DE COMPARACIÓN\n\nconsole.log(3 > 4);     // Mayor que -> false\nconsole.log(3 < 4);     // Menor que -> true\nconsole.log(3 >= 4);    // Mayor o igual que -> false\nconsole.log(3 <= 4);    // Menor o igual que -> true\n\nconsole.log(3 == '3');  // Igual que -> true\nconsole.log(3 != '3');  // Diferente a -> false\nconsole.log(3 == 4);    // false\nconsole.log(3 != 4);    // true\n\nconsole.log(3 === '3'); // Igual que (estricta) -> false\nconsole.log(3 !== '3'); // Diferente a (estricta) -> true\n\n\n// OPERADORES DE ASIGNACIÓN\n\nlet assignSum = 7;\nassignSum += 3;                     // Suma y asignación\nconsole.log(assignSum);             // 10\n\nlet assignSubtract = 7;\nassignSubtract -= 4;                // Resta y asignación\nconsole.log(assignSubtract);        // 3\n\nlet assignMultiplication = 7;\nassignMultiplication *= 2;          // Multiplicación y asignación\nconsole.log(assignMultiplication);  // 14\n\nlet assignDivision = 7;\nassignDivision /= 2;                // División y asignación\nconsole.log(assignDivision);        // 3.5\n\nlet assignModule = 7;\nassignModule %= 2;                  // Módulo y asignación\nconsole.log(assignModule);          // 1\n\nlet assignPow = 7;\nassignPow **= 2;                    // Potencia y asignación\nconsole.log(assignPow);             // 49\n\n\n// OPERADORES DE PERTENENCIA\n\nlet arr = [0, 1, 2, 3, 4];\nconsole.log(3 in arr);      // true\nconsole.log(11 in arr);     // false\n\n\n// OPERADORES DE BITS\n\nconsole.log(3 & 4);         // AND -> 0\nconsole.log(3 | 4);         // OR -> 7\nconsole.log(3 ^ 4);         // XOR -> 7\nconsole.log(~3);            // NOT -> -4\nconsole.log(3 << 4);        // Desplazamiento a izquierda -> 48\nconsole.log(3 >> 4);        // Desplazamiento a derecha -> 0\n\n\n// ESTRUCTURA DE CONTROL: if - else if - else\n\nlet score = 8;\n\nif (score >= 5) {\n    console.log('You have passed the exam!');\n} else if (score < 5) {\n    console.log('You haven\\'t passed the exam...');\n} else {\n    console.log('The scores are not available yet.');\n}\n\n\n// ESTRUCTURA DE CONTROL: switch\n\nlet month = 6;\nlet monthName = '';\n\nswitch (month) {\n    case 1:\n        monthName = 'January';\n        break;\n    case 2:\n        monthName = 'February';\n        break;\n    case 3:\n        monthName = 'March';\n        break;\n    case 4:\n        monthName = 'April';\n        break;\n    case 5:\n        monthName = 'May';\n        break;\n    case 6:\n        monthName = 'June';\n        break;\n    case 7:\n        monthName = 'July';\n        break;\n    case 8:\n        monthName = 'August';\n        break;\n    case 9:\n        monthName = 'September';\n        break;\n    case 10:\n        monthName = 'October';\n        break;\n    case 11:\n        monthName = 'November';\n        break;\n    case 12:\n        monthName = 'December';\n        break;\n    default:\n        monthName = 'Not a valid month number';\n}\nconsole.log(`Month: ${monthName}`);    // Month: June\n\n\n// ESTRUCTURA DE CONTROL: for\n\nfor (let i = 0; i < 5; i++) {\n    console.log(i);\n}\n/* Se imprimen los siguientes números:\n    0\n    1\n    2\n    3\n    4\n*/\n\n\n// ESTRUCTURA DE CONTROL: for-in\n\nconst person = {\n    name: 'Naia',\n    username: 'nlarrea',\n    age: 25\n};\n\nfor (let key in person) {\n    // Se imprimen las claves:\n    console.log(key);\n\n    // Si quisiéramos imprimir los valores:\n    // console.log(person[key]);\n}\n/* Se imprimen los siguientes strings:\n    name\n    username\n    age\n*/\n\n\n// ESTRUCTURA DE CONTROL: for-of\n\nconst numArr = ['hola', true, 7, ['a', 'b', 'c']]\n\nfor (let item of numArr) {\n    console.log(item);\n}\n/* Se imprime:\n    'hola'\n    true\n    7\n    [ 'a', 'b', 'c' ]\n*/\n\n\n// ESTRUCTURA DE CONTROL: while\n\nlet i = 0;\nwhile (i < 5) {\n    console.log(i);\n    i++;\n}\n/* Se imprimen los siguientes números:\n    0\n    1\n    2\n    3\n    4\n*/\n\n\n// ESTRUCTURA DE CONTROL: do-while\n\nlet j = 'Not empty';\ndo {\n    console.log(j);\n} while (j === '');\n/* Se imprime el mensaje 'Not empty' 1 vez aunque no se cumpla la condición del\nwhile, porque siempre se va a ejecutar aunque sea una vez.\n\nCUIDADO: si la condición del while se cumpliera, sería un bucle infinito\n*/\n\n\n// ESTRUCTURA DE CONTROL: try-catch\n\ntry {\n    throw new Error('This is an error');\n    console.log('This is not printed');\n} catch (error) {\n    console.log(error);                     // [Error: This is an error]\n}\n\n\n// ESTRUCTURA DE CONTROL: try-catch-finally\ntry {\n    throw new Error('This is an error');\n    console.log('This is not printed');\n} catch (error) {\n    console.log(error);                     // [Error: This is an error]\n} finally {\n    console.log('This is always printed');  // This is always printed\n}\n\n\n// EJERCICIO EXTRA\n\n/* DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n */\n\nfor (let num = 10; num <= 55; num++) {\n    if (\n        num % 2 === 0 &&\n        num !== 16 &&\n        num % 3 !== 0\n    ) {\n        console.log(num);\n    }\n}\n/* Se imprimen los siguientes números:\n    10 \n    14 \n    20 \n    22 \n    26 \n    28 \n    32 \n    34 \n    38 \n    40 \n    44 \n    46 \n    50 \n    52\n*/"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/nwpablodeveloper.js",
    "content": "// #01 OPERADORES Y ESTRUCTURAS DE CONTROL\n\n(() => {\n    /*\n        OPERADOR DE ASIGNACIÓN\n\n        El operador de asignación va a evaluar todo lo que esta a la derecha\n        del signo = y se lo va a asignar a la variable que esta a su izquierda\n    */\n    console.warn(\"Operador de asignacion ( = )\");\n    let texto = \"Este contenido pá la variable\";\n    console.log(texto)\n    /*\n        OPERADOR DE CONCATENACIÓN\n\n        Utilizaremos el signo + para unir cadenas de textos u otras variables. \n    */\n\n    console.warn(\"Operador de concatenación ( + )\");\n    let nombre  = \"Pablo\";\n    let edad    = 35;\n    let frase   = `Me llamo ${ nombre } y tengo ${ edad } años`;\n    console.log( frase )\n\n\n    /* \n        OPERADORES ARITMETICOS\n\n        sumar\n        restar\n        multiplicar\n        dividir\n        resto de la división \n    */\n    console.warn(\"Operadores Aritmeticos ( + , - , *, /, % )\");\n    let a = 15;\n    let b = 7;\n    let suma            = a + b;\n    let resta           = a - b;\n    let multiplicacion  = a * b;\n    let potencia        = a ** b;\n    let division        = a / b;\n    let resto           = a % b;\n    console.log( \"suma:              15 + 7 = \" + suma );\n    console.log( \"resta:             15 - 7 = \" + resta );\n    console.log( \"multiplicacion:    15 * 7 = \" + multiplicacion );\n    console.log( \"multiplicacion:    15 ** 7 = \" + potencia );\n    console.log( \"division:          15 / 7 = \" + division );\n    console.log( \"resto:             15 % 7 = \" + resto );\n\n\n    /* \n        OPERADORES DE ASIGNACIÓN COMPUESTA\n\n        Se juntaron el operador de aritmetico con el de asignación. \n        Este atajo se puede realizar para otras operaciones además de la suma. \n        Es útil cuando la operación contiene como primer operando al \n        valor de la misma variable en la que se almacena el resultado.\n    */\n    console.warn(\"Operador de asignacion compuesta ( signo= )\");\n\n    a = 35, b = 6;\n    console.warn(\"a = 35; b = 6 \\n\");\n\n    console.log(\"a += b = \" + ( a += b ) );   // a = a + b  \n\n    a = 35; b = 6;\n    console.log(\"a -= b = \" + ( a -= b ) );   // a = a - b  \n\n    a = 35; b = 6;\n    console.log(\"a *= b = \" + ( a *= b ) );   // a = a + b  \n\n    a = 35; b = 6;\n    console.log(\"a /= b = \" + ( a /= b ) );   // a = a + b  \n\n    a = 35; b = 6;\n    console.log(\"a %= b = \" + ( a %= b ) );   // a = a % b  \n\n    a = 2; b = 8;\n    console.log(\"a **= b = \" + ( a **= b ) );   // a = a ** b  \n    /*\n        OPERADORES UNARIOS\n        \n    */\n    console.warn(\"Operadores unarios ( -, --, ++ )\");\n\n    // Operador unario, para cambiar el signo\n    console.log(\"Operador unario para cambiar el signo Ej: \\na = 35\");\n    a = 35;\n    b = -a;\n    console.log(\"b = -a \");\n    console.log(\"b = \"+ b + \"\\n\"); \n\n    // Suma pre-incremento\n    // 1ro hace el incremento al suendo operando y luego lo asigna a la variable\n    console.log(\"Suma unaria Ej: \\na = 35\");\n    a = 35;\n    b = ++a;\n    console.log(\"b = ++a \");\n    console.log(\"b = \"+ b + \"\\n\"); \n    console.log(\"a = \"+ a + \"\\n\"); \n\n\n    // Resta pre-decremento\n    // 1ro hace el decremento al sugundo operando y leugo lo asigna a la variable\n    console.log(\"Resta unaria Ej: \\na = 35\");\n    a = 35;\n    b = --a;\n    console.log(\"b = --a \");\n    console.log(\"b = \"+ b + \"\\n\");  \n    console.log(\"a = \"+ a + \"\\n\"); \n\n    // Operador post-incremento\n    // 1ro asigna el valor del sugundo operando a la variable y luego hace el incremento\n    console.log(\"post-incremento Ej: \\na = 35\");\n    a = 35;\n    b = a++;\n    console.log(\"b = a++ \");\n    console.log(\"b = \"+ b  );  \n    console.log(\"a = \"+ a + \"\\n\");  \n\n    // Operador post-decremento\n    // 1ro asigna el valor del sugundo operando a la variable y luego hace el decremento\n    console.log(\"post-decremento Ej: \\na = 35\");\n    a = 35;\n    b = a--;\n    console.log(\"b = a++ \");\n    console.log(\"b = \"+ b  );  \n    console.log(\"a = \"+ a );  \n\n    /* \n        OPERADORES RELACIONALES\n        Devuelven un valor booleano ( true o false ) a partir de una comparación de 2 variables.\n    */\n    console.warn(\"Operadores relacionales ( ==, !=, <, >, <=, >= ) \");\n    a = 38;             \n    b = 17;   \n    c = \"17\";          \n    let nombre2 = \"Pablo\";    \n    let nombre3 = \"Javier\";  \n    console.log(\"Invertir condición          \" + ( !true ));       \n    console.log(\"38 es igual a 37 ?          \" + ( a == b ));\n    console.log('\"17\" es igual a 17 ?        ' + ( c == b ));\n    console.log('\"17\" es igual a 17 ?        ' + ( c === b ));\n    console.log('\"17\" es igual a 17 ?        ' + ( c !== b ));\n    console.log(\"Pablo es igual a Javier?    \" + ( nombre2 == nombre3 ) );\n    console.log(\"38 es distinto a 17?        \" + ( a != b ) );\n    console.log(\"38 es menor a 17?           \" + ( a < b ) );\n    console.log(\"38 es mayor a 17?           \" + ( a > b ) );\n\n\n    /*\n        OPERADORES CONDICIONALES \n        Realiza la comparación entre datos booleanos y da \n        como resultado otro valor booleano\n    */\n    console.warn(\"Operadores condicionales ( ||, && )\");\n    a = 38;             \n    b = 17;             \n    nombre2 = \"Pablo\";    \n    nombre3 = \"Javier\";  \n    let ressultado;\n\n    // || ( OR ) Una de las 2 o mas evaluaciones tiene que ser verdadera Ej. 1\n    ressultado = (a == b) || ( nombre2 == nombre3 );\n    console.log(\"38 es igual a 17 ? o Pablo es igual a Javier ? \"+  ressultado);\n\n    // || ( OR ) Una de las 2 o mas evaluaciones tiene que ser verdadera Ej. 2\n    ressultado = (a == 38 ) || ( nombre2 == nombre3 );\n    console.log(\"38 es igual a 38 ? o Pablo es igual a Javier ? \"+  ressultado);\n\n    // && ( AND )Las 2 o mas evaluaciones tiene que ser verdadera Ej. 1\n    ressultado = (a == 38 ) && ( nombre2 == \"Pablo\" );\n    console.log(\"38 es igual a 38 ? y Pablo es igual a Pablo ? \"+  ressultado);\n\n    // && ( AND ) Las 2 o mas evaluaciones tiene que ser verdadera Ej. 2\n    ressultado = (a == 38 ) && ( nombre2 == nombre3 );\n    console.log(\"38 es igual a 38 ? y Pablo es igual a Javier ? \"+  ressultado);\n\n\n    /*\n        OPERADOR TERNARIO \n        Si el resultado a a evaluar es verdadero devuelve un resultado luego de\n        la primera expresión o caso contrario luego de la segunda expresión\n    */\n    console.warn(\"Operador ternario ( ?: )\");\n    edad = 17; \n    var resultado = ( edad >= 18 )? \"Es mayorcito\" : \"todavia no tiene preocupaciones\";\n    console.log(resultado);\n\n\n    /*\n        SENTENCIAS DE CONTROL\n        Las sentencias de control se utilizan para ejecutar ciertos bloques de \n        codigo respecto a un resultado anterior \n    */\n    // Sentencia de control If-Else\n    console.warn(\"Sentencia If-Else\");\n    \n    if ( edad >= 18 ) {\n        console.log(\"Es mayor de edad\");\n    } else {\n        console.log(\"Todavia te falta para ser mayorcito\");\n    }\n\n    // Sentencia de control Switch\n    console.warn(\"Sentencia de control switch\");\n    \n    let mensaje;\n    let numero = 8;\n    \n    // Ejemplo 1, si se cumple una condición se ejecuta cierto codigo, el breack le da finalización al Switch\n    switch ( numero ) {\n        case 1:\n            mensaje = \"Es uno\";\n            break;\n        case 2:\n            mensaje = \"Es dos\";\n            break;\n        case 5:\n            mensaje = \"Es cinco\";\n            break;\n        case 8:\n            mensaje = \"Es ocho\";\n            break;\n        default:\n            mensaje = \"No hay coincidencias\";\n            break;\n    }\n    console.log(\"Ejemplo 1: \" + mensaje);\n    \n    // Ejemplo 2, pueden se pueden convinar combinaciones de Case para ejecutar cierto codigo\n    numero = 13;\n    switch ( numero ) {\n        case 1:\n        case 3:\n        case 5:\n            mensaje = \"El numero puede ser uno, tres o cinco\";\n            break;\n        case 6:\n        case 7:\n        case 8:\n            mensaje = \"El numero puede ser seis, siete u ocho\";\n            break;\n        default:\n            mensaje = \"El numero no es ni uno, tres, cinco, seis, siete u ocho\";\n            break;\n    }\n    console.log(\"Ejemplo 2: \" + mensaje);\n\n\n    /*\n        SENTENCIA DE CONTROL CICLO While\n        El ciclo while 1ro va a evualer que la condición que sea verdadera \n        para ejecutar el codigo de su interior, lo va a hacer \n        todas las veces necesarias hasta que la condición cambie a false\n    */\n    console.warn(\"Sentencia de control While\");\n    \n    contador = 0;\n    while ( contador <= 4 ) {\n        console.log( \"Contador While: \" + contador );\n        contador++;\n    }\n\n    /*\n        SENTENCIA DE CONTROL DO-WHILE\n        1ro ejecuta el codigo dentro del bucle y luego verifica\n        si la condición booleana es true, en caso que sea false\n        se termina el bucle pero ya logramos almenos 1 vez\n        el bloque de codigo\n    */\n    console.warn(\"Sentencia Do-While\");\n\n    contador = 3;\n    do {\n        console.log(\"Contador Do-While: \" + contador);\n    } while ( contador > 5 ); \n\n\n    /*\n        SENENTENCIA DE CONTROL FOR\n        El ciclo for repite un codigo todas las veces que nosotros\n        se lo indiquemos, el mismo recibe 3 parametros que son\n        el 1ro, el contador\n        2do la condición booleana\n        3ro el incrementador del contador\n    */\n    console.warn(\"sentencia ciclo For\");\n    \n    // Ejemplo 1\n    for (contador = 0; contador <= 8; contador++) {\n        console.log(\"Ej. 1 - contador ciclo For: \" + contador);    \n    }\n    \n    console.log(\"\");\n    // Ejemplo 2\n    for (contador = 0; contador <= 9 ; contador += 2 ) {\n        console.log(\"Ej. 2 - contador ciclo For: \" + contador);    \n    }\n\n    /*\n        USO DE LA PALABRA CONTINUE\n        Cuando se encuentra la palabra CONTINUE dentro de un bucle\n        la misma finaliza esa vuelta de bucle y pasa a la que sigue \n    */\n    \n    console.log(\"\");\n    // Ejemplo 3\n    for (contador = 0; contador <= 9 ; contador += 2 ) {\n        if ( contador == 4 ) {\n            console.log(\"Saltear cuatro\");\n            continue;\n        }\n        console.log(\"Ej. 3 - contador ciclo For: \" + contador);    \n    }\n\n    /*\n        USO DE LA PALABRA BREK\n        Cuando se encuentra la palabra BREAK dentro de un bucle\n        la misma da por finalizado todo el bucle sin importar\n        si se cumple su condición final\n    */\n    \n    console.log(\"\");\n    // Ejemplo 4\n    for (contador = 0; contador <= 9 ; contador += 2 ) {\n        if ( contador == 6 ) {\n            console.log(\"finalizar bucle\");\n            break;\n        }\n        console.log(\"Ej. 4 - contador ciclo For: \" + contador);    \n    }\n\n    /*\n        SENTENCIA DE CONTROL TRYCATCH\n        Se utiliza para atrapar errores \n    */\n    console.warn(\"Sentencia de control TRYCATCH\");\n    try {\n        console.log(\"Si todo va bien entro por aquí\");\n    } catch (error) {\n        // EXPLOTO LA APP\n        console.log(\"Si hay errores entro por aquí\");\n        console.error(\"Causa del error\" , error)\n        // Por ejemplo conectar a un DB con una contraseña incorrecta\n    } finally {\n        // El finally es opcional\n        console.log(\"Me voy a ejecutar siempre que use el FINALLY\");\n    }\n\n\n    /*\n        DIFICULTAD EXTRA (opcional):\n        Crea un programa que imprima por consola todos los números comprendidos\n        entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3. \n    */\n    console.warn(\"Dificultad extra\");\n    let nro = 9;\n    while( nro < 55 ){\n        nro++\n        if( nro == 55 ) console.log(nro)\n        if( nro == 16 ) continue;\n        if( nro % 3 == 0 ) continue;\n        if( nro % 2 != 0 ) continue;\n        console.log(nro)\n    }\n\n})()\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/nxl22.js",
    "content": "// Operadores en JavaScript\n\n// Operadores aritméticos\nlet a = 10;\nlet b = 3;\nconsole.log(\"Operadores aritméticos:\");\nconsole.log(\"Suma:\", a + b);               // Suma: 10 + 3 = 13\nconsole.log(\"Resta:\", a - b);              // Resta: 10 - 3 = 7\nconsole.log(\"Multiplicación:\", a * b);      // Multiplicación: 10 * 3 = 30\nconsole.log(\"División:\", a / b);           // División: 10 / 3 = 3.333...\nconsole.log(\"Módulo:\", a % b);             // Módulo: 10 % 3 = 1\nconsole.log(\"Potencia:\", a ** b);          // Potencia: 10 ** 3 = 1000\n\n\n// Operadores de comparación\nlet x = 5;\nlet y = 10;\nconsole.log(\"Operadores de comparación:\");\nconsole.log(\"x == y?\", x == y);            // x == y? false\nconsole.log(\"x != y?\", x != y);            // x != y? true\nconsole.log(\"x > y?\", x > y);              // x > y? false\nconsole.log(\"x < y?\", x < y);              // x < y? true\nconsole.log(\"x >= y?\", x >= y);            // x >= y? false\nconsole.log(\"x <= y?\", x <= y);            // x <= y? true\n\n\n// Operadores lógicos\nconsole.log(\"Operadores lógicos:\");\n// AND lógico (&&)\nconsole.log(\"5 && 10?\", 5 && 10);       // 5 && 10? 10 (Ambos operandos son verdaderos, devuelve el segundo valor)\n// OR lógico (||)\nconsole.log(\"0 || 20?\", 0 || 20);       // 0 || 20? 20 (Uno de los operandos es verdadero, devuelve el primer valor verdadero)\n// NOT lógico (!)\nconsole.log(\"!5?\", !5);                 // !5? false (Niega un valor verdadero, devuelve false)\nconsole.log(\"!0?\", !0);                 // !0? true (Niega un valor falso, devuelve true)\n\n\n// Operadores de asignación\nlet z = 5;\nz += 3;  // Equivalente a z = z + 3\nconsole.log(\"Operadores de asignación:\");\nconsole.log(\"z:\", z);                      // z: 8\n\n// Operadores de identidad\nlet str1 = \"hello\";\nlet str2 = \"hello\";\nconsole.log(\"Operadores de identidad:\");\nconsole.log(\"str1 === str2?\", str1 === str2);   // str1 === str2? true\nconsole.log(\"str1 !== str2?\", str1 !== str2);   // str1 !== str2? false\n\n// Operadores de pertenencia\nlet fruits = [\"apple\", \"banana\", \"orange\"];\nconsole.log(\"Operadores de pertenencia:\");\nconsole.log(\"'banana' in fruits?\", 'banana' in fruits);       // 'banana' in fruits? true\nconsole.log(\"'grape' not in fruits?\", !('grape' in fruits));   // 'grape' not in fruits? true\n\n\n// Estructuras de control\n\n// Condicionales\nlet num = 15;\nif (num % 2 === 0) {\n    console.log(\"Es par.\");\n} else {\n    console.log(\"Es impar.\");\n}\n\n// Iterativas\nconsole.log(\"Bucle while:\");\nlet i = 10;\nwhile (i <= 40) {\n    if (i !== 16 && i % 3 !== 0) {\n        console.log(i);\n    }\n    i++;\n}\n\n// Manejo de error\nconsole.log(\"Manejo de error:\");\ntry {\n    let result = 10 / 0;\n} catch (error) {\n    console.log(\"Error: División por cero.\");\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/ocram1304.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n//Operadores en JS\n//Aritméticos: son los operadores básicos para realizar cualquier operación aritmética\n//Incremento\nconst incremento = 1 + 2;\n//Decremento\nconst decremento = 8 -1;\n//Multiplicación \nconst multiplicacion = 2 * 18;\n//Divición \nconst division = 9 / 3;\n//Substracción \nconst substracion = 10 % 2;\n//Potenciasión\nconst potenciacion = 3**2;\n//Operadores de asiganción: estos operadores asignan un valor en una operación de manera consistente\n//un uso muy frecuente de este tipo de opereadorees es de uttilizarlos como acumuladores\nlet x = 1;\n//asiganamiento de incremento\nx= x+3;\n//asiganamiento de decremento\nx = x-2;\n//asiganamiento de multiplicación\nx = x*2;\n//asiganamiento de divicón\nx = x/2;\n\n//Operadores lógicos: efectuán operaciones lógicas donde el resultado es una valor booleano (\"true\" o \"false\")\n//Estrita igualdad\nconst igualdad = 5 === 2 + 4;\n//Desigualdad\nconst desigualdad = 5 !== 2 + 3 ;\n//menor que\nconst menor = 10 < 6;\n//mayor que\nconst mayor = 10 > 20;\n//menor o igual que\nconst menorIgual = 3 <= 2;\n//MayorIgual\nconst mayourIgual = 5 >= 4;\n\n//Estructuras de control: permiten alterar e flujo de  control del programa\n\n//selectivas: permiten ejeecutar una sentencia o un bloque de sentencia dependiendo del resultado de una condición\n//if\nif(10>5){\n  console.log(\"10 es mayor a cinco\");\n}\n//if-else\nif(10>20){\n    console.log(\"10 es mayor a 20\");\n}\nelse{\n    console.log(\"10 no es mayor a 20\");\n}\n//switch: permite ejecutar una sentencia(s) en base al valor que una variable/expresión pueda tomar\nconst expre = \"Naranja\";\nswitch(expre){\n case \"azul\":\n    console.log(\"azul\");\n    break;\ncase \"rosa\":\n    console.log(\"rosa\");\n    break;\ncase \"verde\":\n    console.log(\"verde\");\n    break;\ndefault:\n    console.log(\"color no encotrado\");\n    break;\n\n}\n//repetitivas\nlet i = 1;\n//ciclo while: ejecuta un sentencia(s) mientras se cumpla una determinada condición\nwhile( i < 10){\n    console.log(i);\n    i+=1;\n}\n//do while: permite ejecutar al menos una vez el ciclo while\nlet j = 1;\ndo{\n    console.log(j);\n    j+=1;\n}while(j<10)\n//for: ejecuta un código un número predeterminado de veces\nfor(let k = 0; k<10;k++){\n    console.log(k);\n}\nconst colores= [\"verde\",\"naranja\", \"azul\", \"rojo\"];\n//for of loop: perimite iterar sonbre los valores de un objeto\nfor(const color of colores){\n    console.log(color);\n}\nconst coloresObj = {\n    verde: \"color verde\",\n    rojo: \"color rojo\",\n    azul: \"color azul\",\n    naranja: \"color naranja\"\n}\n//for in loop: permite iterar sobre las keys de un objeto en lugar de los valores.\nfor(const key in coloresObj){\n    console.log(key);\n}\n//De manejo de exepciones\n function dividir(dividendo, divisor) {\n    if (divisor === 0) {\n      \n      throw new Error(\"No se puede dividir por cero\");\n    }\n    return dividendo / divisor;\n  }\n  //Try-catch: señala un bloque de intrucciones a intenter y especifica una respuesta si se produce un expción.\ntry {\n \n    let resultado = dividir(10, 0); \n    console.log(\"El resultado es: \" + resultado); \n  } catch (error) {\n   \n    console.log(\"Ha ocurrido un error: \" + error.message);\n  }\n //Try-catch-finally\n try {\n \n    let resultado = dividir(10, 0); \n    console.log(\"El resultado es: \" + resultado); \n  } catch (error) {\n   \n    console.log(\"Ha ocurrido un error: \" + error.message);\n  }\n  finally{\n    console.log(\"Finalizando el proceso.\");\n  }\n  //Dificultat extra\n for(let z = 10; z <= 55; z++) {\n    if(z === 10 || z === 55 || (z % 2 === 0 && z !== 16 && z % 3 !== 0)) {\n        console.log(z);\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/oleojake.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n// OPERADORES ARITMÉTICOS\nlet suma = 1 + 1;\nlet resta = 2 - 1;\nlet multiplicación = 2 * 3;\nlet división = 6 / 2;\nlet residuo = 12 & 5; // En este  caso devolvería 2;\nlet exponenciacion = 2 ** 3 // 2 elevado a 3\n\n// OPERADORES ASIGNACIÓN\nlet x = 2; // Asicnación\nx += 1; // x = x + 1\nx -= 1; // x = x - 1\nx *= 1; // x = x * 1\nx /= 1; // x = x / 1\nx %= 2; // x = x % 2\nx **= 2; // x = x ** 2\n\n// OPERADORES DE COMPARACIÓN\nlet y = 3;\nconsole.log(y == '3'); // Comprueba igualdad de valores pero no el tipo. TRUE\nconsole.log(y != '4'); // Comprueba diferencia de valores pero no el tipo. TRUE\nconsole.log(y === 3); // Comprueba igualdad de valores y tipo. TRUE\nconsole.log(y !== 4); // Comprueba igualdad de valores y tipo. TRUE\nconsole.log(y > 1); // Comprueba si es mayor. TRUE\nconsole.log(y >=3 ) // Comprueba is es mayor o igual. TRUE\nconsole.log(y < 5); // Comprueba si es menor. TRUE\nconsole.log(y <=3 ) // Comprueba is es menor o igual. TRUE\n\n// OPERADORES DE CADENA\nlet nombreCompleto = \"Pablo\" + \" \" +\"Marzal\";\nconsole.log(nombreCompleto); // Pablo Marzal\n\n// OPERADORES LÓGICOS\n\n// Operador ternario (es el único con tres operandos) Si es TRUE, coge el primer valor, si es FALSE el segundo\nlet edad = 18\nlet edadStatus = edad >= 18 ? \"Mayor de edad\" : \"Menor de edad\";\nconsole.log(edadStatus); // Mayor de edad\n\n// AND &&\n// Devuelve expr1 si se puede convertir a false; de lo contrario, devuelve expr2. \n// Por lo tanto, cuando se usa con valores booleanos, && devuelve true\n// si ambos operandos son true; de lo contrario, devuelve false.\nconsole.log(true && true); // t && t devuelve true\nconsole.log(true && false); // t && f devuelve false\nconsole.log(false && true); // f && t devuelve false\nconsole.log(false && false); // f && f devuelve false\nconsole.log(false && 3 == 4); // f && f devuelve false\nconsole.log(\"Cat\" && \"Dog\"); // t && t devuelve Dog\nconsole.log(false && \"Cat\"); // f && t devuelve false\nconsole.log(\"Cat\" && false); // t && f devuelve false\n\n// OR ||\n// Devuelve expr1 si se puede convertir a true; de lo contrario, devuelve expr2.\n// Por lo tanto, cuando se usa con valores booleanos, || devuelve true\n// si alguno de los operandos es true; si ambos son falsos, devuelve false.\nconsole.log(true || true); // t || t devuelve true\nconsole.log(true || false); // t || f devuelve false\nconsole.log(false || true); // f || t devuelve false\nconsole.log(false || false); // f || f devuelve false\nconsole.log(false || 3 == 4); // f || f devuelve false\nconsole.log(\"Cat\" || \"Dog\"); // t || t devuelve Cat\nconsole.log(false || \"Cat\"); // f || t devuelve Cat\nconsole.log(\"Cat\" || false); // t || f devuelve Cat\n\n// NOT Lógico !\n//Devuelve false si su único operando se puede convertir a true;\n//de lo contrario, devuelve true.\nconsole.log(n1 = !true); // !t devuelve false\nconsole.log(n2 = !false); // !f devuelve true\nconsole.log(n3 = !\"Cat\"); // !t devuelve false\n\n// Operador Anulación Lógica\n// Para cambiar valor de una variable null o undefined\nlet myNull = null;\nmyNull ??= 10;\nconsole.log(myNull);\n\nlet myUndefined = undefined;\nmyUndefined ??= 20;\nconsole.log(myUndefined);\n\n// OPERADORES DE BITS \n// a & b\tDevuelve un uno en cada posición del bit para los que los bits correspondientes de ambos operandos son unos.\n// a | b\tDevuelve un cero en cada posición de bit para el cual los bits correspondientes de ambos operandos son ceros.\n// a ^ b\tDevuelve un cero en cada posición de bit para la que los bits correspondientes son iguales.\n// ~ a\tInvierte los bits de su operando.\n// a << b\tDesplaza a en representación binaria b bits hacia la izquierda, desplazándose en ceros desde la derecha.\n// a >> b\tDesplaza a en representación binaria b bits a la derecha, descartando los bits desplazados.\n// a >>> b\tDesplaza a en representación binaria b bits hacia la derecha, descartando los bits desplazados y desplazándose en ceros desde la izquierda.\n\nlet a = 9; // en bits: 1001\nlet b = 14; // en bits: 1110\n\nconsole.log(a & b); // 1000 (8)\nconsole.log(a | b); // 1111 (15)\nconsole.log(a ^ b); // 0111 (7)\n\nconsole.log(a << 1); // Devuelve 00010010 (18)\nconsole.log(a << 2); // Devuelve 00100100 (36)\nconsole.log(a << 3); // Devuelve 01001000 (72)\nconsole.log(a << 4); // Devuelve 10010000 (144)\n\n\n// ESTRUCTURAS DE CONTROL\n\n// IF/ELSE\nlet notaExamen = 7.5;\nif (notaExamen < 5){\n    console.log (\"He suspendido con un \" +notaExamen);\n} else if (notaExamen >= 5 && notaExamen < 7){\n    console.log (\"He aprobado un suficiente\");\n} else if (notaExamen >= 7 && notaExamen < 9){\n    console.log (\"He aprobado un notable\");\n} else{\n    console.log (\"He aprobado un sobresaliente\");\n}\n\n// SWITCH\nlet provincia = \"Alicante\"\nswitch (provincia) {\n    case 'Alicante':\n        console.log('Soy de la provincia de ' + provincia);\n        break;\n    case 'Valencia':\n        console.log('Soy de la provincia de ' + provincia);\n        break;\n    case 'Castellón':\n        console.log('Soy de la provincia de ' + provincia);\n        break;\n    default:\n        console.log('No soy de la Comunidad Valenciana');\n        break;\n}\n\n//FOR\nfor (var i = 0; i < 3; i++ ){\n    console.log (\"Este es el paso del bucle for número: \" + i)\n}\n\n//FOR of\nlet myArray = [\"Pablo\", \"Marzal\", 30];\nfor (const value of myArray) {\n    console.log(value);\n}\n\n// WHILE\n\nvar i = 0;\nwhile (i <= 3){\n    console.log (\"Paso bucle while número: \" + i);\n    i++;\n}\n\n// do WHILE\nvar i = 3;\ndo{\n    console.log (\"Esto es una cuenta atrás, tic, tac: \" + i);\n    i--;\n} while (i > 0);\nconsole.log(\"BOOM\");\n\n// MANEJO DE EXCEPCIONESS\ntry {\n    const PI = 3.14\n    PI = 0;\n} catch (e) {\n    console.log(e.message); //TypeError: Assignment to constant variable\n} finally{\n        console.log (\"Finalizando el try catch\");\n}       \n\n// EJERCICIO EXTRA\n//Crea un programa que imprima por consola todos los números comprendidos\n//entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\nfor (var i = 10; i <= 55; i++) {\n    if((i % 2 == 0) && (i != 16) && (i % 3 != 0)){\n        console.log (i);\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/omegatroy.js",
    "content": "/*\n * EJERCICIO:\n * -  Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n */\n\n\n// Operadores Aritméticos:\n\nlet numero1 = 23;\nlet numero2 = 21;\n\n// Operador de Asignación -> =\nnumero1 = numero2;\nconsole.log(numero1)// --> esto aria que numero1 sea 21\n\n\n// Operador de Asignación de adición -> +=\nnumero1 += numero2;\nconsole.log(numero1) // --> esto aria que adición sea igual ala suma de numero1 y numero2 o sea 42\n\n\n// Operador de Asignación de resta -> -=\nnumero1 -= numero2;\nconsole.log(numero1) // --> esto Equivale a: la resta de numero1: 42 y numero2: 21 o sea (42 - 21) = 21\n\n\n// Operador de Asignación de multiplicación -> *=\nnumero1 *= numero2;\nconsole.log(numero1) // --> esto Equivale a: la multiplicación de numero1: 21 y numero2: 21 o sea (21 * 21) = 441\n\n\n\n// Operador de Asignación de división -> /=\nnumero1 /= numero2;\nconsole.log(numero1) // --> esto Equivale a: la divisió de numero1: 441 y numero2: 21 o sea (441 / 21) = 21\n\n\n// Operador de Asignación de residuo -> %=\nnumero1 %= numero2;\nconsole.log(numero1) // --> esto Equivale a: el residuo de la división de su valor original (numero1) por numero2, que es 0.\nnumero1 = 2;\n\n\n// Operador de Asignación de exponenciación\nnumero1 **= numero2;\nconsole.log(numero1) // --> esto Equivale a: eleva numero1 a la potencia de un exponente numero2 que es 2097152\n\n\n//Asignación de desplazamiento a la izquierda -> <<=\nnumero1 <<= numero2;\nconsole.log(numero1) // --> esto Equivale a: Realiza un desplazamiento de bits a la izquierda en 'numero1' por numero2: 21 posiciones y asigna el resultado que es 0\nnumero1 = 23\n\n\n//Asignación de desplazamiento a la derecha -> >>=\nnumero1 >>= numero2;\nconsole.log(numero1) // --> esto Equivale a: Realiza un desplazamiento de bits a la derecha en 'numero1' por numero2: 21 posiciones y asigna el resultado que es 0\nnumero1 = -23\n\nnumero1 >>>= 1\nconsole.log(numero1) // --> esto Equivale a:  Realiza un desplazamiento de bits a la derecha sin signo en 'numero1' por 1 posición y asigna el resultado que es 2147483636\n\n\n// Operador de Asignación AND bit a bit -> &=\nnumero1 = 10 // Representación binaria: 1010\nnumero1 &= 5; // Representación binaria de 5: 0101\nconsole.log(numero1) // --> esto Equivale a: Resultado: 0 (1010 & 0101 = 0000)\n\n\n// Operador de Asignación XOR bit a bit -> ^=\nnumero1 = 10;  // Representación binaria: 1010\n// Realiza una operación XOR bit a bit con 6 y asigna el resultado\nnumero1 ^= 6;  // Representación binaria de 6: 0110\nconsole.log(numero1) // --> esto Equivale a: Resultado: 12 (1010 ^ 0110 = 1100)\n\n\n// Operdor de Asignación OR bit a bit -> |=\nlet numero = 10;  // Representación binaria: 1010\n// Realiza una operación OR bit a bit con 5 y asigna el resultado\nnumero |= 5;  // Representación binaria de 5: 0101\nconsole.log(numero) //  --> esto Equivale a: Resultado: 15 (1010 | 0101 = 1111)\n\n\n// Operador de Asignación AND lógico -> &&=\nlet variable1 = true;\nlet variable2 = false;\n// Si variable1 es verdadera, asigna el valor de variable2 a variable1\nvariable1 &&= variable2;\nconsole.log(variable1);  // Resultado: false\n\n// Operadores de Asignación OR lógico -> ||=\n// Si variable1 es falsa, asigna el valor de variable2 a variable1\nvariable1 ||= variable2;\nconsole.log(variable1);  // Resultado: true\n\n\n// Operador de Asignación de anulación lógica \nlet variable3 = null;\nlet variable4 = \"Valor de respaldo\";\n// Asigna el valor de variable2 a variable1 si variable1 es nulo o indefinido\nvariable1 = variable3 ?? variable4;\nconsole.log(variable1);  // Resultado: \"Valor de respaldo\"\n\n\n// Operadores de Comparación:\n\nlet num1 = 10;\nlet num2 = \"10\";\n\nlet igualdad = num1 == num2;          // Igualdad (compara valores)\nlet igualdadEstricta = num1 === num2; // Igualdad estricta (compara valores y tipos)\nlet desigualdad = num1 != num2;       // Desigualdad (compara valores)\nlet desigualdadEstricta = num1 !== num2; // Desigualdad estricta (compara valores y tipos)\nlet mayorQue = num1 > 5;              // Mayor que\nlet menorQue = num1 < 15;             // Menor que\n\nconsole.log(igualdad, igualdadEstricta, desigualdad, desigualdadEstricta, mayorQue, menorQue);\n\n// Operadores Lógicos:\nlet condicion1 = true;\nlet condicion2 = false;\n\nlet and = condicion1 && condicion2; // AND lógico\nlet or = condicion1 || condicion2;  // OR lógico\nlet not = !condicion1;              // NOT lógico\n\nconsole.log(and, or, not);\n\n// Operadores Ternarios:\nlet edad = 20;\n\nlet mensaje = (edad >= 18) ? \"Eres mayor de edad\" : \"Eres menor de edad\";\n\nconsole.log(mensaje)\n\n\n/*\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n*/\n\n\nlet nombre = 'omega';\n\nif(nombre !== 'omegatroy'){\n  console.log('no sos omega no podes pasar')\n}else if(nombre === 'troy'){\n  console.log('sos troy podes pasar')\n} else{\n  console.log('si sos omegatroy')\n}\n\nlet contador = 0;\n\nwhile(contador < 10){\n  console.log(contador)\n  contador++\n}\n\n\ndo {\n  console.log(contador);\n  contador++;\n} while (contador < 10);\n\n\nlet arreglo = [1, 2, 3];\n\nfor (let elemento in arreglo) {\n    console.log(elemento);  // Imprime los índices: 0, 1, 2\n}\n\nfor (let valor of arreglo) {\n    console.log(valor);  // Imprime los valores: 1, 2, 3\n}\n\nlet diaSemana = \"lunes\";\n\nswitch (diaSemana) {\n    case \"lunes\":\n        console.log(\"Comienzo de la semana\");\n        break;\n    case \"viernes\":\n        console.log(\"Fin de la semana\");\n        break;\n    default:\n        console.log(\"Día intermedio\");\n}\n\ntry {\n  // Intenta ejecutar este bloque de código\n  let resultado = 10 / 0;  // Esto lanzará una excepción de división por cero\n  console.log(resultado);  // Esta línea no se ejecutará si se produce una excepción\n} catch (error) {\n  // Maneja la excepción aquí\n  console.error(\"Se produjo un error:\", error.message);\n} finally {\n  // Este bloque siempre se ejecutará, incluso si hay una excepción\n  console.log(\"Bloque 'finally' ejecutado\");\n}\n\n// El flujo del programa continúa aquí después de manejar la excepción\nconsole.log(\"Programa continúa...\");\n\n\n/*\n\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n * \n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\n*/\n\n\n  for(let i = 10; i <= 55; i++){\n    if(i % 2 == 0 && i != 16 && i % 3 != 0){\n      console.log(`Numero: ${i}`)\n    }\n  }\n\n\n// es un poco largo lo se =)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/orlas135.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n/*Solución*/\n\n/*Operadores en JavaScript*/\n\n/*Operador de asignación: = */\n/*Operadores de incremento y decremento: ++ (incrementa en uno), -- (decrementa en uno)*/\n/*Operadores lógicos: !(negación), &&(AND), ||(OR)*/\n\n/*Operadores relacionales: \n  >(mayor que), \n  <(menor que), \n  >=(mayor o igual que), \n  <=(menor o igual que),\n  ==(igual que),\n  !=(diferente que)\n  ===(estrictamente igual en dato y en tipo de dato)\n  !==(estrictamente diferente que)\n*/\n\n/*Operadores aritméticos:\nOrden de prioridad: \n\n1. () Paréntesis\n2. ** Exponenciación\n3. *,/ Multiplicación y división\n4. +,- Suma y resta\n5. %,/ Residuo y cociente\n6. Relacionales\n7. Lógicos \n*/\n\nconst persona_uno = {\n  nombre: \"Camilo\",\n  apellido: \"Vélez\",\n  edad: 25,\n  saludar: function () {\n    console.log(\n      `Hola, mi nombre es ${this.nombre + \" \" + this.apellido}, y tengo ${this.edad} años.`\n    );\n  },\n};\n\nconsole.info('***************************')\npersona_uno.saludar();\n\nconsole.log();\n\nconsole.info('*************If/Else**************')\n\n\n/*Estructura de control If/Else y menor que*/\nconst esMenor = function () {\n  if (persona_uno.edad < 18) {\n    return console.log(`Esta persona es menor de edad`)\n  } else {\n    return console.log(`Esta persona es mayor de edad`)\n  }\n}\nesMenor();\n\nconsole.info('*************Operador Ternario**************')\n/*Operador ternario*/\n\npersona_uno.edad >= 18 \n? console.log(`${persona_uno.nombre} sí es mayor de edad`) \n: console.log(`${persona_uno.nombre} no es mayor de edad`)\n\n\nconsole.log(`/**Utilizando operadores aritméticos**/`)\n/*Potenciación*/\nlet numero_uno = 25;\nlet numero_dos = 5;\n\n/*Operaciones con operadores aritméticos*/\n\n/* Suma y resta */\nconsole.log(numero_uno + numero_dos)\nconsole.log(numero_uno - numero_dos)\n\n/*Multiplicación - División - Residuo/módulo*/\nconsole.log(numero_uno * numero_dos)\nconsole.log(numero_uno / numero_dos)\nconsole.log(numero_uno % numero_dos)\n\n/*Potenciación*/\nconsole.log(numero_uno ** numero_dos)\n\n/*Operaciones matematicas ordenadas por prioridad*/\nconsole.log(((numero_dos*numero_uno) + numero_uno + (numero_dos ** numero_uno) / 5 + (numero_dos + 3)) % 5)\n\n\nconsole.log(`/*********Utilizando operador de negación**********/`)\nlet esMujer = !true\nlet hombre= false\nconsole.log(esMujer === hombre);\nconsole.log(esMujer == hombre);\n\nconsole.log(`/*******Ejercicio de dificultad extra********/`)\n\nlet dificultadExtra = 10\nwhile (dificultadExtra <= 55) {\n  if (dificultadExtra % 2 == 0 && dificultadExtra!= 16){\n    if(dificultadExtra % 3 != 0) {\n      console.log(`Número: ${dificultadExtra}`)\n    }\n  }\n\n  dificultadExtra++;\n}\n\nconsole.log(`/*****Utilizando do/while*******/`)\ndo {\n  console.log(`Mi edad es de ${persona_uno.edad}`)\n  persona_uno.edad++\n}while(persona_uno.edad < 30);\n\nconsole.log(`/**********Utilizando FOR*********/`);\n\nfor (i = 0; i <= 20; i++) {\n  console.log(`Número: ${i}. Residuo 4: ${i%4}`)\n}\n\nconsole.log(`/**********Utilizando estructura Switch/Case************/`)\n\ndia_elegido = `juernes`\n\nswitch(dia_elegido) {\n  case `lunes`:\n    console.info `NOOOOOOOOOOOOOOOOOOOOOOOOO`\n    break;\n  case `martes`:\n    console.log `¿Apenas es martes?`\n    break;\n  case `miercoles`:\n    console.log `Ya casi es viernes`\n    break;\n  case `jueves`:\n    console.log `Ya es juernes!!!!`\n    break;\n  case `viernes`:\n    console.log `HOY ES VIERNEEEEEEEEEEEEEEES`\n    break;\n  case `sábado`:\n    console.log `Hoy me emborracho`\n    break;\n  case `domingo`:\n    console.log `Se acabó el fin de semana :(`\n    break;\n  default:\n    console.log `Qué día es hoy`\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/othamae.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n\n// Arithmetic\nconst num1 = 4\nconst num2 = 2\nconst add = num1 + num2\nconst subtraction = num1 - num2\nconst multiplication = num1 * num2\nconst division = num1 / num2\nconst modulo = num1 % num2\nconst exponentiation = num1 ** num2\n\nconsole.log(`ADD (+): ${num1} + ${num2} = ${add}`)\nconsole.log(`SUBTRACTION (-): ${num1} - ${num2} = ${subtraction}`)\nconsole.log(`MULTIPLICATION (*): ${num1} * ${num2} = ${multiplication}`)\nconsole.log(`DIVISION (/): ${num1} / ${num2} = ${division}`)\nconsole.log(`MODULO (%): ${num1} % ${num2} = ${modulo}`)\nconsole.log(`EXPONENTIATION (**): ${num1} ** ${num2} = ${exponentiation}`)\n\n// Logical\nconst and = true && 1>0 // true as both are true\nconst or = true || 1<0 // true as one is true\nconst not = !1>0 // false as 1>0 with ! is false\nlet andAsigment = 1 \nandAsigment &&= 2 // evaluates the right operand and assigns to the left if the left operand is truthy\nlet orAsigment = 1\norAsigment ||= 2 // evaluates the right operand and assigns to the left if the left operand is falsy\n\nconsole.log(`AND (&&): true && 1>0 = ${and}`)\nconsole.log(`OR (||): true || 1<0 = ${or}`)\nconsole.log(`NOT (!): !1>0  = ${not}`)\nconsole.log(`AND ASSIGNMENT (&&=): andAsigment &&= 2 => ${andAsigment}`)\nconsole.log(`OR ASSIGNMENT (||=): orAsigment ||= 2 => ${orAsigment}`)\n\n\n//Comparation\nconst equal = 1 == 1 // true as both are equal\nconst notEqual = 1 != 1 // false as both are equal\nconst greater = 1 > 0 // true as 1>0\nconst greaterOrEqual = 1 >= 0 // true as 1>=0\nconst less = 1 < 0 // false as 1<0\nconst lessOrEqual = 1 <= 0 // false as 1<=0\n\nconsole.log(`EQUAL (==): 1 == 1 = ${equal}`)\nconsole.log(`NOTEQUAL (!=): 1 != 1 = ${notEqual}`)\nconsole.log(`GREATER THAN (>): 1 > 0 = ${greater}`)+\nconsole.log(`GREATER THAN OR EQUAL (>=): 1 >= 0 = ${greaterOrEqual}`)\nconsole.log(`LESS THAN (<): 1 < 0 = ${less}`)\nconsole.log(`LESS THAN OR EQUAL (<=): 1 <= 0 = ${lessOrEqual}`)\n\n\n// Assignment\nlet number = 5\nconsole.log(`ASSIGNMENT (=): number = 5 => ${number}`)\nnumber ++ // increment by one\nconsole.log(`INCREMENT (++): number ++ => ${number}`)\nnumber -- // decrement by one\nconsole.log(`DECREMENT (--): number -- => ${number}`)\nnumber +=3 // increment by three\nconsole.log(`INCREMENT ASSIGNMENT (+=): number  += 3 => ${number}`)\nnumber -=3 // decrement by three\nconsole.log(`SUBTRACTION ASSIGNMENT (-=): number -= 3 => ${number}`)\nnumber *= 2 // multiply by two\nconsole.log(`MULTIPLICATION ASSIGNMENT (*=): number *= 2 => ${number}`)\nnumber /= 2 // divide by two\nconsole.log(`DIVIDE ASSIGNMENT (/=): number /= 2 => ${number}`)\nnumber **= 2 // exponentiation by two\nconsole.log(`EXPONENTIATION ASSIGNMENT (**=): number **= 2 => ${number}`)\nnumber %= 2 // modulo two\nconsole.log(`MODULO ASSIGNMENT (%=): number %= 2 => ${number}`)\n\n\n// Pertenence\nconst IN = 1 in [1,2,3] // true as 1 is in the array\nconst notPertenence = 4 in [1,2,3] // false as 4 is not in the array\n\nconsole.log(`IN (in): 1 in [1,2,3] = ${IN}`)\nconsole.log(`NOT PERTENENCE (!in): 4 in [1,2,3] = ${notPertenence}`)\n\n// Bitwise\nconst XOR = 5 ^ 3 // 6 --> returns a number or BigInt whose binary representation has a 1 in each bit position for which the corresponding bits of either but not both operands are 1\nconsole.log(`XOR (^): 5 ^ 3 = ${XOR}`)\nlet bit = 5\nconsole.log(`ASSIGNATION: bit = 5 => ${bit}`)\nbit ^=3 // performs bitwise XOR on the two operands and assigns the result to the left operand. \nconsole.log(`BITWISE XOR ASSIGNMENT (^=): bit ^=3 => ${bit}`)\n\n// Conditions\n// If-Else\nconst age = 18\n\nif(age >= 18){\n    console.log(\"You can vote\")\n} else {\n    console.log(\"You can't vote\")\n}\n\n// Switch\nconst color = 'green'\n\nswitch(color){\n    case 'red':\n        console.log(\"Color is red\");\n        break\n    case 'blue':\n        console.log(\"Color is blue\");\n        break\n    default:\n        console.log(`Color is ${color}`);\n        break\n}\n\n// Iteration\n// For\nlet numbersFrom0to9 =''\nfor(let i = 0; i < 10; i++){ \n  numbersFrom0to9 += i\n}\nconsole.log(`FOR LOOP: numbersFrom0to9 = ${numbersFrom0to9}`) \n\n// ForEach\nconst arrayNumbers = [1,2,3,4,5]\narrayNumbers.forEach(number => console.log(`FOREACH number in arrayNumbers: ${number}`))\n\n// For...of\nfor (let number of arrayNumbers){\n    console.log(`FOR...OF number in arrayNumbers: ${number}`)\n}\n\n// For...in\nconst object = { a: 1, b:2, c:3, d:4, e:5 }\nfor (let key in object){\n    console.log(`FOR...IN key in object: ${key}, value: ${object[key]}`)\n}\n\n// While\nlet n = 0\nwhile (n< 5){\n    console.log(`WHILE n < 5: n = ${n}`)\n    n++\n}\n\n// Do...While\nlet m = 0\ndo {\n    m++\n    console.log(`DO WHILE m < 5: m = ${m}`)\n} while (m < 5)\n\n// Try...catch\nconst CONSTANT = 'a'\ntry{\n    CONSTANT = 'b'\n} catch(error){\n    console.log(`ERROR in TRY...CATCH: ${error}`)\n}\n\n\n// EXTRA TASK:\nfunction printNumbersFrom10to55(){\n    let n = 10\n    console.log('Even numbers between 10 and 55 inclusive, excluding 16 and multiples of 3:')\n    while(n <= 55){\n        (n!== 16 && n%3!==0 && n%2===0) && console.log(n)\n        n++       \n    }\n}\n\nprintNumbersFrom10to55()"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/ovjohn.js",
    "content": "//Operadores en Javascript\n\n//Operadores de asignación\n    //Asignacion\n    console.log('//Operadores de asignación');\n   const x = 'asignacion';\n   console.log(\"Resultado de la asignacionde. Operacion -> (x = 'asignacion'):\"+ x);\n    // Asignacion de Adicion\n    let y = 0;\n    y += 2;\n    console.log(\"Resultado de la asignacionde de adicion, Operqacion -> (y += 2):\"+ y);\n    //Asignacion de resta\n    let e = 0;\n    e -= 4;\n    console.log('Resultado de la asignacionde Resto. Operacion -> (e -= 4):'+ e);\n\n//Operadores con Desestructuración\n//Sin desestructuracion\n let comida = ['pera','manzana','azucar'];\n //Con desestructuracion\n let [pera,manzana,azucar] = comida;\n \n console.log(`let comida = ['pera','manzana','azucar']; \n    //Sin desestructuracion\n    La comida[0]=${comida[0]}\n    La comida[1]=${comida[1]}\n    La modida[2]=${comida[2]}\n\n    //Con desestructuracion\n    let [pera,manzana,azucar] = comida;\n    La comida en la posicion 0 es: ${pera};\n    La comida en la posicion 1 es: ${manzana};\n `);\n\n //Operadores de comparación\n let var1 = 1;\n let var2 = 3;\n console.log('Operadores de comparación');\n \n console.log(` \n let var1 = 1;\n let var2 = 3;\n var1 == 1:${var1 == 1};\n var2 != 3:${var2 != 3};\n var1 >= 2:${var1 >= 2};\n var1 <= 2:${var1 <= 2};\n `)\n \n\n\n//Operadores aritmeticos\nconsole.log('Operadores aritmeticos');\nlet suma = 2 + 4;\nconsole.log(`La suma  de 2 + 4 es:${suma}`);\n\n let resta= 2-1;\nconsole.log(`La resta de 2-1 es:${resta}`);\n\nlet multiplicacion = 2*5;\nconsole.log(`La multiplicacion de 2*5 es:${multiplicacion}`);\n\nlet divicion = 10 / 2;\nconsole.log(`La divicion de 10/2 es:${divicion}`);\n\nlet residuo = 12 / 5;\nconsole.log(`El residuo de 12/5 es:${residuo}`);\n\n\n//Operadores lógicos\nconsole.log('Operadores lógicos');\nlet num1 = true;\nlet num2 = false;\nconsole.log(`\nlet num1 = true;\nlet num2 = false;\n console.log(num1 && num2); // Se espera un false ->: ${(num1 && num2)}\n console.log(num1 || num2);// Se espera un true ->: ${(num1 || num2)} \n console.log(!num1);// Se espera un false ->: ${(!num1)}\n `);\n\n //Estructura de Control\n //Condicional if\n console.log(\"//Estructura de Control\");\n console.log(\" //Condicional if\");\n let auto = 'fiat'\nif( auto == 'ford'){\n    console.log(`Mi aunto es un:${auto}`);\n}else if(auto == 'fiat'){\n    console.log(`Mi aunto es un:${auto}`);\n}else{\n    console.log('No es ni uno u otro');\n}\n//operador ternario\nconsole.log(\"//operador ternario\");\nauto === \"ford\"? console.log(`Mi auto es un: ${auto}`): console.log(\"Tu auto no es Ford\");\n\n//switch\nconsole.log(\"//Switch case\");\nlet piso = 5;\nconsole.log(\"Quiero ir a mi apartamento que esta en el piso:\"+piso);\n\nswitch (piso){\n  case 10:\n    calificacion = \"PenHouse\";\n    break;\n    case 8:\n    calificacion = \"No es tu piso\";\n    break;\n  case 7:\n  case 5:\n    calificacion = \"Llegamos a tu Piso:\"+piso+\", por favor bajase aquí\";\n    break;\n  case 5:\n  case 4:\n  case 3:\n  case 2:\n  case 1:\n  case 0:\n    calificacion = \"Pisos bajos\";\n    break;\n  default:\n    // Cualquier otro caso\n    calificacion = \"Emergencia se ha ido la electricidad\";\n    break;\n}\nconsole.log(calificacion);\n\n//Esctructura de Control\n//While\nconsole.log(\"//Esctructura de Control - While\");\nlet numero = 0;\nwhile(numero <= 4){\n  console.log(\"El numero actual es:\"+numero);\n  numero +=1;\n}\n//Do While\nconsole.log(\"Do-While\");\ndo{\n  console.log(\"Me ejecute con el Do While aun y que la condicion no sea True\")\n  numero += 2;\n}\nwhile(numero < 0);\n\n//For\nconsole.log(\"Bucle For\")\nfor(let i = 20;i > 9; --i){\n  console.log(`Soy for en:${i}`);\n}\n\nfor (let i = 0; i < 11; i++) {\n  if (i == 5) {\n    continue; // Para saltar en esta condicion\n  }\n  console.log(\"Valor de i:\", i);\n}\n\n\n//Dificultad Extra\nconsole.log(\"Dificultad Extra\");\nfor (let a = 55; a >= 10; a--){\n  if(a%2 == 0 && a != 16 && a%3 !=0){\n    console.log(a);\n  }  \n}\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/pakiuh.js",
    "content": "// Operadores de asignación\r\nlet x = 10; // asignación\r\nx += 5; // suma y asignación\r\nx -= 2; // resta y asignación\r\nx *= 3; // multiplicación y asignación\r\nx /= 2; // división y asignación\r\nx %= 3; // módulo y asignación\r\n\r\n// Operadores aritméticos\r\nlet y = x + 5; // suma\r\nlet z = x - y; // resta\r\nlet a = x * y; // multiplicación\r\nlet b = x / y; // división\r\nlet c = x % y; // módulo\r\nlet d = x++; // incremento\r\nlet e = y--; // decremento\r\n\r\n// Operadores de comparación\r\nlet isEqual = x == y; // igual a\r\nlet isNotEqual = x != y; // no igual a\r\nlet isStrictEqual = x === y; // estrictamente igual a\r\nlet isStrictNotEqual = x !== y; // estrictamente no igual a\r\nlet isGreaterThan = x > y; // mayor que\r\nlet isLessThan = x < y; // menor que\r\nlet isGreaterThanOrEqual = x >= y; // mayor o igual que\r\nlet isLessThanOrEqual = x <= y; // menor o igual que\r\n\r\n// Operadores lógicos\r\nlet and = x > 5 && y < 10; // y lógico\r\nlet or = x > 5 || y < 10; // o lógico\r\nlet not = !(x == y); // no lógico\r\n\r\n// Operador ternario\r\nlet result = x > y ? \"x es mayor que y\" : \"x no es mayor que y\";\r\n\r\n// Operador typeof\r\nlet type = typeof x; // devuelve el tipo de una variable\r\n\r\n\r\n// Estructuras de control\r\n// Declaraciones condicionales\r\nlet xx = 10;\r\nif (xx > 5) {\r\n    console.log(\"xx es mayor que 5\");\r\n} else if (xx < 5) {\r\n    console.log(\"xx es menor que 5\");\r\n} else {\r\n    console.log(\"xx es igual a 5\");\r\n}\r\n\r\n// Declaración switch\r\nswitch (x) {\r\n    case 5:\r\n        console.log(\"x es 5\");\r\n        break;\r\n    case 10:\r\n        console.log(\"x es 10\");\r\n        break;\r\n    default:\r\n        console.log(\"x no es ni 5 ni 10\");\r\n        break;\r\n}\r\n\r\n// Bucle for\r\nfor (let i = 0; i < 5; i++) {\r\n    console.log(\"El valor de i es: \" + i);\r\n}\r\n\r\n// Bucle while\r\nlet i = 0;\r\nwhile (i < 5) {\r\n    console.log(\"El valor de i es: \" + i);\r\n    i++;\r\n}\r\n\r\n// Bucle do while\r\ni = 0;\r\ndo {\r\n    console.log(\"El valor de i es: \" + i);\r\n    i++;\r\n} while (i < 5);\r\n\r\n// Manejo de excepciones\r\ntry {\r\n    let y = x * z; // z no está definido, por lo que se lanzará una excepción\r\n} catch (error) {\r\n    console.log(\"Ha ocurrido un error: \" + error.message);\r\n} finally {\r\n    console.log(\"Este bloque se ejecuta independientemente de si se produjo una excepción o no\");\r\n}\r\n\r\n// Dificultad Extra\r\n\r\nfor (let i = 10; i <= 55; i++) {\r\n    if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\r\n        console.log(i);\r\n    }\r\n}\r\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/parababire.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n//Operador asignación (=)\nlet x;\nx = 8;\nconsole.log(x);\n\nlet y = 2;\nx += y;//Asignación de suma\nconsole.log(x);\n\nlet z = 4;\nx -= z;//Asignación de resta\nconsole.log(x);\nconsole.log(x *= y);//Asignación de multiplicación\nconsole.log(x /= y);//Asignación de división\n/*Existen otros operadores de asignación, pero no quiero extender el reto*/\n\n//Operadores aritméticos binarios (+, -, *, /, %) y unarios (++, --)\n\nlet num1 = 10;\nlet num2 = 20;\n\nlet suma = num1 + num2;\nconsole.log(suma);\n\nlet saludo = \"Hola\";\nlet persona = \"Ángel\"\nconsole.log(saludo + \", \" + persona);//El operador + puede unir cadenas\n\nlet num3 = \"33\";\nconsole.log(+num3);//El operador + puede convertir cadenas en números\n\nlet resta = num1 - num2;\nconsole.log(resta);\nconsole.log(-resta);//El operador unario - devuelve la negación de su operando\n\nlet mult = num1 * num2;\nconsole.log(mult);\n\nlet division = num1 / num2;\nconsole.log(division);\n\nlet resto = 10 % 2;\nconsole.log(resto);\n\nlet base = 2;\nlet exp = 4;\nlet pot = base ** exp;\nconsole.log(pot);\n\nmult++;\nconsole.log(mult);\n\ndivision--,\nconsole.log(division);\n\n//Operadores lógicos && (AND), || (OR), ! (NOT) y ?? (Nullish Coalescing)\n\nlet edad = 44;\nlet sexo = \"masculino\";\nconsole.log(edad == 44 && sexo == \"masculino\");\nconsole.log(edad == 45 || sexo == \"masculino\");\n\nlet futuroDev = false;\nconsole.log(!futuroDev);\n\nlet numRetos2024;\nlet retosActuales = 2;\nconsole.log(numRetos2024 ?? retosActuales);\n\n//Operadores de comparación (>, <, >=, <=, !=, ==, ===)\n\nconsole.log(num1 < num2);\nconsole.log(num1 > num2);\n\nlet edadMinima = 18;\nconsole.log(edad >= edadMinima);\n\nlet edadNiño = 10;\nconsole.log(edadNiño <= edadMinima);\n\nconsole.log(edad != edadNiño);\n\nconsole.log(edad == \"44\");\nconsole.log(edad === \"44\");\nconsole.log(edad !== \"44\");\n\n//Operadores de bits\n\n/*El operando se convierte a 32 bits antes de la operación de bits*/\n\nlet a = 9; //En bits 00000000000000000000000000001001\nlet b = 12;//En bits 00000000000000000000000000001100\nlet c = -5;//En bits 11111111111111111111111111111011\nlet d = 5; //En bits 00000000000000000000000000000101\n\nconsole.log(a & b);//Devuelve 1 donde los bits de cada operando es 1. De lo contrario devuelve 0.\nconsole.log(a | b);//Devuelve 0 donde los bits de cada operando es 0. De lo contrario devuelve 1.\nconsole.log(a ^ b);//Devuelve 0 donde los bits de cada operando son iguales. De lo contrario devuelve 1.\nconsole.log(~ a);/*Invierte los bits de su operando. El bit más a la izquierda define si el número retornado es negativo o positivo*/\nconsole.log(a << 1);//Agrega un 0 a la derecha del ultimo bit del operando.\nconsole.log(c >> 1);/*Empuja una copia del bit más a la izquierda, los digitos se mueven a la derecha y el ultimo bit (a la derecha) se pierde*/\nconsole.log(d >>> 1);//Un o más 0 bits es empujado a la izquierda y el bit más a la derecha se pierde.\n\n//Estructuras de control\n\n/*Condicionales*/\n\nlet año = prompt(\"Ingresa año de nacimiento?\", \"Ejm: 1980\");\n\nif (año >= 1965 && año <= 1981) {\n  console.log(\"Perteneces a la generación X\");\n}\n\nif (año >= 1965 && año <= 1981) {\n  console.log(\"Perteneces a la generación X\");\n} else {\n  console.log(\"No perteneces a la generación X\");\n}\n\n//Concatenar if else\n\nif (año >= 1946 && año <= 1964) {\n  console.log(\"Perteneces a la generación Boomers\");\n} else if (año >= 1965 && año <= 1981) {\n  console.log(\"Perteneces a la generación X\");\n} else if (año >= 1980 && año <= 1994) {\n  console.log(\"Perteneces a la generación Millennials\");\n} else if (año >= 1995 && año <= 2009) {\n  console.log(\"Perteneces a la generación Z\");\n} else if (año >= 2010) {\n  console.log(\"Perteneces a la generación Alfa\");\n} else {\n  console.log(\"Fecha invalida\");\n}\n\n//Switch\n\nconst mascota = prompt(\"Ingresa un tipo de animal\", \"perro\");\n\nswitch (mascota) {\n  case \"lagarto\":\n    console.log(\"Tengo un lagarto\");\n    break;\n  case \"perro\":\n    console.log(\"Tengo un perro\");\n    break;\n  case \"gato\":\n    console.log(\"Tengo un gato\");\n    break;\n  case \"serpiente\":\n    console.log(\"Tengo una serpiente\");\n    break;\n  case \"loro\":\n    console.log(\"Tengo un loro\");\n    break;\n  default:\n    console.log(\"No tengo mascota\");\n    break;\n}\n\n//Iteraciones\n\n/*While*/\nwhile (a > 0) {\n  console.log(a);\n  a--;\n}\n\n/*Do While*/\nlet password;\n\ndo {\n    password = prompt(\"Password\");\n} while (password != \"1234\");\n\nconsole.log(\"Bienvenido\");\n\n/*For*/\nlet arr = [1, 2, 3, 4, 5, 6];\n\nfor (let i = 0; i < arr.length; i++) {\n  console.log(arr[i]);\n}\n\n//Excepciones\n\nasync function sumarNumeros(a, b) {\n  if (typeof a != \"number\" || typeof b != \"number\") {\n      throw new Error(\"Ambos argumentos deben ser números\");\n  }\n  return a + b;\n}\nasync function manejarErrors() {\n  try {\n      let resultado = await sumarNumeros(\"1\", 2);\n      console.log(resultado);\n  } catch (error) {\n      console.error(error.message);\n  }\n}\nmanejarErrors();\n\n//Dificultad extra\n\nlet i = 10;\ndo {\n  if (i !== 16 && i % 2 === 0 && i % 3 !== 0) {\n    console.log(i);\n  } \n  i++;\n}\nwhile (i <= 55);"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/pedamoci.js",
    "content": "// --------------------- OPERADORES ---------------------\n  // DE ASIGNACION\n    let resultAsignacion\n    let y = 5\n    resultAsignacion = y \n    console.log(resultAsignacion)\n    resultAsignacion += y // de adición\n    console.log(resultAsignacion)\n    resultAsignacion -= y // de resta\n    console.log(resultAsignacion)\n    resultAsignacion *= y // de multiplicación\n    console.log(resultAsignacion)\n    resultAsignacion /= y // de división \n    console.log(resultAsignacion)\n    resultAsignacion %= y // de residuo ej: x = 10  y = 3 --> 10/3 = 3 * 3 + 1 --> residuo = 1 --> x = 1\n    console.log(resultAsignacion)\n    resultAsignacion **= y // de exponenciación\n    console.log(resultAsignacion)\n    resultAsignacion <<= y // desplazamiento a la izquierda ej: x = 5 (0000 0101)  y = 2 --> 0001 0100 --> x = 20\n    console.log(resultAsignacion)\n    resultAsignacion >>= y // desplazamiento a la derecha ej: x = 20 (0001 0100)  y = 2 --> 0000 0101 --> x = 5\n    console.log(resultAsignacion)\n    resultAsignacion >>>= y // desplazamiento a la derecha sin signo\n    console.log(resultAsignacion)\n    resultAsignacion &= y // AND bit a bit ej: x = 5 (0000 0101)  y = 3 (0000 0011) --> 0000 0001 --> x = 1\n    console.log(resultAsignacion)\n    resultAsignacion ^= y // XOR bit a bit ej: x = 5 (0000 0101)  y = 3 (0000 0011) --> 0000 0110 --> x = 6\n    console.log(resultAsignacion)\n    resultAsignacion |= y // OR bit a bit ej: x = 5 (0000 0101)  y = 3 (0000 0011) --> 0000 0111 --> x = 7\n    console.log(resultAsignacion)\n    resultAsignacion &&= y // AND lógico si x = 0, null, '', false, undefined o Nan NO le asigna el valor de y\n    console.log(resultAsignacion)\n    resultAsignacion ||= y // OR lógico si x = 0, null, '', false, undefined o Nan SI le asigna el valor de y\n    console.log(resultAsignacion)\n    resultAsignacion ??= y // anulación lógica si x = null o undefined SI le asigna el valor de y\n    console.log(resultAsignacion)\n\n  // DE COMPARACION\n    let resultComparacion\n    resultComparacion = x == y // igualdad ej: 3 == 3 --> true '3' == 3 --> true\n    console.log(resultComparacion)\n    resultComparacion = x != y // desigualdad\n    console.log(resultComparacion)\n    resultComparacion = x === y // igualdad extricta ej: 3 === 3 --> true '3' === 3 --> false\n    console.log(resultComparacion)\n    resultComparacion = x !== y // desigualdad extricta\n    console.log(resultComparacion)\n    resultComparacion = x > y // mayor que\n    console.log(resultComparacion)\n    resultComparacion = x < y // menor que\n    console.log(resultComparacion)\n    resultComparacion = x >= y // mayor o igual que\n    console.log(resultComparacion)\n    resultComparacion = x <= y // menor o igual que\n    console.log(resultComparacion)\n\n  // ARITMETICOS\n    let resultAritmeticos\n    let ar1 = 5 \n    let ar2 = 2\n    resultAritmeticos = ar1 % ar2 // residuo\n    console.log(resultAritmeticos)\n    resultAritmeticos = ar1++ // incremento\n    console.log(resultAritmeticos)\n    resultAritmeticos = ar1-- // decremento\n    console.log(resultAritmeticos)\n    resultAritmeticos = -ar1 // negación unaria\n    console.log(resultAritmeticos)\n    resultAritmeticos = +'3' // positivo unario --> intenta convertir el operando en un número ej: +true = 1; +false, +null, +'', +' ' = 0; +undefined, +'hola' = NaN\n    console.log(resultAritmeticos)\n    resultAritmeticos = ar1 ** ar2 // exponenciación\n    console.log(resultAritmeticos)\n\n  // BIT A BIT\n    let resultBitABit\n    let bit1 = 5\n    let bit2 = 3\n    bit1 & bit2 // AND bit a bit ej: bit1 = 5 (0000 0101)  bit2 = 3 (0000 0011) --> 0000 0001 --> bit1 = 1\n    console.log(resultBitABit)\n    bit1 | bit2 // OR bit a bit ej: bit1 = 5 (0000 0101)  bit2 = 3 (0000 0011) --> 0000 0111 --> bit1 = 7\n    console.log(resultBitABit)\n    bit1 ^ bit2 // XOR bit a bit ej: bit1 = 5 (0000 0101)  bit2 = 3 (0000 0011) --> 0000 0110 --> bit1 = 6\n    console.log(resultBitABit)\n    ~ bit2 // XOR bit a bit ej: bit1 = 5 (0000 0101)  bit2 = 3 (0000 0011) --> 0000 0110 --> bit1 = 6\n    console.log(resultBitABit)\n    bit1 <<= bit2 // desplazamiento a la izquierda ej: bit1 = 5 (0000 0101)  bit2 = 2 --> 0001 0100 --> bit1 = 20\n    console.log(resultBitABit)\n    bit1 >>= bit2 // desplazamiento a la derecha de propagación de signo ej: bit1 = -20 (1110 1100)  bit2 = 2 --> 1111 1011 --> bit1 = -5\n    console.log(resultBitABit)\n    bit1 >>>= bit2 // desplazamiento a la derecha de relleno de ceros ej: bit1 = -20 (1110 1100)  bit2 = 2 --> 0011 1011 --> bit1 = 59\n    console.log(resultBitABit)\n\n  // LOGICOS\n    let resultLogico\n    resultLogico = true && false // AND lógico devuelve true unicamente si todos los valores son true\n    console.log(resultLogico)\n    resultLogico = true || false // OR lógico devuelve false unicamente si todos los valores son false\n    console.log(resultLogico)\n    resultLogico = !false // NOT lógico invierte el valor boleano\n    console.log(resultLogico)\n\n  // DE CADENA\n    let resultCadena\n    let cad1 = 'Hola '\n    let cad2 = 'mundo'\n    resultCadena = cad1 + cad2 // concatenación\n    console.log(resultCadena)\n    cad1 += cad2 // asignación abreviada \n    console.log(resultCadena)\n\n  // CONDICIONAL (TERNARIO)\n    let resultCondicional\n    let edad = 18\n    resultCondicional = edad >= 18 ? 'adulto' : 'menor' \n    console.log(resultCondicional)\n\n  // COMA\n    let com1 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];\n    let com2 = [x, x, x, x, x];\n\n    for (var i = 0, j = 9; i <= j; i++, j--)\n      //                              ^\n      console.log(\"com2[\" + i + \"][\" + j + \"]= \" + com2[i][j]);\n\n  // UNARIOS\n    let resultUnarios\n    let persona = {\n      nombre: 'Pepe',\n      edad: 68,\n      casado: true\n    }\n    resultUnarios = delete persona.casado // elimina la propiedad de un objeto\n    console.log(resultUnarios)\n    resultUnarios = typeof persona.edad // devuelve el tipo de dato\n    console.log(resultUnarios)\n    resultUnarios = void (persona.edad) // devuelve undefined\n    console.log(resultUnarios)\n\n  // RELACIONALES\n    let resultRalacionales\n    let rel = [10, 20, 30, 40, 50]\n    resultRalacionales = 3 in rel // devuelve true si la propiedad o el indice existe en el objeto\n    console.log(resultRalacionales)\n    resultRalacionales = rel instanceof Array // devuelve true si el objeto es del tipo del objeto especificado\n    console.log(resultRalacionales)\n\n// --------------------- ESTRUCTURAS DE CONTROL ---------------------\n  // CONDICIONALES\n    let puntuacion = 75;\n    if (puntuacion >= 90) {  // IF \n        console.log(\"Puntuacón excelente!\"); \n    } else if (puntuacion >= 70) {  // ELSE IF\n        console.log(\"Buen trabajo!\");\n    } else {  // ELSE\n        console.log(\"Puedes mejorar.\");\n    }\n\n    let usuario = 'admin'\n    switch (usuario) {\n      case 'admin':\n        console.log('Tú eres el admin')\n        break;\n      case 'registrado':\n        console.log('Hola de nuevo!!')\n        break;\n      default: console.log('No estas registrado')\n        break;\n    }\n\n  // BUCLES\n    for (let i = 0; i < 5; i++) {  // FOR\n      console.log(\"Iteración \" + i);\n    }\n    let count = 0\n    while (count < 3) {  //WHILE\n        console.log(\"Valor del contador \" + count);\n        count++;\n    }\n    let number = 0;\n    do {  // DO WHILE\n        console.log(\"Number is \" + number);\n        number++;\n    } while (number < 3);\n    const arr = [3, 5, 7];\n    arr.foo = \"hola\";\n    for (let i in arr) { // FOR IN\n      console.log(i); // logs \"0\", \"1\", \"2\", \"foo\"\n    }\n    for (let i of arr) {  // FOR OF\n      console.log(i); // logs 3, 5, 7\n    }\n\n  // EXEPCIONES\n    try {\n        let data = JSON.parse(\"invalid json\");\n    } catch (error) {\n        console.log(\"Error parsing JSON.\");\n    } finally {\n        console.log(\"Execution completed.\");\n    }\n\n// --------------------- DIFICULTAD EXTRA ---------------------\n\nfor (let i = 10; i <=55 ; i++) {\n  if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n    console.log(`El numero ${i} es par, no es 16 y no es multiplo de 3`)\n  }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/popmaquin.js",
    "content": "/*\n*____________________________\n*|                          |\n |        Operadores        |  \n*|__________________________|\n*/\n\n/* Operadores Aritméticos*/\nconsole.log(\"Suma de 5+5 es: \" + (5+5));\nconsole.log(\"Resta de 5-5 es: \" + (5-5));\nconsole.log(\"Multiplicación de 5*5 es: \" + (5*5));\nconsole.log(\"Divición de 5/5 es: \" + (5/5));\nconsole.log(\"Modulo de 5%5 es: \" + (5%5));\nconsole.log(\"Potencia de 2^5 es: \" + (2**5)); //2**5 == (2x2x2x2x2)\n\n/* Operadores lógicos*/\nconsole.log(\"Operador AND: \" + (true && true));\nconsole.log(\"Operador OR: \"  + (true || false));\nconsole.log(\"Operador NOT: \" + (!true));\n\n/* Operadores de comparacion*/\nconsole.log(\"Operador igualdad: \" + (5==5));        //compara \nconsole.log(\"Operador igualdad triple: \"+ (5===5)); //compara y comprueba dato\nconsole.log(\"Operador menorque: \" + (5<5));\nconsole.log(\"Operador mayorque: \" + (5>5));\nconsole.log(\"Operador menor igual que: \" + (5<=5));\nconsole.log(\"Operador mayor igual que: \" + (5>=5));\nconsole.log(\"Operador desigualdad: \" + (5!=5));\nconsole.log(\"Operador desigualdad estricta: \" + (5!==5));\n\n/* Operadores de asignacion*/\nlet x, y; \nx=8; y=2; \nconsole.log(\"Asignacion de x=8: \" + (x=8)); \nconsole.log(\"Asignacion de suma: x+=y \" + (x+=y));\nconsole.log(\"Asignacion de resta: x-=y \" + (x-=y));\nconsole.log(\"Asignacion de multiplicación: x*=y \" + (x*=y));\nconsole.log(\"Asignacion de division: x/=y \" + (x/=y));\nconsole.log(\"Asignacion de potencia: x**=y \" + (x**=y));\nconsole.log(\"Asignacion de residuos: x%=y \" + (x%=y));\nconsole.log(\"Asignacion de desplazamiento a la izquierda: x<<=y \" + (x<<=y));\nconsole.log(\"Asignacion de desplazamiento a la derecha sin signo: x>>>=y \" + (x>>>=y));\nconsole.log(\"Asignacion AND bit a bit: x&=y \" + (x&=y)); // x & = y == x = x & y;\nconsole.log(\"Asignacion AND bit a bit: x|=y \" + (x|=y));\n\n/* Operadores de unarios*/\nlet a=2;\nconsole.log(\"Valor de a inicial: \" +a);     //a=2\nconsole.log(\"Incremento a++: \"+ (a++));     //a=2\nconsole.log(\"Valor de a ahora: \" +a);       //a=3\nconsole.log(\"Decremento a--: \" + (a--));    //a=3\nconsole.log(\"Valor de a ahora: \" +a);       //a=2\nconsole.log(\"Incremento previo ++a: \"+ (++a)); //a=3\nconsole.log(\"Valor de a ahora: \" +a);          //a=3\nconsole.log(\"Decremento previo --a: \" + (--a));//a=2\nconsole.log(\"Valor de a ahora: \" +a);          //a=2\nconsole.log(\"Resta unaria -a: \" + (-a));       //a=-2 vuelve negativo el valor\n\n\n\n/* Operadores de bit a bit*/\n    console.log(\"AND=& Devuelve uno, si ambos son iguales a uno: \" + (14 & 13) );   // [ 1110 & 1101 ] Salida:1100= 12 \n    console.log(\"OR=| Devuelve cero, si ambos son iguales a cero: \" + (14 | 13) ); // [ 1110 & 1101 ] Salida:1111= 15 \n    console.log(\"XOR=^ Devuelve cero, si ambos son iguales a uno y uno si son diferentes: \" + (14 ^ 13) ); // [ 1110 & 1101 ] Salida:0011= 3 \n    console.log(\"NOT=~  Invierte los bits: \" + (~14) ); // [ 1110 ] Salida: 1111= -15\n\n/* Operadores de cadena*/\n    console.log(\"Mi\" + \" país\" + \" Guatemala\"); //salida: \"Mi país Guatemala\"\n\n/*___________________________\n*|                          |\n |   Estructura de control  |  \n*|__________________________|\n*/\n\n/*** tipos de estructuras de control ***/\n\n/*condicional if*/\nlet edad=2 //Puede cambiar los valores de edad.\n    if (edad<0) {\n        console.log(\"Es numero negativo, ingrese una edad valida\"); \n    } else if (edad===0) {\n        console.log(\"Recien nacido \");          \n    \n    } else if (edad>=18) {\n        console.log(\"Eres mayor de edad \");          \n    } \n    else{\n        console.log(\"Eres menor de edad\")\n    }\n\n/*condicional switch*/\nlet opcion=prompt(\"Ingres uno de los dias de la semana: \");\n\nswitch (opcion) {\n    case \"lunes\":\n        console.log(\"Feliz semana, Desarrolla el éxito a partir de los fracasos.\");\n        break;\n    case \"martes\":\n        console.log(\"Hoy puede ser un día difícil, pero recuerda que cada desafío superado te hace más fuerte.\");\n        break;\n    case \"miercoles\":\n        console.log(\"Las tormentas no duran para siempre.\");\n        break;\n    case \"jueves\":\n        console.log(\"La acción es la clave fundamental de todo éxito.\");\n        break;\n    case \"viernes\":\n        console.log(\"No importa cuántas veces caigas, lo importante es cuántas veces te levantes.\");\n        break;\n    case \"sabado\":\n        console.log(\"Cada día es una nueva oportunidad para empezar de nuevo y hacerlo mejor.\");\n        break;\n    case \"domingo\":\n        console.log(\"No esperes a que las oportunidades lleguen, créalas tú mismo.\");\n        break;\n    default:\n        console.log(\"Ingrese los nombres de los dias validos.\");\n        break;\n}\n\n/*Iterativas.*/ //for \nfor (let index = 0; index < 5; index++) {\n    console.log(\"mensaje \"+ index);  \n    //imprime la palabra mensaje 5 veces.   \n}\n\n//for in\nlet array = [\"Lunes\",\"Martes\",\"Miercoles\",\"Jueves\",\"Viernes\",\"Sabado\",\"Domingo\"]\nfor (i in array) {\n    console.log(array[i]);\n}\n\n//do while\nlet tecla = '';\ndo{\n    tecla = prompt(\"Adivina!!!..¿Qué cosa es que cuanto más le quitas más grande es?:\");\n}while (tecla != 'el agujero');\nalert(\"Has acertado\");\n\n//while\nlet i=0;\nwhile (i<5) {\n    console.log(\"Hola!\");\n    i++;\n}\n// try catch\n\ntry {\n    const prueba = 7\n    console.log(prueba);\n    prueba = 10;\n} catch (error) {\n    console.log(error); //TypeError: Assignment to constant variable. at <anonymous>\n    console.log(\"Error de sintaxis, imposible reasignar valor variable constante.\"); \n} finally{\n    console.log (\"Saliendo del try catch\");\n}       \n    console.log (\"Fuera del try catch\");\n\n/*___________________________\n*|                          |\n |   Extra Opcional         |  \n*|__________________________|\n*/\nfor(numero=10; numero<=55; numero++){\n    if(numero%2==0 && (numero%3!=0) && (numero!=16)){\n    console.log(numero);\n    }\n}\n/*Salida: 10, 14, 20, 22, 26, 28, 32, 34, 38, 40, 44, 46, 50, 52*/ "
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/ppinilla.js",
    "content": "//01 OPERADORES Y ESTRUCTURAS DE CONTROL\n\n/*\nEJERCICIO:\n - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n - Utilizando las operaciones con operadores que tú quieras, crea ejemplos que representen todos los tipos de estructuras de control que existan en tu lenguaje:\n Condicionales, iterativas, excepciones...\n - Debes hacer print por consola del resultado de todos los ejemplos.\n\n DIFICULTAD EXTRA (opcional):\n Crea un programa que imprima por consola todos los números comprendidos entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\n Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n*/\n\n//- Tipos de operadores\n//Operadores de asignación\nlet x = 10, y = 5;\nconsole.log('Operadores de asignación x =', x, 'y =', y);\nconsole.log(\"Asignación: x = y =\", x = y);\nconsole.log('x =', x, 'y =', y);\nconsole.log(\"Asignación de suma: x += y =\", x += y);\nconsole.log('x =', x, 'y =', y);\nconsole.log(\"Asignación de resta: x -= y =\", x -= y);\nconsole.log('x =', x, 'y =', y);\nconsole.log(\"Asignación de multiplicación: x *= y =\", x *= y);\nconsole.log('x =', x, 'y =', y);\nconsole.log(\"Asignación de división: x /= y =\", x /= y);\nconsole.log('x =', x, 'y =', y);\nconsole.log(\"Asignación de resto: x %= y =\", x %= y);\nconsole.log('x =', x, 'y =', y);\nconsole.log(\"Asignación de exponenciación: y **= x =\", y **= x);\nconsole.log('x =', x, 'y =', y);\nx = 10, y = 5\nconsole.log(\"Asignación de desplazamiento a la izquierda: x <<= 2 =\", x <<= 2);\nconsole.log('x =', x);\nconsole.log(\"Asignación de desplazamiento a la derecha: x >>= 2 =\", x >>= 2);\nconsole.log('x =', x);\nconsole.log(\"Asignación de desplazamiento a la derecha sin signo: x >>>= 2 =\", x >>>= 2);\nconsole.log('x =', x);\nx = 9, y = 14\nconsole.log(\"Asignación AND bit a bit: 9 &= 14 =\", x &= y)\nconsole.log('x =', x);\nconsole.log(\"Asignación XOR bit a bit: x ^= 14 =\", x ^= y);\nconsole.log('x =', x);\nconsole.log(\"Asignación OR bit a bit: x |= 14 =\", x |= y);\nconsole.log('x =', x);\nconsole.log(\"Asignación AND lógico: x &&= 14 =\", x &&= y);\nconsole.log('x =', x);\nconsole.log(\"Asignación OR lógico: x ||= 14 =\", x ||= y);\nconsole.log('x =', x);\nconsole.log(\"Asignación de anulación lógica: x ??= 14 =\", x ??= y);\nconsole.log('x =', x);\n\n//Operadores Aritméticos\nx = 10, y = 5;\nconsole.log('Operadores aritméticos: x =', x, 'y =', y);\nconsole.log(\"Suma:\", x + y );\nconsole.log(\"Resta:\", x - y );\nconsole.log(\"Multiplicación:\", x * y );\nconsole.log(\"División:\", x / y );\nconsole.log(\"Residuo:\", x % y );\nconsole.log(\"Exponenciación:\", x ** y );\nconsole.log(\"Incremento:\", ++x );\nconsole.log(\"Decremento:\", --y );\nconsole.log(\"Positivo unario:\", +x );\nconsole.log(\"Negativo unario:\", -x );\n\n//Operadores bit a bit\nx = 9, y = 14;\nconsole.log('Operadores bit a bit: x =', x, 'y =', y);\nconsole.log(\"AND a nivel de bits: x & y =\", x & y)\nconsole.log(\"XOR a nivel de bits: x ^ 14 =\", x ^ y);\nconsole.log(\"OR a nivel de bits:: x | 14 =\", x | y);\nconsole.log(\"NOT a nivel de bits: ~ x =\", ~ x);\nconsole.log(\"Desplazamiento a la izquierda: y << 2 =\", y << 2);\nconsole.log(\"Desplazamiento a la derecha de propagación de signo: y >> 2 =\", y >> 2);\nconsole.log(\"Desplazamiento a la derecha de relleno cero: x >>> 2 =\", y >>> 2);\n\n//Operadores de comparación\nconsole.log('Operadores de comparación: x =', x, 'y =', y);\nconsole.log(x, '>', y, \"'Mayor que': \", x > y);\nconsole.log(x, '<', y, \"'Menor que': \", x < y);\nconsole.log(x, '>=', y, \"'Mayor o igual que': \", x >= y);\nconsole.log(x, '<=', y, \"'Menor o igual que': \", x <= y);\nconsole.log(x, '==', y, \"'Igual': \", x == y);\nconsole.log(x, '===', y, \"'Estrictamente igual': \", x === y);\nconsole.log(x, '!=', y, \"'Distinto': \", x != y);\nconsole.log(x, '!==', y, \"'Estrictamente distinto': \", x !== y);\n\n//Operandos lógicos\nconsole.log('Operandos lógicos: x =', x, 'y =', y); \nconsole.log(\"AND: x && y =\", x && y); //Devuelve y si ambos operandos son true; de lo contrario, devuelve x.\nconsole.log(\"OR: x || y =\", x || y); //Devuelve x si el operando x es true, devuelve y si el operando x es false; si ambos son falsos, devuelve y.\nconsole.log(\"NOT: !x =\", !x); //Devuelve false si su operando es true; de lo contrario, devuelve true.\n\n//Operador de cadena\nlet a = 'Operador', b = 'cadena';\nconsole.log(a + ' de ' + b, 'a + b');\n\n//Operador condicional (ternario)\nconsole.log('Operador condicional');\nlet age = 24;\nlet estado = age >= 18 ? \"adulto\" : \"menor\";\nconsole.log(\"condition ? val1 : val2 ¿Es adulto o menor?\", estado);\n\n//Operador coma\nconsole.log('Operador coma');\nvar n = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];\nvar m = [x, x, x, x, x];\n\nfor (var i = 0, j = 9; i <= j; i++, j--)\n    console.log(\"m[\" + i + \"][\" + j + \"]= \" + i + j);\n\n//Operandores unarios\nconsole.log('Operadores unarios');\nz = 10; //implicitamente crea window.z\nvar h = 24;\nlet myObj = { x: 10 };\nlet diaSem = ['lunes', 'martes', 'miercoles', 'jueves', 'viernes', 'sábado', 'domingo'];\nlet theDay = new Date(2025, 1, 28);\nconsole.log('delete object.property:')\nconsole.log('delete myObj:', delete myObj.x);\nconsole.log('delete.z:', delete z);\nconsole.log('delete.nameVar:', delete h); //No se puede borrar si se declara con var\nconsole.log('typeof operand');\nconsole.log('typeof object:', typeof myObj);\nconsole.log('typeof true:', typeof true);\nconsole.log('void (expression)');\nconsole.log('propNameorNumber in objectName');\nconsole.log('2 in diaSem:', 2 in diaSem);\nconsole.log('8 in diaSem:', 8 in diaSem);\nconsole.log('objectName instanceOf objectType');\nif (theDay instanceof Date){\n    console.log('the Day instanceof Date: true');\n    \n}\n\n//- Tipos de estructuras de control\n//Condicionales\nconsole.log('Expresión if...else: if (condition) { statement_1; } else { statement_2; }');\nlet deuda = 300001\nif (deuda > 300000) {\n    console.log(\"Bienvenido al juego del calamar\");\n} else {\n    console.log(\"No puedes entrar al juego del calamar. Deuda menor a $300000\");\n}\n\n//Bucles\nconsole.log('Expresión switch: switch (expression) { case label_1: statements_1 [break;]  case label_2: statements_2 [break] ... default: statements_def [break;] }');\nlet juego = 'Luz roja, luz verde'\nswitch (juego) {\n    case 'Luz roja, luz verde':\n        console.log('Jugaremos, muevete luz verde');\n        break;\n    case 'Pentatlon de seis piernas':\n        console.log('ddakji, biseokchigi, gong-gi, jegi y peonza');\n        break;\n    case 'Mingle':\n        console.log('Formen grupos de 5');\n        break;\n    default:\n        console.log('Ese juego no existe');\n        break;\n}\n\nconsole.log('Expresión for: for (begin; condition; step) { loopBody }');\nconst juegos = 6;\nfor (let juego = 1; juego <= juegos; juego++){\n    console.log(\"Bienvenidos al juego: \", juego);\n}\n\nconsole.log('Expresión while: while (condition) { loopBody }');\ni = 0;\nwhile (i < 6) {\n    console.log('Felicitaciones, pasas al siguiente juego');\n    i++\n}\n\nconsole.log('Expresión do...while: do { } while (condition);');\ni = 0\ndo {\n    console.log('Felicitaciones, pasas al siguiente juego');\n    i++;\n} while (i < 6);\n\n//- Crea un programa que imprima por consola todos los números comprendidos entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\n\nfor (let i = 10; i <= 55; i++) {\n    if (i % 2 == 0 && i != 16 && i % 3 !== 0) {\n        console.log(i);\n    }\n}\n\n  \n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/pype-Dev.js",
    "content": "/**\n * OPERADORES:\n * Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n * Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n */\n\n// ARITHMETIC OPERATORS\nlet a = 10;\nlet b = 3;\n\nconsole.log(`Suma: ${a} + ${b} = ${a + b}`);\nconsole.log(`Resta: ${a} - ${b} = ${a - b}`);\nconsole.log(`Producto: ${a} * ${b} = ${a * b}`);\nconsole.log(`División: ${a} / ${b} = ${a / b}`);\nconsole.log(`Módulo: ${a} % ${b} = ${a % b}`);\nconsole.log(`Potenciación: ${a} ** ${b} = ${a ** b}`);\n\n/* incremento y decremento */\nlet incremento = 10;\nincremento++;\n++incremento;\nconsole.log(`Incremento: (10++) y (++10) es: ${incremento}`)\n\nlet decremento = 10;\ndecremento--;\n--decremento;\nconsole.log(`Decremento: (10--) y (--10) es: ${decremento}`)\n\n// LOGICAL OPERATORS\nconsole.log(`AND (&&): 10 + 5 == 15 and 8 - 3 == 5 es: ${10 + 5 == 15 && 8 - 3 == 5}`);\nconsole.log(`OR (||): 10 + 5 == 16 or 8 - 3 == 5 es: ${10 +5 == 16 || 8 - 3 == 5}`);\nconsole.log(`NOT (!): 10 + 5 == 15 es: ${!(10 + 5 == 15)}`);\n\n/* Nullish Coalescing: Devuelve el valor derecho solo si el izquierdo es null o undefined */\nlet puntaje = 0;\nconsole.log(`Nullish (??): puntaje ?? 10 es: ${puntaje ?? 10}`)\n\n// COMPARISION OPERATORS\nconsole.log(`Igualdad débil: 5 == '5' es: ${5 == '5'}`);\nconsole.log(`Igualdad estricta: 5 === '5' es: ${5 === '5'}`);\nconsole.log(`Desigualdad débil: 4 != '3' es: ${4 != '3'}`);\nconsole.log(`Desigualdad estricta: 8 !== '7' es: ${8 !== '7'}`);\nconsole.log(`Mayor qué: 15 > 10 es: ${15 > 10}`);\nconsole.log(`Mayor o igual qué: 2 >= 2 es: ${2 >= 2}`);\nconsole.log(`Menor qué: 7 < 13 es: ${7 < 13}`);\nconsole.log(`Menor o igual qué: 4 <= 2 es: ${4 <= 2}`);\n\n// ASSIGNMENT OPERATORS\nlet c = 20; //asignación\nconsole.log(c);\n\nc += 10; //asignación de suna\nconsole.log(c);\n\nc -= 10; //asignación de resta\nconsole.log(c);\n\nc *= 10; //asignación de multiplicación\nconsole.log(c);\n\nc /= 4; //asignación de división\nconsole.log(c);\n\nc %= 4; //asiganción de módulo\nconsole.log(c);\n\nc **= 4; //asignación de exponenciación\nconsole.log(c)\n\nc <<= 2; //asignación de desplazamiento a la izquierda\nconsole.log(c); //(16 = 00010000) (64 = 01000000)\n\nc >>= 2; //asignación de desplazamiento a la derecha\nconsole.log(c); //(64 = 01000000) (16 = 00010000)\n\n/* bitwise and, xor y or assignment */\nlet bit1 = 12;              //1100\nbit1 &= 5;                  //0101 and\nconsole.log(bit1);          //0100\n\nlet bit2 = 10;              //1010\nbit2 ^= 6;                  //0110 xor\nconsole.log(bit2);          //1100\n\nlet bit3 = 8;               //1000\nbit3 |= 3;                  //0011 or\nconsole.log(bit3)           //1011\n\n// BITWISE OPERATORS\nlet x = 5;                  //00000000000000000000000000000101\nlet y = 3;                  //00000000000000000000000000000011\n\nconsole.log(`Bitwise And(&): ${x} & ${y} es: ${x & y}`);        //00000000000000000000000000000001\nconsole.log(`Bitwise Or(|): ${x} | ${y} es: ${x | y}`);         //00000000000000000000000000000111\nconsole.log(`Bitwise Xor(^): ${x} ^ ${y} es: ${x ^ y}`);        //00000000000000000000000000000110\nconsole.log(`Bitwise Not(~): ~${x} es: ${~x}`);                 //11111111111111111111111111111010\nconsole.log(`Left shift(<<): ${x} << 2 es: ${x << 2}`);         //00000000000000000000000000010100\nconsole.log(`Right shift(>>): ${x} >> 2 es: ${x >> 2}`);        //00000000000000000000000000000001\n\n// STRING OPERATORS\nlet myString = \"Hello\";\nmyString += \" World!\";\nconsole.log(myString)\n\n// BIGINT OPERATORS\nconst myBigInt = 9007199254740991n;\ntypeof myBigInt;\n\nlet num = 10;\nlet big = 20n;\nconsole.log(BigInt(num) + big);\n\n//CONDITIONAL (TERNARY) OPERATOR\nlet age = 20;\nconst validacion = (age >= 18) ? \"Es mayor de edad\" : \"Es menor de edad\";\n\nconsole.log(validacion);\n\n//RELATIONAL OPERATORS\n/* Operador relacional en Objetos */\nconst vehiculo = {\n    marca : \"Kawasaki\",\n    referencia : \"Ninja\",\n    cilindraje : 500,\n    modelo : 2026,\n};\n\nconsole.log(\"marca\" in vehiculo); //true\nconsole.log(\"motor\" in vehiculo); //false\n\n/* Operador relacional en Arrays */\nconst estudiantes = [\"Juan\", \"Karen\", \"Alejandra\", \"Sandra\", \"Monica\"];\n\nconsole.log(3 in estudiantes); //true\nconsole.log(5 in estudiantes); //false\nconsole.log(\"Karen\" in estudiantes); //false\n\n\n/**\n * ESTRUCTURAS DE CONTROL:\n * Utilizando las operaciones con operadores que tú quieras, crea ejemplos que representen todos los tipos de estructuras de control que existanen tu lenguaje:\n * Condicionales, iterativas, excepciones...\n */\n//IF...ELSE\nconst edad = Number(prompt(\"Por favor ingresa tu edad:\")); //Number() convierte el string en number\nconst clienteVIP = prompt(\"¿Tienes membresía de cliente VIP?:)\");\nconst valorEntrada = 15000;\n\nif(edad < 12){\n    console.log(\"El precio de la entrada es de $8000 cop\");\n} else if(edad > 65){\n    console.log(\"El precio de la entrada es de $10000 cop\");\n} else if(edad >= 12 && edad <= 65 && clienteVIP == \"true\"){\n    const descuento = (valorEntrada * 0.2);\n    console.log(`Tienes un 20% de descuento en el valor de tu entrada. El precio final es de $${valorEntrada - descuento} cop`)\n} else{\n    console.log(\"El precio de la entrada es de $15.000 cop\")\n}\n\n//SWITCH\nconst num1 = 100;\nconst num2 = 25;\nlet operacion = \"División\"\n\nswitch (operacion){\n    case \"Suma\":\n        console.log(`El resultado de la suma es: ${num1 + num2}`);\n        break;\n    case \"Resta\":\n        console.log(`El resultado de la resta es: ${num1 - num2}`);\n        break;\n    case \"Multiplicación\":\n        console.log(`El resultado de la multiplicación es: ${num1 * num2}`);\n        break;\n    case \"División\":\n        if(num2 == 0){\n            console.log(\"Ningun número se puede dividir por 0. ERROR\")\n        } else{\n            console.log(`El resultado de la división es: ${num1 / num2}`);\n        }\n        break;\n    default:\n        console.log(\"La operación ingresada no es reconocida\");\n}\n\n//FOR\nconst tablaMultiplicar = 5;\n\nfor(let i = 1; i <= 10; i++){\n    let producto = tablaMultiplicar * i;\n    let paridad = (producto % 2 == 0) ? \"PAR\" : \"IMPAR\";\n    console.log(`El resultado ${producto} es ${paridad}.`)\n}\n\n//FOR...OF\nconst precios = [100, 450, 200, 600, 80, 500];\nlet totalOfertas = 0;\n\nfor(const valor of precios){\n    if(valor < 300){\n        totalOfertas += valor;\n    }\n}\n\nconsole.log(`El total de los productos en oferta es: $${totalOfertas}`)\n\n//FOR...IN\nconst stats = {\n    fuerza: 80,\n    agilidad: 40,\n    magia: 95,\n    defensa: 60,\n}\n\nfor(const habilidad in stats){\n    if(stats[habilidad] >= 90){\n        console.log(`¡Habilidad Maestra descubierta: ${habilidad}!`);\n    } else{\n        console.log(`Entrenando la habilidad: ${habilidad}`)\n    }\n}\n\n//WHILE\nlet ahorro = 0;\nconst meta = 100;\n\nwhile(ahorro < meta){\n    ahorro += 25;\n    console.log(`Ahorro actual: ${ahorro}`);\n\n    if(ahorro == 50){\n        console.log(\"¡Ya vas a la mitad!\");\n    }\n}\n\nconsole.log(`¡Meta alcanzada! Tienes $${ahorro} ahorrados.`);\n\n//DO WHILE\nlet dado;\nlet intentos = 0;\n\ndo{\n    dado = Math.floor(Math.random() * 6) + 1;\n    intentos++;\n    console.log(`Lanzamiento ${intentos}: Salio un ${dado}`)\n} while(dado != 6);\n\nconsole.log(`¡Por fin! Tardaste ${intentos} lanzamientos en sacar un 6`);\n\n//TRY...CATCH\nlet presupuestoTotal = 1000;\nlet numeroProyectos = 0;\n\ntry{\n    if(numeroProyectos == 0){\n        throw new Error(\"No puedes dividir el presupuesto entre cero proyectos.\");\n    } else{\n        let resultado = presupuestoTotal / numeroProyectos;\n        console.log(`A cada proyecto le corresponden $${resultado} dólares`);\n    }\n} catch(e){\n    console.error(\"Error de registro: \" + e.message)\n} finally{\n    console.log(\"Proceso de cálculo finalizado.\")\n}\n\n/*\nDIFICULTAD EXTRA (opcional):\nCrea un programa que imprima por consola todos los números comprendidos entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n*/\nfor(let i = 10; i <= 55; i++){\n    if(i % 2 == 0 && i !== 16 && i % 3 !== 0){\n        console.log(i);\n    };\n};\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/qwik-zgheib.js",
    "content": "// -- exercise\n// Arithmetic operators\nlet a = 10;\nlet b = 5;\nlet sum = a + b;\nlet difference = a - b;\nlet product = a * b;\nlet quotient = a / b;\nlet remainder = a % b;\n\nconsole.log(\"Arithmetic Operators:\");\nconsole.log(\"Sum:\", sum);\nconsole.log(\"Difference:\", difference);\nconsole.log(\"Product:\", product);\nconsole.log(\"Quotient:\", quotient);\nconsole.log(\"Remainder:\", remainder);\n\n// Logical operators\nlet x = true;\nlet y = false;\nlet andResult = x && y;\nlet orResult = x || y;\nlet notResult = !x;\n\nconsole.log(\"\\nLogical Operators:\");\nconsole.log(\"AND:\", andResult);\nconsole.log(\"OR:\", orResult);\nconsole.log(\"NOT:\", notResult);\n\n// Comparison operators\nlet num1 = 10;\nlet num2 = 20;\nlet isEqual = num1 === num2;\nlet isNotEqual = num1 !== num2;\nlet greaterThan = num1 > num2;\nlet lessThan = num1 < num2;\nlet greaterThanOrEqual = num1 >= num2;\nlet lessThanOrEqual = num1 <= num2;\n\nconsole.log(\"\\nComparison Operators:\");\nconsole.log(\"Is Equal:\", isEqual);\nconsole.log(\"Is Not Equal:\", isNotEqual);\nconsole.log(\"Greater Than:\", greaterThan);\nconsole.log(\"Less Than:\", lessThan);\nconsole.log(\"Greater Than or Equal:\", greaterThanOrEqual);\nconsole.log(\"Less Than or Equal:\", lessThanOrEqual);\n\n// Assignment operators\nlet assignedValue = 30;\nassignedValue += 5;\nconsole.log(\"\\nAssignment Operator:\");\nconsole.log(\"Assigned Value:\", assignedValue);\n\n// Identity operators\nlet obj1 = {};\nlet obj2 = {};\nlet obj3 = obj1;\nlet identityCheck1 = obj1 === obj2;\nlet identityCheck2 = obj1 === obj3;\n\nconsole.log(\"\\nIdentity Operators:\");\nconsole.log(\"Identity Check 1:\", identityCheck1);\nconsole.log(\"Identity Check 2:\", identityCheck2);\n\n// Membership operators\nlet array = [1, 2, 3];\nlet isInArray = 2 in array;\n\nconsole.log(\"\\nMembership Operator:\");\nconsole.log(\"Is 2 in Array?\", isInArray);\n\n// Bitwise operators\nlet bitwiseAnd = 5 & 1;\nlet bitwiseOr = 5 | 1;\nlet bitwiseXor = 5 ^ 1;\nlet bitwiseNot = ~5;\nlet leftShift = 5 << 1;\nlet rightShift = 5 >> 1;\nlet zeroFillRightShift = 5 >>> 1;\n\nconsole.log(\"\\nBitwise Operators:\");\nconsole.log(\"Bitwise AND:\", bitwiseAnd);\nconsole.log(\"Bitwise OR:\", bitwiseOr);\nconsole.log(\"Bitwise XOR:\", bitwiseXor);\nconsole.log(\"Bitwise NOT:\", bitwiseNot);\nconsole.log(\"Left Shift:\", leftShift);\nconsole.log(\"Right Shift:\", rightShift);\nconsole.log(\"Zero-fill Right Shift:\", zeroFillRightShift);\n\n// Conditional structures\nlet condition = true;\n\nif (condition) {\n  console.log(\"Condition is true.\");\n} else {\n  console.log(\"Condition is false.\");\n}\n\n// ---------------------------------------------\n// Iterative structure -- extra challenge\nconsole.log(\"\\nIterative Structure:\");\nfor (let i = 10; i <= 55; i++) {\n  if (i !== 16 && i % 3 !== 0 && i % 2 === 0) {\n    console.log(i);\n  }\n}\n// ---------------------------------------------\n\n// Exception handling structure\nconsole.log(\"\\nException Handling Structure:\");\ntry {\n  throw new Error(\"Example error\");\n} catch (error) {\n  console.error(error);\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/r4kso.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n */\n\n// Operadores de asignación\nlet x = 1;      // Asignación\nconsole.log(\"El valor de la variable x es: \" + x);\n\nx += 1;         // Asignación de adición\nconsole.log(\"Si a x le sumamos 1 su valor es: \" + x);\n\nx -= 1;         // Asignación de resta\nconsole.log(\"Si a x le restamos 1 su valor es: \" + x);\n\nx *= 2;         // Asignación de multiplicación\nconsole.log(\"Si x lo multiplicamos por 2 su valor es: \" + x);\n\nx /= 2;         // Asignación de división\nconsole.log(\"Si x lo dividimos entre 2 su valor es: \" + x);\n\nx = 7;         \nx %= 2;         // Asignación de residuo\nconsole.log(\"Le hemos dado a x el valor 7. Si ahora le asignamos el residuo de la división entre 2 su valor es: \" + x);\n\nx = 4;\nx **= 2;        // Asignación de exponenciación\nconsole.log(\"Ahora le hemos asignado a x el valor 4. Si elevamos a 2 el valor de x, ahora su valor es: \" + x);\n\nx = 16;\nx <<= 2;        // Asignación de desplazamiento a la izq.\nconsole.log(\"Ahora x vale 16. Si deplazamos dos bits a la izquierda obtenemos el valor: \" + x);\n\nx = 16;\nx >>= 2;        // Asignación de desplazamiento a la der.\nconsole.log(\"Ahora x vale 16. Si desplazamos 2 bits a la derecha obtenemos el valor: \" + x);\n\nx = 10;\nx &= 2;         // Asignación AND bit a bit\nconsole.log(\"Ahora x vale 10. Si hacemos una operación AND bit a bit con 2 obtenemos el valor: \" + x);\n\nx = 10;\nx ^= 12;         // Asignación XOR bit a bit\nconsole.log(\"Ahora x vale 10. Si hacemos una operación XOR bit a bit con 12 obtenemos el valor: \" + x);\n\nx = 10;\nx |= 2;         // Asignación OR bit a bit\nconsole.log(\"Ahora x vale 10. Si hacemos la operación OR bit a bit con 2 obtenemos el valor: \" + x);\n\nx = 5;\nx &&= 2;        // Asignación AND lógico (es equivalente a \"if(x){x=2}\")\nconsole.log(\"Ahora x vale 5. Si hacemos la operación AND lógico con 2 obtenemos el valor: \" + x);\n\nx = 0;\nx ||= 2;        // Asignación OR lógico (es equivalente a \"x=x||y\")\nconsole.log(\"Ahora x vale 0. Si hacemos la operación OR lógico con 2 obtenemos el valor: \" + x);\n\nx = null;\nx ??= 5;        // Asignaciónde anulación lógica\nconsole.log(\"Ahora x vale NULL. Si hacemos la opereación de anulación lógica con 5 obtenemos el valor: \"+ x);\n\n// Operadores de comparación\nx = 1;     \nlet y = x == 1;  // Igual\nconsole.log(\"Ahora x vale 1. Si hacemos una comparación de igualdad con 1 obtenemos el valor: \" + y);\nlet k = x == 4;\nconsole.log(\"Mientras que si lo comparamos con 4 obtenemos: \" + k);\n\nx = 4\ny = x != 3;     // Distinto de\nconsole.log(\"Ahora x vale 4. Si hacemos una comparación de desigualdad con 3 obtenemos que: \" + y);\nk = x != 4;\nconsole.log(\"Mientras que si lo comparamos con 4 obtenemos que: \" + k)\n\nx = 1;\ny = x === 1;    // Estrictamente igual\nconsole.log(\"Ahora x vale 1. Si hacemos una comparación de estricta igualdad con 1 entero obtenemos que: \" + y);\nk = x === \"1\";\nconsole.log(\"Mientras que si lo comparamos con 1 en string obtenemos que: \" + k);\n\nx = 3;\ny = x !== 4;    // Desigualdad estricta\nconsole.log(\"Ahora x vale 3. Si hacemos una comparación de desigualdad con 4 obtenemos que: \" + y);\nk = x !== 3;\nconsole.log(\"Mientras que si lo comparamos con 3 obtenemos: \" + k);\n\n\nx = 1;\ny = x > 0;      // Mayor que\nconsole.log(\"Ahora x vale 1. Si hacemos una comparación de mayor que 0 obtenemos: \" + y);\nk = x > 1;\nconsole.log(\"Mientras que si lo comparamos con 1 obtenemos: \" + k);\n\n\nx = 0;\ny = x >= 0;     // Mayor o igual que\nconsole.log(\"Ahora x vale 0. Si hacemos una comparación de mayor o igual que 0 obtenemos: \" + y);\nk = x >= -1;\nconsole.log(\"Mientras que si lo comparamos con -1\")\n\nx = 1;\ny = x < 2;      // Menor que\nconsole.log(\"Ahora x vale 1. Si hacemos una comparación de menor que 2 obtenemos: \" + y);\nk = x < 1;\nconsole.log(\"Mientras que si lo comparamos con 1: \" + k);\n\nx = 1;\ny = x <= 1;     // Menor o igual que\nconsole.log(\"Ahora x vale 1. Si hacemos una comparación de menor que 2 obtenemos: \" + y);\nk = x <= 2;\nconsole.log(\"Mientras que si lo comparamos con 2: \" + k);\n\n\n// Operadores aritméticos\nx = 12 % 5;     // Residuo\nconsole.log(\"El residuo de 12 entre 5 es: \" + x);\n\n++x;        // Incremento\nconsole.log(\"Tras ejecutar el incremento de x obtenemos: \" + x);\n\n--x;        // Decremento\nconsole.log(\"Tras ejecutar el decremento de x obtenemos: \" + x);\n\nx = -x;         // Negación unaria\nconsole.log(\"Tras ejecutar la negación unaria de x obtenemos: \" + x);\n\nx = +x;         // Positivo unario\nconsole.log(\"Tras ejecutar el positivo unario de x obtenemos: \" + x);\n\nx = 2;\nx = x ** 4;     // Exponenciación\nconsole.log(\"Ahora x vale 2. Si lo elevamos a 4 obtenemos: \" + x);\n\n// Operadores bit a bit\nx = 5 & 3\nconsole.log(\"El operador AND a nivel de bits entre 5 y 3 retorna un valor de: \" + x);      // AND a nivel de bits \n\nx = 5 | 3;      // OR a nivel de bits\nconsole.log(\"El operador OR a nivel de bits entre 5 y 3 retorna un valor de: \" + x);\n\n5 ^ 3;      // XOR a nivel de bits\nconsole.log(\"El operador XOR a nivel de bits entre 5 y 3 retorna un valor de \" + x);\n\nx = ~5;        // NOT a nivel de bits\nconsole.log(\"El operador NOT a nivel de bits de 5 retorna un valor de: \" + x);\n\nx = 5 << 1;     // Desplazamiento a la izquierda\nconsole.log(\"Con el desplazamiento de bits a la izquierda entre 5 y 1 obtenemos un valor: \" + x);\n\nx = 10 >> 1;     // Desplazamiento a la derecha\nconsole.log(\"Con el desplazamiento de bits a la derecha entre 10 y 1 obtenemos un valor: \" + x);\n\nx = -10 >>> 1;    // Desplazamiento a la derecha de relleno cero\nconsole.log(\"Con el desplazamiento de bits a la derecha de relleno 0 entre -10 y 1 obtenemos un valor: \" + x);\n\n\n// Operadores lógicos\nlet a = true;\nlet b = true;\nif(a && b) {    // AND lógico\n    console.log(\"Este mensaje se muestra dado que hemos hecho una comparación de AND lógico entre 'a' y 'b' siendo ambos true\");\n}\n\nb = false;\nif(a || b) {     // OR lógico\n    console.log(\"Este mensaje se muestra a pesar de 'b' ser false y 'a' true, dado que se ha hecho una operación de OR lógico\");\n}\n\nif(!b) {        // NOT lógico\n    console.log(\"Este mensaje se muestra dado que hemos hecho una operación de NOT lógico con 'b' siendo este false\")\n}         \n\n// Operadores de cadena\nlet myString = \"Esto son\";\nconsole.log(myString + \" dos cadenas de texto\");\n\n// Operador condicional (ternario) (condition ? val1: val2)\nlet age = 19\nlet statusFromAge = age >= 18 ? \"adult\" : \"minor\";\nconsole.log(\"Mediante un operador ternario, si la edad vale 19 su categoría es: \" + statusFromAge);\n\n\n// Operador coma\nx = 2;\nlet array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\nlet bidimensionalArray = [x, x, x, x, x]\nfor (let i = 0, j = 9; i <= j; i++, j--) {                          // Coma\n    console.log(\"array[\" + i + \"][\" + j + \"] = \" + array[i][j]);\n}\n\n// Operadores unarios (operadores con un solo operando)\nlet myObject = {h : 4}          // Delete\ndelete myObject.h;\n\nconsole.log(\"La variable 'myObject' es de tipo: \" + (typeof myObject));    // Typeof\n\n// void expression; -> Operador tipo void (retorna vacío)\n\n// Operadores relacionales\nlet person = {\n    name: \"r4kso\",\n    age: 22\n}\nconsole.log(\"¿Existe la propiedad 'age' en la variable 'person'?: \" + (\"age\" in person)); // In\n\nlet colors = [\"red\", \"blue\", \"green\"]\nconsole.log(\"¿Es la variable colors una instancia de array?: \" + (colors instanceof Array));   // Instance Of\n\n// ESTRUCTURAS DE CONTROL:\n// If -> Ya la hemos usado anteriormente\n// Switch\nlet day = \"Monday\";\nswitch (day) {\n  case \"Monday\":\n    console.log(\"It's Monday!\");\n    break;\n\n  case \"Tuesday\":\n    console.log(\"It's Tuesday!\");\n    break;\n\n  case \"Wednesday\":\n    console.log(\"It's Wednesday!\");\n    break;\n\n  case \"Thursday\":\n    console.log(\"It's Thursday!\");\n    break;\n\n  case \"Friday\":\n    console.log(\"It's Friday!\");\n    break;\n\n  default:\n    console.log(\"It's the weekend!\");\n    break;\n}\n\n// For -> Ya lo hemos usado anteriormento\n// While\nlet contador = 1;\nwhile (contador <= 5) {\n  console.log(\"Iteración número \" + contador);\n  contador++;\n}\n\n// Do while\ncontador = 1;\ndo {\n  console.log(\"Iteración número \" + contador);\n  contador++;\n} while (contador <= 5);\n\n\n// EJERCICIO EXTRA\n/* Programa que imprima por consola todos los números comprendidos entre 10 y 55 (incluidos),\n pares, y que no son ni el 16 ni múltiplos de 3.*/\n\nfor(let i = 10; i <= 55; i++) {\n    if ((i % 2 == 0) && (i != 16) && (i % 3 != 0)) {\n        console.log(i)\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/ralphmcralph.js",
    "content": "// Ejemplos de todos los operadores de Javascript\r\n\r\n// Asignación\r\n\r\nlet a = 1;\r\n\r\n// Asignación de suma\r\n\r\na += 1;\r\n\r\n// Asignación de resta\r\n\r\na -= 1;\r\n\r\n// Asignación de multiplicación\r\n\r\na *= 2;\r\n\r\n// Asignación de división\r\n\r\na /= 2;\r\n\r\n// Asignación de resto\r\n\r\na %= 2;\r\n\r\n// Asignación de exponente\r\n\r\na **= 2;\r\n\r\n// Left shift\r\n\r\na <<= 2;\r\n\r\n// Right shift\r\n\r\na >>= 2;\r\n\r\n// Unsigned right shift\r\n\r\na >>>= 2;\r\n\r\n// Asignación BITWISE AND\r\n\r\nlet b = 5;\r\n\r\nb &= 2;\r\n\r\n// BITWISE XOR\r\n\r\nb ^= 2;\r\n\r\n// BITWISE OR\r\n\r\nb |= 2;\r\n\r\n// Deestructuración\r\n\r\nconst foo = [\"one\", \"two\"];\r\n\r\nconst one = foo[0];\r\nconst two = foo[1];\r\n\r\n// Comparación\r\n\r\n// Igual\r\n\r\nvar num1 = 1;\r\n\r\nconsole.log(num1 == 1);\r\n\r\n// No igual\r\n\r\nconsole.log(num1 != 1);\r\n\r\n// Igual estricto\r\n\r\nconsole.log(num1 === 1);\r\n\r\n// No igual estricto\r\n\r\nconsole.log(num1 !== 1);\r\n\r\n// Greater than\r\n\r\nconsole.log(num1 > 1);\r\n\r\n// Greater than or equal\r\n\r\nconsole.log(num1 >= 1);\r\n\r\n// Less than\r\n\r\nconsole.log(num1 < 1);\r\n\r\n// Less than or equal\r\n\r\nconsole.log(num1 <= 1);\r\n\r\n// ARITMÉTICOS\r\n\r\n// Módulo\r\nconsole.log(12 % 5);\r\n\r\n// Incremento\r\n\r\nlet x = 3\r\n\r\nconsole.log(++x);\r\nconsole.log(x++);\r\nconsole.log(x);\r\n\r\n// Decremento\r\n\r\nlet y = 3\r\n\r\nconsole.log(--y);\r\nconsole.log(y--);\r\nconsole.log(y);\r\n\r\n// Negación unitaria\r\n\r\nlet z = 3\r\nconsole.log(-z);\r\n\r\n// Suma unitaria (intenta convertir el operando a número)\r\n\r\nlet num3 = true;\r\n\r\nconsole.log(+num3);\r\n\r\n// Concatenación de strings\r\n\r\nconsole.log(\"Hola\" + \"mundo\");\r\n\r\nlet myString = \"Hola\"\r\n\r\nconsole.log(myString += \"mundo\");\r\n\r\n// Condicionales\r\n\r\nvar age = 18;\r\n\r\nconst adultOrNot = age >= 18 ? \"Adulto\" : \"Menor\"\r\n\r\nconsole.log(adultOrNot);\r\n\r\nif (age >= 18) {\r\n    console.log(\"Adulto\");\r\n\r\n} else {\r\n    console.log(\"Menor\");\r\n\r\n}\r\n\r\n// Tipo de variable\r\n\r\nconsole.log(typeof adultOrNot);\r\n\r\n\r\n// In\r\n\r\nconst myCar = { make: \"Aston Martin\", model: \"AMR25\", year: 2025 };\r\nconsole.log(\"make\" in myCar);\r\nconsole.log(\"color\" in myCar);\r\n\r\n\r\n// Bucle for\r\n\r\nfor (i = 0; i <= 2; i++) {\r\n    console.log(`Iteración nº ${i}`);\r\n}\r\n\r\n// Bucle while\r\n\r\ni = 0;\r\n\r\nwhile (i <= 2) {\r\n    console.log(`Iteración nº ${i}`);\r\n    i++;\r\n}\r\n\r\n// Manejo de excepciones\r\n\r\ntry {\r\n    console.log(Hola);\r\n\r\n} catch {\r\n    console.log(\"Se ha producido un error\");\r\n} finally {\r\n    console.log(\"Ha finalizado el manejo de errores\");\r\n\r\n}\r\n\r\n\r\n/* DIFICULTAD EXTRA:\r\n * Crea un programa que imprima por consola todos los números comprendidos\r\n * entre 10 y 55(incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\r\n */\r\n\r\nfor (i = 10; i <= 55; i++) {\r\n    if (i % 2 == 0 && i != 16 && i % 3 != 0) {\r\n        console.log(i);\r\n    }\r\n}\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/raulG91.js",
    "content": "//Arimethic operators\n\nlet a = 2;\nlet b = 3;\n\n//Sum \nlet sum = a+b;\nconsole.log(\"Sum: \", sum);\n\n//Diff\nlet diff = a-b;\nconsole.log(\"Diff: \", diff);\n\n//Multiply \nlet multiply = a*b;\nconsole.log(\"Mltiply: \",multiply);\n\n//Division \nlet division = b/a;\nconsole.log(\"Division: \",division);\n\n//Remainder\nlet remainder = b%a;\nconsole.log(\"Module: \", remainder);\n\n//Pow \nlet pow = a**b;\nconsole.log(\"Pow: \",pow);\n\n//Logical operators\nconsole.log(\"***Logical operators***\");\n\n//And\nlet and = true && false;\nconsole.log(\"And: \", and);\n\n//OR\nlet or = false || true;\nconsole.log(\"Or: \", or);\n\n//Not\nlet not = !(true);\nconsole.log(\"Not: \", not);\n\n//Comparassion\nconsole.log(\"***Comparassion***\");\n\n//Equal \nlet equal = a==b;\nconsole.log(\"Equal: \",equal);\n\n//Not equal\nlet not_equal = a!=b;\nconsole.log(\"Not equal: \", not_equal);\n\n//Bigger\nlet bigger = a > b;\nconsole.log(\"Bigger: \",bigger);\n\n//Bigger or equal\nlet bigger_equal = a >= b;\nconsole.log(\"Bigger or equal: \", bigger_equal);\n\n//Lower \nlet lower = a < b;\nconsole.log(\"Lower: \", lower);\n\n//Lower or equal\nlet lower_equal = a <= b;\nconsole.log(\"Lower or equal: \", lower_equal);\n\n//Assignation\nlet c = 10;\nconsole.log(\"= \", c);\n\n//Beloning\nlet array = [3,5,0,1];\nlet belong = 3 in array;\nconsole.log(\"IN: \",belong);\n\n//Identity\nlet identity = a ===b;\nconsole.log(\"Identity: \",identity);\n\n//Bits \nconsole.log(\"***Bits***\");\n\n//And\nlet bits_and = 5 & 3;\nconsole.log(\"&: \",bits_and);\n\n//Or\nlet bits_or = 5 | 3;\nconsole.log(\"|: \", bits_or);\n\n// XOR\nlet bits_xor = 5 ^ 3;\nconsole.log(\"^: \",bits_xor);\n\n// Not\nlet bits_not = ~ 5;\nconsole.log(\"~: \",bits_not);\n\n// Control \nconsole.log(\"***If statements***\")\n//If\nif(a<b){\n    console.log(\"If statement\")\n}\nelse{\n    console.log(\"Else statement\");\n}\n//inline if\n(a<b)? console.log(\"If with ?\"):console.log(\"else with ?\");\n\n//Switch\n\nlet color = \"orange\";\n\nswitch(color){\n    case \"orange\":\n        console.log(\"orange color\");\n        break;\n    case \"blue\":\n        console.log(\"blue color\");\n        break;\n    default: \n        console.log(\"Default option\") ;\n        break;       \n}\n\n\n//Loops\nconsole.log(\"***While***\");\n\nwhile(true){\n\n    console.log(\"While loop\");\n    break;\n}\n\nconsole.log(\"***for loop***\");\n\nfor(let i = 0;i<3;i++){\n\n    console.log(i);\n}\n\n//Do while loop\nconsole.log(\"***DO while***\");\n\nlet j=0;\n\ndo{\n    console.log(j);\n    j++;\n\n}while(j<2);\n\n//Exception  \nconsole.log(\"***Exception***\")\ntry{\n\n  f\n}catch(err){\n    console.log(err.message);\n}\n\n//Extra exercise\n\nfor(let index = 10; index <=55;index++){\n\n    if(index%2==0 && index !=16 && index%3 != 0){\n  \n      console.log(index);\n    }\n  }"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/reinaldosanchez.js",
    "content": "//operadores\n\n//aritmeticos\n//suma\nconsole.log(2 + 2);\n//resta\nconsole.log(2 - 2);\n//multiplicacion\nconsole.log(2 * 2);\n//division\nconsole.log(2 / 2);\n//asignacion\nlet x = 2; console.log(x);\nx += 2; console.log(x);\nx -= 2; console.log(x);\nx *= 2; console.log(x);\nx /= 2; console.log(x);\nx %= 2; console.log(x);\nx **= 2; console.log(x);\n//comparacion\nconsole.log(2 == 2);\nconsole.log(2 === 2);\nconsole.log(2 != 2);\nconsole.log(2 !== 2);\nconsole.log(2 > 2);\nconsole.log(2 < 2);\nconsole.log(2 >= 2);\nconsole.log(2 <= 2);\n//lógicos\nconsole.log(true && true);  //verdadero\nconsole.log(true && false); //falso\nconsole.log(false && true); //falso\nconsole.log(false && false); //falso\nconsole.log(true || true);  //verdadero\nconsole.log(true || false); //verdadero\nconsole.log(false || true); //verdadero\nconsole.log(false || false); //falso\nconsole.log(!true); //falso\nconsole.log(!false); //verdadero\n\n//operadores de cadena\nconsole.log(\"Hola\" + \" \" + \"Mundo\");\n//operador condicional\nlet edad = 18;\nlet mensaje = edad >= 18 ? \"Mayor de edad\" : \"Menor de edad\";\nconsole.log(mensaje);\n//operador coma\nlet a = 1, b = 2, c = 3;\nconsole.log(a, b, c);\n//operador de incremento\nlet d = 1;\nconsole.log(d++);\n//operador de decremento\nlet e = 1;\nconsole.log(e--);\n//operador de negacion\nlet f = 1;\nconsole.log(-f);\n//operador bit a bit\nlet g = 1;\nconsole.log(g & 1);\nconsole.log(g | 1);\nconsole.log(g ^ 1);\nconsole.log(~g);\nconsole.log(g << 1);\nconsole.log(g >> 1);\nconsole.log(g >>> 1);\n// operador identidad\nlet h = 1;\nconsole.log(h === 1);\n\n//estructuras de control\n\n//condicionales\nif (2 > 2) {\n    console.log(\"2 es mayor que 2\");\n} else if (2 < 2) {\n    console.log(\"2 es menor que 2\");\n} else {\n    console.log(\"2 es igual que 2\");\n}\n//iterativas\nfor (let i = 0; i < 2; i++) {\n    console.log(i);\n}\n//excepciones\ntry {\n    console.log(\"Intentando acceder a una variable que no existe\");\n    console.log(x);\n} catch (error) {\n    console.log(error);\n}\n//switch\nlet numero2 = 2;\nswitch (numero) {\n    case 1:\n        console.log(\"1\");\n        break;\n    case 2:\n        console.log(\"2\");\n        break;\n    default:\n        console.log(\" Otro\");\n}\n// while\nlet numero3 = 2;\nwhile (numero < 2) {\n    console.log(numero);\n    numero++;\n}\n// do while\nlet numero = 2;\ndo {\n    console.log(numero);\n    numero++;\n} while (numero < 2);\n// for\nfor (let i = 0; i < 2; i++) {\n    console.log(i);\n}\n\n//reto\nconsole.log(\"--- DIFICULTAD EXTRA ---\");\n\nfor (let i = 10; i <= 55; i++) {\n    if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n        console.log(i);\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/rlores-edison.js",
    "content": "//EJERCICIOS:\n\n//1. Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n\n// Aritméticos (+, -, *, /, %, etc.):\n\nconsole.log(\"Aritméticos:\");\n\nconst suma = 10 + 20;\nconsole.log(suma);\n\nconst resta = 20 - 10;\nconsole.log(resta);\n\nconst multiplicacion = 10 * 20;\nconsole.log(multiplicacion);\n\nconst exponenciacion = 10 ** 20;\nconsole.log(exponenciacion);\n\nconst división = 10 / 20;\nconsole.log(división);\n\nconst modulo = 10 % 20;\nconsole.log(modulo);\n\n\n// Lógicos (!, &&, ||)\nconsole.log(\"Lógicos:\");\n\n// AND\n\nlet and = 10 + 3 === 13 && 5 - 1 === 4;\nconsole.log(\"AND &&: 10 + 3 === 13 and 5 - 1 === 4 es:\", and);\n\n//OR\nlet or = 10 + 3 === 13 || 5 - 1 === 4;\nconsole.log(\"OR ||: 10 + 3 === 13 or 5 - 1 === 4 es:\", or);\n\n//NOT\nlet not = !(10 + 3 === 13);\nconsole.log(\"NOT !: 10 + 3=== 13 es:\", not);\n\n\n\n// De comparación (==, ===, !=, !==, >, <, >=, <=)\nconsole.log(\"De comparación:\");\n\nconst igualdadTipoValor = 10 === 10; //igual valor y tipo, true or false\nconsole.log(\"Igualdad: \", igualdadTipoValor);\n\nconst desigualdadTipoValor = 10!== 10; // desigual valor y tipo\nconsole.log(\"Desigualdad: \", desigualdadTipoValor);\n\nconst igualdad = 10 == 10; // igual\nconsole.log(\"Igualdad: \", igualdad);\n\nconst desigualdad = 10 != 10; // desigual\nconsole.log(\"Desigualdad: \", desigualdad);\n\nconst mayor = 12 > 10;\nconsole.log(\"Mayor: \", mayor);\n\nconst mayorOigual = 12 >= 10;\nconsole.log(\"Mayor o igual: \", mayorOigual);\n\nconst menor = 12 < 10;\nconsole.log(\"Menor: \", menor);\n\nconst menorOigual = 12 <= 10;\nconsole.log(\"Menor o igual: \", menorOigual);\n\n\n\n// Asignación (=, +=, -=, *=, /=, etc.)\nconsole.log(\"Asignación:\");\nlet a = 10;\nconsole.log(\"= \", a);\n\na += 5; //añade 5 a la variable a\nconsole.log(\"= \", a);\n\nlet x = 50;\nx -= 5; //sustrae 5 a la variable x\nconsole.log(\"= \", x);\n\nlet y = 500;\ny *= 5; //multiplica 5 a la variable y\nconsole.log(\"= \", y);\n\nlet z = 600;\nz /= 5; //divide 5 a la variable z\nconsole.log(\"= \", z);\n\nlet w = 600;\nw %= 5; //asigna un resto/módulo a la variable w: w tiene como valor el resto, que es 0.\nconsole.log(\"= \", w);\n\nx <<= y; // Asignación de desplazamiento a la izquierda: x = x << y\nx >>= y; // Asignación de desplazamiento a la derecha: x = x >> y\nx >>>= y; // Asignación de desplazamiento a la derecha sin signo: x = x >>> y\nx &= y; // Asignación AND bit a bit: x = x & y\nx ^= y; // Asignación XOR bit a bit\nx |= y; // Asignación OR bit a bit: x = x | y\nx && y; // Asignación AND lógico: x && (x = y)\nx ||= y; // Asignación OR lógico: x || (x = y)\nx ??= y; // Asignación de anulación lógica: x ?? (x = y)\n\n\n//Bitwise (&, |, ^, ~, <<, >>)\nconsole.log(\"Bitwise:\");\n// a & x; // AND a nivel de bits\n// a | x; // OR a nivel de bits\n// a ^ x; // XOR a nivel de bits\n// ~ a; // NOT a nivel de bits\n// a << x; // Desplazamiento a la izquierda\n// a >> x; // Desplazamiento a la derecha de propagación de signo\n// a >>> x; // Desplazamiento a la derecha de relleno de cero\n\nlet e = 5;\nlet b = 3;\n\nconsole.log(\"Value of e:\", e);\nconsole.log(\"Value of b:\", b);\n\n\nlet resultAnd = e & b;\nlet resultOr = e | b;\nlet resultXor = e ^ b;\n\nconsole.log(\"e & b =\", resultAnd);\nconsole.log(\"e | b =\", resultOr);\nconsole.log(\"e ^ b =\", resultXor);\n\n// Print NOT operation\nconsole.log(\"~5 =\", ~e);\n\n// Print shift operations\nconsole.log(\"e << 1 =\", e << 1);\nconsole.log(\"b >> 1 =\", b >> 1);\nconsole.log(\"5 >>> 2 =\", 5 >>> 2);\n\n\n//Ternary operator (?)\nlet height = 1.50;\nvar status = height >= 1.50 ? \"Tall enough to ride\" : \"Too short to ride\";\n \n\n\n// 2 . Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n//  que representen todos los tipos de estructuras de control que existan\n//  en tu lenguaje:\n\n//  Condicionales:\n\nconsole.log(\"Condicionales:\");\n\nconst myString = \"raquelLoresDev\";\n\nif (myString === \"raquelLoresDev\") {\n    console.log(\"Strings are equal\");\n} else if (myString === \"raquel\") {\n    console.log(\"My string is 'raquel'\");\n} else {\n    console.log(\"Strings are not equal and it is not 'raquel'\");\n}\n\n\n//  Iterativas:\nconsole.log(\"Iterativas (bucle for y while):\");\n\nfor (let i = 0; i < 10; i++) {\n    console.log(i);\n}\n\nlet i = 0;\nwhile (i < 10) {\n    console.log(i);\n    i++;\n} \n\n\n//  Manejo de excepciones o errores:\nconsole.log(\"Manejo de excepciones o errores:\");\n\ntry {\n    throw new Error(\"Error\");\n} catch (error) {\n    console.log(error);\n} finally {\n    console.log(\"Finalizado el manejo de excepciones\");\n}     \n\n\n\n// Dificultad EXTRA (opcional):\nconsole.log(\"Dificultad EXTRA:\");\n//  * Crea un programa que imprima por consola todos los números comprendidos entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\n\nfor (let i = 10; i <= 55; i++) {\n  if (i % 2 === 0 && i !== 16 && !(i % 3)) {\n    console.log(i);\n    if (i === 54) { // Condición para parar el bucle\n      break;\n    }\n  }\n}\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/robmxz.js",
    "content": "// Reto #01 -> OPERADORES Y ESTRUCTURAS DE CONTROL\n\n// Operadores\n\n// 1. Aritméticos\n\n// 1.1 Suma \"+\"\nlet suma = 1 + 2; // Suma los valores 1 y 2\nconsole.log(\"Resultado de la suma:\", suma);\n\n// 1.2 Resta \"-\"\nlet resta = 24 - 20; // Resta los valores 24 y 20\nconsole.log(\"Resultado de la resta:\", resta);\n\n// 1.3 Multiplicación \"*\"\nlet multiplicacion = 2 * 4; // Multiplica los valores 2 y 4\nconsole.log(\"Resultado de la multiplicación:\", multiplicacion);\n\n// 1.4 División \"/\"\nlet division = 10 / 2; // Divide los valores 10 y 2\nconsole.log(\"Resultado de la división:\", division);\n\n// 1.5 Módulo \"%\"\nlet modulo = 10 % 3; // Obtiene el residuo de la división de los valores 10 y 3\nconsole.log(\"Resultado del módulo:\", modulo);\n\n// 1.6 Exponenciación \"**\"\nlet exponenciacion = 2 ** 3; // Eleva el valor 2 a la potencia 3\nconsole.log(\"Resultado de la exponenciación:\", exponenciacion);\n\n// 2. Lógicos\n\n// 2.1 AND \"&&\" -> compara si las 2 condiciones son verdaderas\nlet and = 2 > 1 && 24 < 20;\nconsole.log(\"Resultado del operador &&:\", and);\n\n// 2.2 OR \"||\" -> compara si al menos una de las 2 condiciones es verdadera\nlet or = 2 > 1 || 24 < 20;\nconsole.log(\"Resultado del operador ||:\", or);\n\n// 2.3 NOT \"!\" -> niega el valor de la condición\nlet not = !(24 < 20);\nconsole.log(\"Resultado del operador !:\", not);\n\n// 3. Comparación\n\n// 3.1 Igualdad \"==\" -> compara si los valores son iguales\nlet igualdad = 1 == 1;\nconsole.log(\"Resultado del operador =:\", igualdad);\n\n// 3.2 Desigualdad \"!=\" -> compara si los valores son diferentes\nlet desigualdad = 24 != 20;\nconsole.log(\"Resultado del operador !=:\", desigualdad);\n\n// 3.3 Estrictamente igual \"===\" -> compara si los valores y tipos de datos son iguales\nlet estrictamenteIgual = 20 === \"20\";\nconsole.log(\"Resultado del operador ===\", estrictamenteIgual);\n\n// 3.4 Estrictamente desigual \"!==\" -> compara si los valores y tipos de datos son diferentes\nlet estrictamenteDesigual = \"24\" !== 24; \nconsole.log(\"Resultado del operador !==:\",estrictamenteDesigual);\n\n// 3.5 Mayor que \">\" -> compara si el valor de la izquierda es mayor que el de la derecha\nlet mayorQue = 24 > 20;\nconsole.log(\"Resultado del operador >:\", mayorQue);\n\n// 3.6 Menor que \"<\" -> compara si el valor de la izquierda es menor que el de la derecha\nlet menorQue = 20 < 24;\nconsole.log(\"Resultado del operador <:\", menorQue);\n\n// 3.7 Mayor o igual que \">=\" -> compara si el valor de la izquierda es mayor o igual que el de la derecha\nlet mayorIgual = 20 >= 20;\nconsole.log(\"Resultado del operador >=:\", mayorIgual);\n\n// 3.8 Menor o igual que \"<=\" -> compara si el valor de la izquierda es menor o igual que el de la derecha\nlet menorIgual = 24 <= 24;\nconsole.log(\"Resultado del operador <=:\", menorIgual);\n\n// 4. Asignación\n\n// 4.1 Asignación básica \"=\"\nlet asignacion = \"Hola\";\nconsole.log(\"Valor de la variable:\", asignacion);\n\n// 4.2 Asignación de adición \"+=\" -> (a = a + b)\nlet asignacionAdicion = 3;\nasignacionAdicion += 6;\nconsole.log(\"Valor de la variable:\", asignacionAdicion);\n\n// 4.3 Asignación de sustracción \"-=\" -> (a = a - b)\nlet asignacionSustraccion = 3;\nasignacionSustraccion -= 1;\nconsole.log(\"Valor de la variable:\",asignacionSustraccion);\n\n// 4.4 Asignación de multiplicación \"*=\" -> (a = a * b)\nlet asignacionMultiplicacion = 3;\nasignacionMultiplicacion *= 2;\nconsole.log(\"Valor de la variable:\",asignacionMultiplicacion);\n\n// 4.5 Asignación de división \"/=\" -> (a = a / b)\nlet asignacionDivision = 8;\nasignacionDivision /= 2; // Divide el valor 2 a la variable\nconsole.log(\"Valor de la variable:\", asignacionDivision);\n\n// 5. Ternario \"?\"\nlet ternario = 24 > 20 ? \"Verdadero\" : \"Falso\"; // Si 24 es mayor que 20, asigna \"Verdadero\", de lo contrario asigna \"Falso\"\nconsole.log(\"Resultado del operador ternario:\", ternario);\n\n// 6. Operadores de bits\n\n// 6.1 AND \"&\" -> compara bit a bit si ambos son \"1\" retorna 1 de lo contario 0\nlet bitAnd = 0b1111 & 0b1001;\nconsole.log(\"Resultado del operador &:\", bitAnd.toString(2));\n\n// 6.2 OR \"|\" -> compara si al menos uno de los bits son \"1\" retorna 1 de lo contrario 0\nlet bitOr = 0b1111 | 0b1001;\nconsole.log(\"Resultado del operador |:\", bitOr.toString(2));\n\n// 6.3 XOR \"^\" -> retorna 1 si los bits son diferentes de lo contrario 0\nlet bitXor = 0b1111 ^ 0b1001;\nconsole.log(\"Resultado del operador ^:\", bitXor.toString(2));\n\n// 6.4 NOT \"~\" -> cambia el valor de los bits a su opuesto 1 por 0 y 0 por 1\nlet bitNot = ~0b1111;\nconsole.log(\"Resultado del operador ~:\", bitNot.toString(2));\n\n// 6.5 Desplazamiento a la izquierda \"<<\" -> desplaza los bits a la izquierda y los restantes se llenan con 0\nlet bitDesplazamientoIzquierda = 0b1111 << 2;\nconsole.log(\"Resultado del operador <<:\",bitDesplazamientoIzquierda.toString(2));\n\n// 6.6 Desplazamiento a la derecha \">>\" -> desplaza los bits a la derecha y los restantes se llenan con 0\nlet bitDesplazamientoDerecha = 0b1111 >> 2;\nconsole.log(\"Resultado del operador >>:\", bitDesplazamientoDerecha.toString(2));\n\n// Estructuras de control\n\n// 1. if\nif (10 > 4) {\n  console.log(\"Verdadero\");\n}\n\n// 2. if else\nif (4 > 10) {\n  console.log(\"Verdadero\");\n} else {\n  console.log(\"Falso\");\n}\n\n// 3. switch\nlet opcion = 1;\nswitch (opcion) {\n  case 1:\n    console.log(\"Opción 1\");\n    break;\n  case 2:\n    console.log(\"Opción 2\");\n    break;\n  default:\n    console.log(\"Opción no válida\");\n    break;\n}\n\n// 4. for\nfor (let i = 1; i <= 10; i++) {\n  console.log(\"Valor actual de i:\", i);\n}\n\n// 5. while\nlet condicion = true;\nwhile (condicion) {\n  console.log(\"Ciclo while\");\n  condicion = false;\n}\n\n// 6. do while\nlet condicion2 = false;\ndo {\n  console.log(\"Ciclo do while\");\n} while (condicion2);\n\n// Dificultad extra :)\n\n/*\n    Crea un programa que imprima por consola todos los números comprendidos\n    entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n*/\n\nfunction extra(a,b){\n    for(let i = a; i <= b; i++){\n        if(i % 2 == 0 && i != 16 && i % 3 != 0){\n        console.log(\"Número :\",i);\n        }\n    }\n}\nextra(10,55);\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/rserradev.js",
    "content": "// Ejemplos con operadores\n\n// Operadores de asignación\nlet asignacion = 1;\nasignacion += 1; //suma\nasignacion -= 1; //resta\nasignacion *= 1; //multriplicacion\nasignacion /= 1; //division\nasignacion %= 1; //porcentaje\nasignacion **= 1; //elevado o exponente\nasignacion <<= 1; //desplazar izquierda\nasignacion >>= 1; //desplazar derecha\nasignacion &= 1; //AND\nasignacion |= 1; //OR\nasignacion ||= 1; //OR logico\nasignacion ??= 1; //anulacion\n\n//Operadores de comparacion\nlet var1 = 1;\nlet var2 = 2;\n\nconsole.log(var1 == var2); //Igualdad (false)\nconsole.log(var1 != var2); //No es igual (true)\nconsole.log(var1 === var2); //Igualdad estrictor (False)\nconsole.log(var1 !== var2); //No es igualdad estricto (False)\nconsole.log(var1 > var2); //Mayor que (false)\nconsole.log(var1 < var2); //Menor que (true)\nconsole.log(var1 >= var2); //Mayor o igual que (False)\nconsole.log(var1 <= var2); //menor o Igualdad (true)\n\n//Operadores aritméticos\nconsole.log(++var2); //Incremento\nconsole.log(--var2); //Decremento\nconsole.log(-var2); //Negativo\nconsole.log(+var2); //Negativo\nconsole.log(var2 ** var2); //Exponente\n\n// Operadores bit a bit\nconsole.log(var2 & var2); // AND de bits\nconsole.log(var2 | var2); // OR de bits\nconsole.log(var2 ^ var2); // XOR de bits\nconsole.log(~var2); // NOT de bits\n\n// Operadores logicos\nlet var3 = 10;\nlet var4 = \"10\";\n\nconsole.log(var3 && var4); // AND Logico\nconsole.log(var3 || var4); // OR Logico\nconsole.log(!var3); // NOT Logico\n\n// Operadores de cadena\nconsole.log(\"Esta es una\" + \"cadena\");\n\n// Operadores condicionales (ternario)\nlet edad = 25;\nlet isOld = edad >= 18 ? true : false;\nconsole.log(isOld);\n\n// Operadores relacionales\nlet numeros = [1,2,3,4,5];\nconsole.log(0 in numeros);\nconsole.log(6 in numeros);\nlet numero55 = 55;\n\n// Imprimir por consola numeros pares entre 10 y 55 descartando el 16 y multiplos de 3\nfor (let index = 10; index <= numero55; index++) {\n    if (index != 16) {\n        for (let i = 0; i <= numero55; i++) {\n            if (2 * i == index) {\n            console.log(index);\n            }\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/saicobys.js",
    "content": "// # #01 OPERADORES Y ESTRUCTURAS DE CONTROL\n// > #### Dificultad: Fácil | Publicación: 02/01/24 | Corrección: 08/01/24\n\n// ## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n```;\n/* #### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**. */\n\n/* OPERADORES ARITMETICOS. */\nlet resultado = 5 + 3;\nlet diferencia = 13 - 7;\nlet producto = 9 * 9;\nlet cociente = 27 / 7;\nlet residuo = 9 % 3;\nlet aumento = 1;\naumento++;\nlet decremento = 20;\ndecremento--;\nlet potencia = 2 ** 3;\n\n/* ESTRUCTURAS DE CONTROL */\n\n// Sentencia if:\nif (edad >= 18) {\n  console.log(\"Eres mayor de edad\");\n}\n\n// Sentencia else\nif (edad >= 18) {\n  console.log(\"Eres mayor de edad\");\n} else {\n  console.log(\"Eres menor de edad\");\n}\n\n// Sentencia else if\nif (edad >= 18) {\n  console.log(\"Eres mayor de edad\");\n} else if (edad >= 13) {\n  console.log(\"Eres adolecente\");\n} else {\n  console.log(\"Eres un niño\");\n}\n\n// Bucle for\nfor (let i = 0; i < 5; i++) {\n  console.log(\"Number: \", i);\n}\n\n// Bucle while\nlet numero = 10;\nwhile (numero > 0) {\n  console.log(numero);\n  numero--;\n}\n\n// Sentencia break\nfor (let i = 0; i < 10; i++) {\n  if (i === 5) {\n    break;\n  }\n  console.log(i);\n}\n\n// Sentencia continue\nfor (let i = 0; i < 10; i++) {\n  if (i % 2 === 0) {\n    continue;\n  }\n  console.log(i);\n}\n\n// Sentencia switch\nlet dia = \"Lunes\";\nswitch (dia) {\n  case \"Lunes\":\n    console.log(\"Hoy es Lunes\");\n    break;\n\n  case \"Martes\":\n    console.log(\"Hoy es Martes\");\n    break;\n\n  case \"Miercoles\":\n    console.log(\"Hoy es Miercoles\");\n    break;\n\n  default:\n    console.log(\"No conozco ese dia\");\n}\n\n// Sentencia do...while\nlet num = 0;\ndo {\n  console.log(num);\n  num++;\n} while (num < 10);\n\n// Sentenci for...in\nlet persona = { nombre: \"Juan\", edad: 30 };\nfor (let propiedad in persona) {\n  console.log(propiedad + \": \" + persona[propiedad]);\n}\n\n// for...of\nlet num2 = [1, 2, 3, 4, 5];\nfor (let num2 of num2) {\n  console.log(num2);\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/samrdx.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n/////////--- aritmeticos ---//////////\n\n//suma \nconsole.log(\"la suma de 15 + 10 es: \" + (15 + 10));\n\n//resta \nconsole.log('la resta de 10-10 es: ' + (9 - 1));\n\n//multiplacion \nconsole.log('la multiplicacion de 5*10 es: ' + (5 * 10));\n\n//division\nconsole.log('la division de 10/2 es: ' + (10 / 2));\n\n//residuo de la division\nconsole.log('el residuo de la division de 10/3 es: ' + (10 % 3));\n\n//exponenciacion \nconsole.log('la exponenciacion de 2**3 es: ' + (2 ** 3));\n\n//incremento\nfor (let i = 2; i < 6; i++) {\n    console.log('el incremento de 2 es: ' + i);\n};\n\n//decremento\nfor (let i = 11; i > 7; i--) {\n    console.log('el decremento de 11 es: ' + i);\n};\n\n/////////--- comparacion ---//////////\n\n//igual \nconsole.log('10 es igual a 10: ' + (10 == 10));\n\n//estrictamente igual\nconsole.log('10 es estrictamente igual a 10: ' + (10 === 10));\n\n//diferente \nconsole.log('10 es diferente a 11: ' + (10 != 11));\n\n//estrictamente diferente\nconsole.log('10 es estrictamente diferente a 11: ' + (10 !== 11));\n\n//mayor que \nlet c = 15;\nlet d = 8;\nconsole.log('c es mayor que d: ' + (15 > 8));\n\n//menor que \nconsole.log('c es menor que d: ' + (15 < 8));\n\n//mayor o igual que \nconsole.log('c es mayor o igual que d: ' + (15 >= 8));\n\n//menor o igual que \nconsole.log('c es menor o igual que d: ' + (15 <= 8));\n\n/////////--- operadores logicos ---//////////\n\nlet numberA = 10;\nlet numberB = 20;\nlet numberC = 30;\n\nconsole.log((numberA > numberB) && (numberA < numberC));\n\n//or\nconsole.log((numberA > numberB) || (numberA < numberC));\n\n//negacion logica   \n\nlet esPerro = true;\n\nif (!esPerro){\n    console.log('el animal es un perro');\n}else{\n    console.log('el animal no es un perro'); // esto se imprimira ya que la negacion cambia un valor booleano a un valor contrario\n};\n\n/////////--- operadores de asignacion ---//////////\n\n//asignacion simple\nlet number1 = 20;\n\n//asignacion adicion\nnumber1 += 3\n\nconsole.log(number1)//number1 es 23 (20 + 3)\n\n//de sustraccion\nlet number2 = 40;\n\nnumber2 -= 4;\n\nconsole.log(number2)//number2 es 36 (40 - 4)\n\n//  asignacion multiplicacion\nlet number3 = 10;\n\nnumber3 *= 2;\n\nconsole.log(number3)//number3 es 20 (10 * 2)\n\n//asignacion division\nlet number4 = 80;\n\nnumber4 /= 4;\n\nconsole.log(number4)//number4 es 20 (80 / 4)\n\n//asignacion de modulo\nlet number5 = 50;\n\nnumber5 %= 7;\n\nconsole.log(number5)//number5 es 1 (50 % 7)\n\n//asignacion de exponenciacion\nlet number6 = 2;\n\nnumber6 **= 3;\n\nconsole.log(number6)//number6 es 8 (2 ** 3)\n\n//asignacion de concatenacion\nlet texto = \"Hola\";\ntexto += \" Mundo\";\nconsole.log(texto)//texto es \"Hola Mundo\"\n\n//---------------------operadores de identidad-----------------------------\n\n\n//igualdad estricta\n\nlet igual1 = 15;\nlet igual2 = 13;\n\nif (igual1 === igual2){\n    console.log(\"son iguales\");\n}else{\n    console.log(\"no es igual\");//no son iguales \n};\n\n//desigualdad estricta\n\nlet desigualdad = 15;\nlet desigualdad1 = 13;\n\nif (igual1 !== igual2){\n    console.log(\"son iguales\");//son iguales \n}else{\n    console.log(\"no es igual\");\n};\n\n//-----------------------------operadores de pertenencia-----------------------------\n\n//in\n// se usa para verificar una propiedad en un array u objeto \n\nconst persona = {\nnombre: \"Samuel\",\nedad:56\n};\n\nif (`nombre` in persona){\n    console.log(\"la propiedad nombre si existe\")\n}else{\n    console.log(\"la propiedad nombre no existe\")\n};\n\n//intanceof \n\n//se usa para verificar si un objeto es una instancia de una clase o contructor especifico \n\nlet fecha = new Date();\nlet esFecha = fecha instanceof  Date;\n\nconsole.log(esFecha);\n\n//---------- --------------------------dificultad--------------------------------------------------\n\n/* DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n\nfor (let i = 10; i < 56 ; i++){//usamos  un  ciclo for creamos la variable indice igualando a 10, si i e menor a 56 , i aumentara hasta 55\n    if(i === 16){//si i es igual a 16\n        continue;//se salta ese numero \n    }if(i % 3 === 0){//si i es multiplo de 3 \n        continue;//se salta el numero\n    }\n    console.log(i)\n};"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/sandracalatayud.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n\n/* \n    PUNTO 1\n    Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n    Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n    (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n*/\n\n//          TIPOS DE OPERADORES \n\n//------- OPERADORES DE ASIGNACIÓN -------\n\nlet a = 1;\n\nconsole.log( a = 2 );\nconsole.log( a += 2 );\nconsole.log( a -= 2 );\nconsole.log( a *= 2 );\nconsole.log( a /= 2 );\nconsole.log( a %= 4 );\nconsole.log( a **= 2 );\n\n//------- OPERADORES DE COMPARACIÓN -------\n\nlet b = 1;\nlet c = 4;\n\nconsole.log( b == c );\nconsole.log( b != c );\nconsole.log( b === c );\nconsole.log( b !== c );\nconsole.log( b > c );\nconsole.log( b < c );\nconsole.log( b >= c );\nconsole.log( b <= c );\n\n//------- OPERADORES ARITMÉTICOS -------\n\nlet d = 5;\n\nconsole.log( d % 3 );\nconsole.log( d + 3 );\nconsole.log( d - 3 );\nconsole.log( d++ );\nconsole.log( d-- );\nconsole.log( ++d );\nconsole.log( --d );\nconsole.log( d ** 3 );\n\n//------- OPERADORES LOGICOS -------\n\nlet e = 5;\nlet f = 3;\n\nconsole.log( e && f);\nconsole.log( e || f);\nconsole.log( e ?? f);\nconsole.log( !e );\n\n//------- OPERADORES DE STRING -------\n\nlet string  = \"cama\";\nstring += \"stro\";\nconsole.log(string)\n\nconsole.log(\"Podemos unir texto con un +\" + \" y eso hará que salga junto\");\n\n//------- OPERADORES CONDICIONAL -------\n\nlet adulto = 18;\nlet edad = 1;\n\nconsole.log( edad < adulto ? \"Es un niño\" : \"Es un adulto\");\n\n//------- OPERADOR COMA -------\n\n//Puede ser útil para usarlo en el bucle \"for\" de la siguiente forma:\n\nfor (let i = 0, j = 9; i <= j; i++, j--) {\n    \n  }\n\n//------- OPERADORES UNARIOS -------\n\n//  DELETE\n\n//Permite eliminar variables (si no están declaradas como \"var\" y propiedades de objetos).\n\nconst objeto = {\n  name: \"Sandra\"\n}\n\nconsole.log(objeto.name);\n\ndelete objeto.name;\n\nconsole.log(objeto.name);\n\n//  TYPEOF\n\n//Permite saber el tipo de dato\n\nlet type_string = \"Esto es un string\";\nlet type_number = 5;\nlet type_boolean = true;\n\nconsole.log( typeof(type_string) );\nconsole.log( typeof(type_number) );\nconsole.log( typeof(type_boolean) );\n\n//------- OPERADORES DE RELACIÓN -------\n\n//  IN  \n\n//Sirve para saber si es una propiedad de un objeto. Se puede aplicar tanto a objetos como arrays\n\nconst colores = [\"azul\", \"blanco\", \"amarillo\"];\nconst persona = {\n  nombre:\"Sandra\"\n}\n\nconsole.log(1 in colores);           //Para arrays\nconsole.log(7 in colores);           //Para arrays\nconsole.log(\"length\" in colores);    //\nconsole.log(\"nombre\" in persona);    //Para objetos\n\n//   INSTANCE OF\n\n//Sirve para saber si es un tipo de dato concreto\n\nlet numero = new Number(4);\n\nconsole.log(numero instanceof Number);\n\n/*\n  PUNTO 2\n    - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n    que representen todos los tipos de estructuras de control que existan\n    en tu lenguaje:\n    Condicionales, iterativas, excepciones...\n*/\nlet animales = [\"perro\", \"gato\", \"cuervo\", \"serpiente\", \"delfin\"];\nlet perro = \"perro\"\n\n//------- IF ELSE -------\n\nif ( animales.length <= 6 ){\n  console.log(\"Hay menos de 6 animales en el array\")\n} else if (animales.length >=6){\n  console.log(\"Hay más de 6 animales en el array\")\n}else {\n  console.log(\"Hay más de 6 animales en el array\")\n}\n\n//------- SWITCH -------\n\nswitch (perro){\n  case \"perro\": \n    console.log(\"Es un perro\");\n    break;\n  case \"gato\": \n    console.log(\"No es un perro\");\n    break;\n  default:\n    console.log(\"No está definido o es otro animal\")\n}\n\n//------- FOR -------\n\nfor (let i = 0; i < animales.length; i++) {\n  console.log(\"\\n\" +animales[i])  \n};\n\n//------- FOR IN -------\n\nfor (let i in animales){\n  console.log(animales[i]);\n  console.log(i);\n}\n\n//------- FOR OF -------\n\nfor (let i of animales){\n  console.log(i);\n}\n\n\n//------- DO WHILE -------\n\nlet num1 = 0;\n\ndo {\n  console.log(animales[num1]); \n  num1++\n}\nwhile (num1 < animales.length);\n\n//------- WHILE -------\n\nnum1 = 0; \n\nwhile (num1 < animales.length){\n  console.log(animales[num1]); \n  num1++;\n}\n\n//------- CONTROL DE EXCEPCIONES -------\n\nperro = \"gato\";\n\n//    THROW\n\nif (perro !== \"perro\"){\n  //  throw \"Esto es un error\";    //Comentado para que no bloquee la ejecución\n}\n\n//    TRY CATCH\n\ntry {\n  if (perro !== \"perro\"){\n    throw \"Esto es un error\";\n  }\n} catch (err){\n  console.log(perro);\n  console.log(err);\n} finally{\n  perro = \"perro\";\n}\n\n/*\n  PUNTO 3\n  Crea un programa que imprima por consola todos los números comprendidos\n  entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n*/\n\nfor (let i = 10; i <= 55; i++) {\n  if( i % 2 == 0 && i != 16 && i % 3 != 0 ){\n    console.log(i);\n  }\n}\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/sans6114.js",
    "content": "/*\n// Operadores Aritméticos\nlet num1 = 10;\nlet num2 = 5;\n\nconsole.log(\"Operadores Aritméticos:\");\nconsole.log(`Suma: ${num1} + ${num2} = ${num1 + num2}`); // Suma\nconsole.log(`Resta: ${num1} - ${num2} = ${num1 - num2}`); // Resta\nconsole.log(`Multiplicación: ${num1} * ${num2} = ${num1 * num2}`); // Multiplicación\nconsole.log(`División: ${num1} / ${num2} = ${num1 / num2}`); // División\nconsole.log(`Módulo: ${num1} % ${num2} = ${num1 % num2}`); // Módulo\n\n// Operadores de Asignación\nconsole.log(\"\\nOperadores de Asignación:\");\nlet result = 0;\nresult += num1; // Suma y asigna\nconsole.log(`Asignación de suma: result += ${num1} -> result = ${result}`);\nresult -= num2; // Resta y asigna\nconsole.log(`Asignación de resta: result -= ${num2} -> result = ${result}`);\nresult *= num2; // Multiplica y asigna\nconsole.log(`Asignación de multiplicación: result *= ${num2} -> result = ${result}`);\nresult /= num2; // Divide y asigna\nconsole.log(`Asignación de división: result /= ${num2} -> result = ${result}`);\n\n// Operadores de Comparación\nconsole.log(\"\\nOperadores de Comparación:\");\nconsole.log(`Es igual: ${num1} == ${num2} -> ${num1 == num2}`); // Igual\nconsole.log(`Es idéntico: ${num1} === ${num2} -> ${num1 === num2}`); // Idéntico, osea estrictamente igual a\nconsole.log(`Es diferente: ${num1} != ${num2} -> ${num1 != num2}`); // Diferente\nconsole.log(`Es diferente (estricto): ${num1} !== ${num2} -> ${num1 !== num2}`); // Diferente estricto\nconsole.log(`Es mayor: ${num1} > ${num2} -> ${num1 > num2}`); // Mayor\nconsole.log(`Es menor: ${num1} < ${num2} -> ${num1 < num2}`); // Menor\nconsole.log(`Es mayor o igual: ${num1} >= ${num2} -> ${num1 >= num2}`); // Mayor o igual\nconsole.log(`Es menor o igual: ${num1} <= ${num2} -> ${num1 <= num2}`); // Menor o igual\n\n// Operadores Lógicos\nconsole.log(\"\\nOperadores Lógicos:\");\nlet a = true;\nlet b = false;\nconsole.log(`Y (AND): ${a} && ${b} -> ${a && b}`); // AND\nconsole.log(`O (OR): ${a} || ${b} -> ${a || b}`); // OR\nconsole.log(`NO (NOT): !${a} -> ${!a}`); // NOT, es la negación\n\n// Operadores de Identidad\nconsole.log(\"\\nOperadores de Identidad:\");\nconsole.log(`Identidad: ${num1} === ${num1} -> ${num1 === num1}`); // Identidad\nconsole.log(`No identidad: ${num1} !== ${num2} -> ${num1 !== num2}`); // No identidad\n\n// Operadores de Pertenencia\nconsole.log(\"\\nOperadores de Pertenencia:\");\nlet array = [1, 2, 3, 4, 5];\nconsole.log(`¿1 pertenece al array? ${array.includes(1)}`); // Pertenencia\nconsole.log(`¿6 pertenece al array? ${array.includes(6)}`); // Pertenencia\n\n// Operadores de Bits (no los entendi mucho)\nconsole.log(\"\\nOperadores de Bits:\");\nlet bit1 = 5;  // 0101 en binario\nlet bit2 = 3;  // 0011 en binario\nconsole.log(`AND Bit a Bit: ${bit1} & ${bit2} = ${bit1 & bit2}`); // AND\nconsole.log(`OR Bit a Bit: ${bit1} | ${bit2} = ${bit1 | bit2}`); // OR\nconsole.log(`XOR Bit a Bit: ${bit1} ^ ${bit2} = ${bit1 ^ bit2}`); // XOR\nconsole.log(`Negación Bit a Bit: ~${bit1} = ${~bit1}`); // NOT\nconsole.log(`Desplazamiento Izquierda: ${bit1} << 1 = ${bit1 << 1}`); // Desplazamiento a la izquierda\nconsole.log(`Desplazamiento Derecha: ${bit1} >> 1 = ${bit1 >> 1}`); // Desplazamiento a la derecha\n\n\n//CONDICIONALES\n//IF ELSE\nconst numero = 15\nif (numero >= 10) {\n    if (numero == 10) {\n        console.log('el numero es 10')\n    } else {\n        console.log('numero no es 10, es mayor')\n    }\n} else {\n    console.log('el numero es menor a 10')\n}\nconst nombres = [\n    'santiago',\n    'juan',\n    'martin',\n    'natalia',\n    'pablo',\n]\n//SWITCH\nfor (let i = 0; i < nombres.length; i++) {\n    switch (nombres[i]) {\n        case 'santiago':\n            console.log(`hola ${nombres[i]}, en esta iteración estoy saludando a santi.`)\n            break;\n        case 'juan':\n            console.log(`hola ${nombres[i]}, en esta iteración estoy saludando a juan.`)\n            break;\n        case 'martin':\n            console.log(`hola ${nombres[i]}, en esta iteración estoy saludando a martin.`)\n            break;\n        default:\n            console.log('esta case va a imprimirse 2 veces')\n            break;\n    }\n}\n\n//CICLOS\n//WHILE\nlet miNombre = 'santi'\nwhile (miNombre.length <= 10) {\n    if (miNombre.length == 10) {\n        console.log('tu variable logro tener 10 caracteres')\n        break\n    }\n    console.log(miNombre)\n    miNombre += 'i'\n}\n//DO WHILE\nlet miNumero = 10\nwhile (miNumero > 20) {\n    console.log('se ejecuto el while')\n}\n\ndo {\n    console.log('se ejecuto el do while')\n} while (miNumero > 20)\n\n//FOR\nconst misNumeros = [\n    1,\n    2,\n    3,\n    4,\n    5,\n    6,\n]\nfor (let i = 0; i < misNumeros.length; i++) {\n        (misNumeros[i] % 2 === 0) ? console.log(`${misNumeros[i]}, es par`) : console.log(`no es par,`)\n}\n/*\n/* DIFICULTAD EXTRA (opcional):\n* Crea un programa que imprima por consola todos los números comprendidos\n* entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n*\n* Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n*/\n\n//forma 1\nfor (let i = 10; i <= 55; i++) {\n    if (i % 2 === 0) {\n        if (i === 16 || i % 3 == 0) {\n            continue //continue pasara a la siguiente iteracion, si pusiera break el programa al encontrar con 16 dejaria de ejecutarse.\n        }\n        console.log(i)\n    }\n}\nconsole.log('forma 2:')\n//forma 2\nfor (let i = 10; i <= 55; i++) {\nif(i % 2 === 0 && i !== 16 && i % 3 !== 0){\n    console.log(i) \n}\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/santiagoCamachoCamino.js",
    "content": "// 00 - OPERADORES Y ESTRUCTURAS DE CONTROL\n// Santiago Camacho Camino\n// 2025-04-22\n\n// Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n// Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n// (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n\n/**\n * Operadores Aritméticos\n */\n\nlet a=5;\nlet b=10;\n//Incrementación\nconsole.log(++a); //6\n//Muestra el valor de 'a' luego incrementa\nconsole.log(a++); //6\n//Resta\nconsole.log(a-b); //-5\n//Multiplicación\nconsole.log(a*b); //50\n//División\nconsole.log(b/a); //2\n//Modulo\nconsole.log(b % a); //0\n\n/**\n * Operadores de Asignación\n */\n\na += b; //15\na -=b ; //-5\na *= b; //50\na /= b; //0.5\na %= b; //5\na **= b; //9765625\n\n\n/**\n * Operadores de Comparación\n */\n\n//Operadores racionales\nconsole.log(a > b); // false\nconsole.log(a < b); // true\nconsole.log(a <= b); // true\nconsole.log(a >= b); // false\n\n//Operadores de igualdad\nconsole.log(a == b); //false\nconsole.log(a != b); //true\n// compara si son iguales en valor \n// y en tipo de dato\nconsole.log(a !== b); //false \nconsole.log(a === b); //false \n\n\n/**\n * Operadores Lógicos\n */\nlet verdadero=true;\nlet falso=false;\n\n//AND -> &&\n/*\nlas dos expresiones tienen que ser verdaderas, para que devuelva 'true', \nsi una es falsa devuelve 'false'\n*/\nconsole.log(verdadero && falso); //falso\nconsole.log(verdadero && verdadero); //verdadero\nconsole.log(falso && falso); //falso\n\n\n//OR -> ||\n/*\nuna de las dos expresiones tiene que ser verdadera, para que ddevuelva 'true',\nsi las dos son falsas devuelve 'false'\n*/\nconsole.log(verdadero || falso); //verdader\nconsole.log(verdadero || verdadero); //verdadero\nconsole.log(falso || falso); //falso\n\n//NOT -> !\n\nconsole.log(!verdadero); //false\nconsole.log(!falso); //verdadero\n\n/**\n * Operadores Bitwise\n */\n\nconsole.log(a & b); //0\nconsole.log(a | b); //282475259\nconsole.log(a ^ b); //282475259\nconsole.log(~a); //-282475250\nconsole.log(a << b); //1491846144\nconsole.log(a >> b); //275854\n\n/**\n * Operador ternario\n */\n\nlet edadOperador=18;\nlet acceso = edadOperador >=17 ?'Es mayor de edad' : 'Es menor de edad '; //Es mayor de edad\n\n/**\n *  Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n *  Debes hacer print por consola del resultado de todos los ejemplos.\n */\n\n/**\n * Condicionales\n */\n\nlet edad=13;\n\nif(edad < 13 ){\n    console.log(\"Eres un niño/a\");\n}else if(edad >=13 && edad < 18){\n    console.log(\"Eres un adolescente\");\n}else{\n    console.log(\"Eres un adulto\");\n}\n\n/**\n * Switch\n */\n\nlet numDia=7;\n\nswitch (numDia){\n    case 1:\n        console.log(\"Lunes\");\n        break;\n    case 2:\n        console.log(\"Martes\");\n        break;\n    case 3:\n        console.log(\"Miércoles\");\n        break;\n    case 4:\n        console.log(\"Jueves\");\n        break;\n    case 5:\n        console.log(\"Viernes\");\n        break;\n    case 6:\n        console.log(\"Sábado\");\n        break;\n    default:\n            console.log(\"Domingo\");\n}\n\n/**\n * For\n */\n\nfor(let i = 1; i <=10; i++){\n    console.log(i, \"y su cuadrado es\", Math.pow(i, 2))\n}\n\n/**\n * While\n */\nlet num=5;\nwhile(num >=1){\n    console.log(num);\n    num--;\n}\n\n/**\n * Do...While \n */\nlet num2=4;\ndo{\n    console.log(`Número ingresado: ${num2}`);\n    num2++;\n}while(num2 < 10);\n\n\n/**\n * For...in\n */\n\nlet persona={\n    edad: 15,\n    nombre: \"Pepito\",\n    apellido: \"Peréz\",\n}\n\nfor(let propiedades in persona){\n    console.log(`${propiedades}: ${persona[propiedades]}`);\n}\n\n/**\n * For...of\n */\nlet frutas = [\"sandia\", \"banana\", \"pera\", \"uva\"];\n\nfor(let fruta of frutas){\n    console.log(fruta);\n}\n\n/**\n * break/ continue\n */\nfor(let i=1; i<=10;i++){\n    if(i == 5){\n        continue;\n    }else if(i == 8){\n        break;\n    }\n    console.log(i);\n\n}\n\n/**\n * Extra\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n */\nfor(let i=10; i<=55; i++){\n    if(i % 2 == 1 || i % 3 == 0 || i == 16 ){\n        continue;\n    }\n    console.log(i);\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/seandsun.js",
    "content": "/**\n * Operadores aritméticos:\n * \n * Suma, resta, multiplicación, división, residuo y potenciación\n */\n\nlet num1 = 62\nlet num2 = 4\nlet operacion\n\nconsole.log(operacion = num1 + num2)\nconsole.log(operacion = num1 - num2)\nconsole.log(operacion = num1 * num2)\nconsole.log(operacion = num1 / num2)\nconsole.log(operacion = num1 % num2)\nconsole.log(operacion = num1 ** num2)\n\n/**\n * Operadores de asignación:\n * \n * Se puede observar que se están haciendo las operaciones (+,-,*,/,%,**) entre las variables “a” y “b” y\n * al mismo tiempo se está asignando el resultado de esas operaciones a la variable “a”.\n */\n\nlet a = 10\nlet b = 4\n\nconsole.log(a += b)\nconsole.log(a -= b)\nconsole.log(a *= b)\nconsole.log(a /= b)\nconsole.log(a %= b)\nconsole.log(a **= b)\n\n/**\n * Operadores de concatenación\n */\n\nlet nombre = \"Marisol\"\nlet apellido = \"Henao\"\n\nlet nombreCompleto = nombre + \" \" + apellido\nconsole.log(nombreCompleto) // Marisol Henao\n\nnombreCompleto = `Mi nombre es ${nombre} y mi apellido es ${apellido}` // Para las llaves debe ser con \"backticks\" (`)\nconsole.log(nombreCompleto) // Mi nombr es Marisol y mi apellido es Henao\n\n/**\n * Operadores de comparación\n */\n\n// Es igual (compara el valor): ==\na = 50\nb = 50\n\nlet resultado = a == b\nconsole.log(resultado) // true\n\n// Es estrictamente igual (compara el valor y tipo de dato): ===\na = 50\nb = \"50\"\n\nconsole.log(resultado = a === b) // false\n\n// Es diferente (verifica que los valores sean diferentes): !=\na = 50\nb = 20\n\nconsole.log(resultado = a != b) // true\n\n// Es estrictamente diferente (verifica el valor y tipo de dato): !==\na = 50\nb = \"50\"\n\nconsole.log(resultado = a !== b) // true\n\n// Los 4 operadores anteriores los podemos utilizar para comparar números, cadenas de texto y boolenos.\n\n// Mayor que: > y Menor que: <\na = 10\nb = 15\n\nconsole.log(resultado = a > b) // false\nconsole.log(resultado = a < b) // true\n\n// Mayor o igual que: ≥ y Menor o igual que: ≤\na = 15\nb = 15\n\nconsole.log(resultado = a >= b) // true\nconsole.log(resultado = a <= b) // true\n\n/**\n * Operadores lógicos\n */\n\n// AND: &&\na = 10\nb = 20\nlet c = 30\n\n// ¿b es mayor que a y b es mayor que c?\nconsole.log(resultado = (b > a) && (b > c)) // false (Porque se tienen que cumplir las 2)\n\n// OR: ||\na = 10\nb = 20\nc = 30\n\n// ¿b es mayor que a o b es mayor que c?\nconsole.log(resultado = (b > a) || (b > c)) // true (Porque solo es necesario que se cumpla 1)\n\n/**\n * Operadores unarios:\n * \n * Pueden aumentar o decrecer su valor por si mismos.\n */\n\na = 10\n\na++\nconsole.log(a) // 11\n\na--\nconsole.log(a) // 9\n\n/**\n * Operadores ternarios:\n * \n * Los operadores ternarios requieren de 3 argumentos o partes para funcionar:\n * \"condición\" ? \"respuesta si la condición es true\" : \"respuesta si la condición es false\"\n */\n\nlet numero1 = 5\nlet numero2 = 8\n\nlet comparacion = numero2 > numero1 ? \"Sí es mayor\" : \"No es mayor\"\nconsole.log(comparacion) // Sí es mayor\n\n//---------------------------------------------------------------------------------------------------\n\n/**\n * if else if:\n *  \n * \"Si\" eres mayor de edad y menor de 65 años puedes venir a la fiesta. \n * \"Sino\", \"si\" tienes permiso firmado y eres menor de 18, puedes venir. \n * \"Sino\" no puedes venir a la fiesta.\n */\n\nlet persona = \"Cleopatra\"\nlet edad = 15\nlet permiso = true\n\nif (edad > 18 && edad < 65) {\n\tconsole.log(`${persona} puedes venir a la fiesta`)\n} else if (permiso === true && edad < 18) {\n\tconsole.log(`${persona} puedes venir, tienes permiso`) // Cleopatra puedes venir, tienes permiso\n} else {\n\tconsole.log(`${persona} no puedes venir a la fiesta`)\n}\n\n/**\n * for:\n * \n * Imprimir los numeros del 1 al 9\n */\n\nfor (let i = 0; i < 10; i++) {\n    console.log(i)\n}\n\n/**\n * while:\n * \n * Mientras la cantidad de juguetes sea mayor a 0, regalar un juguete.\n */\n\nlet juguetes = 10\n\nwhile (juguetes > 0) {\n    juguetes--\n    console.log(`Regalamos un juguete. Nos quedan ${juguetes}`)\n}\n\n/**\n * Switch:\n * \n * Si eres fuerte y comelón: eres Gokú \n * Si eres veloz y egoísta: eres Vegetta\n * Si eres pequeño y débil: eres Krillin\n * Si eres travieso y juguetón: eres Trunks\n * Si no eres ninguno, eres una sabandija\n */\n\nlet personalidad = \"Travieso y juguetón\"\n\nswitch (personalidad) {\n    case \"Fuerte y comelón\":\n        console.log(\"Eres Gokú\")\n        break\n\tcase \"Veloz y egoísta\":\n\t\tconsole.log(\"Eres Vegetta\")\n\t\tbreak\n\tcase \"Pequeño y débil\":\n\t\tconsole.log(\"Eres Krillin\")\n\t\tbreak\n\tcase \"Travieso y juguetón\":\n\t\tconsole.log(\"Eres Trunks\") // Eres Trunks\n\t\tbreak\n\tdefault:\n\t\tconsole.log(\"Eres una sabandija!\") \n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/sebascmb.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n\n// ! Ejercicio 1 - aritmeticos\n\n// ---- OPERADORES ARITMETICOS ---- //\n\nlet suma           = 5 + 5;               // SUMA\nlet resta          = 2 - 1;               // RESTA\nlet multiplicacion = 3 * 2;               // MULTIPLICACION\nlet division       = 10 / 2;              // DIVISION\nlet modulo         = 4 % 2;               // MODULO\nlet exponencia     = 2 ** 3;              // EXPONENCIA\n\nlet s = 1\nconsole.log(s );\ns++                                       // SUMA 1 AL VALO de s Y RETORNA 1\nconsole.log( s );\ns--                                       // RESTA 1 AL VALOR DE s Y RETORNA 1\nconsole.log( s );\n++s                                       // SUMA 1 AL VALOR DE s RETORNA EL RESULTADO DE LA OPERACION POSTERIOR\nconsole.log( s );\n--s                                       // RESTA 1 A AL VALOR DE s Y RETORNA EL RESULTADO DE LA OPERACION POSTERIOR\nconsole.log( s );\n\nconsole.log( suma, resta, multiplicacion, division, modulo, exponencia,);\n\n\n// ------------ OPERADORES LOGICOS ------------ //\n\nlet valueFalse = false;\nlet valueTrue  = true;\n\n//     AND    //\n\nconsole.log( valueTrue  && valueTrue  );  // DEVUELVE TRUE SI AMBOS VALORES SON VERDADEROS\nconsole.log( valueTrue  && valueFalse );  // DEVUELVE FALSE\nconsole.log( valueFalse && valueTrue  );  // DEVUELVE FALSE\nconsole.log( valueFalse && valueFalse );  // DEVUELVE FALSE\n\n\n//    OR    //\n\nconsole.log( valueFalse || valueFalse );  // DEVUELVE FALSE\nconsole.log( valueFalse || valueTrue  );  // DEVUELVE TRUE\nconsole.log( valueTrue  || valueTrue  );  // DEVUELVE TRUE\nconsole.log( valueTrue  || valueFalse );  // DEVUELVE TRUE\n\n\n //     NOT    //\n\n console.log( !valueFalse ); // DEVUELVE TRUE\n console.log( !valueTrue  ); // DEVUELVE FALSE\n\n\n\n// ------------ OPERADORES COMPARACION E IDENTIDAD ------------ //\n\nlet a = 5;\nlet b = 10\n\nconsole.log( a ==  b  ); // ES FALSE - DEVUELVE TRUE SI LOS VALORES FUERAN IGUALES\nconsole.log( a !=  b  ); // ES TRUE  - DEVUELVE TRUE SI LOS VALORES SON DIFRENTENS\nconsole.log( a === b  ); // ES FALSE - DEVUELVE TRUE SI LOS VALORES SON IGUAL Y DEL MISMO TIPO\nconsole.log( a !== b  ); // ES TRUE  - DEVUELVE TRUE SI LOS VALORES SON DIFERENTES Y DEL MISMO TIPO\nconsole.log( a >   b  ); // ES FALSE - DEVUELVE TRUE SI EL VALOR DE A ES MAYOR QUE B\nconsole.log( a >=  b  ); // ES FALSE - DEVUELVE TRUE SI EL VALOR DE A ES MAYOR O IGUAL QUE B\nconsole.log( a <   b  ); // ES TRUE  - DEVUELVE TRUE SI EL VALOR DE A ES MENOR QUE B\nconsole.log( a <=  b  ); // ES TRUE  - DEVUELVE TRUE SI EL VALOR DE A ES MENOR O IGUAL QUE B\n\n\n\n// ------------ OPERADORES DE ASIGNACION ------------ //\n\nlet x = 2;\nlet y = 3;\n\nlet asignacion1 = x +=  y; // ES IGUAL A X = X +  Y\nlet asignacion2 = x -=  y; // ES IGUAL A X = X -  Y\nlet asignacion3 = x *=  y; // ES IGUAL A X = X *  Y\nlet asignacion4 = x /=  y; // ES IGUAL A X = X /  Y\nlet asignacion5 = x %=  y; // ES IGUAL A X = X %  Y\nlet asignacion6 = x **= y; // ES IGUAL A X = X ** Y\nlet asignacion7 = x &&  y; // ES IGUAL A X = X &  Y\nlet asignacion8 = x ||  y; // ES IGUAL A X = X || Y\n\n\n// ------------ OPERADORES DE PERTENENCIA ------------ //\n\nlet arr1 = [1,3,5,7,8,9,];\n\nconst RESA = 5  in arr1; // DEVUELVE TRUE SI EL VALOR DE 5 ESTA EN EL ARRAY\nconst RESB = 10 in arr1; // DEVUELVE FALSE SI EL VALOR DE 10 NO ESTA EN EL ARRAY\n\n\n// ------------ OPERADORES DE BITS ------------ //\n\nlet o = 9;\nlet p = 5;\n\nconsole.log( o & p );\n\n\n\n// ------------ OPERADORES DE TIPO DE DATO ------------ //\n\n\nlet saludo   = 'Hola';\nlet numero   = 20;\nlet booleano = true;\nlet soyUndefined;\n\nconsole.log( typeof saludo      ); // String\nconsole.log( typeof numero      ); // Number\nconsole.log( typeof booleano    ); // Boolean\nconsole.log( typeof soyUndefined); // Undefined\n\n\n// ------------ OPERADOR CONCATENACION ------------ //\n\n\nlet nombre    = 'Sebastian';\nlet apelllido = 'Marquez';\n\nconsole.log(nombre + ' ' + apelllido);\n\n\n\n// ------------ ESTRUCTRUAS DE CONTROL ------------ //\n\n\n// * IF\n\nlet edad = 18;\n\nif ( edad == 25) {\n  console.log('Tienes muchas cosas por experimentare aun');\n}\n\n// * If - else\n\nif ( edad >= 25) {\n  console.log('Puedes entrar a la discoteca');\n} else {\n  console.log('No puedes entrar a la discoteca');\n}\n\n// * iF - else if\n\nif ( edad >= 25 ) {\n  console.log('Puedes entrar a la discoteca y fumar');\n} else if ( edad <= 18 ) {\n  console.log('No puedes entrar en discotecas, mejor ve a hacer ejercio');\n} else {\n  console.log('Puedes pasar y solo tomar alcohol');\n}\n\n// * ternario\n\nlet num1 = 2\nlet num2 = 4\n\nnum1 > num2 ? console.log('Soy mayor') : console.log('Soy menor');\n\n\n// * Switch\n\nlet dia = 5;\n\nswitch ( dia ) {\n  case 0:\n    console.log('Domingo');\n    break;\n  case 1:\n    console.log('Lunes');\n    break;\n  case 2:\n    console.log('Martes');\n    break;\n  case 3:\n    console.log('Miercoles');\n    break;\n  case 4:\n    console.log('Jueves');\n    break;\n  case 5:\n    console.log('Viernes');\n    break;\n  case 6:\n    console.log('Sabado');\n    break;\n\n  default:\n    console.log('Dia no valido');\n    break;\n}\n\n// * For\n\nfor (let i = 0; i <= 5; i++) {\n  console.log([i]);\n}\n\n// * For in\n\nlet heroes = ['Superman', 'Batman', 'Aquaman', 'Spiderman', 'Deadpool',];\n\nfor ( let i in heroes ) {\n  console.log( heroes[i] );\n}\n\n// * For of\n\nfor ( let heroe of heroes ) {\n  console.log(heroe);\n}\n\n// * While\n\nlet carros = ['Mazda', 'Hyundai', 'Toyota', 'Cevrolet']\nlet i = 0;\n\nwhile ( i < carros.length ) {\n  console.log(carros[i]);\n  i++\n}\n\nlet j = 0;\n\ndo {\n  console.log(carros[j]);\n  j++;\n} while (carros[j]);\n\n\n// DIFICULTAD EXTRA (opcional):\n//  * Crea un programa que imprima por consola todos los números comprendidos\n//  * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n//  *\n//  * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\n\nfor (let m = 10; m <= 55; m++) {\n  if ( m % 2 === 0 && m !== 16 && m % 3 !==0 ) {\n    console.log(m);\n  }\n}\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/septarian.js",
    "content": "//operadores\n\nconsole.log(`10 + 3 = ${10 + 3}`)   //SUMA\nconsole.log(`10 - 3 = ${10 - 3}`)   //RESTA\nconsole.log(`10 / 3 = ${10 / 3}`)   //DIVISION  \nconsole.log(`10 * 3 = ${10 * 3}`)   //MULTIPLICACION\nconsole.log(`10 % 3 = ${10 % 3}`)   //MODULO - RESIDUO DE LA DIVISION\nconsole.log(`10 ** 3 = ${10 ** 3}`)   //EXPONENCIA\n\nlet a = 10\nlet b = 5\n//a = a ...\nconsole.log(a += b)\nconsole.log(a -= b)\nconsole.log(a *= b)\nconsole.log(a /= b)\nconsole.log(a %= b)\nconsole.log(a **= b)\n\n//operador ternario\nlet x = 0\nlet y = 1\nconst res = y < x ? \"X es mayor\" : \"Y es menor\"\nconsole.log(res)\n\nvariable = \"gg\"\nvariable2 = \"GG\"\n//vars compara si son iguales \nvars = variable == variable2\nconsole.log(vars)\n\nconst edad = 2\n\nswitch(edad){\n    case 1:\n        console.log(\"tienes 1 año\")\n        break\n    case 2:\n        console.log(\"tienes 2 años\")\n}\n\n//RETO EXTRA\nfor(let i = 10;i <= 55; i++){\n    if(i === 16 || i % 3 === 0 || i % 2 !== 0){\n\n        //continue se salta esta iteracion y continua a la siguiente\n        continue\n        \n    }\n    console.log(i)\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/shevotool.js",
    "content": "// Operadores de asignación\nlet a = 25;\nlet b = 25;\nconsole.log((a += b));\nconsole.log((a -= b));\nconsole.log((a *= b));\nconsole.log((a /= b));\nconsole.log((a %= b));\nconsole.log((a &= b));\nconsole.log((a ^= b));\nconsole.log((a |= b));\nconsole.log((a &&= b));\nconsole.log((a ||= b));\nconsole.log((a ??= b));\n\n// Operadores de comparación\nconsole.log(a == b);\nconsole.log(a != b);\nconsole.log(a === b);\nconsole.log(a !== b);\nconsole.log(a > b);\nconsole.log(a >= b);\nconsole.log(a < b);\nconsole.log(a <= b);\n\n//Operadores aritméticos\nconsole.log(a % b);\nconsole.log(a++);\nconsole.log(a--);\nconsole.log(--a);\nconsole.log(++a);\n\n// Operadores lógicos\nconsole.log((a = true && true));\nconsole.log((a = true || false));\nconsole.log((a = !false));\n\n// Operador ternario\nlet resultado = a > b ? \"Mayor\" : \"Menor\";\nconsole.log(resultado);\n\n// Operadores de cadena\nlet nombreCompleto = \"Andrey\" + \" \" + \"Martinez\";\nconsole.log(nombreCompleto);\n\n// Operador de propagación\nlet arr = [1, 2, 3];\nlet arr2 = [...arr, 4, 5];\nconsole.log(arr2);\n\n// Operadores de nullish (??)\nlet valor = null;\nconsole.log(valor ?? \"valor por defecto\");\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/sniker1223.js",
    "content": "// Arithmetic Operators\nconsole.log(\"Arithmetic Operators\")\nlet x = 100\nconsole.log(\"+ Addition:\", x + 50)\nconsole.log(\"- Subtraction:\", x - 50)\nconsole.log(\"* Multiplication:\", x * 50)\nconsole.log(\"** Exponentiation:\", x ** 2)\nconsole.log(\"/ Division:\", x / 50)\nconsole.log(\"% Modulus:\", 1 % 2)\nconsole.log(\"++ Increment:\", x++)\nconsole.log(\"-- Decrementing:\", x--)\n\n// Assignment Operators\nconsole.log(\"\\nAssignment Operators\")\nconsole.log(\"= Assignment: x = \", x)\nx += 1\nconsole.log(\"+= Addition assignment: x += \", x)\nx -= 1\nconsole.log(\"-= Substraction Assignment: x -= \", x)\nx *= 2\nconsole.log(\"*= Multiplication Assignment: x *= \", x)\nx /= 3\nconsole.log(\"/= Division Assignment: x /= \", x)\nx %= 2\nconsole.log(\"%= Modulus Assignment: x %= \", x)\nx **= 2\nconsole.log(\"**= Exponentiation Assignment: x **= \", x)\n\n// Shift Assignment Operators\nconsole.log('\\nShift Assignment Operators')\nx = 5\nx <<= 2\nconsole.log('<<= left shift assignment:', x)\nx = 5\nx >>= 2\nconsole.log('>>= right shift assignment:', x)\n\n// Bitwise Assignment Operators\nconsole.log('\\nBitwise Assignment Operators')\nx = 5\nx &= 3\nconsole.log('&= Bitwise AND assignment:', x)\nx = 5\nx ^= 3\nconsole.log('^= Bitwise XOR:', x)\nx = 5\nx |= 3\nconsole.log('|= Bitwise OR assignment:', x)\n\n// Logical Assignment Operators\nconsole.log('\\nLogical Assignment Operators')\nx = 1\nx &&= 2\nconsole.log('&&= Logical AND assignment', x)\nx = 1\nx ||= 2\nconsole.log('||= Logical OR assignment', x)\nx = 1\nx ??= 2\nconsole.log('??= Nullish coalescing assignment', x)\n\n// Comparison Operators\nconsole.log('\\nComparision Operators')\nconsole.log('== equal to:', 2 == '2')\nconsole.log('=== equal value and equal type:', 2 === '2')\nconsole.log('!=\tnot equal:', 2 != \"3\")\nconsole.log('!==\tnot equal value or not equal type:', 2 !== 3)\nconsole.log('> greater than:', 2 > 1)\nconsole.log('< less than:', 2 < 1)\nconsole.log('>=\tgreater than or equal to:', 2 >= 2)\nconsole.log('<=\tless than or equal to:', 2 <= 2)\n\n// Logical Operators\nconsole.log('\\nLogical Operators')\nx = 6\nconsole.log('&& and operator:', x > 1 && x < 8)\nconsole.log('|| or operator:', x > 1 || x > 8)\nconsole.log('! not operator:', !(6 == 6))\n\n// Miscellaneous Operators\nconsole.log('\\nMiscellaneous Operators')\nlet voteable = (7 < 18) ? \"Too young\" : \"Old enough\"\nconsole.log('?: Ternary operator:', voteable)\nlet name = null;\nlet text = \"missing\";\nlet result = name ?? text;\nconsole.log('?? The Nullish Coalescing Operator', result)\nconst car = {\n  type: \"Fiat\",\n  model: \"500\",\n  color: \"white\"\n};\nlet namecar = car?.namecar;\nconsole.log('? The Optional Chaining Operator', namecar)\n\n// CONTROL STRUCTURES\nconsole.log('\\nif Statement')\nif (7 < 18) {\n  console.log(\"Good day\")\n}\n\nconsole.log('\\nelse Statement')\nif (19 < 18) {\n  console.log(\"Good day\")\n} else {\n  console.log(\"Good evening\")\n}\n\nconsole.log('\\nelse if Statement')\nif (1 < 10) {\n  console.log(\"Good morning\")\n} else if (time < 20) {\n  console.log(\"Good day\")\n} else {\n  console.log(\"Good evening\")\n}\n\nconsole.log('\\nSwitch Statement')\nswitch (new Date().getDay()) {\n  case 0:\n    console.log(\"Sunday\")\n    break;\n  case 1:\n    console.log(\"Monday\")\n    break;\n  case 2:\n    console.log(\"Tuesday\")\n    break;\n  case 3:\n    console.log(\"Wednesday\")\n    break;\n  case 4:\n    console.log(\"Thursday\")\n    break;\n  case 5:\n    console.log(\"Friday\")\n    break;\n  case 6:\n    console.log(\"Saturday\")\n}\n\nconsole.log('\\nfor loop')\nconst cars = [\"BMW\", \"Volvo\", \"Saab\", \"Ford\", \"Fiat\", \"Audi\"];\n\nlet texto = \"\";\nfor (let i = 0; i < cars.length; i++) {\n  texto += cars[i] + \"\\n\";\n}\nconsole.log(texto)\n\nconsole.log('\\nfor in loop')\nconst person = {\n  fname: \"John\",\n  lname: \"Doe\",\n  age: 25\n};\nlet textPerson = \"\";\nfor (let x in person) {\n  textPerson += person[x] + \" \"\n}\nconsole.log(textPerson)\n\nconsole.log('\\nFor Of Loop Statement')\nconst cars1 = [\"BMW\", \"Volvo\", \"Mini\"];\nlet textCars = \"\";\nfor (let x of cars1) {\n  textCars += x + \" \"\n}\nconsole.log(textCars)\n\nconsole.log('\\nWhile Loop')\nlet i = 0\nwhile (i < 10) {\n  text += \"The number is \" + i;\n  i++;\n  console.log(i)\n}\n\n// Exceptions(try, catch, finally and throw)\nconsole.log('\\ntry and catch')\ntry {\n  nonExistentFunction()\n} catch (error) {\n  console.log(\"Something went wrong.\")\n}\n\nconsole.log('\\ntry and finally')\n\nfunction doIt() {\n  try {\n    return console.log('1')\n  } finally {\n    return console.log('2')\n  }\n}\ndoIt();\n\nconsole.log('\\ntry, catch and throw')\n\nfunction getRectArea(width, height) {\n  if (isNaN(width) || isNaN(height)) {\n    throw new Error('Parameter is not a number!');\n  }\n}\n\ntry {\n  getRectArea(3, 'A');\n} catch (e) {\n  console.error(e);\n}\n\n// Challenge. Print numbers between 10 and 55(included), even and odd but not print 16 and multiple of 3.\nconsole.log('\\nChallenge')\nfor (let n = 0; n <= 55; n++) {\n  if (n >= 10 && n % 2 == 0 && n != 16 && !(n % 3 == 0) || n == 55) {\n    console.log(n)\n  }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/socramwd.js",
    "content": "// Operadores aritméticos\nconsole.log('Operadores Aritméticos')\n\nconst suma = 10 + 3\nconsole.log( 'Suma: 10 + 3 = ', suma )\n\nconst resta = 10 - 3\nconsole.log( 'Resta: 10 - 3 = ', resta )\n\nconst multiplicacion = 10 * 3\nconsole.log( 'Multiplicación: 10 * 3 = ', multiplicacion )\n\nconst division = 10 / 3\nconsole.log( 'División: 10 / 3 = ', division )\n\nconst modulo = 10 % 3\nconsole.log( 'Módulo: 10 % 3 = ', modulo ) // El resto que nos queda al dividir\n\nconst exponente = 10 ** 3\nconsole.log( 'Exponente: 10 ** 3 = ', exponente ) // Calcula la base a la potencia\n\n\nconsole.log('******************************')\n\n\n// Operaciones de comparación => nos retorna true o false\nconsole.log('Operadores de Comparación')\n\nconst igualdad = 3 == '3'\nconsole.log( '3 es igual que \"3\" => ', igualdad)\n\nconst igualdadEstricta = 3 === '3'\nconsole.log( '3 es igual que \"3\" => ', igualdadEstricta)\n\nconst desigualdad = 3 != '3'\nconsole.log( '3 es desigual que \"3\" => ', desigualdad)\n\nconst desigualdadEstricta = 3 !== '3'\nconsole.log( '3 es desigual que \"3\" => ', desigualdadEstricta)\n\nconst mayorQue = 3 > 5\nconsole.log( '3 es mayor que 5 => ', mayorQue)\n\nconst mayorIgual = 3 >= 3\nconsole.log( '3 es mayor o igual que 3 => ', mayorIgual)\n\nconst menorQue = 3 < 5\nconsole.log( '3 es menor que 5 => ', menorQue)\nconst menorIgual = 3 <= 5\nconsole.log( '3 es menor o igual que 5 => ', menorIgual)\n\n\nconsole.log('******************************')\n\n\n// Operadores lógicos\nconsole.log( 'Operadores Lógicos')\n\nconst and = 10 + 3 == 13 && 5 - 1 == 4\nconsole.log(` AND &&: 10 + 3 == 13 and 5 - 1 == 4 => ${ and } `)\n\nconst or = 10 + 3 == 14 || 5 - 1 == 4\nconsole.log(` OR ||: 10 + 3 == 14 or 5 - 1 == 4 => ${ or } `)\n\nconst not = !(10 + 3 == 14)\nconsole.log(` NOT !: not 10 + 3 == 14 => ${ not } `)\n\n\nconsole.log('******************************')\n\n\n// Operadores de asignación\nconsole.log('Operadores de Asignación')\n\nlet myNumber = 11\nconsole.log( 'Mi número: ', myNumber ) // Asignación\n\nmyNumber += 1\nconsole.log( 'Suma 1 y asignación: ', myNumber) // Suma y asignación\n\nmyNumber -= 1\nconsole.log( 'Resta 1 y asignación: ', myNumber) // Resta y asignación\n\nmyNumber *= 2\nconsole.log( 'Multiplicación por 2 y asignación: ', myNumber) // Multiplicación y asignación\n\nmyNumber /= 2\nconsole.log( 'División por 2 y asignación: ', myNumber) // División y asignación\n\nmyNumber %= 2\nconsole.log( 'Módulo de 2 y asignación: ', myNumber) // Módulo y asignación\n\nmyNumber **= 1\nconsole.log( 'Exponente de 1 y asignación: ', myNumber) // Exponente y asignación\n\n\nconsole.log('******************************')\n\n\n// Operadores de pertenencia\nconsole.log('Operadores de Pertenencia')\n\nconst name = 'socramdev'\nconsole.log( 'Mi nombre es ', name)\n\nconst result = name.includes('d')\nconsole.log( 'Mi nombre incluye la letra d: ', result )\n\n\nconsole.log('******************************')\n\n\n// Operadores de bit\nconsole.log('Operadores de bit')\n\nlet n1 = 10 // 1010\nconsole.log( n1, 'en binario es 1010' )\n\nlet n2 = 3 // 0011\nconsole.log( n2, 'en binario es 0011' )\n\n// Operador bit AND. Convierte los números a bits, y los compara, donde 0+0=0, 1+0=0, 0+1=0, 1+1=1, en este caso el resultado es 0010, que convertido a numero entero es el 2\nlet resultado = n1 & n2\nconsole.log( 'Si los bits son iguales da 1: ', resultado, 'que en binario es 0010')\n\n// Si al menos hay un 1, el resultado es 1, por lo que seria 1011\nlet resultado2 = n1 | n2\nconsole.log( 'Si al menos un bit es 1 da 1: ', resultado2, 'que en binario es 1011')\n\n// Si los bit son iguales, el resultado es 0, por lo que es 1001\nlet resultado3 = n1 ^ n2\nconsole.log( 'Si los bits son iguales da 0: ', resultado3, 'que en binario es 1001')\n\n\nconsole.log('******************************')\n\n\n/*\n    Estructuras de Control\n*/\n\n// Condicionales\nconsole.log('Condicional IF')\nconst edad = 46\nif(edad < 46) {\n    console.log('Tengo más edad')\n} else if(edad == 46) {\n    console.log('Es mi edad')\n} else {\n    console.log('Tengo menos edad')\n}\n\n\nconsole.log('******************************')\n\n// Iterativas\nconsole.log('Iterativa FOR')\nconst limite = 10\nfor (let index = 0; index < 11; index++) {\n    console.log( index )\n}\n\n\nconsole.log('******************************')\n\n\nconsole.log('Iterativa WHILE')\nlet contador = 0\nwhile (contador < 11) {\n    contador++\n    console.log(contador)\n}\n\n\nconsole.log('******************************')\n\n\nconsole.log('Manejo de Excepciones')\ntry {\n    console.log( 'Dividimos 10/1: ', 10 / 1 )\n} catch (error) {\n    console.log( 'El error es: ', error )\n} finally {\n    console.log('Ha finalizado el manejo de excepciones')\n}\n\n\nconsole.log('******************************')\n\n\nconsole.log('EXTRA')\nfor (let i = 10; i < 56; i++) {\n    if( i % 2 === 0 && i !== 16 && i % 3 !== 0 ) {\n        console.log(i)\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/soldochris.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n//Operadores Aritméticos\nlet suma = 2 + 8;\nlet reste = 7 - 2;\nlet mulplicacion = 3 * 4;\nlet potencia = 2 ** 3;\nlet division = 10 / 5;\nlet residuo = 9 / 2;\n\n//Operadores de comparación\nlet igualdad = 2 == 4;\nlet igualdadEstricta = 2 === 2;\nlet diferencia = 5 != 4;\nlet diferenciaEstricta = 3 !== 8;\nlet menor = 3 < 5;\nlet menorIgual = 1 <= 6;\nlet mayor = 9 > 2;\nlet mayorIgual = 8 <= 4;\n\n//Operadores de lógicos\nlet y = true && true;\nlet o = true || false;\nlet negacion = !false;\n\n//Operadores de Asignacion\nlet variable = 2;\n\nvariable += 2; //primero se realiza la suma y luego se hace la asignacion\nvariable =+ 2; //primero se realiza la asignacion y luego se hace la suma\nvariable -= 2; //primero se realiza la resta y luego se hace la asignacion\nvariable =- 2; //primero se realiza la asignacion y luego se hace la resta\n\n//Operador de Incremento\nvariable++;\n\n//Operador de Decremento\nvariable--;\n\n/* Estructuras de control */\n\n//IF\nif(true){\n  console.log(\"Se ejecutara si la condición se cumple o es verdadera\");\n}else{\n  console.log(\"Se ejecutara en casi la primera condición no se cumpla o se falsa\");\n}\n\n//while\nlet iterador = 0;\n\nwhile(iterador < 5){\n  console.log(\"Se ejecutara mientras iterador sea menor que 5\");\n  console.log(`El valor actual de iterador es: ${iterador}`);\n  iterador++;\n}\n\n//For\nfor(let i = 0; i < 5 ; i++){\n  console.log(\"Se ejecutara mientras i sea menor que 5\");\n  console.log(`El valor actual de i es: ${i}`);\n}\n\n//Try - Catch - Finally\ntry{\n  console.log(\"Primero intentara ejecutarse este bloque de código\");\n}catch{\n  console.log(\"Este bloque de código se ejecutara al ocurrir un error en el primer bloque\");\n}finally{\n  console.log(\"Finalmente se ejecutara este bloque de código\");\n}\n\n/* DIFICULTAD EXTRA */\nfor(let i = 10 ; i <= 55; i++){\n  if( i % 2 == 0 && i != 16 && i % 3 != 0){\n    console.log(i);\n  }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/ssanjua.js",
    "content": "const dato = 5;\nlet a = 2;\nlet b = 10;\nlet algo = null;\n\n// Operadores aritmeticos\nconsole.log({ suma: 2 + 2 });\nconsole.log({ resta: 2 - 1 });\nconsole.log({ multiplicacion: 2 * 2 });\nconsole.log({ division: 6 / 3 });\nconsole.log({ modulo: 10 % 2 });\n\n// Operadores logicos\nconsole.log({ or: 2 || 4 });\nconsole.log({ and: true && (dato <= 2) });\nconsole.log({ not: !false });\n\n// Operadores de asignacion\nconsole.log((a += b)); // 12\nconsole.log((a -= b)); // 2\nconsole.log((a *= b)); // 20\nconsole.log((a /= b)); // 2\nconsole.log((a %= b)); // 2\nconsole.log((a &= b)); // 2\nconsole.log((a ^= b)); // 8\nconsole.log((a |= b));  //10\nconsole.log((a &&= b)); // 10\nconsole.log((a ||= b)); // 10\nconsole.log((a ??= b)); // 10\n\n// Operadores de comparacion\nconsole.log({ igual: 2 == 2 })\nconsole.log({ estrictamenteIgual: 2 === '2' });\nconsole.log({ desigual: 2 != '2' });\nconsole.log({ estrictamenteDesigual: 2 !== 4 });\nconsole.log({ mayorQue: 10 > 4 });\nconsole.log({ menorQue: 5 < 9 });\nconsole.log({ mayorOIgual: 10 <= 5 });\nconsole.log({ menorOIgual: 7 <= 9 });\n\n// Operadores de tipo\nconsole.log(\"typeof a :\", typeof a);\nconsole.log(\"typeof 'name' :\", typeof 'name');\nlet text = new String('Hello');\nlet num = new Number(28);\nconsole.log(\"instanceof Number :\", (num instanceof Number));\nconsole.log(\"instanceof String :\", (text instanceof String));\n\n// Operador ternario\nconst age = (a + b) >= 18 ? 'yes' : 'no';\nconsole.log(age);\n\n// Operador de propagacion\nconst array = [2, 29, 99, 103];\nconst newArr = [...array, 1000, 2999];\nconsole.log(newArr);\n\n// Falsy\nconsole.log(algo ?? \"nada\");\n\n\n// Extra\nfunction extra() {\n  for (let i = 10; i <= 55; i++) {\n    if (i % 2 == 0 && i != 16 && i % 3 != 0) {\n      console.log(i);\n    }\n  }\n};\n\nextra();\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/sy-codelico.js",
    "content": "// ! #01 OPERADORES Y ESTRUCTURAS DE CONTROL //\n\n// EJERCICIO\n\nlet numero1 = 20; // Asignacion simple con \"=\".\nlet numero2 = 2;\n\n/*- Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n    Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n    (Ten en cuenta que cada lenguaje puede poseer unos diferentes) */\n\n//Operadores Aritméticos:\nconsole.log(numero1 + numero2); // Suma.\nconsole.log(numero1 - numero2); // Resta.\nconsole.log(numero1 / numero2); // División.\nconsole.log(numero1 * numero2); // Multiplicación.\nconsole.log(numero1 % numero2); // Resto entero.\nconsole.log(numero1++); // Incremento.\nconsole.log(numero1--); // Decremento.\n\n//Operadores de Comparación:\nconsole.log(numero1 == 20); //true (Igualdad) Valida dato pero no su tipo.\nconsole.log(numero1 === \"20\"); //false (Igualdad Estricta) Valida dato y tipo del mismo.\nconsole.log(numero1 != 20); //false (Desigualdad) Valida dato pero no su tipo.\nconsole.log(numero1 !== \"20\"); //true (Desigualdad Estricta) Valida dato y tipo del mismo.\n//Funciones flechas:\nconsole.log(numero1 > numero2); //true (Mayor que)\nconsole.log(numero1 < 20); //false (Menor que)\nconsole.log(numero1 >= 20); //true (Mayor o igual)\nconsole.log(numero1 >= 20); //true (Mayor o igual)\n\n//Operadores de Asignación:\nconsole.log((numero1 += numero2)); //Suma y asigna\nconsole.log((numero1 -= numero2)); //Resta y asigna\nconsole.log((numero1 *= numero2)); //Multiplica y asigna\nconsole.log((numero1 /= numero2)); //Divide y asigna\nconsole.log((numero1 %= numero2)); //Modula (resto entero) y asigna\nconsole.log((numero1 **= numero2)); //Exponencia y asigna\n\n//Operadores Lógicos:\nconsole.log(20 > 10 && 10 > 5); //\"&&\" devuelve true si ambos operandos son true.\nconsole.log(true && true);\nconsole.log(true && false); //de lo contrario, devuelve false.\nconsole.log(false && false);\n\nconsole.log(30 >= 10 || 10 > 30); //\"||\" devuelve true si al menos uno de los operandos es true.\nconsole.log(true || true);\nconsole.log(false || false);\nconsole.log(true || false);\n\nconsole.log(!true); //Operador \"!\" para negar un valor booleano.\nconsole.log(!false);\nconsole.log(!(40 > 30));\nconsole.log(!(40 < 30));\n\n//Operador Ternario (Condicional):\n\nlet edad = 12;\nlet GrupoEtario = edad >= 18 ? \"Mayor de Edad\" : \"Menor de edad\";\nconsole.log(GrupoEtario);\n\n/*- Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n    que representen todos los tipos de estructuras de control que existan\n    en tu lenguaje:\n    Condicionales, iterativas, excepciones... */\n/*- Debes hacer print por consola del resultado de todos los ejemplos.*/\n\n//Expresiones condicionales:\n//if.\nif (edad >= 18) {\n  console.log(\"Mayor de edad\");\n}\n\n//if else.\nif (edad >= 18) {\n  console.log(\"Mayor de edad\");\n} else {\n  console.log(\"Menor de edad\");\n}\n\n//else if.\nif (edad >= 12 && edad < 18) {\n  console.log(\"Púber\");\n} else if (edad >= 18 && edad <= 21) {\n  console.log(\"Adolescente\");\n} else if (edad > 21 && edad <= 30) {\n  console.log(\"Adulto joven\");\n} else if (edad > 30 && edad <= 50) {\n  console.log(\"Adulto\");\n} else {\n  console.log(\"Adulto Mayor\");\n}\n\n  //Switch Statement:\n  switch (edad) {\n    case edad >= 1 && edad <= 11:\n      console.log(\"Niño/a\");\n      break;\n    case edad >= 12 && edad < 18:\n      console.log(\"Púber\");\n      break;\n    case edad >= 18 && edad < 21:\n      console.log(\"Adolescente\");\n      break;\n    case edad >= 21 && edad < 30:\n      console.log(\"Adulto joven\");\n      break;\n    case edad >= 30 && edad <= 50:\n      console.log(\"Adulto\");\n      break;\n    default:\n      console.log(\"Adulto mayor\");\n      break;\n  }\n\n/*-    DIFICULTAD EXTRA (opcional):\n   Crea un programa que imprima por consola todos los números comprendidos\n   entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n  \n   Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.*/\n\n\nfor (let i = 10; i <=55; i++) {\n  if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n    console.log(i)\n  }\n  \n}\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/uyarra73.js",
    "content": "// Operadores aritméticos:\n\n    // Operador + (Suma)\n        let a = 10;\n        let b = 5;\n        console.log(a + b);\n\n    // Operador - (Resta)\n        console.log(a - b);\n    \n    // Operador * (Multiplicación)\n        console.log(a * b);\n    \n    // Operador / (División)\n        console.log(a / b);\n    \n    // Operador % (Módulo)\n        console.log(a % b);\n    \n    // Operador ++ (Incremento)\n        console.log(++a);\n    \n    // Operador -- (Decremento)\n        console.log(--b);\n    \n    // Operador ** (Potencia)\n        console.log(a ** b);\n\n// Operadores de asignación:\n\n    // Operador = (Asignación)\n        let numero = 5;\n        console.log(numero);\n\n    // Operador += (Asignación de suma)\n        numero += 5;\n        console.log(numero);\n    \n    // Operador -= (Asignación de resta)\n        numero -= 5;\n        console.log(numero);\n    \n    // Operador *= (Asignación de multiplicación)\n        numero *= 5;\n        console.log(numero);\n    \n    // Operador /= (Asignación de división)\n        numero /= 5;\n        console.log(numero);\n    \n    // Operador %= (Asignación de módulo)\n        numero %= 5;\n        console.log(numero);\n\n\n// Operadores de comparación:\n\n    // Operador == (Igualdad)\n        console.log(5 == '5');  // true\n    \n    // Operador === (Igualdad estricta)\n        console.log(5 === '5'); // false\n\n    // Operador Desigualdad !==\n        console.log(5!== '5'); // true\n    \n    // Operador > (Mayor que)\n        console.log(10 > 5); // true\n    \n    // Operador < (Menor que)\n        console.log(5 < 10); // true\n    \n    // Operador >= (Mayor o igual que)\n        console.log(5 >= 5); // true\n    \n    // Operador <= (Menor o igual que)\n        console.log(5 <= 5); // true\n    \n\n// Operadores lógicos:\n\n    // Operador && (AND lógico)\n        console.log(10 + 3 == 13 && 5 - 1 == 4); // true\n    \n    // Operador || (OR lógico)\n        console.log(10 + 3 == 13 || 5 - 1 == 4); // true\n    \n    // Operador NOT logico !\n        console.log(!(10 + 3 == 13)); // true\n\n\n// Operadores de bit a bit:\n\n    // Operador & (AND)\n        console.log(10 & 3); // 2\n    \n    // Operador | (OR)\n        console.log(10 | 3); // 11\n    \n    // Operador ^ (XOR)\n        console.log(10 ^ 3); // 9\n    \n    // Operador ~ (NOT)\n        console.log(~10); // -11\n    \n    // Operador << (Desplazamiento a la izquierda)\n        console.log(10 << 3); // 80\n    \n    // Operador >> (Desplazamiento a la derecha)\n        console.log(10 >> 3); // 2\n    \n    // Operador >>> (Desplazamiento a la derecha sin signo)\n        console.log(10 >>> 3); // 2\n\n\n// Operadores de cadena:\n\n    // Operador + (Concatenación de cadenas)\n        console.log('Hola' +'mundo'); // Hola mundo\n    \n    // Operador += (Asignación de concatenación)\n        let cadena = 'Hola';\n        cadena +='mundo';\n        console.log(cadena); // Hola mundo\n\n\n// Operadores de tipo:\n\n    // Operador typeof (Devuelve el tipo de una variable)\n        console.log(typeof 10); // number\n    \n    // Operador instanceof (Devuelve verdadero si un objeto es una instancia de un objeto)\n        console.log(10 instanceof Number); // true\n\n// Operadores unarios:\n\n    // Operador + (Conversión a número)\n        let str = \"123\";\n        let numerito = +str;\n        console.log(numerito); // 123\n        console.log(typeof numerito); // \"number\"\n\n   // Operador - (Negación unaria)\n        let number = -3;\n        let negatedNum = -number;\n        console.log(negatedNum); // 3\n   \n   // Operador NOT lógico ! \n        let boolean = true;\n        let notBoolean =!boolean;\n        console.log(notBoolean); // false\n   \n   // Operador delete (Elimina una propiedad de un objeto)\n        let obj = {a: 1, b: 2};\n        delete obj.a;\n        console.log(obj); // {b: 2}\n   \n   // Operador void (Evalúa una expresión y devuelve undefined)\n        void 0; // undefined\n   \n   // Operador typeof (Devuelve el tipo de una variable)\n        console.log(typeof 10); // \"number\"\n\n   // Operador ~ (NOT a nivel de bits): invierte el valor binario de una variable\n\n        let num = 5;          // 5 en binario es 00000000000000000000000000000101\n        let inverted = ~num;  // ~5 en binario es 11111111111111111111111111111010\n        console.log(inverted); // -6\n   \n\n// Operadores ternarios:\n\n    let edad = 18;\n    let voto = edad >= 18 ? \"Puede votar\" : \"No puede votar\";\n    console.log(voto); // \"Puede votar\"\n\n\n// Operadores de coma (para evaluar multiples expresiones en una declaracion):\n\n    for (let i = 0, j = 2; i <= j; i++, j--){\n        console.log(i, j); // 0 1, 1 0, 2 1\n    }\n\n// Operadores relacional in : Verifica si una propiedad concreta existe en un objeto.\n\n    let persona = {\n        nombre: \"Juan\",\n        edad: 30\n    };\n\n    console.log(\"nombre\" in persona); // true\n    console.log(\"edad\" in persona); // true\n    console.log(\"direccion\" in persona); // false\n\n/* Ejercicio extra:\nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3. */\n\nlet numbers = [];\n\nfor (let i = 10; i <= 55; i++){\n  if (i % 3 === 0){\n    continue;\n  } else if (i % 2 !== 0){\n    continue;\n  } else if (i === 16){\n    continue;\n  } else {\n    numbers.push(i);\n  }\n}\n\nconsole.log(numbers);\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/valeriatorrealba.js",
    "content": "//EJERCICIO:\n//- Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje: Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n//(Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n\n    //1. Operadores Aritméticos\n\n        //Suma (+) para realizar sumas en los operandos.\n        let a = 12;\n        let b = 10;\n        let suma = a + b;\n        console.log(suma); //22\n        \n        //Resta (-) para restar el operando derecho del operando izquierdo.\n        let c = 10;\n        let d = 4;\n        let resta = c - d;\n        console.log(resta); //6\n        \n        //Multiplicación (*) para multiplicar los operandos.\n        let e = 10;\n        let f = 4;\n        let multiplicacion = e * f; \n        console.log(multiplicacion); //40\n        \n        //División (/) para realizar la división en los operandos.\n        let g = 10;\n        let h = 4;\n        let division = g / h;\n        console.log(division); //2.5\n        \n        //Módulo (%). En informática, la operación módulo obtiene el resto entero de la división de un número entre otro.​\n        let i = 10;\n        let j = 4;\n        let modulo = i % j;\n        console.log(modulo); //2\n\n        //Exponenciación (**) para calcular la base a la potencia del exponente (base^exponente).\n        let k = 3;\n        console.log(k**4); //81\n\n        //Incremento (++) para aumentar el valor entero en uno.\n        let l = 3;\n        console.log(++l); //4\n\n        //Decremento (--) que disminuye el valor entero en uno.\n        let m = 3;\n        console.log(--m); //2\n\n        //Operador unario más (+) para intentar convertir el operando en un número si aún no lo es\n        console.log(typeof(\"10\")); // string\n        console.log(typeof(+\"10\")); // number\n        console.log(typeof(false)); // boolean\n        console.log(typeof(+false)); // number\n\n        //Operador de negación unaria (-), que devuelve la negación de su operando.\n        let n = 10;\n        console.log(-n); //-10\n\n    //2. Operadores de asignación\n\n        //Operador de asignación (=) para asignar el valor del operando derecho al operando izquierdo.\n        let o = 10;\n        console.log(o); //10\n\n        //Operador de asignación de suma (+=) para sumar los valores de los operandos izquierdo y derecho y asignar el resultado al operando izquierdo.\n        let p = 10;\n        let q = 5;\n        // Equivalent to p = p+q\n        p += q;\n        console.log(p); //15\n\n        //Operador de asignación de resta (-=) para restar el operando derecho del operando izquierdo y asignará el resultado al operando izquierdo.\n        let r = 10;\n        let s = 5;\n        // Equivalent to r = r-s\n        r -= s;\n        console.log(r); //5\n\n        //Operador de asignación de multiplicación (*=) para multiplicar los valores de los operandos izquierdo y derecho y asigne el resultado al operando izquierdo.\n        let t = 10;\n        let u = 5;\n        // Equivalent to t = t*u\n        t *= u;\n        console.log(t); //50\n\n        //Operador de asignación de división (/=) para dividir el valor del operando izquierdo por el valor del operando derecho y asignar el resultado al operando izquierdo.\n        let v = 10;\n        let w = 5;\n        // Equivalent to v = v/w\n        v /= w;\n        console.log(v); //2\n\n        //Operador de asignación de resto (%=), divide el operando izquierdo por el operando derecho y asigna el resto al operando izquierdo.\n        let x = 10;\n        let y = 5;\n        // Equivalent to x = x%y\n        x %= y;\n        console.log(x); //0\n\n        //Operador de Asignación de Exponenciación (**=), eleva el operando izquierdo a la potencia del operando derecho y asigna el resultado al operando izquierdo.\n        let z = 10;\n        let aa = 5;\n        // Equivalent to z = z**aa\n        z **= aa;\n        console.log(z); //100000\n\n    // 3. Operadores de cadena\n        //El operador de concatenación (+) se usa para concatenar (agregar) cadenas de texto o también llamados strings.\n        let result = \"If\" + \"Geek\" + \"Then\";\n        console.log(result); //IfGeekThen\n\n    // 4. Operadores de comparación\n        //Operador igual (==), devuelve verdadero si los operandos son iguales. Solo compara los valores de los operandos, ignorando su tipo al comparar.\n        console.log(2 == 4); //false\n        console.log(\"2\" == 2); //true\n\n        //Operador no igual (!=), devuelve verdadero si los operandos no son iguales. También ignora el tipo de operandos al comparar.\n        console.log(2 != 4); //true\n        console.log(2 !=\"2\"); //false}\n\n        //Operador de igualdad estricta (===), devuelve verdadero si los operandos son iguales. Compara tanto los valores como los tipos de operandos mientras compara.\n        console.log(2 === 4); //false\n        console.log(\"2\" === 2); //false\n\n        //Operador estricto no igual (!==), devuelve verdadero si los operandos no son iguales. También compara ambos: los valores y el tipo de operandos mientras compara.\n        console.log(2 !== 4); //true\n        console.log(2 !== \"2\"); //true\n\n        //Operador mayor que (>), devuelve verdadero si el operando izquierdo es mayor que el operando derecho.\n        console.log(10 > 4); // true\n        console.log(5 > 5); //false\n\n        //Operador mayor que o igual (>=), devuelve verdadero si el operando izquierdo es mayor o igual que el operando derecho.\n        console.log(10 >= 4); //true\n        console.log(5 >= 5); //true\n\n        //Operador menor que (<), devuelve verdadero si el operando izquierdo es menor que el operando derecho.\n        console.log(10 < 4); //false\n        console.log(5 < 5 ); //false\n\n        //Operador menor o igual (<=), devuelve verdadero si el operando izquierdo es menor o igual que el operando derecho.\n        console.log(10 <= 4); //false\n        console.log(5 <= 5); //true\n\n    // 5. Operadores lógicos\n        //AND lógico (&&)\n        //Uso: expr1 && expr2\n        //Devuelve expr1 si se puede convertir a falso; de lo contrario, devuelve expr2. Cuando se usa con valores booleanos, && devuelve verdadero si ambos operandos son verdaderos; de lo contrario, devuelve falso.\n        console.log(true || false); //true\n\n        //NO lógico (!)\n        //Uso: !expr\n        //Devuelve falso si su único operando se puede convertir en verdadero; de lo contrario, devuelve verdadero.\n        console.log(!true); //false\n        \n    // 6. Operadores Bitwise\n        //Operador bitwise AND(&) - Este operador realiza una operación AND booleana en cada bit de sus argumentos enteros.        \n        // In binary-\n        // 4: 100\n        // 1: 001\n        console.log(4 & 1); //0\n\n        //Operador Bitwise OR (|) - Este operador realiza una operación OR booleana en cada bit de sus argumentos enteros.\n        console.log(4 | 1); //5\n\n        //Operador Bitwise XOR (^) - Este operador realiza una operación OR exclusiva booleana en cada bit de sus argumentos enteros.\n        console.log(4 ^ 1); //5\n\n        //Operador Bitwise NOT (~) - Este operador invierte todos los bits del operando.\n        console.log(~4); // -5\n\n        //Operador de desplazamiento a la izquierda (<<)\n        console.log(4<<1); //8\n\n        //Operador de desplazamiento a la derecha (>>)\n        console.log(4>>1); //2\n\n    // 7. Operadores especiales\n        //Operador Ternario: El operador ternario es la abreviatura de la instrucción if-else. Asigna valor a una variable en base a una condición, la sintaxis de la misma es:\n        \n        condition ? value1 : value2\n\n        //Si la condición es verdadera, el operador devuelve el valor de value1. De lo contrario, devuelve el valor de value2.\n\n        let resultado = (200 > 100) ? \"Yes\" : \"No\";\n        console.log(resultado); //Yes\n\n        //Operador Typeof\n        //Se utiliza para encontrar el tipo de datos de un valor o variable.\n        console.log(typeof(100)); //number\n        console.log(typeof(\"100\")); //string\n\n    //8. Tipo de datos de objeto en JavaScript\n        //Puede crear un objeto vacío en JavaScript usando la sintaxis de \"constructor de objetos\" (nuevo Objeto()) o la sintaxis de \"objeto literal\" (llaves {...}).\n        let obj1 = new Object();\n        let obj2 = {};\n\n        let obj = {\n            \"key1\" : \"value1\",\n            \"key2\" : \"value2\"\n            }\n        console.log(obj.key1); //value1\n\n// - Utilizando las operaciones con operadores que tú quieras, crea ejemplos que representen todos los tipos de estructuras de control que existan\n//en tu lenguaje: Condicionales, iterativas, excepciones...\n//- Debes hacer print por consola del resultado de todos los ejemplos.\n\n    //Condicionales\n        const mayorEdad = 18;\n\n        if(mayorEdad >= 18){\n            console.log(\"Es mayor de edad\");\n        }else {\n            console.log(\"Es menor de edad\");\n        }\n    \n    //Ciclos, Bucles o Loops\n    //For\n\n    const pasos = 5;\n\n    for(let paso = 0; paso <= pasos; paso++){\n        console.log(\"Estoy dando el siguiente paso: \" + paso);\n    }\n\n    //For in\n    var dias = [\"Lunes\", \"Martes\", \"Miércoles\", \"Jueves\", \"Viernes\", \"Sábado\", \"Domingo\"];\n    \n    for(i in dias) {\n    console.log(dias[i]);\n    }\n\n    //While\n    const contador = 0;\n\n    while(contador < 3) {\n        contador++\n    }\n    console.log(\"Contador es igual a : \", contador);\n\n    //Switch\n\n    switch(tipoFruta){\n        case \"Naranjas\":\n            console.log(\"Las Naranjas cuestan $5\");\n            break;\n        case \"Manzanas\":\n            console.log(\"Las Manzanas cuestan $10\");\n            break;\n        case \"Fresas\":\n            console.log(\"Las Fresas cuestan $15\");\n            break;\n        default:\n            console.log(\"Disculpa, no tenemos ese tipo de fruta: \", tipoFruta);\n            break;\n    }\n\n//DIFICULTAD EXTRA (opcional):\n//Crea un programa que imprima por consola todos los números comprendidos entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n//Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\nfor( let num = 10; num <= 55; num++){\n    if(num % 2 === 0 && num !== 16 && num % 3 !== 0){\n        console.log(num);\n    }\n}\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/victor-Casta.js",
    "content": "//Operadores en JavaScript\n\n//✅ Operadores aritmeticos\n  let suma = 1 + 2;\n  let resta = 2 - 1;\n  let division = 4 / 2;\n  let multiplicacion = 2 * 2;\n  let residuo = 8 % 2;\n  let exponenciacion = 2 ** 8;\n\n//✅ Operadores relacionales\n  // in\n  let micoche = { marca: \"Honda\", modelo: \"Accord\", año: 1998 };\n  \"marca\" in micoche; // devuelve true\n  \"modelo\" in micoche; // devuelve true\n  // instanceOf\n  let color1 = new String(\"verde\");\n  console.log(color1 instanceof String);\n  //< menor que\n  let a = 10 < 11;\n  //> mayor que \n  let b = 11 > 10;\n  //<= menor igual que\n  let c = 10 <= 10;\n  //>= mayor igual que\n  let d = 11 >= 11;\n\n  //✅ Operadores de igualdad\n    //operador de igualdad\n    let e = 10 == 10\n    //operador de desigualdad\n    let f = 10 != 9\n    //operador de igualdad estricta\n    let g = 10 === 10\n    //operador de disigualda estricta\n    let h = 10 !== 9\n\n  //✅ Operadores de desplazamiento binario\n    console.log(9 << 3);\n    console.log(9 >> 3);\n    console.log(-9 >>> 3)\n\n  //✅ Operadores binarios bit a bit\n  console.log(14 & 9);\n  console.log(13 | 2);\n  console.log(11 ^ 1);\n\n  //✅ Operadores logicos binarios y operador ternario\n  10 === 10 && 2 === 2\n  10 === 10 || 2 === 2 ? true : false\n\n  // Operadores de  asignacion\n  let x = 5;   // Operador de asignación simple (=)\n  let y = 10;\n  y += 5;      // Operador de asignación de suma (+=)\n  let z = 15;\n  z -= 3;      // Operador de asignación de resta (-=)\n  let l = 4;\n  l *= 2;      // Operador de asignación de multiplicación (*=)\n  let m = 8;\n  m /= 4;      // Operador de asignación de división (/=)\n  let k = 7;\n  k %= 3;      // Operador de asignación de módulo (%=)\n  let n = 2;\n  n **= 3;     // Operador de asignación de exponenciación (**=)\n\n  for (let i = 10; i <= 55; i++) {\n    if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n      console.log(`${i} es par y cumple con las condiciones`);\n    }\n  }\n  "
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/vmatmarco.js",
    "content": "/* Tipos de operadores en JavaScript */\n\n// Operadores aritméticos\nlet suma = 1 + 2;\nlet resta = 3 - 1;\nlet multiplicacion = 2 * 4;\nlet division = 10 / 2;\nlet modulo = 10 % 3;\n\n// Operadores de asignación\nlet x = 5;\nx += 2; // x = x + 2;\nx -= 3; // x = x - 3;\nx *= 4; // x = x * 4;\nx /= 2; // x = x / 2;\nx %= 3; // x = x % 3;\n\n// Operadores de comparación\nlet a = 5;\nlet b = 10;\nconsole.log(a == b); // false\nconsole.log(a != b); // true\nconsole.log(a > b); // false\nconsole.log(a < b); // true\nconsole.log(a >= b); // false\nconsole.log(a <= b); // true\n\n// Operadores lógicos\nlet c = true;\nlet d = false;\nconsole.log(c && d); // false\nconsole.log(c || d); // true\nconsole.log(!c); // false\n\n// Operadores de concatenación\nlet nombre = \"John\";\nlet apellido = \"Doe\";\nlet nombreCompleto = nombre + \" \" + apellido;\nconsole.log(nombreCompleto); // \"John Doe\"\n\n// Operador ternario\nlet edad = 18;\nlet mensaje = (edad >= 18) ? \"Eres mayor de edad\" : \"Eres menor de edad\";\nconsole.log(mensaje); // \"Eres mayor de edad\"\n\n// Operador de tipo\nlet numero = 10;\nconsole.log(typeof numero); // \"number\"\n\n\n/* Estructuras de control */\n\n// Estructuras condicionales\nlet numero1 = 5;  // numero1 = 5\nlet numero2 = 10; // numero2 = 10\nif (numero1 > numero2) {\n    console.log(\"numero1 es mayor que numero2\");\n} else if (numero1 < numero2) {\n    console.log(\"numero1 es menor que numero2\");\n} else {\n    console.log(\"numero1 es igual a numero2\");\n}\n\n\n/* Estructuras de repetición */\n\n// Bucle FOR\nfor (let i = 0; i < 10; i++) {\n    console.log(\"El valor de i es: \" + i);\n}\n\n// Bucle WHILE\nlet i = 0;\nwhile (i < 10) {\n    console.log(\"El valor de i es: \" + i);\n    i++;\n}\n\n// Bucle DO-WHILE\nlet j = 0;\ndo {\n    console.log(\"El valor de j es: \" + j);\n    j++;\n} while (j < 10);\n\n// Estructura de control SWITCH\nlet dia = \"Miércoles\";  // Cambia este valor para probar diferentes casos\n\nswitch (dia) {\n    case \"Lunes\":\n        console.log(\"Hoy es Lunes\");\n        break;\n    case \"Martes\":\n        console.log(\"Hoy es Martes\");\n        break;\n    case \"Miércoles\":\n        console.log(\"Hoy es Miércoles\");\n        break;\n    case \"Jueves\":\n        console.log(\"Hoy es Jueves\");\n        break;\n    case \"Viernes\":\n        console.log(\"Hoy es Viernes\")\n        break;\n    case \"Sábado\":\n        console.log(\"Hoy es Sábado\")\n        break;\n    case \"Domingo\":\n        console.log(\"Hoy es Domingo\")\n        break;\n    default:\n        console.log(\"El valor no corresponde a un día de la semana\")\n}\n\n// Estructura de control de errores TRY/CATCH\ntry\n{\ndocument.write(10/variable1) ; //Variable insegura del usuario (puede introducir un 0)\n}catch(e)\n{\nalert(e.message); // Mensaje en caso de error\n}\n\n\n\n/* DIFICULTAD EXTRA */\n\nfor(i = 1; i<56; i++){\n    if(i % 2 === 0 && i !== 16 && i%3 !== 0){\n        console.log(i);\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/vsUnix0.js",
    "content": "console.log('-------------asignación-------------');\r\n\r\nlet num = 50;\r\n\r\nconsole.log(`El número inicial es ${num}\\n`)\r\n\r\nconsole.log(`Asignación (num = 25): ${num = 25}`);\r\nconsole.log(`Asignación por suma (num + 25): ${num += 25}`);\r\nconsole.log(`Asignación por resta (num - 4): ${num -= 4}`);\r\nconsole.log(`Asignación por multiplicación (num * 3): ${num *= 3}`);\r\nconsole.log(`Asignación por división (num / 3): ${num /= 3}`);\r\nconsole.log(`Asignación por residuo (num % 8): ${num %= 8}`);\r\nconsole.log(`Asignación por exponenciación (num ** 7): ${num **= 7}`);\r\nconsole.log(`Asignación de desplazamiento a la izquierda (num << 3): ${num <<= 3}`);\r\nconsole.log(`Asignación de desplazamiento a la derecha (num >> 4): ${num >>= 4}`);//si hay valores negativos basta con colocar >>> para evitar\r\nconsole.log(`Asignación AND bit a bit (num & 40000): ${num &= 40000}`);\r\nconsole.log(`Asignación XOR bit a bit (num ^ 32): ${num ^= 32}`);\r\nconsole.log(`Asignación OR bit a bit (num | 74): ${num |= 74}`);\r\nconsole.log(`Asignación AND lógico (num && 65): ${num &&= 65}`);\r\nconsole.log(`Asignación OR lógico (num || null) ${num ||= 43}`);//no cambia porque la izquierda es true\r\nconsole.log(`Asignación de anulación lógica (num ?? 43) ${num ??= 43}\\n`);// tampoco cambia porque es true\r\n\r\nconsole.log('-------------desestructuración----------------');\r\n\r\nconst array = [1, 3, 5, 6, 8];\r\n\r\nconst [valor1, valor2, valor3] = array;\r\nconsole.log(valor3);//imprime 5\r\n\r\nconsole.log('-------------operadores de comparación-------');\r\nlet num1 = 3\r\nlet num2 = 4\r\n\r\nconsole.log(`estos son los numeros num1 = ${num1} y num2 = ${num2}\\n`)\r\n\r\nconsole.log(`comparación de igualdad débil:\\nnum1 == num2: ${num1 == num2}\\n`);\r\nconsole.log(`comparación de igualdad fuerte:\\nnum1 === num2: ${num1 === num2}\\n`);\r\nconsole.log(`comparación de desigualdad débil:\\nnum1 != num2: ${num1 != num2}\\n`);\r\nconsole.log(`comparación de desigualdad fuerte:\\nnum1 !== num2: ${num1 !== num2}\\n`);\r\nconsole.log(`mayor que:\\nnum1 > num2: ${num1 > num2}\\n`);\r\nconsole.log(`menor que:\\nnum1 < num2: ${num1 < num2}\\n`);\r\nconsole.log(`mayor o igual que:\\nnum1 >= num2: ${num1 >= num2}\\n`);\r\nconsole.log(`menor o igual que:\\nnum1 <= num2: ${num1 <= num2}\\n`);\r\n\r\nconsole.log('-------------operadores aritméticos-------');\r\n\r\nlet x = 84;\r\nlet y = 94;\r\n\r\nconsole.log(`Valores iniciales: x = ${x} y = ${y}\\n`);\r\nconsole.log(`residuo:\\n x % y: ${x % y} <= da el residuo de una división`);\r\nconsole.log(`incremento:\\n ++x: ${++x} <= se incrementa a si mismo 1 vez el operador se pone al inicio para que muestre el valor`);\r\nconsole.log(`decremento:\\n --y: ${--y} <= decrementa 1 vez`);\r\nconsole.log(`negación unaria:\\n -x: ${-x} <= se niega el número, esto quiere decir que se vuelve negativo`);\r\nconsole.log(`positivo unario:\\n +x: ${+x} <= se coloca el número en positivo`);\r\nconsole.log(`operador de exponenciación:\\n x**y: ${x**y}\\n`);\r\n\r\nconsole.log(`-------------operadores bit a bit---------`);\r\n\r\nx = 13;\r\ny = 52;\r\n\r\nconsole.log(`valores iniciales ${x} y ${y}\\n`);\r\nconsole.log(`AND a nivel de bits:\\n x & b = ${x & y}`);\r\nconsole.log(`OR a nivel de bits:\\n x | y = ${x | y}`);\r\nconsole.log(`XOR a nivel de bits:\\n x ^ y = ${x ^ y}`);\r\nconsole.log(`NOT a nivel de bits:\\n ~x = ${~x}`);\r\nconsole.log(`Desplazamiento a la izquierda:\\n x << y = ${x << y}`);\r\nconsole.log(`Desplazamiento a la derecha:\\n x >> y = ${x >> y}\\n`);\r\n\r\nconsole.log('----------operadores lógicos--------------');\r\n\r\nlet bool = true;\r\nlet bool2 = false;\r\n\r\nconsole.log(`operador &&:\\n bool && bool2 = ${bool && bool2} <= No se cumple porque ambos son diferentes`);\r\nconsole.log(`operador ||:\\n bool || bool2 = ${bool || bool2} <= Este si devuelve true porque uno de los dos es true`);\r\nconsole.log(`operador !:\\n !bool = ${!bool} <= deuvelve false porque lo invierte\\n`);\r\n\r\nconsole.log('-----------operador de cadena-------------');\r\n\r\nlet animal1 = 'dog';\r\nlet animal2 = 'cat';\r\n\r\nconsole.log('I have 2 pets' + ' ' + animal1 + ' and ' + `${animal2}\\n`);\r\n\r\nconsole.log('-------operador condicional ternario------');\r\n\r\nlet ana = 'bird'\r\nconst result = ana === 'dog' \r\n    ? 'Es su mascota' \r\n    : 'No es su mascota';\r\n\r\nconsole.log(`${result}\\n`);\r\n\r\nconsole.log('-------------operador in------------------');\r\n\r\nconst cars = [\r\n    car1 = {\r\n        make: 'Honda', \r\n        model: '2027'\r\n    }, \r\n    car2 = {\r\n        make: 'Suzuki', \r\n        model: '2027'\r\n        }, \r\n    car3 = {\r\n        make: 'Chevrolet', \r\n        model: '2027'\r\n    }\r\n];\r\n\r\nconsole.log(JSON.stringify(cars, null, 3))\r\n\r\nconsole.log(4 in cars ,'\\n')\r\n\r\n//Estructuras de control\r\n\r\nconsole.log('----------------if-else-------------------');\r\n\r\n\r\nfunction clasificarEdad(edad) {\r\n    if (edad < 0){\r\n        console.log('Edad invalida')\r\n    } else if(edad <= 12) {\r\n        console.log('Niño/a')\r\n    } else if(edad <= 17){\r\n        console.log('Adolescente')\r\n    } else if(edad <= 59){\r\n        console.log('Adulto')\r\n    } else{\r\n        console.log('Adulto mayor')\r\n    }\r\n}\r\n\r\nclasificarEdad(60);\r\n\r\nconsole.log('----------------switch--------------------');\r\n\r\nlet color = 2\r\n\r\nswitch (color) {\r\n    case 1:\r\n        console.log('Color elegido: amarillo')\r\n        break;\r\n\r\n    case 2:\r\n        console.log('Color elegido: Verde')\r\n        break;\r\n\r\n    case 3:\r\n        console.log('Color elegido: Azul')\r\n        break;\r\n\r\n    default:\r\n        break;\r\n}\r\n\r\nconsole.log('------------------for---------------------');\r\n\r\nlet numeral = ''\r\n\r\nfor(let i = 0; i < 10; ++i){\r\n    let inglz = numeral += '#';\r\n    console.log(inglz)\r\n}\r\n\r\nconsole.log('-----------------while--------------------');\r\n\r\nlet f = 0\r\nlet conteo = 5\r\n\r\nwhile (f < 5){\r\n    f++\r\n    console.log(conteo--);\r\n    if (f ==5){\r\n        console.log('!Despegue')\r\n    }\r\n}\r\n\r\n\r\nconsole.log('-------------RETO OPCIONAL----------------');\r\nfor (let i = 10; i <= 55; i++){\r\n    if (i !== 16 && i%3 !== 0){\r\n        console.log(i)\r\n    }\r\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/wapastorv.js",
    "content": "/*\n# #01 OPERADORES Y ESTRUCTURAS DE CONTROL\n> #### Dificultad: Fácil | Publicación: 02/01/24 | Corrección: 08/01/24\n\n## Ejercicio  \n*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n// Tipo de Operadores en JavaScript\n\n// Operador Aritméticos\nconsole.log(2 + 2); // Suma\nconsole.log(2 - 2); // Resta\nconsole.log(2 * 2); // Multiplicación\nconsole.log(2 / 2); // División\nconsole.log(2 % 2); // Módulo, que es el resto de la división\nconsole.log(2 ** 2); // Exponenciación\nlet x = 5;\nconsole.log(x++); // Incremento\nconsole.log(x--); // Decremento\n\n\n// Operador Lógicos\nconsole.log(true && true); // AND, devuelve true si ambos son true; ejemplos (5 > 2 && 2 > 1) // true\nconsole.log(true || false); // OR, devuelve true si uno de los dos es true; ejemplos (5 > 2 || 2 > 5) // true\nconsole.log(!true); // NOT, invierte el valor; ejemplos (!true) o !(5 > 3)// false\n\n// Operador de comparación\nconsole.log(2 > 2); // Mayor que\nconsole.log(2 < 2); // Menor que\nconsole.log(2 >= 2); // Mayor o igual que\nconsole.log(2 <= 2); // Menor o igual que\nconsole.log(2 == 2); // Igualdad que (no estricto)\nconsole.log(2 != 2); // Desigualdad que (no estricto)\nconsole,log(2 !== 2); // Desigualdad que (estricto)\nconsole.log(2 === 2); // Igualdad (estricto)\n\n// Operador de asignación\nlet a = 2; // Asignación un valor a una variable\nconsole.log(a); // 2\na += 2; // Suma y asignación\nconsole.log(a); // 4\na -= 2; // Resta y asignación\nconsole.log(a); // 2\na *= 2; // Multiplicación y asignación\nconsole.log(a); // 4\na /= 2; // División y asignación\nconsole.log(a);// 2\na %= 2; // Módulo y asignación\nconsole.log(a); // 0\na **= 2; // Exponenciación y asignación\nconsole.log(a); // 0\n\n\n//Operador de identidad\nconsole.log(2 === 2); // Igual que y mismo tipo (true)\nconsole.log(2 === '2'); // Igual que y mismo tipo (false)\n\n// Operador de pertenencia\nlet b = [1, 2, 3];\nconsole.log(2 in b); // Existe en el array (true) \nconsole.log(4 in b); // Existe en el array (false)\n\n// Operador de bits\nconsole.log(2 & 2); // AND\nconsole.log(2 | 2); // OR\nconsole.log(2 ^ 2); // XOR\nconsole.log(~2); // NOT\nconsole.log(2 << 2); // Desplazamiento a la izquierda\nconsole.log(2 >> 2); // Desplazamiento a la derecha \nconsole.log(2 >>> 2); // Desplazamiento a la derecha sin signo, ejemplos con números negativos\n\n// Operador de tipo\nconsole.log(typeof 2); // Number, devuelve el tipo de una variable\n\n\nlet c = new String('Hola');\nconsole.log(c instanceof String); //instanceof, devuelve true si un objeto es una instancia de un tipo de objeto. // true\n\n// Operador de agrupación\nconsole.log(5 + 3) * 2; // Agrupación de operaciones\n\n// Operador de acceso a propiedad (objeto y array)\nlet d = {nombre: 'Juan'};\nconsole.log(d.nombre); // Juan, el punto se utiliza para acceder a las propiedades de un objeto\n\nlet e = [1, 2, 3];\nconsole.log(e[0]); // 1, el corchete se utiliza para acceder a los elementos de un array\n\n// Operador de encadenamiento opcional\nlet f = {nombre: 'Juan'};\nconsole.log(f.nombre?.apellido); // undefined, si la propiedad no existe no lanza un error\n\n\n// Operador de Coalescencia nula\nlet g = null;\nconsole.log(g ?? 'Valor por defecto'); // Valor por defecto, si el valor es null o undefined devuelve el valor por defecto o valor de la derecha\n\n// Operador de propagación y rest\nlet h = [1, 2, 3];\nlet i = [4, 5, 6];\nconsole.log([...h, ...i]); // [1, 2, 3, 4, 5, 6], propagación de arrays (spread operator)\n\nlet j = [1, 2, 3];\nlet [k, ...l] = j;\nconsole.log(k); // 1, rest operator (desestructuración de arrays)\nconsole.log(l); // [2, 3], rest operator (desestructuración de arrays)\n\n\n// Estructuras de control en JavaScript\n\n// Condicionales \n\n    //if ; if else y if else if\n    let edad = 18;\n    if (edad >= 18) {\n        console.log('Eres mayor de edad');\n    }\n    else {\n        console.log('Eres menor de edad');\n    }\n\n\n    let dia = \"lunes\";\n    if (dia === \"lunes\") {\n        console.log(\"Hoy es lunes\");\n    }\n    else if (dia === \"martes\") {\n        console.log(\"Hoy es martes\");\n    }\n    else {\n        console.log(\"Hoy es otro día\");\n    }\n\n    // Switch\n    let fruta = \"manzana\";\n    switch(fruta) {\n      case \"manzana\":\n        console.log(\"Es una manzana\");\n        break;\n      case \"pera\":\n        console.log(\"Es una pera\");\n        break;\n      default:\n        console.log(\"Es otra fruta\");\n    }\n\n    //Ternario\n    let alto = 180;\n    let esAlto = alto >= 180 ? 'Eres alto' : 'No eres alto';\n    console.log(esAlto); // Eres alto\n\n\n    // Bucles (loops)\n\n    // For\n    for (let i = 0; i < 5; i++) {\n        console.log(i); // 0, 1 \n    }\n\n    // for .. of, recorre las propiedades de un objeto iterando, como arrays o string\n    let personas = [\"juan\", \"maria\", \"pedro\"];\n    for (let persona of personas) {\n        console.log(persona);  // Muestra los elementos del array, juan, maria, pedro\n    }\n\n    let saludoEspecial = \"Hola Mundo, soy un saludo especial\";\n    for (let letra of saludoEspecial) {\n        console.log(letra); // Muestra cada letra del string Hola Mundo, soy un saludo especial \n    }\n\n    // for .. in, itera sobre las propiedades de un objeto(propiedades enumerables)\n    let carro = {marca: \"Toyota\", modelo: \"Corolla\"};\n    for (let propiedad in carro) {\n        console.log(`${propiedad}: ${carro[propiedad]}`); // Muestra las propiedades del objeto, marca: Toyota, modelo: Corolla\n    }\n\n    /* While:\n     Se ejecuta un bloque de código mientras la condición sea verdadera. Es util cuando no se sabe cuantas veces se va a ejecutar el bloque de código.\n    */\n    let contador = 0;\n    while (contador < 5) {\n        console.log(contador);   \n        contador++;\n    }\n    /* Do While:\n        Se ejecuta un bloque de código al menos una vez y luego se ejecuta mientras la condición sea verdadera.\n    */\n    let nuemro = 5;\n    do {\n        console.log(nuemro); // 5, 4, 3, 2, 1\n        nuemro--;\n    } while(nuemro > 0);\n\n\n    // Excepciones\n    \n    /* Try ... Catch: \n        Se utiliza para capturar errores en un bloque de código. Si se produce un error en el bloque de código dentro del bloque try, se ejecuta el bloque catch.\n    */\n    try {\n        let resultado = 10 / 0;\n        console.log(resultado);\n    } catch (error) {\n        console.log(\"Ocurrió un error: \", error.message); // Ocurrió un error:  Cannot divide by zero\n    }\n\n    /* Finally: \n        Se ejecuta un bloque de código después de que se haya intentado ejecutar el bloque try y el bloque catch. Independientemente de si se produce un error o no.\n    */\n    try {\n        let resultado = 10 / 2;\n        console.log(resultado); // 5\n    } catch (error) {\n        console.log(\"Ocurrió un error: \", error.message);\n    } finally {\n        console.log(\"Bloque finally\"); // Bloque finally\n    }\n\n    /* Throw:\n        Permite lanzar una error manualmente. Se puede crear errores personalizados.\n    */\n    try {\n        throw new Error(\"Error personalizado\");\n    } catch (error) {\n        console.log(\"Ocurrió un error: \", error.message); // Ocurrió un error:  Error personalizado\n    }\n\n\n    // EJECICIO DIFICULTAD EXTRA\n    for (let i = 10; i <= 55; i++) {\n        if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n            console.log(i); \n        }\n    }\n\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/wesborland-github.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n/******************************************************************************************************\n\nSitio web consultado para ejercicios: \n\nhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_operators\n\n*******************************************************************************************************\n******************************************************************************************************/\n\nconsole.log(\"--------> Tipos de operadores en javascript <--------\");\nconsole.log(\"****************  Operadores de asignación: ****************\"); // Operadores de asignación\n\nlet numeroBase = 20; // Asignación\nconsole.log(\"Asignación base =\", numeroBase);\nnumeroBase += 20; // Suma\nconsole.log(\"Suma 20 =\", numeroBase);\nnumeroBase -= 10; // Resta\nconsole.log(\"Resta 10 =\", numeroBase);\nnumeroBase /= 2; // División\nconsole.log(\"Divide 2 =\", numeroBase);\nnumeroBase *= 4; // Multiplicación\nconsole.log(\"Multiplica 4 =\", numeroBase);\nnumeroBase **= 2; // Exponenciación\nconsole.log(\"Exponencia 2 =\", numeroBase);\nnumeroBase %= 7; // Resto\nconsole.log(\"Resto división por 7 =\", numeroBase);\n\n/* \"A parte de éstos existen otros poco comunes que son:\n\n- Asignación de desplazamiento a la izquierda:            \tx <<= y\n- Asignación de desplazamiento a la derecha:\t            x >>= y\t\n- Asignación de desplazamiento a la derecha sin signo:\t    x >>>= y\n- Asignación AND bit a bit:                               \tx &= y\t\n- Asignación XOR bit a bit:                             \tx ^= y\t\t\n- Asignación OR bit a bit:\t                                x |= y\t\n- Asignación AND lógico:\t                                x &&= y\t\n- Asignación OR lógico:           \t                        x ||= y\t\n- Asignación de anulación lógica:\t                        x ??= y\n\n*/\n\nconsole.log(\"**************** Operadores de comparación: ****************\"); // Operadores de comparación\n\nlet numComp = 4;\nlet numCompDos = 8;\n\nconsole.log(\"Igual\", numComp, \"y\", numCompDos, \"=\", numComp == numCompDos); // Igual\nconsole.log(\"No igual\", numComp, \"y\", numCompDos, \"=\", numComp != numCompDos); // No igual\nconsole.log(\n  \"Estrictamente igual\",\n  numComp,\n  \"y\",\n  numCompDos,\n  \"=\",\n  numComp === numCompDos\n); // Estrictamente igual\nconsole.log(\n  \"Estrictamente no igual\",\n  numComp,\n  \"y\",\n  numCompDos,\n  \"=\",\n  numComp !== numCompDos\n); // Estrictamente no igual\nconsole.log(\"Mayor\", numComp, \"que\", numCompDos, \"=\", numComp > numCompDos); // Mayor\nconsole.log(\n  \"Mayor o igual\",\n  numComp,\n  \"que\",\n  numCompDos,\n  \"=\",\n  numComp >= numCompDos\n); // Mayor o igual\nconsole.log(\"Menor\", numComp, \"que\", numCompDos, \"=\", numComp < numCompDos); // Menor\nconsole.log(\n  \"Menor o igual\",\n  numComp,\n  \"que\",\n  numCompDos,\n  \"=\",\n  numComp <= numCompDos\n); // Menor o igual\n\nconsole.log(\"**************** Operadores aritméticos: ****************\"); // Operadores aritméticos\n\nlet a = 2;\nlet b = 3;\nlet c = 4;\nlet d = 5;\n\nconsole.log(\"Suma\", a, \"+\", b, \"=\", a + b); // Suma\nconsole.log(\"Resta\", d, \"-\", a, \"=\", d - a); // Resta\nconsole.log(\"Multiplicación\", b, \"*\", c, \"=\", b * c); // Multiplicación\nconsole.log(\"División\", c, \"/\", a, \"=\", c / a); // División\nconsole.log(\"Resto\", d, \"/\", a, \"=\", d % a); // Resto\nconsole.log(\"Incremento\", d, \"=\", ++d); // Incremento\nconsole.log(\"Decremento\", a, \"=\", --a); // Decremento\nconsole.log(\"Negación unaria\", a, \"=\", -a); // Negación unaria\nconsole.log(\"Positivo unario\", b, \"=\", b); // Positivo unario\nconsole.log(\"Operador de exponenciación\", c, \"elevado a\", d, \"=\", c ** d); // Operador de exponenciación\n\nconsole.log(\"**************** Operadores bit a bit: ****************\"); // Operadores bit a bit\n\nconsole.log(\"AND (&) a nivel bits (a & b) =\", a & b); // AND\nconsole.log(\"OR (|) a nivel bits (a | b) =\", a | b); // OR\nconsole.log(\"XOR (^) a nivel bits (a ^ b) =\", a ^ b); // XOR    (Anotación --> alt + 94 = ^)\nconsole.log(\"NOT (~) a nivel bits (~a) =\", ~b); // NOT     (Anotación --> alt + 126 = ~)\nconsole.log(\n  \"Desplazamiento a la izquierda (<<) a nivel bits (a << b) =\",\n  a << b\n); // Desplazamiento a la izquierda\nconsole.log(\"Desplazamiento a la derecha (>>) a nivel bits (a >> b) =\", a >> b); // Desplazamiento a la derecha\n\nconsole.log(\"**************** Operadores lógicos: ****************\"); // Operadores lógicos\n\nconsole.log(\"AND lógico(&&) entre true y false =\", true && false); // Devuelve true si ambos operandos son true, de lo contrario false.\nconsole.log(\"OR lógico(||) entre true y false =\", true || false); // Devuelve true si algún operando es true, de lo contrario false.\nconsole.log(\"NOT lógico(!) de !false =\", !false); // Devuelve false si el operando se puede convertir a true, de lo contrario true. ej: false por si solo se puede convertir a true, pero con el ! el resultante seria siempre false.\n\nconsole.log(\"**************** Operadores de cadena: ****************\"); // Operadores de cadena\n\nconsole.log(\n  \"Ejemplo operador en cadena sumando a + b, donde a=(Retos de) y b=(Brais) =\",\n  \"Retos de \" + \"Brais\"\n); // Suma de operadores en cadena.\n\nconsole.log(\n  \"**************** Operador condicional (ternario): ****************\"\n); // Operador condicional (ternario)\n\nedad = 21;\nlet esMayor = edad >= 18 ? \"Es mayor de edad\" : \"Es menor de edad\"; // si la edad es mayo o igual a 18 esMayor = Es mayor de edad. Sino es menor de edad.\nedad = 17;\nesMayor1 = edad >= 18 ? \"Es mayor de edad\" : \"Es menor de edad\"; // si la edad es mayo o igual a 18 esMayor = Es mayor de edad. Sino es menor de edad.\n\nconsole.log(\"¿ Es mayor de edad con 21 años ? \", esMayor); // Si una condición es true entonces resulta val1, de lo contrario resulta val2\nconsole.log(\"¿ Es mayor de edad con 17 años ? \", esMayor1); // Si una condición es true entonces resulta val1, de lo contrario resulta val2\n\nconsole.log(\"**************** Operador coma: ****************\"); // Operador coma\n\nlet resultado = (5 + 4, 4 / 2);\n\nconsole.log(\n  \"Al evaluar ambos operandos y devolver el último, el resultado de la operación (5+4, 4/2) =\",\n  resultado\n); // Evalúa ambos operandos y devuelve el valor del último operando.\n\nconsole.log(\"**************** Operador unarios: ****************\"); // Operadores unarios\n\nlet numDelete = { a: 23, b: 24 };\ndelete numDelete.a;\nconsole.log(\"Variable con a y b de objetos y se elimina a  =\", numDelete); // Operador delete que elimina la propiedad de un objeto\nlet typeOne = \"Hola\";\nlet typeTwo = 4;\nconsole.log(\n  \"El tipo de operando no evaluado de\",\n  typeOne,\n  \"y\",\n  typeTwo,\n  \"=\",\n  typeof typeOne,\n  typeof typeTwo\n); // Operador typeof que devuelve el tipo de operando no evaluado\nconsole.log(\n  \"El operador void aplicado a typeOne =\",\n  typeOne,\n  \"resulta en typeOne =\",\n  void typeOne\n); // Operador void que especifica una expresión que se evaluará sin devolver un valor siempre como \"undefined\"\n\nconsole.log(\"**************** Operador relacionales: ****************\"); // Operadores relacionales\n\nvar selecciones = [\"Argentina\", \"Alemania\", \"Brasil\", \"Francia\", \"Inglaterra\"];\n\nconsole.log(\n  \"Operador in devuelve del arreglo de la variable si hay 3 equipos =\",\n  3 in selecciones\n); // Operador in devuelve true si la propiedad especificada está en el objeto especificado\nconsole.log(\n  \"Operador instance of devuelve de la variable si es un array =\",\n  selecciones instanceof Array\n); // Operador instance of devuelve true si el objeto especificado es del tipo de objeto especificado\n\nconsole.log(\n  \"**************** Estructuras de control (bucles e iteración): ****************\"\n); // Estructuras de control (bucles e iteración)\n\nfor (let i = 0; i < 4; i++) {\n  console.log(\"iteración for =\", i);\n} //for\n\nlet count = 0;\ndo {\n  console.log(\"contador con do..while =\", count);\n  count++;\n} while (count < 3); //do...while\n\nlet num = 4;\nwhile (num > 0) {\n  console.log(\"Número con while =\", num);\n  num--;\n} //while\n\ncount = 0;\nmarkLoop: while (count < 4) {\n  console.log(\"contador con labeled =\", count);\n  count++;\n  if (count === 4) {\n    break markLoop;\n  }\n} //labeled\n\nfor (let count = 0; count < 4; count++) {\n  if (count === 4) {\n    break;\n  }\n  console.log(\"contador con break =\", count);\n} //break\n\nfor (let count = 0; count < 4; count++) {\n  if (count === 2) {\n    continue;\n  }\n  console.log(\"contador con continue en 2 =\", count);\n} //continue\n\nlet proveeedor = {\n  nombre: \"claro\",\n  downstream: \"50 Mbps\",\n  upstream: \"10 Mbps\",\n};\nconsole.log(\"Ejemplo for..in =\");\nfor (let propiedad in proveeedor) {\n  console.log(propiedad + \":\" + proveeedor[propiedad]);\n} //for...in\n\nconsole.log(\"Ejemplo for..of =\");\nlet angulos = [\"90°\", \"180°\", \"230°\"];\nfor (let angulo of angulos) {\n  console.log(angulo);\n} //for...of\n\nconsole.log(\"**************** Dificultad extra: ****************\"); // Dificultad extra\n\nfor (let count = 10; count <= 55; count++) {\n  if (count !== 16 && count % 2 === 0 && count % 3 !== 0) {\n    console.log(\"Números en dificultad extra =\", count);\n  }\n} // Dificultad extra : números comprendidos entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/willicar27.js",
    "content": "/*Ejercicio 01 moureDev \ntipos de operadores en javascript\n*/\n\n//Operadores Aritmeticos\n\nlet suma = 'la suma se representa 5 + 9'; 5 + 9;\nlet resta = 'la resta se representa 5 - 9'; 5 - 9;\nlet multiplicacion = 'la multiplicacion se representa 5 * 9'; 5 * 9;\nlet division = 'la division se representa 5 / 9'; 5 / 9;\n\n//Operadores de Asignacion\n\nlet a = 5;   // asignar un valor a una variable\nlet b = 7;\nlet f = a ++;  // sumarle un numero a una variable\nlet g = b --;  // restarle un numero a un variable\n\n//Operadores de Comparacion\n\nlet x = 10;\nlet y = 11;\nlet mayorQue = (x > y);\nlet menorQue = (x < y);\nlet menorIgual = (x <= y);\nlet mayorIgual = (x >= y);\nlet comparador = (x == y);\nlet comparadorVariable = ( x === y);\nlet desigual = (x =! y);\n\nif (x != y) {\n    console.log('Los valores de x y y no son iguales');\n}\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/wolffcode.js",
    "content": "    // Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n    /*\n    Operadores de asignacion\nasignacion \n    let x = 10\nmultiplicacion\n    x *= 2\ndivision\n    x /= 2\n\n    */\n\n    /*\n    Operadores de comparacion\nigual\n    ==\nno es igual\n    !=\nestrictamente igual\n    ===\ndesigualdad estricta\n    !==\nmayor que\n    >\nmayor o igual que\n    >=\nmenor que\n    <\nmenor o igual que\n    <=\n    */\n\n    /*\n    Aritmeticos\nresiduo\n    %\nincremento\n    ++\ndecremento\n    --\nnegacion unaria\n    -\npositivo unario\n    +\nexponenciacion\n    **\n    */\n\n    /*\n    Bit a bit\ndesplazamiento izquierda\n    x <<= 2\ndesplazamiento derecha\n    x >>= 2\ndesplazamiento derecha sin signo\n    x >>>= 2\nAND bit a bit\n    x &= y\nXOR bit a bit\n    x ^= y\nOR bit a bit\n    x |= y\nnot bit \n    ~ x\n     */\n\n    /*\n    Logicos\nAND logico\n    x &&= y\nOR logico\n    x ||= y\nanulacion logico\n    x ??= y\n    */\n\n   /*\nOperador ternario\n    condition ? val1 : val2\n   */\n\n    /*\n    Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n    que representen todos los tipos de estructuras de control que existan\n    en tu lenguaje:\n    */\nlet num = 1\nwhile(num<5){\n    console.log(num)\n    num ++\n}\n\ndo{\n    console.log(num)\n    num ++\n}while(num<5)\n\nif(num == 1){\n    console.log(true)\n}else{\n    console.log(false)\n}\n\nswitch(num){\n    case 1:\n        console.log(\"odd\")\n        break\n    case 2:\n        console.log(\"pair\")\n        break\n    case 3:\n        console.log(\"odd\")\n        break\n    case 4:\n        console.log(\"pair\")\n        break\n    case 5:\n        console.log(\"odd\")\n        break\n    default:\n        console.log(\"invalid\")\n}\nfor(let i = 0; i <= 5; i++){\n    console.log(i)\n}\n    // extra\nfor(let i = 10;i<=55;i++){\n\tif(i %3 ==0 ||i == 16){\n\t\tcontinue\n\t}else if(i % 2 == 0){\n\t\tconsole.log(i)\n\t}\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/xmunder.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n// Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje: Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n\n// Operadores aritméticos\nconst a = 4;\nconst b = 2;\n\n// Suma\nconsole.log(a + b); // 6\n// Resta\nconsole.log(a - b); // 2\n// Multiplicación\nconsole.log(a * b); // 8\n// División\nconsole.log(a / b); // 2\n// Resto, residuo o módulo\nconsole.log(a % b); // 0\n// Exponencial\nconsole.log(a ** b); // 16\n// Incremento\nconsole.log(a++); // a = a + 1 = 5\n// Decremento\nconsole.log(a--); // a = a - 1 = 4\n\n// Operadores lógicos\nconst c = true;\nconst d = false;\n\n// AND (&&)\nconsole.log(c && d); // false, devuelve true si ambos operandos son true\n// OR (||)\nconsole.log(c || d); // true, devuelve true si alguno de los operandos es true\n// NOT (!)\nconsole.log(!c); // false, devuelve el valor contrario al operando\n\n// Operadores de comparación\nconst e = 4;\nconst f = 2;\n\n// Igualdad\nconsole.log(e == f); // false, devuelve true si ambos operandos son iguales\n// Desigualdad\nconsole.log(e != f); // true, devuelve true si ambos operandos son diferentes\n// Estrictamente igual\nconsole.log(e === f); // false, devuelve true si ambos operandos son iguales y del mismo tipo\n// Estrictamente desigual\nconsole.log(e !== f); // true, devuelve true si ambos operandos son diferentes o de diferente tipo\n// Mayor que\nconsole.log(e > f); // true, devuelve true si el primer operando es mayor que el segundo\n// Mayor o igual que\nconsole.log(e >= f); // true, devuelve true si el primer operando es mayor o igual que el segundo\n// Menor que\nconsole.log(e < f); // false, devuelve true si el primer operando es menor que el segundo\n// Menor o igual que\nconsole.log(e <= f); // false, devuelve true si el primer operando es menor o igual que el segundo\n\n// Operadores de asignación\nlet g = 4;\nlet h = 2;\n\n// Asignación\nconsole.log((g = h)); // 2, asigna el valor del segundo operando al primero\n// Asignación de suma\nconsole.log((g += h)); // 4, suma el valor del segundo operando al primero\n// Asignación de resta\nconsole.log((g -= h)); // 2, resta el valor del segundo operando al primero\n// Asignación de multiplicación\nconsole.log((g *= h)); // 4, multiplica el valor del segundo operando al primero\n// Asignación de división\nconsole.log((g /= h)); // 2, divide el valor del segundo operando al primero\n// Asignación de resto, residuo o módulo\nconsole.log((g %= h)); // 0, asigna el resto de dividir el valor del primer operando entre el segundo al primero\n// Asignación de exponencial\nconsole.log((g **= h)); // 0, asigna el valor del primer operando elevado al segundo al primero\n\n// Operadores de identidad\nconst i = 4;\nconst j = 2;\n\n// Identidad\nconsole.log(i === j); // false, devuelve true si ambos operandos son iguales y del mismo tipo\n// No identidad\nconsole.log(i !== j); // true, devuelve true si ambos operandos son diferentes o de diferente tipo\n\n// Operadores de pertenencia\nconst k = [1, 2, 3, 4];\nconst l = 2;\n\n// Pertenencia\nconsole.log(l in k); // true, devuelve true si el segundo operando es una propiedad del primero\n\n// Operadores de bits\nconst m = 4;\nconst n = 2;\n\n// AND a nivel de bits\nconsole.log(m & n); // 0, devuelve un 1 para cada bit en la misma posición si ambos operandos son 1\n// OR a nivel de bits\nconsole.log(m | n); // 6, devuelve un 1 para cada bit en la misma posición si alguno de los operandos es 1\n// XOR a nivel de bits\nconsole.log(m ^ n); // 6, devuelve un 1 para cada bit en la misma posición si ambos operandos son diferentes\n// NOT a nivel de bits\nconsole.log(~m); // -5, invierte los bits de un operando\n// Desplazamiento a la izquierda\nconsole.log(m << n); // 16, desplaza los bits del primer operando el número de posiciones indicado por el segundo\n// Desplazamiento a la derecha\nconsole.log(m >> n); // 1, desplaza los bits del primer operando el número de posiciones indicado por el segundo\n\n// Utilizando las operaciones con operadores que tú quieras, crea ejemplos que representen todos los tipos de estructuras de control que existan en tu lenguaje: Condicionales, iterativas, excepciones...\n\n// Condicionales\nconst o = 4;\nconst p = 2;\n\n// IF\nif (o > p) {\n  console.log(`${o} es mayor que ${p}`);\n}\n\n// IF ELSE\nif (o > p) {\n  console.log(`${o} es mayor que ${p}`);\n} else {\n  console.log(`${o} es menor que ${p}`);\n}\n\n// IF ELSE IF\nif (o > p) {\n  console.log(`${o} es mayor que ${p}`);\n} else if (o < p) {\n  console.log(`${o} es menor que ${p}`);\n}\n\n// SWITCH\nconst day = 1;\n\nswitch (o) {\n  case 1:\n    console.log(\"Lunes\");\n    break;\n  case 2:\n    console.log(\"Martes\");\n    break;\n  case 3:\n    console.log(\"Miércoles\");\n    break;\n  case 4:\n    console.log(\"Jueves\");\n    break;\n  case 5:\n    console.log(\"Viernes\");\n    break;\n  case 6:\n    console.log(\"Sábado\");\n    break;\n  case 7:\n    console.log(\"Domingo\");\n    break;\n  default:\n    console.log(\"El día no existe\");\n}\n\n// Iterativas\n// FOR\nfor (let i = 1; i <= 5; i++) {\n  console.log(i); // Muestra 1 2 3 4 5\n}\n\n// WHILE\nlet index = 1;\nwhile (index <= 5) {\n  console.log(index); // Muestra 1 2 3 4 5\n  index++;\n}\n\n// DO WHILE\nlet index2 = 1;\ndo {\n  console.log(index2);\n  index2++;\n} while (index2 <= 5); // Muestra 1 2 3 4 5\n\n// FOR OF\nconst array = [1, 2, 3, 4, 5];\nfor (let element of array) {\n  console.log(element); // Muestra 1 2 3 4 5\n}\n\n// FOR IN\n\nconst object = { a: 1, b: 2, c: 3, d: 4, e: 5 };\nfor (let key in object) {\n  console.log(key); // Muestra a b c d e\n}\n\n// Excepciones\ntry {\n  console.log(\"Hola\");\n} catch (error) {\n  console.log(error);\n} finally {\n  console.log(\"Adiós\");\n}\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\nfor (let i = 10; i <= 55; i++) {\n  if (i !== 16 && i % 3 !== 0 && i % 2 === 0) {\n    console.log(i);\n  }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/yedixdev.js",
    "content": "//Asigno variables para realizar las operaciones\nlet a = 8;\nlet b = 5;\nlet c = \"5\"; // c es un numero en cadena de texto tipo string\nlet d = 10;\n\n//Operadores arismeticos\nconsole.log(a + b); //Suma = 13\nconsole.log(a - b); //Resta = 3\nconsole.log(a * b); //Multiplicacion = 40\nconsole.log(a / b); //Division = 1.6\nconsole.log(a % b); //Modulo 3 (El residuo de la división de 8 entre 5)\n\n//Operaciones de comparacion\nconsole.log(a > b); // 8 mayor que 5 = true\nconsole.log(b >= c); // 5 mayor o igual que \"5\" = true (debido a la conversión de tipos)\nconsole.log(a < b); // 8 menor que 5 = false\nconsole.log(a <= c); // 8 menor o igual que \"5\" = false\nconsole.log(a == b); // 8 igual a 5 = false\nconsole.log(a == c); // 8 igual a \"5\" = true (debido a la conversión de tipos)\nconsole.log(a === c); // 8 estrictamente igual a \"5\" = false (no son del mismo tipo)\nconsole.log(a !== c); // 8 no es estrictamente igual a \"5\" = true (no son del mismo tipo)\n\n//Operaciones  indiferentes\nconsole.log(a != b); // 8 diferente a 5 = true (son numeros diferentes)\nconsole.log(a != c); // 8 diferente a \"5\" = false (debido a la conversión de tipos)\nconsole.log(a !== b); // 8 estrictamente diferente a 5 = true\nconsole.log(a !== d); // 8 estrictamente diferente a 10 = true\n\n//Operaciones   logicos\nconsole.log(a > b && b < d); // true (true AND true)\nconsole.log(a < b || b < d); // true (false OR true)\nconsole.log(!(a === c)); // true (NOT false)\nconsole.log(a < b && b >= c); // false (false AND true)\nconsole.log(a > b || c === d); // true (true OR false)\nconsole.log(a !== b && a > d); // false (true AND false)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/yesidL12.js",
    "content": "// <------- Operadores aritmeticos ---------->\n\n/**\n * suma (+),\n * resta (-).\n * multiplicación(*),\n * división (/),\n * módulo (%),\n * incrementos o decrementos (++ , ++) ==> Aunmenta o disminuye en una unidad.\n */\n\nlet a = 5;\nlet b = 10;\n\nconsole.log(a + b);\nconsole.log(a - b);\nconsole.log(a * b);\nconsole.log(a / b);\nconsole.log(a % b);\n\n// <-------- Operadores Lógicos ---------->\n\n/**\n * || (or) ===> Evalúa si por lo menos una de las condiciones se cumplen.\n * En caso de que eso suceda, devolverá TRUE\n * && (AND) ===> Evaluá si las dos condiciones se cumplen, en caso de ser así devolverá TRUE.\n * ! (Not) ===> EStablece una negación logica de una expresión, es decir, hará que una expreción que da como resultado TRUE, devuelva False\n */\n\n// EJEMPLO\n/** Determina si una persona es mayor de edad y tiene boleto de entrada. Si no es mayor de edad pero tiene acompañante, puede ingresar */\n\nfunction puedeIngresar(edad, entrada, acompañante) {\n    if (edad >= 18 && entrada === true) {\n         console.log('Puede ingresar')\n    } else if (edad < 18 && acompañante === true && entrada === true ) {\n        console.log('Puede ingresar con acompañante');\n    } else {\n        console.log('No puede ingresar');\n    }\n}\n\npuedeIngresar(20, true); // Puede ingresar\npuedeIngresar(12, true, true); // Puede ingresar con acompañante\npuedeIngresar(15, true,false); // No puede ingresar\n\n// <------ Operadores de Comparación ---------->\n /**\n  * == (igaul a)\n  * === (igualdad estricta) ===> ESto quiere decir que el tipo de dato y el valor deben ser iguales\n  * != (no es igual a)\n  * !== (no igualdad estricta)\n  * > (mayor que)\n  * < (Menor que)\n  * >= (mayor o igual)\n  * >= (menor o igual)\n  */\n\nlet y = 4;\nlet z = 5;\nlet w = 1;\nconsole.log(y == '4'); // Comprobación de igualdad de valores sin verificar el tipo de dato\nconsole.log(y != 3); // Comprobación de la diferencia de lavalores sin verificar el tipo de dato\nconsole.log(y === 4); // Comprobación de igualdad de valores y tipo de dato\nconsole.log(y !== 3); // Comprobación de la diferencia de valores o tipo de dato\nconsole.log(z > y); // Comprobación si el valor de z es estrictamente mayor al de y\nconsole.log(z >= y); // Comprobación si el valor de z es mayor o igual al de y\nconsole.log(w < y); // Comprobación si el valor de w es estrictamente menor al de y\nconsole.log(w <= y); // Comprobación si el valor de w es menor o igual al de y\n\n\n // <------------- Operadores de asignación --------------->\n\nlet x = 2; //operador de asignación\nx += 1; // operador de adición, simboliza x = x + 1\nx -= 1; // operador de resta, simboliza x = x - 1\nx *= 1; // operador de multiplicación, simboliza x = x * 1\nx /= 2; // operador de división, simboliza x = x / 2\nx %= 2; // operador de resto, simboliza x = x % 2 y a x se le adigna el resto de la división\nx **= 2; // operador de exponenciación, simboliza x = x ** 2 (x a la potencia de 2)\n\n// <------ Operadores atipicos ----------->\n/**\n * typeof ===> NOs indica el tipo de dato contenido en una variable,\n * void ===>  SE limita a impedir que todo funciones normalmente, es decir,\n *  que una vez evaluadas las instrucciones, sus efectos o presentación de \n * resultados serán anulados. En principio podemos dudar de su utilidad,\n *  pero puede resultar muy util en las ocasiones en que, dependiendo de\n *  una evaluación previa, haya que deshabilitar algun objeto o impedir una\n *  alguna acción.\n */\n\n\n// <------------ Estructuras de control ----------->\n\n/** En javascript podemos dividir estas estructuras de control en don grandes grupos:\n * Condicionales, y\n * ciclos.\n */\n\n// <-------- Condicionales ----------->\n\n// if - else\n/** Nos permite ejecutar un determinado bloque de código dependiendo de si una condición es verdadera o falsa. */\n\nif(condicion){\n    //Bloque de código\n        // Código que se ejecutará si la condición es cierta\n} else {\n    //Bloque de código\n        // Código que se ejecutará si la condición es falsa.\n}\n\n//ejemplo\nlet i = 10;\nif(1 > 5) {\n    console.log('EL valor de i es mayor a 5');\n} else {\n    console.log('El valor de i es menor a 5');\n}\n\n// <-------- Operador ternario --------->\n\n/** Utiliza 3 operandos y en algunas ocasiones puede utlizarse como una abreviación de la estructura if else */\n\ncondicion ? expresion1 : expresion2\n\n// Ejemplo\nlet i2 = (15 % 3 == 0) ? 'Si es múltiplo' : 'No es múltiplo'; // i = 'Si es múltiplo'\n\n\n// <--------- Switch --------->\n\n/**Surge de un concepto conocido como \"caza de patrones\" la idea es que\n *  dada una expresión esta se evalúe y se ejecute el código correspondiente\n *  a ese \"caso\". Si no encontramos un caso que coincida con la expresión,\n *  se ejecutará el bloque de código definido es default, aunque no es obligatorio \n * definir este caso */\n\nswitch (expresion) {\n    case x:\n        //Bloque de código\n        break;\n    case y:\n        //Bloque de código\n        break;\n    default:\n        //Bloque de código\n        break;    \n}\n\n// Ejemplo\n\nlet = 10;\n\nswitch(n) {\n    case 10:\n        console.log('Es 10')\n    case 20: \n        console.log('Es 20')\n        break;\n    default:\n        console.log('No se cumplió ningún caso');\n        break;\n}\n\n// <----------- Ciclos ----------->\n\n/**Un clico es una estructura de control que nos\n * permite ejecutar un mismo bloque de código varias\n *  veces hasta que cierta condición no sea cierta.\n */\n\n// While\n\n/** Verifica una condición y ejecuta el bloque de\n * código siempre que está sea cierta; en cuanto la\n * condición sea falsa, el ciclo dejará de ejecutarse.\n */\n\nwhile (condición) {\n    //Bloque de código\n}\n\n/** Un cliclo while se caracteriza por el manejo\n * manual de los iteradores. Un iterador es un valor\n * que utilizamos para controlar las repeticiones del\n * ciclo y evitar quedarnos estancados en un solo\n * valor; esto ocasionariá que el ciclo se ejecutará\n * infinitamente, pues al no cambiar el valor en la \n * condición no llegariamos nunca a un punto en \n * donde la condición seria falsa. Para lograr esto\n * debemos modificar el valor de dicho iterador en \n * cada ejecución del bloque de código.\n */\n\n// Ejemplo\n\nlet i3 = 0;\nwhile (i3 <= 20) {\n    if(i3 % 2 == 0) {\n        console.log(i3);\n        i3++;\n    }\n}\n\n// <------- Do while ---------->\n/** Do while funciona de manera similar a while\n * la diferencia es que en while primero se evalúa\n * la condición y luego se ejecuta el codigo. \n * En do while, primero se ejecuta el código y luego\n *  se evalúa la condición. Pueden haber casos en\n * que la condición no se evalúa nunca.\n */\n\ndo {\n    //Bloque de código\n} while (condicion)\n\n//Ejemplo\nlet i4 = 15;\nwhile (i4 < 10) {\n    console.log('Se ejecuta el while');\n}\n\ndo{\n    console.log('Se ejecutó el do-while');\n} while (i4 < 10);\n\n// el while no se ejecuta porque la condición es falsa\n// El do- while se ejecuta una vez, y es hasta que esa ejecución termina que se revisa la condición de pemanencia y el ciclo termina.\n\n// <--------- For ----------->\n/**La sintaxis del for se compone de tres elementos principales:\n * iterador ===> Para controlar el número de veces que se ejecuta un ciclo\n * condición ===> Si la condición se evalúa como true el ciclo se ejecuta por otra iteración, si la condición se evalúa como false, la ejecución termina.\n * incremento ===> Es la modificación del valor del iterador.\n */ \n\nfor (iterador; condición; incremento) {\n    //BLoque de código\n}\n\n// Ejemplo\n\nfor (let i5 = 0; i5 <= 20; i5++) {\n    if(i5 % 2 == 0){\n        console.log(i5);\n    }\n}\n\n// <--------- Try-Catch ------------>\n\n/** Nos permite definir un bloque de código para \n * intentar ejecutar (try), y una respuesta si es que\n * se prodice una excepción en dicha ejecución (catch).\n */\n\ntry {\n    //Bloque de código\n} catch (excepción) {\n    // Bloque de código\n}\n\n// Ejemplo\n\ntry{\n    ejemplo();\n} catch (e) {\n    console.log('Ha ocurrido el error:' + e);\n}\n\n\n// <----------- Dificultad extra ------------->\n\n/*** Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3. */\n\nfor (let num = 10; num < 56; num++){\n    if (num % 2 == 0 && num != 16 && num % 3 != 0) {\n        console.log(num);\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/javascript/zuluangel.js",
    "content": "//Assignment operators are used to assign a value to a variable.\nlet myVariable = 5; \n// Assigns the value 5 to the variable myVariable\n//If we don't assign a value to a variable, js will assign the \"undefined\" value by default\nlet myVariable2; \n// myVariable2 is undefined by default\n//The assignment operator can also be used to assign the result of an expression to a variable\n\nmyVariable = 6 //Assigns a diferent value \nconsole.log(myVariable);\nmyVariable += 3; // Adds 3 to the value of myVariable and assigns the result to myVariable\nconsole.log(myVariable);\nmyVariable -= 3; // Subtracts 3 from the value of myVariable and assigns the result to myVariable\nconsole.log(myVariable);\nmyVariable *= 3; // Multiplies the value of myVariable by 3 and assigns the result to myVariable\nconsole.log(myVariable);\nmyVariable /= 3; // Divides the value of myVariable by 3 and assigns the result to myVariable\n\n//Arithmetic operators are used to perform mathematical operations on variables and values.\n//The arithmetic operators are: \n//Addition: + \nconsole.log(5 + 7);\n//Subtraction: -\nconsole.log(5 - 7);\n//Multiplication: *\nconsole.log(5 * 7);\n//Division: /\nconsole.log(5 / 7);\n//Modulus (remainder): %\nconsole.log(5 % 7);\n//Exponentiation: **\nconsole.log(5 ** 7);\n//Increment and decrement operators are used to increase or decrease the value of a variable by 1.\n//Increment ++ the second sign can be replaced by a number, this number will be the increment\nconsole.log(++myVariable);\nconsole.log(++myVariable);\n\n//For example +5 will increment by 5 every step\nconsole.log(myVariable +5);\n\n//Decrement -- the second sign can be replaced by a number, this number will be the decrement\n//For example -5 will decrement by 5 every step\n\nconsole.log(myVariable -5);\n\n//Extra\n\nfor(i=10; i<=55; i++){\n    if(i === 16 || i % 3 === 0 || i % 2 != 0){\n        continue\n    }\n    console.log(i);\n}\n\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/julia/edalmava.jl",
    "content": "# Operadores Aritméticos\n\nx = 10\ny = 20\n\nprint(\"*****OPERADORES ARITMETICOS*****\\n\\n\")\n\nprint(\"Valor de x = $x\\n\")\nprint(\"Valor de y = $y\\n\\n\")\n\nprint(\"Suma de x + y = $(x + y)\\n\")\nprint(\"Resta de y - x = $(x - y)\\n\")\nprint(\"Multiplicación de x * y = $(x * y)\\n\")\nprint(\"División de x / y = $(x / y)\\n\")\nprint(\"División entera de x ÷ y = $(x ÷ y)\\n\")\nprint(\"División inversa de x \\\\ y = $(x \\ y) (Equivalente a y / x)\\n\")\nprint(\"Potenciación x ^ y = $(x ^ y)\\n\")\nprint(\"Módulo de 10 % 2 = $(10 % 2)\\n\")\n\nprint(\"\\n\\n*****OPERADORES BOOLEANOS*****\\n\\n\")\n\na = true\nb = false\n\nprint(\"Valor de a = $a\\n\")\nprint(\"Valor de b = $b\\n\\n\")\n\nprint(\"Negación de !a = $(!a)\\n\")\nprint(\"Negación de !b = $(!b)\\n\")\nprint(\"Operador AND(y) -> a && b = $(a && b)\\n\")\nprint(\"Operador OR(o) -> a || b = $(a || b)\\n\")\n\nprint(\"\\n\\n*****OPERADORES A NIVEL DE BIT (BITWISE)*****\\n\\n\")\n\nprint(\"Operador not ~123 = $(~123)\\n\")\nprint(\"Operador y 123 & 234 = $(123 & 234)\\n\")\nprint(\"Operador o 123 | 234 = $(123 | 234)\\n\")\nprint(\"Operador xor(o exclusivo) 123 ⊻ 234 = $(123 ⊻ 234)\\n\")\nprint(\"Operador nand(not and) 123 ⊼ 123 = $(123 ⊼ 123)\\n\")\nprint(\"Operador nor(not or) 123 ⊽ 124 = $(123 ⊽ 124)\\n\")\n\nprint(\"\\n\\n*****OPERADORES DE ACTUALIZACIÓN*****\\n\\n\")\n\nx = 1\nprint(\"Valor de x + 5 = $(x += 5)\\n\")  # x = x + 5\nprint(\"Valor de x - 5 = $(x -= 5)\\n\")  # x = x - 5\nprint(\"Valor de x * 5 = $(x *= 5)\\n\")  # x = x * 5\nprint(\"Valor de x / 5 = $(x /= 5)\\n\")  # x = x / 5\nprint(\"Valor de x \\\\ 5 = $(x \\= 5)\\n\") # x = x \\ 5\nprint\n#=\n  Otros operadores ÷=, %=, ^=, &=, |=, ⊻=, >>>=, >>=, <<=\n=#\n\nprint(\"\\n\\n*****OPERADORES PUNTO (DOT) VECTORIZED*****\\n\\n\")\n# TODO: Falta este operador\n\nprint(\"\\n\\n*****OPERADORES DE COMPARACIÓN*****\\n\\n\")\n\nprint(\"Operador de igualdad: 1 == 1 = $(1 == 1)\\n\")\nprint(\"Operador de inegualdad: 1 != 1 (≠) = $(1 != 1)\\n\")\nprint(\"Operador menor que: 1 < 2 = $(1 < 2)\\n\")\nprint(\"Operador menor o igual que: 1 <= 2 (≤) = $(1 <= 2)\\n\")\nprint(\"Operador mayor que: 10 > 2 = $(10 > 2)\\n\")\nprint(\"Operador mayor o igual que: 10 >= 2 (≥) = $(10 >= 2)\\n\")\n\nprint(\"\\n\\n*****ESTRUCTURAS DE CONTROL*****\\n\\n\")\n\nprintln(\"Evaluación Condicional\")\nx = 5\ny = 10\nprintln(\"x = $x y = $y\")\nif x < y\n    println(\"x es menor que y\")\nelseif x > y\n    println(\"x es mayor que y\")\nelse\n    println(\"x es igual a y\")\nend\n\nprintln(\"\")\nprintln(\"Ciclos\")\n\nprintln(\"\")\nprintln(\"Ciclo While\")\ni = 1\nwhile i <= 3\n    println(i)\n    global i += 1\nend \n\nprintln(\"\")\nprintln(\"Ciclo for\")\nfor i = 1:3\n    println(i)\nend\n\nprintln(\"Usando in\")\nfor i in [1,4,0]\n    println(i)\nend\n\nprintln(\"Usando ∈\")\nfor s ∈ [\"foo\",\"bar\",\"baz\"]\n    println(s)\nend\n\nprintln(\"\")\nprintln(\"Uso de Break\")\ni = 1\nprintln(\"Con while\")\nwhile true\n    println(i)\n    if i >= 3\n        break\n    end\n    global i += 1\nend\nprintln(\"Con for\")\nfor j = 1:1000\n    println(j)\n    if j >= 3\n        break\n    end\nend\n\nprint(\"\\n\\n*****LA SENTENCIA Try/catch*****\\n\\n\")\ntry\n    sqrt(\"ten\")\ncatch e\n    println(\"Debía haber ingresado un valor numérico\")\nend\n\nprint(\"\\n\\n*****RETO EXTRA*****\\n\\n\")\n\nfor i = 10:55\n    if i % 2 == 0 && i != 16 && i % 3 != 0\n        println(\"$(i)\")\n    end\nend\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/julia/roilhi.jl",
    "content": "#=\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n=#\n\n# Operadores aritméticos \nusing Printf\nx = 3;\ny = 2;\n\nprint(\" * * * * * * * * * * * * * * * \\n\");\nprint(\"Operadores aritméticos \\n\");\nprint(\" * * * * * * * * * * * * * * *\\n\");\n\n@printf \"variables x = %d, y = %d \\n\" x y;\n\n@printf \"Suma x+y = %d \\n\" x+y;\n\n@printf \"Resta x+y = %d \\n\" x-y;\n\n@printf \"Multiplicación x*y = %d \\n\" x*y;\n\n@printf \"División decimal x/y = %0.4f \\n\" x/y; #4 decimales\n\n@printf \"Cociente de la división x/y = %d \\n\" x÷y; # Por medio de \\div + tab se coloca el signo\n\n@printf \"Residuo de la división x/y = %d \\n\" x%y; # también es posible usando rem(x,y)\n\n@printf \"División inversa y/x = %f \\n\" x\\y;\n\n@printf \"Potencia x^y = %d \\n\" x^y;\n\nprint(\" * * * * * * * * * * * * * * *\\n\");\na = true;\nb = false;\nprint(\"Operadores booleanos \\n\");\nprint(\" * * * * * * * * * * * * * * *\\n\");\n\n@printf \"variables a = %s, b = %s \\n\" a b;\n\n@printf \"Operación AND(a,b): %s \\n\" a&&b;\n\n@printf \"Operación OR(a,b): %s \\n\" a||b;\n\n@printf \"Negación !a: %s \\n\" !a;\n\nprint(\" * * * * * * * * * * * * * * *\\n\");\nprint(\"Operadores de comparación \\n\");\nprint(\" * * * * * * * * * * * * * * *\\n\");\n\n@printf \" 3 == 0: %s \\n\" 3==0; # también puede teclearse el comando isequal(a,b)\n\n@printf \" 3 ≠ 0: %s \\n\" 3 ≠ 0; # para el signo no igual se teclea \\ne + tab, el mismo operador es ! =  \n\n@printf \" 3 > 0: %s \\n\" 3 > 0 ; \n\n@printf \" 3 < 0: %s \\n\" 3 < 0;\n\nprint(\" * * * * * * * * * * * * * * *\\n\");\nprint(\"Operadores de asignación \\n\");\nprint(\" * * * * * * * * * * * * * * *\\n\");\n\n@printf \"variables x = %d, y = %d \\n\" x y;\n\n@printf \"Suma + asignación x+=2: %d \\n\" x+=2;\n\n@printf \"Resta + asignación y-=2: %d \\n\" y-=2;\n\nx = 3; y = 2;\n\n@printf \"Multiplicación + asignación: x*=2 %d \\n\" x*=2;\n\n@printf \"División + asignación: y/=2 %0.2f \\n\" y/=2;\n\n\nprint(\" * * * * * * * * * * * * * * *\\n\");\nprint(\"Operadores a nivel bit (bitwise) \\n\");\nprint(\" * * * * * * * * * * * * * * *\\n\");\n\n@printf \"Not ~123 = %d \\n\" ~123;\n\n@printf \"And 1 & 2 = %d \\n\" 1&2;\n\n@printf \"Or 1 | 2 = %d \\n\" 1|2;\n\n@printf \"XOR 1 ⊻ 2 = %d \\n\" 1⊻2; #símbolo \\xor + TAB o xor(1,2)\n\n@printf \"NAND 1 ⊼ 2 = %d \\n\" 1⊼2; #símbolo \\nand + TAB o nand(1,2)\n\nprint(\" * * * * * * * * * * * * * * *\\n\");\nprint(\"Estructuras de control \\n\");\nprint(\" * * * * * * * * * * * * * * *\\n\");\n\nprint(\"Expresiones compuestas \\n\");\n# Una expresión compuesta evalúa dos o más expresiones en conjunto\n# En este caso evaluaremos x^2+y^2 en conjunto\nbegin #inicio de la expresión\n    x=3; y=4;\n    x^2+y^2;\n    z=√x; # \\sqrt para el operador raíz cuadrada \nend # fin de la expresión\n\n@printf \"Expresión compuesta caso 1: sqrt(x^2+y^2) = %d \\n\" z;\n\n# Otra forma de escribir la expresión\nz = (x=3; y=4; x^2+y^2; r=√x);\n\n@printf \"Expresión compuesta caso 2: sqrt(x^2+y^2) = %d \\n\" z;\n\nprint(\"Condicionales \\n\");\n\nx = -3;\nif x>0\n    println(\"El número x es positivo\");\nelse\n    println(\"El número x es negativo\");\nend\n\n# Otra forma de usar Condicionales\n#= con el comando ? se puede evaluar una expresión, se agrega el caso\n positivo y el caso negativo separados por un \":\" =#\nprintln(x>0 ? \"x es mayor a cero\" : \"x no es mayor a cero\"); #debe haber espacio entre \":\"\n\nx = 0;\n# Condicional múltiple\nfunction test(x)\n    if x<0\n        println(\"X es menor que cero\");\n    elseif x==0\n        println(\"x es igual a cero\");\n    else\n        println(\"x es menor que cero\");\n    end\nend\ntest(x);\n\nprintln(\"Ciclo while\");\n\nj=1;\nwhile j<=5\n    println(j);\n    global j +=1; #nueva sintaxis para asignar j en el contexto global\nend\n\nfor r=1:3\n    @printf \"r = %d\\n\" r;\nend\n\n# For each en Julia:\nl = [\"hola\",\"somos\",\"strings\",\"desde\",\"un\",\"array\"];\n\nfor str_text ∈ l #para el signo se teclea \\in + TAB \n    println(str_text);\nend\n\n# También existe el método zip como en Python\nfor (f,g) in zip([0,1,2],[3,4,5])\n    println((f,g))\nend\n\nprint(\" * * * * * * * * * * * * * * *\\n\");\nprint(\"Excepciones \\n\");\nprint(\" * * * * * * * * * * * * * * *\\n\");\n\n# Excepciones de dominio\nf(x) = x>0 ? 1/x : throw(DomainError(x,\"El argumento debe ser mayor a cero\"))\n#f(-1)\nf(4)\n#println(4)\n\n# Excepciones \"custom\"\ntry\n    sqrt(\"one\")\ncatch e\n    println(\"Error: El valor a ingresar debe ser numérico\");\nend\nprint(\" * * * * * * * * * * * * * * *\\n\");\nprint(\"DIFICULTAD EXTRA \\n\");\nprint(\" * * * * * * * * * * * * * * *\\n\");\n\nnums = range(10,step=1,stop=55);\n\nfor num ∈ nums\n    if num%3!=0 && num%2==0 && num != 16\n        println(num)\n    end\nend"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/julia/santiago-munoz-garcia.jl",
    "content": "### Operadores en Julia\n\n# Operadores aritméticos\na = 14\nb = 3\n\nsuma = a + b\nresta = a - b\nmultiplicacion = a * b\ndivision::Float32 = a / b\ndivision_entera::Int32 = a ÷ b\nmodulo::Int32 = a % b\npotencia = a ^ b\n\nprintln(\"Operadores aritméticos:\")\nprintln(\"a = $a, b = $b\")\nprintln(\"a + b = $suma\")\nprintln(\"a - b = $resta\")\nprintln(\"a * b = $multiplicacion\")\nprintln(\"a / b = $division\")\nprintln(\"a ÷ b = $division_entera\")\nprintln(\"a % b = $modulo\")\nprintln(\"a ^ b = $potencia\") \n\n# Operadores de comparación\nprintln(\"\\nOperadores de comparación:\")\nprintln(\"a es igual a b: $(a == b)\")\nprintln(\"a es distinto de b: $(a != b)\")\nprintln(\"a es mayor que b: $(a > b)\")\nprintln(\"a es menor que b: $(a < b)\")\nprintln(\"a es mayor o igual que b: $(a >= b)\")\nprintln(\"a es menor o igual que b: $(a <= b)\")\n\n# Operadores lógicos\nx = true\ny = false\nprintln(\"\\nOperadores lógicos:\")\nprintln(\"x = $x, y = $y\")\nprintln(\"x AND y: $(x && y)\")\nprintln(\"x OR y: $(x || y)\")\nprintln(\"NOT x: $(!x)\")\n\n# Operadores de asignación (=)\nprintln(\"\\nOperadores de asignación:\")\nc = 20\nprintln(\"c después de la asignación inicial: c = $c\")\nc += 5  # c = c + 5\nprintln(\"c después de la nueva asignación: c = $c\")\n\n# Operador de identidad (===)\nd = [1, 2, 3]\ne = d\nf = copy(d)\nprintln(\"\\nOperador de identidad:\")\nprintln(\"d es e: $(d === e)\")  # Verdadero, porque e es una referencia a d\nprintln(\"d es f: $(d === f)\")  # Falso, porque f es una copia de d\n\n# Operador de pertenencia\nprintln(\"\\nOperador de pertenencia:\")\nprintln(\"1 está en d: $(1 in d)\")\nprintln(\"4 está en d: $(4 in d)\")\n\n# Operadores de bits\ng = 0b00001010  # 10 en binario\nh = 0b00001100  # 12 en binario\nprintln(\"\\nOperadores de bits:\")\nprint(\"g = $(string(g, base=2)), \")\nprintln(\"h = $(string(h, base=2))\")\nprintln(\"g AND h: $(string(g & h, base=2))\")  \nprintln(\"g OR h: $(string(g | h, base=2))\")   \nprintln(\"g XOR h: $(string(g ⊻ h, base=2))\")  \nprintln(\"NOT g: $(string(~g, base=2))\")        \nprintln(\"NOT h: $(string(~h, base=2))\")  \n\n### Estructuras de control en Julia\n\n## Estructuras de control condicionales en Julia\nprintln(\"\\nEstructuras de control condicionales:\")\n\n# Condicional simple\nif a > b\n    println(\"a es mayor que b\")\nelse\n    println(\"a no es mayor que b\")\nend\n\n# Condicional compuesto con elseif\nif x < y\n    println(\"x es menor que y\")\nelseif x == y\n    println(\"x es igual a y\")\nelse\n    println(\"x es mayor que y\")\nend\n\n# Condicional con operadores lógicos\nif x < 20 && x > 10\n    println(\"x está entre 10 y 20\")\nelse\n    println(\"x no está entre 10 y 20\")\nend\n\n# Simulación de un switch usando if-elseif-else \nday = 3\nprintln(\"día = $day\")\nprint(\"Hoy es \")\nif day == 1\n    println(\"lunes\")\nelseif day == 2\n    println(\"martes\")\nelseif day == 3\n    println(\"miércoles\")\nelseif day == 4\n    println(\"jueves\")\nelseif day == 5\n    println(\"viernes\")\nelseif day == 6\n    println(\"sábado\")\nelseif day == 7\n    println(\"domingo\")\nelse\n    println(\"día NO VÁLIDO !!!\")\nend\n\n## Estructuras de control iterativas en Julia\nprintln(\"\\nEstructuras de control iterativas:\")\n\n# Bucle for con un rango específico\nprintln(\"\\nBucle for con un rango específico\")\nfor i in 10:15\n    println(\"Número: $i\")\nend\n\n# Bucle for sobre un array\nprintln(\"\\nBucle for sobre un array\")\nnombres = [\"Ana\", \"Luis\", \"Pedro\"]\nfor nombre in nombres\n    println(\"Hola, $nombre\")\nend\n\n# Bucle while\nprintln(\"\\nBucle while\")\ncontador = 1\nwhile contador <= 5\n    println(\"El contador es: $contador\")\n    global contador += 1  \nend\n\n# Manejo de excepciones\nprintln(\"\\nManejo de excepciones:\")\ntry\n    error(\"Esto es un error de prueba\")\ncatch exception\n    println(\"Se capturó una excepción: $exception\")\nend\n\n# DIFICULTAD EXTRA: Números entre 10 y 55, pares, no 16 ni múltiplos de 3\nprintln(\"\\nNúmeros entre 10 y 55, pares, no 16 ni múltiplos de 3:\")\nfor n in 10:55\n    if n % 2 == 0 && n != 16 && n % 3 != 0\n        println(n)\n    end\nend\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/kotlin/AnCarlu.kt",
    "content": "\n\nfun main() {\n    var a= 20\n    val b= 10\n\n    //Operadores en Kotlin\n    println(\"-a = ${-a}\")//Operadores de signos\n\n    //Operadores Aritmeticos\n    println(\"a + b = ${a+b}\")//Suma\n    println(\"a - b = ${a-b}\")//Resta\n    println(\"a * b = ${a*b}\")//Multiplicacion\n    println(\"a / b = ${a/b}\")//Division\n    println(\"a % b = ${a%b}\")//Resto\n\n    //Operadores de Asignacion compuesta\n    a += b\n    println(\"+= $a\")\n    a -= b\n    println(\"-= $a\")\n    a *= b\n    println(\"*= $a\")\n    a /= b\n    println(\"/= $a\")\n    a %=b\n    println(\"%= $a\")\n\n    //Operadores de incremento y decremento\n    a++\n    println(\"a++ = $a\")//Incremento\n    a--\n    println(\"a-- =$a\")//Decremento\n\n    //Operadores relacionales (devuelven un Boolean)\n    println(\"a = b = ${a==b}\")//igualdad\n    println(\"a != b = ${a != b}\")//diferente\n    println(\"a < b = ${a<b} \")//menor que\n    println(\"a > b = ${a>b}\")//mayor que\n    println(\"a <= b = ${a <= b}\")//menor o igual\n    println(\"a >= b = ${a >=b}\")//mayor o igual\n\n    //Operadores lógicos\n    var result : Boolean\n    val greater = b>0\n    val isEven = b%2 ==0\n    result= greater && isEven //Y\n    println(\"La variable b es par y mayor que 0 $result\")\n    result= greater || isEven //0\n    println(\"La variable b es par O mayor que 0 $result\")\n    result = !greater\n    println(\"La variable b es menor que 0 $result\")\n\n    //Operadores a nivel de bits\n    println(\"a and b = ${a and b}\")//and bit a bit\n    println (\" a or b = ${a or b}\")// or bit a bit\n    println(\" a xor b = ${a xor b}\")// xor bit a bit\n    println(\"a.inv()= ${a.inv()}\")// not bit a bit\n    println(\"a shl b = ${a shl b}\")// Desplazamiento de bits a la izquierda\n    println(\"a shr b = ${a shl b}\")//Desplazamiento de bits a la derecha\n    println(\"a ushr b = ${a ushr b}\")// Desplazamiento de bits a la derecha sin signo\n\n    //Estructuras de control\n    //Condicionales\n    val name = \"Adrian\"\n    if(name.contains(\"a\")){\n        println(\"Tu nombre contiene una A\")\n    }else{\n        println(\"Tu nombre no contiene ninguna A\")\n    }\n\n    val x= 3\n    when (x){\n        1 -> println(\"x = 1\")\n        2 -> println(\" x =2\")\n        else -> println(\"x no es ni 1 ni 2\")\n    }\n\n    //Bucles\n    for (i in 1..5){\n        println(i)//Imprime del 1 al 5\n    }\n\n    var z=0\n    while (z<6){\n        println(\"El valor de la variable z es $z\")\n        z++\n    }\n\n    do{\n        println(\"El nuevo valor de z es $z\")\n        z--\n    }while (z>0)\n\n    //De salto\n    for(i in 1..10){\n        if(i==5)break\n        println(i)\n    }\n\n    for(i in 1..10){\n        if(i%2==0)continue\n        println(i)\n    }\n\n    eReturn()\n\n    //Control de excepciones\n    try{\n        val resultado =10/0\n    }catch (e:ArithmeticException){\n        println(\"Error: Division por 0\")\n    }finally {\n        println(\"Este bloque siempre se ejecuta\")\n    }\n\n    //Control de ambito\n    val list= mutableListOf(1, 2, 3)\n    with(list){\n        add(4)\n        println(this)\n    }\n\n    list.run {\n        add(5)\n        println(this)\n    }\n\n    name?.let {\n        println(name.length)\n    }\n\n    list.apply {\n        add(4)\n        add(5)\n    }\n    println(list)\n\n    list.also {\n        it.add(8)\n    }\n    println(list)\n\n    exercise()\n}\n\nfun eReturn():Boolean{\n    val name= \"Adrian\"\n    val control: Boolean\n    if(name.contains(\"b\")){\n        control=true\n    }else{\n        control=false\n    }\n    return control\n}\n\nfun exercise(){\n    for (i in 10..55){\n        if(i %2==0 && i !=16 && i %3!=0){\n            println(i)\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/kotlin/Clotrack.kt",
    "content": "// 01 OPERADORES Y ESTRUCTURAS DE CONTROL\n        // EJERCICIO:\n            /* 01-01 Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n             *       Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n             *       (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n             */\n        // Inicializo unas variables random para trabajar con ellas, para todos los ejercicios\n        var myOperator1 = 5\n        var myOperator2 = 3\n        var myProveOperator = 0\n        var i = 0\n        var myBooleanTrue = true\n        var myBooleanFalse = false\n        var rangeAlfabet = 'a'..'d'\n        var myCahr = 'b'\n\n        // En kotlin tenemos 5 tipos de operadores aritmeticos [+] [-] [*] [/] [%] a continuacion unos ejemplos variados\n        myProveOperator = myOperator1 + myOperator2 ++\n        println(myProveOperator)\n        myProveOperator = myOperator1 --\n        println(myProveOperator)\n        println(myOperator1 * 9)\n        println((myProveOperator * myOperator1) / myOperator2)\n        if(myProveOperator % 2 == 0) {\n            println(\"El numero \" + myProveOperator + \" es par\")\n        }\n        // En kotlin tenemos cuatro operadores logicos [|] = OR [&] = AND [.xor()] = XOR y Desigualdad [!] y a continuacion unos ejemplos\n        println(\"${myBooleanTrue || myBooleanFalse} \\n${myBooleanTrue && myBooleanFalse} \\n${myBooleanFalse.xor(myBooleanTrue)} \\n${!myBooleanTrue}\")\n\n        // En Kotlin tenemos diferentes comparadores [>] mayor [<] menor y [=] que podemos jugar con ellos y mezclarlos con igualdad [>=]\n        if(myOperator1 > 20){\n            println(\"El numero $myOperator1 es mayor que 20\")\n        } else if(myOperator1 < 20){\n            println(\"El numero $myOperator1 es menor que 20\")\n        } else {\n            println(\"El numero $myOperator1 es igual a 20\")\n        }\n\n        // No podemos olvidarnos de los comparadores [==] de igualdad o el de [!=] diferencia\n        if(myOperator1 == myProveOperator){\n            println(\"Te va a tocar la loteria\")\n        } else if(myOperator1 != myProveOperator){\n            println(\"No hay suerte colega, asi es la vida\")\n        } else {\n            println(\"Esto no tendria que pasar colega!\")\n        }\n\n        //Ya por ultimo y para mi sorpresa se pueden utilizar comparaciones como [a..d] o [1..4]\n        if (myCahr in rangeAlfabet){ // este tipo de comparador [a..d] se debe usar dentro de una variable\n            println(\"El caracter $myCahr esta dentro del rango entre a y d\")\n        } else{\n            println(\"El caracter $myCahr esta fuera del rango entre a y d\")\n        }\n\n        if (myOperator2 !in 1..4){\n            println(\"El numero $myOperator2 esta dentro del rango entre 1 y 4\")\n        } else{\n            println(\"El numero $myOperator2 esta fuera de rango entre el 1 y el 4\")\n        }\n\n            /* 01-02 Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n             *       que representen todos los tipos de estructuras de control que existan\n             *       en tu lenguaje: Condicionales, iterativas, excepciones...\n             */\n        // Me cae tanta gracia que dejadme repetir este ejemplo condicional de 'if, else if y else' ;)\n        if(myOperator1 == myProveOperator){\n            println(\"Te va a tocar la loteria\")\n        } else if(myOperator1 != myProveOperator){\n            println(\"No hay suerte colega, asi es la vida\")\n        } else {\n            println(\"Esto no tendria que pasar colega!\")\n        }\n\n        // No es el unico condicional tambien tenemos 'when' es en apariencia identico a un swithc\n        when (myProveOperator){\n            myOperator1 -> println(\"Los espiritus estan de tu lado hoy\")\n            myOperator2 -> println(\"Ten cuidado al salir dedida, ponte crema solar o arderas como un misto\")\n            else -> {\n                println(\"Ten cuidado esta noche al salir con la luna llena\")\n            }\n        }\n\n        // Comencemos con los bucles en este caso con el 'while' quiero aclarar un concepto la condicion de cierre del\n        // bucle es hacer mientras la condicion se cumpla! en el ejemplo mientras myProbeOperator sea menor que 10\n        while (myProveOperator < 10){\n            println(\"El valor del operador de prueba es $myProveOperator \")\n            myProveOperator ++\n        }\n\n        //Sigamos con el bucle 'do-while que en este caso si o si almenos una vez debe ejecutarse el do manejar con cuidado!\n        do{\n            println(\"Numero de veces que declare mi amor y me rompieron el corazon en mil trocitos $myProveOperator\")\n            myProveOperator ++\n        } while (myProveOperator < myOperator2)\n\n        // Ya para finalizar el marabilloso y explendido bucle 'for' aclarar que la diferencia esque la condicion de\n        // cierre de este bucle es hacer asta que se cumpla la condicion!\n        for (myProveOperator in 5 downTo 1){\n            println(\"Doy vuelta y vueltas sin parar, que mareo! Ya ne se cuanto tiempo llevo aqui!\")\n        }\n\n        // Ahora que tenemos la variable myProbeOperator en 0 y viendo lo extraño que es declarar 'for' en kotlin\n        // quiero imprimir una tabla de multiplicar del 5 ;) sin operaciones dentro del 'for' directamente en su condicion\n        // debo aclarar que no he podido crear las tipicas variables dentro del bucle como [i, j o k] sino fuera del bucle :(\n        for (myProveOperator in 0..50 step 5){\n            println(\"$i x 5 = $myProveOperator\")\n            i ++\n        }\n            // 01-03 Debes hacer print por consola del resultado de todos los ejemplos.\n        // Todos los ejemplos/resultados anteriores ya han sido impresos por consola anteriormente!!\n\n            /* 01-04 DIFICULTAD EXTRA (opcional):\n             *       Crea un programa que imprima por consola todos los números comprendidos\n             *       entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n             */\n        i = 10\n        for (i in 10..55) {\n            if (i % 2 == 0 && i != 16 && i % 3 != 0){\n                println(i)\n            }\n        }"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/kotlin/CrisDev3.kt",
    "content": "fun main() {\n    /* Operadores unarios, representan si un numeros es\nnegativo o positivo\n */\n    var positiveNum = +3\n    var negativeNum = -3\n\n// Operadores aritmeticos\n    var sum = 42 + 33\n    println(sum)\n\n    var sustraction = 3 - 1\n    println(sustraction)\n\n    var multiplication = 2 * 2\n    println(multiplication)\n\n    var division = 6 / 3\n    println(division)\n\n    var mod = 6 % 3\n    println(mod)\n\n// Operador de asignación simple\n    var val1 = \"hello world\"\n    println(val1)\n\n// Operadores de asignacion aumentada\n    var a += b\n    println(\"+= $a\")\n\n    var a -= b\n    println(\"-= $a\")\n\n    var a *= b\n    println(\"*= $a\")\n\n    var a /= b\n    println(\"/= $a\")\n\n    var a %= b\n    println(\"%= $a\")\n\n// Operadores logicos\n    val entrada = 10\n    var resto: Boolean\n\n    val mayorQueCero = input > 0\n    val esPar = input % 2 == 0\n\n// Operador and\n    resto = mayorQueCero && esPar\n    println(\"Es mayor que cero y par:$resto\")\n\n// Operador or\n    resto = mayorQueCero || esPar\n    println(\"Es mayor que cero o par:$resto\")\n\n// Operador not\n    resto = mayorQueCero && !esPar\n    println(\"Es mayor que cero e impar:$resto\")\n\n// Operadores relacionales\n    val first = 12\n    val second = 42\n\n    println(\"$first es igual a $second: ${first == second}\")\n    println(\"$first es diferente a $second: ${first != second}\")\n    println(\"$first es menor que $second: ${first < second}\")\n    println(\"$first es mayor que $second: ${first > second}\")\n    println(\"$first es menor o igual que $second: ${first <= second}\")\n    println(\"$first es mayor o igual que $second: ${first >= second}\")\n\n// Operadores de incremento ++ y decremento --\n    var a = 2\n    println(a)\n    ++a\n    println(a)\n    a++\n    println(a)\n    --a\n    println(a)\n    a--\n    println(a)\n\n// Operador de rangos\n\n    val b = 1..3\n    val c = 1 until 8\n    println(b)\n    println(c)\n\n// Operador in\n\n    /* 3 in numeros. Esta expresión evalúa si el número 3 está\n    presente en el array numeros y almacena el resultado en la\n    variable estaPresente */\n    val numeros = arrayOf(1, 2, 3, 4, 5)\n    val estaPresente = 3 in numeros\n    println(\"¿El número 3 está presente en la lista? $estaPresente\")\n\n// Operadores de acceso a indices\n    val cadena = \"Hola\"\n    println(cadena[1]) // accede al caracter en la posicion 1 que es la 'o'\n\n    /* Operador de llamada segura !!, esto fuerza al programa a\n    acceder a una propiedad o llamar a un método en una variable\n    que puede ser nula\n     */\n    val cadena1: String? = null\n    val longitud = cadena1!!.length\n    println(longitud)\n\n    /* Operador de llamada segura ?, se utiliza para acceder\n     a las propiedades o métodos de un objeto de manera\n     segura, evitando que se produzca una excepción NullPointerException\n     si el objeto es nulo.\n     */\n    val d: String? = null\n    println(d)\n\n    /* Operador Elvis ?:, es una forma concisa de manejar valores nulos. Se\n     utiliza como una expresión que devuelve el valor de la izquierda si no\n     es nulo, y si es nulo, devuelve el valor de la derecha.\n     */\n    val cadena2: String? = null\n    val longitud: Int = cadena2?.length ?: -1\n    println(\"Longitud de la cadena: $longitud\") // Imprime: Longitud de la cadena: -1\n\n// Estructuras de control en kotlin\n\n// Estructuras iterativas\n\n// for loop\n    val nombress = listOf(\n        \"Dalmata\",\n        \"Husky\",\n        \"Chihuahua\",\n        \"Pitbull\"\n    )\n    for (nombre in nombres) {\n        val n = nombre.replaceFirstChar { it.lowercase() }\n        println(n)\n\n// while loop\n        var variable1 = 1\n        while (variable1 <= 5) {\n            println(\"Númber: $variable1\")\n            ++variable\n        }\n\n// do-While loop\n        var j = 1\n        do {\n            println(j)\n            j++\n        } while (j <= 5)\n\n// Estructuras condicionales\n\n// Sentencia if\n        val isAdult: Boolean? = null\n        if (isAdult == true) {\n            println(\"Es verdadero\")\n        } else {\n            println(\"Es falso o nulo\")\n        }\n\n// Sentencia when\n        val dia = 3\n        val nombreDia = when (dia) {\n            1 -> \"Lunes\"\n            2 -> \"Martes\"\n            3 -> \"Miércoles\"\n            4 -> \"Jueves\"\n            5 -> \"Viernes\"\n            6 -> \"Sábado\"\n            7 -> \"Domingo\"\n            else -> \"Día inválido\"\n        }\n        println(\"Hoy es $nombreDia\")\n\n// Excepciones\n        /* Try catch, Se utiliza para manejar excepciones en Kotlin.\n         El bloque try contiene el código que puede generar una\n         excepción, mientras que el bloque catch se utiliza para manejar\n         la excepción si ocurre.\n         */\n        val cadenaNumero = \"abc\"\n        try {\n            val numero = cadenaNumero.toInt()\n            println(\"Número: $numero\")\n        } catch (excepcion: NumberFormatException) {\n            println(\"Error: No se pudo convertir la cadena a número\")\n        }\n\n        /* Throw, Se utiliza para lanzar manualmente una excepción en un\n         punto específico del código.\n         */\n        val valor = -10\n        if (valor < 0) {\n            throw IllegalArgumentException(\"El valor no puede ser negativo\")\n        }\n        println(\"El valor es $valor\")\n\n\n// DIFICULTAD EXTRA (opcional):\n// * Crea un programa que imprima por consola todos los números comprendidos\n// * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n        for (i in 10..55) {\n            if (i % 2 == 0 && (i != 16) && (i % 3 != 0)) {\n                println(i)\n            }\n\n        }\n }\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/kotlin/Luis-VB.kt",
    "content": "\nfun main () {\n// Variables with data types & initialized:\n    val a: Int = 3\n    val b: Byte = 127\n    val c: Long = 100_000_000_000_000L\n    val d: Float = 1.25f\n    val e: Double = 3.23\n    val f: String = \"myString \"\n    val g: String = \"anotherString\"\n// Operaciones aritmeticas con las variables previas:\n    val sum: Int = b + a\n    val sum2: String = f + g\n    val rest = c - b\n    val mult = d * e\n    val div = b / a\n    val aRem2 = a % 2\n    val bRem2 = b % 2\n// Operadores Lógicos\n    val myTrue: Boolean = true\n    val myFalse: Boolean = false\n    val isAEven: Boolean = aRem2 == 0\n    val isAOdd: Boolean = bRem2 != 0\n// Valores de las constantes\n    println(a)\n    println(b)\n    println(c)\n    println(d)\n    println(e)\n    println(f)\n    println(g)\n    println()\n// Operaciones aritmeticas\n    println(sum)\n    println(sum2)\n    println(rest)\n    println(mult)\n    println(div)\n    println()\n// Operaciones lógicas\n    println(isAEven)\n    println(isAOdd)\n    println(myTrue || myFalse)\n    println(myTrue && myFalse)\n    println(!myTrue)\n    println()\n// Operaciones de comparación\n    println(b > a)\n    println(b < a)\n    println(myTrue == myTrue)\n    println(!myTrue)\n    println()\n\n// Operadores de asignación\n    var myNumber = 11\n    println(myNumber)\n    myNumber += 1\n    println(myNumber)\n    myNumber -= 2\n    println(myNumber)\n    myNumber *= 3\n    println(myNumber)\n    myNumber /= 2\n    println(myNumber)\n    myNumber %= 2\n    println(myNumber)\n\n//  Estructuras de control = Control flow\n// If expression\n    if (a > b) {\n        println(\"$a is bigger than $b\")\n    } else {\n        println(\"$a is not bigger than $b\")\n    }\n    println()\n\n// When else expression\n    val temp = 9\n    val description = when {\n        // If temp < 0 is true, sets description to \"very cold\"\n        temp < 0 -> \"very cold\"\n        // If temp < 10 is true, sets description to \"a bit cold\"\n        temp < 10 -> \"a bit cold\"\n        // If temp < 20 is true, sets description to \"warm\"\n        temp < 20 -> \"warm\"\n        // Sets description to \"hot\" if no previous condition is satisfied\n        else -> \"hot\"\n    }\n    println(description)\n    println()\n\n// For loops & ranges\n    for (number in 1..5) {\n        println(number)\n    }\n    println()\n    for (number in 1..<5) {\n        println(number)\n    }\n    println()\n    for (number in 10 downTo 5) {\n        println(number)\n    }\n    println()\n    for (number in 0..<28 step 2) {\n        println(number)\n    }\n    println()\n    val cakes = listOf(\"carrot\", \"cheese\", \"chocolate\")\n    for (cake in cakes) {\n        println(\"Yummy, it´s a $cake cake!\")\n    }\n\n/*\n/While loops\n Using a when expression, update the following program so that when you input\n     the names of GameBoy buttons, the actions are printed to output.\n*/\n    println()\n    val button = \"X\"\n    println(\n        when (button) {\n            \"A\" -> \"Yes\"\n            \"B\" -> \"No\"\n            \"X\" -> \"Menu\"\n            \"Y\" -> \"Nothing\"\n            else -> \"There is not such a button\"\n        }\n    )\n    // Do + While. Program that counts pizza slices until there’s a whole pizza with 8 slices.\n    println()\n    var pizzaSlices = 0\n    pizzaSlices++\n\n    do {\n        println(\"There's only $pizzaSlices slice/s of pizza :(\")\n        pizzaSlices++\n    } while (pizzaSlices <= 8)\n    println(\"Hooray! We have a whole pizza! :D\")\n\n    // For and if to print only the words that start with the letter l (from a list)\n    println()\n    val words = listOf(\"dinosaur\", \"limousine\", \"magazine\", \"language\")\n    for (word in words) {\n        if (word.startsWith(\"l\"))\n            println(word)\n    }\n\n// Break and continue loops\n    println()\n    mainLoop@ for (i in 1..5) {\n        val letras = listOf(\"a\", \"b\", \"c\")\n\n        secondaryLoop@ for (letra in letras) {\n\n            if (letra == \"c\") {\n                break@secondaryLoop\n            }\n            println(letra)\n        }\n    }\n\n// Error handling\n    println()\n    try {\n        println(1 / 0)\n    } catch (e: ArithmeticException) {\n        println(\"Error: División por cero\")\n    } finally {\n        println(\"Esto se imprime siempre\")\n    }\n\n//Ejercicio extra\n    println()\n    for (i in 10..55) {\n        if (i % 2 == 0 && i != 16 && i % 3 != 0) {\n            println(i)\n        }\n    }\n}\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/kotlin/OcandoDev.kt",
    "content": "fun main(){\n\n    //Definicion de variables\n    val a = 4\n    val b = 2\n\n    //Tipos de operadores en kotlin\n\n    println(\"Operadores aritmeticos\")\n\n    println(a + b) //Suma\n    println(a - b) //Resta\n    println(a * b) //Multiplicacion\n    println(a / b) //Division\n    println(a % b)  //Modulo\n\n    println(\"Operadores de comparacion\")\n\n    val c = 10\n    val d = 20\n\n    println(c == d) //Igual\n    println(c != d) //Desigual\n    println(c < d) //Menor\n    println(c <= d) //Menor igual\n    println(c > d) //Mayor\n    println(c >= d) //Mayor igual\n\n    println(\"Operadores logicos\")\n\n    val isRaining =  true\n    val isCold = false\n    val canGoOut = true\n\n    println(!isRaining && !isCold)\n    println(isRaining || isCold)\n    println(!canGoOut)\n\n    println(\"Operadores de asignacion\")\n\n    var e = 5 //Asignacion simple\n    println(e)\n\n    e += 1 //Suma y asignacion\n    println(e)\n\n    e -= 2 //Resta y asignacion\n    println(e)\n\n    e *= 3 //Multiplica y asignacion\n    println(e)\n\n    e /= 1 //Divide y asignacion\n    println(e)\n\n    e %= 4 //Modulo y asignacion\n    println(e)\n\n    println(\"Incremento y decremento\")\n\n    var counter = 0\n\n    println(counter)\n    counter++\n    println(counter)\n    ++counter\n    println(counter)\n    counter--\n    println(counter)\n    --counter\n    println(counter)\n\n    println(\"Operadores de rango\")\n\n    val numbers = 1..10 //Incluyendo 1 y 10\n    println(numbers)\n    val letters = 'a'..'z' //Letras de la 'a' a la 'z'\n    println(letters)\n    val even_numbers = 2 until 10 //Numeros pares del 2 al 9 (excluyendo el 10)\n    println(even_numbers)\n\n    println(\"Operadores de bits\")\n\n    val bin_1 = 10 //1010 en binario\n    val bin_2 = 5  //0101 en binario\n\n    println(a and b) // Resultado es 1 cuando ambos bits son 1\n    println(a or b) //Resultado es 1 si al menos un bit es 1\n    println(a xor b) //Resultado es 1 si los bits son diferentes\n    println(a shl 2) //Desplaza los bits a la izquierda, rellenando con ceros a la derecha\n    println(a shr 2) //Desplaza los bits a la derecha, rellenando con el bit de signo a la izquierda\n    println(a ushr 2) // Desplaza los bits a la derecha, rellenando con ceros a la izquierda\n\n    println(\"Estructuras de control\")\n\n    println(\"If:\")\n\n    val age = 18\n\n    if(age >= 18){\n        println(\"Eres mayor de edad\")\n    } else {\n        println(\"Eres menor de edad\")\n    }\n\n    println(\"When:\")\n\n    val day = \"Monday\"\n\n    when(day) {\n        \"Monday\" -> println(\"It's monday\")\n        \"Tuesday\" -> println(\"It's tuesday\")\n        \"Wednesday\" -> println(\"It's wednesday\")\n        \"Thursday\" -> println(\"It's thursday\")\n        \"Friday\" -> println(\"It's friday\")\n        else -> println(\"Weekend!\")\n    }\n\n    println(\"for\")\n\n    for(i in 1..3){\n        print(i)\n    }\n\n    println()\n\n    println(\"while:\")\n    var w_i = 0\n\n    while(w_i < 3){\n        print(w_i)\n        w_i++\n    }\n\n    println()\n\n    println(\"do-while\")\n\n    var j = 0\n    do {\n        print(j)\n        j++\n    }while(j < 3)\n\n    println()\n\n    println(\"break\")\n\n    for (i in 1..10) {\n        if (i == 5) {\n            break\n        }\n        print(i)\n    }\n\n    println()\n\n    println(\"continue\")\n\n    for (i in 1..10) {\n        if (i % 2 == 0) {\n            continue\n        }\n        print(i)\n    }\n\n    println()\n    \n    println(\"Ejercicio extra!:\")\n\n    for(i in 10..55){\n        if(i % 2 == 0 && i % 3 != 0) {\n            print(\"$i \")\n        }\n       if(i == 16){\n            continue\n        }\n    }\n\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/kotlin/SebasGRDev.kt",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n\n// OPERADORES DE SIGNO\nfun opSigno() {\n    val a = -5\n\n    println(\"a = ${-a}\")\n}\n\n//OPERADORES ARITMETICOS\nfun opAritmeticos(){\n    val a = 15\n    val b = 30\n\n    println(\"$a + $b = ${a + b}\")\n    println(\"$a - $b = ${a - b}\")\n    println(\"$a * $b = ${a * b}\")\n    println(\"$a / $b = ${a / b}\")\n    println(\"$a % $b = ${a % b}\")\n}\n\n//OPERADORES DE ASIGNACION COMPESTA\nfun opAsignCompuesta() {\n    var a = 500\n    val b = 5\n\n    a += b \n    println(\"+= $a\")\n\n    a -= b\n    println(\"-= $a\")\n\n    a *= b \n    println(\"*= $a\")\n\n    a /= b \n    println(\"/= $a\")\n\n    a %= b \n    println(\"%= $a\")\n}\n\n//OPERADORES DE INCREMENTO Y DECREMENTO\nfun opIncrDecr() {\n    var a = 1\n\n    println(\"De $a a ${++a}\")\n    println(\"De $a a ${--a}\")\n    println(\"Valor final > $a\")\n}\n\n//OPERADORES RELACIONALES\nfun opRelacionales() {\n    val a = 15\n    val b = 20\n\n    println(\"$a es igual a $b: ${a == b}\")\n    println(\"$a es diferente a $b: ${a != b}\")\n    println(\"$a es menor que $b: ${a < b}\")\n    println(\"$a es mayor a $b: ${a > b}\")\n    println(\"$a es menor o igual $b: ${a <= b}\")\n    println(\"$a es mayor o igual $b: ${a >= b}\")\n}\n\n//OPERADORES LOGICOS\nfun opLogicos() {\n    val a = 15\n    var res: Boolean\n\n    val mayorQueCero = a > 0\n    val isEven = a % 2 == 0\n\n    res = mayorQueCero & isEven\n    println(\"Es mayor que cero y par: $res\")\n\n    res = mayorQueCero || isEven\n    println(\"Es mayor que cero o par: $res\")\n\n    res = mayorQueCero && !isEven\n    println(\"Es mayor que cero e impar: $res\")\n}\n\n//OPERADORES A NIVEL DE BITS\nval a = 8\nval b = 3\n\nprintln(\"a and b: ${a and b}\")\nprintln(\"a or b: ${a or b}\")\nprintln(\"a xor b: ${a xor b}\")\nprintln(\"a inv b: ${a .inv() b}\")\nprintln(\"a shl b: ${a shl b}\")\nprintln(\"a shr b: ${a shr b}\")\nprintln(\"a ushr b: ${a ushr b}\")\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n */\n\n fun numeracion (){\n    for(i in 9..56) {\n        if (i % 2 == 0 && i % 3 != 0 && i != 16) {\n            println(\"numero = $i\")\n        }\n    }\n }"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/kotlin/Vikkanh.kt",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n    \n// ------------------------  Operaciones  ------------------------\n    \n// Operaciones Aritmeticas\n    \nval suma = 5 + 2\nprintln(suma)\n    \nval resta = 8 - 5\nprintln(resta)\n    \nval multiplicacion = 3 * 5\nprintln(multiplicacion)\n    \nval division = 10 / 2\nprintln(division)\n    \nval modulo = 10 % 3\nprintln(modulo)\n    \n    \n// Operaciones Logicas\n    \nprintln(\"${(12 + 5 == 10) && (5 + 12 == 17)}\")   // operacion AND se utiliza &&\nprintln(\"${(12 + 5 == 10) || (5 + 12 == 17)}\")   // operacion OR se utiliza ||\nprintln(\"${!(12 + 5 == 10)}\")   // operacion NOT se utiliza !\n    \n    \n// Operaciones de comparacion\n    \nval a = 7\nval b = 3\n\nprintln(\"igualdad: ${a == b}\")\nprintln(\"desigualdad: ${a != b}\")\nprintln(\"mayor que: ${a > b}\")\nprintln(\"menor que: ${a < b}\")\nprintln(\"mayor o igual que: ${a >= b}\")\nprintln(\"menor o iguial que: ${a <= b}\")\n    \n    \n// Operaciones de asignacion\n    \nvar c = 8   // asignacion numero a variable\nprintln(c)\n    \nc += 5   // suma y asignacion\nprintln(c)\n    \nc ++   // suma 1 a la variable\nprintln(c)\n    \nc -= 6   // resta y asignacion\nprintln(c)\n    \nc --   // resta 1 a la variable\nprintln(c)\n    \nc *= 3   // multiplica y asignacion\nprintln(c)\n    \nc /= 2   // division y asignacion\nprintln(c)\n    \n    \n// Operaciones de pertenencia\n    \nval ciudades = listOf(\"España\", \"Italia\", \"Alemania\", \"Francia\", \"Bulgaria\")\n    \nprintln(\"Alemania\" in ciudades)\nprintln(\"Noruega\" !in ciudades)\n    \n    \n// ------------------------ Estructura de control ------------------------\n    \n// Condicionales\n    \nval edad = 36\n    \nif (edad >= 18){\n    println(\"eres mayor de edad\")\n}else if (edad > 0){\n    println(\"eres menor de edad\")    \n}else {\n    println(\"no es una edad valida\")\n}\n    \n    \n// ------------------------  Iteraciones  ------------------------\n    \n// for\n    \nval nombre = listOf(\"Carlos\", \"David\", \"Sarah\", \"Lucia\", \"Cristian\")\n    \nfor (n in nombre){\n    println(\"me llamo $n\")\n}\n    \nfor (i in 1..10){\n    println(i)\n}\n    \n    \n// while\n      \nvar contador = 1\n    \nwhile (contador <= 5){\n    println(\"contado = $contador\")\n    contador ++\n}\n    \n    \n// do while\n    \ncontador = 1\n    \ndo {\n    println(\"contado = $contador\")\n    contador ++\n} while (contador <= 5)\n    \n    \n// when\n    \nvar diaDeLaSemana = 5\n    \nwhen (diaDeLaSemana){\n    1 -> println(\"Lunes\")\n    2 -> println(\"Martes\")\n    3 -> println(\"Miercoles\")\n    4 -> println(\"Jueves\")\n    5 -> println(\"Viernes\")\n    6 -> println(\"Sabado\")\n    7 -> println(\"Domingo\")               \n}\n    \n// ------------------------  Ejercicio Extra  ------------------------\n    \nfor (i in 10..55){\n    if (i % 2 == 0 && i != 16 && i % 3 != 0 ){\n        println(i)\n    }        \n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/kotlin/VincentRodriguezR.kt",
    "content": "fun main(){\n\n    // Punto #1 -> Operaciones con diferentes tipos de operadores\n\n    //Operadores Aritmeticos\n    val suma = 5 + 5 //Operador de suma\n    val resta = 8 - 5 //Operador de resta\n    val multi = 10 * 10 //Operador de multiplicacion\n    val divi = 100 / 30 //Operador de division\n    val perc = 100 % 3 //Operador modulo, devuelve el resto de la division\n\n\n    //Operadores de asignacion\n    val asigna = \"Asignacion\" //el = asigna un valor a la variable\n    var resultado = 0\n    resultado += suma //la combinacion de un operador con = devuelve la operacion directa, en este caso -> resultado = resultado + suma\n\n\n    //Operadores de comparacion\n    val igualdad = (5 == 5) //Igualdad ==\n    val diferente = (8 != 9) //Desigualdad o diferente !=\n    val mayorMenor = (9 > 10) //Comparadores >, <, >=, <=\n\n\n    //Operadores logicos\n    val and = (true && false) //Operador and &&\n    val or = (true || true) //Operador or ||\n    val not = !true //Operador Nor !\n\n\n    //Operadores de incremento y decremento\n    var incremento = 5\n    incremento++ //Operador de incremento ++ el valor final es 6 ya que se incrementa en 1\n    var decremento = 5\n    decremento-- //Operador de decremento -- el valor final es 4 ya que se decrementa en 1\n\n\n    //Punto #2 -> Ejercicios con estructuras de control existentes\n\n    //Condicionales\n\n    //if\n    var condicional = true\n    if (condicional == true)\n        println(\"Codigo a ejecutar si se cumple la condicion (Si son varias instrucciones ponerlas entre {})\")\n\n    //if else\n    if (condicional == true)\n        println(\"Codigo a ejecutar si se cumple la condicion (Si son varias instrucciones ponerlas entre {})\")\n    else\n        println(\"Codigo a ejecutar si no se cumple la condicion (Si son varias instrucciones ponerlas entre {})\")\n\n    //When\n    val conmutador = 4\n    when (conmutador){\n        1 -> println(\"esta instruccion no se ejecutara ya que el valor no es igual al dado en al condicion osea en la variable conmutador\")\n        2, 3 -> println(\"esta instruccion no se ejecutara ya que el valor no es igual al dado en al condicion osea en la variable conmutador, se pueden concatenar varios resultados en un solo caso\")\n        4 -> println(\"esta instruccion se ejecutara ya que el conmutador contiene el valor de este caso cumpliendo la condicion del when\")\n        else -> println(\"esta instruccion se ejecutaria en caso de que ninguno de los valores definidos cumpla con la condicion del when\")\n    }\n\n    //do while\n    do{\n        println(\"Instrucciones que se ejecutan mientras la condicion del while se cumpla, en este caso primero se ejecutan las acciones y luego se evalua la condicion\")\n        condicional = false\n    } while(condicional == true)\n\n    //while\n    while(condicional == false){\n        println(\"esta instruccion se ejecutara mientras la condicion del while se cumpla, en este caso se evalua primero la condicion y luego se ejecutan als acciones\")\n        condicional = true\n    }\n\n    //for + break\n    val arreglo: Array<Int> = arrayOf(1,2,3)\n    for(i in arreglo){\n        println(\"Se ejecutan estas acciones hasta que se reccorra todo el arreglo en este caso son 3 posiciones que contiene el array\")\n        break //con Break se rompe el bucle haciendolo parar\n    }\n\n    //Punto Extra -> Crea un programa que imprima por consola todos los números comprendidos entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3\n\n    for(i in 10 .. 55){\n        if(i != 16 && i%3 != 0 ){\n            println(i)\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/kotlin/VolumiDev.kt",
    "content": "fun main(args: Array<String>) {\n  var num1 = 10\n  var num2 = 6\n\n  // Operadores aritmeticos (+, -, *, /, %)\n  // suma\n  println(\"### Suma ###\")\n  println(\"$num1 + $num2 = ${ num1 + num2 }\")\n  \n  // resta\n  println(\"### Resta ###\")\n  println(\"$num1 - $num2 = ${ num1 - num2 }\")\n\n\n  // multiplicacion\n  println(\"### Multiplicación ###\")\n  println(\"$num1 * $num2 = ${ num1 * num2 }\")\n\n  //division\n  println(\"### División ###\")\n  println(\"$num1 / $num2 = ${ num1 / num2 }\")\n\n  // resto\n  println(\"### Resto ###\")\n  println(\"$num1 % $num2 = ${ num1 % num2 }\")\n\n  //operadores de asignacion \n  println(\"### Operadores de asignación ###\")\n  num1 = 100\n  num1 += 1 \n  println(\"El nuevo valor de num1 = $num1\")\n  num1 -= 1\n  println(\"El nuevo valor de num1 = $num1\")\n  num1 *= 2\n  println(\"El nuevo valor de num1 = $num1\")\n  num1 /= 2\n  println(\"El nuevo valor de num1 = $num1\")\n  num1 %= 24\n  println (\"El nuevo valor de num1 = $num1\")\n\n  //operadores unarios \n  println(\"### Operadores de unarios ###\")\n  println(\"Num1 mas 1 = ${ ++num1 }\")\n  println(\"Num1 menos 1 = ${ --num1 }\")\n  println(\"Num1 en negativo = ${ -num1 }\")\n  var bol = true\n\n  //operadiores de comparacion\n  println(\"### Operadores de comparación ###\")\n  println(\"$num1 > $num2 -> ${ num1 > num2 }\")\n  println(\"$num1 < $num2 -> ${ num1 < num2 }\")\n  println(\"$num1 igual $num2 -> ${ num1 == num2 }\")\n  println(\"$num1 distinto $num2 -> ${ num1 != num2 }\")\n  println(\"$num1 mayor o igual $num2 -> ${ num1 >= num2 }\")\n  println(\"$num1 menor o igual $num2 -> ${ num1 <= num2 }\")\n\n  \n  //operadores logicos (&&, ||, !)\n  println(\"### Operadores de lógicos ###\")\n  println(\"$bol && ${ !bol } => ${ bol && !bol }\")\n  println(\"$bol || ${ !bol } => ${ bol || !bol }\")\n  println(\"La negacion de $bol es ${ !bol }\")\n\n  // operadores de bits (and, or, xor, inv, shl, shr, ushr, ushl)\n  println(\"### Operadores de bits ###\")\n  num1 = 0b1100\n  num2 = 0b1010\n  println(\"El resultado de AND $num1 y $num2 es -> ${ num1 and num2 }\") \n  println(\"El resultado de OR $num1 y $num2 es -> ${ num1 or num2 }\")\n  println(\"El resultado de XOR $num1 y $num2 es -> ${ num1 xor num2 }\")\n  println(\"El resultado de complemento (inv) es -> ${ num1.inv() }\")\n  println(\"El resultado de desplazamiento a la izquerda es -> ${ num1 shl 1 }\")\n  println(\"El resultado de desplazamiento a la derecha es -> ${ num1 shr 1 }\")\n  println(\"El resultado de desplazamiento a la derecha sin signo es -> ${ num1 ushr 1 }\")\n\n  // Estructura de control\n  var var1 = 10\n  var var2 = 5\n\n  println(\"### IF / ELSE ###\")\n  if ( var1 > var2 ) println(\"Aqui se cumple\") else println(\"Aqui no se cumple\")\n\n  println(\"### WHEN ###\")\n  when (var2){\n    1 -> println(\"es un uno\")\n    2 -> println(\"es un dos\")\n    3 -> println(\"es un tres\")\n    4 -> println(\"es un cuatro\")\n    5 -> println(\"es un cinco\")\n    else -> println(\"opcion no valida\")\n  }\n\n  println(\"### FOR ###\")\n  var frutas = listOf(\"Platano\", \"Naranja\", \"Manzana\", \"Melon\")\n\n  for ( fruta in frutas){\n    print(\"$fruta - \")\n  }\n\n  var indice = 0 \n  println(\"### WHILE ###\")\n  while (indice < frutas.size){\n    println(\"fruta en el indice $indice es ${ frutas[indice] }\")\n    indice++\n  }\n\n  println(\"### DO WHILE ###\")\n\n  indice = 0\n  do{\n    println(\"El indice ira aumentando, ahora es $indice\")\n    indice++\n  }while (indice <= 5)\n\n  /*\n  DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n  */\n\n  for (x in 10..55){\n    if (x % 2 == 0){\n      if (x != 16 && x % 3 != 0) print(\"$x - \")\n    }\n  }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/kotlin/acirdeveloper.kt",
    "content": "fun main() {\n   /** \n    * Todo: Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n    * ? Utilizando las operaciones con operadores que tú quieras, crea ejemplos que representen todos los tipos de estructuras de control que existan en tu lenguaje: Condicionales, iterativas, excepciones...\n    *\n    * ? DIFICULTAD EXTRA (opcional):\n      - Crea un programa que imprima por consola todos los números comprendidos\n      - entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n    */\n  val name = \"Acir\"\n  val age = 25\n  val isDeveloper = false\n  var ageProgrammer = 1\n\n  //* Comparacion\n  println(\"Igual a: ${age == ageProgrammer}\")\n  println(\"Diferente a: ${age != ageProgrammer}\")\n  println(\"Mayor que: ${age > ageProgrammer}\")\n  println(\"Menor que: ${age < ageProgrammer}\")\n  println(\"Mayor o igual que: ${age >= ageProgrammer}\")\n  println(\"Menor o igual que: ${age <= ageProgrammer}\")\n  println(\"Comparacion de referencias: ${name === \"Acir\"}\")\n  \n  val number = 10\n  val number2 = 55\n\n  //* Logicos\n  if (number > 5 && number2 < 60) {\n    println(\"Ambas condiciones son verdaderas\")\n  }\n\n  if (number > 5 || number2 < 50) {\n    println(\"Al menos una condicion es verdadera\")\n  }\n\n  if (!isDeveloper) {\n    println(\"No es desarrollador\")\n  }\n\n  //* Arithmetic\n val i = 10\n println(\"Numeros comprendidos entre 10 y 55, pares y no son 16 ni multiplos de 3:\")\n  for (i in 10..55) {\n    if (i % 2 == 0 && i != 16 && i % 3 != 0) {\n      print(\"$i, \")\n    }\n  }\n\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/kotlin/adridoce.kt",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n fun main() {\n    // Operadores Aritmeticos\n    println(\"Operadores Aritmeticos:\")\n    val suma = 10 + 5\n    println(\"10 + 5 = $suma\")\n\n    val resta = 10 - 5\n    println(\"10 - 5 = $resta\")\n\n    val multiplicacion = 10 * 5\n    println(\"10 * 5 = $multiplicacion\")\n\n    val division = 10 / 5\n    println(\"10 / 5 = $division\")\n\n    val modulo = 10 % 5\n    println(\"10 % 5 = $modulo\")\n\n    // Operadores de asignacion\n    println(\"Operadores de asignacion:\")\n    var x = 10\n    println(\"x = 10 -> $x\")\n\n    x += 5\n    println(\"x += 5 -> $x\")\n\n    x -= 2\n    println(\"x -= 2 -> $x\")\n\n    x *= 2\n    println(\"x *= 2 -> $x\")\n\n    x /= 4\n    println(\"x /= 4 -> $x\")\n\n    x %= 2\n    println(\"x %= 2 -> $x\")\n\n    // Operadores de comparacion\n    val a = 5\n    val b = 10\n\n    println(\"$a == $b -> ${a == b}\")\n    println(\"$a != $b -> ${a != b}\")\n    println(\"$a < $b -> ${a < b}\")\n    println(\"$a > $b -> ${a > b}\")\n    println(\"$a <= $b -> ${a <= b}\")\n    println(\"$a >= $b -> ${a >= b}\")\n\n    // Operadores logicos\n    val c = true\n    val d = false\n\n    println(\"$c && $d -> ${c && d}\")\n    println(\"$c || $d -> ${c && d}\")\n    println(\"$c ! $d -> ${c && d}\")\n\n    //Operadores de incremento y decremento\n    var contador = 5\n    println(\"Contador: $contador\")\n    contador++\n    println(\"Contador++ = $contador\")\n    contador--\n    println(\"Contador-- = $contador\")\n\n    //Operadores de rango\n    val rangoInclusivo = 1..5\n    println(\"Rango inclusivo: $rangoInclusivo\")\n    val rangoExclusivo = 1 until 5\n    println(\"Rango exclusivo: $rangoExclusivo\")\n\n    //Estructuras de Control de Selección\n    val numero = 10\n    if (numero > 0) println(\"Es positivo\") else println(\"Es negativo o cero\")\n\n    val dia = 6\n    when (dia) {\n        1 -> println(\"Lunes\")\n        2 -> println(\"Martes\")\n        3 -> println(\"Miercoles\")\n        4 -> println(\"Jueves\")\n        5 -> println(\"Viernes\")\n        6 -> println(\"Sabado\")\n        7 -> println(\"Domingo\")\n        else -> println(\"Día no válido\")\n    }\n\n    // Estructuras de control de iteracion\n    for (i in 1..5) {\n        println(i)\n    }\n\n    var iterador = 0\n    while (iterador < 5) {\n        println(iterador)\n        iterador++\n    }\n\n    var y = 0\n    do {\n        println(y)\n        y++\n    } while (y < 5)\n\n    // Estructuras de control de saltos\n\n    for (i in 1..10) {\n        if (i == 5) break\n        println(i)\n    }\n\n    for (i in 1..10) {\n        if (i % 2 == 0) continue\n        println(i)\n    }\n\n    try {\n        val valor = 4/0\n    } catch (e: ArithmeticException){\n        println(\"Excepción aritmética: $e\")\n    }\n\n    // Reto extra: \n    // Crea un programa que imprima por consola todos los números comprendidos entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\n    retoExtra()\n}\n\nfun retoExtra() {\n    for (i in 10..55) {\n        if (i % 2 != 0 || i == 16 || i % 3 = 0) continue else println(i)\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/kotlin/blackriper.kt",
    "content": "@file:Suppress(\"DIVISION_BY_ZERO\")\r\n\r\nfun main() {\r\n    //operadores de comparacion\r\n    val a = 10\r\n    val b = 5\r\n    println(a > b)\r\n    println(a < b)\r\n    println(a >= b)\r\n    println(a <= b)\r\n    println(a == b)\r\n    println(a != b)\r\n\r\n    //operadores logicos\r\n    println(a > b && a < b)\r\n    println(a > b || a < b)\r\n    println(!true)\r\n\r\n    //operadores de asignacion\r\n    var c = 10\r\n    println(c)\r\n    c += 5\r\n    println(c)\r\n    c -= 5\r\n    println(c)\r\n    c *= 5\r\n    println(c)\r\n    c /= 5\r\n    println(c)\r\n    c %= 5\r\n    println(c)\r\n\r\n   //operadores de pertenecia\r\n    println(5 in 1..10)\r\n    println(5 !in 1..10)\r\n\r\n   // operadores de bits\r\n    println(5 and 10)\r\n    println(5 or 10)\r\n    println(5 xor 10)\r\n    println(5 shl 1)\r\n    println(5 shr 1)\r\n    println(5 ushr 1)\r\n    println(5 and 10)\r\n    println(5 or 10)\r\n    println(5 xor 10)\r\n\r\n    // condicional if\r\n    if (a > b) {\r\n        println(\"a es mayor que b\")\r\n    } else {\r\n        println(\"a no es mayor que b\")\r\n    }\r\n\r\n    //when\r\n    when (a) {\r\n        1 -> println(\"a es 1\")\r\n        2 -> println(\"a es 2\")\r\n        else -> println(\"a no es ni 1 ni 2\")\r\n    }\r\n\r\n    //loop for\r\n    for (i in 1..10) {\r\n        println(i)\r\n    }\r\n    for (i in 10 downTo 1) {\r\n        println(i)\r\n    }\r\n    for (i in 1..10 step 2) {\r\n        println(i)\r\n    }\r\n    for (i in 10 downTo 1 step 2) {\r\n        println(i)\r\n    }\r\n\r\n    // loop while\r\n    var i = 1\r\n    while (i <= 10) {\r\n        println(i)\r\n        i++\r\n    }\r\n\r\n    // loop do while\r\n    do {\r\n        println(i)\r\n        i++\r\n    } while (i <= 10)\r\n\r\n    //break y continue\r\n    for (d in 1..10) {\r\n        if (d == 5) {\r\n            break\r\n        }\r\n    }\r\n\r\n    for (f in 1..10) {\r\n        if (f == 5) {\r\n            continue\r\n        }\r\n    }\r\n\r\n    // exception\r\n    try {\r\n        val x = 10 / 0\r\n    } catch (e: ArithmeticException) {\r\n        println(\"No se puede dividir entre 0\")\r\n    }\r\n\r\n    // extra reto\r\n    extraReto()\r\n}\r\n\r\nfun extraReto(){\r\n    for (i in 10..55){\r\n        if(i%2==0 && i!=16 && i%3!=0 ){\r\n            println(i)\r\n        }\r\n\r\n    }\r\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/kotlin/didacdev.kt",
    "content": "fun main() {\n\n    // --------------------- Operadores -----------------------\n\n    // Asignación\n    val nombre = \"Diego\"\n    var edad = 27\n    println(\"$nombre tiene $edad años\")\n\n    // Artiméticos\n    val suma = 1 + 2\n    println(\"Suma: $suma\")\n\n    val resta = 3 - 2\n    println(\"Resta: $resta\")\n\n    val multiplicacion = 3 * 2\n    println(\"Multiplicación: $multiplicacion\")\n\n    val division = 10 / 2\n    println(\"División: $division\")\n\n    val concatenacion = \"hello \" + \"world\"\n    println(concatenacion)\n\n    val resto = 9 % 8\n    println(\"Resto: $resto\")\n\n    val tres = 3\n    val negativo = -tres\n    println(\"Negativo: $negativo\")\n\n    val cuatro = -4\n    val positivo = +cuatro\n    println(\"Positivo: $positivo\")\n\n    var compuesto = 2\n    compuesto += 2\n    println(\"Compuesto: $compuesto\")\n\n    // Comparación\n    println(1 == 1)\n    println(2 != 1)\n    println(2 > 1)\n    println(1 < 2)\n    println(1 >= 1)\n    println(2 <= 1)\n\n    // if-else\n    val resultado = if (2 + 1 == 3) true else false\n    println(resultado)\n\n    // Non-nullable\n    var color: String? = null\n    var colorCoche = if (color != null) \"Es $color\" else \"Es nulo\"\n    println(colorCoche)\n\n    println(color?.length)\n    val colorString = color?.toString()\n    println(colorString)\n\n    colorCoche = color?.toString() ?: \"Es nulo\"\n    println(colorCoche)    \n\n    // println(color!!.toString())\n\n    // Rango\n    for (index in 1..5) {\n        println(index)\n    }\n\n    for (index in 1 downTo 5) {\n        println(index)\n    }\n\n    for (index in 1..5 step 2) {\n        println(index)\n    }\n\n    for (index in 1 until 5) {\n        println(index)\n    }\n\n    // ----------------------- Estructuras de control --------------------\n    // Bucles for-in\n    val nombres = listOf(\"Anna\", \"Alex\", \"Brian\", \"Jack\")\n    for (nombre in nombres) {\n        println(\"Hola $nombre\")\n    }\n\n    // Bucle while\n    var numero = 0\n    while (numero < 4) {\n        println(numero)\n        numero +=1\n    }\n\n    // Bucle do-while\n    do {\n        println(numero)\n        numero += 1\n    } while (numero < 8)\n\n    // Condicional if\n    if (numero == 7) {\n        println(\"El número es 7\")\n    } else {\n        println(\"No es 7\")\n    }\n\n    // When\n    when (numero) {\n        7 -> println(\"Es 5\")\n        8 -> println(\"Es 8\")\n        else -> println(\"No es 7 ni 8\")\n    }\n\n    // Transferencia de control\n    for (index in 1..5) {\n        if (index == 3) {\n            continue\n        }\n\n        println(index)\n    }\n\n    for (index in 1..5) {\n        if (index == 3) {\n            break\n        }\n\n        println(index)\n    }\n\n    // Etiquetas\n    mainLoop@ for (i in 1..5) {\n        val letras = listOf(\"a\", \"b\", \"c\")\n\n        secondaryLoop@ for (letra in letras) {\n\n            if (letra == \"b\") {\n                break@secondaryLoop\n            }\n            println(letra)\n        }\n    }\n\n    // Error Handling\n    try {\n        println(1 / 0)\n    } catch (e: ArithmeticException) {\n        println(\"Error: División por cero\")\n    } finally {\n        println(\"Esto se imprime siempre\")\n    }\n\n    // -------------------------- Ejercicio extra -------------------------\n    for (index in 10..55) {\n\n        if (index % 2 == 0) {\n\n            if (index != 16 && index % 3 != 0) {\n                println(index)\n            }\n        }\n    }\n}   \n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/kotlin/elpeque29.kt",
    "content": "@file:Suppress(\"KotlinConstantConditions\")\n\npackage `100-Dias-de-Kotlin`.`Dia-002`.`01-OperadoresYEstructurasDeControl`\n\nfun main() {\n// Operators\n// https://kotlinlang.org/docs/keyword-reference.html#operators-and-special-symbols\n\n    mathOperators()\n    augmentedAssignmentsOperators()\n    incrementAndDecrementOperators()\n    logicalOperators()\n    equalityOperators()\n    referentialEqualityOperators()\n    comparisonOperators()\n    indexedAccessOperator()\n    nonNullable()\n    safeCalls()\n    elvisOperator()\n    rangeOperator()\n\n// Control Flow\n// https://kotlinlang.org/docs/control-flow.html\n\n    ifExpression()\n    whenExpression()\n    forLoops()\n    whileLoops()\n    doWhileLoops()\n}\n\n/* Operators */\n\nfun mathOperators() {\n    val adition = 0 + 1\n    val substraction = 1 - 1\n    val multiplication = 2 * 2\n    val division = 25 / 5\n    val rest = 5 % 5\n    println(listOf(adition,substraction,multiplication,division,rest))\n}\n\nfun augmentedAssignmentsOperators() {\n    var value = 3\n    value += 1\n    println(value)\n    value -= 1\n    println(value)\n    value *= 2\n    println(value)\n    value /= 2\n    println(value)\n    value %= 2\n    println(value)\n}\n\nfun incrementAndDecrementOperators() {\n    var otherValue = 5\n    otherValue++\n    println(otherValue)\n    otherValue--\n    println(otherValue)\n}\n\nfun logicalOperators() {\n    val logic = true\n    val notLogic = false\n    println(listOf(logic && notLogic, logic || notLogic, !logic))\n}\n\nfun equalityOperators() {\n    val a = \"String\"\n    val b = \"string\"\n    val c = a\n    println(a == c)\n    println(a != b)\n}\n\nfun referentialEqualityOperators() {\n    val a = 5\n    val b = 1\n    val c = a\n\n    println(a === b)\n    println(a !== c)\n}\n\nfun comparisonOperators() {\n    val d = 50\n    val e = 4\n    val f = 15\n    val g = e\n    println(d > f)\n    println(e < f)\n    println(e >= g)\n    println(e <= f)\n}\n\nfun indexedAccessOperator() {\n    val array = arrayOf(\"a\", \"b\")\n    println(array[0])\n}\n\nfun nonNullable() {\n    val nullableString: String?\n    nullableString = \"Hello\"\n    val length = nullableString!!.length // Here, you're certain that nullableString isn't null\n    println(length)\n}\n\nfun safeCalls() {\n    val b: String? = null\n    println(b?.length)\n}\n\nfun elvisOperator() {\n    // instead of using val l: Int = if (b != null) b.length else -1 you can use the Elvis Operator\n    val b = \"String\"\n    val l = b?.length ?: -1\n    println(l)\n}\n\nfun rangeOperator() {\n    println(4 in 1..4)\n}\n\n/* Control Flow */\n\nfun ifExpression() {\n    val bushiHasSlaves = false\n    if (bushiHasSlaves) println(\"Yup, don't say it loud. He can hear us.\") else println(\"Nah, he pays you with honor and recognition.\")\n}\n\nfun whenExpression() {\n    when (30) {\n        1 -> print(\"1\")\n        2 -> print(\"2\")\n        else -> {\n            println(\"x is neither 1 nor 2\")\n        }\n    }\n}\n\nfun forLoops() {\n    for (x in 1..3) {\n        println(x)\n    }\n}\n\nfun whileLoops() {\n    var x = 10\n    while (x > 0) {\n        x--\n        println(x)\n    }\n}\n\nfun doWhileLoops() {\n        var number = 6\n        var factorial = 1\n        do {\n            factorial *= number\n            number--\n        }while(number > 0)\n        println(\"Factorial of 6 is $factorial\")\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/kotlin/eulogioep.kt",
    "content": "fun main() {\n    // Operadores aritméticos\n    println(\"Operadores aritméticos:\")\n    println(\"5 + 3 = ${5 + 3}\")\n    println(\"10 - 4 = ${10 - 4}\")\n    println(\"6 * 2 = ${6 * 2}\")\n    println(\"15 / 3 = ${15 / 3}\")\n    println(\"17 % 5 = ${17 % 5}\")\n\n    // Operadores de asignación\n    var x = 10\n    println(\"\\nOperadores de asignación:\")\n    println(\"x = $x\")\n    x += 5\n    println(\"x += 5: $x\")\n    x -= 3\n    println(\"x -= 3: $x\")\n    x *= 2\n    println(\"x *= 2: $x\")\n    x /= 4\n    println(\"x /= 4: $x\")\n\n    // Operadores de comparación\n    println(\"\\nOperadores de comparación:\")\n    println(\"5 > 3: ${5 > 3}\")\n    println(\"5 < 3: ${5 < 3}\")\n    println(\"5 >= 5: ${5 >= 5}\")\n    println(\"5 <= 4: ${5 <= 4}\")\n    println(\"5 == 5: ${5 == 5}\")\n    println(\"5 != 4: ${5 != 4}\")\n\n    // Operadores lógicos\n    println(\"\\nOperadores lógicos:\")\n    println(\"true && false: ${true && false}\")\n    println(\"true || false: ${true || false}\")\n    println(\"!true: ${!true}\")\n\n    // Operadores de identidad\n    val a = Integer(5)\n    val b = Integer(5)\n    val c = a\n    println(\"\\nOperadores de identidad:\")\n    println(\"a === b: ${a === b}\")\n    println(\"a === c: ${a === c}\")\n    println(\"a !== b: ${a !== b}\")\n\n    // Operadores de bits\n    println(\"\\nOperadores de bits:\")\n    println(\"5 and 3: ${5 and 3}\")\n    println(\"5 or 3: ${5 or 3}\")\n    println(\"5 xor 3: ${5 xor 3}\")\n    println(\"5 shl 1: ${5 shl 1}\")\n    println(\"5 shr 1: ${5 shr 1}\")\n\n    // Estructuras de control\n    \n    // Condicional if-else\n    println(\"\\nCondicional if-else:\")\n    val numero = 7\n    if (numero % 2 == 0) {\n        println(\"$numero es par\")\n    } else {\n        println(\"$numero es impar\")\n    }\n\n    // Condicional when (switch)\n    println(\"\\nCondicional when:\")\n    when (numero) {\n        in 1..5 -> println(\"$numero está entre 1 y 5\")\n        in 6..10 -> println(\"$numero está entre 6 y 10\")\n        else -> println(\"$numero está fuera del rango 1-10\")\n    }\n\n    // Bucle for\n    println(\"\\nBucle for:\")\n    for (i in 1..5) {\n        println(\"Iteración $i\")\n    }\n\n    // Bucle while\n    println(\"\\nBucle while:\")\n    var i = 0\n    while (i < 5) {\n        println(\"Mientras i < 5, i = $i\")\n        i++\n    }\n\n    // Bucle do-while\n    println(\"\\nBucle do-while:\")\n    var j = 0\n    do {\n        println(\"Do-while j < 5, j = $j\")\n        j++\n    } while (j < 5)\n\n    // Manejo de excepciones\n    println(\"\\nManejo de excepciones:\")\n    try {\n        val resultado = 10 / 0\n        println(resultado)\n    } catch (e: ArithmeticException) {\n        println(\"Error: División por cero\")\n    } finally {\n        println(\"Este bloque siempre se ejecuta\")\n    }\n\n    // DIFICULTAD EXTRA\n    println(\"\\nDIFICULTAD EXTRA:\")\n    for (num in 10..55) {\n        if (num % 2 == 0 && num != 16 && num % 3 != 0) {\n            println(num)\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/kotlin/frealexandro.kt",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n\n\n// #01 OPERADORES Y ESTRUCTURAS DE CONTROL\nfun main() {\n    //definición de variables\n    val a = 10\n    val b = 5\n\n\n\n    //Tipos de operadores en kotlin\n\n    println(\"Operadores aritméticos\")\n    println(\"Suma: ${a + b}\")\n    println(\"Resta: ${a - b}\")\n    println(\"Multiplicación: ${a * b}\")\n    println(\"División: ${a / b}\")\n    println(\"Módulo: ${a % b}\")\n\n    println(\"Operadores de comparación\")\n    println(\"Igual: ${a == b}\")\n    println(\"Desigual: ${a != b}\")\n    println(\"Menor: ${a < b}\")\n    println(\"Menor igual: ${a <= b}\")\n    println(\"Mayor: ${a > b}\")\n    println(\"Mayor igual: ${a >= b}\")\n\n    println(\"Operadores lógicos\")\n    val isTrue = true\n    val isFalse = false\n\n    println(\"$isTrue && $isFalse es ${isTrue && isFalse}\")\n    println(\"$isTrue || $isFalse es ${isTrue || isFalse}\")\n    println(\"!$isTrue es ${!isTrue}\")\n\n    println(\"Operadores de asignación\")\n    var c = 5 //Asignación simple\n    println(\"c = $c\")\n    c += 2 //Suma y asignación\n    println(\"c += 2 es $c\")\n    c -= 2 //Resta y asignación\n    println(\"c -= 2 es $c\")\n    c *= 2 //Multiplica y asignación\n    println(\"c *= 2 es $c\")\n    c /= 2 //Divide y asignación\n    println(\"c /= 2 es $c\")\n    c %= 2 //Módulo y asignación\n    println(\"c %= 2 es $c\")\n    \n    println(\"Operadores de rango\")\n\n    val numbers = 1..10 //Incluyendo 1 y 10\n    println(numbers)\n    val letters = 'a'..'z' //Letras de la 'a' a la 'z'\n    println(letters)\n    val even_numbers = 2 until 10 //Numeros pares del 2 al 9 (excluyendo el 10)\n    println(even_numbers)\n\n    println(\"Operadores de bits\")\n\n    val bin_1 = 10 //1010 en binario\n    val bin_2 = 5  //0101 en binario\n\n    println(\"Operador de bits AND: ${bin_1 and bin_2}\")\n    println(\"Operador de bits OR: ${bin_1 or bin_2}\")\n    println(\"Operador de bits XOR: ${bin_1 xor bin_2}\")\n    println(\"Operador de bits desplazamiento a la izquierda: ${bin_1 shl 1}\")\n    println(\"Operador de bits desplazamiento a la derecha: ${bin_1 shr 1}\")\n    println(\"Operador de bits desplazamiento a la derecha sin signo: ${bin_1 ushr 1}\")\n\n    //Estructuras de control\n\n    println(\"Estructuras de control\")\n\n    //Condicionales\n    println(\"If:\")\n\n    val x = 10\n    val y = 5\n\n    if (x > y) {\n        println(\"$x es mayor que $y\")\n    } else {\n        println(\"$x es menor que $y\")\n    }\n\n    //When\n    println(\"When:\")\n\n    val day = \"Monday\"\n\n    when(day) {\n        \"Monday\" -> println(\"It's monday\")\n        \"Tuesday\" -> println(\"It's tuesday\")\n        \"Wednesday\" -> println(\"It's wednesday\")\n        \"Thursday\" -> println(\"It's thursday\")\n        \"Friday\" -> println(\"It's friday\")\n        else -> println(\"Weekend!\")\n    }\n\n    //Iterativas\n\n    println(\"Iterativas\")\n\n    //For\n\n    println(\"For\")\n    for (i in 1..10) {\n        println(i)\n    }\n\n    //While\n\n    println(\"While\")\n\n    var w_i = 0\n\n    while (w_i < 10) {\n        println(w_i)\n        w_i++\n    }\n\n    //Do-While\n\n    println(\"Do-While\")\n\n    var j = 0\n\n    do {\n        println(j)\n        j++\n    } while (j < 10)\n\n    //Excepciones\n\n    // println(\"Excepciones\")\n\n    // try {\n    //     val z = 10 / 0\n    // } catch (e: Exception) {\n    //     println(\"Error: ${e.message}\")\n    // }\n\n    //Break\n\n    println(\"Break\")\n\n    for (i in 1..10) {\n        if (i == 5) {\n            break\n        }\n        print(i)\n    }\n\n    //Continue\n\n    println(\"Continue\")\n\n    for (i in 1..10) {\n        if (i % 2 == 0) {\n            continue\n        }\n        print(i)\n    }\n\n    //Ejercicio extra\n\n    println(\"Ejercicio extra\")\n\n    for (i in 10..55) {\n        if (i % 2 == 0 && i % 3 != 0) {\n            print(\"$i \")\n        }\n        if (i == 16) {\n            continue\n        }\n    }\n\n\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/kotlin/gamitocu.kt",
    "content": "// #01 OPERADORES Y ESTRUCTURAS DE CONTROL\nfun main(){\n\n    //Definicion de variables\n    val a = 8\n    val b = 2\n\n    //Tipos de operadores en kotlin\n\n    println(\"Operadores aritmeticos\")\n    println(\"$a + $b = \" a + b) //Suma\n    println(\"$a - $b = \" a - b) //Resta\n    println(\"$a * $b = \" a * b) //Multiplicacion\n    println(\"$a / $b = \" a / b) //Division\n    println(\"$a % $b = \" a % b) //Modulo\n\n    println(\"Operadores de comparacion\")\n    println(\"$a == $b => \" a == b) //Igual\n    println(\"$a != $b => \" a != b) //Desigual\n    println(\"$a < $b => \" a < b)   //Menor\n    println(\"$a <= $b => \" a <= b) //Menor igual\n    println(\"$a > $b => \" a > b)   //Mayor\n    println(\"$a >= $b => \" a >= b) //Mayor igual\n\n    println(\"Operadores logicos\")\n    val isTrue =  true\n    val isFalse = false\n\n    println(\"$isTrue && $isFalse es ${isTrue && isFalse}\")\n    println(\"$isTrue || $isFalse es ${isTrue || isFalse}\")\n    println(\"!$isTrue es ${!isTrue}\")\n\n    println(\"Operadores de asignacion\")\n    var c = 5 //Asignacion simple\n    println(\"c = $c\")\n    c += 2 //Suma y asignacion\n    println(\"c += 2 es $c\")\n    c -= 2 //Resta y asignacion\n    println(\"c -= 2 es $c\")\n    c *= 2 //Multiplica y asignacion\n    println(\"c *= 2 es $c\")\n    c /= 2 //Divide y asignacion\n    println(\"c /= 2 es $c\")\n    c %= 2 //Modulo y asignacion\n    println(\"c %= 2 es $c\")\n\n\n    println(\"Operadores de rango\")\n\n    val numbers = 1..10 //Incluyendo 1 y 10\n    println(numbers)\n    val letters = 'a'..'z' //Letras de la 'a' a la 'z'\n    println(letters)\n    val even_numbers = 2 until 10 //Numeros pares del 2 al 9 (excluyendo el 10)\n    println(even_numbers)\n\n    println(\"Operadores de bits\")\n\n    val bin_1 = 10 //1010 en binario\n    val bin_2 = 5  //0101 en binario\n\n    println(a and b) // Resultado es 1 cuando ambos bits son 1\n    println(a or b) //Resultado es 1 si al menos un bit es 1\n    println(a xor b) //Resultado es 1 si los bits son diferentes\n    println(a shl 2) //Desplaza los bits a la izquierda, rellenando con ceros a la derecha\n    println(a shr 2) //Desplaza los bits a la derecha, rellenando con el bit de signo a la izquierda\n    println(a ushr 2) // Desplaza los bits a la derecha, rellenando con ceros a la izquierda\n\n    println(\"Estructuras de control\")\n\n    println(\"If:\")\n\n    val age = 18\n\n    if(age >= 18){\n        println(\"Eres mayor de edad\")\n    } else {\n        println(\"Eres menor de edad\")\n    }\n\n    println(\"When:\")\n\n    val day = \"Monday\"\n\n    when(day) {\n        \"Monday\" -> println(\"It's monday\")\n        \"Tuesday\" -> println(\"It's tuesday\")\n        \"Wednesday\" -> println(\"It's wednesday\")\n        \"Thursday\" -> println(\"It's thursday\")\n        \"Friday\" -> println(\"It's friday\")\n        else -> println(\"Weekend!\")\n    }\n\n    println(\"for\")\n\n    for(i in 1..3){\n        print(i)\n    }\n\n    println()\n\n    println(\"while:\")\n    var w_i = 0\n\n    while(w_i < 3){\n        print(w_i)\n        w_i++\n    }\n\n    println()\n\n    println(\"do-while\")\n\n    var j = 0\n    do {\n        print(j)\n        j++\n    }while(j < 3)\n\n    println()\n\n    println(\"break\")\n\n    for (i in 1..10) {\n        if (i == 5) {\n            break\n        }\n        print(i)\n    }\n\n    println()\n\n    println(\"continue\")\n\n    for (i in 1..10) {\n        if (i % 2 == 0) {\n            continue\n        }\n        print(i)\n    }\n\n    println()\n\n    println(\"Ejercicio extra!:\")\n\n    for(i in 10..55){\n        if(i % 2 == 0 && i % 3 != 0) {\n            print(\"$i \")\n        }\n        if(i == 16){\n            continue\n        }\n    }\n\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/kotlin/isaacus98.kt",
    "content": "var a = 1\nvar b = 2\n\nfun main(){\n    // Operadores aritméticos\n    println(\"Operadores de aritmeticos\")\n    println(1+1)\n    println(1-1)\n    println(2*5)\n    println(6/2)\n    println(1%1)\n\n    // Operadores lógicos\n    println(\"Operadores lógicos\")\n    println(a < b && b > a)\n    println(a < b || b > a)\n    println(!true)\n\n    // operadores de comparación\n    println(\"Operadores de comparación\")\n    println(a == b)\n    println(a != b)\n    println(a < b)\n    println(a > b)\n    println(a <= b)\n    println(a >= b)\n\n    // operadores de asignación\n    println(\"Operadores de asignación\")\n    var c = 1\n    println(c)\n    c += 1\n    println(c)\n    c -= 1\n    println(c)\n    c *=8\n    println(c)\n    c /= 2\n    println(c)\n    c %= 5\n    println(c)\n\n    // Operadores de pertenencia\n    println(\"Operadores de pertenencia\")\n    println(2 in 1..10)\n    println(2 !in 1..10)\n\n    // Operadores de bits\n    println(\"Operadores de bits\")\n    println(a and b)\n    println(a or  b)\n    println(a xor b)\n    println(a.inv())\n    println(a shl b)\n    println(a shr b)\n    println(a ushr b)\n\n    //Estructuras de control\n    println(\"Estructuras de control\")\n\n    // IF\n    println(\"IF\")\n    if (a < b)\n        println(\"$a es mas pequeño que $b\")\n    else\n        println(\"$b es mas grande que $a\")\n\n    // WHEN\n    println(\"WHEN\")\n    when (a){\n        1 -> println(\"a es 1\")\n        2 -> println(\"a es 2\")\n        else -> println(\"a no es 1 ni tampoco 2\")\n    }\n\n    // FOR\n    println(\"FOR\")\n    for (i in 1..10){\n        println(i)\n    }\n\n    // WHILE\n    println(\"WHILE\")\n    var d = 1\n    while (d <= 5){\n        println(d)\n        d++\n    }\n\n    // DO WHILE\n    println(\"DO WHILE\")\n    d = 1\n    do {\n        println(d)\n        d++\n    } while (d <= 5)\n\n    // FOREACH\n    println(\"FOREACH\")\n    val nombres = arrayOf(\"Isaac\", \"Sergi\", \"Gerrard\", \"Eric\", \"Pol\")\n    for (nombre in nombres)\n        println(nombre)\n\n    // TRY CATCH\n    println(\"TRY CATCH\")\n    try {\n        val valor = 20/0\n    } catch (e: ArithmeticException){\n        println(\"Excepción aritmética\")\n    }\n\n    // Reto extra\n    println(\"Reto extra\")\n    retoExtra()\n}\n\nfun retoExtra() {\n    for (numero in 10..55){\n        if (numero%2 == 0 && numero != 16 && numero%3 != 0)\n            println(numero)\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/kotlin/jaennova.kt",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n\n fun operadoresAritmeticos(){\n    val a1: Int = 4\n    val a2: Int = 42\n    println(\"Operadores Aritmeticos\")\n    println(\"a1 = $a1, a2 = $a2\\n\")\n    println(\"$a1 - $a2 = ${a1 - a2}\")\n    println(\"$a1 * $a2 = ${a1 * a2}\")\n    println(\"$a1 / $a2 = ${a1 / a2}\")\n    println(\"$a1 % $a2 = ${a1 % a2}\")\n}\n\n\nfun operadoresLogicos(){\n    val o1: Int = 23\n    val o2: Int = 41\n    println(\"\\nOperadores Logicos\")\n    println(\"o1 = $o1, o2 = $o2\\n\")\n    println(\"$o1 == $o2 = ${o1 == o2}\")\n    println(\"$o1 != $o2 = ${o1 != o2}\")\n}\n\nfun operadoresRelacionCompuesta(){\n    val a = 5\n    val b = 3\n    val c = 1\n    println(\"/nOperadores de relacion compuesta\")\n    println(\"a = $a, b = $b, c = $c\")\n    println(\"a > b && b > c = ${a > b && b > c}\")  // imprime true, ya que a > b y b > c son ambas verdaderas\n    println(\"a < b || b > c = ${a < b || b > c}\")  // imprime true, ya que al menos una de las expresiones es verdadera (b > c)\n}\n\nfun operadoresRelacionales(){\n    val a = 5\n    val b = 3\n    val c = 5\n    println(a == b)  // imprime false\n    println(a != b)  // imprime true\n    println(a > b)   // imprime true\n    println(a < b)   // imprime false\n    println(a >= b)  // imprime true\n    println(a <= b)  // imprime false\n    println(a == c)  // imprime true\n}\n\nfun condicionales(){\n    val a = 5\n    val b = 3\n    val c = 5\n    if(a != b) println(\"a es diferente de b\") else println(\"a no es diferente de b\")\n    if(b && c > a){\n        println(\"$a y $c son mayores que $a\")\n    } else{\n        println(\"$a y $c no son mayores que $a\")\n    }\n}\n//  * DIFICULTAD EXTRA (opcional):\n//  * Crea un programa que imprima por consola todos los números comprendidos\n//  * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\nfun ejercicio(){\n    for(i in 10..5){\n        if(i % 2 == 0 && i != 16 && i % 3 != 0){\n            println(i)\n            }\n        }\n}\nfun main(){\n    operadoresAritmeticos()\n    operadoresLogicos()\n    operadoresRelacionCompuesta()\n    condicionales()\n    ejercicio()\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/kotlin/juandaherrera.kt",
    "content": "/*\n     * DIFICULTAD EXTRA (opcional):\n     * Crea un programa que imprima por consola todos los números comprendidos\n     * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n     *\n     * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n*/\n\nfun main() {\n    for (number in 10..55) {\n        if (number % 2 == 0 && number != 16 && number % 3 != 0) {\n            println(number)\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/kotlin/juaruibr.kt",
    "content": "/*\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n\n// Lenguaje Kotlin\n\n/* Operadores de Signo\n   Comenzamos con los operadores unarios que representan la propiedad de un número de ser negativo,\n   representado por -, o positivo, representado por +.\n\n   Operador\tExpresión\tFunción equivalente\n      +\t       +a\t       a.unaryPlus()\n      -\t       -a\t       a.unaryMinus()\n*/\nfun operadoresDeSignos() {\n    val a = -3\n    println(\"a=${-a}\") // Negar valor con valor de -3, por resultado nos dará a=3\n}\n\n// Operadores Aritméticos\nfun operadoresAritmeticos() {\n    val a = 10\n    val b = 20\n\n    println(\"($a + $b)= ${a + b}\") // Suma\n    println(\"($a - $b)= ${a - b}\") // Resta\n    println(\"($a x $b)= ${a * b}\") // Multiplicación\n    println(\"($a / $b)= ${a / b}\") // Divisón\n    println(\"($a % $b)= ${a % b}\") // Residuo\n}\n\n/* Operadores de Asignación Compuesta\n   Estos operadores son la combinación entre el operador de asignación y los operadores aritméticos,\n   con el fin de usar como operando la variable de resultado.\n\n   Por ejemplo: si quieres acumular el valor de b en a, la abreviación para el operador compuesto\n                de suma es la siguiente: a += b // a = a + b\n\n   Operador\tExpresión simplificada\tExpresión Completa\tFunción Equivalente\n      +=\t       a+=b\t                   a=a+b\t      a.plusAssign(b)\n      -=\t       a-=b\t                   a=a-b\t      a.minusAssign(b)\n      *=\t       a*=b\t                   a=a*b\t      a.timesAssign(b)\n      /=\t       a/=b\t                   a=a/b\t      a.divAssign(b)\n      %=\t       a%=b\t                   a=a%b\t      a.remAssign(b)\n */\nfun operadoresAsignacionCompuesta() {\n    var a = 100\n    val b = 5\n\n    a += b\n    println(\"+= $a\")\n    a -= b\n    println(\"-= $a\")\n    a *= b\n    println(\"*= $a\")\n    a /= b\n    println(\"/= $a\")\n    a %= b\n    println(\"%= $a\")\n}\n\n/* Operadores de Incremento y Decremento\n   El operador de incremento, representado por dos signos de suma (++), incrementa en la unidad\n   al operando.\n\n   monstersKilled++\n\n   Análogamente, el operador de decremento, doble signo menos (--), disminuye en la unidad al\n   operando.\n\n   hearts--\n\n   El incremento depende de si el operador es prefijo o sufijo del operando:\n\n    Prefijo: Se realiza el incremento sobre la variable y luego es usada en la expresión que la\n    contiene.\n\n    Sufijo: Se usa la variable en la expresión y luego si se aplica el incremento.\n    Ejemplo: Declarar una variable entera con el valor de 2 e imprimir su valor luego de incrementar\n             con prefijo y decrementar con sufijo.\n */\nfun operadoresDeIncrementoyDecremento() {\n    var a = 2\n\n    println(\"De $a a ${++a}\") // De 2 a 3\n    println(\"De $a a ${a--}\") // De 3 a 3\n    println(\"Valor final > $a\") // Valor final > 2\n\n    // Aunque el valor es disminuido en la segunda impresión, este no se hace efectivo sino hasta\n    // que se termina la línea.\n    // Por eso el resultado final es 2 en la tercera impresión.\n}\n\n/* Operadores Relacionales\n   Los operadores relacionales te permiten verificar enunciados de igualdad y desigualdad entre dos\n   valores. El tipo de dato resultante de la expresión es Boolean, indicando la veracidad del\n   enunciado expresado.\n\n   Aquí hay una la tabla de estos operadores:\n\n    Operador\t  Enunciado\t           Expresión\t       Función Equivalente\n      ==\t    a es igual a b\t          a==b\t       a?.equals(b) ?: (b === null)\n      !=\t    a es diferente de b\t      a!=b\t      !(a?.equals(b) ?: (b === null))\n       <\t    a es menor que b\t      a<b\t            a.compareTo(b)<0\n       >\t    a es mayor que b\t      a>b\t            a.compareTo(b)>0\n      <=\t    a es menor ó igual que b  a<=b\t            a.compareTo(b)<=0\n      >=\t    a es mayor o igual que b  a>=b\t            a.compareTo(b)>=0\n\n    Ejemplo: Usar los operadores relacionales entre los números 17 y 20.\n */\nfun operadoresRelacionales() {\n    val a = 17\n    val b = 20\n\n    println(\"$a es igual a $b: ${a == b}\")  // 20: false\n    println(\"$a es diferente a $b: ${a != b}\") // 20: true\n    println(\"$a es menor que $b: ${a < b}\")  // 20: true\n    println(\"$a es mayor que $b: ${a > b}\")  // 20: false\n    println(\"$a es menor o igual que $b: ${a <= b}\")  // 20: true\n    println(\"$a es mayor o igual que $b: ${a >= b}\")  // 20: false\n}\n\n/* Operadores Logicos\n   Los operadores lógicos te permiten crear expresiones de lógica proposicional como lo son\n   conjunción, disyunción y negación.\n\n   && / Conjunción (and): el resultado es true si a y b son true / a && b\n   || / Disyunción (or): el resultado es true si a o b son true / a || b\n   !  / Negación (not): el resultado es false si a es true, o viceversa / !a\n\n   Ejemplo: Usar las proposiciones «5 mayor que 0» y «5 es par» para comprobar el funcionamiento\n   de los operadores lógicos.\n */\n\nfun operadoresLogicos() {\n    val input = 5\n    var res: Boolean\n\n    val greaterThanZero = input > 0\n    val isEven = input % 2 == 0\n\n    res = greaterThanZero && isEven\n    println(\"Es mayor que cero y par:$res\")\n\n    res = greaterThanZero || isEven\n    println(\"Es mayor que cero o par:$res\")\n\n    res = greaterThanZero && !isEven\n    println(\"Es mayor que cero e impar:$res\")\n}\n\n/* Operadores a nivel de Bits\n   Kotlin provee funciones para los tipos primitivos enteros, que actúan como operadores a nivel\n   de bits.\n\n   and()\tand bit a bit\ta and b\n   or()\t    or bit a bit\ta or b\n   xor()\txor bit a bit\ta xor b\n   inv()\tnot bit a bit\ta.inv()\n   shl()\tDesplazamiento de bits a la izquierda\t          a shl b\n   shr()\tDesplazamiento de bits a la derecha\t              a shr b\n   ushr()\tDesplazamiento de bits a la derecha sin signo\t  a ushr b\n\n   Ejemplo: Operar a nivel de bits los números enteros 5 y 7.\n */\n\nfun operadoresaNivelDeBits() {\n    val a = 5\n    val b = 7\n\n    println(\"a and b: ${a and b}\")   // a and b: 5\n    println(\"a or b: ${a or b}\")     // a or b: 7\n    println(\"a xor b: ${a xor b}\")   // a xor b: 2\n    println(\"a.inv(): ${a.inv()}\")   // a.inv(): -6\n    println(\"a shl b: ${a shl b}\")   // a shl b: 640\n    println(\"a shr b: ${a shr b}\")   // a shr b: 0\n    println(\"a ushr b: ${a ushr b}\") // a ushr b: 0\n}\n\n// *************************************************************************************************\n// ESTRUCTURAS DE CONTROL\n/*\n    Las estructuras de programación en Kotlin son las construcciones fundamentales que te permiten\n    controlar el flujo de ejecución de un programa. Las principales estructuras de programación en\n    Kotlin son:\n\n    Estructuras Condicionales:\n\n    if: Permite ejecutar un bloque de código si una condición es verdadera.\n    when: Similar a un switch-case en otros lenguajes, pero más versátil y poderoso.\n\n    Estructuras Repetitivas:\n\n    for: Utilizado para iterar sobre una secuencia de elementos (como un rango numérico).\n    while: Ejecuta un bloque de código mientras una condición sea verdadera.\n    do-while: Ejecuta un bloque de código al menos una vez y luego verifica una condición.\n\n    Control de Flujo:\n    return: Devuelve un valor y sale de una función.\n    break: Sale de un bucle antes de que termine su ejecución normal.\n    continue: Salta a la siguiente iteración de un bucle.\n */\n\n/* ESTRUCTURAS CONDICIONALES */\n\n//Estructura if basico\nval edad = 18\nif (edad >= 18) { println(\"Eres mayor de edad\") }\nelse { println(\"Eres menor de edad\") }\n\n// Estructura if como expresión\nval calificacion = 85\nval resultado = if (calificacion >= 60) { \"Aprobado\" }\nelse { \"Reprobado\" } println(\"El resultado es: $resultado\")\n\n// Estructura when\n// La estructura when es similar a un switch-case en otros lenguajes, pero más poderosa y flexible.\nval dia = 3\nwhen (dia) {\n    1 -> println(\"Lunes\")\n    2 -> println(\"Martes\")\n    3 -> println(\"Miércoles\")\n    4 -> println(\"Jueves\")\n    5 -> println(\"Viernes\")\n    else -> println(\"Día no válido\")\n}\n\n// También puedes usar el when con expresiones:\nval calificacion = 85\nval resultado = when {\n    calificacion >= 90 -> \"Excelente\"\n    calificacion >= 80 -> \"Bueno\"\n    calificacion >= 70 -> \"Regular\"\n    else -> \"Insuficiente\" }\n    println(\"El resultado es: $resultado\")\n\n/* ESTRUCTURAS REPETITIVAS */\n/*\n    En Kotlin, al igual que en otros lenguajes de programación, puedes utilizar estructuras\n    repetitivas para ejecutar un bloque de código varias veces. Las estructuras repetitivas más\n    comunes son los bucles for, while y do-while. Aquí tienes ejemplos de cómo usarlos:\n */\n\n// Bucle for\n// El bucle for se utiliza para iterar sobre una secuencia de elementos\n// (por ejemplo, un rango numérico).\n\nfor (i in 1..5) { println(\"Iteración $i\") }\n\n// Bucle while\n// El bucle while se ejecuta siempre que la condición especificada sea verdadera.\n\nvar contador = 1 while (contador <= 5) { println(\"Iteración $contador\") contador++ }\n\n// Bucle do-while\n// El bucle do-while se ejecuta al menos una vez, ya que primero se ejecuta el bloque y\n// luego se verifica la condición.\n\nvar contador = 1 do { println(\"Iteración $contador\") contador++ } while (contador <= 5)\n\n// Uso de breal y continue\n// Puedes usar la instrucción break para salir de un bucle antes de que se complete su iteración\n// normal. Y puedes usar la instrucción continue para omitir la iteración actual y pasar a\n// la siguiente.\n\nfor (i in 1..10) { if (i == 5) {\n    break\n}\n// Sale del bucle cuando i es 5 } if (i % 2 == 0) { continue // Salta la iteración cuando i es par }\n// println(\"Número impar: $i\") }\n\n// Estos son ejemplos básicos de cómo utilizar estructuras repetitivas en Kotlin.\n// Puedes combinar estas estructuras con condiciones y lógica adicional para lograr comportamientos\n// más complejos en tu programa.\n\n\n/* ESTRUCTURAS CONTROL DE FLUJO */\n/*\n   ¡Por supuesto! Aquí tienes un ejemplo de control de flujo en Kotlin que utiliza una estructura\n   condicional (if) y una estructura repetitiva (while) para simular un juego de adivinanza:\n */\n\n    fun main() {\n        val numeroSecreto = (1..100).random()\n        var intentos = 0\n        var adivinanza: Int\n\n        println(\"¡Bienvenido al juego de adivinanza!\")\n        println(\"Intenta adivinar el número secreto entre 1 y 100.\")\n\n        while (true) {\n            print(\"Ingresa tu suposición: \")\n            adivinanza = readLine()!!.toInt()\n            intentos++\n\n            if (adivinanza == numeroSecreto) {\n                println(\"¡Felicidades! Adivinaste el número en $intentos intentos.\")\n                break\n            } else if (adivinanza < numeroSecreto) {\n                println(\"El número es mayor.\")\n            } else {\n                println(\"El número es menor.\")\n            }\n        }\n    }\n\n/*\n    En este ejemplo, el programa genera un número secreto aleatorio entre 1 y 100. Luego, utiliza\n    un bucle while que se ejecuta hasta que el jugador adivine correctamente el número.\n    Dentro del bucle, se lee la suposición del jugador y se compara con el número secreto\n    utilizando la estructura condicional if. Si el número adivinado es igual al número secreto,\n    se muestra un mensaje de felicitaciones y se muestra la cantidad de intentos realizados.\n    Si no, se proporciona una pista indicando si el número es mayor o menor.\n\n    Este es solo un ejemplo de cómo se puede implementar el control de flujo en Kotlin.\n    Puedes ajustar y expandir el programa según tus necesidades y creatividad.\n */"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/kotlin/miguelex.kt",
    "content": "fun main () {\n\n    // Operadores aritmeticos\n\n    val a = 3\n    val b = 2\n\n    println(\"a + b = ${a + b}\")\n    println(\"a - b = ${a - b}\")\n    println(\"a * b = ${a * b}\")\n    println(\"a / b = ${a / b}\")\n    println(\"a % b = ${a % b}\")\n\n    // Operadores de asignacion\n\n    var c = 5\n    println(\"El valor de c es $c\")\n    c += 2\n    println(\"El valor de c += 2 es $c\")\n    c -= 2\n    println(\"El valor de c -= 2 es $c\")\n    c *= 2\n    println(\"El valor de c *= 2 es $c\")\n    c /= 2\n    println(\"El valor de c /= 2 es $c\")\n    c %= 2\n    println(\"El valor de c %= 2 es $c\")\n\n    // Operadores de comparacion\n\n    println(\"a == b es ${a == b}\")\n    println(\"a != b es ${a != b}\")\n    println(\"a > b es ${a > b}\")\n\n    // Operadores logicos\n\n    val x = true\n    val y = false\n\n    println(\"x && y es ${x && y}\")\n    println(\"x || y es ${x || y}\")\n    println(\"!x es ${!x}\")\n\n    // Operadores bits\n\n    val m = 12\n    val n = 25\n\n    println(\"m and n es ${m and n}\")\n    println(\"m or n es ${m or n}\")\n    println(\"m xor n es ${m xor n}\")\n\n    // Operadores de desplazamiento\n    println(\"m shl 3 es ${m shl 3}\")\n    println(\"m shr 3 es ${m shr 3}\")\n    println(\"m ushr 3 es ${m ushr 3}\")\n\n    // if else\n\n    val edad = 18\n    if (edad >= 18) {\n        println(\"Eres mayor de edad\")\n    } else {\n        println(\"Eres menor de edad\")\n    }\n\n    // when\n\n    val calificacion = 5\n    when (calificacion) {\n        10 -> println(\"Excelente\")\n        9 -> println(\"Muy bien\")\n        8 -> println(\"Bien\")\n        7 -> println(\"Regular\")\n        6 -> println(\"Suficiente\")\n        else -> println(\"Insuficiente\")\n    }\n\n    // for\n\n    val frutas = listOf(\"Manzana\", \"Pera\", \"Fresa\", \"Uva\")\n    for (fruta in frutas) {\n        println(fruta)\n    }\n\n    // while\n    var contador = 0\n    while (contador < 5) {\n        println(\"El contador es $contador\")\n        contador++\n    }\n\n    // do while\n\n    var contador2 = 0\n    do {\n        println(\"El contador2 es $contador2\")\n        contador2++\n    } while (contador2 < 5)\n\n    // foreach\n    val numeros = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)\n    numeros.forEach {\n        println(it)\n    }\n\n    // break\n    for (i in 1..10) {\n        if (i == 5) {\n            break\n        }\n        println(i)\n    }\n\n    // continue \n    for (i in 1..10) {\n        if (i % 2 == 0) {\n            continue\n        }\n        println(i)\n    }\n\n    // Extra\n\n    for (i in 10..55) {\n        if (i % 2 == 0 && i != 16 && i % 3 == 0)\n            println(i)\n    }\n\n\n\n\n\n\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/kotlin/orzefox.kt",
    "content": "import java.lang.ArithmeticException\n\nfun main() {\n    var a = 2\n    var b = 3\n\n    // Operadores Aritmeticos\n    println(a + b)\n    println(a - b)\n    println(a * b)\n    println(a / b)\n    println(a % b)\n\n    // Operadores Logicos\n    println(a < b && a > b)\n    pritnln(a < b || a > b)\n    printls(!true)\n\n    //Operadores de comparacion\n    println(a == b)\n    println(a != b)\n    println(a < b)\n    println(a > b)\n    println(a >= b)\n    println(a <= b)\n\n    // Operadores de Asignacion\n    var c = 1\n    println(c)\n    c += 1\n    println(c)\n    c -= 2\n    println(c)\n    c *= 3\n    println(c)\n    c /= 4\n    println(c)\n    c %= 5\n    println(c)\n\n    // Operadores de pertenencia\n    println(15 in 1..35)\n    println(25 !in 1..10)\n\n    // Operadores de Bits\n\n    println(a and b)\n    println(a or b)\n    println(a xor b)\n    println(a shl 2)\n    println(a shr 1)\n    println(a ushr b)\n\n    // Condicionales\n\n    // if\n    if(a == b)\n        println(\"$a es igual a $b\")\n    else\n        println(\"$a es diferente a $b\")\n\n    // when\n\n    when (a)\n    {\n        2 -> println(\"Es dos\")\n        3 -> println(\"Es tres\")\n        else -> println(\"No es ni dos ni tres\")\n    }\n\n    // while\n\n    while (a < 5)\n    {\n        println(\"La variable a es $a\")\n        contador++\n    }\n\n    // do while\n\n    do\n    {\n        println(\"La variable b es $b\")\n        b--\n    }\n    while (b > 0)\n\n    // for\n\n    for (i in 0 until 10)\n        println(\"valor del indice es $i\")\n\n    // try catch\n\n    try\n    {\n        val d = b / 0\n        println(\"el resultado es : $d\")\n    }\n    catch (e: ArithmeticException)\n    {\n        println(\"ERROR ARITMETICO\")\n    }\n\n    retroExtra()\n}\n\nfun retroExtra()\n{\n    var ind = 10\n    while (ind != 55)\n    {\n        if (ind % 2 == 0 && ind != 16 && !(ind % 3 == 0)\n            println(ind)\n        ind++\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/kotlin/pedroomar23.kt",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n // Operadores Aritméticos\nfun sum(numero1: Int, numero2: Int): Int {\n    return a + b \n}\n\nfun resta(a: Int, b: Int): Int {\n    return a - b \n}\n\nfun multiplicar(c: Int, d: Int): Int {\n    return c * d \n}\n\nfun dividir(e: Int, f: Int): Int {\n    return e / f \n}\n\nfun modulo(g: Int, h: Int): Int {\n    return g % h\n}\n\n // Operadores Logicos \n val myTrue: Boolan = false || true // OR \n val myFalse: Boolean = true && false // AND \n val myTrueFalse: Boolean != false // Not \n\n // Operadores de Comparacion \n val mayor = 5 > 4 // Mayor Que \n val menor = 4 < 5 // Menor que \n val mayorIgual = 5 >= 4 // Mayor Igual \n val menorIgual = 4 <= 5 // Menor Igual \n\n \n// Bucles \n for (i in 1...3) {\n    print(i)\n }\n\n // IF \n if 5 > 4 {\n    println(\"5 es mayor que 4 \")\n }\n\n // IF ElSE \n if 5 < 4 {\n    print(\"5 es menor que 4 \")\n } else {\n    print(\"5 es menor que 4 \")\n }\n\n // WHEN \n when (x) {\n    0.1 -> print(x == 0, x == 1 )\n    else -> print(\"otherwise\")\n }\n\n // WHile \n do {\n    val y = 5 \n } while y < 5 "
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/kotlin/rikmij.kt",
    "content": "fun main() {\n    println((\"-\".repeat(9) + \" OPERADORES ARITMÉTICOS \" + \"-\".repeat(9)))\n\n    print(\"\\tOperador '+': 3+6 = \")\n    println(3+6)\n    print(\"\\tOperador '-': 6-3 = \")\n    println(6-3)\n    print(\"\\tOperador '*': 3*6 = \")\n    println(3*6)\n    print(\"\\tOperador '/': 6/3 = \")\n    println(6/3)\n    print(\"\\tOperador '%': 6%3 = \")\n    println(6%3)\n\n\n    println(('\\n'+\"-\".repeat(9) + \" OPERADORES LÓGICOS \" + \"-\".repeat(9)))\n\n    print(\"\\tOperador '&&': true && false = \")\n    println(true && false)\n    print(\"\\tOperador '||': true || false = \")\n    println(true || false)\n    print(\"\\tOperador '!': !false = \")\n    println(!false)\n\n\n    println(('\\n'+\"-\".repeat(9) + \" OPERADORES DE COMPARACIÓN \" + \"-\".repeat(9)))\n\n    print(\"\\tOperador '<': 3<6 = \")\n    println(3<6)\n    print(\"\\tOperador '<=': 3<=6 = \")\n    println(3<=6)\n    print(\"\\tOperador '>': 3>6 = \")\n    println(3>6)\n    print(\"\\tOperador '>=': 3>=6 = \")\n    println(3>=6)\n    print(\"\\tOperador '==': 3==6 = \")\n    println(3==6)\n    print(\"\\tOperador '!=': 3!=6 = \")\n    println(3!=6)\n    print(\"\\tOperador '===': 3===3 = \")\n    println(3===3)\n\n    println(('\\n'+\"-\".repeat(9) + \" OPERADORES DE ASIGNACIÓN \" + \"-\".repeat(9)))\n\n    println(\"\\tvar n = 7\")\n    var n = 7\n    print(\"\\tOperador '+=': n += 3 ---> \")\n    n+=3\n    println(n)\n    print(\"\\tOperador '-=': n -= 3 ---> \")\n    n-=3\n    println(n)\n    print(\"\\tOperador '*=': n *= 3 ---> \")\n    n*=3\n    println(n)\n    print(\"\\tOperador '/=': n /= 3 ---> \")\n    n/=3\n    println(n)\n    print(\"\\tOperador '%=': n %= 3 ---> \")\n    n%=3\n    println(n)\n\n\n    println(('\\n'+\"-\".repeat(9) + \" OPERADORES DE INCREMENTO Y DECREMENTO \" + \"-\".repeat(9)))\n\n    println(\"\\tvar a = 3\")\n    var a = 3\n    print(\"\\tOperador '++': ++a = \")\n    println(++a)\n    print(\"\\tOperador '--': --a = \")\n    println(--a)\n\n\n    println(('\\n'+\"-\".repeat(9) + \" OPERADORES DE BITS \" + \"-\".repeat(9)))\n\n    print(\"\\tOperador 'and()': 3 and 6 = \")\n    println(3 and 6)\n    print(\"\\tOperador 'or()': 3 or 6 = \")\n    println(3 or 6)\n    print(\"\\tOperador 'xor()': 3 xor 6 = \")\n    println(3 xor 6)\n    print(\"\\tOperador 'shl()': 3 shl 6 = \")\n    println(3 shl 6)\n    print(\"\\tOperador 'shr()': 3 shr 6 = \")\n    println(3 shr 6)\n    print(\"\\tOperador 'ushr()': 3 ushr 6 = \")\n    println(3 ushr 6)\n    print(\"\\tOperador 'inv()': (a es la variable del apartado anterior) a.inv = \")\n    println(a.inv())\n\n\n    println(('\\n'+\"-\".repeat(9) + \" EJEMPLOS CON ESTRUCTURAS DE CONTROL \" + \"-\".repeat(9)))\n\n    println((\"-\".repeat(3)) + \"EJERCICIO 1\" + (\"-\".repeat(3)))\n    while(true) {\n        try {\n            println(\"Escribe un número para comprobar si es par o impar: \")\n            val num = readln().toInt()\n\n            if (num %2 == 0){\n                println(\"Es par\")\n            }else{\n                println(\"Es impar\")\n            }\n            break\n        }catch(e: Exception){\n            println(\"Que sea un número\")\n        }\n    }\n\n    println((\"-\".repeat(3)) + \"EJERCICIO 2\" + (\"-\".repeat(3)))\n    println(\"Vamos a contar las vocales. Pon una palabra: \")\n    val word = readln()\n    val vocals = \"aeiou\"\n    val count = mutableListOf<Char>()\n\n    for (letter in word){\n        if (letter in vocals){\n           count.add(letter)\n        }\n    }\n    println(count.size)\n\n    println((\"-\".repeat(3)) + \"EJERCICIO 3\" + (\"-\".repeat(3)))\n    val rangeNum = 1..30\n    val numChosen = rangeNum.random()\n    var vidas = 5\n\n    do {\n        print(\"Escoge un número entre 1 y 30: \")\n        val choose = readln().toInt()\n\n        if(choose > numChosen){\n            println(\"El número es menor. Pon uno más pequeño. Te quedan $vidas\")\n            vidas -= 1\n        }else if(choose < numChosen){\n            println(\"El número es mayor. Pon uno más grande. Te quedan $vidas\")\n            vidas -= 1\n        }\n        if (vidas == 0){\n            println(\"Perdiste. El número era $numChosen\")\n            break\n        }\n    } while (choose != numChosen)\n\n    if(vidas > 0){\n        println(\"Ganaste!\")\n    }\n\n\n    println('\\n'+\"*\".repeat(11)+\" EXTRA \"+\"*\".repeat(11))\n    val nums = mutableListOf<Int>()\n\n    for (n in 10..55) {\n        if (n % 2 == 0 && n % 3 != 0 && n != 16) {\n            nums.add(n)\n        }\n    }\n    println(nums)\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/kotlin/saracorraless.kt",
    "content": "//01 - OPERADORES Y ESTRUCTURAS DE CONTROL\n\n//https://kotlinlang.org/docs/keyword-reference.html#modifier-keywords\n//http://www.androidcurso.com/index.php/99-kotlin/912-estructuras-de-control-en-kotlin\n//https://kotlin.desarrollador-android.com/basico/control-de-flujo/\n\nfun main(): Unit {\n    //OPERADORES ARITMÉTICOS\n    var ope1 = 5\n    var ope2 = 4\n    var ope3 = 1\n    //Suma\n    println(\"Con operador + \" + (ope1 + ope2))\n    println(\"Con función equivalente sumar \"+ ope1.plus(ope2))\n    ope3+=ope1\n    println(\"Suma asignación compuesta \"+ ope3)\n\n    //Restar\n    println(\"Con operador - \" + (ope1 - ope2))\n    println(\"Con función equivalente restar \"+ ope1.minus(ope2))\n    ope3-=ope1\n    println(\"Resta asignación compuesta \"+ ope3)\n\n    //Múltiplicación\n    println(\"Con operador * \" + (ope1 * ope2))\n    println(\"Con función equivalente multiplicación \"+ ope1.times(ope2))\n    ope3*=ope1\n    println(\"Multiplicación asignación compuesta \"+ ope3)\n\n    //División\n    println(\"Con operador / \" + (ope2 / ope1))\n    println(\"Con función equivalente división \"+ ope2.div(ope1))\n    ope3/=ope1\n    println(\"División asignación compuesta \"+ ope3)\n\n    //residuo\n    println(\"Con operador % \" + (ope1 % ope2))\n    println(\"Con función equivalente multiflicación \"+ ope1.rem(ope2))\n    ope3%=ope1\n    println(\"Residuo asignación compuesta \"+ ope3)\n\n\n    //Incremento: puede ir como prefijo o sufijo\n    println(\"Incremento \"+ (ope1++))\n\n    //Decremento: puede ir como prefijo o sufijo\n    println(\"Decremento \"+ (ope1--))\n\n    //Operadores relacionales\n    //igualdad\n    println(\"los númenos 2 y 2 son iguales: \"+ (2==2))\n\n    //diferente de...\n    println(\"los númenos 2 y 1 son diferentes: \"+ (2!=1))\n\n    //menor que\n    println(\"2 es menor que 3: \"+ (2<3))\n\n    //mayor que\n    println(\"4 es menor que 3: \"+ (4>3))\n\n    //menos o igual que\n    println(\"2 es menor o igual que 3: \"+ (2<=3))\n\n    //mayor o igual que\n    println(\"3 es mayor o igual que 3: \"+ (2>=3))\n\n\n    //Operadores lógicos\n    var num1 = 1\n    var num2 = 4\n    //AND\n    println(\"num1 and num2: ${num1 and num2}\")\n    //OR\n    println(\"num1 or num2: ${num1 or num2}\")\n    //XOR\n    println(\"num1 xor num2: ${num1 xor num2}\")\n\n    //NOT\n    println(\"num1.inv(): ${num1.inv()}\")\n\n    //DESPLAZAMIENTO DE BITS A LA IZQUIERDA\n    println(\"num1 shl num2: ${num1 shl num2}\")\n    //DESPLAZAMIENTO DE BITS A LA DERECHA\n    println(\"num1 shr num2: ${num1 shr num2}\")\n    //DESPLAZAMIENTO DE BITS A LA DERECHA SIN SIGNO\n    println(\"num1 ushr num2: ${num1 ushr num2}\")\n\n\n    //ESTRUCTURAS DE CONTROL\n    //IF\n    if (2<3){\n        println(\"2 es menor a 3\")\n    }\n\n    //IF ELSE\n    if (\"agua\" != \"cafe\"){\n        println(\"El café es mejor que el agua\")\n    } else{\n        println(\"Hay que beber agua para estar sano\")\n    }\n\n    //WHEN\n    when(\"Agua\"){\n        \"Agua\" -> print(\"sanito\")\n        \"zumo\" -> print(\"Mejor come fruta natural\")\n        else -> { println(\"mejora tu dieta\")\n        }\n    }\n\n\n    //BUCLE FOR\n    for (i in 0..5){\n        println(\"contador for: \"+ i)\n    }\n\n    //BUCLE WHILE\n    while (num2 > 0){\n        println(\"contador while: \"+ num2)\n        num2--\n    }\n    num2 = 6\n    //BUCLE DO WHILE\n    do {\n        println(\"contador do while: \"+ num2)\n        num2--\n    }while(num2 > 0)\n\n    //se pueden usar controladores para salir de la estructura\n    //return : retornamos de la función actual (o función anónima).\n    //break : terminamos el bucle más cercano.\n    //continue : continuamos con el siguiente paso en el bucle más cercano.\n\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/kotlin/traver79.kt",
    "content": "fun main() {\n/*\n1) TODOS LOS OPERADORES DEL LENGUAJE. CON EJEMPLOS. \n */\n// - Ejemplos de operadores aritmeticos\n// Son los siguientes: +, -, *, /, % - mathematical operators\nval numero1 = 10\nval numero2 = 5\n\nprintln(\"Los operadores matematicos: Ejemplo con el 10 y el 5\")\nprintln(\"$numero1 + $numero2 =${numero1+numero2}\")\nprintln(\"$numero1 - $numero2 =${numero1-numero2}\")\nprintln(\"$numero1 * $numero2 =${numero1*numero2}\")\nprintln(\"$numero1 / $numero2 =${numero1/numero2}\")\nprintln(\"$numero1 % $numero2 =${numero1%numero2}\")\n\n// Ejemplos de operadores lógicos\n// &&, ||, ! - logical 'and', 'or', 'not' operators\nprintln(\"-----------------------------------------------------\")\nprintln(\"Los operadores logicos:\")\nval myboolean1=true\nval myboolean2=false\nprintln(\"$myboolean1 and (&&) $myboolean2 =${myboolean1 && myboolean2}\")\nprintln(\"$myboolean1 or (||) $myboolean2 =${myboolean1 || myboolean2}\")\nprintln(\"not (!) $myboolean1 = ${!myboolean1}\")\n\n// Ejemplos de operadores de comparación\n// <, >, <=, >= - comparison operators \nprintln(\"-----------------------------------------------------\")\nprintln(\"Los operadores de comparacion\")\nprintln(\"$numero1 > $numero2 = ${numero1>numero2}\")\nprintln(\"$numero1 < $numero2 = ${numero1<numero2}\")\nprintln(\"$numero1 <= $numero2 = ${numero1<=numero2}\")\nprintln(\"$numero1 >= $numero2 = ${numero1>=numero2}\")\nprintln(\"$numero1 == $numero2 = ${numero1==numero2}\")\nprintln(\"$numero1 != $numero2 = ${numero1!=numero2}\")\n// Ejemplos de operadores de asignación, identidad, pertenencia, bits\n//Asignación\nprintln(\"-----------------------------------------------------\")\nprintln(\"El operador de asignacion :  = \")\n // Declaración de una variable sin iniciarla:\n var numero: Int\n// Asignación de un valor a la variable\n numero = 10\n // Imprimir el valor de la variable\n println(\"El valor de la variable 'numero' es: $numero y la he asignado con =\")\n\n //identidad son === y !==\n println(\"-----------------------------------------------------\")\n println(\"Los operadores de identidad son === y !==, se utilizan para verificar \")\n println(\"si dos referencias apuntan al mismo objeto en la memoria.\")\n val a: String = \"Hola\"\n val b: String = \"Hola\"\n val resultado1: Boolean = (a === b)\n println(\"a y b apuntan al mismo objeto? $resultado1\")  // Imprime: ¿a y b apuntan al mismo objeto? true\n\n //pertenencia\n /*En Kotlin, los operadores de pertenencia se utilizan \n para verificar si un elemento está presente en una colección o en un rango. \n Los operadores principales de pertenencia son in y !in\n*/\n println(\"-----------------------------------------------------\")\n println(\"Los operadores de pertenencia \")\n var numeros = listOf(1, 2, 3, 4, 5)\n var resultado2: Boolean = 3 in numeros\n println(\"El numero 3 esta en la lista? $resultado2\")  // Imprime: ¿El número 3 está en la lista? true\n\n//BITS\nprintln(\"-----------------------------------------------------\")\nprintln(\"Los operadores de BITS \")\n// Operador AND a nivel de bits\nval resultadoAnd = 0b1010 and 0b1100\nprintln(\"Resultado de AND a nivel de bits: $resultadoAnd\")  // Imprime: Resultado de AND a nivel de bits: 8 (binario: 0b1000)\n\n// Operador OR a nivel de bits\nval resultadoOr = 0b1010 or 0b1100\nprintln(\"Resultado de OR a nivel de bits: $resultadoOr\")  // Imprime: Resultado de OR a nivel de bits: 14 (binario: 0b1110)\n\n// Operador XOR a nivel de bits\nval resultadoXor = 0b1010 xor 0b1100\nprintln(\"Resultado de XOR a nivel de bits: $resultadoXor\")  // Imprime: Resultado de XOR a nivel de bits: 6 (binario: 0b0110)\n\n// Operador de desplazamiento a la izquierda\nval resultadoShl = 0b1010 shl 2\nprintln(\"Resultado de desplazamiento a la izquierda: $resultadoShl\")  // Imprime: Resultado de desplazamiento a la izquierda: 40 (binario: 0b101000)\n\n// Operador de desplazamiento a la derecha\nval resultadoShr = 0b1010 shr 1\nprintln(\"Resultado de desplazamiento a la derecha: $resultadoShr\")  // Imprime: Resultado de desplazamiento a la derecha: 5 (binario: 0b0101)\n\n// Operador de desplazamiento a la derecha con extensión de signo\nval resultadoUshr = (-8).ushr(1)\nprintln(\"Resultado de desplazamiento a la derecha sin extensión de signo: $resultadoUshr\")  // Imprime: Resultado de desplazamiento a la derecha sin extensión de signo: 2147483644\n\n\n/*\n2) Ejemplos de todos los tipos de estructuras de control que existan en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n*/\n\nprintln(\"-----------------------------------------------------\")\nprintln(\"LAS ESTRUCTURAS DE CONTROL\")\nestructurasControl()\n\n\n/*3) EXTRA: Crea un programa que imprima por consola todos los números comprendidos\n entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n  */\n\n  println(\"-----------------------------------------------------\")\n  println(\"EL EXTRA\")\n  val rango = 10..55 \n  for (i in rango ){\n        if (i %2 == 0 && i!=16 && i%3!=0){\n            println(i)\n        }}\n\nprintln(\"de otra forma\")\nfor (i in 10..55 step 2) {\n            if (i != 16 && i % 3 != 0) {\n                println(i)\n            }\n        }\n\n    }\n\n\n\nfun estructurasControl() {\n    // Estructura de control if\n    val numero = 10\n    if (numero > 0) {\n        println(\"El numero es positivo\")\n    } else if (numero < 0) {\n        println(\"El número es negativo\")\n    } else {\n        println(\"El número es cero\")\n    }\n\n    // Estructura de control when (similar a switch en otros lenguajes)\n\n    val diaSemana = 3\n    when (diaSemana) {\n        1 -> println(\"Lunes\")\n        2 -> println(\"Martes\")\n        3 -> println(\"Miércoles\")\n        4 -> println(\"Jueves\")\n        5 -> println(\"Viernes\")\n        else -> println(\"Fin de semana\")\n    }\n\n    // Estructura de control for\n    val listaNumeros = listOf(1, 2, 3, 4, 5)\n    println(\"Recorriendo lista con for:\")\n    for (a in listaNumeros) {\n        println(a)\n    }\n\n    // Estructura de control while\n    var contador = 0\n    println(\"Contando hasta 5 con while:\")\n    while (contador <= 5) {\n        println(contador)\n        contador++\n    }\n\n    // Estructura de control do-while\n    var contadorDoWhile = 0\n    println(\"Contando hasta 5 con do-while:\")\n    do {\n        println(contadorDoWhile)\n        contadorDoWhile++\n    } while (contadorDoWhile <= 5)\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/kotlin/westwbn.kt",
    "content": "fun main() {\n//    Operadores:\n//    #Aritméticos\n    var money = 1000\n    val numberOne = 5\n    val numberTwo = 3\n    val addition = numberOne + numberTwo\n    val subtraction = numberOne - numberTwo\n    val multiplication = numberOne * numberTwo\n    val division = numberOne / numberTwo\n    val module = numberOne % numberTwo\n\n    println(\"Suma: $addition \\nResta: $subtraction \\nMultiplicación: $multiplication \\nDivisión: $division \\nModulo: $module\")\n\n//    #Logicos\n    val conditionTrue = true\n    val conditionFalse = false\n    println()\n    println(\"conditionTrue AND conditionFalse: ${conditionTrue && conditionFalse}\")\n    println(\"conditionTrue OR conditionFalse: ${conditionTrue || conditionFalse}\")\n    println(\"NOT conditionTrue: ${!conditionTrue}\")\n\n//  #Comparación\n    println()\n    println(\"$numberOne es igual a $numberTwo?: ${numberOne == numberTwo}\")\n    println(\"$numberOne no es igual a $numberTwo?: ${numberOne != numberTwo}\")\n    println(\"$numberOne es mayor que $numberTwo?: ${numberOne > numberTwo}\")\n    println(\"$numberOne es menor que $numberTwo?: ${numberOne < numberTwo}\")\n    println(\"$numberOne es mayor o igual que $numberTwo?: ${numberOne >= numberTwo}\")\n    println(\"$numberOne es menor o igual que $numberTwo?: ${numberOne <= numberTwo}\")\n\n//    #Asignación\n    println()\n    println(\"Actualmente hay $$money\")\n    money += 1200\n    println(\"Se realizo una venta y se añadieron $1200. El saldo es de $${money}\")\n    money -= 500\n    println(\"Se descontaron $500 de impuestos, el dinero total disponible es $$money\")\n\n//    #Pertenencia\n    println()\n    val listNumber = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)\n    println(\"2 esta en la lista?: ${2 in listNumber}\")\n    println(\"18 no esta en la lista?: ${18 !in listNumber}\")\n\n//    Estructuras de control\n//    #If\n    println()\n    if (numberOne in listNumber) {\n        println(\"$numberOne esta en la lista!\")\n    }\n\n//    #If - Else\n    println()\n    if (money in listNumber) {\n        println(\"El numero $money esta en la lista\")\n    } else {\n        println(\"El numero $money no esta en la lista\")\n    }\n\n//    #When\n    val shoppingCart = listOf(\"Leche\", \"Galletitas\", \"Fideos\", \"Aceite\", \"Mayonesa\", \"Gaseosa\")\n    val favorites = listOf(\"Carne\", \"Pollo\", \"Huevos\")\n\n    println()\n    println(\"Selecciona una opción: \\n 1) Carrito de compras \\n 2) Favoritos \\n 3) Menú principal\\n\")\n    val option = readln().toInt()\n\n    when (option) {\n        1 -> {\n            println(\"El carrito contiene los siguientes artículos:\")\n            shoppingCart.forEach { articles -> println(articles) }\n        }\n\n        2 -> {\n            println(\"Sus artículos favoritos son:\")\n            favorites.forEach { articles -> println(articles) }\n        }\n\n        3 -> println(\"Regresando al menu principal..\")\n        else -> println(\"Elige una opcion correcta\")\n    }\n\n//    #For\n    println(\"\\nLa cesta contiene:\")\n    for (article in shoppingCart) {\n        println(article)\n    }\n\n//    #While\n    var loop = 10\n    print(\"\\nCuenta regresiva: \")\n    while (loop >= 0) {\n        print(\"${loop--}..\")\n    }\n    println(\"\\n\")\n\n//    #Do while\n    var life = 500\n    do {\n        val damage = (1..minOf(100, life)).random()\n\n        life -= damage\n        println(\"Daño enemigo: $damage \\nSalud: $life\")\n\n        if (life < 1) {\n            println(\"++Fin del juego!++\")\n            break // Salir del bucle cuando la vida es baja\n        }\n\n    } while (life > 0)\n\n//    Ejercicio Extra\n    extraExercise()\n}\n\nfun extraExercise() {\n    println()\n    println(\"Resultado del ejercicio extra:\")\n    for (number in 10..55 step 2) {\n        if (number == 16 || number % 3 == 0) {\n            continue\n        }\n        println(number)\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/lua/14DavidNKT.lua",
    "content": "-- Lua posee operadores Aritmeticos, Relacionales y Logicos:\n-- ARITMETICOS\n\nprint('Suma: 5 + 5 = ' .. 5 + 5)\nprint('Resta: 10 - 5 = ' .. 10 - 5)\nprint('Multiplicación: 40 * 2 = ' .. 40 * 2)\nprint('División: 8 / 2 = ' .. 8 / 2)\nprint('Modulo: 15 % 3 = ' .. 15 % 3)\nprint('Exponente: 15 ^ 3 = ' .. 15 ^ 3)\n\n-- RELACIONALES\n-- Los operadores relacionales devuelven siempre un resultado \"true\" o \"false\"\n\nprint('Igualdad: 10 == 10', 10 == 10)\nprint('Desigualdad: 10 ~= 10', 10 ~= 10)\nprint('Es mayor que: 10 > 5', 10 > 5)\nprint('Es menor que: 10 < 5', 10 < 5)\nprint('Es mayor o igual que: 10 <= 5', 10 <= 5)\nprint('Es menor o igual que: 10 >= 5', 10 >= 5)\n\n-- LOGICOS\n-- Son and, or y not, como las estructuras de contol, todos los operadores logicos consideran false y nil\n-- como falso y todo lo demas verdadero.\n\nprint('AND: 5 + 5 = 10 and 10 - 5 = 5 es', 5 + 5 == 10 and 10 - 5 == 5)\nprint('OR: 5 + 5 = 14 or 10 - 5 = 5 es', 5 + 5 == 14 and 10 - 5 == 5)\nprint('NOT: NOT 5 + 5 = 14 es', not (5 + 5 == 14))\n\n-- ESTRUCTURAS DE CONTROL\nmi_variable = \"Estructuras de Control\"\n\n-- Condicionales\nif mi_variable == \"Estructuras de Control\" then\n    print('mi_variable es \"Estructuras de Control\"')\nelseif mi_variable == \"Estructuras\" then\n    print('mi_variable es \"Estructuras\"')\nelse\n    print('mi_variable no es \"Estructuras de Control\"')\nend\n\n-- Iterativas\ni = 0\n\nfor i=0,5  do\n    print(i)\nend\n\nwhile i <= 10 do\n    print(i)\n    i = i + 1\nend\n---------------------- Ejecicio Adicional-------------------------------------\nfor i=10, 55 do\n    if i % 2 == 0 and i ~= 16 and i % 3 ~= 0 then\n        print(i)\n    end\nend\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/lua/Bert008.lua",
    "content": "--[[]\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n]]\nprint(\"Operadores Aritmeticos\")\nx = 10\ny = 5\nprint(\"Suma (x + y) = \", x + y)\nprint(\"Resta (x - y) = \", x - y)\nprint(\"Multiplicacion (x * y) = \", x * y)\nprint(\"Divicion (x / y) = \", x / y)\nprint(\"Modulo (x % y) = \", x % y)\nprint(\"Exponente (x ^ y) = \", x ^ y)\nprint(\"Cociente (x // y) = \", x // y)\n\nprint(\"Operadores de comparacion\")\nprint(\"Igual que (x == y): \", x == y)\nprint(\"Diferente de (x ~= y): \", x ~= y)\nprint(\"Menor que (x < y): \", x < y)\nprint(\"Mayor que (x > y): \", x > y)\nprint(\"Menor o igual que (x <= y): \", x <= y)\nprint(\"Mayor o igual que (x >= y): \", x >= y)\n\nprint(\"Operasores logicos\")\nprint(\"And (x and y): \", x and y)\nprint(\"Or (x or y): \", x or y)\nprint(\"Not False: \", not false)\n\nprint(\"Operadores de concatenacion y longitud\")\nname = \"Bert\"\nlastname = \"008\"\nprint(name .. lastname)\nprint(#lastname)\n\nprint(\"Estructuras de control\")\nprint(\"Estructura if - else\")\nif x == y then\n    print(\"son iguales\")\nelseif x < y then\n    print(\"x es menor que y\")\nelse\n    print(\"x es mayor que\")\nend\nprint(\"Estructura while\")\ni = 0\nwhile i <= 10 do\n    print(\"bucle: \", i)\n    i = i + 1\nend\nprint(\"Estructura repeat\")\ni = 0\nrepeat\n    print(\"bucle: \", i)\n    i = i + 1\nuntil i > 5\nprint(\"Estructura for\")\nfor i = 1, 5 do\n    print(\"i\")\nend\n\nprint(\"puntos extra\")\nfor i = 10, 55, 2 do\n    if i % 3 ~= 0 and i ~= 16 then\n        print(i)\n    end\nend"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/lua/ElTitoJet.lua",
    "content": "-- ================================================\n-- Operadores en Lua\n-- ================================================\n\n-- Aritméticos\nlocal suma = 5 + 3\nlocal resta = 10 - 4\nlocal multiplicacion = 2 * 6\nlocal division = 8 / 2\nlocal potencia = 2 ^ 3\nlocal modulo = 10 % 3\n\nprint(\"Operadores Aritmeticos:\")\nprint(\"Suma:\", suma)\nprint(\"Resta:\", resta)\nprint(\"Multiplicacion:\", multiplicacion)\nprint(\"Division:\", division)\nprint(\"Potencia:\", potencia)\nprint(\"Modulo:\", modulo)\n\n-- Comparación\nprint(\"\\nOperadores de Comparacion:\")\nprint(\"5 > 3:\", 5 > 3) -- Mayor que\nprint(\"5 < 3:\", 5 < 3) -- Menor que\nprint(\"5 == 5:\", 5 == 5) -- Igual que\nprint(\"5 ~= 3:\", 5 ~= 3) -- Distinto que\nprint(\"5 >= 5:\", 5 >= 5) -- Mayor o igual que\nprint(\"3 <= 4:\", 3 <= 4) -- Menor o igual que\n\n-- Lógicos\nlocal a, b = true, false\nprint(\"\\nOperadores Logicos:\")\nprint(\"true and false:\", a and b)\nprint(\"true or false:\", a or b)\nprint(\"not true:\", not a)\n\n-- Asignación (en Lua, el operador de asignación es solo `=`)\nlocal x = 10\nx = x + 5\nprint(\"\\nOperador de Asignacion:\")\nprint(\"x =\", x)\n\n-- Identidad (comparación de referencia para tablas)\nlocal t1 = {1, 2}\nlocal t2 = t1\nlocal t3 = {1, 2}\nprint(\"\\nOperador de Identidad (referencia de tablas):\")\nprint(\"t1 == t2:\", t1 == t2) -- true\nprint(\"t1 == t3:\", t1 == t3) -- false\n\n-- Pertenencia (no existe directamente en Lua, se simula con búsqueda en tabla)\nprint(\"\\nSimulacion de Operador de Pertenencia:\")\nlocal frutas = {\"manzana\", \"pera\", \"naranja\"}\nfunction contiene(tabla, valor)\n  for _, v in ipairs(tabla) do\n    if v == valor then return true end\n  end\n  return false\nend\nprint(\"¿Contiene 'pera'?:\", contiene(frutas, \"pera\"))\n\n-- Operadores de bits (desde Lua 5.3)\nprint(\"\\nOperadores de Bits:\")\nlocal bit_or = 5 | 3    -- 0101 OR 0011 = 0111 = 7\nlocal bit_and = 5 & 3   -- 0101 AND 0011 = 0001 = 1\nlocal bit_xor = 5 ~ 3   -- 0101 XOR 0011 = 0110 = 6\nlocal bit_not = ~5      -- NOT 0101 = 1010 = -6 (complemento a dos)\nprint(\"5 | 3:\", bit_or)\nprint(\"5 & 3:\", bit_and)\nprint(\"5 ~ 3:\", bit_xor)\nprint(\"~5:\", bit_not)\n\n-- ================================================\n-- Estructuras de Control\n-- ================================================\n\n-- Condicional\nprint(\"\\nEstructura Condicional:\")\nlocal edad = 20\nif edad >= 18 then\n  print(\"Eres mayor de edad\")\nelseif edad >= 13 then\n  print(\"Eres adolescente\")\nelse\n  print(\"Eres menor\")\nend\n\n-- Iterativa: for\nprint(\"\\nEstructura Iterativa: for\")\nfor i = 1, 5 do\n  print(\"Iteracion:\", i)\nend\n\n-- Iterativa: while\nprint(\"\\nEstructura Iterativa: while\")\nlocal n = 1\nwhile n <= 3 do\n  print(\"n =\", n)\n  n = n + 1\nend\n\n-- Iterativa: repeat-until (como do-while)\nprint(\"\\nEstructura Iterativa: repeat-until\")\nlocal m = 1\nrepeat\n  print(\"m =\", m)\n  m = m + 1\nuntil m > 3\n\n-- Excepciones: pcall (protección de llamadas)\nprint(\"\\nManejo de Excepciones con pcall:\")\nlocal function divide(a, b)\n  return a / b\nend\n\nlocal success, result = pcall(divide, 10, 0)\nif success then\n  print(\"Resultado:\", result)\nelse\n  print(\"Error al dividir:\", result)\nend\n\n-- ================================================\n-- DIFICULTAD EXTRA\n-- Números entre 10 y 55 que:\n-- - Son pares\n-- - No son 16\n-- - No son múltiplos de 3\n-- ================================================\nprint(\"\\nDIFICULTAD EXTRA:\")\nfor i = 10, 55 do\n  if i % 2 == 0 and i ~= 16 and i % 3 ~= 0 then\n    print(i)\n  end\nend\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/lua/ansuzgs.lua",
    "content": "--[[\n    OPERATORS\n]]\n\n-- Arithmetic operators\n\nprint(\"5 + 2 = \", 5 + 2)\nprint(\"5 - 2 = \", 5 - 2)\nprint(\"5 * 2 = \", 5 * 2)\nprint(\"5 / 2 = \", 5 / 2)\nprint(\"5 % 2 = \", 5 % 2)\nprint(\"5 ^ 2 = \", 5 ^ 2)\nprint(\"-5 = \", -5)\n\n-- Relational operators\n\nprint(\"5 == 2 is \", 5 == 2)\nprint(\"5 ~= 2 is \", 5 ~= 2)\nprint(\"5 > 2 is \", 5 > 2)\nprint(\"5 < 2 is \", 5 < 2)\nprint(\"5 >= 2 is \", 5 >= 2)\nprint(\"5 <= 2 is \", 5 <= 2)\n\n-- Logical operators\n\nprint(\"true and false is \", true and false)\nprint(\"true or false is \", true or false)\nprint(\"not true is \", not true)\n\n-- Other operators\n\nprint(\"Hello\" .. \"World\")\nprint(\"#'Hello' is \", #'Hello')\n\n-- EXTRA\n\nfor i = 10, 55, 2 do\n  if i ~= 16 and i % 3 ~= 0 then\n    print(i)\n  end\nend\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/lua/edalmava.lua",
    "content": "-- Operadores aritméticos\n\nlocal x, y = 10, 5\n\nprint(\"Dado los valores x = 10 y y = 5\")\nprint(\"Suma: x + y = \" .. x + y)\nprint(\"Resta: x - y = \" .. x - y)\nprint(\"Multiplicación: x * y = \" .. x * y)\nprint(\"División: x / y = \" .. x / y)\nprint(\"Exponenciación: x ^ y = \" .. x ^ y)\nprint(\"Negación: -x = \" .. -x)\nprint(\"Módulo: x % 2 = \" .. x % 2)\n\n-- Operadores relacionales\n\nlocal a, b, c = 5, 10, 5\nprint(\"\\nDado los valores a = 5, b = 10, c = 5\")\nprint(\"Igualdad: a == c : \", a == c)\nprint(\"Negación de la igualdad: a ~= b :\", a ~= b)\nprint(\"a < b = \", a < b)\nprint(\"a > b = \", a > b)\nprint(\"a <= b = \", a <= b)\nprint(\"a >= b = \", a >= b)\n\n-- Operadores lógicos\n\nlocal m, n = true, false\nprint(\"\\nDado los valores m = true y n = false\")\nprint(\"m and n = \", m and n)\nprint(\"m or n = \", m or n)\nprint(\"not m = \", not m)\nprint(\"not n = \", not n)\n\n-- Estructuras de Control\n\nprint(\"\\nUso de if\")\n\nif a < 0 then a = 0 end\n\nif a < b then\n    print(a)\nelse\n    print(b)\nend\n\nlocal op = \"*\"\nlocal r\nif op == \"+\" then\n    r = a + b\n  elseif op == \"-\" then\n    r = a - b\n  elseif op == \"*\" then\n    r = a*b\n  elseif op == \"/\" then\n    r = a/b\n  else\n    error(\"Operación inválida\")\n  end\nprint(r)\n\nprint(\"\\nUso de while\")\n\nlocal arr = {1, 2, 3, 4, 5}\nlocal i = 1\nwhile arr[i] do\n    print(arr[i])\n    i = i + 1\nend\n\nprint(\"\\nUso de repeat\")\n\nlocal line\nrepeat\n    line = io.read()\nuntil line ~= \"\"\nprint(line)\n\nprint(\"\\nUso de for\")\nfor j = 10, 1, -1 do\n    print(j)\nend\n\nprint(\"\\nReto Extra\")\nfor j = 10, 55, 2 do\n    if j ~= 16 and j % 3 ~= 0 then\n        print(j)\n    end\nend\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/lua/santyjL.lua",
    "content": "--[[\n    /*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n]]\n\n--#region aritmetica\nlocal suma = 5 + 5\nlocal resta = 5 - 5\nlocal multiplicacion = 5 * 5\nlocal division = 5 / 5\n\nlocal modulo = 10 % 7\nlocal potencia = 5 ^ 5\n\nprint(\"suma : \", suma)\nprint(\"resta : \", resta)\nprint(\"multiplicacion : \", multiplicacion)\nprint(\"division : \", division)\nprint(\"modulo : \", modulo)\nprint(\"potencia : \", potencia)\n\n--#region Logicos\n\n-- and\nlocal and1 = true and true -- verdadero\nlocal and2 = true and false -- falso\nlocal and3 = false and true -- falso\nlocal and4 = false and false -- falso\n\nprint(\"and1 (true and true): \", and1)\nprint(\"and2 (true and false): \", and2)\nprint(\"and3 (false and true): \", and3)\nprint(\"and4 (false and false): \", and4)\n\n-- or\nlocal or1 = true or true -- verdadero\nlocal or2 = true or false -- verdadero\nlocal or3 = false or true -- verdadero\nlocal or4 = false or false -- falso\n\nprint(\"or1 (true or true): \", or1)\nprint(\"or2 (true or false): \", or2)\nprint(\"or3 (false or true): \", or3)\nprint(\"or4 (false or false): \", or4)\n\n-- not\nlocal not_true = not true -- falso\nlocal not_false = not false -- verdadero\n\nprint(\"not_true (not true): \", not_true)\nprint(\"not_false (not false): \", not_false)\n\n--#region comparacion\n\nlocal mayor = 5 > 6 -- falso\nlocal menor = 5 < 6 -- verdadero\nlocal igual = 5 == 6 -- falso\nlocal es_diferente = 5 ~= 6 -- verdadero\nlocal mayor_o_igual = 5 >= 6 -- falso\nlocal menor_o_igual = 5 <= 6 -- verdadero\n\nprint(\"mayor (5 > 6): \", mayor)\nprint(\"menor (5 < 6): \", menor)\nprint(\"igual (5 == 6): \", igual)\nprint(\"es_diferente (5 ~= 6): \", es_diferente)\nprint(\"mayor_o_igual (5 >= 6): \", mayor_o_igual)\nprint(\"menor_o_igual (5 <= 6): \", menor_o_igual)\n\n--#region asignacion\nsuma = suma + 4\nresta = resta - 4\nmultiplicacion = multiplicacion * 4\ndivision = division / 4\nmodulo = modulo % 4\npotencia = potencia ^ 4\n\nprint(\"nueva suma : \", suma)\nprint(\"nueva resta : \", resta)\nprint(\"nueva multiplicacion : \", multiplicacion)\nprint(\"nueva division : \", division)\nprint(\"nuevo modulo : \", modulo)\nprint(\"nueva potencia : \", potencia)\n\n--#region control de flujo\n\n--condiciones\nlocal edad = 14\n\nif edad > 18 and edad < 45 then -- si entonces\n    print(\"eres mayor de edad\")\n\nelseif edad > 45 then           -- si no si entonces\n    print(\"ya estas consado jefe \")\n\nelse\n    print(\"sos un pete\")\n\nend\n\n-- bucles for\nfor niveles= 1 , 10 do\n    print(\"nivel actual : \" , niveles)\n\nend\n\nfor niveles_x2 = 10 , 20 , 2 do\n    print(\"nivel actual : \" , niveles_x2)\n\nend --end para cerrar el bucle\n\n--bucle while\nlocal i = 1\n\nwhile i < 15 do\n    print(\"hi hitler\" , i)\n    i = i + 1\nend\n\n--#region Extra\n\nfor i = 10, 55, 2 do\n    if i ~= 16 and i % 3 ~= 0 then\n      print(i)\n    end\n  end\n\nprint(55)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/mojo/angelsanchezt.mojo",
    "content": "\"\"\"\n#01 OPERADORES Y ESTRUCTURAS DE CONTROL\nDificultad: Fácil | Publicación: 02/01/24 | Corrección: 08/01/24\n\nEJERCICIO:\n - Crea ejemplos de funciones básicas que representen las diferentes\n    posibilidades del lenguaje:\n    Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n  - Comprueba si puedes crear funciones dentro de funciones.\n  - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n  - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n  - Debes hacer print por consola del resultado de todos los ejemplos.\n    (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n \n  DIFICULTAD EXTRA (opcional):\n  Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n  - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n    - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n    - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n    - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n    - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n \n  Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n  Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n\"\"\"\n\n\"\"\"\nRun a Mojo file.\n1. Instalación del Mojo SDK \n  https://docs.modular.com/mojo/manual/get-started/\n\n2. Run a Mojo file.\n  mojo angelsanchezt.mojo\n\"\"\"\n\n\"\"\"\nOperadores\n\"\"\"\n\nfn main():\n    # Operadores ariméticos\n    let a = 10 # a es inmutable\n    let b = 3\n    \n    var z = a + b # z es mutable\n    print(\"Suma: \" + str(a) + \" + \" + str(b) + \" = \" + str(z))\n\n    z = a - b\n    print(\"Resta: \" + str(a) + \" - \" + str(b) + \" = \" + str(z))\n\n    z = a * b\n    print(\"Multiplicación: \" + str(a) + \" * \" + str(b) + \" = \" + str(z))\n\n    let w: Float64 = a / b\n    print(\"División: \" + str(a) + \" / \" + str(b) + \" = \" + str(w))\n    \n    z = a % b\n    print(\"Módulo: \" + str(a) + \" % \" + str(b) + \" = \" + str(z))\n\n    z = a ** b\n    print(\"Exponente: \" + str(a) + \" ** \" + str(b) + \" = \" + str(z))\n\n    z = a // b\n    print(\"División entera: \" + str(a) + \" // \" + str(b) + \" = \" + str(z))\n    \n    # Operadores de comparación\n    var resultado = a == b\n    print(\"Igualdad: \", str(a), \" == \", str(b), \" es \", str(resultado) )\n    \n    resultado = a != b\n    print(\"Desigualdad: \", str(a), \" != \", str(b), \" es \", str(resultado) )\n\n    resultado = a > b\n    print(\"Mayor que: \", str(a), \" > \", str(b), \" es \", str(resultado) )\n\n    resultado = a < b\n    print(\"Menor que: \", str(a), \" < \", str(b), \" es \", str(resultado) )\n\n    resultado = a >= b\n    print(\"Mayor o igual que: \", str(a), \" >= \", str(b), \" es \", str(resultado) )\n\n    resultado = a <= b\n    print(\"Menor o igual que: \", str(a), \" <= \", str(b), \" es \", str(resultado) )\n\n    # Operadores lógicos\n    resultado = (10 + 3 == 13) and (5 - 1 == 4)\n    print(\"AND &&: 10 + 3 == 13 and 5 - 1 == 4 es \", str(resultado))\n\n    resultado = (10 + 3 == 14) or (5 - 1 == 4)\n    print(\"OR ||: (10 + 3 == 14) or (5 - 1 == 4) es\", str(resultado))\n\n    resultado = not (10 + 3 == 14)\n    print(\"NOT !: not (10 + 3 == 14) es \", str(resultado))\n\n    # Operadores de asignación\n    var my_number = 11 # asignación\n    print(my_number)\n    my_number += 1  # suma y asignación\n    print(my_number)\n    my_number -= 1  # resta y asignación\n    print(my_number)\n    my_number *= 2  # multiplicación y asignación\n    print(my_number)\n    my_number /= 2  # división y asignación\n    print(my_number)\n    my_number %= 2  # módulo y asignación\n    print(my_number)\n    my_number **= 1  # exponente y asignación\n    print(my_number)\n    my_number //= 1  # división entera y asignación\n    print(my_number)\n\n    # Operadores de bit\n    let c = 10  # 1010\n    let d = 3  # 0011\n    print(\"AND: 10 & 3 = \", c & d)  # 0010\n    print(\"OR: 10 | 3 =\", c | d)  # 1011\n    print(\"XOR: 10 ^ 3 = \", 10 ^ 3)  # 1001\n    print(\"NOT: ~10 = \", ~10)\n    print(\"Desplazamiento a la derecha: 10 >> 2 = \", 10 >> 2)  # 0010\n    print(\"Desplazamiento a la izquierda: 10 << 2 = \", 10 << 2)  # 101000\n\n\n    \"\"\"\n    Estructuras de control\n    \"\"\"\n\n    # Condicionales\n\n    let my_string = \"Brais\"\n\n    if my_string == \"MoureDev\":\n        print(\"my_string es 'MoureDev'\")\n    elif my_string == \"Brais\":\n        print(\"my_string es 'Brais'\")\n    else:\n        print(\"my_string no es 'MoureDev' ni 'Brais'\")\n    \n    # Iterativas\n\n    for i in range(11):\n        print(i)\n\n    var i = 0\n    while i <= 10:\n      print(i)\n      i += 1\n\n    # Manejo de excepciones\n    try:\n        print(10 / 0)\n    except:\n        print(\"Se ha producido un error\")\n    finally:\n        print(\"Ha finalizado el manejo de excepciones\")\n\n  \n    \"\"\"\n    Extra\n    \"\"\"\n\n    for number in range(10, 56):\n        if number % 2 == 0 and number != 16 and number % 3 != 0:\n            print(number)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/mql4/confley.mq4",
    "content": "void OnStart() {\n    // TODO. OPERADORES DE MQL4\n    // Aritméticos \n    Print(\"Suma:            10 + 5 = \", 10 + 5); // 15\n    Print(\"Resta:           10 - 5 = \", 10 - 5); // 5\n    Print(\"Multiplicación:  10 * 5 = \", 10 * 5); // 50\n    Print(\"División:        10 / 5 = \", 10 / 5); // 2\n    Print(\"Módulo:          10 % 5 = \", 10 % 5); // 0\n    \n    // Asignación  \n    int a; \n    Print(\"Valor de 'a':                          \", a);      // a = 0 \n    Print(\"Asignación:                  a = 3  es \", a = 3);  // a = 3\n    Print(\"Suma y asignación:           a += 3 es \", a += 3); // a = 6\n    Print(\"Resta y asignación:          a -= 3 es \", a -= 3); // a = 3\n    Print(\"Multiplicación y asignación: a *= 3 es \", a *= 3); // a = 9\n    Print(\"División y asignación:       a /= 3 es \", a /= 3); // a = 3 \n    Print(\"Módulo y asignación:         a %= 3 es \", a %= 3); // a = 0\n    \n    // Comparasión \n    Print(\"Igualdad:        a == 10 es \", a == 10); // false\n    Print(\"Desigualdad:     a != 10 es \", a != 10); // true\n    Print(\"Mayor que:       a > 10  es \", a > 10);  // false \n    Print(\"Menor que:       a < 10  es \", a < 10);  // true\n    Print(\"Mayor o igual:   a >= 10 es \", a >= 10); // false \n    Print(\"Menor o igual:   a <= 10 es \", a <= 0);  // true\n    \n    // Lógicos \n    Print(\"AND &&: false && false  es \", false && false); // true\n    Print(\"OR  ||: true || flase   es \", true || false);  // true\n    Print(\"NOT  !: !true           es \", !true);          // false\n    \n    // Bit a Bit\n    // 5 -> 0101\n    // 3 -> 0011\n    Print(\"AND &: 5 & 3 es \", 5 & 3); // 0001 -> 1 \n    Print(\"OR  |: 5 | 3 es \", 5 | 3); // 0111 -> 7 \n    Print(\"XOR ^: 5 ^ 3 es \", 5 ^ 3); // 0110 -> 6\n    Print(\"NOT ~: ~ 5 es\", ~5);       // 1010 -> -6\n    Print(\"Desplazamiento izquierda <<: 5 << 1 es \", 5 << 1); // 1010 -> 10 \n    Print(\"Desplazamiento derecha >>: 5 >> 1 es \", 5 >> 1);   // 0010 -> 2 \n    \n    // Incremento y decremento \n    int i = 3; \n    i++; Print(\"Incremento: i++ es \", i); // 4\n    i--; Print(\"Decremento: i-- es \", i); // 3\n    \n    // Ternarios -> Forma abreviada de if \n    // '(condicional) ? [val_verdadero] : [val_falso]' \n    Print(\"Ternario: (i == 3) ? true : false -> \", i == 3 ? true : false);\n    \n    \n    \n    // TODO. ESTRUCTURAS DE CONTROL ===============================================================\n    // Condicionales \n    string var = \"mql4\"; \n    if (var == \"mql4\") { \n        Print(\"Variable es 'mql4'. \"); \n    } else if (var == \"texto\") { \n        Print(\"Variable no es 'mql4', pero es 'texto'. \"); \n    } else { \n        Print(\"Variable no es ningún caso. \"); \n    }\n    \n    int A = 6; \n    switch(A) {\n        case 0:\n            Print(\"La variable 'A' entra en el caso 1, donde vale 0. \"); \n            break; \n        case 3: \n            Print(\"La variable 'A' entra en el caso 2, donde vale 3. \"); \n            break; \n        case 6: \n            Print(\"La variable 'A' entra en el caso 2, donde vale 6. \"); \n            break; \n        default: \n            Print(\"La variable 'A' entra en el caso por defecto, donde no encontramos su valor. \"); \n            break; \n    }    \n    \n    \n    \n    // Bucles \n    int start = 0, stop = 10; \n    for (int j=start; j<=stop; j++) {\n        // Usamos j para saber el número de la iteración en la que vamos \n        Print(\"j vale \", j); \n    } \n    \n    // j = 11\n    while (j > start) {\n        j--; \n        Print(\"j vale \", j); \n    }\n    \n    // j = 0\n    do {\n        j++; \n        Print(\"j vale \", j); \n    } while (j == 1); \n    \n    \n    // En mql4 no hay manejo de excepciones :(\n    \n    Print(\"======================================\");\n    // TODO. EJERCICIO EXTRA \n    for(int c=10; c<=55; c+=2) {\n        if(c == 54) { Print(c+1); continue; } // ¿El 55 también se incluye o no? .-.  \n        if(c%3 == 0 || c == 16) continue;   // Se salta la iteración actual \n        Print(c); \n    }\n}\n\n//* OBSERVACIONES \n// - Para concatenar en print es con ' + ' o con ' , '. \n// - No se puede imprimir directamente el operador incremental ' c++ '. \n// - '' las comillas simples no se pueden poner en una impresión (print). \n// - En consola true / false se representa con 0 y 1. \n// - el switch solo funciona con datos enteros (int). "
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/nasm/evanz2608.s",
    "content": "; https://www.nasm.us/\n\n\n; ======================================================================================================================\n; Testeado en Arch linux. No lo he testeado en otras distribuciones.\n; Para ensamblar: nasm -f elf64 -o evanz1902.o evanz1902.s\n; Para linkear y generar el ejecutable: ld -o evanz1902 evanz1902.o -lc --dynamic-linker=/lib64/ld-linux-x86-64.so.2\n; ======================================================================================================================\n\n\n\nextern printf       ; Se usa para llamar a la función printf de libc.\n\n; ===========================================================================\n; Sección de código, con permisos de lectura y ejecución\n; ===========================================================================\nsection .text\nglobal _start\n\n\n_start:\n; IMPORTANTE:\n; Todas las instrucciones en ensamblador pueden recibir 0, 1, o 2 parametros, donde:\n;     instruccion destino, fuente\n; destino puede ser un registro o una direccion de memoria. (variable que se accede con [variable])\n; fuente puede ser un registro, una direccion de memoria o un valor inmediato\n; pero NO SE PUEDE usar dos direcciones de memoria como destino y fuente a la vez. Ej:\n;     mov qword [var_integer], qword [mi_float]\n; no está permitido.\n; Como se ve, cuando se accede a la memoria, se debe especificar el tamaño que se espera y deben coincidir los dos operandos. Ej\n; RAX es un registro de 64 bits (8 bytes), y cuando se escribe su valor en memoria, se usa qword [variable] para indicar que vamos a escribir 8 bytes.\n; EAX hace referencia a los primeros 32 bits (4 bytes) del registro rax, y se usaría dword [variable] para indicar que escribimos 4 bytes.\n\n\n\n\n; Operación de asignación. Para asignar un valor a una variable definida en la sección .data, usamos la instrucción mov\n  mov qword [var_integer], 10\n\n; imprimimos el valor en [var_integer]\n; para entender como se imprime por pantalla, le pasamos a printf los parametros que espera\n;   printf(const char* fmt, ...)\n; Para entender como se pasan parametros en ensamblador: https://www.ired.team/miscellaneous-reversing-forensics/windows-kernel-internals/linux-x64-calling-convention-stack-frame\n  lea rdi, [mask_string]\n  lea rsi, [int_string]\n  mov rdx, [var_integer]\n  xor rax, rax\n  call printf\n\n\n; Lo mismo que antes, pero usando un registro. Movemos 10 a rax, y luego escribimos en [var_integer] el valor en rax. (rax = 20 en este caso).\n  mov rax, 20\n  mov qword [var_integer], rax\n; y volvemos a imprimr el valor en [var_integer]\n  lea rdi, [mask_string]\n  lea rsi, [int_string]\n  mov rdx, [var_integer]\n  xor rax, rax\n  call printf\n\n\n; Operaciones aritmeticas. Usamos add para sumar, sub para restar, mul para multiplicar y div para dividir.\n  mov rax, 10                 ; rax = 10\n  mov qword [var_integer], 10  ; var_integer = 10\n  add qword [var_integer], rax ; Sumamos. El resultado se guarda en var_integer.\n\n; imprimimos en pantalla el resultado.\n  lea rdi, [mask_string]\n  lea rsi, [suma]\n  mov rdx, [var_integer] \n  xor rax, rax\n  call printf\n\n  sub qword [var_integer], 5 ; restamos 5 al resultado.\n; imprimimos en pantalla el resultado.\n  lea rdi, [mask_string]\n  lea rsi, [resta]\n  mov rdx, [var_integer] \n  xor rax, rax\n  call printf\n\n; Como dije antes, RAX es un registro de 64 bits, que está subdividido en registros más pequeños. Dejo una referencia: https://www.jamieweb.net/info/x86_64-general-purpose-registers-reference/\n\n; Tanto la instrucción MUL como DIV, trabajan de una manera un tanto particular:\n; El primer parametro se debe cargar en el registro RAX.\n; luego se llama a la instrucción con el segundo parametro, que puede ser un registro o un valor guardado en memoria.\n; El resultado se devuelve en RDX:RAX.\n; Al multiplicar, se puede dar el caso que el resultado sea tan grande que no entre en un solo registro, por lo que se usan dos registros para devolver el valor, de la siguiente forma:\n; RDX:RAX = resultado.\n; en RAX estan los primeros 64 bits del resultado (bits 0-63), y en RDX los siguientes (bits 64- 127). Si el resultado cabe en 64 bits, entonces RDX será 0 y el resultado estará en RAX.\n; Se pueden usar los registros de 32 bits también y siguen la misma regla, el resultado estará en EDX:EAX, aunque se debe tener en cuenta que en tal caso\n; se deberá usar un registro de 32 bits para el segundo operando también.\n\n  mov rax, 10\n  mov rbx, 3\n  mul rbx     ; rax * rbx. En este caso el resultado es RDX = 0, RAX = 30.\n; imprimimos en pantalla el resultado.\n  lea rdi, [mask_string]\n  lea rsi, [multiplicacion]\n  mov rdx, rax\n  xor rax, rax\n  call printf\n\n\n; En este caso utilizamos los registros de 32 bits. Se usa el registro ebx puesto que todos los parametros deben ser del mismo tamaño.\n  mov eax, 20\n  mov ebx, 10\n  mul ebx     ; eax * ebx. El resultado es EDX = 0, EAX = 200\n; imprimimos en pantalla el resultado.\n  lea rdi, [mask_string]\n  lea rsi, [multiplicacion]\n  mov rdx, rax\n  xor rax, rax\n  call printf\n\n\n; La división funciona de manera muy similar a MUL: Ya que se puede dar que el dividendo sea mas grande que el registro que vayamos a usar, se pasa\n; en los registros combinados RDX:RAX para 64 bits, EDX:EAX en 32 bits, y el divisor debe ser un registro del mismo tamaño, u un valor en memoria también del\n; mismo tamaño. El resultado se devuelve de la siguiente forma: RAX = cociente, RDX = resto.\n\n  mov rdx, 0    ; limpiamos rdx, de esta manera rdx:rax = 100\n  mov rax, 100\n  mov rbx, 12\n  div rbx       ; rax / rbx. El resultado es RAX = 8 (cociente), RDX = 4 (resto).\n; imprimimos en pantalla el resultado.\n  lea rdi, [mask_div]\n  mov rsi, rax\n  call printf\n\n  mov edx, 0    ; limpiamos edx, de esta manera rdx:rax = 100\n  mov eax, 200\n  mov ebx, 12\n  div ebx       ; eax / ebx. El resultado es EAX = 16 (cociente), EDX = 8 (resto).\n; imprimimos en pantalla el resultado.\n  lea rdi, [mask_div]\n  mov rsi, rax\n  call printf\n\n; Existen dos instrucciones más, imul e idiv. Ambas funcionan de la misma manera sólo que tienen en cuenta el signo de los operandos.\n; voy a poner un ejemplo sólo con idiv.\n\n  mov rdx, 0\n  mov rax, -100\n  mov rbx, 2\n  idiv rbx\n; imprimimos en pantalla el resultado.\n  lea rdi, [mask_div]\n  mov rsi, rax\n  call printf\n\n; Ahora, para trabajar con números decimales (float), se usa la fpu (floating point unit) del procesador.\n; La fpu tiene 8 registros: st0 - st7 que se comportan como un stack, con lo cual para cargar datos debemos hacer un \"push\"\n; en el siguiente ejemplo se explica con comentarios todo el codigo.\n; Vamos a usar qword para nuestras variables, o lo que es lo mismo, el tipo double de C/C++. Si usaramos dword, serían float de C/C++.\n; Existen varias instrucciones que operan en la fpu: fmul, fadd, fdiv, etc... Funcionan todas de manera muy similar\n; Ademas de la fpu, existen otros registros (xmm0 - xmm15) que se usan para el manejo de valores decimales y tenemos acceso a ellos de la misma manera\n; que accedemos a los registros de uso general.\n\n  fninit                    ; Inicializamos la fpu para evitar inconsistencias.\n  fld qword [var_float1]    ; Cargamos en st0 el valor de var_float1. Sólo se pueden cargar datos desde la memoria\n  fld qword [var_float2]    ; Cargamos en st0 el valor de var_float2. El valor de st0 se pasa a st1 y se carga en st0 el nuevo valor.\n  faddp                     ; (Add and pop) Suma st0 con st1. El resultado se guarda en st0 y st1 ahora queda vacío.\n  fstp qword [var_result]    ; Guarda el valor de st0 en var_result y hace un \"pop\", con lo cual ahora el stack de la fpu queda vacío.\n; imprimimos en pantalla el resultado.\n  movsd xmm0, [var_result]\n  lea rdi, [mask_float]\n  call printf\n\n\n; Operadores de comparación y condicionales:\n;\n; Referencia de todas las instrucciones de salto que hay: https://www.felixcloutier.com/x86/jcc\n;\n; Para comparaciones tenemos dos instrucciones: cmp y test. Son prácticamente iguales y se usan en conjunto con los saltos para \n; crear estructuras de control. cmp y test comparan dos valores, y modifican la flags del procesador, que luego usaremos para controlar el flujo\n; de ejecución con saltos condicionales. Hay que tener en cuenta que las operaciones aritméticas también modifican los flags y por lo tanto, a la hora de saltar,\n; hay que tener esto en cuenta, ya que se pueden usar las instrucciones de salto en conjunto con estas operaciones directamente sin usar cmp o test.\n; Para poder controlar donde vamos a continuar la ejecución debemos conocer la dirección de memoria donde esté la próxima instrucción que querramos ejecutar,\n; aunque sería muy engorroso tener que calcular esas direcciones a mano. Para eso usamos las etiquetas, o labels que podemos definir en cualquier parte de nuestro programa\n; y luego saltar a ellas. NASM calculará las direcciones cuando ensamblemos el programa y reemplazará las etiquetas con los offsets correspondientes.\n; Para declarar una etiqueta basta con escribir un nombre seguido de \":\". Esto definirá una etiqueta a la que podremos saltar desde cualquier lado de nuestro programa.\n;\n; Vamos a declarar algunas etiquetas y saltar a ellas como prueba.\n\n  mov rax, 20\n  mov rbx, 10\ncomparacion_rax_rbx:        ; definimos una etiqueta para volver a ella luego de las comparaciones\n  cmp rax, rbx              ; cmp hará una resta entre los operandos y modificará los flags del cpu acorde al resultado.\n  ja mayor                  ; ja = Jump if Above. En este caso, saltará a \"mayor\" sólo si rax es mayor que rbx. Existe también jae = Jump if Above or Equal.\n  je iguales                ; je = Jump if Equal. Este salto condicional saltará a la etiqueta \"iguales\" si rax y rbx son iguales.\n  jne distintos             ; jne = Jump if Not Equal. Este salto condicional saltará a la etiqueta \"distintos\" si rax y rbx son distintos.\n\n  jmp fin_de_saltos         ; jmp = Jump. Es una instrucción de salto incondicional, por lo que siempre saltará. En este caso, como en ensamblador las instrucciones\n                            ; ejecutan de manera secuencial, si no saltamos a \"fin_de_saltos\", el programa volvería a ejecutar el código que hay debajo, por lo que\n                            ; tenemos que saltarlo sí o sí para continuar nuestra ejecución. Es aquí donde se ve la utilidad de jmp.\n                            ; En este caso, nunca se ejecutará este salto, ya que lo vamos a hacer en \"distintos\", de lo contrario estaríamos en un bucle infinito ya que\n                            ; no existe forma de escapar de estas tres comparaciones a la vez, lo que muestra que hay que tener cuidado a la hora de hacer saltos sin\n                            ; tener en cuenta esta posibilidad.\n\n\ndistintos:                  ; Saltamos aquí cuando rax es distinto de rbx. Imprimimos un mensaje y preparamos rax y rbx para el próximo salto.\n  lea rdi, [mask_jumps]\n  lea rsi, [str_distintos]\n  call printf\n  jmp fin_de_saltos         ; Saltamos fuera de las comprobaciones, de lo contrario estaríamos en un bucle infinito.\n\niguales:                    ; Saltamos aquí cuando rax y rbx son iguales. Imprimimos un mensaje y preparamos rax y rbx para el próximo salto.\n  lea rdi, [mask_jumps]\n  lea rsi, [str_iguales]\n  call printf\n  mov rax, 10\n  mov rbx, 20\n  jmp comparacion_rax_rbx\n\nmayor:\n  lea rdi, [mask_jumps]\n  lea rsi, [str_mayor]\n  call printf\n  mov rax, 20\n  mov rbx, 20\n  jmp comparacion_rax_rbx\n\nfin_de_saltos:\n\n; Con estas instrucciones, podemos crear fácilmente ciclos del estilo while, do while, etc...\n; También podemos crear estructuras del estilo if (a == b), if (a == 0), if (a == b) else (), etc...\n; Las etiquetas se pueden definir en cualquier parte dentro de la sección .text y vamos a poder saltar a ellas\n; de manera que no es necesario que estén debajo del punto donde hacemos la comprobación.\n\n; ===================================\n; Ejercicio opcional\n; ===================================\n\n  lea rdi, [str_adicional]\n  call printf\n\n\n  mov byte [valor], 9    ; pongo [valor] en 9 porque lo primero que haré en bucle será incrementarlo.\nbucle:\n  add qword [valor], 1\n  cmp qword [valor], 55\n  je fin_de_bucle\n  jmp es_par\n\nimprimir:\n  lea rdi, [mask_int]\n  mov rsi, [valor]\n  call printf\n  jmp bucle\n\nes_16:\n  cmp qword [valor], 16\n  jne es_multiplo\n  jmp bucle\n\nes_multiplo:\n  mov rbx, 3\n  mov rdx, 0\n  mov rax, qword [valor]\n  div rbx\n  cmp rdx, 0\n  jne imprimir\n  jmp bucle\n\nes_par:\n  mov rbx, 2\n  mov rdx, 0\n  mov rax, qword [valor]\n  div rbx\n  cmp rdx, 0\n  je es_16\n  jmp bucle\n\nfin_de_bucle:\n  lea rdi, [mask_int]\n  mov rsi, [valor]\n  call printf\n  lea rdi, [mask_nl]\n  call printf\n  jmp exit_proc\n\n; Terminamos la ejecucion\nexit_proc:\n  mov rax, SYS_exit\n  xor rdi, rdi\n  syscall\n; ===========================================================================\n; Sección de datos inicializados con permisos de sólo lectura.\n; ===========================================================================\nsection .rodata\n  SYS_exit: equ 60\n  mask_string: db \"%s %u\", 10, 0\n  mask_div: db \"Division: cociente: %i - resto: %i\", 10, 0\n  mask_float: db \"Float: %.4f\", 10, 0\n  mask_jumps: db \"Comparacion: RAX es %s que RBX\", 10, 0\n  mask_rcx_zero: db \"Comparacion: RCX es igual a 0\"\n  mask_int: db \"%u - \", 0\n  mask_nl: db 0x0A\n\n  int_string: db \"var_integer:\", 0\n  suma: db \"Suma:\", 0\n  resta: db \"Resta:\", 0\n  multiplicacion: db \"Multiplicacion:\", 0\n  str_distintos: db \"distinto\", 0\n  str_iguales: db \"igual\", 0\n  str_mayor: db \"mayor que\", 0\n  str_mayor_igual: db \"mayor o igual\", 0\n  str_menor: db \"menor\", 0\n  str_menor_igual: db \"menor o igual\", 0\n  str_zero: db \"es igual a 0\", 0\n  str_not_zero: db \"es distinto de 0\", 0\n\n  str_adicional: db 0x0A, 0x0A, 0x0A, \"Ejercicio adicional\", 0x0A, 0\n\n\n; ===========================================================================\n; Sección de datos inicializados con permisos de lectura y escritura.\n;   No existe en ensamblador el concepto de tipo de datos, sólo son bytes que\n;   reservamos para su uso.\n;   \n; ===========================================================================\nsection .data\n  var_integer: dq 0\n  var_float1: dq 100.0\n  var_float2: dq 200.0\n  valor: dq 0\n\n; ===========================================================================\n; Sección de datos no inicializados con permisos de lectura y escritura.\n;   Aplica lo mismo que para la sección .data, solo que la memoria que usemos\n;   en esta sección no va a ser inicializada y va a contener datos basura\n;   hasta que escribamos en ella.\n; ===========================================================================\nsection .bss\n  var_result: resq 1\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/ocaml/luishendrix92.ml",
    "content": "type person =\n  { age : int\n  ; name : string\n  }\n\n(* In OCaml, operators are functions (unary, and binary) that can be passed\n   around and returned from other functions just like any other. Also, we\n   can define our own infix operator (binary operators that stand in\n   between two arguments) as long as they don't collide with existing ones. *)\n\nlet bar_bouncer person =\n  let blacklist = [ \"Bob Smith\"; \"Jane Doe\"; \"Spongebob\" ] in\n  (* OCaml's logical operators [|||] and [&&] work as expected.\n     Same as the built-in comparisons [>=], [<=], etc. *)\n  person.age >= 18 && not (List.mem person.name blacklist)\n;;\n\n(* Example of the pipe operator [|>], which applies argument A to (potentially\n   partialy-applied) a function B. It can be chained to assemble a pipeline. *)\nprint_endline \"Welcome to Sr.Frog's Bar!\";\n[ { name = \"Luis Lopez\"; age = 31 }\n; { name = \"Spongebob\"; age = 25 }\n; { name = \"Jane Doe\"; age = 60 }\n; { name = \"Homer Simpson\"; age = 56 }\n]\n|> List.filter bar_bouncer\n|> List.iter (fun person ->\n  Printf.printf \"- %s of age %d\\n\" person.name person.age)\n\n(* Operators can be used as curried functions for simplicity. *)\nlet sum_list nums = List.fold_left ( + ) 0 nums\nlet list_product nums = List.fold_left ( * ) 1 nums;;\n\n(* The [=] operator can act as assignment and equality comparison which is\n   confusing to beginners, but you get used to it with time. Also, in\n   OCaml, the [if/else] {b control flow structure} is an expression and\n   the [elseif] construct doesn't exist but it looks like it does due to\n   associativity working in our favour. This means the following:\n\n   {[\n     if COND1 then BRANCH1 else if COND2 then BRANCH2 else BRANCH3\n   ]}\n\n   and this next one with parenthesis:\n\n   {[\n     if COND1 then BRANCH1 else (if COND2 then BRANCH2 else BRANCH3)\n   ]}\n\n   are both equivalent expressions, interesting isn't it? *)\nlet sky = \"green\" in\nif sky = \"blue\"\nthen print_endline \"\\nThe sky is clear and blue today :)\"\nelse if sky = \"dark\"\nthen print_endline \"\\nIt's night time :O\"\nelse print_endline \"\\nThe sky has an unknown color!\"\n\n(* Another interesting tidbit of OCaml is that there are separate operators\n   for integers and floating point numbers. For [int], we have the usual\n   [+], [-], [/], and [*] but they only work if both their arguments are of\n   type [int]. For [float] we have [+.], [-.], [/.], and [*.] which is just\n   the same operators with a dot at the end. Don't forget that floating point\n   numbers must also have a dot after them even if they don't have decimals. *)\nlet int_arithmetics = 45 + (15 * 10) - int_of_float 0.5\nlet float_arithmetics = (12. -. float_of_int 42 +. 99.99) /. -23.33;;\n\n(* String concatenation is possible, but the operator is a bit uncommon. *)\nlet book = \"At \" ^ \"the mountains\" ^ \" of madness\" in\nPrintf.printf \"%s is a cosmic horror story.\\n\" book\n\n(* OCaml also has bitwise operators, mod (modulo), and more! *)\nlet bitwise = 12 land 45 lor 0 lxor (lnot 1 lsl 20 lsr 3)\nlet list_append = 5 :: [ 4; 3; 2; 1; 0 ]\nlet list concat = [ 'A'; 'B'; 'C' ] @ [ 'D'; 'E'; 'F' ]\n\n(* [<>] and [!=] are similar except for the way they check for equality. *)\nlet is_odd n = n mod 2 <> 0\nlet is_pair n = n mod 2 = 0\n\n(* Despite being a functional langauge, OCaml has a for loop construct\n   as procedural alternative for recursion. This is an iterative control\n   structure that has been simplified to work with a range of integers\n   specified in the form of [A to B] where B is inclusive. Note that this\n   block expression returns a unit [()] type so it must be followed with a\n   [;] if the intention is to return something else. *)\nlet array_max arr =\n  let len = Array.length arr in\n  (* [match PATTERN with] is a powerful pattern-matching control structure\n     featured in many functional languages such as Elixir and Kotlin.\n     Not only does it allow to match against destructured containers and\n     primitive values; it also binds variables to use in each branch. *)\n  match len with\n  | 0 -> raise (Failure \"array_max: Array is empty\")\n  | 1 -> arr.(0)\n  | _ ->\n    let max_value : 'a ref = ref arr.(0) in\n    for i = 1 to len - 1 do\n      if arr.(i) > !max_value then max_value := arr.(i)\n    done;\n    !max_value\n;;\n\nlet arr = [| 5; 0; -99; 12; 3 |] in\nPrintf.printf \"Maximum value of 'arr' is %d\\n\" (array_max arr)\n\ntype action =\n  | Introduce of person\n  | Compare of person * person\n  | BarrelRoll\n\n(* Pattern matching can also be used for the last function parameter. *)\nlet dispatcher = function\n  | Introduce { name; age } ->\n    Printf.printf \"Hi, I'm %s, %d years old.\\n\" name age\n  | Compare (a, b) ->\n    let status =\n      if a.age = b.age\n      then \"the same age as\"\n      else if a.age > b.age\n      then \"older than\"\n      else \"younger than\"\n    in\n    Printf.printf \"%s is %s %s.\\n\" a.name status b.name\n  | BarrelRoll -> print_endline \"Do a barrel roll *rolls around*\"\n;;\n\ndispatcher (Introduce { name = \"John Doe\"; age = 48 });\n(* Surprisingly, while loops are also available. *)\nRandom.self_init ();\nlet trapped_in_simulation : bool ref = ref true in\nwhile !trapped_in_simulation do\n  print_endline \"I'm trapped in a simulation :(\";\n  trapped_in_simulation := Random.bool ()\ndone;\nprint_endline \"I escaped from a simulation :)\"\n\n(* Exceptions in OCaml are encouraged when there is no way to recover from an\n   error, usually produced by external forces such as an user doing something\n   incorrectly, a failed network or system call, etc. Sometimes they are also\n   useful for handling failure in imperative code and then transform the\n   {b failure} into a [None] optional type, or the {b success} into a [Some];\n   though [Result] also exists, mostly used in network calls. *)\nlet count_file_lines filename =\n  let lines =\n    try In_channel.open_bin filename |> In_channel.input_lines with\n    | Sys_error _ -> []\n  in\n  List.length lines |> Printf.printf \"'%s' | %d lines were read.\\n\" filename\n;;\n\ncount_file_lines \"non_existant_file.txt\";\ncount_file_lines \"luishendrix92.ml\"\n\n(** [extra_challenge] is a function that prints all pair numbers within a\n    range of [a] to [b] (inclusive) excluding [16] and mutliples of [3]. *)\nlet extra_challenge a b =\n  let is_good_number n = is_pair n && n mod 3 <> 0 && n <> 16 in\n  for n = a to b do\n    if is_good_number n then print_endline (string_of_int n)\n  done;\n  (* It can also be written in a functional style with lazy sequences. *)\n  Seq.ints a\n  |> Seq.take (b - a + 1)\n  |> Seq.filter is_good_number\n  |> Seq.map string_of_int\n  |> Seq.iter print_endline\n;;\n\nextra_challenge 10 55\n\n(* Running the script produces the following output:\n\n   {@plain[\n     Welcome to Sr.Frog's Bar!\n     - Luis Lopez of age 31\n     - Homer Simpson of age 56\n\n     The sky has an unknown color!\n     At the mountains of madness is a cosmic horror story.\n     Maximum value of 'arr' is 12\n     Hi, I'm John Doe, 48 years old.\n     I'm trapped in a simulation :(\n     I'm trapped in a simulation :(\n     I'm trapped in a simulation :(\n     I'm trapped in a simulation :(\n     I escaped from a simulation :)\n     'non_existant_file.txt' | 0 lines were read.\n     'luishendrix92.ml' | 226 lines were read.\n     10\n     14\n     20\n     22\n     26\n     28\n     32\n     34\n     38\n     40\n     44\n     46\n     50\n     52\n     10\n     14\n     20\n     22\n     26\n     28\n     32\n     34\n     38\n     40\n     44\n     46\n     50\n     52\n   ]}\n\n   If you have OCaml installed on your machine, try running this\n   script file with [ocaml luishendrix92.ml] or using {b [utop]}\n   which will give you aceess to its defined functions and types:\n\n   {[\n     #use \"luishendrix92.ml\";;\n   ]}\n*)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/pascal/edalmava.pas",
    "content": "program Operadores;\nuses Crt, Math;\ntype\n    dias = (Domingo, Lunes, Martes, Miercoles, Jueves, Viernes, Sabado);\nvar\n    x, y, I : Integer;\n    cad1, cad2 : String;\n    c : Char;\n    d : dias;\n\nbegin\n    ClrScr;\n    WriteLn('Operador de asignacion := ');\n    WriteLn('x := 5  -> 5 se asigna a x');\n    WriteLn('y := 10 -> 10 se asigna a y');\n    x := 5;\n    y := 10;\n    WriteLn('');\n    WriteLn('Operadores Aritmeticos Binarios');\n    WriteLn('Suma: x + y = ', x + y);\n    WriteLn('Resta: y - x = ', y - x);\n    WriteLn('Multiplicacion: x * y = ', x * y);\n    WriteLn('Exponenciacion: y ** x = ', y ** x);      // Para usar el operador ** se debe agregar la unidad Math\n    WriteLn('Division: x / y = ', (x / y):2:2);\n    WriteLn('Division Entera: x Div y = ', x Div y);\n    WriteLn('Modulo: y mod 2 = ', y mod 2);\n    WriteLn('');\n    WriteLn('Operadores Aritmeticos Unarios');\n    x := +7;\n    y := -7;\n    Writeln('+ especifica que el valor es positivo: +', x);\n    WriteLn('- especifica que el valor es negativo: ', y);\n    WriteLn('');\n    WriteLn('Operadores Relacionales');\n    WriteLn('Igual: 5 = 5 se evalua a ', 5 = 5);\n    WriteLn('No Igual: 5 <> 4 se evalua a ', 5 <> 4);\n    WriteLn('Menor que: 20 < 20 se evalua a ', 20 < 20);\n    WriteLn('Menor o igual que: 20 <= 20 se evalua a ', 20 <= 20);\n    WriteLn('Mayor que: 20 > 10 se evalua a ', 20 > 10);\n    WriteLn('Mayor o igual que: 20 >= 20 se evalua a ', 20 >= 20);\n    WriteLn('');\n    WriteLn('Operadores Booleanos');\n    WriteLn('Negacion not: not true se evalua a ', not true);\n    WriteLn('Negacion not: not false se evalua a ', not false);\n    WriteLn('Y logico: true and true se avalua a ', true and true);\n    WriteLn('O logico: true or false se evalua a ', true or false);\n    WriteLn('XOR logico: false xor false se evalua a ', false xor false);\n    WriteLn('');\n    WriteLn('Operador de Concatenacion de Cadenas +');\n    cad1 := 'Hola ';\n    cad2 := 'Pascal';\n    WriteLn('Cadena 1: ', cad1);\n    WriteLn('Cadena 2: ', cad2);\n    Writeln('Concatenando Cadena 1 + Cadena2: ', cad1 + cad2);\n    WriteLn('');\n    WriteLn('Operadores de Conjuntos (Set) - Se tratan en el ejercicio #18 sobre conjuntos');\n    WriteLn('');\n    WriteLn('Estructuras de Control');\n    WriteLn('Sentencia Case');\n    c := 'b';\n    Case c of\n        'a' : WriteLn('Se selecciono a');\n        'b' : WriteLn('Se selecciono b');\n        'c' : WriteLn('Se selecciono c');\n    else\n        Writeln('Opcion seleccionada invalida');\n    end;\n    WriteLn('Sentencia if .. then .. else');\n    d := Lunes;\n    Write('Lunes es: ');\n    If d in [Lunes..Viernes] then\n        Write('Dia de trabajo')\n    else\n        Write('Dia de descanso');\n    WriteLn('');\n    WriteLn('');\n    WriteLn('Sentencia for..to/downto..do');\n    for I := 1 to 5 do\n        WriteLn(I ** 2);\n    for I := 5 downto 1 do\n        WriteLn(I);\n    WriteLn('');\n\n    WriteLn('*****RETO EXTRA*****');\n    for I := 10 to 55 do\n    begin\n        If (I mod 2 = 0) and (I <> 16) and (I mod 3 <> 0) then\n            WriteLn(I);\n    end;\nend.\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/pascal/miguelex.pas",
    "content": "program miguelex;\n\nuses sysutils;\n\nvar\n  a, b: integer;\n  x: real;\n  bool1, bool2: Boolean;\n  \nbegin\n    { Asignación }\n    writeln('Ejemplo de asignacion');\n    a := 5;\n    x := a;\n    writeln('Mostramos el valor de a, que la teniamos declarada como entero => ', a);\n    writeln('Mostramos el valor de x, que la teniamos declarada como real y le hemos asigando el valor de a => ', x);\n    WriteLn('Notese como se añaden los decimales a la variable real');\n\n    { Aritméticos }\n    writeln('Ejemplo de operadores aritmeticos');\n    a := 5;\n    b := 2;\n    writeln('Mostramos el valor de a => ', a);\n    writeln('Mostramos el valor de b => ', b);\n    writeln('Suma de a + b => ', a + b);\n    writeln('Resta de a - b => ', a - b);\n    writeln('Multiplicacion de a * b => ', a * b);\n    writeln('Division de a / b => ', a / b);\n    writeln('Modulo de a mod b => ', a mod b);\n    \n    { Relacionales }\n    writeln('Ejemplo de operadores relacionales');\n    a := 5;\n    b := 2;\n    writeln('Mostramos el valor de a => ', a);\n    writeln('Mostramos el valor de b => ', b);\n    writeln('a > b => ', a > b);  \n    writeln('a < b => ', a < b);\n    writeln('a >= b => ', a >= b);\n    writeln('a <= b => ', a <= b);\n    writeln('a = b => ', a = b);\n    writeln('a <> b => ', a <> b);\n    \n    { Lógicos }\n    writeln('Ejemplo de operadores logicos');\n    bool1 := True;\n    bool2 := False;\n    writeln('Mostramos el valor de a => ', bool1);\n    writeln('Mostramos el valor de b => ', bool2);\n    writeln('bool1 and bool2 => ', bool1 and bool2);\n    writeln('bool1 or bool2 => ', bool1 or bool2);\n    writeln('not bool1 => ', not bool1);\n    writeln('not bool2 => ', not bool2);\n    \n  { Ejemplo de try catch }\n  try\n    writeln('Ejemplo de try catch');\n    writeln('Mostramos el valor de a => ', a);\n    writeln('Mostramos el valor de b => ', b);\n    writeln('a div b => ', a div b);\n  except\n    on E: EDivByZero do\n      writeln('Error: ', E.Message);\n  end;\n  \n  { Ejemplo de if }\n  writeln('Ejemplo de if');\n  if a > b then\n    writeln('a es mayor que b')\n  else\n    writeln('a es menor que b');\n    \n  { Ejemplo de case }\n  writeln('Ejemplo de case');\n  case a of\n    1: writeln('a vale 1');\n    2: writeln('a vale 2');\n    3: writeln('a vale 3');\n    4: writeln('a vale 4');\n    5: writeln('a vale 5');\n    6: writeln('a vale 6');\n    7: writeln('a vale 7');\n    8: writeln('a vale 8');\n    9: writeln('a vale 9');\n    10: writeln('a vale 10');\n  end;\n  \n  { Ejemplo de for }\n  writeln('Ejemplo de for');\n  for a := 1 to 10 do\n    writeln('a vale ', a);\n    \n  { Ejemplo de while }\n  writeln('Ejemplo de while');\n  a := 1;\n  while a <= 10 do\n  begin\n    writeln('a vale ', a);\n    a := a + 1;\n  end;\n  \n  { Ejemplo de repeat }\n  writeln('Ejemplo de repeat');\n  a := 1;\n  repeat\n    writeln('a vale ', a);\n    a := a + 1;\n  until a > 10;\n  \n  { Ejemplo de break }\n  writeln('Ejemplo de break');\n  for a := 1 to 10 do\n  begin\n    writeln('a vale ', a);\n    if a = 5 then\n      break;\n  end;\n  \n  { Ejemplo de continue }\n  writeln('Ejemplo de continue');\n  for a := 1 to 10 do\n  begin\n    if a = 5 then\n      continue;\n    writeln('a vale ', a);\n  end;\n  \n  { Extra }\n  writeln('Ejemplo extra');\n  for a := 10 to 55 do\n  begin\n    if (a mod 2 = 0) and (a <> 16) and (a mod 3 <> 0) then\n      writeln(a);\n  end;\n    \nend."
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/php/BertoMP.php",
    "content": "<?php\n\n// OPERADORES ARITMÉTICOS\necho \"OPERADORES ARITMÉTICOS<br/>\";\n$firstNumber = 7;\n$secondNumber = 2;\n$result = 0;\n\n// Operador suma (+)\n$result = $firstNumber + $secondNumber;\necho \"La suma de $firstNumber + $secondNumber es $result<br />\";\n\n// Operador resta (-)\n$result = $firstNumber - $secondNumber;\necho \"La resta de $firstNumber - $secondNumber es $result<br />\";\n\n// Operador multiplicación (*)\n$result = $firstNumber * $secondNumber;\necho \"La multiplicación de $firstNumber * $secondNumber es $result<br />\";\n\n// Operador división (/)\n$result = $firstNumber / $secondNumber;\necho \"La división de $firstNumber / $secondNumber es $result<br />\";\n\n// Operador módulo (%)\n$result = $firstNumber % $secondNumber;\necho \"El resto de la división de $firstNumber / $secondNumber es $result<br />\";\n\n// OPERADORES LÓGICOS\necho \"<br />OPERADORES LÓGICOS<br />\";\n$firstBool = true;\n$secondBool = false;\n\n// Operador lógico AND (&&)\n$logicAnd = ($firstBool && $secondBool);\necho \"AND lógico: $logicAnd<br />\";\n\n// Operador lógico OR (||)\n$logicOr = ($firstBool || $secondBool);\necho \"OR lógico: $logicOr<br />\";\n\n// Operador lógico NOT (!)\n$logicNot = !$firstBool;\necho \"NOT lógico: $logicNot<br />\";\n\n// OPERADORES DE COMPARACIÓN\necho \"<br />OPERADORES DE COMPARACIÓN<br />\";\n// Operador mayor que (>)\n$greatThan = (5 > 10);\necho \"¿Es 5 mayor que 10? -> $greatThan<br />\";\n\n// Operador menor que (<)\n$lessThan = (5 < 10);\necho \"¿Es 5 menor que 10? -> $lessThan<br />\";\n\n// Operador mayor o igual que (>=)\n$greatOrEqual = (5 >= 10);\necho \"¿Es 5 mayor o igual que 10? -> $greatOrEqual<br />\";\n\n// Operador menor o igual que (<=)\n$lessOrEqual = (5 <= 10);\necho \"¿Es 5 menor o igual que 10? -> $lessOrEqual<br />\";\n\n// OPERADORES DE ASIGNACIÓN\necho \"<br />OPERADORES DE ASIGNACIÓN<br />\";\n// Operador de asignación simple (=)\n$number = 10;\necho \"Valor asignado: $number<br />\";\n\n// Operador de suma y asignación (+=)\n$number += 5; // 10 + 5 = 15\necho \"Valor del resultado de suma y asignación: $number<br />\";\n\n// Operador de resta y asignación (-=)\n$number -= 5; // 15 - 5 = 10\necho \"Valor del resultado de resta y asignación: $number<br />\";\n\n// Operador de multiplicación y asignación (*=)\n$number *= 5; // 10 * 5 = 50\necho \"Valor del resultado de multiplicación y asignación: $number<br />\";\n\n// Operador de división y asignación (/=)\n$number /= 5; // 50 / 5 = 10\necho \"Valor del resultado de división y asignación: $number<br />\";\n\n// Operador de módulo y asignación (%=)\n$number %= 5; // 10 % 5 = 0\necho \"Valor del resultado de módulo y asignación: $number<br />\";\n\n// OPERADORES DE IDENTIDAD\necho \"<br />OPERADORES DE IDENTIDAD<br />\";\n// Operador de igualdad estricta\n$strictEqualComp = (5 === 5);\necho \"¿Es 5 estrictamente igual a 5? -> $strictEqualComp<br />\";\n\n// Operador de desigualdad estricta (!==)\n$strictDiffComp = ('5' !== '5');\necho \"¿Es '5' estrictamente diferente a '5'? -> $strictDiffComp<br />\";\n\n// OPERADORES DE PERTENENCIA\necho \"<br />OPERADORES DE PERTENENCIA<br />\";\n$intArray = [1, 12, 5, 643, 3];\n$firstCheck = in_array(3, $intArray); // Devolverá true\n$secondCheck = in_array(65, $intArray); // Devolverá false\n\necho \"¿Está el número 3 en el array de números? -> \";\necho $firstCheck ? \"true<br />\" : \"false<br />\";\necho \"¿Está el número 65 en el array de números? -> \";\necho $secondCheck ? \"true<br />\" : \"false<br />\";\n\n// OPERADORES DE BITS\necho \"<br />OPERADORES DE BITS<br />\";\n$firstBit = 5; // Representación binaria: 0000 0101\n$secondBit = 3; // Representación binaria: 0000 0011\n\n// Operador AND a nivel de bits (&)\n$bitAnd = $firstBit & $secondBit; // Devuelve 1 (representación binaria: 0000 0001)\necho \"Resultado AND bit a bit -> $bitAnd<br />\";\n\n// Operador OR a nivel de bits (|)\n$bitOr = $firstBit | $secondBit; // Devuelve 7 (representación binaria: 0000 0111)\necho \"Resultado OR bit a bit -> $bitOr<br />\";\n\n// Operador XOR a nivel de bits (^)\n$bitXor = $firstBit ^ $secondBit; // Devuelve 6 (representación binaria: 0000 0110)\necho \"Resultado OR bit a bit -> $bitXor<br />\";\n\n// Operador NOT a nivel de bits (~)\n$bitNot = ~$firstBit; // Devuelve -6 (representación binaria: 1111 1010)\necho \"Resultado NOT bit a bit -> $bitNot<br />\";\n\n// Operador de desplazamiento hacia la derecha (>>)\n$toRightBit = $firstBit >> 1; // Devuelve 2 (representación binaria: 0000 0010)\necho \"Desplazamiento hacia la derecha -> $toRightBit<br />\";\n\n// Operador de desplazamiento hacia la izquierda (<<)\n$toLeftBit = $firstBit << 1; // Devuelve 10 (representación binaria: 0000 1010)\necho \"Desplazamiento hacia la izquierda -> $toLeftBit<br />\";\n\n// ESTRUCTURAS DE CONTROL CONDICIONAL\necho \"<br />ESTRUCTURAS DE CONTROL CONDICIONAL<br />\";\n// if-else\necho \"if-else<br />\";\n$num = 10;\n\nif ($num > 0) {\n    echo \"El número es positivo.<br />\";\n} else if ($num === 0) {\n    echo \"El número es cero.<br />\";\n} else {\n    echo \"El número es negativo.<br />\";\n}\n\n// Operador ternario\necho \"<br />Operador ternario<br />\";\necho ($num > 0) ? \"El número es positivo.<br />\" : \"El número es cero o negativo.<br />\";\n\n// switch-case\necho \"<br />Switch-Case<br />\";\n$option = 1;\n\nswitch ($option) {\n    case 1:\n        echo \"Se ha seleccionado la opción 1.<br />\";\n        break;\n    case 2:\n        echo \"Se ha seleccionado la opción 2.<br />\";\n        break;\n    default:\n        echo \"Opción por defecto.<br />\";\n        break;\n}\n\n// ESTRUCTURAS DE CONTROL ITERATIVAS\necho \"<br />ESTRUCTURAS DE CONTROL ITERATIVAS<br />\";\n// while\necho \"Bucle While<br />\";\n$counter = 0;\nwhile ($counter < 5) {\n    echo \"Iteración: $counter<br />\";\n    $counter++;\n}\n\n// do-while\necho \"<br />Bucle do-while<br />\";\n$counter = 0;\ndo {\n    echo \"Iteración: $counter<br />\";\n    $counter++;\n} while ($counter < 5);\n\n// for\necho \"<br />Bucle for<br />\";\nfor ($counter = 0; $counter < 5; $counter++) {\n    echo \"Iteración: $counter<br />\";\n}\n\n// for ... each\necho \"<br />Bucle for ... each<br />\";\n$arrNumbers = [1, 2, 5, 2, 7, 9];\nforeach ($arrNumbers as $number) {\n    echo \"Número -> $number<br />\";\n}\n\n// for ... in (Simulación)\necho \"<br />Bucle for ... in (Simulación)<br />\";\n$persona = ['name' => 'Alberto', 'age' => 33];\nforeach ($persona as $key => $value) {\n    echo \"$key -> $value<br />\";\n}\n\n// MANEJO DE EXCEPCIONES\necho \"<br />MANEJO DE EXCEPCIONES<br />\";\necho \"Bloque try-catch<br />\";\n$errNumber = 10;\n\ntry {\n    if ($errNumber === 10) {\n        throw new Exception('El número es igual a 10.');\n    }\n    echo \"El número es distinto de 10.<br />\";\n} catch (Exception $error) {\n    echo \"Se ha producido un error debido a -> {$error->getMessage()}<br />\";\n}\n\necho \"<br />Bloque try-catch-finally<br />\";\ntry {\n    if ($errNumber === 10) {\n        throw new Exception('El número es igual a 10.');\n    }\n    echo \"El número es distinto de 10.<br />\";\n} catch (Exception $error) {\n    echo \"Se ha producido un error debido a -> {$error->getMessage()}<br />\";\n} finally {\n    echo \"Bloque finally. Esto siempre se ejecuta haya o no excepción.<br />\";\n}\n\n// DIFICULTAD EXTRA\necho \"<br />EJERCICIO EXTRA<br />\";\n/*  Crea un programa que imprima por consola todos los números comprendidos entre 10 y 55 (incluidos), pares, y\n *  que no son ni el 16 ni múltiplos de 3.*/\nfor ($i = 10; $i <= 55; $i++) {\n    if (($i % 2 === 0) && ($i !== 16) && ($i % 3 !== 0)) {\n        echo \"Iteración: $i<br />\";\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/php/CeciliaPorras01.php",
    "content": "<?php\n\n\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n\n//Operadores aritméticos\n\nprint (\"Suma: 5 + 2 = \" . (5 + 2));\nprint (\"Resta: 5 - 2 = \" . (5 - 2));\nprint (\"Multiplicación: 5 * 2 = \" . (5 * 2));\nprint (\"División: 5 / 2 = \" . (5 / 2));\nprint (\"Módulo: 5 % 2 = \" . (5 % 2));\nprint (\"Exponenciación: 5 ** 2 = \" . (5 ** 2));\nprint (\"División entera: 5 // 2 = \" . (ROUND(5 / 2)));\n\n//Operadores de comparación\n\nprint(\"Igualdad: 5 == 2 = \" . (5 == 2));\nprint(\"Desigualdad: 5 != 2 = \" . (5 != 2));\nprint(\"Mayor que: 5 > 2 = \" . (5 > 2));\nprint(\"Menor que: 5 < 2 = \" . (5 < 2));\nprint(\"Mayor o igual que: 5 >= 2 = \" . (5 >= 2));\nprint (\"Menor o igual que: 5 <= 2 = \" . (5 <= 2));\n\n//Operadores lógicos\n\nprint(\"AND: 5 == 5 && 2 == 2 = \" . (5 == 5 && 2 == 2));\nprint(\"OR: 5 == 5 || 2 == 3 = \" . (5 == 5 || 2 == 3));\nprint(\"NOT: !(5 == 5) = \" . !(5 == 5));\n\n//Operadores de asignación\n\n$variable = 5;\nprint(\"Asignación: variable = 5 = \" . $variable);\n$variable += 2;\nprint(\"Suma: variable += 2 = \" . $variable);\n$variable -= 2;\nprint(\"Resta: variable -= 2 = \" . $variable);\n$variable *= 2;\nprint(\"Multiplicación: variable *= 2 = \" . $variable);\n$variable /= 2;\nprint(\"División: variable /= 2 = \" . $variable);\n$variable %= 2;\nprint(\"Módulo: variable %= 2 = \" . $variable);\n$variable **= 2;\nprint(\"Exponenciación: variable **= 2 = \" . $variable);\n\n//Operadores de identidad\n$number = 5;\nprint ($number is $my_number);\n\n\n//Operadores de pertenencia\n$numbers = array(1, 2, 3, 4, 5);\nprint (3 in $numbers);\n\n//Operadores de bits\nprint(\"AND: 5 & 2 = \" . (5 & 2));\nprint(\"OR: 5 | 2 = \" . (5 | 2));\nprint(\"XOR: 5 ^ 2 = \" . (5 ^ 2));\nprint(\"Desplazamiento a la izquierda: 5 << 2 = \" . (5 << 2));\nprint(\"Desplazamiento a la derecha: 5 >> 2 = \" . (5 >> 2));\nprint(\"Negación: ~5 = \" . (~5));\n\n\n//Estructura de control \n\n//condicional\n$number = 5;\nif($number == 5){\n    print(\"El número es 5\");\n} else {\n    print(\"El número no es 5\");\n}\n\n$string = \"Hola\";\n\nswitch($string){\n    case \"Hola\":\n        print(\"Hola\");\n        break;\n    case \"Adiós\":\n        print(\"Adiós\");\n        break;\n    default:\n        print(\"No es ni Hola ni Adiós\");\n}\n\n//iterativa\nfor($i = 10; $i <= 55; $i++){\n    if($i % 2 == 0 && $i != 16 && $i % 3 != 0){\n        print($i);\n    }\n}\n\n//Manejador de excepciones\ntry {\n    if (0 == 0) {\n        throw new Exception(\"División por cero\");\n    }\n    print (10 / 0);\n} catch (Exception $e) {\n    print($e->getMessage());\n}\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/php/DanielBelenguer.php",
    "content": "<?php\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n$var_a = 10;\n$var_b = 15;\n$var_a_bool = true;\n$var_b_bool = false;\n\n// Aritméticos\n\necho (+$var_a) . \"\\n\";\necho (-$var_a) . \"\\n\";\necho ($var_a + $var_b) . \"\\n\";\necho ($var_a - $var_b) . \"\\n\";\necho ($var_a * $var_b) . \"\\n\";\necho ($var_a / $var_b) . \"\\n\";\necho ($var_a % $var_b) . \"\\n\";\necho ($var_a ** $var_b) . \"\\n\";\n\n//Incremento y decremento\n\necho ($var_a++) . \"\\n\"; // Muestra 10 y luego incrementa en 1.\necho (++$var_a) . \"/n\"; // Incrementa en 1 y luego muestra 12.\necho ($var_a--) . \"\\n\"; // Muestra 12 y luego decrementa en 1.\necho (--$var_a) . \"\\n\"; // Decrementa en 1 y luego muestra 10.\n\n// Lógicos\n\necho ($var_a_bool and $var_b_bool) . \"\\n\"; // Es false porque tienen que se las dos true para que sea true. La variable $var_b_bool es false.\necho ($var_a_bool && $var_b_bool) . \"\\n\"; // Equivalente a la anterior.\necho ($var_a_bool or $var_b_bool) . \"\\n\"; // Es true porque con que una de las dos sea true, el resultado es true.\necho ($var_a_bool || $var_b_bool) . \"\\n\"; // Equivalente a la anterior.\necho ($var_a_bool xor $var_b_bool) . \"\\n\"; // Es true porque solo una de las dos es true.\necho (!$var_a_bool) . \"\\n\"; // Es false porque la variable $var_a_bool es true.\n\n// Comparación\n\necho ($var_a == $var_b) . \"\\n\"; // Es false porque $var_a es 10 y $var_b es 15.\necho ($var_a === $var_b) . \"\\n\"; // Es false porque $var_a es 10 y $var_b es 15. Con triple igual se compara el valor y el tipo.\necho ($var_a != $var_b) . \"\\n\"; // Es true porque $var_a es 10 y $var_b es 15. Son diferentes.\necho ($var_a !== $var_b) . \"\\n\"; // Es true porque $var_a es 10 y $var_b es 15. Son diferentes y de diferente tipo.\necho ($var_a < $var_b) . \"\\n\"; // Es true porque $var_a es menor que $var_b.\necho ($var_a > $var_b) . \"\\n\"; // Es false porque $var_a es menor que $var_b.\necho ($var_a <= $var_b) . \"\\n\"; // Es true porque $var_a es menor que $var_b.\necho ($var_a >= $var_b) . \"\\n\"; // Es false porque $var_a es menor que $var_b.\n\n// Asignación\n\necho ($var_a = 50) . \"\\n\"; // Asigna 50 a $var_a y devuelve 50.\necho ($var_a += $var_b) . \"\\n\"; // Suma $var_b a $var_a y devuelve 65.\n\n$var_string = \"¡Hola\";\n$var_string .= \" Mundo\"; // Concatena \" Mundo\" a $var_string.\n$var_string .= \"!\"; // Concatena \"!\" a $var_string.\necho $var_string . \"\\n\";\n\n//Operadores de ejecución\n\n$output = `ls -al`;\necho \"<pre>$output</pre>\"; // Ejecuta el comando ls -al y muestra el resultado.\n\n// If\nif ($var_a > $var_b) {\n    echo \"a es mayor de b\";\n}\n// Else\nif ($var_a < $var_b) {\n    echo \"b es mayor de a\";\n}else {\n    echo \"a es mayor de b\";\n}\n\n// Elseif / else if\nif ($var_a > $var_b) {\n    echo \"a es mayor de b\";\n} elseif ($var_a < $var_b) {\n    echo \"b es mayor de a\";\n} else {\n    echo \"a y b son iguales\";\n}\n\n// Switch\nswitch ($var_a) {\n    case 1:\n        echo \"a es 1\";\n        break;\n    case 2:\n        echo \"a es 2\";\n        break;\n    default:\n        echo \"a no es ni 1 ni 2\";\n}\n\n// While\n\n$i = 0;\nwhile ($i < 10) {\n    echo $i . \"\\n\";\n    $i++;\n} // Esto hace una cuenta de 0 al 9.\n\n// Do while\n// Esta estructura es igual que el while, pero se ejecuta al menos una vez. Yo la suelo utilizar para hacer los menus interativos.\ndo {\n    echo $i . \"\\n\";\n    $i--;\n} while ($i > 0); // Esto hace una cuenta de 10 al 1.\n\n// For\n\nfor ($i = 0; $i < 10; $i++) {\n    echo $i . \"\\n\";\n} // Esto hace una cuenta de 0 al 9.\n\n// Foreach\n$array = [1, 2, 3, 4, 5];\nforeach ($array as $value) {\n    echo $value . \"\\n\";\n} // Esto muestra los valores del array.\n\n// Dificultad extra\n\n/*Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n*/\n\nfor ($i = 10; $i <= 55; $i++) {\n    if ($i % 2 == 0 and $i != 16 and $i % 3 != 0) {\n        echo $i . \"\\n\";\n    }\n}\n\n\n\n\n?>"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/php/GitHjuan.php",
    "content": "# #01 OPERADORES Y ESTRUCTURAS DE CONTROL\n\nEJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n<?php\n\necho \"Operadores Aritméticos: \";\necho \"<br/>\";\n\necho \"Suma: 10 + 7 = \"  . 10 + 7 , \"<br/>\"; \necho \"Resta: 10 - 7 = \"  . 10 - 7, \"<br/>\";\necho \"Multiplicacion: 10 * 7 = \"  . 10 * 7, \"<br/>\";\necho \"Division: 10 / 2 = \"  . 10 / 2, \"<br/>\"; \necho \"Módulo: 10 % 2 = \"  . 10 % 2, \"<br/>\"; \necho \"Exponentes: 10 ** 7 = \"  . 10 ** 2, \"<br/>\";\n\necho \"<br/>\";\necho \"Operadores Logicos: \";\necho \"<br/>\";\n\n$edad = 18;\n$nombre = \"Enrique\";\n\necho \"AND - &&\";\necho \"<br/>\"; //salto de linea\n\nif ($edad >= 18 && $nombre === \"Enrique\"){\n\techo \"Los datos coinciden\";\n}else {\n\techo \"los datos no coinciden\";\n}\n\necho \"<br/>\"; //salto de linea\n\necho \"OR - ||\";\n\necho \"<br/>\"; //salto de linea\n\nif ($edad != 17 || $nombre !== \"Enrique\"){\n\techo \"Los datos no son correctos\";\n}else {\n\techo \"Los datos son correctos\";\n}\necho \"<br/>\"; //salto de linea\n$n1 = 10;\n$n2 = 11;\n\necho \"<br/>\"; //salto de linea\n\n//OPERADORES DE COMPARACION \n\n\nif (\"Juan\" == \"Juan\") echo \"Los dato son iguales <br/>\"; //igualdad\nif (22 === 22) echo \"Los datos son identicos <br/>\"; //Identico\nif (22 != \"22\") echo \"Los datos no son diferentes <br/>\"; //Diferentes\nif (22 > 20) echo \"22 es mayor que 20 <br/>\"; //Mayor que \nif (22 < 23) echo \"22 es menor que 23 <br/>\"; //Menor que\nif (22 >= 20) echo \"22 es mayor o igual que 20 <br/>\"; //Mayor o igual que\nif (22 <= 23) echo \"22 es menor o igual que 23\". \"<br/>\"; //Menor o igual que\n echo \"Operador de nave espacial (11 <=> 12): \". (11 <=> 12). \"<br/>\"; //Es -1 cuando el valor de la derecha es mayor que el de la izquierda\n echo \"Operador de nave espacial (12 <=> 12): \". (12 <=> 12). \"<br/>\"; //Es 0 cuando los dos valores son iguales\n echo \"Operador de nave espacial (13 <=> 12): \". (13 <=> 12). \"<br/>\"; //Es 1 cuando el valor de la izquierda es mayor\n\n\n $vocales = \"'wa'\";\n $vocal = \" es una vocal\";\n\n switch($vocales){\n case \"a\":\n \techo $vocales. $vocal;\n \tbreak;\n case \"e\":\n \techo $vocales. $vocal;\n \tbreak;\n case \"i\":\n \techo $vocales. $vocal;\n \tbreak;\n \tcase \"o\":\n \techo $vocales. $vocal;\n \tbreak;\n \tcase \"u\":\n \techo $vocales. $vocal;\n \tbreak;\n default:\n echo  $vocales. \" no es una vocal\";\n break;\n}\n\necho \"<br/>\";\n\n // Asignacion\necho $numero = 5;\necho \"<br/>\";\n\n//Operadores de incremento/decremento\necho \"<br/>\";\necho \"Pos-incremento\" . $numero++ . \"<br/>\";\necho \"Pos-decremento\" . $numero-- . \"<br/>\";\necho \"Pre-incremento\" . ++$numero . \"<br/>\";\necho \"Pre-decremento\" . --$numero . \"<br/>\";\necho $numero += 1; //Suma y asignacion\necho \"<br/>\";\necho $numero -= 1;// Resta y asignacion \necho \"<br/>\";\necho $numero *= 2;//Multiplicacion y asignacion \necho \"<br/>\";\necho $numero /= 2;// Division y Asignacion \necho \"<br/>\";\n\n//------------String\n$string = \"Hola\";\n$string .= \" PHP\";\necho $string;\t\n\n//---------Estructuras de Control\n//-----------Condicionales\necho \"Condicion 'IF'\";\necho \"<br/>\";\n\n$user = \"gitjuan\";\n\nif($user == \"gitjuan\"){\n\techo \"El usuario es correcto\";\n}else if($user == \"gitjose\"){\n\techo \"el 2 usuario es correcto\";\n}else{\n\techo \"El usuario es incorrecto\";\n}\n\n//-----------Operadores de iteración\n//-----------Bucles\necho \"<br/>\";\necho \"Ciclo For\";\necho \"<br/>\";\n//-----------Ciclo for\nfor($i = 10 ; $i <= 100 ; $i += 5){\n\techo $i . ',';\n};\n\necho \"<br/>\";\necho \"Ciclo while\";\necho \"<br/>\";\n$numero = 2;\n//-----------Ciclo While\nwhile($numero <= 20){\n\techo $numero . '<br/>';\n\t$numero++;\n}\n\necho \"<br/>\";\necho \"Ciclo DoWhile\";\necho \"<br/>\";\n\n//------------Ciclo Dowhile\n$n = 10;\ndo { \n\techo $n . '<br/>';\n\t$n += 2;\n}while ($n <= 50);\n\necho \"<br/>\";\necho \"Ciclo foreach\";\necho \"<br/>\";\n\n//-----------Ciclo Foreach\n$array = array (\"a\", \"e\", \"i\", \"o\", \"u\");\n\nforeach ($array as $vocal){\n\t\techo  $vocal . '<br/>';\n}\n\n/* - DIFICULTAD EXTRA (opcional):\n    Crea un programa que imprima por consola todos los números comprendidos\n    entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3. */\n\n    echo \"<br/>\";\n\techo \"DIFICULTAD EXTRA\";\n\techo \"<br/>\";\n\n     for ($i = 10 ; $i <= 55 ; $i++){\n     \tif($i % 2 === 0 && $i !== 16 && $i % 3 !== 0 ){\n     \techo $i . '<br/>';\n     }\n     }"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/php/H4cker0n.php",
    "content": "<?php\n /* OPERADORES ARITMETICOS */\n\n $a = 40;\n $b = 55;\n\n echo \"Suma de $a y $b: \" . ($a + $b) . \"\\n\"; // Suma\n echo \"Resta de $a y $b: \" . ($a - $b) . \"\\n\"; // Resta\n echo \"Multiplicación de $a y $b: \" . ($a * $b) . \"\\n\"; // Multiplicación   \n echo \"División de $a y $b: \" . ($a / $b) . \"\\n\"; // División    \necho \"Módulo de $a y $b: \" . ($a % $b) . \"\\n\"; // Módulo    \necho \"Exponente de $a y $b: \" . ($a ** $b) . \"\\n\"; // Exponente\necho \"Incremento de $a: \" . (++$a) . \"\\n\"; // Incremento        \necho \"Decremento de $b: \" . (--$b) . \"\\n\"; // Decremento\n    \n/* OPERADORES DE ASIGNACION */\n\n$c = 25;\necho \"Asignación de $c: \" . $c . \"\\n\"; // Asignación\n$c += 5;\necho \"Asignación con suma de $c: \" . $c . \"\\n\"; // Asignación con suma\n$c -= 10;\necho \"Asignación con resta de $c: \" . $c . \"\\n\"; // Asignación con resta\n$c *= 2;\necho \"Asignación con multiplicación de $c: \" . $c . \"\\n\"; // Asignación con multiplicación\n$c /= 5;\necho \"Asignación con división de $c: \" . $c . \"\\n\"; // Asignación con división\n$c %= 3;\necho \"Asignación con módulo de $c: \" . $c . \"\\n\"; // Asignación con módulo\n$c **= 2;\necho \"Asignación con exponente de $c: \" . $c . \"\\n\"; // Asignación con exponente\n\n/* OPERADORES DE COMPARACION */\n$d = 10;    \n$e = 20;\necho \"Igualdad de $d y $e: \" . ($d == $e ? 'Verdadero' : 'Falso') . \"\\n\"; // Igualdad   \necho \"Desigualdad de $d y $e: \" . ($d != $e ? 'Verdadero' : 'Falso') . \"\\n\"; // Desigualdad\necho \"Identidad de $d y $e: \" . ($d === $e ? 'Verdadero' : 'Falso') . \"\\n\"; // Identidad\necho \"No identidad de $d y $e: \" . ($d !== $e ? 'Verdadero' : 'Falso') . \"\\n\"; // No identidad\necho \"Mayor que $d y $e: \" . ($d > $e ? 'Verdadero' : 'Falso') . \"\\n\"; // Mayor que\necho \"Menor que $d y $e: \" . ($d < $e ? 'Verdadero' : 'Falso') . \"\\n\"; // Menor que\necho \"Mayor o igual que $d y $e: \" . ($d >= $e ? 'Verdadero' : 'Falso') . \"\\n\"; // Mayor o igual que\necho \"Menor o igual que $d y $e: \" . ($d <= $e ? 'Verdadero' : 'Falso') . \"\\n\"; // Menor o igual que\n\n/* OPERADORES LOGICOS */\n$f = true;\n$g = false;\necho \"AND lógico de $f y $g: \" . ($f && $g ? 'Verdadero' : 'Falso') . \"\\n\"; // AND lógico\necho \"OR lógico de $f y $g: \" . ($f || $g ? 'Verdadero' : 'Falso') . \"\\n\"; // OR lógico\necho \"NOT lógico de $f: \" . (!$f ? 'Verdadero' : 'Falso') . \"\\n\"; // NOT lógico\n\n/* OPERADORES DE IDENTIDAD */\n$h = \"10\";  \n$i = 10;\necho \"Identidad de tipo y valor de $h y $i: \" . ($h === $i ? 'Verdadero' : 'Falso') . \"\\n\"; // Identidad\necho \"No identidad de tipo y valor de $h y $i: \" . ($h !== $i ? 'Verdadero' : 'Falso') . \"\\n\"; // No identidad\n\n/* OPERADORES DE PERTENENCIA */\n$array = array(1, 2, 3, 4, 5);  \necho \"El 3 está en el array: \" . (in_array(3, $array) ? 'Verdadero' : 'Falso') . \"\\n\"; // Pertenencia\necho \"El 6 no está en el array: \" . (!in_array(6, $array) ? 'Verdadero' : 'Falso') . \"\\n\"; // No pertenencia\n\n/* OPERADORES DE BIT */ \n$j = 5; // 0101 en binario\n$k = 3; // 0011 en binario  \necho \"AND bit a bit de $j y $k: \" . ($j & $k) . \"\\n\"; // AND bit a bit\necho \"OR bit a bit de $j y $k: \" . ($j | $k) . \"\\n\"; // OR bit a bit\necho \"XOR bit a bit de $j y $k: \" . ($j ^ $k) . \"\\n\"; // XOR bit a bit\necho \"Desplazamiento a la izquierda de $j: \" . ($j << 1) . \"\\n\"; // Desplazamiento a la izquierda\necho \"Desplazamiento a la derecha de $k: \" . ($k >> 1) . \"\\n\"; // Desplazamiento a la derecha\n\n/* OPERADORES DE TERNARIO */\n$condicion = true;\necho \"Operador ternario: \" . ($condicion ? 'Condición verdadera' : 'Condición falsa') . \"\\n\"; // Ternario\n\n/* ESTRUCTURAS DE CONTROL */\nif ($a > $b) {\n    echo \"$a es mayor que $b\\n\"; // Estructura if\n} elseif ($a < $b) {\n    echo \"$a es menor que $b\\n\"; // Estructura elseif\n} else {\n    echo \"$a es igual a $b\\n\"; // Estructura else\n}\nswitch ($a) {\n    case 40:\n        echo \"$a es igual a 40\\n\"; // Estructura switch\n        break;\n    case 50:\n        echo \"$a es igual a 50\\n\"; // Estructura switch\n        break;\n    default:\n        echo \"$a no es ni 40 ni 50\\n\"; // Estructura default\n}\n\nfor ($i = 0; $i < 5; $i++) {\n    echo \"Iteración $i del bucle for\\n\"; // Bucle for\n}   \nwhile ($i < 5) {\n    echo \"Iteración $i del bucle while\\n\"; // Bucle while\n    $i++;\n}\ndo {\n    echo \"Iteración $i del bucle do-while\\n\"; // Bucle do-while\n    $i++;\n} while ($i < 10);\nforeach ($array as $valor) {\n    echo \"Valor del array: $valor\\n\"; // Bucle foreach\n}\n\n// EJERCICIO EXTRA */\n\nfor ($i = 10; $i <= 55; $i++) {\n    // 1. Verificar si es par\n    if ($i % 2 === 0) {\n        // 2. Verificar si no es 16\n        if ($i !== 16) {\n            // 3. Verificar si no es múltiplo de 3\n            if ($i % 3 !== 0) {\n                echo $i . \"\\n\";\n            }\n        }\n    }\n}\necho \"\\n\";\n\n\n?>\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/php/Hugovrc.php",
    "content": "<?php\n\n$numero1 = 10;\n$numero2 = 5;\n$resultado = 0;\n// Operadores Aritmeticos\n\n//suma\necho \"----suma----\\n\";\n$resultado = $numero1 + $numero2;\necho $numero1. \" + \" .$numero2. \" = \" .$resultado. \"\\n\"; \n//resta\necho \"----resta----\\n\";\n$resultado = $numero1 - $numero2;\necho $numero1. \" - \" .$numero2. \" = \" .$resultado. \"\\n\";\n//multiplicacion\necho \"----multiplicacion----\\n\";\n$resultado = $numero1 * $numero2;\necho $numero1. \" * \" .$numero2. \" = \" .$resultado. \"\\n\";\n//division\necho \"----division----\\n\";\n$resultado = $numero1 / $numero2;\necho $numero1. \" / \" .$numero2. \" = \" .$resultado. \"\\n\";\n//modulo\necho \"----modulo----\\n\";\n$resultado = $numero1 % $numero2;\necho $numero1. \" % \" .$numero2. \" = \" .$resultado. \"\\n\";\n//exponenciacion\necho \"----exponenciacion----\\n\";\n$resultado = $numero1 ** $numero2;\necho $numero1. \" ** \" .$numero2. \" = \" .$resultado. \"\\n\";\n\n//Operadores de asignación\n$numero3 = 4;\n\n//Operadores de comparación\n//igual\n$numero1 == $numero2;\n//identico\n$numero1 === $numero2;\n//diferente\n$numero1 != $numero2;\n$numero1 <> $numero2;\n//no identico\n$numero1 !== $numero2;\n//menor que\n$numero1 < $numero2;\n//mayor que\n$numero1 > $numero2;\n//menor o igual que\n$numero1 <= $numero2;\n//mayor o igual que\n$numero1 >= $numero2;\n\n//Operadores de incremento/decremento\n//pre-incremento\n++$numero1. \"\\n\"; //incrementa $numero1 en 1 y luego retorna $numero1.\n//post-incremento\n$numero2++. \"\\n\"; //retorna $numero2, y luego incrementa $numero2 en 1.\n//pre-decremento\n--$numero1. \"\\n\"; //Decrementa $numero1 en uno, luego retorna $numero1.\n//post-decremento\n$numero2++. \"\\n\"; //Retorna $numero2, luego decrementa $numero2 en uno.\n\n//Operadores lógicos\n// And\n$numero1 and $numero2; //verdadero si tanto $numero1 como $numero2 son verdaderos.\n$numero1 && $numero2;\n// Or\n$numero1 or $numero2; //verdadero si cualquiera de $numero1 o $numero2 es verdadero.\n$numero1 || $numero2;\n// Xor\n$numero1 xor $numero2; //verdadero si $numero1 o $numero2 es verdadero, pero no ambos.\n// Not\n!$numero1; //verdadero si $numero1 no es true.\n\n//Estructuras de Control\n//Condicionales\n\n//If\necho \"----if----\\n\";\nif ($numero1 > $numero2) {\n    echo $numero1. \" es mayor que \" .$numero2. \"\\n\"; \n}\n//else\necho \"----else----\\n\";\nif ($numero1 < $numero2) {\n    echo $numero1. \" es menor que \" .$numero2. \"\\n\";\n} else {\n    echo $numero1. \" es mayor que \" .$numero2. \"\\n\";\n}\n//elseif\necho \"----elseif----\\n\";\nif ($numero1 < $numero2) {\n    echo $numero1. \" es menor que \" .$numero2. \"\\n\";\n} elseif ($numero1 == $numero2) {\n    echo $numero1. \" es igual que \" .$numero2. \"\\n\";\n} else {\n    echo $numero1. \" es mayor que \" .$numero2. \"\\n\";\n}\n\n//switch\necho \"----switch----\\n\";\n$fruta = \"manzana\";\nswitch ($fruta) {\n    case \"naranja\":\n        echo \"la fruta es una naranja\\n\";\n        break;\n    case \"manzana\":\n        echo \"la fruta es una manzana\\n\";\n        break;\n    case \"limon\":\n        echo \"la fruta es un lima\\n\";\n        break;\n}\n\n//Iterativas\n//while\necho \"----while----\\n\";\n$numero4 = 1;\nwhile ($numero4 <= 10) {\n    echo $numero4++. \"\\n\";\n}\n\n//do-while\necho \"----do-while----\\n\";\n$numero4 = 0;\ndo {\n    echo $numero4. \"\\n\";\n    $numero4++;\n} while ($numero4 <= 5);\n\n//for\necho \"----for----\\n\";\nfor ($numero4 = 1; $numero4 <= 10; $numero4++) {\n    echo $numero4. \"\\n\";\n}\n\n//foreach\necho \"----foreach----\\n\";\n$array = array(1,2,10,9);\nforeach ($array as &$valor) {\n    echo $valor. \"\\n\";\n}\n\n//excepciones\necho \"----try catch----\\n\";\necho \"----division por 0----\\n\";\n$a = 10;\n$b = 0;\ntry {\n    if ($b === 0) {\n        throw new Exception(\"no se admiten divisiones por 0\");\n    }\n    echo $a / $b;\n} catch (Exception $e) {\n    echo \"ha habido una excepcion: \" .$e->getMessage(). \"\\n\";\n}\n\necho \"----Dificultad extra----\\n\";\nfor ($numero = 10; $numero <= 55; $numero++) {\n    if ($numero % 2 == 0 and $numero != 16 and $numero % 3 != 0) {\n        echo $numero. \"\\n\";\n    }\n}\n?>"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/php/Jeyker-Dev.php",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n <?php\n$suma_1 = 10;\n$suma_2 = 10;\n\n$resultado_suma = $suma_1 + $suma_2; //Operador +\n\n$resta_1 = 5;\n$resta_2 = 3;\n\n$resultado_resta = $resta_1 - $resta_2; //Operador -\n\n$multiplicacion_1 = 5;\n$multiplicacion_2 = 3;\n\n$resultado_multiplicacion = $multiplicacion_1 * $multiplicacion_2; //Operador *\n\n$division_1 = 5;    \n$division_2 = 3;\n\n$resultado_division = $division_1 / $division_2; //Operador /\n\n$modulo_1 = 5;\n$resultado_modulo = $modulo_1 % 3; //Operador %\n\n$incremento_1 = 5;\n$resultado_incremento = $incremento_1++; //Operador ++\n\n$decremento_1 = 5;\n$resultado_decremento = $decremento_1--; //Operador --\n\n\necho $resultado_suma.\"\\n\";\n\necho $resultado_resta.\"\\n\";\n\necho $resultado_multiplicacion.\"\\n\";\n\necho $resultado_division.\"\\n\";\n\necho $resultado_modulo.\"\\n\";\n\necho $resultado_incremento.\"\\n\";\n\necho $resultado_decremento.\"\\n\";\n\n$esteno = 16;\n\nfor($i = 10; $i <= 55; $i++)\n{\n    if($i === $esteno)\n    {\n        continue;\n    }\n    if( $i % 3 == 0 )\n    {\n        continue;\n    }\n    echo $i.\"\\n\";\n}   // Here End For\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/php/NightAlchemist.php",
    "content": "<?php\n\n$valor1 = 15;\n$valor2 = 35;\n\n# OPERADORES ARITMETICOS\necho $valor1 + $valor2 . \"\\n\";  // Suma\necho $valor1 - $valor2 . \"\\n\";  // Resta\necho $valor1 * $valor2 . \"\\n\";  // Multiplicación\necho $valor1 / $valor2 . \"\\n\";  // División\necho $valor1 % $valor2 . \"\\n\";  // Módulo\necho $valor1 ** $valor2 . \"\\n\"; // Exponenciación\n\n# OPERADORES LOGICOS\nif( \"Danielle\" == \"Danielle\" && 30 == 30 ) echo \"Ambos condicionales son Verdaderos\\n\"; // And\nif( \"Danielle\" == \"Danielle\" || 20 == 30 ) echo \"Uno de los 2 condicionales es Verdadero\\n\"; // Or\nif( \"Danielle\" == \"Danielle\" xor 20 == 30 ) echo \"Uno de los 2 condicionales es Verdadero\\n\"; // Xor\nif( \"Danielle\" != \"Danielle\" ) echo \"El condicional es Falso\\n\"; // Not\n\n# OPERADORES DE COMPARACION\nif( 30 == 30 ) echo \"Los datos son iguales\\n\"; // Igual\nif( 30 === 30 ) echo \"Los datos son idénticos\\n\"; // Identico\nif( 30 != 40 ) echo \"Los datos no son iguales\\n\"; // No igual\nif( 30 !== 40 ) echo \"Los datos no son idénticos\\n\"; // No identico\nif( 30 < 40 ) echo \"30 es menor a 40\\n\"; // Menor que\nif( 30 <= 30 ) echo \"30 es menor o igual a 30\\n\"; // Menor o igual\nif( 40 > 30 ) echo \"40 es mayor a 30\\n\"; // Mayor que\nif( 40 >= 40 ) echo \"40 es mayor o igual a 40\\n\"; // Mayor o igual\n\n# OPERADORES DE ASIGNACION\n$valor1 += $valor2; // Suma\n$valor1 -= $valor2; // Resta\n$valor1 *= $valor2; // Multiplicación\n$valor1 /= $valor2; // División\n$valor1 %= $valor2; // Módulo\n$valor1 **= $valor2; // Exponenciación\n\n# OPERADORES DE IDENTIDAD\nif( 30 === 30 ) echo \"Los datos son idénticos\\n\"; // Identico\nif( 30 !== 40 ) echo \"Los datos no son idénticos\\n\"; // No identico\n\n# OPERADORES DE PERTENENCIA\n$frutas = array(\"Manzana\", \"Pera\", \"Uva\");\nif( in_array(\"Manzana\", $frutas) ) echo \"La fruta existe\\n\"; // Incluido\nif( !in_array(\"Banano\", $frutas) ) echo \"La fruta no existe\\n\"; // No incluido\n\n# OPERADORES DE BITS\n$valor1 = 30;\n$valor2 = 40;\necho $valor1 & $valor2 . \"\\n\"; // And\necho $valor1 | $valor2 . \"\\n\"; // Or\necho $valor1 ^ $valor2 . \"\\n\"; // Xor\necho ~$valor1 . \"\\n\"; // Not\necho $valor1 << $valor2 . \"\\n\"; // Desplazamiento a la izquierda\necho $valor1 >> $valor2 . \"\\n\"; // Desplazamiento a la derecha\n\n# ESTRUCTURAS DE CONTROL\n\n// Estructura de control condicional\n\n//Estructura de control IF - ELSE\n$edad = 18;\nif($edad >= 18) {\n  echo \"Eres mayor de edad\\n\";\n} else {\n  echo \"Eres menor de edad\\n\";\n}\n\n// Estructura de control ELSE IF\n$hora = 12;\nif($hora < 12) {\n  echo \"Buenos días\\n\";\n} else if($hora < 20 || $hora == 12) {\n  echo \"Buenas tardes\\n\";\n} else {\n  echo \"Buenas noches\\n\";\n}\n\n// Estructura de control condicional switch\n$dia = 7;\nswitch($dia) {\n  case 1:\n      echo \"Es lunes\\n\";\n      break;\n  case 2:\n      echo \"Es martes\\n\";\n      break;\n  case 3:\n      echo \"Es miércoles\\n\";\n      break;\n  case 4:\n      echo \"Es jueves\\n\";\n      break;\n  case 5:\n      echo \"Es viernes\\n\";\n      break;\n  default:\n      echo \"Es fin de semana\\n\";\n};\n\n// Operador ternario\n$edad = 18;\necho ($edad >= 18) ? \"Eres mayor de edad\\n\" : \"Eres menor de edad\\n\";\n\n// Estructura de control Iterativa\n\n// Estructura de control FOR\n$asistencia_clase = 10;\nfor($i = 0; $i < $asistencia_clase; $i++) {\n  echo \"Asistieron a clase $i alumnos.\\n\";\n}\n\n// Estructura de control WHILE\n$numero = 10;\nwhile($numero <= 55) {\n  if($numero != 16 && $numero % 3 != 0) {\n    echo $numero . \"\\n\";\n  }\n  $numero++;\n}\n\n// Estructura de control DO WHILE\n$numero = 10;\ndo {\n  if($numero != 16 && $numero % 3 != 0) {\n    echo $numero . \"\\n\";\n  }\n  $numero++;\n} while($numero <= 55);\n\n// Estructura de control FOREACH\n$frutas = array(\"Manzana\", \"Pera\", \"Uva\");\nforeach($frutas as $fruta) {\n  echo $fruta . \"\\n\";\n}\n\n// Estructura de control de excepciones\n\n// Estructura de control de excepciones try - catch\ntry {\n  throw new Exception(\"Error en la aplicación\");\n} catch(Exception $e) {\n  echo $e->getMessage() . \"\\n\";\n}\n\n// Estructura de control de excepciones try - catch - finally\ntry {\n  throw new Exception(\"Error en la aplicación\");\n} catch(Exception $e) {\n  echo $e->getMessage() . \"\\n\";\n} finally {\n  echo \"Finalizando la aplicación\\n\";\n}\n\n\n/* \n* DIFICULTAD EXTRA (opcional):\n* Crea un programa que imprima por consola todos los números comprendidos\n* entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n*/\nfor($i = 10; $i <= 55; $i++) {\n  if($i % 2 == 0 && $i != 16 && $i % 3 != 0) {\n    echo $i . \"\\n\";\n  }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/php/adrs1166ma.php",
    "content": "<?php\n\n/*\n* EJERCICIO:\n* - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n*   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n*   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n* - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n*   que representen todos los tipos de estructuras de control que existan\n*   en tu lenguaje:\n*   Condicionales, iterativas, excepciones...\n* - Debes hacer print por consola del resultado de todos los ejemplos.\n*\n* DIFICULTAD EXTRA (opcional):\n* Crea un programa que imprima por consola todos los números comprendidos\n* entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n*\n* Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n*/\n\n/*\n    🟢 Operadores\n*/\n\n// 🔸 Aritméticos\n\n$numero1 = 20;\n$numero2 = 10;\n\necho \"/- Operadores aritméticos -/<br>\";\necho \"<h1>Valor numero 1 como: $numero1, <br>y numero 2 como: $numero2,<br> en las operaciones</h1><br>\";\n\necho \"Suma: \" . ($numero1 + $numero2). '<br>'; // Sumar ➕\necho \"Resta: \" . ($numero1 - $numero2).'<br>'; // Resta ➖\necho \"Multiplicación: \" . ($numero1 * $numero2).'<br>'; // Multiplicacion ✖️\necho \"División: \" . ($numero1 / $numero2).'<br>'; // Division ➗\necho \"Módulo: \" . ($numero1 % $numero2).'<br>';\necho \"Exponenciación: \" . ($numero1 ** $numero2).'<br>'; \necho 2 ** 3;  echo '<br>';\necho \"Identidad: \" . (+$numero1).'<br>';\necho \"Negación: \" . (-$numero1).'<br>';\n\n\necho '<br>';\n// 🔸 Comparación\necho '<br>';\n$x = 5;\n$y = 9;\n$z = 5;\necho \"/- Operadores de comparación -/<br>\";\necho \"x = $x <br>\";\necho \"y = $y <br>\";\necho \"z = $z <br>\";\necho \"Igual: x == y: \"; var_dump($x == $y);echo '<br>';\necho \"Identico: x === y: \"; var_dump($x === $y);echo '<br>';\necho \"Distinto: x != y: \"; var_dump($x != $y);echo '<br>';\necho \"Distinto: x <> y: \"; var_dump($x <> $y);echo '<br>';\necho \"No identico: x !== y: \"; var_dump($x !== $y);echo '<br>';\necho \"Menor que: x < y: \"; var_dump($x < $y);echo '<br>';\necho \"Mayor que: x > y: \"; var_dump($x > $y);echo '<br>';\necho \"Menor o igual que x <= y: \"; var_dump($x <= $y);echo '<br>';\necho \"Mayor o igual que x >= y: \"; var_dump($x >= $y);echo '<br>';\n// -1 Si Izquierda es menor, 0 Si es igual, 1 Si izquierda es mayor\necho \"x <=> y: \" ; var_dump($x <=> $y);echo '<br>';\necho \"y <=> x: \" ; var_dump($y <=> $x);echo '<br>';\necho \"x <=> z: \" ; var_dump($x <=> $z);echo '<br>';\n\n\necho '<br>';\n// 🔸 Incremento y Decremento\necho '<br>';\necho \"/- Operadores de Incremento y Decremento -/<br>\";\necho \"x = $x <br>\";\necho \"Pre-incremento: ++x: \" . (++$x).\"<br>\";\necho \"Post-incremento: x++: \" . ($x++).\"<br>\";\necho \"Pre-decremento: --x: \" . (--$x).\"<br>\";\necho \"Post-decremento: x--: \" . ($x--).\"<br>\";\n\n\necho '<br>';\n// 🔸 Asignación\necho '<br>';\n$x = 3;\n$y = 4;\necho \"/- Operadores de Asignación -/<br>\";\necho \"x = $x<br>\";\necho \"y = $y<br>\";\necho \"x += y: \" . ($x += $y).\"<br>\";\necho \"x -= y: \" . ($x -= $y).\"<br>\";\necho \"x *= y: \" . ($x *= $y).\"<br>\";\necho \"x /= y: \" . ($x /= $y).\"<br>\";\necho \"x %= y: \" . ($x %= $y).\"<br>\";\necho \"x **= y: \" . ($x **= $y).\"<br>\";\n\n\necho '<br>';\n// 🔸 Lógicos\necho '<br>';\necho \"/- Operadores de Lógicos -/<br>\";\necho \"x = $x<br>\";\necho \"y = $y<br>\";\necho \"And: x and y: \" . ($x and $y).\"<br>\";\necho \"Or: x or y: \" . ($x or $y).\"<br>\";\necho \"Xor: x xor y: \" . ($x xor $y).\"<br>\";\necho \"&&: x && y: \" . ($x && $y).\"<br>\";\necho \"||: x || y: \" . ($x || $y).\"<br>\";\necho \"Not: !x: \" . (!$x).\"<br>\";\n\n\necho '<br>';\n// 🔸 Strings\necho '<br>';\necho \"/- Operadores para strings -/<br>\";\necho \"x = $x<br>\";\necho \"y = $y<br>\";\necho \"Concatenación: x . y: \" . ($x . $y).\"<br>\";\necho \"Concatenación: x .= y: \" . ($x .= $y).\"<br>\";\necho \"+: +x: \" . (+$x).\"<br>\";\necho \"Repetición: x * y: \" . ($x * $y).\"<br>\";\n\necho '<br>';\n// 🔸 Arrays\necho '<br>';\necho \"/- Operadores para arrays -/<br>\";\n$arr1 = array(1,2,3,4);\n$arr2 = array(1,3, 5,6,7,8);\necho \"Unión:<br>\";\necho '<pre>'; // Ordenar, start 🟣\nvar_dump($arr1+$arr2);\necho '</pre>'; // Ordenar, end 🟣\necho \"Igualdad:<br>\";\nvar_dump($arr1 == $arr2);\necho \"Identidad:<br>\";\nvar_dump($arr1 === $arr2);\necho \"Desigualdad:<br>\"; \nvar_dump($arr1!= $arr2);\necho \"Desigualdad:<br>\"; \nvar_dump($arr1 <> $arr2);\necho \"No identidad:<br>\" ;\nvar_dump($arr1 !== $arr2);\n\necho '<br>';\n// 🔸 Bits\necho '<br>';\necho \"/- Operadores bit a bit -/<br>\";\necho \"<h5>x = $x</h5><br>\";\necho \"<h5>y = $y</h5><br>\";\necho \"And -> x & y: \" . ($x & $y).\"<br>\";\necho \"Or -> x | y: \" . ($x | $y).\"<br>\";\necho \"Xor -> x ^ y: \" . ($x ^ $y).\"<br>\";\necho \"Desplazamiento a izquierda -> x <<= y: \" . ($x <<= $y).\"<br>\";\necho \"Desplazamiento a derecha -> x >>= y: \" . ($x >>= $y).\"<br>\";\n\necho '<br>';\n\n/*\n    🟢 Estructuras de control\n*/\necho '<br>';\necho \"/- Estructuras de control -/<br>\";\necho '<br>';\n// 🔸 if\necho \"/- if -/<br>\";\nif ($x > $y) {\n    echo \"x es mayor que y<br>\";\n} elseif ($x == $y) {\n    echo \"x es igual que y<br>\";\n} else {\n    echo \"x es menor que y<br>\";\n}\n\necho '<br>';\n// 🔸 switch\necho \"/- switch -/<br>\";\nswitch ($x) {\n    case 1:\n        echo \"x es 1<br>\";\n        break;\n    case 2:\n        echo \"x es 2<br>\";\n        break;\n    default:\n        echo \"x no es ni 1 ni 2<br>\";\n}\n\necho '<br>';\n// 🔸 while\necho \"/- while -/<br>\";\n$i = 0;\nwhile ($i < 10) {\n    echo $i.\"<br>\";\n    $i++;\n}\n\necho '<br>';\n// 🔸 do while\necho \"/- do while -/<br>\";\n$i = 0;\ndo {\n    echo $i.\"<br>\";\n    $i++;\n} while ($i < 10);\n\necho '<br>';\n// 🔸 for\necho \"/- for -/<br>\";\nfor ($i = 0; $i < 10; $i++) {\n    echo $i.\"<br>\";\n}\n\necho '<br>';\n// 🔸 foreach\necho \"/- foreach -/<br>\";\n$arr = array(1,2,3,4,5,6,7,8,9,10);\nforeach ($arr as $value) {\n    echo $value.\"<br>\";\n}\n\necho '<br>';\n// 🔸 foreach con clave\necho \"/- foreach con clave -/<br>\";\n$arr = array(1,2,3,4,5,6,7,8,9,10);\nforeach ($arr as $key => $value) {\n    echo \"Clave: $key, Valor: $value<br>\";\n}\n\necho '<br>';\n// 🔸 break\necho \"/- break -/<br>\";\nfor ($i = 0; $i < 10; $i++) {\n    if ($i == 5) {\n        break;\n    }\n    echo $i.\"<br>\";\n}\n\necho '<br>';\n// 🔸 continue\necho \"/- continue -/<br>\";\nfor ($i = 0; $i < 10; $i++) {\n    if ($i == 5) {\n        continue;\n    }\n    echo $i.\"<br>\";\n}\n\necho '<br>';\n// 🔸 goto\necho \"/- goto -/<br>\";\nfor ($i = 0; $i < 10; $i++) {\n    if ($i == 5) {\n        goto end;\n    }\n    echo $i.\"<br>\";\n}\nend:\necho \"Fin del bucle<br>\";\n\necho '<br>';\n// 🔸 return\necho \"/- return -/<br>\";\nfunction suma($x, $y) {\n    return $x + $y;\n}\necho suma(5, 6).\"<br>\";\n\necho '<br>';\n// 🔸 Operador ternario \necho \"Ternario: \".($x > $y ? \"x es mayor que y\" : \"x es menor o igual que y\").\"<br>\";\n\necho '<br>';\n// 🔸 Excepciones en PHP\necho \"/- Excepciones en PHP -/<br>\";\ntry {\n    throw new Exception(\"Excepción lanzada\");\n} catch (Exception $e) {\n    echo $e->getMessage();\n}\n\necho '<br>';\n// 🔸 Excepcion con finally\necho \"/- Excepcion con finally -/<br>\";\ntry {\n    throw new Exception(\"Excepción lanzada\");\n} catch (Exception $e) {\n    echo $e->getMessage();\n} finally {\n    echo \"<br>Esto se ejecuta siempre<br>\";\n}\n\n\n\n\n\necho '<br>🔥 Extra';\n/*\n    🔥 Extra\n*/\necho '<br>'; // 1ra forma\nfor ($i = 10; $i <= 55; $i++) {\n    if ((($i%3 != 0)and($i!=16))and(($i==55)or($i%2 ==0))){                         \n        echo $i.\"<br>\";\n    }\n}   \n\necho '<br>'; // 2da forma\nfor ($i = 10; $i <= 55; $i++) {\n                            \n    echo ((($i%3 != 0)&&($i!=16))&&(($i==55)||($i%2 ==0)) ? $i.\"<br>\" : \"\" );\n    \n}  \n\n?>"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/php/eulogioep.php",
    "content": "<?php\n\n// Ejemplos de operadores en PHP\n\n// 1. Operadores Aritméticos\necho \"--- Operadores Aritméticos ---\\n\";\necho \"Suma: 5 + 3 = \" . (5 + 3) . \"\\n\";\necho \"Resta: 10 - 4 = \" . (10 - 4) . \"\\n\";\necho \"Multiplicación: 6 * 2 = \" . (6 * 2) . \"\\n\";\necho \"División: 15 / 3 = \" . (15 / 3) . \"\\n\";\necho \"Módulo: 17 % 5 = \" . (17 % 5) . \"\\n\";\necho \"Exponenciación: 2 ** 3 = \" . (2 ** 3) . \"\\n\";\n$a = 5; $a++; echo \"Incremento: \\$a = 5; \\$a++; \\$a = $a\\n\";\n$b = 8; $b--; echo \"Decremento: \\$b = 8; \\$b--; \\$b = $b\\n\";\n\n// 2. Operadores de Asignación\necho \"\\n--- Operadores de Asignación ---\\n\";\n$x = 10;\necho \"Asignación simple: \\$x = 10; $x\\n\";\n$x += 5;\necho \"Suma y asignación: \\$x += 5; $x\\n\";\n$x *= 2;\necho \"Multiplicación y asignación: \\$x *= 2; $x\\n\";\n\n// 3. Operadores de Comparación\necho \"\\n--- Operadores de Comparación ---\\n\";\necho \"Igualdad: 5 == '5' es \" . (5 == '5' ? 'true' : 'false') . \"\\n\";\necho \"Igualdad estricta: 5 === '5' es \" . (5 === '5' ? 'true' : 'false') . \"\\n\";\necho \"Desigualdad: 5 != '6' es \" . (5 != '6' ? 'true' : 'false') . \"\\n\";\necho \"Mayor que: 7 > 5 es \" . (7 > 5 ? 'true' : 'false') . \"\\n\";\necho \"Menor o igual que: 10 <= 10 es \" . (10 <= 10 ? 'true' : 'false') . \"\\n\";\n\n// 4. Operadores Lógicos\necho \"\\n--- Operadores Lógicos ---\\n\";\necho \"AND lógico: true && false es \" . (true && false ? 'true' : 'false') . \"\\n\";\necho \"OR lógico: true || false es \" . (true || false ? 'true' : 'false') . \"\\n\";\necho \"NOT lógico: !true es \" . (!true ? 'true' : 'false') . \"\\n\";\n\n// 5. Operadores de Tipo\necho \"\\n--- Operadores de Tipo ---\\n\";\necho \"instanceof: new stdClass() instanceof stdClass es \" . (new stdClass() instanceof stdClass ? 'true' : 'false') . \"\\n\";\necho \"gettype(42) es \" . gettype(42) . \"\\n\";\n\n// 6. Operadores de Bits\necho \"\\n--- Operadores de Bits ---\\n\";\necho \"AND a nivel de bits: 5 & 3 = \" . (5 & 3) . \"\\n\";\necho \"OR a nivel de bits: 5 | 3 = \" . (5 | 3) . \"\\n\";\necho \"XOR a nivel de bits: 5 ^ 3 = \" . (5 ^ 3) . \"\\n\";\necho \"Desplazamiento a la izquierda: 5 << 1 = \" . (5 << 1) . \"\\n\";\n\n// Ejemplos de estructuras de control\n\n// 1. Estructura Condicional: if-else\necho \"\\n--- Estructura Condicional: if-else ---\\n\";\n$numero = 15;\nif ($numero > 10) {\n    echo \"El número es mayor que 10\\n\";\n} elseif ($numero < 10) {\n    echo \"El número es menor que 10\\n\";\n} else {\n    echo \"El número es igual a 10\\n\";\n}\n\n// 2. Estructura Condicional: switch\necho \"\\n--- Estructura Condicional: switch ---\\n\";\n$dia = \"Lunes\";\nswitch ($dia) {\n    case \"Lunes\":\n        echo \"Hoy es Lunes\\n\";\n        break;\n    case \"Martes\":\n        echo \"Hoy es Martes\\n\";\n        break;\n    default:\n        echo \"Es otro día de la semana\\n\";\n}\n\n// 3. Estructura Iterativa: for\necho \"\\n--- Estructura Iterativa: for ---\\n\";\nfor ($i = 0; $i < 5; $i++) {\n    echo \"Iteración for: $i\\n\";\n}\n\n// 4. Estructura Iterativa: while\necho \"\\n--- Estructura Iterativa: while ---\\n\";\n$contador = 0;\nwhile ($contador < 3) {\n    echo \"Iteración while: $contador\\n\";\n    $contador++;\n}\n\n// 5. Estructura Iterativa: do-while\necho \"\\n--- Estructura Iterativa: do-while ---\\n\";\n$j = 0;\ndo {\n    echo \"Iteración do-while: $j\\n\";\n    $j++;\n} while ($j < 3);\n\n// 6. Manejo de Excepciones: try-catch\necho \"\\n--- Manejo de Excepciones: try-catch ---\\n\";\ntry {\n    throw new Exception(\"Este es un error de ejemplo\");\n} catch (Exception $e) {\n    echo \"Error capturado: \" . $e->getMessage() . \"\\n\";\n} finally {\n    echo \"Este bloque siempre se ejecuta\\n\";\n}\n\n// DIFICULTAD EXTRA\necho \"\\n--- DIFICULTAD EXTRA ---\\n\";\nfor ($num = 10; $num <= 55; $num++) {\n    if ($num % 2 == 0 && $num != 16 && $num % 3 != 0) {\n        echo $num . \"\\n\";\n    }\n}\n\n?>"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/php/gabrielmoris.php",
    "content": "<?php\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n// Arithmetic\n$addition = 1 + 1;\n$substraction = 1 - 1;\n$increment = $addition++;\n$decrement = $addition--;\n$increment2 = ++$addition;\n$decrement2 = --$addition;\n$multiplication = 1 * 1;\n$division = 1 / 1;\n$reminder = 1 % 1;\n$exponential = 2 ** 2;\n$negation = -$exponential;\n$identity = +$exponential;\n\n//Bitwise Operators\n$and = 1 & 2;\n$or = 1 | 2;\n$xor = 1 ^ 2;\n$not = ~1;\n$shift_left = 1 << 2;\n$shift_right = 1 >> 2;\n\n// String Operators\n\n$a = \"Hello \";\n$b = $a . \"World!\";\n$b .= \"!\\n\";\n\necho $b;\n\n// Array Operators\n\n$arr1 = [\"item1\" => \"value1\", \"item2\" => \"value2\"];\n$arr2 = [\"item3\" => \"value3\"];\n\n$union = $arr1 + $arr2;\nprint_r($union);\n\n// Coparison\n$equal = 1 == 1;\n$identical = 1 === 1;\n$not_Equal = 1 != 2;\n$not_equal_2 = 1 <> 2;\n$not_identical = 1 !== 2;\n$less_than =  1 < 2;\n$more_than = 2 > 1;\n$less_or_equal = 1 <= 2;\n$more_or_equal = 2 >= 1;\n$less_equal_more_than = 1 <=> 2;\n\n// Logic\n\n$if_both_true = true and true;\n$if_both_true2 = true && true;\n$if_one_true = true or false;\n$if_one_true2 = true || false;\n$only_one_true = true xor true;\n$not = !false;\n\n// Control Structures\n\n// conditionals\nif (1 < 0) {\n    return;\n} elseif (1 === 0) {\n    return;\n} else {\n    echo \"Else: 1 < 0\\n\";\n};\n\n$ternalOp = true ? \"yes\\n\" : \"not\\n\";\necho $ternalOp;\n\n// Iterators\necho \"\\nWhile:\\n\";\n$index = 10;\nwhile ($index < 56) {\n    if ($index % 2 === 0 && $index % 3 !== 0 && $index !== 16) {\n        echo $index;\n        echo \", \";\n    }\n    $index++;\n};\necho \"\\nDO While:\\n\";\n$index = 10;\ndo {\n    if ($index % 2 === 0 && $index % 3 !== 0 && $index !== 16) {\n        echo $index;\n        echo \", \";\n    }\n    $index++;\n} while ($index < 56);\n\n\necho \"\\nFor Loop:\\n\";\nfor ($i = 10; $i <= 55; $i++) {\n    if ($i % 2 === 0 && $i % 3 !== 0 && $i !== 16) {\n        echo $i;\n        echo \", \";\n    }\n}\necho \"\\nFor Each Arr:\\n\";\n$hardcodedArr = [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55];\n\nforeach ($hardcodedArr as $val) {\n    if ($val % 2 === 0 && $val % 3 !== 0 && $val !== 16) {\n        echo $val;\n        echo \", \";\n    }\n}\n// Switch\necho \"\\nSwitch:\\n\";\nforeach ($hardcodedArr as $index) {\n    switch ($index) {\n        case $index % 2 === 0 && $index % 3 !== 0 && $index !== 16:\n            echo $index;\n            echo \", \";\n            break;\n        default:\n            break;\n    }\n}\n\n// Match\necho \"\\nMatch:\\n\";\n$food = 'cake';\n\n$return_value = match ($food) {\n    'apple' => 'This food is an apple',\n    'bar' => 'This food is a bar',\n    'cake' => 'This food is a cake',\n};\necho $return_value . \"\\n\";\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/php/guido2288.php",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n*/\n\n<?php\n  $number1 = 23;\n  $number2 = 55;\n\n  // Operadores Aritméticos\n  echo $number1 + $number2; //Addition\n  echo $number1 - $number2; //Subtraction\n  echo $number1 * $number2; //Multiplication\n  echo $number1 / $number2; //Division\n  echo $number1 % $number2; //Modulo\n  echo $number1 ** $number2; //Exponentiation  \n\n  // Operadores Logicos\n\n  if( \"Pepe\" == \"Pepe\" && 30 == 30 ) echo \"Ambos condiconales son Verdaderos <br>\"; // And\n\n  if( \"Pepe\" == \"Pepe\" || 20 == 30 ) echo \"Uno de los 2 condiconales son Verdaderos <br>\"; // Or\n\n  // Operadores de comparación\n\n  if('Guido' == 'Guido') echo \"Los datos son iguales <br>\"; // Igual\n\n  if( 22 === 22) echo \"Los datos son iguales <br>\"; // Identico\n\n  if( 25 != 22) echo \"Los datos no son iguales <br>\"; // No igual\n\n  if( 25 !== '25') echo \"Los datos no son iguales <br>\"; // No identico\n\n  if( 25 < 30) echo \"25 es menor a 30 <br>\"; // Menor que\n\n  if( 25 <= 25) echo \"25 es menor o igual a 25 <br>\"; // Menor o igual\n\n  if( 40 > 30) echo \"40 es mayor a 30 <br>\"; // Mayor que\n\n  if( 25 >= 25) echo \"25 es mayor o igual a 25 <br>\"; // Mayor o igual\n\n\n  $dia = 7;\n  switch($dia) {\n    case 1:\n        echo \"Es lunes <br/>\";\n        break;\n    case 2:\n        echo \"Es martes <br/>\";\n        break;\n    case 3:\n        echo \"Es miercoles <br/>\";\n        break;\n    case 4:\n        echo \"Es jueves <br/>\";\n        break;\n    case 5:\n        echo \"Es viernes <br/>\";\n        break;\n    default:\n        echo \"Es finde <br/>\";\n        break;  \n  };\n\n  // Operadores de iteración\n\n\n  // do While  (imprime mientras miEdad sea menor a 18);\n  $mayor = 18;\n  $miEdad = 8;\n  do {\n    echo \"No puedes comprar cerveza porque eres menor <br>\";\n    $miEdad++;\n  } while ($miEdad <= $mayor);\n\n  // foreach (imprime todos los valores del array)\n  $arrNumbers = [1, 2, 5, 2, 7, 9];\n  foreach ($arrNumbers as $number) {\n    echo \"Número -> $number<br />\";\n  }\n\n  // for in... \n  $persona = ['name' => 'Alberto', 'age' => 33];\n  foreach ($persona as $key => $value) {\n    echo \"$key -> $value<br />\";\n  }\n\n  //Opcional\n\n  /*\n    Crea un programa que imprima por consola todos los números comprendidos\n    entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n */\n\n  for ($i=10; $i <= 55 ; $i++) { \n    if($i != 16 && $i % 3 != 0){\n      echo \"<p>$i<p/><br>\";\n    } \n  }\n\n?>"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/php/jago86.php",
    "content": "<?php\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n\n$add = 1 + 1; // Addition\n$sub = 5 - 2; // Subtraction\n$multiply = 3 * 4; // Multiplication\n$division = 1 / 3; // Division\n$greatThan = 10 > 5; // Greater than\n$lessThan = 10 < 5; // Less than\n$greatOrEqual = 10 >= 5; // Greater than or equal to\n$lessOrEqual = 10 <= 5; // Less than or equal to\n$notEqual = 10 <> 5; // Not equal to\n$assignment = \"Value\"; // Assignment\n$number = 5;\n$number++; // Return $number and then increments  by 1\n$number--; // Return $number and then decrements  by 1\n++$number; // Increments  by 1 and then return $number\n$number--; // Decrements  by 1 and then return $number\n$isValid = true && false; // AND operator\n$isValid = true || false; // OR operator\n$isValid = true and false; // AND operator\n$isValid = true or false; // OR operator\n$isValid = true xor false; // XOR operator\n$isValid = !true; // NOT operator\n$isValid = true ? 'accepted' : 'rejected'; // Ternary operator\n$name = null;\n$userName = $name ?: 'Unknow'; // Short ternary opertor\n$roleName = $role ?? 'guest'; // Null coalescing\n\n// If\nif ($roleName == 'guest') {\n\t$grantAccess = false;\n} elseif ($roleName == 'admin') {\n\t$grantAccess = true;\n}\n\n// Switch\n\nswitch ($roleName) {\n\tcase 'guest':\n\t\t$grantAccess = false;\n\t\tbreak;\n\n\tcase 'admin':\n\t\t$grantAccess = true;\n\t\tbreak;\n\t\n\tdefault:\n\t\t$grantAccess = false;\n\t\tbreak;\n}\n\n// Match\n$grantAccess = match ($roleName) {\n\t'guest' => false,\n\t'admin' => true,\n\tdefault => false,\n};\n\n$page = 1;\n$totalPages = 10;\n\nwhile ($page < $totalPages) {\n\t// Do stuff\n\t$page++;\n}\n\ndo {\n\t$page++;\n\t// Do stuff\n} while ($page <= $totalPages);\n\n$sales = [10, 15, 12, 20];\n$total = 0;\nfor ($i=0; $i <= 3; $i++) { \n\t$total = $total + $sales[$i];\n}\n\n$total = 0;\nforeach ($sales as $sale) {\n\t$total = $total + $sale;\n}\n\ntry {\n\tthrow new Exception(\"Error Processing Request\", 1);\n\n} catch (Exception $e) {\n\t// Handle the exception\n}\n\nforeach (range(10, 55) as $number) {\n\n\tif (($number % 2 == 0 || $number == 55) && $number != 16 && $number % 3 != 0) {\n\n\t\techo $number . PHP_EOL;\n\t}\n\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/php/johannhsdev.php",
    "content": "<?php\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n$valor1 = 30;\n$valor2 = 40;\n\n # OPERADORES ARITMETICOS\necho $valor1 + $valor2; // Suma\necho $valor1 - $valor2; // Resta\necho $valor1 * $valor2; // Multiplicación\necho $valor1 / $valor2; // División\necho $valor1 % $valor2; // Módulo\necho $valor1 ** $valor2; // Exponenciación\n\n# OPERADORES LOGICOS\nif( \"Johann\" == \"Johann\" && 30 == 30 ) echo \"Ambos condicionales son Verdaderos <br>\"; // And\nif( \"Johann\" == \"Johann\" || 20 == 30 ) echo \"Uno de los 2 condicionales son Verdaderos <br>\"; // Or\nif( \"Johann\" == \"Johann\" xor 20 == 30 ) echo \"Uno de los 2 condicionales son Verdaderos <br>\"; // Xor\nif( \"Johann\" != \"Johann\" ) echo \"El condicional es Falso <br>\"; // Not\n\n# OPERADORES DE COMPARACION\nif( 30 == 30 ) echo \"Los datos son iguales <br>\"; // Igual\nif( 30 === 30 ) echo \"Los datos son iguales <br>\"; // Identico\nif( 30 != 40 ) echo \"Los datos no son iguales <br>\"; // No igual\nif( 30 !== 40 ) echo \"Los datos no son iguales <br>\"; // No identico\nif( 30 < 40 ) echo \"30 es menor a 40 <br>\"; // Menor que\nif( 30 <= 30 ) echo \"30 es menor o igual a 30 <br>\"; // Menor o igual\nif( 40 > 30 ) echo \"40 es mayor a 30 <br>\"; // Mayor que\nif( 40 >= 40 ) echo \"40 es mayor o igual a 40 <br>\"; // Mayor o igual\n\n# OPERADORES DE ASIGNACION\n$valor1 += $valor2; // Suma\n$valor1 -= $valor2; // Resta\n$valor1 *= $valor2; // Multiplicación\n$valor1 /= $valor2; // División\n$valor1 %= $valor2; // Módulo\n$valor1 **= $valor2; // Exponenciación\n\n# OPERADORES DE IDENTIDAD\nif( 30 === 30 ) echo \"Los datos son iguales <br>\"; // Identico\nif( 30 !== 40 ) echo \"Los datos no son iguales <br>\"; // No identico\n\n# OPERADORES DE PERTENENCIA\n$frutas = array(\"Manzana\", \"Pera\", \"Uva\");\nif( in_array(\"Manzana\", $frutas) ) echo \"La fruta existe <br>\"; // Incluido\nif( !in_array(\"Banano\", $frutas) ) echo \"La fruta no existe <br>\"; // No incluido\n\n# OPERADORES DE BITS\n$valor1 = 30;\n$valor2 = 40;\necho $valor1 & $valor2; // And\necho $valor1 | $valor2; // Or\necho $valor1 ^ $valor2; // Xor\necho ~$valor1; // Not\necho $valor1 << $valor2; // Desplazamiento a la izquierda\necho $valor1 >> $valor2; // Desplazamiento a la derecha\n\n# ESTRUCTURAS DE CONTROL\n\n// Estructura de control condicional\n\n//Estructura de control IF - ELSE\n$edad = 18;\nif($edad >= 18) {\n  echo \"Eres mayor de edad <br/>\";\n} else {\n  echo \"Eres menor de edad <br/>\";\n}\n\n// Estructura de control ELSE IF\n$hora = 12;\nif($hora < 12) {\n  echo \"Buenos días <br/>\";\n} else if($hora < 20 || $hora == 12) {\n  echo \"Buenas tardes <br/>\";\n} else {\n  echo \"Buenas noches <br/>\";\n}\n\n// Estructura de control condicional switch\n$dia = 7;\nswitch($dia) {\n  case 1:\n      echo \"Es lunes <br/>\";\n      break;\n  case 2:\n      echo \"Es martes <br/>\";\n      break;\n  case 3:\n      echo \"Es miercoles <br/>\";\n      break;\n  case 4:\n      echo \"Es jueves <br/>\";\n      break;\n  case 5:\n      echo \"Es viernes <br/>\";\n      break;\n  default:\n      echo \"Es finde <br/>\";\n};\n\n// Operador ternario\n$edad = 18;\necho ($edad >= 18) ? \"Eres mayor de edad <br/>\" : \"Eres menor de edad <br/>\";\n\n// Estructura de control Iterativa\n\n// Estructura de control FOR\n$asistencia_clase = 10;\nfor($i = 0; $i < $asistencia; $i++) {\n  echo \"Asistieron a clase $i alumnos. <br/>\";\n}\n\n// Estructura de control WHILE\n$numero = 10;\nwhile($numero <= 55) {\n  if($numero != 16 && $numero % 3 != 0) {\n    echo $numero . \"<br>\";\n  }\n  $numero++;\n}\n\n// Estructura de control DO WHILE\n$numero = 10;\ndo {\n  if($numero != 16 && $numero % 3 != 0) {\n    echo $numero . \"<br>\";\n  }\n  $numero++;\n} while($numero <= 55);\n\n// Estructura de control FOREACH\n$frutas = array(\"Manzana\", \"Pera\", \"Uva\");\nforeach($frutas as $fruta) {\n  echo $fruta . \"<br>\";\n}\n\n// Estructura de control de excepciones\n\n// Estructura de control de excepciones try - catch\ntry {\n  throw new Exception(\"Error en la aplicación\");\n} catch(Exception $e) {\n  echo $e->getMessage();\n}\n\n// Estructura de control de excepciones try - catch - finally\ntry {\n  throw new Exception(\"Error en la aplicación\");\n} catch(Exception $e) {\n  echo $e->getMessage();\n} finally {\n  echo \"Finalizando la aplicación\";\n}\n\n\n/* \n* DIFICULTAD EXTRA (opcional):\n* Crea un programa que imprima por consola todos los números comprendidos\n* entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n*/\nfor($i = 10; $i <= 55; $i++) {\n  if($i % 2 == 0 && $i != 16 && $i % 3 != 0) {\n    echo $i . \"<br>\";\n  }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/php/jonathanj20.php",
    "content": "<?php \n    /* Un operador es algo que toma uno o más valores (o expresiones) y que devuelve otro valor.\n    */\n\n    // operadores aritméticos\n    $num1 = 4;\n    $num2 = 2;\n   \n    $sum = $num1 + $num2; #suma\n    $subtraction = $num1 - $num2; #resta\n    $multiplication = $num1 * $num2; #multiplicación\n    $division = $num1 / $num2; #división\n    $modulo = $num1 % $num2; #módulo\n    $exponentiation = $num2 ** $num1; //exponenciación\n\n    echo $sum.\"<br>\";\n    echo $subtraction . \"<br>\";\n    echo $multiplication . \"<br>\";\n    echo $division . \"<br>\";\n    echo $modulo . \"<br>\";\n    echo $exponentiation . \"<br>\";\n\n    //operadores de asignación - sirve para asignar un valor a una variable\n\n    #asignación simple (=)\n    $num1 = 10;\n    $num2 = 5;\n    echo $num1;\n    echo \"<br>\";\n    echo $num2;\n\n    #asignación y suma (+=)\n    $num1 += $num2;\n    echo $num1;\n    echo \"<br>\";\n\n    #asignación y resta (-=);\n    $num1 -= $num2;\n    echo $num1;\n    echo \"<br>\";\n\n    #asignación y multiplicación (*=)\n    $num1 *= $num2;\n    echo $num1;\n    echo \"<br>\";\n\n    #asignación y división (/=)\n    $num1 /= $num2;\n    echo $num1;\n\n    #asignación y módulo (%=)\n    $num1 %= $num2;\n\n    // operadores de comparación\n    $num1 = 4;\n    $num2 = 2;\n\n    echo $num1 == $num2; //igual (compara valor)\n    echo $num1 === $num2; // idéntico (compara valor y tipo)\n    echo $num1 != $num2; //diferente de \n    echo $num1 <> $num2; //no igual\n    echo $num1 !== $num2; // diferente de (compara valor y tipo)\n    echo $num1 > $num2; //mayor que\n    echo $num1 < $num2; //menor que\n    echo $num1 >= $num2; //mayor o igual que\n    echo $num1 <= $num2; //mayor que\n    //operador spaceship (me devuelve -1, 0 o 1 dependiendo de si el primer número es menor, igual o mayor que el segundo.)\n    echo $num1 <=> $num2; \n    echo \"<br>\";\n\n    // operadores de incremento/decremento\n    $num1 = 0;\n    echo $num1++; //pre-incremento\n    echo ++$num1; //post-incremento\n    echo --$num1; //pre-decremento\n    echo $num1--; //post-decremento\n    echo \"<br>\";\n\n    // operadores lógicos\n    $expression1 = 18 > 9;\n    $expression2 = 50 > 15;\n    \n    echo $expression1 && $expression2; //and\n    echo $expression1 || $expression2; //or\n    echo $expression1 xor $expression2; //xor\n    echo !$expression2;\n    echo \"<br>\";\n\n    //operadores de cadena\n    $string1 = \"Esto es una cadena\";\n    $string2 = \"Esto es otra cadena\";\n\n    echo $string1 . $string2; //concatenación\n    echo $string1 .= $string2; //asignación con concatenación\n\n    echo \"<br>\";\n    //operadores de matrices\n    $array1 = [\"uno\" => 1,\"dos\" => 2, \"tres\" => 3];\n    $array2 = [\"cuatro\" => 4,\"cinco\" => 5,\"seis\" =>  6];\n\n    $array3 = $array1 + $array2; // unión (concatena o une dos arrays);\n    print_r($array3);\n\n    var_dump($array1 == $array2); //igual\n    var_dump($array1 === $array2); //identidad (compara valor y tipo)\n    var_dump($array1 != $array2); //diferente de\n    var_dump($array1 !== $array2); //diferente de (compara valor y tipo)\n    var_dump($array1 <> $array2); //diferente de\n    echo \"<br>\";\n    \n    //operadores de asignación condicional\n    /**Se usan para asignar un valor a algo dependiendo si se cumple una condición o no. */\n\n    $number = null;\n    echo $number > 10 ? \"el número $number es mayor a diez\" : \"el número $number es menor o igual a diez\"; //operador ternario\n    echo \"<br>\";\n\n    //null coalescing\n    /**Este operador asigna un valor dependiendo si el primer operando es null o no.\n     * si la primera expresión es null, asigna la segunda expresión o el segundo valor.\n     * si el primer valor o el primer operando contiene un valor y no es null, entonces asignará la primera expresión.\n     */\n    echo $number ?? \"No existe ningún número\";\n    echo \"<br>\";\n\n    /** Estructuras de control */\n    //condicionales\n\n    $a = 20;\n    $b = 25;\n\n    if($a > $b){\n        echo \"$a es más grande que $b\";\n    } elseif($a === $b) {\n        echo  \"$a es igual a $b\";\n    } else {\n        echo \"$a es menor a $b\";\n    }\n\n    echo \"<br>\";\n\n    //estructuras repetitivas(ciclo)\n    $i = 0;\n    while($i <= 10):\n        echo $i++.\"<br>\";\n    endwhile;\n\n    $elements = [1, 2, 3, 4, 5];\n    $i = 0;\n    do{\n        echo \"Elemento #\".$elements[$i].\"<br>\"; \n        $i++;\n    }while($i < count($elements));\n\n    $total = 0;\n    $numbers = [1, 2, 3, 4, 5];\n\n    echo \"Elementos: \";\n    for($i = 0; $i < count($numbers); $i++){\n        echo \"$numbers[$i] \";\n        $total += $numbers[$i];\n    }\n\n    echo \"<br>La suma total de los elementos es: $total <br>\";\n\n    $languagesPeople = [\n        \"Ana\" => [\"Español\", \"Francés\"], \n        \"José\" => [\"Italiano\", \"Inglés\"], \n        \"Mateo\" => [\"Español\", \"Inglés\"]\n    ];\n\n    //mostrado los idiomas de cada persona con foreach anidado\n    foreach($languagesPeople as $namePerson => $languages){\n        echo \"Los idiomas que habla $namePerson son \";\n        foreach($languages as $language){\n            echo \"$language \";\n        }\n        echo \"<br>\";\n    }\n\n    echo \"====<br>\";\n\n    //mostrando los idiomas con desestructuración de array\n    foreach($languagesPeople as $namePerson => [$language1, $language2]){\n        echo \"Los idiomas que habla $namePerson son $language1 y $language2 <br>\";\n    }\n\n    /**\n     * break\n     * la sentencia break permite salir de una estructura for, while, do-while, foreach y switch;\n     */\n\n    for ($i=0; $i < 10; $i++) { \n        if($i === 5){\n            echo \"STOP\";\n            break;\n        }\n\n        echo \"$i \";\n    }\n\n    echo \"<br>\";\n\n    /**\n     * break acepta como argumento un valor numérico que indica cuántas estructuras \n     * anidadas quiero interrumpir o romper. por defecto el valor es 1, y sólo \n     * termina la estructura de la que se encuentra dentro;\n     */\n\n    for ($i=0; $i < 10; $i++) { \n        for ($j=0; $j < 10; $j++) { \n           if($j === 5 && $i === 5){\n                echo \"[ $i ] [ $j ] <br>\";\n                echo \"Se rompen/interrumpen los dos ciclos anidados\";\n                break 2;\n           } else if($j === 5){\n                echo \"[ $i ] [ $j ] <br>\";\n                break;\n           }\n        }\n    }\n\n    echo \"<br>\";\n\n    /**\n     * continue \n     * -salta a la siguiente iteración de un bucle.\n     * -evita las instrucciones de código de la iteración actual y me lleva a la condición del bucle, si se cumple,\n     * ejecuta la siguiente iteración.\n     */\n\n    $i = 0;\n    $countries = [\"Mexico\", \"Italy\", \"Mozambique\", \"Costa Rica\", \"Germany\", \"Egypt\", \"New Zealand\"];\n    const LETTER_TO_COMPARE = \"m\";\n\n    while($i < count($countries)){\n        if(str_contains(strtolower($countries[$i]), LETTER_TO_COMPARE)){\n            $i++;\n            continue;\n        }\n\n        echo $countries[$i].\"<br>\";\n        $i++;\n    }\n\n    /**\n     * Estructura switch\n     */\n\n    /**\n    * \"La lista de comandos de un case puede estar vacía, en cuyo caso PHP utilizará la lista de comandos del caso siguiente.\"\n    */\n\n    foreach ($countries as $country) {\n        switch (strtolower($country)) {\n            case \"mexico\":\n            case \"costa rica\":\n                echo \"$country es de América <br>\";\n                break;\n            case \"italy\":\n            case \"germany\":\n                echo \"$country es de Europa <br>\";\n                break;\n            case \"mozambique\":\n            case \"egypt\":\n                echo \"$country es de África <br>\";\n                break;\n            default:\n                echo \"$country es de otro continente <br>\";\n                break;\n        }\n    }\n\n    #Excepciones\n    //validar que el usuario sólo ingrese números, que no se pueda dividir entre 0, y que ingrese un signo de opración válida (+ - * /)\n\n    function calculateOperation($number1, $number2, $operation){\n        define(\"OPERATIONS\", [\"+\", \"-\", \"*\", \"/\"]);\n        $signoDivision = OPERATIONS[3];\n\n        if(!is_numeric($number1) || !is_numeric($number2)){\n            return \"Se tienen que ingresar números\";\n        }\n\n        if(!in_array($operation, OPERATIONS)){\n            return \"Mandaste una operación inválida\";\n        }\n\n        if($operation === $signoDivision && ($number1 === 0 || $number2 === 0)){\n            return \"No se puede dividir entre 0\";\n        }\n\n        switch($operation){\n            case \"+\":\n                return $number1 + $number2;\n                break;   \n            case \"-\":\n                return $number1 - $number2;\n                break;\n            case \"*\":\n                return $number1 * $number2;\n                break;\n            case \"/\":\n                return $number1 / $number2;\n                break;\n        }\n    }\n\n    const NUMBER1 = 20;\n    CONST NUMBER2 = 4;\n    const OPERATION = \"/\";\n\n    try {\n        //en try pongo el código donde puede puede haber una excepción (o un error)\n        $result = calculateOperation(NUMBER1, NUMBER2, OPERATION);\n\n        if(is_string($result)){\n            throw new Exception($result);\n        }\n\n        echo NUMBER1.OPERATION.NUMBER2.\"=\".$result;\n    } catch (Exception $e) {\n        //en caso de que lance una excepción, entra a este bloque 'catch' \n        echo $e->getMessage();\n    } finally {\n        // este código se ejecuta, se lance o no una excepción.\n        echo \"<br>resultado obtenido\";\n    }\n\n    echo \"<br><br>\";\n    /* -- Dificultad extra -- */\n    const INITIAL_NUMBER = 10;\n    const LIMIT_NUMBER = 55;\n    const NUMBER_WITHOUT_PRINT = 16;\n\n    for($i = INITIAL_NUMBER; $i <= LIMIT_NUMBER; $i++){\n        if($i % 2 === 0 && $i !== NUMBER_WITHOUT_PRINT && $i % 3 !== 0){\n            echo \"$i \";\n        }\n    }\n?>"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/php/kodenook.php",
    "content": "<?php\n\n$num1 = 3;\n$num2 = 2;\n\n# Arithmetic Operators\n\n// addition\necho 'sum: ' . $num1 + $num2, PHP_EOL;\n// subtraction\necho 'subtraction: ' . $num1 - $num2, PHP_EOL;\n// multiplication\necho 'multiplication: ' . $num1 * $num2, PHP_EOL;\n// division\necho 'division: ' . $num1 / $num2, PHP_EOL;\n// modulus\necho 'modulus: ' . $num1 % $num2, PHP_EOL;\n// exponentiation\necho 'exponentiation: ' . $num1 ** $num2, PHP_EOL;\n\n# Assignment Operators\n\necho $num3 = 1, PHP_EOL; // assignment\necho $num3 += 2, PHP_EOL; // addition\necho $num3 -= 2, PHP_EOL; // subtraction\necho $num3 *= 4, PHP_EOL; // multiplication\necho $num3 /= 4, PHP_EOL; // division\necho $num3 %= 5, PHP_EOL; // modulus\n\n# Comparison Operators\n\necho 1 == 1, PHP_EOL; // equal\necho 1 === '1', PHP_EOL; // identical (value and type)\necho 1 != 2, PHP_EOL; // not equal\necho 1 <> 2, PHP_EOL; // not equal (equal to !=)\necho 1 !== '1', PHP_EOL; // not identical (value and type)\necho 2 > 1, PHP_EOL; // greater than\necho 1 < 2, PHP_EOL; // less than\necho 4 >= 3, PHP_EOL; // greater than or equal to\necho 3 <= 4, PHP_EOL; // less than or equal to\necho 1 <=> 1, PHP_EOL; // spaceship (return -1,0 or 1)\n\n\n# Increment/Decrement Operators\n\necho ++$num1, PHP_EOL; // increments by 1 then return $num1\necho $num1++, PHP_EOL; // return $num1 then increments by 1\necho --$num1, PHP_EOL; // decrements by 1 then return $num1\necho $num1--, PHP_EOL; // return $num1 then decrements by 1\n\n# Logical Operators\n\necho $num1 and $num2, PHP_EOL; // true if both are true\necho $num1 or $num2, PHP_EOL; // true if either are true\necho $num1 xor $num2, PHP_EOL; // true if either are true, but not both\necho $num1 && $num2, PHP_EOL; // true if both are true\necho $num1 || $num2, PHP_EOL; // true if either are true\necho !$num1, PHP_EOL; // true if not true\n\n# String Operators\n\n$word = '';\n\necho 'hello ' . 'world', PHP_EOL; // concatenation\necho $word .= 'word', PHP_EOL; // concatenation assignment\n\n# Conditional Assignment\n\necho $num1 ? 'true' : 'false', PHP_EOL; // ternary\necho $num1 ?: 'false', PHP_EOL; // short ternary\necho $num4 ?? 'null', PHP_EOL; // null coalescing\n\n\n# if\n\nif ($num1) {\n    echo $num1, PHP_EOL;\n} elseif ($num2) {\n    echo $num2, PHP_EOL;\n} else {\n    echo 'null', PHP_EOL;\n}\n\n# short hand if\n\nif ($num1 < 10) echo 1, PHP_EOL;\n\n# Switch\n\n$color = 'white';\n\nswitch ($color) {\n    case 'red':\n        echo true, PHP_EOL;\n        break;\n\n    default:\n        echo 'false', PHP_EOL;\n        break;\n}\n\n# Match\n\necho match (8.0) {\n    '8.0' => \"Oh no!\",\n    8.0 => \"This is what I expected\",\n}, PHP_EOL;\n\n# Loop While\n\n$a = 1;\n\nwhile ($a <= 10) {\n    echo ++$a, PHP_EOL;\n}\n\n# Loop Do-while\n\ndo {\n    echo --$a, PHP_EOL;\n} while ($a >> 1);\n\n# Loop For\n\nfor ($a = 0; $a < 10; $a++) {\n    echo $a, PHP_EOL;\n}\n\n# Loop Foreach\n\n$days = ['saturday', 'sunday', 'monday'];\n\nforeach ($days as $key => $value) {\n    echo 'key: ' . $key . ', value: ' . $value, PHP_EOL;\n}\n\n# Exceptions\n\ntry {\n    if ($num1 <> 1000) {\n        throw new Exception(\"Error Processing Request\", 1);\n    }\n} catch (\\Throwable $th) {\n    echo 'error: ' . $th->getMessage() . ' with code: ' . $th->getCode();\n}\n\n# Exercise\n\nfor ($i = 10; $i < 56; $i++) {\n    if ($i % 2 === 0 and $i !== 16 and $i % 3 !== 0) {\n        echo $i, PHP_EOL;\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/php/kuroz00.php",
    "content": "<?php\n//Crea ejemplos utilizando todos los tipos de operadores en tu lenguaje\n//Aritmeticos\n$num1 = 1;\n$num2 = 2;\n\n$suma = $num1 + $num2;\n$resta = $num1 - $num2;\n$multi = $num1 * $num2;\n$div = $num1 / $num2;\necho \"suma: \".$suma; echo \"resta: \".$resta; echo \"multi: \".$multi; echo \"div: \".$div;\n\n//asignacion\n$num3 = 3;\n$num4 = 4;\n\n$num3 += $num4;\necho \"suma: \".$num3; \n\n$num3 -= $num4;\necho \"resta: \".$num3; \n\n$num3 *= $num4;\necho \"multi: \".$num3; \n\n$num3 /= $num4;\necho \"div: \".$num3; \n\n//Comparacion\necho $num1 == $num2; \necho $num1 != $num2; \necho $num1 < $num2; \necho $num1 > $num2; \necho $num1 <= $num2; \necho $num1 >= $num2; \n\n//incremento o decremento \n$num5 = 1;\necho $num5; $num5++; $num5--;\n\n//Logicos\necho $num1 and $num2, PHP_EOL;\necho $num1 or $num2, PHP_EOL;\necho $num1 xor $num2, PHP_EOL;\necho $num1 && $num2, PHP_EOL;\necho $num1 || $num2, PHP_EOL;\necho !$num1, PHP_EOL;\n\n//Condicionales \n//if\nif($num1 < $num2){\n    echo \"$num2 < $num1\";\n} else {\n    echo \"$num2 > $num1\";\n}\n\n//if acortado\nif($num1 < $num2) echo \"$num2 < $num1\";\n\n//switch \n\n$diaLibre = \"lunes\";\n\nswitch($diaLibre){\n    case \"lunes\":\n        echo \"DIA LIBRE!\";\n        break;\n    case \"martes\":\n        echo \"TRABAJO!\";\n        break;\n    case \"miercoles\":\n        echo \"TRABAJO!\";\n        break;\n    case \"jueves\":\n        echo \"TRABAJO!\";\n        break;\n    case \"viernes\":\n        echo \"TRABAJO!\";\n        break;\n    case \"sabado\":\n        echo \"TRABAJO!\";\n        break;\n    case \"domingo\":\n        echo \"TRABAJO!\";\n        break;\n    default:\n        echo\"dia no encontrado\";\n        break;\n}\n$num = 0;\n$numTope = 10;\n\n//while\nwhile($num < $numTope){\n    echo \"numero actual: $num \";\n    $num += 1;\n} \n//do while\ndo{\n    $num++;\n    echo \"numero actual: $num\";\n} while($num == $numTope);\n//for\nfor($num=0;$num!=10;$num++){\n    echo $num;\n}\n$tareas = [\"ordenar casa\", \"lavar la losa\", \"dormir\"];\nforeach ($tareas as $key => $value) {\n    echo \"Tarea n°\" . ($key + 1) . \" = \" . $value . PHP_EOL;\n}\n\n$num1 = 1;\n$num2 = \"2\";\n\ntry {\n    // Intentamos realizar la operacion\n    if (!is_numeric($num1) || !is_numeric($num2)) {\n        throw new Exception(\"Uno de los valores no es numérico.\");\n    }\n\n    echo \"Resultado: \" . ($num1 + $num2) . PHP_EOL;\n} catch (Exception $e) {\n    // Capturamos la excepcion\n    echo \"Error: \" . $e->getMessage() . PHP_EOL;\n}\n\n\n//ejercicio adicional\nfor($num=10;$num<=55;$num++){\n    if(($num % 2 == 0) && ($num % 3 != 0) && ($num != 16)){\n        echo $num.PHP_EOL;\n    }\n}\n?>\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/php/lorenamesa.php",
    "content": "<?php\n\n/****************** OPERADORES ****************/\n\n// Aritméticos\n$a = 5;\n$b = 3;\necho \"Identidad: \" . +$a . \"\\n\";  // Conversión de $a a int o float según el caso.\necho \"Opuesto: \" . -$a . \"\\n\";  // Opuesto de $a.\necho \"Suma: \" . ($a + $b) . \"\\n\"; // Suma de $a y $b.\necho \"Resta: \" . ($a - $b) . \"\\n\"; // Diferencia de $a y $b.\necho \"Multiplicación: \" . ($a * $b) . \"\\n\"; // Producto de $a y $b.\necho \"División: \" . ($a / $b) . \"\\n\"; // Cociente de $a y $b.\necho \"Modular: \" . ($a % $b) . \"\\n\"; // Resto de $a dividido por $b.\necho \"Exponenciación: \" . ($a ** $b) . \"\\n\"; // Resultado de elevar $a a la potencia $b\n\n// Incremento/Decremento\necho \"Pre-incremento: \" . ++$a . \"\\n\";  // Incrementa $a en uno, y luego retorna $a.\necho \"Post-incremento: \" . --$a . \"\\n\";  // Retorna $a, y luego incrementa $a en uno.\necho \"Pre-decremento: \" . $a++ . \"\\n\"; // Decrementa $a en uno, luego retorna $a.\necho \"Post-decremento: \" . $a-- . \"\\n\"; // Retorna $a, luego decrementa $a en uno.\n\n// Asignación\n$a = 3;\necho $a . \"\\n\"; // Devuelve 3\n$a += 5;\necho $a . \"\\n\"; // Devuelve 8\n$a -= 2;\necho $a . \"\\n\"; // Devuelve 7\n\n$b = \"Hola\";\necho $b . \"\\n\"; // Devuelve \"Hola\"\n$b .= \" PHP\\n\";\necho $b; // Devuelve \"Hola PHP\"\n\n// Comparación\n$a = 5;\n$b = 8;\n$c = 3;\n\necho \"Igual: \" . ($a == $b) . \"\\n\"; // \ttrue si $a es igual a $b después de la manipulación de tipos.\necho \"Idéntico: \" . ($a === $b) . \"\\n\"; // true si $a es igual a $b, y son del mismo tipo.\necho \"Diferente: \" . ($a != $b) . \"\\n\"; // true si $a no es igual a $b después de la manipulación de tipos.\necho \"Diferente: \" . ($a <> $b) . \"\\n\"; // true si $a no es igual a $b después de la manipulación de tipos.\necho \"Distinto: \" . ($a !== $b) . \"\\n\"; // true si $a no es igual a $b, o si no son del mismo tipo.\necho \"Menor que: \" . ($a < $b) . \"\\n\"; // true si $a es estrictamente menor que $b.\necho \"Mayor que: \" . ($a > $b) . \"\\n\"; // true si $a es estrictamente mayor que $b.\necho \"Menor o igual que: \" . ($a <= $b) . \"\\n\"; // true si $a es menor o igual que $b.\necho \"Mayor o igual que: \" . ($a >= $b) . \"\\n\"; // true si $a es mayor o igual que $b.\necho \"Nave espacial: \" . ($a <=> $b) . \"\\n\"; // Un integer menor que, igual a, o mayor que cero cuando $a es respectivamente menor que, igual a, o mayor que $b. Disponible a partir de PHP 7.\necho \"Fusión de null: \" . ($a ?? $b ?? $c) . \"\\n\"; // El primer operando de izquierda a derecha que exista y no sea null. null si no hay valores definidos y no son null\n\n// Lógicos\necho \"And: \" . ($a and $b) . \"\\n\"; // true si tanto $a como $b son true.\necho \"Or: \" . ($a or $b) . \"\\n\"; // true si cualquiera de $a o $b es true.\necho \"Xor: \" . ($a xor $b) . \"\\n\"; // true si $a o $b es true, pero no ambos.\necho \"Not: \" . !$a . \"\\n\"; // true si $a no es true.\necho \"And: \" . ($a && $b) . \"\\n\"; // true si tanto $a como $b son true.\necho \"Or: \" . ($a || $b) . \"\\n\"; // true si cualquiera de $a o $b es true.\n\n// Bits\n$a = 1;\n$b = 0;\n\necho \"Y: \" . ($a & $b) . \"\\n\"; // Los bits que están activos en ambos $a y $b son activados.\necho \"O inclusivo: \" . ($a | $b) . \"\\n\"; // Los bits que están activos ya sea en $a o en $b son activados.\necho \"O exclusivo: \" . ($a ^ $b) . \"\\n\"; // Los bits que están activos en $a o en $b, pero no en ambos, son activados.\necho \"No: \" . ~ $b . \"\\n\"; // Los bits que están activos en $a son desactivados, y viceversa.\necho \"Desplazamiento a la izquierda: \" . ($a << $b) . \"\\n\"; // Desplaza los bits de $a, $b pasos a la izquierda (cada paso quiere decir \"multiplicar por dos\").\necho \"Desplazamiento a la derecha: \" . ($a >> $b) . \"\\n\"; // Desplaza los bits de $a, $b pasos a la derecha (cada paso quiere decir \"dividir por dos\").\n\n/****************** ESTRUCTURAS DE CONTROL ****************/\n$a = 3;\n$b = 5;\n$c = 7;\n\nif ($a < $b) {\n    echo '$a es menor que $b' . \"\\n\";\n} elseif ($a > $b) {\n    echo '$a es mayor que $b' . \"\\n\";\n} else {\n    echo '$a y $b son iguales' . \"\\n\";\n}\n\nwhile ($a < $c) {\n    echo '$a es menor que $c' . \"\\n\";\n    $a++;\n}\n\ndo {\n    echo '$a es menor que $b' . \"\\n\";\n    $a++;\n} while ($a < $b);\n\nfor ($i = 0; $i <= $b; $i++) {\n    echo 'Estoy imprimiendo numeros hasta el valor de $b: ' . $i . \"\\n\";\n}\n\n$arrayValues = [0, 1, 2];\necho \"Los valores de mi array son:\\n\";\nforeach ($arrayValues as $arrayValue) {\n    echo \"$arrayValue\\n\";\n}\n\nswitch ($a) {\n    case 0:\n        echo \"a es igual a 0\";\n        break;\n    case 1:\n        echo \"a es igual a 1\";\n        break;\n    case 2:\n        echo \"a es igual a 2\";\n        break;\n    default:\n        echo \"a es mayor a 2\";\n    echo \"\\n\";\n}\n\n\n/****************** DIFICULTAD EXTRA ****************/\necho \"****************EJERCICIO EXTRA:****************\\n\";\n\nfor ($i = 10; $i <= 55; $i++) {\n    if (($i == 16) || ($i % 3 === 0)) {\n        continue;\n    }\n    if ($i % 2 === 0) {\n        echo $i . \"\\n\";\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/php/marcode24.php",
    "content": "<?php\n\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n// Operadores aritméticos\n$suma = 5 + 3;\n$resta = 10 - 4;\n$multiplicacion = 6 * 7;\n$division = 20 / 4;\n$modulo = 15 % 4;\n\necho \"Operadores Aritméticos:\\n\";\necho \"Suma: $suma\\n\";\necho \"Resta: $resta\\n\";\necho \"Multiplicación: $multiplicacion\\n\";\necho \"División: $division\\n\";\necho \"Módulo: $modulo\\n\";\n\n// Operadores lógicos\n$and = true && false;\n$or = true || false;\n$not = !true;\n\necho \"\\nOperadores Lógicos:\\n\";\necho \"AND: \" . var_export($and, true) . \"\\n\";\necho \"OR: \" . var_export($or, true) . \"\\n\";\necho \"NOT: \" . var_export($not, true) . \"\\n\";\n\n// Operadores de comparación\n$igual = 5 == '5';\n$estrictamenteIgual = 5 === '5';\n$diferente = 10 !== 5;\n$mayorQue = 15 > 10;\n$menorQue = 7 < 12;\n\necho \"\\nOperadores de Comparación:\\n\";\necho \"Igual (==): \" . var_export($igual, true) . \"\\n\";\necho \"Estrictamente Igual (===): \" . var_export($estrictamenteIgual, true) . \"\\n\";\necho \"Diferente (!=): \" . var_export($diferente, true) . \"\\n\";\necho \"Mayor Que (>): \" . var_export($mayorQue, true) . \"\\n\";\necho \"Menor Que (<): \" . var_export($menorQue, true) . \"\\n\";\n\n// Operadores de asignación\n$x = 10;\n$x += 5; // equivalente a $x = $x + 5\n$y = 20;\n$y *= 2; // equivalente a $y = $y * 2\n\necho \"\\nOperadores de Asignación:\\n\";\necho \"x: $x\\n\";\necho \"y: $y\\n\";\n\n// Operadores bitwise\n$bitwiseAnd = 5 & 3; // AND\n$bitwiseOr = 5 | 3; // OR\n$bitwiseXor = 5 ^ 3; // XOR\n$bitwiseNot = ~5; // NOT\n$leftShift = 5 << 1; // Left Shift\n$rightShift = 5 >> 1; // Right Shift\n$zeroFillRightShift = 5 >> 1; // Zero-fill Right Shift\n\necho \"\\nOperadores Bitwise:\\n\";\necho \"Bitwise AND (&): $bitwiseAnd\\n\";\necho \"Bitwise OR (|): $bitwiseOr\\n\";\necho \"Bitwise XOR (^): $bitwiseXor\\n\";\necho \"Bitwise NOT (~): $bitwiseNot\\n\";\necho \"Left Shift (<<): $leftShift\\n\";\necho \"Right Shift (>>): $rightShift\\n\";\necho \"Zero-fill Right Shift (>>>): $zeroFillRightShift\\n\";\n\n// Estructuras de control\n// Condicionales\n$edad = 18;\nif ($edad >= 18) {\n  echo \"\\nEres mayor de edad.\\n\";\n} else {\n  echo \"\\nEres menor de edad.\\n\";\n}\n\n// Iterativas\necho \"\\nNúmeros entre 10 y 55 (pares, no 16 ni múltiplos de 3):\\n\";\nfor ($i = 10; $i <= 55; $i++) {\n  if ($i % 2 === 0 && $i !== 16 && $i % 3 !== 0) {\n    echo \"$i\\n\";\n  }\n}\n\n// Excepciones\ntry {\n  throw new Exception('Este es un ejemplo de excepción.');\n} catch (Exception $error) {\n  echo \"\\nExcepción: {$error->getMessage()}\\n\";\n}\n\n// Visita mi repo en GitHub para ver y correr los tests de este código --> https://github.com/marcode24/weekly-challenges\n\n?>\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/php/maussho.php",
    "content": "# 01 OPERADORES Y ESTRUCTURAS DE CONTROL\n#maussho\n\n<?php\n\n// 1. Crea ejemplos utilizando todos los tipos de operadors de tu lenguaje\n\n# Operadores aritmeticos\n# Valores \n$num1 = 14;\n$num2 = 2;\n\n# Suma\nprint \"--Suma--\" .\"\\n\";\n$suma = $num1 + $num2;\necho $suma .\"\\n\";\n\n# Resta\nprint \"--Resta--\" .\"\\n\";\n$resta = $num1 - $num2;\necho $resta .\"\\n\";\n\n# Multiplicación\nprint \"--Multiplicación--\" .\"\\n\";\n$multi = $num1 * $num2;\necho $multi .\"\\n\";\n\n# División\nprint \"--División--\" .\"\\n\";\necho $num1 / $num2 .\"\\n\";\n\n# Modulo o Residuo\nprint \"--Modulo o Residuo--\" .\"\\n\";\necho $num1 % $num2 .\"\\n\";\n\n# Operadores de asignación\n# =\nprint \"--Igual--\" .\"\\n\";\n$valor1 = 10;\n$valor2 = 9;\n\n# Incremento\nprint \"--Incremento--\" .\"\\n\";\n$valor1 += 2;\n\necho $valor1 .\"\\n\";\n\n# decremento\nprint \"--Decremento--\" .\"\\n\";\n$valor2 -= 2;\n\necho $valor2 .\"\\n\";\n\n# Concatenación\nprint \"--Concatenación--\" .\"\\n\";\n$texto2 = \"Hola\";\n$texto2 .= \" mundo\";\nprint $texto2 .\"\\n\";\n\n# Asignación por referencia\n$a = 4;\n$b = $a;\n// echo $b .\"\\n\"\n\n# Operadores lógicos\nprint \"--Operadores lógicos--\" .\"\\n\";\n# and\n$ab = true;\n$ac = false;\nif ($ab && $ab) {\n    echo \"true\" .\"\\n\";\n}\nif($ab && $ac){\n\n}else{\n    echo \"false\" .\"\\n\";\n}\n# or\nif ($ab || $ab) {\n    echo \"true\" .\"\\n\";\n}\nif($ab || $ac){\n    echo \"true\" .\"\\n\";\n}\n\n$a10 = 4;\nif ($a10<5) {\n    echo $a10 .\"\\n\";\n}\n\n\n#Condicionales\nprint \"--Condicionales--\" .\"\\n\";\n$name = \"mauri\";\necho $name .\"\\n\";\n\n#Iterativas\nprint \"--Iterativas--\" .\"\\n\";\n# Ciclo For\nfor ($i=0; $i < 10; $i++) { \n    echo $i .\"\\n\";\n}\n\n# Ciclo ForEach\n$array = [1, 2, 3];\nforeach ($array as $clave => $value) {\n    echo $clave .- $value .\"\\n\"; \n}\n\n# Ciclo while\necho \"Ciclo While\" .\"\\n\";\n$i = 10;\nwhile ($i <= 12) {\n    echo $i .\"\\n\";\n    $i++;\n}\n\n# Dificultad Extra\necho \"DIFICULTAD EXTRA\" .\"\\n\";\nfor ($i=10; $i<=55; $i++) { \n    if ($i % 2 == 0){\n        if($i !== 16){\n            if($i % 3 !== 0){\n                echo $i .\"\\n\";\n            }\n        }\n        \n    }\n}\n\n# Otra opción:\n// for ($i=10; $i<=55; $i++) { \n//     if($i % 2 == 0 && $i !== 16 && $i % 3 !== 0){\n//         echo $i . \"\\n\";\n//     }\n// }\n?>\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/php/mayerga.php",
    "content": "<?php\n\n$a = 5;\n$b = 10;\n\n// OPERADORES ARITMÉTICOS\n$suma = $a + $b; // El resultado será 15\n$resta = $a - $b; // El resultado será -5\n$multiplicacion = $a * $b; // El resultado será 50\n$división = $a / $b; // El resultado será 0.5\n$módulo = $a % $b; // El resultado será 5\n$exponente = $a ** $b; //El resultado será 9765625\n\n// OPERADORES DE ASIGNACIÓN\n//Asignación simple (=)\n$numero = 42;\n$mensaje = 'Hola, que tal?';\n\n//Asignación y suma (+=)\n$contador = 5;\n$contador += 3; // será 8\n\n//Asignación y resta (-=)\n$var_asigResta = 10;\n$asignacion_resta -= 3; // será 7\n\n//Asignación y multiplicación (*=)\n$var_asigMulti = 4;\n$asignacion_multi *= 3; // Será 12\n\n//Asignación y división (/=)\n$var_asigdivi = 15;\n$asignacion_divi /= 3; // Será 5\n\n//Asignación y módulo (%=)\n$var_asigModu = 15;\n$asignacion_modu %= 4; // Será 3\n\n//Asignación y exponente (**=)\n$var_asigexpo = 2;\n$asignacion_expo **= 3; // Será 8\n\n\n// OPERADORES DE COMPARACIÓN\n\n// Igual (==)\n\n$a = 10;\n$b = 10;\n\nif ($a == $b) {\n  echo \"Los valores son iguales\";\n} else {\n  echo \"Los valores no son iguales\";\n}\n\n// Idéntico (===)\n$a = 10;\n$b = \"10\";\n\nif ($a === $b) {\n  echo \"Los valores son iguales y del mismo tipo\";\n} else {\n  echo \"Los valores no son iguales o no son del mismo tipo\";\n}\n\n// Diferente (!= o <>)\n$a = 10;\n$b = 20;\n\nif ($a != $b) {\n  echo \"Los valores son diferentes\";\n} else {\n  echo \"Los valores son iguales\";\n}\n\n//No idéntico (!==)\n$a = 10;\n$b = \"10\";\n\nif ($a !== $b) {\n  echo \"Los valores son diferentes o no son del mismo tipo\";\n} else {\n  echo \"Los valores son iguales y del mismo tipo\";\n}\n\n//Mayor que (>)\n$a = 10;\n$b = 5;\nif ($a > $b) {\n  echo \"El valor de a es mayor que el valor de b\";\n} else {\n  echo \"El valor de a no es mayor que el valor de b\";\n}\n\n//Menos que (<)\n$a = 10;\n$b = 5;\n\nif ($a < $b) {\n  echo \"El valor de a es menor que el valor de b\";\n} else {\n  echo \"El valor de a no es menor que el valor de b\";\n}\n\n//Mayor o igual que (>=)\n$a = 10;\n$b = 5;\n\nif ($a >= $b) {\n  echo \"El valor de a es mayor o igual que el valor de b\";\n} else {\n  echo \"El valor de a no es mayor o igual que el valor de b\";\n}\n\n//Menor o igual que (<=)\n$a = 10;\n$b = 5;\n\nif ($a <= $b) {\n  echo \"El valor de a es menor o igual que el valor de b\";\n} else{\n  echo \"El valor de a no es menor o igual que el valor de b\";\n}\n\n//Comparación de nave espacial (<=>)\n$a = 5; \n$b = 10; \n\n$resultado = ($a <=> $b); // -1, porque 5 es menor que 10\n\n\n// OPERADORES DE INCREMENTO/DECREMENTO\n\n// Incremento (++)\n$contador = 5;\n$nuevoValor = ++$contador; // $contador = 6, $nuevoValor = 6\n\n\n// Decremento (--)\n$contador = 5;\n$nuevoValor = $contador++; // $contador = 6, $nuevoValor = 5\n\n// OPERADORES LÓGICOS\n// AND (&& o and)\n$a = 10;\n$b = 5;\n$c = 20;\n\nif ($a > $b && $a < $c) {\n  echo \"El valor de a está entre el valor de b y c\";\n} else {\n  echo \"El valor de a no está entre el valor de b y c\";\n}\n\n// OR (|| o or)\n$a = 10;\n$b = 5;\n$c = 20;\n\nif ($a > $b || $a > $c) {\n  echo \"El valor de a es mayor que el valor de b o c\";\n} else {\n  echo \"El valor de a no es mayor que el valor de b ni c\";\n}\n\n// XOR (xor)\n$a = true;\n$b = false;\n\nif ($a xor $b) {\n    echo \"Solo una de las variables es verdadera.\";\n}\n\n// NOT (!)\n$a = 10;\n\nif (!($a > 5)) {\n  echo \"El valor de a no es mayor que 5\";\n} else {\n  echo \"El valor de a es mayor que 5\";\n}\n\n\n// OPERADORES DE CADENA\n//Concatenación (.)\n$nombre = \"Juan\";\n$apellido = \"Pérez\";\n$nombreCompleto = $nombre . \" \" . $apellido;\n\necho $nombreCompleto; // Muestra \"Juan Pérez\"\n\n//Asignación de concatenación (.=)\n$frase = \"Hola, \";\n$frase .= \"mundo!\";\n\necho $frase; // Muestra \"Hola, mundo!\"\n\n\n// OPERADORES DE CONTROL DE ERRORES\n// El operador de control de errores (@) en PHP se utiliza para suprimir los mensajes de error que podrían ser generados por una expresión específica.\n$resultado = @file_get_contents(\"archivo_no_existente.txt\");\n\nif ($resultado === false) {\n    echo \"No se pudo leer el archivo.\";\n} else {\n    echo \"Contenido del archivo: \" . $resultado;\n}\n\n//OPERADORES DE EJECUCIÓN\n// El operador de ejecución en PHP consiste en comillas invertidas o “backticks” (`). Al utilizar este operador, el comando del sistema operativo entre las comillas invertidas se ejecutará y el resultado se devolverá como un string.\n\n$comando = `dir`; // En Windows\n// $comando = `ls`; // En Linux y macOS\n\necho \"<pre>$comando</pre>\";\n\n\n// OPERADORES DE TIPO\n// Operador instanceof\n// El operador instanceof es utilizado para determinar si un objeto es una instancia de una clase específica, incluyendo las clases heredadas.\n$objeto instanceof Clase\n\n\n// OPERADOR TERNARIO\n//condicion ? valor_si_verdadero : valor_si_falso;\n$edad = 18;\n\n$mensaje = $edad >= 18 ? \"Eres mayor de edad.\" : \"Eres menor de edad.\";\n\necho $mensaje; // Imprime: \"Eres mayor de edad.\"\n\n//Estructuras de Control\n//Condicionales\n\n//If\necho \"----if----\\n\";\nif ($numero1 > $numero2) {\n    echo $numero1. \" es mayor que \" .$numero2. \"\\n\"; \n}\n//else\necho \"----else----\\n\";\nif ($numero1 < $numero2) {\n    echo $numero1. \" es menor que \" .$numero2. \"\\n\";\n} else {\n    echo $numero1. \" es mayor que \" .$numero2. \"\\n\";\n}\n//elseif\necho \"----elseif----\\n\";\nif ($numero1 < $numero2) {\n    echo $numero1. \" es menor que \" .$numero2. \"\\n\";\n} elseif ($numero1 == $numero2) {\n    echo $numero1. \" es igual que \" .$numero2. \"\\n\";\n} else {\n    echo $numero1. \" es mayor que \" .$numero2. \"\\n\";\n}\n\n//switch\necho \"----switch----\\n\";\n$fruta = \"manzana\";\nswitch ($fruta) {\n    case \"naranja\":\n        echo \"la fruta es una naranja\\n\";\n        break;\n    case \"manzana\":\n        echo \"la fruta es una manzana\\n\";\n        break;\n    case \"limon\":\n        echo \"la fruta es un lima\\n\";\n        break;\n}\n\n//Iterativas\n//while\necho \"----while----\\n\";\n$numero4 = 1;\nwhile ($numero4 <= 10) {\n    echo $numero4++. \"\\n\";\n}\n\n//do-while\necho \"----do-while----\\n\";\n$numero4 = 0;\ndo {\n    echo $numero4. \"\\n\";\n    $numero4++;\n} while ($numero4 <= 5);\n\n//for\necho \"----for----\\n\";\nfor ($numero4 = 1; $numero4 <= 10; $numero4++) {\n    echo $numero4. \"\\n\";\n}\n\n//foreach\necho \"----foreach----\\n\";\n$array = array(1,2,10,9);\nforeach ($array as &$valor) {\n    echo $valor. \"\\n\";\n}\n\n//excepciones\necho \"----try catch----\\n\";\necho \"----division por 0----\\n\";\n$a = 10;\n$b = 0;\ntry {\n    if ($b === 0) {\n        throw new Exception(\"no se admiten divisiones por 0\");\n    }\n    echo $a / $b;\n} catch (Exception $e) {\n    echo \"ha habido una excepcion: \" .$e->getMessage(). \"\\n\";\n}\n\necho \"----Dificultad extra----\\n\";\nfor ($numero = 10; $numero <= 55; $numero++) {\n    if ($numero % 2 == 0 and $numero != 16 and $numero % 3 != 0) {\n        echo $numero. \"\\n\";\n    }\n}\n\n\n?>"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/php/miguelex.php",
    "content": "<?php\n\n/* En PHP podemos encontrar los siguientes tipos de operadores:\nOperadores aritméticos\nOperadores de asignación\nOperadores bit a bit\nOperadores de comparación\nOperadores de incremento/decremento\nOperadores lógicos\nOperadores para strings\nOperadores para arrays\n*/\n\n// Operadores aritmeticos\n\n$num1 = 5;\n$num2 = 2;\n\necho \"--- Operadores aritméticos ---\\n\";\necho \"Usaremos los valores $num1 y $num2 para las operaciones\\n\";\necho \"Suma: \" . ($num1 + $num2).\"\\n\";\necho \"Resta: \" . ($num1 - $num2).\"\\n\";\necho \"Multiplicación: \" . ($num1 * $num2).\"\\n\";\necho \"División: \" . ($num1 / $num2).\"\\n\";\necho \"Módulo: \" . ($num1 % $num2).\"\\n\";\necho \"Exponenciación: \" . ($num1 ** $num2).\"\\n\";\necho \"Identidad: \" . (+$num1).\"\\n\";\necho \"Negación: \" . (-$num1).\"\\n\";\n\n// Operadores de asignación\n$x = 3;\n$y = 4;\necho \"--- Operadores de asignación ---\\n\";\necho \"x = $x\\n\";\necho \"y = $y\\n\";\necho \"x += y: \" . ($x += $y).\"\\n\";\necho \"x -= y: \" . ($x -= $y).\"\\n\";\necho \"x *= y: \" . ($x *= $y).\"\\n\";\necho \"x /= y: \" . ($x /= $y).\"\\n\";\necho \"x %= y: \" . ($x %= $y).\"\\n\";\necho \"x **= y: \" . ($x **= $y).\"\\n\";\n\n// Operadores bit a bit\necho \"--- Operadores bit a bit ---\\n\";\necho \"x = $x\\n\";\necho \"y = $y\\n\";\necho \"And -> x & y: \" . ($x & $y).\"\\n\";\necho \"Or -> x | y: \" . ($x | $y).\"\\n\";\necho \"Xor -> x ^ y: \" . ($x ^ $y).\"\\n\";\necho \"Desplazamiento a izquierda -> x <<= y: \" . ($x <<= $y).\"\\n\";\necho \"Desplazamiento a derecha -> x >>= y: \" . ($x >>= $y).\"\\n\";\n\n// Operadores de comparación\necho \"--- Operadores de comparación ---\\n\";\necho \"x = $x\\n\";\necho \"y = $y\\n\";\necho \"Igual: x == y: \" . ($x == $y).\"\\n\";\necho \"Identico: x === y: \" . ($x === $y).\"\\n\";\necho \"Distinto: x != y: \" . ($x != $y).\"\\n\";\necho \"Distinto: x <> y: \" . ($x <> $y).\"\\n\";\necho \"No identico: x !== y: \" . ($x !== $y).\"\\n\";\necho \"Menor que: x < y: \" . ($x < $y).\"\\n\";\necho \"Mayor que: x > y: \" . ($x > $y).\"\\n\";\necho \"Menor o igual que x <= y: \" . ($x <= $y).\"\\n\";\necho \"Mayor o igual que x >= y: \" . ($x >= $y).\"\\n\";\necho \"x <=> y: \" . ($x <=> $y).\"\\n\";\n\n// Operadores de incremento/decremento\necho \"--- Operadores de incremento/decremento ---\\n\";\necho \"x = $x\\n\";\necho \"y = $y\\n\";\necho \"Pre-incremento: ++x: \" . (++$x).\"\\n\";\necho \"Post-incremento: x++: \" . ($x++).\"\\n\";\necho \"Pre-decremento: --x: \" . (--$x).\"\\n\";\necho \"Post-decremento: x--: \" . ($x--).\"\\n\";\n\n// Operadores lógicos\necho \"--- Operadores lógicos ---\\n\";\necho \"x = $x\\n\";\necho \"y = $y\\n\";\necho \"And: x and y: \" . ($x and $y).\"\\n\";\necho \"Or: x or y: \" . ($x or $y).\"\\n\";\necho \"Xor: x xor y: \" . ($x xor $y).\"\\n\";\necho \"&&: x && y: \" . ($x && $y).\"\\n\";\necho \"||: x || y: \" . ($x || $y).\"\\n\";\necho \"Not: !x: \" . (!$x).\"\\n\";\n\n// Operadores para strings\necho \"--- Operadores para strings ---\\n\";\necho \"x = $x\\n\";\necho \"y = $y\\n\";\necho \"Concatenación: x . y: \" . ($x . $y).\"\\n\";\necho \"Concatenación: x .= y: \" . ($x .= $y).\"\\n\";\necho \"+: +x: \" . (+$x).\"\\n\";\necho \"Repetición: x * y: \" . ($x * $y).\"\\n\";\n\n// Operadores para arrays\necho \"--- Operadores para arrays ---\\n\";\n$arr1 = array(1,2,3,4);\n$arr2 = array(1,3, 5,6,7,8);\necho \"Unión:\\n\";\nvar_dump($arr1+$arr2);\necho \"Igualdad:\\n\";\nvar_dump($arr1 == $arr2);\necho \"Identidad:\\n\";\nvar_dump($arr1 === $arr2);\necho \"Desigualdad:\\n\"; \nvar_dump($arr1!= $arr2);\necho \"Desigualdad:\\n\"; \nvar_dump($arr1 <> $arr2);\necho \"No identidad:\\n\" ;\nvar_dump($arr1 !== $arr2);\n\n// Excepciones en PHP\necho \"--- Excepciones en PHP ---\\n\";\ntry {\n    throw new Exception(\"Excepción lanzada\");\n} catch (Exception $e) {\n    echo $e->getMessage();\n}\n\n// Excepcion con finally\necho \"--- Excepcion con finally ---\\n\";\ntry {\n    throw new Exception(\"Excepción lanzada\");\n} catch (Exception $e) {\n    echo $e->getMessage();\n} finally {\n    echo \"Esto se ejecuta siempre\\n\";\n}\n\n// Estructuras de control\necho \"--- Estructuras de control ---\\n\";\n\n// if\n\necho \"--- if ---\\n\";\nif ($x > $y) {\n    echo \"x es mayor que y\\n\";\n} elseif ($x == $y) {\n    echo \"x es igual que y\\n\";\n} else {\n    echo \"x es menor que y\\n\";\n}\n\n// switch\necho \"--- switch ---\\n\";\nswitch ($x) {\n    case 1:\n        echo \"x es 1\\n\";\n        break;\n    case 2:\n        echo \"x es 2\\n\";\n        break;\n    default:\n        echo \"x no es ni 1 ni 2\\n\";\n}\n\n// while\necho \"--- while ---\\n\";\n$i = 0;\nwhile ($i < 10) {\n    echo $i.\"\\n\";\n    $i++;\n}\n\n// do while\necho \"--- do while ---\\n\";\n$i = 0;\ndo {\n    echo $i.\"\\n\";\n    $i++;\n} while ($i < 10);\n\n// for\necho \"--- for ---\\n\";\nfor ($i = 0; $i < 10; $i++) {\n    echo $i.\"\\n\";\n}\n\n// foreach\necho \"--- foreach ---\\n\";\n$arr = array(1,2,3,4,5,6,7,8,9,10);\nforeach ($arr as $value) {\n    echo $value.\"\\n\";\n}\n\n// foreach con clave\necho \"--- foreach con clave ---\\n\";\n$arr = array(1,2,3,4,5,6,7,8,9,10);\nforeach ($arr as $key => $value) {\n    echo \"Clave: $key, Valor: $value\\n\";\n}\n\n// break\necho \"--- break ---\\n\";\nfor ($i = 0; $i < 10; $i++) {\n    if ($i == 5) {\n        break;\n    }\n    echo $i.\"\\n\";\n}\n\n// continue\necho \"--- continue ---\\n\";\nfor ($i = 0; $i < 10; $i++) {\n    if ($i == 5) {\n        continue;\n    }\n    echo $i.\"\\n\";\n}\n\n// goto\necho \"--- goto ---\\n\";\nfor ($i = 0; $i < 10; $i++) {\n    if ($i == 5) {\n        goto end;\n    }\n    echo $i.\"\\n\";\n}\nend:\necho \"Fin del bucle\\n\";\n\n// return\necho \"--- return ---\\n\";\nfunction suma($x, $y) {\n    return $x + $y;\n}\necho suma(5, 6).\"\\n\";\n\n// Operador ternario \necho \"Ternario: \".($x > $y ? \"x es mayor que y\" : \"x es menor o igual que y\").\"\\n\";\n\n// Extra\necho \"--- Extra ---\\n\";\nfor ($i = 10; $i <= 55; $i++){\n    if (($i % 2 == 0) && ($i != 16) && ($i % 3 != 0))\n        echo $i.\"\\n\";\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/php/pabloTaber.php",
    "content": "<?php\n\n/* - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n    Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...*/\n\n    //Aritmeticos\n    +$a; //Identidad, convierte a Int o Float.\n    -$a; //Negación\n    $suma = $a + $b; \n    $resta = $a - $b;\n    $multiplicacion = $a * $b;\n    $division = $a / $b;\n    $modulo = $a % $b;\n    $exponenciacion = $a ** $b; //Eleva el valor de $a con $b.\n\n    //Logicos\n    $and = $a && $b;\n    $or = $a || $b;\n    $not = !$a;\n    $xor = $a xor $b; //Devuelve true si $a o $b son true, pero no ambos.\n\n    //Comparacion\n    $iguales = $a == $b; //Devuelve true si $a es igual a $b, pero realiza conversión de tipos.\n    $identicos = $a === $b; \n    $diferentes = $a != $b; //Opuesto a ==\n    $noIdentico = $a !== $b; //Opuesto a ===\n    $menor = $a < $b;\n    $menorIgual = $a <= $b;\n    $mayor = $a > $b;\n    $mayorIgual = $a >= $b;\n    $naveEspacial = $a <=> $b; //Devuelve -1 si $a < $b, devuelve 1 si $a > $b y devuelve 0 si son iguales.\n    $fusionNull = $a ?? $b; //Devuelve $a si $a !== null, si $a === null entonces devuelve $b.\n\n    //Asignacion\n    $a = 2;\n\n    //bit a bit\n    $and = $a & $b; //Los bits que están activos en $a y $b se activan.\n    $or = $a | $b; //Los bits que están activos en $a o $b se activan.\n    $xor = $a ^ $b; //Los bits que están activos en $a o $b, pero no en ambos, se activan.\n    $not = ~ $a; //Los bits que están activos en $a se desactivan, y viceversa.\n    $desplazamientoIzquierda = $a << $b; //Desplaza los bits de $a $b veces a la izquierda, equivale a multiplicar por 2.\n    $desplazamientoDerecha = $a >> $b; //Desplaza los bits de $a $b veces a la derecha, equivale a dividir por 2.\n\n    //Incremento/Decremento\n    $preDecremento = ++$a; \n    $postDecremento = $a++;\n    $preDecremento = --$a;\n    $postDecremento = $a--;\n\n    //Para Strings\n    $concatenar = \"Hola \".\"a todos\";\n    $concatenar .= \"!\"; //Equivalente a $concatenar = $concatenar.\"!\"\n\n    //Para Arrays\n    $union = $a + $b;\n    $igualdad = $a == $b; //Si $a y $b tienen las mismas parejas clave/valor.\n    $identidad = $a === $b; //cumple la igualdad, pero ademas están en el mismo orden y son del mismo tipo.\n    $desigualdad = $a != $b;\n    $noIdenticos = $a !== $b;\n\n\n/* - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n    que representen todos los tipos de estructuras de control que existan\n    en tu lenguaje:\n    Condicionales, iterativas, excepciones...\n  - Debes hacer print por consola del resultado de todos los ejemplos.*/\n\n    //Condicionales\n    $edad = 44;\n    if ($edad < 18) {\n        echo \"Menor de edad\";\n    } else if ($edad > 65) {\n        echo \"Edad de juvilación\";\n    } else {\n        echo \"Edad laboral\";\n    }\n\n    switch ($a) {\n        case 0:\n            echo \"a vale 0\";\n            break;\n        \n        case 1:\n            echo \"a vale 1\";\n            break;\n            \n        default:\n            echo \"a no vale ni 0 ni 1\";\n            break;\n    }\n\n    //Bucles\n\n    //Ejemplos de distintos bucles imprimiendo los numeros del 1 al 10.\n    for ($i=1; $i < 11; $i++) { \n        echo $i;\n    }\n\n    $i = 1;\n    while ($i <= 10) {\n        echo $i++;\n    }\n\n    $i=1;\n    do {\n        echo $i++;\n    } while ($i <= 10);\n\n    $arr = [1, 2, 3, 4, 5];\n    foreach ($arr as $clave => $valor) {\n        echo \"Clave: $clave / valor: $valor\";\n    }\n\n/* - DIFICULTAD EXTRA (opcional):\n    Crea un programa que imprima por consola todos los números comprendidos\n    entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3. */\n\n    for ($i=10; $i < 56; $i++) { \n        if ($i % 2 === 0 && $i !== 16 && $i % 3 !== 0) {\n            echo $i.PHP_EOL;\n        }\n    }\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/php/qv1ko.php",
    "content": "<?php\n\n    $a = 3;\n    $b = 4;\n\n    echo \"\\nNumber A: \" . $a;\n    echo \"\\nNumber B: \" . $b;\n\n    $sum = $a + $b;\n    echo \"\\n$a + $b = \" . $sum;\n\n    $sub = $a - $b;\n    echo \"\\n$a - $b = \" . $sub;\n\n    $mul = $a * $b;\n    echo \"\\n$a * $b = \" . $mul;\n\n    $div = $a / $b;\n    echo \"\\n$a / $b = \" . $div;\n\n    $res = $a % $b;\n    echo \"\\n$a % $b = \" . $res;\n\n    $pow = $a ** $b;\n    echo \"\\n$a ** $b = \" . $pow;\n\n    $a += $b;\n    echo \"\\n$a += $b\\t Number A: \" . $a;\n\n    $a -= $b;\n    echo \"\\n$a -= $b\\t Number A: \" . $a;\n\n    $a *= $b;\n    echo \"\\n$a *= $b\\t Number A: \" . $a;\n\n    $a /= $b;\n    echo \"\\n$a /= $b\\t Number A: \" . $a;\n\n    $a %= $b;\n    echo \"\\n$a %= $b\\t Number A: \" . $a;\n\n    $a++;\n    echo \"\\n$a++\\t Number A: \" . $a;\n\n    $b--;\n    echo \"\\n$b--\\t Number B: \" . $b;\n\n    if ($a == $b) {\n        echo \"\\nNumber A equals number B\";\n    }\n\n    if ($a === $b) {\n        echo \"\\nNumber A is equal to the number B and they are of the same kind\";\n    } else {\n        echo \"\\nNumber A is equal to number B and they are not of the same type\";\n    }\n\n    echo ($a != $b) ? \"\\nThe number A is different from the number B\" : \"\\nThe number A is not different from the number B\";\n\n    echo ($a <> $b) ? \"\\nThe number A is different from the number B\" : \"\\nThe number A is not different from the number B\";\n\n    echo ($a !== $b) ? \"\\nThe number A and its type are different from the number B\" : \"\\nThe number A and its type are not different from the number B\";\n\n    if ($a > $b) {\n        echo \"\\nThe number A is greater than the number B\";\n    } else if ($a < $b) {\n        echo \"\\nThe number A is less than the number B\";\n    } else {\n        echo \"\\nNumber A equals number B\";\n    }\n\n    while ($a > 0 and $b > 0) {\n        echo \"\\nLoop while\";\n        $a--;\n    }\n\n    do {\n        echo \"\\nLoop do while\";\n        $a++;\n        $b++;\n    } while ($a < 3 || $b < 0);\n\n    do {\n        echo \"\\nLoop do while\";\n        $a++;\n        $b--;\n    } while ($a xor $b);\n\n    switch ($a <=> $b) {\n        case -1:\n            echo \"\\nNumber A is less than number B\";\n            break;\n\n        case 0:\n            echo \"\\nNumber A is equal to the number B\";\n            break;\n\n        case 1:\n            echo \"\\nNumber A is greater than the number B\";\n            break;\n\n        default:\n            break;\n\n    }\n\n    for ($i = 0; $i < 3; $i++) {\n        echo \"\\nLoop for \" . $i;\n    }\n      \n\n    foreach ([1, 2, 3] as $num) {\n        echo \"\\nLoop for each \" . $num;\n    }\n\n    checkNum(2);\n\n    program();\n\n    function checkNum($n) {\n        if ($n > 3) {\n            throw new Exception(\"\\nThe value must be equal to or less than 3\");\n        }\n        return true;\n    }\n\n    function program() {\n        echo \"\\nProgram:\\n\";\n        for ($i = 10; $i <= 55; $i++) {\n            if ($i % 2 == 0 && $i != 16 && $i % 3 != 0) {\n                echo $i . \"\\t\";\n            }\n        }\n    }\n\n?>\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/php/rocallejas.php",
    "content": "<?php\n# Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n# Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits.\n\n    // Operadores aritméticos\n        echo \"**************** Operadores aritméticos ****************  <br>\";\n        $a = 16;\n        $b = 8;\n\n        // Suma\n        $resultadoSuma = $a + $b;\n        echo \"Resultado de la suma de $a mas $b es: $resultadoSuma <br>\";\n\n        // Resta\n        $resultadoResta = $a - $b;\n        echo \"Resultado de la resta de $a menos $b es: $resultadoResta <br>\";\n\n        // Multiplicación\n        $resultadoMultiplicacion = $a * $b;\n        echo \"Resultado de la multiplicación de $a por $b es: $resultadoMultiplicacion <br>\";\n\n        // División\n        $resultadoDivision = $a / $b;\n        echo \"Resultado de la división de $a entre $b es: $resultadoDivision <br>\";\n\n        // Módulo (resto de la división)\n        $resultadoModulo = $a % $b;\n        echo \"Resultado de $a módulo de $b es: $resultadoModulo <br>\";\n\n    // Operadores de comparación\n        echo \"<br> **************** Operadores de comparación **************** <br>\";\n        $x = 16;\n        $y = \"16\";\n\n        // Igual ==\n        $resultadoIgual = ($x == $y);\n        echo \"Resultado de la igualdad: \" . ($resultadoIgual ? 'true' : 'false') . \" <br>\";\n\n        // Comparación de identidad (valor y tipo) con ===\n        $resultadoIdentico = ($x === $y);\n        echo \"Resultado de la identidad: \" . ($resultadoIdentico ? 'true' : 'false') . \" <br>\";\n\n        // Diferente !=\n        $resultadoDiferente = ($x != $y);\n        echo \"Resultado de la diferencia: \" . ($resultadoDiferente ? 'true' : 'false') . \" <br>\";\n\n        // No idéntico !==\n        $resultadoNoIdentico = ($x !== $y);\n        echo \"Resultado de la no identidad: \" . ($resultadoNoIdentico ? 'true' : 'false') . \" <br>\";\n\n        // Mayor que >\n        $resultadoMayorQue = ($x > $y);\n        echo \"Resultado de mayor que: \" . ($resultadoMayorQue ? 'true' : 'false') . \" <br>\";\n\n        // Menor que <\n        $resultadoMenorQue = ($x < $y);\n        echo \"Resultado de menor que: \" . ($resultadoMenorQue ? 'true' : 'false') . \" <br>\";\n\n        // Mayor o igual que >=\n        $resultadoMayorIgual = ($a >= $b);\n        echo \"Resultado de mayor o igual que: \" . ($resultadoMayorIgual ? 'true' : 'false') . \" <br>\";\n\n        // Menor o igual que <=\n        $resultadoMenorIgual = ($a <= $b);\n        echo \"Resultado de menor o igual que: \" . ($resultadoMenorIgual ? 'true' : 'false') . \" <br>\";\n\n    // Operadores lógicos\n        echo \"<br> **************** Operadores lógicos **************** <br>\";\n\n        $p = true;\n        $q = false;\n\n        // AND lógico (&&)\n        $resultadoAnd = ($p && $q);\n        echo \"Resultado del AND lógico: \" . ($resultadoAnd ? 'true' : 'false') . \" <br>\";\n\n        // OR lógico (||)\n        $resultadoOr = ($p || $q);\n        echo \"Resultado del OR lógico: \" . ($resultadoOr ? 'true' : 'false') . \" <br>\";\n\n        // NOT lógico (!)\n        $resultadoNot = !$p;\n        echo \"Resultado del NOT lógico: \" . ($resultadoNot ? 'true' : 'false') . \" <br>\";\n\n    // Operadores de asignación\n        echo \"<br> **************** Operadores de asignación **************** <br>\";\n\n        $variable = 8;\n\n        // Asignación simple\n        $variable = 16;\n        echo \"Valor actual de la variable: $variable <br>\";\n\n        // Asignación con suma\n        $variable += 3;\n        echo \"Valor después de la asignación con suma: $variable <br>\";\n\n        // Asignación con resta\n        $variable -= 2;\n        echo \"Valor después de la asignación con resta: $variable <br>\";\n\n        // Asignación con multiplicación\n        $variable *= 4;\n        echo \"Valor después de la asignación con multiplicación: $variable <br>\";\n\n        // Asignación con división\n        $variable /= 2;\n        echo \"Valor después de la asignación con división: $variable <br>\";\n\n    // Operadores de pertenencia\n        echo \"<br> **************** Operadores de pertenencia **************** <br>\";\n\n        $array = array(1, 2, 3, 4, 5);\n\n        // Verificar si un valor está en un array con in_array()\n        $resultadoPertenencia = in_array(3, $array);\n        echo \"Resultado de la pertenencia en array: \" . ($resultadoPertenencia ? 'true' : 'false') . \" <br>\";\n\n    // Operadores de Bits\n        echo \"<br> **************** Operadores de Bits **************** <br>\";\n        /*\n            Los operadores de bits son menos comunes en aplicaciones cotidianas,\n            pero pueden ser útiles en situaciones específicas donde se trabaje directamente\n            con representaciones binarias de datos\n        */\n        $numero1 = 5;   // Representación binaria: 0101\n        $numero2 = 3;   // Representación binaria: 0011\n\n        // Operador AND a nivel de bits &\n        $resultadoAndBits = $numero1 & $numero2;\n        echo \"Resultado del AND a nivel de bits: $resultadoAndBits <br>\";\n\n        // Operador OR a nivel de bits |\n        $resultadoOrBits = $numero1 | $numero2;\n        echo \"Resultado del OR a nivel de bits: $resultadoOrBits <br>\";\n\n        // Operador XOR a nivel de bits ^\n        $resultadoXorBits = $numero1 ^ $numero2;\n        echo \"Resultado del XOR a nivel de bits: $resultadoXorBits <br>\";\n\n        // Desplazamiento a la izquierda <<\n        $resultadoDesplazamientoIzquierda = $numero1 << 1;\n        echo \"Resultado del desplazamiento a la izquierda: $resultadoDesplazamientoIzquierda <br>\";\n\n        // Desplazamiento a la derecha >>\n        $resultadoDesplazamientoDerecha = $numero1 >> 1;\n        echo \"Resultado del desplazamiento a la derecha: $resultadoDesplazamientoDerecha <br>\";\n\n# Utilizando las operaciones con operadores que tú quieras, crea ejemplos que representen todos los tipos\n# de estructuras de control que existan en tu lenguaje: Condicionales, iterativas, excepciones\n\n    // Condicionales\n        echo \"<br> **************** Condicionales **************** <br>\";\n\n        // if, else y elseif\n        echo \"---- if, else y elseif ----  <br>\";\n        $edad = 35;\n\n        if ($edad < 18) {\n            echo \"Eres menor de edad. <br>\";\n        } elseif ($edad >= 18 && $edad < 65) {\n            echo \"Eres adulto. <br>\";\n        } else {\n            echo \"Eres un adulto mayor. <br>\";\n        }\n\n        // SWITCH\n        echo \"---- switch ----  <br>\";\n\n        $marca = \"Toyota\";\n\n        switch ($marca) {\n            case \"Toyota\":\n                echo \"Seleccionaste un vehículo de la marca Toyota <br>\";\n                break;\n            case \"Honda\":\n                echo \"Seleccionaste un vehículo de la marca Honda <br>\";\n                break;\n            case \"Nissan\":\n                echo \"Seleccionaste un vehículo de la marca Nissan <br>\";\n                break;\n            default:\n                echo \"La marca seleccionada no es una marca japonesa conocida <br>\";\n                break;\n        }\n\n    // Iterativas\n        echo \"<br> **************** Iterativas **************** <br>\";\n\n        // Bucle FOR\n        echo \"Resultado del bucle FOR: \";\n        for ($i = 1; $i <= 5; $i++) {\n            echo $i . \" \";\n        }\n        echo \" <br>\";\n\n        // Bucle WHILE\n        echo \"Resultado del bucle WHILE: \";\n        $num = 1;\n        while ($num <= 5) {\n            echo $num . \" \";\n            $num++;\n        }\n        echo \" <br>\";\n\n        // Bucle DO-WHILE\n        echo \"Resultado del bucle DO-WHILE: \";\n        $num = 1;\n        do {\n            echo $num . \" \";\n            $num++;\n        } while ($num <= 5);\n        echo \" <br>\";\n\n        // Bucle FOREACH\n        echo \"Resultado del bucle FOREACH:  <br>\";\n        $colores = array(\"Rojo\", \"Verde\", \"Azul\");\n\n        foreach ($colores as $color) {\n            echo \"Color: $color <br>\";\n        }\n\n    // Excepciones try, catch, finally\n        echo \"<br> **************** Excepciones try, catch, finally **************** <br>\";\n            function dividir($a, $b) {\n                try {\n                    if ($b == 0) {\n                        throw new Exception(\"División por cero.\");\n                    }\n                    $resultado = $a / $b;\n                    echo \"Resultado: \" . $resultado;\n                } catch (Exception $ex) {\n                    echo \"Error: \" . $ex->getMessage();\n                } finally {\n                    echo \" Fin de la operación.\";\n                }\n            }\n        echo \"Resultado de dividir(10, 2): \";\n        dividir(10, 2); // Salida: Resultado: 5 Fin de la operación.\n        echo \" <br>\";\n\n        echo \"Resultado de dividir(10, 0): \";\n        dividir(10, 0); // Salida: Error: División por cero. Fin de la operación.\n        echo \" <br>\";\n\n# Reto extra\n    /*\n        Crea un programa que imprima por pantalla todos los números comprendidos\n        entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3\n    */\n    echo \"<br> **************** Reto extra **************** <br>\";\n\n    echo \"Números pares entre 10 y 55 (excluyendo el 16 y múltiplos de 3): \";\n    echo \"<ul>\"; // Abre la lista\n    for ($i = 10; $i <= 55; $i++) {\n        // Verificar si el número es par\n        $esPar = $i % 2 == 0;\n\n        // Verificar si el número no es el 16\n        $noEs16 = $i != 16;\n\n        // Verificar si el número no es múltiplo de 3\n        $noEsMultiploDe3 = $i % 3 != 0;\n\n        // Comprobar todas las condiciones\n        if ($esPar && $noEs16 && $noEsMultiploDe3) {\n            echo \"<li>$i</li>\";\n        }\n    }\n    echo \"</ul>\"; // Cierra la lista\n?>"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/php/samuel20-dev.php",
    "content": "<?php\n\n# Operadores\n\n$a = 4;\n$b = 15;\n\n// Operadores aritmeticos\nprint \"suma: 10 + 15 = \" . 10 + 15;\nprint \"resta: 10 - 15 = \" . 10 - 15;\nprint \"multiplicacion: 10 x 10 = \" . 10 * 10;\nprint \"division: 20 / 10 = \" . 20 / 10;\nprint \"modulo: 20 % 2 = \" . 20 % 2;\nprint \"exponente: 10 ** 2 = \" . 10 ** 2;\n\n// Operadores de comparacion\nprint \"igualdad: 10 == 5 es \" . (10 == 5 ? 'true' : 'false');\necho \"desigualdad: 10 != 4 es \" . (10 != 4 ? 'true' : 'false');\nprint \"mayor que: 10 > 2 es \" . (10 > 2 ? 'true' : 'false');\necho \"menor que: 3 < 1 es \" . (3 < 1 ? 'true' : 'false');\nprint \"mayor o igual que: 8 >= 7 es \" . (8 >= 7 ? 'true' : 'false');\nprint \"menor o igual que: 2 <= 2 es \" . (2 <= 2 ? 'true' : 'false');\n\n// Operadores lógicos\n\n# AND && : sirve para que dos condiciones se cumplan.\n# OR || : Sirve para que al menos una de las condiciones se cumpla\n# NOT ! : Sirve para revertir un valor booleano true a false y visebersa. \n\nprint \"&& AND: 20 + 5 == 25 && 8 - 7 == 1 es \" . (20 + 5 == 25 && 8 - 7 == 1 ? 'true' : 'false');\nprint \"|| OR: 10 - 2 == 8 || 5 - 2 == 4 es \" . (10 - 2 == 8 || 5 - 2 == 4 ? 'true' : 'false');\n\n\n// Operador de asignacion \n\n$variable_int = 22; #asignacion\n$variable_int += 8; # suma y asignacion\n$variable_int -= 2; # resta y asignacion\n$variable_int *= 2; # multiplicación y asignacion\n$variable_int /= 4; # division y asignacion\n$variable_int %= 4; # módulo y asignación\n$variable_int **= 2; # exponente y asignacion\n$variable_str = 'carlos ';\n$variable_str .= 'samuel'; #concatenacion y asignacion.\nprint $variable_str;\nprint $variable_int;\n\n/*\nOperadores de indentidad:\nNos sirve para comparar el valor de la posicion en memoria.\n*/\n$n1 = 10;\n$n2 = 10;\nprint \"10 === 10 es \" . ($n1 === $n2 ? 'true' : 'false'); # es identico\nprint \"10 !== 10 es \" . ($n1 !== $n2 ? 'true' : 'false'); # es distinto\n\n// Operadores bit a bit\n# Los operadores bit a bit nos permiten realizar operaciones a nivel de bit sobre numeros enteros. Lo que hace es transforma el int a bit y realiza una operacion que al final nos da el resultado de lo que nos dio en bit, convertido en integer.\n\n# AND -> solo si los dos valores son 1, entonces será 1.\n# OR -> si almenos un valor es 1, entonces será 1.\n# XOR -> compara bit a bit, si son diferentes entonces será 1, sino 0.\n# ~ NOT -> revierte cada bit a bit que encuentra. si esta activo, lo desactiva.\n\n\n$a = 10; #1010\n$b = 3;  #0011\n\nprint \"& AND: 10 & 3 = \" . ($a & $b); #0010\nprint \"| OR: 10 | 3 = \" . ($a | $b); #1011\nprint \"^ XOR: 10 ^ 3 = \" . ($a ^ $b); #1001\nprint \"~ NOT: ~ 10 = \" . (~$a);\n\n\n// ESTRUCTURAS DE CONTROL\n\n$a = 3;\n$b = 1;\n\n# if \nif ($a > $b) {\n   echo \"a es mayor que b\";\n}\n\n$nombre = 'juan';\nif ($nombre == 'juan') {\n   echo \"los nombres coinciden\";\n}\n\n$nombre = 'juan';\nif ($nombre != 'pablo') {\n   echo \"los nombres son distintos\";\n}\n\n# if else\n$usuario = 'usuario';\n$password = '123456';\nif (\n   $usuario == 'usuario' && $password == '12345'\n) {\n   echo \"Bienvenido\";\n} else {\n   echo \"Error al ingresar credenciales\";\n}\n\n#if elseif else\n$nombre = 'juan';\nif ($nombre == 'juan') {\n   echo \"escribiste tu primer nombre\";\n} elseif ($nombre == 'pablo') {\n   echo \"escribiste tu segundo nombre\";\n} else {\n   echo \"No ingresaste un nombre\";\n}\n\n# switch\n$opcion = '3';\nswitch ($opcion) {\n   case '1':\n      print \"opcion 1\";\n      break;\n\n   case '2':\n      print \"opcion 2\";\n      break;\n\n   case '3':\n      print \"opcion 3\";\n      break;\n\n   default:\n      print \"ingresa una opcion válida\";\n      break;\n}\n\n#ternario\n$edad = 14;\nprint $edad >= 18 ? 'Es mayor de edad' : 'Eres menor';\n\n\n// ESTRUCTURAS DE CONTROL ITERATIVAS\n\n#FOR \n\n#imprimir numeros del 1 - 10\nfor ($i = 1; $i <= 10; $i++) {\n   print $i . \"\\n\";\n}\n\n#tabla de multiplicar hasta 10\n$n_tabla = 2;\nfor ($i = 1; $i <= 10; $i++) {\n   print $n_tabla . \" x \" . $i . \" = \" . ($n_tabla * $i) . \"\\n\";\n}\n\n#suma de los primero 100 numeros\n$suma = 0;\nfor ($i = 1; $i <= 100; $i++) {\n   $suma += $i;\n}\necho \"la suma de los primeros 100 numeros es : $suma\";\n\n// WHILE\n\n#sumar numeros del 1 al 5\n$n = 1;\n\nwhile ($n <= 5) {\n   print $n++;\n}\n\n#mostrar los numeros pares del 1 al 20\n$n = 2;\n$pares = \"\";\n\nwhile ($n <= 20) {\n   if ($n % 2 == 0) {\n      $pares .= $n . \"\\n\";\n   }\n   $n++;\n}\nprint $pares;\n\n#factorial de un numero \n$factorial = 6;\n$resul = 1;\n\nwhile ($factorial >= 1) {\n   $resul *= $factorial;\n   $factorial--;\n}\necho \"el resultado es: $resul\";\n\n#Serie fibonacci de los primero 100 numeros.\n$n_factorial = 10;\n$a = 0;\n$b = 1;\n$result = 0;\n$contador = 2;\n$total_fibonacci = \"$a, $b, \";\n\nwhile ($contador <= $n_factorial) {\n   $result = $a + $b;\n   $a = $b;\n   $b = $result;\n   $total_fibonacci .= \"$result, \";\n   $contador++;\n}\nprint $total_fibonacci;\n\n# Numero primo\n$n_primo = 100;\n$resul = \"es primo\";\n\nfor ($i = 2; $i <= sqrt($n_primo); $i++) {\n   if ($n_primo % $i == 0) {\n      $resul = \"no es primo\";\n      break;\n   }\n}\necho $resul;\n\n# foreach\n$array = array(1, 2, 3, 4);\n\nforeach ($array as $valor) {\n   $valor = $valor * 2;\n   echo $valor;\n}\n\n// Menejo de excepciones - try catch\n\nfunction dividir($numero)\n{\n   if (!$numero) {\n      throw new Exception(\"Error division por 0 \\n\");\n   }\n   return 1 / $numero;\n}\n\ntry {\n   echo dividir(12) . \"\\n\";\n} catch (Exception $e) {\n   echo \"Excepción capturada: \" . $e->getMessage();\n} finally {\n   echo \"finalizó el manejo de excepciones \\n\";\n}\nprint \"sigue funcionando\";\n\n# Ejercicio con Try catch\n\n/*\nCrea una función que reciba dos números y un operador (+, -, *, /) como parámetros. La función debe realizar la operación correspondiente, pero debe lanzar una excepción si:\n\nEl operador no es válido.\nSe intenta dividir por cero.\n*/\n\nfunction calculadora($n1, $n2, $operador)\n{\n\n   #validacion\n   if ($n1 == 0 || $n2 == 0) {\n      throw new Exception(\"Ingresa un numero mayor a 0\");\n      return;\n   }\n\n   switch ($operador) {\n      case \"+\":\n         return  $n1 + $n2;\n         break;\n      case \"-\":\n         return  $n1 - $n2;\n         break;\n      case \"*\":\n         return $n1 * $n2;\n         break;\n      case \"/\":\n         return  $n1 / $n2;\n         break;\n      default:\n         throw new Exception(\"El operador no es válido\");\n         break;\n   }\n}\n\ntry {\n   echo calculadora(5, 4, \"%\");\n} catch (Throwable $t) {\n   print \"Error: \" . $t->getMessage();\n}\n\n\n\n\n/* DIFICULTAD EXTRA (opcional):\nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n*/\n\nfor ($i = 10; $i < 56; $i++) {\n   if ($i % 2 == 0 && $i % 3 !== 0 && $i != 16) {\n      print \"$i \\n\";\n   }\n}\n\n/* EJERCICIO EXTRA:\nImprime todos los números entre 1 y 50 que sean múltiplos de 5.\n*/\n\nfor ($i = 1; $i < 51; $i++) {\n   if ($i % 5 == 0) {\n      echo \"$i \\n\";\n   }\n}\n\n/*\nEjercicio extra: Suma de múltiplos de 7\nCalcula la suma de todos los múltiplos de 7 entre 1 y 100.\n*/\n$suma = 0;\nfor ($i = 1; $i <= 100; $i++) {\n   if ($i % 7 == 0) {\n      $suma += $i;\n   }\n}\necho \"la sumatoria de los multiplos de 7 es: $suma\";\n\n\n/*\nEjercicio extra: Múltiplos de 8 hasta un número dado\nPide al usuario un número máximo y, a partir de 1, imprime todos los múltiplos de 8 que sean menores o iguales a ese número.\n*/\n\nfunction multiplos_ocho($limite)\n{\n   for ($i = 1; $i <= $limite; $i++) {\n      if ($i % 8 == 0) {\n         echo \"$i \\n\";\n      }\n   }\n}\n\nmultiplos_ocho(40);\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/prolog/blfuentes.pl",
    "content": "%\n%EJERCICIO:\n%- Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n%  Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n%  (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n%- Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n%  que representen todos los tipos de estructuras de control que existan\n%  en tu lenguaje:\n%  Condicionales, iterativas, excepciones...\n%- Debes hacer print por consola del resultado de todos los ejemplos.\n%\n%DIFICULTAD EXTRA:\n%Crea un programa que imprima por consola todos los números comprendidos\n%entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n%\n%Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n%\n\n% OPERADORES LóGICOS\n% AND ,\nambos_son_0(X, Y) :-\n    X =:= 0,\n    Y =:= 0.\n% OR ;\nuno_es_0(X, Y) :-\n    X =:= 0;\n    Y =:= 0.\n% mayor que >\nmayor_que(X, Y) :- X > Y.\n% menor que <\nmenor_que(X, Y) :- X < Y.\n% mayor o igual >=\nmayor_igual_que(X, Y) :- X >= Y.\n% menor o igual =<\nmenor_igual_que(X, Y) :- X =< Y.\n% igual que =:=\nigual_que(X, Y) :- X =:= Y.\n% diferente =\\= (aritmético)\ndiferente_que(X, Y) :- X =\\= Y.\n% diferente \\= (términos)\ndiferente_que_t(X, Y) :- X \\= Y.\n% OPERADORES ARITMéTICOS\n% añadir +\nanadir(X, Y, R) :- R is X + Y.\n% sustraer -\nsustraer(X, Y, R) :- R is X - Y.\n% multiplicar *\nmultiplicar(X, Y, R) :- R is X * Y.\n% dividir /\ndividir(X, Y, R) :- R is X / Y.\n% potencia **\npotencia(X, Y, R) :- R is X**Y.\n% division entera //\ndivision_entera(X, Y, R) :- R is X // Y.\n% módulo mod\nmodulo(X, Y, R) :- R is X mod Y.\n% negacion\nno_entero(X) :- not(integer(X)).\n\n% PERTENENCIA\n% cabeza de lista\nlist_member(X, [X|_]).\n% parte de la cola\nlist_member(X,[_|TAIL]) :- list_member(X, TAIL).\n\n% ESTRUCTURAS DE CONTROL\n% en prolog no hay estructuras de control, se basa en la recursion\n% se simula el if-then con predicados and/or\nes_par(X) :-\n    (X mod 2 =:= 0 -> \n        write(\"es par\"), nl\n    ; \n        write(\"no es par\"), nl\n    ).\n\n% BUCLES\n% hay que simularlo con recursión\ncontar_desde_hasta(LOW, HIGH) :-\n    LOW > HIGH.\ncontar_desde_hasta(LOW, HIGH) :-\n    LOW =< HIGH,\n    writeln(LOW),  \n    NextLow is LOW + 1,\n    contar_desde_hasta(NextLow, HIGH).\n\n% EXCEPCIONES\n% no existen, hay que simularlas con cláusulas de failure\nnumero_positivo(X) :-\n    X > 0, !.  % success si se cumple\nnumero_positivo(X) :-\n    atom_concat('Exception. No es positivo: ', X, ERROR),\n    writeln(ERROR), nl,\n    fail.     % Fallo!\n\n% ejercicio\nnumero_valido(X) :-\n    X mod 2 =:= 0, X =\\= 16, X mod 3 =\\= 0.\n\nmostrar_pares_no16_nomultiplo3(DESDE, HASTA) :-\n    DESDE > HASTA.\nmostrar_pares_no16_nomultiplo3(DESDE, HASTA) :-\n    DESDE =< HASTA,\n    (numero_valido(DESDE) ->\n        writeln(DESDE),\n        NextDESDE is DESDE + 1,\n        mostrar_pares_no16_nomultiplo3(NextDESDE, HASTA)\n    ;\n    NextDESDE is DESDE + 1,\n    mostrar_pares_no16_nomultiplo3(NextDESDE, HASTA)).\n\n% otra forma de hacerlo simplificado\nmostrar_pares_no16_nomultiplo3_simplificado(DESDE, HASTA, NUM) :-\n    between(DESDE, HASTA, NUM),\n    NUM mod 2 =:= 0, NUM \\= 16, NUM mod 3 =\\= 0.\n% ejecutar con \n% forall(mostrar_pares_no16_nomultiplo3_simplificado(10, 55, Number), writeln(Number)).\n\n main :- write(\"¡OPERADORES Y ESTRUCTURAS DE CONTROL!\")."
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/ JesusAcst.py",
    "content": "# Operadores arimeticos\nprint(\"Operadores Aritméticos:\")\nprint(f\"Suma: 13 + 7 = {13 + 7}\")\nprint(f\"Resta: 13 - 7 = {13 - 7}\")\nprint(f\"Multiplicación: 13 * 7 = {13 * 7}\")\nprint(f\"División: 13 / 7 = {13 / 7}\")\nprint(f\"División entera: 13 // 7 = {13 // 7}\")\nprint(f\"Módulo: 13 % 7 = {13 % 7}\")\nprint(f\"Potencia: 13 ** 7 = {13 ** 7}\")\n\n# Operadores de comparación\nprint(\"Operadores de Comparación:\")\nprint(f\"Igualdad: 13 == 7 es {13 == 7}\")\nprint(f\"Desigualdad: 13 != 7 es {13 != 7}\")\nprint(f\"Mayor que: 13 > 7 es {13 > 7}\")\nprint(f\"Menor que: 13 < 7 es {13 < 7}\")\nprint(f\"Mayopr o igual: 13 >= 7 es {13 >= 7}\")\nprint(f\"Menor o igual: 13 <= 7 es {13 <= 7}\")\n\n# Operadores de asignación\nprint(\"Operadores de Asignación:\")\nnumber = 13  # Asignación\nprint(f\"Valor inicial: {number}\")\nnumber += 7  # Suma y asignación\nprint(f\"Después de += 7: {number}\")\nnumber -= 7  # Resta y asignación\nprint(f\"Después de -= 7: {number}\")\nnumber *= 7  # Multiplicación y asignación\nprint(f\"Después de *= 7: {number}\")\nnumber /= 7  # División y asignación\nprint(f\"Después de /= 7: {number}\")\nnumber //= 7  # División entera y asignación\nprint(f\"Después de //= 7: {number}\")\nnumber %= 7  # Módulo y asignación\nprint(f\"Después de %= 7: {number}\")\nnumber **= 7  # Exponente y asignación\nprint(f\"Después de **= 7: {number}\")\n\n# Operadores de Identidad\nprint(\"Operadores de Identidad:\")\nnew_number = 13  # Asignación   \nprint(f\"number is new_number: {number is new_number}\")\nprint(f\"number is not new_number: {number is not new_number}\")\n\n# Operadores de Pertenencia\nprint(\"Operadores de Pertenencia:\")\nprint(f\"'Y' in 'Python' = {'y' in 'python'}\") # verifica si la letra 'y' está presente en la palabra 'python', y devuelve True o False dependiendo del resultado\nprint(f\"'B' not in 'Python' = {'b' not in 'python'}\") # verifica si la letra 'b' no está presente en la palabra 'python', y devuelve True o False dependiendo del resultado\n\n# Operadores de bit\nprint(\"Operadores de Bit:\")\nprint(f\"AND: 13 & 7 = {13 & 7}\") # 13 en bit es 1101 y 7 en bit es 0111, el resultado es 0101 que es 5 en decimal\nprint(f\"OR: 13 | 7 = {13 | 7}\") # 13 en bit es 1101 y 7 en bit es 0111, el resultado es 1111 que es 15 en decimal\nprint(f\"XOR: 13 ^ 7 = {13 ^ 7}\") # 13 en bit es 1101 y 7 en bit es 0111, el resultado es 1010 que es 10 en decimal\nprint(f\"NOT: ~ 13 = {~13}\") # 13 en bit es 1101, el resultado es 0010 que es -14 en decimal (en complemento a dos)\nprint(f\"Desplazamiento a la izquierda: 13 << 2 = {13 << 2}\") # 13 en bit es 1101, el resultado es 110100 que es 52 en decimal\nprint(f\"Desplazamiento a la derecha: 13 >> 2 = {13 >> 2}\") # 13 en bit es 1101, el resultado es 11 que es 3 en decimal\n\n\n\"\"\"\nEstructuras de control:\n- Condicionales: if, elif, else\n- Iterativas: for, while\n- Excepciones: try, except, finally\n\"\"\"\n\n# Condicionales\nprint(\"Condicionales:\")\nmy_string = 'Python'\nif my_string == 'Python':\n    print(\"La cadena es Python\")\nelif my_string == 'Java':\n    print(\"La cadena es Java\")\nelse:\n    print(\"La cadena no es Python ni Java\")\n\n# Iterativas\nprint(\"Iterativas\")\nfor i in range(11):\n     print(i)\n\ni = 0\nwhile i < 11:\n    i += 1\n    print(i)\n\n# Manejo de Excepciones\nprint(\"Manejo de Excepciones:\")\ntry:\n    print(10 / 0)\nexcept ZeroDivisionError:\n    print(\"No se puede dividir por cero\")\nfinally:\n    print(\"Finalizó el manjeo de excepciones\")\n\nprint(\"Dificultad extra:\")\nfor i in range(10, 55):\n    if i % 2 == 0 and i != 16 and i % 3 != 0: # Si i es par, no es 16 y no es múltiplo de 3, entonces se imprime\n        print(i)\n    \n    \n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/13sauca13.py",
    "content": "a = 1\nb = 2\nprint(\"Dadas las variables a=1 y b=2:\\n\")\n\n# Operadores aritméticos:\nsuma = a+b\nresta = a-b\nmultiplicacion = a*b\ndivision = a/b\nmodulo = a%b\ndiv_entera = a//b\nexponenciacion = a**b\nprint(f\"\"\"Las operaciones aritméticas realizables son:\n      Suma: {suma}\n      Resta: {resta}\n      Multiplicación: {multiplicacion}\n      Division: {division}\n      Modulo: {modulo}\n      Division entera: {div_entera}\n      Exponenciacion: {exponenciacion}\\n\"\"\")\n\n# Operadores lógicos\ny = a and b\no = a or b\nno = not a\nprint(f\"\"\"Las operaciones lógicas básicas realizables son:\n      AND: {y}\n      OR: {o}\n      NOT: {no}\\n\"\"\")\n\n# Operadores de comparacion\nmayor_que = a>b\nmayor_o_igual = a>=b\nmenor_que = a<b\nmenor_o_igual = a<=b\nigualdad = a==b\ndesigualdad = a!=b\nprint(f\"\"\"Las operaciones de comparacion realizables son:\n      Mayor que: {mayor_que}\n      Mayor o igual que: {mayor_o_igual}\n      Menor que: {menor_que}\n      Menor o igual que: {menor_o_igual}\n      Igualdad: {igualdad}\n      Desigualdad: {desigualdad}\\n\"\"\")\n\n# Operadores de asignación\nasignacion = \"simbolo =\"\na += b\na -= b\na *= b\nprint(f\"\"\"En principio la asignación se hace con {asignacion}\n      Es posible agregar cualquier operación aritmética a la vez que se asigna valor de manera que se asignará a la variable su propio valor con la operación realizada\"\"\")\n\n# Operadores de identidad\nes = a is b\nno_es = a is not b\nprint(f\"\"\"Las operaciones de identidad realizables son:\n      Es: {es}\n      No es: {no_es}\"\"\")\n\n# Operadores de pertenencia\na = \"gato\"\nb = \"perro\"\nen = a in b\nno_en = a not in b\nprint(f\"\"\"Las operaciones de pertenencia son para elementos iterables, tenemos que cambiar las variables a a=\"gato\" y b=\"perro\":\n      En: {en}\n      No en: {no_en}\"\"\")\n\n# Operadores bitwise\na = 1\nb = 2\nbit_and = a&b\nbit_or = a|b\nbit_not = ~a\nbit_xor = a^b\nprint(f\"\"\"Las operaciones bitwise (bit a bit) son con la forma binaria de las variables:\n      AND: {bit_and}\n      OR: {bit_or}\n      NOT: {bit_not}\n      XOR: {bit_xor}\"\"\")\n\n# Estructuras de control\n\n# Condicionales\nif a<b:\n    print(\"a es menor que b\")\nelif a>b:\n    print(\"a es mayor que b\")\nelse:\n    print(\"deben ser iguales porque no se cumple ninguna condicion...\")\n\n# Bucle for\nfor i in range(1,4):\n    print(f\"Esta es la vez {i} de este bucle for\")\n\n# Bucle while\ni=0\nwhile i<5:\n    print(f\"Esta es la vez {i} del bucle while\")\n    i+=1\n\n# EXTRA\nfor i in range(10,56):\n    if (i%2==0) and (i!=16) and (i%3!=0):\n        print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/59822.py",
    "content": "'''Operadores:\n1. Aritméticos:\n    + Suma\n    - Resta\n    * Multiplicación\n    / División\n    // División entera\n    % Módulo (resto de la división)\n    ** Potenciación'''\n    \nnumero1 = 20\nnumero2 = 30\n\nprint(\"Suma\", numero1 + numero2)        # 50\nprint(\"Resta\", numero1 - numero2)       # -10\nprint(\"Multiplicación\", numero1 * numero2)  # 600\nprint(\"División\", numero1 / numero2)    # 0.6666666666666666\nprint(\"División entera\", numero1 // numero2)  # 0\nprint(\"Módulo\", numero1 % numero2)     # 20\nprint(\"Potenciación\", numero1 ** numero2)  # 107374182400\n\n# Operadores de comparación ( >, <, ==, >=, <=, !=, ) -> devuelve un valor booleano\n# Estructuras de control (if, elif, else), condicionales\n'''\n2. Comparación:\n    == Igual a\n    != Diferente de\n    < Menor que\n    > Mayor que\n    <= Menor o igual que\n    >= Mayor o igual que\n'''\nif numero1 == numero2:\n    print(\"Los números son iguales\")\nelif numero1 != numero2:\n    print(\"Los números son diferentes\")\n    if numero1 < numero2:\n        print(f\"El numero {numero1} es menor que {numero2}\")\n    elif numero1 > numero2:\n        print(f\"El numero {numero1} es mayor que {numero2}\")    \nif numero1 <= numero2 or numero1 >= numero2:\n    if numero1 <= numero2:\n        print(f\"El numero {numero1} es menor o igual que {numero2}\")\n    elif numero1 >= numero2:\n        print(f\"El numero {numero1} es mayor o igual que {numero2}\")\n\n# Operadores lógicos (para trabajar con valores de tipo bool) -> AND, OR, NOT\n'''\n3. Lógicos:\n    and Y\n    or O\n    not Negación\n'''\nprint(True and True)        # devuelve True\nprint(True and False)       # devuelve False\nprint(True or False)        # devuelve True\nprint(False or True)        # devuelve True\nprint(not True)             # devuelve False\nprint(not False)            # devuelve True\n\n'''4. Asignación:\n    = Asignación\n    += Suma y asignación\n    -= Resta y asignación\n    *= Multiplicación y asignación\n    /= División y asignación\n    //= División entera y asignación\n    %= Módulo y asignación\n    **= Potenciación y asignación\n'''\nnumero_uno = 10\nnumero_dos = 20\n\nnumero_uno -= numero_dos\nprint(numero_uno)\nnumero_uno *= numero_dos\nprint(numero_uno)\nnumero_uno /= numero_dos\nprint(numero_uno)\nnumero_uno //= numero_dos\nprint(numero_uno)\nnumero_uno %= numero_dos\nprint(numero_uno)\nnumero_uno **= numero_dos\nprint (numero_uno)\n'''\n    \n\n5. Identidad:\n    is Es el mismo objeto\n    is not No es el mismo objeto\n'''\na = 1\nb = 2\nc = 2\n\na is b # False\nb is c # True\nb is not c # False\na is not c # True\n\n'''\n6. Pertenencia:\n    in Está en\n    not in No está en\n'''\nlista = [1, 2, 3, 4, 5, 12]\nprint(9 in lista) # False\nprint(9 not in lista) # True\nprint(12 in lista) # True\nprint(12 not in lista) # False\n\n\n# For para la iteración en listas y tuplas\n\ntupla = (\"Colombia\", \"Perú\", \"México\", \"Argentina\", \"Chile\")\nfor i in tupla:\n    print(i)\n\n\n''' DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.'''\n\nfor i in range (10, 56):\n    if i % 2 == 0 and i != 16 and i % 3 != 0 #Si el residuo de la division entre 2 es 0 y entre 3 es diferente 0\n        print(i)\n        "
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/AChapeton.py",
    "content": "# Operadores Aritmeticos\nsuma = 2 + 3\nresta = 9 - 5\nproducto = 5 * 5\ndivision = 21 / 7\nmodulo = 16 % 3\npotencia = 8 ** 3\ndivision_entera = 16 // 5\nprint('Suma: ', suma)\nprint('Resta: ', resta)\nprint('Producto: ' , producto)\nprint('Division: ', division)\nprint('Modulo: ', modulo)\nprint('Potencia: ', potencia)\nprint('Division con enteros: ', division_entera) \n\n\n# Operadores Relacionales\nmayor_que = 3 > 5\nmenor_que = 5 < 8\nigualdad = 7 == 7\nmayor_igual = 5 >=5\nmenor_igual = 7 <= 4\ndesigualdad = 8 != 6\nprint('Mayor que: ', mayor_que)\nprint('Menor que: ', menor_que)\nprint('Igualdad: ', igualdad)\nprint('Mayor o igual que: ', mayor_igual)\nprint('Menor o igual que: ', menor_igual)\nprint('Desigualdad: ', desigualdad)\n\n\n# Operadores Bit a Bit\nprint('AND', 10 & 12)\nprint('OR', 10 | 12)\nprint('XOR', 10 ^ 12)\nprint('NOT', ~12)\nprint('Desplazamiento a la derecha', 10 >> 12)\nprint('Desplazamiento a la izquierda', 10 << 12)\n\n\n# Operadores de Asignacion\n# Estos operadores son una forma mas rapida de utilizar los operadores Aritmeticos\n\n# Asignacion\nx =  0 \nprint(x)\n# Suma\nx +=  5\nprint(x)\n# Resta\nx -= 5\nprint(x)\n# Producto\nx *= 5\nprint(x)\n# Division\nx /= 5\nprint(x)\n# Modulo\nx %= 5\nprint(x)\n# Potencia\nx **= 5\nprint(x)\n# Division Entera\nx //= 5\nprint(x)\n\n\n# Operadores Logicos\ntrue_value = True\nfalse_value = False\n# and - Devuelve true si ambos son True\nprint('and: ', true_value and false_value)\n# or - Devuelve Truse si alguno es False\nprint('or: ', true_value or false_value)\n# not - Devuelve True si alguno es False\nprint('not: ', not false_value)\n\n\n# Operadores de Pertenencia\nlist = [1, 2, 3, 4, 5]\nhello = 'Hello World'\n# in - Devuelve True si el elemento se encuentra en la lista\nprint('In list: ', 3 in list)\nprint('In Hello: ', 'World' in list)\n# not in - Devuelve Truse si el elemento NO se encuentra en la lista\nprint('Not in list: ', 7 not in list)\nprint('Not in Hello: ', 'Hello' not in list)\n\n\n# Operadores de Identidad\n# is - Devuelve True si los operandos se refieren al mismo objeto\n# is not - Devuelve True si los operandos NO se refieren al mismo objeto\naa = 3\nbb = 3  \ncc = 4\nprint('AA es BB', aa is bb) # muestra True\nprint('AA no es BB',aa is not bb) # muestra False\nprint('AA no es CC', aa is not cc) # muestra True\n\n# Condicionales\n\n# If\nedad = 18\nif edad < 18:\n  print(\"Menor de edad\")\nelif edad >= 18:\n  print('Mayor de edad')\nelse:\n  print('No se va a ejecutar')\n\n\n# For\nlenguajes = ['Python', 'JavaScript', 'Dart']\nfor lenguaje in lenguajes:\n  print(lenguaje)\n\n# While\ncontador = 0\nwhile contador < 3:\n  print(\"Dentro del bucle\", contador)\n  contador += 1\n\n\n\n# DIFICULTAD EXTRA\n\nfor i in range(10, 56):\n  if i % 2 == 0:\n    if i != 16 and i % 3 != 0:\n      print(i)\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/AbelPerezCollado.py",
    "content": "from random import randint\nn1 = randint(1,10)\nn2 = randint(1,10)\n\n# Operadores aritmeticos\nprint(f'Suma {n1} + {n2} = {n1+n2}')\nprint(f'Resta {n1} - {n2} = {n1-n2}')\nprint(f'Multiplicacion {n1} * {n2} = {n1*n2}')\nprint(f'Division {n1} / {n2} = {n1/n2}')\nprint(f'Resto {n1} % {n2} = {n1%n2}')\nprint(f'Potencia {n1} ** {n2} = {n1**n2}')\nprint(f'Division entera {n1} // {n2} = {n1//n2}')\nprint(f'Suma {n1} + {n2} = {n1+n2}')\n\n# Operadores Logicos\nprint(2==2 and 1==1)\nprint(n1==n2 or 1==1)\nprint(not n1==n2)\n    \n\n# Operadores de comparación\nprint(\"Igualdad: 1 == 1 es\", 1 == 1) \nprint(\"Desigualdad: a != b es\", 'a' != 'b') \nprint(\"Mayor que: 10 > 3 es\", 10 > 3) \nprint(\"Menor que: 2 < 3 es\", 2 < 3) \nprint(\"Mayor o igual que: 2 >= 2 es\", 2 >= 2) \nprint(\"Menor o igual que: 2 <= 7 es\", 2 <= 7)\n\n# Operadores de asignación\na = 5\nprint(f'Operador a = 5 ->{a}')\na += 5\nprint(f'Operador a += 5 ->{a}')\na -= 5\nprint(f'Operador a -= 5 ->{a}')\na *= 3\nprint(f'Operador a *= 3 ->{a}')\na /= 3\nprint(f'Operador a /= 3 -> {a}')\na %=3\nprint(f'Operador a %= 3 -> {a}')\na **=3\nprint(f'Operador a **= 3 -> {a}')\na //=3\nprint(f'Operador a //= 3 -> {a}')\n\n\n# Operadores de identidad\na = 3\nb = 3\nc = 4\nprint(f'3 is 3 -> {a is b}')\nprint(f'4 is not 3 -> {c is not b}')\n\n\n# Operadores de pertenencia \na = [1,2,3,4,5]\nprint(f'1 in a -> {1 in a}')\nprint(f'7 not in a -> {7 not in a}')\n\n# Operadores de bits\nprint(\"AND bit a bit: 2 & 3 es\", 2 & 3) \nprint(\"OR bit a bit: 2 | 3 es\", 2 | 3) \nprint(\"XOR bit a bit: 2 ^ 3 es\", 2 ^ 3) \nprint(\"NOT bit a bit: ~2 es\", ~2) \nprint(\"Desplazamiento a la derecha: 2 >> 1 es\", 2 >> 1) \nprint(\"Desplazamiento a la izquierda: 2 << 1 es\", 2 << 1) \n\n# Estructuras de control condicionales iterativas, excepciones\nname = 'Abel'\napellido = 'Perez'\n#Condicionales\nif name is not apellido:\n    print('Sentencia IF')\nif name is apellido:\n    pass\nelif 'a' in apellido:\n    print('Sentencia elif')\nelse:\n    print('Sentencia else')\n\n# Iteraciones\nfor l in name:\n    print(l)\n\nn =0    \nwhile n <= 4:\n    print(n)\n    n += 1\n    \n# Excepciones\na = 1\nb = 2\ntry:\n    print(len(a))\nexcept Exception as err:\n    print(err)\n    \n# Extra: Programa que imprima por consola todos los numeros comprendidos entre 10 y 55 incluidos\n#        pares y que no son ni el 16 ni multiplos de 3\nfor n in range(10,56):\n    if not n % 3 == 0 and n != 16 and n % 2 == 0:\n        print(n)\n \n\n    "
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Adirv5.py",
    "content": "\"\"\"\nOperadores\n\"\"\"\n# Operadores Aritméticos\nprint(f\"Suma: 10 + 3 = {10 + 3}\")\nprint(f\"Resta: 10 - 3 = {10 - 3}\")\nprint(f\"Multiplicación: 10 * 3 = {10 * 3}\")\nprint(f\"División: 10 / 3 = {10 / 3}\")\nprint(f\"Módulo: 10 % 3 = {10 % 3}\")\nprint(f\"Exponenciación: 10 ** 3 = {10 ** 3}\")\nprint(f\"División Entera: 10 // 3 = {10 // 3}\")\n\n# Operadores de Comparación\nprint(f\"igual a: 10 == 3 = {10 == 3}\")\nprint(f\"diferente de: 10 != 3 = {10 != 3}\")\nprint(f\"mayor que: 10 > 3 = {10 > 3}\")\nprint(f\"menor que: 10 < 3 = {10 < 3}\")\nprint(f\"mayor o igual que: 10 >= 3 = {10 >= 3}\")\nprint(f\"menor o igual que: 10 <= 3 = {10 <= 3}\")\n\n# Operadores Lógicos\nprint(f\"AND &&: 10 + 3 == 13 and 5 - 1 == 4 es {10 + 3 == 13 and 5 - 1 == 4}\")\nprint(f\"OR ||: 10 + 3 == 13 or 5 - 1 == 4 es {10 + 3 == 14 or 5 - 1 == 4}\")\nprint(f\"NOT !: not 10 + 3 == 14 es {not 10 + 3 == 14}\")\n\n# Operadores de Asignación\nmy_number = 11 # asignacion \nprint(my_number)\nmy_number += 2 # suma y asignacion\nprint(my_number)\nmy_number -= 3 # resta y asignacion \nprint(my_number)\nmy_number *= 2 # multiplicacion y asignacion\nprint(my_number)\nmy_number /= 2 # division y asignacion\nprint(my_number)\nmy_number %= 3 # modulo y asignacion\nprint(my_number)\nmy_number //= 1 # division entera y asignacion\nprint(my_number)   \nmy_number **= 2 # exponenciacion y asignacion\nprint(my_number)\n\n# Operadores de Identidad\nmy_new_number = my_number\nprint(f\"my_number es my_new_number: {my_number is my_new_number}\")\nprint(f\"my_number no es my_new_number: {my_number is not my_new_number}\")\n\n# Operadores de Pertenencia\nprint(f\"'u' in 'Python es un lenguaje de programación': {'u' in 'Python es un lenguaje de programación'}\")\nprint(f\"'b' not in 'Python es un lenguaje de programación': {'b' not in 'Python es un lenguaje de programación'}\")\n\n# Operadores de bit\nprint(f\"AND 10 & 3 = {10 & 3}\") # 0010 en binario\nprint(f\"OR 10 | 3 = {10 | 3}\") # 1011 en binario\nprint(f\"XOR 10 ^ 3 = {10 ^ 3}\") # 1001 en binario\nprint(f\"NOT ~10 = {~10}\") # 0101 en binario\nprint(f\"Desplazamiento a la derecha: 10 >> 1 = {10 >> 1}\") # 0010\nprint(f\"Desplazamiento a la izquierda: 10 << 1 = {10 << 1}\") # 101000\n\n\"\"\"Estructuras de Control\n\"\"\"\n# Condicionales\n\nmy_string = \"Adirv5\"\n\nif my_string == \"Adirv5\":\n    print(\"El string es igual a Adirv5\")\nelif my_string == \"Wero\":\n    print(\"El string es igual a Wero\")\n    \n    1\n2\n3\n4\n6\nincome—1SOO\ni f income>2SOO:\ntax—S00\nelse:\n—200\nprint(tax)+\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/AgustinDamonte17.py",
    "content": "# --------------------\n# Operadores aritméticos\n# --------------------\na = 10\nb = 3\n\nprint(\"Operadores Aritméticos:\")\nprint(\"Suma:\", a + b)\nprint(\"Resta:\", a - b)\nprint(\"Multiplicación:\", a * b)\nprint(\"División:\", a / b)\nprint(\"División entera:\", a // b)\nprint(\"Módulo:\", a % b)\nprint(\"Potencia:\", a ** b)\nprint()\n\n# --------------------\n# Operadores de comparación\n# --------------------\nprint(\"Operadores de Comparación:\")\nprint(\"¿a == b?\", a == b)\nprint(\"¿a != b?\", a != b)\nprint(\"¿a > b?\", a > b)\nprint(\"¿a < b?\", a < b)\nprint(\"¿a >= b?\", a >= b)\nprint(\"¿a <= b?\", a <= b)\nprint()\n\n# --------------------\n# Operadores lógicos\n# --------------------\nx = True\ny = False\n\nprint(\"Operadores Lógicos:\")\nprint(\"x and y:\", x and y)\nprint(\"x or y:\", x or y)\nprint(\"not x:\", not x)\nprint()\n\n# --------------------\n# Operadores de asignación\n# --------------------\nprint(\"Operadores de Asignación:\")\nc = 5\nprint(\"Valor inicial:\", c)\nc += 2\nprint(\"c += 2:\", c)\nc -= 1\nprint(\"c -= 1:\", c)\nc *= 3\nprint(\"c *= 3:\", c)\nc /= 2\nprint(\"c /= 2:\", c)\nc %= 4\nprint(\"c %= 4:\", c)\nc **= 2\nprint(\"c **= 2:\", c)\nc //= 3\nprint(\"c //= 3:\", c)\nprint()\n\n# --------------------\n# Operadores de identidad\n# --------------------\nprint(\"Operadores de Identidad:\")\nd = [1, 2, 3]\ne = d\nf = [1, 2, 3]\n\nprint(\"e is d:\", e is d)\nprint(\"f is d:\", f is d)\nprint(\"f is not d:\", f is not d)\nprint()\n\n# --------------------\n# Operadores de pertenencia\n# --------------------\nprint(\"Operadores de Pertenencia:\")\nprint(\"2 in d:\", 2 in d)\nprint(\"5 not in d:\", 5 not in d)\nprint()\n\n# --------------------\n# Operadores a nivel de bits\n# --------------------\nprint(\"Operadores de Bits:\")\nx = 6  # 110\ny = 3  # 011\nprint(\"x & y:\", x & y)   # 010\nprint(\"x | y:\", x | y)   # 111\nprint(\"x ^ y:\", x ^ y)   # 101\nprint(\"~x:\", ~x)         # complemento\nprint(\"x << 1:\", x << 1) # desplazamiento izquierda\nprint(\"x >> 1:\", x >> 1) # desplazamiento derecha\nprint()\n\n# --------------------\n# Estructuras de control: condicionales\n# --------------------\nprint(\"Condicionales:\")\nedad = 20\nif edad >= 18:\n    print(\"Es mayor de edad.\")\nelif edad > 13:\n    print(\"Es adolescente.\")\nelse:\n    print(\"Es niño.\")\nprint()\n\n# --------------------\n# Estructuras de control: iterativas\n# --------------------\nprint(\"Iteración con for:\")\nfor i in range(3):\n    print(\"Iteración\", i)\n\nprint(\"\\nIteración con while:\")\nn = 0\nwhile n < 3:\n    print(\"n =\", n)\n    n += 1\nprint()\n\n# --------------------\n# Estructuras de control: manejo de excepciones\n# --------------------\nprint(\"Manejo de Excepciones:\")\ntry:\n    resultado = 10 / 0\nexcept ZeroDivisionError as e:\n    print(\"Error:\", e)\nfinally:\n    print(\"Bloque finally ejecutado.\")\nprint()\n\n# --------------------\n# DIFICULTAD EXTRA\n# --------------------\nprint(\"Dificultad extra:\")\nfor i in range(10, 56):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print(i, end=\" \")\nprint()\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/AlainMartz.py",
    "content": "### RETO #01 - Operadores y estructuras de control\n\n### 1. Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje\n\n## Operaradores aritméticos\n\"Se utilizan para realizar operaciones aritméticas\"\n\na, b = 17, 5\nprint(\"OPERADORES ARITMÉTICOS\\n\")\nprint(\"Suma de {} + {} = \".format(a,b), (a+b)) # Suma\nprint(\"Resta de {} - {} = \".format(a,b), (a-b)) # Resta\nprint(\"Multiplicación de {} * {} = \".format(a,b), (a*b)) # Multiplicación\nprint(\"División de {} / {} = \".format(a,b), (a/b)) # División\nprint(\"Resto entre {} - {} = \".format(a,b), a%b) # Módulo / Resto\nprint(\"{} elevado a {} = \".format(a,b), a**b) # Potencia\nprint(\"División entera {} + {} = \".format(a,b), a//b) # División entera\nprint(\"Valor absoluto de -{}\".format(a), abs(-a)) # Absoluto\n\n## Operadores Binarios\n\"Se usan para realizar operaciones a nivel de bit\"\n\nprint(\"\\nOPERADORES BINARIOS\")\nprint(\"\\nValor binario de {} y {}, \".format(a,b), bin(a), bin(b))\nprint(\"Operador AND: {} & {} = \".format(a,b),a&b) # AND devuelve 1 si ambos coinciden en 1 y el resto de los casos 0. 1AND1=1 / 1AND0, 0AND1, 0AND0 = 0. Fórmula: (a & b) = a x b\nprint(\"Operador OR: {} | {} = \".format(a,b),a|b) # OR Retorna 1 si alguno de los bits comparados es 1. 1OR1, 1OR0, 0OR1 = 1, 0OR0 = 0. Fórmula: (a|b) = a + b - (a x b)\nprint(\"Operador XOR: {} ^ {} = \".format(a,b),a^b) # XOR (exclusive OR) Devuelve 1 para  1XOR0 o 0XOR1, y 0 para los otros casos. Fórmula: (a^b) = (a+b)mod2\nprint(\"Operador NOT: ~{}, ~{} = \".format(a,b),~a,~b) # NOT retorna el valor contrario. Fórmula: ~a = 1 - a \nprint(\"Operador LEFT SHIFT: {} << 1, {} << 1 = \".format(a,b),a<<1,b<<1) # LEFT SHIFT agrega ceros a la izquierda | 0010 << 2 => 1000. Fórmula: a << n = a x 2^n\nprint(f\"Operador RIGTH SHIFT: {a} >> 1, {b} >> 1 = \",a>>1,b>>1) # RIGTH SHIFT agrega ceros a la derecha | 1000 >> 2 => 0010. Fórmula: a >> n = a//2^n\n\n\n## Operadores de asignación\n\"Permiten realizar una operación y almacenar su resultado en la variable inicial\"\n\nprint(\"\\nOPERADORES DE ASIGNACIÓN\")\n#Suma\na+=b \nprint(f\"\\nAsignación Suma {a} += {b}:\", a) \n#Resta\na-=b\nprint(f\"Asignación Resta {a} -= {b}:\", a)\n#Multiplicación\na*=b\nprint(f\"Asignación Multiplicación {a} *= {b}:\", a)\n#División\na/=b\nprint(f\"Asignación División {a} /= {b}:\", a)\n#Módulo\na%=b\nprint(f\"Asignación Módulo {a} %= {b}:\", a)\n#Potencia\na**=b\nprint(f\"Asignación Potencia {a} **= {b}:\", a)\n#Floor\na//=b\nprint(f\"Asignación División entera {a} //= {b}:\", a)\n\n\n#AND\na,b = 17,5\na&=b\nprint(f\"\\nAsignación AND {a} &= {b}:\", a)\n#OR\na,b = 17,5\na|=b\nprint(f\"Asignación OR {a} |= {b}:\", a)\n#XOR\na,b = 17,5\na^=b\nprint(f\"Asignación XOR {a} ^= {b}:\", a)\n#LSHIFT\na,b = 17,5\na<<=b\nprint(f\"Asignación LShift {a} <<= {b}:\", a)\n#RSHIFT\na,b = 17,5\na>>=b\nprint(f\"Asignación RShift {a} >>= {b}:\", a)\n\n\n\n## Operadores de lógicos\n\"Permiten operar datos booleanos, True o False\"\n\nc, d = True, False\nprint(\"\\nOPERADORES LÓGICOS\")\nprint(f\"\\nOperador and: {c} and {d}: \", c and d) # Compara ambos valores y devuelve True si ambos son True\nprint(f\"Operador and: {c} or {d}: \", c or d) # Compara ambos valores y devuelve True si alguno de los dos es True\nprint(f\"Operador and: not {c}, not {d}: \", not c, not d) # Devuelve el valor contrario, True si es False, False si es True\n\n## Operadores relacionales\n\"Permiten comparar entre dos variables, devuelven valores True or False si las condiciones se cumplen\"\n\na,b = 17,5\nprint(\"\\nOPERADORES RELACIONALES\" )\nprint(f\"Operador Igual: {a} == {b}: \", a == b)\nprint(f\"Operador Distinto: {a} != {b}: \", a != b)\nprint(f\"Operador Mayor: {a} > {b}: \", a > b)\nprint(f\"Operador Menor: {a} < {b}: \", a < b)\nprint(f\"Operador Mayor o Igual: {a} >= {b}: \", a >= b)\nprint(f\"Operador Menor o Igual: {a} <= {b}: \", a <= b)\n\n## Operadores de identidad\n\"Compara la ubicación en la memoria de dos objetos\"\n\na,b,c,d = 10,10,[1,2,3],[1,2,3]\nprint(\"\\nOPERADORES DE IDENTIDAD\")\nprint(\"\\na = 10\\nb = 10\\nc = [1,2,3]\\nd = [1,2,3]\")\nprint(\"\\na is b: \", a is b) # a y b serán iguales si, id(a) e id(b) lo son. El número 10 almacenado por a y b tiene la misma ubicación en la memoria\nprint(\"id(a) :\", id(a))\nprint(\"id(b) :\", id(b))\nprint(\"c is not d :\", c is not d) # c y d no serán iguales si, id(c) e id(d) no lo son. Las listas creadas para c y d corresponden a objetos diferentes, por lo tanto ocupan distintos espacios en la memoria\nprint(\"id(c) :\", id(c))\nprint(\"id(d) :\", id(d))\n\n## Operadores de membresia\n\"Son operadores que nos permiten saber si un elemento esta contenido en una secuencia. Por ejemplo si un número está contenido en una lista de números, devuelven valores True o False\"\n\nprint(\"\\nOPERADORES DE MEMBRESÍA\")\nprint(\"\\na in c:\", a in c) # Si a está contenido dentro de c entonces devolverá True\nprint(\"(4,5) not in c:\", (4,5) not in c) # Si a no está contenido dentro de c entonces devolverá True\n\n\n## Operadores de cadenas\n\"Permite manejar cadenas de texto\"\n\nprint(\"\\nOPERADORES DE CADENAS\")\nprint(\"\\nConcatenación: 'Buenos ' + 'Días' = \", \"Buenos \" + \"Días\")\nprint(\"Multiplicación: 'Doble'*3 \", \"Doble\"*3)\nprint(\"Índice: 'Paralelepípedo[3]' = \", \"Paralelepípedo\"[3])\nprint(\"Slicing/range: 'Paralelepípedo[3:8]' = \", \"Paralelepípedo\"[3:8])\nprint(\"Largo de la cadena: len('Paralelepípedo')\", len('Paralelepípedo'))\nprint(\"Iteración: for i in 'paralelepipedo' print(i)\")\nfor i in 'paralelepipedo':\n    print(i)\n\n### 2. Utilizando las operaciones con operadores que tú quieras, \n### crea ejemplos que representen todos los tipos de estructuras \n### de control que existan en tu lenguaje\n\n## Condicionales\n\n# If - Elif - Else\n\nprint(\n\"\"\"\nESTRUCTURAS DE CONTROL\n\nCondicionales: if, elif, else:\n\na,b = 12, 34\n\nif a == b:\n    print (f\"{a} es igual a {b}\")\nelif a > b:\n    print (f\"{a} es mayor a {b}\")\nelse:\n    print(f\"{a} debe ser menor que {b}\")\n\"\"\")\n\na,b = 12, 34\n\nif a == b:\n    print (f\"{a} es igual a {b}\")\nelif a > b:\n    print (f\"{a} es mayor a {b}\")\nelse:\n    print(f\"{a} debe ser menor que {b}\")\n\n## De Bucle\n\n# For - While - Break - Continue - Pass\n\n\"\"\"\ni = 0\nwhile i < len(\"exterior\"):\n    print (f\"\\nIteración en {'exterior'[i]}\")\n    for j in  \"interior\":\n        if j == \"n\":\n            print(f\"Continuing el búcle interior en la letra {j}\")\n            continue # Salta la letra n y continua el búcle\n        elif j == \"t\":\n            print(f\"Passing el búcle interior en la letra {j}\")\n            pass # No pasa nada\n        elif j == \"o\":\n            print(f\"Breaking el búcle interior en la letra {j}\")\n            break # Sale del búcle en la letra o\n    if \"exterior\"[i] == \"r\":\n        break\n    i += 1\nprint (\"\\nFin del búcle\")    \n\"\"\"\n\ni = 0\nwhile i < len(\"exterior\"):\n    print (f\"\\nIteración en {'exterior'[i]}\")\n    for j in  \"interior\":\n        if j == \"n\":\n            print(f\"Continuing el búcle interior en la letra {j}\")\n            continue # Salta la letra n y continua el búcle\n        elif j == \"t\":\n            print(f\"Passing el búcle interior en la letra {j}\")\n            pass # No pasa nada\n        elif j == \"o\":\n            print(f\"Breaking el búcle interior en la letra {j}\")\n            break # Sale del búcle en la letra o\n    if \"exterior\"[i] == \"r\":\n        break\n    i += 1\nprint (\"\\nFin del búcle\")        \n\n## Excepciones\n\n# Try - except - raise - finally\n\n\ndef excepciones(a,b):\n    try:\n        result = a/b\n    except ZeroDivisionError:\n        print(\"Error: No se puede dividir por cero.\")\n        result = None \n    except TypeError:\n        print(\"Error: Tipos de datos deben ser compatibles.\")\n        result = None\n    else:\n        print(f\"El resultado es {result}\")\n    finally:\n        print(\"Operación terminada\")\n    return result\n\nprint(\"\\nEXCEPCIONES\\n\")\nprint(\n    \"\"\"\ndef excepciones(a,b):\n    try:\n        result = a/b\n    except ZeroDivisionError:\n        print(\"Error: No se puede dividir por cero.\")\n        result = None \n    except TypeError:\n        print(\"Error: Tipos de datos deben ser compatibles.\")\n        result = None\n    else:\n        print(f\"El resultado es {result}\")\n    finally:\n        print(\"Operación terminada\")\n    return result\\n\\n\n\"\"\"\n)\n\nprint (f\"Caso 1, a = 10, b = 0\")\nexcepciones(10,0)\nprint (f\"\\nCaso 2, a = 10, b = '0'\")\nexcepciones(10,\"0\")\nprint (f\"\\nCaso 3, a = 10, b = 5\")\nexcepciones(10,5)\n\n## EXTRA    \n\"Crea un programa que imprima por consola todos los números comprendidos entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3\"\n\nfor i in range(10,56):\n    if (i%2 == 0) and i != 16 and (i%3!=0):\n        print(i)\n\n## versión list comprehesion\n## numero = [i for i in range(10,56) if (i%2 == 0) and i != 16 and (i%3!=0)]\n## print (numero)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Aldroide.py",
    "content": "# Ejemplos de operadores aritmeticos\n\nnum_1 = 5\nnum_2 = 2\n\nOp_arit = 0\nprint(\"##### Operaciones Aritmeticas #####\")\nOp_arit = num_1 + num_2\nprint(f\"Suma: {Op_arit}\")\nOp_arit = num_1 - num_2\nprint(f\"Resta: {Op_arit}\")\nOp_arit = num_1 * num_2\nprint(f\"Multiplicación: {Op_arit}\")\nOp_arit = num_1 / num_2\nprint(f\"División: {Op_arit}\")\nOp_arit = num_1 % num_2\nprint(f\"Módulo: {Op_arit}\")\nOp_arit = num_1 ** num_2\nprint(f\"Potencia: {Op_arit}\")\nOp_arit = num_1 // num_2\nprint(f\"División entera: {Op_arit} \\n\")\n\n\"\"\" Ejemplos de operadores relacionales, se usan para comparar\n    y establecer una relación entre ellos, devuelven un valor\n    booleano (true o false) basado en la condición.\n\"\"\"\nop_rel = False\nop_rel = num_1 > num_2\nprint(\"##### Operaciones Relacionales ##### \")\nprint(f\"Mayor: {op_rel}\")\nop_rel = num_1 < num_2\nprint(f\"Menor: {op_rel}\")\nop_rel = num_1 == num_2\nprint(f\"Igual: {op_rel}\")\nop_rel = num_1 >= num_2\nprint(f\"Mayor o igual: {op_rel}\")\nop_rel = num_1 <= num_2\nprint(f\"Menor o igual: {op_rel}\")\nop_rel = num_1 != num_2\nprint(f\"Diferente: {op_rel} \\n\")\n\n\"\"\" Ejemplos de operadores Bit a Bit\n    consideramos a =2 (binario 10) y \n    b= 3 (binario 11)\n\"\"\"\na = 2  # 10 en binario\nb = 3  # 11 en binario\n\nprint(\"##### Operaciones Bit a Bit #####\")\nop_bit = a & b\nprint(f\"And: {op_bit}\")\nop_bit = a | b\nprint(f\"Or: {op_bit}\")\nop_bit = a ^ b\nprint(f\"XOR: {op_bit}\")\nop_bit = ~a\nprint(f\"NOT {op_bit}\")\nop_bit = a >> b\nprint(f\"Desplazamiento a la derecha : {op_bit}\")\nop_bit = a << b\nprint(f\"Desplazamiento a la izquierda : {op_bit} \\n\")\n\n\"\"\" Operadores de asignación se utilizan para asignar valores a las variables\n    gerenalmente se combinan con operadores aritmeticos \n\"\"\"\nprint(\"##### Operadores de asignación #####\")\na = 5\nprint(f\"Asignación directa a=5 : {a}\")\na += 5\nprint(f\"Asignación de sumar 5 (a += 5):  {a}\")\na -= 5\nprint(f\"Asignación de restar 5 (a -= 5):  {a}\")\na *= 3\nprint(f\"Asignación de multiplicar 3 (a *= 3):  {a}\")\na /= 3\nprint(f\"Asignación de dividir entre 3 (a /= 3):  {a}\")\na %= 3\nprint(f\"Asignación de módulo entre 3 (a %= 3):  {a}\")\na **= 3\nprint(f\"Asignación de elevar al 3 (a **= 3):  {a}\")\na //= 3\nprint(f\"Asignación de divier entero entre 3 (a //= 3):  {a}\")\n\n\"\"\"Operadores de pertenencia se utilizan para identificar si pertenece a alguna secuencia\n    com listas, strings, tuplas, in y not in son operadores de pertenencia\n\"\"\"\nprint(\"\\n ##### Operadores de Pertenencia #####\")\na = [1, 2, 3, 4, 5]\nstring = \"Hello world this is python!\"\nr = 3 in a\nprint(r)\nr = 12 not in a\nprint(r)\nr = \"World\" in string\nprint(r)\nr = \"map\" not in string\nprint(r)\n\nprint(\"\\n ##### Operadores Lógicos #####\")\nx = True\ny = False\n\nre_log = x and y\nprint(\"AND:\", re_log)\nre_log = x or y\nprint(\"OR:\", re_log)\nre_log = not x\nprint(\"NOT:\", re_log)\n\n\n\"\"\" DIFICULTAD EXTRA (opcional):\n    Crea un programa que imprima por consola todos los números comprendidos\n    entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3\n\"\"\"\nc = []\nfor i in range(10, 56):\n    if i != 16 and i % 2 == 0 and i % 3 != 0 or i==55:\n        c.append(i)\n\nprint(c)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/AlejandroVelasquezR.py",
    "content": "#Ejercicio 01 operadores y estructuras de control\n'''/*\n * EJERCICIO:\n \n \n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n '''\n\n\n\n\"\"\" - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n#   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n\"\"\"\ndef Aritméticos():\n    #suma\n    suma = 1 + 1\n    print(\"suma: \", suma)\n    #resta\n    resta = 1 - 1\n    print(\"resta: \", resta)\n    #multiplicacion\n    multiplicacion = 1 * 1\n    print(\"multiplicacion: \", multiplicacion)\n    #division\n    division = 1 / 1\n    print(\"division: \", division)\n    #modulo\n    modulo = 1 % 1\n    print(\"modulo: \", modulo)\n    #exponente\n    exponente = 1 ** 1\n    print(\"exponente: \", exponente)\n    #division entera\n    divisionEntera = 1 // 1\n    print(\"division entera: \", divisionEntera)\n\ndef Logicos():\n    #and\n    andLogico = True and True\n    print(\"and: \", andLogico)\n    #or\n    orLogico = True or False\n    print(\"or: \", orLogico)\n    #not\n    notLogico = not True\n    print(\"not: \", notLogico)\n\ndef Comparacion():\n    #igual\n    igual = 1 == 1\n    print(\"igual: \", igual)\n    #diferente\n    diferente = 1 != 2\n    print(\"diferente: \", diferente)\n    #mayor que\n    mayorQue = 1 > 2\n    print(\"mayor que: \", mayorQue)\n    #menor que\n    menorQue = 1 < 2\n    print(\"menor que: \", menorQue)\n    #mayor o igual que\n    mayorOIgualQue = 1 >= 2\n    print(\"mayor o igual que: \", mayorOIgualQue)\n    #menor o igual que\n    menorOIgualQue = 1 <= 2\n    print(\"menor o igual que: \", menorOIgualQue)\n\ndef identidad():\n    #is\n    isIdentidad = 1 is 1\n    print(\"is: \", isIdentidad)\n    #is not\n    isNotIdentidad = 1 is not 2\n    print(\"is not: \", isNotIdentidad)\n\ndef pertenencia():\n    #in\n    inPertenencia = 1 in [1,2,3]\n    print(\"in: \", inPertenencia)\n    #not in\n    notInPertenencia = 1 not in [1,2,3]\n    print(\"not in: \", notInPertenencia)\n\ndef bits():\n    #and\n    andBits = 1 & 1\n    print(\"and: \", andBits)\n    #or\n    orBits = 1 | 1\n    print(\"or: \", orBits)\n    #xor\n    xorBits = 1 ^ 1\n    print(\"xor: \", xorBits)\n    #not\n    notBits = ~ 1\n    print(\"not: \", notBits)\n    #desplazamiento a la izquierda\n    desplazamientoIzquierda = 1 << 1\n    print(\"desplazamiento a la izquierda: \", desplazamientoIzquierda)\n    #desplazamiento a la derecha\n    desplazamientoDerecha = 1 >> 1\n    print(\"desplazamiento a la derecha: \", desplazamientoDerecha)\n\n\"\"\"\"\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n\"\"\"\n\ndef condicionales():\n    #if\n    if 1 == 1:\n        print(\"if\")\n    #if else\n    if 1 == 1:\n        print(\"if\")\n    else:\n        print(\"else\")\n    #elif\n    if 1 == 1:\n        print(\"if\")\n    elif 1 == 2:\n        print(\"elif\")\n    else:\n        print(\"else\")\n\ndef iterativas():\n    #for\n    for i in range(0,10):\n        print(\"for\")\n    #while\n    while True:\n        print(\"while\")\n        break\n\ndef excepciones():\n   #try except\n   while True:\n    try:\n        x = int(input(\"Please enter a number: \"))\n        break\n    except ValueError:\n        print(\"Oops!  That was no valid number.  Try again...\")\n    #try except finally\n    try:\n        x = int(input(\"Please enter a number: \"))\n    except ValueError:\n        print(\"Oops!  That was no valid number.  Try again...\")\n    finally:\n        print(\"Finally, I executed!\")\n    #raise\n    x = \"hello\"\n    if not type(x) is int:\n        raise TypeError(\"Only integers are allowed\")\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n\"\"\"\n\ndef dificultadextra():\n    for i in range(10,56):\n        if i % 2 == 0 and i != 16 and i % 3 != 0:\n            print(i)\n\ndificultadextra()\n# Perdon por el codigo tan largo pero es la manera mas ordenada que pude hacerlo jaja"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Aleran07.py",
    "content": "# 01\nx = 2\ny = 5\nz = 1+2\nprint(z)\nz = 2-6\nprint(z)\nz = 2/6\nprint(z)\nz = 2*6\nprint(z)\n\nz = 1//2\nprint(z)\nz = 2%6\nprint(z)\nz = 2**6\nprint(z)\n\n\nz = 1==2\nprint(z)\nz = 2!=6\nprint(z)\nz = 2<6\nprint(z)\nz = 2>6\nprint(z)\nz = 2>=6\nprint(z)\nz = 2<=6\nprint(z)\n\n# Operadores lógicos\nz = (1==2) and (2<6)\nprint(z)\nz = (1==2) or (2<6)\nprint(z)\nz = not(1==2)\nprint(z)\nz = not(2<6)\nprint(z)\n\n\n# Operadores de asignación\nx = 2\nx += 2  # x = x + 2\nprint(x)\nx -= 2  # x = x - 2\nprint(x)\nx *= 2  # x = x * 2\nprint(x)\nx /= 2  # x = x / 2\nprint(x)\nx //= 2  # x = x // 2\nprint(x)\nx %= 2  # x = x % 2\nprint(x)\nx **= 2  # x = x ** 2\nprint(x)\n\n# operadores de identidad\nx = 2\ny = 5\nz = x is y\nprint(z)\nz = x is not y\nprint(z)\ny = 2\nz = x is y\nprint(z)\nz = x is not y\nprint(z)\n\n# operadores de pertenencia\nx = \"Hola\"\ny = \"H\"\nz = \"H\" in x\nprint(z)\nz = \"H\" not in x\nprint(z)\n\n\n# operadores bit a bit\nx = 2  # 10 en binario\ny = 5  # 101 en binario\nz = x & y  # AND bit a bit\nprint(z)  # 0 en binario\n\nz = x | y  # OR bit a bit\nprint(z)  # 7 en binario\n\n\nz = x ^ y  # XOR bit a bit\nprint(z)  # 7 en binario\nz = ~x  # NOT bit a bit\nprint(z)  # -3 en binario\nz = x << 1  # Desplazamiento a la izquierda\nprint(z)  # 4 en binario\n\n# Ejercicios\nimport random\nprint(\"Operadores en Python\\n\")\n# OPERADORES ARITMÉTICOS\nprint(\"Operadores Aritméticos\")\na = random.randint(1, 10)\nb = random.randint(1, 10)\nprint(f'    - La suma de {a} + {b} es igual a {a + b}')\nprint(f'    - La resta de {a} - {b} es igual a {a - b}')\nprint(f'    - La multiplic de {a} x {b} es igual a {a * b}')\nprint(f'    - La división de {a} entre {b} es igual a {a / b}')\nprint(f'    - El resto de {a} entre {b} es igual a {a % b}')\nprint(f'    - La división de piso de {a} entre {b} es igual a {a // b}')\nprint(f'    - La potencia de {a} elevado a {b} es igual a {a ** b}\\n')\n\n\n\nprint(\"Ejercicio de dificultad extra\")\na = random.randint(1, 10)\nb = random.randint(1, 10)\nc = random.randint(1, 10)\nd = random.randint(1, 10)\ne = random.randint(1, 10)\nf = random.randint(1, 10)\nprint(f'    - El resultado de la operación ({a} + {b}) * ({c} - {d}) / ({e} + {f}) es igual a {((a + b) * (c - d)) / (e + f)}')\nprint(f'    - El resultado de la operación ({a} + {b}) * ({c} - {d}) // ({e} + {f}) es igual a {((a + b) * (c - d)) // (e + f)}')\nprint(f'    - El resultado de la operación ({a} + {b}) * ({c} - {d}) % ({e} + {f}) es igual a {((a + b) * (c - d)) % (e + f)}')\n\n\n# Ejercicio de dificultad extra\n# Crea un programa que imprima por consola todos los números comprendidos\n# * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\nfor i in range(10, 56):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print(i)\n\nx = 13\ny = x % 2\nprint(y)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/AllanYSalazarG.py",
    "content": "\"\"\"#01 OPERADORES Y ESTRUCTURAS DE CONTROL\"\"\"\n\nnumero1 = 2\nnumero2 = 4\n\n# Aritmeticos\nsuma = numero1 + numero2  # Suma los valores\nresta = numero1 - numero2  # Resta los valores\nmultiplicacion = numero1 * numero2  # Multiplica los valores\ndivision = numero1 / numero2  # Divide los valores, regresando un float siempre\n# Divide los valores, regresando un int siempre (descarga el decimal)\ndivisionEntera = numero1 // numero2\nmodulo = numero1 % numero2  # Divide los valores y regresa el residuo\npotencia = numero1 ** numero2  # b ^ e Multiplica la b, e veces por si misma\n\n# Relacional, comparacion (Devuelve True o False basado en la expresión)\n# > indica si el numero de la izquierda es mayor que el de la derecha\nmayorQue = numero1 > numero2\n# < indica si el numero de la izquierda es menor que el de la derecha\nmenorQue = numero1 < numero2\nigualQue = numero1 == numero2  # == indica si ambos valores son iguales\n# >= indica si el valor de la izquierda es mayor o igual que el de la derecha\nmayorIgualQue = numero1 >= numero2\n# <= indica si el valor de la izquierda es menor o igual que el de la derecha\nmenorIgualQue = numero1 <= numero2\ndiferenteDe = numero1 != numero2  # != indica si los valores son diferentes\n\n# Operadores Bit a Bit\nAND = numero1 & numero2  # Hace la operacion AND\nOR = numero1 | numero2  # Hace la operacion OR\nXOR = numero1 ^ numero2  # Hace la operacion XOR\ncejilla = ~numero1  # Hace la operacion NOT\ndespDer = numero1 >> numero2  # Desplaza a la derecha\ndespIzq = numero1 << numero2  # Desplaza a la izquierda\n\n# Estos dos ultimos dezplazan a la izquierda o a la derecha los bits del operador de la izquierda\n# tantos bits como indica el operando de la derecha\n\n# Operadores de asignación\n\"\"\" \n= : a = 1: El valor 1 se asigna a la variable a\nTodos los demás, equivalen \"a = a + 1\" (cambiando el operador)\n+=: a += 1\n-=: a -= 1\n*=: a *= 1\n/=: a /= 1\n%=: a %= 1\n**=: a **= 1\n//=: a //= 1\n&=: a &= 1\n|=: a |= 1\n^=: a ^= 1\n>>=: a >>= 1\n<<=: a <<= 1\n\"\"\"\n\n# Operadores logicos\n\"\"\" and: Devuelve True si ambos operandos son True: a and b\nor: Devuelve True si al menos un operando es True: a or b\nnot: Devuelve True si alguno de los operandos es False: not a\"\"\"\n\n# Operadores de pertenencia\n\"\"\" in: Devuelve True si el valor especificado se encuentra en la secuencia\nnot in: Devuelve True si el valor no se encuentra en la secuencia \"\"\"\n\na = [1, 2, 3]\nprint(3 in a)  # Muestra True\nprint(4 not in a)  # Muestra True\n\n# Estructuras de control\n\n# IF, ELIF, ELSE\n\nif numero1 > numero2:\n    print(f\"{numero1} es mayor\")\nelse:\n    print(f\"{numero2} es mayor\")\n\n# FOR\n\nfor numero in range(2):\n    print(numero)\n\n# WHILE\ncontador = 0\nwhile contador < 5:\n    print(contador, end=\" -> \")\n    contador += 1\n\n# Comprension de Listas\n\nlistaNumeros = [a for a in range(1, 5)]\nprint(listaNumeros)\n\n# Sentencias de control de bucles (break, continue y pass)\n\n\"\"\"\nbreak: se usa para finalizar el ciclo\ncontinue: se usa para saltar a la siguiente iteración\npass: no hace nada, sirve como marcador de posición\"\"\"\n\n# EJERCICIO OPCIONAL\n# Crea un programa que imprima por consola todos los números comprendidos\n# entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\nfor valor in range(10, 56):\n    if valor == 55:\n        print(valor)\n    if valor != 16:\n        if valor % 3 != 0:\n            if valor % 2 == 0:\n                print(valor, end=\" \")\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Aloween.py",
    "content": "'''Operadores\n    - Aritméticos\n    - De asignación\n    - De comparación\n    - Lógicos\n    Estructuras de control\n    - Condicionales\n    - Bucles\n    - Funciones'''\n\n# Operadores aritméticos\nprint (f\"Suma 10 + 3 = { 10 + 3}\")\nprint (f\"Resta 10 - 3 = { 10 - 3}\")\nprint (f\"Multiplicación 10 * 3 = { 10 * 3}\")\nprint (f\"División 10 / 3 = { 10 / 3}\")\nprint (f\"Modulo 10 % 3 = { 10 % 3}\")  # Se usa para obtener el residuo de una división y se hace con el símbolo %.\nprint (f\"Exponente 10 ** 3 = { 10 ** 3}\") # Eleva un número a la potencia de otro.\nprint (f\"División entera 10 // 3 = { 10 // 3}\") # Devuelve el cociente de una división redondeado hacia abajo al entero más cercano.\n\n# Operadores de comparación podemos usarlos para comparar valores de variables, strings y devuelven un valor booleano (True o False)\n\nprint(f\"10 > 3 = { 10 > 3 }\")   # Mayor que\nprint(f\"10 < 3 = { 10 < 3 }\")   # Menor que\nprint(f\"10 >= 3 = { 10 >= 3 }\") # Mayor o igual que\nprint(f\"10 <= 3 = { 10 <= 3 }\") # Menor o igual que\nprint(f\"10 == 3 = { 10 == 3 }\") # Igual que (Compara valores)\nprint(f\"10 != 3 = { 10 != 3 }\") # Diferente que (Compara valores)\nprint(f\"10 is 3 = { 10 is 3 }\") # Identidad (Compara referencias en memoria)\nprint(f\"10 is not 3 = { 10 is not 3 }\") # No identidad (Compara referencias en memoria)\nprint(f\"[1, 2, 3] is [1, 2, 3] = { [1, 2, 3] is [1, 2, 3] }\") # False porque son dos listas diferentes en memoria\nprint(f\"[1, 2, 3] == [1, 2, 3] = { [1, 2, 3] == [1, 2, 3] }\") # True porque tienen el mismo contenido\n\n#Operadores lógicos\nprint(f\"AND: 10 + 3 == 13  and 5 - 1 == 4  es {10 + 3 == 13  and 5 - 1 == 4 }\") # Devuelve True si ambos operandos son True, en otros lenguajes se puede representar con &&\nprint(f\"OR: 10 + 3 == 13  or 5 - 1 == 4  es {10 + 3 == 20  or 5 - 1 == 4 }\")   # Devuelve True si al menos uno de lass operaciones es True en otros lenguajes se puede representar con ||\nprint(f\"NOT:! not 10 + 3 ==14 { not 10 + 3 ==14 }\")# Invierte el valor booleano es decir si es True lo convierte en False y viceversa.\n\n\n#Operadores de asignación\nmy_var = 10 # Asignación simple\nprint( my_var)\nprint( f\"my_var += 5  es { my_var + 5 }\") # Suma y asigna\nprint( f\"my_var -= 3  es { my_var - 3 }\") # Resta y asigna\nprint( f\"my_var *= 2  es { my_var * 2 }\") # Multiplica y asigna\nprint( f\"my_var /= 4  es { my_var / 4 }\") # Divide y asigna\nprint( f\"my_var %= 3  es { my_var % 3 }\") # Modulo y asigna\nprint( f\"my_var **= 2 es { my_var ** 2 }\") # Exponente y asigna\nprint( f\"my_var //= 2 es { my_var // 2 }\") # División entera y asigna\n\n\"\"\"Operadores de identenidad nos permiten comparar el valor en memoria de dos variables, es decir si apuntan al mismo objeto en memoria las variables pueden tener el mismo valor pero estar en diferente espacio en memoria ( direcciones de memoria) para ello utilizamos is (identidad) y is not (no identidad)\"\"\"\n\nmy_new_var = 5 \nprint(f\"my_var es igual a my_new_var? { my_var is my_new_var }\") # False porque son diferentes en memoria\nmy_new_var = my_var\nprint(f\"my_var es igual a my_new_var?  { my_var is my_new_var }\") # True porque ahora apuntan al mismo objeto en memoria\n\n#is not es lo contrario de is\nprint(f\"my_var es diferente a my_new_var? { my_var is not my_new_var }\") # False porque ahora apuntan al mismo objeto en memoria\n\n# Operadores de pertenencia\n\"\"\"nos permiten verificar si un valor o variable está presente en una secuencia (como una lista, tupla, conjunto o cadena de texto) ¿algo esta presente dentro de algo ?\"\"\"\n\nprint(f\"10 in [1, 2, 3, 4, 5] es { 10 in [1, 2, 3, 4, 5] }\") # False porque no esta presente.\nprint(f\"10 not in [1, 2, 3, 4, 5] es { 10 not in [1, 2, 3, 4, 5] }\") # True porque no esta presente.\n\n#Operadores de bit a bit  ( nivel de bits) se utilizan para manipular datos a nivel de bits, es decir, trabajan directamente con la representación binaria de los números.\na =10 # En binario: 1010\nb = 3 # En binario: 0011\nprint(f\" ADD: a & b = { a & b }\") # AND: 0010 (2 en decimal) es decir el lenguaje compara bit a bit y si ambos son 1 devuelve 1, si alguno es 0 devuelve 0.\nprint (f\"OR: a | b = {a | b }\") # OR: 0011 ( 11 en decimal) es decir el lenguaje compara bit a bit y si alguno es 1 devuelve 1, si ambos son 0 devuelve 0.\nprint(f\"XOR: a ^ b = { a ^ b }\") #XOR: 1001 (9 en decimal) es decir  el lenguaje compara bit a bit y si los bits son diferentes devuelve 1, si son iguales devuelve 0.\nprint(f\"NOT: ~a = { ~a }\") #NOT: 0101 (5 en decimal) es decir invierte los bits, los 0s los convierte en 1s y los 1s los convierte en 0s.\nprint(f\"left shift: a << 1 = { a << 1 }\") # Desplazamiento a la izquierda: 10100 (20 en decimal) es decir desplaza todo los bits a la izquierda y completa con los ceros a la derecha.\nprint(f\"right shift: a >> 1 = { a >> 1 }\")  #Desplazamiento a la derecha: 0101 ( 5 en decimal) es decir desplaza todos los bits a la derecha y elimina el bit menos significativo.\n\n'''Estructuras de control condicionales:\nif, elif, else\nciclos:\nfor, while\nfunciones:'''\nmy_string = \" Alonso en Barcelona \"\nif \"Alonso\" in my_string: #Si Alonso está presente en my_string\n    print(f\"Alonso está presente en { my_string }\")\nelse: #si no está presente\n    print(\"Alonso no está presente en my_string\")\n\nmy_string= \" Aloween \"\nif my_string == \" Halloween\": #Si my_string es igual a \" Halloween\"\n    print(\"Feliz Halloween\")\nelif my_string == \" Aloween \": #elif se utilza para que haga comprabaciones intermedias.\n    print(\"Hola Aloween\")\nelse:\n    print(\"my_string no es ni Halloween ni Aloween\")\n\n#While es un ciclo que se repite mientras una condicion sea verdadera.\nmy_string = \" Aloween \"\nwhile my_string != \" Aloween \": #Mientras my_string sea diferente a \"Aloween\"\n    print(\"my_string no es ni Halloween ni Aloween\")\n    my_string = input(\"Ingrese Aloween: \") #Pide al usuario que ingrese \"Aloween\"\n\ni = 1\nwhile i <= 10:\n    print(i)\n    i +=1  \n#Ciclo for se utiliza para iterar sobre una secuencia ( lista, tupla, diccionario, conjunto o de cadena de texto). Es decir, nos vale para recorrer una estructura de datos o ejecutar una accion un numero determinado de veces.\nfor i in range(5): #Rango recorre toda la secuendia que le indiquemos, en este caso del 0 al 4\n    print(i) #Imprime el valor de i en cada iteracion\n\n#Manejo de Excepciones ( son estructuras de control que nos permiten manejar errores en tiempo de ejecucion para evitar que el programa se detenga abruptamente)\ntry:\n    print(10 / 0) #Intentamos dividir por cero\nexcept:\n    print(\"Error: No se puede dividir por cero\") #Imprimimos un mensaje de error\nfinally:\n    print(\"Fin del programa\") #Se ejecuta siempre al final del bloque try-except\n\n\n'''Extra'''\n\nfor number in range(10, 56):\n    if number % 2 == 0 and number != 16 and number % 3 == 0:\n        print(number)\n   "
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Alvaro-Neyra.py",
    "content": "# Operadores Aritmeticos:\n\n# Suma\nsuma = 4 + 5\nprint(suma)\n# Resta\nresta = 9 - 3\nprint(resta)\n# Multiplicacion\nmultiplicacion = 5 * 6\nprint(multiplicacion)\n# Division\ndivision = 20 % 5\nprint(division)\n# Modulo\nmodulo = 20 % 2\nprint(modulo)\n# Exponente\nexponente = 4 ** 2\nprint(exponente)\n# Division Baja o Division Entera\ndivision_baja = 5 // 2\nprint(division_baja)\n\n# Operadores de comparacion: >, <, ==, >=, <=, !=\n\n# > (Mayor que)\nprint(30 > 10) # True\n# < (Menor que)\nprint(20 < 30) # False\n# == (Igual que)\nprint(\"hola\" == 'hola') # True\n# >= (Mayor o Igual que)\nprint(20 >= 20) # True\n# <= (Menor o Igual que)\nprint(20 <= 30) # True\n# != (No Igual que)\nprint(20 != 200) # True\n\n\n# Operadores Logicos: and, or, not\n\n# and\nprint(40 > 10 and \"hola\" == \"Hola\".lower()) # Imprime True, ya que las dos condiciones son verdaderas\n\n# or\nprint(30 - 20 == 10 or 30 - 20 == 100) # Imprime True, si una de las condiciones son verdaderas\n\n# not\nprint(not 20 - 10 == 10) # Imprime False, ya que la condicion es True y el operador NOT invierte al valor contrario\n\n\n# Operadores Bit a Bit: &, |, ^, ~, >>, <<\n\n# & (AND bit a bit)\nnumero_binario1 = 8 # --> 0b1000\nnumero_binario2 = 4 # --> 0b0100\n\"\"\"Este operador primero convierte sus operandos a numeros binarios para luego comparar cada bit con AND. Si 1 AND 1 es 1, 1 AND 0 es 0.\"\"\"\nresultado_binario = numero_binario1 & numero_binario2\nprint(resultado_binario) #0b0000 --> 0\n\n# | (OR bit a bit)\nnumero_binario3 = 5 # --> 0b0101\nnumero_binario4 = 10 # --> 0b1010\n\"\"\"Este operador primero convirte sus operandos a numeros binarios para luego comparar cada bit con OR. Si 1 OR 0 es 1, 0 OR 0 es 0, entonces\n1 OR 1 es 1\"\"\"\nresultado_binario2 = numero_binario3 | numero_binario4\nprint(resultado_binario2) # 0b1111 --> 15\n\n# ^ (XOR bit a bit)\nnumero_binario5 = 7 # --> 0b0111\nnumero_binario6 = 2 # --> 0b0010\n\"\"\"Este operador primero convirte sus operandos a numeros binarios para luego comparar cada bit con XOR. En XOR si los numeros que se estan\ncomparando son iguales es 0 y sin son diferentes es 1\"\"\"\nresultado_binario3 = numero_binario5 ^ numero_binario6\nprint(resultado_binario3) # 0b0101 --> 5\n\n# >> (desplazamiento a la derecha bit a bit)\nnumero_binario7 = 6 # --> 0b0110\ndesplazar_x = 1\n\"\"\"Este operador primero convierte el primer operando a binario luego desplaza cada bit del extremo izquierdo x(el otro operando) veces\nhacia la derecha\"\"\"\nresultado_binario4 = numero_binario7 >> desplazar_x\nprint(resultado_binario4) # 0b0011 --> 3\n\n# << (desplazamiento a la izquierda bit a bit)\nnumero_binario8 = 3 # --> 0b00000011\ndesplazar_y = 8\n\"\"\"Este operador primero convierte el primer operando a binario luego desplaza cada bit del extremo derecho x(el otro operando) veces\nhacia la izquierda\"\"\"\nresultado_binario5 = numero_binario8 << desplazar_y\nprint(resultado_binario5) # 0b1100000000 --> 768\n\n# Operadores de asignacion: =, +=, -=, *=, /=, %=, **=, //=, &=, |=, ^=, >>=, <<=\n\n# = (Operador de asignacion)\nvariable_numerica = 40 - 20\nprint(variable_numerica)\n\n# += (Operador de suma y asignacion)\nnumero= 20\nnumero += 10\n\nprint(numero) # 30\n\n# -= (Operador de resta y asignacion)\nnumero1 = 50\nnumero1 -= 10\nprint(numero1) # 40\n\n# *- (Operador de multiplicaion y asignacion)\nnumero2 = 30\nnumero2 *= 2\nprint(numero2) # 60\n\n# /= (Operador de division y asignacion)\nnumero3 = 40\nnumero3 /= 2\nprint(numero3) # 20\n\n# %= (Operador de modulo y asignacion)\nnumero4 = 30\nnumero4 %= 5\nprint(numero4) # 0 # 30 es divisible por 5\n\n# **/ (Operador de potencia y asignacion)\nnumero5 = 2\nnumero5 **= 3\nprint(numero5) # 8\n\n# //= (Operador de division entera y asignacion)\nnumero6 = 400\nnumero6 //= 3\nprint(numero6) # 133 (el operador de division entera, divide los dos operandos y devuelve el cociente entero descartando cualquier parte decimal)\n\n# &= (Operador de AND bit a bit y asignacion) \n\"\"\" Este Operador de asignacion (&=), primero convierte cada operando a numeros binarios luego compara con AND cada bit\nen la posicion correspondiente de cada numero binario. Si el resultado de True AND False es False, el resultado de 1 AND 0 es 0 y si\nel resultado de True AND True es True entonces el resultado de 1 AND 1 es 1. (Asi se van a ir comparando cada bit de los numeros binarios)\"\"\"\nx = 5 # en binario: 0b101\ny = 3 # en binario: 0b011\nx &= y # se comparan con AND 0b101 y 0b011, la respuesta seria 0b001. --> 1\n\"\"\"Se compara cada bit de cada operando en sus posiciones correspondientes, si en el primer numero binario su ultimo\nbit es 1 y en el segundo numero binario su ultimo bit es 1, la respuesta de la ultimo bit del resultado seria 1 ya que se esta usando AND.\nAsi se compara cada bit restante de los operandos para hallar el numero binario resultante.\nRecuerden los bits de los numeros binarios estan compuestos solo por 0 y 1. \"\"\"\nprint(x) # 1\n\n# |= (Operador de OR bit a bit y asignacion)\n\"\"\"Este Operador de asignacion (|=), primero convierte cada operando a numeros binarios luego compara con OR cada bit\nen la posicion correspondiente de cada numero binario. Si el resultado de True OR False es True, el resultado de 1 OR 0 es 1 y si\nel resultado de True OR True es True entonces el resultado de 1 OR 1 es 1. (Asi se van a ir comparando cada bit de los numeros binarios)\"\"\"\nz = 8 # en binario: 0b1000\ng = 3 # en binario: 0b0011\nz |= g # se comparan con OR 0b1000 y 0b0011, la respuesta es 0b1011. --> 11\n\"\"\"Se compara cada bit de cada operando en sus posiciones correspondientes, si en primer numero binario su ultimo bit es 0\ny el en segundo numero binario su ultimo bit es 1, la respuesta del ultimo bit del resultado es 1 ya que se esta usando OR\"\"\"\nprint(z)\n\n# ^= (Operador de XOR bit a bit y asignacion)\n\"\"\"Este Operador de asignacion (^=), primero convierte cada operando a numeros binarios luego compara con XOR cada bit\nen la posicion correspondiente de cada numero binario. La operacion XOR bit a bit devuelve 1 en el bit resultante si los bits correspondientes\nson diferentes y 0 si son iguales\"\"\"\nm = 5 # en binario: 0b101\nn = 3 # en binario: 0b011\nm ^= n # se comparan con XOR 0b101 y 0b011, la respuesta es 0b110. --> 6\nprint(m)\n\n# >>= (Operador de desplazamiento a la derecha con asignacion)\n\"\"\"Este Operador de asignacion (>>=), primero convierte el operando principal (el mas a la izquierda) a binario y \nluego desplaza sus bits n(el otro operando) veces hacia la derecha, habran bits que se desplazaran fuera y se perderan. Los espacios\nen donde estaban los bits desplazados seran reemplazandos por 0\"\"\"\nbinario1 = 8 # en binario: 0b1000\ndesplazar_n = 2\nbinario1 >>= desplazar_n # Se desplazan los bits de la izquierda hacia la derecha y las posiciones donde estaban los bits se reemplazan por 0 --> 0b0010\nprint(binario1) # 2\n\n# <<= (Operador de desplazamiento a la izquierda con asignacion)\n\"\"\"Este operador de asignacion (<<=), primero convierte el operando principal (el mas a la izquierda) a binario y\nluego desplaza sus bits n(el otro operando) veces hacia la izquierda, habran bits que se desplazaran fuera y se perderan. Los espacios\nen donde estaban los bits desplazados seran reemplazados por 0\"\"\"\nbinario2 = 2 # en binario: 0b0010\ndesplazar_m = 2\nbinario2 <<= desplazar_m # Se desplazan los bits de la derecha hacia la izquierda y las posiciones donde estaban los bits se reemplazan por 0 --> 0b1000\nprint(binario2) # 0b1000 --> 8\n\n# Operadores de identidad: is , is not\n\n# is devuelve True si los operandos se refieren al mismo objecto. De lo contrario devuelve False\n# is not devuelve True si los operandos no se refieren al mismo objecto. De lo contrario devuelve False\n\na = 2\nb = 10\nc = 2\nprint(a is b) # --> False\nprint(a is not c) # --> False\nprint(a is c) # --True\n\n# Operadores de pertenencia: in, not in\n\n# in devuelve True si el valor especificado se encuentra en la secuencia (objeto). De lo contrario devuelve False\n# not in devuelve True si el valor especificado no se encuentra en la secuencia (objeto). De lo contrario devuelve False\n\nlista_de_numeros = [20, 50, 100, 70, 400]\nprint(30 in lista_de_numeros) # False\ncadena_de_texto = \"Hola, Mundo!\"\nprint(\"H\" in cadena_de_texto) # True\n\n# Estructuras de control:\n# Condicional if, elif y else\n\nganancia = int(input(\"Cuanto dinero ganas al mes aproximadamente?: \"))\ngasto = int(input(\"Cuanto gastas aproximadamente cada mes?: \"))\n\nif ganancia/3 >= gasto :\n    print(\"Estas ahorrando correctamente!!\")\nelif ganancia/2 >= gasto:\n    print(\"Estas ahorrando!!\")\nelif ganancia > gasto and gasto <= ganancia * 0.8:\n    print(\"Estas ahorrando pero puedes ahorrar mucho mas!!\")\nelse:\n    print(\"No estas ahorrando correctamente!\")\n\n# Bucles for, while\nlista_iterable = [\"Hola\", \"mi\", \"nombre\", \"es\", \"Alvaro\", \"Neyra\"]\n\n#for\n\nfor palabra in lista_iterable:\n    print(palabra)\n\n# for, range\n    \nfor i in range(10):\n    print(f\"{i + 1}\")\n\n# while and exceptions: Se ejecuta ilimitadamente hasta que la condicion sea falsa\n\nwhile True:\n    print(\"Dividir dos numeros....\")\n    dividir_numero1 = int(input(\"Primer operando: \"))\n    dividir_numero2 = int(input(\"Segundo operando: \"))\n    try:\n       resultado_de_la_division = dividir_numero1 / dividir_numero2\n    except ValueError as e:\n        print(\"Tiene que ser un numero!!\")\n        print(f\"Error: {e}\")\n    except Exception as Error:\n        print(f\"Error cometido: {Error}\")\n    else:\n        break\n    finally:\n        print(\"Finally siempre se ejecuta siempre!\")\n\nprint(resultado_de_la_division)\n\n# for, zip()\nnumeros = [8, 100, 200]\nse_llaman = [\"Ocho\", \"Cien\", \"Doscientos\"]\n\nfor e, i in zip(numeros, se_llaman):\n    print(f\"{e} se llama: {i}\")\n\n# for, enumerate():\nlista_de_elementos = [\"Palabra\", True, 300]\n\nfor indice, elemento in enumerate(lista_de_elementos):\n    print(f\"Este es el elemento: {elemento} del indice: {indice}\")\n\n# Crea un programa que imprima por consola todos los números comprendidos entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\ndef dificultad_extra():\n    for i in range(10, 56):\n        if i == 16:\n            continue\n        if i % 3 == 0:\n            continue\n        if i % 2 != 0:\n            continue\n\n        print(i)\n\ndificultad_extra()"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/AndresMCardenas.py",
    "content": "### Operadores ###\n\n# Operadores aritméticos\n\n# Suma\nprint(2 + 2)  \n\n# Resta\nprint(2 - 2)\n\n# Multiplicación\nprint(2 * 2)  \n\n# División  \nprint(3 / 2)\n\n# División entera \nprint(10 // 2)\n\n# Módulo \nprint(10 % 2)\n\n# Potencia \nprint(2 ** 3)\n\n# Operadores de comparación\n\n# Igualdad  \nprint(2 == 2)\nprint(2 == 3)\n\n# Desigualdad\nprint(2 != 3)\nprint(2 != 2) \n\n# Mayor que\nprint(2 > 3)  \nprint(3 > 2)  \n\n# Menor que\nprint(2 < 3)\nprint(3 < 2)\n\n# Mayor o igual que \nprint(2 >= 3)\nprint(3 >= 2)\n\n# Menor o igual que\nprint(2 <= 3)\nprint(3 <= 2)\n\n# Operadores lógicos\n\n# AND comparación de dos valores booleanos o variables y devuelve True si ambos son True\nprint(True and True) # Imprime True\nprint(True and False) # Imprime False\nprint(3 > 2 and 2 > 3)  # Imprime False\n\n# OR comparación de dos valores booleanos o variables y devuelve True si alguno es True\nprint(True or False) # Imprime True\nprint(False or False) # Imprime False\nprint(3 > 2 or 2 > 3)  # Imprime True\n\n# NOT niega el valor booleano o variable\nprint(not True) # Imprime False\nprint(not False) # Imprime True\nprint(not 3 > 2) # Imprime False\n\n# Operadores de asignación\nq = 2\n\n# Asignación simple\nprint(q)\n\n# Asignación de suma\nq += 2 # q = q + 2 daria el mismo resultado = 4\nprint(q)\n\n# Asignación de resta\nq -= 2 # q = q - 2 daria el mismo resultado = 2\nprint(q)\n\n# Asignación de multiplicación\nq *= 2 # q = q * 2 daria el mismo resultado = 4\nprint(q)\n\n# Asignación de división\nq /= 2 # q = q / 2 daria el mismo resultado = 2\nprint(q)\n\n# Asignación de división entera\nq //= 2 # q = q // 2 daria el mismo resultado = 1\nprint(q)\n\n# Asignación de módulo\nq %= 2 # q = q % 2 daria el mismo resultado = 0\nprint(q)\n\n# Asignación de potencia\nq **= 2 # q = q ** 2 daria el mismo resultado = 0\nprint(q)\n\n# Operadores de identidad\nprint(2 is 2) # da True porque son el mismo objeto\nprint(2 is not 2) # da False porque son el mismo objeto\n\n# is\nprint(2 is 2) # da True porque son el mismo objeto\nprint(2 is 3) # da False porque no son el mismo objeto\n\n# is not\nprint(2 is not 2) # da False porque son el mismo objeto\nprint(2 is not 3) # da True porque no son el mismo objeto\n\n# Operadores de pertenencia\nlista = [1, 2, 3, 4, 5, 6]\nprint(lista)\n\n# in\nprint(2 in lista) # da True porque el 2 esta en la lista\nprint(7 in lista) # da False porque el 7 no esta en la lista\n\n# not in\nprint(2 not in lista) # da False porque el 2 esta en la lista\nprint(7 not in lista) # da True porque el 7 no esta en la lista\n\n# Operadores de bits\n\"\"\"\neso es para operar con bits, pero no se como se usa\nson los siguientes:\nAND (&) \nOR (|)\nXOR (^)\nNOT (~)\nDesplazamiento a la izquierda (<<)\nDesplazamiento a la derecha (>>)\n\"\"\"\n\n# AND\na = 5 & 3 # da 1\nprint(0b1010 & 0b1100) # da 8\n\n# OR\na = 5 | 3 # da 7\nprint(0b1010 | 0b1100) # da 12\n\n# XOR\na = 5 ^ 3 # da 6\nprint(0b1010 ^ 0b1100) # da 4\n\n# NOT\na = ~5 # da -6\nprint(a)\n\n# Desplazamiento a la izquierda\na = 5 << 3 # da 40\nprint(a)\n# Desplazamiento a la derecha\na = 5 >> 3 # da 0\nprint(a)\n# Operadores de precedencia\n\"\"\" \"\"\"\n\n# () para agrupar operaciones\nprint(2 + 3 * 5) # da 17\n\nprint(2 ** 3 ** 2) # da 512\n\nprint(2 + 3 * 5) # da 17\n\n# estructura de control\n\n# if se usa para evaluar una condición y ejecutar un bloque de código si se cumple\nif (2 + 3) * 5 == 25:\n    print(\"Correcto\")# se ejecuta si la condición es verdadera\nelif (2 + 3) * 5 == 30: \n    print(\"Casi\")# se ejecuta si la primera condición no se cumple y la segunda si\nelse: \n    print(\"Incorrecto\") # se ejecuta si ninguna de las condiciones anteriores se cumple\n\n# for se usa para iterar sobre una secuencia de elementos\n    \nfor i in range(5): # se ejecuta 5 veces\n    print( \"For \" + str(i)) # imprime hola y el valor de i\n\n# while se usa para ejecutar un bloque de código mientras se cumpla una condición\ni = 0\nwhile i < 5: # se ejecuta mientras i sea menor que 5\n    print( \"While \" + str(i)) # imprime hola y el valor de i\n    i += 1 # incrementa el valor de i en 1\n\n# try se usa para probar un bloque de código en busca de errores\ntry:\n  print(10 / 0) # intenta dividir 10 entre 0  \nexcept ZeroDivisionError:\n  print(\"Error: División entre cero\")\nfinally:\n  print(\"Terminado\")\n\n# With se usa para ejecutar un bloque de código con un recurso externo\n\"\"\"\nwith open(\"archivo.txt\") as f: # abre el archivo y lo asigna a la variable f\n  print(f.read()) # imprime el contenido del archivo\n\"\"\"\n\n\"\"\"\n DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\"\"\"\n\nprint(\" ejercico con for\")\nfor extra in range(10, 56): # extra inicia en 10 y se ejecuta mientras extra sea menor que 56\n    if extra % 2 == 0 and extra != 16 and extra % 3 != 0: # si el numero es par y no es 16 y no es multiplo de 3\n        print(extra)  # imprime el numero en extra\n\nprint(\" ejercico con while\")\nextra2 = 10 # extra inicia en 10\nwhile extra2 <= 55: # se ejecuta mientras extra sea menor que 56\n    if extra2 % 2 == 0 and extra2 != 16 and extra2 % 3 != 0: # si el numero es par y no es 16 y no es multiplo de 3\n        print(extra2)  # imprime el numero en extra\n    extra2 += 1 # incrementa el valor de extra en 1"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Angel-Delg.py",
    "content": "# Operadores Aritméticos\nnum1 = 10\nnum2 = 5\nsuma = num1 + num2\nresta = num1 - num2\nmultiplicacion = num1 * num2\ndivision = num1 / num2\nmodulo = num1 % num2\npotencia = num1 ** num2\n\nprint(\"Operadores Aritméticos:\")\nprint(\"Suma:\", suma)\nprint(\"Resta:\", resta)\nprint(\"Multiplicación:\", multiplicacion)\nprint(\"División:\", division)\nprint(\"Módulo:\", modulo)\nprint(\"Potencia:\", potencia)\n\n# Operadores de Comparación\nigual = (num1 == num2)\ndiferente = (num1 != num2)\nmayor_que = (num1 > num2)\nmenor_que = (num1 < num2)\nmayor_o_igual = (num1 >= num2)\nmenor_o_igual = (num1 <= num2)\n\nprint(\"\\nOperadores de Comparación:\")\nprint(\"Igual:\", igual)\nprint(\"Diferente:\", diferente)\nprint(\"Mayor que:\", mayor_que)\nprint(\"Menor que:\", menor_que)\nprint(\"Mayor o igual:\", mayor_o_igual)\nprint(\"Menor o igual:\", menor_o_igual)\n\n# Operadores Lógicos\nand_op = (num1 > 0) and (num2 < 0)\nor_op = (num1 > 0) or (num2 < 0)\nnot_op = not (num1 > 0)\n\nprint(\"\\nOperadores Lógicos:\")\nprint(\"AND:\", and_op)\nprint(\"OR:\", or_op)\nprint(\"NOT:\", not_op)\n\n# Operadores de Asignación\na = 5\na += 2  # Equivalente a: a = a + 2\nb = 10\nb *= 3  # Equivalente a: b = b * 3\n\nprint(\"\\nOperadores de Asignación:\")\nprint(\"a:\", a)\nprint(\"b:\", b)\n\n# Estructuras de Control - Condicionales\nif num1 > num2:\n    print(\"\\nCondicionales:\")\n    print(\"num1 es mayor que num2\")\nelif num1 == num2:\n    print(\"num1 es igual a num2\")\nelse:\n    print(\"num1 es menor que num2\")\n\n# Estructuras de Control - Iterativas\nprint(\"\\nIterativas:\")\nfor i in range(10, 56):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print(i, end=\" \")\n\n# Estructuras de Control - Excepciones\ntry:\n    resultado = num1 / 0\nexcept ZeroDivisionError:\n    print(\"\\n\\nExcepciones:\")\n    print(\"Error: División por cero\")\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Angell4S.py",
    "content": "print(\"### Operadores Aritméticos ###\")\nsuma = 5 + 5\nresta = 10 - 2\nmulti = 5 * 2\ndiv = 6 / 3\npontencia = 2 ** 3\nprint(f\"suma: {suma}, resta: {resta}, multi: {resta}, división: {div}, pontencia: {pontencia}\")\n\nprint(\"### Operadores Lógicos ###\")\n\nprint(\"## Comparación ##\")\nmayor = 4 > 3\nmenor = 5 < 3\nigual = 5 == 5\nmayorigual = 5 >= 5\nmenorigual = 7 <= 5\ndiferente = 3 != 4\nprint(mayor, menor, igual, mayorigual, menorigual, diferente)\n\nprint(\"## Asignación ##\")\nx = 4\nx = x + 1\nx += 1\n\nd = 5\nd *= 2\nprint(x, d)\n\nprint(\"## Identidad ##\")\na = 1\nb = 2\nc = 4\nprint(a is 1)\nprint(b is not 2)\n\nprint(\"## Pertenencia ##\")\nlist = [1,2,3,4,5]\nprint(3 in list)\nprint(6 in list)\nprint(6 not in list)\n\nprint(\"## BIT ##\")\na = 10\nb = 3\nprint(f\"AND: 10 & 3 = {10 & 3}\")\nprint(f\"OR: 10 | 3 = {10 | 3}\")\nprint(f\"XOR: 10 ^ 3 = {10 ^ 3}\")\nprint(f\"NOT: ~10 = {~10}\")\nprint(f\"Desplazamiento a la derecha: 10 >> 2 = {10 >> 2}\")\nprint(f\"Desplazamiento a la izquierda: 10 << 2 = {10 << 2}\")\n\nprint(\"### Estructuras de control ###\")\nprint(\"## IF ##\")\nedad = 18\nif edad is 18:\n   print(\"Es mayor de edad\")\nelse:\n   print(\"Menor de edad\")\n\nprint(\"## FOR ##\")\nfor num in range(13):\n   print(f\"5 * {num} = {5 * num}\")\n\nprint(\"## WHILE ##\")\nn = -1\nwhile n < 12:\n   n += 1\n   print(f\"5 * {n} = {5 * n}\")\n\nprint(\"## EXCEPCIONES ##\")\ntry:\n   print(10 / 1)\nexcept:\n   print(\"Se ha producido un error\")\nfinally:\n   print(\"Ha finalizado el manejo de excepciones\")\n\n\nprint(\"### EXTRA ###\")\nfor number in range(10, 56):\n   if number % 2 == 0 and number != 16 and number % 3 != 0:\n      print(number)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Anvildestroyer.py",
    "content": "var_numero1 = 1\nvar_numero2 = 2\nvar_numero3 = 4\nvar_numero4 = 4\n\n\"\"\"Operadores Aritméticos\"\"\"\n#Suma\nprint (f\"suma = {var_numero1 + var_numero2}\") \n#Resta\nprint (f\"resta = {var_numero1 - var_numero2}\") \n#Multiplicación\nprint (f\"multiplicación = {var_numero1 * var_numero2}\") \n#División\nprint (f\"división = {var_numero1 / var_numero2}\")\n#División entera\nprint (f\"división_entera = {var_numero1 // var_numero2}\")\n#Modulo\nprint (f\"modulo = {var_numero1 % var_numero2}\")\n#Potencia\nprint (f\"potencia = {var_numero1 ** var_numero2}\")\n\n\n\"\"\"Operadores Lógicos\"\"\"\n#and o conocido como \"y\" \nif var_numero1 == var_numero2 and var_numero3 == var_numero4:\n    print (\"son iguales\")\nelse:\n    print (\"no son iguales\")\n\n#or o conocido como \"o\"\nif var_numero1 == var_numero2 or var_numero3 == var_numero4:\n    print (\"son iguales\")\nelse:\n    print (\"no son iguales\")\n\n#not o conocido como \"no\"\noperando_no =  not (var_numero1 == var_numero2)\nif operando_no == True:\n        print (\"esta correcto el operando\")\nelse:\n        print (\"¿se ha equivocado?\")\n\n\n\"\"\"Operadores comparación\"\"\"\n\nprint (f\"Mayor que: {var_numero1 > var_numero2}\") \nprint (f\"Menor que: {var_numero1 < var_numero2}\")\nprint (f\"Igual que: {var_numero1 == var_numero2}\")\nprint (f\"Mayor igual que: {var_numero1 >= var_numero2}\")\nprint (f\"Menor igual que: {var_numero1 <= var_numero2}\")\nprint (f\"No es igual: {var_numero1 != var_numero2}\")\n\n\"\"\"Operadores asignación\"\"\"\n#operador =  el valor 7 es asignado a la variable var_operador1\nvar_operador1 = 2\nvar_operador2 = 1\n#operador += es equivalente a var_operador1 = var_operador1 + 7\nvar_operador1 += 7\n#operador -= es equivalente a var_operador1 = var_operador1 - 7\nvar_operador1 -= 7\n#operador *= es equivalente a var_operador1 = var_operador1 * 7\nvar_operador1 *= 7\n#operador /= es equivalente a var_operador1 = var_operador1 / 7\nvar_operador1 /= 7\n#operador %= es equivalente a var_operador1 = var_operador1 % 7\nvar_operador1 %= 7\n#operador **= es equivalente a var_operador1 = var_operador1 ** 7\nvar_operador1 **= 7\n#operador //= es equivalente a var_operador1 = var_operador1 // 7\nvar_operador1 -= 7\n#operador &= es un operador bit a bit  es equivalente a var_operador1 = var_operador1 & 7\nvar_operador2 &= 7\n#operador |= es un operador bit a bit  es equivalente a var_operador1 = var_operador1 | 7\nvar_operador2 |= 7\n#operador ^= es equivalente a var_operador1 = var_operador1 ^ 7\nvar_operador2 ^= 7\n#operador >>= es un operador bit a bit  es equivalente a var_operador1 = var_operador1 >>= 7\nvar_operador2 >>= 7\n#operador <<= es es un operador bit a bit  es equivalente a var_operador1 = var_operador1 <<= 7\nvar_operador2 <<= 7\n\n\n\"\"\"Operadores identidad\"\"\"\nx = 1\ny = x\nz = y\nprint (id(z))# muestra el valor de objeto 140732182763960\nprint (id(x))# muestra el valor de objeto 140732182763960\nprint (z is x) # muestra True por que comparten el mismo valor de Objeto, esto no quiere decir que compartan valor asignado.\nprint (z is not x) # muestra False por que comparten el mismo valor de Objeto, esto no quiere decir que compartan valor asignado.\n\n\"\"\"Operadores Pertenencia\"\"\"\nb = [5,4,3,2,1]\n#Esta 3 en la lista a?\nprint (9 in b) # Muestra True  \n#No está 12 en la lista a?\nprint (12 not in b) # Muestra True\n\n\"\"\"Operadores Bit a Bit\"\"\"\n#AND bit a bit (&): \na = 60  # 60 = 0011 1100\nb = 13  # 13 = 0000 1101\nprint(a & b)  # Resultado es 12 = 0000 1100\n#OR bit a bit (|):\na = 60  # 60 = 0011 1100\nb = 13  # 13 = 0000 1101\nprint(a | b)  # Resultado es 61 = 0011 1101\n#XOR bit a bit (^):\na = 60  # 60 = 0011 1100\nb = 13  # 13 = 0000 1101\nprint(a ^ b)  # Resultado es 49 = 0011 0001\n#NOT bit a bit (~):\na = 60  # 60 = 0011 1100\nprint(~a)  # Resultado es -61 = 1100 0011\n#Desplazamiento a la izquierda (<<): \na = 60  # 60 = 0011 1100\nprint(a << 2)  # Resultado es 240 = 1111 0000\n#Desplazamiento a la derecha (>>): \na = 60  # 60 = 0011 1100\nprint(a >> 2)  # Resultado es 15 = 0000 1111\n\n\n# Estructuras de control\n\n# Condicionales If,  elif y else, permite ejecutar un bloque de código si una condición específica es verdadera.\nedad = 18\nif edad < 18:\n    print(\"Menor de edad\")\nelif edad >= 18:\n    print(\"Mayor de edad\")\nelse:\n    print(\"Este código nunca se ejecutará\")\n\n# While  se utilizara mientras una condición sea verdadera.\ncontador = 0\nwhile contador < 3:\n    print(\"Dentro del bucle\")\n    contador += 1\n\n# For se utiliza para iterar sobre una secuencia\nfrutas = [\"manzana\", \"banana\", \"cereza\"]\nfor fruta in frutas:\n    print(fruta)\n\n#try-except - Excepciones\na = 0\nb = 6\n\ntry:\n    c = a / b \nexcept ZeroDivisionError:\n    print(\"Estás intentando dividir por cero\")\n\n#Range  genera una secuencia de números que van desde 0 por defecto hasta el número que se pasa como parámetro menos 1\n\nfor i in range(6):\n    print(i) #0, 1, 2, 3, 4, 5\n\n# Break\nfor num in range(5):\n    if num == 3:\n        break    # Sale del bucle\n    print(num)\n\n# Continue\nfor a in range(5):\n    if a == 2:\n        continue\n    print(f\"a es {a}\")\n\n\n#reto\n\n\"\"\"\n* Crea un programa que imprima por consola todos los números comprendidos\n* entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\"\"\"\n\ni = 9\nwhile i <= 54:\n    i += 1\n    if (i % 2 == 0) and (i != 16) and (i % 3 != 0):\n        print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Aquiles735.py",
    "content": "  #variables para las operaciones\nnum_a= 5\nnum_b=10\n\nprint(num_a+num_b) #15\nprint(num_b-num_a)  #5\nprint(num_a*num_b)  #50\nprint(num_a/num_b)  #0.5\nprint(num_a%num_b)  #5\nprint(num_b**num_a) #100000\nprint(num_b//num_a) #2\n\n\nprint(\"Ejemplo de condicional if\")\n\nif num_a > num_b:\n    print(\"True\") \nelse:\n    print(\"false\")       # false\n\n\nprint(\"Ejemplo de iterativa\")\nc=10\nwhile c<55:\n    print(c)\n    c +=2\n    print(55)\n        \n\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/ArtDugarte.py",
    "content": "import random;\n\n# --------------------------  TIPOS DE OPERADORES EN PYTHON -------------------------- \n\nnum1 = random.randint(1, 99);\nnum2 = random.randint(1, 99);\n\n# Operadores aritméticos:\n\nprint(\"-----------------OPERADORES ARITMÉTICOS-----------------\" + \"\\n\");\n# Suma: +\nprint(f\"SUMA: {num1} + {num2} = {num1 + num2}\" + \"\\n\");\n\n# Resta: -\nprint(f\"RESTA: {num1} - {num2} = {num1 - num2}\" + \"\\n\");\n\n# Multiplicación: *\nprint(f\"MULTIPLICACION: {num1} * {num2} = {num1 * num2}\" + \"\\n\");\n\n# División: /\nprint(f\"DIVISION: {num1} / {num2} = {float(num1 / num2):.2f}\" + \"\\n\");\n\n# Módulo: %\nprint(f\"MODULO: {num1} % {num2} = {num1 % num2}\" + \"\\n\");\n\n# Potencia: **\nprint(f\"POTENCIA: {num1} ** {num2} = {num1 ** num2}\" + \"\\n\");\n\n# División entera: //\nprint(f\"DIVISION ENTERA: {num1} // {num2} = {num1 // num2}\" + \"\\n\");\n\n# Operadores de comparación:\nprint(\"-----------------OPERADORES DE COMPARACIÓN-----------------\" + \"\\n\");\n# Igual: ==\nprint(f\"IGUAL: {num1} == {num2} = {num1 == num2}\" + \"\\n\");\n\n# Diferente: !=\nprint(f\"DIFERENTE: {num1} != {num2} = {num1 != num2}\" + \"\\n\");\n\n# Mayor que: >\nprint(f\"MAYOR QUE: {num1} > {num2} = {num1 > num2}\" + \"\\n\");\n\n# Menor que: <\nprint(f\"MENOR QUE: {num1} < {num2} = {num1 < num2}\" + \"\\n\");\n\n# Mayor o igual que: >=\nprint(f\"MAYOR O IGUAL QUE: {num1} >= {num2} = {num1 >= num2}\" + \"\\n\");\n\n# Menor o igual que: <=\nprint(f\"MENOR O IGUAL QUE: {num1} <= {num2} = {num1 <= num2}\" + \"\\n\");\n\n# Operadores de asignación:\nprint(\"-----------------OPERADORES DE ASIGNACIÓN-----------------\" + \"\\n\");\n# =\nnum3 = num1;\nprint(f\"NUM3 = NUM1: {num3} = {num1}\" + \"\\n\");\n\n# Operadores de identidad:\nprint(\"-----------------OPERADORES DE IDENTIDAD-----------------\" + \"\\n\");\n# is\nprint(f\"IDENTIDAD: {num1} is {num2} = {num1 is num2}\" + \"\\n\");\n\n# is not\nprint(f\"IDENTIDAD: {num1} is not {num2} = {num1 is not num2}\" + \"\\n\");\n\n# Operadores de pertenencia:\nprint(\"-----------------OPERADORES DE PERTENENCIA-----------------\" + \"\\n\");\n\n# in\nVector = [random.randint(1, 99) for i in range(10)]\nprint(f\"PERTENECE: {num1} in {Vector} = {num1 in Vector}\" + \"\\n\");\n\n# not in\nprint(f\"NO PERTENECE: {num1} not in {Vector} = {num1 not in Vector} \" + \"\\n\");\n\n# Operadores de bits:\nprint(\"-----------------OPERADORES DE BITS-----------------\" + \"\\n\");\n# &\nprint(f\"&: {num1} & {num2} = {num1 & num2}\" + \"\\n\");\n\n# |\nprint(f\"|: {num1} | {num2} = {num1 | num2}\" + \"\\n\");\n\n# ^\nprint(f\"^: {num1} ^ {num2} = {num1 ^ num2}\" + \"\\n\");\n\n# ~\nprint(f\"~: {num1} ~ {num2} = {~num1}\" + \"\\n\");\n\n# <<\nprint(f\"<<: {num1} << {num2} = {num1 << num2}\" + \"\\n\");\n\n# >>\nprint(f\">>: {num1} >> {num2} = {num1 >> num2}\" + \"\\n\");\n\n# Operadores lógicos:\nprint(\"-----------------OPERADORES LÓGICOS-----------------\" + \"\\n\");\n\nboolean1 = bool(random.randint(0, 1));\nboolean2 = bool(random.randint(0, 1));\n\n# and\nprint(f\"AND: {boolean1} and {boolean2} = {boolean1 and boolean2}\" + \"\\n\");\n\n# or\nprint(f\"OR: {boolean1} or {boolean2} = {boolean1 or boolean2}\" + \"\\n\");\n\n# not\nprint(f\"NOT: {boolean1} not = {not boolean1}\" + \"\\n\");\n\n\n# --------------------------  TIPOS DE ESTRUCTURAS DE CONTROL -------------------------- \n\n# Ciclos, Condicionales y Exepciones:\nprint(\"-----------------ESTRUCTURAS DE CONTROL-----------------\");\ntry:\n    print(Vector[10])\nexcept:\n\n    # For\n\n    print (\"\\n\" + \"For:\" + \"\\n\")\n    x = 0\n    for i in (Vector):\n        x += 1\n        print(f\"{x} = {i}\"); \n\n    # While con Condicionales\n\n    print (\"\\n\" + \"While con Condicionales:\" + \"\\n\")\n    while x > 0:\n        \n        if x in Vector:\n            print(f\"{x} Somos iguales {x}\");\n        elif x not in Vector:\n            print(f\"{x} No encontré un elemento parecido\");\n        else :\n            print(f\"{x} No es un número {x}\");\n        x -= 1;\n\n\n# EXTRA:\n\nprint(\"\\n\" + \"-----------------EJERCICIO EXTRA-----------------\" + \"\\n\");\n\nfor i in range(10, 56):\n    if (i == 16 or not i%2==0 or i%3==0):\n        continue\n    print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/BerlinBeltranAvila.py",
    "content": "# #01 OPERADORES Y ESTRUCTURAS DE CONTROL\n#### Dificultad: Fácil | Publicación: 02/01/24 | Corrección: 08/01/24\n\n## Ejercicio\n\n\"\"\"\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\"\"\"\n\nsuma = 5 + 4;\nresta = 8 -5;\nmultiplicacion = 3 * 4;\ndivision = 10 / 2;\nrestante = 10 % 3;\npotencia = 8**7;\ndivison_enteros = 25//4;\n\nmayor = 30 > 18;\nmenor = 12 > 20;\nigual = 20 == 20;\nmenor_igual = 10<=15;\nmayor_igual = 20>=20;\nno_iguales = 10 !=  12;\n\n#operadores bit a bit\na = 10 #1010\nb = 4  #0100        \nand_bit = a & b #0000\nor_bit = a | b  #1110\nxor_bit = a ^ b #1110\nnot_bit = ~a    #-1011\ndesplazar_izquierda = a << 2 #101000\ndesplazar_derecha = a >> 2   #0010  \n\n#operadores logicos\nand_logico = (5 > 2) and (3 < 4);\nor_logico = (5 > 2) or (3 > 4);\nnot_logico = not(5 > 2);        \n\n#operadores de asignacion\nx = 5;\nx += 3; #x = x + 3\nx -= 2; #x = x - 2          \nx *= 2; #x = x * 2\nx /= 2; #x = x / 2\nx %= 3; #x = x % 3\nx //= 2; #x = x // 2\nx **= 3; #x = x ** 3\n\n#operadores de pertenencia\npertenencia1 = 'a' in 'manzana';\npertenencia2 = 'b' not in 'manzana';        \n#operadores de identidad\ny = 10;\nidentidad1 = y is 10;\nidentidad2 = y is not 10;   \n\n\nprint(\"Operadores Aritméticos\")\nprint(f\"Suma: {suma}\")\nprint(f\"Resta: {resta}\")\nprint(f\"Multiplicación: {multiplicacion}\")\nprint(f\"División: {division}\")\nprint(f\"Restante: {restante}\")\nprint(f\"Potencia: {potencia}\")\nprint(f\"División de enteros: {divison_enteros}\")\nprint(\"\\nOperadores de Comparación\")\nprint(f\"Mayor que: {mayor}\")            \n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Bert008.py",
    "content": "'''\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n'''\nx = 2\ny = 4\nprint(\"x = \", 2)\nprint(\"y = \", 4)\nprint(\"------------------------------------------------\")\nprint(\"Operadores aritmeticos\")\nprint(\"Suma (x + y) = \", x + y)\nprint(\"Resta (x - y) = \", x - y)\nprint(\"Multiplicacion (x * y) = \", x * y)\nprint(\"Divicion (y / x) = \", y/x)\nprint(\"Esponente (y ** x) = \", y ** x)\nprint(\"Modulo (y % x) = \", y % x)\nprint(\"Cociente (x // y) = \", x // y)\nprint(\"------------------------------------------------\")\nprint(\"Operadores logicos\")\nprint(\"True and True: \", True and True)\nprint(\"False and False: \", False and False)\nprint(\"True and False: \", True and False)\nprint(\"False and True: \", False and True)\n\nprint(\"True or True: \", True or True)\nprint(\"False or False: \", False or False)\nprint(\"True or False: \", True or False)\nprint(\"False or True: \", False or True)\n\nprint(\"Not False: \", not False)\nprint(\"Not True: \", not True)\nprint(\"------------------------------------------------\")\nprint(\"Operadores de comparacion\")\nprint(\"Es igual que (x == y): \", x == y)\nprint(\"No es igual que (x != y): \", x != y)\nprint(\"Es mayor que (x > y): \", x > y)\nprint(\"Es menor que (x < y): \", x < y)\nprint(\"Es mayor o igual que (x >= y): \", x >= y)\nprint(\"Es menor o igual que (x <= y): \", x <= y)\nprint(\"------------------------------------------------\")\nprint(\"Operadores de asignacion\")\nx = y\na = 10; a += x\nb = 10; b -= x\nc = 10; c *= x\nd = 10; d /= x\ne = 10; e **= x\nf = 10; f %= x\ng = 10; g //= x\nh = 10; h &= x\ni = 10; i <<= x\nj = 10; j >>= x\nprint(\"a += x: \")\nprint(\"b -= x: \")\nprint(\"c *= x: \")\nprint(\"d /= x: \")\nprint(\"e **= x: \")\nprint(\"f %= x: \", f)\nprint(\"g //= x: \", g)\nprint(\"h &= x: \", h)\nprint(\"i <<= x: \", i)\nprint(\"j >>= x: \", j)\nprint(\"------------------------------------------------\")\nprint(\"Operadores de identidad y pertenencia\")\nlista = [1, 2, 3, 4, 5]\nlista2 = [1, 2, 3, 4, 5]\nprint(\"x is y: \", x is y)\nprint(\"x is not y\", x is not y)\nprint(\"lista == lista2: \", lista == lista2)\nprint(\"lista is lista2: \", lista is lista2)\nprint(\"lista is not lista2: \", lista is not lista2)\n# las listas no se identifican de una como otra ya que aunque contienen los mismo atributos, de acuerdo con python estos dos son dos objetos disnintos.\nprint(\"1 in lista: \", 1 in lista) # 1 se encuentra dentro de lista\nprint(\"1 not in lista: \", 1 not in lista) # 1 si esta en la lista\nprint(\"6 not in lista: \", 6 not in lista) # 6 si esta en la lista\nprint(\"------------------------------------------------\")\nprint(\"Operadores de bits\")\nprint(\"Bitwise\")\n#x = bin(2)\n#y = bin(10)\nprint(\"Or x | y = \", (x | y))\nprint(\"And x & y = \", x & y)\nprint(\"Not ~(x): \", ~(x))\nprint(\"Xor x ^ y = \", x ^ y)\nprint(\"Desplazamiento a la derecha x << y: \", x << y)\nprint(\"Desplazamiento a la izquierda x >> y: \", x >> y)\n\n'''\n* DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n'''\nprint(\"-------------------------------------------------------------\")\nprint(\"Dificultad extra\")\nfor i in range(10, 56, 2):\n    if i != 16 and i % 3 != 0:\n        print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/BertoMP.py",
    "content": "# OPERADORES ARITMÉTICOS\nprint('OPERADORES ARITMÉTICOS')\nfirst_number = 7\nsecond_number = 2\nresult = 0\n\n# Operador suma (+)\nresult = first_number + second_number\nprint(f\"La suma de {first_number} + {second_number} es {result}\")\n\n# Operador resta (-)\nresult = first_number - second_number\nprint(f\"La resta de {first_number} - {second_number} es {result}\")\n\n# Operador multiplicación (*)\nresult = first_number * second_number\nprint(f\"La multiplicación de {first_number} * {second_number} es {result}\")\n\n# Operador división (/)\nresult = first_number / second_number\nprint(f\"La división de {first_number} / {second_number} es {result}\")\n\n# Operador módulo (%)\nresult = first_number % second_number\nprint(f\"El resto de la división de {first_number} / {second_number} es {result}\")\n\n# OPERADORES LÓGICOS\nprint('\\nOPERADORES LÓGICOS')\nfirst_bool = True\nsecond_bool = False\n\n# Operador lógico AND (and)\nlogic_and = first_bool and second_bool\nprint(f\"AND lógico: {logic_and}\")\n\n# Operador lógico OR (or)\nlogic_or = first_bool or second_bool\nprint(f\"OR lógico: {logic_or}\")\n\n# Operador lógico NOT (not)\nlogic_not = not first_bool\nprint(f\"NOT lógico: {logic_not}\")\n\n# OPERADORES DE COMPARACIÓN\nprint('\\nOPERADORES DE COMPARACIÓN')\n# Operador mayor que (>)\ngreat_than = 5 > 10\nprint(f\"¿Es 5 mayor que 10? -> {great_than}\")\n\n# Operador menor que (<)\nless_than = 5 < 10\nprint(f\"¿Es 5 menor que 10? -> {less_than}\")\n\n# Operador mayor o igual que (>=)\ngreat_or_equal = 5 >= 10\nprint(f\"¿Es 5 mayor o igual que 10? -> {great_or_equal}\")\n\n# Operador menor o igual que (<=)\nless_or_equal = 5 <= 10\nprint(f\"¿Es 5 menor o igual que 10? -> {less_or_equal}\")\n\n# OPERADORES DE ASIGNACIÓN\nprint('\\nOPERADORES DE ASIGNACIÓN')\n# Operador de asignación simple (=)\nnumber = 10\nprint(f\"Valor asignado: {number}\")\n\n# Operador de suma y asignación (+=)\nnumber += 5  # 10 + 5 = 15\nprint(f\"Valor del resultado de suma y asignación: {number}\")\n\n# Operador de resta y asignación (-=)\nnumber -= 5  # 15 - 5 = 10\nprint(f\"Valor del resultado de resta y asignación: {number}\")\n\n# Operador de multiplicación y asignación (*=)\nnumber *= 5  # 10 * 5 = 50\nprint(f\"Valor del resultado de multiplicación y asignación: {number}\")\n\n# Operador de división y asignación (/=)\nnumber /= 5  # 50 / 5 = 10\nprint(f\"Valor del resultado de división y asignación: {number}\")\n\n# Operador de módulo y asignación (%=)\nnumber %= 5  # 10 % 5 = 0\nprint(f\"Valor del resultado de módulo y asignación: {number}\")\n\n# OPERADORES DE IDENTIDAD\nprint('\\nOPERADORES IDENTIDAD')\n# Operador de igualdad estricta (==)\nstrict_equal_comp = 5 == 5\nprint(f\"¿Es 5 estrictamente igual a 5? -> {strict_equal_comp}\")\n\n# Operador de desigualdad estricta (!=)\nstrict_diff_comp = '5' != '5'\nprint(f\"¿Es '5' estrictamente diferente a '5'? -> {strict_diff_comp}\")\n\n# OPERADORES DE PERTENENCIA\nprint('\\nOPERADORES DE PERTENENCIA')\nint_list = [1, 12, 5, 643, 3]\nfirst_check = 3 in int_list  # Devolverá True\nsecond_check = 65 in int_list  # Devolverá False\n\nprint(f\"¿Está el número 3 en la lista de números? -> {first_check}\")\nprint(f\"¿Está el número 65 en la lista de números? -> {second_check}\")\n\n# OPERADORES DE BITS\nprint('\\nOPERADORES DE BITS')\nfirst_bit = 5  # Representación binaria: 0000 0101\nsecond_bit = 3  # Representación binaria: 0000 0011\n\n# Operador AND a nivel de bits (&)\nbit_and = first_bit & second_bit  # Devuelve 1 (representación binaria: 0000 0001)\nprint(f\"Resultado AND bit a bit -> {bit_and}\")\n\n# Operador OR a nivel de bits (|)\nbit_or = first_bit | second_bit  # Devuelve 7 (representación binaria: 0000 0111)\nprint(f\"Resultado OR bit a bit -> {bit_or}\")\n\n# Operador XOR a nivel de bits (^)\nbit_xor = first_bit ^ second_bit  # Devuelve 6 (representación binaria: 0000 0110)\nprint(f\"Resultado XOR bit a bit -> {bit_xor}\")\n\n# Operador NOT a nivel de bits (~)\nbit_not = ~first_bit  # Devuelve -6 (representación binaria: 1111 1010)\nprint(f\"Resultado NOT bit a bit -> {bit_not}\")\n\n# Operador de desplazamiento hacia la derecha (>>)\nto_right_bit = first_bit >> 1  # Devuelve 2 (representación binaria: 0000 0010)\nprint(f\"Desplazamiento hacia la derecha -> {to_right_bit}\")\n\n# Operador de desplazamiento hacia la izquierda (<<)\nto_left_bit = first_bit << 1  # Devuelve 10 (representación binaria: 0000 1010)\nprint(f\"Desplazamiento hacia la izquierda -> {to_left_bit}\")\n\n# ESTRUCTURAS DE CONTROL CONDICIONAL\nprint('\\nESTRUCTURAS DE CONTROL CONDICIONAL')\n# if-else\nprint('if-else')\nnum = 10\n\nif num > 0:\n    print('El número es positivo.')\nelif num == 0:\n    print('El número es cero.')\nelse:\n    print('El número es negativo.')\n\n# Operador ternario\nprint('\\nOperador ternario')\nprint('El número es positivo.' if num > 0 else 'El número es cero o negativo.')\n\n# ESTRUCTURAS DE CONTROL ITERATIVAS\nprint('\\nESTRUCTURAS DE CONTROL ITERATIVAS')\n# while\nprint('Bucle While')\ncounter = 0\nwhile counter < 5:\n    print(f\"Iteración: {counter}\")\n    counter += 1\n\n# do-while (No hay una estructura directa de do-while en Python)\nprint('\\nBucle do-while')\ncounter = 0\nwhile True:\n    print(f\"Iteración: {counter}\")\n    counter += 1\n    if counter >= 5:\n        break\n\n# for\nprint('\\nBucle for')\nfor counter in range(5):\n    print(f\"Iteración: {counter}\")\n\n# for ... in (array)\nprint('\\nBucle for ... in para arrays')\narr_numbers = [1, 2, 5, 2, 7, 9]\nfor number in arr_numbers:\n    print(f\"Número -> {number}\")\n\n# for ... in (objeto)\nprint('\\nBucle for ... in para objetos')\npersona = {'name': 'Alberto', 'age': 33}\nfor att, value in persona.items():\n    print(f\"{att} -> {value}\")\n\n# MANEJO DE EXCEPCIONES\nprint('\\nMANEJO DE EXCEPCIONES')\nprint('Bloque try-catch')\nerr_number = 10\n\ntry:\n    if err_number == 10:\n        raise ValueError('El número es igual a 10.')\n    print('El número es distinto de 10.')\nexcept Exception as error:\n    print(f\"Se ha producido un error debido a -> {error}\")\n\nprint('\\nBloque try-catch-finally')\ntry:\n    if err_number == 10:\n        raise ValueError('El número es igual a 10.')\n    print('El número es distinto de 10.')\nexcept Exception as error:\n    print(f\"Se ha producido un error debido a -> {error}\")\nfinally:\n    print('Bloque finally. Esto siempre se ejecuta haya o no excepción.')\n\n# DIFICULTAD EXTRA\nprint(\"\\nEJERCICIO EXTRA\")\n\"\"\" \nCrea un programa que imprima por consola todos los números comprendidos entre 10 y 55 (incluidos), pares, y\nque no son ni el 16 ni múltiplos de 3.\n\"\"\"\nfor i in range(10, 56):\n    if (i % 2 == 0) and (i != 16) and (i % 3 != 0):\n        print(\"Iteración:\", i)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Bertolini-Victor.py",
    "content": "\"\"\"\n    EJERCICIO:\n    1) Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n        Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n        (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n    2) Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n        que representen todos los tipos de estructuras de control que existan\n        en tu lenguaje:\n        Condicionales, iterativas, excepciones...\n    *Debes hacer print por consola del resultado de todos los ejemplos.\n\n    DIFICULTAD EXTRA (opcional):\n    3)  Crea un programa que imprima por consola todos los números comprendidos\n        entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\"\"\"\n\n# 1) \n\n# Arithmetic Operators\nx = 10\ny = 3\n\nprint(\"First we have the arithmetic operators.\")\nprint(\"\")\nprint(f\"Addition: {x} + {y} = {x + y}\")\nprint(f\"Subtraction: {x} - {y} = {x - y}\")\nprint(f\"Multiplication: {x} * {y} = {x * y}\")\nprint(f\"Division: {x} / {y} = {x / y}\")\nprint(f\"Modulus: {x} % {y} = {x % y}\")\nprint(f\"Exponentiation: {x} ** {y} = {x ** y}\")\nprint(f\"Floor division: {x} // {y} = {x // y}\")\n\n# Assignment Operators\nprint(\"\")\nprint(\"Second we have the assignment operators.\")\nprint(\"\")\nx = 5\nprint(f\"Initial value of x: {x}\")\nx += 2\nprint(f\"After x += 2, x: {x}\")\nx -= 2\nprint(f\"After x -= 2, x: {x}\")\nx *= 2\nprint(f\"After x *= 2, x: {x}\")\nx /= 2\nprint(f\"After x /= 2, x: {x}\")\nx %= 3\nprint(f\"After x %= 3, x: {x}\")\nx //= 2\nprint(f\"After x //= 2, x: {x}\")\nx **= 2\nprint(f\"After x **= 2, x: {x}\")\n\n# Comparison Operators\nx = 10\ny = 3\nprint(\"\")\nprint(\"In third we have the comparison operators.\")\nprint(\"\")\nprint(f\"Equal: {x} == {y} is {x == y}\")\nprint(f\"Not equal: {x} != {y} is {x != y}\")\nprint(f\"Greater than: {x} > {y} is {x > y}\")\nprint(f\"Less than: {x} < {y} is {x < y}\")\nprint(f\"Greater than or equal to: {x} >= {y} is {x >= y}\")\nprint(f\"Less than or equal to: {x} <= {y} is {x <= y}\")\n\n# Logical Operators\nx = True\ny = False\n\nprint(\"\")\nprint(\"In fourth we have the logical operators.\")\nprint(\"\")\n\nprint(f\"AND: {x} and {y} is {x and y}\")\nprint(f\"OR: {x} or {y} is {x or y}\")\nprint(f\"NOT: not {x} is {not x}\")\n\n# Identity Operators\nx = [\"star\", \"wars\"]\ny = [\"star\", \"wars\"]\nz = x\n\nprint(\"\")\nprint(\"In fifth we have the identity operators.\")\nprint(\"\")\n\n\nprint(f\"IS: x is z is {x is z}\")\nprint(f\"IS NOT: x is not y is {x is not y}\")\n\n# Membership Operators\nx = [\"star\", \"wars\"]\n\nprint(\"\")\nprint(\"In fifth we have the membership  operators.\")\nprint(\"\")\n\n\nprint(f\"IN: 'wars' in x is {'wars' in x}\")\nprint(f\"NOT IN: 'pineapple' not in x is {'pineapple' not in x}\")\n\n# Bitwise Operators\nx = 10  # binary: 1010\ny = 4   # binary: 0100\n\nprint(\"\")\nprint(\"Last but not least we have the bitwise operators.\")\nprint(\"\")\n\n\nprint(f\"AND: {x} & {y} = {x & y}\")\nprint(f\"OR: {x} | {y} = {x | y}\")\nprint(f\"XOR: {x} ^ {y} = {x ^ y}\")\nprint(f\"NOT: ~{x} = {~x}\")\nprint(f\"Zero fill left shift: {x} << 2 = {x << 2}\")\nprint(f\"Signed right shift: {x} >> 2 = {x >> 2}\")\n\n\n# 2)\n\n# Conditionals (if, elif, else)\nx = 10\ny = 20\n\nprint(\"\")\nprint(\"Conditionals (if, elif, else)\")\nprint(\"\")\n\nif x < y:\n    print(\"x is less than y\")\nelif x > y:\n    print(\"x is greater than y\")\nelse:\n    print(\"x is equal to y\")\n\n\n# Loops (For, while, Break, Continue)\np = []\no = []\nh = []\nt = []\n\nprint(\"\")\nprint(\"Loops (for, while, Break, Continue)\")\nprint(\"\")\n\n# For loop\nfor i in range(5):\n    p.append(i) \nprint(p)\n\n# While loop\ni = 0\nwhile i < 5:\n    o.append(i)\n    i += 1\nprint(o)\n\n# Break\nfor i in range(5):\n    if i == 3:\n        break\n    h.append(i)\nprint(h)\n\n# Continue\nfor i in range(5):\n    if i == 3:\n        continue\n    t.append(i)\nprint(t)\n\n\n# Execeptions.\nprint(\"\")\nprint(\"Exceptions.\")\nprint(\"\")\n\ntry:\n    print(13)\nexcept NameError:\n    print(\"Variable x is not defined\")\nfinally:\n    print(\"The 'try except' is finished\")\n\n\n\n# 3) Extra Excercise. \n\n\n\"\"\" \n    Crea un programa que imprima por consola todos los números comprendidos\n    entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3\n\"\"\"\ndef printPairNumbersFrom10To55():\n    k = []\n    for j in range(10, 55):\n        if j != 16 and j % 3 != 0 and j % 2 == 0:\n            k.append(j)\n    print(k)\n\nprint(\" \")\nprint(\"Extra exercise:\")\nprint(\"\")\nprintPairNumbersFrom10To55()"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/BrianSilvero.py",
    "content": "\"\"\"Operadores\"\"\"\n\n# Operadores aritméticos\n\nprint(f\"Suma: 10 + 3 = {10+3}\")\nprint(f\"Resta: 10 - 3 = {10-3}\")\nprint(f\"Multiplicacion: 10 x 3 = {10*3}\")\nprint(f\"Division: 10 / 3 = {10/3}\")\nprint(f\"Modulo: 10 % 3 = {10%3}\")\nprint(f\"Exponente: 10 ** 3 = {10**3}\")\nprint(f\"Division entera: 10 // 3 = {10//3}\")\n\n# Operadores de comparacion\nprint(f\"Igualdad: 10 == 3 es {10==3}\")\nprint(f\"Desigualdad: 10 != 3 es {10!=3}\")\nprint(f\"Mayor que: 10 > 3 es {10>3}\")\nprint(f\"Menor que: 10 < 3 es {10<3}\")\nprint(f\"Mayor o igual que: 10 >= 10 es {10>=10}\")\nprint(f\"Menor o igual que: 10 <= 3 es {10<=3}\")\n\n# Operadores lógicos\nprint(f\"AND &&: 10 + 3 == 13 and 5 - 1 == 4 es {10 + 3 == 13 and 5 - 1 == 4}\")\nprint(f\"OR ||: 10 + 3 == 14 and 5 - 1 == 4 es {10 + 3 == 14 or 5 - 1 == 4}\")\nprint(f\"NOT !: not 10 + 3 == 14 {not 10 + 3 == 14}\")\n\n# Operadores de asignación \nmy_number = 11  # asignación\nprint(my_number) \nmy_number += 1  # suma y asignación  \nprint(my_number)\nmy_number -= 1  # resta y asignación \nprint(my_number)\nmy_number *= 2  # multiplicacion y asignación \nprint(my_number)\nmy_number /= 2   # division y asignación\nprint(my_number)\nmy_number %= 2   # módulo y asignación \nprint(my_number)\nmy_number **= 1  # exponente y asignación\nprint(my_number)\nmy_number //= 1  # division entera y asignación \n\n\n# Operadores de indentidad \nmy_new_number = my_number\nprint(f\"my_number is my_new_number es {my_number is my_new_number}\")\nprint(f\"my_numbre is not my_new_numbre es {my_number is not my_new_number}\")\n\n# Operadores de pertenencia \nprint(f\"'u' in 'mouredev' = {'u' in 'mouredev'}\")\nprint(f\"'b' not in 'mouredev' = {'b' not in 'mouredev'}\")\n\n# Operadores de bit \na = 10 # 1010\nb = 3 #0011\n\nprint(f\"AND: 10 & 3 = {10 & 3}\") # 0010\nprint(f\"OR: 10 | 3 = {10 | 3}\") # 1011\nprint(f\"XOR: 10 ^ 3 = {10 ^ 3}\") # 1001\nprint(f\"AND: 10 ~ 3 = {~10}\") # 0010\nprint(f\"Desplazamiento  a la derecha: 10 >> 2 = {10 >> 2}\") # 0010\nprint(f\"Desplazamiento  a la izquierda: 10 << 2 = {10 << 2}\") # 101000\n\n\n\"\"\"\nEstructuras de control\n\"\"\"\n\n# Condicionales\n\nmy_string = \"Brais\"\n\nif my_string == \"MoureDev\":\n    print( \"mys_sting es 'MoureDev'\")\nelif my_string == \"Brais\":\n    print(\"my_string es 'Brais'\")\nelse:\n    print(\"my_string no es 'MoureDev' ni 'Brais'\")\n\n\n# Iterativas \n\nfor i in range (11):\n    print(i)\n    \ni = 0\n\nwhile i <= 10:\n    print(i)\n    i += 1\n    \n# Manejo de excepciones \ntry: \n    print(10/0) \nexcept:\n    print(\"Se ha producido un error\")\nfinally:\n    print(\"Ha finalizado el manejo de excepciones\")\n    \n    \n\"\"\"\nExtra\n\"\"\"\nfor number in range(10,56):\n    if (number % 2 == 0 and number != 16 and number % 3 != 0) or number == 55:\n        print(number)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Bryan112094.py",
    "content": "\"\"\"\nEJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\"\"\"\n\nprint(\"Aritmeticos\")\nnum01 = 10\nnum02 = 3\nprint(f\"Suma: {num01 + num02}\")\nprint(f\"Resta: {num01 - num02}\")\nprint(f\"Multiplicación: {num01 * num02}\")\nprint(f\"División: {num01 / num02}\")\nprint(f\"División Entera: {num01 // num02}\")\nprint(f\"Potencia: {num01 ** num02}\")\nprint(f\"Residuo: {num01 % num02}\")\n\nprint(\"\\nOperadores Lógicos\")\n#AND -> si ambos son TRUE el resultado es TRUE si no el resultado será FALSE\nprint(f\"AND: True and True -> {True and True}, True and Flase -> {True and False}\")\n#OR -> si ambos son FALSE el resultado es FALSE si no el resultado será TRUE\nprint(f\"OR: False or False -> {False or False}, True or Flase -> {True or False}\")\n#NOT -> Invierte los valores TRUE -> FALSE, FALSE -> TRUE\nprint(f\"NOT: not True -> {not True}, not False -> {not False}\")\n\nprint(\"\\nOperadores de comparación\")\n# Mayor \">\" => si el de la izquierda es mayor al de la derecha resultara TRUE si no sera FALSE\nprint(f\"Mayor > : 10>5 -> {10>5}, 5>15 -> {5>15}\")\n# Menor \"<\" => si el de la izquierda es menor al de la derecha resultara TRUE si no sera FALSE\nprint(f\"Menor < : 10<5 -> {10<5}, 5<15 -> {5<15}\")\n# Igual \"==\" => Si son iguales obtendra TRUE si no FALSE\nprint(f\"Igual == : Bryan == Bryan -> {'Bryan' == 'Bryan'}, Bryan == Bryat -> {'Bryan' == 'Bryat'}\")\n# Distintos \"!=\" => Si son diferentes obtendra TRUE si no FALSE\nprint(f\"Distinto != : 24 != 24 -> {24 != 24}, 15 != 16 -> {15 != 16}\")\n\nprint(\"\\nAsignación\")\nx = 5\nprint(f\"Asignar valor : x=5 -> {x}\")\nx += 3\nprint(f\"Asignar equivalente : x+=3 -> {x}\")\n\nprint(\"\\nIdentidad\")\na = 2\nb = 3\nc = 2\nprint(f\"Si 'a' es igual a b {a is b} o es igual a c {a is c}\")\n\nprint(\"\\nPertenencia\")\np1 = [1, 2, 3, 5]\np2 = 2\np3 = 4\nprint(f\"Si 'p2' pertenece a 'p1' {p2 in p1} o 'p3' pertenece a 'p1' {p3 not in p1}\")\n\nresult = []\nfor i in range(10, 56):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        result.append(i)\n    if i == 55:\n        result.append(i)\nprint(f\"\\nExtra: {result}\")"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/BryanAlzate007.py",
    "content": "# Operadores Aritméticos:\n\n# +: Suma\n# -: Resta\n# *: Multiplicación\n# /: División\n# %: Módulo (residuo de la división)\n# **: Exponenciación\n# //: División entera (descarta la parte decimal)\n\nprint(f\"Operador + ejemplo: 1 + 3 esto da como resultado: {1 + 3}\")\nprint(f\"Operador - ejemplo: 1 - 3 esto da como resultado: {1 - 3}\")\nprint(f\"Operador * ejemplo: 1 * 3 esto da como resultado: {1 * 3}\")\nprint(f\"Operador / ejemplo: 10 / 3 esto da como resultado: {10/3}\")\nprint(f\"Operador % ejemplo: 10 / 3 esto da como resultado: {10 % 3}\")\nprint(f\"Operador ** ejemplo: 10 ** 3 esto da como resultado:{10**3}\")\nprint(f\"Operador // ejemplo: 10 // 3 esto da como resultado: {10 // 3}\")\n\n\n\n# Operadores de Comparación:\n\n# == Igual a\n# != Diferente de\n# > Mayor que\n# < Menor que\n# >= Mayor o igual que\n# <= Menor o igual que\n\n# el resultado de estos operadores nos devuelve un valor booleano true or false\n\nprint(f\"Operador comparación == ejemplo 1 == 1 esto da como resultado: {1 == 1}\")\nprint(f\"Operador de comparación != ejemplo 1 != 1 esto da como resultado {1 != 1}\")\nprint(f\"Operador de comparación > ejemplo 10 > 1 esto da como resultado {10 > 1}\")\nprint(f\"Operador de comparación < ejemplo 10 > 1 esto da como resultado {10 < 1}\")\nprint(f\"Operador de comparación <= ejemplo 10 > 1 esto da como resultado {10 <= 1}\")\nprint(f\"Operador de comparación >= ejemplo 10 > 1 esto da como resultado {10 >= 1}\")\n\n#Operadores Logicos\n\n# and: Verdadero si ambas condiciones son verdaderas\n# or: Verdadero si al menos una condición es verdadera\n# not: Invierte el valor de verdad\n\nprint(f\"Operador and ejemplo 1 + 3 == 4 and 2 + 2 == 4{1 + 3 == 4 and 2 + 2 == 4}\")\nprint(f\"Operador and ejemplo 1 + 3 == 4 and 2 + 2 == 4{1 + 3 == 4 or 2 + 2 == 4}\")\n# print(f\"Operador and ejemplo 1 + 3 == 4 and 2 + 2 == 4{1 + 3 == 4 not 2 + 2 == 4}\")\n\nx = 10\ny = 5\n\n\nx = 10\nx += 5  # Equivalente a x = x + 5\nprint(x)  # Salida: 15\n\nx = 10\nx -= 3  # Equivalente a x = x - 3\nprint(x)  # Salida: 7\n\nx = 10\nx *= 2  # Equivalente a x = x * 2\nprint(x)  # Salida: 20\n\nx = 10\nx /= 2  # Equivalente a x = x / 2\nprint(x)  # Salida: 5.0\n\nx = 10\nx %= 3  # Equivalente a x = x % 3\nprint(x)  # Salida: 1\n\nx = 2\nx **= 3  # Equivalente a x = x ** 3\nprint(x)  # Salida: 8\n\nx = 10\nx //= 3  # Equivalente a x = x // 3\nprint(x)  # Salida: 3\n\n\n\na = [1, 2, 3]\nb = a\nc = [1, 2, 3]\n\nprint(a is b)  # Salida: True, porque 'a' y 'b' apuntan al mismo objeto\nprint(a is c)  # Salida: False, porque 'a' y 'c' son objetos diferentes en memoria\n\n\nprint(a is not b)  # Salida: False, porque 'a' y 'b' apuntan al mismo objeto\nprint(a is not c)  # Salida: True, porque 'a' y 'c' son objetos diferentes en memoria\n\n\n\n# Ejemplo con listas\nfruits = [\"apple\", \"banana\", \"cherry\"]\nprint(\"banana\" in fruits)  # Salida: True, porque \"banana\" está en la lista 'fruits'\n\n# Ejemplo con cadenas\nsentence = \"The quick brown fox\"\nprint(\"quick\" in sentence)  # Salida: True, porque \"quick\" está en la cadena 'sentence'\n\n# Ejemplo con diccionarios\nages = {\"Alice\": 30, \"Bob\": 25, \"Charlie\": 35}\nprint(\"Bob\" in ages)  # Salida: True, porque \"Bob\" es una clave en el diccionario 'ages'\n\n\n# Ejemplo con listas\nfruits = [\"apple\", \"banana\", \"cherry\"]\nprint(\"grape\" not in fruits)  # Salida: True, porque \"grape\" no está en la lista 'fruits'\n\n# Ejemplo con cadenas\nsentence = \"The quick brown fox\"\nprint(\"slow\" not in sentence)  # Salida: True, porque \"slow\" no está en la cadena 'sentence'\n\n# Ejemplo con diccionarios\nages = {\"Alice\": 30, \"Bob\": 25, \"Charlie\": 35}\nprint(\"David\" not in ages)  # Salida: True, porque \"David\" no es una clave en el diccionario 'ages'\n\n\na = 12  # 1100 en binario\nb = 7   # 0111 en binario\n\nresult = a & b  # 0100 en binario, que es 4 en decimal\nprint(result)  # Salida: 4\n\na = 12  # 1100 en binario\nb = 7   # 0111 en binario\n\nresult = a | b  # 1111 en binario, que es 15 en decimal\nprint(result)  # Salida: 15\n\n\na = 12  # 1100 en binario\nb = 7   # 0111 en binario\n\nresult = a ^ b  # 1011 en binario, que es 11 en decimal\nprint(result)  # Salida: 11\n\n\na = 12  # 1100 en binario\n\nresult = ~a  # Inversión de bits, que es -13 en decimal (en el sistema de complemento a dos)\nprint(result)  # Salida: -13\n\na = 3  # 0011 en binario\n\nresult = a << 2  # Desplaza 2 posiciones a la izquierda, resultando en 1100 en binario, que es 12 en decimal\nprint(result)  # Salida: 12\n\na = 12  # 1100 en binario\n\nresult = a >> 2  # Desplaza 2 posiciones a la derecha, resultando en 0011 en binario, que es 3 en decimal\nprint(result)  # Salida: 3\n\n\n# * DIFICULTAD EXTRA (opcional):\n# * Crea un programa que imprima por consola todos los números comprendidos\n# * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\n# Iterar sobre el rango de números entre 10 y 55 (incluidos)\nfor num in range(10, 56):\n    # Verificar si el número es par\n    if num % 2 == 0:\n        # Verificar que el número no sea el 16 y no sea múltiplo de 3\n        if num != 16 and num % 3 != 0:\n            print(num)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/C-Gabs.py",
    "content": "#Reto 01\n\n'''EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.'''\n\n\n#tipos de operadores\n\n#Aritmeticos\n\nsuma = 5 + 3\nprint(f'suma:',suma)\n\nresta = 5 - 3\nprint(f'resta:',resta)\n\nmultiplicacion = 5*3\nprint(f'Multiplicación:',multiplicacion)\n\ndivision = 15/3\nprint(f'División:',division)\n\ndiv_entera = 15//3\nprint(f'División:',div_entera)\n\npotencia = 5**3\nprint(f'Potencia:',potencia)\n\nresto = 15%3\nprint(f\"Resto:\", resto)\n\n#Lógicos\n\nconjuncion = True and True\nprint(f'conjunción:',conjuncion)\n\nconjuncion = True and False\nprint(f'conjunción:',conjuncion)\n\ndisyuncion = True or False\nprint(f'Disyunción:',disyuncion)\n\ndisyuncion = False or False\nprint(f'Disyunción:',disyuncion)\n\ndisyuncion = True or True\nprint(f'Disyunción:',disyuncion)\n\nnegacion = not True\nprint(f'Negación:',negacion)\n\nnegacion = not False\nprint(f'Negación:',negacion)\n\n#Comparación\n\nmayor_que = 5 > 3\nprint(f'Mayor qué:',mayor_que)\n\nmenor_que = 5 < 3\nprint(f'Menor qué:',menor_que)\n\nigual = 5 == 4\nprint(f'Igual:',igual)\n\nigual = 4 == 4\nprint(f'Igual:',igual)\n\ndiferente = 5 != 4\nprint(f'Diferente:',diferente)\n\ndiferente = 5 != 5\nprint(f'Diferente:',diferente)\n\nmayor_igual_que = 5 >= 4\nprint(f'Mayor o igual qué:',mayor_igual_que)\n\nmayor_igual_que = 5 >= 8\nprint(f'Mayor o igual qué:',mayor_igual_que)\n\nmayor_igual_que = 8 >= 8\nprint(f'Mayor o igual qué:',mayor_igual_que)\n\nmenor_igual_que = 5 <= 4\nprint(f'Menor o igual qué:',menor_igual_que)\n\nmenor_igual_que = 5 <= 8\nprint(f'Menor o igual qué:',menor_igual_que)\n\nmenor_igual_que = 5 <= 5\nprint(f'Menor o igual qué:',menor_igual_que)\n\n#Asignación\n\nvar = 5\nprint(f'Asignación básica:', var)\n\nvar += 6\nprint(f'Asignación con suma:', var)\n\nvar -= 7\nprint(f'Asignación con resta:', var)\n\nvar *= 8\nprint(f'Asignación con multiplicación:', var)\n\nvar /= 5\nprint(f'Asignación con división:', var)\n\nvar *= 3\nprint(f'Asignación con potencia:', var)\n\nvar %= 2\nprint(f\"Asignación con resto:\", var)\n\n#Operadores de identidad\n\nprint('Operador \"is\": ', 5 is True)\nprint('Operador \"is\": ', 5 is False)\nprint('Operador \"is\": ', 5 is 4)\nprint('Operador \"is\": ', 5 is 3 + 2)\n\nprint('Operador \"is not\": ', 5 is not True)\nprint('Operador \"is not\": ', 5 is not False)\nprint('Operador \"is not\": ', 5 is not 4)\nprint('Operador \"is not\": ', 5 is not 3 + 2)\n\n#Operadores de pertenencia\n\nstring = \"Hola mundo\"\n\nprint(\"Hola\" in string)\nprint(\"Python\" in string)\nprint(\"Hola\" not in string)\nprint(\"Python\" not in string)\n\n#Operadores de bits\n\nprint(\"Operador &: \", 1010 & 1100)\nprint(\"Operador |: \", 1010 | 1100)\nprint(\"Operador ~: \", ~1100)\nprint(\"Operador ^: \", 1010 ^ 1100)\nprint(\"Operador >>: \", 1010 >> 2)\nprint(\"Operador <<: \", 1010 << 2)\n\n#Operadores de conjuntos\n\nset_1 = {2,4,6,8,10}\nset_2 = {1,3,5,7,9}\nset_3 = set_1 | set_2\nprint(f\"Unión de conjuntos:\", set_3)\nprint(f\"Intersección de conjuntos:\", set_1 & set_3)\nprint(f\"Diferencia de conjuntos:\", set_2 - set_1, \"(set_2 - set_1)\")\nprint(f\"Diferencia de conjuntos:\", set_1 - set_2, \"(set_1 - set_2)\")\nprint(f\"Diferencia simétrica de conjuntos:\", set_1 ^ set_2)\nprint(f\"Inclusión de conjuntos:\", set_1 <= set_3, \"(set_1 subconjunto de set_2)\")\nprint(f\"Inclusión de conjuntos:\", set_1 >= set_3, \"(set_1 superconjunto de set_2)\")\nset_4 = {1,2,3,4,5,6,7,8,9,10}\nprint(f\"Ingualdad de conjuntos:\", set_4 == set_3)\n\n#Operador de concatenación\n\nstring_2 = string + \",\" + \" hola Python!\"\nprint(string_2)\n\nlista = [1,2,3] + [4,5,6]\nprint(lista)\n\n#Estructuras de control\nprint(\"Estructura iterativa for\")\nfor char in string_2:\n    print(char)\n\nprint(\"Estructura iterativa while y estructura condicional\")\nnum = 0\nwhile num < 10:\n    if num == 5:\n        print(\"Se cumple la coondición\")\n    else:\n        print(num)\n    num +=1\n\n#Excepciones\n\ntry:\n    ejemplo = input(\"Ingrese un número: \")\n    int(ejemplo)\nexcept:\n    print(\"Hubo un error\")\nfinally:\n    print(\"Entra en el finally\")\n\n#Ejercicio extra\nfor number in range(10,56):\n    if (number != 16 and number % 3 != 0) and number % 2 == 0:\n        print(number)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/CRaphaelAM.py",
    "content": "\"\"\"\nEJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\"\"\"\n\n\n\n#Operadores aritméticos\nx,y = 4,5\n\n#Suma\nprint(f\"Suma: {x + y = }\")\n\n#Resta\nprint(f\"Resta: {x - y = }\")\n\n#Producto\nprint(f\"Producto: {x * y = }\")\n\n#Division flotante\nprint(f\"Divison flotante: {x / y = }\")\n\n#Division entera\nprint(f\"Divison entera: {x // y = }\")\n\n#Division residual\nprint(f\"Mod: {x%y = }\")\n\n\n\n#Operadores de comparacion\n\nprint(f\"{x > y = }\")\nprint(f\"{x < y = }\")\nprint(f\"{x == y = }\")\nprint(f\"{x != y = }\")\nprint(f\"{x >= y = }\")\nprint(f\"{x <= y = }\")\n\n\n#Asignacion\nx = 5  # Asignación simple\nprint(x)  # 5\n\nx += 3  # Equivalente a x = x + 3\nprint(x)  # 8\n\nx -= 2  # Equivalente a x = x - 2\nprint(x)  # 6\n\nx *= 4  # Equivalente a x = x * 4\nprint(x)  # 24\n\nx /= 2  # Equivalente a x = x / 2\nprint(x)  # 12.0\n\nx //= 3  # Equivalente a x = x // 3 (división entera)\nprint(x)  # 4.0\n\nx %= 3  # Equivalente a x = x % 3\nprint(x)  # 1.0\n\nx **= 2  # Equivalente a x = x ** 2\nprint(x)  # 1.0\n\n\n#Operadores Logicos\nx = True\ny = False\n\n# AND lógico\nprint(x and y)  # False\n\n# OR lógico\nprint(x or y)  # True\n\n# NOT lógico\nprint(not x)  # False\n\n#Identidad\na = [1, 2, 3]\nb = [1, 2, 3]\nc = a\n\n# \"is\" verifica si son el mismo objeto\nprint(a is b)  # False (porque son listas diferentes en la memoria)\n\nprint(a is c)  # True (porque c es una referencia a a)\n\n# \"is not\" verifica si no son el mismo objeto\nprint(a is not b)  # True\n\n#Pertenencia\nlista = [1, 2, 3, 4]\n\n# \"in\" verifica si un valor está presente\nprint(3 in lista)  # True\n\n# \"not in\" verifica si un valor no está presente\nprint(5 not in lista)  # True\n\n\n#Operadores a nivel de bit\na = 10  # 1010 en binario\nb = 4   # 0100 en binario\n\n# AND bit a bit\nprint(a & b)  # 0 (0000)\n\n# OR bit a bit\nprint(a | b)  # 14 (1110)\n\n# XOR bit a bit\nprint(a ^ b)  # 14 (1110)\n\n# Desplazamiento a la derecha\nprint(a >> 2)  # 2 (0010)\n\n# Desplazamiento a la izquierda\nprint(a << 2)  # 40 (101000)\n\n\nx = 8  # 1000 en binario\n\nx &= 5  # x = x & 5 -> 1000 & 0101 = 0000\nprint(x)  # 0\n\nx |= 3  # x = x | 3 -> 0000 | 0011 = 0011\nprint(x)  # 3\n\nx ^= 2  # x = x ^ 2 -> 0011 ^ 0010 = 0001\nprint(x)  # 1\n\nx <<= 1  # x = x << 1 -> 0001 << 1 = 0010\nprint(x)  # 2\n\nx >>= 1  # x = x >> 1 -> 0010 >> 1 = 0001\nprint(x)  # 1\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\"\"\"\n\nprint(\"*** Difiultad extra ***\")\nfor n in range(10,56):\n    if n%2 == 0 and n!=16 and n%3!=0:\n        print(n)\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Caleb699-hub.py",
    "content": "nombre_esudiante = input(\"ingresa tu nombre: \")\n\nlista_de_notas = []\ncontador = 1 \n\n#uso del bucle while\nwhile contador <=3:\n    lista_de_notas.append(float(input(\"Ingresa una calificación: \")))\n    contador += 1\n\n#uso de operadores aritmeticos para el promedio\nprint(lista_de_notas)\npromedio_de_notas = (sum(lista_de_notas))/3\nprint(promedio_de_notas)\n\n#condicional y uso del operador lógico and\nif promedio_de_notas >= 6 and all(nota > 4 for nota in lista_de_notas):\n    print(f\"El estudiate {nombre_esudiante} a sido aprobado\")\nelse:\n    print(f\"El estudiante {nombre_esudiante} a sido reprobado\")\n\n\n\"\"\"\nDIFICULTAD EXTRA\n\"\"\"\n\nfor i in range(10,56,2):\n    if i % 3 != 0 and i != 16:\n        print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Carl6289.py",
    "content": "# Operadores aritméticos\nresultado_1 = 55 + 45 # Suma\nprint(resultado_1)\n\nresultado_2 = 1000 - 500 # Resta\nprint(resultado_2)\n\nresultado_3 = 7 * 8 # Multiplicación\nprint(resultado_3)\n\nresultado_4 = 600 / 200 # División\nprint(resultado_4)\n\n# Operadores lógicos\n# Ejemplo de and\ncalificacion = 16\npago = True\nentregar_certificado = (calificacion >= 15) and pago \nprint(f\"¿Entregar certificado? {entregar_certificado}\")\n\n# Ejemplo de or\npadre = False\ngasto = 5092\ndescuento = padre or (gasto >= 5000)\nprint(f\"¿Descuento del día del padre? {descuento}\")\n\n# Ejemplo de not\nalumno_becado = False\nalumno_no_becado = not alumno_becado\nprint(f\"¿El alumno está becado? {alumno_becado}\")\nprint(f\"¿El alumno no está becado? {alumno_no_becado}\")\n\n# Operadores de comparación\n# Ejemplo de igualdad y desigualdad\nx = 75\ny = 103\nes_igual = x == y\nprint(f\"¿Es igual? {es_igual}\")\n\nes_distinto = x != y\nprint(f\"¿Es distinto? {es_distinto}\")\n\n# Ejemplo de mayor y menor\nedad = 17\nmayor_de_edad = edad >= 18\nprint(f\"¿Es mayor de edad? {mayor_de_edad}\")\n\nmenor_de_edad = edad < 18\nprint(f\"¿Es menor de edad? {menor_de_edad}\")\n\n# Operadores de asignación\nsaldo = 75\nsaldo += 25\nprint(saldo)\n\n# Operadores de identidad\n# Ejemplo de is\na = 1\nb = a\nprint(a is b)\n\n# Ejemplo de is not\nc = 3\nd = 4\nprint(c is not d)\n\n# Operadores de pertenencia\n# Ejemplo de in\ndesarrollador = [\"maria\", \"luis\", \"karina\", \"carlos\"]\nes_desarrollador = \"carlos\" in desarrollador\nprint(f\"¿Carlos es desarrollador? {es_desarrollador}\")\n\n# Ejemplo de not in\nedad_nino = (8, 6, 9, 11)\nhay_10 = 10 not in edad_nino\nprint(f\"¿No hay niños de 10 años? {hay_10}\")\n\n# Operadores de bits\n# Ejemplo de &\nnum_1 = 10\nnum_2 = 4\nresultado_5 = num_1 & num_2\nprint(resultado_5)\n\n# Ejemplo de |\nnum_3 = 10\nnum_4 = 4\nresultado_6 = num_3 | num_4\nprint(resultado_6)\n\n# Ejemplo de ^\nnum_5 = 10\nnum_6 = 4\nresultado_7 = num_5 ^ num_6\nprint(resultado_7)\n\n# Ejemplo de <<\nnum_7 = 5\nresultado_8 = num_7 << 2\nprint(resultado_8)\n\n# Ejemplo de >>\nnum_8 = 20\nresultado_9 = num_8 >> 2\nprint(resultado_9)\n\n# Operador de concatenación (+)\nsaludo = \"Hola\"\nnombre = \"Brais\"\nfrase = saludo + \" \" + nombre + \"!\"\nprint(frase)\n\n# Operador de repetición\nrisa = \"ja\" * 5\nprint(risa)\n\n# Operador de indexación\ncolores = [\"amarillo\", \"azul\", \"rojo\"]\nprimer_color = colores [0]\nprint(primer_color)\n\ntercer_color = colores [2]\nprint(tercer_color)\n\n# Operador de segmentación\nseleccion_color = colores [0:2]\nprint(seleccion_color)\n\n# Estructuras de control condicionales\n# Ejemplo de if y else\ncalificacion_2 = 11\nif calificacion_2 >= 10:\n   print(\"Aprobado!\")\nelse:\n   print(\"Reprobado!\")\n\n# Ejemplo de if, elif y else\ncalificacion_3 = 18\nif calificacion_3 >= 19:\n   print(\"Calificación: A\")\nelif calificacion_3 >= 15:\n   print(\"Calificación: B\")\nelif calificacion_3 >= 10:\n   print(\"Calificación: C\")\nelif calificacion_3 >= 6:\n   print(\"Calificación: D\")\nelse:\n   print(\"Calificación: E\")\n\n# Estructuras de control iterativas\n# Ejemplo del bucle for\npasos = [\"1. Calentar el sarten\", \"2. Romper el huevo\", \"3. Sazonar y cocinar\", \"4. Servir\"]\nfor receta in pasos:\n   print(receta)\n\n# Ejemplo del bucle while\ncontador = 1\nwhile contador <= 10:\n   print(contador)\n   contador += 1 \n\n# Estructura de control de excepciones\n# Ejemplo de try y except\ncapitales = {\"Argentina\": \"Buenos Aires\", \"Chile\": \"Santiago\"}\npais_buscado = \"Venezuela\"\ntry:\n    capital = capitales[pais_buscado]\n    print(f\"La capital de {pais_buscado} es {capital}\")\nexcept KeyError:\n    print(f\"El país '{pais_buscado}' no se encuentra en la base de datos.\")\n    print(\"El programa sigue funcionando.\")\n\n# Ejercicio de dificultad extra\nprint(\"***Programa 01***\")\ncontador_prog = 10\nwhile contador_prog <= 55: \n   if contador_prog % 2 == 0 and contador_prog != 16 and not contador_prog % 3 == 0:\n    print(contador_prog)\n   elif contador_prog == 55:\n      print(contador_prog)\n   contador_prog += 1"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/CarlosMqz969.py",
    "content": "# Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n\n#Operadores Aritmeticos\n\nprint(3 + 4)\nprint(7 - 3)\nprint(3 * 4)\nprint(12 / 3)\n\n#Operador Modulo\n\nprint(10%2)\nprint(10%3)\n\n#Floor división\nprint(10 // 3)\n#Esta división aproxima el resultado a un número entero\n\n#Calcular exponente\nprint(2 ** 3)\n\n#Operadores Comparativos\n\nprint(3 > 4)\nprint(3 < 4)\nprint(3 >= 4)\nprint(3 <= 4)\nprint(3 == 4)\nprint(3 != 4)\n\n#Operadores lógicos\n\nprint(3 > 4 and 5 > 3)\nprint(3 > 4 or 5 > 3)\nprint(not(3>4)) #not niega toda la condición y la invierte\n\n# DIFICULTAD EXTRA (opcional):\n#* Crea un programa que imprima por consola todos los números comprendidos\n#* entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\ndef my_range():\n    for i in range(10,56):\n        if i % 2 == 0 and i !=16 and i % 3 != 0:\n            print(i)\n\nmy_range()"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/CaveroBrandon.py",
    "content": "# Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n\n# ************************************************************\n# OPERADORES ARITMETICOS\n# ************************************************************\nval1 = 20\nval2 = 10\n\naddition = val1 + val2  # Addition\nsubtraction = val1 - val2  # Subtraction\nmultiplication = val1 * val2  # Multiplication\ndivision = val1 / val2  # Division\nmodulus = val1 % val2  # Modulus\nfloor_division = val1 // val2  # floor division\nexponentiation = val1 ** val2  # Exponentiation\n\n# ************************************************************\n# OPERADORES LOGICOS\n# ************************************************************\na = True\nb = False\n\nc = a and b  # AND, return False\nd = a or b  # OR, return True\ne = not a  # NOT, return False\n\n# ************************************************************\n# OPERADORES DE IDENTIDAD\n# ************************************************************\nname = 'Brandon'\nlastname = 'Cavero'\n\nis_equal = name is lastname  # returns False\nis_not_equal = name is not lastname  # returns True\n\n# ************************************************************\n# OPERADORES DE COMPARACION\n# ************************************************************\nsmall_volume = 5\nbig_volume = 10\n\nis_equal = (small_volume == big_volume)  # return False\nis_not_equal = (small_volume != big_volume)  # return True\nis_less = (small_volume < big_volume)  # return True\nis_greater = (small_volume > big_volume)  # return False\nis_less_than = (small_volume <= big_volume)  # return True\nis_greater_than = (small_volume >= big_volume)  # return False\n\n# ************************************************************\n# OPERADORES DE PERTENENCIA\n# ************************************************************\nlanguage = 'Python'\nsyllabus = 'Py'\n\na = syllabus in language  # return True, 'Py' is in 'Python'\nb = 'Xo' in language  # return True, 'Xo' is not in 'Python'\n\n\"\"\"\nUtilizando las operaciones con operadores que tú quieras, crea ejemplos\nque representen todos los tipos de estructuras de control que existan\nen tu lenguaje:\n\"\"\"\n\n# ************************************************************\n# IF\n# ************************************************************\nprint('********* If statement *********')\ncondition = True\n\nif condition:\n    print('The condition is True so this will be printed')\nelse:\n    print('This should be printed if none of the conditions are True')\n\n# ************************************************************\n# FOR LOOP\n# ************************************************************\nprint('********* For loop *********')\nfruits = ['bananas', 'apples', 'grapes']\n\nfor fruit in fruits:\n    print(fruit)\n\n# ************************************************************\n# WHILE LOOP\n# ************************************************************\nprint('********* While loop *********')\ncounter = 3\n\nwhile counter > 0:\n    print('While loop')\n    counter -= 1\n\n# ************************************************************\n# TRY - EXCEPT\n# ************************************************************\nprint('********* Try - Except *********')\ntry:\n    a = 1 + _  # This should raise an exception\nexcept Exception as e:\n    print('This is being printed because of the error: ', e)\n\n\"\"\"\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\"\"\"\nprint('********* DIFICULTAD EXTRA *********')\nfor number in range(10, 56):\n    if number == 16 or (number % 3) == 0:\n        pass\n    elif number % 2 == 0:\n        print(number, end=' ')\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/CeciliaRava1.py",
    "content": "numberOne = 1\nnumberTwo = 2\n\nsum = numberOne + numberTwo\nsub = numberOne - numberTwo\nmultiplication = numberOne * numberTwo\ndivision = numberOne / numberTwo\nmodule = numberOne % numberTwo\n\n\nif numberTwo > numberOne:\n    print(f'{numberTwo} is higher than {numberOne}')\nelif numberTwo != numberOne:\n    print(f'{numberOne} and {numberTwo} are differents')\nelse:\n    print(f'{numberOne} is higher than {numberTwo}')\n\nwhile numberOne != numberTwo:\n    numberOne += 1\n\n'''\nCreate a program that prints to the console all numbers between 10 and 55 (inclusive), that are even, and are neither 16 \nnor multiples of 3.\n'''\n\nfor i in range(10, 56):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/CesarCarmona30.py",
    "content": "'''\n  OPERADORES\n'''\n\n# Operadores Aritméticos:\nprint(f\"Suma: 8 + 5 = {8 + 5}\")\nprint(f\"Resta: 8 - 5 = {8 - 5 }\")\nprint(f\"Multiplicación: 8 * 5 = {8 * 5}\")\nprint(f\"División: 8 / 5 = {8 / 5}\")\nprint(f\"División entera: 8 // 5 = {8 // 5}\")\nprint(f\"Módulo: 8 % 5 = {8 % 5}\")\nprint(f\"Potencia: 8 ** 5 = {8 ** 5}\")\n\n# Operadores Lógicos:\nprint(f\"AND (and):\") \nprint(f\"True and True = {True and True}\")\nprint(f\"True and False = {True and False}\")\nprint(f\"False and False = {False and False}\")\nprint(f\"OR (or):\") \nprint(f\"True or True = {True or True}\")\nprint(f\"True or False = {True or False}\")\nprint(f\"False or False = {False or False}\")\nprint(f\"NOT (not):\") \nprint(f\"not True = {not True}\")\nprint(f\"not False = {not False}\")\n\n# Operadores de Comparación:\nprint(f\"Igualdad: 15 == 5 es {15 == 5}\")\nprint(f\"Desigualdad: 15 != 5 es {15 != 5}\")\nprint(f\"Mayor que: 15 > 5 es {15 > 5}\")\nprint(f\"Menor que: 15 < 5 es {15 < 5}\")\nprint(f\"Mayor o igual que: 15 >= 155 es {15 >= 155}\")\nprint(f\"Menor o igual que: 155 <= 155 es {155 <= 155}\")\n\n# Operadores de Asignación:\nnumero = 50\nprint(f\"Asignación: numero = {numero}\")\nnumero += 1\nprint(f\"Suma y asignación: numero += 1 ({numero})\")\nnumero -= 3\nprint(f\"Resta y asignación: numero -= 3 ({numero})\")\nnumero *= 3\nprint(f\"Multiplicación y asignación: numero *= 3 ({numero})\")\nnumero /= 4\nprint(f\"División y asignación: numero /= 4 ({numero})\")\nnumero //= 5\nprint(f\"División entera y asignación: numero //= 5 ({numero})\")\nnumero %= 5\nprint(f\"Módulo y asignación: numero %= 5 ({numero})\")\nnumero **= 8\nprint(f\"Potencia y asignación: numero **= 8 ({numero})\")\n\n# Operadores de Identidad:\na = 85\nb = a\nc = b\n\nprint(f\"a = 85 y b = a, entonces b is a es: {b is a}\")\nprint(f\"b = a y c = b, entonces c not is a es: {c is not a}\")\n\n# Operadores de Pertenencia:\nprint(f\"'Hola' in 'Hola Mundo' es: {'Hola' in 'Hola Mundo'}\")\nprint(f\"'Hello' not in 'Hola Mundo' es: {'Hello' not in 'Hola Mundo'}\")\n\n# Operadores Bit a Bit:\nx = 10\ny = 12\n\nprint(f\"AND: 10 & 12 = {10 & 12}\") \nprint(f\"OR: 10 | 12 = {10 | 12}\")  \nprint(f\"XOR: 10 ^ 12 = {10 ^ 12}\")  \nprint(f\"NOT: ~2 = {~2}\")\nprint(f\"Desplazamiento a la derecha: 10 >> 2 = {10 >> 2}\") \nprint(f\"Desplazamiento a la izquierda: 10 << 2 = {10 << 2}\")\n\n'''\n  ESTRUCTURAS DE CONTROL\n'''\n\n# Condicionales\n\nmi_lenguaje = \"Python\"\n\nprint('Ejecutando estructura if: ')\nif mi_lenguaje == \"JavaScript\":\n  print(\"Estoy programando en JavaScript\")\nelif mi_lenguaje == \"Python\":\n  print(\"Estoy programando en Python\")\nelse:\n  print(\"No estoy programando en JavaScript ni en Python\")\n\n#Iterativas\n\nprint('Ejecutando estructura for: ')   \n\nfor n in range(1, 11):\n  print(n, end=' ')\n\nprint('\\nEjecutando estructura while: ')\n\nm = 0\nwhile m <= 10:\n  print(m, end=', ')\n  m += 1\n\n# Manejo de Excepciones\n\nprint('\\nEjecutando estructura try-except: ')\n\nprint('5 / 0 = ...')\ntry:\n  print(5 / 0)\nexcept ZeroDivisionError as err:\n  print(f\"Se produjo un error de tipo: {type(err).__name__}\")\nfinally:\n  print(\"*Nota: Recuerda que la división por cero no esta definida\")\n\n'''\n  EJERCICIO EXTRA\n'''\n\nfor number in range(10, 56):\n    if number % 2 != 0 or number == 16 or number % 3 == 0:\n      continue\n    print(number, end=' ')"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Chrisdev00.py",
    "content": "######   OPERADORES DE ASIGNACION  #######\n\nx = 5\n\nx = 5\nx += 3   # Es igual a escribir: x = x + 3\n\ny = 5\ny -= 3   # Es igual a escribir: y = y - 3\n\nc = 5\nc *= 3   # Es igual a escribir: c = c * 3\n\nd = 5\nd /= 3   # Es igual a escribir: d = d / 3\n\ne = 5\ne %= 3   # Es igual a escribir: e = e % 3\n\nf = 5\nf //= 3  # Es igual a escribir: f = f // 3\n\ng = 5\ng **= 3  # Es igual a escribir: g = g ** 3\n\nh = 5\nh &= 3   # Es igual a escribir: h = h & 3\n\ni = 5\ni |= 3   # Es igual a escribir: i = i | 3\n\nj = 5\nj ^= 3   # Es igual a escribir: j = j ^ 3\n\nk = 5\nk >>= 3  # Es igual a escribir: k = k >> 3\n\nl = 5\nl <<= 3  # Es igual a escribir: l = l << 3\n\nprint(x)\nprint(x)\nprint(y)\nprint(c)\nprint(d)\nprint(e)\nprint(f)\nprint(g)\nprint(h)\nprint(i)\nprint(j)\nprint(k)\nprint(l)\n\n######    OPERADORES ARITMETICOS    ############\n\na = 3 \nb = 2 \n\ntotal = a + b # no se puede poner sum como nombre de variable ya que sum es una funcion interna \ndiff = a - b\nproduct = a * b\ndivision = a / b\nresto = a % b\nfloor_division = a // b\nexponential = a ** b\n\nprint(total) \nprint('a + b = ', total)\nprint('a - b = ', diff)\nprint('a * b = ', product)\nprint('a / b = ', division)\nprint('a % b  = ', resto)\nprint('a // b = ', floor_division)\nprint('a ** b = ', exponential)\n\n#####    OPERADORES DE COMPARACION   ##########\n\n\"\"\"\n==\tEqual\tx == y\t\n!=\tNot equal\tx != y\t\n>\tGreater than\tx > y\t\n<\tLess than\tx < y\t\n>=\tGreater than or equal to\tx >= y\t\n<=\tLess than or equal to\tx <= y\n\n\"\"\"\n\nprint(3 > 2)     # True\nprint(3 >= 2)    # True\nprint(3 < 2)     # False\nprint(2 < 3)     # True\nprint(2 <= 3)    # True\nprint(3 == 2)    # False\nprint(3 != 2)    # True\nprint(len('mango') == len('manzana'))  # False\nprint(len('mango') != len('manzana'))  # True\nprint(len('mango') < len('manzana'))   # True\nprint(len('milk') != len('meat'))      # False\nprint(len('milk') == len('meat'))      # True\nprint(len('tomato') == len('potato'))  # True\nprint(len('python') > len('dragon'))   # False\n\n\"\"\"\nAdemás del operador de comparación anterior, Python usa:\n\nes : Devuelve verdadero si ambas variables son el mismo objeto (x es y)\nno es : Devuelve verdadero si ambas variables no son el mismo objeto (x no es y)\nin : Devuelve Verdadero si la lista consultada contiene un elemento determinado (x en y)\nnot in : devuelve True si la lista consultada no tiene un elemento determinado (x en y)\n\n\"\"\"\n\nprint('1 is 1', 1 is 1)                       # True\nprint('1 is not 2', 1 is not 2)               # True \nprint('A in Algoritmo', 'A' in 'Algoritmo')   # True \nprint('B in Algoritmo', 'B' in 'Algoritmo')   # False \nprint('coding' in 'coding for all')           # True \nprint('4 is 2 ** 2:', 4 is 2 ** 2)            # True\n\n\n####  OPERADORES LOGICOS  ###########\n\n\"\"\"\nand \tDevuelve True si ambas condiciones son verdaderas:\t    x < 5 and  x < 10\t\nor\t    Devuelve True si una de las condiciones es verdadera:\tx < 5 or x < 4\t\nnot\t    Invierte el resultado, devuelve Falso si el resultado es verdadero:\tnot(x < 5 and x < 10)\n\n\"\"\"\n\nprint(3 > 2 and 4 > 3) # True\nprint(3 > 2 and 4 < 3) # False - porque la segunda condicion es falsa\nprint(3 < 2 and 4 < 3) # False \nprint('True and True: ', True and True)\nprint(3 > 2 or 4 > 3)  # True\nprint(3 > 2 or 4 < 3)  # True - porque una de las condiciones es verdadera\nprint(3 < 2 or 4 < 3)  # False - porque las dos condiciones son falsas\nprint('True or False:', True or False)\nprint(not 3 > 2)     # False - porque 3 > 2 es verdadero, entonces not True devuelve Falso\nprint(not True)      # False - Negacion\nprint(not False)     # True\nprint(not not True)  # True\nprint(not not False) # False\n\n\n####    Crea un programa que imprima por consola todos los números comprendidos\n####    entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\nfor i in range(10, 56):\n    if i == 16:\n        pass\n    elif i % 3 == 0:\n        pass\n    elif i % 2 == 0:\n        print(i)\n\n    "
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/CipollaLucas.py",
    "content": "# * - EJERCICIO * :\r\n\"\"\" - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\r\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\r\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\r\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\r\n *   que representen todos los tipos de estructuras de control que existan\r\n *   en tu lenguaje:\r\n *   Condicionales, iterativas, excepciones...\r\n * - Debes hacer print por consola del resultado de todos los ejemplos.\r\n *\r\n * DIFICULTAD EXTRA (opcional):\r\n * Crea un programa que imprima por consola todos los números comprendidos\r\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\r\n *\r\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo \"\"\"\r\n\r\n# * ------------------------------------------------------------------------------------ * #\r\n\r\n\"\"\" - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\r\nAritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\"\"\"\r\n# * Aritméticos\r\nsuma = 2+2\r\nresta = 2-2\r\nmultiplicacion = 2*2\r\ndivision = 2/2\r\nmodulo = 2%2\r\nparte_entera = 2//2\r\npotencia = 2**2\r\nprint(\"\\n\")\r\nprint(\"Suma: \", suma, \"\\nResta: \", resta, \"\\nMultiplicacion: \", multiplicacion, \"\\nDivision: \", division, \"\\nModulo: \", modulo, \"\\nParte entera: \", parte_entera, \"\\nPotencia: \", potencia)\r\nprint(\"\\n------------------------------------------------------------------------------------- \\n\")\r\n\r\n# * lógicos (and, or o not)\r\n#AND ambas deben ser verdad para delvolver True.\r\nprint(\"\\nAND\")\r\nif(1==1 and 2==2):\r\n    print (True)\r\nelse:\r\n    print(\"ERROR!\")\r\n\r\n#OR con que una sea verdadera bastará para retornar True\r\nprint(\"\\nOR\")\r\nif (1!=2 | 1!=1): \r\n    print (True)\r\nelse:\r\n    print (False)\r\n\r\n#NOT solo dará verdadero cuando su condición sea negada.\r\nprint(\"\\nNOT\")\r\nif (1!=0):\r\n    print(True)\r\nelse:\r\n    print(False)\r\nprint(\"------------------------------------------------------------------------------------- \\n\")\r\n\r\n# * Asignación\r\nnum = 2\r\nprint (\"\\n\", num)\r\n# Asignación compuesta\r\nnum+=2\r\nprint (\"\\n\", num)\r\nnum-=2\r\nprint (\"\\n\", num)\r\nnum*=2\r\nprint (\"\\n\", num)\r\nnum/=2\r\nprint (\"\\n\", num)\r\nnum%=2\r\nprint (\"\\n\", num)\r\nnum//=2\r\nprint (\"\\n\", num)\r\nnum**=2\r\nprint (\"\\n\", num)\r\nprint(\"------------------------------------------------------------------------------------- \\n\")\r\n\r\n#* Operadores bits a bits o bitwise\r\nnum = 27\r\nnumb = 28\r\nprint(bin(num))\r\nprint(bin(numb))\r\nnum&=numb\r\nprint (\"\\n\", num)\r\nnum|=numb\r\nprint (\"\\n\", num)\r\nnum^=numb\r\nprint (\"\\n\", num)\r\nnum>>=numb\r\nprint (\"\\n\", num)\r\nnum<<=numb\r\nprint (\"\\n\", num)\r\nprint(\"------------------------------------------------------------------------------------- \\n\")\r\n\r\n# * Operadores de identidad\r\nprint(\"Identidad\")\r\nprint(1 is 2)\r\nprint(1 is not 2)\r\nprint(\"------------------------------------------------------------------------------------- \\n\")\r\n\r\n# * Operadores de pertenencia\r\nprint(\"Membresia\")\r\nprint(1 in [1,2,3])\r\nprint(1 not in [2,3,4,5])\r\nprint(\"------------------------------------------------------------------------------------- \\n\")\r\n\r\n\r\n# * ------------------------------------------------------------------------------------ * #\r\n\r\n\"\"\"- Utilizando las operaciones con operadores que tú quieras, crea ejemplos\r\nque representen todos los tipos de estructuras de control que existan\r\nen tu lenguaje:\r\nCondicionales, iterativas, excepciones...\r\nDebes hacer print por consola del resultado de todos los ejemplos.\"\"\"\r\nprint(\"Condicionales\\n\")\r\nprint(\"IF\")\r\na = 4\r\nb = 2\r\nif (a > b):\r\n    print(\"Resultado: \", a/b)\r\nelse:\r\n    print(\"B es mas grande que A, y no tengo ganas de dividir de esa manera.\")\r\n\r\nprint(\"\\nFor\")\r\nnum = 1\r\nlista = [1,2,3,4,5]\r\nfor num in lista:\r\n    print(num)\r\n\r\nprint(\"\\nForRange\")\r\nfor i in range (0, 5):\r\n    print(i)\r\n\r\nprint(\"\\nWhile\")\r\nnum = 1\r\nwhile (num != 5):\r\n    print(num)\r\n    num+=1\r\n\r\nprint(\"\\nSwitch se puede emular, pero no tiene de manera nativa\")\r\ncondicion = 5\r\nif condicion == 1:\r\n    print(\"Haz a\")\r\nelif condicion == 2:\r\n    print(\"Haz b\")\r\nelif condicion == 3:\r\n    print(\"Haz c\")\r\nelse:\r\n    print(\"Haz d\")\r\n\r\nprint(\"\\n\")\r\n\r\nprint(\"\\nBreak\") #Permite alterar el while y el for.\r\n\r\ncadena = 'Python'\r\nfor letra in cadena:\r\n    if letra == 'h':\r\n        print(\"Se encontro la h\")\r\n        break\r\n    print(letra)\r\n\r\nprint(\"\\nContinue\") #También permite alterar el while y el for.\r\ncadena = 'Python'\r\nfor letra in cadena:\r\n    if letra == 'P':\r\n        print(\"Se encontro la P\")\r\n        continue\r\n    print(letra)\r\n\r\n\r\nprint(\"\\nFuncion zip()\") #Viene incluída por defecto. Si le pasamos dos listas nos dará una tupla combinada. También podemos utilizarla con diccionarios.\r\na = [5, 2, 3, 4, 9]\r\nb = [\"Uno\", \"Dos\", \"Tres\", \"Cuatro\", \"Nueve\"]\r\nc = zip(a, b)\r\n\r\nprint(list(c))\r\n\r\nprint(\"\\nEnumerate\") #Sirve para recorrer algo y además de buscar un valor, podemos extraer facilmente la posición.\r\nlista = [\"A\", \"B\", \"C\"]\r\n\r\nfor indice, letra in enumerate(lista):\r\n    print(indice, letra)\r\n\r\nprint(\"\\nList Comprehensions\") #Nos permite crear una lista en una sola línea: lista = [expresión for elemento in iterable]\r\ncuadrados = [i**2 for i in range(5)]\r\nprint(cuadrados)\r\n\r\nprint(\"\\nIteradores e Iterables\") #Permite iterar colecciones que sean iterables\r\n\r\n# * ------------------------------------------------------------------------------------ * #\r\n\"\"\" * DIFICULTAD EXTRA (opcional):\r\nCrea un programa que imprima por consola todos los números comprendidos\r\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\"\"\"\r\nprint(\"\\n Desafio EXTRA\")\r\nfor i in range(10, 56):\r\n    if (i % 2 == 0):\r\n        if (i % 3 != 0):\r\n            if(i != 16):\r\n                print(i)\r\n\r\n\r\n# * ------------------------------------------------------------------------------------ * #\r\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Complex303.py",
    "content": "#Operadores Aritmeticos\n\nvalor1 = 20\nvalor2 = 22\nresultado = valor1 + valor2\n\nprint(f\"La suma de {valor1} + {valor2} = {resultado}\")\n\n\nprint(f\"La Suma de 8 + 7 =  {8+7}\")\nprint(f\"La Resta de 10 - 2 = {10-2}\")\nprint(f\"La Multiplicacion de 8 x 7 =  {8*7}\")\nprint(f\"La Division de 10 / 2 = {int(10/2)}\")\nprint(f\"El residuo de 16 % 3 es {16 % 3}\")\nprint(f\"Exponente de  10 ^ 2 = {10**2}\")\nprint(f\"La Division entere de 16 // 3 =  {16 // 3}\")\n\n\n#operadores de comparacion\nprint (f\"Igualdad: 4 == 2 es {4 == 2}\") #compara si 4 es igual 2, si es igual pone true, sino false\nprint (f\"Desigualdad: 4 != 2 es {4 != 2}\")\nprint (f\" 4 > 2 = {4 > 2}\") #mayor que\nprint (f\" 4 < 2 = {4 < 2}\") #menor que \nprint (f\" 4 >= 2 = {4 >= 2}\") #mayor o igual que\nprint (f\" 4 <= 2 = {4 <= 2}\") #menor o igual que\n\n\n#operadores logicos\nprint(f\"AND &: 20 == 10 AND 7 - 2 == 5  = {20 == 10 and 7 - 2 == 5} \")\nprint(f\"or ||: 20 == 10 or 7 - 2 == 5  = {20 == 10 or 7 - 2 == 5} \")\nprint(f\"NOT !: 20 + 20 == 50 {not 20 + 20 == 50} \")\n\n\n#operadores de asignacion\ncantidad = 12\nprint(cantidad)\ncantidad +=1 #suma y asignacion \nprint(cantidad)\ncantidad -= 1 #restq y asignacion\nprint(cantidad)\ncantidad *=2 #multipliclacion y asignacion\nprint(cantidad)\ncantidad /=3 #division y asignacion\nprint(int(cantidad))\ncantidad %=3 #modulo y asignacion\nprint(int(cantidad))\ncantidad **=3 #exponente y asignacion\nprint(int(cantidad))\ncantidad //=3 #division entera y asignacion\n\n\n\n\"\"\"operadores de identidad: Son operadores que comparan si dos variables apuntan al mismo objeto en memoria, \nno si su contenido es igual, sino si son el mismo objeto\"\"\"\n\nnueva_cantidad  = 8\nprint(f\"cantidad es mi nueva_cantidad: {cantidad is nueva_cantidad}\") #false \n\n\nnueva_cantidad  = cantidad\nprint(f\"cantidad es mi nueva_cantidad: {cantidad is nueva_cantidad}\") #true\nprint(f\"cantidad no es mi nueva_cantidad: {cantidad is not nueva_cantidad}\") #False\n\n\n\n#Operadores de pertenencias\n\nprint(f\"p in Complex:{'p' in 'Complex'}\") #la letra p esta en la palabras \"Complex\"? en este casi si, por lo que devuelve true\nprint(f\"p in Complex:{'p' not in 'Complex'}\") #false\n\n\n#operadores de bit\na = 10 #1010\nb = 3 #0011\nprint(f\"AND: 10 & 3 = {10 & 3}\") #LOS DOS TIENE QUE SER 1. #EL RESULTADO SERIA: 0010 (2) EN BIT\nprint(f\"OR: 10 | 3 = {10 | 3}\") #AL MENOS UNO TIENE QUE SER 1. #EL RESULTADO SERIA: 1011 (11) EN BIT\nprint(f\"XOR: 10 ^ 3 = {10 ^ 3}\") #SI LOS BIT SON DIFERENTE ES 1, SI SON IGUALES ES 0. #EL RESULTADO SERIA: 1001 (9) EN BIT\nprint(f\"NOT: ~10 = {~10}\") \nprint(f\"Desplazamiento a la derecha: 10 >> 2 = {10 >> 2}\") #10 (1010) si lo desplamazamos 2 veces a la dercha seria = 2 (0010)\nprint(f\"Desplazamiento a la izquiera: 10 << 2 = {10 << 2}\") #10 (1010) si lo desplamazamos 2 veces a la dercha seria 101000 (40)\n\n\n#Estructura de control\n\n#condicionales\n\nyear = 2024\n\nif year == 2025:\n    print(\"El año es 2025\")\nelif year < 2025:\n    print(\"El año ya paso\")\nelse:\n    print(\"El año no es 2025\")\n\n\n#iterativas\n\nfor i in range(11):\n    print(i)\n\n\ni = 0\n\nwhile i <= 10:\n    print(i)\n    i +=1\n\n\n#manejo de excepciones\ntry:\n    print(10/0)\nexcept:\n    print(\"No se puede dividir entre 0\")\nfinally:\n    print(\"Ha finalizado el manejo de excepciones\")\n\n\n'''\nDIFICULTAD EXTRA (opcional):\nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3. '''\n\n\n\n\nfor num in range(10, 56):\n    if num % 2 ==0 and num != 16 and num % 3 != 0:\n        print(num)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/D3rk1us.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\"\"\"\n\n# Aritméticos\n\nop1 = 2 + 2     # Suma\nop2 = 3 - 2     # Resta\nop3 = 4 * 2     # Multiplicación\nop4 = 5 / 2     # División\nop5 = 6 % 2     # Módulo\nop6 = 7 ** 2    # Potencia\nop7 = 8 // 2    # Divide con resultado de número entero.\n\nprint(\"Operadores Aritméticos:\")\nprint(f\"Suma = {op1}\\nResta = {op2}\\nMultiplicación = {op3}\\nDivisión = {op4}\\nMódulo = {op5}\\nPotencia = {op6}\\nResultado entero de la división = {op7}\")\n\n# Lógicos y condicional if\n\nprint(\"\\nOperadores Lógicos:\")\n\n\nif True and True:\n    print(f\"True and True = {True and True}\")    # True, si ambos elementos son verdaderos.\n\nif True or False:\n    print(f\"True or False = {True or False}\")    # True, si al menos un elemento es verdadero.\nelse:\n    print(f\"True or False = False\")\n\nprint(f\"not True = {not True}\")                  # Devuelve lo contrario.\n\n# De Comparación\n\na = 12\nb = 7\nc = 12\n\nprint(\"\\nOperadores de Comparación:\")\nprint(f\"{a} > {b} = {a > b}\")\nprint(f\"{a} < {b} = {a < b}\")\nprint(f\"{a} == {c} = {a == c}\")\nprint(f\"{a} != {c} = {a != c}\")\nprint(f\"{a} <= {c} = {a <= c}\")\nprint(f\"{b} >= {a} = {b >= a}\")\n\n\n# Asignación\n\nprint(\"\\nOperadores de Asignación:\")\nprint(\"x += 2\\nx -= 2\\nx *= 2\\nx /= 2\\nx %= 2\\nx //= 2\\nx **= 2\\nx &= 2\\nx |= 2\\nx ^= 2\\nx >>= 2\\nx <<= 2\")\t\n\n# Identidad\n\nv = \"Hola\"\nx = 67\n\nprint(\"\\nOperadores de Identidad:\")\nprint(f\"{v} is {x} = {v is x}\")\nprint(f\"{x} is not {v} = {x is not v}\")\nprint(f\"{x} is 67 = {x is 67}\")\n\n# Pertenencia\n\nlista = [1, 2, 3, 4, 5, 6]\n\nprint(\"\\nOperadores de Pertenencia:\")\nprint(f\"2 in lista = {2 in lista}\")\nprint(f\"5 not in lista = {5 not in lista}\")\n\n# Excepciones y bucle while\n\nwhile True:\n    try:\n        num = int(input(\"Introduce un número: \"))\n        break\n    \n    except ValueError:\n        print(\"No ha sido un número válido. Inténtalo de nuevo...\")\n\n\n# Ejercicio opcional con bucle for:\n\nfor i in range(10, 56):\n    if i != 16 and i % 3 != 0 and i % 2 == 0:\n        print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/DAVstudy.py",
    "content": "\nprint(\" Operadores de Python\")\nprint(\"\")\n\n# Operadores aritméticos \nprint(f\"Operadores aritméticos\")\nprint(\"\")\nprint(f\"Definiremos: 'x' = 4 e 'y' = 3\")\nprint(\"\")\nx = 4\ny = 3\n\n# Suma\nsuma = x + y  # Suma de 'x' mas 'y'\nprint(\"Suma:\")\nprint(f\"x + y = {suma}\")\nprint(\"\")\n\n# Resta\nresta = x - y # Resta de 'x' menos 'y'\nprint(\"Resta:\")\nprint(f\"x - y = {resta}\")\nprint(\"\")\n\n# Multiplicación\nmultiplicacion = x * y  # Multiplicación de  'x' por 'y'\nprint(\"Multiplicacion:\")\nprint(f\"x * y = {multiplicacion}\")\nprint(\"\")\n\n# Potenciación\npotenciacion = x ** y  # Potenciación de 'x' elevado a 'y'\nprint(\"Potenciación:\")\nprint(f\"x ** y = {potenciacion}\")\nprint(\"\")\n\n# División\ndivision = x / y  # División de 'x' sobre 'y'\nprint(\"División:\")\nprint(f\"x / y = {division}\")\nprint(\"\")\n\n# División entera (resulta solo la parte entera de la división)\ndivision_entera = x // y  # División entera de 'x' sobre 'y'\nprint(\"División entera:\")\nprint(f\"x // y = {division_entera}\")\nprint(\"\")\n\n# Resto de una división o Módulo\nresto_division = x % y  # Resto o modulo de la división de 'x' sobre 'y'\nprint(\"Resto de una división o Módulo:\")\nprint(f\"x % y = {resto_division}\")\nprint(\"\")\n\n\nprint(\"\"\"\nOperadores Relacionales\n\n>  Devuelve True si el operador de la izquierda es mayor que el operador de la derecha\n<  Devuelve True si el operador de la derecha es mayor que el operador de la izquierda\n== Devuelve True si ambos operandos son iguales\n>= Devuelve True si el operador de la izquierda es mayor o igual que el operador de la derecha\n<= Devuelve True si el operador de la derecha es mayor o igual que el operador de la izquierda\n!= Devuelve True si ambos operandos no son iguales\n\nFuente: https://www.freecodecamp.org/espanol/news/operadores-basicos-en-python-con-ejemplos/\n\"\"\")\n\nprint(\"\")\n\nresultado_mayor_que = x > y  # Retorna True\nprint(\"Ejemplo con > :\")\nprint(f\"x > y  = {resultado_mayor_que}\")\nprint(\"\")\n\n\nresultado_menor_que = x < y  # Retorna False\nprint(\"Ejemplo con < :\")\nprint(f\"x < y  = {resultado_menor_que}\")\nprint(\"\")\n\nresultado_igualdad = x == y  # Retorna False\nprint(\"Ejemplo con == :\")\nprint(f\"x == y  = {resultado_igualdad}\")\nprint(\"\")\n\nresultado_mayor_igual = x >= y  # Retorna True\nprint(\"Ejemplo con >= :\")\nprint(f\"x >= y  = {resultado_mayor_igual}\")\nprint(\"\")\n\nresultado_menor_igual = x <= y  # Retorna False\nprint(\"Ejemplo con <= :\")\nprint(f\"x <= y  = {resultado_menor_igual}\")\nprint(\"\")\n\nresultado_distinto_a = x != y  # Retorna True\nprint(\"Ejemplo con != :\")\nprint(f\"x != y  = {resultado_distinto_a}\")\nprint(\"\")\n\nprint(\"\"\"\nOperadores Bit a bit\n\n&\tRealiza bit a bit la operación AND en los operandos.\n|\tRealiza bit a bit la operación OR en los operandos.\n^\tRealiza bit a bit la operación XOR en los operandos.\n~\tRealiza bit a bit la operación NOT bit a bit. Invierte cada bit en el operando.\n>>\tRealiza un desplazamiento a la derecha bit a bit. Desplaza los bits del operador \n    de la izquierda a la derecha tantos bits como indica el operador de la derecha.\n<<\tRealiza un desplazamiento a la izquierda bit a bit. Desplaza los bits del operando\n    de la izquierda a la izquierda tantos bits como especifique el operador de la derecha.\n\nFuente: https://www.freecodecamp.org/espanol/news/operadores-basicos-en-python-con-ejemplos/\n\"\"\")\n\nprint(\"\")\nprint(\"Como ejemplo usaremos a = 2 (bit = 10) y b = 3 (bit = 11)\")\na = 2\nb = 3\n\n# AND\nresultado_and = a & b  # El resultado es 2 (Bit: 10 & 11 = 10 )\nprint(\"Ejemplo con AND:\")\nprint(f\"a & b = {resultado_and} (Bit: 10 & 11 = 10 )\")\nprint(\"\")\n\n# OR\nresultado_or = a | b  # El resultado es 3 (Bit: 10 | 11 = 11 )\nprint(\"Ejemplo con OR:\")\nprint(f\"a | b = {resultado_or} (Bit: 10 | 11 = 11 )\")\nprint(\"\")\n\n# XOR\nresultado_xor = a ^ b  # El resultado es 1 (Bit: 10 ^ 11 = 01)\nprint(\"Ejemplo con XOR :\")\nprint(f\"a ^ b = {resultado_xor} (Bit: 10 ^ 11 = 01)\")\nprint(\"\")\n\n# NOT\nresultado_not = ~a  # El resultado es -3 (Bit: ~(00000010) = (11111101))\nprint(\"Ejemplo con NOT:\")\nprint(f\"~a  = {resultado_not} (Bit: ~(00000010) = (11111101))\")\nprint(\"\")\n\n# Desplazamiento a la derecha bit a bit.\nresultado_der = a >> b  # El resultado es 0 (Binario: 00000010 >> 00000011 = 0)\nprint(\"Ejemplo con Desplazamiento a la derecha bit a bit:\")\nprint(f\"a >> b  = {resultado_der} (Binario: 00000010 >> 00000011 = 0)\")\nprint(\"\")\n\n# Desplazamiento a la izquierda bit a bit.\nresultado_izq = a << b  # El resultado es 16 (Binario: 00000010 >> 00000011 = 00001000)\nprint(\"Ejemplo con Desplazamiento a la izquierda bit a bit:\")\nprint(f\"a << b  = {resultado_izq} (Binario: 00000010 >> 00000011 = 00001000)\")\nprint(\"\")\n\nprint(\"\"\"\nOperadores de Asignación\n\n=   Asigna el valor ejemplo: x = 4 se le asigna el valor de 4 a 'x'\n+=  Incrementa, es equivalente a la suma\n-=  Decrementa, es equivalente a la resta\n*=  Es equivalente a la multiplicación\n**= Es equivalente a la potenciación\n/=  Es equivalente a la división\n//= Es equivalente a la división entera\n%=  Es equivalente al resto o modulo\n&=  Es equivalente a AND\n|=  Es equivalente a OR\n^=  Es equivalente a XOR\n>>= Es equivalente a el desplazamiento a la derecha\n<<= Es equivalente a el desplazamiento a la izquierda\n\nFuente: https://www.freecodecamp.org/espanol/news/operadores-basicos-en-python-con-ejemplos/\n\n\"\"\")\nprint(\"Definimos z = 5\")\nprint(\"\")\n\nz = 5  # Se le asigna el valor de 5 a 'z'\nprint(\"Ejemplo = :\")\nprint(f\"z = 5  = {z}\")\nprint(\"\")\n\nz += 5  # Se le suma el valor de 5 al valor anterior de z (resultado z = 10)\nprint(\"Ejemplo += :\")\nprint(f\"z += 5 = {z}\")\nprint(\"\")\n\nz -= 5  # Se le resta el valor de 5 al valor anterior de z (resultado z = 5)\nprint(\"Ejemplo -= :\")\nprint(f\"z -= 5 = {z}\")\nprint(\"\")\n\nz *= 5  # Se le multiplica el valor de 5 al valor anterior de z (resultado z = 25)\nprint(\"Ejemplo *= :\")\nprint(f\"z *= 5 = {z}\")\nprint(\"\")\n\nz **= 5 # Se le eleva a 5 al valor anterior de z (resultado z = 9765625)\nprint(\"Ejemplo **= :\")\nprint(f\"z **= 5 = {z}\")\nprint(\"\")\n\nz /= 100000  # Se le divide 'z' sobre 100000 (resultado z = 97.65625)\nprint(\"Ejemplo /= :\")\nprint(f\"z /= 5 = {z}\")\nprint(\"\")\n\nz //= 30  # Se hace una division entera a 'z' sobre 30 (resultado z = 3)\nprint(\"Ejemplo //= :\")\nprint(f\"z //= 5 = {z}\")\nprint(\"\")\n\nz %= 2  # Se obtiene el resto de 'z' divido por 2 (resultado z = 1)\nprint(\"Ejemplo %= :\")\nprint(f\"z %= 5 = {z}\")\nprint(\"\")\n\n\nprint(\"Utilizare los valores de a y b de la seccion de operadores bit a bit\" )\nprint(\"\")\na = 2\nb = 3\n\na &= b  # El resultado es a = 2 (Bit: 10 & 11 = 10 )\nprint(\"Ejemplo con &= :\")\nprint(f\"a &= b el valor de a es: {a} (Bit: 10 & 11 = 10 )\")\nprint(\"\")\n\na = 2\nb = 3\na |= b  # El resultado es a = 3 (Bit: 10 | 11 = 11 )\nprint(\"Ejemplo con |= :\")\nprint(f\"a |= b el valor de a es: {a} (Bit: 10 | 11 = 11 )\")\nprint(\"\")\n\na = 2\nb = 3\na ^= b  # El resultado es a = 1 (Bit: 10 ^ 11 = 01)\nprint(\"Ejemplo con |= :\")\nprint(f\"a |= b el valor de a es: {a} (Bit: 10 ^ 11 = 01)\")\nprint(\"\")\n\na = 2\nb = 3\na >>= b  # El resultado es a = 0 (Binario: 00000010 >> 00000011 = 0)\nprint(\"Ejemplo con >>= :\")\nprint(f\"a >>= b el valor de a es: {a} (Binario: 00000010 >> 00000011 = 0)\")\nprint(\"\")\n\na = 2\nb = 3\na <<= b  # El resultado es a = 16 (Binario: 00000010 >> 00000011 = 00001000)\nprint(\"Ejemplo con <<= :\")\nprint(f\"a <<= b el valor de a es: {a} (Binario: 00000010 >> 00000011 = 00001000)\")\nprint(\"\")\n\n\nprint(\"\"\"\nOperadores Lógicos\n\nand Devuelve True si ambos operandos son True\nor  Devuelve True si alguno de los operandos es True\nnot Devuelve True si alguno de los operandos False\n\nFuente: https://www.freecodecamp.org/espanol/news/operadores-basicos-en-python-con-ejemplos/\n\n\"\"\")\n\nresultado_log_and = x > y and x < y\nprint(\"Ejemplo 'and' :\")\nprint(f\"x > y and x < y = {resultado_log_and}, con 'x' = 4 e 'y' = 3\")\nprint(\"\")\n\nresultado_log_or = x > y or x < y\nprint(\"Ejemplo 'or' :\")\nprint(f\"x > y or x < y = {resultado_log_or}, con 'x' = 4 e 'y' = 3\")\nprint(\"\")\n\nresultado_log_not = not x > y\nprint(\"Ejemplo 'or' :\")\nprint(f\"not x > y = {resultado_log_not}, con 'x' = 4 e 'y' = 3\")\nprint(\"\")\n\n\nprint(\"\"\"\nOperadores de Pertenencia\n\nin  Devuelve True si el valor especificado se encuentra en la secuencia.\n    En caso contrario devuelve False.\n\nnot in  devuelve True si el valor especificado no se encuentra en la secuencia.\n        En caso contrario devuelve False.\n\nFuente: https://www.freecodecamp.org/espanol/news/operadores-basicos-en-python-con-ejemplos/\n\n\"\"\")\n\nmi_cadena = \"Hola Mundo\"\n\nresultado_in = \"H\" in mi_cadena\nprint(\"Ejemplo 'in' :\")\nprint(f\"'H' in mi_cadena = {resultado_in}, con 'mi_cadena' = 'Hola Mundo'\")\nprint(\"\")\n\nresultado_not_in = \"x\" not in mi_cadena\nprint(\"Ejemplo 'not in' :\")\nprint(f\"'x' not in mi_cadena = {resultado_not_in}, con 'mi_cadena' = 'Hola Mundo'\")\nprint(\"\")\n\nprint(\"\"\"\nOperadores de Identidad\n\nis  Devuelve True si los operandos se refieren al mismo objeto.\n    En caso contrario devuelve False.\n\nis not  Devuelve True si los operandos no se refieren al mismo objeto.\n        En caso contrario devuelve False.\n\nFuente: https://www.freecodecamp.org/espanol/news/operadores-basicos-en-python-con-ejemplos/\n\n\"\"\")\n\nmi_cadena = \"Hola Mundo\"\nmi_cadena_2 = \"Hola Mundo\"\n\nresultado_is = mi_cadena is mi_cadena_2\nprint(\"Ejemplo 'not in' :\")\nprint(f\"mi_cadena is mi_cadena_2 = {resultado_is}, con 'mi_cadena' = 'Hola Mundo' y 'mi_cadena_2' = 'Hola Mundo'\")\nprint(\"\")\n\nresultado_is_not = mi_cadena is not mi_cadena_2\nprint(\"Ejemplo 'not in' :\")\nprint(f\"mi_cadena is not mi_cadena_2 = {resultado_is_not}, con 'mi_cadena' = 'Hola Mundo'\")\nprint(\"\")\n\n\n# Estructuras de control\n\nprint(\"\"\"\nEstruturas Condicionales\n\nEstructura if, elif y else:\n\nif 'condición':\n    codigo a ejecutar si se cumple la condición\nelfi 'condición_2':\n    se ejecutara este bloque si la condicion no se cumple pero la condicion_2 si\nelse:\n    Si no secumplen las condiciones anteriores se ejecutara este bloque\n\nnota: la condición if puede utilizarse por si sola.\n\nFuente: https://www.freecodecamp.org/espanol/news/operadores-basicos-en-python-con-ejemplos/\n\n\"\"\")\nprint(\"\")\n\nprint(\"\"\"Usaremos el siguiente ejemplo\n\nif suma == 7 and \"H\" in mi_cadena:\n    print(\"Se cumple la primera condicion: 'suma == 7 and 'H' in mi_cadena:' \")\nelif resta < division:\n    print(\"Se cumple la segunda condicion: 'resta < division' \")\nelse:\n    print('No se cumplio ninguna de las condiciones anteriores')\n\nComo la suma si es igual a 7 y 'H' esta en micadena se ejecurara el codigo que esta en if.\n\n\"\"\")\n\nif suma == 7 and \"H\" in mi_cadena:\n    print(\"Se cumple la primera condicion: 'suma == 7 and 'H' in mi_cadena:' \")\nelif resta < division:\n    print(\"Se cumple la segunda condicion: 'resta < division' \")\nelse:\n    print('No se cumplio ninguna de las condiciones anteriores')\n\nprint(\"\")\nprint(\"\"\"\nEstructuras Iterativas\n\nEstructura while:\n\nwhile 'condicion':\n    se ejecutara el codigo iterativamente, hasta que la condicion no se cumpla\n\nEstructura for:\n\nfor 'variable iteradora' in 'cantidad de iteraciones'\n    se ejecutara el codigo\n\n'cantidad de iteraciones': pueden ser listas, rangos, entre otros.\n\n\"\"\")\nprint(\"\")\n\nprint(\"\"\"Usaremos el siguiente ejemplo:\n\nwhile x < 7:\n    x += 1\n    print(x)\n\nEntraremos al bucle, y se le sumara uno a la variabla 'x' que vale 4 y se imprimira en terminal\nse saldra del bucle en el momento que no se cumpla la condicion x < 7\n\n\"\"\")\n\nprint(\"Entrando en bucle while: \")\n\nwhile x < 7:\n    x += 1\n    print(x)\n\nprint(\"Sali del bucle while \")\n\nprint(\"\")\nprint(\"\"\"Usaremos el siguiente ejemplo:\n\nfor i in range(3):\n    print(i)\n\nEntraremos al  for, que tiene como iterador la variable i y con range() daremos la cantidad de \niteraciones que en este caso seran 3. y cada ves que se itere se imprimira la variable i\n\n\"\"\")\n\nprint(\"Entrando en bucle for: \")\n\nfor i in range(3):\n    print(i)\n\nprint(\"Sali del bucle for \")\n\n\nprint(\"\"\"\nEstructura de Excepciones\n\nEstructura try, except, else y finally. usaremos el siguiente ejemplo:\n\ntry:\n    # Intenta ejecutar este código\n    resultado = 10 / 0\nexcept ZeroDivisionError:\n    # Se ejecuta si hay una excepción ZeroDivisionError\n    print(\"¡Error! No se puede dividir por cero.\")\nelse:\n    # Se ejecuta si no hay ninguna excepción\n    print(\"La división fue exitosa.\")\nfinally:\n    # Siempre se ejecuta, haya o no haya una excepción\n    print(\"Este es el bloque finally, se ejecuta siempre al final.\")\n\ncomo 10/0 es un error del tipo 'ZeroDivisionError', el codifo aplicara la excepción y no se detendra,\npero como tenemos un finally se imprimira ese mensaje al final.\n      \n\"\"\")\n\n\ntry:\n    # Intenta ejecutar este código\n    resultado = 10 / 0\nexcept ZeroDivisionError:\n    # Se ejecuta si hay una excepción ZeroDivisionError\n    print(\"¡Error! No se puede dividir por cero.\")\nelse:\n    # Se ejecuta si no hay ninguna excepción\n    print(\"La división fue exitosa.\")\nfinally:\n    # Siempre se ejecuta, haya o no haya una excepción\n    print(\"Este es el bloque finally, se ejecuta siempre al final.\")\n\n\nprint(\"\")\n\n# Opcional\nprint(f\"Se realiza el ejercicio de DIFICULTAD EXTRA\")\nprint(\"\"\"La estructura utilizada es:\n\nlista_numeros = []\n\nfor i in range(10, 56):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        lista_numeros.append(i)\n    elif i == 55:\n        lista_numeros.append(i)\n\nLo que da como resultado la lista con los valores:\n\"\"\")\nlista_numeros = []\n\nfor i in range(10, 56):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        lista_numeros.append(i)\n    elif i == 55:\n        lista_numeros.append(i)\n\nprint(lista_numeros)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/DGJuancho.py",
    "content": "# Operadores Aritméticos\nprint(f\"Suma: 12 + 10 = {12+10}\")\nprint(f\"Resta: 12 - 10 = {12-10}\")\nprint(f\"Multiplicación: 12 * 2 = {12*2}\")\nprint(f\"División: 12 / 2 = {12/2}\")\nprint(f\"Módulo: 12 % 5 = {12%5}\")\nprint(f\"Potencia: 12 ** 2 = {12**2}\")\nprint(f\"Div-Enteros: 12 // 7 = {12//7}\")\n\n# Operadores relacionales\nprint(f\"Igualdad: 10 == 5 es {10 == 5}\")\nprint(f\"Desigualdad: 10 != 5 es {10 != 5}\")\nprint(f\"Mayor que: 10 > 5 es {10 > 5}\")\nprint(f\"Menor que: 10 < 5 es {10 < 5}\")\nprint(f\"Mayopr o igual: 10 >= 5 es {10 >= 5}\")\nprint(f\"Menor o igual: 10 >= 5 es {10 <= 5}\")\n\n# Operadores bit a bit\nprint(f\"AND: 5 & 3 = {5&3}\")\nprint(f\"OR: 5 | 3 = {5|3}\")\nprint(f\"XOR: 5 ^ 3 = {5^3}\")\nprint(f\"NOT: ~ 5 = {~5}\")\nprint(f\"Desplazamiento a la izquierda: 5 << 2 = {5<<2}\")\nprint(f\"Desplazamiento a la derecha: 5 >> 2 = {5>>2}\")\n\n# Operadores de asignación\nnumber = 5  # Asignación\nprint(number)\nnumber += 2  # suma y asignación\nprint(number)\nnumber -= 1  # Resta y asignación\nprint(number)\nnumber *= 3  # Multiplicación y asignación\nprint(number)\nnumber /= 2  # División y asignación\nprint(number)\nnumber %= 2  # Módulo y asignación\nprint(number)\nnumber **= 2  # Potenciación y asignación\nprint(number)\nnumber //= 3  # División entera y asignación\n\n# Operadores Lógicos\nprint(f\"AND &&: 5 + 4 == 9 and 5 - 4 == 1 es {5 + 4 == 9 and 5 - 4 == 1}\")\nprint(f\"OR ||: 5 + 4 == 9 or 5 - 4 == 1 es {5 + 4 == 9 or 5 - 4 == 1}\")\nprint(f\"NOT !: not 5 + 4 == 9 es {not 5 + 4 == 9}\")\n\n# operadores de pertenencia\nprint(f\"'u' in 'DGJuancho' = {'u' in 'DGJuancho'}\")\nprint(f\"'b' not in 'DGJuancho' = {'b' not in 'DGJuancho'}\")\n\n# Operadores de identidad\nmy_number = number\nprint(f\"number is my_number es {number is my_number}\")\nprint(f\"number is not my_number es {number is not my_number}\")\n\n# Estructuras de control\nx = 6\nif x == 5:\n    print(\"Es 5\")\nelif x == 6:\n    print(\"Es 6\")\nelif x == 7:\n    print(\"Es 7\")\nelse:\n    print(\"Es otro\")\n\n# Operador Ternario\nx = 5\nprint(\"Es 5\" if x == 5 else \"No es 5\")\n\n# Bucle for\nfor i in \"DGJuancho\":\n    print(i)\n\n# Usando range con for\nfor i in range(5, 0, -1):\n    print(i)\n\n# Bucle while\nx = 5\nwhile x > 0:\n    x -= 1\n    print(x)  # 4,3,2,1,0\nelse:  # No es común, pero se puede utilizar un else al final de un while\n    print(\"El bucle ha finalizado\")\n\n# Ejercicio extra\nfor i in range(10, 56, 2):\n    if i != 16 and i % 3 != 0:\n        print(i)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/DGrex.py",
    "content": "\"\"\"\nCrea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\nAritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n(Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n\"\"\"\n\n\n\"\"\"\nOperadores aritméticos:\n    - Suma: +\n    - Resta: -\n    - Multiplicación: *\n    - División: /\n    - División entera: //\n    - Módulo (resto de la división): %\n    - Exponente: **\n\"\"\"\nnum_one = 3\nnum_two = 2\n\nprint(\"Operadores aritméticos\")\nprint(f\"Suma: {num_one + num_two}\")\nprint(f\"Resta: {num_one - num_two}\")\nprint(f\"Multiplicación: {num_one * num_two}\")\nprint(f\"División: {num_one / num_two}\")\nprint(f\"División entera: {num_one // num_two}\")\nprint(f\"Módulo: {num_one % num_two}\")\nprint(f\"Exponente: {num_one ** num_two}\")\n\n\"\"\"\nOperadores de asignación:\n    Asignación: =\n    Suma y asignación: +=\n    Resta y asignación: -=\n    Multiplicación y asignación: *=\n    División y asignación: /=\n    División entera y asignación: //=\n    Módulo y asignación: %=\n    Exponente y asignación: **=\n\"\"\"\n\nprint(\"\\nOperadores de asignación\")\n\nasignacion = 5\nprint(f\"Asignación: {asignacion}\")\n\nasignacion += 3\nprint(f\"Suma y asignación: {asignacion}\")\n\nasignacion -= 3\nprint(f\"Resta y asignación: {asignacion}\")\n\nasignacion *= 3\nprint(f\"Multiplicación y asignación: {asignacion}\")\n\nasignacion /= 3\nprint(f\"División y asignación: {asignacion}\")\n\nasignacion //= 3\nprint(f\"División entera y asignación: {asignacion}\")\n\nasignacion %= 3\nprint(f\"Módulo y asignación: {asignacion}\")\n\nasignacion **= 3\nprint(f\"Exponente y asignación: {asignacion}\")\n\n\"\"\"\nOperadores de comparación:\n    Igual a: ==\n    No igual a: !=\n    Mayor que: >\n    Menor que: <\n    Mayor o igual que: >=\n    Menor o igual que: <=\n\"\"\"\n\nnum_one = 3\nnum_two = 2\nnumeber_tree = 2\n\nprint(\"\\nOperadores de comparación\")\n\nprint(\"\\nIgualdad\")\n# Igualdad\nprint(f\"¿ {num_one} es igual a {num_two} ? : {num_one == num_two}\")\nprint(f\"¿ {num_two} es igual a {numeber_tree} ? : {num_two == numeber_tree}\")\n\nprint(\"\\nDiferencia\")\n# Diferencia\nprint(f\"¿ {num_one} es diferente a {num_two} ? : {num_one != num_two}\")\nprint(f\"¿ {num_two} es diferente a {numeber_tree} ? : {num_two != numeber_tree}\")\n\nprint(\"\\nMayor que\")\n# Mayor que\nprint(f\"¿ {num_one} es mayor a {num_two} ? : {num_one > num_two}\")\nprint(f\"¿ {num_two} es mayor a {num_one} ? : {num_two > num_one}\")\nprint(f\"¿ {num_two} es mayor a {numeber_tree} ? : {num_two > numeber_tree}\")\n\nprint(\"\\nMenor que\")\n# Menor que\nprint(f\"¿ {num_two} es menor a {num_one} ? : {num_two < num_one}\")\nprint(f\"¿ {num_one} es menor a {num_two} ? : {num_one < num_two}\")\nprint(f\"¿ {num_two} es menor a {numeber_tree} ? : {num_two < numeber_tree}\")\n\nprint(\"\\nMayor o igual a\")\n# Mayor o igual a\nprint(f\"¿ {num_one} es mayor o igual a {num_two} ? : {num_one >= num_two}\")\nprint(f\"¿ {num_two} es mayor o igual a {numeber_tree} ? : {num_two >= numeber_tree}\")\nprint(f\"¿ {num_two} es mayor o igual a {num_one} ? : {num_two >= num_one}\")\n\nprint(\"\\nMenor o igual a\")\n# Menor o igual a\nprint(f\"¿ {num_two} es menor o igual a {num_one} ? : {num_two <= num_one}\")\nprint(f\"¿ {num_two} es menor o igual a {numeber_tree} ? : {num_two <= numeber_tree}\")\nprint(f\"¿ {num_one} es menor o igual a {num_two} ? : {num_one <= num_two}\")\n\n\n\"\"\"\nOperadores lógicos:\n    AND lógico: and\n    OR lógico: or\n    NOT lógico: not\n\"\"\"\n\nprint(\"Operadores lógicos\")\n\nprint(\"\\nOperador lógico AND \")\nprint(True and True)\nprint(True and False)\nprint(False and False)\n\nprint(\"\\nOperador lógico OR \")\nprint(True or True)\nprint(True or False)\nprint(False or False)\n\nprint(\"\\nOperador lógico NOT\")\nprint(not(False))\nprint(not(True))\n\n\"\"\"\nOperadores de identidad:\n    is: devuelve True si ambas variables son el mismo objeto\n    is not: devuelve True si ambas variables no son el mismo objeto\n\"\"\"\n\nprint(\"\\nOperadores de identidad\")\n\n# is\nprint(\"\\nOperadores de identidad is\")\nprint(f\"{True} is {True}: {True is True}\")\nprint(f\"{True} is {False}: {True is False}\")\nprint(f\"{False} is {False}: {False is False}\")\n\n# is not\nprint(\"\\nOperadores de identidad is not\")\nprint(f\"{True} is not {False}: {True is not False}\")\nprint(f\"{True} is not {True}: {True is not True}\")\nprint(f\"{False} is not {False}: {False is not False}\")\n\n\"\"\"\nOperadores de Pertenencia\n    in: Devuelve True si el valor está presente en la secuencia\n    not in: Devuelve True si el valor no está presente en la secuencia.\n\"\"\"\ncadena = \"Soy DGrex\"\n\n# in\nprint(\"\\nOperadores de Pertenencia in\")\nprint(\"DGrex\" in cadena)\nprint(\"dgrex\" in cadena)\n\n# not in\nprint(\"\\nOperadores de Pertenencia not in\")\n\nprint(\"DGrex\" not in cadena)\nprint(\"dgrex\" not in cadena)\n\n\n\"\"\"\nOperadores Bit a Bit\n-Se utilizan para realizar operaciones a nivel de bits.\n    & (AND bit a bit): Realiza una operación AND a nivel de bits.\n    | (OR bit a bit): Realiza una operación OR a nivel de bits.\n    ^ (XOR bit a bit): Realiza una operación XOR a nivel de bits.\n    ~ (NOT bit a bit): Invierte todos los bits del operando\n    << (Desplazamiento a la izquierda): Desplaza los bits del operando a la izquierda\n    >> (Desplazamiento a la derecha): Desplaza los bits del operando a la derecha.\n\"\"\"\n\nprint(\"\\nOperadores Bit a Bit\")\n\nnum_one = 5\nnum_two = 3\n\n\n#  & (AND bit a bit)\nprint(\"\\nOperadores Bit a Bit & (AND bit a bit)\")\nprint(num_one & num_two)\n\n# | (OR bit a bit)\nprint(\"\\nOperadores Bit a Bit | (OR bit a bit)\")\nprint(num_one | num_two)\n\n# ^ (XOR bit a bit)\nprint(\"\\nOperadores Bit a Bit ^ (XOR bit a bit)\")\nprint(num_one ^ num_two)\n\n# ~ (NOT bit a bit)\nprint(\"\\nOperadores Bit a Bit~ (NOT bit a bit)\")\nprint(~num_two)\n\n#  << (Desplazamiento a la izquierda)\nprint(\"\\nOperadores Bit a Bit << (Desplazamiento a la izquierda)\")\nnumero = 5  # 0101 en binario\nprint(numero << 1)  # 1010 en binario, que es 10 en decimal\nprint(numero << 2)  # 10100 en binario, que es 20 en decimal\n\n#  >> (Desplazamiento a la derecha)\nprint(\"\\nOperadores Bit a Bit >> (Desplazamiento a la derecha)\")\nnumero = 5  # 0101 en binario\nprint(numero >> 1)  # 0010 en binario, que es 2 en decimal\nprint(numero >> 2)  # 0001 en binario, que es 1 en decimal\n\n\n\"\"\"\nUtilizando las operaciones con operadores que tú quieras, crea ejemplos\nque representen todos los tipos de estructuras de control que existan\nen tu lenguaje:\nCondicionales, iterativas, excepciones...\n\"\"\"\n\n# Condicionales\n\n#Sentencia if \n\nprint(\"\\nSentencia if \")\nif 3 > 2:\n    print(\"3 es mayor que 2\")\n\n#Sentencia if-else \nprint(\"\\nSentencia if-else \")\nif 2 > 3:\n    print(\"2 es mayor a 3\")\nelse:\n    print(\"3 es mayor que 2\")\n\n#Sentencia if-elif-else \nprint(\"\\nSentencia if-elif-else \")\nif 2 > 2:\n    print(\"2 es mayor a 3\")\nelif 2 == 2:\n    print(\"Ambos numero son iguales\")\nelse:\n    print(\"3 es mayor que 2\")\n\n\n# Iteractivas\n\n# while\nprint(\"\\nIteractiva While\")\ni = 0 \nwhile i <= 11:\n    i += 1\n    print(f\"{2} X {i}: {i * 2}\")\n\n\nprint(\"\\nIteractiva for\")\n# for\nlista = [\"Denis\", \"Javier\", \"Goyes\", \"Moran\"]\nfor elemento in lista:\n    print(elemento)\n\n\n# Excepciones\n\nnum_one = 5\nnum_two = \"3\"\n\n# try-except\n\nprint(\"\\nExcepciones\")\ntry:\n    print(num_one + num_two)\n    print(\"No se a producido el error\")\nexcept TypeError as error: # as es reservada y error es una variable\n    print(f\"{error}\")\n\n\n\"\"\"\nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\"\"\"\n\nprint(\"\\nEjercicio\")\n\nfor num in range(10,55):\n\n    if num % 2 == 0:\n        if num != 16 and num % 3 != 0:\n            print(num) \n\nprint(\"\\nEjercicio\")\n\nnum = 10\n\nwhile num <= 55:\n    if num % 2 == 0 and num != 16 and num % 3 != 0:\n        print(num)\n    num += 1\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/DLGAI12.py",
    "content": "\"\"\"/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\"\"\"\nnum1 = 14\nnum2 = 5\n\"\"\" Operadores Aritmeticos \"\"\"\n\nprint(\"Operadores Aritmeticos\")\nprint(\"Suma:num1+num2 =\",num1+num2)\nprint(\"Resta:num1-num2 =\",num1-num2)\nprint(\"Multiplicación:num1*num2 =\",num1*num2)\nprint(\"División:num1/num2 =\",num1/num2)\nprint(\"Modulo:num1%num2 =\",num1%num2)\nprint(\"Potencia:num1+num2 =\",num1**num2)\nprint(\"Divición Entera :num1//num2 =\",num1//num2)\n\n\"\"\" Operadores Relacionales \"\"\"\n\nprint(\"Operadores Relacionales\")\n#Mayor Que >\nprint(str(num1)+\">\"+str(num2)+\":\"+str(num1>num2)) # Devuelve True si el  primer operando es mayor que el segundo si no false\n\n#Menor Que <\nprint(str(num1)+\"<\"+str(num2)+\":\"+str(num1<num2)) # Devuelve True si el  primer operando es menor que el segundo si no false\n\n#Igual que ==\nprint(str(num1)+\"==\"+str(num2)+\":\"+str(num1==num2)) # Devuelve True si el  primer operando es igual que el segundo si no false\n\n#Mayor o Igual Que >=\nprint(str(num1)+\">=\"+str(num2)+\":\"+str(num1>=num2)) # Devuelve True si el  primer operando es mayor o igual  que el segundo si no false\n\n#Menor o Igual Que <=\nprint(str(num1)+\"<=\"+str(num2)+\":\"+str(num1<=num2)) # Devuelve True si el  primer operando es menor o igual  que el segundo si no false\n\n#Distinto  Que !=\nprint(str(num1)+\"!=\"+str(num2)+\":\"+str(num1!=num2)) # Devuelve True si el  primer operando es distinto que el segundo si no false\n\n\"\"\" \n    Operadores de Asignación\n\"\"\"\nprint(\"Operadores de Asignación\")\n#=\ni=5\nprint(i)\n\n#+=5\ni+=5\nprint(i)\n\n#-=5\ni-=5\nprint(i)\n\n#*=5\ni*=5\nprint(i)\n\n#/=5\ni/=5\nprint(i)\n\n#%=5\ni=9\ni%=5\nprint(i)\n\n#**=5\ni**=5\nprint(i)\n\n#//=5\ni//=5\nprint(i)\n\na = 7  # Binario: 111\nb = 9  # Binario: 1001\n\na &= b\nprint(\"a &= b =\", a)\n\na |= b\nprint(\"a |= b =\", a  )\n\na ^= b\nprint(\"a ^= b =\", a ) \n\na>>=b\nprint(\"a >>= b =\", a) \n\na<<=b\nprint(\"a << = b =\", a)  \n\n\"\"\"\n    Operadores Lógicos\n\"\"\"\n\nprint(\"Operadores Lógicos\")\na=True \nb=False\n\nprint(a and b) # Devuelve true si a y b son verdaderos si no devuelve false\nprint(a or b) # Devuelve true si a o b son verdaderos si no devuelve false\nprint(not a) # Devuelve lo conntrario a lo que recibe si recibe true devuelve false y si recibe false devuelve true\n\n\"\"\"\n    Operadores de Pertenencia\n\"\"\"\nprint(\"Operadores de Pertenencia\")\na = [1,2,3,4,5]\n  \n#Esta 3 en la lista a?\nprint(3 in a) # Muestra True \n  \n#No está 12 en la lista a?\nprint(12 not in a) # Muestra True\n\n\"\"\"\n    Operadores de Identidad\n\"\"\"\nprint(\"Operadores de Identidad\")\na = 3\nb = 3  \nc = 4\nprint ( a is b) # muestra True\nprint (a is not b) # muestra False\nprint (a is not c) # muestra True\n\nx = 1\ny = x\nz = y\nprint (z is 1) # muestra True\nprint (z is x )# muestra True\n\nstr1 = \"Hola\"\nstr2 = \"Hola\"\n\nprint (str1 is str2 )# muestra True\nprint (\"Codigo\" is str2 )# muestra False\n\na = [10,20,30]\nb = [10,20,30]\n\nprint (a is b) # muestra False (ya que las listas son objetos mutables en Python)  \n\n\n\"\"\" Estructuras de control\"\"\"\nprint(\"Estructuras de control\")\n#condicionales\na=5\n\n\nif(a>0):\n    print(\"A es positivo\")\nelif(a<0):\n    print(\"B es negativo\")\nelse:\n    print(\"A es cero\")\n    \n    \nprint (\"for\")\nfor i in range(5):\n    print(i)\n\nx=5\nprint (\"while\")\nwhile x > 0:\n    print (x)\n    x-=1\n\n\"\"\"Control de flujo dentro de bucles\"\"\"\nprint(\"Control de flujo dentro de bucles\")\n# Ejemplo de break\nfor i in range(10):\n    if i == 5:\n        break\n    print(i)\n\nprint(\"Continue\")\n# Ejemplo de continue\nfor i in range(10):\n    if i == 5:\n        continue\n    print(i)\n\n\n#Manejo de excepciones\nprint(\"Excepecion\")\ntry:\n    x = 1 / 0 \nexcept ZeroDivisionError:\n    print(\"No se puede dividir por cero!\")\nfinally:\n    print(\"Este código se ejecuta sin importar si hubo un error o no\")\n   \nprint(\"Extra\")\nfor i in range(10,56):\n    if (i == 16 or i%2==0 or i%3==0):\n        continue\n    print(i)\n\nnumeros = [i for i in range(10, 56) if i != 16 and i % 2 != 0 and i % 3 != 0]\nfor numero in numeros:\n    print(numero)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/DaniQB99.py",
    "content": "\n#  * EJERCICIO:\n#  * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n#  *   Aritméticos, logicos, de comparacion, asignacion, identidad, pertenencia, bits...\n#  *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n\n# Aritméticos\nprint(f'Suma: {2 + 2}')\nprint(f'Resta: {2 - 2}')\nprint(f'Multiplicacion: {2 * 2}')\nprint(f'Division: {3 / 2}')\nprint(f'Division entera: {3 // 2}')\nprint(f'Resto de la division: {2 % 2}')\nprint(f'Potencia: {2 ** 2}')\n\n# logicos  \nprint(f'AND &&: 10 + 4 == 14 and 4 - 1 == 3 es {True and True}')\nprint(f'OR ||: 10 + 4 == 14 or 4 - 1 == 3 es {True or True}')\nprint(f'NOT !: 10 + 4 == 14 no es {not True}')\n\n# Comparacion\nprint(f'Igual: {2 == 2}')\nprint(f'Diferente: {5 != 5}')\nprint(f'Mayor: {10 > 3}')\nprint(f'Menor: {2 < 7}')\nprint(f'Mayor o igual: {3 >= 2}')\nprint(f'Menor o igual: {1 <= 6}')\n\n# Asignacion\nmy_number = 5\nprint(f'Asignacion: {my_number}')\nmy_number += 5\nprint(f'Suma y asignacion: {my_number}')\nmy_number *= 5\nprint(f'Multiplicacion y asignacion: {my_number}')\nmy_number **= 5\nprint(f'Potencia y asignacion: {my_number}')\nmy_number -= 5\nprint(f'Resta y asignacion: {my_number}')\nmy_number /= 5\nprint(f'Division y asignacion: {my_number}')\nmy_number //= 5\nprint(f'Division entera y asignacion: {my_number}')\nmy_number %= 5\nprint(f'Resto de la division y asignacion: {my_number}')\n\n\n# Identidad\nmy_string = 'test'\nmy_new_string = my_string\nprint(f'my_string is my_new_string es: {my_string is my_new_string}')\nprint(f'my_string is not my_new_string es: {my_string is not my_new_string}')\n\n\n# Pertenencia \nprint(f\"'t' in 'test' = {'t' in 'test'}\")\nprint(f\"'h' not in 'test' = {'h' not in 'test'}\")\n\n# Bits\na = 10\nb = 2\nprint(f'AND: 10 & 2 = {a & b}') \nprint(f'OR: 10 | 2 = {a | b}') \nprint(f'XOR: 10 ^ 2 = {a ^ b}')\nprint(f'NOT: ~10 = {~a}')\n\nprint(f'Desplazamiento a la derecha: 8 >> 2 = {8 >> 2}')\nprint(f'Desplazamiento a la izquierda: 8 << 2 = {8 << 2}')\n\n\n# ESTRUCTURAS DE CONTROL\n\n# Condicionales\nif my_string == 'DaniQB99':\n    print('Hola, soy DaniQB99')\nelif my_string == 'Dani':\n    print('Hola, soy Dani')\nelse:\n    print('Hola, soy otro usuario')\n\n# Iterativas\nfor i in range(10): # Iteramos 10 veces\n    print(i)\n\n# While\ni = 0\nwhile i < 10: # Mientras i sea menor que 10\n    print(i)\n    i += 1\n\n# Manejo de excepciones\ntry:\n    print(12 / 0)\nexcept ZeroDivisionError:\n    print('No se puede dividir por cero')\nfinally:\n    print('Finalizado, el manejo de excepciones')\n\n\"\"\" \nCrea un programa que imprima por consola todos los números comprendidos entre 10 y 55 (incluidos), pares, y\nque no son ni el 16 ni múltiplos de 3.\n\"\"\"\nprint('\\n--- EJERCICIO EXTRA ---')\nfor num in range(10, 55):\n    if num % 2 == 0 and num != 16 and num % 3 != 0:\n        print(num)\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/DaniRojasDev.py",
    "content": "a = 10\nb = 3\n\n'''\nOperadores aritméticos\n'''\nprint (f\"10 + 4 = {a + b}\") #suma\nprint (f\"10 - 4 = {a - b}\")#resta\nprint (f\"10 x 4 = {a * b}\") #multiplicación\nprint (f\"10 / 4 = {a / b}\") #división\nprint (f\"10 % 4 = {a % b}\")#módulo (muestra el resto de una división)\nprint (f\"10 ** 4 = {a ** b}\") #exponente (número de la izquierda elevado al número de la derecha)\nprint (f\"10 // 4 = {a // b}\") #cociente (muestra el cociente de la división)\n\n'''\nOperadores de comparación\n'''\nprint (f\"10 = 3 is {a==b}\") # Igualdad\nprint (f\"10 is diferent than 3 is {a!=b}\") # Desigualdad\nprint (f\"10 is greater than 3 is {a>b}\") # Mayor que\nprint (f\"10 is less than 3 is {a<b}\") # Menor que\nprint (f\"10 is greater or equal than 3 is {a>=b}\") # Mayor o igual que\nprint (f\"3 is less or equal than 10 is {b<=a}\") # Menor o igual que\n\n'''\nOperadores lógicos\n'''\n# operador \"and\"\nprint (f\"10+3 = 13 y 10-3 = 7 is {a+b==13 and a-b==7}\") # Si ambas operaciones son verdad es true, si no false\nprint (f\"10+3 = 13 y 10-3 = 7 is {a+b==12 and a-b==7}\") # Si ambas operaciones son verdad es true, si no false\n\n# operador \"or\"\nprint (f\"10+3 = 13 y 10-3 = 7 is {a+b==13 or a-b==7}\") # Si una de las operaciones es verdad es true, si no false\nprint (f\"10+3 = 13 y 10-3 = 7 is {a+b==12 or a-b==7}\") # Si una de las operaciones es verdad es true, si no false\nprint (f\"10+3 = 13 y 10-3 = 7 is {a+b==12 or a-b==7}\") # Si una de las operaciones es verdad es true, si no false\n\n# operador \"not\"\nprint (f\"10+3 = 13 is not {not a+b == 13 }\") # Si una de las operaciones es verdad es false, si no true (invierte true por false)\n\n'''\nOperadores de asignación\n'''\n\n# Asigna un valor a la constante y le realiza la operación\n\nnumber = 7 # Asignación\nprint (number)\n\nnumber += 2 # Suma el valor y asigna\nprint (number)\n\nnumber -= 2 # Resta el valor y asigna\nprint (number)\n\nnumber *= 2 # Multiplica el valor y asigna\nprint (number)\n\nnumber /= 2 # Divide el valor y asigna\nprint (number)\n\nnumber %= 2 # Modula el valor y asigna\nprint (number)\n\nnumber //= 2 # Saca el cociente de la división y asigna\nprint (number)\n\nnumber **= 2 # Eleva el valor por el número que se le da y asigna\nprint (number)\n\n'''\nOperadores de identidad\n'''\n\nprint (f\"the number a is the number b {a is b}\") # Dice si ambos valores son el mismo\nprint (f\"the number a is the number b {a is not b}\") # Dice si ambos valores no son el mismo\n\n'''\nOperadores de identidad\n'''\nprint (f\"Hello is in Hello, Python!! {'Hello' in 'Hello, Python!!'}\") # Sale true si Hello esta dentro de Hello, Python!!\nprint (f\"Hola isn´t Hello, Python!! {'Hola' not in 'Hello, Python!!'}\") # Sale true si hola  no esta dentro de Hello, Python!!\n\n'''\nOperadores de bit\n'''\n# Sirven para trabajar con números en binario \nprint (f\"The number 10 in binary is {bin (10)}\")\nprint (f\"The number 3 in binary is {bin (3)}\")\n\nprint (f\"AND: 10 & 3 = {10 & 3}\")\nprint (f\"OR: 10 | 3 = {10 | 3}\")\nprint(f\"XOR: 10 ^ 3 = {10 ^ 3}\")  \nprint(f\"NOT: ~10 = {~10}\")\nprint(f\"Desplazamiento a la derecha: 10 >> 2 = {10 >> 2}\")  \nprint(f\"Desplazamiento a la izquierda: 10 << 2 = {10 << 2}\")\n\n'''\nEstructuras de control condicionales\n'''\n# Si se cumple la condición imprime una cosa en cosa en caso contrario imprime otra\n\nstring = \"Hola\"\n\nif string == \"Hello\":\n    print (\"string is Hello\")\nelse:\n    print (\"string ins´t Hello\")\n\n# si se cumple la primera condición imprime una cosa, si no, comprueba la segunda condición y si se cumple imprime otra, si no se cumple ninguna de las 2 imprime otra\n\nif string == \"Hello\":\n    print (\"string is Hello\")\nelif string == \"Hola\":\n    print (\"string is Hola\")\nelse:\n    print (\"string ins´t Hello\")\n\n'''\nEstructuras de control iterativas\n'''\n# Coge los números de un rango que le indiquemos desde el 0 hasta un número menos del indicado\n\nfor c in range (11):\n    print (c)\n\n# Ejecuta el codigo repetidas veces hasta que se cumple la condición que le indiquemos en este caso mientras sea mayor de 0\n\nwhile c >0:\n    c -=1\n    print (c)\n\n'''\nEstructuras de control de excepciones\n'''\n# Intenta realizar la operación si se puede la realiza y si no se puede, en lugar de dar error el programa, nos sale el mensaje que le indiquemos y el programa sigue corriendo\ntry:\n    print(10 / 0)\nexcept:\n    print(\"Se ha producido un error\")\n\n'''\nExtra\n'''\nprint (\"Esta es la parte extra del ejercicio\")\n\nfor d in range (10, 56):\n    if d % 2 == 0 and d !=16 and d % 3 != 0:\n        print (d)\n\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Daniel-sanabria0419.py",
    "content": "##creacion de ejemplos con operadores de python\nseparador = \"--------------------------------------------------------------\"\n'''\nOPERADORES ARITMETICOS \nson para operaciones matematicas basicas [suma, resta, multiplcacion, division, division entera,\nmodulo y exponeciacion]\n'''\nprint(\"OPERADORES ARITMETICOS\",separador)\nprint(\"SUMA 3+5 = \",3+5)\nprint(\"RESTA 3-5 = \",3-5)\nprint(\"MULTIPLCACION 3*5 = \",3*5)\nprint(\"DIVISION 3/5 = \",3/5)\nprint(\"DIVISION ENETERA 3//5 = \",3//5)\nprint(\"MODULO 10%5 = \",10%3)\nprint(\"EXPONENCIACION 3**5 = \",3**5)\n\n\n'''\nOPERADORES DE COMPARACION \nse usan para comparar valores y devuleven un valor de tipo bool (true or false) [igual, distinto que,\nmayor que, menor que, mayor o igual que, menor o igual que]\n'''\n\nprint(\"OPERADORES COMPARACION\",separador)\nprint(\"4 es = 2\",4 == 2) #igual\nprint(\"4 !=(no igual) 2\",4 != 2) #distinto \nprint(\"4 es > 2 = \",4 > 2 ) #mayor que  \nprint(\"4 es < 2 = \",4 < 2 ) #menor que\nprint(\"3 es >= 3 = \",4 >= 2 )# mayor o igual que\nprint(\"4 es <= 2 = \",4 <= 2 ) #menor o igual que\n'''\nOPERADORES DE ASIGNACION \nse usan para asignar valores a variables y muchos de estos se combinan con operadores\naritmeticos \n'''\nx = 56\nprint(\"OPERADORES ASIGNACION\",separador)\nprint(\"[igual =]x es igual que\", x )\nx += 2 \nprint(\"[mas igual +=] x+=2 es igual a\",x)\nx *= 2\nprint(\"[por igual *=] x *=3 igual a\", x )\nx /= 3\nprint(\"[dividido igual /=] x /=2  igual a\", x )\nx //= 3\nprint(\"[divido entero igual *=]x //=2  igual a\", x )\n\n'''\nOPERADORES LOGICOS\nse usan para combinar expresiones boleanas o para compararlas y esta arroja resultado\nde dato booleano [and, or, not]\n'''\nprint(\"OPERADORES LOGICOS\",separador)\n\nprint(\"false and true =\" , False and True) #los dos deben ser TRUE para que arroje TRUE\nprint(\"false and true =\" , False or True) #Cualquiera debe ser TRUE para que arroje TRUE\nprint(\"not false =\" ,  not False) #devolvera lo opuesto a lo que se esta negando\n\n'''\nOPERADORES DE PERTENENCIA\nse usa para verificar si un elemento se encuentra en una secuencia devuelve booleano[in, not in]\n'''\nprint(\"OPERADORES DE PERTENENCIA\",separador)\n\nmy_list = [1,2,3,4,5,\"adios\"]\nprint(\"esta es la lista 'my_list'\", my_list)\nprint(\"4 se encuentra dentro de my_list\", 4 in my_list)\nprint(\"hola no se encuentra dentro de my_list\", \"hola\" not in my_list)\n\n'''\nOPERADORES DE IDENTIDAD\nse usa para saber si dos variables apuntan al mismo objeto en memoria arroja un booleano\n [is, is not]\n'''\nprint(\"OPERADORES DE IDENTIDAD\",separador)\n\nmy_object = {\"uno\" : 1, \"dos\" : 2 , \"tres\" : 3}\nprint(\"my_object es mi diccionario de numeros\", my_object)\n\ncopy_object = my_object\nprint(\"copy_object es una copia de mi diccionario de numero\", copy_object)\nprint(\"es decir que esas dos variables ocupan el mismo espacio en memorio\",copy_object is my_object)\n\nmy_book = (1,2,3,4)\nprint(\"my_book es mi libro que tiene su propio espacion en memoria\", my_book)\nyour_book = (1,2,3,4)\nprint(\"your_book es tu libro que tiene su priopio espcio en memoria\", your_book)\nprint(\"asi que your_book is not my_book\", your_book is not my_book)\n\n'''\nESTRUCTURAS DE CONTROL CONDICIONALES \npermiten ejecutar ciertas lineas de codigo si la condicion se cumplo o no [if, elif, else]\n\n'''\nedad = 18\n\nif edad >= 18:\n    print(\"eres mayor de edad\")\nelif edad == 17:\n    print(\"te falta un año para ser mayor de edad\")\nelse :\n    print(\"eres menor de edad\")\n    \n#los condicionales tiene un tipo de extructura de control de una sola linea que se llama \n#exprecion ternaria\nmensaje = \"eres mayor de edad \" if edad >= 18 else \"eres menor de edad\" #condcion en una sola linea\nprint(mensaje)\n'''\nESTRUCTURAS DE CONTROL BUCLES [while, for]\n\nwhile se utiliza para repetir un bloque de codigo mientras la condicion se cumpla\n\nfor se utiliza para repetir un bloque de codigo sobre secuencias o entre un rango de iteraciones\n\n'''\n#while\ncontador = 1\nwhile contador <= 2048:\n    print(contador)\n    contador += contador\n\n#for\n\nfor i in range(1,18,1):\n    print(i)\n    i += i\n\n#hay formas de controlar el control de flujo dentro de estas estructuras de control las cuales pueden ser\n#[break, continue, else, ]estas se utilizan en bucles y hay un manejo de excepciones \n# tambien que se pueden utilizar en condiciones[try, except, finally]\n\n#try, except y finally\n\nfor x in range(10,-1,-1):\n    try:\n        resultado = 10/x\n        print(resultado)\n    except:\n        print(\"la divion por 0 no es posible\")\n    finally:\n        print(\"el tryCatch finalizo\")\n\n\n#continue, else y brake\n\n#tenemos una lista de numero y el for debe encontrar si tiene un numero primo y que \n# sea menor que 10 si no lo tiene debera imprimir que no hay numero primo\n\nlista = [1,2,3,4,5,6,7,8,9]\nfor numero in lista:\n    if numero < 10:\n        continue\n    prueba = numero%5\n    if prueba == 0:\n        print(\"el numero es= \", numero)\n        break\nelse:\n    print(\"no hay ningun numero mayor a 10 en esta lista que sea divisible por 5\")\n\n\n\nfor j in range(10, 56, 2):\n    modulo = j%3\n    if j == 16 or modulo == 0:\n        continue\n    print(j)\n    \n\n\n\n    \n        \n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Danilo0203.py",
    "content": "# OPERADORES\n\n# 📌 OPERADORES ARITMETICOS\nprint(\"\\n======== OPERADORES ARITMETICOS ========\")\nprint(f\"Suma: 2+2 = {2+2}\")\nprint(f\"Resta: 4-2 = {4-2}\")\nprint(f\"Multiplicacion: 2*2 = {2*2}\")\nprint(f\"Division 10/3:  = {10/3}\")\nprint(f\"Division Entera 10//3:  = {10//3}\")\nprint(f\"Resto : 2%2 = {2%2}\")\nprint(f\"Exponente : 2**2 = {2**2}\")\n\n# 📌 OPERADORES DE COMPARACIÓN\nprint(\"\\n======== OPERADORES DE COMPARACIÓN ========\")\nprint(f\"Igualdad: 10 == 3 {10 == 3}\")\nprint(f\"Desigualdad: 10 != 3 {10 != 3}\")\nprint(f\"Mayor que: 10 > 3 {10 > 3}\")\nprint(f\"Menor que: 10 < 3 {10 < 3}\")\nprint(f\"Mayor o igual que: 10 >= 3 {10 >= 3}\")\nprint(f\"Menor o igual que: 10 <= 3 {10 <= 3}\")\n\n# 📌 OPERADORES LOGICOS\nprint(\"\\n======== OPERADORES LOGICOS ========\")\nprint(f\"AND: 10 + 3 == 13 and 5 - 1 == 4 es: {10 + 3 == 13 and 5 - 1 == 4}\")\nprint(f\"OR: 10 + 4 == 13 or 5 - 1 == 4 es: {10 + 4 == 13 or 5 - 1 == 4}\")\nprint(f\"NOT: not 10 + 3 == 14 es: {not 10 + 3 == 14}\")\n\n# 📌 OPERADORES DE ASIGNACION\nprint(\"\\n======== OPERADORES DE ASIGNACIÓN ========\")\nmy_number = 11\nprint(f\"Asignacion (=): my_number = 11, R//{my_number}\")\nmy_number += 1\nprint(f\"Suma y asignacion (+=): my_number += 1, R//{my_number}\")\nmy_number *= 2\nprint(f\"Multiplicacion y asignacion (*=): my_number *= 2, R//{my_number}\")\nmy_number -= 2\nprint(f\"Restar y asignacion (-=): my_number -= 2, R//{my_number}\")\nmy_number /= 11\nprint(f\"Division y asignacion (/=): my_number /= 11, R//{my_number}\")\nmy_number %= 2\nprint(f\"Modulo y asignacion (%=): my_number %= 2, R//{my_number}\")\nmy_number = 2\nmy_number **= 2\nprint(f\"Exponente y asignacion (**=): my_number **= 2, R//{my_number}\")\nmy_number //= 2\nprint(f\"Division Entera y asignacion (//=): my_number //= 2, R//{my_number}\")\n\n# 📌 OPERADORES DE IDENTIDAD\nprint(\"\\n======== OPERADORES DE IDENTIDAD ========\")\nmy_new_number = 1.0\nprint(\n    f\"OPERADOR DE IDENTIDAD (is) my_number is my_new_number es {my_number is my_new_number}\"\n)\nmy_new_number = my_number\nprint(\n    f\"OPERADOR DE IDENTIDAD (is) my_number is my_new_number es {my_number is my_new_number}\"\n)\nprint(\n    f\"OPERADOR DE NO IDENTIDAD (is not) my_number is my_new_number es {my_number is not my_new_number}\"\n)\n\n# 📌 OPERADORES DE PERTENENCIA\nprint(\"\\n======== OPERADORES DE PERTENCIA ========\")\nprint(f\"OPERADOR (in) 'i' in 'Danilo => {'i' in 'Danilo'}'\")\nprint(f\"OPERADOR (not in) 'i' not in 'Danilo => {'i' not in 'Danilo'}'\")\n\n# 📌 OPERADORES DE BIT\nprint(\"\\n======== OPERADORES DE BIT ========\")\na = 10  # 1010\nb = 3  # 0011\nprint(f\"AND: 10 & 3 = {10 & 3}\")  # 0010\nprint(f\"OR: 10 | 3 = {10 | 3}\")  # 1011\nprint(f\"XOR: 10 ^ 3 = {10 ^ 3}\")  # 1001\nprint(f\"NOT: ~10 = {~10}\")  # -11\n\nprint(\"\\n======== OPERADORES DE DESPLAZAMIENTO ========\")\nprint(f\"Desplazamiento a la derecha 10>>2 = {10 >> 2}\")  # 0010\nprint(f\"Desplazamiento a la izquierda 10<<2 = {10 << 2}\")  # 101000\n\n# ESTRUCTURAS DE CONTROL\nprint(\"\\n======== ESTRUCTURAS DE CONTROL ========\")\n\n# 📌 CONDICIONALES\nprint(\"\\n======== CONDICIONALES ========\")\n\nprint(\"\\n======== IF ELSE ========\")\nmy_name = \"Hola\"\n\nif my_name == \"Danilo\":\n    print('my_name es : \"Danilo\"')\nelif my_name == \"Calderon\":\n    print('my_name es: \"Calderon\"')\nelse:\n    print(\"my_name no es 'Danilo' ni 'Calderon'\")\n\nprint(\"\\n======== ITERATIVAS ========\")\nprint(\"\\n======== FOR IN ========\")\nfor i in range(11):\n    print(i)\n\nprint(\"\\n======== WHILE ========\")\ni = 0\nwhile i <= 10:\n    print(i)\n    i += 1\n\nprint(\"\\n======== MANEJO DE EXCEPCIONES ========\")\nprint(\"\\n======== TRY CATCH FINALLY ========\")\ntry:\n    print(10 / 1)\nexcept:\n    print(\"Se a producido un error\")\nfinally:\n    print(\"Ha finalizado el manejo de excepciones\")\n\n\"\"\" DIFICULTAD EXTRA (opcional):\n Crea un programa que imprima por consola todos los números comprendidos\n entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3. \"\"\"\nprint(\"\\n======== DIFICULTAD EXTRA ========\")\nprint(\"\\n======== MI SOLUCION ========\")\ncount = 10\nwhile count <= 55:\n    if count % 2 == 0 and count != 16 and count % 3 != 0:\n        print(count)\n    count += 1\n\nprint(\"\\n======== MOUREDEV ========\")\nfor number in range(10, 56):\n    if number % 2 == 0 and number != 16 and number % 3 != 0:\n        print(number)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Dans182.py",
    "content": "\"\"\"\n* EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\"\"\"\n\n# Operadores\n\n## Operadores aritméticos\n\nsuma = 2 + 2\nprint(\"Suma: 2 + 2 =\", suma)\n\nresta = 2 - 2\nprint(\"Resta: 2 - 2 =\", resta)\n\nmultiplicación = 2 * 2\nprint(\"Multiplicación: 2 * 2 =\", multiplicación)\n\ndivision = 2 / 2\nprint(\"Division: 2 / 2 =\", division)\n\nmodulo = 10 % 3 #El resto de la división\nprint(\"Módulo: 10 % 3 =\", modulo)\n\npotencia = 10 ** 3\nprint(\"Exponente: 10 ** 3 =\", potencia)\n\ndivision_entera = 10 // 3 #El resultado nos tiene que dar un n1 redondeado, entero. Evita la parte decimal.\nprint(\"Division Entera: 10 / 3 =\", division_entera)\n\n## Operadores de comparación\n\nprint(f\"Operador de igualdad: 10 == 3: {10 == 3}\")\nprint(f\"Operador de desigualdad: 10 != 3: {10 != 3}\")\nprint(f\"Mayor que: 10 > 3: {10 > 3}\")\nprint(f\"Menor que: 10 < 3: {10 < 3}\")\nprint(f\"Mayor o igual que: 10 >= 3: {10 >= 3}\")\nprint(f\"Menor o igual que : 10 <= 3: {10 <= 3}\")\n\n## Operadores lógicos\n\nprint(f\"And &&: 10 > 3 and 8 < 19: {10 > 3 and 8 < 19}\")\nprint(f\"Or ||: 10 > 3 and 8 > 19: {10 > 3 or 8 > 19}\")\nprint(f\"NOT !: 10 + 3 = 14: {not 10 + 3 == 14}\")\n\n## Operadores de asignación\n\nmy_number = 18 #asignacion\nprint(my_number)\n\nmy_number += 1 #suma y asignacion\nprint(my_number)\n\nmy_number -= 1 #resta y asignacion\nprint(my_number)\n\nmy_number *= 1 #multiplicacion y asignacion\nprint(my_number)\n\nmy_number /= 1 #division y asignacion\nprint(my_number)\n\nmy_number %= 1 #modulo y asignacion\nprint(my_number)\n\nmy_number **= 1 #exponente y asignacion\nprint(my_number)\n\nmy_number //= 1 #division entera y asignacion\nprint(my_number)\n\nmy_number_three = 3\nprint(my_number_three)\n\nmy_number_three &= 1 # y asignacion\nprint(my_number_three)\n\nmy_number_three |= 1 # y asignacion\nprint(my_number_three)\n\nmy_number_three ^= 1 # y asignacion\nprint(my_number_three)\n\nmy_number_three >>= 1 # y asignacion\nprint(my_number_three)\n\nmy_number_three <<= 1 # y asignacion\nprint(my_number_three)\n\n## Operadores de identidad\n\n#Los valores de identidad lo que buscan es comparar es el valor en memoria.\n#Por eso dando el mismo valor, da false. Porque tienen direcciones en la memoria distintas\nmy_new_number = 0.0\nprint(my_number)\nprint(f\"my_number is my_new_number es {my_number is my_new_number}\")\nprint(f\"my_new_number is my_new_number es {my_new_number is my_new_number}\")\n\n## Operadores de pertenencia\n\nprint(f\" 'd' in 'dans182' = {'d' in 'dans182'}\")\nprint(f\" 'd' not in 'dans182' = {'d' not in 'dans182'}\")\n\n## Operadores bit a bit\n#8421\na = 10 #1010\nb = 3  #0011\n\nprint(f\"AND: 10 & 3 = {10 & 3}\") #0010 -> 2 en decimal Compara bit a bit, y si los dos bits son \"uno\", devuelve uno\nprint(f\"OR: 10 | 3 = {10 | 3}\") #1011 -> 11 en decimal Compara bit a bit, y si al menos uno de los dos bits es uno, devuelve uno\nprint(f\"XOR: 10 ^ 3 = {10 ^ 3}\") #0101 -> 9 en decimal Compara bit a bit, y si los bits son diferentes, devuelve uno\nprint(f\"NOT: ~10 = {~10}\") #Invierte cada bit en el operando\nprint(f\"Dezplazamiento a la derecha: 10 >> 2 = {10 >> 2}\") #1010 >> 2 -> 0010 (2) \nprint(f\"Dezplazamiento a la izquierda: 10 << 2 = {10 << 2}\") #1010 << 2 -> 101000 (40) \n\n\n## Operadores de pertenencia\n\n\n# Estructuras de Control\n\n##Condicioneales.\n\n## If\n\nmy_string = \"Dans182\"\n\nif my_string == \"Dans182\":\n    print(\"my_string es 'Dans182'\")\nelif my_string == \"Daniel\":\n    print(\"my_string es 'Daniel'\")\nelse:\n    print(\"my_string no es 'Dans182' ni 'Daniel'\")\n\n## Iterativas\n\nfor i in range(11):\n    print(i)\n\ni = 0\n\nwhile i <= 10:\n    print(i)\n    i += 1\n\n## Manejo de excepciones\ntry:\n    print(10 / 0)\nexcept:\n    print(\"Se ha producido un error\")\nfinally:\n    print(\"Ha finalizado el manejo de excepciones\")\n\n\"\"\"\nExtra\n\"\"\"\n\nfor number in range(10, 56):\n    if number % 2 == 0 and number != 16 and number % 3 != 0:\n        print(number)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Daparradom.py",
    "content": "### 01-Operadores y Estructuras de Control ###\n\n#Operadores Aritmeticos\n\nprint(5 + 1, \"suma\") #suma\nprint(5 - 1, \"resta\") #resta\nprint(5 * 1, \"Multiplicacion\") #multiplicación\nprint(5 / 1, \"Division\") #División\nprint(10 % 2, \"Modulo\") #modulo ---> da el remanente\nprint(5 // 3, \"floor division\") #floor division --> division sin remanente o sin flotante\nprint(3**4, \"Operacion con exponente\") #Exponente\n\n#Operadores comparativos\n\n(5 == 4) # igual que \n(5 > 4) # mayor que\n(5 < 4) # menor que\n(5 >= 4) # mayor o igual que\n(5 <= 4) # menor o igual que\n(5 != 4) # diferente que\n\n# Operadores logicos \n\nprint( 5==3 and 1>0.5) \nprint( 1==2 or 3>5) \nprint(not (7<6)) \n\n# Condicionales\n\nresul = 5\n\nif resul>0:\n    print (f\"la variable resul cuyo valor es {resul} es positiva \")\nelif resul == 0:\n    print (f\"La variable resul cuyo valor es {resul} es igual a 0\")\nelse:\n    print(f\"La variable resul cuyo valor es {resul} es negativa\")\n\n#loops\n    \nwhile resul < 30 :\n    print(resul)\n    resul+=2\nelse:\n    print(\"mi variable resul es mayor a 30\")\n    \nnumbers = [1,2,3,4,5,6,7,8,9,10]\n\nfor number in numbers:\n    print(number)\n\nfor i in range(1,50,10):\n    print(i)\nelse:\n    print(\"se ha terminado el for\")\n\n## Programa \n\nprint(\"Se comienza el programa\\n\")\nfor number in range(10,56,1):\n    if number%2 == 0 and number!=16 and number%3!=0:\n        print(number)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/DarianGL.py",
    "content": "\"\"\"TIPOS DE OPERADORES\"\"\"\n\n# La interpolacion permite agregar codigo a una cadena de texto (f,{})\n\n# OPERADORES ARITMETICOS\nprint(f\"Suma: 7 + 8 = {7 + 8}\") # Operador de Suma (+)\nprint(f\"Resta: 20 - 5 = {20 - 5}\") # Operador de Resta (-)\nprint(f\"Multiplicación: 3 * 5 = {3 * 5}\") # Operador de Multiplicación (*)\nprint(f\"División: 10 / 3 = {10 / 3}\") # Con este operador se pueden realizar divisiones con decimales (/)\nprint(f\"Módulo: 14 % 10 = {14 % 10}\") # Este operador sirve para calcular el residuo de una división (%)\nprint(f\"Exponente: 10 ** 3 = {10 ** 3}\") # Este operador sirve para realizar operaciones exponenciales (**)\nprint(f\"División entera: 10 // 3 = {10 // 3}\") # Con este operador se realizan divisiones sin decimal (//)\n\n# OPERADORES DE COMPARACIÓN\nvariable_1 = \"Hola\"\nvariable_2 = \"Adios\"\nprint(f\"Igualdad: variable_1 == variable_2 {variable_1 == variable_2}\") # Operador de Igualdad (==)\nprint(f\"Desigualdad: variable_1 != variable_2 {variable_1 != variable_2}\") # Operador de Desigualdad (!=)\nprint(f\"Mayor o igual que: 15 >= 8 {15 >= 8}\") # Operador de Mayor o igual que (>=) (alt + 62)\nprint(f\"Menor o igual que: 8 <= 15 {8 <= 15}\") # Operador de Menor que (<=) (alt + 60)\n\n# OPERADORES LÓGICOS\nprint(f\"And &&: 7 + 8 == 15 and 10 - 2 == 8 {7 + 8 == 15 and 10 - 2 == 8}\") # Operador and (And, &&)\nprint(f\"Or ||: 7 + 8 == 16 or 10 - 2 == 8 {7 + 8 == 16 or 10 - 2 == 8}\") # Operador Or (Or, ||)\nprint(f\"Not !: Not 7 + 8 == 16 {not 7 + 8 == 16}\") # Operador de negación (Not, !)\n\n# OPERADORES DE ASIGNACIÓN\nnumber = 10\nprint(f\"Asignación: {number}\") # Operador de Asignación (=)\nnumber += 10\nprint(f\"Suma y asignación: {number}\") # Operador de Suma y Asignacion (+=)\nnumber -= 5\nprint(f\"Resta y Asignación: {number}\") # Operador de Resta y Asignacion (-=)\nnumber *= 2\nprint(f\"Multiplicación y Asignación: {number}\") # Operador de Multiplicación y Asignacion (*=)\nnumber /= 2\nprint(f\"División y Asignación: {number}\") # Operador de División y Asignación (/=)\nnumber %= 2\nprint(f\"Módulo y Asignación: {number}\") # Operador de Módulo y Asignación (%=)\nnumber **= 2\nprint(f\"Exponente y Asignación: {number}\") # Operador de Exponente y Asignación (**=)\nnumber //= 1\nprint(f\"División entera y Asignación: {number}\") # Operador de División entera y Asignación (//=)\n\n# OPERADORES DE IDENTIDAD (sirve para comparar la identidad de las variables)\nnew_number = 1.0\nprint(f\"number is new_number {number is new_number}\") # Operador de identidad (is)\nprint(f\"number is not new_number {number is not new_number}\") # Operador de identidad (is not)\n\n# OPERADORES DE PERTENENCIA\nprint(f\"'Y' in 'Python' = {'y' in 'python'}\") # Operador de Pertenencia (in)\nprint(f\"'X' not in 'Python' = {'x' not in 'python'}\") # Operador de Pertenencia (not in)\nprint(f\"'5' in '888' = {'5' in '888'}\")\n\n# OPERADORES DE BIT (Comparan bit pot bit y hacen operaciones en binario)\na = 8 # 1000\nb = 10 # 1010\nprint(f\"AND: 8 & 10 = 1000 = {a & b}\") # Operador de bit And (&) (si dos bits son igual a 1 el resultado es 1)\nprint(f\"OR: 8 | 10 = 1010 = {a | b}\") # Operador de bit Or (|) (si al menos uno de los dos bits es uno el resultado es 1)\nprint(f\"XOR: 8 ^ 10 = 0010 = {a ^ b}\") # Operador de bit Xor (^, alt + 94) (Si los dos bits son diferentes el resultado es 1 y si son iguales es 0)\nprint(f\"NOT: ~8 = {~a}\") # Operador de bit NOT (~, alt + 126) (invierte el valor del numero bit a bit)\nprint(f\"Desplazamiento derecha: 10 >> 3 = {b >> 3}\") # Desplaza a la derecha los bits el numero de veces indicado (>>)\nprint(f\"Desplazamiento izquierda: 10 << 1 = {b << 1}\") # Desplaza a la izquierda los bits el numero de veces indicado (<<)\n\n\"\"\"ESTRUCTURAS DE CONTROL\"\"\"\n\n# ESTRUCTURAS CONDICIONALES\nstring = \"Xion\"\nif string == \"Roxas\":\n    print(\"string es 'Roxas'\")\nelif string == \"Axel\":\n    print(\"string es 'Axel'\")\nelse:\n    print(\"String es 'Xion'\")\n\n# ESTRUCTURAS ITERATIVAS\nfor i in range(11): # Sirve para crear rangos\n    print(i)\ni = 0\nwhile i <= 10: # Sirve para crear bucles\n    print(i)\n    i += 2\n\n# Estructuras de Excepción\ntry:\n    print(10 / 0)\nexcept:\n    print(\"Se ha producido un error\")\nfinally:\n    print(\"Finalizado el manejo de excepciones\")\n\n\n\"\"\"EXTRA\"\"\"\nfor my_number in range(10, 56):\n    if my_number % 2 == 0 and my_number % 3 != 0 and my_number != 16:\n        print(my_number)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/DataCiriano.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\"\"\"\n\n# Operadores Aritméticos\n\nprint(f\"Suma: 10 + 3 = {10 + 3}\")\nprint(f\"Resta: 10 - 3 = {10 - 3}\")\nprint(f\"Multiplicación: 10 * 3 = {10 * 3}\")\nprint(f\"División: 10 / 3 = {10 / 3}\")\nprint(f\"Módulo: 10 % 3 = {10 % 3}\")\nprint(f\"Exponente: 10 ** 3 = {10 ** 3}\")\nprint(f\"División entera: 10 // 3 = {10 // 3}\")\n\n\n# Operadores Comparación\n\nprint(f\"Igualdad: 5 == 7 {5 == 7}\")\nprint(f\"Desigualdad: 5 != 7 {5 != 7}\")\nprint(f\"Mayor que: 5 > 7 {5 > 7}\")\nprint(f\"Menoror que: 5 < 7 {5 < 7}\")\nprint(f\"Mayor o igual que: 5 >= 7 {5 >= 7}\")\nprint(f\"Menor o igual que: 5 <= 7 {5 <= 7}\")\n\n\n# Operadores lógicos\n\nprint(f\"AND &&: 10 + 3 == 13 and 5 - 1 == 4 es {10 + 3 == 13 and 5 - 1 == 4}\")\nprint(f\"OR ||: 10 + 3 == 13 or 5 - 1 == 4 es {10 + 3 == 14 or 5 - 1 == 4}\")\nprint(f\"NOT !: not 10 + 3 == 14 es {not 10 + 3 == 14}\")\n\n\n# Operadores de asignación\n\nnumber = 15  # asignación\nprint(number)\nnumber += 1  # suma y asignación\nprint(number)\nnumber -= 1  # resta y asignación\nprint(number)\nnumber *= 2  # multiplicación y asignación\nprint(number)\nnumber /= 2  # división y asignación\nprint(number)\nnumber %= 2  # módulo y asignación\nprint(number)\nnumber **= 1  # exponente y asignación\nprint(number)\nnumber //= 1  # división entera y asignación\nprint(number)\n\n# Operadores de identidad\n\nnew_number = number\nprint(f\"number is new_number es {number is new_number}\")\nprint(f\"number is not new_number es {number is not new_number}\")\n\n\n# Operadores de bit\n\na = 10  # 1010\nb = 3  # 0011\nprint(f\"AND: 10 & 3 = {10 & 3}\")  # 0010\nprint(f\"OR: 10 | 3 = {10 | 3}\")  # 1011\nprint(f\"XOR: 10 ^ 3 = {10 ^ 3}\")  # 1001\nprint(f\"NOT: ~10 = {~10}\")\nprint(f\"Desplazamiento a la derecha: 10 >> 2 = {10 >> 2}\")  # 0010\nprint(f\"Desplazamiento a la izquierda: 10 << 2 = {10 << 2}\")  # 101000\n\n\n#Estructuras de control\n\n#Condicionales\n\nvariable = 7\n\nif variable > 10:\n    print(\"La variable es mayor a 10\")\nelif variable < 10:\n    print(\"La variable es menor a 10\")\nelse:\n    print(\"La variable es 10\")\n    \n# Iterativos\n\nfor i in range(0,11,2):\n    print(i)\n    \niteracion = 1\n    \nwhile iteracion <= 10:\n    print(f\"Iteración: {iteracion}\")\n    iteracion += 1\n    \n#Manejo de excepciones\n\ntry:\n    print(10/0)\nexcept:\n    print(\"Se produjo un error\")\nfinally:\n    print(\"Fin del contro de excepciones\")\n    \n    \n# Extra\n\nfor i in range(10,56):\n    if i % 2 == 0 and i != 16 and not i % 3 == 0:\n        print(i) "
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/DerianCastilloP.py",
    "content": "######################## Operadores Aritmeticos ########################\n\nprint(\"# Operadores Aritmeticos #\\n\")\n\nx = 3\ny = 4\n\nsuma = x + y            #7\nprint(f\"El resultado de {x} + {y} es = {suma}\")\n\nresta = x - y           #-1\nprint(f\"El resultado de {x} - {y} es = {resta}\")\n\nmultip = x * y          #12\nprint(f\"El resultado de {x} * {y} es = {multip}\")\n\ndivision = x / y        #0.75\nprint(f\"El resultado de {x} / {y} es = {division}\")\n\nmodulo = x % y          #3 (el modulo es el mismo numero ya que como el 4 que el 3\nprint(f\"El resultado de {x} % {y} es = {modulo}\")\n\nexponencial = x ** y    #81\nprint(f\"El resultado de {x} ** {y} es = {exponencial}\")\n\nfloor_div = x // y      #0\nprint(f\"El resultado de {x} // {y} es = {floor_div}\")\n\n\n######################## Operadores de asignacion  ########################\nprint(\"\\n\\n## Operadores de Asignacion ##\\n\")\n\nnombre_var = 7\nprint(f\"Operador '=' asigna a 'nombre_variable' un valor Ej: x = {nombre_var}\")\n\nnombre_var += 2\nprint(f\"Operador '+=' asigna a 'nombre_variable' un valor + el valor anterior de la variable Ej: x += 2 resultado es {nombre_var}\")\n\nnombre_var -= 4\nprint(f\"Operador '-=' asigna a 'nombre_variable' un valor - el valor anterior de la variable Ej: x -= 4 resultado es {nombre_var}\")\n\nprint(\"\"\"\\nEsto se puede hacer con todos los Operadores Aritmeticos agregandole un igual '=' \nEj: '*=', '/=', '%=', '//=', '**=' asiendo la su respectiva operacion con la variable y\nagregandole el resultado a la minma variable\"\"\")\n\n\n######################## Operadores de comparacion  ########################\n\n\nprint(\"\\n\\n### Operadores de comparacion ###\\n\")\n\nc = x == y # compara si es igual\nprint(f\"{x} es Igual a {y} ? = {c}\")\n\nc = x != y # compara si es diferente\nprint(f\"{x} es Diferente a {y} ? = {c}\")\n\nc = x < y # compara si es menor\nprint(f\"{x} es Menor que {y} ? = {c}\")\n\nc = x > y # compara si es mayor\nprint(f\"{x} es Mayor que {y} ? = {c}\")\n\nc = x <= y # compara si es menor o igual\nprint(f\"{x} es menor o igual que {y} ? = {c}\")\n\nc = x >= y # compara si es mayor o igual\nprint(f\"{x} es Mayor o igual que {y} ? = {c}\")\n\n\n######################## Operadores Logicos  ########################\n\n\nprint(\"\\n\\n#### Operadores Logicos ####\")\n\nverdadero = True\nfalso = False\n\nprint(\"\\nSiendo V = Verdadero y Siendo F = Falso\")\nprint(\"\\nOperador 'and'\")\n# \"and\" si ambos son verdadero entonces es True de lo contrario es False\nprint(\"V and V = \", verdadero and verdadero)\nprint(\"V and F = \", verdadero and falso)\nprint(\"F and V = \", falso and verdadero)\nprint(\"F and F = \", falso and falso)\n\nprint(\"\\nOperador 'or'\")\n# \"or\" si almenos hay un verdadero entonces es True de lo contrario es False\nprint(\"V or V = \", verdadero or verdadero)\nprint(\"V or F = \", verdadero or falso)\nprint(\"F or V = \", falso or verdadero)\nprint(\"F or F = \", falso or falso)\n\nprint(\"\\nOperador 'not'\")\n# \"not\" Invierte el resultado vamos a poner un ejemplo con el operador \"or\"\nprint(\"(not) V or V = \", not(verdadero or verdadero))\nprint(\"(not) V or F = \", not(verdadero or falso))\nprint(\"(not) F or V = \", not(falso or verdadero))\nprint(\"(not) F or F = \", not(falso or falso))\n\n\n######################## Operadores de Identidad  ########################\n\n\nprint(\"\\n\\n##### Operadores de Identidad #####\")\n\n# Los operadores de identidad indican si dos variables hacen referencia al mismo\n# objeto, por ejemplo para saber si dos variables distintas tienen el mismo id.\n\nprint(\"'x' referencia al mismo valor que 'y'? : \", x is y)\nprint(\"'x' referencia no al mismo valor que 'y'? : \", x is not y)\n\n\n######################## Operadores de membresia  ########################\n\nprint(\"\\n###### Operadores de Membresia ######\")\n\n#Los operadores de membresía se utilizan para probar si un elemento esta\n#dentro de una secuencia, como una lista por ejemplo.\n\nlistas = [\"carro\", \"motor\", \"patin\", \"avion\"]\nvehiculo = \"motor\"\n\nprint(listas)\nprint(\"\\nEl Vehiculo 'carro' esta en la lista? : \", vehiculo in listas)\nprint(\"El Vehiculo 'carro' no esta en la lista? : \", vehiculo not in listas)\n\n######################################################################################################\n################################### TIPOS DE ESTRUCTURAS DE CONTROS ##################################\n###################################      QUE EXISTEN EN PYTHON     ###################################\n######################################################################################################\n\n\n######################## Condicionales  ########################\n\n\nprint(\"\\n\\n# Condicionales #\\n\")\n\n#Las estructuras condicionales permiten ejecutar código según una condición.\n\nprint('En estas tenemos \"if\" si se cumple una condicion')\n\n#Ejemplos 'if', 'else', 'elif'\nif x < y:\n    print(\"Ejemplo 1: x es menor que y\")\n\n#Tenemos el \"else\" por si no se cumple la condicion\nif x > y:\n    print(\"Ejemplo 2: x es mayor que y\")\nelse:\n    print(\"Ejemplo 2:la condicion no se cumplio\")\n\n#si queremos evaluar multiples condiciones podemos usar \"elif\"\n\nif x > y:\n    print(\"Ejemplo 3: x es mayor que y\")\nelif x < y:\n    print(\"Ejemplo 3: x es menor que y\")\nelse:\n    print(\"Ejemplo 3:la condicion no se cumplio\")\n\n\n############################ Bucles  #############################\n\nprint(\"\\n\\n## Bucles For ##\\n\")\n\n#Los bucles permiten repetir código varias veces\n\nprint('*Bucle \"for\" es un blucle que itera sobre una secuencia\\n')\n\n#Ejemplo \"for\"\nprint(\"Ejemplo_1\")\nfor numero in range(7):\n    print(f\"Numero: {numero}\")\n\nprint(\"\\n\")\n\n#Ejemplo \"for\" con listas\n\nprint(\"Ejemplo_2\")\nfor vehiculo in listas:\n    print( vehiculo.title())\n\n## for + enumerate() ##\n\nprint('''\\n*Bucle \"for\" tambien lo puedes usar con la funcion \"enumrate\" para \nsaber he imprimir el indice de los elementos en la lista\\n''')\n\nprint(\"Ejemplo_3\")\nfor indice, vehiculo in enumerate(listas):\n    print(f'{indice} : {vehiculo}')\n\n## for + zip() ##\n\nprint('''\\n*Bucle \"for\" tambien lo puedes usar con la funcion \"zip\" para \npara recorrer 2 listas a la vez\\n''')\n\nprint(\"Ejemplo_4\")\nprecios = [898, 387, 77, 7123]\n\nfor price, vehiculo in zip(precios,listas):\n    print(f'${price} es el valor del {vehiculo}')\n\n\nprint(\"\\n\\n## Bucles while ##\\n\")\n\nprint('*Bucle \"while\" es un blucle que itera mientras la condicion sea verdadera\\n')\n\n#Ejemplo \"while\"\nprint(\"Ejemplo_1 \")\ncontador = 0\n\nwhile contador <= 7:\n    print(f\"contador: {contador}\")\n    contador += 1 #el contador tiene que incrementar por que si no no se cumpliria la condicion y seria un Bucle infinito\n\nprint(\"\\nEjemplo_2 \")\ncondicion = True\nx = 0\nwhile condicion == True:\n    print('El while se esta Ejecutando')\n    x += 1\n    if x == 7:\n        print(\"la condicion cambio a False\")\n        print(\"Deteniendo el while...\")\n        condicion = False\n\n\n############################ Control de Bucles  #############################\n\nprint(\"\\n\\n### Control de Bucles ###\\n\")\n\nprint('*Control de Bucles Permiten modificar el comportamiento de los bucles.\\n')\n\nprint(\"Para detener un bucle tenemos 'break'\")\n\n#Ejemplos_1 'break'\nprint(\"\\nEjemplo_1\")\nfor numero in range(7):\n    if numero == 4:\n        break # se detiene antes que el numero 4\n    print(f\"Numero: {numero}\")\n\nprint(\"\\nPara saltar una iteracion tenemos 'continue'\")\n\n#Ejemplos_2 'continue'\nprint(\"\\nEjemplo_2\")\nfor numero in range(7):\n    if numero == 4:\n        continue # se salta el numero 4\n    print(f\"Numero: {numero}\")\n\nprint(\"\\nEl 'pass' Se usa cuando quieres dejar código sin implementar y no causar errores 'no hace nada'\")\n\n#Ejemplos_3 'pass'\nprint(\"\\nEjemplo_3\")\nfor numero in range(7):\n    if numero == 4:\n        pass\n    print(f\"Numero: {numero}\")\n\n############################ Manejo de errores  #############################\n\nprint(\"\\n\\n#### Manejo de errores ####\\n\")\n\nprint(\"\\nLos Manejos de errores evitan que el programa se detenga si ocurre algun error con 'try-except'\\n\")\n\n#el codigo prueba si no hay ningun error y si ocurre ejecuta la excencion (existen mas errores que el de 'ZeroDivisionError')\n\nprint(\"Ejemplo_1\")\ntry:\n    resultado = 7 / 0  # Error de división por cero\nexcept ZeroDivisionError:\n    print(\"No se puede dividir por cero\")\n\n\nprint(\"\\ntambien podemos usa 'try-except-else-finally'\\n\")\n# El 'else' se ejecuta si no hay error y el 'finally' siempre se ejecuta\n\nprint(\"Ejemplo_2:)\")\ntry:\n    numero = 7\nexcept ValueError:\n    print(\"Eso no es un número válido\")\nelse:\n    print(f\"El número ingresado es {numero}\")\nfinally:\n    print(\"Este mensaje siempre se ejecuta\")\n\n############################ Estructuras Especiales  #############################\n\nprint(\"\\n\\n##### Estruturas Especiales #####\\n\")\n\nprint(\"\"\"Encontre algunas Estructuras especiales como:\t'match-case', 'with', 'yield', 'list comprehensions' \nque aun estoy conociendo pero es bueno saber que existen\"\"\")\n\nprint(\"\\nEjemplo_1: sobre match-case (funciona como un switch-case en otros lenguajes.)\\n\")\nopcion = 2\n\nmatch opcion:\n    case 1:\n        print(\"Elegiste opción 1\")\n    case 2:\n        print(\"Elegiste opción 2\")\n    case _:\n        print(\"Opción no válida\")\n\n\n####################################################################################################\n###################################          DIFICULTAD          ##################################\n###################################             EXTRA             ##################################\n####################################################################################################\n\n\nprint(\"\\n\\n##### Dificultad Extra #####\")\n\nprint(\"\"\"\\nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3\"\"\")\n\nnumeros_extras = list() #cree la lista para que sea una visulizacion mas clara\n\nfor num_extra in range(10,56):\n    if num_extra % 2 == 0:\n        if num_extra % 3 != 0 and num_extra != 16:\n            numeros_extras.append(num_extra)\n\nprint(f\"\\nResultado: {numeros_extras}\")\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/DiegoIBB.py",
    "content": "#01 ESTRUCTURAS DE CONTROL_Retos_Semanales\n\n\"\"\" OPERADORES\n\tAsignación: =, +=, -=, *=, /=, %=, **=, etc..\n\tAritméticos: +, -, *, /, %, **, etc..\n\tComparasión: <, >, <=, >=, ==, !=\n\tLógicos: &&(and),||(or), !(not)\n\"\"\"\n#OPERADORES ARITMETICOS\n\nx = 6\ny = 2\n\nsuma = x + y\nresta = x - y\nmultiplicacion = x * y\ndivision = x / y\nmodulo = x % y\nexponente = x ** y\n\nprint(\"----OPERADORES ARITMETICOS----\")\nprint(f\"Suma {x} + {y}: {suma}\")\nprint(f\"Resta {x} - {y}: {resta}\")\nprint(f\"Multiplicación {x} * {y}: {multiplicacion}\")\nprint(f\"División {x} / {y}: {division}\")\nprint(f\"Modulo {x} % {y}: {modulo}\")\nprint(f\"Exponente {x} ** {y}: {exponente}\")\n\n\n#OPERADORES DE ASIGNACIÓN\n\na = 0 #Asignación \n\nb = 1 #Incremento\nb += 1\n\nc = 2 #Decremento\nc -= 1\n\nd = 3 #Multiplicacion \nd *= 2 \n\ne = 2 #Division\ne /= 2\n\nf = 5 #Modulo\nf %= 3\n\ng = 2 #Exponenciación\ng **= 3\n\nprint(\"----OPERADORES DE ASIGNACION----\")\nprint(f\"Asignación = {a}\")\nprint(f\"Incremento += {b}\")\nprint(f\"Decremento -= {c}\")\nprint(f\"Multiplicación *= {d}\")\nprint(f\"División /= {e}\")\nprint(f\"Modulo %= {f}\")\nprint(f\"Exponente **= {g}\")\n\n\n#OPERADORES DE COMPARACION\n\nh = 45\ni = 34\n\nprint(\"----OPERADORES DE COMPARACION----\")\nprint(f\"Operador menor que -> h(45) < i(34): {h < i}\")\nprint(f\"Operador mayor que -> h(45) > i(34): {h > i}\")\nprint(f\"Operador menor o igual que -> h(45) <= i(34): {h <= i}\")\nprint(f\"Operador mayor o igual que -> h(45) >= i(34): {h >= i}\")\nprint(f\"Operador igualdad -> h(45) == i(34): {h == i}\")\nprint(f\"Operador desigualdad -> h(45) != i(34): {h != i}\")\n\n#OPERADORES DE LOGICOS\n\nj = True\nk = False\nn = True\n\nprint(\"----OPERADORES DE LOGICOS----\")\nprint(j == k and n >= j)\nprint(j != k or n == j)\nprint(not k <= j)\n\n#OPERADORES DE IDENTIDAD Y PERTENENCIA\n\"\"\"\nLos operadores de identidad permiten revisar si un objeto es identico a otro, por otro lado\nlos operadores de pertenencia permiten ver si un elemento es parte de un conjunto\n\"\"\"\nprint(\"----OPERADORES DE IDENTIDAD----\")\nelementos = [\"casa\", 3234, 'D', 4.6, True]\ne1 = \"casa\"\ne2 = 89\n\nprint(e1 is elementos[1])\nprint(e2 is not elementos[3])\n\nprint(\"----OPERADORES DE PERTENENCIA----\")\nfrutas = (\"Pera\", \"Manzana\", \"Piña\", \"Platano\", \"Mango\")\nf1 = \"Mango\"\nf2 = \"Piña\"\n\nprint(f1 in frutas[4])\nprint(f2 not in frutas[3])\n\n\n#OPERADORES DE BITS\n\nnum_1 = 5 #0000000000000101\nnum_2 = 7 #0000000000000111\n\nprint (num_1 & num_2) #Nos entrega la cantidad de 1(unos) que tienen los números en su descripción binaria\nprint (num_1 | num_2) #Nos entrega un número que comparte todos los 1(unos) que tienen los números en común\nprint (num_1 ^ num_2) #Cambia todos los números por 1(unos) inclusive si solo uno lo es\nprint (~ num_2) #Invierte los valores de 1s a 0s y viceversa\nprint (num_1 << num_2)\nprint (num_1 >> num_2)\n\n\n#ESTRUCTURAS DE SELECCION O TOMA DE DESICION\n\n#Estructuras if-elif-else\n\nprint(\"----ESTRUCTURAS IF_ELIF_ELSE----\")\naño = int(input(\"Year: \"))\n\nif (año % 4) == 0:\n    if (año % 100) == 0:\n        if (año % 400) == 0:\n            print(\"Es año bisiesto\")\n        else:\n            print(\"No es año bisiesto\")\n    else:\n        print(\"Es año bisiesto\")\nelse:\n   print(\"No es año bisiesto\")\n\nbebidas = [\"Te\", \"Mocca\", \"Capuccino\", \"Mocaccino\", \"Americano\", \"Espresso\"]\n\neleccion = int(input(\"Elija una bebida: \"))\n\nif eleccion == 1:\n    print(f\"Ha elegido {bebidas[0]}\")\nelif eleccion == 2:\n    print(f\"Ha elegido {bebidas[1]}\")\nelif eleccion == 3:\n    print(f\"Ha elegido {bebidas[2]}\")\nelif eleccion == 4:\n    print(f\"Ha elegido {bebidas[3]}\")\nelif eleccion == 5:\n    print(f\"Ha elegido {bebidas[4]}\")\nelif eleccion == 6:\n    print(f\"Ha elegido {bebidas[5]}\")\nelse:\n    print(\"Opción no registrada\")\n\nprint(\"----ESTRUCTURAS FOR----\")\n\n#ESTRUCTURAS DE REPETICION\n\nprint(\"----ESTRUCTURAS WHILE----\")\n\nnum_ciclos = 6\n\nwhile num_ciclos >= 0:\n    print(f\"N° de Ciclo: {num_ciclos}\")\n    num_ciclos -= 1\n\nprint(\"----ESTRUCTURAS WHILE_EXCEPCIONES----\")\n\nwhile True:\n    try:\n        name = int(input(\"Ponga su edad: \"))\n    except ValueError:\n        print(\"Su edad no es un valor númerico valido\")\n    else:\n        print(f\"Edad ingresada: {name}\")\n        break\n\n\nprint(\"----ESTRUCTURAS FOR----\")\n\nx = 0\npalabra = \"Hola\"\n\nfor letra in palabra:\n    x += 1\n    print(palabra[0:x])\nx = 0\n\n\nfrase = input(\"Inserte una frase: \")\ncontador_a = 0\n\nfor i in frase:\n     if i == \"a\":\n          contador_a = contador_a + 1\n          continue\n     elif i == \"A\":\n          contador_a = contador_a + 1\n          continue     \n\nprint(f\"Letras a en la {frase}: {contador_a} letras a\")\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Dkp-Dev.py",
    "content": "\"\"\"\nEJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos. \n \"\"\"\n\n# Operadores Aritmeticos\nprint(f\"Suma 37 + 13 = {37 + 13}\")\nprint(f\"Resta 76 - 14 = {76 - 14}\")\nprint(f\"Multiplica 14 * 14 = {14 * 14}\")\nprint(f\"Divide 255 / 4 = {255 / 4}\")\nprint(f\"Modulo 23 % 3 = {23 % 3}\")  # Nota personal: Modulo es el residuo de una division, en el ejemplo 23/3 es 7 y 7*3 es 21 quedando 2 como resultado del Modulo.\nprint(f\"Exponente 14 ** 3 = {14 ** 3}\")\nprint(f\"Division entera 255 // 4 = {255 // 4}\")\n\n# Operadores de Comparacion\nprint(f\"Igualdad: 14 == 14 es {14 == 14}\")\nprint(f\"Desigualdad: 14 == 27 es {14 != 27}\")\nprint(f\"Mayor que: 12 > 13 es {12 > 13}\")\nprint(f\"Menor que: 7 < 13 es {7 < 13}\")\nprint(f\"Mayor o igual que: 14 >= 13 es {14 >= 13}\")\nprint(f\"Menor o igual que: 10 <= 13 es {10 <= 13}\")\n\n# Operadores Logicos\nprint(f\"AND &&: 14 + 14 == 28 and 7 + 3 == 10 es {14 + 14 == 28 and 7 + 3 == 10}\")\nprint(f\"OR ||: 76 - 40 == 36 or 12 / 4 == 3 es {76 - 40 == 36 or 12 / 4 == 3}\")\nprint(f\"NOT !: not 14 - 7 == 6 es {not 14 - 7 == 6}\")\n\n# Operadores de Asignacion\n# Nota personal: Son operadores que pueden funcionar para asignar valores a variables.\nnumero = 14\nprint(numero)\nnumero += 14\nprint(\"+ 14 =\", numero)\nnumero -= 4\nprint(\"- 4 =\", numero)\nnumero *= 2\nprint(\"* 2 =\", numero)\nnumero /= 2\nprint(\"/ 4 =\", numero)\nnumero %= 5\nprint(\"% 5 =\", numero)\nnumero **= 2\nprint(\"** 2 =\", numero)\nnumero //= 3\nprint(\"// 3 =\", numero)\n\n# Operadores de Identidad\n# Nota personal: Aqui veremos que una identidad es distinto de un valor, las variables valen 5.0, pero no son iguales.\nnuevo_numero = 5.0\nprint(f\"Mi nuevo numero es mi numero es {nuevo_numero is numero}\")\nprint(nuevo_numero, \"y\", numero)\n# Aqui cambiaremos el valor de la variable por el de otra y replicaremos el ejercicio.\nnuevo_numero = numero\nprint(f\"Mi nuevo numero es mi numero es {nuevo_numero is numero}\")\nprint(nuevo_numero, \"y\", numero)\nprint(f\"Mi nuevo numero no es mi numero es {nuevo_numero is not numero}\")\n\n# Operadores de pertenencia\n# Nota personal: para comprobar si algo pertenece a algo.\nprint(f\"'D' in 'Dkp' es {'D' in 'Dkp'}\")\nprint(f\"'V' in 'Dkp' es {'V' in 'Dkp'}\")\nprint(f\"'D' not in 'Dkp' es {'D' not in 'Dkp'}\")\nprint(f\"'V' not in 'Dkp' es {'V' not in 'Dkp'}\")\n\n# Operadores de Bit\na = 10  # 1010      # esta es su representacion binaria\nb = 3   # 0011      # ocuparemos estos dos para hacer las operaciones manualmente\n\nprint(f\"AND: 10 & 3 = {10 & 3}\")     # 0010     # AND-& va comparar bit a bit y si ambos son 1 dara 1\nprint(f\"OR: 10 | 3 = {10 | 3}\")      # 1011     # OR-| va comparar y si un bit es 1 dara 1\nprint(f\"XOR: 10 ^ 3 = {10 ^ 3}\")     # 1001     # XOR-^ va comparar y si los bit no son iguales dara 1\nprint(f\"NOT: ~10 = {~10}\")                      # va negando bit a bit\n\nprint(f\"Desplazamiento a la derecha: 10 >> 2 es {10 >> 2}\")     # >> sirve para mover bits en ceros, 10 es 1010 pasa a 0010 que es 2\nprint(f\"Desplazamiento a la izquierda: 10 << 2 es {10 << 2}\")   # << aqui 10 que es 1010 pasa a 101000 que es 40\n\n\"\"\"\nEstructura de control\n\"\"\"\n\n# Condicionales\n\nstring = \"Condicional 1\"\n\nif string == \"Condicional 1\":\n    print(\"Se imprime primera condicion\")\nelif string == \"Condicional 2\":\n    print(\"Se imprime segunda condicion\")\nelse:\n    print(\"No es la condicion\")\n\n# Iterativas\n\nfor i in range(8):\n    print(i)\nprint(\"Termina el for\")\n\ni = 0\nwhile i <= 10:\n    print(i)\n    i += 1\nprint(\"Termina el while\")\n\n# Manejo de excepciones\n\nconejo = 10\n\ntry:\n    print(conejo / 2)\nexcept: \n    print(\"Dio error\")\nfinally:\n    print(\"Ha finalizado el sistema de manejo de excepciones\")\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\"\"\"\n\nprint(\"Tarea Extra\")\n\nfor tortuga in range(10,56):\n    if tortuga % 2 == 0 and tortuga != 16 and tortuga % 3 != 0:\n        print(tortuga)\n\nprint(\"Fin del ejercicio\")"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Dota43ver.py",
    "content": "\n# Operadores\n\n# Operadores aritmetico\n\nprint(f\"Suma : 10 + 3 = {10+3}\")\nprint(f\"Resta : 10 - 3 = {10-3}\")\nprint(f\"Multiplicacion : 10 * 3 = {10*3}\")\nprint(f\"Division : 10 / 3 = {10/3}\")\nprint(f\"Modulo : 10 % 3 = {10%3}\")\nprint(f\"exponente : 10 ** 3 = {10**3}\")\nprint(f\"Division entera : 10 // 3 = {10//3}\")\n\n# Operadores de comparacion\n\nprint(f\"Igualdad: 10 == 3 es {10==3}\")\nprint(f\"Desigualdad: 10 != 3 es {10!=3}\")\nprint(f\"Mayor que: 10 > 3 es {10>3}\")\nprint(f\"Menor que: 10 < 3 es {10<3}\")\nprint(f\"Mayor igual que: 10 >= 10 es {10>=10}\")\nprint(f\"Menor igual que: 10 <= 10 es {10<=3}\")\n\n# Operadores logicos\n\nprint(f\"And: 10 + 3 = 13 and 5 - 1 = 4 {10 + 3 == 13 and 5 - 1 == 4}\") # Se deben cumplir ambas operaciones para dar true\nprint(f\"Or: 10 + 3 = 13 or 5 - 1 = 4 {10 + 3 == 10 or 5 - 1 == 4}\") # Se debe cumplir al menos 1 operacion para dar true  (5 - 1 = 4) \nprint(f\"Not: not 10 + 3 = 14 {not 10 + 3 == 14}\") # En caso de que la operacion (comparacion) sea false poniendole un not adelante la invierte a true\n\n# Operadores de asignacion\n# Operadores de asignación\nmy_number = 11  # asignación\nprint(my_number)\nmy_number += 1  # suma y asignación\nprint(my_number)\nmy_number -= 1  # resta y asignación\nprint(my_number)\nmy_number *= 2  # multiplicación y asignación\nprint(my_number)\nmy_number /= 2  # división y asignación\nprint(my_number)\nmy_number %= 2  # módulo y asignación\nprint(my_number)\nmy_number **= 1  # exponente y asignación\nprint(my_number)\nmy_number //= 1  # división entera y asignación\nprint(my_number)\n\n# Operadores de identidad\nmy_new_number = my_number\nprint(f\"my_number is my_new_number es {my_number is my_new_number}\") # compara posiciones de memoria, no los valores.\nprint(f\"my_number is not my_new_number es {my_number is not my_new_number}\")\n\n# Operadores de pertenencia\nprint(f\"'u' in 'mouredev' = {'u' in 'mouredev'}\")\nprint(f\"'b' not in 'mouredev' = {'b' not in 'mouredev'}\")\n\n# Operadores de bit\na = 10  # 1010\nb = 3  # 0011\nprint(f\"AND: 10 & 3 = {10 & 3}\")  # 0010\nprint(f\"OR: 10 | 3 = {10 | 3}\")  # 1011\nprint(f\"XOR: 10 ^ 3 = {10 ^ 3}\")  # 1001\nprint(f\"NOT: ~10 = {~10}\")\nprint(f\"Desplazamiento a la derecha: 10 >> 2 = {10 >> 2}\")  # 0010\nprint(f\"Desplazamiento a la izquierda: 10 << 2 = {10 << 2}\")  # 101000\n\n\"\"\"\nEstructuras de control\n\"\"\"\n\n# Condicionales\n\nmy_string = \"Brais\"\n\nif my_string == \"MoureDev\":\n    print(\"my_string es 'MoureDev'\")\nelif my_string == \"Brais\":\n    print(\"my_string es 'Brais'\")\nelse:\n    print(\"my_string no es 'MoureDev' ni 'Brais'\")\n\n# Iterativas\n\nfor i in range(11):\n    print(i)\n\ni = 0\n\nwhile i <= 10:\n    print(i)\n    i += 1\n\n# Manejo de excepciones\ntry:\n    print(10 / 0)\nexcept:\n    print(\"Se ha producido un error\")\nfinally:\n    print(\"Ha finalizado el manejo de excepciones\")\n\n\"\"\"\nExtra\n\"\"\"\n\nfor number in range(10, 56):\n    if number % 2 == 0 and number != 16 and number % 3 != 0:\n        print(number)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/E-techgod.py",
    "content": "\n### Operators ###\n\n# Arithmetic Operators #\nprint (\"Arithmetic Operators\")\nprint (5+5) # sum \nprint (5-5) # substraction \nprint (5*5) # multiplication \nprint (5**5) # power \nprint (5/5) # division \nprint (10//5) # floor \nprint (12%5) # mod \nprint (\"\\n\")\n\n# Assignment Operators #\nx=5 # x = 5\nprint (\"Assignment Operators\")\nprint (x)\nx=+5 # x = x+5\nprint (x)\nx=-5 # x = x-5\nprint (x)\nx*=5 # x = x*5\nprint (x)\nx/=5 # x = x/5\nprint (x)\nx%=5 # x = x%5\nprint (x)\nx//=5 # x = x//5\nprint (x)\nx**5 # x= x**5\nprint (x)\nprint (\"\\n\")\n\n# Comparison Operatos #\nx= 10\ny= 20\nprint (\"Comparison Operatos\")\nprint (x==y) # Equal \nprint (x!=y) # Not Equal \nprint (x<y) # Less Than\nprint (x>y) # Greater Than\nprint (x<=y) # Less or Equal \nprint (x>=y) # Greater or Equal \nprint (\"\\n\")\n\n# Logical Operatos #\nx=1\ny=2\nprint (\"Logical Operators\")\nprint (x==y and x<=y) # Both conditions must be true, otherwise is False\nprint (x==y or x<=y) # Juts one condition must be true\nprint (not(x==y and x<=y)) # It changes the result, if is True changes to False, and vice-versa\nprint (\"\\n\")\n\n#  Identity Operators #\nx=2\ny=1\nprint (\"Identity Operators\")\nprint (x is y) # It returns true if both are the same, otherwise is false\nprint (x is not y) # It returns true if both are not the same \nprint (\"\\n\")\n\n# Member Operators #\nvar1= \"Python\"\nvar2= \"Hello\"\n\nprint (\"Member Operators\")\nprint (\"o\" in var1) # It returns true if the value is presented, otherwise is false\nprint (\"a\" not in var2) # It returns true if the value is not presented, otherwise is ture\nprint (\"\\n\")\n\n\n# Challenge #\n\"\"\"\nCrea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3\n\"\"\"\n\nprint (\"CHallenge\")\nfor x in range(10, 56):\n    if x%2==0 and x != 16 and x % 3 != 0:\n        print (x, end=' ')\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/ETrauco.py",
    "content": "# #01 OPERADORES Y ESTRUCTURAS DE CONTROL\n\n\"\"\"\n1.\n - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n\"\"\"\n\n'''# OPERADORES ARITMÉTICOS'''\n\na = 4\nb = 6\n\nprint(a + b) # suma\nprint(a - b) # resta\nprint(a * b) # multiplicación\nprint(a / b) # división\nprint(a // b) # división entera\nprint(a % b) # Môdulo, devuelve el resto de la división\nprint(a ** b) # Elevado a...\nprint(-a) # Negación, cambiar el valor positivo o negativo \n\n# ==================================================================\n\n'''OPERADORES LÓGICOS'''\n# Utlizados para combinar o invertir expresiones condicionales (booleanos)\n\na = True\nb = False\nx = 10\n\n#AND (Y lógico)\nprint(a and b) # imprime False\n\n#Ejemplo\nprint(x > 5 and x < 20) # True\nprint(x < 11 and x != 10) # False\n\n#=================================\n#OR (O lógico)\nprint( a or b) # Imprime True\nprint(x < 5 or x > 8) # True\n\n#=================================\n#NOT (Negación lógica)\nprint(not a) # False\nprint(not(x > 5)) # False\n\n#===============================================\n\n'''OPERADORES DE COMPARACIÓN'''\n\n# IGUAL A...\na = 5\nb = 12\nprint(a == b) # False\n\n# DISTINTO DE...\nprint(a != b) # True\n\n# MAYOR QUE...\nprint( a > b) # False\n\n# MENOR QUE...\nprint(a < b) # True\n\n# MAYOR O IGUAL QUE...\nprint(a >= b) # False\n\n# MENOR O IGUAL QUE...\nprint(a <= b) # True\n\n#=====================================\n'''OPERADORES DE ASIGNACIÓN'''\n\n# Asignaciôn simple\nx = 20\n\n# Suma y asigna\nx += 1\nprint(x) # 4\n\n# Resta y asigna\nx -= 2\nprint(x)\n\n# Multiplica y asigna\nx *= 5\nprint(x)\n\n# Divide y asigna\nx /= 2\nprint(x)\n\n#División entera y asigna\nx //= 2\nprint(x)\n\n# Módulo y asigna\nx %= 5\nprint(x)\n\n# Potencia y asigna\nx **= 4\nprint(x)\n\n#========================================\n\n'''Operadores Bit a Bit'''\nc = 5 # 0101\nd = 3 # 0011\n\n# AND bit a bit; devuelve 1 solo si ambos bits son 1.\nprint(c & d) \n\n# OR bit a bit; devuelve 1 si al menos uno de los bits es 1.\nprint(c | d)\n\n# XOR bit a bit; devuelve 1 solo so los bits son diferentes\nprint(c ^ d)\n\n#NOT bit a bit; invierte todos los bits de un número.\nprint(~c) \n\n# Desplazamiento a la izquierda; desplaza los bits de un número hacia la izq, añadiendo ceros al final.\nprint(c << 1)\n\n# Desplazamiento a la derecha; desplaza los bits de un número a la derecha, descartando los bits finales.\nprint(c >> 1)\n\n#=======================================================\n\n'''OPERADORES DE MEMBRESÍA'''\n\n# IN; devuelve True si el elemento está en la secuencia\n\nmi_lista = [1, 2, 3, 4]\nprint(3 in mi_lista) # True\n\ntexto = \"Python\"\nprint(\"Py\" in texto) # True\n\n# NOT IN; devuelve True si el elemento NO está en la secuencia\n\nprint(5 not in mi_lista) # True\nprint(\"Java\" not in texto) # True\n\n#=========================================================\n\n'''OPERADORES DE INDENTIDAD'''\n\n# IS; Devuelve True si dos variables apuntan al mismo objeto\n\na = [1, 2, 3]\nb = a\nc = [1, 2, 3]\n\nprint(a is b) # True\nprint(a is c) # False, son objetos diferentes, aunque iguales\n\n# IS NOT; Devuelve True si dos variables NO apuntan al mismo objeto\n\nprint(a is not c)\n\n#===========================================================\n\n'''OPERADORES ESPECIALES'''\n\n# OPERADOR TERNARIO (Condicional en una línea)\n# forma compacta de escribir condiciones\n\nx = 10\ny = 20\nmayor = x if x > y else y \nprint(mayor) # 20\n\n# OPERADOR LAMBDA (Función anónima)\n# Define una función en una sola línea\n\nsuma = lambda x, y: x + y\nprint(suma(5, 3)) # 8\n\nes_par = lambda x: \"Par\" if x % 2 == 0 else \"Impar\"\nprint(es_par(10)) # Par\n\n#==================================================\n\n'''ESTRUCTURAS DE CONTROL'''\n\n# CONDICIONALES IF, ELIF, ELSE\n\nnum = 10\n\nif num % 2 == 0:\n    print(f\"{num} es un número par.\")\nelif num > 10:\n    print(f\"{num} es mayor que 10.\")\nelse:\n    print(f\"{num} es impar o menor que 10.\")\n\n# ESTRUCTURAS ITERATIVAS\n\n# FOR\nfor i in range(1,6):\n    print(f\"El cuadrado de {i} es {i **2}\")\n\n# WHILE\n\nn = 0\nlimite = 5\n\nwhile n <= limite:\n    print(f\"n = {n}\")\n    n += 1\n\n# EXCEPCIONES TRY, EXCEPT, ELSE, FINALLY\n\ntry:\n    resultado = 10 / 0 # generará una excepción \nexcept ZeroDivisionError as e:\n    print(\"Error: División por cero no permitida.\")\nelse:\n    print(f\"El resultado es {resultado}\")\nfinally:\n    print(\"Bloque finally ejecutado.\")\n\n# COMPREHENSIONS (estructura de control implícita en Python)\n\n# lista de números pares utilizando if dentro de una lista\nnumeros = [x for x in range(10) if x % 2 == 0]\nprint(numeros) # salida: [0, 2, 4, 6, 8]\n\n# lista con una operación utilizando FOR y CONDICIONALES\n#(lista con cuadrados de números pares y un mensaje para impares)\nresultado = [x ** 2 if x % 2 == 0 else \"Impar\" for x in range (1, 6)]\nprint(resultado) # salida: ['Impar', 4, 'Impar', 16, 'Impar']\n\n# OPERADORES DENTRO DE FUNCIONES\n# Función con operadores aritméticos\ndef calcular_area(base, altura):\n    return base * altura / 2\n\narea = calcular_area(10, 5)\nprint(f\" El área del triángulo es: {area}\")\n\n# Función con operadores lógicos\ndef es_mayor_de_edad(edad):\n    return edad >= 18\n\nprint(es_mayor_de_edad(20))\nprint(es_mayor_de_edad(16))\n\n#===================================================\n\n'''EJERCICIO EXTRA\n\n * Crea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n'''\n\nfor numero in range(10, 56):\n    if numero % 2 == 0 and numero != 16 and numero % 3 != 0:\n        print(numero)\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Elbam.py",
    "content": "# operadores basicos\naritmeticos=5+12-2*1/1\ncaracter=\" de\"+\" operadores\"+\" caracteres\"\nimprime2= \"Ejemplo {}, ejemplo aritmetico {}\".format(caracter, aritmeticos)\nimprime=f\"Ejemplo {caracter}, ejemplo aritmetico {aritmeticos}\"\n\nprint (imprime)\nprint(imprime2)\nprint(f\"Ejemplo modulo {11 % 3}\")\nprint(f\"Ejemplo exponencial {15 ** 3}\")\nprint(f\"Ejemplo div entera {11 // 3}\")\n\n# otros operadores\nprint(f\"Ejemplo comparacion {'a' == 'b'}\")\nnum1=10\nnum2= 11\nprint (f\"Ejemplo de desplazamiento bit {num1 >> num2 }\" )\n\nuno=3\ndos=3\ntres=4\nprint (f\"Ejemplo de operador identidad {uno is dos}\")\n#Un operador de identidad se emplea para comprobar si dos variables emplean la misma ubicación en memoria.\n\nl1=[10,20,30]\nl2=[10,20,30]\nprint (f\"Ejemplo de operador identidad en Listas {l1 is l2}\")\n\nt1=(1, 2.5, \"prueba\")\nt2=(1, 2.5, \"prueba\")\nprint (f\"Ejemplo de operador identidad en Tuplas {t1 is t2}\")\n#Tuplas soninmutables\n\nprint (f\"Ejemplo de operador de pertenencia {'u' in 'universida'}\")\n\n# Estructuras de Control \n\nif aritmeticos > 15:\n    print (\"es mayor a 15\")\nelif aritmeticos < 10:\n   print (\"es menor a 10\")\nelse:\n    print (\"es otro numero\")\n    \nnumeroletras=0\nwhile numeroletras <= 10:\n     print (numeroletras) \n     numeroletras += 1\n\nfor l in l1:\n    print (l)     \n\nfor t in t1:\n    print (t)     \n\n# try\n\ntry:\n    print (10 /0)\nexcept:\n    print (\" se produce un error\")\nfinally:\n    print ( \" se ha ejeuctado el manejo de error\")     \n\n# Dificultad Extra \n \ninicial=10\nultimo= 55       \nnegado=16\n\nwhile inicial <= ultimo:\n    if  (inicial % 2) == 0  :\n        if  (inicial % 3 ) == 0 :\n            if inicial != negado :\n                print (inicial)\n    inicial += 1\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/EliasBonnin.py",
    "content": "# Ejercicio 01\n# En el siguiente URL https:/python.org Tenemos la documentacion de phyton\n# Los retos se encuentran en https://retosdeprogramacion.com\n\n# Tipo de operadores de Lenguaje *Aritmenticos*\n\n# Variables para uso Aritmetico\n\n\nmy_suma = 0\nmy_resta = 0\nmy_multiplicacion = 0\nmy_division = 0\nmy_modulo = 0\nmy_exponencial = 0\nmy_division_entera = 0\n\nmy_variable_1 = 10\nmy_variable_2 = 5\nmy_variable_3 = 2\n\nmy_suma = my_variable_1 + my_variable_2  # Suma de dos variables\nmy_resta = my_variable_1 - my_variable_2  # Resta de dos variables\nmy_multiplicacion = my_variable_1 * my_variable_2  # Multiplicacion de dos variables\nmy_division = my_variable_1 / my_variable_2  # Division de dos variables\nmy_modulo = my_variable_1 % my_variable_2  # Modulo de dos variables\nmy_exponencial = my_variable_1**my_variable_2  # Exponencial de dos variables\nmy_division_entera = my_variable_1 // my_variable_2  # Division entera de dos variables\n\nprint(f\"el valor de la suma es {my_suma}\")\nprint(f\"el valor de la resta es {my_resta}\")\nprint(f\"el valor de la multiplicacion es {my_multiplicacion}\")\nprint(f\"el valor de la division es {my_division}\")\nprint(f\"el valor del modulo es {my_modulo}\")\nprint(f\"el valor de la exponencial es {my_exponencial}\")\nprint(f\"el valor de la division entera es {my_division_entera} \\n\")\n\n# Tipo de operadores de Lenguaje de *Asignacion*\n\n# Variables para uso de Asignacion\n\n\nmy_asig_suma = 0\nmy_asig_resta = 0\nmy_asig_multiplicacion = 0\nmy_asig_division = 0\nmy_asig_modulo = 0\nmy_asig_exponencial = 0\nmy_asig_division_entera = 0\n\nmy_asig_variable_1 = 10\nmy_asig_variable_2 = 5\nmy_asig_variable_3 = 2\n\nmy_asig_suma = 10\nmy_asig_suma += 5  # Asignacion de suma\n\nmy_asig_resta = 5\nmy_asig_resta -= 2  # Asignacion de resta\n\nmy_asig_multiplicacion = 2\nmy_asig_multiplicacion *= 5  # Asignacion de multiplicacion\n\nmy_asig_division = 10\nmy_asig_division /= 5  # Asignacion de division\n\nmy_asig_modulo = 10\nmy_asig_modulo %= 5  # Asignacion de modulo\n\nmy_asig_exponencial = 10\nmy_asig_exponencial **= 5  # Asignacion de exponencial\n\nmy_asig_division_entera = 10\nmy_asig_division_entera //= 5  # Asignacion de division entera\n\nprint(f\"my asing suma es {my_asig_suma}\")\nprint(f\"my asing resta es {my_asig_resta}\")\nprint(f\"my asing multiplicacion es {my_asig_multiplicacion}\")\nprint(f\"my asing division es {my_asig_division}\")\nprint(f\"my asing modulo es {my_asig_modulo}\")\nprint(f\"my asing exponencial es {my_asig_exponencial}\")\nprint(f\"my asing division entera es {my_asig_division_entera} \\n\")\n\n# Tipo de operadores de Lenguaje de *Comparacion*\n\n# Variables para uso de Comparacion\n\nmy_comp_variable_1 = 10\nmy_comp_variable_2 = 5\nmy_comp_variable_3 = 2\nmy_comp_variable_4 = 10\n\nif my_comp_variable_1 == my_comp_variable_4:\n    # Comparacion de igualdad\n    print(f\"{my_comp_variable_1} es igual a {my_comp_variable_4}\")\n\nif my_comp_variable_2 != my_comp_variable_3:\n    # Comparacion de desigualdad\n    print(f\"{my_comp_variable_2} es diferente a {my_comp_variable_3}\")\n\nif my_comp_variable_4 > my_comp_variable_3:\n    # Comparacion mayor que\n    print(f\"{my_comp_variable_4} es mayor que {my_comp_variable_3}\")\n\nif my_comp_variable_4 < my_comp_variable_3:\n    print(\"Esto no se cumpliria\")\nelse:\n    # Comparacion menor que\n    print(f\"{my_comp_variable_4} es mayor que {my_comp_variable_3}\")\n\nif my_comp_variable_4 < my_comp_variable_3:\n    print(\"Esto no se cumpliria\")\nelif my_comp_variable_4 <= my_comp_variable_3:\n    print(\"Esto no se cumpliria\")\nelif my_comp_variable_4 >= my_comp_variable_3:\n    # Comparacion menor o igual que\n    print(f\"{my_comp_variable_4} es mayor que {my_comp_variable_3} \\n\")\nelse:\n    print(\"Esto no se cumpliria\")\n\n# Tipo de operadores de Lenguaje de *Logicos*\n\nmy_log_varaible_1 = True\n\nif my_comp_variable_1 == my_comp_variable_4 or my_comp_variable_2 == my_comp_variable_3:\n    # Comparacion de igualdad\n    print(f\"{my_comp_variable_1} es igual a {my_comp_variable_4}\")\n    print(f\"o {my_comp_variable_2} es igual a {my_comp_variable_3}\")\n\nif not my_log_varaible_1:\n    print(\"Vacio\")\nelse:\n    print(\"No es vacio\")  # Comparacion de negacion\n\n\n# Utilizacion de estructuras de control.\n\n# Estructura de control IF-ELIF-ELSE\n\nmy_if_variable_1 = 10\nmy_if_variable_2 = 5\n\nif my_if_variable_1 != my_if_variable_2:  # Comparacion de desigualdad\n    print(f\"{my_if_variable_1} es diferente a {my_if_variable_2}\")\nelif my_if_variable_1 > my_if_variable_2:\n    print(f\"{my_if_variable_1} es mayor que {my_if_variable_2}\")\nelse:\n    print(f\"{my_if_variable_1} es igual a {my_if_variable_2}\")\n\n\n# Estructura de control WHILE\n\nmy_while_variable_1 = 10\nmy_while_variable_2 = 5\nmy_while_variable_3 = 0\n\nwhile my_while_variable_1 > my_while_variable_2:\n    print(f\"{my_while_variable_1} es mayor que {my_while_variable_2}\")\n    my_while_variable_2 += 1  # Incremento de la variable 2\n\nfor i in range(1, 6):\n    print(i)  # Estructura de control FOR\n\n\nfor i in range(1, 6):\n    if i == 3:\n        break  # Rompe el ciclo cuando i es igual a 3\n    print(i)  # Estructura de control FOR con break\n    if i == 2:\n        continue\n\n\n# Extra\n\nfor i in range(10, 56):\n    if (i % 2 == 0 and i != 16 and i % 3 != 0) or i == 55:\n        print(i)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Eliskopun.py",
    "content": "#                   Operadores de mi lenguaje:\n\n#   Aritmeticos\na = 28\nb = 11\nprint(\"Suma:\", a + b)\nprint(\"Resta:\", a - b)\nprint(\"Multiplicación:\", a * b)\nprint(\"División:\", a / b)\nprint(\"Resto:\", a % b)\nprint(\"Potenciación:\", a ** b)\nprint(\"División entera:\", a // b)\n\n#   Relacional\nprint(f\"{a} es mayor que {b}:\", a > b)\nprint(f\"{a} es menor que {b}:\", a < b)\nprint(f\"{a} es igual que {b}:\", a == b)\nprint(f\"{a} es distinto que {b}:\", a != b)\nprint(f\"{a} es mayor o igual que {b}:\", a >= b)\nprint(f\"{a} es menor o igual que {b}:\", a <= b)\n\n#   Lógicos\na = True\nb = False\nprint(\"AND lógico:\", a and b)  \nprint(\"OR lógico:\", a or b)  \nprint(\"NOT lógico:\", not a)\na = 28 # regreso a valor de entero inicial\nb = 11 # regreso b valor de entero inicial\n\n\n#   Bit a Bit\nprint(\"AND a nivel de bit:\", a & b)\nprint(\"OR a nivel de bit:\", a | b)\nprint(\"XOR a nivel de bit:\", a ^ b)\nprint(\"NOT a nivel de bit:\", ~a)\nprint(\"Desplazamiento a la izquierda:\", b << 2)\nprint(\"Desplazamiento a la derecha:\", a >> 2)\n\n#   Asignación\nprint(\"Asignación de igualdad: a =\", a)\na += 2\nprint(\"Asignación de suma:\", a)\na -= 2\nprint(\"Asignación de resta:\", a)\na *= 2\nprint(\"Asignación de multiplicación:\", a)\na /= 2\nprint(\"Asignación de división:\", a)\na %= 2\nprint(\"Asignación de resto:\", a)\na **= 2\nprint(\"Asignación de potenciación:\", a)\na //= 2\nprint(\"Asignación de división entera:\", a)\na = 28 #restauro el valor inicial de a\na &= 2 \nprint(\"AND bit a bit con asignación:\", a)\na |= 2\nprint(\"OR bit a bit con asignación:\", a)\na^= 2\nprint(\"XOR bit a bit con asignación:\", a)\na>>= 2\nprint(\"Desplazamiento a la derecha con asignación:\", a)\na<<= 2\nprint(\"Desplazamiento a la izquierda con asignación:\", a)\n\n#   Pertenencia\na = [1, 2, 3]\nprint(\"¿1 pertenece en a?\", 1 in a)\nprint(\"¿3 no pertenece en a?\", 3 not in a)\ntexto = \"Gracias al curso de Git/Github puedo participar sin saber programar :)\"\nresultado = \"participar\" in texto\nprint(resultado)\nresultado_2 = \"gracias\" in texto\nprint(resultado_2) # Toma en cuenta mayusculas y minisculas por eso da falso\nresultado_3 = \"Eres grandioso Moure\" not in texto\nprint(resultado_3)\n\n#   Identidad\na = [1, 2, 3]\nb = a\nc = 4\nprint(f\"{a} es identico a {b}:\", a is b)\nprint(f\"{a} no es identico {c}:\", a is not c)\n\n\n#                   Estructuras de control:\n\n#   Condicionales\na = 11 # me encantan\nb = 28 # estos numeros\nif a > b:\n    print(\"a es mayor que b\")\nelif a == b:\n    print(\"a es igual que b\")\nelse:\n    print(\"a es menor que b\")\n    \n#   Bucle for (iterativas)\nfor i in range(5):\n    print(\"Bucle for, iteración:\", i)\n\n#   Bucle while\nwhile a > 0:\n    print(\"Bucle while, valor de a:\", a)\n    a -= 1\n    \n#   Excepciones\ntry:\n    resultado = 10 / 0\nexcept:\n    print(\"Error: División por cero!\")\nfinally:\n    print(\"Bloque finally ejecutado\")\n\n\n#   Extra\nfor nrs in range(10,56,2):\n    if nrs != 16 and nrs % 3 != 0:\n        print(nrs)\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/EmmanuelMMontesinos.py",
    "content": "\"\"\"\r\n * EJERCICIO:\r\n * X) Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\r\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\r\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\r\n * x) Utilizando las operaciones con operadores que tú quieras, crea ejemplos\r\n *   que representen todos los tipos de estructuras de control que existan\r\n *   en tu lenguaje:\r\n *   Condicionales, iterativas, excepciones...\r\n * 3) Debes hacer print por consola del resultado de todos los ejemplos.\r\n *\r\n * DIFICULTAD EXTRA (opcional):\r\n * Crea un programa que imprima por consola todos los números comprendidos\r\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\r\n\"\"\"\r\n\r\n\"\"\"Operador aritméticos:\"\"\"\r\n\r\n# Suma\r\nvariable = 1 + 1\r\n\r\n# Resta\r\nvariable = 1 - 1\r\n\r\n# Multiplicación\r\nvariable = 1 * 1\r\n\r\n# División\r\nvariable = 1/1\r\n\r\n# División Entera\r\nvariable = 1//1\r\n\r\n# Resto de la División\r\nvariable = 1 % 1\r\n\r\n# Potencia\r\nvariable = 1**1\r\n\r\n\"\"\"Operador de asignación:\"\"\"\r\n\r\n# Asignación\r\nvariable = 0\r\n\r\n# Asignación con suma\r\nvariable += 1\r\n\r\n# Asignación con resta\r\nvariable -= 1\r\n\r\n# Asignación con multiplicación\r\nvariable *= 1\r\n\r\n# Asignación con división\r\nvariable /= 1\r\n\r\n# Asignación con división entera\r\nvariable //= 1\r\n\r\n# Asignación con resto de división\r\nvariable %= 1\r\n\r\n# Asignación con potencia\r\nvariable **= 1\r\n\r\n\"\"\"Operadores de comparación\"\"\"\r\n# Igual que\r\nvariable == 1\r\n\r\n# No igual que\r\nvariable != 1\r\n\r\n# Mayor que\r\nvariable > 1\r\n\r\n# Menor que\r\nvariable < 1\r\n\r\n# Mayor o igual que\r\nvariable >= 1\r\n\r\n# Menor o igual que\r\nvariable <= 1\r\n\r\n\"\"\"Operadores lógicos\"\"\"\r\n# AND (esto y esto)\r\nvariable is 1\r\n\r\n# OR (esto o esto)\r\nvariable or 1\r\n\r\n\"\"\"Operadores de identidad\"\"\"\r\n# Es\r\nvariable is str\r\n\r\n# No es\r\nvariable is not int\r\n\r\n\"\"\"Operadores de pertenencia\"\"\"\r\nlist_variables = []\r\n# Esta en\r\nvariable in list_variables\r\n\r\n# No esta en\r\nvariable not in list_variables\r\n\r\n\"\"\"Operadores de bits\"\"\"\r\n# AND (si ambos bits son 1)\r\n1 & 1\r\n\r\n# OR (mientras alguno sea 1)\r\n1 | 1\r\n\r\n# XOR (si solo hay 1)\r\n1 ^ 1\r\n\r\n# Desplaza bit a la izquierda\r\n1 << 1\r\n\r\n# Desplaza bit a la derecha\r\n1 >> 1\r\n\r\n\"\"\"Estructuras de control\"\"\"\r\na = 1\r\nb = 2\r\nc = 3\r\nd = 4\r\ne = 5\r\nlista = [a, b, c]\r\n\r\n# Condicionales\r\nif a < b:\r\n    print(b)\r\nelif a > b:\r\n    print(a)\r\nelse:\r\n    print(f\"{a} y {b} son iguales\")\r\n\r\n# Itinerables\r\nfor data in lista:\r\n    print(data)\r\n\r\n# Bucle condicional\r\nwhile d not in lista:\r\n    lista.append(d)\r\n    print(f\"{d} añadido a lista\")\r\n\r\n# Control de bucles/condicionales\r\nwhile a < 10:\r\n    if a == 1:\r\n        a += 1\r\n        pass\r\n    elif e not in lista:\r\n        a *= 2\r\n        lista.append(e)\r\n        print(\"continua el bucle\")\r\n        continue\r\n    else:\r\n        print(\"cerrando bucle\")\r\n        break\r\n\r\n# Excepciones\r\ntry:\r\n    print(\"hola\" + True)\r\nexcept TypeError as e:\r\n    print(e)\r\nelse:\r\n    print(\"No hubo fallos\")\r\nfinally:\r\n    print(\"Fin de la Gesntion de Excepciones\")\r\n\r\n\"\"\"Ejercicio Extra\"\"\"\r\nlista_numeros = [number for number in range(\r\n    1, 56) if number >= 10 and number % 3 != 0 and number % 2 == 0 and number != 16 or number == 55]\r\nprint(lista_numeros)\r\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/EricJoel-code.py",
    "content": "# Operadores aritméticos\n\nprint(10+3)#Suma\nprint(10-3)#Resta\nprint(10*3)#Multiplicación\nprint(10/3)#División\nprint(10//3)#División entera\nprint(10%3)#Módulo\nprint(10**3)#Exponente\n\n# Operadores de comparación\n\nprint(10==3)#Igualdad\nprint(10!=3)#Desigualdad\nprint(10>3)#Mayor que\nprint(10<3)#Menor que\nprint(10>=3)#Mayor o igual que\nprint(10<=3)#Menor o igual que\n\n#Operadores logicos\n\nprint(10>3 and 5<2)#AND\nprint(10>3 or 5<2)#OR\nprint(not(10>3))#NOT\n\n#Operadores de asignación\n\nnum = 10 #asignación\nprint(num)\nnum += 5 #asignación con suma\nprint(num)\nnum -= 3 #asignación con resta\nprint(num)\nnum *= 2 #asignación con multiplicación\nprint(num)\nnum /= 4 #asignación con división\nprint(num)\nnum //= 2 #asignación con división entera\nprint(num)\nnum **= 2 #asignación con exponente\nprint(num)\nnum %= 3 #asignación con módulo\nprint(num)\n\n# Operadores de identidad \n\nnum2 = 10\nprint(num is num2) # Identidad\nprint(num is not num2) # No identidad\n\n# Operadores de pertenencia\n\nprint(num in [1, 2, 3, 4, 5]) # Pertenece\nprint(num not in [1, 2, 3, 4, 5]) # No pertenece\n\n# Operadores bit a bit\nprint(10 & 3) # AND bit a bit\nprint(10 | 3) # OR bit a bit\nprint(10 ^ 3) # XOR bit a bit\nprint(~10)    # NOT bit a bit\nprint(10 << 2) # Desplazamiento a la izquierda\nprint(10 >> 2) # Desplazamiento a la derecha\n\n#Estructuras de control\n\n#Condicionales\n\nnum3 = 11\nif num3 > 10:\n    print(\"El numero es mayor que 10\")\nelif num3 == 10:\n    print(\"El numero es igual a 10\")\nelse:\n    print(\"El numero es menor que 10\")\n    \n# Iterativas\n\nfor i in range(5):\n    print(\"Iteracion:\", i)\n    \nvalor = 0\n\nwhile valor < 5:\n    print(valor)\n    valor += 1\n\n# Manejo de excepciones\ntry:\n    print(10/0)\nexcept ZeroDivisionError:\n    print(\"Error: Division por cero no permitida.\")\n    \n#Extra\nfor number in range(10,56):\n    if number % 2 ==0 and number != 16 and number % 3 == 0:\n        print(number)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/EriickM.py",
    "content": "#Operadores Aritméticos:\nprint(f'suma            = {4 + 6}')\nprint(f'resta           = {8 - 4}')\nprint(f'multiplicacion  = {12 * 3}')\nprint(f'division        = {12 / 4}')\nprint(f'modulo          = {36 % 3}')\nprint(f'potencia        = {2**4}')\nprint(f'division_entera = {36//3}')\nprint(f'\\n')\n\n# Operadores de Comparación:\nprint(f'2 es igual que 2         = {2==2}')\nprint(f'\"A\" es distinto que \"B\"  = {\"A\"!=\"B\"} ')\nprint(f'8 es menor que 10        = {8<10}')\nprint(f'8 es mayor que 10        = {8>10}')\nprint(f'20 es menor o igual a 20 = {20<=20}')\nprint(f'20 es mayor o igual a 20 = {12>=20}')\nprint(f'\\n')\n\n# Operadores Lógicos:\nprint(f'Solo sera True cuando ambas condiciones sean verdad : {2==2 and 3<1}')\nprint(f'Sera True cuando alguna condicion sean verdad       : {2==2 or 3<1}')\nprint(f'Negara el cualquier valor boleano                   : {2==2 and not(3<1)}')\nprint(f'\\n')\n\n# Operadores de Pertenencia:\nprint(f'Sera True cuando \"A\" PERTENESCA al conjunto de datos [A,B,C,D,E]    : {\"A\" in [\"A\",\"B\",\"C\",\"D\"]}')\nprint(f'Sera True cuando \"A\" NO PERTENESCA al conjunto de datos [A,B,C,D,E] : {\"A\" not in [\"A\",\"B\",\"C\",\"D\"]}')\nprint(f'\\n')\n\n# Operadores de Identidad:\nprint(f'El valor 3 es 3 :{3 is 3}')\nprint(f'El valor 3 es 3 :{3 is not [3]}')\nprint(f'\\n')\n# Estructuras de Control de Flujo:\n\n# if-elif-else:\na = 20\nb = 1\nc = 3\nd = 0\nif b > a:\n      print('Si el valor B es mayor que A')\nelif a//c == 0:\n      print(f'Sino entonce El valor {c}, es un dividendo de {a}')\nelse:\n      print('Entonce ninguna condicion cumplida')\nprint(f'\\n')\n# Bucles:\n\n# for: \nfor d in range(5):\n      if d > c:\n            print(f'Se termina en {d}')\n            break\n      else:\n            print(d)\n            continue\n\nprint(f'\\n')\n# while\nwhile True:\n      try:\n            resultado = d / a\n            if (resultado == 0.3):\n                  break\n            print(f'El resultado es {resultado}')\n      except:#Se ejecuta en cualquiera de los dos casos \n            print('Division no posible')\n      finally: #Se ejecuta en cualquiera de los dos casos \n            d = d + 1\n            print('Ya terminanos')\n# Expresión Ternaria:\nprint(f'\\n')\nprint(f'Esta es una operacion ternaria como un if pero con una estructura de una linea {\"Si es verdad\" if 2 > 5 else \"Si es Falso\" }')"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/EspinoLeandroo.py",
    "content": "#%% Operadores --------------------------------------------------\nprint(\"Operadores --------------------------------------------------\")\n#%% Aritméticos\nprint(\"Aritméticos\")\na = 10\nb = 3\n\nsuma = a + b\nresta = a - b\nmultiplicacion = a * b\ndivision = a / b\nmodulo = a % b\nexponente = a ** b\ndivision_entera = a // b\n\nprint(\"Suma:\", suma)\nprint(\"Resta:\", resta)\nprint(\"Multiplicación:\", multiplicacion)\nprint(\"División:\", division)\nprint(\"Módulo:\", modulo)\nprint(\"Exponente:\", exponente)\nprint(\"División Entera:\", division_entera)\n\n#%% Lógicos\nprint(\"Lógicos\")\nx = True\ny = False\n\nand_result = x and y\nor_result = x or y\nnot_result = not x\n\nprint(\"AND:\", and_result)\nprint(\"OR:\", or_result)\nprint(\"NOT:\", not_result)\n\n#%% De comparación\nprint(\"De comparación\")\nc = 5\nd = 10\n\nigual = c == d\ndiferente = c != d\nmayor = c > d\nmenor = c < d\nmayor_igual = c >= d\nmenor_igual = c <= d\n\nprint(\"Igual:\", igual)\nprint(\"Diferente:\", diferente)\nprint(\"Mayor:\", mayor)\nprint(\"Menor:\", menor)\nprint(\"Mayor o Igual:\", mayor_igual)\nprint(\"Menor o Igual:\", menor_igual)\n\n#%% Asignación\nprint(\"Asignación\")\ne = 5\ne += 2  # Equivalente a: e = e + 2\nprint(\"Asignación con Suma:\", e)\n\n#%% Identidad\nprint(\"Identidad\")\nf = [1, 2, 3]\ng = [1, 2, 3]\nh = f\n\nidentidad1 = f is g\nidentidad2 = f is h\nno_identidad = f is not g\n\nprint(\"Identidad 1:\", identidad1)\nprint(\"Identidad 2:\", identidad2)\nprint(\"No Identidad:\", no_identidad)\n\n#%% Pertenencia\nprint(\"Pertenencia\")\nlista = [1, 2, 3, 4, 5]\n\npertenencia1 = 3 in lista\npertenencia2 = 6 not in lista\n\nprint(\"Pertenencia 1:\", pertenencia1)\nprint(\"Pertenencia 2:\", pertenencia2)\n\n#%% Bits\nprint(\"Bits\")\nbitwise_and = a & b\nbitwise_or = a | b\nbitwise_xor = a ^ b\nbitwise_not = ~a\nbitwise_left_shift = a << 2\nbitwise_right_shift = a >> 1\n\nprint(\"Bitwise AND:\", bitwise_and)\nprint(\"Bitwise OR:\", bitwise_or)\nprint(\"Bitwise XOR:\", bitwise_xor)\nprint(\"Bitwise NOT:\", bitwise_not)\nprint(\"Bitwise Left Shift:\", bitwise_left_shift)\nprint(\"Bitwise Right Shift:\", bitwise_right_shift)\n\n#%% Estructuras de Control: -----------------------------------\nprint(\"Estructuras de Control: -----------------------------------\")\n\n#%% Condicionales\nprint(\"Condicionales\")\nnumero = 15\n\nif numero > 10:\n    print(\"El número es mayor que 10\")\nelif numero < 10:\n    print(\"El número es menor que 10\")\nelse:\n    print(\"El número es igual a 10\")\n\n#%% Iterativas\nprint(\"Iterativas\")\nfor i in range(5):\n    print(i)\n\nwhile numero > 0:\n    print(numero)\n    numero -= 1\n\n#%% Excepciones\nprint(\"Excepciones\")\ntry:\n    resultado = 10 / 0\nexcept ZeroDivisionError:\n    print(\"Error: División por cero\")\nfinally:\n    print(\"Este bloque siempre se ejecutará\")\n\n#%% Opcional --------------------------------------------------\nprint(\"Opcional --------------------------------------------------\")\nfor numero in range(10, 56):\n    if numero % 2 == 0 and numero != 16 and numero % 3 != 0:\n        print(numero)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/ExanderGuitar.py",
    "content": "# Operadores aritméticos\n# Suma\nx = 20\ny = 5\nsuma = x + y\nprint(suma)\n\n# Resta\nresta = x - y\nprint(resta)\n\n# Multiplicación\nmultiplicacion = x * y\nprint(multiplicacion)\n\n# División\ndivision = x / y\nprint(division)\n\n# Módulo\nmodulo = x % y\nprint(modulo)\n\n# Potencia\npotencia = x ** y\nprint(potencia)\n\n# División con resultado entero\ndivsion_entera = x // y\nprint(divsion_entera)\n\n# Operaciones relacionales\n# Mayor que\nmayor = x > y\nprint(mayor)\n\n# Menor que\nmenor = x < y\nprint(menor)\n\n# Mayor o igual que\nmayor_igual = x >= y\nprint(mayor_igual)\n\n# Menor o igual que\nmenor_igual = x <= y\nprint(menor_igual)\n\n# Igual que\nigual = x == y\nprint(igual)\n\n# No igual\nno_igual = x != y\nprint(no_igual)\n\n# Operadores lógicos\n# Operador AND\noperador_and = 5 > 10 and 3 < 5\nprint(operador_and)\n\n# Operador OR\noperador_or = 5 > 10 or 3 < 5\nprint(operador_or)\n\n# Operador NOT\noperador_not = not 5 > 10\nprint(operador_not)\n\n# Operadores bit a bit\na = 0b0001\nb = 0b0101\n\n## Operador and\nprint(a & b)\n\n## Operador or\nprint(a | b)\n\n## Operador xor\nprint(a ^ b)\n\n## Operador not\nprint(~b)\n\n## Operador desplazamiento a la derecha\nprint(a >> b)\n\n## Operador desplazamiento a la izquierda\nprint(a << b)\n\n# Controles de flujo\n## Sentencia if\nif (5 > 3):\n    print(\"Funciona\")\n\nif (3 < 1):\n    print(\"Aqui no\")\nelse:\n    print(\"Aqui sí\")\n\nif (5 == 8):\n    print(\"Mmmm\")\nelif(2 == 2):\n    print(\"Yeah\")\nelse:\n    print(\"Hola?\")\n\nif True:\n    pass\n\n## Bucle for\nfor i in range(0, 5):\n    print(i)\n\nfor i in \"Python\":\n    print(i)\n\n## Bucle while\nj = 0\nwhile (j < 5):\n    print(j)\n    j += 1\n\n# Ejercicio extra\nfor i in range(10, 56):\n    if(i % 2 == 0):\n        if(i != 16 and i % 3 != 0):\n            print(i)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/FabianPA505.py",
    "content": "#---  OPERATORS  ---#\r\n\r\n# Arithmetic ( +, -, *, /, %, **, // )\r\noperand_1 = 10\r\noperand_2 = 7\r\nprint(f'Addition: {operand_1 + operand_2}')           # returns the sum\r\nprint(f'Subtraction: {operand_1 - operand_2}')        # returns the difference\r\nprint(f'Multiplication: {operand_1 * operand_2}')     # returns the product\r\nprint(f'Division: {operand_1 / operand_2}')           # returns the quotient (includes decimals)\r\nprint(f'Modulus: {operand_1 % operand_2}')            # returns the remainder\r\nprint(f'Power: {operand_1 ** operand_2}')             # returns the exponentiation\r\nprint(f'Floor division: {operand_1 // operand_2}')    # returns the integer quotient\r\n\r\n\r\n# Logical ( for boolean values ) -> AND, OR, NOT\r\nprint(True and True)        # returns True\r\nprint(True and False)       # returns False\r\nprint(True or False)        # returns True\r\nprint(not True)             # returns False\r\nprint(not False)            # returns True\r\nprint(not 0)                # zero is equivalent to False, returns True\r\nprint(not 1)                # one is equivalent to True, returns False\r\n\r\n\r\n# Comparison ( >, <, ==, >=, <=, !=, ) -> returns a boolean value\r\nprint(f'Greater than: {operand_1 > operand_2}')         # returns True\r\nprint(f'Less than: {operand_1 < operand_2}')            # returns False\r\nprint(f'Equal to: {operand_1 == operand_2}')            # returns False\r\nprint(f'Greater or equal: {operand_1 >= operand_2}')    # returns True\r\nprint(f'Less or equal: {operand_1 <= operand_2}')       # returns False\r\nprint(f'Not equal: {operand_1 != operand_2}')           # returns True\r\n\r\n\r\n# Assignment ( =, +=, -=, *=, /=, %=, **=, //= ) -> assign values to a variable\r\nx = 5\r\nprint(f'Variable x: {x}')\r\nx += 10 # equivalent to x = x + 10\r\nprint(f'Add 10 to variable x: {x}')\r\nx -= 10 # equivalent to x = x - 10\r\nprint(f'Subtract 10 from variable x: {x}')\r\nx *= 10 # equivalent to x = x * 10\r\nprint(f'Multiply variable x by 10: {x}')\r\nx /= 10 # equivalent to x = x / 10\r\nprint(f'Divide variable x by 10: {x}')\r\ny = 45\r\ny %= 10 # equivalent to y = y % 10\r\nprint(f'Modulus 10 with variable y: {y}')\r\ny **= 10\r\nprint(f'Power 10 to variable y: {y}')\r\ny //= 5\r\nprint(f'Floor division of variable y by 5: {y}')\r\n\r\n\r\n# Identity ( is, is not) -> check if two variables reference the same memory location\r\nx = 3\r\ny = 3\r\nz = 4\r\nprint(x is y)               # returns True\r\nprint(x is not y)           # returns False\r\nprint(x is z)               # returns False\r\nprint(x is not z)           # returns True\r\n\r\n\r\n# Membership ( in, not in) -> check if a value is in a sequence (lists, tuples, strings)\r\nnumbers = [1, 2, 3, 4, 5]\r\nprint(3 in numbers)          # returns True\r\nprint(15 not in numbers)     # returns True\r\n\r\ntext = 'Hello, how are you?'\r\nprint('how' in text)         # returns True\r\nprint('of' in text)          # returns False\r\nprint('He' in text)          # returns True\r\nprint('he' in text)          # returns False, case sensitive\r\n\r\n\r\n\r\n#---  CONTROL STRUCTURES ( Conditional, iterative, exception handling... )  ---#\r\n\r\n# CONDITIONAL\r\n# If, elif, else ( check if one or multiple conditions are met -> use comparison and logical operators)\r\ntotal_purchase = 120\r\n\r\nif total_purchase <= 100:\r\n    print('Pay with cash')\r\nelif 100 < total_purchase < 500:\r\n    print('Pay with debit card')\r\nelse:\r\n    print('Pay with credit card')\r\n\r\n\r\n# ITERATIVE\r\n# While ( perform an action while a condition is true. Stops when the condition is false)\r\ncount = 0\r\nwhile count <= 10:\r\n    print(count)\r\n    count += 1\r\n\r\n\r\n# For ( iterate over a collection - Lists or Tuples)\r\ncolors = ('green', 'red', 'yellow', 'blue', 'orange')\r\nfor color in colors:\r\n    print(color)\r\n\r\n\r\n# EXCEPTION HANDLING\r\nwhile True:\r\n    # exception control\r\n    try:\r\n        number = int(input('Enter a number: '))\r\n        break # if a valid number is entered, exit the loop\r\n    \r\n    # if an invalid input is entered, handle the error\r\n    except ValueError:\r\n        print('Error! Invalid input. Please try again.')\r\n\r\n\r\n#---  Extra Challenge  ---#\r\n# Use a For loop to iterate over the range and an If statement with comparison operators\r\nfor number in range(10, 56):\r\n    if number % 2 == 0 and number != 16 and number % 3 != 0:\r\n        print(number)\r\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/FabianRpv.py",
    "content": "# Tipos de Operadores\n\nnum1 = 5\nnum2 = 2\n\n#Operadores Aritmeticos:\n\nsuma = num1 + num2\nprint(f\"suma: {suma}\")\nresta = num1 - num2\nprint(f\"resta: {resta}\")\nmultiplicacion = num1 * num2\nprint(f\"multiplicacion: {multiplicacion}\")\ndivision = num1 / num2\nprint(f\"division: {division}\")\ndivision_entera = num1 // num2\nprint(f\"division entera: {division_entera}\")\nmodulo = num1 % num2\nprint(f\"modulo: {modulo}\")\npotencia = num1 ** num2\nprint(f\"potencia: {potencia}\")\n\n\n#Operadores Logicos:\n\nop_and = True and False\nprint(op_and)\nop_or = True or False\nprint(op_or)\nop_not = not True\nprint(op_not)\n\n#Operadores de Comparación:\n\nigualdad = 5 == 5\nprint(igualdad)\ndiferencia = 5 != 5\nprint(diferencia)\nmayor_que = 2 > 5\nprint(mayor_que)\nmenor_que = 2 < 5\nprint(menor_que)\nmayor_o_igual_que = 2 >= 2\nprint(mayor_o_igual_que)\nmenor_o_igual_que = 3 <= 2\nprint(menor_o_igual_que)\n\n\n#Operadores de Asignación:\n\nvalor = 5   #Asignacion Basica\nvalor += 2  #sumar y asignar\nvalor -= 2  #restar y asignar\nvalor *= 2  #multiplicar y asignar\nvalor /= 2  #dividir y asignar\nvalor //= 2  #dividir entero y asignar\nvalor %= 2  #mmodulo y asignar\nvalor **= 2  #potencia y asignar\n\n\n#Operadores de Identidad:\n\nnuevo_valor = valor\nprint(nuevo_valor is valor)\nprint(nuevo_valor is not valor)\n\n\n#Operadores de Pertenencia:\n\nprint('h' in 'hola')\nprint(\"h\" not in \"hola\")\n\n\n#Operadores Binarios:\n\nand_binario = num1 & num2 \nor_binario = num1 | num2 \nxor_binario = num1 ^ num2 \nnot_binario = ~num1 \nderecha_binario = num1 >> 1 \nizquierda_binario = num1 << 1 \n\n\n\n\n#Estructuras de Control\n\nedad = 21\n\n#Condicionales:\n\nif(edad < 0 or edad > 100):\n    print(\"Edad Invalida\")\nelif(edad < 18):\n    print(\"Eres menor de Edad\")\nelse:\n    print(\"Eres mayor de Edad\")\n\n\nopcion = 3\n\nmatch opcion:\n    case 1:\n        print(\"Opcion 1\")\n    case 2:\n        print(\"Opcion 2\")\n    case 3:\n        print(\"Opcion 3\")\n\n\n#Bucles:\n\nfor i in range(11):\n    print(i)\n\n\nfrutas = [\"Manzana\", \"Pera\", \"Fresa\"]\n\nfor fruta in frutas:\n    print(fruta)\n\n\ncontador = 0\n\nwhile(contador < 3):\n    print(contador)\n    contador += 1\n\n\n#Excepciones: \n\ntry:\n    resultado = 10 / 0\nexcept ZeroDivisionError:\n    print(\"No se puede dividir por cero!\")\nfinally:\n    print(\"Bloque final siempre se ejecuta\")\n\n\n\nfor numero in range(10, 56):\n    if(numero % 2 == 0 and numero != 16 and numero % 3 != 0):\n        print(numero)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/FedeAirala.py",
    "content": "# Reto #01 Roadmap\n\n\"\"\"\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\"\"\"\n\n# Operadores Arietméticos \n\nsum_integer =  10 + 10     # Suma de enteros\nsum_float = 10.5 + 10.1    # Suma de flotantes\nsub_integer = 10 - 5       # Resta de enteros\nsub_float = 10.5 - 10.1    # Resta de flotantes\nmult_integer = 5 * 3       # Multiplicación de enteros\nmult_float = 5.5 * 3.6     # Multiplicación de flotantes\ndiv_enteros = 10 / 2       # División de enteros (puede retornar un número flotante)\ndiv_float = 10.5 / 2.3     # División de flotantes\nmod = 10 % 3               # Módulo, calcula el cociente y devuelve el resto de la operación\npot = 10 ** 3              # Potencia de un número ( en el ejemplo es 10 elevado a 3)\ncoc = 10 // 3              # Calcula el cociente de la divisón y devuelve la parte entera\n\n## Impresión de los resultados de las operaciones aritméticas\n\nprint (f\"La suma de los números 10 + 10 es : {sum_integer}\")\nprint (f\"La suma de los números 10.5 + 10.1 es : {sum_float}\")\nprint (f\"La resta de los números 10 - 5 es : {sub_integer}\")\nprint (f\"La resta de los números 10.5 - 10.1 es : {sub_float}\")\nprint (f\"La multiplicación de los números 5 * 3 es : {mult_integer}\")\nprint (f\"La multiplicacicón de los números 5.5 * 3.6 es : {mult_float}\")\nprint (f\"La división entre los números 10 / 2 es : {div_enteros}\")\nprint (f\"La división entre los números 10.5 / 2.3 es : {div_float}\")\nprint (f\"El módulo entre los números 10 % 3 es : {mod}\")\nprint (f\"La potencia entre los números 10 ** 3 es : {pot}\")\nprint (f\"La parte entera del cociente entre los números 10 // 3 es : {coc}\")\n\n# Operadores Lógicos\n\n\"\"\"\nLos operadores lógicos nos permiten trabajar con valores de tipo booleano. \nUn valor booleano es un tipo de dato que solo puede tomar valores True o False\n\"\"\"\n## Operador lógico and\n\n\"\"\"\nEste operador analiza si se cumplen dos condiciones\n\"\"\"\nprint(True and True)   # Devuelve el valor True\nprint(True and False)  # Devuelve el valor False\nprint(False and True)  # Devuelve el valor False\nprint(False and False) # Devuelve el valor False\n\n## Operador lógico or\n\n\"\"\"\nEste operador analiza si se cumplen al menos una de dos condiciones\n\"\"\"\nprint(True or True)   # Devuelve el valor True\nprint(True or False)  # Devuelve el valor True\nprint(False or True)  # Devuelve el valor True\nprint(False or False) # Devuelve el valor False\n\n## Operador lógico not\n\n\"\"\"\nEste operador analaiza la negación de las condiciones\n\"\"\"\n\nprint(not True)      # Devuelve el valor False\nprint(not False)     # Devuelve el valor True\nprint( not not True) # Devuelve el valor True\n\n# Operadores de comparación\n\n\"\"\"\nEstos operadores se utilizan para comparar dos o más datos y devuelven True o False\n\"\"\"\n\n## Mayor (>)\n\"\"\"\nCompara si el dato de la izquierda es mayor al de la derecha\n\"\"\"\nprint (\"Comparar si 10 es mayor a 5 (10>5): \",10>5)  # Devuelve True\nprint (\"Comparar si 10 es mayor a 15 (10>15): \",10>15) # Devuelve False\n\n## Mayor o igual (>=)\n\"\"\"\nCompara si el dato de la izquierda es mayor o igual al de la derecha\n\"\"\"\nprint (\"Comparar si 10 es mayor o igual a 5 (10>=5): \",10>=5)  # Devuelve True\nprint (\"Comparar si 10 es mayor a o igual 15 (10>=15): \",10>=15) # Devuelve False\nprint (\"Comparar si 10 es mayor a o igual 10 (10>=10): \",10>=10) # Devuelve True\n\n## Menor (<)\n\"\"\"\nCompara si el dato de la izquierda es menor al de la derecha\n\"\"\"\n\nprint (\"Comparar si 10 es menor a 5 (10<5): \",10<5)  # Devuelve False\nprint (\"Comparar si 10 es menor a 15 (10<15): \",10<15) # Devuelve True\n\n## Menor o igual (<=)\n\"\"\"\nCompara si el dato de la izquierda es menor o igual al de la derecha\n\"\"\"\nprint (\"Comparar si 10 es menor o igual a 5 (10<=5): \",10<=5)  # Devuelve False\nprint (\"Comparar si 10 es menor a o igual 15 (10<=15): \",10<=15) # Devuelve True\nprint (\"Comparar si 10 es menor a o igual 10 (10<=10): \",10<=10) # Devuelve True\n\n## Igual (==)\n\n\"\"\"\nCompara si el dato de la izquierda es igual al de la derecha\n\"\"\"\nprint (\"Comparar si 10 es igual a 10: \", 10==10) # Deluve True\nprint (\"Comparar si 10 es igual a 5: \", 10==5) # Deluve False\nprint (\"Comparar si Maria es igual a Maria: \",\"Maria\"==\"Maria\") # Deluve True\nprint (\"Comparar si Maria es igual a Pedro: \",\"Maria\"==\"Pedro\") # Deluve False\n\n## Distinto (!=)\n\n\"\"\"\nCompara si el dato de la izquierda es distinto al de la derecha\n\"\"\"\nprint (\"Comparar si 10 es distinto a 10: \", 10!=10) # Deluve False\nprint (\"Comparar si 10 es distinto a 5: \", 10!=5) # Deluve True\nprint (\"Comparar si Maria es distinto a Maria: \",\"Maria\"!=\"Maria\") # Deluve False\nprint (\"Comparar si Maria es distinto a Pedro: \",\"Maria\"!=\"Pedro\") # Deluve True\n\n# Operadores de Asignación\n\n\"\"\"\nEstos operadores se utilizan para asignar valores a una variable.\n\"\"\"\n## Ejemplos de asignaciones (=)\n\nnum = 50               # Asigna el valor 50 a la variable num\nstr = \"Hola Python!\"   # Asigna el string \"Hola Python!\" a la variable str\n\n## Asignaciones compuestas\n\n\"\"\"\nTambién se pueden realizar asignaciones que realizan algun tipo de operación\n\"\"\"\n\n## Ejemplos de asignaciones compuestas\n\nx = 0      # Asignación simple a variable x utilizada después para realidas las asignaciones compuestas\nx += 2     # Asigna a x el valor de x más 2\nx -= 2     # Asigna a x el valor de x menos 2\nx *= 2\t   # Asigna a x el valor de x multiplicado por 2\nx /= 2\t   # Asigna a x el valor de x divido 2\nx %= 2\t   # Asigna a x el módulo de x divido 2\nx //= 2\t   # Asigna a x el resto de x divido 2\nx **= 2\t   # Asigna a x la potencia de x elevado a 2\n\n\n# Operadores de identidad (is , is not)\n\n\"\"\"\nEstos operadores se utilizan para comparar si una variable is o no un tipo de dato \ny devuelve True en caso de ser afirmativo o False en caso contrario \n\"\"\"\n## Operador is\n\nx = \"Hola Python!\"\ny = int (25)\n\nprint (\"La variable x es un número entero: \", x is int)  # Devlueve False\nprint (\"La variable x es un string: \", x is str)         # Devlueve True\nprint (\"La variable y es un número entero: \", y is 25)   # Devuelve True\nprint (\"La variable y es un string: \", y is str)         # Devlueve False\n\n## Operador is not\n\nprint (\"La variable x no es un número entero: \", x is not int)  # Devlueve True\nprint (\"La variable x no es un string: \", x is not str)         # Devlueve False\nprint (\"La variable y no es un número entero: \", y is not 25)   # Devuelve False\nprint (\"La variable y no es  un string: \", y is not str)        # Devlueve True\n\n\n# Operadores de Pertenencia (in, not in)\n\n\"\"\"\nEstos operadores se utilizan para comprobar si un valor o variable \n se encuentran dentro de una secuencia y devueven True en caso de pertenecer\no False en caso contrario. Es decir, por ejemplo, si pertenecen\n o están dentro de una lista, arreglo, diccionario, etc.\n \n\"\"\"\n# Ejemplo: dada una lista de números, verificar si un valor está dentro de la misma.\n\nlist_num = [1,2,3,4,5,6,7,8,9,10]\nprint (\"El valor 10 se encuentra en la lista?:\",10 in list_num ) # Devuelve True\nprint (\"El valor 30 se encuentra en la lista?:\",30 in list_num ) # Devuelve False\nprint (\"El valor 10 no se encuentra en la lista?:\",10 not in list_num ) # Devuelve False\nprint (\"El valor 30 no se encuentra en la lista?:\",30 not in list_num ) # Devuelve True\n\n# Operadores a nivel de bits\n\n\"\"\"\nLos operadores a nivel de bits actúan sobre los operandos como si fueran \nuna cadena de dígitos binarios. Como su nombre indica,\nactúan sobre los operandos bit a bit.\n\"\"\"\n# Sin ejemplos porque todavía no estoy interiorizado en el tema \n\n# x | y\t  # or bit a bit de x e y.\n# x ^ y\t  # or exclusivo bit a bit de x e y.\n# x & y\t  # and bit a bit de x e y.\n# x << 10\t  # Desplaza x 10 bits a la izquierda.\n# x >> 10\t  # Desplaza x 10 bits a la derecha.\n\n\n# Condicionales (if, elif, else)\n\n\"\"\"\nEstas sentencias se utilizan para comprobar alguna condición y si se cumple realizar alguna operación,\nen caso de no cumplir con la condición no entra en la sentencia y sigue ejecutando el promama con la\nsiguiente instrucción. Para entender un poco más vease el ejemplo siguiente\n\"\"\"\n\"\"\"\n - Comprobar si un elemento pertence a una lista, en caso de que sea así debe imprimir por pantalla\n    que la misma ya se encuentra en la lista y en caso contrario debe agregarse a la lista e imprimir la nueva\n    lista por pantalla.\n\"\"\"\nlist_fruits = [\"naranjas\",\"manzanas\",\"bananas\",\"kiwis\",\"peras\"] # Creación de una lista de frutas\n\nfruit = input (\"Ingrese una fruta:\")\n\nif fruit in list_fruits:                                   # Pregunta si la fruta ingresada se encuentra en la lista\n    print (f\"La fruta {fruit} se encuentra en la lista\")   # Imprime indicando que la fruta se encuentra en la lista\nelif  fruit not in list_fruits:                            # Si no se encuentra\n    list_fruits.append(fruit)                              # Agrega la fruta ingresada a la lsita\n    print (list_fruits)                                    # Imrpime la nueva lista\nelse:\n    print (\"Ha ocurrido un error en el programa\")\n\n# Iterativas for y while\n\n\"\"\"\nEl bucle for se utiliza para recorrer todos los elementos dentro de una estructura o rango dado\ny se pueden realizar operaciones por cada elemento dentro de la o del mismo.\n\"\"\"\n\nprint (\" El bucle For\")\n\nfor i in range (11):\n    print (i)\n\n\"\"\"\nEl bucle while se utiliza para hacer una iteración mientras se cumpla una condición\n\"\"\"\n\nprint (\" El bucle While\")\n\nx = 0\nwhile x <= 10 :    \n    print (x)\n    x+=1\n\n# Excepciones\n\n\"\"\"\nPara el manejo de excepciones se utilizan las estructuras try y except.\nEn este tipo de estructuras se realizan las operaciones dentro de try, si ocurre algún tipo\nde error entra en la estructura de except. Para ello veremos un ejemplo\n\"\"\"\n\ntry:\n    num = int(input(\"Ingrese un número:\"))                     \n    print (\"La suma del número ingresado más 10 es\", num + 10)\nexcept:\n    print (\"Ha ocurrido un error en la ejeccución del try\")  \n\n\"\"\"\nEn el ejemplo anterior se pide al usuario que ingrese un número, si el ingreso no es del tipo dato\ncon el cual se pueda realizar la operación, la ejecución sigue por el except e imprime que ha ocurrido un error.\nEsta es forma más sencilla para controlar error sin que la ejecrción del programa tire un error.\n\n\"\"\" \n\n\n# Ejercicio de dificultad extra\n\ntry:\n    print (\"Números del rango entre 10 y 56 que son pares, no es el 16 y no son múltiplos de 3\")\n    \n    for i in range (10,56):\n        if i % 2 == 0 and i != 16 and i % 3 != 0:\n            print (i)\n\nexcept:\n    print (\"Error en la ejecución del programa\")\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Fernando-Antoni0.py",
    "content": "'''- Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)'''\n\na = 7\nb = 4\n\nprint(\"Valores... a = 7  y  b = 4\")\n#Operadores aritmeticos\nprint(\"Operadores aritmeticos\")\n#Suma +\nprint(f\"La suma de a + b es: {a + b}\")\n#Resta -\nprint(f\"La resta de a - b es: {a - b}\")\n#Multiplicacion *\nprint(f\"La multiplicacion de a * b es: {a * b}\")\n#Division /\nprint(f\"La division de a / b es: {a / b}\")\n#Division entera(ENTEROS) //\nprint(f\"La division entera de a // b es: {a // b}\")\n#Modulo(residuo division) %\nprint(f\"El modulo de a % b es: {a % b}\")\n#Potencia **\nprint(f\"La potencia de a ** b es: {a ** b}\")\n\n#Operadores comparativos\nprint(\"Operadores de comparacion\")\n#Mayor que >\nprint(f\"Mayor que, a > b : {a > b}\")\n#Mayor o igual que >=\nprint(f\"Mayor o igual que, a >= b : {a >= b}\")\n#Menor o igual que <=\nprint(f\"Menor o igual que, a <= b : {a <= b}\")\n#Menor que <\nprint(f\"Menor que, a < b : {a < b}\")\n#Igual que ==\nprint(f\"Es igual que, a == b : {a == b}\")\n#Diferente que !=\nprint(f\"Diferente que, a != b : {a != b}\")\n\n#Operadores logicos\nprint(\"Operadores logicos\")\n#AND &&\nprint(f\"AND &&: 2 + 5 == 7 and 4 - 2 == 1 : {2 + 5 == 7 and 4 - 2 == 1}\")\n#OR ||\nprint(f\"OR ||: 2 + 5 == 7 or 4 - 2 == 1 : {2 + 5 == 7 or 4 - 2 == 1}\")\n#NOT !\nprint(f\"NOT !: 15 - 5 == 11 : {not 15 - 5 == 11}\")\n\n#Operadores de asignacion\nprint(\"Operadores de asignacion\")\n\nasignacion = 9\nprint(asignacion)\nasignacion += 1 #Suma y asignacion\nprint(asignacion)\nasignacion -= 2 #Resta y asignacion\nprint(asignacion)\nasignacion *= 3 #Multiplicacion y asignacion\nprint(asignacion)\nasignacion /= 4 #Division y asignacion\nprint(asignacion)\nasignacion //= 5 #Division de enteros y asignacion\nprint(asignacion)\nasignacion **= 6 #Potencia y asignacion\nprint(asignacion)\nasignacion %= 7 #Modulo y asignacion\nprint(asignacion)\n\n#Operadores de pertenencia\nprint(\"Operadores de pertenencia\")\nprint(f\"Hay una 'n' in 'Fernando' {'n' in 'Fernando'}\" )\nprint(f\"Hay una 'z' not in 'Fernando' {'z' not in 'Fernando'}\" )\n\n#Operadores de identidad\nprint(\"Operadores de identidad\")\nidentidad1 = \"gato\"\nidentidad2 = \"gato\"\n\nprint(f\"identidad1 is identidad2 : {identidad1 is identidad2}\")\nprint(f\"identidad1 is not identidad2 : {identidad1 is not identidad2 }\")\n\n'''\nEstructuras de control\n'''\n'''\nUtilizando las operaciones con operadores que tú quieras, crea ejemplos\nque representen todos los tipos de estructuras de control que existan\nen tu lenguaje\n'''\n\n#condicionales\n\nnum = 5\n\nif num == 5:\n    print(\"El numero es 5\")\nelif num == 3:\n    print(\"El numero es 3\")\nelse:\n    print(\"El numero no es 5 y tampoco 3\")\n\n#Iterativas\n\nfor i in range(11):\n    print(i)\n\n\ni = 0\n\nwhile i <= 10:\n    print(i)\n    i += 1\n\n#Manejo de excepciones\n\ntry:\n    print(30 / 0)\nexcept:\n    print(\"El programa tuvo un error\")\nfinally:\n    print(\"Se termino la prueba de excepciones\")\n\n\n\n'''\nDIFICULTAD EXTRA (opcional):\nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n'''\n\nfor i in range(10, 56):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/FernandoATello.py",
    "content": "\"\"\" En este ejercicio crearemos los operadores aritméticos, de comparación,\nlógicos y más\"\"\"\n\n# Operadores aritméticos\nprint(f\"Sumar 13 + 3 = {13 + 10}, es mi número favorito\")\nprint(f\"Restar 16 - 3 = {16 - 3}, es mi número de la suerte\")\nprint(f\"Multiplicar 9 * 6 = {9 * 6}\")\nprint(f\"Dividir 9 / 6 = {9 / 6}\")\nprint(f\"Módulo 17 % 7 = {17 % 7}\")\nprint(f\"Exponente 3 ** 6 = {3 ** 6}\")\nprint(f\"División entera 9 // 6 = {9 // 6}\")\n\n# Operadores de comparación\nprint(f\"Igualdad: 12 == 6 es {12 == 6}\")\nprint(f\"Desigualdad: 12 != 6 es {12 != 6}\")\nprint(f\"Mayor: 12 > 6 es {12 > 6}\")\nprint(f\"Menor: 12 < 6 es {12 < 6}\")\nprint(f\"Mayor o igual que: 12 >= 6 es {12 >= 6}\")\nprint(f\"Menor o igual que: 12 <= 6 es {12 <= 6}\")\n\n# Operadores lógicos\nprint(f\"AND &&: 13 + 3 == 16 and 7 - 3 == 4 es {13 + 3 == 16 and 7 - 3 == 4}\")\nprint(f\"OR ||: 13 + 3 == 16 or 7 - 5 == 4 es {13 + 3 == 16 or 7 - 5 == 4}\")\nprint(f\"NOT !: not 13 + 2 == 16 {not 13 + 2 == 16}\")\n\n# Operadores de asignación\nmy_number = 8 # asignación\nprint(my_number)\nmy_number += 1 # suma y asignación\nprint(my_number)\nmy_number -= 1 # resta y asignación\nprint(my_number)\nmy_number *= 2 # multiplicación y asignación\nprint(my_number)\nmy_number /= 2 # división y asignación\nprint(my_number)\nmy_number %= 2 # módulo y asignación\nprint(my_number)\nmy_number **= 2 # exponente y asignación\nprint(my_number)\nmy_number //= 2 # división entera y asignación\nprint(my_number)\n\n# Operadores de identidad\nmy_new_number = 1.0\nprint(f\"my_number is my_new_number es {my_number is my_new_number}\")\nprint(f\"my_number is not my_new_number es {my_number is not my_new_number}\")\n\n# Operadores de pertenencia\nprint(f\"'o' in 'Fernando'{'o' in 'Fernando'}\")\nprint(f\"'j' not in 'Fernando'{'j' not in 'Fernando'}\")\n\n# Operadores de bit\na = 10 #1010\nb = 3 # 0011\nprint(f\"AND: 10 & 3 = {10 & 3}\") # 0010\nprint(f\"OR: 10 | 3 = {10 | 3}\") # 1011\nprint(f\"XOR: 10 ^ 3 = {10 ^ 3}\") # 1001\nprint(f\"NOT: ~10  = {~10}\")\nprint(f\"Desplazamiento a la derecha: 10 >> 2 = {10 >> 2}\") # 0010 \nprint(f\"Desplazamiento a la izquierda: 10 << 2 = {10 << 2}\") # 101000\n\n\"\"\"\nEstructuras de control\n\"\"\"\n\n# Condicionales\n\nmy_name = \"Fernando\"\n\nif my_name == \"Tello\":\n    print(\"my_name es 'Tello'\")\nelif my_name == \"Fernando\":\n    print(\"my_name es 'Fernando'\")\nelse:\n    print(\"my_name no es 'Tello' ni 'Fernando'\")\n\n# Iterativas\n\nfor i in range(11):\n    print(i)\n\ni = 0\n\nwhile i <= 10:\n    print(i)\n    i += 1\n\n# Manejo de excepciones\n\ntry:\n    print(10/0)\nexcept:\n    print(\"Se ha producido un error\")\nfinally:\n    print(\"Ha finalizado el manejo de excepciones\")\n\n\"\"\"\nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\"\"\"\n\nfor (i) in range (10, 55, 2):\n    if i != 16 and i % 3 !=0:\n        print(i)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Franz-Arzapalo.py",
    "content": "\"\"\"\nEJERCICIO: #01 OPERADORES Y ESTRUCTURAS DE CONTROL\n\n- Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n  Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n  (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n- Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n  que representen todos los tipos de estructuras de control que existan\n  en tu lenguaje:\n  Condicionales, iterativas, excepciones...\n- Debes hacer print por consola del resultado de todos los ejemplos.\n\n DIFICULTAD EXTRA (opcional):\n  Crea un programa que imprima por consola todos los números comprendidos\n  entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n  Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\"\"\"\n\n# 1. Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n#    Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n#    (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n\n\"\"\"\nVariables para los ejemlos:\n\"\"\"\n\nX = 5\nY = 4\nZ = 2\n\nprint(f\"Valor de las variables para los ejemplos X = {X}, Y = {Y}, Z = {Z}\")\nprint(f\"Valores negativos -X = {-X}, -Y = {-Y}, -Z = {-Z}\")\n\n\"\"\"\nTipos de operadores Aritméticos: \"+, -, /, //, %, *, **\" \nSe usan para ejecutar operaciones matematicas simples con datos o variables devueven integers o floats.\n\"\"\"\n\nsuma = X + Y\nprint(f\"La suma total entre {X} + {Y} = {suma}\")\n# La suma se usa con el signo \"+\" realiza una suma en este caso entre la variable X y Y.\n# devuelve un valor de tipo integer(entero) si los valores sumados son integer(entero) y floats(decimales) si son floats(decimales). \n\nresta = X - Y\nprint(f\"La diferencia entre {X} - {Y} = {resta}\")\n# La resta se una con el signo \"-\" realiza una resta en este caso la diferencia entre X y Y.\n# devuelve un valor de tipo integer(entero) si los valores sumados son integer(entero) y floats(decimales) si son floats(decimales).\n\nmultiplicación = Y * Z\nprint(f\"El producto resultado de {Y} * {Z} = {multiplicación}\")\n# La multiplicación se usa con el signo \"*\" realiza una multiplicación en este caso da el producto de Z y Y.\n# devuelve un valor de tipo integer(entero) si los valores sumados son integer(entero) y floats(decimales) si son floats(decimales). \n\ndivisión = Y / Z\nprint(f\"El cociente de {Y} / {Z} es {división}\")\n# la división se usa con el signo \"/\"  realiza una división en este caso da el cociente de Y entre Z.\n# devuelve un valor de tipo float(decimal) aunque los valores sean integers(enteros) se le agregara .0 al final.\n\nresto_ent = X % Z \nprint(f\"El resto de la división entera {X} / {Z} = {resto_ent}\")\n# La opración de signo \"%\" devuelve un resto de una división entera en este caso X y Z.\n# devuelve un valor de tipo integer(entero) si los valores sumados son integer(entero) y floats(decimales) si son floats(decimales).\n\npotencia = Y ** Z\nprint(f\"La potencia que resulta de elevar {Y} al exponente {Z} = {potencia}\" )\n# La potecia se usa con los signos \"**\" en este caso eleva la base Y a la potencia Z.\n# devuelve un valor de tipo integer(entero) si los valores sumados son integer(entero) y floats(decimales) si son floats(decimales). \n\ndivisión_ent = X // Z\nprint(f\"El cociente entero de {X} // {Z} es = {división_ent}\")\n# la operación de signo \"//\" hace una división en este caso Y entre Z.\n# devuelve un valor de tipo integer(entero).\n\n\"\"\"\nTipos de operadores Lógicos: \"and = &; or = ||; not = !\"\nse usan de manera que realacionan un valor booleano(True o False) con otro booleano(True o Falso)\ny devuelven otro valor booleano(True o Falso) que depende del operador.\n\"\"\"\n\n# Ejemplo con el operador logico \"And\".\nprint(f\"Si True and True = {True and True}, Si True and False = {True and False} y Si False and False = {False and False}\")\nprint(f\"Si True and True = {True & True}, Si True and False = {True & False} y Si False and False = {False & False}\")\n# El operador \"and\" necesita que ambos valores relacionados sean verdaderos(True) para devolver verdadero(True).\n\n# Ejemplo con el operador logico \"Or\"\nprint(f\"Si True or True = {True or True}, Si True or False = {True or False} y Si False or False = {False or False}\")\nprint(f\"Si True or True = {True | True}, Si True or False = {True | False} y Si False or False = {False | False}\")\n# El operador \"or\" necesita que uno de los valores relacionados sea verdadero(True) para devolver verdadero(True).\n\n# Ejemplo con el operador logico \"Not\"\nprint(f\"Si not True = {not True}, Si not False = {not False}\")\n# El operador \"not\" necesita que el valor sea falso(false) para devolver verdadero(true).\n\n\"\"\"\nTipos de operadores de comparación: \"==(igualdad), !=(diferente), <(menor que), >(mayor que), <=(menor o igual que), >=(mayor o igual que)\"\nconparan todos los tipos de datos primitivos con otros datos del mismo tipo y devuelven un valor de tipo booleano(True y False).\n\"\"\"\n\n# Ejemplo con el operador de comparación \"igualdad(==)\"\nprint(f\"10 == 10 entonces {10 == 10}, si 10 == 5 entonces {10 == 5}\") #Ejemplo con Integers\nprint(f\"1.5 == 1.5 entonces {1.5 == 1.5}, si 1.8 == 0 entonces {1.8 == 0}\") #Ejemplo con Floats\nprint(f\"Verdadero == Verdadero entonces {'Verdadero' == 'Verdadero'}, si Verdadero == Falso entonces {'Verdadero' == 'Falso'}\") #Ejemplo con Strings\nprint(f\"True == True entonces {True == True}, si True == False entonces {True == False}\") #Ejemplo con Booleanos\n# Si despues de comparar determina ambos valores iguales devuelve un True caso contrario False.\n\n# Ejemplo con el operador de comparación \"diferente(!=)\"\nprint(f\"10 != 10 entonces {10 != 10}, si 10 != 5 entonces {10 != 5}\") #Ejemplo con Integers\nprint(f\"1.5 != 1.5 entonces {1.5 != 1.5}, si 1.8 != 0 entonces {1.8 != 0}\") #Ejemplo con Floats\nprint(f\"Verdadero != Verdadero entonces {'Verdadero' != 'Verdadero'}, si Verdadero != Falso entonces {'Verdadero' != 'Falso'}\") #Ejemplo con Strings\nprint(f\"True != True entonces {True != True}, si True != False entonces {True != False}\") #Ejemplo con Booleanos\n# Si despues de comparar determina ambos valores diferentes devuevle un True caso contrario False.\n\n# Ejemplo con el operador de comparación \"menor que(<)\"\nprint(f\"Si 1 < 2 entonces {1 < 2}, si 2 < 1 entonces {2 < 1}\") #Ejemplo con Integers\nprint(f\"Si 1.5 < 2 entonces {1.5 < 2}, si 2 < 1.5 entonces {2 < 1.5}\") #Ejemplo con Floats\n# Si despues de comparar determina que el primer valor es menor que el segundo entoces devuelve un True caso contrario False.\n# Por su naturaleza aritmetica solo trabajo con Integers y Floats no con Strings ni con Booleanos.\n\n# Ejemplo con el operador de comparación \"mayor que(>)\"\nprint(f\"Si 2 > 1 entonces {2 > 1}, si 1 > 2 entonces {1 > 2}\") #Ejemplo con Integers\nprint(f\"Si 2 > 1.5 entonces {2 > 1.5}, si 1.5 > 2 entonces {1.5 > 2}\") #Ejemplo con Floats\n# Si despues de comparar determina que el primer valor es mayor que el segundo entoces devuelve un True caso contrario False.\n# Por su naturaleza aritmetica solo trabajo con Integers y Floats no con Strings ni con Booleanos.\n\n# Ejemplo con el operador de comparación \"menor igual que(<=)\"\nprint(f\"Si 1 <= 2 entonces {1 <= 2}, si 2 <= 1 entonces {2 <= 1}\") #Ejemplo con Integers\nprint(f\"Si 2.5 <= 2.5 entonces {2.5 <= 2.5}, si 4.5 <= 2 entonces {4.5 <= 2}\") #Ejemplo con Floats\n# Si despues de comparar determina que el primer valor es mayor que el segundo entoces devuelve un True caso contrario False.\n# Por su naturaleza aritmetica solo trabajo con Integers y Floats no con Strings ni con Booleanos.\n\n# Ejemplo con el operador de comparación \"mayor igual que(>=)\"\nprint(f\"Si 2 >= 1 entonces {2 >= 1}, si 1 >= 2 entonces {1 >= 2}\") #Ejemplo con Integers\nprint(f\"Si 2 >= 1.5 entonces {2 >= 1.5}, si 1.5 >= 2 entonces {1.5 >= 2}\") #Ejemplo con Floats\n# Si despues de comparar determina que el primer valor es mayor que el segundo entoces devuelve un True caso contrario False.\n# Por su naturaleza aritmetica solo trabajo con Integers y Floats no con Strings ni con Booleanos.\n\n\"\"\"\nTipos de operadores de asignación: \"=, +=, -=, /=, //=, %=, *=, **=\"\nse usan de forma comun cuando se quiere asginar un valor a una variable\no alterar de forma corta el volar a una variable mediante operaciones\naritmeticas siendo que se pone el signo de la operación aritmetica luego \nel signo de asignación(=) y despues el numero que conduce la operación.\n\"\"\"\n\n# Operador de asignacion: \"=\"\nvariable = 2\nprint(f\"definimos el valor de la variable con el signo '=' = {variable}\")\n# Le asigna un valor a una varible de la misma manera se puede canbiar el valor de la variable.\n\n# Operador de suma y asignacion: \"+=\"\nvariable += 2\nprint(f\"despues de usar el operador '+=' con el numero 2 el valor queda = {variable}\")\n# Le suma la cantidad escrita despues de el signo de \"+=\" y le asgina el resultado a la variable.\n\n# Operador de resta y asignacion: \"-=\"\nvariable -= 3\nprint(f\"despues de usar el operador '-=' con el numero 3 el valor queda = {variable} \")\n# Le resta de la cantidad escrita despues del signo de \"-=\" y le asina el resultado a la variable.\n\n# Operador de division y asignacion: \"/=\"\nvariable /= 2\nprint(f\"despues de usar el operador '/=' con el numero 2 el valor queda = {variable}\")\n# La division del valor sobre la cantidad escrita despues del signo \"/=\" y le asina el resultado a la variable.\n\n# Operadaor de multipliacion y asignacion: \"*=\"\nvariable *= 10 \nprint(f\"despues de usar el operador '*=' con el numero 10 el valor queda = {variable}\")\n# Le multiplica la cantidad escrita despues del signo \"*=\" y le asigna el resultado a la variable.\n\n# Operador de division entera y asignacion: \"//=\"\nvariable //= 2\nprint(f\"despues de usar el operador '//=' con el numero 2 el valor queda = {variable}\")\n# Divide la cantidad del valor sobre la cantidad escrita despues del signo \"//=\" y asigna el resultado a la variable.\n# Si el cociente es un float cambia el valor despues del punto a 0(pero no lo combierte en un int).\n\n# Operador de potenciacion y asignacion: \"**=\"\nvariable **= 3\nprint(f\"despues de usar el operador '**=' con el numero 3 el valor queda = {variable}\")\n# Potencia el valor de la variable al numero escrito despues del signo \"**=\" el resultado se asigna a la variable.\n\n# Operador de resto y asignacion: \"%=\"\nvariable %= 3\nprint(f\"despues de usar el operador '%=' con el numero 3 el valor queda = {variable}\")\n# Divide el valor de la variable sobre el numero escrito despues del signo \"%=\" devievel el resto de haber\n# si no devuelve 0 y la asigna a la variable\n\n\n\"\"\"\nTipos de operadores de identidad: \"Is , Is not\"\nCompara si dos variables tienen el mismo valor y devuelve un booleano(True o False)\ndependiendo el operador las condiciones son opuestas.\n\"\"\"\n# Variables para los ejemplos\n\nA = 4\nB = 4\nC = \"Ejm\"\nD = \"Ejm\"\n\n# Operador de identidad: \"Is\"\nprint(f\"Si A y B tienen el mismo valor entonces = {A is B}\")\nprint(f\"Si B y C tienen no mismo valor entonces = {B is C}\")\n# Si despues de la comparacion determina que tienen el mismo valor devolvera True caso contrario False.\n\n# Operador de identidad: \"Is Not\"\nprint(f\"Si A y B tienen el mismo valor entonces = {A is not B}\")\nprint(f\"Si B y C tienen no mismo valor entonces = {B is not C}\")\n# Si despues de la comparacion determina que no tienen el mismo valor devolvera True caso contrario False.\n\n\"\"\"\nTipos de operadores de pertenencia: \"In, Not In\"\nIdentifica si un valor puede ser econtrado dentro de otro valor estos valores tienen que ser de tipo String \ny devuelve un valor de tipo booleano. (No aceptan un Integer normales)\n\"\"\"\n\n# Varables para los ejemplos\n\nEjemplo_1 = \"Ej\"\nEjemplo_2 = \"Ejemplo\"\n\n# Operador de pertenencia: \"In\"\nprint(f\"Si {Ejemplo_1} esta en {Ejemplo_2} = {Ejemplo_1 in Ejemplo_2}\") \nprint(f\"Si {Ejemplo_2} esta en {Ejemplo_1} = {Ejemplo_2 in Ejemplo_1}\")\n# si la primera cadena de texto esta dentro la segunda devolver True caso contrario devolvera False.\n\n# Operadores de pertenencia: \"Not In\"\nprint(f\"Si {Ejemplo_2} no esta en {Ejemplo_1} = {Ejemplo_2 not in Ejemplo_1}\")\nprint(f\"Si {Ejemplo_1} no esta en {Ejemplo_2} = {Ejemplo_1 not in Ejemplo_2}\") \n# Si la primera cadena de texto no esta dentro de la segunda devolvera True caso contrario devolvera False.\n\n\"\"\"\nTipos de operadores de bits: \"& = and, | = or, ~ = not, << = desplazarce a la derecha, >> = desplazarce a la izquierda\"\nCuando se trabajan con  estos operadores se trabaja con numeros, nosostros ingresamos numeros en el sistema decimal\npero se transfoman al sistema binario para ejecutar los operadores y se devuelve el resultado en sistema decimal.\nEl resutado depende del operador usado pero en la mayoria de casos compara los numeros de las mismas posiciones \ncomo es sistema binario solo 1 y 0 en las posiciones que no tengan un numero se completaran con 0.\n\"\"\"\n\n# Podemos transformar del sistema decimal al sistema binario con la funcion bin() cuando se ejecute antes del numero estara 0b\n# Esto es una señal que el numero esta en sistema binario.\n\nprint(f\"En el sistema decimal 10 en sistema binario {bin(10)}\")\n# 1010\nprint(f\"En el sistema decimal 3 en sistema binario {bin(3)}\")\n# 11\n\n# Operador de bits: \"&\"\nprint(f\"10 & 3 = {10 & 3}\")\n# Como vimos antes 10 = 0b1010 y 3 = 0b11 el resultado de la funcion es 0b10 osea 2.\n# El resultado es asi porque al comparar cada numero si en ambas posiciones los numeros tienen 1 el numeor resultante tendra 1 en esa \n# posicion caso contrario sera 0 en la posicion.\n\n# Operador de bits: \"|\"\nprint(f\"10 | 3 = {10 | 3}\")\n# Como sabemos 10 = 0b1010 y 3 = 0b11 el resultado de la funcion es 0b1011 osea 11.\n# El resultado es asi porque al comparar cada umero si en una de los numeros almenos un 1 ocupa esa posicion devolvera un 1 en caso\n# ningun 1 ocupa la posicion devolvera 0.\n\n# Operador de bits: \"~\"\nprint(f\"~10 = {~10}\")\n# El comportamineto normal deveria ser el intercambiar los valores del codigo binario correspodiente cada 0 a 1 y 1 a 0.\n# Pero en python el resultado es el producto del numero con -1 seguido de restarle 1 al resultado por eso:\n# el resutado de esta funcion siendo ingresado el numero 10 es -11\n\n# Operador de bits: \"^\"\nprint(f\"10 ^ 3 = {10 ^ 3}\")\n# Como sabemos 10 = 0b1010 y 3 = 0b11 el resultado de la funcion es 0b1001 osea 9\n# Devuelve 9 por que despues de comporar cada numero si tiene un 0 y un 1 en la misma posicion devuelve 1 si ambos son 0 o 1\n# devuelve 0.\n\n# Operador de bits: \">>\"\nprint(f\"3 >> 2 = {3 >> 2}\")\n# Como sabemos 3 = 0b11 el resultado de la funcion es 0b0 osea 0.\n# Es asi porque desplaza los numeros la cantidad de veces espesificado luego del signo \">>\" \n# en este caso devuelve 0 porque si despalaza dos digitos como los 3 en binario solo tiene 2 digitos \n# y ambos estan en el extremo derecho la desplazr dos digitos a la derecha y no haber espacio los elimina.\n\n# Operador de bits: \"<<\"\nprint(f\"10 << 2 = {10 << 2}\")\n# Como sabemos 10 = 0b1010 el resutado de la funcion es 0b101000 osea 40.\n# Es asi porque desplaza los digitos hacia la izquierda al contrario de su operador analogo >> envez de \n# elminar los dumeros que esten al extremo izquierdo agrega 0 al extremo derecho.\n\n\"\"\"\nOperador walrus: \":=\" \nUn operador muy criticado y dificil de utilizar porque se usa para definir una variable dentro de un funcion.\n\"\"\"\n\n# Ejemplo Operador walrus:\nprint(k := 2)\n# Como se obesarva en la terminal imprime k y k fue definida en la misma funcion print esto puede ser util para\n# reducir el numero de lineas de codigo en un funcion pero es criticada porque es dificil de interpretar para el resto de personas.\n\n# 2. Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n#    que representen todos los tipos de estructuras de control que existan\n#    en tu lenguaje:\n#    Condicionales, iterativas, exepciones...\n\n\"\"\"\nTipos de estructuras de control\n\"\"\"\n\n# Variables para los ejemplos:\nEjm_int_1 = 5\nEjm_int_2 = 2\nEjm_string_1 = \"str\"\nEjm_string_2 = \"stg\"\n\n# Codicionales:\n\n# Condicional \"If\":\nif Ejm_int_1 == 5 :\n    print(f\"Ejm_int_1 = {Ejm_int_1}\")\n# Al usar el condicional If de esta manera definimos una accion que se tiene que realizar en caso la condicion sea True.\n# Si la condicion definida no es True no pasara nada, pero si la accion no esta definida devolvera un error de sintaxys\n# para evitar eso se puede poner \"pass\" en la accion y y el codigo compilara de forma normal sin hacer nada cuando se ejecute el condicional.\n# Si bien el condicional tiene ese formato definido se puede escribir en una sola liena de ser necesario definiendo la accion seguido de los\n# dos puntos y para agregar otra accion separarlas con punto y como sera suficiente. \n\n# Extension de if \"Else\"\nif Ejm_int_1 == 2 :\n    print(f\"Ejm_int_1 = {Ejm_int_1}\")\nelse : \n    print(f\"Ejm_int-1 no es = {2}\")\n# AL usar esta extension \"else\" lagragamos una accion que se ejecutara si el caso definido con if no es True.\n\n# Extension de if \"ELif\" esto renplaza de cierta manera \"Switch\" esto no existe en python pero es es util saberlo. \nif Ejm_string_1 == \"str\" :\n    print(f\"Ejm_string_1 = {Ejm_string_1}\")\nelif Ejm_string_1 == \"stg\" : \n    print(f\"Ejm_string_1 = {Ejm_string_2}\")\nelif Ejm_string_1 == 5 :\n    print(f\"Ejm_string_1 = {Ejm_int_1}\")\nelif Ejm_string_1 == 2 :\n    print(f\"Ejm_string_1 = {2}\")\nelse:\n    print(\"No sabemos\")\n# Al usar esta extension \"elif\" conseguimos detallar mas condiocnes esto nos permite detallar tambien acciones diferentes en caso\n# se cumplan diferentes condiciones y esta extension puede funcionar de manera igual con else en caso ninguna condicion se cumpla.\n\n# Operador terniario: El operador terniario es otra manera de usar el condicional If:\nP = 5\nprint(\"es 5\" if P == 5 else \"no es 5\")  \n# de esta forma la estructura de la condicional es:\n# [codigo si cumple] if [condicion] else [codigo si no cumple]\n\n# Iterativas:\n\n\"\"\"\nIterables e Iteradores son conceptos que tenemos que tener claros para usar de forma eficaz las siguientes funciones.\n\nIterables:\nSi usamos la funcion isinstance() podemos saber si la variable es iterable.\nAl usar la funcion devuelve True o False para indicar si la variable es iterable.\n\"\"\"\n# print(isinstance(\"Python\", type(\"Python\"))) True\n\"\"\"\nde la siguiente forma podremos saber si un objeto es iterable.\n\nIteradores:\nSi bien sabemos como identificar si una variables es iterable podemos saber su clase de forma que podremos utilizar mejor los iteradores \nque se ajustan a esa clase y sabler cuando un iterador no sera conveniente depedinedo el caso.\nEsta forma es usando la funcion iter() dentro va el nombre de la variable.\n\"\"\"\n# print(iter(\"Python\")) str_ascii_iterator object at 0x0000023E90943FD0\n\"\"\"\nSi el uso de la funcion da un error significa que no esta dentro de la lista de clases esta lista incluye: str_iterator para cadenas,\nlist_iterator para sets, tuple_iterator para tuplas, set_iterator para sets, dict_keyiterator para diccionarios.\n\"\"\"\n# Bucle \"For\":\nfor i in \"Python\":\n    print(i)\n# En el bucle \"For\" la i(variable) representa uno de los valores de la varaible interable.\n# En este caso toma cada una de las letras de la cadena \"Python\" y las imprime en una linea cada letra, si pusieras un numero como string\n# lo imprime de la misma manera.\n\n# Funcion \"Range\":\nfor i in range(5,50,5):\n    print(i) # 5 10 15 20 25 30 35 40 45\n# Range es una forma de generar una sucesion de numeros por defecto esta enpieza en 0 y salta de 1 hasta el numero definido en el parentesis.\n# El orden de los parametros de la funcion es Range([Inicio],[Fin],[Salto])\n# El inicio es abierto lo que significa que utilza el numero que se define dentro de la sucesion.\n# El fin es cerrado lo que signica que excluye el numero definido dentro de la sucesion.\n# Y el salto solo es la diferencia que abra entre los numeros de la sucesion.\n\n# Bucle \"While\": \nx = 5\nwhile x > 0:\n    x -= 1\n    print(x) # 4 3 2 1\n# importante diferencia\nx = 5\nwhile x > 0:\n    print(x) # 5 4 3 2 1 \n    x -= 1\n# El bucle while tambien necestia una variable aqui utilizamos un operador de asignacion para modificar esa variable esta funciona como una condicion que mentras se cumpla\n# seguira repitiendo la accion (esto puede generar un error en la ejecucion) Una ejecucion completa del codigo se llama iteracion.\n\n# Else en while:\nx = 5\nwhile x > 0:\n    x -=1\n    print(x) #4,3,2,1,0\nelse:\n    print(\"El bucle ha finalizado\")\n# Se puede usar el else en while aqui el else se ejecuta cuando la condicion del while se deja de cumplirn osea cuando el bucle se termina.\n\n# Modificadores \"Break\" y \"Continue\" : Son modificadores de comportamiento para los bucles se usan de la siguiente manera.\n\n# \"Break\":\nfor l in \"Break\":\n    if l == \"a\":\n        print(\"Econtro la a\")\n        break\n    print(l)\n# De esta forma cuando \"l\" sea igual a \"a\" el bucle parara pero antes se ejecutara el codigo que lo precede.\n\n# \"Continue\":\nnum = 5\nwhile x > 0:\n    num -= 1\n    if num == 3:\n        continue\n    print(num)\n# De esta forma cuando \"num\" sea igual a 3  el bucle omitira y pasara a la siguiente operacion.\n\n# Manejo de excepciones\ntry:\n    print(10 / 0)\nexcept:\n    print(\"Se ha producido un error\")\nfinally:\n    print(\"Ha finalizado el manejo de excepciones\")\n# lo que hay dentro del try es la sección del código que podría lanzar la excepción que se está capturando en el except. \n# Por lo tanto cuando ocurra una excepción, se entra en el except pero el programa no se para.\n# finally Este bloque se suele usar si queremos ejecutar algún tipo de acción de limpieza.\n# Dicho bloque se ejecuta siempre, haya o no haya habido excepción.\n\n# 3. Debes hacer print por consola del resultado de todos los ejemplos. (Cumplida)\n\n# 4. Crea un programa que imprima por consola todos los números comprendidos\n#  entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n#  Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo. (Opcional)\n\nfor i in range(10, 56):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print(i)\n        \n# Fin."
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/FreyFonseca.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n#  *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n#  *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n#  * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n#  *   que representen todos los tipos de estructuras de control que existan\n#  *   en tu lenguaje:\n#  *   Condicionales, iterativas, excepciones...\n#  * - Debes hacer print por consola del resultado de todos los ejemplos.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea un programa que imprima por consola todos los números comprendidos\n#  * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n#  *\n#  * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n#  */\n\n\"\"\"\nOperadores\n\"\"\"\n\n# Operadores aritméticos\nprint(f\"Suma: 10 + 3 = {10 + 3}\")\nprint(f\"Resta: 10 - 3 = {10 - 3}\")\nprint(f\"Multiplicación: 10 * 3 = {10 * 3}\")\nprint(f\"División: 10 / 3 = {10 / 3}\")\nprint(f\"Módulo: 10 % 3 = {10 % 3}\")\nprint(f\"Exponente: 10 ** 3 = {10 ** 3}\")\nprint(f\"División entera: 10 // 3 = {10 // 3}\")\n\n# Operadores de comparación\nprint(f\"Igualdad: 10 == 3 es {10 == 3}\")\nprint(f\"Desigualdad: 10 != 3 es {10 != 3}\")\nprint(f\"Mayor que: 10 > 3 es {10 > 3}\")\nprint(f\"Menor que: 10 < 3 es {10 < 3}\")\nprint(f\"Mayor o igual que: 10 >= 10 es {10 >= 10}\")\nprint(f\"Menor o igual que: 10 <= 3 es {10 <= 3}\")\n\n# Operadores lógicos\nprint(f\"AND &&: 10 + 3 == 13 and 5 - 1 == 4 es {10 + 3 == 13 and 5 - 1 == 4}\")\nprint(f\"OR ||: 10 + 3 == 13 or 5 - 1 == 4 es {10 + 3 == 14 or 5 - 1 == 4}\")\nprint(f\"NOT !: not 10 + 3 == 14 es {not 10 + 3 == 14}\")\n\n# Operadores de asignación\nmy_number = 11  # asignación\nprint(my_number)\nmy_number += 1  # suma y asignación\nprint(my_number)\nmy_number -= 1  # resta y asignación\nprint(my_number)\nmy_number *= 2  # multiplicación y asignación\nprint(my_number)\nmy_number /= 2  # división y asignación\nprint(my_number)\nmy_number %= 2  # módulo y asignación\nprint(my_number)\nmy_number **= 1  # exponente y asignación\nprint(my_number)\nmy_number //= 1  # división entera y asignación\nprint(my_number)\n\n# Operadores de identidad\nmy_new_number = my_number\nprint(f\"my_number is my_new_number es {my_number is my_new_number}\")\nprint(f\"my_number is not my_new_number es {my_number is not my_new_number}\")\n\n# Operadores de pertenencia\nprint(f\"'u' in 'mouredev' = {'u' in 'mouredev'}\")\nprint(f\"'b' not in 'mouredev' = {'b' not in 'mouredev'}\")\n\n# Operadores de bit\na = 10  # 1010\nb = 3  # 0011\nprint(f\"AND: 10 & 3 = {10 & 3}\")  # 0010\nprint(f\"OR: 10 | 3 = {10 | 3}\")  # 1011\nprint(f\"XOR: 10 ^ 3 = {10 ^ 3}\")  # 1001\nprint(f\"NOT: ~10 = {~10}\")\nprint(f\"Desplazamiento a la derecha: 10 >> 2 = {10 >> 2}\")  # 0010\nprint(f\"Desplazamiento a la izquierda: 10 << 2 = {10 << 2}\")  # 101000\n\n\"\"\"\nEstructuras de control\n\"\"\"\n\n# Condicionales\n\nmy_string = \"Brais\"\n\nif my_string == \"MoureDev\":\n    print(\"my_string es 'MoureDev'\")\nelif my_string == \"Brais\":\n    print(\"my_string es 'Brais'\")\nelse:\n    print(\"my_string no es 'MoureDev' ni 'Brais'\")\n\n# Iterativas\n\nfor i in range(11):\n    print(i)\n\ni = 0\n\nwhile i <= 10:\n    print(i)\n    i += 1\n\n# Manejo de excepciones\ntry:\n    print(10 / 0)\nexcept:\n    print(\"Se ha producido un error\")\nfinally:\n    print(\"Ha finalizado el manejo de excepciones\")\n\n\"\"\"\nExtra\n\"\"\"\nfor i in range(10,56):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print(i)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/GaboDev23.py",
    "content": "\"\"\"\n- Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje: Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits... (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n\"\"\"\n# Asignación\nasignacion = 'valor' # Asignación (=) Asigna un valor a una variable\nasignacion = 3\nasignacion += 2 # Suma 2 valores a la variable\nasignacion -= 1 # Resta 1 valor a la variable\nasignacion *= 2 # Multiplica 2 valores a la variable\nasignacion /= 4 # Divide 4 valores a la variable\nasignacion %= 3 # Devuelve el resto de dividir 3 valores a la variable\nasignacion **= 2 # Eleva 2 valores a la variable\n\nprint(asignacion)\n\n# Aritméticos\nsuma = 1 + 1 # Suma (+) suma dos valores\nresta = 5 - 3 # Resta (-) resta dos valores\nmultiplicacion = 2 * 4 # Multilicación (*) multiplica dos valores\ndivision = 20 / 5 # División (/) divide dos valores\nresto = 6 % 5 # Resto (%) de la división guarda el resto de la misma\nexponente = 5 ** 2 # Exponente (**) Eleva el 5 al 2\ndivision_entera = 11 // 3 # División Entera (//) Hace una división normal pero guarda su parte entera\n\n# Cómparación\nigualacion = suma == resta # Igualación (==) comprueba si 2 valores son iguales - Devuelve True\ndiferentes = multiplicacion != division # Diferentes (!=) comprueba si 2 valores son distintos - Devuelve True\nmayor = resto > suma # Mayor que (>) Devuelve si un valor es mayor que otro - Devuelve False\nmenor = suma < resta # Menor que (<) Devuelve si un valor es menor que otro - Devuelve False\nmayor_igual = multiplicacion >= resta # Mayor o igual que (>=) Devuelve si un valor es mayor o igual que otro - Devuelve True\nmenor_igual = multiplicacion <= division # Menor o igual que (<=) Devuelve si un valor es menor o igual que otro  - Devuelve False\n\n# Lógicos\ny = igualacion and diferentes # Y (and) Con que uno de los valores sea sea False todo es False - Devuelve True\no = mayor or menor # O (or) Con que uno de los valores sea True todo es True - Devuelve False\nnegacion = not mayor_igual # No (not) Devuelve el valor booleano contrario - Devuelve False\n\n# Identidad\nes = suma is resta # Es (is) Hace referencia al mismo objeto - Devuelve True\nno_es = resta is not multiplicacion # No es (is not) Hace referencia a objetos distintos - Devuelve True\n\n# Pertenencia\nprint('Dato' in 'Python es para Ciencias de Datos') # En (in) Evalúa si un objeto pertenece a otro - Devuelve True\nprint('Python' not in 'Python es para Ciencias de Datos') # No en (not in) Evalúa si un objeto no pertenece a otro - Devuelve False\n\n# De bits\nbit_y = 10 & 3 # Y (&) Compara bit a bit los 2 números si encuentra 2 unos devuelve un 1 sino un 0, el resultado será el decimal del binario resultante\nbit_o = 10 | 3 # O (|) Compara bit a bit los 2 números si encuentra al menos un 1 devuelve 1 sino un 0, el resultado será el decimal del binario resultante\nbit_xor = 10 ^ 3 # Xor (^) Compara bit a bit los 2 números si los bits son diferentes el resultado es 1 sino es 0\nbit_not = ~10 # Not (~) Invierte los bits del numero\nderecha = 10 >> 2 # Desplazamiento hacia la derecha (>>) Desplaza cada bit 2 posiciones hacia la derecha\nizquierda = 10 << 1 # Desplazamiento hacia la izquierda (<<) Desplaza cada bit 1 posición hacia la izquierda\n\nprint(derecha) \n\n'''\n- Utilizando las operaciones con operadores que tú quieras, crea ejemplos que representen todos los tipos de estructuras de control que existan en tu lenguaje:\nCondicionales, iterativas, excepciones...\n'''\n\n# Condicionales\n\n# if\nif suma == resta: # Si la condición es verdadera ejecuta lo que hay después del :\n    print ('La suma es igual a la resta')\nelif resta != multiplicacion: # Si la primera condición es falsa evalua las condiciones de elif y si es verdadera ejecuta lo que hay después del :\n    print ('La resta y la multipliación son diferentes')\nelse: # Si ninguna de las condiciones es verdadera ejecuta lo que hay despues del : del else\n    print ('La suma no es igual a la resta ni la resta distinta a la multiplicación')\n    \ni = 0\n\n# Iteraciones\n\n# while\nwhile i < 5: # Ejecuta la instrucción mientras la condición sea verdadera\n    print (i)\n    i += 1 # Se suma 1 a la variable porque i puede quedar siempre con su valor original asignado (0) y quedar en un bucle infinito, de esta manera i en algun momento dejará de ser menor que 5 y el bucle termina\n\nfor x in range(5): # Ejecuta un bucle hasta llegar a un valor en específico\n    print(x)\n\n# Excepciones\ntry: # Intentamos ejecutar un código\n    print(10 / 1)\nexcept: # Si encuentra un error ejecutará el siguiente código\n    print('Opa, cuidao, está cometiendo un delito que puede tener una pena de 30 años como mínimo')\nfinally: # Ejecuta el siguiente código al finalizar la excepción\n    print('Ha finalizado la excepción con éxito')\n    \n# ----------------------------------------------------------------\n'''Extra'''\ntext = ''\nfor i in range(10, 55):\n    if i != 16 and i % 2 == 0:\n        text += f'{i}, ';\n        \nprint(text);"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Gallitofast.py",
    "content": "#No se si alguien lea esto pero deje c por que se me hizo muy dificil para proyectos personales \n# y no quiero que se me olvide como se hace\n# =======================\n# OPERADORES EN PYTHON\n# =======================\n\nprint(\"=== Operadores Aritméticos ===\")\na = 10\nb = 3\nprint(\"Suma:\", a + b)\nprint(\"Resta:\", a - b)\nprint(\"Multiplicación:\", a * b)\nprint(\"División:\", a / b)\nprint(\"División entera:\", a // b)\nprint(\"Módulo:\", a % b)\nprint(\"Potencia:\", a ** b)\n\nprint(\"\\n=== Operadores de Comparación ===\")\nprint(\"Igualdad:\", a == b)\nprint(\"Diferente:\", a != b)\nprint(\"Mayor que:\", a > b)\nprint(\"Menor que:\", a < b)\nprint(\"Mayor o igual:\", a >= b)\nprint(\"Menor o igual:\", a <= b)\n\nprint(\"\\n=== Operadores Lógicos ===\")\nx = True\ny = False\nprint(\"and:\", x and y)\nprint(\"or:\", x or y)\nprint(\"not:\", not x)\n\nprint(\"\\n=== Operadores de Asignación ===\")\nc = 5\nprint(\"Inicial:\", c)\nc += 2\nprint(\"c += 2:\", c)\nc *= 3\nprint(\"c *= 3:\", c)\nc -= 1\nprint(\"c -= 1:\", c)\nc /= 2\nprint(\"c /= 2:\", c)\n\nprint(\"\\n=== Operadores de Identidad ===\")\nm = [1, 2]\nn = m\nz = [1, 2]\nprint(\"m is n:\", m is n)\nprint(\"m is z:\", m is z)\nprint(\"m is not z:\", m is not z)\n\nprint(\"\\n=== Operadores de Pertenencia ===\")\nprint(\"2 in m:\", 2 in m)\nprint(\"3 not in m:\", 3 not in m)\n\nprint(\"\\n=== Operadores de Bits ===\")\nx = 4  # 0100\ny = 1  # 0001\nprint(\"x & y:\", x & y)  # 0000\nprint(\"x | y:\", x | y)  # 0101\nprint(\"x ^ y:\", x ^ y)  # 0101\nprint(\"~x:\", ~x)        # complemento\nprint(\"x << 1:\", x << 1)  # 1000\nprint(\"x >> 1:\", x >> 1)  # 0010\n\n# =======================\n# ESTRUCTURAS DE CONTROL\n# =======================\n\nprint(\"\\n=== Condicionales ===\")\nedad = 20\nif edad >= 18:\n    print(\"Eres mayor de edad\")\nelif edad >= 13:\n    print(\"Eres adolescente\")\nelse:\n    print(\"Eres niño\")\n\nprint(\"\\n=== Bucle while ===\")\ni = 0\nwhile i < 3:\n    print(\"i vale:\", i)\n    i += 1\n\nprint(\"\\n=== Bucle for ===\")\nfor letra in \"hey\":\n    print(\"Letra:\", letra)\n\nprint(\"\\n=== Manejo de excepciones ===\")\ntry:\n    resultado = 10 / 0\nexcept ZeroDivisionError as e:\n    print(\"Error:\", e)\nfinally:\n    print(\"Bloque finally siempre se ejecuta\")\n\n# =======================\n# DIFICULTAD EXTRA\n# =======================\nprint(\"\\n=== Dificultad extra: Números pares entre 10 y 55, sin 16 ni múltiplos de 3 ===\")\nfor num in range(10, 56):\n    if num % 2 == 0 and num != 16 and num % 3 != 0:\n        print(num, end=\" \")\n    \nprint()  # Salto de línea final\nimport sys\nprint(sys.version)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Gordo-Master.py",
    "content": "### Operadores ###\n\n# Operadores aritmeticos\nprint(f\"Suma: 10 + 3: {10+3}\")\nprint(f\"Resta: 10 + 3: {10-3}\")\nprint(f\"Multiplicación: 10 * 3: {10*3}\")\nprint(f\"División: 10 / 3: {10/3}\")\nprint(f\"Módulo: 10 % 3: {10%3}\")\nprint(f\"Exponente: 10 ** 3: {10**3}\")\nprint(f\"División entera: 10 // 3: {10//3}\")\n\n# Operadores de bit a bit\nprint(bin(2))\nprint(bin(3))\nprint(f\"AND: 2 & 3: {2&3}\")\nprint(f\"OR: 2 | 3: {2|3}\")\nprint(f\"XOR: 2 ^ 3: {2^3}\")\nprint(f\"NOT: ~2 : {~2}\") # Tener en cuenta que los int tienen 8 bits en memoria | 2 = 00000010  \nprint(f\"Desplazamiento a la derecha: 2 >> 1: {2>>1}\") # El primero (base) en binario, el segundo (numero normal) cantidad de espacios deplazados\nprint(f\"Desplazamiento a la izquierda: 2 << 1:: {2<<1}\")\n\n\n# Operadores de asignación\na = 10 \nprint(f\"Asignación: a = 10: {a}\")\n\na += 1 \nprint(f\"Aplica un suma sobre la misma variable: a += 1: {a}\")\n\na *= 3 \nprint(f\"Aplica un multiplicación sobre la misma variable: a *= 3: {a}\")\n\na /= 3 \nprint(f\"Aplica un división sobre la misma variable: a /= 3: {a}\")\n\na %= 3 \nprint(f\"Aplica un modulo sobre la misma variable: a %= 3: {a}\")\n\na **= 3 \nprint(f\"Aplica un exponente sobre la misma variable: a **= 3: {a}\")\n\na //= 3 \nprint(f\"Aplica un división entera sobre la misma variable: a //= 3: {a}\")\n\na = 3\na &= 2 \nprint(f\"# Aplica un operación bit a bit AND sobre la misma variable: a &= 2: {a}\")\n\na |= 3 \nprint(f\"# Aplica un operación bit a bit OR sobre la misma variable: a |= 2: {a}\")\n\na ^= 2 \nprint(f\"# Aplica un operación bit a bit XOR sobre la misma variable: a ^= 2: {a}\")\n\na = 4\na >>= 2 \nprint(f\"# Aplica un operación bit a bit desplazamiento derecha sobre la misma variable: a >>= 2: {a}\")\n\na <<= 2 \nprint(f\"# Aplica un operación bit a bit desplazamiento izquierda sobre la misma variable: a <<= 2: {a}\")\n\n\n# Operadores lógicos\nprint(f\"AND, 2+3==5 and 3+4==7: {2+3==5 and 3+4==7}\")\nprint(f\"OR, 2+3==5 or 3+4==6: {2 or 3}\")\nprint(f\"NOT, not ({2+3==5}): {not 2+3==5}\")\n\n# Operadores de pertenencia\n\nprint(f\"Operación de pertenencia \\\"in\\\", devuelve un boolean de si el elemento se encuentra en la secuencia\")\nprint(f\" 5 in [1,4,81,34]: {5 in [1,4,81,34]}\")\n\nprint(f\"Operación de pertenencia \\\"not in\\\", devuelve un boolean de si el elemento no se encuentra en la secuencia\")\nprint(f\" 5 in [1,4,81,34]: {5 not in [1,4,81,34]}\")\n\n# Operador de identidad\nprint(f\"Operador de identidad \\\"is\\\" busca saber si ambos son los mismos objetos en el mismo espacio de memoria.\")\nprint(f\"Operador de identidad \\\"is not\\\" busca saber son objetos diferentes en diferentes espacios de memoria.\")\n# Hay que recordar que en python todo es un objeto.\n\n# Operadores de comparación\nprint(f\"Operador de comparación ==, ve si los valores de las variables son las mismas: 7 == 5 :{7 == 5}.\")\nprint(f\"Operador de comparación !=, ve si los valores de las variables son diferentes: 7 == 5 :{7 != 5}.\")\nprint(f\"Operador de comparación >, ve si el primero es mayor que el segundo: 7 > 5 :{7 > 5}.\")\nprint(f\"Operador de comparación <, ve si el primero es menor que el segundo: 7 < 5 :{7 < 5}.\")\nprint(f\"Operador de comparación >=, ve si el primero es mayor o igual que el segundo:: 7 >= 5 :{7 >= 5}.\")\nprint(f\"Operador de comparación <=, ve si el primero es menor o igual que el segundo: 7 <= 5 :{7 <= 5}.\")\n\n\"\"\"\nEstructura de control\n\"\"\"\n\n# Condicionales\n\nmy_string = \"Gordo-Master\"\n\nif my_string == \"Gordo-Master\":\n    print(\"my_string es 'Gordo-Master'\")\nelif my_string == \"Gordo\":\n    print(\"my_string es 'Gordo'\")\nelse:\n    print(\"my_string no es 'Gordo-Master'\")\n\n\n# Iterativas\n\nfor i in range(11):\n    print(i)\n\ni = 0\nwhile i <= 10:\n    print(i)\n    i +=1\n\n# Manejo de excepciones\ntry:\n    print(10/0)\nexcept:\n    print(\"Se ha producido un error\")\nfinally:\n    print(\"Ha finalizado el manejo de excepciones\")\n\nfor i in range(10,56):\n    if i != 16 and i % 2 == 0 and i % 3 !=0:\n        print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/HarrisonGuerrero18.py",
    "content": "# Operadores\n\nprint(\"Bienvenido al pequeño menú de para realizar operaciones aritméticas en Python\")\n\nprint('''\nEstas son las operaciones disponibles: \n1) Suma\n2) Resta\n3) Multiplicación\n4) División\n5) Exponenciación\n6) Módulo/Residuo\n''')\n\ndef sumar(num1, num2):\n    return num1 + num2\n\ndef restar(num1, num2):\n    return num1 - num2\n\ndef multiplicar(num1, num2):\n    return num1 * num2\n\ndef pedir_numero(mensaje):\n    while True:\n        try:\n            valor = float(input(mensaje))\n            return int(valor) if valor % 1 == 0  else valor\n        except ValueError:\n            print(\"Error: debes ingresar un número válido.\")\n\ndef dividir(num1, num2):\n    if num2 == 0:\n        return \"Error. No se puede dividir entre 0\"\n    if num1 % 1 == 0 and num2 % 1 == 0:\n        if num1 % 2 == 0 or num2 % 2 == 0:\n            return num1 // num2\n        else:\n            return num1 // num2\n    else:\n        return num1 / num2\n    \n\ndef exponenciar(num1, num2):\n    return num1**num2\n\ndef modular(num1, num2):\n    return num1 % num2\n\ntry:\n    opcion = int(input(\"Ingresa el numero correspondiente a tu elección: \"))\nexcept ValueError:\n    print(\"Debes ingresar un número válido\")\n\nmatch opcion:\n    case 1:\n        x = int(input(\"Digita un número: \"))\n        y = int(input(\"Digita otro número: \"))\n        print(f'El resultado de la suma entre {x} y {y} es: {sumar(x,y)}')\n    case 2: \n        x = int(input(\"Digita un número: \"))\n        y = int(input(\"Digita otro número: \"))\n        print(f'El resultado de la resta entre {x} y {y} es: {restar(x,y)}')\n    case 3:\n        x = int(input(\"Digita un número: \"))\n        y = int(input(\"Digita otro número: \"))\n        print(f'El resultado de multiplicar {x} x {y} es: {multiplicar(x,y)}')\n    case 4:\n        x = pedir_numero(\"Digita un número: \")\n        y = pedir_numero(\"Digita otro número: \")\n        resultado = dividir(x,y)\n        print(f\"El resultado de la división entre {x} y {y} es: {resultado if resultado % 1 != 0 else int(resultado)}\")\n    case 5:\n        x = int(input(\"Digita un número: \"))\n        y = int(input(\"Digita otro número: \"))\n        print(f'El resultado de exponer {x} sobre {y} es: {exponenciar(x,y)}')\n    case 6:\n        x = int(input(\"Digita un número: \"))\n        y = int(input(\"Digita otro número: \"))\n        print(f'El residuo que queda al dividir {x} entre {y} es: {modular(x,y)}')  \n    case _:\n        print(\"Digitaste un valor incorrecto. Rango:1-6\")\n        \n# Operadores de comparación\n\nprint(\"Operadores de comparación: tendrás que ingresar 2 números para compararlos\")\n\ndef pedir_numeros(mensaje):\n    while True:\n        try:\n            return int(input(mensaje))\n        except ValueError as e:\n            print(f\"Error: Debes ingresar un número válido. Por favor, inténtalo de nuevo. Detalle: {e}\")\n        \ndef comparar_numeros (num1, num2):\n    if num1>num2:\n        return f\"{num1} es mayor que {num2}\"\n    elif num1 < num2:\n        return f\"{num1} es menor que {num2}\"\n    elif x == y:\n        return f\"{num1} y {num2} son el mismo número\"\n\nx = pedir_numeros(\"Ingresa un número: \")\ny = pedir_numeros(\"Ingresa otro número: \")\n\nprint(comparar_numeros(x,y))\n\n# Operadores lógicos\n\nprint(\"Operadores lógicos. Aquí tendrás que escribir verdadero o falso segun la comparación\")\n\ndef obtener_operaciones():\n    caso_uno = 5 > 2 and not 10 > 5\n    caso_dos = 3 == 2 or 6 > 3\n    caso_tres = 10 % 2 == 0 and not 10 % 2 == 5 / 5\n    caso_cuatro = 4**4 >= 125 or 56 / 8 <= 7 and 12 / 6 + 5 * 3 >= 18 or not 5 * 12 / 2 + 8 == 6 ** 3 - 526 / 2\n    caso_cinco = not 25 / 5 ** 3 + 6 == 16 * 4 / 2 - 100 or 32 * 2 / 8 ** 2 + 140 == 50 * 6 + 15 / 5 ** 4 and not 268 / 14 + 22 * 7 ** 2 - 19 == 1998 / 6 + 3 * 12 - 4 ** 3\n    \n    return [caso_uno, caso_dos, caso_tres, caso_cuatro, caso_cinco]\n\ndef evaluar_operaciones(operaciones):\n    resultados = []\n    for i, resultado in enumerate(operaciones, start=1):\n        respuesta = input(f\"¿Es verdadero o falso el caso {i}: {resultado}? \")\n        resultados.append((i, respuesta.lower() == \"verdadero\"))\n    return resultados\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/HendryAvila.py",
    "content": "#operadores aritmeticos\nprint(f\"\"\" \nNombre          | Representacion  |  Ejemplo\nSuma            +                    1 + 2\nResta           -                    10 - 2\nMultiplicacion  *                    1 * 2\nDivision        /                    10 / 5\nDivision entera //                   10.5 // 4\nModulo          %                    10 % 3\nExponente       **                   10 ** 2\n\"\"\")\n\n#Operadores de comparacion\nprint(f\"\"\" \nNombre          | Representacion  |  Ejemplo\nIgual a           ==                    2 == 2\nDistinto de       !=                   10 != 2\nmenor que         <                    1 < 2\nMayor que         >                    10 > 5\nMenor o igual que <=                   10.5 <= \nMayor o igual que >=                   10 >= 3\n\"\"\")\n\n#Operadores logicos\nprint(f\"\"\" \nNombre          | Representacion  |  Ejemplo\nAND               and             True and True        \nOR                or             True or False   \nNOT               not            not True\n\"\"\")\n\n#Operadores de asignacion\nprint(f\"\"\" \nNombre          | Representacion  |  Ejemplo\nA.Suma            +=                    1 + 2\nA.Resta           -=                    10 - 2\nA.Multiplicacion  *=                    1 * 2\nA.Division        /=                    10 / 5\nA.Division entera //=                   10.5 // 4\nA.Modulo          %=                    10 % 3\nA.Exponente       **=                   10 ** 2\nA.bitwise AND     &=                   h &= 3\nA.bitwise OR      |=                   h |= 5\nA.bitwise XOR     ^=                   h ^= 5 \n\"\"\")\n\n#Operadores de identidad(compara posicion en memoria)\nprint(f\"\"\" \nNombre          | Representacion  |  Ejemplo\nEs               is                  a is b\nNo es           not is               a is not b\n\"\"\")\n\n#Operadores de pertenencia\nprint(f\"\"\" \nNombre          | Representacion  |  Ejemplo\nEsta              in                  2 in [1,2,3,4,5]\nno esta           not in              2 is not [1,2,3,4,5]\n\"\"\")\n\n#Operadores de bitwise\nprint(f\"\"\" \nNombre          | Representacion  |  Ejemplo\nAND bit a bit     &                  a & b\nOR bit a bit      |                  a | b\nXOR bit a bit     ^                  a ^ b\nDesplazamiento a la izq. <<          a<< b\nDesplazamiento a la der. >>          a >> b\n\"\"\")\n\n#Operadores de ternario\nprint(f\"\"\" \nNombre          | Representacion  |  Ejemplo\nternario         is-else            a if x == b else b\n\"\"\")\n\n#Operadores de walrus\nprint(f\"\"\" \nNombre          | Representacion  |  Ejemplo\nwalrus           :=                (x := valor)\n\"\"\")\n\n\n\n\n\n#control de flujo iterativo\n\n#for con funcion range\nfor i in range(10):\n    print(i)\n\n#While\nnumber = 0\nwhile(number < 10):\n    print(number)\n    number += 1\n    \n#Control de flujos condicionales\n\nif 10 < 15:\n    print(\"10 es menor que 15\")\nelif 10 < 20:\n    print(\"10 es menor que 20\")\nelse:\n    print(\"Esto es un else, se entra cuando las condiciones anteriores no se completaron\")\n    \n    \nprint(\"Ejercicio extra\")\n\nmy_list = [item for item in range(10, 56)if item != 16 and item % 2 == 0 and item % 3 != 0]\nprint(my_list)\n\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Hyromy.py",
    "content": "# ---- OPERADORES ----\n# Aritmeticos\n\"\"\"\n+ suma\n- resta\n* multiplicacion\n/ division\n% modulo\n// division redondeada\n** potencia\n\"\"\"\n\n# Logicos\n\"\"\"\nand y\nor o\nnot no\n\"\"\"\n\n# Comparacion\n\"\"\"\n== igual que\n!= diferente que \n< menor que\n<= menor o igual que\n> mayor que\n>= mayor o igual que\n\"\"\"\n\n# Asignacion\n\"\"\"\n= igual\n+= agregar\n-= disminuir\n*= producto\n/= repartir\n%= sobrante\n//= repartir (redondeado)\n**= potenciar\n\"\"\"\n\n# Pertenencia\n\"\"\"\nis es\nis not no es\n\"\"\"\n\n# Bits\n\"\"\"\n& y\n| o\n^ o exclusivo\n<< desplazamiento izquierda\n>> desplazamiento derecha\n\"\"\"\n\n# Adicionales\n\"\"\"\n+ concatenacion (strings)\n* repeticion (strings)\n[] idenxacion (arrays)\n[:] slicing (arrays)\n\"\"\"\n\n# ---- EJEMPLOS DE OPERADORES ----\n\nprint(\"Modulo y Division redondeada\")\n\n# cociente de la division = 5\n# residuo de la division = 3\nprint(23 % 4) # 3\n\n# resultado de la division = 5.75\n# cociente de la division = 5\nprint(23 // 4) # 5\nprint()\n\n# ----\n\nprint(\"Asignacion\")\n\nvar_1 = 15\nvar_1 += 2 # var_1 = var_1 + 2\nprint(var_1)\n\nvar_2 = 10\nvar_2 **= 3 # var_2 = var_2 ** 3\nprint(var_2)\nprint()\n\n# ----\n\nprint(\"Pertenencia\")\n\nobj_1 = [1, 2, 3]\nobj_2 = [1, 2, 3]\nobj_3  = obj_1\n\nprint(obj_1 is obj_2) # aunque sus valores seas identicos, son objetos diferentes\nprint(obj_1 is obj_3) # obj_1 y obj_3 hacen referencia al mismo objeto\nprint()\n\n# ----\n\nprint(\"Bits\")\n\nbit_1 = 5 # numero binario      0101\nbit_2 = 12 # numero binario     1100\n\nprint(bit_1 & bit_2) # salida   0100\nprint(bit_1 | bit_2) # salida   1101\nprint(bit_1 ^ bit_2) # salida   1001\nprint(bit_1 << 1) # salida      1010\nprint(bit_1 << 3) # salida    101000\nprint(bit_1 >> 2) # salida      0001\nprint()\n\n# ----\n\nprint(\"Adicionales\")\n\nstr_1 = \"Hola\"\nstr_2 = \"Python\"\n\nstr_3 = str_1 + str_2\nprint(str_3)\n\nstr_4 = (str_1 + \"_\") * 3\nprint(str_4)\n\nlist_1 = [55, 1.77, \"Hyromy\", True]\nprint(list_1[2])\n\"\"\"\nlist_1[0] = 55\nlist_1[1] = 1.77\nlist_1[2] = \"Hyromy\"\nlist_1[3] = True\n\"\"\"\n\nprint(list_1[1:3]) # selecciona desde el primer indice hasta el ultimo (sin inluirlo)\n\nmoure_dev = \"MoureDev\"\nprint(moure_dev[0:5])\nprint()\n\n# ---- EJEMPLOS DE ESTRUCTURAS DE CONTROL ----\nprint(\"Estructuras de control\")\n\n\n# Condicion si (if)\nedad = 19\ncondicion = edad >= 18 # True\n\nif condicion: # Si la condicion se cumple...\n    \n    # hacemos esto\n    print(\"Eres mayor de edad\")\n    print(\"Eres mayor de edad\") \n\n\n# Condicion de lo contrario (else)\nif False:\n    print(\"Este es en caso de que la condicion no se haya cumplido\")\nelse: # En caso de que nada se cumpla\n    print(\"La condicion no se cumplió\")\n    print(\"Pero aun asi puedo hacer algo\")\n  \n    \n# Condicion de lo contrario si (else if)\nnombre = \"Hyromy\"\nif nombre == \"MoureDev\":\n    print(\"Hola MoureDev :D\")\nelif nombre == \"Hyromy\": # Si lo anterior no se cumplió, voy a ver si esta condicion se cumple\n    print(\"Hola yo ¿Como estas?\")\nelse: # en caso de que nada se cumpla\n    print(\"Hola \" + nombre)\n    \n    \n# Estructura de control de flujo condicional (if serial)\nestrellas = 4\nif estrellas == 1:\n    print(\"es una estrella\")\nelif estrellas == 2:\n    print(\"son dos estrellas\")\nelif estrellas == 3:\n    print(\"son tres estrellas\")\nelif estrellas == 4:\n    print(\"son cuatro estrellas\")\nelif estrellas == 5:\n    print(\"son cinco estrellas\")\nelse:\n    print(\"solo se contar hasta 5\")    \n\n\n# if anidado (if paralelo)\ncoche_color = \"rojo\"\ncoche_ruedas = 6\n\nif coche_color == \"rojo\":\n    if coche_ruedas < 4:\n        print(\"eso es una moto\")\n    elif coche_ruedas == 4:\n        print(\"que bonito coche rojo\")\n    else:    \n        print(\"¿por que tiene \" + str(coche_ruedas) + \" ruedas?\")\nelse:\n    print(\"no me gusta el color\")\n\n\n# manejo de errores (try except)\nnumero = 10\ndivisor = 0\n\ntry: # codigo que pueda dar errores durante su ejecucion\n    resultado = numero / divisor\n    print(\"el resultado es \" + str(resultado))\n    \nexcept Exception as e: # accciones en caso de error y evitar que el programa se pare\n    print(\"algo salió mal\")\nprint()\n\n\n# Sentencia mientras (while)\nnumero = 2.3\nwhile numero < 100:\n    print(\"el numero vale \" + str(numero))\n    numero *= 2\nelse: # acciones cuando el bucle termine de forma natural\n    print(\"la sentencia while terminó\")\n    \n    \n# Sentencia while interrumpida\nnumero = 1\n\nwhile numero != 10:\n    if numero == 5:\n        break \n    \n    print(\"el numero vale \" + str(numero))\n    numero += 1\nelse: # no se ejecuta porque el bucle se interrumpió\n    print(\"la sentencia while terminó de forma natural\")\nprint()\n    \n\n# bucle for (iterar)\nfor i in range(0, 10): # itera la variable i del 0 hasta el 10 (sin incluirlo)\n    print(i)\nelse: # acciones cuando el bucle termine\n    print(\"el for terminó\")\n    \n# bucle for interrumpido\nfor x in range(1, 100):\n    if x == 12:\n        break\n    print(x)\nelse:\n    print(\"el for terminó\")\n    \n# sentencia continue\nfor y in range(0, 5):\n    if y == 3:\n        print(\"se omitió esta iteracion\")\n        continue # todo lo que vaya delante no se ejecuta pero el bucle continua\n    print(y)\nelse:\n    print(\"el for terminó\")\n    \n\n# ---- DIFICULTAD ADICIONAL ----\nprint(\"DIFICULTAD ADICIONAL\\n\")\n\nfor i in range(10, 55):\n    if i % 2 == 0 and i != 16 and not i % 3 == 0:\n        print(i)\nelse:\n    print(i + 1)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Irenetitor.py",
    "content": "# 1. All operators categories: Arithmetic, Assignment, Comparison, Logical, Identity, Membership, Bitwise\n\n#Arithmetic Operators: +, -, *, /, %, **, //\nAddition = 10 + 5\nSubtraction = 10 - 5    \nMultiplication = 10 * 5\nDivision  = 10 / 5        #(always float )\nFloor_Division  = 10 // 3   #(rounds down to nearest whole number)\nModulus  = 10 % 3    #(remainder of division)\nExponentiation = 10 ** 2\n\n#Comparison Operators: ==, !=, >, <, >=, <=\nEqual = (10 == 5)          #False(checks if values are equal)\nNot_Equal = (10 != 5)      #True(checks if values are not equal)\nGreater_than = (10 > 5)    #True\nLess_than = (10 < 5)       #False\nGreater_than_or_equal_to = (10 >= 5)  #True\nLess_than_or_equal_to = (10 <= 5)     #False\n\n#Logical Operators: and, or, not\nLogical_AND = (10 > 5 and 5 < 3)  #False(both conditions must be true)\nLogical_OR = (10 > 5 or 5 < 3)   #True(at least one condition must be true)\nLogical_NOT = not(10 > 5)         #False(inverts the boolean value)\n\n#Assignment Operators: =, +=, -=, *=, /=, %=, //=, **=\na = 10      #Assigns value 10 to a\na += 5      #Equivalent to a = a + 5 (now a is 15)\na -= 3      #Equivalent to a = a - 3 (now a is 12)\na *= 2      #Equivalent to a = a * 2 (now a is 24)\na /= 4      #Equivalent to a = a / 4 (now a is 6.0)\na %= 4      #Equivalent to a = a % 4 (now a is 2.0)\na //= 2     #Equivalent to a = a // 2 (now a is 1.0)\na **= 3     #Equivalent to a = a ** 3 (now a is 1.0)\n\n#Identity Operators: is, is not\nx = [\"apple\", \"banana\"] #True (same object in memory)\ny = [\"apple\", \"banana\"] #False (different objects in memory)\n\n#Bitwise Operators: &, |, ^, ~, <<, >>\nBitwise_AND = 5 & 3    #1 (binary 0101 & 0011 = 0001)\nBitwise_OR = 5 | 3     #7 (binary 0101 | 0011 = 0111)\nBitwise_XOR = 5 ^ 3    #6 (binary 0101 ^ 0011 = 0110)\nBitwise_NOT = ~5       #-6 (inverts bits, ~0101 = 1010 which is -6 in two's complement)\nLeft_Shift = 5 << 1    #10 (binary 0101 << 1 = 1010)\nRight_Shift = 5 >> 1   #2 (binary 0101 >> 1 = 0010) \n\n#Membership Operators: in, not in\nfruits = [\"apple\", \"banana\", \"cherry\"] #True (checks if \"banana\" is in the list)\nhas_mango = \"mango\" not in fruits #True (checks if \"mango\" is not in the list)\n\n# 2. Control structures: if, elif, else, for, while, break, continue, pass\n#Sequential structure (default mode, executes statements one after another)\nprint(\"Start\")\nprint(\"Middle\")\nprint(\"End\")\n\n#A. Conditional Statements (decision-making)\nage = 20\nif age < 18:\n    print(\"Minor\")\nelif age == 18:\n    print(\"Just became an adult\")\nelse:\n    print(\"Adult\")\n\n#nested if\nif age >= 18:\n    if age < 65:\n        print(\"Adult\")\n    else:\n        print(\"Senior\")\n\n\n#B. Iteration (loops)\n#For loop (iterates over a sequence)\nfruits = [\"apple\", \"banana\", \"cherry\"]\nfor fruit in fruits:\n    print(fruit)\n\n#While loop (repeats as long as a condition is true)\ncount = 0\nwhile count < 5:\n    print(count)\n    count += 1  #Increment count to avoid infinite loop\n\n#Nested loops (loops inside loops) (Used for multi-dimensional logic)\nfor i in range(3):  #Outer loop\n    for j in range(2):  #Inner loop\n        print(f\"i: {i}, j: {j}\")\n\n#C. Jump statements (alter the flow of loops)\n#Continue statement (skips the current iteration)\nfor i in range(10):\n    if i % 2 == 0:\n        continue  #Skip even numbers\n    print(i)  #Prints only odd numbers  \n\n#Break statement (exits the loop)\nfor i in range(10):\n    if i == 5:\n        break  #Exit loop when i is 5\n    print(i)\n\n#Pass statement (does nothing, used as a placeholder)\nfor i in range(5):\n    pass  #No operation, can be used to create empty loops or functions\nprint(\"Loop completed\")\n\n#D. Exception Handling (try, except, finally)\ntry:\n    result = 10 / 0  #This will raise a ZeroDivisionError\nexcept ZeroDivisionError:\n    print(\"Error: Division by zero is not allowed.\")\nfinally:\n    print(\"Execution completed.\")\n#The finally block always executes, regardless of whether an exception occurred or not.\n\n#3. Print Examples\n\n#4. Optional exercise \n\nfor x in range(10, 56, 1):\n    if x % 2 != 0 or x == 16 or x % 3 == 0:\n        continue\n    print(x)\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/JAdraz.py",
    "content": "''' - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)'''\n\n''' - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n    que representen todos los tipos de estructuras de control que existan\n    en tu lenguaje:\n    Condicionales, iterativas, excepciones...'''\n\n''' - Debes hacer print por consola del resultado de todos los ejemplos.'''\n\n## -- Arithmethic Operators --\nnum1 = 1\nnum2 = 2\n\n# --- Additions ---\n\naddition = num1 + num2\nprint(f\"Addition \\n The addition results is: {addition}\")\n\n# --- Substraction ---\nsubstraction = num2 - num1\nprint(f\"Substraction \\n The substraction result is: {substraction}\")\n\n# --- Multiplication ---\nmultiplication = num1 * num2\nprint(f\"Multipliation\\n The multiplication result is: {multiplication}\")\n\n# --- Division ---\ndivision = int(num2 / num1)\nprint(f\"Division \\n The division result is: {division}\")\n\n# --- Module ---\nmodule = num2 % num1\nprint(f\"Module \\n The module result is: {module}\")\n\n# --- Exponentation ---\nexponentation = num2 ** num1\nprint(f\"Exponentation \\n The exponentation result is: {exponentation}\")\n\n# --- Floor Division ---\nfloor_division = num2 // num1\nprint(f\"Floor Division \\n The floor division result is: {floor_division}\")\n\n## -- Assignment Operators --\n\n# --- Assignment ---\nassignment = num1\nprint(f\"Assignment \\n The assigment result is: {assignment}\")\n\n# --- Addition Assigment ---\nnum1 += 1\nprint(f\"Addition Assigment \\n The addition assigment result is: {num1}\")\n\n# --- Substraction Assigment ---\nnum2 -= 1\nprint(f\"Substraction Assigment \\n The substraction assigment result is: {num2}\")\n\n# --- Multiplication Assigment ---\nnum2 *= 3\nprint(f\"Multiplication Assigment \\n The multiplication assigment result is: {num2}\")\n\n# --- Divison Assigment ---\nnum2 /= 1\nprint(f\"Divison Assigment \\n The division assigment result is: {num2}\")\n\n# --- Modulus Assigment ---\nnum2 %= 1\nprint(f\"Modulus Assigment \\n The modulus assigment result is: {num2}\")\n\n# --- Floor Division Assigment ---\nnum1 //= 3\nprint(f\"Floor Division Assigment \\n The floor division assigment result is: {num1}\")\n\n# --- Exponentation Assigment ---\nnum2 = 3\nnum2 **= 5\nprint(f\"Exponentation Assigment \\n The exponentation assigment result is: {num2}\")\n\n# --- Bitwise AND Assigment ---\na = 5\na &= 3\nprint(f\"Bitwise AND Assigment \\n The bitwise AND assigment result is: {a}\")\n\n# --- Bitwise OR Assigment ---\nb = 5\nb |= 3\nprint(f\"Bitwise OR Assigment \\n The bitwise OR assigment result is: {b}\")\n\n# --- Bitwise XOR Assigment ---\nc = 5\nc ^= 3\nprint(f\"Bitwise XOR Assigment \\n The bitwise XOR assigment result is: {c}\")\n\n# --- Left Shift Assigment ---\nd = 5\nd <<= 2\nprint(f\"Left Shift Assigment \\n The left shift assigment result is: {d}\")\n\n# --- Right Shift Assigment ---\ne = 20\ne >>= 2\nprint(f\"Right Shift Assigment \\n The right shift assigment result is: {e}\")\n\n\n## -- Comparison Operatos --\nnum3 = 5\nnum4 = 10\n\n# --- Equal ---\nprint(\"Equal Operator\")\nif num3 == num4:\n    print(\"\\n They are equal\")\nelse:\n    print(\"\\n They are not equals\")\n\n# --- Not Equal ---\nprint(\"Not Equal Operators\")\nif num3 != num4:\n    print(\"\\n They are differents\")\nelse:\n    print(\"\\n They are equals\")\n\n# --- Greater Than ---\nprint(\"Greater Than Operator\")\nif num3 > num4:\n    print(f\"\\n {num3} is greater than {num4}\")\nelse:\n    print(f\"\\n {num3} is not greater than {num4}\")\n\n# --- Less Than ---\nprint(\"Less Than Operator\")\nif num3 < num4:\n    print(f\"{num3} is less than {num4}\")\nelse:\n    print(f\"{num3} is not less than {num4}\")\n\n# --- Greater Than or Equal to ---\nprint(\"Greater Than or Equal to Operator\")\nif num3 >= num4:\n    print(f\"\\n {num3} is greater than or equal to {num4}\")\nelse:\n    print(f\"\\n {num3} is not greater than or equal to{num4}\")\n\n# --- Less Than or Equal to ---\nprint(\"Less Than or Equal to Operator\")\nif num3 <= num4:\n    print(f\"{num3} is less than or equal to {num4}\")\nelse:\n    print(f\"{num3} is not less than or equal to{num4}\")\n\n## -- Logical Operators --\nnum5 = 3\nnum6 = 7\n\n# --- AND Operator ---\nprint(f\"AND Operator\")\nif num3 < num4 and num3 == num5:\n    print(\"\\n True\")\nelse:\n    print(\"\\n False\")\n\n# --- OR Operator ---\nprint(f\"OR Operator\")\nif num3 < num4 or num3 == num6:\n    print(\"\\n True\")\nelse:\n    print(\"\\n False\")\n    \n# --- NOT Operator ---\nprint(f\"NOT Operator\")\nif not(num3 < num4 or num3 == num6):\n    print(\"\\n True\")\nelse:\n    print(\"\\n False\")\n\n## -- Identity Operatos\n\n# --- IS Operator ---\nprint(\"Identity Operators\")\nif num3 is num5:\n    print(\"They are the same\")\nelse:\n    print(\"They are not the same\")\n\n## -- Membership Operators\n\n# --- IN Operator ---\nlist1 = [1, 2, 3]\nl1 = 1\nl2 = 4\n\nprint(\"IN Operator\")\n\nif l1 in list1:\n    print(f\"\\n {l1} in in the list\")\nelse:\n    print(f\"\\n {l1} is not in the list\")\n\n# --- NOT IN Operator ---\nif l2 not in list1:\n    print(f\"\\n {l2} is not in the list\")\nelse:\n    print(f\"\\n {l2} is in the list\")\n\n''' DIFICULTAD EXTRA (opcional):\n    Crea un programa que imprima por consola todos los números comprendidos\n    entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\n    Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.'''\n\nprint(\"Optional Exercise\")\n\nfor i in range(10, 56):\n    if i == 16:\n        pass\n    elif i % 3 == 0:\n        pass\n    elif i % 2 == 0:\n        print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/JacMac45.py",
    "content": "# Operadores\n\n# 📌 OPERADORES ARITMETICOS\n\nprint(\"\\n======== OPERADORES ARITMETICOS ========\")\nprint(f\"Suma: 2+2 = {2+2}\")\nprint(f\"Resta: 4-2 = {4-2}\")\nprint(f\"Multiplicacion: 2*2 = {2*2}\")\nprint(f\"Division 10/3:  = {10/3}\")\nprint(f\"Division Entera 10//3:  = {10//3}\")\nprint(f\"Resto : 2%2 = {2%2}\")\nprint(f\"Exponente : 2**2 = {2**2}\")\n\n# 📌 OPERADORES DE COMPARACIÓN\n\nprint(\"\\n======== OPERADORES DE COMPARACIÓN ========\")\nprint(f\"Igualdad: 10 == 3 {10 == 3}\")\nprint(f\"Desigualdad: 10 != 3 {10 != 3}\")\nprint(f\"Mayor que: 10 > 3 {10 > 3}\")\nprint(f\"Menor que: 10 < 3 {10 < 3}\")\nprint(f\"Mayor o igual que: 10 >= 3 {10 >= 3}\")\nprint(f\"Menor o igual que: 10 <= 3 {10 <= 3}\")\n\n# 📌 OPERADORES LOGICOS\n\nprint(\"\\n======== OPERADORES LOGICOS ========\")\nprint(f\"AND: 10 + 3 == 13 and 5 - 1 == 4 es: {10 + 3 == 13 and 5 - 1 == 4}\")\nprint(f\"OR: 10 + 4 == 13 or 5 - 1 == 4 es: {10 + 4 == 13 or 5 - 1 == 4}\")\nprint(f\"NOT: not 10 + 3 == 14 es: {not 10 + 3 == 14}\")\n\n# 📌 OPERADORES DE ASIGNACION\n\nprint(\"\\n======== OPERADORES DE ASIGNACIÓN ========\")\nmy_number = 11 #asignacion\nprint(my_number)\nmy_number += 1 #suma y asignacion\nprint(my_number)\nmy_number -= 1 #resta y asignacion\nprint(my_number)\nmy_number *= 1 #multiplicacion y asignacion\nprint(my_number)\nmy_number /= 1 #division y asignacion\nprint(my_number)\nmy_number %= 2 #modulo y asignacion\nprint(my_number)\nmy_number **= 2 #exponente y asignacion\nprint(my_number)\nmy_number //= 2 #division entera y asignacion\nprint(my_number)\n\n# 📌 OPERADORES DE IDENTIDAD\n\nprint(\"\\n======== OPERADORES DE IDENTIDAD ========\")\nmy_new_number = my_number\nprint(f\"OPERADOR DE IDENTIDAD (is) my_number is my_new_number es {my_number is my_new_number}\")\nmy_new_number = 1.0\nprint(f\"OPERADOR DE IDENTIDAD (is) my_number is my_new_number es {my_number is my_new_number}\")\nprint(f\"OPERADOR DE NO IDENTIDAD (is not) my_number is my_new_number es {my_number is not my_new_number}\")\n\n# 📌 OPERADORES DE PERTENENCIA\n\nprint(\"\\n======== OPERADORES DE PERTENENCIA ========\")\nprint(f\"OPERADOR (in) 'i' in 'Danilo => {'i' in 'Danilo'}'\")\nprint(f\"OPERADOR (not in) 'i' not in 'Danilo => {'i' not in 'Danilo'}'\")\n\n# 📌 OPERADORES DE BIT\n\nprint(\"\\n======== OPERADORES DE BIT ========\")\na = 10 # 1010\nb = 3 # 0011\n\nprint(f\"AND: 10 & 3 = {10 & 3}\") # 0010\nprint(f\"OR: 10 | 3 = {10 | 3}\") # 1011\nprint(f\"XOR: 10 ^ 3 = {10 ^ 3}\") # 1001\nprint(f\"NOT: ~10 = {~10}\")\nprint(f\"Desplazamiento a la derecha: 10 >> 2 = {10 >> 2}\") # 0010\nprint(f\"Desplazamiento a la izquierda: 10 << 2 = {10 << 2}\") # 101000\n\n\n# ESTRUCTURAS DE CONTROL\n\n# 📌 CONDICIONALES\n\nprint(\"\\n======== CONDICIONALES ========\")\n\nprint(\"\\n======== IF ELSE ========\")\nmy_name = \"Hola\"\n\nif my_name == \"Danilo\":\n    print('my_name es : \"Danilo\"')\nelif my_name == \"Calderon\":\n    print('my_name es: \"Calderon\"')\nelse:\n    print(\"my_name no es 'Danilo' ni 'Calderon'\")\n\n# 📌 ITERATIVAS\n\nprint(\"\\n======== ITERATIVAS ========\")\n\nprint(\"\\n======== FOR IN ========\")\nfor i in range(11):\n    print(i)\n\nprint(\"\\n======== WHILE ========\")\ni = 0\nwhile i <= 10:\n    print(i)\n    i += 1\n\n# 📌 MANEJO DE EXCEPCIONES\n\nprint(\"\\n======== MANEJO DE EXCEPCIONES ========\")\ntry:\n    print(10 / 0)\nexcept:\n    print(\"Ha ocurrido un error\")\nfinally:\n    print(\"Ha finalizado el manejo de excepciones\")\n    \n# 📌 EXTRA\n    \nfor i in range(10, 56):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print(i)\n    \n    \nnumber = 10\n\nwhile number < 56:\n    if number % 2 == 0 and number != 16 and number % 3 != 0:\n        print(number)\n    number += 1\n    \n    "
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Jackziel-Sumoza.py",
    "content": "\n#** Operadores\n\nnum_1 = 24\nnum_2 = 54\nnum_3 = 2.45\n\n#* Aritméticos\nprint()\nprint(\"OPERADORES ARITMÉTICOS\")\nprint(f\"Esto es una suma {num_1} + {num_2}: {num_1 + num_2}\")\nprint(f\"Esto es una resta {num_1} - {num_2}: {num_1 - num_2}\")\nprint(f\"Esto es una división {num_1} / {num_2}: {num_1 / num_3}\")\nprint(f\"Esto es una división entera {num_1} // {num_2}: {num_1 // num_3}\")\nprint(f\"Esto es una multiplicación {num_1} * {num_2}: {num_1 * num_2}\")\nprint(f\"Esto es modulo o resto {num_1} % {num_2}: {num_1 % num_3}\")\nprint(f\"Esto es una potencia {num_1} ** {num_2}: {num_1 ** num_3}\")\n\n#* Lógicos\nprint()\nprint(\"OPERADORES LÓGICOS\")\nprint(f\"{num_1} es igual a {num_2} y {num_2} es igual a {num_3}: {num_1 == num_2 and num_2 == num_3}\")\nprint(f\"{num_1} es menor {num_2} o {num_2} es igual a {num_3}: {num_1 < num_2 or num_2 == num_3}\")\nprint(f\"{num_1} no es igual a {num_2}: {not num_1 ==  num_2}\")\n\n#* Comparación\nprint()\nprint(\"OPERADORES DE COMPARACIÓN\")\nprint(f\"Igual que {num_1} == {num_2}: {num_1 == num_2}\")\nprint(f\"Distinto de {num_1} != {num_2}: {num_1 != num_2}\")\nprint(f\"Mayor que {num_1} > {num_2}: {num_1 > num_2}\")\nprint(f\"Menor que {num_1} < {num_2}: {num_1 < num_2}\")\nprint(f\"Mayor o igual que {num_1} >= {num_2}: {num_1 >= num_2}\")\nprint(f\"Menor o igual que {num_1} <= {num_2}: {num_1 <= num_2}\")\n\n#* Asignación\nprint()\nprint(\"OPERADORES DE ASIGNACIÓN\")\nnum_1 = 25\nprint(f\"asignar un valor 25: {num_1}\")\nnum_1 += 2\nprint(f\"sumar dos: {num_1}\")\nnum_1 -= 2\nprint(f\"restar dos: {num_1}\")\nnum_1 *= 4\nprint(f\"multiplicar por cuatro: {num_1}\")\nnum_1 /= 1\nprint(f\"dividir entre uno: {num_1}\")\nnum_1 //= 2\nprint(f\"división entera entre dos: {num_1}\")\nnum_1 %= 3\nprint(f\"Modulo de tres: {num_1}\")\nnum_1 **= 3\nprint(f\"elevación al cubo: {num_1}\")\n\n#* Identidad\nprint()\nprint(\"OPERADORES DE IDENTIDAD\")\nobjeto_1 = [1,2,3]\nobjeto_2 = objeto_1\nobjeto_3 = [1,2,3]\nprint(f\"objeto_2 se refiere al mismo objeto que objeto_1: {objeto_1 is objeto_2}\")\nprint(f\"objeto_3 no se refiere al mismo objeto que objeto_1: {objeto_3 is not objeto_1}\")\n\n#* Pertenencia\nprint()\nprint(\"OPERADORES DE PERTENENCIA\")\nlista_1 = [1,2,3,4,5,6,7,8,9,10]\nprint(f\"El numero 7 se encuentra en la lista_1: {10 in lista_1}\")\nprint(f\"La palabra \\\"Python\\\" no se encuentra en la lista_1: {\"Python\" not in lista_1}\")\n\n#* Bits\nprint()\nprint(\"OPERADORES DE BITS\")\nbinario_1, binario_2 = 20, 43 \n# Si ambos bits correspondientes son 1, el resultado es 1; de lo contrario, es 0.\nprint(f\"Operador binario and: {bin(binario_1)} AND[&] {bin(binario_2)}: {bin(binario_1 & binario_2)}\")\n# Si al menos uno de los bits correspondientes es 1, el resultado es 1; de lo contrario, es 0.\nprint(f\"Operador binario or: {bin(binario_1)} OR[|] {bin(binario_2)}: {bin(binario_1 | binario_2)}\")\n# Si los bits correspondientes son diferentes, el resultado es 1; de lo contrario, es 0.\nprint(f\"Operador binario xor: {bin(binario_1)} XOR[^] {bin(binario_2)}: {bin(binario_1 ^ binario_2)}\")\n# Invierte todos los bits de un número.\nprint(f\"Operador binario not: {bin(binario_1)} NOT[~]: {bin(~ binario_2)}\")\n# Desplaza todos los bits de un número una cierta cantidad de posiciones hacia la izquierda, llenando los espacios vacíos con ceros.\nprint(f\"Desplazar a la derecha: 2 posiciones a {bin(binario_2)} [>>]: {bin(binario_1 >> 2)}\")\n#  Desplaza todos los bits de un número una cierta cantidad de posiciones hacia la derecha. El comportamiento del bit más a la izquierda depende del tipo de entero (con o sin signo).\nprint(f\"Desplazar a la izquierda: 2 posiciones a {bin(binario_1)} [<<]: {bin(binario_1 << 2)}\")\n\n#** Condicionales\n\nnum_1 = 40\nnum_2 = 50\nnum_3 = num_1\n\nprint()\nprint(\"CONDICIONALES\")\nif num_1 == num_3:\n    print(f\"El numero {num_1} es igual a {num_3}\")\nelif num_1 != num_2 and num_2 != num_3:\n    print(f\"el {num_1} es distinto de {num_2} y {num_2} es distinto de {num_3}\")\nelse:\n    print(\"ninguna de las afirmaciones anteriores son reales\")\n\n#** Bucles\n\n#* For\nprint()\nprint(\"BUCLE FOR\")\nnombre = \"Jackziel\"\nletras = list()\nfor letra in nombre:\n    letras.append(letra)\nprint(letras)\n\n#* While\nprint()\nprint(\"BUCLE WHILE\")\nx = 0\nnumeros_naturales = list()\nwhile x - 10:\n    numeros_naturales.append(x)\n    x += 1\nprint(numeros_naturales)\n\n#** Excepciones\n\nprint()\nprint(\"EXCEPCIONES\")\ntry:\n    print(f\"{\"hola mundo\" + 15.6}\")\nexcept:\n    print(\"No puedes sumar dos tipos de datos diferentes, corrígelo y vuelve a intentar\")\nfinally:\n    print(\"el programa a finalizado\")\n\n#** Ejercicio complejo\n\nprint()\nprint(\"DIFICULTAD EXTRA\")\nfor numero in range(10, 56):\n    if numero % 2 == 0 and numero != 16 and numero % 3 != 0:\n        print(numero)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Jandresalvar.py",
    "content": "# EJERCICIO:\n# - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n#   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n#   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n# - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n#   que representen todos los tipos de estructuras de control que existan\n#   en tu lenguaje:\n# Condicionales, iterativas, excepciones...\n# - Debes hacer print por consola del resultado de todos los ejemplos.\n\n# DIFICULTAD EXTRA (opcional):\n# Crea un programa que imprima por consola todos los números comprendidos\n# entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n \n# Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\n\n# SOLUCIÓN\n\n# Operadores Aritméticos\n    a = 10\n    b = 3\n    print(\"Suma:\", a + b)         # Suma\n    print(\"Resta:\", a - b)        # Resta\n    print(\"Multiplicación:\", a * b)  # Multiplicación\n    print(\"División:\", a / b)     # División\n    print(\"División entera:\", a // b) # División entera\n    print(\"Módulo:\", a % b)       # Residuo de la división\n    print(\"Potencia:\", a ** b)    # Potencia\n\n# Operadores de Comparación\n    print(\"¿Igual?\", a == b)      # Igualdad\n    print(\"¿Diferente?\", a != b)  # Desigualdad\n    print(\"¿Mayor?\", a > b)       # Mayor que\n    print(\"¿Menor?\", a < b)       # Menor que\n    print(\"¿Mayor o igual?\", a >= b) # Mayor o igual\n    print(\"¿Menor o igual?\", a <= b) # Menor o igual\n\n# Operadores Lógicos\n    x = True\n    y = False\n    print(\"AND lógico:\", x and y) # AND lógico\n    print(\"OR lógico:\", x or y)   # OR lógico\n    print(\"NOT lógico:\", not x)   # NOT lógico\n\n# Operadores de Asignación\n    c = 5\n    c += 2  # c = c + 2\n    print(\"Asignación += :\", c)\n    c -= 1  # c = c - 1\n    print(\"Asignación -= :\", c)\n    c *= 3  # c = c * 3\n    print(\"Asignación *= :\", c)\n    c /= 2  # c = c / 2\n    print(\"Asignación /= :\", c)\n    c //= 2  # c = c // 2\n    print(\"Asignación //= :\", c)\n    c %= 2  # c = c % 2\n    print(\"Asignación %= :\", c)\n    c **= 3  # c = c ** 3\n    print(\"Asignación **= :\", c)\n\n# Operadores de Identidad\n    print(\"¿Es el mismo objeto?\", a is b)   # `is`\n    print(\"¿No es el mismo objeto?\", a is not b) # `is not`\n\n# Operadores de Pertenencia\n    lista = [1, 2, 3, 4, 5]\n    print(\"¿Está en la lista?\", 3 in lista)     # `in`\n    print(\"¿No está en la lista?\", 6 not in lista) # `not in`\n\n# Operadores a Nivel de Bits\n    p = 5  # 0101 en binario\n    q = 3  # 0011 en binario\n    print(\"AND a nivel de bits:\", p & q)   # AND bit a bit\n    print(\"OR a nivel de bits:\", p | q)    # OR bit a bit\n    print(\"XOR a nivel de bits:\", p ^ q)   # XOR bit a bit\n    print(\"Complemento a nivel de bits:\", ~p) # Complemento\n    print(\"Desplazamiento a la izquierda:\", p << 1) # Desplaza bits a la izquierda\n    print(\"Desplazamiento a la derecha:\", p >> 1)  # Desplaza bits a la derecha\n\n# Estructuras Condicionales (if, else, elif)\n    x = 10\n    y = 20\n\n    if x > y:\n        print(\"x es mayor que y\")\n    elif x == y:\n        print(\"x es igual a y\")\n    else:\n        print(\"x es menor que y\")\n\n# Bucles Iterativos (for, while)\n\n    numeros =[1, 2, 3, 4, 5]\n    for numero in numeros: # Itera sobre cada elemento de la lista\n        cuadrado = numero**2\n        print(f'El cuadrado de {numero} es {cuadrado}')\n\n    \n    contador = 1\n    while contador <=5: # Condición lógica\n        print(f'contador: {contador}')\n        contador += 1\n\n# Excepciones (try, except, else, finally)\n\n    numerador = 10\n    denominador = 0\n\n    try:\n        resultado = numerador / denominador  # División por cero\n    except ZeroDivisionError:\n        print(\"Error: No se puede dividir por cero.\")\n    else:\n        print(f\"Resultado: {resultado}\")\n    finally:\n        print(\"Bloque finalmente ejecutado.\")\n\n# Estructura implícita\n\n    cuadrados_pares = [n ** 2 for n in range(1, 11) if n % 2 == 0]  \n    print(\"Cuadrados de números pares:\", cuadrados_pares)\n\n# Estructura con break y continue\n    \n    for i in range(10):\n        if i % 2 == 0:  # Saltar números pares\n            continue\n        f\"Número impar: {i}\"\n        if i == 5:\n            print(\"Se alcanzó el valor 5. Salida del bucle.\")\n            break\n        print(i)\n\n# Estructura con match\n\n    operador = \"+\"\n    a, b = 10, 5\n\n    match operador:\n        case \"+\":\n            print(f\"Suma: {a + b}\")\n        case \"-\":\n            print(f\"Resta: {a - b}\")\n        case \"*\":\n            print(f\"Multiplicación: {a * b}\")\n        case \"/\":\n            print(f\"División: {a / b}\")\n        case _:\n            print(\"Operador no válido.\")\n\n# Ejercicio opcional:\n\n    pares = [n for n in range(10, 56) if n != 16 and n % 2 == 0 and n % 3 != 0]\n    print(pares)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/JesusAntonioEEscamilla.py",
    "content": "# #01 - Python -> Jesus Antonio Escamilla\n\n\"\"\"\nEJERCIÓ\n\"\"\"\n\n\"\"\"\nOperaciones\n\"\"\"\n'''\nARITMÉTICA\n'''\nprint(f\"Suma: 3 + 5 = {3 + 5}\")\nprint(f\"Resta: 6 - 4 = {6 - 4}\")\nprint(f\"Multiplicación: 5 * 2 = {5 * 2}\")\nprint(f\"Division: 10 / 1 = {10 / 1}\")\nprint(f\"Division Entera: 10 // 2= {10 // 2}\")\nprint(f\"Modulo: 8 % 2 = {8 % 2}\")\nprint(f\"Exponente: 4 ** 2 = {4 ** 2}\")\n\n'''\nASIGNACIÓN\n'''\nnumber = 5\nprint(f\"Asignación {number}\")\nnumber += 2\nprint(f\"Asignación y Suma {number}\")\nnumber -= 1\nprint(f\"Asignación y Resta {number}\")\nnumber *= 7\nprint(f\"Asignación y Multiplicación {number}\")\nnumber /= 3\nprint(f\"Asignación y Division {number}\")\nnumber //= 3\nprint(f\"Asignación y Division Entera {number}\")\nnumber %= 6\nprint(f\"Asignación y Modulo {number}\")\nnumber **= 3\nprint(f\"Asignación y Exponente {number}\")\n\n'''\nCOMPARACIÓN\n'''\nprint(f\"Igualdad: 10 == 3 -> {10 == 3}\")\nprint(f\"Distinto: 2 != 1 -> {2 != 1}\")\nprint(f\"Mayor que: 5 > 4 -> {5 > 4}\")\nprint(f\"Menor que: 8 < 11 -> {8 < 11}\")\nprint(f\"Mayor que o igual: 7 >= 6 -> {7 >= 6}\")\nprint(f\"Menor que o igual: 9 <= 4 -> {9 <= 4}\")\n\n'''\nLÓGICOS\n'''\nprint(f\"AND - &&: 10 == 10 and 5 == 6 {10 == 10 and 5 == 6}\")\nprint(f\"OR - ||: 7 == 3 or 3 == 3 {7 == 3 or 3 == 3}\")\nprint(f\"NOT - !: not 2 == 4 {not 2 == 4}\")\n\n'''\nIDENTIDAD\n'''\nnew_number = number\nprint(f\"new_number is number: {new_number is number}\")\nprint(f\"new_number is not number: {new_number is not number}\")\n\n'''\nBITS\n'''\na = 10  # 1010 en binario\nb = 4   # 0100 en binario\n\nprint(f\"AND: a & b: {a & b}\")\nprint(f\"OR: a | b: {a | b}\")\nprint(f\"XOR: a ^ b: {a ^ b}\")\nprint(f\"NOT: a & b: {~a}\")\nprint(f\"Desplazamiento a la izquierda: a & b: {a << b}\")\nprint(f\"Desplazamiento a la derecha: a & b: {a >> b}\")\n\n\n\"\"\"\nEstructura de Control\n\"\"\"\n'''\nIF-ELIF-ELSE\n'''\nx = 10\nif x > 0:\n    print(\"Es positivo\")\nelif x == 0:\n    print(\"Es cero\")\nelse:\n    print(\"Es Negativo\")\n\n'''\nFOR\n'''\nfrutas = [\"Manzana\", \"Pera\", \"Cereza\"]\nfor fruta in frutas:\n    print(fruta)\n    \nfor i in range(5):\n    print(i)\n\n\n'''\nWHILE\n'''\ni = 0\nwhile i < 5:\n    print(i)\n    i += 1\n\n\n'''\nTRY-EXCEPT-FINALLY\n'''\ntry:\n    resultado = 10/0\nexcept:\n    print(\"No se puede dividir entre 0\")\nfinally:\n    print(\"Fin del bloque try-except\")\n\n\n\"\"\"\nEXTRA\n\"\"\"\nfor num in range(10, 56):\n    if num % 2 == 0 and num != 16 and num % 3 != 0:\n        print(num)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/JheisonQuiroga.py",
    "content": "# asignement operator\nn1 = 10\nn2 = 3\nn1 += 2 # same that n1 = n1 + 2\n\n# Aricmethic operators\nadd = 2 + 2\nsub = 3 - 2 \nmult = 5 * 2 \ndiv = 10 * 2 # 5.0 (Division always return a float number)\nmod = 10 % 3 # Module (return the reaminder) 1 \nfloor_division = 10 // 3 # 3, Return a integer of division\nexponential = 2 ** 3 # 2 * 2 * 2\n\n#Logic operators\n\"\"\"\nAND = Return True if both conditions are true\nOR = Return True if one of the statement is true\nNOT = Invert the result, if not True = False \n\"\"\"\nprint(3 < 5 and 4 < 5) # True\nprint(3 < 5 and 5 < 5) #False\nprint(3 < 5 or 5 < 5) #True\nprint(3 < 2 or 4 < 2) #False\nprint(not True) #False \nprint(not False) #True\n\n#Comparison operators\n\"\"\"\n== equal\n> mayor than\n>= mayor or equal than\n< menor than\n<= menor or equal than\n!= not equal or diferent\n\"\"\"\nprint(\"-----Comparison Operators-----\")\nprint(3 == 2) # False\nprint(3 == 3) #True\nprint(3 > 2) #True\nprint(3 > 3) #False\nprint(5 >= 2) #True\nprint(2 >= 3) #False\nprint(2 < 3) #True\nprint(3 < 2) # False\nprint(2 <= 2) #True\nprint(2 <= 1) #False\nprint(2 != 3) #True\nprint(3 != 3) #False\n\nprint(\"-----Identity Operators-----\")\n\"\"\"\nIdentity Operators are used to compare objects\nIS = is the same object?\nIS NOT = Is no the same object\n\"\"\"\nx = 10\ny = 8 \nprint(x is 5 + 5) # True, because 10 is equal that 5+5=10\nprint(y is not 4 * 2) # False, because 8 is 8\n\nprint(\"-----Membership operators-----\")\n\"\"\"\nAre used to test if a statement is present in an object\nIN = Return True if a Sequence specific in an object\nNOT IN = Return True if a statement specific is not present in the object \n\"\"\"\nprint(f\"'D' in 'Duban:' {'D' in 'Duban'}\")\nprint(f\"'S' not in 'Duban': {'S' not in 'Duban'}\") #True\n\n\nprint(\"-----Bit Operators-----\")\n\"\"\"\nInteger numbers to binary numbers\nAND (&)\nOR (|)\nXOR (^)\nNOT (~)\nMOVE TO RIGHT (>>)\nMOVE TO LEFT (<<)\n\"\"\"\na = 10 # 1010\nb = 3 # 0011\n\nprint(f\"AND: 10 & 3 = {a & b}\") # 0010 = 2\nprint(f\"OR: 10 | 3 = {a | b}\") # 1011 = 11\nprint(f\"XOR: 10 ^ 3 = {a ^ b}\") # 1001 = 9\nprint(f\"NOT: {~10}\") \nprint(f\"Desplazamiento a la derecha: 10 >> 2 = {10 >> 2}\") # 0010 = 2\nprint(f\"Desplazamiento a la izquierda: 10 << 2 = {10 << 2}\") # 101000 = 40\n\n\nprint(\"-----Control estructures-----\")\n#Conditionals\n\"\"\"\nif- elif - else\n\"\"\"\nprint(\"IF STATEMENT\")\ngrade = -1\nif 9 <= grade <= 10: # if\n    print(\"Excelent\")\nelif 6 <= grade < 9:  # elif\n    print(\"Aprobbed\")\nelif 0 <= grade <= 5:\n    print(\"Reprobbed\")  \nelse:\n    print(\"Invalid grade\")\n\n# Iteratives\n\n\"\"\"\nwhile\n\"\"\"\ncounter = 1\nwhile counter <=10:\n    print(counter)\n    counter += 1\n\n# for\n# Using the range function\nmy_list = [\"Orange\", \"Pineapple\", \"Strawberry\", \"Watermelon\"]\nfor i in my_list:\n    print(i) # Print each element of my list\n\n#try - except\n\ntry:\n    number = int(input(\"enter a int number: \"))\nexcept:\n    print(\"X is not integer\")\nelse:\n    print(f\"your number: {number}\")\nfinally:\n    print(\"Continue with the program\")\n\n\n\"\"\"Extra difficulty\"\"\"\n\nfor num in range(10,56):\n    if num % 2 == 0 and num != 16 and num % 3 != 0:\n        print(num)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/JhonMarin12.py",
    "content": "#Python cuenta con multiples operadores, a continuación se enlistan los diferentes que existen\n\n#Operadores numericos\n\nsuma = 13 + 12\nresta = 45 - 12\ndivision = 21 / 9\nmultiplicacion = 12 * 89\npotencia = 12 ** 12\ndivision_entera = 45 // 6\nmodulo = 12 % 8\n\n#Operadores de comparación \nigualdad = 'Hola' == 'Hola'\nmayor_que = 5 > 12 #tambien existe el mayor o igual >=\nmenor_que = 6 < 0  #tambien existe el menor o igual <=\ndiferente = 'hola' != 'hola'\n\n#operadores booleanos\ny_and = True and False\no_or = (5 > 32) or ('perro' != 'gato')\nno_not = not(True)\n\n#Operaciones con strings\nconcatenacion = 'Hola' + ' como estas?'\nrepeticion = 'hola' * 3 #da 'holaholahola'\n\n# condicionales\na = 89\nb = 12\n\nif a > b:\n    print(f'El numero {a} es mayor que {b}')\nelif b > a:\n    print(f'El numero {a} es menor que {b}')\nelse:\n    print('a y b son iguales')\n\n#Ciclos\n\n#Ciclo for\nfor i in range(0,10):\n    pass\n\n#Ciclo while\n# while True:\n#     #Hacer esto\n#     pass\n\ndef operar(a,b):\n    try:\n        operacion = a/b\n        print(a/b)\n    except ZeroDivisionError:\n        print(\"No se peude dividir entre cero\")\n\noperar(12,0)\n\n\n# Ejercicio opcional\nfor i in range(10,56):\n    if i % 2 == 0 and i != 16 and not(i % 3 == 0):\n        print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/JorgeGarcia-Dev.py",
    "content": "# * EJERCICIO:\n#  * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n#  *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n#  *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n\nprint(\"****ARITMÉTICOS****\")\n\na = 10\nb = 5\n\nsum = a + b\nprint(sum)\n\nsub = a - b\nprint(sub)\n\nmult = a * b\nprint(mult)\n\ndiv = a / b\nprint(div)\n\nresiduo = a % b == 0\nprint(residuo)\n\npotencia = a**b\nprint(potencia)\n\ndiv_int = a // b\nprint(div_int)\n\nprint(\"****LÓGICOS****\")\n\nprint(f\"and: True and True = {True and True}\")\nprint(f\"or: True or False = {True or False}\")\nprint(f\"not: not True = {not True}\")\n\nprint(\"****DE COMPARACIÓN****\")\n\nprint(f\"Mayor: {a} > {b} = {a > b}\")\nprint(f\"Mayor o igual: {a} >= {b} = {a >= b}\")\nprint(f\"Menor: {a} < {b} = {a < b}\")\nprint(f\"Menor o igual: {a} <= {b} = {a <= b}\")\nprint(f\"Igual: {a} == {b} = {a == b}\")\nprint(f\"Distinto: {a} != {b} = {a != b}\")\n\nprint(\"****ASIGNACIÓN****\")\n\na = 10\nb = 5\n\na += b\nprint(a)\n\na -= b\nprint(a)\n\na *= b\nprint(a)\n\na /= b\nprint(a)\n\na %= b\nprint(a)\n\na //= b\nprint(a)\n\na **= b\nprint(a)\n\nprint(\"****IDENTIDAD****\")\n\nprint(f\"Is: {a} is {b} = {a is b}\")\nprint(f\"Is not: {a} is not {b} = {a is not b}\")\n\nprint(\"****PERTENENCIA****\")\n\nprint(f\"In: {a} in [1, 2, 3] = {a in [1, 2, 3]}\")\nprint(f\"Not in: {a} not in [1, 2, 3] = {a not in [1, 2, 3]}\")\n\nprint(\"****BITS****\")\n\na = 0b1010\nb = 0b1101\n\nprint(f\"Bitwise and: {bin(a)} & {bin(b)} = {bin(a & b)}\")\nprint(f\"Bitwise or: {bin(a)} | {bin(b)} = {bin(a | b)}\")\nprint(f\"Bitwise xor: {bin(a)} ^ {bin(b)} = {bin(a ^ b)}\")\nprint(f\"Bitwise not: ~{bin(a)} = {bin(~a)}\")\nprint(f\"Bitwise left shift: {bin(a)} << {bin(b)} = {bin(a << b)}\")\nprint(f\"Bitwise right shift: {bin(a)} >> {bin(b)} = {bin(a >> b)}\")\n\n#  * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n#  *   que representen todos los tipos de estructuras de control que existan\n#  *   en tu lenguaje:\n#  *   Condicionales, iterativas, excepciones...\n#  * - Debes hacer print por consola del resultado de todos los ejemplos.\n\nprint(\"****CONDICIONALES****\")\n\nif a < b:\n    print(f\"{a} es menor que {b}\")\nelif a > b:\n    print(f\"{a} es mayor que {b}\")\nelse:\n    print(f\"{a} es igual que {b}\")\n\nprint(\"****ITERATIVAS****\")\n\nfor i in \"Exercises\":\n    print(i)\n\nfor i in range(11):\n    print(i)\n\nnum = 1\nwhile num <= 5:\n    print(num)\n    num += 1\n\nprint(\"****EXCEPCIONES****\")\n\nnum1 = 5\nnum2 = 0\n\ntry:\n    num3 = num1 / num2\nexcept Exception:\n    print(\"Ha habido una excepción\")\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea un programa que imprima por consola todos los números comprendidos\n#  * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\nprint(\"****DIFICULTAD EXTRA****\")\n\n\ndef pares():\n    for i in range(10, 56):\n        if i % 2 == 0 and i % 3 != 0 or i == 16:\n            print(i)\n\n\npares()\n\n#  * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Jose-Luis-Lanza.py",
    "content": "# Python divide sus operadores en los siguientes grupos:\n#   * Operadores Aritmeticos\n#   * Operadores de Asignacion\n#   * Operadores de Comparacion\n#   * Operadores logicos\n#   * Operadores de identidad\n#   * Operadores de pertenencia\n#   * Operadores a nivel de bit\n\n# OPERADORES ARITMETICOS\n\n# SUMA +\nx = 2\ny = 3\nz = x + y\nprint(z)\n\n# RESTA -\nx = 7\ny = 5\nz = x - y\nprint(z)\n\n# MULTIPLICACION *\nx = 5\ny = 2\nz = x * y\nprint(z)\n\n# DIVISION /\nx = 10\ny = 2\nz = x / 2\nprint(z)\n\n# MODULUS %\n\nx = 3\ny = 2\nz = x % y\nprint(z)\n\n# Exponenciación\n\nx = 2\ny = 3\nz = 2**3\nprint(z)\n\n# Floor division (en Python es una operación matemática\n# que devuelve el mayor número entero posible).\nx = 7\ny = 2\nz = x // y\nprint(z)\n\n# OPERADORES DE ASIGNACION\n\n# Operador (=)\nx = 10\nprint(x)\n\n# Operador (+=)\nx = 10\nx += 5\nprint(x)\n\n# Operador (-=)\nx = 10\nx -= 5\nprint(x)\n\n# Operador (*=)\nx = 10\nx *= 5\nprint(x)\n\n# Operador (/=)\nx = 10\nx /= 5\nprint(x)\n\n# Operador (%=)\nx = 10\nx %= 5\nprint(x)\n\n# Operador (//=)\nx = 10\nx //= 5\nprint(x)\n\n# Operador (**=)\nx = 2\nx **= 5\nprint(x)\n\n# Operador (&=)\na = 12  # in binary: 1100\nb = 10  # in binary: 1010\na &= b  # now 'a' becomes 8, which is 1000 in binary\nprint(a)\n\n# Operador (|=)\na = 12  # in binary: 1100\nb = 10  # in binary: 1010\na |= b  # now 'a' becomes 14, which is 1110 in binary\nprint(a)\n\n# Operador (^=)\na = 12  # in binary: 1100\nb = 10  # in binary: 1010\na ^= b  # now 'a' becomes 6, which is 0110 in binary\nprint(a)\n\n# Operador (>>=)\na = 12  # in binary: 1100\na >>= 2  # now 'a' becomes 3, which is 0011 in binary\nprint(a)\n\n# Operador (<<=)\na = 3  # in binary: 0011\na <<= 2  # now 'a' becomes 12, which is 1100 in binary\nprint(a)\n\n# OPERADORES DE COMPARACION\n# Operador igual (==)\nx = 5\ny = 3\nprint(x == y)   # Retorna falso porque x no es igual a y\n\n# Operador no igual (!=)\nx = 5\ny = 3\nprint(x != y)   # Retorna verdadero porque x no es igual a y\n\n# Operador mayor que (>)\nx = 5\ny = 3\nprint(x > y)   # Retorna verdadero porque x no es mayor a y\n\n# Operador menor que (>)\nx = 5\ny = 3\nprint(x < y)   # Retorna falso porque x no es menor a y\n\n# Operador mayor o iqual que (>=)\nx = 5\ny = 3\nprint(x >= y)   # Retorna verdadero porque x es mayor a y\n\n# Operador menor o iqual que (<=)\nx = 5\ny = 3\nprint(x <= y)   # Retorna falso porque x es mayor a y\n\n# OPERADORES LOGICOS\n\n# Operador AND\nx = 5\nprint(3 < x and x < 10) # Retorna verdadero porque x es mayor que 3 y\n                        # tambien es menor que 10\n\n# Operador OR\nx = 5\nprint(3 < x or x < 2) # Retorna True porque cumple con alguna de las condiciones,\n                      # en este caso x es mayor que 3\n\n# Operador NOT\nx = 5\nprint(not(3 < x and x < 10)) # Revierte el resultado, retorna falso si el resultado es verdadero\n                             # para nuestro caso retorna falso\n\n# OPERADORES DE IDENTIDAD\n\n# Operador IS\nx = [\"apple\", \"banana\"]\ny = [\"apple\", \"banana\"]\nz = x\nprint(x is z)   # Retorna verdadero porque z es el mismo objeto que x\n\n# Operador IS NOT\nx = [\"apple\", \"banana\"]\ny = [\"orange\", \"banana\"]\nprint(x is y)   # Retorna falso porque x no es el mismo objeto que y\n\n# OPERADORES DE PERTENENCIA\n\n# Operador IN\nx = [\"apple\", \"banana\"] # Devuelve verdadero si una secuencia con el valor\n                        # especificado está presente en el objeto.\nprint(\"banana\" in x)\n\n# Operador NOT IN\nx = [\"apple\", \"banana\"] # Retorna verdadero porque en la secuencia el\n                        # valor de \"pineapple\"  no se encuentra en la lista\nprint(\"pineapple\" not in x)\n\n# OPERADORES A NIVEL DE BIT\n\n# Operador & (AND)\nprint(6 & 3)\n\"\"\"\nThe & operator compares each bit and set it to 1 if both are 1, otherwise it is set to 0:\n\n6 = 0000000000000110\n3 = 0000000000000011\n--------------------\n2 = 0000000000000010\n====================\n\"\"\"\n\n# Operador | (OR)\nprint(6 | 3)\n\"\"\"\nThe | operator compares each bit and set it to 1 if one or both is 1, otherwise it is set to 0:\n\n6 = 0000000000000110\n3 = 0000000000000011\n--------------------\n7 = 0000000000000111\n====================\n\"\"\"\n\n# Operador | (XOR)\nprint(6 ^ 3)\n\"\"\"\nThe ^ operator compares each bit and set it to 1 if only one is 1, otherwise (if both are 1 or both are 0) it is set to 0:\n\n6 = 0000000000000110\n3 = 0000000000000011\n--------------------\n5 = 0000000000000101\n====================\n\"\"\"\n\n# Operador ~ (NOT)\nprint(~3)\n\"\"\"\nThe ~ operator inverts each bit (0 becomes 1 and 1 becomes 0).\n\nInverted 3 becomes -4:\n 3 = 0000000000000011\n-4 = 1111111111111100\n\"\"\"\n\n# Operador << (Zero fill left shift)\nprint(3 << 2)\n\"\"\"\nThe << operator inserts the specified number of 0's (in this case 2) from the right and let the same amount of leftmost bits fall off:\n\nIf you push 00 in from the left:\n 3 = 0000000000000011\nbecomes\n12 = 0000000000001100\n\"\"\"\n\n# Operador >> (Signed right shift)\nprint(8 >> 2)\n\"\"\"\nThe >> operator moves each bit the specified number of times to the right. Empty holes at the left are filled with 0's.\n\nIf you move each bit 2 times to the right, 8 becomes 2:\n 8 = 0000000000001000\nbecomes\n 2 = 0000000000000010\n\"\"\"\n\n# ESTRUCTURAS DE CONTROL\n\n# CONDICIONALES\n# IF\nx = 7\ny = 5\n\nif x > y:\n    print(\"x es mayor que y\")\n\n# ELIF\n\nx = 5\ny = 7\n\nif x > y:\n    print(\"x es mayor que y\")\nelif y > x:\n    print(\"y es mayor que x\")\n\n# ELSE\n\nx = 7\ny = 7\n\nif x > y:\n    print(\"x es mayor que y\")\nelif y > x:\n    print(\"y es mayor que x\")\nelse:\n    print(\"x es igual que y\")\n\n# SHORT HAND IF\n\nx = 7\ny = 5\n\nif x > y: print(\"x es mayor que y\")\n\n# SHORT HAND IF... ELSE\n\nx = 5\ny = 7\n\nprint(\"x es mayor que y\") if x > 7 else print(\"y es mayor que x\")\n\n# MATCH CASE\n\nfruta = \"manzana\"\n\nmatch fruta:\n    case \"naranja\":\n        print(\"Es una naranja\")\n    case \"platano\":\n        print(\"Es un platano\")\n    case \"frutilla\":\n        print(\"Es una frutilla\")\n    case \"manzana\":\n        print(\"Es una manzana\")\n\n# ITERATIVAS\n\n# FOR\nfrutas = [\"manzana\", \"naranja\", \"platano\"]\nfor fruta in frutas:\n    print(fruta)\n\n# WHILE\ni = 0\nwhile i < 3:\n    print(\"meow\")\n    i += 1\n\n# EXCEPCIONES\n\nwhile True:\n    try:\n        user_input = int(input(\"Que es n?: \"))\n\n    except ValueError:\n        print(\"valor incorrecto, trate nuevamente\")\n        pass\n\n    else:\n        print(\"El valor de n es:\", user_input)\n        break\n\n# DIFICULTAD EXTRA (opcional):\n# Crea un programa que imprima por consola todos los números comprendidos\n# entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\nfor n in range(10, 56):\n    if n % 2 == 0 and n % 3 != 0 and n != 16:\n        print(n)\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/JoseAlberto13.py",
    "content": "'''\nEJERCICIO:\n- Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n  Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n  (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n- Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n  que representen todos los tipos de estructuras de control que existan\n  en tu lenguaje: Condicionales, iterativas, excepciones...\n- Debes hacer print por consola del resultado de todos los ejemplos.\nDIFICULTAD EXTRA (opcional):\nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\nSeguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n'''\n\n#Operadores Aritméticos\nprint(f\"(+) Suma: 8 + 2 = {8 + 2}\")\nprint(f\"(-) Resta: 8 - 2 = {8 - 2}\")\nprint(f\"(*) Multipicación: 8 * 2 = {8 * 2}\")\nprint(f\"(/) División: 8 / 3 = {8 / 3}\")\nprint(f\"(//) División Entera 'Int': 8 // 3 = {8 // 3}\")\nprint(f\"(%) Modulo o Resto de una División: 8 % 3 = {8 % 3}\")\nprint(f\"(**) Potencia: 8 ** 3 = {8 ** 3}\")\n\n#Operdores Lógicos\nprint(f\"(and) AND: 8 + 2 == 10 and 8 * 2 == 16 = {8 + 2 == 10 and 8 * 2 == 16}\")\nprint(f\"(or) OR: 8 < 2 or 8 > 2 = {8 < 2 or 8 > 2}\")\nprint(f\"(or) OR: 8 < 2 or 8 == 2 = {8 < 2 or 8 == 2}\")\nprint(f\"(not) NOT: not 8 + 2 == 10 = {not 8 + 2 == 10}\")\n \n#Operadores de Comparación\nprint(f\"(<) Menor que: 8 < 8 = {8 < 8}\")\nprint(f\"(>) Mayor que: 8 > 3 = {8 > 3}\")\nprint(f\"(<=) Menor o Igual que: 8 <= 8 = {8 <= 8}\")\nprint(f\"(>=) Mayor o Igual que: 8 >= 3 = {8 >= 3}\")\nprint(f\"(==) Igual que: 8 == 3 = {8 == 3}\")\nprint(f\"(!=) Distinto que: 8 != 3 {8 != 3}\")\n\n#Operadores de Asignación\nvariable = 10\nprint(\"(= 10) Asignación variable = \",variable)\nvariable += 7\nprint(\"(+= 7) Suma y aignación variable = \",variable)\nvariable -= 4\nprint(\"(-= 4) Resta y aignación variable = \",variable)\nvariable *= 4\nprint(\"(*= 4) Multiplicación y aignación variable = \",variable)\nvariable /= 2\nprint(\"(/= 2) División y aignación variable = \",variable)\nvariable %= 3\nprint(\"(%= 3) Modulo y aignación variable = \",variable)\nvariable **= 4\nprint(\"(**= 4) Potencia y aignación variable = \",variable)\nvariable //= 3\nprint(\"(//= 3) División Entera y aignación variable = \",variable)\n\n#Operadores de Indentidad\nlista1 = [\"uno\", \"dos\", \"tres\"]\nlista2 = [\"uno\", \"dos\", \"tres\"]\nprint(\"(is) \", lista1 is lista2)\nprint(\"(is not) \", lista1 is not lista2)\n\n#Operadores de Pertenencia\nprint(f\"(in) '1' in lista1 = {1 in lista1}\")\nprint(f\"(in) '1' not in lista1 = {1 not in lista1}\")\n\n#Operadores de Bits\na = 10\nb = 3\nprint(f\"a = {bin(a)}\\nb = {bin(b)}\")\nprint(f\"(&) AND: 10 & 3 = {10 & 3}  resultado en bits {bin(10 & 3)}\") #Compara los bits, devolviendo 1 solo cuando ambos bits son 1, de lo contrario es igual a 0.   \"1 AND 0 = 0\"\nprint(f\"(|) OR : 10 | 3 = {10 | 3}  resultado en bits {bin(10 | 3)}\") #Compara los bits, devolviendo 1 si alguno de los bits es 1, de lo contario es igual a 0.      \"1 OR  0 = 1\"\nprint(f\"(^) XOR: 10 ^ 3 = {10 ^ 3}  resultado en bits {bin(10 ^ 3)}\") #Compara los bits, devolviendo 1 si la comparación es diferente, de lo contario es igual a 0.  \"1 XOR 1 = 0\"\nprint(f\"(>>) Desplazamiento Derecha: 10 >> 3 = {10 >> 3}  resultado en bits {bin(10 >> 3)}\") #Desplaza los bits la cantidad de veces que le asignemos a la derecha. \"1010  >> 3  = 0101 -> 0010 -> 0001\"\nprint(f\"(<<) Desplazamiento Izquierda: 10 << 3 = {10 << 3}  resultado en bits {bin(10 << 3)}\") #Desplaza los bits la cantidad de veces que le asignemos a la izquierda, agregando 0. \"1010 << 3 = 10100 -> 101000 -> 1010000\"\n\n#Estructuras de Control\n#--Condicionales\nedad = 25\nif edad < 18:\n    print(\"La edad es menor a 18 años\")\nelif edad < 60:\n    print(\"La edad es la de un adulto\")\nelse:\n    print(\"La edad es de un adulto mayor\")\n\n#--Iterativas (Bucles)\nfor i in range (4):\n    print(i)\n\ni = 0\nwhile i <= 3:\n    print(i)\n    i += 1\n\n#--Manejo de Exepciones\ntry:\n    print(10 / 2)\nexcept:\n    print(\"¡ERROR! No se puede dividir entre 0\")\nfinally:\n    print(\"Fin de manejo de exepciones\")\n\n'''\nEXTRA\n'''\ni = 10\nwhile i <= 55:\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print(i)\n    i += 1"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/JoseGago27.py",
    "content": "#Operadores\n\n# Operadores Aritmeticos\n\nprint(f\"Suma: 2 + 2 = {2 + 2}\")\nprint(f\"Resta: 4 - 2 = {4 - 2}\")\nprint(f\"Multiplicacion: 2 x 3 = {2 * 3}\")\nprint(f\"Division: 4 / 2 = {4 / 2}\")\nprint(f\"Media: 4 % 2 = {4 % 2}\")\nprint(f\"Exponencial: 2 ** 2 = {2 ** 2}\")\nprint(f\"Division entera: 4 // 2 = {4 // 2}\")\n\n# Operadores de comparacion\n\nprint(f\"Igualdad: 10 == 3 es {10 == 3}\")\nprint(f\"Diferente: 10 != 3 es {10 != 3}\")\nprint(f\"Mayor que: 20 > 15 es {20 > 15}\")\nprint(f\"Menor que: 30 < 40 es {30 < 40}\")\nprint(f\"Mayor o igual que: 50 >= 50 es {50>=50}\")\nprint(f\"Menor o igual que: 80 <= 30 es {80 <= 30}\")\n\n#Operadores logicos\n\nprint(f\"AND : 2 + 2 == 4 and 3 + 2 == 5 {2 + 2 == 4 and 3 + 2 == 5}\")\nprint(f\"OR : 2 + 2 == 100 or 3 + 2 == 5 {2 + 2 == 100 or 3 + 2 == 5}\")\nprint(f\"NOT : not 2 + 2 == 100  {not 2 + 2 == 100}\")\n\n#Operadores de asignacion\n\nnum1 = 10 #Asignacion\nprint(num1)\nnum1 += 1 #Suma y asignacion\nprint(num1)\nnum1 -= 2 #Resta y asignacion\nprint(num1)\nnum1 *= 2 #Multiplicacion y asignacion\nprint(num1)\nnum1 /= 2 #Division y asignacion\nprint(num1)\n\n#Operadores de identidad\n\nmy_number = num1\nprint(f\"my_number is num1 es {my_number is num1}\")\nprint(f\"my_number is not num1 es {my_number is not num1}\")\n\n#Operadores de pertenencia\n\nprint(f\"Esta la 'R' en 'Ramon'?, la respuesta es {'R' in 'Ramon'}\")\nprint(f\"No esta la 'R' en 'Ramon', la respuesta es {'R' not in 'Ramon'}\")\n\n#Operadores de bit\na = 10\nb = 3\n\nprint(f\"AND: 10 & 3 = {10 & 3}\")\nprint(f\"OR: 10 | 3 = {10 | 3}\")\nprint(f\"XOR: 10 ^ 3 = {10 ^ 3}\")\nprint(f\"NOT: ~10 = {~10}\")\nprint(f\"Desplazamiento a la derecha: 10 >> 2 = {10 >> 2}\")\nprint(f\"Desplazamiento a la izquierda: 10 << 2 = {10 << 2}\")\n\n#Estructuras de control\n\n#Condicionales\n\nstring1 = \"otra prueba\"\n\nif string1 == \"prueba de condicion\":\n    print(\"Si es igual\")\nelif string1 == \"otra prueba\":\n    print(\"no lo es\")\nelse:\n    print(\"No es igual\")\n\n#Iterativas\n\nfor i in range(11):\n    print(i)\n\ni = 0\n\nwhile i <= 10:\n    print(i)\n    i += 1\n\n#Manejo de excepciones\n\ntry:\n    print(10/0)\nexcept:\n    print(\"Se ha producido un error\")\nfinally:\n    print(\"Ha finalizado el manejo de excepciones\")\n\n#Extra\n\nfor number in range(10, 56):\n    if number % 2 == 0 and number != 16 and number % 3 ==0:\n        print(number)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/JosephFaster.py",
    "content": "'''/\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n'''\n'''\nOperadores\n'''\n#Operadores aritmeticos\nprint(f'La suma de 10+3 = {10+3}')\nprint(f'La resta de 10-3 = {10-3}')\nprint(f'El producto de 10*3 = {10*3}')\nprint(f'La división de 10+3 = {10/3}')\nprint(f'La modulo de 10%3 = {10%3}')\nprint(f'La potencia de 10**3 = {10**3}')\nprint(f'La división entenra de 10//3 = {10//3}')\n\n#Operadores comparativos\nprint(f'Igualdad: 10 == 3 es {10==3}')\nprint(f'Desigualdad: 10 != 3 es {10!=3}')\nprint(f'Mayor que: 10 > 3 es {10>3}')\nprint(f'Menor que: 10 < 3 es {10<3}')\nprint(f'Mayor o igual a que: 10 >= 3 es {10>=3}')\nprint(f'Menor o igual a que: 10 <= 3 es {10<=3}')\n\n#Operadores lógicos\n#Aquí aroja un resultado True+True que nos das True\nprint(f'AND &&: 10 + 3 == 13 and 5 - 1 == 4 {10 + 3 == 13 and 5 - 1 == 4}')\n#Or se deben cumplir una de las dos condiciones que sea true para que sea true\nprint(f'AND ||: 10 + 3 == 13 or 5 - 1 == 4 {10 + 3 == 13 or 5 - 1 == 4}')\n#Not, se cumple la condición si ese no es.\nprint(f'NOT !: 10 + 3 == 14 {not 10 + 3 == 14}')\n\n\n#Operadores de asigancion\n\nnumber = 11 #asignación\nprint(number)\nnumber += 5 #suma y asignación \nprint(number)\nnumber -1 #resta y asignación\nprint(number)\nnumber *1 #producto y asignación\nprint(number)\nnumber /= 3 #división y asignación\nprint(number)\nnumber **=2 # Exponenete y asignación\nprint(number)\nnumber //=2 #División entera y asignación\nprint(number)\nnumber %= 3 #modulo y asinación\n\n\n#Operadores de identidad\n#Nos sirven para comparar el valor de la posición de memoria\n\nmy_number = 1.0\nprint(f'my_number es number es {my_number is number}') # falsoCada uno tiene una identidad de memoria diferente\n#Si cambio my_number = number, nos dará true\n\n\n#Operadores de pertenencia\nprint(f'\"u\" in \"moure\" = {\"u\" in \"moure\"}')\nprint(f'\"u\" not in \"moure\" = {\"u\" not in \"moure\"}')\n\n#Operadores de bit\na = 10 # 1010, el 10 se representa en binario así\nb = 3 # 11, el 3 se representan como 11 en binario\n\nprint(f'AND: 10 & 3 ={10&3}')#0010\nprint(f'OR: 10 | 3 ={10|3}')#0010\nprint(f'XOR: 10 ^ 3 ={10^3}')#0010\n#print(f'NOT: 10 ~3 ={10~3}')#0010\nprint(f'Desplazamiento a la derecha: 10 >> 2 = {10>>2}')\nprint(f'Desplazamiento a la derecha: 10 << 2 = {10<<2}')\n\n\n'''\nEstructuras de control\n'''\n\n# Condicionales\n\nmy_string = 'Joseph'\n\nif my_string == 'Joseph':\n    print('my_string es \"Joseph\"')\nelif my_string == 'Faster':\n    print('my_string es \"Faster\"')\nelse:\n    print('my_string no \"Joseph\"')\n\n\n#Iterativas\n\nfor i in range(11):\n    print(i)\n\n\ni = 0\n\nwhile i <= 10:\n    print(i)\n    i += 1\n\n#manejo de excepciones\ntry:\n    print(10/0)\nexcept:\n    print('Se ha producido un error')\nfinally:\n    print('Se ha finalizado la esepción')\n\n\n#EXTRA\nprint(\"Números entre 10 y 55 que son pares y no son ni 16 ni múltiplos de 3:\")\nfor num in range(10, 56):\n    if num % 2 == 0 and num != 16 and num % 3 != 0:\n        print(num)\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Josue-py.py",
    "content": "\"\"\"\nOperadores\n\"\"\"\n\ndef operadores_aritmeticos(a,b):\n    print(f\"Este es el operador de suma '+'\\nmira el resultado de a y b de los dos numeros que proporcionaste: {a + b}\")\n    print(f\"Este es el operador de resta '-'\\nmira el resultado de a y b de los dos numeros que proporcionaste: {a - b}\")\n    print(f\"Este es el operador de multiplicacion '*'\\nmira el resultado de a y b de los dos numeros que proporcionaste: {a * b}\")\n    print(f\"Este es el operador de division '/'\\nmira el resultado de a y b de los dos numeros que proporcionaste: {a / b}\")\n    print(f\"Este es el operador de potencia '**'\\nmira el resultado de a y b de los dos numeros que proporcionaste: {a ** b}\")\n    print(f\"Este es el operador llamado modulo '%'\\nmira el resultado de a y b de los dos numeros que proporcionaste: {a % b}\")\n    print(f\"Este es el operador de division entera '//' \\nmira el resultado de a y b de los dos numeros que proporcionaste: {a // b}\")\noperadores_aritmeticos(20,80) # coloca dos numeros que quieras\n\n# Operadores logicos: son and,or y not\n\ndef operadores_logicos(x,y):\n    print(x==y and x > y)\n    print(x >= y or x != y)\n    print(not(x < y and x == y))\n\noperadores_logicos(40,50)\n\n#Operadores de comparacion:\n\ndef operadores_de_comparacion(a,b):\n    print(f\"IGUAL: a == b, seran iguales? {a==b}\")\n    print(f\"DIFERENTE: a != b, seran distintos? {a != b} \")\n    print(f\"Mayor: a > b,es 'a' mayor que b? {a > b}\")\n    print(f\"Menor: a < b es 'a' menor que b? {a < b}\")\n    print(f\"Menor o igual: a <= b es 'a' menor o igual que 'b'? {a <= b}\")\n    print(f\"Mayor o igual: a >= b es 'a' mayor o igual que 'b'? {a <= b}\")\n\noperadores_de_comparacion(90,50)\n\n# Operadores de asignacion\n\na = 5\na += 3\nprint(f\"Suma y asignación (a += 3): {a}\")\na -= 2\nprint(f\"Resta y asignación (a -= 2): {a}\")\na *= 4\nprint(f\"Multiplicación y asignación (a *= 4): {a}\")\na /= 2\nprint(f\"División y asignación (a /= 2): {a}\")\na **= 2\nprint(f\"Potencia y asignación (a **= 2): {a}\")\na //= 3\nprint(f\"División entera y asignación (a //= 3): {a}\")\na %= 2\nprint(f\"Módulo y asignación (a %= 2): {a}\")\n\n# Operadores de identidad: son is y is not,algo parecidos a los de comparacion\n\ndef operadores_de_identidad(a,b):\n    print(f\"'is' me devuelve true si estos son iguales,sera cierto que {a} is {b}? {a is b}\")\n    print(f\"'is not' me devuelve true si estos son diferentes,sera cierto que {a} is not {b}? {a is not b}\")\noperadores_de_identidad('HOLA','HUESO')\n\n# Operadores de pertenencia: in y not in\n\ndef operadores_de_pertenencia(a,b):\n    print(f\" '{a} in {b}' in devolvera True si '{a}' no esta en la frase {b}, veamos si es cierto {a in b}\")\n    print(f\" '{a} not in {b}' not in devolvera True si '{a}' no esta en la frase {b}, veamos si es cierto {a not in b}\")\n\noperadores_de_pertenencia(\"a\",\"barcelona\")\n\ndef operadores_de_bit(a,b): # Parecidos a los operadores logicos\n    print(f\"AND: {a} & {b} = {a & b} \")\n    print(f\"OR: {a} | {b} = {a | b} \") #\n    print(f\"XOR: {a} ^ {b} = {a ^ b} \")\n    print(f\"NOT: ~{a} = {~a}\")\n    print(f\"Desplazamiento a la derecha: {a} >> {b} = {a >> b} \")\n    print(f\"Desplazamiento a la izquierda: {a} << {b} = {a << b} \")\n\noperadores_de_bit(10,3)\n\n\"\"\"\nEstructuras de control\n\"\"\"\n\n# Estructura de control condicional\ndef condicionales():\n    prompt1 = input(\"escriba un numero: \")\n    prompt2 = input(\"Escriba otro numero: \")\n    if prompt1 < prompt2:\n        print(f\" Si {prompt1} es menor que {prompt2}\")\n    elif prompt1 > prompt2:\n        print(f\" en este caso {prompt1} es mayor que {prompt1}\")\n    else:\n        print(\"los numeros son iguales\")\ncondicionales()\n\n# Iterativas\nfor i in range (6):\n    print(\"Hola Brais,esto es un bucle for\")\n\nn = 20\nwhile n != 3:\n    print(n)\n    n -= 1\n\n# excepciones\ntry:\n    print(0/0)\nexcept:\n    print(\"Hay un error\")\nfinally:\n    print(\"Como vas a dividr 0/0?\")\n\"\"\"\nEXTRA\n\"\"\"\n\nfor j in range(9,56):\n    if j == 16:\n        continue\n    elif j % 3 == 0:\n        print(j)\n    else:\n        continue\n\nprint(\"WALAAAAAAA!\")"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/JowelGod.py",
    "content": "# ===============================\n# 1. ARITHMETIC OPERATORS\n# ===============================\nprint(\"🔢 Arithmetic Operators\")\n\na = 10\nb = 3.2\nc = 2\nprint(f\"Addition: {a} + {b} = {a + b}\")\nprint(f\"Subtraction: {a} - {b} = {a - b}\")\nprint(f\"Multiplication: {a} * {b} = {a * b}\")\nprint(f\"Division: {a} / {b} = {a / b}\")\nprint(\"always returns a floating-point number\")\nprint(f\"Floor Division: {a} // {b} = {a // b}\")\nprint(\"return an integer result\")\nprint(f\"Modulus: {a} % {b} = {a % b}\")\nprint(f\"Exponentiation: {a} ** {c} = {a ** c}\")\nprint(\"The equal sign (=) is used to assign a value to a variable\")\nprint(f\"There is full support for floating point; \noperators with mixed type operands convert the \ninteger operand to floating point:\")\n\n# ===============================\n# 2. COMPARISON OPERATORS\n# ===============================\n# Se usan para comparar valores y devuelven booleanos (True o False).\n\nes_igual = a == b            # False\nes_diferente = a != b        # True\nmayor = a > b                # True\nmenor = a < b                # False\nmayor_o_igual = a >= b       # True\nmenor_o_igual = a <= b       # False\n\nprint(\"\\n🔍 Comparison Operators\")\nprint(f\"== : {es_igual}, != : {es_diferente}, > : {mayor}, < : {menor}\")\nprint(f\">= : {mayor_o_igual}, <= : {menor_o_igual}\")\n\nprint(f\"{a} == {b} ➜ {a == b}\")\nprint(f\"{a} != {b} ➜ {a != b}\")\nprint(f\"{a} > {b} ➜ {a > b}\")\nprint(f\"{a} < {b} ➜ {a < b}\")\nprint(f\"{a} >= {b} ➜ {a >= b}\")\nprint(f\"{a} <= {b} ➜ {a <= b}\")\n\n# ===============================\n# 3. LOGICAL OPERATORS\n# ===============================\n# Se usan para combinar expresiones booleanas.\n\nx = True\ny = False\n\nresultado_and = x and y  # False\nresultado_or = x or y    # True\nresultado_not = not x    # False\n\nprint(\"\\n🔐 Logical Operators\")\nprint(f\"{x} and {y} ➜ {resultado_and}\")\nprint(f\"{x} or {y} ➜ {resultado_or}\")\nprint(f\"not {x} ➜ {resultado_not}\")\n\n# ===============================\n# 4. ASSIGNMENT OPERATORS\n# ===============================\n# Se usan para asignar valores y modificarlos directamente.\n\nz = 5\nz += 3  # z = z + 3 → 8\nz -= 2  # z = z - 2 → 6\nz *= 2  # z = z * 2 → 12\nz /= 3  # z = z / 3 → 4.0\nz %= 2  # z = z % 2 → 0.0\n\nprint(f\"z = {z}\")\nprint(f\"z += 3 ➜ {z}\")\nprint(f\"z -= 2 ➜ {z}\")\nprint(f\"z *= 2 ➜ {z}\")\nprint(f\"z /= 3 ➜ {z}\")\nprint(f\"z %= 2 ➜ {z}\")\n\nprint(\"\\n🖋 Assignment Operators\")\nprint(f\"Resultado final de z: {z}\")\n\n# ===============================\n# 5. IDENTITY OPERATORS\n# ===============================\n# Comparan si dos variables apuntan al mismo objeto en memoria.\n\nlista_1 = [1, 2, 3]\nlista_2 = [1, 2, 3]\nlista_3 = lista_1\n\nmisma_identidad = lista_1 is lista_3     # True\ndiferente_identidad = lista_1 is not lista_2  # True (aunque tengan el mismo contenido)\n\nprint(\"\\n🪞 Identity Operators\")\nprint(f\"lista_1 is lista_3 ➜ {misma_identidad}\")\nprint(f\"lista_1 is not lista_2 ➜ {diferente_identidad}\")\n\n# ===============================\n# 6. MEMBERSHIP OPERATORS\n# ===============================\n# Verifican si un valor está (o no está) presente en una secuencia.\n\nfrutas = [\"manzana\", \"banana\", \"cereza\"]\n\nhay_manzana = \"manzana\" in frutas         # True\nno_hay_uva = \"uva\" not in frutas          # True\n\nprint(\"\\n📦 Membership Operators\")\nprint(f\"'manzana' in frutas ➜ {hay_manzana}\")\nprint(f\"'uva' not in frutas ➜ {no_hay_uva}\")\n\nlista = [1, 2, 3, 4, 5]\nprint(f\"3 in lista ➜ {3 in lista}\")\nprint(f\"10 not in lista ➜ {10 not in lista}\")\n\n\n# ===============================\n# 7. BITWISE OPERATORS\n# ===============================\n# Operan a nivel de bits. Son útiles en optimización o en programación de bajo nivel.\n\n# Representaciones binaria:\n# x = 5  → 0101\n# y = 3  → 0011\n\nx = 5\ny = 3\n\nbitwise_and = x & y     # 1 (0001)\nbitwise_or = x | y      # 7 (0111)\nbitwise_xor = x ^ y     # 6 (0110)\nbitwise_not = ~x        # -6 (complemento a 2)\ndesplazar_izq = x << 1  # 10 (multiplica por 2)\ndesplazar_der = x >> 1  # 2 (divide entre 2)\n\nprint(\"\\n💡 Bitwise Operators\")\nprint(f\"{x} & {y} = {bitwise_and}\")\nprint(f\"{x} | {y} = {bitwise_or}\")\nprint(f\"{x} ^ {y} = {bitwise_xor}\")\nprint(f\"~{x} = {bitwise_not}\")\nprint(f\"{x} << 1 = {desplazar_izq}\")\nprint(f\"{x} >> 1 = {desplazar_der}\")\n\n# ===============================\n# 8. CONTROL STRUCTURES\n# ===============================\nprint(\"\\n🧠 Control Structures\")\n\n# --- Condicionales (if/elif/else)\nedad = 17\nif edad >= 18:\n    mensaje = \"Eres mayor de edad\"\nelif edad == 17:\n    mensaje = \"Tienes 17, casi adulto\"\nelse:\n    mensaje = \"Eres menor de edad\"\nprint(mensaje)\n\n# --- Bucle for\nprint(\"\\nBucle for:\")\nfor numero in range(1, 4):  # Imprime 1, 2, 3\n    cuadrado = numero ** 2\n    print(f\"{numero} al cuadrado es {cuadrado}\")\n\n# --- Bucle while\nprint(\"\\nBucle while:\")\ncontador = 0\nwhile contador < 3:\n    print(f\"Contador = {contador}\")\n    contador += 1\n\n# --- Try/Except (manejo de errores)\nprint(\"\\nManejo de excepciones:\")\ntry:\n    division = 10 / 0\nexcept ZeroDivisionError:\n    print(\"❌ No puedes dividir entre cero.\")\nfinally:\n    print(\"Este bloque se ejecuta siempre.\")\n\n#Ejercicio Dificultad extra\nfor i in range(10,56):\n  if i != 16 and i%3 != 0 and i%2 == 0:\n    print(f\"{i}\", end \" \")\n\n  \n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Juan-Wills.py",
    "content": "#assigment operators (assign values to variables or constants)\nnum1= 2\nnum2= 3\n\n#Aritmethic operators (returns numbers)\n2+3      #addition\n2-3      #substraction\n2*3      #multiplication\n2/3      #division\n2%3      #module\n2**3     #exponent\n2//3     #floor division\n\nnum1+=7         #increment by 'X'         \nnum2-=2         #decrement by 'X'\nnum1*=6         #multiplication by 'X'\nnum2/=3         #division by 'X'\nnum1%=9         #module by 'X'\nnum2**=4        #power by 'X'\nnum1//=5        #floor division by 'X'\n\n#Comparative operators (returns boolean)\nnum1<num2    #Bigger than\nnum1>num2    #Smaller than\nnum1<=num2   #Bigger or equal than\nnum1<=num2   #Smaller or equal than\nnum1==num2   #Equal to\nnum1!=num2   #Not equal to\n\n#Logic operators (returns booleans)\nnum1 and num2    #Are they both true?\nnum2 or num1     #Are only one of them true?\nnot num1         #Changes the boolean state to its contrapart\n\n#Membership operators (returns booleans)\narray=['car','bicycle','motorcycle','truck']\n'bicycle' in array      #the string is into the list of the array\n'van' not in array  #the string in not into the list of the array\n\n#Identity operators (returns booleans)\nobj1=['phone','printer']\nobj2=['phone','printer']\nobj3=obj1\nobj1 is obj3     #obj3 is the same as obj1  \nobj1 is not obj2 #despite both has the same content, they're different and are store in distint slots in memory\n\n#Bitwise operators (returns numbers)\n\"\"\"\nThese are hard to explain so I'll \njust skip them, you can always search\nby your own in google tho\n\"\"\"\nbit= num1 & num2\nbit= num1 | num2\nbit= ~num1\n\n#Ternary operators\n'num1 is the smallest' if (num1<num2) else 'num2 is the smallest'\n    #Help to make decisions between two options\n'Option 1 (true)' if (num1>num2) else('Option 2 (false-true)' if (num1==num2) else 'Option 3 (false-false)')\n    #Ternary operators can be nested\n\n#if-elif-else\nage=17\nif (age<=17 and age>0):\n    print('User is younger than 18')\nelif (age==18):\n    print('User has 18 years old')\nelse:\n    print('User is older than 18')\n\n#while-loop\ni=12\nprint('list of number from 0 to 9:')\nwhile (i<12):\n    i+=1\n    if (i==11):\n        break       #Used to stop the loop despite the condition is still true\n\n    if(i==4):\n        print('number three skipped')    \n        continue    #Used to pass to the next iteration \n            \n    print(i-1)\nelse:               #Used to run code once condition is no longer true\n    print('we have reached the top!')\n\n#for-loop\nList=[2,3,4,5,6,7]\nfor i in range(len(List)):      #for repeats according to the length of the item of any sequence\n    print(List[i], end=\",\" if i!=(len(List))-1 else \"\")\n    print(\" I was printed\",i+1,\"times.\")\n    break                       #else statement won't be triggered if break executes\nprint(\"\\n\")\n\nfor j in range(1,11,2):         #default start value is 0, the third number is to add incremente or decrement\n    print(j)\nelse:\n    print(\"We have printed all the numbers in the range.\")\n\nstudent_list=0\nstudent_names=[\"Juan\",\"Santi\",\"Jose\",\"Maria\",\"Josefa\"]\nfor name in student_names:      #'name' is the item of the list according to the iteration\n    if name==\"Jose\":\n        student_list+=1\n        continue\n    print(\"Student\",student_list,\":\",name)\n\nfor i in range(10,56):\n    if i%2==0 and i!=16 and i%3!=0:\n        print(i)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Juanma0416.py",
    "content": "\n# 1\n\n'''\nOperadores\n'''\n# Operadores Aritméticos\nprint (f\"Suma: 20 + 30 = {20 + 30}\")\nprint (f\"Resta: 80 - 30 = {80 - 30}\")\nprint (f\"División: 90 / 20 = {90 / 20}\")\nprint (f\"Multiplicación: 20 * 30 = {20 * 30}\")\nprint (f\"Módulo: 90 % 17 = {90 % 17}\") # Resto de la división\nprint (f\"Exponente: 3 ** 4 = {3 ** 4}\") # Potencia\nprint (f\"División entera: 90 // 20 = {90 // 20}\") # División sin decimales\n\n# Operadores de Comparación\nprint (f\"Igualdad: 20 == 30 es {20 == 30}\") # Igual que\nprint (f\"Desigualdad: 20 != 30 es {20 != 30}\") # Diferente de\nprint (f\"Mayor que: 20 > 30 es {20 > 30}\")\nprint (f\"Menor que: 20 < 30 es {20 < 30}\")\nprint (f\"Mayor o igual que: 20 >= 30 es {20 >= 20}\") # Mayor o igual que  \nprint (f\"Menor o igual que: 20 <= 30 es {20 <= 30}\") # Menor o igual que\n\n# Operadores Lógicos\nprint (f\"AND &&: (20 > 10) and (30 > 20) es {(20 > 10) and (30 > 20)}\") # Ambas condiciones deben ser verdaderas para que el resultado sea verdadero\nprint (f\"OR ||: (20 > 10) or (30 < 20) es {(10 > 10) or (30 < 20)}\") # Suficiente con que una de las dos condiciones sea verdadera para que el resultado sea verdadero\nprint (f\"NOT !: not(20 > 10) es {not(20 > 10)}\") # Invierte el valor de verdad de la condición\n\n# Operadores de Asignación\nmy_number = 120 # Asignación simple ya que el valor de la derecha se asigna a la variable de la izquierda por medio del operador \"=\"\nprint (my_number)\nmy_number += 4 # Esta es una forma corta de escribir my_number = my_number + 4 y esto lo que hace es sumar 4 al valor actual de my_number y luego asignar el resultado a my_number y se puede hacer con cualquier operador aritmético\nprint (my_number) \nmy_number -= 10 # Resta 10 al valor actual de my_number\nprint (my_number)\nmy_number *= 2 # Multiplica el valor actual de my_number por 2\nprint (my_number)\nmy_number /= 3 # Divide el valor actual de my_number entre 4\nprint (my_number)\nmy_number %= 7 # Calcula el resto de la división del valor actual de my_number entre 3\nprint (my_number)\nmy_number **= 3 # Eleva el valor actual de my_number a la potencia de 3\nprint (my_number)\nmy_number //= 2 # Realiza una división entera del valor actual de my_number entre 2\nprint (my_number)\n\n# Operadores de Identidad\nmy_new_number = 108.0\nprint (f\"my_number is my_new_number: {my_number is my_new_number}\") # Devuelve True si ambas variables apuntan al mismo objeto en memoria a través del operador \"is\" cuya función es comprobar la identidad de los objetos y en este caso devuelve False porque aunque ambos tienen el mismo valor, tienen diferente posición en memoria.\nmy_new_number = my_number\nprint (f\"my_number is my_new_number: {my_number is my_new_number}\")\nprint (f\"my_number is not my_new_number: {my_number is not my_new_number}\") # En este caso devuelve False porque ambas variables apuntan al mismo objeto en memoria y el operador \"is not\" comprueba que no son el mismo objeto en memoria.\n\n# Operadores de Pertenencia\nprint (f\" 'a' in 'juan' = {'a' in 'juan'}\") # Devuelve True si el valor de la izquierda se encuentra en el valor de la derecha\nprint (f\" 'm' not in 'juan' = {'m' not in 'juan'}\") # Devuelve True si el valor de la izquierda no se encuentra en el valor de la derecha\n\n# Operadores de bit\nj = 7 # En binario es 0111 (Este es en 4 bits)\nk = 3 # En binario es 0011 (Este es en 4 bits)\nprint (f\"AND: 7 & 3 = {7 & 3}\") # Operador AND a nivel de bits, compara cada bit de los dos números y devuelve un nuevo número donde cada bit es 1 si ambos bits son 1, de lo contrario es 0. En este caso 0111 & 0011 = 0011 que es 3 en decimal.\nprint (f\"OR: 7 | 3 = {7 | 3}\") # Operador OR a nivel de bits, compara cada bit de los dos números y devuelve un nuevo número donde cada bit es 1 si al menos uno de los bits es 1, de lo contrario es 0. En este caso 0111 | 0011 = 0111 que es 7 en decimal.\nprint (f\"XOR: 7 ^ 3 = {7 ^ 3}\") # Operador XOR a nivel de bits, compara cada bit de los dos números y devuelve un nuevo número donde cada bit es 1 si los bits son diferentes, de lo contrario es 0. En este caso 0111 ^ 0011 = 0100 que es 4 en decimal.\nprint (f\"NOT: ~7 = {~7}\") # Operador NOT a nivel de bits, invierte todos los bits del número. En este caso ~0111 = 1000 que es -8 en decimal (~x = -(x + 1)).\nprint (f\"Desplazamiento a la derecha: 7 >> 1 = {7 >> 1}\") # Desplaza todos los bits del número a la derecha una posición. En este caso 0111 >> 1 = 0011 que es 3 en decimal. Una forma sencilla de verlo es que el desplazamiento a la derecha es equivalente a una división entera por 2: (7÷2)=3\nprint (f\"Desplazamiento a la izquierda: 7 << 1 = {7 << 1}\") # Desplaza todos los bits del número a la izquierda una posición. En este caso 0111 << 1 = 1110 que es 14 en decimal. Una forma sencilla de verlo es que el desplazamiento a la izquierda es equivalente a una multiplicación por 2: (7*2)=14\n\n\n# 2\n\n'''\nEstructuras de Control\n'''\n\n# Condicionales\nmy_name = \"JuanmaDev\"\n\nif my_name == \"JuanmaDev\": # Si my_name es igual a \"Juanma\"\n    print (\"Hola JuanmaDev\") # Se ejecuta este bloque de código\nelif my_name == \"Manuel\": # Si no se cumple la condición anterior, pero my_name es igual a \"Manuel\"\n    print (\"Hola Manuel\") # Se ejecuta este bloque de código\nelse: # Si no se cumple ninguna de las condiciones anteriores\n    print (\"Hola desconocido\") # Se ejecuta este bloque de código\n\n# Iterativas\nfor i in range(5): # Bucle for que itera desde 0 hasta 4 (5 no incluido)\n    print (f\"Iteración {i}\") # Imprime el valor de i en cada iteración desde 0 hasta 4 ya que range(5) genera una secuencia de números desde 0 hasta 4\n\ni = 0\nwhile i < 5: # Bucle while que se ejecuta mientras i sea menor que 5\n    print (f\"Iteración {i}\") # Imprime el valor de i en cada iteración\n    i += 1 # Incrementa i en 1 en cada iteración para evitar un bucle infinito\n\n# Manejo de Excepciones\ntry: # Intenta ejecutar el siguiente bloque de código\n    print (10 / 2) # Esto genera una excepción de división por cero\nexcept: # Si se genera una excepción, se ejecuta este bloque de código\n    print (\"Se ha producido un error\") # Imprime un mensaje de error\nfinally: # Este bloque de código se ejecuta siempre, haya o no una excepción\n    print (\"Ha finalizado el manejo de excepciones\") # Imprime un mensaje indicando que ha finalizado el manejo de excepciones\n\n\n'''\nEjercicio EXTRA\n'''\nfor number in range (10, 56): # Itera desde 10 hasta 55 (56 no incluido)\n    if number % 2 == 0 and number != 16 and number % 3 != 0: # Si el número es par, no es 16 y no es múltiplo de 3\n        print (number)\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Juanseevn.py",
    "content": "#OPERADORES MATEMÁTICOS\nnum1 = 6\nnum2 = 3\n\nsuma = num1 + num2\nprint(f\"Suma: {suma}\")\n\nresta = num1 - num2\nprint(f\"Resta: {resta}\")\n\nproducto = num1 * num2\nprint(f\"Producto: {producto}\")\n\ndivision = num1/num2\nprint(f\"División: {division}\")\n\nresiduo = num1%num2\nprint(f\"Residuo: {residuo}\")\n\n#OPERADORES LÓGICOS\ntrue=True\nfalse=False\n\nprint(true and false)\nprint(true or false)\nprint(not false)\n\n#OPERADORES DE COMPARACIÓN\nnum3 = 10\nnum4 = 5\n\nprint(f\"true == false es {true==false}\")\nprint(f\"true != false es {true!=false}\")\nprint(f\"{num3} > {num4} es {num3>num4}\")\nprint(f\"{num3} < {num4} es {num3<num4}\")\n\n#OPERADORES DE ASIGNACIÓN\nx=9\nprint(f\"x=9, {x}\")\nx+=1\nprint(f\"x+=1, {x}\")\nx-=2\nprint(f\"x-=2, {x}\")\nx*=3\nprint(f\"x*=3, {x}\")\nx/=2\nprint(f\"x/=2, {x}\")\nx**=2\nprint(f\"x**=2, {x}\")\n\n#OPERADORES DE IDENTIDAD\n\nprint(f\"10 is 5 es {num3 is num4}\")\nprint(f\"10 is not 5 es {num3 is not num4}\")\n\n#OPERADORES DE MEMBRESÍA\n\nlista = {1,2,3,4,5}\n\nprint(f\"1 in lista es {1 in lista}\")\nprint(f\"6 not in lista es {6 not in lista}\")\n\n#ESTRUCTURAS CONDICIONALES\n\nlista = {6,7,8,9,10}\n\nif 10 in lista:\n    print(\"10 se encuentra dentro de la lista\")\nelif 10 not in lista:\n    print(\"10 no se encuentra dentro de la lista\")\nelse:\n    print(\"Demás eventos\")\n    \n#ESTRUCTUA DE BUCLE\n\nlista = {6,7,8,9,10}\n\nfor i in lista:\n    print(i)\n\nj=0\n    \nwhile j<5:\n    print(j)\n    j+=1\n\n#ESTRUCTURA DE EXCEPCIONES\nx=10\ny=0\n\ntry:\n    x/y\nexcept ZeroDivisionError:\n    print(\"No se puede dividir entre cero\")\n    \n    \n#CASO\nlimiteMin=10\nlimiteMax=56\n\nprint(\"\\nCASO PROPUESTO\")\n\nfor m in range(limiteMin, limiteMax):\n    \n    if(m%2==0 and m!=16 and m%3!=0):\n    \n        print(m)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Julind0.py",
    "content": "\n#Tipos de operadores del lenguaje python\n\n\"Aritmeticos\"\n\n#suma \nresultado_suma = 5+3\nprint(\"El resultado de la suma es:\",resultado_suma)\n\n#Resta\nresultado_resta = 5-3\nprint(\"El resultado de la resta es:\",resultado_resta)\n\n#multiplicación \nresultado_multiplicación = 5*3\nprint(\"El resultado de la multiplicación es:\",resultado_multiplicación)\n\n#División entera y decimal\nresultado_division = 8/2\nprint(\"El resultado de la division es:\", resultado_division)\n\n#Division entera\ndivision_entera = 10//5\nprint(\"El resultado de la division entera es:\",division_entera)\n\n#Modulo o residuo de una operacion \nmodulo = 9%2\nprint(\"El residuo de la operacion es:\",modulo)\n\n#Exponenciacion o elevar a \npotencia = 4**2\nprint(\"El resultado del numero elevado es:\",potencia)\n\n\"Logicos\"\n\n#and Este operador devuelve True si ambos operandos son verdaderos. Si uno de los operandos es falso, devuelve False.\na = False\nb = True\nresultado = a and b\nprint(\"El resultado es:\", resultado)\n\n#or Este operador devuelve True si al menos uno de los operandos es verdadero. Si ambos operandos son falsos, devuelve False.\nresultado1 = a or b\nprint(\"El resultado es\",resultado1)\n\n#not Este operador invierte el valor booleano del operando. Si el operando es True, devuelve False, y si el operando es False, devuelve True.\nvariable = not False\nprint (\"La variable no es falsa sino:\",variable)\n\n\"Operadores de comparacion\"\n\n#igual Comprueba si los valores de dos operandos son iguales.\na=5\nb=5\nprint(\"¿5 es igual a 5?\",a==b)\n\n#Distinto de. Comprueba si los valores de dos operandos no son iguales.\nc=6\nd=5\nprint(c != d)\n\n#Mayor que. Comprueba si el valor del operando de la izquierda es mayor que el valor del operando de la derecha.\nprint(c > d)\n\n#Menor que. Comprueba si el valor del operando de la izquierda es menor que el valor del operando de la derecha.\nprint(d < c)\n\n#Mayor o igual que. Comprueba si el valor del operando de la izquierda es mayor o igual que el valor del operando de la derecha.\nprint (c >= d)\n\n#Menor o igual que.\nprint(d <= c)\n\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/KateAmador.py",
    "content": "# EJERCICIO:\n#  * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n#  *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n#  *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n#  * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n#  *   que representen todos los tipos de estructuras de control que existan\n#  *   en tu lenguaje:\n#  *   Condicionales, iterativas, excepciones...\n#  * - Debes hacer print por consola del resultado de todos los ejemplos.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea un programa que imprima por consola todos los números comprendidos\n#  * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n#  *\n#  * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\n\n# Operadores Aritméticos\na = 10\nb = 3\n\nsuma = a + b\nresta = a - b\nmultiplicacion = a * b\ndivision = a / b\nmodulo = a % b\nexponente = a ** b\ndivision_entera = a // b\n\nprint(\"Operadores Aritméticos:\\n---------------------------\")\nprint(\"Suma:\", suma)    \nprint(\"Resta:\", resta)\nprint(\"Multiplicación:\", multiplicacion)\nprint(\"División:\", division)\nprint(\"Módulo:\", modulo)\nprint(\"Exponente:\", exponente)\nprint(\"División Entera:\", division_entera)\n\n\n# Operadores de asignación\nx = 5 \n\nprint(\"\\nOperadores de Asignación:\\n---------------------------\")\nx += 2 \nprint(\"Después de x += 2:\", x)\nx -= 1\nprint(\"Después de x -= 1:\", x)\nx *= 3 \nprint(\"Después de x *= 3:\", x)\nx /= 2 \nprint(\"Después de x /= 2:\", x)\nx %= 2 \nprint(\"Después de x %= 2:\", x)\nx //= 2 \nprint(\"Después de x //= 2:\", x)\nx **= 2\nprint(\"Después de x **= 2:\", x)\nx = int(x)  # Asegurar que x es entero antes de operaciones bit a bit\nx &= 1 \nprint(\"Después de x &= 1:\", x)\nx |= 2 \nprint(\"Después de x |= 2:\", x)\nx ^= 1 \nprint(\"Después de x ^= 1:\", x)\nx >>= 1 \nprint(\"Después de x >>= 1:\", x)\nx <<= 1\nprint(x := 3)\n\n\n# Operadores de comparación\na = 7\nb = 10\n\nigual = a == b\ndiferente = a != b\nmayor_que = a > b\nmenor_que = a < b\nmayor_o_igual = a >= b\nmenor_o_igual = a <= b\n\nprint(\"\\nOperadores de Comparación:\\n---------------------------\")\nprint(\"Igual:\", igual)\nprint(\"Diferente:\", diferente)  \nprint(\"Mayor que:\", mayor_que)\nprint(\"Menor que:\", menor_que)\nprint(\"Mayor o igual:\", mayor_o_igual)  \nprint(\"Menor o igual:\", menor_o_igual)\n\n# Operadores lógicos\nx = 10\ny = 5\n\nand_result = (x > 5) and (y < 10)\nor_result = (x < 5) or (y < 10)\nnot_result = not (x > 5)\n\nprint(\"\\nOperadores Lógicos:\\n---------------------------\")\nprint(\"AND:\", and_result)\nprint(\"OR:\", or_result)\nprint(\"NOT:\", not_result)\n\n\n# Operadores de identidad\nlist1 = [1, 2, 3]\nlist2 = list1\nis_result = list1 is list2\nis_not_result = list1 is not [1, 2, 3]\n\nprint(\"\\nOperadores de Identidad:\\n---------------------------\")\nprint(\"is:\", is_result)\nprint(\"is not:\", is_not_result)\n\n\n# Operadores de pertenencia\nfrutas = ['manzana', 'banana', 'cereza']\nin_result = 'banana' in frutas\nnot_in_result = 'pera' not in frutas\n\nprint(\"\\nOperadores de Pertenencia:\\n---------------------------\")\nprint(\"in:\", in_result)\nprint(\"not in:\", not_in_result)\n\n\n# Operadores a nivel de bits\np = 5\nq = 3\nand_bit = p & q\nor_bit = p | q\nxor_bit = p ^ q\nnot_bit = ~p\nleft_shift = p << 1\nright_shift = p >> 1\n\nprint(\"\\nOperadores a Nivel de Bits:\\n---------------------------\")\nprint(\"AND a nivel de bits:\", and_bit)\nprint(\"OR a nivel de bits:\", or_bit)\nprint(\"XOR a nivel de bits:\", xor_bit)\nprint(\"NOT a nivel de bits:\", not_bit)\nprint(\"Desplazamiento a la izquierda:\", left_shift)\nprint(\"Desplazamiento a la derecha:\", right_shift)\n\n\n\n# Estructuras de control\nprint(\"\\nEstructuras de Control:\\n---------------------------\")\n\n# Estructura condicional\nprint(\"Estructura Condicional\\n---------------------------\")\n\nnum = 15\n\nif num > 10:\n    print(\"El número es mayor que 10\")\nelif num == 10:\n    print(\"El número es igual a 10\")\nelse:\n    print(\"El número es menor que 10\")\n\n\nmy_string = \"Hola Mundo\"\nif 'Mundo' in my_string:\n    print(\"La cadena contiene 'Mundo'\")\nelse:\n    print(\"La cadena no contiene 'Mundo'\")\n\n\nday = \"Sábado\"\nmatch day:\n    case \"Lunes\":\n        print(\"Hoy es Lunes\")\n    case \"Martes\":\n        print(\"Hoy es Martes\")\n    case \"Miércoles\":   \n        print(\"Hoy es Miércoles\")\n    case \"Jueves\":\n        print(\"Hoy es Jueves\")\n    case \"Viernes\":\n        print(\"Hoy es Viernes\")\n    case \"Sábado\" | \"Domingo\":\n        print(\"Es fin de semana\")\n    case _:\n        print(\"Día no válido\")\n\n\n# Estructura iterativa\nprint(\"\\nEstructura Iterativa\\n---------------------------\")\n\nfor i in range(16):\n    print(\"Iteración:\", i)\n\nnum = 0\nwhile num <= 15:\n    print(\"Iteración:\", num)\n    num += 1\n\n\n# Estructura de manejo de excepciones\nprint(\"\\nEstructura de Manejo de Excepciones\\n---------------------------\")\ntry:\n    resultado = 10 / 0\nexcept ZeroDivisionError:\n    print(\"Error: División por cero no permitida.\")\nfinally:\n    print(\"Bloque finally ejecutado.\")\n\n\n\n# DIFICULTAD EXTRA\nprint(\"\\nNúmeros entre 10 y 55, pares, que no son ni el 16 ni múltiplos de 3:\\n---------------------------\")\n\nfor numero in range(10, 56):\n    if numero % 2 == 0 and numero != 16 and numero % 3 != 0:\n        print(numero)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Kcx46.py",
    "content": "#Operadores y estructuras de control#\n\n#operadores aritmeticos\nsuma = 5 + 5\nresta = 5 - 5\nmultiplicacion = 5 * 5\ndivision = 5 / 5\ndivision_entera = 5 // 5\nmodulo = 5 % 5\npotencia = 5 ** 5\n#operadores logicos\nand_op = True and False\nor_op = True or False\nalso_or_op = True | False\nnot_op = not True\n#operadores de comparacion\nigual = 5 == 5\ndiferente = 5 != 5\nmayor_que = 5 > 5\nmenor_que = 5 < 5\nmayor_o_igual_que = 5 >= 5\nmenor_o_igual_que = 5 <= 5\n#printeos\nprint(f\"5 + 5 = {suma}\", \"\\n\")\nprint(f\"5 - 5 = {resta}\", \"\\n\")\nprint(f\"5 * 5 = {multiplicacion}\", \"\\n\")\nprint(f\"5 / 5 = {division}\", \"\\n\")\nprint(f\"5 // 5 = {division_entera}\", \"\\n\")\nprint(f\"5 % 5 = {modulo}\", \"\\n\")\nprint(f\"5 ** 5 = {potencia}\", \"\\n\")\nprint(f\"True and False = {and_op}\", \"\\n\")\nprint(f\"True or False = {or_op}\", \"\\n\")\nprint(f\"True | False = {also_or_op}\", \"\\n\")\nprint(f\"not True = {not_op}\", \"\\n\")\nprint(f\"5 == 5 es {igual}\", \"\\n\")\nprint(f\"5 != 5 es {diferente}\", \"\\n\")\nprint(f\"5 > 5 es {mayor_que}\", \"\\n\")\nprint(f\"5 < 5 es {menor_que}\", \"\\n\")\nprint(f\"5 >= 5 es {mayor_o_igual_que}\", \"\\n\")\nprint(f\"5 <= 5 es {menor_o_igual_que}\", \"\\n\")\nprint(\"*\"*50)\n#estructuras de control\nprint(\"**ESTRUCTURAS DE CONTROL**\")\nprint(\"if sum == 10 print sum \\n\")\nif suma == 10:\n    print(\"La suma es igual a 10\")\nelse:\n    print(\"La suma no es igual a 10\")\nif resta == 0:\n    print(\"La resta es igual a 0\")\nelif resta < 0:\n    print(\"La resta es menor a 0\")\nelse:\n    print(\"La resta es mayor a 0\")\nprint(\"\\n\")\n\nlist_for_for = [1, 2, 3, 4, 5]\nprint(\"**FOR**\")\nfor i in list_for_for:\n    print(i)\nprint(\"\\n\")\nprint(\"**WHILE**\")\nwhile suma < 20:\n    print(suma)\n    suma += 1\nprint(\"\\n\")\nprint(\"*\"*50)\nprint(\"***EJERCICIO EXTRA***\")\n#Dificultad extra\n'''\nEste imprime por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n'''\nfor i in range(10, 57):\n    if i % 2 == 0 and i != 16 and 1 % 3 != 0:\n        print(i)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/KevinED11.py",
    "content": "##01 - OPERADORES Y ESTRUCTURAS DE CONTROL\n\"\"\"\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\"\"\"\n\n#Aritméticos\nsuma : int = 3 + 4\nresta : int = 3 - 4\nmultiplicacion : int = 3 * 4\ndivision : float = 3 / 4                                    #siempre regresa un float\npotencia : int = 3 ** 5\nDivision_baja : int = 3 // 3                                #las divisiones bajas regresan un valor entero , el mas bajo por ejemplo si la resuesta es 4.9 regresara 4 int\nresto : float = 3 % 4                                       #regresa el restante de una division\n\nprint(\"------------Aritméticos----------------\")\nprint(f\"\"\"\n        suma  3 + 4 = {suma}\n        resta  3 - 4 = {resta}\n        multiplicacion  3 * 4 = {multiplicacion}\n        division  3 / 4 = {division}\n        potencia  3 ** 5 = {potencia}\n        Division_baja   3 // 3 = {Division_baja}\n        resto  3 % 3 = {resto}\n      \"\"\")\n\n#logicos\nprint(\"------------logicos----------------\")\n\nprint(\"True and True = \" , True and True)                #para que and sea sierto las 2 opciones tienen que ser verdaderas si no false\nprint(\"True and False = \" , True and False)\n\nprint(\"True or False = \" , True or False)                #con que una sea verdadera regresara verdadero si no false\nprint(\"False or False = \", False or False)\n\nprint(\"not False = \",not False)                         #retorna >true\nprint(\"not True = \",not True)                           #retorna < false\n\n#comparación\nprint(\"------------comparación----------------\")\n\nmayor_que : bool = 3 > 4\nmenor_que : bool= 3 < 4\nigual_que : bool = 3 == 4\ndiferente_que : bool = 3 != 4\nmayor_o_igual : bool = 3 >= 4\nmenor_o_igual : bool = 3 <= 4\n\nprint(f\"\"\"\n        mayor_que  3 > 4 {mayor_que}\n        menor_que  3 < 4 {menor_que}\n        igual_que  3 == 4 {igual_que}\n        diferente_que  = 3 != 4 {diferente_que}\n        mayor_o_igual  = 3 >= 4 {mayor_o_igual}\n        menor_o_igual  = 3 <= 4 {menor_o_igual}\n      \"\"\")\n\n#asignación\nprint(\"------------asignación----------------\")\n\nvariable_vacia : int = 12\nvariable_vacia += 3\nvariable_vacia -= 4\nvariable_vacia *= 2\nvariable_vacia /= 2\nvariable_vacia **= 3\nvariable_vacia //= 6\nvariable_vacia %= 4\n\nprint(\"\"\"\n    VARIABLE += 3\n    VARIABLE -= 4\n    VARIABLE *= 2\n    VARIABLE /= 2\n    VARIABLE **= 3\n    VARIABLE //= 6\n    VARIABLE %= 4\n     \"\"\")\n\n#identidad\nprint(\"------------asignación----------------\")\n\nmayor_que is True\nnot menor_que is False\n\nprint(\"\"\"\n        is\n        not is\"\"\")\n\n#pertenencia\nprint(\"------------pertenencia----------------\")\nmy_variable = \"hola mundo\"\n\nresultado1 = \"hola\" in my_variable\nresultado2 = \"hola\" not in my_variable\nprint(\"\"\"\n        in\n        not in\"\"\")\n\n#bits\nprint(\"------------bits----------------\")#este no se usa casi nunca por no decir nunca\nnum1 = 0b101\nnum2 = 0b011\n\nresultado_and = num1 & num2\nresultado_or = num1 | num2\nresultado_xor = num1 ^ num2\nresultado_izquierda = num1 << 2\nresultado_derecha = num1 >> 2\n\nprint(f\"\"\"\n        resultado_and = {resultado_and}\n        resultado_or = {resultado_or}\n        resultado_xor = {resultado_xor}\n        resultado_izquierda = {resultado_izquierda}\n        resultado_derecha = {resultado_derecha}\n      \"\"\")\n\n\"\"\"\n#control de flujo\n#bucles\n#range para repetir una cantidad de veces definida\n\"\"\"\n\nfor i in range(1 , 4):\n    print(f\"------------{i}----------------\")\n\n#for para iterar cada elemento de la lista\nfor i in [1 , 2 , 4 ,6]:\n    print(i)\n\n\nprint(\"------------while----------------\\n\")\ni = 0\n\n#while se ejecuta mientras la condicion se cumpla , cuidado con los bucles infinitos\nwhile i < 5:\n    print(i)\n    i += 1\n\n\n#Condicionales\nprint(\"------------Condicionales_&_excepciones----------------\\n\")\n\nclave = 1234\n\ntry: #manejo de excepciones\n    clave_introducida = int(input(\"introduce la contraseña numerica : \"))\n\n    if clave == clave_introducida: #si retorna un True se ejecuta si no se ejecutara el else\n        print(\"contraseña correcta\")\n\n    else :\n        print(\"contraseña incorrecta\")\n\nexcept ValueError as error:\n    print(\"el valor no es numerico\")\n\n\nprint(\"------------Condicionales_&_comparadores_logicos----------------\\n\")\n\nfor number in range(1, 46):\n\n    if number % 3 == 0 and number % 5 == 0:\n        print(number , \"fizzbuzz\")\n\n    elif number % 3 == 0:\n        print(number , \"fizz\")\n\n    elif number % 5 == 0:\n        print(number , \"buzz\")\n\n#EXTRA\n\nprint(\"------------reto_extra----------------\\n\")\nfor i in range(10 , 56):\n\n    if i == 16:\n        continue\n\n    if i % 2 == 0 :\n        if i % 3 != 0 :\n            print(i)\n    else :\n        continue"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Lazar171717ech.py",
    "content": "## 1. OPERADORES DE LENGUAJE ##\n\n# Aritmeticos #\nprint(f\"Suma: 5 + 2 = {5 + 2}\") #Es 7\nprint(f\"Resta: 5 - 2 = {5 - 2}\") #Es 3\nprint(f\"Multiplicación: 5 * 2 = {5 * 2}\") #Es 10\nprint(f\"División: 5 / 2 = {5 / 2}\") #Es 2.5\nprint(f\"División Entera: 5 // 2 = {5 // 2}\") #Es 2 (Se quitan los decimales y deja un resultado entero)\nprint(f\"Módulo: 5 % 2 = {5 % 2}\") #Es 1 (Se refiere al resto de la división)\nprint(f\"Potencia: 5 ** 2 = {5 ** 2}\") #Es 25\n\n# Lógicos #\nprint(f\"True and True = {True and True} / True and False = {True and False}\") #Solo será True si ambos son True (True, False)\nprint(f\"True or False = {True or False} / False or False = {False or False}\") #Solo será True si uno o ambos son True (True, False)\nprint(f\"not True = {not True} / not False = {not False}\") #Cambia de True a False y de False a True (False, True)\n\n# Comparación #\nprint(f\"Mayor: 5 > 2 = {5 > 2} / 2 > 5 = {2 > 5}\") #Será True si el primer valor es mayor al segundo (True, False)\nprint(f\"Menor: 5 < 2 = {5 < 2} / 2 < 5 = {2 < 5}\") #Será True si el primer valor es menor al segundo (False, True)\nprint(f\"Igual: 5 == 2 = {5 == 2} / 5 == 5 = {5 == 5}\") #Será True si los dos valores son iguales (False, True)\nprint(f\"Diferente: 5 != 2 = {5 != 2} / 5 != 5 = {5 != 5}\") #Será True si los dos valores son diferentes (True, False)\nprint(f\"Mayor o igual: 5 >= 2 {5 >= 2} / 5 >= 5 = {5 >= 5}\") #Será True si el primer valor es mayor al segundo o si ambos son iguales (True, True)\nprint(f\"Menor o igual: 5 <= 2 {5 <= 2} / 5 <= 5 = {5 <= 5}\") #Será True si el primer valor es menor al segundo o si ambos son iguales (True, True)\n\n# Asignación #\nvar: int = 5\nvar += 2 #Esto sería equivalente a \"var = var + 2\" por lo que se sumaría al valor de var (var = 7)\nvar -= 2 #Esto sería equivalente a \"var = var - 2\" por lo que se restaría al valor de var (var = 5)\nvar *= 2 #Esto sería equivalente a \"var = var * 2\" por lo que se multiplicaría al valor de var (var = 10)\nvar /= 2 #Esto sería equivalente a \"var = var / 2\" por lo que se dividiría al valor de var (var = 5)\n\n# Identidad #\nvar1: int = 5\nvar2: int = 2\nprint(f\"var1 is var2 = {var1 is var2} / var1 is var1 = {var1 is var1}\") #Comprobamos si estamos haciendo referencia a la misma instancia (False, True)\nprint(f\"var1 is not var2 = {var1 is not var2} / var1 is not var1 = {var1 is not var1}\") #Comprobamos si estamos haciendo referencia a diferente instancia (True, False)\n#Podríamos decir que lo que compara no son las variables en sí sino sus id's (id(var1) == id(var2))\n\n# Pertenencia #\nlista = [1, 3, 5, 7, 9]\nprint(f\"5 in lista = {5 in lista} / 2 in lista = {2 in lista}\") #Comprobamos que la primera parte está en la lista (True, False)\nprint(f\"5 not in lista = {5 not in lista} / 2 not in lista = {2 not in lista}\") #Comprobamos que la primera parte NO está en la lista (False, True)\n\n# Bits #\nprint(f\"y: bin(5 & 2) = {bin(5 & 2)} / bin(5 & 4) = {bin(5 & 4)}\") #Aquí se comparan los bits de los números por parejas siendo 1 si ambos son 1 (0b0, 0b100)\nprint(f\"o: bin(5 | 2) = {bin(5 | 2)} / bin(5 | 4) = {bin(5 | 4)}\") #Aquí se comparan los bits de los números por parejas siendo 1 si al menos alguno de los dos es 1 (0b111, 0b101)\nprint(f\"xor: bin(5 ^ 2) = {bin(5 ^ 2)} / bin(5 ^ 4) = {bin(5 ^ 4)}\") #Aquí se comparan los bits de los números por parejas siendo 1 si solo uno de los dos es 1 (0b111, 0b1)\nprint(f\"not: ~bin(5) = {bin(~5)} / ~bin(2) = {bin(~2)}\") #Aquí se cambian cada uno de los bits de 1 a 0 y de 0 a 1. Aquí lo que hace es el contrario.\nprint(f\"deslizar a la derecha: bin(5>>2) = {bin(5>>2)} / bin(2>>2) = {bin(2>>2)}\") #Aquí traslada los bits ciertas unidades a la derecha (0b1, 0b0)\nprint(f\"deslizar a la izquierda: bin(5<<2) = {bin(5<<2)} / bin(2<<2) = {bin(2<<2)}\") #Aquí traslada los bits ciertas unidades a la izquierdas (0b10100, 0b1000)\n\n## 2. ESTRUCTURAS DE CONTROL ##\n\n# Condicional #\n\nif \"Hola\" == \"Adiós\": #Aquí se realiza una condición y solo si esta es True se ejecuta el codigo.\n    print(\"Es el fin del mudo\") #Este es el codigo que se ejecuta si la condición es True.\nelif \"Hola\" == \"Hasta mañana\": #Esta condición solo se ejecutará si la anterior no lo hizo. elif viene de un \"else: if:\"\n    print(\"Es el fin del mundo\") #Este es el codigo que se ejecuta si la segunda condición es True.\nelse: #Esta condición solo se ejecutará si todas las anteriores no lo hicieron.\n    print(\"Todo bien\") #Este es el codigo que se ejecuta si la última condición es True.\n\n# Bucle while #\n\nvar: int = 0\nwhile var <= 10: #Se establece una condición que se comprueba en cada ciclo\n    var += 1\n    print(var) #El código dentro del bucle se ejecutará continuamente hasta que la condición deje de cumplirse\nprint(\"¡Bucle terminado!\")\n\n# Bucle for #\n\nfor index in range(0, 10): #Se establece una variable que recorrerá un contenedor dandole cada valor del contenedor en cada ciclo\n    if index == 3: #Cuando hacemos referencia al index dentro del bucle hacemos referencia a su valor en el ciclo\n        continue #El continue hace saltar al bucle al siguiente ciclo\n    print(index)\nprint(\"¡Bucle terminado!\")\n\n# Excepción #\n\ntry:\n    var: int = int(\"Hola\") #Intenta realizar la operación\nexcept ValueError: #Si en la operación del try surge un error, en este caso un ValueError, Ejecutará el codigo\n    print(\"Error!\")\n\n## 3. EJERCICIO EXTRA ##\n\nfor index in range(10, 56, 2):\n    if index != 16 and index % 3 != 0:\n        print(index)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Lilitr09.py",
    "content": "# Name: Liliana N. Torres Rignack\n\n# EJERCICIO\n\n# OPERADORES ARITMETICOS\nprint(\"--> OPERADORES ARITMETICOS <--\")\n\nmy_sum = 10 + 9\nprint(my_sum)\n\nmy_rest = 10 - 9\nprint(my_rest)\n\nmy_multiplication = 79 * 45\nprint(my_multiplication)\n\nmy_division = 189 / 4\nprint(my_division)\n\nmodulo_operator = 20 % 2\nprint(modulo_operator)\n\nmy_floor_division = 256 // 3\nprint(my_floor_division)\n\nmy_exponent = 2**6\nprint(my_exponent)\n\n# OPERADORES DE COMPARACION\nprint(\"--> OPERADORES DE ASIGNACION <--\")\nprint(2 == 2)  # True\nprint(\"A\" != \"a\") # True\nprint(25 > 30) # False\nprint(23456 < 23658) # True\nprint(10 >= 10) # True\nprint(5 <= 6) # True\n\n# OPERADORES LOGICOS\nprint(\"--> OPERADORES LOGICOS <--\")\nprint(f\"False and False --> {False and False}\") # False\nprint(f\"True or False --> {True or False}\") # True\nprint(f\"not True --> {not True}\") # False\n\n# OPERADORES DE ASIGNACION\nmy_name = \"Liliana\" # Asignacion simple\nmy_num: int = 2\nmy_num += 4 # my_num = 6\nmy_num -= 1 # my_num = 5\nmy_num *= 5 # my_num = 25\nmy_num /= 5 # my_num = 5\n\n# BITS\nprint(\"--> BITS <--\")\nx = 4\ny = 5\nprint(f\"AND bit a bit --> {x & y}\")\nprint(f\"OR bit a bit --> {x | y}\")\nprint(f\"XOR bit a bit --> {x ^ y}\")\nprint(f\"Complemento bit a bit --> {x} --> {~x}\")\nprint(f\"Desplazamiento a la izquierda {x << 1}\")\nprint(f\"Desplazamiento a la derecha {x >> 1}\")\n\n# OPERADORES DE IDENTIDAD\nprint(\"--> OPERADORES DE IDENTIDAD <--\")\nvariable_1: str = \"Variable\"\nvariable_2: str = \"variable\"\nprint(variable_1 is variable_2) # False\nprint(variable_1 is not variable_2) # True\n\n# OPERADORES DE PERTENENCIA\nprint(\"--> OPERADORES DE PERTENENCIA <--\")\nmy_list = [10, 20, 30, 40, 50]\nprint(25 in my_list) # False\nprint(40 not in my_list) # False\n\n# ESTRUCTURAS DE CONTROL\n\nprint(\"--> CONDICIONAL <--\")\n# Condicionales\nvar = 10\nif var < 12:\n    print(\"Less than 12\")\nelif var > 12:\n    print(\"Greater than 12\")\nelse:\n    print(\"Equals to 12\")\n\nprint(\"--> WHILE LOOP <--\")    \n# Bucles while\nvar = 1\nwhile var <= 5:\n    print(var)\n    var += 1\n\nprint(\"--> FOR LOOP <--\")    \n# Bucles for\nfor _ in range(6):\n    print(\"This is a for loop!\")\n\nprint(\"--> TRY / EXCEPT <--\")    \n# Excepciones\ntry:\n    print(\"Trying\")\nexcept ValueError:\n    print(\"Cannot do this\")\n\nprint(\"--> EXTRA <--\")    \n# DIFICULTAD EXTRA\ndef numbers(a, b):\n    for number in range(a, b + 1, 2):\n        if number is not 16 and number % 3 != 0:\n            print(number)\n\nnumbers(10, 55)\n        "
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Lio7master.py",
    "content": "'''\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n'''\n\"\"\"\nOPERADORES\n\"\"\"\n#Operadores aritméticos\nprint(\"Operadores aritméticos\")\n\nprint(f\"Suma: 10 + 3 = {10 + 3}\")\nprint(f\"Resta: 10 - 3 = {10 - 3}\")\nprint(f\"Multiplicación: 10 * 3 = {10 * 3}\")\nprint(f\"División: 10 / 3 = {10 / 3}\")\nprint(f\"División entera: 10 // 3 = {10 // 3}\") #La división entera es la parte entera de la división\nprint(f\"Modulo: 10 % 3 = {10 % 3}\") #El modulo es el resto de la división\nprint(f\"Potencia: 10 ** 3 = {10 ** 3}\")\nprint(f\"Raíz cuadrada: 10 ** (1/2) = {10 ** (1/2)}\")\nprint(f\"Raíz cúbica: 10 ** (1/3) = {10 ** (1/3)}\")\n#Raízes a la n: 10 ** (1/n) = {10 ** (1/n)})\n\n#Operadores de comparación\nprint(\"Operadores de comparación\")\nprint(f\"Mayor que: 10 > 3 = {10 > 3}\")\nprint(f\"Menor que: 10 < 3 = {10 < 3}\")\nprint(f\"Mayor o igual que: 10 >= 3 = {10 >= 3}\")\nprint(f\"Menor o igual que: 10 <= 3 = {10 <= 3}\")\nprint(f\"Igual que: 10 == 3 = {10 == 3}\")\nprint(f\"Diferente que: 10 != 3 = {10 != 3}\")\n\nprint(\"Operadores lógicos\")\nprint(f\"AND &&: 10 +3 == 13 and 5 - 1 == 4 es {10 + 3 == 13 and 5 - 1 == 4}\")\nprint(f\"OR ||: 10 + 3 == 14 or 5 - 1 == 4 es {10 + 3 == 14  or 5 - 1 == 4}\")\nprint(f\"NOT !: not 10 + 3 == 14 es { not 10 + 3 == 14}\")\n\n#Operadores de asignacion\nmy_number = 11 #asiganación\nprint(my_number)\nmy_number += 1#Suma y asignación\nprint(my_number)\nmy_number -= 1 #Resta y asignación\nprint(my_number)\nmy_number *= 2 #Multiplicación y asignación\nprint(my_number)\nmy_number /=2 #División y asignación\nprint(my_number)\nmy_number %= 2 #Modulo y asignación\nprint(my_number)\nmy_number **= 2 #Exponenete y asignación\nprint(my_number)\nmy_number //= 1 #Division enterea y asignación\nprint(my_number)\n\n#Operadores de identidad \nmy_new_number = 1.0\nprint(f\"my_number is my_new_number es {my_number is my_new_number}\") #Es False porque aunque tienen el mismo valor ocupan diferentes direciones de memoria\n\nmy_new_var = my_number\n\nprint(f\"my_new number is my_number es: {my_new_number is my_new_number}\") #Ahora si es true porque hemos indicado que se apunte el mismo valor de memoria\nprint(f\"my_new number is not my_number es: {my_new_number is not my_new_number}\")\n\n#Operadores de pertenencia\nprint(f\"'m' in 'Lio7master' = {'m' in 'Lio7master'}\")\nprint(f\"'u' not in 'Lio7master' = {'u' not in 'Lio7master'}\")\n\n#Operadores de bit\na = 10 # 1010\nb = 3 # 0011\n\nprint(f\"AND: 10 & 3= {10 & 3}\") # 0010 el resultado devuelve en bit la comparacion\nprint(f\"OR: 10 | 3= {10 & 3}\") # 1011\nprint(f\"XOR: 10 ^ 3= {10 ^ 3}\") # 1001\nprint(f\"NOT: ~10 = {~10}\") # 0101\nprint(f\"Dezplazamiento a la derecha: 10 >> 2 = {10 >> 2}\")# 0010\nprint(f\"Dezplazamiento a la izquierda: 10 >> 2 = {10 << 2}\")# 101000\n\n\"\"\"\nESTRUCTURAS DE CONTROL\n\"\"\"\n\n#Condicionales\nmy_string = \"Lio7master\"\n\nif my_string == \"Leonardo\":\n    print(\"my_string es 'Leonardo'\")\nelif my_string == \"Lio7master\":\n    print(\"my_string es 'Lio7master'\")\nelse:\n    print(\"my_string no es 'Leonardo' ni es 'Lio7master\")\n\n#Interactivas\nfor i in range(11): #Range excluye el ultimo numero indicado siendo el 11 el resultado dara 10\n    print(i)\n\ni = 0\nwhile (i<= 10):\n    print(i)\n    i += 1\n\n#Manejo de excepciones\ntry:\n    print(10/0)\nexcept:\n    print(\"Se ha producido un error\")\nfinally:\n    print(\"finalizado el manejo de excepciones\")"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Lioomx.py",
    "content": "\n'''\nTipos de operadores en Python\n'''\n# OPERADORES ARTMÉTICOS (Realizan operaciones matemáticas básicas)\n\na = 10; b = 3\n\nsuma = a + b \nprint(suma)\n\nresta = a - b\nprint(resta)\n\nmultiplicación = a * b\nprint(multiplicación)\n\ndivisión = a / b # flotante\nprint(división)\n\ndivisión_entera = a // b\nprint(división_entera)\n\nMódulo = a % b # Residuo de la división\nprint(Módulo)\n\nExponenciación = a ** b\nprint(Exponenciación)\n\n# OPERADORES DE COMPARACIÓN (Comparan dos valores y devuelven un Booleano)\n'''\nUn Booleano sólo puede tener dos valores posibles: True o False\n'''\n\nIgualdad = a == b\nprint(Igualdad)\n\nDesigualdad = a != b\nprint(Desigualdad)\n\nMayor_que = a > b\nprint(Mayor_que)\n\nMenor_que = a < b\nprint(Menor_que)\n\nMayor_o_igual_que = a >= b\nprint(Mayor_o_igual_que)\n\nMenor_o_igual_que = a <= b\nprint(Menor_o_igual_que)\n\n# OPERADORES LÓGICOS (Permiten combinar valores Booleanos y devuelen un Booleano)\n\nx = True; y = False\n\nAND = x and y # Devuelve True si ambos valores son True\nprint(AND)\n\nOR = x or y # Devuelve True si al menos uno de los valores es True \nprint(OR)\n\nNOT = not x # Devuelve True si el valor es Falsa y viceversa\nprint(NOT)\n\n# OPERADORES DE ASIGNACIÓN (Asignan un valor a una variable)\n\na = 7; b = 2 # Asignación simple\nprint(a, b)\n\nx=a; x+=b; print(\"x+=\", x) # Suma en asignación\nx=a; x-=b; print(\"x-=\", x) # Resta en asignación\nx=a; x*=b; print(\"x*=\", x) # Multiplicación en asignación\nx=a; x/=b; print(\"x/=\", x) #División en asignación\nx=a; x%=b; print(\"x%=\", x) # Módulo en asignación\nx=a; x//=b; print(\"x//=\", x) # División entera en asignación\nx=a; x**=b; print(\"x**=\", x) # Exponenciación en asignación\nx=a; x&=b; print(\"x&=\", x) # AND en asignación\nx=a; x|=b; print(\"x|=\", x) # OR en asignación\nx=a; x^=b; print(\"x^=\", x) # XOR en asignación\nx=a; x>>=b; print(\"x>>=\", x) # Desplazamiento a la derecha en asignación \nx=a; x<<=b; print(\"x<<=\", x) # Desplazamiento a la izquierda en asignación\n\n# OPERADORES BIT A BIT (Realizan operaciones bit a bit)\n\na = 10; b = 3\n\nAND = a & b # AND bit a bit\nprint(AND)\n\nOR = a | b # OR bit a bit\nprint(OR)\n\nXOR = a ^ b # XOR bit a bit\nprint(XOR)\n\nNOT = ~a # NOT bit a bit\nprint(NOT)\n\nDesp_a_izq = a << b # Desplazamiento a la izquierda\nprint(Desp_a_izq)\n\nDesp_a_der = a >> b # Desplazamiento a la derecha\nprint(Desp_a_der)\n\n#OPERADORES DE IDENTIDAS (Comparan la memoria de dos objetos y devuelven un Booleano)\n\na = 10; b = 10; c = 5\n\nis_1 = a is b # Devuelve True si ambos objetos son iguales\nprint(is_1)\n\nis_2 = a is c # Devuelve True si ambos objetos son iguales\nprint(is_2)\n\nis_not_1 = a is not b # Devuelve Trues si ambos objetos no son iguales\nprint(is_not_1)\n\nis_not_2 = a is not c # Devuelve True si ambos objetos no son iguales\nprint(is_not_2)\n\n# OPERADORES DE PERTENENCIA (Comprueban si un objeto se encuentra en otro objetos y devuelven un Booleano)\n\nlista = [1, 2, 3, 4, 5]\n\nin_1 = 1 in lista # Devuelve True si el objeto se encuentra en la lista\nprint(in_1)\n\nin_2 = 6 in lista # Devuelve True si el objeto se encuentra en la lista\nprint(in_2)\n\nnot_in_1 = 1 not in lista # Devuelve True si el objeto no se encuentra en la lista\nprint(not_in_1)\n\nnot_in_2 = 6 not in lista # Devuelve True si el objeto no se encuentra en la lista\nprint(not_in_2)\n\n# OPERADORES DE MEMBRESÍA (Comprueban si un objeto se encuentra en otro objeto y devuelve un Booleano)\n\ncadena = \"Hola Mundo\"\n\nin_1 = \"H\" in cadena # Devuelve True si el objeto se encuentra en la cadena\nprint(in_1)\n\nin_2 = \"h\" in cadena # Devuelve True si el objeto se encuentra en la cadena\n\nnot_in_1 = \"H\" not in cadena # Devuelve True si el objeto no se encuentra en la cadena\nprint(not_in_1)\n\nnot_in_2 = \"h\" not in cadena # Devuelve True si el objeto no se encuentra en la cadena\n\n# OPERADORES TERNARIOS (Permiten realizar una operación condicional)\n\na = 10; b = 20\n\nresultado = a if a > b else b \nprint(resultado)\n\n'''\nEjemplos prácticos Ternarios\n'''\n# Asignar Valores\n\nedad = 18\nmensaje = \"Mayor de edad\" if edad >= 18 else \"Menor de edad\"\nprint(mensaje)  # Salida: Mayor de edad\n\n# Usar una función\n\ndef obtener_estado(puntaje): # def: es una palabra reservada que indica que se encuentra definida una función\n    return \"Aprobado\" if puntaje >= 60 else \"Reprobado\"\n\nprint(obtener_estado(75))  # Salida: Aprobado\nprint(obtener_estado(50))  # Salida: Reprobado\n\n# Anidar operadores ternarios\n\na = 5\nb = 10\nc = 15\n\nresultado = \"a es mayor\" if a > b and a > c else \"b es mayor\" if b > c else \"c es mayor\"\nprint(resultado)  # Salida: c es mayor\n\n# Usar en listas o generadores\n\nnumeros = [1, 2, 3, 4, 5]\npares_o_impares = [\"Par\" if num % 2 == 0 else \"Impar\" for num in numeros]\nprint(pares_o_impares)  # Salida: ['Impar', 'Par', 'Impar', 'Par', 'Impar']\n\n# OPERADORES DE CONCATENACIÓN (Unen dos o mas cadenas)\n\ncadena_1 = \"Hola\"\ncadena_2 = \"Mundo\"\n\nconcatenacion = cadena_1 + \" \" + cadena_2\nprint(concatenacion)\n\n# OPERADORES DE REPETICIÓN (Repite una cadena un número determinado de veces)\n\ncadena = \"Hola\"\n\nrepetición = cadena * 3\nprint(repetición)\n\n# OPERADORES DE SLICING (Extraen una parte de una cadena)\n\ntexto = \"Hola Mundo\"\n\nslicing = texto[0:4] # Extrae las primeras 4 letras \"Hola\"\nprint(slicing)\nslicing = texto[-5:] # Extrae las ultimas 5 letras \"Mundo\"\nprint(slicing)\nslicing = texto[::-1] # Invierte el texto\nprint(slicing)\n\n# OPERADORES DE FORMARO (Permiten formatear una cadena)\n\nnombre = \"Lio\"\nedad = 25\n\nformateo = \"Hola, mi nombre es {} y tengo {} años\".format(nombre, edad)\nprint(formateo)\n\nformateo = \"Hola, mi nombre es {0} y tengo {1} años\".format(nombre, edad)\nprint(formateo)\n\nformateo = \"Hola, mi nombre es {nombre} y tengo {edad} años\".format(nombre=\"Lio\", edad=25)\nprint(formateo)\n\n# OPERADORES DE ENTRADA Y SALIDA (Permiten recibir y mostrar información)\n\nnombre = input(\"ingresa tu nombre: \") # Input: Recibe información del usuario y la almacena en una variable\nprint(\"Hola\", nombre)\n\nedad = input(\"Ingresa tu edad: \")\nprint(\"Tu edad es\", edad)\n\n# OPERADORES DE SALIDA (Muestran información en la consola)\n\nprint(\"Hola Mundo\") # Print: Muestra información en la consola \nprint(\"Hola\", \"Mundo\") \nprint(\"Hola\" + \"Mundo\")\n\n# OPERADORES DE COMENTARIOS (Permiten añadir comentarios en el código fuente)\n\n# Comentario de una sola línea\n\n'''\nComentario\nde\nvarias\nlíneas\n'''\n\n# OPERADORES DE BLOQUES DE CÓDIGO (Permiten agrupar instrucciones)\n\nif True: # if: es una palabra reservada que indica que se encuentra una condiciónes verdadera\n    print(\"Hola Mundo\") # Bloque de código\n\nedad = 18\n\nif edad >= 18: \n    print(\"Eres mayor de edad\")\nelse: # else: es una palabra reservada que indica que se encuentra un bloque de código alternativo\n    print(\"Eres menor de edad\")\n\nfor i in range(3): # for: es una palabra reservada que indica que se encuentra un bucle\n    print(f\"Iteración {i}\") \n\ndef saludar():\n    print(\"¡Hola!\")\n    print(\"Bienvenido a Python\")\n\nsaludar()\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/LittleMabbit.py",
    "content": "# * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n# *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n\n## Operadores Aritméticos - Operadores utilizados para llevar acabo operaciones matemáticas\nmy_sum = 5 + 5 # 10 - Suma de dos numeros positivos\nprint(my_sum)\nmy_sub = 5 - 4 # 1 - Resta de dos numeros positivos.\nprint(my_sub)\nmy_mult = 2 * 2 # 4 - Multiplicacion de numeros positivos.\nprint(my_mult)\nmy_div = 10 / 2 # 5 - División de numeros positivos\nprint(my_div)\nmy_floor_div = 10 // 3 # 3 - Divisón cuyo restante redondea.\nprint(my_floor_div)\nmy_modulo = 10 % 7 # 3 - Modulo de una operación, es decir, el restante de una operación.\nprint(my_modulo)\nmy_power = 2 ** 8 # 256\nprint(my_power)\n\n\n## Operadores de Asignación - Operadores utilizados para asignar valores a variables.\na = 1 # Utilizando el '=' asignamos '1' a la variable 'a'.\nprint(a)\na += 1 # Utilizando el '+=' y asignando el valor de '1' a la variable 'a', tomamos el valor actual de la variable 'a' y le sumamos '1'. Luego actualizamos 'a' con el resultado.\nprint(a)\na -= 1 # Utilizando el '-=' y asignando el valor de '1' a la variable 'a', tomamos el valor actual de la variable 'a' y le restamos '1'. Luego actualizamos 'a' con el resultado.\nprint(a)\na *= 6 # Utilizando el '*=' y asignando el valor de '6' a la variable 'a', tomamos el valor actual de 'a' y lo multiplicamos por '6' luego actualizamos 'a' con el resultado.\nprint(a) # Para que este funcione, toca cambiar el valor inicial de la variable 'a' en la linea 22.\na /= 3 # Utilizando el '/=' y asignando el valor de '6' a la variable 'a', tomamos el valor actual de 'a' y lo dividimos entre '3', luego actualizamos 'a' con el resultado.\nprint(a) # Para que este funcione, toca cambiar el valor inicial de la variable 'a' en la linea 22.\na %= 6 # Utilizando el '%=' y asignando el valor de '6' a la variable 'a', tomamos el valor actual de 'a' y calculamos el restante de '6', luego actualizamos 'a' con el resultado.\nprint(a)\na **= 8 # Utilizando el '**=' y asignando el valor de '8' a la variable 'a', tomamos el valor actual de 'a' y elevamos al cuadrado '8' veces, luego actualizamos 'a' con el resultado.\nprint(a)\n\nb = 5\nc = 8\nb /= c\nprint(b)\n\n'''\nEn el ejemplo de encima, utilizamos la división para tomar el valor de B, y dividirlo entre C y actualizar el resultado de B.\n'''\n\n## Operadores de Comparación - Compara los resultados entre dos variables/valores y retorna un booleano True o False.\n'''\na = 5\nb = 2\n\nprint (a > b)    # True - is 'a' greater than 'b'? False\n'''\n\nseis = 6\ndiez = 10\n\nseis == diez # Igual a - Devuelve False, ya que seis es menos que diez, no es igual.\nseis != diez # Diferente a - Devuelve True, ya que seis es diferente a diez.\nseis > diez # Mayor a - Devuelve False, ya que seis no es mayor a diez.\nseis < diez # Menor a - Devuelve True, ya que seis es menor a diez.\nseis >= diez # Mayor o igual a - Devuelve False, ya que seis no es mayor ni tampoco es igual a diez.\nseis <= diez # Menor o igual a - Devuelve True, ya que seis es menor a diez, mas no igual.\n\n## Operadores lógicos - Operadores utilizados para saber si una operación es True o False.\n\na = 5\nb = 6\n\nprint((a > 2) and (b >= 6))    # True - Devuelve true ya que 'a' es mayor a '2', y 'b' es mayor o igual a '6'. Como ambos son True, devuelve True.\nprint((a > 2) or (b >= 6))    # True - Devuelve true ya que uno de los dos operandos es true.\nprint(not True)    # False - Es lo contrario a lo que se verifica con el not. En este caso, da False. Si escribiera False, entonces sería True.\n\n## Operadores en bits - Operadores utilizados para calcular en base a bits.\na = 5 # 0101\nb = 10 # 1010\n\n# Bitwise AND (&) retornará el valor de '1' cada vez que los bits en su posición correspondiente equivalgan a '1'.\nresult_and = a & b   # 0101 & 0011 = 0001 (1 en decimal)\nprint(\"Bitwise AND:\", result_and)\n\n# Bitwise OR (|) retornará el valor de '1' cada vez que uno de los los bits en su posición equivalga a '1', de resto si es 0, entonces devolverá 0.\nresult_or = a | b    # 0101 | 0011 = 0111 (7 en decimal)\nprint(\"Bitwise OR:\", result_or)\n\n# Bitwise XOR\nresult_xor = a ^ b   # 0101 ^ 0011 = 0110 (6 en decimal)\nprint(\"Bitwise XOR:\", result_xor)\n\n# Bitwise NOT (~) retornará el valor de los bits una vez estos sean flipeados y convertidos a decimales.\nresult_not_a = ~a   # 0101 -> 1010 -> 11010 -> 2^4 = -16 + 8 + 2 = 6. El 0101 equivale al 5, flipeado queda 1010, mas el sign bit quedaría en 11010, el primer bit se eleva a su posición (cuarta posición) osea 2^4, queda -16 (negativo por su signo) y luego los bits activos (8 y 2 por su valor elevado) se le suman al -16.\nprint(\"Bitwise NOT of a:\", result_not_a)\n\n# Left Shift\nresult_left_shift = a << 1   # 0101 << 1 = 1010 (10 in decimal)\nprint(\"Left Shift of a:\", result_left_shift)\n\n# Right Shift\nresult_right_shift = a >> 1  # 0101 >> 1 = 0010 (2 in decimal)\nprint(\"Right Shift of a:\", result_right_shift)\n\n\n## Operadores de identidad - Operadores utilizados para saber si dos valores estan localizados en el mismo lugar en la memoria física.\na1 = 5\nb1 = 5\na2 = 'Hola'\nb2 = 'Hola'\na3 = [1,2,3]\nb3 = [1,2,3]\n\nprint(a1 is not b1)  # prints False - a1 literalmente se almacena en el mismo lugar que b1, así que retorna False, ya que NO está lugares diferentes.\n\nprint(a2 is b2)  # prints True - a2 se encuentra en el mismo lugar en memoria que b1, con el mismo valor, así que retorna True ya que bueno, a2 literalmente está en b2.\n\nprint(a3 is b3)  # prints False - Esto sucede porque a pesar de que los valores son iguales, no son idénticos en memoria.\n\n## Operadores de membresía/pertenencia - Operadores utilizados para comprobar la validez de un valor en una sequencia.\nmessage = 'Hello world'\ndict1 = {1:'a', 2:'b'}\n\nprint('H' in message)  # Devuelve True - Revisará si el string con la letra 'H' está en la variable 'mensaje'.\nprint('hello' not in message)  # prints True - Revisará si el string 'hello' NO esta en mensaje, en este caso devuelve True, osea que realmente NO está en message.\nprint(1 in dict1)  # prints True - Revisará si la key '1' está presente en 'dict1', y como lo está, entonces devuelve True.\nprint('a' in dict1)  # prints False - Revisará si el string 'a' está en dict1, y como no lo está, entonces devuelve False.\n\n'''\n - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n'''\n\na = 5\nb = 10\n#Declaración de 'if's.\nif a < b:\n    print(f\"{a} es menor que {b}\")\nif b > a:\n    print(f\"{b} es menor que {a}\")\n\n# Declaración de 'else-if'\nif a > b:\n    print(f\"Esta es una declaración else-if. {a} es menor que {b}\")\nelse:\n    print(f\"Esta es la parte 'else' de un else-if. {a} es mayor que {b}\")\n\n# Declaración de elif\nif a > b:\n    print(f\"Esta es una declaración elif. {a} es menor que {b}\")\nelif a < b:\n    print(f\"Esta es la parte 'elif' de un else-if. {a} es mayor que {b}\")\nelse:\n    print(\"Está fuera del rango.\")\n   \n# Declaración del for loop\nnumbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n\nfor i in numbers:\n    print(i)\n\n# Declaración de un while\nx = 0\n\nwhile x < 10:\n    x += 1\n    print(\"Esto es un bucle while\", x)\n\n# Declaración de una excepción\nvalores = [10, 8, 5, 0, 2, 6, 7, 'Hi']\n\nfor valor in valores:\n    try:\n        print(10 / valor)\n    except ZeroDivisionError as e:\n        print(f\"Un error ha ocurrido: {e}\")\n    except TypeError as e:\n        print(f\"{e}. \\nPor favor, no uses texto en este campo.\")\n\n\ndef ejercicioExtra():\n    # Crear numeros entre 10 y 55\n    for i in range(10, 56):\n        # Si el módulo de i entre 2 da 0, y el indice i NO es igual a 16, y el módulo de i entre 3 no es igual a 0, entonces haz print.\n        if i % 2 == 0 and i != 16 and i % 3 != 0:\n            print(i)\n\n        \nejercicioExtra()"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/LordAguaKate.py",
    "content": "#Reto 01 OPERADORES Y ESTRUCTURAS DE CONTROL\n\n'''\nLos operadores aritmeticos permiten realizar operaciones numericas\nusando variables\n'''\n#Operadores Aritmeticos\nsuma = 3 + 3\nresta = 10 - 5\nmultiplicacion = 5 * 5\ndivision = 10 / 2        #Esta division se usa para decimales\nmodulo = 10 % 3\npotencia = 5 ** 2\ndivisionEntera = 10 // 2 #Esta division se usa para numeros enteros\n\n'''\nLos operadores de asignacion funcionan para asignar valor a una variable\n'''\n# Operadores de Asignacion\nvalor = 10 #Asignacion\nvalor += 2 #Suma\nvalor -= 3 #Resta\nvalor *= 2 #Multiplicacion\nvalor /= 2 #Division\nvalor %= 3 #Modulo\nvalor **= 2 #Potencia\nvalor //= 2 #Division entera\n\n#Operadores relacionales\nejem1 = 10\nejem2 = 5\nprint(ejem1 == ejem2) #Igualdad\nprint(ejem1 != ejem2) #Desigualdad\nprint(ejem1 < ejem2) #Menor que\nprint(ejem1 <= ejem2) #Menor igual que\nprint(ejem1 > ejem2) #Mayor que\nprint(ejem1 >= ejem2) #Mayor igual que\n\n'''\nLos operadores logicos se usan en combinacion con los operadores de \ncomparacion cuando la expresion de la condicion lo requiere\n'''\n#Operadores logicos\nx = 10\ny = 5\n\nprint(x > 5 and y < 5)\nprint(x > 5 or y < 5)\nprint(not y == 5)\n\n'''\nLas estructuras de control son muy fundamentales para la ejecuccion de un codigo, permitiendo \nla ejecuccion continua de codigo hasta cumplir con la condicional\n'''\n\n'''\nEl uso de if, elif, else. se basa en si es verdadero o falso\n'''\n#Uso de if, elif, else.\ndinero = 100\n\nif dinero >= 100:\n    print(\"Gasta lo que quieras\")\nelif dinero >= 50:\n    print(\"No gastes mucho\")\nelse:\n    print(\"No gastes nada mejor\")\n\n#Bucle for\nfor i in range(10):\n    print(\"Bucles\", i)\n\n#Ciclo while\nnumeros = 0\nwhile numeros <= 10:\n    print(numeros)\n    numeros += 1\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/LucasRebuffo.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */ \"\"\"\n\n##Operadores aritmeticos\nprint(f\"Suma 100 + 50 :{100+50}\")\nprint(f\"Resta 100 - 50 :{100-50}\")\nprint(f\"Multiplicacion 100 * 50 :{100*50}\")\nprint(f\"Division 100 / 50 :{100/50}\")\nprint(f\"Modulo 100 % 50 :{100 % 50}\")\nprint(f\"Potencia 2 ** 50 :{2**50}\")\nprint(f\"Division entera 2 // 50 :{6**50}\")\n\n## Operadores de comparacion\nprint(f\"Igual 6 == 6 :{6==6}\")\nprint(f\"No igual 6 != :{6!=6}\")\nprint(f\"Mayor 2 > 50 :{6>50}\")\nprint(f\"Menor entera 2 < 50 :{6<50}\")\nprint(f\"Menor o igual entera 2 <= 50 :{6<=50}\")\nprint(f\"Mayor o igual entera 2 >= 50 :{6>=50}\")\nprint(f\"Division entera 2 // 50 :{6**50}\")\n\n##Operadores logicos\nprint(f\"AND True and True :{4+4 == 8 and 6 == 5+1}\")\nprint(f\"OR True or False :{4+4 == 8 or 6 == 5}\")\nprint(f\"NOT False :{not 6 == 9*3}\")\n\n## Operadores de asignacion\nnum = 4\nprint(num)\nnum += 1\nprint(num)\nnum -= 1\nprint(num)\nnum *= 2\nprint(num)\nnum /= 3\nprint(num)\nnum %= 2\nprint(num)\nnum **= 2\nprint(num)\nnum //= 4\nprint(num)\n\n## Operadores de identidad\nmy_var = 0.0\nprint(f\"my_var is my_other_var {my_var is num}\")\nprint(f\"my_var is not my_other_var {my_var is not num}\")\n\n## Operadores de pertenencia\nprint(f\"'u' in 'lucas' = {'u' in 'lucas'}\")\nprint(f\"'v' not in 'lucas' = {'u' not in 'lucas'}\")\n\n\n## Operadores de bit\na = 8  # 1000\nb = 9  # 1001\nprint(f\"AND : 8 & 9: {a & b}\")\nprint(f\"OR : 8 | 9: {a | b}\")\nprint(f\"XOR : 8 ^ 9: {a ^ b}\")\nprint(f\"NOT : ~8: {~a}\")\nprint(f\"RShift : 8 >> 2: {a >> 2}\")\nprint(f\"LShift : 8 << 2: {a << 2}\")\n\n## Estructuras de control\n\n## Condicionales\nvar = \"lucas\"\nif var == \"alberto\":\n    print(\"Condicional\")\nelif var != \"lucas\":\n    print(\"elif\")\nelse:\n    print(\"else\")\n\n##Iterativas\nfor num in range(11):\n    print(num)\n\nnumer = 20\nwhile numer > 0:\n    print(numer)\n    numer -= 1\n\n## Excepciones\ntry:\n    10 / 0\nexcept:\n    raise (ZeroDivisionError)\nfinally:\n    print(\"Finalizado exitosamente\")\n\n\n## Extra\nfor num in range(10, 56):\n    if (not (num == 16 or num % 3 == 0)) and num % 2 == 0:\n        print(num)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/LuisK0706.py",
    "content": "# Operadores aritmeticos (+, -, *, /)\n\n# Operador + se utiliza para realizar sumas\nmi_suma = 4 + 7 \n# Operador - se utiliza para realizar restas\nmi_resta = 10 - 6 \n# Operador * se utiliza para realizar multiplicaciones \nmi_multiplicacion = 5 * 9 \n# Operador / se utiliza para realizar divisiones\nmi_division = 9 / 3 \n# Operador // se utiliza para realizar una division entera\nmi_division_entera = 10 // 3\n# Operador % se utiliza para obtener el residuo de una division\nmi_residuo = 3 % 2\n# Operador ** se utiliza para realizar potencias\nmi_potencia = 2**2\n\n#Impresion de los resultados\nprint(\"Operadores aritmeticos \\n\"\n      \"---------------------------\\n\"\n      f\"Suma: {mi_suma}\\n\"\n      f\"Resta: {mi_resta}\\n\"\n      f\"Multiplicacion: {mi_multiplicacion}\\n\"\n      f\"Division: {mi_division}\\n\"\n      f\"Division entera: {mi_division_entera}\\n\"\n      f\"Residuo: {mi_residuo}\\n\"\n      f\"Potencia: {mi_potencia}\\n\")\n\n\n# Operadores logicos (and, or, not)\n\n# El operador and devolvera True si ambas condiciones se cumplen\nusando_and = 5 < 3 and 10 > 5\n# El operador or devolvera True si una de las dos condiciones se cumple\nusando_or = 5 < 3 or 10 > 5\n# El operador not devolvera False si su operando es True y True si es False\nusando_not = True\n\n#Impresion de los resultados\nprint(\"Operadores logicos \\n\"\n      \"---------------------------\\n\"\n      f\"Operador and: {usando_and}\\n\"\n      f\"Operador or: {usando_or}\\n\"\n      f\"Operador not: {not(usando_not)}\\n\")\n\n\n# Operadores de comparacion (<, >, ==, !=)\n\n# Operador < se utiliza para varificar si un elemento es menor a otro\nusando_menorque = 3 < 5\n# Operador > se utiliza para verificar si un elemento es mayor a otro\nusando_mayorque = 3 > 5\n# Operador == devuelve True si son iguales\nusando_igual = 8 == 5\n# Operador != devueve True si son diferentes\nusando_no_es_igual = 8 != 5\n# Operador <= devuelve True si el elemento es menor o igual al otro\nusando_menor_o_igual = 8 <= 8\n# Operador >= devuelve True si el elemento es mayor o igual al otro\nusando_mayor_o_igual = 8 >= 9\n\n\n#Impresion de los resultados\nprint(\"Operadores de comparación \\n\"\n      \"----------------------------\\n\"\n      f\"Operador <: {usando_menorque}\\n\"\n      f\"Operador >: {usando_mayorque}\\n\"\n      f\"Operador ==: {usando_igual}\\n\"\n      f\"Operador !=: {usando_no_es_igual}\\n\"\n      f\"Operador <=: {usando_menor_o_igual}\\n\"\n      f\"Operador >=: {usando_mayor_o_igual}\\n\")\n\n\n\n# Operadores de asignacion (=, +=, -=, *=, /=, //=, %=, **=)\nmi_variable = 10\nprint(\"Operadores de asignacion\\n\"\n      \"---------------------------\\n\")\n# Asignacion simple se realiza solo con el signo = dandole algun valor a una vaiable\nasignacion_simple = 'Mi asignacion simple'\n# Asignacion con una suma += lo que hace es a la misma variable le suma el numero asignado\nmi_variable += 5 \nprint(f\"Suma: {mi_variable}\")\n# Funciona igual con los demas operadores aritmeticos\nmi_variable -= 5\nprint(f\"Resta: {mi_variable}\")\nmi_variable *= 5\nprint(f\"Multiplicacion: {mi_variable}\")\nmi_variable //= 3\nprint(f\"Division entera: {mi_variable}\")\nmi_variable %= 5\nprint(f\"Residuo: {mi_variable}\")\nmi_variable **= 5\nprint(f\"Potencia: {mi_variable}\")\nmi_variable /= 5\nprint(f\"Division: {mi_variable}\\n\")\n\n\n\n# Operadores de identidad (is, is not)\n\n# Operador is devuelve True si es correcto\nusando_is = usando_mayorque is True\n# Operador not is devuelve True si es correcto\nusando_is_not = not usando_mayorque is True\n\n# Impresion de resultados\nprint(\"Operadores de identidad\\n\"\n      \"---------------------------------\\n\"\n      f\"Operador is: {usando_is}\\n\"\n      f\"Operador is not: {usando_is_not}\\n\")\n\n\n# Operadores de pertenencia (in, not in)\n\nmi_lista = [5, 4, 3, 2, 1]\n\n# Operador in devuelve True si encuentra el dato buscado\nusando_in = 5 in mi_lista\n# Operador not in devuelve True si no encuentra el dato buscado\nusando_not_in = 5 not in mi_lista\n\nprint(\"Operadores de pertenencia\\n\"\n      \"-----------------------------\\n\"\n      f\"Operador in: {usando_in}\\n\"\n      f\"Operador not in: {usando_not_in}\\n\")\n\n\n\n# Operadores de bits (&, |, <<, >>)\n\nx = 0b101\ny = 0b1000\n# Desplazamiento a la izquierda << desplaza el numero de bits a la izquierda de la variable asignada\nizquierda = x << 2\n# Desplzamiento a la derecha >> desplaza el numero de bits a la derecha de la variable asignada\nderecha = y >>2\n# Operador & operacion and entre dos numeros binarios\nusando_and_bits = x & y\n# Operador | operacion or entre dos numeros binarios\nusando_or_bits = x | y\n\n# Impresion de resultados\nprint(\"Operadores de bits\\n\"\n      \"-------------------------\\n\"\n      f\"Desplazamiento de bits a la izquierda: {izquierda}\\n\"\n      f\"Desplazamiento de bits a la derecha: {derecha}\\n\"\n      f\"Operador and en bits: {usando_and_bits}\\n\"\n      f\"Operador or en bits: {usando_or_bits}\\n\")\n\n\n# Estructuras de control \n\n# Condicionales\n\n# Estructura (if, elif, else)\n\n# El if se utiliza para hacer algo si se cumple una condicion\nprint(\"Usando if\\n\"\n      \"-------------------------\\n\")\nif mi_suma > mi_resta: \n    print(f\"{mi_suma} es mayor que {mi_resta}\\n\")\n# El elif se utiliza en caso de no cumplirse la primera condicion se agrega una condicion extra\nelif mi_suma < mi_resta:\n    print(f\"{mi_resta} es mayor que {mi_suma}\\n\")\n# El else es una ultima accion en caso de no cumplirse ninguna de las condiciones\nelse:\n    print(\"son iguales\\n\")\n\n\n# Iterativas (for, while)\n\n# El ciclo for imprime datos segun el rango asignado o las condiciones aplicadas\n\nprint(\"Ciclo for\\n\"\n      \"-------------------------\")\nfor i in range(1, 5):\n    print(i)\n\n# El ciclo while imprime datos mientras se sigue cumpliendo la condicion\ncontador = 0\n\nprint(\"Ciclo while\\n\"\n      \"-------------------------\")\nwhile(contador < 10):\n    print(contador)\n    contador += 1\n\n\n# Excepciones\n\ntry:\n    numero = int(input(\"Ingrese un numero: \"))\n    resultado = 10 / numero\n    print(f\"Resultado: {resultado}\")\n\n# Retorna algunos mensajes de error para casos no validos\nexcept ZeroDivisionError:\n    print(\"No se puede dividir entre 0\")\n\n# Ejercicio extra\n\"\"\" Crea un programa que imprima por consola todos los números comprendidos\n  entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\"\"\"\n\nfor i in range(10, 56):\n    if i == 16 or i % 3 == 0:\n        pass\n    elif i % 2 == 0 or i == 55:\n        print(i)\n    else:\n        pass\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/LuisOlivaresJ.py",
    "content": "\"\"\"\n\nFor this exercise I am going to follow this guide:\nhttps://realpython.com/python-operators-expressions/\n\n\"\"\"\n\n'''\n* - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n'''\n\n# Assignment Operator\nmy_var = 1\n\n\n# Arithmetic Operators\n1 + my_var  # Suma aritmetica\n1 - my_var  # Resta\n1 * my_var  # Multiplicación\n1 / my_var  # División\n1 % my_var  # El residuo al dividir 1 y my_var\n1 // my_var  # La divisón de 1 y my_var, redondeando al menor entero.\n1 ** my_var  # Potencia de 1 elevado a my_var\n\n\n# Comparison Operators\n\na = 2  # Seting up some test values\nb = 5\n\na == b  # Igual a\na != b  # No igual a\na < b  # a menor que b\na <= b  # a menor o igual que b\na > b  # a mayor que b\na >= b # a mayor o igual que b\n\n\n# Boolean Operators\na = True\nb = False\n\na and b  # returns b\na or b  # returns a\nnot a  # returns False\n\n\n# Identity Operators.\n    # Allow you to determine whether two operands have the same identity\n\nx = 500\ny = 500\n\nx is y  # returns Flase\nx is not y  # returns True\n\n\n# Membership Operators.\n    # To determine whether a value is present in a container data type, \n    # such as a list, tuple, or set\n\n5 in [2, 3, 5, 9, 7]  # returns True\n8 in [2, 3, 5, 9, 7]  # returns False\n\n\n# Concatenation and Repetition Operators\n\"Hello, \" + \"World!\"  # returns \"Hello, World!\"\n\"Hello\" * 3  # returns \"HelloHelloHello\"\n\n\n# Walrus Operator :=\ndef validate_length(string):\n    if (n:= len(string)) < 8:\n        print(f\"Length {n} is too short, needs at least 8.\")\n    else:\n        print(f\"Length {n} is okay!\")\n\n\n# Bitwise Operators\n    # Bitwise operators treat operands as sequences of binary \n    # digits and operate on them bit by bit \n        \n# Bitwise AND\n#   0b1100    12\n# & 0b1010    10\n# --------\n# = 0b1000     8\nbin(0b1100 & 0b1010)\n#'0b1000'\n12 & 10\n#8\n\n\n'''\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n'''\n\n# Estructuras de control: if, elif, for \n\na = 5\nb = 10\n\nif a < b:\n    print(\"a is smaller\")\nelif b < a:\n    print(\"b is smaller\")\nelse:\n    print(\"a is equal b\")\n\na=0\nwhile a < 10:\n    print(a)\n    a += 1\n\ntry:\n    \"hola\" / 5\n\nexcept TypeError:\n    print(\"Both arguments must be numbers.\")\n\n'''\n    * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n '''\n\nfor i in range(10, 56):\n    if (i % 2) == 0:\n        if i != 16:\n            if (i % 3) != 0:\n                print(i)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Lumanet.py",
    "content": "a = 7\nb = 3\n# Aritméticos\nprint(f\"Suma: {a} + {b} = {a + b}\")\nprint(f\"Resta: {a} - {b} = {a - b}\")\nprint(f\"Multiplicación: {a} * {b} = {a * b}\")\nprint(f\"División: {a} / {b} = {a / b}\")\nprint(f\"Módulo: {a} % {b} = {a % b}\")\nprint(f\"Exponente: {a} ** {b} = {a ** b}\")\nprint(f\"División entera: {a} // {b} = {a // b}\")\n\n# De comparación\nprint(f\"Igualdad: {a} == {b} es {a == b}\")\nprint(f\"Desigualdad: {a} != {b} es {a != b}\")\nprint(f\"Mayor que: {a} > {b} es {a > b}\")\nprint(f\"Menor que: {a} < {b} es {a < b}\")\nprint(f\"Mayor o igual que: {a} >= {a} es {a >= a}\")\nprint(f\"Menor o igual que: {a} <= {b} es {a <= b}\")\n\n# Lógicos\nprint(f\"AND &&: {a} + {b} == {a + b} and 5 - 1 == 4 es {a + b == 10 and 5 - 1 == 4}\")\nprint(f\"OR ||: {a} + {b} == {a + b} or 5 - 1 == 4 es {a + b == {a + b} or 5 - 1 == 4}\")\nprint(f\"NOT !: not {a} + {b} == 14 es {not a + b == 14}\")\n\n# De asignación\nmi_numero = 7  # asignación\nprint(mi_numero)\nmi_numero += 1  # suma y asignación\nprint(mi_numero)\nmi_numero -= 1  # resta y asignación\nprint(mi_numero)\nmi_numero *= 3  # multiplicación y asignación\nprint(mi_numero)\nmi_numero /= 3  # división y asignación\nprint(mi_numero)\nmi_numero %= 2  # módulo y asignación\nprint(mi_numero)\nmi_numero **= 1  # exponente y asignación\nprint(mi_numero)\nmi_numero //= 1  # división entera y asignación\nprint(mi_numero)\n\n# De identidad\notro_numero = mi_numero\nprint(f\"mi_numero is otro_numero es {mi_numero is otro_numero}\")\nprint(f\"mi_numero is not otro_numero es {mi_numero is not otro_numero}\")\n\n# De pertenencia\nprint(f\"'a' in 'lumanet' = {'a' in 'lumanet'}\")\nprint(f\"'s' not in 'lumanet' = {'s' not in 'lumanet'}\")\n\n# De bit\na = 7  # 0111\nb = 5  # 0101\nprint(f\"AND: {a} & {b} = {a & b}\")  # 0101 -> 5\nprint(f\"OR: {a} | {b} = {a | b}\")  # 0111 -> 7\nprint(f\"XOR: {a} ^ {b} = {a ^ b}\")  # 0010 -> 2\nprint(f\"NOT: ~{a} = {~a}\") # 1000 -> -8\nprint(f\"Desplazamiento a la derecha: {a} >> 2 = {a >> 2}\")  # 0001 -> 1\nprint(f\"Desplazamiento a la izquierda: {a} << 2 = {a << 2}\")  # 11100 -> 28\n\n\"\"\"\nEstructuras de control\n\"\"\"\n\n# Condicionales\n\ncadena = \"Marcos\"\n\nif cadena == \"lumanet\":\n    print(\"cadena es 'lumanet'\")\nelif cadena == \"Marcos\":\n    print(\"cadena es 'Marcos'\")\nelse:\n    print(\"cadena no es 'lumanet' ni 'Marcos'\")\n\n# Iterativas\n\nfor i in range(11):\n    print(i)\n\ni = 0\n\nwhile i <= 10:\n    print(i)\n    i += 1\n\n# Manejo de excepciones\ntry:\n    print(10 / 0)\nexcept:\n    print(\"No se puede dividir por 0.\")\nfinally:\n    print(\"Proceso terminado.\")\n    \n\"\"\"\n Crea un programa que imprima por consola todos los números comprendidos\n entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\"\"\"\n\nfor i in range(10, 56):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Maanghel.py",
    "content": "\"\"\"\nEJERCICIO:\n- Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n    Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n    (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n- Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n    que representen todos los tipos de estructuras de control que existan\n    en tu lenguaje:\n    Condicionales, iterativas, excepciones...\n- Debes hacer print por consola del resultado de todos los ejemplos.\n\nDIFICULTAD EXTRA (opcional):\nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\nSeguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\"\"\"\n\n# Operadores Aritméticos\nprint(\"Operadores Aritméticos: +, -, *, /, //, %, **\")\nprint(f\"\\nLa suma de 5 + 4 es {5 + 4} \") # Suma\nprint(f\"La resta de 5 - 4 es {5 - 4} \") # Resta\nprint(f\"La multiplicación de 5 * 4 es {5 * 4} \") # Multiplicacion\nprint(f\"La división de 5 / 4 es {5 / 4} \") # Division\nprint(f\"La división entera de 5 // 4 es {5 // 4} \") # Division Entera\nprint(f\"El módulo de 5 % 4 es {5 % 4} \") # Modulo\nprint(f\"La exponenciación de 5 ** 4 es {5 ** 4} \") # Exponenciacion\nprint(\"-\" * 50)\n\n# Operadores de Comparación\nprint(\"\\nOperadores de Comparación: ==, !=, >, <, >=, <=\")\nprint(f\"\\nEl resultado de 5 == 5 es {5 == 5}\") # Igual a\nprint(f\"El resultado de 5 != 5 es {5 != 5}\") # Distinto a\nprint(f\"El resultado de 5 > 4 es {5 > 5}\") # Mayor que\nprint(f\"El resultado de 5 < 6 es {5 < 5}\") # Menor que\nprint(f\"El resultado de 5 >= 7 es {5 >= 5}\") # Mayor o igual que\nprint(f\"El resultado de 5 <= 5 es {5 <= 5}\") # Menor o igual que\nprint(\"-\" * 50)\n\n# Operadores Lógicos\nprint(\"\\nOperadores Lógicos: and, or, not\")\nprint(f\"Operador And/&&: {True and True}\") # And: Retorna True si ambas condiciones son verdaderas\nprint(f\"Operador Or/||: {False or True}\") # Or: Retorna True si al menos una de las condiciones es verdadera\nprint(f\"Operador Not/!: {not True}\") # Not: Invierte el valor de la condicion (si es True se convierte en False, y viceversa)\nprint(\"-\" * 50)\n\n# Operadores de Asignación\nprint(\"\\nOperadores de Asignación: =, +=, -=, *=, /=, //=, **=, %=\")\nnumero1 = 1 # Asignacion\nprint(f\"\\nEl resultado de declarar una variable y asignarle un 1 es {numero1}\")\nnumero1 += 2 # Suma y Asignacion\nprint(f\"El resultado de sumar 2 y asignarlo a la variable es {numero1}\")\nnumero1 -= 1 # Menos y Asignacion\nprint(f\"El resultado de restar 1 y asignarlo a la variable es {numero1}\")\nnumero1 *= 4 # Multiplicacion y Asignacion\nprint(f\"El resultado de multiplicar por 4 y asignarlo a la variable es {1}\")\nnumero1 /= 2 # Division y Asignacion\nprint(f\"El resultado de dividir con 2 y asignarlo a la variable es {numero1}\")\nnumero1 //= 2 # Division entera y Asignacion\nprint(f\"El resultado de realizar una division entera con 2 y asignarlo a la variable es {numero1}\")\nnumero1 **= 3 # Exponenciacion y Asignacion\nprint(f\"El resultado de exponenciar por 3 y asignarlo a la variable es {numero1}\")\nnumero1 %= 5 # Modulo y Asignacion\nprint(f\"El resultado de modulo con 5 y asignarlo a la variable es {numero1}\")\nprint(\"-\" * 50)\n\n# Operadores de Identidad\nprint(\"\\nOperadores de Identidad: is, is not\")\nnumero2 = numero1\nprint(f\"\\nnumero1 = {numero1}\\nnumero2 = {numero2}\")\nprint(f\"¿Las variables numero1 y numero2 hacen referencia al mismo objeto?: {numero1 is numero2}\") # is: Comprueba si dos variables hacen referencia al mismo objeto\nprint(f\"¿Las variables numero1 y numero2 no hacen referencia al mismo objeto?: {numero1 is not numero2}\") # is not: Comprueba si dos variables no hacen referencia al mismo objeto\nprint(\"-\" * 50)\n\n# Operadores de Pertenencia/membresía\nprint(\"\\nOperadores de Pertenencia: in, not in\")\nlista = [1, 2, 3]\nprint(f\"\\nLista: {lista}\")\nprint(f\"¿El numero 2 esta en la lista? {2 in lista}\") # in: Verifica si un elemento esta contenido dentro de una secuencia, como podria ser una lista\nprint(f\"¿El numero 4 esta en la lista? {4 not in lista}\") # not in: Verifica que un elemento no este contenido en una secuencia\nprint(\"-\" * 50)\n\n# Operadores de Bit a Bit/Bitwise\nprint(\"\\nOperadores de Bit a Bit: &, |, ^, ~, <<, >>\")\nbit1 = 4 # 0100\nbit2 = 2 # 0010\nprint(f\"\\nAND: 4(0100) & 2(0010) es igual a {bit1 & bit2}({bin(bit1 & bit2)})\")\nprint(f\"OR: 4 | 2 es igual a {bit1 | bit2}({bin(bit1 | bit2)})\")\nprint(f\"XOR: 4 ^ 2 es igual a {bit1 ^ bit2}({bin(bit1 ^ bit2)})\")\nprint(f\"NOT: ~4 es igual a {~bit1}({bin(~bit1)})\")\nprint(f\"Desplazamiento derecha: 4 >> 2 es igual a {bit1 >> bit2}({bin(bit1 >> bit2)})\")\nprint(f\"Desplazamiento izquierdo: 4 << 2 es igual a {bit1 << bit2}({bin(bit1 << bit2)})\")\nprint(\"-\" * 50)\n\n# Estructuras de Control\n\n# Estructuras de Control Condicional: if, elif, else\nx = 10\nif x > 0:\n    print(\"\\nEs positivo\")\nelif x == 0:\n    print(\"\\nEs cero\")\nelse:\n    print(\"\\nEs negativo\")\nprint(\"-\" * 50)\n\n# Estructuras de Control Bucles: while, for\ncontador = 1\nwhile contador <= 5:\n    print(contador)\n    contador += 1\nprint(\"-\" * 50)\n\nfor numero in range(11):\n    print(numero, end= \"-\")\nprint()\nprint(\"-\" * 50)\n\n# Estructuras de Control de Flujo: break, continue, pass\nfor i in range(10):\n    if i == 3:\n        continue # Salta a la siguiente iteracion\n    if i == 7:\n        break # finaliza el for\n    print(i)\nprint(\"-\" * 50)\n\n# Estructuras de Control de Excepciones: try, except, finally\ntry: \n    x = 10 / 0\nexcept ZeroDivisionError: # Se ejecuta si se produce un error tipo ZeroDivisionError\n    print(\"No se puede dividir entre cero\")\nfinally: # Siempre se ejecuta\n    print(\"Finalizo la operación\")\nprint(\"-\" * 50)\n\n# EXTRA\nprint(\"\\nSe imprimiran los numeros del 10 al 55(pares incluidos), excepto los multiplos de 3 o el numero 16:\")\nprint([x for x in range(10, 56) if x % 3 != 0 and x != 16 and x % 2 == 0])\nprint(\"-\" * 50)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/MarcosE-FerretoE.py",
    "content": "# Operadores aritméticos\nsuma = 24 + 24\nresta = 25 - 1\nmultiplicacion = 4 * 6\ndivision = 48 / 2\npotencia = 2 ** 3.585\nmod = 48 % 24\n\n# Operadores lógicos\nresultado_and = (24 + 6 == 30) and (10 - 6 == 4)\nresultado_or = (16 + 4 == 20) or (25 - 5 == 30)\nresultado_not = not (24 - 4 == 10)\n\n# Operadores de comparación\nigual_a = (24 == 24)\nno_igual_a = (24 != 42)\nmayor_que = (42 > 24)\nmenor_que = (24 < 50)\nmayor_o_igual_que = (14 >= 14)\nmenor_o_igual_que = (4 <= 5)\n\n# Operadores de asignación\nmi_variable = 5\nmi_variable += 2\nmi_variable -= 3\nmi_variable *= 5\nmi_variable /= 2\nmi_variable %= 5\n\n# Operadores de identidad\nmi_lista1 = [1, 2, 3]\nmi_lista2 = [1, 2, 3]\nresultado_listas = mi_lista1 is mi_lista2\n\nmi_lista3 = [3, 2, 1]\nmi_lista4 = [3, 2, 1]\nresultado_listas2 = mi_lista3 is not mi_lista4\n\n# Operadores de pertenencia\nmi_lista = [1, 2, 3, 4, 5]\nresultado_lista = 3 in mi_lista\n\nmis_lenguajes = ['Python', 'Java', 'C']\nresultado_lenguaje = 'Kotlin' not in mis_lenguajes\n\n# Operadores de bits\nresultado_and_bits = 5 & 3\nresultado_or_bits = 5 | 3\nresultado_xor_bits = 5 ^ 3\nresultado_shift_left = 5 << 1\nresultado_shift_right = 5 >> 1\n\n# Condicionales\n\nnumero = 20\n\nif numero > 0:\n    print(\"El número es positivo\")\nelif numero == 0:\n    print(\"El número es cero\")\nelse:\n    print(\"El número es negativo\")\n\n# Iterativas\n\ncontador = 0\n\nwhile contador <= 100:\n    print(contador)\n    contador += 1\n\nfor i in range(0, 100, 2):\n    print(i)\n\n# Excepciones\ntry:\n    print(10 / 1)\nexcept:\n    print(\"Hay un error\")\nfinally:\n    print(\"Fin del manejo de excepciones\")    \n\n#Extra\n\nfor i in range(10,56, ):\n    if i % 2 == 0 and i != 16 and 1 % 3 != 0:\n        print(i)\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/MarkTwin25.py",
    "content": "def extra(inicio, fin):\r\n    for i in range(inicio, fin+1):\r\n        num = f\"{i}\"\r\n        if i != 16 and i % 3 != 0:\r\n            num += \" (no es ni 16 ni multiplo de 3)\"\r\n        if i % 2 == 0:\r\n            num += \" (par)\"\r\n        print(num)\r\n\r\nextra(10,55)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/MartaProg.py",
    "content": "a = 666\nb = 66\n\n#Operadores Aritméticos. \nprint(\"----- Operadores Aritméticos -----\")\n\nprint(f\"Suma: 666 + 66 = {a + b}\")\nprint(f\"Resta: 666 - 66 = {a - b}\")\nprint(f\"Multiplicacíon: 666 * 66 = {a * b}\")\nprint(f\"División: 666 / 66 = {a / b}\")\nprint(f\"Módulo: 666 % 66 = {a % b}\")\nprint(f\"Potencia: 666 ** 66 = {a ** b}\")\nprint(f\"División entera: 666 // 66 = {a // b}\")\n\n#Operadores de comparación.\nprint(\"----- Operadores de comparación -----\")\nprint(f\"Mayor que: 666 > 66 --> {a > b}\")\nprint(f\"Menor que: 666 < 66 --> {a < b}\")\nprint(f\"Igual a: 666 == 66 --> {a ==b}\")\nprint(f\"Mayor o igual: 666 >= 66 --> {a >= b}\")\nprint(f\"Menor o igual: 666 <= 66 --> {a <= b}\")\nprint(f\"Diferente a: 666 != 66 --> {a != b}\")\n\n#Operadores Bit a Bit\n\nprint(\"----- Operadores Bit a Bit -----\")\nprint(f\"AND: 666 & 66 --> {a & b}\")\nprint(f\"OR: 666 | 66 --> {a | b}\")\nprint(f\"XOR: 666 ^ 66 --> {a ^ b}\")\nprint(f\"NOT: ~666 --> {~a}\")\nprint(f\"Desplazamiento izquierda: 666 << 2 --> {a << 2}\")\nprint(f\"Desplazamiento derecha: 666 >> 2 --> {a >> 2}\")\n\n#Operadores de asignación\nprint(\"----- Operadores de asignación -----\")\n\nx = a\nx += b\nprint(f\"{a} += {b} = {x}\")\n\nx = a\nx -= b\nprint(f\"{a} -= {b} = {x}\")\n\nx = a\nx *= b\nprint(f\"{a} *= {b} = {x}\")\n\nx = a\nx /= b\nprint(f\"{a} /= {b} = {x}\")\n\nx = a\nx %= b\nprint(f\"{a} %= {b} = {x}\")\n\nx = a\nx //= b\nprint(f\"{a} //= {b} = {x}\")\n\nx = a\nx **= b\nprint(f\"{a} **= {b} = {x}\")\n\n#Operadores Logicos\nprint(\"----- Operadores Lógicos -----\")\n\nprint(f\"({a} > {b}) and ({b} < 100) = {(a > b) and (b < 100)}\")\nprint(f\"({a} < {b}) or ({b} == 66) = {(a < b) or (b == 66)}\")\nprint(f\"not ({a} == {b}) = {not (a == b)}\")\n\n\n#Tipos de estructuras de control\n#Condicionales\nif a > b: \n    print(f\"{a} es mayor a {b}\")\nelif a == b:\n    print(f\"{a} es igual a {b}\")\nelse:\n    print(f\"{a} es menor a {b}\")\n\n#Iteratividad\n#While\ncontador = 0\nwhile contador < 5:\n    print(contador)\n    contador += 1\n    \n#For\nfor n in range(1,6):\n    print(n)\n    \n#Control de flujo\n#Break\nfor i in range(10):\n    if i == 5:\n        break\n    print(i)\n\n#Continue\nfor i in range(b): \n    if i == 1: \n        continue\n    print(f\"i = {i}\")\n    \n#Pass\nfor i in range(5): \n    if i == 3:\n        pass\n    print(f\"i = {i}\")\n    \n#Control de excepciones\ntry:\n    x = int(\"abc\")\nexcept ValueError:\n    print(\"¡Eso no es un número!\")\n\n#Opcional \nfor i in range(10,56): \n    if i % 2 == 0 and i != 16 and i % 3 == 0:   #Tabla del  6?\n        print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/MartinZeta.py",
    "content": "\n\"\"\"\n\n# #01 OPERADORES Y ESTRUCTURAS DE CONTROL\n> #### Dificultad: Fácil | Publicación: 02/01/24 | Corrección: 08/01/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n\n\"\"\"\n\n\"\"\"\nOPERADORES\n\"\"\"\n\n#Operadores aritmeticos \nprint(f\"Suma: 24 + 6 = {24 + 6}\")\nprint(f\"Resta: 24 - 6 = {24 - 6}\")\nprint(f\"Multiplicacion: 24 * 6 = {24 * 6}\")\nprint(f\"Division: 24 / 6 = {24 / 6}\")\nprint(f\"Division Entera: 24 // 6 = {24 // 6}\")\nprint(f\"Resto: 24 % 6 = {24 % 6}\")\nprint(f\"Exponente: 24 ** 6 = {24 ** 6}\")\n\n#Operadores de comparacion\nprint(f\"Mayor: 24 > 6 = {24 > 6}\")\nprint(f\"Menor: 24 < 6 = {24 < 6}\")\nprint(f\"Mayor o igual: 24 >= 6 = {24 >= 6}\")\nprint(f\"Menor o igual: 24 <= 6 = {24 <= 6}\")\nprint(f\"Igual: 24 == 6 = {24 == 6}\")\nprint(f\"Diferente: 24 != 6 = {24 != 6}\")\n\n#Operadores logicos     \nprint(f\"AND: 10 + 3 == 13 and 3 + 2 == 5 = {10 + 3 == 13 and 3 + 2 == 5}\") #Si ambos true, devuelve true\nprint(f\"OR: 10 + 3 == 13 or 3 + 2 == 5 = {10 + 3 == 14 or 3 + 2 == 6}\") #Si alguno true, devuelve true\nprint(f\"NOT: not 10 + 3 == 14 = {not 10 + 3 == 13}\") #Si alguno true, devuelve false\n\n#Operadores de asignacion\n\nmy_number = 10 #asignacion\nprint(f\"my_number = 10 = {my_number}\")\nmy_number += 10 #suma y asignacion\nprint(f\"my_number += 10 = {my_number}\")\nmy_number -= 10 #resta y asignacion\nprint(f\"my_number -= 10 = {my_number}\")\nmy_number *= 10 #multiplicacion y asignacion\nprint(f\"my_number *= 10 = {my_number}\")\nmy_number /= 10 #division y asignacion\nprint(f\"my_number /= 10 = {my_number}\")\nmy_number %= 10 #modulo y asignacion\nprint(f\"my_number %= 10 = {my_number}\")\n\n#Operadores de identidad: is y is not es un operador de comparacion que se utiliza para comprobar si dos variables son la misma o no\nmy_new_number = my_number\nprint(f\"my_number is my_new_number es {my_number is my_new_number}\")\nmy_new_number = 1.0\nprint(f\"my_number is my_new_number es {my_number is my_new_number}\")\nprint(f\"my_number is not my_new_number es {my_number is not my_new_number}\")\n\n#Operadores de pertenencia: in y not in es un operador de comparacion que se utiliza para comprobar si un elemento esta en una secuencia\nprint(f\"'m' in 'martin' = {'m' in 'martin'}\")\nprint(f\"'m' not in 'martin' = {'m' not in 'martin'}\")\n\n#Operadores de bit \na = 10 # 1010\nb = 3 # 0011\n\nprint(f\"AND: a & b = {a & b}\") # 0010\nprint(f\"OR: a | b = {a | b}\") # 1011 \nprint(f\"XOR: a ^ b = {a ^ b}\") # 1001 \nprint(f\"NOT: ~a = {~a}\") # -11\nprint(f\"DESPLAZAMIENTO A LA IZQUIERDA: a << 2 = {a << 2}\") # 40\nprint(f\"DESPLAZAMIENTO A LA DERECHA: a >> 2 = {a >> 2}\") # 2\n\n\n\"\"\"\nESTRUCTURAS DE CONTROL\n\"\"\"\n\n#Condicionales\nmy_string = \"Zeta\"\n\nif my_string == \"Martin\":\n    print(\"my_string es 'Martin'\")\nelif my_string == \"Zeta\":\n    print(\"my_string es 'Zeta'\")\nelse:\n    print(\"my_string no es 'Martin' ni 'Zeta'\")\n    \n#Iterativas o bucles\n\nfor i in range(11):\n    print(i)\n\ni = 0\n\nwhile i <= 10:\n    print(i)\n    i += 1\n    \n#Manejo de excepciones\ntry:\n    # Código que podría causar una excepción\n    print(10 / 0)\nexcept:\n    print(\"Se ha producido un error\")\nfinally:\n    print(\"Ha finalizado el manejo de excepciones\")\n    \n    \n\"\"\"\nEXTRAS\n\"\"\"\n\nfor number in range(10, 56):\n    if number % 2 == 0 and number != 16 and number % 3 != 0:\n        print(number)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Matc-Channel.py",
    "content": "'''\nOPERADORES\n'''\n\n# Aritméticos\nprint(f\"suma: 10 + 3 = {10 + 3}\")\nprint(f\"Resta: 10 - 3 = {10 - 3}\")\nprint(f\"Multiplicación: 10 * 3 = {10 * 3}\")\nprint(f\"División: 10 / 3 = {10 / 3}\")\nprint(f\"Módulo: 10 % 3 = {10 % 3}\")\nprint(f\"Exponente: 10 ** 3 = {10 ** 3}\")\nprint(f\"División Entera: 10 // 3 = {10 // 3}\")\n\n\n# variable uso\nsum = 10 + 3\nprint(sum)\n\n# OPERADORES DE COMPARACIÓN\nprint(f\"Igualdad: 10 == 3 es {10 == 3}\")\nprint(f\"Desigualdad: 10 == 3 es {10 != 3}\")\nprint(f\"Mayor que: 10 == 3 es {10 > 3}\")\nprint(f\"Menor que: 10 == 3 es {10 < 3}\")\nprint(f\"Mayor o igual que: 10 == 3 es {10 >= 3}\")\nprint(f\"Menor o igual que: 10 == 3 es {10 <= 3}\")\n\n# Operadores Lógicos\nprint(f\"AND &&: 10 + 3 and 5 - 1 == 4 es {10 + 3 == 13 and 5 - 1 == 4}\")\nprint(f\"OR ||: 10 + 3 == 13 or 5 - 1 == 4 es {10 + 3 == 13 or 5 - 1 == 4}\")\nprint(f\"NOT !: 10 + 3 == 14 es {10 + 3 == 14}\")\n# añadiendo NOT\nprint(f\"NOT !: 10 + 3 == 14 es {not 10 + 3 == 14}\")\n\n# OPERADORES DE ASIGNACIÓN\nmy_number = 11  # => asignar\nprint(my_number)\n# suma y asignación\nmy_number += 2\nprint(my_number)\n# resta y asignación\nmy_number -= 2\nprint(my_number)\n# multiplicación y asignación\nmy_number *= 2\nprint(my_number)\n# División y asignación\nmy_number /= 2\nprint(my_number)\n# Módulo y asignación\nmy_number %= 2\nprint(my_number)\n# Exponente y asignación\nmy_number **= 2\nprint(my_number)\n# División Enteta\nmy_number //= 2\nprint(my_number)\n\n\n# OPERADORES DE IDENTIDAD\n# False por que ocupan diferente dirección de memoria\nmy_new_number = 1.0\nprint(f\"my_new_number is my_new_number es: {my_number is my_new_number}\")\n\n# True por que  ocupan mismo lugar de memoria\nmy_new_number = my_number\nprint(f\"my_new_number is my_new_number es: {my_number is my_new_number}\")\n\n# Añadiendo operador de DESIGUALDAD NOT\nprint(f\"my_new_number is my_new_number es: {my_number is not my_new_number}\")\n\n# OPERADORES DE PERTENECIA\n'''Si algo pertenece a algo...'''\nprint(f\"'m' in 'Kramer' = {'u' in 'mourdev'}\")\nprint(f\"'z' not in 'Kramercito' = {'z' not in 'Kramercito'}\")\n\n# OPERADORES DE BIT\na = 10  # => 1010\nb = 3   # => 0011\n# 1 si ambos BITS son 1\nprint(f\"AND: 10 & 3 = {10 & 3}\")    # => 0010\n# 1 si al menos uno de los BITS es 1\nprint(f\"OR: 10 | 3 = {10 | 3}\")     # => 1011\n# 1 si los BITS son DIFERENTES\nprint(f\"XOR: 10 ^ 3 = {10 ^ 3}\")   # => 1001\n# fórmula ~n = -(n+1)\nprint(f\"NOT: ~10 = {~10}\")  # => -11\n# BITS del número se MUEVEN A LA DERECHA\nprint(f\"Desplazamiento a la derecha: {10 >> 2}\")    # => 1010 = 0010=2\n# BITS del número se MUEVEN A LA IZQUIERDA\nprint(f\"Desplazamiento a la Izquierda: {10 << 2}\")    # => 1010 = 101000=40\n\n\n'''\nESTRUCTURAS DE CONTROL\n'''\n\n# CONDICIONALES\n\nmy_string = 'MoureDev'\n\nif my_string == 'MoureDev':\n    print(\"my_string es 'Mouredev'\")\nelif my_string == 'Brais':\n    print(\"my_string es 'Brais'\")\nelse:\n    print(\"my_string no es 'MoureDev' ni 'Brais'\")\n\n\n# ITERATIVAS\n# Esto es un BUCLE o LOOP\n# 'i' es una VARIABLE que cambia cada vuelta de BUCLE: i=0, i=1... i=10.\nfor i in range(11):     # => Hacer algo 11 veces\n    print(i)    # => Imprime números del 0-10\n\n\ni = 0   # => Le decimos, EMPIEZA desde CERO...\n\nwhile i <= 10:\n    print(i, 'Kramercito')  # => Mientras i sea MENOR o IGUAL a 10 REPITE..\n    i += 1  # => SUMALE 1 A i MIENTRAS se repite el BUCLE...\n\n\n# ESTRUCTURAS DE CONTROL PARA MANEJO DE EXEPCIONES\n\ntry:    # INTENTAR\n    print(10 / 0)   # => INTENTAEJECUTAR ESTE CÓDIGO\nexcept ZeroDivisionError:   # => FLAKE8 ERROR al DIOVIDIR por CERO\n    print('Se ha producido un ERROR')   # => SALTA AQUÍ, si falla el BLOQUE TRY\nfinally:\n    print('Ha finalizado el manejo de exepciones')  # => EJECUTA SIEMPRE\n\n\n'''\nEXTRA\n\nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\nSeguro que al revisar detenidamente las posibilidades has descubierto algo\nnuevo.\n'''\n\nfor number in range(10, 56):    # => BUCLE de 10-55, excluye 56.\n    if number % 2 == 0 and number != 16 and number % 3 != 0:\n        print(number)\n\n# terminado\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/MercedesDF.py",
    "content": "# Operadores Aritméticos\na = 10\nb = 3\nprint(\"Suma:\", a + b)  # Suma\nprint(\"Resta:\", a - b)  # Resta\nprint(\"Multiplicación:\", a * b)  # Multiplicación\nprint(\"División:\", a / b)  # División (flotante)\nprint(\"División entera:\", a // b)  # División entera\nprint(\"Módulo:\", a % b)  # Residuo\nprint(\"Potencia:\", a ** b)  # Potencia\nprint(\"\")\n# Operadores Lógicos\nx = True\ny = False\nprint(\"Lógico AND:\", x and y)  # AND\nprint(\"Lógico OR:\", x or y)  # OR\nprint(\"Lógico NOT x:\", not x)  # NOT\nprint(\"Lógico NOT y:\", not y)  # NOT\nprint(\"\")\n# Operadores de Comparación\nprint(\"Igualdad:\", a == b)  # Igualdad\nprint(\"Diferente:\", a != b)  # Diferencia\nprint(\"Mayor que:\", a > b)  # Mayor que\nprint(\"Menor que:\", a < b)  # Menor que\nprint(\"Mayor o igual que:\", a >= b)  # Mayor o igual que\nprint(\"Menor o igual que:\", a <= b)  # Menor o igual que\nprint(\"\")\n# Operadores de Asignación\nc = 5\nc += 2  # c = c + 2\nprint(\"Asignación (+=):\", c)\nc *= 3  # c = c * 3\nprint(\"Asignación (*=):\", c)\nprint(\"\")\n# Operadores de Identidad\nprint(\"¿a es b?\", a is b)  # Verifica si a y b son el mismo objeto\nprint(\"¿a no es b?\", a is not b)  # Verifica si no lo son\nprint(\"\")\n# Operadores de Pertenencia\nlista = [1, 2, 3, 4, 5]\nprint(\"¿2 en lista?\", 2 in lista)  # Verifica si el 2 está en la lista\nprint(\"¿6 no en lista?\", 6 not in lista)  # Verifica si el 6 no está en la lista\nprint(\"\")\n# Operadores de Bits\nnum = 6  # 110 en binario\nprint(\"AND de bits:\", num & 3)  # AND a nivel de bits (110 & 011 = 010 = 2)\nprint(\"OR de bits:\", num | 3)  # OR a nivel de bits (110 | 011 = 111 = 7)\nprint(\"XOR de bits:\", num ^ 3)  # XOR a nivel de bits (110 ^ 011 = 101 = 5)\nprint(\"Desplazamiento a la izquierda:\", num << 1)  # Desplazar bits a la izquierda (110 << 1 = 1100 = 12)\nprint(\"Desplazamiento a la derecha:\", num >> 1)  # Desplazar bits a la derecha (110 >> 1 = 11 = 3)\nprint(\"\")\n# Ejemplos de estructuras de control\n# Condicionales\nif a > b:\n    print(\"a es mayor que b\")\nelif a == b:\n    print(\"a es igual a b\")\nelse:\n    print(\"a es menor que b\")\nprint(\"\")\n# Bucle for\nfor i in range(5):\n    print(f\"Iteración {i} en el bucle for\")\nprint(\"\")\n# Bucle while\ncontador = 0\nwhile contador < 3:\n    print(f\"Iteración {contador} en el bucle while\")\n    contador += 1\nprint(\"\")\n# Manejo de excepciones\ntry:\n    resultado = a / 0  # Error de división por cero\nexcept ZeroDivisionError:\n    print(\"Error: División por cero\")\nprint(\"\")\n# Desafío extra: imprimir los números entre 10 y 55, pares, que no sean 16 ni múltiplos de 3\nfor num in range(10, 56):\n    if num % 2 == 0 and num != 16 and num % 3 != 0:\n        print(num)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Miguelberrio0810.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n#  *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n#  *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n#  * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n#  *   que representen todos los tipos de estructuras de control que existan\n#  *   en tu lenguaje:\n#  *   Condicionales, iterativas, excepciones...\n#  * - Debes hacer print por consola del resultado de todos los ejemplos.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea un programa que imprima por consola todos los números comprendidos\n#  * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n#  *\n#  * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n#  */\n\nn1 = int(input(\"Ingresa un numero: \"))\nn2 = int(input(\"Ingresa otro numero: \"))\n\ndef condicionales(n1, n2):\n    if (n1 > n2):\n        print(f\"numero 1 : {n1}, es mayor que numero {n2}\")\n    else:\n        print(f\"numero 2: {n2}, es mayor que numero 1: {n1}\")\n\ndef iteraciones(n):\n    for i in range(n, 21):\n        print(n)\n        n += 1\n        break\n\ndef Suma(n1, n2):\n    return n1 + n2\n\ndef Resta(n1, n2):\n    return n1 - n2\n\ndef Division(n1, n2):\n    return n1 / n2\n\ndef Multiplicacion(n1, n2):\n    return n1 * n2\n\ndef Exponeciacion(n1, n2):\n    return n1 ** n2\n\ndef imprimir_numeros(n1, n2):\n    for i in range(10, 56):  # Rango de 10 a 55, 56 no está incluido\n        if i % 2 == 0 and i != 16 and i % 3 != 0:\n            print(i)\n\n\nprint(condicionales(n1, n2))\nprint(iteraciones(8))\nprint(Suma(n1, n2))\nprint(Resta(n1, n2))\nprint(Division(n1, n2))\nprint(Multiplicacion(n1, n2))\nprint(Exponeciacion(n1, n2))\nprint(imprimir_numeros(n1, n2))\n\nprint(\"Fin del Juego, Gracias!\")"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/MirandaYuber.py",
    "content": "import random\n\nprint('######  OPERADORES_ARITMETICOS  ######')\nprint(f'suma (1 + 1): {1 + 1}')\nprint(f'resta (1 - 1): {1 - 1}')\nprint(f'Multiplicación (10 * 2): {10 * 2}')\nprint(f'Division (12 / 2): {12 / 2}')\nprint(f'Division con resultado entero (18 // 5): {18 // 5}')\nprint(f'Modulo (16 % 3): {16 % 3}')\nprint(f'Potencia (12 ** 2): {12 ** 2}')\nprint()\nprint()\n\n\nprint('###### OPERADORES_RELACIONALES  ######')\nprint(f'Mayor que (12 > 2): {12 > 2}')\nprint(f'Mayor o igual que (12 >= 12): {12 >= 12}')\nprint(f'Menor que (2 < 2): {2 < 2}')\nprint(f'Menor o igual que (5 <= 5): {5 <= 5}')\nprint(f'Igual que (3 == \"3\"): {3 == \"3\"}')\nprint(f'Diferente que (1 != \"1\"): {1 != \"1\"}')\nprint()\nprint()\n\n\nprint('######  OPERADORES_DE_ASIGNACIÓN  ######')\na = 10\nprint(f'Asignación (a = 10): {a}')\na += 7\nprint(f'Suma y asignación (a += 7): {a}')\na -= 7\nprint(f'Resta y asignación (a -= 7): {a}')\na *= 7\nprint(f'Multiplicación y asignación (a *= 7): {a}')\na /= 7\nprint(f'División y asignación (a /= 7): {a}')\na //= 7\nprint(f'División de resultado entero y asignación (a /= 7): {a}')\na %= 7\nprint(f'Modulo y asignación (a %= 7): {a}')\na **= 7\nprint(f'Potencia y asignación (a **= 7): {a}')\nprint()\nprint()\n\n\nprint('######  OPERADORES_LOGICOS  ######')\na = False\nb = True\nprint(f'And: {a and b}')\nprint(f'Or: {a or b}')\nprint(f'Not: {not b}')\nprint()\nprint()\n\n\nprint('######  OPERADORES_PERTENENCIA  ######')\nnumeros = [1, 2, 3, 4, 5, 6]\nprint(f'In: {2 in numeros}')\nprint(f'not in: {10 not in numeros}')\nprint()\nprint()\n\n\nprint('######  OPERADORES_IDENTIDAD  ######')\nnum1 = 1\nnum2 = 1\nnum3 = 2\nprint(f'Is: {num1 is num2}')\nprint(f'Is not: {num1 is not num2}')\nprint()\nprint()\n\n\nprint('######  CONDICIONALES  ######')\nnumeros = random.randint(-10, 10)\nprint('Condicional if else:')\nif numeros > 0:\n    print(f'El número {numeros} es positivo')\nelse:\n    print(f'El número {numeros} es negativo')\nprint()\nprint()\n\nprint('######  CICLOS  ######')\nprint('Ciclo For:')\nlenguajes = ['Python', 'PHP', 'Java', 'Ruby']\nfor lenguaje in lenguajes:\n    print(lenguaje)\n\nprint('Ciclo While:')\ncontador = 0\nwhile contador <= 10:\n    print(f'Iteración {contador}')\n    contador += 1\n\nprint('Excepción:')\ntry:\n    edad = int(input('Digite su edad (en números): '))\n    print(f'Su edad es {edad}')\nexcept ValueError:\n    print('Debe ingresar solo valores númericos')\n\nprint()\nprint()\n\nprint('######  EXTRA  ######')\nfor numero in range(10, 56):\n    if numero % 2 == 0 and numero != 16 and numero % 3 != 0:\n        print(numero)\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/MizadloGcia.py",
    "content": "\"\"\"\nOperadores\n\"\"\"\n\n# Operadores aritmeticos\n\nprint(f\"Suma: 100 + 50 = {100 + 50}\")\nprint(f\"Resta: 100 - 50 = {100 - 50}\")\nprint(f\"Multiplicacion: 10 * 5 = {10 * 5}\")\nprint(f\"Division: 12 / 3 = {12 / 3}\")\nprint(f\"Modulo: 16 % 3 = {16 % 3}\")\nprint(f\"Potencia: 12 ** 3 = {12 ** 3}\")\nprint(f\"Division Entera: 18 // 5 = {18 // 5}\")\n\n# Operadores relacionales\n\nprint(f\"Mayor que(>): 10 > 5 = {10 > 5}\")\nprint(f\"Menor que(<): 10 < 5 = {10 < 5}\")\nprint(f\"Igual a: (==): {100 == 100}\")\nprint(f\"Mayor o igual que(>=): {75 >= 50}\")\nprint(f\"Menor o igual que(<=): {50 <= 75}\")\nprint(f\"Diferente(!=): {0 != 1}\")\n\n# Operadores Bit\n\nprint(f\"AND(&): 2 & 3 = {2 & 3}\")\nprint(f\"OR(|): 2 | 3 = {2 | 3}\")\nprint(f\"XOR(^) 2 ^ 3 = {2 ^ 3}\")\nprint(f\"NOT(~) ~2 = {~2}\")\nprint(f\"Desplazamiento derecha bit(>>): 2 >> b = {2 >> 3}\")\nprint(f\"Desplazamiento izquierda bit(>>): 2 << b = {2 << 3}\")\n\n# Operadores de asignacion\n\nmy_var = 10 # Asignacion\nprint(my_var)\n\nmy_var += 5 # Suma y asignacion\nprint(my_var)\n\nmy_var -= 5 # Resta y asignacion\nprint(my_var)\n\nmy_var *= 3 # Multiplicacion y asignacion\nprint(my_var)\n\nmy_var /= 2 # Division y asignacion\nprint(my_var)\n\nmy_var %= 4 # Modulo y asignacion\nprint(my_var)\n\nmy_var **= 3 # Potencia y asignacion\nprint(my_var)\n\nmy_var //= 4 # Division entera y asignacion\nprint(my_var)\n\nmy_new_var = 50\nmy_new_var &= 18 # AND bit y asignacion\nprint(my_new_var)\n\nmy_new_var |= 3 # OR bit y asignacion\nprint(my_new_var)\n\nmy_new_var ^= 3 # XOR bit y asignacion\nprint(my_new_var)\n\nmy_new_var >>= 3 # Desplazamiento derecha bit y asignacion\nprint(my_new_var)\n\nmy_new_var <<= 3 # Desplazamiento izquierda bit y asignacion\nprint(my_new_var)\n\n# Operadores Logicos\n\nprint(f\"AND(and): 5 > 2 and 10 < 20 = {5 > 2 and 10 < 20}\")\nprint(f\"OR(or): 5 > 2 or 10 > 20 = {5 > 2 or 10 > 20}\")\nprint(f\"NOT(not): not(5 < 2) = {not(5 < 2)}\")\n\n# Operadores de pertenencia\n\na = [1, 2, 3, 4, 5]\n\nprint(3 in a)\nprint(12 not in a)\nprint(15 in a)\n\nb = \"Hello World\"\n\nprint(\"World\" in b)\nprint(\"code\" not in b)\n\n# Operadores de identidad\n\na = 3\nb = 3\nc = 4\n\nprint(a is b)\nprint(a is not c)\nprint(b is c)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Monikgbar.py",
    "content": "\"\"\"Operadores\"\"\"\n\n# Operadores de asignación\nnumero = 8 # asignación\nprint(numero) \nnumero += 8 # suma\nprint(numero)\nnumero -= 8 # resta\nprint(numero)\nnumero *= 8 # multiplicación\nprint(numero)\nnumero /= 8 # división\nprint(numero)\nnumero //= 8 # división entera\nprint(numero)\nnumero **= 8 # exponente\nprint(numero)\nnumero %= 8 # módulo\nprint(numero)\n\n# Operadores aritméticos\nprint(f\"Suma: 5 + 9 = {5 + 9}\") \nprint(f\"Resta: 5 - 9 = {5 - 9}\") \nprint(f\"Multiplicación: 5 * 9 = {5 * 9}\") \nprint(f\"Exponente: 5 ** 9 = {5 ** 9}\") \nprint(f\"División: 5 / 9 = {5 / 9}\")\nprint(f\"División entera: 5 // 9 = {5 // 9}\")\nprint(f\"Módulo: 5 % 9 = {5 % 9}\")\n\n# Operadores relacionales\nprint(f\"Igualdad: 3 == 2 es {3 == 2}\")\nprint(f\"Desigualdad: 3 != 2 es {3 != 2}\")\nprint(f\"Menor que: 3 < 2 es {3 < 2}\")\nprint(f\"Mayor que: 3 > 2 es {3 > 2}\")\nprint(f\"Menor o igual que: 3 <= 2 es {3 <= 2}\")\nprint(f\"Mayor o igual que: 3 >= 2 es {3 >= 2}\")\n\n# Operadores lógicos\nprint(f\"AND &&: True and True es {True and True}\")\nprint(f\"OR ||: True or True es {True or True}\")\nprint(f\"NOT !: not True == True es {not True == True}\")\n\n\"\"\"Estructuras de control\"\"\"\n\n# Condicionales\nanimal = \"gato\"\nif animal == \"gato\":\n    print(\"El animal es correcto\")\nelif animal == \"perro\":\n    print(\"El animal escogido no es el correcto\")\nelse:\n    print(\"Has encontrado una nueva especie\")\n\n# Iteradores\ncontador = 5\nwhile contador <= 5:\n    print(\"Hola mundo\")\n    contador += 1\n\nfor i in range(10):\n    print(i)\n\n\"\"\"Excepciones\"\"\"\n\ntry:\n    numero = float(input(\"Introduce un número: \"))\n    mi_numero = 5\n    print(f\"La suma de ambos números es: {mi_numero + numero}\")\nexcept:\n    print(\"Se ha producido un error\")\nelse:\n    print(\"Has introducido correctamente el número\")\nfinally:\n    print(\"Podemos continuar con el programa\")\n\n\n\"\"\"Extra\"\"\"\nfor i in (10, 56):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Mstaz4.py",
    "content": "# EJERCICIO 01\n\n\"\"\"\n1. - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje: Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n\"\"\"\n\nprint(\"Operadores Aritméticos:\\n\")\na = 3\nb = 4\n\nprint(\"\\tadición. 3 + 4 =\", a + b)\nprint(\"\\tsustracción. 3 - 4 =\", a - b)\nprint(\"\\tmultiplicación. 3 * 4 =\", a * b)\nprint(\"\\tmodulo. 3 % 4 =\", a % b)\nprint(\"\\tdivision. 3 / 4 =\", a / b)\nprint(\"\\texponencial. 3 ** 4 =\", a ** b)\nprint(\"\\tfloor division. 3 // 4 =\", a // b)\n\nprint(\"\\nOperadores Lógicos:\")\na = True\nb = False\n\nprint(\"\\ta and b =\", a and b)\nprint(\"\\ta or b =\", a or b)\nprint(\"\\tnot a =\", not a)\n\nprint(\"\\nOperadores Relacionales:\")\na = 5\nb = 67\n\nprint(\"\\t a > b =\", a > b)\nprint(\"\\t a < b =\", a < b)\nprint(\"\\t a == b =\", a == b)\nprint(\"\\t a >= b =\", a >= b)\nprint(\"\\t a <= b =\", a <= b)\nprint(\"\\t a != b =\", a != b)\n\nprint(\"\\nOperadores de Bit a Bit:\")\na = 2\nb = 3\n\nprint(\"\\t a & b =\", a & b)\nprint(\"\\t a | b =\", a | b)\nprint(\"\\t ~a =\", ~a)\nprint(\"\\t a >> b =\", a >> b)\nprint(\"\\t a << b =\", a << b)\n\nprint(\"\\nOperadores de asignación:\")\na = 5\nprint(\"\\ta = \", a)\na += 5\nprint(\"\\ta = a + 5 ->\", a)\na -= 5\nprint(\"\\ta = a - 5 ->\", a)\na *= 5\nprint(\"\\ta = a * 5 ->\", a)\na /= 5\nprint(\"\\ta = a / 5 ->\", a)\na %= 5\nprint(\"\\ta = a % 5 ->\", a)\na **= 5\nprint(\"\\ta = a ^ 5 ->\", a)\na //= 5\nprint(\"\\ta = a // 5 ->\", a)\n\nprint(\"\\nOperadores de pertenencia:\")\nlista = [1, 2, 3, 4, 5, 6, 7, 9]\nprint(lista)\nprint(\"\\tEl número 8 está en la lista? \", 8 in lista)\nprint(\"\\tEl número 63 no está en la lista? \", 8 not in lista)\n\nprint(\"\\nOperadores de identidad:\")\na = 1\nb = 2\nc = 1\n\nprint(\"a =\", a, \"b=\", b, \"c=\", c)\nprint(\"\\ta es b? \", a is b)\nprint(\"\\ta no es b? \", a is not b)\nprint(\"\\ta es c? \", a is c)\n\n\"\"\" \n2. - Utilizando las operaciones con operadores que tú quieras, crea ejemplos que representen todos los tipos de estructuras de control que existan en tu lenguaje:\n  Condicionales, iterativas, excepciones...\n\"\"\"\n# Condicionales\nprint(\"Ejemplo de condicional if\")\nedad = 20\nif edad < 18:\n    print(\"Menor de edad\\n\")\nelif edad > 65:\n    print(\"Adulto mayor\\n\")\nelse:\n    print(\"Adulto\\n\")\n\n# Iterativas\nprint(\"Ejemplo de estructura iterativa for\")\nfor i in range(5):\n    print(i)\n\nprint(\"\\nEjemplo de estructura iterativa while\")\ncontador = 0\nwhile contador < 5:\n    print(contador)\n    contador += 1\n\n# Excepciones\nprint(\"\\nEjemplo de try, except y finally\")\ntry:\n    num = int(input(\"Ingrese un número: \"))\nexcept ValueError:\n    print(\"Error: Debe ingresar un número\")\nfinally:\n    print(\"Operación finalizada\")\n\n\"\"\" \n3. - Crea un programa que imprima por consola todos los números comprendidos entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3. \n\"\"\"\nprint(\"\\nImprime por consola los números del 10 al 55 sin el 16 ni los multiplos de 3\")\nfor i in range(10, 56):\n    if i == 16 or i % 3 == 0:\n        continue\n    print(i)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Nach012.py",
    "content": "#Operadores aritméticos\n\nprint(f\"Suma 10 + 5 = {10 + 5}\")\nprint(f\"Resta 10 - 5 = {10 - 5}\")\nprint(f\"Multiplicación 10 * 5 = {10 * 5}\")\nprint(f\"División 10 / 5 = {10 / 5}\")\nprint(f\"División Entera 10 // 4 = {10 // 4}\")\nprint(f\"Modulo 10 % 4 = {10 % 4}\")\nprint(f\"Exponenciales 10 ** 5 = {10 ** 5}\")\n\n#Operadores de Comparación \n#Los operadores de comparación nos van a dar resultados \"True or False\"\n\nprint(f\"Igualdad: 10 == 5 es {10 == 5}\")   \nprint(f\"Desiguladad: 10 != 5 es {10 != 5}\")  \nprint(f\"Mayor que: 10 > 5 es {10 > 5}\")\nprint(f\"Menor que: 10 < 5 es {10 < 5}\")\nprint(f\"Mayor o igual que: 10 >= 10 es {10 >= 10}\")\nprint(f\"Menor o igual que: 10 <= 5 es {10 <= 5}\") \n\n#Operadores lógicos\n\nprint(f\"AND &&: 10 + 3 == 13 and 5 - 1 == 4 es {10 + 3 == 13 and 5 - 1 == 4}\")\nprint(f\"OR ||: 10 + 3 == 14 or 5 - 1 == 4 es {10 + 3 == 14 or 5 - 1 == 4}\")\nprint(f\"NOT !: 10 + 3 == 14 or 5 - 1 == 4 es {10 + 3 == 14 or 5 - 1 == 4}\")\n\n#Operadores de asignación\n#Los usamos en conjunto con el valor de las variables\n\nmy_number = 10 # El operador de asignación es \"=\", lo estoy utilizando para establecer que my_number es igual a 10.\nprint(my_number)\nmy_number += 5 # Suma y asignación. Al valor de my_number le sume 5.\nprint(my_number)\nmy_number -= 5 # Resta y asignación. Al valor de my_number le reste  5.\nprint(my_number) \nmy_number *= 5 # Multiplicación y asignación. Al valor de my_number le multiplique por  5.\nprint(my_number) \nmy_number /= 2 # División y asignación. Al valor de my_number lo dividí por  2.\nprint(my_number) \nmy_number //= 3 # División entera y asignación. Al valor de my_number lo dividí de forma entera por  3. División sin decimales.\nprint(my_number)\nmy_number %= 3 # Módulo y asignación. Al valor de my_number lo calcule el resto de forma entera por  5. (8 // 3 = 3+3 da 6 la diferencia es 2)\nprint(my_number) \nmy_number **= 5 # Exponente y asignación. Al valor de my_number lo multiplique exponencialmente por  5.\nprint(my_number)\n\n# Operadores de identidad\n# Sirven para comparar el valor de la posición de memoria.\n\nmy_new_number = my_number\nprint(my_new_number)\nprint(f\"my_number is my_new_number es {my_number is my_new_number}\") # IS se usa para igualdad\nprint(f\"my_number is not my_new_number es {my_number is not my_new_number}\") # IS NOT se usa para desigualdad\n\n# Operadores de pertenencia\n\nprint(f\"'a' in 'nacho' es {'a' in 'nacho'}\") # true (in se utiliza para corrobar que PERTENECE)\nprint(f\"'p' in 'nacho' es {'p' in 'nacho'}\") # false\n\nprint(f\"'p' not in 'nacho' es {'p' not in 'nacho'}\") # true (not in se utiliza para corroborar que NO PERTENECE)\n\nmy_variable1 = \"AprendiendoPhyton\"\nprint(f\"'Aprendiendo' in 'my_variable1' is {'Aprendiendo' in my_variable1}\")\n\n# Operadores de bit\na = 10\nb = 3\nprint(f\"AND: 10 & 3 = {10 & 3}\") #1010\nprint(f\"OR: 10 | 3 = {10 | 3}\") #1011\nprint(f\"XOR: 10 ^ 3 = {10 ^ 3}\") #1001\nprint(f\"NOT: ~10 = {~10}\") #1010\nprint(f\"Desplazamiento a la derecha 10 >> 2 = {10 >> 2}\") #0010\nprint(f\"Desplazamiento a la izquierda 10 << 2 = {10 << 2}\") #10100\n\n\"\"\"\nEstructuras de control\n\"\"\"\n\n# Condicionales\n\nmy_string = \"nacho\"\n\nif my_string == \"nacho\":\n    print(\"my_string es 'nacho'\")\nelif my_string == \"ignacio\":\n    print(\"my_string is 'ignacio'\")\nelse:\n    print(\"my_string no es 'nacho'\")\n\n# Iterativas\n# Ejecuta lo que se encuentra dentro del bucle. Recorre una escructura determinada.\n\nfor n in range(10):\n    print(n)\n\ni = 0\n\nwhile i <= 10:\n    print(i)\n    i += 1\n\n# Manejo de excepciones\n# La finalidad es que la aparición de un error en el código, ese error no destruya el funcionamiento del mismo. Es una especie de cortafuegos que impide que el error tire abajo el programa.\n\n\ntry:\n    print(10 / 0)\nexcept:\n    print(\"Se ha producido un error\")\nfinally:\n    print(\"Ha finalizado el manejo de excepciones\")\n\n\"\"\"\nExtra\n\"\"\"\n\nfor number in range (10,56):\n    if number % 2 == 0 and number != 16 and number % 3 != 0:\n        print(number)\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/NeosV.py",
    "content": "#Operadores aritmeticos\n\nprint (f\"Suma: 2 + 5 = {2 + 5}\")\nprint (f\"Resta: 2 - 5 = {2 - 5}\")\nprint (f\"Division: 2 / 5 = {2 / 5}\")\nprint (f\"Multiplicacion: 2 * 5 = {2 * 5}\")\nprint (f\"Modulo: 2 % 5 = {2 % 5}\")\nprint (f\"Exponente: 2 ** 5 = {2 ** 5}\")\nprint (f\"Division entera: 2 // 5 = {2 // 5}\")\n\n#Operadores de comparacion\n\nprint (f\"Igualdad: 10 == 3 = {10 == 3}\")\nprint (f\"Igualdad: 10 != 3 = {10 != 3}\")\nprint (f\"Mayor que: 10 > 3 = {10 > 3}\")\nprint (f\"Menor que: 10 < 3 = {10 < 3}\")\nprint (f\"Mayor o igual que: 10 >= 3 = {10 >= 10}\")\nprint (f\"Menos o igual que: 10 <= 3 = {10 <= 3}\")\n\n#Operadores logicos\n\nprint (f\"AND : 10 + 3 == 13 and 5 - 1 == 4 = {10 + 3 == 13 and 5 - 1 == 4}\")\nprint (f\"OR : 10 + 3 == 15 and 5 - 1 == 4 = {10 + 3 == 15 or 5 - 1 == 4}\")\nprint (f\"NOT : not 10 + 3 == 14 = {not 10 + 3 == 14}\")\n\n#Operadores de asignacion\n\nnumero= 11  #asignacion\nprint (numero)\nnumero += 3 #asignacion con suma\nprint (numero)\nnumero -= 3 #asignacion con resta\nprint (numero)\nnumero *= 3 #asignacion con multiplicacion\nprint (numero)\nnumero /=3 #asignacion con division\nprint (numero)\nnumero %=3 #asignacion con modulo\nprint (numero)\nnumero //=3 #asignacion con division entera\nprint (numero)\nnumero **=3 #asignacion con exponente\nprint (numero)\n\n\n#Operadores de identidad\n\nnuevo_numero = 10\n\nprint(f\"numero is nuevo_numero es: {numero is nuevo_numero}\")\nprint(f\"numero is not nuevo_numero es: {numero is not nuevo_numero}\")\n\n#Operadores de pertenencia\n\nprint (f\"'r' in 'Andres'= {'r' in 'Andres'}\")\nprint (f\"'b' not in 'Andres'= {'r' in 'Andres'}\")\n\n#Operadores de bit\n\na = 10 #1010\nb = 3 # 0011\n\nprint (f\"AND: 10 & 3 = {10 & 3}\") #0010\nprint (f\"OR: 10 | 3 = {10 | 3}\") #1011\nprint (f\"XOR: 10 ^ 3 = {10 ^ 3}\") #1001\nprint (f\"NOT: ~10 = {~10}\") \nprint (f\"Desplazar a la derecha 10 >>2 = {10 >> 2}\") \nprint (f\"Desplazar a la izquierda 10 <<2 = {10 << 2}\") \n\n#Estructuras de control\n\nmy_string = \"Andres\"\n\nif my_string == \"Andres\":\n    print(\"my_string es Andres\")\nelif my_string == \"Felipe\":\n     print (\"my_string es Felipe\")\nelse:\n     print (\"my_string no es Andres\")\n\n\nfor i in range (0,5):\n     print (i) \n\nfor i in my_string:\n     print (i)\n\nit = iter(my_string)\nprint(next(it))\nprint(next(it))\n\nlista_test= [[56, 34, 1],\n         [12, 4, 5],\n         [9, 4, 3]]\n\nfor i in lista_test:\n     for j in i:\n      print (j)\n\nfor i in my_string[::-1]:\n    print (i)\n\nfor i in range (2,20,3):\n print(i)\n\nfor i in range (20,10,-1):\n   print(i)\n\nnumero_while = 5 \n\n\nwhile numero_while > 0:\n    numero_while -=1\n    print (numero_while)\n\nmy_list = [\"Uno\",\"Dos\", \"Tres\"]\nwhile my_list:\n    my_list.pop(0)\n    print (my_list)\n\nwhile numero_while > 0:\n    numero_while -=1\n    print (numero_while)\nelse:\n    print (\"Bucle finalizado\")   \n\n\nfor i in range (0,5):\n    for j in range (6):\n        print (\"#\",end=\"\")\n    print ()    \n\nz = 7\nx = 1\n\nwhile z > 0:\n    print('' * z + '*' * x + ''* z)\n    x+=2\n    z-=1\n\na = 0\nb = 1\n\nwhile b < 89:\n    print (b)\n    a, b = b, a+b\n\n\nif(a == 1):\n    print (\"1\")\nelif ( a == 2):\n    print(\"2\")\nelif (a == 3):\n    print (\"3\")     \n\ncadena = \"python\"\n\nfor letra in cadena:\n    if letra == 'h':\n        print (\"se encontro la h\")\n        break \n    print (letra)\n\n\nfor letra in cadena:\n    if letra == 't':\n        print (\"se encontro la t\")\n        continue\n    print (letra)\n\nlista1 = [1,2,3]\nlista2 = ['a','b','c'] \nlistazip = zip(lista1 , lista2)\n\nfor numerozip, textozip in zip (lista1 , lista2):\n    print (\"lista 1\", numerozip, \"lista 2\", textozip)\n\nc = [(1, 'One'), (2, 'Two'), (3, 'Three')]\n\na , b = zip(*c)\nprint (a)\nprint (b)\n\nlista = [\"A\", \"B\", \"C\"]\n\nfor indice, l in enumerate (lista):\n    print (indice, l)\n\nen = list(enumerate(lista))\nprint (en)    \n\n\ncuadrado = [i for i in range (5)]\nprint (cuadrado)\n\nfrase = \"El perro de san roque no tiene rabo\"\n\nset = { i for i in frase if i == \"o\"}\nprint (set)\n\nlista3 = ['nombre', 'edad', 'región']\nlista4 = ['Pelayo', 30, 'Asturias']\n\ndictionario = {i:j for i,j in zip(lista3, lista4)}\nprint (dictionario)\n\n\n# Ejercicio Extra \n\nfor i in range (10 , 55):\n    if  i % 2 == 0 and i  != 16 and i % 3 > 0:\n        print (i)                                                                                                                                                                \n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/NicoHeguaburu.py",
    "content": "\n\n\n#aritmeticos\nx = 3\ny = 6\n\nsuma = x + y\nprint (suma)\n\nresta = x - y\nprint (resta)\n\ndividir = x / y \nprint (dividir)\n\nmultiplicar = x * y\nprint (resta)\n\ndividir_enteros = x // y\nprint(dividir_enteros)\n\nexponente = x ** y\nprint(exponente)\n\nresto = x % y\nprint(resto)\n\n\n#logicos\n#and\nprint (True and True) \nprint (False and False)\nprint (True and False)\nprint (False and True)\n\n\n#or \nprint (True or True)\nprint (False or False)\nprint (True or False)\nprint (False or True)\n\n\n#not\nprint (not True)\nprint (not False)\n\n\n#comparacion\nigual = 5 == 5\nprint(igual)\n\ndiferente = 5 != 5\nprint(diferente)\n\nmayor = 5 > 3\nprint(mayor)\n\nmenor = 5 < 9\nprint(menor)\n\nmayor_igual = 5 >= 5\nprint(mayor_igual)\n\nmenor_igual = 5<= 1\nprint(menor_igual)\n\n\n#asignacion\n\n#simple\nz = 3\nprint(z)\n\n#suma\nz += 4\nprint(z)\n\n#resta\nz -= 8\nprint(z)\n\nz *= 2\nprint(z)\n\nz /= 2\nprint(z)\n\n#identidad\na = 25\nb = 2\n\nprint(a is b)\nprint(a is not b)\n\n\n#pertenecia\nprint(\"n\" in \"nicolás\")\nprint(\"x\" in \"nicolás\")\n\nprint(\"n\" not in \"nicolás\")\nprint(\"x\" not in \"nicolás\")\n\n#bits\nx = 5               # 5 = 101 en bit\ny = 3               # 3 = 011 en bit\n\nprint(x & y)      #AND bit a bit\nprint(x | y)      #OR  bit a bit\nprint(x ^ y)      #XOR bit a bit\nprint(~ x)        #NOT bit a bit\nprint(x << 1)     #dezplazar a la izq en bit \nprint(x >> 1)     #dezplazar a la der en bit\n\n\n\n\n\n#ESTRUCTURAS DE CONTROL\n\n#condicionales\nx = 10\ny = 20\nif x > y:\n    print(\"X ES MAYOR A Y\")\nelif x == y: \n    print(\"X ES IGUAL A Y\")\nelse:\n    print(\"X ES MENOR A Y\")\n\n\n#iteraciones\nfor i in range(11):\n    print(i)\n\ny = 8\nwhile y <= 10:\n    print(y)\n    y += 1\n\n\n#excepciones\ntry:\n    print(10 / 10)\nexcept:\n    print(\"hay un error\")\nfinally:\n    print(\"se a completado la operacion\")\n\n\n#DIFICULTAD EXTRA\ni = 10\nwhile i <= 55:\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print (i)\n        i += 1\n    else:\n        i += 1 "
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Nicojsuarez2.py",
    "content": "'''\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n'''\na = 2\nb = 3\n\n# OPERADORES ARITMÉTICOS\nprint(a + b)    # Suma -> 5\nprint(a - b)    # Resta -> -1\nprint(a / b)    # División -> 0.6666666666666666\nprint(a // b)   # División entera -> 0\nprint(a * b)    # Multiplicación -> 6\nprint(a % b)    # Módulo -> 2\nprint(a ** b)   # Potencia -> 8\nprint(a ** 0.5) # Raíz cuadrada -> 1.4142135623730951\nprint(a)\n\n# OPERADORES LÓGICOS\nprint(a and b)   # AND -> False\nprint(a or b)    # OR -> True\nprint(a is not b)  # NOT -> False\n\n# OPERADORES DE COMPARACIÓN\nprint(a > b)    # Mayor que -> False\nprint(a < b)    # Menor que -> True\nprint(a >= b)   # Mayor o igual que -> False\nprint(a <= b)   # Menor o igual que -> True\nprint(a == b)   # Igual que -> False\nprint(a != b)   # Diferente a -> True\n\n# OPERADORES DE ASIGNACIÓN\nassign_sum = 7\nassign_sum += 3                 # Suma y asignación\nprint(assign_sum)               # 10\n\nassign_subtract = 7\nassign_subtract -= 4            # Resta y asignación\nprint(assign_subtract)          # 3\n\n# OPERADORES DE IDENTIDAD\nlist_a = [1, 2, 3]\nlist_b = list_a\nlist_c = [1, 2, 3]\n\nprint(3 is list_b) #True, el mismo contenido en la \"misma\" memoria\nprint(1 in list_a) #True\n\n# OPERADORES ITERADORES Y DE PERTENENCIA\nfor i in range(1, len(list_a)):\n        print(i)\n\nwhile a < 3:\n    print(\"todavia no\")\n    a += 1\n    \nif a > b:\n    print(\"a es mayor que b\")\nelif a < b:\n     print(\"a es menor que b\")\nelse:\n        print(\"a es igual a b\")\n\n\n# OPERADORES DE BITS\nnum_1 = 3 #0011\nnum_2 = 8 #1000\n\nfor i in range(10, 55):\n        if i % 2 == 0 and i != 16 and i % 3 != 0:\n                print(i)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/NoMeLlamoDante.py",
    "content": "#### EJERCICIO: ###\n\"\"\"- Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n    Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n    (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n\"\"\"\n\n# Arithmetic Operators\nprint(f\"Addition 9 + 6 = {9 + 6}\")\nprint(f\"Subtraction 9 - 6 = {9 - 6}\")\nprint(f\"Multiplication 9 * 6 = {9 * 6}\")\nprint(f\"Exponentiation 9 ** 6 = {9 ** 6}\")\nprint(f\"Division 9 / 6 = {9 / 6}\")\nprint(f\"Floor_division 9 // 6 = {9 // 6}\")\nprint(f\"Modulus 9 % 6 = {9 % 6}\")\n\n#Logic Operators\nprint(f\" True And False : {True and False}\")\nprint(f\"True Or False : {True or False}\")\nprint(f\"Not False : {not False}\")\n\n#Comparison Operators\nprint(f\"Equal: 10 == 10 {10 == 10}\")\nprint(f\"Not Equal: 10 != 5 {10 != 5}\")\nprint(f\"Greater than 5 > 10 {5 > 10}\")\nprint(f\"Greater than or equal to 5 >= 10 {5 >= 10}\")\nprint(f\"Less than 5 < 10 {5 < 10}\")\nprint(f\"Less than or equal to 5 > 10 {5 <= 10}\")\n\n#Bitwise Operators\nx = 10\ny = 7\nprint(f\"x({x}, {bin(x)}) & y({y}, {bin(y)}) = {x & y}, {bin(x & y)}\")\nprint(f\"x({x}, {bin(x)}) | y({y}, {bin(y)}) = {x | y}, {bin(x | y)}\")\nprint(f\"x({x}, {bin(x)}) ^ y({y}, {bin(y)}) = {x ^ y}, {bin(x ^ y)}\")\nprint(f\"~ ( x({x}, {bin(x)}) ) = {~x}, {bin(~x)}\")\nprint(f\"x ({x},{bin(x)} >> 2 = {x >> 2}, {bin(x>>2)}\")\nprint(f\"x ({x},{bin(x)} << 2 = {x << 2}, {bin(x<<2)}\")\n\n#Assignment Operators\nx = 10 \nprint(f\"x = 10:  {x}\")\nx += 10\nprint(f\"x = x + 10:  {x}\")\nx -= 10\nprint(f\"x = x - 10:  {x}\")\nx *= 10\nprint(f\"x = x * 10:  {x}\")\nx /= 5\nprint(f\"x = x / 5:  {x}\")\nx %= 11\nprint(f\"x = x % 11:  {x}\")\nx //= 3\nprint(f\"x = x // 3:  {x}\")\nx **=2\nprint(f\"x = x ** 2:  {x}\")\n\n#Assignment Bitwise Operators\nx = int(x)\nprint(f\"x = {bin(x)}\")\nprint(f\"8 = {bin(3)}\")\nx &= 8\nprint(f\"x = x &= 8:  {bin(x)}: {x}\")\nprint(f\"7 = {bin(7)}\")\nx |= 7\nprint(f\"x = x &= 7:  {bin(x)}: {x}\")\nprint(f\"5 = {bin(5)}\")\nx ^= 5\nprint(f\"x = x ^= 5:  {bin(x)}: {x}\")\nx>>=2\nprint(f\"x >>= 2 = {x}, {bin(x)}\")\nx<<=2\nprint(f\"x <<= 2 = {x}, {bin(x)}\")\n\n#Identity Operators\nx = [1,2,3]\ny = [1,2,3]\nz = x\nprint(f\"x= {x}, y= {y}, z= x\")\nprint(f\"x is z? {x is z} || x is y? {x is y}\")\nprint(f\"x is not z? {x is not z} || x is not y? {x is not y}\")\n\n#Membership Operators\ntext = \"refrigerator\"\nprint(f\"text = {text}\")\nprint(f\"'t' in {text}= {'t' in text}\")\nprint(f\"'z' not in {text}= {'z' not in text}\")\n\"\"\"- Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n    que representen todos los tipos de estructuras de control que existan\n    en tu lenguaje:\n    Condicionales, iterativas, excepciones...\n\"\"\"\ntext = \"digital\"\nfor char in text:\n    if char == \"a\":\n        index = 5\n        while index >=0:\n            index-=1\n            if index %3 == 0 and index!=0:\n                continue\n            try:\n                print(f\"5 / index = {5/index}\")\n            except Exception as e:\n                print(f\"error: {e}\")\n        else :\n            print(\"end while\")\n    elif char == \"g\":\n        while True:\n            print(\"other while\")\n            break\n    else: \n        print(f\"char: {char}\")\n    \n\"\"\"- Debes hacer print por consola del resultado de todos los ejemplos.\"\"\"\n\n\n\"\"\"DIFICULTAD EXTRA (opcional):\nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\nSeguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\"\"\"\nfor index in range(10,56):\n    if index % 2 == 0 and index != 16 and not index%3 == 0:\n        print(f\"index = {index}\")\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/NotJ0S3.py",
    "content": "# EJERCICIO:\n# - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n#   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n#   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n\n# Operadores aritmeticos:\na = 4\nb = 2\n\nprint(a + b) # Suma\nprint(a - b) # Resta\nprint(a * b) # Multiplicacion\nprint(a / b) # Division\nprint(a % b) # Modulo\nprint(a ** b) # Potencia o exponencia\nprint(a // b) # Division entera\n\n# Operadores logicos:\nc = True\nd = False\n\nprint(c and d) # AND\nprint(c or d) # OR \nprint(not c) # NOT\n\n# Operadores de comparacion:\ne = 10\nf = 20\n\nprint(e == f) # Igual\nprint(e != f) # Distinto de\nprint(e > f) # Mayor que\nprint(e < f) # Menor que\nprint(e >= f) # Mayor o igal que\nprint(e <= f) # Menor o igual que\n\n# Operadores de identidad:\ng = [1, 2, 3]\nh = g\ni = [1, 2, 3]\n\nprint(g is h) # Mismo objeto\nprint(g is i) # Diferente objeto\nprint(g is not i) # Verifica que no son el mismo objeto\n\n# Operadores de Pertenencia\nlistaNueva = [10, 20, 30, 40, 50]\n\nprint(30 in listaNueva) # Comprueba la existencia en la lista\nprint(60 not in listaNueva) # Comprueba si no esta en la lista\n\n# Operadores a nivel de Bits\nx = 4 # Binario: 0100\ny = 5 # Binario: 0101\n\nprint(x & y)  # AND bit a bit\nprint(x | y)  # OR bit a bit\nprint(x ^ y)  # XOR bit a bit\nprint(~x)     # NOT bit a bit\nprint(x << 1) # Desplazamiento a la izquierda\nprint(x >> 1) # Desplazamiento a la derecha\n\n# - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n#   que representen todos los tipos de estructuras de control que existan\n#   en tu lenguaje:\n#   Condicionales, iterativas, excepciones...\n#   Debes hacer print por consola del resultado de todos los ejemplos.\n\n# Condicionales (if, elif, else):\nif x > 8:\n    print(\"x es mayor que 8\")\nelif x == 8:\n    print(\"x es igual a 8\")\nelse: print(\"x es menor que 8\")\n\n# Bucle (while):\nj = 1\nwhile j <= 5:\n    print(j)\n    j += 1\n\n# Bucles (for):\nfor num in g: # Sobre una lista\n    print(num)\n   \nfor p in range(1, 6): # Usando un rango de números\n    print(p)\n    \n# Bucles con break y continue:\n# break:\nfor z in range(1, 6):\n    if z == 3:\n        break  # Rompera o terminara el bucle cuando z sea 3\n    print(z)\n\n# continue:\nfor w in range(1, 6):\n    if w == 3:\n        continue  #  Se salta la iteracion cuando w es igual a 3\n    print(w)\n\n\n# DIFICULTAD EXTRA (opcional):\n# - Crea un programa que imprima por consola todos los números comprendidos\n# - entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\nfor numero in range(10, 56):\n    if numero % 2 == 0 and numero != 16 and numero % 3 != 0:\n        print(numero)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/OscarDRD.py",
    "content": "#Ejemplos operadores Aritmeticos\nprint(\"************** Ejemplos operadores aritmeticos **************\")\nprint(f\"Suma: {5+5}\") #Suma\nprint(f\"Resta: {5-5}\") #Resta\nprint(f\"Multiplicación: {5*5}\") #Multiplicación\nprint(f\"División: {5/5}\") #División\nprint(f\"División entera: {5//5}\") #División entera\nprint(f\"Modulo: {5%5}\") #Modulo\nprint(f\"Exponente: {5**5}\") #Exponente\n\n#Ejemplos operadores de comparación\na = 5\nb = 10\nprint(\"************** Ejemplos operadores de comparación **************\")\nprint(f\"Igualdad: {a == b}\") #Igualdad\nprint(f\"Diferencia: {a != b}\") #Diferencia\nprint(f\"Mayor que: {a > b}\") #Mayor que\nprint(f\"Menor que: {a < b}\") #Menor que\nprint(f\"Mayor o igual que: {a >= b}\") #Mayor o igual que\nprint(f\"Menor o igual que: {a <= b}\") #Menor o igual que\n\n#Ejemplos operadores lógicos\na = True\nb = False\nprint(\"************** Ejemplos operadores lógicos **************\")\nprint(f\"AND: {a and b}\") #AND\nprint(f\"OR: {a or b}\") #OR\nprint(f\"NOT: {not a}\") #NOT\n\n#Ejemplos operadores de asignación\na = 2\nb = 3\nprint(\"************** Ejemplos operadores de asignación **************\")\nprint(f\"Asignación: {a}\") #Asignación\na += b\nprint(f\"Suma: {a}\") #Suma\na -= b\nprint(f\"Resta: {a}\") #Resta\na *= b\nprint(f\"Multiplicación: {a}\") #Multiplicación\na /= b\nprint(f\"División: {a}\") #División\na %= b\nprint(f\"Modulo: {a}\") #Modulo\na **= b\nprint(f\"Exponente: {a}\") #Exponente\na //= b\nprint(f\"División entera: {a}\") #División entera\n\n#Ejemplos operadores de identidad\nprint(\"************** Ejemplos operadores de identidad **************\")\na = 5\nb = 5\nprint(f\"Identidad: {a is b}\") #Identidad\nprint(f\"No identidad: {a is not b}\")\n\n#Ejemplos operadores de pertenencia\nprint(\"************** Ejemplos operadores de pertenencia **************\")\na = [1, 2, 3, 4, 5]\nb = 3\nprint(f\"Pertenencia: {b in a}\") #Pertenencia\nprint(f\"No pertenencia: {b not in a}\") #No pertenencia\n\n#Ejemplos operadores de bits\nprint(\"************** Ejemplos operadores de bits **************\")\na = 5\nb = 3\nprint(f\"AND: {a & b}\") #AND\nprint(f\"OR: {a | b}\") #OR\nprint(f\"XOR: {a ^ b}\") #XOR\nprint(f\"Desplazamiento a la izquierda: {a << b}\") #Desplazamiento a la izquierda\nprint(f\"Desplazamiento a la derecha: {a >> b}\") #Desplazamiento a la derecha\n\n'''\nEjercicio Extra:\nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n'''\nprint(\"************** Ejercicio Extra **************\")\nprint(\"Números comprendidos entre 10 y 55 (incluidos):\")\nfor i in range(10, 56):\n    print(i)\nprint(\"Números pares:\")\nfor i in range(10, 56):\n    if i % 2 == 0:\n        print(i)\nprint(\"Números que no son el 16 ni múltiplos de 3:\")\nfor i in range(10, 56):\n    if i != 16 and i % 3 != 0:\n        print(i)\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Pablo25.py",
    "content": "'''* - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje: Aritméticos, lógicos, de comparación, \nasignación, identidad, pertenencia, bits... (Ten en cuenta que cada lenguaje puede poseer unos diferentes)'''\n    # Operadores: En Python, existen varios tipos de operadores que permiten realizar diferentes operaciones sobre datos.\n# 1) Operadores Aritméticos: Se usan para realizar operaciones matemáticas.\n # Ejemplo: para los valores:\na = 8; b = 5\nprint (\"Operadores Aritmeticos\")\nprint (\"Suma =\", a + b)\nprint (\"Resta =\", a - b)\nprint (\"Multiplicación =\", a * b)\nprint (\"División =\", a / b)\nprint (\"Modulo =\", a % b)\nprint (\"Exponente =\", a ** b)\nprint (\"Cociente =\", a // b)\n# Orden de Aplicación\n'''El orden de prioridad para su ejecución sería el siguiente, siendo el primero el de mayor prioridad. \n1.\t() paréntesis.\n2.\t** exponente\n3.\t* / // %multiplicación, división, cociente, modulo\n4.\t+ - suma, resta.'''\n# Ejemplo de lo antes descrito.\nprint (10*(5+3)) # 80 con paréntesis se realiza la suma primero.\nprint (10*5+3) # 53 sin paréntesis se realiza primero la multiplicación.\n# 2) Operadores de Asignación: Permite realizar una operación aritmética y asignar ese valor a una variable.\n# Ejemplo para los valores:\na = 10; b = 5\nprint (\"Operadores de Asignación\")\nx = a; x += b; print (\"x +=\", x)\nx = a; x -= b; print (\"x -=\", x)\nx = a; x *= b; print (\"x *=\", x)\nx = a; x /= b; print (\"x /=\", x)\nx = a; x **= b; print (\"x **=\", x)\nx = a; x %= b; print (\"x %=\", x)\nx = a; x //= b; print (\"x //=\", x)\n# Se coloca x = a, para reiniciar el valor de x, al valor inicial de a, para que no afecte los resultados.\n# 3) Operadores de Comparación: Permite comparar dos valores y devuelve un valor booleano (True o False).\n# Ejemplo para los valores:\na = 10; b = 5\nprint (\"Operadores de Comparación\")\nprint (\"Igualdad (==)\", a == b)\nprint (\"Diferente (!=)\", a != b)\nprint (\"Menor que (<)\", a < b)\nprint (\"Mayor que (>)\", a > b)\nprint (\"Menor o Igual que (<=)\", a <= b)\nprint (\"Mayor o Igual que (>=)\", a >= b)\n# 4) Operadores Lógicos: AND, OR, NOT. Permite combinar expresiones booleanas y devuelve un valor booleano.\n# Ejemplo para los valores:\na = True; b = False\nprint (\"Operadores Lógicos\")\nprint (\"Operador (and)\", a and b)\nprint (\"Operador (or)\", a or b)\nprint (\"Operador (not)\", not a)\nprint (not not not not True) # PyTip si el número de condiciones es Par, el valor permanece, si es impar el valor cambia.\n# 5) Operadores de Identidad: Permite comparar si dos variables apuntan al mismo objeto en memoria. Operadores IS y IS NOT.\n# Ejemplo para los valores:\na = 10; b = a\nprint (\"Operadores de Identidad\")\nprint (\"Operador (is)\", a is b)\nprint (\"Operador (is not)\", a is not b)\n# Para Python, las listas son mutables, por lo tanto crea objetos diferentes para cada lista.\n# Ejemplo.\na = [1,2,3]; b = a\nprint (a is not b)\n# 6) Operadores de Pertenencia: Permite comprobar si un valor pertenece a una secuencia (como una lista, tupla o cadena).\n# Ejemplo para los valores:\na = [1,2,3]\nprint (\"Operadores de Pertenencia\")\nprint (\"Operador (in)\", 2 in a)\nprint (\"Operador (not in)\", 4 not in a)\n# 7) Operadores Bit a Bit: Permite realizar operaciones a nivel de bits.\n'''Los operadores más comunes son:\n1.\tOperador AND (&) Realiza una operación AND a nivel de bits.\n2.\tOperador OR (|) Realiza una operación OR a nivel de bits.\n3.\tOperador XOR (^) Realiza una operación XOR a nivel de bits.\n4.\tOperador NOT (~) Realiza una operación NOT a nivel de bits.\n5.\tOperador de Desplazamiento Izquierdo (<<) Desplaza los bits a la izquierda.\n6.\tOperador de Desplazamiento Derecho (>>) Desplaza los bits a la derecha.'''\n# Ejemplo para los valores:\na = 10; b = 4\nprint (\"Operadores Bit a Bit\")\nprint (\"Operador AND (&)\", a & b)\nprint (\"Operador OR (|)\", a | b)\nprint (\"Operador XOR (^)\", a ^ b)\nprint (\"Operador NOT (~)\", ~a)\nprint (\"Operador de Desplazamiento Izquierdo (<<)\", a << 1)\nprint (\"Operador de Desplazamiento Derecho (>>)\", a >> 1)\n'''* - Utilizando las operaciones con operadores que tú quieras, crea ejemplos que representen todos los tipos \nde estructuras de control que existan, en tu lenguaje: Condicionales, iterativas, excepciones...\nDebes hacer print por consola del resultado de todos los ejemplos.'''\n    # Estructuras de control en Python, permiten dirigir el flujo de ejecución de un programa.\n# 1) Estructuras condicionales: Es una estructura de control de selección que sirve para tomar decisiones, IF, ELIF, ELSE.\n# Ejemplo para los valores:\na = 10; b = 5\nif a > b:\n    print(\"a es mayor que b\")\nelif a < b:\n    print(\"a es menor que b\")\nelse:\n    print(\"a es igual a b\")\n# 2) Estructuras de Bucles: Permite repetir un bloque de código varias veces, mientras se cumpla una condición. FOR, WHILE.\n# Ejemplo para los valores:\n# Bucle For:\nfor i in range(5):\n    print(\"Bucle for:\", i)\n# Bucle While:\nj = 0\nwhile j < 5:\n    print(\"Bucle while:\", j)\n    j += 1\n# 3) Gestion de Excepciones: Permite manejar errores y excepciones que pueden ocurrir durante la ejecución del programa. \n# TRY-EXCEPT.\n# Ejemplo para el valor:\na = int(input(\"Ingrese un número entero: \"))\nb = int(input(\"Ingrese otro número entero: \"))\ntry:\n    c = a / b \n    print(\"Resultado de la división:\", c)\nexcept ZeroDivisionError:\n    print(\"Error: División por cero no permitida.\")\n# 4) Otros elementos importantes.\n# Ejemplo para el valor:\n# Operador break\ncadena = 'Python'\nfor letra in cadena:\n    if letra == 'h':\n        print(\"Se encontró la h\")\n        break\n    print(letra)\n# Operador continue\nx = 5\nwhile x > 0:\n    x -= 1\n    if x == 3:\n        continue\n    print(x)\n# Operador pass\nfor i in range(10):\n      if i == 5:\n          pass # Se omite la acción en la iteración 5\n      else:\n          print(i)\n#Operador range\nfor i in range(6):\n    print(i) #0, 1, 2, 3, 4, 5\n'''* DIFICULTAD EXTRA (opcional): Crea un programa que imprima por consola todos los números comprendidos entre 10 y 55 \n(incluidos), pares, y que no son ni el 16,ni múltiplos de 3. \nSeguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.'''\n# Respuesta en bruto\nlista_0 = list(range(10, 56)) # crear lista de 10 a 55\nprint(lista_0)\nlista_1 = [] # lista de números pares\nfor i in (lista_0):\n    if ((-1)**i) > 0: lista_1.append(i)\nprint(lista_1)\nfor i in (lista_1): # eliminar múltiplos de 3\n    if i % 3 == 0:\n        lista_1.remove(i)\nprint(lista_1)\nfor i in (lista_1): # eliminar 16\n    if i == 16:\n        lista_1.remove(i)\nprint(lista_1)\n# Respuesta un poco más elegante.\nlista_0 = list(range(10, 56)) # crear lista de 10 a 55\nlista_1 = [] # lista de números pares\nfor i in (lista_0): # agrega números pares\n    if ((-1)**i) > 0: lista_1.append(i)\nfor i in (lista_1): # eliminar múltiplos de 3\n    if i % 3 == 0: lista_1.remove(i)\nfor i in (lista_1): # eliminar numero 16\n    if i == 16: lista_1.remove(i)\nprint(lista_1)\n# Respuesta más elegante y eficiente, por Mouredev.!!! Me falta calle :-)!!!\nfor number in range(10, 56): # imprimir números pares, no 16, no múltiplos de 3\n    if ((-1)**number) > 0 and number != 16 and number % 3 != 0:\n        print(number)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Paprikaistkrieg.py",
    "content": "\n\n#Operadores\n\n\n#operadores aritmeticos\n\n#suma\nfrom test._test_multiprocessing import exception_throwing_generator\n\n\nsum = 5 + 2\nprint(f\"Sum: 5 + 2 = {sum}\")\nprint(f\"Sum: 5 + 2 = {(5 + 2)}\")\n\n#resta\nSubtraction = 5 - 2\nprint(f\"Subtraction: 5 - 2 = {Subtraction}\")\nprint(f\"Subtraction: 5 - 2 = {(5 - 2)}\")\n\n\n#multiplicación\nMultiplication = 5 * 2\nprint(f\"Multiplication: 5 * 2 = {Multiplication}\")\nprint(f\"Multiplication: 5 * 2 = {(5 * 2)}\")\n\n#división\nDivision = 5 / 2\nprint(f\"Division: 5 / 2 = {Division}\")\nprint(f\"division: 5 / 2 = {(5 / 2)}\")\n\n#modulo\nModulo = 5 % 2\nprint(f\"modulo: 5 % 2 = {Modulo}\")\nprint(f\"modulo: 5 % 2 = {(5 % 2)}\")\n\n#potencia\nPower = 5 ** 2\nprint(f\"potencia: 5 ** 2 = {Power}\")\nprint(f\"potencia: 5 ** 2 = {(5 ** 2)}\") \n\n#exponente\nExponent = 5 // 2\nprint(f\"Exponent: 5 ** 2 = {Exponent}\")\nprint(f\"Exponent: 5 ** 2 = {(5 ** 2)}\")\n\n#division entera\nIntegerDivision = 5 // 2\nprint(f\"Integer Division: 5 // 2 = {IntegerDivision}\")\nprint(f\"Integer Division: 5 // 2 = {(5 // 2)}\")\n\n#operadores de comparacion\n\n\"\"\"\nAunque se represente con números,\nes posible comparar variables, cadenas de texto, listas, etc.\n\"\"\"\n\n#igual\nEqual = 5 == 2\nprint(f\"Equal: 5 == 2 = {Equal}\") \nprint(f\"Equal: 5 == 2 = {(5 == 2)}\")\n\n#diferente\nDifferent = 5 != 2\nprint(f\"Different: 5 != 2 = {Different}\")\nprint(f\"Different: 5 != 2 = {(5 != 2)}\")\n\n#mayor que\nGreaterThan = 5 > 2\nprint(f\"Greater Than: 5 > 2 = {GreaterThan}\")\nprint(f\"Greater Than: 5 > 2 = {(5 > 2)}\")   \n\n#menor que\nLessThan = 5 < 2\nprint(f\"Less Than: 5 < 2 = {LessThan}\")\nprint(f\"Less Than: 5 < 2 = {(5 < 2)}\")\n\n#mayor o igual que\nGreaterThanOrEqual = 5 >= 2\nprint(f\"Greater Than or Equal: 5 >= 2 = {GreaterThanOrEqual}\")\nprint(f\"Greater Than or Equal: 5 >= 2 = {(5 >= 2)}\")    \n\n#menor o igual que\nLessThanOrEqual = 5 <= 2\nprint(f\"Less Than or Equal: 5 <= 2 = {LessThanOrEqual}\")\nprint(f\"Less Than or Equal: 5 <= 2 = {(5 <= 2)}\")\n\n#operadores logicos \n\n\"\"\"Los operadores lógicos se utilizan para combinar condiciones y evaluar expresiones booleanas.\nLos operadores lógicos más comunes son and, or y not.\"\"\"\n\n#and (dos condiciones deben ser iguales o verdaderas  para que se cumpla la condicion)\n\nAnd = (5 > 2) and (2 < 3)\nprint(f\"And: (5 > 2) and (2 < 3) = {And}\")\nprint(f\"And: (5 > 2) and (2 < 3) = {((5 > 2) and (2 < 3))}\")\n\n#or  (al menos una condicion debe ser verdadera para que se cumpla la condicion)\n\nOr = (5 > 2) or (2 < 3)\nprint(f\"Or: (5 > 2) or (2 < 3) = {Or}\")\nprint(f\"Or: (5 > 2) or (2 < 3) = {((5 > 2) or (2 < 3))}\")\n \n#not (invierte el resultado de la condicion)    \n\nNot = not (5 > 2)\nprint(f\"Not: not (5 > 2) = {Not}\")\nprint(f\"Not: not (5 > 2) = {(not (5 > 2))}\")\n\n#operadores de asignación\n\n\"\"\"Los operadores de asignación se utilizan para asignar valores a variables.\nEl operador de asignación más común es el signo igual (=), pero también existen otros operadores que combinan la asignación con una operación aritmética.\"\"\"\n\n#asignación\n#asignación simple\n#asigna el valor especificado a la variable y esta asignacion se representa con el signo igual (=)\n\nmy_variable = 7\nprint(my_variable)\n\n#asignación con suma\n#le suma a la variable el valor especificado \n\nmy_variable += 3\nprint(my_variable)\n\n#asignación con resta\n#le resta a la variable el valor especificado\n\nmy_variable -= 3\nprint(my_variable)\n\n#asignación con multiplicación\n#le multiplica a la variable el valor especificado\n\nmy_variable *= 2\nprint(my_variable)  \n\n#asignación con división\n#le divide a la variable el valor especificado\nmy_variable /= 2\nprint(my_variable)\n\n#asignación con módulo\n#le aplica el módulo a la variable con el valor especificado\nmy_variable %= 3\nprint(my_variable)\n\n#asignación con potencia\nmy_variable **= 2\nprint(my_variable)  \n\n#asignación con división entera\nmy_variable //= 2\nprint(my_variable)\n\n#asignación con exponente\nmy_variable **= 2\nprint(my_variable)\n\n#operadores de identidad\n\n\"\"\"Los operadores de identidad se utilizan para comparar objetos y verificar si son el mismo objeto en memoria.\nLos operadores de identidad más comunes son is e is not.\"\"\"\n\n\nmynewvariable = my_variable\n\n\n#is (verifica si dos objetos son el mismo objeto en memoria) (no solo compara el valor, sino si son el mismo objeto en memoria)\n\n\n\nprint(f\"is: my_variable is mynewvariable = {my_variable is mynewvariable}\")\n\n\n#is not (verifica si dos objetos no son el mismo objeto en memoria) (no solo compara si son mismo el valor, sino si no son el mismo objeto en memoria)\n\nprint(f\"is not: my_variable is not mynewvariable = {(my_variable is not mynewvariable)}\")\n\n\n#operadores de pertenencia\n\n\"\"\"Los operadores de pertenencia se utilizan para verificar si un valor está presente en una secuencia, como una lista, tupla o cadena de texto.\nLos operadores de pertenencia más comunes son in y not in.\"\"\"   \n\n#in (verifica si un valor está presente en una secuencia)\n\nmy_list = [1, 2, 3, 4, 5]\nprint(f\"in: 3 in my_list = {3 in my_list}\")  \n\n#not in (verifica si un valor no está presente en una secuencia)\nprint(f\"not in: 7  not in my_list = {7 not in my_list}\")\n\n# Ejemplo con combinación de operadores lógicos\nprint(f\"Ejemplo: (3 in my_list) and (6 not in my_list) = {(3 in my_list) and (6 not in my_list)}\")\n\n#operadores de bits\n\n\"\"\"Los operadores de bits se utilizan para realizar operaciones a nivel de bits en números enteros.\nLos operadores de bits más comunes son &, |, ^, ~, << y >>.\"\"\"\n\n\n\n\na = 10 #1010\nb = 3  #0011\n\n# AND bit a bit\nbitwise_and =  10  & 3\nprint(f\"Bitwise AND: 10 & 3 = {bitwise_and}\") \n\n\"\"\"lo opera en binario comparando los valores en este formato, por ejemplo en este caso seria\n1010\n0011\n----\n0010 = 2 en decimal\"\"\"\n\n# OR bit a bit\nbitwise_or = 10 | 3\nprint(f\"Bitwise OR: 10 | 3 = {bitwise_or}\")\n\n\"\"\"Tambien comparará bit a bit y si al menos uno de los valoes es 1 dará a a 1, por ejemplo\n 1010\n 0011\n ----\n 1011 = 11 en decimal\"\"\"\n\n\n# XOR bit a bit\nbitwise_xor = 10 ^ 3\nprint(f\"Bitwise XOR: 10 ^ 3 = {bitwise_xor}\")\n\n\"\"\" Tambien los comparará pero solo si son diferentes el resultado será 1 ny si no lo son será 0\n1010\n0011\n----\n1001 en decimal 9\"\"\"\n\n# NOT bit a bit\nbitwise_not = ~10\nprint(f\"Bitwise NOT: ~10 = {bitwise_not}\")   \n\n\"\"\" Este los que realizará será invertir todos los bits de los numeros que comparará, negando bit a bipor asi decirlo\n\n00001010\n(~10): = -(10 + 1) = \n1010\n----\n0101 lo que sería -11 en decimal \"\"\"\n\n#Desplazamiento a la derecha (>>)\nright_shift = 10 >> 2\nprint(f\"right shift: 10 >> 2 = {right_shift}\")  \n\n\"\"\"lo que hará sera dezplazar todos los bits a la derecha, por ejemplo\n1010\n>>>>\n0010 = 2 en decimal (10//2² = 2.5 pero como se manejan enteros al usar este tipo de operadores pasa a ser = 2)\n\"\"\"\n\n #Desplazamiento a la izquierda (<<)\nleft_shift = 10 << 2\nprint(f\"left shift: 10 << 2 = {left_shift}\")  \n\n\n\"\"\"lo que hará sera desplazar a la izquierda todos los bits por ejemplo\n1010\n<<<<\n101000 = 40 en decimal (10**2² = 40 )\"\"\"\n\n#the end of operators\n\n#Estructuras de control\n\n\"\"\"Las estructuras de control son bloques de código que permiten tomar decisiones y ejecutar diferentes acciones según ciertas condiciones. \nLas estructuras de control más comunes son las condicionales (if, elif, else) y los bucles (for, while).\"\"\"\n\n\"\"\"Estructuras de control condicionales;\nestas estructuras de control condicionales permiten ejecutar bloques de código basados en condiciones específicas.\"\"\"\n\n\n#Condicional if\n\n\"\"\"La estructura if evalúa una condición y ejecuta un bloque de código si la condición es verdadera.\"\"\"\n\n#la condicional elif \n\n\"\"\"evalúa si una condición es verdadera y, si lo es, ejecuta el bloque de código indentado debajo de ella.\"\"\"\n\n#la condicional else\n\"\"\"else se ejecuta si ninguna de las condiciones anteriores es verdadera.\"\"\"\n\nmy_string = \"Kriptum\"\nif my_string == \"Paprika\":\n    print(\"La variable my_string es igual a 'Paprika'\")\nelif my_string == \"Ivan\":\n    print(\"La variable my_string es igual a 'Ivan'\")\nelse:\n    print(\"La variable my_string no es igual a 'Paprika'\")\n\n#Condicionales iterativas\n\n\"\"\"Las estructuras de control iterativas permiten repetir un bloque de código varias veces.\nLas estructuras de control iterativas más comunes son los bucles for y while.\"\"\"\n\n#Bucle for\n\n\"\"\"El bucle for se utiliza para iterar sobre una secuencia (como una lista, tupla o cadena de texto) y ejecutar un bloque de código para cada elemento de la secuencia.\"\"\"\n\nfor i in range(10):\n    print(f\"{i} es un número en el rango de 0 a 9\")\n\n#Bucle while\n\n\"\"\"El bucle while se utiliza para repetir un bloque de código mientras se cumpla una condición.\"\"\"\ni = 0\nwhile i < 10:\n    print(f\"{i} es un número en el rango de 0 a 9\")\n    i += 1\n\n#manejo de excepciones\n\n\"\"\"El manejo de excepciones permite capturar y manejar errores que pueden ocurrir durante la ejecución del código.\nLa estructura try-except se utiliza para manejar excepciones en Python.\"\"\"\n\ntry:\n    result = 10 / 0\nexcept ZeroDivisionError:\n    print(\"Error: La división por cero no es permitida.\")\nexcept:\n    print(\"Error: Ocurrió un error inesperado.\")\nfinally:\n    print(\"This the end of the try-except block.\")\n\n    \"\"\"\n    Posibles errores que puedes capturar con except:\n- ValueError: cuando alguien ingresa texto en vez de un número\n- TypeError: si haces operaciones incompatibles\n- KeyError: al acceder a un diccionario con una clave que no existe\n- IndexError: al acceder a una posición inválida en una lista\n- ZeroDivisionError: si hay división entre cero\n- FileNotFoundError: al trabajar con archivos que no existen\n- Exception: para capturar errores generales que no anticipaste\n- ImportError: al intentar importar un módulo que no existe\n\"\"\"\n\n\n\n\n\n#Fin de las estructuras de control\n\n\n\n\n\n#ejercicio extra\n\n\"\"\"\nCrea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n \"\"\"\n\nfor ejercicio_extra in range(10, 56):\n    if ejercicio_extra % 2 == 0 and ejercicio_extra != 16 and ejercicio_extra % 3 != 0:\n        print(ejercicio_extra)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/PatricKFER99.py",
    "content": "def demostrar_operadores():\n    print(\"\\n--- 1. OPERADORES ---\")\n    \n    # Aritméticos\n    a, b = 10, 3\n    print(f\"Aritméticos (10 y 3): Suma={a+b}, Resta={a-b}, Mult={a*b}, Div={a/b:.2f}, Módulo={a%b}, Exp={a**b}, Div.Entera={a//b}\")\n\n    # Comparación\n    print(f\"Comparación: 10 > 3 es {10 > 3}, 10 == 10 es {10 == 10}, 10 != 3 es {10 != 3}\")\n\n    # Lógicos\n    print(f\"Lógicos: (True and False) es {True and False}, (True or False) es {True or False}, not True es {not True}\")\n\n    # Asignación (Mostrando el cambio)\n    x = 5\n    print(f\"Asignación original: x={x}\")\n    x += 5  # x = x + 5\n    print(f\"Asignación compuesta (x+=5): x={x}\")\n\n    # Identidad (is vs ==) -> ¡Ojo aquí, importante en Python!\n    lista_1 = [1, 2, 3]\n    lista_2 = [1, 2, 3]\n    lista_3 = lista_1\n    print(f\"Identidad (is): lista_1 is lista_2? {lista_1 is lista_2} (Son objetos distintos en memoria)\")\n    print(f\"Igualdad (==): lista_1 == lista_2? {lista_1 == lista_2} (Tienen el mismo contenido)\")\n    print(f\"Identidad (is): lista_1 is lista_3? {lista_1 is lista_3} (Apuntan al mismo espacio de memoria)\")\n\n    # Pertenencia\n    fruta = \"Manzana\"\n    print(f\"Pertenencia: 'z' in 'Manzana'? {'z' in fruta}\")\n\n    # BITS (Muy importante para Ciberseguridad y redes)\n    # 10 en binario es 1010\n    # 3  en binario es 0011\n    print(f\"Bits AND (10 & 3): {10 & 3} (Binario: 0010)\") \n    print(f\"Bits OR  (10 | 3): {10 | 3} (Binario: 1011)\")\n    print(f\"Bits XOR (10 ^ 3): {10 ^ 3} (Binario: 1001)\") # XOR es clave en criptografía\n\n\ndef demostrar_estructuras_control():\n    print(\"\\n--- 2. ESTRUCTURAS DE CONTROL ---\")\n\n    # Condicionales\n    user_role = \"admin\"\n    if user_role == \"admin\":\n        print(\"Condicional: Acceso total concedido (Admin).\")\n    elif user_role == \"user\":\n        print(\"Condicional: Acceso limitado.\")\n    else:\n        print(\"Condicional: Acceso denegado.\")\n\n    # Iterativa (Bucle For)\n    print(\"Iterativa For:\", end=\" \")\n    for i in range(1, 4):\n        print(f\"Intento {i}...\", end=\" \")\n    print(\"Conectado.\")\n\n    # Iterativa (Bucle While)\n    contador = 3\n    print(\"Iterativa While (Cuenta regresiva):\", end=\" \")\n    while contador > 0:\n        print(contador, end=\"..\")\n        contador -= 1\n    print(\"¡Boom!\")\n\n    # Excepciones (Try - Except - Finally)\n    # Esto es vital para manejar errores sin que el programa colapse\n    print(\"Excepciones:\", end=\" \")\n    try:\n        resultado = 10 / 0\n    except ZeroDivisionError:\n        print(\"¡Error! No puedes dividir por cero (Capturado correctamente).\")\n    finally:\n        print(\"Este bloque 'finally' se ejecuta siempre, haya error o no.\")\n\n\ndef reto_extra():\n    print(\"\\n--- 3. DIFICULTAD EXTRA (Filtrado de números) ---\")\n    \n    # Solución \"Pythonica\" usando List Comprehension (En una sola línea)\n    # Rango: 10 a 55 (inclusive, por eso range va hasta 56)\n    numeros_filtrados = [\n        n for n in range(10, 56) \n        if n % 2 == 0          # Que sea par\n        and n != 16            # Que no sea 16\n        and n % 3 != 0         # Que no sea múltiplo de 3\n    ]\n    \n    print(f\"Números resultantes: {numeros_filtrados}\")\n\n\n# --- EJECUCIÓN DEL PROGRAMA PRINCIPAL (Entry Point) ---\nif __name__ == \"__main__\":\n    demostrar_operadores()\n    demostrar_estructuras_control()\n    reto_extra()"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Paula2409.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n \"\"\"\ndef operate():\n    print(f'''\n    *******BIENVENIDO*******\n    1. Sumar\n    2. Restar\n    3. Multiplicar\n    4. Dividir\n    5. Comparar\n    6. Bits\n    7. Numeros divisibles por numero determinado\n    8. Salir''')\n    option = int(input('Ingrese una opcion para operar: '))    \n    while True:\n        try:\n            while option != 8:\n                a = int(input('Primer numero: '))\n                b = int(input('Segundo numero: '))\n                \n                if option == 1:\n                    print(f'La suma de los numeros es: {a+b}')\n                \n                if option == 2:\n                    print(f'La resta de los numeros es: {a-b}')\n                \n                if option == 3:\n                    print(f'El producto de los numeros es: {a*b}')\n                    \n                if option == 4:\n                    try:\n                        print(f'La division de los numeros es: {a/b}')\n                    except ZeroDivisionError:\n                        print('El segundo numero no puede ser 0')\n                \n                if option == 5:\n                    if a == b:\n                        print(f'Los datos ingresados son iguales')\n                    if a < b:\n                        print(f'{a} es menor a {b}')\n                    if a > b:\n                        print(f'{b} es menor a {a}') \n                \n                if option == 6:\n                    print(f'Operador or &: {a & b}')\n                    print(f'Operador and |: {a|b}')\n                    print(f'Operador xor ^: {a ^ b}')\n                    print(f'Operador >>: {a >> b}')\n                    \n                if option == 7:\n                    range_number = int(input('Que rango desea usar?: '))\n                    a_even,b_even = 0,0\n                    for num in range(1,range_number):\n                        if num % a == 0:\n                            a_even += 1\n                        if num % b == 0:\n                            b_even += 1\n                    print(f'Los numeros divisibles por el primer numero ({a}) son {a_even} ')\n                    print(f'Los numeros divisibles por el segundo numero ({b}) son {b_even} ')\n                    \n                option = int(input('Ingrese una opcion para operar: '))\n\n        except ValueError:\n            print('Ingrese numeros para operar')\n            option = int(input('Ingrese una opcion para operar: '))\n        else:\n            print('Muchas Gracias')\n            break    \n\ndef print_numbers():\n    print('Los numeros son: ')\n    for number in range(10,56):\n        if number % 2 == 0 and number != 16 and number % 3 != 0:\n            print(number)\n\nprint_numbers()\noperate()\n\n               \n    \n    "
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/PedroJOG.py",
    "content": "#Operadores aritméticos\nnum1 = 4\nnum2 = 3\nsuma = num1 + num2\nresta = num1 - num2\nproducto = num1 * num2\ndivision = num1 / num2\ndivision_entero = num1 // num2\nresto = num1 % num2\npotencia = num1 ** num2\n\nprint(f\"Suma: {suma}, Resta: {resta}, Producto: {producto}, División: {division}, División entero: {division_entero}, Resto: {resto}, Potencia: {potencia}\")\n\n#Operadores relacionales\nmayor_que = num1 > num2\nmenor_que = num1 < num2\nigual_a = num1 == num2\nmayor_o_igual = num1 >= num2\nmenor_o_igual = num1 <= num2\ndiferente_de = num1 != num2\n\nprint(f\"Mayor que: {mayor_que}, Menor que: {menor_que}, Igual a: {igual_a}, Mayor o igual que: {mayor_o_igual}, Menor o igual que: {menor_o_igual}, Diferente de: {diferente_de}\")\n\n#Operadores de asignación\nnum3 = 4\nnum3 += 8   #Equivalencia: num1 = num1 + 8\nprint(num3)\nnum3 -= 8   #Equivalencia: num1 = num1 - 8\nprint(num3)\nnum3 *= 8   #Equivalencia: num1 = num1 * 8\nprint(num3)\nnum3 **= 8   #Equivalencia: num1 = num1 ** 8\nprint(num3)\nnum3 /= 8   #Equivalencia: num1 = num1 / 8\nprint(num3)\nnum3 //= 8   #Equivalencia: num1 = num1 // 8\nprint(num3)\nnum3 %= 8   #Equivalencia: num1 = num1 % 8\nprint(num3)\n\n#Operadores lógicos\nprint(f\"5 < 8 and 8 > 3 es: {5 < 8 and 8 > 3}\")\nprint(f\"4 > 3 or 2 > 9 es: {4 > 3 or 2 > 9}\")\nprint(f\"5 > 6 es: {not 5 > 6}\")\n\n#Operadores de pertenencia\nprint(f\"in: 'a' in 'hola' es {'a' in 'hola'}\") #True\nprint(f\"not in: 'a' not in 'hola' es {'a' not in 'hola'}\") #False\n\n#Operadores de identidad\nmi_variable = 10 \nprint(id(mi_variable)) #4372070928\ntu_variable = 10\nprint(id(tu_variable)) #4372070928\n\nprint(f\"is: mi_variable is tu_variable es {mi_variable is tu_variable}\") #True\nprint(f\"is not: mi_variable is not tu_variable es {mi_variable is not tu_variable}\") #False\n\n#Operador nivel de Bit\n  ##operador and &: comparamos todos los bits uno a uno, y, si están los dos a 1, entonces sería 1; si alguno de los dos valores está a 0, sería 0.\nnumero = 20\nnumero_bin = 0b10100\n\nnumero_dos = 22\nnumero_dos_bin = 0b10110\n\nprint(bin(numero & numero_dos)) ## 0b10100\n\n  #operador or |: comparamos todos los bits uno a uno, y, si está alguno de los dos a 1, entonces sería 1; y si no está ninguno, es 0.\n\nprint(bin(numero | numero_dos)) ## 0b10110\n\n  #operador not ~ invierte cada bit en el operando. El bit que tiene como valor 1 lo pone a 0, y al contrario.\n\nprint(bin(~numero)) ## -ob10101\n\n  #operador xor ^ devuelve los bits que estén a 1 no comunes en los dos operandos.\n\nprint(bin(numero ^ numero_dos)) ##^0b10\n\n  #operador shift >> ó << se utiliza para mover bits hacia la derecha ó izquierda. Hacen falta dos parámetros para indicarle primero qué vamos a desplazar y después el número de posiciones que lo desplazaremos.\n\nprint(bin(numero >> 2)) ##ob101\nprint(bin(numero << 2)) ##ob1010000\n\n## Estructuras de control\n\n  # if  =>  condicional\ncolor = \"azul\"\n\nif color == \"azul\":\n  print(\"Hace frio en la calle\")\nelif color == \"rojo\":\n  print(\"Hace calor en la calle\")\nelse:\n  print(\"No hace ni frío ni calor\")\n\n  # for => iterativa\n\ncadena = 'Sevilla'\n\nfor i in cadena:\n  print(i)\n\n  # while => iterativa\n\nnumero = 1\nwhile numero < 6:\n  print('hola mundo')\n  numero = numero + 1\n\n  # Manejo de excepciones\ntry:\n  print('No hay error')\nexcept TypeError:\n  print(f'Encontré este error: {TypeError}')\nfinally:\n  print('Siempre se ejecuta')\n\n### EXTRA ###\n\nfor a in range(10, 56):\n  if a % 2 == 0 and a != 16 and a % 3 != 0:\n    print(a)\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Pipe281.py",
    "content": "#01 OPERADORES Y ESTRUCTURAS DE CONTROL\n\n#Aritmeticos\nedad = 2024 - 1990\ningreso_anual = 500000 * 12 \na = 10 + 5\nb = 10 * 5\nc = 12 / 5\nd = 16 % 5 #Residuo\ne = 16 ** 5 #Potencia\nf = 16 // 5 # División con numeros enteros \n\n\n#Lógicos + Comparación\nif edad >= 18 and  ingreso_anual >=  30000000:\n    print(\"Tu sueldo alcanza para realizar un prestamo\")\nelse:\n    print(\"Tu sueldo NO alcanza para realizar un prestamo, muy pobre, Lo siento 8(\")\n\nif edad >= 18 or ingreso_anual >=  3000000:\n    print(\"Tu sueldo alcanza para realizar un prestamo\")\nelse:\n    print(\"Tu sueldo NO alcanza para realizar un prestamo, muy pobre, Lo siento 8(\")\n\nusuario_autenticado = False\n\nif not usuario_autenticado:\n    print(\"Acceso denegado. Debes iniciar sesión.\")\nelse:\n    print(\"¡Bienvenido!\")\n\n# Asignación (Toma los valores ingresados mas arriba y los calcula)\nedad = 33\na += 5\nb -= 5\nc *= 5    \nd /= 5\n\n#Operadores de Identidad\na = 10\nb = 20\nc = 10\n\nprint(a is b) # Muestra False\nprint(a is c) # Muestra True\nprint(a is not b) # Muestra True\n\n#Operadores Pertenencia\na = [1,2,3,4,5]\n\nprint(2 in a) # Muestra True\nprint(6 in a) # Muestra False\nprint(6 not in a) # Muestra True\n\n#Operadores Bit a Bit\n\"No los entiendo\"\n\n#Ejemplos\na = [b, c, d, e]\nfor numeros in a:\n    print(numeros)\n\nfor a in range():\n    print(a)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Print-Alan.py",
    "content": "\"\"\"Operadores y estructuras de control\"\"\"\n\n#Operadores aritméticos\n\na = 3\nb = 5\nsuma = a + b\nresta = a - b\nmultiplicacion = a * b\nDivision = a / b\nModulo = a % b\nExponenciacion = a ** b\nDivicion_entera = a // b\n\n#Operadores logicos\n\n#Operadores de comparación\n\n#Operadores de asignación\n\n#Operadores de identidad\n\n#Operadores de pertenencia\n\n#Operadores de bits\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/PyTorDev.py",
    "content": "'''\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n '''\n  # Operadores\n#Operadores de Asignación\nx = 1\na = 1\nb = 3\nx += 1\nx -= 1\n# Y así con todos los operadores aritmeticós\n\n#Operadores Aritmeticós\n\na + b\na - b\na * b\na ** b\na / b\na // b\na % b\n\n# Operadores de comparación\na == b\na != b\na < b\na > b\na <= b\na >= b\n\n# Operadores lógicos\na and b\na or b\nnot b\n\n# Operadores de Bitwise\na & b\na | b\na ^ b\n~ b\na << b\na >> b\n\n# Operadores de pertenencia\n\n'a' in 'avion'\n'a' not in 'vision'\n\n# Operadores de Identidad\n\na is b\na is not b\n\n# Operador ternario\n\na = a if a > b else b\n\n\n  # Estructuras de control\nnum = 5\n#Condicionales\n\n#if\nif num > 0:\n  print('Es positivo')\n\n#if-else\nif num % 2 == 0:\n  print('Par')\nelse: print('Impar')\n\n#if_elif_else\nif num > 0:\n  print('Es positivo')\nelif num == 0:\n  print('Es cero')\nelse:\n  print('Es negativo')\n\n#Iterativas\n\n#for\nfor i in range(3):\n  print(i)\n\n#while\ni = 0\nwhile i < 3:\n   print(i)\n   i += 1\n\n# Variaciónes de estas estructuras\n# Break\nfor i in range(5):\n  if i == 3:\n    break\n  print(i) \n\n# Continue\nfor i in range(5):\n  if i == 2:\n    continue\n  print(i)\n\n#else con for\nfor i in range(3):\n  print(i)\nelse:\n  print('Bucle completado')\n\n#else con while\nwhile i < 3:\n  print(i)\n  i += 1\nelse:\n  print('Bucle completado')\n\n#Excepciones\n#try-except\ntry:\n  x = 1 / 0\nexcept ZeroDivisionError as e:\n  print('No se puede dividir por cero')\n\n#try-except-else\ntry:\n  x = 10 / 2\nexcept ZeroDivisionError:\n  print('Error')\nelse:\n  print('EL calculo salio bien')\n\n#try-except-finaly\ntry:\n  x = 10 / 0\nexcept:\n  print(\"Error\")\nfinally:\n  print('Esto se ejecuta en cualquier caso')\n\n#Ejerccio extra\n\ndef imprimir_numeros():\n  for i in range(10, 55):\n    if i % 2 == 0:\n      if i != 16 and i % 3 != 0:\n        print(i)\n    \n\nimprimir_numeros()"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Rafapg93.py",
    "content": "#Reto 01\n\n#Ejemplos con todos los tipos de operadores:\n    # Operadores aritméticos\na = 10\nb = 4\n#Suma\nsum = a + b\nprint(sum)\n#Resta\nrest = a - b\nprint(rest)\n#División\ndiv = a / b\nprint(div)\n#Multiplicación\nmulti = a * b\nprint(multi)\n#Modulo entre operandos (obtiene el resto de la división)\nmodulo = a % b\nprint(modulo)\n#Potencia de operandos\npot = a ** b\nprint(pot)\n#División con resultado de número entero\ndivent = a // b\nprint(divent)\n\n    #Operadores de comparación (devuelven valor booleano)\n#Mayor que\nmayorque = a > b\nprint(mayorque)\n#Menor que\nmenorque = a < b\nprint(menorque)\n#Igual\nigual = a == b\nprint(igual)\n#Mayor o igual que\nmoique = a >= b\nprint(moique)\n#Menor o igual que\nmeoique = a <= b\nprint(meoique)\n#Diferente\ndif = a != b\nprint(dif)\n\n    #Operadores Bit a bit\nc = 2\nd = 3\ne = 2\n# & Realiza bit a bit la operación AND en los operandos: c & d = 2 (binario = 10 & 11 = 10)\nbitand = c & d\nprint(bitand)\n# | Realiza bit a bit la operación OR en los operandos: c | d = 3  (binario = 10 | 11 = 11)\nbitor = c | d\nprint(bitor)\n# ^ Realiza bit a bit la operación XOR en los operandos: c ^ d = 2  (binario = 10 ^ 11 = 01)\nbitxor = c ^ d\nprint(bitxor)\n# ~ Realiza bit a bit la operación NOT. Invierte cada bit en el operando: ~e = -3 (Binario: ~(00000010) = (11111101))\nbitnot = ~e \nprint(bitnot)\n# >> Desplaza los bits del operador de la izquierda a la derecha tantos bits como indica el operador de la derecha: c >> d = 0 (Binario: 00000010 >> 00000011 = 0)\nbitdespder = c >> d\nprint(bitdespder)\n# << Desplaza los bits del operador de la izquierda a la izquierda tantos bits como indica el operador de la derecha: c << d = 16 (Binario: 00000010 << 00000011 = 00001000)\nbitdespizq = c << d \nprint(bitdespizq)\n\n    #Operadores de asignación\n\"\"\" Se utilizan para asignar valores a una variable, generalmente se combina con otros poeradores\ndonde la operación se realiza en los operandos y el resultado se asigna al operando irquierdo.  \n\"\"\"\n\na = 18 # = asigna el valor a la variable\nprint(a)\na += 10 # += es equivalente a a = a + 10\nprint(a)\na -= 5 # -= es equivalente a a = a - 5\nprint(a)\na *= 3 # *= es equivalente a a = a * 3\nprint(a)\na /= 3 # /= es equivalente a a = a / 3\nprint(a)\na %= 3 # %= es equivalente a a = a % 3\nprint(a)\na **= 3 # **= es equivalente a a = a ** 3\nprint(a)\na //= 3 # //= es equivalente a a = a // 3\nprint(a)\na &= 5 # &= es equivalente a a = a & 3\na |= 3 # |= es equivalente a a = a | 3\na ^= 3 # ^= es equivalente a a = a ^ 3\na >>= 3 # >>= es equivalente a a = a >> 3\na <<= 3 # <<= es equivalente a a = a << 3\n\n    #Operadores lógicos\n\"\"\" Se utilizan para tomar una decisión basada en múltiples condiciones\n\"\"\"\ng = True\nh = True\ni = False\n# AND - Devuelve True si ambos operandos son True\nland = g and h\n# OR - Devuelve True si alguno de los operandos es True\nlor = g or i\n# NOT - Devuelve True si alguno de los operandos es False\nlnot = not h\n\n    #Operadores de pertenencia\n\"\"\" Se emplean para identificar pertenencia en alguna secuencia (listas, strings, tuplas)\n\"\"\"\nlista = [1,2,3,4,5]\n\n# in devuelve True si el valor especificado se encuentra en la secuencia, en caso contrario devuelve False.\nprint(4 in lista)\n\n# not in devuelve True si el valor especificado no se encuentra en la secuencia, en caso contrario devuelve False.\nprint(6 not in lista)\n\n    #Operadores de identidad\n\"\"\" Se utilizan para comprobar si dos variables son, o no, el mismo objeto\n\"\"\"\nx = 4\ny = 2\nlista2 = [1, 5]\n# is devuelve True si ambos operandos hacen referencia al mismo objeto, False en caso contrario\n# is not devuelve True si ambos operandos no hacen referencia al mismo objeto, False en caso contrario\nprint(x is 4)\nprint(x is y)\nprint(x is not lista2)\n\n# Ejemplos de estructura condicional\nedadlegal = 18\nfechaactual = 2024\nfechanacimiento = input(\"Introduce tu año de nacimiento:\")\nfechanacimiento = int(fechanacimiento)\n\n# IF - elif - else\nif fechaactual - fechanacimiento < edadlegal:\n    print(\"No tienes acceso, eres menor de edad\")\nelif fechaactual - fechanacimiento == edadlegal:\n    print(\"Acceso autorizado, felicidades por tus 18\")\nelse:\n    print(\"Acceso autorizado\")\n\n# While\nhora = 0\nhoradescuento = 12\n\nwhile hora < horadescuento:\n    print(\"Aun no es la hora feliz! Faltan \",horadescuento - hora,\" horas\")\n    hora = input(\"¿Que hora es?\")\n    hora = int(hora)\n    \n# For \nfor numero in range(1, 10):\n    print(numero)\n\n# OPCIONAL - programa que imprime los números comprendidos entre 10 y 55, pares, que no sean 16 ni múltiplos de 3.\n    \nfor numero in range(10, 56):\n    if numero % 2 == 0 and numero != 16 and numero % 3 != 0:         \n        print(numero)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Ramirofordev.py",
    "content": "# Operadores\n\n# Operadores aritmeticos \n\nprint(f\"La suma de 5 + 2 es {5 + 2}\")\nprint(f\"La resta de 10 - 10 es {10 - 20}\")\nprint(f\"La multiplicacion de 100 * 20 es {100 * 20}\")\nprint(f\"La division de 70 / 18 es {70 / 18}\")\nprint(f\"El modulo de 5 % 2 es {5 % 2}\")\nprint(f\"Dos al cuadrado es {2**2}\")\nprint(f\"La division por piso de 5 // 10 es {5 // 10}\")\n\n# Operaciones de comparacion\n\nprint(3 > 2)\nprint(2 < 3)\nprint(10 >= 100)\nprint(56 <= 10)\nprint(\"hola\" == \"hola\")\nprint(2 != 3)\n\n# Operadores logicos\nprint(f\"AND &&: 10 + 3 == 13 and 5 - 1 == 4 es {10 + 3 == 13 and 5 - 1 == 4}\")\nprint(f\"OR ||: 5 * 2 == 10 or 5 / 2 == 1 es {5 * 2 == 10 or 5 / 2 == 1}\")\nprint(f\"NOT !: not 10 + 15 == 25 es {not 10 + 15 == 25}\")\n\n# Operaciones de asignacion\na = 5\nprint(a)\na += 10\nprint(a)\na -= 9\nprint(a)\na *= 2\nprint(a)\na /= 3\nprint(a)\na %= 4\nprint(a)\na **= 8\nprint(a)\na //= 5\nprint(a)\n\n# Operadores de identidad\nnew_number = a\nprint(f\"new_number is a es {new_number is a}\")\nprint(f\"new_number is a es {new_number is not a}\")\n\n# Operadores de pertenencia \nnumbers = [1, 2, 3, 4, 5]\nprint(f\"IN: 3 in numbers es {3 in numbers}\")\nprint(f\"NOT IN: 3 not in numbers es {3 not in numbers}\")\n\n# Operadores de bit\na = 10 # 1010\nb = 3 # 0011\nprint(f\"AND: 10 & 3 es {10 & 3}\") # 0010\nprint(f\"OR: 10 | 3 es {10 | 3}\") #  1011\nprint(f\"XOR: 10 ^ 3 es {10 ^ 3}\") # 1001\nprint(f\"NOT: ~10 es {~10}\")\nprint(f\"Desplazamiento a la derecha: 10 >> 2 es {10 >> 2}\")\nprint(f\"Desplazamiento a la izquierda: 10 << 2 es {10 << 2}\")\n\n# Estructuras de control\n\n# Condicionales\n\nage = 18\nif age >= 18: \n    print(\"Felicidades eres mayor de edad.\")\nelif age >= 80:\n    print(\"Felicidades entraste a la etapa final de tu vida\")\nelse:\n    print(\"Eres menor de edad. Felicidades sigues siendo un chaval.\")\n\n# Iterativas\n\nfor i in range(3):\n    print(\"Hola Python!\")\n\nwhile True:\n    r = input(\"Bienvenidos a mi menu: \\n\" \\\n    \"1. Decir hola.\" \\\n    \"2. Salir\")\n    if r == 1:\n        print(\"Hola\")\n    else:\n        break\n\n# Manejo de excepciones\n\ntry:\n    print(10 / 0)\nexcept:\n    print(\"No se puede dividir entre 0\")\nfinally:\n    print(\"Gracias por ejecutarme\")\n\n# Ejercicio opcional\n\nfor i in range(10, 56):\n    if i % 3 != 0 and i != 16 and i % 2 == 0:\n        print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Ramon01-ing.py",
    "content": "\"\"\"\"\nOperadores\n\"\"\"\n# Operadores artiméticos\nop_sum = 2 + 5\nprint(op_sum)\nop_res = 10 - 3\nprint(op_res)\nop_div = 20/10\nprint(op_div)\nop_multiply = 4*5\nprint(op_multiply)\nop_module = 16 % 3\nprint(op_module)\nop_pow = 3**3\nprint(op_pow)\nop_div_int = 35//7\nprint(op_div_int)\n\n#Operadores lógicos\na = 3\nb = 4\n\nop_and = b > a and b >=10\nprint(op_and)\nop_or = a < b or b < 12\nprint(op_or)\nop_not = not a > b\nprint(op_not)\n\n#Operadores de comparación\nb = 10\nc = 30\n\nop_equal = b == c\nprint(op_equal)\nop_menor = c > b\nprint(op_menor)\nop_mayor = b < 30\nprint(op_mayor)\nop_minus_than = c <= b\nprint(op_minus_than)\nop_mayor_than = b >= c\nprint(op_mayor_than)\nop_distinct = b != c\nprint(op_distinct)\n\n# Operadores de asignación\nnum = 35\nnum += 1 #suma y asiganación\nprint(num)\nnum -= 1 # resta y asiganación\nprint(num) \nnum *= 3 # multiplicación y asiganación\nprint(num) \nnum /= 5 # division y asiganación\nprint(num)\nnum %= 10 # modulo y asignación\nprint(num)\nnum **= 3 # potencia y asiganación\nprint(num)\nnum //= 6 # division entera y asiganación\nprint(num)\n\n\"\"\"\"\nEstrcuturas de control\n\"\"\"\n\n# Condicionales\nnumero = 7\nif numero != 350:\n    print(\"No es mi numero favorito\")\nelif numero * 50 == 350:\n    print(\"Ese es mi numero favorito\")\nelse:\n    print(\"Prueba otro numero\")\n\n# Iterativas\nfor i in range(35):\n    if i % 2 == 0:\n        print(\"Es un número par\")\n    else:\n        print(\"Es número impar\")\n\n\ni = 0\nwhile(i<=35):\n    i += 1\n    print(i)\n\n#Excepciones\n\ntry:\n    print(20 / 0)\nexcept:\n    print(\"No se puede realizar esa operación\")\n\n\n\"\"\"\nExtra\n\"\"\"\n\nfor i in range(10,56):\n    if i % 2 == 0 and i % 3 != 0 and i != 16:\n        print(i)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/RgeditV1.py",
    "content": "\"\"\"\nTodos los operadores\n'+' se utiliza para concatenar o sumar variables\n'-' Se utuliza para restar valores\n'*' Se utiliza para multiplicar valores\n'/' Se utiliza para divir valores\n'//' se utiliza para devolver divisiones en entero\n'**' se utiliza para potenciacion\n\"\"\"\nprint(\"OPERADORES ARITMETICOS\")\nsumar = 1+1\nrestar= 2-2\nmultiplicar = 3*3\ndividir = 5/2\npotencia = 5**3\ndivicion_entera = 6//4\n\nprint(f\" sumar: {sumar}\\n restar: {restar}\\n multiplicar: {multiplicar}\\n dividir: {dividir}\\n potencia: {potencia}\\n\",\n      f\"division entera: {divicion_entera}\")\n\n\n\"\"\"Operadores Logicos\n\nTrue or False indican si algo es verdadero o falso\nel operador 'or' indica que si una de las condiciones es verdadera entonces devuelve True\nel operador \"and\" indica que si todas las condiciones es verdadera entonces devuelve True\nel operador \"not\" indica que si es lo contrario a algo entonces devuelve True o False\n\"\"\"\nprint(\"OPERADORES LOGICOS EJEMPLOS\\n\")\nprint(True or False)\n\nprint(not False)\n\nprint(True and False)\n\n\"\"\"Operadores de Comparacion\n< indica si algo es menor que entonces es True\n> si algo es mayor que entonces devuelve True\n<= si algo es menor o igual entonces devuelve True\n>= si algo es mayor o igual entonces devuelve True\n!= si algo es diferente entonces devuelve True\n== si algo es si o si igual entonces devuelve True\n\"\"\"\nprint(\"EJEMPLOS OPERADORES DE COMPARACION\")\nx,y = 5,10\nprint(x < y)\nprint(x > y)\nprint(x <= y)\nprint(x >= y)\nprint(x != y)\nprint(x == y)\n\n\n#Ciclo For en Python\ncount = 12\nfor i in range(1,count+1): #este ciclo hara un conteo hasta el numero en variable count\n    print(i)\n\n#bucle While\ni = 0\nwhile not i > 10: # mientras no sea mayor seguira el bucle\n    print(\"Mouredev gracias por los ejercicios ;)\")\n    i+=1 #aqui la var i incrementa en 1 cada vuelta\nelse:\n    print('Vueltas terminadas')\n\n#Condicionales en python\npe = ['robert','mouredev','Dalto','midudev']\ndulces = 4\n\nif dulces >= len(pe): #si hay mas o la misma cantidad de dulces que personas\n    print('Se han repartido los duces equitativamente')\nelse: # si no es asi entonces\n    print('No quedan tantos dulces, habra que comprar mas')\n\n#Excepciones\n\nwhile True:\n    try: #intenta divir las dos variables\n        num1 = int(input(\"Introduce digito 1: \"))\n        num2 = int(input(\"Introduce digito 2: \"))\n        print(num1/num2)\n        break\n    except ZeroDivisionError: # si se divide por cero imprime\n        print('No se puede dividir por cero\\n')\n    except ValueError: # si se introduce texto entonces imprime\n        print('Solo introduce Digitos\\n')\n\n\n#Dificultad extra completada\n\nfor i in range(10,56,2): #del 10 hasta el 56 multiplicando por 2\n    if not i == 16 and not i%3 == 0: #si no es igual a 16 i no deja residuo cero al divir entre tres entonces\n        print(i)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/RickUbb.py",
    "content": "# Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n# Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n# Aritmeticos\nfrom operator import truediv\n\nmi_suma = 4 + 4\nmi_resta = 4 - 2\nmi_multip = 3 * 3\nmi_div = 10/3\n# 2 elevado a la 4\nmi_expoenciacion = 2**4\n# modulo es lo que sobra de la division\nmi_modulo = 10 % 5\n# Se redondea hacia abajo\nmi_diventera = 10//3\nmi_diventera2 = -10//3\nprint(mi_suma)\nprint(mi_resta)\nprint(mi_multip)\nprint(mi_div)\nprint(mi_expoenciacion)\nprint(mi_modulo)\nprint(mi_diventera)\nprint(mi_diventera2)\n\n# Logicos\n# and\nedad = 18\ntiene_licencia = True\n\nif (edad >= 18 and tiene_licencia == True):\n    print(\"Podeis pasar!\")\n\n# or\nedad = 18\ntiene_licencia = True\n\nif (edad <= 18 or tiene_licencia == False):\n    print(\"No podeis pasar!\")\n\n# not\nedad = 18\ntiene_licencia = True\n\nif not(edad <= 18 or tiene_licencia == False):\n    print(\"No podeis pasar!\")\n\n# De comparación\n# igual a\nif 7 == 7:\n    print(\"Siuu!\")\n\n# diferente de\nif mi_suma != mi_resta:\n    print(\"Not Siuu!\")\n\n# menor\nif mi_suma < mi_resta:\n    print(\"Suma menor\")\nelse:\n    print(\"Resta menor\")\n\n# menor o igual\nif mi_suma <= mi_resta:\n    print(\"Suma menor o igual\")\nelse:\n    print(\"Resta menor y no igual\")\n\n# mayor\nif mi_suma > mi_resta:\n    print(\"Suma mayor\")\nelse:\n    print(\"Resta mayor\")\n\n# mayor o igual\nif mi_suma >= mi_resta:\n    print(\"Suma mayor o igual\")\nelse:\n    print(\"Resta mayor y no igual\")\n\n# is\na = 9\nb = 9\nprint(a is b)\na = [1,2,3]\nb = [1,2,3]\nprint(a is b)\n\nx = None\n\nif x is None:\n    print(\"No tiene valor\")\n\n# in\n# OJO: en diccionarios, in busca en las claves, no en los valores.\nprint(7 in [7, 8, 9])\n\ntexto = \"hola mundo\"\n\nprint(\"hola\" in texto)   # True\nprint(\"z\" in texto)      # False\n\n# De asignacion\n# basico\n# normal =\nmi_variable = 20\nprint(mi_variable)\n\n# suma =\nmi_variable += 2\nprint(mi_variable)\n\n# resta =\nmi_variable -= 2\nprint(mi_variable)\n\n# multp =\nmi_variable *= 2\nprint(mi_variable)\n\n# div =\nmi_variable /= 2\nprint(mi_variable)\n\n# divent =\nmi_variable //= 2\nprint(mi_variable)\n\n# potencia =\nmi_variable **= 2\nprint(mi_variable)\n\n# modulo =\nmi_variable %= 2\nprint(mi_variable)\n\n# Asignacion con bits\n# &= AND bit a bit\nx = 6   # 110\nx &= 3  # 011\nprint(x)  # 2\n\n# |= OR bit a bit\nx = 6   # 110\nx |= 3  # 011\nprint(x)  # 7\n\n# ^= XOR bit a bit\nx = 6   # 110\nx ^= 3  # 011\nprint(x)  # 5\n\n# <<= Shift izquierda (desplazar bits a la izquierda)\n# Es como multiplicar por 2 cada vez que te mueves 1 lugar.\nx = 3      # 011\nx <<= 2    # mueve 1 a la izquierda\nprint(x)   # 12\n\n# >>= Shift derecha (desplazar bits a la derecha)\n# Es como dividir por 2 (entero) cada vez que te mueves 1 lugar.\nx = 24      # 011\nx >>= 2    # mueve 1 a la izquierda\nprint(x)   # 6\n\n# Operador especial := (Walrus operator)\n# Permite asignar valor a variables dentro de if, while, etc\n\nsaludo = \"Hola\"\nif (n := len(saludo) == 4) :\n    print(saludo)\n\n#while (linea := input(\"Escribe algo: \")) != \"\":\n#    print(\"Dijiste:\", linea)\n\n\n# Estructuras de control\n# Condicionales\n#If elif else\nif (2 > 10):\n    print(\"Hola\")\nelif (3 > 10):\n    print(\"Holas\")\nelse:\n    print(\"Hola mundo\")\n\n#Iterativas\n#For\nfor i in range(5):\n    print(i)\n\n\n#While\n\nwhile (i < 10):\n    print(i)\n    i += 1\n\n#break\nfor i in range(10):\n    if i == 5:\n        break\n    print(i)\n\n#continue\nfor i in range(5):\n    if i == 2:\n        continue\n    print(i)\n\nif True:\n    pass\n\n\n# Manejo de exepciones\ntry:\n    x = int(input(\"Ingresa un número: \"))\n    print(10 / x)\nexcept ValueError:\n    print(\"Eso no es un número\")\nexcept ZeroDivisionError:\n    print(\"No se puede dividir para 0\")\nelse:\n    print(\"Todo salió bien ✅\")\nfinally:\n    print(\"Esto siempre se ejecuta\")\n\n\n# Selección múltiple:\nopcion = 2\n\nmatch opcion:\n    case 1:\n        print(\"Crear\")\n    case 2:\n        print(\"Editar\")\n    case 3:\n        print(\"Eliminar\")\n    case _:\n        print(\"Opción inválida\")\n\n\n# Crea un programa que imprima por consola todos los números comprendidos\n# entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\nprint(\"\")\nfor i in range(10 , 55):\n    if (i % 2 == 0 and i >= 10 and i % 3 != 0 and i != 16):\n        print(i)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/RiukAC.py",
    "content": "'''\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.'''\n \n# Operadores aritméticos basicos:\n# Ejemplo de suma de dos numeros enteros\n\nprint(\"operadores aritmeticos:\")\nnum1_int, num2_int = 10, 10\nsuma = num1_int + num2_int\nprint(\"la suma de los dos numeros es: \", suma)\n\n# Ejemplo de resta de dos numero decimales\n\nn1_float, n2_float = 6.55, 1.32\nresta = n1_float - n2_float\nresultado_resta = round(resta, 2) # La funcion round redondea a N decimales la operacion\nprint(\"la resta de los dos numeros es: \", resultado_resta)\n\n# Ejemplo del operador de division \n\nn1_division, n2_division = 5, 3\ndivision = n1_division / n2_division\ndivision = round(division, 2) # La funcion round redondea a N decimales la operacion\nprint(\"la division de los dos numeros es: \", division)\n\n# Ejemplo del operador de multiplicacion\n\nn1_multiplicacion, n2_multiplicacion = 3, 6\nmultiplicacion = n1_multiplicacion * n2_multiplicacion\nprint(\"la multiplicacion de los dos numeros es: \", multiplicacion)\n\n# Operadores logicos\n\nprint(\"operadores logicos:\")\nprint(True and True) # El operador AND devuelve verdad solo cuando ambos son verdad, es decir; true and true is true, false and false is true \nprint(True or False) # El operador OR devuelve verdad cuando uno de los dos es verdad, si ambos son falso devolvera false\nprint(not True) # El operador NOT niega una condicion, es decir; si negamos false devolvera verdadero, si negamos true devolvera false\n\n# Operadores de comparacion\n\nprint(\"operadores de comparacion:\")\nprint(10 > 5) # El simbolo (>) reprensenta si es mayor, es decir; ¿10 es > (mayor) a 5?, si es mayor por lo que devolvera true\nprint(10 < 5) # El simbolo (<) reprensenta si es menor, es decir; ¿10 es < (menor) a 5?, si es menor por lo que devolvera false\nprint(\"mono\" == \"mono\") # El simbolo (==) reprensenta una comparacion, es decir; ¿mono es (==) igual a mono?, como es verdad devolvera true, hay que tener en cuenta que diferencia mayusculas y minusculas\nprint(10 != 10) # El simbolo (!=) reprensenta una diferencia, es decir; ¿10 es (!=) diferente de 10?, no es diferente por lo que devolvera false\nprint(10 >= 11) # El simbolo (>=) reprensenta si es mayor o igual, es decir; ¿10 es (>=) mayor o igual a 11?, no es mayor ni igual, por lo que devolveria false\nprint(15 <= 15) # El simbolo (<=) reprensenta si es menor o igual, es decir; ¿10 es (<=) menor o igual a 15?, no es menor, pero si es igual, por lo que retorna true\n\n# Operadores condicionales\n# Devuelve uno de dos valores en función de una condición, ejemplo:\n\nprint(\"operadores condicionales:\") \nif 20 > 10:                   # (IF) si 20 es (>) mayor a 10 entonces realiza...\n    print(\"si es mayor :D \")  # este bloque de codigo\nelse:                         # (ELSE) en caso contrario de que no se cumpla\n    print(\"no es mayor :( \")  # ejecuta este bloque de codigo\n\n# Operadores de asignación\n# se utilizan para asignar un valor a una variable, ejemplo:\n\nx = 7 # Asigna un valor a una variable\nx += 2 # Equivalente a x = x + 2, Incrementa el valor de la variable\nx -= 2 # Equivalente a x = x - 2, Decrementa el valor de la variable\nx *= 2  # Equivalente a x = x * 2, Multiplica el valor de la variable\nx /= 2  # Equivalente a x = x / 2, Divide el valor de la variable\n\n# Operadores índex y slicing\n# Lista\nnombres = ['riuck', 'fermando', 'jesus'] # Esto es una lista\n\n# Ejemplos que representen los tipos de estructuras de control\n# condicionales\n\nprint(\"ingrese dos numeros para comparlos\")\na = int(input(\"ingrese el primer numero: \")) # Solicitamos al usuario que ingrese el primer numero, y lo guardamos en la variable (a)\nb = int(input(\"ingrese el segundo numero: \")) # Solicitamos al usuario que ingrese el segundo numero, y lo guardamos en la variable (b)\nif a == b: # Utilizamos la condicional (if) y aplicamos la comparacion \n    print(\"son iguales :D \") # si la condicion se cumple se imprime este bloque de codigo\nelse:\n    print(\"no son iguales :( \") # si no se cumple la condicion se imprime este bloque de codigo \n\n# Bucles\n# For: Itera sobre una secuencia (lista, tupla, cadena, etc.)\nnombres = ['riuck', 'fernando', 'jesus'] # creamos una variable tipo lista\nfor k in nombres:\n    print(k)\n\n# While: Ejecuta un bloque de código mientras se cumpla una condición\ni = 10 # Declaro una variable, y le asigno un valor de 10\nwhile i > 0: # (WHILE) mientras i (>) sea mayor a 0 (:) entonces, ejecuta el siguiente bloque de codigo  \n    print(i)\n    i -= 1 # Aqui discrementamos el valor de i en 1, cuando i sea menor a 0 se saldra de bucle, sin una condicion de salida tendriamos un bulce infinito.\n\n''' Crea un programa que imprima por consola todos los números comprendidos\n entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3'''\n\n# Aplicamos un ciclo for para solventar este problema, utilizamos un rango para las interaciones se la variable n\n# gracias a la funcion range (min, max, step) ademas de usar step que es un incremento, es este caso de 2 en 2\nfor n in range(10, 55, 2):\n    if n != 16 and n % 3 != 0: # utilizamos la condicional if, y decimos que la codicion es que n sea diferente de 16, y que n no sea multiplo de 3\n        print(n) # hacemos un print para pintar los numeros pares, y cumplir las exepciones \nprint(55) # agrego el 55\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Rodrigoghr.py",
    "content": "# #01 OPERADORES Y ESTRUCTURAS DE CONTROL\n#### Dificultad: Fácil | Publicación: 02/01/24 | Corrección: 08/01/24\n\n## Ejercicio\n\n'''\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n'''\n# Números\nnumero_1 = 2\nnumero_2 = 10\n\n# OPERADORES:\n' Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits... '\nprint('Operadores Aritméticos')\nprint(f'\\tSuma: {numero_1} + {numero_2} = {numero_1 + numero_2}')\nprint(f'\\tResta: {numero_1} - {numero_2} = {numero_1 - numero_2}')\nprint(f'\\tMultiplicación: {numero_1} * {numero_2} = {numero_1 * numero_2}')\nprint(f'\\tDivision: {numero_1} / {numero_2} = {numero_1 / numero_2}')\nprint(f'\\tDivision Entera: {numero_1} // {numero_2} = {numero_1 // numero_2}')\nprint(f'\\tResto: {numero_2} % {numero_1} = {numero_2 % numero_1}')\nprint(f'\\tPotencia: {numero_1} ** {numero_2} = {numero_1 ** numero_2}')\n\nprint('\\n\\nOperadores Lógicos')\nprint('\\tAND: True and True = ', True and True)\nprint('\\tOR: True or True = ', True or True)\nprint('\\tNOT: not True =', not True)\n\nprint('\\n\\nOperadores de Asignación')\nvariable = 58\nprint(f'\\t=  Asigna valor a una variable: variable = {variable}')\nvariable += 4\nprint(f'\\t+= Incrementa el valor de la variable en {4}: variable += {4} --> variable = {variable}')\nvariable -= 5\nprint(f'\\t-= Decrementa el valor de la variable en {5}: variable -= {5} --> variable = {variable}')\nvariable *= 2\nprint(f'\\t*= Multiplica el valor de la variable por {2}: variable *= {2} --> variable = {variable}')\nvariable /= 3\nprint(f'\\t/= Divide el valor de la variable por {3}: variable /= {3} --> variable = {variable}')\nvariable = int(variable)\nvariable %= 13\nprint(f'\\t%= Resto o modulo del valor de la variable por {13}: variable %= {13} --> variable = {variable}')\nvariable //= 2\nprint(f'\\t//= División entera del valor de la variable por {2}: variable //= {2} --> variable = {variable}')\nvariable **= 2\nprint(f'\\t**= Eleva la variable al exponente {2}: variable **= {2} --> variable = {variable}')\n\nprint('\\n\\nOperadores Relacionales')\nx, y = 5, 8\nprint(f'\\t{x} == {y} =', x==y)\nprint(f'\\t{x} != {y} =', x!=y)\nprint(f'\\t{x} >  {y} =', x>y) \nprint(f'\\t{x} <  {y} =', x<y) \nprint(f'\\t{x} >= {y} =', x>=y)\nprint(f'\\t{x} <= {y} =', x<=y)\n\n\nprint('\\n\\nOperadores de Identidad')\nprint('\\tEl operador \"is\" comprueba si dos variables hacen referencia a el mismo objeto')\nid1, id2 = 10, 20\nprint(f'\\t{id1} is {id2} = {id1 is id2}')\nid1, id2 = 10, 10\nprint(f'\\t{id1} is {id2} = {id1 is id2}')\nprint('\\tEl operador \"is not\" comprueba si dos variables no hacen referencia a el mismo objeto')\nid1, id2 = 10, 20\nprint(f'\\t{id1} is {id2} = {id1 is id2}')\nid1, id2 = 10, 10\nprint(f'\\t{id1} is {id2} = {id1 is id2}')\n\n\nprint('\\n\\nOperadores de Pertenencia')\nprint('Los operadores \"in\" y \"not in\" nos indican si un elemento esta o no contenido en una secuencia (lista, string, etc)')\nnumeros = [13, 17, 15]\nprint(f'\\tLista numeros: {numeros}')\nprint(f'\\tComprobamos si 14 está contenido en la lista de numeros: 14 in {numeros} = {14 in numeros}')\nprint(f'\\tComprobamos si 17 está contenido en la lista de numeros: 17 in {numeros} = {17 in numeros}')\nprint(f'\\tComprobamos si 18 no está contenido en la lista de numeros: 18 not in {numeros} = {18 not in numeros}')\nprint(f'\\tComprobamos si 13 no está contenido en la lista de numeros: 13 not in {numeros} = {13 not in numeros}')\nfrase = 'Hola mundo'\nprint(f'\\tComprobamos si \"Hola\" está contenido en \"{frase}\": \"Hola\" in \"{frase}\" = {\"Hola\" in frase}')\n\nprint('\\n\\nOperadores Bits')\nx, y = 5, 3\nprint(f'\\tAND: {x} & {y} es {x & y}') \nprint(f'\\tOR : {x} | {y} es {x | y}') \nprint(f'\\tNOT: {x} es {~x}') \nprint(f'\\tXOR: {x} ^ {y} es {x ^ y}') \nprint(f'\\tDesplazamiento a la derecha  : {x} >> {y} es {x >> y}') \nprint(f'\\tDesplazamiento a la izquierda: {x} << {y} es {x << y}') \n\n# ESTRUCTURAS DE CONTROL\n' Condicionales, iterativas, excepciones...'\nprint('\\nCondicionales:')\nprint('if - else:')\nnumero = 25\nif numero % 2 == 0:\n    print('\\tNúmero Par')\nelse:\n    print('\\tNúmero Impar')\nprint('\\nIterativos:')\nprint('1. for:')\nfrutas = ['pera','manzana','naranja','fresa']\nprint('\\tLista de frutas: ')\nfor fruta in frutas:\n    print(f'\\t\\t{fruta}')\n\nprint('2. while:')\nintentos = 1\nwhile intentos <= 5:\n    print(f'\\tIntento {intentos}')\n    intentos += 1\n\nprint('\\nExcepciones:')\nwhile True:\n    # Control excepcion\n    try:\n        number = int(input('\\tInserta un numero: '))\n        break # Si el valor es válido (número) finaliza la ejecucion\n    \n    # Si el valor es invalido (diferente a un número) --> devuelve el error controlado\n    except ValueError:\n        print('\\tError! Valor inválido. Inténtelo de nuevo')\n        \n# DIFICULTAD EXTRA (opcional):\n'''\n    Crea un programa que imprima por consola todos los números comprendidos\n    entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n'''\nfor numero in range(10,56,2):\n    if numero != 16 and numero % 3 != 0:\n        print(numero)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/RoniPG.py",
    "content": "# @RoniPG\n\t\nprint(\"Tipo de operadores.\")\n\t\t\nprint(\"Operadores Aritmeticos.\")\n\t\t\nprint(\"Suma +, Resta -, Division /, Multiplicacion *, Resto % (En la division inexacta = lo que sobra)\") \n\t\t\nprint(\"Ejemplos\")\n\na = 2\nb = 3\n\nsuma = a + b\nprint(str(a) + \" + \" + str(b) + \" = \" + str(suma))\n\nresta = a - b\nprint(str(a) + \" - \" + str(b) + \" = \" + str(resta))\n\ndivision = a / b\nprint(str(a) + \" / \" + str(b) + \" = \" + str(division))\n\nmultiplicacion = a * b\nprint(str(a) + \" * \" + str(b) + \" = \" + str(multiplicacion))\n\nresto = a % b\nprint(str(a) + \" % \" + str(b) + \" = \" + str(resto))\n\nprint(\"Operadores de Asignacion.\")\n\nprint(\" = para asignar el valor sobrescirbiendolo\")\nprint(\"+= sumar a la variable el valor dedicidido\")\nprint(\"-= restar a la variable el valor dedicidido\")\nprint(\"*= mutilpicar a la variable el valor dedicidido\")\nprint(\"/= dividir a la variable el valor dedicidido\")\n\nprint(\"Ejemplos\")\n\nprint(a)\nprint(str(a) + \" += 2 \")\na += 2\nprint(a)\nprint(str(a) + \" -= 2 \")\na -= 2\nprint(a)\nprint(str(a) + \" *= 2 \")\na *= 2\nprint(a)\nprint(str(a) + \" /= 2 \")\na /= 2\nprint(a)\n\nprint(\"Operadores de comparacion\")\n\nprint(\"== igual a (para objetos equals(), != difente de, < menor que,\") \nprint(\"<= menor o igual que, >= mayor o igual que, > mayor que.\") \nprint(\"Todos estos valores devuelven un booleano true o false\")\n\nprint(\"Ejemplos\")\n\ncomparacion = False\n\na = 2\n\nprint(str(a) + \" | \" + str(b))\ncomparacion = a == b\nprint(str(a) + \" es igual a \" + str(b) + \": \" + str(comparacion))\ncomparacion = a != b\nprint(str(a) + \" no es igual a \" + str(b) + \": \" + str(comparacion))\ncomparacion = a < b\nprint(str(a) + \" es menor que \" + str(b) + \": \" + str(comparacion))\ncomparacion = a <= b\nprint(str(a) + \" es menor o igual que \" + str(b) + \": \" + str(comparacion))\ncomparacion = a >= b\nprint(str(a) + \" es mayor o igual que \" + str(b) + \": \" + str(comparacion))\ncomparacion = a > b\nprint(str(a) + \" es mayor que \" + str(b) + \": \" + str(comparacion))\n\nprint(\"Operadores logicos.\")\n\nprint(\"operador or (devuelve true si una de las variables se cumple)\")\nprint(\"operador and (devuelve true si todas las variables se cumplen)\")\nprint(\"operador not (invierte el valor de la condici├│n, de true a false y viceversa)\")\n\nprint(\"Ejemplos\")\n\nlogico= True\ncomparacion=False\n\nprint(\"Operador OR: \" + str(comparacion) + \" or \" + str(logico))\n\nif comparacion or logico: \n    print(logico)\nelse:\n    print(comparacion)\n\nprint(\"Operador AND: \" + str(comparacion) + \" and \" + str(logico))\nif comparacion and logico:\n    print(logico)\nelse:\n    print(comparacion)\n\nprint(\"Operador NOT: not \" + str(comparacion))\nif not comparacion:\n    print(logico)\nelse:\n    print(comparacion)\n\nprint(\"Operadores ternarios\")\n\nprint(\"Tienen la forma: valor_si_verdadero if condicion else valor_si_falso.\")\n\nprint(\"Ejemplos\")\n\nternario = False\n\nternario = logico if comparacion or logico else comparacion\nprint(\"Operador OR en ternario: \" + str(comparacion) + \" or \" + str(logico) + \" ternario = \" + str(ternario))\nternario = logico if comparacion and logico else comparacion\nprint(\"Operador AND en ternario: \" + str(comparacion) + \" and \" + str(logico) + \" ternario = \" + str(ternario))\nternario = logico if not comparacion else comparacion\nprint(\"Operador NOT en ternario: not\" + str(comparacion) + \" ternario = \" + str(ternario))\n\nprint(\"Operadores de concatenacion\")\n\nprint(\"+ Unir diferentes strings a uno solo.\")\n\nprint(\"Ejemplos\")\n\ntexto1 = \"Hola, \"\nprint(texto1)\ntexto2 = \"Python!\"\nprint(texto2)\ntextoFinal = texto1 + texto2\nprint(textoFinal)\n\nprint(\"Operadores de conversion de tipo\\nNo contiene ya que es un lenguaje debilmente tipado\")\n\nprint(\"Ejemplos\")\n\ntexto1 = \"2\"\nprint(type(texto1))\nprint(\"Dato en texto = \" + texto1)\ntexto1 = 2\nprint(type(texto1))\nprint(\"Dato convertido a entero = \" + str(texto1))\ntexto1 = \"2\"\nprint(type(texto1))\nprint(\"Dato convertido a texto = \" + texto1)\ntexto1 = 2.0\nprint(type(texto1))\nprint(\"Dato convertido a flotante = \" + str(texto1))\n\nprint(\"Tipo de estucturas.\")\n\nprint(\"Estructura if\")\n\nprint(\"Se ejecuta el bolque si se cumple la condicion.\")\n\nprint(\"Ejemplos\")\n\na = 2\nb = 2\n\nprint(\"Si \" + str(a) + \" = \" + str(b))\nif a == b:\n    print(\"Se ejecuta el bloque\")\n\nprint(\"Estructura if-else\")\n\nprint(\"Se ejecuta el bloque if si se cumple la condicion, si no se cumple se ejecuta el else.\")\n\nprint(\"Ejemplos\")\n\nprint(\"Si \" + str(a) + \" < (menor que) \" + str(b))\nif a < b :\n    print(\"Se ejecuta el bloque if\")\n\nelse :\n    print(\"Se ejecuta el bloque else\")\n\nprint(\"Estructura if else-if else\")\n\nprint(\"Se ejecuta el bloque if si se cumple la condicion.\")\nprint(\"Si no se cumple se ejecuta la siguiente condicion else if(asi sucesivamente).\")\nprint(\"Si no se cumple niguna condicion se ejecuta el else.\")\n\nprint(\"Ejemplos\")\n\nprint(\"if \" + str(a) + \" < (menor que) \" + str(b) + \"\\n\" + \n                    \"else if \" + str(a) + \" = (igula a) \" + str(b))\nif a < b :\n    print(\"Se ejecuta el bloque if\")\n\nelif a == b :\n    print(\"Se ejecuta el bloque else if\")\n\nelse :\n    print(\"Se ejecuta el bloque else\")\n\nprint(\"Estructura de bucles\")\n\nprint(\"Bucle for\")\n        \nprint(\"Se ejecuta un bloque de codigo mientras la condicion sea verdadera.\")\nprint(\"Esto se controla mediante un iterador que se ira aumentando por cada ejecucion del bucle.\")\n        \nprint(\"Ejemplos\")\n\nc=3\n\nfor i in range (0, c) :\n    print(i)\n\nprint(\"Bucle while\")\n\nprint(\"Se ejecuta un bloque de codigo mientras la condicion sea verdadera.\")\nprint(\"El bucle se ejecutara hasta que se modifique la condicion.\")\n        \nprint(\"Ejemplos\")\n\nprint(\"Condicion: \" + str(a) + \" menor que \" + str(c))\n\nwhile a != c :\n    print(\"La condicion es verdera\")\n    a += 1\n    print(a)\n\nprint(\"DIFICULTAD EXTRA (opcional):\")\nprint(\"Crea un programa que imprima por consola todos los n├║meros comprendidos\")\nprint(\"entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni m├║ltiplos de 3.\")\n\nfor i in range (10,55) : \n    if i%2 != 0:\n        None\n    elif (i == 16) or (i%3 == 0) :\n        None\n    else: \n        print (i)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Roy-garcia-rendon.py",
    "content": "a = 1\nb = 2\nprint(\"Dadas las variables a=1 y b=2:\\n\")\n\n# Operadores aritméticos:\nsuma = a+b\nresta = a-b\nmultiplicacion = a*b\ndivision = a/b\nmodulo = a % b\ndiv_entera = a//b\nexponenciacion = a**b\nprint(f\"\"\"Las operaciones aritméticas realizables son:\nSuma: {suma}\nResta: {resta}\nMultiplicación: {multiplicacion}\nDivision: {division}\nModulo: {modulo}\nDivision entera: {div_entera}\nExponenciacion: {exponenciacion}\\n\"\"\")\n\n# Operadores lógicos\ny = a and b\no = a or b\nno = not a\nprint(f\"\"\"Las operaciones lógicas básicas realizables son:\nAND: {y}\nOR: {o}\nNOT: {no}\\n\"\"\")\n\n# Operadores de comparacion\nmayor_que = a > b\nmayor_o_igual = a >= b\nmenor_que = a < b\nmenor_o_igual = a <= b\nigualdad = a == b\ndesigualdad = a != b\nprint(f\"\"\"Las operaciones de comparacion realizables son:\nMayor que: {mayor_que}\nMayor o igual que: {mayor_o_igual}\nMenor que: {menor_que}\nMenor o igual que: {menor_o_igual}\nIgualdad: {igualdad}\nDesigualdad: {desigualdad}\\n\"\"\")\n\n# Operadores de asignación\nasignacion = \"simbolo =\"\na += b\na -= b\na *= b\nprint(f\"\"\"En principio la asignación se hace con {asignacion}\nEs posible agregar cualquier operación aritmética a la vez que se asigna valor de manera que se asignará a la variable su propio valor con la operación realizada\"\"\")\n\n# Operadores de identidad\nes = a is b\nno_es = a is not b\nprint(f\"\"\"Las operaciones de identidad realizables son:\nEs: {es}\nNo es: {no_es}\"\"\")\n\n# Operadores de pertenencia\na = \"gato\"\nb = \"perro\"\nen = a in b\nno_en = a not in b\nprint(f\"\"\"Las operaciones de pertenencia son para elementos iterables, tenemos que cambiar las variables a a=\"gato\" y b=\"perro\":\nEn: {en}\nNo en: {no_en}\"\"\")\n\n# Operadores bitwise\na = 1\nb = 2\nbit_and = a & b\nbit_or = a | b\nbit_not = ~a\nbit_xor = a ^ b\nprint(f\"\"\"Las operaciones bitwise (bit a bit) son con la forma binaria de las variables:\nAND: {bit_and}\nOR: {bit_or}\nNOT: {bit_not}\nXOR: {bit_xor}\"\"\")\n\n# Estructuras de control\n\n# Condicionales\nif a < b:\n    print(\"a es menor que b\")\nelif a > b:\n    print(\"a es mayor que b\")\nelse:\n    print(\"deben ser iguales porque no se cumple ninguna condicion...\")\n\n# Bucle for\nfor i in range(1, 6):\n    print(f\"Se repitio{i} de este bucle for\")\n\n# Bucle while\ni = 0\nwhile i < 9:\n    print(f\"Se repitio {i}\")\n    i += 1\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/RuhlMirko.py",
    "content": "import random\n\nprint(f\"Suma: 5+6 = {5+6}\")\nprint(f\"Resta: 5-6 = {5-6}\")\nprint(f\"Multiplicacion: 5*6 = {5*6}\")\nprint(f\"Exponente: 5**6 = {5**6}\")\nprint(f\"Division: 5/6 = {5/6}\")\nprint(f\"Division Entera: 5//6 = {5//6}\")\nprint(f\"Modulo: 5%6 = {5%6}\")\n\nprint(\"\\nLogicos\")\nnum_aleatorio = random.randint(1, 10)\n\nprint(f\"Comparar Igualdad: 10 == {num_aleatorio} -> {5 == num_aleatorio}\")\nprint(f\"Comparar Desigualdad: 10 != {num_aleatorio} -> {5 != num_aleatorio}\")\nprint(f\"Comparar si es numero mayor: 10 > {num_aleatorio} -> {5 > num_aleatorio}\")\nprint(f\"Comparar si es numero menor: 10 < {num_aleatorio} -> {5 < num_aleatorio}\")\nprint(f\"Comparar si es numero mayor o igual: 10 >= {num_aleatorio} -> {5 >= num_aleatorio}\")\nprint(f\"Comparar si es numero menor o igual: 10 <= {num_aleatorio} -> {5 <= num_aleatorio}\")\n\nprint(\"\\nComparacion\")\n\nprint(f\"Operador AND: {num_aleatorio}%2==0 and {num_aleatorio}%4==0 -> {num_aleatorio % 2 == 0 and num_aleatorio % 4 == 0}\")\nprint(f\"Operador OR: {num_aleatorio}%2==0 or {num_aleatorio}%4==0 -> {num_aleatorio % 2 == 0 or num_aleatorio % 4 == 0}\")\nprint(f\"Operador NOT: not {num_aleatorio}%2==0 -> {not num_aleatorio % 2 == 0}\")\n\nprint(\"\\nAsignacion\")\n\nnumero_asignado = num_aleatorio * 2\nprint(numero_asignado)\nnumero_asignado += 2\nprint(numero_asignado)\nnumero_asignado -= 2\nprint(numero_asignado)\nnumero_asignado *= 2\nprint(numero_asignado)\nnumero_asignado **= 2\nprint(numero_asignado)\nnumero_asignado /= 2\nprint(numero_asignado)\nnumero_asignado //= 2\nprint(numero_asignado)\nnumero_asignado %= 1\nprint(numero_asignado)\n\nprint(\"\\nIdentidad\")\nnuevo_numero = 0.0\nprint(f\"{numero_asignado} is {nuevo_numero} == {numero_asignado is nuevo_numero}\")\nprint(f\"{numero_asignado} is not {nuevo_numero} == {numero_asignado is not nuevo_numero}\")\n\nprint(\"\\nPertenencia\")\nprint(f\"'t' in 'python' = {'t' in 'python' }\")\nprint(f\"'t' not in 'python' = {'t' not in 'python' }\")\n\nprint(\"\\nBits\")\nprimer_bit = 10\nsegundo_bit = 3\nprint(f\"AND: 10 & 3 =  {primer_bit & segundo_bit}\")\nprint(f\"OR: 10 | 3 =  {primer_bit | segundo_bit}\")\nprint(f\"AND: 10 ^ 3 =  {primer_bit ^ segundo_bit}\")\nprint(f\"NOT: ~10 =  {~primer_bit}\")\n\nprint(\"\\nCondicionales\")\nnum_aleatorio = random.randint(0, 10)\nif num_aleatorio % 2 == 0:\n    print(\"Numero Par\")\nelif num_aleatorio % 3 == 0:\n    print(\"Divisible por tres\")\nelse:\n    print(\"Numero Impar\")\n\n\nprint(\"\\nIterables\")\nprint(\"For loop\")\nfor i in range(num_aleatorio):\n    print(i)\nprint(\"While loop\")\nwhile num_aleatorio > 0:\n    print(num_aleatorio)\n    num_aleatorio -= 1\n\n\nprint(\"\\nExcepciones\")\ntry:\n    print(5/0)\nexcept ZeroDivisionError:\n    print(\"No se puede dividir por 0\")\nfinally:\n    print(\"Excepcion controlada\")\n\n\n\nprint(\"\\nDificultad Extra: \")\nfor number in range(10, 55):\n    if number % 2 == 0:\n        if number % 3 != 0 and number != 16:\n            print(number)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Rusanov16.py",
    "content": "\"\"\"\nEJERCICIO 01:\n    - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n    Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n    \n    - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n    que representen todos los tipos de estructuras de control que existan\n    en tu lenguaje:\n    Condicionales, iterativas, excepciones...\n    \n    - Debes hacer print por consola del resultado de todos los ejemplos.\n    \n    DIFICULTAD EXTRA (opcional):\n    \n    Crea un programa que imprima por consola todos los números comprendidos\n    entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\n\"\"\"\n\n#*-------------------------------------------------------------------------------------------------------------#\n\"\"\"\nCrea ejemplos utilizando todos los tipos de operadores de tu lenguaje: Aritméticos, lógicos, de comparación, \nasignación, identidad, pertenencia, bits... \n    \n\"\"\"\n#Operadores Aritméticos\nprint(\"Operadores Aritméticos:\")\nprint(\"------------------------------------------------------\")\n#Suma\nprint(f\" -Suma: +; 55 + 24 =  {55 + 24}\")\nprint(\"------------------------------------------------------\")\n#Resta\nprint(f\" -Resta: -; 55 - 24 = {55 - 24}\")\nprint(\"------------------------------------------------------\")\n#Multiplicación\nprint(f\" -Multiplicación: *; 55 * 24 = {55 * 24}\")\nprint(\"------------------------------------------------------\")\n#División\nprint(f\" -División: /; 55 / 24 = {round((55 / 24),4)}\")\nprint(\"------------------------------------------------------\")\n#Módulo\nprint(f\" -Módulo: %; 55 % 2 = {55 % 24}\")\nprint(\"------------------------------------------------------\")\n#Exponente\nprint(f\" -Exponente: **; 55 ** 24 = {55 ** 24}\")\nprint(\"------------------------------------------------------\")\n#Cociente\nprint(f\" -Cociente: //; 55 // 24 = {55 // 24}\")\nprint(\"------------------------------------------------------\")\nprint(\"\\n\")\n\n#Operadores Lógicos\nprint(\"Operadores Lógicos:\")\nprint(\"------------------------------------------------------\")\n#AND\nprint(\" -Operador AND:\")\nprint(f\" True and True =  {True and True}\")\nprint(f\" True and False =  {True and False}\")\nprint(f\" False and True =  {False and True}\")\nprint(f\" False and False =  {False and False}\")\nprint(\"------------------------------------------------------\")\n#OR\nprint(\" -Operador OR:\")\nprint(f\" True or True =  {True or True}\")\nprint(f\" True or False =  {True or False}\")\nprint(f\" False or True =  {False or True}\")\nprint(f\" False or False =  {False or False}\")\nprint(\"------------------------------------------------------\")\n#NOT\nprint(\" -Operador NOT:\")\nprint(f\" not True =  {not True}\")\nprint(f\" not False =  {not False}\")\nprint(\"------------------------------------------------------\")\nprint(\"\\n\")\n\n#Operadores de comparación\nprint(\"Operadores de Comparación:\")\nprint(\"------------------------------------------------------\")\n#Operador ==\nprint(f\" -Operador ==; 5 == 2 =  {5 == 2}\")\nprint(\"------------------------------------------------------\")\n#Operador !=\nprint(f\" -Operador !=; 5 != 2 =  {5 != 2}\")\nprint(\"------------------------------------------------------\")\n#Operador >\nprint(f\" -Operador >; 5 > 2 =  {5 > 2}\")\nprint(\"------------------------------------------------------\")\n#Operador <\nprint(f\" -Operador <; 5 < 2 =  {5 < 2}\")\nprint(\"------------------------------------------------------\")\n#Operador >=\nprint(f\" -Operador >=; 5 >= 2 =  {5 >= 2}\")\nprint(\"------------------------------------------------------\")\n#Operador >=\nprint(f\" -Operador >=; 5 >= 2 =  {5 <= 2}\")\nprint(\"------------------------------------------------------\")\nprint(\"\\n\")\n\n# Operadores de Identidad\nprint(\"Operadores de Identidad:\")\nprint(\"------------------------------------------------------\")\n#Operador is\nprint(f\" -Operador is; 5 is 2 =  {5 is 2}\")\nprint(\"------------------------------------------------------\")\n#Operador is not\nprint(f\" -Operador is not; 5 is not 2 =  {5 is not 2}\")\nprint(\"------------------------------------------------------\")\nprint(\"\\n\")\n\n# Operadores de Pertenencia\nprint(\"Operadores de Pertenencia:\")\nprint(\"------------------------------------------------------\")\n#Operador in\nlista = [2,6,8,10]\nprint(f\" -Operador in; 5 in [2,6,8,10] =  {5 in lista}\")\nprint(\"------------------------------------------------------\")\n#Operador  not in\nprint(f\" -Operador not in; 5 not in [2,6,8,10] =  {5 not in lista}\")\nprint(\"------------------------------------------------------\")\nprint(\"\\n\")\n\n# Operadores de Bits\nprint(\"Operadores de Bits:\")\nprint(\"------------------------------------------------------\")\na = 0b1101 #Valor binario del número 27\nb = 0b1011\n#Operador |\nprint(f\"-Operador |; 0b1101 | 0b1011 = {bin(a | b)}\")\nprint(\"------------------------------------------------------\")\n#Operador &\nprint(f\"-Operador &; 0b1101 & 0b1011 = {bin(a & b)}\")\nprint(\"------------------------------------------------------\")\n#Operador ~\nc = 40\nprint(f\"-Operador ~; ~40 = {bin(~c)}\")\nprint(\"------------------------------------------------------\")\n#Operador ^\nx = 0b0110 ^ 0b1010\nprint(f\" -Operador ^; x = 0b0110 ^ 0b1010 = {x}\")\nprint(\"------------------------------------------------------\")\n#Operador >>\nprint(f\"-Operador >>; 0b1101 >> 2 = {bin(a >> 2)}\")\nprint(\"------------------------------------------------------\")\n#Operador <<\nprint(f\"-Operador <<; 0b1101 << 5 = {bin(a << 5)}\")\nprint(\"------------------------------------------------------\")\nprint(\"\\n\")\n\n#*-------------------------------------------------------------------------------------------------------------#\n\n\"\"\"    - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n    que representen todos los tipos de estructuras de control que existan\n    en tu lenguaje:\n    Condicionales, iterativas, excepciones...\n\"\"\"\n\nprint(\"Estructuras de Control\")\n\n#if\nprint(\"IF\")\nif 25 % 5 == 0:\n    print(\"25 es múltiplo de 5\")\nprint(\"------------------------------------------------------\")\n\n#if/else\nprint(\"IF/ELSE\")\nif 25 % 5 == 0:\n    print(\"25 es múltiplo de 5\")\nelse:\n    print(\"25 no es múltiplo de 5\")\nprint(\"------------------------------------------------------\")\n\n#if/elif/else\nprint(\"IF/ELIF/ELSE\")\nedad = 45\nif edad < 13:\n    print(\"Eres un niño.\")\nelif edad < 20:\n    print(\"Eres un adolescente.\")\nelif edad < 65:\n    print(\"Eres un adulto.\")\nelse:\n    print(\"Eres un adulto mayor.\")\nprint(\"------------------------------------------------------\")\nprint(\"\\n\")\n\n#for\nprint(\"FOR\")\nfor i in \"Programming\":\n    print(i)\nprint(\"------------------------------------------------------\")\n#while\nprint(\"WHILE\")\n\ni = 1\nwhile i <= 3:\n    print(i)\n    i += 1\nprint(\"Números del 1 al 3\")\n\nprint(\"\\n\")\n\n#*-------------------------------------------------------------------------------------------------------------#\n\n\"\"\"       DIFICULTAD EXTRA (opcional):\n    \n    Crea un programa que imprima por consola todos los números comprendidos\n    entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\"\"\"\n\nfor i in range(10,55):\n    if i % 2 == 0 and i % 3 != 0 and i != 16 :\n        print(i)\n        "
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Rusian69.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\"\"\"\n\n# ejemplos de operadores\n\nprint(3 + 4) # suma\nprint(3 - 4) # resta\nprint(3 * 4) # multiplicacion\nprint(3 / 4) # division\nprint(10 % 3) # residuo de la divicion\nprint(10 // 3) #divicion con resultado entero forzado\nprint(2 ** 3) # potenciacion\n\n# Operaciones con enteros\nprint(3 > 4) # mayor\nprint(3 < 4) # menor\nprint(3 >= 4) # mayor o igual\nprint(4 <= 4) # menor o igual\nprint(3 == 4) # igualdad (resultado bool)\nprint(3 != 4) #desigualdad (resultado bool)\n\n# Operadores Lógicos #\nprint(3 > 4 and \"Hola\" > \"Python\") # retorna verdad si ambos son verdaderos\nprint(3 > 4 or \"Hola\" > \"Python\") # retorna verdad si uno de los enunciados es verdaderos\nprint(3 < 4 and \"Hola\" < \"Python\")\nprint(3 < 4 or \"Hola\" > \"Python\")\nprint(3 < 4 or (\"Hola\" > \"Python\" and 4 == 4))\nprint(not (3 > 4)) # da el valor contrario al real\n\n# DIFICULTAD EXTRA (opcional)\ndef contador():\n    result = []\n    for index in range(10,51):\n        if index % 2 == 0 and index % 3 != 0 and index != 16:\n            result.append(index)\n    print(result)\ncontador()\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Ruthmp.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n         */\n\"\"\"\n\n# OPERADORES ARITMÉTICOS\na = 5\nb = 3\nprint (f\" SUMA: a + b = {a+b}\")\nprint (f\"Resta: a - b = {a-b}\")\nprint (f\"Multiplicación: a * b ={a*b}\")\nprint (f\"División: a / b = {a/b}\")\nprint (f\"Modulo: a % b = {a%b}\")\nprint (f\"Exponente: a ** b = {a**b}\")\nprint (f\"División entera: a // b = {a//b}\")\n\n# OPERADORES DE COMPARACIÓN\nprint (f\"Igualdad: a == b es {a==b}\")\nprint (f\"Desigualdad: a != b es {a!=b}\")\nprint (f\"Mayor que: a > b es {a>b}\")\nprint (f\"Menor que: a < b es {a<b}\")\nprint (f\"Mayor o igual: a >= b es {a>=b}\")\nprint (f\"Menor o igual que: a <= b es {a<=b}\")\n\n#OPERADORES LÓGICOS\nprint (f\"AND &&: a>b and b==3 es {a>b and b==3} \")\nprint (f\"OR || :a>b or b>a es {a>b or b>a} \")\nprint (f\"NOT ! : not a + b == 10 es { not a + b == 10}\")\n\n#OPERADORES DE ASIGNACIÓN\nnum = 10\nprint(f\"ASIGNACIÓN: num = 10 es {num}\")\nnum+=1\nprint(f\"SUMA Y ASIGNACIÓN: num += 1 es {num}\")\nnum-=1\nprint(f\"RESTA Y ASIGNACIÓN: num -= 1 es {num}\")\nnum*=2\nprint(f\"MULTIPLICACIÓN Y ASIGNACIÓN: num *= 2 es {num}\")\nnum/=2\nprint(f\"DIVISIÓN Y ASIGNACIÓN: num /=2 es {num}\")\nnum%=3\nprint(f\"MODULO Y ASIGNACIÓN: num %= 3 es {num}\")\nnum**=3\nprint(f\"EXPONENTE Y ASIGNACIÓN: num **= 3 es {num}\")\nnum //=3\nprint(f\"DIVISIÓN ENTERA Y ASIGNACIÓN: num //= 3 es {num}\")\n\n#OPERADORES DE IDENTIDAD\nnum2 = num\nprint(f\"IS: num 2 is num es {num2 is num}\")\nprint(f\"IS NOT: num2 is not num es {num2 is not num}\")\n\n#OPERADORES DE PERTENENCIA\narray = [\"pera\", \"manzana\", \"melón\"]\nprint(\"pera\" in array)\nprint(\"tomate\" not in array)\n\n#OPERADORES DE BITS\n\n\"\"\"\nESTRUCTURAS DE CONTROL\n\"\"\"\n\n#CONDICIONALES\nhora = 12\nif hora>=7 and hora<=14:\n    print(\"Buenos días\")\nelif hora>14 and hora<20:\n    print(\"Buenas tardes\")\nelse:\n    print(\"Buenas noches\")\n\n#ITERATIVAS\nfor x in range (10):\n    print(x)\n\ni=0\nwhile i<6:\n    print(i)\n    i+=1\n\n#EXCEPCIONES\n\ntry:\n    print(5/0)\nexcept:\n    print(\"Se ha producido un error\")\nfinally:\n    print(\"El manejo de excepciones ha finalizado\")\n\n\"\"\"\nEXTRA\n\"\"\"\n\nfor num_extra in range (10,56):\n    if num_extra %2==0 and num_extra !=16 and num_extra %3!=0:\n        print(num_extra)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/SNaoj.py",
    "content": "# Operadores en Python\n\n#Aritmeticos\n\nprint(f\"Suma 8 + 9 = {8+9}\")\nprint(f\"Resta 18 - 7 = {18-7}\")\nprint(f\"Multiplicacion 6 * 5 = {6*5}\")\nprint(f\"Division 10 / 3 = {10/3}\")\nprint(f\"Modular 10 % 3 = {10%3}\")\nprint(f\"Exponente 10 ** 3 = {10**3}\")\nprint(f\"Division entera 10//3 = {10//3}\")\n\n#Comparacion\n\nprint(f\"Igualdad 5 = 5 {5==5}\")\nprint(f\"Desigualdad 5 != 5 {5!=5}\")\nprint(f\"Mayor que 5 > 5 {5>5}\")\nprint(f\"Mayor o igual que 5 >= 5 {5 >= 5}\")\nprint(f\"Menor que 5 < 5 {5 < 5}\")\nprint(f\"Menor o igual que 5 <= 5 {5 <= 5}\")\n\n#Logicos\n\nprint(f\"AND &&: 5 + 2 == 7 and 9 - 8 == 1 es {5 + 2 == 7 and 9 - 8 == 1}\")\nprint(f\"OR ||: 5 + 2 == 7 or 9 - 8 == 3 es {5 + 2 == 7 or 9 - 8 == 3}\")\nprint(f\"NOT !: !6 + 8 == 14  es {not 6 + 8 == 14 }\")\n\n#Asignacion\n\nmy_number = 16\nprint(my_number)\nmy_number += 2\nprint(my_number)\nmy_number -= 4\nprint(my_number)\nmy_number *= 2\nprint(my_number)\nmy_number /= 4\nprint(my_number)\nmy_number **= 2\nprint(my_number)\nmy_number %= 2\nprint(my_number)\nmy_number //= 4\nprint(my_number)\n\n\n#Identidad \n\nmy_new_number = my_number\nprint(f\"My new number is my number es {my_new_number is my_number}\")\nprint(f\"My new number is not my number es {my_new_number is not my_number}\")\n\n#Pertenencia \n\nprint(f\"'s' in 'steven' {'s' in 'steven'}\")\nprint(f\"'f' in 'steven' {'f' in 'steven'}\")\nprint(f\"'s' not in 'steven' {'s' not in 'steven'}\")\n\n#Bit\n\na = 10 # 1010\nb = 5  # 0101\n\nprint(f\"AND: 10 & 5 = {10 & 5}\") #0000\nprint(f\"OR: 10 | 5 = {10 | 5}\") #1111\nprint(f\"XOR: 10 ^ 5 = {10 ^ 5}\") #1111\nprint(f\"NOT: ~10 = {~10}\")\nprint(f\"Desplazamiento a la derecha 10 >> 1 = {10 >> 1}\") #0101\nprint(f\"Desplazamiento a la izquierda 10 << 1 = {10 << 1}\") #101000\n\n\n\"\"\"\nEstructuras de control\n\"\"\"\n\n#Condicionales\n\nmy_str= \"SNaoj\"\n\nif my_str == \"SNaoj\":\n    print(\"my_str es 'SNaoj'\")\nelif my_str == \"Mouredev\":\n    print(\"my_str es 'Mouredev'\")\nelse: \n    print(\"my_str no es 'Snaoj' ni 'Mouredev\")\n\n#Iterativas\n\nfor i in range (11):\n    print(i)\n\ni = 0\nwhile i <= 10:\n    print(i)\n    i += 2\n\n# Manejo de excepciones\ntry:\n    print(50 / 2)\nexcept:\n    print(\"Se ha producido un error\")\nfinally:\n    print(\"Ha finalizado el manejo de excepciones\")\n\n\n#Extra\n\nfor number in range (10, 56):\n    if number % 2 == 0 and number != 16 and number % 3 != 0:\n        print(number)\n        "
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Sac-Corts.py",
    "content": "\"\"\"\nOperadores\n\"\"\"\n\n# Operadores Aritméticos\nprint(\"Operadores Aritméticos\")\nprint(f\"Suma: 5 + 7 = {5 + 7}\")\nprint(f\"Resta: 5 - 7 = {5 - 7}\")\nprint(f\"Multiplicación: 5 * 7 = {5 * 7}\")\nprint(f\"División: 10 / 2 = {10 / 2}\")\nprint(f\"Divisón Entera: 10 // 2 = {10 // 2}\")\nprint(f\"Módulo: 10 % 2 = {10 % 2}\")\nprint(f\"Potencia: 4 ** 2 = {4 ** 2}\")\n\n# Operadores Relacionales\nprint(\"Operadores Relacionales\")\na, b = 6, 3\nprint(f\"Mayor: a > b = {a > b}\")\nprint(f\"Mayor o igual que: a >= b = {a >= b}\")\nprint(f\"Menor: a < b = {a < b}\")\nprint(f\"Menor o igual que: a <= b = {a <= b}\")\nprint(f\"Igual: a == b = {a == b}\")\nprint(f\"Diferente: a != b = {a != b}\")\n\n# Operadores Bit a Bit\nprint(\"Operadores Bit a Bit\")\nc, d = 2, 3\nprint(f\"AND (&): c & d = {c & d}\")\nprint(f\"OR (|): c | d = {c | d}\")\nprint(f\"XOR (^): c ^ d = {c ^ d}\")\nprint(f\"NOT (~): ~c = {~c}\")\nprint(f\"RIGHT SHIFT (>>): c >> d = {c >> d}\")\nprint(f\"LEFT SHIFT (<<): c << d = {c << d}\")\n\n# Operadores de Asignación\nprint(\"Operadores de Asignación\")\nx, z = 5, 2\nprint(f\"(=): x = 5: {x}\")\nx += 5\nprint(f\"(+=): x += 5: {x}\")\nx -= 5\nprint(f\"(-=): x -= 5: {x}\")\nx *= 2\nprint(f\"(*=): x *= 2: {x}\")\nx **= 2\nprint(f\"(**=): x **= 2: {x}\")\nx //= 2\nprint(f\"(//=): x //= 2: {x}\")\nx /= 2\nprint(f\"(/=): x /= 2: {x}\")\nx %= 2\nprint(f\"(%=): x %= 2: {x}\")\nz &= 3\nprint(f\"(&=): z &= 3: {z}\")\nz |= 3\nprint(f\"(|=): z |= 3: {z}\")\nz ^= 1\nprint(f\"(^=): z ^= 3: {z}\")\nz >> 2\nprint(f\"(>>=): z >> 2: {z}\")\nz << 2\nprint(f\"(<<=): z << 2: {z}\")\n\n# Operadores Lógicos\nprint(\"Operadores Lógicos\")\na , b = True, False\nprint(f\"and (&&): a and b = {a and b}\")\nprint(f\"or (||): a or b = {a or b}\")\nprint(f\"not (!): not a  = {not a}\")\n\n# Operadores de Pertenencia\nprint(\"Operadores de Pertenencia\")\na = [1, 2, 3, 4, 5, 6]\n# in devuelve True si el valor especificado se encuentra en la secuencia\n# not in devuelve True si el valor especificado no se encuentra en la secuencia\nprint(f\"¿10 está en la lista? = {10 in a}\")\nprint(f\"¿10 está en la lista? = {10 not in a}\")\nprint(f\"¿4 está en la lista? = {4 in a}\")\nprint(f\"¿4 está en la lista? = {4 not in a}\")\n\n# Operadores de Identidad\nprint(\"Operadores de Identidad\")\na, b, c = 3, 3, 4\n# is devuelve True si los operandos se refieren al mismo objeto\n# is not devuelve True si los operandos no se refieren al mismo objeto\nprint(f\"¿a es igual a b? = {a is b}\")\nprint(f\"¿a es igual a b? = {a is not b}\")\nprint(f\"¿a es igual a c? = {a is not c}\")\n\n\"\"\"\nEstructuras de Control\n\"\"\"\n\n### Condicionales if, elif, else ###\nedad = 15\nif edad < 18:\n    print(\"Menor de edad\")\nelif edad >= 18:\n    print(\"Mayor de edad\")\nelse:\n    print (\"Este código nunca se ejecutará\")\n\n### Bucles for y while ###\n## Bucle for ##\nfrutas = [\"Manzana\", \"Fresa\", \"Naranja\"]\nfor fruta in frutas:\n    print(fruta)\n\n## Bucle while ##\ncontador = 0\nwhile contador < 3:\n    print(\"Dentro del bucle\")\n    contador += 1\n\n### Comprensión de listas ###\ncuadrados = [x**2 for x in range(10)]\nprint(cuadrados)\n\n###Control de flujo break, continue, pass ###\n## Break ##\nfor num in range(5):\n    if num == 3:\n        break    # Sale del bucle\n    print(num)\n\n## Continue ##\ncadena = \"Python\"\nfor letra in cadena:\n    if letra == 'P':\n        continue\n    print(letra)\n\n## Pass ##\nfor num in range(5):\n    if num == 3:\n        pass  \n    print(num)\n\n\"\"\"\nEjercicio Extra\n\"\"\"\nprint(\"EJERCICIO EXTRA\")\nfor numero in range(10, 56):\n    if numero % 2 == 0 and numero != 16 and numero % 3 != 0:\n        print(numero)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Sandrogmz.py",
    "content": "\"Operadores\"\r\n\r\n# Operadores Aritméticos\r\n\r\nprint(f\"Suma: 10 + 3 = {10 + 3}\")  # SUMA\r\nprint(f\"Resta: 10 - 3 ={10 - 3}\")  # RESTA\r\nprint(f\"Multi: 10 * 3 = {10 * 3}\")  # MULTIPLICACIÓN\r\nprint(f\"Div: 12 / 3 = {10 / 3}\")  # DIVISION\r\nprint(f\"Mod: 16 % 3 = {16 % 3} \")  # MÓDULO\r\nprint(f\"Potencia: 12 ** 3 = {12 ** 3}\")  # POTENCIA\r\nprint(f\"DivInt: 18 // 5 = {18 // 5}\")  # DIVISION NUMERO ENTERO\r\n\r\n# Operadores Relacionales\r\n\r\n# Devuelve True si el operador de la izquierda es mayor que el operador de la derecha\r\nprint(f\"OpLftBigTru: 3 > 2 = {3 > 2}\")\r\n# Devuelve True si el operador de la derecha es mayor que el operador de la izquierda\r\nprint(f\"OpRightBigTru: 2 < 3 = {2 < 3}\")\r\n# Devuelve True si ambos operandos son iguales\r\nprint(f\"SameValuesTru: 10 == 10 {10 == 10}\")\r\n# Devuelve True si el operador de la izquierda es mayor o igual que el operador de la derecha\r\nprint(f\"OpLftBigOrSameTrue: 10 >= 5 10 >= 10{10 >= 5}{10 >= 10}\")\r\n# Devuelve True si el operador de la derecha es mayor o igual que el operador de la izquierda\r\nprint(f\"OpRigBigOrSameTrue: 5 <= 10 10 <= 10{5 <= 10}{10 <= 10}\")\r\n# Devuelve True si ambos operandos no son iguales\r\nprint(f\"DifOpTrue: 10 != 7{10 != 7}\")\r\n\r\n# Operadores de Bit\r\n\r\n# Realiza bit a bit la operación AND en los operandos\r\nprint(f\"OpBitAND: 10 & 3 = {10 & 3}\")\r\n# Realiza bit a bit la operación OR en los operandos\r\nprint(f\"OpBiOR: 10 | 11 = {10 | 11}\")\r\n# Realiza bit a bit la operación XOR en los operandos\r\nprint(f\"OpBitXOR: 10 ^ 11 = {10 ^ 11}\")\r\n# Realiza bit a bit la operación NOT bit a bit. Invierte cada bit en el operando\r\nprint(f\"OpBitNOT: ~3 ={~3}\")\r\n# Realiza un desplazamiento a la derecha bit a bit. Desplaza los bits del operador de la izquierda a la derecha tantos bits como indica el operador de la derecha\r\nprint(f\"DespDer: 10 >> 2 = {10 >> 2}\")\r\n# Realiza un desplazamiento a la izquierda bit a bit. Desplaza los bits del operando de la izquierda a la izquierda tantos bits como especifique el operador de la derecha\r\nprint(f\"DespIzq: 10 << 2 = {10 << 2}\")\r\n\r\n# Operadores de asignación\r\n\r\nnumero = 20  # Asignación\r\nprint(numero)\r\nnumero += 5  # Suma y Asignaciónn\r\nprint(numero)\r\nnumero -= 5  # Resta y Asignación\r\nprint(numero)\r\nnumero *= 30  # Multiplicacion y Asignación\r\nprint(numero)\r\nnumero /= 2  # Division y Asignación\r\nprint(numero)\r\nnumero %= 1  # Modulo y Asignación\r\nprint(numero)\r\nnumero **= 1  # Exponente y Asignación\r\nprint(numero)\r\nnumero //= 1  # Division entera y asignación\r\nprint(numero)\r\n\r\n# Operadores lógicos\r\n\r\nprint(f\"AND &&: True and True es {True and True}\")\r\nprint(f\"OR ||: True or True es {True or True}\")\r\nprint(f\"NOT !: not True == True es {not True == True}\")\r\n\r\n# Operadores de Pertenencia\r\n\r\nprint(f\"'a' in 'sandro' = {'a' in 'sandro'}\")\r\nprint(f\"'s' not in 'sandro' = {'s' not in 'sandro'}\")\r\n\r\n\"\"\"in y not in son operadores de pertenencia.\r\n\r\nin devuelve True si el valor especificado se encuentra en la secuencia. En caso contrario devuelve False.\r\n\r\nnot in devuelve True si el valor especificado no se encuentra en la secuencia. En caso contrario devuelve False.\"\"\"\r\n\r\n# Operadores de identidad\r\n\r\nMiNuevoNumero = numero\r\nprint(f\"numero is MiNuevoNumero es {numero is MiNuevoNumero}\")\r\nprint(f\"numero is not MiNuevoNumero es {numero is not MiNuevoNumero}\")\r\n\r\n# Operadores Condicionales\r\n\r\nmy_string = \"Gomez\"\r\n\r\nif my_string == \"Sandro\":\r\n    print(\"my_string es 'Sandro'\")\r\nelif my_string == \"Gomez\":\r\n    print(\"my_string es 'Gomez'\")\r\nelse:\r\n    print(\"my_string no es 'Sandro' ni 'Gomez'\")\r\n\r\n# Iteradores\r\n\r\nnumber = 17\r\nwhile number <= 17:\r\n    print(\"Hola Python!\")\r\n    number += 2\r\n\r\nfor i in range(5):\r\n    print(i)\r\n\r\n    # Manejo de excepciones\r\n\r\n\r\ndef verificar_paridad():\r\n    try:\r\n        # Pedimos al usuario un número y convertimos la entrada a entero\r\n        numero = int(input(\"Introduce un número entero: \"))\r\n\r\n        # Verificamos si el número es par o impar usando el operador módulo\r\n        if numero % 2 == 0:\r\n            print(f\"El número {numero} es par.\")\r\n        else:\r\n            print(f\"El número {numero} es impar.\")\r\n\r\n    except ValueError:\r\n        # Capturamos el error cuando el usuario no introduce un número entero\r\n        print(\"Error: Debes introducir un número entero válido.\")\r\n\r\n        \"Extra\"\r\n\r\n\r\nfor numero in range(10, 56):\r\n    if numero % 2 == 0 and numero != 16 and numero % 3 != 0:\r\n        print(numero)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Seba9906.py",
    "content": "def operadores_aritmeticos():\n    print(\"OPERADORES ARITMETICOS\\n\")\n    a = 10\n    b = 7\n    suma = a + b\n    print(f\"Suma de {a} y {b} = {suma}\")\n    resta = a - b\n    print(f\"Resta de {a} y {b} = {resta}\")\n    multiplicacion = a * b\n    print(f\"Multiplicación de {a} y {b} = {multiplicacion}\")\n    division = a / b\n    print(f\"División de {a} y {b} = {division}\")\n    division_entera = a // b\n    print(f\"División entera de {a} y {b} = {division_entera}\")\n    modulo = a % b\n    print(f\"Módulo de {a} y {b} = {modulo}\")\n    exponente = a ** b\n    print(f\"Exponente de {a} y {b} = {exponente} \\n \")\n\ndef operadores_logicos():\n    print(\"OPERADORES LOGICOS\\n\")\n    x = True\n    y = False\n    resultado_and = x and y\n    print(f\"{x} AND {y} = {resultado_and}\")\n    resultado_or = x or y\n    print(f\"{x} OR {y} = {resultado_or}\")\n    resultado_not = not x\n    print(f\"NOT {x} = {resultado_not}\")\ndef operadores_comparacion():\n    print(\"OPERADORES DE COMPARACION\\n\")\n    a = 10\n    b = 7\n    c = 7\n    igual = a == b\n    print(f\"{a} == {b}: {igual}\")\n    diferente = a != b\n    print(f\"{a} != {b}: {diferente}\")\n    mayor = a > b\n    print(f\"{a} > {b}: {mayor}\")\n    menor = a < b\n    print(f\"{a} < {b}: {menor}\")\n    menorIgual = b <= c\n    print(f\"{b} <= {c}: {menorIgual}\")\n\ndef estructuras_control():\n    print(\"ESTRUCTURAS CONDICIONALES\\n\")\n    a = 5\n    b = 10\n    if a > b:\n        print(f\"{a} es mayor que {b}\")\n    elif a < b:\n        print(f\"{a} es menor que {b}\")\n    else:\n        print(f\"{a} y {b} son iguales\")\n\n    # Iterativas - Bucle for\n    for i in range(3):\n        print(f\"Repetición {i+1} con for\")\n    \n    # Iterativas - Bucle while\n    i = 0\n    while i < 3:\n        print(f\"Repetición {i+1} con while\")\n        i += 1\n\n    # Excepciones\n    try:\n        division = 10 / 0\n    except ZeroDivisionError:\n        print(\"División por cero no permitida.\")\n\ndef dificultad_extra():\n    print(\"Números entre 10 y 55, pares, y que no son ni 16 ni múltiplos de 3:\")\n    for i in range(10, 56):\n        if i % 2 == 0 and i != 16 and i % 3 != 0:\n            print(i, end=\" \")\noperadores_aritmeticos()\noperadores_logicos()\noperadores_comparacion()\nestructuras_control()\ndificultad_extra()"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/SergioGI99.py",
    "content": "\"\"\"\n-----------------------------------\nOPERADORES Y ESTRUCTURAS DE CONTROL\n-----------------------------------\nEJERCICIO:\n- Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n  Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n  (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n- Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n  que representen todos los tipos de estructuras de control que existan\n  en tu lenguaje:\n  Condicionales, iterativas, excepciones...\n- Debes hacer print por consola del resultado de todos los ejemplos.\nDIFICULTAD EXTRA (opcional):\nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n(Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.)\n\"\"\"\n#Ejercicio\n\n# Operadores aritméticos\nprint(3 + 4)\nprint(3 - 4)\nprint(3 * 4)\nprint(3 / 4)\nprint(10 % 3)\nprint(10 // 3)\nprint(2 ** 3)\n\n# Operadores comparativos\nprint(3 > 4)\nprint(3 < 4)\nprint(3 >= 4)\nprint(3 <= 4)\nprint(3 == 4)\nprint(3 != 4)\nprint(2 < 3 != 4)\n\n# Operadores lógicos\nprint(3 > 4 and \"Hola\" > \"Python\") # False and False = False\nprint(3 > 4 or \"Hola\" > \"Python\") # False or False = False\nprint(3 < 4 and \"Hola\" < \"Python\") # True and True = True\nprint(3 < 4 or \"Hola\" <  \"Python\") # True or True = True\nprint(3 < 4 and \"Hola\" > \"Python\") # True and Fasle = False\nprint(3 < 4 or \"Hola\" >  \"Python\") # True or False = True\nprint(not(3 > 4)) # Not(False) = True (Not niega)\n\n# Operadores bit a bit\nprint(bin(0b100001 & 0b101101)) # AND\nprint(bin(0b100001 | 0b101101)) # OR\nprint(bin(~0b101101)) # NOT (-x -1) (cambia a negativo y añade -1)\nprint(bin(0b100001 ^ 0b101101)) #XOR\nprint(bin(0b000100 >> 1)) # Desplaza todos los bits a la derecha un numero determinado de veces\nprint(bin(0b000100 << 1)) # Analogo de >>\n\n# Operadores de asignación\na = 20; print(a) #20\na += 2; print(a) #22\na -= 2; print(a) #20\na *= 2; print(a) #40\na /= 2; a = int(a); print(a) #20\na %= 3; print(a) #2\na **= 3; print(a) #8\na //= 3; print(a) #2\nb = 0b101010\nb &= 0b111111; print(bin(b)) #0b101010\nb |= 0b111111; print(bin(b)) #0b111111\nb = 0b101010\nb ^= 0b111111; print(bin(b)) #0b010101 = 0b10101\nb <<= 1; print(bin(b))\nb >>= 1; print(bin(b))\n\n# Operadores de identidad\n  \n  # is\na = 10\nb = 10\nprint(a is b) # True\nb = 15\nprint(a is b) # False\n  \n  # is not\na = 10\nb = 10\nprint(a is not b) # False\nb = 15\nprint(a is not b) # True\n\n# Operadores de pertenencia\nmy_str = \"Hola Python\"\nprint(\"Hola\" in my_str) # True\nprint(\"hola\" in my_str) # False\nmy_set = set([1, 2, 3, 4, 5])\nprint(3 in my_set) # True\nprint(8 in my_set) # False\nprint(8 not in my_set) # True\n\n# Estructuras de control\nnumber = 25\n  \n  # condicionales\nif number >= 10  and number <= 20:\n  print(number, \"es igual o mayor que 10 y menor o igual que 20\")\nelif number < 10:\n  print(number, \"es menor que 10\")\nelse:\n  print(number, \"es mayor que 20\")\n  \n  # iterativas\nwhile number > 0:\n  print(number)\n  number -= 1\n  \n  # for\nfor n in range(0, 6):\n  print(n)\n\n# EXTRA\nfor n in range(10, 56):\n  if n % 2 == 0 and n % 3 != 0 and n != 16:\n    print(n)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Sofia-d-p.py",
    "content": "#Operadores aritméticos\nprint(\"Operadores aritméticos\")\nprint(f\"sumar 10+3 = {10+3}\")\nprint(f\"restar 78-43 {78-43 }\")\nprint(f\"multiplicar 63*3 = {63*3}\")\nprint (f\"dividir 125/5 = {125/5}\")\nprint(f\"esto es elevar a una potencia 5**5= {5**5}\")\nprint(f\"es es una división entera 10 //3 {10//3}\")\nprint(f\"esto es el módulo de una división 10%3 = {10%3}\")\n\n#Operadores de comparación\nprint(\"Operadores de comparación\")\nprint(f\"este es el operador de igualdad 10 == 10 y es {10 == 10}\")\nprint(f\"este operador es desigual != {10!=3}\")\nprint(f\"este operador es mayor > {10>3}\")\nprint(f\"este operador es menor < {10<3}\")\nprint(f\"este operador es mayor o igual >= {10>=3}\")\nprint(f\"este operador es menor o igual <= {10<=3}\")\n\n#Operadores lógicos\nprint(\"Operadores lógicos\")\nprint(f\"Operador AND 25 + 10 = 35 and 25<50 {25 + 10 == 35 and 25<50}\") #Se cumplen las 2 condiciones\nprint(f\"Operador OR  25 + 10 = 45 OR 25<50 {25 + 10 == 45 or 25<50}\") #Se cumple 1 sola condición\nprint(f\"Operador NOT 25 > 50 {not 25>50}\") #Niega condición \n\n#Operadores de pertenencia\nprint(\"Operadores de pertenencia\")\nprint(f\"F en Sofia = {'f' in 'sofia'}\")\n\n#Operadores de asignación\na=7; b=2\nprint(\"Operadores de asignación\")\nx=a; x+=b;  print(\"x+=\", x)  # 9\nx=a; x-=b;  print(\"x-=\", x)  # 5\nx=a; x*=b;  print(\"x*=\", x)  # 14\nx=a; x/=b;  print(\"x/=\", x)  # 3.5\nx=a; x%=b;  print(\"x%=\", x)  # 1\nx=a; x//=b; print(\"x//=\", x) # 3\nx=a; x**=b; print(\"x**=\", x) # 49\n\n\n\n\"\"\"\nEstructuras de control\n\"\"\"\n\n#Condicionales \nprint(\"Condicionales\")\n\nmy_string = \"Sofita aprende Python\"\n\nif my_string == \"Sofita aprende Python\":\n    print(\"'my_string' es 'Sofita aprende Python'\")\nelif my_string == \"Sofita\":\n    print(\"'my_string' es 'Sofita'\")\nelse:\n    print(\"'my_string' es otra\")\n    \n#Iterativas\nprint(\"Iterativas\")\n\nfor i in range(0, 5):\n    print(i)\n        \n#Iterativa con while\nx = 5\nwhile x > 0:\n    x -=1\n    print(x)\n\n#Manejo de excepciones\nprint(\"Excepciones\")\ntry:\n    print(10/0)\nexcept ZeroDivisionError:\n    print(\"Error\")\nfinally:\n    print(\"Este bloque siempre se ejecuta\")\n    \n\"\"\"\nDificultad extra\n\"\"\"\n#Todos los numeros todos los números comprendidos entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3   \nprint(\"Dificultad extra\")    \nfor i in range (10,56):\n    if i % 2 ==0 and i != 16 and i % 3 != 0:\n        print (i)\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/SooHav.py",
    "content": "#01 OPERADORES Y ESTRUCTURAS DE CONTROL\n\n#Ejemplos de operadores con Python \n\n# Operadores aritméticos\nprint(f\"Adición entre los operandos: 12 + 3 = {12 + 3}\")\nprint(f\"Substracción entre los operandos: 12 - 3 = {12 - 3}\")\nprint(f\"Multiplicación entre los operandos: 12 * 3 = {12 * 3}\")\nprint(f\"División entre los operandos: 12 / 3 = {12 / 3}\")\nprint(f\"Módulo entre los operandos: 12 % 3 = {12 % 3}\")\nprint(f\"Potencia de los operandos: 12 ** 3 = {12 ** 3}\")\nprint(f\"División con resultado de número entero: 12 // 3 = {12 // 3}\")\n\n# Operadores relacionales\nprint(f\">  Devuelve True si el operador de la izquierda es mayor que el operador de la derecha\t12 > 3 = {12 > 3}\")\nprint(f\"<  Devuelve True si el operador de la derecha es mayor que el operador de la izquierda\t3 < 12 = {3 < 12}\")\nprint(f\"== Devuelve True si ambos operandos son iguales\t12 == 12 = {12 == 12}\")\nprint(f\">= Devuelve True si el operador de la izquierda es mayor o igual que el operador de la derecha\t12 >= 3 = {12 >= 3}\")\nprint(f\"=< Devuelve True si el operador de la derecha es mayor o igual que el operador de la izquierda\t3 <= 12 = {3 <= 12}\")\nprint(f\"!= Devuelve True si ambos operandos no son iguales 12 != 3 = {12 != 3}\")\n\n# Operadores lógicos\nprint(f\"and - True si ambos operandos son True: 12>1 and 3<6 = {12>1 and 3<6}\")\nprint(f\"or  - True si alguno de los operandos es True: 12>1 or 3>6 = {12>1 or 3>6}\")\nprint(f\"not - True si alguno de los operandos False: not 3<6 = {not 3>6}\")\n\n# Operadores de identidad\na = 10\nb = a\nprint(f\"is     Comprueba si dos variables hacen referencia a el mismo objeto: a is b es {a is b}\")\na = [1, 2, 3]\nb = [1, 2, 3]\nprint(f\"is     Comprueba si dos variables hacen referencia a el mismo objeto: a is b es {a is b}\")\nprint(f\"is not Comprueba si dos variables NO hacen referencia a el mismo objeto: a is not b es {a is b}\")\n\n# Operadores de pertenencia\na = 2\nb = [1, 2, 3]\nprint(f\"in     Comprueba si una variable se encuentra en la otra: a in b es {a in b}\")\nprint(f\"not in Comprueba si una variable no se encuentra en la otra: a in b es {a not in b}\")\n\n# Operadores con bits\nprint(bin(27))\n# 0b11011\n\n##Operador &\n'''recorre ambos números en su representación \nbinaria elemento a elemento, y hace una operación and \ncon cada uno de ellos'''\na = 0b1101\nb = 0b1011\nprint(bin(a & b)) \n#0b1001\n\n##Operador |\n'''realiza la operación or elemento a elemento con cada \nuno de los bits de los números que introducimos'''\na = 0b1101\nb = 0b1011\nprint(bin(a | b)) \n# 0b1111\n\n##Operador ~\n'''realiza la operación not sobre cada bit del número \nque le introducimos, es decir, invierte el valor de \ncada bit, poniendo los 0 a 1 y los 1 a 0'''\na = 40\nprint(bin(a))\nprint(bin(~a)) \n0b101000\n-0b101001\n\n##Operador ^\n'''realiza la función xor con cada bit de las dos variables que se le proporciona. \nLo que hace es devolver True o 1 cuando hay al menos un valor True pero no los dos. \nEs decir, solo devuelve 1 para las combinaciones 1,0 y 0,1 y 0 para las demás.'''\nx = 0b0110 ^ 0b1010 \nprint(bin(x))\n# 0 xor 1 = 1\n# 1 xor 0 = 1\n# 1 xor 1 = 0\n# 0 xor 0 = 0\n# 0b1100\n\n##Operador >>\n'''desplaza todos los bit n unidades a la derecha '''\na=0b1000\nprint(bin(a>>2)) \n# 0b10\n\n##Operador <<\n'''desplaza todos los bit n unidades a la izquierda '''\na=0b0001\nprint(bin(a<<3)) \n# 0b1000\n\n# Operadores de asignación\na=5 #valor asignado\nprint(f\"=   Asignación, el valor es asignado a una variable: a es {a}\")\na += 1\nprint(f\"+=  Suma, equivale a=(a + 1): a+=1 es {a}\")\na -= 2\nprint(f\"-=  Resta, equivale a=(a - 2): a-=2 es {a}\")\na *= 3\nprint(f\"*=  Multiplicación, equivale a=(a * 3): a*=3 es {a}\")\na /= 2\nprint(f\"/=  División, equivale a=(a / 2): a/=2 es {a}\")\na %= 4\nprint(f\"%=  Modulo, equivale a=(a % 4): a%=4 es {a}\")\na **= 3\nprint(f\"**= Potencia, equivale a=(a ** 3): a**=3 es {a}\")\na //= 3\nprint(f\"//= División entera, equivale a=(a // 3): a//=2 es {a}\")\na=5 #a partir de aqui requiere numeros enteros bit a bit\na &= 3\nprint(f\"&=  Comparación & bit a bit, equivale a=(a & 3): a&=2 es {a}\")\na |= 3\nprint(f\"|=  Operador | elemento a elemento, equivale a=(a | 3): a|=3 es {a}\")\na ^= 5\nprint(f\"^=  Operador ^ elemento a elemento, equivale a=(a ^ 5): a^=5 es {a}\")\na >>= 2\nprint(f\">>= Operador >>= elemento a elemento, equivale a=(a >> 2): a>>=2 es {a}\")\na <<= 5\nprint(f\"<<= Pperador <<= elemento a elemento, equivale a=(a << 5): a<<=5 es {a}\")\n\n#Estructuras de control con Python\n\"\"\"\nLas estructuras de control son herramientas que nos permiten condicionar \nla ejecución del código a ciertas circunstancias. \nEn Python, las estructuras de control más comunes son las condicionales y los bucles.\n-Condicional if\n-Bucle for\n-Bucle while\n-List comprehensions\n-excepciones (basicas)\n\"\"\"\n#Condicional if/else/elif\na = 4\nb = 2\nif b != 0:\n    c = a/b\n    d = c + 1\n    print(d)\n\nx = 5\nif x == 5:\n    print(\"Es 5\")\nelse:\n    print(\"No es 5\")\n\nx = 5\nif x == 5:\n    print(\"Es 5\")\nelif x == 6:\n    print(\"Es 6\")\nelif x == 7:\n    print(\"Es 7\")\nelse:\n    print(\"Es otro\")\n\nx = 6\nif not x%2:  #Como detectar par/impar\n    print(\"Es par\")\nelse:\n    print(\"Es impar\")\n    \n#Bucle for (range/break/continue/zip/enumerate)\nfor i in (0, 1, 2, 3, 4, 5):\n    print(i) \n\nfor i in range(0, 6):\n    print(i)   \n\nfor i in \"Python\":\n    print(i)\n\ntexto = \"Python\"\nfor i in texto[::-1]: #invierte\n    print(i) \n\nfor letra in texto:\n    if letra == 'h':\n        print(\"Se encontró la h\")\n        break #corta el bucle\n    print(letra)\n\nfor letra in texto:\n    if letra == 'P':\n        continue #salta unelemnto y continua hasta terminar el bucle\n    print(letra)\n\na = [1, 2]\nb = [\"Uno\", \"Dos\"]\nc = zip(a, b) \n\"\"\"\nsi pasamos dos listas a zip como entrada, \nel resultado será una tupla donde cada elemento \ntendrá todos y cada uno de los elementos i-ésimos \nde las pasadas como entrada.\n\"\"\"\nfor numero, texto in zip(a, b):\n    print(\"Número\", numero, \"Letra\", texto)\n\nlista = [\"A\", \"B\", \"C\"]\n\nfor indice, l in enumerate(lista):  #para acceder al indice y al elemento\n    print(indice, l)\n\n#List comprenhension\n\"\"\"\nLas list comprehension nos permiten crear \nlistas de elementos en una sola línea de código.\n\"\"\"\ncuadrados = [i**2 for i in range(5)]\n\n#Bucle While (else/pop)\nx = 5\nwhile x > 0:\n    x -=1\n    print(x)\n\nx = [\"Uno\", \"Dos\", \"Tres\"]\nwhile x:\n    x.pop(0) #pop elimina un elemnto de la lista\n    print(x)        \n\nx = 5\nwhile x > 0:\n    x -=1\n    print(x) #4,3,2,1,0\nelse:\n    print(\"El bucle ha finalizado\")\n\n# Manejo de excepciones\ntry:\n    print(10 / 0)\nexcept:\n    print(\"Se ha producido un error\")\nfinally:\n    print(\"Ha finalizado el manejo de excepciones\")\n\na = 10; b = 0\ntry:\n    c = a/b\nexcept ZeroDivisionError: #tipo de excepción\n    print(\"No se ha podido realizar la división\")\n\n# DIFICULTAD EXTRA (opcional):\n\"\"\" Crea un programa que imprima por consola todos los números comprendidos\n entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\"\"\"\n\nfor number in range(10, 56):\n    if number % 2 == 0 and number != 16 and number % 3 != 0:\n        print(number)\n\nnumeros = [i for i in range(56) if i%2==0 and i !=16 and i%3 !=0]\nprint(numeros)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Tashidian.py",
    "content": "# Aritméticos\nprint(\"ARITMÉTICOS\")\nop_add = 3 + 2 # sum\nop_substraction = 5 - 3 # resta\nop_multiplication = 3 * 3 # multiplicación\nop_division = 9 / 3 # división\nop_modulus = 10 % 5 # resto\nop_exponentiation = 2 ** 4 # potencia\nop_floor_division = 10 // 3 # cociente\n\nprint(f\"3 + 2 = {op_add}\")\nprint(f\"5 - 3 = {op_substraction}\")\nprint(f\"3 * 3 = {op_multiplication}\")\nprint(f\"9 / 3 = {op_division}\")\nprint(f\"10 % 5 = {op_modulus}\")\nprint(f\"2 ** 4 = {op_exponentiation}\")\nprint(f\"10 // 3 = {op_floor_division}\")\n\n# Lógicos o booleanos\nprint(\"LÓGICOS O BOOLEANOS\")\nval_1 = True\nval_2 = False\nop_or = val_1 or val_2 #or\nop_and = val_1 and val_2 #and\nop_not = not val_1 #not\n\nprint(f\"val_1 == {val_1}\")\nprint(f\"val_2 == {val_2}\")\nprint(f\"val_1 or val_2 = {op_or}\")\nprint(f\"val_1 and val_2 = {op_and}\")\nprint(f\"not val_1 = {op_not}\")\n\n# De comparación\nprint(\"DE COMPARACIÓN\")\nval_3 = 9\nval_4 = 1\n\nop_equal = val_3 == val_4\nop_less_than = val_3 < val_4\nop_greater_than = val_3 > val_4\nop_less_equal = val_3 <= val_4\nop_greater_equal = val_3 >= val_4\nop_not_equal = val_3 != val_4\n\nprint(f\"val_3 == {val_3}\")\nprint(f\"val_4 == {val_4}\")\nprint(f\"val_3 == val_4 -> {op_equal}\")\nprint(f\"val_3 < val_4 -> {op_less_than}\")\nprint(f\"val_3 > val_4 -> {op_greater_than}\")\nprint(f\"val_3 <= val_4 -> {op_less_equal}\")\nprint(f\"val_3 >= val_4 -> {op_greater_equal}\")\nprint(f\"val_3 != val_4 -> {op_not_equal}\")\n\n# Asignación\nprint(\"ASIGNACIÓN\")\nval_5 = 2\nprint(f\"val_5 = {val_5}\")\n\nval_5 += 2\n\nprint(f\"val_5 +=2 -> {val_5}\")\n\nval_5 -= 1\nprint(f\"val_5 -= 1 -> {val_5}\")\n\nval_5 *= 2\nprint(f\"val_5 *= 2 -> {val_5}\")\n\nval_5 /= 3\nprint(f\"val_5 /= 3 -> {val_5}\")\n\nval_5 %= 2\nprint(f\"val_5 %= 2 -> {val_5}\")\n\nval_6 = 10\nprint(f\"val_6 = {val_6}\")\n\nval_6 //= 2\nprint(f\"val_6 //= 2 -> {val_6}\")\n\nval_6 **= 2\nprint(f\"val_6 **= 2 -> {val_6}\")\n\nval_6 &= 3\nprint(f\"val_6 &= 3 -> {val_6}\")\n\nval_6 |= 4\nprint(f\"val_6 |= 4 -> {val_6}\")\n\nval_6 ^= 6\nprint(f\"val_6 ^= 6 -> {val_6}\")\n\nval_6 >>= 2\nprint(f\"val_6 >>= 2 -> {val_6}\")\n\nval_6 <<= 3\nprint(f\"val_6 <<= 3 -> {val_6}\")\n\n# Identidad\nprint(\"IDENTIDAD\")\nval_7 = 4\nlist_1 = [1, 2]\nop_is = val_7 is 4\nop_is_not = list_1 is not 2\n\nprint(f\"val_7 = {val_7}\")\nprint(f\"list_1 = {list_1}\")\nprint(f\"val_7 is 4 = {op_is}\")\nprint(f\"list_1 is not 2 = {op_is_not}\")\n\n# Pertenencia\nprint(\"PERTENECIA\")\nlist_2 = [1, 2, 3, 4]\nstring_1 = \"First string\"\n\nop_in = \"tri\" in string_1\nop_not_in = 5 not in list_2\n\nprint(f\"list_2 = {list_2}\")\nprint(f\"string_1 = {string_1}\")\nprint(f\"'tri' in string_1 =  {op_in}\")\nprint(f\"5 not in list_2 = {op_not_in}\")\n\n# Bits\nprint(\"BITS\")\nval_8 = 2\nval_9 = 7\n\nop_bit_or = val_8 | val_9\nop_bit_xor = val_8 ^ val_9\nop_bit_and = val_8 & val_9\nop_bit_n_left = val_9 << 2\nop_bit_n_right = val_9 >> 2\nop_bit_not = -val_8\n\nprint(f\"val_8 = {val_8}\")\nprint(f\"val_9 = {val_9}\")\nprint(f\"val_8 | val_9 = {op_bit_or}\")\nprint(f\"val_8 ^ val_9 = {op_bit_xor}\")\nprint(f\"val_8 & val_9 = {op_bit_and}\")\n\nprint(f\"val_9 << 2 = {op_bit_n_left}\")\nprint(f\"val_9 >> 2 = {op_bit_n_right}\")\nprint(f\"-val_8 = {op_bit_not}\")\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/ThePhobos01.py",
    "content": "# Operadores aritmeticos\n\nsuma = 3 + 2 # operador +\nprint(suma)\n\nresta = 5 - 2 # operador -\nprint(resta)\n\nmultiplicacion = 5 * 3 #operador *\nprint(multiplicacion)\n\ndivision = 10 / 2 # operador /\nprint(division)\n\ndivision_entera = 13 // 3 # operador //\nprint(division_entera)\n\ndivision_residuo = 13 % 3 # operador %\nprint(division_residuo)\n\nexponente = 3 ** 2 #operador **\nprint(exponente)\n\n# Operadores logicos\n\n# Operador and: devuelve True si ambos valores son True, devuelve False si alguna de los valores es False\n\nprint(True and True)\nprint(True and False)\nprint(False and False)\n\n# Operador or: devuelve True si al menos una de los valores es True, si ambos son False, devuelve False\n\nprint(True or True)\nprint(True or False)\nprint(False or False)\n\n# Operador not: Invierte el valor booleano\n\nprint(not True)\nprint(not False)\n\n# Operadores de comparacion\n\nprint(5 > 3) # 5 es mayor que 3, asi que devuelve True\nprint(5 < 3) # 5 no es menor que 3, asi que devuelve False\nprint(5 >= 5) # 5 si es igual o mayor que 5, asi que devuelve True\nprint(5 <= 5) # 5 si es menor o igual que 5, asi que devuelve True\nprint(5 == 5) # 5 si es igual que 5, asi que duevuelve True\nprint(5 != 4) # 5 no es igual a 4 asi que devuelve True\n\n# Operadores de asignacion\n\nvar = 5 # asigna un valor a una variable\nvar += 2 # suma un nuevo valor a la variable\nprint(var)\n\nvar -= 3 # resta un nuevo valor a la variable\nprint(var)\n\nvar *= 3 # multiplica por el valor asignado la variable\nprint(var)\n\nvar /= 2 # divide entre el valor asignado de la variable\nprint(var)\n\nvar %= 2 # Modulo del valor asignado a la variable\nprint(var)\n\nvar += 10\nvar //= 3 # Division entera\nprint(var)\n\nvar **= 2 # hace operacion de potencia a la variable\nprint(var)\n\n# Estructuras de control\n\n# Condicional if\n\nmi_numero = 5\n\nif mi_numero == 5:\n    print(\"mi numero es igual a 5\")\nelif mi_numero > 5:\n    print(\"mi numero es mayor que 5\")\nelse:\n    print(\"mi numero es menor que 5\")\n\n# Bucle for\n\nfor i in range(10):\n    print(i)\n\n# Bucle while\n\ni = 0\n\nwhile i <= 10:\n    print(i)\n    i += 1\n\n# Manejo de excepcion\ntry:\n    print (10 / 0)\nexcept: \n    print(\"No se puede dividir entre 0\")\nfinally:\n    print(\"Se concluyo el manejo de excepciones\")\n\n# Ejercisio de dificultad extra\n\nfor i in range(10, 56):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/TheReDNooB.py",
    "content": "print(\"***Python Operators***\\n\")\n\na,b = 3,5\n\n#Arithmetic Operators\n\nsuma = a + b\nresta = a - b\nmultiplicacion = a * b\ndivision = a / b\nmodulo = a % b\npotencia = a**b\ndivision_entera = a//b\n\nprint(f\"\"\"Python Arithmetic Operators\n    suma(+): {suma}\n    resta(-): {resta}\n    multiplicacion(*): {multiplicacion}\n    division(/): {division}\n    modulo(%): {modulo}\n    potencia(**): {potencia}\n    division_entera(//): {division_entera}\\n\n\"\"\")\n\n\n#Python Assignment Operators\n\na+=1\na-=1\na&=1\n\nprint(f\"\"\"Python Assignment Operators\n    los operadores de asignacion son usados para asignar valores a las variables.\n    Se realizan con el simbolo =, puedes hacer uso de los operadores aritmeticos\n    y los operadores a nivel de Bit (Bitwise)\n    {a}\\n\n\"\"\")\n\n#Python Comparison Operators\n\nigual = a==b\nno_igual = a!= b\nmayor_que = a>b\nmenor_que = a<b\nmayor_igual = a>=b\nmenor_igual = a<=b\n\nprint(f\"\"\"Python Comparison Operators\n    igual que(==): {igual}\n    diferente(!=): {no_igual}\n    mayor que(>): {mayor_que}\n    mayor o igual(>=): {mayor_igual}\n    menor que(<): {menor_que}\n    menor o igual(<=): {menor_igual}\\n\n\"\"\")\n\n#Python Logical Operators\n\ncond_and = (a>6 and b<1)\ncond_or = (a<3 and b==5)\ncond_not = not(a!=b)\n\nprint(f\"\"\"Python Logical Operators\n    AND: {cond_and} (solo si ambas condiciones son verdaderas retorna un True)\n    OR: {cond_or} (si una de las condiciones es verdadera retorna True)\n    NOT: {cond_not} (revierte el resultado, si la condicion es True lo revierte a False)\\n\n\"\"\")\n\n#Python Identity Operators\n\noperator_is = a is b\noperator_is_not = a is not b\n\nprint(f\"\"\"Python Identity Operators\n    is; retorna True si las variables son el mismo objeto, {operator_is}\n    is not; retorna False si ambas variables no son el mismo objeto, {operator_is_not}\\n\n\"\"\")\n\n\n#Python Membership Operators\n\nfruits = [\"manzana\", \"tomate\"]\n\nprint(\"Python Membership Operator\")\nprint(\"banana\" in fruits)\nprint(\"banana\" not in fruits)\n\n#Python Bitwise Operators\n\nbit_and = a&b\nbit_or = a|b\nbit_not = ~b\nbit_xor = a^b\n\nprint(f\"\"\"\\nPython Bitwise Operators\n    AND(&): Compara cada bit de dos números y devuelve\n    1 solo si ambos bits son 1. {bit_and}\n\n    OR(|): Compara cada bit y devuelve 1 si uno de ellos\n    es 1. {bit_or}\n\n    NOT(~): Invierte los bits de un numero {bit_not}\n\n    XOR(^): Compara cada bit si al menos uno de los bits\n    es 1 (no ambos) {bit_xor}\\n\n\"\"\")\n\n#Estructuras de Control\n\n#Condicionales\"\nif a > b:\n    print(\"el mayor el a\")\nelif a < b:\n    print(\"el mayor es b\")\nelse:\n    print(\"ambas variables son iguales\")\n\nnota_aprobatoria = 5.0\n\nmatch nota_aprobatoria:\n    case 5.0:\n        print(\"puntaje alto\")\n    case 4.0:\n        print(\"puntaje aceptable\")\n    case 3.0:\n        print(\"puntaje promedio\")\n    case 2.0:\n        print(\"puntaje bajo\")\n    case 1.0:\n        print(\"reprobado\")\n\n#Bucles\n\n#for\nfor i in range(1,10):\n    print(f\"iteracion N°{i}\")\n\n#while\ni = 0\nwhile i<6:\n    print(f\"bucle N°{i}\")\n    i+=1\n\n#Extra\n\nfor i in range(10,56):\n    if i%2==0 and i!=16 and i%3!=0:\n        print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/ThonyS07.py",
    "content": "# aritméticos\nsuma=10+3\nresta=10-3\nmultiplicacion=10*3\ndivision=10/3\nmodulo=10%3\nexponente=10**3\ndivisionEntera=10//3\nprint(\"Aritmeticos:\\nSuma: \", suma,\"\\nResta: \", resta,\"\\nMultiplicacion: \", multiplicacion,\"\\nDivision: \", division,\"\\nModulo: \", modulo,\"\\nExponente: \", exponente,\"\\nDivision entera: \", divisionEntera)\n\n\n#relacionales\nprint(f\"> True si izquierda es mayor que derecha: 5>3 es {5>3} false en caso contrario: 3>5 es {3>5}\")\nprint(f\"< True si izquierda es menor que derecha: 5<8 es {3<5} false en caso contrario: 8<5 es {5<3}\")\nprint(f\">= True si izquierda es mayor o igual que derecha: 5>=3 es {5>=3} false en caso contrario: 3>=5 es {3>=5}\")\nprint(f\"<= True si izquierda es menor o igual que derecha: 3<=5 es {3<=5} false en caso contrario: 5<=3 es {5<=3}\")\nprint(f\"== True si izquierda es igual que derecha: 3==3 es {3==3} false en caso contrario: 3==5 es {3==5}\")\nprint(f\"!= True si izquierda NO ES igual que derecha: 3!=5 es {3!=5} false en caso contrario: 3!=3 es {3!=3}\")\n\n\n#lógicos\nprint(f\"and &: True si ambos operandos son true: {5+2==7 & 3-1==2} false si alguno es false {4 + 3 == 13 and 3 - 1 == 2}\")\nprint(f\"or |: True si alguno de los operandos es true: {5+3==7 | 3-1==2} false si ninguno es true {4 + 3 == 13 or 2 - 1 == 2}\")\nprint(f\"not !: True si alguno de los operandos es false: {not(5==7)} false si ninguno es false {(7!= 7 )}\")\n\n#pertenencia\nprint(f\"in: True si el valor especificado se encuentra en la secuencia: 'hon' in 'thony' es { 'hon' in 'thony'} false en caso contrario 1 in [1, 2, 3] es {1 in [1, 2, 3]}\")\nprint(f\"not in: True si el valor especificado no se encuentra en la secuencia: 'z' not in 'thony' es { 'z' not in 'thony'} false en caso contrario: 1 not in [1, 2, 3] es {1 not in [1, 2, 3]}\")\n\n#asignacion\nnumero=5 \nprint(f\"asignacion numero = {numero}\")\nnumero+=5\nprint(f\"suma y asignacion += {numero}\") \nnumero-=5 #resta y asignacion\nprint(f\"resta y asignacion -= {numero}\") \nnumero*=3 #multiplicacion y asignacion\nprint(f\"multiplicacion y asignacion *= {numero}\") \nnumero/=3 #división y asignacion\nprint(f\"división y asignacion /= {numero}\") \nnumero%=3 #módulo y asignacion\nprint(f\"módulo y asignacion %= {numero}\") \nnumero**=3 #exponente y asignacion\nprint(f\"exponente y asignacion **= {numero}\") \nnumero//=3 #división entera y asignacion\nprint(f\"división entera y asignacion //= {numero}\") \n\n#identidad\na=3\nb=3\nc=4\nprint(f\" is es true si los operandos se refieren al mismo objeto identidad a is b es {a is b}\")\nprint(f\"is not es true si los operandos no se refieren al mismo objeto identidad a is not b es {a is not b}\")\nprint(f\"identidad a is not c es {a is not c}\")\n\n\n# Operadores de bit\na = 2  # 10\nb = 3  # 11\nprint(f\"AND: 2 & 3 = {2 & 3}\")  # 10\nprint(f\"OR: 2 | 3 = {2 | 3}\")  # 11\nprint(f\"XOR: 2 ^ 3 = {2 ^ 3}\") #01\nprint(f\"NOT: ~2 = {~2}\")#01\nprint(f\"Desplazamiento a la derecha: 2 >> 3 = {2>> 3}\")  # 0\nprint(f\"Desplazamiento a la izquierda: 2<< 3 = {2 << 3}\")  #10000\n\n# Condicionales\n\nmy_variable=\"It's me\"\n\nif type(my_variable) == str:\n    print(f\"my_variable es {my_variable} una cadena de texto\")\nelif type(my_variable) == int:\n    print(f\"my_variable es {my_variable} un entero\")\nelse:\n    print(\"my_variable no es cadena de texto ni entero\")\n\n# Iterativas\n\nfor i in range(11):\n    print(f\"imprimiendo cada valor hasta culminar {i}\")\n\ni = 0\n\nwhile i <= 5:\n    print(f\"imprimiendo cada valor hasta culminar {i}\")\n    i += 1\n\n# Manejo de excepciones\ntry:\n    print(10 / 2)\n    print(10 / 0)\nexcept:\n    print(\"Hubo un error\")\nfinally:\n    print(\"Culminado el manejo de excepciones\")\n\n\n#EXTRA\nfor number in range(10, 56):\n    if number % 2 == 0 and number != 16 and number % 3 != 0:\n        print(number)\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/TizoG.py",
    "content": "# Ejemplos de Operadores\n\nprint(1 + 1) # Suma\nprint(1 - 1) # Resta\nprint(2 * 2) # Multiplicacion\nprint(2 / 2) # Division\nprint(5 % 2) # Modulo\nprint(10 // 3) # Division con resultado entero forzado\nprint(2 ** 2) # Potenciacion\n\n# Operaciones con enteros\nprint(3 < 2) # Menor\nprint(3 > 2) # Mayor\nprint(3 <= 2) # Menor o Igual\nprint(3 >= 2) # Mayor o Igual \nprint(3 == 2) # Igualdad\nprint(3 != 2) # Desigualdad\n\n# Operadores Logicos\nprint(3 < 2 and \"hola\" < \"mundo\") # Retorna verdadero si ambos son verdadero\nprint(3 < 2 or \"hola\" < \"mundo\") # Retorna verdad si uno de los dos es verdadero\nprint(3 > 2 and \"hola\" > \"mundo\")\nprint(3 > 2 or \"hola\" > \"mundo\")\nprint(not(3 > 4)) # Da el valor contrario\n\n# Operadores de asignación \nmy_number = 1\nprint(my_number)\nmy_number += 1 # suma y asignación \nprint(my_number)\nmy_number -= 1\nprint(my_number)\nmy_number *= 2\nprint(my_number)\nmy_number /= 2\nprint(my_number)\nmy_number %= 2\nprint(my_number)\nmy_number **= 2\nprint(my_number)\nmy_number //= 1\nprint(my_number)\n\n\n\n# Operadores de identidad\nmy_nuevo_numero = my_number\nprint(f\"my_number is my_nuevo_numero es {my_number is my_nuevo_numero}\")\nprint(f\"my_numer is not my_nuevo_numero {my_number is not my_nuevo_numero}\")\n\n# Operadores de pertenencia\nprint(f\"'i' in 'TizoG' = {'i' in 'TizoG'}\")\nprint(f\"'a' in 'TizoG' = {'a' in 'TizoG'}\")\n\n# Operadores de bit\na = 5\nb = 2\nprint(f\"AND : 5 & 2 = {5 & 2}\")\nprint(f\"OR: 5 | 2 = {5| 2}\")\nprint(f\"XOR: 5 ^ 2 = {5 ^ 2}\")\nprint(f\"Desplazamiento a la derecha: 5 >> 2 = {5 >> 2}\")\nprint(f\"Desplazamiento a la izquierda: 5 << 2 = {5 << 2}\")\n\n\"\"\"\nEstructuras de control\n\"\"\"\n\n# Condicionales\nmy_name = \"TizoG\"\nif my_name == \"TizoG\":\n    print(\"my_name is 'TizoG'\")\nelif my_name == \"tizog\":\n    print(\"my_name is 'tizog'\")\nelse:\n    print(\"my_name no es 'TizoG' ni 'tizog'\")\n\n# Iterativas\nfor i in range(11):\n    print(i)\n\ni = 0\nwhile i <= 10:\n    print(i)\n    i += 1\n\n# Manejo de excepciones\ntry: \n    print(10 /0)\nexcept:\n    print(\"Se ha produicido un error\")\nfinally:\n    print(\"ha finalizado el manejo de excepciones\")\n\n\n\"\"\"\nExtra\n\"\"\"\n\nfor number in range(10, 56):\n    if number % 2 == 0 and number != 16 and number % 3 != 0:\n        print(number)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Tomu98.py",
    "content": "\"\"\" Reto 01: Operadores y Estructuras de control \"\"\"\n\n\"\"\" Operadores \"\"\"\n\n# Operadores Aritméticos\nprint(f\"Suma: 11 + 10 = {11 + 10}\")\nprint(f\"Resta: 32 - 11 = {32 - 11}\")\nprint(f\"Multiplicación: 3 * 7 = {3 * 7}\")\nprint(f\"División: 63 / 3 = {63 / 3}\")\nprint(f\"Módulo: 10 % 4 = {10 % 4}\")\nprint(f\"División entera: 4 // 3 = {4 // 3}\")\nprint(f\"Exponente: 2 ** 4 = {2 ** 4}\")\n\n# Operadores de Comparación\nprint(f\"Igualdad: 21 == 12 es {21 == 12}\")\nprint(f\"Desigualdad: 21 != 12 es {21 != 12}\")\nprint(f\"Mayor que: 21 > 12 es {21 > 12}\")\nprint(f\"Menor que: 21 < 12 es {21 < 12}\")\nprint(f\"Mayor o igual que: 21 >= 21 {21 >= 21}\")\nprint(f\"Menor o igual que: 12 <= 21 es {12 <= 21}\")\n\n# Operadores Lógicos\nprint(f\"AND: 21 > 12 and 12 < 21 es {21 > 12 and 12 < 21}\")\nprint(f\"OR: 21 < 12 or 12 < 21 es {21 < 12 or 12 < 21}\")\nprint(f\"NOT: not 21 < 12 es {not 21 < 12}\")\n\n# Operadores de Asignación\nvar = 21   # asignación\nprint(var)\nvar += 1   # suma y asignación\nprint(var)\nvar -= 1   # resta y asignación\nprint(var)\nvar *= 2   # multiplicación y asignación\nprint(var)\nvar /= 2   # división y asignación\nprint(var)\nvar %= 4   # módulo y asignación\nprint(var)\nvar **= 1  # exponente y asignación\nprint(var)\nvar //= 1  # división entera y asignación\nprint(var)\n\n# Operadores de Identidad y Pertenencia\nnueva_var = var\nprint(f\"var is nueva_var es {var is nueva_var}\")\nprint(f\"var is not nueva_var es {var is not nueva_var}\")\nprint(f\"'T' in 'Tomu98' = {'T' in 'Tomu98'}\")\nprint(f\"'i' not in 'Tomu98' = {'i' not in 'Tomu98'}\")\n\n# Operadores de bit\na = 10  # 1010\nb = 3   # 0011\nprint(f\"AND: 10 & 3 = {10 & 3}\")  # 0010\nprint(f\"OR: 10 | 3 = {10 | 3}\")   # 1011\nprint(f\"XOR: 10 ^ 3 = {10 ^ 3}\")  # 1001\nprint(f\"NOT: ~10 = {~10}\")\nprint(f\"Desplazamiento a la derecha: 10 >> 2 = {10 >> 2}\")   # 0010\nprint(f\"Desplazamiento a la izquierda: 10 << 2 = {10 << 2}\") # 101000\n\n\n\n\"\"\" Estructuras de control \"\"\"\n\n# Condicionales\nmy_string = \"Tomu98\"\nif my_string == \"Tomu98\":\n    print(\"my_string es 'Tomu98'\")\nelif my_string == \"Arlert\":\n    print(\"my_string es 'Tomu Arlert'\")\nelse:\n    print(\"my_string no es 'Tomu98' ni 'Tomu Arlert'\")\n\n# Iterativas\nfor i in range(11):\n    print(i)\n\ni = 0\nwhile i <= 10:\n    print(i)\n    i += 1\n\n# Manejo de excepciones\ntry:\n    print(10 / 0)\nexcept:\n    print(\"Se ha producido un error\")\nfinally:\n    print(\"Ha finalizado el manejo de excepciones\")\n\n\n\n\"\"\" Reto extra \"\"\"\n\nfor number in range(10, 56):\n    if number % 2 == 0 and number != 16 and number != 0:\n        print(number)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Tonywarcode.py",
    "content": "num_x = 7\nnum_y = 3\n\n\n\n### Operadores de Asignación ###\nprint(\"---- Operadores Asignacion ----\")\n\nx=num_x; x+=num_y   #suma\nprint(\"x+=\", x)\n\nx=num_x; x-=num_y   #resta\nprint(\"x-=\", x)\n\nx=num_x; x*=num_y   #multiplicación\nprint(\"x*=\", x)\n\nx=num_x; x/=num_y   #división\nprint(\"x/=\", x)\n\nx=num_x; x%=num_y   #Módulo\nprint(\"x%=\", x)\n\nx=num_x; x**=num_y  #Exponente\nprint(\"x**=\", x)\n\nx=num_x; x//=num_y  #Cociente\nprint(\"x//=\", x)\n\nx=num_x; x&=num_y   #bit a bit con AND\nprint(\"x&=\", x)\n\nx=num_x; x|=num_y   #bit a bit con OR\nprint(\"x|=\", x)\n\nx=num_x; x^=num_y   #bit a bit con XOR\nprint(\"x^=\", x)\n\nx=num_x; x>>=num_y  #bit a bit desplazamiento a izquierda\nprint(\"x>>=\", x)\n\nx=num_x; x<<=num_y  #bit a bit desplazamiento a derecha\nprint(\"x<<=\", x )\nprint('\\n')\n\n### Operadores Aritméticos ###\nprint(\"---- Operadores Aritméticos ----\")\n\nprint(\"Suma x+y= \", num_x+num_y)\nprint( 10 + 5) # se puede operar directamente\nprint(\"Resta x-y= \", num_x-num_y)\nprint( 10 - 5)\nprint(\"Multiplicación x*y= \", num_x*num_y)\nprint( 10 * 5)\nprint(\"División x/y= \", num_x/num_y)\nprint( 10 / 5)\nprint(\"Módulo x%y= \", num_x%num_y)\nprint( 10 % 5)\nprint(\"Exponente x**y= \", num_x**num_y)\nprint( 10 ** 5)\nprint(\"Cociente x//y= \", num_x//num_y)\nprint( 10 // 5)\nprint('\\n')\n\n### Operadores Relacionales ###\nprint(\"---- Operadores Relacionales ----\")\n\nprint(\"x==y\", num_x==num_y) #false\nprint(\"x=!y\", num_x!=num_y) #true\nprint(\"x>y\", num_x>num_y) #true\nprint(\"x<y\", num_x<num_y) #false\nprint(\"x>=y\", num_x>=num_y) #true\nprint(\"x<=y\", num_x<=num_y) #false\nprint('\\n')\n\n### Operadores lógicos ###\n\nprint(\"---- Operadores Lógicos ----\")\nprint(\"**AND**\")\nprint(True and True) #true\nprint(True and False) #false\nprint(False and True) #false\nprint(False and False) #false\nprint('\\n')\n\nprint(\"**OR**\")\nprint(True or True) #true\nprint(True or False) #true\nprint(False or True) #true\nprint(False or False) #false\nprint('\\n')\n\nprint(\"**NOT**\")\nprint(not True) #false\nprint(not False) #true\nprint(not not not not True) #true\nprint('\\n')\n\n### Operadores Identidad ###\nprint(\"---- Operadores Identidad ----\")\n\na= 1\nb= 1\nprint(num_x is num_y) #false\nprint(a==b) #true\nprint( a is b) # true\nprint(a is not b)  # false\nprint(num_x is not num_y)  # True\nprint('\\n')\n\n### Operadores Pertenencia ###\nprint(\"---- Operadores Pertenencia ----\")\nlista =[1, 2, 3]\nprint(3 in lista) #true\nprint(5 in lista) #false\nprint(3 not in lista) #false\nprint(5 not in lista) #true\nprint('\\n')\n\n# Operadores de bit\nprint(\"---- Operadores bit ----\")\n\na=7 #111\nprint(bin(a))\nb=10 #1010\nprint(bin(b))\n\nprint(a & b) \nprint(a | b) \nprint(~a)\nprint(a^b)\nprint(a>>b)\nprint(a<<b)\n\n\n### Tipos Estructuras de Control ###\nprint(\"---- Condicional if-elif-else ----\")\n\nif num_x == num_y:\n    print(\"Son Iguales\")\nelse:\n    print(\"No son iguales\")\n\n\nif num_y == 3:\n    print(\"Es el número 3\")\nelif num_y == 6:\n    print(\"Es el número 6\")\nelif num_y == 7:\n    print(\"Es el número 7\")\nelse:\n    print(\"Es otro número\")\n\nprint('\\n')\n\nprint(\"---- Repetitivas - Bucles ----\")\n\n#Bucle FOR\nprint(\"** FOR **\")\n#número de iteraciones(repeticiones) ya esta definido\n\nfor i in range(0, 5):\n    print(i)\n\nprint('\\n')\n\ntext1 = \"python\"\nfor j in text1[::-1]:\n    print(j)\n\nprint('\\n')\n\nfor i in range(6, 60, 2):  #range(inicio, fin, salto)\n    print(i, end=\" \")\n\nprint('\\n')\n\n#Bucle While\nprint(\"** while **\")\n#iteraciones no definidas\n\nx = 5\nwhile x > 0:\n    x -=1\n    print(x)\nprint('\\n')\n\n### Excepciones ###\nprint(\"---- Excepciones ----\")\ntry:\n    print(num_x / 0)    # si hay error no la ejecuta salta al except\n    print(\"No se ha producido un error\")    \nexcept:\n    # Se ejecuta si se produce una excepción\n    print(\"Se ha producido un error\")\nfinally:\n    print(\"Se finaliza la excepción\")\n\n    \nprint('\\n')\n\n# *** extra ***\n# Crea un programa que imprima por consola todos los números comprendidos\n# entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\n# Lista para almacenar los números que cumplen con las condiciones\nnumeros = []\n\n# Recorrer los números del 10 al 55\nfor num in range(10, 56):  \n    # Verificar si el número es par, no es 16 y no es múltiplo de 3\n    if num % 2 == 0 and num != 16 and num % 3 != 0:\n        # Añadir el número a la lista si cumple con todas las condiciones\n        numeros.append(num)\n\n# Imprimir los números que cumplen las condiciones\nprint(numeros)\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/TroyNebula.py",
    "content": "#!/usr/bin/env python\r\n\r\n''' \r\nCrea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\r\naritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\r\n(Ten en cuenta que cada lenguaje puede poseer unos diferentes)\r\n'''\r\n # Debes hacer print por consola del resultado de todos los ejemplos.\r\n\r\nprint(\"***Operadores Aritméticos***\")\r\nprint (\"suma 1+2=\",(1+2),\"\\n\"\"resta 2-1=\",(2-1),\"\\n\"\"multiplicación 2*2=\",(2*2),\"\\n\"\"división 10/3=\" ,(10/3),\"\\n\"\"devuelve resto de división 10/3=\" ,(10%3),\"\\n\"\"división sin decimales 10/3=\",(10//3),\"\\n\"\"exponenciación 3 elevado a 3=\",(3**3))\r\nprint(f\"Suma: 10 + 3 = {10 + 3}\")  # una sola línea por operador y más limpio\r\nprint()\r\n# \r\nprint(\"***Operadores de Comparación***\")  # Devuelven booleano    \r\nprint(\"¿Es 1 igual a 1?:\",(1==1),\"\\n\"\"¿2 es diferente de 3?=\",(2!=3),\"\\n\"\"¿Es 10 mayor que 1?:\",(10>1),\"\\n\"\"¿Es 10 menor que 1?:\",(10<1),\"\\n\"\"¿Es 1 mayor o igual que 1?:\",(1>=1),\"\\n\"\"¿Es 2 menor o igual que 1?:\",(2<=1),\"\\n\")\r\n\r\nprint(\"***Operadores Lógicos***\")\r\nUno=1\r\nprint(f\"1=1 y 2+2=4: {(1==1) and (2+2==4)},\\n1=1 o 2+3=4: {(1==1) or (2+3==4)},\\nUno no es 3: {not Uno == 3}\")\r\nprint()\r\n\r\nprint(\"***Operadores de asignación***\")\r\nvariable=10\r\nprint (\"Mi variable es:\",variable)\r\nprint (\"Mi variable es al sumarle 1:\",variable+1) # suma y asignación\r\nvariable -=1 # resta y asignación\r\nprint (\"Mi variable es al restarle 1:\",variable)\r\nprint(\"... También podemos combinar con los demás operadores aritméticos como **= etc.\")\r\nprint()\r\n\r\nprint (\"vOperadores de Identidad***\")  # comparan valores de la posición de memoria no de la variable\r\nnueva_variable= variable\r\nprint (\"Mi nueva variable es igual a variable:\",(nueva_variable is variable))\r\nprint (\"Mi nueva variable no es igual a variable:\",(nueva_variable is not variable))\r\nprint()\r\n\r\nprint (\"***Operadores de pertenencia***\")  # si algo existe en otro conjunto\r\nprint(f\"'u' está en Nebula: {\"u\" in \"Nebula\"}\")\r\nprint(f\"'h' no está en Nebula: {\"h\" not in \"Nebula\"}\")\r\nprint()\r\n\r\nprint (\"***Operadores de Bit***\")\r\na = 10  # 1010\r\nb = 3  # 0011\r\nprint(f\"AND: 10 & 3 = {10 & 3}\")  # 0010\r\nprint(f\"OR: 10 | 3 = {10 | 3}\")  # 1011\r\nprint(f\"XOR: 10 ^ 3 = {10 ^ 3}\")  # 1001\r\nprint(f\"NOT: ~10 = {~10}\")\r\nprint(f\"Desplazamiento a la derecha: 10 >> 2 = {10 >> 2}\")  # 0010\r\nprint(f\"Desplazamiento a la izquierda: 10 << 2 = {10 << 2}\")  # 1010\r\nprint()\r\n\r\n''' \r\nUtilizando las operaciones con operadores que tú quieras, crea ejemplos\r\nque representen todos los tipos de estructuras de control que existan\r\nen tu lenguaje:\r\nCondicionales, iterativas, excepciones...\r\n '''\r\n # Debes hacer print por consola del resultado de todos los ejemplos.\r\n\r\nprint(\"***Estructuras de control***\")\r\nprint(\"***Condicionales***\")\r\n\r\nmi_string = \"Nebula\"\r\nif mi_string == \"Nebula\":\r\n    print(\"mi_string es 'Nebula'\")\r\nelif my_string == \"Troy\":\r\n    print(\"mi_string es 'Troy'\")\r\nelse:\r\n    print(\"mi_string no es ni 'Nebula' ni 'Troy'\")\r\nprint()\r\n\r\nprint(\"***Iterativas***\")\r\nprint(\"Deben salir del 0 al 5:\")\r\nfor i in range(6):\r\n    print(i)\r\ni = 0\r\nwhile i <= 5:\r\n    print(i)\r\n    i += 1\r\nprint()\r\n\r\nprint(\"***Manejo de excepciones***\")\r\ntry:\r\n    print(10 / 0)  #intenta\r\nexcept:\r\n    print(\"¡¡Se ha producido un error!!\")  #si no funciona\r\nfinally:\r\n    print(\"Ha finalizado el intento/manejo de excepciones\")  #sí o sí cuando acabe la excepción\r\nprint()\r\n\r\n'''DIFICULTAD EXTRA (opcional):\r\nCrea un programa que imprima por consola todos los números comprendidos\r\n entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.'''\r\n\r\nprint (\"***Números comprendidos entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3:***\")\r\ndef numeros_pares():\r\n    for num in range (10,56):\r\n        if num % 2 ==0 and num !=16 and num %3!=0:\r\n            print (num)\r\n\r\nnumeros_pares()\r\n            \r\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Vesubius.py",
    "content": "\"\"\" \nEJERCICIO:\n  - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n    Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n    (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n\n  - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n   que representen todos los tipos de estructuras de control que existan\n   en tu lenguaje:\n   Condicionales, iterativas, excepciones...\n\n  - Debes hacer print por consola del resultado de todos los ejemplos.\n \n DIFICULTAD EXTRA (opcional):\n    Crea un programa que imprima por consola todos los números comprendidos\n    entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n \n    Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n \n \"\"\"\n\n\n# ****************************************** OPERADORES *******************************************************************\n#========================================= Operadores aritmeticos =========================================\nprint(\"========================================= Operadores aritmeticos =========================================\")\n# Suma\na = 5\nb = 3\nresultado_suma = a + b\nprint(\"Suma de\", a, \"y\", b, \"es:\", resultado_suma)  \n\n# Resta\na = 7\nb = 2\nresultado_resta = a - b\nprint(\"Resta de\", a, \"y\", b, \"es:\", resultado_resta)  \n\n# Multiplicación\na = 4\nb = 6\nresultado_multiplicacion = a * b\nprint(\"Multiplicación de\", a, \"y\", b, \"es:\", resultado_multiplicacion)  \n\n# División\na = 10\nb = 2\nresultado_division = a / b\nprint(\"División de\", a, \"y\", b, \"es:\", resultado_division)  \n\n# División entera\na = 10\nb = 3\nresultado_division_entera = a // b\nprint(\"División entera de\", a, \"y\", b, \"es:\", resultado_division_entera)  \n\n# Módulo\na = 10\nb = 3\nresultado_modulo = a % b\nprint(\"Módulo de\", a, \"y\", b, \"es:\", resultado_modulo)  \n\n# Potencia\na = 2\nb = 3\nresultado_potencia = a ** b\nprint(\"Potencia de\", a, \"a la\", b, \"es:\", resultado_potencia)  \n\n\n\n#================================================== Operadores Logicos ===========================================\nprint(\"================================================== Operadores Logicos ===========================================\")\n# Operador AND (and)\nx = 5\ny = 10\nz = 15\nresultado_and = (x < y) and (y < z)\nprint(\"Operador AND:\", resultado_and) \n\n# Operador OR (or)\nedad = 25\nnacionalidad = \"Mexicana\"\nes_adulto = (edad >= 18) or (nacionalidad == \"Mexicana\")\nprint(\"Operador OR:\", es_adulto)  \n\n# Operador NOT (not)\nllueve = False\nprint(\"Operador NOT:\", not llueve)  \n\n# Operador XOR (^)\na = True\nb = False\nresultado_xor = a ^ b\nprint(\"Operador XOR:\", resultado_xor)  \n\n#================================================== Operadores de comparacion ===========================================\nprint(\"================================================== Operadores de comparacion ===========================================\") \n# Operador de igualdad (==)\na = 5\nb = 5\nresultado_igual = a == b\nprint(\"Operador de igualdad:\", resultado_igual) \n\n# Operador de desigualdad (!=)\nx = 10\ny = 20\nresultado_desigual = x != y\nprint(\"Operador de desigualdad:\", resultado_desigual) \n# Operador de mayor que (>)\nnum1 = 15\nnum2 = 10\nresultado_mayor = num1 > num2\nprint(\"Operador de mayor que:\", resultado_mayor)  \n\n# Operador de menor que (<)\nnum3 = 5\nnum4 = 8\nresultado_menor = num3 < num4\nprint(\"Operador de menor que:\", resultado_menor)  \n\n# Operador de mayor o igual que (>=)\nx = 10\ny = 10\nresultado_mayor_igual = x >= y\nprint(\"Operador de mayor o igual que:\", resultado_mayor_igual)  \n\n#================================================== Operadores de asignacion ===========================================\nprint(\"================================================== Operadores de asignacion ===========================================\") \n# Operador de asignación (=)\nx = 5\nprint(\"Operador de asignación:\", \"x = 5:\", x)  \n\n# Operador de asignación con suma (+=)\ny = 10\ny += 5\nprint(\"Operador de asignación con suma:\", \"10 += 5:\", y)  \n\n# Operador de asignación con resta (-=)\nz = 20\nz -= 7\nprint(\"Operador de asignación con resta:\", \"20 -= 7:\", z) \n\n# Operador de asignación con multiplicación (*=)\na = 3\na *= 4\nprint(\"Operador de asignación con multiplicación:\", \"3 *= 4:\", a)  \n\n# Operador de asignación con división (/=)\nb = 25\nb /= 5\nprint(\"Operador de asignación con división:\", \"25 /= 5:\", b)  \n\n# Operador de asignación con módulo (%=)\nc = 17\nc %= 5\nprint(\"Operador de asignación con módulo:\", \"17 %= 5:\", c)  \n\n# Operador de asignación con exponente (**=)\nd = 2\nd **= 3\nprint(\"Operador de asignación con exponente:\", \"2 **=3\", d)  \n\n# Operador de asignación con división entera (//=)\ne = 25\ne //= 4\nprint(\"Operador de asignación con división entera:\", \"25 //= 4:\", e) \n\n\n#================================================== Operadores de identidad ===========================================\nprint(\"================================================== Operadores de identidad ===========================================\") \n\n# Operador de identidad (is)\nx = [1, 2, 3]\ny = [1, 2, 3]\nz = x\nprint(\"La lista x:\",x)\nprint(\"La lista y:\",y)\nprint(\"La lista z es una compia de la x\",z)\n\nprint(\"Operación: x is y =\", x is y)\nprint(\"Operación: x is z =\", x is z)\n\n# Operador de no identidad (is not)\nprint(\"Operación: x is not y =\", x is not y)\n\n\n# #================================================== Operadores de Pertenencia ===========================================\nprint(\"================================================== Operadores de Pertenencia ===========================================\") \n# Operador de pertenencia (in)\nlista = [1, 2, 3, 4, 5]\nprint(lista)\nprint(\"Operador de pertenencia 3 (in) lista :\", 3 in lista)\n\n# Operador de no pertenencia (not in)\nprint(\"Operador de no pertenencia 6 (not in) lista:\", 6 not in lista)\n\n\n# #================================================== Operadores de bits ===========================================\nprint(\"================================================== Operadores de bits ===========================================\") \n\n# Operador AND a nivel de bits (&)\nresultado_and = 15 & 7\nprint(\"Operación: 15 & 7 =\", resultado_and)\n\n# Operador OR a nivel de bits (|)\nresultado_or = 15 | 7\nprint(\"Operación: 15 | 7 =\", resultado_or)\n\n# Operador XOR a nivel de bits (^)\nresultado_xor = 15 ^ 7\nprint(\"Operación: 15 ^ 7 =\", resultado_xor)\n\n# Operador NOT a nivel de bits (~)\nresultado_not = ~15\nprint(\"Operación: ~15 =\", resultado_not)\n\n# Operador Desplazamiento a la izquierda (<<)\nresultado_despl_izq = 15 << 2\nprint(\"Operación: 15 << 2 =\", resultado_despl_izq)\n\n# Operador Desplazamiento a la derecha (>>)\nresultado_despl_der = 15 >> 2\nprint(\"Operación: 15 >> 2 =\", resultado_despl_der)\n\n\n\n# ****************************************** ESTRUCTURAS DE CONTROL *******************************************************************\n\n# ====================================== Condicionales ==========================================\nx = 10\nif x > 0:\n    print(\"x es positivo\")\nelif x == 0:\n    print(\"x es igual a cero\")\nelse:\n    print(\"x es negativo\")\n\n# Iterativa con for\nfrutas = [\"manzana\", \"banana\", \"cereza\"]\nfor fruta in frutas:\n    print(fruta)\n\n\n# ======================================== Iterativa con while ==================================\ncontador = 0\nwhile contador < 5:\n    print(\"El contador es:\", contador)\n    contador += 1\n\n\n#========================================== Manejo de excepciones ===========================\n\"\"\"try:\n    resultado = 10 / 0\nexcept ZeroDivisionError:\n    print(\"Error: No se puede dividir por cero\")\nfinally:\n    print(\"El programa ha terminado de ejecutar el bloque try-except\")\n\"\"\"\n\n\n\n #======================================DIFICULTAD EXTRA (opcional) ========================================\n\"\"\" Crea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\"\"\"\nfor num in range(10,56):\n    if num % 2 == 0:\n        if num is not 16:\n            if not num  % 3 == 0:\n                print(num)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/VickAlc.py",
    "content": "#01 OPERADORES Y ESTRUCTURAS DE CONTROL\n\n#_ Operadores de asignación\nprint('\\n***Operadores de asignación***')\nnum1 = 10\nnum2 = 3\nnum3 = 7\n##\nnum1 += 5\nnum2 -= 2\nnum3 *= 4\nnum1 /= 3\nprint(f'número 1 = {num1}')\nprint(f'número 2 = {num2}')\nprint(f'número 3 = {num3}')\n\n\n#_ Operadores aritméticos\nprint('\\n***Operadores aritméticos***')\nsuma = num1 + num2\nprint(f'suma = {suma}')\n\nresta = num1 - num2\nprint(f'resta = {resta}')\n\nmult = num1 * num2\nprint(f'multiplicación = {mult}')\n\ndiv = num1/num2\nprint(f'división = {div}')\n\nmod = num1 % num2\nprint(f'módulo = {mod}')\n\npot = num1 ** num2\nprint(f'potencia = {pot}')\n\ndiv_ent = num1 // num2\nprint(f'división entera = {div_ent}')\n\n\n#_ Operadores de comparación\nprint('\\n***Operadores de comparación***')\nigualdad = num1 == num3\nprint(igualdad)\n\ndesigualdad = num1 != num2\nprint(desigualdad)\n\nmayor_que = num2 > num3\nprint(mayor_que)\n\nmenor_que = num2 < num1+num3\nprint(menor_que)\n\nmayor_igual = num2 >= num3\nprint(mayor_igual)\n\nmenor_igual = num1 <= num2+num3\nprint(menor_igual)\n\n\n#_ Operadores lógicos\nprint('\\n***Operadores lógicos***')\nresultado = num1 > num2 and num1 > num3\nprint(resultado)\n\nresultado = num1 < num2 or num1 < num3\nprint(resultado)\n\nresultado = not (num1 == num2)\nprint(resultado)\n\n\n#_ Operadores de identidad\nprint('\\n***Operadores de identidad***')\nnum4 = num1\nlista1 = [1,2,3]\nlista2 = [1,2,3]\n\nop_is1 = num1 is num4\nprint(op_is1)\n\nop_is2 = lista1 is lista2\nprint(op_is2)\n\nop_is1 = num1 is not num4\nprint(op_is1)\n\nop_is2 = lista1 is not lista2\nprint(op_is2)\n\n\n#_ Operadores de pertenencia\nprint('\\n***Operadores de pertenencia***')\nresultado = num2 in lista1\nprint(resultado)\n\nresultado = num2 not in lista1\nprint(resultado)\n\n\n#_ Operadores de bits\nprint('\\n***Operadores de bits***')\na = 10  # Representación binaria: 1010\nb = 6   # Representación binaria: 0110\n\nresultado_and = a & b\nprint(\"AND:\", resultado_and)  # 2 en binario: 0010\n\nresultado_or = a | b\nprint(\"OR:\", resultado_or)  # 14 en binario: 1110\n\nresultado_xor = a ^ b\nprint(\"XOR:\", resultado_xor)  # 12 en binario: 1100\n\ndesplazamiento_izquierda = a << 2\nprint(\"Desplazamiento a la izquierda:\", desplazamiento_izquierda)  # 40 en binario: 101000\n\ndesplazamiento_derecha = a >> 1\nprint(\"Desplazamiento a la derecha:\", desplazamiento_derecha)  # 5 en binario: 0101\n\ncomplemento_a = ~a\nprint(\"Complemento:\", complemento_a)  # -11 en binario: -1011\n\n\n#_ Estructuras de control\nprint('\\n***Estructuras de control***')\n\n# condicional\nif num1 > num2:\n    print(f'{num1} es mayor que {num2}')\nelse:\n    print(f'{num1} es menor que {num2}')\n\n# while\ncontador = 0\nwhile contador <= (num1-2):\n    print(contador)\n    contador +=1\n\n# for\nfor i in lista1:\n    print(f'{i*10}')\n\nlista3 = [1,2,3,4,5,6,7,8,9,10]\nfor i in lista3:\n    if i ==2:\n        continue\n    if i == 3:\n        pass\n    if i == 5:\n        break\n    else:\n        print(i)\n\n# Excepciones\ntry:\n    num0 = 0\n\n    # División entre cero\n    resultado = num1 / num0\n\nexcept ZeroDivisionError:\n    print(\"Error: No es posible dividir por cero.\")\n\n\n#_ Dificultad extra\nprint('\\n***Dificultad extra***')\nfor i in range(10, 56):\n    if (i % 2) != 0:\n        continue\n    elif i==16:\n        pass\n    elif (i % 3) == 0:\n        continue\n    else:\n        print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/VictorE16.py",
    "content": "#Operadores\n\n#Operadores artimeticos\nprint(\"*****Operadores Aritmeticos*****\")\na = 8\nb=8\nprint(f\"Suma: 8 + 8 = {a + b}\")\nprint(f\"Resta: 8 - 8 = {a - b}\")\nprint(f\"Multiplicacion: 8 * 8 = {a * b}\")\nprint(f\"Division: 8 / 8 = {a / b}\")\nprint(f\"Modulo: 8 % 8 = {a % b}\")\nprint(f\"Potencia: 8 ** 8 = {a ** 2}\")\nprint(f\"Division Entera: 8 // 8 = {a // b}\\n\")\n\n#Operadores de asignacion\nprint(\"*****Operadores de asignacion*****\")\nnum = 11\nprint(f\"Asignacion simple: {num}\")\nnum += 1\nprint(f\"Suma y asigna: {num}\")\nnum -= 11\nprint(f\"Resta y asigna: {num}\")\nnum *= 2\nprint(f\"Multiplica y asigna: {num}\")\nnum /= 2\nprint(f\"Divide y asigna: {num}\")\nnum %= 2\nprint(f\"Modulo y asigna: {num}\")\nnum **= 1\nprint(f\"Exponenciacion y asigna: {num}\")\nnum //= 1\nprint(f\"Division entera y asigna: {num}\\n\")\n\n#Operadores de Comparacion\nprint(\"*****Operadores de comparacion*****\")\nprint(f\"Igualdad: 8 == 8 = {8 == 8}\")\nprint(f\"Distinto de: 8 != 8 = {8 != 8}\")\nprint(f\"Mayor que: 8 > 6 = {8 > 6}\")\nprint(f\"Menor que: 8 < 6 = {8 < 6}\")\nprint(f\"Mayor o igual que: 16 >= 8 = {16 >= 8}\")\nprint(f\"Menor o igual que: 8 <= 4 = {8 <= 4}\\n\")\n\n#Operadores logicos\nprint(\"*****Operadores Logicos*****\")\nprint(f\"AND &&: 2 + 2 = 4 and 3 - 1 = 2 = {2 + 2 == 4 and 3 - 1 == 2}\")\nprint(f\"OR ||: 2 + 2 = 4 or 3 - 1 = 2 = {2 + 2 == 4 or 3 - 1 == 2}\")\nprint(f\"NOT !: not 2 + 2 == 5 = {not 2 + 2 == 5}\\n\")\n\n#Operadores de Identidad\nprint(\"*****Operadores de Identidad*****\")\nother_num = num\nprint(f\"other_num is num = {other_num is num}\")\nprint(f\"other_num is not num = {other_num is not num}\\n\")\n\n#Operadores de Pertenencia\nprint(\"*****Operadores de pertenencia*****\")\nprint(f\"'v' in 'victore16' = {'v' in 'victore16'}\")\nprint(f\"'j' not in 'victore16' = {'j' not in 'victore16'}\\n\")\n\n#Operadores de bit\na = 10 # 1010\nb = 3 # 0011\n\nprint(\"*****Operadores de bit*****\")\nprint(f\"AND: 10 & 3 = {10 & 3}\") #0010\nprint(f\"OR: 10 | 3 = {10 | 3}\") #1011\nprint(f\"XOR: 10 ^ 3 = {10 ^ 3}\") #1001\nprint(f\"NOT: ~10 = {~10}\") \nprint(f\"Desplazamiento a la derecha: 10 >> 2 = {10 >> 2}\") #0010\nprint(f\"Desplazamiento a la izquierda: 10 << 2 = {10 << 2}\\n\") #10100\n\n# -----------Estructuras de control --------------\nprint(\"*****ESTRUCTURAS DE CONTROL*****\\n\")\n#Estructuras condicionales\nprint(\"*****Estructuras condicionales*****\\n\")\ncondition = 11\n\nif condition == 11:\n    print(\"Mi condicion se cumplio\\n\")\nelif condition > 11:\n    print(\"Mi segunda condicion se cumplio\")\nelse:\n    print(\"Ninguna de las condiciones se cumplio\")\n\n#Estructuras de bucle\nprint(\"*****Estructuras de bucle*****\")\nfor i in range(11):\n    print(i)\n\ni = 0\n\nwhile i <= 10:\n    print(i)\n    i += 1\n\n#Control de excepciones\nprint(\"*****Control de excepciones*****\")\ntry:\n    print(10 / 0)\nexcept:\n    print(\"Se ha producido un error\")\nfinally:\n    print(\"Ha finalizado el manejo de excepciones\\n\")\n\n#Extra\nprint(\"*****Ejercicio Extra*****\")\n\nfor number in range(10,56):\n    if number % 2 == 0 and number != 16 and number % 3 != 0:\n        print(number)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/VictorJaimesR.py",
    "content": "\n#Operadores aritméticos\n\nprint(f\"Suma: 10 + 3 = {10 + 3}\")\nprint(f\"Resta: 10 - 3 = {10 - 3}\")\nprint(f\"Multiplicacion: 10 * 3 = {10 * 3}\")\nprint(f\"Division: 10 / 3 = {10 / 3}\")\nprint(f\"Residuo: 10 % 3 = {10 % 3}\")\nprint(f\"Exponente: 10 ** 3 = {10 ** 3}\")\nprint(f\"Division entera: 10 // 3 = {10 // 3}\")\n\n#Operadores de comparacion\n\nprint(f\"Igualdad: 10==5 {10==5}\")\nprint(f\"Diferencia: 10!=5 {10!=5}\")\nprint(f\"mayorque: 10>5 {10>5}\")\nprint(f\"menorque: 10<5 {10<5}\")\nprint(f\"mayoroigualque: 10>=5 {10>=5}\")\nprint(f\"menoroigualque: 10<=5 {10<=5}\")\n\n#operadores logicos\n\nprint(f\"and &&: 10>5 and 5>3 {10>5 and 5>3}\")\nprint(f\"or ||: 10>5 and 5>3 {10<5 or 5>3}\")\nprint(f\"not !: 10+3=14 {not(10+3==14)}\")\n\n#operadores de asignación\nnum=15\nprint(num)\nnum+=2\nprint(num)\nnum-=2\nprint(num)\nnum*=2\nprint(num)\nnum/=2\nprint(num)\nnum%=12\nprint(num)\nnum**=2\nprint(num)\nnum//=2\nprint(num)\n\n#operadores de identidad\nnum2=num\nprint(f\"num is num2 es {num is num2}\")\nprint(f\"num is not num2 es {num is not num2}\")\n\n#operadores de pertenencia\n\nprint(f\"v in victor {'v' in 'victor'}\")\nprint(f\"b in victor {'b' in 'victor'}\")\n\n#operadores de bits\n\n\na=10\nb=3\n\nprint(f\"and &: 10 and 3 es: {10&3}\")#compara los numeros a nivel de bits y si ambos bits son 1 el bit resultante es 1 de lo contrario es 0\nprint(f\"or |: 10 | 3 es: {10|3}\")# con que haya 1 al comparar el bit será 1\nprint(f\"xor ^: 10 ^ 3 es: {10 ^ 3}\")# si los bits son iguales es 1, si son diferentes es 0\nprint(f\" ~a es {~a}\")\nprint(f\"Desplazamiento a la derecha 10>>2 {10>>2}\")\nprint(f\"Desplazamiento a la izquierda 10<<2 {10<<2}\")\n\n#estructuras de control\n#condicionales\n\nnombre=\"Andres\"\nif nombre==\"victor\":\n    print(f\"Mi nombre es:{nombre}\")\nelif nombre==\"Andres\":\n    print(f\"Entonces mi nombre es: {nombre}\")\nelse:\n    print(\"Mi nombre no es Victor\")\n\n#iterativas\n\nfor i in range(11):\n    print(i)\n\ni=0\nwhile i <= 10:\n    print(i)\n    i += 1\n\n#manejo de exepciones\n\ntry:\n    print(10/0)\nexcept:\n    print(\"Se ha producido un error\")\nfinally:\n    print(\"Ha finalizado el manejo de excepciones\")\n\n#EJERCICIO DE DIFICULTAD EXTRA\n\nfor i in range(10,56):\n    if i%2==0 and i%3!=0 and i!=16:\n     print(f\"[{i}]\",end=\"\")"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/VictorRivero1204.py",
    "content": "\"\"\"\nOperadores\n\"\"\"\n\n# Operadores aritmeticos\n\nprint(f\"Suma: 10 + 3 = {10 + 3}\")\n\nprint(f\"Resta: 10 - 3 = {10 - 3}\")\n\nprint(f\"Multiplicacion: 10 * 3 = {10 * 3}\")\n\nprint(f\"Division: 10 / 3 = {10 / 3}\")\n\nprint(f\"Modulo: 10 % 3 = {10 % 3}\")\n\nprint(f\"Exponencial: 10 ** 3 = {10 ** 3}\")\n\n#Operadores de comparacion\n\nprint(f\"Igualdad: 10 == 3 es {10 == 3}\")\n\nprint(f\"Desigualdad: 10 != 3 es {10 != 3}\")\n\nprint(f\"Mayor que: 10 > 3 es {10 > 3}\")\n\nprint(f\"Menor que: 10 < 3 es {10 < 3}\")\n\nprint(f\"Mayor o igual que: 10 >= 3 es {10 >= 10}\")\n\nprint(f\"Menor o igual que: 10 <= 3 es {10 <= 3}\")\n\nprint(f\"Menor o igual que: 10 <= 3 es {10 <= 3}\")\n\n#Operadores logicos\n\nprint(f\"AND &&: 10 + 3 == 13 and 5 - 1 == 4 es {10 + 3 == 13 and 5 - 1 == 4}\")\n\nprint(f\"OR ||: 10 + 3 == 14 or 5 - 1 == 4 es {10 + 3 == 14 or 5 - 1 == 4}\")\n\nprint(f\"NOT !: not 10 + 3 == 14 es {not 10 + 3 == 14}\")\n\n#Operadores de asignacion\n\nmy_number = 11 #asignacion\nprint(my_number)\n\nmy_number += 1 # suma y asignacion\nprint(my_number)\n\nmy_number -= 1 # resta y asignacion\nprint(my_number)\n\nmy_number *= 1 # multiplicacion y asignacion\nprint(my_number)\n\nmy_number /= 1 # division y asignacion\nprint(my_number)\n\nmy_number %= 1 # modulo y asignacion\nprint(my_number)\n\nmy_number **= 1 # exponente y asignacion\nprint(my_number)\n\nmy_number //= 1 # division entera y asignacion\nprint(my_number)\n\n#Operadores de identidad\n\nmy_new_number = my_number\n\nprint(f\"my_number is my_new_number es {my_number is my_new_number}\")\n\nprint(f\"my_number is not my_new_number es {my_number is not my_new_number}\")\n\n#Operadores de pertenencia\n\nprint(f\"'u' in 'mouse' ={'u' in 'mouse'}\")\n\nprint(f\"'b not in 'mouse' ={'b' not in 'mouse'}\")\n\n#Operadores de bit\n\na = 10 # 1010\nb = 3 # 0011\n\nprint(f\"AND: 10 & 3 = {10 & 3}\") # 0010\n\nprint(f\"OR: 10 | 3 = {10 | 3}\") # 1011\n\nprint(f\"XOR: 10 ^ 3 = {10 ^ 3}\") # 1001\n\nprint(f\"NOT: ~10 = {~10}\")\n\nprint(f\"DESPLAZAMIENTO  A LA DERECHA: 10 >> 2 = {10 >> 2}\") # 0010\n\nprint(f\"DESPLAZAMIENTO  A LA IZQUIERDA: 10 << 2 = {10 << 2}\") # 101000\n\n\"\"\"\nEstructuras de control\n\"\"\"\n\n# Condicionales\n\nmy_string = \"VictorRivero\"\n\nif my_string == \"VictorRivero\":\n    print(\"my_string es: 'VictorRivero'\")\nelif my_string == \"Juan\":\n    print(\"my_string es Juan\")\nelse:\n    print(\"my_string no es 'VictorRivero'\")\n\n#Iternativas \n\nfor i in range(11):\n    print(i)\n\ni = 0 \n\nwhile i <= 10:\n    print(i)\n    i += 1\n\n#Manejo de excepciones\n\ntry: \n    print(10 / 0)\nexcept:\n    print(\"Se ha producido un error\")\nfinally:\n    print(\"Ha finalizado el manejo de excepciones\")\n\n\"\"\"\nExtra\n\"\"\"\n\nfor number in range(10, 56):\n    if number % 2 == 0 and number != 16 and number %3 != 0:\n        print(number)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/VictorZm0h.py",
    "content": "\"\"\"EJERCICIO:\r\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\r\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\r\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\"\"\"\r\n\r\n#Operadores:\r\n\r\n# Aritméticos\r\nsuma = 5 + 3\r\nresta = 10 - 4\r\nmultiplicacion = 2 * 6\r\ndivision = 8 / 2\r\nmodulo = 10 % 3\r\nexponente = 2 ** 3\r\n#Ejemplos:\r\nprimernumero=float(input(\"Introduce el primer numero: \"))\r\nsegundonumero=float(input(\"Introduce el segundo numero: \"))\r\ntipoDeOperacion=input(\"Introduce el tipo de operacion: \")\r\nif tipoDeOperacion==\"suma\":\r\n    print(\"El resultado de la suma es: \", primernumero+segundonumero)\r\nelif tipoDeOperacion==\"resta\":\r\n    print(\"El resultado de la resta es: \", primernumero-segundonumero)\r\nelif tipoDeOperacion==\"multiplicacion\":\r\n    print(\"El resultado de la multiplicacion es: \", primernumero*segundonumero)\r\nelif tipoDeOperacion==\"division\":\r\n    print(\"El resultado de la division es: \", primernumero//segundonumero)\r\nelse:\r\n    print(\"Operacion no valida\")\r\n# Lógicos\r\nand_logico = True and False # Deben cumplirse ambas condiciones\r\nor_logico = True or False # Se cumple si al menos una condición es verdadera\r\nxor_logico = True ^ False  # Se cumple si solo una condición es verdadera\r\nnot_logico = not True # Negación de una condición\r\n#Ejemplos: \r\n#Si la edad es mayor o igual a 18 Y menor o igual a 100, mostrar \"Puedes votar\". En caso contrario, mostrar \"No puedes votar\".\r\nedad=(int(input(\"Introduce tu edad: \")))\r\nif edad>=18 and edad<=100:\r\n    print(\"Puedes votar\")\r\nelse:\r\n    print(\"No puedes votar\")\r\nedad=(int(input(\"Introduce tu edad: \")))\r\npais=input(\"Introduce tu país: \")\r\nif edad>=18 and pais.lower()==\"venezuela\":\r\n    print(\"Puedes ingresar al ejercito\")\r\nelse:\r\n    print(\"No puedes ingresar al ejercito\")\r\n#Si el cliente es estudiante O tiene más de 65 años, mostrar \"Tienes descuento\". En caso contrario, mostrar \"No tienes descuento\".\r\nestudiante=(int(input(\"¿Eres estudiante? (1-Si/0-No): \")))\r\nedad=int(input(\"Introduce tu edad: \"))\r\nif estudiante==1 or edad>65:\r\n    print(\"Tienes descuento\")\r\nelse:\r\n    print(\"No tienes descuento\")\r\nedad=int(input(\"Introduce tu edad: \"))\r\npais=input(\"Introduce tu país: \")\r\nif (edad>=18 and pais.lower()==\"venezuela\") or (edad>=20 and pais.lower()==\"colombia\"):\r\n    print(\"Puedes ingresar al ejercito\")\r\nelse:\r\n    print(\"No puedes ingresar al ejercito\")\r\n#Si NO tiene membresía, mostrar \"Debes pagar la tarifa completa\".Si tiene membresía, mostrar \"Tienes acceso gratuito\".\r\nmembresia=(int(input(\"¿Tienes membresía? (1-Si/0-No): \")))\r\nif not membresia==1:\r\n    print(\"Debes pagar la tarifa completa\")\r\nelse:\r\n    print(\"Tienes acceso gratuito\")\r\n\r\n# Comparación\r\nigual = (5 == 5)\r\ndiferente = (5 != 3)\r\nmayor_que = (5 > 3)\r\nmenor_que = (3 < 5)\r\nmayor_igual = (5 >= 5)\r\nmenor_igual = (3 <= 5)\r\n# Asignación\r\nasignacion = 10\r\nasignacion += 5  # equivalente a asignacion = asignacion + 5\r\nasignacion -= 3  # equivalente a asignacion = asignacion - 3    \r\nasignacion *= 2  # equivalente a asignacion = asignacion * 2\r\nasignacion /= 4  # equivalente a asignacion = asignacion / 4\r\nasignacion %= 3  # equivalente a asignacion = asignacion % 3\r\nasignacion **= 2  # equivalente a asignacion = asignacion ** 2\r\n# Identidad\r\nis_identity = (asignacion is not None)  # Verifica si asignacion no es None\r\n# Pertenencia\r\nlista = [1, 2, 3, 4, 5]\r\npertenencia = 3 in lista  # Verifica si 3 está en la lista\r\n# Bits\r\nbit_and = 5 & 3  # AND bit a bit\r\nbit_or = 5 | 3   # OR bit a bit\r\nbit_xor = 5 ^ 3  # XOR bit a bit\r\nbit_not = ~5  # NOT bit a bit\r\n# Desplazamiento de bits\r\ndesplazamiento_izquierda = 5 << 1  # Desplaza los bits de 5 a la izquierda (multiplica por 2)\r\ndesplazamiento_derecha = 5 >> 1  # Desplaza los bits de 5 a la derecha (divide por 2)\r\n\r\n\"\"\"\r\nDIFICULTAD EXTRA (opcional):\r\n * Crea un programa que imprima por consola todos los números comprendidos\r\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\r\n\"\"\"\r\n\r\nfor i in range(10, 56):\r\n    if i%2==0 and i!=16 and i%3!=0:\r\n        print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/WinstonS6079.py",
    "content": "'''Operadores y estructuras de control'''\n\n# Operadores aritméticos\nprint(f\"Suma: 10 + 45 = {10 + 45}\")\nprint(f\"Resta: 10 - 45 = {10 - 45}\")\nprint(f\"Multiplicación: 10 * 45 = {10 * 45}\")\nprint(f\"División: 10 / 45 = {10 / 45}\")\nprint(f\"División entera: 10 // 45 = {10 // 45}\")\nprint(f\"Módulo: 10 % 45 = {10 % 45}\")\nprint(f\"Exponente: 10 ** 45 = {10 ** 45}\")\n\n#Operadores de comparación\nprint(f\"Igualdad: 10 == 45: {10 == 45}\")\nprint(f\"Desigualdad: 10 != 45: {10 != 45}\")\nprint(f\"Mayor que: 10 > 45: {10 > 45}\")\nprint(f\"Menor que: 10 < 45: {10 < 45}\")\nprint(f\"Mayor o igual que: 10 >= 45: {10 >= 45}\")\nprint(f\"Menor o igual que: 10 <= 45: {10 <= 45}\")\n\n#Operadores lógicos\nprint(f\"AND: True and False: {True and False}\") \nprint(f\"AND: True and False: {True and True}\")\nprint(f\"OR: True or False: {True or False}\")\nprint(f\"NOT: not True: {not True}\")\n\n#Operadores de asignación\nx = 10\nprint(f\"Asignación: x = {x}\")\nx += 5\nprint(f\"Asignación con suma: x += 5: {x}\")\nx -= 3\nprint(f\"Asignación con resta: x -= 3: {x}\")\nx *= 2\nprint(f\"Asignación con multiplicación: x *= 2: {x}\")\nx /= 4\nprint(f\"Asignación con división: x /= 4: {x}\")\nx //= 2\nprint(f\"Asignación con división entera: x //= 2: {x}\")\nx %= 3\nprint(f\"Asignación con módulo: x %= 3: {x}\")\nx **= 2\nprint(f\"Asignación con exponente: x **= 2: {x}\")\n\n#Operadores de identidad\nmy_number = 10\nmy_new_number = my_number\nprint(f\"Identidad: my_number is my_new_number: {my_number is my_new_number}\")\nprint(f\"Identidad: my_number is not my_new_number: {my_number is not my_new_number}\")\n\n#Operadores de pertenencia\nprint(f\"Pertenencia: 'a' in 'Winston': {'a' in 'Winston'}\")\nprint(f\"Pertenencia: 'a' not in 'Winston': {'a' not in 'Winston'}\")\n\n#Operadores bit a bit\na = 20 # 20 en binario es 10100\nb = 10 # 10 en binario es 01010\n\nprint(f\"AND bit a bit: {a} & {b} = {a & b}\")  \nprint(f\"OR bit a bit: {a} | {b} = {a | b}\")    \nprint(f\"XOR bit a bit: {a} ^ {b} = {a ^ b}\")    \nprint(f\"Desplazamiento a la izquierda: {a} << 2 = {a << 2}\")  \nprint(f\"Desplazamiento a la derecha: {a} >> 2 = {   a >> 2}\")  \n\n'''\nEstructuras de control\n'''\n\n# Condicionales\nX = 10    \nif 10 > 5:\n    print(\"10 es mayor que 5\")\nelif 10 == 5:\n    print(\"10 es igual a 5\")\nelse: \n    print(\"10 no es mayor que 5\")\n\n#Iterativas\nfor i in range(20):\n    print(i)\n\ni = 0\nwhile i <= 20:\n    print(i)\n    i += 1\n\n#Manejo de excepciones\ntry:\n    print(10 / 0)\nexcept ZeroDivisionError:\n    print(\"Error: División por cero\")\nfinally:\n    print(\"Bloque finally ejecutado, independientemente de si hubo error o no\")\n\n\n'''\n\nExtra\n\n'''\n\nfor i in range(10, 56):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print(i)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Yani-Git.py",
    "content": "\"\"\"\nOperadores\n\n\"\"\"\n\n#operadores aritméticos \n\nprint (f\"Suma: 10 + 3 = {10 + 3}\")  #la \"f\" sirve para interpolar la suma en la cadena de texto\n\nprint (f\"Resta: 10 - 3 = {10 - 3}\") \n\nprint (f\"Multiplicación: 10 * 3 = {10 * 3}\")\n\nprint (f\"División: 10 / 3 = {10 / 3}\") \n\nprint (f\"Módulo: 10 % 3 = {10 % 3}\")   #es el resto de la división, es lo que nos queda despues de dividir\n\nprint (f\"Exponente: 10 ** 3 = {10 ** 3}\") \n\nprint (f\"División entera: 10 // 3 = {10 // 3}\") # el resultado no tiene que dar un  numero entero a diferencia de la división que da como resultado decimales 3.33\n\n\n\n#operadores de comparación: se pueden usar con números y con variables, para comparar numeros y cadenas de texto \n\nprint (f\"Igualdad: 10 == 3 {10 == 3}\")\n\nprint (f\"Desigualdad: 10 != 3 {10 != 3}\")\n\nprint (f\"Mayor que: 10 > 3 {10 > 3}\")\n\nprint (f\"Menor que: 10 < 3 {10 < 3}\")\n\nprint (f\"Mayor o igual que: 2 >= 3 {2 >= 3}\")\n\nprint (f\"Menor o igual que: 10 <= 3 {10 <= 3}\")\n\n\n\n#operadores lógicos \n\nprint (f\"AND &&: 10 + 3 == 13 and 5 - 1 == 4 es { 10 + 3 == 13 and 5 - 1 == 4}\") #intenta que dos condiciones sean iguales\n\nprint (f\"OR ||: 10 + 3 == 13 or 5 - 1 == 4 es { 10 + 3 == 13 or 5 - 1 == 4}\")  # el OR pide que sea verdadera al menos una de las condiciones lógicas\n\nprint (f\"NOT !: not 10 + 3 == 14 {not 10 + 3 == 14}\")  #sirve para decir que algo no es, afirma que algo es incorrecto y devuelve  true, por el contrario, si afirmara que algo es incorrecto siendo correcto devolverá como resultado folse\n\n\n\n#operadores de asignación: son operadores que actuan en conjunto con el valor de las variables\n\nmy_number = 11  #esto es una asignación \nprint (my_number) #suma y asignación\nmy_number += 1  #le suma 1 al 11 que tengo como asignación\nprint (my_number)\nmy_number -= 1 #resta y asignación\nprint (my_number)\nmy_number *= 2 #multiplicación  y asignación\nprint (my_number)\nmy_number /= 2 #división  y asignación\nmy_number %= 2 #módulo  y asignación\nprint (my_number)\nmy_number **= 1 #exponente  y asignación\nprint (my_number)\nmy_number //= 1 #división entera  y asignación\nprint (my_number)\n\n\n#operadores de identidad: IS sirve para comparar el valor de la pisición de memoria\nmy_new_number = my_number\nprint (f\"my_number is my_new_number es {my_number is my_new_number}\")\n\n#operador de desigualdad: NOT\nprint (f\"my_number is not my_new_number es {my_number is not my_new_number}\")\n\n\n\n#operadores de pertenencia\n\nprint (f\"'i' in  'Yani' = {'i' in  'Yani'}\")\nprint (f\"'e'  not in 'Yani' = {'e' not in   'Yani'}\")\n\n\n\n#operadores de bit\na = 10  #1010 - en numeros binarios 0=0, 1=1, 2=10, 3=11, 4=100\nb = 3 #0011\n\nprint (f\"AND: 10 & 3 ={10 & 3 }\") # 0010\n\"\"\"el operador AND compara bit a bit si el numero es 1 devuelve 1 de lo contrario devuelve 0\n    en el ejemplo dado: 1=0 resultado 0, 0= 0 resulado 0, 1=1 resultado 1, \n    0=0 resultado 0, en  el ejemplo con AND 0010= 2, se sigue el principio de contar en decimal, \n    pero con la diferencia de que solo se utilizan los dígitos 0 y 1 \n\"\"\"\nprint (f\"OR: 10 | 3 ={10 | 3 }\")  #1011\n\"\"\"compara bit a bit y si al menos uno de los operadores es 1 el resultado\n    será 1   ejemplo 1=0 resultado 1, 0=0 reslutado 0, 1=1 resultado 1, 0=1 resultado 1 total= 1011\"\"\"\nprint (f\"XOR: 10 ^ 3 ={10 ^ 3 }\") #1001\n\"\"\"el xor commpara los bit si el resultado es diferente entonces sera 1   en el ejercicio el resulado es 1001 \n\"\"\"\nprint (f\"NOT: ~10 ={~10}\") # invierte el resultado sobre la respresentación \n\nprint(f\"Desplazamiento a la derecha: 10 >> 2 = {10 >> 2}\") #1010 con el desplazamiento 0010 = 2\n\nprint(f\"Desplazamiento a la izquierda: 10 << 2 = {10 << 2}\") # 1010 con el desplazamiento 101000 = 40\n\n\n\"\"\"\nEstructura de control: tipos de estructuras ==>  \n\n\"\"\"\n\n# ==> Condicionales \n\nmy_string = \"Yani-Git\"\n\nif my_string == \"Yani-Git.py\":\n    print (\"my_String es 'Yan'\")\nelif my_string == \"Yani\":\n    print (\"my_String es 'Yani'\")\nelse: \n    print (\"my_String no es 'Yani-Git' ni 'Yani'\")           \n\n\n#Iterativas\n\nfor i in range (11):  # cuando imprime en la pantalla lo hace hasta el 10 no toma en cuenta el 11\n     print(i)\n\ni = 0\n\n\"\"\"while i <= 10:    #se plantea una condición para que se ejecuta  mientras sea verdadera \n    print (i)     #bucle infinito \"\"\"\n\n\nwhile i <= 10:\n    print (i)\n    i += 1\n\n# manejo de excepciones \n\ntry:\n    print (10 / 0)\nexcept:\n    print (\"se ha producido un error\")\nfinally:                                       #se va a ejecutar siempre que se maneje el error, se prodzca errer o no se produzca \n    print (\"Ha finalizado el manejo de excepciones\")\n \n\n\n\n\n# Dificultad extra\n\nfor number  in range (10, 56):\n    if number % 2 == 0 and number  != 16 and number %3 != 0:\n        print (number)\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/YgriegaSB.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n \"\"\"\n\n# Suma\na = 5\nb = 3\nsuma = a + b\nprint(\"Suma:\", suma)  # Resultado: 8\n\n# Resta\nresta = a - b\nprint(\"Resta:\", resta)  # Resultado: 2\n\n# Multiplicación\nmultiplicacion = a * b\nprint(\"Multiplicación:\", multiplicacion)  # Resultado: 15\n\n# División\ndivision = a / b\nprint(\"División:\", division)  # Resultado: 1.6666666666666667\n\n# División entera\ndivision_entera = a // b\nprint(\"División entera:\", division_entera)  # Resultado: 1\n\n# Módulo (resto de la división)\nmodulo = a % b\nprint(\"Módulo:\", modulo)  # Resultado: 2\n\n# Exponenciación\nexponenciacion = a ** b\nprint(\"Exponenciación:\", exponenciacion)  # Resultado: 125\n\n# AND lógico\nx = True\ny = False\nand_logico = x and y\nprint(\"AND lógico:\", and_logico)  # Resultado: False\n\n# OR lógico\nor_logico = x or y\nprint(\"OR lógico:\", or_logico)  # Resultado: True\n\n# NOT lógico\nnot_logico = not x\nprint(\"NOT lógico:\", not_logico)  # Resultado: False\n\n# Igualdad\na = 5\nb = 3\nigualdad = a == b\nprint(\"Igualdad:\", igualdad)  # Resultado: False\n\n# Desigualdad\ndesigualdad = a != b\nprint(\"Desigualdad:\", desigualdad)  # Resultado: True\n\n# Mayor que\nmayor_que = a > b\nprint(\"Mayor que:\", mayor_que)  # Resultado: True\n\n# Menor que\nmenor_que = a < b\nprint(\"Menor que:\", menor_que)  # Resultado: False\n\n# Mayor o igual que\nmayor_igual_que = a >= b\nprint(\"Mayor o igual que:\", mayor_igual_que)  # Resultado: True\n\n# Menor o igual que\nmenor_igual_que = a <= b\nprint(\"Menor o igual que:\", menor_igual_que)  # Resultado: False\n\nx = 5\n# Asignación\nx += 2  # Equivalente a: x = x + 2\nprint(\"Asignación:\", x)  # Resultado: 7\n\nx = [1, 2, 3]\ny = [1, 2, 3]\nz = x\n\n# Identidad (comparando referencias de objetos)\nidentidad1 = x is y\nprint(\"Identidad 1:\", identidad1)  # Resultado: False\n\nidentidad2 = x is z\nprint(\"Identidad 2:\", identidad2)  # Resultado: True\n\n# No Identidad\nno_identidad = x is not y\nprint(\"No Identidad:\", no_identidad)  # Resultado: True\n\n# Pertenencia (comprobando si un valor está presente en una secuencia)\nlista = [1, 2, 3, 4, 5]\npertenencia = 3 in lista\nprint(\"Pertenencia:\", pertenencia)  # Resultado: True\n\n# No Pertenencia\nno_pertenencia = 6 not in lista\nprint(\"No Pertenencia:\", no_pertenencia)  # Resultado: True\n\na = 10  # Representación binaria: 1010\nb = 4   # Representación binaria: 0100\n\n# AND a nivel de bits\nand_bits = a & b\nprint(\"AND a nivel de bits:\", and_bits)  # Resultado: 0 (binario: 0000)\n\n# OR a nivel de bits\nor_bits = a | b\nprint(\"OR a nivel de bits:\", or_bits)    # Resultado: 14 (binario: 1110)\n\n# XOR a nivel de bits\nxor_bits = a ^ b\nprint(\"XOR a nivel de bits:\", xor_bits)  # Resultado: 14 (binario: 1110)\n\n# Desplazamiento a la izquierda\ndespl_izquierda = a << 2\nprint(\"Desplazamiento a la izquierda:\", despl_izquierda)  # Resultado: 40 (binario: 101000)\n\n# Desplazamiento a la derecha\ndespl_derecha = a >> 1\nprint(\"Desplazamiento a la derecha:\", despl_derecha)  # Resultado: 5 (binario: 101)\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Yisusocanto.py",
    "content": "#ejemplos de operadores de python\n\n#aritmeticos\nsuma = 5 + 5\nresta = 5 - 3\nmulltiplicacion = 4 * 4\ndivision = 6 / 5\ndivision_int = 8 // 2\nmodulo = 7 % 2\nexponente = 4 ** 4\n\nprint(suma)\nprint(resta)\nprint(mulltiplicacion)\nprint(division)\nprint(division_int)\nprint(modulo)\nprint(exponente)\n\n#relacionales\nprint(5 >2 ) #mayor a\nprint(5 < 8) #menor a\nprint(5 == 5) #igual a\nprint(5 >= 3) #igual o mayor a \nprint(5 <= 9) #igual o menor a\nprint(5 != 5) #no igual a \n\n#logicos\nnum1 = 5\nnum2 = 5\nnum3 = 5\nnum4 = 8\nnum = 1\n\nif num1 and num2 == num3:\n\tprint(\"True\")\n\nif num1 or num4 == num3:\n\tprint(\"True\")\n\nif not num1 == num4:\n\tprint(\"True\")\n\n#de asignacion\nvar1 = 5 #igual\n\nvar1 += 1 #se le suma al valor actual\nprint(var1)\n\nvar1 -= 2 #se le resta al valor actual\nprint(var1)\n\nvar1 *= 2 #se multiplica al valor actual\nprint(var1)\n\nvar1 /= 3  #se divide al valor actual\nprint(var1)\n\nvar1 **= 3 #se le eleva al valor actual\nprint(var1)\n\nvar1 //= 2 #se divide al valor actual y retorna un entero\nprint(var1)\n\nvar1 %= 2 #se modula al valor actual\nprint(var1)\n\n#de identidad\nnumber = 100\nmy_new_number = number\n\nprint(f\"number es my_new_number: {number is my_new_number}\")\nprint(f\"number no es my_new_number: {number is not my_new_number}\")\n\n#operadores de pertenencia\nprint(f\"'a' esta en 'arbol': {'a' in 'arbol'}\")\nprint(f\"'a' no esta en 'arbol': {'a' not in 'arbol'}\")\n\n## Operadores de bit\na = 10  # 1010\nb = 3  # 0011\nprint(f\"AND: 10 & 3 = {10 & 3}\")  # 0010\nprint(f\"OR: 10 | 3 = {10 | 3}\")  # 1011\nprint(f\"XOR: 10 ^ 3 = {10 ^ 3}\")  # 1001\nprint(f\"NOT: ~10 = {~10}\")\nprint(f\"Desplazamiento a la derecha: 10 >> 2 = {10 >> 2}\")  # 0010\nprint(f\"Desplazamiento a la izquierda: 10 << 2 = {10 << 2}\")  # 101000\n\n#estructuras de control\n\n#iterables\nfor letras in \"iteracion\":\n\tprint(letras)\n\nvar_iter = 7\n\nwhile var_iter >= 4:\n\tprint(var_iter)\n\tvar_iter -= 2\n\n#condicionales\nvar_if = 6\n\nif var_if < 0:\n\tprint(\"la variable es negativa\")\nelif var_if < 10:\n\tprint(\"la variable es positiva\")\nelse:\n\tprint(\"la variable es igual o mayor a diez\")\n\n#excepcones\ntry:\n\t6 / 0\nexcept ZeroDivisionError as e:\n\tprint(\"Division por cero\")\nelse:\n\tprint(\"error desconocido\")\nfinally:\n\tprint(\"FIN\")\n\n#ejercicio extra\n\nfor numero in range(10, 56):\n\tif numero % 2 == 0 and numero != 16 and numero % 3 != 0:\n\t\tprint(numero)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/YorjanVarela.py",
    "content": "#tipos de operadores en python\n#operadores aritmeticos\nsuma = 2+2\nresta = 2-2\nmultiplicacion = 2*2\ndivision = 2/2\nmodulo = 2%2 #el residuo o resto  de la division\ndivision_entera = 2//2 #devuelve la parte entera de la division\npotencia = 2**2\n\nprint(suma)\nprint(resta)\nprint(multiplicacion)\nprint(division)\nprint(modulo)\nprint(division_entera)\nprint(potencia) \n\n#operadores de comparacion\n\nigual_a = 2 == 2\ndistinto_de = 2 != 2\nmayor_que = 2 > 2\nmenor_que = 2 < 2\nmayor_o_igual_que = 2 >= 2\nmenor_o_igual_que = 2 <= 2\n\nprint(igual_a) \nprint(distinto_de) \nprint(mayor_que) \nprint(menor_que) \nprint(mayor_o_igual_que) \nprint(menor_o_igual_que)\n\n#operadores logicos\nAnd = True and True\nOr = True or False\nNot = not True\n\nprint(And)\nprint(Or)\nprint(Not)\n\n#operadores de asignacion\nasignacion = 2 \nasignacion += 2\nasignacion -= 2\nasignacion *= 2\nasignacion /= 2\nasignacion //= 2\nasignacion %= 2\nasignacion **= 2\n\nprint(asignacion)\n\n#operadores bit a bit\nbit_a_bit_and = 2 & 2\nbit_a_bit_or = 2 | 2\nbit_a_bit_xor = 2 ^ 2\ncomplemento = ~2\ndesplazar = 2 << 2\ndesplazar_a_derecha = 2 >> 2\n\nprint(bit_a_bit_and)\nprint(bit_a_bit_or)\nprint(bit_a_bit_xor)\nprint(complemento)\nprint(desplazar)\nprint(desplazar_a_derecha)\n\n#operadores de identidad\nidentidad = 2 is 2\nno_identidad = 2 is not 2\n\nprint(identidad)\nprint(no_identidad)\n\n#operadores de pertenencia\npertenece = 2 in [1, 2, 3]\nno_pertenece = 2 not in [1, 4, 3]\n\nprint(pertenece)\nprint(no_pertenece)\n\n#operadores de ternario \nedad = 18\nmensaje = \"Eres mayor de edad\" if edad >= 18 else \"Eres menor de edad\"\nprint(mensaje)  # Imprimirá: Eres mayor de edad\n\n#Estructuras de control\n#condicionales\nedad = 18\nif edad > 18:\n    print(\"Eres mayor de edad\")\nelif edad == 18:\n    print(\"Acabas de cumplir la mayoría de edad\")\nelse:\n    print(\"Eres menor de edad\")\n\n#bucles\nfor i in range(5):\n    print(i)\n\ni = 0\nwhile i < 5:\n    print(i)\n    i += 1\n\n#otras estructuras de control\n\nnumeros = [1, 2, 3, 4, 5]\nfor numero in numeros:\n    if numero == 3:\n        break\n    print(numero)\n\nfor i in range(10):\n    if i % 2 == 0:\n        continue\n    print(i)\n\ndef mi_funcion():\n    # Aquí iría el código de la función, pero por ahora solo vamos a poner pass\n    pass\n\nif 1 == 1:\n    pass  # Hacer algo\nelse:\n    pass  # No hacer nada en este caso\n\nprint(mi_funcion)\n\n#programa extra \nfor i in range(10, 56):\n    if i == 16:\n        continue\n    if i % 3 == 0:\n        continue\n    print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Younes0-0.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\"\"\"\n\n# Operaciones Aritméticos\nprint(\"Operaciones Aritmeticas\")\nprint(\"Operacion de suma\")\nprint(\"10 + 3 = \",10 + 3)\nprint(\"Operacion de resta\")\nprint(\"10 - 3 = \",10 - 3)\nprint(\"Operacion de multiplicaión\")\nprint(\"10 * 3 = \",10 * 3)\nprint(\"Operacion de división\")\nprint(\"10 / 3 = \",10 / 3)\nprint(\"Operacion de residuo o resto\")\nprint(\"10 % 3 = \",10 % 3)\nprint(\"Operacion de potencia\")\nprint(\"10 ** 3 = \",10 ** 3)\nprint(\"Operacion de división entera\")\nprint(\"10 // 3 = \",10 // 3)\nprint(\"-------------------------------------------\")\n\n# Operadores relacionales\nprint(\"Operadores Relacionales\")\nprint(\"Mayor que\")\nprint(\"10 > 3 = \",10 > 3)\nprint(\"Menor que\")\nprint(\"10 < 3 = \",10 < 3)\nprint(\"Igual\")\nprint(\"10 == 3 = \",10 == 3)\nprint(\"Mayor o igual\")\nprint(\"10 >= 3 = \",10 >= 3)\nprint(\"Menor o igual\")\nprint(\"10 <= 3 = \",10 <= 3)\nprint(\"Diferente\")\nprint(\"10 != 3 = \",10 != 3)\nprint(\"-------------------------------------------\")\n\n# Operadores Bit a Bit\nprint(\"Operadores Bit a Bit\")\nprint(\"Operacion de AND\")\nprint(\"0b1101 & 0b1011 = \",bin(0b1101 & 0b1011))\nprint(\"Operacion de OR\")\nprint(\"0b1101 | 0b1011 = \",bin(0b1101 | 0b1011))\nprint(\"Operacion de XOR\")\nprint(\"0b1101 ^ 0b1011 = \",bin(0b1101 ^ 0b1011))\nprint(\"Operacion de NOT\")\nprint(\"~0b1101 = \",bin(~0b1101))\nprint(\"Operacion de LEFT SHIFT\")\nprint(\"10 << 3 = \",10 << 3)\nprint(\"Operacion de RIGHT SHIFT\")\nprint(\"10 >> 3 = \",10 >> 3)\nprint(\"-------------------------------------------\")    \n\n# Operaciones de asignación\nprint(\"Operaciones de asignación\")\nprint(\"Operacion de asignación\")\ndiez = 10\nprint(\"10 = \",diez)\nprint(\"Operacion de suma\")\ndiez = 10\ndiez += 3\nprint(\"10 += 3 = \",diez)\nprint(\"Operacion de resta\")\ndiez = 10\ndiez -= 3\nprint(\"10 -= 3 = \",diez)\nprint(\"Operacion de multiplicaión\")\ndiez = 10\ndiez *= 3\nprint(\"10 *= 3 = \",diez)\nprint(\"Operacion de división\")\ndiez = 10\ndiez /= 3\nprint(\"10 /= 3 = \",diez)\nprint(\"Operacion de residuo o resto\")\ndiez = 10\ndiez %= 3\nprint(\"10 %= 3 = \",diez)\nprint(\"Operacion de potencia\")\ndiez = 10\ndiez **= 3\nprint(\"10 **= 3 = \",diez)\nprint(\"Operacion de división entera\")\ndiez = 10\ndiez //= 3\nprint(\"10 //= 3 = \",diez)\nprint(\"Operacion AND de bits\")\ndiez = 0b1101\ndiez &= 0b1011\nprint(\"0b1101 &= 0b1011 = \",bin(diez))\nprint(\"Operacion OR de bits\")\ndiez = 0b1101\ndiez |= 0b1011\nprint(\"0b1101 |= 0b1011 = \",bin(diez))\nprint(\"Operacion XOR de bits\")\ndiez = 0b1101\ndiez ^= 0b1011\nprint(\"0b1101 ^= 0b1011 = \",bin(diez))\nprint(\"Operacion LEFT SHIFT de bits\")\ndiez = 0b1101\ndiez <<= 0b1011\nprint(\"0b1101 <<= 0b1011 = \",bin(diez))\nprint(\"Operacion RIGHT SHIFT de bits\")\ndiez = 0b1011\ndiez >>= 0b1011\nprint(\"0b1011 >>= 0b1011 = \",bin(diez))\nprint(\"-------------------------------------------\")\n\n# Operaciones lógicas\nprint(\"Operaciones lógicas\")\nverdad = True\nfalso = False\nprint(\"Operacion AND\")\nprint(\"verdad y verdad = \",verdad and verdad)\nprint(\"verdad y falso = \",verdad and falso)\nprint(\"falso y verdad = \",falso and verdad)\nprint(\"falso y falso = \",falso and falso)\nprint(\"Operacion OR\")\nprint(\"verdad o verdad = \",verdad or verdad)\nprint(\"verdad o falso = \",verdad or falso)\nprint(\"falso o verdad = \",falso or verdad)\nprint(\"falso o falso = \",falso or falso)\nprint(\"Operacion NOT\")\nprint(\"not verdad = \",not verdad)\nprint(\"not falso = \",not falso)\nprint(\"-------------------------------------------\")\n\n# Operaciones de identidad\nprint(\"Operaciones de identidad\")\nprint(\"10 is 10 = \",10 is 10)\nprint(\"10 is not 10 = \",10 is not 10)\nprint(\"-------------------------------------------\")\n\n# Operaciones de pertenencia\nprint(\"Operaciones de pertenencia\")\nprint(\"10 in [1,2,3,4,5] = \",10 in [1,2,3,4,5])\nprint(\"10 not in [1,2,3,4,5] = \",10 not in [1,2,3,4,5])\nprint(\"-------------------------------------------\")\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/YulioBNO.py",
    "content": "\"Aritméticos\"\n\nprint(\"Aritméticos\") #Operadores que realizan operaciones matemáticas básicas\nprint(\"Suma: \", 7 + 8) #Suma de dos números\nprint(\"Resta: \", 1 - 4) #Resta de dos números\nprint(\"Multiplicación: \", 12 * 4) #Multiplicación de dos números\nprint(\"División: \", 12 / 4) #División de dos números\nprint(\"Módulo: \", 10 % 3) #Resto de la división\nprint(\"Exponente \", 7** 3) #Potencia (un numero elevado a otro)\nprint(\"División entera: \", 70 // 20) #División sin decimales\n\nprint(\"--------------------------------------------------\")\n\n\"Asignación\"\n\nprint(\"Asignación\") #Operadores que asignan valores a las variables y realizan operaciones con ellas\n\nx = 4 #Asignación de un valor a cada variable\ny = 10\nz = 5\na = 3\nb = 8\nc = 2\n\nprint(\"Valor de x: \", x ) #Impresión del valor de la variable\nprint(\"Valor de y: \", y )\nprint(\"Valor de z: \", z )\nprint(\"Valor de a: \", a )\nprint(\"Valor de b: \", b )\nprint(\"Valor de c: \", c )\n\nx += 3 #Incremento del valor de la variable en 3 (Equivalente a x = x + 3)\nprint(\"Valor de x después de +=3: \", x) #Impresión del nuevo valor de la variable\n\ny -= 2 #Decremento del valor de la variable en 2 (Equivalente a y = y - 2)\nprint(\"Valor de y después de -=2: \", y) #Impresión del nuevo valor de la variable\n\nz *= 4 #Multiplicación del valor de la variable por 4 (Equivalente a z = z * 4)\nprint(\"Valor de z después de *=4: \", z) #Impresión del nuevo valor de la variable\n\na /= 3 #División del valor de la variable entre 3 (Equivalente a a = a / 3)\nprint(\"Valor de a después de /=3: \", a) #Impresión del nuevo valor de la variable\n\nb %= 4 #Resto de la división del valor de la variable entre 4 (Equivalente a b = b % 4)\nprint(\"Valor de b después de &=4: \", b) #Impresión del nuevo valor de la variable\n\nc **= 3 #Potencia del valor de la variable elevado a 3 (Equivalente a c = c ** 3)\nprint(\"valor de c después de **=3: \", c)\n\nprint(\"--------------------------------------------------\")\n\n\"Comparación\"\n\nprint(\"Comparación\") #Operadores que comparan dos valores y devuelven un valor booleano (True o False)\n\nprint(\"¿Es 5 igual a 5?: \", 5 == 5) #Comparación de igualdad entre dos valores\nprint(\"¿Es 5 diferente a 3?: \", 5 != 3) #Comparación de desigualdad entre dos valores\nprint(\"¿Es 6 mayor que 8?: \", 6 > 8) #Comparación de mayor que entre dos valores\nprint(\"¿Es 6 menor que 8?: \", 6 < 8) #Comparación de menor que entre dos valores\nprint(\"¿Es 7 mayor o igual que 7: \", 7 >= 7) #Comparación de mayor o igual que entre dos valores\nprint(\"¿Es 8 menor o igual a 10?: \", 8 <= 10) #Comparación de menor o igual que entre dos valores\n\nprint(\"--------------------------------------------------\")\n\n\"Logicos\"\n\nprint(\"Lógicos\") #Operadores que combinan expresiones booleanas y devuelven un valor booleano (True o False)\n\n\"and, or, not\" #and (y), or (o), not (no)\n\"\"\"Con And:\nTrue and True = True\nTrue and False = False\nFalse and False = False\nFalse and True = False\n\"\"\"\n\nprint(\"Es True y False?: \", True and False) #Devuelve True si ambas expresiones son True\nprint(\"Es True y True?: \", True and True) #Devuelve True si ambas expresiones son True\nprint(\"Es False y False?: \", False and False) #Devuelve True si ambas expresiones son True\nprint(\"Es False y True?: \", False and True) #Devuelve True si ambas expresiones son True\n\n\"\"\"Con Or:\nTrue or True = True\nTrue or False = True\nFalse or False = False\nFalse or True = True\n\"\"\"\nprint(\"Es True o False?: \", True or False) #Devuelve True si al menos una de las expresiones es True\nprint(\"Es True o True?: \", True or True) #Devuelve True si al menos una de las expresiones es True\nprint(\"Es False o False?: \", False or False) #Devuelve True si al menos\nprint(\"Es False o True?: \", False or True) #Devuelve True si al menos una de las expresiones es True\n\n\"\"\"Con Not:\nnot True = False\nnot False = True\n\"\"\"\n\nprint(\"No es True?: \", not True) #Invierte el valor de la expresión (True a False y viceversa)\nprint(\"No es False?: \", not False) #Invierte el valor de la expresión (True a False y viceversa)\n\nprint(\"--------------------------------------------------\")\n\n\"Identidad\"\n\nprint(\"Identidad\") #Operadores que comparan la identidad de dos objetos\n\nx = [1, 5]\ny = [1, 5]\nz = x\n\nprint(\"¿Es x igual a y?: \", x == y) #Comparación de igualdad entre dos objetos\nprint(\"¿Es x idéntico a y?: \", x is y) #Comparación de identidad entre dos objetos\nprint(\"¿Es x idéntico a z?: \", x is z) #Comparación de identidad entre dos objetos\nprint(\"¿Es x no idéntico a y?: \", x is not y) #Comparación de no identidad entre dos objetos\nprint(\"¿Es x no idéntico a z?: \", x is not z) #Comparación de no identidad entre dos objetos\n\nprint(\"--------------------------------------------------\")\n\n\"Pertenencia\"\n\nprint(\"Pertenencia\") #Operadores que comprueban la pertenencia de un elemento a una secuencia (como listas, tuplas o cadenas de texto)\n\nCarros = [ \"BMW\", \"Mercedes\", \"Volkswagen\"] #Lista de carros\n\nprint(\"¿Está BMW en la lista de carros?: \", \"BMW\" in Carros) #Comprueba si un elemento está en la lista\nprint(\"¿Está Audi en la lista de carros?: \", \"Audi\" in Carros) #Comprueba si un elemento está en la lista\nprint(\"No está Audi en la lista de carros: \", \"Audi\" not in Carros) #Comprueba si un elemento no está en la lista\nprint(\"No está BMW en la lista de carros: \", \"BMW\" not in Carros) #Comprueba si un elemento no está en la lista\n\nprint(\"--------------------------------------------------\")\n\n\"Bit a bit\"\n\nprint(\"Bit a bit\") #Operadores que realizan operaciones a nivel de bits en números enteros\n\nx =10 #Nümero entero 10 en binario es 1010\ny = 4 #Número entero 4 en binario es 0100\n\nprint(\"AND bit a bit (x & y): \", x & y) #Operador AND bit a bit\nprint(\"AND bit a bit (y & x): \", y & x) #Operador AND bit a bit\n\nprint(\"OR bit a bit (x | y): \", x | y) #Operador OR bit a bit\nprint(\"OR bit a bit (y | x): \", y | x) #Operador OR bit a bit\n\nprint(\"XOR bit a bit (x ^ y): \", x ^ y) #Operador XOR bit a bit\nprint(\"XOR bit a bit (y ^ x): \", y ^ x) #Operador XOR bit a bit\n\nprint(\"NOT bit a bit (~x): \", ~x) #Operador NOT bit a bit\nprint(\"NOT bit a bit (~y): \", ~y) #Operador NOT bit a bit\n\nprint(\"Desplazamiento a la izquierda (x << 2): \", x << 2) #Desplazamiento de bits a la izquierda\nprint(\"Desplazamiento a la izquierda (y << 3): \", y << 3) #Desplazamiento de bits a la izquierda\n\nprint(\"Desplazamiento a la derecha (x >> 2): \", x >> 2) #Desplazamiento de bits a la derecha\nprint(\"Desplazamiento a la derecha (y >> 1): \", y >> 1) #Desplazamiento de bits a la derecha\n\nprint(\"--------------------------------------------------\")\n\n\"Operadores especiales\"\n\nprint(\"Operadores especiales\") #Operadores que realizan operaciones específicas en ciertos tipos de datos\n\nprint(\"Concatenación de cadenas: \", \"Hola\" + \" \" + \"Mundo\") #Concatenación de cadenas de texto\nprint(\"Repetición de cadenas: \", \"Hola\" * 3) #Repetición de una cadena de texto\nprint(\"Concatenación de listas: \", [1, 2, 3] + [4, 5, 6]) #Concatenación de listas\nprint(\"Repetición de listas: \", [1, 3, 5] * 2) #Repetición de listas\nprint(\"Concatenación de tuplas: \", (1, 2, 3) + (4, 5, 6)) #Concatenación de tuplas\nprint(\"Repetición de tuplas: \", (1, 3, 5) * 2) #Repetición de tuplas\nprint(\"Concatenación de conjuntos: \", {1, 2, 3} | {3, 4, 5}) #Unión de conjuntos\nprint(\"Intersección de conjuntos: \", {1, 2, 3} & {3, 4, 5}) #Intersección de conjuntos\nprint(\"Diferencia de conjuntos: \", {1, 2, 3} - {3, 4, 5}) #Diferencia de conjuntos\nprint(\"Diferencia simétrica de conjuntos: \", {1, 2, 3} ^ {3, 4, 5}) #Diferencia simétrica de conjuntos\nprint(\"Repetición de cadenas con f-string: \", f\"{'Hola' * 3}\") #Repetición de cadenas de texto usando f-string\nprint(\"Repetición de listas con f-string: \", f\"{[1, 3, 5] * 2}\") #Repetición de listas usando f-string\nprint(\"Repetición de tuplas con f-string: \", f\"{(1, 3, 5) * 2}\") #Repetición de tuplas usando f-string\nprint(\"Concatenación de cadenas con f-string: \", f\"{'Hola' + ' ' + 'Mundo'}\") #Concatenación de cadenas de texto usando f-string\nprint(\"Concatenación de listas con f-string: \", f\"{[1, 2, 3] + [4, 5, 6]}\") #Concatenación de listas usando f-string\nprint(\"Concatenación de tuplas con f-string: \", f\"{(1, 2, 3) + (4, 5, 6)}\") #Concatenación de tuplas usando f-string\nprint(\"Concatenación de conjuntos con f-string: \", f\"{ {1, 2, 3} | {3, 4, 5} }\") #Unión de conjuntos usando f-string\nprint(\"Intersección de conjuntos con f-string: \", f\"{ {1, 2, 3} & {3, 4, 5} }\") #Intersección de conjuntos usando f-string\nprint(\"Diferencia de conjuntos con f-string: \", f\"{ {1, 2, 3} - {3, 4, 5} }\") #Diferencia de conjuntos usando f-string\nprint(\"Diferencia simétrica de conjuntos con f-string: \", f\"{ {1, 2, 3} ^ {3, 4, 5} }\") #Diferencia simétrica de conjuntos usando f-string\n\nprint(\"--------------------------------------------------\")\n\n\"Estructuras de control\"\n\nprint(\"Estructuras de control\") #Estructuras que permiten controlar el flujo de ejecución del programa usando operadores\n\n\"Condicionales\"\n\nprint(\"Condicionales\") #Estructuras que permiten ejecutar código según una condición\n\n\"if, elif, else\" #if (si), elif (sino si), else (sino)\n\nEdad = int(input(\"Ingresa tu edad: \")) #Entrada de la edad del usuario\n\nif Edad < 18: #Si la edad es menor a 18\n    print(\"Eres menor de edad.\") #Imprime que es menor de edad\n\nelif Edad >= 18 and Edad < 65: #Si la edad es mayor o igual a 18 y menor a 65\n    print(\"Eres adulto.\") #Imprime que es adulto\n    \nelif Edad >=100: #Si la edad es mayor o igual a 100\n    print(\"Eres una persona centenaria.\") #Imprime que es una persona centenaria\n\nelse: #Si la edad es mayor o igual a 65\n    print(\"Eres adulto mayor.\") #Imprime que es adulto mayor\n\n\nprint(\"--------------------------------------------------\")\n\n\"Interactivas\"\n\nprint(\"Interactivas\") #Estructuras que permiten repetir código mientras una condición sea verdadera\n\n\"while, for, break, continue\" #while (mientras), for (para), break (romper), continue (continuar)\n\nprint(\"Ejemplo con while:\") #Ejemplo de uso de while\n\ncontraseña = \"\" #Contraseña inicialmente vacía\nwhile contraseña != \"Felix\": #Mientras la contraseña sea diferente a \"Felix\" se repite el ciclo\n    contraseña = input(\"Ingresa la contraseña por favor: \") #Entrada de la contraseña del usuario\n    if contraseña != \"Felix\": #Si la contraseña es diferente a \"Felix\"\n        print(\"Contraseña incorrecta, intente de nuevo.\") #Imprime que la contraseña es incorrecta2\n\nelse: #Si la contraseña es igual a \"Felix\"\n    print(\"Has ingresado correctamente.\") #Imprime que ha ingresado correctamente\n\nprint(\"Ejemplo con for:\") #Ejemplo de uso de for\n\ncomida = [\"Pizza\", \"Hamburguesa\", \"Enchiladas\", \"Sushi\"] #Lista de comidas favoritas\n\nfor plato in comida: #Para cada plato en la lista de comidas\n    if plato == \"Pizza\": #Si el plato es \"Pizza\"\n        print(\"Mi favorita es Pizza\") #Imprime un mensaje específico para la Pizza\n\n        continue #Continúa con la siguiente iteración del ciclo\n\n    print(f\"Me gusta comer {plato}\") #Imprime el plato que te guste también\n    if plato == \"Sushi\": #Si el plato es \"Sushi\"\n\n        break #Rompe el ciclo\n\nprint(\"--------------------------------------------------\")\n\n\"Excepciones\"\n\nprint(\"Excepciones\") #Estructuras que permiten manejar errores en el código\n\n\"try, except, finally\" #try (intentar), except (excepto), finally (finalmente)\n\ntry: #Intenta ejecutar el siguiente bloque de código\n\n    x =int(input(\"Ingresa un número: \")) #Entrada de un número del usuario\n    f = 20 // x #División del número entre 20\n\n\nexcept ValueError:\n    print(\"Error: Debes ingresar un número válido.\") #Imprime que el número no es válido\n\nexcept ZeroDivisionError:\n    print(\"Error: No se puede dividir entre cero.\") #Imprime que no se puede dividir entre cero\n\nelse:\n    print(\"El resultado de 20 dividido entre\", x, \"es:\", f) #Imprime el resultado de la división si no hay errores\n\nfinally: \n    print(\"Gracias por usar el programa.\") #Imprime un mensaje de agradecimiento al final\n\nprint(\"--------------------------------------------------\")\n\n\"Funciones\"\n\nprint(\"Funciones\") #Estructuras que permiten definir bloques de código reutilizables\n\n\"def, return\" #def (definir), return (retornar)\n\ndef saludar(nombre): #Definición de una función que saluda a una persona\n    return f\"Hola, {nombre}\" #Retorna el saludo con el nombre de la persona\n\nnombre = input(\"Ingresa tu nombre: \") #Entrada del nombre del usuario\nprint(saludar(nombre)) #Imprime el saludo con el nombre del usuario\n\nprint(\"--------------------------------------------------\")\n\n\"Clases\"\n\nprint(\"Clases\") #Estructuras que permiten definir objetos con atributos y métodos\n\nclass Animales: #Definición de una clase llamada Animales\n    def __init__(self, nombre, especie): #Método constructor que inicializa los atributos de la clase\n        self.nombre = nombre #Atributo nombre\n        self.especie = especie #Atributo especie\n    \n    def tipo_alimentación(self, alimentación): #Método que define el tipo de alimentación del animal\n        self.alimentación = alimentación #Atributo alimentación\n        return f\"{self.nombre} es un {self.especie} y se alimenta de {self.alimentación}\" #Retorna una descripción del animal\n\nAnimal1 = Animales(nombre = input(\"Ingresa el nombre del León: \"), especie = \"León\") #Creación de un objeto de la clase Animales\nprint(Animal1.tipo_alimentación(input(f\"Ingresa el tipo de alimentación de {Animal1.nombre}: \"))) #Imprime la descripción del animal con su tipo de alimentación\n\nAnimal2 = Animales(nombre = input(\"Ingresa el nombre del perro: \"), especie = \"perro\") #Creación de otro objeto de la clase Animales\nprint(Animal2.tipo_alimentación(input(f\"Ingresa el tipo de alimentación de {Animal2.nombre}: \"))) #Imprime la descripción del animal con su tipo de alimentación\n\nprint(\"--------------------------------------------------\")\n\n\"Dificultad extra\"\n\nprint(\"Dificultad extra\") #Ejemplos adicionales de estructuras de control y operadores\nprint(\"Crea un programa que imprima por consola todos\\\n los números comprendidos entre 10 y 55 (incluidos)\\\n pares, y que no son ni el 16 ni múltiplos de 3.\")\n\nfor num in range(10, 56): #Para cada número en el rango de 10 a 55\n    multi3 = num % 3 == 0 #Variable que almacena el resultado de la operación módulo para determinar si un número es múltiplo de 3\n    par = num % 2 == 0 #Variable que almacena el resultado de la operación módulo para determinar si un número es par\n    if par and num != 16 and not multi3: #Si el número es par, diferente a 16 y no es múltiplo de 3\n        print(num) #Imprime el número que cumple con las condiciones\n\nprint(\"--------------------------------------------------\")"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/ZAKKDRTE.py",
    "content": "##01 - OPERADORES Y ESTRUCTURAS DE CONTROL\n\"\"\"\nEJERCICIO:\n- Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\nAritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n(Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n- Utilizando las operaciones con operadores que tú quieras, crea ejemplos\nque representen todos los tipos de estructuras de control que existan\nen tu lenguaje:\nCondicionales, iterativas, excepciones...\n- Debes hacer print por consola del resultado de todos los ejemplos.\n\nDIFICULTAD EXTRA (opcional):\nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\nSeguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\n\"\"\"\n\n# Operadores Aritmeticos #\nprint(20 + 10)  # Suma\nprint(20 - 10)  # Resta\nprint(20 * 10)  # Multiplicacion\nprint(20 / 10)  # Dvision con resultado float\nprint(20 // 10) # Division con resultado entero\nprint(20 ** 2)  # Exponentes\nprint(20 % 10)  # Residuo\n\n# Operadores Logicos #\nprint(True or False)    # Devuelve True \nprint(True and False)   # Devuelve False\nprint(not( True or False))  # Devuelve False \nprint(not(True and False))  # Devuelve True\n\n# Operadores de Comparacion\nprint(5 < 10)   # Devuelve True porque 5 es menor que 10\nprint(5 <= 10)  # Devuelve True porque 5 es menor que 10    *NOTA* Este da True si es menor o igual\nprint(5 > 10)   # Devuelve False porque 5 no es mayor que 10\nprint(5 >= 10)  # Devuelve False porque 5 no es mayor que 10    *NOTA* Este da True si es mayor o igual\nprint(5 == 10)  # Devuelve False porque 5 no es igual que 10\nprint(5 != 10)  # Devuelve True porque 5 es diferente que 10\n\n# Operadores de asignacion #\na = 5   # Se le asigna valor igual a 5\nprint(a)\na += 10 # Se le asigna un +10 y da como resultado 15\nprint(a)\na -= 10 # Se le asigna un -10 y da como resultado 5\nprint(a)\na *= 10 # Se le asigna un *10 y da como resultado 50\nprint(a)\na //= 5 # Se le asigna un //5 y da como resultado 10 sin float\nprint(a)\na **= 2 # Se le asigna un exponente 2 y da como resultado 100\nprint(a)\na /= 2  # Se le asigna un /5 y da como resultado 50.0 con float\nprint(a)\na %= 9  # Se le asigna un %9 y da como resultado 5.0\nprint(a)\n\n# Operadores de Identidad #\n    ## Este operadores es boolean y devuelve True si ambos operandos apuntan al mismo objeto de memoria ##\na = 5\nb = 5\nc = 3\n\nprint(a is b)   # Devuelve True\nprint(a is not b)   # Devuelve False\nprint(a is c)   # Devuelve False\nprint(a is not c)   # Devuelve True\n\n# Operadores de Pertenencia #\nlist = [1, 2, 3, 4, 5]\n\nprint(3 in list)    # Devuelve True\nprint(6 in list)    # Devuelve False\nprint(3 not in list)    # Devuelve False\nprint(6 not in list)    # Devuelve True\n\n# bits\n## Se hace uso de las tablas de la verdad ##\na = 5    # Representación binaria: 0b0101\nb = 3    # Representación binaria: 0b0011\nprint(a & b ) # Resultado: 0b0001 (1 en binario)\na = 5    # Representación binaria: 0b0101\nb = 3    # Representación binaria: 0b0011\nprint(a | b ) # Resultado: 0b0111 (7 en binario)\na = 5    # Representación binaria: 0b0101\nb = 3    # Representación binaria: 0b0011\nprint(a ^ b)  # Resultado: 0b0110 (6 en binario)\na = 5    # Representación binaria: 0b0101\nprint(~a ) # Resultado: Dependiente de la representación en complemento a dos, en este caso, -6\na = 5    # Representación binaria: 0b0101\nprint(a << 1 ) # Resultado: 0b1010 (10 en binario)\na = 5    # Representación binaria: 0b0101\nprint(a >> 1)  # Resultado: 0b0010 (2 en binario)\n\n# Estructuras de Control #\nnum = 0\n\nwhile num < 11:\n    if num < 10:\n        print(\"Es menor que 10\")\n        num += 1\n    elif num == 10:\n        print(\"Es igual a 10\")\n        num += 1\n    else:\n        break\n\nfor i in range(1, 101):\n    if i % 3 == 0 and i % 5 == 0:\n        print(\"fizzbuzz\")\n    elif i % 3 == 0:\n        print(\"fizz\")\n    elif i % 5 == 0:\n        print(\"buzz\")\n    else:\n        print(i)\n\ntry:\n    resultado = 10 / 0\nexcept Exception as e:\n    print(f\"Se produjo una excepción: {type(e).__name__}\")\n\n\n\n# Ejercicio Extra #\n\n\n\ndef nums():\n    for i in range(10, 56):\n        if i % 2 == 0 and i != 16 and i % 3 != 0:\n            print(i)\n\nnums()"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Zequy40.py",
    "content": "# Retos de programación.\n'''\nNOTA:\nSoy nuevo en esto, pero me pareció interesantes para aprender más. Aunque mi lenguaje no es Python, quiero hacer el reto en este lenguanje para coger experiencia despues de ver los cursos de moure, y un forma de seguir mejorando.\nNo sé si lo haré bien porque al ser nuevo no entendía bien lo que se pedía, y espero que lo haya hecho correctamente. Veré la correción el 8. Lo he intentado hacer lo mejor posible.\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n \n Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\n Para saber todos los tipos de operadores de tu lenguaje de Python, me he basado en la documentación de Python https://docs.python.org/es/3.11/library/operator.html?highlight=operadores. \n Es posible que me falte o se me haya pasado algunos, aprovecharé a correccion para saber si falta o están todos.\n '''\n\n# Aritméticos\na = 8\nb = 3\n\nsuma = a + b  #operadores basaicos\nresta = a - b\nmultiplicacion = a * b\ndivision = a / b\nmodulo = a % b #Operador que devuelve lo que queda del resultado de una división\npotencia = a ** b #Operador que eleva a la potencia especificada\ndivision_entera = a // b #Este operador hace la división igual que la normal pero el resultado será entero porque el residuo lo ignora, mientras que la normal puede haber numero decimal.\n\nprint(f\"Aritméticos: {suma}, {resta}, {multiplicacion}, {division}, {modulo}, {potencia}, {division_entera}\")\n\n# Lógicos\nx = True\ny = False\n\nand_result = x and y #Este operador es el de siempre\nor_result = x or y #Este operador es el o de siempre\nnot_result = not x #Y este operador es peculiar porque devolverá siempre lo contrario, por ejemplo si es x es True devolverá False, y si x es False devolverá True\n\nprint(f\"Lógicos: {and_result}, {or_result}, {not_result}\")\n\n# De comparación\na = 5\nb = 10\n\nigual = a == b\ndiferente = a != b\nmayor_que = a > b\nmenor_que = a < b\nmayor_o_igual = a >= b\nmenor_o_igual = a <= b\n\nprint(f\"De comparación: {igual}, {diferente}, {mayor_que}, {menor_que}, {mayor_o_igual}, {menor_o_igual}\")\n\n# De asignación\nx = 5\n\nx += 2  # x = x + 2 para no tener que repetir el numero 5 = 5 + 2 --> queda 5 += 2 para condensar el codigo\nx -= 3  # x = x - 3\nx *= 4  # x = x * 4\nx /= 2  # x = x / 2\nx %= 3  # x = x % 3\n\nprint(f\"De asignación: {x}\")\n\n# De identidad\n''' Un apunte aparte, para explicar un detalle más (no sé muy bien si entra en la categoría),\npero quiero dar este apunte porque a mí me creo confunción respeto a otros lenguajes:\nHay diferencia entre Lista, Sets, Tuplas y Diccionarios.\n- LISTA --> se utiliza []\n- SETS --> se utiliza {}\n- Tuplas --> se utiliza ()\n- DICCIONARIO --> se utiliza {\"x\":\"y\"} lo que se denomina clave:valor\nY cada uno tiene un comportamiento distinto\n'''\n\na = [1, 2, 3] #Es una lista\nb = a #Aquí b hace referencia la lista a\nc = [1, 2, 3] #Pero aquí aunque c tenga los mismos valores que a es una lista distinta.\n\nidentidad1 = a is b #Aquí devolverá True porque hace referencia a la misma lista\nidentidad2 = a is c #Aquí devolverá False porque aunque tenga el mismo valor son listas distintas\n\nprint(f\"De identidad: {identidad1}, {identidad2}\")\n\n# De pertenencia\nlista = [1, 2, 3, 4, 5]\npertenece1 = 3 in lista #Simplemente pregunta si el 3 está en lista\npertenece2 = 6 not in lista #Aquí si el 6 no está en lista\n\nprint(f\"De pertenencia: {pertenece1}, {pertenece2}\")\n\n# Bits\nx = 5\ny = 3\n\n#Aunque esto operadores se parezcan al and que vimos arriba, en realidad no son iguales\n#Aquí se trabaja con numeros enteros, en los logicos se trabaja con booleanos\nand_bits = x & y \nor_bits = x | y\nxor_bits = x ^ y #Aquí es un poco peculiar porque devolverá True si uno de los numeros está en la position 1\ncomplemento_bits = ~x #Aquí no lo sé muy bien, y no lo entiendo tampoco (la teoría es que los bits se invierten, no sé más)\nshift_izquierda = x << 1 #Igual (la teoría es que los bits se desplazan a la izquierda, no sé más)\nshift_derecha = x >> 1 #Igual (la teoría es que los bits se desplazan a la derecha, no sé más)\n\nprint(f\"Bits: {and_bits}, {or_bits}, {xor_bits}, {complemento_bits}, {shift_izquierda}, {shift_derecha}\")\n\n# Condicionales\nedad = 18\n\nif edad < 18:\n    print(\"Eres menor de edad\")\nelif edad == 18:\n    print(\"Tienes 18 años\")\nelse:\n    print(\"Eres mayor de edad\")\n\n#O esta otra forma también usanso mayor \">\"\nif edad > 18:\n    print(\"Eres mayor de edad\")\nelif edad == 18:\n    print(\"Tienes 18 años\")\nelse:\n    print(\"Eres menor de edad\")\n\n# Iterativas\nfor i in range(5):\n    print(i)\n\nedad = 18\nwhile edad > 0:\n    print(edad)\n    edad -= 1\n\n#Hay otra manera posible:\nedad = 18 \nwhile True:\n  if edad > 0:\n    print(edad)\n    edad -= 1\n\n# Excepciones\ntry:\n    resultado = 10 / 0\nexcept ZeroDivisionError:\n    print(\"¡Error! División por cero.\")\nfinally:\n    print(\"Este bloque siempre se ejecuta.\")\n\n'''\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n'''\n\nstrangeNumber = [i for i in range(10, 56) if (i != 16 and i % 2 == 0 and i % 3 != 0) or i == 55]\n\nprint(strangeNumber)\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Zerek247.py",
    "content": "# -------------------- Tipos de operadores Aritméticos en python ------------------------\n#Operador suma ( + )\nprint(\"Ahora vamos con la suma\")\nnum1 = 20\nnum2 = 21\nsuma = num1 + num2\nprint(f'El resultado de sumar {num1} + {num2} es: {suma}')\n\n#Operador resta ( - )\nprint(\"\\nAhora vamos con la resta\")\nnum1 = 40\nnum2 = 13\nresta = num1 - num2\nprint(f'El resultado de restar {num1} - {num2} es: {resta}')\n\n#Operador multiplicación ( * )\nprint(\"\\nAhora vamos con la multiplicacion\")\nnum1 = 23\nnum2 = 55\nmultiplicacion = num1 * num2\nprint(f'El resultado de multiplicar {num1} * {num2} es: {multiplicacion}')\n\n#Operador división ( / )\nprint(\"\\nAhora vamos con la división\")\nnum1 = 10\nnum2 = 2\ndivision = num1 / num2\nprint(f'El resultado de dividir {num1} / {num2} es: {division}')\n\n#Operador división entera ( // )\nprint(\"\\nAhora vamos con la división entera\")\nnum1 = 70\nnum2 = 20\ndivision_entera = num1 // num2\nprint(f'El resultado de la division entera {num1} // {num2} es: {division_entera}')\n\n#Operador división entera ( // )\nprint(\"\\nAhora vamos con la división entera\")\nnum1 = 70\nnum2 = 20\ndivision_entera = num1 // num2\nprint(f'El resultado de la division entera {num1} // {num2} es: {division_entera}')\n\n#Operador Módulo (Resto de la división) ( % )\nprint(\"\\nAhora vamos con el resto\")\nnum1 = 86\nnum2 = 67\nresto = num1 % num2\nprint(f'El resultado del módulo o resto {num1} % {num2} es: {resto}')\n\n#Operador exponente (potencia)\nprint(\"\\nAhora vamos con la potencia\")\nnum1 = 4\nnum2 = 2\nexponente = num1 ** num2\nprint(f'El resultado del numero {num1} elevado al {num2} es: {exponente}')\n\n\n# ------------------- Tipos de operadores lógicos en python ---------------------------\n\n\n#Operador  AND ( & ) Es true si ambas condiciones se cumplen\nnum1 = 50\nnum2 = 60\nif num1 & num2 >40:\n    print(True)   \nelse:\n    print(False)\n    \n#operador OR ( | ) Es true si al menos una condicion se cumple\nnum1 = 50\nnum2 = 60\nif num1 | num2 > 55:\n    print(True)   \nelse:\n    print(False)\n    \n#Operador NOT (  )\nnum1 = 50\nnum2 = 60\nif not (num1 > num2):\n    print(\"No es mayor\")   \nelse:\n    print(\"Es mayor\")\n    \n# ------------------------ Tipos de operadores de comparación en python -------------------------\n\n#Operador Igual a ( == )\ntupla1 = (23,67,89,0)\ntupla2 = (23,67,89,0)\n\nif tupla1 == tupla2:\n    print(\"Son iguales\")\nelse:\n    print(\"No son iguales\")\n    \n#Operador No igual a ( != )\nlista1 = [23,67,89,0]\nlista2 = [23,6,89,0]\n\nif lista1 != lista2:\n    print(\"Son diferentes\")\nelse:\n    print(\"Son iguales\")\n    \n#Operador Mayor que ( > )\nnum1 = 23.3\nnum2 = 23.1\nif num1 > num2:\n    print(f'Efectivamente {num1} es mayor a {num2}')\nelse:\n    print(f'El numero {num1} no es mayor a {num2}')\n    \n#Operador Mayor o igual que ( >= )\nnum1 = 78\nnum2 = 78\nif num1 >= num2:\n    print(f\"El numero {num1} es igual o mayor al numero {num2}\")\nelse:\n    print(f'El numero {num1} no es mayor o igual al numero {num2}')\n    \n#Operador Menor que ( < )\nnum1 = 23.3\nnum2 = 23.1\nif num1 < num2:\n    print(f'Efectivamente {num1} es menor a {num2}')\nelse:\n    print(f'El numero {num1} no es menor a {num2}')\n    \n#Operador Menor o igual que ( <= )\nnum1 = 90\nnum2 = 78\nif num1 <= num2:\n    print(f\"El numero {num1} es igual o menor al numero {num2}\")\nelse:\n    print(f'El numero {num1} no es menor o igual al numero {num2}')\n    \n\n# ---------------------  Tipos de operadores de asignacíon en python --------------------------------\n\n#Asignación simple ( = )\na = 4\nprint(a)\n\n#Suma y signación ( += )\nc = 3\nc += 6\nprint(c)\n\n#Resta y asignación ( -= )\nd = 90\nd -= 70\nprint(d)\n\n#Multiplicación y asignación\ng = 4\ng *=4\nprint(g)\n\n#División y asignación ( /= )\nh = 10\nh /= 2\nprint(h)\n\n#Módulo y asignación ( %= )\nb = 8\nb %= 5\nprint(b)\n\n#División entera y asignación ( //= )\ne = 34\ne //= 4\nprint(e)\n\n#Exponente y asignación ( **= )\nf = 4\nf **= 2\nprint(f)\n\n# AND bit a bit y asignación ( &= )\n''' 00000011  (3 en binario)\n &  00000111  (7 en binario)\n-----------\n    00000011  (resultado, que es 3 en decimal)\n'''\ni = 3\ni &= 7\nprint(i)\n#OR bit a bit y asignación ( |= )\n''' 00000011  (3 en binario)\n |  00000111  (7 en binario)\n-----------\n    00000111  (resultado, que es 7 en decimal)\n'''\nj = 3\nj |= 7\nprint(j)\n#XOR bit a bit y asignacíon ( ^= )\n''' 00000011  (3 en binario)\n ^  00000111  (7 en binario)\n-----------\n    00000100  (resultado, que es 7 en decimal)\n'''\nk = 3\nk ^= 7\nprint(k)\n#Desplazamiento a la derecha y asignación ( >>= )\n'''  00110010  (50 en binario)\n>>          3  (desplazamos 3 posiciones a la derecha)\n--------------\n     00000110  (resultado, que es 0 en decimal)\n'''\nl = 50\nl >>= 3\nprint(l)\n#Desplazamiento a la izquierda y asignación ( <<= )\n'''  00101101  (50 en binario)\n<<          3  (desplazamos 3 posiciones a la derecha)\n--------------\n     00000110  (resultado, que es 0 en decimal)\n'''\nm = 45\nm <<= 3\nprint(m)\n\n\n# ------------------- Operadores de identidad ( ís & is not) ---------------------\n#Operador is\na = [1, 2, 3]\nb = a\nc = [1, 2, 3]\nprint(a is b)  # True, porque b es la misma referencia que a\nprint(a is c)  # False, porque c es una lista diferente, aunque tiene el mismo contenido\n#Operador is not\na = [1, 2, 3]\nb = a\nc = [1, 2, 3]\nprint(a is not b)  # False, porque b es la misma referencia que a\nprint(a is not c)  # True, porque c es una lista diferente, aunque tiene el mismo contenido\n\n\n# ----------------------Operadores de indentidad (in & not in) ----------------------------\n#Operador in\n# Ejemplo con una lista\nlista = [1, 2, 3, 4, 5]\nprint(3 in lista)  # True, porque 3 está en la lista\n#Operador not\nlista = [1, 2, 3, 4, 5]\nprint(6 not in lista)  # True, porque 6 no está en la lista\n\n\n\n# programa que imprima por consola todos los números comprendidos\n# entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\nfor contador in range(10, 56):\n    if contador != 16 and contador % 2 == 0 and contador % 3 != 0:\n        print(contador)\n        "
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/Zzepu.py",
    "content": "# Declarando operadores aritmeticos\n\nprint(f'Suma: 15 + 15 = {15 + 15}')\nprint(f'Resta: 50 - 15 = {50 - 15}')\nprint(f'Multiplicacion: 5 * 5 = {5 * 5}')\nprint(f'Division: 50 / 2 = {50 / 2}')\nprint(f'Modulo: 50 % 2 = {50 % 2}')\nprint(f'Exponente: 50 ** 2 = {50 ** 2}')\nprint(f'Division entera: 50 // 2 = {50 // 2}')\n\n# Declarando operadores de comparacion\nprint(f'Igualdad: 10 == 3 es {10 == 3}')\nprint(f'Desigualdad: 10 != 3 es {10 != 3}')\nprint(f'Mayor que: 10 > 3 es {10 > 3}')\nprint(f'Menor que: 10 < 3 es {10 < 3}')\nprint(f'Mayor o igual que: 10 >= 3 es {10 >= 3}')\nprint(f'Menor o igual que: 10 <= 3 es {10 <= 3}')\n\n# Declarando operadores logicos\nprint(f'AND: 30 + 5 == 35 and 10 + 10 == 20 es: {30 + 5 == 35 and 10 + 10 == 20}')\nprint(f'OR: 30 + 5 == 35 or 10 + 10 == 20 es: {30 + 5 == 35 or 10 + 10 == 20}')\nprint(f'NOT: not 20 + 5 == 31 es {not 20 + 5 == 31}')\n\n# Declarando operadores de asignacion\nsweet_number = 50 # Asignacion\nprint(sweet_number)\nsweet_number += 5 # suma y asignacion\nprint(sweet_number)\nsweet_number -= 5 # Resta y asignacion\nprint(sweet_number)\nsweet_number *= 5 # Multiplicacion y asignacion\nprint(sweet_number)\nsweet_number /= 6 # Division y asignacion\nprint(sweet_number)\nsweet_number %= 5 # Modulo y asignacion\nprint(sweet_number)\nsweet_number **= 9 # Exponente y asignacion\nprint(sweet_number)\nsweet_number //= 6 # Division entera y asignacion\nprint(sweet_number)\n\n# Declarando operadores de identidad\nnew_sweet_number = 16.0\nprint(f'sweet_number is new_sweet_number es {sweet_number is new_sweet_number}')\nprint(f'sweet_number is not new_sweet_number es {sweet_number is not new_sweet_number}')\n\n# Operadores de pertenencia\nprint(f\"'e' in 'zzepu' es {'e' in 'zzepu'}\")\nprint(f\"'s' not in 'zzepu' es {'s' not in 'zzepu'}\")\n\n# Operadores de bit\ny = 10 # 1010\nz = 3 # 0011\nprint(f'AND: 10 & 3 es {10 & 3}')\nprint(f'OR: 10 | 3 es {10 | 3}')\nprint(f'XOR: 10 ^ 3 es {10 ^ 3}')\nprint(f'NOT: ~10 es {~10}')\nprint(f'Desplazamiento a la derecha: 10 >> 2 es {10 >> 2}')\nprint(f'Desplazamiento a la izquierda: 10 << 2 es {10 << 2}')\n\n\"\"\"\nEstructuras de control\n\"\"\"\n\nsweet_string = 'Zzepu'\n\nif sweet_string == 'Zzepu':\n    print('sweet_string es Zzepu')\nelse:\n    print('sweet_string no es Zzepu')\n\n# Ciclos iterativos\n\nfor i in range(11):\n    print(i)\n\ni = 0\nwhile i <=10:\n    print(i)\n    i += 1\n\n\n# Manejo de expepciones\n\ntry:\n    print(10 / 0)\nexcept:\n    print('Ups! Hay un falloooo')\nfinally:\n    print('Ha concluido el manejo de excepciones')\n\n\n# Ejercicio extra!\n\n\nfor numbers in range(10,56):\n    if numbers % 2 == 0 and numbers != 16 and numbers % 3 != 0:\n        print(numbers)\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/a-mayans.py",
    "content": "'''\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n'''\n\n#---  OPERADORES  ---#\n\n# Aritmeticos ( +, -, *, /, %, **, // )\noperando_1 = 10\noperando_2 = 7\nprint(f'Suma: {operando_1 + operando_2}')               # devuelve la suma\nprint(f'Resta: {operando_1 - operando_2}')              # devuelve la resta\nprint(f'Multiplicacion: {operando_1 * operando_2}')     # devulve la multiplicacion\nprint(f'Division: {operando_1 / operando_2}')           # devuelve el cociente (inclye decimales)\nprint(f'Modulo: {operando_1 % operando_2}')             # devuelve el resto/residuo\nprint(f'Potencia: {operando_1 ** operando_2}')          # devuelve el numero en potencia\nprint(f'Division entero: {operando_1 // operando_2}')   # devuelve el cociente entero\n\n\n# Logicos ( para trabajar con valores de tipo bool ) -> AND, OR, NOT\nprint(True and True)        # devuelve True\nprint(True and False)       # devuelve False\nprint(True or False)        # devuelve True\nprint(not True)             # devuelve False\nprint(not False)            # devuelve True\nprint(not 0)                # cero es igual a False, entonces devuelve True\nprint(not 1)                # uno es igual a True, entonces devuelve False\n\n\n# Comparacion ( >, <, ==, >=, <=, !=, ) -> devuelve un valor booleano\nprint(f'Mayor que: {operando_1 > operando_2}')              # devuelve True\nprint(f'Menor que: {operando_1 < operando_2}')              # devuelve False\nprint(f'Igual que: {operando_1 == operando_2}')             # devuelve False\nprint(f'Mayor o igual que: {operando_1 >= operando_2}')     # devuelve True\nprint(f'Menor o igual que: {operando_1 <= operando_2}')     # devuelve False\nprint(f'Distinto que: {operando_1 != operando_2}')          # devuelve True\n\n\n# Asignacion ( =, +=, -=, *=, /=, %=, **=, //= ) -> asignar valores a una variable\na = 5\nprint(f'Variable a: {a}')\na += 10 # es lo mismo que a = a + 10\nprint(f'Sumando 10 a la variable a: {a}')\na -= 10 # es lo mismo que a = a - 10\nprint(f'Restando 10 a la variable a: {a}')\na *= 10 # es lo mismo que a = a * 10\nprint(f'Multiplicando 10 a la variable a: {a}')\na /= 10 # es lo mismo que a = a / 10\nprint(f'Dividiendo 10 a la variable a: {a}')\nb = 45\nb %= 10 # es lo mismo que a = a % 10\nprint(f'Modulo 10 a la variable b: {b}')\nb **= 10\nprint(f'Potencia 10 a la variable b: {b}')\nb //= 5\nprint(f'Division entera 10 a la variable b: {b}')\n\n\n# Indentidad ( is, is not) -> comprobar si dos variables emplean la misma ubicacion en memoria\na = 3\nb = 3\nc = 4\nprint(a is b)               # devuelve True\nprint(a is not b)           # devuelve False\nprint( a is c)              # devuelve False\nprint( a is not c)          # devuelve True\n\n\n# Pertenencia ( in, not it) -> para indicar pertenencia a alguna secuencia (listas, tuplas, strings)\nlista = [1, 2, 3, 4, 5]\nprint(3 in lista)           # devuelve True\nprint(15 not in lista)      # devuelve True\n\nstring = 'Hola, que tal'\nprint('que' in string)      # devuelve True\nprint('de' in string)       # devuelve False\nprint('Ho' in string)       # devuelve True\nprint('ho' in string)       # devuelve False, distingue entre mayusculas y minusculas, es case sensitive\n\n\n\n#---  ESTRUCTURAS DE CONTROL ( Condicionales, iterativas, excepciones... )  ---#\n\n# CONDICIONAL\n# If, elif, else ( controlar si se cumple 1 o varias condiciones -> utilizar operadores de comparacion y logicos)\ntotal_compra = 120\n\nif total_compra <= 100:\n    print('Pago en efectivo')\nelif total_compra > 100 and total_compra < 500:\n    print('Pago con targeta de debito')\nelse:\n    print('Pago con targeta de credito')\n\n\n# ITERATIVA\n# While ( ejecuta una misma accion mientras una condicion se cumpla. Dejara de ejecutarse cuando la condicion se incumpla)\nnumero = 0\nwhile numero <= 10:\n    print(numero)\n    numero += 1\n\n\n# For ( permite iterar sobre una variable compleja - Listas o Tuplas)\ntupla = ('verde', 'rojo', 'amarillo', 'azul', 'naranja')\nfor color in tupla:\n    print(color)\n\n\n# EXCEPCION\nwhile True:\n    # control de la excepcion\n    try:\n        number = int(input('Inserta un numero: '))\n        break # si introduce un valor valido termina la ejecucion\n    \n    # si no introduce un valor valido, devuelve el error controlado\n    except ValueError:\n        print('Error! No ha insertado un valor valido. Intentelo de nuevo')\n\n\n#---  Reto Extra  ---#\n# Iterando con un bucle For sobre el rango, y utilizando el condicional If con operadores de comparacion\nfor num in range(10, 56):\n    if num % 2 == 0 and num != 16 and num % 3 != 0:\n        print(num)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/aBoredLlama.py",
    "content": "# Operadores del lenguaje Python.\n\n## Operadores aritméticos.\n\nprint(\"Suma: 2 + 2 =\", 2 + 2) # sirve para sumar dos números o variables.\nprint(\"Resta: 2 - 2 =\", 2 - 2) # sirve para restar dos números o variables.\nprint(\"Multiplicación: 2 * 2 =\", 2 * 2) # sirve para multiplicar dos números o variables.\nprint(\"División: 2 / 2 =\", 2 / 2) # sirve para dividir dos números o variables.\nprint(\"Módulo: 2 % 2 =\", 2 % 2) # sirve para obtener el residuo de una división.\nprint(\"Exponente: 2 ** 2 =\", 2 ** 2) # sirve para elevar un número a una potencia.\nprint(\"División entera: 2 // 2 =\", 2 // 2) # sirve para obtener la parte entera de una división.\n\n## Operadores de asignación.\n\nprint(\"Asignación: 2 =\", 2) # sirve para asignar un valor a una variable.\nprint(\"Suma y asignación (+=): x = 2, x += 2 =\", 2 + 2) # sirve para sumar un valor a una variable y asignar el resultado.\nprint(\"Resta y asignación (-=): x = 2, x -= 2 =\", 2 - 2) # sirve para restar un valor a una variable y asignar el resultado.\nprint(\"Multiplicación y asignación (*=): x = 2, x *= 2 =\", 2 * 2) # sirve para multiplicar un valor a una variable y asignar el resultado.\nprint(\"División y asignación (/=): x = 2, x /= 2 =\", 2 / 2) # sirve para dividir un valor a una variable y asignar el resultado.\nprint(\"Módulo y asignación (%=): x = 2, x %= 2 =\", 2 % 2) # sirve para obtener el residuo de una división y asignar el resultado.\nprint(\"Exponente y asignación (**=): x = 2, x **= 2 =\", 2 ** 2) # sirve para elevar un número a una potencia y asignar el resultado.\nprint(\"División entera y asignación (//=): x = 2, x //= 2 =\", 2 // 2) # sirve para obtener la parte entera de una división y asignar el resultado.\n\n## Operadores de comparación.\n\nprint(\"Igualdad: 2 == 2 es\", 2 == 2) # sirve para comparar si dos valores o variables son iguales.\nprint(\"Desigualdad: 2 != 3 es\", 2 != 3) # sirve para comparar si dos valores o variables son diferentes.\nprint(\"Mayor que: 2 > 3 es\", 2 > 3) # sirve para comparar si un valor es mayor que otro.\nprint(\"Menor que: 2 < 3 es\", 2 < 3) # sirve para comparar si un valor es menor que otro.\nprint(\"Mayor o igual que: 2 >= 2 es\", 2 >= 2) # sirve para comparar si un valor es mayor o igual que otro.\nprint(\"Menor o igual que: 2 <= 3 es\", 2 <= 3) # sirve para comparar si un valor es menor o igual que otro.\n\n## Operadores lógicos.\n\nprint(\"AND: 2 + 2 == 4 and 3 - 1 == 2 es\", 2 + 2 == 4 and 3 - 1 == 2) # sirve para realizar una operación AND lógica.\nprint(\"OR: 2 + 2 == 4 or 3 - 1 == 2 es\", 2 + 2 == 4 or 3 - 1 == 2) # sirve para realizar una operación OR lógica.\nprint(\"NOT: not 2 + 2 == 4 es\", not 2 + 2 == 4) # sirve para realizar una operación NOT lógica.\n\n## Operadores de identidad.\n\nprint(\"Identidad: 2 is 2 es\", 2 is 2) # sirve para verificar si dos variables son el mismo objeto.\nprint(\"No identidad: 2 is not 3 es\", 2 is not 3) # sirve para verificar si dos variables no son el mismo objeto.\n\n## Operadores de membresía.\n\nprint(\"Membresía: 'a' in 'abc' es\", 'a' in 'abc') # sirve para verificar si un elemento está presente en una secuencia.\nprint(\"No membresía: 'd' not in 'abc' es\", 'd' not in 'abc') # sirve para verificar si un elemento no está presente en una secuencia.\n\n## Operadores de bits.\n\nprint(\"AND bit a bit: 2 & 3 es\", 2 & 3) # sirve para realizar una operación AND bit a bit.\nprint(\"OR bit a bit: 2 | 3 es\", 2 | 3) # sirve para realizar una operación OR bit a bit.\nprint(\"XOR bit a bit: 2 ^ 3 es\", 2 ^ 3) # sirve para realizar una operación XOR bit a bit.\nprint(\"NOT bit a bit: ~2 es\", ~2) # sirve para realizar una operación NOT bit a bit.\nprint(\"Desplazamiento a la derecha: 2 >> 1 es\", 2 >> 1) # sirve para realizar un desplazamiento a la derecha.\nprint(\"Desplazamiento a la izquierda: 2 << 1 es\", 2 << 1) # sirve para realizar un desplazamiento a la izquierda.\n\n# Estructuras de Control.\n\n## Condicionales.\n\nname = input(\"Introduce tu nombre: \")\nletter = input(\"Introduce una letra: \")\n\nif letter in name and name != \"aBoredLlama\":\n    print(f\"La letra \\'{letter}' está en el nombre {name}.\")\nelif name == \"aBoredLlama\" and letter in name:\n    print(\"¡Hola todopoderoso aBoredLlama!\")\nelse:\n    print(f\"La letra \\'{letter}' no está en el nombre {name}.\")\n\n## Iteraciones.\n\na = 0\nprint(f\"a se inicializó en {a}\")\nfor i in range(10):\n    a += 2\n    print(f\"a se incrementó a {a}\")\n\nb = 2\nc = 5\n\nwhile b < c:\n    print(f\"el resultado de la operación AND entre {b} y {c} es {b & c}\")\n    b += 1\n    c -= 1\n\n## Excepciones.\n\ntry:\n    mensaje = int(input(\"Introduce un número decimal: \"))\nexcept ValueError:\n    print(\"Ingrese un número válido. No se aceptan letras ni caracteres especiales.\")\nelse:\n    print(f\"El número ingresado es {mensaje}.\")\nfinally:\n    print(\"¡Gracias por participar!\")\n\n# Ejercicio de desafio.\n\na = 10\nb = 55\n\nfor i in range(a,b):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print(i)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/aDogdev.py",
    "content": "# 1- operadores\n\n# aritméticos\noperando_1 = 5\noperando_2 = 2\n\nprint(f\"Suma: {operando_1} + {operando_2} = {operando_1 + operando_2}\")\nprint(f\"Resta: {operando_1} - {operando_2} = {operando_1 - operando_2}\")\nprint(f\"Multiplicación: {operando_1} * {operando_2} = {operando_1 * operando_2}\")\nprint(f\"División: {operando_1} / {operando_2} = {operando_1 / operando_2}\")\nprint(f\"Módulo: {operando_1} % {operando_2} = {operando_1 % operando_2}\")\nprint(f\"Potencia: {operando_1} ** {operando_2} = {operando_1 ** operando_2}\")\nprint(f\"División entera: {operando_1} // {operando_2} = {operando_1 // operando_2}\")\n\n# lógicos\nprint(f\"AND &&: True and True es: {True and True}\")\nprint(f\"AND &&: True and False es: {True and False}\")\nprint(f\"OR ||: True or True es: {True or True}\")\nprint(f\"OR ||: True or False es: {True or False}\")\nprint(f\"NOT !: not True or False es: {not True or False}\")\n\n# comparación\nprint(f\"Igualdad: {operando_1} == {operando_2} es {operando_1 == operando_2}\")\nprint(f\"Desigualdad: {operando_1} != {operando_2} es {operando_1 != operando_2}\")\nprint(f\"Mayor que: {operando_1} > {operando_2} es {operando_1 > operando_2}\")\nprint(f\"Mayor o igual que: {operando_1} >= {operando_2} es {operando_1 >= operando_2}\")\nprint(f\"Menor que: {operando_1} < {operando_2} es {operando_1 < operando_2}\")\nprint(f\"Menor o igual que: {operando_1} <= {operando_2} es {operando_1 <= operando_2}\")\n\n# asignación\nage = 23\nprint(f\"age: {age}\")\nage += 1\nprint(f\"age += 1: {age}\")\nage -= 1\nprint(f\"age -= 1: {age}\")\nage *= 2\nprint(f\"age *= 2: {age}\")\nage /= 2\nprint(f\"age /= 2: {age}\")\nage %= 2\nprint(f\"age %= 2: {age}\")\nage **= 2\nprint(f\"age **= 2: {age}\")\nage //= 1\nprint(f\"age //= 1: {age}\")\n\n# identidad\na = 1\nb = 1\nprint(f\"a is b es: {a is b}\")\nprint(f\"a is not b es: {a is not b}\")\nb = a\nprint(f\"a is b es: {a is b}\")\nprint(f\"a is not b es: {a is not b}\")\n\n# pertenencia\nprint(f\"'o' in 'aDog': {'o' in 'aDog'}\")\nprint(f\"'i' not in 'aDog': {'o' in 'aDog'}\")\n\n# bits\na = 10\nb = 3\nprint(f\"AND: {a} & {b}: {a & b}\")\nprint(f\"OR: {a} | {b}: {a | b}\")\nprint(f\"XOR: {a} ^ {b}: {a ^ b}\")\nprint(f\"NOT: ~{a}: {~a}\")\nprint(f\"Desplazamiento a la derecha {a} >> {b}: {a >> b}\")\nprint(f\"Desplazamiento a la izquierda {a} << {b}: {a << b}\")\n\n# 2- estructuras de control\n\n# condicionales\nname = \"aDog\"\nif name == \"aDog\":\n    print(\"name es 'aDog'\")\nelif name == \"Flowey\":\n    print(\"name es 'Flowey'\")\nelse:\n    print(\"name no es 'aDog' ni 'Flowey'\")\n\n# iterativas\nfor x in range(10):\n    print(x)\n\nx = 0\ny = 0\n\nwhile y <= 10:\n    print(y)\n    y += 1\n\n# excepciones\ntry:\n    print(y / x)\nexcept:\n    print(\"Se ha producido un error\")\nfinally:\n    print(\"Ha finalizado el manejo de excepciones\")\n\n\n# dificultad extra\ndef my_function(x, y):\n    for x in range(x, y):\n        if x % 2 == 0 and x != 16 and x % 3 != 0:\n            print(x)\n\n\nmy_function(10, 55)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/abascal92.py",
    "content": "'''\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n'''\n\n# Variables\nnum1, num2 = 23, 10\n\n# Operadores aritméticos\nprint(f\"La suma de {num1} y {num2} es: {num1 + num2}\") #Operador aritmético de suma\nprint(f\"La resta de {num1} y {num2} es: {num1 - num2}\") #Operador aritmético de resta\nprint(f\"La multiplicación de {num1} y {num2} es: {num1 * num2}\") #Operador aritmético de multiplicación\nprint(f\"La división de {num1} y {num2} es: {num1 / num2}\") #Operador aritmético de división\nprint(f\"La potencia de {num1} y {num2} es: {num1 ** num2}\") #Operador aritmético de potencia\nprint(f\"El módulo de {num1} y {num2} es: {num1 % num2}\") #Operador aritmético de módulo\nprint(f\"La división entera de {num1} y {num2} es: {num1 // num2}\") #Operador aritmético de división entera\n\n# Operadores lógicos\nprint(f\"¿{num1} es mayor que {num2}?: {num1 > num2}\") #Operador lógico de mayor que\nprint(f\"¿{num1} es mayor o igual que {num2}?: {num1 >= num2}\") #Operador lógico de mayor o igual que\nprint(f\"¿{num1} es menor que {num2}?: {num1 < num2}\") #Operador lógico de menor que\nprint(f\"¿{num1} es menor o igual que {num2}?: {num1 <= num2}\") #Operador lógico de menor o igual que\nprint(f\"¿{num1} es igual a {num2}?: {num1 == num2}\") #Operador lógico de igualdad\nprint(f\"¿{num1} es diferente de {num2}?: {num1 != num2}\") #Operador lógico de diferencia\n\n# Operadores de asignación\nprint(f\"El valor de num1 es: {num1}\")\nprint(f\"{num1} += {num2} es igual a: {num1 + num2}\") #Operador de asignación de suma\nprint(f\"{num1} -= {num2} es igual a: {num1 - num2}\") #Operador de asignación de resta\nprint(f\"{num1} *= {num2} es igual a: {num1 * num2}\") #Operador de asignación de multiplicación\nprint(f\"{num1} /= {num2} es igual a: {num1 / num2}\") #Operador de asignación de división\nprint(f\"{num1} **= {num2} es igual a: {num1 ** num2}\") #Operador de asignación de potencia\nprint(f\"{num1} %= {num2} es igual a: {num1 % num2}\") #Operador de asignación de módulo\nprint(f\"{num1} //= {num2} es igual a: {num1 // num2}\") #Operador de asignación de división entera\n\n# Operadores de identidad\nprint(f\"¿{num1} es {num2}?: {num1 is num2}\") #Operador de identidad de igualdad\nprint(f\"¿{num1} no es {num2}?: {num1 is not num2}\") #Operador de identidad de diferencia\n\n# Operadores de pertenencia\nlista = [1, 2, 3, 4, 5]\nprint(f\"¿{num1} está en la lista?: {num1 in lista}\") #Operador de pertenencia de existencia\nprint(f\"¿{num1} no está en la lista?: {num1 not in lista}\") #Operador de pertenencia de inexistencia\n\n# Operadores de bits\nnum1 = 23 # 10111\nnum2 = 10 # 01010\nprint(f\"La operación AND entre {num1} y {num2} es: {num1 & num2}\") #Operador de bits AND (00010) (2)\nprint(f\"La operación OR entre {num1} y {num2} es: {num1 | num2}\") #Operador de bits OR (11111) (31)\nprint(f\"La operación XOR entre {num1} y {num2} es: {num1 ^ num2}\") #Operador de bits XOR (11101) (29)\nprint(f\"La operación NOT de {num1} es: {~num1}\") #Operador de bits NOT (11111111111111111111111111101000) (-24)\nprint(f\"La operación de corrimiento a la izquierda de {num1} es: {num1 << num2}\") #Operador de bits de desplazamiernto a la izquierda (101110000000000000000) (23552)\nprint(f\"La operación de corrimiento a la derecha de {num1} es: {num1 >> num2}\") #Operador de bits de desplazamiernto a la derecha (0) (0)\n\n# Estruturas de control\nif num1 > num2:\n    print(f\"{num1} es mayor que {num2}\")\nelif num1 == num2:\n    print(f\"{num1} es igual a {num2}\")\nelse:\n    print(f\"{num1} es menor que {num2}\")\n\nfor i in lista:\n    print(i)\n\nwhile num1 > num2:\n    print(f\"{num1} es mayor que {num2}\")\n    num1 -= 1\n\ntry:\n    print(lista[10])\nexcept Exception as e:\n    print(f\"Error: {e}\")\nelse:  \n    print(\"No hay errores\")\nfinally:\n    print(\"Fin del try\")\n\n# DIFICULATAD EXTRA\nfor i in range(10,55):\n    if i % 2 == 0 and (i != 16 and i % 3 != 0):\n        print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/adolfolozaa.py",
    "content": "\"\"\"\r\nEJERCICIO:\r\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\r\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\r\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\r\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\r\n *   que representen todos los tipos de estructuras de control que existan\r\n *   en tu lenguaje:\r\n *   Condicionales, iterativas, excepciones...\r\n * - Debes hacer print por consola del resultado de todos los ejemplos.\r\n\"\"\"\r\n\r\n\"\"\"\r\nOperadores\r\n\"\"\"\r\n\r\nprint(f\"Suma: 10 + 3 = {10 + 3}\")\r\nprint(f\"resta: 10 + 3 = {10 - 3}\")\r\nprint(f\"Multiplicacion: 10 + 3 = {10 * .3}\")\r\nprint(f\"Modulo : 10 % 3 = {10 % 3}\")\r\nprint(f\"Exponente: 10 ** 3 = {10 ** 3}\")\r\nprint(f\"Division entera: 10 // 3 = {10 // 3}\")\r\n\r\n\r\n#  Operadores de comparacion\r\n\r\nprint(f\"Iguldad: 10 == 3 es {10 ==3}\")\r\nprint(f\"desiguldad: 10 != 3 es {10 !=3}\")\r\nprint(f\"Mayor que: 10 > 3 es {10 >3}\")\r\nprint(f\"Menor que: 10 < 3 es {10 <3}\")\r\nprint(f\"Mayor o igual que: 10 >= 3 es {10 >=3}\")\r\nprint(f\"Menor o igual que: 10 <= 3 es {10 <=3}\")\r\n\r\n#  Operadores Logicos\r\n\r\nprint(f\"AND &&: 10 + 3 == 13 and 5 - 1 == 4 es {10 + 3 == 13 and 5 - 1 == 4}\")\r\nprint(f\"OR ||: 10 + 3 == 14 or 5 - 1 == 4 es {10 + 4 == 13 or 5 - 1 == 4}\")\r\nprint(f\"NOT !: not 10 + 3 == 14  es {not 10 + 3 == 14 }\")\r\n\r\n# Operadores de Asignacion\r\nmy_number = 11   # asignacion\r\nprint(my_number)\r\n\r\nmy_number += 1   # suma y asignacion\r\nprint(my_number)\r\n\r\nmy_number -= 1  # resta y asignacion\r\nprint(my_number)\r\n\r\nmy_number *= 2  # Multiplicacion  y asignacion\r\nprint(my_number)\r\nmy_number /= 2  # division y asignacion\r\nprint(my_number)\r\n\r\nmy_number %= 2  # Modulo y asignacion\r\nprint(my_number)\r\n\r\nmy_number **= 1  # exponencial y asignacion\r\nprint(my_number)\r\n\r\nmy_number //= 1  # division entera y asignacion\r\nprint(my_number)\r\n\r\n\r\n# Operadores de Identidad : compara los valores en memoria\r\nmy_new_number = 1.0\r\nprint(f\"my_number is my_new_number es {my_number is my_new_number}\")\r\nprint(f\"my_number is not my_new_number es {my_number is not my_new_number}\")\r\n# Operadores de Pertenencia\r\nprint(f\"'o' in 'Adolfo = {'o' in 'Adolfo'}\")\r\nprint(f\"'c' not in 'Adolfo = {'c' not in 'Adolfo'}\")\r\n\r\n#  Operadores de bit\r\n\r\na = 10   # 1010\r\nb = 3   # 0011\r\n\r\nprint(f\"AND: 10 & 3 = {10 & 3}\")  #compara bit a bit i si son iguales es 1\r\nprint(f\"OR: 10 | 3 = {10 | 3}\") #compara bit a bit y si alguno es 1 es 1\r\nprint(f\"XOR: 10 ^ 3 = {10 ^ 3}\") #compara bit a bit y si son diferentes es 1\r\nprint(f\"NOT: ~10 = {~10}\") #niega cada uno de los bits\r\n\r\nprint(f\"Desplazamiento a la derecha: 10 >> 2 es {10 >> 2}\")\r\nprint(f\"Desplazamiento a la izquierda: 10 << 2 es {10 << 2}\")\r\n\r\n\"\"\" \r\nEstructuras de Control\r\n\"\"\"\r\n# Condicionales\r\nmy_string = \"Loza1\"\r\nif my_string == \"Adolfo\":\r\n    print(\"my_string es 'Adolfo\")\r\nelif my_string == \"Loza\":\r\n    print(\"my_string es 'Loza'\")\r\nelse: \r\n    print(\"my_string no es 'Adolfo'\")\r\n\r\n# Iterativas\r\nfor i in range(11):\r\n    print(i)\r\n\r\ni=0\r\nwhile i<=10:\r\n    print(i)\r\n    i+=1\r\n\r\n# Manejo de excepciones\r\ntry:\r\n    print(10/0)\r\nexcept:\r\n    print(\"Se ha producido un error\")\r\nfinally:\r\n    print(\"Ha finalizado el manejo de excepciones\")\r\n\r\n\"\"\"\r\nDIFICULTAD EXTRA (opcional):\r\n * Crea un programa que imprima por consola todos los números comprendidos\r\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\r\n \r\n\"\"\"\r\nfor number in range(10,56):\r\n    if number % 2 == 0 and number != 16 and number % 3 != 0:\r\n        print(number)\r\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/adra-dev.py",
    "content": "\"\"\"\nEJERCICIO:\n- Crea ejemplos utilizando todos los tipos de operadores de tu \nlenguaje: Aritméticos, lógicos, de comparación, asignación, identidad,\npertenencia, bits...\n(Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n- Utilizando las operaciones con operadores que tú quieras, crea ejemplos\nque representen todos los tipos de estructuras de control que existan\nen tu lenguaje: Condicionales, iterativas, excepciones...\n- Debes hacer print por consola del resultado de todos los ejemplos.\n\n- DIFICULTAD EXTRA (opcional):\nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\nSeguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\nby adra-dev.\n\"\"\"\n\n\"\"\"\nOperadores: Los operadores son simbolos que indican la operacion que \nse va a llevar a cabo.\n\"\"\"\n\n\"\"\"\nOperadores de asignacion: Son aquellos que permiten dar un valor a \nuna variable o modificarlo.\n\"\"\"\n\nresultado = 6 # Asignacion simple\nprint(resultado)\nresultado += 2 # Asignacion de suma\nprint(resultado)\nresultado -= 4 # Asignacion de resta\nprint(resultado)\nresultado *= 5 # Asignacion de multiplicacion\nprint(resultado)\nresultado /= 2 # Asignacion de division\nprint(resultado)\nresultado %= 4 # Asignacion de modulo\nprint(resultado)\nresultado **= 3 # Asignacion exponencial\nprint(resultado)\nresultado //= 5 # Aasignacion de division entera\nprint(resultado)\n\n\"\"\"\nOperadores aritmeticos: Son aquellos que permiten realizar operaciones \naritmeticas.\n\"\"\"\n\na = 10\nb = 8\n\na + b # Suma\nprint(a+b)\na - b # Resta\nprint(a-b)\na * b # Multiplicacion\nprint(a*b)\na ** b # Potencia\nprint(a**b)\na / b # Cociente de la division\nprint(a/b)\na // b # Cociente de la division entera\nprint(a//b)\na % b # Resto de la division entera\nprint(a%b)\n\n\"\"\"\nOperadores relacionales o de comparacion: Son simbolos que se utilizan\npara comparar dos valores o expresiones.\n\"\"\"\n\na == b # Igual a \nprint(a==b)\na != b # Distinto de \nprint(a!=b)\na > b # Mayor que\nprint(a>b)\na < b # Menor que\nprint(a<b)\na >= b # Mayor o igual que\nprint(a>=b)\na <= b # Menor o igual que\nprint(a<=b)\n\n\"\"\"\nOperadores logicos o booleanos: Son aquellos que permiten conectar\ndos expresiones de comparcion y evaluarlas de forma logica, excepto\nel operador not que invierte el valor logico de la expresion sobre \nla que se aplica.\n\"\"\"\n\na = (3 > 2)\nb = (5 >= 6)\nc = (3 != (2+1))\nd = (4 == (2*3))\n\n# and\nprint(a and b)\nprint(a and c)\nprint(c and a)\nprint(c and d)\n\n# or\nprint(a or b)\nprint(a or c)\nprint(c or a)\nprint(c or d)\n\n# not\nprint(not a)\nprint(not b)\nprint(not c)\nprint(not d)\n\n\"\"\"\nOperadores a nivel de bit: Se utilizan para comparar numeros enteros\nen su representacion binaria, es decir operan sobre cada uno de los \nbits del entero sobre el que se aplican, y devuelven el numero entero\ncorrespondiente al resultado binario.\n\"\"\"\n\na = 5\nb = 4\n\n# & and binario\nprint(a & b)\n\n# | or binario\nprint(a | b)\n\n# ^ or exclusivo binario\nprint(a ^ b)\n\n# ~ not binario\nprint(~a)\nprint(~b)\n\n# << desplazamiento a la izquierda\nprint(a << 2)\n\n# >> desplazamiento a la derecha\nprint(a >> 2)\n\n# podmeos mostrar la representacion binaria de un entero con la funcion bin()\n\nprint(bin(5))\n\nprint(bin(3))\n\nprint(bin(5&3))\nprint(bin(5|3))\nprint(bin(5>>2))\nprint(bin(5<<2))\n\n\"\"\"\nOperadores de pertenencia: Se utilizan para comparar si un dato forma\nparte o no de una coleccion.\n\"\"\"\n\na = 4\nb = [1, 2, 3, 4, 5, 6]\nc = 2\nd = ('caramelos', 2)\ne = 'b'\nf = 'casa'\n\nprint(a in b)\n\nprint(c in d)\n\nprint(e in f)\n\nprint(a not in b)\n\nprint(c not in d)\n\nprint(e not in f)\n\n\"\"\"\nOperadores de identidad: Evaluan si las referencias de dos variables\napuntan al mismo objeto.\n\"\"\"\n\na = [1, 2, 3, 4, 5, 6]\n\nb = [1, 2, 3, 4, 5, 6]\n\nprint(a is b)\n\na = [1, 2 , 3]\n\nb = a\n\nprint(b is a)\n\n\"\"\"\nEstructuras de control: Permiten ejecutar mas de una vez una instruccion\no un bloque de instrucciones.\n\"\"\"\n\n\"\"\"\nCondicones: permiten elegir entre distintos resultados segun el valor\nde una expresion.\n\"\"\"\n\n# if\nedad = 16\n\nif edad >= 18:\n    acceso = 'Puede entrar al pub'\nelse:\n    acceso = 'No puede entrar al pub'\nprint(acceso)\n\n# switch \npeso = 100\ndef colocar_huevo(caja):\n    \n    if peso < 53:\n        caja = \"S\"\n    elif peso < 63:\n        caja = \"M\"\n    elif peso < 73:\n        caja = \"L\"\n    else:\n        caja = \"XL\"\n    return caja\n\nprint(colocar_huevo(peso))\n\n\n\n# match o switch (version de python 3.12 en adelante):\n\ndef http_error(status):\n    \"\"\"\n    Una instrucción match toma una expresión y compara su valor con \n    patrones sucesivos dados como uno o más bloques de casos.\n    \"\"\"\n    match status:\n        case 400:\n            return \"Bad request\"\n        case 404:\n            return \"Not found\"\n        case 418:\n            return \"I'm a teapot\"\n        case _:\n            return \"Something's wrong with the internet\"\n        \nprint(http_error(418))\n\n\n\"\"\"\nBucles for y while: permiten repetir un bloque de instrucciones hasta\nque una condicion se cumpla.\n\"\"\"\n\n# while repite instrucciones mientras se cumpla la condicion.\n\n# calculo de !4\na = 4\nacc =1\nwhile a > 1:\n    acc *= a\n    a -= 1\nprint(acc)\n\n# for se utiliza cuando conocemos el numero de repeticiones.\n\nfor e in [1, 2, 3]:\n    print(e**2)\n\n\"\"\"\nExcepciones: Una excepcion es un error logico que se produce en \ntiempo de ejecucion. \n\nLas excepciones van asociadas a distintos tipos,\ny ese mismo tipo es el que se muestra en el mensaje de error.\n\"\"\"\n\ntry:\n    \n    print(resultado =  15 * (3/0))   \nexcept IOError:\n    # Instrucciones si ocurre la excepcion IOError\n    print(\"Error de entrada/salida.\")\nexcept ZeroDivisionError:\n    # Instrucciones si ocurre la excepcion ZeroDivisionError\n    print(\"Error de division por cero.\")\nelse:\n    # Instrucciones si no ocurre ninguna excepcion\n    print(\"El resultado de la division es\", resultado)\nfinally:\n    # Instrucciones si ocurren o no ocurren excepciones\n        print(\"Archivo resultado.txt cerrado.\")\n\n\n# Extra\n\nfor n in range(9, 56):\n    if n == 16:\n        pass\n    elif not(n % 3 == 0) and (n % 2 == 0):\n            print(n)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/adridlth.py",
    "content": "# EJERCICIO:\n\n# - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje: Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits... (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\nx = 5\ny = 3\nz = (8, 9)\nprint(x, y)\n\n# Arithmetic operators\naddition = x + y\nsubtraction = x - y\nmultiplication = x * y\ndivision = x / y\nmodulus = x % y\nexponentiation = x ** y\nfloorDivision = x // y\nprint('ARITHMETIC OPERATORS')\nprint('addition = ', {addition})\nprint('subtraction = ', {subtraction})\nprint('multiplication = ', {multiplication})\nprint('division = ', {division})\nprint('modulus = ', {modulus})\nprint('exponentiation = ', {exponentiation})\nprint('floorDivision = ', {floorDivision})\nprint()\n\n# -----------------------------------------------------------------------------------------\n# -----------------------------------------------------------------------------------------\n\n# Assignment operators\nprint('ASSIGNMENT OPERATORS')\nprint('x =', x)\nprint('x +=', x)\nprint('x -=', x)\nprint('x *=', x)\nprint('x /=', x)\nprint('x %=', x)\nprint('x //', x)\nprint('x **', x)\nprint('x &=', x)\nprint('x |=', x)\nprint('x ^=', x)\nprint('x >>=', x)\nprint('x <<=', x)\nprint('x :=', x)\nprint()\n\n# -----------------------------------------------------------------------------------------\n# -----------------------------------------------------------------------------------------\n\n# Comparison operators\nprint('COMPARISON OPERATORS')\nprint('equal:\tx == y = ',x == y)\nprint('not equal:\tx != y = ',x != y)\nprint('greater than:\tx > y = ',x > y)\nprint('less than:\tx < y = ',x < y)\nprint('greater than or equal:\tx >= y = ',x >= y)\nprint('less than or equal:\tx <= y = ',x <= y)\nprint()\n\n# -----------------------------------------------------------------------------------------\n# -----------------------------------------------------------------------------------------\n\n# Logical operators\nprint('LOGICAL OPERATORS')\nprint('and: x < 3 and y > 5 = ',x < 3 and y > 5)\nprint('or: x < 3 or y > 5 = ',x < 3 or y > 5)\nprint('not: x < 3 not y > 5 = ',not(x < 3 and y > 5))\nprint()\n\n# -----------------------------------------------------------------------------------------\n# -----------------------------------------------------------------------------------------\n\n# Identity operators\nprint('IDENTITY OPERATORS')\nprint('is: x is y = ',x is y)\nprint('is not: x is not y = ',x is not y)\nprint()\n\n# -----------------------------------------------------------------------------------------\n# -----------------------------------------------------------------------------------------\n\n# Membership operators\nprint('MEMBERSHIP OPERATORS')\nprint('in: x in y = ',8 in z)\nprint('not in: x not in y = ',7 not in z)\nprint()\n\n# -----------------------------------------------------------------------------------------\n# -----------------------------------------------------------------------------------------\n\n# Bitwise operators\nprint('BITWISE OPERATORS')\nprint('AND: x & y =', x & y)\nprint('OR: x | y =', x | y)\nprint('XOR: x ^ y =', x ^ y)\nprint('NOT: ~y =', ~y)\nprint('<<: x << 2 =', x << 2)\nprint('>>: x >> 2 =', x >> 2)\nprint()\n\n# -----------------------------------------------------------------------------------------\n# -----------------------------------------------------------------------------------------\n\n\n\n\n# - Utilizando las operaciones con operadores que tú quieras, crea ejemplos que representen todos los tipos de estructuras de control que existan en tu lenguaje: Condicionales, iterativas, excepciones...\nprint('IF-ELIF-ELSE')\nif x >=5:\n\tprint('Good job!')\nelif x > 0:\n\tprint('Try again')\nelse:\n\tprint('Repeat the lesson')\nprint()\n\nprint('FOR LOOP')\nworker1 = 'Ben'\nworker2 = 'John'\nworker3 = 'Suzy'\nworker4 = 'Vanessa'\nteam = [worker1, worker2, worker3, worker4]\nfor worker in team:\n\tprint(worker)\nprint()\n\nprint('WHILE LOOP')\nx = 1\nwhile x < 5:\n    print(x)\n    x += 1\nprint()\n\n\n# - Debes hacer print por consola del resultado de todos los ejemplos.\n\n\n# DIFICULTAD EXTRA (opcional): Crea un programa que imprima por consola todos los números comprendidos entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\nnumero = 10\nwhile numero <= 55:\n    if numero == 16:\n        pass\n    elif numero % 3 == 0:\n        pass\n    elif numero % 2 == 0:\n        print(numero)\n    else:\n        pass\n  \n    numero += 1\n\n# Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/aegpgrafologo.py",
    "content": "\"\"\"\nOperadores\n\"\"\"\n\"\"\"Operadores matemáticos\nOperador de adición con interpolación \nsustituyendo el nombre de una variable por sus valores \ncuando se construye un «String»\"\"\"\n#Operador de adición\nprint(f\"Operación 250 + 895 = {250+895}\")\n#Operador de sustracción\nprint(f\"Operación 895 - 250 = {895-250}\")\n#Operador de multiplicación\nprint(f\"Operación 250 * 895 = {250*895}\")\n#Operador de división\nprint(f\"Operación 895 / 250 = {895/250}\")\n#Operador de módulo\nprint(f\"Operación 4 % 3 = {4%3}\")\n#Operador exponencial\nprint(f\"Operación 3 ** 3 = {3**3}\")\n#Operador disión exacta\nprint(f\"Operación 895 // 250 = {895//250}\")\n\n#Operadores de comparación (Sirven para comparar valores)\n#Operador igualdad - no solo con números, tambien variables, string e.t.c\nprint(f\"Igualdad: 895 == 895 es: {895==895}\")\n#Operador desigualdad\nprint(f\"Desigualdad: 895 != 250 es: {895!=250}\")\n#Operadores mayor que, menor que, mayor o igual que o menor o igual que\nprint(f\"Mayor que: 895 > 250 es: {895>250}\")\nprint(f\"Menor que: 895 < 250 es: {895<250}\")\nprint(f\"Mayor o igual que: 895 >= 250 es: {895>=250}\")\nprint(f\"Menor o igual que: 895 <= 250 es: {895<=250}\")\n\n# Operadores logicos\n#Operador AND\nprint(f\"AND &&: 895 + 250 == 687 and 6-8 == 2 es: {895 + 250 == 687 and 6 - 8 == 2}\")\n#Operador OR - Que por lo menos una de las concidiones sea verdadera\nprint(f\"OR ||: 895 + 250 == 687 or 6-4 == 2 es: {895 + 250 == 687 or 6 - 4 == 2}\")\n#Operador NOT\nprint(f\"NOT !: not 895 + 250 == 687 es: {not 895 + 250 == 687}\")\n\n# Operadores de asignación\nvariable_prueba = 12 # En este caso se hace asignación con el operador igual\nprint(variable_prueba)\nvariable_prueba += 2 # Suma y asignación\nprint(variable_prueba)\nvariable_prueba -= 2 # resta y asignación\nprint(variable_prueba)\nvariable_prueba *= 2 # multipliación y asignación\nprint(variable_prueba)\nvariable_prueba /= 2 # división y asignación\nprint(variable_prueba)\nvariable_prueba %= 2 # módulo y asignación\nprint(variable_prueba)\nvariable_prueba **= 2 # exponente y asignación\nprint(variable_prueba)\nvariable_prueba //= 2 # división exacta y asignación\nprint(variable_prueba)\n\n#Operadores de identidad - Comparar el valor de la posición en memoria\nnueva_variable_prueba = variable_prueba\nprint(f\"variable_prueba is nueva_variable_prueba es: {variable_prueba is nueva_variable_prueba}\")\nprint(f\"variable_prueba is not nueva_variable_prueba es: {variable_prueba is not nueva_variable_prueba}\")\n\n# Operadores de pertenencia - Verifica si algo esta dentro de un conjunto.\nprint(f\"'A' in 'Anyelo' = {'A' in 'Anyelo'}\")\nprint(f\"'a' not in 'Anyelo' = {'a' not in 'Anyelo'}\")\n\n# Operadores de bit - Operaciones con bits\nPrimera = 10\nSegunda = 3\n# Operador AND - Transforma a binario y opera\nprint (f\"AND: 10 & 3 = {10 & 3}\")\n# Operador OR - Transforma a binario y opera, SI AL MENOS UNO DE LOS DOS BIT ES UNO EL RESULTADO ES UNO\nprint (f\"OR: 10 | 3 = {10 | 3}\")\n# Operador XOR - Transforma a binario y opera, SI los bit son diferentes el resultado es UNO Y SI SON IGUALES ES CERO\nprint (f\"XOR: 10 ^ 3 = {10 ^ 3}\")\n# Operador NOT - INTERCAMBIA EL VALOR BIT A BIT DE CUALQUIERA DE LOS ELEMENTOS\nprint (f\"NOT: ~10 = {~10}\")\n# Operador Desplazamiento a la derecha\nprint (f\"Desplazamiento a la derecha: 10 >> 2 = {10 >> 2}\")\n# Operador Desplazamiento a la izquierda\nprint (f\"Desplazamiento a la izquierda: 10 << 2 = {10 << 2}\")\n\n\"\"\"\nEstructuras de control - indica al código que camino debe seguir\n\"\"\"\n#Condicionales\nmi_nombre = \"Esneider\"\nif mi_nombre == \"Anyelo\":\n    print(\"mi_nombre es 'Anyelo'\")\nelif mi_nombre == \"Esneider\":\n    print(\"mi_nombre es 'Esneider'\")\nelse:\n    print(\"mi_nombre no es 'Anyelo' ni 'Esneider'\")\n\n#Iterativas\n#For - crea bucles - recorrer estructura con más de un elemento o para ejecutar una acción varias veces\nfor x in range (5):\n    print(x) \n#While - el bucle se ejecuta mientras la condición sea verdadera\nx = 0\nwhile x <= 10:\n    print(x)\n    x += 1 \n\n#Manejo de excepciones\ntry:\n    print (10 / 0)\nexcept:\n    print (\"Se ha detectado un error\")\nfinally:\n    print (\"Ha terminado el manejo de excepciones\")\n\n\"\"\"\nPrograma impresos por consola de numeros entre el 10 y 55,\npares y que no son ni el 16 ni multiplos de 3.\n\"\"\"\nfor numeros in range(10, 56):\n    if numeros % 2 == 0 and numeros != 16 and numeros % 3 !=0:\n        print(numeros)\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/agusrosero.py",
    "content": "# Operadores aritmeticos\nsuma = 5 + 5\nresta = 5 - 5\nmultiplicacion = 5 * 5\ndivision = 5 / 5\nmodulo = 5 % 5\nexponente = 5 ** 5\nprint(suma, resta, multiplicacion, division, modulo, exponente)\n\n# Operadores de asignacion\nx = 5\nprint(x)\nx += 5\nprint(x)\nx -= 5\nprint(x)\nx *= 5\nprint(x)\nx /= 5\nprint(x)\nx %= 5\nprint(x)\nx **= 5\nprint(x)\nx //= 5\nprint(x)\n\n# Operadores de comparacion\nprint(5 == 5)\nprint(5 != 5)\nprint(5 > 5)\nprint(5 < 5)\nprint(5 >= 5)\nprint(5 <= 5)\n\n# Operadores logicos\nprint(True and True)\nprint(True and False)\nprint(True or True)\nprint(True or False)\nprint(not True)\nprint(not False)\n\n# Operadores de identidad\nprint(5 is 5)\nprint(5 is not 5)\n\n# Estructuras de control\nif 5 == 5:\n    print(\"5 es igual a 5\")\nelse:\n    print(\"5 no es igual a 5\")\n    \nwhile 5 == 5:\n    print(\"5 es igual a 5\")\n    break\n\nfor i in range(5):\n    print(i)\n    \ntry:\n    print(5 / 0)\nexcept ZeroDivisionError:\n    print(\"No se puede dividir entre 0\")\n    "
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/ainaragmt.py",
    "content": "# Operadores aritméticos\nprint(\"\\nOperadores aritméticos\")\nprint(f\"Suma: 2 + 3 = {2 + 3}\")\nprint(f\"Resta: 2 - 3 = {2 - 3}\")\nprint(f\"Multiplicación: 2 * 3 = {2 * 3}\")\nprint(f\"División: 2 / 3 = {2 / 3}\")\nprint(f\"Módulo: 2 % 3 = {2 % 3}\") # Resto de la división\nprint(f\"Exponente: 2 ** 3 = {2 ** 3}\")\nprint(f\"División entera: 2 // 3 = {2 // 3}\") # División truncada\n\n# Operadores lógicos\nprint(\"\\nOperadores lógicos\")\nprint(f\"AND: 2 + 3 == 4 & 2 + 3 == 5 es {2 + 3 == 4 & 2 + 3 == 5}\") # & o and\nprint(f\"OR: 2 + 3 == 4 | 2 + 3 == 5 es {2 + 3 == 4 | 2 + 3 == 5}\") # | o or\nprint(f\"NOT: 2 + 3 == 4 es {not 2 + 3 == 4}\")\n\n# Operadores de comparación\nprint(\"\\nOperadores de comparación\")\nprint(f\"Igualdad: 2 == 3 es {2 == 3}\")\nprint(f\"Desigualdad: 2 != 3 es {2 != 3}\")\nprint(f\"Mayor que: 2 > 3 es {2 > 3}\")\nprint(f\"Menor que: 2 < 3 es {2 < 3}\")\nprint(f\"Mayor igual que: 2 >= 3 es {2 >= 3}\")\nprint(f\"Menor igual que: 2 <= 3 es {2 <= 3}\")\n\n# Operadores de asignación\nprint(\"\\nOperadores de asignación\")\nmy_int = 17 # asignación\nprint(my_int)\nmy_int += 1 # suma y asignación\nprint(my_int)\nmy_int -= 1 # resta y asignación\nprint(my_int)\nmy_int *= 2 # multiplicación y asignación\nprint(my_int)\nmy_int /= 2 # división y asignación\nprint(my_int)\nmy_int %= 2 # módulo y asignación\nprint(my_int)\nmy_int **= 1 # exponente y asignación\nprint(my_int)\nmy_int //= 1 # división entera y asignación\nprint(my_int)\n\n# Operadores de identidad (comparan la posición de memoria)\nprint(\"\\nOperadores de identidad\")\nmy_new_int = 1.0\nprint(f\"my_int es my_new_int? {my_int is my_new_int}\")\nmy_int = my_new_int\nprint(f\"my_int es my_new_int? {my_int is my_new_int}\")\n\n# Operadores de pertenecia\nprint(\"\\nOperadores de pertenencia\")\nprint(f\"'a' está en 'ainara'? {'a' in 'ainara'}\")\nprint(f\"'a' está en 'ainara'? {'a' not in 'ainara'}\")\n\n# Operadores de bits\nprint(\"\\nOperadores de bits\")\na = 10 # 1010\nb = 3 # 0011\nprint(f\"AND: 10 & 3 = {a & b}\")\nprint(f\"OR: 10 | 3 = {a | b}\")\nprint(f\"XOR: 10 ^ 3 = {a ^ b}\")\nprint(f\"NOT: ~ 10 = {~ a}\")\nprint(f\"Shift right: 10 >> 1 = {10 >> 1}\")\nprint(f\"Shift left: 10 << 1 = {10 << 1}\")\n\n# Estructuras condicionales\nprint(\"\\nEstructuras condicionales\")\na = 10\nb = 3\nif (a == b):\n    print(\"a == b\")\nelif (a == 10):\n    print(\"a == 10\")\nelse:\n    print(\"a != b\")\n\n# Estructuras iterativas\nprint(\"\\nEstructuras iterativas\")\nfor i in range (5):\n    print(\"i: \", i) # hace el i++ por defecto\n\nj = 5\nwhile j > 2:\n    j -= 1\n    print(\"j: \", j)\n\n# Excepciones\nprint(\"\\nExcepciones\")\ntry:\n    print(3 / 1)\n    print(5 / 0)\n    print(2 / 1) # no se llega a ejecutar porque salta la excepción\nexcept:\n    print(\"No se puede dividir entre 0\")\nfinally:\n    print(\"Ha finalizado el manejo de excepciones\") # se ejecuta tanto si se produce algún error como si no\n\n'''\nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n'''\nprint(\"\\nEjercicio de dificultad extra\")\na = 10\nwhile a <= 55:\n    if (a != 16 and (a % 3) != 0):\n        if (a % 2) == 0:\n            print(a)\n    a+=1"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/alabacw74.py",
    "content": "'''\n# 01 OPERADORES Y ESTRUCTURAS DE CONTROL\nDificultad: Fácil | Publicación: 02/01/24 | Corrección: 08/01/24\nAuthor: Alfredo Aburto Alcudia https://github.com/alabacw74\nPropuesto por: Brais Moure https://github.com/mouredev\n## Ejercicio\n\n\nEJERCICIO:\n- Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n    Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia,\n    bits...\n    (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n- Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n    que representen todos los tipos de estructuras de control que existan\n    en tu lenguaje:\n    Condicionales, iterativas, excepciones...\n\n- Debes hacer print por consola del resultado de todos los ejemplos.\n \nDIFICULTAD EXTRA (opcional):\nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n \nSeguro que al revisar detenidamente las posibilidades has descubierto algo \nnuevo.\n\n'''\n\n# Tipos de operadores\n\n# Asignacion\na = 29\nprint(a)\n\n# Añadir el valor de la derecha al valor actual de la variable\na += 1\nprint(a)\n\n# Restar el valor de la derecha al valor actual de la variable\na -= 26\nprint(a)\n\n# Dividir el valor actual de la variable por el valor de la derecha\na /= 2\nprint(a)\n\n# Calcular el modulo del valor actual de la variable por el valor de la derecha\na %= 0.45\nprint(a)\n\n# Calcula division entera del valor actual de la variable por el valor de la\n# derecha\nb = 26\nb //= 11\nprint(b)\n\n# Elevar el valor actual de la variable a la potencia del valor de la derecha\nb **= 3\nprint(b)\n\n# Aritmeticos\nprint(f'5 + 3 = {5 + 3}') # Suma\nprint(f'5 - 3 = {5 - 3}') # Resta\nprint(f'5 * 3 = {5 * 3}') # Multiplicación\nprint(f'5 / 5 = {5 / 5}') # Division (siempre retorna un float)\nprint(f'5 % 3 = {5 % 3}') # Modulo\nprint(f'5 // 3 = {5 // 3}') # Division entera\nprint(f'5 ** 3 = {5 ** 3}') # Exponente\n\n# Logicos y relacionales\nprint(\"Logicos y relacionales\")\na = True\nb = False\n\nprint(f'a = {a} y b = {b}')\n\nprint(\"a and b\")\nprint(a and b)\nprint(\"a or b\")\nprint(a or b)\nprint(\"not a\")\nprint(not a)\n\nprint(\"--------------------------\")\nx = 5\ny = 1\nz = 5.01\nprint(f'x = {x}, y = {y}, z = {z}')\n\nprint(f'x > y = {x > y}')\nprint(f'x < y = {x < y}')\nprint(f'x >= z = {x >= z}')\nprint(f'x <= z = {x <= z}')\nprint(f'x == z = {x == z}')\nprint(f'x != z = {x != z}')\n\n# De pertenencia\nprint('De pertenencia')\nlista = [1, 2, 3, 4, 5]\nprint(lista)\nresultado_in = 3 in lista\nprint(f'resultado_in = 3 in lista --> {resultado_in}')\n\n# De identidad\nprint(\"De identidad\")\nx = 5\ny = 5\nresultado_is = x is y\n\nprint(f'x = {x}, y = {y}')\nprint(f'x is y --> {resultado_is}')\n\n# De bits\nprint(\"De bits\")\n'''\nLos operadores de bits en Python trabajan a nivel de bits en números enteros. \nEstos operadores realizan operaciones en los bits individuales de los números,\n lo que puede ser útil en situaciones donde se necesita manipular datos a un \n nivel más bajo.\n'''\n\na = 5\nb = 3\n\nresultado_and_bits = a & b\nresultado_or_bits = a | b\nresultado_xor_bits = a ^ b\nresultado_complemento = ~a\nresultado_desplazamiento_izquierda = a << 1\nresultado_desplazamiento_derecha = a >> 1\n\nprint(\"Operador AND a nivel de bits:\", resultado_and_bits)\nprint(\"Operador OR a nivel de bits:\", resultado_or_bits)\nprint(\"Operador XOR a nivel de bits:\", resultado_xor_bits)\nprint(\"Complemento a uno:\", resultado_complemento)\nprint(\"Desplazamiento a la izquierda:\", resultado_desplazamiento_izquierda)\nprint(\"Desplazamiento a la derecha:\", resultado_desplazamiento_derecha)\nprint(\"---------------------------------------------\")\n# Estructuras de control\nprint(\"Estructuras de control\")\n\nprint(\"if-else\")\nprint('''x = 10\nif x > 5:\n    print(\"x es mayor que 5\")\nelse:\n    print(\"x no es mayor que 5\")''')\n\nx = 10\nif x > 5:\n    print(\"x es mayor que 5\")\nelse:\n    print(\"x no es mayor que 5\")\nprint('-------------------')\nprint(\"for\")\nprint('''\nfor i in range(5):\n    print(i)\n\n      ''')\nfor i in range(5):\n    print(i)\nprint('-------------------')\nprint(\"while\")\nprint('''\n    y = 0\nwhile y < 5:\n    print(y)\n    y += 1\n'''\n)\n\ny = 0\nwhile y < 5:\n    print(y)\n    y += 1\n\nprint('-------------------')\nprint(\"break\")\nprint('''\nfor i in range(10):\n    if i == 5:\n        break\n    print(i)\n''')\n\nfor i in range(10):\n    if i == 5:\n        break\n    print(i)\n\nprint('-------------------')\nprint(\"continue\")\nprint('''\nfor i in range(5):\n    if i == 2:\n        continue\n    print(i)\n''')\nfor i in range(5):\n    if i == 2:\n        continue\n    print(i)\n\nprint('-------------------')\nprint(\"try-except\")\n\nprint('''\nLa estructura try-except en Python se utiliza para manejar excepciones o errores\ndurante la ejecución del código. Consiste en un bloque try que contiene\nel código propenso a generar una excepción, y uno o más bloques except \nque manejan específicamente esas excepciones.\n''')\nprint('''\ntry:\n    resultado = 10 / 0\n    print(resultado)\nexcept ZeroDivisionError:\n    print(\"¡División por cero!\")\n''')\ntry:\n    resultado = 10 / 0\n    print(resultado)\nexcept ZeroDivisionError:\n    print(\"¡División por cero!\")\n\nprint('-------------------')\nprint(\"width\")\n\nprint('''\nLa estructura with se utiliza para trabajar con objetos que requieren una \nconfiguración y limpieza específica, como archivos, sockets, conexiones \na bases de datos, entre otros. Proporciona un manejo más limpio de los\nrecursos, ya que garantiza que los recursos se liberen adecuadamente \ndespués de su uso, incluso si ocurren excepciones.\n''')\nprint('''\nwith open('archivo.txt', 'r') as file:\n    contenido = file.read()\n    print(contenido)\n# En este punto, el archivo se cierra automáticamente, incluso si ocurren excepciones\n\n''')\nprint('-------------------')\nprint(\"DIFICULTAD EXTRA\")\n'''\nDIFICULTAD EXTRA (opcional):\nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n'''\n\nprint('''\nfor i in range(10,56):\n    if i % 2 == 0:\n        if i == 16 or i % 3 == 0:\n            continue\n        else:\n            print(i)\n''')\n\nfor i in range(10,56):\n    if i % 2 == 0:\n        if i == 16 or i % 3 == 0:\n            continue\n        else:\n            print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/alanshakir.py",
    "content": "#operadores aritmeticos\nprint(\"suma\", 5 + 3)\nprint(\"resta\", 5 - 3)\nprint(\"multiplicacion\", 5 * 3)\nprint(\"division\", 5 / 3)\nprint(\"division exacta\", 5 // 3)\nprint(\"modulo\", 5 % 3)\nprint(\"exponente\", 5 ** 3)\n\n#operadores logicos\nprint(\"operador AND:\", 8 + 5 == 13 and 9 + 4 == 13)\nprint(\"operador OR:\", 8 + 5 == 13 or 9 + 4 == 13)\nprint(\"operador NOT:\", not 8 + 5 == 14)\n\n#operadores de comparacion\nprint(\"igualdad: \", 15 == 5)\nprint(\"distinto: \", 15 != 5)\nprint(\"mayor que: \", 15  > 5)\nprint(\"menor que: \", 15  < 5)\nprint(\"mayor o igual que: \", 15  >= 5)\nprint(\"menor o igual que: \", 15  <= 5)\n\n#estructuras de control\n#condicionales\nmy_variable = 8\nif my_variable == 10:\n    print(\"mi variable es: \", my_variable)\nelif my_variable > 10:\n    print(\"mi variable es mayor que 10\")\nelse:\n    print(\"mi variable es menor que  10\")\n\n#iterativas\nindex = 0\nwhile index < 7:\n    print(index)\n    index+=1\n\nfor index in range(7):\n    print(index)\n\n#excepciones\ntry:\n    print(7/0)\nexcept:\n    print(\"division entre cero no es posible\")\nfinally:\n    print(\"cambiar numero divisor\")\n\n#ejercicio opcional\nfor index in range(10, 56):\n    if index % 2 == 0 and index % 3 != 0:\n        if index != 16:\n            print(index)\n    if index == 55:\n         print(index)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/alberba.py",
    "content": "print(\"4 + 3 =\", 4 + 3)\nprint(\"4 == 3 or 10==10.0 = \", 4 == 3 or 10 == 10.0)\na = 5\nb = 2\nprint(\"a es b?: \", a is b)\nlista = [4, a, \"a\"]\nprint(\"'a' in lista: \", \"a\" in lista)\nprint(\" a & b : \", a | b)\n\nif (a in lista): \n    print(\"La variable A esta en la lista\")\n\nwhile (b < 5):\n    b += 1\n    print(\"B es igual a \", b)\n\n# Excepciones \ntry:\n    print(\"a / 0 = \", a / 0)\nexcept ZeroDivisionError:\n    print(\"No se puede dividir por 0\")\n\n# Dificultad extra\n\nfor i in range (10, 56):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/albertorevel.py",
    "content": "# @author Alberto Revel\n\n\"\"\"\n Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n\"\"\"\n\n# 1. Arithmetic operators\nprint(\"\\n**** PART 1 - Operators ****\\n\")\nprint(\"\\n** 1. Arithmetic Operators **\\n\")\nprint (\" - Addition (1+2) -> \" + str(1+2)) \nprint (\" - Subtraction (3-4) -> \" + str(3-4)) \nprint (\" - Multiplication (7*11) -> \" + str(7*11)) \nprint (\" - Division (float) (40/6) -> \" + str(40/6)) \nprint (\" - Division (floor) (40//6) -> \" + str(40//6)) \nprint (\" - Modulus (40%6) -> \" + str(40%6)) \nprint (\" - Power (2**8) -> \" + str(2**8)) \nprint (\"\\n\")\n\n# 2. Assignment operators\nprint(\"\\n** 2. Assignment Operators **\\n\")\nvar1 = 15\nvar2 = 8\nprint (f\" - var1 = 15, var2 = 8 -> var1:  {var1} , var2: {var2}\") \nvar1+=var2\nprint (f\" - var1 += var2 ->  {var1}\") \nvar1-=var2\nprint (f\" - var1 -= var2 ->  {var1}\") \nvar1*=var2\nprint (f\" - var1 *= var2 ->  {var1}\") \nvar1/=var2\nprint (f\" - var1 /= var2 ->  {var1}\") \nvar1%=8\nprint (f\" - var1 %= 8 ->  {var1}\") \nvar1//=3\nprint (f\" - var1 //= 3 ->  {var1}\") \nvar1**=var2\nprint (f\" - var1 **= var2 ->  {var1}\") \nvar2&=3\nprint (f\" - var2 &= 3 ->  {var2}\") \nvar2|=32\nprint (f\" - var2 |= 32 ->  {var2}\") \nvar2^=5\nprint (f\" - var2 ^= 5 ->  {var2}\") \nvar2<<=8\nprint (f\" - var2 <<= 8 ->  {var2}\") \nvar2>>=10\nprint (f\" - var2 >>= 10 ->  {var2}\") \nprint (\"\\n\")\n\n# 3. Logic operators\nprint(\"\\n** 3. Logic Operators **\\n\")\nvar3 = 15\nprint(\"Being var3 = 15\\n\")\nprint(\" - var3 > 0 and var3 > 50: \" + str(var3 > 0 and var3 > 50))\nprint(\" - var3 > 0 or var3 > 50: \" + str(var3 > 0 or var3 > 50))\nprint(\" - not(var3 > 0 and var3 > 50): \" + str(not(var3 > 0 and var3 > 50)))\nprint (\"\\n\")\n\n# 4. Identity operators\nprint(\"\\n** 4. Identity Operators **\\n\")\nvar4 = 7\nvar5 = 15\nprint(\"\"\"Being var3 = 15\n      var 4 = 7\n      var5 = 15\"\"\")\nprint(\"var3 is var5: \" + str(var3 is var5))\nprint(\"var4 is not var5: \" + str(var4 is not var5))\nprint (\"\\n\")\n\n# 5. Comparison operators\nprint(\"\\n** 5. Comparison Operators **\\n\")\nprint(\"\"\"Being var3 = 15\n      var 4 = 7\n      var5 = 15\"\"\")\nprint(\"var4 == var5: \" + str(var4 == var5))\nprint(\"var3 != var5: \" + str(var3 != var5))\nprint(\"var3 > var5: \" + str(var3 > var5))\nprint(\"var4 < var5: \" + str(var4 < var5))\nprint(\"var3 >= var5: \" + str(var3 >= var5))\nprint(\"var4 <= var5: \" + str(var4 <= var5))\nprint (\"\\n\")\n\n# 6. Membership  operators\nprint(\"\\n** 6. Membership  Operators **\\n\")\nlist1 = [\"iPhone\", \"Pixel\"]\nprint(\"\"\"Being list1 = [\"iPhone\", \"Pixel\"]\"\"\")\nprint(\"\"\" - \"Samsung\" in list1: \"\"\" + str(\"Samsung\" in list1))\nprint(\"\"\" - \"Samsung\" not in list1: \"\"\" + str(\"Samsung\" not in list1))\nprint (\"\\n\")\n\n# 7. Bitwise  operators\nprint(\"\\n** 7. Bitwise  Operators **\\n\")\nvar6=10 # 1010\nvar7=4 # 0100\nprint(\"\"\"Being var6=10 # 1010\n      var7=4 # 0100\"\"\")\nprint (\" - var6 | var7 -> \" + str(var6|var7)) \nprint (\" - var6 ~ var7 -> \" + str(~var6)) \nprint (\" - var6 & var7 -> \" + str(var6&var7)) \nprint (\" - var6 ^ var7 -> \" + str(var6^var7)) \nprint (\" - var6 >> 1 -> \" + str(var6>>1)) \nprint (\" - var6 << var7 -> \" + str(var6<<var7)) \nprint (\"\\n\")\n\n\n\"\"\"\nUtilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n\"\"\"\nprint(\"\\n**** PART 2 - Control structures ****\\n\")\nprint(\"\\n** 1. Conditionals **\\n\")\nprint(\"\"\"Being var5=15\n      var6=10\n      var7=4\"\"\")\nif (var6 > var7):\n    print(\"- var6 is greater than var7\")\nelif (var6 < var7):\n    print(\"- var6 is lower than var7\")\nelse:\n    print(\"- var6 is equals to var7\")\nprint(\"- var5 is greater than var6\") if var5 > var6 else print(\" - var6 is not greater than var5\")\nif var5>0: print(\"- var5 is greater than 0\")\n\nprint(\"\\n** 2. While **\\n\")\nprint(\"\\n - Simple loop\")\nindex = 1\nwhile index < 6:\n  print(f\"  · iteration {index}\")\n  index += 1\nelse:\n  print(f\" - End of loop, index value = {index}\")\n\nprint(\"\\n - Break at pairs\")\nindex = 0\nwhile index < 6:\n  index += 1\n  if (index % 2 == 0): \n     break\n  print(f\"  · iteration {index}\")\nelse:\n  print(f\" - End of loop, index value = {index}\") # Not executed because of break\n\nprint(\"\\n - Continue at pairs\")\nindex = 0\nwhile index < 6:\n  index += 1\n  if (index % 2 == 0): \n     continue\n  print(f\"  · iteration {index}\")\nelse:\n  print(f\" - End of loop, index value = {index}\")\n\n\n# 3. For loop\nprint(\"\\n** 3. For loop **\\n\")\nlist1 = [\"iPhone\", \"Pixel\", \"Poco\",\"Samsung\"]\nprint(\"- Array list\")\nfor element in list1:\n    print(f\"  · {element}\")\nprint (\"\\n\")\n\nprint(\"- Looping through string chars in string 'iPhone'\")\nfor eachChar in list1[0]:\n    print(f\"  · {eachChar}\")\nprint (\"\\n\")\n\nprint(\"- Nested loop\")\nfor element in list1:\n    for eachChar in element:\n        print(f\"  · {eachChar}\")\nprint (\"\\n\")\n\nprint(\"- Continue on words containing letter 'o'\")\nfor element in list1:\n    if \"o\" in element:\n      continue\n    print(f\"  · {element}\")\nprint (\"\\n\")\n\n\nprint(\"- Range function -> range(5)\")\nfor element in range(5):\n    print(f\"  · {element}\")\nprint (\"\\n\")\n\nprint(\"- Range function -> range(2,5)\")\nfor element in range(2,5):\n    print(f\"  · {element}\")\nprint (\"\\n\")\n\nprint(\"- Range function -> range(1,20,3)\")\nfor element in range(1,20,3):\n    print(f\"  · {element}\")\nelse:\n   print(\"Finished\")\nprint (\"\\n\")\n\nprint(\"- Range function with pass -> range(1,3)\")\nfor element in range(1,3):\n   pass\nprint (\"\\n\")\n\n\n\nprint(\"\\n** 4. Exceptions **\\n\")\nprint(\"print('Try block')\")\ntry:\n  print(\"Try block\")\nexcept:\n  print(\"Exception thrown\")\nelse:\n  print(\"No exception, not except block reached\")\nprint (\"\\n\")\n\nprint(\"print(var10)\")\ntry:\n  print(var10)\nexcept NameError:\n  print(\"Exception thrown of type NameError\")\nexcept:\n  print(\"Exception thrown (not of type NameError)\")\nprint (\"\\n\")\n\nprint(\"print(1/0)\")\ntry:\n  print(1/0)\nexcept NameError:\n  print(\"Exception thrown of type NameError\")\nexcept:\n  print(\"Exception thrown (not of type NameError)\")\nprint (\"\\n\")\n\n\n\"\"\"\n DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\"\"\"\nprint(\"\\n**** PART 3 - OPTIONAL ****\\n\")\nfor eachValue in range(10,56,2):\n   if (eachValue == 16 or eachValue % 3 == 0):\n      continue\n   print(f\" - {eachValue}\")\n   "
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/alcaan16.py",
    "content": "\"\"\"\n#01\nOPERADORES Y ESTRUCTURAS DE CONTROL\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\"\"\"\n\n\nfor i in range(10,56):\n    modulo_3 = i % 3\n    modulo_2 = i % 2\n\n    if i != 16 and modulo_2 == 0 and modulo_3 != 0:\n        print (i)\n\n\n\"\"\"\nExtra moruredev\n\nfor number in range(10, 56):\n    if number % 2 == 0 and number != 16 and number % 3 != 0:\n        print(number)\n\n\"\"\""
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/alejandro-mantilla.py",
    "content": "\"\"\"\nOPERADORES \n\"\"\"\n\n# Operadores Aritméticos\n\"\"\"\nOperadores en interpolación\n\"\"\"\nprint(f\"Suma: 20 + 3 = {20 + 3}\")\nprint(f\"Resta: 33 - 10 = {33 - 10}\")\nprint(f\"Multiplicacion 20 * 3 = {20 * 3}\")\nprint(f\"División: 20 / 3 = {20 / 3}\")\nprint(f\"Módulo: 20 % 3 = {20 % 3}\")\nprint(f\"Exponente: 20 ** 3 = {20 ** 3}\")\nprint(f\"División entera: 20 // 3 = {20 // 3}\")\n\n# Operadores de comparación\nprint(f\"Igualdad: 20 == 3 es {20 == 3}\")\nprint(f\"Desigualdad: 20 != 3 es {20 != 3}\")\nprint(f\"Mayor que: 20 > 3 es {20 > 3}\")\nprint(f\"Menor que: 20 < 3 es {20 < 3}\")\nprint(f\"Mayor o igual que: 20 >= 3 es {20 >= 3}\")\nprint(f\"Menor o igual que: 20 <= 3 es {20 <= 3}\")\n\n#Operadores lógicos\nprint(f\"AND &&: 20 + 3 == 23 and 5 - 1 == 4 es: {20 + 3 == 23 and 5 - 1 == 4}\") # Si ambos es verdadero la respuesta es Verdadero(True), si uno es falso la respuest es Falso(False)\nprint(f\"OR ||: 20 + 3 == 23 and 5 - 1 == 4 es: {20 + 3 == 22 or 5 - 1 == 4}\") # Si uno u otro es verdadero la respuesta es Verdadero(True)\nprint(f\"NOT !: not 20 + 3 = 24 es: {not 20 + 3 == 24}\")\n\n#Operadores de asignación\nmy_number = 11 # = <-asignación\nprint(my_number)\nmy_number += 1 # suma y asignación += <-asignación\nprint(my_number)\nmy_number -+ # resta y asignación -= <-asignación\nprint(my_number)\nmy_number *= 2 # multiplicación y asignación *= <-asignación\nprint(my_number)\nmy_number /= 2 # división y asignación /= <-asignación\nprint(my_number)\nmy_number %= 2 # modulo y asignación %= <-asignación\nprint(my_number)\nmy_number **= 1 # exponente y asignación **= <-asignación\nprint(my_number)\nmy_number // = 1 # división entera y asignación //= <-asignación\nprint(my_number)\n\n# Operadores de identidad\nmy_new_number = my_number\nprint(f\"my_number is my_new_number es {my_number is my_new_number}\")\nprint(f\"my_number is not my_new_number es {my_number is not my_new_number}\")\n\n# Operadores de pertenencia\nprint(f\"'o' in 'Alejandro' =  {'o' in 'Alejandro'}\")\nprint(f\"'b' not in 'Alejandro' =  {'o' not in 'Alejandro'}\")\n\n# Operadores de bit\na = 10 # 1010 <- num 10 respresntado en Binario\nb = 3 # 0011 <- num 3 representado en Binario\nprint(f\"AND: 10 & 3 = {10 & 3}\") # 0010\nprint(f\"OR: 10 & 3 = {10 | 3}\") # 1011\nprint(f\"XOR: 10 & 3 = {10 ^ 3}\") # 1001\nprint(f\"NOT: ~10 = {~10}\")\nprint(f\"Desplazamiento a la derecha: 10 >> 2 = {10 >> 2}\") # 0010\nprint(f\"Desplazamiento a la izquierda: 10 >> 2 = {10 >> 2}\") # 101000\n\n\"\"\"\nEstructura de control\n\"\"\"\n\n# Condicionales\n\nmy_string = \"ManCar\"\nif my_string == \"Alejandro\"\n  print(\"my_string es 'Alejandro'\")\nelif my_string = \"ManCar\":\n  print(\"my_string es 'ManCar'\")\nelse: \n  print(\"my_string no es 'Alejandro' ni 'ManCar'\")\n\n# Iterativas\n\nfor i in range(11):\n  print(i)\n  \ni = 0\n\nwhile i <= 10:\n  print(i)\n  i += 1\n\n# Manejo de excepciones\ntry:\n  print(10 / 0)\nexcept: \n  print(\"Se ha producido un error\")\nfinally:\n  print(\"Ha finalzado el manejo de excepciones\")\n\n\"\"\"\nExtra\n\"\"\"\n\nfor number in range(10, 56)\n  if number %2 == 0 and number != 16 and number % 3 != 0:\n    print(number)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/alejo-digital.py",
    "content": "# 01 Operadores y estructuras de control\n\n\"\"\"\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n \"\"\"\n\n # Operadores Aritmeticos\n\nsuma = 10 + 5  # Suma\nresta = 10 - 5  # Resta\nmultiplicacion = 10 * 5  # Multiplicación\ndivision = 10 / 3  # División\nmodulo = 10 % 3  # Módulo\nexponente = 10 ** 3  # Exponente\ndivision_entera = 10 // 3  # División entera\n\nprint(\"Operadores Aritméticos:\")\nprint(f\"Suma 10 + 5: {suma}\")\nprint(f\"Resta 10 - 5: {resta}\")\nprint(f\"Multiplicación 10 * 5: {multiplicacion}\")\nprint(f\"División 10 / 3: {division}\")\nprint(f\"Módulo 10 % 3: {modulo}\")\nprint(f\"Exponente 10 ** 3: {exponente}\")\nprint(f\"División entera 10 // 3: {division_entera}\")\n\n# Operadores de Comparación\n\nmayor_que = 10 > 5  # Mayor que\nmenor_que = 10 < 5  # Menor que\nigual_que = 10 == 5  # Igual que\nmayor_igual_que = 10 >= 5  # Mayor o igual que\nmenor_igual_que = 10 <= 5  # Menor o igual que\ndiferente_que = 10 != 5  # Diferente que \n\nprint(\"\\nOperadores de Comparación:\")\nprint(f\"10 > 5: {mayor_que}\")\nprint(f\"10 < 5: {menor_que}\")\nprint(f\"10 == 5: {igual_que}\")\nprint(f\"10 >= 5: {mayor_igual_que}\")\nprint(f\"10 <= 5: {menor_igual_que}\")\nprint(f\"10 != 5: {diferente_que}\")\n\n# Operadores Lógicos\n\nand_condition = True and False  # AND lógico\nor_condition = True or False  # OR lógico\nnot_condition = not True  # NOT lógico\nprint(\"\\nOperadores Lógicos:\")\nprint(f\"True and False: {and_condition}\")\nprint(f\"True or False: {or_condition}\")\nprint(f\"not True: {not_condition}\")\n\n# Operadores de Asignación\n\nasignacion = 10  # Asignación simple\nprint(\"\\nOperadores de Asignación:\")\nprint(f\"Asignación simple: {asignacion}\")\nasignacion += 5  # Asignación con suma\nprint(f\"Asignación += 5: {asignacion}\")\nasignacion -= 3  # Asignación con resta\nprint(f\"Asignación -= 3: {asignacion}\")\nasignacion *= 2  # Asignación con multiplicación\nprint(f\"Asignación *= 2: {asignacion}\")\nasignacion /= 3  # Asignación con división\nprint(f\"Asignación /= 3: {asignacion}\")\nasignacion %= 3  # Asignación con módulo\nprint(f\"Asignación %= 3: {asignacion}\")\nasignacion **= 4  # Asignación con exponente\nprint(f\"Asignación **= 4: {asignacion}\")\nasignacion //= 5  # Asignación con división entera\nprint(f\"Asignación //= 5: {asignacion}\")\n\n# Operadores de Identidad\n\nis_operator = (10 is 10)  # Identidad\nis_not_operator = (10 is not 5)  # No identidad\nprint(\"\\nOperadores de Identidad:\")\nprint(f\"10 is 10: {is_operator}\")\nprint(f\"10 is not 5: {is_not_operator}\")\n\n# Operadores de Pertenencia\nin_operator = 10 in [1, 2, 3, 4, 5]  # Pertenencia\nnot_in_operator = 10 not in [1, 2, 3, 4, 5]  # No pertenencia \nis_true = \"e\" in \"Alejandro\"  # Verifica si 'e' está en 'Alejandro'\nprint(\"\\nOperadores de Pertenencia:\")\nprint(f\"10 in [1, 2, 3, 4, 5]: {in_operator}\")\nprint(f\"10 not in [1, 2, 3, 4, 5]: {not_in_operator}\")\nprint(f\"'e' in 'Alejandro': {is_true}\")\n\n# Operadores de Bits\n\nbit_and = 10 & 5  # AND bit a bit \nbit_or = 10 | 5  # OR bit a bit\nbit_xor = 10 ^ 5  # XOR bit a bit\nbit_not = ~10  # NOT bit a bit\nbit_left_shift = 10 << 2  # Desplazamiento a la izquierda\nbit_right_shift = 10 >> 2  # Desplazamiento a la derecha\nprint(\"\\nOperadores de Bits:\")\nprint(f\"10 & 5: {bit_and}\")\nprint(f\"10 | 5: {bit_or}\")\nprint(f\"10 ^ 5: {bit_xor}\")\nprint(f\"~10: {bit_not}\")\nprint(f\"10 << 2: {bit_left_shift}\")\nprint(f\"10 >> 2: {bit_right_shift}\")\n\n# Estructuras de Control\nprint(\"\\nEstructuras de Control:\")\n\n# Condicionales\nprint(\"\\nCondicionales:\")\n\nif 10 > 5:\n    print(\"\\nCondicional: 10 es mayor que 5\")\nelif 10 < 5:\n    print(\"\\nCondicional: 10 es menor que 5\")\nelse:\n    print(\"\\nCondicional: 10 es igual a 5\")\n\n\n# Iterativas\n\nprint(\"\\nIterativas:\")\nfor i in range(5):\n    print(f\"Iterativa: Iteración {i}\")\nwhile i < 5:\n    print(f\"Iterativa: Iteración {i}\")\n    i += 1\n\n# Excepciones\nprint(\"\\nExcepciones:\")\ntry:\n    print(\"Resultado de la división 10 / 0:\")\n    resultado = 10 / 0  # Esto generará una excepción\nexcept ZeroDivisionError:\n    print(\"Excepción: No se puede dividir por cero\")\nprint(\"\\nExtra: Números entre 10 y 55, pares, no 16 ni múltiplos de 3\")\nprint(\"Dificultad Extra:\")\nfor num in range(10, 56):\n    if num % 2 == 0 and num != 16 and num % 3 != 0:\n        print(num, end=\" \")\nprint(\"\\n \\nFin del reto. ¡Sigue practicando y aprendiendo!\")"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/alejosor.py",
    "content": "'''\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n'''\nimport random\n# OPERADORES ARITMÉTICOS\nprint(\"\\nOperadores Aritméticos\")\nprint(f'    - La suma de 10 + 5 es igual a {10 + 5}')\nprint(f'    - La resta de 10 - 5 es igual a {10 - 5}')\nprint(f'    - La multiplic de 10 x 5 es igual a {10 * 5}')\nprint(f'    - La división de 10 entre 5 es igual a {10 / 5}')\nprint(f'    - El resto de 10 entre 5 es igual a {10 % 5}')\nprint(f'    - La división de piso de 10 entre 5 es igual a {10 // 5}')\nprint(f'    - La potencia de 10 elevado a 5 es igual a {10 ** 5}\\n')\n\n# OPERADORES LÓGICOS\nprint(\"Operadores Lógicos\")\nprint(f\"    - AND -> True and True = {True and True}\") # Operador AND\nprint(f\"    - OR -> True or False = {True or False}\") # Operador OR\nprint(f\"    - NOT = not True = {not True}\\n\") # Operador NOT\n\n# OPERADORES DE COMPARACIÓN\nprint(\"Operadores de Comparación\")\nprint(f\"    - Mayor > -> 5 es mayor(>) a 3 = {5>3}\") #Operador de comparación >\nprint(f\"    - Menor < -> 5 es menor(<) a 3 = {5<3}\") #Operador de comparación <\nprint(f\"    - Mayor o Igual >= -> 5 es mayor o igual (>=) a 3 = {5>3}\") #Operador de comparación >=\nprint(f\"    - Menor o Igual <= -> 5 es menor o igual (<=) a 3 = {5>3}\") #Operador de comparación <=\nprint(f\"    - Igual == -> 5 es igual(==) a 5 = {5==5}\") #Operador de comparación ==\nprint(f\"    - No igual != -> 5 no es igual(!=) a 3 = {5!=3}\\n\") #Operador de comparación !=\n\n# OPERADORES DE ASIGNACIÓN\nprint(\"Operadores de Asignación\")\nprint(f\"    -> x = 5\")\nprint(f\"    - x+=3 -> x = x + 3 = {5+3}\") # Suma\nprint(f\"    - x-=3 -> 5 - 3 = {5-3}\") # Resta\nprint(f\"    - x*=3 -> 5 * 3 = {5*3}\") # Multiplicación\nprint(f\"    - x/=3 -> 5 / 3 = {5/3}\") # División\nprint(f\"    - x%=3 -> 5 % 3 = {5%3}\") # Resto\nprint(f\"    - x//=3 -> 5 // 3 = {5//3}\") # División de piso\nprint(f\"    - x**=3 -> 5 ** 3 = {5**3}\\n\") # Potencia\n\n# OPERADORES DE IDENTIDAD\nnum_1 = 5\nnum_2 = num_1\nprint(\"Operadores de Identidad\")\nprint(f'    - num_1 is num_2 = {num_1 is num_2}')\nprint(f'    - num_1 is not num_2 = {num_1 is not num_2}\\n')\n\n# OPERADORES DE PERTENENCIA\nprint(\"Operadores de Pertenencia\")\nprint(f\"    - 'a' in 'alejandro' = {\"a\" in \"alejandro\"}\")\nprint(f\"    - 'u' not in 'alejandro' = {\"u\" not in \"alejandro\"}\\n\")\n\n# OPERADORES DE BITS\na = 5\nb = 3\nprint(\"Operadores de Bits\")\nprint(\"a = 5\") # 0101\nprint(\"b = 3\") # 0011\nprint(f'AND: a & b = {a & b}')\nprint(f'OR: a | b = {a | b}')\nprint(f'XOR: a ^ b = {a ^ b}')\nprint(f'NOT: ~a = {~a}')\nprint(f\"Desplazamiento a la derecha a >> b = {a >> b}\")\nprint(f\"Desplazamiento a la izquierda a << b = {a >> b}\\n\")\n\n# ESTRUCUTURAS DE CONTROL\nprint(\"Estructuras de control\")\n# CONDICIONALES\nprint(\"Condicionales\")\nmy_number = random.randint(1,10)\nif my_number > 5:\n    print(\"Mi número es mayor a 5\")\nelif my_number < 9:\n    print(\"Mi número es menor a 9\")\nelse:\n    print(\"Mi número no es ninguna de las condiciones anteriores\")\n\n# INTERATIVOS\nprint(\"\\nCondicionales: FOR\")\nfor i in range(6):\n    print(i)\n\ni = 10\n\nprint(\"\\nCondicionales: WHILE\")\nwhile i <= 6:\n    print(f'El número es {i} y es menor igual a 6\\n')\n    \n# MANEJO DE EXCEPCIONES\nprint(\"Manejo de excepciones\")\ntry:\n    print(a/0)\nexcept Exception as e:\n    print(f\"Ups.. Hay un error, {e}\")\nfinally:\n    print(\"Secuencia terminada\")\n\n# Extras\n# Crea un programa que imprima por consola todos los números comprendidos\n#  * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\nprint(\"\\nExtra\")\nfor i in range(10,56):\n    if i & 2 == 0 and i != 16 and i % 3 != 0:\n        print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/alexdevrep.py",
    "content": "\"\"\"\n  EJERCICIO:\n  - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n    Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n    (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n  - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n    que representen todos los tipos de estructuras de control que existan\n    en tu lenguaje:\n    Condicionales, iterativas, excepciones...\n  - Debes hacer print por consola del resultado de todos los ejemplos.\n \n *DIFICULTAD EXTRA (opcional):\n  Crea un programa que imprima por consola todos los números comprendidos\n *entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n \n  Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\"\"\"\n#Operadores aritméticos\n\n#Suma \nsuma = 1 + 2\n\n#Resta \nresta = 7 - 8\n\n#Multiplicación\nmultiplicacion = 2 * 2\n\n#División\ndivision = 10 / 2\n\n#División con cociente entero\ndivisionEntero = 13 # 4\n\n#Módulo (es el resto de la división)\nmodulo = 9 % 2\n\n#Exponente \nexponente = 3**3\n\n\n# Operadores lógicos (vamos a declarar antes para este apartado)\nVALORTRUE = True\nVALORFALSE = False\n\n#Operación AND (la salida será True cuando todas las variables sean true)\nAND = VALORFALSE and VALORTRUE\n\n#Operación OR (la salida será True cuando alguna variable sea true)\nOR = VALORFALSE or VALORTRUE\n\n#Devuelve false si su único operando es true, de lo contrario devuelve true\nNOT = not VALORTRUE\n\n\n#Operadores de comparación\n\n#Igualdad \nigualdad = 3==3\n\n#No igualdad\nnoIgualdad = 4 !=56\n\n#Mayor que \nmayorQue = 23 > 18\n\n#Menor que\nmenorQue = 12 < 34\n\n#Mayor o igual que \nmayorOIgual = 33 >= 33\n\n#Menor o igual que \nmenorOIgual = 12 <= 13\n\n\n#Operadores de asignación\nnumero1 = 3\nnumero2 = 5\n\n#Operador suma\nnumero1 += numero2 # numero1 = numero1 + numero 2\n\n#Operador resta \nnumero2 -= numero1 #numero2 = numero2 - numero1\n\n#Operador multiplicación\nnumero1 *= numero2 # numero1 = numero1 * numero2\n\n#Operador división\nnumero1 /= numero2 # numero1 = numero1 / numero2\n\n#Operador módulo\nnumero2 %= numero1 # numero2 = resto de la división entre numero 2 y numero 1\n\n#Operador exponente \nnumero1 **= numero2 #numero1 = numero1 ** numero2\n\n#Operador división entera\nnumero2 #= numero1 #numero2 = numero2 / numero1 pero el cociente será un numero entero\n\n\n#Operadores de identidad\nnumero3 = 7\nnumero4 = 9\n#Operador de igualdad esctricta\nnumero3 is numero4 #En caso de que sean estrictamente iguales el terminal devolverá true\n#Operador de desigualdad estricta\nnumero3 is not numero4 #Si son desiguales en algo el ternimal devuelve true\n\n\n#Operadores de pertenencia\nmyList = [1,2,3,4,5,6]\n\npertTrue = 3 in myList #Devuelve true\n\npertFalse = 33 in myList #Devuelve false\n\n\n#Operadores bit a bit (Los números se convierten a numeros binarios y se hacen las operaciones lógicas correspondientes bit a bit)\nnumero5 = 15\nnumero6 = 9\n#AND a nivel de bits (Devuelve un uno en cada posición del bit para los que los bits correspondientes de ambos operandos son unos)\nbitAnd = numero5 & numero6 # 1111 (15) & 1001 (9)= 1001, la operación AND devuelve 1 cuando ambos bits sean 1 y 0 para el resto de los casos\n#OR a nivel de bits (Devuelve un uno en cada posición del bit para los que los bits correspondientes de ambos operandos no sean 0)\nbitOr = numero5 | numero6 # 1111 (15) & 1001 (9)= 1111, la operación OR devuelve 1 cuando ambos bits sean 1 o 0 y 0 para el resto de los casos\n#XOR a nivel de bits\nbitXor = numero5 ^ numero6 # 1111 (15) & 1001 (9)= 0110, la operación XOR devuelve 1 cuando ambos bits sean distintosy 0 para cuando sean iguales\n#NOT a nivel de bits\nbitNot = ~numero5 #Convierte los bits los que son 1 pasan a 0 y vicerversa \n#Desplazamiento a la izquierda\nbitIzq = numero6<< 3 # 9<<3 desplaza el numero6 3 ceros a la izquierda y da resultado 1001000\n#Desplazamiento a la derecha \nbitDcha = numero6 >> 3# 9>>3 desplaza el numero6 3 ceros a la derecha y da resultado 1\n\n\n#Estructuras de control\n\n#Sentencia IF si se cumple la condición se ejecuta el bloque de código que hay dentro de la sentencia, en caso contrario se ejecuta otro código\nprint(\"Resultado Sentencia IF:\")\n\nif (numero1 < numero2):\n\n    print(\"Número 1 es mayor que número 2\") \n\nelse :\n    \n    print(\"Número 2 es mayor que número 1\")\n\n# Bucle WHILE la acción se ejecuta hasta que la condición deja de cumplirse (ideal para cuando no sabemos el número de iteraciones del bucle)\nprint(\"Resultado Bucle WHILE:\")\nnumero7 = 1\n\nwhile (numero7 <= 9):\n    print(numero7)\n    numero7 = numero7 + 1\n\n # Bucle FOR la acción se ejecuta hasta que se cumple con el número máximo de iteraciones\nprint(\"Resultado Bucle FOR:\")\nnumero8 = 1\nfor numero8 in range (1,10):\n    print(\"Es mi primer bucle for en Python\")\n\n#Excepciones\n    \n#Sentencias try y except\n\ntry: #EL PROGRAMA VA A EJECUTAR ESTE CÓDOGO PRIMERO\n    numero12 = int(input(\"Introduce un número\"))\n    numero14 = int (input(\"Introduce otro número\"))\n    resultado = numero12 + numero14\n    print (resultado)\nexcept: # SI NO SE INTRODUCEN NÚMEROS EL PROGRAMA EJECUTA ESTO EN VEZ DE QUEDARSE BLOQUEADO\n    print(\"Debes introducir números\")\n\n#Sentencia finally (esto se ejecuta si o si de error o no)\ntry: \n    numero12 = int(input(\"Introduce un número\"))\n    numero14 = int (input(\"Introduce otro número\"))\n    resultado = numero12 + numero14\n    print (resultado)\nexcept: \n    print(\"Debes introducir números\")\nfinally:\n    print (\"Esto se ejecuta si o si\")\n\n\n\n\n\n\n#DIFICULTAD EXTRA  \n\nnumero9 = 10\n\nfor numero9 in range (9,55):\n    numero9 = numero9 + 1\n    if (numero9 % 2 == 0 and numero9 != 16 and numero9 % 3 !=0):\n        print (numero9)\n    \n\n\n       \n\n        \n       \n\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/allbertoMD.py",
    "content": "# Arithmetics Operators\naddition = 4 + 8\nsubtraction = 10 - 4\nmultiplication = 12 * 2\ndivision = 100 / 6\nmodulus = 30 % 7\n\nprint(\"\\nArithmetic Operators\")\nprint(f\"addition result: {addition}\")\nprint(f\"subtraction result: {subtraction}\")\nprint(f\"multiplication result: {multiplication}\")\nprint(f\"division result: {division}\")\nprint(f\"modulus result: {modulus}\")\n\n\n# Assignment Operators\nnumber_by_assigment = 777\nassigment_operator = number_by_assigment\naddition_assigment = 222\naddition_assigment += number_by_assigment\nsubtraction_assigment = 999\nsubtraction_assigment -= number_by_assigment\nmultiplication_assigment = 12982\nmultiplication_assigment *= number_by_assigment\ndivision_assigment = 1414\ndivision_assigment /= number_by_assigment\nmodulus_assigment = 11000\nmodulus_assigment %= number_by_assigment\n\nprint(\"\\n Assigment Operators\")\nprint(f\"addition_assigment result: {addition_assigment}\")\nprint(f\"subtraction_assigment result: {subtraction_assigment}\")\nprint(f\"multiplication_assigment result: {multiplication_assigment}\")\nprint(f\"division_assigment result: {division_assigment}\")\nprint(f\"modulus_assigment result: {modulus_assigment}\")\n\n\n# Comparison Operators\nequal_to = 1 == 1\nnot_equal_to = 1 != 4\ngreatter_than = 20 > 40\nless_than = 9 < 1\ngreatter_than_or_equal_to = 77 >= 22\nless_than_or_equal_to = 23 <= 98\n\nprint(\"\\n Comparison Operators\")\nprint(f\"equal_to result: {equal_to}\")\nprint(f\"not_equal_to result: {not_equal_to}\")\nprint(f\"greatter_than result: {greatter_than}\")\nprint(f\"less_than result {less_than}\")\nprint(f\"greatter_than_or_equal_to result: {greatter_than_or_equal_to}\")\nprint(f\"less_than_or_equaal_to result: {less_than_or_equal_to}\")\n\n\n# Logical Operators\nand_operator = True == True and False == False\nor_operator = 1 < 0 or 0 >= -3\nnot_operator = not False\n\nprint(\"\\nLogical Operators\")\nprint(f\"and_operator result: {and_operator}\")\nprint(f\"or_operator result: {or_operator}\")\nprint(f\"not_operator result: {not_operator}\")\n\n\n# Ternary Opretator\nternary_operator = \"Hello\" if True else \"Bye\"\n\nprint(\"\\nTernary Operator\")\nprint(f\"ternary_operator result: {ternary_operator}\")\n\n\n# Range Operator\nrange_Operator = range(0, 11)\n\nprint(\"\\nRange Operator\")\nfor n in range_Operator:\n    print(f\"the range_o[erator result now is: {n}\")\n\n\n# Bit Operators\nfirst_binary = 22 # 0001 0110\nsecond_binary = 44 # 0010 1100\nbitwise_AND = first_binary & second_binary\nbitwise_OR = first_binary | second_binary\nbitwise_XOR = first_binary ^ second_binary\nbitwise_NOT = ~first_binary\nbitwise_left_shift = first_binary << 1\nbitwise_right_shift = second_binary >> 1\n\nprint(\"\\nBit Operators\")\nprint(f\"bitwise_AND result: {bitwise_AND}\")\nprint(f\"bitwise_OR result: {bitwise_OR}\")\nprint(f\"bitwise_XOR result: {bitwise_XOR}\")\nprint(f\"bitwise_NOT result: {bitwise_NOT}\")\nprint(f\"bitwise_left_shift result: {bitwise_left_shift}\")\nprint(f\"bitwise_right_shift result: {bitwise_right_shift}\")\n\n\n# Exception\nprint(\"\\nExeption\")\ntry:\n    result = 10 / 0\nexcept:\n    print(\"Error\")\nelse:\n    print(result)\nfinally:\n    print(\"End\")\n\n\n# Control Flow (if, else and elif)\nprint(\"\\nControl Flow (if, else and elif)\")\ncontrol_flow_test = 0\nif control_flow_test == 1:\n    print(\"Is 1\")\nelif control_flow_test == 2:\n    print(\"Is 2\")\nelse:\n    print(\"Is 0\")\n\n\n# Loop (for)\nprint(\"\\nLoop (for)\")\nfor i in range(0, 11):\n    print(f\"The for result is now: {i}\")\n\n\n# Loop (while)\nprint(\"\\nLoop (while)\")\nnumber_while = 22\nwhile number_while < 33:\n    print(f\"The while result is now: {number_while}\")\n    number_while += 1\n\n\n\n\n# Extra Dificulty\n############################################################\n\ndef print_numbers():\n    for number in range(10, 55):\n        if number == 16:\n            continue\n        if number % 2 == 0 and number % 3 != 0:\n            print(number)\n        \nprint(\"\\nNumbers from 10 to 55 without 16 and multiples of three\")\nprint_numbers()"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/anblackter.py",
    "content": "# Aritmetric operators are (+ sum) (- rest) (* multiplciation) (/ division)\n# Those are also complement of aritmetric operators (// floor division) (% remainder) (** squared root)\n\nprint(f'sum {1 + 2}')\nprint(f'rest {2 - 1}')\nprint(f'multiplication {2 * 2}')\nprint(f'division {2 / 2}')\nprint(f'floor division {23 // 2}')\nprint(f'division remainder {23 % 3}')\nprint(f'square {3 ** 2}')\n\n# Comparative operations uses (< less than) (> greater than) (<= less or equal than) (>= greater or equal than)\n# (== equals) (!= different)\nprint(f'less than {1 < 2}')\nprint(f'less than {1 > 2}')\nprint(f'greater or equal than {2 >= 2}')\nprint(f'less or equal than {10 <= 2}')\nprint(f'different {10 != 2}')\nprint(f'equals {10 == 10}')\n\n# Logical operators are (and) (or) (not)\nprint(f' and {10 != 2 and 2 == 2}')\nprint(f' or {10 != 2 or 2 == 2}')\nprint(f' not {not (10 != 2)}')\n\n# Iterations are (for) (while)\nfor i in range(10):\n    print(i)\n\ncounter = 0\nwhile counter < 10:\n    print(counter)\n\n# Conditionals are (if, else)\nif 1 <= 2:\n    print('1 is less or equal than 2')\nelif 2 >= 1:\n    print('2 is greater or equal than 1')\nelse:\n    print('None of those conditions true')\n\n# Exceptions\ntry:\n    print(a)\nexcept:\n    print('This is an error, a is undefined before used')\nelse:\n    print('This print appears if not exception occurs when run into try block')\nfinally:\n    print('This print always appear at the end of teh try except blocks. Doesn\\'t matter is exception occurs or not')\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/andreessj.py",
    "content": "# Operadores\nprint(\"OPERADORES ARITMETICOS\\n\")\n\nprint(f\"Suma 2+2 = {2+2}\")\nprint(f\"Resta 2-2 = {2-2}\")\nprint(f\"Multiplicacion 2*2 = {2*2}\")\nprint(f\"Exponente 2**2 = {2**2}\")\nprint(f\"Division 2/2 = {2/2}\")\nprint(f\"Division entera 2//2 = {2//2}\")\nprint(f\"Resto 2%2 = {2%2}\")\n\nprint(\"\\nOPERADORES DE COMPARACION\\n\")\n\nprint(f\"Igualdad 5 == 5 es {5==5}\")  # true\nprint(f\"Igualdad 2 < 5 es {5==5}\")  # true\nprint(f\"Igualdad 5 > 3 es {5==5}\")  # true\nprint(f\"Igualdad 5 >= 5 es {5==5}\")  # true\nprint(f\"Igualdad 5 <= 5 es {5==5}\")  # true\n\nprint(\"\\nOPERADORES LOGICOS\\n \")\n\nprint(f\"AND 4 <= 5 and 5 > 1 es = {4<=5 & 5 > 1}\")\nprint(f\"OR 6 <= 5 or 0 > 1 es = {6<=5 | 0 > 1}\")\nprint(f\"NOT 6 <= 5 es = {not 6<=5}\")  # true\nprint(f\"NOT 5 <= 5 es = {not 5<=5}\")  # false\n\nprint(\"\\nOPERADORES DE ASIGNACION\\n \")\n\nnumber = 5\nnumber += 2  # 7\n\nnumber2 = 4\nnumber2 -= 2  # 2\n\nnumber3 = 6\nnumber3 *= 2  # 12\n\nnumber4 = 8\nnumber4 //= 2\n\nprint(\n    f\"Suma = {number}\\nResta = {number2}\\nMultplicacion = {number3}\\nDivision = {number4}\"\n)\n\nprint(\"\\nOPERADORES DE PERTENENCIA\\n \")\n\nprint(f\"'P' in Password? = {'P' in 'Password'}\")\nprint(f\"'P' in Password? = {'P' not in 'Password'}\")\n\nprint(\"\\nCONDICIONALES\\n \")\n\nname = \"Andres\"\n\nif len(name) >= 5:\n    print(\"Tu nombre tiene mas de 5 caracteres\")\nelif len(name) < 5 and len(name) >= 1:\n    print(\"Nombre corto\")\nelse:\n    print(\"No hay nombre\")\n\n\nprint(\"\\nITERADORES\\n\")\n\nindex = 0\n\nprint(\"\\nFor:\\n\")\nfor item in range(5):\n    print(f\"Numero [{item + 1}]\")\n\nprint(\"\\nWhile:\\n\")\nwhile index < 5:\n    print(f\"Numero [{index + 1}]\")\n    index += 1\n\nprint(\"\\nEXCEPCIONES\\n\")\n\ntry:\n    print(2 / 0)\nexcept:\n    print(\"Se ha producido un error\")\nfinally:\n    print(\"Fin del programa\")\n\nprint(\"\\nEXTRA\\n\")\n\nfor i in range(10, 56):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print(i)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/andres54-coder.py",
    "content": "\"\"\"\nOperadores y estructuras de control\n\"\"\"\n\n# Operadores aritméticos\nprint(f\"suma = 1 + 2: {1 + 2}\")\nprint(f\"resta = 7 - 8: {7 - 8}\")\nprint(f\"multiplicacion = 2 * 2: {2 * 2}\")\nprint(f\"division = 10 / 2: {10 / 2}\")\nprint(f\"divisionEntero = 13 // 4: {13 // 4}\")\nprint(f\"modulo = 9 % 2: {9 % 2}\")\nprint(f\"exponente = 3 ** 3: {3 ** 3}\")\n\n# operadores de comparación\n\nprint(f\"igualdad = 1 == 1: {1 == 1}\")\nprint(f\"desigualdad = 1 != 2: {1 != 2}\")\nprint(f\"mayor Que = 1 > 2: {1 > 2}\") \nprint(f\"menor Que = 1 < 2: {1 < 2}\") \nprint(f\"mayor o igua = 1 >= 2: {1 >= 2}\") \nprint(f\"menor o igual = 1 <= 2: {1 <=2}\") \n\n# operadores lógicos\n\nprint(f\"and &&= 10 + 3 == 13 and 5 - 1 == 4: { 10 + 3 == 13 and 5 - 1 == 4}\")\nprint(f\"or || = 10 + 3 == 13 or 5 - 1 == 5: { 10 + 3 == 13 or 5 - 1 == 4}\")\nprint(f\"not ! = not 10 + 3 == 13: {not 10 + 3 == 13}\")\n\n# operadores de asignación\n\nmy_number = 10 #asignación\nprint(my_number)\nmy_number += 5 #suma  \nprint(my_number)\nmy_number -= 5 #resta\nprint(my_number)\nmy_number *= 5 #multiplicación\nprint(my_number)\nmy_number /= 5 #división\nprint(my_number)\nmy_number %= 5 #modulo\nprint(my_number)\nmy_number **= 5 #exponente\nprint(my_number)\nmy_number //= 5 #división entera\nprint(my_number)\n\n# operadores de identidad \n# // se usa para saber si una variable tiene el mismo espacio de memoria que otra\n# my_number = 1.0\nmy_new_number = my_number\nprint(f\"my_number is my_new_number es {my_number is my_new_number}\")\nprint(f\"my_number is not my_new_number es {my_number is not my_new_number}\")\n# print(my_new_number, my_number)\n\n# operadores de pertenencia\n\nmy_list = [1, 2, 3, 4, 5]\nprint(my_list)\nprint(f\"1 in my_list es {1 in my_list}\")\nprint(f\"6 not is my_list es {6 not in my_list}\")\n\n#operadores de bits\n\na = 10 # 1010\nb= 3 # 0011\n\nprint(f\"AND: 10 & 3= {a & b}\") # 0010\nprint(f\"OR: 10 | 3= {a | b}\") # 1011 \nprint(f\"XOR: 10 ^ 3= {a ^ b}\") # 1001\nprint(f\"NOT: ~10= {~a}\") # 0101\nprint(f\"Desplazamiento a la derecha: 10 >> 1= {a >> 2}\") # 0010\nprint(f\"Desplazamiento a la izquierda: 10 << 1= {a << 2}\") # 101000\n\n\n\"\"\"\nEstructuras de control\n\"\"\"\n# condicionales\nmy_sring = \"hola3\"\nif my_sring == \"hola\":\n    print(\"my_sring es igual a hola\")\nelif my_sring == \"hola2\":\n    print(\"my_sring es igual a hola2\")\nelse:\n    print(\"my_sring no es igual a 'hola' ni 'hola2'\")\n\n\n# bucles\n# for\nfor i in range(0, 11):\n    print(i)\n\ni = 0\n# while\nwhile i < 11:\n    print(i)\n    i += 1\n\n#manejo de excepciones\ntry:\n    print(10/1)\nexcept:\n    print(\"No se puede dividir por cero\")\nfinally:\n    print(\"Se termino el proceso\")\n\n\n# Ejercicio EXTRA\nfor i in range(10, 56):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/andresgcastillo.py",
    "content": "# Operadores aritméticos\nsuma = 5 + 3\nresta = 5 - 3\nmultiplicacion = 5 * 3\ndivision = 5 / 3\nmodulo = 5 % 3\nexponente = 5 ** 3\ndivision_entera = 5 // 3\n\nprint(\"Operadores aritméticos:\", suma, resta, multiplicacion, division, modulo, exponente, division_entera)\n\n# Operadores de comparación\nigual = 5 == 3\nno_igual = 5 != 3\nmayor_que = 5 > 3\nmenor_que = 5 < 3\nmayor_o_igual_que = 5 >= 3\nmenor_o_igual_que = 5 <= 3\n\nprint(\"Operadores de comparación:\", igual, no_igual, mayor_que, menor_que, mayor_o_igual_que, menor_o_igual_que)\n\n# Operadores lógicos\nand_logico = True and False\nor_logico = True or False\nnot_logico = not True\n\nprint(\"Operadores lógicos:\", and_logico, or_logico, not_logico)\n\n# Operadores de asignación\na = 5\na += 3\na -= 3\na *= 3\na /= 3\na %= 3\na **= 3\na //= 3\n\nprint(\"Operadores de asignación:\", a)\n\n# Operadores de identidad\na = 5\nb = a\nes = a is b\nno_es = a is not b\n\nprint(\"Operadores de identidad:\", es, no_es)\n\n# Operadores de pertenencia\nlista = [1, 2, 3, 4, 5]\npertenece = 3 in lista\nno_pertenece = 6 not in lista\n\nprint(\"Operadores de pertenencia:\", pertenece, no_pertenece)\n\n# Operadores de bits\nand_bits = 5 & 3\nor_bits = 5 | 3\nnot_bits = ~5\nxor_bits = 5 ^ 3\ndesplazamiento_derecha = 5 >> 3\ndesplazamiento_izquierda = 5 << 3\n\nprint(\"Operadores de bits:\", and_bits, or_bits, not_bits, xor_bits, desplazamiento_derecha, desplazamiento_izquierda)\n\n# Estructuras de control\n# Condicionales\nif 5 > 3:\n    print(\"5 es mayor que 3\")\nelse:\n    print(\"5 no es mayor que 3\")\n\n# Iterativas\nfor i in range(5):\n    print(i)\n\ni = 0\nwhile i < 5:\n    print(i)\n    i += 1\n\n# Excepciones\ntry:\n    print(5 / 0)\nexcept ZeroDivisionError:\n    print(\"No se puede dividir por cero\")\n\n#Dificultad Extra\n# Recorremos el rango de números del 10 al 55 (incluidos)\nfor i in range(10, 56):\n    # Comprobamos si el número es par, no es 16 y no es múltiplo de 3\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/andresmendozaf.py",
    "content": "\"\"\"\nOperadores\n\"\"\"\n\n# Operadores Aritméticos\nsum = 10 + 5\nprint(f\"Suma: 10 + 3 = {10 + 3}\")\nprint(sum)\nprint(f\"Resta: 20 - 8 = {20 - 8}\")\nprint(f\"Multiplicación: 6 * 6 = {6 * 6}\")\nprint(f\"División: 20 / 7 = {20 / 7}\")\nprint(f\"Módulo: 20 % 7 = {20 % 7}\")\nprint(f\"Exponente: 2 ** 4 = {2 ** 4}\")\nprint(f\"División Entera: 20 // 7 = {20 // 7}\")\n\n# Operadores de comparación // devuelve un valor True o False\nprint(f\"Igual a: 10 == 3 es {10 == 3}\")\nprint(f\"No es igual: 10 != 3 es {10 != 3}\")\nprint(f\"Es mayor que: 10 > 3 es {10 > 3}\")\nprint(f\"Es menor que: 10 < 3 es {10 < 3}\")\nprint(f\"Es mayor o igual que: 10 >= 10 es {10 >= 10}\")\nprint(f\"Es menor o igual que: 10 <= 8 es {10 <= 8}\")\n\n# Operadores lógicos\nprint(f\"AND: 10 + 3 == 13 and 5 -1 == 4 es: {10 + 3 == 13 and 5 -1 == 4}\")\nprint(f\"OR: 10 + 9 == 16 and 5 -1 == 4 es: {10 + 9 == 16 or 5 -1 == 4}\")\nprint(f\"NOT: 20 + 7 == 24 es: {not 20 + 7 == 24}\")\n\n# Operadores de asigmación\nmi_numero = 12 # = asignación\nprint(f\"Mi número es: {mi_numero}\")\nmi_numero += 5 # + suma y asignación\nprint(mi_numero)\nmi_numero -= 5 # - resta y asignación\nprint(mi_numero)\nmi_numero *= 5 # * multiplicación y asignación\nprint(mi_numero)\nmi_numero /= 4 # / división y asignación\nprint(mi_numero)\nmi_numero %= 2 # % módulo y asignación\nprint(mi_numero)\nmi_numero **= 8 # ** exponente y asignación\nprint(mi_numero)\nmi_numero //= 12 # división exacta y asignación \nprint(mi_numero)\n\n# Operadores de identidad\nmi_nuevo_numero = 0.0 # mismo valor numérico, distinta posición en memoria\nprint(f\"mi_numero is mi_nuevo_numero es: {mi_numero is mi_nuevo_numero}\")\nmi_nuevo_numero = mi_numero # misma posición en memoria\nprint(f\"mi_numero is mi_nuevo_numero es: {mi_numero is mi_nuevo_numero}\")\nprint(f\"mi_numero is not mi_nuevo_numero es: {mi_numero is not mi_nuevo_numero}\")\n\n# Operadores de pertenencia\nprint(f\" 'a' está en 'mendoza' = 'a' in 'mendoza' = {'a' in 'mendoza'}\")\nprint(f\" 'b' no está en 'mendoza' = 'a' not in 'mendoza' = {'b' not in 'mendoza'}\")\n\n# Operadores de bit\na = 10 # 1010\nb = 3 # 0011\nprint(f\"AND: 10 & 3 = {10 & 3}\") # 0010\nprint(f\"OR: 10 & 3 = {10 | 3}\") # 1011\nprint(f\"XOR: 10 & 3 = {10 ^ 3}\") # 1001\nprint(f\"NOT: ~10  = {~10}\") # 1001 \nprint(f\"Desplazamiento a la derecha: 10 >> 2 = {10 >> 2}\") # 0010\nprint(f\"Desplazamiento a la izquierda: 10 << 2 = {10 << 2}\") # 101000\n\n\"\"\"\nEstrucuras de Control\n\"\"\"\n\n# Condicionales\n\nmi_cadena = \"AndresMendoza\"\nif mi_cadena == \"AndresMendoza\":\n    print(\"mi_cadena es 'AndresMendoza'\")\nelif mi_cadena == \"Figueroa\":\n    print(\"mi_cadena es 'Figueroa'\")\nelse:\n    print(\"mi_cadena no es ni 'AndresMendoza' ni tampoco 'Figueroa'\")\n\n# Iterativas\n\nfor i in range(11):\n    print(i) #imprimirá de 0 a 10\n\nx = 0\n\nwhile x <= 10:\n    print(x)\n    x += 1 #imprimirá de 0 a 10\n\n# Manejo de excepciones\ntry:\n    print(10/0)\nexcept:\n    print(\"Se ha producido un error\")\nfinally:\n    print(\"Ha finalizado el control de excepciones\")\n\n\"\"\"\nEjercicio extra\n\"\"\"\n\nfor i in range(10,56):\n    if i%2 == 0 and i != 16 and i%3 != 0:\n        print(i, end= '-')"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/angelsanchezt.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\"\"\"\n\n# Operadores\n# Aritméticos\nresultado_aritmetico = 10 + 5 * 2\nprint(f'Aritmético: {resultado_aritmetico}')\n\n# Lógicos\nvalor_logico = True and False\nprint(f'Lógico: {valor_logico}')\n\n# De comparación\ncomparacion = 5 > 3\nprint(f'Comparación: {comparacion}')\n\n# De asignación\nvariable_asignacion = 42\nprint(f'Asignación: {variable_asignacion}')\n\n# De identidad\na = [1, 2, 3]\nb = [1, 2, 3]\nidentidad = a is b\nprint(f'Identidad: {identidad}')\n\n# De pertenencia\nlista = [1, 2, 3]\npertenencia = 2 in lista\nprint(f'Pertenencia: {pertenencia}')\n\n# Bits\noperacion_bits = 5 & 3\nprint(f'Bits: {operacion_bits}')\n\n# Estructuras de control\n# Condicionales\nif resultado_aritmetico > 20:\n    print(\"El resultado es mayor que 20\")\nelif resultado_aritmetico == 20:\n    print(\"El resultado es igual a 20\")\nelse:\n    print(\"El resultado es menor que 20\")\n\n# Iterativas\nfor i in range(10, 56):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print(f'Número válido: {i}')\n\n# Excepciones\ntry:\n    resultado_division = 10 / 0\nexcept ZeroDivisionError:\n    print(\"¡Error! División por cero.\")\nelse:\n    print(f'Resultado de la división: {resultado_division}')\nfinally:\n    print(\"Operación completa.\")\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/annnerssv.py",
    "content": "# OPERADORES\n\n#----OPERADORES ARITMETICOS----\n# ---- SUMA ----\nsum = 10 + 13\nprint(f'La suma de 10 + 13 = {sum}')\n# ---- RESTA ----\nresta = 10 - 13\nprint(f'La resta de 10 - 13 = {resta}')\n# ---- MULTIPLICACION ----\nmultiplicacion = 10 * 13\nprint(f'La multiplicacion de 10 * 13 = {multiplicacion}')\n# ---- DIVISION ----\ndivision = 10 / 13  \nprint(f'La division de 10 / 13 = {division}')\n# ---- DIVISION ENTERA ----\ndivision_entera = 10 // 13  \nprint(f'La division entera de 10 // 13 = {division_entera}')    \n# ---- MODULO ----\nmodulo = 10 % 13      \nprint(f'El modulo de 10 % 13 = {modulo}')\n# ---- POTENCIA ----\npotencia = 10 ** 3 \nprint(f'La potencia de 10 ** 3 = {potencia}')\n\n#OPERADORES DE COMPARACION\n# ---- IGUAL ----\nprint(f'Igualdad: 10 == 13 = {10 == 13}')\n# ---- DISTINTO ----\nprint(f'Distinto: 10 != 13 = {10 != 13}')\n# ---- MAYOR ----\nprint(f'Mayor: 10 > 13 = {10 > 13}')\n#  ---- MENOR ----\nprint(f'Menor: 10 < 13 = {10 < 13}')\n# ---- MAYOR O IGUAL ----\nprint(f'Mayor o igual: 10 >= 13 = {10 >= 13}')\n# ---- MENOR O IGUAL ----\nprint(f'Menor o igual: 10 <= 13 = {10 <= 13}')\n\n#OPERADORES LOGICOS\n# ---- AND ----\nprint(f'AND &&: 10 + 3 == 12 and 5 - 4 == 1  = {10 + 3 == 12 and 5 - 4 == 1}')\n# ---- OR ----\nprint(f'OR ||: 10 + 3 == 13 and 5 - 4 == 1 = {10 + 3 == 13 or 5 - 4 == 1}')\n# ---- NOT ----\nprint(f'NOT !: not 10 + 3 == 14 = {not 10 + 3 == 14}')\n\n# OPERADORES DE ASIGNACION\n# ---- ASIGNACION ----\nx = 10\nprint(f'Asignacion: x = 10 = {x}') \n# ---- ADICION DE VALORES DE UNA VARIABLE ----\nx += 5\nprint(f'Adicion: x += 5 = {x}')\n# ---- RESTA DE VALORES DE UNA VARIABLE----\nx -= 5\nprint(f'Resta: x -= 5 = {x}')\n# ---- MULTIPLICACION DE VALORES DE UNA VARIABLE----\nx *= 5\nprint(f'Multiplicacion: x *= 5 = {x}')\n# ---- DIVISION DE VALORES DE UNA VARIABLE----\nx /= 5\nprint(f'Division: x /= 5 = {x}')\n# ---- DIVISION ENTERA DE VALORES DE UNA VARIABLE----\nx //= 5\nprint(f'Division entera: x //= 5 = {x}')\n# ---- MODULO DE VALORES DE UNA VARIABLE----\nx %= 5\nprint(f'Modulo: x %= 5 = {x}')\n# ---- POTENCIA DE VALORES DE UNA VARIABLE----\nx **= 5\nprint(f'Potencia: x **= 5 = {x}')\n\n#  OPERADORES DE IDENTIDAD\nnew_x = x\n# ---- IS ----\nprint(f'Is: x is new_x = {x is new_x}')\n# ---- IS NOT ----\nprint(f'Is not: x is not new_x = {x is not new_x}')\n\n# OPERADORES DE PERTENENCIA\n# ---- IN ----\nprint(f'In: \"a\" in \"Annerssv\" = {\"a\" in \"Annerssv\"}')\nprint(f'In: \"a\" not in \"Annerssv\" = {\"a\" not in \"Annerssv\"}')\n\n# OPERADORES DE BIT\na = 10 #1010 \nb = 3 #0011\n\n# ---- AND ----\nprint(f'AND: 10 & 13 = {10 & 13}') #0010\n# ---- OR ----\nprint(f'OR: 10 | 13 = {10 | 13}') #1011\n# ---- XOR ----\nprint(f'XOR: 10 ^ 13 = {10 ^ 13}') #1001\n# ---- NOT ----\nprint(f'NOT: ~10 = {~10}')\n# ---- DESPLAZAMIENTO A LA DERECHA ----\nprint(f'Desplazamiento a la derecha: 10 >> 13 = {10 >> 2}') #0010\n# ---- DESPLAZAMIENTO A LA IZQUIERDA ----\nprint(f'Desplazamiento a la izquierda: 10 << 13 = {10 << 2}') #101000\n\n\n\n#ESTRUCUTURAS DE CONTROL\n\n#SENTENCIAS CONDICIONALES\n\nmi_cadena = 'Annerssv'\n\nif mi_cadena == 'Annerssv':\n    print('Mi cadena es \"Annerssv\"')\nelif mi_cadena == 'Pier':\n    print('Mi cadena es \"Pier\"')\nelse:\n    print('Mi cadena no es \"Annerssv\" ni \"Pier\"')\n\n\n# BUCLES\n\n# ---- FOR ----\nfor i in range(10):\n    print(i)\n\n# ---- WHILE ----\ncontador = 0\n\nwhile contador < 10:\n    print(contador)\n    contador += 1   \n\n# MANEJO DE EXCEPCIONES\n\ntry:\n    print(10 / 0)\n\nexcept:\n    print('No se puede dividir entre 0')\n\nfinally:\n    print('Se ha ejecutado el manejo de errores')\n\n\n# RETO EXTRA\n\nfor number in range(10, 56):\n    if number % 2 == 0 and number != 16 and number % 3 != 0:\n        print(number)\n        \n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/ansuzgs.py",
    "content": "# Operatdores\n\n# Aritméticos\nprint(f\"Suma: 2 + 2 = {2 + 2}\")\nprint(f\"Resta: 2 - 2 = {2 - 2}\")\nprint(f\"Multiplicacion: 2 * 2 = {2 * 2}\")\nprint(f\"Division: 2 / 2 = {2 / 2}\")\nprint(f\"Modulo: 2 % 2 = {2 % 2}\")\nprint(f\"Exponente: 2 ** 2 = {2 ** 2}\")\nprint(f\"Division entera: 2 // 2 = {2 // 2}\")\n\n# Comparación\nprint(f\"Igual: 2 == 2 es {2 == 2}\")\nprint(f\"Diferente: 2 != 2 es {2 != 2}\")\nprint(f\"Mayor que: 2 > 2 es {2 > 2}\")\nprint(f\"Menor que: 2 < 2 es {2 < 2}\")\nprint(f\"Mayor o igual que: 2 >= 2 es {2 >= 2}\")\nprint(f\"Menor o igual que: 2 <= 2 es {2 <= 2}\")\n\n# Lógicos\nprint(f\"And: True and True es {True and True}\")\nprint(f\"Or: True or False es {True or False}\")\nprint(f\"Not: not True es {not True}\")\nprint(f\"Xor: True ^ False es {True ^ False}\")\n\n# Asignación\na = 5\nprint(f\"Asignación: a = 2, a es {a}\")\na += 2\nprint(f\"Suma: a += 2, a es {a}\")\na -= 2\nprint(f\"Resta: a -= 2, a es {a}\")\na *= 2\nprint(f\"Multiplicación: a *= 2, a es {a}\")\na /= 2\nprint(f\"División: a /= 2, a es {a}\")\na %= 2\nprint(f\"Módulo: a %= 2, a es {a}\")\na **= 2\nprint(f\"Exponente: a **= 2, a es {a}\")\na //= 2\nprint(f\"División entera: a //= 2, a es {a}\")\n\n# Identidad\nprint(f\"Es: 2 is 2 es {2 is 2}\")\nprint(f\"No es: 2 is not 2 es {2 is not 2}\")\n\n# Pertenencia\nprint(f\"Está: 'a' in 'hola' es {'a' in 'hola'}\")\nprint(f\"No está: 'a' not in 'hola' es {'a' not in 'hola'}\")\n\n# Binarios\nprint(f\"And binario: 0b100 & 0b110 es {0b100 & 0b110}\")\nprint(f\"Or binario: 0b100 | 0b110 es {0b100 | 0b110}\")\nprint(f\"Xor binario: 0b100 ^ 0b110 es {0b100 ^ 0b110}\")\nprint(f\"Desplazamiento izquierda: 0b100 << 2 es {0b100 << 2}\")\nprint(f\"Desplazamiento derecha: 0b100 >> 2 es {0b100 >> 2}\")\n\n# Estructuras de control\n\n# If\na = 5\nif a == 5:\n    print(f\"a es {a}\")\nelif a == 3:\n    print(f\"a es {a}\")\nelse:\n    print(f\"a no es 5 ni 3\")\n\n# While\na = 0\nwhile a < 5:\n    print(f\"a es {a}\")\n    a += 1\n\n# For\nfor a in range(5):\n    print(f\"a es {a}\")\n\n# Break\na = 0\nwhile True:\n    if a == 5:\n        break\n    print(f\"a es {a}\")\n    a += 1\n\n# Continue\nfor a in range(5):\n    if a == 2:\n        continue\n    print(f\"a es {a}\")\n\n# Excepciones\ntry:\n    a = 5 / 0\nexcept ZeroDivisionError:\n    print(\"No se puede dividir por 0\")\n\n# Extra\nfor number in range(10, 56):\n    if number % 2 == 0 and number != 16 and number % 3 != 0:\n        print(number)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/antii16.py",
    "content": "'''\nCrea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\nAritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n'''\n# OPERADORES\n# Aritméticos\nn1 = 10\nn2 = 2\nprint('ARITMÉTICOS')\nprint(f'Suma -> 2+10= {n2+n1}')\nprint(f'Resta -> 10-2= {n1-n2}')\nprint(f'Multiplicación -> 2*10= {n2*n1}')\nprint(f'División -> 10/2= {n1/n2}')\nprint(f'Módulo -> 10%2= {n1%n2}')\nprint(f'Potencia -> 10**2= {n1**n2}')\nprint(f'División con número entero -> 10//2= {n1//n2}')\n\n# Lógicos\nprint('')\nprint('LÓGICOS')\nprint(f'AND -> {n1==10 and n2==10}')\nprint(f'OR -> {n1==10 or n2==10}')\nprint(f'NOT -> {not n1==10}')\n\n# Comparación\nprint('')\nprint('COMPARACIÓN')\nprint(f'10>2 -> {n1>n2}')\nprint(f'10<2 -> {n1<n2}')\nprint(f'10>=2 -> {n1>=n2}')\nprint(f'10<=2 -> {n1<=n2}')\nprint(f'10!=2 -> {n1!=n2}')\n\n# Asignación\nprint('')\nprint('ASIGNACIÓN')\nn1 += n2\nprint(f'n1 += n2 -> {n1}')\nn1 -= n2\nprint(f'n1 -= n2 -> {n1}')\nn1 *= n2\nprint(f'n1 *= n2 -> {n1}')\nn1 /= n2\nprint(f'n1 /= n2 -> {n1}')\nn1 %= 4\nprint(f'n1 %= n2 -> {n1}')\nn1 //= n2\nprint(f'n1 //= n2 -> {n1}')\nn1 **= n2\nprint(f'n1 **= n2 -> {n1}')\n\n# Identidad\nprint('')\nprint('IDENTIDAD')\nprint(f'n1 is n2 -> {n1 is n2}')\nprint(f'n1 is not n2 -> {n1 is not n2}')\n\n# Pertenencia\nfrase = 'Hola, Mundo'\npalabra = 'Mundo'\nprint(f'¿\"{palabra}\" está en \"{frase}\" ? {palabra in frase}')\n\n# A nivel de bits\nprint('')\nprint('A NIVEL DE BITS')\nx = 4 #0100\ny = 2 #0010\nprint(f'& -> x & y = {x&y}')\nprint(f'| -> x | y = {x|y}')\nprint(f'~ -> x ~ y = {~y}')\nprint(f'^ -> x ^ y = {x^y}')\nprint(f'>> -> x >> y = {x>>y}')\nprint(f'<< -> x << y = {x<<y}')\n\n'''\nUtilizando las operaciones con operadores que tú quieras, crea ejemplos\nque representen todos los tipos de estructuras de control que existan\nen tu lenguaje:\nCondicionales, iterativas, excepciones...\n'''\n# Condicionales\nprint('')\nprint('CONDICIONALES')\n\ncolor = 'amarillo'\nif color == 'azul':\n    print('El color es azul')\nelif color == 'rojo':\n    print('Pues a lo mejor es de color rojo')\nelse:\n    print('No queda otra, el color es amarillo')\n\n# Iterativas\nprint('')\nprint('ITERATIVAS')\nprint('WHILE')\nn = 0\nwhile n != 5:\n    print(n)\n    n+=1\n\nprint('')\nprint('FOR')\nnombre = 'Lolito'\nfor letra in nombre:\n    print(letra)\n\nprint('')\nprint('range(fin)')\nfor i in range(10):\n    print(i)\nprint('range(inicio, fin)')\nfor i in range(5,10):\n    print(i)\nprint('range(inicio, fin, salto)')\nfor i in range(1,20, 2):\n    print(i)\n\n\n# EXCEPCIONES\nprint('')\nprint('EXCEPCIONES')\na = 4\nb = 0\n\ntry: \n    a/b\nexcept ZeroDivisionError:\n    print('No se puede dividir por 0')\nfinally:\n    print('Fin')\n\n'''\nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n'''\n\n# DIFICULTAD EXTRA\nprint('')\nprint('DIFICULTAD EXTRA')\nfor n in range(10, 56):\n    if n%2 == 0 and n != 16 and n%3 != 0:\n        print(n)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/antoniosuero.py",
    "content": "#  * EJERCICIO:\n#  * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n#  *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n#  *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n#  * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n#  *   que representen todos los tipos de estructuras de control que existan\n#  *   en tu lenguaje:\n#  *   Condicionales, iterativas, excepciones...\n#  * - Debes hacer print por consola del resultado de todos los ejemplos.\n#  *\n\n\n# OPERADORES ARITMÉTICOS\nprint(\"\\nOPERADORES ARITMÉTICOS: \")\nprint(\"Suma +\\n5 + 2 =\", 5 + 2)\nprint(\"Resta -\\n5 - 2 =\", 5 - 2)\nprint(\"Multiplicacíón *\\n5 * 2 =\", 5 * 2)\nprint(\"División /\\n5 / 2 =\", 5 / 2)\nprint(\"División entera //\\n5 // 2 =\", 5 // 2)\nprint(\"Módulo % (Residuo de la división)\\n5 % 2 =\", 5 % 2)\nprint(\"Exponente **\\n5 ** 2=\", 5 ** 2)\n\n# OPERADORES DE COMPARACIÓN\nprint(\"\\nOPERADORES DE COMPARACIÓN: \")\nprint(\"igual que ==\\n5 == 2 =\", 5 == 2)\nprint(\"diferente que !=\\n5 != 2 =\", 5 != 2)\nprint(\"mayor que >\\n 5 > 2 =\", 5 > 2)\nprint(\"menor que >\\n 5 < 2 =\", 5 < 2)\nprint(\"mayor o igual que >=\\n 5 >= 2 =\", 5 >= 2)\nprint(\"menor o igual que <=\\n 5 <= 2 =\", 5 <= 2)\n\n# OPERADORES LÓGICOS\nprint(\"\\nOPERADORES LÓGICOS: \")\nprint(\"y lógico: and\\nTrue and False =\", True and False)\nprint(\"o lógico: or\\nTrue or False =\", True or False)\nprint(\"no lógico: not\\nnot False =\", not False)\n\n# OPERADORES DE ASIGNACIÓN\nprint(\"\\nOPERADORES DE ASIGNACIÓN: \")\nj = 1\nprint(\"asignación =\\nj = 1\")\nj += 1\nprint(\"incremento +=\\nj += 1, j =\", j)\nj -= 1\nprint(\"decremento -=\\nj -= 1, j =\", j)\nj *= 4\nprint(\"multiplicación y asignación *=\\nj *= 4, j =\", j)\nj /= 2\nprint(\"división y asignación /=\\nj /= 2, j =\", j)\nj **= 2\nprint(\"exponente y asignación **=\\nj **= 2, j =\", j)\nj //= 3\nprint(\"división entera y asignación //=\\nj //= 3, j =\", j)\nj %= 1\nprint(\"módulo y asignación %=\\nj %= 1, j =\", j)\n\n# OPERADORES DE IDENTIDAD\nprint(\"\\nOPERADORES DE IDENTIDAD (is - is not): \")\na = [1, 2, 3]\nb = a\nc = [1, 2, 3]\nprint(f\"a = {a}\\nb = a\\nc = {c}\")\nprint(\"Es la misma identidad: a is b =\", a is b)\nprint(\"Es la misma identidad: a is c =\", a is c)\nprint(\"No es la misma identidad: a is not c =\", a is not c)\n\n# OPERADORES DE PERMANENCIA\nprint(\"\\nOPERADORES DE PERMANENCIA (in - not in): \")\ntexto = \"Campus MoureDevpro\"\nprint(\"texto = \\\"Campus MoureDevpro\\\"\")\nprint(\"Campus in texto =\", \"Campus\" in texto)\nprint(\"Mundo in texto =\", \"Mundo\" in texto)\nprint(\"Mundo not in texto =\", \"Mundo\" not in texto)\n\n# OPERADORES BIT A BIT O NIVEL DE BITS\nprint(\"\\nOPERADORES BIT A BIT: \")\nx = 12  # 0b1100\ny = 6  # 0b0110\nprint(f\"x = {x} # 1100\\ny = {y}  # 0110\")\nprint(\"AND (&) 1 si ambos bits son 1\\nx & y =\", x & y, \"   # 0100\")\nprint(\"OR (|) 1 si al menos un bit es 1\\nx | y =\", x | y, \"  # 1110\")\nprint(\"XOR (^) 1 si los bits son diferentes\\nx ^ y =\", x ^ y, \"  # 1100\")\nprint(\"NOT (~) Invierte los bits\\n~x =\", ~x,\"    # 0011 complemento a 2\")\nprint(\"<< Desplazamiento a la izquierda cada desplazamiento multiplica por 2\\nx << 1 =\", x << 1, \" # 11000\")\nprint(\">> Desplazamiento a la derecha cada desplazamiento divide entre 2\\nx >> 1 =\", x >> 1, \"  # 1100\")\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea un programa que imprima por consola todos los números comprendidos\n#  * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n#  *\n#  * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\nfor numero in range(10, 56):\n  if numero == 16 or numero % 3 == 0 or numero % 2 != 0:\n    continue\n  print(numero)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/any7dev.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */ \"\"\"\n\nx = 5\ny = 3\nverdadero = True\nfalso = False\na = 0b0001\nb = 0b1010\ntexto = \"Esto es una cadena\"\nnumero = 10\n\n# OPERADORES\n\n# Operadores aritméticos\nsuma = x + y\nprint(suma)\n\nresta = x - y\nprint(resta)\n\nmultiplicacion = x * y\nprint(multiplicacion)\n\ndivision = x / y \nprint(division)\n\nmodulo = x % y\nprint(modulo)\n\nexponente = x ** y\nprint(exponente)\n\ncociente = x // y\nprint(cociente)\n\n# Operadores de asignación\nx = 7\nprint(x)\n\nx += 2\nprint(x)\n\nx -=  3\nprint(x)\n\nx *= 5\nprint(x)\n\nx /= 4\nprint(x)\n\nx %= 2\nprint(x)\n\ny //= 2\nprint(y)\n\nx **= 3\nprint(x)\n\n# Operadores lógicos\nprint(verdadero and  falso)\n\nprint(verdadero or falso)\n\nprint(verdadero and falso or verdadero)\n\nprint(verdadero or falso and falso)\n\nprint(not verdadero)\n\n# Operadores de comparación\nprint(x==y)\n\nprint(x!=y)\n\nprint(x<y)\n\nprint(x>y)\n\nprint(x<=y)\n\nprint(x>=y)\n\n# Operadores de identidad\nprint(y is x)\n\nprint(x is not y)\n\n# Operadores de bit\nprint(bin(a&b))\n\nprint(bin(a|b))\n\nprint(bin(~a))\n\nprint(bin(a^b))\n\nprint(bin(a>>2))\n\nprint(bin(a<<1))\n\n# Operadores de membresía\nprint(7 in [1, 2, 4, 8, 7])\n\nprint(4 not in (6, 1, 0, 3, 4))\n\n\n# ESTRUCTURAS DE CONTROL\n\n# If\nif a != b:\n    print(a)\n# If y else\nif a == b:\n    print(\"Iguales\")\nelse:\n    print(\"No iguales\") # Se puede esxcribir en una sóla línea de código -> print(\"Iguales\" if a==b else \"No iguales\")\n# If, elif y else\nif x > y:\n    print(\"Mayor x\")\nelif x < y:\n    print(\"Mayor y\")\nelse:\n    print(\"Iguales\")\n\n# Match y case\nanimal = \"perro\"\nmatch animal:\n    case \"perro\": \n        print(\"Es un perro\")\n    case \"gato\": \n        print(\"Es un gato\")\n    case \"pájaro\":\n        print(\"Es un pájaro\")\n    case _:\n        print(\"Animal indeterminado\")\n\n# For\nfor i in range(0, 10):\n    print(i)\n\nfor i in range(0, 10, 2):\n    print(i)\n\nfor i in \"Cadena\":\n    print(i)\n\nfor i in texto[::-1]:\n    print(i)\n\nfor i in texto[::2]:\n    print(i)\n# For y break\nfor caracter in texto:\n    if caracter == \"d\":\n        print(\"Letra D encontrada\")\n        break\n# For y continue\nfor caracter in texto:\n    if caracter == \"d\":\n        continue\n    print(caracter)\n\n# For, break, continue y pass\nfor caracter in texto:\n    if caracter == \"e\":\n        print(\"3\")\n    elif caracter == \"a\":\n        print(\"Paso\")\n        pass\n    elif caracter == \"d\":\n        break\n    elif caracter == \"n\":\n        print(\"Vuelvo a empezar\")\n        continue \n    else:\n        print(caracter)\n\n# While\ni = 0\nwhile i < 11:\n    print(i)\n    i += 1\n# While y else\ni = 0\nwhile i < 11:\n    print(i)\n    i += 1\nelse:\n    print(\"i mayor que 10\")\n# While y break\ni = 0\nwhile i < 11:\n    print(i)\n    i += 1\n    if i == 8:\n        break\n# While y continue\ni = 0\nwhile i < 11:\n    i += 1\n    if i == 8:\n        continue\n    print(i)\n\n# While, break, continue y pass\ni = 0\nwhile i < 11:\n    i += 1\n    if i == 5:\n        print(\"Paso\")\n        pass\n    elif i == 2:\n        print(\"Vuelvo a empezar\")\n        continue\n    elif i == 10:\n        break\n    else: \n        print(i)\n\n# Excepciones\ntry:\n    for j in range(4,-4,-1):\n        print(numero/j)\nexcept ZeroDivisionError:\n    print(\"No se puede dividir entre 0\")\nfinally:\n    print(\"Esto se ejecuta siempre\")\n\n\n# DIFICULTAD EXTRA\nfor i in range(10, 56, 2):\n    if i != 16 and i % 3 != 0:\n        print(i)\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/arkmiguel379.py",
    "content": "#Operadores aritmericos\n\nnum1 = 5\nnum2 = 2\n\nsuma = num1 + num2 #Operacion de suma\nresta = num1 - num2 #Operacion de resta\nmultiplicacion = num1 * num2 #Operacion de multiplicacion\ndivision = num1 / num2 #Operacion de division\nmodulo = num1 % num2 #Operacion de residuo de una division\ndivision_entera = num1 // num2 # El resultado de la division es un numero entero\npotencia = num1 ** num2 #Potenciación\n\nprint(suma)\nprint(resta)\nprint(multiplicacion)\nprint(division)\nprint(modulo)\nprint(division_entera)\nprint(potencia)\n\nprint(\"\\n\")\n\n#Operadores de comparacion\n\nigual = num1 == num2 #Valor A igual que valor B\ndiferente = num1 != num2 #Valor A diferente de valor B\nmayor = num1 > num2 #Valor A mayor que valor B\nmenor = num1 < num2 #Valor A menor que valor B\nmayor_igual = num1 >= num2 #Valor A mayor o igual que valor B\nmenor_igual = num1<= num2 #Valor A menor o igual que valor B\n\nprint(igual)\nprint(diferente)\nprint(mayor)\nprint(menor)\nprint(mayor_igual)\nprint(menor_igual)\n\nprint(\"\\n\")\n\n#Operadores logicos\n\nop_and = (num1 == num2) and (num1 > num2) #Operador Y (Se tienen que cumplir las dos condiciones para que el valor sea true)\nop_or = (num1 == num2) or (num1 > num2) #Operador O (Se tiene una de las dos condiciones para que el valor sea true)\nop_not = not (num1 == num2) == (num1 > num2) #Operador NO (El valor es el contrario al que realmente es)\n\nprint(op_and)\nprint(op_or)\nprint(op_not)\n\nprint(\"\\n\")\n\n# Operadores de asignacion\n\nx = 10\n\nx += 3 #El valor de x se suma con 3\nprint(x)\n\nx -= 3 #El valor de x se resta con 3\nprint(x)\n\nx *= 3 #El valor de x se multiplica con 3\nprint(x)\n\nx /= 3 #El valor de x se divide con 3\nprint(x)\n\nx //= 3 #El residuo de la division es un numero entero\nprint(x)\n\nx %= 3 #El valor dado es el residuo de la division de x entre 3\nprint(x)\n\nx **= 3 #El valor de x se potencia en 3\nprint(x)\n\nprint(\"\\n\")\n\n# Operadores de pertenencia\n\nnombre = \"Miguel Angel Moreno\"\nprint('o' in nombre) # Verifica si un valor está presente en una secuencia, como una lista, cadena, etc.\nprint('o' not in nombre) # Verifica si un valor no está presente en una secuencia.\n\n# Operadores de identidad\n\nmy_number1 = 257\nmy_number2 = 379\n\nif my_number1 is my_number2: # IS: Verifica si dos variables son la misma instancia de objeto\n    print(\"Son el mismo numero\")\nelse:\n    print(\"No son el mismo numero\")\n\nif my_number1 is not my_number2: # IS NOT: Verifica si dos variables no son la misma instancia de objeto\n    print(\"No son el mismo numero\")\nelse:\n    print(\"Son el mismo numero\")\n\nprint(\"\\n\")\n\n#Estructuras condicionales\n\nif num1 == num2:\n    print(f\"{num1} es igual que {num2}\")\n\nelif num1 > num2:\n    print(f\"{num1} es mayor que {num2}\")\n\nelif num1 < num2:\n    print(f\"{num1} es menor que {num2}\")\n\nelif num1 != num2:\n    print(f\"{num1} es diferente de {num2}\")\n\nprint(\"\\n\")\n\n# Estructuras iterativas\n\nwhile num1 > num2:\n    print(f\"Num2 ha aumentado su valor en 1, su valor ahora es {num2 + 1}\")\n    num2 += 1\n\nprint(\"\\n\")\n\ncontador = 0\n\nwhile True:\n    print(\"Codigo que se ejecuta el menos una vez\")\n    contador += 1\n\n    if contador > 3:\n        break\n\nprint(\"\\n\")\n\n# Control de excepciones\n\ntry:\n    print(65 + \"Cadena\")\nexcept:\n    print(\"Se ha producido un error\")\nfinally:\n    print(\"El control de excepciones ha finalizado\")\n\n\n# ======================== EXTRA ===========================\n\nfor i in range(10, 56):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print(i)\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/augustdev2003.py",
    "content": "\"\"\"\nOperadores\n\"\"\"\n\n# Aritméticos\n\nprint(f'Suma -> 10 + 5 = {10 + 5}')  # Adición\nprint(f'Resta -> 10 - 5 = {10 - 5}')  # Sustracción\nprint(f'Multiplicación -> 10 * 5 = {10 * 5}')  # Multiplicación\nprint(f'División -> 10 / 5 = {10 / 5}')  # División\nprint(f'Módulo -> 10 % 5 = {10 % 5}')  # Módulo\nprint(f'Exponente -> 10 ** 5 = {10 ** 5}')  # Exponenciación\nprint(f'División entera -> 10 // 5 = {10 // 5}')  # División entera\n\n# Asignación\n\nx = 0\nprint(f'Valor asignado: {x}')\n\nx += 10\nprint(f'Suma y asignación: {x}')\n\nx -= 5\nprint(f'Resta y asignación: {x}')\n\nx *= 10\nprint(f'Multiplicación y asignación: {x}')\n\nx /= 5\nprint(f'División y asignación: {x}')\n\nx %= 1\nprint(f'Módulo y asignación: {x}')\n\nx **= 2\nprint(f'Exponente y asignación: {x}')\n\n# Comparación\n\nprint(f'Igualdad: 10 == 3 -> {10 == 3}')\nprint(f'Desigualdad: 10 != 3 -> {10 != 3}')\nprint(f'Mayor que: 10 > 3 -> {10 > 3}')\nprint(f'Menor que: 10 < 3 -> {10 < 3}')\nprint(f'Mayor o igual que: 10 >= 3 -> {10 >= 3}')\nprint(f'Menor o igual que: 10 <= 3 -> {10 <= 3}')\n\n# Lógicos\n\nprint('and: Este operador devuelve True si ambas comparaciones son True, de lo contrario devolverá False')\nprint(f'10 == 3 and 10 != 3 -> {10 == 3 and 10 != 3}\\n')\n\nprint('''or: Este operador devuelve True si al menos una de las comparaciones es True,\nen caso de que ambas comparaciones sean False, devolverá False''')\nprint(f'10 == 3 or 10 != 3 -> {10 == 3 or 10 != 3}')\n\nprint('''not: Sirve para negar(invertir) el valor de una comparación booleana.\nEn el caso de que una comparación esté evaluada en True, este operador hará que evalue en False, y viceversa.''')\nprint(f'10 != 3 and not 10 == 3 -> {10 != 3 and not 10 == 3}')\n\n# Identidad\n\nx = True\ny = False\n\n# Devuelve True si ambas variables son el mismo objeto\nprint(f'x is y -> {x is y}')\n# Devuelve True si ambas variables no son el mismo objeto\nprint(f'x is not y -> {x is not y}')\n\n# Pertenencia\n\nlista = [1, 32, 7, 10]\n# Devuelve True si el dato especificado se encuentra dentro del objeto\nprint(f'32 in lista {32 in lista}')\n# Devuelve True si el dato especificado no se encuentra dentro del objeto\nprint(f'2 not in lista {2 not in lista}')\n\n\"\"\"\nEstructuras de control\n\"\"\"\n\n# Condicionales\n\nnombre = 'Juan'\n\nif nombre == \"Juan\":\n    print(f'Tu nombres es {nombre}')\nelif nombre == 'Pedro':\n    print(f'Tu nombre es {nombre}')\nelse:\n    print('Tu nombre no es Juan ni Pedro')\n\n# Iterativas\n\nfor x in range(16):\n    print(x)\n\nlista = ['Mouredev', 'Juan', 'Pedro', 'Chanchito']\nfor name in lista:\n    print(name)\n\ndiccionario = {'nombre': 'Lucas', 'profesion': 'Médico'}\nfor clave, valor in diccionario.items():\n    print(f'{clave} : {valor}')\n\nx = 0\n\nwhile x <= 10:\n    print(x)\n    x += 1\n\n# Excepciones\n\ntry:\n    print(1 / 0)\nexcept:\n    print(\"Se produjo un error\")\nfinally:\n    print(\"Terminó el manejo de expeciones\")\n\n\"\"\"Ejercicio extra\"\"\"\n\nfor num in range(10, 56):\n    if num % 2 == 0 and num != 16 and num % 3 != 0:\n        print(num)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/avcenal.py",
    "content": "### OPERADORES Y ESTRUCTURAS DE CONTROL ###\n\n#AUTOR: avcenal\n\n#Aritméticos\nprint(\"\\n\")\nprint (\"Operadores De Aritméticos\")\nprint(5 + 2)\nprint(5 - 2)\nprint(5 * 2)\nprint(5 / 2)\nprint(5 % 2)\nprint(5 // 2) #floor division\nprint(2 ** 2) #potencia\n\n#Aritméticos en cadenas\nprint(\"\\n\")\nprint (\"Operadores De Aritméticos en cadenas\")\nprint (\"Hola \" + \"mundo\")\nprint (\"Hola\" * 5)\nprint (\"Hola\" * int(2.5*2))\nprint(\"Hola\" * (2 ** 2))\n\n#Comparación\nprint(\"\\n\")\nprint (\"Operadores De Comparación\")\nprint(3 > 4)\nprint(3 < 4)\nprint(3 >= 4)\nprint(3 <= 4)\nprint(3 == 3)\nprint(3 != 4)\n\n#Lógicos\nprint(\"\\n\")\nprint (\"Operadores Lógicos\")\nprint (3 > 4 and 5 < 7)\nprint (3 > 4 or 5 < 7)\nprint (not 3 > 4)\n\n#Pertenencia: comprueba si el valor está dentro de una estructura\nprint(\"\\n\")\nprint (\"Operadores De Pertenencia\")\nmy_tuple = (38,25,3)\nprint (35 in my_tuple)\nprint (78 not in my_tuple)\n\n#Identidad: sirven para comprobar si dos variables emplean la misma ubicación de memoria\nprint(\"\\n\")\nprint (\"Operadores De Identidad\")\nvar_1 = 4\nvar_2 = 4\nvar_3 = 7\nprint(var_1 is var_2)\nprint(var_1 is not var_3)\n\n#Bit a bit\nprint(\"\\n\")\nprint (\"Operadores Bit a Bit\")\nprint(var_1 & var_3)\nprint(var_1 | var_3)\nprint(var_1 ^ var_3)\nprint(~ var_3)\nprint(var_1 >> var_3)\nprint(var_1 << var_3)\n\n#Estructuras condicionales\nprint(\"\\n\")\nprint (\"Estructuras condicionales\")\nif (var_1 > var_3):\n    print(f\"la variable var_1 con varlor {var_1} es mayor que la variable var_3 con valor {var_3}\")\nelif (var_1 == var_3):\n    print (f\"Las variables var_1 y var_3 son iguales con el valor {var_1}\")\nelse:\n    print(f\"La variable var_3 con valor {var_3} es mayor que la variable var_1 con valor {var_1}\")\n\n#Estructuras iterativas\nprint(\"\\n\")\nprint (\"Estructuras condicionales\")\nprint (\"WHILE - ELSE\")\nlimit = 0\nwhile limit < var_3:\n    print(f\"El valor de la variable limit en esta vuelta es: {limit}\")\n    limit += 1\nelse:\n    print(f\"La variable limit ya vale lo mismo que var_3: {limit} y salgo del While\")\n\nprint(\"\\n\")\nprint (\"WHILE - ELSE con BREAK\")\nlimit = 0\nwhile limit < var_3:\n    if limit == 4:\n        print(\"Paro la ejecución del while mediante un break cuando la variable limit vale 4\")\n        break\n    print(f\"El valor de la variable limit en esta vuelta es: {limit}\")\n    limit += 1\nelse:\n    print(f\"La variable limit ya vale lo mismo que var_3: {limit} y salgo del While\")\n    \nprint(\"\\n\")\nprint (\"FOR - ELSE\")\nmy_list = [23, 34, 52, 16, 81, 90]\nfor element in my_list:\n    print(element)\nelse:\n    print(\"Ya he recorrido la lista my_list\")\n\nprint(\"\\n\")\nprint (\"FOR - ELSE con RANGOS\")\ntop_range = 10\nfor index in range (0,10):\n    print (f\"Estoy en el index {index}\")\nelse:\n    print (f\"He recorrido hasta el número {index} del rango (0,10)\")\n\nprint(\"\\n\")\nprint (\"FOR - ELSE con BREAK\")\ncount = 0\nfor element in my_list:\n    count += 1\n    print(f\"El elemento en la posición {count} es {element}\")\n    if count == 3:\n        print(f\"Salgo del bucle for con un break cuando llege a la posición {count} de my_list\")\n        break\nelse:\n    print (f\"He recorrido hasta el número {index} del rango (0,10)\")\n\n#Excepciones\nprint(\"\\n\")\nprint (\"Excepciones\")\nvalue_one = 3\nvalue_two = \"5\"\n#try - except\nprint (\"TRY - EXCEPT\")\ntry:\n    print(f\"La suma de los valores es {value_one + value_two}\")\n    print(\"No he ha producino ningún error\")\nexcept:\n    print(\"Se ha producido un error\")\n\n#try - except - else     \nprint(\"\\n\")\nprint (\"TRY - EXCEPT - ELSE\")\nvalue_two = 5\ntry:\n    print(f\"La suma de los valores es {value_one + value_two}\")\n    print(\"No se ha producino ningún error\")\nexcept:\n    print(\"Se ha producido un error\")\nelse:\n    print(\"La ejecución sigue sin errores\")\n\n#try - except - else - finally\nprint(\"\\n\")\nprint (\"TRY - EXCEPT - ELSE - FINALLY\")\nvalue_two = \"5\"\ntry:\n    print(f\"La suma de los valores es {value_one + value_two}\")\n    print(\"No se ha producino ningún error\")\nexcept:\n    print(\"Se ha producido un error\")\nelse:\n    print(\"La ejecución sigue sin errores\")\nfinally:\n    print(\"La ejecución del manejo de excepciones ha finalizado\")\n\n#Captura de excepciones por tipo\nprint(\"\\n\")\nprint (\"Captura de excepciones por tipo\")\ntry:\n    print(f\"La suma de los valores es {value_one + value_two}\")\n    print(\"No se ha producino ningún error\")\nexcept TypeError:\n    print(\"Se ha producido un TypeError\")\nexcept ValueError:\n    print(\"Se ha producido un ValueError\")\nexcept IndexError:\n    print(\"Se ha producido un IndexError\")\n\n#Captura de la información de la excepción\nprint(\"\\n\")\nprint (\"Captura de la información de la excepción\")\ntry:\n    print(f\"La suma de los valores es {value_one + value_two}\")\n    print(\"No se ha producino ningún error\")\nexcept ValueError:\n    print(\"Se ha producido un ValueError\")\nexcept Exception as error:\n    print(error)\n\n# DIFICULTAD ADICIONAL o BONUS TRACK =)\nprint(\"\\n\")\nprint (\"DIFICULTAD ADICIONAL o BONUS TRACK =)\")\n\ndef roadmap_01():\n    min_range = 10\n    max_range = 55\n    for index in range(min_range,max_range+1):\n        if index % 2 == 0:\n            if index != 16 and index % 3 != 0:\n                print (index)\n\nroadmap_01()\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/axelprz.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */ \"\"\"\n \n\"\"\"Operadores Aritméticos:\"\"\"\n # Suma\nresultado_suma = 5 + 3\nprint(\"Suma:\", resultado_suma)\n\n# Resta\nresultado_resta = 10 - 4\nprint(\"Resta:\", resultado_resta)\n\n# Multiplicación\nresultado_multiplicacion = 3 * 6\nprint(\"Multiplicación:\", resultado_multiplicacion)\n\n# División\nresultado_division = 15 / 3\nprint(\"División:\", resultado_division)\n\n# Módulo\nresultado_modulo = 17 % 4\nprint(\"Módulo:\", resultado_modulo)\n\n# Potencia\nresultado_potencia = 2 ** 4\nprint(\"Potencia:\", resultado_potencia)\n\n\"\"\"Operadores de Comparación:\"\"\"\n# Igualdad\nes_igual = (5 == 5)\nprint(\"Igualdad:\", es_igual)\n\n# Desigualdad\nno_es_igual = (7 != 3)\nprint(\"Desigualdad:\", no_es_igual)\n\n# Mayor que\nmayor_que = (10 > 5)\nprint(\"Mayor que:\", mayor_que)\n\n# Menor que\nmenor_que = (8 < 12)\nprint(\"Menor que:\", menor_que)\n\n# Mayor o igual que\nmayor_o_igual_que = (6 >= 6)\nprint(\"Mayor o igual que:\", mayor_o_igual_que)\n\n# Menor o igual que\nmenor_o_igual_que = (9 <= 10)\nprint(\"Menor o igual que:\", menor_o_igual_que)\n\n\"\"\"Operadores Lógicos:\"\"\"\n# AND lógico\nand_logico = True and False\nprint(\"AND lógico:\", and_logico)\n\n# OR lógico\nor_logico = True or False\nprint(\"OR lógico:\", or_logico)\n\n# NOT lógico\nnot_logico = not True\nprint(\"NOT lógico:\", not_logico)\n\n\"\"\"Operadores de Asignación:\"\"\"\n# Asignación simple\nvariable_asignada = 42\nprint(\"Variable asignada:\", variable_asignada)\n\n# Asignación con suma\nvariable_asignada += 8\nprint(\"Variable asignada con suma:\", variable_asignada)\n\n# Asignación con multiplicación\nvariable_asignada *= 2\nprint(\"Variable asignada con multiplicación:\", variable_asignada)\n\n\"\"\"Operadores de Identidad:\"\"\"\n# Identidad\nx = [1, 2, 3]\ny = [1, 2, 3]\n\nes_misma_identidad = x is y\nprint(\"Misma identidad:\", es_misma_identidad)\n\n# No es la misma identidad\nno_es_misma_identidad = x is not y\nprint(\"No es la misma identidad:\", no_es_misma_identidad)\n\n\"\"\"Operadores de Pertenencia:\"\"\"\n# Pertenencia a una lista\nlista = [1, 2, 3, 4]\npertenece_a_lista = 3 in lista\nprint(\"Pertenece a lista:\", pertenece_a_lista)\n\n# No pertenece a una lista\nno_pertenece_a_lista = 5 not in lista\nprint(\"No pertenece a lista:\", no_pertenece_a_lista)\n\n\"\"\"Operadores a Nivel de Bits:\"\"\"\n# AND a nivel de bits\nresultado_and_bits = 5 & 3\nprint(\"AND a nivel de bits:\", resultado_and_bits)\n\n# OR a nivel de bits\nresultado_or_bits = 5 | 3\nprint(\"OR a nivel de bits:\", resultado_or_bits)\n\n# XOR a nivel de bits\nresultado_xor_bits = 5 ^ 3\nprint(\"XOR a nivel de bits:\", resultado_xor_bits)\n\n# Desplazamiento a la izquierda\nresultado_desplazamiento_izquierda = 8 << 2\nprint(\"Desplazamiento a la izquierda:\", resultado_desplazamiento_izquierda)\n\n\"\"\"Estructuras Condicionales (if-elif-else):\"\"\"\n# Condicional simple\nnumero = 10\nif numero > 0:\n    print(\"El número es positivo.\")\nelif numero == 0:\n    print(\"El número es cero.\")\nelse:\n    print(\"El número es negativo.\")\n\n# Condicional con operador ternario\nresultado = \"Éxito\" if numero > 0 else \"Fracaso\"\nprint(\"Resultado:\", resultado)\n\n\"\"\"Bucle For:\"\"\"\n# Bucle for para imprimir los números del 1 al 5\nfor i in range(1, 6):\n    print(i)\n\n\"\"\"Bucle While:\"\"\"\n# Bucle while para imprimir los números del 1 al 5\ncontador = 1\nwhile contador <= 5:\n    print(contador)\n    contador += 1\n\n\"\"\"Manejo de Excepciones:\"\"\"\n# Manejo de excepciones para dividir dos números\ntry:\n    numerador = 10\n    denominador = 0\n    resultado_division = numerador / denominador\n    print(\"Resultado de la división:\", resultado_division)\nexcept ZeroDivisionError:\n    print(\"Error: División por cero.\")\nexcept Exception as e:\n    print(f\"Otro error: {e}\")\nfinally:\n    print(\"Este bloque siempre se ejecuta.\")\n\n#Programa pedido\nfor i in range(10,55):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print(i);\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/baauus.py",
    "content": "\"\"\"\n1. Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\nAritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n(Ten en cuenta que cada lenguaje puede poseer unos diferentes) \n\"\"\"\n# Operadores aritmeticos\nprint(suma=15 + 5)\nprint(resta=39 - 12)\nprint(multiplicacion=12 * 3)\nprint(division=12 / 4)\nprint(resto=12 % 5)\nprint(potencia=3**2)\nprint(division_resultado_entero=15 // 4)\n\n# Operadores Relacionales\nprint(igualdad=15 == 15)\nprint(distinto=15 != 15)\nprint(mayor=15 > 15)\nprint(menor=15 < 15)\nprint(mayorIgual=15 >= 15)\nprint(menorIgual=15 <= 15)\n\n# Operadores bit a bit\nprint(and_=2 & 1)\nprint(or_=2 | 1)\nprint(xor=2 ^ 1)\nprint(not_=~2)\nprint(shift_left=2 << 1)\nprint(shift_right=2 >> 1)\n\n# Operadores asignacion\na = 100\nprint(a=10)\na += 1\nprint(a)\na -= 1\nprint(a)\na /= 3\nprint(a)\na *= 3\nprint(a)\na %= 3\nprint(a)\na **= 3\nprint(a)\na //= 3\nprint(a)\na &= 3\nprint(a)\na ^= 3\nprint(a)\na <<= 3\nprint(a)\na >>= 3\nprint(a)\n\n# Operadores lógicos\nprint(and_=True and True)\nprint(or_=True or False)\nprint(not_=not True)\n\n# Operadores de pertinencia\nprint(a=[1, 2, 3])\nprint(x=3 in a)\nprint(y=4 not in a)\n\n# Operadores de identidad\nprint(x=4 is 4)\nprint(z=4 is not 4)\n\n#\n\"\"\"\n2. Utilizando las operaciones con operadores que tú quieras, crea ejemplos\nque representen todos los tipos de estructuras de control que existan\nen tu lenguaje:\nCondicionales, iterativas, excepciones...\n\"\"\"\n# if-elif-else\nx = 10\nz = 3\nif x > z:\n    print(\"x es mayor que z\")\nelif x < z:\n    print(\"x es menor que z\")\nelse:\n    print(\"x es igual a z\")\n\n# for\nfor i in range(10):\n    print(i)\n\n# while\nwhile i < 10:\n    print(i)\n\n# exception\ntry:\n    1 / 0\nexcept NameError:\n    print(\"No se puede dividir entre cero\")\n    print(\"Cambiar numero divisor\")\nfinally:\n    print(\"Cambiar numero divisor\")\n\n#\n\"\"\" \n3. Debes hacer print por consola del resultado de todos los ejemplos.\n\"\"\"\n\"\"\"\n4. Crea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\"\"\"\nfor i in range(10, 56):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print(i)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/barrancus.py",
    "content": "# Operadores de aritméticos\r\nprint('Operadores de aritméticos')\r\nnum_one = 34\r\nnum_two = 6\r\nprint(f'{num_one} + {num_two} = {num_one + num_two}')\r\nprint(f'{num_one} - {num_two} = {num_one - num_two}')\r\nprint(f'{num_one} * {num_two} = {num_one * num_two}')\r\nprint(f'{num_one} ** {num_two} = {num_one ** num_two}')\r\nprint(f'{num_one} / {num_two} = {num_one / num_two}')\r\nprint(f'{num_one} // {num_two} = {num_one // num_two}')\r\nprint(f'{num_one} % {num_two} = {num_one % num_two}')\r\n\r\n# Operadores lógicos\r\nprint('Operadores lógicos')\r\nbool_one = True\r\nbool_two = False\r\nprint(f'{bool_one} and {bool_two} = {bool_one and bool_two}')\r\nprint(f'{bool_one} or {bool_two} = {bool_one or bool_two}')\r\nprint(f'not {bool_one} = {not bool_one}')\r\nprint(f'not {bool_two} = {not bool_two}')\r\n\r\n# Operadores relacionales\r\nprint('Operadores relacionales')\r\nprint(f'{num_one} equal {num_two} = {num_one == num_two}')\r\nprint(f'{num_one} not equal {num_two} = {num_one != num_two}')\r\nprint(f'{num_one} more than {num_two} = {num_one > num_two}')\r\nprint(f'{num_one} less than {num_two} = {num_one < num_two}')\r\nprint(f'{num_one} more or equal than {num_two} = {num_one >= num_two}')\r\nprint(f'{num_one} less or equial than {num_two} = {num_one <= num_two}')\r\n\r\n# Operadores de asignación\r\nprint('Operadores de asignación')\r\nnum_a=7; num_b=2\r\nprint(f\"Operadores de asignación para x={num_a} y {num_b}\")\r\nnum_x=num_a; num_x+=num_b; print(\"x+=\", num_x)  # 9\r\nnum_x=num_a; num_x-=num_b; print(\"x-=\", num_x)  # 5\r\nnum_x=num_a; num_x*=num_b; print(\"x*=\", num_x)  # 14\r\nnum_x=num_a; num_x/=num_b; print(\"x/=\", num_x)  # 3.5\r\nnum_x=num_a; num_x%=num_b; print(\"x%=\", num_x)  # 1\r\nnum_x=num_a; num_x//=num_b;print(\"x//=\", num_x) # 3\r\nnum_x=num_a; num_x**=num_b;print(\"x**=\", num_x) # 49\r\nnum_x=num_a; num_x&=num_b; print(\"x&=\", num_x);  print(\"x&=\", bin(num_x))# 2\r\nnum_x=num_a; num_x|=num_b; print(\"x|=\", num_x); print(\"x|=\", bin(num_x))  # 7\r\nnum_x=num_a; num_x^=num_b;print(\"x^=\", num_x); print(\"x^=\", bin(num_x))   # 5\r\nnum_x=num_a; num_x>>=num_b;print(\"x>>=\", num_x); print(\"x>>=\", bin(num_x)) # 1\r\nnum_x=num_a; num_x<<=num_b;print(\"x<<=\", num_x); print(\"x<<=\", bin(num_x)) # 28\r\n\r\n# Operadores bitwise\r\nprint('Operadores bitwise')\r\nbit_a = 0b1101; bit_b = 0b1011;\r\nprint(f'AND: {bit_a} & {bit_b} = {bin(bit_a & bit_b)}') # 0b1001\r\nprint(f'OR: {bit_a} | {bit_b} = {bin(bit_a | bit_b)}') # 0b1111\r\nprint(f'XOR {bit_a} ^ {bit_b} = {bin(bit_a ^ bit_b)}')\r\nnum_a = 40; print(f'NOT {num_a}: {~num_a}'); print(bin(num_a),bin(~num_a))\r\nbit_a=0b1000; print(bin(bit_a>>2)) # 0b10\r\nbit_a=0b0001; print(bin(bit_a<<3)) # 0b1000\r\n\r\n# Operadores de Identidad comparan los valores en memoria\r\nprint('Operadores de Identidad')\r\nid_a = 10; id_b = 10; print(f'{id_a} is {id_b} = {id_a is id_b}'); print(f'El id del objeto es: {id(id_a)}'); print(f'El id del objeto es: {id(id_b)}')\r\nid_a = 10; id_b = 10.0; print(f'{id_a} is {id_b} = {id_a is id_b}'); print(f'El id del objeto es: {id(id_a)}'); print(f'El id del objeto es: {id(id_b)}')\r\nid_a = \"perro\"; id_b = 'perro'; print(f'{id_a} is {id_b} = {id_a is id_b}'); print(f'El id del objeto es: {id(id_a)}'); print(f'El id del objeto es: {id(id_b)}')\r\nid_a = \"perro\"; id_b = 'Perro'; print(f'{id_a} is {id_b} = {id_a is id_b}'); print(f'El id del objeto es: {id(id_a)}'); print(f'El id del objeto es: {id(id_b)}')\r\nid_a = \"perro\"; id_b = 'gato'; print(f'{id_a} is {id_b} = {id_a is id_b}'); print(f'El id del objeto es: {id(id_a)}'); print(f'El id del objeto es: {id(id_b)}')\r\nid_a = [1, 2, 3]; id_b = [1, 2, 3]; print(f'{id_a} == {id_b}: {id_a == id_b}'); print(f'{id_a} is {id_b}: {id_a is id_b}'); print(f'El id del objeto es: {id(id_a)}'); print(f'El id del objeto es: {id(id_b)}')\r\nid_a = [1, 2, 3]; id_b = [1, 2, 3]; print(f'{id_a} != {id_b}: {id_a != id_b}'); print(f'{id_a} is not {id_b}: {id_a is not id_b}'); print(f'El id del objeto es: {id(id_a)}'); print(f'El id del objeto es: {id(id_b)}')\r\n\r\n# Operadores de membresía o pertnencia\r\nprint('Operadores de membresía o pertnencia')\r\nmemb_phrase = \"El perro de San Roque ya no tiene rabo, porque Ramon Ramirez se lo ha cortado\"\r\nmemb_a = 'perro'; print(f'Is \"{memb_a}\" in \"{memb_phrase}\": {memb_a in memb_phrase}')\r\nmemb_a = 'Perro'; print(f'Is \"{memb_a}\" in \"{memb_phrase}\": {memb_a in memb_phrase}')\r\nmemb_a = 'Ramon'; print(f'Is \"{memb_a}\" in \"{memb_phrase}\": {memb_a in memb_phrase}')\r\nmemb_a = 'gato'; print(f'Is \"{memb_a}\" in \"{memb_phrase}\": {memb_a in memb_phrase}')\r\nmemb_a = 'perro'; print(f'Is not \"{memb_a}\" in \"{memb_phrase}\": {memb_a not in memb_phrase}')\r\nmemb_a = 'Perro'; print(f'Is not \"{memb_a}\" in \"{memb_phrase}\": {memb_a not in memb_phrase}')\r\nmemb_a = 'ramon'; print(f'Is not \"{memb_a}\" in \"{memb_phrase}\": {memb_a not in memb_phrase}')\r\nmemb_a = 'gato'; print(f'Is not \"{memb_a}\" in \"{memb_phrase}\": {memb_a not in memb_phrase}')\r\n\r\n# Operador Walrus\r\nprint('Operador Walrus')\r\nx = \"Python\"\r\nprint(x)\r\nprint(type(x))\r\nprint(x := ascii(x))\r\nprint(type(x))\r\n\r\nprint('Utilizando las operaciones')\r\nlist_numeros = []\r\nfor num_d in range(25,0,-1):\r\n    if num_d - 13 == 0:\r\n        continue\r\n    elif num_d - 13 < -2:\r\n        break\r\n    else:\r\n        list_numeros.append(25 // (num_d - 13))\r\n        list_numeros.append(25 % (num_d - 13))\r\nprint(list_numeros)\r\n\r\nlist_numeros.clear()\r\nnum_c = 1\r\nwhile num_c <= 65:\r\n    list_numeros.append(num_c)\r\n    num_c *=3\r\nprint(list_numeros)\r\n\r\nlist_animals=['cat','dog','fish','mamut',num_c,'fly','butterfly','pikachu']\r\nfor animal in list_animals:\r\n    try:\r\n        print(animal.capitalize())\r\n    except Exception as error:\r\n        print(f'El valor que ha fallado ha sido {animal} por fallo {error}')\r\n\r\n# Calculadora subred y broadcast\r\nnum_mask = 248\r\nnum_check = 121\r\nsubred = num_mask&num_check\r\nbroadcast = subred + (255-num_mask)\r\nprint(f'La subred es :{subred}')\r\nprint(f'La IP de broadcast es :{broadcast}')\r\n\r\n# DIFICULTAD EXTRA (opcional):\r\nprint(list(num_z for num_z in range(10,56) if (num_z % 2) == 0 and num_z != 16 and (num_z % 3) != 0 ))"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/beonzj.py",
    "content": "#   OPERADORES\n\nprint(\"## OPERADORES ##\\n\")\n\nprint(\"# Aritméticos\\n\")\nprint(f\"7 + 2 = {7+2}\") # Suma\nprint(f\"5 - 2 = {5-2}\") # Resta\nprint(f\"5 * 2 = {5*2}\") # Multiplicación\nprint(f\"5 / 2 = {5/2}\") # División\nprint(f\"5 % 2 = {5%2}\") # Resto de división\nprint(f\"5 // 2 = {5//2}\") # Cociente de división\nprint(f\"5 ** 2 = {5**2}\") # Exponente\n\nprint(\"\\n\\n# Relacionales\\n\")\nprint(f\"5 == 2 es {5==2}\") # Igual que\nprint(f\"5 != 2 es {5!=2}\") # Diferente a\nprint(f\"5 < 2 es {5<2}\") # Menor que\nprint(f\"5 > 2 es {5>2}\") # Mayor que\nprint(f\"5 <= 2 es {5<=2}\") # Menor o igual que\nprint(f\"5 >= 2 es {5>=2}\") # Mayor o igual que\n\nprint(\"\\n\\n# Lógicos\\n\")\nprint(f\"1 + 2 == 3 or 2 - 1 == 1 {1 + 2 == 3 or 2 - 1 == 1}\") # or\nprint(f\"1 + 2 == 3 and 2 - 1 == 1 {1 + 2 == 3 and 2 - 1 == 1}\") # and\nprint(f\"not 2 - 1 == 2 {not 2 - 1 == 2}\") # not\n\nprint(\"\\n\\n# Asignación\\n\")\nx = 23 # Asignación\nprint(x) \nx += 2 # Suma y asignación\nprint(x)\nx -= 2 # Resta y asignación\nprint(x)\nx *= 2 # Multiplicación y asignación\nprint(x)\nx /= 2 # División y asignación\nprint(x)\nx %= 3 # Resto y asignación\nprint(x)\nx //= 1 # Cociente y asignación\nprint(x)\nx **= 2 # Exponente y asignación\nprint(f\"{x}\")\n\nprint(\"\\n\\n# Identidad\\n\")\ny = 2\nprint(f\"y is 2 es {y is 2}\") # is\nprint(f\"y is not 2 es {y is not 2}\") # is not\n\nprint(\"\\n\\n# Pertenencia\\n\")\nprint(f\"'p' in 'palabra' es {'p' in 'palabra'}\")\nprint(f\"'o' not in 'palabra' es {'p' in 'palabra'}\")\n\nprint(\"\\n\\n# A nivel de bit\\n\")\na = 10\nb = 3\nprint(f\"a | b = {a | b}\")\nprint(f\"a ^ b = {a ^ b}\")\nprint(f\"a & b = {a & b}\")\nprint(f\"a << 2 = {a << b}\")\nprint(f\"a >> 2 = {a >> b}\")\nprint(f\"~a = {~a}\")\n\nprint(\"\\n\\n## ESTRUCTURAS DE CONTROL ##\\n\")\n\nprint(\"# Condicionales\\n\")\nnumber = 11\nprint(f\"Número= {number}\")\nif number > 0 and number <= 10:\n    print(\"El número es mayor a 0 e igual o menor que 10\")\nelif number > 10 and number <= 20:\n    print(\"El número es mayor a 10 e igual o menor que 20\")\nelse:\n    print(\"El número es menor a 0 y mayor que 20\")\n\nprint(\"\\n\\n# Iterativas\\n\")\n\nprint(\"for\")\nfor i in range(11):\n    print(i)\n\ni = 0\n\nprint(\"\\nwhile\")\nwhile i <= 10:\n    print(i)\n    i += 1\n\nprint(\"\\n\\n# Excepciones\\n\")\n\ntry:\n    print(c-ac)\nexcept:\n    print(\"Excepción error\")\nfinally:\n    print(\"Fin de la exepción\")\n\n\nprint(\"\\n\\n## TAREA EXTRA ##\\n\")\n\nfor x in range(10, 56):\n    if x % 2 == 0 and x != 16 and x % 3 != 0:\n        print(x)\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/betzadev.py",
    "content": "print('\\n--- OPERADORES Y ESTRUCTURAS DE CONTROL 🐍 ---')\n\nwhile True:\n    try:\n        num1 = int(input(\"Ingrese el primer número: \"))\n        num2 = int(input(\"Ingrese el segundo número: \"))\n        break\n    except ValueError:\n        print(\"Por favor, ingrese números válidos.\")\nresult = 0\n\nprint('\\n🔷Operadores lógicos o booleanos')\n\nx = True\ny = False\nresultado_and = x and y\nresultado_or = x or y\nresultado_not = not x\nprint(f\"AND: {resultado_and}, OR: {resultado_or}, NOT: {resultado_not}\")\n\n\nprint('\\n🔷Operadores de comparación')\n\nprint(f\"Igualdad: {num1} == {num2} es {num1 == num2}\")\nprint(f\"Desigualdad: {num1} != {num2} es {num1 != num2}\")\nprint(f\"Mayor que: {num1} > {num2} es {num1 > num2}\")\nprint(f\"Menor que: {num1} < {num2} es {num1 < num2}\")\nprint(f\"Mayor o igual que: {num1} >= {num1} es {num1 >= num1}\")\nprint(f\"Menor o igual que: {num1} <= {num2} es {num1 <= num2}\")\n\nprint('\\n🔷Operadores aritméticos')\n\n# Operador suma (+)\nresult = num1 + num2\nprint(f\"La suma de {num1} + {num2} es {result}\")\n\n# Operador resta (-)\nresult = num1 - num2\nprint(f\"La resta de {num1} - {num2} es {result}\")\n\n# Operador multiplicación (*)\nresult = num1 * num2\nprint(f\"La multiplicación de {num1} * {num2} es {result}\")\n\n# Operador división (/)\nresult = num1 / num2\nprint(f\"La división de {num1} / {num2} es {result}\")\n\n# Operador módulo (%)\nresult = num1 % num2\nprint(f\"El resto de la división de {num1} / {num2} es {result}\")\n\nprint('\\n🔷Operadores a nivel de bits')\n\nnum = 10\ncomplemento = ~num\nprint(f\"Complemento de {num}: {complemento}\")\n\na = 5  # Representación binaria: 0101\nb = 3  # Representación binaria: 0011\nresultado_and = a & b\nprint(f\"AND entre {a} y {b}: {resultado_and}\")\n\nx = 12  # Representación binaria: 1100\ny = 6   # Representación binaria: 0110\nresultado_or = x | y\nprint(f\"OR entre {x} y {y}: {resultado_or}\")\n\np = 9   # Representación binaria: 1001\nq = 6   # Representación binaria: 0110\nresultado_xor = p ^ q\nprint(f\"XOR entre {p} y {q}: {resultado_xor}\")\n\nnum_binario = 10  # Representación binaria: 1010\ndesplazamiento_izquierda = num_binario << 2\ndesplazamiento_derecha = num_binario >> 1\nprint(f\"Desplazamiento izquierda: {desplazamiento_izquierda}, Desplazamiento derecha: {desplazamiento_derecha}\")\n\nnum_rotacion = 15  # Representación binaria: 1111\nrotacion_izquierda = (num_rotacion << 2) | (num_rotacion >> 2)\nprint(f\"Rotación izquierda: {rotacion_izquierda}\")\n\n\nprint('\\n🔷Operadores de asignación')\n\nx = 10\nx += 5\nx -= 3\nx *= 2\nprint(f\"Valor final de x: {x}\")\n\n\nprint('\\n🔷Operadores de identidad y pertenencia')\n\nlista1 = [1, 2, 3]\nlista2 = [1, 2, 3]\nes_mismo_objeto = lista1 is lista2\nesta_en_lista = 2 in lista1\nprint(f\"Mismo objeto: {es_mismo_objeto}, Está en lista: {esta_en_lista}\")\n\n\nprint('\\n--- ESTRUCTURAS DE CONTROL ---')\n\nprint('\\n🔷Condicionales (if-elif-else)')\n\nedad = 18\nif edad < 18:\n    print(\"Eres menor de edad\")\nelif edad == 18:\n    print(\"Tienes 18 años\")\nelse:\n    print(\"Eres mayor de edad\")\n    \nprint('\\n🔷Iterativas (for y while)')\n    \n# Ciclo for\nfor i in range(5):\n    print(f\"Valor de i: {i}\")\n\n# Ciclo while\ncontador = 0\nwhile contador < 3:\n    print(f\"Contador: {contador}\")\n    contador += 1\n\n\nprint('\\n🔷Manejo de excepciones')\n\ntry:\n    print(3 / 0)\nexcept:\n    print(\"Se ha producido un error\")\nfinally:\n    print(\"Ha finalizado el manejo de excepciones\")\n\n\nprint('\\n🔷EJERCICIO EXTRA:')\n\"\"\" \nCrea un programa que imprima por consola todos los números comprendidos entre 10 y 55 (incluidos), pares, y\nque no son ni el 16 ni múltiplos de 3.\n\"\"\"\nfor number in range(10, 56):\n    if number % 2 == 0 and number != 16 and number % 3 != 0:\n        print(number)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/bladi23.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n \n \"\"\"\n \n #OPERADORES ARITMÉTICOS\n \nprint(\"Suma:\", a + b)\nprint(\"Resta:\", a - b)\nprint(\"Multiplicación:\", a * b)\nprint(\"División:\", a / b)\nprint(\"División entera:\", a // b)\nprint(\"Módulo:\", a % b)\nprint(\"Potencia:\", a ** b)\n\n# OPERADORES DE ASIGNACIÓN COMPUESTA\nx = 10\nx += 5\nprint(\"x += 5 →\", x)\nx *= 2\nprint(\"x *= 2 →\", x)\n\n# OPERADORES DE IDENTIDAD\nlista1 = [1, 2, 3]\nlista2 = lista1\nlista3 = [1, 2, 3]\nprint(\"lista1 is lista2:\", lista1 is lista2)\nprint(\"lista1 is lista3:\", lista1 is lista3)\nprint(\"lista1 is not lista3:\", lista1 is not lista3)\n\n# OPERADORES DE PERTENENCIA\nprint(\"2 in lista1:\", 2 in lista1)\nprint(\"4 not in lista1:\", 4 not in lista1)\n\n#EJEMPLOS DE OPERADORES LOGICOS \n\nedad_usuario=int(input(\"Introduce tu edad: \"))\nentrada=input(\"Has pagado la entrada? (si/no): \").lower()\nif edad_usuario>=18 and entrada ==\"si\":\n    print(\"Bienvenido a la fiesta \")\nelse :\n    print(\"Lo siento, no puedes entrar a la fiesta\")\n\nedad_cine=int(input(\"Introduce tu edad: \"))\nentrada=input(\"Tiene entrada VIP? (si/no): \").lower()\nif edad_cine>=16 or entrada==\"si\":\n    print(\"Puedes entrar al cine\")\nelse:\n    print(\"Lo siento, no puedes entrar al cine\")\n    \n#OPERADORES DE COMPARACION\nprint(\"a == b:\", a == b)\nprint(\"a != b:\", a != b)\nprint(\"a > b:\", a > b)\nprint(\"a < b:\", a < b)\nprint(\"a >= b:\", a >= b)\nprint(\"a <= b:\", a <= b)\n\n#ESTRUCTURAS DE CONTROL CONDICIONALES\nedad=20\nif edad>=18:\n    print(\"Eres mayor de edad\")\nelif edad==17:\n    print(\"Casi eres mayor de edad \")\nelse:\n    print(\"Eres menor de edad\")\n    \nprint(\"Bucle while:\")\ni = 0\nwhile i < 5:\n    print(i)\n    i += 1\n\nprint(\"Bucle for:\")\nfor i in range(5):\n    print(i)\n\n# CONTROL DE FLUJO\nprint(\"Break:\")\nfor i in range(10):\n    if i == 5:\n        break\n    print(i)\n\nprint(\"Continue:\")\nfor i in range(10):\n    if i == 5:\n        continue\n    print(i)\n\nprint(\"Pass:\")\nfor i in range(3):\n    if i == 1:\n        pass\n    print(i)\n# MANEJO DE EXCEPCIONES\ntry:\n    numero = int(input(\"Introduce un número para dividir: \"))\n    resultado = 10 / numero\n    print(\"Resultado:\", resultado)\nexcept ZeroDivisionError:\n    print(\"No puedes dividir entre cero.\")\nexcept ValueError:\n    print(\"Por favor, ingresa un número válido.\")\n\n# DIFICULTAD EXTRA: imprimir números del 10 al 55, pares, no 16 ni múltiplos de 3\nprint(\"Números del 10 al 55 que son pares, no son 16 y no son múltiplos de 3:\")\nfor i in range(10, 56):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/blancowilson.py",
    "content": "a:int = 13\nb:int = 5\n\naddition = a + b\nprint(addition)\nsubstract = a - b\nprint(substract)\nmultiply = a * b\nprint(multiply)\ndivision = a/b\nprint(division)\ninteger_division = a//b\nprint(integer_division)\npower = a**b\nprint(power)\nremainder = a%b\nprint(remainder)\n\nprint (\"comparation operatos == != > <\")\ncompare = a == b\nprint(compare)\ncompare = a != b\nprint(compare)\ncompare = a > b\nprint(compare)\ncompare = a < b\nprint(compare)\ncompare = a >= b\nprint(compare)\n\nprint (\"logical operators\")\n# Logical NOT with ~\nprint((~(2 == 2)))\n# Logical AND with &\nprint((1!=1) & (1<1))\n# Logical OR with |\nprint(( 1>=1 ) | (1 <1))\n# Logical XOR with \nprint((1 != 1) ^ ( 1< 1))\n\ni=0\n\nwhile i < 10:\n    print(i,end=' ')\n    i +=1\n\n\n\n# Resolucion dificultad extra opcional\nfor i in range(10,56):\n    odd = False\n    odd= ((i % 2) == 0)\n    multiply_of_three = not((i % 3) == 0)\n    #print (f\"{i} es multiplo de 3 {((i % 3) == 0)}\")\n    if odd and multiply_of_three and i !=16: print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/blonsh.py",
    "content": "\"\"\"\nCrear ejemplos de operadores\n\"\"\"\n\n## Operadores aritméticos\na = 10\nb = 3\n\nprint(\"Suma:\", a + b)            # 13\nprint(\"Resta:\", a - b)          # 7\nprint(\"Multiplicación:\", a * b) # 30\nprint(\"División:\", a / b)       # 3.333...\nprint(\"Módulo:\", a % b)         # 1\nprint(\"Exponente:\", a ** b)     # 1000\nprint(\"División entera:\", a // b) # 3\n\n## Operadores de comparación\nm = 5\nn = 7\n\nprint(\"Igual a:\", m == n)         # False\nprint(\"Distinto de:\", m != n)     # True\nprint(\"Mayor que:\", m > n)        # False\nprint(\"Menor que:\", m < n)        # True\nprint(\"Mayor o igual:\", m >= n)  # False\nprint(\"Menor o igual:\", m <= n)  # True\n\n##Operadores lógicos\nx = True\ny = False\n\nprint(\"AND:\", x and y)     # False\nprint(\"OR:\", x or y)       # True\nprint(\"NOT x:\", not x)     # False\n\n## Operadores de asignación\nnum = 5\nprint(\"Valor inicial:\", num)    # 5\n\nnum += 2\nprint(\"Suma y asigna:\", num)    # 7\n\nnum -= 1\nprint(\"Resta y asigna:\", num)   # 6\n\nnum *= 3\nprint(\"Multiplica y asigna:\", num) # 18\n\nnum /= 2\nprint(\"Divide y asigna:\", num)  # 9.0\n\nnum %= 4\nprint(\"Módulo y asigna:\", num)  # 1.0\n\nnum **= 3\nprint(\"Exponente y asigna:\", num) # 1.0\n\nnum //= 2\nprint(\"División entera y asigna:\", num) # 0.0\n\n## Operadores de identidad\na = [1, 2, 3]\nb = a\nc = [1, 2, 3]\n\nprint(\"a es b:\", a is b)     # True\nprint(\"a es c:\", a is c)     # False\nprint(\"a no es c:\", a is not c) # True\n\n## Operadores de pertenencia\nlista = [1, 2, 3, 4, 5]\n\nprint(\"2 en lista:\", 2 in lista)       # True\nprint(\"10 en lista:\", 10 in lista)     # False\nprint(\"10 no en lista:\", 10 not in lista) # True\n\n## Operadores de bit\na = 5   # en binario:  0101\nb = 3   # en binario:  0011\n\n\nprint(\"a en binario:\", bin(a))   # 0b101\nprint(\"b en binario:\", bin(b))   # 0b11\n\n# AND (y bit a bit)\nprint(\"AND (a & b):\", a & b)     # 1  (0001)\n\n# OR (o bit a bit)\nprint(\"OR (a | b):\", a | b)      # 7  (0111)\n\n# XOR (o exclusivo bit a bit)\nprint(\"XOR (a ^ b):\", a ^ b)     # 6  (0110)\n\n# NOT (negación bit a bit)\nprint(\"NOT (~a):\", ~a)           # -6 (complemento a 2)\n\n# Desplazamiento a la izquierda\nprint(\"a << 1:\", a << 1)         # 10 (1010)\n\n# Desplazamiento a la derecha\nprint(\"a >> 1:\", a >> 1)         # 2  (0010)\n\n## Estructuras de control\n\n# Condicionales\ncalificacion = int(input(\"Ingresa tu calificación (0–100): \"))\n\nif calificacion >= 90:\n    print(\"Excelente, obtuviste una A.\")\nelif calificacion >= 80:\n    print(\"Muy bien, obtuviste una B.\")\nelif calificacion >= 70:\n    print(\"Bien, obtuviste una C.\")\nelif calificacion >= 60:\n    print(\"Pasaste, obtuviste una D.\")\nelse:\n    print(\"Reprobaste, obtuviste una F.\")\n\n## Iterativas\n\n# Pedir calificaciones de 3 estudiantes\nfor i in range(3):\n    calificacion = int(input(f\"Ingrese la calificación del estudiante {i+1} (0–100): \"))\n    \n    if calificacion >= 90:\n        print(\"Excelente, obtuviste una A.\")\n    elif calificacion >= 80:\n        print(\"Muy bien, obtuviste una B.\")\n    elif calificacion >= 70:\n        print(\"Bien, obtuviste una C.\")\n    elif calificacion >= 60:\n        print(\"Pasaste, obtuviste una D.\")\n    else:\n        print(\"Reprobaste, obtuviste una F.\")\n\n# Pedir calificaciones hasta que el usuario escriba -1\nwhile True:\n    calificacion = int(input(\"Ingrese una calificación (0–100) o -1 para salir: \"))\n    \n    if calificacion == -1:\n        print(\"Fin del programa.\")\n        break\n    \n    if calificacion >= 90:\n        print(\"Excelente, obtuviste una A.\")\n    elif calificacion >= 80:\n        print(\"Muy bien, obtuviste una B.\")\n    elif calificacion >= 70:\n        print(\"Bien, obtuviste una C.\")\n    elif calificacion >= 60:\n        print(\"Pasaste, obtuviste una D.\")\n    else:\n        print(\"Reprobaste, obtuviste una F.\")\n\n## Manejo de excepciones\ntry:\n    x = int(input(\"Ingresa un número: \"))\n    resultado = 10 / x\n    print(\"El resultado es:\", resultado)\n\nexcept ZeroDivisionError:\n    print(\"Error: No puedes dividir entre cero.\")\n\nexcept ValueError:\n    print(\"Error: Debes ingresar un número válido.\")\n\nelse:\n    print(\"Todo salió bien.\")\n\nfinally:\n    print(\"Esto se ejecuta siempre, ocurra o no un error.\")\n\n\"\"\"\"Extra\"\"\"\nfor num in range(10, 56):  # desde 10 hasta 55 inclusive\n    if num % 2 == 0 and num != 16 and num % 3 != 0:\n        print(num)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/buriticasara.py",
    "content": "\"\"\"Los operadores aritmeticos son:\n+ - * / % // ** \"\"\"\n#Ejemplos\nprint(f\"20+4= {20+4}\")\nprint(f\"20-4= {20-4}\")\nprint(f\"20*4= {20*4}\")\nprint(f\"20/4= {20/4}\")\nprint(f\"20%4= {20%4}\")\nprint(f\"20//4= {20//4}\")\nprint(f\"20**4= {20**4}\")\n\n\n#Ejemplo operadores relacionamiento\na=5\nb=8\nprint(f\"5 es menor que 8= {a<b}\")\nprint(f\"5 es mayor que 8= {a>b}\")\nprint(f\"5 es igual que 8= {a==b}\")\nprint(f\"5 es diferente que 8= {a!=b}\")\nprint(f\"5 es menor o igual que 8= {a<=b}\")\n\n\n#Ejemplo operadores lógicos\nprint(f\"4-1 es igual a 2+1 = {4-1==3 and 2+1==3}\")\nprint(f\"uno de estos dos números es par: 9 o 4 {9%2==0 or 4%2==0}\")\nprint(f\"4+1 no es igual a 4-1= {not 4+1 == 4-1}\")\n\n\n#Ejemplo operadores de asignación\nc=8\nprint(c)\nc += 1\nprint(c)\nc -=2\nprint(c)\n\n\n#Ejemplo operadores de pertenencia\nd= (8,4,3)\nprint(f\"el 8 no esta en d: {8 not in d} \")\nprint(f\"el 9 esta en d: {9 in d} \")\n\n\n#Ejemplo operadores de identidad\ncapital= 'Bogota'\nprint(f\"Bogota es una capital: {'Bogota' is capital} \")\nprint(f\"Bogota no es una capital: {'Bogota'is not capital} \")\n\n#Ejercicio extra\nfor z in range (10,56):\n  if z%2 == 0 and z != 16 and z%3 != 0:\n    print(z)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/byTiagoGhost.py",
    "content": "# Operadores y Estructuras de Control\r\n# Autor: byTiagoGhost\r\n\r\n# Ejercicio 1\r\n# Operadores Aritmeticos\r\nprint(3 + 4) # Suma\r\nprint(3 - 4) # Resta   \r\nprint(3 * 4) # Multiplicacion\r\nprint(3 / 4) # Division\r\nprint(3 ** 4) # Exponenciacion\r\nprint(3 % 4) # Modulo = Te da el residuo de la division\r\nprint(3 // 4) # Division Entera = Te da el cociente de la division\r\n\r\nprint(\"\")\r\n\r\n# Operadores de Asignacion\r\n# = Igualacion. \r\n# Ejemplo: \r\nx = 5\r\nprint(\"Igualacion:\", x) \r\n# Igual que: x = 5\r\n\r\n\r\n# Nota: Estamos reservando la variable de la X, entonces eso signiica que la variable puede cambiar de valor.\r\n\r\n# += Suma en asignacion\r\n# Ejemplo:\r\nx+=3\r\nprint(\"Suma:\", x)\r\n# Igual que: x = x + 3\r\n\r\n# -= Resta en asignacion\r\n# Ejemplo:\r\nx-=3\r\nprint(\"Resta:\", x)\r\n# Igual que: x = x - 3\r\n\r\n# *= Multiplicacion en asignacion\r\n# Ejemplo:\r\nx*=3\r\nprint(\"Multiplicacion:\", x)\r\n# Igual que: x = x * 3\r\n\r\n# /= Division en asignacion\r\n# Ejemplo:\r\nx/=3\r\nprint(\"Division:\", x)\r\n# Igual que x = x / 3\r\n\r\n# %= Modulo en asignacion\r\n# Ejemplo:\r\nx%=3\r\nprint(\"Modulo:\", x)\r\n# Igual que x = x % 3\r\n\r\n# //= Division Entera en asignacion\r\n# Ejemplo:\r\nx//=3\r\nprint(\"Division Entera:\", x)\r\n# Igual que x = x // 3\r\n\r\n# **= Exponenciacion en asignacion\r\n# Ejemplo:\r\nx**=3\r\nprint(\"Exponenciacion:\", x)\r\n# Igual que x = x ** 3\r\n\r\n# &= AND en asignacion o bitside\r\n# Ejemplo:\r\ny = 5   # 5  en bits = 101\r\ny&=3   # 3 en bits = 011\r\nprint(\"AND o BITSIDE:\", y) # 1 en bits = 001\r\n# Igual que y = y & 3\r\n\r\n# |= OR en asignacion o bitside\r\n# Ejemplo:\r\ny = 5   # 5  en bits = 101\r\ny|=3   # 3 en bits = 011\r\nprint(\"OR o BITSIDE:\", y) # 7 en bits = 111\r\n# Igual que y = y |\r\n\r\n# ^= XOR en asignacion o bitside\r\n# Ejemplo:\r\ny = 5   # 5  en bits = 101\r\ny^=3   # 3 en bits = 011\r\nprint(\"XOR o BITSIDE:\", y) # 6 en bits = 110\r\n# Igual que y = y ^ 3\r\n\r\n# >>= Desplazamiento a la derecha en asignacion o bitside\r\n# Ejemplo:\r\ny = 5   # 5  en bits = 101\r\ny>>=3   # 3 en bits = 011\r\nprint(\"Desplazamiento a la derecha:\", y) # 0 en bits = 000\r\n# Igual que y = y >> 3\r\n\r\n# <<= Desplazamiento a la izquierda en asignacion o bitside\r\n# Ejemplo:\r\ny = 5   # 5  en bits = 101\r\ny<<=3   # 3 en bits = 011\r\nprint(\"Desplazamiento a la izquierda:\", y) # 40 en bits = 101000\r\n# Igual que y = y << 3\r\n\r\nprint(\"\")\r\n# Operadores de Comparacion\r\n\r\n# == Igual que\r\n# Ejemplo:\r\nprint(3 == 4) # False\r\nprint(3 == 3) # True\r\n\r\n# != Diferente que\r\n# Ejemplo:\r\nprint(3 != 4) # True\r\nprint(3 != 3) # False\r\n\r\n# > Mayor que\r\n# Ejemplo:\r\nprint(3 > 4) # False\r\nprint(3 > 3) # False\r\nprint(4 > 3) # True\r\n\r\n# < Menor que\r\n# Ejemplo:\r\nprint(3 < 4) # True\r\nprint(3 < 3) # False\r\nprint(4 < 3) # False\r\n\r\n# >= Mayor o igual que\r\n# Ejemplo:\r\nprint(3 >= 4) # False\r\nprint(3 >= 3) # True\r\nprint(4 >= 3) # True\r\n\r\n# <= Menor o igual que\r\n# Ejemplo:\r\nprint(3 <= 4) # True\r\nprint(3 <= 3) # True\r\nprint(4 <= 3) # False\r\n\r\nprint(\"\")\r\n# Operadores Logicos\r\n\r\n# and\r\n# Ejemplo:\r\nprint(3 == 4 and 3 == 3) # False\r\nprint(3 == 3 and 3 == 4) # False\r\nprint(3 != 3 and 4 != 4) # False\r\nprint(3 == 3 and 4 == 4) # True\r\n\r\n# or\r\n# Ejemplo:\r\nprint(3 == 4 or 3 == 3) # True\r\nprint(3 == 3 or 4 == 4) # True\r\nprint(3 != 3 or 3 != 4) # True\r\nprint(3 != 3 or 4 != 4) # False\r\n\r\n# not\r\n# Ejemplo:\r\nprint(not 3 == 4) # True\r\nprint(not 3 == 3) # False\r\nprint(not (3 != 3 and 3 == 4)) # True\r\n\r\nprint(\"\")\r\n# Estructuras de Identidad\r\n\r\n# is\r\n# Ejemplo:\r\nx = 5\r\ny = 5\r\nprint(x is y) # True\r\n\r\n# is not\r\n# Ejemplo:\r\nx = 5\r\ny = 5\r\nprint(x is not y) # False\r\n\r\nprint(\"\")\r\n# Estructuras de Afiliacion\r\n\r\n# in\r\n# Ejemplo:\r\nx = [1, 2, 3, 4, 5]\r\nprint(3 in x) # True\r\nprint(6 in x) # False\r\n\r\n# not in\r\n# Ejemplo:\r\nx = [1, 2, 3, 4, 5]\r\nprint(3 not in x) # False\r\nprint(6 not in x) # True\r\n\r\nprint(\"\")\r\n# Estructuras de Procedencia de Operadores\r\n\r\n# ()\r\n# Ejemplo:\r\nprint(3 + 4 * 5) # 23\r\nprint((3 + 4) * 5) # 35\r\n\r\n# **\r\n# Ejemplo:\r\nprint(3 ** 4 * 5) # 405\r\nprint(3 ** (4 * 5)) # 810\r\n\r\n# *, /, //, %\r\n# Ejemplo:\r\nprint(3 * 4 / 5) # 2.4\r\nprint(3 * 4 // 5) # 2\r\nprint(3 * 4 % 5) # 2\r\n\r\n# +, -\r\n# Ejemplo:\r\nprint(3 + 4 - 5) # 2\r\n\r\n# <<, >>\r\n# Ejemplo:\r\nprint(3 << 4 >> 5) # 0\r\n\r\n# &\r\n# Ejemplo:\r\nprint(3 & 4) # 0\r\n\r\n# ^\r\n# Ejemplo:\r\nprint(3 ^ 4) # 7\r\n\r\n# |\r\n# Ejemplo:\r\nprint(3 | 4) # 7\r\n\r\n# >, >=, <, <=\r\n# Ejemplo:\r\nprint(3 > 4 >= 5) # False\r\nprint(3 < 4 <= 5) # True\r\n\r\n# ==, !=\r\n# Ejemplo:\r\nprint(3 == 4 != 5) # False\r\nprint(3 != 4 == 5) # True\r\n\r\nprint(\"\")\r\n# Estructuras de Control\r\n\r\n# if\r\n# Ejemplo:\r\nx = 5\r\nif x == 5:\r\n    print(\"Es igual a 5\")\r\n\r\n# else\r\n# Ejemplo:\r\nx = 5\r\nif x == 4:\r\n    print(\"Es igual a 4\")\r\nelse:\r\n    print(\"No es igual a 4\")\r\n\r\n# elif\r\n# Ejemplo:\r\nx = 5\r\nif x == 4:\r\n    print(\"Es igual a 4\")\r\nelif x == 5:\r\n    print(\"Es igual a 5\")\r\nelse:\r\n    print(\"No es igual a 4 o 5\")\r\n\r\n# while\r\n# Ejemplo:\r\nx = 0\r\nwhile x < 5:\r\n    print(x)\r\n    x += 1\r\n\r\n# for\r\n# Ejemplo:\r\nx = [1, 2, 3, 4, 5]\r\nfor i in x:\r\n    print(i)\r\n\r\n# break\r\n# Ejemplo:\r\nx = 0\r\nwhile x < 5:\r\n    print(x)\r\n    x += 1\r\n    if x == 3:\r\n        break\r\n\r\n# continue\r\n# Ejemplo:\r\nx = 0\r\nwhile x < 5:\r\n    x += 1\r\n    if x == 3:\r\n        continue\r\n    print(\"Continue\",x)\r\n\r\n# pass\r\n# Ejemplo:\r\nx = 0\r\nwhile x < 5:\r\n    x += 1\r\n    if x == 3:\r\n        pass\r\n    print(\"pass\",x)\r\n\r\n# else\r\n# Ejemplo:\r\nx = 0\r\nwhile x < 5:\r\n    print(x)\r\n    x += 1\r\nelse:\r\n    print(\"Fin del ciclo\")\r\n\r\n# try\r\n# Ejemplo:\r\ntry:\r\n    x = 5 / 0\r\nexcept:\r\n    print(\"Error\")\r\n\r\n# except\r\n# Ejemplo:\r\ntry:\r\n    x = 5 / 0\r\nexcept ZeroDivisionError:\r\n    print(\"No se puede dividir por 0\")\r\n\r\nprint(\"\")\r\n# Mis ejemplos \r\nx = 5 \r\nif (3 + 2) == x:\r\n    print(\"Es igual a 5\")\r\n\r\ny = 5\r\nif (x + y) == 10 or (x - y) == 0:\r\n    print(\"Es igual a 10 o 0\")\r\n\r\nz = 7\r\nif (x + y) == 10 and (z - y) != 0 or (z - y) == 2:\r\n    print(\"Es igual a 10 y 2\")\r\n\r\na = 5\r\nif (x + y) == 10 and (z - y) != 0 or (a - y) == 2:\r\n    print(\"Es igual a 10 y 2\")\r\nelse:\r\n    print(\"No es igual a 10 y 2\")\r\n\r\nwhile x <= 10:\r\n    print(\"Esto es un ciclo:\",x)\r\n    x += 1\r\n\r\nfor i in range(1, 10):\r\n    print(\"Esto es un ciclo:\",i)\r\n\r\n# Tarea \r\ni = 10\r\nwhile i <= 55:\r\n    if i % 2 == 0 and i % 3 != 0 and i != 16 or i == 55:\r\n        print(i)\r\n    i += 1\r\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/c3sarmx.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\"\"\"\n\nprint(\"========== Operadores Aritméticos ==========\")\n# Declaramos dos variables\na = 10\nb = 3\nprint(\"a = 10, b = 3\")\n\n# * Suma: Junta dos valores\nsuma = a + b\nprint(\"a + b:\", suma)\n\n# * Resta: Quita el segundo valor al primero\nresta = a - b \nprint(\"a - b:\", resta)\n\n# * Multiplicación: Repite el valor varias veces\nmultiplicacion = a * b\nprint(\"a * b:\", multiplicacion)\n\n# * División: Divide y devuelve un float (valor decimal)\ndivision = a / b \nprint(\"a / b:\", division)\n\n# * División entera: Divide y descarta los decimales\ndivision_entera = a // b \nprint(\"a // b:\", division_entera)\n\n# * Modulo: Devuelve lo que sobra de una división\nmodulo = a % b \nprint(\"a % b:\", modulo)\n\n# * Potencia: Eleva el primer número al exponente del segundo\npotencia = a ** b\nprint(\"a ** b:\", potencia)\n\n\nprint(\"========== Operadores de Comparación ==========\")\n# Declaramos dos variables\na = 10\nb = 3\nprint(\"a = 10, b = 3\")\n\n# * ¿Son iguales estos dos valores?\nprint(f\"Igualdad: a == b es {a == b}\") \n\n# * ¿Son distintos estos dos valores?\nprint(f\"Desigualdad: a != b es {a != b}\")\n\n# * ¿El de la izquierda es mayor?\nprint(f\"Mayor_que: a > b es {a > b}\")\n\n# * ¿El de la izquierda es menor?\nprint(f\"Menor_que: a < b es {a < b}\")\n\n# * ¿Es mayor o exactamente igual?\nprint(f\"Mayor_igual_que: a >= b es {a >= b}\")\n\n# * ¿Es menor o exactamente igual?\nprint(f\"Menor_igual_que: a <= b es {a <= b}\")\n\nprint(\"========== Operadores Lógicos ==========\")\n# Declaramos variables\nedad = 18\ntiene_id = True\npermiso = False\n\nprint(\"Edad: 18, Tiene id\")\n\n# * Usamos \"and\" para decidir, recordamos que en \"and\" ambos datos deben ser verdaderos.\nif edad >= 18 and tiene_id:\n    print(\"Tiene acceso\")\nelse:\n    print(\"No tienes acceso\")\n\n# * Usamos \"or\" para decidir, recordamos que en \"or\" al menos uno de los datos debe ser verdadero. \nif edad >= 18 and (tiene_id or permiso):\n    print(\"Tienes acceso\")\nelse:\n    print(\"No tienes acceso\")\n\nautorizacion = False\n\n# * Aquí usamos \"not\", en este caso la autorización por defecto es negada.\nif not autorizacion:\n    print(\"No tienes acceso\")\nelse:\n    print(\"Tienes acceso\")\n\nprint(\"========== Operadores de Asignación ==========\")\n# * \"x\" guarda \"10\"\nx = 10\nprint(x)\n\n# * Suma y guarda\nx += 10 #! x = x + 10\nprint(x)\n\n# * Resta y guarda\nx -= 10 #! x = x - 10\nprint(x)\n\n# * Multiplica y guarda\nx *= 10 #! x = x * 10\nprint(x)\n\n# * Divide y guarda\nx /= 10 #! x = x /10\nprint(x)\n\n# * Divide entero y guarda\nx //= 10 \nprint(x)\n\n# * Quedate con lo que sobra y guarda\nx %= 10\nprint(x)\n\nprint(\"========== Operadores de Identidad ==========\")\n# Declaramos dos listas\na = [1, 2, 3]\nb = [1, 2, 3]\n\nprint(\"a = [1, 2, 3]\")\nprint(\"b = [1, 2, 3]\")\n\nprint(\"lista a == lista b:\", a == b) #* True: mismo contenido\nprint(\"lista a is lista b:\", a is b) #* False: NO son el mismo objeto \n\nprint(\"========== Operadores de Pertenencia ==========\")\n# Declaramos una lista\nfrutas = [\"pera\", \"manzana\", \"piña\"]\n\nprint(\"frutas =\", frutas)\n\n#* in revisa si un elemento está dentro de la lista\nprint(\"pera in frutas:\", \"pera\" in frutas)\n\n#* not in revisa si un elemento NO está dentro de la lista\nprint(\"piña not in frutas:\", \"piña\" not in frutas)\n\nprint(\"=\" * 44)\nprint(\"========== Estructuras de control ==========\")\nprint(\"=\" * 44)\n\nprint(\"========== Condicionales ==========\")\n# Declaramos variable\nedad = 16\n\nif edad >= 18:\n    print(\"Eres mayor de edad\")\nelif edad >= 13:\n    print(\"Eres un adolescente\")\nelse:\n    print(\"Eres un niño\")\n\nprint(\"========== Iterativas ==========\")\nprint(\"== for ==\")\n\nfor num in range (1, 11): \n    print(num) #* “Para cada número del 1 al 10, imprímelo”\n#* Se cuantas veces repetir \"for\"\n\nprint(\"== while ==\")\n\ncontador = 1\n\nwhile contador <= 5:\n    print(contador)\n    contador += 1\n#* Depende de una condición \"while\"\n\nprint(\"=\" * 43)\nprint(\"========== Manejo de excepciones ==========\")\nprint(\"=\" * 43)\n\ntry:\n    resultado = 10 / 0\nexcept:\n    print(\"Ocurrió un error\")\n\n#* Manejo con 'else'\ntry:\n    numero = int(\"5\")\nexcept ValueError:\n    print(\"Error\")\nelse:\n    print(\"Conversión exitosa:\", numero) #* 'else' solo corre si no hubo excepción\n\n#* 'finally'\ntry:\n    numero = int(\"5\")\nexcept ValueError:\n    print(\"Error\")\nfinally:\n    print(\"Esto siempre se ejecuta\")\n\n#* try:\n    # código riesgoso\n#* except TipoDeError:\n    # qué hacer si falla\n#* else:\n    # qué hacer si todo salió bien\n#* finally:\n    # siempre se ejecuta\n\n# * DIFICULTAD EXTRA (opcional):\n# * Crea un programa que imprima por consola todos los números comprendidos\n# * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\nprint(\"=\" * 27)\nprint(\"========== EXTRA ==========\")\nprint(\"=\" * 27)\n\nfor num in range (10, 56):\n    if num % 2 == 0 and num != 16 and num % 3: #* % pregunta: ¿que sobra? si sobra 0 = division exacta, != 0 hay residuo\n        print(num)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/camilo-zuluaga.py",
    "content": "# Operadores aritméticos de python\nprint(\"-Operadores aritméticos-\")\n\n# Contamos con 7 operadores aritméticos: +, -, *, /, //, %, **\n\nnum1, num2 = 5, 2\n\nsuma = num1 + num2  # 7\nresta = num1 - num2  # 3\nmultiplicacion = num1 * num2  # 10\ndivision = num1 / num2  # 2.5\ndivision_entera = num1 // num2  # 2\nmodulos = num1 % num2  # 1\nexponente = num1**num2  # 25\n\nprint(\n    f\"\"\"\n    Suma: {suma}\n    Resta: {resta}\n    Multiplicacion: {multiplicacion}\n    Division: {division}\n    Division entera: {division_entera}\n    Modulos: {modulos}\n    Exponente: {exponente}\n    \"\"\"\n)\n\nprint(\"\\n-Operadores lógicos-\")\n\n# Contamos con 3 operadores lógicos: and, or, not\n\na, b = True, False\n\nand_operator = a and b  # False\nor_operator = a or b  # True\nnot_operator = not a  # False\n\nprint(\n    f\"\"\"\n    AND: {and_operator}\n    OR: {or_operator}\n    NOT: {not_operator}\n    \"\"\"\n)\n\nprint(\"\\n-Operadores de comparación-\")\n\n# Contamos con 6 operadores de comparación: >, <, >=, <=, ==, !=\n\na, b = 5, 10\n\nmayor = a > b  # False\nmenor = a < b  # True\nmayor_igual = a >= b  # False\nmenor_igual = a <= b  # True\nigual = a == b  # False\ndiferente = a != b  # True\n\nprint(\n    f\"\"\"\n    Mayor: {mayor}\n    Menor: {menor}\n    Mayor o igual: {mayor_igual}\n    Menor o igual: {menor_igual}\n    Igual: {igual}\n    Diferente: {diferente}\n    \"\"\"\n)\n\nprint(\"\\n-Operadores de asignación-\")\na = 7\nb = 2\n\n\"\"\"\nLos operadores de asignación o assignment operators \nnos permiten realizar una operación y almacenar su \nresultado en la variable inicial:\n\n    +=, -=, *=, /=, %=, **=, //=, &=, |=, ^=, >>=, <<=\n    \nPodemos ver como realmente el único operador nuevo es el =. \nEl resto son abreviaciones de otros operadores que habíamos visto con anterioridad. \n\"\"\"\n\nprint(f\"a = {a}, b = {b}\")\na += b\nprint(\"a+=\", a)  # 9\na -= b\nprint(\"a-=\", a)  # 5\na *= b\nprint(\"a*=\", a)  # 14\na /= b\nprint(\"a/=\", a)  # 3.5\na %= b\nprint(\"a%=\", a)  # 1\n\nprint(\"\\n-Operadores de identidad-\")\n# Python reutiliza el mismo objeto en memoria por lo que ambas variables apuntan al mismo objeto\na, b = 5, 5\n\n# Python crea dos objetos diferentes en memoria, por lo que a pesar de tener el mismo valor, no son el mismo objeto\nc = [1, 2, 3]\nd = [1, 2, 3]\n\nprint(\n    f\"\"\"\n    A is B: {a is b}\n    A is not B: {a is not b}\n    C is D: {c is d}\n    C is not D: {c is not d}\n    \"\"\"\n)\n\nprint(\"\\n-Operadores de pertenencia-\")\n\n# Contamos con dos operadores de pertenencia: in y not in.\n# Nos devuelve true si el elemento pertenece al segundo elemento\n\nstring_in = \"Hola\" in \"Hola Mundo\"  # True\nstring_not_in = \"Hola\" not in \"Retos de Programación\"  # True\nstring_in_false = \"Hola\" in \"Retos de Programación\"  # False\nprint(\n    f\"\"\"\n    \"Hola\" in \"Hola Mundo\": {string_in}\n    \"Hola\" not in \"Retos de Programación\": {string_not_in}\n    \"Hola\" in \"Retos de Programación\": {string_in_false}\n    \"\"\"\n)\n\n# También podemos usarlo con listas\n\nS = [1, 2, 3, 4, 5]\n\nlist_in = 1 in S  # True\nlist_in_false = 6 in S  # False\nlist_not_in = 6 not in S  # True\n\nprint(\n    f\"\"\"\n    1 in [1, 2, 3, 4, 5]: {list_in}\n    6 not in [1, 2, 3, 4, 5]: {list_not_in}\n    6 in [1, 2, 3, 4, 5]: {list_in_false}\n    \"\"\"\n)\n\nprint(\"\\n-Operadores de bits-\")\n\n# Los operadores a nivel de bit o bitwise operators son operadores que actúan sobre números enteros pero usando su representación binaria.\n\nf, g = 60, 13\nbitwise_and = f & g  # And bit a bit\nbitwise_or = f | g  # Or bit a bit\nbitwise_xor = f ^ g  # Xor bit a bit\nbitwise_not = ~f  # Not bit a bit\nbitwise_left_shift = g << 2  # Desplazamiento a la izquierda\nbitwise_right_shift = g >> 1  # Desplazamiento a la derecha\n\nprint(\n    f\"\"\"\n    Bitwise AND: {bitwise_and}\n    Bitwise OR: {bitwise_or}\n    Bitwise XOR: {bitwise_xor}\n    Bitwise NOT: {bitwise_not}\n    Bitwise Desplazamiento a la izquierda: {bitwise_left_shift}\n    Bitwise esplazamiento a la derecha: {bitwise_right_shift}\n    \"\"\"\n)\n\nprint(\"\\n-Estructuras de control-\")\n\nprint(\"\\n-> Condicionales\")\nedad = 0\n\nif edad > 0:\n    print(\"El numero es mayor a 0 y es positivo\")\nelif edad == 0:\n    print(\"El numero es 0\")\nelse:\n    print(\"El numero es negativo\")\n\nprint(\"\\n-> Iterativas\")\n\nprint(\"\\n-> For\")\nfor i in range(5):\n    print(i)\n\nprint(\"\\n-> While\")\nwhile edad < 5:\n    print(edad)\n    edad += 1\n\nprint(\"\\n-> Excepciones\")\n\ntry:\n    print(edad)\nexcept NameError:\n    print(\"La variable no esta definida\")\nfinally:\n    print(\"Se ejecuta siempre\")\n\n\nprint(\"\\n-Desafios-\")\n\n\"\"\" Crea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3. \"\"\"\n\n\nfor i in range(10, 56):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print(i)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/carlosalberto05.py",
    "content": "'''\nOperadores\n'''\n\n#Operadores aritméticos\nprint(f\"Suma:15 + 5 = {15 + 5}\")\nprint(f\"Resta:250 - 30 = {250 - 30}\")\nprint(f\"Multiplicación:2*3 = {2 * 3}\")\nprint(f\"División: 10/30 = {10 / 3}\")\nprint(f\"Módulo: 10%30 = {10 % 30}\")\nprint(f\"Exponente: 5**2 = {5 ** 2}\")\nprint(f\"División entera: 10//30 = {10 // 3}\")\n\n#Operadores de comparación\nprint(f\"Igualdad: Juan == Puan = {'Juan' == 'Juan'}\")\nprint(f\"Igualdad: Juan != Pedro = {'Juan' != 'Pedro'}\")\nprint(f\"Mayor que: 8 > 9 = {8 > 9}\")\nprint(f\"Menor que: 8 < 9 = {8 < 9}\")\nprint(f\"Mayor que: 8 >= 8 = {8 >= 8}\")\nprint(f\"Menor que: 8 <= 12 = {8 <= 2}\")\n\n#Operadores lógicos\nprint(f\"AND &&: 3 == 3 and 8 < 10 es { 3 == 3 and 8 < 10}\")\nprint(f\"OR ||: 3 > 3 or 2 > 1 es {3 > 3 or 2 > 1}\")\nprint(f\"NOT !: not 3 + 3 == 9 es {not 3 + 3 == 9}\")\n\n#Operadores de asignación\nmy_data = 'Hola' #Asignación\nprint(my_data)\nmy_data += ' mouredev' #Contenar \"suma\" y asignación\nprint(my_data) \nnew_data = 10 #Asignación y asignación\nprint(new_data)\nnew_data -= 5 #Resta y asignación\nprint(new_data)\nnew_data *= 5 #Multiplicación y asignación\nprint(new_data)\nnew_data /= 5 #División y asignación\nprint(new_data)\nnew_data %= 3 #Módulo y asignación\nprint(new_data)\nnew_data **= 5 #Módulo y asignación\nprint(new_data)\nnew_data //= 3 #División entera y asignación\nprint(new_data)\n\n#Operadores de identidad\nmy_new_data = new_data\nprint(f\"my_new_data is new_data es {my_new_data is new_data}\")\nprint(f\"my_new_data is not new_data es {my_new_data is not new_data}\")\n\n#Operadores de pertenencia\nprint(f\" 'a' in 'carlos' = {'a' in 'carlos'}\")\nprint(f\" 'e' not in 'carlos' = {'e' not in 'carlos'}\")\n\n#Operadores de bit\nx = 10 #1010\ny = 3 #0011\nprint(f\"AND: 10 & 3 = {10 & 3}\") #0010 que es 2\nprint(f\"OR: 10 | 3 = {10 | 3}\") #1011 que es 11\nprint(f\"XOR: 10 ^ 3 = {10 ^ 3}\") #1001 que es 9\nprint(f\"NOT: ~10 = {~10}\") # que es -11\nprint(f\"Desplazamiento a la derecha: 10>>2 = {10>>2}\") #0010 que es 2\nprint(f\"Desplazamiento a la izquierda: 10<<2 = {10<<2}\") #101000 que es 40\n\n'''\nEstructuras de control\n'''\n\n#Condicionales\nis_empty = True\nif is_empty == True:\n    print(\"Está vacío\")\n#elif\nelse:\n    print(\"No está vacío\")\n\n#Iterativas\nfor i in range(11):\n    print(i)\n    \ni = 0\n\nwhile i <= 10:\n    print(i)\n    i += 1\n    \n#Manejo de excepciones\ntry:\n\tprint(10/0)\nexcept: \n    print(\"Error en el programa\")\nfinally:\n    print(\"Ha finalizado el manejo de excepciones\")\n\n'''\nExtra\n'''\n\nfor i in range(10,56):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n    \tprint(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/carlosmarte23.py",
    "content": "'''\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n'''\n\n# Ejemplos de operadores en Python:\n\n# OPERADORES ARITMETICOS:\nnumero_1 = 5;\nnumero_2 = 10;\n\nprint(\"Operadores aritmeticos:\")\nprint(f\"Suma: {numero_1 + numero_2}\");\nprint(f\"Resta: {numero_1 - numero_2}\");\nprint(f\"Multiplicacion: {numero_1 * numero_2}\");\nprint(f\"Potencia: {numero_1 ** numero_2}\");\nprint(f\"Division: {numero_1 / numero_2}\");\nprint(f\"Division entera: {numero_1 // numero_2}\");\nprint(f\"Modulo: {numero_1 % numero_2}\");\nprint(\"##########################################\")\n\n# OPERADORES DE COMPARACION:\nprint(\"Operadores de comparacion:\")\nprint(f\"Mayor que: {numero_1 > numero_2}\");\nprint(f\"Menor que: {numero_1 < numero_2}\");\nprint(f\"Mayor o igual que: {numero_1 >= numero_2}\");\nprint(f\"Menor o igual que: {numero_1 <= numero_2}\");\nprint(f\"Igualdad: {numero_1 == numero_2}\");\nprint(f\"Desigualdad: {numero_1!= numero_2}\");\nprint(\"##########################################\")\n\n# OPERADORES DE ASIGNACION:\nprint(\"Operadores de asignacion:\")\nnumero_1 = 5;\nnumero_2 = 10;\n\nresultado = 0;\n# Asignacion de suma:\nresultado += numero_1;\nprint(f\"Asignacion de suma: {resultado}\");\n\n# Asignacion de resta:\nresultado -= numero_2;\nprint(f\"Asignacion de resta: {resultado}\");\n\n# Asignacion de multiplicacion:\nresultado *= numero_1;\nprint(f\"Asignacion de multiplicacion: {resultado}\");\n\n# Asignacion de division:\nresultado /= numero_2;\nprint(f\"Asignacion de division: {resultado}\");\n\n# Asignacion de modulo:\nresultado %= numero_1;\nprint(f\"Asignacion de modulo: {resultado}\");\nprint(\"##########################################\")\n\n# OPERADORES LOGICOS:\nprint(\"Operadores logicos:\")\nverdadero = True;\nfalso = False;\n\nprint(f\"Condicional AND: {verdadero and verdadero}\");\nprint(f\"Condicional OR: {verdadero or falso}\");\nprint(f\"Negacion: {not verdadero}\");\nprint(\"##########################################\")\n\n# OPERADORES DE IDENTIDAD:\nprint(\"Operadores de identidad:\")\nprint(f\"Identidad 'is': {numero_1 is numero_1}\");\nprint(f\"Identidad con negacion 'is not': {numero_1 is not numero_2}\");\nprint(\"##########################################\")\n\n# OPERADORES DE PERTENENCIA:\nprint(\"Operadores de pertenencia:\")\nprint(\"Ejemplo de pertenencia in:\")\nlista = [1, 2, 3, 4, 5];\nprint(f\"1 in lista: {1 in lista}\");\n\nprint(\"Ejemplo de pertenencia not in:\")\ntexto = \"Python\";\nprint(f\"Z not in texto: { 'Z' not in texto}\");\nprint(\"##########################################\")\n\n# OPERADORES DE BIT:\nprint(\"Operadores de bits:\")\nbyte_1 = 0b00010101;\nbyte_2 = 0b00011011;\n\nprint(f\"Byte 1: {bin(byte_1)}, Byte 2: {bin(byte_2)}\");\nprint(\"Ejemplo de operador AND bit a bit:\")\nprint(f\"Resultado AND bit a bit: {bin(byte_1 & byte_2)}\");\n\nprint(\"Ejemplo de operador OR bit a bit:\")\nprint(f\"Resultado OR bit a bit: {bin(byte_1 | byte_2)}\");\n\nprint(\"Ejemplo de operador XOR bit a bit:\")\nprint(f\"Resultado XOR bit a bit: {bin(byte_1 ^ byte_2)}\");\n\nprint(\"Ejemplo de operador NOT bit a bit:\")\nprint(f\"Resultado NOT bit a bit: {bin(~byte_1)}\");\n\nprint(\"Ejemplo de operador RIGHT SHIFT bit a bit:\")\nprint(f\"Resultado RIGHT SHIFT bit a bit: {bin(byte_1 >> 1)}\");\n\nprint(\"Ejemplo de operador LEFT SHIFT bit a bit:\")\nprint(f\"Resultado LEFT SHIFT bit a bit: {bin(byte_1 << 1)}\");\nprint(\"##########################################\")\n\n# OPERADORES DE ITERACION:\nprint(\"Operadores de iteracion:\")\nprint(\"Ejemplo de iteracion for:\")\nfor i in range(1, 10):\n  print(f\"Iteracion for: {i}\");\n\nprint(\"Ejemplo de iteracion while:\")\ni = 1;\nwhile i <= 10:\n  print(f\"Iteracion while: {i}\");\n  i += 1;\n\nprint(\"Ejemplo de iteracion for-else:\")\nfor i in range(1, 10):\n  print(f\"Iteracion for-else: {i}\");\nelse:\n  print(\"Fin del for-else\");\n\nprint(\"Ejemplo de iteracion while-else:\")\ni = 1;\nwhile i <= 10:\n  print(f\"Iteracion while-else: {i}\");\n  i += 1;\nelse:\n  print(\"Fin del while-else\");\nprint(\"##########################################\")\n\n# OPERADORES DE EXCEPCIONES:\nprint(\"Operadores de excepciones:\")\ntry:\n  print(\"Ejemplo de try:\")\n  print(numero_1 / 0);\nexcept ZeroDivisionError:\n  print(\"Error de division por cero\");\n\ntry:\n  print(\"Ejemplo de try-except-else:\")\n  print(numero_1 / 0);\nexcept ZeroDivisionError:\n  print(\"Error de division por cero\");\nelse:\n  print(\"No hubo error de division por cero\");\n\ntry:\n  print(\"Ejemplo de try-except-finally:\")\n  print(numero_1 / 0);\nexcept ZeroDivisionError:\n  print(\"Error de division por cero\");\nfinally:\n  print(\"Se ejecuta siempre\");\nprint(\"##########################################\")\n\n# Ejercicio Extra:\nprint(\"Ejercicio Extra:\")\nfor i in range(10, 55):\n  if i % 2 == 0 and i!= 16 and i % 3!= 0:\n    print(i)\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/carrenoalexander.py",
    "content": "\"\"\"\n * Operadores\n\"\"\"\n\n# Aritméticos \n\nprint(f\"Addition: 18 + 8 = {18 + 8}\")\nprint(f\"Subtraction: 18 - 8 = {18 - 8}\")\nprint(f\"Multiplication: 18 * 8 = {18 * 8}\")\nprint(f\"Division: 18 / 8 = {18 / 8}\")\nprint(f\"Modulus: 18 % 8 = {18 % 8}\")\nprint(f\"Floor division: 18 // 8 = {18 // 8}\")\nprint(f\"Exponentiation: 18 ** 8 = {18 ** 8}\")\n\n# Lógicos\n\nprint(True == True and False == False)\nprint(False == True or False == False)\nprint(not True)\n\n# Comparación\n\nprint(f\"Greater than: 24 > 24: {24 > 24}\")\nprint(f\"Less than: 24 < 24: {24 < 24}\")\nprint(f\"Greater than or equal to: 24 >= 24: {24 >= 24}\")\nprint(f\"Less than or equal to: 24 <= 24: {24 <= 24}\")\nprint(f\"Equal: 24 == 24: {24 == 24}\")\nprint(f\"Not equal: 24 != 24: {24 != 24}\")\n\n# Asignación\n\nnumber = 12\n\nnumber += 2\nprint(number)\nnumber -= 2\nprint(number)\nnumber *= 2\nprint(number)\nnumber /= 2\nprint(number)\nnumber %= 2\nprint(number)\nnumber //= 2\nprint(number)\nnumber **= 2\nprint(number)\n\n# Identidad\n\nvariable = None\n\nprint(f\"My variable is None: {variable is None}\")\nprint(f\"My variable is not None: {variable is not None}\")\n\n# Pertenencia\n\nprint(f\"'E' in word: {\"E\" in \"word\"}\")\nprint(f\"'E' not in word: {\"E\" not in \"word\"}\")\n\n# Bits\n\na = 8  # 1000\nb = 10  # 1010\n\nprint(f\"AND: 8 & 10 = {8 & 10}\")  # 0001 <\nprint(f\"OR: 8 | 10 = {8 | 10}\")   # 0101 <\nprint(f\"XOR: 8 ^ 10 = {8 ^ 10}\")  # 0100 <\nprint(f\"NOT: ~8 = {~8}\")\nprint(f\"Right shift: 8 >> 10: {8 >> 2}\")  # 0010\nprint(f\"Left shift: 8 << 10: {8 << 2}\")   # 100000\n\n\"\"\"\n * Estructuras de control\n\"\"\"\n\n# Condicionales\n\nlanguage = \"Python\"\n\nif language == \"JavaScript\":\n    print(\"The language is JavaScript\")\nelif language == \"Python\":\n    print(\"The language is Python\")\nelse:\n    print(\"It could be another language\")\n\n# Iterativas\n\nfor number in range(1, 9):\n    print(number)\n\nage = 0\n\nwhile age <= 8:\n    print(age)\n    age += 2\n\n# Excepciones\n\ntry:\n    print(18 / 0)\nexcept:\n    print(\"Cannot divide by zero\")  # ZeroDivisionError\nfinally:\n    print(\"Try again\")\n\n\"\"\"\n * Extra\n\"\"\"\n\nfor extra_number in range(10, 56):\n    if extra_number %2 == 0 and extra_number != 16 and extra_number %3 != 0:\n        print(extra_number)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/cbuenrostrovalverde.py",
    "content": "\"\"\"\nOperadores aritméticos\n\"\"\"\n\nsuma = 3 + 4\nresta = 5 - 2\nmultiplicacion = 3 * 5\ndivision = 8 / 3\nmodulo = 8 % 2\nexponencial = 2 ** 2\ndivision_entera = 7 // 2\n\nprint('El resultado de los operadores aritmeticos son: ')\nprint(f'El resultado de la suma 3 + 4 es: {suma}')\nprint(f'El resultado de la resta 5 - 2 es: {resta}')\nprint(f'El resultado de la multiplicacion 3 * 5 es: {multiplicacion}')\nprint(f'El resultado de la division 8 / 3 es: {division}')\nprint(f'El resultado de la modulo 8 % 2 es: {modulo}')\nprint(f'El resultado de la exponencial es 2 ** 2: {exponencial}')\nprint(f'El resultado de la division entera 7 // 2 es: {division_entera}')\n\n\"\"\"\nOperadores relacionales\n\"\"\"\n\nprint(f'Mayor que: 10 > 3 es {10 > 3}')\nprint(f'Menor que: 3 < 10 es {3 < 10}')\nprint(f'Igual que: 3 = 3 es {3 == 3}')\nprint(f'Mayor o igual que: 10 >= 10 es {10 >= 10}')\nprint(f'Menor o igual que: 10 <= 3 es {10 <= 10}')\nprint(f'No es igual 7 a 3 es {7 != 3} ')\n\n\"\"\"\nOperadores lógicos\n\"\"\"\n\nprint(f'AND &&: 10 + 3 es 13 AND 15 - 2 es 13 {10 + 3 == 13 and 15 - 2 == 13 }')\nprint(f'OR: 10 + 3 == 15 or 5 - 1 == 4 es {10 + 3 == 13 or 5 - 1 == 4}')\nprint(f'NOT: 10 + 3 == 14 es {not 10 + 3 == 14} ')\n\n\n'''\nOperadores de asignación\n'''\n\nmi_numero = 4\nprint(mi_numero)\n\n# suma y asignación\nmi_numero += 1\nprint(mi_numero)\n# Resta y asignación\nmi_numero -= 2\nprint(mi_numero)\n# multiplicación y asignación\nmi_numero *= 2\nprint(mi_numero)\n# división y asignación\nmi_numero /= 2\nprint(mi_numero)\n# Exponencial y asignación\nmi_numero **= 2\nprint(mi_numero)\n\n'''Operadores \nde identidad\n'''\n\nmy_new_number = mi_numero\nprint(f'my_new_number is my_new_number es {mi_numero is my_new_number}')\nprint(f'my_new_number is my_new_number es {mi_numero is not my_new_number}')\n\n# Operadores de bit\na = 10  # 1010\nb = 3  # 0011\nprint(f\"AND: 10 & 3 = {10 & 3}\")  # 0010\nprint(f\"OR: 10 | 3 = {10 | 3}\")  # 1011\nprint(f\"XOR: 10 ^ 3 = {10 ^ 3}\")  # 1001\nprint(f\"NOT: ~10 = {~10}\")\nprint(f\"Desplazamiento a la derecha: 10 >> 2 = {10 >> 2}\")  # 0010\nprint(f\"Desplazamiento a la izquierda: 10 << 2 = {10 << 2}\")  # 101000\n\n\"\"\"\nEstructuras de control\n\"\"\"\n\n# Condicionales\n\nmy_string = \"Carlos\"\n\nif my_string == \"cbuenrostrovalverde\":\n    print(\"my_string es 'cbuenrostrovalverde'\")\nelif my_string == \"Carlos\":\n    print(\"my_string es 'Carlos'\")\nelse:\n    print(\"my_string no es 'cbuenrostrovalverde' ni 'Carlos'\")\n\n# Iterativas\n\nfor i in range(11):\n    print(i)\n\ni = 0\n\nwhile i <= 10:\n    print(i)\n    i += 1\n\n# Manejo de excepciones\ntry:\n    print(10 / 0)\nexcept:\n    print(\"Se ha producido un error\")\nfinally:\n    print(\"Ha finalizado el manejo de excepciones\")\n\n\"\"\"\nExtra: imprimir por pantalla números entre 10 - 55\n\"\"\"\n\nfor numero in range (10, 56):\n    if numero %2 == 0 and numero != 16 and numero % 3 != 0:\n        print(numero)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/cdbiancotti.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n#  *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n#  *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n\n# Aritméticos\nprint(2 + 2)\nprint(2 - 2)\nprint(2 * 2)\nprint(3 / 2)\nprint(3 // 2)\nprint(2 % 2)\nprint(2 ** 2)\n\n# lógicos\nprint(True and True)\nprint(True or True)\nprint(not True)\n\n# comparación\nprint(2 == 2)\nprint(2 != 2)\nprint(2 > 2)\nprint(2 < 2)\nprint(2 >= 2)\nprint(2 <= 2)\n\n# asignación\na = 2\nprint(a)\na += 2\nprint(a)\na *= 2\nprint(a)\na **= 2\nprint(a)\na -= 2\nprint(a)\na /= 2\nprint(a)\na //= 2\nprint(a)\na %= 2\nprint(a)\nif test := 5 + 5:\n    print(test)\n\ndicc = {'test': 2}\ndicc2 = dicc\n\n# identidad\nprint(dicc is dicc2)\n\n# pertenencia\nprint('test' in dicc2)\n\n# bits\na = 0b1010\nb = 0b1101\n\nprint(~15)\nprint(~(-15))\nprint(a & b)\nprint(a | b)\nprint(a ^ b)\n\nprint(2 << 4)\nprint(21 >> 4)\n\n#  * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n#  *   que representen todos los tipos de estructuras de control que existan\n#  *   en tu lenguaje:\n#  *   Condicionales, iterativas, excepciones...\n#  * - Debes hacer print por consola del resultado de todos los ejemplos.\n\nprint('\\n=== if-elif-else ===\\n')\n\n\ndef if_elif_else(value):\n    if value == 1:\n        print('IF')\n    elif value == 2:\n        print('ELIF1')\n    elif value == 3:\n        print('ELIF2')\n    else:\n        print('ELSE')\n\n\nif_elif_else(1)\nif_elif_else(2)\nif_elif_else(3)\nif_elif_else(0)\n\nprint('\\n=== while-else ===\\n')\n\n\ndef while_else(iterations_number):\n    count = 1\n    while count < iterations_number:\n        print(f'while iteration {count}.')\n        if count == 4:\n            print('The iterations stop for a break sentence.')\n            break\n        count += 1\n    else:\n        print('This is a print from else related with a while.')\n\n\nwhile_else(3)\nwhile_else(5)\n\nprint('\\n=== for-else ===\\n')\n\n\ndef for_else(iterations_number):\n    for val in range(iterations_number):\n        print(f'for iteration {val}.')\n        if val == 4:\n            print('The iterations stop for a break sentence.')\n            break\n    else:\n        print('This is a print from else related with a for.')\n\n\nfor_else(3)\nfor_else(5)\n\nprint('\\n=== match ===\\n')\n\n\ndef show_match(value):\n    match value:\n        case 1:\n            print('case 1')\n        case 2:\n            print('case 2')\n        case _:\n            print('default case')\n\n\nshow_match(1)\nshow_match(2)\nshow_match(3)\n\nprint('\\n=== try-except-else-finally ===\\n')\n\n\ndef try_except_else_finally(value):\n    try:\n        print('try')\n        division = 5 / value\n        if division == 1:\n            return 'return value from try'\n    except ZeroDivisionError as error:\n        print('except ZeroDivisionError', error)\n        return 'return value from except ZeroDivisionError'\n    except Exception as error:\n        print('except Exception', error)\n        return 'return value from except Exception'\n    else:\n        print('else from try')\n        return 'return value from else'\n    finally:\n        print('finally')\n        return 'return value from finally'\n\n\nresult = try_except_else_finally(5)\nprint(result)\nresult = try_except_else_finally(6)\nprint(result)\nresult = try_except_else_finally(0)\nprint(result)\nresult = try_except_else_finally('a')\nprint(result)\n\n\nprint('\\n=== Dificultad extra ===\\n')\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea un programa que imprima por consola todos los números comprendidos\n#  * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\nfor num in (x for x in range(10, 55, 2) if not (x == 16 or x % 3 == 0)):\n    print(num)\n\n#  * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n#  */\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/cesar-ch.py",
    "content": "﻿# Operadores Aritméticos\na = 5\nb = 2\nprint(\"Suma:\", a + b)\nprint(\"Resta:\", a - b)\nprint(\"Multiplicación:\", a * b)\nprint(\"División:\", a / b)\nprint(\"Módulo:\", a % b)\nprint(\"Incremento:\", a + 1)\nprint(\"Decremento:\", b - 1)\n\n# Operadores de Comparación\nx = 10\ny = \"10\"\nprint(\"Igualdad:\", x == y)\nprint(\"Igualdad \", x == int(y))\nprint(\"Desigualdad:\", a != b)\nprint(\"Mayor que:\", a > b)\nprint(\"Menor que o igual:\", a <= b)\n\n# Operadores Lógicos\np = True\nq = False\nprint(\"AND lógico:\", p and q)\nprint(\"OR lógico:\", p or q)\nprint(\"NOT lógico:\", not p)\n\n# Operadores de Asignación\nc = 3\nc += 2\nprint(\"Asignación con adición:\", c)\n\n# Operadores de Identidad\nprint(\"Identidad:\", x == 10)\nprint(\"Identidad:\", y == 10)\n\n# Operadores de Pertenencia\narreglo = [1, 2, 3]\nprint(\"Pertenece al arreglo:\", 2 in arreglo)\n\n# Operadores de Bits\nnum1 = 5  # Representación binaria: 0101\nnum2 = 3  # Representación binaria: 0011\nprint(\"AND a nivel de bits:\", num1 & num2)  # Resultado: 0001 (1 en binario)\nprint(\"OR a nivel de bits:\", num1 | num2)  # Resultado: 0111 (7 en binario)\nprint(\"Desplazamiento a la izquierda:\", num1 << 1)  # Resultado: 1010 (10 en binario)\nprint(\"Desplazamiento a la derecha:\", num1 >> 1)  # Resultado: 0010 (2 en binario)\n\n# Estructuras de Control\n# Condicionales\nedad = 18\nif 18 <= edad <= 125:\n    print(\"Eres mayor de edad\")\nelif edad < 18:\n    print(\"Eres menor de edad\")\nelse:\n    print(\"Edad no válida\")\n\n# Excepciones\ntry:\n    resultado = 10 / 0\n    print(\"Resultado:\", resultado)\nexcept ZeroDivisionError as error:\n    print(\"Error:\", error)\nfinally:\n    print(\"Finalizado el bloque try-catch\")\n\n# Programa\nfor i in range(10, 56):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/cevicheconaji.py",
    "content": "# Operadores aritméticos\n\nx = 5\ny = 2\n\nprint(\"Suma:\", x + y)\nprint(\"Resta:\", x - y)\nprint(\"Multiplicación:\", x * y)\nprint(\"División:\", x / y)\nprint(\"Módulo:\", x % y)\nprint(\"Potencia:\", x ** y)\nprint(\"División entera:\", x // y)\n\n# Operadores de comparación\n\nz = 10\nw = 20\n\nprint(\"Igualdad:\", z == w)\nprint(\"Desigualdad:\", z != w)\nprint(\"Mayor\", z > w)\nprint(\"Menor\", z < w)\nprint(\"Mayor o igual\", z >= w)\nprint(\"Menor o igual\", z <= w)\n\n# Operadores lógicos\n\nprint(True and True)\n\nprint(False or True)\n\nprint(not False)\n\n# Operadores de asignación\na = 5\na += 2\nprint(\"Asignación con adición:\", a)\n\nb = 10\nb -= 2\nprint(\"Asignación con sustracción:\", b)\n\nc = 3\nc *= 2\nprint(\"Asignación con multiplicación:\", c)\n\nd = 10\nd /= 2\nprint(\"Asignación con división:\", d)\n\ne = 10\ne %= 3\nprint(\"Asignación con módulo:\", e)\n\nf = 2\nf **= 3\nprint(\"Asignación con potencia:\", f)\n\ng = 10\ng //= 3\nprint(\"Asignación con división entera:\", g)\n\n# Operadores de identidad\n\nh = 10\ni = 10\nprint(\"Identidad:\", h is i)\n\nj = 10\nk = 20\nprint(\"Identidad:\", j is k)\n\nprint(\"Identidad con not:\", j is not k)\n\n# Operadores de pertenencia\n\nl = [1, 2, 3, 4, 5]\nprint(\"Pertenece a la lista:\", 4 in l)\n\nm = [1, 2, 3, 4, 5]\nprint(\"Pertenece a la lista:\", 6 in m)\n\nprint(\"Pertenece a la lista con not:\", 6 not in m)\n\n# Operadores de bits\n\nn = 5\no = 3\n\nprint(\"AND a nivel de bits:\", n & o)\n\nprint(\"OR a nivel de bits:\", n | o)\n\nprint(\"XOR a nivel de bits:\", n ^ o)\n\nprint(\"Desplazamiento a la izquierda:\", n << 1)\n\nprint(\"Desplazamiento a la derecha:\", n >> 1)\n\n# Operadores walrus y iteradores\n\np = 10\n\nif (q := p + 1) > p:\n    print(\"El valor de q es:\", q)\n\nr = 10\n\nwhile (s := r - 1) > 0:\n    print(\"El valor de s es:\", s)\n    r = s\n\nfor t in range(10):\n    print(\"El valor de t es:\", t)\n\n#excepciones\ntry:\n    print(u)\nexcept NameError as e:\n    print(\"Error:\", e)\n\n'''Ejercicio extra \nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n'''\n\nfor u in range(10, 56):\n    if u % 2 == 0 and u != 16 and u % 3 != 0:\n        print(u)\n\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/christiancoc.py",
    "content": "# Tipos de operadores\n\n# Operadores aritméticos\nnumber1 = 10\nnumber2 = 2\n\nsuma = number1 + number2\nresta = number1 - number2\nmultiplicacion = number1 * number2\ndivision = number1 / number2\ndivision_entera = number1 // number2\nmodulo = number1 % number2\npotenciacion = number1 ** number2\n\n# Operadores de asignación\nnumber1 += number2\nnumber1 -= number2\nnumber1 *= number2\nnumber1 /= number2\nnumber1 %= number2\nnumber1 **= number2\n\n# Operadores de comparación\nigual = (number1 == number2)\nno_igual = (number1 != number2)\nmayor = (number1 > number2)\nmayor_igual = (number1 >= number2)\nmenor = (number1 < number2)\nmenor_igual = (number1 <= number2)\n\n# Operadores logicos\ny = True\nx = False\nprint(y and x)\nprint(y or x)\nprint(not x)\n\n# Operadores de pertenencia\nstring = \"hola\"\nprint(\"h\" in string)\nprint(\"h\" not in string)\n\n# Operadores de identidad\nlista_de_numeros = [1, 2, 3]\ntupla_de_numeros = (1, 2, 3)\nuna_lista = lista_de_numeros\n\nprint(una_lista is lista_de_numeros)\nprint(una_lista is not tupla_de_numeros)\nprint(lista_de_numeros is tupla_de_numeros)\n\n# Tipos de estructuras de control\n\n# Condicionales\nif number1 > number2:\n    print(\"number1 es mayor que number2\")\nelif number1 < number2:\n    print(\"number1 es menor que number2\")\nelse :\n    print(\"number1 es igual que number2\")\n\n# while\nnumber3 = 5\nwhile number3 > 0:\n    print(number3)\n    number3 -= 1\n\n# for in\nfor number4 in lista_de_numeros:\n    print(number4)\n    \n# for range\nfor number5 in range(10, 20, 2):\n    print(number5)\n    \n# break\nfor number6 in range(10, 20, 2):\n    print(number6)\n    if number6 == 16:\n        break\n    \n# continue\nfor number7 in range(10, 20, 2):\n    if number7 == 16:\n        continue\n    print(number7)\n    \n# excepciones\ndef division(a, b):\n    try:\n        return a / b\n    except ZeroDivisionError:\n        print(\"No se puede dividir por cero\")\n        \ndivision(5, 0)\n    \n# Extra\nexcluir_numero = 16\nfor i in range(10, 55, 2):\n    if i == excluir_numero or i % 3 == 0:\n        continue\n    print(i)\n\n    \n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/clainu04.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n#  *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n#  *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n#  * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n#  *   que representen todos los tipos de estructuras de control que existan\n#  *   en tu lenguaje:\n#  *   Condicionales, iterativas, excepciones...\n#  * - Debes hacer print por consola del resultado de todos los ejemplos.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea un programa que imprima por consola todos los números comprendidos\n#  * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n#  *\n#  * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n#  */\n\nnum_1 = int(input(\"Dame un numero: \"))\nnum_2 = int(input(\"Dame otro numero: \"))\n\noperacion = int(input(\"Que operacion quieres realizar? \\n 1. Suma \\n 2. Resta \\n 3. Multiplicacion \\n 4. Division \\n\"))\n\nsuma = num_1 + num_2\nresta = num_1 - num_2\nmultiplicacion = num_1 * num_2\ndivision = num_1 / num_2\n\nif operacion == 1:\n    print(f\"El resultado de la suma es: {suma}\")\nelif operacion == 2:\n    print(f\"El resultado de la resta es: {resta}\")\nelif operacion == 3:\n    print(f\"El resultado de la multiplicacion es: {multiplicacion}\")\nelif operacion == 4:\n    print(f\"El resultado de la division es: {division}\")\nelse:\n    print(\"No se ha realizado ninguna operacion\")\n    \n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/clmiranda.py",
    "content": "# Operadores Aritmeticos\nprint(34 + 78)  # Suma\nprint(43 - 19)  # Resta\nprint(27 * 8)  # Producto\nprint(112 / 14)  # División\nprint(103 % 7)  # Modulo\nprint(12**6)  # Potencia\nprint(18 // 5)  # División con resultado entero\n\n\n# Operadores Lógicos\nx, y = True, False\nprint(x and y)  # True and False => False\nprint(x or y)  # True or False => True\nprint(not y)  # Valor opuesto de False => True\n\n\n# Operadores de Pertenencia\nlst = [1, 3, 9, 17, 22, 187, 99]\nprint(22 in lst)  # True\nprint(112 in lst)  # False\nprint(456 not in lst)  # True\nprint(99 not in lst)  # False\n\n\n# Operadores de Identidad\na, b = \"Python\", \"JavaScript\"\nprint(a is b)  # False\nprint(a is not b)  # True\n\n\n# Operadorees de Comparación\nprint(10 > 8)  # True\nprint(19 < 11)  # False\nprint(15 >= 15)  # True\nprint(58 <= 26)  # False\nprint(29 == 30)  # False\nprint(44 != 88)  # True\n\n\n# Operadores a nivel de Bits\nprint(3 | 7)  # 7\nprint(3 ^ 7)  # 4\nprint(3 & 7)  # 3\nprint(3 << 7)  # 384\nprint(3 >> 7)  # 0\nprint(~7)  # -8\n\n\n# Operadores de Asignación\nm, n = 24, 4\nm += n  # m = m + n\nm -= n  # m = m - n\nm *= n  # m = m * n\nm /= n  # m = m / n\nm %= n  # m = m % n\nm //= n  # m = m // n\nm **= n  # m = m ** n\nm = int(m)\nm |= n  # m = m | n\nm ^= n  # m = m ^ n\nm &= n  # m = m & n\nm <<= n  # m = m << n\nm >>= n  # m = m >> n\n\n\n# Estructuras de Control Condicionales\n# if-elif-else\nif 4 >= 3 >= 1 and True is not False:\n    print(\"Primer cuatrimestre\")\nelif 8 >= 7 >= 5 and 1 in [2, 6, 8, 1]:\n    print(\"Segundo cuatrimestre\")\nelif 12 >= 10 >= 9 and not False:\n    print(\"Tercer cuatrimestre\")\nelse:\n    print(\"Valores incorrectos\")\n\n\n# Estructuras de Control Iterativas\n# for\nfor i in range(0, 30):\n    if i % 2 == 1:\n        print(i, end=\" \")\n\n\n# while\nprint()\nresul = 50\nwhile resul >= 20:\n    resul -= 7\nprint(f\"El resultado es: {resul}\")\n\n\n# Estructuras de Control para Manejo de Excepciones\n# exception\nv1, v2 = 45, \"Hola Mundo\"\ntry:\n    v1 += v2\nexcept TypeError:\n    print(\"Error: no se puede sumar un tipo de dato int con uno str\")\n\n\n# Crea un programa que imprima por consola todos los números comprendidos entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\nprint([i for i in range(10, 56) if i % 2 == 0 and i != 16 and i % 3 != 0])\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/codeskin-r.py",
    "content": "# Operadores aritmeticos\n\na = 5\nb = 3\n\nsuma = a + b              # 10 + 5 = 15\nresta = a - b             # 10 - 4 = 6\nmultiplicacion = a * b    # 10 * 3 = 30\ndivision = a / b          # 4 / 2 = 2\ndivision_entera = a // b  # 10 / 3 = 3 (redondeado hacia abajo)\nmodulo = a % b            # 10 % 3 = 1 (resto de la division)\npotencia = a ** b         # 10^3 = 1000\n\nprint(suma, resta, multiplicacion, division, division_entera, modulo, potencia)\n\n\n# Operadores de asignacion\n\nx = 5     # Asignación normal\n\nx += 3    # Equivale a: x = x + 3  → x = 8\nx -= 2    # x = x - 2  → x = 6\nx *= 4    # x = x * 4  → x = 24\nx /= 3    # x = x / 3  → x = 8.0\nx //= 2   # x = x // 2  → x = 4.0\nx %= 3    # x = x % 3  → x = 1.0\nx **= 2   # x = x ** 2  → x = 1.0\n\nprint(x)\n\n# Operadores de comparacion\n\na = 10\nb = 5\n\nprint(a == b)    # False (10 no es igual a 5)\nprint(a != b)    # True (10 es diferente de 5)\nprint(a > b)     # True (10 es mayor que 5)\nprint(a < b)     # False (10 no es menor que 5)\nprint(a >= 10)   # True (10 es mayor o igual a 10)\nprint(a <= 5)    # False (10 no es menor o igual a 5)\n\n\n# Operadores logicos\n\nx = True\ny = False\n\nprint(x and y)  # False (Ambos deben ser True)\nprint(x or y)   # True (Basta con que uno sea True)\nprint(not x)    # False (Invierte el valor de x)\n\n\n# Operadores de identidad\n\na = [1, 2, 3]\nb = a\nc = [1, 2, 3]\n\nprint(a is b)      # True (b apunta al mismo objeto que a)\nprint(a is not c)  # True (c es una lista nueva, aunque tenga los mismos valores)\n\n\n# Operadores de pertenencia\n\nfrutas = [\"manzana\", \"banana\", \"cereza\"]\n\nprint(\"manzana\" in frutas)  # True (manzana está en la lista)\nprint(\"pera\" not in frutas) # True (pera NO está en la lista)\n\n\n# Operadores Bit a Bit\n\na = 5  # En binario:  0101\nb = 3  # En binario:  0011\n\nprint(a & b)  # AND →  0101 & 0011 = 0001 → 1\nprint(a | b)  # OR  →  0101 | 0011 = 0111 → 7\nprint(a ^ b)  # XOR →  0101 ^ 0011 = 0110 → 6\nprint(~a)     # NOT →  ~0101 = -6  (por cómo maneja Python los bits)\nprint(a << 1) # Desplazar bits a la izquierda (multiplica por 2) → 1010 → 10\nprint(a >> 1) # Desplazar bits a la derecha (divide por 2) → 0010 → 2\n\n\n\n\n\n# Ejemplos de estructuras de control\n\n\n# Condicionales (if, elif, else)\n# Bucles (for, while)\n# Control de flujo en bucles (break, continue, pass)\n\n\n# Condicionales\n\n# se usan para ejecutar codigo solo si se cumplen ciertas condiciones\n\nedad = 20\n\nif edad >= 18:  # Comparación con >=\n    print(\"Eres mayor de edad.\")\nelif edad == 17:  # Comparación con ==\n    print(\"Casi eres mayor de edad.\")\nelse:\n    print(\"Eres menor de edad.\")\n\n\n# Ejemplo con operadores logicos\n\nusuario = \"admin\"\nclave = \"5432\"\n\nif usuario == \"admin\" and clave == \"5432\":  # AND lógico\n    print(\"Acceso permitido\")\nelse:\n    print(\"Acceso denegado\")\n\n\n# Ejemplo con operadores de identidad y pertenencia\n\nlista = [1, 2, 3, 4]\nx = 3\n\nif x in lista:  # Pertenencia\n    print(\"El número está en la lista.\")\n\nif type(x) is int:  # Identidad\n    print(\"x es un entero.\")\n\n\n\n# Bucle (for)\n\n# Se usa para recorrer secuencias (listas, tuplas, cadenas, etc.)\n\n# Usando un bucle for con operadores aritméticos\nfor i in range(1, 6):  # Genera números del 1 al 5\n    print(f\"El cuadrado de {i} es {i**2}\")  # Operador de potencia\n\n\n# Ejemplo con listas y operadores de asignación\n\nnumeros = [1, 2, 3, 4, 5]\nsuma = 0\n\nfor num in numeros:\n    suma += num  # Operador de asignación (+=)\n\nprint(\"La suma total es:\", suma)\n\n\n# Ejemplo con cadenas y pertenencia\n\npalabra = \"Python\"\n\nfor letra in palabra:\n    if letra in \"aeiou\":  # Verifica si es una vocal\n        print(f\"{letra} es una vocal\")\n\n\n# Bucle (while)\n\nx = 10\n\nwhile x > 0:  # Condición con operador de comparación\n    print(f\"x vale {x}\")\n    x -= 2  # Resta usando operador de asignación (-=)\n\n# Ejemplo con operadores logicos\n\nnumero = 1\n\nwhile numero < 10 and numero % 2 != 0:  # AND lógico y operador módulo\n    print(f\"{numero} es impar\")\n    numero += 2\n\n\n\n# Control de flujo en bucles (break, continue, pass)\n\n\n# Estos comandos permiten modificar el comportamiento de los bucles\n\n# break (sale del bucle)\n\nfor num in range(10):\n    if num == 5:\n        print(\"Se encontró el 5, saliendo del bucle.\")\n        break  # Detiene la ejecución\n    print(num)\n\n# continue (salta a la siguiente iteracion)\n\nfor num in range(1, 6):\n    if num == 3:\n        continue  # Salta la iteración cuando num es 3\n    print(num)\n\n# pass (se usa como marcador de posicion)\n\nfor num in range(3):\n    pass  # No hace nada, evita errores de sintaxis\n\nif True:\n    pass  # Se usa cuando aún no hemos definido la lógica\n\n\n\"\"\"\nDIFICULTAD EXTRA:\nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\"\"\"\n\n# Bucle que recorre los números del 10 al 55 (incluidos)\n\n#for numero in range(10, 56):  # range(10, 56) genera números del 10 al 55\n\n#    if numero % 2 != 0:  # Si el número NO es par, lo saltamos\n#        continue  # Salta a la siguiente iteración\n\n#    if numero == 16:  # Si el número es 16, lo saltamos\n#        continue\n\n#    if numero % 3 == 0:  # Si el número es múltiplo de 3, lo saltamos\n#        continue\n\n#    print(numero)  # Si pasa todos los filtros, lo imprimimos\n\nfor n in range(10, 56, 2):  # Solo números pares del 10 al 55\n    if n != 16 and n % 3:\n        print(n)\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/csaraugusto2.py",
    "content": "#01 OPERADORES Y ESTRUCTURAS DE CONTROL\n\n# Ejercicios\n\n# - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n\n# ARITMETICOS\n\nprint('\\nOperaciones Aritmeticas\\n')\nprint('----------------------------Inicio-------------------------------------\\n')\n# Suma (+)\nn1 = 5\nn2 = 3\n\nsuma = n1 + n2\n\nprint(f'Suma: {n1} + {n2} = {suma}\\n')\n\n# Resta (-)\n\nresta = n1 - n2\n\nprint(f'Resta: {n1} - {n2} = {resta}\\n')\n\n# multiplicacion (*)\n\nmult = n1 * n2\n\nprint(f'Multiplicacion: {n1} x {n2} = {mult}\\n')\n\n# Division (/)\n\ndiv = n1 / n2\n\nprint(f'Division: {n1} / {n2} = {div}\\n')\n\n# Modulo (%)\n\nmodulo = n1 % n2\n\nprint(f'Residuo: {n1} % {n2} = {modulo}\\n')\n\n# Potencia (**)\n\npotencia = n1 ** n2\n\nprint(f'Potencia: {n1}^{n2} = {potencia}\\n')\n\n# Cociente (//)\n\ncociente = n1 // n2\n\nprint(f'Cociente: {n1} // {n2} = {cociente}\\n')\n\nprint('----------------------------Fin----------------------------------------\\n')\n\n# Concatenacion de cadenas de caracteres\nprint('Concatenacion de cadenas de caracteres\\n')\n\nprint('----------------------------Inicio-------------------------------------\\n')\n\nc1 = 'Hola'\nc2 = 'Pyton'\n\nconcat = 'Unimos esta frase para decir: \"' + c1 + ' ' + c2 + '\"'\nprint(f'Concatenaremos una frase con: ({c1}) y ({c2}) en la linea siguente:')\nprint(concat,'\\n')\n\nprint('----------------------------Fin----------------------------------------\\n')\n\n# Logicos (and, or, not) y Booleanos (true/False)\n\nA = True\nB = False\nprint(f'Manejo de los Operadores logicos con resultados Booleanos {A} y {B}\\n')\nprint('----------------------------Inicio-------------------------------------\\n')\n\nresultado = A and B #Falso\nprint(f'AND: {A} Y {B} = {resultado}') \n\nresultado = A or B #Verdadero\nprint(f'OR: {A} O {B} = {resultado}')\n\nresultado = not B # Cambia Falso por Verdadero\nprint(f'NOT: NO {B} = {resultado}\\n') # Cambia Verdadero por Falso\n\nprint('----------------------------Fin----------------------------------------\\n')\n\n# Operadores de Comparacion ( mayor > , mayor o igual >= , menor < , menor o igual <= , igual ==)\n\nprint('Operadores de Comparacion\\n')\nprint('----------------------------Inicio-------------------------------------\\n')\n\nresultado = n1 < n2\nprint(f'{n1} es menor a {n2} ? --> {resultado}')\n\nresultado = n1 <= n2\nprint(f'{n1} es menor o igual a {n2} ? --> {resultado}')\n\nresultado = n1 == n2\nprint(f'{n1} es igual a {n2} ? --> {resultado}')\n\nresultado = n1 >= n2\nprint(f'{n1} es mayor o igual a {n2} ? --> {resultado}')\n\nresultado = n1 > n2\nprint(f'{n1} es mayor a {n2} ? --> {resultado}\\n')\n\nprint('----------------------------Fin----------------------------------------\\n')\n\n# Operadores de asignacion (=)\nprint('Operadores de asignacion\\n')\nprint('----------------------------Inicio-------------------------------------\\n')\n\nconcat = 'Aqui estamos asignando esta cadena de caracteres a la variable \"concat\" para luego mostrarla en el print'\nprint(concat,'\\n')\n\nprint('----------------------------Fin----------------------------------------\\n')\n\n# - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n#   que representen todos los tipos de estructuras de control que existan\n#   en tu lenguaje:\n\nprint('Ejemplos de operaciones con estructuras de control\\n')\n\n# Condicionales\nprint('Condicionales if/elif/else\\n')\nprint('----------------------------Inicio-------------------------------------\\n')\n\nprint(f'Si {n1} es menor a {n2} mostrar la suma de ambos, sino mostrar la resta')\nif n1 < n2:\n    p = n1 + n2\n    print(f'La suma es: {n1} + {n2} = {p}\\n')\nelif n1 > n2:\n    p = n1 - n2\n    print(f'La resta es: {n1} - {n2} = {p}\\n')\n\nprint('----------------------------Fin----------------------------------------\\n')\n\n# Iterativas\nprint('Iteraciones con Wile y For\\n')\n\ni = 0\n# Wile\nprint('iteracion de 1 a 5 con Wile\\n')\nprint('----------------------------Inicio-------------------------------------\\n')\n\nwhile i != n1:\n    i += 1\n    print(i)\n\nprint('----------------------------Fin----------------------------------------\\n')\n\n# For\n\nprint('5 iteraciones de solo numero pares con For\\n')\nprint('----------------------------Inicio-------------------------------------\\n')\nfor i in range(5):\n    i *= 2\n    print(i)\n\nprint('----------------------------Fin----------------------------------------\\n')\n\n# Excepciones\nprint('Excepciones\\n')\nprint('----------------------------Inicio-------------------------------------\\n')\n\nvar1 = 5\nvar2 = \"Cinco\"\n\nprint(f'Intentamos sumar ({var1} + {var2}) y capturaremos el error')\n\ntry:\n    resultado = var1 + var2\nexcept Exception as ex:\n    print(f'Ha ocurrido un error: {ex}')\n\nprint('\\n----------------------------Fin----------------------------------------\\n')\n\n\n\n\n# Dificultad extra\n'''    \nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n'''\nprint('Ejercicio adicional propuesto como Dificultad Extra\\n')\nprint('----------------------------Inicio-------------------------------------\\n')\n\nprint('Números comprendidos entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3')\n\nfor i in range(10,55):\n    if i != 16 and i % 2 == 0 and i % 3 != 0:\n        print(i)\n\nprint('----------------------------Fin----------------------------------------\\n')\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/culebropalido.py",
    "content": "#!/usr/bin/env  python3\n\"\"\"\n *\n * #01 OPERADORES Y ESTRUCTURAS DE CONTROL\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia,\n *   bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto\n * algo nuevo.\n \"\"\"\n\n# Operadores Aritméticos\n\n# Suma\nprint(\"\\n[+]Operadores Aritméticos\\n\")\na = 5\nb = 2\nprint(\"Suma:\", a, \"+\", b, \"=\", a + b)\n\n# Resta\nprint(\"Resta: %d - %d =\" % (a, b),  a - b)\n\n# Multiplicación\nprint(\"Multiplicación:\", a, \"*\", b, \"=\", a * b)\n\n# División\nprint(\"División: %d / %d =\" % (a, b),  a / b)\n\n# División entera\nprint(\"División entera:\", a, \"//\", b, \"=\", a // b)\n\n# Módulo (resto)\nprint(\"Hallar el resto: %d mod %d =\" % (a, b), a % b)\n\n# Exponenciación\nprint(f\"Potencias: {a} elevado a {b} =\", a ** b)\n\n# Operadores de comparación\nprint(\"\\n[+] Operadores de comparación\\n\")\n\n# Igual a ==\nprint(\"%d es igual a %d\" % (a, b), a == b)\n\n# Distinto de !=\nprint(a, \"es distinto de\", b, a != b)\n\n# Mayor que\nprint(\"%d es mayor que %d\" % (a, b), a > b)\n\n# Menor que\nprint(a, \"Es menor que\", b, a < b)\n\n# Mayor igual que\nprint(f\"{a} es mayor o igual que {b}\", a >= b)\n\n# Menor igual que\nprint(f\"{a} es menor o igal que {b}\", a <= b)\n\nprint(\"Tambien sirve para strings, Hola es mayor que Python?\", \"Hola\" > \"Python\")\nprint(\"Otro ejemplo: Oceanos es mayor que mar?\", \"Oceano\" > \"Mar\")\nprint(\"Lobo es igual a Lobo?\", \"Lobo\" == \"Lobo\")\nprint(\"Cuidado, no cuenta los caracteres, si no que hace una ordenacion alfabetica, para contar caracteres hay que utilizar la función leb()\")\nprint (\"Ejemplo, es Terremoto menor que Gato?\", len(\"Terremoto\") < len(\"Gato\"))\n# Operadores lógicos\n\n# AND Devuelve True si ambos son True\nprint(\"\\n[+] Operadores Lógicos\\n\")\n\n# Operando AND devuelve True si todos los argumentos son True\nprint(\"a es igual a\", a, \"AND(y) b es igual a\", b, a == a and b == b)\n\n# Operando OR devuele True si solo uno de los argumentos es True\nprint(f\"{a} es menor que {b} OR(o) {b} es menor que {a}\", a < b or b < a)\n\n# Operando NOT invierte el resultado, si es True devuelve False\nprint(f\"{a} es mayor que {b} NOT(no)\", not a > b)\n\n# Operadores de Asignación\n\nprint(\"\\n[+] Operadores de Asignación\\n\")\nvar_a = 7\nvar_b = 3\n\n# Operador =\nprint(f\"= asigna el valor a una variable var_a = 7 var_a vale: {var_a}\")\n\n# Operador Incremento +=\nvar_a += 3\nprint(\"+= suma el valor del operando derecho al operando izquierdo y se asigna al operando izquierdo\", var_a)\n\n# Operado decremento -=\nvar_b -= 3\nprint (\"-= resta el valor del operando derecho al valor del operando izquierdo %d\" % var_b)\n\n# Operando Multiplicación *=\nvar_a *= 7\nprint (\"*= Multiplica el operando derecho con el operando izquierdo y asigna el resultado al operando izquierdo\", var_a)\n\n# Operando Division /=\nvar_b /= 3\nprint (f\"/= Divide el operando izquierdo por el operando derecho y asigna el resultado al operando izquierdo {var_b}\")\n\n# División entera //=\nvar_a //= 5\nprint(\"Realiza una división entera entre el operando izquierdo y el operando derecho y asigna el resultado al operando izquierdo %d\" % var_a)\n\n# Módulo %=\nvar_b %= 2\nprint(f\"Calcula el módulo del operando izquierdo por el operando derecho y asigna el resultado al operando izquierdo {var_b}\")\n\n# Exponenciación **=\nvar_a **= 3\nprint(f\"Calcula el módulo del operando izquierdo por el operando derecho y asigna el resultado al operando izquierdo {var_a}\")\n\n# Operadores de bits\nprint(\"\\n[+] Operadores de bits\\n\")\na = 10\nb = 4\n\n# Operador AND\nprint(\"& Realiza una operación AND bit a bit a & b =\", a & b)\n\n# Operador OR\nprint(\"| Realiza una operación OR bit a bit a | b =\", a | b)\n\n# Operador XOR\nprint(\"^ Realiza una operación XOR bit a bit a ^ b =\", a ^ b)\n\n# Operado NOT\nprint(\"~ Realiza una operación NOT bit a bit ~ a =\", ~ a)\n\n# Operadores de Memebresia\n\nprint(\"\\n[+] Operadores de Memebresia\\n\")\n\nlista = [\"Gato\", \"Perro\", \"Pajaro\", \"Pez\"]\n\n# Operado in\nprint(lista)\nprint(\"El operador 'in' verifica si un elemento esta presente en una secuencia\")\nprint(\"¿Esta Perro en la lista?\\n\", \"Perro\" in lista)\n\n# Operando not in\nprint(\"El operador 'not in' verifica si un elemento no esta en una secuencia\")\nprint(\"¿NO esta Oso en la lista?\\n\", \"oso\" not in lista)\n\n# Operadores de identidad\nprint(\"\\n[+] Operadores de Identidad\\n\")\nlista = [1, 2, 3]\nb = lista\nc = lista[:]\n\nprint(lista)\n\nprint(\"El operador 'is' verifica son el mismo objeto. ¿a is b?\", a is b)\nprint(\"Otro ejemplo, ¿a is c?\", c is b)\n\n# Estructuras de control\nprint(\"\\n[+] Estructuras de control\\n\")\n# If\nvalor_a = 5\nvalor_b = 8\n\n# If\nif valor_b > valor_a:\n    print(valor_a, \" Es mayor que \", valor_b)\n\n# If else\nif valor_a > valor_b:\n    print(valor_a, \" Es mayor que \", valor_b)\nelse:\n    print(valor_a, \" Es menor que \", valor_b)\n\n# if elif\nvalor_a = 5\nvalor_b = 5\nif valor_a > valor_b:\n    print(valor_a, \" Es mayor que \", valor_b)\nelif valor_a == valor_b:\n    print(valor_a, \" es igual a \", valor_b)\nelse:\n    print(valor_a, \" Es menor que \", valor_b)\n\n# For in\n# Iterar sobre una lista sacar el contenido por pantalla mientras se rellena\n# una tupla con el contenido de la lista\nlista = [\"P\", \"y\", \"t\", \"h\", \"o\", \"n\"]\ntupla = ()\nfor i, x in enumerate(lista):\n    print(f\"\\n Visualizando lista elemento: {i} | Valor: {x}\")\n    tupla = tupla + (i, x)\nprint(f\"\\nVisualizando tupla creada {tupla}\\n\")\n\n# Rellenan un lista con un for que va del 0 al 10 e imprimir la lista por\n# pantalla\nlista = []\nfor i in range(10):\n    lista.append(i)\nprint(lista)\n\n# Rellenar una lista mientras i valga menos de 30.\nwhile i < 30:\n    lista.append(i)\n    print(lista)\n    i += 1\n\n# Control de execepciones con Try Except\ntry:\n    resultado = 10 / 0\nexcept:\n    print(\"Se produjo una excepción\")\n\n# Reto opcional\nprint(\"\\nListar los numero del 16 al 55 incluidos, menos los impares, el 16 y los multiplos de 3\")\nfor i in range(16, 55):\n    if i == 16:\n        i += 1\n    else:\n        if i % 2 == 0:\n            if i % 3 != 0:\n                print(f\"{i} Es par y No es multiplo de 3\")\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/d0ubt0.py",
    "content": "#Operadores logicos Python\n\n#Aritmeticos\nprint(1 + 1)\nprint(1 - 1 )\nprint(2 * 2)\nprint(4 / 2)\nprint(5 // 2)\nprint(12 % 3)\nprint(3 ** 2)\n\n#Comparacion\nprint((2 == 3))\nprint((2 != 3))\nprint((2>3))\nprint((2<3))\nprint((2>=3))\nprint((2<=3))\n\n#Logicos\nprint(False and True)\nprint(False or True)\nprint(not True)\n\n#Identidad\na = 1\nb = 1\nprint((a is b))\nprint((a is not b))\n\n#Pertenencia\nprint('Python' in 'Estoy practicando en Python')\n\ndef es_multiplo_3(n : int):\n    if n % 3 == 0:\n        return True\n    return False\n\ndef es_par(n: int):\n    if n % 2 == 0:\n        return True\n    return False\n\nfor i in range(10 ,56):\n    if i == 13 or es_multiplo_3(i):\n        continue\n    if es_par(i):\n        print(i)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/dandrusco.py",
    "content": "# Operadores Aritméticos:\na = 10\nb = 3\n\nsuma = a + b\nresta = a - b\nmultiplicacion = a * b\ndivision = a / b\nresto = a % b\ndivision_entera = a // b\nexponente = a ** b\n\nprint(suma, resta, multiplicacion, division, resto , division_entera, exponente)\n\n# Operadores Lógicos:\np = True\nq = False\n\ny_logico = p and q\no_logico = p or q\nnegacion = not p\n\nprint(y_logico, o_logico, negacion)\n\n# Operadores de Comparación:\nx = 5\ny = 10\n\nigual = x == y\ndiferente = x != y\nmenor_que = x < y\nmayor_que = x > y\nmenor_igual = x <= y\nmayor_igual = x >= y\n\nprint(igual, diferente, menor_que, mayor_que, menor_igual, mayor_igual)\n\n# Operadores de Asignación:\na = 5\nb = 2\n\na += b\nprint(a)\n\na *= 3\nprint(a)\n\n# Estructuras Condicionales:\nx = 10\n\nif x > 0:\n    print(\"x es positivo\")\nelif x == 0:\n    print(\"x es cero\")\nelse:\n    print(\"x es negativo\")\n\n# Bucle for:\nfor i in range(5):\n    print(i)\n\n# Bucle while:\nn = 0\n\nwhile n < 5:\n    print(n)\n    n += 1\n\n# Estructuras de Control de Flujo usando break:\nfor i in range(10):\n    if i == 5:\n        break\n    print(i)\n\n# Estructuras de Control de Flujo usando continue\nfor i in range(5):\n    if i == 2:\n        continue\n    print(i)\n\n\n# DIFICULTAD EXTRA (opcional):\nfor num in range(10, 56):\n    # Verificar si el número es par y no es el 16 ni múltiplo de 3\n    if num % 2 == 0 and num != 16 and num % 3 != 0:\n        print(num)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/danielhdzr.py",
    "content": "#01 OPERADORES Y ESTRUCTURAS DE CONTROL\n# '''\n# EJERCICIO:\n#  * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n#  *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n#  *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n#  * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n#  *   que representen todos los tipos de estructuras de control que existan\n#  *   en tu lenguaje:\n#  *   Condicionales, iterativas, excepciones...\n#  * - Debes hacer print por consola del resultado de todos los ejemplos.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea un programa que imprima por consola todos los números comprendidos\n#  * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n#  *\n#  * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n# '''\n\ndef main():\n    a = 1\n    b = 2\n    print()\n    print(\"Operadores aritmeticos\")\n    print(a + b)\n    print(a - b)\n    print(a * b) \n    print(a / b)\n    print(a // b)\n    print(a % b)\n    print(a ** b)\n\n    print()\n\n    print(\"Operadores logicos\")\n    print(a < b and b > a)\n    print(a > b or b > a)\n    print(not (a > b and b > a))\n\n    print()\n\n    print(\"Operadores de comparacion\")\n    print(a == b)\n    print(a < b)\n    print(a > b)\n    print(a <= b)\n    print(a >= b)\n    print(a != b)\n\n    print()\n\n    print(\"Operadores de asignacion\")\n    # =   \n    x = 3\t\n    print(x)\n    # +=\t\n    x += 3\t\t\n    print(x)\n    # -=\t\n    x -= 3\t\n    print(x)\n    # *=\t\n    x *= 3\n    print(x)\t\t\n    # /=\t\n    x /= 3\n    print(x)\t \n    # %=\t\n    x %= 3\n    print(x)\t\n    # //=\t\n    x //= 3\n    print(x)\t\t\n    # **=\t\n    x **= 3\n    print(x)\n    # :=  \t\n    print(x := 3)\t\n    print(\"(este es su equivalente)\")\n    x = 3  \n    print(x)\n    \n    print()\n\n    print(\"Operadores de identidad\")\n    print(a is b)\n    print(a is not b)\n\n    print()\n\n    print(\"Operadores de pertenencia\")\n    lista1 = [\"apple\",\"orange\"]\n\n    print(\"apple\" in lista1)\n    print(\"orange\" not in lista1)\n\n    print()\n\n    print(\"Operadores de bits\")\n    # AND\n    print(a & b)\t\n    # OR\n    print(a | b)\t\n    # XOR \n    print(a ^ b)\t\n    # NOT\n    print(~b)\t\n    # Zero fill left shift\n    print(a << 2)\n    # Signed right shifT\n    print(a >> 2)\n\n    print()\n\n    print(\"Operadores con estructuras de control\")\n    print()\n\n    print(\"Condicional If\")\n    if a > b:\n        print(\"a es mayor que b\")\n    elif a < b:\n        print(\"a es menor que b\")\n    else:\n        print(\"a y b son iguales\")\n\n    print()\n\n    print(\"Inicia while loop\")\n    while a <= b:\n        print(a)\n        a += 1\n        if a > b:\n            break\n    print(\"Termina el while loop\")\n\n    print()\n\n    print(\"Inicia for loop\")\n    print(\"Lista 1 contiene:\")\n    lista2 = list()\n    for i in (lista1):\n        print(i)\n        lista2.append(i)\n    if \"banana\" not in lista2:\n        lista2.append(\"banana\")\n    print(f\"Nueva lista contiene: {lista2}\")\n\n    print()\n\n    print(\"Comienza try/except\")\n    try:\n        int(lista1)\n    except TypeError:\n        print(\"No se puede convertir lista 2 a int\")\n        \nif __name__==\"__main__\":\n    main()"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/danielperezrubio.py",
    "content": "def print_section(name: str, lines_from_top: int = 0) -> None:\n    [print() for i in range(lines_from_top)]\n\n    print(f\"{'*' * 14} {name} {'*' * 14}\")\n    print(\"-\" * 60)\n\n\ndef print_sub_section(title: str) -> None:\n    print(f\"\\n** {title} **\")\n\n\n# ************** Operadores **************\nprint_section(\"Operadores\")\n\n\n# ** Operadores Aritméticos **\nprint_sub_section(\"Operadores Aritméticos\")\n# Suma\nprint(f\"10 + 4 = {10 + 4}\")\n# Resta\nprint(f\"10 - 4 = {10 - 4}\")\n# Multiplicación\nprint(f\"10 * 4 = {10 * 4}\")\n# División\nprint(f\"28 / 7 = {28 / 7}\")\n# Módulo\nprint(f\"5 % 2 = {5 % 2}\")\n# División entera\n\"\"\"\nLa división entera redondea cerca de cero solo\ncuando los números son positivos.\n\"\"\"\nprint(f\"10 // 3 = {10 // 3}\")\nprint(f\"10 // -3 = {10 // -3}\")\n# Potencia\nprint(f\"4**2 = {4**2}\")\n\n\n#  ** Operadores Lógicos **\nprint_sub_section(\"Operadores Lógicos\")\n\"\"\"\nSe pueden usar tanto True y False como los números 0 y 1,\nsiendo 0: False y 1: True\n\"\"\"\n# and\nprint(f\"True and False = {True and False}\")\nprint(f\"0 and 1 = {0 and 1}\")\n# or\nprint(f\"True or False = {True or False}\")\nprint(f\"1 or 0 = {1 or 0}\")\n# not\nprint(f\"not True = {not True}\")\nprint(f\"not 1 = {not 1}\")\n\n\n# ** Operadores de Comparación **\nprint_sub_section(\"Operadores de Comparación\")\n# Menor que\nprint(f\"4 < 8 = {4 < 8}\")\n# Mayor que\nprint(f\"4 > 8 = {4 > 8}\")\n# Igual\nprint(f\"4 == 8 = {4 == 8}\")\n# Mayor o igual\nprint(f\"4 >= 8 = {4 >= 8}\")\n# Menor o igual\nprint(f\"4 <= 8 = {4 <= 8}\")\n# Distinto\nprint(f\"4 != 8 = {4 != 8}\")\n\n\n# ** Operadores de Concatenación **\nprint_sub_section(\"Operadores de Concatenación\")\nprint(f\"'ab' + 'cd' = '{'ab' + 'cd'}'\")\n\n\n# ** Operadores de Bits **\nprint_sub_section(\"Operadores de Bits\")\n# and\nprint(f\"10 & 4 = {10 & 4}\")\n# or\nprint(f\"10 | 4 = {10 | 4}\")\n# not\nprint(f\"~10 = {~10}\")\n# xor\nprint(f\"10 ^ 4 = {10 ^ 4}\")\n# Desplazamiento a izquierda\nprint(f\"10 << 4 = {10 << 4}\")\n# Desplazamiento a derecha\nprint(f\"10 >> 4 = {10 >> 4}\")\n\n\n# ** Operadores de Asignación **\nprint_sub_section(\"Operadores de Asignación\")\nx = 4\nprint(f\"x = 4   = {4}\")\nprint(f\"x += 4   = {x + 4}\")\nprint(f\"x -= 4   = {x - 4}\")\nprint(f\"x *= 4   = {x * 4}\")\nprint(f\"x /= 4   = {x / 4}\")\nprint(f\"x %= 4   = {x % 4}\")\nprint(f\"x //= 4   = {x // 4}\")\nprint(f\"x **= 4   = {x ** 4}\")\nprint(f\"x &= 4   = {x & 4}\")\nprint(f\"x |= 4   = {x | 4}\")\nprint(f\"x ^= 4   = {x ^ 4}\")\nprint(f\"x <<= 4   = {x << 4}\")\nprint(f\"x >>= 4   = {x >> 4}\")\n\n\n# ** Operadores de Identidad **\nprint_sub_section(\"Operadores de Identidad\")\nprint(f\"True is False = {True is False}\")\nprint(f\"True is not False = {True is not False}\")\n\n\n# ** Operadores de Pertenencia **\nprint_sub_section(\"Operadores de Pertenencia\")\nprint(f\"4 in [3, 4, 5] = {4 in [3, 4, 5]}\")\nprint(f\"4 not in [3, 4, 5] = {4 not in [3, 4, 5]}\")\n\n\n# ************** Estructuras de Control **************\nprint_section(\"Estructuras de Control\", lines_from_top=2)\n\n\n# ** Condicionales **\nprint_sub_section(\"Condicionales\")\nx = -5\nif x >= 5:\n    print(\"x es mayor o igual que 5\")\nelif x > 0:\n    print(\"x es mayor que 0 y menor que cinco\")\nelse:\n    print(\"x es menor o igual que 0\")\n\n\n# ** Excepciones **\nprint_sub_section(\"Excepciones\")\ntry:\n    4 + \"5\"\nexcept TypeError:\n    print(\"No se puede sumar un int y un string\")\nelse:\n    print(\"Ejecutado sin problemas\")\nfinally:\n    print(\"Acabando sin importar si huvo algún problema\")\n\n\n#  ** Iterativas **\nprint_sub_section(\"Iterativas\")\nc = 1\nwhile c > 0:\n    print(f\"c es igual a {c}\")\n    c -= 1\n\n# EXTRA\nnums = []\nprint(\"\\nEjercicio extra:\")\nfor i in range(10, 55):\n    if i % 2 == 0:\n        if i != 16:\n            if i % 3 != 0:\n                nums.append(i)\nprint(nums)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/davidrguez98.py",
    "content": "\"\"\" # #01 OPERADORES Y ESTRUCTURAS DE CONTROL\n> #### Dificultad: Fácil | Publicación: 02/01/24 | Corrección: 08/01/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**. \"\"\"\n\n#OPERADORES DE ASIGNACIÓN\n\nx = 4       #x = 2\nx += 2      #x = x + 2\nx -= 2      #x = x - 2\nx *= 2      #x = x * 2\nx /= 2      #x = x / 2\nx %= 2      #x = x / 2\nx **= 2     #x = x ** 2\n\n#OPERADORES ARITMÉTICOS\n\n2 + 2       #4\n2 - 2       #0\n2 * 2       #4\n2 / 2       #1\n8 // 4      #2\n8 % 4       #0\n2 ** 3      #8\n\n#OPERADORES DE COMPARACIÓN\n\nx == \"y\"\nx != \"y\"\nx > \"y\"\nx < \"y\"\nx >= \"y\"\nx<= \"y\"\n\n#OPERADORES LÓGICOS\n\nTrue and False = False\nTrue and True = True\n\nTrue or False = True\nTrue or True = True\n\nnot True = False\n\n#OPERADORES BIT\n\nprint(bin(27)) = \"0b11011\"\n\na = \"0b1101\"\nb = \"0b1011\"\nprint(bin(a & b)) = \"0b1001\" #Si ambas posiciones de números coinciden es 1, si no es 0 (equivalente a AND)\n\na = \"0b1101\"\nb = \"0b1011\"\nprint(bin(a | b)) = \"0b1111\" #Equivalente a OR\n\na = 40 \nprint(bin(a)) = \"0b101000\"\nprint(bin(~a)) = \"-0b101000\" #Equivalente a NOT\n\nx = 0b0110 ^ 0b1010 #0b1100\nprint(bin(x)) \n#0 xor 1 = 1\n#1 xor 0 = 1\n#1 xor 1 = 0\n#0 xor 0 = 0\n\na = 0b1000 #0b10\nprint(bin(a>>2)) #Las unidades se desplazan a la derecha el número de veces que marcamos en el bin, rellenándo los puestos de la izquierda con ceros\n\na = 0b001 #0b1000\nprint(bin(a<<3)) #Al contrario que el anterior\n\n#OPERADORES DE IDENTIDAD\n\na = 10\nb = 10\nprint(a is b) #True\n\na = 10\nb = 10\nprint(a is not b) #False\n\n#OPERADORES DE MEMBRESÍA\n\nprint(3 in[1, 2, 3]) #True\n\nprint(3 not in[1, 2, 3]) #False\n\n\"\"\"----------------------------------------------------------------------\"\"\"\n\n#CONDICIONALES\n\nx = input(int())\n\nif x >= 18:\n    print(\"Eres mayor de edad\")\nelse:\n    print(\"Eres menor de edad\")\n\n#BUCLES\n\nwhile x >= 18:\n    print(\"Eres mayor de edad\")\nelse:\n    print(\"Eres menor de edad\")\n\nedad = input(int())\nfor x in edad:\n    if edad >= 18:\n        print(\"Eres mayor de edad\")\n    else:\n        print(\"Eres menor de edad\")\n\n\"\"\"----------------------------------------------------------------------\"\"\"\n\n#DIFICULTAD EXTRA\n\nnumeros = list(range(10, 56))\n\nfor numeros in numeros:\n    if numeros % 2 == 0 and numeros != 16 and numeros % 3 != 0:\n        print(numeros)\nfor numeros in numeros:\n    if numeros % 2 == 0:\n        print(numeros)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/dchevesich.py",
    "content": "\"\"\"\n EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\"\"\"\n\n### Operadores Aritmeticos ###\n\n# Suma\nprint(f\"Suma: 10 + 30 = {10 + 30}\")\n\n# Resta\nprint(f\"Resta: 50 - 20 = {50 - 20}\")\n\n# Multiplicacion\nprint(f\"Multiplica: 234 x 2244 = {234 * 2244}\")\n\n# Division\nprint(f\"Divide: 34 / 2 = {34 / 2} \")\n\n# Modulo\nprint(f\"Modulo: 40 % 3 = {40 % 3}\")\n\n# Exponenciales\nprint(f\"Potencia de 40 a la 5 es = {40 ** 5}\")\n\n# Division Entera\nprint(f\"Division entera de 40 // 3 = {40 // 3}\")\n\n### Operadores Logicos ###\n\n# and => Devuelve True solo si ambos operadores son True\nprint(f\"and: True and True = {True and True}\")\nprint(f\"and: True and False = {True and False}\")\nprint(f\"and: False and False = {False and False}\")\n\n# or => Devuelve True si cualquiera de los operadores es True\nprint(f\"or True or True = {True or True}\")\nprint(f\"or: True or False = {True or False}\")\nprint(f\"or: False or False = {False or False}\")\n\n# not => Invierte los operadores, si es True not devuelve False y viceversa\nprint(f\"not: not True = {not True}\")\nprint(f\"not: not False = {not False}\")\n\n### Operadores de comparacion ###\n\nprint(f\"igualdad: 10 == 1 = {10 == 1}\")\nprint(f\"No es igual: 10 != 1 = {10 != 1 }\")\nprint(f\"Mayor que: 10 > 5 = {10 > 5}\")\nprint(f\"Menor que: 1 < 10 = {1 < 10}\")\nprint(f\"Mayor o igual que: 10>= 10 {10 >= 10}\")\nprint(f\"Menor o igual que: 10 <= 9 {10 <= 9}\")\n\n### Operadores de Asignacion ###\n\nmy_number = 20\nprint(my_number)\nmy_number += 1  # Asignacion y suma\nprint(my_number)\nmy_number -= 1  # Asignacion y resta\nprint(my_number)\nmy_number *= 2  # Asignacion y Multiplicacion\nprint(my_number)\nmy_number /= 2  # Asignacion y Division\nprint(my_number)\nmy_number %= 4  # Modulo y Asignacion\nprint(my_number)\nmy_number //= 4  # Division de entero y Asignacion\nprint(my_number)\nmy_number **= 5  # Exponenciacion y Asignacion\nprint(my_number)\n\n### Operadores de Identidad ###\n\nmy_new_number = 1\n# Evalua si los elementos pertenecen al mismo lugar en memoria\nprint(f\"my_number is my_new_number es {my_number is my_new_number}\")\nprint(f\"my_number is not my_new_number es {my_number is not my_new_number}\")\n\n### Operadores de Pertenencia ###\n\n# Evalua si un elemento se encuentra el elemento dado\nprint(f\"'e' in Jose = {'e' in 'Jose'}\")\nprint(f\"'e' not in Jose = {'e' not in 'Jose'}\")\n\n### Operadores de bit ###\n\na = 10  # 1010\nb = 3  # 0011\n\nprint(f\"AND 10 & 3 = {10 & 3}\")\nprint(f\"OR 10 | 3 = {10 | 3}\")\nprint(f\"XOR 10 ^ 3 = {10 ^ 3}\")\nprint(f\"NOT ~10 = {~10}\")\nprint(f\"Desplazamiento a la Derecha 10 >> 3 = {10 >> 3}\")\nprint(f\"Desplazamiento a la Izquierda 10 << 3 = {10 << 3}\")\n\n\"\"\"\n    Estructuras de Control\n\"\"\"\n\n### Condicionales ###\n\nmy_name = \"Jose\"\n\nif my_name == \"Pedro\":\n    print(\"Mi nombre es Jose\")\nelif my_name == \"Juan\":\n    print(\"Hola Juan\")\nelse:\n    print(\"Pedro Pedro Pedro PE\")\n\n    ### Iterativas ###\n\nfor i in range(11):\n    print(i)\n\n\ni = 0\n\nwhile i <= 10:\n    print(i)\n    i += 1\n\n    ### Manejo de Excepciones ###\n\n\ntry:\n    print(10 / 0)\nexcept:\n    print(\"Se ha producido un error\")\nfinally:\n    print(\"Ha finalizado el manejo de exepciones con exito\")\n\n\n\"\"\"\n        EXTRA\n        Crea un programa que imprima por consola todos los números comprendidos\n        entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\"\"\"\n\n\nfor i in range(10, 56):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print(i)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/devcherry1.py",
    "content": "\"\"\"\n**OPERADORES**\n\"\"\"\n\n# OPERADORES ARIMETICOS\n\nprint(f\"Suma: 470 + 90 = { 470 + 90 }\") #Interpolando codigo en una cadena texto\nvalor_mayor = 987\nvalor_menor = 222\ndef resta(valor1,valor2):\n    return valor1 - valor2\nprint(f\"Resta con funcion \" + str(resta(valor_mayor,valor_menor)))\nprint('Multiplicacion usando formato {} por {} es {}.'.format(valor_mayor,valor_menor, valor_mayor*valor_menor))\nprint(f\"Division: 10 / 3 = {10 / 3}\") \nprint(f\"Division entera: 10 // 3 = {10 // 3}\") \nprint(f\"Modulo: 10 % 3 = {10 % 3}\") \n#modulo igual a resto o sobrante de la division\nprint(f\"Exponente: 10 ** 3 {10 ** 3}\")\n#potencia\n\n# OPERADORES DE COMPARACION\n\nprint(f\"Igualdad: 10 == 3 { 10 == 3 }\") #retorna un boolean\nprint(f\"Desigualdad: 10 != 3 { 10 != 3 }\") \nprint(f\"Mayor que: 10 > 3 { 10 > 3 }\") \nprint(f\"Menor o igual que: 10 <= 3 { 10 <= 3 }\")\n\n# OPERADORES LOGICOS\n\nprint(f\"AND &&: 10 + 3 == 13 and 5 - 1 == 4: {10 + 3 == 13 and 5 - 1 == 4}\")\nprint(f\"OR ||: 10 + 3 == 13 or 5 - 1 == 4: {10 + 3 == 13 or 5 - 1 == 4}\")\nprint(f\"OR ||: 10 + 3 == 13 or 5 - 1 == 4: {10 + 3 == 13 or 5 - 1 == 4}\")\nprint(f\"NOT !: not 10 + 3 == 14: {not 10 + 3 == 14}\")\n\n# OPERADORES DE ASIGNACION\n\nmy_number = 11 # '=' asignacion  \nprint(my_number)\nmy_number += 5 # '+=' suma y asignacion  \nprint(my_number)\nmy_number -= 5  \nprint(my_number)\nmy_number *= 5   \nprint(my_number)\nmy_number /= 5   \nprint(my_number)\nmy_number %= 5   \nprint(my_number)  \nprint(my_number)\nmy_number **= 5  \nprint(my_number)\nmy_number //= 5  \nprint(my_number)\n\n# OPERADORES DE IDENTIDAD\n\nmy_new_number = 1.0\nprint(f\"my_number is my_new_number es {my_number is my_new_number}\")\n# Igualdad compara la posicion en memoria, no importa que las dos variables contengan el mismo valor\nprint(f\"my_number is not my_new_number es {my_number is not my_new_number}\")\n# Desigualdad\n\n# OPERADORES DE PERTENENCIA\n\nprint(f\"'u' in 'juan' {'u' in 'juan'}\")\nprint(f\"'u' not in 'juan' {'u' not in 'juan'}\")\n\n\"\"\"\n**ESTRUCTURAS DE CONTROL**\n\"\"\"\n\n# CONDICIONALES\n\nmy_string = 15\n\nif type(my_string) == str:\n    print(\"Si es una String yay\")\nelif type(my_string) == int:\n    print(\"cabezon esto es un numero\")\nelse:\n    print(\"Sabra Dios que hay en esa variable\")\n# Puede haber un if dentro de otro pero no creo que sea buena idea, \n# Debe ser mejor usar funciones, nota en python no existe el switch\n\n# ITERATIVAS\n\nfor i in range(5):\n    print(i)\n# no es necesario definir i, hara el conteo desde 0 hasta 4 sin incluir 5\n\nf = 17\n\nwhile f <= 21:\n    print(f\"tu numero es: {f}\")\n    f += 1\n          \n# MANEJO DEE EXCEPCIONES\n\ntry:\n    print(10 / 0)\nexcept:\n    print(\"uyyy algo fallo\")\nfinally:\n    print(\"Ha finalizado el manejo de excepciones\")\n\n\n\"\"\"\n----------------------------------------------------\n********DIFICULTAD EXTRA**********\n___________________________________________________\n\"\"\"\nz = 1\nfor z in range(10,56):\n    if z % 2 == 0 and z != 16 and z % 3 != 0:\n        print(z)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/diegopc-dev.py",
    "content": "#Operadores y estructuras de control\n\n#->Operadores ariméticos\nprint(f\"Suma: 12 + 3 = {12 + 3}\")\nprint(f\"Resta: 12 - 3 = {12 - 3}\")\nprint(f\"Multiplicación: 12 * 3 = {12 * 3}\")\nprint(f\"División: 12 / 3 = {12 / 3}\")\nprint(f\"División entera: 12 // 3 = {12 // 3}\")\nprint(f\"Exponencial: 12 ** 3 = {12 ** 3}\")\nprint(f\"Módulo: 12 % 3 = {12 % 3}\")\n\n#->Operadores de comparación\nprint(f\"Comparacion igualdad: 12 == 3 -> {12 == 3}\")\nprint(f\"Comparacion no es igual: 12 != 3 -> {12 != 3}\")\nprint(f\"Comparacion mayor que: 12 > 3 -> {12 > 3}\")\nprint(f\"Comparacion menor que: 12 < 3 -> {12 < 3}\")\nprint(f\"Comparacion mayor igual que: 12 >= 3 -> {12 >= 3}\")\nprint(f\"Comparacion menor igual que: 12 <= 3 -> {12 <= 3}\")\n\n#->Operadores lógicos\nprint(f\"AND: Verdadero && verdadero -> {True and True}\")\nprint(f\"OR: Verdadero || falso -> {True or False} \")\nprint(f\"NOT: !Falso -> {not False}\")\n\n#->Operadores de asignación\nn = 10\nprint(f\"Asignación: n = {n}\")\nn += 1\nprint(f\"Suma con asignación: n += 1 -> {n}\")\nn -= 1\nprint(f\"Resta con asignación: n -= 1 -> {n}\")\nn *= 2\nprint(f\"Multiplicacion con asignación: n *= 2 -> {n}\")\nn /= 2\nprint(f\"División con asignación: n /= 2 -> {n}\")\nn //= 2\nprint(f\"Division entera con asignación: n //= 2 -> {n}\")\nn %= 2\nprint(f\"Modulo con asignación: n %= 2 -> {n}\")\nn **= 2\nprint(f\"Exponente con asignación: n **= 2 -> {n}\")\n\n#->Operadores de identidad\na = \"hola\"\nb = \"hola\"\nprint(f\"a esta en b {a is b}\")\nprint(f\"a no esta en b {a is not b}\")\n\n#->Operadores de pertenencia\nprint(f\"'o' esta en 'hola' -> {'o' in 'hola'}\")\nprint(f\"'x' no esta en 'hola' -> {'x' not in 'hola'}\")\n\n#->Operadores de bit\na = 10  # 1010\nb = 7  # 0111\nprint(f\"AND: 10(1010) & 7(0111) = {a & b}\")  # 0010\nprint(f\"OR: 10(1010) | 7(0111) = {a | b}\")  # 1111\nprint(f\"XOR: 10(1010) ^ 7(0111) = {a ^ b}\")  # 1101\nprint(f\"NOT: ~10(1010) = {~10}\")\nprint(f\"Desplazamiento a la derecha: 8(1000) >> 2 = {8 >> 2}\")  # 0010\nprint(f\"Desplazamiento a la izquierda: 1(0001) << 3 = {1 << 3}\")  # 0100\n\n#->Estructuras de control condicionales\nhambre = True\nfrigo = \"vacío\"\nif hambre:\n    print(\"Necesito comer algo\")\nelif frigo == \"vacío\":\n    print(\"Necesito hacer la compra antes\")\nelse:\n    print(\"A seguir escribiendo código\")\n\n#->Estructuras de control iterativas\nnombre = \"Diego\"\n\nfor i in nombre:\n    print(i)\n\ni=0\nwhile i <= 4:\n    print(nombre[i])\n    i+=1\n\n#->Estructuras de control de excepciones\ntry:\n    i=0\n    while i <= 5:\n        print(nombre[i])\n        i+=1\nexcept:\n    print(\"Ocurrió un error\")\nfinally:\n    print(\"Se puede continuar con la ejecución despues del error\")\n\n#Extra\nfor num in range(10, 56):\n    if num % 2 == 0 and num != 16 and num % 3 != 0:\n        print(num)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/dimasb69.py",
    "content": "print(\"\\n\\n\\tTratare de ser muy especifico mas que concentrarme en resolver!!\\n\\n\")\n\n\nprint(f\"\"\"\\nOperadores Aritméticos\\n\n      uso del operador + (suma)\n      1 + 3 = {1+3}\n      \n      uso del operador - (resta)\n      10 - 3 = {10-3}\n      \n      uso del operador * (multiplicacion)\n      3 * 5 = {3*5}\n      \n      uso del operador / (division)\n      5 / 2 = {5/2}\n      \n      uso del operador % (modulo devuelve el resto de la división)\n      5 % 2 = {5 % 2}\n      \n      uso del operador ** (Realiza la potencia de los operandos)\n      2 ** 3 = {2**3}\n      \n      uso del operador // (convierte el resultado de la division a enetero)\n      5 // 2 = {5//2}  (devuelve 2 en vez de 2.5)\n      \"\"\" )\n\nprint(f\"\"\"Operadores Relacionales\n\n      mayor que > para determinar si un numero es mayor que otro\n      2 es mayor que 1: {2>1} (True = si // Flase = no)\n      \n      menor que < para determinar si un numero es menor que otro\n      2 es menor que 1: {2<1} (True = si // Flase = no)\n      \n      igual que == para determinar dos valores son iguales\n      100 es igual que 200: {100 == 200} (True = si // Flase = no)\n    \n      mayor ó igual que >= valida si el 1er numero es igual o mayor que el 2do\n      100 es mayor ó igual que 200: {100 >= 200} (True = si // Flase = no)\n      \n      menor ó igual que <= valida si el 1er numero es igual o menor que el 2do\n      100 es menor ó igual que 200: {100 <= 200} (True = si // Flase = no)\n      \n      diferente que != para determinar dos valores son diferentes\n      100 es diferente que 200: {100 != 200} (True = si // Flase = no)\n      \n      \"\"\" )\n\nprint(\"Operadores Asignación\\n\")\n## = asigna el valor descrito a la variable\na = 500\nprint(f\"\\ta = 500, valor de a: {a}\")\nprint(\"\\tse asigna el valor de 500 a la variable a\\n\")\n\n## += suma el valor dado al valor actual de la variable\na += 1\nprint(f\"\\ta += 1, valor de a: {a}\")\nprint(\"\\tsuma el valor 1 al valor actual de a\\n\")\n\n## -= resta el valor dado al valor actual de la variable\na -= 499\nprint(f\"\\ta -= 499, valor de a: {a}\")\nprint(\"\\tresta el valor 499 al valor actual de a\\n\")\n\n## *= multiplica el valor de la variable por valor dado\na *= 10\nprint(f\"\\ta *= 10, valor de a: {a}\")\nprint(\"\\tmultiplica el 10 dado al valor actual de a\\n\")\n\n## /= divide el valor de la variable por valor dado y devuelve un Float\na /= 2\nprint(f\"\\ta /= 2, valor de a: {a}\")\nprint(\"\\tdivide el valor dado al valor actual de a y devuelve un float\\n\")\n\n## %= devuelve el resto de la divicion de la variable entre valor dado\na %= 6\nprint(f\"\\ta %= 6, valor de a: {a}\")\nprint(\"\\tdevuelve el resto de la division de a entre 6 mantiene el tipo float\\n\")\n\n## **= exponencia la variable al valor dado\na **= 3\nprint(f\"\\ta **= 3, valor de a: {a}\")\nprint(\"\\texponencia a la 3 el valor de a (a*a*a) mantiene el tipo float\\n\")\n\n## //= divide la variable y el resultado si lo tiene le elimina los decimales\na //= 5\nprint(f\"\\ta //= 5, valor de a: {a} \")\nprint(\"\\tdivide a entre 5 y le quita el decimal el resultado debio ser 12.8 mantiene el tipo float\\n\")\n\n\nprint(f\"\"\"Operadores Logicos\n\n      and (y) obliga a cumplir dos o mas condiciones si una de ellas\n      no se cumple retorna false, si todas se cumple retorna True\n      \n      2 > 1:True and 5 < 3:False = {(2>1)and(5<3)} (retorna False por la segunda\n      condicion no se cumple)\n      2 > 5 < 10: {(2>1)and(5<10)} (retorna True por ambas condiciones\n      se cumplen)\n      \n      or (ó) evalua dos o mas condiciones y si una se cumple retorna True\n      si ninguna se cumple retorna False\n      \n      2 > 1:True or 5 < 3:False = {(2>1)or(5<3)} (retorna True por que la primera\n      condicion es valida)\n      2 > 3:False or 5 < 4:False = {(2>3)or(5<4)} (retorna False por ninguna\n      condicion se cumplen)\n      \n            \n      -*Logicos de Pertenencia\n      \n      in (en) Retornara True si lo buscado estan en lo comparado\n             \n      carro in (perro, 20, True, carro) = {'carro' in ({'perro', 20, True, 'carro'})} \n      (retorna True carro esta en la lista)\n      12 in (perro, 20, True, carro) = {12 in ({'perro', 20, True, 'carro'})} \n      (retorna False 12 no esta en la lista)\n      \n      Funciona igual para string\n      ola in Hola = {('ola') in ('Hola') }\n      (ola si esta es parte de la palabra Hola)\n      hola in Hola = {('hola') in ('Hola') }\n      (hola no esta la comparacion la h es direfente a H)\n      \n      \n      not in (no esta en) Retorna True si el valor comparado no existe\n      \n      Hola not in (perro, 20, True, carro) = {'Hola' not in ({'perro', 20, True, 'carro'})} \n      (retorna True Hola no esta en la lista)\n      20 not in (perro, 20, True, carro) = {20 not in ({'perro', 20, True, 'carro'})} \n      (retorna False 20 si esta en la lista)\n      \n      Funciona igual para string\n      Mundo not in 'Hola como estas!!' = {('Mundo') not in ('Hola como estas!!')}\n      (Mundo no esta en 'Hola como estas!!')\n      Hola not in 'Hola como estas!!' = {('Hola') not in ('Hola como estas!!') }\n      (Hola si esta en 'Hola como estas!!')\n      \n      -*Logicos de Identidad\n      \n      is (es) Retorna True si la comparacion es Valida\n      es decir valida que el resultado sea lo esperado\n      \n      2 is 3 = {2 is 3} (retorna Falso 2 no es 3)\n      3 is 3 = {3 is 3} (retorna True 3 si es 3)\n      \n      Funciona igual para string y otros valores\n      Hola is ola = {('Hola') is  ('ola')}\n      False is False = {(False) is (False)}\n      \n      is not (no es) Evalua que el resultado no sea Verdadero\n      si es verdadero retorna False\n      \n      2 is not 3 = {2 is not 3} (retorna True 2 no es 3)\n      3 is 3 = {3 is not 3} (retorna Falso 3 si es 3)\n      \n      Funciona igual para string y otros valores\n      Hola is not ola = {('Hola') is not  ('ola')}\n      True is not True = {(True) is not (True)}\n      \n      \"\"\" )\nprint(\"Estructuras de control\\n\")\nprint(\"\\tSecuenciales\\n\")\ndef secuenciales(): #se define la funcion\n      #se ejecuta cada instruccion una por una en secuencia!\n      a = \"Hola \"\n      print(\"\\tSe crea una varibale a ='Hola '\")\n      b = \"Mundo\"\n      print(\"\\tSe crea una varibale b ='Mundo'\")\n      c = a+b\n      print(\"\\tSe crea una varibale c y se le suma a+b\")\n      print('\\tSe imprime el resultado de c')\n      print(f\"\\tc = {c}\\n\")\n      \nsecuenciales() #se ejecuta la funcion\n\nprint(\"\\tCondicionales y Ciclos\\n\")\ndef condicionales(): #se define la funcion\n      \n      print(\"\\tCONDICION: if\\n\\tejecuta solo la instruccion que cumpla la condicion\")\n      #se ejecutara solo la funcion que cumpla la condicion\n      a = \"Hola \"\n      print(\"\\tSe crea una varibale a ='Hola '\")\n      b = \"Mundo\"\n      print(\"\\tSe crea una varibale b ='Mundo'\")\n      c = a+b\n      print(\"\\tSe crea una varibale c y se le suma a+b\")\n      print(\"\\tse crea una funcion con una serie de condicionales If\\n\")\n      def condIf():#es importante mantener la identacion para que la estructura se mantenga\n            print(\"\\tSe compara a y c si son iguales mostraria el primer print\\n\\tpero como no cumple se ejecuta el print del else\\n\")\n            if(a == c):\n                  #esta instruccion no se va a ejecutar\n                  print (f\"\\t nda que hacer\")\n            else:\n                  #como la condicion anterion no se cumple esta es la instruccion que se ejecutara\n                  print(f\"\\ta='{a}' es diferente a c='{c}'por eso esto se imprime\")\n            \n            print(\"\\tLa funcion de este if fue: if(a==c)\\n\")\n            \n            print(\"\\tEsta vez se comparan varias condiciones en secuencia con elif\\n\\tse imprime solo las condiciones que se cumpla\\n\\tel esle del final se ejecutaria solo si ninguna de las anterios se cumple\\n\")\n            if(c == 'Hola Mundo'):\n                  #esta instruccin es correcta se ejecutara\n                  print(f\"\\tc='{c}' es igual a 'Hola Mundo' por eso esto se imprime\")\n            elif(c != a):\n                  #esta tambien es correcta pero no se mostrara por que ya se cumplio la primera\n                  print(f\"\\tc='{c}' es diferente a a='{a}', esta condicion tambien se cumple pero no se imprime\")\n            elif(a+b != 'Hola Mundo'):\n                  #esta ultima condicion no se cumple este elif se omite igualmente por la primer ya se cumplio\n                  print(\"\\tEste print no se muestra pero por que ya se cumplio una\\n\\tno por que la funcion no es valida\")\n            else:\n                  #esta instruccion se ejecutaria solo si alguna de las anteriores no cumple la condicion\n                  print(\"\\testa linea no se imprimira\")\n            print(\"\"\"\\tEn este if se compararon 3 condiciones y una alternativa\n                  if(c == 'Hola Mundo') \n                  //esta es correcta y se ejecuto lo que contiene\n                  elif(c != a) \n                  //esta es correcta pero la primera ya se cumplio se omite\n                  elif(a+b != 'Hola Mundo') \n                  //esta no se cumple pero la primera se cumplio se omite \n                  else \n                  // el else se ejecuta si ninguna de las anteriores se cumplio\n                  \\n\"\"\")\n      def cicloFor():\n            print(\"\\tCICLO: for\\n\\tEl ciclo for ejecuta las instrucciones por el lapso que se indique\")\n            print(\"\\tSe crea una lista x={0,1,2,3,4,5,6,7,8,9,10}con los numeros del 0 al 10\")\n            print(\"\\tSe creara una funcion con un ciclo for que imprima lo que esta en x\\n\")\n            x={0,1,2,3,4,5,6,7,8,9,10}\n            for n in x:\n                  print(f\"\\tNumero: {n}\")\n            print(\"\\tEsto se imprime cuando termina el ciclo for\\n\")\n            \n            print(\"\\ttambien funciona con strings ejemplo y='Hola Mundo!'\\n\")\n            y='Hola Mundo!'\n            for n in y:\n                  print(f\"\\tcaracter: {n}\")\n            print(\"\\tEn etse ciclo se descompuso la oracion, el espacio y ! tambien cuenta\\n\")\n            \n      def cicloWhile():\n            print(\"\\tCICLO: while\\n\\tEl ciclo while ejecuta las instrucciones mientras una condicion se cumpla\\n\\tsi no se tiene cudado se puede crear un ciclo infinito\\n\")\n            print(\"\\tSe crea variable en 1 v=1\")\n            print(\"\\tSe creara una funcion con un ciclo un while para que imprima los numeros sean pares\\n\\tentre el 1 y el 10 incrementando en cada vuelta el valor de v\")\n            v=1\n            while v < 11:\n                  if(v%2 == 0):     \n                        print(f\"\\tNumero: {v}\")\n                  v = v+1      \n            print(\"\\tEsto se imprime cuando terminan el ciclo\\n\")\n            \n            \n      \n      condIf()\n      cicloFor()\n      cicloWhile()\n      \ncondicionales() #se ejecuta la funcion\n\nprint(\"Excepciones\")\nprint (\"\\tEl manejo de excepciones es la forma de evitar que debido a un erro conocido\\n\\tla aplicacion finalice inesperadamente\\n\")\n\nprint(\"\\tuna forma de manejar ecepciones es con la funcion try except\\n\\testo permite capturar la excepcion y realizar un proceso sin finalizar la app\")\nprint(\"\\tCreemos una funcion que tomes dos variables y las divida entre si\\n\\tEn la primera opcion colocare b=0 para probar como muestra\\n\\tel mensajde del error ZeroDivisionError\\n\\tLuego colocare uno de los valores como texto y veremos el mensaje de TypeError\\n\")\ndef tryExcept(a, b):\n      try:\n            result= a/b\n            print(f\"\\tResultado= {result}\\n\")\n      except ZeroDivisionError:\n            print(\"\\tERROR: La división entre 0 no se puede realizar\")\n      except TypeError:\n            print('\\tERROR: revisa los valores uno de ellos no es correcto')\n      except Exception:\n            print('\\tERROR: Algo Salio Mal')\n            \n            \ntryExcept(10, 0)\nprint(\"\\tSe observa el mensaje dentro de execpt ZeroDivisionError\\n\")\n\ntryExcept(20, 'Hola')\nprint(\"\\tSe observa el mensaje  dentro de execpt TypeError\\n\")\n\nprint(\"\\tExisten muchos tipos de errores que se pueden manejar para eviar el colapso\\n\\tAlgunos son: AttributeError | IndexError | NotImplementedError | ValueError \")\n\n\nprint(\"\\n\\t*****EXTRA*****\\n\")\n\ndef numCiclo(n):\n      print(\"\\tFuncion que imprime los numeros entre 10 y el 55 incluidos\")\n      print(\"\\t__________________________\")\n      while n <= 55:\n            print(f\"\\tNumero: {n}\")\n            n = n+1     \n                 \ndef numPar(n):\n      print(\"\\n\\tFuncion que imprime los numeros pares entre 10 y el 55 incluidos\")\n      print(\"\\t__________________________\")\n      while n <= 55:\n            if(n%2 == 0):     \n                  print(f\"\\tNumero: {n}\")\n            n = n+1 \n            \ndef numMult(n):\n      print(\"\\n\\tFuncion que imprime los numeros multiplos de 3 sin incluir el 16\\n\\tentre los numeros 10 y 55 incluidos\")\n      print(\"\\t__________________________\")\n      while n <= 55:\n            if(n%3== 0 and n is not 16):     \n                  print(f\"\\tNumero: {n}\")\n            n = n+1           \n                  \nnumCiclo(10)\nnumPar(10)\nnumMult(10)\n\nprint(\"\\n\\n\\tSALUODS A TODOS -  me estoy uniendo tarde pero siempre es bueno practicar!!\")\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/dokeys28.py",
    "content": "#Operadores Aritmeticos\nsuma  = 2 + 5\nresta = 8 - 2\nmultiplicacion = 3 * 5\ndivision = 1 / 5\nmodulo = 6 % 2\npotencia = 3 ** 9\ndivision_entero = 18//5\nprint(suma)\nprint(resta)\nprint(multiplicacion)\nprint(division)\nprint(modulo)\nprint(potencia)\nprint(division_entero)\n\n#Operadores Relacionales\nmayor_que = 5 > 0\nmenor_que = 1 < 8\nigual_que = 5 == 5\ndiferente_que = 8 != 4\nmayor_o_igual = 5 >= 5 \nmenor_o_igual = 2 <= 3\nprint(mayor_que)\nprint(menor_que)\nprint(igual_que)\nprint(diferente_que)\nprint(mayor_o_igual)\nprint(menor_o_igual)\n\n#Operadores de Asignacion\nmi_numero = 2\nmi_numero += 4\nmi_numero -= 2\nmi_numero *= 2\nmi_numero /= 8\nmi_numero %= 5\nmi_numero **= 6\nmi_numero //= 2\nprint(mi_numero)\n\n#Operadores Logicos\nmi_condicion_1 = True\nmi_condicion_2 = False\nprint(mi_condicion_1)\nprint(mi_condicion_2)\n\nconclusion_1 = mi_condicion_1 and mi_condicion_2\nconclusion_2 = mi_condicion_1 or mi_condicion_2\nconclusion_3 = not mi_condicion_2\nprint(conclusion_1)\nprint(conclusion_2)\nprint(conclusion_3)\n\n#Operadores de Pertenencia\nmi_lista_de_compras = [ 'leche', 'huevos', 'arroz']\ncondicion_3 = 'leche' in mi_lista_de_compras\ncondicion_4 = 'soda' not in mi_lista_de_compras\nprint(condicion_3)\nprint(condicion_4)\n\n#Operadores de Identidad\na = 1\nb = 2\nc = a is b\nd = b is not a\nprint(c)\nprint(d)\n\n#DIFICULTAD EXTRA\nfor n in range(9,56):\n  if n % 2 != 0:\n    continue\n  if n == 16:\n    continue\n  if n % 3 != 0:\n    continue\n  print(n)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/domo2pdev.py",
    "content": "'''\nEJERCICIO:\n- Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n- Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n   que representen todos los tipos de estructuras de control que existan\n   en tu lenguaje:\n   Condicionales, iterativas, excepciones...\n- Debes hacer print por consola del resultado de todos los ejemplos.\n\nDIFICULTAD EXTRA (opcional):\nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\nSeguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n'''\n\n# Operators (Operadores)\n\n# Assignment Operators\nmy_number = 4621\nprint(f\"Assignment (=) {my_number}\")\nmy_number += 13\nprint(f\"Addition and Assignment (+=) {my_number}\")\nmy_number -= 3\nprint(f\"Subtraction and assignment (-=) {my_number}\")\nmy_number *= 3\nprint(f\"Multiplication and assignment (*=) {my_number}\")\nmy_number /= 3\nprint(f\"Division and assignment (/=) {my_number}\")\nmy_number %= 3\nprint(f\"Modulus and assignment (%=) {my_number}\")\nmy_number //= 3\nprint(f\"Floor division and assignment (//=) {my_number}\")\nmy_number **= 3\nprint(f\"Exponentiation and assignment (**=) {my_number}\")\n\n# Bitwise AND and assignment (&=)\nmy_number = 10\nmy_number &= 3\nprint(f\"Bitwise AND and assignment (&=) {my_number}\")\n\n# Bitwise OR assignment (|=)\nmy_number = 5\nmy_number |= 3\nprint(f\"Bitwise OR assignment (|=) {my_number}\")\n\n# Bitwise XOR assignment (^=)\nmy_number = 5\nmy_number ^= 3\nprint(f\"Bitwise XOR assignment (^=) {my_number}\")\n\n# Right shift assignment (>>=)\nmy_number = 5\nmy_number >>= 3\nprint(f\"Right shift assignment (>>=) {my_number}\")\n\n# Left shift assignment (<<=)\nmy_number = 5\nmy_number <<= 3\nprint(f\"Left shift assignment (<<=) {my_number}\")\n\n# Expression assignment operator (:=)\nprint(my_new_number := 6)\n\n# Arithmetic Operators\n\n# Addition Operator (+)\nage_one = 15\nage_two = 20\nmy_addition = age_one + age_two\nprint(f\"The result of the addition is {my_addition}\")\n\n# Subtraction Operator (-)\nfathers_age = 42\ndaughters_age = 8\nage_differenece = fathers_age - daughters_age\nprint(f\"The age difference is {age_differenece}\")\n\n# Multiplication Operator (*)\napples_per_box = 3\nnumber_of_boxes = 43\ntotal_apples = apples_per_box * number_of_boxes\nprint(f\"The total amount of apples is {total_apples}\")\n\n# Exponentiation Operator (**)\nmy_base = 3\nmy_exponent = 2\nmy_result = my_base ** my_exponent\nprint(f\"The result of the exponentiation is {my_result}\")\n\n# Division Operator (/)\nmy_dividend = 540\nmy_divisor = 9\ndivision_result = my_dividend / my_divisor\nprint(f\"The result of the division is {division_result}\")\n\n# Modulus Operator (%)\nmy_modulus_dividend = 369\nmy_modulus_divisor = 6\nmy_modulus = my_modulus_dividend % my_modulus_divisor\nprint(f\"The result of the modulus operation is {my_modulus}\")\n\n# Floor Division Operator (//)\nnumber_of_kids = 5\nnumber_of_bananas = 16\nbananas_per_kid = number_of_bananas // number_of_kids\nprint(f\"Every kid receives {bananas_per_kid} bananas\")\n\n# Comparison Operators\na = 3\nb = 9\nprint(f\"Comparison Equal (==) {a == b}\")\nprint(f\"Comparison Not equal (!=) {a != b}\")\nprint(f\"Comparison Greater than (>) {a > b}\")\nprint(f\"Comparison Less than (<) {a < b}\")\nprint(f\"Comparison Greater than or equal to (>=) {a >= b}\")\nprint(f\"Comparison Less than or equal to (<=) {a <= b}\")\n\n# Logical Operators\nprint(f\"Logical operation AND (and) {a < 10 and b < 10}\")\nprint(f\"logical operation OR (or) {a > 14 or b > 1}\")\nprint(f\"Logical operation NOT (not) {not (a < 4 and b < 10)}\")\n\n# Membership Operators\nfruits = [\"apple\", \"banana\", \"cherry\"]\nprint(f\"Is there an apple in the fruits basket? {\"apple\" in fruits}\")\nprint(f\"There is not a banana in the fruits basket {\"banana\" not in fruits}\")\n\n# Bitwise Operators\n\nmy_number_x = 10\nmy_number_y = 3\nprint(f\"Bitwise AND (&) {my_number_x & my_number_y}\")\nprint(f\"Bitwise OR (|) {my_number_x | my_number_y}\")\nprint(f\"Bitwise XOR (^) {my_number_x ^ my_number_y}\")\nprint(f\"Signed right shift (>>) {my_number_x >> my_number_y}\")\nprint(f\"Zero fill left shift (<<) {my_number_x << my_number_y}\")\nprint(f\"Bitwise NOT (~){~ my_number_x}\")\n\n# Identity Operators\nprint(my_number_x is my_number_x)\nprint(my_number_x is not my_number_x)\nprint(my_number_x is my_number_y)\n\n\n\"\"\" Control Statements \"\"\"\n\nmy_number_x = 1\nmy_number_y = 6\n# if statement\nif my_number_x > my_number_y:\n   print(f\"{my_number_x} is greater than {my_number_y}\")\nelse:\n   print(f\"{my_number_y} is grater than {my_number_x}\")\n\n# elif statement\nif my_number_x > my_number_y:\n   print(f\"{my_number_x} is grater than {my_number_y}\")\nelif my_number_x == my_number_y:\n   print(f\"{my_number_x} is equal to {my_number_y}\")\nelse:\n   print(f\"{my_number_x} is less than {my_number_y}\")\nprint(\"\\n\")\n\n# While loop\nwhile my_number_x < my_number_y:\n   print(f\"{my_number_x} is less than {my_number_y}\")\n   my_number_x += 1\n\n#For loop\ncars = [\"Ford\", \"Volvo\", \"BMW\"]\nfor car in cars:\n   print(car)\n\n# try cath finally stastements \ntry:\n   print(\"Hello\")\nexcept:\n   print(\"Something went wrong\")\nfinally:\n   print(\"The 'try except' is finished\")\n\n\"\"\" Extra\nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\nSeguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\"\"\"\n\nfor i in range(10, 56):\n   if i % 2 == 0:\n      if i != 16 and i % 3 != 0:\n         print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/drolo18.py",
    "content": "\"\"\"\n\n        Operadores\n\n\"\"\"\n\n\n## Operadores aritméticos\n\nprint (f\"suma: 25 + 30 es {25 + 30}\")\nprint (f\"resta: 25 - 30 es {25 - 30}\")\nprint (f\"multiplicación: 25 * 30 es {25 * 30}\")\nprint (f\"división: 25 / 30 es {25 / 30}\")    \nprint (f\"módulo: 25 % 30 es {25 % 30}\")\nprint (f\"potencia: 25 ** 30 es {25 ** 30}\")\nprint (f\"división entera: 25 // 30 es {25 // 30}\")       \nprint (f\"raíz cuadrada: 25 ** 0.5 es {25 ** 0.5}\")\n\n## Operadores lógicos\n\nprint (f\"AND: 3 + 5 == 8 and 8 + 3 == 11 es {3 + 5 == 8 and 8 + 3 == 11}\")\nprint (f\"OR: 3 + 5 == 11 or 8 + 3 == 11 es {3 + 5 == 11 or 8 + 3 == 11}\")\nprint (f\"NOT: not 3 + 5 == 11 es {not 3 + 5 == 11}\")\n\n## Operadores de comparación\n\nprint (f\"igual: 25 == 30 es {25 == 30}\")\nprint (f\"distinto: 25 != 30 se {25 != 30}\")\nprint (f\"mayor: 25 > 30 es {25 > 30}\")\nprint (f\"menor: 25 < 30 es {25 < 30}\")\nprint (f\"mayor o igual: 25 >= 30 es {25 >= 30}\")\nprint (f\"menor o igual: 25 <= 30 es {25 <= 30}\")\nprint (f\"comparación de cadenas: 'hola cadena 1' == 'hola cadena 2' es {'hola cadena 1' == 'hola cadena 2'}\")\nprint (f\"comparación de cadenas: 'hola cadena 1' != 'hola cadena 2' es {'hola cadena 1' != 'hola cadena 2'}\")\nprint (f\"comparación de cadenas: 'hola cadena 1' > 'hola cadena 2' es {'hola cadena 1' > 'hola cadena 2'}\")\nprint (f\"comparación de cadenas: 'hola cadena 1' < 'hola cadena 2' es {'hola cadena 1' < 'hola cadena 2'}\")  \nprint (f\"comparación de cadenas: 'hola cadena 1' >= 'hola cadena 2' es {'hola cadena 1' >= 'hola cadena 2'}\")\nprint (f\"comparación de cadenas: 'hola cadena 1' <= 'hola cadena 2' es {'hola cadena 1' <= 'hola cadena 2'}\")   \nprint (f\"comparación de listas: [1, 2, 3] == [5, 6, 7] es {[1, 2, 3] == [5, 6, 7]}\")\nprint (f\"comparación de listas: [1, 2, 3] != [5, 6, 7] es {[1, 2, 3] != [5, 6, 7]}\")\nprint (f\"comparación de listas: [1, 2, 3] > [5, 6, 7] es {[1, 2, 3] > [5, 6, 7]}\") \nprint (f\"comparación de listas: [1, 2, 3] < [5, 6, 7] es {[1, 2, 3] < [5, 6, 7]}\")\nprint (f\"comparación de listas: [1, 2, 3] >= [5, 6, 7] es {[1, 2, 3] >= [5, 6, 7]}\")\nprint (f\"comparación de listas: [1, 2, 3] <= [5, 6, 7] es {[1, 2, 3] <= [5, 6, 7]}\")\n\n\n\n## Operadores de bits\n\na= 25 # 11001\nb= 30 # 11110\nprint (f\"AND: 25 & 30 es {a & b}\") # 11000\nprint (f\"OR: 25 | 30 es {a | b}\") # 11111\nprint (f\"XOR: 25 ^ 30 es {a ^ b}\") # 00111\nprint (f\"NOT: ~25 es {~a}\") \nprint (f\"Desplazamiento a la izquierda: 25 << 2 es {a << 2}\") # 1100100\nprint (f\"Desplazamiento a la derecha: 25 >> 2 es {a >> 2}\") # 110\n\n\n## Operadores de pertenencia\n\nprint (f\"pertenencia: 'o' in 'drolo18' es {'o' in 'drolo18'}\")  \nprint (f\"pertenencia: 'b' not in 'drolo18' es {'b' not in 'drolo18'}\")\n\n## Operadores de asignación\n\nmy_number = 25 # asignación\nprint (my_number)   \nmy_number += 2 # suma y asignación\nprint (my_number)\nmy_number -= 2 # resta y asignación\nprint (my_number)\nmy_number *= 2 # multiplicación y asignación\nprint (my_number)\nmy_number /= 2 # división y asignación\nprint (my_number)\nmy_number %= 2 # módulo y asignación\nprint (my_number)\nmy_number **= 2 # potencia y asignación\nprint (my_number)\nmy_number //= 1 # división entera y asignación\nprint (my_number)\n\n## Operadores de identidad\n\nmy_new_number  = 1.0\nprint (f\"identidad: my_new_number is my_number es {my_new_number is my_number}\")\nprint (f\"identidad: my_new_number is not my_number es {my_new_number is not my_number}\")\n\nmy_new_number = my_number   \nprint (f\"identidad: my_new_number is my_number es {my_new_number is my_number}\")\nprint (f\"identidad: my_new_number is not my_number es {my_new_number is not my_number}\")\n\n\"\"\"\nEstructuras de control\n\"\"\"\n\n# condicionales\n\nmy_string = \"juan\"\n\nif my_string == \"drolo18\":\n    print (\"my_string es 'drolo18'\")\nelif my_string == \"pedro\":\n    print (\"my_string es 'Pedro'\")\nelse:\n    print (\"my_string no es ni 'drolo18' ni 'Pedro'\")\n\n\n# interactivas\n\nfor i in range(25):\n    print (i)\n\ni = 0\nwhile i < 25:\n    print (i)\n    i += 1\n\n# manejo de excepciones\n\ntry:\n    print (10 / 1) \nexcept: \n    print (\"se ha producido un error\")\nfinally:\n    print (\"finalizado el manejo de excepciones\")   \n\n\"\"\"\nExtra\n\"\"\"     \n\nfor number in range(1, 56):\n    if number % 2 == 0 and number != 16 and number % 3 != 0: \n         print (number)  \n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/duendeintemporal.py",
    "content": "# { ROADMAP PARA PROGRAMADORES }  #1 OPERADORES Y ESTRUCTURAS DE CONTROL\n# BIBLIOGRAFY REFERENCE: Python Notes for Professionals. 800+ pages of professional hints and tricks (GoalKicker.com) (Z-Library)\n\n# SIMPLE MATEMATICAL OPERATORS\n\n# DIVISION\n\"\"\" Python does integer division when both operands are integers. The behavior of Python's division operators have changed from Python 2.x and 3.x (*see also Integer Division ). \"\"\"\n\na, b, c, d, e = 3, 2, 2.0, -3, 10\n\nprint(a / b) # = 1.5\nprint(a / c) # = 1.5\nprint(d / b) # = -1.5\nprint(b / a) # = 0.6666666666666666\nprint(d / e) # = -0.3\n\nd /= b # = -1.5\nprint(d) # = -1.5\n\n\n# The ' // ' operator in Python 2 forces floored division regardless of type.\nprint(a // c) # = 1.0 (Integer Division)\nfloat(a) / float(b) # = 1.5 \n\n''' Possible combinations (builtin types):\nint and int (gives an int in Python 2 and a float in Python 3)\nint and float (gives a float)\nint and complex (gives a complex)\nfloat and float (gives a float)\nfloat and complex (gives a complex)\ncomplex and complex (gives a complex) '''\n\n# ADDITION\n\nprint(a + b) # = 5\na += e # = 13\n\n# SUBSTRACTION\n\nprint(e - b) # = 8\ne -= a + 2 # = -5\n\nimport operator # contains 2 argument arithmetic functions\noperator.sub(b, a) # = -1\n\n# MULTIPLICATION\n\nprint(e * e) # = 25\ne *= b # = -10\nprint(e) # = -10\n\nimport operator\noperator.mul(e, e) # = 25\n\n# EXPONENTIATION\n\na, b = 2, 3\n(a ** b) # = 8\npow(a, b) # = 8 \n\nimport math\nmath.pow(a, b) # = 8.0 (always float; does not allow complex results)\n\nimport operator\noperator.pow(a, b) # = 8\n\n# Another difference between the built-in pow and math.pow is that the built-in pow can accept three arguments:\na, b, c = 2, 3, 2\npow(2, 3, 2) # 0, calculates (2 ** 3) % 2, but as per Python docs,\n# does so more efficiently\n\n# MODULUS\nprint(3 % 4) # 3\nprint(10 % 2) # 0\nprint(6 % 4) # 2\n\n#Or by using the operator module:\nimport operator\noperator.mod(3 , 4) # 3\noperator.mod(10 , 2) # 0\noperator.mod(6 , 4) # 2\n\n#You can also use negative numbers.\nprint(-9 % 7) # 5\nprint(9 % -7) # -5\nprint(-9 % -7) # -2\n\n#If you need to find the result of integer division and modulus, you can use the divmod function as a shortcut:\nquotient, remainder = divmod(9, 4)\n# quotient = 2, remainder = 1 as 4 * 2 + 1 == 9\n\n# INPLACE OPERATIONS\n\n# It is common within applications to need to have code like this:\na = a + 1\n# or\na = a * 2\n# There is an effective shortcut for these in place operations:\na += 1\n# and\na *= 2\n\n''' Any mathematic operator can be used before the '=' character to make an inplace operation:\n-= decrement the variable in place\n+= increment the variable in place\n*= multiply the variable in place\n/= divide the variable in place\n//= floor divide the variable in place # Python 3\n%= return the modulus of the variable in place\n**= raise to a power in place '''\n\n#BITWISE OPERATORS\n\"\"\" #The ~ operator will flip all of the bits in the number. Since computers use signed number representations — most notably, the two's complement notation to encode negative binary numbers where negative numbers are written with a leading one (1) instead of a leading zero (0). from 0000 0000 to 0111 1111 to represent numbers from 0 to 127 and reserve 1xxx xxxx to represent negative numbers.\n#Eight-bit two's-complement numbers Bits Unsigned Value Two's-complement Value 0000 0000 0 0 0000 0001 1 1 0000 0010 2 2 0111 1110 126 126 0111 1111 127 127 1000 0000 128 -128 1000 0001 129 -127 1000 0010 130 -126 1111 1110 254 -2 1111 1111 255 -1\n#In essence, this means that whereas 1010 0110 has an unsigned value of 166 (arrived at by adding (128 * 1) + (64 * 0) + (32 * 1) + (16 * 0) + (8 * 0) + (4 * 1) + (2 * 1) + (1 * 0)), it has a two's-complement value of -90 (arrived at by adding (128 * 1) - (64 * 0) - (32 * 1) - (16 * 0) - (8 * 0) - (4 * 1) - (2 * 1) - (1 * 0), and complementing the value).\n#In this way, negative numbers range down to -128 (1000 0000). Zero (0) is represented as 0000 0000, and minus one (-1) as 1111 1111. \"\"\"\n#In general, though, this means ~n = -n - 1.\n# 0 = 0b0000 0000\nprint(~0) # Out: -1\n# -1 = 0b1111 1111\n# 1 = 0b0000 0001\nprint(~1) # Out: -2\n# -2 = 1111 1110\n# 2 = 0b0000 0010\nprint(~2) # Out: -3\n# -3 = 0b1111 1101\n# 123 = 0b0111 1011\nprint(~123) # Out: -124\n# -124 = 0b1000 0100\n#Note, the overall effect of this operation when applied to positive numbers can be summarized:\n#~n -> -|n+1|\n#And then, when applied to negative numbers, the corresponding effect is:\n#~-n -> |n-1|\n\n\n# Unary Plus and Minus\n# When the unary plus is applied to a non-numeric value, it converts it to a number.\n\nstr1 = \"03\"\nstr1 = int(str1)\nprint(str1)  # value becomes numeric 3\n\nstr2 = \"1.4\"\nprint(str1 + float(str2))  # 4.4\n\nstr2 = float(str2)\nprint(str2)  # value becomes numeric 1.4\n\nstr3 = \"zaz\"\nstr3 = float('nan')  # Cannot convert to number, becomes NaN\nprint(str3)  # value becomes NaN\n\nbool_val = True\nbool_val = int(bool_val)  # True becomes 1\nprint(bool_val)  # value becomes numeric 1\n\nf_num = 2.8\nf_num = float(f_num)  # no change, still 2.8\nprint(f_num)  # 2.8\n\nclass Obj:\n    def __int__(self):\n        return -5\n\nobj = Obj()\nobj = int(obj)  # value becomes numeric -5\nprint(obj)  # -5\n\n# Negation\ng_actions = 50\ng_actions = -g_actions\nprint(g_actions)  # value becomes -50\n\nstr1 = -str1\nprint(str1)  # value becomes numeric -3\n\nstr2 = -str2\nprint(str2)  # value becomes numeric -1.4\n\nstr3 = -str3\nprint(str3)  # value becomes NaN\n\nbool_val = -bool_val\nprint(bool_val)  # value becomes numeric -1\n\nf_num = -f_num\nprint(f_num)  # no change, still -2.8\n\nobj = -obj\nprint(obj)  # value becomes numeric 5\n\n# Increment/Decrement\nnum1 = 10\nnum2 = 5\nnum3 = num1\nnum1 += 1\nprint(num3)  # 10\nprint(num1)  # 11\nnum3 = num1 + 1\nprint(num3)  # 12\nprint(num1)  # 11\nnum4 = num2\nnum2 -= 1\nprint(num4)  # 5\nprint(num2)  # 4\nnum4 -= 1\nprint(num4)  # 4\nprint(num2)  # 4\nnum4 += 1\nprint(num4)  # 5\n\n# Bitwise Operators\n# Bitwise NOT ~\nn1 = 25  # binary 00000000000000000000000000011001\nn2 = ~n1  # binary 11111111111111111111111111100110\nprint(n2)  # -26\n\n# Bitwise AND &\nn3 = 25 & 3\nprint(n3)  # 1\n\n# Bitwise OR |\nn3 = 25 | 3\nprint(n3)  # 27\n\n# Bitwise XOR ^\nn3 = 25 ^ 3\nprint(n3)  # 26\n\n# Left Shift <<\nnumber = 2  # 10 in binary code\nnew_number = number << 6  # 10000000 in binary code which is decimal 128\nprint(new_number)  # 128\n\n# Signed Right Shift >>\nnumber = 128  # 10000000 in binary code\nnew_number = number >> 6  # 10 in binary code which is decimal 2\nprint(new_number)  # 2\n\n# Boolean Operators\n# Logical NOT !\nprint(not False)  # True\nprint(not \"shadow\")  # False\nprint(not 0)  # True\nprint(not float('nan'))  # False\nprint(not \"\")  # True\nprint(not 57344)  # False\nprint(not None)  # True\n\n# Logical AND &&\nprint(True and 'Angy')  # Angy\nprint(False and 'Angy')  # False\nprint(4 < 5 and 8 > 6)  # True\n\n# Note: Both AND and OR are short-circuit operators, meaning sometimes only the first operator is evaluated.\n\n# Multiplicative Operators\n# There are three multiplicative operators in Python: multiply, divide, and modulus.\n# These operators work similarly to their counterparts in languages such as Java, C, and Perl,\n# but they also include some automatic type conversions when dealing with non-numeric values.\n\n# Multiply Operator *\nnumber = 4 * int('8')\nprint(number)  # Logs: 32\n\n# Divide Operator /\nnumber = 10 / 5\nprint(number)  # Logs: 2.0\nnumber = 4 / 40\nprint(number)  # Logs: 0.1 \n\n# Modulus (remainder) Operator %\nnumber = 41 % 5\nprint(number)  # Logs: 1\n\n# Exponentiation Operator **\nnumber = 4 ** 2\nprint(number)  # Logs: 16\n# same as\nprint(pow(4, 2))  # Logs: 16\n\n# Add Operator +\nnumber = 76 + 78\nprint(number)  # Logs: 154\nprint('76' + '78')  # Logs: 7678 (string concatenation)\n\nnumber = 767867686876876 + 6757575755\nprint(number)  # Logs: 767874444452631\n\n# Subtract -\nnumber = 48 - 3\nprint(number)  # Logs: 45\n\n# Note: These operators have particular behavior in some cases when used with 'inf'(Infinity), 0, 'nan'(NaN not a number).\n\n# Relational Operators\n# The less-than (<), greater-than (>), less-than-or-equal-to (<=), and greater-than-or-equal-to (>=)\n# relational operators perform comparisons between values similarly to what you learned in math class.\n\ncomputation = 76 < 4\nprint(computation)  # Logs: False\ncomputation = 87 > 32\nprint(computation)  # Logs: True\ncomputation = 43 <= 43\nprint(computation)  # Logs: True\ncomputation = 44 >= 85\nprint(computation)  # Logs: False\n\nuser = {\n    'name': 'Calvin & Hobbes'\n}\n\ntry:\n    print(user <= 4)  # This will raise a TypeError\nexcept TypeError as e:\n    print(f\"Error: {e}\")  # Handle the error and print a message\n# TypeError: '<=' not supported between instances of 'dict' and 'int'   \n#This way the program doesn't interrup with the TypeError\n\nprint(\"43\" < \"8\")  # Logs: True\ntry:\n    print(\"43\" < 8)  # This will raise a TypeError\nexcept TypeError as e:\n    print(f\"Error: {e}\")  # Handle the error and print a message\n# TypeError: '<' not supported between instances of 'str' and 'int'     \n\nprint('DeepState' < 'real people')  # Logs: True  \n# True not only cause are more real people, but when we talk about strings the upper characters has lower codes than the regulars ones\nprint('deepstate' < 'real people')  # Logs: True\n# True again ... well ummm sometimes we win \n\n#Comparison Behavior in Python\n#Numeric Comparison:\n#If both operands are numbers (integers or floats), Python performs a numeric comparison directly.\n\nprint(5 > 3)  # True\n\n#String Comparison:\n#If both operands are strings, Python compares them lexicographically (dictionary order) based on the Unicode code points of the characters.\n\nprint(\"apple\" < \"banana\")  # True\n\n#Mixed Types (Number and String):\n#If one operand is a number and the other is a string, Python raises a TypeError. Unlike JavaScript, Python does not automatically convert types for comparison.\n\ntry:\n    print(5 > \"3\")  # Raises TypeError\nexcept TypeError:\n    print(\"Cannot compare number and string!\")  # This will be printed\n\n#Boolean Comparison:\n#Booleans in Python are a subclass of integers. True is treated as 1 and False as 0 when compared with numbers.\n\nprint(True == 1)  # True\nprint(False == 0)  # True\n\n#Object Comparison:\n#If the operands are objects, Python will use the __lt__, __le__, __gt__, __ge__, __eq__, or __ne__ methods defined in the class of the objects to perform the comparison. If these methods are not defined, Python will raise a TypeError if the objects are of incompatible types.\n\nclass MyClass:\n    def __init__(self, value):\n        self.value = value\n\n    def __lt__(self, other):\n        return self.value < other.value\n\nobj1 = MyClass(1)\nobj2 = MyClass(2)\nprint(obj1 < obj2)  # True\n\n# Equality operators\n# Determining whether two variables are equivalent is one of the most important operations in programming.\n\n# Equal or Equality Operator ==\nprint(2 == '2')  # Logs: False (2 is an integer, '2' is a string)\n\n# Not-equal or Inequality Operator !=\nprint(2 != '2')  # Logs: True (2 is not equal to '2' because they are different types)\n\n# In Python, there is no strict equality operator (===) or strict inequality operator (!==) like in JavaScript.\n# The == and != operators perform value comparisons without type checking.\n\n# Checking both value and type\nprint(2 == '2' and type(2) == type('2'))  # Logs: False\nprint(2 != '2' and type(2) != type('2'))  # Logs: True\n\n\n#Equality and Comparison Rules in Python\n#Boolean Values:\n#In Python, when using the equality (==) operator, True is treated as 1 and False as 0. However, there is no implicit conversion of Booleans to numeric values for comparison; they are compared directly.\nprint(True == 1)  # True\nprint(False == 0)  # True\n\n# String and Number Comparison:\n# Python does not automatically convert strings to numbers for equality checks.\n# Comparing a string with a number using == will return False, not raise an error.\n\nprint(\"5\" == 5)  # Logs: False (no TypeError is raised)\n\n# However, if you try to perform an operation that requires both to be the same type, it will raise a TypeError.\ntry:\n    result = \"5\" + 5  # This will raise TypeError\nexcept TypeError:\n    print(\"Cannot add string and number!\")  # This will be printed\n\n\n# Object Comparison:\n# In Python, if one operand is an object and the other is not, the comparison will depend on the type of the other operand.\n# If the other operand is not compatible, a TypeError will be raised.\n\nclass MyClass:\n    def __eq__(self, other):\n        # Custom equality check (optional)\n        return isinstance(other, MyClass)\n\nobj = MyClass()\n\n# Comparing the same object\nprint(obj == obj)  # True (same object)\n\n# Comparing with a different object of the same class\nanother_obj = MyClass()\nprint(obj == another_obj)  # False (unless __eq__ is defined to return True for same class)\n\n# Comparing with a non-object (like an integer)\ntry:\n    print(obj == 5)  # This will raise TypeError if __eq__ is not defined for MyClass\nexcept TypeError:\n    print(\"Cannot compare object and non-object!\")  # This will be printed if TypeError occurs\n\n# If __eq__ is defined, it will return False instead of raising an error\nprint(obj == \"string\")  # This will raise TypeError if __eq__ is not defined for MyClass\n\n# None Values:\n# In Python, None is a singleton object and is used to signify 'no value' or 'null'.\n# It is equal to itself but not equal to any other value.\nprint(None == None)  # True (None is equal to None)\nprint(None == 0)     # False (None is not equal to 0)\n\n# NaN (Not a Number):\n# Python has a specific representation for NaN, which is float('nan').\n# In Python, NaN is not equal to itself, which is a property of NaN in the IEEE floating-point standard.\nimport math\nprint(math.isnan(float('nan')))  # True (math.isnan() correctly identifies NaN)\nprint(float('nan') == float('nan'))  # False (NaN is not equal to NaN)\n\n# Additional note: NaN is often used in data analysis and scientific computing to represent undefined or unrepresentable values.\n\n# Object Identity:\n# In Python, the 'is' operator checks for object identity (whether two references point to the same object),\n# while '==' checks for value equality.\n\na = [1, 2, 3]  # List a\nb = a         # b references the same object as a\nc = a[:]      # c is a shallow copy of a, so it is a different object\n\nprint(a is b)  # True (a and b point to the same object)\nprint(a == c)  # True (a and c have the same value)\nprint(a is c)  # False (a and c are different objects)\n\n# Checking for NaN\nimport math\nprint(math.isnan(float('nan')))  # True (math.isnan() correctly identifies NaN)\n\n# Boolean and None comparisons\nprint(True == 1)  # True (True is equal to 1 in Python)\nprint(None == float('nan'))  # False (None is not equal to NaN)\nprint(None is None)  # True (None is equal to itself)\n\n# Conditional Operator (Ternary Operator)\n# In Python, the conditional expression (also known as the ternary operator) allows for conditional assignment to a variable.\n# The syntax is: true_value if condition else false_value\n\nuser = {'name': 'Nixon'}  # Example user dictionary\n\n# Conditional expression to determine the login message\nlogin = f\"Successful login, Welcome {user['name']}\" if user['name'] != 'Nixon' else \"Sorry we don't have any user with that name\"\nprint(login)  # Logs: Sorry we don't have any user with that name\n\n# Assignment Operators\na = 'a'  # Initial assignment\na = a + a  # Concatenating the string with itself\nprint(a)  # Logs: aa\n\n# Example of using an assignment operator with a number\nnumber = 8\nnumber += 2  # This is equivalent to number = number + 2\nprint(number)  # Logs: 10\n\n# Compound assignment operators allow you to perform an operation and assign the result to a variable in one step.\n# They are done with one of the arithmetic or bitwise operators followed by an equal sign (=).\n\nnumber = 8  # Initial value\nnumber *= number  # Equivalent to number = number * number\nprint(number)  # Logs: 64\n\nnumber -= 4  # Equivalent to number = number - 4\nprint(number)  # Logs: 60\n\n# Compound-assignment operators exist for each of the major mathematical operations and a few others as well.\n# They are as follows:\n# - Multiply/assign (*=)\n# - Divide/assign (/=)\n# - Modulus/assign (%=)\n# - Add/assign (+=)\n# - Subtract/assign (-=)\n# - Left shift/assign (<<=)\n# - Signed right shift/assign (>>=)\n\n# Note: Python does not have an unsigned right shift operator (>>>=).\n\n# Membership Operators\n# The 'in' operator\nCrows = {\n    'description': \"Mutant fat man lives beyond the margins of the known universe...\",\n    'age': 600,\n}\n\nprint('description' in Crows)  # Logs: True\nprint('location' in Crows)  # Logs: False\n\n# instanceof operator\nclass User:\n    def __init__(self, name, age, email):\n        self.name = name\n        self.age = age\n        self.email = email\n\n    def greeting(self):\n        return f\"Hi {self.name}. Welcome to Roadmap Exercise #01.\"\n\nniko_zen = User('Niko', 41, 'duendeintemporal@hotmail.com')\nprint(niko_zen.greeting())  # Logs: 'Hi Niko. Welcome to Roadmap Exercise #01.'\n\nprint(isinstance(niko_zen, User))  # Logs: True\nprint(isinstance(niko_zen, object))  # Logs: True\nprint(isinstance(4, int))  # Logs: True (4 is a primitive value)\nfour = 4\nprint(isinstance(four, int))  # Logs: True\n\n# Type Operators\n# We can use isinstance or type() to check the type of an object.\nprint(type(True))  # Logs: <class 'bool'>\nprint(type(float('nan')))  # Logs: <class 'float'>\nprint(type(niko_zen))  # Logs: <class '__main__.User'>\n\n# Destructuring Operations - spread operator equivalent in Python\n# on arrays (lists)\nbooks = ['Dune', 'Shibumi', 'El Maestro de Esgrima', 'El Perfume']\nbooks2 = ['Eloquent JavaScript', 'You Don’t Know JS ES6 Beyond', 'Linux Command Line An Admin Beginners Guide', 'Learn Bash the Hard Way', 'Programming Algorithms', 'MATLAB Notes for Professionals']\nmix_books = books + books2  # Concatenating two lists\nfrank_herbert, trevanian = books[0], books[1]  # Destructuring assignment\nprint(trevanian)  # Logs: Shibumi\n\n# on objects (dictionaries)\nemail = niko_zen.email  # Accessing an attribute of the User instance\nprint(email)  # Logs: duendeintemporal@hotmail.com\n\nniko_zen_settings = {\n    'mode': 'dark',\n    'avatar': 'moebius.svg',\n    'interface': 'compact',\n}\n\n# Merging dictionaries using unpacking\nniko_zen_data = {**niko_zen.__dict__, **niko_zen_settings}\nprint(niko_zen_data)  # Logs both objects niko_zen instance and niko_zen_settings\n\n# Function to display user information\ndef show_user(user):\n    print(f\"User name: {user['name']}, age: {user['age']}, email: {user['email']}\")\n\nshow_user(niko_zen.__dict__)  # Logs: User name: Niko, age: 41, email: duendeintemporal@hotmail.com\n\n# Assigning default values in destructuring\nconfig = {'font': 'monospace'}\nfont = config.get('font')  # Gets the value for 'font'\nmode = config.get('mode', 'dark')  # Gets the value for 'mode', defaults to 'dark' if not found\n\nprint(font, mode)  # Logs: monospace dark\n\n# Variable assignment and swapping\nninja1 = 'Hiroshi'\nninja2 = 'Neko'\nninja3 = 'Kage'\n\n# Swapping values using destructuring\nninja1, ninja2, ninja3 = ninja2, ninja3, ninja1\nprint(ninja1)  # Logs: Neko\n\n# Copying objects (dictionaries) without modifying the original\nshinobi = {\n    'skills': ['fast', 'quick', 'precise', 'lethal', 'computational thinking'],\n    'location': 'not found',\n}\n\ntrix = shinobi.copy()  # Create a shallow copy of the dictionary\ntrix['location'] = 'Bangkok, Thailand'  # Modify the copy\n\nprint(shinobi['location'])  # Logs: not found (original remains unchanged)\nprint(trix['location'])      # Logs: Bangkok, Thailand (modified copy)\n\n# Using * operator to unpack list elements as arguments in functions\nnums = [1, 3, 4, 5, 6]\nprint(max(*nums))  # Logs: 6 (unpacking the list to pass as arguments)\n\n# Function to calculate average\ndef calculate_average(*numbers):\n    total = sum(numbers)  # Sum of all numbers\n    return total / len(numbers)  # Average calculation\n\naverage = calculate_average(90, 76, 45, 23, 67)\nprint(average)  # Logs: 60.2\n\n# Converting a string into a list of its individual characters\nmaximum = 'in a society that has abolished every kind of adventure, the only adventure that remains is abolishing the society'\nmaxim_arr = list(maximum)  # Converts string to list of characters\nprint(maxim_arr)  # Logs: ['i', 'n', ' ', 'a', ' ', 's', 'o', 'c', 'i', 'e', ...]\n\n# Tuple unpacking (comma operator equivalent in Python)\nnumber1, number2, number3, number4 = 1, 2, 3, None\nprint(number1, number2, number3, number4)  # Logs: 1 2 3 None\n\n# Flow Control Statements\nnumber = 225\nif number:  # Checks if number is truthy (non-zero)\n    number += 4\n    print(number)  # Logs: 229\n\n# Else statement\nif number:\n    number += 4\n    print(number)  # Logs: 233\nelse:\n    pass  # This block will not execute since number is truthy\n\n# Else if statement (elif)\nif number > 300:\n    number += 4\n    print(number)  # This block will not execute since number is not greater than 300\nelif number > 200:\n    number += 4\n    print(number)  # Logs: 237 (since number is 233, which is greater than 200)\nelse:\n    pass  # This block will not execute since the previous condition was true\n\n# Do-while equivalent using a while loop\ncount = 0\nwhile True:\n    print(\"I'm learning a lot in this roadmap for coders, even with these basic exercises\")\n    count += 1\n    if count >= 1:\n        break  # This simulates a do-while loop by ensuring the loop runs at least once\n\n# For loop to sum numbers from 1 to 100\nnumber = 0\nfor i in range(1, 101):\n    number += i  # Accumulate the sum of numbers from 1 to 100\nprint(number)  # Logs: 5050\n\n# For-in statement to iterate over dictionary keys\nuser2 = {\n    'name': 'Nikita',\n    'age': 32,\n    'location': 'Not Found',\n}\n\nfor key in user2:\n    print(key)  # Logs only the property (key): name\n    print(key, user2[key])  # Logs the property and the value: name Nikita\n\n# For-of equivalent to iterate over list elements\nodd_nums = [1, 3, 5, 7, 9]\nfor num in odd_nums:\n    print(num)  # Logs each number in the odd_nums list\n\n# Using items() to iterate over dictionary\nfor key, val in user2.items():\n    print(f\"{key}: {val}\")  # Logs key-value pairs in the dictionary\n\n# Label statements equivalent using break\nouter_loop = True\nfor i in range(11):\n    for y in range(5):\n        if (i == 2) and (y == 4):\n            outer_loop = False  # Set flag to exit outer loop\n            break\n        if y == 4:\n            break  # Breaks the inner loop when y reaches 4\n        print('Is there anybody out there?')\n    if not outer_loop:\n        break  # Breaks the outer loop if the flag is set\n\n# Break and continue statements\nnumber = 0\nwhile number < 5:\n    if number == 3:\n        break  # Exits the loop when number is 3\n    print(number)  # Logs: 0, 1, 2\n    number += 1\n\nnumber = 0\nwhile number < 5:\n    if number == 3:\n        number += 1  # Increment number to avoid infinite loop\n        continue  # Skips the rest of the loop when number is 3\n    print(number)  # Logs: 0, 1, 2, 4\n    number += 1\n\n# The Switch Statement equivalent using if-elif-else\nuser_name = user2['name']  # Assuming user2 is defined as in previous examples\nif user_name == 'Nikita':\n    print('Welcome agent')  # This will log because the name is 'Nikita'\nelif user_name == 'Calvin & Hobbes':\n    print('Bring me some cookies')\nelse:\n    print('Turn off that TV')  # This will log if the name is neither 'Nikita' nor 'Calvin & Hobbes'\n\n# Extra difficulty: Create a program that prints the even numbers from 10 to 55 inclusive\n# and avoids printing the numbers if they are equal to 16 or multiples of 3.\nfor i in range(10, 56):  # Loop through numbers from 10 to 55\n    if i % 3 == 0 or i == 16:  # Skip if the number is a multiple of 3 or equal to 16\n        continue\n    if i % 2 == 0:  # Check if the number is even\n        print(i)  # Print the even number\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/eamartin96.py",
    "content": "def Aritmeticos():\n    print(\"Operadores aritmeticos\")\n    a = 5\n    b = 2\n\n    print(f\"Suma: {a} + {b} = {a + b}\")\n    print(f\"Resta: {a} - {b} = {a - b}\")\n    print(f\"Multiplicacion: {a} * {b} = {a * b}\")\n    print(f\"Division: {a} / {b} = {a / b}\")\n    print(f\"Modulo: {a} % {b} = {a % b}\")\n    print(f\"Potencia: {a} ^ {b} = {a ** b}\")\n\ndef Logicos():\n    print(\"\\nOperadores logicos\")\n    a = True\n    b = False\n\n    print(f\"AND: {a} AND {b} = {a and b}\")\n    print(f\"OR: {a} OR {b} = {a or b}\")\n    print(f\"NOT: NOT {a} = {not a}\")\n\ndef Comparacion():\n    print(\"\\nOperadores de comparacion\")\n    a = 5\n    b = 2\n\n    print(f\"{a} > {b} = {a > b}\")\n    print(f\"{a} >= {b} = {a >= b}\")\n    print(f\"{a} < {b} = {a < b}\")\n    print(f\"{a} <= {b} = {a <= b}\")\n    print(f\"{a} == {b} = {a == b}\")\n    print(f\"{a} != {b} = {a != b}\")\n\ndef Identidad():\n    print(\"\\nOperadores de identidad\")\n    a = 1\n    b = 2\n\n    print(f\"{a} is {b} = {a is b}\")\n    print(f\"{a} is {b} = {a is b}\")\n\ndef Bits():\n    print(\"\\nOperadores de Bits\")\n    a = 5\n    b = 3\n\n    print(f\"AND: {a} & {b} = {a & b}\")\n    print(f\"OR: {a} | {b} = {a | b}\")\n    print(f\"XOR: {a} ^ {b} = {a ^ b}\")\n    print(f\"Left shift: {a} << 3 = {a << 3}\")\n    print(f\"Right shift: {a} >> 3 = {a >> 3}\")\n    print(f\"NOT: !{a} = {~a}\")\n\ndef Pertenencia():\n    print(\"\\nOperadores de Pertenencia\")\n    a = 4\n    lista = [1, 2, 3, 4 , 5]\n\n    print(\"Lista:\", *lista)\n    print(f\"{a} is in Lista = {a in lista}\")\n    print(f\"{a} is not in Lista = {a not in lista}\")\n\ndef Condicionales():\n    a = 5\n    print(f\"a = {a}\")\n    if a == 5:\n        print(\"if: a == 1\")\n\n    if a != 5:\n        print(\"if\")\n    else:\n        print(\"else: a != 1\")\n\n    if a < 4:\n        print(\"if\")\n    elif a > 4:\n        print(\"elif: a > 4\")\n    else:\n        print(\"else\")\n\ndef Iterativas():\n    for i in range(1,6):\n        print(\"for\")\n\n    i = 5\n    while(i < 5):\n        print(\"while\")\n\ndef Exceptions():\n    while True:\n        try:\n            x = int(input(\"Enter a number: \"))\n            break\n        except ValueError:\n            print(\"Opps! That was no valid number. Try again...\")\n\ndef ExtraDificult():\n    for number in range(10, 56):\n        if number % 2 == 0 and number != 16 and number % 3 != 0:\n            print(number)\n\ndef main():\n# Operadores\n    Aritmeticos()\n    Logicos()\n    Comparacion()\n    Identidad()\n    Bits ()\n    Pertenencia()\n\n# Operaciones\n    Condicionales()\n    Iterativas()\n    Exceptions()\n\n# Dificultad Extra\n    ExtraDificult()\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/eberstr.py",
    "content": "x = 9\ny = 8\n\n# Ejemplos operadores aritmeticos\nprint(\"operadores aritmeticos\")\nprint(f'suma \"x + y\" {x + y}')\nprint(f'resta \"x - y\" {x - y}')\nprint(f'multiplicación \"x * y\" {x * y}')\nprint(f'división \"x / y\" {x / y}')\nprint(f'modulo \"x % y\" {x % y}')\nprint(f'Potencia \"x ** y\" {x ** y}')\nprint(f'División entera \"x // y\" {x // y}')\n\n# Operadores lógicos\nj= True\ni = False\nprint(\"Operadores lógicos\")\nprint(j)\nprint(i)\nprint(f'and \"j and i\" {j and i}')\nprint(f'or - \"j or i\" {j or i}')\nprint(f'not - \"j not i\" {j not i}')\n\n# Operadores comparacion\nprint(\"Operadores comparacion\")\nprint(f'Mayor que \">\"; \"x > y\" {x > y}')\nprint(f'Mayor o igual que \">=\" x > y\" {x >= y}')\nprint(f'Menor que \"<\"; \"x < y\" {x < y}')\nprint(f'Menor o igual que \"<=\"; \"x <= y\" {x <= y}')\nprint(f'igual que \"==\"; \"x == y\" {x == y}')\nprint(f'igual que \"!=\"; \"x != y\" {x != y}')\n\n# Operadores de asignación\na=0\nprint(\"Operadores de asignación\")\nprint(\"Asignar a = 0\")\na += 5\nprint(f\"Suma 'a += 5' {a}\")\na -= 5\nprint(f\"Resta 'a -= 5' {a}\")\na *= 5\nprint(f\"Multiplicación 'a *= 5' {a}\")\na /= 5\nprint(f\"División 'a /= 5' {a}\")\na %= 5\nprint(f\"Modulo 'a %= 5' {a}\")\na **= 5\nprint(f\"Potencia 'a **= 5' {a}\")\na // 5\nprint(f\"Division entera 'a //= 5' {a}\")\n\n# Operadores de Identidad\nprint(\"Operadores de identidad\")\nprint(f'is \"x is y\"  {x is y}')\nprint(f'is not \"x is not y\"  {x is not y}')\n\n# Operadores de pertenencia\nlista = [1, 3, 4]\nprint(\"Operadores de pertenencia\")\nprint(f'in \"x in lista\" {x in lista}')\nprint(f'not in \"x not in lista\" {x not in lista}')\n\n# Operadores de Bits\nprint(\"Operadores de Bits\")\nprint(f\"AND: 'x & y' {x & y}\")\nprint(f\"OR: 'x | y' {x | y}\")\nprint(f\"XOR: 'x ^ y' {x ^ y}\")\nprint(f\"NOT: '~10' {~x}\")\nprint(f\"Desplazamiento a la derecha: 'y >> x' {y>>y}\")\nprint(f\"Desplazamiento a la izquierda: 'y << x' {x<<y}\")\n\n# Estrucura de control if\na = 10\nb = 30\n\nif a > b:\n    print(\"a es mayor que b\")\nelif a < b:\n    print(\"a es menor que b\")\nelse:\n    print(\"a es igual a b\")\n\n# Estrucuta de control for\nnumeros = [18,50,90,-20,100,80,37]\nfor n in numeros:\n    print(n)\n\n# Estrucua de control while\nx = 1\nwhile x < 5:\n    print(x)\n    x += 1\n\n# Estructura de control try/except\na = int(input(\"Ingrese un número entero: \"))\nb = int(input(\"Ingrese otro número entero: \"))\n\ntry:\n    c = a / b \nexcept ZeroDivisionError:\n    print(\"Estás intentando dividir por cero\")\n\n\n# Ejercicio extra\nfor i in range(10,56):\n    if  i % 2 == 0 and i != 16 and i % 3 != 0:\n        print(i)\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/eckoseal89.py",
    "content": "a = 2\r\nb = 10\r\n\r\nprint (a + b)\r\nprint (a - b)\r\nprint (a * b)\r\nprint (b / a)\r\nprint (b // a)\r\nprint (b ** a)\r\nprint (a % b)\r\n\r\nfor x in range(10,56):\r\n    if x % 2 == 0 and x != 16 and x % 3 != 0:\r\n        print(x,end=\",\")\r\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/edalmava.py",
    "content": "# Operadores aritméticos\nx = 5; y = 10\nprint(f\"Dado los valores: x = {x}; y = {y}\")\nprint(f\"Suma: x + y = {x + y}\")\nprint(f\"Resta: x - y = {x - y}\")\nprint(f\"Multiplicación: x * y = {x * y}\")\nprint(f\"División: x / y = {x / y}\")\nprint(f\"Módulo: y % x = {y % x}\")\nprint(f\"Exponenciación: y ** x = {y ** x}\")\nprint(f\"Cociente: x // y = {x // y}\")\n\n# Operadores relacionales o de comparación - Devuelven True o False\nprint(\"\")\nprint(f\"Igual: x == y = {x == y}\")         # False\nprint(f\"Distinto: x != y = {x != y}\")      # True\nprint(f\"Mayor: x > y = {x > y}\")           # False\nprint(f\"Menor: x < y = {x < y}\")           # True\nprint(f\"Mayor o igual: x >= y = {x >= y}\") # False\nprint(f\"Menor o igual: x <= y = {x <= y}\") # True\n\n# Operadores lógicos\nx = True; y = False\nprint(\"\")\nprint(f\"Dado los valores: x = {x}; y = {y}\")\nprint(f\"and - y lógico: x and y = {x and y}\") # False\nprint(f\"or - o lógico: x or y = {x or y}\")    # True\nprint(f\"not - negación: not x = {not x}\")     # False\nprint(f\"not - negación: not y = {not y}\")     # True\n\n# Operadores bitwise - a nivel de bit\na = 0b1101   # 13\nb = 0b1011   # 11\nprint(\"\")\nprint(f\"Dados dos numeros: a = {a} y b = {b}\")\nprint(f\"And a nivel de bits: a & b = {a & b}\")       # 1001 = 9\nprint(f\"Or a nivel de bits: a | b = {a | b}\")        # 1111 = 15\nprint(f\"Not a nivel de bits: ~a = {~a} y ~b = {~b}\") # -14 y -12 => ~a = -a - 1\nprint(f\"XOR bit a bit: a ^ b = {a ^ b}\")             # 0110 = 6  => Es 1 para 1, 0 o 0, 1\nprint(f\"Desplazamiento a la derecha: 10 >> 1 = {10 >> 1}\")   # 1010 => 0101 = 5\nprint(f\"Desplazamiento a la izquierda: 10 << 1 = {10 << 1}\") # 1010 => 10100 = 20\n\n# Operadores de asignación\na=7; b=2\nprint(\"\")\nprint(\"Operadores de asignación\")\nprint(f\"Dado los valores a = {a}, b = {b} y x = {a}\")\nx=a; x+=b;  print(\"x += \", x)  # 9\nx=a; x-=b;  print(\"x -= \", x)  # 5\nx=a; x*=b;  print(\"x *= \", x)  # 14\nx=a; x/=b;  print(\"x /= \", x)  # 3.5\nx=a; x%=b;  print(\"x %= \", x)  # 1\nx=a; x//=b; print(\"x //= \", x) # 3\nx=a; x**=b; print(\"x **= \", x) # 49\nx=a; x&=b;  print(\"x &= \", x)  # 2  \nx=a; x|=b;  print(\"x |= \", x)  # 7   \nx=a; x^=b; print(\"x ^= \", x)   # 5  \nx=a; x>>=b; print(\"x >>= \", x) # 1\nx=a; x<<=b; print(\"x <<= \", x) # 28    \n\n# Operadores de identidad\nx = 10; y = 10; z = 5\nprint(\"\")\nprint(f\"Dado los valores x = {x}; y = {y}\")\nprint(f\"x y y son el mismo objeto = {x is y}\")  # is comprueba si dos variables hacen referencia a el mismo objeto.\nprint(f\"x y y no son el mismo objeto = {x is not y}\") # False\n\n# Operadores de pertenencia o de membresía\nprint(\"\")\nprint(f\"La letra a esta en murciélago = {'a' in 'murciélago'}\")\nprint(f\"El número 3 no esta en la lista [1, 2, 4, 5] = {3 not in [1, 2, 4, 5]}\")\nprint(\"\")\n\n# Estructuras de Control\n\n# Condicionales \n\n# Uso de if - else - elif\nx = 5\nif x == 5:\n    print(\"Es 5\")\nelif x == 6:\n    print(\"Es 6\")\nelif x == 7:\n    print(\"Es 7\")\nelse:\n    print(\"Es otro\")\n\n# Operador ternario\na = 10\nb = 5\nc = a / b if b != 0 else -1\nprint(c)                     # Imprime 2.0\n\n# Bucle for\nfor i in range(0, 5):\n    print(i)\n# Salida:\n# 0\n# 1\n# 2\n# 3\n# 4\n\nfor i in \"Python\":\n    print(i)\n# Salida:\n# P\n# y\n# t\n# h\n# o\n# n\n\n# Bucle while\nx = 5\nwhile x > 0:\n    x -= 1\n    print(x)\n# Salida: 4,3,2,1,0\n\n# Sucesión de Fibonacci\nprint(\"Sucesión de Fibonacci\")\na, b = 0, 1\nwhile b < 25:\n    print(b)\n    a, b = b, a + b\n#1, 1, 2, 3, 5, 8, 13, 21\n\n# Match - En python es similar al switch\nhora = 8\nmatch hora:\n    case 8:\n        print(\"Desayuno\")\n    case 14:\n        print(\"Comida\")\n    case 21:\n        print(\"Cena\")\n    case _:                       # _ caso por defecto\n        print(\"No toca comer\")\n# Desayuno\n\n\nprint(\"\")\nprint(\"Reto Extra\")\nprint(\"\")\n\nfor i in range(10, 56):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print(i)\n\nprint(\"Usando List comprehensions\")\nprint([i for i in range(10, 56) if i % 2 == 0 and i != 16 and i % 3 != 0])\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/eduhumanes91.py",
    "content": "'''\nEJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */ \n'''\n# Operadores Aritméticos\n\nprint(\"\\n *******Operadores Aritméticos******* \\n\")\nprint(f\"Suma: 5 + 5 = {5 + 5}\")\nprint(f\"Resta: 10 - 5 = {10 - 5}\")\nprint(f\"Multiplicación: 5 * 5 = {5 * 5}\")\nprint(f\"División: 10 / 2 = {10 / 2}\")\nprint(f\"División entera: 10 // 3 = {10 // 3}\")\nprint(f\"Resto: 10 % 3 = {10 % 3}\")\nprint(f\"Potencia: 2 ** 3 = {2 ** 3}\")\n\n# Operadores de Comparación\n\nprint(\"\\n *******Operadores de Comparación******* \\n\")\nprint(f\"Igualdad: 5 == 5 = {5 == 5}\")\nprint(f\"Diferente: 5 != 5 = {5 != 5}\")\nprint(f\"Mayor que: 5 > 3 = {5 > 3}\")\n\n# Operadores Lógicos\n\nprint(\"\\n *******Operadores Lógicos******* \\n\")\nprint(f\"And: True and False = {True and False}\")\nprint(f\"Or: True or False = {True or False}\")\nprint(f\"Not: not True = {not True}\")\n\n# Operadores de Asignación\n\nprint(\"\\n *******Operadores de Asignación******* \\n\")\na = 5\nprint(f\"Asignación: a = 5, a = {a}\")\na += 5\nprint(f\"Suma: a += 5, a = {a}\")\na -= 5\nprint(f\"Resta: a -= 5, a = {a}\")\na *= 5\nprint(f\"Multiplicación: a *= 5, a = {a}\")\na /= 5\nprint(f\"División: a /= 5, a = {a}\")\na //= 2\nprint(f\"División entera: a //= 2, a = {a}\")\na %= 3\nprint(f\"Resto: a %= 3, a = {a}\")\na **= 2\nprint(f\"Potencia: a **= 2, a = {a}\")\n\n# Operadores de Identidad\n\nprint(\"\\n *******Operadores de Identidad******* \\n\")\na = 6\nb = 5\nprint(\"Suponiendo a = 6 y b = 5\")\nprint(f\"Identidad: a is b = {a is b}\")\nprint(f\"No Identidad: a is not b = {a is not b}\")\n\n# Operadores de Pertenencia\n\nprint(\"\\n *******Operadores de Pertenencia******* \\n\")\nlista = [1, 2, 3, 4, 5]\nprint(f\"Suponiendo la lista: {lista}\")\nprint(f\"Pertenencia: 2 in lista = {2 in lista}\")\nprint(f\"No Pertenencia: 2 not in lista = {2 not in lista}\")\n\n# Condicionales\n\nprint(\"\\n *******Condicionales******* \\n\")\n\nprint(\"If, elif, else: 5>3 =\\n\")\nif 5 > 3:\n    print(\"5 es mayor que 3\")\nelif 5 < 3:\n    print(\"5 es menor que 3\")\nelse:\n    print(\"5 es igual a 3\")\n\n# Iterativas\n    \nprint(\"\\n *******Iterativas******* \\n\")\n\nprint(\"For:\\n\")\nfor i in range(5):\n    print(i)\n\nprint(\"\\nWhile:\\n\")\ni = 0\nwhile i < 5:\n    print(i)\n    i += 1\n\n\n# Dificultad Extra\n\nprint(\"\\n *******Dificultad Extra******* \\n\")\n\nfor i in range (1,56):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print(i)\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/elder202.py",
    "content": "#01 OPERADORES Y ESTRUCTURAS DE CONTROL\n\n#ARITMETICOS\n#suma\nsuma = 1 + 2\nprint(\"suma: \", suma)\n\n#ARITMETICOS\n#resta\nresta = 3 - 2\nprint(\"resta: \", resta)\n\n#multiplicacion\nmultiplicacion = 3 * 2\nprint(\"multiplicacion: \", multiplicacion)\n\n#resta\ndivision = 4 / 2\nprint(\"division: \", division)\n\n#Logicos\n#and\nand_logico = True and True\nprint(\"and: \", and_logico)\n#or\nor_logico = True or False\nprint(\"or: \", or_logico)\n#not\nnot_logico = not True\nprint(\"not: \", not_logico)\n\n#Comparacion\n\n#igual\nigual = 4 == 4\nprint(\"igual: \", igual)\n#diferent\ndiferente = 1 != 2\nprint(\"diferente: \", diferente)\n#mayor que\nmayor_que = 2 > 1\nprint(\"mayor que: \", mayor_que)\n#menor que\nmenor_que = 1 < 2\nprint(\"menor que: \", menor_que)\n#mayor o igual que\nmayor_o_igual_que = 2 >= 1\nprint(\"mayor o igual que: \", mayor_o_igual_que)\n#menor o igual que\nmenor_o_igual_que = 1 <= 2\nprint(\"menor o igual que: \", menor_o_igual_que)\n\n#Identidad\n#is\nisIdentidad = 1 is 1\nprint(\"is: \", isIdentidad)\n#is not\nisNotIdentidad = 1 is not 2\nprint(\"is not: \", isNotIdentidad)\n\n#in\ninPertenencia = 1 in [1,2,3]    \nprint(\"in: \", inPertenencia)\n#not in\nnotInPertenencia = 1 not in [1,2,3]\nprint(\"not in: \", notInPertenencia)\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/elkin-dev.py",
    "content": "## Operadores en Python\na: int = 7\nb: int = 2\n\n# Operadores de comparación\na == b  # Igual a\na != b  # No igual a\na < b  # Menos que\na <= b  # Menos que o igual a\na >= b  # Mas grande que\na >= b  # Mayor que o igual a\n\n\n# Operadores aritméticos\n+a  # Positivo\n-b  # Negativo\na + b  # Suma\na - b  # Resta\na * b  # Multiplicación\na / b  # División\na % b  # Modulo\na // b  # División de piso o división entera\na**b  # Exponenciación\n\n\n# Operadores de asignación\nnumber: int = 26\nday = 19\ndigits = (1, 2, 3, 4, 5, 6, 7, 8, 9, 0)\nvocals = [\"a\", \"e\", \"i\", \"o\", \"u\"]\n\n\n# Operadores lógicos\nprint(\n    a > b and b == a\n)  # and ej. a and b ambos valores deben cumplirse True and True = True\nprint(a > b and a != b)\nprint(\n    a > b or b == a\n)  # or ej. a or b uno o ambos se debe cumplir True and False = True\nprint(a > b or a != b)\nprint(not True)  # not ej. True = False; False = True\n\n\n# Operadores de identidad\nx: int = 1001\ny: int = \"1001\"\na: str = \"Hello, Pythonista!\"\nb: str = a\nprint(x is y)  # x is y\nprint(a is b)\nprint(id(x))\nprint(id(y))\nprint(x is not y)  # x is not y\n\n\n# Operadores de membresía\nprint(5 in [32, 5, 3, 9, 0])  # Valor dentro de la colección\nprint(5 not in [32, 5, 3, 9, 0])  # El valor no esta dentro de la colección\n\n\n# Operadores y expresiones de concatenación\nprint(\"Hello, \" + \"world!\")  # Concatenación\nprint([1, 6, 9, 8] + [1, 9, 9, 7])\nprint(3 * \"hello\")  # Repetición\nprint(3 * [1, 9, 9, 7])\n\n\n# Operador morsa y las expresiones de asignación\n# Devuelve el resultado de la expresión.\n# Asigna el resultado a una variable.\ndef validate_length(string):\n    if (n := len(string)) < 8:\n        print(f\"La longitud {n} es demasiado corta, necesita al menos 8\")\n    else:\n        print(f\"La longitud {n} está bien!\")\n\n\nvalidate_length(\"Pythonista\")\n\nvalidate_length(\"Python\")\n\n\n# Operadores bit a bit y expresiones\n# Bitwise AND\n#   0b1100    12\n# & 0b1010    10\n# --------\n# = 0b1000     8\nbin(0b1100 & 0b1010)\n\nprint(12 & 10)\n\n# Bitwise OR\n#   0b1100    12\n# | 0b1010    10\n# --------\n# = 0b1110    14\nbin(0b1100 | 0b1010)\n\nprint(12 | 10)\n\n\n# Operadores y expresiones de asignación aumentada\nx, y = 2, 4\nx += y  # x = x + y\nx -= y  # x = x - y\nx *= y  # x = x * y\nx /= y  # x = x / y\nx //= y  # x = x // y\nx %= y  # x = x % y\nx **= y  # x = x ** y\n\nx &= y  # x = x & y [Y bit a bit aumentado ( conjunción )]\nx |= y  # x = x | y [OR bit a bit aumentado ( disyunción )]\nx ^= y  # x = x ^ y [XOR bit a bit aumentado ( disyunción exclusiva )]\nx >>= y  # x = x >> y [Desplazamiento a la derecha bit a bit aumentado]\nx <<= y  # x = x << y [Desplazamiento bit a izquierda aumentado]\n\n## Condicionales\n# if\nx: int = 3\ny: int = 5\n\n'''\nif x < y:\n    print(True)\nif x > y:\n    print(True) \nif y:\n    print(True)\nif x or y:\n    print(True)\nif x and y:\n    print(True)\n'''\nif \"python\" in \"Hola python\":\n    print(True)\n\nif 2 in [32, 1, 56, 2]:\n    print(True)\n\n# if else\nx = 0\ny = 0\nif x < y:\n    print(x, \"Es menor que\", y)\nelse:\n    print(y, \"Es mayor que\", x)\n\n# if elif\n\nname = \"Elkin\"\ngreetings = \"Hola\"\nif name == \"Pedro\":\n    print(greetings, name)\nelif name == \"Juan\":\n    print(greetings, name)\nelif name == \"Elkin\":\n    print(greetings, name)\nelif name == \"Carlos\":\n    print(greetings, name)\nelse:\n    print(\"No se a encontrado el nombre de\", name)\n\n# if en una sola linea\nif \"s\" in \"Elkin\": print(\"1\"); print(\"2\"); print(\"3\")\n\n# Operadores ternarios\nprint(True) if 3 > 5 else print(False)\n\n# Bucles en python (while: Mientras)\nn = 5\nwhile n > 0:\n    n -= 1\n    print(n)\na = [\"foo\", \"bar\", \"baz\"]\nwhile a:\n    print(a.pop(-1))\n#  while and break\n\nn = 0\nwhile n < 10:\n    n += 1\n    if n == 2:\n        break\n    print(n)\nprint(\"Loop ended.\")\n\n# While and continue\nn = 0\nwhile n < 10:\n    n += 1\n    if n == 2:\n        continue\n    print(n)\nprint(\"End loop\")\n\n# while and clause\nn = 0\nwhile n < 3:\n    n += 1\n    print(n)\nelse:\n    print(\"End loop\")\n\na = [\"foo\", \"bar\", \"baz\"]\nwhile True:\n    if not a:\n        break\n    print(a.pop(-1))\nprint(a)\n# bucles anidados\nage = 45\ngender = \"F\"\n\nif age < 18:\n    if gender == \"M\":\n        print(\"hijo\")\n    else:\n        print(\"hija\")\nelif age >= 18 and age < 65:\n    if gender == \"M\":\n        print(\"Padre\")\n    else:\n        print(\"Madre\")\nelse:\n    if gender == \"M\":\n        print(\"Abuelo\")\n    else:\n        print(\"Abuela\")\n\na = [\"foo\", \"bar\"]\nwhile len(a):\n    print(a.pop(0))\n    b = [\"baz\", \"qux\"]\n    while len(b):\n        print(\">\", b.pop(0))\n# Bucles de ultima linea\nn = 5\nwhile n > 0: n -= 1; print(n)\n\nnums = [1, 3, 9, 10, 27]\nfor n in nums:\n    print(n)\n# Esta es la forma de saber si un objeto es un iterable\nnums = [1, 3, 9, 10, 27]\nit = iter(nums)\nprint(next(it))\n\nvalores = {'A': 4, 'E': 3, 'I': 1, 'O': 0}\nfor v in valores.values():\n    print(v)\n    \nfor k in valores.keys():\n    print(k)\nvalores = {\"A\": 4, \"E\": 3, \"I\": 1, \"O\": 0}\n\nfor k, v in valores.items():\n    print(\"Keys:\", k, \"Values:\", v)\n\nfor n in range(10):\n    print(n)\n\nfor n in range(1, 10 , 3):\n    print(n)\ncoleccion = [2, 4, 5, 7, 8, 4, 3, 4]\nfor e in coleccion:\n    if e == 4:\n        break\n    print(e)\n\nfor e in coleccion:\n    if e == 4:\n        continue\n    print(e)\ncoleccion = [2, 4, 5, 7, 8, 4, 3, 4]\nv = 10\nfor n in coleccion:\n    if n == v:\n        break\n    print(n)\nelse:\n    print(\"No se encontró el numero\", v)\n\n\n\n\"\"\" \nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\"\"\"\n\nn = 10\nwhile n <= 55:\n    if n % 2 == 0 and not n == 16 and not n % 3 == 0:\n        print(n)\n    n += 1\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/eloitr.py",
    "content": "\"\"\"\n EJERCICIO:\n - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n    Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n    (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n- Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n    que representen todos los tipos de estructuras de control que existan\n    en tu lenguaje:\n    Condicionales, iterativas, excepciones...\n- Debes hacer print por consola del resultado de todos los ejemplos.\n \nDIFICULTAD EXTRA (opcional):\n  Crea un programa que imprima por consola todos los números comprendidos\n  entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n \nSeguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\"\"\"\n\n#### EJEMPLOS DE TODOS LOS TIPOS DE OPERADORES ###\n#De comparación:\nprint(3<4)\nprint(3<=4)\nprint(3>4)\nprint(3>=4)\nprint(3==4)\nprint(3!=4)\n\nmy_list = []\nmy_tuple = ()\nprint(my_list is my_tuple)\nprint(my_list is not my_tuple)\n\n\n#Matemáticos\nprint(3+4)\nprint(3-4)\nprint(3*4)\nprint(3/4)\nprint(3//4)\nprint(3%4)\nprint(-4) #(valor negativo)\nprint(+4) #(valor positivo)\nprint(abs(-4))\nprint(int(4.459))\nprint(float(4))\nc = complex(4)\nprint(c)\nprint(c.conjugate()) #parte real igual, opuesta de la imagiaria original\nprint(divmod(3, 4)) #(x // y, x % y)\n\nprint(pow(3, 4)) #x^y\nprint(3 ** 4) #x^y\n\n\n#BITS\nprint(3<4 | 3>4) #or\nprint(3<4 ^ 3>4) #exclusive or\n\nprint(3<4 & 3>4) #and\n\nprint(3 << 10) #3 desplazado a la izquierda 10 bits\nprint(3 >> 1) #3 desplazado a la derecha 10 bits\n\nprint(~0) #invertir los bits de 4\n\n\n\n\n\n### ESTRUCTURAS DE CONTROL ###\n\n#if\nif 3==4:\n    print(\"TRUE\")\nelif 3>4:\n    print(\"TRUE\")\nelse:\n    print(\"FALSE\")\n\n#while \nwhile 4!=4:\n    print(\"Hola Python\")\nelse:\n    print(\"Adiós Python\")\n\n#for\nfor i in range(0, 5):\n    print(i)\nelse:\n    print(\"Hola mundo\")    \n    \n#try\ntry:\n    res = 4/0\n    print(res)\nexcept ZeroDivisionError:\n    print(\"No se puede dividir entre 0\")\nelse:\n    print(res)\nfinally:\n    print(\"Gracias\")\n\n\n    \n### EXTRA ###\nprint(\"\\nPROGRAMA EXTRA:\")\nfor i in range(10, 56, 2):\n    if i%3 != 0 and i != 16:\n        print(i)  \n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/emilceinfante.py",
    "content": "for number in (range(10,56)):\n    if (number % 2) == 0 and (number != 16) and (number % 3) == 0:\n        print(number)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/emilianohoyos.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\"\"\"\n\"\"\"\noperadores\n\"\"\"\n# Operadores aritmeticos\nprint(f\"suma : 10+4={10+4}\")\nprint(f\"resta : 10-4={10-4}\")\nprint(f\"division : 10/4={10/4}\")\nprint(f\"multiplicacion : 10*4={10*4}\")\nprint(f\"modulo : 10%4={10%4}\")\nprint(f\"exponencial : 10**4={10**4}\")\nprint(f\"division entera : 10//4={10//4}\")\n\n# Operadores de comparación\n\nprint(f\"Igualdad : 10==3 es {10==3}\")\nprint(f\"Negación : 10!=3 es {10!=3}\")\nprint(f\"Mayor que : 10>3 es {10>3}\")\nprint(f\"Menor que : 10>3 es {10>3}\")\nprint(f\"Mayor igual que : 10>=3 es {10>=3}\")\nprint(f\"Menor igual que : 10<=3 es {10<=3}\")\n\n#operadores Lógicos\nprint(f\"And &&: 10+3==13 and 5-1==4 es {10+3==13 and 5-1==4 }\")\nprint(f\"Or &&: 10+3==14 or 5-1==4 es {10+3==14 or 5-1==4 }\")\nprint(f\"Not &&: 10+3==14 { not 10+3==14 }\")\n\n#operadores de asignación\nmy_number=11 #asignacion\nprint(my_number)\nmy_number+=1 #suma y asignacion\nprint(my_number)\nmy_number-=1 #resta y asignacion\nprint(my_number)\nmy_number*=2 #multiplicacion y asignacion\nprint(my_number)\nmy_number/=2 #division y asignacion\nprint(my_number)\nmy_number%=2 #modulo y asignacion\nprint(my_number)\nmy_number**=2 #modulo y asignacion\nprint(my_number)\nmy_number//=2 #division entera y asignacion\nprint(my_number)\n\n# Operadores de identidad\nmy_new_number=my_number\nprint(f\"Muy number is my_new_number es {my_number is my_new_number}\")\nprint(f\"Muy number is NOT my_new_number es {my_number is not my_new_number}\")\n\n#operadores de pertenencia\nprint(f\"'y' in hoyos= {'y' in 'hoyos'}\")\nprint(f\"'b' not in hoyos= {'b' not in 'hoyos'}\")\n\n#operadores de bit\na=10 #1010\nb=3 #  11\n\nprint(f\"AND: 10 & 3={10&3}\")#0010\nprint(f\"OR: 10 | 3={10|3}\")#1011\nprint(f\"XOR: 10 ^ 3={10^3}\")#1001\nprint(f\"NOT: ~10={~10}\")#0110\nprint(f\"Desplazamiento a la derecha: 10>>2={10>>2}\")#0010\nprint(f\"Desplazamiento a la izquierda: 10<<2={10<<2}\")#101000\n\n\n\"\"\"\nEstructuras de control\n\"\"\"\n#Condicionales\nmy_string=\"Emilianohoyos\"\nif my_string==\"Emilianohoyos\":\n    print(\"my_string es 'EmilianoHoyos'\")\nelif my_string==\"Brais\":\n    print(\"my_string es 'Brais'\")\nelse:\n    print(\"my_string No es 'EmilianoHoyos' ni 'Brais'\")\n\n#iterativa\n\nfor i in range(11):\n    print(i)\n\ni=0\nwhile i<=10:\n    print(i)\n    i+=1\n\n#manejo de excepciones\ntry:\n    print(10/0)\nexcept:\n    print(\"se ha producido un error\")\nfinally:\n    print('ha finalizado el manejo de excepciones')\n\n\"\"\"\nextra\n\"\"\"\nfor number in range(10,56):\n        if number%2==0 and number!=16 and number%3!=0:\n            print(number)\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/estelacode.py",
    "content": "# 01 - OPERADORES Y ESTRUCTURAS DE CONTROL\n\n## 1. Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n# Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...(Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n\n\n### Operadores Aritméticos : permiten realizar operaciones aritméticas y devolver su resultado.\n#-----------------------------------------------------------------------------\nx = 2; y = 3\nprint(\"Operadores aritméticos\")\nprint(\"x+y =\", x+y)   # operador +  (suma)\nprint(\"x-y =\", x-y)   # operador -  (resta)\nprint(\"x*y =\", x*y)   # operador * (multiplicación)\nprint(\"x/y =\", x/y)   # operador / (dividion)\nprint(\"x%y =\", x%y)   # opoerador % (modulo)\nprint(\"x**y =\", x**y) # operador ** (potencia)\nprint(\"x//y =\", x//y)  # operador // (división entera)\n\n# Nota: el orden de prioridad de losoperadores aritméticos es el siguiente: \n# () Parentesis, \n# ** Potencia, \n# -x Negacion, \n# * / // % Multiplicación, División, Cociente, Módulo\n# + - Suma, Resta\n\n\n\n### Operadores de Asignación : permiten realizar una operacion y asignar el resultado a una variable.\n#-----------------------------------------------------------------------------\n# Operador  = asigna un valor a una variable\n# Operador += equivalente a sumar y asignar el resultado a la variable inicial.\n# Operador -= equivalente a restar y asignar el resultado a la variable inicial.\n# Operador *= equivale a multiplicar una variable por otra y almacenar el resultado en la primera.\n# Operador /= equivale a dividir una variable por otra y almacenar el resultado en la primera.\n# Operador %= equivale a hacer el módulo de la división de dos variables y almacenar su resultado en la primera.\n# Operador //= la operación cociente entre dos variables y almacena el resultado en la primera.\n# Operador **= equivale  a realiza la operación exponente del primer número elevado al segundo, y almacena el resultado en la primera variable.\n# Operador &= equivale  a realiza la operación AND entre dos variables y almacena el resultado en la primera variable.\n\na=2; b=3\nprint(\"Operadores de asignación\")\nx=a; x+=b;  print(\"x+=\", x) #5\nx=a; x-=b;  print(\"x-=\", x) #-1\nx=a; x*=b;  print(\"x*=\", x) #6\nx=a; x/=b;  print(\"x/=\", x) #0.6666666666666666\nx=a; x%=b;  print(\"x%=\", x) #2\nx=a; x//=b; print(\"x//=\", x) #0\nx=a; x**=b; print(\"x**=\", x) #8\nx=a; x&=b;  print(\"x&=\", x) #2 \nx=a; x|=b;  print(\"x|=\", x) #3\n\n\n### Operadores Relacionales : permiten realizar operaciones de comparación y devolver True o False.\n#-----------------------------------------------------------------------------\nx=2; y=3\nprint(\"Operadores Relacionales\")\nprint(\"x==y =\", x==y) # False  Operador de comparación (igualdad)\nprint(\"x!=y =\", x!=y) # True   Operador de comparación (desigualdad)\nprint(\"x>y  =\", x>y)  # False  Operador de comparación (mayor que)\nprint(\"x<y  =\", x<y)  # True   Operador de comparación (menor que)\nprint(\"x>=y =\", x>=y) # False  Operador de comparación (mayor o igual que)\nprint(\"x<=y =\", x<=y) # True   Operador de comparación (menor o igual que)\n\n\n### Operadores Lógicos : permiten realizar operaciones logicas y devolver True o False.\n#-----------------------------------------------------------------------------\n# and   Devuelve True si ambos elementos son True\t            True and True = True\n# or\tDevuelve True si al menos un elemento es True\t        True or False = True\n# not\tDevuelve el contrario, True si es Falso y viceversa\t     not True = False\n\n\n# AND: \n#El operador and evalúa si el valor a la izquierda y el de la derecha son True, y en el caso de ser cierto, devuelve True. Si uno de los dos valores es False, el resultado \n# será False.\nprint(True and True)   # True\nprint(True and False)  # False\nprint(False and True)  # False\nprint(False and False) # False\n\n\n# OR:\n# El operador or devuelve True cuando al menos uno de los elementos es igual a True. Es decir, evalúa si el valor a la izquierda o el de la derecha son True.\n\nprint(True or True)   # True\nprint(True or False)  # True\nprint(False or True)  # True\nprint(False or False) # False\n\n\n# NOT:\n# El operador not devuelve el opuesto de un valor. Es decir, True se convierte en False y False se convierte en True.\nprint(not True)  # False\nprint(not False) # True\nprint(not not not not True) # True\n\n# Se puede usar 0 y 1 para representar False y True respectivamente. \nprint(not 0) # True\nprint(not 1) # False\n\n\n# Nota: el orden de aplicación de los operadores puede influir en el resultado. De mayor a menor prioridad: not, and y or.\nprint(False and False or True) # True\nprint(True or False and False) # True\nprint(0 and not 1 or 1 and not 0 or 1 and 0) #(False and False or True and True or True and False) --> # True\n\n\n# Operadores de Identidad: permiten comprobar si dos variables hacen referencia al mismo objeto, devolviendo True en el cado  de ser cierto.\n#-----------------------------------------------------------------------------\n# is\t    Devuelve True si hacen referencia a el mismo objeto\n# is not\tDevuelve False si no hacen referencia a el mismo objeto\n\na = 10 ; b = 10 ; print(a is b) # True\n# La funcion id() Devuelve el identificador único de un objeto. Ambos apuntan a la misma ubicación en memoria al ser el mismo valor.\nprint(id(a)) # 9756512  Este valor es la dirección de memoria del objeto\nprint(id(b)) # 9756512  Este valor es la dirección de memoria del objeto\n\na = 10 ; b = 10 ; print(a is not b) # False --> ambas variables apuntan a el mismo objeto.\na = 10 ; b = 20 ; print(a is not b) # True --> las variables no apuntan a el mismo objeto.\n\n\n# Operadores de pertenecia: permiten comprobar si un objeto pertenece a una secuencia ( lista, tupla , conjunto o cadena), devolviendo True en el caso de ser cierto.\n#-----------------------------------------------------------------------------\n# in\t    Devuelve True si el objeto pertenece a la secuencia\n# not in\tDevuelve False si el objeto no pertenece a la secuencia\n\na = 10  ; print(a in [10,20,30]) # True\na = 50  ; print(a in [10,20,30]) # False\nprint([1, 2] in [4, [1, 2], 7]) # True\nprint(3 not in [1, 2, 4, 5]) # True\nx = [\"apple\", \"banana\"] ; print(\"banana\" in x) # True\nprint('s' in 'perro') # False\n\n\n# Operadores de bitwise\n#-----------------------------------------------------------------------------\n# AND (&)\tRealiza una operación AND bit a bit  --> Compara cada bit de dos operandos y devuelve 1 si ambos bits son 1, de lo contrario devuelve 0.\na = 4 ; bin_a = bin(a)\nb = 5; bin_b = bin(b)\n\nprint(f\"AND: {bin_a} & {bin_b} = {bin(a & b)}\")\n\n# OR (|)\tRealiza una operación OR bit a bit --> compara cada bit de dos operandos y devuelve 1 si al menos uno de los bits es 1.\nprint(f\"OR: {bin_a} | {bin_b} = {bin(a | b)}\")\n\n# NOT (~)\tRealiza una operación NOT bit a bit --> ealiza la operación not sobre cada bit del número que le introducimos, es decir, invierte el valor de cada bit, \n# poniendo los 0 a 1 y los 1 a 0. El comportamiento en Python puede ser algo distinto del esperado. En realidad  ~a sería -a-1\n\nprint(f\"NOT: ~{bin_a} = {bin(~a)}\")\n\n# XOR (^)\tRealiza una operación XOR bit a bit -->  compara cada bit de dos operandos y devuelve 1 si exactamente uno de los bits es 1, pero no ambos.\nprint(f\"XOR: {bin_a} ^ {bin_b} = {bin(a ^ b)}\")\n\n# Operadores de Desplazamiento:Los operadores de desplazamiento mueven los bits de un número hacia la izquierda (<<) o hacia la derecha (>>) en la cantidad especificada.\n#-----------------------------------------------------------------------------\n\n# Desplazamiento Derecha (>>)\tDesplaza los bits a la derecha\n\nprint(f'{bin_a} >> 2  = {bin(a>>2)}')\nprint(f'{bin_b} >> 2  = {bin(b>>2)}')\n\n# Desplazamiento Izquierda (<<)\tDesplaza los bits a la izquierda\n\nprint(f'{bin_a} << 2  = {bin(a<<2)}')\nprint(f'{bin_b} << 2  = {bin(b<<2)}')\n\n\n## 2. Utilizando las operaciones con operadores que tú quieras, crea ejemplos:\n# que representen todos los tipos de estructuras de control que existan en tu lenguaje:\n# Condicionales, iterativas, excepciones...\n\n## Estrcuturas de control\n# Condicionales\n\n# If-elif-else\ndef grupo_edad(edad):\n    if edad <=0:  \n        print('la edad no puede ser negativa, ni igual a 0')  \n    elif 0 > edad <=3:\n        print('bebe')\n    elif 4 >= edad <=12:\n        print('niño')\n    elif 13 >= edad <=17:\n        print('adolescente')\n    elif 18>= edad <=60:\n        print('adulto')\n    else:\n        print('mayor de 60')\n\ngrupo_edad(-5)\ngrupo_edad(0)\ngrupo_edad(4)\ngrupo_edad(17)\ngrupo_edad(25)\ngrupo_edad(80)\n\n\n# Iterativas\nfor i in range(5):\n    print(i)\n\n\n# Ciclos anidados\nmatrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]\n\nfor row in matrix:\n    for item in row:\n        print(item)\n\n\nx = 3\nwhile x > 0: \n    x -=1\n    print(x)   \n\n# Excepciones\n# Una excepción es un evento inesperado que ocurre durante la ejecución del programa.\n# Control de excepciones: try, except, else, finally.\n\n\"\"\"\nPrincipales tipos de excepciones:\n* TypeError : Ocurre cuando se aplica una operación o función a un dato del tipo inapropiado.\n* ZeroDivisionError : Ocurre cuando se itenta dividir por cero.\n* OverflowError : Ocurre cuando un cálculo excede el límite para un tipo de dato numérico.\n* IndexError : Ocurre cuando se intenta acceder a una secuencia con un índice que no existe.\n* KeyError : Ocurre cuando se intenta acceder a un diccionario con una clave que no existe.\n* FileNotFoundError : Ocurre cuando se intenta acceder a un fichero que no existe en la ruta indicada.\n* ImportError : Ocurre cuando falla la importación de un módulo.\n\n\"\"\"\n\ndef division(a, b):\n    try:\n        result = a / b\n    except ZeroDivisionError as e:\n        print('catch ZeroDivisionError:', e)\n    except TypeError as e:\n        print('catch TypeError:', e)\n    else:\n        print(\"result is\", result)\n    finally:\n        print(\"'This is always executed'\")\n\ndivision(10, 0)\ndivision('a', 'b')\ndivision(12, 3)\n\n\n## 3. Debes hacer print por consola del resultado de todos los ejemplos.\n\n##DIFICULTAD EXTRA (opcional):\n# Crea un programa que imprima por consola todos los números comprendidos entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n# Resultado : 10, 14, 20, 22, 26, 28, 32, 34, 38, 40, 44, 46, 50, 52\n\n\n# solucion 1\nprint(\"Solucion 1\")\nfor i in range(10, 56,2):\n    if i != 16 and i % 3 != 0:\n        print(i)\n    \n\n# solucion 2\nprint(\"Solucion 2\")\nfor i in range(10, 56):\n    if i%2 == 0 and i != 16 and i % 3 != 0:\n        print(i)\n    "
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/eugeniasoria.py",
    "content": "# #01 OPERADORES Y ESTRUCTURAS DE CONTROL\r\n'''\r\n * EJERCICIO:\r\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\r\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\r\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\r\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\r\n *   que representen todos los tipos de estructuras de control que existan\r\n *   en tu lenguaje:\r\n *   Condicionales, iterativas, excepciones...\r\n * - Debes hacer print por consola del resultado de todos los ejemplos.\r\n'''\r\n\r\nprint('>>Arithmetic operators / Operadores aritméticos')\r\nprint(f'(+) Addition / Suma: 2 + 3 = {2 + 3}')\r\nprint(f'(-) Subtraction / Resta: 5 - 7 = {5 - 7}')\r\nprint(f'(*) Multiplication / Multiplicación: 6 * 8 = {6 * 8}')\r\nprint(f'(/) Division / División: 10 / 6 = {10 / 6}')\r\nprint(f'(%) Modulus / Módulo: 5 % 2 = {5 % 2}')\r\nprint(f'(**) Exponentiation / Potencia: 2 ** 32 = {2 ** 32}')\r\nprint(f'(//) Floor Division / División entera : 10 // 6 = {10 // 6}')\r\n\r\nprint()\r\nprint('>>Assignment operators / Operadores de asignación')\r\nx = 1000\r\nprint(f'(=) x = 5 => {x}')\r\nx += 3\r\nprint(f'(+=) x += 3  lo mismo que  x = x + 3 => {x}')\r\nx -= 3 \r\nprint(f'(-=) x -= 3  lo mismo que  x = x - 3 => {x}')\r\nx *= 3\r\nprint(f'(*=) x *= 3  lo mismo que  x = x * 3 => {x}')\r\nx /= 3\r\nprint(f'(/=) x /= 3  lo mismo que  x = x / 3 => {x}')\r\nx %= 3\r\nprint(f'(%=) x %= 3  lo mismo que  x = x % 3 => {x}')\r\n\r\nx = 1000\r\nprint(f\"x=1000\")\r\nx //= 3\r\nprint(f'(//=) x //= 3  lo mismo que  x = x // 3 => {x}')\r\nx **= 3\r\nprint(f'(**=) x **= 3  lo mismo que  x = x ** 3 => {x}')\r\nx &= 3\r\nprint(f'(&=) x &= 3  lo mismo que  x = x & 3 => {x}')\r\nx |= 3\r\nprint(f'(|=) x |= 3  lo mismo que  x = x | 3 => {x}')\r\nx = 10\r\nprint(f\"x=10\")\r\nx ^= 3\r\nprint(f'(^=) x ^= 3  lo mismo que  x = x ^ 3 => {x}')\r\nx >>= 3\r\nprint(f'(>>=) x >>= 3  lo mismo que  x = x >> 3 => {x}')\r\nx <<= 3\r\nprint(f'(<<=) x <<= 3  lo mismo que  x = x << 3 => {x}')\r\nprint(f'(:=) print(x := 44)  lo mismo que y luego print')\r\nprint(x := 44)\r\n\r\nprint()\r\nprint('>>Comparison operators / Operadores de comparación')\r\nx = 10\r\ny = 5\r\nprint(f\"x=10, y=5\")\r\nprint(f'(==) Equal/Igual x == y => {x == y}')\r\nprint(f'(!=) Not equal/Distinto x != y => {x != y}')\r\nprint(f'(>)  Greater than/Mayor que x > y => {x > y}')\r\nprint(f'(<)  Less than/Menor que x < y => {x < y}')\r\nprint(f'(>=) Greater than or equal to/Mayor o igual que x >= y => {x >= y}')\r\nprint(f'(<=) Less than or equal to/Menor o igual que x <= y => {x <= y}')\r\n\r\nprint()\r\nprint('>>Logical operators / Operadores lógicos')\r\nx = 10\r\ny = 5\r\nprint(f\"x=10, y=5\")\r\nprint(f'(and) Retorna True si ambas sentencias son True  x < 5 and  x < 10 => {x < 5 and  x < 10}')\r\nprint(f'(or)  Retorna True si una de las sentencias es True  x < 5 or x < 4 => {x < 5 or x < 4}') \r\nprint(f'(not) Revierte el resultado, Retorna False si el resultado es True  not(x < 5 and x < 10) => {not(x < 5 and x < 10)}')\r\n\r\nprint()\r\nprint('>>Identity operators / Operadores de Identidad')\r\nx = [\"manzana\", \"banana\"]\r\ny = [\"manzana\", \"banana\"]\r\nz = x\r\nprint('x = [\"manzana\", \"banana\"]')\r\nprint('y = [\"manzana\", \"banana\"]')\r\nprint('z = x')\r\n\r\nprint(f'(is)  Retorna True si ambas variables son el mismo objeto x is y => {x is y}, x is z => {x is z}')\r\nprint(f'(is not) Retorna True si ambas variables no son el mismo objeto x is not y => {x is not y}, x is not z => {x is not z}')\r\n\r\nprint()\r\nprint('>>Membership operators / Operadores de Membresía')\r\nx = [\"sol\", \"luna\"]\r\nprint('x = [\"sol\", \"luna\"]')\r\nprint(f'(in)     Retorna True si una secuencia con el valor especificado está presente en el objeto    \"sol\" in x        => {\"sol\" in x}')\r\nprint(f'(not in) Retorna True si una secuencia con el valor especificado no está presente en el objeto \"asteroide\"\" in x => {\"asteroide\" in x}')\r\n\r\nprint()\r\nprint('>>Bitwise operators / Operadores bit a bit')\r\nx = 6\r\ny = 3\r\nprint(f\"x=6, 6 = 0000000000000110\")\r\nprint(f\"y=3, 3 = 0000000000000011\")\r\nprint(f'(&) AND Establece cada bit en 1 si ambos bits son 1 x & y => {x & y} (2 = 0000000000000010)')\r\nx = 6\r\ny = 3\r\nprint(f\"x=6, 6 = 0000000000000110\")\r\nprint(f\"y=3, 3 = 0000000000000011\")\r\nprint(f'(|) OR Establece cada bit en 1 si uno de los dos bits es 1 x | y => {x | y} (7 = 0000000000000111)')\r\nx = 6\r\ny = 3\r\nprint(f\"x=6, 6 = 0000000000000110\")\r\nprint(f\"y=3, 3 = 0000000000000011\")\r\nprint(f'(^) XOR Establece cada bit en 1 si solo uno de los dos bits es 1 x ^ y => {x ^ y} (5 = 0000000000000101)')\r\nx = 3\r\nprint(f\"x=3, 3 = 0000000000000011\")\r\nprint(f'(~) NOT Invierte todos los bits ~x => {~x} (-4 = 1111111111111100)')\r\nx = 3\r\nprint(f\"x=3, 3 = 0000000000000011\")\r\nprint(f'(<<) Zero fill left shift: Desplaza hacia la izquierda empujando ceros desde la derecha')\r\nprint(f'y deja que los bits más a la izquierda caigan')\r\nprint(f'x << 2 => {x << 2} (12 = 0000000000001100)')\r\n\r\nx = 8\r\nprint(f\"x=8, 8 = 0000000000001000\")\r\nprint(f'(>>) Signed right shift: Desplaza a la derecha empujando copias del bit más a la izquierda desde la izquierda,', end = ' ' )\r\nprint(f'y deja que los bits más a la derecha se caigan x >> 2 => {x >> 2} ( 2 = 0000000000000010)')\r\n\r\nprint()\r\nprint('Estructuras de control')\r\nprint('Condicionales, iterativas, excepciones...')\r\n\r\nprint('>>If statement')\r\na = 4\r\nb = 8\r\nprint ('a = 4\\nb = 8 \\nif a < b :\\n print(\"a es menor que b\")')\r\nprint ('Resultado: ')\r\nif a < b:\r\n  print(\"a es menor que b\")\r\n\r\nprint()\r\nprint('>>If statement - Elif')\r\na = 4\r\nb = 4\r\nprint ('a = 4\\nb = 4 \\nif b < a: :\\n print(\"b es menor que a\")\\nelif a == b :\\n print(\"a y b son iguales\")  ')\r\nprint ('>Resultado: ')\r\nif b < a:\r\n  print(\"b es menor que a\")  \r\nelif a == b :\r\n  print(\"a y b son iguales\") \r\n\r\nprint()\r\nprint('>>If statement - Else')\r\na = 400\r\nb = 40\r\nprint ('a = 400\\nb = 40 \\nif b > a:\\n print(\"b es mayor que a\")\\nelif a == b:\\n print(\"a y b son iguales\")\\nelse:\\n print(\"a es mayor que b\")')\r\nprint ('>Resultado: ')\r\nif b > a:\r\n  print(\"b es mayor que a\")\r\nelif a == b:\r\n  print(\"a y b son iguales\")\r\nelse:\r\n  print(\"a es mayor que b\")\r\n\r\nprint()\r\nprint('>>If statement - Short Hand if (en una linea)')\r\na = 256\r\nb = 255\r\nprint('a = 256\\nb = 255 \\nif a > b: print(\"a es mayor que b\")')\r\nprint ('>Resultado: ')\r\nif a > b: print(\"a es mayor que b\")\r\n\r\nprint()\r\nprint('>>If statement - Short Hand if ... Else (en una linea)')\r\na = 6\r\nb = 110\r\nprint('a = 6\\nb = 110 \\nprint(\"A\") if a > b else print(\"B\")')\r\nprint ('>Resultado: ')\r\nprint(\"A\") if a > b else print(\"B\")\r\n\r\nprint()\r\nprint('>>If statement - Short Hand if ... Else con 3 condiciones(en una linea)')\r\na = 4444\r\nb = 4444\r\nprint('a = 4444\\nb = 4444 \\nprint(\"A\") if a > b else print(\"=\") if a == b else print(\"B\")')\r\nprint ('>Resultado: ')\r\nprint(\"A\") if a > b else print(\"=\") if a == b else print(\"B\")\r\n\r\nprint()\r\nprint('>>If statement - Nested if (if anidados)')\r\nx = 41\r\nprint('x = 41\\nif x > 10:\\n print(\"Above ten,\")\\n if x > 20:\\n  print(\"and also above 20!\")\\n else:\\n  print(\"but not above 20.\")')\r\nprint ('>Resultado: ')\r\nif x > 10:\r\n  print(\"Más que 10,\")\r\n  if x > 20:\r\n    print(\"y también más que 20!\")\r\n  else:\r\n    print(\"pero no más que 20.\")\r\n\r\nprint()\r\nprint('>>If statement - The pass Statement (evitar error en sentencias if sin contenido)')\r\na = 1\r\nb = 2\r\nprint('a = 1\\nb = 2\\nif b > a:\\n pass')\r\nprint ('>Resultado: ')\r\nif b > a:\r\n  pass\r\n\r\n\r\nprint('\\n\\n')\r\nprint('>>The while Loop')\r\n\r\nprint('i = 1\\nwhile i < 6:\\n print(i)\\n i += 1')\r\nprint ('>Resultado: ')\r\ni = 1\r\nwhile i < 6:\r\n  print(f'iteracion: {i}')\r\n  i += 1\r\n\r\nprint()\r\nprint('>>The break Statement')\r\nprint('i = 1\\nwhile i < 6:\\n print(i)\\n if i == 3:\\n  break\\n i += 1')\r\nprint ('>Resultado: ')\r\ni = 1\r\nwhile i < 6:\r\n  print(i)\r\n  if i == 3:\r\n    break\r\n  i += 1\r\n\r\nprint()\r\nprint('>>The continue Statement')\r\nprint('i = 1\\nwhile i < 6:\\n i += 1\\n if i == 3:\\n  continue\\n print(i)')\r\nprint ('>Resultado: ')\r\ni = 0\r\nwhile i < 6:\r\n  i += 1\r\n  if i == 3:\r\n    continue\r\n  print(i)\r\n\r\nprint()\r\nprint('>>The else Statement')\r\nprint('i = 1\\nwhile i < 6:\\n print(i)\\n i += 1\\nelse:\\n  print(\"i is no longer less than 6\")')\r\nprint ('>Resultado: ')\r\ni = 1\r\nwhile i < 6:\r\n  print(i)\r\n  i += 1\r\nelse:\r\n  print(\"i ya no es menor que 6\")\r\n\r\n\r\nprint('\\n\\n')\r\nprint('>>For Loops')\r\n\r\nprint('mascotas = [\"Luna\", \"Ash\", \"Alma\"]\\nfor x in mascotas:\\n print(x)')\r\nprint ('>Resultado: ')\r\nmascotas = [\"Luna\", \"Ash\", \"Alma\"]\r\nfor x in mascotas:\r\n  print(x)\r\n\r\nprint('\\n>>Loop en un String')  \r\nprint('for x in \"Python\":\\n print(x)')\r\nprint ('>Resultado: ')\r\nfor x in \"Python\":\r\n  print(x)\r\n\r\nprint('\\n>>The break Statement')  \r\nprint('planetas = [\"Tierra\", \"Marte\", \"Plutón\", \"Júpiter\"]\\nfor x in planetas:\\n print(x) \\n if x == \"Plutón\":\\n  break')\r\nprint ('>Resultado: ')\r\nplanetas = [\"Tierra\", \"Marte\", \"Plutón\", \"Júpiter\"]\r\nfor x in planetas:\r\n  print(x)\r\n  if x == \"Plutón\":\r\n    break\r\n\r\nprint('\\n>>The continue Statement')  \r\nprint('planetas = [\"Tierra\", \"Marte\", \"Plutón\"]\\nfor x in planetas:\\n if x == \"Marte\":\\n  continue\\n print(x)')\r\nprint ('>Resultado: ')\r\nplanetas = [\"Tierra\", \"Marte\", \"Plutón\"]\r\nfor x in planetas:  \r\n  if x == \"Marte\":\r\n    continue\r\n  print(x)\r\n\r\nprint('\\n>>The range() Function')  \r\nprint('con 1 solo parámetro comienza en 0 y termina antes que el valor pasado')\r\nprint('for x in range(6):\\n print(x)')\r\nprint ('>Resultado: ')\r\nfor x in range(6):\r\n  print(x)\r\n\r\nprint('\\ncon 2 parámetros comienza en el valor del primero y termina antes que el segundo valor')  \r\nprint('for x in range(2, 6):\\n print(x)')\r\nprint ('>Resultado: ')\r\nfor x in range(2, 6):\r\n  print(x)  \r\n\r\nprint('\\nsi se agrega un 3er parámetro, este indica los incrementos')  \r\nprint('for x in range(2, 30, 3):\\n print(x)')\r\nprint ('>Resultado: ')\r\nfor x in range(2, 30, 3):\r\n  print(x)\r\n\r\nprint('\\nElse in For Loop')  \r\nprint('for x in range(6):\\n print(x)\\nelse:\\n print(\"Finally finished!\")')\r\nprint ('>Resultado: ')\r\nfor x in range(6):\r\n  print(x)\r\nelse:\r\n  print(\"Finally finished!\")\r\n\r\nprint('\\nNested Loops')  \r\nprint('color = [\"azul\", \"verde\", \"dorado\"]\\nobjeto = [\"violeta\", \"manzana\", \"sol\"]\\nfor x in color:\\n for y in objeto:\\n  print(x, y)')\r\nprint ('>Resultado: ')\r\ncolor = [\"azul\", \"verde\", \"dorado\"]\r\nobjeto = [\"piedra\", \"manzana\", \"sol\"]\r\nfor x in color:\r\n  for y in objeto:\r\n    print(x, y)\r\n\r\nprint('\\nThe pass Statement (evitar error en loop for sin contenido)')  \r\nprint('for x in [0, 1, 2]:\\n pass')\r\nprint ('>Resultado: ')\r\nfor x in [0, 1, 2]:\r\n  pass\r\n\r\n'''\r\n * DIFICULTAD EXTRA (opcional):\r\n * Crea un programa que imprima por consola todos los números comprendidos\r\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\r\n *\r\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\r\n'''\r\n\r\nfor i in range(10, 56):\r\n  if i % 2 == 0 and i != 16 and i % 3 != 0:\r\n    print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/evilpotato04.py",
    "content": "#/*\n# * EJERCICIO:\n# * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n# *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n# *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n# * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n# *   que representen todos los tipos de estructuras de control que existan\n# *   en tu lenguaje:\n# *   Condicionales, iterativas, excepciones...\n# * - Debes hacer print por consola del resultado de todos los ejemplos.\n\n# ====== >> Operadores aritméticos << ======\n# suma (+)\nsuma = 3 + 4\nprint(suma) # result: 7\n\n# resta (-)\nresta = 3 - 4\nprint(resta) # result: -1\n\n# multiplicacion (*)\nmult = 3 * 4\nprint(mult) # result: 12\n\n# división (/)\ndivision = 3 / 4\nprint(division) # result: 0.75\n\n# división interna (//)\ndivision_interna = 3 // 4\nprint(division_interna) # result: 0\n\n# módulo (%)\nmodulo = 3 % 4\nprint(modulo) # result: 3\n\n# exponenciación (**)\nexpo = 3 ** 4\nprint(expo) # result: 81\n\n# ====== >> Operadores de comparación << ======\n# igual (==)\ncomp1 = 3 == 4\nprint(comp1) # result: False\n\n# diferente (!=)\ncomp2 = 3 != 4\nprint(comp2) # result: True\n\n# más grande que (>)\ncomp3 = 3 > 4\nprint(comp3) # result: False\n\n# mayor o igual (>=)\ncomp3 = 3 >= 4\nprint(comp3) # result: False\n\n# menos que (<)\ncomp4 = 3 < 4\nprint(comp4) # result: True\n\n# menos o igual (<=)\ncomp4 = 3 <= 4\nprint(comp4) # result: True\n\n# ====== >> Operadores lógicos << ======\n# and (and)\ncomp_log1 = 3 == 4 and \"rojo\" == \"rojo\"\nprint(comp_log1) # result: False\n\n# or (or)\ncomp_log2 = 3 == 4 or \"rojo\" == \"rojo\"\nprint(comp_log2) # result: True\n\n# not (not)\ncomp_log3 = not (3 == 4 or \"rojo\" == \"rojo\")\nprint(comp_log3) # result: False\n\n# ====== >> Operadores de asignación << ======\n# = \tx = 1\na, b, c, d, e, f = 10, 10, 10, 10, 10, 10\nprint(a) # result: 10\n# +=\tx = x + 1\nb += 2\nprint(b) # result: 12\n# -=\tx = x - 1\nc -= 3\nprint(c) # result: 7\n# *=\tx = x * 1\nd *= 4\nprint(d) # result: 40\n# /=\tx = x / 1\ne /= 5\nprint(e) # result: 2.0\n# %=\tx = x % 1\nf %= 6\nprint(f) # result: 4\n\n# ====== >> Operadores de identidad << ======\npokemon = [\"Bulbasaur\", \"Charmander\", \"Squirtle\"]\npokemon2 = [\"Bulbasaur\", \"Charmander\", \"Squirtle\"]\npokemon3 = pokemon\n\n# is\nprint(pokemon is pokemon2) # result: False\nprint(pokemon is pokemon3) # result: True\n\n# is not\nprint(pokemon is not pokemon2) # result: True\nprint(pokemon is not pokemon3) # result: False\n\n# ====== >> Operadores de pertenencia << ======\n# in\nprint(\"Pikachu\" in pokemon) # result: False\n# not in\nprint(\"Pikachu\" not in pokemon) # result: True\n\n# ====== >> Operadores bitwise << ======\n# Ejemplos de equivalencias entre números decimales y binarios:\n# 0 = “0”\n# 1 = “1”\n# 2 = “10”\n# 3 = “11”\n# 4 = “100”\n# 5 = “101”\n# 1029 es “10000000101” == 2**10 + 2**2 + 2**0 == 1024 + 4 + 1\n\n# x << y    (x = x * 2 ** y)\nx = 5 # equivalente a \"101\" en binario\ny = 3 # equivalente a \"11\" en binario\n\nresult = x << y\nprint(result) # result: 40 (equivalente a \"101000\" en binario)\n# es decir, aumentó 3 ceros a la derecha del binario\n\n# x >> y    (x = x / 2 ** y)\nx = 40 # equivalente a \"101000\" en binario\ny = 3 # equivalente a \"11\" en binario\n\nresult = x >> y\nprint(result) # result: 5 (equivalente a \"101\" en binario)\n# es decir, disminuyó 3 ceros a la derecha del binario\n\n# x & y (and bit-a-bit)\n# tabla verdad de \"AND\"\n# False + False = False\n# False + True = False\n# True + False = False\n# True + True = True\n\nx = 5 # \"101\" en binario\ny = 3 # \"011\" en binario\nresult = x & y\nprint(result) # result: 1 (equivalente a \"001\" en binario)\n\n# x | y (or bit-a-bit)\n# tabla verdad de \"OR\"\n# False + False = False\n# False + True = True\n# True + False = True\n# True + True = True\n\nx = 5 # \"101\" en binario\ny = 3 # \"011\" en binario\nresult = x | y\nprint(result) # result: 7 (equivalente a \"111\" en binario)\n\n# x ^ y (xor bit-a-bit)\n# tabla verdad de \"XOR\"\n# False + False = False\n# False + True = True\n# True + False = True\n# True + True = False\n\nx = 5 # \"101\" en binario\ny = 3 # \"011\" en binario\nresult = x ^ y\nprint(result) # result: 6 (equivalente a \"110\" en binario)\n\n# ~x (devuelve el complemento)\nx = 5 # \"101\" en binario\nresult = ~x\nprint(result) # result: -6 (\"1111 1111 1111 1010\" en binario [numero negativo])\n\n# ====== >> Estructura de control (condicionales) << ======\nelemento = \"tierra\"\n\n# if-else\nif elemento == \"agua\":\n    print(\"El elemento es agua\")\nelse:\n    print(\"El elemento no es agua\")\n\n# elif\nif elemento == \"agua\":\n    print(\"El elemento es agua\")\nelif elemento == \"tierra\":\n    print(\"El elemento es tierra\")\nelif elemento == \"fuego\":\n    print(\"El elemento es fuego\")\nelif elemento == \"aire\":\n    print(\"El elemento es aire\")\n\n# match-case\nmatch elemento:\n    case \"agua\":\n        print(\"El elemento es agua\")\n    case \"tierra\":\n        print(\"El elemento es tierra\")\n    case \"fuego\":\n        print(\"El elemento es fuego\")\n    case \"aire\":\n        print(\"El elemento es aire\")\n    case _:\n        print(\"No es elemento\")\n\n# ====== >> Estructura de control (iterativas) << ======\n# while\ncount = 5\nwhile count > 0:\n    print(\"count down:\", count)\n    count -= 1\n\n# for-in\nfor counting in range(5):\n    print(\"count up:\", counting)\n\n# ====== >> Estructura de control (excepciones) << ======\n# try-except\ntry:\n    x = 2\n    y = 0\n    result = x / y # result: ZeroDivisionError (division by zero)\n    print(result)\nexcept:\n    print(\"ocurrió un error\")\n\n# * DIFICULTAD EXTRA (opcional):\n# * Crea un programa que imprima por consola todos los números comprendidos\n# * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n# *\n# * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n# */\n    \ndef dificultad_extra():\n    \"\"\"\n    Crea un programa que imprima por consola todos los números comprendidos\n    entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n    \"\"\"\n    for numero in range(56):\n        if numero >= 10 and numero <= 55:\n            if numero % 2 == 0:\n                if numero != 16:\n                    if not numero % 3 == 0:\n                        print(numero)\n\ndificultad_extra()"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/ezecc-eze.py",
    "content": "# operadores aritmeticos\n\nprint(5+2)  # suma\nprint(5-2)  # resta\nprint(5*2)  # multi\nprint(5/2)  # division\nprint(5 % 2)  # devuelve lo que sobra de la division entera\nprint(5//2)  # devuelve division sin decimales\nprint(5**2)  # exponente\n# primero resuelve el exponente, luego la multi,despues la division , la suma y por ultimo la resta\nprint(5**2+3-5*4/2)\nprint(\"hola \" + \"python \")  # suma los str\nprint(\"hola \" + str(2))  # suma el hola y el 2 lo convertimos a str\nprint(\"hola \"*3)  # imprime el hola 3 veces\n\n# operadores comparativos\n\nprint(5 > 2)\nprint(5 < 2)\nprint(5 >= 2)\nprint(5 <= 2)\nprint(5 == 2)\nprint(5 != 2)\nprint(\"soy\" < \"eze\")  # compara un orden alfabetico\nprint(len(\"eze\") >= len(\"quiel\"))  # cuenta caracteres\n\n# operadores logicos\n\nprint(5 < 2 and 7 < 5)\nprint(5 > 2 and 7 > 5)\nprint(5 > 2 or 5 == 5)\nprint(5 > 2 and 6/2)\nprint(5 > 2 and 8/2 == 4)\nprint(5 > 2 and 5 == 5 or \"eze\" < \"soy\")\nprint(not (5 > 2))\n\n#operadores de asignacion\n\nnumerito = 5 # asignacion\nprint(numerito)\nnumerito += 2 #suma y asignacion\nprint(numerito)\nnumerito -= 2 #resta y asignacion\nprint(numerito)\nnumerito *= 2 #multi y asignacion\nprint(numerito)\nnumerito /= 2 #divi y asignacion\nprint(numerito)\nnumerito %= 2 #modulo y asignacion\nprint(numerito)\n\n#operadores de identidad\n\nmi_numero = 1.0\nprint(mi_numero is 1.0)\nprint(mi_numero is not numerito)\n\n#operadores de pertenencia\n\nprint(f\"'u' in 'auto' ={'u' in 'auto'}\") \nprint(f\"'u'  not it 'auto' ={'u' not in 'auto'}\") \n\n#operadores de bit\n\nope = 10 #1010\noper = 3  #0011\n\nprint(f\"AND: 10 & 3 = {10 & 3}\") #0010 #and : si ambos bit son 1 el bit resultante es 1 de lo contrario es 0\nprint(f\"OR: 10 & 3 = {10 | 3}\") #1011 #or: si al menos 1 de los bit es 1 , el resultado es 1\nprint(f\"XOR: 10 & 3 = {10 ^ 3}\") #1001 #xor: si los bit son diferentes el resultado es 1 , si los bit son iguales el resultado es 0\nprint(f\"not: ~10 = {~10}\") #1001 # not: intercambia el valor bit a bit de cualquiera de los elementos\nprint(f\"desplazamiento a la derecha: 10 >> 2 = {10 >> 2}\") # 0010\nprint(f\"desplazamiento a la izquierda: 10 << 2 = {10 << 2}\") # 101000\n\n\n# estructuras de control\n# condicinales\n\nvelocidad_auto_1 = 70\nif velocidad_auto_1 < 120 and velocidad_auto_1 > 60:\n    print(\"velocidad permitida:puede circular\")\nelif velocidad_auto_1 == 60:\n    print(\"circula al limite minimo\")\nelif velocidad_auto_1 == 120:\n    print(\"circula al limite maximo\")\nelse:\n    print(\"no esta en el rango disponible para circular\")\n\nvelocidad_auto_1 = \"\"\n\nif not velocidad_auto_1:\n    print(\"el auto no esta en marcha\")\n#iterativas\n\nfor velocidadess in range(60, 70):\n    print(velocidadess)\n\n\n# loops\n\nmi_auto_nuevo = 100\nwhile mi_auto_nuevo < 120:\n    print(mi_auto_nuevo)\n    mi_auto_nuevo += 5\nelse:\n    print(\"'mi_auto_nuevo' no se encuentra en el rango\")\n\nwhile mi_auto_nuevo < 150:\n    print(mi_auto_nuevo)\n    mi_auto_nuevo += 5\n    if mi_auto_nuevo == 130:\n        print(\"mi auto supera lo permitido:bajar velocidad\")\n        break\nprint(mi_auto_nuevo)\n\nvelocidades_de_hoy = [67, 75, 90, 90, 103, 125, 115]\nfor velocidades in velocidades_de_hoy:\n    print(velocidades)\n    if velocidades == 103:\n        break\n    print(\" no supera los 103\")\n\nelse:\n    print(\"los autos no vuelan\")\n\n# excepciones\n\ngiro = 180\ndobla = 90\ngiro = \"un u\"\n\ntry:\n    print(giro + dobla)\n    print(\"todo bien\")\nexcept:\n    print(\"se ha producido un error\")\nelse:\n    print(\"la ejecucion sigue correctamente\")\nfinally:\n    print(\"sigue funcionando\")\n\n#extra\n\nfor numeros_validos in range (10, 55):\n    if numeros_validos == 16:\n        continue\n    if numeros_validos % 3 != 0 and numeros_validos % 2 == 0:\n        print(numeros_validos) \n        \n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/fborjalv.py",
    "content": "# EJERCICIOS\n\n# Tipos de operadores: Aritméticos, Lógicos, Relacionales, asignación, pertenencia, identidad\n# Asignación: \n\noperador_a = 4\noperador_b = 2\n\n# Aritméticos\nprint(\"--- OPERADORES ARITMÉTICOS---\")\nprint(f\"Suma: {operador_a + operador_b} \")\nprint(f\"Resta: {operador_a - operador_b}\")\nprint(f\"División: {operador_a / operador_b}\")\nprint(f\"Multiplicación: {operador_a * operador_b}\")\nprint(f\"Resto: {operador_a % operador_b}\")\nprint(f\"Potencia: {operador_a ** operador_b}\")\n\n# Lógicos\nprint(\"--- OPERADORES LÓGICOS ---\")\nprint(\"si primer elemento es 2 y si segundo elemento es 4\")\nprint(operador_a == 2 and operador_b == 4)\nprint(\"si primer elemento es 2 O segundo elemeto es 5\")\nprint(operador_a == 2 or operador_b ==5 )\nprint(\"si primer elemento NO es 2\")\nprint(not operador_a == 4)\n\n\n# Relacionales\nprint(\"--- OPERADORES RELACIONALES ---\")\nprint(f\"2 es mayor que 4: {operador_b > operador_a}\")\nprint(f\"2 es menor que 4: {operador_b < operador_a}\")\nprint(f\"2 es igual que 4: {operador_b == operador_a}\")\nprint(f\"2 No es igual que 4: {operador_b != operador_a}\")\nprint(f\"2 es menor o igual que 4: {operador_b <= operador_a}\")\nprint(f\"2 es menor o igual que 4: {operador_b >= operador_a}\")\n\n\n# Asignación \n\nprint(\"--- OPERADORES DE ASIGNACIÓN ---\")\n\ncontador = 6 #asigna un valor\nprint(contador) \ncontador += 1 #incremeta valor en 1 y lo asigna a la variable\nprint(contador) \ncontador -= 1 #reduce valor en 1 y lo asigna a la variable \nprint(contador)\ncontador *= 2\nprint(contador)\ncontador /= 2\nprint(contador)\ncontador %= 2\nprint(contador)\n\n\n# Estructuras de control:  condicionales (if), iterativas (for, while), excepciones\n\na = 4\nb = 3\nc = 5\n\n# CONDICIONALES \nif a == 3:\n    print(\"a es igual a cuatro\")\nelif b != 5:\n    print(\"b no es igual a cinco\")\nelif c == 4:\n    print (\"c es igual a cuatro\")\nelse: \n    print(\"hemos llegado al final\")\n\n# ITERATIVAS: \nvar = \"fborjalv\"\n\nfor i in var:\n    print(i)\n\ncount = 0\nwhile count < len(var):\n    print(var[count])\n    count +=1\n\ntry:\n    print(10/0)\nexcept:\n    print(\"no se puede divir por cero\")\nfinally:\n    print(\"Fin al control de excepciones \")\n\n# DIFICULTAD EXTRA: \n\nfor num in range(10,56):\n    if num % 2 == 0 and not (num == 16 or num % 3 == 0):\n        print(num)\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/fidelysla.py",
    "content": "\n# * EJERCICIO:\n#  * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n#  *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n#  *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n\n#  * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n#  *   que representen todos los tipos de estructuras de control que existan\n#  *   en tu lenguaje:\n#  *   Condicionales, iterativas, excepciones...\n#  * - Debes hacer print por consola del resultado de todos los ejemplos.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea un programa que imprima por consola todos los números comprendidos\n#  * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n#  *\n#  * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\n\n# ? TIPOS DE OPERADORES\n\n# **Operadores Aritmeticos**\n\nnum1 = 3\n-num1 # -3\n\nnum1 + num1\nnum1 - num1\nnum1 * num1\nnum1 / num1\nnum1 % num1  # Devuelve el resto de la división\nnum1 ** num1 # Calcula el exponente\nnum1 // num1 # Devuelve el cociente de la división\n\n# **Operador de asignacion**\nnum2 = 20\nnum2 += 1  # num2 = num2 + 1\nnum2 -= 1\nnum2 *= 1\nnum2 /= 2\nnum2 %= 2  # num2 = num2 % 2\nnum2 **= 2 # num2 = num2 ** 2\nnum2 //= 2 # num2 = num2 // 2\n\n# **Operadores de comparacion**\n\nprint(3 == \"3\") #False\nprint(4 != \"4\") #True\nprint(3 > 2) #True\nprint(4 < 5) #True\nprint(6 >= 5) #True\n\n\n# **Operadores Logicos**\nisString = True\nisNum = False\n\nprint(isString and isNum)   # False\nprint(isString or isNum)    # True\nprint(not isNum)            # True\n\n\n# **Operadores Bit a Bit**\na = 5;  # Representación binaria: 0101\nb = 3;  # Representación binaria: 0011\n\nprint(a & b)  # 1 (AND a nivel de bits)\nprint(a | b)  # 7 (OR a nivel de bits)\nprint(a ^ b)  # 6\n\n\n# **Operadores de Pertenecia**\na = [1,2,3,4,5]\n\nprint(3 in a)       # True\nprint(12 not in a)  # True\n\n\n# **Operadores de Identidad**\n\"\"\"\nUn operador de identidad se emplea para comprobar\nsi dos variables emplean la misma ubicación en memoria.\n\"\"\"\na = 3\nb = 3\nc = 4\n\nprint(a is b)       # True\nprint(a is not b)   # False\nprint(a is not c)   # True\n\n\n\n# ? Ejemplos de tipos de estructuras de control\n\n#! **Condicionales**\n\n#* If-elif-else\n\nif isString and isNum:\n    print(\"Son tipos de datos verdaderos\")\nelif isString or isNum:\n    print(\"Por lo menos uno es tipo de dato verdadero\")\n\nif ( 15 > 16 ):\n    print(\"Consola 1\")\nelif (15 < 16):\n    print(\"Consola 2\")\n\n\n#! **Ciclos**\n\n#* For\n\nfor i in range(0,11):\n    if i % 2 == 0:\n        print(i)\n\n\nabc = { \"a\": 1, \"b\": 2, \"c\": 3 }\nfor (k, v) in abc.items():\n    print(f\"{k}: {v}\")\n\n\narr1 = [\"a\",\"b\",\"c\",\"d\",\"e\"]\nfor i in arr1:\n    print(i)\n\nfor (index, value) in enumerate(arr1):\n    print(f\"Index: {index}, Value: {value}\")\n\n\n#* While\n# Numeros entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\nnum3 = 10\nwhile (num3 <= 55):\n    if (num3 == 10):\n        print(num3)\n    elif (num3 % 3 == 0 or num3 == 16):\n        pass\n    else:\n        print(num3)\n    num3 += 2\n\n\n# **Manejo de Errores**\nx = 2\ny = 0\ntry:\n    result = x / y\nexcept ZeroDivisionError:\n    print(\"Error: Division por cero!\")\nelse:\n    print(\"Resultado:\", result)\nfinally:\n    print(\"Ejecutando la cláusula finalmente\")"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/fishellVvv.py",
    "content": "# operadores aritméticos\nprint(f\"Suma: 10 + 3 = {10 + 3}\")\nprint(f\"Resta: 10 - 3 = {10 - 3}\")\nprint(f\"Multiplicación: 10 * 3 = {10 * 3}\")\nprint(f\"División: 10 / 3 = {10 / 3}\")\nprint(f\"Módulo: 10 % 3 = {10 % 3}\")\nprint(f\"Exponente: 10 ** 3 = {10 ** 3}\")\nprint(f\"División entera: 10 // 3 = {10 // 3}\")\n\n# operadores de comparación\nprint(f\"Igualdad: 10 == 3 es {10 == 3}\")\nprint(f\"Desigualdad: 10 != 3 es {10 != 3}\")\nprint(f\"Mayor que: 10 > 10 es {10 > 10}\")\nprint(f\"Menor que: 10 < 3 es {10 < 3}\")\nprint(f\"Mayor o igual que: 10 >= 10 es {10 >= 10}\")\nprint(f\"Menor o igual que: 10 <= 3 es {10 <= 3}\")\n\n# operadores lógicos\nprint(f\"AND: 10 + 3 == 13 and 5 - 1 == 4 es {10 + 3 == 13 and 5 - 1 == 4}\")\nprint(f\"OR: 10 + 3 == 14 or 5 - 1 == 4 es {10 + 3 == 14 or 5 - 1 == 4}\")\nprint(f\"NOT: 10 + 3 == 14 es {not 10 + 3 == 14}\")\n\n# operadores de asignación\nmy_number = 11 # asgnación\nprint(my_number)\nmy_number += 2 # suma y asignación\nprint(my_number)\nmy_number -= 2 # resta y asignación\nprint(my_number)\nmy_number *= 2 # multiplicación y asignación\nprint(my_number)\nmy_number /= 2 # división y asignación\nprint(my_number)\nmy_number %= 2 # módulo y asignación\nprint(my_number)\nmy_number **= 2 # exponente y asignación\nprint(my_number)\nmy_number //= 2 # división entera y asignación\nprint(my_number)\n\n# operadores de identidad\nmy_new_number = 1.0\nprint(f\"my_number is my_new_number es {my_number is my_new_number}\")\nmy_new_number = my_number\nprint(f\"my_number is my_new_number es {my_number is my_new_number}\")\nprint(f\"my_number is not my_new_number es {my_number is not my_new_number}\")\n\n# operadores de pertenencia\nprint(f\"'v' in 'fishellVvv' = {'v' in 'fishellVvv'}\")\nprint(f\"'v' not in 'fishellVvv' = {'v' not in 'fishellVvv'}\")\n\n# operadores de bit\na = 10 # 00001010\nb = 3  # 00000011\nprint(f\"AND: 10 & 3 = {10 & 3}\") # 00000010\nprint(f\"OR: 10 | 3 = {10 | 3}\")  # 00001011\nprint(f\"XOR: 10 ^ 3 = {10 ^ 3}\") # 00001001\nprint(f\"NOT: ~10 = {~10}\")       # 11110101\nprint(f\"Despalzamiento a la derecha: 10 >> 2 = {10 >> 2}\") # 00000010\nprint(f\"Despalzamiento a la izquierda: 10 << 2 = {10 << 2}\") # 00101000\n\n# estructuras de control condicionales\nif a == b:\n    print(\"a es igual a b\")\nelif a > b:\n    print(\"a es mayor que b\")\nelse:\n    print(\"a no es igual ni mayor que b\")\n\n# estructuras de control iterativas\nfor i in range(a):\n    print(i, end=\"\")\nwhile b < a:\n    print(b, end=\"\")\n    b += 1\n\n# estructuras de control para manejo de excepciones\ntry:\n    print(a/0)\nexcept:\n    print(\"\\nSe ha producido un error\")\nfinally:\n    print(\"Ha finalizado el manejo de excepciones\")\n\n# EXTRA\n\nfor i in range(10, 56, 2):\n    if i != 16 and i % 3 != 0:\n        print(i, end=\", \")"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/fjsubero.py",
    "content": "\"\"\"\n  EJERCICIO:\n  - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n    Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n    (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n  - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n    que representen todos los tipos de estructuras de control que existan\n    en tu lenguaje:\n    Condicionales, iterativas, excepciones...\n  - Debes hacer print por consola del resultado de todos los ejemplos.\n \n *DIFICULTAD EXTRA (opcional):\n  Crea un programa que imprima por consola todos los números comprendidos\n *entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n \n  Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\"\"\"\n\n### Tipos de operadores en Python ###\n\n# 1. Operadores Aritméticos\n# Se utilizan para realizar operaciones matemáticas básicas.\n\nsuma = 5 + 3\nresta = 5 - 3\nmultiplicacion = 5 * 3\ndivision = 5 / 3\ndivision_entera = 5 // 3\nmodulo_resto = 1 % 3\npotencia = 5 ** 2\n\nprint(\"Suma:\", suma, \"Tipo de dato:\", type(suma))\nprint(\"Resta:\", resta, \"Tipo de dato:\", type(resta))\nprint(\"Multiplicación:\", multiplicacion, \"Tipo de dato:\", type(multiplicacion))\nprint(\"División:\", division, \"Tipo de dato:\", type(division))\nprint(\"División entera:\", division_entera, \"Tipo de dato:\", type(division_entera))\nprint(\"Módulo (resto):\", modulo_resto, \"Tipo de dato:\", type(modulo_resto))\nprint(\"Potencia:\", potencia, \"Tipo de dato:\", type(potencia))\n\n## 2. Operadores de Asignación\n\"\"\"\nAsignación simple: = (Ej: x = 5)\nAsignación con operación: +=, -=, *=, /=, //= (Ej: x += 3 es equivalente a x = x + 3)\n\"\"\"\n# Se utilizan para asignar valores a variables.\n\n# Operadores de Asignación\n\n# Asignación simple (=)\nx = 5\nprint(\"x =\", x)\n\n# Asignación con operación:\n\n#  Suma y asigna (+=)\nx += 3  # Equivalente a x = x + 3\nprint(\"x =\", x)\n\n# Resta y asigna (-=)\nx -= 2  # Equivalente a x = x - 2\nprint(\"x =\", x)\n\n# Multiplica y asigna (*=)\nx *= 4  # Equivalente a x = x * 4\nprint(\"x =\", x)\n\n# Divide y asigna (/=)\nx /= 2  # Equivalente a x = x / 2\nprint(\"x =\", x)\n\n# Divide a entero y asigna (//=)\nx //= 2  # Equivalente a x = x // 2 (división entera)\nprint(\"x =\", x)\n\n# Módulo(resto) y asigna (%=)\nx %= 3  # Equivalente a x = x % 3 (módulo)\nprint(\"x =\", x)\n\n# Potencia y asigna (**=)\nx **= 2  # Equivalente a x = x ** 2 (potencia)\nprint(\"x =\", x)\n\n\n## 3. Operadores de Comparación\n\"\"\"\nIgual: ==\nDiferente: !=\nMayor que: >\nMenor que: <\nMayor o igual que: >=\nMenor o igual que: <=\n\"\"\"\n# Se utilizan para comparar valores y devolver un valor booleano (True o False).\n\n# Nuestras variables para ejemplificar\nvalor_uno = 5\nvalor_dos = 3\ntexto_uno = \"Juan\"\ntexto_dos = \"Perez\"\n\n# Igualdad (==)\nprint(valor_uno == valor_dos)  # False\nprint(texto_uno == texto_dos)   # False\n\n# Desigualdad (!=)\nprint(valor_uno != valor_dos)  # True\nprint(texto_uno != texto_dos)   # True\n\n# Mayor que (>)\nprint(valor_uno > valor_dos)  # True\n# No se puede comparar directamente un número con un texto\n\n# Menor que (<)\nprint(valor_uno < valor_dos)  # False\n# No se puede comparar directamente un número con un texto\n\n# Mayor o igual que (>=)\nprint(valor_uno >= valor_dos)  # True\nprint(valor_uno >= valor_uno)  # True\n\n# Menor o igual que (<=)\nprint(valor_uno <= valor_dos)  # False\nprint(valor_uno <= valor_uno)  # True\n\n# Comparación de cadenas\nprint(\"apple\" < \"banana\")  # True (porque 'a' viene antes que 'b')\n\n# Comparación de números flotantes\nprint(3.14 > 3)  # True\n\n# Comparación de valores booleanos\nprint(True == True)  # True\nprint(False != True)  # True\n\n\n## 4. Operadores Lógicos\n\"\"\"\nY: and (Ambas expresiones deben ser True para que el resultado sea True)\nO: or (Al menos una expresión debe ser True para que el resultado sea True)\nNo: not (Invierte el valor booleano)\n\"\"\"\n# Se utilizan para combinar expresiones booleanas.\n\n# Operadores Lógicos\n\n# Definimos algunas variables booleanas\na = True\nb = False\n\n# Operador AND (y)\nprint(a and b)  # False (ambas deben ser True)\nprint(a and a)  # True (ambas son True)\n\n# Operador OR (o)\nprint(a or b)  # True (al menos una debe ser True)\nprint(b or b)  # False (ninguna es True)\n\n# Operador NOT (no)\nprint(not a)  # False (invierte el valor de a)\nprint(not b)  # True (invierte el valor de b)\n\n# Combinando operadores\nprint(a and (not b))  # True (a es True y b es False)\nprint((not a) or b)  # False (ninguna es True)\n\n## 5. Operadores de Identidad\n\"\"\"\nEs: is\nNo es: is not\n\"\"\"\n# Comprueban si dos objetos son exactamente el mismo objeto en memoria.\n\n# Nuestras variables\na = 3\nb = 3\nc = 4\n\n# Impresión de resultados\nprint(a is b)               # True\nprint(a is not b)           # False\nprint( a is c)              # False\nprint( a is not c)          # True\n\n\n# 6. Operadores de Pertenencia \n\"\"\"\nEn: in\nNo en: not in\n\"\"\"\n# Comprueban si un valor está presente en una secuencia (como una lista, tupla o cadena)\n\nlista = [1, 2, 3, 4, 5]\nprint(3 in lista)           # True\nprint(15 not in lista)      # True\n\nstring = 'Hola, que tal'\nprint('que' in string)      # True\nprint('de' in string)       # False\nprint('Ho' in string)       # True\nprint('ho' in string)       # False, ya que distingue entre mayusc y minusc\n\n## 7. Operadores Bit a Bit\n# Realizan operaciones a nivel de bits sobre números enteros.\n\"\"\"\nOperadores bit a bit:\n&: Realiza una operación AND bit a bit, donde cada bit correspondiente se compara. \nSi ambos bits son 1, el resultado es 1; de lo contrario, es 0.\n\n|: Realiza una operación OR bit a bit. Si al menos uno de los bits correspondientes es 1, \nel resultado es 1.\n\n^: Realiza una operación XOR bit a bit. Si los bits correspondientes son diferentes, \nel resultado es 1; de lo contrario, es 0.\n\n~: Invierte todos los bits de un número.\n\n<<: Desplaza los bits hacia la izquierda, multiplicando el número por una potencia de 2.\n\n>>: Desplaza los bits hacia la derecha, dividiendo el número por una potencia de 2 (división entera).\n\"\"\"\n\n# variables de ejemplo\na = 5  # En binario: 0101\nb = 3  # En binario: 0011\n\n# AND bit a bit (&)\nc = a & b\nprint(c)  # Resultado: 1 (en binario: 0001)\n\n# OR bit a bit (|)\nd = a | b\nprint(d)  # Resultado: 7 (en binario: 0111)\n\n# XOR bit a bit (^)\ne = a ^ b\nprint(e)  # Resultado: 6 (en binario: 0110)\n\n# Complemento a dos (~)\nf = ~a\nprint(f)  # Resultado: -6 (el complemento a dos puede variar según la implementación)\n\n# Desplazamiento a la izquierda (<<)\ng = a << 2\nprint(g)  # Resultado: 20 (5 * 2^2)\n\n# Desplazamiento a la derecha (>>)\nh = a >> 1\nprint(h)  # Resultado: 2 (5 / 2^1, división entera)\n\n## 8. Operador de Concatenación:\n\"\"\"\n+: Une dos cadenas de texto para formar una cadena más larga.\n\"\"\"\n# Ejemplos\n\nmensaje = \"Hola, \" + \"mundo!\"\nprint(mensaje)  # Imprime: Hola, mundo!\n\nnombre = \"Juan\"\nsaludo = \"Bienvenido, \" + nombre + \"!\"\nprint(saludo)  # Imprime: Bienvenido, Juan!\n\n### Estructuras de Control ###\n\"\"\"\npermiten alterar el flujo normal de ejecución de un programa, \ntomando decisiones o repitiendo bloques de código\n\"\"\"\n\n## 1. Condicionales (if, elif, else)\n\"\"\"\nif: Se ejecuta un bloque de código si una condición es verdadera.\nelif: Se ejecuta si la condición anterior era falsa y esta nueva condición es verdadera.\nelse: Se ejecuta si ninguna de las condiciones anteriores era verdadera.\n\"\"\"\n\nedad = 18\n\nif edad < 18:\n  print(\"Eres menor de edad.\")\nelif edad == 18:\n  print(\"Acabas de cumplir la mayoría de edad.\")\nelse:\n  print(\"Eres mayor de edad.\")\n\n## 2. Iterativas\n\"\"\"\nfor: Se utiliza para iterar sobre una secuencia (lista, tupla, cadena, etc.).\nwhile: Se ejecuta un bloque de código mientras una condición sea verdadera.\n\"\"\"\n# Bucle for\nlista_de_frutas = [\"manzana\", \"banana\", \"cereza\"]\nfor fruta in lista_de_frutas:\n  print(fruta)\n\n# Bucle while\ncontador = 0\nwhile contador <= 5:\n  print(contador)\n  contador += 1\n\n\n## 3. Sentencia try-except\n\"\"\"\ntry: Intenta ejecutar un bloque de código.\nexcept: Captura y maneja excepciones (errores) que puedan ocurrir.\n\"\"\"\ntry:\n  numero = int(input(\"Ingrese un número: \"))\n  resultado = 10 / numero\n  print(resultado)\nexcept ZeroDivisionError:\n  print(\"No puedes dividir por cero.\")\nexcept ValueError:\n  print(\"Debes ingresar un número entero.\")\n\n## 4. Otras estructuras de control (opcional)\n\"\"\"\nbreak: Sale de un bucle.\ncontinue: Salta a la siguiente iteración de un bucle.\npass: Sirve como un marcador de posición para una sentencia que aún no se ha implementado.\n\"\"\"\n\n# break\nfor i in range(10):\n  if i == 5:\n    break\n  print(i)\n\n# continue\nfor i in range(10):\n  if i % 2 == 0:\n    continue\n  print(i)\n\n### DIFICULTAD EXTRA ###\n\"\"\"\nCreación de programa de python que imprime por consola todos los números \ncomprendidos entre 10 y 55 (incluidos estos), que sean solo pares, \ny que no son ni el 16 ni múltiplos de 3.\n\"\"\"\nfor numero in range(10, 56):  # Iteramos desde 10 hasta 55\n    if numero % 2 == 0 and numero != 16 and numero % 3 != 0:\n        print(numero)\n\n\"\"\"\nExplicación del código:\nfor numero in range(10, 56): Este bucle for itera sobre todos los números desde \n10 hasta 55 (56 no se incluye, así que llega hasta 55).\n\nif numero % 2 == 0 and numero != 16 and numero % 3 != 0: Esta condición verifica \ntres cosas en cada iteración:\n  numero % 2 == 0: Comprueba si el número es par (el resto de la división entre 2 es 0).\n  numero != 16: Verifica si el número es diferente de 16.\n  numero % 3 != 0: Comprueba si el número no es múltiplo de 3 \n  (el resto de la división entre 3 es diferente de 0).\n\nprint(numero): Si todas las condiciones se cumplen, se imprime el número.\n\"\"\""
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/franvozzi.py",
    "content": "# Operadores aritméticos\ndef suma(a, b):\n    result = a + b\n    print(\"El resultado de la suma es: \" + result)\n\ndef resta(a, b):\n    result = a - b\n    print(\"El resultado de la resta es: \" + result)\n\ndef multiplicacion(a, b):\n    result = a * b\n    print(\"El resultado de la multiplicación es: \" + result)\n    \ndef division(a, b):\n    result = a / b  # Corrección aquí: debe ser división en lugar de suma\n    print(\"El resultado de la división es: \" + result)\n\ndef modulo(a, b):\n    result = a % b\n    print(\"El resultado del modulo es: \" + result)\n    \ndef potencia(a, b):\n    result = a ** b\n    print(\"El resultado de la potencia es: \" + result)\n    \ndef divisionEntera(a, b):\n    result = a // b\n    print(\"El resultado de la división entera es: \" + result)\n    \n# Operadores Relacionales (devuelve True o False)\n\nprint(\"12 es mayor a 3? \" + str(12 > 3)) # Es mayor?\nprint(\"12 es menor a 3? \" + str(12 < 3)) # Es menor?\nprint(\"Tres es igual a tres? \" + str(3 == 3)) # Es igual?\nprint(\"Tres es lo mismo que 3? \" + str(\"3\" == 3)) # Tiene mismo operando?\nprint(\"3 es mayor o igual a 3.0000001? \" + str(3 >= 3.0000001)) # Es mayor o igual?\nprint(\"2.999999998 es menor o igual a 2.999999999? \" + str(2.999999998 <= 2.999999999)) # Es menor o igual?\nprint(\"2 es diferente a 1? \" + str(2 != 1)) # Es diferente?\n\n\n\n# Operadores Bit a Bit\ndef ANDFunction(a, b):\n    resultado = a & b\n    print(\"a AND b es:\" + str(resultado)) # imprime entero\n\ndef ORFunction(a, b):\n    resultado = a | b\n    print(\"a OR b es:\" + str(resultado)) # imprime entero\n\ndef XORFunction(a, b):\n    resultado = a ^ b\n    print(\"a XOR b es:\" + str(resultado)) # imprime entero\n    \ndef NOTFunction(a, b):\n    a = ~a\n    b = ~b\n    print(a) # imprime A\n    print(b)  # imprime B\n\n# Operadores lógicos (and, or y not)\na = True\nb = False\nprint(a or b) # Es True si al menos uno es verdadero\nprint(not a) # Invierte valor booleano\nprint(a and b) # Ambos deben ser el mismo valor booleano\n\n# Operadores de pertenencia (in y not in)\na = [1,2,3,4,5]\nprint(3 in a) # Se encuentra el 3 en el array \"a\"?\nprint(12 in a) # Se encuentra el 12 en \"a\"?\n\nfrase = \"Hola retos!\"\nprint(\"Hola\" in frase)\nprint(\"Mundo\" not in frase)\n\n# Condicionales\ndef esMayor(a, b):\n    if (a > b):\n        print (\"es mayor: \" + str(True))\n    else:\n        print (\"es mayor: \" + str(False))\n\nesMayor(5,4)\n\n# Iteraciones (Itera e imprime numeros del 1 al 10)\nfor numero in range (1, 11):\n    print(numero)\n    \n# DESAFIO EXTRA\nfor numero in range(10, 56):\n    if numero % 2 == 0:\n        if numero != 16 and numero % 3 != 0:\n            print(numero)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/franxiscodev.py",
    "content": "\"\"\"\nOPERADORES\n\"\"\"\n# Ariméticos\nprint(f\"Suma 5 + 5 =  {5+5}\")\nprint(f\"Resta 5 - 5 =  {5-5}\")\nprint(f\"Multiplicación 5 * 5 =  {5*5}\")\nprint(f\"División 6 / 5 =  {6/5}\")\nprint(f\"División entera 6 // 5 =  {6//5}\")\nprint(f\"Módulo 6 % 5 =  {6 % 5}\")\nprint(f\"Potencia 5 ** 5 =  {5**5}\")\n\n# Comparación\nprint(f\"Igualdad 5 == 5 =  {5 == 5}\")\nprint(f\"Diferencia 5 != 5 =  {5 != 5}\")\nprint(f\"Mayor que 5 > 5 =  {5 > 5}\")\nprint(f\"Menor que 5 < 5 =  {5 < 5}\")\nprint(f\"Mayor o igual que 5 >= 5 =  {5 >= 5}\")\nprint(f\"Menor o igual que 5 <= 5 =  {5 <= 5}\")\nprint(f\"Comparación múltiple 5 < 6 < 7 =  {5 < 6 < 7}\")\n\n# Lógicos\nprint(f\"And 5 == 5 and 5 == 5 =  {5 == 5 and 5 == 5}\")\nprint(f\"Or 5 == 5 or 5 == 5 =  {5 == 5 or 5 == 5}\")\nprint(f\"Not not 5 == 5 =  {not 5 == 5}\")\n\n# Asignación\nx = 5\nprint(f\"Asignación x = 5, x = {x}\")  # 5\nx += 5\nprint(f\"Asignación x += 5, x = {x}\")  # 10\nx -= 5\nprint(f\"Asignación x -= 5, x = {x}\")  # 5\nx *= 5\nprint(f\"Asignación x *= 5, x = {x}\")  # 25\nx /= 5\nprint(f\"Asignación x /= 5, x = {x}\")  # 5.0\nx //= 5\nprint(f\"Asignación x //= 5, x = {x}\")  # 1.0\nx %= 5\nprint(f\"Asignación x %= 5, x = {x}\")  # 1.0\nx **= 5\nprint(f\"Asignación x **= 5, x = {x}\")  # 1.0\n\n# Identidad - posición de memoria\nprint(f\"Identidad 5 is 5 =  {5 is 5}\")\nprint(f\"Identidad 5 is not 5 =  {5 is not 5}\")\nprint(f\"Identidad 5 is 5.0 =  {5 is 5.0}\")\nprint(f\"Identidad 5 is not 5.0 =  {5 is not 5.0}\")\n\n# Pertenencia\nprint(f\"Pertenencia 5 in [5, 6, 7] =  {5 in [5, 6, 7]}\")\nprint(f\"Pertenencia 5 not in [5, 6, 7] =  {5 not in [5, 6, 7]}\")\nprint(f\"Pertenencia 'x' in 'franxisco' =  {'x' in 'franxisco'}\")\nprint(f\"Pertenencia 'x' not in 'franxisco' =  {'x' not in 'franxisco'}\")\n\n# Bitwise\nprint(f\"Bitwise 5 & 5 =  {5 & 5}\")  # 5\nprint(f\"Bitwise 5 | 5 =  {5 | 5}\")  # 5     0101\nprint(f\"Bitwise 5 ^ 5 =  {5 ^ 5}\")  # 0\nprint(f\"Bitwise ~5 =  {~5}\")  # -6\nprint(f\"Bitwise 5 << 1 =  {5 << 1}\")  # 10\nprint(f\"Bitwise 5 >> 1 =  {5 >> 1}\")  # 2\n\n# estructuras de control\n# if    elif    else\nif 5 == 5:\n    print(\"5 es igual a 5\")\nelif 5 == 6:\n    print(\"5 es igual a 6\")\nelse:\n    print(\"5 no es igual a 5\")\n\n# iteración\n# while\ni = 0           # inicialización\nwhile i < 5:    # condición\n    print(i)\n    i += 1      # incremento\n\n\n# for\nfor i in range(5):\n    print(i)    # 0 1 2 3 4\n\n# for\nfor i in [5, 6, 7]:\n    print(i)    # 5 6 7\n\n# manejo de excepciones\ntry:\n    print(5/0)  # ZeroDivisionError\nexcept ZeroDivisionError as e:\n    print(e)\nfinally:\n    print(\"Final de le excepción\")  # siempre se ejecuta\n\n\"\"\"\nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\"\"\"\nfor i in range(10, 56):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print(i)    # 10 14 20 22 26 28 32 34 38 40 44 46 50 52\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/frostbitepy.py",
    "content": "#01 Roadmap\n\n\"\"\"\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\"\"\"\n\n\n# Aritméticos\na = 10\nb = 3\n\nsuma = a + b        # Suma\nresta = a - b       # Resta\nmultiplicacion = a * b  # Multiplicación\ndivision = a / b    # División\ndivision_entera = a // b  # División entera\nresto = a % b       # Resto\npotencia = a ** b   # Potencia\n\n\n# Comparación\nx = 5\ny = 10\n\nigual = x == y     # Igual a\ndiferente = x != y  # Diferente de\nmayor = x > y       # Mayor que\nmenor = x < y       # Menor que\nmayor_igual = x >= y   # Mayor o igual que\nmenor_igual = x <= y   # Menor o igual que\n\n\n# Asignación\na = 5\nb = 10\n\na += b     # a = a + b\na -= b     # a = a - b\na *= b     # a = a * b\na /= b     # a = a / b\na %= b     # a = a % b\na **= b    # a = a ** b\na //= b    # a = a // b\n\n\n# Identidad\nlista1 = [1, 2, 3]\nlista2 = [1, 2, 3]\n\nidentidad = lista1 is lista2     # Compara identidad de objetos\nno_identidad = lista1 is not lista2  # Compara no identidad de objetos\n\n# Pertenencia\nelemento_en_lista = 1 in lista1      # Comprueba si un elemento está en la lista\nelemento_no_en_lista = 4 not in lista1  # Comprueba si un elemento no está en la lista\n\n\n# Bits\nbitwise_and = 5 & 3     # AND a nivel de bits\nbitwise_or = 5 | 3      # OR a nivel de bits\nbitwise_xor = 5 ^ 3     # XOR a nivel de bits\nbitwise_not = ~5        # NOT a nivel de bits\nleft_shift = 5 << 1     # Desplazamiento a la izquierda\nright_shift = 5 >> 1    # Desplazamiento a la derecha\n\n\n\n# Estructura de control if\nnumero = 10\n\nif numero > 0:\n    print(\"El número es positivo.\")\nelif numero < 0:\n    print(\"El número es negativo.\")\nelse:\n    print(\"El número es cero.\")\n\n\n# Estructura de control for\nfor i in range(5):\n    print(\"Iteración:\", i)\n\n\n# Estructura de control try-except\ntry:\n    resultado = 10 / 2\nexcept ZeroDivisionError:\n    resultado = \"Error: División por cero.\"\nfinally:\n    print(\"Resultado:\", resultado)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/gabrielramos02.py",
    "content": "## 01 - OPERADORES Y ESTRUCTURA DE CONTROL\n\n# Operadores aritmeticos\nprint(2 + 3)  # Suma\nprint(2 - 3)  # Resta\nprint(1 / 2)  # Division\nprint(1 * 2)  # Multiplicacion\nprint(13 // 2)  # Division Entera\nprint(13 % 2)  # Resto de la division\nprint(12**2)  # Exponenciacion\n\n# Operadores de Comparacion\nprint(2 < 3)  # Menor que\nprint(2 <= 3)  # Menor o igual que\nprint(2 > 3)  # Mayor que\nprint(2 >= 3)  # Mayor o igual que\nprint(2 == 3)  # Igual a\nprint(2 != 3)  # Distinto de\n\n# Operadores Logicos\nprint(True and True)  # Operador and\nprint(True or False)  # Operador or\nprint(not False)  # Operador not\n\n# Condicionales\nprint(\"Condicionales\")\n#############################\nif True:\n    print(\"Condicional 'if'\")\n#############################\nif False:\n    pass\nelif True:\n    print(\"Condicional 'elif'\")\n#############################\nif False:\n    pass\nelif False:\n    pass\nelse:\n    print(\"Condicional 'else'\")\n\n# Estructuras Repetitivas\nfor i in range(5):\n    print(\"Esto es un 'for'\")\n#############################\nj = 0\nwhile j < 5:\n    print(\"Esto es un 'while'\")\n    j += 1\n\n# Excepciones\n    try:\n        division = 10 / 0\n    except ZeroDivisionError:\n        print(\"No se puede dividir por cero\")\n    else:\n        print(\"Division realizada\")\n    finally:\n        print(\"Bloque ejecutado al finalizar\")\n\n    \n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/garos01.py",
    "content": "# Operciones aritmeticas\na = 5\nb = 3\nsuma = a + b\nresta = a - b\nmultiplicacion = a * b\ndivision = a / b\nmodulo = a % b\npotencia = a**b\n\nprint(suma, resta, multiplicacion, division, modulo, potencia)\n\n\n# Operadores de comparación\nigual = a == b\ndiferente = a != b\nmayor_que = a > b\nmenor_que = a < b\n\n# Operadores lógicos\nand_logico = (a > b) and (a < 20)\nor_logico = (a < b) or (b > 0)\nnot_logico = not (a == b)\n\nprint(igual, diferente, mayor_que, menor_que, and_logico, or_logico, not_logico)\n\n\n# Operadores de asignacion\na = 5\na += 3  # equivalente a: a = a + 3\nprint(a)\n\n\nlista_1 = [1, 2, 3]\nlista_2 = [1, 2, 3]\n\n# Operadores de identidad\nidentidad = lista_1 is lista_2\nno_identidad = lista_1 is not lista_2\n\n# Operadores de pertenencia\npertenece = 1 in lista_1\nno_pertenece = 4 not in lista_1\n\nprint(identidad, no_identidad, pertenece, no_pertenece)\n\n\n# Operadores a nivel de bits\na = 5\nb = 3\n\nbitwise_and = a & b\nbitwise_or = a | b\nbitwise_xor = a ^ b\nbitwise_not_a = ~a\nleft_shift = a << 1\nright_shift = a >> 1\n\nprint(bitwise_and, bitwise_or, bitwise_xor, bitwise_not_a, left_shift, right_shift)\n\n# Estructuras de control\n# Condicionales\nedad = 18\n\nif edad >= 18:\n    print(\"Eres mayor de edad\")\nelse:\n    print(\"Eres menor de edad\")\n\n# Iterativas\nfor i in range(5):\n    print(i)\n\nwhile edad < 21:\n    print(\"Eres menor de 21 años\")\n    edad += 1\n\n# Excepciones\ntry:\n    resultado = 10 / 0\nexcept ZeroDivisionError:\n    print(\"Error: División por cero\")\nfinally:\n    print(\"Este bloque se ejecuta siempre\")\n\n# Ejercicio extra\n\nlista_a = []\n\nfor i in range(10, 55):\n    if i % 2 == 0:\n        lista_a.append(i)\n        if i % 3 == 0:\n            lista_a.remove(i)\n        elif i == 16:\n            lista_a.remove(i)\n\nprint(lista_a)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/ggilperez.py",
    "content": "\"\"\"\nOperators\n\"\"\"\n\n# Arithmetic\nprint(\"Arithmetic\")\nprint(f\"Sum {1+2 = }\")\nprint(f\"Sub {2-3 = }\")\nprint(f\"Mul {3*4 = }\")\nprint(f\"Div {4/5 = }\")\nprint(f\"Div int {5//6 = }\")\nprint(f\"Exp {6**7 = }\")\nprint(f\"Mod {7%8 = }\")\nprint()\n\n# Comparison\nprint(\"Comparison\")\nprint(f\"Equality {1 == 2 = }\")\nprint(f\"Inequality {2 != 3 = }\")\nprint(f\"Greater than {3 > 4 = }\")\nprint(f\"Less than {4 < 5 = }\")\nprint(f\"Greater or equal {5 >= 6 = }\")\nprint(f\"Less or equal {6 <= 7 = }\")\nprint()\n\n# Logical\nprint(\"Logical\")\nprint(f\"AND {1 + 2 == 3 and 4 - 5 == -1 = }\")\nprint(f\"OR {1 + 2 == 3 or 4 - 5 == 6 = }\")\nprint(f\"NOT {not 1 + 2 == 3 = }\")\nprint()\n\n# Assignment\nprint(\"Assignment\")\nmy_int = 0\nprint(f\"my_int = 0 => {my_int}\")\nmy_int += 1\nprint(f\"my_int += 1 => {my_int}\")\nmy_int -= 2\nprint(f\"my_int -= 2 => {my_int}\")\nmy_int *= 3\nprint(f\"my_int *= 3 => {my_int}\")\nmy_int /= 4\nprint(f\"my_int /= 4 => {my_int}\")\nmy_int //= 5\nprint(f\"my_int //= 5 => {my_int}\")\nmy_int **= 6\nprint(f\"my_int **= 6 => {my_int}\")\nmy_int %= 7\nprint(f\"my_int %= 7 => {my_int}\")\nprint()\n\n# Identity\nprint(\"Identity\")\naux_int = my_int\nprint(f\"{my_int is aux_int = }\")\nprint(f\"{my_int is not aux_int = }\")\nprint()\n\n# Containment\nprint(\"Containment\")\nprint(f\"{'y' in 'python' = }\")\nprint(f\"{'a' in 'python' = }\")\nprint(f\"{'y' not in 'python' = }\")\nprint(f\"{'a' not in 'python' = }\")\nprint()\n\n# Bitwise\nprint(\"Bitwise\")\na = 10  # 1010\nb = 3  # 0011\nprint(f\"AND {10 & 3 = }\")\nprint(f\"OR {10 | 3 = }\")\nprint(f\"XOR {10 ^ 3 = }\")\nprint(f\"NOT {~10 = }\")\nprint(f\"Right Shift {10 >> 2 = }\")  # 0010\nprint(f\"Left Shift {10 << 2 = }\")  # 101000\nprint()\n\n\"\"\"\nCompound statements\n\"\"\"\n\n# Conditional\nprint(\"Conditional\")\nmy_int = 3\n\nif my_int % 2 == 0:\n    print(\"my_int is even\")\nelif my_int == 0:\n    print(\"can't check, 0 given\")\nelse:\n    print(\"my_int is odd\")\nprint()\n\n# Iterative\nprint(\"Iterative\")\nfor i in range(5):\n    print(i)\n\ni = 0\nwhile i <= 5:\n    print(i)\n    i += 1\nprint()\n\n# Exceptions management\nprint(\"Exceptions\")\ntry:\n    print(10 / 0)\nexcept ZeroDivisionError:\n    print(\"Division by 0\")\nelse:\n    print(\"All OK\")\nfinally:\n    print(\"Finishing\")\nprint()\n\n# Extra\nprint(\"Extra\")\nprint([number for number in range(10, 56) if number % 2 == 0 and number != 16 and number % 3 != 0])\nprint()\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/giulianovfz.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\"\"\"\n\n# ejemplos operadores aritmeticos\na = 5\nb = 3\n\nprint(f'suma a={a} b={b} a + b = {a+b}')\nprint(f'resta a={a} b={b} a - b = {a-b}')\nprint(f'multiplicación a={a} b={b} a * b = {a*b}')\nprint(f'división a={a} b={b} a / b = {a/b}')\nprint(f'módulo a={a} b={b} a % b = {a % b}')\nprint(f'División entera a={a} b={b} a // b = {a // b}')\n\n# ejemplos operadores lógicos\n\nc = 8\n\n# and\nif c > 5 and c < 11:\n    print(f'Valor de c:{c}, c < 5 = {c > 5}, c < 11 = {c < 11}')\n\n# or\nif c < 5 or c < 11:\n    print(f'Valor de c:{c}, c < 5 = {c < 5}, c < 11 = {c < 11}')\n\n# not\nif not (c < 5 and c < 11):\n    print(f'Valor de c:{c}, not(c < 5 = {c < 5} and c < 11 = {\n          c < 11}) = {not (c < 5 and c < 11)}')\n\n\n# ejemplos de comparación\n\nx = 7\ny = 15\nz = 3\n# == igual a\nif x == 7:\n    print(f'El valor de x = {x}')\n\n# != distinto de\nif x != 10:\n    print(f'El valor de x = {x}')\n\n# > mayor que\nif x > z:\n    print(f'x={x},z={z} x > z = {x > z}')\n\n# < menor que\nif x < y:\n    print(f'x={x},y={y} x < y = {x < y}')\n\n# >= menor o igual que\nif x >= 7:\n    print(f'x={x} x >= 7 = {x >= 7}')\n\n# <= mayor o igual que\nif y <= 16:\n    print(f'x={x} x >= 7 = {x <= 7}')\n\n# ejemplo asignación\n\nh = 7\nprint(f'h = {h}')\n\nh += 4\nprint(f'h = h + 4 → h += 4: {h}')\n\nh -= 4\nprint(f'h = h - 4 → h -= 4: {h}')\n\nh *= 4\nprint(f'h = h * 4 → h *= 4: {h}')\n\nh = 8\nh /= 4\nprint(f'División, h = h / 4 → h /= 4: {h}')\n\nh = 8\nh %= 4\nprint(f'Módulo, h = h % 4 → h %= 4: {h}')\n\nh = 8\nh //= 4\nprint(f'División entera, h = h // 4 → h //= 4: {h}')\n\nh = 8\nh **= 4\nprint(f'Exponente, h = h ** 4 → h **= 4: {h}')\n\nh = 8\nh &= 4\nprint(f\"\"\"\\n\\toperador and comparador de bit a bit, El operador & compara cada bit\n      y lo establece en 1 si ambos son 1, de lo contrario se establece en 0. El resultado\n      binario lo convierte a decimal y este valor es retornado, por ejemplo\n\n        8 = 1000\n        4 = 0100\n        ----------\n            0000 → en decimal: 0\n\n       h = h & 4 → h &= 4: {h}\"\"\")\n\nh = 8\nh |= 4\nprint(f\"\"\"\\n\\toperador or:| comparador de bit a bit, El operador | compara cada bit\n      y lo establece en 1 si uno o ambos son 1; de lo contrario, se establece en 0,\n      El resultado binario lo convierte a decimal y este valor es retornado, por ejemplo\n\n        8 = 1000\n        4 = 0100\n        ----------\n            1100 → en decimal: 12\n\n       h = h | 4 → h |= 4: {h}\"\"\")\n\nh = 6\nh ^= 3\nprint(f\"\"\"\\n\\toperador xor:^ comparador de bit a bit, El operador ^ compara cada bit\n      y lo establece en 1 si solo uno es 1; de lo contrario (si ambos son 1 o ambos son 0)\n      se establece en 0, El resultado binario lo convierte a decimal y este valor es\n      retornado, por ejemplo\n\n        6 = 0110\n        3 = 0011\n        ----------\n            0101 → en decimal: 5\n\n       h = h ^ 3 → h ^= 3: {h}\"\"\")\n\nh = 6\nh1 = -7\nprint(f\"\"\"\\n\\toperador not:~ comparador de bit a bit, El operador ~ invierte cada bit\n      (0 se convierte en 1 y 1 se convierte en 0), El resultado binario lo convierte\n      a decimal y este valor es retornado, por ejemplo\n\n                         6 → 0110\n                             ↓↓↓↓\n        invierto los bits   -1001\n                             ↓↓↓↓\n        invertir nuevamente -0110\n                             +  1\n                           ----------\n                            -0111 → en decimal: -7\n      para simplificarlo puede decir el binario le sumo y al transformarlo a decimal se\n      le coloca el signo negativo primero, siempre y cuando el número sea positivo.\n\n      vale decir 6 → 0110\n                     +  1\n                    ------\n                    -0111 → en decimal: -7\n\n       h = 6 → ~h : {~h}\n\n      si el número es negativo tengo que hacer el complemento a 1 mencionado ateriormente,\n      esto quiere decir convertir los ceros en unos y los unos en cero, sumarle uno y luego\n      convertir nuevamente el binario.\n      ejemplo:\n\n                -7 →  -(0111)\n                        ↓↓↓↓\n      se convierte   -(-1000)\n      se le suma 1    (+   1)\n                    ---------\n                       (1001)\n      se convierte      ↓↓↓↓\n                       (0110) en decimal: 6\n\n        h1 = -7 → ~h1 : {~h1}\n        \"\"\")\n\n\n# Operadores de Pertenencia\n\n# in\ng = [\"booleano\", \"enteros\", \"flotantes\"]\n\nprint(f\"\"\"\\nflotantes se encuentra en g(\"flotantes\" in g): {\n      \"flotantes\" in g}\\n\"\"\")\n\n# not in\nprint(f\"\"\"\\nstrings no se encuentra en g(\"strings\" not in g): {\n      \"strings\" not in g}\\n\"\"\")\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/gjbecerrae.py",
    "content": "a = 3\nb = 4\nenabler = True\n#numero 8 en decimal\nbitNumber = '1000'\n\nwhile True:\n    try:\n        bitNumber = int(input(\"ingresa un numero \"))\n        a = int(input(\"ingresa un numero a \"))\n        b = int(input(\"ingresa un numero b \"))\n        break\n    except ValueError:\n        print(\"Oops!  That was no valid number.  Try again...\")\n\nif a > b:\n    print('a es mayor que b')\nelif a < b:\n    print('a es menor que b')\nelse:\n    print('a es igual a b')\n\nfor i in range (0,b):\n    print(f'Esta es la iteracion {i}')\n    print('si multiplicamos por 3 la iteracion tenemos:', 3*i)\nprint(bitNumber >> 1)\n\n#ntbitNumber >> 1 se desplaza 1 bit a la derecha y se compara con 4. 1000(8)  se convierte en 0100(4)\nif bitNumber >> 1 > 4 :\n    print ('bitnumber es mayor que 8')\nelif bitNumber >> 1 < 4:\n    print ('bitnumber era menor a 8')\nelse:    \n    print ('bitnumber era 8 o 9')\n\nprint('\\n Ejercicio opcional \\n')\nfor i in range (10,56):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print (i)\n    elif i == 55:\n        print (i)\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/gmbarrios.py",
    "content": "# Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje: aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n\n# 1. Aritméticos\na = 8\nb = 3\n\nsuma = a + b\nresta = a - b\nmultiplicación = a * b\ndivision = a / b\ndivision_entera = a // b\nmodulo = a % b\nexponente = a ** b\n\nprint(f\"Suma: {suma}\")\nprint(f\"Resta: {resta}\")\nprint(f\"Multiplicacion: {multiplicación}\")\nprint(f\"Division: {division}\")\nprint(f\"Division entera: {division_entera}\")\nprint(f\"Modulo: {modulo}\")\nprint(f\"Exponente: {exponente}\")\n\n\n# 2. De comparación\nc = 10\nd = 15\n\nmayor_que = d > c\nmenor_que = c < d\nmayor_igual = c >= d\nmenor_igual = d <= c\nigual = c == d\nno_igual = c != d\n\nprint(f\"Mayor que: {mayor_que}\")\nprint(f\"Menor que: {menor_que}\")\nprint(f\"Mayor o igual que: {mayor_igual}\")\nprint(f\"Menor o igual que: {menor_igual}\")\nprint(f\"Igual: {igual}\")\nprint(f\"No es igual: {no_igual}\")\n\n\n# 3. Lógicos\nx = True\ny = False\n\nand_result = x and y\nor_result = x or y\nnot_result = not x\n\nprint(f\"AND: {and_result}\")\nprint(f\"OR: {or_result}\")\nprint(f\"NOT: {not_result}\")\n\n\n# 4. Asignación\ne = 10\ne += 2\ne -= 2\ne *= 2\ne /= 3\ne //= 3\ne %= 3\ne **= 2\n\nprint(f\"Asignación de 'e' tomando el ultimo valor: {e}\")\n\n\n# 5. Identidad\nf = [1, 2, 3, 4, 5]\ng = [6, 7, 8, 9]\nh = f\n\nidentidad = f is g\nidentidad2 = f is h\nidentidad3 = g is not h\nprint(identidad)\nprint(identidad2)\nprint(identidad3)\n\n\n# 6. Pertenencia\nmi_lista = [1, 2, 3, 4, 5, 6]\n\npertenencia = 3 in mi_lista\npertenencia2 = 9 not in mi_lista\npertenencia3 = 1 not in mi_lista\n\nprint(pertenencia)\nprint(pertenencia2)\nprint(pertenencia3)\n\n\n# 7. Bits\na = 2\nb = 5\n\nbitwise_and = a & b\nbitwise_or = a | b\nbitwise_xor = a ^ b\nbitwise_not = ~a\nbitwise_left_shift = a << 2\nbitwise_right_shift = a >> 1\n\nprint(f\"Bitwise AND: {bitwise_and}\")\nprint(f\"Bitwise OR: {bitwise_or}\")\nprint(f\"Bitwise XOR: {bitwise_xor}\")\nprint(f\"Bitwise NOT: {bitwise_not}\")\nprint(f\"Bitwise Left Shift: {bitwise_left_shift}\")\nprint(f\"Bitwise Right Shift: {bitwise_right_shift}\")\n\n\n# Utilizando las operaciones con operadores que quieras, crea ejemplos que representen todos los tipos de estructuras de control que existan en tu lenguaje: condicionales, iterativas, excepciones...\n\n# Condicionales\na = 15\n\nif a > 20:\n    print(f\"{a} es mayor que 20\")\nelif a == 20:\n    print(f\"{a} es igual a 20\")\nelse:\n    print(f\"{a} es menor que 20\")\n\n\n# Iterativas\nfor sequence in range(10):\n    print(sequence)\n\nnumber = 5\nwhile number < 10 and number > 1:\n    print(number)\n    number += 1\n\n\n# Excepciones\ntry:\n    result = 5 / 0\nexcept ZeroDivisionError:\n    print(\"No puede dividirse por cero\")\nfinally:\n    print(\"Este bloque siempre se ejecutará\")\n\n# DIFICULTAD EXTRA (opcional):\n# Crea un programa que imprima por consola todos los números comprendidos entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\nfor number in range(10, 56):\n    if number % 2 == 0 and number != 16 and number % 3 != 0:\n        print(number)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/gmigues.py",
    "content": "#01\n# OPERADORES Y ESTRUCTURAS DE CONTROL\n# /*\n#  * EJERCICIO:\n#  * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n#  *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n#  *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n#  * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n#  *   que representen todos los tipos de estructuras de control que existan\n#  *   en tu lenguaje:\n#  *   Condicionales, iterativas, excepciones...\n#  * - Debes hacer print por consola del resultado de todos los ejemplos.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea un programa que imprima por consola todos los números comprendidos\n#  * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n#  *\n#  * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n#  */\n\n\n\nnum_a = 10\nnum_b = 5\n\nsuma = num_a + num_b\nresta = num_a - num_b\nmultiplicacion = num_a * num_b\ndivision = num_a / num_b\n\n\nprint('Los numeros son: ' + str(num_a) + ' y ' + str(num_b))\nprint('Este es el resultado de la suma: ' + str(suma ))\nprint('Este es el resultado de la resta: ' + str(resta ))\nprint('Este es el resultado de la multiplicacion: ' + str(multiplicacion ))\nprint('Este es el resultado de la division: ' + str(division ))\nprint()\nprint('######################################')\nprint()\n\n\nif num_a > num_b:\n    print('el número ' + str(num_a) + ' es mayor que el número ' + str(num_b))\nelif num_b > num_a:\n    print('el número ' + str(num_b) + ' es mayor que el número ' + str(num_a))\nelif num_a == num_b:\n    print('los números son iguales')\nelse:\n    print('los números no son correctos')\n\nprint()\nprint('######################################')\nprint()\n\nfor i in range(1,10):\n    if num_b < num_a:\n        print(num_b)\n        num_b = num_b + 1\n    else:\n        break\n\nprint()\nprint('######################################')\nprint()\n\ncontador = 1\n\nwhile contador < 10:\n    print(contador)\n    contador = contador + 1\n\nprint()\nprint('######################################')\nprint()\nprint('######################################')\n\ny = 10\nz = 0\n\ntry:\n    x = y / z\n    print(f'La división entre {y} y {z} es igual a {x}')\nexcept:\n    print(\"Error.\")\n\nprint()\nprint('######################################')\nprint()\nprint('######################################')\n\n\npython = True\ngo = False\n\nresultado_and = python and go\nresultado_or = python or go\nresultado_not = not go\n\nprint(\"AND: estudiando Python Y go?: \", resultado_and) # Ambas tienen que ser True\nprint(\"OR: estudiando Python O go? \", resultado_or)   # Una de las dos tiene que ser True\nprint(\"NOT: Estudiando solo python? \", resultado_not) # Opuesto al valor \n\n\nprint()\nprint('######################################')\nprint()\nprint('######################################')\nprint('EXTRA')\nprint('######################################')\n\nfor i in range(10,56):\n    if i == 16:\n        continue\n    elif i % 3 == 0:\n        continue\n    elif i % 2 == 0:\n        print(i)\n    else:\n        continue\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/gonzadev28.py",
    "content": "\n#Operadores aritmeticos \nnum1 = 11\nnum2 = 3 \n\n#Suma\nsuma = num1 + num2\n#Resta\nresta = num1 - num2\n#Multiplicacion \nmulti = num1 * num2\n#Division \ndivision = num1 / num2\n#Modulo o resto\nmodulo = num1 % num2\n#Potencia\npotencia = num1 ** num2\n#Division con numeros enteros\ndivision_entera = num1 // num2\n\nprint(\"Los resultados son:\", suma, resta, multi, division, modulo, potencia, division_entera)\n\n#Operadores logicos \nestudiante = True \nprogramador = True \n\nprint(\"Operador AND:\", estudiante and programador) #Ambas condiciones se deben cumplir\nprint(\"Operador OR\", estudiante, programador) #Al menos unas de las condiciones se debe cumplir\nprint(\"Operador NOT\", not estudiante) # Invierte el valor (de true a false en este caso)\n\n#Operadores de comparacion\nprint(\"Mayor que\", num1 > num2)\nprint(\"Menor que\", num1 < num2)\nprint(\"Mayor o igual que\", num1 >= num2)\nprint(\"Menor o igual que\", num1 <= num2)\nprint(\"Igual que\", num1 == num2)\nprint(\"Distinto que\", num1 != num2)\n\n#Operadores de asignacion\nmi_nuevo_numero = 7 # asigancion\nprint(mi_nuevo_numero)\nmi_nuevo_numero += 1 #suma y asignacion\nprint(mi_nuevo_numero)\nmi_nuevo_numero -=1 #resta y asignacion\nprint(mi_nuevo_numero)\nmi_nuevo_numero *=2 #multiplicacion y asignacion\nprint(mi_nuevo_numero)\nmi_nuevo_numero /= 2 #division y asignacion\nprint(mi_nuevo_numero)\nmi_nuevo_numero %= 2 #modulo y asignacion\nprint(mi_nuevo_numero)\nmi_nuevo_numero **= 2 #potencia y asignacion\nprint(mi_nuevo_numero)\nmi_nuevo_numero //= 2 #division entera y asignacion\nprint(mi_nuevo_numero)\n\n#Operadores de identidad\n\nn1 = 93\nn2 = 93 \nprint(n1 is n2) #True porque ambas variables hacen referencia al mismo objeto\nprint(n1 is not n2) #False \n\n#Operadores de pertencia \nmensaje = \"Aprendiendo Python\"\nprint(mensaje in \"Aprendiendo Python\")\nprint(mensaje not in \"Aprendiendo Java\")\n\n#Operadores de bits\nbinario1 = 5 #0101 \nbinario2 = 7 #0111\nprint(\"AND: \", binario1 & binario2) #Compara si ambos bits contiene \"1\" en la misma posicion = 0101 --> 5\nprint(\"OR: \", binario1 | binario2) #Compara si al menos 1 de los bits es \"1\" en la misma posicion = 0111 --> 7\nprint(\"XOR: \", binario1 ^ binario2) #Si el bit es igual en la misma posicion es \"0\" sino es \"1\" = 0010 --> 2\n\n#Condicionales\n\nmi_entero = 19\n\nif mi_entero == 20:\n    print (\"Se cumple la condicion del if\")\nelif mi_entero == 18:\n    print(\"Se cumple la condicion del elif\")\nelse:\n    print(\"Ahora si se cumple la condicion\")\n\n# Imprime del 1 al 20 con un ciclo \"while\"\ni = 1\nwhile i <= 20:\n    print(i)\n    i += 1\n\n# Imprime del 1 al 10 con un ciclo \"for\"\nfor i in range (1, 11):\n    print(i)\n\n\"\"\"DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\"\"\"\n\nfor numero in range(10, 56):\n    if numero % 2 == 0 and numero != 16 and numero % 3 != 0:\n        print(numero)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/gregfc95.py",
    "content": "\"\"\" \n* Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n\"\"\"\n# *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n\n# Variables\nx = 12\ny = 3\nz = 5\n\n#Operadores Aritmeticos\nprint(f\"Sumando 12 + 5 = {x+z}\")\nprint(f\"Restando 12 - 5 = {x-z}\")\nprint(f\"Multiplicando 12 * 5 = {x*z}\")\nprint(f\"Dividiendo 12/5 {x/y}\")\nprint(f\"Modulo 12%5 {x%y}\")\nprint(f\"Dividiendo con rendondeo 12/5 {x//y}\")\nprint(f\"Expontente 12^5 {x**y}\")\n\n#Operadores Comparacion\n\nprint(f\"igualdad 2 == 3 { 3 == 3}\")\nprint(f\"No igual 2 != 3  {2 != 3}\")\nprint(f\"Mayor que 2 > 3 {2 > 3}\")\nprint(f\"menor que 2 < 3 {2 < 3}\")\nprint(f\"mayor igual que 2 >= 3 {2 >= 3}\")\nprint(f\"menor igual que 2 <= 3 {2 <= 3}\")\n\n#Python Logical Operators\nprint(f\"And &&: 2 == 3 and 5 == 5 { 2 == 3 and 5 == 5}\")\nprint(f\"or ||: 2 == 3 or 5 == 5 { 2 == 3 or 5 == 5}\")\nprint(f\"not negacion !: 2 + 3 and 5 == 5 { not 2 + 3 == 5}\")\n\n#Python operador de precedencia\nprint(f\"() parentesis (((2 + 3) * 5) - 1) { (((2 + 3) * 5) - 1)}\")\n\n#Python operador de identidad\n#Compara el valor de la posicion de memoria, si es igual (is) si no lo es (is not)\nposA = 3\nposB = posA\nprint(f\"Si posA, la (posA) de mem. is (posB), return false { posA is posB }\")\nprint(f\"Si posA, la (posA) de mem. is not (posB), return false { posA is not posB }\")\n\n\n#Python Mermership o de conjuntos, recordar diagrama de Venn\nprint(f\"'o' in 'jose' { 'o' in 'jose' }\")\nprint(f\"'o' not in 'jose' { 'o' not in 'jose' }\")\n\n#Python Operadores de asignacion\nvalorA = 55 #Asignacion\nprint(valorA)\nvalorA += 1 #Suma y asignacion\nprint(valorA)\nvalorA -=1 #Resta y asignacion\nprint(valorA)\nvalorA *=1 #Mult. y asignacion  \nprint(valorA)\nvalorA /= 1 #Division y asignacion\nprint(valorA)\nvalorA %= 2 # Resto y asginacion\nprint(valorA)\nvalorA //= 2 # Division Redondeada y asiginacion\nprint(valorA)\nvalorA **= 2 # Exponente y asginacion\nprint(valorA)\nvalorA = 10\nvalorA &= 1 # And en bit y asignacion\nprint(valorA)\nvalorA |= 1 # OR en bit y asignacion\nprint(valorA)\nvalorA ^= 1 # XOR en bit y asignacion 0 0 = 0, 1 1 = 0\nprint(valorA) \nvalorA >>= 1 # Desplazamiento a la derecha en bit y asignacion 0 0 = 0, 1 1 = 0\nprint(valorA)\nvalorA <<= 1 # Desplazamiento a la izq en bit y asignacion 0 0 = 0, 1 1 = 0\nprint(valorA)  \n\n#Python Operadores de bit\na = 10 # 1010\nb = 3 # 0011\nprint(f\"AND: 10 & 3 = {a & b}\")\nprint(f\"OR: 10 | 3 = {a | b}\")\nprint(f\"XOR: 10 ^ 3 = {a ^ b}\")\nprint(f\"NOT: 10 = {~a}\")\nprint(f\"Desplazacion a la izq 10 << 2 = {a<<2}\")\nprint(f\">>Desplazamiento a la derecha 10 >> 2 = {a>>2}\")\n\n\n#Ejercicio\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\"\"\"\n\nnumero = 0\n\nfor numero in range(10, 56, 2):\n    if ((numero != 16) and (numero % 3 != 0)):\n         print(numero)\n        "
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/guillermo-k.py",
    "content": "'''Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)'''\n\n# -------ARITMÉTICOS-----------\nnum1 = 5\nnum2 = 4\n\n# SUMA (+)\nsuma = num1 + num2\nprint(\"SUMA\")\nprint(num1,\"+\",num2,\"=\",suma)\nprint(\"----\")\n\n# RESTA (-)\nresta = num2 - num1\nprint(\"RESTA\")\nprint(num1,\"-\",num2,\"=\",resta)\nprint(\"----\")\n\n# MULTIPLICACIÓN (*)\nmulti = num1 * num2\nprint(\"MULTIPLICACIÓN\")\nprint(num1,\"*\",num2,\"=\",multi)\nprint(\"----\")\n\n# DIVISIÓN (/)\ndivision = num1 / num2\nprint(\"DIVISIÓN\")\nprint(num1,\"/\",num2,\"=\",division)\nprint(\"----\")\n\n\n# DIVISION ENTERA (//)\ndivision_entera = num1 // num2\nprint('DIVISION ENTERA')\nprint(num1,'//',num2,'=',division_entera)\nprint('----')\n\n\n# MODULO (%)\nmodulo = num1 % num2\nprint('MODULO')\nprint(num1,'%',num2,'=',modulo)\nprint('----')\n\n\n# POTENCIACIÓN (**)\npotencia = num1 ** num2\nprint('POTENCIACIÓN')\nprint(num1,'**',num2,'=',potencia)\nprint('----')\n\n\n\n\n\n\n\n# -------LÓGICOS-----------\nverdadero = True\nfalso = False\n\n# AND (and)\nprint(\"AND\")\nprint(\"Verdadero AND falso =\",verdadero and falso )\n\n\n# OR (or)\nprint(\"OR\")\nprint(\"Verdadero OR falso =\",verdadero or falso )\n\n\n# NOT (not)\nprint(\"NOT\")\nprint(\"NOT Verdadero =\",not verdadero )\n\n\n\n\n# -------DE COMPARACIÓN-----------\n\n\n# MAYOR QUE (>)\nmayor_que = num1 > num2\nprint('MAYOR QUE')\nprint(num1,'>',num2,'=',mayor_que)\nprint('----')\n\n# MENOR QUE (<)\nmenor_que = num1 < num2\nprint('MENOR QUE')\nprint(num1,'<',num2,'=',menor_que)\nprint('----')\n\n# IGUAL QUE (==)\nigual_que = num1 == num2\nprint('IGUAL QUE')\nprint(num1,'==',num2,'=',igual_que)\nprint('----')\n\n# MAYOR O IGUAL QUE (>=)\nmayor_igual_que = num1 >= num2\nprint('MAYOR O IGUAL QUE')\nprint(num1,'>=',num2,'=',mayor_igual_que)\nprint('----')\n\n# MENOR O IGUAL QUE (<=)\nmenor_igual_que = num1 <= num2\nprint('MENOR O IGUAL QUE')\nprint(num1,'<=',num2,'=',menor_igual_que)\nprint('----')\n\n# DESIGUAL A (!=)\ndesigual = num1 != num2\nprint('DESIGUAL A')\nprint(num1,'!=',num2,'=',desigual)\nprint('----')\n\n\n# -------DE ASIGNACIÓN-----------\n\n# ARITMÉTICOS\n\n# ASIGNACION DIRECTA (=)\nvariable = num1 \nprint('ASIGNACION DIRECTA')\nprint('Variable =',variable)\nprint('----')\n\n# INCREMENTAR (+=)\nvariable += num2\nprint('INCREMENTAR')\nprint('Variable += num1 =',variable)\nprint('----')\n\n# DECREMENTAR (-=)\nvariable -= num2\nprint('DECREMENTAR')\nprint('Variable -= num2 =',variable)\nprint('----')\n\n# MULTIPLICAR (*=)\nvariable *= num2\nprint('MULTIPLICAR')\nprint('Variable *= num2 =',variable)\nprint('----')\n\n# DIVIDIR (/=)\nvariable /= num1\nprint('DIVIDIR')\nprint('variable /= num1 =',variable)\nprint('----')\n\n# DIVIDIR ENTERO (//=)\nvariable //= 2\nprint('DIVIDIR ENTERO')\nprint('variable //= 2 =',variable)\nprint('----')\n\n# MODULO (%=)\nvariable %= num2\nprint('MODULO')\nprint('variable %= num2 =',variable)\nprint('----')\n\n# POTENCIACIÓN (**=)\nvariable **= num2\nprint('POTENCIACIÓN')\nprint('variable **= num2 =',variable)\nprint('----')\n\n# LÓGICOS BIT A BIT\n\n# AND B a B (&=)\nvariable = num1\nvariable &= num2\nprint('AND B a B')\nprint(num1,'&=',num2,'=',variable)\nprint('----')\n\n# OR BaB (|=)\nvariable = num1\nvariable |= num2\nprint('OR BaB')\nprint(num1,'|=',num2,'=',variable)\nprint('----')\n\n# XOR BaB (^=)\nvariable = num1\nvariable ^= num2\nprint('XOR BaB')\nprint(num1,'^=',num2,'=',variable)\nprint('----')\n\n# DESPLAZAMIENTO A LA DERECHA BaB (>>=)\nvariable = num1\nvariable >>= num2\nprint('DESPLAZAMIENTO A LA DERECHA BaB')\nprint(num1,'>>=',num2,'=',variable)\nprint('----')\n\n# DESPLAZAMIENTO A LA IZQUIERDA BaB (<<=)\nvariable = num1\nvariable <<= num2\nprint('DESPLAZAMIENTO A LA IZQUIERDA BaB')\nprint(num1,'<<=',num2,'=',variable)\nprint('----')\n\n\n# -------DE IDENTIDAD-----------\n\n# ES (is)\nvariable = num1 is num2\nprint('ES')\nprint(num1,'is',num2,'=',variable)\nprint('----')\n\n# NO ES (is not)\nvariable = num1 is not num2\nprint('NO ES')\nprint(num1,'is not',num2,'=',variable)\nprint('----')\n\n\n# -------DE PERTENENCIA-----------\nlista = [i for i in range(10)]\n\n# EN (in)\nvariable = num1 in lista\nprint('EN')\nprint(num1,'in',lista,'=',variable)\nprint('----')\n\n# NO EN (not in)\nvariable = num1 not in lista\nprint('NO EN')\nprint(num1,'not in',lista,'=',variable)\nprint('----')\n\n\n# -------DE BITS-----------\n    # ----LÓGICOS----\n\n# AND (&)\nprint(\"AND\")\nprint(\"Verdadero AND falso =\",verdadero & falso )\nprint('----')\n\n\n# OR (|)\nprint(\"OR\")\nprint(\"Verdadero OR falso =\",verdadero | falso )\nprint('----')\n\n\n# XOR (^)\nprint(\"XOR\")\nprint(\"Verdadero XOR falso =\",verdadero ^ verdadero )\nprint('----')\n\n\n# NOT (~)\nprint(\"NOT\")\nprint(\"NOT Verdadero =\", ~verdadero )\nprint('----')\n\n    # ----DE DESPLAZAMIENTO----\nnum1_bin = 0b100100\n\n# A LA IZQUIERDA(<<)\nprint('A LA IZQUIERDA')\nprint('Num1_b(',bin(num1_bin),') << 3 =',bin(num1_bin << 3))\nprint('----')\n\n# A LA DERECHA(>>)\nprint('A LA DERECHA')\nprint('Num1_b(',bin(num1_bin),') >> 2 =',bin(num1_bin >> 2))\nprint('----')\n\n\n\n\n# -------ASIGNACIÓN EN EJECUCIÓN-----------\n\n# WALRUS (:=)\nif (variable := num2)==num2:\n    print('WALRUS')\n    print(num2,variable)\n\n\n'''- Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n  que representen todos los tipos de estructuras de control que existan  en tu lenguaje:\n  Condicionales, iterativas, excepciones...'''\n\n# -------CONDICIONALES-----------\n\n# IF\nprint('IF')\nif num1 < num2:\n    print(num1,'es menor que',num2)\nelif num1 > num2:\n    print(num1,'es mayor que',num2)\nelse:\n    print(num1,'es igual a',num2)\nprint('----')\n\n# MATCH\nprint('MATCH')\nmatch num1:\n    case 1: print('num1 vale 1')\n    case 2: print('num1 vale 2')\n    case 3: print('num1 vale 3')\n    case 4: print('num1 vale 4')\n    case 5: print('num1 vale 5')\n    case 6: print('num1 vale 6')\n    case 7: print('num1 vale 7')\n    case 8: print('num1 vale 8')\n    case 9: print('num1 vale 9')\n    case 10: print('num1 vale 10')\n    case _: print('num1 no es un entero entre 1 y 10')\nprint('----')\n\n# -------ITERATIVAS-----------\n    \n# FOR\nprint('FOR')\nfor i in range(num1):\n    print(i+1)\nprint('----')\n\n# WHILE\nprint('WHILE')\nx=1\nwhile x<=num2:\n    print(x)\n    x+=1\nprint('----')\n\n\n# -------EXCEPCIONES----------- \n# TRY, EXCEPT, ELSE, FINALLY\nprint('TRY, EXCEPT, ELSE, FINALLY')\n\ntry:\n    print(num1/0)\nexcept ZeroDivisionError:\n    print('No es posible realizar',num1,'/ 0','ya que la división por 0 no esta definida')\nelse:\n    print('Esto se imprimiria si no se hubiese lanzado un error')\nfinally:\n    print('Este texto se imprime haya o no ocurrido un error, y como se puede ver, a pesar de que ocurrio el mismo, la ejecución no se detuvo')\n\n\n\n'''DIFICULTAD EXTRA (opcional):\nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.'''\n\nfor i in range(10,56):\n    if(i%2 == 0 and i%3 != 0 and i != 16):\n        print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/guillesese.py",
    "content": "# 01 - OPERADORES Y ESTRUCTURAS DE CONTROL\n\n# - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n#   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n#   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n# - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n#   que representen todos los tipos de estructuras de control que existan\n#   en tu lenguaje:\n#   Condicionales, iterativas, excepciones...\n# - Debes hacer print por consola del resultado de todos los ejemplos.\n\n'''\nOperadores\n'''\n\n#      Aritméticos\nprint(\" ARITMETICAS\")\nprint(f\"Suma: 1 + 2 = {1 + 2}\")\nprint(f\"Resta: 1 - 2 = {1 - 2}\")\nprint(f\"Multiplicación: 1 * 2 = {1 * 2}\")\nprint(f\"División: 1 / 2 = {1 / 2}\")\nprint(f\"Módulo: 1 % 3 = {1 % 3}\")\nprint(f\"Exponente: 1 ** 3 = {1 ** 3}\")\nprint(f\"División entera: 1 // 3 = {1 // 3}\")\n\n#     Lógicos\nprint(\"\\n LOGICAS\")\nprint(f\"AND: (10 + 3 == 13) and (5 - 1 == 4) es {(10 + 3 == 13) and (5 - 1 == 4)}\")\nprint(f\"OR: (10 + 3 == 13) or (5 - 1 == 3) es {(10 + 3 == 13) or (5 - 1 == 3)}\")\nprint(f\"NOT: not (10 + 3 == 13) es {not (10 + 3 == 13)}\")\n\n#    Comparación\nprint(\"\\n COMPARACIÓN\")\nprint(f\"Igualdad: 10 == 3 es {10 == 3}\")\nprint(f\"Desigualdad: 10 != 3 es {10 != 3}\")\nprint(f\"Mayor que: 3 > 10 es {3 > 10}\")\nprint(f\"Mayor o igual: 10 <= 10 es {10 <= 10}\")\nprint(f\"Menor que: 3 < 10 es {3 < 10}\")\nprint(f\"Menor o igual: 3 <= 10 es {3 <= 10}\")\n\n#    Asignación\nprint(\"\\n ASIGNACION\")\nmy_number = 11 #asignación\nprint(my_number)\nmy_number += 1 #suma y asignación\nprint(my_number)\nmy_number -= 1 #resta y asignación\nprint(my_number)\nmy_number *= 2 #multiplicación y asignación\nprint(my_number)\nmy_number /= 2 #división y asignación\nprint(my_number)\nmy_number %= 2 #módulo y asignación \nprint(my_number)\nmy_number **= 3 #exponente y asignación\nprint(my_number)\nmy_number //= 2 #división entera y asignación\nprint(my_number)\n\n#    Operadores de identidad\nprint(\"\\n IDENTIDAD\")\nmy_new_number = my_number\nprint(f\"my_number is my_new_number es {my_number is my_new_number}\")\nprint(f\"my_number is not my_new_number es {my_number is not my_new_number}\")\n\n#    Operadores de pertenencia\nprint(\"\\n PERTENENCIA\")\nprint(f\"'u' in 'Guillesese' = {'u' in 'Guillesese'}\")\nprint(f\"'b' not in 'Guillesese' = {'b' not in 'Guillesese'}\")\n\n#    Operadores de bit\nprint(\"\\n BIT\")\na = 10 # 1010 \nb = 3  # 0011\nprint(f\"AND: 10 & 3 = {10 & 3}\") #0010\nprint(f\"OR: 10 | 3 = {10 | 3}\") #1011\nprint(f\"XOR: 10 ^ 3 = {10 ^ 3}\") #1001\nprint(f\"NOT: ~10 = {~10}\")\nprint(f\"Desplazamiento dcha: 10 >> 2 = {10 >> 2}\") # 0010\nprint(f\"Desplazamiento izda: 10 << 2 = {10 << 2}\") #10100\n\n'''\nEstructuras de control \n'''\n\n#     Condicionales\nprint(\"\\n CONDICIONALES\")\nmy_string = \"sese\"\nif my_string == \"guille\": \n    print(\"my_string es 'guille'\")\nelif my_string == 'sese':\n    print(\"my_string es 'sese'\")\nelse:   \n    print(\"my_string no es ni 'guille' ni 'sese'\")\n\n#   Iterativas\nprint(\"\\n ITERATIVAS\")\nfor i in range(10): \n    print (i)\n\ni = 0\nwhile i<=10: \n    print (i)\n    i += 1\n\nprint(\"\\n EXCEPCIONES\")\ntry:\n    print(10/0)\nexcept:\n    print(\"Error de división por 0\")\nfinally:\n    print(\"Fin del manejo de excepciones\")\n\n#DIFICULTAD EXTRA (opcional):\n#  Crea un programa que imprima por consola todos los números comprendidos\n#  entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\nfor number in range(10,56): \n    if (number % 2 == 0) and (number != 16) and (number % 3 != 0):\n        print(number)\n\n    "
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/h4ckxel.py",
    "content": "\"\"\"\nOperadores \n\"\"\"\n\n# Aritmeticos \nprint(f\"Suma: 10 + 8 = {10 + 8}\")\nprint(f\"Resta: 10 - 8 = {10 - 8}\")\nprint(f\"Multiplicacion: 10 * 8 = {10 * 8}\")\nprint(f\"Division: 10 / 8 = {10 / 8}\")\nprint(f\"Modulo: 10 % 8 = {10 % 8}\")\nprint(f\"Exponente: 10 ** 0 = {10 ** 8}\")\nprint(f\"División entera: 10 // 8 = {10 // 8}\")\n\n# Comparacion \nprint(f\"igualdad: 10 == 3 es {10 == 3}\")\nprint(f\"Desigualdad: 10 != 3 es {10 != 3}\")\nprint(f\"Mayor que: 10 > 3 es {10 > 3}\")\nprint(f\"Menor que: 10 < 3 es {10 < 3}\")\nprint(f\"Mayor o igual que: 10 >= 10 es {10 >= 10}\")\nprint(f\"Menor o igual que: 10 <= 3 es {10 <= 3}\")\n\n# Lógicos\nprint(f\"AND &&: 10 + 3 == 13 and 5 - 1 == 4 es {10 + 3 == 13 and 5 -1 == 4}\")\nprint(f\"OR ||: 10 + 3 == 13 or 5 - 1 == 4 es {10 + 3 == 14 or 5 - 1 == 4}\")\nprint(f\"NOT !: not 10 + 3 == 14 es {not 10 + 3 == 14}\")\n\n# Asignacón \nmy_number = 11  \nprint(my_number)\nmy_number += 1  \nprint(my_number)\nmy_number -= 1  \nprint(my_number)\nmy_number *= 2  \nprint(my_number)\nmy_number /= 2  \nprint(my_number)\nmy_number %= 2  \nprint(my_number)\nmy_number **= 1  \nprint(my_number)\nmy_number //= 1  \nprint(my_number)\n\n# Identida \nmy_new_number = my_number\nprint(f\"my_number is my_new_number es {my_number is my_new_number}\")\nprint(f\"my_number is not my_new_number es {my_number is not my_new_number}\")\n\n# Pertenencia \nprint(f\"'y' in 'Python' = {'y' in 'Python'}\")\nprint(f\"'b' not in 'Python' = {'b' not in 'Python'}\")\n\n# Bit \na = 10  # 1010\nb = 3  # 0011\nprint(f\"AND: 10 & 3 = {10 & 3}\")  # 0010\nprint(f\"OR: 10 | 3 = {10 | 3}\")  # 1011\nprint(f\"XOR: 10 ^ 3 = {10 ^ 3}\")  # 1001\nprint(f\"NOT: ~10 = {~10}\")\nprint(f\"Desplazamiento a la derecha: 10 >> 2 = {10 >> 2}\")  # 0010\nprint(f\"Desplazamiento a la izquierda: 10 << 2 = {10 << 2}\")  # 101000\n\n\"\"\"\nEstructuras de control\n\"\"\"\n# Condicionales\n\nmy_string = \"Python\"\n\nif my_string == \"Rust\":\n    print(\"my_string es 'Rust'\")\nelif my_string == \"Python\":\n    print(\"my_string es 'Python'\")\nelse:\n    print(\"my_string no es 'Rust' ni 'Python'\")\n\n# Iterativas\n\nfor i in range(11):\n    print(i)\n\ni = 0\n\nwhile i <= 10:\n    print(i)\n    i += 1\n\n# Manejo de excepciones\ntry:\n    print(10 / 0)\nexcept:\n    print(\"Se ha producido un error\")\nfinally:\n    print(\"Ha finalizado el manejo de excepciones\")\n\n\"\"\"\nExtra\n\"\"\"\n\nfor number in range(10, 56):\n    if number % 2 == 0 and number != 16 and number % 3 != 0:\n        print(number)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/haroldAlb.py",
    "content": "# Operadores Aritméticos \nprint('Operadores Aritméticos')\nnum= 2 + 2 # suma\nprint(num)\nprint(num - 1) # resta\nprint(num * 2) # multiplicación\nprint(num / 3) # división\nprint(num % 2) # módulo; Devuelve el resto de la división\nprint(num ** 2) # exponente\nprint(num // 3) # Devuelve el entero del resultado de la división, sin decimales.\n\n# Operadores de Comparación\nprint('Operadores de Comparación')\nnum2= 8\nprint(num == num2) # igual a\nprint(num != num2) # diferente a\nprint(num > num2) # mayor que\nprint(num < num2) # menor que\nprint(num >= num2) # mayor o igual que\nprint(num <= num2) # menor o igual que\n\n# Operadores de Asignación\nprint('Operadores de Asignación')\nnum3= 9 # Asigna un valor a un elemento. Puede ser  variable, lista, diccionario, tupla, etc.\nprint(num3)\nnum3 += 1 # Suma uno a num3 y lo guarda en num3\nprint(num3)\nnum2 -= 1 # Resta uno a num2 y lo guarda en num2\nprint(num2)\nnum2 *= 2 # Multiplica por 2 a num2 y lo guarda en num2\nprint(num2)\nnum2 /= 2 # Divide entre 2 a num2 y lo guarda en num2\nprint(num2)\nnum2 %= 2 # Divide entre 2 a num2 y el resto lo guarda en num2\nprint(num2)\nnum3 **= 2 # Eleva num3 a 2 y lo guarda en num3\nprint(num3)\n\n# Operadores Lógicos\nprint('Operadores Lógicos')\nprint(10 > 5 and 3 < 5) # Es verdadero cuando TODAS las expresiones son ciertas.\nprint(10 > 5 or 3 < 2) # Es verdadero cuando al menos una expresión sea verdadera.\nprint(not 10 < 5) # Será verdadera cuando la expresión sea falsa y viceversa.\n\n# Operadores Pertenencia - si un valor está presente dentro de una secuencia (como una cadena, lista, tupla, o un conjunto).\nprint('Operadores Pertenencia')\nhay_letra= ('n' in 'Python') \nprint(hay_letra)\nhay_letra= ('a' not in 'Python')\nprint(hay_letra)\n\n# Operadores Identidad - Verifica si dos variables se refieren al mismo objeto en la memoria.\nprint('Operadores de Identidad')\nnum = 100\nnum2 = num\n\nprint(num is num2)\nprint(num is not num2)\n\n# Operadores Bitwise\nprint('Operadores Bitwise')\na = 10  # 1010 en binario\nb = 3   # 0011 en binario\nprint(a and b) # and(&) 1010 & 0011 = 0010 (decimal 2)\nprint(a or b) # or(|) 1010 | 0011 = 1011 (decimal 11)\nprint(a ^ b) # xor(^) 1010 ^ 0011 = 1001 (decimal 9)\n\n# ESTRUCTURAS DE CONTROL https://www.luisllamas.es/python-condicionales/\nprint('ESTRUCTURAS DE CONTROL')\n# if, elif y else\nprint('if, elif y else')\nx= 10\ny= 5\nz= 30\nif x < y: # ejecuta un bloque de código si una condición es verdadera\n    print('x es menos que y')\nelif y == z: # se ejecuta si la  anterior condicion es falsa y esta es verdadera\n    print('y es igual a z')\nelse: # Se ejecuta si todas las anteriores condiciones son falsas\n    print('Las anteriores son falsas')\n\n#Bucle for\nprint('Bucle for')\nword= 'Python'\nfor char in word:\n    print(char)\nnombres= ['Edu', 'Kike', 'Toni', 'Isa', 'Mónica', 'Bego']\nfor nombre in nombres:\n    print(nombre)\nfor num in range(2,25,2):\n    print(num)\n\n# Bucle While\nprint('Bucle While')\ncount=0\nwhile count < 6:\n    print(count)\n    count += 1\n\nprint('Bucle While con Break')\nwhile count < 13:\n    print(count)\n    if count == 10:\n        break # Cuando se ejecute el BREAK, se detendrá el bucle \n    count += 1\n\nprint('Bucle while con continue')\nwhile count < 20:\n    if count % 2 == 0:\n        count += 1\n        continue\n    print(count)\n    count += 1\n\nprint('EJERCICIO OPCIONAL')\n# Crea un programa que imprima por consola todos los números comprendidos\n# entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\nfor num in range(10,56,2):\n    if num == 16 or num % 3 == 0:\n        continue\n    else:\n        print(num)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/hectorio23.py",
    "content": "# Autor: Héctor Adán \n# GitHub: https://github.com/hectoiro23\n\n'''\n* EJERCICIO:\n* - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n*   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n*   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n* - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n*   que representen todos los tipos de estructuras de control que existan\n*   en tu lenguaje:\n*   Condicionales, iterativas, excepciones...\n* - Debes hacer print por consola del resultado de todos los ejemplos.\n*\n* DIFICULTAD EXTRA:\n* Crea un programa que imprima por consola todos los números comprendidos\n* entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n*\n* Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n'''\n\n# Operadores aritméticos\nprint(\"******** OPERADORES ARITMÉTICOS ********\")\nprint(\"SUMA: 4 + 5 =\", 4 + 5)\nprint(\"RESTA: 4 - 5 =\", 4 - 5)\nprint(\"MULTIPLICACIÓN: 4 * 5 =\", 4 * 5)\nprint(\"DIVISIÓN: 4 / 5 =\", 4 / 5)\nprint(\"DIVISIÓN ENTERA: 4 // 5 =\", 4 // 5)\nprint(\"MÓDULO: 4 % 5 =\", 4 % 5)\nprint(\"POTENCIA: 4 ** 5 =\", 4 ** 5)\n\n# Operadores de comparación\nprint(\"******** OPERADORES DE COMPARACIÓN ********\")\nprint(\"IGUAL QUE: 4 == 5:\", 4 == 5)\nprint(\"DIFERENTE DE: 4 != 5:\", 4 != 5)\nprint(\"MAYOR QUE: 4 > 5:\", 4 > 5)\nprint(\"MENOR QUE: 4 < 5:\", 4 < 5)\nprint(\"MAYOR O IGUAL QUE: 4 >= 5:\", 4 >= 5)\nprint(\"MENOR O IGUAL QUE: 4 <= 5:\", 4 <= 5)\n\n# Operadores lógicos\nprint(\"******** OPERADORES LÓGICOS ********\")\nprint(\"AND: True and False:\", True and False)\nprint(\"OR: True or False:\", True or False)\nprint(\"NOT: not True:\", not True)\n\n# Operadores de asignación\nprint(\"******** OPERADORES DE ASIGNACIÓN ********\")\nx = 5\nprint(\"x =\", x)\nx += 2\nprint(\"x += 2 ->\", x)\nx -= 1\nprint(\"x -= 1 ->\", x)\nx *= 3\nprint(\"x *= 3 ->\", x)\nx /= 2\nprint(\"x /= 2 ->\", x)\nx %= 4\nprint(\"x %= 4 ->\", x)\nx **= 2\nprint(\"x **= 2 ->\", x)\nx //= 3\nprint(\"x //= 3 ->\", x)\n\n# Operadores de identidad\nprint(\"******** OPERADORES DE IDENTIDAD ********\")\na = [1, 2, 3]\nb = a\nprint(\"a is b:\", a is b)\nc = a[:]\nprint(\"a is c:\", a is c)\nprint(\"a == c:\", a == c)\n\n# Operadores de pertenencia\nprint(\"******** OPERADORES DE PERTENENCIA ********\")\nprint(\"1 in [1, 2, 3]:\", 1 in [1, 2, 3])\nprint(\"4 not in [1, 2, 3]:\", 4 not in [1, 2, 3])\n\n# Operadores a nivel de bits\nprint(\"******** OPERADORES A NIVEL DE BITS ********\")\nprint(\"AND: 4 & 5 =\", 4 & 5)\nprint(\"OR: 4 | 5 =\", 4 | 5)\nprint(\"XOR: 4 ^ 5 =\", 4 ^ 5)\nprint(\"NOT: ~4 =\", ~4)\nprint(\"Desplazamiento a la izquierda: 4 << 1 =\", 4 << 1)\nprint(\"Desplazamiento a la derecha: 4 >> 1 =\", 4 >> 1)\n\n# Estructuras de control condicionales\nprint(\"******** ESTRUCTURAS DE CONTROL CONDICIONALES ********\")\nif x > 2:\n    print(\"x es mayor que 2\")\nelif x == 2:\n    print(\"x es igual a 2\")\nelse:\n    print(\"x es menor que 2\")\n\n# Estructuras de control iterativas\nprint(\"******** ESTRUCTURAS DE CONTROL ITERATIVAS ********\")\nprint(\"Bucle for:\")\nfor i in range(3):\n    print(\"i =\", i)\n\nprint(\"Bucle while:\")\nn = 3\nwhile n > 0:\n    print(\"n =\", n)\n    n -= 1\n\n# Manejo de excepciones\nprint(\"******** MANEJO DE EXCEPCIONES ********\")\ntry:\n    resultado = 10 / 0\nexcept ZeroDivisionError:\n    print(\"No se puede dividir por cero\")\nfinally:\n    print(\"Bloque finally ejecutado\")\n\n\n\nprint(\"******** EJERCICIO EXTRe ********\")\n# Imprime los numeros del 10 al 55 siempre y cuando sean pares y no sean multiplos de 3 y 16 \nprint([ element for element in range(10, 56, 2) if element % 3 != 0 and element % 16 != 0])\n# 10, 14, 20, 22, 26, 28, 32, 34, 38, 40, 44, 46, 50, 52\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/hozlucas28.py",
    "content": "\"\"\"\n    Type of operators...\n\"\"\"\n\n# Arithmetic\nADDITION = 1 + 1\nprint(f\"Add: 1 + 1 --> {ADDITION}\")\n\nSUBTRACTION = 1 - 1\nprint(f\"Subtraction: 1 - 1 --> {SUBTRACTION}\")\n\nMULTIPLICATION = 2 * 5\nprint(f\"Multiplication: 2 * 5 --> {MULTIPLICATION}\")\n\nDIVISION = 10 / 3\nprint(f\"Division: 10 / 3 --> {DIVISION}\")\n\nMODULE = 24 % 2\nprint(f\"Module: 24 % 2 --> {MODULE}\")\n\nEXPONENT = 2**3\nprint(f\"Exponent: 2 ** 3 --> {EXPONENT}\")\n\nQUOTIENT = 10 // 3\nprint(f\"Quotient: 10 // 3 --> {QUOTIENT}\")\n\n\n# Comparison\nEQUAL = 1 == 1\nprint(f\"\\nEqual: 1 == 1 --> {EQUAL}\")\n\nNOT_EQUAL = 1 != 2\nprint(f\"Not Equal: 1 != 2 --> {NOT_EQUAL}\")\n\nGREATER_THAN = 1 > 1\nprint(f\"Greater than: 1 > 1 --> {GREATER_THAN}\")\n\nLESS_THAN = -1 < 0\nprint(f\"Less than: -1 < 0 --> {LESS_THAN}\")\n\nGREATER_THAN_OR_EQUAL_TO = 1 >= 1\nprint(f\"Greater than or equal to: 1 >= 1 --> {GREATER_THAN_OR_EQUAL_TO}\")\n\nLESS_THAN_OR_EQUAL_TO = 2 <= 2\nprint(f\"Less than or equal to: 2 <= 2 --> {LESS_THAN_OR_EQUAL_TO}\")\n\nLETTER_A_01 = 1\nLETTER_A_02 = LETTER_A_01\nprint(f\"Is: {LETTER_A_01} is {LETTER_A_02} --> {LETTER_A_01 is LETTER_A_02}\")\n\nLETTER_A_03 = 1\nLETTER_A_04 = LETTER_A_01\nprint(\n    f\"Is not: {LETTER_A_03} is not {LETTER_A_04} --> {LETTER_A_03 is not LETTER_A_04}\"\n)\n\nARRAY_01 = [\"Hello\", \"World\"]\nprint(f\"In: 'World' in {ARRAY_01} --> {'World' in ARRAY_01}\")\n\nARRAY_02 = [\"Hello\", \"World\"]\nprint(f\"Not in: 'World' not in {ARRAY_02} --> {'World' not in ARRAY_02}\")\n\n\n# Logical\nprint(f\"\\nAnd: True and False --> {True and False}\")\n\nprint(f\"Or: False or True --> {False or True}\")\n\nprint(f\"Not: not False --> {not False}\")\n\n\n\"\"\"\n    Control structures...\n\"\"\"\n\n# < if > and < if else >\nif True:\n    print(\"\\nIf: True statement\")\n\nif False:\n    print(\"If else: False --> True statement\")\nelse:\n    print(\"If else: False --> False statement\")\n\n# < if elif else >\nLETTER = \"A\"\nif LETTER == \"D\":\n    print(f\"If elif else: {LETTER} --> First statement\")\nelif LETTER == \"C\":\n    print(f\"If elif else: {LETTER} --> Second statement\")\nelif LETTER == \"B\":\n    print(f\"If elif else: {LETTER} --> Third statement\")\nelse:\n    print(f\"If elif else: {LETTER} --> Default statement\")\n\n# < while >\ni = 5\nwhile i > 0:\n    print(f\"While (condition i > 0): loop {i}\")\n\n    if i == 3:\n        break\n\n    i = i - 1\n\n# < for >\nfor char in \"banana\":\n    if char == \"n\":\n        continue\n    print(f\"{char}\")\n\n\n\"\"\"\n    Additional challenge...\n\"\"\"\n\nprint(\"\")\nfor n in range(10, 56):\n    if n != 16 and n % 2 == 0 and n % 3 != 0:\n        print(f\"{n}\")\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/iban99.py",
    "content": "#Tipos de operadores\n    #Comparación\nprint(f\"10 es más grande que 3, es {10 > 3}\")\n\"\"\" \n2 == 3\n98 <= 100\n98 >= 100\n76 < 0\n76 > 0 \n75 != 1 \"\"\"\n\n    #Lógicos\n\"\"\" True AND && False\nTrue OR || False\nTrue NOT !: False \"\"\"\n\n    #Aritméticos\nprint(f\"Suma: 10 + 3 = {10 + 3}\")\nprint(f\"Resta: 10 - 3 = {10 - 3}\")\nprint(f\"Mult: 10 / 3 = {10 / 3}\")\nprint(f\"Div: 10 * 3 = {10 * 3}\")\nprint(f\"Mod: 10 % 3 = {10 % 3}\")\nprint(f\"Exp: 10 ** 3 = {10 ** 3}\")\nprint(f\"Suma: 10 // 3 = {10 // 3}\")\n\n    #Asignación\nmy_number = 11 #Asignación \nmy_number += 1 #Asignación y suma\nprint(my_number) \nmy_number -= 1 #Asignación y resta\nprint(my_number)\nmy_number *= 4 #Asignación y multiplicación\nprint(my_number) \nmy_number /= 1 #Asignación y división\nprint(my_number) \nmy_number %= 3 #Asignación y módulo\nprint(my_number) \nmy_number **= 1 #Asignación y exponente\nprint(my_number) \nmy_number //= 1 #Asignación y división entera\nprint(my_number)\n\n    #Identidad\nmy_new_number = my_number\nprint(f\"my_number is my_new_number es {my_number is my_new_number}\")\nprint(f\"my_number is not my_new_number es {my_number is not my_new_number}\")\n#Tener en cuenta la posición de memoria, aunque sea el mismo numero.\n\n    #Pertenencia\nprint(f\"'u' in moure = {'u' in 'moure'}\") \nprint(f\"'b' not in moure = {'b' not in 'moure'}\") \n\n    #Bit\na = 10 # 1010\nb = 3 # 0011\n#Los operadores binarios van a convertir el numero a bits para hacer operaciones\nprint(f\"AND: 10 & 3 = {10 & 3}\")\nprint(f\"OR: 10 | 3 = {10 | 3}\")\nprint(f\"XOR: 10 ^ 3 = {10 ^ 3}\")\nprint(f\"NOT: 10 ~ 3 = {~10}\")\nprint(f\"Desplazamiento a la derecha: 10 >> 2 = {10 >> 2}\")\nprint(f\"Desplaxamiento a la izquierda: 10 << 2 = {10 << 2}\")\n\n\n#Estructuras de control\n    #Condicionales\nmy_string = \"MoureDev\"\n\nif my_string == \"MoureDev\":\n    print(\"my_String es MoureDev\")\nelif my_string == \"Brais\":\n    print((\"my_String es Brais\"))\nelse:\n    print(\"my_String no es MoureDev\")\n\n\n    #Iterativas\nfor i in range(11):\n    print(i)\n\n\ni = 0\nwhile i <= 10:\n    print(i)\n    i += 1\n    \n\n    #Manejo de Excepciones\ntry:\n    print(10/1)\nexcept:\n    print(\"Se ha producido un error\")\nfinally:\n    print(\"Ha finalizado el manejo de excepciones\")\n    \n\n#Dificultad extra\nfor number in range(10, 56):\n    if number % 2 == 0 and number != 16 and number  % 3 == 0:\n        print(number)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/ibuetab.py",
    "content": "#OPERADORES\n\n#Operadores aritméticos\nsuma = 2+3;\nresta = 5-2;\nmultiplicacion= 2*5;\ndivision = 6/2;\nmodulo = 10%2;\ndivision_entera = 10 // 3;\nexponente = 2**2;\n\nprint(f\"Suma 2+3 = {suma}, Resta 5-2 = {resta}, Multiplicación 2*5 = {multiplicacion}, División 6/2 = {division}, Módulo 10%2 = {modulo}, División entera 10 // 3 = {division_entera}, Exponente 2**2 = {exponente}\");\n\n\n#Operadores de asignación\noperador_asignacion = 2;\nprint(operador_asignacion);\noperador_asignacion += 1;\nprint(operador_asignacion);\noperador_asignacion -= 1;\nprint(operador_asignacion);\noperador_asignacion *= 2;\nprint(operador_asignacion);\noperador_asignacion /= 2;\nprint(operador_asignacion);\noperador_asignacion %= 2;\nprint(operador_asignacion);\noperador_asignacion //= 2;\nprint(operador_asignacion);\noperador_asignacion ** 2;\nprint(operador_asignacion);\n\n\n#Operadores lógicos\noperador_and = 3 < 5 and 2 < 4;\noperador_or = 2 > 1 or 5 < 3;\noperador_not = not(3 < 5 and 12 > 16);\n\nprint(f\"AND = {operador_and}, OR = {operador_or}, NOT = {operador_not}\");\n\n\n#Operadores de comparación\nvariable_int = 10;\nprint(f\"Igualdad: {variable_int==10}, Diferente: {variable_int!=10}, Mayor que: {variable_int > 10}, Menor que: {variable_int < 10}, Mayor o igual: {variable_int >= 10}, Menor o igual: {variable_int <= 10}   \");\n\n\n#Operadores de identidad\ncadena = \"Hola Mundo\";\ncadena_2 = \"Hola\";\nprint(f\"{cadena is cadena_2}\");\nprint(f\"{cadena is not cadena_2}\");\n\n#Operadores de pertenencia\nprint(f\"{cadena_2 in cadena}\");\nprint(f\"{cadena_2 not in cadena}\");\n\n#Operadores bit\na = 10;\nb =2;\nprint(f\"AND {a & b}\");\nprint(f\"{a | b}\");\nprint(f\"{a ^ b}\");\nprint(f\"{~a}\");\nprint(f\"{a << 2}\");\nprint(f\"{a >> 2}\");\n\n#-------------------------------------------------------------------------------------------------------------------------------------------------------\n\n#ESTRUCTURAS DE CONTROL\n\n#Condicionales\nvariable_condicional = 2;\n\nif(variable_condicional == 2):\n    print(\"Igual\");\nelif(variable_condicional < 3):\n    print(\"Verdadero\");\nelse:\n    print(\"Falso\");\n\n#Bucles\nfor i in range(11): #Imprime del 1 al 10 contando el 0\n    print(i);\n\n\nfor i in range(1,10+1): #Imprime del 1 al 10 sin contar el 0\n    print(i);\n \n#Imprime del 1 al 10 contando el 0\ni=0; \nwhile i <= 10:\n    print(i);\n    i+=1;\n\n#Imprime del 1 al 10 sin contar el 0\ni=1; \nwhile i <= 10:\n    print(i);\n    i+=1;\n\n#Do-While emulado\ncounter = 0;\nwhile True:\n    print(\"Hola\");\n    counter += 1;\n    if counter > 5:\n        break;\n\n#Excepciones\ntry:\n    print(5/0);\nexcept:\n    print(\"No se puede dividir entre 0\");\nfinally:\n    print(\"Programa finalizado\");\n\n\n#EXTRA\nfor i in range(10,55+1):\n    if(i % 2 == 0 and i != 16 and i % 3 != 0 ):\n        print(i);\n\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/icedrek.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\"\"\"\n# OPERADORES DE ASIGNACION - Asignan un valor a una variable\na = 1  # El valor 1 es asignado a la variable a\nprint(a)\na += 5  # Es equivalente a: a = a + 5\nprint(a)\na -= 3  # Es equivalente a: a = a - 2\nprint(a)\na *= 3  # Es equivalente a: a = a * 2\nprint(a)\na /= 3  # Es equivalente a: a = a / 3\nprint(a)\na %= 3  # Es equivalente a: a = a % 3\nprint(a)\na **= 3  # Es equivalente a: a = a ** 3\nprint(a)\na //= 3  # Es equivalente a: a = a // 3\nprint(a)\n\na = 5\na &= 3  # Es equivalente a: a = a & 3\nprint(a)\na |= 3  # Es equivalente a: a = a | 3\nprint(a)\na ^= 3  # Es equivalente a: a = a ^ 3\nprint(a)\na >>= 3  # Es equivalente a: a = a >> 3\nprint(a)\na <<= 3  # Es equivalente a: a = a << 3\nprint(a)\n\n\n# OPERADORES ARITMETICOS - Devuelven un cálculo\n# Suma(+)\nprint(1 + 2)\n# Resta(-)\nprint(2 - 1)\n# Multiplicación (*)\nprint(2 * 3)\n# División (/)\nprint(6 / 2)\n# División parte entera (//)\nprint(5 // 2)\n# Módulo o Resto de la división(%)\nprint(5 % 2)\n# Potencia (**)\nprint(3**2)\n\n\n# OPERADORES DE COMPARACION - Devuelven True o False\n# Igual (==)\nprint(1 == 1)\n# No igual (!=)\nprint(1 != 2)\n# Mayor (>)\nprint(3 > 2)\n# Mayor o igual (>=)\nprint(2 >= 2)\n# Menor (<)\nprint(2 < 3)\n# Menor o igual (<=)\nprint(3 <= 3)\n\n# OPERADORES LOGICOS - Devuelven True o False\n# AND - True si se cumplen ambas condiciones\nif 1 == 1 and 2 == 2:\n    print(\"AND - True\")\n# OR - True si se cumple alguna de las condiciones\nif 1 == 0 or 1 == 1:\n    print(\"OR - True\")\n# NOT - True si alguno de los operandos es False\nif not 1 == 2:\n    print(\"NOT - True\")\n\n\n# OPERADORES DE BIT\nprint(1 & 2)  # Binario: 01 AND 10 = 00\nprint(1 | 2)  # Binario: 01 OR 10 = 11\nprint(1 ^ 2)  # Binario: 01 XOR 10 = 11\nvalue1 = int(\"01\", 2)\nprint(bin(~value1))  # Binario NOT (invierte cada bit) ~(01) = -10\n# Desplaza bits de operador de la izquierda a derecha los bits que indica operador de la derecha\nprint(3 >> 1)\n# Desplaza los bits del operando de la izquierda a la izquierda tantos bits como especifique el operador de la derecha\nprint(2 << 1)\n\n\n# OPERADORES DE PERTENENCIA - Devuelven True o False\nlista = [1, 2, 3, 4, 5]\n# IN - True si el valor especificado se encuentra en una secuencia\nif 5 in lista:\n    print(\"el 5 está en la lista\")\n# NOT IN - True si el valor especificado no se encuentra en una secuencia\nif 6 not in lista:\n    print(\"el 6 NO está en la lista\")\n\n# OPERADORES DE IDENTIDAD - Devuelven True o False\nlista2 = lista\nlista3 = [1, 2, 3, 4, 5]\n# IS - True si los operandos hacen referencia al mismo objeto\nprint(lista is lista2)\n# IS NOT - True si los operandos no hacen referencia al mismo objeto\nprint(lista is not lista3)\n# NOTA: lista y lista2 son el mismo objeto, lista y lista3 son iguales, pero no son el mismo objeto\n\n# ESCTRUCTURAS CONDICIONALES\n# IF-ELIF-ELSE\nif 5 in lista:\n    print(\"primer condicion\")\nelif 6 in lista:\n    print(\"primer condicion\")\nelse:\n    print(\"Si no se cumple nada de lo anterior, se sale por aqui\")\n\n# MATCH-CASE - A partir de la version 3.10\ncondicion = 10\nmatch condicion:\n    case 11:\n        print(\"Si se cumple, entra aqui\")\n    case 10:\n        print(\"En este caso, entrara aqui\")\n    case _:\n        print(\"Si no se cumple nada de lo anterior, se sale por aqui\")\n\n\n# ESTRUCTRUAS ITERATIVAS\n# Bucle FOR\nfor elemento in lista:\n    print(elemento)\n# Bucle WHILE\ncontador = 0\nwhile contador < 10:\n    print(contador)\n    contador += 1\n\n# CONTROL DE ERRORES\n# TRY-EXCEPT\ntry:\n    a = 2 + \"a\"\nexcept TypeError:\n    print(\"Tipos no soportados para la operacion +\")\nelse:\n    print(a)  # Si no da error, se ejecuta esta parte [OPCIONAL]\nfinally:\n    print(\"Se sale del try\")  # Si se incluye este bloque, se ejecuta siempre [OPCIONAL]\n\n\n# EJEMPLOS EXTRA\nfor _ in range(10, 55):\n    if _ % 2 == 0:\n        if _ != 16:\n            if _ % 3 != 0:\n                print(f\"{_}, \", end=\"\")\n\nprint(\"\\n\")\n\nfor _ in range(10, 55, 2):\n    if _ != 16 and _ % 3 != 0:\n        print(f\"{_}, \", end=\"\")\n\nprint(\"\\n\")\n\na = 10\nwhile a <= 55:\n    if a != 16 and a % 3 != 0:\n        print(f\"{a}, \", end=\"\")\n\n    a += 2\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/idiegorojas.py",
    "content": "# Operadores Aritmeticos\n\nprint(f\"\"\"Los operadores aritmeticos son:\n    Suma: 3 + 2,\n    Resta: 5 - 2,\n    Multiplicacion: 3 * 2,\n    Division: 10 / 2,\n    Modulo: 10 % 3,\n    Exponente: 2 ** 3,\n    Division Entera: 10 // 3\n\"\"\")\n\n\n# Operadores de comparacion\n\nprint(f\"\"\"Los operadores de comparacion son los siguientes:\n    Igual a: 3 == 3\n    Diferente de: 3 != 2\n    Mayor que: 5 > 3\n    Menor que: 3 < 5\n    Mayor o igual que: 5 >= 3\n    Menor o igual que: 5 <= 3\n\"\"\")\n\n\n# Operadores logicos\n\nprint(f\"\"\"Los operadores logicos son:\n    and: True and False -> False \n    or: True or False -> True\n    not: not True -> False\n\"\"\")\n\n\n# Operadores de Asignacion\n\nprint(f\"\"\"Los operadores de asignacion son:\n    Asignacion basica: x = 5\n    Suma y asigna: x += 3\n    Resta y asigna: x -= 2\n    Multiplica y asigna: x *= 2\n    Divide y asigna: x /= 2\n    Modulo y asigna: x %= 3\n    Exponente y asigna: x **= 2\n    Division entera y asigna: x //= 2 \n\"\"\")\n\n\n# Operadores de Identidad\n\nprint(f\"\"\"Los operadores de identidad son:\n    Es: x is y -> Devuelve True si ambos objetos son iguales\n    No es: x is not y -> Devuelve True si ambos objetos no son iguales\n\"\"\")\n\n\n# Operadores de pertenencia\n\nprint(f\"\"\"Los operadores de identidad son:\n    En: 3 in [1, 2, 3] -> Devuelve True si el valor está en la secuencia\n    En no: 4 not in [1, 2, 3] -> Devuelve True si el valor no está en la secuencia\n\"\"\")\n\n# Extra:\nprint(f\"\"\"Crea un programa que imprima por consola todos los números comprendidos\ndentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\"\"\")\n\nfor num in range(10, 56):\n    if num % 2 == 0 and num != 16 and num % 3 != 0:\n        print(num)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/ignacioGM1973.py",
    "content": "'''\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n'''\n# 1º punto del ejercicio\n'''\n- Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n'''\n\na, b, resultado = 10, 30, 0\n\n# suma\nresultado = a + b\n# resta\nresultado = a - b\n# multiplicacion\nresultado = a * b\n# division\nresultado = a / b\n# division entera\nresultado = a // b\n# resto\nresultado = a % b\n# exponente\nresultado = a ** b\n\n# Comparacion\nprint(a == b)\n# distinto\nprint(a != b)\n# mayor\nprint(a > b)\n# mayor igual\nprint(a >= b)\n# menor\nprint(a < b)\n# menor igual\nprint(a <= b)\n# Operadores lógicos\na = True\nb = False\n# and\nprint(a and b)\n# Or\nprint(a or b)\n# not\nprint(not a)\nprint(not b)\n#  Operadores Bit a Bit (Bitwise)\nx = 5  # 101 en binario\ny = 3  # 011 en binario\nprint(x & y)  # 001 → 1\nprint(x | y)  # 111 → 7\nprint(x ^ y)  # 110 → 6\nprint(~x)     # Complemento a 2 → -6\nprint(x << 1)  # Desplazamiento a la izquierda → 1010 → 10\nprint(x >> 1)  # Desplazamiento a la derecha → 10 → 2\n# Operadores de Identidad\nx = [1, 2, 3]\ny = x\nz = [1, 2, 3]\nprint(x is y)   # True (son el mismo objeto)\nprint(x is z)   # False (tienen los mismos valores, pero son objetos distintos)\nprint(x is not z)  # True\n# Operadores de Pertenencia\nlista = [1, 2, 3, 4]\nprint(2 in lista)       # True\nprint(5 not in lista)   # True\n\n# 2º punto del ejercicio\n'''\n- Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n'''\n# Comparar\na = 10\nb = 30\nif a > b:\n    print(\"A es mayor que B\")\nelse:\n    print(\"A es menor que B\")\n\nlista = [1, 7, 8, 50, 6, 3]\n# buscar número más alto bucle For.\nn = lista[0]\nfor i in lista:\n    if i > n:\n        n = i\nprint(f\"El número más alta de la lista es: {n}\")\n\n# bucle While\nr = 1\nprint(\"**** Imprimo la tabla del 7 ****\")\nwhile r <= 10:\n    print(f\"7 * {r} = {7*r}\")\n    r += 1\n\n# Control de excepciones\ntry:\n    texto = int(input(\"Introduce un texto: \"))\n    print(\"Lo que ha introducido No es un caracter. No es Correcto\")\nexcept ValueError:\n    print(\"Lo que ha introducido es un caracter. Es correcto\")\n\n# 3º punto del ejercicio\n'''\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n'''\n# Altenativa estandar\nprint(\"\\nAlternativa estandar:\\n\")\nfor i in range(10, 56):\n    if i % 2 == 0 and i != 16 and (i % 3 != 0):\n        print(i)\n\n# version por compresión\nnumeros_validos = [i for i in range(\n    10, 56) if i % 2 == 0 and i != 16 and i % 3 != 0]\nprint(f\"\\nVersión por compresion: {numeros_validos}\\n\")\n\n# Alternativa usando continue\nprint(\"\\nAlternativa usando continue:\\n\")\nfor i in range(10, 56):\n    if i == 16 or i % 2 != 0 or i % 3 == 0:\n        continue\n    print(i)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/ignaciovihe.py",
    "content": "\"\"\"\nOperadores\n\"\"\"\n#Operadores aritmeticos\nprint(f\"10 + 4 = {10 + 4}\")\nprint(f\"10 - 4 = {10 - 4}\")\nprint(f\"10 * 4 = {10 * 4}\")\nprint(f\"10 / 4 = {10 / 4}\")\nprint(f\"10 ** 4 = {10 ** 4}\")\nprint(f\"10 % 4 = {10 % 4}\")\nprint(f\"10 // 4 = {10 // 4}\")\n\n#Operedores de comparación\nprint(f\"Igualdad: 10 == 4 es: {10 == 4}\")\nprint(f\"Mayor que: 10 > 4 es: {10 > 4}\")\nprint(f\"Menor que: 10 < 4 es: {10 < 4}\")\nprint(f\"Mayor o igual que: 10 >= 4 es: {10 >= 4}\")\nprint(f\"Menor o igual que: 10 <= 10 es: {10 <= 10}\")\nprint(f\"Desigualdad: 10 != 4 es: {10 != 4}\")\n\n#Operadores de asignación\nmy_number = 4 #Asignacion\nprint(f\"my_number = {my_number}\")\nmy_number += 2 #Suma y asignación\nprint(f\"my_number = {my_number}\")\nmy_number -= 3 #Resta y asignación\nprint(f\"my_number = {my_number}\")\nmy_number *= 2 #Multiplicación y asignación\nprint(f\"my_number = {my_number}\")\nmy_number /= 2 #División y asignación\nprint(f\"my_number = {my_number}\")\nmy_number **= 2 #Exponente y asignación\nprint(f\"my_number = {my_number}\")\nmy_number %= 2 #Modulo y asignación\nprint(f\"my_number = {my_number}\")\nmy_number //= 2 #División entera y asignación\nprint(f\"my_number = {my_number}\")\n\n#Operadores logicos\nprint(f\"AND : 10 > 0 and 3 < 1 es: {10 > 0 and 3 < 1}\")\nprint(f\"OR : 10 > 0 or 3 < 1 es: {10 > 0 or 3 < 1}\")\nprint(f\"NOT 10 > 0 es: {not 10 > 0}\")\n\n\n#Operadores de identidad\nmy_number = 1\nmy_other_number = 1\n#Para números pequeños, Python reutiliza los mismos objetos de memoria, por eso devuelve True\nprint(f\"my_other_number is my_number es: {my_other_number is my_number}\")\nmy_other_number = my_number\nprint(f\"my_other_number is my_number es: {my_other_number is my_number}\")\nmy_other_number = 3000\nprint(f\"my_other_number is my_number es: {my_other_number is my_number}\")\nmy_other_number = my_number\nprint(f\"my_other_number is my_number es: {my_other_number is my_number}\")\nprint(f\"my_other_number is not my_number es: {my_other_number is not my_number}\")\n\n\n#Operadores de pertenencia\nprint(f\"IN: 'a' in 'Hola, Python!' es: {'a' in 'Hola, Python!'}\")\nprint(f\"IN: 'u' in 'Hola, Python!' es: {'u' in 'Hola, Python!'}\")\nprint(f\"IN: 'u' not in 'Hola, Python!' es: {'u' not in 'Hola, Python!'}\")\n\n#Operadores de bits\na= 10 # 1010\nb= 5  # 0101\nprint(f\"AND: 10 & 5 = {10 & 5}\")  # Ambos bits son '1' -- 0000\nprint(f\"OR: 10 | 5 = {10 | 5}\")  # Al menos 1 de los dos bits es '1' - 1111\nprint(f\"XOR: 10 ^ 5 = {10 ^ 5}\")  # Ambos bits son diferentes - 1111\nprint(f\"NOT: ~10 = {~10}\") # Invierte los bits 00001010 -> 11110101. En decimal es -(x+1)\nprint(f\"Desplazamiento a la derecha: 10 >> 2 = {10 >> 3}\")  # 0001\nprint(f\"Desplazamiento a la izquierda: 10 << 2 = {10 << 3}\")  # 1010000\n\n\n\"\"\"\nEstructuras de control\n\"\"\"\n\n#Condicionales\n#IF\nedad = 21\nif edad < 18:\n    print(\"Tarifa reducida por minoria de edad\")\nelif edad < 65:\n    print(\"Tarifa normal\")\nelse:\n    print(\"Tarifa reducida por mayor de 65\")\n\n# MATCH - CASE\n\ndia = \"sabado\"\n\nmatch dia:\n    case \"lunes\":\n        print(\"Primer dia de la semana\")\n    case \"viernes\":\n        print(\"Último día laborable\")\n    case \"sabado\" | \"domingo\":\n        print(\"Fin de semana\")\n    case _:\n        print(\"Dia normal\")\n\n\n#Iterativas\n\nfor num in range(11):\n    print(num)\n\ni = 0\nwhile i < 11:\n    print(i)\n    i += 1\n\n#Manejo de excepciones\n\na, b = 3, \"4\"\ntry:\n    print(f\"{a}/{b} = {int(a)/int(b)}\")\nexcept ZeroDivisionError as error:\n    print(error)\nexcept ValueError as error:\n    print(error)\n\n\"\"\"\nExtra\nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\"\"\"\nfor i in range(10,56,2):\n    if (i % 3) and i != 16:\n        print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/inf015.py",
    "content": "#EJERCICIO:\n#1 - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...(Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n\n\n#Operadores Aritméticos:\nnum1 = 5\nnum2 = 15\n\n#Suma: +\nprint(f'Suma de {num1} + {num2} = {num1 + num2}')\n\n#Resta: -\nprint(f'Resta de {num1} - {num2} = {num1 - num2}')\n\n#Multiplicación: *\nprint(f'Multiplicacion de {num2} * {num1} = {num2 * num1}')\n\n#División: /\nprint(f'Division de {num2} / {num1} = {num2 / num1}')\n\n#División entera: //\nprint(f'Division de {num2} // {num1} = {num2 // num1}')\n\n#Módulo (resto de la división): %\nprint(f'Modulo de {num2} / {num1} = {num2 % num1}')\n\n#Potenciación: **\nprint(f'Potencia de {num2} ** {num1} = {num2 ** num1}')\n\n#Operadores de Comparación (Relacionales):\n#Igual a: ==\nprint(f'Es igual  {num2} y {num1}?:  {num2 == num1}')\n\n#No igual a: !=\nprint(f'Es diferente  {num2} y {num1}?:  {num2 != num1}')\n\n#Mayor que: >\nprint(f'Es mayor  {num2} que {num1}?:  {num2 > num1}')\n\n#Menor que: <\nprint(f'Es menor  {num2} que {num1}?:  {num2 < num1}')\n\n#Mayor o igual que: >=\nprint(f'Es mayor o igual {num2} que {num1}?:  {num2 > num1}')\n\n#Menor o igual que: <=\nprint(f'Es menor o igual {num2} que {num1}?:  {num2 < num1}')\n\n#Operadores Lógicos:\nx = True\ny = False\n\n#Y lógico: and\nand_result = x and y\nprint(f\"AND: {and_result}\")\n\n#O lógico: or\nor_result = x or y\nprint(f\"OR: {or_result}\")\n\n\n#No lógico: not\nnot_result = not x\nprint(f\"NOT: {not_result}\")\n\n#Operadores de Asignación:\n#Asignación simple: =\n\nasig = 10\nprint(f\"asgnacion = {asig}\")\n#Suma y asignación: +=\nasig += 10\nprint(f\"asgnacion += {asig}\")\n\n#Resta y asignación: -=\nasig -= 5\nprint(f\"asgnacion -= {asig}\")\n\n#Multiplicación y asignación: *=\nasig *= 10\nprint(f\"asgnacion *= {asig}\")\n\n#División y asignación: /=\nasig /= 10\nprint(f\"asgnacion /= {asig}\")\n\n#División entera y asignación: //=\nasig //= 3.4\nprint(f\"asgnacion //= {asig}\")\n\n#Módulo y asignación: %=\nasig %= 100\nprint(f\"asgnacion %= {asig}\")\n\n#Potenciación y asignación: **=\nasig **= 3\nprint(f\"asgnacion **= {asig}\")\n\n\n#Operadores de Pertenencia:\nlist = [1,2,3,4,5]\n#Pertenencia en: in\nprint(4 in list)\nprint(7 in list)\n\n#No pertenencia en: not in\nprint(4 not in list)\nprint(7 not in list)\n#2 - Utilizando las operaciones con operadores que tú quieras, crea ejemplosque representen todos los tipos de estructuras de control que existanen tu lenguaje:Condicionales, iterativas, excepciones...\nx = 10\ny = 5\n\n#Estructuras de control condicionales:\nif x == y:\n    print(f\"{x} es igual que {y}\")\n\nelif x > y:\n    print(f\"{x} es mayor que {y}\")\n\nelse:\n    print(f\"{x} es menor que {y}\")\n\n#Bucles (Estructuras de control iterativas):\n#while\nwhile y <= x:\n    print(f\"imprimiendo con while {y}\")\n    y += 1\n\n#for\nfor list in list:\n    print(f\"lista usando for {list}\")    \n\n\n#3- Debes hacer print por consola del resultado de todos los ejemplos.\n\n\n'''\n DIFICULTAD EXTRA (opcional):\n Crea un programa que imprima por consola todos los números comprendidos\n entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\n Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n '''\n\nfor numero in range(10, 56):\n    if numero % 2 == 0 and numero != 16 and numero % 3 != 0:\n        print(numero)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/inkhemi.py",
    "content": "# Suma\nprint(f\"2 + 2 = {2 + 2}\")\n\n# Resta\nprint(f\"2 - 2 = {2 - 2}\")\n\n# Multiplicación\nprint(f\"2 * 2 = {2 * 2}\")\n\n# División\nprint(f\"2 / 2 = {2 / 2}\")\n\n# División entera\nprint(f\"2 // 2 = {2 // 2}\")\n\n# Módulo\nprint(f\"2 % 2 = {2 % 2}\")\n\n# Potencia\nprint(f\"2 ** 2 = {2 ** 2}\")\n\n# Operadores de comparación\n\n# Igualdad\nprint(f\"2 == 2: {2 == 2}\")\n\n# Desigualdad\nprint(f\"2 != 2: {2 != 2}\")\n\n# Mayor que\nprint(f\"2 > 2: {2 > 2}\")\n\n# Menor que\nprint(f\"2 < 2: {2 < 2}\")\n\n# Mayor o igual que\nprint(f\"2 >= 2: {2 >= 2}\")\n\n# Menor o igual que\nprint(f\"2 <= 2: {2 <= 2}\")\n\n# Operadores lógicos\n\n# AND\nprint(f\"True and False = {True and False}\")\n\n# OR\nprint(f\"True or False = {True or False}\")\n\n# NOT\nprint(f\"not True = {not True}\")\n\n# Operadores de asignación\n\n# Asignación\na = 2\nprint(f\"a = 2\")\n\n# Asignación con suma\nprint(f\"a += 2: {a + 2}\")\n\n# Asignación con resta\nprint(f\"a -= 2: {a - 2}\")\n\n# Asignación con multiplicación\nprint(f\"a *= 2: {a * 2}\")\n\n# Asignación con división\nprint(f\"a /= 2: {a / 2}\")\n\n# Asignación con división entera\nprint(f\"a //= 2: {a // 2}\")\n\n# Asignación con módulo\nprint(f\"a %= 2: {a % 2}\")\n\n# Asignación con potencia\nprint(f\"a **= 2: {a ** 2}\")\n\n# Operadores de identidad\n\n# is\nb = None\nprint(f\"b is None: {b is None}\")\nb = 1\nprint(\"b = 1\")\nprint(f\"b is None: {b is None}\")\n\n# is not\nprint(f\"b is not None: {b is not None}\")\n\n# Operadores de pertenencia\n\n# in\nprint(f\"2 in [1, 2, 3]: {2 in [1, 2, 3]}\")\n\n# not in\nprint(f\"2 not in [1, 2, 3]: {2 not in [1, 2, 3]}\")\n\n# Operadores de bits\n\n# AND\nprint(f\"2 & 2 = {2 & 2}\")\n\n# OR\nprint(f\"2 | 2 = {2 | 2}\")\n\n# XOR\nprint(f\"2 ^ 2 = {2 ^ 2}\")\n\n# NOT\nprint(f\"~2 = {~2}\")\n\n# Desplazamiento a la izquierda\nprint(f\"2 << 2 = {2 << 2}\")\n\n# Desplazamiento a la derecha\nprint(f\"2 >> 2 = {2 >> 2}\")\n\n# Estructuras de control\n\n# Condicionales\n\n# if\nif (2 + 2 == 4):\n    print(\"2 + 2 = 4\")\n\n# if else\nif (2 + 2 == 3):\n    print(\"2 + 2 = 3\")\nelse:\n    print(\"2 + 2 != 3\")\n\n# if elif else\nif (isinstance(2, str)):\n    print(\"2 es un string\")\nelif (isinstance(2, int)):\n    print(\"2 es un entero\")\nelse:\n    print(\"2 no es un string ni un entero\")\n\n# Iterativas\n\n# for\nfor number in range(1, 6):\n    print(number)\n\n# while\nnumber = 1\nwhile number < 6:\n    print(number)\n    number += 1\n\n# Excepciones\n\n# try except\ntry:\n    print(2 / 0)\nexcept ZeroDivisionError:\n    print(\"No se puede dividir entre 0\")\n\n# try except else\ntry:\n    print(2 / 2)\nexcept ZeroDivisionError:\n    print(\"No se puede dividir entre 0\")\nelse:\n    print(\"No se ha producido ninguna excepción\")\n\n# try except finally\ntry:\n    print(2 / 0)\nexcept ZeroDivisionError:\n    print(\"No se puede dividir entre 0\")\nfinally:\n    print(\"Se ejecuta siempre\")\n\n# try except else finally\ntry:\n    print(2 / 2)\nexcept ZeroDivisionError:\n    print(\"No se puede dividir entre 0\")\nelse:\n    print(\"No se ha producido ninguna excepción\")\nfinally:\n    print(\"Se ejecuta siempre\")\n\n# Dificultad extra\n\n# Lista de números prohibidos (múltiplos de 3, número 16 y pares)\nprohibited_numbers = [x for x in range(10, 56) if (\n    x % 3 == 0 or x == 16 or x % 2 != 0)]\n\nfor number in range(10, 56):\n    if number in prohibited_numbers:\n        continue\n    print(number)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/inmortalnight.py",
    "content": "# 01 - Python\n\n# Operadores\n# Aritméticos\nprint(f\"Suma: 10 + 5 = {10 + 5}\")\nprint(f\"Resta: 10 - 5 = {10 - 5}\")\nprint(f\"Multiplicación: 10 * 5 = {10 * 5}\")\nprint(f\"División: 10 / 5 = {10 / 5}\")\nprint(f\"División entera: 10 // 5 = {10 // 5}\")\nprint(f\"Residuo: 10 % 5 = {10 % 5}\")\nprint(f\"Potencia: 10 ** 5 = {10 ** 5}\")\n\n# Lógicos\nprint(f\"10 y 5 son mayores que 7? {10>7 and 5>7}\") # AND\nprint(f\"10 o 5 son mayores que 7? {10>7 or 5>7}\") # OR\nprint(f\"10 no es mayor que 7? {not 10>7}\") # NOT\n\n# Comparación\nprint(f\"10 es igual a 5? {10 == 5}\")\nprint(f\"10 es diferente a 5? {10 != 5}\")\nprint(f\"10 es mayor a 5? {10 > 5}\")\nprint(f\"10 es menor a 5? {10 < 5}\")\nprint(f\"10 es mayor o igual a 5? {10 >= 5}\")\nprint(f\"10 es menor o igual a 5? {10 <= 5}\")\n\n# Asignación\na = 10\nprint(f\"Valor de a: {a}\")\na += 5\nprint(f\"Valor de a al sumarle 5: {a}\")\na -= 5\nprint(f\"Valor de a al restarle 5: {a}\")\na *= 5\nprint(f\"Valor de a al multiplicarlo por 5: {a}\")\na /= 5\nprint(f\"Valor de a al dividirlo por 5: {a}\")\na //= 5\nprint(f\"Valor de a al dividirlo y redondearlo a la 5: {a}\")\na %= 5\nprint(f\"Valor de a al sacarle el residuo de dividirlo por 5: {a}\")\na **= 5\nprint(f\"Valor de a al elevarlo a la 5: {a}\")\n\n# Identidad\nmy_number = 10\nnew_variable = my_number \nprint(f\"my_number es igual a new_variable? {my_number is new_variable}\") #Comprobamos si my_number y new_variable son el mismo objeto\nnew_variable = 5\nprint(f\"my_number es igual a new_variable? {my_number is new_variable}\") #Comprobamos si my_number y new_variable son el mismo objeto\nprint(f\"my_number no es igual a new_variable? {my_number is not new_variable}\") #Comprobamos si my_number y new_variable no son el mismo objeto\n\n# Pertenencia\nmy_list = [1, 2, 3, 4, 5]\nprint(f\"1 está en la lista? {1 in my_list}\") # Comprobamos si 1 está en la lista\nprint(f\"6 no está en la lista? {6 not in my_list}\") # Comprobamos si 6 no está en la lista\n\n# Bit\nprint(f\"10 en binario: {bin(10)}\") #es 1010\nprint(f\"5 en binario: {bin(5)}\") #es 101\nprint(f\"10 & 5 = {10 & 5}\") # 1010 & 0101 = 0000, AND\nprint(f\"10 | 5 = {10 | 5}\") # 1010 | 0101 = 1111, OR\nprint(f\"10 ^ 5 = {10 ^ 5}\") # 1010 ^ 0101 = 1111, XOR\nprint(f\"~10 = {~10}\") # ~1010 = -1011, NOT\nprint(f\"10 << 2 = {10 << 2}\") # 1010 << 2 = 101000, Desplazamiento a la izquierda \n\n# Estructuras de control\n# Condicionales\nif 10 > 5:\n    print(\"10 es mayor que 5\")\nelif 10 == 5:\n    print(\"10 es igual a 5\")\nelse:\n    print(\"5 es mayor que 10\")\n\n# Iterativas\nfor i in range(5,10):\n    print(i)\n\n# Excepciones\ntry:\n    print(10 / 0)\nexcept:\n    print(\"Ha ocurrido un error\")\n\n# Extra: Programa que imprime los números entre 10 y 55, pares, que no son 16 ni múltiplos de 3\nfor i in range(10, 56):\n    if 16 != i and i % 2 == 0 and i % 3 != 0:\n        print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/ipfabio.py",
    "content": "\"\"\"\nAritméticos: + - * / //\n\"\"\"\n# Pide al usuario que ingrese 2 números y los asigna a las variables ´a' y 'b', con map les aplicamos a ambos la función int() para convertirlos en enteros y poder operarlos. (por default recibidos en string, por eso se parsea/convierte)\na, b = map(int, input(\"Ingresa 2 valores para los ejemplos de Operadores Aritméticos separados por espacio (Ej: 5 1): \").split())\n\n# Realizamos las operaciones.\nsuma = a + b\nresta = a - b\nmultiplicacion = a * b\ndivision = a / b\ndivision_entera = a // b\nmodulo = a % b\nexponente = a ** b\n\n# Imprimimos las operaciones mostrando un ejemplo de como se realiza con los valores 'a' y 'b'.\nprint(f\"Suma: {a} + {b} = {suma}\")\nprint(f\"Resta: {a} - {b} = {resta}\")\nprint(f\"Multiplicación: {a} * {b} = {multiplicacion}\")\nprint(f\"División: {a} / {b} = {division}\")\nprint(f\"Módulo: {a} % {b} = {modulo}\")\nprint(f\"Exponente: {a}**{b} = {exponente}\")\nprint(f\"Division entera: {a} // {b} = {division_entera}\")\n\n# Operadores de comparación\na, b = map(int, input(\"Ingresa dos valores para los ejemplos de Operadores de comparación separados por espacio (Ej: 10 3): \").split())\n\nigual = a == b\ndistinto = a != b\nmayor_que = a > b\nmenor_que = a < b\nmayor_igual = a >= b\nmenor_igual = a <= b\n\nprint(f\"Igualdad: {a} == {b} = {igual}\")\nprint(f\"Distintos: {a} != {b} = {distinto}\")\nprint(f\"Mayor que: {a} > {b} = {mayor_que}\")\nprint(f\"Menor que: {a} < {b} = {menor_que}\")\nprint(f\"Mayor o igual: {a} >= {b} = {mayor_igual}\")\nprint(f\"Menor o igual: {a}<={b} = {menor_igual}\")\n\n# Operadores Lógicos\na,b = map(int, input(\"Ingresa los primeros dos valores separados por un espacio (Ej: 10 3): \").split())\nc,d = map(int, input(\"Ingresa los otros dos valores a comprobar formato similar al anterior (Ej: 5 1): \").split())\n\n# Verdadero Ambos\nprint(f\"AND &&: {a} + {b} == {a + b} and {c} - {d} == {c - d} es: {a + b == a + b and c - d == c - d}\")\n# Verdadero Uno u Otro\nprint(f\"OR ||: {a} + {b} == {a + b} or {d} - {c} == {d - c} es: {a + b == a + b  or c - d == d - c}\")\n# No es\nprint(f\"NOT !: NOT {d} - {c} == {c - d} es: {not c - d == d - c}\")\n\n# Operadores de asignación\nmy_number = 11 # Asignación\nprint(f\"Base: {my_number}\")\nmy_number += 1 # Suma y asignación\nprint(f\"Suma y asignacion += 1 {my_number}\")\nmy_number -= 1 # Suma y asignación\nprint(f\"Resta y asignacion -= 1 {my_number}\")\nmy_number *= 2 # Suma y asignación\nprint(f\"Multiplicación y asignacion *= 2 {my_number}\")\nmy_number /=2  # Suma y asignación\nprint(f\"División y asignacion /= 1 {my_number}\")\nmy_number %= 2 # Suma y asignación\nprint(f\"Módulo y asignacion %= 2 {my_number}\")\nmy_number **= 1 # Suma y asignación\nprint(f\"Elevación y asignacion **= 1 {my_number}\")\nmy_number //= 1 # Suma y asignación\nprint(f\"División entera y asignacion //= 1 {my_number}\")\n\n# Operadores de identidad\nmy_new_number = my_number\n# Compara si son iguales basandose en la posición de memoria\nprint(f\"my_number is my_new_number es: {my_number is my_new_number}\")\nprint(f\"my_number is not my_new_number es: {my_number is not my_new_number}\")\n\n# Operadores de pertenencia\nprint(f\"'i' in 'Kirito' = {'i' in 'Kirito'} \")\nprint(f\"'u' in 'Kirito' = {'u' not in 'Kirito'} \")\n\n# Operadores de bit\na = 10 # 1010\nb = 3 # 0011\n\nprint(f\"AND: 10 & 3 = {10 & 3}\") # 0010\nprint(f\"OR: 10 | 3 = {10 | 3}\") # 1011 (Si al menos 1 es 1)\nprint(f\"XOR: 10 ^ 3 = {10 ^ 3}\") #1001 (Si son diferentes da 1, sino 0)\nprint(f\"XOR: ~10 = {~10}\") # (Intercambia el valor bit a bit de los elementos)\nprint(f\"Desplazamiento a la derecha: 10 >> 2 = {10 >> 2}\") # 10: 1010 >> 0010\nprint(f\"Desplazamiento a la derecha: 10 << 2 = {10 << 2}\") # 10: 1010 >> 101000\n\n\"\"\"\nEstructuras de control\n\"\"\"\n\n# Condicionales\n\nmy_string = \"Martes\"\n\nif my_new_number == \"Martes\":\n    print(\"Buen Martes para todos!\")\nelif my_string == \"Miercoles\":\n    print(\"Buen Miercoles para todos!\")\nelse:\n    print(\"Buena semana para todos!\")\n\n# Iterativas\nfor i in range(11):\n    print(i)\n\ni = 0\n\nwhile i <= 10:\n    print(i)\n    i += 1\n\n# Manejo de excepciones\ntry:\n    print(10 / 1)\nexcept:\n    print(\"Se ha producido un error\")\nfinally:\n    print(\"Hemos terminado el manejo de excepciones\")\n\n# Dificultad Extra\n#  * Crea un programa que imprima por consola todos los números comprendidos\n#  * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\nfor i in range(10,56):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/isilanes.py",
    "content": "# Operators:\nprint(\"Operadores aritméticos:\")\nprint(f\"1 + 1 = {1+1}\")\nprint(f\"1 - 1 = {1-1}\")\nprint(f\"2 * 2 = {2*2}\")\nprint(f\"6 / 2 = {6/2}\")\nprint(f\"6 // 2 = {6//2}\")\nprint(f\"7 % 2 = {7%2}\")\nprint(f\"2**3 = {2**3}\")\n\n# Logic:\nprint(\"\\nOperadores lógicos:\")\nprint(f\"not True = {not True}\")\nprint(f\"True and True = {True and True}\")\nprint(f\"True and False = {True and False}\")\nprint(f\"True or False = {True or False}\")\nprint(f\"False or False = {False or False}\")\n\n# Comparison:\nprint(\"\\nOperadores de comparación:\")\nprint(f\"1 == 1 = {1==1}\")\nprint(f\"1 != 1 = {1==1}\")\nprint(f\"1 > 1 = {1>1}\")\nprint(f\"1 >= 1 = {1>=1}\")\nprint(f\"1 < 1 = {1<1}\")\nprint(f\"1 <= 1 = {1<=1}\")\nprint(f\"1 < 2 < 3 = {1 < 2 < 3}\")\n\n# Assignment:\nprint(\"\\nOperadores de asignación:\")\na = 1\nprint(f\"a = 1 -> {a}\")\na += 1\nprint(f\"a += 1 -> {a}\")\na -= 1\nprint(f\"a -= 1 -> {a}\")\n\n# Identity:\nprint(\"\\nOperadores de identidad:\")\nprint(f\"None is None = {None is None}\")\nprint(f\"False is not None = {False is not None}\")\n\n# Membership:\nprint(\"\\nOperadores de pertenencia:\")\nprint(f\"1 in [1, 2, 3] = {1 in [1, 2, 3]}\")\nprint(f\"1 not in [4, 5, 6] = {1 not in [4, 5, 6]}\")\n\n# Bitwise:\nprint(\"\\nOperadores de bits:\")\nprint(f\"~0b1 = {bin(~0b1)}\")\nprint(f\"0b101 & 0b011 = {bin(0b101&0b011)}\")\nprint(f\"0b101 | 0b011 = {bin(0b101|0b011)}\")\nprint(f\"0b101 ^ 0b011 = {bin(0b101^0b011)}\")\nprint(f\"0b100 >> 2 = {bin(0b100>>2)}\")\nprint(f\"0b100 << 2 = {bin(0b100<<2)}\")\n\n# Control structures:\nprint(\"\\nCondicional:\")\nif 2 > 1:\n    print(\"2 es mayor que 1\")\nelse:\n    print(\"Nunca llegaremos aquí, porque 2 no es igual o menor que 1\")\n\nprint(\"\\nIteración con bucle for:\")\nfor i in range(3):\n    print(f\"ciclo {i}\")\n\nprint(\"\\nIteración con while:\")\na = 1\nwhile a < 3:\n    print(f\"{a} es menor que 3\")\n    a += 1\n\nprint(\"\\nExcepción:\")\ndenominator = input(\"Introduce un número: \")\ntry:\n    denominator = float(denominator)\nexcept ValueError:\n    print(f\"Chacho, has introducido un valor que no puede convertirse en float ({denominator})\")\n\ntry:\n    print(f\"1.0 / {denominator} = {1./denominator}\")\nexcept ZeroDivisionError:\n    print(f\"Pillín, introdujiste cero, y no puedo hacer la división\")\nexcept TypeError:\n    print(\"Como te dije, el valor introducido no es un número, así que omito la división\")\nfinally:\n    print(\"Habrás visto una división, si introdujiste un valor válido\")\n\n# Extra:\nprint(\"\\nTodos los pares entre 10 y 55 (inclusive), que no son ni 16 ni múltiplos de 3:\")\nfor i in range(10, 56, 2):\n    if not i % 3 or i == 16:\n        continue\n\n    print(i)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/ivangdev.py",
    "content": "# Suma\nsuma = 10 + 10\nprint(\"Suma:\", suma)\n\n# Resta\nresta = 10 - 5\nprint(\"Resta:\", resta)\n\n# Multiplicacion\nmultiplicacion = 10 * 5\nprint(\"Multiplicacion:\", multiplicacion)\n\n# Division\ndivision = 10 / 2\nprint(\"Division:\", division)\n\n# Modulo\nmodulo = 10 % 3\nprint(\"Modulo:\", modulo)\n\n# Potencia\npotencia = 2**3\nprint(\"Potencia:\", potencia)\n\n# --------------------------- Comparacion---------------------------\n\nif 1 == 1:\n    print(\"1 es igual a 1\")\nif 5 > 4:\n    print(\"5 es mayor que 4\")\nif 3 < 4:\n    print(\"3 es menor que 4\")\nif 7 >= 6:\n    print(\"7 es mayor o igual que 6\")\nif 1 <= 2:\n    print(\"1 es menor o igual que 2\")\nif 3 != 2:\n    print(\"3 es distinto de 2\")\n\n# ------------------------------ Logicos -------------------------\nA = 3\nB = 2\nif A > B and isinstance(A, int):\n    print(\"A es mayor que B y A es un entero\")\n\nif A > B or B > A:\n    print(\"A es mayor que B o B es mayor que A\")\n\nif not A == B:\n    print(\"A no es igual a B\")\n# ------------------------------ Asignacion ------------\nC = 5\nprint(\"Valor inicial de C:\", C)\nC += 2\nprint(\"Despues de sumar 2:\", C)\nC -= 1\nprint(\"Despues de restar 1:\", C)\nC *= 3\nprint(\"Despues de multiplicar por 3:\", C)\nC /= 2\nprint(\"Despues de dividir entre 2:\", C)\nC %= 2\nprint(\"Despues de aplicar modulo 2:\", C)\nC **= 2\n\n# ----------------- Operadores a nivel de Bits -----------------\n\n# & es un AND lógico pero aplicado a cada bit del número\na = 3\nb = 3\na &= B\nprint(a)\n\n# |=   # OR a nivel de bits y asigna\na |= B\nprint(a)\n\n# ^=   # XOR a nivel de bits y asigna\na ^= B\nprint(a)\n\n# >>=  # corrimiento a la derecha y asigna\na = 8\na >>= 1\nprint(a)\n\n# <<=  # corrimiento a la izquierda y asigna\na <<= 1\nprint(a)\n\n# ----------------- Operadores de Identidad -----------------\nx = [\"a\", \"b\", \"c\"]\ny = x\nz = [\"a\", \"b\", \"c\"]\n\nprint(x is y)\nprint(x is z)\nprint(x is not z)  # No son el mismo objeto\n\n# ----------------- Operadores de Pertenencia -----------------\n\nnumeros = [1, 2, 3, 4, 5]\nprint(3 in numeros)\nprint(6 in numeros)\nprint(\"b\" in \"base\")\nprint(\"z\" not in \"base\")  # Z no aparece en casa\n\n\n# ----------------- Estructuras de control ------------------\nif 6 > 5:\n    print(\"6 es mayor que 5\")\nelif 8 == 8:\n    print(\"8 no es igual a 8\")\nelse:\n    print(\"6 no es mayor que 5\")\n\nfor i in range(5):\n    print(\"Iteracion:\", i)\n\nwhile i <= 5:\n    print(\"i es menor que 5\")\n    i += 1\n\n# ---------------- Iterativas -----------------------------\n# for\n# while\n# break, continue, pass, else\n\nfor numero in numeros:\n    print(numero)\n\ni = 0\nwhile i < len(numeros):\n    print(numeros[i])\n    i += 1\n\nnums = [1, 2, 3, 4, 5, 8, 9, 0]\nfor numero in nums:\n    if numero < 0:\n        print(\"Es negativo\")\n        break\n    elif numero == 0:\n        print(\"Es 0, continuamos...\")\n        continue\n    elif numero % 2 == 0:\n        print(\"Es par\")\n        pass\nelse:\n    print(\"No hay negativos\")\n\n\n# ---------------- excepciones -----------------------------\n# try ... except\ntexto = \"hola\"\ntry:\n    d = int(texto)\nexcept ValueError:\n    print(\"Error: Imposible convertir en numero\")\n\n# try ... except ... else\ng = 5\ntry:\n    d = int(g)\nexcept ValueError:\n    print(\"Error: Imposible convertir en numeroo\")\nelse:\n    print(\"Conversion correcta, x =\", g)\n\n# try ... except ... finally\ntry:\n    d = int(texto)\nexcept ValueError:\n    print(\"Error: Imposible convertir en numero\")\nfinally:\n    print(\"Se termino el intento de conversion\")\n\n# raise → lanzar excepciones\na = \"hola\"\n# try:\n#     numero = int(a)\n# except ValueError:\n#     raise ValueError(\"No se puede convertir a entero\")\n\n\n# ---------------- Otras -----------------------------\n# match - case\nopcion = 1\nmatch opcion:\n    case 1:\n        print(\"Opcion 1\")\n    case 2:\n        print(\"Opcion 2\")\n    case 3:\n        print(\"Opcion 3\")\n    case _:\n        print(\"Opcion no valida\")\n\n\n# ---------------- DIFICULTAD EXTRA (opcional): -----------------------------\n#\n#  * Crea un programa que imprima por consola todos los números comprendidos\n#  * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\nnumeros = range(10, 56)\nfor numero in numeros:\n    if numero % 2 == 0:\n        if numero == 16:\n            continue\n        if numero % 3 == 0:\n            continue\n        print(numero)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/jaldana1006.py",
    "content": "\"\"\"\nOperadores\n\"\"\"\n\n#Operadores aitmeticos \nprint(f\"Suma: 10 + 3 = {10 + 3}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/javierfiestasbotella.py",
    "content": "'''EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */'''\n\nfor i in range(10,56):\n    if i%2==0 and i!=16 and i%3!=0:\n        print(i)\n\na=1\nb=2\nc=3\n\nif a>b:\n    print(f'{a} es mayor a {b}')\nelif a<b:\n        print(f'{b} es mayor a {a}')\nelse:\n     print(f'{a} y {b} son iguales')\n\nprint(f'asi se imprime boleano si le digo que b es par de la manera\\n b%2==0 me imprime: {b%2==0}')\nprint(f'si divido dos numeros enteros me da un numero float que representaré imprimiendo el tipo con type(b/2): {type(b/2)}')"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/javierjoyera.py",
    "content": "print(\"01 - Python\")\n#Operadores aritméticos\nmy_first_value = 8\nmy_second_value = 3\nprint(\"-----------------------\")\nprint(\"OPERADORES ARITMÉTICOS\")\nprint(\"-----------------------\")\n# Suma\nmy_suma = my_first_value + my_second_value\nprint(\"Suma: %d + %d =  %d\" % (my_first_value, my_second_value ,my_suma))\n\n# Resta\nmy_resta = my_first_value - my_second_value\nprint(\"Resta: %d - %d =  %d\" % (my_first_value, my_second_value ,my_resta))\n\n# Multiplicación\nmy_multiplicacion = my_first_value * my_second_value\nprint(\"Multiplicación: %d * %d =  %d\" % (my_first_value, my_second_value ,my_multiplicacion))\n\n# División\nmy_division = my_first_value / my_second_value\nprint(\"División: %d / %d =  %d\" % (my_first_value, my_second_value ,my_division))\n\n# División entera\nmy_division_entera = my_first_value // my_second_value\nprint(\"División Entera: %d // %d =  %d\" % (my_first_value, my_second_value ,my_division_entera))\n\n# Módulo\nmy_modulo = my_first_value % my_second_value\nprint(\"Módulo: %d %% %d =  %d\" % (my_first_value, my_second_value ,my_modulo))\n\n# Potencia\nmy_potencia = my_first_value ** my_second_value\nprint(\"Potencia: %d ** %d =  %d\" % (my_first_value, my_second_value ,my_potencia))\n\n#Operadores de comparación Se puede realizar con números y cadenas de texto\nprint(\"-----------------------\")\nprint(\"OPERADORES DE COMPARACIÓN\")\nprint(\"-----------------------\")\n# Igualdad ==\nmy_igualdad = my_first_value == my_second_value\nmy_igualdad_string = \"Hola\" == \"HolaPython\"\nprint(\"Igualdad: %d == %d =  %s\" % (my_first_value, my_second_value ,my_igualdad))\n\n# Desigualdad != \nmy_desigualdad = my_first_value != my_second_value\nmy_desigualdad_string = \"Hola\" != \"HolaPython\"\nprint(\"Desigualdad: %d != %d =  %s\" % (my_first_value, my_second_value ,my_desigualdad))\n\n# Mayor que >\nmy_mayor_que = my_first_value > my_second_value\nprint(\"Mayor que: %d > %d =  %s\" % (my_first_value, my_second_value ,my_mayor_que))\n\n# Menor que <\nmy_menor_que = my_first_value < my_second_value\nprint(\"Menor que: %d < %d =  %s\" % (my_first_value, my_second_value ,my_menor_que))\n\n# Mayor o igual que >=\nmy_mayor_igual_que = my_first_value >= my_second_value\nprint(\"Mayor o igual que: %d >= %d =  %s\" % (my_first_value, my_second_value ,my_mayor_igual_que))\n\n# Menor o igual que <=\nmy_menor_igual_que = my_first_value <= my_second_value\nprint(\"Menor o igual que: %d <= %d =  %s\" % (my_first_value, my_second_value ,my_menor_igual_que))\n\n#Operadores lógicos (AND, OR, NOT)\nprint(\"-----------------------\")\nprint(\"OPERADORES LÓGICOS\")\nprint(\"-----------------------\")\nmy_and = True and False\nprint(\"AND: %s\" % my_and)\n\nmy_or = True or False\nprint(\"OR: %s\" % my_or)\n\nmy_not = not True\nprint(\"NOT: %s\" % my_not)\n\n#Operadores de asignación\nprint(\"-----------------------\")\nprint(\"OPERADORES DE ASIGNACIÓN\")\nprint(\"-----------------------\")\nmy_asignacion = 2\nprint(\"Asignación: %d\" % my_asignacion)\n\nmy_asignacion += 2\nprint(\"Asignación +=: %d\" % my_asignacion)\n\nmy_asignacion -= 2\nprint(\"Asignación -=: %d\" % my_asignacion)\n\nmy_asignacion *= 2\nprint(\"Asignación *=: %d\" % my_asignacion)\n\nmy_asignacion /= 2\nprint(\"Asignación /=: %d\" % my_asignacion)\n\nmy_asignacion **= 2\nprint(\"Asignación **=: %d\" % my_asignacion)\n\nmy_asignacion %= 2\nprint(\"Asignación %%=: %d\" % my_asignacion)\n\nmy_asignacion //= 2\nprint(\"Asignación //=: %d\" % my_asignacion)\n\n#Operadores de identidad\nprint(\"-----------------------\")\nprint(\"OPERADORES DE IDENTIDAD\")\nprint(\"-----------------------\")\nmy_number = 2\n\nmy_is = my_number is 2\nprint(\"Is: %s\" % my_is)\n\nmy_is_not = my_number is not 2\nprint(\"Is not: %s\" % my_is_not)\n\n#Operadores de Pertenencia\nprint(\"-----------------------\")\nprint(\"OPERADORES DE PERTENENCIA\")\nprint(\"-----------------------\")\nmy_list = [1,2,3,4,5]\nprint(my_list)\nmy_in = 1 in my_list\nprint(\"1 IN my_list: %s\" % (my_in))\nmy_not_in = 3 not in my_list\nprint(\"3 NOT IN my_list: %s\" % (my_not_in))\n\n\n#Condicionales\nprint(\"-----------------------\")\nprint(\"CONDICIONALES\")\nprint(\"-----------------------\")\n\nmy_var = 34 \nmy_var2 = 45\n\nprint(\"my_var: %d\" % my_var)\nprint(\"my_var2: %d\" % my_var2)\n\nif(my_var>my_var2):\n    print(\"La variable my_var es mayor que my_var2\")\nelif(my_var==my_var2):\n    print(\"La variable my_var es igual que my_var2\")\nelse:\n    print(\"La variable my_var es menor que my_var2\")\n\n#Bucles\nprint(\"-----------------------\")\nprint(\"BUCLES\")\nprint(\"-----------------------\")\n\n#Bucle for\n\nfor i in range(1,10):\n    print(\"Esto es un bucle for: %d\" % i)\n\n#Bucle while\nmy_new_var = 0\nwhile(my_new_var<10):\n    print(\"Esto es un bucle while: %d\" % my_new_var)\n    my_new_var += 1\n\n# Estructura de control de excepciones\nprint(\"-----------------------\")\nprint(\"EXCEPCIONES\")\nprint(\"-----------------------\")\n\nmy_first_value = 10\nmy_second_value = 0\n\n# Intentamos realizar una división que causará una excepción de división por cero\ntry:\n    resultado = my_first_value / my_second_value\nexcept ZeroDivisionError as e:\n    print(\"Error: %s. No se puede dividir por cero.\" % e)\nelse:\n    print(\"Resultado: %d\" % resultado)\nfinally:\n    print(\"Fin del programa\")\n\n\n#PARTE OPCIONAL\nprint(\"-----------------------\")\nprint(\"PARTE OPCIONAL\")\nprint(\"-----------------------\")\n\nprint(\"Imprimimos por consola los números comprendidos entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3\")\nfor numero in range(10, 56):\n    if numero % 2 == 0 and numero != 16 and numero % 3 != 0:\n        print(numero)\n\nprint(\"-----------------------\")\nprint(\"FIN DEL EJERCICIO 01 - PYTHON\")\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/javirub.py",
    "content": "'''\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n'''\n\n#Operadores aritméticos\ndef arithmetic(a, b):\n    print(f'La suma de {a} + {b} es {a + b}')\n    print(f'La resta de {a} - {b} es {a - b}')\n    print(f'La multiplicación de {a} * {b} es {a * b}')\n    print(f'La división de {a} / {b} es {a / b}')\n    print(f'El módulo entre {a} y {b} es {a % b}')\n    print(f'El resultado de {a}^{b} es {a ** b}')\n    print(f'La división entera de {a} y {b} es {a // b}')\nprint('Probando función de operadores aritmeticos:')\narithmetic(5, 12)\nprint()\n\n#Operadores lógicos\ndef logic(a, b, c):\n    if a > c and b > c: print(f'{a} y {b} son mayores que {c}')\n    elif a > c or b > c: print(f'{a} o {b} es mayor que {c}')\n    elif not a > c and not b > c: print(f'{a} y {b} son menores que {c}')\n\nprint('Probando la función de operadores lógicos:')\nlogic(10, 12, 6)\nlogic(10, 12, 11)\nlogic(10, 12, 20)\nprint()\n\n#Operadores de comparación\ndef comparison(a,b):\n    if a == b: print(f'{a} es igual a {b}')\n    if a != b: print(f'{a} es distinto a {b}')\n    if a > b: print(f'{a} es mayor que {b}')\n    if a < b: print(f'{a} es menor que {b}')\n    if a >= b: print(f'{a} es mayor o igual que {b}')\n    if a <= b: print(f'{a} es menor o igual que {b}')\n\nprint('Probando la función de operadores de comparación:')\ncomparison(16, 12)\ncomparison(16,16)\ncomparison(12, 16)\nprint()\n\n#Operadores de asignación\ndef assignment(a,b,symbol):\n    if symbol == '=': result = b\n    if symbol =='+=': result = a + b\n    if symbol =='-=': result = a - b\n    if symbol =='*=': result = a * b\n    if symbol =='/=': result = a / b\n    if symbol == '%=': result = a % b\n    if symbol == '//=': result = a // b\n    if symbol == '**=': result = a ** b\n    if symbol == '&=': result = a & b\n    if symbol == '|=': result = a | b\n    if symbol == '^=': result = a ^ b\n    if symbol == '>>=': result = a >> b\n    if symbol == '<<=': result = a << b\n    print(f'a {symbol} b; a = {result}')\n\nprint('Probando la función de operadores de asignación con a=5 y b=12:')\nassignment(5, 12, '=')\nassignment(5, 12, '+=')\nassignment(5, 12, '-=')\nassignment(5, 12, '*=')\nassignment(5, 12, '/=')\nassignment(5, 12, '%=')\nassignment(5, 12, '//=')\nassignment(5, 12, '**=')\nassignment(5, 12, '&=')\nassignment(5, 12, '|=')\nassignment(5, 12, '^=')\nassignment(5, 12, '>>=')\nassignment(5, 12, '<<=')\nprint()\n\n#Operadores de identidad\ndef identity(a,b):\n    print(f'{a} es lo mismo que {b}? {a is b}')\n    print(f'{a} es distinto a {b}? {a is not b}')\n\nprint('Probando la función de operadores de identidad:')\nidentity(1,1)\nprint()\n\n#Operadores de pertenencia\ndef membership(a, b):\n    print(f'{a} pertenece a {b}? {a in b}')\n    print(f'{a} no pertenece a {b}? {a not in b}')\n\nprint('Probando la función de operadores de pertenencia:')\nmembership('platano', ['fresa', 'manzana', 'platano'])\nmembership('platano', ['fresa', 'manzana', 'banana'])\nprint()\n\n#Operadores de bits\ndef bitwise(a, b, c=2):\n    print(f'El operador & (AND), devuelve 1 en la posición donde ambos bits de los distintos valores son 1: {bin(a)} & {bin(b)} = {bin(a & b)}; {a} & {b} = {a & b}')\n    print(f'El operador | (OR), devuelve 1 donde al menos uno de los dos bits de los distintos valores es 1: {bin(a)} | {bin(b)} = {bin(a | b)}; {a} | {b} = {a | b}')\n    print(f'El operador ^ (XOR, exclusive or), devuelve 1 solo si uno de los dos valores es 1: {bin(a)} ^ {bin(b)} = {bin(a ^ b)}; {a} ^ {b} = {a ^ b}')\n    print(f'El operador ~ (NOT), invierte todos los bits: ~{bin(a)} = {bin(~a)} ; ~{bin(b)} = {bin(~b)}; ~{a} = {~a}; ~{b} = {~b}')\n    print(f'El operador << (Zero fill left shift), desplaza hacia la izquierda añadiendo 0 a la derecha y deja que los bits más a la izquierda caigan: {bin(a)} << {c} = {bin(a << c)}; {bin(b)} << {c} = {bin(b << c)}; {a} << {c} = {a << c}; {b} << {c} = {b << c}')\n    print(f'El operador >> (Signed right shift), desplaza hacia la derecha añadiendo 0 a la izquierda y deja que los bits más a la derecha caigan: {bin(a)} >> {c} = {bin(a >> c)}; {bin(b)} >> {c} = {bin(b >> c)}; {a} >> {c} == {a >> c}; {b} >> {c} = {b >> c}')\n\nprint('Probando la función de operadores de bits:')\nbitwise(28, 31)\n\nprint()\n\n#Ejercicio opcional\n\nprint('Ejercicio opcional; Todos los números pares que no son multiples de 3 ni son el 16 entre 10 y 55 incluidos:')\nfor i in range(10, 55, 2):\n    if (i != 16) & (i %3 != 0):\n        print(i)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/javitron100.py",
    "content": "# OPERADORES  Y ESTRUCTURAS DE CONTROL\r\n\r\n# Operadores aritméticos\r\nsuma = 10 + 5\r\nresta = 18 - 4\r\nmultiplicacion = 8 * 11\r\ndivision = 120 / 3\r\n\r\nprint(f\"El resultado de la suma es {suma}\")\r\nprint(f\"El resultado de la resta es {resta}\")\r\nprint(f\"El resultado de la multiplicación es {multiplicacion}\")\r\nprint(f\"El resultado de la división es {division}\")\r\n\r\n\r\n# Operadores lógicos\r\nverdadero = True\r\nfalso = False\r\n\r\nresultado = verdadero and verdadero\r\nprint (f\"Verdadero y Verdadero es igual a {resultado}\")\r\nresultado = verdadero or falso\r\nprint(f\"Veradero o Falso es igual a {resultado}\")\r\nresultado = not verdadero\r\nprint(f\"No verdadero es igual a {resultado}\")\r\n\r\n\r\n# Operadores de comparación\r\nresultado = 7 > 8\r\nprint(f\"7 es mayor que 8? {resultado}\")\r\nresultado = 10 < 20\r\nprint(f\"10 es menor que 20? {resultado}\")\r\nresultado = 26 <= 29\r\nprint(f\"26 es menor o igual que 29? {resultado}\")\r\nresultado = 34 >= 104\r\nprint (f\"34 es mayor o igual que 104? {resultado}\")\r\nresultado = 56 == 56\r\nprint(f\"56 es igual a 56? {resultado}\")\r\nresultado = 77 != 77\r\nprint(f\"77 es distinto de 77? {resultado}\")\r\n\r\n\r\n# Operadores de asignación\r\nnumero = 17\r\n\r\nnumero+=2\r\nprint(f\"El valor actual de la variable número es {numero}\")\r\nnumero-=2\r\nprint(f\"El valor actual de la variable número es {numero}\")\r\nnumero*=2\r\nprint(f\"El valor actual de la variable número es {numero}\")\r\nnumero/=2\r\nprint(f\"El valor actual de la variable número es {numero}\")\r\n\r\n\r\n# Operadores de identidad\r\nobjeto1 = 10\r\nobjeto2 = [12, 14]\r\n\r\nprint(f\"Objeto1 es Objeto2? {objeto1 is objeto2}\")\r\nprint(f\"Objeto1 no es Objeto2? {objeto1 is not objeto2}\")\r\n\r\n\r\n# Operadores de pertenencia\r\nprint(f\"17 está en [1, 14, 17, 34]? {17 in [1, 14, 17, 34]}\")\r\nprint(f\"17 no está en [1, 14, 17, 34]? {17 not in [1, 14, 17, 34]}\")\r\n\r\n\r\n# Operadores binarios\r\nnumero1 = 16\r\nnumero2 = 128\r\n\r\nprint(f\"El binario de numero1 y numero2 es {bin(numero1 & numero2)}\")\r\nprint(f\"El binario de numero1 o numero2 es {bin(numero1 | numero2)}\")\r\nprint(f\"El binario de not numero1 es {bin(~numero1)}\")\r\nprint(f\"El binario de numero1 xor numero2 es {bin(numero1 ^ numero2)}\")\r\n\r\n\r\n# Condicionales\r\nn1 = 33\r\nn2 = 46\r\n\r\nif n1 == n2:\r\n    print(f\"El número {n1} es igual al número {n2}\")\r\nelse:\r\n    print(f\"El número {n1} es distinto al número {n2}\")\r\n\r\n\r\n# For\r\nlista = [0, 1, 2, 3, 4, 5]\r\n\r\nfor elemento in lista:\r\n    print(elemento)\r\n\r\n\r\n# While\r\nrepeticiones = 1\r\n\r\nwhile repeticiones < 11:\r\n    print(f\"Ejecución del bucle while {repeticiones}\")\r\n    repeticiones += 1\r\n\r\n\r\n# Ejercicio extra\r\nfor i in range(10, 56):\r\n    if (i % 2 == 0) and (i != 16) and (i % 3 != 0):\r\n        print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/jcdm60.py",
    "content": "# #01 OPERADORES Y ESTRUCTURAS DE CONTROL\n#### Dificultad: Fácil | Publicación: 02/01/24 | Corrección: 08/01/24\n\n## Ejercicio\n\n#\n# EJERCICIO:\n# - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n#   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n#   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n# - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n#   que representen todos los tipos de estructuras de control que existan\n#   en tu lenguaje:\n#   Condicionales, iterativas, excepciones...\n# - Debes hacer print por consola del resultado de todos los ejemplos.\n#\n# DIFICULTAD EXTRA (opcional):\n# Crea un programa que imprima por consola todos los números comprendidos\n# entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n#\n# Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n#\n\n# OPERADORES ARITMÉTICOS\n# Suma\nprint(2 + 3)  \n\n# Resta\nprint(15 - 7)  \n\n# Multiplicación\nprint(8 * 6)  \n\n# División\nprint(18 / 3)  \n\n# División entera\nprint(19 // 5)  \n\n# Módulo\nprint(17 % 7)  \n\n# Potencia\nprint(2 ** 4)  \n\n# OPERADORES DE COMPARACION\n# Igualdad\nprint(3 == 3)  \n\n# Desigualdad\nprint(14 != 5)  \n\n# Mayor que\nprint(13 > 10)  \n\n# Menor que\nprint(4 < 9)  \n\n# Mayor o igual que\nprint(22 >= 22)  \n\n# Menor o igual que\nprint(7 <= 9)\n\n# OPERADORES LOGICOS\n# AND lógico\nprint(True and False)  \n\n# OR lógico\nprint(True or False)  \n\n# NOT lógico\nprint(not True)\n\n# OPERADORES DE ASIGNACION\nx = 7\nprint(x)\n\nx += 2  # Equivalente a x = x + 3\nprint(x)\n\nx -= 2  # Equivalente a x = x - 2\nprint(x)\n\nx *= 4  # Equivalente a x = x * 4\nprint(x)\n\nx /= 2  # Equivalente a x = x / 2\nprint(x)\n\n# OPERADORES DE IDENTIDAD\na = [1, 2, 3]\nb = a\nc = [1, 2, 3]\n\nprint(a is b)  # True, ya que 'a' y 'b' apuntan al mismo objeto\nprint(a is not c)  # True, ya que 'a' y 'c' no apuntan al mismo objeto\n\n# OPERADORES DE PERTENENCIA\nlista = [1, 2, 3, 4, 5]\n\nprint(2 in lista)  # True, ya que 2 está en la lista\nprint(6 not in lista)  # True, ya que 6 no está en la lista\n\n# OPERADORES A NIVEL DE BITS\n# AND a nivel de bits\nprint(5 & 3)\n\n# OR a nivel de bits\nprint(5 | 3)\n\n# XOR a nivel de bits\nprint(5 ^ 3)\n\n# Desplazamiento a la derecha\nprint(10 >> 1)\n\n# Desplazamiento a la izquierda\nprint(10 << 1)\n\n\n# ESTRUCTURAS DE CONTROL\n# CONDICIONALES\n# If-else\nx = 10\nif x > 5:\n    print(\"x es mayor que 5\")\nelse:\n    print(\"x es menor o igual que 5\")\n\n# If-elif-else\ny = 20\nif y > 25:\n    print(\"y es mayor que 25\")\nelif y == 25:\n    print(\"y es igual a 25\")\nelse:\n    print(\"y es menor que 25\")\n\n# ITERATIVAS\n# Bucle for\nfor i in range(8):\n    print(i)\n\n# Bucle while\nnum = 0\nwhile num < 8:\n    print(num)\n    num += 1\n\n# EXCEPCIONES\n# Bloque try-except\ntry:\n    resultado = 10 / 0\nexcept ZeroDivisionError:\n    print(\"¡Error! División entre cero.\")\n\n# EJERCICIO OPCIONAL\n# Imprimir los números que cumplen con las condiciones dadas\nfor num in range(10, 56):\n    if num % 2 == 0 and num != 16 and num % 3 != 0:\n        print(num)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/jesusgdev.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\"\"\"\n\n# 1. Tipos de operadores en Python\n\n# Aritméticos\na = 8\nb = 5\n\n# operadore suma\nsuma = a + b\nprint(suma) # 13\n\n# operadore resta\nresta = a - b\nprint(resta) # 3\n\n# operadore multiplicación\nmultiplicacion = a * b\nprint(multiplicacion) # 40\n\n# operadore división\ndivision = a / b\nprint(division) # 1.6\n\n# operadore división entera\ndivision_entera = a // b\nprint(division_entera) # 1\n\n# operadore módulo\nmodulo = a % b\nprint(modulo) # 3\n\n# operadore potencia\npotencia = a ** b\nprint(potencia) # 32768\n\n# Lógicos\nx = True\ny = False\n\nprint(x and y)  # False\nprint(x or y)   # True\nprint(not x)    # False\n\n# Comparación\na = 5\nb = 7\nprint(a == b)  # False\nprint(a != b)  # True\nprint(a > b)   # False\nprint(a < b)   # True\nprint(a >= b)  # False\nprint(a <= b)  # True\n\n# Asignación\nc = 9\nc += 1  # c = c + 1\nprint(c)  # 10\nc -= 2  # c = c - 2\nprint(c)  # 8\nc *= 2  # c = c * 2\nprint(c)  # 16\nc /= 4  # c = c / 4\nprint(c)  # 4.0\nc //= 2  # c = c // 2\nprint(c)  # 2.0\nc %= 2  # c = c % 2\nprint(c)  # 0.0\nc **= 3  # c = c ** 3\nprint(c)  # 0.0\n\n# Identidad\nx = [1, 2, 3]\ny = x\nz = [1, 2, 3]\n\nprint(x is y)  # True, porque y es una referencia al mismo objeto que x\nprint(x is z)  # False, porque z es un objeto diferente aunque tenga el mismo contenido\nprint(x is not z)  # True, porque z es un objeto diferente\nprint(x == z)  # False, porque a y b son diferentes objetos\n\n# Pertenencia\nlista = [1, 2, 3, 4, 5]\nprint(3 in lista)  # True, porque 3 está en la lista\nprint(6 not in lista)  # True, porque 6 no está en la lista \n\n# Bits\na = 5  # 0101 en binario\nb = 3  # 0011 en binario\nprint(a & b)  # 1, porque 0101 & 0011 = 0001\nprint(a | b)  # 7, porque 0101 | 0011 = 0111\nprint(a ^ b)  # 6, porque 0101 ^ 0011 = 0110\nprint(~a)     # -6, porque ~0101 = 1010 (en complemento a dos)\nprint(a << 1)  # 10, porque 0101 << 1 = 1010\nprint(a >> 1)  # 2, porque 0101 >> 1 = 0010\n\n# 2. Estructuras de control en Python\n\n# Condicionales\nedad = 20\nif edad < 18:\n    print(\"Eres menor de edad\")\nelif edad < 65:\n    print(\"Eres adulto\")\nelse:\n    print(\"Eres mayor de edad\")\n# Iterativas (for y while)\n# Bucle for\nfor i in range(5):\n    print(f\"Bucle for: {i}\")\n\n# Bucle while\ncontador = 0\nwhile contador < 5:\n    print(f\"Bucle while: {contador}\")\n    contador += 1\n\n# Control de flujo: break y continue\nfor i in range(10):\n    if i == 5:\n        break  # Sale del bucle cuando i es 5\n    print(f\"Break ejemplo: {i}\")\nfor i in range(10):\n    if i % 2 == 0:\n        continue  # Salta a la siguiente iteración si i es par\n    print(f\"Continue ejemplo: {i}\")\n\n# Manejo de excepciones\ntry:\n    resultado = 10 / 0\nexcept ZeroDivisionError:   \n    print(\"Error: División por cero\")\nelse:\n    print(\"División exitosa\")\nfinally:\n    print(\"Bloque finally ejecutado\")\n\n# DIFICULTAD EXTRA (opcional)\n'''\n1. Numeros entre 10 y 55\n2. pares excepto el 16\n3. Que no sean multiplos de 3\n'''\nfor i in range(10, 56):\n    if (i % 2 == 0 and i != 16) and i % 3 != 0:\n        print(i)   \n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/jesusway69.py",
    "content": "import os\nos.system('clear') #MAC/LINUX\n#os.system('cls') #WINDOWS\n\n\n\"\"\"\n* EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\"\"\"\n\n\n#CONDICIONALES CON OPERADORES DE COMPARACIÓN\n\nmi_numero = int(input('Escriba un número: '))\n\nif mi_numero > 10:\n   print (\"Tu número es mayor de 10\")\nelif mi_numero == 10:\n   print (\"Tu número es 10\")\nelse:\n   print(\"Tu número es menor a 10\") \n\nif mi_numero % 2 == 0:\n   print(\"Tu número es par\") \nelif mi_numero % 2 != 0:\n   print(\"Tu número es impar\")\nif mi_numero % 5 == 0:\n   print(\" y múltiplo de 5\") \n\n\n\n\n#OPERADORES ARITMÉTICOS ENTRE 2 NÚMEROS:\n   \nmi_otro_numero =  int(input('Escriba otro número: '))\nprint (\"Tu primer número y tu segundo número suman:\" , (mi_numero + mi_otro_numero))\nprint (\"Tu primer número menos tu segundo número es:\" , (mi_numero - mi_otro_numero))\nprint (\"Tu primer número multiplicado por tu segundo número es:\" , (mi_numero * mi_otro_numero))\nprint (\"Tu primer número dividido por tu segundo número es:\" , (mi_numero / mi_otro_numero))\n\n\n\n#ESTRUCTURAS DE CONTROL:\n\ncondicion = True\nif condicion:\n print(\"se ejecuta la condición si es true\")\n\n#Si aquí hay un else entra por él si condición es false y no entra al siguiente if\n\n condicion = 5*2\nif condicion == 10:\n     print ('se ejecuta la condicion del segundo if')\n\n     print (\"la ejecución continúa\")\n\ncondicion=0\nwhile condicion<100:\n    print(condicion)\n    condicion += 11\n    if condicion==55:\n     print ('hemos cortado la ejecución en', condicion)\n     break\n     \"\"\"con break el programa finaliza al cumplirse la condición del if,\n       sino continúa hasta cumplirse la condición del while-else\"\"\"\n     \nelse:\n    print(\"ya ha llegado a\" , condicion)\n\n\n\n\n\n#CONTROL DE EXCEPCIONES:\n    \nprimer_numero = 4\nsegundo_numero = 0\n#Comentar y descomentar la siguiente asignación de segundo_numero para ver cambios\nsegundo_numero = \"5\"\n\n\n### try-except\ntry:\n  print(primer_numero + segundo_numero)\n  print(\"operación correcta\")\nexcept:\n    print(\"operación incorrecta\")\n\n### try-except-else\ntry:\n   print(primer_numero + segundo_numero)\n   print(\"operación correcta\")\nexcept: #obligatorio para completar try\n    print(\"operación incorrecta\")\nelse: # opcional para continuar sin excepciones\n    print (\"la ejecución continúa\")\n\n   ### try-except-else-finally\ntry: \n   print(primer_numero + segundo_numero)\n   print(\"operación correcta\")\nexcept: #obligatorio para completar try\n    print(\"operación incorrecta\")\nelse: # opcional para continuar sin excepciones\n    print (\"la ejecución contitúa\")\nfinally: #opcional para continuar con y sin excepciones\n    print(\"la ejecución continúa pero puede haber errores\")\n\n   ###prevención de excepciones por tipo\ntry: \n   print(primer_numero + segundo_numero)\n   print(\"operación correcta\")\nexcept TypeError: #TypeError limita la excepción al tipo de dato\n    print(\"tipos de dato incompatibles para esta opración\")\n\n   ###prevención de excepciones por tipo y/o por valor\ntry: \n   print(primer_numero + segundo_numero)\n   print(\"operación correcta\")\nexcept ValueError: #ValueError limita la excepción al valor del dato\n    print(\"valores incompatibles con esta operación\")\nexcept TypeError: #TypeError limita la excepción al tipo de dato\n    print(\"tipos de dato incompatibles para esta operación\")\n\n\n    ###prevención y captura de fallos (concretos o genéricos)\ntry: \n   print(primer_numero / segundo_numero)\n   print(\"operación correcta\")\nexcept Exception as fallo: #Exception nos permite capturar cualquier excepción en una variable\n    print(fallo)\n\n\n\n\n\n#EJERCICIO PROPUESTO\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\"\"\"\n\nfor i in range (10,56):\n   if i % 2 == 0 and i % 3 != 0 and i != 16:  \n     print (i)\n   "
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/jfdacovich.py",
    "content": "\"\"\"\nOperadores aritméticos\n\"\"\"\n\nprint(f\"--------Operadores aritméticos--------\")\na = 11\nb = 7\nprint(f\"Suma: {a + b}\")          \nprint(f\"Resta: {a - b}\")         \nprint(f\"Multiplicación: {a * b}\") # 30\nprint(f\"División: {a / b}\")      # 3.3333...\nprint(f\"División entera: {a // b}\") # 3\nprint(f\"Módulo: {a % b}\")        # 1\nprint(f\"Exponenciación: {a ** b}\") # 1000\n\n# Operadores de comparación\nprint(f\"--------Operadores de comparación--------\")\nprint(f\"Igual a: {a == b}\")      # False\nprint(f\"Distinto de: {a != b}\")  # True\nprint(f\"Mayor que: {a > b}\")     # True\nprint(f\"Menor que: {a < b}\")     # False\nprint(f\"Mayor o igual que: {a >= b}\") # True\nprint(f\"Menor o igual que: {a <= b}\") # False\n\n# Operadores lógicos\nprint(f\"--------Operadores lógicos--------\")\nx = True\ny = False\nprint(\"AND lógico:\", x and y)  # False\nprint(\"OR lógico:\", x or y)    # True\nprint(\"NOT lógico:\", not x)    # False\n\n# Operadores de asignación\nprint(f\"--------Operadores de asignación--------\")\nc = 5\nc += 2  # c = c + 2\nprint(\"Asignación suma:\", c)   # 7\nc -= 2  # c = c - 2\nprint(\"Asignación resta:\", c)  # 5\nc *= 2  # c = c * 2\nprint(\"Asignación multiplicación:\", c) # 10\nc /= 2  # c = c / 2\nprint(\"Asignación división:\", c) # 5.0\nc //= 2 # c = c // 2\nprint(\"Asignación división entera:\", c) # 2.0\nc %= 2  # c = c % 2\nprint(\"Asignación módulo:\", c)  # 0.0\nc **= 2 # c = c ** 2\nprint(\"Asignación exponenciación:\", c) # 0.0\n\n# Operadores bit a bit\nprint(f\"--------Operadores bit a bit--------\")\nd = 6  # 110 en binario\ne = 2  # 010 en binario\nprint(\"AND bit a bit:\", d & e)  # 2 (010 en binario)\nprint(\"OR bit a bit:\", d | e)   # 6 (110 en binario)\nprint(\"XOR bit a bit:\", d ^ e)  # 4 (100 en binario)\nprint(\"Desplazamiento a la izquierda:\", d << 1) # 12 (1100 en binario)\nprint(\"Desplazamiento a la derecha:\", d >> 1)  # 3 (011 en binario)\n\n# Operadores de identidad\nprint(f\"--------Operadores de identidad--------\")\nf = [1, 2, 3]\ng = [1, 2, 3]\nh = f\nprint(\"Es:\", f is h)            # True\nprint(\"No es:\", f is not g)     # True\n\n# Operadores de pertenencia\nprint(f\"--------Operadores de pertenencia--------\")\nprint(\"En:\", 1 in f)            # True\nprint(\"No en:\", 4 not in f)     # True\n\n\"\"\"\nEstructuras de control\n\"\"\"\nprint(f\"--------Condicionales--------\")\nif a > b:\n    print(f\"{a} es mayor que {b}\")\nelif a < b:\n    print(f\"{a} es menor que {b}\")\nelse:\n    print(f\"{a} es igual a {b}\")\n\n# Estructuras iterativas\nprint(f\"--------Estructuras iterativas--------\")\nfor i in range(5):\n    print(f\"Iteración {i}\")\n\ncontador = 0\nwhile contador < 5:\n    print(f\"Iteración {contador}\")\n    contador += 1\n\n# Manejo de excepciones\nprint(f\"--------Manejo de excepciones--------\")\ntry:\n    resultado = a / 0\nexcept ZeroDivisionError:\n    print(\"Error: División por cero\")\nfinally:\n    print(\"Bloque finally ejecutado\")\n\n\"\"\"\nExtra\n\"\"\"\n\nfor i in range(10, 55+1):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/jgutierrez9891.py",
    "content": "# #01 OPERADORES Y ESTRUCTURAS DE CONTROL - SOLUCION\n\n# Arithmetic operators\nop_suma = 3 + 5\nprint (\"Operador suma: 3 + 5 = \" + str(op_suma))\n\nop_resta = 10 - 3\nprint (\"Operador resta: 10 - 3 = \" + str(op_resta))\n\nop_multiplicacion = 3 * 2\nprint (\"Operador multiplicacion: 3 * 2 = \" + str(op_multiplicacion))\n\nop_division = 9 / 2\nprint (\"Operador division: 9 / 2 = \" + str(op_division))\n\nop_exponente = 2**4\nprint (\"Operador exponente: 2**4 = \" + str(op_exponente))\n\nop_modulo = 7 % 2\nprint (\"Operador módulo: 7 % 2 = \" + str(op_modulo))\n\nop_division_entera = 9 // 2\nprint (\"Operador division entera: 9 // 2 = \" + str(op_division_entera))\n\n# Logic operators\n\nop_NOT = not True\nprint (\"Operador NOT: not True = \" + str(op_NOT))\n\nop_AND = 3 > 2 and 2 < 8\nprint (\"Operador AND: 3 > 2 and 2 < 8 = \" + str(op_AND))\n\nop_OR = 3 < 2 and 2 > 8\nprint (\"Operador OR: 3 < 2 and 2 > 8 = \" + str(op_OR))\n\n# Comparison operators\n\nop_mayor_que = 3 > 2\nprint (\"Operador mayor que: 3 > 2 = \" + str(op_mayor_que))\n\nop_menor_que = 3 < 2\nprint (\"Operador menor que: 3 < 2 = \" + str(op_menor_que))\n\nop_igualdad = 3==3\nprint (\"Operador igualdad: 3 == 3 = \" + str(op_igualdad))\n\nop_diferente = 4 != 41\nprint (\"Operador diferente: 4 != 41 = \" + str(op_diferente))\n\nop_menor_igual = 4 <= 4.1\nprint (\"Operador menor o igual: 4 <= 4.1 = \" + str(op_menor_igual))\n\nop_mayor_igual = 4.2 >= 4.1\nprint (\"Operador mayor o igual: 4.2 >= 4.1 = \" + str(op_mayor_igual))\n\n# Assignment operators\n\nx = 5; x += 1\nprint (\"Operador 5+=1 => \" + str(x))\n\nx = 5; x -= 2\nprint (\"Operador 5-=2 => \" + str(x))\n\nx = 5; x *= 8\nprint (\"Operador 5*=8 => \" + str(x))\n\nx = 5; x /= 3\nprint (\"Operador 5/=3 => \" + str(x))\n\nx = 5; x %= 3\nprint (\"Operador 5%=3 => \" + str(x))\n\nx = 5; x //= 2\nprint (\"Operador 5//=2 => \" + str(x))\n\nx = 5; x **= 2\nprint (\"Operador 5**=2 => \" + str(x))\n\nx = 5; x &= 2\nprint (\"Operador 5&=2 => \" + str(x))\n\nx = 5; x |= 2\nprint (\"Operador 5|=2 => \" + str(x))\n\nx = 5; x ^= 2\nprint (\"Operador 5^=2 => \" + str(x))\n\nx = 5; x >>= 2\nprint (\"Operador 5>>=2 => \" + str(x))\n\n# Identity operators\n\nprint (\"Operador is: \" + str(4 is 3))\nprint (\"Operador is not: \" + str(4 is not 3))\n\n# Conditional structures\n\n#if\nif 3 < 5:\n    print(\"Condición if se cumple\")\n\n#if-else\nif 3 > 5:\n    print(\"Condición if se cumple\")\nelse:\n    print(\"Condición no se cumple\")\n\n#if-elif-else\nif 5 - 2 < 3:\n    print(\"Condición if se cumple\")\nelif 5 - 3 < 3:\n    print(\"Condición elif se cumple\")\nelse:\n    print(\"Condición no se cumple\")\n\n# Iterative structures\n\n# while\n\nx = 10\nwhile x > 5:\n    x-=1\n    print(\"x es igual a: \" + str(x))\n\n# for\n\nbrands = ['apple', 'BMW', 'Ford', 'Nvidia', 'BYD', 'MacDonalds', 'Dior']\nfor i in brands:\n    print (\"La marca actual es: \" + i)\n    if i == 'MacDonalds':\n        break\n\n# Exceptions\n\na = 5; b = 0\ntry:\n    c = a/b\nexcept ZeroDivisionError:\n    print(\"No se ha podido realizar la división\")\nexcept Exception:\n    print(\"Ha saltado una excepción diferente\")\n\n# Opcional\n\nfor i in range(10,56):\n    if i  % 2 == 0 and i != 16 and i % 3 != 0:\n        print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/jhoshmc.py",
    "content": "a= 5\nb= 3\n\n#* operadores aritmeticos\ndef aritmeticos():\n  suma= a+b\n  resta = a-b\n  multiplicacion= a*b\n  divicion= a/b\n  resto= a%b\n  print(\"\\t operadores aritmeticos\")\n  print(a,\" + \",b,\" = \",suma)\n  print(a,\" - \",b,\" = \",resta)\n  print(a,\" * \",b,\" = \",multiplicacion)\n  print(a,\" / \",b,\" = \",divicion)\n  print(a,\" % \",b,\" = \",resto)\n\n#* operaciones logicos\ndef logicos():\n  verdadero= True\n  falso = False\n  and_logico = verdadero and verdadero\n  or_logico = verdadero and falso\n  negacion = not verdadero\n  print(\"\\t operadores logicos\")\n  print(\"verdadero: \", verdadero)\n  print(\"falso: \",falso)\n  print(verdadero,\" and \",verdadero,\" = \", and_logico)\n  print(verdadero,\" or \",falso,\" = \", or_logico)\n  print(\"not \",verdadero)\n\n#* operadores de comparacion\ndef comparacion():\n  mayor= a>b\n  menor = a<b\n  igual = a==b\n  diferente = a != b\n  mayor_igual = a>=b\n  menor_igual = a<=b\n  print(\"\\t operadores de comparacion\")\n  print(a,\" > \",b,\" = \",mayor)\n  print(a,\" < \",b,\" = \",menor)\n  print(a,\" == \",b,\" = \",igual)\n  print(a,\" != \",b,\" = \",diferente)\n  print(a,\" >= \",b,\" = \",mayor_igual)\n  print(a,\" <= \",b,\" = \",menor_igual)\n\n#* asignacion\ndef asigacion():\n  n=0\n  print(\"\\t asignacion\")\n  print(\"n= \",n)\n  print(\"se le asignara a n el numero 5\")\n  n=5\n  print(\"ahora n= \",n)\n\n#*operadores de identidad\ndef identidad():\n c=10\n d=10\n arr_1=[1,2,3]\n arr_2=[1,2,3]\n print(\"\\t operadores de identidad \")\n print (c,\" is \", d,\" = \",(c is d))\n print (arr_1,\" is \", arr_2,\" = \",(arr_1 is arr_2))\n \"\"\"\n 'is' verifica si ambos utilizan el mismo onbjero (el mismo espacio de memoria para almacenar  que sean iguales , no significa que utilicen el mismo espacio de memoria , como el ejemplo del array\n \"\"\"\n\n # is not, es lo contrario a is\n print (c,\" is not \", d,\" = \",(c is not d))\n print (arr_1,\" is not \", arr_2,\" = \",(arr_1 is not arr_2))\n \n print(\"direccion de memoria a: \",id(c))\n print(\"direccion de memoria b: \",id(d))\n print(\"direccion de memoria arr_1: \",id(arr_1))\n print(\"direccion de memoria arr_2: \",id(arr_2))\n\n#* operador de pertenencia\ndef pertenencia():\n  frutas=[\"manzana\",\"pera\",\"naranja\"]\n  #* in : ve si el elemento que se busca enstá en el array\n  print(\"\\t pertenencia\")\n  print(\"pera in frutas = \", (\"pera\" in frutas))\n  print(\"coco in frutas = \", (\"coco\" in frutas))\n  #* not in, es lo contrario\n  print(\"pera not in frutas= \",(\"pera\" not in frutas))\n  print(\"coco not in frutas= \",(\"coco\" not in frutas))\n\n#* operadores de bits\ndef bits():\n  A= 1010\n  B= 1011\n  print(\"\\t operadores de bits\")\n  print(f\" {A} & {B} = {A & B}\") #* AND\n  print(f\" {A} | {B} = {A | B}\") #* OR\n  print(f\" {A} ^ {B} = {A ^ B}\") #* XOR\n  print(f\" ~10 = {~10}\") #* NOT\n  print(f\"Desplazamiento a la Derecha 10 >> 3 = {10 >> 3}\")\n  print(f\"Desplazamiento a la Izquierda 10 << 3 = {10 << 3}\")\n\n#* estructuras de control\ndef estructuras_de_control():\n  #* condicionales\n  if(a > b):\n    print(f\"sumamos a + b : {a+b}\")\n  else:\n    print(f\"restamos a - b : {a-b}\")\n  valor =20\n  resultado = \"El valor es 10\" if valor == 10 else \"El valor es 20\"\n  print(resultado)\n  #* ciclos\n  #* for\n  print(\"for\")\n  frutas=[\"manzana\",\"coco\",\"pera\",\"platano\"]\n  for i in frutas:\n    print(i)\n  print(\"while\")\n  #* while\n  contador=0\n  while (contador < 2):\n    print(frutas[contador])\n    contador+=1\n\n#* excepciones\n# def excepciones():\n # try:\n\t  # Codigo a ejecutar\n\t  # Pero podria haber errores en este bloque\n    \n # except <tipo de error>:\n\t  # Haz esto para manejar la excepcion\n\t  # El bloque except se ejecutara si el bloque try lanza un error\n    \n # else:\n\t  # Esto se ejecutara si el bloque try se ejecuta sin errores\n   \n # finally:\n\t  # Este bloque se ejecutara siempre\n\n#* ejercicio extra\ndef extra():\n  i= 10\n  fin= 55\n  while(i <= fin):\n    if((i%2 == 0) and (i!= 16) and (i%3 != 0) or (i == fin)):\n      print(i)\n    i+=1\n\naritmeticos()\nlogicos()\ncomparacion()\nasigacion()\nidentidad()\npertenencia()\nbits()\nestructuras_de_control()\n# execiones()\nextra()"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/jmontoyac.py",
    "content": "# Ejemplo de operadores aritmeticos\n\na = 5\nb = 2\n\nprint(f'Valor de variable a: {a}')\nprint(f'Valor de variable b: {b}')\n\nprint(f'a + b: {a+b}')\nprint(f'a - b: {a-b}')\nprint(f'a * b: {a*b}')\nprint(f'a / b: {a/b}')\nprint(f'a % b: {a%b}')\n\n# Ejemplo de operadores logicos\n\n# Operador and\nprint('## Operador and  ##')\nprint(f'True and True: {True and True}')\nprint(f'True and False: {True and False}')\nprint(f'False and True: {False and True}')\nprint(f'False and False: {False and False}')\n\n# Operador or\nprint('## Operador or  ##')\nprint(f'True or True: {True or True}')\nprint(f'True or False: {True or False}')\nprint(f'False or True: {False or True}')\nprint(f'False or False: {False or False}')\n\n# Operador not\nprint('## Operador not  ##')\nprint(f'not True: {not True}')\nprint(f'not False: {not False}')\n\n# Operadores de comparacion\n\nprint('## Operadores de comparacion ##')\nprint(f'{a} == {b}: {a==b}')\nprint(f'{a} != {b}: {a!=b}')\nprint(f'{a} < {b}: {a<b}')\nprint(f'{a} > {b}: {a>b}')\nprint(f'{a} <= {b}: {a<=b}')\nprint(f'{a} >= {b}: {a>=b}')\n\n# Operadores de asignacion\n\nprint('## Operadores de asignacion ##')\nx = \"Hola\"\ny = 256\nz = 128\nprint(f'x = \"Hola\", valor de variable x: {x}')\nprint(f'y = 265, valor de variable y: {y}')\ny += z\nprint(f'y += z, resultado: {y}')\ny -= z\nprint(f'y -= z, resultado: {y}')\ny *= z\nprint(f'y *= z, resultado: {y}')\ny /= z\nprint(f'y /= z, resultado: {y}')\ny %= z\nprint(f'y %= z, resultado: {y}')\ny = 2\nz = 6\ny **= z\nprint(f'y **= z, resultado: {y}')\ny //= z\nprint(f'y //= z, resultado: {y}')\n\n# Operadores de identidad\na = 100\nb = 100\n\nprint(f'a={a}, b={b}, a is b: {a is b}')\nb = 200\nprint(f'a={a}, b={b}, a is b: {a is b}')\n\nlista1 = [10, 20, 30]\nlista2 = [10, 20, 30]\n\nprint(f'l1: {lista1}, l2: {lista2} l1 is l2: {lista1 is lista2}')\n\na = 100\nb = 100\n\nprint(f'a={a}, b={b}, a is not b: {a is not b}')\nb = 200\nprint(f'a={a}, b={b}, a is not b: {a is not b}')\n\n# Operadores de pertenencia\n\nlista1 = ['a', 'c', 'e']\nprint(f'e in {lista1}: {\"e\" in lista1}')\nprint(f'g in {lista1}: {\"g\" in lista1}')\nprint(f'e not in {lista1}: {\"e\" not in lista1}')\nprint(f'n not in {lista1}: {\"n\" not in lista1}')\n\n# Operadores de bits\n\nx = 0b0001\ny = 0b1010\n\nprint(f'Operador and & bitwise: {x} & {y}: {x & y}')\nprint(f'Operador or | bitwise: {x} | {y}: {x | y}')\nprint(f'Operador not ~ bitwise: {x}: {~x}')\nprint(f'Operador xor ^ bitwise: {x} ^ {y}: {x ^ y}')\n\n# Estructuras de control\n\n# Condicionales\nprint(f'if {a} == {b}: {a == b}')\nprint(f'if {a} != {b}: {a != b}')\nprint(f'if {a} > {b}: {a > b}')\nprint(f'if {a} < {b}: {a < b}')\nprint(f'if {a} >= {b}: {a >= b}')\nprint(f'if {a} <= {b}: {a <= b}')\n\n# Iterativas\n\n# While\nx = 0\nwhile x < 3:\n    print(f'Ciclo while, Valor de x: {x}')\n    x += 1\nelse:\n    print('Fin de ciclo while')\n    \n# For \nx = 3\nfor i in range (0, x):\n    print(f'Ciclo for, Valor de i: {i}')\n    \nfor elemento in lista1:\n    print(f'Elemento de lista: {elemento}')\n    \ncadena = 'cadena de texto'\nfor c in cadena:\n    print(f'Caracter de cadena de texto: {c}')\n    \n# Ejercicio de dificultad extra\n\nn = 56\nfor i in range (10, n):\n    if (i % 2 == 0) and (i != 16) and (i % 3 != 0):\n        print(f'Numeros: {i}')"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/joandevpy.py",
    "content": "\n# Operadores aritméticos\n\nprint(\"Operadores aritméticos:\")\nprint(f\"Suma: 10 + 3 = {10 + 3}\")\nprint(f\"Resta: 10 - 3 = {10 - 3}\")\nprint(f\"Multiplicación: 10 * 3 = {10 * 3}\")\nprint(f\"División: 10 / 3 = {10 / 3}\")\nprint(f\"División entera: 10 // 3 = {10 // 3}\")\nprint(f\"Modulo: 10 % 3 = {10 % 3}\")\nprint(f\"Exponencial: 10 ** 3 = {10 ** 3}\")\n\n\"\"\" \nOperadores de comparación-\nPueden ser con variables__|\n\"\"\"\nprint(\"\\nOperadores de comparación:\")\nprint(f\"Igual 10 == 3 : {10 == 3}\")\nprint(f\"Desigual 10 != 3 : {10 != 3}\")\nprint(f\"Maypr que 10 > 3 : {10 > 3}\")\nprint(f\"Menor que 10 < 3 : {10 < 3}\")\nprint(f\"Mayor o igual que 10 >= 10 : {10 >= 10}\")\nprint(f\"Menor o igual que 10 <= 3 : {10 <= 3}\")\n\n# Operadores lógicos\nprint(\"\\nOperadores lógicos:\")\nprint(f\"10 > 5 and 3 < 5 : {10 > 5 and 3 < 5}\")\nprint(f\"3 > 5 or || 3 < 2 : {10 > 5 or 3 < 2}\")\nprint(f\"not(10 > 5) : {not 10 > 5}\")\n\n# Operadores de asignación\nmy_number = 11\n\nprint(\"\\nOperadores de asignación:\")\nprint(f\"my_number es {my_number}\")\nmy_number += 5\nprint(f\"my_number += 5: {my_number}\") # Suma y Asignacion\nmy_number -= 2\nprint(f\"my_number -= 2: {my_number}\") # Resta y Asignacion\nmy_number *= 3\nprint(f\"my_number *= 3: {my_number}\") # Multiplicar y Asignacion\nmy_number /= 4\nprint(f\"my_number /= 4: {my_number}\") # Divide y Asignacion\nmy_number //= 2\nprint(f\"my_number //= 2: {my_number}\") # Divide entera y Asignacion\nmy_number %= 3\nprint(f\"my_number %= 3: {my_number}\") # Modulo y Asignacion\nmy_number **= 2\nprint(f\"my_number **= 2: {my_number}\") # Exponencial y Asignacion\n\n# Operadores de identidad\nprint(\"\\nOperadores de identidad:\")\nmy_new_number = my_number\nprint(f\"my_number is my_new_number : {my_number is my_new_number}\")\nprint(f\"my_number is not my_new_number : {my_number is not my_new_number}\")\n\n\n# Operadores de pertenencia\nprint(\"\\nOperadores de pertenencia:\")\nprint(f\"'a' in 'joandevpy' : {'a' in 'joandevpy'}\")\nprint(f\"'a' not in 'joandevpy' : {'a' not in 'joandevpy'}\")\n\n\n# Operadores de bits\nprint(\"\\nOperadores de bits:\")\nc = 10  # 1010\nd = 3   # 0011\nprint(f\"c & d : {c & d}\")  # AND bit a bit\nprint(f\"c | d : {c | d}\")  # OR bit a bit\nprint(f\"c ^ d : {c ^ d}\")  # XOR bit a bit\nprint(f\"~c : {~c}\")        # NOT bit a bit\nprint(f\"c << 1 : {c << 2}\") # Desplazamiento a la izquierda\nprint(f\"c >> 1 : {c >> 1}\") # Desplazamiento a la derecha\n\n\n\"\"\"\nEstructuras de control\n\"\"\"\n\n# Condicionales\n\nprint(\"\\nCondicionales:\")\n\nmy_string = \"joandevpyy\"\n\nif my_string == \"joandevpy\":\n    print(\"my_string es joandevpy\")\nelif my_string == \"Joan\":\n   print(\"my_string es Joan\")\nelse:\n    print(\"my_string no es joandevpy ni Joan\")\n\n# Bucles for o Iterativas\nprint(\"\\nBucles for o iterativas:\")\nfor i in range(11): # el ultimo numero no se imprime seria hasta el 10\n    print(i)\n\n# Bucles while siempre se ejecuta mientras sea True (Bucle Infinito)\nprint(\"\\nBucles while:\")\ni = 0\nwhile i < 5:\n    print(f\"Contador en {i}\")\n    i += 1\n\n# Excepciones\nprint(\"\\nExcepciones:\")\ntry:\n    resultado = 10 / 0\n    print(f\"El resultados es: {resultado}\")\nexcept ZeroDivisionError:\n    print(\"Error: División por cero\")\nfinally:\n    print(\"Ha finalizado el manejo de excepciones\")    \n\n\n# Dificultad extra\nprint(\"\\nNúmeros entre 10 y 55, pares, que no son ni el 16 ni múltiplos de 3:\")\nfor number in range(10, 56):\n    if number % 2 == 0 and number != 16 and number % 3 != 0:\n        print(number)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/jofedev.py",
    "content": "\"\"\"\n EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\"\"\"\n\n            ### Operadores Aritmeticos ###\n\n#Suma\nprint(f\"Suma: 10 + 30 = {10 + 30}\")\n\n# Resta\nprint(f\"Resta: 50 - 20 = {50 - 20}\")\n\n# Multiplicacion\nprint(f\"Multiplica: 234 x 2244 = {234 * 2244}\")\n\n# Division\nprint(f\"Divide: 34 / 2 = {34 / 2} \")\n\n# Modulo\nprint(f\"Modulo: 40 % 3 = {40 % 3}\")\n\n# Exponenciales\nprint(f\"Potencia de 40 a la 5 es = {40 ** 5}\")\n\n# Division Entera\nprint(f\"Division entera de 40 // 3 = {40 // 3}\")\n\n        \n            ### Operadores Logicos ###\n\n# and => Devuelve True solo si ambos operadores son True\nprint(f\"and: True and True = {True and True}\")\nprint(f\"and: True and False = {True and False}\")\nprint(f\"and: False and False = {False and False}\")\n\n# or => Devuelve True si cualquiera de los operadores es True\nprint(f\"or True or True = {True or True}\")\nprint(f\"or: True or False = {True or False}\")\nprint(f\"or: False or False = {False or False}\")\n\n# not => Invierte los operadores, si es True not devuelve False y viceversa\nprint(f\"not: not True = {not True}\")\nprint(f\"not: not False = {not False}\")\n\n            ### Operadores de comparacion ###\n\nprint(f\"igualdad: 10 == 1 = {10 == 1}\")\nprint(f\"No es igual: 10 != 1 = {10 != 1 }\")\nprint(f\"Mayor que: 10 > 5 = {10 > 5}\")\nprint(f\"Menor que: 1 < 10 = {1 < 10}\")\nprint(f\"Mayor o igual que: 10>= 10 {10 >= 10}\")\nprint(f\"Menor o igual que: 10 <= 9 {10 <= 9}\")\n\n\n            ### Operadores de Asignacion ###\n\nmy_number = 20\nprint(my_number)\nmy_number += 1 #Asignacion y suma\nprint(my_number)\nmy_number -= 1 # Asignacion y resta\nprint(my_number)\nmy_number *= 2 # Asignacion y Multiplicacion\nprint(my_number)\nmy_number /= 2 # Asignacion y Division\nprint(my_number)\nmy_number %= 4 # Modulo y Asignacion\nprint(my_number)\nmy_number //= 4 # Division de entero y Asignacion\nprint(my_number)\nmy_number **= 5 # Exponenciacion y Asignacion\nprint(my_number)\n\n\n            ### Operadores de Identidad ###\n\nmy_new_number = 1\nprint(f\"my_number is my_new_number es {my_number is my_new_number}\") # Evalua si los elementos pertenecen al mismo lugar en memoria\nprint(f\"my_number is not my_new_number es {my_number is not my_new_number}\")\n\n\n            ### Operadores de Pertenencia ###\n\nprint(f\"'e' in Jose = {'e' in 'Jose'}\") # Evalua si un elemento se encuentra el elemento dado\nprint(f\"'e' not in Jose = {'e' not in 'Jose'}\") \n\n\n            ### Operadores de bit ###\n\na = 10 # 1010\nb = 3 # 0011\n\nprint(f\"AND 10 & 3 = {10 & 3}\")\nprint(f\"OR 10 | 3 = {10 | 3}\")\nprint(f\"XOR 10 ^ 3 = {10 ^ 3}\")\nprint(f\"NOT ~10 = {~10}\")\nprint(f\"Desplazamiento a la Derecha 10 >> 3 = {10 >> 3}\")\nprint(f\"Desplazamiento a la Izquierda 10 << 3 = {10 << 3}\")\n\n\"\"\"\n    Estructuras de Control\n\"\"\"\n\n            ### Condicionales ###\n\nmy_name = \"Jose\"\n\nif my_name == \"Pedro\":\n    print(\"Mi nombre es Jose\")\nelif my_name == \"Juan\":\n    print(\"Hola Juan\")\nelse:\n    print(\"Pedro Pedro Pedro PE\")\n\n\n            ### Iterativas ###\n\nfor i in range(11):\n    print(i)\n\n\ni = 0\n\nwhile i <= 10:\n    print(i)\n    i += 1\n\n            ### Manejo de Excepciones ###\n\n\ntry:\n    print(10 / 0)\nexcept: \n    print(\"Se ha producido un error\")\nfinally:\n    print(\"Ha finalizado el manejo de exepciones con exito\")\n\n\n\"\"\"\n        EXTRA\n        Crea un programa que imprima por consola todos los números comprendidos\n        entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\"\"\"\n\n\nfor i in range(10,56):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print(i)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/jorgeadamowicz.py",
    "content": "# 1- Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n#  Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n\n# operadores aritméticos #\na = 3\nb = 2\n\nprint (\"la suma de a y b: \",  (a + b))# operador de suma\nprint (\"la resta de a y b: \",  (a - b))# operador de resta .\nprint (\"la multiplicación de a y b: \",  (a * b))# operador de multiplicación\nprint (\"la división de a y b: \",  (a / b))# operador de división\nprint (\"la división entera de a y b: \",  (a // b))# operador de división entera\nprint (\"la división de resto o módulo de a y b: \",  (a % b))# operador de división de resto o módulo\nprint (\"la potencia de a y b: \",  (a ** b))# operador de potencia o exponencial\n\n## operadores de comparación ##\n\nprint (a == b)# operador es igual a: (output False)\nprint (a != b)# operador es diferente a: (output True)\nprint (a > b)# operador es mayor que: (output True)\nprint (a < b)# operador es menor que: (output False)\nprint (a >= b)# operadro es mayor o igual que: (output True)\nprint (a >= b)# operadro es menor o igual que: (output False)\n\n### operadores de pertenencia ###\n\ncolores_primarios = [\"rojo\", \"amarillo\", \"azul\"]\ncolor_test = input(\"ingresa un color: \")\nif color_test in colores_primarios:\n    print(color_test, \"es un color primario!\")\nelse:\n    print(color_test, \"no es un color primario\")\n\n### operadores lógicos ###\n\nc = 1\n\nprint (a > b and a > c)# operador de conjunción: (output True)\nprint (a > b or a > c)# operador de diyunción: (output True)\nprint (not (a > b))# operador not: (output False)\n\n\n## operadores de asignación ##\n\nmy_assignment_variable = \"este es mi operador de asignación\"\nprint( my_assignment_variable)\n\nmy_number = 10 #asignación de valor a una variable\nprint(my_number)\nmy_number += 1 #asignación y suma\nprint(my_number)\nmy_number -= 1 #asignación y resta\nprint(my_number)\nmy_number *= 1 #asignación y multimplicación\nprint(my_number)\nmy_number /= 2 #asignación y divición\nprint(my_number)\nmy_number //= 2 #asignación y divición entera\nprint(my_number)\nmy_number %= 1 #asignación y resto o módulo\nprint(my_number)\nmy_number **= 1 #asignación y exponencial o potencia\n\n\n\n### operadores de bits ###\n\nprint (a & b)# operación AND (output 2)\nprint (a | b )# operación or (output 3)\nprint (a ^ b)# operación Xor (output 1)\nprint (~ b) #operador Not  (b=2 en binario: b=10 por lo tanto ~b= 01)\nprint (a >> b) # operador de desplazamiento a la derecha (output 0)\nprint (a << b)# operador de desplazamiento a la izquierda (output 12)\n\n## estructuras de control##\n\n#condicional if, elif, else. #\nif a > b:\n    print(a, \"es mayor que \", b)\nelif a == b:\n    print(a, \"es igual que \", b)\nelse:\n    print(a, \"es menor que \", b)\n\n### iterativas##\n#bucle while#\n\nwhile c < a:\n    c+=1\nprint(\" ahora \", c ,\"es igual a  \", a)\n\n# bucle for#\n\nfor i in range (11):\n    print(i)\n\n#excepciones ##\n\ntry:\n    print(\"en esta linea, tal vez haya un error\")\nexcept: \n    print(\" ha ocurrido un error\")\nfinally: \n     print(\"la ejecución continua\")\n\n##DIFICULTAD EXTRA (opcional):##\n\nfor number in range (10, 56, 2):\n    #if number % 2== 0 and number != 16 and number %3 !=0: (version compacta)\n    if number == 16:\n        continue\n    elif number % 3 == 0:\n        continue\n    print(number)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/josandgon12.py",
    "content": "\"\"\"\nEJERCICIO: Operadores y Estructuras de Control en Python\n\"\"\"\n\nprint(\"=\" * 60)\nprint(\"OPERADORES EN PYTHON\")\nprint(\"=\" * 60)\n\n# 1. OPERADORES ARITMÉTICOS\nprint(\"\\n--- OPERADORES ARITMÉTICOS ---\")\na = 15\nb = 4\nprint(f\"a = {a}, b = {b}\")\nprint(f\"Suma (a + b): {a + b}\")\nprint(f\"Resta (a - b): {a - b}\")\nprint(f\"División (a / b): {a / b}\")\nprint(f\"División entera (a // b): {a // b}\")\nprint(f\"Módulo (a % b): {a % b}\")\nprint(f\"Potencia (a ** b): {a ** b}\")\n\n# 2. OPERADORES DE COMPARACIÓN\nprint(\"\\n--- OPERADORES DE COMPARACIÓN ---\")\nx = 10\ny = 20\nprint(f\"x = {x}, y = {y}\")\nprint(f\"Igual (x == y): {x == y}\")\nprint(f\"Diferente (x != y): {x != y}\")\nprint(f\"Mayor que (x > y): {x > y}\")\nprint(f\"Menor que (x < y): {x < y}\")\nprint(f\"Mayor o igual (x >= y): {x >= y}\")\nprint(f\"Menor o igual (x <= y): {x <= y}\")\n\n# 3. OPERADORES LÓGICOS\nprint(\"\\n--- OPERADORES LÓGICOS ---\")\nverdadero = True\nfalso = False\nprint(f\"verdadero = {verdadero}, falso = {falso}\")\nprint(f\"AND (verdadero and falso): {verdadero and falso}\")\nprint(f\"OR (verdadero or falso): {verdadero or falso}\")\nprint(f\"NOT (not verdadero): {not verdadero}\")\n\n# 4. OPERADORES DE ASIGNACIÓN\nprint(\"\\n--- OPERADORES DE ASIGNACIÓN ---\")\nnumero = 10\nprint(f\"Asignación inicial: numero = {numero}\")\nnumero += 5\nprint(f\"Suma y asignación (+=): {numero}\")\nnumero -= 3\nprint(f\"Resta y asignación (-=): {numero}\")\nnumero *= 2\nprint(f\"Multiplicación y asignación (*=): {numero}\")\nnumero //= 3\nprint(f\"División entera y asignación (//=): {numero}\")\nnumero %= 5\nprint(f\"Módulo y asignación (%=): {numero}\")\nnumero **= 2\nprint(f\"Potencia y asignación (**=): {numero}\")\n\n# 5. OPERADORES DE IDENTIDAD\nprint(\"\\n--- OPERADORES DE IDENTIDAD ---\")\nlista1 = [1, 2, 3]\nlista2 = [1, 2, 3]\nlista3 = lista1\nprint(f\"lista1: {lista1} (id: {id(lista1)})\")\nprint(f\"lista2: {lista2} (id: {id(lista2)})\")\nprint(f\"lista3: {lista3} (id: {id(lista3)})\")\nprint(f\"lista1 is lista2: {lista1 is lista2}\")\nprint(f\"lista1 is lista3: {lista1 is lista3}\")\nprint(f\"lista1 is not lista2: {lista1 is not lista2}\")\n\n# 6. OPERADORES DE PERTENENCIA\nprint(\"\\n--- OPERADORES DE PERTENENCIA ---\")\nfrutas = [\"manzana\", \"pera\", \"naranja\"]\nprint(f\"Lista de frutas: {frutas}\")\nprint(f\"'manzana' in frutas: {'manzana' in frutas}\")\nprint(f\"'uva' in frutas: {'uva' in frutas}\")\nprint(f\"'uva' not in frutas: {'uva' not in frutas}\")\n\n# 7. OPERADORES DE BITS\nprint(\"\\n--- OPERADORES DE BITS ---\")\nnum1 = 10  # 1010 en binario\nnum2 = 4   # 0100 en binario\nprint(f\"num1 = {num1} ({bin(num1)}), num2 = {num2} ({bin(num2)})\")\nprint(f\"AND bit a bit (num1 & num2): {num1 & num2} ({bin(num1 & num2)})\")\nprint(f\"OR bit a bit (num1 | num2): {num1 | num2} ({bin(num1 | num2)})\")\nprint(f\"XOR bit a bit (num1 ^ num2): {num1 ^ num2} ({bin(num1 ^ num2)})\")\nprint(f\"NOT bit a bit (~num1): {~num1} ({bin(~num1)})\")\nprint(f\"Desplazamiento izquierda (num1 << 2): {num1 << 2} ({bin(num1 << 2)})\")\nprint(f\"Desplazamiento derecha (num1 >> 2): {num1 >> 2} ({bin(num1 >> 2)})\")\n\nprint(\"\\n\" + \"=\" * 60)\nprint(\"ESTRUCTURAS DE CONTROL\")\nprint(\"=\" * 60)\n\n# 1. CONDICIONALES (if, elif, else)\nprint(\"\\n--- CONDICIONALES ---\")\nedad = 25\nprint(f\"Edad: {edad}\")\nif edad < 18:\n    print(\"Eres menor de edad\")\nelif edad < 65:\n    print(\"Eres adulto\")\nelse:\n    print(\"Eres adulto mayor\")\n\n# Operador ternario\nmensaje = \"Par\" if edad % 2 == 0 else \"Impar\"\nprint(f\"La edad es: {mensaje}\")\n\n# 2. BUCLE FOR\nprint(\"\\n--- BUCLE FOR ---\")\nprint(\"Números del 1 al 5:\")\nfor i in range(1, 6):\n    print(f\"  {i}\")\n\nprint(\"Iterando sobre una lista:\")\ncolores = [\"rojo\", \"verde\", \"azul\"]\nfor color in colores:\n    print(f\"Color: {color}\")\n\n# 3. BUCLE WHILE\nprint(\"\\n--- BUCLE WHILE ---\")\ncontador = 0\nprint(\"Contando hasta 3:\")\nwhile contador < 3:\n    contador += 1\n    print(f\"Contador: {contador}\")\n\n# 4. BREAK Y CONTINUE\nprint(\"\\n--- BREAK Y CONTINUE ---\")\nprint(\"Usando break (detener en 5):\")\nfor i in range(1, 10):\n    if i == 5:\n        break\n    print(f\"{i}\")\n\nprint(\"Usando continue (saltar números pares):\")\nfor i in range(1, 8):\n    if i % 2 == 0:\n        continue\n    print(f\"{i}\")\n\n# 5. MANEJO DE EXCEPCIONES\nprint(\"\\n--- MANEJO DE EXCEPCIONES ---\")\ntry:\n    resultado = 10 / 0\nexcept ZeroDivisionError as e:\n    print(f\"Error capturado: {e}\")\nexcept Exception as e:\n    print(f\"Otro error: {e}\")\nelse:\n    print(\"No hubo errores\")\nfinally:\n    print(\"Este bloque siempre se ejecuta\")\n\n\n# 6. MATCH-CASE\nprint(\"\\n--- MATCH-CASE ---\")\ndia = 3\nmatch dia:\n    case 1:\n        print(\"Lunes\")\n    case 2:\n        print(\"Martes\")\n    case 3:\n        print(\"Miércoles\")\n    case 4 | 5:\n        print(\"Jueves o Viernes\")\n    case _:\n        print(\"Fin de semana\")\n\nprint(\"\\n\" + \"=\" * 60)\nprint(\"\\nNúmeros entre 10 y 55 (incluidos), pares, que NO son 16 ni múltiplos de 3:\")\nprint()\n\nfor numero in range(10, 56):\n    # Debe ser par\n    if numero % 2 != 0:\n        continue\n    \n    # No debe ser 16\n    if numero == 16:\n        continue\n    \n    # No debe ser múltiplo de 3\n    if numero % 3 == 0:\n        continue\n    \n    print(numero)\n\n# for i in range(10,56):\n#     if i % 2 == 0 and i != 16 and i % 3 != 0:\n#         print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/jose-larss.py",
    "content": "numero1 = 10\nnumero2 = 3\nnumero3 = 343\n\ncadena = \"10 23 esto es una cadena\"\n\nx = True\ny = False\n\n# Aritméticos\nsuma = numero1 + numero2\nresta = numero1 - numero2\nmulti = numero1 * numero2\ndivision = numero1 / numero2\n\nprint(\"Suma\", suma)\nprint(\"Resta\", resta)\nprint('Multiplicación', multi)\nprint('División', division)\n\n#Lógicos And Or Not\nres = x and y\nprint(res)\n\nres = x or y\nprint(res)\n\nres = not x\nprint(res)\n\n# Operadores de asignación\nsuma += numero3\nresta -= numero3\nmulti *= numero3\ndivision /= numero3\n\nprint(\"Suma\", suma)\nprint(\"Resta\", resta)\nprint('Multiplicación', multi)\nprint('División', division)\n\n# Operadores de Comparación\nres = numero1 > numero2\nprint(res)\n\nres = numero1 < numero2\nprint(res)\n\nres = numero1 == numero2\nprint(res)\n\nres = numero1 != numero2\nprint(res)\n\n# Operadores de Identidad\n\"\"\"\nres = 10 is numero1\nprint(res)\n\nres = \"esto\" is not cadena\nprint(res)\n\"\"\"\n# Operadores de pertenencia\nres = \"esto\" in cadena\nprint(res)\n\nres = \"esto\" not in cadena\nprint(res)\n\n# Operadores de Bits\nres = numero1 | numero2 # or bit a bit de x e y.\nprint(res)\n\nres = numero1 & numero2 # and bit a bit de x e y.\nprint(res)\n\nres = ~numero1 # not x. Obtiene los bits de x invertidos.\nprint(res)\n\n# Condicionales\nif numero1 == numero2:\n    print(\"son iguales\")\nelif numero1 > numero2:\n    print(\"numero1 es mayor que numero2\")\nelse:\n    print(\"numer1 es menor que numero 2\")\n\n# Iterativas:\nfor i in cadena:\n    print(i)\ni=1\nwhile i < numero1:\n    print(\"esta es la vuelta \", i)\n    i += 1\n\n\n#Excepciones\n\ntry:\n    res = numero3 / 0\n    print(res)\nexcept ZeroDivisionError:\n    print(\"Un numero no puede ser dividido por 0\")\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\"\"\"\n\nfor i in range(10, 56):\n    if ((i % 2 == 0) and (i != 16) and not (i % 3 == 0)):\n        print(i)\n            \n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/josecox13.py",
    "content": "'''\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n'''\n\n\n#Aritméticos\nprint('\\n-----Operadores aritméticos-----')\nprint (f'Suma: 1 + 4 = {1+4}')\nprint(f'Resta: 4 - 1 = {4-1}')\nprint(f'Multiplicación: 4 * 3 = {4*3}')\nprint(f'Division: 12 / 3 = {12/3}')\nprint(f'Potencia: 4 ** 3 = {4**3}')\nprint(f'Resto: 5 % 3 = {5%31}')\nprint(f'Parte entera: 7 // 3 = {7//3}')\n\n\n#Lógicos\nprint('\\n-----Operadores de comparación-----')\nprint(f'Mayor que: 5 > 3 -> {5>3}')\nprint(f'Mayor o igual que: 5 >= 3 -> {5>=3}')\nprint(f'Menor que: 6 < 3 -> {6<3}')\nprint(f'Menor o igual que: 6<= 6 -> {6<=6}')\nprint(f'Igual que: 6 == 3 -> {6==3}')\nprint(f'Distinto de: 6 != 3 -> {6!=3}')\n\n\n#A nivel de bit\nprint('\\n-----Operadores a nivel de bit-----')\nprint (f'AND bitwise: 5 & 3 = {5&3}')\nprint(f'OR bitwsie: 5 | 3 = {5|3}')\nprint(f'Negación bitwise: ~3 = {~3}')\nprint(f'XOR bitwsie 5 ^ 3 = {5^3}')\nprint(f'Desplazamiento hacia la izquierda 1 posición: 5 << 1 = {5<<1}')\nprint(f'Desplazamiento hacia la derecha 3 posiciones: 56 >> 3 = {56>>3}')\n\n\n#Pertenencia\nprint('\\n-----Operadores de pertenencia-----')\nlista = [1,2,3]\nprint('lista = [1,2,3]')\nprint(f'Pertenencia a lista: 5 in lista = {5 in lista}')\nprint(f'No pertenencia a lista: 7 not in lista = {7 not in lista}')\n1 in lista #pertenencia a la lista: Devolverá True\n2 not in lista #no pertenece a la lista: Devolveerá False\n\n#Asignación\nprint('\\n-----Operadores de asignación-----')\nx = 873\nprint(f'Asignación: x = 6873-> {x}')\nx += 5\nprint(f'Asignación con suma: x += 5 -> {x}')\nx -= 5\nprint(f'Asignación con resta: x -= 5 -> {x}')\nx *= 2\nprint(f'Asignación con multiplicación: x *= 2 -> {x}')\nx /= 2\nprint(f'Asignación con división: x /= 2 -> {x}')\nx %= 46\nprint(f'Asignación con resto: x %= 46 -> {x}')\nx //= 6\nprint(f'Asignación con parte entera: x //= 2 -> {x}')\nx **= 4\nprint(f'Asignación con parte entera: x **= 2 -> {x}')\n\n\n#Operadores de identidad\nprint('\\n-----Operadores de identidad-----')\nprint('is : Devuelve true si los operandos se refieren al mismo objeto') \nprint('is not: Devuelve true si los operandos no se refieren al mismo objeto')\nx = 6\ny = 9\nz = 9\nprint('x = 6 \\ny = 9 \\nz = 9')\nprint(f'x is z -> {x is z}')\nprint(f'y is z -> {y is z}')\nprint(f'y is not z -> {y is not z}')\nprint(f'x is not  z -> {x is not z}')\n\n\n#Operadores de lógicos\nprint('\\n-----Operadores lógicos-----')\nprint(f'AND: 5 + 2 == 7 and 8 * 3 == 15 -> {5+2==7 and 8*3 == 15}')\nprint(f'OR: 5 + 2 == 7 or 8 * 3 == 15 -> {5+2==7 or 8*3 == 15}')\nprint(f'NOT: not 5 + 2 == 7 -> {not 5+2==7}')\n\n\n#Estructuras de control\nprint('\\n-----Estructuras de control-----')\nprint('1- Condicionales')\nx = 3\nif x ==5:\n    print('x es 5')\nelif x %2 == 0:\n    print('x es divisible entre 2')\nelse:\n    print('x no es 5 ni divisible entre 2')\n\nprint('2- Bucle for')\nfor i in range(6):\n    print(i)\n\nprint('3- Bucle while')\nx = 0\nwhile x < 4:\n    print(x)\n    x += 1\n\n#Manejo de excepciones\nprint('\\n-----Manejo de excepciones-----')\ntry:\n    print(6/2)\nexcept:\n    print('No se pudo realizar la división')\nfinally:\n    print('Se terminó el tratamiento de excepciones')\n\nprint(\"\\n======== DIFICULTAD EXTRA ========\")\nfor i in range(10,56):\n    if i%2 ==0 and i%3 == 0 and i != 16:\n        print (i)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/joshu725.py",
    "content": "# Operadores\n\n# Operadores aritmeticos\nprint(f\"Suma: {8 + 3}\")\nprint(f\"Resta: {8 - 3}\")\nprint(f\"Multiplicacion: {8 * 3}\")\nprint(f\"Division: {8 / 3}\")\nprint(f\"Potencia: {8 ** 3}\")\nprint(f\"Modulo: {8 % 3}\")\nprint(f\"Division entera: {8 // 3}\")\n\n# Operadores logicos\nprint(f\"AND: {8 + 3 == 11 and 8 - 3 == 2}\")\nprint(f\"OR: {8 + 3 == 11 or 8 - 3 == 2}\")\nprint(f\"NOT: {not 8 + 3 == 11}\")\n\n# Operadores de comparacion\nprint(f\"Mayor que: {8 > 3}\")\nprint(f\"Menor que: {8 < 3}\")\nprint(f\"Mayor o igual que: {8 >= 3}\")\nprint(f\"Menor o igual que: {8 <= 3}\")\nprint(f\"Igualdad: {8 == 3}\")\nprint(f\"Desigualdad: {8 != 3}\")\n\n# Operadores de asignacion\nnumber = 22\nprint(number)\nnumber += 2\nprint(number)\nnumber -= 2\nprint(number)\nnumber *= 3\nprint(number)\nnumber /= 2\nprint(number)\nnumber %= 3\nprint(number)\nnumber **= 2\nprint(number)\nnumber //= 2\nprint(number)\n\n# Operadores de identidad\nnumber = 18\nsecond_number = 15\n\nprint(number is second_number)\nprint(number is not second_number)\n\n# Operadores de pertenencia\nprint(\"a\" in \"gato\")\nprint(\"b\" in \"perro\")\n\n# Operadores de bits\na = 3  # 0011\nb = 5  # 0101\nprint(f\"AND : {a & b}\")  # 0001\nprint(f\"OR : {a | b}\")  # 0111\nprint(f\"XOR : {a ^ b}\")  # 0110\nprint(f\"NOT : {~b}\")  # 1010\n\n# Estructuras de control\n\n# Condicionales\nnumber = 11\nif number > 15:\n    print(\"Mayor a 15\")\nelif number > 12:\n    print(\"Mayor a 12\")\nelse:\n    print(\"Menor a 15 y 12\")\n\n# Iterativas\nfor i in range(1, 10):\n    print(i)\n\nc = 0\nwhile c < 5:\n    print(c)\n    c += 1\n\n# Excepciones\ntry:\n    print(25/0)\nexcept:\n    print(\"Error\")\n\n# Extra\nfor i in range(10, 56):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print(i)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/jptxaya.py",
    "content": "\nmy_integer_1 = 3\nmy_integer_2 = 2\n#Operadores aritmeticos\nprint(my_integer_1 + my_integer_2)\nprint(my_integer_1 - my_integer_2)\nprint(my_integer_1 * my_integer_2)\nprint(my_integer_1 / my_integer_2)\nprint(my_integer_1 // my_integer_2)\nprint(my_integer_1 % my_integer_2)\nprint(my_integer_1 ** my_integer_2)\n\n#Operadores logicos\n\nmy_boolean_1 = True\nmy_boolean_2 = False\nprint(my_boolean_1 and my_boolean_2)\nprint(my_boolean_1 or my_boolean_2)\nprint (not my_boolean_1)\n\n#Operadores comparacion\nprint( my_integer_1 == my_integer_2)\nprint( my_integer_1 != my_integer_2)\nprint( my_integer_1 > my_integer_2)\nprint( my_integer_1 >= my_integer_2)\nprint( my_integer_1 < my_integer_2)\nprint( my_integer_1 <= my_integer_2)\n\n#Operadores de Bit\n\nprint(my_integer_1 & my_integer_2)\nprint(my_integer_1 | my_integer_2)\nprint(my_integer_1 ^ my_integer_2)\nprint(my_integer_1 >> my_integer_2)\nprint(my_integer_1 << my_integer_2)\n\n#Operadores de asignacion\nmy_integer_1 += 2\nmy_integer_1 -= 2\nmy_integer_1 *= 2\nmy_integer_1 /= 2\nmy_integer_1 //= 2\nmy_integer_1 **= 2\nmy_integer_2 &= 2\nmy_integer_2 |= 2\nmy_integer_2 ^= 2\nmy_integer_2 >>= 2\nmy_integer_2 <<= 2\n\n#Operadores de pertenencia\na = [3,4,5]\nprint(3 in a)\nprint(3 not in a)\n\n#Operadores de identidad\na = 3\nb = 3\nprint (a is b)\nprint( a is not b)\n\n#Estructuras de control\n\nif a > 3:\n    print(\"A mayor que 3\")\nelif a < 3:\n    print(\"A es menor que 3\")\nelse:\n    print(\"A es igual que 3\")\n    \nmatch a:\n    case 1:\n        print(\"case 1\")\n    case 2:\n        print(\"case 2\")\n    case 3:\n        print(\"case 3\")\n    \n#While y for\nwhile a < 10:\n    print(f\"while: {a}\")\n    if a == 8:\n        break\n    a += 1\n\nprint(\"******************\")\n\nfor elem in range(0,10):\n    print(f\"for {elem}\")\n\n#Exception\ntry:\n    print(\"try\")\n    a = a / 0\nexcept:\n    print(\"Excepcion\")\nelse:\n    print(\"Else exception\")\nfinally:\n    print(\"Finally exception\")\n    \nprint(\"Dificultad Extra\")\nfor elem in range (10,56):\n    if elem % 2 == 0 and elem != 16 and not elem % 3 == 0:\n        print(elem)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/jsacristanbeltri.py",
    "content": "#Operadores Aritméticos\nprint('######## Operadores Aritméticos ########')\nprint(f'1 + 2 = {1+2}')\nprint(f'1 - 2 = {1-2}')\nprint(f'1 * 2 = {1*2}')\nprint(f'1 / 2 = {1/2}')\nprint(f'10 % 2 = {10%2}')\n\n#Operadores logicos\nprint('######## Operadores logicos ########')\nprint(f'True and True={True and True}')\nprint(f'True and False={True and False}')\nprint(f'False and True={False and True}')\nprint(f'False and False={False and True}')\nprint(f'True or True={True or True}')   \nprint(f'True or False={True or False}')  \nprint(f'False or True={False or True}')  \nprint(f'False or False={False or False}') \nprint(f'not True={not True}')\nprint(f'not False={not False}')\n#Operadores de comparacion\nprint('######## Operadores de comparacion ########')\nprint(f'1==1={1==1}')\nprint(f'1!=1={1!=1}')\nprint(f'1<1={1<1}')\nprint(f'1<=2={1<=2}')\nprint(f'1>1={1>1}')\nprint(f'1>=2={1>=2}')\n\n#Operadores de asignacion\nprint('######## Operadores de asignacion ########')\nr = 1\nr+=2\nprint(f'1+=2={r}')\nr = 1\nr-=2\nprint(f'1-=2={r}')\nr = 1\nr*=2\nprint(f'1*=2={r}')\nr = 1\nr/=2\nprint(f'1/=2={r}')\nr = 1\nr%=2\nprint(f'1%=2={r}')\nr = 1\nr//=2\nprint(f'1//=2={r}')\nr = 1\nr**=2\nprint(f'1**=2={r}')\nr = 1\nr&=2\nprint(f'1&=2={r}')\nr = 1\nr|=2\nprint(f'1|=2={r}')\nr = 1\nr^=2\nprint(f'1^=2={r}')\nr = 1\nr>>=2\nprint(f'1>>=2={r}')\nr = 1\nr<<=2\nprint(f'1<<=2={r}')\n\n#Operadores de identidad\nx = 4\ny = 2\nlista = [1, 5]\nprint('######## Operadores de identidad ########')\nprint(f'x:{x}')\nprint(f'y:{y}')\nprint(f'lista: {lista}')\nprint(f'x is lista={x is lista}')\nprint(f'x is y={x is y}')\nprint(f'x is not y={x is not y}')\nprint(f'x is 4={x is 4}')\n\n#Operadores de pertenencia\nprint('######## Operadores de pertenencia ########')\nlista = [1, 3, 2, 7, 9, 8, 6]\nprint(f'lista: {lista}')\nprint(f'4 in lista={4 in lista}')\nprint(f'3 in lista={3 in lista}')\nprint(f'4 not in lista={4 not in lista}')\n\n#Operadores a nivel de bit\nprint('######## Operadores a nivel de bit ########')\nx = 2\ny = 7\nprint(f'x:{x}')\nprint(f'y:{y}')\nprint(f'x | y = {x | y}')\nprint(f'x ^ y={x ^ y}')\nprint(f'x & y={x & y}')\nprint(f'x << 1={x << 1}')\nprint(f'x >> 1={x >> 1}')\nprint(f'~x={~x}')\n\n#Operadores de concatenacion de cadenas\nprint('######## Operadores de concatenacion de cadenas ########')\nhola = 'Hola'\npython = 'Pythonista'\nhola_python = hola + ' ' + python  # concatenamos 3 strings\nprint(f'Hola +\\' \\'+ Pythonista={hola_python}')\n\n#Condicionales\nprint('######## Condicionales ########')\nx = 2\ny = 7\nprint(f'x:{x}')\nprint(f'y:{y}')\nif(x>y):\n    print('x es mayor que y')\nelif(x<y):\n    print('x es menor que y')\nelse:\n    print('x es igual que y')\n\n#Iteracion\nprint('######## Iteracion ########')\nlista = [1, 3, 2, 7, 9, 8, 6]\ntotal=0\nfor n in lista:\n    total+=n\nprint(f'lista: {lista}')\nprint(f'La suma de todos los elementos de la lista es: {total}')\n\n\nx=10\nwhile(x>0):\n    print(f'x={x}')\n    x-=1\n\n#Excepciones\nprint('######## Excepciones ########')\ntry: \n    resultado = 4/0\nexcept Exception as e: \n    print(f'error 4/0={e}')\n\n\n'''programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3. '''\nprint('programa que imprima por consola todos los números comprendidos' \n      +' entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.')\nfor n in range(10,56):\n    if(n%2==0 and n!=16 and n%3!=0):\n        print(n)\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/jtrujilloalcocer.py",
    "content": "# #01 OPERADORES Y ESTRUCTURAS DE CONTROL\n## Ejercicio\n\n'''\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n '''\n \n #OPERADORES DE ASIGNACION\na=5\nb=10\nc=15\nd=25\n \n #OPERADORES ARITMETICOS\nprint(a + b) #Suma\nprint(a - c) #Resta\nprint(c * a) #Multimplicacion\nprint(a / d) #Division\nprint(d % a) #Resto division\nprint(a // c)#Cociente Division\nprint(a**2, b**3)#Exponentes\n\n#OPERADORES RELACIONALES\n\n#OPERADORES COMPARACION\nprint(a > b) #si a es mayor que b imprime un True, de lo contrario un False\nprint(c < d) #si c es menor que d imprime un True, de lo contrario un False\nprint(a >= d) #si a es mayor o igual que d imprime un True, de lo contrario un False\nprint(c <= b) #si c es menor o igual que b imprime un True, de lo contrario un False\n\n#OPERADORES LOGICOS \nprint(a < b and b > c) #si las dos comparaciones se cumplen imprime un True, de lo contrario un False\nprint(c > a or b < a) #si una de las dos comparaciones se cumple imprime un True, de lo contrario un false\nprint(not(c < b)) #Invierte el resultado de la comparacion.\n\n#DIFICULTAD\n'''DIFICULTAD EXTRA (opcional):\n Crea un programa que imprima por consola todos los números comprendidos\n entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3'''\n \ndef main():\n    for i in range(10,56): #Itera entre 10 y 55\n        if i % 2 == 0 and i != 16 and i % 3 != 0: #Si el numero es par, no es 16 y no es multiplo de 3\n            print(i)\n          \nif __name__ == \"__main__\": \n    main()\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/juanDAW37.py",
    "content": "\"\"\"\n* EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *    \n\"\"\"\n# Operadores:\n# Aritméticos: +, -, *, /, %, **\nsuma = 2 + 3 # Suma\nresta = 2 - 3 # Resta\nmultiplicacion = 2 * 3 # Multiplicación\ndivision = 2 / 3 # División\nmodulo = 2 % 3 # Módulo\npotencia = 2 ** 3 # Potencia\ndivision_entera = 2 // 3 #División entera\nprint(f\"Aritméticos: Suma:{suma}, Resta:{resta}, Multiplicación:{multiplicacion}, División:{division}, Módulo{modulo}, Exponenciación{potencia}, División entera:{division_entera}\")\n\n# Comparación\n# ==, !=, >, <, >=, <=\nprint(f\"Igualdad: 2 == 2: {2 == 2}\") # Si se cumple, devuelve True, en caso contrario False\nprint(f\"Diferencia: 2 != 2 {2 != 2}\") # Si se cumple, devuelve True, en caso contrario False\nprint(f\"Mayor que: 2 > 2 {2 > 2}\") # Si se cumple, devuelve True, en caso contrario False\nprint(f\"Menor que: 2 < 2 {2 < 2}\") # Si se cumple, devuelve True, en caso contrario False\nprint(f\"Mayor o igual que: 2 >= 2 {2 >= 2}\") # Si se cumple, devuelve True, en caso contrario False\nprint(f\"Menor o igual que: 2 <= 2 {2 <= 2}\") # Si se cumple, devuelve True, en caso contrario False\n\n# Lógicos \n# and, or, not\nprint(f\"and: 2 > 2 and 2 < 2 {2 > 2 and 2 > 2}\") # Ambas condiciones, derecha e izquierda deben cumplirse, de ser así, devuelve True\nprint(f\"or: 2 > 2 or 2 < 2 {2 > 2 or 2 > 2}\") # Cualquiera de las dos condiciones, derecha e izquierda deben cumplirse, de ser así, devuelve True\nprint(f\"not: not 2 + 2 = 5 { not 2 + 2 == 5} \") # En este ejemplo si no se cumple que 2 + 2 sea igual a 5, devuelve True\n\n#Asignación\n# =, +=, -=, *=, /=, %=, **=, //=\na = 11 # A la variable a se le asigna el valor 2\nprint(a)\na += 2 # Se calcula la suma más 2 y se asigna\nprint(a)\na -= 2 # Se calcula la resta menos 2 y se asigna\nprint(a)\na *= 2 # Se calcula la multiplicación por 2 y se asigna\nprint(a)\na /= 2 # Se calcula la división por 2 y se asigna\nprint(a)\na %= 2 # Se calcula el módulo entre 2 y se asigna\nprint(a)\na **= 2 # Se calcula la exponeciación por 2 y se asigna\nprint(a)\na //= 2 # Se calcula la división entera por 2 y se asigna\nprint(a)\n\n# Identidad\nnueva_var = a\nprint(f\"¿La variable nueva_var es la variable a?: {nueva_var is a}\") # Devuelve True si ambos objetos son el mismo objeto, en este caso, se crea nueva_var y se le asigna directamente a, la variable creada anteriormente\nprint(f\"¿La variable nueva_var es la variable a?: {nueva_var is not a}\") # Devuelve False si ambos objetos no son el mismo objeto, en este caso, se crea nueva_var y se le asigna directamente a, la variable creada anteriormente\n\n# Pertenencia\n# in, not in\nprint(f\"¿El número 2 pertenece a la lista [1, 2, 3, 4]?: {2 in [1,2,3,4]}\")\nprint(f\"¿El número 5 NO pertenece a la lista [1, 2, 3, 4]?: {5 not in [1,2,3,4]}\")\n\n# Bit\n# &, |, ^, ~, <<, >>\na = 2 # 2 en binario es 10\nb = 3 # 3 en binario es 11\nprint(f\"AND: {a & b}\") # 10 & 11 = 10\nprint(f\"OR: {a | b}\") # 10 | 11 = 11\nprint(f\"XOR: {a ^ b}\") # 10 ^ 11 = 1\nprint(f\"NOT: {~ b}\") # ~ 11 = -10\nprint(f\"Desplazamiento a la izquierda: {b << 2} \") # b << 2 = 1100\nprint(f'Desplazamiento a la derecha: {a >> 2}') # a << 2 = 0\n\n# Estructuras de control:\n# Condicionales\n# if, elif, else\nif 2 > 3:\n    print('2 es mayor que 3')\nelif 2 == 3:\n    print('2 es igual a 3')\nelse:\n    print('2 es menor que 3')\n\n# Iterativas\n# while, for\n# while\ni = 0\nwhile i < 10:\n    print(i)\n    i += 1\n\n# for\nfor i in range(10):\n    print(i)\n\n# Manejo de excepciones\n# try, except, finally\ntry:\n    var = 3 / 0\nexcept ArithmeticError as e:\n    print(f'Error {e}')\nfinally:\n    print('Se ejecuta siempre')\n    \n\"\"\" Dificultad extra \"\"\"\nfor i in range (10, 56):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print(f'número {i}')"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/juanRCoder.py",
    "content": "# Operadores Aritméticos\nprint(f\"Suma: {3 + 1}\")\nprint(f\"Resta: {10 - 2}\")\nprint(f\"Multiplicacion: {2 * 5}\")\nprint(f\"Potencia: {3 ** 2}\")\nprint(f\"Dividir: {27 / 9}\")             #-> devuelve un valor flotante\nprint(f\"Division_baja: {27 // 9}\")      #-> devuelve un valor entero\nprint(f\"Resto: {12 % 2}\")\n\nprint()\n# Operadores logicos\nprint(True and False)    #-> devuelve True porque ambos son True\nprint(True or False)     #-> devuelve True porque al menos hay un True\nprint(not False)         #-> devuelve siempre lo contrario, True\n\nprint()\n# Operadores de asignacion\nprint(10 > 5)   #-> 10 mayor que 5?, True\nprint(10 < 5)   #-> 10 es menor que 5?, False\nprint(5 >= 6)   #-> 5 es mayor igual que 6?, False\nprint(16 <= 3)  #-> 16 es menor igual que 3?, False\nprint(5 == 5)   #-> 5 es igual a 5?, True\nprint(9 != 4)   #-> 9 es diferente que 4?, True\n\n\nprint()\n# Operadores de identidad\nx = [4, 5, 6]\ny = [4, 5, 6]\nz = x\nprint(x is y)       #-> False, x y y no apuntan a lo mismo en memoria.\nprint(x is not y)   #-> True, x y y ahora si no apuntan a lo mismo en memoria.\nprint(x is z)       #-> True, x y z apuntan al mismo objetivo en memoria. \n\nprint()\n# Operadores de pertenencia\nlista = ['maria', 'manzana', 24, True]\nprint('maria' in lista) #-> True, 'maria' esta presente en la lista\nprint(6 not in lista)   #-> True, 6 no esta presente en la lista\n\nprint()\n# Operadores a nivel de bit\na = 5\nb = 3\nprint(f\"AND: {a & b}\")  #-> 1, en binario 001\n'''\n   101   (5 en binario)\n & 011   (3 en binario)\n ------\n   001   (Resultado en binario)\n'''\n\nprint(f\"OR: {a | b}\")   #-> 7, en binario es 111\n'''\n   101   (5 en binario)\n | 011   (3 en binario)\n ------\n   111   (Resultado en binario)\n'''\n\nprint(f\"XOR: {a ^ b}\")  #-> True, 6 en binario es 110\n'''\n   101   (5 en binario)\n ^ 011   (3 en binario)\n ------\n   110   (Resultado en binario)\n'''\n\nprint(f\"NOT: {~a}\")     #-> -5, en binario es -0b101\n                        #-> prefijo negativo en binario -> -0b\n\nprint(f\"Desplzamiento a la izquierda: {a << 1}\")    #-> 10, es decimal es 1010\n# 010 << 1 = 1010\n\nprint(f\"Desplzamiento a la derecha: {a >> 1}\")      #-> 2, es decimal es 0010\n# 010 >> 1 = 0010\n\n# CONDICINAL ELSE IF:\n# Condicionales, bloques de codigo que se cumplen si la condicion es verdadera\nlista = [1, 2, 'Maria']\n\n# Si se cumple, se imprime True\nif 2 in lista:\n    print(True)\n\n# Si en caso la primera es falsa y esta condicion es verdadera, se imprime False\nelif lista[0] == lista[1]:\n    print(False)\n     \n# Si ninguna condicion se cumple se imprime False \nelse:\n    print(False)\n\n# BUCLES:\nfor x in range(10):\n    if x == 9:\n        print(x, end='')\n    else:\n        print(x, end=', ')\n# 0, 1, 2, 3, 4, 5, 6, 7, 8, 9\n\nx = 0\nwhile x < 10:\n    print(x, end='')\n    x += 1\n# 0123456789\n\n#  DIFICULTAD EXTRA (opcional):\nfor i in range(11,55+1):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print(i, end=' ')\n\n# 14 20 22 26 28 32 34 38 40 44 46 50 52"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/juanchernandezdev.py",
    "content": "### Python Operators ###\n\n#! Arithmetic\n\n# Addition \nprint(4 + 5)\n\n# Subtraction\nprint(5 - 4)\n\n# Multiplication\nprint(5 * 5)\n\n# Division\nprint(15 / 3)\n\n#* Modulus\nprint(10 % 2)\n\n# Exponent\nprint(6**2)\n\n# Floor Division\nprint(15 // 2)\n\n#! Comparison Operators\n\n# Equal\nprint(2 == 2)\n\n#*Not Equal\nprint(2 != 2)\n\n# Less Than\nprint(5 < 10)\n\n# Greater Than\nprint(8 > 10)\n\n# Less Than Or Equal To\nprint(8 <= 8)\n\n# Greater Than Or Equal To\nprint(8 >= 8)\n\n#! Assignment Operators\n\n# Assignment Operator\nx = \"Hello\"\nprint(x)\n\n# Addition Assignment\nmy_num = 10\nmy_num += 8\nprint(my_num)\n\n# Subtraction Assignment\nmy_num = 10\nmy_num -= 5\nprint(my_num)\n\n# Multiplication Assignment\nmy_num = 10\nmy_num *= 2\nprint(my_num)\n\n# Division Assignment\nmy_num = 20\nmy_num /= 2\nprint(my_num)\n\n# Remainder Assignment\nmy_num = 50\nmy_num %= 5\nprint(my_num)\n\n# Exponent Assignment\nmy_num = 5\nmy_num **= 2\nprint(my_num)\n\n# Floor Division Assignment\nmy_num = 9\nmy_num //= 2\nprint(my_num)\n\n#! Logical Operators\n\n# And\nprint(True and True)\nprint(False and True)\n\n# Or\nprint(True or True)\nprint(False or True)\n\n# Not\nprint(not False)\n\n#! Membership Operators\n\n# In\nmy_list = [1, 5, 8, 5, 6]\nprint(1 in my_list)\nprint(10 in my_list)\n\n# Not In\nmy_list = [1, 5, 8, 5, 6]\nprint(1 not in my_list)\nprint(10 not in my_list)\n\n#! Identity Operators\n\n# Is\nnum_one = 1\nnum_two = 2\nprint(num_one is num_one)\nprint(num_one is num_two)\n\nnum_one = 1\nnum_two = num_one\nprint(num_one is num_one)\nprint(num_one is num_two)\n\n# Is Not\nnum_one = 1\nnum_two = 2\nprint(num_one is num_one)\nprint(num_one is num_two)\n\nnum_one = 1\nnum_two = num_one\nprint(num_one is not num_one)\nprint(num_one is not num_two)\n\n#! Bitwise Operators\n\n# Binary And\nprint(1 & 0)\n\n# Binary Or\nprint(1 | 0)\n\n# Binary Xor\nprint(1 ^ 0)\n\n# Binary Complement\nprint(~1)\n\n# Binary Left Shift\nprint(10 << 2)\n\n# Binary Right Shift\nprint(40 >> 2)\n\n###* Control Structures ###\n\n#! Selection Statements\n\nnum_one = 55\nnum_two = 10\n\nif num_one > num_two:\n  print(f'Num one {num_one} is greater than num two {num_two}.')\nelif num_one < num_two:\n  print(f'Num two {num_two} is greater than num two {num_one}.')\nelse:\n  print(f'Num one {num_one} and number two {num_two} are equal.')\n  \nnum_one = 55\nnum_two = 100\n\nif num_one > num_two:\n  print(f'Num one {num_one} is greater than num two {num_two}.')\nelif num_one < num_two:\n  print(f'Num two {num_two} is greater than num two {num_one}.')\nelse:\n  print(f'Num one {num_one} and number two {num_two} are equal.')\n  \nnum_one = 55\nnum_two = 55\n\nif num_one > num_two:\n  print(f'Num one {num_one} is greater than num two {num_two}.')\nelif num_one < num_two:\n  print(f'Num two {num_two} is greater than num two {num_one}.')\nelse:\n  print(f'Num one {num_one} and number two {num_two} are equal.')\n  \nmy_var_one = True\nmy_var_two = True\n\nif my_var_one and my_var_two:\n  print('All of the items are True')\nelse:\n  print('One of the Items is False')\n  \nmy_var_one = True\nmy_var_two = False\n\nif my_var_one and my_var_two:\n  print('All of the items are True')\nelse:\n  print('One of the Items is False')\n  \nmy_var_one = True\nmy_var_two = False\n\nif my_var_one or my_var_two:\n  print('One of the items is True')\nelse:\n  print('All of the Items are False')\n  \nmy_var_one = False\nmy_var_two = False\n\nif my_var_one or my_var_two:\n  print('One of the items is True')\nelse:\n  print('All of the Items are False')\n\n#! Repetition\n\ncounter = 0\n\nwhile counter <= 10:\n  print(f'Counting to ten: {counter}')\n  counter += 1\n  \nmy_nums = [1 ,5 ,4 ,8, 10, 15]\n\nfor num in my_nums:\n  print(num) if num != 5 else print(f'I\\'m a five')\n\n#! Optional Challenge\n\nprint('---Optional Challenge----')\n\nfor num in range(10, 56):\n  if num == 55:\n    print(num)\n  \n  if num % 2 == 0 and num % 3 != 0 and num != 16:\n    print(num)\n  \n  \n  \n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/juandaherrera.py",
    "content": "\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\"\"\"\n\n\ndef main():\n    for number in range(10, 56):\n        if number % 2 == 0 and number != 16 and number % 3 != 0:\n            print(number)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/juanmax2.py",
    "content": "\"\"\" \nEjemplos de operadores\n\"\"\"\n# Operadores lógicos\n\n# Ejemplo and:\nmy_num1 = 1\nmy_num2 = 10\nif my_num1 == 1 and my_num2 == 10:\n    print(\"Las dos condiciones se cumplen\")\nelse:\n    print(\"No se cumplen las condiciones\")\n# Ejemplo or:\nif my_num1 == 1 or my_num2 == 10:\n    print(\"Una de las condiciones se cumple\")\nelse:\n    print(\"Ninguna de las condiciones se cumple\")\n\n# Ejemplo not:\nif not my_num1 == 2:\n    print(\"El numero 1 no es igual a 2\")\n\n# Operadores aritméticos\nprint(f\"Suma: 9 + 3 = {9 + 3}\")\nprint(f\"Resta: 9 - 3 = {9 - 3}\")\nprint(f\"Multiplicación: 9 * 3 = {9 * 3}\")\nprint(f\"División: 9 / 3 = {9 / 3}\")\nprint(f\"Módulo: 9 % 3 = {9 % 3}\")\nprint(f\"Poténcia: 9 ** 3 = {9 ** 3}\")\nprint(f\"División entera: 9 // 3 = {9 // 3}\")\n\n# Operadores de comparación\nprint(f\"Operador igualdad: 9 == 3 es {9 == 3}\")\nprint(f\"Operador desigualdad: 9 != 3 es {9 != 3}\")\nprint(f\"Operador mayor que: 9 > 3 es {9 > 3}\")\nprint(f\"Operador menor que: 9 < 3 es {9 < 3}\")\nprint(f\"Operador mayor o igual que: 9 >= 3 es {9 >= 3}\")\nprint(f\"Operador menor o igual que: 9 <= 3 es {9 <= 3}\")\n\n# Operadores de asignación\nnumero = 1 # Asignación\nprint(numero)\nnumero += 1 # Asignación y suma\nprint(numero)\nnumero -= 1 # Asignación y resta\nprint(numero)\nnumero *= 2 # Asignación y multiplicación\nprint(numero)\nnumero /= 2 # Asignación y división\nprint(numero)\nnumero **= 2 # Asignación y potencia\nprint(numero)\nnumero %= 2 # Asignación y módulo\nprint(numero)\nnumero //= 2 # Asignación y división entera\nprint(numero)\n\n# Operadores de identidad\nnuevo_numero = numero\nprint(f\"numero is nuevo_numero es {numero is nuevo_numero}\")\nprint(f\"numero is not nuevo_numero es {numero is not nuevo_numero}\")\n\n# Operadores de pertenencia\n\nprint(f\"'a' in 'juanma' = {'a' in 'juanma'}\")\nprint(f\"'d' not in 'juanma' = {'d' not in 'juanma'}\")\n\n# Operadores de bit\nx = 9\ny = 3\nprint(f\"AND: 9 & 3 = {9 & 3}\")\nprint(f\"OR: 9 | 3 = {9 | 3}\")\nprint(f\"XOR: 9 ^ 3 = {9 ^ 3}\")\nprint(f\"NOT: ~9 = {~9}\")\nprint(f\"Desplazamiento a la derecha: 9 >> 3 = {9 >> 3}\")\nprint(f\"Desplazamiento a la izquierda: 9 << 3 = {9 << 3}\")\n\n\"\"\"\nEstructuras de control\n\"\"\"\n# IF:\nif my_num1 == 1 and my_num2 == 10:\n    print(\"Las dos condiciones se cumplen\")\nelif my_num == 1 or my_num2 == 10:\n    print(\"Una de las condiciones se cumple\")\nelse:\n    print(\"No se cumplen las condiciones\")\n    \n# FOR:\nfor i in range(0,11):\n    print(i)\n\n# WHILE:\nwhile i < 10:\n    print(i)\n    i += 1\n\n# Manejo de excepciones:\ntry: \n    print(10 / 0)\nexcept:\n    print(\"Se ha producido un error\")\nfinally:\n    print(\"Ha finalizado el manejo de excepciones\")\n\n\n\"\"\"Ejercicio extra:\nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\"\"\"\n\nfor i in range(10,56):\n    if (i % 2 == 0) and (not i == 16) and (i % 3 != 0):\n        print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/juanppdev.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n \"\"\"\n\n# Operadores Aritmeticos\nprint(f\"5 + 5 = {5 + 5}\") # Suma\nprint(f\"5 - 5 = {5 - 5}\") # resta\nprint(f\"5 * 5 = {5 * 5}\") # Multiplicacion\nprint(f\"5 / 5 = {5 / 5}\") # Division\nprint(f\"5 % 5 = {5 % 5}\") # Modulo\nprint(f\"5 ** 5 = {5 ** 5}\") # Exponente\nprint(f\"5 // 5 = {5 // 5}\") # Cociente\n\n# Operadoes Logicos\nprint(True and True)   # and\nprint(False or True)   # or\nprint(not True)   # not\n\n# Operadores de Comparacion\nx = 4\ny = 8\nprint(x > y) # >\nprint(x >= y) # >=\nprint(x < y) # <\nprint(x <= y) # <=\nprint(x == y) # ==\nprint(x != y) # !=\n\n# Operadores de Asignacion\na = 7\nb = 2\nprint(\"Operadores de Asignacion\")\nx=a; x+=b;  print(\"x+=\", x)  # 9\nx=a; x-=b;  print(\"x-=\", x)  # 5\nx=a; x*=b;  print(\"x*=\", x)  # 14\nx=a; x/=b;  print(\"x/=\", x)  # 3.5\nx=a; x%=b;  print(\"x%=\", x)  # 1\nx=a; x//=b; print(\"x//=\", x) # 3\nx=a; x**=b; print(\"x**=\", x) # 49\nx=a; x&=b;  print(\"x&=\", x)  # 2\nx=a; x|=b;  print(\"x|=\", x)  # 7\nx=a; x^=b; print(\"x^=\", x)   # 5\nx=a; x>>=b; print(\"x>>=\", x) # 1\nx=a; x<<=b; print(\"x<<=\", x) # 28\n\n# Operadores de Identidad\na = 10\nb = 10\n\nprint(a is b) # is\nprint(a is not b) # is not\n\n# Asignacion de pertenencia\nlista = [1, 3, 2, 7, 9, 8, 6]\nprint(4 in lista) # in\nprint(6 not in lista) # not in\n\n# Asignacion de bitwise\na = 0b1101\nb = 0b1011\nprint(bin(a & b)) # &\nprint(bin(a | b)) # |\na = 40\nprint(bin(a))\nprint(bin(~a)) # ~\nx = 0b0110 ^ 0b1010\nprint(bin(x)) # ^\na=0b1000\nprint(bin(a>>2)) # >>\na=0b0001\nprint(bin(a<<3)) # <<\n\n# Condicionales\nnumero = int(input(\"Escriba un número positivo: \"))\nif numero < 0:\n    print(\"¡Le he dicho que escriba un número positivo!\")\nprint(f\"Ha escrito el número {numero}\")\n\n# Iteradores\ncontador = 1\nwhile contador <= 10:\n    print(\"Paso: \",str(contador))\n    contador+=1\n\n# Excepciones\nwhile True:\n    try:\n        x = int(input(\"Ingresa un Numero: \"))\n        break\n    except ValueError:\n        print(\"Oops!  Ese no es un numero valido.  Intentalo nuevamente...\")\n\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\"\"\"\n\nfor numbers in range(10, 56):\n    if numbers % 2 == 0 and numbers != 16 and numbers % 3 != 0:\n        print(numbers)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/jucedinv.py",
    "content": "#01 - OPERADORES Y ESTRUCTURAS DE CONTROL\nprint('01 - OPERADORES Y ESTRUCTURAS DE CONTROL')\n#Addition - Adds values on either side of the operator.\nr_addition1 = 10 + 20 #10 + 20 will give 30\nr_addition2 = 10 + -20 #10 + -20 will give -10\nprint('Addition - Adds values on either side of the operator.')\nprint('10 + 20 = ', r_addition1)\nprint('10 + -20 = ', r_addition2)\n#Subtraction - Subtracts right hand operand from left hand operand.\nr_subtraction1 = 20 - 10 #20 - 10 will give 10\nr_subtraction2 = 10 - 20 #10 - 20 will give -10\nprint('Subtraction - Subtracts right hand operand from left hand operand.')\nprint('20 - 10 = ', r_subtraction1)\nprint('10 - 20 = ', r_subtraction2)\n#Multiplication - Multiplies values on either side of the operator.\nr_multiplication1 = 10 * 20 #10 * 20 will give 200\nr_multiplication2 = 10 * 0.5 #10 * 0.5 will give 5.0\nprint('Multiplication - Multiplies values on either side of the operator.')\nprint('10 * 20 = ', r_multiplication1)\nprint('10 * 0.5 = ', r_multiplication2)\n#Division - Divides left hand operand by right hand operand.\nr_division1 = 20 / 10 #20 / 10 will give 2\nr_division2 = 10 / 20 #10 / 20 will give 0.5\nprint('Division - Divides left hand operand by right hand operand.')\nprint('20 / 10 = ', r_division1)\nprint('10 / 20 = ', r_division2)\n#Modulus - Divides left hand operand by right hand operand and returns remainder.\nr_modulus1 = 20 % 10 #20 % 10 will give 0\nr_modulus2 = 22 % 10 #22 % 10 will give 2\nprint('Modulus - Divides left hand operand by right hand operand and returns remainder.')\nprint('20 % 10 = ', r_modulus1)\nprint('22 % 10 = ', r_modulus2)\n#Exponent - Performs exponential (power) calculation on operators.\nr_exponent1 = 10 ** 2 # 10 ** 2 will give 100\nr_exponent2 = 100 ** 0.5 # 100 ** 0.5 will give 10\nprint('Exponent - Performs exponential (power) calculation on operators.')\nprint('10 ** 2 = ', r_exponent1)\nprint('100 ** 0.5 = ', r_exponent2)\n#Floor Division - The division of operands where the result is the quotient in which the dig its after the decimal point are removed.\nr_fdivision1 = 9 // 2 #9//2 is equal to 4\nr_fdivision2 = 9.0 // 2.0 #9.0//2.0 is equal to 4.0\nprint('Floor Division - The division of operands where the result is the quotient in which the dig its after the decimal point are removed.')\nprint('9 // 2 = ', r_fdivision1)\nprint('9.0 // 2.0 = ', r_fdivision2)\n#Equality - checks if the value of two operands are equal or not, if yes then condition becomes true.\nr_equality1 = 20 == 10 #20 == 10 is not true.\nr_equality2 = 10 == 10 #10 == 10 is true.\nprint('Equality - checks if the value of two operands are equal or not, if yes then condition becomes true.')\nprint('20 == 10 = ', r_equality1)\nprint('10 == 10 = ', r_equality2)\n#Inequality - Checks if the value of two operands are equal or not, if values are not equal then condition becomes true.\nr_inequalityA1 = 20 != 10 #(20 != 10) is true.\nr_inequalityA2 = 10 != 10 #(10 != 10) is not true.\nprint('Inequality - Checks if the value of two operands are equal or not, if values are not equal then condition becomes true.')\nprint('20 != 10 = ', r_inequalityA1)\nprint('10 != 10 = ', r_inequalityA2)\n#Inequality (obsolet) - Checks if the value of two operands are equal or not, if values are not equal then condition becomes true.\n#r_inequalityB1 = 20 <> 10 #(20 <> 10) is true. This is similar to != operator in version 2.0\n#r_inequalityB2 = 10 <> 10 #(10 <> 10) is not true. This is similar to != operator in version 2.0\n#Greater-than - Checks if the value of left operand is greater than the value of right operand, if yes then condition becomes true.\nr_greater_than1 = 20 > 10 #(20 > 10) is true.\nr_greater_than2 = 10 > 20 #(10 > 20) is not true.\nprint('Greater-than - Checks if the value of left operand is greater than the value of right operand, if yes then condition becomes true.')\nprint('20 > 10 = ', r_greater_than1)\nprint('10 > 20 = ', r_greater_than2)\n#Less-than - Checks if the value of left operand is less than the value of right operand, if yes then condition becomes true.\nr_less_than1 = 20 < 10 #(20 > 10) is not true.\nr_less_than2 = 10 < 20 #(10 > 20) is true.\nprint('Less-than - Checks if the value of left operand is less than the value of right operand, if yes then condition becomes true.')\nprint('20 < 10 = ', r_less_than1)\nprint('10 < 20 = ', r_less_than2)\n#Greater than or equal to - Checks if the value of left operand is greater than or equal to the value of right operand, if yes then condition becomes true.\nr_greater_than_or_equal_to1 = 20 >= 10#(20 >= 10) is true.\nr_greater_than_or_equal_to2 = 10 >= 20#(10 >= 20) is not true.\nr_greater_than_or_equal_to3 = 20 >= 20#(20 >= 20) is true.\nprint('Greater than or equal to - Checks if the value of left operand is greater than or equal to the value of right operand, if yes then condition becomes true.')\nprint('20 >= 10 = ', r_greater_than_or_equal_to1)\nprint('10 >= 20 = ', r_greater_than_or_equal_to2)\nprint('20 >= 20 = ', r_greater_than_or_equal_to3)\n#Less than or equal to - Checks if the value of left operand is less than or equal to the value of right operand, if yes then condition becomes true.\nr_less_than_or_equal_to1 = 20 <= 10#(20 >= 10) is not true.\nr_less_than_or_equal_to2 = 10 <= 20#(10 >= 20) is true.\nr_less_than_or_equal_to3 = 20 <= 20#(20 >= 20) is true.\nprint('Less than or equal to - Checks if the value of left operand is less than or equal to the value of right operand, if yes then condition becomes true.')\nprint('20 <= 10 = ', r_less_than_or_equal_to1)\nprint('10 <= 20 = ', r_less_than_or_equal_to2)\nprint('20 <= 20 = ', r_less_than_or_equal_to3)\n#Assignment - Simple assignment operator - Assigns values from right side operands to left side operand.\nr_assignment1 = 10#r_assignment1 = 10 will assigne value 10 into r_assignment1\nr_assignment2 = 20#r_assignment2 = 20 will assigne value 20 into r_assignment2\nr_assignment3 = 10 + 20#r_assignment3 = 10 + 20 will assigne value of 10 + 20 into r_assignment3\nprint('Assignment - Simple assignment operator - Assigns values from right side operands to left side operand.')\nprint('r_assignment1 = 10 ----> Value of r_assignment1 = ', r_assignment1)\nprint('r_assignment2 = 20 ----> Value of r_assignment2 = ', r_assignment2)\nprint('r_assignment3 = 10 + 20 ----> Value of r_assignment3 = ', r_assignment3)\n#Addition assignment - Add AND assignment operator, It adds right operand to the left operand and assig n the result to left operand.\n#c += a is equivalent to c = c + a\nr_addition_assignment1 = 1\nr_addition_assignment1 += 3#r_addition_assignment1 += 3 is equivalent to r_addition_assignment1 = r_addition_assignment1 + 3, result 4.\nr_addition_assignment2 = 1\nr_addition_assignment2 += -3#r_addition_assignment2 += -3 is equivalent to r_addition_assignment2 = r_addition_assignment1 + -3, result -2.\nprint('Addition assignment - Add AND assignment operator, It adds right operand to the left operand and assig n the result to left operand.')\nprint('r_addition_assignment1 = 1')\nprint('r_addition_assignment1 += 3 ----> Value of r_addition_assignment1 = ', r_addition_assignment1)\nprint('r_addition_assignment2 = 1')\nprint('r_addition_assignment2 += -3 ----> Value of r_addition_assignment2 = ', r_addition_assignment2)\n#Subtract assignment - Subtract AND assignment operator, It subtracts right operand from the left operand and assig n the result to left operand.\n#c -= a is equivalent to c = c - a\nr_subtraction_assignment1 = 10\nr_subtraction_assignment1 -= 3#r_subtraction_assignment1 -= 3 is equivalent to r_subtraction_assignment1 = r_subtraction_assignment1 - 3, result 7.\nr_subtraction_assignment2 = 10\nr_subtraction_assignment2 -= -3#r_subtraction_assignment2 -= -3 is equivalent to r_subtraction_assignment2 = r_subtraction_assignment2 - -3, result 13.\nprint('Subtract assignment - Subtract AND assignment operator, It subtracts right operand from the left operand and assig n the result to left operand.')\nprint('r_subtraction_assignment1 = 10')\nprint('r_subtraction_assignment1 -= 3 ----> Value of r_subtraction_assignment1 = ', r_subtraction_assignment1)\nprint('r_subtraction_assignment2 = 10')\nprint('r_subtraction_assignment2 -= -3 ----> Value of r_subtraction_assignment2 = ', r_subtraction_assignment2)\n#Multiplication assignment - Multiply AND assignment operator, It multiplies right operand with the left operand and assign the result to left operand.\n#c *= a is equivalent to c = c * a\nr_multiplication_assignment1 = 10\nr_multiplication_assignment1 *= 2#r_multiplication_assignment1 *= 2 is equivalent to r_multiplication_assignment1 = r_multiplication_assignment1 * 2, result 20.\nr_multiplication_assignment2 = 10\nr_multiplication_assignment2 *= 0.5#r_multiplication_assignment2 *= 0.5 is equivalent to r_multiplication_assignment2 = r_multiplication_assignment2 * 0.5, result 5.\nprint('Multiplication assignment - Multiply AND assignment operator, It multiplies right operand with the left operand and assign the result to left operand.')\nprint('r_multiplication_assignment1 = 10')\nprint('r_multiplication_assignment1 *= 2 ----> Value of r_multiplication_assignment1 = ', r_multiplication_assignment1)\nprint('r_multiplication_assignment2 = 10')\nprint('r_multiplication_assignment2 *= 0.5 ----> Value of r_multiplication_assignment2 = ', r_multiplication_assignment2)\n#Division assignment - Divide AND assignment operator, It divides left operand with the rig ht operand and assign the result to left operand.\n#c /= a is equivalent to c = c / a\nr_division_assignment1 = 10\nr_division_assignment1 /= 2#r_division_assignment1 /= 2 is equivalent to r_division_assignment1 = r_division_assignment1 / 2, result 5.0.\nr_division_assignment2 = 10\nr_division_assignment2 /= 0.5#r_division_assignment2 /= 0.5 is equivalent to r_division_assignment2 = r_division_assignment2 / 0.5, result 20.0.\nprint('Division assignment - Divide AND assignment operator, It divides left operand with the rig ht operand and assign the result to left operand.')\nprint('r_division_assignment1 = 10')\nprint('r_division_assignment1 /= 2 ----> Value of r_division_assignment1 = ', r_division_assignment1)\nprint('r_division_assignment2 = 10')\nprint('r_division_assignment2 /= 0.5 ----> Value of r_division_assignment2 = ', r_division_assignment2)\n#Modulus assignment - Modulus AND assignment operator, It takes modulus using two operands and assign the result to left operand.\n#c %= a is equivalent to c = c % a\nr_modulus_assignment1 = 10\nr_modulus_assignment1 %= 2#r_modulus_assignment1 %= 2 is equivalent to r_modulus_assignment1 = r_modulus_assignment1 % 2, result 0.\nr_modulus_assignment2 = 10\nr_modulus_assignment2 %= 3#r_modulus_assignment2 %= 3 is equivalent to r_modulus_assignment2 = r_modulus_assignment2 % 3, result 1.\nprint('Modulus assignment - Modulus AND assignment operator, It takes modulus using two operands and assign the result to left operand.')\nprint('r_modulus_assignment1 = 10')\nprint('r_modulus_assignment1 %= 2 ----> Value of r_modulus_assignment1 = ', r_modulus_assignment1)\nprint('r_modulus_assignment2 = 10')\nprint('r_modulus_assignment2 %= 3 ----> Value of r_modulus_assignment2 = ', r_modulus_assignment2)\n#Exponent assignment - \"Exponent AND assignment operator, Performs exponential (power) calculation on operators and assign value to the left operand.\n#c **= a is equivalent to c = c ** a\nr_exponent_assignment1 = 10\nr_exponent_assignment1 **= 2#r_exponent_assignment1 **= 2 is equivalent to r_exponent_assignment1 = r_exponent_assignment1 ** 2, result 100.\nr_exponent_assignment2 = 100\nr_exponent_assignment2 **= 0.5#r_exponent_assignment2 **= 0.5 is equivalent to r_exponent_assignment2 = r_exponent_assignment2 ** 0.5, result 10.0.\nprint('Exponent assignment - \"Exponent AND assignment operator, Performs exponential (power) calculation on operators and assign value to the left operand.')\nprint('r_exponent_assignment1 = 10')\nprint('r_exponent_assignment1 **= 2 ----> Value of r_exponent_assignment1 = ', r_exponent_assignment1)\nprint('r_exponent_assignment2 = 100')\nprint('r_exponent_assignment2 **= 0.5 ----> Value of r_exponent_assignment2 = ', r_exponent_assignment2)\n#Floor Division assignment - Floor Dividion and assigns a value, Performs floor division on operators and assign value to the left operand.\n#c //= a is equivalent to c = c // a\nr_floor_division_assignment1 = 9\nr_floor_division_assignment1 //= 2#r_floor_division_assignment1 //= 2 is equivalent to r_floor_division_assignment1 = r_floor_division_assignment1 // 2, result 4.\nr_floor_division_assignment2 = 11\nr_floor_division_assignment2 //= 3#r_floor_division_assignment2 //= 3 is equivalent to r_floor_division_assignment2 = r_floor_division_assignment2 // 3, result 3.\nprint('Floor Division assignment - Floor Dividion and assigns a value, Performs floor division on operators and assign value to the left operand.')\nprint('r_floor_division_assignment1 = 9')\nprint('r_floor_division_assignment1 //= 2 ----> Value of r_floor_division_assignment1 = ', r_floor_division_assignment1)\nprint('r_floor_division_assignment2 = 11')\nprint('r_floor_division_assignment2 //= 3 ----> Value of r_floor_division_assignment2 = ', r_floor_division_assignment2)\n#Logical AND operator - If both the operands are true then then condition becomes true.\nr_logical_and1 = False and False #(False and False) is not true.\nr_logical_and2 = True and False #(True and False) is not true.\nr_logical_and3 = False and True #(False and True) is not true.\nr_logical_and4 = True and True #(True and True) is true.\nprint('Logical AND operator - If both the operands are true then then condition becomes true.')\nprint('False and False = ', r_logical_and1)\nprint('True  and False = ', r_logical_and2)\nprint('False and True  = ', r_logical_and3)\nprint('True  and True  = ', r_logical_and4)\n#Logical OR Operator - If any of the two operands are non-zero then then condition becomes true.\nr_logical_or1 = False or False #(False or False) is not true.\nr_logical_or2 = True or False #(True or False) is true.\nr_logical_or3 = False or True #(False or True) is true.\nr_logical_or4 = True or True #(True or True) is true.\nprint('Logical OR Operator - If any of the two operands are non-zero then then condition becomes true.')\nprint('False or False = ', r_logical_or1)\nprint('True  or False = ', r_logical_or2)\nprint('False or True  = ', r_logical_or3)\nprint('True  or True  = ', r_logical_or4)\n#Logical XOR Operator - If any of the two operands are diferents then then condition becomes true.\nr_logical_xor1 = False ^ False #(False ^ False) is not true.\nr_logical_xor2 = True ^ False #(True ^ False) is true.\nr_logical_xor3 = False ^ True #(False ^ True) is true.\nr_logical_xor4 = True ^ True #(True ^ True) is not true.\nprint('Logical XOR Operator - If any of the two operands are diferents then then condition becomes true.')\nprint('False ^ False = ', r_logical_xor1)\nprint('True  ^ False = ', r_logical_xor2)\nprint('False ^ True  = ', r_logical_xor3)\nprint('True  ^ True  = ', r_logical_xor4)\n#Logical NOT Operator - Use to reverses the logical state of its operand. If a condition is true then Logical NOT operator willmake false.\nr_logical_not1 = not False #not False is true.\nr_logical_not2 = not True #not True is not true.\nprint('Logical NOT Operator - Use to reverses the logical state of its operand. If a condition is true then Logical NOT operator willmake false.')\nprint('not False = ', r_logical_not1)\nprint('not True  = ', r_logical_not2)\n#Membership operator found - Evaluates to true if it finds a variable in the specified sequence and false otherwise.\nr_membership_found1 = 1 in [1,2,3,4] # 1 in [1,2,3,4] is true, because 1 is member of list [1,2,3,4].\nr_membership_found2 = 10 in [1,2,3,4] # 10 in [1,2,3,4] is not true, because 10 not is member of list [1,2,3,4].\nprint('Membership operator found - Evaluates to true if it finds a variable in the specified sequence and false otherwise.')\nprint('1  in [1,2,3,4] = ', r_membership_found1)\nprint('10 in [1,2,3,4] = ', r_membership_found2)\n#Membership operator not found - Evaluates to true if it does not finds a variable in the specified sequence and false otherwise.\nr_membership_notfound1 = 1 not in [1,2,3,4] # 1 not in [1,2,3,4] is not true, because 1 is member of list [1,2,3,4].\nr_membership_notfound2 = 10 not in [1,2,3,4] # 10 not in [1,2,3,4] is true, because 10 not is member of list [1,2,3,4].\nprint('Membership operator not found - Evaluates to true if it does not finds a variable in the specified sequence and false otherwise.')\nprint('1  not in [1,2,3,4] = ', r_membership_notfound1)\nprint('10 not in [1,2,3,4] = ', r_membership_notfound2)\n#Identity operator - is\t\"Evaluates to true if the variables on either side of the operator point to the same object and false otherwise.\n#x is y, here is results in 1 if id(x) equals id(y).\na = [1,3,5,10]\nb = a\nc = [1,3,5,10]\nr_identity1 = a is b # a is b is true because id(a) is equals to id(b).\nr_identity2 = a is c # a is b is not true because id(a) is not equals to id(c).\nprint('Identity operator - is\t\"Evaluates to true if the variables on either side of the operator point to the same object and false otherwise.')\nprint('a = [1,3,5,10]')\nprint('id(a) = ',id(a))\nprint('b = a')\nprint('id(b) = ',id(b))\nprint('c = [1,3,5,10]')\nprint('id(c) = ',id(c))\nprint('a is b = ', r_identity1)\nprint('a is c = ', r_identity2)\n#Identity operator inverse - Evaluates to false if the variables on either side of the operator point to the same object and true otherwise.\n#x is not y, here is not results in 1 if id(x) is not equal to id(y).\na = [1,3,5,10]\nb = a\nc = [1,3,5,10]\nr_identity_inv1 = a is not b # a is not b is not true because id(a) is equals to id(b).\nr_identity_inv2 = a is not c # a is not b is true because id(a) is not equals to id(c).\nprint('Identity operator inverse - Evaluates to false if the variables on either side of the operator point to the same object and true otherwise.')\nprint('a = [1,3,5,10]')\nprint('id(a) = ',id(a))\nprint('b = a')\nprint('id(b) = ',id(b))\nprint('c = [1,3,5,10]')\nprint('id(c) = ',id(c))\nprint('a is not b = ', r_identity_inv1)\nprint('a is not c = ', r_identity_inv2)\n\n#Binary AND Operator - Perform bit a bit (bitwise) and. Copies a bit to the result if it exists in both operands.\nr_binary_and1 = 10 & 20 # (10 & 7) binary representation: (001010 & 010100), will give 0 because is 000000 in binary.\nr_binary_and2 = 10 & 7 # (10 & 7) binary representation: (1010 & 0111), will give 2 because is 0010 in binary.\nprint('Binary AND Operator - Perform bit a bit (bitwise) and. Copies a bit to the result if it exists in both operands.')\nprint('10 & 20 = ',r_binary_and1)\nprint(format(10, '08b'), ' &')\nprint(\"\\033[4m\"+format(20, '08b')+\"\\033[0m\")\nprint(format(r_binary_and1,'08b'))\nprint('10 & 7 = ',r_binary_and2)\nprint(format(10, '08b'), ' &')\nprint(\"\\033[4m\"+format(7, '08b')+\"\\033[0m\")\nprint(format(r_binary_and2,'08b'))\n#Binary OR Operator - Perform bit a bit (bitwise) or. Copies a bit if it exists in eather operand.\nr_binary_or1 = 10 | 20 # (10 | 7) binary representation: (001010 | 010100), will give 30 because is 011110 in binary.\nr_binary_or2 = 10 | 7 # (10 | 7) binary representation: (1010 | 0111), will give 15 because is 1111 in binary.\nprint('Binary OR Operator - Perform bit a bit (bitwise) or. Copies a bit if it exists in eather operand.')\nprint('10 | 20 = ',r_binary_or1)\nprint(format(10, '08b'), ' |')\nprint(\"\\033[4m\"+format(20, '08b')+\"\\033[0m\")\nprint(format(r_binary_or1,'08b'))\nprint('10 & 7 = ',r_binary_or2)\nprint(format(10, '08b'), ' |')\nprint(\"\\033[4m\"+format(7, '08b')+\"\\033[0m\")\nprint(format(r_binary_or2,'08b'))\n#Binary XOR Operator - Perform bit a bit (bitwise) xor. Copies the bit if it is set in one operand but not both.\nr_binary_xor1 = 10 ^ 20 # (10 ^ 7) binary representation: (001010 ^ 010100), will give 30 because is 011110 in binary.\nr_binary_xor2 = 10 ^ 7 # (10 ^ 7) binary representation: (1010 ^ 0111), will give 13 because is 1101 in binary.\nprint('Binary XOR Operator - Perform bit a bit (bitwise) xor. Copies the bit if it is set in one operand but not both.')\nprint('10 ^ 20 = ',r_binary_xor1)\nprint(format(10, '08b'), ' ^')\nprint(\"\\033[4m\"+format(20, '08b')+\"\\033[0m\")\nprint(format(r_binary_xor1,'08b'))\nprint('10 ^ 7 = ',r_binary_xor2)\nprint(format(10, '08b'), ' ^')\nprint(\"\\033[4m\"+format(7, '08b')+\"\\033[0m\")\nprint(format(r_binary_xor2,'08b'))\n#Binary Ones Complement Operator - Perform not each bit in 8 bits, this result a negative numbre (Two's Complement Representation).\n#Is unary and has the efect of 'flipping ' bits.\nr_binary_complement1 = ~7 # (~7) binary representation: (~00000111), will give -8 because is 11111000 in binary (Two's Complement Representation).\nr_binary_complement2 = ~10 # (~7) binary representation: (~00001010), will give -11 because is 11110101 in binary (Two's Complement Representation).\nr_binary_complement3 = ~20 # (~7) binary representation: (~00010100), will give -21 because is 11101011 in binary (Two's Complement Representation).\nprint('Binary Ones Complement Operator - Perform not each bit in 8 bits, this result a negative numbre (Two\\'s Complement Representation).')\nprint('~7 = ',r_binary_complement1)\nprint(format(7, '08b'), ' (Standard binary form of 7)')\nprint(format((1 << 8) + r_binary_complement1,'08b'), ' (Two\\'s Complement Representation of -8)')\nprint(format(r_binary_complement1,'08b'), ' (Standard binary form of -8)')\nprint('~10 = ',r_binary_complement2)\nprint(format(10, '08b'), ' (Standard binary form of 10)')\nprint(format((1 << 8) + r_binary_complement2,'08b'), ' (Two\\'s Complement Representation of -11)')\nprint(format(r_binary_complement2,'08b'), ' (Standard binary form of -11)')\nprint('~20 = ',r_binary_complement3)\nprint(format(20, '08b'), ' (Standard binary form of 20)')\nprint(format((1 << 8) + r_binary_complement3,'08b'), ' (Two\\'s Complement Representation of -21)')\nprint(format(r_binary_complement3,'08b'), ' (Standard binary form of -21)')\n#Binary Left Shift Operator - The left operands value is moved left by the number of bits specified by the right operand.\nr_binary_left_shift1 = 7 << 1 # (7) << 1 binary representation: (00000111) << 1, wil give 14 because is 00001110 in binary.\nr_binary_left_shift2 = 7 << 2 # (7) << 2 binary representation: (00000111) << 2, wil give 28 because is 00011100 in binary.\nr_binary_left_shift3 = 10 << 3 # (7) << 3 binary representation: (00001010) << 3, wil give 80 because is 01010000 in binary.\nprint('Binary Left Shift Operator - The left operands value is moved left by the number of bits specified by the right operand.')\nprint('7 << 1 = ',r_binary_left_shift1)\nprint(format(7, '08b'), ' << 1')\nprint(format(r_binary_left_shift1,'08b'))\nprint('7 << 2 = ',r_binary_left_shift2)\nprint(format(7, '08b'), ' << 2')\nprint(format(r_binary_left_shift2,'08b'))\nprint('10 << 3 = ',r_binary_left_shift3)\nprint(format(10, '08b'), ' << 3')\nprint(format(r_binary_left_shift3,'08b'))\n#Binary Right Shift Operator - The left operands value is moved rig ht by the number of bits specified by the right operand.\nr_binary_right_shift1 = 7 >> 1 # (7) >> 1 binary representation: (00000111) >> 1, wil give 3 because is 00000011 in binary.\nr_binary_right_shift2 = 7 >> 2 # (7) >> 2 binary representation: (00000111) >> 2, wil give 1 because is 00000001 in binary.\nr_binary_right_shift3 = 10 >> 3 # (7) >> 3 binary representation: (00001010) >> 3, wil give 1 because is 00000001 in binary.\nprint('Binary Right Shift Operator - The left operands value is moved rig ht by the number of bits specified by the right operand.')\nprint('7 >> 1 = ',r_binary_right_shift1)\nprint(format(7, '08b'), ' >> 1')\nprint(format(r_binary_right_shift1,'08b'))\nprint('7 >> 2 = ',r_binary_right_shift2)\nprint(format(7, '08b'), ' >> 2')\nprint(format(r_binary_right_shift2,'08b'))\nprint('10 >> 3 = ',r_binary_right_shift3)\nprint(format(10, '08b'), ' >> 3')\nprint(format(r_binary_right_shift3,'08b'))\n\n#The IF statement (single line) - They allow specific line of code to execute only when a given condition evaluates to True.\nedad = 17\nprint('The IF statement (single line) - They allow specific line of code to execute only when a given condition evaluates to True.')\nprint('edad = ', edad)\nif edad < 18: print('Es menor de edad.')\n#The IF statement - They allow specific blocks of code to execute only when a given condition evaluates to True.\nedad = 18\nprint('The IF statement - They allow specific blocks of code to execute only when a given condition evaluates to True.')\nprint('edad = ', edad)\nif edad >= 18:\n    print('Es mayor de edad.')\n    print('Puede Votar.')\n#The ELSE statement with IF - Provide an alternative block of code to be executed when none of the preceding conditions are met.\n#It acts as a \"catch-all\" for any scenario not covered by the previous conditions.\nedad = 0\nprint('The ELSE statement with IF - Provide an alternative block of code to be executed when none of the preceding conditions are met.')\nprint('edad = ', edad)\nif edad >= 18:\n    print('Es mayor de edad.')\n    print('Puede Votar.')\nelse:\n    print('No es mayor de edad.')\n#The ELIF statement - Is used in conjunction with an if statement to check for multiple conditions sequentially.\nedad = 5\nprint('The ELIF statement - Is used in conjunction with an if statement to check for multiple conditions sequentially.')\nprint('edad = ', edad)\nif edad >= 18:\n    print('Es mayor de edad.')\n    print('Puede Votar.')\nelif edad >= 0:\n    print('Es menor de edad.')\n    print('No puede Votar.')\nelse:\n    print('Edad no válida')\n#The WHILE loop (single statement suit) -  used for repeatedly executing a single statement as long as a specified condition remains true.\ncount = 1\nprint('The WHILE loop (single statement suit) -  used for repeatedly executing a single statement as long as a specified condition remains true.')\nwhile count <= 5: print(count); count += 1\n#The WHILE loop - used for repeatedly executing a block of code as long as a specified condition remains true.\ncount = 2\nprint('The WHILE loop - used for repeatedly executing a block of code as long as a specified condition remains true.')\nwhile count <= 10:\n    print(count)\n    count += 2\n#The ELSE statement with WHILE - The else block associated with a while loop executes only if the loop terminates normally, meaning the while condition eventually becomes False.\ncount = 1\nprint('The ELSE statement with WHILE - The else block associated with a while loop executes only if the loop terminates normally, meaning the while condition eventually becomes False.')\nwhile count <= 5:\n    print(count)\n    count += 1\nelse:\n    print('Loop finished normaly.')\n#The BREAK statement with WHILE - The break statement provides a way to exit this loop prematurely, even if the while condition is still True.\ncount = 1\nprint('The BREAK statement with WHILE - The break statement provides a way to exit this loop prematurely, even if the while condition is still True.')\nwhile count <= 5:\n    print(count)\n    if count == 4: break\n    count += 1\nelse:\n    print('This will NOT be printed because of break.')\n#The CONTINUE statement with WHILE - used to skip the rest of the code within the current iteration of the loop and immediately proceed to the next iteration. \ncount = 1\nprint('The CONTINUE statement with WHILE - used to skip the rest of the code within the current iteration of the loop and immediately proceed to the next iteration.')\nwhile count <= 5:\n    count += 1\n    if count == 4: continue\n    print(count)\nelse:\n    print('Loop finished normaly.')\n#The PASS statement with WHILE - is a null operation; when it is executed, nothing happens.\ncount = 1\nprint('The PASS statement with WHILE - is a null operation; when it is executed, nothing happens.')\nwhile count <= 5:\n    count += 1\n    if count == 4:\n        pass\n    else:\n        print(count)\nelse:\n    print('Loop finished normaly.')\n#The FOR loop - is a control flow statement used for iterating over a sequence (such as a list, tuple, string, or range) or other iterable objects.\nlst_leters = ['a','b','c','d','e']\nprint('The FOR loop - is a control flow statement used for iterating over a sequence (such as a list, tuple, string, or range) or other iterable objects.')\nfor leter in lst_leters:\n    print(leter)\n#The FOR loop (using enumerate()) - simultaneously accessing both the index and the value of each item.\nlst_leters = ['a','b','c','d','e']\nprint('The FOR loop (using enumerate()) - simultaneously accessing both the index and the value of each item.')\nfor index, leter in enumerate(lst_leters):\n    print(index, ' - ', leter)\n#Handling an EXCEPTION - is a mechanism to handle the event that disrupts the normal flow of a program's execution.\nprint('Handling an EXCEPTION - is a mechanism to handle the event that disrupts the normal flow of a program\\'s execution.')\ntry:\n    result = 10 / 0\n    print(result)\nexcept ZeroDivisionError as z:\n    print(z)\nexcept TypeError as t:\n    #Handle another specific exception and get its details\n    print(t)\nexcept Exception as e:\n    #Catch any other unhandled exceptions\n    print(e)\nelse:\n    print('Operation completed successfully.')\nfinally:\n    print('Cleanup operations completed.')\n#The EXCEPTION clause with no exceptions - when no specific exception define\nprint('The EXCEPTION clause with no exceptions - when no specific exception define')\ntry:\n    result = 10 / 0\n    print(result)\nexcept:\n    print('An exception occurred')\nelse:\n    print('Operation completed successfully.')\nfinally:\n    print('Cleanup operations completed.')\n#The EXCEPTION clause with multiple exceptions - when multiple exceptions are defined\nprint('The EXCEPTION clause with multiple exceptions - when multiple exceptions are defined')\ntry:\n    result1 = 10 / 10\n    result2 = 10 + '10'\n    print(result1, ' - ', result2)\nexcept ZeroDivisionError as z:\n    print(z)\nexcept TypeError as t:\n    print(t)\nelse:\n    print('Operation completed successfully.')\nfinally:\n    print('Cleanup operations completed.')\n#Raising an EXCEPTIONS - allows you to explicitly signal that an error or an unexpected condition has occurred during program execution.\ndef process_number(number):\n    if not isinstance(number, (int, float)):\n        raise TypeError(\"Input must be a number.\")\n    if number < 0:\n        raise ValueError(\"Number cannot be negative.\")\n    return number * 2\nprint('Raising an EXCEPTIONS - allows you to explicitly signal that an error or an unexpected condition has occurred during program execution.')\ntry:\n    result = process_number('5')\n    print(result)\nexcept ValueError as e:\n    print(f\"Error: {e}\")\nexcept TypeError as e:\n    print(f\"Error: {e}\")\n#user-defined EXCEPTIONS\nclass Networkerror(RuntimeError):\n   def __init__(self, arg):\n      self.args = arg\nprint('user-defined EXCEPTIONS')\ntry:\n    raise Networkerror('Bad hostname')\nexcept Networkerror as n:\n    print(n.args)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/julianbuitragocharry-dev.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\"\"\"\n\n# Aritmetic Operators\nx = 10\ny = 5.1\naddition = x + y\nprint(addition)\nsubtraction = x - y\nprint(subtraction)\nmultiplication = x * y\nprint(multiplication)\ndivision = x / y\nprint(division)\nmodulus = x % y\nprint(modulus)\nexponential = x ** y\nprint(exponential)\nfloor_division = x // y\nprint(floor_division)\n\n# Asygment Operators\nx = 5\nprint(x)\nx += 3\nprint(x)\nx -= 3\nprint(x)\nx *= 3\nprint(x)\nx /= 3\nprint(x)\nx %= 3\nprint(x)\nx //= 3\nprint(x)\nx **= 3\nprint(x)\nx &= 3\nprint(x)\nx |= 3\nprint(x)\nx ^= 3 \nprint(x)\nx >>= 3\nprint(x)\nx <<= 3 \nprint(x)\n\n# Comparision Operators\nx = True\ny = False\nequal = x == y\nprint(equal)\nnot_equal = x != y\nprint(not_equal)\ngreater_than = x > y\nprint(greater_than)\nless_than = x < y\nprint(less_than)\ngreater_than_or_equal_to = x >= y\nprint(greater_than_or_equal_to)\nless_than_or_equal_to = x <= y\nprint(less_than_or_equal_to)\n\n# Logical Operators\n\"\"\"\nor --> returns True if one of the statements is true\nand --> returns True if both of the statements is true\nnot --> reverse the result\n\"\"\"\n\n# Identity\n\"\"\"\nis --> returns true if both variables are the same object\nis not --> return true if both variables are not the same object\n\"\"\"\n\n# Membership\n\"\"\"\nin --> returns true if a sequence with the specified value is present in object\nnot in --> returns true if a sequence with the specified value is not present in object\n\"\"\"\n\n# Condictionals\nyear = 18\nif year == 18:\n    print('You can follow')\nelse:\n    print('You can\\'t follow')\n\n# Iteratives\ni = 0\nwhile(i <= 10):\n    print(i)\n    i += 1\n\nfor i in range(0, 11):\n    print(i)\n\n# Exceptions\ntry:\n    print(not_define)\nexcept:\n    print(\"An exception occurred\")\n\ndef challenge():\n    for numb in range(10, 56, 2):\n        if numb == 16 or numb % 3 == 0:\n            pass\n        else:\n            print(numb)\n\nchallenge()"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/juliand89.py",
    "content": "#operadores aritmeticos\n\nprint(f\"Suma: 10 + 3 = {10 + 3}\")\nprint(f\"Resta: 10 - 3 = {10 - 3}\")\nprint(f\"Multiplicacion: 10 * 3 = {10 * 3}\")\nprint(f\"Division: 10 / 3 = {10 / 3:2f}\")\nprint(f\"Modulos: 10 % 3 = {10 % 3:2f}\")\nprint(f\"Exponenciacion: 10 ** 3 = {10**3}\")\nprint(f\"Division entera : 10 // 3 = {10 // 3}\")\n\n#Operadores de comparacion \nprint(f\"Igualdad: 2 == 3 = {2==3}\")\nprint(f\"Desigualdad 2 != 3 = {2!=3}\")\nprint(f\"Mayor que: 2 > 3 = {2>3}\")\nprint(f\"Menor que: 2 < 3 = {2<3}\")\nprint(f\"Moyor o igual que: 2 >= 3 = {2>=3}\")\nprint(f\"Menor o igual que: 2 <= 3 = {2<=3}\")\n\n# operadores Logicos\nprint(f\"AND: 10 + 3 == 13 and 5 - 1 == 4 es {10+3 == 13 and 5-1 == 4}\")\nprint(f\"OR: 10 + 3 == 13 or 5 - 1 == 5 es {10+3 == 13 or 5-1 == 5}\")\nprint(f\"NOT: not 10 + 3 == 13 es {not(10+3 == 13)}\")\n\n#operadores de asignacion \nnumber = 89\nprint(number)\nnumber += 1\nprint(number)\nnumber -= 2\nprint(number)\nnumber *= 2\nprint(number)\nnumber /= 2\nprint(number)\nnumber %= 2\nprint(number)\nnumber //= 1\nprint(number)\nnumber **= 1\nprint(number)\n\n#operadores de identidad\nnew_number = number\nprint(f\"IS: new_number is number es {new_number is number}\")\nprint(f\"IS NOT: new_number is not number es {new_number is not number}\")\n\n#operadores de menbresia \nprint(f\"IN: 'j' in 'julian' =  {'j' in 'julian'}\")\nprint(f\"NOT IN: 'y' not in 'julian' =  {'y' not in 'julian'}\")\n\n#Operadores de Bit\na = 10 # 1010\nb = 3 # 0011\nprint(f\"AND: 10 & 3 = {10 & 3}\") # Establece cada bit en 1 si ambos bits son 1 0010 = 2\nprint(f\"OR: 10 | 3 = {10 | 3}\") # Establece cada bit en 1 si uno de los dos bits es 1  1011 = 11\nprint(f\"XOR: 10 ^  3 = {10 ^  3}\") # Establece cada bit en 1 si solo uno de los dos bits es 1 1001 = 9\n\n#Estructuras de control \n\n# if, elif y else\nedad = 15\nif edad >= 30:\n    print(\"Puede ver la pelicula con descuento\")\nelif edad >= 18:\n    print(\"Puede ver la pelicula\")    \nelse:\n    print(\"No puede ingresar\")\n\n# For \nbuscar = 4\nfor numero in range(5):\n    print(numero)\n    if numero == buscar: \n        print (f\"Encontre el numero {buscar}\")\n        break\nelse:\n    print(f\"No encontre el numero {buscar}\")\n\n#while    \nnumero = 1\nwhile numero < 10:\n    print(numero)\n    numero +=1  \n# ejercicio\nc = 10\nwhile c < 56:\n    if (c % 2 == 0 and c != 16 and c % 3 != 0):\n        print(c)\n    c +=1"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/juserdev.py",
    "content": "'''\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n'''\n\nprint(10 + 2) \nprint(10 - 2)\nprint(10 * 2)\nprint(10 / 2)\nprint(10 % 2)\nprint(10 ** 2)\n\na, b = False, True\n\nresult = a and b\nprint(result)\nresult = a or b\nprint(result)\n\nc = not True\nprint(c)\n\na, b, c = 5, 10, 5\n\nprint(a > b)\nprint(a < b)\nprint(a <= b)\nprint(a >= b)\nprint(a == b)\nprint(a == c)\nprint(a != c)\nprint(a != b)\n\na += 4\nprint(a)\na -= 4\nprint(a)\na *= 4\nprint(a)\na /= 4\nprint(a)\na //= 4\nprint(a)\nb %= 4\nprint(b)\nb **= 4\nprint(b)\n\na = [a,b,c]\nb = a\nresult = a is b\nprint(result)\nresult = a is not b\nprint(result)\n\nlist = {1,2,3,4}\n\nresult = (3 in list)\nprint(result)\n\nresult = (5 in list)\nprint(result)\n\nresult = (3 not in list)\nprint(result)\n\nresult = (6 not in list)\nprint(result)\n\nif a  == b:\n  print(f\"a es igual a b {a}{b}\") \nelse:\n  print(f\"a no es igual a b {a}{b}\")\n\na = 10\nb = 10\n\nif a > b:\n  print(\"a es mayor que b\")\nelif a < b:\n  print(\"a es menor que b\")\nelse:\n  print(\"a y b son iguales\")\n\na = [1, 2,4,5,2]\n\nfor i in a:\n  print(i)\n\ncontador = 0\nwhile contador <= 5:\n  print(f\"Contador -> {contador}\")\n  contador += 1\n\n\ntry:\n  result = 10/0\n  print(f\"El resultado es -> {result}\")\nexcept ZeroDivisionError as e:\n  print(f\"se genero un error -> {e}\")\nfinally:\n  print(\"este bloque siempre se ejecuta\")\n\n\nnumber = 10\nwhile number < 55:\n  number += 1\n  if number % 2 == 0 and number != 16 and number % 3 != 0:\n    print(number)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/k-90.py",
    "content": "### Aritméticos\n\nsuma = 8 + 3\nprint(suma)\nresta = 9 - 5\nprint(resta)\nmultiplicacion = 7 * 3\nprint(multiplicacion)\ndivision = 4 / 2 \nprint(int(division))\npotencia = 4**2\nprint(potencia)\nmodulo = 16 % 3\nprint(modulo)\ndivision_enteros = 18 // 7\nprint(division_enteros)\n\n### Lógicos\nx = 3\ny = 5\nz = x or y # Imprime por consola uno u otro numero\nprint(z)\ns = x and y # Imprime por consola ambos numeros\nprint(s)\n\n### Comparación\nmenor_que = x < y\nprint(menor_que)\nmenor_igual = x <= y\nprint(menor_igual)\nmayor_que = x > y\nprint(mayor_que)\nmayor_igual = x >= y\nprint(mayor_igual)\nigual = x == y\nprint(igual)\ndistinto = x != y\nprint(distinto)\nigualdad = x is y\nprint(igualdad)\ndesigualdad = x is not y\nprint(desigualdad)\n\n### Asignación\n\nnumero = 4\nprint(numero)\nnumero += 1\nprint(numero)\nnumero -= 2\nprint(numero)\nnumero *= 4\nprint(numero)\nnumero /= 3\nprint(int(numero))\nnumero **= 3\nprint(int(numero))\nnumero %= 3\nprint(int(numero))\nnumero //= 1\nprint(int(numero))\n\n### Identidad\nnew_number = 8\nprint(f\"Mi numero y mi nuevo numero es {numero is new_number} \")\nprint(f\"Mi numero y mi nuevo numero es {numero is not new_number} \")\n\n### Pertenencia\nprint(f\"'e' in 'kike' {'e' in 'kike'}\")\nprint(f\"'p' in 'enrique' {'p' not in 'enrique'}\")\n\n### Operadores de bit\n\nb = 15 # 1111\nc = 7 # 111\nprint(f\"OR: 15|7 {15|7} \")\nprint(f\"XOR: 15^7 {15^7}\")\nprint(f\"AND: 15&7 {15&7}\")\nprint(f\"El valor desplazado a la izquierda {b << 5}\")\nprint(f\"El valor desplazado a la derecha {c >>3}\")\nprint(f\"invierte los bits {~c}\")\n\n        ### Estructuras de control  ###\n\n### Condicionales\n\nmy_var = \"Enrique\"\n\nif my_var == \"Enrique\":\n    print(\"Mi variable es Enrique\")\nelif my_var == \"k-90\":\n    print(\"Mi variable es k-90\")\nelse:\n    print(\"Mi variable no es Enrique ni k-90\")\n\n### iterativas (Loops)\n    \nfor i in range (7):\n    print(i)\n\ni = 0\n\nwhile i >= 6:\n    print(i)\n    i += 1\n\n### Manejo de Excepciones\n\ntry:\n    print(7/0)\nexcept:\n    print(\"No se puede dividir entre 0\")\nfinally:\n    print(\"La excepcion ha finalizado\")\n\n### Extra ###\n    \nfor number in range(10,56):\n    if number % 2 == 0 and number != 16 and number % 3 != 0:\n        print(number)\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/kenysdev.py",
    "content": "\n# ╔══════════════════════════════════════╗\n# ║ Autor: Kenys Alvarado                ║\n# ║ GitHub: https://github.com/Kenysdev  ║\n# ║ 2024 - Python                        ║\n# ╚══════════════════════════════════════╝\nprint(f\"\"\"\n1. Imprimir ejemplos utilizando todos los tipos \nde operadores de tu lenguaje:\n-----------------------------------------------\nOperadores aritmeticos:\n********************************\n- Suma:              10 + 5 = {10 + 5}\n- Resta:             10 - 5 = {10 - 5}\n- Multiplicacion:    10 * 5 = {10 * 5}\n- Division:          10 / 5 = {10 / 5}\n- Division Entera:   17// 4 = {17// 4}\n- Residuo:           20 % 7 = {20 % 7}\n- Potenciacion:      2 ** 3 = {2 ** 3}\n- Combined: (4 + 2) * 3 / 2 = {(4 + 2) * 3 / 2}\n\nOperadores de Comparación:\n**************************\n- igual a       5 == 5 -> {5 == 5}\n- Diferente de  5 != 5 -> {5 != 5}\n- Menor que     4 < 5  -> {4 <  5}\n- Mayor que     4 > 5  -> {4 >  5}\n- Menor o igual 4 <= 5 -> {4 <= 5}\n- Mayor o igual 4 >= 5 -> {4 >= 5}\n\nOperadores de Asignación:\n*************************\"\"\")\nn = 10; print(f\"- asigna:          n = 10  = {n}\")\nn += 2; print(f\"- suma:            n += 2  = {n}\")\nn -= 2; print(f\"- resta:           n -= 2  = {n}\")\nn *= 2; print(f\"- multiplica:      n *= 2  = {n}\")\nn /= 2; print(f\"- división:        n /= 2  = {n}\")\nn **=2; print(f\"- exponenciación:  n **= 2 = {n}\")\nn //=2; print(f\"- división entera: n //= 2 = {n}\")\nn %= 2; print(f\"- modulo:          n %= 2  = {n}\")\n\nprint(f\"\"\"\nOperadores Lógicos:\n*******************\nand: 5 == 5 and 6 != 5 -> {5 == 5 and 6 != 5}\nor:  5 == 5 or 6 != 5  -> {5 == 5 or 6 != 5 }\nnot: not 5 == 6        -> {not 5 == 6}\n\nOperadores de Identidad:\n************************\nis:     (6 > 5) is True     -> {(6 > 5) is True}\nis not: (6 > 5) is not True -> {(6 > 5) is not True}\n\nOperadores de Pertenencia:\n**************************\nin:     \"c\" in \"abcde\"     -> {\"c\" in \"abcde\"}\nnot in: \"f\" not in \"abcde\" -> {\"f\" not in \"abcde\"}\"\"\")\na = 0b1100\nb = 0b1010\nprint(f\"\"\"\n#Operadores Bit a Bit:\n**********************\nand:       bin(a & b)  -> {bin(a & b)}\nor:        bin(a | b   -> {bin(a | b)}    \nxor:       bin(a ^ b)  -> {bin(a ^ b)}\nnot_a:     bin(~a)     -> {bin(~a)}\nizquierda: bin(a << 2) -> {bin(a << 2)}\nderecha:   bin(a >> 1) -> {bin(a >> 1)}\n\n2. Estructuras de control:\n--------------------------\n# condicinal:\n*************\"\"\")\nif 5 == 5:\n    print(\"Si 5 == 5\")\n# si de lo contrario\nelif suma == 2:\n    print(\"Si 2 == 2\")\nelse:\n    print(\"Ninguna\")\n\nprint(\"\"\"\nOperador ternario:\"\"\")\nmy_bool = True if 15 == 15 else False\nprint(\"si es igual\" if my_bool else \"no es igual\")\n\nprint(\"\"\"\nmatch:\"\"\")\ndef operacion(operador):\n    match operador:\n        case 'suma': return \"Realizando suma\"\n        case 'resta': return \"Realizando resta\"\n        case 'multiplica':return \"Realizando multiplicación\"\n        case 'divide': return \"Realizando división\"\n        case _: return None\nprint(operacion('resta'))\n\nprint(\"\"\"\nBucle for\nzip: combina dos o más iterables creando una secuencia de tuplas.\nenumerate: agrega un contador a un iterable.\nrange: iterar sobre una secuencia de números.\"\"\")\ncadena = \"abcd\"\nfor i in range(2):\n    print(cadena)\n# de y hasta.\nfor i in range(3, 5):\n    print(i)\n\nprint(\"con objeto_iterable\")\nfor elemento in cadena:\n    print(elemento)\n\nprint(\"Bucle while\")\nn = 3\nwhile True:\n    print(n) # 3, 2, 1\n    n -= 1\n    if n == 0:\n        print(\"Llego a 0.\")\n        break # salir del bucle\n\nprint(\"while con condicional\")\nn = 3\nwhile n > 0:\n    print(n) # 3, 2, 1\n    n -= 1\nelse:\n    print(\"Llego a 0.\")\n\nprint(\"Bucles anidados\")\nelementos = [\"a\", \"b\", \"c\"]\nn = 1\nwhile n < 4:\n    print(n)\n    n += 1\n    for e in elementos:\n        print(e)\n\nprint(\"*continue* en for o while\")\nfor i in range(1, 4):\n    if i == 2:\n        continue\n    print(i) \n    # 1, 3\nprint(\"\"\"\nControl de Excepciones:\n***********************\"\"\")\ntry:\n    print(5 / 0)\nexcept Exception as e:\n    print(f\"{type(e).__name__}: {str(e)}\")\nfinally:\n    # Se produce o no se produce error.\n    print(\"finalizado\")\n\nprint(\"\"\"\n# Context Managers:\n# Se utiliza para asegurar que ciertos recursos \n# se adquieran y liberen correctamente.\nwith open('ejemplo.txt', 'w') as archivo:\n     archivo.write('hola')\n\n3. Ejercicio:\n-------------\nCrea un programa que imprima por consola todos los números comprendidos\n* entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\"\"\")\nfor numero in range(10, 56):\n    if numero % 2 == 0 and numero != 16 and numero % 3 != 0:\n        print(numero)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/knowledgesoftdev.py",
    "content": "import random\n\n#operadores aritmeticos\n\n#suma\na=12\nb=12\nsuma=a+b\nprint(\"La suma es:\",suma)\n\n#resta\nc=14\nd=9\nresta=c-d\nprint(\"La resta es:\",resta)\n\n#Multiplicacion\ne=20\nf=3\nmultiplicacion=e*f\nprint(\"La multiplicacion es: \",multiplicacion)\n\n#Divison\ng=12\nh=0\nif (h==0):\n     print(\"Ojo el divisor no puede ser 0\")  \nelse:\n    division=g/h\n    print(\"La division es:\",division)\n\n#modulo (residuo)\ni=12\nj=9\nif (j==0):\n     print(\"Ojo el divisor no puede ser 0\")  \nelse:\n    modulo=i%j\n    print(\"El modulo es:\",modulo)\n\n\n#operadores logicos y condicionales\n\n#operadores logicos\n#saber si el numero elegido es igual al numero ingresado, y verificar si es positivo el numero\nnum=8\nnumElegido=4\nif num==numElegido and num>0:\n     print(\"El numero es igual al numero elegido, el numero es positivo:\",num) \nelse:\n     print(\"El numero no es igual al numero elegido, el numero es negativo:\",num)\n\n#aqui tenemos el if else en logicos\n#Saber si eres nayor de edad sabiendo que los 18 años ya eres mayor de edad\nedad=12\nif(edad>=18):\n     print(\"Eres mayor de edad\")\nelse:\n     print(\"Eres menor de edad\")\n\n\n\n#Comparacion\n'''\naqui tenemos los signos de comparacion:\n<   mayor\n>   menor\n>=  mayor igual\n<=  menor igual\n==  igua igual\n!=  diferente\n'''\nif(12>8): print(\"El numero\",12,\"es mayor\")\nif(8<12): print(\"El numero\",8,\"es menor\")\nif(12>=8): print(\"El numero\",12,\"es mayor o igual\")\nif(8<=12): print(\"El numero\",8,\"es menor o igual\")\nif(12==12): print(\"son iguales\")\nif(12!=8): print(\"son diferentes\")\n\n#asignacion\n#Es simple y sencilo lo que se le asigna a una variable ejemplo\nvariable=12\nprint(\"mi varible tiene asignada\",variable,\"y su tipo de datos es\",type(variable))\n\n#identidad\n#Simple y sencillo cuando es igual, pero a la vez tambien es igual el tipo de datos ejemplo\nvariableUno=120\nvariableDos=120\nindentidad= variableUno is variableDos\nprint(\"Es identico?\",indentidad)\n\n#pertenencia\n#Aqui vamos a ver si cierta consonante o vocal esta dentr del nombre ingresado\nnombre=\"Brayan Trujillo\" \n\npertence= (\"s\" in nombre)\nprint(\"Pertence?\",pertence) \n\n#iteratividad\nfor i in range(1,11):\n     print(i)\n\n#excepciones\ntry:\n     dividir=12/0\nexcept:\n     print(\"Error, no se puede dividri en tre cero\")\n\nprint(\"Ejercicio\")\n'''\nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n'''\nfor i in range(10,56):\n    if(i%2==0):\n         if(i!=16 and i%3!=0):\n              print(i)\n          \n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/kodenook.py",
    "content": "\nnum1:int = 3\nnum2:int = 2\n\n\"\"\" Arithmetic Operators\"\"\"\n\n# addition\nprint(f'sum: {num1 + num2}')\n# subtraction\nprint(f'subtraction: {num1 - num2}')\n# multiplication\nprint(f'multiplication: {num1 * num2}')\n# division\nprint(f'division: {num1 / num2}')\n# modulus\nprint(f'modulus: {num1 % num2}')\n# exponentiation\nprint(f'exponentiation: {num1 ** num2}')\n# floor division (rounds the result down to the nearest whole number)\nprint(f'floor division: {num1 // num2}')\n\n\"\"\" Assignment Operators\"\"\"\n\nnum3 = 2 # assignment\nprint(num3)\nnum3 += 1\nprint(num3)\nnum3 -= 2\nprint(num3)\nnum3 *= 2\nprint(num3)\nnum3 /= 2\nprint(num3)\nnum3 %= 3\nprint(num3)\nnum3 **= 2\nprint(num3)\nnum3 //= 1\nnum3 = 4\nprint(num3)\nnum3 &= 1\nprint(num3)\nnum3 |= 1\nprint(num3)\nnum3 ^= 1\nprint(num3)\nnum3 <<= 1\nprint(num3)\nnum3 >>= 1\nprint(num3)\n\n\"\"\" Comparison Operators \"\"\"\n\nprint(3 == 2) # equal\nprint(4 != 2) # not equal\nprint(4 > 2) # greater than\nprint(4 < 2) # less than\nprint(4 >= 2) # greater than or equal than\nprint(4 <= 2) # less than or equal than\n\n\"\"\" Logical Operators \"\"\"\n\nprint(1 and 2) # true if both are true\nprint(1 or 3) # true if either are true\nprint(not(1)) # return false if result is true\n\n\"\"\" Identity Operators \"\"\"\n\nprint(1 is 1) # return true if are the same\nprint(1 is not 1) #return true if are not the same\n\n\"\"\" Membership Operators \"\"\"\n\nprint('h' in 'hi') # true if value is present in the object\nprint('h' not in 'hi') # true if value is not present in the object\n\n\"\"\" Bitwise Operators \"\"\"\n\nprint(6 & 3) # compare each bit and set it to 1 if both are 1, otherwise it is set to 0\nprint(6 | 3) # compare each bit and set it to 1 if one or both are 1, otherwise it is set to 0\nprint(6 ^ 3) # compare each bit and set it to 1 if only one is 1, otherwise it is set to 0\nprint(~3) # inverts each bit, 0 becomes 1 and 1 becomes 0\nprint(3 << 2) # insert the specified numbers of 0's (in this case 2) from the right\nprint(8 >> 2) # insert the specified numbers of 0's (in this case 2) from the left\n\n\"\"\" If \"\"\"\n\nif 3 > 1:\n    print(3)\nelif 3 < 4:\n    print(4)\nelse:\n    print('other result')\n\n\"\"\" Short hand if \"\"\"\n\nif 3 == 3: print('equals')\nprint('A') if 'A' > 'B' else print('B')\nprint('A') if 'a' > 'b' else print('=') if 'a' == 'A' else print('B')\n\n\"\"\" Loop while \"\"\"\n\ni = 1\nwhile i < 2:\n    print(i)\n    i += 1\nelse:\n    print(\"i is no longer less than 6\")\n\n\"\"\" Loop for \"\"\"\n\nfor x in range(6):\n    print(x)\nelse:\n    print(\"Finally finished!\")\n\n\"\"\" Exceptions \"\"\"\n\ntry:\n    if 2 == 2:\n        raise Exception(\"Sorry, no numbers below zero\")\nexcept:\n    print(\"Something went wrong\")\nelse:\n    print(\"Nothing went wrong\")\nfinally:\n  print(\"The 'try except' is finished\")\n\n\n\"\"\" Exercise \"\"\"\nfor x in range(10, 56):\n    if x % 2 == 0 and x != 16 and x % 3 != 0:\n        print(x)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/kuroz00.py",
    "content": "#Que hacia una caja en el gym? entrenaba para ser caja fuerte :D hahahahahahahahahaha\nx =x2 =x3 =x4 =0\n\n#ARITMETICOS ¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬\nprint('\\naritmeticos: ')\nx = 2 + 1\nprint('x = 1 + 2 =', x)\nx = 2 - 1\nprint('x = 1 - 2 =', x)\nx = 2 * 1\nprint('x = 1 * 2 =', x)\nx = 2 / 1\nprint('x = 1 / 2 =', x)\nx = 2 % 1 \nprint('x = 1 % 2 =', x)\n\n\n#LOGICOS ¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬\nprint('\\nLogicos: ')\nx  = 0\nx3 = 10\nwhile (x != 5 and x3 != 5):\n    x  += 1\n    x3 -= 1\n    print('\\nx: ', x)\n    print('x3:', x3) \nwhile x < 10 or x3 < 10:\n    x  += 1\n    x3 += 1\n    print('\\nx:', x)\n    print('x3', x3)     \n\nverdad = False\nif not verdad:\n    print('No es verdad, es una mentira! somos todos una ilusion...') \n\n\n\n#COMPARACION y ASIGNACION ¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬\nprint('\\nComparacion y asignacion: ')\n\nx2 = 10\nprint('x2 =', x2)\nif x + 2 == 2:\n    x2 += x\n    print('x2 + x =', x2)\nelif x - 2 != 2:\n    x2 -= x\n    print('x2 - x =', x2)\nelif x > 2:\n    x2 /= x\n    print('x2 / x =', x2)\nelif x < 2:\n    x2 *= x\n    print('x2 * x =', x2)    \nelif x >= 2:\n    x2 %= x\n    print('x2','%','x =', x2)\nelif x <= 2:\n    x2 **= x\n    print('x2 ** x =', x2)  \nelse:\n    print('hola mundo!')                  \n\n\n#IDENTIDAD ¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬\nx = [1,2,3,4,5]\ny = x\nif x is y:\n    print('\\nx = ',x)\n\n\n\n#PERTENENCIA ¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬\nif 2 in x:\n    print('\\nx contiene el valor \"2\" ')\nif 0 not in x:\n    print('x no contiene el valor \"0\" ')\n        \n#BITS ¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬\na = 5 #101\nb = 2 #010    \n    #OR\nc = a | b \nprint('\\na | b =', c)\n    #AND\nc = a & b \nprint('a & b =', c)\n    #XOR\nc = a ^ b \nprint('a ^ b =', c)\n\n    #NOT\nc = ~c \nprint('~c =', c)\n    #>>\nc = a >> b \nprint('a >> b =', c)\n    #<<\nc = a << b \nprint('a << b =', c)\n\n\n#Dificultad extra ¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬\n\nfor i in range(10, 56):\n    if i % 2 == 0 and i % 3 != 0 and i != 16: \n      print(i) "
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/lPassword012.py",
    "content": "#Operadores \n\n# Declaracion y asignacion de variables:\na, b = 10, 3\nc = 5\nx, y = True, False\nlista = [1, 2, 3, 4, 5]\nw, z = 5, 3\n\n# Aritméticos\nprint(\"Concepto operaciones\\n\")\nprint(\"Es posible trabajar con diversas operaciones en Python.\\nSe agrupan en las siguientes categorias:\\n\")\nprint(\"-Aritmeticos\\n-Comparacion\\n-Asignacion\\n-Logicos\\n-Identidad\\n-Pertenencia\\n-Bits\\n\")\n\nprint(\"Operadores Aritmeticos:\")\nprint(f\"Suma: {a} + {b} = \", a + b)\nprint(f\"Resta: {a} - {b} = \", a - b)\nprint(f\"Multiplicacion: {a} * {b} = \", a * b)\nprint(f\"Division con parte decimal: {a} / {b} = \", a / b)\nprint(f\"Division con parte entera: {a} / {b} = \", a // b)\nprint(f\"Módulo: {a} % {b} = \", a % b)\nprint(f\"Potencia: {a} ** {b} = \", a ** b)\n\n# Comparación\nprint(\"\\nOperadores de comparacion:\")\nprint(\"Igualdad:\", a == b)\nprint(\"Desigualdad:\", a != b)\nprint(\"Mayor:\", a > b)\nprint(\"Menor o igual:\", a <= b)\n\n# Asignación\nc += 2  # Equivalente a c = c + 2\nprint(\"\\nAsignacion:\", c)\n\n# Lógicos\nprint(\"\\nOperadores logicos:\")\nprint(\"AND logico:\", x and y)\nprint(\"OR logico:\", x or y)\nprint(\"NOT logico:\", not x)\n\n# Identidad\nprint(\"\\nOperadores de identidad:\")\nprint(\"Es el mismo objeto:\", a is b)\nprint(\"No es el mismo objeto:\", a is not b)\n\n# Pertenencia\nprint(\"\\nOperadores de pertenencia:\")\nprint(f\"Lista de numeros naturales: {lista}\")\nprint(f\"El {lista[2]} existe en la lista:\", 3 in lista)\nprint(f\"El {lista[4]} no existe en la lista:\", 5 not in lista)\n\n# Operadores de bits\nprint(\"\\nOperadores de bits:\")\nprint(\"AND bit:\", w & z)\nprint(\"OR bit:\", w | z)\nprint(\"XOR bit:\", w ^ z)\nprint(\"\\nDesplazamiento izquierda:\", w << 1)\nprint(\"Desplazamiento derecha:\", w >> 1)\n\n# Estructuras de control\nprint(\"\\nEstructuras de control:\\n\")\n\n# Condicionales\nprint(\"Bifurcacion:\")\nedad = 28\nprint(f\"La edad del usuario es {edad}\")\nif edad >= 18:\n    print(\"Eres mayor de edad\\n\")\nelse:\n    print(\"Eres menor de edad\\n\")\n\n# Bucle iterativo - for\nprint(\"Bucles:\")\nprint(\"Iterar en un rango 0...5 iterable:\")\nfor i in range(5):\n    print(f\"Iteración {i}\")\n\n# Bucle iterativo - while\ncontador = 0\nprint(\"\\nIterar sobre una condicion:\")\nwhile contador < 3:\n    print(f\"Contador en {contador}\")\n    contador += 1\n\n# Manejo de excepciones\nprint(\"\\nManejo de excepciones:\")\ntry:\n    resultado = 10 / 0\nexcept ZeroDivisionError:\n    print(\"No se puede dividir por cero\")\nfinally:\n    print(\"Fin del manejo de excepciones\")\n\n# Ejercicio extra:\nprint(\"\\n========================\")\nprint(\"Ejercicio extra:\")\nprint(\"\\nCrea un script que imprima por consola todos los numeros comprendidos\")\nprint(\"Entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni multiplos de 3.\")\n\nnumeros_comprendidos=[]\n\nfor numero in range(10, 56):\n    if numero % 2 == 0 and numero != 16 and numero % 3 != 0:\n        numeros_comprendidos.append(numero)\n\nprint(f\"\\nLista de numeros comprendidos: {numeros_comprendidos}\")\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/latteMiguelangel.py",
    "content": "\"\"\"\nEJERCICIO:\n- Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n  Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n  (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n- Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n  que representen todos los tipos de estructuras de control que existan\n  en tu lenguaje:\n  Condicionales, iterativas, excepciones...\n- Debes hacer print por consola del resultado de todos los ejemplos.\nDIFICULTAD EXTRA (opcional):\nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\nSeguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\"\"\"\n\n# ---------- ARITHMETIC OPERATORS -----------\n\nfrom re import match\n\n\nA = 50\nB = 77\nC = 21\nD = 3\n\naddition = (A + C) + (A + B)\nsustraction = (C - D) - (B - A)\nmultiplication = A * B\nfloat_division = B / D\nint_division = A // D\nexponential = A**D #It's like 50^3\nrest = A % D\n# ---------- LOGIC & COMPARISON OPERATORS -----------\n\n\n# equals ------------->       ==\nmy_boolean_1 = A == B\n# different ---------->       !=\nmy_boolean_2 = A != B           \n# minor -------------->       <\nmy_boolean_3 = A < B\n# superior ----------->       >\nmy_boolean_4 = A > B\n# minor or equals ---->       <=\nmy_boolean_5 = A <= B\n# superior or equals ->       >=\nmy_boolean_6 = A >= B\n\n\n# AND\nand_test = A > D and C < B\nprint(and_test) #True\n\n# OR\nor_test = A > B or B == D\nprint(or_test) #False\n\n# NOT\nnot_test = not(A <= D) #A is superior than D (False), but this proposition are negated (True)\nprint(not_test)\n\n\n# ---------------------- CONTROL STRUCTURES ----------------------\n\n# selectives structures (IF-ELSE, MATCH(SWITCH))\nif B >= A:\n    print(f\"{B} >= {A}\")\n\nif A > B or A < C:\n    print(A)\nelif B + C == A:\n    print(B + C)\nelse:\n    D = D * 4\n    print(D)\n# ------------------------------------------------\nday = 7\nmatch day:\n    case 1:\n        print(\"monday\")\n    case 2:\n        print(\"tuesday\")\n    case 3:\n        print(\"wednesday\")\n    case 4:\n        print(\"thursday\")\n    case 5:\n        print(\"friday\")\n    case 6:\n        print(\"saturday\")\n    case 7:\n        print(\"sunday\")\n    case _:\n        print(\"this is a default form\")\n\n# loop structures\n\nwhile D < B:\n    D = D + 1\n    print(D)\n\n# --------------\nprint(\"-\"*30)\n\nfor i in range(0,100,2):\n    print(i)\n\n\n# ---------------------- CHALLENGE ----------------------\nprint(\"\\n\\n\\n\\n\")\nprint(\"CHALLENGE\")\nfor i in range (10,56):\n    if(i % 2 == 0 and i != 16):\n        if(i % 3 != 0):\n            print(f\"{i}, \", end=\"\")\n    if(i >= 55):\n        print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/lauradiazm29.py",
    "content": "#EJEMPLOS DE OPERADORES\n\n#Aritméticos\nnum1 = 2\nnum2 = 3\nnum3 = 6\nnum4 = 15\nprint(f\"{num1} + {num2} = {num1+num2}\") #suma\nprint(f\"{num3} - {num2} = {num3-num2}\") #resta\nprint(f\"{num3} / {num2} = {num3/num2}\") #división\nprint(f\"{num1} * {num2} = {num1*num2}\") #multiplicación\nprint(f\"{num1} ^ {num2} = {num1**num2}\") #potencia\nprint(f\" {num4} mod {num3} = {num4%num3}\") #módulo\nprint(f\"El cociente de {num4}/{num3} es {num4//num3}\") #cociente entero\n\n#Lógicos\na = True\nb = False\n    #El operador and solo devuelve true si los dos valores son true\nprint(f\"{a} and {b} es {a and b}\")\nprint(f\"{a} and {a} es {a and a}\")\nprint(f\"{b} and {b} es {b and b}\")\n    #El operador or devuelve true si al menos uno de los dos valores es true\nprint(f\"{a} or {b} es {a or b}\")\nprint(f\"{a} or {a} es {a or a}\")\nprint(f\"{b} or {b} es {b or b}\")\n    #El operador not devuelve true si el valor es false y false si el valor es true\nprint(f\"not {a} es {not a}\")\nprint(f\"not {b} es {not b}\")\n\n#Comparativos\nx = 2\ny = 3\nz = 2\n    #El operador == devuelve true si ambos valores son iguales\nprint(f\"{x} == {y} es {x==y}\")\nprint(f\"{x} == {z} es {x==z}\")\n    #El operador != devuelve true si ambos valores no son iguales\nprint(f\"{x} != {y} es {x!=y}\")\nprint(f\"{x} != {z} es {x!=z}\")\n    #El operador < devuelve true si el primer valor es menor que el segundo\nprint(f\"{x} < {y} es {x<y}\")\nprint(f\"{y} < {x} es {y<x}\")\n    #El operador > devuelve true si el primer valor es mayor que el segundo\nprint(f\"{x} > {y} es {x>y}\")\nprint(f\"{y} > {x} es {y>x}\")\n    #El operador <= devuelve true si el primero es menor o igual que el segundo\nprint(f\"{x} <= {y} es {x<=y}\")\nprint(f\"{y} <= {x} es {y<=x}\")\nprint(f\"{z} <= {x} es {z<=x}\")\n    #El operador >= devuelve true si el primero es mayor o igual que el segundo\nprint(f\"{x} >= {y} es {x>=y}\")\nprint(f\"{y} >= {x} es {y>=x}\")\nprint(f\"{z} >= {x} es {z>=x}\")\n#Asignación\n    #El operador = asigna un valor a una variable\nvar1=36\nprint(f\"La variable var1 tiene el valor de {var1}\")\n    #Los operadores +=, -=, *=, /=, %=, //=, **/ son equivalentes a:\nx = 2\ny = 12\nprint(f\"El valor inicial de x es {x}\")\nx += 1\nprint(f\"x += 1 es igual a x = x + 1 = {x}\")\nx -= 2\nprint(f\"x -= 1 es igual a x = x - 2 = {x}\")\nx *= 9\nprint(f\"x*= 9 es igual a x = x * 9 = {x}\")\nx /= 3\nprint(f\"x /= 3 es igual a x = x / 3 = {x}\")\nx %= 2\nprint(f\"x %= 2 es igual a x = x % 2 = {x}\")\nprint(f\"El valor inicial de y es {y}\")\ny //= 5\nprint(f\"y //= 5 es igual a y = y // 5 = {y}\")\ny **= 3\nprint(f\"y **= 3 es igual a y = y ** 3 = {y}\")\n\n#Identidad\n    #El operador is devuelve true si dos variables hacen referencia al mismo objeto\n    #no se debe confundir con el operador ==\na = 10\nb = 10\nprint(f\" a is b es {a is b}\")\na = [1,2,3]\nb = [1,2,3]\nprint(f\" a is b es {a is b}\")\n    #El operador is not hace lo contrario que is\na = 10\nb = 10\nprint(f\" a is not b es {a is not b}\")\na = [1,2,3]\nb = [1,2,3]\nprint(f\" a is not b es {a is not b}\")\n\n#Pertenencia\n    #El operador in nos devuelve true si el elemento se encuentra dentro de una secuencia iterable\nnum = 3\nlista1 = [1,2,3]\nlista2 = [1,2,4]\nprint(f\"3 in lista 1 es {num in lista1}\")\nprint(f\"3 in lista 2 es {num in lista2}\")\n    #El operador is not hace lo contrario\nprint(f\"3 not in lista 1 es {num not in lista1}\")\nprint(f\"3 not in lista 2 es {num not in lista2}\")\n#EJEMPLOS DE ESTRUCTURAS DE CONTROL\n\n#Condicionales\n    #if/else es utilizado para controlar diferentes situaciones, si la condición que precede al if\n    #es verdadera el codigo siguiente se ejecuta, sino se ejecutará el codigo de dentro del else\na = 5\nb = 6\nif a > b:\n    print(f\"{a} es mayor que {b}\")\nelse:\n    print(f\"{a} es menor que {b}\")\n    #también se puede hacer uso de los elif para contar con más de dos escenarios\nif a > b:\n    print(f\"{a} es mayor que {b}\")\nelif a < b:\n    print(f\"{a} es menor que {b}\")\nelse:\n    print(f\"{a} es igual que {b}\")\n\n#Iterativas\n    #bucle for: el codigo se ejecutará el numero de veces definido en el for\nfor i in range(1,11): #contar hasta diez\n    print(i)\n    #bucle while: el codigo se ejecutará mientras la condición se cumpla\na = 0\nwhile a < 5:\n    a += 1\n    print(a)\n\n#Excepciones\n    #try/except: utililzado para controlar posibles errores en el codigo sinque el programa se detenga\ntry:\n    c = 3/0\nexcept Exception:\n    print(\"Error\")\n\n'''Crea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.'''\n\nfor i in range(10,57,2):\n    if (i != 16) and ((i%3) != 0):\n        print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/linerlander.py",
    "content": "\"\"\"\nOperadores\n\"\"\"\n#Operadores arimético\nprint(f'Suma: 10 + 3 = {10 + 3}') # Suma\nprint(f'Resta: 10 - 3 = {10 - 3}') #Resta\nprint(f'Multiplicación: 10 * 3 = {10 * 3}') # Multiplicación\nprint(f'División: 10 / 3 = {10 / 3}') # División\nprint(f'Modulo: 10 % 3 = {10 % 3}') # Modulo\nprint(f'Exponente: 10 ** 3 = {10 ** 3}') # Exponente\nprint(f'División: 10 // 3 = {10 // 3}') # División Entera\n\n#Operadores de comparación\nprint(f'Igualdad: 10 == 3: {10 == 3}') # Igualdad\nprint(f'Desigualdad: 10 == 3: {10 != 3}') # Desigualdad\nprint(f'Mayor que: 10 > 3: {10 > 3}') # Mayor\nprint(f'Menor que: 10 < 3: {10 == 3}') # Menor\nprint(f'Mayor o igual que: 10 > 3: {10 >= 3}') # Mayor igual que\nprint(f'Menor o igual que: 10 < 3: {10 <= 3}') # Menor igual que\n\n#Operadores lógicos\nprint(f'AND &&: 10 + 3 == 13 and 5 -1 == 4 es {10 + 3 == 13 and 5 -1 == 4}') # Operador and\nprint(f'OR ||: 10 + 3 == 13 or 5 -1 == 4 es {10 + 3 == 14 or 5 -1 == 4}') # Operador or\nprint(f'NOT !: 10 + 3 == 14 {not 10 + 3 == 14}') # Operador not\n\n#Operadores de Asignación\nmy_number = 11 # Operador de asignación\nprint(my_number)\nmy_number += 1 # Suma y asignación\nprint(my_number)\nmy_number -= 1 # Resta y asignación\nprint(my_number)\nmy_number *= 2 # Multiplicación y asignación\nprint(my_number)\nmy_number /= 2 # División y asignación\nprint(my_number)\nmy_number %= 2 # Modulo y asignación\nprint(my_number)\nmy_number %= 2 # Modulo y asignación\nprint(my_number)\nmy_number **= 1 # Exponente y asignación\nprint(my_number)\nmy_number //= 1 # División entera y asignación\nprint(my_number)\n\n#Operadores de indentidad\n\nmy_new_number = my_number\nprint(f'my_number is my_new_number es {my_number is my_new_number}') # Compara dirección de memoria\nprint(f'my_number is my_new_number es {my_number is not my_new_number}') # Negar la comparación de dirección de memoria\n\n#Operadores de pertenencia\nprint(f'\"u\" in \"more\" = {\"u\" in \"liner\"}') # Comparar un dato este dentro de otro\nprint(f'\"u\" in \"more\" = {\"b\" not in \"liner\"}') # Negar Comparar un dato este dentro de otro\n\n#Operadores de bit\na = 10 # 1010\nb = 3 # 0011\n\nprint(f'AND: 10 & 3 {10 & 3}') # 0010\nprint(f'OR: 10 | 3 {10 | 3}') # 1011\nprint(f'XOR: 10 ^ 3 {10 ^ 3}') # 1001\nprint(f'NOT: ~10  {~10}')\nprint(f'Desplazamiento ala derecha: 10 >> 2 {10 >> 2}') # 1010 --> 0101 --> 0010\nprint(f'Desplazamiento ala izquierda: 10 << 2 {10 << 2}') # 101000 <-- 1010\n\n'''\nEstructruras de control\n'''\n\n#Condicionales\nmy_string = 'LinerDev'\n\nif my_string == \"LinerDev\":\n    print(\"My_string es 'LinerDev'\")\nelif my_string == \"LanderDev\":\n    print(\"my_string no es 'LanderDev'\")\nelse:\n    print(\"my_string no es 'LinerDev'\")\n\n#Iterativas\nfor i in range(11):\n    print(i)\ni = 0\nwhile i <= 10:\n    print(i) \n    i += 1\n\n#Manejo de excepciones\ntry:\n    print(10/0)\nexcept:\n    print('Se ha producido un error')\n\nfinally:\n    print('Ha finalizado el manejo de excepciones')\n\n### Dificultada Extra ###\n\nx = 10\nwhile x <= 55:\n    if x % 2 == 0 and x != 16 and x % 3 != 0:\n        print(x)\n        x += 1\n    else:\n        x += 1\n\nfor number in range(10,56):\n    if number % 2 == 0 and number != 16 and number % 3 != 0:\n        print(number)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/luisssSoto.py",
    "content": "'''aritmetic operators'''\nvar1 = 10\nvar2 = 20\nprint(var1 + var2)\nprint(var1 - var2)\nprint(var1 * var2)\nprint(var1 / var2)\nprint(var1 // var2) #floor division\nprint(var1 % var2)\nprint(var1 ** var2,)\nprint()\n\n'''relational operators'''\n'''1. strict operators'''\nprint(var1 < var2)\nprint(var1 > var2)\nprint()\n\n'''2. no strict operators'''\nprint(var1 <= var2)\nprint(var1 >= var2)\nprint()\n\n'''3. equal operators'''\nprint(var1 == var2)\nprint(var1 != var2)\nprint()\n\n'''bits operators'''\nprint(var1 | var2)\nprint(var1 & var2)\nprint(~var1)\nprint(var1 ^ var2)\nprint(var1 << var2)\nprint(var1 >> var2)\nprint()\n\n'''logic operators'''\nprint(var1 and 10 == var2)\nprint(var1 or var2 > 10)\nprint(not True)\n\n'''Conditional Selective structures'''\n'''1. if'''\nif (var1 < var2):\n    print(var1, 'is less than', var2)\n\n'''2. if else'''\nif (var1 > var2):\n    print(var1, 'is greater than', var2)\nelse:\n    print(var1, 'is less than', var2)\n\n'''3. if elif else'''\nif (var1 > var2):\n    print(var1, 'is greater than', var2)\nelif (var1 == var2):\n    print(var1, 'is exactly equal to', var2)\nelse:\n    print(var1, 'is less than', var2)\n\n'''Repetitive Structure'''\n'''1. for'''\nfor i in range(10):\n    print(i, end=' ')\n    if i == 9:\n        print()\n\n'''2. while'''\ncount = 5\nwhile count > 0:\n    print(count)\n    count -= 1\n\n'''Exceptions'''\ntry:\n    print('try to do this:')\n    print(10/0)\nexcept ZeroDivisionError:\n    print('Division between 0 is impossible')\nprint()\n\n'''Last Excercise'''\nfor number in range(10, 56):\n    if number % 2 == 0:\n        if number == 16: continue\n        elif number % 3 == 0: continue\n        else: print(number, end=' ')\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/luistecnocode.py",
    "content": "'''\n/*\n * EJERCICIO 01 - OPERADORES Y ESTRUCTURAS DE CONTROL:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n'''\n\n# Operadores aritméticos\nprint(f\"Suma: 10 + 5 = {10 + 5}\")\nsum = 15 + 5\nprint(f\"Suma con variable: 15 + 5 = {sum}\")\nprint(f\"Multiplicacion: 10 * 5 = {10 * 5}\")\nprint(f\"Divison: 10 / 5 = {10 / 5}\") # La division deja resultado float\nprint(f\"Módulo: 10 % 3 = {10 % 3}\")\nprint(f\"Exponente: 10 ** 5 = {10 ** 5}\")\nprint(f\"Division entera: 10 // 5 = {10 // 5}\")\n\n# Operadores de comparación\nprint(f\"Igualdad: 10 == 3 es {10 == 3}\")\nprint(f\"Desigualdad: 10 != 3 es {10 != 3}\")\nprint(f\"Mayor que: 10 > 3 es {10 > 3}\")\nprint(f\"Menor que: 10 < 3 es {10 < 3}\")\nprint(f\"Mayor o igual que: 10 >= 10 es {10 >= 10}\")\nprint(f\"Menor o igual que: 10 <= 3 es {10 <= 3}\")\n\n# Operadores lógicos\nprint(f\"AND &&: 10+3 and 5-1 == 4 es {10+3 and 5-1 == 4}\") # Es verdadero\nprint(f\"OR ||: 10+3==14 or 5-1 == 4 es {10+3 == 14 or 5-1 == 4}\") #Es verdadero\nprint(f\"NOT !: 10 + 3  == 14 es {not 10+3 == 14}\") # True porque no es igual a 14\n\n# Operadores de asignación\nmy_number = 11 # asigna\nprint(my_number)\nmy_number += 1 # suma y asigna\nprint(my_number)\nmy_number -= 1 # resta y asigna\nprint(my_number)\nmy_number *= 2 # multiplica y asigna\nprint(my_number)\nmy_number /= 2 # divide y asigna\nprint(my_number)\nmy_number %= 2 # modulo y asigna\nprint(my_number)\nmy_number **= 2 # exponente y asigna\nprint(my_number)\nmy_number //= 2 # divide entero y asigna\nprint(my_number)\nmy_number = 1\n\n# Operadores de identidad\nmy_new_number = 1.0\nprint(f\"my_number is my_new_number es {my_number is my_new_number}\")\nmy_new_number = my_number\nprint(f\"my_number is my_new_number es {my_number is my_new_number}\")\nprint(f\"my_number is not my_new_number es {my_number is not my_new_number}\")\n\n# Operador de pertenencia\nprint(f\"'u' in 'moure' = {'u' in 'moure'}\")\nprint(f\"'z' in 'moure' = {'z' in 'moure'}\")\nprint(f\"'b' not in 'moure' = {'b' not in 'moure'}\")\n\n# Operadores de bit\na = 10 # 1010\nb = 3 # 0011\nprint(f\"AND: 10 & 3 = {10 & 3}\") #  0010 ¿Son los dos 1?\nprint(f\"OR: 10 | 3 = {10 | 3}\") #  1011 ¿Al menos uno es 1?\nprint(f\"XOR: 10 ^ 3 = {10 ^ 3}\") # 1001 ¿Son diferentes?\nprint(f\"NOT: ~10 = {~10}\") # -11 ?? Ni idea\nprint(f\"Desplazamiento a la derecha: 10 >> 2 {10 >> 2}\") # 0010 Se desplazan los bits 2 posiciones\nprint(f\"Desplazamiento a la izquierda: 10 << 2 {10 << 2}\") # 101000 Se desplazan los bits 2 posiciones\n\n# ESTRUCTURAS DE CONTROL\n\n# Condicionales\nmy_string = \"Jiji\"\nif my_string == \"Luis\":\n    print(\"my_string es 'Luis'\")\nelif my_string == \"MdF\":\n    print(\"my_string es 'MdF'\")\nelse:\n    print(\"my_string no es ni 'Luis' ni 'MdF\")\n\n# Iterativas\nprint(\"Bucle for\")\nfor i in range(10): # De 0 a 9\n    print(i)\n\nprint(\"Bucle while\") \ni=0\nwhile i <= 5: # De 0 a 5\n    print(i)\n    i += 1 \n\n# Manejo de excepciones\ntry:\n    print(10 / 0)\nexcept:\n    print(\"Se ha producido un error\")\nfinally:\n    print(\"Ha finalizado las excepciones\")\n\n#########\n# EXTRA #\n#########\nfor i in range(10, 56):\n    if (i % 2 == 0) and (i != 16) and  (i % 3 != 0):\n        print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/luterfloyd.py",
    "content": "'''\n  EJERCICIO:\n  - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n    Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n    (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n  - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n    que representen todos los tipos de estructuras de control que existan\n    en tu lenguaje:\n    Condicionales, iterativas, excepciones...\n  - Debes hacer print por consola del resultado de todos los ejemplos.\n \n  DIFICULTAD EXTRA (opcional):\n  Crea un programa que imprima por consola todos los números comprendidos\n  entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n'''\n\n\nprint('\\nOPERADOR DE ASIGNACION SIMPLE (=)') \nnumero1 = 2 \nnumero2 = 3\nlista_pares = [2,4,6]\n\ntexto1 = 'manzana'\ntexto2 = 'pera'\nlista_frutas = ['pera','mango','platano','melon','guanabana','guayaba','patilla']\n\nprint(f'numero1 = {numero1}')\nprint(f'numero2 = {numero2}')\nprint(f'texto1 = {texto1}')\nprint(f'texto2 = {texto2}')\n\nprint('\\nOPERADORES ARITMETICOS (+,-,*,/,%,**,//)')\nprint(f'suma:\\t\\t{numero1} + {numero2} = {numero1+numero2}')\nprint(f'resta:\\t\\t{numero2} - {numero1} = {numero2-numero1}')\nprint(f'multiplicacion:\\t{numero1} * {numero2} = {numero1*numero2}')\nprint(f'division:\\t{numero2} / {numero1} = {numero2/numero1}')\nprint(f'modulo:\\t\\t{numero2} % {numero1} = {numero2%numero1}')\nprint(f'potencia:\\t{numero1} ** {numero2} = {numero1**numero2}')\nprint(f'div. entero:\\t{numero2} // {numero1} = {numero2//numero1}')\nprint('concatenar texto con +\\t-> mi fruta favorita es la ' + texto1)\nprint(f'repetir texto con *\\t-> {texto1} * 3 =', texto1*3)\n\nprint('\\nOPERADORES LOGICOS (and, or, not)')\nprint('a and b -> Si a se evalúa a falso, entonces devuelve a, si no devuelve b:' )\nprint(f'{numero1} and {numero2} -> {numero1 and numero2}')\nprint('a or b -> Si a se evalúa a falso, entonces devuelve b, si no devuelve a:' )\nprint(f'{numero1} or {numero2} -> {numero1 or numero2}')\nprint('not a -> Si a se evalúa a falso, entonces devuelve True, si no devuelve False:' )\nprint(f'not {numero2} -> {not numero2}')\n\nprint('\\nOPERADORES DE COMPARACION (>,<,==,>=,<=,!=)')\n\nprint(f'mayor que:\\t{numero1} > {numero2}  -> {numero1>numero2}')\nprint(f'menor que:\\t{numero1} < {numero2}  -> {numero1<numero2}')\nprint(f'igual que:\\t{numero1} == {numero2} -> {numero1==numero2}')\nprint(f'mayor-igual que:{numero2} >= {numero1} -> {numero1>=numero2}')\nprint(f'menor-igual:\\t{numero2} <= {numero1} -> {numero1<=numero2}')\nprint(f'diferente que:\\t{numero1} != {numero2} -> {numero1!=numero2}')\n\nprint('\\nOPERADORES DE ASIGNACION (+=,-=,*=,/=,//=,**=)')\nasignacion = numero2\nasignacion += numero1\nprint(f'suma y asig.:\\t\\t{numero2} += {numero1} -> {asignacion}')\nvalor_anterior = asignacion\nasignacion -= numero1\nprint(f'resta y asig.:\\t\\t{valor_anterior} += {numero1} -> {asignacion}')\nvalor_anterior = asignacion\nasignacion *= numero1\nprint(f'multiplicacion y asig.:\\t{valor_anterior} *= {numero1} -> {asignacion}')\nvalor_anterior = asignacion\nasignacion /= numero1\nprint(f'division y asig.:\\t{valor_anterior} /= {numero1} -> {asignacion}')\nvalor_anterior = asignacion\nasignacion **= numero1\nprint(f'potenciacion y asig.:\\t{valor_anterior} **= {numero1} -> {asignacion}')\n\nprint('\\nOPERADORES DE IDENTIDAD (is, is not)')\nprint(f'{numero1} is {numero2}\\t\\t-> {numero1 is numero2}')\nprint(f'{texto1} is {texto2}\\t-> {texto1 is texto2}')\nprint(f'{numero1} is {lista_pares}\\t-> {numero1 is lista_pares}')\nprint(f'{numero2} is {numero2}\\t\\t-> {numero2 is numero2}')\nprint(f'{numero1} is not {numero2}\\t-> {numero1 is not numero2}')\n\nprint('\\nOPERADORES DE PERTENENCIA (in -> para comprobar si existe en una secuencia)')\nprint(f'{numero1} in {lista_pares} -> {numero1 in lista_pares}')\nprint(f'{numero2} in {lista_pares} -> {numero2 in lista_pares}')\nprint(f'{texto1}\\tin {lista_frutas} -> {texto1 in lista_frutas}')\nprint(f'{texto2}\\tin {lista_frutas} -> {texto2 in lista_frutas}')\n\nprint('\\nOPERADORES BIT A BIT (&,|,^,>>,<<)')\nprint(f'AND:\\t\\t{numero1} & {numero2} = {numero1&numero2}')\nprint(f'OR:\\t\\t{numero1} | {numero2} = {numero1|numero2}')\nprint(f'XOR:\\t\\t{numero1} ^ {numero2} = {numero1^numero2}')\nprint(f'desplaz. der.:\\t{numero1} >> {numero2} = {numero1>>numero2}')\nprint(f'desplaz. izq.:\\t{numero1} << {numero2} = {numero1<<numero2}')\n\nprint('\\nESTRUCTURAL DE CONTROL:')\nprint('* condicionales (if-elif-else/ while)')\nif numero1 > numero2:\n    print(f'{numero1} es mayor que {numero2}')\nelif numero1 < numero2:\n        print(f'{numero1} es menor que {numero2}')\nelse:\n      print(f'{numero1} es igual a {numero2}')\n\nprint('\\n* (while)')\ncontador = 0\nwhile contador < 40:\n      print(contador,'*'*contador)\n      contador += numero1**numero2\n      if contador==32:\n            print ('ciclo interrumpido (break)')\n            break\n      else:\n           continue\nelse:\n      print('final sin interrupcion')\nprint(f'valor de la variable :',contador)\n\nprint('\\n* iterables (for)')\nprint('lista de frutas (segun lista_pares):')\nfor numero in lista_pares:\n     print(lista_frutas[numero])\n\nprint('\\n*for - range')\nfor numero in range(1,11):\n  print(numero)\n\nprint('\\nPRUEBA EXTRA: numeros pares entre 10 y 55 (incluidos) que no sean 16, ni multiplos 3')\nfor numero in range(10,56):\n    if numero!=16 and numero%3 and not numero%2:\n      print (numero)\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/m-doce.py",
    "content": "#Operadores aritméticos: +, -, *, /, %\r\nsuma = (7 + 5)\r\nresta = (10 - 8)\r\nmultiplicacion = (3 * 9)\r\ndivision = (21 / 2)\r\ndivisionEntera = (21 // 2) #Devuelve solo la parte entera de la división\r\nmodulo = (21 % 2) #Devuelve el resto de la división (en este caso, 1)\r\npotencia = (2 ** 5) #Imprime el numero de la izquierda elevado al de la derecha\r\n\r\n#Operadores de asignación y comparación: =, !=, <, >, ==\r\nasignacion = 1 #El simbolo '=' se usa para asignar valores a las variables\r\nprint(9==3) #El '==' se utiliza para comparar la igualdad entre valores (devolviendo verdadero o falso)\r\nprint(9!=3) #El '!=' se utiliza para comparar si existe diferencia entre dos valores (devolviendo verdadero o falso)\r\nprint(9<3) #El '<' devuelve true cuando el valor a su izq es menor\r\nprint(9>3) #El '>' devuelve true cuando el valor a su izq es mayor\r\n\r\n#Operadores lógicos: and, or, not\r\nprint(True and False) #Con 'and' evaluamos si se cumplen dos o más condiciones\r\nprint(True or False) #Con 'or' evaluamos si se cumple al menos una condición\r\nprint(not True) #Con 'not' negamos/revertimos una condición\r\n\r\n#Operadores de identidad: is, is not\r\n#Estos operadores se utilizan para saber si dos variables apuntan o no al mismo objeto en memoria\r\nfirst = 10\r\nsecond = 10\r\nthird = first\r\nprint(first is second)\r\nprint(first is not second)\r\nprint(first is third)\r\nprint(first is not third)\r\n\r\n#Operadores de pertenencia: in, not in\r\n#Estos operadores se utilizan para saber si un valor esta presente en un conjunto de datos (string, arrays, etc)\r\npalabra = \"Operadores\"\r\nprint(\"u\" in palabra)\r\nprint(not \"u\" in palabra)\r\n\r\n#Estructuras de control\r\n#If-Else, se utiliza para seguir por un camino u otro en base a una condición\r\nnumber = 10\r\nif number > 10:\r\n    print(\"El numero es mayor que 10\")\r\nelif number == 10:\r\n    print(\"El numero es 10\")\r\nelse:\r\n    print(\"El numero es menor que 10\")\r\n\r\n#Estructuras de repetición\r\n#For, se utiliza para ejecutar instrucciones en bucle una cantidad de veces determinada\r\n\r\nfor i in range(10):\r\n    print(i)\r\n\r\n#While, se utiliza para ejecutar instrucciones en bucle una cantidad de veces indeterminada (por lo general hasta cumplir cierta condición)\r\nuserInput = int(input(\"Ingrese un numero para ver su doble, o '0' para finalizar: \"))\r\nwhile userInput != 0:\r\n    print(userInput*2)\r\n    userInput = int(input(\"Ingrese un numero para ver su doble, o '0' para finalizar: \"))\r\n\r\n#Estructuras de excepciones\r\ntry:\r\n    print(19 / 0)\r\nexcept:\r\n    print(\"Se ha producido un error\")\r\nfinally:\r\n    print(\"Fin del manejo de excepciones\")\r\n\r\n#EJERCICIO EXTRA\r\n\r\nfor value in range(10, 56):\r\n    if (value%2 == 0) and (value%3 != 0) and (value != 16):\r\n        print(value)\r\n\r\nprint(\"Fin del programa\")"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/m1l0j05.py",
    "content": "# Operadores Aritméticos:\n# 1. `+` (suma)\n# 2. `-` (resta)\n# 3. `*` (multiplicación)\n# 4. `/` (división)\n# 5. `%` (módulo - devuelve el resto de una división)\n# 6. `**` (exponente)\n# 7. `//` (división entera -  devuelve el cociente de la división redondeado hacia abajo al entero más cercano)\n\na = 10\nb = 3\n\naddition = a + b\nsubtraction = a - b\nmultiplication = a * b\ndivision = a / b\nmodulo = a % b\nexponent = a ** b\ninteger_division = a // b\n\nprint('\\nOPERADORES ARITMETICOS\\n')\nprint(addition)\nprint(subtraction)\nprint(multiplication)\nprint(division)\nprint(modulo)\nprint(exponent)\nprint(integer_division)\n\n\n# Operadores de Asignación:\n# 1. `=` (asignación)\n# 2. `+=` (suma y asigna)\n# 3. `-=` (resta y asigna)\n# 4. `*=` (multiplica y asigna)\n# 5. `/=` (divide y asigna)\n# 6. `%=` (módulo y asigna)\n# 7. `**=` (exponente y asigna)\n# 8. `//=` (división entera y asigna)\n# 9. `&=` (AND bit a bit y asigna) -> Este operador realiza un AND bit a bit entre dos variables y luego asigna el resultado a la variable de la izquierda. Ejemplo: x &= y es equivalente a x = x & y.\n# 10. `|=` (OR bit a bit y asigna) -> Realiza un OR bit a bit entre dos variables y asigna el resultado a la variable de la izquierda. Ejemplo: x |= y es equivalente a x = x | y.\n# 11. `^=` (XOR bit a bit y asigna) -> Ejecuta un XOR bit a bit entre dos variables y asigna el resultado a la variable de la izquierda. Ejemplo: x ^= y es equivalente a x = x ^ y.\n# 12. `>>=` (desplaza a la derecha y asigna) -> Desplaza los bits de la variable de la izquierda a la derecha por el número de posiciones indicadas por la variable de la derecha y luego asigna el resultado. Ejemplo: x >>= y es equivalente a x = x >> y.\n# 13. `<<=` (desplaza a la izquierda y asigna) -> Desplaza los bits de la variable de la izquierda a la izquierda por el número de posiciones indicadas por la variable de la derecha y luego asigna el resultado. Ejemplo: x <<= y es equivalente a x = x << y.\n\n# Los operadores de asignación del 9 al 13 en Python son operadores \n# compuestos que combinan una operación bit a bit con una asignación.\n\nprint('\\nOPERADORES DE ASIGNACION\\n')\n\nc = 5\nc += 2  # c es ahora 7\nc -= 1  # c es ahora 6\nc *= 2  # c es ahora 12\nc /= 4  # c es ahora 3.0\nc %= 3  # c es ahora 0.0\nc **= 2 # c es ahora 0.0\nc //= 2 # c es ahora 0.0\n\n# Inicialización de variables\nx = 4  # 100 en binario\ny = 3  # 011 en binario\n\n# Operador &= (AND bit a bit y asigna)\nx_and_assign = x  # Copiamos x para no modificar el original\nx_and_assign &= y # Equivalente a x_and_assign = x_and_assign & y\n# x_and_assign es ahora 0 (000 en binario)\n\n# Operador |= (OR bit a bit y asigna)\nx_or_assign = x  # Copiamos x para no modificar el original\nx_or_assign |= y # Equivalente a x_or_assign = x_or_assign | y\n# x_or_assign es ahora 7 (111 en binario)\n\n# Operador ^= (XOR bit a bit y asigna)\nx_xor_assign = x  # Copiamos x para no modificar el original\nx_xor_assign ^= y # Equivalente a x_xor_assign = x_xor_assign ^ y\n# x_xor_assign es ahora 7 (111 en binario)\n\n# Operador >>= (desplaza a la derecha y asigna)\nx_shr_assign = x  # Copiamos x para no modificar el original\nx_shr_assign >>= 1 # Equivalente a x_shr_assign = x_shr_assign >> 1\n# x_shr_assign es ahora 2 (010 en binario)\n\n# Operador <<= (desplaza a la izquierda y asigna)\nx_shl_assign = x  # Copiamos x para no modificar el original\nx_shl_assign <<= 1 # Equivalente a x_shl_assign = x_shl_assign << 1\n# x_shl_assign es ahora 8 (1000 en binario)\n\n# Resultados\nprint(\"AND bit a bit y asigna (x &= y):\", x_and_assign)\nprint(\"OR bit a bit y asigna (x |= y):\", x_or_assign)\nprint(\"XOR bit a bit y asigna (x ^= y):\", x_xor_assign)\nprint(\"Desplaza a la derecha y asigna (x >>= 1):\", x_shr_assign)\nprint(\"Desplaza a la izquierda y asigna (x <<= 1):\", x_shl_assign)\n\n\n# Operadores de Comparación:\n# 1. `==` (igual a)\n# 2. `!=` (diferente de)\n# 3. `>` (mayor que)\n# 4. `<` (menor que)\n# 5. `>=` (mayor o igual que)\n# 6. `<=` (menor o igual que)\n\n\nprint('\\nOPERADORES DE COMPARACION\\n')\n\nd = 5\ne = 10\n\nequals = d == e # False\ndifferent = d != e # True\ngreater_than = d > e # False\nless_than = d < e # True\ngreater_equal = d >= e # False\nless_equal = d <= e # True\n\nprint(equals)\nprint(different)\nprint(greater_than)\nprint(less_than)\nprint(greater_equal)\nprint(less_equal)\n\n\n# Operadores Lógicos:\n# 1. `and` (y lógico)\n# 2. `or` (o lógico)\n# 3. `not` (no lógico)\n\nprint('\\nOPERADORES LOGICOS\\n')\n\nf = True\ng = False\n\nand_logical = f and g # False\nor_logical = f or g # True\nnot_logical = not f # False\n\nprint(and_logical)\nprint(or_logical)\nprint(not_logical)\n\n# Operadores de Identidad:\n# 1. `is` (es)\n# 2. `is not` (no es)\n\nprint('\\nOPERADORES DE IDENTIDAD\\n')\n\nh = [1, 2, 3]\ni = [1, 2, 3]\nj = h\n\nit_is = h is j     # True\nits_not = h is i  # False\n\nprint(it_is)\nprint(its_not)\n\n# Operadores de Membresía:\n# 1. `in` (en)\n# 2. `not in` (no en)\n\nprint('\\nOPERADORES DE IDENTIDAD\\n')\n\nk = 3\n\nits_in = k in h   # True\nits_not_in = k not in i # False\n\nprint(its_in)\nprint(its_not_in)\n\n# Operadores Bit a Bit:\n# 1. `&` (AND)\n# 2. `|` (OR)\n# 3. `^` (XOR)\n# 4. `~` (NOT)\n# 5. `<<` (desplazamiento a la izquierda)\n# 6. `>>` (desplazamiento a la derecha)\n\nprint('\\nOPERADORES BIT A BIT\\n')\n\nl = 6  # 110 en binario\nm = 2  # 010 en binario\n\nand_bit = l & m  # 010 -> 2\nor_bit = l | m   # 110 -> 6\nxor_bit = l ^ m  # 100 -> 4\nnot_bit = ~l     # -011 -> -7\ndesp_left = l << m # 11000 -> 24\ndesp_rigth = l >> m # 001 -> 1\n\nprint(and_bit)\nprint(or_bit)\nprint(xor_bit)\nprint(not_bit)\nprint(desp_left)\nprint(desp_rigth)\n\n# Estructuras de Control Condicionales\n# Ejemplo de if, elif, else\nnumber = 10\nif number > 15:\n    print(\"The number is greater than 15\")\nelif number == 10:\n    print(\"The number is 10\")\nelse:\n    print(\"The number is less than 15 and not 10\")\n\n# Estructuras de Control de Bucles\n# Ejemplo de for\nnames = [\"Ana\", \"Juan\", \"Carlos\"]\nfor name in names:\n    print(f\"Hello, {name}\")\n\n# Ejemplo de while\ncounter = 5\nwhile counter > 0:\n    print(f\"Counter: {counter}\")\n    counter -= 1\n\n# Ejemplo de break\nfor i in range(1, 10):\n    if i == 5:\n        break\n    print(i)\n\n# Ejemplo de continue\nfor i in range(1, 10):\n    if i % 2 == 0:\n        continue\n    print(i)\n\n# Estructuras de Control para Manejar Excepciones\n# Ejemplo de try, except, else, finally\ntry:\n    result = 10 / 0\nexcept ZeroDivisionError:\n    print(\"Division by zero\")\nelse:\n    print(\"Division performed correctly\")\nfinally:\n    print(\"This block is always executed\")\n\n# Ejercicio Extra:\n\nprint('\\n[+] Ejercicio extra:\\n')\n\ndef number_checker(start :int, end :int, exception :int) -> list:\n    verified_numbers = []\n    for number in range(start, end + 1):\n        if number % 2 == 0 and number % 3 != 0 and number != exception:\n            verified_numbers.append(number)\n\n    return verified_numbers\n\nstart_range = 10\nend_range = 55\nexcluded_number = 16\n\nresult = number_checker(start_range, end_range, excluded_number)\n\nprint(result)\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/macova96.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\"\"\"\na = 5\nb = 7\nt=True\nf=False\n\nprint(\"\\n_________________________________________________\")\n\nprint(\"OPERADORES ARITMETICOS\")\nprint(f\"Variable A= {a}\")\nprint(f\"Variable B= {b}\")\n\nprint(f\"\\nA + B = {a+b:10} <--Suma\")\nprint(f\"A - B = {a-b:10} <--Resta\")\nprint(f\"A * B = {a*b:10} <--Multiplicación\")\nprint(f\"A / B = {a/b:10.2f} <--División\")\nprint(f\"A % B = {a%b:10} <--Módulo\")\nprint(f\"A ** B = {a**b:10} <--Exponenciación\")\nprint(f\"A // B = {a//b:10} <--Cociente\")\nprint(\"\\n_________________________________________________\")\n\nprint(\"\\nOPERADORES LÓGICOS\")\nprint(f\"Variable T= {t}\")\nprint(f\"Variable F= {f}\")\n\nprint(f\"\\nT and F = {t and f:10} <--AND\")\nprint(f\"T or F = {t or f:10} <--OR\")\nprint(f\"not T = {not t:10} <--NOT\")\nprint(\"\\n_________________________________________________\")\n\nprint(\"\\nOPERADORES DE COMPARACION\")\nprint(f\"Variable A= {a}\")\nprint(f\"Variable B= {b}\")\n\nprint(f\"\\nA == B = {a==b:10} <--Igualdad\")\nprint(f\"A != B = {a!=b:10} <--Desigualdad\")\nprint(f\"A < B = {a<b:10} <--Menor que\")\nprint(f\"A > B = {a>b:10} <--Mayor que\")\nprint(f\"A <= B = {a>=b:10} <--Menor o igual que\")\nprint(f\"A >= B = {a>=b:10} <--Mayor o igual que\")\nprint(\"\\n_________________________________________________\")\n\nprint(\"\\nOPERADORES DE ASIGNACIÓN\")\nx = 0\nprint(f\"Variable x= {x}\")\na = 5\nprint(f\"\\nA = 5 --> {a:10} <--Asignacion simple\")\na += 3\nprint(f\"A += 3 --> {a:10} <--Suma y asigna\")\na -= 4\nprint(f\"A -= 4 --> {a:10} <--Resta y asigna\")\na *= 5\nprint(f\"A *= 5 --> {a:10} <--Multiplica y asigna\")\na /= 6\nprint(f\"A /= 6 --> {a:10.2f} <--Divide y asiga\")\na //= 7\nprint(f\"A //= 7 --> {a:10} <--División entera y asigna\")\na //= 7\nprint(f\"A %= 8 --> {a:10} <--Módulo y asigna\")\na //= 7\nprint(f\"A **= 7 --> {a:10} <--Exponenciación y asigna\")\na //= 7\nprint(f\"A //= 7 --> {a:10} <--Divición entera y asigna\")\nprint(\"\\n_________________________________________________\")\n\nprint(\"\\nOPERADORES BIT A BIT\")\n\n# Definimos dos números enteros (representando valores binarios)\na_bin = 5  # En binario: 0101\nb_bin = 3  # En binario: 0011\n\nprint(f\"Variable A= {a_bin}\")\nprint(f\"Variable B= {b_bin}\")\n\n# Operadores bit a bit\nprint(f\"\\nA & B = {a_bin & b_bin:10} <--AND bit a bit\")\nprint(f\"A | B = {a_bin | b_bin:10} <--OR bit a bit\")\nprint(f\"A ^ B = {a_bin ^ b_bin:10} <--XOR bit a bit\")\nprint(f\"~A = {~a_bin:10} <--NOT bit a bit\")\nprint(\"\\n_________________________________________________\")\n\n\nprint(\"\\nOPERADORES DE IDENTIDAD\")\n\"\"\"\nCompara sin dos objetos apuntan a la misma ubicacion en memoria\nEsto es diferente de comparar si dos objetos tiene el mismo valor\n\"\"\"\na_list = [1, 2, 3]\nb_list = [1, 2, 3]\nc_list = a_list\n\nprint(f\"Lista A= {a_list}\")\nprint(f\"Lista B= {b_list}\")\nprint(f\"Lista C= {c_list} <-- c_list = a_list\")\n\nprint(f\"\\nA is B = {a_list is b_list} <--Devuelve true si son el mismo objeto\")\nprint(f\"A is not B = {a_list is not b_list} <--Devuelve true si diferentes objetos\")\nprint(f\"A is C = {a_list is c_list} \")\nprint(\"\\n_________________________________________________\")\n\nprint(\"\\nOPERADORES DE PERTENENCIA\")\n\"\"\"\nValidad si un valor se encuentra dentro de una lista\n\"\"\"\nfrutas = [\"manzana\", \"pera\", \"banano\"]\nprint(f\"Lista de frutas = {frutas}\")\n\nprint(f\"\\npera in frutas {\"pera\" in frutas} <--Develve true si el valor esta dentro de la lista\")\nprint(f\"zapote in frutas {\"zapote\" in frutas} <--Develve true si el valor NO esta dentro de la lista\")\n\nprint(\"\\n_________________________________________________\")\n\nprint(\"\\nESTRUCTURAS DE CONTROL - ITERATIVAS - EXCEPCIONES\")\nprint(\"\\nIF - ELIF - ELSE --> (EJEMPLO CALIFICACIONES)\")\n\ntry:\n    calificacion = int(input(\"Ingrese su calificación de 1 a 10\\n\"))\n\n    if calificacion >= 9 :\n        print(\"\\nExcelente\")\n    elif calificacion >= 8 :\n        print(\"\\nMuy Bien\")\n    elif calificacion >= 7 :\n        print(\"\\nBien\")\n    elif calificacion >= 6 :\n        print(\"\\nRegualar\")\n    else:\n        print(\"\\nMal\")\n\nexcept ValueError:\n    print(\"Error: debe ingresar un numero valido \")\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/majinka10.py",
    "content": "# Operadores de asignación.\nx = 10\ny = 2\nz = x + y\nverdadero = True\nfalso = False\nlista = [10, 2]\n\noperadores_aritmeticos = [('+', \"Suma\"), ('-', \"Resta\"), (\"*\", \"Multiplicación\"), ('/', \"División\"), ('**', \"Exponenciación\"), ('%', \"Módulo\"), ('//', \"División entera\")]\n\nprint(\"Operadores aritméticos.\\n\")\nfor operador in operadores_aritmeticos:\n    resultado = eval(f'{x} {operador[0]} {y}')\n    print(f'{x} {operador[0]} {y} = {resultado} - {operador[1]}')\n\nprint(\"\\nOperadores lógicos.\\n\")\nprint(f\"Verdadero y Falso: {verdadero and falso}\")\nprint(f\"Verdadero o Falso: {verdadero or falso}\")\nprint(f\"Verdadero y no Falso: {verdadero and not falso}\")\nprint(\"\\nOperadores de comparación.\\n\")\nprint(f\"{x} es igual a {y}: {x == y}\")   \nprint(f\"{x} es diferente a {y}: {x != y}\")   \nprint(f\"{x} es mayor que {y}: {x > y}\")    \nprint(f\"{x} es menor que {y}: {x < y}\")    \nprint(f\"{x} es mayor o igual que {y}: {x >= y}\")   \nprint(f\"{x} es menor o igual que {y}: {x <= y}\")   \n\nprint(\"\\nOperadores de identidad. \\n\")\nprint(f\"¿x es z?: {x is z}\")\nprint(f\"¿x no es z?: {x is not z}\")\n\nprint(\"\\nOperadores de pertenencia.\\n\")\nprint(f\"¿x está en la lista?: {x in lista}\")\nprint(f\"¿y no está en la lista?: {y not in lista}\")\n\nprint(\"\\nOperadores de bits\\n\")\nprint(f\"AND: {x & y}\")\nprint(f\"OR: {x | y}\")\nprint(f\"XOR: {x ^ y}\")\nprint(f\"Desplazamiento a la izquierda: {x << 1}\")\nprint(f\"Desplazamiento a la derecha: {y >> 1}\")\nprint(f\"Complemento a uno de {x}: {~x}\")\n\n# if\n# elif \n# else\n# while\n# for\n# break\n# continue\n# pass\n# try\n# excep\n# finally\n\nprint(\"\\nEstructura de control if\")\nedad = int(input(\"Ingrese su edad: \"))\nif edad >= 18:\n    print(\"Eres mayor de edad.\")\nelse:\n    print(\"Eres menor de edad.\")\n\nprint(\"\\nEstructura de control while\")\ncontador = 0\nwhile contador < 3:\n    print(f\"Contador: {contador}\")\n    contador += 1\n\nprint(\"\\nEstructura de control for con pass\")\nfor i in range(5):\n    if i == 3:\n        pass \n    else:\n        print(i)\n\nprint(\"\\nEstructura de control else en bucle\")\nfor i in range(3):\n    print(f\"Iteración {i}\")\nelse:\n    print(\"El bucle ha finalizado.\")\n\nprint(\"\\nEstructura de control if-else en una línea\")\nvalor = 10\nresultado = \"Par\" if valor % 2 == 0 else \"Impar\"\nprint(f\"El número {valor} es {resultado}.\")\n\nprint(\"\\nEstructura de control break y continue\")\nfor num in range(10):\n    if num == 5:\n        print(\"Encontré el número 5. Salgo del bucle.\")\n        break\n    elif num % 2 == 0:\n        print(f\"Número par: {num}\")\n        continue\n    print(f\"Número impar: {num}\")\n\nprint(\"\\nEstructura de control try, except, finally\")\ntry:\n    print(\"Vamos a hacer una división.\")\n    numerador = int(input(\"Ingrese el numerador: \"))\n    denominador = int(input(\"Ingrese el denominador: \"))\n    resultado = numerador / denominador\n    print(f\"Resultado de la división: {resultado}\")\nexcept ValueError:\n    print(\"Error: Ingrese números enteros.\")\nexcept ZeroDivisionError:\n    print(\"Error: No se puede dividir por cero.\")\nfinally:\n    print(\"Este bloque siempre se ejecuta, independientemente de las excepciones.\")\n\nprint(\"\\nEjercicio EXTRA\")\nfor _ in range(10, 56):\n    if _ % 2 == 0 and _ != 16 and _ % 3 != 0:\n        print(_)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/mallcca.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\"\"\"\n\n# Listado de operadores\nprint('--------------------------------')\nprint('Operadores aritméticos')\nprint('--------------------------------')\nresultado = 10 + 5\nprint(resultado)\n\n# Operador resta\nresultado = 15 - 10\nprint(resultado)\n\n# Operador división\nresultado = 15 / 10\nprint(resultado)\n\n# Operador división descartando el resto\nresultado = 15 / 10\nprint(resultado)\n\nprint('--------------------------------')\nprint('Operadores lógicos')\nprint('--------------------------------')\n\nresultado = True and True\nprint(resultado)\n\nresultado = True or False\nprint(resultado)\n\nresultado = not True\nprint(resultado)\n\nprint('--------------------------------')\nprint('Operadores de identidad')\nprint('--------------------------------')\n\nresultado = 'Hello' is 'Hi'\nprint(resultado)\n\nresultado = 'Hello' is 'Hello'\nprint(resultado)\n\nresultado = 'Hello' is not 'Hi'\nprint(resultado)\n\nprint('--------------------------------')\nprint('Operadores de asignación')\nprint('--------------------------------')\n\nresultado = 100\nresultado += 1\nprint(resultado)\n\nresultado = 100\nresultado -= 1\nprint(resultado)\n\nresultado = 100\nresultado *= 3\nprint(resultado)\n\nresultado = 100\nresultado /= 3\nprint(resultado)\n\nprint('--------------------------------')\nprint('Operadores de pertenencia')\nprint('--------------------------------')\n\nresultado = 'a' in ['a', 'b', 'c']\nprint(resultado)\n\nresultado = 'z' in ['a', 'b', 'c']\nprint(resultado)\n\nprint('--------------------------------')\nprint('Operadores de bit')\nprint('--------------------------------')\n\nresultado = 'a' in ['a', 'b', 'c']\nprint(resultado)\n\nprint('--------------------------------')\nprint('Estructuras de control')\nprint('--------------------------------')\n\nprint('--- If-elif-else ---')\na = 10\nb = 100\nif a == b:\n    print('a es igual a b')\nelif a > b:\n    print('a es mayor a b')\nelse:\n    print('a es menor a b')\n\nprint('--- for ---')\nlist = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]\nfor x in list:\n    print(x)\n\nprint('--- try-except-finally ---')\na = 100\nb = 'cien'\n\nif str(a) == b:\n    print('a es igual a b')\n    \ntry:\n    if a == int(b):\n        print('a es igual a b')\nexcept:\n    print('Error: a y b no se pueden comparar')\nfinally:\n    print('try-except ejecutado')\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\"\"\"\nfor x in range(10, 56):\n    if x%2 == 0 and x != 16 and x%3 != 0:\n        print(x)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/manjaitan.py",
    "content": "'''\n\nOPERATORS:\n\n+       -       *       **      /       //      %      @\n<<      >>      &       |       ^       ~       :=\n<       >       <=      >=      ==      !=\n\n'''\n\n# ARITMETICOS:\n\nprint (\"########################\")\n\n# Operador suma:\nresultado = 1 + 1\nprint (resultado)\n\n# Operador resta:\nresultado = 1 - 1\nprint (resultado)\n\n# Operador multiplica:\nresultado = 2 * 2\nprint (resultado)\n\n# Operador dividir:\nresultado = 2 / 2\nprint (resultado)\n\n# Operador division del piso, descarta el resto:\nresultado = 2 // 2\nprint (resultado)\n\n# Operador resto:\nresultado = 2 % 2\nprint (resultado)\n\n# LOGICOS:\n\n# and => True and True => Devuelve True.\n# or => True or false => Devuleve True.\n# not => not True => Devuelve False.\n\nprint (\"########################\")\n\na = True\nb = False\n\nresultado = a and a\nprint (resultado)\n\nresultado = a or b\nprint (resultado)\n\nresultado = b or b\nprint (resultado)\n\nresultado = (not a)\nprint (resultado)\n\nresultado = (not b)\nprint (resultado)\n\n# OPERADORES DE ASIGNACION:\n\n# = += -= *= /= %= **= //=\n\nprint (\"########################\")\n\nvalor = 1\nvalor += 1\nprint(valor)\n\nvalor = 1\nvalor -= 1\nprint(valor)\n\nvalor = 2\nvalor *= 2\nprint(valor)\n\nvalor = 20\nvalor /= 5\nprint(valor)\n\n# OPERADORES DE INDENTIDAD:\n\n# is , is not.\n\nprint (\"########################\")\n\na = 1\nb = 2\nc = 3\n\nprint (a is b)\nprint (a is not b)\nprint (a is not c)\n\n# OPERADORES DE PERTENCIAS, devuelve valor True o Falso.\n# in, not in.\nprint (\"########################\")\n\nlista = [1,2,3,4,5,6,8,9,10]\nresultado = 4 in lista\nprint (resultado)\nresultado = 5 in lista\nprint (resultado)\nresultado = 5 not in lista\nprint (resultado)\nresultado = 4 not in lista\nprint (resultado)\n\n\n# OPERADORES DE BIT.\n# x | y, x ^ y, x & y, x << n, x >> n, ~x\n\nprint (\"########################\")\n\na = 4\nb = 2\nresultado = a | b\nprint(resultado)\n\n# ESTRUCTURAS CONDICIONALES, ITERATIVAS, EXCEPCIONES.\n# if, if-else\n# for\nprint (\"########################\")\n\na = 1 ; b = 2; c = 3\n\nresultado = a + b + c\n\nif ( resultado >= 3 ):\n    print (\"Resultado es mayor a 3\")\nelse:\n    print (\"Resultado es menor a 3\")\n\nprint (\"########################\")\n    \n# ITERATIVAS.\n\nfor x in range (1, 10, 1):\n    print (x)\n    \n\nprint (\"########################\")\n\n# EXCEPCION.\n\nwhile True:\n    try:\n        x = int(input(\"Introduzca un número: \"))\n        break\n    except ValueError:\n        print (\"Número introducido no es del tipo correcto, vuelva a intentarlo.\")\n        \n# OPCIONAL:\nprint (\"########################\")\n\n\nfor x in range (10, 56, 1 ):\n    if x == 16:\n        exit\n    elif x % 2 == 0:\n        print (x)\n    elif x % 3 == 0:\n        exit"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/marcelosanchez166.py",
    "content": "\"\"\"EJERCICIO:\n  - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n    Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n    (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n\n  - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n    que representen todos los tipos de estructuras de control que existan\n    en tu lenguaje:\n    Condicionales, iterativas, excepciones...\n\n  - Debes hacer print por consola del resultado de todos los ejemplos.\n  DIFICULTAD EXTRA (opcional):\n  Crea un programa que imprima por consola todos los números comprendidos\n  entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\n  Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\"\"\"\n\n\n# 1. Operadores Aritmeticos\n\nsuma = 1 + 2\nresta = 2 - 1\nmultiplicacion = 3 * 4\ndivision = 25 / 5\ndivision_entera = 15 // 4\nmodulo = 4 % 2\nexponente = 3 ** 2\n\n# 2. Operadores de Comparación:\n\nigualdad = 5 == 5\nmenor_que = 5 < 6\nmayor_que = 7 > 3\nmenor_igual_que = 4 <= 5\nmayor_igual_que = 5 >= 2\ndiferente_de = 7 != 6\n\nis_ = suma is resta\nis_not = resta is not multiplicacion\nprint(is_, is_not)\n\n# 3. Operadores Lógicos:\n\nand_ = igualdad and menor_que\nor_ = mayor_igual_que or menor_igual_que\nnot_ = not igualdad\n\nprint(and_, or_, not_)\n\n\n# 4. Operadores de asignacion\n\n# asignando el entero 5 a la variable x\nx = 5\n# Suma y asigna.\nx += 3\n# Resta y asigna\nx -= 2\n# Multiplica y asigna\nx *= 4\n# Divide y asigna\nx /= 10\n# Módulo y asigna\nx %= 3\n\n\n# Operaciones con operadores:  Condicionales, iterativas, excepciones...\nif suma:\n    print(suma)\n\nvalor = 5\nfor i in range(1, valor+1):\n    if i == 5:\n        print(\"soy igual que el valor de la variable\")\n    else:\n        print(i)\n\n\nfor i in range(10, 0, -2):\n    if i >= 3:\n        print(\"numero es mayor o igual a 3\")\n    else:\n        print(i)\n\nfrutas = ['manzana', 'banana', 'uva']\n\nfor fruta in frutas:\n    if \"tomate\" not in frutas:\n        print(\"No esta en la lista\")\n\nnombres = ['Ana', 'Luis', 'Mario']\n\nfor i, nombre in enumerate(nombres):\n    if \"Ana\" == nombre:\n        print(\"El nombre Ana si existe en la lista\")\n    else:\n        print(f\"{i}: {nombre}\")\n\npersona = {'nombre': 'Juan', 'edad': 30}\n\nfor clave in persona:\n    print(clave)\n\n\nfor clave, valor in persona.items():\n    print(f\"{clave}: {valor}\")\n\n\nfor letra in \"Hola\":\n    print(letra)\n\ncontador = 0\nwhile contador < 5:\n    print(contador)\n    contador += 1\n\n\nnumero = 0\nwhile numero <= 0:\n    try:\n        numero = int(input(\"Ingrese un número positivo: \"))\n        if numero <= 0:\n            print(\"El número debe ser positivo.\")\n    except ValueError:\n        print(\"Entrada inválida. Ingrese un número.\")\nprint(\"Número válido ingresado:\", numero)\n\nwhile True:\n    entrada = input(\"Ingrese 'salir' para terminar: \")\n    if entrada.lower() == \"salir\":\n        break\n    print(\"Entrada:\", entrada)\n\n\nnumero = 0\nwhile numero < 10:\n    numero += 1\n    if numero % 2 == 0:\n        continue  # Salta el resto del código en esta iteración si es par\n    print(numero)\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/marcoh2325.py",
    "content": "### Operaciones aritmeticas en Python ###\n\nprint(\"Operaciones aritmeticas en Python\")\nprint()\noperando_1 = 24 #Asignación del valor 24 a la variable operando_1\noperando_2 = 2\nprint(f\"\"\"Dados dos valores {operando_1} y {operando_2}, siendo estos bool, int, float o complex.\nTener en cuenta al realizar operaciones aritmeticas True equivale al valor 1 y False al 0. \nRecordar tambien que al igual de cuando se trabaja con el conjunto de los números reales o complejos\nla division por 0 no esta definida\"\"\")\nprint(\"En python podemos sumarlos:\" , operando_1 + operando_2)\nprint(\"Restarlos: \", operando_1 - operando_2)\nprint(\"Multiplicarlos: \", operando_1 * operando_2)\nprint(\"Dividirlos: \", operando_1 / operando_2)\nprint(\"Dividirlos y truncar los todos decimales del resultado: \", operando_1 // operando_2)\nprint(\"Calcular el módulo (si ninguno de los operandos es de tipo complex): \", operando_1 % operando_2)\nprint(f\"Tambien se puede elevar un número a otro. Para por ejemplo calcular {operando_1} elevado a {operando_2}, obteniendo {operando_1**operando_2}\")\nprint()\noperando_1 = \"Monty \"\noperando_2 = \"Python\"\nprint(f\"En el caso de que ambos valores sean del tipo string, siendo estos: '{operando_1}',  '{operando_2}'\")\nprint(f\"La operación '+' los concatena y crea con el resultado un nuevo string: '{operando_1 + operando_2}'\")\nprint(\"\"\"De forma similar si ambos operandos son de tipo list o de tipo tuple, \nse obtendrá como resultado una nueva lista/tupla con los elementos del primer operando y del segundo, en ese orden.\"\"\")\noperando_1 = [1, 2, 3]\noperando_2 = [30, 20, 10]\nprint(f\"Por ejemplo, para los operandos {operando_1} y {operando_2} se obtiene:\", operando_1 + operando_2)\nprint()\nprint(f\"\"\"En el caso de que tengamos un objeto int multiplicando un operador de tipo lista, tupla o string.\nEl resultado es otro iterable del mismo tipo pero que contiene tantas copias del contanido como valor tenga el\nobjeto int. Examplos: \"\"\")\noperando_1 = 2\noperando_2 = \"Hola\"\nprint(f\"Para los operandos {operando_1} y '{operando_2}', resultado: '{operando_1*operando_2}'\")\noperando_1 = 4\noperando_2 = [2,3]\nprint(f\"Para los operandos {operando_1} y {operando_2}, resultado: {operando_1*operando_2}\")\noperando_1 = 3\noperando_2 = (2,\"cereza\")\nprint(f\"Para los operandos {operando_1} y {operando_2}, resultado: {operando_1*operando_2}\")\n\"Se puede observar que si el objeto de tipo int es negativo o igual a cero, el resultado es una lista, tupla o string vacío\"\noperando_1 = 0\nprint(f\"Para los operandos {operando_1} y {operando_2}, resultado: {operando_1*operando_2}\")\noperando_1 = -6\nprint(f\"Para los operandos {operando_1} y {operando_2}, resultado: {operando_1*operando_2}\")\nprint(\"Estas operaciones no se pueden realizar con objetos del tipo set o dict, porque dichos tipos no admiten copias de sus elementos\")\nprint()\n\n### Operadores lógicos ###\n\nprint(\"\"\"Recordar que en Python dado un iterable si este no esta vacío se evalua como verdadero (True) y si esta vacío como falso (False).\nSi se trata de un número, se evalua como verdadero (True) si es diferente a cero, en caso contrario se evalua como falso (False)\"\"\")\noperando_1 = True\noperando_2 = False\nprint(f\"\"\"Negación lógica, ejemplo: para el operando_1 = {operando_1} su negación se escribe 'not operando_1'\ny es igual a  {not operando_1}\"\"\")\nprint(f\"\"\"Or, ejemplo: Para operando_1 = {operando_1} y operando_2 = {operando_2} la operación or se escribe\n'operando_1 or operando_2' y da como resultado {operando_1 or operando_2}\"\"\")\nprint(f\"\"\"And, ejemplo: Para operando_1 = {operando_1} y operando_2 = {operando_2} la operación and se escribe\n'operando_1 and operando_2' y da como resultado {operando_1 and operando_2}\"\"\")\n\n### Operadores de comparación ###\nprint(\"\"\"Si se los operandos son int o float, se puede realizar las siguientes comparaciones: \"\"\")\noperando_1 = 4\noperando_2 = 4.5\nprint(f\"es igual? Ejemplo: '{operando_1} == {operando_2}', da como resultado {operando_1 == operando_2}\")\nprint(f\"es diferente? Ejemplo: '{operando_1} != {operando_2}', da como resultado {operando_1 != operando_2}\")\nprint(f\"es menor o igual? Ejemplo: '{operando_1} <= {operando_2}', da como resultado {operando_1 <= operando_2}\")\nprint(f\"es mayor o igual? Ejemplo: '{operando_1} >= {operando_2}', da como resultado {operando_1 >= operando_2}\")\nprint(f\"es menor? Ejemplo: '{operando_1} < {operando_2}', da como resultado {operando_1 < operando_2}\")\nprint(f\"es mayor? Ejemplo: '{operando_1} > {operando_2}', da como resultado {operando_1 > operando_2}\")\nprint(\"Si los operandos son ambos del tipo complex o dicts solo las operaciones de comparación == o != estan definidas\")\nprint(\"\"\"Si los operandos son strings, lists, tuples, sets. Todas las operaciones de comparación estan definidas. \nEl criterio de comparación varía dependiendo de que contengan.\nEn el caso de los strings, que contienen carácteres, se realiza una comparación de los códigos ascii cada carácter uno a uno de ambos string\npara determinar el resultado.\nDe forma similar cuando se comparan listas o tuplas, se compara el primer elemento de ambas listas/tuplas, luego el segundo de ambas\ny se continua así hasta que terminar una de las listas/tuplas, determinando finalmente el resultado de la comparación\"\"\")\nprint(\"\"\"En el caso de que los operandos sean sets: \n< : es subconjunto de\n> : contiene\n>= : contiene o es igual a\n<= : es subconjunto de o es igual a\nAlgunos ejemplos en este caso:\"\"\")\n\noperando_1 = {2, 4}\noperando_2 = {1, 2, 3, 4}\nprint(f\"son iguales? Ejemplo: {operando_1} == {operando_2}, da como resultado {operando_1 == operando_2}\")\nprint(f\"son diferentes? Ejemplo: {operando_1} != {operando_2}, da como resultado {operando_1 != operando_2}\")\nprint(f\"es subconjunto o es igual? Ejemplo: {operando_1} <= {operando_2}, da como resultado {operando_1 <= operando_2}\")\nprint(f\"contiene o es igual? Ejemplo: {operando_1} >= {operando_2}, da como resultado {operando_1 >= operando_2}\")\nprint(f\"es subconjunto y es diferente? Ejemplo: {operando_1} < {operando_2}, da como resultado {operando_1 < operando_2}\")\nprint(f\"contiene y es diferente? Ejemplo: {operando_1} > {operando_2}, da como resultado {operando_1 > operando_2}\")\nprint()\n### Asignaciones ###\noperando_1 = {2, 4, 6, 8, 10}\noperando_2 = 4\nprint(\"Existen diferentes formas de asignar valores a variables en Python\")\n# =\nprint(f\"Utilizando =, se asigna un objeto a una variable. Ejemplo: 'even_numbers_to_10 = {operando_1}'\")\n# +=\noperando_1 = 10\nprint(f\"\"\"Utilizando '<variable> += <objeto>', se obtiene un resultado equivalente a '<variable> = <variable> + <objeto>'. \nEjemplo: Si operando_1 = {operando_1} y operando_2 = {operando_2}\"\"\")\noperando_1 += operando_2\nprint(f\"'operando_1 += operando_2' da como resultado operando_1 = {operando_1}\")\n# -=\nprint(f\"\"\"Utilizando '<variable> -= <objeto>', se obtiene un resultado equivalente a '<variable> = <variable> - <objeto>'. \nEjemplo: Si operando_1 = {operando_1} y operando_2 = {operando_2}\"\"\")\noperando_1 -= operando_2\nprint(f\"'operando_1 -= operando_2' da como resultado operando_1 = {operando_1}\")\n# *=\nprint(f\"\"\"Utilizando '<variable> *= <objeto>', se obtiene un resultado equivalente a '<variable> = <variable> * <objeto>'. \nEjemplo: Si operando_1 = {operando_1} y operando_2 = {operando_2}\"\"\")\noperando_1 *= operando_2\nprint(f\"'operando_1 *= operando_2' da como resultado operando_1 = {operando_1}\")\n# /=\nprint(f\"\"\"Utilizando '<variable> /= <objeto>', se obtiene un resultado equivalente a '<variable> = <variable> / <objeto>'. \nEjemplo: Si operando_1 = {operando_1} y operando_2 = {operando_2}\"\"\")\noperando_1 /= operando_2\nprint(f\"'operando_1 /= operando_2' da como resultado operando_1 = {operando_1}\")\n# //=\nprint(f\"\"\"Utilizando '<variable> //= <objeto>', se obtiene un resultado equivalente a '<variable> = <variable> // <objeto>'. \nEjemplo: Si operando_1 = {operando_1} y operando_2 = {operando_2}\"\"\")\noperando_1 //= operando_2\nprint(f\"'operando_1 //= operando_2' da como resultado operando_1 = {operando_1}\")\n# %=\nprint(f\"\"\"Utilizando '<variable> %= <objeto>', se obtiene un resultado equivalente a '<variable> = <variable> % <objeto>'. \nEjemplo: Si operando_1 = {operando_1} y operando_2 = {operando_2}\"\"\")\noperando_1 %= operando_2\nprint(f\"'operando_1 %= operando_2' da como resultado operando_1 = {operando_1}\")\n# **=\nprint(f\"\"\"Utilizando '<variable> **= <objeto>', se obtiene un resultado equivalente a '<variable> = <variable> ** <objeto>'. \nEjemplo: Si operando_1 = {operando_1} y operando_2 = {operando_2}\"\"\")\noperando_1 **= operando_2\nprint(f\"'operando_1 **= operando_2' da como resultado operando_1 = {operando_1}\")\nprint(\"\"\"Notar que para utilizar un tipo de asignación que incluya una operación aritmetica, esta tiene que estar definida\npara el objeto guardado en la variable y el objeto que se asigna\"\"\")\nprint(\"\"\"Tambien se puede realizar una asignación doble, triple, etc en una sola línea (aunque seguramente no siempre\nsea recomendable de cara a facilitar la lectura). Utilizando la sintaxis que se muestra en el siguiente ejemplo: \nDados dos objetos y dos variables de la siguiente forma: \n'smallest_ramanujan_n, fav_dinosaur = 1729, \"Triceratops\"' de forma que después de la\nasignación la variable smallest_ramanujan_n = 1729 y fav_dinosaur = \"Triceratops\" \"\"\")\nprint()\n\n### Identidad y Pertenencia ###\nprint(\"En Python existe una operación que nos permite saber si dos objetos son el mismo (estan guardados en la misma posición de memoria):\")\nprint(\"Se trata de la operación 'is' y de su contraria 'is not'\")\noperando_1 = [1,2,3]\noperando_2 = [1,2,3]\nprint(f\"Ejemplo: Siendo operando_1 = {operando_1} y operando_2 = {operando_2}, 'operando_1 is operando_2' da como resultado {operando_1 is operando_2}\")\nprint(f\"Ejemplo: Siendo operando_1 = {operando_1} y operando_2 = {operando_2}, 'operando_1 is not operando_2' da como resultado {operando_1 is not operando_2}\")\nprint(f\"\"\"Notar que el hecho de que ambos valores coincidan (que el resultado de la operación == sea True), \nno significa que se trate del mismo objeto\"\"\")\noperando_1 = \"Hello\"\noperando_2 = \"Hello\"\nprint(f\"\"\"También se puede observar que por cuestiones de implementación del lenguaje, \nen el caso de los string que los valores coincidan significa que se trata del mismo objeto en algunos casos. \nEjemplo: Siendo operando_1 = \"{operando_1}\" y operando_2 = \"{operando_2}\", \n'operando_1 is operando_2' da como resultado {operando_1 is operando_2}\"\"\")\noperando_2 = \"He\"\noperando_3 = \"llo\"\nprint(f\"\"\"Esto parece que sucede siempre y cuando el string no sea el resultado de una operación\ny se haya inicializado como tal por ejemplo: 'operador_1 = \"Hello\"' 'operador_2 = \"He\"' y 'operador_3 = \"llo\"'\n'operador_1 is (operador_2 + operador_3)' da como resultado {operando_1 is (operando_2 + operando_3)}\"\"\")\nprint(\"\"\"Existe además los operadores de pertenencia, 'in' y 'not in', que sirven para saber\nsi un objeto pertenece a un iterable (objeto que se puede iterar, ejemplo: lists, tuples, dictionaries, sets, strings) \"\"\")\noperando_1 = \"Girona\"\noperando_2 = [\"Barcelona\", \"LLeida\", \"Girona\", \"Tarragona\"]\nprint(f\"\"\"Ejemplo: Siendo operando_1 = \"{operando_1}\" y operando_2 = {operando_2}, 'operando_1 in operando_2' da como resultado {operando_1 in operando_2}\nEjemplo: Siendo operando_1 = \"{operando_1}\" y operando_2 = {operando_2}, 'operando_1 not in operando_2' da como resultado {operando_1 not in operando_2}\"\"\")\nprint()\n\n### Operaciones con bits ###\n\nprint(\"Hay ciertas operaciones que se realizan bit a bit. Estas se pueden realizar siempre y cuando los operandos sean ambos de tipo int\")\noperando_1 = 4\noperando_2 = 3\n# &\nprint(f\"\"\"Conjunción (and) bit a bit, con el operador &: \nSiendo el operando_1 = {operando_1} y operando_2 = {operando_2}, el resultado\nde 'operando_1 & operando_2' es {operando_1 & operando_2}\"\"\")\n# |\nprint(f\"\"\"Disyunción (or) bit a bit, con el operador |: \nSiendo el operando_1 = {operando_1} y operando_2 = {operando_2}, el resultado\nde 'operando_1 | operando_2' es {operando_1 | operando_2}\"\"\")\n# ~\nprint(f\"\"\"Negación bit a bit, en el operador ~:\nSiendo el operando_1 = {operando_1}, el resultado\nde la operación '~operando_1' es {~operando_1}\"\"\")\n# ^\nprint(f\"\"\"Disyunción exclusiva (xor) bit a bit, con el operador ^: \nSiendo el operando_1 = {operando_1} y operando_2 = {operando_2}, el resultado\nde 'operando_1 ^ operando_2' es {operando_1 ^ operando_2}\"\"\")\n# >>\nprint(f\"\"\"Desplazamiento bit a bit a la derecha, con el operador >>: \nSiendo el operando_1 = {operando_1} y operando_2 = {operando_2}, el resultado\nde 'operando_1 >> operando_2' es {operando_1 >> operando_2}\"\"\")\n# <<\nprint(f\"\"\"Desplazamiento bit a bit a la izquierda, con el operador <<: \nSiendo el operando_1 = {operando_1} y operando_2 = {operando_2}, el resultado\nde 'operando_1 << operando_2' es {operando_1 << operando_2}\"\"\")\nprint()\n\n### Control de flujo: Condicionales ###\nprint(\"Ejemplo de control de flujo: estructura condicional if/elif/else\")\nn = 50\nif(not n % 2): # Si el resultado de evaluar la condición es cierto, se ejecutará el código con una tabulación extra respecto del if se encuentra inmediatamente abajo\n    print(\"El número es par\")\nelif(not n % 3): # Opcional, si la condición es verdadera y las anteriores no lo han sido se imprimirá \"El número es múltiplo de tres\"\n    print(\"El número es múltiplo de tres\")\nelse: # Opcional, si todas las condiciones anteriores son incorrectas se ejecutará el código dentro del scope de else\n    print(\"El número es impar y no es múltiplo de tres\")\n\nprint()\n\n### Control de flujo: Bucles ###\n\nprint(\"Ejemplo de control de flujo: bucle for\")\n# En cada iteración i tomará uno de los objetos del iterable\n# hasta que se hayan recorrido todos los elementos del iterable (range(1, 101))\nfor i in range(1, 101): \n    print(i)\nelse: #Si el bucle se completa sin excepciones o un break se ejecuta el código en el scope del else\n    print(\"Los números se imprimieron sin percances\")\n\nprint(\"Ejemplo de control de flujo: bucle while\")\nimport random\nresultado_lanzamiento = random.randint(1, 6) #Genera un número entero dentro del intervalo de 1 a 6 incluyendo ambos\nwhile(resultado_lanzamiento != 6): #El código se repite hasta que la condición se cumpla\n    print(\"No has sacado un 6\")\n    resultado_lanzamiento = random.randint(1, 6)\nelse: #Si el bucle se completa sin excepciones o un break se ejecuta el código en el scope del else\n    print(\"Has sacado un 6\")\n\nprint()\n\n### Control de excepciones ###\n\nprint(\"Ejemplo 1 de control de excepciones\")\nn = 10\ntry:\n    # Se intenta ejecutar este código y en caso de que se produzca una excepción,\n    # se pasará a ejecutar el código dentro del scope the except\n    if(n != 9):\n        raise ValueError(\"El número tiene que ser igual a 9\") # Se lanza un error del tipo ValueError con el mensaje pasado como argumento\n    print(\"El número es igual a 9\")\nexcept ValueError as e: #Si dentro del código en el scope de try, se ha producido una excepción esta se captura\n    print(e) #Se imprime la excepción capturada\n    #raise ValueError(\"Valor incorrecto!\")\nelse: #Este código se ejecuta si ninguna excepción se produjo (opcional)\n    print(\"No se ha producido ninguna excepción\")\nfinally: #Esta código se ejecuta en cualquier caso incluso si dentro del except se lanza una excepción (opcional)\n    print(\"Se continua ejecutando el código\")\n\nprint()\n\nprint(\"Ejemplo 2 de control de excepciones\")\nn_input = \"7\"\ntry:\n    n_input = n_input + 5\n    print(n_input)\nexcept Exception: #forma más general posible de capturar una excepcion\n    #Pero en este caso no se guarda el valor de la excepción\n    #Lo cúal dificulta saber porque el programa ha fallado\n    print(\"El programa ha fallado\")\n\n### DIFICULTAD EXTRA: EJERCICIO ###\ndef ejercicio_extra():\n    min_n = 11\n    max_n = 55\n    for n in range(min_n, max_n + 1):\n        if( (n % 2 == 0) and (n % 3 != 0) and (n != 16)):\n            print(n)\n\nprint(\"Resultado ejercicio extra: \")\nejercicio_extra()\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/mariovelascodev.py",
    "content": "#Operadores de asignación\nprint(\"Operadores de asignación\")\na = 5\nb = 10\n\nprint(f\"Operador =: a = 5\")\nprint(f\"Operador =: b = 10\")\n\na += b\nprint(f\"Operador +=: a += b = {a}\")\n\na -= b\nprint(f\"Operador -=: a -= b = {a}\")\n\na *= b\nprint(f\"Operador *=: a *= b = {a}\")\n\na /= b\nprint(f\"Operador /=: a /= b = {a}\")\n\na %= b\nprint(f\"Operador %=: a %= b = {a}\")\n\na //= b\nprint(f\"Operador //=: a //= b = {a}\")\n\na **= b\nprint(f\"Operador **=: a **= b = {a}\")\nprint(\"...............................\")\n\n#Operadores aritméticos\na = 18\nb = 2\nprint(\"Operadores aritméticos\")\nprint(f\"Suma: {a} + {b} = {a + b}\")\nprint(f\"Resta: {a} - {b} = {a - b}\")\nprint(f\"Multiplicación: {a} * {b} = {a * b}\")\nprint(f\"División: {a} / {b} = {a / b}\")\nprint(f\"Modulo: {a} % {b} = {a % b}\")\nprint(f\"Exponente: {a} ** {b} = {a ** b}\")\nprint(f\"Cociente: {a} // {b} = {a // b}\")\nprint(\"...............................\")\n\n#Operadores lógicos\nprint(\"Operadores lógicos\")\nprint(f\"and: True and True = {True and True}\")\nprint(f\"or: True or False = {True or False}\")\nprint(f\"not: not True = {not True}\")\nprint(\"...............................\")\n\n#Operadores de comparación\nprint(\"Operadores de comparación\")\nprint(f\"Mayor: {a} > {b} = {a > b}\")\nprint(f\"Mayor o igual: {a} >= {b} = {a >= b}\")\nprint(f\"Menor: {a} < {b} = {a < b}\")\nprint(f\"Menor o igual: {a} <= {b} = {a <= b}\")\nprint(f\"Igual: {a} == {b} = {a == b}\")\nprint(f\"Distinto: {a} != {b} = {a != b}\")\nprint(\"...............................\")\n\n#Operadores de identidad\nprint(\"Operadores de identidad\")\nprint(f\"is: {a} is {b} = {a is b}\")\nprint(f\"is not: {a} is not {b} = {a is not b}\")\nprint(\"...............................\")\n\n#Operadores de pertenencia\nprint(\"Operadores de pertenencia\")\nprint(f\"in: {a} in [1, 2, 3] = {a in [1, 2, 3]}\")\nprint(f\"not in: {a} not in [1, 2, 3] = {a not in [1, 2, 3]}\")\nprint(\"...............................\")\n\n#Operadores de bit\nprint(\"Operadores de bit\")\nbit_1 = 0b1101\nbit_2 = 0b1011\n\nprint(f\"&: {bin(bit_1)} & {bin(bit_2)} = {bin(bit_1 & bit_2)}\")\nprint(f\"|: {bin(bit_1)} | {bin(bit_2)} = {bin(bit_1 | bit_2)}\")\nprint(f\"~: ~{bin(bit_1)} = {bin(~bit_1)}\")\nprint(f\"^: {bin(bit_1)} ^ {bin(bit_2)} = {bin(bit_1 ^ bit_2)}\")\nprint(f\">>: {bin(bit_1)}>>2 = {bin(bit_1>>2)}\")\nprint(f\"<<: {bin(bit_1)}<<2 = {bin(bit_1<<2)}\")\nprint(\"...............................\")\n\n#Estructuras de control\nprint(\"Estructuras de control\")\n\nprint(\"Condicional if\")\nif a < b:\n    print(f\"{a} es menor que {b}\")\nelif a > b:\n    print(f\"{a} es mayor que {b}\")\nelse:\n    print(f\"{a} es igual que {b}\")\nprint(\"...............................\")\n\nprint(\"Bucle for\")\nfor i in \"Python\":\n    print(i)\nprint(\"...........Recorrer un rango................\")\nfor i in range(11):\n    print(i)\nprint(\"...............................\")\n\nprint(\"Bucle while\")\nnum = 5\nwhile num > 0:\n    print(num)\n    num -= 1\nprint(\"...............................\")\n\n#Excepciones\nprint(\"Excepciones\")\nnum1 = 5\nnum2 = 0\n\ntry:\n    num3 = num1 / num2\nexcept Exception:\n    print(\"Ha habido una excepción\")\n\nprint(\"...............................\")\n\n#EXTRA\nprint(\"DIFICULTAD EXTRA\")\nfor i in range(10,56):\n    if i % 2 == 0 and i % 3 != 0:\n        if i == 16:\n            continue\n        print(i)\n        if i == 52:\n            i += 3\n            print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/maxiRica.py",
    "content": "\"\"\"\nVamos a crear operadores aritméticos en python\n\"\"\"\n\nsuma=2+3\nresta=6-3\ndivision=10/2\nmodulo=10%3\ndiv_entera=10//3\nexponencial=2**3\n\n\nprint(suma)\nprint(resta)\nprint(division)\nprint(modulo)\nprint(div_entera)\nprint(exponencial)\n\n\"\"\"\noperadores de asignación\n\"\"\"\nprint(\" \")\nsuma += 1\nprint(f\"le sumo 1 = {suma}\")\nresta -=1\nprint(f\"le resto 2 = {resta}\")\ndivision /= 2\nprint(f\"divido por 2 = {division}\")\nmodulo %= 2\nprint(f\"divido por 2 y le asigno el resto = {modulo}\")\ndiv_entera //= 2\nprint(f\"realizo división entera por 2 y la asigno = {div_entera}\")\nexponencial **= 2\nprint(f\"realizo exponencial por 2 y la asigna = {exponencial}\")\n\n\"\"\"\noperadores de comparación\n\"\"\"\nprint(\" \")\nigual = 1 == 2\nprint(f\"1 es igual a 2? Eso es {igual}\")\ndesigual = 1!=2\nprint(\"1 es desigual a 2? eso es {desigual}\")\nsuperior = 2>1\nprint(f\"2 es superior a 1? eso es {superior}\")\ninferior = 1<2\nprint(f\"1 es inferior a 2? eso es {inferior}\")\nsup_igual= 2 >= 3\nprint(f\"2 es superior o igual a 3? Eso es {sup_igual}\")\ninf_igual=2<3\nprint(f\"2 es inferior o igual a 3? Eso es {inf_igual}\")\n\n\"\"\"\noperadores lógicos que se usan habitualmente en las estructuras de control\n\"\"\"\nprint(\" \")\nprimero = True\nsegundo = True\nif (primero and segundo): # operador AND. Se usa para concatenar dos valores iguales para operar\n    print(\"cierto\")\n\nif (primero or segundo):\n    print(\"cierto también\") # operador OR. Se usa para operar si uno u otro es cierto.\n\ncontrario = False\nif not contrario:\n    print(\"es cierto si es falsa la variable\") # operador NOT. Se usa para generar el valor contrario de la variable booleana\n\n\"\"\"\nEstructuras de control\nif\nelif\nelse\n\"\"\"\nprint(\" \")\ncontrol = True  # usamos solo if\nif (control):\n    print(\"control es cierto\")\n\nprint(\" \")\ncontrol = False # usamos elif si la funcion if no concuerda su condición\nif (control):\n    print(\"control es cierto\")\nelif control == False:\n    print(\"control es falso\")\n\nprint(\" \")\ncontrol = False # usamos else cuando ni if ni elif actuan\na = 0\nif (control):\n    print(\"control es cierto\")\nelif control == False and a == 1:\n    print(\"control es falso\")\nelse:\n    print(\"nada es correcto\")\n\n\"\"\"\nfunciones de iteración \nwhile\nfor\n\"\"\"\nprint(\" \")\nwhile a<=5: # while realiza la iteración mientras se da la condición\n    print(f\"bucle while {a}\")\n    a+=1\n\nprint(\" \")\nfor a in range(5): # for realiza una iteración que estableces en la función range() o en los valores de una tupla, lista, cadena\n    print(f\"bucle for {a}\")\n\n\"\"\"\nEJERCICIO\n\"\"\"\nprint(\" \")\nfor i in range(10,56,2):\n    if (i==16) or i%3 == 0:\n        continue\n    \n    print(f\"iteración {i} no es 16 ni múltiplo de 3\")\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/mendozalz.py",
    "content": "'''\n# Ejercicios de Programación\n\n## Operadores\n\n- [X] Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n  - Aritméticos\n  - Lógicos\n  - De comparación\n  - Asignación\n  - Identidad\n  - Pertenencia\n  - Bits\n\n## Estructuras de Control\n\n- [X] Utilizando las operaciones con operadores que tú quieras, crea ejemplos que representen todos los tipos de estructuras de control que existan en tu lenguaje:\n  - Condicionales\n  - Iterativas\n  - Excepciones\n- [X] Debes hacer print por consola del resultado de todos los ejemplos.\n\n## Dificultad Extra (Opcional)\n\n- [X] Crea un programa que imprima por consola todos los números comprendidos entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\n- [X] Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n'''\n\n\n##Operadores Aritméticos:\n\n# Suma (+)\na = 15\nb = 44 \nprint(f\"Suma= {a+b}\")\n\n# Resta (-)\nprint(f\"Resta= {a-b}\")\n\n# Multiplicación (*)\nprint(f\"Multiplicación= {a*b}\")\n\n# División (/)\nprint(f\"División= {b/a}\")\n\n# Módulo (%)\nprint(f\"Mudulo= {b%a}\")\n\n# Potencia (**)\nprint(f\"Potencia= {a**b}\")\n\n# División entera (//)\nprint(f\"División entera= {b//a}\")\n\n\n#Operadores de Comparación:\n\n# Igual (==)\nprint(f\"Comparación= {a==b}\")\n\n# No igual (!=)\nprint(f\"Desigualdad {a!=b}\")\n\n# Mayor que (>)\nprint(f\"Mayor que= {a>b}\")\n\n# Menor que (<)\nprint(f\"Menor que= {a<b}\")\n\n# Mayor o igual que (>=)\nprint(f\"Mayor igual= {a>=b}\")\n\n# Menor o igual que (<=)\nprint(f\"Menor igual= {a<=b}\")\n\n\n#Operadores Lógicos:\n\n# AND (and)\nprint(f\"AND= {True and True}\")\n\n# OR (or)\nprint(f\"OR= {True or False}\")\n\n# NOT (not)\nprint(f\"NOT= {not True}\")\n\n\n# Operadores de Asignación:\n\n#Asignación (=)\nc=44\nprint(f\"Asignación= {c}\")\n\n# Suma y asignación (+=)\nc+=1\nprint(f\"Suma y asignación= {c}\")\n\n# Resta y asignación (-=)\nc-=3\nprint(f\"Resta y asignación= {c}\")\n\n# Multiplicación y asignación (*=)\nc*=2\nprint(f\"Multiplicación y asignación= {c}\")\n\n# División y asignación (/=)\nc/=2\nprint(f\"División y asignación= {c}\")\n\n# Módulo y asignación (%=)\nc%=2\nprint(f\"Modulo y asignación= {c}\")\n\n\n#Operadores de Identidad:\n\n# is\nprint(f\"IS= {a is b}\")\n\n# is not\nprint(f\"IS NOT= {a is not b}\")\n\n\n# Operadores de Pertenencia:\nnick = \"Mendozalz\"\n\n# in\nprint(f\"La M esta incluida en Mendozalz= {'M' in nick}\")\n\n# not in\nprint(f\"La X esta incluida en Mendozalz= {'M' not in nick}\")\n\n\n# Operadores de Bits:\n\n# AND a nivel de bits (&)\nprint(f\"Bit AND= {a&b}\")\n\n# OR a nivel de bits (|)\nprint(f\"Bit OR= {a|b}\")\n\n# XOR a nivel de bits (^)\nprint(f\"Bit XOR= {a^b}\")\n\n# Complemento a nivel de bits (~)\nprint(f\"Complemento a nivel de bit= {~b}\")\n\n# Desplazamiento a la izquierda (<<)\nprint(f\"Desplazamiento a la izquierda= {a<<b}\")\n\n# Desplazamiento a la derecha (>>)\nprint(f\"Desplazamiento a la derecha= {a>>b}\")\n\n## Estructuras de Control\n\n# Condicionales\n\nusuario = input(\"Por favor indica tu edad \")\nedad = int(usuario)\nif(edad<18):\n    print(\"Eres menor de edad\")\nelse:{\n    print(\"Eres mayor de edad\")\n}\n# Iterativas\n\nfor i in range(11):\n    print(i)\n\n# Excepciones\n\ndef div(a,b):\n    try:\n        result= a/b\n    except:\n        print(\"No se puede dividir por cero\")\n    finally:\n        print(\"El programa a finalizado\")\n\ndiv(7, 0)\n\n# Crea un programa que imprima por consola todos los números comprendidos entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\nfor i in range(10, 56):\n    if i % 2 == 0 and i != 16 and 1 % 3 != 0:\n        print(f\"Imprimiendo entre 10 y 55 {i}\")\n    "
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/mensius87.py",
    "content": "\"\"\" #01 OPERADORES Y ESTRUCTURAS DE CONTROL\n Dificultad: Fácil | Publicación: 02/01/24 | Corrección: 08/01/24\n\nEjercicio\n\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n    Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n    (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n    que representen todos los tipos de estructuras de control que existan\n    en tu lenguaje:\n    Condicionales, iterativas, excepciones...\n\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n  entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\"\"\"\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/mhayhem.py",
    "content": "# - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n#   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n#   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n\nprint(\"Operadores Aritméticos:\")\nprint(f\"suma: 5 + 6 = {5 + 6}\")\nprint(f\"resta: 10 - 4 = {10 - 4}\")\nprint(f\"multiplicacion: 3 x 20 = {3 * 20}\")\nprint(f\"división: 245 / 3 = {245 / 3}\")\nprint(f\"división entera: 245 // 3 = {245 // 3}\")\nprint(f\"módulo (resto): 34 % 3 = {34 % 3}\")\nprint(f\"exponente: 2 ** 3 = {2 ** 3}\")\nprint(\"\\nOperadores de Comparación: (retornán un booleano)\")\nprint(f\"igualdqad: 5 == 5 = {5 == 5}\")\nprint(f\"diferencia: 6 != 4 = {6 != 4}\")\nprint(f\"mayor que: 3 < 10 = {3 < 10} también puede ser mayor o igual que: 3 <= 10 = {3 <= 10}\")\nprint(f\"menor que: 20 > 2 = {20 > 2} también puede ser menor o igual que: 20 >= 2 = {20 >= 2}\")\nprint(\"\\nOperadores Lógicos: (retornán un booleano)\")\nprint(f\"operador AND: verdadadero y falso =  {True and False}\")\nprint(f\"operador OR: verdadero o falso = {True or False}\")\nprint(f\"operador NOT: negación de verdadero = {not True}\")\nprint(\"\\nOperadores de Asignación:\")\nx = 5\nprint(f\"operador de asignacion: x = 5, donde x es una variable que almacena el valor {x}\")\nx += 3\nprint(f\"operador de asignacion mas suma: x += 3, x ahora es {x}\")\nx -= 2\nprint(f\"operador de asignacion mas suma: x -= 2, x ahora es {x}\")\nx *= 5\nprint(f\"operador de asignacion mas suma: x *= 5, x ahora es {x}\")\nx /= 2\nprint(f\"operador de asignacion mas suma: x /= 2, x ahora es {x}\")\nx //= 3\nprint(f\"operador de asignacion mas suma: x //= 3, x ahora es {x}\")\nx %= 4\nprint(f\"operador de asignacion mas suma: x %= 4, x ahora es {x}\")\nx **= 2\nprint(f\"operador de asignacion mas suma: x **= 2, x ahora es {x}\")\nprint(\"\\nOperadores de Identidad: (retornán un booleano)\")\nx = \"python\"\nprint(f\"operador is: x is 'python' = {x is 'python'}\")\nprint(f\"operador is not: x is not 'java' = {x is not 'java'}\")\nprint(\"\\nOperadores de Pertenencia: (retornán un booleano)\")\nlista = [1, 2, 3, 4, 5]\nprint(f\"operador in: 3 in lista = {3 in lista}\")\nprint(f\"operador not in: 6 not in lista = {6 not in lista}\")\nprint(\"\\nOperadores Bit a Bit:\")\nprint(f\"AND bit a bit: 5 & 3 = {5 & 3}\")\nprint(f\"OR bit a bit: 5 | 3 = {5 | 3}\")\nprint(f\"XOR bit a bit: 5 ^ 3 = {5 ^ 3}\")\nprint(f\"NOT bit a bit: ~5 = {~5}\") # NOT invierte todos los bits y no lo puse en ele pull request\nprint(f\"Desplazamiento a la izquierda: 5 << 1 = {5 << 1}\")\nprint(f\"Desplazamiento a la derecha: 5 >> 1 = {5 >> 1}\")\n\n# - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n#   que representen todos los tipos de estructuras de control que existan\n#   en tu lenguaje:\n#   Condicionales, iterativas, excepciones...\nprint(\"\\nEstructuras de Control Condicionales:\")\n\"\"\"condicionalonales 'if' y 'else': con ellos podemos ejecutar un bloque de código si se cumple una condición. Además, podemos añadirle otro condicional 'elif'\npara evaluar múltiples condiciones.\"\"\"\n\nx = 17\nif x > 10:\n    print(\"es mayor\")\nelif x > 10 and x < 20:\n    print(\"es mayor que 10 pero menor a 20\")\nelse:\n    print(\"es menor\")\nprint(\"\\nEstructuras de Control Iterativas:\")\n\n\"\"\"con las estructuras de control iterativas podemos ejecutar un bloque de código varias veces, ya sea un número determinado de veces o mientras se cumpla una condición.\nCon un bucle 'for' podemos iterar sobre una lista de números e imprimir cada uno de ellos.\"\"\"\n\nfor n in range(6):\n    print(n)\n\"\"\"Con un bucle 'while' podemos seguir ejecutando un bloque de código mientras una condición sea verdadera.\"\"\"\nwhile x < 5:\n    print(x)\n    x += 1  \nprint(\"\\nEstructuras de Control de Excepciones:\")\n\"\"\"con la estructura de control de excepciones 'try-except' podemos manejar errores que podrían ocurrir en nuestro programa, también podemos usar 'finally'\npara ejecutar un bloque de código al final, independientemente de si se produjo un error o no.\"\"\"\nx = None\ntry:\n    print(x + 5)\nexcept TypeError:\n    print(\"Error: No se puede sumar None a un número.\")\nfinally:\n    print(\"Este bloque se ejecuta siempre, haya o no un error.\")\n# - Debes hacer print por consola del resultado de todos los ejemplos.\n#\n# DIFICULTAD EXTRA (opcional):\n# Crea un programa que imprima por consola todos los números comprendidos\n# entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\nprint(\"\\nDIFICULTAD EXTRA:\")\nfor n in range(10, 56):\n    if n % 2 == 0 and n != 16 and n % 3 != 0:\n        print(n)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/mick2332-q.py",
    "content": "a = 2\nb = 2\n\n#Operadores Aritméticos\nsuma = a + b\nresta = a - b\nmultiplicacion = a * b\ndivision = a / b\ndivision_entera = a // b\nmodulo= a % b\npotencia = a ** b\n\nprint(\"Operadores aritmeticos:\",\"\\n Suma:\", suma, \"\\n Resta:\", resta, \"\\n Multiplicación:\", multiplicacion, \"\\n División:\", division , \"\\n División entera:\", division_entera, \"\\n Módulo:\", modulo, \"\\n Potencia:\", potencia)\n\n#Operadores logicos\nop_and = (a > 1) and (b > 1)\nop_or = (a > 1) or (b < 1)\nop_not = not(a > 1)\n\nprint(\"\\nOperadores lógicos:\",\"\\n AND:\", op_and, \"\\n OR:\", op_or, \"\\n NOT:\", op_not)\n\n#Operadores de comparación\nigualdad = (a == b)\ndiferencia = (a != b)\nmayor_que = (a > b)\nmenor_que = (a < b)\nmayor_o_igual = (a >= b)\nmenor_o_igual = (a <= b)\n\nprint(\"\\nOperadores de comparación:\",\"\\n Igualdad:\", igualdad, \"\\n Diferencia:\", diferencia, \"\\n Mayor que:\", mayor_que, \"\\n Menor que:\", menor_que, \"\\n Mayor o igual:\", mayor_o_igual, \"\\n Menor o igual:\", menor_o_igual)\n\n#Operadores de asignación\nx = 5\nope_asig= ['+=', '-=', '*=', '/=', '//=', '%=', '**=']\n\nfor i in ope_asig:\n    print(f\"\\nvalor anterior de x: {x}\")\n    exec(f\"x {i} 2\")\n    print(f\"Operacion realizada x{i}2: x = {x}\")\n\n#Operadores de identidad\ny = x\nop_is = (x is y)\nop_is_not = (x is not b)\nprint(\"\\nOperadores de identidad:\",\"\\n is:\", op_is, \"\\n is not:\", op_is_not)\n\n#Operadores de pertenencia\nlista = [1, 2, 3, 4, 5]\nop_in = (3 in lista)\nop_not_in = (6 not in lista)\nprint(\"\\nOperadores de pertenencia:\",\"\\n in:\", op_in, \"\\n not in:\", op_not_in)\n\n#Operadores a nivel de bits\nand_bit = a & b \nor_bit = a | b \nxor_bit = a ^ b\nnot_bit = ~a\nleft_shift = a << 1\nright_shift = a >> 1\nprint(\"\\nOperadores a nivel de bits:\",\"\\n AND:\", and_bit, \"\\n OR:\", or_bit, \"\\n XOR:\", xor_bit, \"\\n NOT:\", not_bit, \"\\n Left Shift:\", left_shift, \"\\n Right Shift:\", right_shift)\n\n\nlista=[]\nprint(lista)\n\nfor i in range(10,55):\n    if i % 2==0 and  i %3!=0 and i !=16:\n        lista.append(i)\n    \nprint(\"Lista de números entre 10 y 54 que son pares y no múltiplos de 3:\", lista)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/miguelex.py",
    "content": "# Ejemplos de operadores aritmeticos en python\n\nprint(\"Vamos a mostrar ejemplos de los operadores aritmeticos\")\nprint(f\"La solución de 2 + 3 es igual a {2 + 3}\")\nprint(f\"La solución de 2 - 3 es igual a {2 - 3}\")\nprint(f\"La solución de 5 * 3 es igual a {5 * 3}\")\nprint(f\"La solución de 5 / 3 es igual a {5 / 3} (Esta es la división normal)\")\nprint(f\"La solución de 5 % 3 es igual a {5 % 3}\")\nprint(f\"La solución de 5 ** 3 es igual a {5 ** 3}\")\nprint(f\"La solución de 5 // 3 es igual a { 5// 3} (Esta es la división entera)\")\nprint(\"\\n\")\n\n# Ejemplos de operadores logicos\nprint(\"Vamos a mostrar ejemplos de los operadores logicos\")\nprint(f\"¿Verdad && Verdad? {True and True} (Ejemplo de AND)\")\nprint(f\"¿Verdad || Falso? {True or True} (Ejemplo de OR)\")\nprint(f\"¿not Verdad? {not True} (Ejemplo de NOT)\")\nprint(\"\\n\")\n\n# Ejemplos de operadores de comparación \nprint(\"Vamos a mostrar ejemplos de los operadores de comparación\")\nprint(f\"¿5 == 3? {5 == 3} (Ejemplo de igualdad)\")\nprint(f\"¿5 != 3? {5 != 3} (Ejemplo de desigualdad)\")\nprint(f\"¿5 < 3? {5 < 3} (Ejemplo de Menor que )\")\nprint(f\"¿5 <= 3? {5 <= 3} (Ejemplo de Menor o Igual que)\")\nprint(f\"¿5 > 3? {5 > 3} (Ejemplo de Mayor)\")\nprint(f\"¿5 >= 3? {5 >= 3} (Ejemplo de Mayor o Igual que)\")\nprint(\"\\n\")\n\n# Ejemplos de oepradores de asignación\nprint(\"Vamos a mostrar ejemplos de los operadores de asignación\")\nnumero = 1\nprint(f\"El valor de numero es {numero}\")\nnumero += 1\nprint(f\"El valor de numero += 1 es {numero}\")\nnumero -= 1\nprint(f\"El valor de numero -= 1 es {numero}\")\nnumero *= 5\nprint(f\"El valor de numero *= 5 es {numero}\")\nnumero /= 2\nprint(f\"El valor de numero /= 2 es {numero}\")\nnumero %= 2\nprint(f\"El valor de numero %= 2 es {numero}\")\nnumero **= 2\nprint(f\"El valor de numero **= 2 es {numero}\")\nnumero //= 2\nprint(f\"El valor de numero //= 2 es {numero}\")\nprint(\"\\n\")\n\n# Ejemplos operadores de bit\nprint(\"Vamos a mostrar ejemplos de los operadores de bit\")\na = 10\nb = 15\nprint(f\"El valor de a & b es {a & b} (Operacion AND)\")\nprint(f\"El valor de a | b es {a | b} (Operación OR)\")\nprint(f\"El valor de a ^ b es {a ^ b} (Operación XOR)\")\nprint(f\"El valor de ~a es {~a} (Operación NOt)\")\nprint(f\"El valor de a >> b es {a >> b}\")\nprint(f\"El valor de a << b es {a << b}\")\nprint(\"\\n\")\n\n# Estructuras de control\n\n# Ejemplos de if\nprint(\"Vamos a mostrar ejemplos de if\")\nif 5 > 3:\n    print(\"5 es mayor que 3\")\nprint(\"\\n\")\n\n# Ejemplos de if else\nprint(\"Vamos a mostrar ejemplos de if else\")\nif 5 < 3:\n    print(\"5 es menor que 3\")\nelse:\n    print(\"5 no es menor que 3\")\nprint(\"\\n\")\n\n# Ejemplos de if elif else\nprint(\"Vamos a mostrar ejemplos de if elif else\")\nif 5 < 3:\n    print(\"5 es menor que 3\")\nelif 5 == 3:\n    print(\"5 es igual que 3\")\nelse:\n    print(\"5 es mayor que 3\")\nprint(\"\\n\")\n\n# Ejemplo de match\nprint(\"Vamos a mostrar ejemplos de match\")\nnumero = 5\nmatch numero:\n    case 1:\n        print(\"El numero es 1\")\n    case 2:\n        print(\"El numero es 2\")\n    case 3:\n        print(\"El numero es 3\")\n    case 4:\n        print(\"El numero es 4\")\n    case 5:\n        print(\"El numero es 5\")\n    case 6:\n        print(\"El numero es 6\")\n    case 7:\n        print(\"El numero es 7\")\n    case 8:\n        print(\"El numero es 8\")\n    case 9:\n        print(\"El numero es 9\")\n    case 10:\n        print(\"El numero es 10\")\n    case _:\n        print(\"El numero es mayor que 10\")\nprint(\"\\n\")\n\n# Ejemplo de while\nprint(\"Vamos a mostrar ejemplos de while\")\nnumero = 1\nwhile numero <= 10:\n    print(numero)\n    numero += 1\nprint(\"\\n\")\n\n# Ejemplo de do .. while\nprint(\"Vamos a mostrar ejemplos de do .. while\")\nnumero = 1\nwhile True:\n    print(numero)\n    numero += 1\n    if numero > 10:\n        break\nprint(\"\\n\")\n\n# Ejemplo de for\nprint(\"Vamos a mostrar ejemplos de for\")\nfor numero in range(1, 11):\n    print(numero)\nprint(\"\\n\")\n\n# Ejemplo Range\nprint(\"Vamos a mostrar ejemplos de range\")\nfor numero in range(1, 5):\n    print(numero)\nprint(\"\\n\")\n\nprint(\"Vamos a mostrar ejemplos de range con saltos\")\nfor numero in range(1, 20, 2):\n    print(numero)\nprint(\"\\n\")\n\n# Ejemplo de for else\nprint(\"Vamos a mostrar ejemplos de for else\")\nfor numero in range(1, 11):\n    print(numero)\nelse:\n    print(\"El for ha terminado\")\nprint(\"\\n\")\n\n# Ejemplo de break\nprint(\"Vamos a mostrar ejemplos de break\")\nfor numero in range(1, 11):\n    print(numero)\n    if numero == 5:\n        break\nprint(\"\\n\")\n\n# Ejemplo de continue\nprint(\"Vamos a mostrar ejemplos de continue\")\nfor numero in range(1, 11):\n    if numero == 5:\n        continue\n    print(numero)\nprint(\"\\n\")\n\n# Ejemplo de pass\nprint(\"Vamos a mostrar ejemplos de pass\")\nfor numero in range(1, 11):\n    if numero == 5:\n        pass\n    print(numero)\nprint(\"\\n\")\n\n# Ejemplo de for in\nprint(\"Vamos a mostrar ejemplos de for in\")\nlista = [1, 2, 3, 4, 5]\nfor numero in lista:\n    print(numero)\nprint(\"\\n\")\n\n# Ejemplo de excepciones\nprint(\"Vamos a mostrar ejemplos de excepciones\")\ntry:\n    print(5 / 0)\nexcept:\n    print(\"Ha ocurrido un error\")\nfinally:\n    print(\"Ha finalizado el manejo de excepciones\")\nprint(\"\\n\")\n\n# Ejemplo de raise\nprint(\"Vamos a mostrar ejemplos de raise\")\ntry:\n    raise Exception(\"Ha ocurrido un error\")\nexcept Exception as error:\n    print(error)\nprint(\"\\n\")\n\n# Ejemplo de assert\nprint(\"Vamos a mostrar ejemplos de assert\")\ntry:\n    assert 5 > 3, \"5 no es mayor que 3\"\nexcept AssertionError as error:\n    print(error)\nprint(\"\\n\")\n\n# Ejercicio extra\n\nprint(\"Vamos a mostrar ejemplos de ejercicio extra\")\n\nfor number in range(10, 56):\n    if number % 2 == 0 and number != 16 and number % 3 != 0:\n        print(number)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/mikelm2020.py",
    "content": "# Operadores Aritméticos\ndef suma(a, b):\n    return a + b\n\n\ndef sustraction(a, b):\n    return a - b\n\n\ndef multiplication(a, b):\n    return a * b\n\n\ndef division(a, b):\n    if b != 0:\n        return a / b\n    else:\n        print(\"Operador inválido\")\n\n\ndef int_division(a, b):\n    if b != 0:\n        return a // b\n    else:\n        print(\"Operador inválido\")\n\n\ndef resiudue(a, b):\n    if b != 0:\n        return a % b\n    else:\n        print(\"Operador inválido\")\n\n\ndef power(a, b):\n    return a**b\n\n\n# Operadores lógicos y de comparación\ndef greather_than(a, b, c):\n    if a > b and a > c:\n        return a\n    elif a < c and b < c:\n        return c\n    else:\n        return b\n\n\n# Operadores de asignación e identidad\ndef identity():\n    a = 100\n    b = 100\n\n    print(f\"Dados las asignaciones a = 100 y b = 100 , a pertenece a b es: {a is b}\")\n    return None\n\n\ndef identity_negative():\n    a = [1, 2, 3, 4, 5]\n    b = [1, 2, 3, 4, 5]\n\n    print(f\" Dada las lista a {a}\")\n    print(f\"Y la lista b {b}\")\n    print(f\" a no pertenece a b es: {a is not b}\")\n    return None\n\n\n# Operadores de pertenencia\ndef belonging():\n    s = set([1, 2, 3, 4, 5])\n    print(f\"Dado el conjunto s {s}\")\n    print(f\"{3} pertenece a s: {3 in s}\")\n    print(f\"{8} pertenece a s: {8 in s}\")\n    print(f\"{8} no pertenece a s: {8 not in s}\")\n    return None\n\n\n# Operadores de bit\ndef bit_operators(a, b):\n    binary_a = bin(a)\n    binary_b = bin(b)\n    print(f\"Operador 1 El número {a} convertido a binario es: {binary_a}\")\n    print(f\"Operador 2 El número {b} convertido a binario es: {binary_b}\")\n    print(\"Las operaciones serían:\")\n\n    print(f\"El operador And (&) aplicado a {a} y {b} es: {bin(a & b)}\")\n    print(f\"El operador Or (|) aplicado a {a} y {b} es: {bin(a | b)}\")\n    print(f\"El operador Not (~) aplicado a {a} y {b} es: {bin(~a)} y {bin(~b)}\")\n    print(f\"El operador Xor (^) aplicado a {a} y {b} es: {bin(a ^ b)}\")\n    print(\n        f\"El operador desplazamiento a la derecha (>>) aplicado a {a} 2 unidades y {b} 4 unidades es: {bin(a>>2)} y {bin(b>>4)}\"\n    )\n    print(\n        f\"El operador desplazamiento a la iquierda (<<) aplicado a {a} 2 unidades y {b} 4 unidades es: {bin(a<<2)} y {bin(b<<4)}\"\n    )\n    return None\n\n\n# Estructuras de control\ndef control_structures():\n    # Ciclo while\n    # Se detiene hasta que el número se haya incrementado en 5 unidades\n\n    print(\"Ejemplo con ciclo while inicia en 1 y se detiene en 5\")\n    number = 1\n    while number <= 5:\n        print(f\"El número es: {number}\")\n        number += 1\n\n    # Ciclo for\n    # Se imprimen los primeros 10 números enteros a partir del 1\n\n    print(\"Ejemplo de ciclo for se imprimen los primeros 10 números empezando en 1\")\n    for number in range(1, 11):\n        print(f\"El número es: {number}\")\n\n    return None\n\n\n# EXTRA\ndef extra():\n    print(\n        \"\"\"Programa que imprime por consola todos los números comprendidos\n entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\"\"\"\n    )\n    for number in range(10, 55, 2):\n        if number != 16 and number % 3 != 0:\n            print(f\"El número es: {number}\")\n    return None\n\n\nif __name__ == \"__main__\":\n    # Lee los 3 números\n    number_1, number_2, number_3 = map(\n        int, input(\"Dame 3 números:\").rstrip().split(\" \")\n    )\n\n    print(f\"La suma de {number_1} y {number_2} es: {suma(number_1, number_2)}\")\n    print(f\"La resta de {number_1} y {number_2} es: {sustraction(number_1, number_2)}\")\n    print(\n        f\"La multiplicación de {number_1} y {number_2} es: {multiplication(number_1, number_2)}\"\n    )\n    print(f\"La división de {number_1} y {number_2} es: {division(number_1, number_2)}\")\n    print(\n        f\"La división entera de {number_1} y {number_2} es: {int_division(number_1, number_2)}\"\n    )\n    print(f\"El residuo de {number_1} y {number_2} es: {resiudue(number_1, number_2)}\")\n    print(\n        f\"La potencia de {number_1} elavado a {number_2} es: {power(number_1, number_2)}\"\n    )\n    print(\n        f\"El número mayor entre {number_1} , {number_2} y {number_3} es: {greather_than(number_1, number_2, number_3)}\"\n    )\n    print(\"Un ejemplo de identidad\")\n    identity()\n    print(\"Un ejemplo de identidad negativa\")\n    identity_negative()\n    print(\"Un ejemplo de pertenencia\")\n    belonging()\n    print(\n        f\"Un ejemplo de operadores con bits convirtiendo a binarios el número {number_1} y {number_2}\"\n    )\n    bit_operators(number_1, number_2)\n    print(\"Un ejemplo de estructuras de control\")\n    control_structures()\n    print(\"El resultado del ejercio extra\")\n    extra()\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/minn09.py",
    "content": "# Operadores aritmeticos\na = 10\nb = 5\nsuma = a + b\nresta = a - b\nmultiplicacion = a * b\npotencia = a ** b\ndivision = a / b\ndivision_entera = a // b\nmodulo = a % b\nprint(\"*-*-*-Operadores aritmeticos-*-*-*\")\nprint(f\"Suma de {a} y {b} = {suma}\")\nprint(f\"Resta de {a} y {b} = {resta}\")\nprint(f\"Multiplicacion de {a} y {b} = {multiplicacion}\")\nprint(f\"Potencia de {a} y {b} = {potencia}\")\nprint(f\"Division de {a} y {b} = {division}\")\nprint(f\"Division entera de {a} y {b} = {division_entera}\")\nprint(f\"Modulo de {a} y {b} = {modulo}\")\nprint(\"*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\\n\")\n\n# Operadores logicos\nx = 15\ny = 0\ncaso1 = x or y\ncaso2 = x and y\ncaso3 = not x\ncaso4 = not y\nprint(\"*-*-*-Operadores Logicos-*-*-*\")\nprint(f\"{x} or {y} = {caso1}\")\nprint(f\"{x} and {y} = {caso2}\")\nprint(f\"not {x} = {caso3}\")\nprint(f\"not {y} = {caso4}\")\nprint(\"*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\\n\")\n\n# Operadores de comparacion\nigualdad = a == b\ndiferente = a != b\na_mayor_que_b = a > b\na_menor_que_b = a < b\na_menor_igual_que_b = a <= b\na_mayor_igual_que_b = a >= b\nprint(\"*-*-*-Operadores de comparacion-*-*-*\")\nprint(f\"{a} es igual a {b} : {igualdad}\")\nprint(f\"{a} es diferente a {b} : {diferente}\")\nprint(f\"{a} es igual a {b} : {a_mayor_que_b}\")\nprint(f\"{a} es igual a {b} : {a_menor_que_b}\")\nprint(f\"{a} es igual a {b} : {a_mayor_igual_que_b}\")\nprint(f\"{a} es igual a {b} : {a_menor_igual_que_b}\\n\")\nprint(\"*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\\n\")\n# Operadores de identidad\nz = 4\nk = 2\nlista_identidad = [2, 4]\noperador_is = z is lista_identidad\noperador_is1 = z is k\nprint(\"*-*-*-Operadores de identidad-*-*-*\")\nprint(f\"z esta en la lista_identidad : {operador_is}\")\nprint(f\"z esta en k : {operador_is1}\\n\")\nprint(\"*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\\n\")\n\n# Operadores de pertenencia\nlista_pertenencia = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\nin_lista = 4 in lista_pertenencia\nnot_in_lista = 4 not in lista_pertenencia\nprint(\"*-*-*-Operadores de pertenencia-*-*-*\")\nprint(f\"4 esta en la lista_pertenencia: {in_lista}\")\nprint(f\"4 no esta en la lista_pertenencia: {not_in_lista}\\n\")\nprint(\"*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\\n\")\n\n# Operadores de bits\nb = 1\nn = 0\n# Esta informacion la obtuve de la pagina web: https://j2logo.com/python/tutorial/operadores-en-python/\nprint(\"*-*-*-Operadores de bits-*-*-*\")\nprint(\"Operacion OR a nivel de bits: \", b | n)\nprint(\"Operación XOR a nivel de bits: \", b ^ n)\nprint(\"Operación AND a nivel de bits: \", b & n)\nprint(\"Se desplaza n bits a la izquierda: \", b << 1)\nprint(\"Se desplaza n bits a la derecha: \", b >> 1)\nprint(\"Obtiene los bits invertidos: \", ~b)\nprint(\"*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\\n\")\n\n# Condicionales\nprint(\"*-*-*-Condicionales-*-*-*\")\nnombre = \"julio\"\n\nif nombre == \"julio\":\n    print(\"Nombre registrado\")\nelif nombre == \"carmen\":\n    print(\"Nombre registrado\")\nelse:\n    print(\"Nombre no registrado\")\nprint(\"*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\\n\")\n\nprint(\"*-*-*-Operador match-*-*-*\")\n\n\ndef verificador_colores(color):\n    match color:\n        case \"verde\":\n            return \"color verde\"\n        case \"rojo\":\n            return \"color rojo\"\n        case \"marron\":\n            return \"color marron\"\n        case _:\n            return \"No añadiste ningun color registrado\"\n\n\nprint(f\"Operador match: {verificador_colores('rojo')}\")\nprint(\"*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\\n\")\n\n# Iterativas\nprint(\"*-*-*-Bucle for-*-*-*\")\nfor i in range(1, 10):\n    print(i)\nprint(\"*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\\n\")\n\nprint(\"*-*-*-Bucle while-*-*-*\")\nwhile True:\n    print(i)\n    if i == 9:\n        break\nprint(\"*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\\n\")\n\n# Excepciones\nprint(\"*-*-*-Excepciones-*-*-*\")\ntry:\n    a = 1\n    b = 0\n    division = a/b\nexcept Exception as e:\n    print(f'Excepcion: {e}')\nprint(\"*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\\n\")\n\nprint(\"*-*-*-Programa extra-*-*-*\")\n\n\ndef filter_numbers():\n    for i in range(10, 56):\n        if i % 2 == 0 and i % 3 != 0 and i != 16:\n            print(i)\n\n\nfilter_numbers()\nprint(\"*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\\n\")\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/mmacalli.py",
    "content": "\"\"\" \nOperadores\n\"\"\"\n#Operadores aritmeticos\nprint(f\"suma: 10 + 3 = {10 + 3}\")\nprint(f\"resta: 10 - 3 = {10 - 3}\")\nprint(f\"multiplicacion : 10 * 3 = {10 * 3}\")\nprint(f\"division : 10 / 3 = {10 / 3}\")\nprint(f\"modulo : 10 % 3 = {10 % 3}\")\nprint(f\"exponente: 10 ** 3 = {10 ** 3}\")\nprint(f\"division entera: 10 + 3 = {10 // 3}\")\n\n#operadores de comparacion\n\nprint(f\"igualdad: 10 == 3 = {10 == 3}\")\nprint(f\"desigualdad: 10 != 3 = {10 != 3}\")\nprint(f\"mayor que: 10 > 3 = {10 > 3}\")\nprint(f\"menor que: 10 < 3 = {10 < 3}\")\nprint(f\"menor igual que: 10 >= 3 = {10 >= 10}\")\nprint(f\"mayor igual que: 10 <= 3 = {10 <= 3}\")\n\n#Operadores Logicos\nprint(f\"AND && : 10 + 3 == 13 and 5 - 1 == 4 es {10 + 3 == 13 and 5 - 1 == 4} \")\nprint(f\"OR || : 10 + 3 == 13 or 5 - 1 == 4 es {10 + 3 == 13 or 5 - 1 == 4} \")\nprint(f\"NOT ! : not 10 + 3 == 14 es {not 10 + 3 == 14} \")\n\n#Operadores de asignacion\nmy_number = 11\nprint(my_number)\nmy_number += 1\nprint(my_number)\nmy_number -= 1\nprint(my_number)\nmy_number *= 2\nprint(my_number)\nmy_number /= 2\nprint(my_number)\nmy_number **= 2\nprint(my_number)\nmy_number //= 2\nprint(my_number)\nmy_number %= 2\nprint(my_number)\n\n#Operador de identidad\nmy_new_number = my_number\nprint(f\"my_number is my_new_number es: {my_number is my_new_number}\")\nprint(f\"my_number is not my_new_number es: {my_number is not my_new_number}\")\n\n#Operadores de pertenencia\nprint(f\"'a' in 'martin' = {'a' in 'martin'}\")\nprint(f\"'x' not in 'martin' = {'a' in 'martin'}\")\n\n#Operadores de bit\na = 10 #1010\nb = 3 #0011\nprint(f\"AND: 10 & 3 = {10 & 3}\")\nprint(f\"OR: 10 | 3 = {10 | 3}\")\nprint(f\"XOR: 10 ^ 3 = {10 ^ 3}\")\nprint(f\"NOT: 10 ~ 3 = {~10}\")\nprint(f\"Desplaza a la derecha: 10 >> 2 = {10 >> 2}\")\nprint(f\"Desplaza a la izquierda: 10 << 2 = {10 << 2}\")\n\n\"\"\"\nEstructuras de control\n\"\"\"\n#Condicionales\n\nmy_sting = \"martin\"\n\nif my_sting == \"martin\":\n    print(\"my_sting es : 'martin'\")\nelif my_sting == \"maca\":\n    print(\"my_string es 'maca'\")\nelse:\n    print(\"my_string no es 'martin' ni 'maca\")\n\n# Interactivas\n    \nfor i in range(22):\n    print(i)\n\ni = 0\nwhile i <= 10:\n    print(i)\n    i += 1\n    \n# Manejo de excepciones\n\n\ntry:\n    print(10/0)\nexcept:\n    print(\"tiene un error\") \nfinally:\n    print(\"finaliza el manejo de excepciones\")\n    \n\"\"\"\nExtra\n\"\"\"\nfor number in range (10, 56):\n    if number % 2 == 0 and number !=16 and number %3 != 0:\n        print(number)\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/monicavaquerano.py",
    "content": "# Mónica Vaquerano\n# https://monicavaquerano.dev\n\n# EJERCICIO 01:\n# - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n# Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n# (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n\n\nprint(\"\\nOperadores Aritméticos:\")\nx, y = 2, 2\n\nsuma = x + y\nresta = x - y\nmultiplicacion = x * y\ndivision = x / y\nmodulo = x % y\nexponencial = x**y\nfloor_division = x // y\n\nprint(\"Suma: x + y =\", suma)\nprint(\"Resta: x - y =\", resta)\nprint(\"Multiplicación: x * y =\", multiplicacion)\nprint(\"División: x / y =\", division)\nprint(\"Modulo: x % y =\", modulo)\nprint(\"Exponencial: x ** y =\", exponencial)\nprint(\"Floor division: x // y =\", floor_division)\n\nprint(\"\\nOperadores de Asignación:\")\nprint(\"X = 10\")\nprint(\"x += 2\")\nprint(\"x -= 3\")\nprint(\"x *= 8\")\nprint(\"x /= 6\")\nprint(\"x %= 2\")\nprint(\"x %= 3\")\nprint(\"x //= 1\")\nprint(\"x **= 5\")\nprint(\"x &= 0\")\nprint(\"x |= 3\")\nprint(\"x ^= 3\")\nprint(\"x >>= 3\")\nprint(\"x <<= 3\")\n\n\nprint(\"\\nOperadores de Comparación:\")\nx, y = 12, 6\nif x == 12:\n    print(\"X es igual a 12 (x == 12)\")\nif x != y:\n    print(\"X no es igual a Y (x != y)\")\nif x > y:\n    print(\"X es mayor a Y (x > y)\")\nif y < x:\n    print(\"Y es menor a X (y < x)\")\nif y >= 4:\n    print(\"Y es mayor o igual que 4 (y >= 4)\")\nif x <= 20:\n    print(\"X es menor o igual que 20 (x <= 20)\")\n\nprint(\"\\nOperadores de Lógicos:\")\nif x > y and x == 12:\n    print(\"X es mayor que Y, y X es igual a 12 (x > y and x == 12)\")\nif x != 12 or y == 6:\n    print(\"X es diferente a 12 o Y es igual a 6 (x != 12 or y == 6)\")\nif not (x != 12 and y != 6):\n    print(\"No es X diferente a 12 y Y diferente a 6 (not (x != 12 and y != 6))\")\n\nprint(\"\\nOperadores de Identidad:\")\nx, y = 5, 10\nprint(f\"X is Y?: {x is y}\")\nprint(f\"X is not Y?: {x is not y}\")\n\nprint(\"\\nOperadores de Pertenencia:\")\nlist = [5, 10, 20, 55, 75]\nprint(f\"20 is in List?: {20 in list}\")\nprint(f\"20 is not in List?: {20 not in list}\")\n\n# - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n# que representen todos los tipos de estructuras de control que existan\n# en tu lenguaje:\n# Condicionales, iterativas, excepciones...\n# Debes hacer print por consola del resultado de todos los ejemplos.\nprint(\"\\nEstructuras de Control Condicional:\")\nlist = [-3, 0, 1, 6]\nfor item in list:\n    item *= 2\n    if item < 0:\n        print(\"Soy un número negativo:\", item, end=\". \")\n    elif item == 0:\n        print(\"Soy cero!\", end=\". \")\n    elif 0 < item < 4:\n        print(\"Soy un número entre 0 y 5:\", item, end=\". \")\n    else:\n        print(\"Soy un número mayor a 5:\", item, end=\". \")\nprint()\n\nprint(\"\\nEstructuras de Control Ternario:\")\nfor i in range(len(list)):\n    print(\n        \"Soy un número negativo\" if list[i] <= 0 else \"Soy un número positivo\", end=\". \"\n    )\nprint()\n\nprint(\"\\nEstructuras de Control Iterativas:\")\nprint(\"While loop:\")\ncounter = 0\nwhile counter < 3:\n    print(\"Counter es menor a 3: counter =\", counter, end=\". \")\n    counter += 1\nprint()\n\nprint(\"\\nDo-While loop:\")\ncounter = 3\nwhile True:\n    print(\"Counter es mayor a 0: counter =\", counter, end=\". \")\n    counter -= 1\n    if counter <= 0:\n        break\nprint()\n\nprint(\"\\nFor loop:\")\nfor i in range(10, -1, -1):\n    if i == 0:\n        print(\"Boom!\")\n    else:\n        print(i, end=\", \")\n\nprint(\"\\nFor in loop:\")\nfor item in list:\n    print(\"Item:\", item, end=\". \")\nprint()\n\nprint(\"\\nFor in loop en objeto:\")\ncontactos = {\n    \"Alice\": {\"telefono\": \"0123456\"},\n    \"Bob\": {\"telefono\": \"0123456\"},\n    \"Charlie\": {\"telefono\": \"0123456\"},\n}\nfor key, value in contactos.items():\n    print(f\"{key.capitalize()} -> \", end=\"\")\n    for subkey, subvalue in value.items():\n        print(f\"{subkey.capitalize()} | {subvalue}\", end=\" |\")\n    print()\n\nprint(\"\\nExcepciones:\")\nprint(\"Try and except:\")\nx = 0\ntry:\n    if x == 0:\n        raise ValueError\nexcept:\n    print(\"Ocurrió una excepción.\")\n\nprint(\"\\nMuchas excepciones:\")\ntry:\n    if x == 0:\n        raise NameError\nexcept NameError:\n    print(\"La excepción NameError fue llamada.\")\nexcept:\n    print(\"NameError salio bien, pero algo más salio mal\")\n\n\nprint(\"\\nExcepciones con Else:\")\ntry:\n    print(\"Hola, me ejecutaron con éxito!\")\nexcept:\n    print(\"Algo salió mal\")\nelse:\n    print(\"Nada salió mal\")\n\n\nprint(\"\\nExcepciones con Finally:\")\ntry:\n    if x == 0:\n        raise NameError\nexcept:\n    print(\"Algo salió mal: NameError fue llamado\", end=\". \")\nfinally:\n    print(\"El bloque 'try except' terminó y ahora el bloque 'finally' se ejecuta.\")\n\n\nextra = \"\"\"\n                DIFICULTAD EXTRA (opcional):\nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3:\n\"\"\"\nprint(f\"{extra}\")\nprint(\"> \", end=\"\")\nfor i in range(10, 56):\n    if i % 2 == 0 and not i % 3 == 0 and i != 16:\n        print(i, end=\", \")\nprint()\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/monisstar.py",
    "content": "# Operdadores\n\n# Operdadores aritméticos\n\nprint(f'Suma -> 2 + 2 = {2 + 2}')\nprint(f'Resta -> 5 - 2 = {5 - 2}')\nprint(f'Multiplicación -> 4 * 8 = {4 * 8}')\nprint(f'División -> 10 / 2 = {10 / 2}')\nprint(f'Módulo -> 10 % 3 = {10 % 3}')\nprint(f'Potencia -> 2 ** 3 = {2 ** 3}')\nprint(f'División entera -> 10 // 2 = {10 // 2}')\n\n# Operaciones de comparación\nprint(f'Igualdad: 25 == 43 {25 == 43}')\nprint(f'Desigualdad: 25 != 43 {25 != 43}')\nprint(f'Mayor que: 25 > 43 {25 > 43}')\nprint(f'Menor que: 25 < 43 {25 < 43}')\nprint(f'Mayor o igual que: 25 >= 43 {25 >= 43}')\nprint(f'Menor o igual que: 25 <= 43 {25 <= 43}')\n\n#Operdaores lógicos\nprint(f'AND &&: 25 + 43 == 68 and 25 - 43 == 0 es: {25 + 43 == 68 and 25 - 43 == 0}')\nprint(f'OR ||: 25 + 43 == 68 or 25 - 43 == 0 es: {25 + 43 == 68 or 25 - 43 == 0}')\nprint(f'NOT !: not 25 + 43 == 68 es: {not 25 + 43 == 68}')\n\n# Operadores de asignación\nnumber = 5\nprint(number)\nnumber += 1  # suma y asignación\nprint(number)\nnumber -= 1  # resta y asignación\nprint(number)\nnumber *= 2  # multiplicación y asignacion\nprint(number)\nnumber %= 2  # módulo y asignación\nprint(number)\nnumber **= 2 # potencia y asignación\nnumber //= 2 # división entera y asignación\n\n# Operadores de identidad\nn_number = 5\nprint(f'n_number is number es {n_number is number}')\nprint(f'n_number is not number es {n_number is not number}')\n\n# Operadores de pertenencia\nprint(f\"'o' in 'monisstar' es {'o' in 'monisstar'}\")\nprint(f\"'j' not in 'monisstar' es {'j' not in 'monisstar'}\")\n\n# Operadores de bit\na = 10\nb = 3\nprint(f'AND: 10 & 3 = {a & b}')\nprint(f'OR: 10 | 3 = {a | b}')\nprint(f'XOR: 10 ^ 3 = {a ^ b}')\nprint(f'NOT: ~10 = {~a}')\nprint(f'Desplazamiento a la derecha: 10 >> 2 = {10 >> 2}')\nprint(f'Desplazamiento a la izquierda: 10 << 2 = {10 << 2}')\n\n'''\nEstructuras de control\n'''\n# Condicionales\nmy_string = 'monisstar'\nif my_string == 'monisstar':\n    print('my_string es monisstar')\nelif my_string == 'Brais':\n    print('my_string es Brais')\nelse:\n    print('my_string es diferente de monisstar y Brais')\n\n# Iterativas\nfor i in range(11):\n    print(i)\n\ni = 0\n\nwhile i <= 10:\n    print(i)\n    i += 1\n\n# Manejo de excepciones\ntry:\n    print(10 / 0)\nexcept ZeroDivisionError:\n    print('No se puede dividir entre 0')\nfinally:\n    print('Finalizado, el manejo de excepciones')\n\n'''\nDIFICULTAD EXTRA\n'''\nfor i in range(10, 56):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/mordevspt.py",
    "content": "'''\n* - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n*   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n*   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n'''\n\n'''\n* - Debes hacer print por consola del resultado de todos los ejemplos.\n'''\n\n# Operadores Aritméticos\nprint(\"OPERADORES ARITMÉTICOS: \\n\")\n# Variables que usaremos para ilustrar los ejemplos\na = 5\nb = 13\nprint(f\"Valores a usar a:{a}, b:{b}\")\n# Suma\nsuma = a + b\nprint(f\"Suma a + b: {suma} \\n\")\n# Resta\nresta = b - a\nprint(f\"Resta b - a: {resta} \\n\")\n# Multiplicación\nmulti = a * b\nprint(f\"Multiplicación a * b: {multi} \\n\")\n# División\ndivi = a / b\nprint(f\"División a / b: {divi} \\n\")\n# Módulo\nmodulo = b % a\nprint(f\"Módulo b % a: {modulo} \\n\")\n# Potencia\npotencia = b ** a\nprint(f\"Potencia b ** a: {potencia} \\n\")\n# División entera\ndivient = b // a\nprint(f\"División entera b // a: {divient} \\n\")\n\n# Operadores de Asignación\nprint(\"OPERADORES DE ASIGNACIÓN: \\n\")\n# Asignación de valor y variables que usaremos para ilustrar los ejemplos\na = 10\nb = 100\nc = 55\nprint(f\"Variables a:{a}, b:{b}, c:{c} \\n\")\n# Asig. Valor + 1\na += 6 # a = 16\nprint(f\"a += 6: {a} \\n\")\n# Asig. Valor - 1\na -= 6 # a = 10\nprint(f\"a -= 6: {a} \\n\")\n# Asig. Valor * 5\na *= 5 # a = 50\nprint(f\"a *= 5: {a} \\n\")\n# Asig. Valor / 2\na /= 5 # a = 10\nprint(f\"a /= 5: {a} \\n\")\n# Asig. Valor % 3\na %= 3 # a = 1\nprint(f\"a %= 3: {a} \\n\")\n# Asig. Valor % 3\na **= 5 # a = 1\nprint(f\"a **= 5: {a} \\n\")\n# Asig. Valor // 4\nb //= 4 # b = 25\nprint(f\"b //= 4: {b} \\n\")\n# Asig. Valor & 3\nb &= 3 # b = 1\nprint(f\"b &= 3: {b} \\n\")\n# Asig. Valor | 5\nb |= 5 # b = 5\nprint(f\"b |= 5: {b} \\n\")\n# Asig. Valor ^=\nc ^= 5 # c = 50\nprint(f\"c ^= 5: {c} \\n\")\n# Asig. Valor >>=\nc >>= 5 # c = 1\nprint(f\"c >>= 5: {c} \\n\")\n# Asig. Valor <<=\nc <<= 5 # c = 32\nprint(f\"c <<= 5: {c} \\n\")\n\n# Operadores de Identidad\nprint(\"OPERADORES DE IDENTIDAD: \\n\")\n# Variables que usaremos para ilustrar los ejemplos\na = 5\nb = 13\nc = 5\nprint(f\"Variables a:{a}, b:{b}, c:{c} \\n\")\n# Comparación valores iguales => True\nprint(f\"a is c: {a is c} \\n\")\n# Comparación valores NO iguales => False\nprint(f\"a is b: {a is b} \\n\")\n# Comparación valores si no son iguales => False\nprint(f\"a is not c: {a is not c} \\n\")\n# Otras variables tipo String\ntxt1 = \"RestosDeProgramacion\"\ntxt2 = \"RestosDeProgramacion\"\n# Comparación valores iguales => True\nprint(f\"txt1 is txt2: {txt1 is txt2} \\n\")\n# Comparación valores si no son iguales => False\nprint(f\"txt1 is not txt2: {txt1 is not txt2} \\n\")\n# Otras variables tipo list\nlist1 = [10,20,30]\nlist2 = [10,20,30]\n# Comparación valores iguales => False (Las listas son objetos mutables)\nprint(f\"list1 is list2: {list1 is list2} \\n\")\n\n# Operadores Relacionales\nprint(\"OPERADORES RELACIONALES: \\n\")\n# Variables que usaremos para ilustrar los ejemplos\na = 10\nb = 20\nc = 10\nprint(f\"Variables a:{a}, b:{b}, c:{c} \\n\")\n# Mayor que\nprint(f\"Mayor que: a>b: {a>b} \\b\")\n# Menor que\nprint(f\"Menor que: a<b: {a<b} \\n\")\n# Valor igual\nprint(f\"Valor igual: a==c: {a==c} \\n\")\t\n# Mayor que o igual\nprint(f\"Mayor que o igual: b>=c: {b>=c} \\n\")\t\n# Menor que o igual\nprint(f\"Menor que o igual: c<=b: {c<=b} \\n\")\t\n# Valor diferente\nprint(f\"Valor diferente: a!=c: {a!=c} \\n\")\n\n# Operadores Bit a Bit\nprint(\"OPERADORES BIT A BIT: \\n\")\n# Variables que usaremos para ilustrar los ejemplos\na = 2 # en binario = 10\nb = 3 # en binario = 11\nprint(f\"Variables a:{a}, b:{b} \\n\")\n# Operación AND => a & b = 2 (Binario: 10 & 11 = 10)\nprint(f\"Operación AND: a & b: {a & b} \\n\")\n# Operación OR => a | b = 3 (Binario: 10 | 11 = 11)\nprint(f\"Operación OR: a | b: {a | b} \\n\")\n# Operación XOR => a ^ b = 1 (Binario: 10 ^ 11 = 01)\nprint(f\"Operación XOR: a ^ b: {a ^ b} \\n\")\n# Operación NOT => ~a = -3 (Binario: ~(00000010) = (11111101))\nprint(f\"Operación NOT: ~a: {~a} \\n\")\n# Desplaza los bits del operando de izquierda a la derecha => a >> b = 0 (Binario: 00000010 >> 00000011 = 0)\nprint(f\"Desplazar Bits de Izquierda a Derecha: a >> b: {a >> b} \\n\")\n# Desplazalos bits del operando de la izquierda a la izquierda => a << b = 16 (Binario: 00000010 << 00000011 = 00001000)\nprint(f\"Desplazar Bits de Izquierda a Izquierda: a << b: {a << b} \\n\")\n\n# Operadores Lógicos\nprint(\"OPERADORES LÓGICOS: \\n\")\n# Variables que usaremos para ilustrar los ejemplos\na = True\nb = False\nprint(f\"Variables a:{a}, b:{b} \\n\")\n# AND\nprint(f\"AND: a and b: {a and b} \\n\")\n# OR\nprint(f\"OR: a or b: {a or b} \\n\")\n# NOT\nprint(f\"NOT: not a: {not a} \\n\")\n\n# Operadores de Pertenencia\nprint(\"OPERADORES DE PERTENENCIA: \\n\")\n# Variables que usaremos para ilustrar los ejemplos\nlista = [1,2,3,4,5]\ntexto = \"Hola Mundo\"\nprint(f\"Variables \\n - Lista:{a} \\n - Texto:{b} \\n\")\n  \nprint(\"¿Esta el número/palabra en la lista/texto?: \\n\")\n# Muestra True\nprint(f\"4 in lista: {4 in lista} \\n\")\nprint(f\"'Mundo' in texto: {\"Mundo\" in texto} \\n\")\n\nprint(\"¿No está el número/palabra en la lista/texto?: \\n\")\n# Muestra True \nprint(f\"25 not in lista: {12 not in lista} \\n\")\nprint(f\"'Visual' not in texto: {\"Visual\" not in texto} \\n\")\n\n'''\n* - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n*   que representen todos los tipos de estructuras de control que existan\n*   en tu lenguaje:\n*   Condicionales, iterativas, excepciones...\n'''\n\n# Condicionales\nprint(\"OPERADORES CONDICIONALES: \\n\")\n\nnombreMascota = \"Caramelo\"\n\nif nombreMascota == \"Calcetines\":\n    print(\"El nombre de la mascota es 'Calcetines' \\n\")\nelif nombreMascota == \"Manchitas\":\n    print(\"El nombre de la mascota es 'Manchitas' \\n\")\nelse:\n    print(f\"El nombre de la mascota no es 'Calcetines' ni 'Manchitas', es {nombreMascota} \\n\")\n\n# Iterativas\nprint(\"OPERADORES ITERATIVOS: \\n\")\n# Variables que usaremos para ilustrar los ejemplos\na = 3\nb = 33\n# Bucle For\nprint(f\"Bucle For de {a} hasta {b} \\n\")\nfor i in range(a,b+1):\n    print(f\"- {i}\")\n\n# Bucle While\nprint(f\"\\n Bucle While de {a} hasta {b} \\n\")\ni = a\nwhile i <= b:\n    print(f\"- {i}\")\n    i += 1\n\n# Excepciones\nprint(\"\\n MANEJO DE EXCEPCIONES: \\n\")\ntry:\n    print(f\"Comparamos b <= a: {b <= a} \\n\")\nexcept:\n    print(\"Se ha producido un error en la operación. \\n\")\nfinally:\n    print(\"Ha finalizado el manejo de excepciones pase lo que pase \\n\")\n\n'''\n* DIFICULTAD EXTRA (opcional):\n* Crea un programa que imprima por consola todos los números comprendidos\n* entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n'''\n\n# Hacemos uso de la estructura for para recorrer un rango e ir comprobando números\nprint (\"EJERCICIO \\n\")\nfor i in range(10, 56):\n    # Comprobamos que el número a imprimir cumple con las tres condiciones\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print(f\"- {i}\")\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/mouredev.py",
    "content": "\"\"\"\nOperadores\n\"\"\"\n\n# Operadores aritméticos\nprint(f\"Suma: 10 + 3 = {10 + 3}\")\nprint(f\"Resta: 10 - 3 = {10 - 3}\")\nprint(f\"Multiplicación: 10 * 3 = {10 * 3}\")\nprint(f\"División: 10 / 3 = {10 / 3}\")\nprint(f\"Módulo: 10 % 3 = {10 % 3}\")\nprint(f\"Exponente: 10 ** 3 = {10 ** 3}\")\nprint(f\"División entera: 10 // 3 = {10 // 3}\")\n\n# Operadores de comparación\nprint(f\"Igualdad: 10 == 3 es {10 == 3}\")\nprint(f\"Desigualdad: 10 != 3 es {10 != 3}\")\nprint(f\"Mayor que: 10 > 3 es {10 > 3}\")\nprint(f\"Menor que: 10 < 3 es {10 < 3}\")\nprint(f\"Mayor o igual que: 10 >= 10 es {10 >= 10}\")\nprint(f\"Menor o igual que: 10 <= 3 es {10 <= 3}\")\n\n# Operadores lógicos\nprint(f\"AND &&: 10 + 3 == 13 and 5 - 1 == 4 es {10 + 3 == 13 and 5 - 1 == 4}\")\nprint(f\"OR ||: 10 + 3 == 13 or 5 - 1 == 4 es {10 + 3 == 14 or 5 - 1 == 4}\")\nprint(f\"NOT !: not 10 + 3 == 14 es {not 10 + 3 == 14}\")\n\n# Operadores de asignación\nmy_number = 11  # asignación\nprint(my_number)\nmy_number += 1  # suma y asignación\nprint(my_number)\nmy_number -= 1  # resta y asignación\nprint(my_number)\nmy_number *= 2  # multiplicación y asignación\nprint(my_number)\nmy_number /= 2  # división y asignación\nprint(my_number)\nmy_number %= 2  # módulo y asignación\nprint(my_number)\nmy_number **= 1  # exponente y asignación\nprint(my_number)\nmy_number //= 1  # división entera y asignación\nprint(my_number)\n\n# Operadores de identidad\nmy_new_number = my_number\nprint(f\"my_number is my_new_number es {my_number is my_new_number}\")\nprint(f\"my_number is not my_new_number es {my_number is not my_new_number}\")\n\n# Operadores de pertenencia\nprint(f\"'u' in 'mouredev' = {'u' in 'mouredev'}\")\nprint(f\"'b' not in 'mouredev' = {'b' not in 'mouredev'}\")\n\n# Operadores de bit\na = 10  # 1010\nb = 3  # 0011\nprint(f\"AND: 10 & 3 = {10 & 3}\")  # 0010\nprint(f\"OR: 10 | 3 = {10 | 3}\")  # 1011\nprint(f\"XOR: 10 ^ 3 = {10 ^ 3}\")  # 1001\nprint(f\"NOT: ~10 = {~10}\")\nprint(f\"Desplazamiento a la derecha: 10 >> 2 = {10 >> 2}\")  # 0010\nprint(f\"Desplazamiento a la izquierda: 10 << 2 = {10 << 2}\")  # 101000\n\n\"\"\"\nEstructuras de control\n\"\"\"\n\n# Condicionales\n\nmy_string = \"Brais\"\n\nif my_string == \"MoureDev\":\n    print(\"my_string es 'MoureDev'\")\nelif my_string == \"Brais\":\n    print(\"my_string es 'Brais'\")\nelse:\n    print(\"my_string no es 'MoureDev' ni 'Brais'\")\n\n# Iterativas\n\nfor i in range(11):\n    print(i)\n\ni = 0\n\nwhile i <= 10:\n    print(i)\n    i += 1\n\n# Manejo de excepciones\ntry:\n    print(10 / 0)\nexcept:\n    print(\"Se ha producido un error\")\nfinally:\n    print(\"Ha finalizado el manejo de excepciones\")\n\n\"\"\"\nExtra\n\"\"\"\n\nfor number in range(10, 56):\n    if number % 2 == 0 and number != 16 and number % 3 != 0:\n        print(number)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/mplatab.py",
    "content": "# Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits\n\na = 10\nb = 3\n\n# Operadores aritméticos\nprint(\"*************OPERADORES ARITMÉTICOS*************\")\nprint(f\"Suma: 10 + 3 = {a + b}\")\nprint(f\"Resta: 10 - 3 = {a - b}\")\nprint(f\"Mulplicación: 10 * 3 = {a * b}\")\nprint(f\"División: 10 / 3= {a / b}\")\nprint(f\"Módulo: 10 % 3= {a % b}\")\nprint(f\"Exponente: 10 ** 3 = {a ** b}\")\nprint(f\"División entera: 10 // 3 = {a // b}\")\n\n# Operadores lógicos\nprint(\"*************OPERADORES LÓGICOS*************\")\nprint(f\"AND: 20 + 5 == 25 and 30 - 15 == 15 es {20 + 5 == 25 and 30 - 15 == 15}\")\nprint(f\"OR: 20 + 5 == 25 or 30 - 15 != 15 es {20 + 5 == 25 or 30 - 15 != 15}\")\nprint(f\"NOT: not 10 + 3 == 14 es {not 10 + 3 == 14}\")\n\n# Operadores de comparación\nprint(\"*************OPERADORES DE COMPARACIÓN*************\")\nprint(f\"Igualdad: 10 == 3 es {a == b}\" )\nprint(f\"Desigualdad: 10 != 3 es {a != b}\" )\nprint(f\"Mayor que: 10 > 3 es {a > b}\" )\nprint(f\"Menor que: 10 < 3 es {a < b}\" )\nprint(f\"Mayor o igual que: 10 >= 3 es {a >= b}\" )\nprint(f\"Menor o igual que: 10 <= 3 es {a <= b}\" )\n\n# Operadores de asignación\nprint(\"*************OPERADORES DE ASIGNACIÓN*************\")\nmy_number = 11 # asignación\nprint(my_number)\n\nmy_number += 1 # suma y asignacion\nprint(my_number)\n\nmy_number -= 1 # resta y asignacion\nprint(my_number)\n\nmy_number *= 3 # multiplicación y asignacion\nprint(my_number)\n\nmy_number /= 3 # división y asignacion\nprint(my_number)\n\nmy_number %= 3 # modulo y asignacion\nprint(my_number)\n\nmy_number **= 1 # potenciación y asignacion\nprint(my_number)\n\nmy_number //= 1 # devisión entera y asignacion\nprint(my_number)\n\n# Operadores de identidad comparan la dirección de memoria con is\nmy_new_number = 1.0\nprint(f\"my_number is my_new_number es {my_number is my_new_number}\") # igualdad\nprint(f\"my_number is my_new_number es {my_number is not my_new_number}\") # desigualdad\n\n# Operadores de pertenencia\nprint(f\" a in 'marcos' = {'a' in 'marcos'}\") # verifica si a pertenece o esta incluido en marcos\n\n# Operadores de bits\nc = 10 # 1010\nd = 3 # 0011\n\nprint(f\"AND: 10 & 3 = {10 & 3}\") # 0010 Compara bit a bit solo si los bit son 1-1 es 1\nprint(f\"OR: 10 | 3 = {10 | 3}\") # 1011 Compara bit a bit si al menos uno de los bit es 1 el resultado es 1 \nprint(f\"XOR: 10 ^ 3 = {10 ^ 3}\") # 1001 Compara bit a bit si los bit son diferentes el resultado es 1 caso contrario es 0\nprint(f\"NOT: ~10 = {~10}\") # Intercambia el valor bit a bit de cualquiera de los elementos\n\n# Desplazamiento\nprint(f\"Desplazamientoa la derecha: 10 >> 2 = {10 >> 2}\") # 1010 -> 0010\nprint(f\"Desplazamientoa la izquierdad: 10 << 2 = {10 << 2}\") # 1010 -> 101000\n\n\"\"\"\nEstructuras de control\n\"\"\"\n# Condicionales\nmy_age = 25\n\nif(my_age < 0):\n    print(\"La edad tiene que ser mayor o igual a 0\")\nelif(my_age >= 18):\n    print(\"Es mayor de edad\")\nelse:\n    print(\"Es menor edad\")\n\n# Iterativas\nprint(\"-----for-----\")\nfor i in range(0, 11):\n    print(i)\n\nprint(\"-----while-----\")\ncontador = 0\nwhile(contador <= 10):\n    print(contador)\n    contador += 1\n\n# Manejo de excepciones\nprint(\"-----Manejo de errores-----\")\n\ntry:\n    print(10 / 1)\nexcept:\n    print(\"Se ha producido un error\")\nfinally:\n    print(\"Ha terminado el manejo de errores o excepciones\")\n\n\"\"\"\nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\"\"\"\n\nprint(\"****EJERCICIO OPCIONAL****\")\nfor i in range(10, 56):\n    if(i % 2 == 0 and i != 16 and i % 3 != 0):\n        print(i)\n        "
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/mrodara.py",
    "content": "#\n# EJERCICIO:\n# - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n#   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n#   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n# - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n#   que representen todos los tipos de estructuras de control que existan\n#   en tu lenguaje:\n#   Condicionales, iterativas, excepciones...\n# - Debes hacer print por consola del resultado de todos los ejemplos.\n#\n# DIFICULTAD EXTRA (opcional):\n# Crea un programa que imprima por consola todos los números comprendidos\n# entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n#\n# Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n#/\n\n# Operadores aritméticos\nprint(10 + 5) # Suma\nprint(10 - 5) # Resta\nprint(10 * 5) # Multiplicación\nprint(10 / 5) # División\nprint(10 % 5) # Módulo\nprint(10 ** 5) # Potencia\nprint(10 // 5) # División entera\n\n# Operadores lógicos\nprint(True and True) # Y lógico\nprint(True or False) # O lógico\nprint(not True) # Negación lógica\n\n# Operadores de comparación\nprint(10 == 5) # Igual\nprint(10 != 5) # Distinto\nprint(10 > 5) # Mayor que\nprint(10 < 5) # Menor que\nprint(10 >= 5) # Mayor o igual que\nprint(10 <= 5) # Menor o igual que\nprint(10 is 5) # Identidad\nprint(10 is not 5) # No identidad\nprint(10 in [1, 2, 3]) # Pertenencia\nprint(10 not in [1, 2, 3]) # No pertenencia\n\n# Estructuras de control\n\n# Condicionales\nmy_fuel = 0\n\nif my_fuel == 0:\n    print(\"No tienes combustible, tienes que repostar antes de continuar\")\n\n\nage = 18\n\nif age >= 18:\n    print(\"Eres mayor de edad\")\nelse:\n    print(\"Eres menor de edad\")\n\nmy_fuel = 100\n\nif my_fuel == 0:\n    print(\"No tienes combustible, tienes que repostar antes de continuar\")\nelif my_fuel < 50:\n    print('El tanque está por debajo del 50%')\nelif my_fuel < 75:\n    print('El tanque está por debajo del 75%')\nelse:\n    print('El tanque está lleno')\n\n# Otra opción conditional, similar al switch\nmatch age:\n    case 18:\n        print(\"Eres mayor de edad\")\n    case 17:\n        print(\"Eres menor de edad\")\n    case _:\n        print(\"No tienes edad\")\n\n\n# Iterativas\n\nmy_string = \"Hola Mundo\"\n\n# For\nfor char in my_string:\n    print(char, end=' ')\n\n# While\ni = 0\n\nwhile i < 5:\n    print(i, end=' ')\n    i += 1\n    \n# Excepciones\ntry:\n    print(10 / 0)\nexcept ZeroDivisionError:\n    print(\"No puedes dividir por cero\")\nexcept:\n    print(\"Algo salió mal\")\nfinally:\n    print(\"Esto se ejecuta siempre\")\n\n\n# DIFICULTAD EXTRA\n\nfor i in range(10, 56):\n    if i % 2 == 0 and i != 16 and i % 3 !=0:\n        print(i, end=' ')\n    "
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/mvidalb.py",
    "content": "\"\"\"\nOperadores\n\"\"\"\n\n# Operadores aritméticos\nprint(f\"Suma: 10 + 3 = {10 + 3}\")\nprint(f\"Resta: 10 - 3 = {10 - 3}\")\nprint(f\"División: 10  3 = {10 / 3}\")\nprint(f\"Multiplicación: 10 * 3 = {10 + 3}\")\nprint(f\"Módulo: 10 % 3 = {10 % 3}\")\nprint(f\"Exponente: 10 ** 3 = {10 ** 3}\")\nprint(f\"División entera: 10 // 3 = {10 // 3}\")\n\n# Operadores de comparación\nprint(f\"Igualdad: 10 == 3 es {10 == 3}\")\nprint(f\"Desigualdad: 10 != 3 es {10 != 3}\")\nprint(f\"Mayor que: 10 > 3 es {10 > 3}\")\nprint(f\"Menor que: 10 < 3 es {10 < 3}\")\nprint(f\"Mayor o igual que: 10 >= 3 es {10 >= 3}\")\nprint(f\"Menor o igual que: 10 <= 3 es {10 <= 3}\")\n\n# Operadores lógicos\nprint(f\"AND &&: 10 + 3 == 13 and 5-1 == 4 es {10 + 3 == 13 and 5-1 == 4}\")\nprint(f\"OR ||: 10 + 3 == 13 or 5-1 == 4 es {10 + 3 == 14 or 5-1 == 4}\")\nprint(f\"NOT !: not 10 + 3 ==14 es {not 10 + 3 == 14}\")\n\n# Operadores de asginación\nmy_number = 11      \nprint(my_number)\nmy_number += 1      # suma y asignación\nprint(my_number)\nmy_number -= 1      # resta y asignación\nprint(my_number)\nmy_number *= 1      # multiplicación y asignación\nprint(my_number)\nmy_number /= 2      # división y asignación\nprint(my_number)\nmy_number %= 1      # módulo y asignación\nprint(my_number)\nmy_number **= 1     # exponente y asignación\nprint(my_number)\nmy_number //= 1     # división entera y asignación\nprint(my_number)\n\n# Operadores de identidad \nmy_new_umber = my_number\nprint(f\"my_number is my_new_umber es {my_number is my_new_umber}\")\nprint(f\"my_number is not my_new_umber es {my_number is not my_new_umber}\")\n\n# Operadores de pertenencia\nprint(f\"'u' in 'Mario' = {'u' in 'Mario'}\")\nprint(f\"'u' not in 'Mario' = {'u' not in 'Mario'}\")\n\n# Operadores de bit\na = 10  # 1010\nb = 3   # 0011\n\nprint(f\"AND: 10 & 3 = {10 & 3}\")    # 0010 = 2\nprint(f\"OR: 10 | 3 = {10 | 3}\")     # 1011 = 11\nprint(f\"XOR: 10 ^ 3 = {10 ^ 3}\")    # 1001 = 9\nprint(f\"NOT: ~10 = {~10}\")\nprint(f\"Desplazamiento a la derecha: 10 >> 2 = { 10 >> 2}\")  #0010\nprint(f\"Desplazamiento a la izquierda: 10 << 2 = { 10 << 2}\")  #10100\n\n\n\"\"\"\nEstructuras de control\n\"\"\"\n\n# Condicionales\nmy_string = \"Mario\"\nif my_string == \"Mario\":\n    print(\"my_string es 'Mario'\")\nelif my_string == \"Pedro\":\n    print(\"my_string es 'Pedro'\")\nelse:\n    print(\"my_string no es 'Mario ni 'Pedro'\")\n\n# Iterativas\nfor i in range(0,11):\n    print(i)\n\ni=0\nwhile i <= 10:\n    print(i)\n    i += 1\n\n# Manejo de excepciones\ntry:\n    10/0\nexcept:\n    print(\"Error!\")\nfinally:\n    print(\"Esto se ejecuta siempre, haya un error o no!\")\n\n\n'''\nEjercicio extra\n'''\n\ndef ejerc_extra():\n    for i in range(10,56):\n        if i % 2 == 0 and i != 16 and i % 3 != 0:\n            print(i)\n\nejerc_extra()\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/nachodev7.py",
    "content": "\"\"\"\nOperadores \n\"\"\"\n\n# Aritméticos \n\nprint(f\"Suma: 10 + 3 = {10 + 3}\")\nprint(f\"Resta: 10 - 3 = {10 - 3}\")\nprint(f\"Multiplicación: 10 * 3 = {10 * 3}\")\nprint(f\"División: 10 / 3 = {10 / 3}\")\nprint(f\"Módulo: 10 % 3 = {10 % 3}\")\nprint(f\"Exponente: 10 ** 3 = {10 ** 3}\")\nprint(f\"División entera: 10 // 3 = {10 // 3}\")\n\n# Comparación \nprint(f\"igualdad: 10 == 3 es {10 == 3}\")\nprint(f\"Desigualdad: 10 != 3 es {10 != 3}\")\nprint(f\"Mayor que: 10 > 3 es {10 > 3}\")\nprint(f\"Menor que: 10 < 3 es {10 < 3}\")\nprint(f\"Mayor o igual que: 10 >= 10 es {10 >= 10}\")\nprint(f\"Menor o igual que: 10 <= 3 es {10 <= 3}\")\n\n# Lógicos\nprint(f\"AND &&: 10 + 3 == 13 and 5 - 1 == 4 es {10 + 3 == 13 and 5 -1 == 4}\")\nprint(f\"OR ||: 10 + 3 == 13 or 5 - 1 == 4 es {10 + 3 == 14 or 5 - 1 == 4}\")\nprint(f\"NOT !: not 10 + 3 == 14 es {not 10 + 3 == 14}\")\n\n# Asignacón \nmy_number = 11  \nprint(my_number)\nmy_number += 1  \nprint(my_number)\nmy_number -= 1  \nprint(my_number)\nmy_number *= 2  \nprint(my_number)\nmy_number /= 2  \nprint(my_number)\nmy_number %= 2  \nprint(my_number)\nmy_number **= 1  \nprint(my_number)\nmy_number //= 1  \nprint(my_number)\n\n# Identida \nmy_new_number = my_number\nprint(f\"my_number is my_new_number es {my_number is my_new_number}\")\nprint(f\"my_number is not my_new_number es {my_number is not my_new_number}\")\n\n# Pertenencia \nprint(f\"'y' in 'Python' = {'y' in 'Python'}\")\nprint(f\"'b' not in 'Python' = {'b' not in 'Python'}\")\n\n# Bit \na = 10  # 1010\nb = 3  # 0011\nprint(f\"AND: 10 & 3 = {10 & 3}\")  # 0010\nprint(f\"OR: 10 | 3 = {10 | 3}\")  # 1011\nprint(f\"XOR: 10 ^ 3 = {10 ^ 3}\")  # 1001\nprint(f\"NOT: ~10 = {~10}\")\nprint(f\"Desplazamiento a la derecha: 10 >> 2 = {10 >> 2}\")  # 0010\nprint(f\"Desplazamiento a la izquierda: 10 << 2 = {10 << 2}\")  # 101000\n\n\"\"\"\nEstructuras de control\n\"\"\"\n# Condicionales\n\nmy_string = \"Python\"\n\nif my_string == \"Rust\":\n    print(\"my_string es 'Rust'\")\nelif my_string == \"Python\":\n    print(\"my_string es 'Python'\")\nelse:\n    print(\"my_string no es 'Rust' ni 'Python'\")\n\n# Iterativas\n\nfor i in range(11):\n    print(i)\n\ni = 0\n\nwhile i <= 10:\n    print(i)\n    i += 1\n\n# Manejo de excepciones\ntry:\n    print(10 / 0)\nexcept:\n    print(\"Se ha producido un error\")\nfinally:\n    print(\"Ha finalizado el manejo de excepciones\")\n\n\"\"\"\nExtra\n\"\"\"\n\nfor number in range(10, 56):\n    if number % 2 == 0 and number != 16 and number % 3 != 0:\n        print(number)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/neslarra.py",
    "content": "\"\"\"\n EJERCICIO:\n - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n   que representen todos los tipos de estructuras de control que existan\n   en tu lenguaje:\n   Condicionales, iterativas, excepciones...\n - Debes hacer print por consola del resultado de todos los ejemplos.\n\n DIFICULTAD EXTRA (opcional):\n Crea un programa que imprima por consola todos los números comprendidos\n entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\n Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\"\"\"\n\nprint(f\"{'='*10} OPERADORES {'='*40}\", end=\"\\n\\n\")\n\nprint(f\"\"\" Tipos de operadores:\n\\tde Asignación\n\\tde Cadena\n\\tAritméticos\n\\tLógicos\n\\tde Comparación\n\\tde Pertenencia\n\\tde Identidad\n\\tde Bits\n\"\"\")\n\n# operador de asignación -----------------------------------------------------------------------------------------------\n\nsaludo: str = \"Hola\"\nnombre: str = \"Mundo\"\n\nprint(\"de ASIGNACIÓN\")\nprint(f\"El operador '=' se usa para asignar valores a variables: saludo => {saludo} y nombre => {nombre}\")\nprint(f\"También se lo usa en combinación con otros operadores que veremos más adelante\", end=\"\\n\\n\")\n\n# operador de cadena ---------------------------------------------------------------------------------------------------\n\nprint(\"de CADENA\")\nimprimo: str = saludo + \" \" + nombre + \"!!!\"\nprint(f\"El operador '+' concatena cadenas (aunque NO es la única forma) => saludo + nombre => {imprimo}\", end=\"\\n\\n\")\n\n# operadores aritméticos -----------------------------------------------------------------------------------------------\nnumero_1: int = 10\nnumero_2: int = 3\nsuma = numero_1 + numero_2\nresta = numero_1 - numero_2\nproducto = numero_1 * numero_2\ndivision = numero_1 / numero_2\ndivision_entera = numero_1 // numero_2\nresto = numero_1 % numero_2\npotencia = numero_1 ** numero_2\n\nprint(\"ARITMÉTICOS\")\nprint(f\"El operador '+' da la suma: {numero_1} + {numero_2} => {suma}\")\nprint(f\"El operador '-' da la resta: {numero_1} - {numero_2} => {resta}\")\nprint(f\"El operador '*' da la multiplicación: {numero_1} * {numero_2} => {producto}\")\nprint(f\"El operador '/' da el cociente: {numero_1} / {numero_2} => {division}\")\nprint(f\"El operador '//' da el cociente entero: {numero_1} // {numero_2} => {division_entera}\")\nprint(f\"El operador '%' da el resto: {numero_1} % {numero_2} => {resto}\")\nprint(f\"El operador '**' da la potencia: {numero_1} ** {numero_2} => {potencia}\", end=\"\\n\\n\")\n\n# operadores de comparación --------------------------------------------------------------------------------------------\n\nvar_1: str = \"1\"\nvar_2: int = 1\nverdadero: bool = (var_1 == \"1\")\nfalso: bool = (var_1 == 1)\n\nprint(\"de COMPARACIÓN\")\nprint(f\"El operador '==' devuelve verdadero si los comparandos son iguales, sino devuelve falso\")\nprint(f\"\\t'{var_1}' == '1' => {verdadero}\")\nprint(f\"\\t'{var_1}' == 1 => {falso}\")\n\nverdadero: bool = (var_2 > 0)\nfalso: bool = (var_2 > 5)\n\nprint(f\"El operador '>' devuelve verdadero si el primer comparando es mayor que el segundo, sino devuelve falso\")\nprint(f\"\\t{var_2} > 0 => {verdadero}\")\nprint(f\"\\t{var_2} > 5 => {falso}\")\n\nverdadero: bool = (var_2 < 5)\nfalso: bool = (var_2 < 0)\n\nprint(f\"El operador '<' devuelve verdadero si el primer comparando es menor que el segundo, sino devuelve falso\")\nprint(f\"\\t{var_2} < 5 => {verdadero}\")\nprint(f\"\\t{var_2} < 0 => {falso}\")\n\nverdadero: bool = (var_1 != var_2)\nfalso: bool = (var_2 != 1)\n\nprint(f\"El operador '!=' devuelve verdadero si el primer comparando es distinto que el segundo, sino devuelve falso\")\nprint(f\"\\t'{var_1}' != {var_2} => {verdadero}\")\nprint(f\"\\t{var_2} != 1 => {falso}\")\n\nverdadero: bool = (var_2 >= 1)\nfalso: bool = (var_2 <= 0)\n\nprint(f\"También se puede combinar '>=' (mayor o igual) o '<=' (menor o igual)\")\nprint(f\"\\t{var_2} >= 1 => {verdadero}\")\nprint(f\"\\t{var_2} <= 0 => {falso}\", end=\"\\n\\n\")\n\n# operadores lógicos ---------------------------------------------------------------------------------------------------\n\nverdadero: bool = (var_1 == \"1\" and var_2 == 1)\nfalso: bool = (var_1 == 1 and var_2 == \"1\")\n\nprint(\"LÓGICOS\")\nprint(f\"El operador 'and' evalúa que dos o más condiciones sean TODAs verdaderas:\")\nprint(f\"\\tvar_1 == '{var_1}' and var_2 == {var_2} => {verdadero}\")\nprint(f\"\\tvar_1 == {var_1} and var_2 == '{var_2}' => {falso}\")\n\nverdadero: bool = (var_1 == 7 or var_2 == 1)\nfalso: bool = (var_1 == 7 or var_2 == \"J\")\n\nprint(\"El operador 'or' evalúa que AL MENOS una de dos o más condiciones sea verdadera:\")\nprint(f\"\\t{var_1} == 7 or {var_2} == {var_2} => {verdadero}\")\nprint(f\"\\t{var_1} == 7 or {var_2} == 'J' => {falso}\")\n\nverdadero: bool = not falso\nfalso: bool = not verdadero\n\nprint(f\"El operador 'not devuelve Verdadero si la condición es falsa y viceversa:\")\nprint(f\"\\tnot falso => {verdadero}\")\nprint(f\"\\tnot verdadero => {falso}\", end=\"\\n\\n\")\n\n# más operadores de asignación  ----------------------------------------------------------------------------------------\n\nprint(\"Más sobre ASIGNACIÓN\")\n\nsaludo = \"Hola \"\nsaludo += \"Mundo!!!\"\n\nprint(f\"Con '+=' se asigna concatenando strings (saludo contiene 'Hola '): saludo += 'Mundo!!!' => {saludo}\")\n\nnumero_1 = 10\nnumero_1 += 3\n\nprint(f\"Con '+=' se asigna sumando (numero_1 contiene 10): numero_1 += 3 => {numero_1}\")\n\nnumero_1 = 10\nnumero_1 -= 3\n\nprint(f\"Con '-=' se asigna restando (numero_1 contiene 10): numero_1 -= 3 => {numero_1}\")\n\nnumero_1 = 10\nnumero_1 *= 3\n\nprint(f\"Con '*=' se asigna multiplicando (numero_1 contiene 10): numero_1 *= 3 => {numero_1}\")\n\nnumero_1 = 10\nnumero_1 /= 3\n\nprint(f\"Con '/=' se asigna dividiendo (numero_1 contiene 10): numero_1 /= 3 => {numero_1}\")\n\nnumero_1 = 10\nnumero_1 //= 3\n\nprint(f\"Con '//=' se asigna división entera (numero_1 contiene 10): numero_1 //= 3 => {numero_1}\")\n\nnumero_1 = 10\nnumero_1 %= 3\n\nprint(f\"Con '%=' se asigna el resto (numero_1 contiene 10): numero_1 %= 3 => {numero_1}\")\n\nnumero_1 = 10\nnumero_1 **= 3\n\nprint(f\"Con '**=' se asigna potencia (numero_1 contiene 10): numero_1 **= 3 => {numero_1}\", end=\"\\n\\n\")\n\n# operadores de pertenencia --------------------------------------------------------------------------------------------\n\nlista = [1, 2, 3, 4]\nsi_esta = 3 in lista\nno_esta = 3 not in lista\n\nprint(\"PERTENENCIA\")\n\nprint(f\"Con 'in' o 'not in' valida si un determinado valor está contenido, o no, dentro de un tipo compuesto (o cadena):\")\nprint(f\"\\t3 in {lista} => {si_esta}\")\nprint(f\"\\t3 not in {lista} => {no_esta}\")\nprint(f\"\\tl in {saludo} => {'l' in saludo}\")\nprint(f\"\\tL in {saludo} => {'L' in saludo}\", end=\"\\n\\n\")\n\n# operadores de identidad ----------------------------------------------------------------------------------------------\n\nsaludo_2 = saludo\nsaludo_identico = saludo is saludo_2\n\nprint(f\"IDENTIDAD\")\n\nprint(\"Con 'is' e 'is not' se evalúa si dos varialbes son la misma o no.\")\nprint(\"Dos variables 'inmutables' (tipos primitivos y tuplas) son la misma si tienen el mismo valor.\")\nprint(\"Dos variables 'mutables' (tipos compuestos excepto tupla) son la misma aún cuando una de ellas cambie.\", end=\" \")\nprint(\"Para que dos variables mutables sean distintas se sebe asignar una copia de una a la otra y no directamente.\", end=\" \")\nprint(\"Se dice que las variables 'inmutables' se pasan por 'valor' y las mutables por 'referencia'.\")\nprint(f\"\\tsaludo = {saludo} / saludo_2 = {saludo_2} => saludo is saludo_2 => {saludo_identico}\")\n\nsaludo_2 = saludo_2 + \" :)\"\nsaludo_identico = saludo is saludo_2\n\nprint(f\"\\tsaludo = {saludo} / saludo_2 = {saludo_2} => saludo is saludo_2 => {saludo_identico}\")\n\nlista_2 = lista\nlista_identica = lista is lista_2\n\nprint(f\"\\tlista = {lista} / lista_2 = {lista_2} => lista is lista_2 => {lista_identica}\")\n\nlista_2.append(5)\nlista_identica = lista is lista_2\n\nprint(f\"\\tlista = {lista} / lista_2 = {lista_2} => lista is lista_2 => {lista_identica}\")\n\nlista_2 = lista.copy()\nlista_2.append(5)\nlista_identica = lista is lista_2\n\nprint(f\"\\tlista = {lista} / lista_2 = {lista_2} => lista is lista_2 => {lista_identica}\")\n\n# operadodores de bits -------------------------------------------------------------------------------------------------\n\nval_1 = 7\nval_2 = 3\nbit_or = val_1 | val_2\nbit_xor = val_1 ^ val_2\nbit_and = val_1 & val_2\nbit_nor = ~val_1\nbit_izquierda = val_1 << 2\nbit_derecha = val_1 >> 2\n\nprint(\"BITS\")\n\nprint(f\"Los operadores operan bit a bit sobre cada una de las variables: {val_1} es '00111' y {val_2} es 00011''\")\nprint(f\"El operador '|' es un 'or': {val_1} | {val_2} => {bit_or}\")\nprint(f\"El operador '^' es un 'xor': {val_1} ^ {val_2} => {bit_xor}\")\nprint(f\"El operador '&' es un 'and': {val_1} & {val_2} => {bit_and}\")\nprint(f\"El operador '~' es un 'nor': ~{val_1} => {bit_nor}\")\nprint(f\"El operador '<<' es un 'desplazamiento a izquierda': {val_1} << 2 => {bit_izquierda}\")\nprint(f\"El operador '>>' es un 'desplazamiento a derecha': {val_1} >> 2 => {bit_derecha}\", end=\"\\n\\n\")\n\n\nprint(f\"{'='*10} ESTRUCTURAS DE CONTROL {'='*40}\", end=\"\\n\\n\")\n\n# control condicional --------------------------------------------------------------------------------------------------\n\nefectivo = 100\ntarjeta = 1000\ngasto = 123\n\nprint(f\"\"\"Control de flujo condicional: 'if' (si algo), 'elif' (si no algo más), 'else' (si no cualquier otra cosa):\ngasto = {gasto} / Límites: efectivo: {efectivo}, tarjeta: {tarjeta}, cheque: +{tarjeta} \nif gasto <= efectivo:\n    print(\"Pago en efectivo\")\nelif gasto <= tarjeta:\n    print(\"Pago con tarjeta\")\nelse:\n    print(\"Pago con cheque\")\nPago con tarjeta\n\"\"\")\n\nedad = 21\nlimite = 18\ncontrol = (\"Puede pasar\" if edad >= limite else \"No puede pasar\")\n\nprint(f\"\"\"Condicional por comprehensión:\nedad = {edad} / limite = {limite}\ncontrol = (\"Puede pasar\" if edad >= limite else \"No puede pasar\")\nprint(control) => {control}\n\"\"\", end=\"\\n\\n\")\n\nmusico = \"Mozart\"\n\nprint(f\"\"\"El control condicional 'match' (coincidir), case (ocurrencia):\nmusico = {musico}\nmatch musico:\n    case \"Bach\":\n        estilo = \"Barroco\"\n    case \"Beethoven\":\n        estilo = \"Romanticismo\"\n    case \"Mozart\":\n        estilo = \"Clásico\"\n     case _:                          # '_' indica default o else\n        estilo = \"Desconocido\"\n\"\"\")\nmatch musico:\n    case \"Bach\":\n        estilo = \"Barroco\"\n    case \"Beethoven\":\n        estilo = \"Romanticismo\"\n    case \"Mozart\":\n        estilo = \"Clásico\"\n    case _:\n        estilo = \"Desconocido\"\nprint(f\"{musico} corresponde al {estilo}\", end=\"\\n\\n\")\n\n# control de flujo en bucle o iterativo --------------------------------------------------------------------------------\n\nprint(\"\"\"El control 'while' se ejecuta mientras una condición dada sea verdadera:\ncontador = 10\nwhile contador > 0:\n    print(f\"Tiempo en {contador} y contando\")\n    contador -= 1\nprint(\"Lanzado\")\n\"\"\")\ncontador = 10\nwhile contador > 0:\n    print(f\"Tiempo en {contador} y contando\")\n    contador -= 1\nprint(\"Lanzado\", end=\"\\n\\n\")\n\nprint(\"\"\"El control 'for' se ejecuta para cada uno de los elemento de un iterable:\nfor contador in range(10, 0, -1):\n    print(f\"Tiempo en {contador} y contando\")\nprint(\"Lanzado\")\n\"\"\")\nfor contador in range(10, 0, -1):\n    print(f\"Tiempo en {contador} y contando\")\nprint(\"Lanzado\", end=\"\\n\\n\")\n\n# dificultad extra -----------------------------------------------------------------------------------------------------\n\nprint(\"\"\"DIFICULTAD EXTRA\n\nmi_lista = [x for x in range(10, 56) if (x % 2 == 0) and x != 16 and (x % 3 > 0)]\nprint(mi_lsta)\n\"\"\")\n\nmi_lista = [x for x in range(10, 56) if (x % 2 == 0) and x != 16 and (x % 3 > 0)]\nprint(mi_lista)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/nevaito.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\"\"\"\n\"\"\" \nOperadores\n \"\"\"\n# Operadores aritmeticos\nprint(f\"Suma: 10 + 3 = {10 + 3}\")\nprint(f\"Resta: 10 - 3 = {10 - 3}\")\nprint(f\"Multiplicacion: 10 * 3 = {10 * 3}\")\nprint(f\"Division: 10 / 3 = {10 / 3}\")\nprint(f\"Modulo: 10 % 3 = {10 % 3}\") # modulo es el resto de la division\nprint(f\"Exponente: 10 ** 3 = {10 ** 3}\") # elevar un numero\nprint(f\"Division entera: 10 // 3 = {10 // 3}\") # resultado numero entero\n\n# Operadores de comparacion\nprint(f\"Igualdad: 10 == 3 es {10 == 3}\")\nprint(f\"Desigualdad: 10 != 3 es {10 != 3}\")\nprint(f\"Mayor Que: 10 > 3 es {10 > 3}\")\nprint(f\"Menor Que: 10 < 3 es {10 < 3}\")\nprint(f\"Mayor o igual que: 10 >= 3 es {10 >= 3}\")\nprint(f\"Menor o igual que: 10 <= 3 es {10 <= 3}\")\n\n# Operadores logicos\nprint(f\"AND &&: 10 + 3 == 13 and 5 - 1 == 4 es {10 + 3 == 13 and 5 - 1 == 4}\") # se tienen q cumplir las dos condiciones para que sea true\nprint(f\"OR ||: 10 + 3 == 14 or 5 - 1 == 4 es {10 + 3 == 14 or 5 - 1 == 4}\") # se tiene que cumplir al menos una de las condiones para que sea true\nprint(f\"NOT !: not 10 + 3 == 14 es {not 10 + 3 == 14}\")\n\n# Operadores de asignacion\nmy_number = 11  #asignacion\nprint(my_number)\nmy_number += 1  #suma y asignacion\nprint(my_number)\nmy_number -= 1   #resta y asignacion\nprint(my_number)\nmy_number *= 2  #multiplicacion y asignacion\nprint(my_number)\nmy_number /= 2  #division y asignacion\nprint(my_number)\nmy_number %= 2  #modulo y asignacion\nprint(my_number)\nmy_number **= 1  #exponente y asignacion\nprint(my_number)\nmy_number //= 1  # Div entera y asignacion\nprint(my_number)\n\n# Operadores de identidad\nmy_new_number = my_number\nprint(f\"my_number is my_new_number es {my_number is my_new_number}\")\nprint(f\"my_number is not my_new_number es {my_number is not my_new_number}\")\n\n# Operadores de pertenencia\nprint(f\"'d' in 'David' = {'d' in 'David'}\")\nprint(f\"'b' not in 'David' = {'b' not in 'David'}\")\n\n# Operadores de bit\na = 10 # 1010\nb = 3 # 0011\nprint(f\"AND: 10 & 3 = {10 & 3}\") # 0010\nprint(f\"OR: 10 | 3 = {10 | 3}\") # 1011\nprint(f\"XOR: 10 ^ 3 = {10 ^ 3}\") # 1001\nprint(f\"NOT: ~10 = {~10}\")\nprint(f\"Desplazamiento a la derecha: 10 >> 2 = {10 >> 2}\") # 0010\nprint(f\"Desplazamiento a la izquierda: 10 << 2 = {10 << 2}\") # 101000\n\n\n\"\"\"\nEstructuras de control\n\"\"\"\n# Condicionales\n\nmy_string = \"Daviddd\"\n\nif my_string == \"David\":\n    print(\"my_string es 'David'\")\nelif my_string == \"Hoyos\":\n    print(\" my string es 'Hoyos'\")\nelse:\n    print(\"my_string no es 'David'ni 'Hoyos'\")\n\n# Iterativas\n\nfor i in range(11):\n    print(i)\n\ni = 0\n\nwhile i <= 10:\n    print(i)\n    i += 1\n\n# Manejo de excepciones\ntry:\n    print(10/0)\nexcept:\n    print(\"Se ha producido un error\")\nfinally:\n    print(\"Ha finalizo el manejo de excepciones\")\n\n\"\"\"\nExtra\n\"\"\"\nfor number in range(10, 56):\n    if number % 2 == 0 and number != 16 and number % 3 != 0:\n        print(number)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/nightblockchain30.py",
    "content": "# Operadores aritmeticos\nsuma = 5 + 5\nresta = 5 - 5\nmultiplicacion = 5 * 5\ndivision = 5 / 5\nmodulo = 5 % 5\nexponente = 5 ** 5\nprint(suma, resta, multiplicacion, division, modulo, exponente)\n\n# Operadores de asignacion\n\ny = 5\nx = 5\nprint(x)\nx += 5\nprint(x)\nx -= 5\nprint(x)\nx *= 5\nprint(x)\nx /= 5\nprint(x)\nx %= 5\nprint(x)\nx **= 5\nprint(x)\nx //= 5\nprint(x)\n\n# Operadores de comparacion\nprint(5 == 5)\nprint(5 != 5)\nprint(5 > 5)\nprint(5 < 5)\nprint(5 >= 5)\nprint(5 <= 5)\n\n# Operadores logicos\nprint(True and True)\nprint(True and False)\nprint(True or True)\nprint(True or False)\nprint(not True)\nprint(not False)\n\n# Operadores de identidad\nprint(5 is 5)\nprint(5 is not 5)\n\n# Estructuras de control\nif 5 == 5:\n    print(\"5 es igual a 5\")\nelse:\n    print(\"5 no es igual a 5\")\n    \nwhile 5 == 5:\n    print(\"5 es igual a 5\")\n    break\n\nfor i in range(5):\n    print(i)\n    \ntry:\n    print(5 / 0)\nexcept ZeroDivisionError:\n    print(\"No se puede dividir entre 0\")\n    "
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/njaimev.py",
    "content": "\n# Primero tenemos los operadores aritmeticos para realizar operaciones matematicas\n\na = 6\nb = 15\n\nprint(a + b)\nprint(a - b)\nprint(a * b)\nprint(b / a)\nprint(b % a)\nprint(a ** b)\nprint(b // a)\n\n# // sería una división entera sin decimales\n\n# Luego tenemos los operadores de asignación que se usan para asignar valores a variables\n\nasign_suma = 3 #suma y asigna\nasign_suma += 4 \nprint(asign_suma)\n\nasign_resta = 6 #resta y asigna\nasign_resta -= 2 \nprint(asign_resta)\n\nasign_mult = 2 #multiplica y asigna\nasign_mult *= 2 \nprint(asign_mult)\n\nasign_div = 12 #divide y asigna\nasign_div /= 10 \nprint(asign_div)\n\nasign_mod = 12 #modulo y asigna\nasign_mod %= 18 \nprint(asign_mod)\n\nasign_exp = 2 #exponenciacion y asigna\nasign_exp **= 2 \nprint(asign_exp)\n\nasign_div_e = 4 #division entera y asigna\nasign_div_e //= 3 \nprint(asign_div_e)\n\n# Tambien estan los operadores de comparacion\n# Usando las variable ya definidas a y b\n\nprint(a == b)\nprint(a != b)\nprint(a < b)\nprint(a > b)            # Esto dara como resultado un booleano\nprint(a <= b)\nprint(a >= b)\n\n# Operadores logicos para realizar operaciones logicas entre booleanos\n\na = False\nb = True\n\nprint(a and b)  #True si ambos son true\nprint(a or b)   #True si alguno es true\nprint(not b)  #Devuelve lo contrario (False)\n\n# Los operadores de identidad comprueban si dos objetos son el mismo (en memoria)\n\nlist_a = [1, 2, 3]\nlist_b = list_a\nlist_c = [1, 2, 3]\n\nprint(list_a is list_b) #True, el mismo contenido en la \"misma\" memoria\nprint(list_c is list_a) #False, los datos son los mismos pero ocupan memoria distinta\n\n# Operadores de pertenencia comprueban si un valor esta en una secuencia\n\nlist_x = [1, 2, 3, 4, 5, 6]\n\nprint(5 in list_x) #True\nprint(9 not in list_x) #True\n\n# Operadores de bits realizan operaciones logicas a nivel de bits\n\nnum_1 = 3 #0011\nnum_2 = 8 #1000\n\nprint(num_1 & num_2)\nprint(num_1 | num_2)\nprint(num_1 ^ num_2)\nprint(~num_2)\nprint(num_1 << num_2)\nprint(num_1 >> num_2)\n\n# If, if else, else\n\nnota = 4\n\nif nota > 4:\n    print(\"Apruebas\")\nelif nota < 4: \n    print(\"REPRUEBAS!\")\nelse:\n    print(\"nota morada uf\")\n\n# Bucle, para repetir un bloque de codigo hasta que se cumpla la condición\n\n# FOR\n\nnombres = [\"Ana\", \"Luis\", \"Carlos\"]\nfor nombre in nombres:\n    print(f\"Hola, {nombre}!\")\n\n# WHILE\n\nnumero = 0\nwhile numero <= 3:\n    print(numero)\n    numero += 1\n\n\n# EJERCICIO EXTRA \n\nfor num in range(10, 56):  # Recorre números del 10 al 55\n    if num % 2 == 0 and num != 16 and num % 3 != 0: #al dividir por 2 el num da 0 Y el numero es distinto a 16\n        print(num)                                  # Y el restante al dividir por 3 es distinto a 0\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/nlarrea.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\"\"\"\n\n# OPERADORES ARITMÉTICOS\n\nprint(3 + 4)    # Suma -> 7\nprint(3 - 4)    # Resta -> -1\nprint(3 / 4)    # División -> 0.75\nprint(3 // 4)   # División entera -> 0\nprint(3 * 4)    # Multiplicación -> 12\nprint(3 % 4)    # Módulo -> 3\nprint(3 ** 4)   # Potencia -> 81\n\n\n# OPERADORES LÓGICOS\n\nprint(True and False)   # AND -> False\nprint(True or False)    # OR -> True\nprint(not True)         # NOT -> False\n\n\n# OPERADORES DE COMPARACIÓN\n\nprint(3 > 4)    # Mayor que -> False\nprint(3 < 4)    # Menor que -> True\nprint(3 >= 4)   # Mayor o igual que -> False\nprint(3 <= 4)   # Menor o igual que -> True\n\nprint(3 == \"3\") # Igual que -> False\nprint(3 != \"3\") # Diferente a -> True\nprint(3 == 4)   # False\nprint(3 != 4)   # True\n\n\n# OPERADORES DE ASIGNACIÓN\n\nassign_sum = 7\nassign_sum += 3                 # Suma y asignación\nprint(assign_sum)               # 10\n\nassign_subtract = 7\nassign_subtract -= 4            # Resta y asignación\nprint(assign_subtract)          # 3\n\nassign_multiplication = 7\nassign_multiplication *= 2      # Multiplicación y asignación\nprint(assign_multiplication)    # 14\n\nassign_division = 7\nassign_division /= 2            # División y asignación\nprint(assign_division)          # 3.5\n\nassign_int_division = 7\nassign_int_division //= 2       # División entera y asignación\nprint(assign_int_division)      # 3\n\nassign_module = 7\nassign_module %= 2              # Módulo y asignación\nprint(assign_module)            # 1\n\nassign_pow = 7\nassign_pow **= 2                # Potencia y asignación\nprint(assign_pow)               # 49\n\n\n# OPERADORES DE PERTENENCIA\n\narr = [0, 1, 2, 3, 4]\nprint(3 in arr)         # True\nprint(11 in arr)        # False\n\n\n# OPERADORES DE BITS\n\nprint(3 & 4)        # AND -> 0\nprint(3 | 4)        # OR -> 7\nprint(3 ^ 4)        # XOR -> 7\nprint(~3)           # NOT -> -4\nprint(3 << 4)       # Desplazamiento a izquierda -> 48\nprint(3 >> 4)       # Desplazamiento a derecha -> 0\n\n\n# ESTRUCTURA DE CONTROL: if - else if - else\n\nscore = 8\n\nif score >= 5:\n    print(\"You have passed the exam!\")\nelif score < 5:\n    print(\"You haven't passed the exam...\")\nelse:\n    print(\"The scores are not available yet.\")\n\n\n# ESTRUCTURA DE CONTROL: for\nfor i in range(5):\n    print(i)\n\"\"\" Se imprimen los siguientes números:\n    0\n    1\n    2\n    3\n    4\n\"\"\"\n\n\n# ESTRUCTURA DE CONTROL: for (otro ejemplo con objetos)\n\nPERSON = {\n    \"name\": \"Naia\",\n    \"username\": \"nlarrea\",\n    \"age\": 25\n}\n\nfor key in PERSON:\n    # Se imprimen las claves:\n    print(key)\n\n    # Si quisiéramos imprimir los valores:\n    # print(PERSON[key])\n\n\"\"\" Se imprimen los siguientes strings:\n    name\n    username\n    age\n\"\"\"\n\n\n# ESTRUCTURA DE CONTROL: for (otro ejemplo con listas)\n\nNUM_LIST = ['hola', True, 7, ['a', 'b', 'c']]\n\nfor item in NUM_LIST:\n    print(item)\n\n\"\"\" Se imprime:\n    'hola'\n    True\n    7\n    [ 'a', 'b', 'c' ]\n\"\"\"\n\n\n# ESTRUCTURA DE CONTROL: while\n\ni = 0\nwhile i < 5:\n    print(i)\n    i += 1\n\n\"\"\" Se imprimen los siguientes números:\n    0\n    1\n    2\n    3\n    4\n\"\"\"\n\n\n# ESTRUCTURA DE CONTROL: try-except\n\ntry:\n    print(5 / 0)                                        # Esto es un error\n    raise Exception(\"This is another error\")            # No se lanza porque hay otro error antes\n    print(\"This is not printed\")\nexcept ZeroDivisionError as error:\n    print(f\"{type(error).__name__}: {error}\")           # ZeroDivisionError: division by zero\nexcept Exception as error:\n    print(error)\n\n\n# ESTRUCTURA DE CONTROL: try-except-finally\n\ntry:\n    raise ValueError(\"This is a custom error message\")\n    print(\"This is not printed\")\nexcept Exception as error:\n    print(f\"{type(error).__name__}: {error}\")           # ValueError: This is a custom error message\nfinally:\n    print(\"This is always printed\")                     # This is always printed\n\n\"\"\" try-except(-finally):\nEn estas estructuras se puede añadir el bloque 'else' que se ejecuta\nsiempre que en el 'try' no haya ocurrido ningún error. \"\"\"\n\n\n# EJERCICIO EXTRA\n\n\"\"\" DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n \"\"\"\n\nfor num in range(10, 55 + 1):\n    if (\n        num % 2 == 0 and\n        num != 16 and\n        num % 3 != 0\n    ):\n        print(num)\n\n\"\"\" Se imprimen los siguientes números:\n    10 \n    14 \n    20 \n    22 \n    26 \n    28 \n    32 \n    34 \n    38 \n    40 \n    44 \n    46 \n    50 \n    52\n\"\"\""
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/noaregui.py",
    "content": "\"\"\"\nTipos de operadores\n\"\"\"\n# Operadores aritméticos: Para realizar operaciones matemáticas básicas\nsuma = 4 + 2\nresta = 4 - 2\ndivision = 4 / 2\n\nmultiplicacion = 4 * 2\nmodulo = 4 % 2\nexponencial = 4 ** 2\ndivision_entera = 4 // 2\n\nprint(f\"Suma: 4 + 2 = {suma}\")\nprint(f\"Resta: 4 - 2 = {resta}\")\nprint(f\"Division: 4 / 2 = {division}\")\nprint(f\"Multiplicacion: 4 * 2 = {multiplicacion}\")\nprint(f\"Modulo: 4 % 2 = {modulo}\")\nprint(f\"Exponencial: 4 ** 2 = {exponencial}\")\nprint(f\"Division entera: 4 // 2 = {division_entera}\")\n\n# Operadores de comparación: Para evaluar si dos valores son iguales o no\nprint(f\"Iguales: 4 == 2 {4 == 2}\")\nprint(f\"Diferentes: 4 != 2 {4 != 2}\")\nprint(f\"Mayor: 4 > 2 {4 > 2}\")\nprint(f\"Menor: 4 < 2 {4 < 2}\")\nprint(f\"Mayor o igual: 4 >= 2 {4 >= 2}\")\nprint(f\"Menor o igual: 4 <= 2 {4 <= 2}\")\n\n# Operadores lógicos: Para realizar operaciones booleanas\nprint(f\"Operador AND se simboliza con &&: 5 + 1 == 6 and 2 + 10 = 12 es {\n      5 + 1 == 6 and 2 + 10 == 12}\")\nprint(f\"Operador OR se simboliza con ||: 5 + 1 == 6 and 2 + 10 = 12 es {\n      5 + 1 == 6 and 2 + 10 == 12}\")\nprint(f\"Operador NOT se simboliza con ! : 10 + 3 == 14 es {not 10 + 3 == 14}\")\n\n# Operadores de asignación: Para asignar valores a variables\nmi_numero = 5\nprint(f\"Asignacion = : {mi_numero}\")\n\nmi_numero = 5\nmi_numero += 2\nprint(f\"Asginacion de suma += 2 : {mi_numero}\")\n\nmi_numero = 5\nmi_numero -= 2\nprint(f\"Asignacion resta -= 2 : {mi_numero}\")\n\nmi_numero = 5\nmi_numero *= 3\nprint(f\"Asignacion multiplicacion *= 3 : {mi_numero}\")\n\nmi_numero = 5\nmi_numero /= 3\nprint(f\"Asignacion division /= 3 : {mi_numero}\")\n\nmi_numero = 5\nmi_numero %= 5\nprint(f\"Asignacion modulo %= 5 : {mi_numero}\")\n\nmi_numero = 5\nmi_numero **= 3\nprint(f\"Asignacion exponencial **= 3 : {mi_numero}\")\n\nmi_numero = 5\nmi_numero //= 5\nprint(f\"Asignacion division entera //= 5 : {mi_numero}\")\n\n# Operadores bit a bit\na = 10  # 1010\nb = 3  # 0011\n\n# 0010 = 2 al comparar si los dos bit son 1 se escribe\nprint(f\"AND: 10 & 3 = {10 & 3}\")\n\n# 1011 = 11 al comparar si uno de los dos es 1 se escribe\nprint(f\"OR: 10 | 3 = {10 | 3}\")\nprint(f\"XOR: 10 ^ 3 = {10 ^ 3}\")  # 1001 = 9 al comparar si son diferentes 1\nprint(f\"XOR: 10 ~ 3 = {~10}\")\nprint(f\"Desplazamiento a la derecha: 10 >> 2 = {\n      10 >> 2}\")\n# Pasa de 1010 a 0010 = 2\nprint(f\"Desplazamiento a la izquierda: 10 << 2 = {\n      10 << 2}\")\n# Pasa de 1010 a 101000 = 40\n\n# Operadores de identidad: Para verificar la identidad de los objetos\nmi_variable = 5\nnuestra_variable = 5\n\nmi_variable = nuestra_variable\nprint(f\"Operador is: {mi_variable is nuestra_variable}\")\nprint(f\"Operador is not: {mi_variable is not nuestra_variable}\")\n\n\n# Operadores de pertenencia: Para verificar si un elemento está en una lista\nlista1 = [1, 2, 3, 4]\nprint(f\"Operador de pertenencia in: Esta el numero 5 en la lista? {\n      5 in lista1}\")\nprint(f\"Operador de pertenencia not in: El numero 5 no esta en la lista {\n      5 not in lista1}\")\n\n\n\"\"\"\nCrea ejemplos que representen todos los \ntipos de estructuras de control\n\"\"\"\n\n# ESTRUCTURAS DE CONTROL CONDICIONALES: if, elif, else\nnumero = 5\n\nif numero > 0:\n    print(f\"El numero {numero} es positivo\")\nelif numero == 0:\n    print(f\"El numero {numero} es 0\")\nelse:\n    print(f\"El numero {numero} es negativo\")\n\n# ESTRUCTURAS DE CONTROL ITERATIVAS (bucle): for y while\n\n# for\nfrutas = [\"sandia\", \"piña\", \"melocoton\"]\nfor fruta in frutas:\n    print(fruta)\n\nnumeros = [1, 2, 3, 4, 5]\nfor numero in numeros:\n    print(numero)\n\n# ¿Quieres sumar un valor a cada número? Podemos hacerlo con variables de asignación\nnumeros = [1, 2, 3, 4, 5]\nfor numero in numeros:\n    numero += 10\n    print(numero)\n\n# Utilizando for con range\nfor i in range(5):\n    print(i)\n\n# while\nedad = int(input(\"Ingresa tu edad: \"))\nwhile edad < 18:\n    print(\"Eres menor de edad\")\n    edad = int(input(\"Ingresa tu edad: \"))\n\nprint(\"Eres mayor de edad\")\n\n# ESTRUCTURAS DE CONTROL DE SALTO: break, continue, pass\n\n# break\nfor i in range(10):  # 0, 1, 2, 3, 4, 5, 6, 7, 8, 9\n    if i == 5:  # 0, 1, 2, 3, 4\n        break\n    print(i * 2)  # 0, 2, 4, 6, 8\n\n# continue\nfor i in range(10):  # 0, 1, 2, 3, 4, 5, 6, 7, 8, 9\n    if i % 2 == 0:  # Si el numero es par\n        continue   # No lo imprimas. Imprime: 1, 3, 5, 7, 9\n    print(i ** 3)  # Elevando al cubo los números impares\n\n# pass\nfor i in range(10):\n    if i % 2 == 0:\n        pass\n    print(i)\n\n# ESTRUCTURAS DE CONTROL COMPUESTAS\n\n# Bucle con condicional\nfor i in range(5, 10):\n    if i % 2 == 0:\n        continue  # Solo impares\n    print(i)\n\n# Bucle anidado????\n\n# Bucle con break\nfor i in range(10):\n    if i == 8:\n        break\n    print(i)\n\n# ESTRUCTURA DE CONTROL DE EXCEPCIONES\ntry:\n    print(10/0)\nexcept:\n    print(\"Ha habido un error\")\nfinally:\n    print(\"Ha finalizado el manejo de excepciones\")\n\n'''\nCrea un programa que imprima por consola todos los números comprendidos\n entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3\n'''\nfor i in range(10, 56):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print(i)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/nox456.py",
    "content": "# OPERADORES ARITMÉTICOS\n\n# Suma\nn1 = 5 + 3 # 8\n\n# Resta\nn2 = 3 - 3 # 0\n\n# Multiplicación\nn3 = 10 * 2 # 20\n\n# División\nn4 = 10 / 3 # 3.3333333333333335\n\n# División entera\nn5 = 10 // 3 # 3\n\n# Exponenciación\nn6 = 2 ** 2 # 4\n\n# Modulo o Residuo\nn7 = 5 % 2 # 1\n\n# OPERADORES DE COMPARACIÓN\n\n# Mayor que...\nc1 = 5 > 3 # True\n\n# Menor que...\nc2 = 1 < 3 # True\n\n# Igual que...\nc3 = 5 == 5 # True\n\n# Mayor o igual que...\nc4 = 5 >= 30 # False\n\n# Menor o igual que...\nc5 = 3 <= 3 # True\n\n# Diferente que...\nc6 = 6 != 6 # False\n\n# OPERADORES LÓGICOS\n\n# Y (AND)\nl1 = (1 == 3) and (3 >= 3) # False\n\n# O (OR)\nl2 = (1 != 0) or (9 < 3) # True\n\n# Negación (NOT)\n\nl3 = not(9 == 9) # False\n\n# OPERADORES BINARIOS\n\n# & (AND binario)\nb1 = 5 & 5 # 0b101 & 0b101 = 0b101 = 5\n\n# | (OR binario)\nb2 = 3 | 9 # 0b11 | 0b1001 = 0b1011\n\n# ^ (XOR binario)\nb3 = 8 ^ 2 # 0b1000 ^ 0b10 = 0b1010\n\n# ~ (Binario inverso)\nb4 = ~3 # -4\n\n# << (Desplazamiento a la izquierda)\nb5 = 8 << 3 # 0b1000 << 3 = 0b1000000 = 64\n\n# >> (Desplazamiento a la derecha)\nb6 = 4 >> 2 # 0b100 >> 2 = 0b1 = 1\n\n# OPERADORES DE IDENTIDAD\n\n# is\ni1 = 5 is 5 # False\ni2 = [1,2] is [1,2] # False\n\n# is not\ni3 = 5 is not 5 # True\ni4 = [1,2] is not [1,2] # True\n\n# OPERADORES DE PERTENENCIA\n\n# in\np1 = 3 in [1,2,3] # True\np2 = [2,3] in [1,[2,3],4] # True\n\n# not in\np3 = 3 not in [1,2,3] # False\np4 = [2,3] not in [1,[2,3],4] # False\n\n# ESTRUCTURAS DE CONTROL\n\n# CONDICIONAL\na = 4\nb = 5\nif a > b:\n    print(f\"{a} es mayor que {b}\")\nelif a == b:\n    print(f\"{a} es igual a {b}\")\nelse:\n    print(f\"{b} es mayor que {a}\")\n\n# ITERATIVAS\n\n# WHILE\n\nc = 10\ni = 1\nwhile i <= c:\n    print(i)\n    i += 1\n\n# FOR\n\nd = [2,4,6,8,10]\n\nfor i in d:\n    print(i)\n\n\n# RETO OPCIONAL\n\ni = 10\nfinal = 55\nwhile i <= final:\n    if i != 16 and i % 3 != 0:\n        print(i)\n    i += 1\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/nwpablodeveloper.py",
    "content": "from os import system\nsystem(\"cls\")\n# 01 - OPERADORES Y ESTRUCTURAS DE CONTROL\n\n# OPERADOR DE ASIGNACIÓN ( = )\n\"\"\"\n    El signo = ( igual ) se utiliza para asignar el valor que se encuentra a su derecha ( 2do operando )\n    a a la variable que se encuentra a su izquierda ( 1er operando )\n\"\"\"\n\nvariable = \"contenido por acá\"\nnombre = \"pablo\"\nedad = \"35\"\n\n# OPERADORES DE CONCATENACIÓN ( + , f\" { } \" )\nprint(\"=========================================================================\")\nprint(\"OPERADORES DE CONCATENACIÓN\")\n\"\"\"\n    El signo + ( mas ) ademas de que sirve como signo aritmetico para realizar sumas tambien se utiliza\n    para realizar uniones de contenido\n\n    f \" { variables } \" podemos unir usando variables de diferentes tipos de datos\n\"\"\"\n\ntexto_concatenado_f = f\"Mi nombre es { nombre }  y tengo  { edad } años \"\nprint(texto_concatenado_f)\ntexto_concatenado_mas = \"Mi nombre es \" + nombre + \"  y tengo  \" + edad + \" años \"\nprint(texto_concatenado_mas)\n\n# OPERADORES ARITMETICOS ( +, -, *, **, /, //, % )\nprint(\"=========================================================================\")\nprint(\"OPERADORES ARITMETICOS\")\n\"\"\"\n    Los operadores aritmeticos se utilizan para llevar al cabo calculos matematicos\n\"\"\"\n\nnro1 = 7\nnro2 = 3\nprint(f\"Suma ( + )                  { nro1 } +  { nro2 }  = { nro1 + nro2 }\")       \nprint(f\"resta ( - )                 { nro1 } -  { nro2 }  = { nro1 - nro2 }\")       \nprint(f\"multiplicar ( * )           { nro1 } *  { nro2 }  = { nro1 + nro2 }\")       \nprint(f\"potencia ( ** )             { nro1 } ** { nro2 }  = { nro1 ** nro2 }\")       \nprint(f\"División ( / )              { nro1 } /  { nro2 }  = { nro1 / nro2 }\")       \nprint(f\"Coinciente entero ( // )    { nro1 } // { nro2 }  = { nro1 // nro2 }\")       \nprint(f\"Resto de la división ( % )  { nro1 } %  { nro2 }  = { nro1 % nro2 }\")      \n\n# OPERADORES DE COMPARACIÓN O RELACIONALES\nprint(\"=========================================================================\")\nprint(\"OPERADORES DE COMPARACIÓN\")\n\"\"\"\n    Los operadores de comparación dan como resultado un valor booleano\n\"\"\"\n\nprint(f\"Igualdad            ( 33 == 16)  { 33 == 16 } \")\nprint(f\"Desigual            ( 82 != 35)  { 83 != 35 } \")\nprint(f\"Mayor que           ( 25 > 53 )  { 25 > 53 }\")\nprint(f\"Menor que           ( 17 < 50 )  { 17 < 50 }\")\nprint(f\"Mayor o igual que   ( 56 >= 56 ) { 56 >= 56 }\")\nprint(f\"Menor o igual que   ( 70 <= 73 ) { 70 <= 73 }\")\n\n# OPERADORES LÓGICOS\nprint(\"=========================================================================\")\nprint(\"OPERADORES DE LÓGICOS\")\n\"\"\"\n    Los operadores lógicos dan como resultado un valor booleano luego de realizar la comparación\n    entreo otros 2 valores booleanos\n\"\"\"\n\nprint(f\"Pablo == Javier and 35 > 20     { \"Pablo\" == \"Javier\" and 35 > 20}\")\nprint(f\"Pablo != Javier and 35 > 20     { \"Pablo\" != \"Javier\" and 35 > 20}\")\nprint(f\"Pablo != Javier and 35 > 20     {not \"Pablo\" != \"Javier\" and 35 > 20}\")\nprint(f\"50 == 30 or 35 == 35            { 50 == 30 or 35 == 35 }\")\n\n# OPERADORES DE ASIGNACIÓN COMPUESTA\nprint(\"=========================================================================\")\nprint(\"OPERADORES DE ASIGNACIÓN COMPUESTA\")\n\"\"\"\n    Aplica el resultado de los operandos al primer operando\n\"\"\"\n\nnumero1 = 10\nnumero1 += 4\nprint(f\"10 += 4     { numero1 }\")\n\nnumero1 = 10\nnumero1 -= 4\nprint(f\"10 -= 4     { numero1 }\")\n\nnumero1 = 10\nnumero1 *= 5\nprint(f\"10 *= 5     { numero1 }\")\n\nnumero1 = 10\nnumero1 **= 3\nprint(f\"10 **= 9    { numero1 }\")\n\nnumero1 = 10\nnumero1 /= 3\nprint(f\"10 /= 3     { numero1 }\")\n\nnumero1 = 10\nnumero1 %= 3\nprint(f\"10 %= 3     { numero1 }\")\n\nnumero1 = 10\nnumero1 //= 3\nprint(f\"10 //= 3    { numero1 }\")\n\n# OPERADORES DE IDENTIDAD\nprint(\"=========================================================================\")\nprint(\"OPERADORES DE IDENTIDAD\")\n\"\"\"\n    Los operadores de identidad se usan para comparar si las variables ocupan\n    la misma dirección en memoria\n\"\"\"\n\nnumero2 = numero1\nprint(f\"numero1 is numero2      { numero1 is numero2 }\")\nprint(f\"numero1 is not numero2  { numero1 is  not numero2 }\")\n\n# OPERADORES DE PERTENENCIA\nprint(\"=========================================================================\")\nprint(\"OPERADORES DE PERTENENCIA\")\n\"\"\"\n    El operador de pertencia su usa para saber si algo pertenece a algo\n    por ejemplo si una letra esta dentro de una cadena de texto\n\"\"\"\n\nfrase = \"La pajara pinta a la sombra del verde limon\"\nprint(f\"'u' in { frase }          {'u' in frase} \")\nprint(f\"'u' not in { frase }      {'u' not in frase} \")\n\n# OPERADORES DE BIT \nnro  = 2    # 00010\nnro1 = 10   # 01010\nnro2 = 12   # 01100\nnro3 = 16   # 10000\n# El AND da como resultado 1 cuando los 2 bits a comprar es 1\nprint(f\"AND: 10 & 12 ( 01010 & 01100 )      = { 10 & 12}  ( 01000 )\")    # 01000\n\n# El OR al menos 1 de los 2 bits a comparar tiene que ser 1\nprint(f\"OR: 10 | 12  ( 01010 | 01100 )      = { 10 | 12 } ( 01110 )\")    # 01110\n\n# El XOR si los 2 bits a comparar son difierentes da como resultado 1\nprint(f\"XOR 16 ^ 12  ( 10000 ^ 01100 )      = { 16 ^ 12 } ( 11100 )\" )   # 11100\n\n# El DEPLAZAMIENOT rellena de 0 hacia la izquierda o hacia la derecha la cantidad que le indiquemos\nprint(f\"DESPLAZAR 12 << 2   ( 01010 << 2 )  = { 12 << 2 } ( 0110000 )\" )     # 0110000\nprint(f\"DESPLAZAR 16 << 12  ( 10000 << 4 )  = { 16 << 4 } ( 100000000 )\" )   # 100000000\n\n\n# ESTRUCTURAS DE CONTRO IF ELSEIF\nprint(\"=========================================================================\")\nprint(\"ESTRUCTURAS DE CONTRO IF ELSEIF\")\n\"\"\"\n    Se evaluan los 2 operandos y por medio de una respuestas booleana\n    elige continuar por un lado o por el otro\n\"\"\"\n\nnombre = \"Pablo\"\nif nombre == \"Pablo\":\n    print(\"El nombre es Pablo\")\nelif nombre == \"Romina\":\n    print(\"El nombre es Pablo\")\nelse:\n    print(\"El nombre es otro\")\n\n\n# CICLO FOR\nprint(\"=========================================================================\")\nprint(\"CICLO FOR\")\n\"\"\"\n    Se utiliza para repetir un bloque de codigo un X cantidad de veces\n\"\"\"\n\n# for variable_contadora in range(valor_inicial, valor_final, tamaño_paso:)\nfor i in range( 0, 31, 3 ):\n    print(i)\n\n\n# CICLO WHILE\nprint(\"=========================================================================\")\nprint(\"CICLO WHILE\")\n\"\"\"\n    Se repite un bloque de codigo mientras la condición sea TRUE\n\"\"\"\n\ni = 0\nwhile i <= 12:\n    print(i) \n    i += 2\n\n\n# MANEJO DE ERRORES\nprint(\"=========================================================================\")\nprint(\"MANEJO DE ERRORES\")\n\"\"\"\n    El manejo de errores se utiliza para caputar el error en una parte del programa\n    y luego seguir operando , por ejemplo un error del servidor\n\"\"\"\n\ntry:\n    print(\"aca no hay error\")\nexcept:\n    print(\"Aca hay un error \")\nfinally:\n    print(\"El finally es opcional y siempre se va a ejecutar\")\n\n\n\n# DIFICULTAD EXTRA\nprint(\"=========================================================================\")\nprint(\"DIFICULTAD EXTRA\")\n\nfor i in range( 10, 56 ):\n    if ( i  == 55 ): print(i)\n    if ( i % 2 != 0 or i == 16 or i % 3 == 0 ): continue\n    print(i)\n    \nprint(\"==================   FIN DEL RETO   =====================================\")\nprint(\"\\n\")"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/oniricoh.py",
    "content": "def obtener_numero(mensaje):\n    \"\"\"\n    Solicita al usuario que ingrese un número y lo devuelve.\n    \"\"\"\n    while True:\n        try:\n            return float(input(f\"{mensaje}: \"))\n        except ValueError:\n            print(\"Por favor, ingresa un número válido.\")\n\ndef imprimir_resultado(nombre_operacion, resultado):\n    \"\"\"\n    Imprime el resultado de una operación con su nombre.\n    \"\"\"\n    print(f\"{nombre_operacion}: {resultado}\")\n\ndef imprimir_comparacion(nombre_operacion, comparacion):\n    \"\"\"\n    Imprime el resultado de una comparación con su nombre.\n    \"\"\"\n    print(f\"{nombre_operacion}: {comparacion}\")\n\ndef operador_de_identidad(a, b):\n    \"\"\"\n    Verifica la identidad entre dos variables y devuelve el resultado como cadena.\n\n    Parameters:\n    - a (float): Primer variable.\n    - b (float): Segunda variable.\n\n    Returns:\n    str: Cadena que indica si las dos variables son iguales o distintas.\n    \"\"\"\n    return \"Las dos variables son iguales\" if a is b else \"Las dos variables son distintas\"\n\ndef operador_de_pertenencia(a):\n    \"\"\"\n    Verifica si un número pertenece a un rango y devuelve el resultado como cadena.\n\n    Parameters:\n    - a (float): Número a verificar.\n\n    Returns:\n    str: Cadena que indica si el número está en el rango o no.\n    \"\"\"\n    return f\"{a} {'está' if a in range(10, 20) else 'no está'} en el rango\"\n\ndef comparadores(a, b):\n    \"\"\"\n    Realiza comparaciones entre dos números y devuelve el resultado como cadena.\n\n    Parameters:\n    - a (float): Primer número.\n    - b (float): Segundo número.\n\n    Returns:\n    str: Cadena que describe el resultado de las comparaciones.\n    \"\"\"\n    resultado = []\n    if a == b:\n        resultado.append(\"a = b\")\n    if a != b:\n        resultado.append(\"a != b\")\n    if a > b:\n        resultado.append(\"a > b\")\n    if a < b:\n        resultado.append(\"a < b\")\n    if a >= b:\n        resultado.append(\"a >= b\")\n    if a <= b:\n        resultado.append(\"a <= b\")\n    return \", \".join(resultado)\n# Solicitar números al usuario\na = obtener_numero(\"Escribe un numero\")\nb = obtener_numero(\"Escribe otro numero\")\n\n# Operaciones\nimprimir_resultado(\"suma\", a + b)\nimprimir_resultado(\"resta\", a - b)\nimprimir_resultado(\"multiplicacion\", a * b)\nimprimir_resultado(\"exponente\", a ** b)\nimprimir_resultado(\"division\", a / b)\nimprimir_resultado(\"division_entera\", a // b)\nimprimir_resultado(\"resto_division\", a % b)\n\n# Comparaciones\nimprimir_comparacion(\"comparador_and\", int(a) & int(b))\nimprimir_comparacion(\"comparador_or\", int(a) | int(b))\nimprimir_comparacion(\"comparadores\", comparadores(a, b))\nimprimir_comparacion(\"operador_de_pertenencia\", operador_de_pertenencia(int(a)))\nimprimir_comparacion(\"operador_de_identidad\", operador_de_identidad(a, b))\n\n\n\n\nfor numero in range(10, 56):\n    if numero == 16:\n        continue\n    elif numero%3 == 0:\n        continue\n    elif numero%2 == 0:\n        print(numero)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/oriaj3.py",
    "content": "\"\"\"\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\"\"\"\n\n### Operadores aritméticos \na = 2\nb = 3 \n\n# Suma\nprint(f\"La suma de {a} + {b} es: {a+b}\")\n\n# Resta\nprint(f\"La resta de {a} - {b} es: {a-b}\")\n\n# Multiplicación\nprint(f\"La multiplicación de {a} * {b} es: {a*b}\")\n\n# División\nprint(f\"La división de {a} / {b} es: {a/b}\")\n\n# Módulo\nprint(f\"El módulo de {a} % {b} es: {a%b}\")\n\n# Exponente\nprint(f\"El exponente de {a} ** {b} es: {a**b}\")\n\n# División entera o Resto\nprint(f\"La división entera de {a} // {b} es: {a//b}\")\n\n### Operadores de comparación\na = 2\nb = 3\n\n# Igualdad\nprint(f\"¿{a} es igual a {b}?: {a==b}\")\n\n# Desigualdad\nprint(f\"¿{a} es desigual a {b}?: {a!=b}\")\n\n# Mayor que\nprint(f\"¿{a} es mayor que {b}?: {a>b}\")\n\n# Menor que \nprint(f\"¿{a} es menor que {b}?: {a<b}\")\n\n# Mayor o igual que\nprint(f\"¿{a} es mayor o igual que {b}?: {a>=b}\")\n\n# Menor o igual que\nprint(f\"¿{a} es menor o igual que {b}?: {a<=b}\")\n\n### Operadores lógicos\na = True\nb = False\n\n# AND\nprint(f\"¿{a} AND {b}?: {a and b}\")\n\n# OR\nprint(f\"¿{a} OR {b}?: {a or b}\")\n\n# NOT\nprint(f\"¿NOT {a}?: {not a}\")\n\n### Operadores de asignación\na = 2\nb = 3\n\n# Asignación\nprint(f\"¿a es igual a {a}?: {a}\")\n\n# Suma\na += b\nprint(f\"¿a += {b}?: {a}\")\n\n# Resta\na -= b\nprint(f\"¿a -= {b}?: {a}\")\n\n# Multiplicación\na *= b\nprint(f\"¿a *= {b}?: {a}\")\n\n# División\na /= b\nprint(f\"¿a /= {b}?: {a}\")\n\n# Módulo\na %= b\nprint(f\"¿a %= {b}?: {a}\")\n\n# Exponente\na **= b\nprint(f\"¿a **= {b}?: {a}\")\n\n# División entera\na //= b\nprint(f\"¿a //= {b}?: {a}\")\n\n### Operadores de identidad\n# Compara si una dirección de memoria es la misma\na = 2\nb = 2.0\n\n# is\nprint(f\"¿{a} is {b}?: {a is b}\")\n\n# is not\nprint(f\"¿{a} is not {b}?: {a is not b}\")\n\n### Operadores de pertenencia\na = 2\nb = 3\nc = [1, 2, 3, 4, 5]\n\n# in\nprint(f\"¿{a} in {c}?: {a in c}\")\n\n# not in\nprint(f\"¿{a} not in {c}?: {a not in c}\")\n\n### Operadores de bits\na = 10\nb = 11\n\n# AND\nprint(f\"¿{a} & {b}?: {a & b}\")\n\n# OR\nprint(f\"¿{a} | {b}?: {a | b}\")\n\n# XOR\nprint(f\"¿{a} ^ {b}?: {a ^ b}\")\n\n# NOT\nprint(f\"¿~{a}?: {~a}\")\n\n\nb = 2\n\n# Desplazamiento a la izquierda dos bits\nprint(f\"¿{a} << {b}?: {a << b}\")\n\n# Desplazamiento a la derecha dos bits \nprint(f\"¿{a} >> {b}?: {a >> b}\")\n\n### Estructuras de control condicionales\na = 2\nb = 3\n\n# if\nif a == b:\n    print(f\"¿{a} == {b}?: {a == b}\")\n\n# if-else\nif a == b:\n    print(f\"¿{a} == {b}?: {a == b}\")\nelse:\n    print(f\"¿{a} != {b}?: {a != b}\")\n\n# if-elif-else\nif a == b:\n    print(f\"¿{a} == {b}?: {a == b}\")\nelif a > b:\n    print(f\"¿{a} > {b}?: {a > b}\")\nelse:\n    print(f\"¿{a} < {b}?: {a < b}\")\n\n### Estructuras de control iterativas\na = 2\nb = 3\n\n# while\nwhile a < b:\n    print(f\"¿{a} < {b}?: {a < b}\")\n    a += 1\n\n# for\nfor i in range(a, b):\n    print(f\"¿{i} < {b}?: {i < b}\")\n\n### Estructuras de control de excepciones\na = 2\nb = 0\n\n# try-except\ntry:\n    print(f\"¿{a} / {b}?: {a / b}\")\nexcept ZeroDivisionError:\n    print(\"No se puede dividir entre 0\")\n\n# try-except-else\nb = 3\ntry:\n    print(f\"¿{a} / {b}?: {a / b}\")\nexcept ZeroDivisionError:\n    print(\"No se puede dividir entre 0\")\nelse:\n    print(f\"¿{a} / {b}?: {a / b}\")\nfinally:\n    print(\"Fin del manejo de excepciones\")\n    \n\n    \n### Ejercicio extra\n# * DIFICULTAD EXTRA (opcional):\n# Crea un programa que imprima por consola todos los números comprendidos\n# entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n#\n# Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\n# Solución 1\nfor i in range(10, 56):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print(i)\n\n# Solución 2\nfor i in range(10, 56, 2):\n    if i != 16 and i % 3 != 0:\n        print(i)\n\n# Solución 3\nfor i in range(10, 56, 2):\n    if i == 16 or i % 3 == 0:\n        continue\n    print(i)\n\n# Solución 4\nfor i in range(10, 56, 2):\n    if i == 16 or i % 3 == 0:\n        break\n    print(i)\n\n# Solución 5\ni = 10\nwhile i < 56:\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print(i)\n    i += 1\n\n# Solución 6\ni = 10\nwhile i < 56:\n    if i == 16 or i % 3 == 0:\n        i += 1\n        continue\n    print(i)\n    i += 1\n\n# Solución 7\ni = 10\nwhile i < 56:\n    if i == 16 or i % 3 == 0:\n        break\n    print(i)\n    i += 1\n\n# Solución 8\ni = 10\nwhile i < 56:\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print(i)\n    i += 2\n\n# Solución 9\ni = 10\nwhile i < 56:\n    if i == 16 or i % 3 == 0:\n        i += 2\n        continue\n    print(i)\n    i += 2\n\n# Solución 10\ni = 10\nwhile i < 56:\n    if i == 16 or i % 3 == 0:\n        break\n    print(i)\n    i += 2\n\n# Solución 11\ni = 10\nwhile i < 56:\n    if i % 2 != 0 or i == 16 or i % 3 == 0:\n        i += 1\n        continue\n    print(i)\n    i += 1"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/oscargeovannyrincon.py",
    "content": "'''/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */'''\nprint('OPERADORES DE ASIGNACION \\n')\nx=5\nprint(f'Asignacion de un valor, x={x}')\nx+=3\nprint(f'Operador += x+=3, x={x}')\nx-=3\nprint(f'Operador -= x-=3, x={x}')\nx*=3\nprint(f'Operador *= x*=3, x={x}')\nx/=3\nprint(f'Operador /= x/=3, x={x}')\nx%=3\nprint(f'Operador %= x%=3, x={x}')\nx=27\nx//=3\nprint(f'Operador //=, x=27, x//=3, x={x}')\nx**=3\nprint(f'Operador **= x**=3, x={x}')\nx=10\nx&=15\nprint(f'Operador &=, x={x}')\nx=10\nx|=5\nprint(f'Operador |=, x={x}')\nx=10\nx^=5\nprint(f'Operador ^=, x={x}')\nx>>=3\nprint(f'Operador >>= x>>=3, x={x}')\nx<<=3\nprint(f'Operador <<= x<<=3, x={x}')\n\nprint('\\nOPERADORES ARITMETICOS')\nx=15\ny=7\nz=x+y\nprint(f\"Operador +\\n{x}+{y}={z}\")\nz=x-y\nprint(f\"Operador -\\n{x}-{y}={z}\")\nz=x*y\nprint(f\"Operador *\\n{x}*{y}={z}\")\nz=x/y\nprint(f\"Operador /\\n{x}/{y}={z}\")\nz=x%y\nprint(f\"Operador %\\n{x}%{y}={z}\")\nz=x**y\nprint(f\"Operador **\\n{x}**{y}={z}\")\nz=80//6\nprint(f\"Operador //\\n{x}//{y}={z}\")\n\nprint('\\nOPERADORES COMPARACION')\nx=15\ny=7\nprint(f'x={x}, y={y}')\nprint(f'Operador  IGUAL ==\\nx==y=>{x==y}')\nprint(f'Operador NO ES IGUAL !=\\nx!=y=>{x!=y}')\nprint(f'Operador MAYOR QUE >\\nx>y=>{x>y}')\nprint(f'Operador de MENOR QUE <\\nx<y=>{x<y}')\nprint(f'Operador de MAYOR O IGUAL QUE >=\\nx>=y=>{x>=y}')\nprint(f'Operador de MENOR O IGUAL QUE <=\\nx<=y=>{x<=y}')\n\n\nprint('\\nOPERADORES LOGICOS')\nprint('3 > 2 and 4 > 3', 3 > 2 and 4 > 3) #true\nprint('3 > 2 and 4 < 3', 3 > 2 and 4 < 3) #false\nprint('3 < 2 and 4 < 3', 3 < 2 and 4 < 3) #false\nprint('True and True: ', True and True)#true\nprint('3 > 2 or 4 > 3', 3 > 2 or 4 > 3)  #true\nprint('3 > 2 or 4 < 3', 3 > 2 or 4 < 3)  #true\nprint('3 < 2 or 4 < 3', 3 < 2 or 4 < 3)  #false\nprint('True or False:', True or False)#true\nprint('not 3 > 2', not 3 > 2)     #false\nprint('not True=>', not True)      #false\nprint('not False=>', not False)     #true\nprint('not not True=>', not not True)  #true\nprint('not not False=>', not not False,'\\n')#false\n\n'''* - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.'''\n \n#       CONDICIONALES       #\n\nnum=9\nif num>=10 and num<=20:\n    print('Su numero esta entre 10 y 20, incluidos')\nelif num<10:\n    print('El numero es menor que 10')\nelse:\n    print('El numero es mayor que 20')\n\n#       ITERATIVAS      #\n\nnumeros=list(range(0,20))\nprint(f'Esta es la lista {numeros}')\nindice=0\nprint('Estos son los numeros divisibles por 3 de la lista')\nwhile indice<25:\n    if indice<len(numeros):\n        variable=numeros[indice]\n        if variable%3==0:\n            print(numeros[indice])\n        indice+=1\n    else:\n        print('Se acabo el ciclo while')\n        break\n\nfrutas=['Melón', 'Ciruela', 'Melocotón', 'Nectarina', 'Sandía', 'Cereza', 'Uva', 'Higos', 'Albaricoque', 'Naranja', 'Mango', 'Aguacate', 'Níspero', 'Mora']\nprint(f'Esta es una lista de frutas, {frutas}')\nprint('Estas son las frutas en indices pares')\nfor indice_1 in range(len(frutas)):\n    if indice_1%2==0:\n        print(f'Indice {indice_1}, fruta {frutas[indice_1]}')\n        \n#       EXCEPCIONES     #\n\n#print(\"Realizaremos una division de dos numero\\nIngresa el primer numero\")\nnumero_1=input(\"Realizaremos una division de dos numero\\nIngresa el primer numero: \")\n#numero_1=float(numero_1)\n#print( \"Ingrese el segundo numero\")\nnumero_2=(input(\"Ingrese el segundo numero: \"))\n#numero_2=int(numero_2)\n#print(f'El resultado de la divion {numero_1}/{numero_2} es {numero_1/numero_2}')\ntry:\n    #print(f'El resultado de la divion {numero_1}/{numero_2} es {int(numero_1/numero_2)}')\n    print(f'El resultado de la divion {numero_1}/{numero_2} es {float(numero_1)/float(numero_2)}')\nexcept ValueError:\n    print('Error de valor')\nexcept ZeroDivisionError:\n    print('Error division por cero')\nelse:\n    print('Impresion correcta')\nfinally:\n    print('Fin del programa de control')\n    \n\n'''/*\n* DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */'''\nnumbers=list(range(10,56))\n#print(numbers)\nfor number in numbers:\n    if number%2==0:\n        if number!=16:\n            if number%3!=0:\n                print(number)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/oscarhub90.py",
    "content": "\n\n# Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n\nprint(\"\\nOperadores aritméticos\\n\")\n\nnumero1 = 13\nnumero2 = 8\n\nresultado = print(f\"El resultado de la suma (+) es: {numero1+numero2}\")\nresultado = print(f\"El resultado de la resta (-) es: {numero1-numero2}\")\nresultado = print(f\"El resultado de la multiplicación (*)es: {numero1*numero2}\")\nresultado = print(f\"El resultado de la división (/) es: {numero1/numero2}\")\nresultado = print(f\"El resultado de la división entera (//) es: {numero1 // numero2}\")\nresultado = print(f\"El resultado de la multiplicación xponencial (**) es: {numero1 ** numero2}\")\nresultado = print(f\"El resultado del módulo (%) es: {numero1 % numero2}\")\n\n# *******Operadores de comparación*******\n\nprint(\"\\nOperadores de comparación\\n\")\n\nresultado = print(f\"¿Ambos números son iguales (==)?: {numero1 == numero2}\")\nresultado = print(f\"¿Ambos números son diferentes (!=)?: {numero1 != numero2}\")\nresultado = print(f\"el primer número es mayor que el segundo (>)?: {numero1 > numero2}\")\nresultado = print(f\"el primer número es menor que el segundo (<)?: {numero1 < numero2}\")\nresultado = print(f\"el primer número es mayor o igual que el segundo (>=)?: {numero1 >= numero2}\")\nresultado = print(f\"el primer número es menor o igual que el segundo (<=)?: {numero1 <= numero2}\")\n\n#*******Operadore Logicos*******\n\nprint(\"\\nOperadores lógicos\\n\")\n\n# AND - se evalúan x condicioes y todas deben ser verdaderas\nresultado = print(f\"¿El primer número es mayor que el segundo Y (AND) el segundo número es impar? : {numero1 > numero2 and numero2 %2 != 0 }\")\n\n# OR - se evalúan x condicioes y al menos una debe ser verdadera\nresultado = print(f\"¿el primer número es mayor que el segundo O (OR) el segundo número es impar? : {numero1 > numero2 or numero2 %2 != 0 }\")\n\n# NOT -se evalúan x condicioes y el resultado es la negación de la evaluación\nresultado = print(f\"Negación (NOT) ¿El primer número es mayor que el segundo Y el segundo número es impar? : {numero1 > numero2 or numero2 %2 != 0 }\")\n\n#*******Operadore de pertencia*******\n\nprint(\"\\nOperadores de pertenencia\\n\")\n\nedades = [21, 18, 33, 28]\n\n# in - evalua si un vaalor está en la lista\nprint(edades)\nprint(f\"El número 44 está (IN) en la lista? {44 in edades} \")\n\n# not in - evalua si un vaalor está NO la lista\nprint(f\"El número 44 NO está (NOT IN) en la lista? {44 not in edades} \")\n\n# *******operadores e Identidad *******\n#- Usados para comprobar si dos variables son el mismo objeto en memoria\n\nedades2 = [12, 17, 23, 18, 33]\nedades3 = [12, 17, 23, 18, 33]\nedades4 = edades2\n\n# IS - valida si dos variables son el mismo objeto \n\nprint(f\"¿edades2 ES el mismo objeto (IS) que edades3 ? {edades2 is edades3}\")\nprint(f\"¿edades2 ES el mismo objeto que edades4 ? {edades2 is edades4}\")\n\n# IS NOT - valida si dos variables NO SON el mismo objeto\n\nprint(f\"¿edades2 NO ES el mismo objeto (IS NOT) que edades3 ? {edades2 is not edades3}\")\n\n# ******Operadores de bit*******\n\nprint(\"\\nOperadores de bit\\n\")\n# - Permiten realizar operaciones de bit en números enteros, compara bit a bit y devuelve el resultado en entero.\n\nnumber1 = 10 # binario 1010\nnumber2 = 7 # binario 0111\n\nprint(\"AND = valdrá 1 si ambos bit son =1 (&): \", number1 & number2) # resultante 0010 = 2\nprint(\"OR = valdrá 1 si al menos un bit es =1 (|): \", number1 | number2) # resultante 1111 = 15\nprint(\"XOR = valdrá 1 los bit son diferentes (^): \", number1 ^ number2 ) # resultante 1101 = 13\nprint(\"NOT = invierte bit por bit (~)\", ~number2)\nprint(\"Desplazamientro a la izquierda (<<): \", 10 << 2 )\nprint(\"Desplazamientro a la derecha(>>): \", 10 >> 2 )\n\n\n#*******Estructuras de control*******\n\n# Condicionales\n\nprint(\"\\nEstructuras de control\\n Condicionales: \\n\")\n\nedad1= 17\n\nif edad1 >= 18:\n  print(\"Mayor de edad, puede ingresar.\")\nelse:\n  print(\"Menor de edad no puede ingresar.\\n\")\n\n# CicloS\n\nedades_clase = [12,13,14,22,33,14,58,23,45,17]\nprint(\"edades de la clase impresas con el ciclo for. \")\nfor edad in edades_clase:\n  print(edad)\n\n\ncontador = 0\nwhile contador < 10:\n  print(\"Ciclo while contador \",  contador)\n  contador += 1\n\n\nfor i in range (10):\n  if i % 2 ==0:\n    print(i)\n\n# control de exxcepciones\n\nnumero = 18\ntry:\n  resultado = numero / 0 # Esta división no es posible\nexcept:\n  print(\"Verifique los valores y operación\")\nfinally:\n  print(\"Manejo de excepción try, except y finally terminado.\")\n\n#Ejercicio de dificultad extra#\n\"\"\"\nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\"\"\"\nfor i in range(10,56):\n\n  if i != 16 and i %3 != 0 and i%2 == 0:\n    print(i, end=\" - \")\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/pabloche73.py",
    "content": "# Operadores aritméticos\n\nprint(\"eradores aritméticos\")\nprint()\nprint(\"Suma: 3 + 2 = \", 3 + 2)\nprint(\"Resta: 3 - 2 = \", 3 - 2)\nprint(\"Multiplicación: 3 * 2 = \", 3 * 2)\nprint(\"División: 3 / 2 = \", 3 / 2)\nprint(\"División entera: 3 // 2 = \", 3 // 2)\nprint(\"Módulo: 3 % 2 = \", 3 % 2)\nprint(\"Potencia: 3 ** 2 = \", 3 ** 2)\n\n# Operadores de comparación\n\nprint()\nprint(\"Operadores de comparación\")\nprint()\nprint(\"Igualdad: 3 == 2 = \", 3 == 2)\nprint(\"Diferencia: 3 != 2 = \", 3 != 2)\nprint(\"Mayor que: 3 > 2 = \", 3 > 2)\nprint(\"Menor que: 3 < 2 = \", 3 < 2)\nprint(\"Mayor o igual que: 3 >= 2 = \", 3 >= 2)\nprint(\"Menor o igual que: 3 <= 2 = \", 3 <= 2)\n\n# Operadores lógicos\n\nprint()\nprint(\"Operadores lógicos\")\nprint()\nprint(\"And: True and False = \", True and False)\nprint(\"Or: True or False = \", True or False)\nprint(\"Not: not True = \", not True)\n\n# Operadores de asignación\n\nprint()\nprint(\"Operadores de asignación\")\nprint()\na = 11\nprint(\"a = 11\") # Asignación\na += 2\nprint(\"a += 2: \", a) # Suma\na -= 2\nprint(\"a -= 2: \", a) # Resta\na *= 2\nprint(\"a *= 2: \", a) # Multiplicación\na /= 2\nprint(\"a /= 2: \", a) # División\na //= 2\nprint(\"a //= 2: \", a) # División entera\na %= 2\nprint(\"a %= 2: \", a) # Módulo\na **= 2\nprint(\"a **= 2: \", a) # Potencia\n\n# Operadores de identidad\n\nprint()\nprint(\"Operadores de identidad\")\nprint()\na = 11\nb = 11\nprint(\"a = 11, b = 11\")\nprint(\"a is b: \", a is b)\nprint(\"a is not b: \", a is not b)\n\n# Operadores de pertenencia\n\nprint()\nprint(\"Operadores de pertenencia\")\nprint()\nlista = [1, 2, 3, 4, 5]\nprint(\"lista = [1, 2, 3, 4, 5]\")\nprint(\"1 in lista: \", 1 in lista)\nprint(\"1 not in lista: \", 1 not in lista)\nprint(\"6 in lista: \", 6 in lista)\nprint(\"6 not in lista: \", 6 not in lista)\n\n# Operadores de bits\nprint()\nprint(\"Operadores de bits\")\nprint()\nprint(\"AND: 5 & 3 = \", 5 & 3) # 101 & 011 = 001\nprint(\"OR: 5 | 3 = \", 5 | 3) # 101 | 011 = 111\nprint(\"XOR: 5 ^ 3 = \", 5 ^ 3) # 101 ^ 011 = 110\nprint(\"Desplazamiento a la izquierda: 5 << 3 = \", 5 << 3) # 101 << 3 = 101000\nprint(\"Desplazamiento a la derecha: 5 >> 3 = \", 5 >> 3) # 101 >> 3 = 000\nprint(\"Inversión: ~5 = \", ~5) # ~101 = 010\n\n# Estructuras de control\n\n# Condicional if\nprint()\nprint(\"Condicional if\")\nprint()\n\na = 2\nif a > 3:\n    print(\"a es mayor que 3\")\nelif a == 3:\n    print(\"a es igual a 3\")\nelse:\n    print(\"a es menor que 3\")\n\n# Bucle while\nprint()\nprint(\"Bucle while\")\nprint()\na = 0\nwhile a < 5:\n    print(a)\n    a += 1\n\n# Bucle for\nprint()\nprint(\"Bucle for\")\nprint()\nfor i in range(5):\n    print(i)\n\n# Exception\nprint()\nprint(\"Exception\")\nprint()\ntry:\n    a = 1 / 0\nexcept ZeroDivisionError:\n    print(\"Error: división por cero\")\nfinally:\n    print(\"Finalizado\")\n\n# Extra\nprint()\nprint(\"Extra\")\nprint()\nfor i in range(10,56):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print (i)\n\n# THE END"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/pablosalme.py",
    "content": "#operadores aritmeticos y asignacion\n\n#suma\nprint(\"SUMA\")\nsuma = 10 + 15\nprint(suma)\nsuma += 10\nprint(f\"Suma + 10 = {suma}\")\n\n#resta\nprint(\"\\nRESTA\")\nresta = 15 - 10\nprint(resta)\nresta -= 5\nprint(f\"Resta - 5 = {resta}\")\n\n#multiplicacion\nprint(\"\\nMULTIPLICACION\")\nmult = 5 * 2\nprint(mult)\nmult *= 2\nprint(f\"mult x 2 = {mult}\")\n\n#division\nprint(\"\\nDIVISION\")\ndiv = 20 / 2\nprint(div)\ndiv /= 10\nprint(f\"div / 10 = {div}\")\n\n#modulo\nprint(\"\\nMODULO\")\nmod = 10 % 2\nprint(mod)\nmod %= 1\nprint(f\"mod % 1 = {mod}\")\n\n#exponente\nprint(\"\\nEXPONENTE\")\nexp = 2 ** 2\nprint(exp)\nexp **= 2\nprint(f\"exp ** 2 = {exp}\")\n\n#cociente\nprint(\"\\nCOCIENTE\")\ncoc = 100 // 2\nprint(coc)\ncoc //= 2\nprint(f\"coc // 2 = {coc}\")\n\n#operadores logicos\n\n#and\nprint(\"\\nAND\")\nprint(\"True and False = \", True and False)\n#or\nprint(\"\\nOR\")\nprint(\"True or True = \", True or True)\n#not\nprint(\"\\nNOT\")\nprint(\"not True = \", not True)\n\n#operadores de comparación\n\n#identico\nprint(\"\\nIDENTICO\")\nprint(\"1 == 2 = \", 1 == 2)\n#distinto\nprint(\"\\nDISTINTO\")\nprint(\"1 != 2 = \", 1 != 2)\n#mayor\nprint(\"\\nMAYOR QUE\")\nprint(\"1 > 2 = \", 1 > 2)\n#menor\nprint(\"\\nMENOR QUE\")\nprint(\"1 < 2 = \", 1 < 2)\n#mayor o igual\nprint(\"\\nMAYOR O IGUAL\")\nprint(\"1 >= 2 = \", 1 >= 2)\n#menor o igual\nprint(\"\\nMENOR O IGUAL\")\nprint(\"1 <= 2 = \", 1 <= 2)\n\n# Definición de variables\na = 'Hola'\nb = 'Hola'\nc = [0, 1, 2]\nd = [0, 1, 2]\n\n# Operador is\nprint(\"\\nIS\")\nprint(f\"a is b: {a is b}\")  # True\nprint(f\"id(a) == id(b): {id(a) == id(b)}\")  # True\n\nprint(f\"c is d: {c is d}\")  # False (hace referencia al id, y son listas diferentes aunque con el mismo contenido)\nprint(f\"id(c) == id(d): {id(c) == id(d)}\")  # False (muestra que son objetos diferentes)\n\n# Operador is not\nprint(\"\\nIS NOT\")\nprint(f\"a is not b: {a is not b}\")  # False (son el mismo objeto)\nprint(f\"c is not b: {c is not b}\")  # True (son diferentes tipos de objetos)\n\n# Definición de la lista\nx = [1, 2, 3, 4]\n\n# Operador in\nprint(f\"1 in x: {1 in x}\")  # True (1 está en la lista x)\nprint(f\"123 in x: {123 in x}\")  # False (123 no está en la lista x)\n\n# Operador not in\nprint(f\"1 not in x: {1 not in x}\")  # False (1 está en la lista x, así que no es verdad que no esté)\nprint(f\"123 not in x: {123 not in x}\")  # True (123 no está en la lista x, así que es verdad que no esté)\n\n# Definición de variables\na = 10  # 1010 en binario\nb = 4   # 0100 en binario\n\n# Operador AND (&)\nprint(\"\\nAND\")\nresult = a & b\nprint(f\"{a} & {b} = {result} (binario: {bin(result)})\")\n# Operador OR (|)\nprint(\"\\nOR\")\nresult = a | b\nprint(f\"{a} | {b} = {result} (binario: {bin(result)})\")\n# Operador XOR (^)\nprint(\"\\nXOR\")\nresult = a ^ b\nprint(f\"{a} ^ {b} = {result} (binario: {bin(result)})\")\n# Operador NOT (~)\nprint(\"\\nNOT\")\nresult = ~a\nprint(f\"~{a} = {result} (binario: {bin(result)})\")\n# Desplazamiento a la izquierda (<<)\nprint(\"\\nDESP. IZQ.\")\nresult = a << 2\nprint(f\"{a} << 2 = {result} (binario: {bin(result)})\")\n# Desplazamiento a la derecha (>>)\nprint(\"\\nDESP. DER.\")\nresult = a >> 2\nprint(f\"{a} >> 2 = {result} (binario: {bin(result)})\")\n\nprint(\"ESTRUCTURAS DE CONTROL\")\n#IF\nprint(\"IF\")\nif 1 < 2:\n    print(\"1 < 2\")\nelse:\n    print(\"1 > 2\")\n\n#ITERATIVAS (FOR)\nprint(\"FOR\")\nfor i in range(10):\n    print(i)\n\n    print(\"ESTRUCTURAS DE CONTROL\")\n\n# IF\nprint(\"IF\")\nif 1 < 2:\n    print(\"1 < 2\")\nelse:\n    print(\"1 > 2\")\n\n# ITERATIVAS (FOR)\nprint(\"FOR\")\nfor i in range(10):\n    print(i)\n\n# EXCEPCIONES\nprint(\"EXCEPCIONES\")\ntry:\n    resultado = 10 / 0\nexcept ZeroDivisionError as e:\n    print(f\"Ocurrió una excepción: {e}\")\nfinally:\n    print(\"Esto se ejecuta siempre, haya o no una excepción\")\n\nprint(\"El programa continúa ejecutándose después de manejar la excepción\")\n\n''' * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.'''\n\nfor i in range(10, 51):\n    if (i % 2 == 0) and (i != 16) and (i % 3 != 0):\n        print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/pakiuh.py",
    "content": "# Operadores en Python\r\nprint(\"Operadores en Python:\")\r\n\r\n# Aritméticos\r\nprint(\"\\nOperadores aritméticos:\")\r\nprint(\"5 + 2 =\", 5 + 2)\r\nprint(\"5 - 2 =\", 5 - 2)\r\nprint(\"5 * 2 =\", 5 * 2)\r\nprint(\"5 / 2 =\", 5 / 2)\r\nprint(\"5 % 2 =\", 5 % 2)\r\nprint(\"5 ** 2 =\", 5 ** 2)\r\nprint(\"5 // 2 =\", 5 // 2)\r\n\r\n# Lógicos\r\nprint(\"\\nOperadores lógicos:\")\r\nprint(\"True and False =\", True and False)\r\nprint(\"True or False =\", True or False)\r\nprint(\"not True =\", not True)\r\n\r\n# Comparación\r\nprint(\"\\nOperadores de comparación:\")\r\nprint(\"5 == 2 =\", 5 == 2)\r\nprint(\"5 != 2 =\", 5 != 2)\r\nprint(\"5 > 2 =\", 5 > 2)\r\nprint(\"5 < 2 =\", 5 < 2)\r\nprint(\"5 >= 2 =\", 5 >= 2)\r\nprint(\"5 <= 2 =\", 5 <= 2)\r\n\r\n# Asignación\r\nprint(\"\\nOperadores de asignación:\")\r\na = 5\r\nprint(\"a = 5 -> a =\", a)\r\na += 2\r\nprint(\"a += 2 -> a =\", a)\r\na -= 2\r\nprint(\"a -= 2 -> a =\", a)\r\na *= 2\r\nprint(\"a *= 2 -> a =\", a)\r\na /= 2\r\nprint(\"a /= 2 -> a =\", a)\r\na %= 2\r\nprint(\"a %= 2 -> a =\", a)\r\na **= 2\r\nprint(\"a **= 2 -> a =\", a)\r\na //= 2\r\nprint(\"a //= 2 -> a =\", a)\r\n\r\n# Identidad\r\nprint(\"\\nOperadores de identidad:\")\r\nprint(\"5 is 2 =\", 5 is 2)\r\nprint(\"5 is not 2 =\", 5 is not 2)\r\n\r\n# Pertenencia\r\nprint(\"\\nOperadores de pertenencia:\")\r\nprint(\"5 in [1, 2, 3] =\", 5 in [1, 2, 3])\r\nprint(\"2 not in [1, 2, 3] =\", 2 not in [1, 2, 3])\r\n\r\n# Bits\r\nprint(\"\\nOperadores de bits:\")\r\nprint(\"5 & 2 =\", 5 & 2)\r\nprint(\"5 | 2 =\", 5 | 2)\r\nprint(\"5 ^ 2 =\", 5 ^ 2)\r\nprint(\"~5 =\", ~5)\r\nprint(\"5 << 2 =\", 5 << 2)\r\nprint(\"5 >> 2 =\", 5 >> 2)\r\n\r\n# Estructuras de control en Python\r\nprint(\"\\nEstructuras de control en Python:\")\r\n\r\n# Condicionales\r\nprint(\"\\nCondicionales:\")\r\nif 5 > 2:\r\n    print(\"5 es mayor que 2\")\r\nelse:\r\n    print(\"5 no es mayor que 2\")\r\n\r\n# Iterativas\r\nprint(\"\\nIterativas:\")\r\nfor i in range(5):\r\n    print(i)\r\n\r\n# Excepciones\r\nprint(\"\\nExcepciones:\")\r\ntry:\r\n    print(5 / 0)\r\nexcept ZeroDivisionError:\r\n    print(\"No se puede dividir por cero\")\r\n\r\n# Programa que imprime por consola todos los números comprendidos entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3\r\nprint(\"\\nPrograma que imprime por consola todos los números comprendidos entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3:\")\r\nfor i in range(10, 56):\r\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\r\n        print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/pakomor.py",
    "content": "\n\n# operadores Aritmeticos\n\nsuma = 80 + 13\nresta = 80 - 13\ndivision = 80 / 13\nmultiplicacion = 80 + 13\nmodulo = 80 % 13\nexponente = 80 ** 13\ndivision_entera = 80 // 13\n\nprint(suma)\nprint(resta)\nprint(division)\nprint(multiplicacion)\nprint(modulo)\nprint(exponente)\nprint(division_entera)\n\n\n# Operador Comparacion\n\nigual = 80 == 13\ndiferente = 80 != 13\nmayor = 80 > 13\nmenor = 80 < 13\nmayor_igual = 80 >= 13\nmenor_igual = 80 <= 13\n\nprint(igual)\nprint(diferente)\nprint(mayor)\nprint(menor)\nprint(mayor_igual)\nprint(menor_igual)\n\n# Operadores logicos\n\n# Ejemplo con operador AND\nedad = 39\ningreso_mensual = 1500\n\nif edad > 18 and ingreso_mensual > 2000:\n    print(\"Eres mayor de edad y tu ingreso es suficiente.\")\nelse:\n    print(\"No cumples con los requisitos.\")\n\n# Ejemplo con operador OR\nnombre = \"Fran\"\napellido = \"Moreno\"\n\nif nombre == \"Alice\" or apellido == \"Jones\":\n    print(\"Eres una maquina tete.\")\nelse:\n    print(\"No eres quien dices que eres.\")\n\n# Ejemplo con combinación de operadores lógicos\nedad = 39\ntiene_trabajo = True\ntiene_ahorros = False\n\nif edad > 18 and (tiene_trabajo or tiene_ahorros):\n    print(\"Cumples con los requisitos para el préstamo.\")\nelse:\n    print(\"No cumples con los requisitos para el préstamo.\")\n\n# Operadores de asignación\n\nmy_number = 11  # asignación\nprint(my_number)\nmy_number += 1  # suma y asignación\nprint(my_number)\nmy_number -= 1  # resta y asignación\nprint(my_number)\nmy_number *= 2  # multiplicación y asignación\nprint(my_number)\nmy_number /= 2  # división y asignación\nprint(my_number)\nmy_number %= 2  # módulo y asignación\nprint(my_number)\nmy_number **= 1  # exponente y asignación\nprint(my_number)\nmy_number //= 1  # división entera y asignación\nprint(my_number)\n\n\n# Ejemplo de condicional (if-else)\nedad = 20\n\nif edad >= 18:\n    print(\"Eres mayor de edad.\")\nelse:\n    print(\"Eres menor de edad.\")\n\n# Ejemplo de condicional anidado\npuntuacion = 60\n\nif puntuacion >= 90:\n    print(\"Excelente compadre\")\nelif puntuacion >= 70:\n    print(\"Buen trabajo loko\")\nelse:\n    print(\"Necesitas mejorar, dejate de ChatGpt\")\n\n# Ejemplo de bucle while\ncontador = 0\n\nwhile contador < 5:\n    print(f\"Contador: {contador}\")\n    contador += 1\n\n# Ejemplo de bucle for\nfor i in range(3):\n    print(f\"Iteración {i}\")\n\n# Iterar sobre una lista\ncolores = [\"rojo\", \"verde\", \"azul\"]\n\nfor color in colores:\n    print(color)\n\n# Programa que imprime números entre 10 y 55, pares, y no son ni el 16 ni múltiplos de 3\n\nfor numero in range(10, 56):\n    # Verificar si el número es par y no es ni el 16 ni múltiplo de 3\n    if numero % 2 == 0 and numero != 16 and numero % 3 != 0:\n        print(numero)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/pcosin.py",
    "content": "# Operadores Aritméticos\n\nprint(4 + 5) # adición\nprint(5 - 5) # resta\nprint(7 * 5) # multiplicación\nprint(9 / 4) # división\nprint(10 % 2) # módulo\nprint(4**2) # exponente\nprint(9 // 3) # división entera \n\n# Operadores de comparación\n\nprint(8 > 4) # Mayor qué\nprint(8 < 4) # Menor qué\nprint(8 <= 4) # Menor igual qué\nprint(8 >= 4) # Mayor igual qué\nprint(8 == 4) # Igualdad\nprint(8 != 4) # Desigualdad\n\n# Operadores lógicos\n\nprint(8 > 4 and 4 != 2) #Operador and\nprint(8 < 4 or 2 == 2) #Operador or\nprint(not 4 == 2) #Operador not\n\n# Operadores de asignación\n\nvar_num = 10 # asignación\nprint(var_num)\nvar_num += 3 #asignación y suma\nprint(var_num)\nvar_num -= 3 #asignación y resta\nprint(var_num)\nvar_num *= 2 #asignación y multiplicación\nprint(var_num)\nvar_num **= 2 #asignación y exponente\nprint(var_num)\nvar_num //= 2 #asignación y división entera\nprint(var_num)\nvar_num %= 2 #asignación y módulo\nprint(var_num)\n\n\n# Operadores de identidad\nprint(\"2 is 2 =\", 2 is 2)\nprint(\"4 is not 2 =\", 4 is not 2)\n\n# Operadores de pertenencia\nprint(\"8 in [1, 2, 3] =\", 8 in [1, 2, 3])\nprint(\"8 not in [1, 2, 3] =\", 8 not in [1, 2, 3])\n\n# Operadores de bits\nprint(\"\\nOperadores de bits:\")\nprint(\"5 & 2 =\", 5 & 2)\nprint(\"5 | 2 =\", 5 | 2)\nprint(\"5 ^ 2 =\", 5 ^ 2)\nprint(\"~5 =\", ~5)\nprint(\"5 << 2 =\", 5 << 2)\nprint(\"5 >> 2 =\", 5 >> 2)\n\n# Condicionales\n\nvar_cond_1 = 10\nvar_cond_2 = 20\n\nif var_cond_1 > var_cond_2:\n    print(f\"{var_cond_1} es mayor\")\nelif var_cond_1 < var_cond_2:     \n    print(f\"{var_cond_2} es mayor\")\nelse:\n    print(\"Los números son iguales\")\n\n# Bucles\n    \n# While\n\ni = 0\n\nwhile (i < 5):\n    print(i)\n    i += 1\n\n# for\n    \n    for i in range(10):\n        print(i)\n\n# Extra\n        \nfor numero in range(10, 50):\n    if numero % 2 == 0 and numero != 16 and numero % 3 != 0:\n        print(numero)         \n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/pedro-blasco.py",
    "content": "a = float(input(\"Introduce el valor de a: \")) # El input devuelve un string con el valor introducido por el usuario\nb = float(input(\"Introduce el valor de b: \")) # El input devuelve un string con el valor introducido por el usuario\n\n\n\"\"\"\nOperadores Aritmeticos:\n\"\"\"\nSuma = a + b # La suma devuelve el resultado de sumar a y b\nResta = a - b # La resta devuelve el resultado de restar b a a\nMultiplicacion = a * b # La multiplicacion devuelve el resultado de multiplicar a por b\nDivision = a / b # La division devuelve un numero decimal aunque el resultado sea un numero entero\nDivision_Entera = a // b # La division entera devuelve el resultado de dividir a entre b sin decimales, redondeando hacia abajo\nExponente = a ** b # El exponente devuelve el resultado de elevar a a la potencia de b\nModulo = a % b # El modulo devuelve el resto de la division entre a y b\n\n\"\"\"\nOperadores de Asignacion:\n\"\"\"\n\nx = 5 # El operador de asignacion \"=\" asigna el valor de 5 a la variable x\nx += 3 # El operador de asignacion \"+=\" suma 3 al valor actual de x y asigna el resultado a x\nx -= 2 # El operador de asignacion \"-=\" resta 2 al valor actual de x y asigna el resultado a x\nx *= 4 # El operador de asignacion \"*=\" multiplica el valor actual de x por 4 y asigna el resultado a x\nx /= 2 # El operador de asignacion \"/=\" divide el valor actual de x entre 2 y asigna el resultado a x\nx //= 3 # El operador de asignacion \"//=\" divide el valor actual de x entre 3 sin decimales y asigna el resultado a x\nx **= 2 # El operador de asignacion \"**=\" eleva el valor actual de x a la potencia de 2 y asigna el resultado a x\nx %= 4 # El operador de asignacion \"%=\" calcula el resto de dividir el valor actual de x entre 4 y asigna el resultado a x\n\n\"\"\"\nOperadores de Comparacion:\n\"\"\"\n\na_igual_a_b = a == b # El operador de comparacion \"==\" devuelve True si a es igual a b, False en caso contrario\na_par = a % 2 == 0 # El operador de comparacion \"==\" devuelve True si a es par, False en caso contrario\na_distinto_de_b = a != b # El operador de comparacion \"!=\" devuelve True si a es distinto de b, False en caso contrario\na_menor_que_b = a < b # El operador de comparacion \"<\" devuelve True si a es menor que b, False en caso contrario\na_menor_o_igual_a_b = a <= b # El operador de comparacion \"<=\" devuelve True si a es menor o igual a b, False en caso contrario\na_mayor_que_b = a > b # El operador de comparacion \">\" devuelve True si a es mayor que b, False en caso contrario\na_mayor_o_igual_a_b = a >= b # El operador de comparacion \">=\" devuelve True si a es mayor o igual a b, False en caso contrario\n\n\"\"\"\nOperadores Logicos:\n\"\"\"\n\n# El operador logico \"and\" devuelve True si ambas condiciones son True, False en caso contrario\n\ncondicion1 = a > 0 and b > 0 # Devuelve True si a es mayor que 0 y b es mayor que 0, False en caso contrario\n\n# El operador logico \"or\" devuelve True si al menos una de las condiciones es True, False en caso contrario\n\ncondicion2 = a > 0 or b > 0 # Devuelve True si a es mayor que 0 o b es mayor que 0, False en caso contrario\n\n# El operador logico \"not\" devuelve True si la condicion es False, False si la condicion es True\n\ncondicion3 = not(a > 0) # Devuelve True si a no es mayor que 0, False si a es mayor que 0\n\n\"\"\"\nOperadores de Pertenencia e Identidad:\n\"\"\"\n\n# El operador de pertenencia \"in\" devuelve True si el elemento esta en la secuencia, False en caso contrario\n\ny = [1, 2, 3, 4, 5] # Lista de numeros del 1 al 5\npertenencia = 3 in y # Devuelve True si el numero 3 esta en la lista y, False en caso contrario\n\n# Se puede utilizar \"not in\" para comprobar si un elemento no esta en la secuencia\n\n# El operador de identidad \"is\" devuelve True si ambas variables apuntan al mismo objeto en memoria, False en caso contrario\n\na = [1, 2, 3] # Lista de numeros del 1 al 3\nb = [3, 2, 1] # Lista de numeros del 3 al 1\nidentidad = a is b # Devuelve False porque a y b son listas diferentes en memoria, aunque tengan los mismos elementos\nindentidad2 = a is not b # Devuelve True porque a y b son listas diferentes en memoria, aunque tengan los mismos elementos\n\n# No creo necesario agregar los operadores bit a bit porque son mas avanzados y actualmente no los comprendo\n\n# Print de todos los ejemplos anteriores para comprobar que funcionan correctamente\nprint(\"Operadores Aritmeticos:\")\nprint(\"Suma:\", Suma)\nprint(\"Resta:\", Resta)\nprint(\"Multiplicacion:\", Multiplicacion)\nprint(\"Division:\", Division)\nprint(\"Division Entera:\", Division_Entera)\nprint(\"Exponente:\", Exponente)\nprint(\"Modulo:\", Modulo)\nprint(\"\\nOperadores de Asignacion:\")\nprint(\"x:\", x)\nprint(\"\\nOperadores de Comparacion:\")\nprint(\"a igual a b:\", a_igual_a_b)\nprint(\"a es par:\", a_par)\nprint(\"a distinto de b:\", a_distinto_de_b)\nprint(\"a menor que b:\", a_menor_que_b)\nprint(\"a menor o igual a b:\", a_menor_o_igual_a_b)\nprint(\"a mayor que b:\", a_mayor_que_b)\nprint(\"a mayor o igual a b:\", a_mayor_o_igual_a_b)\nprint(\"\\nOperadores Logicos:\")\nprint(\"condicion1 (a > 0 and b > 0):\", condicion1)\nprint(\"condicion2 (a > 0 or b > 0):\", condicion2)\nprint(\"condicion3 (not(a > 0)):\", condicion3)\nprint(\"\\nOperadores de Pertenencia e Identidad:\")\nprint(\"pertenencia (3 in y):\", pertenencia)\nprint(\"identidad (a is b):\", identidad)\nprint(\"identidad2 (a is not b):\", indentidad2)\n\n\"\"\" \nDIFICULTAD EXTRA (OPCIONAL): Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n \"\"\"\n \nprint(\"\\nDificultad Extra:\")\nprint(\"\\nNúmeros comprendidos entre 10 y 55, pares, y que no son ni el 16 ni múltiplos de 3:\")\nfor i in range(10, 56): # Itera numeros desde el 10 al 55\n    if i % 2 == 0 and i != 16 and i % 3 != 0: # Comprueba que el numero es par, no es 16 y no es multiplo de 3\n        print(i) # Imprime el numero si cumple las condiciones"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/pguillo02.py",
    "content": "#En python existen las principales aritmético-lógicas propias de la computación\n\n#Suma, resta, multiplicación y división\nprint(2-1)\n\nprint(2*2)\n\nprint(4/2)\n\nprint(1+1)\n\n#Aglutinadores\n\n2==0 and 1==1\n\n3==3 or 2==4\n\n#También encontramos comparaciones lógicas\n\nprint(1==1)\n\nprint(1<0)\n\nprint(2>1)\n\nprint(1<=0)\n\nprint(2>=1)\n\nprint(1!=0)\n\n#También tenemos operaciones especiales como los módulos o la divisón entera\n\nprint(1%1)\n\nprint(1//1)\n\n#En lo que a listas se refiere contamos con sentencias de permanencia y existencia\n\n1 in [1,2,3] \n\n1 is int\n\n#En lo que a estructuras de control contamos con la típica clausa if que se emplea para manejara flujos de control\n\nif 1==1:\n    print(\"Caso afirmativo\")\nelif 1 == 0:\n    print(\"Caso secundario\")\nelse:\n    print(\"caso negativo\")\n\n\n#Además, contamos con los típicos bucles iterativos for y while\n\nfor item in range(10):\n    print(item)\n\ni=0\n\nwhile i<10:\n    print(i)\n    i+=1\n\n#Optativo\n\nfor item in range(10, 56):\n    if item != 16 and item % 3 != 0 and item % 2 == 0:\n        print(item)\n        \n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/pipngpop.py",
    "content": "\"\"\"\nOperadores\n\"\"\"\n\n#Operadores aritmeticos\nprint(f\"Suma: 10 + 3 = {10+3}\")\nprint(f\"Resta: 10 - 3 = {10-3}\")\nprint(f\"Multiplicación: 10 x 3 = {10*3}\")\nprint(f\"División: 10 / 3 = {10/3}\")\nprint(f\"Módulo: 10 % 3 = {10%3}\")\nprint(f\"Exponencial: 10 ** 3 = {10**3}\")\nprint(f\"División entera: 10 // 3 = {10//3}\")\n\n#Operadores de comparación\nprint(f\"Igualdad: 10 == 3 es {10==3}\")\nprint(f\"Desigualdad: 10 != 3 es {10!=3}\")\nprint(f\"Mayor que: 10 > 3 es {10>3}\")\nprint(f\"Menor que: 10 < 3 es {10<3}\")\nprint(f\"Mayor o igual que: 10 >= 3 es {10>=3}\")\nprint(f\"Menor o igual que: 10 <= 3 es {10<=3}\")\n\n\n#Operadores lógicos\nprint(f\"AND &&: 10 + 3 == 13 and 5 - 1 == 4 es {10+3==13 and 5-1==4}\")\nprint(f\"OR ||: 10 + 3 == 13 or 5 - 1 == 3 es {10+3==13 or 5-1==3}\")\nprint(f\"NOT !: not 10 + 3 == 14 es {not 10+3==14}\")\n\n\n#Operadores de asignación\nmy_number=11 #asignación\nprint(my_number)\nmy_number+=1 #suma y asignación\nprint(my_number)\nmy_number-=1 #resta y asignación\nprint(my_number)\nmy_number*=2 #multiplicación y asignación\nprint(my_number)\nmy_number/=2 #división y asignación\nprint(my_number)\nmy_number%=2 #módulo y asignación\nprint(my_number)\nmy_number**=1 #exponente y asignación\nprint(my_number) \nmy_number//=1 #división entera y asignación\nprint(my_number)\n\n\n# Operadores de identidad\nmy_new_number=my_number\nprint(f\"my_number is my_new_number es {my_number is my_new_number}\")\nprint(f\"my_number is not my_new_number es {my_number is not my_new_number}\")\n\n\n# Operadores de pertenencia\nprint(f\"'u' in 'moure'={'u' in 'moure'}\")\nprint(f\"'b' not in 'moure'={'b' not in 'moure'}\")\n\n\n# Opreadores de bit\na =10 # en bits 1010\nb = 3 # en bits 11\nprint(f\"AND: 10 & 3 = {10 & 3}\") #0010\nprint(f\"OR: 10 | 3 = {10 | 3}\") #1011\nprint(f\"XOR: 10 ^ 3 = {10 ^ 3}\") #1001\nprint(f\"NOT: -10 = {-10}\")\nprint(f\"Desplazamiento a la derecha 10 >> 2 = {10 >> 2}\") #0010\nprint(f\"Desplazamiento a la izquierda 10 << 2 = {10 << 2}\") #101000\n\n'''\n Estructuras de control\n'''\n\n# Condicionales\n\nmy_string = \"Mouredev\"\n\nif my_string == \"Mouredev\":\n    print(\"my_string is 'Mouredv'\")\nelif  my_string == \"Brais\":\n    print(\"my string is 'Brais'\")\nelse:\n    print(\"my_string no es 'Mouredev' ni 'Brais'\")\n\n\n# Iterativas\n\nfor i in range(11):\n    print(i)\n\ni = 0\n\nwhile i <= 10:\n    print(i)\n    i += 1\n\n\n# Manejo de excepciones\ntry:\n    print(10 / 0)\nexcept:\n    print(\"Se ha producido un error\")\nfinally:\n    print(\"Ha  finalizado el manejo de excepciones\")\n\n\n'''\nExtra\n'''\n'''\n Crea un programa que imprima por consola todos los números comprendidos\n entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n '''\n\n#mi solución\nn=10\nwhile n <= 55:\n    if n%2==0:\n        if n!=16:\n            if n%3!=0:\n                 print(n)\n    n += 1\n\n#su solución\nfor number in range (10, 56):\n    if number % 2 == 0 and number != 16 and number % 3 != 0:\n        print (number)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/pirrin22.py",
    "content": "\nnumero1 = 10\nnumero2 = 5\n# Operadores Aritmeticos\n\nprint(numero1 + numero2) # Suma\nprint(numero1 - numero2) # Resta\nprint(numero1 * numero2) # Multiplicacion\nprint(numero1 / numero2) # Division\nprint(numero1 % numero2) # Modulo\nprint(numero1 ** numero2) # Potencia\nprint(numero1 // numero2) # Division entera\n\n# Operadores relacionales\n\nprint(numero1 == numero2) # Igualdad\nprint(numero1 != numero2) # Diferente\nprint(numero1 > numero2) # Mayor que \nprint(numero1 < numero2) # Menor que  \nprint(numero1 >= numero2) # Mayor o igual que\nprint(numero1 <= numero2) # Menor o igual que\n\n# Operadors Bit a Bit\n\nprint(numero1 & numero2) # AND\nprint(numero1 | numero2) # OR\nprint(numero1 ^ numero2) # XOR\nprint(~numero1) # NOT\nprint(numero1 << 2) # Desplazamiento a la izquierda\nprint(numero1 >> 2) # Desplazamiento a la derecha\n\n# Operadores de Asignacion\n\na = 5\na += 5 # a = a + 5\nprint(a)\na -= 5 # a = a - 5\nprint(a)\na *= 5 # a = a * 5\nprint(a)\na /= 5 # a = a / 5\nprint(a)\na %= 5 # a = a % 5\nprint(a)\na **= 5 # a = a ** 5\nprint(a)\na //= 5 # a = a // 5\nprint(a)\na //= 5 # a = a // 5\nprint(a)\n\n# Operadores Logicos\n\nif numero1 > 5 and numero2 < 10:\n    print(\"Se cumple la condicion\")\n\nif numero1 > 5 or numero2 < 10:\n    print(\"Se cumple la condicion\")\n\nif not numero2 > 5:\n    print(\"Se cumple la condicion\")\n\n#Operadores de Pertenencia\n\nmy_list = [1, 2, 3, 4, 5, 6]\n\n\nif 1 in my_list:\n    print('True')\n\nif 10 not in my_list:\n    print('True')\n\n\n# Operadores de Identidad\n\nx = 7\ny = 7\nz = 3\n\nprint(x is y)\nprint(x is not y)\nprint(x is not z)\n\n\n# Estructura de control condicinal\n\nmy_variable1 = 4\n\nif my_variable1 > 10:\n    print(\"La variable es mayor a 10\")\nelif my_variable1 < 10:\n    print(\"La variable es menor a 10\")\nelse:\n    print(\"La variable es igual a 10\")\n\n# Estructura de control iterativa\n\nfor i in 'Esternoclidomastoideo':\n    print(i)\n\nwhile my_variable1 < 10:\n    print(my_variable1)\n    my_variable1 += 1\n\n\n# Estructura de control de excepciones\n\ntry:\n    print(10/0)\nexcept ZeroDivisionError:\n    print(\"No se puede dividir por cero\")\nfinally:\n    print(\"Se termino la ejecucion\")\n\n\n\n# Ejercicio dificultad extra\n\ndef numeros():\n    for i in range(10, 56):\n       if i % 2 == 0 and i != 16 and i % 3 != 0:\n              print(i)\n\n        \n\nnumeros()\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/pyramsd.py",
    "content": "'''\nCrea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\nAritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n'''\n\nvar_a = 3\nvar_b = 5\n\n# aritmeticos\nprint('Operadores aritmeticos:')\nprint(f'Suma {var_a} + {var_b} = {var_a + var_b}')\nprint(f'Resta {var_a} - {var_b} = {var_a - var_b}')\nprint(f'Multiplicación {var_a} * {var_b} = {var_a * var_b}')\nprint(f'Division {var_a} / {var_b} = {var_a / var_b}')\nprint(f'Division entera {var_a} // {var_b} = {var_a // var_b}')\nprint(f'Modulo {var_a} % {var_b} = {var_a % var_b}')\nprint(f'Potencia {var_a} ** {var_b} = {var_a ** var_b}')\n\nprint()\n\n# de asignacion\nnumero = 6\nprint('Operadores de asignacion')\nprint('numero = 6')\nnumero += 3\nprint(f'numero += 3 es {numero}')\nnumero -= 1\nprint(f'numero -= 1 es {numero}')\nnumero /=2\nprint(f'numero /= 2 es {numero}')\nnumero *= 3\nprint(f'numero *= 3 es {numero}')\nnumero **=2\nprint(f'numero **=2 es {numero}')\nnumero //=3\nprint(f'numero //=3 es {numero}')\nnumero %=2\nprint(f'numero %=2 es {numero}')\n\nprint()\n\n# de comparacion\nprint('Operadores de comparacion')\nprint(f'{var_b} == {var_b} -> {var_a == var_b}')\nprint(f'{var_b} != {var_b} -> {var_a != var_b}')\nprint(f'{var_b} < {var_b} -> {var_a < var_b}')\nprint(f'{var_b} > {var_b} -> {var_a > var_b}')\nprint(f'{var_b} <= {var_b} -> {var_a <= var_b}')\nprint(f'{var_b} >= {var_b} -> {var_a >= var_b}')\n\nprint()\n\n# operadores logicos\nprint('operadores logicos')\na = (var_a == var_b)\nb = (var_a <= var_b)\nc = (var_a >= var_b)\n\nprint(f'a or b es {a or b}')\nprint(f'a and c es {a and b}')\nprint(f'not a es {not a}')\nprint(f'not b es {not b}')\nprint(f'not c es {not c}')\n\nprint()\n\n# bits\nprint('Operadores a nivel de bits')\n\nvar_a = 6\nvar_b = 4\n\nprint(f'and binario: {var_a} & {var_b} -> {var_a & var_b}')\nprint(f'or binario: {var_a} | {var_b} -> {var_a | var_b}')\nprint(f'exclusivo binario: {var_a} ^ {var_b} -> {var_a ^ var_b}')\nprint(f'not binario: ~{var_a} -> {~var_a}')\nprint(f'not binario: ~{var_b} -> {~var_b}')\nprint(f'desplazamiento a la izquierda: {var_a} << 2 -> {var_a << 2}')\nprint(f'desplazamiento a la derecha: {var_a} >> 2 -> {var_a >> 2}')\nprint(f'representacion binaria de un entero: bin(5) -> {bin(5)}')\n\nprint()\n\n# Operadores de pertenencia\nprint('Operadores de pertenencia')\nlista = [1,2,3,4,5,6,7,8]\nnum = 9\nnum_2 = 4\n\nprint(f'operador in: {num_2} in {lista} -> {num_2 in lista}')\nprint(f'operador not in: {num} not in {lista} -> {num not in lista}')\n\nprint()\n\n# Operador de identidad\nprint('Operador de identidad')\na = 1\nb = 1\n\nprint(a is b)\n\nprint()\n\n'''\nUtilizando las operaciones con operadores que tú quieras, crea ejemplos\nque representen todos los tipos de estructuras de control que existan\nen tu lenguaje:\n'''\n# condicionales if, elif y match\nprint('condicionales if, elif y match')\n#   if\nif 5 < 4:\n    print('5 es menor que 4')\nelse: \n    print('5 es mayor que 4')\n\n#   elif\nif 4 < 3:\n    print('El 3 es mayor')\nelif 4 > 3:\n    print('El 4 es el mayor')\nelse:\n    print('Los numeros son iguales')\n\n#   match\ndia = 'lunes'\nmatch dia:\n    case 'lunes':\n        print('Es lunes')\n    case 'martes':\n        print('Es martes')\n    case 'miercoles':\n        print('Es miercoles')\n    case 'jueves':\n        print('Es jueves')\n    case 'viernes':\n        print('Es viernes')\n    case _:\n        print('Ninguno')\n    \nprint()\n\nprint('Bucles for y while')\n# Bucles for y while\n\n#   bucle for\niter = 0\nfor i in range(10):\n    iter +=1\n    print(iter)\n\nprint()\n\n#   bucle while\niter = 0\nwhile iter < 10:\n    iter += 1\n    print(iter)\n\nprint()\n\nprint('Excepciones')\n\ntry:\n    div_by_0 = 3/0\n    print(div_by_0)\nexcept ZeroDivisionError as e:\n    print(f'error: {e}')\n\n'''\nDIFICULTAD EXTRA (opcional):\nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n'''\n\nprint()\n\nprint('Programa extra')\nfor i in range(10, 56):\n    if i == 16:\n        pass\n    elif not(i % 3 == 0) and i % 2 == 0:\n        print(i)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/qv1ko.py",
    "content": "a = 3\nb = 4\n\nsum = a + b\nprint(f\"Number A + Number B = {sum}\")\n\nsub = a - b\nprint(f\"Number A - Number B = {sub}\")\n\nmul = a * b\nprint(f\"Number A * Number B = {mul}\")\n\ndiv = a / b\nprint(f\"Number A / Number B = {div}\")\n\nres = a % b\nprint(f\"Number A % Number B = {res}\")\n\npow = a ** b\nprint(f\"Number A ** Number B = {pow}\")\n\nflo = a // b\nprint(f\"Number A // Number B = {flo}\")\n\na = b;\nprint(f\"a = b\\t Number A:  {a}\")\n\na += b;\nprint(f\"a += b\\t Number A:  {a}\")\n\na -= b;\nprint(f\"a -= b\\t Number A:  {a}\")\n\na *= b;\nprint(f\"a *= b\\t Number A:  {a}\")\n\na /= b;\nprint(f\"a /= b\\t Number A:  {a}\")\n\na %= b;\nprint(f\"a %= b\\t Number A:  {a}\")\n\na //= b;\nprint(f\"a //= b\\t Number A:  {a}\")\n\nif a == b:\n    print(f\"Number A equals number B\")\n\nif a != b: print(f\"Number A does not equal number B\")\n\nif a > b:\n    print(f\"Number A is greater than number B\")\nelif a < b:\n    print(f\"Number A is less than number B\")\nelse:\n    print(f\"Number A equal number B\")\n\nprint(\"Number A is greater than or equal to number B\") if a >= b else print(\"Number A is less than number B\")\n\nwhile a > b or b == 3:\n    a += 1\n\nfor i in [1, 2, 3]:\n    print(i)\n\nfor i in range(3, 5):\n    print(i)\n\ntry:\n  print(a)\nexcept:\n  print(\"Exception\") \n\ndef program():\n    for i in range(10, 55):\n        if i % 2 != 0 or i == 16 or i % 3 == 0:\n            continue\n        else:\n            print(f\"\\n{i}\")\n\nprogram()\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/qwik-zgheib.py",
    "content": "# -- aritmetics\naddition: int = 1 + 2\nsubtraction: int = 1 - 2\nmultiplication: int = 1 * 2\ndivision: float = 1 / 2\nexponentiation: int = 1**2\nmodulo: int = 1 % 2\nprint(\"----- aritmetics -----\")\nprint(f\"addition: {addition}\")\nprint(f\"subtraction: {subtraction}\")\nprint(f\"multiplication: {multiplication}\")\nprint(f\"division: {division}\")\nprint(f\"exponentiation: {exponentiation}\")\nprint(f\"modulo: {modulo}\")\n\n# -- logic\nand_op: bool = True and False\nor_op: bool = True or False\nlogical_not: bool = not True\nprint(\"----- logic -----\")\nprint(f\"and_op: {and_op}\")\nprint(f\"or_op: {or_op}\")\nprint(f\"logical_not: {logical_not}\")\n\n# -- comparison\nequal: bool = 1 == 2\nnot_equal: bool = 1 != 2\ngreater_than: bool = 1 > 2\nless_than: bool = 1 < 2\ngreater_than_or_equal: bool = 1 >= 2\nless_than_or_equal: bool = 1 <= 2\nprint(\"----- comparison -----\")\nprint(f\"equal: {equal}\")\nprint(f\"not_equal: {not_equal}\")\nprint(f\"greater_than: {greater_than}\")\nprint(f\"less_than: {less_than}\")\nprint(f\"greater_than_or_equal: {greater_than_or_equal}\")\nprint(f\"less_than_or_equal: {less_than_or_equal}\")\n\n# -- assignment\nprint(\"----- assignment -----\")\nassignment: int = 5\nprint(f\"assignment: {assignment}\")\nassignment += 3\nprint(f\"assignment += 3: {assignment}\")\nassignment -= 3\nprint(f\"assignment -= 3: {assignment}\")\nassignment *= 3\nprint(f\"assignment *= 3: {assignment}\")\nassignment /= 3\nprint(f\"assignment /= 3: {assignment}\")\nassignment %= 3\nprint(f\"assignment %= 3: {assignment}\")\nassignment **= 3\nprint(f\"assignment **= 3: {assignment}\")\n\n# -- membership\nmembership: bool = 1 in [1, 2, 3]\nnot_membership: bool = 1 not in [1, 2, 3]\nprint(\"----- membership -----\")\nprint(f\"membership: {membership}\")\nprint(f\"not_membership: {not_membership}\")\n\n# -- bitwise\nbitwise_and: int = 1 & 2\nbitwise_or: int = 1 | 2\nbitwise_xor: int = 1 ^ 2\nbitwise_not: int = ~1\nbitwise_left_shift: int = 1 << 2\nbitwise_right_shift: int = 1 >> 2\nprint(\"----- bitwise -----\")\nprint(f\"bitwise_and: {bitwise_and}\")\nprint(f\"bitwise_or: {bitwise_or}\")\nprint(f\"bitwise_xor: {bitwise_xor}\")\nprint(f\"bitwise_not: {bitwise_not}\")\nprint(f\"bitwise_left_shift: {bitwise_left_shift}\")\nprint(f\"bitwise_right_shift: {bitwise_right_shift}\")\n\n# -- conditional\nprint(\"----- conditional -----\")\ncondition: bool = 5 > 6\nif condition:\n    print(\"5 is greater than 6\")\nelse:\n    print(\"5 is not greater than 6\")\n\n\nprint(\"\\n----- extra -----\")\n\n\ndef print_numbers():\n    for i in range(10, 56):\n        if i % 2 == 0 and i != 16 and i % 3 != 0:\n            print(i)\n\n\nprint_numbers()\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/ramon-almeida.py",
    "content": "\nsuma = 1+1\nprint(suma)\nresta = 56-32\nprint(resta)\ncomparación = 20 < 10\nprint(comparación)\ndivisión = 50 / 5\nprint(división)\nresto_división = 74 % 5\nprint(resto_división)\n\n\n\"\"\" Crea un programa que imprima por consola todos los números comprendidos\n entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\n \"\"\"\n\nresult = []\n\nfor i in range(10, 56):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        result.append(i)\n\n\nprint(result)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/ramxv.py",
    "content": "### Tipos de Operadores ###\n\n# Aritméticos\n'''\n  Operador    Nombre\n  +           Suma\n  -           Resta\n  *           Multiplicación\n  /           División\n  %           Modulo\n  **          Exponente\n  //          Cociente\n''' \nadicion = 12 + 15\nsubtraccion = 12 - 15\nmultiplicacion = 12 * 15\ndivision = 12 / 4\nmodulo = 12 % 3\npotencia = 12 ** 2\ndivision_entero = 12 // 5\nprint(\"### Operadores Aritméticos ###\")\nprint(adicion)\nprint(subtraccion)\nprint(multiplicacion)\nprint(division)\nprint(modulo)\nprint(potencia)\nprint(division_entero,\"\\n\")\n\n# Lógicos\n'''\n  Operador              Descripción\n  and         Devuelve True si ambos son True\n  or          Devuelve True si alguno de los operandos es True\n  not         Devuelve True si alguno de los operandos es False\n'''\nprint(\"### Operadores Lógicos ###\")\nprint(True and False)\nprint(True or False)\nprint(not True,\"\\n\")\n\n# Comparación\n'''\n  Operador    Nombre\n  ==          Igual\n  !=          Distinto\n  >           Mayor\n  <           Menor\n  >=          Mayor o igual\n  <=          Menor o igual\n''' \nx=2; y=3\nprint(\"### Operadores de Comparación ###\")\nprint(x == y)\nprint(x != y)\nprint(x > y)\nprint(x < y)\nprint(x >= y)\nprint(x <= y,\"\\n\")\n\n# Bit a Bit\n'''\nLos operadores a nivel bit o bitwise operators son operadores actúan sobre números enteros pero usando su representación binaria.\n\n  Operador      Nombre\n  |             And bit a bit\n  &             Or bit a bit\n  ~             Not bit a bit \n  ^             Xor bit a bit\n  >>            Desplazamiento a la derecha \n  <<            Desplazamiento a la izquierda\n'''\nprint(\"### Operadores Bit a Bit ###\")\na = 0b1101\nb = 0b1011\nprint(bin(a | b)) # 0b1111\nprint(bin(a & b)) # 0b1001\nprint(bin(~a)) # -0b1110\nprint(bin(a ^ b)) # 0b110\nprint(bin(a>>2)) # 0b11\nprint(bin(a<<2),\"\\n\") # 0b110100\n\n# Asignación\n'''\n  Operadores\n  =  \n  += \n  -= \n  *= \n  /= \n  %= \n  **=\n  //=         \n  &=\n  |=\n  ^=\n  >>=\n  <<=\n''' \nprint(\"### Operadores de Asignación ###\")\n# Le asignamos el valor de 7 a la variable a\na = 7\nprint(\"a = 7 ->\",a) # 7\n\n# a += 2 es equivalente a: a = a + 2 \na = 7\na += 2 \nprint(\"a += 2 ->\",a) # 14\n\n# a -= 2 es equivalente a: a = a - 2 \na = 7\na -= 2\nprint(\"a -= 2 ->\",a) # 2\n\n# a *= 2 es equivalente a: a = a * 2 \na = 7\na *= 2\nprint(\"a *= 2 ->\",a) # 49\n\n# a /= 2 es equivalente a: a = a / 2\na = 7\na /= 2\nprint(\"a /= 2 ->\",a) # 3.5\n\n# a %= 2 es equivalente a: a = a % 2\na = 7\na %= 2\nprint(\"a %= 2 ->\",a) # 1\n\n# a **= 2 es equivalente a: a = a ** 2\na = 7\na **= 2\nprint(\"a **= 2 ->\",a) # 49\n\n# a //= 2 es equivalente a: a = a  2\na = 7\na //= 2\nprint(\"a //= 2 ->\",a) # 3\n\n# a &= 2 es equivalente a: a = a  2\na = 7\na &= 2 \nprint(\"a &= 2 ->\",a) # 2\n\n# a |= 2 es equivalente a: a = a  2\na = 7\na |= 2\nprint(\"a |= 2 ->\",a) # 7\n\n# a ^= 2 es equivalente a: a = a  2\na = 7\na ^= 2\nprint(\"a ^= 2 ->\",a) # 5\n\n# a >>= 2 es equivalente a: a = a  2\na = 7\na >>= 2\nprint(\"a >>= 2 ->\",a) # 1\n\n# a <<= 2 es equivalente a: a = a  2\na = 7\na <<= 2\nprint(\"a <<= 2 ->\",a,\"\\n\") # 28\n\n# Pertenencia\n'''\nUn operador de pertencia se emplea para identificar pertenencia en algunas secuencia(listas,strings,tuplas).\n\n- 'in' y 'not in' son operadores de pertencia.\n\n- 'in' devuelve True si el valor especificado se encuentra en la    secuencia. En caso contrarios devulve False.\n\n- 'not in' devuelve True si el valor especificado no se encuentra en la secuencia. En caso contrario devuelve False.\n'''\nl = [1,2,3,4,5,6]\nprint(\"### Operadores de Pertenencia ###\")\nprint(6 in l) # True\nprint(7 not in l) # True\nprint(0 in l) # False\nprint(2 not in l) # False\nstring = \"Hola Python\"\nprint(\"Hola\" in string) # True\n# Nota: distingue entre mayúsculas y minúsculas.\nprint(\"python\" in string,\"\\n\") # False\n\n# Identidad\n'''\nUn operador de identidad se emplea para comprobar si dos variables emplean la misma ubicación en memoria.\n\n- 'is' y 'is not' son operadores de identidad.\n\n- 'is' devuelve True si los operandos se refieren al mismo objeto. En caso contrario devuelve False.\n\n- 'not in' devuelve True si los operandos no se refieren al mismo objeto. En caso contrario devuelve False.\n\nTen en cuenta que dos valores, cuando son iguales, no implica necesariamente que sean idénticos.\n'''\nz = 3 \nk = 3\ni = 2\nprint(\"### Operadores de Identidad ###\")\nprint(z is k)\nprint(z is not k)\nprint(z is not i, \"\\n\")\n\n### Estructuras de Control ###\n\n# Estructura de control if: \nprint(\"### Estructura de control if ###\")\n\n# Utilizando else\na = 10\nif a > 5 and a < 15:\n  print(\"Mayor que 5 y menos que 15\")\nelse:\n  print(\"No esta en el rango\")\n\n# Utilizando elif\nb = 16\nif b > 5 and b < 15:\n  print(\"Mayor que 5 y menos que 15\")\nelif b <= 5:\n  print(\"Menor o igual que 5\")\nelif b >= 15:\n  print(\"Mayor o igual que 15\")\n\n# Operador Ternario \nx = 5\nprint(\"Es 5\" if x == 5 else \"No es 5\")\nprint(\"\\n\")\n\n# Estructura de control for\nprint(\"### Estructura de control for ###\")\nfor i in range(0,10):\n  print(i)\nprint(\"\\n\")\n\n# Estructura de control while\nprint(\"### Estructura de control for ###\")\nx = 5\nwhile(x > 0):\n  x -= 1\n  print(x)\nprint(\"\\n\")\n\n# Punto opcional\nprint(\"### Punto Opcional ###\")\nfor i in range(10,56):\n  if i % 2 == 0 and i != 16 and i % 3 != 0:\n    print(i)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/rantamhack.py",
    "content": "\n# OPERADORES ARITMETICOS\n# toman los operadores que se le indican y realizan un cálculo matemático\n\nsuma = 3 + 5\nresta = 5 - 3\nmultiplicacion = 5 * 3 \ndivision = 5 / 2\nmodulo = 10 % 3  # Modulo es el resto que nos queda de la división en éste caso es 1\npotencia = 10**3 # Eleva a la potencia 3 el pirmer operando que le pasamos \nresultado_entero = 10 // 3 # El resultado de esta división sería el resto como numero entero\nprint(f\"{suma}\\n{resta}\\n{multiplicacion}\\n{division}\\n{modulo}\\n{potencia}\\n{resultado_entero}\")\n\nprint(\"\\n\\n=======================================================================\\n\\n\")\n\n# OPERADORES RELACIONALES\n# Son los que relacionan dos elementos entre sí\n\nprint(5 > 3) # Devuelve True si es verdadero \nprint(5 >= 3) # Devuelve True si es verdadero\nprint(5 < 3) # Devuelve True si es verdadero\nprint(5 <= 3) # Devuelve True si es verdadero\nprint(5 == 3) # Devuelve True solo si los dos operandos son iguales\nprint(5 != 3) # Devuelve True solo si los dos operandos son diferentes\n\nprint(\"\\n\\n=======================================================================\\n\\n\")\n\n# OPERADORES LOGICOS\n# Se usan basandonos en condiciones\n\n# El operando \"and\" devuelve True siempre que los dos operandos sean correctos\nprint((3 + 2 == 5) and (7 * 2 == 14))\n# El operando \"or\" devuelve True siempre que uno de los dos operandos sea correcto\nprint((3 + 2 == 5) or (7 * 2 == 10))\n# El operando \"not\" devuelve True siempre que uno de los dos operandos sea falso\nprint(not(10 + 3 == 14))\n\nprint(\"\\n\\n=======================================================================\\n\\n\")\n\n# OPERADORES DE ASIGNACION\n# Son los que se usan para dar valor a una variable por ejemplo\nmy_variable = 5         # Asignación    \nprint(my_variable)\n\nmy_variable += 1\nprint(my_variable)      # Suma y Asignación\n\nmy_variable -= 1\nprint(my_variable)      # Resta y Asignación\n\nmy_variable *= 2\nprint(my_variable)      # Multiplicación y Asignación\n\nmy_variable /= 2\nprint(my_variable)      # División y Asignación\n\nmy_variable //= 2\nprint(my_variable)      # Division entera y Asignación\n\nmy_variable **= 3                   \nprint(my_variable)      # Exponente (al cubo) y Asignación\n\nmy_variable %= 3\nprint(my_variable)      # Mòdulo y aAsignación\n\nprint(\"\\n\\n=======================================================================\\n\\n\")\n\n# OPERADORES DE IDENTIDAD\n# Se usan para indicar si dos variables usan la misma ubicación en la memoria\nmy_new_variable = my_variable\n\nprint(f\"my_variable is my_new_variable es {my_variable is my_new_variable}\")\nprint(f\"my_variable is not my_new_variable es {my_variable is not my_new_variable}\")\n\nprint(\"\\n\\n=======================================================================\\n\\n\")\n\n# OPERADORES DE PERTENENCIA\n# Se usan para ver la pertenencia de un elemento a una estructura\n\nprint(f\"'y' in 'my_variable' = {'y' in 'my_variable'}\")\nprint(f\"'y' not in 'my_variable' = {'y' not in 'my_variable'}\")\n\nprint(\"\\n\\n=======================================================================\\n\\n\")\n\n# Operadores de bit\n# Realiza operaciones en los operandos bit a bit\n\na = 10 # 1010 en binario\nb = 3  # 0011\n\nprint(f\"AND: 10 & 3 = {10 & 3}\")  # 0010 (2) and bit a bit 1+0=0; 0+0=0; 1+1=1; 0+1=0; los dos bits han de ser uno para dar uno\nprint(f\"OR: 10 | 3 = {10 | 3}\")   # 1011 (11) or bit a biy  1|0=1; 0|0=0; 1|1=1; 0|1=1; al menos uno de los dos bits ha de ser uno para dar uno\nprint(f\"XOR: 10 ^ 3 = {10 ^ 3}\")  # 1001 (9) xor bit a bit 1^0=1; 0^0=0; 1^1=1; 0^1=1; si los dos son iguales el resultado es cero, si uno cambia el resultado es uno\nprint(f\"Not: ~10 = {~10}\")        # 0101 Inetercambia el valor bit a bit de cualquiera de los elementos\nprint(f\"Desplazamiento a la derecha: 10 >> 2 = {10 >> 3}\")      # 0001 (1) Desplazamos a la derecha 3 bits y rellenamos con ceros por delante\nprint(f\"Desplazamiento a la izquierda: 10 << 3 = {10 << 3}\")    #1010000 (80) Cubrimos con ceros por detras las posiciones que nos pide el segundo operando\n\nprint(\"\\n\\n=======================================================================\\n\\n\")\n\n# ESTRUCTURAS DE CONTROL \n# CONDICIONALES \n\nmy_name = \"juan\"\n\nif my_name is \"luis\":\n    print(\"mi nombre es luis\")\nelif my_name is \"juan\":\n    print(\"mi nombre es juan\")\nelse:\n    print(\"mi nombre no sale en el programa\")\n\nprint(\"\\n\\n=======================================================================\\n\\n\")\n\n# ESTRUCTURAS DE CONTROL \n# ITERATIVAS\n\nfor i in range(1, 11):\n    print(i) \n\nprint(\"\\n\\n=======================================================================\\n\\n\")\n\nn = 11\n\nwhile n < 21:\n    print(n)\n    n += 1\n\nprint(\"\\n\\n=======================================================================\\n\\n\")\n\n# ESTRUCTURAS DE CONTROL \n# MANEJO DE EXCEPCIONES\n\ntry:\n    print(1 / 0)\nexcept:\n    print(\"ZeroDivisionError\")\nfinally:\n    print(\"Fin del manejo de excepciones\")\n\nprint(\"\\n\\n=======================================================================\\n\\n\")\n\n\nfor number in range(10, 56):\n    if number % 2==0 and number != 16 and number % 3 != 0:\n        print(number)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/raulG91.py",
    "content": "\n#Arithmetic operations\nsum = 2+3\nprint(\"Sum: \", sum)\ndiff =  5-1\nprint(\"Diff: \", diff)\nmultiply = 6*8\nprint(\"multiply: \", multiply)\ndivision =  40 / 5\nprint(\"Division\", division)\nint_division = 3//2\nprint(\"Int division\", int_division)\nmodule = 30 % 2\nprint(\"Module\", module)\npower = 2**2\nprint(\"Power: \",str(power))\n\n#Logical \nv_and = True and False\nprint(\"And: \",v_and)\nv_or = True or False\nprint(\"Or : \", v_or)\nv_not = not(True)\nprint(\"Not: \", v_not)\n\n#Comparation\nequal = True == True\nprint(\"Equal : \", equal)\nnot_equal = False != True\nprint(\"Not equal: \", not_equal)\ngreater = 3 > 2\nprint(\"> : \", greater)\ngreater_equal = 3>=3\nprint(\">= :\", greater_equal)\nless = 5 < 10 \nprint(\"<: \", less)\nless_equal = 5<= 2\nprint(\"<= : \",less_equal)\n\n#Identity\nidentity = 1 is -1\nprint(\"is : \", identity)\n\n#Belonging\nbeloning = 1 in [3,4,5,1]\nprint(\"in: \",beloning)\n\n#Bits\nbits_and = 1 & 1\nprint(\"& : \", bits_and)\nbits_or = 1 | 1\nprint(\"| : \", bits_or)\nbits_xor = 1 ^ 1\nprint(\"^ : \", bits_xor)\nbits_not = ~ 1\nprint(\"~ : \",bits_not)\n\na = 5\n\n#if - elif - else\nif a < 3:\n    print(\"Number less than 3\")\nelif a>=3 and a <10:\n    print(\"Number between 3 and 9\")\nelse:\n    print(\"Number bigger than 10\")  \n    \n#Loops    \nfor number in range(0,5):\n    print(number)          \n\nwhile (True):\n    print(\"While loop\")\n    break    \n\ntry:\n    n = float(input(\"Enter a number: \"))\n    m = 4\n    print(\"{}/{} = {}\".format(n,m,n/m))\nexcept:\n    print(\"Number entered is not correct\")\nelse:\n    print(\"Everything is ok\")\n       \n'''\nExtra Exercise: \n* Crea un programa que imprima por consola todos los números comprendidos\n* entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n'''        \n\nfor num in range(10,56):\n    if (num % 2 == 0) and (num !=16)  and (num % 3 != 0):\n        print(num)\n    "
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/rayn1er.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n#  *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n#  *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n#  * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n#  *   que representen todos los tipos de estructuras de control que existan\n#  *   en tu lenguaje:\n#  *   Condicionales, iterativas, excepciones...\n#  * - Debes hacer print por consola del resultado de todos los ejemplos.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea un programa que imprima por consola todos los números comprendidos\n#  * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n#  *\n#  * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n#  */\n\n\n#artimeticos\nsum_operator = 2 + 2 #operador logico de suma\nsub_operator = 4 - 2 #operador logico de la resta\ndiv_operator = 10 / 2 #operador logico de division\nmul_operator = 5 * 2 #operador logico de la multiplicacion\nexp_operator = 5 ** 2 #operador de potencia\nfloat_div_operator = 55 /2 #operador para dividir redoneando\n\nprint(sum_operator,sub_operator,div_operator,mul_operator,exp_operator,float_div_operator)\n#comparacion \n\ngreater_than =  5 > 2 #operador logico mayor que, devuelve un boleano (en este caso true)\nless_than = 2 < 5 #Operador logico menor que, devuelve un boleano (en este caso true)\nequal_to = 2 == 5 #operador logico de igual que, devuelve booleano (en este caso false)\nnot_equal_to = 2 != 5 #operador logico de no igual que, en este caso devuelve true\ngreater_than_or_equal_to = 2 >= 5 #operador logico de igual o mayor que, devuelve false\nless_than_or_equal_to = 2 <=5 #operador logico de menor o igual que, devuelve true\n\n#logicos\n\n# El operador and evalua ambos y valores y si los dos son true, devuelve true, en caso de uno de los valores sea false, entonces el resultado sera false\n\nprint(True and True) #imprime true\nprint(True and False) #imprime false\n\n#por su parte el operador or nos devuelve true siempre y cuando uno de los valores sea true\n\nprint(True or True) #imprime True\nprint(True or False) #tambien imprime true\nprint(False or False) #imprime False\n\n#finalmente tenemos el operador nor el cual nos invierte el valor de nuestro booleano\n\nprint(not True) #imprime False\nprint(not False) #imprime true\n\n\n#asignacion\n\nvariable = 10 # utilizamos el simbolo = para asignar un valor a nuestra variable\nprint(variable)\nvariable += 10 #utilizamos += 10 para aumentar en 10 nuestro valor\nprint(variable) #imprimimos para ver los cambios\nvariable -= 10 #lo mismo con el operador -= que en este caso nos ayuda a restar\nprint(variable) #volvemos a imprimir para ver los cambios\nvariable *= 10 # *= para multiplicar\nprint(variable) #volvemos a imprimir para ver los cambios\nvariable /= 10 # para dividir\nprint(variable) #volvemos a imprimir para ver los cambios\nvariable **= 10 # **= para el exponencial\nprint(variable) #volvemos a imprimir para ver los cambios\nvariable //= 10 # //= para dividir redondeando \nprint(variable) #volvemos a imprimir para ver los cambios\nvariable %= 10 # %= para el modulo\nprint(variable) #volvemos a imprimir para ver los cambios\n\n#identidad\n\n#supongamos que tenemos dos variables y queremos verificar si ambas son iguales, para ello utilizariamos los operadores de identidad, que nos devuelve un booleano positivo si el valor ambos elementos es igual\n\nvalue_a = 100\nvalue_b = 100\nprint(value_a is value_b) #el operador is nos arroja true si el objeto vale lo mismo, en este caso true\n\n#el operador is not devuelve true si el elemento no es el mismo\nvalue_c = 10\n\nprint(value_a is not value_c) #en este caso nos arroja tambien true\n\n#el funcionamento de esto es diferente si lo aplicamos en listas que contengan los mismos objetos, debido a que a pesar de que los elementos contenidos dentro de la lista son los mismos, dichas listas se almacenan en lugares diferentes de la memoria\n\nlist_a = [1,2,3]\nlist_b = [1,2,3]\n\nprint(list_a is list_b) #en este caso arroja false, puesto que son listas distintas\nprint(list_a is not list_b) #como las listas no son las mismas, devuelve un true\n\n#pertenencia\n#aqui tenemos los operadores in y not in, que se utilizan para verificar si un elemento se encuentra o pertenece a otro\nstring = \"soy una cadena de textos de python!\"\n\nprint('i' in string) #en este caso nos arrojara false, puesto que \"i\" no esta comprendido en la cadena de texto\nprint('i' not in string) #todo lo contrario aca, nos arroja true porque la letra en cuestion no esta comprendida en la variable\n\n#operadores bitwise\n#estos son los operadores que utilizamos para trabajar a nivel binario\n\nbit_a = 10\nbit_b = 3\n\nprint(bit_a & bit_b) # & (and) compara cada bit de los operandos y devuelve uno si ambos bit son 1, de lo contrario devuelve 0\nprint(bit_a | bit_b) # | (or) compara cada bit de los operandos y devuelve 1 si al menos uno de ambos es 1 \nprint(bit_a ^ bit_b) # ^ (xor) compara ambos y devuelve uno si uno de los bit es 1, pero no ambos\nprint(~bit_a) # ~ (not) invierte los bits del operando\nprint(bit_a >> 2) # >> (desplazamiento a la derecha) reemplaza los bits hacia la derecha segun lo indiquemos, en este caso 2 digitos\nprint(bit_a << 2 ) # << (desplazamiento hacia la izquierda) reemplaza los bits hacia la izquierda segun lo indiquemos, en este caso dos digitos\n\n\n#estructuras de control\n\n#utilizamos if para verificar si una condicion se cumple o no y en base a ello ejecutar un codigo u otro\n\ntown = 'megalovania' #estableceremos esta variable para verificar si la misma contiene la letra \"a\"\n\nif 'a' in town:\n    print(\"la letra se encuentra\") #codigo que se ejecutara, puesto que la letra esta en la variable\n#aca podriamos colocar un elif en caso de querer agregar otro comportamiento para otra condicion dada\nelse:\n    print(\"la letra no se encuentra\") #codigo que se ejecutara en caso de que la letra no este en la variable\n\n#tambien tenemos la palabra reservada while, que utilizamos para ejecutar codigo siempre y cuando se cumpla una condicion\n\ncounter = 0 #estableceremos un contador para ir aumentando su numero gradualmente\n\nwhile counter < 10: #si el contador es menor a 10, ejecutamos codigo\n    counter += 1 #agregamos uno a la variable\n    print(counter) #imprimimos por consola\n\n#tambien tenemos el bucle for, el cual se ejecutara un numero dado de veces, a diferencia del while que podria ejecutarse de manera infinita\n\nfor i in range(0,counter): #imprimimos desde el uno cantidad de veces hasta el valor de contador el cual se ha incrementado a diez\n    print(f'hola #{i}')\n\n#finalmente tenemos la estructura de control try, la cual nos sirve para detectar posibles errores y ejecutar un codigo alternativo con el objetivo de que el error no rompa el flujo de ejecucion de nuestro programa\n\ntry:\n    print(2/0) #realizar esta operacion derivara en un error, puesto que no podemos dividir un numero entre 0\n\nexcept:\n    print(\"el programa ha presentado un error puesto que no se puede dividir por 0\") #utilizamos except para continuar el flujo de la aplicacion\n\nfinally:\n    print(\"el programa ha continuado exitosamente\") #utilizamos finally para ejecutar codigo luego de realizar el except\n\n#programa extra\n\nfor i in range(10,56):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print(i)\n        "
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/raynerpv2022.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n \"\"\"\n\na = 10\nb = 18\nsuma = a+b\nresta = a-b\nmult = a*b\ndiv = a/b\ndivEntera = a // b\n\nmayorq = a > b\nmenorq = a < b\nigualq = a == b\ndesigualq = a != b\n\nif suma > a or suma > b :\n    print(\"variable a o variable b son distintas de 0\")\n\nfor i in range(10):\n    print(a+i)\n    print(b-i)\n    if a == 12:\n        continue\n    elif a == 13:\n        break\nwhile b<20 :\n    print(b)\n    b+=1\n\n# aritmeticos\nprint(\"*** Operadores Aritmeticos ***\")\nprint(f\"{a}+{b}={suma}\")\nprint(a,\"-\",b,\"=\", resta)\nprint(\"{0}*{1}={2}\".format(a,b,mult))\nprint(b,\"/\",a,\"=\", div)\nprint(b,\"//\",a,\"=\", divEntera)\nprint(b,\"%\",a,\"=\", a%b)\nprint(a, \"**\",b,\"==\", a**b)\n\n# comparacion\nprint(\"*** Operadores comparacion ***\")\nprint(a,\">\",b,\"=\", mayorq)\nprint(a,\"<\",b,\"=\", menorq)\nprint(a,\"=\",b,\"=\", igualq)\nprint(a,\"!=\",b,\"=\", desigualq)\n\n#logicos\nprint(\"*** Operadores Logicos ***\")\nprint(f\"AND 10 > 5 and 5 > 0 {10 > 5 and 5 > 0}\")\nprint(f\"OR 10 > 5 and 5 == 0 {10 > 5 or 5 == 0}\")\nprint(f\"NOT not (10 == 5 and 5 == 0) {not (10 == 5 and 5 == 0)}\")\n\n#asignacion\nprint(\"*** Operadores Asignacion ***\")\nage = 20\nprint(f\"  age = 20 ... {age}\")\nage += 1\nprint(f\"  age += 1 ... {age}\")\nage -= 10\nprint(f\"  age -= 10 ... {age}\")\nage *= 2\nprint(f\"  age *= 2 ... {age}\")\nage /=3\nprint(f\"  age /= 3 ... {age}\")\n\n# identidad\nprint(\"*** Operadores Identidad ***\")\noldage = age\nprint(f\"oldage is age {oldage is age}\")\noldage = age +10\nprint(f\"oldage is age {oldage is age}\")\noldage = 1.0\nprint(f\"oldage is age {oldage is age}\")\nage = \"aaaa\"\nnewage = \"aaaa\"\nprint(f\"newage is age {newage is age}\")\nprint(f\"newage is not age {newage is not age}\")\n\n# pertenencia\nprint(\"*** Operadores Pertenencia***\")\na = [1,2,3,4,56,0]\nb = 1\nprint(f\" b is in a {b in a}\")\nprint(f\"'f' un 'fire' {'f' in 'fire'}\")\n\n#operadores con bits\nprint(\"*** Operadores con bits ***\")\nprint(f\"AND 9 & 5 = {9 & 5}\") # 9 = 1001 5 = 101  and ... 1 si los dos son 1\nprint(f\"OR 9 | 5 = {9 | 5}\")  # | es 1 si al menos uno es 1\nprint(f\"XOR 9 ^ 5 = {9 ^ 5}\") # ^  es 1 si son diferentes\nprint(f\"NOT ~9 = {~9}\") #  \nprint(f\"desplazamiento derecha 9 >> 3 = {9 >> 3}\") \nprint(f\"desplazamiento izquierda 9 << 3 = {9 << 3}\") \n\n# extructuras de control\n# condionales \nprint(\"*** extructuras de control condicionales ***\")\nif \"asus\" in \"asustech\":\n    print(\"good\")\nelif \"asus\" not in \"ASUS\":\n    print(\"asus not in ASUS\")\nelse:\n    print(\"ni asus ni ASUS\")\n\n# iterativas\nprint(\"*** extructuras de control Iteractivas ***\")\nfor i in range(3,10,3):\n    print(i)\n\na=0\n\nwhile True:\n    a+=1\n    print(a)\n    if a == 10:\n        break\n\n#excepciones\nprint(\"*** extructuras de control manejo errores ***\")\n\ntry:\n    print(12 / 0)\nexcept:\n    print(\"error\")\nfinally:\n    print(\"salida del try\")\n\n\nprint(\" ****** EXTRA ****** \")\n\n# usando step2\nfor i in range(10,56,2):\n    if i == 16 or i % 3 ==0:\n        continue\n    print(i)\n\n# usando if para pares\nfor i in range(10,56):\n    if i %2 != 0 or i == 16 or i % 3 != 0:\n        continue\n    print(i)\n\ni = 10\nwhile i < 56:\n    print(i)\n    i+=2\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/restevean.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\"\"\"\n\n\n# OPERADORES\nprint(\"OPERADORES\")\n\n# Aritméticos\nprint(\"\\nAritméticos\")\nprint(\"Suma: 2 + 3 =\", 2 + 3)\nprint(\"Resta: 2 - 3 =\", 2 - 3)\nprint(\"Multiplicación: 2 * 3 =\", 2 * 3)\nprint(\"División: 2 / 3 =\", 2 / 3)\nprint(\"División entera: 2 // 3 =\", 2 // 3)\nprint(\"Módulo: 2 % 3 =\", 2 % 3)\nprint(\"Potencia: 2 ** 3 =\", 2 ** 3)\n\n# Lógicos\nprint(\"\\nLógicos\")\nprint(\"And: True and False =\", True and False)\nprint(\"Or: True or False =\", True or False)\nprint(\"Not: not True =\", not True)\nprint(\"Xor: True ^ False =\", True ^ False)\n\n# De comparación\nprint(\"\\nDe comparación\")\nprint(\"Equal: 2 == 3 =\", 2 == 3)\nprint(\"Not equal: 2 != 3 =\", 2 != 3)\nprint(\"Less than: 2 < 3 =\", 2 < 3)\nprint(\"Less than or equal: 2 <= 3 =\", 2 <= 3)\nprint(\"Greater than: 2 > 3 =\", 2 > 3)\nprint(\"Greater than or equal: 2 >= 3 =\", 2 >= 3)\n\n# Asignación\nprint(\"\\nAsignación\")\na = 5\nprint(\"a = 5, a =\", a)\na += 2\nprint(\"a += 2, a =\", a)\na -= 2\nprint(\"a -= 2, a =\", a)\na *= 2\nprint(\"a *= 2, a =\", a)\na /= 2\nprint(\"a /= 2, a =\", a)\na %= 2\nprint(\"a %= 2, a =\", a)\n\n# Identidad\nprint(\"\\nIdentidad\")\na = 1000\nb = 1000\nprint(\"Is: a is b =\", a is b)\nprint(\"Is: a is not b =\", a is not b)\n\n# Pertenencia\nprint(\"\\nPertenencia\")\nprint(\"In: 2 in [1, 2, 3] =\", 2 in [1, 2, 3])\nprint(\"Not in: 2 not in [1, 2, 3] =\", 2 not in [1, 2, 3])\n\n# Bits\nprint(\"\\nBits\")\nprint(\"Bitwise And: 2 & 3 =\", 2 & 3)\nprint(\"Bitwise Or: 2 | 3 =\", 2 | 3)\nprint(\"Bitwise Xor: 2 ^ 3 =\", 2 ^ 3)\nprint(\"Bitwise Not: ~2 =\", ~2)\nprint(\"Left shift: 2 << 3 =\", 2 << 3)\nprint(\"Right shift: 2 >> 3 =\", 2 >> 3)\n\n# ESTRUCTURAS DE CONTROL\nprint(\"\\nESTRUCTURAS DE CONTROL\")\n\n# Condicionales\nprint(\"\\nCondicionales\")\nif 100 < 1000:\n    print(\"100 < 1000\")\nelse:\n    print('100 >= 1000')\n\n# Condicionales en una sola línea\nprint(\"\\nEn una sola línea\")\nprint(\"2 < 3\") if 2 < 3 else print(\"2 >= 3\")\n\n# Iterativas\nprint(\"\\nIterativas\")\nfor i in range(3):\n    print(i)\ni = 0\nwhile i < 3:\n    print(i)\n    i += 1\n\n# Excepciones\nprint(\"\\nExcepciones\")\ntry:\n    print(2 / 0)\nexcept ZeroDivisionError:\n    print(\"Cannot divide by zero\")\nfinally:\n    print(\"Ended the exception handling\")\n\n# DIFICULTAD EXTRA\nprint(\"\\nDIFICULTAD EXTRA\")\nfor i in range(10, 56):\n    print(i) if i % 2 == 0 and i != 16 and i % 3 != 0 else None\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/rianojnicolas.py",
    "content": "# Operadores Aritmeticos\n\na = 1\nb = -2\nprint(\"OPERADORES ARITMETICOS\")\nsuma = a + b \nprint(f'La suma entre {a} y {b} es igual a {suma}')\nresta = a - b\nprint(f'La resta entre {a} y {b} es igual a {resta}')\ndivision = a/b\nprint(f'La division entre {a} y {b} es igual a {division}')\nproducto = a*b\nprint(f'La multiplicacion entre {a} y {b} es igual a {producto}')\npotencia = a**b\nprint(f'El numero {a} elevado a la potencia {b} es igual a {potencia}')\nmodulo = a%b\nprint(f'El resto de la division entre {a} y {b} es igual a {modulo}')\nprint(\"\")\n\n# Operadores Relacionales\nprint(\"OPERADORES RELACIONALES\")\nigualdad = a == b\nprint(f'¿ Son iguales {a} y {b} ? RTA -> {igualdad}')\ndiferencia = a != b\nprint(f'¿ Son diferentes {a} y {b} ? RTA -> {diferencia}')\nmayor = a > b\nprint(f'¿ {a} es mayor a {b} ? RTA -> {mayor}')\nmenor = a < b\nprint(f'¿ {a} es menor a {b} ? RTA -> {menor}')\nmenorIgual = a <= b\nprint(f'¿ {a} es menor e igual a {b} ? RTA -> {menorIgual}')\nmayorIgual = a >= b\nprint(f'¿ {a} es mayor e igual a {b} ? RTA -> {mayorIgual}')\nprint(\"\")\n\n# Operadores de Asignacion\nprint(\"OPERADORES DE ASIGNACION\")\nprint(\"\"\"\nAsignación\"\"\")\nx = 2\nprint(f'A la variable *x* le asiganmos el valor {x}, con la siguiente sintaxis x = 1 \\n')\n\nprint(\"CONTADOR DE SUMA\")\nx += 1\nprint(f'La operacion (x += 1), es equivalente x = x + 1, que da como resultado {x} \\n')\n\nprint(\"CONTADOR DE RESTA\")\nx -= 2\nprint(f'La operacion (x -= 2), es equivalente x = x - 2, que da como resultado {x} \\n')\n\nprint(\"CONTADOR DE PRODUCTO\")\nx *=5\nprint(f'La operacion (x *= 5), es equivalente x = x * 5, que da como resultado {x} \\n')\n\nprint(\"CONTADOR DE DIVISION\")\nx /= 5\nprint(f'La operacion (x /= 5), es equivalente x = x / 5, que da como resultado {x} \\n')\n\nprint(\"CONTADOR DE MODULO\")\nprint(f'La operacion (x %= 0.5), es equivalente al residuo de la división entre {x} / 0.5')\nx %= 2\nprint(f'Esta operacion da como resultado {x} \\n')\n\nprint(\"CONTADOR DE POTENCIACION\")\nx **= 2\nprint(f'La operacion (x **= 2), es equivalente x = x^2, que da como resultado {x} \\n')\n\n\n# Operadores Logicos\nA = True\nB = False\nprint(\"OPERADORES LOGICOS\")\n# AND\nprint(f'{A} and {B} = {A and B}')\nprint(f'{B} and {A} = {B and A}')\nprint(f'{A} and {A} = {A and A}')\n\n# OR\nprint(f'{B} or {A} = {B or A}')\nprint(f'{A} or {B} = {A or B}')\nprint(f'{A} or {A} = {A or A}')\nprint(f'{B} or {B} = {B or B}')\n\n# NOT\nprint(f'not({A}) = {not A}')\nprint(f'not({B}) = {not B}')\nprint(\"\")\n\n# Operadores de Pertenencia\nprint(\"OPERADORES DE PERTENCIA\")\nmy_list = [1, 10, 4, 5, 100]\nprint(my_list, \"\\n\")\nelement = 2\nprint(f'¿{element} esta en la lista? RTA->{element in my_list}')\nprint(f'¿{element} no esta en la lista? RTA->{element not in my_list} \\n')\n\n# Operadores de Identidad\nprint(\"OPERADORES DE IDENTIDAD\")\nprint(f'¿{element} es {my_list[element]}? RTA->{element is my_list[element]}')\nprint(f'¿{element} no es {my_list[element]}? RTA->{element is not my_list[element]}\\n')\n\n# Estructuras de Control\nmode = input(\"Ingresa modo de juego 1 o 2:\")\n\n# Ciclo while\nprint(\"Ciclo while - Iterativa \\n\")\nwhile (mode != \"1\" and mode != \"2\"):\n    print(\"Please enter the correct input\")\n    mode = input(\"Enter the mode: \")\n\n# Ciclo IF\nprint(\"\\nCiclo IF - Condicional\")\nif (mode == \"2\"):\n    print(\"Elegiste modo de juego 2\")\nelse:\n    print(\"Elegiste modo de juego 1\")\n\n# Ciclo for\nprint(\"\\nCiclo for - Iterativa\")\nfor i in range(0,5):\n    if (i%2==0):\n        print(f'{i} es un numero par')\n    else:\n        print(f'{i} es un numero impar')\n\n# Excepciones\nprint(\"\\nExcepciones\")\ntry:\n    dividendo = int(input(\"Ingresa el dividendo de la división: \"))\n    divisor = int(input(\"Ingresa el divisor de la división: \"))\n    division = dividendo/divisor\nexcept Exception as e:\n    print(\"Error !!!!\", e)\n\nprint(\"\\n\")\n# Dificultad Extra\nfor i in range(9,56):\n    if (i == 16):\n        continue\n    elif (i%3 == 0):\n        continue\n    else:\n        print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/rigo93acosta.py",
    "content": "#01 OPERADORES Y ESTRUCTURAS DE CONTROL\n'''\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n'''\n\n# Operadores aritmeticos\nprint(\"--Operadores aritmeticos--\")\nprint(1 + 2)\nprint(1 - 2)\nprint(1 * 2)\nprint(1 / 2)\nprint(1 // 2)\nprint(1 % 2)\nprint(1 ** 2)\n\n# Operadores logicos\nprint(\"--Operadores logicos--\")\nprint(True and False)\nprint(True or False)\nprint(not False)\n      \n# Operadores comparacion\nprint(\"--Operadores comparacion--\")\nprint(1 > 2)    \nprint(1 < 2)    \nprint(1 >= 2)   \nprint(1 <= 2)   \nprint(1 == 2) \nprint(1 != 2) \n\n# Operadores de asignacion\nprint(\"--Operadores de asignacion--\")\n# Suma\nas_1 = 1\nas_1 += 2                 \nprint(as_1)     \n# Resta\nas_2 = 1\nas_2 -= 2            \nprint(as_2)          \n# Mult\nas_3 = 1\nas_3 *= 2      \nprint(as_3)    \n# Div\nas_4 = 1\nas_4 /= 2            \nprint(as_4)          \n# Div Ent\nas_5 = 1\nas_5 //= 2       \nprint(as_5)      \n# Modulo\nas_6 = 1\nas_6 %= 2              \nprint(as_6)            \n# Potenica\nas_7 = 1\nas_7 **= 2\nprint(as_7)\n\n# Operadores binarios\nprint(\"--Operadores binarios--\")\n# And\nprint(1 & 2)\n# Or        \nprint(1 | 2)\n# Xor\nprint(1 ^ 2)\n# Not\nprint(~1)\n# Desplazamiento left\nprint(1 << 2)\n# Desplazamiento right\nprint(1 >> 2)\n\n# Operador pertenencia\nprint(\"--Operador pertenencia--\")\narr = [i for i in range(10)]\nprint(3 in arr)\nprint(11 in arr)\n\n# estructuras de control\nprint(\"--Estructuras de control--\")\nage = 30\nif age >= 30:\n    print(\"Ya no eres joven!\")\nelif age < 30:\n    print(\"Eres joven!\")\nelse:\n    print(\"Eres tan anciano como el universo.\")\n\n\n# Estructura de control iterativo for\nprint(\"--Estructura de control iterativo for--\")\nfor i in range(10):\n    print(i)\n\n# Estructura de control iterativo while\nprint(\"--Estructura de control iterativo while--\")\nj = 0\nwhile j < 10:\n    print(j)\n    j += 1\n\n# Estructura de control try-except\nprint(\"--Estructura de control try-except--\")\n# Ejemplo clasico de division por 0\ntry:\n    print(1 / 0)\nexcept:\n    print(\"Error de division\")\n\n# Extra\n    print(\"--DIFICULTAD EXTRA--\")\n\"\"\"\nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\"\"\"\nnumbers = [i for i in range(10, 56) if i % 2 == 0 and i != 16 and i % 3 != 0]\nprint(numbers)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/rikmij.py",
    "content": "'''\nUso la librería colorama para añadir color a algunas partes del código, como a los resultados.\nEsta librería hay que instalarla, no viene incluída\n'''\n\nimport colorama\n\ncolor_green = colorama.Fore.GREEN\ncolor_blue = colorama.Fore.BLUE\ncolor_grey = colorama.Fore.BLACK\ncolor_red = colorama.Fore.RED\nend_color = colorama.Fore.RESET\n\nimport random\n\nprint('-'*10, \"OPERADORES ARITMÉTICOS\", '-'*10)\n\nprint(\"\\tOperador '+':\", color_green, \"3+6 = \", 3+6, end_color)\nprint(\"\\tOperador '-':\", color_green, \"6-3 = \", 6-3, end_color)\nprint(\"\\tOperador '*':\", color_green, \"3*6 = \", 3*6, end_color)\nprint(\"\\tOperador '/':\", color_green, \"6/3 = \", 6/3, end_color) \n#por defecto saca un float. Para que sea un int usamos '//' o especificamos que sea un int(n1/n2)\nprint(\"\\tOperador '//':\", color_green, \"6//3 = \", 6//3, end_color)\nprint(\"\\tOperador '**':\", color_green, \"6/3 = \", 6**3, end_color, \"\\n\")\n\n\nprint('-'*10, \"OPERADORES LÓGICOS\", '-'*10)\n\nprint(\"\\tOperador 'or':\", color_grey, \"True or False = \", True or False, end_color)\nprint(\"\\tOperador 'and':\", color_grey, \"True and False = \", True and False, end_color)\nprint(\"\\tOperador 'not':\", color_grey, \"not False = \", not False, end_color, \"\\n\")\n\n\nprint('-'*10, \"OPERADORES DE COMPARACIÓN\", '-'*10)\n\nprint(\"\\tOperador '<':\", color_blue, \"3 < 6 = \", 3<6, end_color)\nprint(\"\\tOperador '>':\", color_blue, \"3 > 6 = \", 3>6, end_color)\nprint(\"\\tOperador '==':\", color_blue, \"3 == 6 = \", 3==6, end_color)\nprint(\"\\tOperador '!=':\", color_blue, \"3 != 6 = \", 3!=6, end_color)\nprint(\"\\tOperador '<=':\", color_blue, \"3 <= 6 = \", 3<=6, end_color)\nprint(\"\\tOperador '>=':\", color_blue, \"3 >= 6 = \", 3>=6, end_color)\n\n\nprint('-'*10, \"OPERADORES DE ASIGNACIÓN\", '-'*10)\n\nprint(\"\\tOperador '=':\", color_red, \"x = 10 \", end_color)\nx = 10\nx+=2\nprint(\"\\tOperador '+=':\", color_red, \"x += 2 ->\", x, end_color)\nx-=2\nprint(\"\\tOperador '-=':\", color_red, \"x -= 2 ->\", x, end_color)\nx*=2\nprint(\"\\tOperador '*=':\", color_red, \"x *= 2 ->\", x, end_color)\nx/=2\nprint(\"\\tOperador '/=':\", color_red, \"x /= 2 ->\", x, end_color)\nx%=6\nprint(\"\\tOperador '%=':\", color_red, \"x %= 6 ->\", x, end_color)\n\n\nprint('-'*10, \"OPERADORES DE IDENTIDAD\", '-'*10)\n\nprint(\"\\tOperador 'is':\", color_green, \"3 is 6 = \", 3 is 6, end_color)\nprint(\"\\tOperador 'is not ':\", color_green, \"3 is not 6 = \", 3 is not 6, end_color)\n\n\nprint('-'*10, \"OPERADORES DE PERTENENCIA\", '-'*10)\n\nprint('proof_list = [\"Python\", \"Kotlin\", \"Swift\", \"Go\", \"JavaScript\", \"COBOL\"]')\nproof_list = [\"Python\", \"Kotlin\", \"Swift\", \"Go\", \"JavaScript\", \"COBOL\"]\n\nprint(\"\\tOperador 'in':\", color_grey, \"'Python' in proof_list ->\", \"Python\" in proof_list, end_color)\nprint(\"\\tOperador 'not in':\", color_grey, \"'Python' not in proof_list ->\", \"Python\" not in proof_list, end_color)\n\n\nprint('-'*10, \"OPERADORES DE BITS\", '-'*10)\nprint(\"\\tOperador '&':\", color_blue, \"3 & 6 = \", 3 & 6, end_color)\nprint(\"\\tOperador '|':\", color_blue, \"3 | 6 = \", 3 | 6, end_color)\nprint(\"\\tOperador '^':\", color_blue, \"3 ^ 6 = \", 3 ^ 6, end_color)\nprint(\"\\tOperador '~':\", color_blue, \"~ 6 = \", ~ 6, end_color)\nprint(\"\\tOperador '<<':\", color_blue, \"3 << 2 = \", 3 << 2, end_color)\nprint(\"\\tOperador '>>':\", color_blue, \"3 >> 2 = \", 3 >> 2, end_color)\n\n\nprint('\\n','-'*10, \"EJEMPLOS CON ESTRUCTURAS DE CONTROL\", '-'*10)\n\nprint('*'*3, \"EJERCICIO 1\", '*'*3)\nwhile True:\n    try:\n        num = int(input(\"Pon un número:\"))\n        if num%2 == 0:\n            print(color_green, \"Es un número par\", end_color)\n        else:\n            print(color_green, \"Es un número impar\", end_color)\n        break\n    except:\n        print(color_red,\"Que sea un número\", end_color)\n\nprint('*'*3, \"EJERCICIO 2\", '*'*3)\nword = input(\"Vamos a contar las vocales. Pon una palabra: \")\nvocals = \"aeiou\"\ncount = []\nfor letra in word:\n    if letra in vocals:\n        count.append(letra)\n    else:\n        pass\nprint(len(count))\n\nprint('*'*3, \"EJERCICIO 3\", '*'*3)\nchosen_number = random.randint(1, 30)\nvidas = 5\n\nchoose = None\n\nwhile chosen_number != choose:\n    choose = int(input(\"Elige un número entre el 1 y el 30: \"))\n    vidas -= 1\n\n    if chosen_number > choose:\n        print(color_grey, f\"El número es mayor, pon uno más grande. Te quedan {vidas} vidas\", end_color)\n    elif chosen_number < choose:\n        print(color_grey, f\"El número es menor, pon uno más pequeño. Te quedan {vidas} vidas\", end_color)\n\n    if vidas == 0:\n        print(color_red, f\"Perdiste. El número era {chosen_number}\", end_color)\n        break\nelse:\n    print(color_green, \"Ganaste!!\", end_color)\n\n\nprint('\\n','*'*13, \"EXTRA\", '*'*13)\n#Crea un programa que imprima por consola todos los números comprendidos entre 10 y 55 (incluidos), pares,\n#y que no son ni el 16 ni múltiplos de 3.\n\nnums = []\nfor n in range(10,56):\n    if n%2 == 0 and n%3 != 0 and n != 16:\n        nums.append(n)\n\nprint(\"Números entre el 10 y 55 pares, no múltiplos de 3 y no 16:\\n\", color_blue, nums, end_color)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/rojasricoo.py",
    "content": "# author: Oscar Duvan R\n'''\n\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\n\n'''\n\n# 1)\n\n# Operadores aritmeticos\nx, y = 2,5\nprint(f'Suma: {x + y}')\nprint(f'Resta: {x - y}')\nprint(f'Multiplicación: {x * y}')\nprint(f'Divición: {x / y}')\nprint(f'Elevado al cuadrado: {x ** y}') # etc...\n\n# Operadores Logicos\nprint(True and False) # and: True  higual a False => False\nprint(True or False) # or: True o False => True\nprint(not(True == False)) # not: True distinto a False => True\n\n# Operadores de Comparación\nprint(f'mayor que: {x > y}')\nprint(f'menor que: {x < y}')\nprint(f'mayor o higual: {x >= y}')\nprint(f'menor o higual: {x <= y}')\nprint(f'higual y higual: {x == y}')\nprint(f'distinto: {x != y}')\n\n# Operadores de asignación\nx = 5\nx += 2\n\nxx = 5\nxx -= 2\n\nxxx = 5\nxxx *= 2\n\nxxxx = 5\nxxxx /= 2\n\nxxxxx = 5\nxxxxx %= 2\n\ny = 5\ny //= 2\n\n\nyy = 5\nyy **= 2\n\nyyy = 5\nyyy &= 2\n\nprint(f'Ahora x se le ha aumentado +2: {x}')\nprint(f'Ahora x se le ha restado -2: {xx}')\nprint(f'Ahora x se le ha multiplicado *2: {xxxx}')\nprint(f'Ahora x se le ha divido /2: {xxxx}')\nprint(f'Ahora x se le ha el resto %2: {xxxxx}')\nprint(f'Ahora x se le ha dado el cociente //2: {y}')\nprint(f'Ahora x se le ha elevado al cuadrado **2: {yy}')\nprint(f'Ahora x se le ha echo comparacion en bits: {yyy}')\n# etc...\n\n# Operadores de identidad\np,j = 1,1\nprint(p is j) # si  valor contenido es higual\nprint(p is not j) # si  valor contenido NO es higual\n\n# Operadores de pertenencia\nstring = 'Hola Python'\nprint('Hola' in string) # Evalue si 'Hola' se encuentra en string\nprint('hola' not in string) # Evalua si 'hola' NO se encuentra en string\n\n# Operadores de bits\ns,d=5,3\nr = s & d # comparación de bit a bit, devuelve 1 solo si ambos bits son 1\nprint(r) \n\nr = s | d # realizar operacion OR bit a bit. evuelve 1 si almenos uno de los bits es 1\nprint(r)\n\nr = s ^ d # realiza una operacionXOR bit a bit, devuelve 1 solo si uno de los bits es 1, pero no ambos\nprint(r)\n\nr = ~ d # este operador realiza una operacion NOT bit a bit, invertiendo todos los bits del numero\nprint(r)\n\nr = s << d # Desplaza todos los bits por un numero hacia la izquierda\nprint(r) \n\nr = s >> d # Desplaza hacia la derecha  por numero\nprint(r) \n\n######################################################################################\n\n# 2)\n# if/elif/else/\nx,y=5,4\nif x == y:\n    print(\"La comprobacion de que 'x' es higual a 'y' fue Verdadero\")\nif x != y:\n    print(\"La comprobacion de que 'x' es distinto a 'y' fue Verdadera\")\nelse:\n    print('Las comprobaciones no han sido suficiente')\n\n# while\nsubs_mr_beast = 0\nwhile subs_mr_beast <= 1000: # ejecuta mientras subs_mr_beast sea menor o higual a 1000\n    #print(subs_mr_beast)\n    if subs_mr_beast == 1000: # si es higual entonces ejecuta esto\n        print(f'Emos alcanzado los {subs_mr_beast}M de subcriptores y por eso regalaremos {subs_mr_beast}M de casas a las personas mas pobres del mundo.')\n    subs_mr_beast +=1 # incrementamos\n\n\nx = [2,3,4]\n# 1) ej\nfor valor in x: # va recorriendo la lista cada vez que avanza la guarda en la variable valor que se encuentra en cada posición \n    print('imprimimos el valor de cada posicion de la lista recorrida: ',valor) # imprimimos el valor de cada posicion de la lista recorrida\n# 2) ej\nx='Pedro'\nfor xz in x:\n    print('imprimimos el valor de cada posicion de la lista recorrida: ',xz)\n\n########################################################################################\n\n# 3)\n#* DIFICULTAD EXTRA (opcional):\n#* Crea un programa que imprima por consola todos los números comprendidos\n# * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\nx=10\nwhile x<=55:\n    if x%2==0 and x%3:\n        print(x)\n    x+=1"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/rserradev.py",
    "content": "# Ejemplos con todos los tipos de operadores del lenguaje\nx = 5\ny = 5\n\n# Aritmeticos\naddition = x + y\nprint(addition)\n\nsubtraction = x - y\nprint(subtraction)\n\nmultiplication = x * y\nprint(multiplication)\n\ndivision = x / y\nprint(division)\n\nmodulus = x % y\nprint(modulus)\n\nexponentiation = x ** y\nprint(exponentiation)\n\nfloorDivision = x // y\nprint(floorDivision)\n\n# Asignación\nx = 10\nx += 3\nx -= 3\nx *= 3\nx /= 3\nx %= 3\nprint(x := 3)\n\n# Comparación\nx = 20\ny = 20\n\nprint(x == y)\t\nprint(x != y)\t\nprint(x > y)\nprint(x < y)\nprint(x >= y)\t\nprint(x <= y)\n\n# Logicos\nx = 30\ny = 30\n\nprint(x < 5 and x < 10)\nprint(x < 5 or x < 10)\nprint(not(x < 5 and x < 10))\n\n# Identidad\n\nx = 1\ny = \"1\"\n\nprint(x is y)\nprint(x is not y)\n\n# BitWise (binary)\n\nx = 99\ny = 10\n\nprint(x & y)\nprint(x | y)\nprint(x ^ y)\nprint(x >> y)\nprint(x << y)\n\n# Ejercicio opcional\nx = 10\ny = 56\n\nfor i in range(x, y):\n    if (i % 3 != 0) and (i % 2 == 0) and (i != 16):\n        print(\"numero \" + str(i))\n    elif (i == 55):\n        print(\"numero \" + str(i))\n    else:\n        print(\"no es multiplo de 3, no es numero par ni tampoco es el numero 16\")"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/s384.py",
    "content": "\"\"\"/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\"\"\"\n\n# Operadores aritméticos\na = 4\nb = 2\n# Suma\nprint(a + b)  # 6\n# Resta\nprint(a - b)  # 2\n# Multiplicación\nprint(a * b)  # 8\n# División\nprint(a / b)  # 2.0\n# Potencia\nprint(a ** b)  # 16\n# Resto\nprint(a % b)  # 0\n# División con resultado entero\nprint(a // b)  # 2\n\n# Operadores lógicos\na = True\nb = False\n# AND lógico\nprint(a and b)  # False\n# OR lógico\nprint(a or b)  # True\n# NOT lógico\nprint(not a)  # False\n\n# Operadores de comparación\na = 5\nb = 3\n# Igualdad\nprint(a == b)  # False\n# Desigualdad\nprint(a != b)  # True\n# Mayor que\nprint(a > b)  # True\n# Menor que\nprint(a < b)  # False\n# Mayor o igual que\nprint(a >= b)  # True\n# Menor o igual que\nprint(a <= b)  # False\n\n# Operadores de asignación\na = 5\n# =\na = 5\n# +=\na += 5\n# -=\na -= 5\n# *=\na *= 5\n# /=\na /= 5\n# %=\na %= 5\n# **=\na **= 5\n# // 5\na //= 5\n\n# Operadores de identidad\na = 5\nb = 5\n# is\nprint(a is b)  # True\n# is not\nprint(a is not b)  # False\n\n# Operadores de pertenencia\na = [1, 2, 3]\nb = 2\n# in\nprint(b in a)  # True\n# not in\nprint(b not in a)  # False\n\n# Operadores de bits\na = 10\nb = 6\n# &\nprint(a & b)  # 2\n# |\nprint(a | b)  # 14\n# ^\nprint(a ^ b)  # 8\n# <<\nprint(a << b)  # 40\n# >>\nprint(a >> b)  # 2\n\n# Estructuras de control\n\n# if\n# elif\n# else\na = -5\nif a > 0:\n    print(\"El valor de a es positivo\")\nelif a < 0:\n    print(\"El valor de a es negativo\")\nelse:\n    print(\"El valor de a es cero\")\n\n# while\na = 4\nwhile a > 0:\n    print(\"El valor de a es positivo\")\n    a -= 1\n\n# for\na = 4\nfor i in range(a):\n    print(f\"El valor de a es {a}\")\n\n# break\na = 4\nfor i in range(a):\n    print(f\"El valor de a es {a}\")\n    if i == 2:\n        break\n\n# continue\na = 4\nfor i in range(a):\n    print(f\"El valor de a es {a}\")\n    if i == 2:\n        continue\n\n# pass\na = 4\nfor i in range(a):\n    print(f\"El valor de a es {a}\")\n    if i == 2:\n        pass\n\n# try\n# except\n# finally\na = 4\ntry:\n    print(f\"El valor de a es {a}\")\nexcept:\n    print(\"Se ha producido un error\")\nfinally:\n    print(\"La ejecución ha finalizado\")\n\n# Dificultad Extra\nfor i in range(10, 56):\n    if (i % 2) != 0:\n        if i == 16 or i % 3 == 0:\n            continue\n        else:\n            print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/saezMD.py",
    "content": "#01 OPERADORES Y ESTRUCTURAS DE CONTROL\n\nx=12\ny=3\n\n#Arithmetic Operators\nz0= x + y \nz1= x - y\nz2= x * y\nz3= x / y\nz4= x % y\nz5= x ** y\nz6= x // y #Floor division (Entera, sin decimales)\n\n#Python Assignment Operators\n\"\"\"\n=\t    x = 5\t    x = 5\t\n+=\t    x += 3\t    x = x + 3\t\n-=\t    x -= 3\t    x = x - 3\t\n*=\t    x *= 3\t    x = x * 3\t\n#/=\t    x /= 3\t    x = x / 3\t\n%=\t    x %= 3\t    x = x % 3\t\n\\//=\tx //= 3\t    x = x // 3\t\n**=\tx   **= 3\t    x = x ** 3\t\n&=\tx   &= 3\t    x = x & 3\t\n|=\tx   |= 3\t    x = x | 3\t\n^=\tx   ^= 3\t    x = x ^ 3\t\n>>=\tx   >>= 3\t    x = x >> 3\t\n<<=\tx   <<= 3\t    x = x << 3\n\"\"\"\n\n#Python Comparison Operators\nx == y\nx != y\nx > y\nx < y\nx >= y\nx <= y\n\n#Python Logical Operators\nx > 2 and x > 20\nx > 3 or x < 0\nnot (x > 2 and x > 15)\n\n#Python Identity Operators\nx is not y\nx is y\n\n#Python Membership Operators\n\"\"\"\nx in y\nx not in y\n\"\"\"\n\n#Python Bitwise Operators\n\"\"\"\nx & y   #AND\nx | y   #OR\nx ^ y   #XOR                    Sets each bit to 1 if only one of two bits is 1\n~x      #NOT                    Inverts all the bits\t\nx << 2  #Zero fill left shift   Shift left by pushing zeros in from the right and let the leftmost bits fall off\nx >> 2  #Signed right shift\t    Shift right by pushing copies of the leftmost bit in from the left, and let the rightmost bits fall off\t\n\"\"\"\n\n# If statement\nif x > y:\n    z = 20\nelif x < 0: \n    z = 0\nelse:\n    z = 10\nprint(z)\n\n# For Statements\nfor i in range(1,10):\n    print(i)\n\n# While loop\nwhile x > y:\n\tprint(y)\n\ty += 1\n\n\n#examples\nprint(x > 2 and y < 20)\nprint(x > 3 or y < 0)\nprint(not(x >= 12 and y >3))\n\ntuplecats =(\"red\", \"blue\", \"brown\", \"orange\")\nprint(\"cat\" in tuplecats)\n\nprint(x + y)\nprint(x ** y)\nprint(x // y )\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\"\"\"\nprint(\"Extra -------------------------------------------------------------\")\n\ndef numConditions(startNUM: str, endNUM: str) -> str:\n\n    for i in range(startNUM,endNUM):\n        if i % 2 == 0:\n            if i % 3 != 0:\n                if i != 16:\n                    print(i)\n    return print(\"Done\")\n                \nnumConditions(10,56)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/saicobys.py",
    "content": "\"\"\" Operadores en Python: \"\"\"\n# Operadores Aritméticos\na = 10\nb = 3\nprint(f\"Suma: {a + b}\")          # Suma\nprint(f\"Resta: {a - b}\")          # Resta\nprint(f\"Multiplicación: {a * b}\")  # Multiplicación\nprint(f\"División: {a / b}\")        # División\nprint(f\"División entera: {a // b}\") # División entera\nprint(f\"Módulo: {a % b}\")         # Resto de la división\nprint(f\"Exponenciación: {a ** b}\") # Potencia\n\n# Operadores de Comparación\nx = 5\ny = 8\nprint(f\"x == y: {x == y}\")      # Igual a\nprint(f\"x != y: {x != y}\")      # Distinto de\nprint(f\"x > y: {x > y}\")       # Mayor que\nprint(f\"x < y: {x < y}\")       # Menor que\nprint(f\"x >= y: {x >= y}\")      # Mayor o igual que\nprint(f\"x <= y: {x <= y}\")      # Menor o igual que\n\n# Operadores Lógicos\np = True\nq = False\nprint(f\"p and q: {p and q}\")    # AND lógico (ambos deben ser True)\nprint(f\"p or q: {p or q}\")     # OR lógico (al menos uno debe ser True)\nprint(f\"not p: {not p}\")       # NOT lógico (invierte el valor de verdad)\n\n# Operadores de Asignación\nz = 20\nz += 5   # z = z + 5\nprint(f\"z += 5: {z}\")\nz -= 3   # z = z - 3\nprint(f\"z -= 3: {z}\")\nz *= 2   # z = z * 2\nprint(f\"z *= 2: {z}\")\nz /= 4   # z = z / 4\nprint(f\"z /= 4: {z}\")\n\n# Operadores de Identidad\nlista1 = [1, 2, 3]\nlista2 = [1, 2, 3]\nlista3 = lista1\nprint(f\"lista1 is lista2: {lista1 is lista2}\")  # False (objetos diferentes)\nprint(f\"lista1 is lista3: {lista1 is lista3}\")  # True (misma referencia)\n\n# Operadores de Pertenencia\nprint(f\"1 in lista1: {1 in lista1}\")  # True\nprint(f\"4 in lista1: {4 in lista1}\")  # False\n\n\"\"\" Estructuras de Control en Python: \"\"\"\n# Condicionales (if, elif, else)\nedad = 25\n\nif edad < 18:\n    print(\"Eres menor de edad\")\nelif 18 <= edad < 65: # Combina comparación y operadores lógicos\n    print(\"Eres adulto\")\nelse:\n    print(\"Eres adulto mayor\")\n\n# Bucles (for , while)\nfor i in range(1, 6): # Bucle for: itera sobre un rango de números\n    print(i)\n\ncontador = 0\nwhile contador < 5:   # Bucle while: itera mientras se cumpla una condición\n    print(contador)\n    contador += 1\n\n# Excepciones (try, except, else, finally)\ntry:\n    resultado = 10 / 0 # División por cero (genera una excepción)\nexcept ZeroDivisionError:\n    print(\"Error: División por cero no permitida\")\nelse: # Se ejecuta si no hubo excepciones\n    print(\"El resultado es:\", resultado)\nfinally: # Se ejecuta siempre, haya o no excepciones\n    print(\"Fin del programa\")\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/salkalero.py",
    "content": "# Operadores Aritméticos\nprint(\"Operadores Aritméticos\")\n\na = 1\nb = 2\nprint(f\"Suma:10+5={10+5}\")#Suma\nprint(f\"Resta:265-65={265-65}\")#Resta\nprint(a*b)#Multiplicación\nprint(a/b)#División\nprint(a%b)#Módulo (resto de la división)\nprint(a**b)#Exponencial\nprint(b//a)#División con resultado entero\n\nprint(\"\\n\"*0)\n#Operadores de Asignación\nprint(\"Operadores de Asignación\")\n\nc = 2\nprint(c)# =\n\nc += 2\nprint(c)# +=\n\nc -= 2\nprint(c)# -=\n\nc *= 2\nprint(c)# *=\n\nc /= 2\nprint(c)# /=\n\nc %= 3\nprint(c)# %=\n\nc //= 1\nprint(c)# //=\n\nc **= 5\nprint(c)# **=\n\nc = 1\nc &= 2\nprint(c)# &=\n\nc |= 2\nprint(c)# |=\n\nc ^= 4\nprint(c)# ^=\n\nc >>= 2\nprint(c)# >>=\n\nc <<= 2\nprint(c)# <<=\n\nc &= 2\nprint(c := 3)# :=\n\nprint(\"\\n\"*0)\n# Operadores de Comparación\nprint(\"Operadores de Comparación\")\n\nd = 6\ne = 15\nprint(d == e)# Igual\n\nprint(d != e)# No es igual\n\nprint(d < e)# Mayor que\n\nprint(d > e)#Menor que\n\nprint(d <= e)#Mayor o igual que\n\nprint(d >= e)# Menor o igual que\n\nprint(\"\\n\"*0)\n#Operadores Lógicos\nprint(\"Operadores Lógicos\")\n\nf = 25\nprint (f > 15 and f < 2)\n\nprint (f > 15 or f < 2)\n\nprint (not(f > 15 and f < 2))\n\nprint(\"\\n\"*0)\n#Operadores de Identidad\nprint(\"Operadores de Identidad\")\n\ng = 15\nh = 32\nprint(g is h)\nprint(g is not h)\n\nprint(\"\\n\"*0)\n#Operadores de Menbresía\nprint(\"Operadores de Membresía\")\n\ni = [\"Melocotón\", \"Ciruela\"]\nprint(\"Melocotón\" in i)\n\ni = [\"Melocotón\", \"Ciruela\"]\nprint(\"Melocotón\" not in i)\n\nprint(\"\\n\"*0)\n#Operadores de Bit a Bit\nprint(\"Operadores de Bit a Bit\")\n\nprint(6 & 9)\n\nprint(6 | 9)\n\nprint(6 ^ 9)\n\nprint(6 << 9)\n\nprint(6 >> 9)\n\nprint(~ 9)\n\nprint(\"\\n\"*0)\n#- crea ejemplos que representen todos los tipos de estructuras de control\nprint(\"Ejemplos de Estructuras de Control\")\n\nb = 14\nc = 15\n\nif c < b :\n    print(\"c es menor que b\")\n\nelif b == c :\n    print(\"b es igual que c\")\n\nelse:\n    print(\"c es mayot que b\")\n\n\nif c > b : print(\"c es mayor que b\")\n\nprint (\"B\") if b > c else print (\"C\")\nprint(\"\\n\"*0)\n#Bucles\nx = 1\nwhile x < 10:\n    print (x)\n    x += 3\n\nprint(\"\\n\"*0)\n\nx = 1\nwhile x < 100:\n    x += 3\n    if x == 4 :\n        continue\n    print(x)\n\nprint(\"\\n\"*0)\n\nObjetos = [\"Cuchara\",\"Cuchillo\",\"Tenedor\"]\nfor a in Objetos:\n    print (a)\nprint(\"\\n\"*0)\n\nfor b in \"Plátano\"\"Manzana\":\n    \n    print(b)\n\nprint(\"\\n\"*0)\n#Extra\nprint(\"extra\")\nprint(\"\\n\"*0)\n\n\n\nfor x in range(10, 55):\n   if  x % 3 != 0 and x % 2 == 0 and x != 16 :\n      print(x)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/santiago434c.py",
    "content": "\"\"\"\n*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n\"\"\"\n#SOLUCION\n\na = 10\nb = 2\nx = [2, 5, 10]\n\n#Operadores\n\nprint(\"La suma de 10 y 2 es: \", a + b) #Suma\n\nprint(\"La resta de 10 y 2 es: \",a - b) #Resta\n\nprint(\"La multiplicacion de 10 y 2 es: \",a * b)\n\nprint(\"La division de 10 en 2 es: \",a / b)\n\nprint(\"El modulo (Residuo) de 10 / 2 es: \",a % b)\n\nprint(\"10 elevado al 2 es: \",a ** b)\n\nprint(\"La division redondeada de 10 en 3 es: \", a // 3)\n\nb += 3 #otra forma de sumar a una variable\n\nprint(\"La suma de 2 y 3 es: \",b)\n\nb -= 3 #otra forma de restar a una variable\n\nprint(\"La resta de 5 y 3 es: \", b)\n\na *= 3 #otra forma de multiplicar a una variable\n\nprint(\"La multiplicacion de 10 y 3 es: \",a)\n\na /= 3 #otra forma de dividir a una variable\n\nprint(\"La divison de 30 entre 3 es: \",a)\n\na %= 3 #otra forma de sacar el modulo a una variable\n\nprint(\"El modulo (Residuo) de 10 / 3 es: \", a)\n\nb //= 1.2  #otra forma de sacar la division redondeada a una variable\n\nprint(\"El resulatdo redondeado de de 2 / 1.2 es: \",a)\n\na **= 3 #otra forma de sacar la potencai x de una variable\n \nprint(\"El resulatdo de 1 elevado a la 3 es: \", a)\n\nprint(\"1 y 1 son lo mismo?: \", a == b) #Comparacion de igualdad entre dos varibles // True o False\n\nprint(\"1 y 1 son lo diferentes?: \", a != b) #Comparacion de diferncia entre dos varibles // True o False\n\nprint (\"1 es mayor que 1?: \",a > b) #Comparacion de que valor es más grande > // True o False\n\nprint(\"1 es menor que 2?: \",a < 2) #Comparacion de que valor es más grande < // True o False\n\nprint(\"1 es mayor o igual que 1?: \",a >= b) #Comparacion de que valor es más grande o igualdad (inclusivo) > // True o False\n\nprint(\"1 es menor o igual que 2?: \",a <= 2) #Comparacion de que valor es más grande o igualdad (inclusivo) < // True o False\n\nprint(a > b and a < 100) #operador \"and\" devuelve true si los dos statements son verderos (True) // True o False\n\nprint(a < b or a < 100) #operador \"or\" devuelve true si uno de los dos statements son verderos (True) // True o False\n\nprint(not(a > b and a < 100)) #operador \"not\" invierte el resultado del operador logioo // True o False\n\nprint(a in x) #Operador \"in\" para revisar si un elemento esta en otro // Este caso de variable en lista // True o False\n\nprint(b not in x) #Operador \"not in\" para revisar si un elemento no esta en otro // Este caso de variable en lista // True o False\n\n#Estructuras de Control\n\n#if Else\n\nif a > b:\n    print(\"a es mayor que b!\")\nelif a < b:\n    print(\"b es mayor que a!\")\nelse:\n    print(\"a y b son iguales!\")\n\n#While\n    \nwhile a < 5:\n    print(a)\n    a += 1\n\n#For\n\nfor i in x:\n  if i == 10:\n    break\n  print(i)\n\n#Try Except\n\ntry:\n  print(x)\nexcept:\n  print(\"Un error ocurrió\")\n\n#EXTRA\n\"\"\"\nExtra Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\n if x % 2 == 0 | x % 3 != 0 | x != 16:\n\"\"\"\n\nfor x in range(10, 55):\n   if  x % 3 != 0 and x % 2 == 0 and x != 16 :\n      print(x)\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/santiagobailleres.py",
    "content": "'''\n* EJERCICIO:\n* - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n*   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n*   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n* - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n*   que representen todos los tipos de estructuras de control que existan\n*   en tu lenguaje:\n*   Condicionales, iterativas, excepciones...\n* - Debes hacer print por consola del resultado de todos los ejemplos.\n*\n* DIFICULTAD EXTRA (opcional):\n* Crea un programa que imprima por consola todos los números comprendidos\n* entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n*\n* Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n*/\n'''\n# 1. Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n#   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n#   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n\n# Operadores aritméticos: estos son los operadores que se utilizan para realizar operaciones matemáticas.\n# En Python tenemos los siguientes operadores aritméticos:\n# + (suma), - (resta), * (multiplicación), / (división), % (módulo), ** (exponente), // (división entera)\nprint(f\"Suma: 1 + 2 = {1 + 2}\")\nprint(f\"Resta: 1 - 2 = {1 - 2}\")\nprint(f\"Multiplicación: 1 * 2 = {1 * 2}\")\nprint(f\"División: 1 / 2 = {1 / 2}\")\nprint(f\"Módulo: 1 % 2 = {1 % 2}\")\nprint(f\"Exponente: 1 ** 2 = {1 ** 2}\")\nprint(f\"División entera: 1 // 2 = {1 // 2}\")\n\n# Operadores de comparación: estos operadores se utilizan para comparar dos valores.\n# En Python tenemos los siguientes operadores de comparación:\n# == (igualdad), != (desigualdad), >\nprint(f\"Igualdad: 1 == 2 es {1 == 2}\")\nprint(f\"Desigualdad: 1 != 2 es {1 != 2}\")\nprint(f\"Mayor que: 1 > 2 es {1 > 2}\")\nprint(f\"Menor que: 1 < 2 es {1 < 2}\")\n\n# Operadores lógicos: estos operadores se utilizan para combinar expresiones lógicas.\n# En Python tenemos los siguientes operadores lógicos:\n# and (y), or (o), not (no)\nprint(f\"AND &&: 1 == 1 and 2 == 2 es {1 == 1 and 2 == 2}\") #tambien el and se puede escribir como &&\nprint(f\"OR ||: 1 == 1 or 2 == 2 es {1 == 1 or 2 == 2}\") #tambien el or se puede escribir como ||\nprint(f\"NOT !: not 1 == 2 es {not 1 == 2}\") #tambien el not se puede escribir como !\n\n# Operadores de asignación: estos operadores se utilizan para asignar un valor a una variable.\n# En Python tenemos los siguientes operadores de asignación:\n# = (asignación), += (suma y asignación), -= (resta y asignación), *= (multiplicación y asignación), /= (división y asignación), %= (módulo y asignación), **= (exponente y asignación), //= (división entera y asignación)\nnum = 2  # asignación\nprint(num)\nnum += 1  # suma y asignación\nprint(num)\nnum -= 1  # resta y asignación\nprint(num)\nnum *= 2  # multiplicación y asignación\nprint(num)\nnum /= 2  # división y asignación\nprint(num)\nnum %= 3  # módulo y asignación\nprint(num)\nnum **= 2  # exponente y asignación\nprint(num)\nnum //= 2  # división entera y asignación\nprint(num)\n\n# Operadores de identidad: estos operadores se utilizan para comparar la identidad de dos objetos.\n# En Python tenemos los siguientes operadores de identidad:\n# is (es), is not (no es)\nnum2 = num\nprint(f\"num is num2 es {num is num2}\") #tambien el is se puede escribir como ==\nprint(f\"num is not num2 es {num is not num2}\") #tambien el is not se puede escribir como !=\n\n# Operadores de pertenencia: estos operadores se utilizan para comprobar si un objeto está presente en otro objeto.\n# En Python tenemos los siguientes operadores de pertenencia:\n# in (en), not in (no en)\ncadena = \"Hola Mundo\"\nprint(f\"'a' in 'Hola Mundo' = {'a' in 'Hola Mundo'}\")\nprint(f\"'b' not in 'Hola Mundo' = {'b' not in 'Hola Mundo'}\")\n\n# Operadores de bit: estos operadores se utilizan para realizar operaciones a nivel de bits.\n# En Python tenemos los siguientes operadores de bit:\n# & (AND), | (OR), ^ (XOR), ~ (NOT), << (desplazamiento a la izquierda), >> (desplazamiento a la derecha)\na = 5  # 0101 en binario\nb = 2  # 0010 en binario\nprint(f\"AND: 5 & 2 = {5 & 2}\")  # 0000 en binario\nprint(f\"OR: 5 | 2 = {5 | 2}\")  # 0111 en binario\nprint(f\"XOR: 5 ^ 2 = {5 ^ 2}\")  # 0111 en binario\nprint(f\"NOT: ~5 = {~5}\")  # 1010 en binario\nprint(f\"Desplazamiento a la derecha: 5 >> 2 = {5 >> 2}\")  # 0001 en binario\nprint(f\"Desplazamiento a la izquierda: 5 << 2 = {5 << 2}\")  # 10100 en binario \n\n# 2. Utilizando las operaciones con operadores que tú quieras, crea ejemplos \n# que representen todos los tipos de estructuras de control que existan\n# en tu lenguaje: Condicionales, iterativas, excepciones...\n\n# Condicionales\nnum = 5\nif num == 10:\n    print(\"num es 10\")\nelif num == 20:\n    print(\"num es 20\")\nelse:\n    print(\"num no es ni 10 ni 20\")\n\n# Iterativas\nnum = 0\nwhile num < 5:\n    print(num)\n    num += 1\n\nfor i in range(5):\n    print(i)\n\n# Manejo de excepciones\ntry:\n    print(10 / 0)\nexcept:\n    print(\"No se puede dividir por cero\")\nfinally:\n    print(\"Ha finalizado el manejo de excepciones\")\n\n# 3. Crea un programa que imprima por consola todos los números comprendidos\n# entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\nfor num in range(10,56):\n    if num % 2 == 0 and num != 16 and num % 3 != 0:\n        print(num)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/santiagobima.py",
    "content": "#operadores aritmeticos\n\na = 20\nb = 3\n\nprint('suma',a+b)\nprint('resta',a-b)\nprint('multiplicacion',a*b)\nprint('division',a/b)\nprint('modulo',a%b)\nprint('potencia',a**b)\n\n\n#operadores lógicos\n\nc = True\nd = False\n\nprint('and logico', c and d)\nprint('or logico',c or d)\nprint('NOT logico',  not d)\n\n#Operadores de comparacion\n\nprint('Mayor que', a>b)\nprint('menos que', a<b)\nprint('igualdad:', a==b)\nprint('distinto que', a!=b)\nprint('mayor o igual', a>=b)\nprint('menos o igual', a<=b)\n\n\n#Operadores de asignacion\n\nt = 10\n\nprint('Asignacion inicial', c)\n\nc+=2\n\nc*=3\n\nprint('resultado final',c)\n\n#Operadores de identidad // intentan comparar el valor en memoria.\n\ne = [1,2,3]\nf = [1,2,3]\n\nprint('es igual', e is f)\nprint('no es igual', e is not f)\n\ne = f\n\nprint('ahora si : ', e is f)\n\n#Operadores de pertenencia\n\nprint('3 esta en la lista', 3 in e)\n\nprint('5 no esta en la lista', 5 not in e)\n\n#Operadores de bit\n\na = 10 #1010\n\nb = 3 #0011\n\nprint(f'AND: 10 & 3 = {10 & 3}')\nprint(f'OR: 10 | 3 = {10 & 3}')\nprint(f'OR: 10 ^ 3 = {10 & 3}')\n \n \n\n\n#Estructuras de control\n\n#Condicionales\n\nif a > b:\n    print('a es mayor que b')\n\nelif a == b:\n    print('a es igual a b')\n    \nelse:\n    print('a es menor que b')\n    \n#While\n\ncount = 0\n\nwhile count < 0:\n    print(count)\n    count +=1\n    \n#For\n\nfor i in range(10):\n    print(i)\n    \ntry:\n    result = a / 0\n    \nexcept ZeroDivisionError:\n    print('error no puedo dividir en 0 ')\n    \nfinally:\n    print('Ha finalizado el manejo de excepciones')\n\n\n#€xtra\nfor i in range(10,56):\n    if i % 2 == 0 and i != 16 and i % 3 != 0 : \n        print(i)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/santiagodc8.py",
    "content": "# Operadores\n\n# Operadores Aritmeticos\nprint(f'Suma: 10 + 3 = {10 + 3}')\nprint(f'Resta: 10 - 3 = {10 - 3}')\nprint(f'Multiplicacion: 10 * 3 = {10 * 3}')\nprint(f'Division: 10 / 3 = {10 / 3}')\nprint(f'Modulo: 10 % 3 = {10 % 3}')\nprint(f'Suma: 10 + 3 = {10 + 3}')\nprint(f'Exponente: 10 ** 3 = {10 ** 3}')\nprint(f'Division Entera: 10 // 3 = {10 // 3}')\n\n# Operadores de Comparacion\nprint(f\"Igualdad: 10 == 3 es: {10 == 3}\")\nprint(f\"Desigualdad: 10 != 3 es: {10 != 3}\")\nprint(f\"Mayor que: 10 > 3 es: {10 > 3}\")\nprint(f\"Menor que: 10 < 3 es: {10 < 3}\")\nprint(f\"Mayor o igual que: 10 >= 10 es: {10 >= 10}\")\nprint(f\"Menor o igual que: 10 <= 3 es: {10 <= 3}\")\n\n# Operadores Logicos\nprint(f\"AND &&: 10 + 3 == 13 AND 5 - 1 == 4 es {10 + 3 == 13 and 5 - 1 == 4}\")\nprint(f\"OR ||: 10 + 3 == 13 AND 5 - 1 == 4 es {10 + 3 == 13 and 5 - 1 == 4}\")\nprint(f\"NOT !: not 10 + 3 == 14 es {not 10 + 3 == 14}\")\n\n# Operadores de Asignacion\nmy_number = 11 # asignacion\nprint(my_number)\nmy_number += 1 # suma y asignacion\nprint(my_number)\nmy_number -= 1 # resta y asignacion\nprint(my_number)\nmy_number *= 2 # multiplicacion y asignacion\nprint(my_number)\nmy_number /= 2 # division y asignacion\nprint(my_number)\nmy_number %= 2 # modulo y asignacion\nprint(my_number)\nmy_number **= 1 # exponente y asignacion\nprint(my_number)\nmy_number //= 1 # division entera y asignacion\n\n# Operadores de Identidad\nmy_new_number = my_number\nprint(f\"my_number is my_new_number es {my_number is my_new_number}\")\nprint(f\"my_number is not my_new_number es {my_number is not my_new_number}\")\n\n# Operadores de Pertenencia \nprint(f\"'u' in 'santiago' = {'u' in 'santiago'}\")\nprint(f\"'g' not in 'santiago' = {'u' not in 'santiago'}\")\n\n# Operadores de Bit\na = 10 # 1010 bits\nb = 3  # 0011 bits\nprint(f\"AND: 10 & 3 = {10 & 3}\") # 0010\nprint(f\"OR:  10 | 3 = {10 | 3}\") # 1011\nprint(f\"XOR: 10 ^ 3 = {10 ^ 3}\") # 1001\nprint(f\"NOT: ~10 = {~10}\") # 1001\nprint(f\"Desplazamiento a la derecha: 10 >> 2 = {10 >> 2}\") # 0010\nprint(f\"Desplazamiento a la izquierda: 10 << 2 = {10 << 2}\") # 101000\n\n'''\nEstructuras de Control\n'''\n\n# if y else\n\nmy_string = \"duran\"\n\nif my_string == \"Santiago xd\":\n    print(\"my_string es: Santiago xd\")\nelif my_string == \"Duran\":\n    print(\"my_string es: Duran\")\nelse: \n    print(\"my_string no es 'Santiago xd' ni 'Duran'\")\n    \n    \n# Iterativas\nfor i in range(11):\n    print(i)\n    \n\ni = 0\n\nwhile i <= 10:\n    print(i)\n    i += 1\n    \n# Manejo de Excepciones\ntry:\n    print(10 / 0)\nexcept:\n    print(\"No se puede dividir por 0\")\nfinally:\n    print(\"Se ha finalizado el manejo de excepciones\")\n    \n    \n'''\nExtra\n'''\n\nfor number in range(10, 56):\n    if number % 2 == 0 and number != 16 and number % 3 != 0:\n        print(number)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/santyjL.py",
    "content": "##01 - OPERADORES Y ESTRUCTURAS DE CONTROL\n\"\"\"\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\"\"\"\n\n#Aritméticos\nsuma : int = 3 + 4\nresta : int = 3 - 4\nmultiplicacion : int = 3 * 4\ndivision : float = 3 / 4                                    #siempre regresa un float\npotencia : int = 3 ** 5\nDivision_baja : int = 3 // 3                                #las divisiones bajas regresan un valor entero , el mas bajo por ejemplo si la resuesta es 4.9 regresara 4 int\nresto : float = 3 % 4                                       #regresa el restante de una division\n\nprint(\"------------Aritméticos----------------\")\nprint(f\"\"\"\n        suma  3 + 4 = {suma}\n        resta  3 - 4 = {resta}\n        multiplicacion  3 * 4 = {multiplicacion}\n        division  3 / 4 = {division}\n        potencia  3 ** 5 = {potencia}\n        Division_baja   3 // 3 = {Division_baja}\n        resto  3 % 3 = {resto}\n      \"\"\")\n\n#logicos\nprint(\"------------logicos----------------\")\n\nprint(\"True and True = \" , True and True)                #para que and sea sierto las 2 opciones tienen que ser verdaderas si no false\nprint(\"True and False = \" , True and False)\n\nprint(\"True or False = \" , True or False)                #con que una sea verdadera regresara verdadero si no false\nprint(\"False or False = \", False or False)\n\nprint(\"not False = \",not False)                         #retorna >true\nprint(\"not True = \",not True)                           #retorna < false\n\n#comparación\nprint(\"------------comparación----------------\")\n\nmayor_que : bool = 3 > 4\nmenor_que : bool= 3 < 4\nigual_que : bool = 3 == 4\ndiferente_que : bool = 3 != 4\nmayor_o_igual : bool = 3 >= 4\nmenor_o_igual : bool = 3 <= 4\n\nprint(f\"\"\"\n        mayor_que  3 > 4 {mayor_que}\n        menor_que  3 < 4 {menor_que}\n        igual_que  3 == 4 {igual_que}\n        diferente_que  = 3 != 4 {diferente_que}\n        mayor_o_igual  = 3 >= 4 {mayor_o_igual}\n        menor_o_igual  = 3 <= 4 {menor_o_igual}\n      \"\"\")\n\n#asignación\nprint(\"------------asignación----------------\")\n\nvariable_vacia : int = 12\nvariable_vacia += 3\nvariable_vacia -= 4\nvariable_vacia *= 2\nvariable_vacia /= 2\nvariable_vacia **= 3\nvariable_vacia //= 6\nvariable_vacia %= 4\n\nprint(\"\"\"\n    VARIABLE += 3\n    VARIABLE -= 4\n    VARIABLE *= 2\n    VARIABLE /= 2\n    VARIABLE **= 3\n    VARIABLE //= 6\n    VARIABLE %= 4\n     \"\"\")\n\n#identidad\nprint(\"------------identidad----------------\")\n\nmayor_que is True\nnot menor_que is False\n\nprint(\"\"\"\n        is\n        not is\"\"\")\n\n#pertenencia\nprint(\"------------pertenencia----------------\")\nmy_variable = \"hola mundo\"\n\nresultado1 = \"hola\" in my_variable\nresultado2 = \"hola\" not in my_variable\nprint(\"\"\"\n        in\n        not in\"\"\")\n\n#bits\nprint(\"------------bits----------------\")#este no se usa casi nunca por no decir nunca\nnum1 = 0b101\nnum2 = 0b011\n\nresultado_and = num1 & num2\nresultado_or = num1 | num2\nresultado_xor = num1 ^ num2\nresultado_izquierda = num1 << 2\nresultado_derecha = num1 >> 2\n\nprint(f\"\"\"\n        resultado_and = {resultado_and}\n        resultado_or = {resultado_or}\n        resultado_xor = {resultado_xor}\n        resultado_izquierda = {resultado_izquierda}\n        resultado_derecha = {resultado_derecha}\n      \"\"\")\n\n\"\"\"\n#control de flujo\n#bucles\n#range para repetir una cantidad de veces definida\n\"\"\"\n\nfor i in range(1 , 4):\n    print(f\"------------{i}----------------\")\n\n#for para iterar cada elemento de la lista\nfor i in [1 , 2 , 4 ,6]:\n    print(i)\n\n\nprint(\"------------while----------------\\n\")\ni = 0\n\n#while se ejecuta mientras la condicion se cumpla , cuidado con los bucles infinitos\nwhile i < 5:\n    print(i)\n    i += 1\n\n\n#Condicionales\nprint(\"------------Condicionales_&_excepciones----------------\\n\")\n\nclave = 1234\n\ntry: #manejo de excepciones\n    clave_introducida = int(input(\"introduce la contraseña numerica : \"))\n\n    if clave == clave_introducida: #si retorna un True se ejecuta si no se ejecutara el else\n        print(\"contraseña correcta\")\n\n    else :\n        print(\"contraseña incorrecta\")\n\nexcept ValueError as error:\n    print(\"el valor no es numerico\")\n\n\nprint(\"------------Condicionales_&_comparadores_logicos----------------\\n\")\n\nfor number in range(1, 46):\n\n    if number % 3 == 0 and number % 5 == 0:\n        print(number , \"fizzbuzz\")\n\n    elif number % 3 == 0:\n        print(number , \"fizz\")\n\n    elif number % 5 == 0:\n        print(number , \"buzz\")\n\n#EXTRA\n\nprint(\"------------reto_extra----------------\\n\")\nfor i in range(10 , 56):\n\n    if i == 16:\n        continue\n\n    if i % 2 == 0 :\n        if i % 3 != 0 :\n            print(i)\n    else :\n        continue"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/sarismejiasanchez.py",
    "content": "# OPERADORES ARITMETICOS\n\"\"\"\nhttps://quickref.me/python.html\nUn operador aritmético toma dos operandos como entrada, realiza un cálculo y devuelve el resultado.\n\"\"\"\nprint(\"OPERADORES ARITMETICOS\")\nresult = 10 + 30 # => 40\nprint(f\"10 + 30 = {result}\")\nresult = 40 - 10 # => 30\nprint(f\"40 - 10 = {result}\")\nresult = 50 * 5  # => 250\nprint(f\"50 * 5 = {result}\")\nresult = 16 / 4  # => 4.0 (Float Division)\nprint(f\"16 / 4 = {result}\")\nresult = 16 // 4 # => 4 (Integer Division)\nprint(f\"16 // 4 = {result}\")\nresult = 25 % 2  # => 1\nprint(f\"25 % 2 = {result}\")\nresult = 5 ** 3  # => 125\nprint(f\"5 ** 3 = {result}\")\n\n\n# OPERADORES LOGICOS\n\"\"\"\nhttps://ellibrodepython.com/operadores-logicos\nSe utiliza un operador lógico para tomar una decisión basada en múltiples condiciones. \nLos operadores lógicos utilizados en Python son  and, or y not.\n\"\"\"\nprint(\"OPERADORES LOGICOS\")\n# AND\n    # Devuelve True si ambos operandos son True\nprint(\"AND\")\nprint(f\"True and True: {True and True}\")   # True\nprint(f\"True and False: {True and False}\")  # False\n\n# OR\n    # Devuelve True si alguno de los operandos es True\t\nprint(\"OR\")\nprint(f\"True or True: {True or True}\")   # True\nprint(f\"True or False: {True or False}\")  # True\nprint(f\"False or True: {False or True}\")  # True\nprint(f\"False or False: {False or False}\") # False\nprint(f\"True and True and False: {True and True and False}\")\n#     |-----------|\n#           True  and  False\n#         |------------------|\n#                False\nprint(f\"False and True or True or False: {False and True or True or False}\")\n#     False and True = False\n#               Fase or True = True\n#                       True or False = True\n# True\n\n# NOT\n    # Devuelve True si alguno de los operandos False\nprint(\"NOT\")\nprint(f\"not True: {not True}\")  # False\nprint(f\"not False: {not False}\") # True\nprint(f\"not not not not True: {not not not not True}\") # True\nprint(f\"not 0: {not 0}\") # True\nprint(f\"not 1: {not 1}\") # False\n\n# COMPARACION / RELACIONALES\n\"\"\"\nhttps://www.freecodecamp.org/espanol/news/operadores-basicos-en-python-con-ejemplos/\nUn operador relacional se emplea para comparar y establecer la relación entre ellos. \nDevuelve un valor booleano (true o false) basado en la condición.\n\"\"\"\nprint(\"COMPARACION / RELACIONALES\")\n\n\"\"\"\nMayor que (>)\nDevuelve True si el operador de la izquierda es mayor que el operador de la derecha\t\n\"\"\"\nprint(f\"12 > 3: {12 > 3}\") # True\n\n\"\"\"\nMenor que (>)\nDevuelve True si el operador de la derecha es mayor que el operador de la izquierda\t\n\"\"\"\nprint(f\"12 < 3: {12 < 3}\") # False\n\n\"\"\"\nIgualdad (==)\nDevuelve True si ambos operandos son iguales\n\"\"\"\nprint(f\"12 == 3: {12 == 3}\") # False\n\n\"\"\"\nMayor o Igual que (>=)\nDevuelve True si el operador de la izquierda es mayor o igual que el operador de la derecha\n\"\"\"\nprint(f\"12 >= 3: {12 >= 3}\") # True\nprint(f\"12 >= 12: {12 >= 12}\") # True\nprint(f\"12 >= 13: {12 >= 13}\") # False\n\"\"\"\nMenor o Igual que (<=)\nDevuelve True si el operador de la derecha es mayor o igual que el operador de la izquierda\t\n\"\"\"\nprint(f\"12 <= 3: {12 <= 3}\") # False\nprint(f\"12 <= 12: {12 <= 12}\") # True\nprint(f\"12 <= 13: {12 <= 11}\") # False\n\"\"\"\nDiferente (!=)\nDevuelve True si ambos operandos no son iguales\t\n\"\"\"\nprint(f\"12 != 3: {12 != 3}\") # True\nprint(f\"12 != 12: {12 != 12}\") # False\n\n# OPERADORES DE ASIGNACION\n\"\"\"\nhttps://ellibrodepython.com/operadores-asignacion#operadores-de-asignaci%C3%B3n\nSe utiliza un operador de asignación para asignar valores a una variable. \nEsto generalmente se combina con otros operadores (como aritmética, bit a bit) \ndonde la operación se realiza en los operandos y el resultado se asigna al operando izquierdo.\n\"\"\"\nprint(\"OPERADORES DE ASIGNACION\")\nprint(\"Operador = 5\")\n\"\"\"\nasigna a la variable de la izquierda el contenido que le ponemos a la derecha\n\"\"\"\na = 5\nprint(f\"a = {a}\") # El valor 5 es asignado a la variable a\n\nprint(\"Operador += 5\")\n\"\"\"\nEl operador += en a += 5 es equivalente a a=a+5. \n\"\"\"\na += 5 # es equivalente a a = a + 5\nprint(f\"a += {a}\")\n\nprint(\"Operador -= 5\")\n\"\"\"\nEl operador -= es equivalente a restar y asignar el resultado a la variable inicial. \nEs decir, a-=5 es equivalente a a=a-5.\n\"\"\"\na -= 5 # es equivalente a a = a - 5\nprint(f\"a -= {a}\")\n\nprint(\"Operador *= 5\")\n\"\"\"\nEl operador *= equivale a multiplicar una variable por otra y almacenar el resultado en la primera, \nes decir a*=5 equivale a a=a*5.  \n\"\"\"\na *= 5 # es equivalente a a = a * 5\nprint(f\"a *= {a}\")\n\nprint(\"Operador /= 5\")\n\"\"\"\nEl operador /= equivale a dividir una variable por otra y almacenar el resultado en la primera, \nes decir a/=5 equivale a a=a/5.  \n\"\"\"\na /= 5 # es equivalente a a = a / 5\nprint(f\"a /= {a}\")\n\nprint(\"Operador %= 5\")\n\"\"\"\nEl operador %= equivale a hacer el módulo de la división de dos variables \ny almacenar su resultado en la primera.\n\"\"\"\na %= 5 # es equivalente a a = a % 5\nprint(f\"a %= {a}\")\n\nprint(\"Operador **= 5\")\n\"\"\"\nEl operador **= realiza la operación exponente del primer número elevado al segundo, \ny almacena el resultado en la primera variable. \nEl equivalente de a**=5 sería a=a**a.\n\"\"\"\na **= 5 # es equivalente a a = a ** 5\nprint(f\"a **= {a}\")\n\nprint(\"Operador //= 5\")\n\"\"\"\nEl operador //= realiza la operación cociente entre dos variables \ny almacena el resultado en la primera. El equivalente de a//=5 sería a=a//5.\n\"\"\"\na //= 5 # es equivalente a a = a // 5\nprint(f\"a //= {a}\")\n\nprint(\"Operador &=\")\n\"\"\"\nEl operador &= realiza la comparación & bit a bit entre dos variables y \nalmacena su resultado en la primera. El equivalente de a&=1 sería a=a&1\n\"\"\"\na = 0b101010\na&= 0b111111\nprint(bin(a)) # # 0b101010\n\nprint(\"Operador |=\")\n\"\"\"\nEl operador |= realiza el operador | elemento a elemento entre dos variables \ny almacena su resultado en la primera. El equivalente de x|=5 sería x=x|5\n\"\"\"\na = 0b101010\na|= 0b111111\nprint(bin(a)) # 0b111111\n\nprint(\"Operador ^=\")\n\"\"\"\nEl operador ^= realiza el operador ^ elemento a elemento entre dos variables \ny almacena su resultado en la primera. El equivalente de x^=2 sería x=x^2\n\"\"\"\na = 0b101010\na^= 0b111111\nprint(bin(a)) # 0b10101\n\nprint(\"Operador »=\")\n\"\"\"\nEl operador >>= es similar al operador >> pero permite almacenar el resultado en la primera variable. \nPor lo tanto x>>=3 sería equivalente a x=x>>3\n\"\"\"\na = 10\na >>= 1 # 5\nprint(f\"a >> {a}\")\n\nprint(\"Operador «=\")\n\"\"\"\nMuy similar al anterior, <<= aplica el operador << y almacena su contenido en la primera variable. \nEl equivalente de x<<=1 sería x=x<<1\n\"\"\"\na = 10     # Inicializamos a 10\na <<=1    # Desplazamos 1 a la izquierda\nprint(f\"a << {a}\") # 20\n\n\n# IDENTIDAD\nprint(\"OPERADORES DE IDENTIDAD\")\n\"\"\"\nhttps://www.freecodecamp.org/espanol/news/operadores-basicos-en-python-con-ejemplos/\nUn operador de identidad se emplea para comprobar si dos variables emplean la misma ubicación en memoria.\n\"\"\"\nprint(\"Operador is devuelve True si los operandos se refieren al mismo objeto. En caso contrario devuelve False.\")\nprint(\"Operador is not devuelve True si los operandos no se refieren al mismo objeto. En caso contrario devuelve False.\")\na = 3\nb = 3  \nc = 4\nprint(f\"a = {a}\")\nprint(f\"b = {b}\")\nprint(f\"c = {c}\")\nprint(f\"a is b: {a is b}\") # True\nprint(f\"a is not b: {a is not b}\") # False\nprint(f\"a is not c: {a is not c}\") # True\n\nx = 1\ny = x\nz = y\nprint(f\"x = {x}\")\nprint(f\"y = {y}\")\nprint(f\"z = {z}\")\nprint(f\"z is 1: {z is 1}\") # True\nprint(f\"z is x: {z is x}\") # False\n\n\nstr1 = \"FreeCodeCamp\"\nstr2 = \"FreeCodeCamp\"\n\nprint(f\"str1 = {str1}\")\nprint(f\"str2 = {str2}\")\nprint(f\"str1 is str2: {str1 is str2}\") # True\nprint(f\"'Code' is str2: {\"Code\" is str2}\") # False\n\n\na = [10,20,30]\nb = [10,20,30]\nprint(f\"a = {a}\")\nprint(f\"b = {b}\")\nprint(f\"a is b: {a is b}\") # muestra False (ya que las listas son objetos mutables en Python) \n\n\n# PERTENENCIA\nprint(\"OPERADORES DE PERTENENCIA\")\n\"\"\"\nhttps://www.freecodecamp.org/espanol/news/operadores-basicos-en-python-con-ejemplos/\nUn operador de pertenencia se emplea para identificar pertenencia en alguna secuencia (listas, strings, tuplas).\nin y not in son operadores de pertenencia.\nin devuelve True si el valor especificado se encuentra en la secuencia. En caso contrario devuelve False.\nnot in devuelve True si el valor especificado no se encuentra en la secuencia. En caso contrario devuelve False.\n\"\"\"\na = [1, 2, 3, 4, 5]\nprint(f\"a = {a}\")\n#Esta 3 en la lista a?\nprint(f\"3 in a: {3 in a}\") # Muestra True \n\n#No está 12 en la lista a?\nprint(f\"12 not in a: {12 not in a}\") # Muestra True\n\nstr = \"Hello World\"\nprint(f\"str: {str}\")\n\n#Contiene World el string str?\nprint(f\"'World' in str: {'World' in str}\") # Muestra True\n\n#Contiene world el string str? (nota: distingue mayúsculas y minúsculas)\nprint(f\"'world' in str: {'world' in str}\")  # Muestra False  \n\nprint(f\"'code' not in str: {'code' not in str}\") # Muestra True\n\n# BITS\nprint(\"OPERADORES BIT A BIT\")\n\"\"\"\nhttps://www.freecodecamp.org/espanol/news/operadores-basicos-en-python-con-ejemplos/\nUn operador bit a bit realiza operaciones en los operandos bit a bit.\nConsideremos a = 2 (en binario = 10) y b = 3 (en binario = 11) para los siguientes casos.\n\"\"\"\na = 2 # (en binario = 10)\nb = 3 # (en binario = 11)\nprint(\"\"\"Operador & \\nRealiza bit a bit la operación AND en los operandos\"\"\")\nprint(f\"a & b: {a & b}\") # = 2(Binario: 10 & 11 = 10)\n\nprint(\"\"\"\nOperador | \\nRealiza bit a bit la operación OR en los operandos\"\"\")\nprint(f\"a | b: {a | b}\") # = 3 (Binario: 10 | 11 = 11)\n\nprint(\"\"\"\nOperador ^ \\nRealiza bit a bit la operación XOR en los operandos\"\"\")\nprint(f\"a ^ b: {a ^ b}\") # = 1 (Binario: 10 ^ 11 = 01)\n\nprint(\"\"\"\nOperador ~ \\nRealiza bit a bit la operación NOT bit a bit. Invierte cada bit en el operando\"\"\")\nprint(f\"~ a: {~ a}\") # = -3 (Binario: ~(00000010) = (11111101))\n\nprint(\"\"\"\nOperador >> \n        Realiza un desplazamiento a la derecha bit a bit.\n        Desplaza los bits del operador de la izquierda a la derecha tantos bits \n        como indica el operador de la derecha\"\"\")\nprint(f\"a >> b: {a >> b}\") # = 0 (Binario: 00000010 >> 00000011 = 0)\n\nprint(\"\"\"\nOperador <<\n        Realiza un desplazamiento a la izquierda bit a bit. \n        Desplaza los bits del operando de la izquierda a la izquierda tantos bits \n        como especifique el operador de la derecha\"\"\")\nprint(f\"a << b: {a << b}\") # 16 (Binario: 00000010 << 00000011 = 00001000)\n\n# ESTRUCTURAS DE CONTROL\nprint(\"ESTRUCTURAS DE CONTROL\")\n    # CONDICIONALES\n    # ITERATIVAS\n    # EXCEPCIONES\n\"\"\"\nhttps://ellibrodepython.com/estructuras-control-python#estructuras-de-control-en-python\nhttps://jorgedelossantos.github.io/apuntes-python/Estructuras%20de%20control.html#ciclo-while\nEstas estructuras de control nos permiten repetir un determinado bloque de código tantas veces como queramos.\n\"\"\"\nprint(\"Condicional if-elif-else\")\n\"\"\"\nEl condicional if-elif-else es una estructura de control de selección que sirve para tomar decisiones, \nbasándose en la evaluación de condiciones y/o comparaciones, en el flujo del programa. \n\"\"\"\n# programa que verifica si el valor de a es mayor, menor o igual al valor de b.\na = 10\nb = 30\nprint(f\"a = {a}\")\nprint(f\"b = {b}\")\nif a > b:\n    print(\"a es mayor que b\")\nelif a < b:\n    print(\"a es menor que b\")\nelse:\n    print(\"a es igual a b\")\n\n# Numero par\ncalificacion = 150\nprint(f\"calificacion = {calificacion}\")\n\nif calificacion < 0 or calificacion > 100:\n    print(\"La calificación debe estar en la escala de 0 a 100\")\nelif calificacion >= 70:\n    print(\"Aprobado\")\nelse:\n    print(\"No aprobado\")\n    \nprint(\"Ciclo for\")\n\"\"\"\nEn Python, el ciclo for se utiliza para iterar sobre una secuencia \n(como una lista, tupla, cadena de caracteres, etc.) o cualquier objeto iterable. \nEl formato básico del ciclo for es el siguiente:\n\nfor variable in secuencia:\n    # Código que se ejecuta en cada iteración\nD\nonde:\n\nvariable es una variable que toma el valor de cada elemento en la secuencia en cada iteración del bucle.\nsecuencia es la colección de elementos sobre la cual estás iterando.\n\n\"\"\"\n\nnumeros = [18,50,90,-20,100,80,37]\nprint(f\"numeros = {numeros}\")\nfor n in numeros:\n    print(n)\n\n\nprint(\"Ciclo while\")\n\"\"\"\nEn Python, el ciclo while se utiliza para ejecutar un bloque de código mientras \nuna condición especificada sea verdadera. Su estructura básica es la siguiente:\n\nwhile condicion:\n    # Código que se ejecuta mientras la condición sea verdadera\n\nDonde:\n\ncondicion es la expresión booleana que se evalúa en cada iteración del bucle.\nEl bloque de código que sigue al while se ejecutará repetidamente mientras la condición sea verdadera.\nUn ejemplo sencillo sería un bucle while que imprime los números del 1 al 5:\n\"\"\"\nnumero = 1\n\nwhile numero <= 5:\n    print(numero)\n    numero += 1\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\"\"\"\nprint(\"DIFICULTAD EXTRA\")\nfor i in range(10, 56):\n    if i % 2 == 0: # Pares\n        if i != 16: # No es el 16\n            if i % 3 != 0: # No es multiplo de 3\n                print(i)\n\nprint(\"Optimizado\")\nfor i in range(10, 56):\n    if (i % 2 == 0 and i != 16 and i % 3 != 0):\n        print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/saulmrto.py",
    "content": "\"\"\"\nOperadores\n\"\"\"\n\n# Operadores aritmeticos\nprint(f\"Suma: 10 + 3 = {10 + 3}\")\nprint(f\"Resta: 10 - 3 = {10 - 3}\")\nprint(f\"Multiplicacion: 10 * 3 = {10 * 3}\")\nprint(f\"Division: 10 / 3 = {10 / 3}\")\nprint(f\"Modulo: 10 % 3 = {10 % 3}\")\nprint(f\"Exponente: 10 ** 3 = {10 ** 3}\")\nprint(f\"Division entera: 10 // 3 = {10 // 3}\")\n\n# Operadores de comparacion\nprint(f\"Igualdad: 10 == 3 es {10 == 3}\")\nprint(f\"Desigualdad: 10 != 3 es {10 != 3}\")\nprint(f\"Mayor que: 10 > 3 es {10 > 3}\")\nprint(f\"Menor que: 10 < 3 es {10 < 3}\")\nprint(f\"Mayor que: 10 >= 10 es {10 >= 10}\")\nprint(f\"Menor que: 10 <= 3 es {10 <= 3}\")\n\n# Operadores logicos\nprint(f\"AND &&: 10 + 3 == 13 and 5 - 1 == 4 es {10 + 3 == 13 and 5 - 1 == 4}\")\nprint(f\"OR ||: 10 + 3 == 14 or 5 - 1 == 4 es {10 + 3 == 14 or 5 - 1 == 4}\")\nprint(f\"NOT !: not 10 + 3 == 14 es {not 10 + 3 == 14}\")\n\n# Operadores de asignacion\nmy_number = 11 # asignacion\nprint(my_number)\nmy_number += 1 # suma y asignacion\nprint(my_number)\nmy_number -= 1 # resta y asignacion\nprint(my_number)\nmy_number *= 3 # multiplicacion y asignacion\nprint(my_number)\nmy_number /= 2 # division y asignacion\nprint(my_number)\nmy_number %= 1 # modulo y asignacion\nprint(my_number)\nmy_number **= 1 # exponente y asignacion\nprint(my_number)\nmy_number //= 1 # division entera y asignacion\nprint(my_number)\n\n# Operadores de identidad\nmy_new_number = my_number\nprint(f\"my_number is my_new_number es {my_number is my_new_number}\")\nprint(f\"my_number is my_new_number es {my_number is not my_new_number}\")\n\n# Operadores de pertenencia\nprint(f\"'u' in 'mooure' = {'u' in 'moure'}\")\nprint(f\"'b' not in 'mooure' = {'b' not in 'moure'}\")\n\n# Operadores de bit\na = 10 #  1010\nb = 3 # 0011\nprint(f\"AND: 10 & 3 = {10 & 3}\") # 0010\nprint(f\"OR: 10 | 3 = {10 | 3}\") # 1011\nprint(f\"XOR: 10 ^ 3 = {10 ^ 3}\") # 1001\nprint(f\"NOT: ~10 = {~10}\") # 0101\nprint(f\"Desplazamiento a la derecha: 10 >> 2 = {10 >> 2}\") # 0010\nprint(f\"Desplazamiento a la izquierda: 10 << 2 = {10 << 2}\") # 1000\n\n\"\"\"\nEstructuras de control\n\"\"\"\n\n# Condicionales\n\nmy_string = \"Saul\"\n\nif my_string == \"toonsaul\":\n    print(\"my_string es 'toonsaul'\")\nelif my_string == \"Saul\":\n    print(\"my_string es 'Saul'\")\nelse:\n    print(\"my_string no es 'toonsaul' ni 'Saul'\")\n\n# Iterativas\n\nfor i in range(11):\n    print(i)\n\ni = 0\n\nwhile i  <= 10:\n    print(i)\n    i += 1\n\n# Manejo de excepciones\n\ntry:\n    print(10 / 1)\nexcept:\n    print(\"Se ha producido un error\")\nfinally:\n    print(\"Ha finalizado el manejo de instrucciones\")\n\n\"\"\"\nExtra\n\"\"\"\n\nfor number in range(10, 56):\n    if number % 2 == 0 and number != 16 and number % 3 != 0:\n        print(number)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/seni889.py",
    "content": "# \"\"\"\n# Operadores\n# \"\"\"\n# #operadores aritmeticos\n\nprint(f\"Suma: 10 + 3 = {10 + 3}\")\nprint(f\"Resta = {10 - 3}\" )\nprint (f\"Modulo = {10 % 3}\")\nprint(f\"Multiplicacion = {10 * 3}\")\nprint(f\"division = {10 / 3}\")\n\n#Operadores comparacion\nprint(f\"Igualdad: 10==3 es {10==3}\")\nprint(f\"Desigualdad:!= {10 !=3}\" )\nprint(f\"mayor que = {10>3}\")\nprint(f\"mejor que {10<3}\")\nprint(f\"mayor o igual que = {10 >= 3}\")\nprint(f\"menor o igual que = {10<=3 }\")\n\n#Operadores logicos\nprint(f\"AND es {10 + 3 == 13 and 5 - 1 ==4 }\")\nprint(f\"OR es {10 + 3 == 13 and 5 - 1 ==4 } \")\nprint(f\"NOT es {not 10 + 3 == 14}\") \n\n#Operaciones de aignacion\nmy_number = 11\nprint (my_number)\nmy_number += 4\nprint (my_number)\nmy_number -= 2\nprint(my_number)\nmy_number *=3\nprint(my_number)\nmy_number /=1\nprint(my_number)\nmy_number %= 2\nprint(my_number)\n\n#Operadores de identidad\nmy_new_number = my_number\nprint(f\"my_number is my_new_numberc es {my_number is my_new_number}\")\nprint(f\"my_number is not my_new_numberc es {my_number is not my_new_number}\")\n\n#Operadores de pertenencia\nprint(f\"'u' in 'moure' = {'u' in 'moure'}\")\nprint(f\"'A' in 'Anzin' = {'A' in 'Anzin'}\")\nprint(f\"'b' not in 'lucho'= {'b' not in 'lucho'}\")\n\n#Operadores de bit\na = 10  #numero bits 1010\nb = 3   # 0011\nprint(f\"AND: = {10 & 3}\")\nprint(f\"OR = {a | b}\")\nprint(f\"XOR = {a ^ b}\")\nprint(f\"NOT = {~10}\")\nprint(f\"Desplazamiento D = {a >> b}\")\nprint(f\"Desplazamiento I = {a << b}\")\n\n# \"\"\"\n# Estructura de control\n# \"\"\"\n\n# #condicionales\n# my_string = \"viejo\"\n\n# if my_string == \"anzin\":\n#     print(\"Mi usuario es anzin\")\n# elif my_string == \"viejo\":\n#     print(\"Este si es mi usuario\")    \n# else:\n#     print(\"Ese no es mi usuario\")\n    \n# #Iterativas\n# for i in range(11):\n#     print(i)   \n\n# for i in range(5):\n#     print(i)\n\n# i = 0\n\n# while i <= 10:\n#     print(i)  \n#     i += 1\n\n\n# #Manejo de excepciones\n# try:\n#     print(10 / 0)\n# except:\n#     print(\"Se a producido un error\") \n# finally:\n#     print(\"Ha finalizado el manejo de excepcion\")    \n\n# ##EJERCICIO EXTRA\n     \n# for num in range(10, 56):\n#     if num % 2 ==0 and num !=16 and num % 3 ==0:\n#         print(num)\n\n\n\n# saludo = \"Hola\"\n# print(saludo)  \n# nombre = input(\"¿Como te llamas?: \")   \n# print(\"Bienvenido\", nombre)\n# edad = int(input(\"Ingresa tu edad: \"))\n# print(\"Tu edad es: \", edad)\n\n# if edad>=18:\n\n#     print(\"Usted puede continuar\")\n# else:\n#     print(\"Disculpe no puede continuar\")    \n\n# text = input(\"Quien te envio? \")\n\n# text ==\"anzin\"\n\n# if text == \"anzin\":\n#     print(\"Bienvenido señor\")\n# else:\n#     print(\"Usted no puede ingresar\")   \n    \n\n\n####################################################################\n\n#Operadores \n#Aritmeticos\nx = 15\ny = 5\n\nsuma = x + y \nprint(f\"La suma de 15 + 5: {suma}\")\nresta = x - y\nprint(f\"resta de 15 - 5: {resta}\")\n\n#Comparacion\nprint(f\"15 es mayor que 5? :{15 > 5}\")\nprint(f\"5 es mejor que 15?: {15>5}\")\n\n#asignacion\nnum1 = 5\nprint(f\"Estos numeros son {num1}\")\nnum2 = 10\nprint(f\"Este numero es {num2}\")\n\n#logicos\nprint(f\"estos numeros son: {num1 < 10 and num2 > 5}\")\nprint(f\"num1 es mayor que 10 y num2 es menor que 5: {num1 > 10 or num2<5}\")\nprint(f\"num1 no es mayor que num2: {not(num1 > num2)}\")\n\nj = 10\nif not (j > 5):\n    print(\"j no es mayor que 5\")\nelse:\n    print(\"j es mayor que 5\")\n\n#Condiciones\na = 20\nif a > 5:\n    print(\"a es mayor que 5\")\nelif a == 5:\n    print(\"a es igual a 5\")\nelse:\n    print(\"a es menor que 5\")\n\n\n#Bucles \n    #for\n\npersonas = [\"Jose\", \"Luis\", \"Mateo\"]\nfor persona in personas:\n    print(persona)\n\n#recorrer numeros\nfor i in range(3):\n    print(i)\n\n\n    #while\n#repetir mientras es verdadera\ncontador = 0\nwhile contador < 5:\n    print(contador)\n    contador += 1 #incrementea para evitar bucles infitos\n\n\n\nusuarioc = \"Andy\"\nclavec = \"python123\"\n\nusuario = \"\"\n\nwhile usuario != usuarioc:\n    usuario = input(\"Ingresa tu usuario: \")\n    if usuario != usuarioc:\n        print(\"Usuario incorrecto\")\nprint(f\"Bienvenido señor {usuario}\")\n\nclave = \"\"\nwhile clave != clavec:\n    clave = input(\"Ingrese la clave: \")\n    if clave != clavec:\n        print(\"Contraseña incorrecta. Ingrese otra vez\")\nelse:\n    print(\"Ingreso accedido, disfruta las comodidades\")\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/slaughtbear.py",
    "content": "# T I P O S   D E   O P E R A D O R E S\nprint('======================')\nprint('A R I T M E T I C O S')\nprint('======================')\n# 1. Adición ( + )\nprint(f'800 + 88 = {800 + 88}')\n\n# 2. Substracción ( - )\nprint(f'900 - 12 = {900 - 12}')\n\n# 3. Multiplicación ( * )\nprint(f'444 * 2 = {444 * 2}')\n\n# 4. División ( / )\nprint(f'8880 / 10 = {8880 / 10}')\n\n# 5. Módulo ( % )\nprint(f'1788 % 900 = {1788 % 900}')\n\n# 6. Potencia ( ** )\nprint(f'8 ** 2 = {8 ** 2}')\n\n# 7. División entera\nprint(f'18 // 5 = {18 // 15}')\nprint('======================')\n\n\nprint('R E L A C I O N A L E S')\nprint('======================')\n# 1. Mayor que ( > )\nprint(f'10 > 5 = {10 > 5}')\n\n# 2. Menor que ( < )\nprint(f'10 < 5 = {10 < 5}')\n\n# 3. Igual que ( == )\nprint(f'10 == 10 = {10 == 10}')\n\n# 4. Mayor o igual que ( >= )\nprint(f'8 >= 8 = {8 >= 8}')\n\n# 5. Menor o igual que ( <= )\nprint(f'6 <= 3 = {6 <= 3}')\n\n# 6. Diferente que ( != )\nprint(f'10 != 5 = {10 != 5}')\nprint('======================')\n\nprint('B I T  A  B I T')\nprint('======================')\na = 2 # 10 en binario\nb = 3 # 11 en binario\n\n# 1. AND ( & )\nprint(f'a & b = {a & b}')\n\n# 2. OR ( | )\nprint(f'a | b = {a | b} ')\n\n# 3. XOR ( ^ )\nprint(f'a ^ b = {a ^ b}')\n\n# 4. NOT ( ~ )\nprint(f'~a = {~a}')\n\n# 5. Desplazamiento a la derecha ( >> )\nprint(f'5 >> 1 = {5 >> 1}')\n\n# 6. Desplazamiento a la izquierda ( << )\nprint(f'5 << 1 = {5 << 1}')\nprint('======================')\n\nprint('D E  A S I G N A C I Ó N')\nprint('======================')\n# 1. Asignación ( = )\na = 5\nprint(f'a = {a}')  # a = 5\n\n# 2. Asignación de adición ( += )\na += 1\nprint(f'a += 1 = {a}') \n\n# 3. Asignación de substracción ( -= )\na -= 1\nprint(f'a -= 1 = {a}')  \n\n# 4. Asignación de multiplicación ( *= )\na *= 2\nprint(f'a *= 2 = {a}')  \n\n# 5. Asignación de división ( /= )\na /= 2\nprint(f'a /= 2 = {a}')  \n\n# 6. Asignación de módulo ( %= )\na = 10\na %= 2\nprint(f'a (10) %= 2 = {a}') \n\n# 7. Asignación de potencia ( **= )\na = 8\na **= 2\nprint(f'a (8) **= 2 = {a}')  \n\n# 8. Asignación de división entera ( //= )\na //= 2\nprint(f'a //= 2 = {a}')\nprint('======================')\n\nprint('L Ó G I C O S')\nprint('======================')\n# 1. and\na = 10\nb = 5\nprint(f'a == 10 and b == 5 --> {a == 10 and b == 5}')\n\n# 2. or \nprint(f'a == 10 or b == 15 --> {a == 10 or b == 15}')\n\n# 3. not\na = True\nprint(f'not a = {not a}')\nprint('======================')\n\nprint('D E  P E R T E N E N C I A')\nprint('======================')\n# 1. in\nlista_numeros = [1, 2, 3, 4, 5]\nprint(lista_numeros)\nprint(f'¿Se encuentra en la lista el número \"3\"? --> {3 in lista_numeros}')\nprint('======================')\n\n# 2. not in\nlista_lenguajes = ['Python', 'JavaScript', 'C#', 'PHP']\nprint(lista_lenguajes)\nprint(f'¿No se encuentra en la lista el lenguaje \"Java\"? --> {'Java' not in lista_lenguajes}')\nprint('======================')\n\nprint('D E   I D E N T I D A D')\nprint('======================')\n# 1. is\na = 888\nprint(f'a = 888')\nprint(f'¿a is 888? --> {a is 888}')\n\n# 2. is not\nprint(f'¿a is not 999? --> {a is not 999}')\n\nprint('======================')\n\nprint('E S T R U C T U R A S   D E   C O N T R O L')\nprint('======================')\nprint('1. I F')\nnum = 8\nif num > 0:\n\tprint(f'{num} es un número positivo.')\nprint('======================')\n\nprint('1.1. I F - E L S E')\nif num < 0:\n\tprint(f'{num} es un número negativo.')\nelse:\n\tprint(f'{num} es un número positivo.')\nprint('======================')\n\nprint('1.2. I F - E L I F - E L S E')\nnum = 0\nif num > 0:\n\tprint(f'{num} es un número positivo.')\nelif num < 0:\n\tprint(f'{num} es un número negativo.')\nelse:\n\tprint('El número es cero.')\nprint('======================')\n\nprint('1.3. O P E R A D O R  T E R N A R I O ')\nnum = 8\nprint('Es positivo.') if num > 0 else print('Es negativo.')\nprint('======================')\n\nprint('2. F O R')\nlista_nombres = ['Iván','Gera', 'Joaquín']\nfor nombre in lista_nombres:\n\tprint(nombre)\nprint('======================')\n\nprint('2.1. F O R  E N U M E R A T E')\nlista_nombres = ['Iván', 'Gera', 'Joaquín']\nfor indice, valor in enumerate(lista_nombres):\n\tprint(indice, valor)\nprint('======================')\n\nprint('2.2. F O R  R A N G E')\nfor _ in range(4):\n\tprint('Python')\nprint('======================')\n\t\nprint('3. W H I L E ')\ncontador = 1\n\nwhile contador <= 5:\n    print(contador)\n    contador += 1\nprint('======================')\n\nprint('4. T R Y ')\na = 10\ntry:\n\tresultado = a / 0\nexcept ZeroDivisionError:\n\tprint('No se puede dividir entre cero.')\nprint('======================')\n\nprint(' E X T R A ')\nfor i in range(10, 56): \n    if i % 2 == 0 and i != 16 and i % 3 != 0:  \n        print(i)\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/sniker1223.py",
    "content": "# Arithmetic Operators\nprint('Arithmetic Operators')\nprint('+ Addition: ',5+3)\nprint('- Subtraction: ',5-3)\nprint('* Multiplication: ',5*3)\nprint('/ Division: ',5/3)\nprint('% Modulus: ',5%3)\nprint('** Exponentiation: ',5**3)\nprint('// Floor division: ',5//3)\n\n# Assignment Operators\nprint('\\nAssignment Operators')\nlet =10\nprint('= Assigment: ',let)\nlet+=1\nprint('+= Addition assigment: ',let)\nlet-=1\nprint('-= Substraction assigment: ',let)\nlet *=10\nprint('*= Multiplication assigment: ',let)\nlet /=5\nprint('/= Division assigment: ',let)\nlet %=1.5\nprint('%= Modulus assigment: ',let)\nvar =5\nvar &=3\nprint('&= Bitwise AND assigment: ',var)\nvar |=3\nprint('|= Bitwise OR assigment: ',var)\nvar ^=7\nprint('^= Bitwise XOR assigment: ',var)\nvar >>=0\nprint('>>= right shift assigment: ',var)\nvar <<=1\nprint('<<= left shift assigment: ',var)\n\n# Comparison Operators\nprint('\\nComparison Operators')\nprint('> Greater than:',1 > 2)\nprint('> Less than:',1 < 2)\nprint('== Equal to:',1 == 2)\nprint('!= Equal to:',1 != 2)\nprint('>= Greater to:',1 >= 2)\nprint('<= Less to:',1 <= 2)\n\n# Logical Operators\nprint('\\nLogical Operators')\nx = 2\nprint('and',x < 5 and  x < 10)\nprint('or',x < 5 or  x < 10)\nprint('not',not(x < 5 and x < 10))\n\n# Identity Operators\nprint('is', 1 is 1)\nprint('is not', 1 is not 1)\n\n# Membership Operators\nfuits = [\"apple\", \"banana\"]\nprint(\"banana\" in fuits)\nprint(\"pineapple\" not in fuits)\n\n# CONTROL STRUCTURES\nprint('\\nCONTROL STRUCTURES')\nprint('if')\na = 33\nb = 200\nif b > a:\n  print(\"b is greater than a\")\n\nprint('\\nelif')\na = 33\nb = 33\nif b > a:\n  print(\"b is greater than a\")\nelif a == b:\n  print(\"a and b are equal\")\n\nprint('\\nelse')\na = 200\nb = 33\nif b > a:\n  print(\"b is greater than a\")\nelif a == b:\n  print(\"a and b are equal\")\nelse:\n  print(\"a is greater than b\")\n\nprint('\\nShort Hand If')\na = 200\nb = 33\nif a > b: print(\"a is greater than b\")\n\nprint('\\nShort Hand If ... Else')\na = 2\nb = 330\nprint(\"A\") if a > b else print(\"B\")\n\n# Loops\nprint('\\nwhile')\ni = 1\nwhile i < 6:\n  print(i)\n  i += 1\n\nprint('\\nwhile with break statement')\ni = 1\nwhile i < 6:\n  print(i)\n  if i == 3:\n    break\n  i += 1\n\nprint('\\nwhile with continue statement')\ni = 0\nwhile i < 6:\n  i += 1\n  if i == 3:\n    continue\n  print(i)\n\nprint('\\nwhile with else Statement')\ni = 1\nwhile i < 6:\n  print(i)\n  i += 1\nelse:\n  print(\"i is no longer less than 6\")\n\nprint('\\nfor')\nfruits = [\"apple\", \"banana\", \"cherry\"]\nfor x in fruits:\n  print(x) \n\nprint('\\nfor through a String')\n\nfor x in \"banana\":\n  print(x)\n\nprint('\\nfor with break Statement')\nfruits = [\"apple\", \"banana\", \"cherry\"]\nfor x in fruits:\n  print(x)\n  if x == \"banana\":\n    break\n\nprint('\\nfor with continue Statement')\nfruits = [\"apple\", \"banana\", \"cherry\"]\nfor x in fruits:\n  if x == \"banana\":\n    continue\n  print(x) \n\nprint('\\nfor with range() Function')\nfor x in range(6):\n  print(x) \n  \n# values from 2 to 6\nfor x in range(2, 6):\n  print(x)\n\nprint('\\nElse in For Loop')\nfor x in range(6):\n  print(x)\nelse:\n  print(\"Finally finished!\")\n\n# Challenge. Print numbers between 10 and 55(included), even and odd but not\n# print 16 and multiple of 3.\nprint('\\nchallenge')\nfor x in range(10, 56):\n  if x >= 10 and x % 2 == 0 and x != 16 and not x % 3 == 0 or x == 55: \n    print(x)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/sorubadguy.py",
    "content": "num1 = 2\nnum2 = 10\nnum3 = 100\n#Operadores Aritmeticos\n\nprint(f\"suma: {num1} + {num2} = {num1 + num2}\")\nprint(f\"resta: {num2} - {num1} = {num2 - num1}\")\nprint(f\"multiplicacion: {num1} * {num2} = {num1 * num2}\")\nprint(f\"divicion: {num2} / {num1} = {num2 / num1}\")\nprint(f\"suma: {num1} + {num2} = {num1 + num2}\")\nprint(f\"modulo: {num2} % {num1} = {num2 % num1}\")\nprint(f\"exponente: {num1} ** {num2} = {num1 ** num2}\")\nprint(f\"division entera: {num3} // {num2} = {num3 // num2}\")\n\n#Operadores de comparacion\n\nprint(f\"igual que: {num1} == {num2} = {num1 == num2}\")\nprint(f\"distinto que: {num1} != {num2} = {num1 != num2}\")\nprint(f\"mayor que: {num1} > {num2} = {num1 > num2}\")\nprint(f\"menor que: {num1} < {num2} = {num1 < num2}\")\nprint(f\"mayor o igual que: {num1} >= {num2} = {num1 >= num2}\")\nprint(f\"menor o igual que: {num1} <= {num2} = {num1 <= num2}\")\n\n#Operadores Logicos\n\nprint(f\"AND: {num1} + {num2} = {num3} and {num2} ** {num1} == {num3} = {(num1 + num2 == num3) and (num2 ** num1 == num3)}\")\nprint(f\"OR: {num1} + {num2} = {num3} or {num2} ** {num1} == {num3} = {(num1 + num2 == num3) or (num2 ** num1 == num3)}\")\nprint(f\"NOT: not {num2} ** {num1} == {num3} = {not(num2 ** num1 == num3)}\")\n\n#Operadores de Asignacion\n\nnum3 = num1 + num2\nprint(f\"num3 = num1 + num2: {num3}\")\nnum3 += num1\nprint(f\"num3 += num1: {num3}\")\nnum3 -= num1\nprint(f\"num3 -= num1: {num3}\")\nnum3 *= num1\nprint(f\"num3 *= num1: {num3}\")\nnum3 /= num1\nprint(f\"num3 /= num1: {num3}\")\nnum3 **= num1\nprint(f\"num3 **= num1: {num3}\")\nnum3 //= num1\nprint(f\"num3 //= num1: {num3}\")\nnum3 %= num1\nprint(f\"num3 %= num1: {num3}\")\n\n#Operadores de Identidad\n\nprint(f\"num1 is num3: {num1 is num3}\")\nprint(f\"num1 is not num3: {num1 is not num3}\")\n\n#Operadores de pertenencia\n\nprint(f\"'b' in 'sorubadguy': {'b' in 'sorubadguy'}\")\nprint(f\"'b' not in 'sorubadguy': {'b' not in 'sorubadguy'}\")\n\n#Operadores de bit\n\nnum1 = 5  #0101\nnum2 = 10 #1010\nprint(f\"AND: num1 & num2: {num1 & num2}\") #0000\nprint(f\"OR: num1 | num2: {num1 | num2}\") #1111\nprint(f\"XOR: num1 ^ num2: {num1 ^ num2}\") #1111\nprint(f\"NOT: ~num1: {~num1}\") #1010\nprint(f\"Desplazamiento hacia la izquierda: num1 << num2: {num1 << num2}\")\nprint(f\"Desplazamiento hacia la derecha: num1 >> num2: {num1 >> num2}\")\n\n#Estructuras de Datos\n\n#Condicionales\n\nif(num1 == num2):\n    print(f\"{num1} y {num2} son iguales\")\nelif(num1 == num2):\n    print(f\"{num1} y {num3} son iguales\")\nelse:\n    print(\"ningun numero es igual\")\n\n#Iteraciones\n\nfor i in range(10):\n    print(i)\n\ni=0\n\nwhile i <= 10:\n    print(i)\n    i += 1\n\n#manejo de exepciones\n\ntry:\n    print(25/0)\nexcept:\n    print(\"se ha producido un error\")\nfinally:\n    print(\"fin del manejo de exepciones\")\n\n#Extra\ni=0\n\nfor i in range(10,56):\n    if(i % 2 == 0 and i % 3 != 0 and i != 16):\n        print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/soydaviddev.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\"\"\"\nnum1 = 10\nnum2 = 3\n\n# Aritméticos\nprint(num1 + num2) # Suma\nprint(num1 - num2) # Resta\nprint(num1 * num2) # Multiplicación\nprint(num1 / num2) # División\nprint(num1 % num2) # Módulo\nprint(num1 // num2) # División Entera\nprint(num1 ** num2) # Exponente\n\n# Lógicos\nlogic1 = True\nlogic2 = False\n\nresultado = logic1 and logic2\nprint(resultado)\nresultado = logic1 or logic2\nprint(resultado)\nresultado = not logic1\nprint(resultado)\n\n# Comparación\nprint(num1 == num2)\nprint(num1 != num2)\nprint(num1 > num2)\nprint(num1 < num2)\nprint(num1 >= num2)\nprint(num1 <= num2)\n\n# Asignación\nnum1 = 20\nprint(num1)\nnum1 += 2\nprint(num1)\nnum1 -= 2\nprint(num1)\nnum2 *= 2\nprint(num2)\nnum2 /= 2\nprint(num2)\nnum2 %= 2\nprint(num2)\nnum1 //=2\nprint(num1)\nnum1 **=3\nprint(num1)\n\n# Identidad\nmi_lista = list()\nmi_lista = [1 , 2, 3]\nmi_other_lista = [1 , 2, 3]\nprint(mi_lista is mi_other_lista)\n\nprint(mi_lista is not mi_other_lista)\n\n# Pertenencia\nmi_saludo = \"Hola, Mundo!\"\nprint(\"M\" in mi_saludo)\n\nprint(\"s\" not in mi_saludo)\n\n# Condicionales\n\nif num1 > num2:\n    print(\"El primero es mayor que el segundo\")\nelif num1 == num2:\n    print(\"Son iguales\")\nelse:\n    print(\"El segundo es mayor que el primero\")\n\n# Iterativas\n\nlenguajes = [\"Python\", \"Java\", \"JavaScript\", \"Php\"]\n\nfor lenguaje in lenguajes:\n    print(f\"Me gusta mucho aprender sobre {lenguaje}\")\n\nnum1 = 10\nnum2 = 0\nwhile num1 > num2:\n    print(num2)\n    num2+=2\n\n#Excepciones\ntry:\n    num_user = input(\"Dime un número\")\n    resultado = num1 / int(num_user)\n    print(resultado)\nexcept Exception:\n    print(\"Entrada no válida, intenta que no sea 0 y no introducir texto.\")\nfinally:\n    print(\"El programa ha finalizado\")\n\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n */\n\"\"\"\nnum1 = 55\nnum2 = 10\n\nwhile num2 < num1:\n    if num2 % 2 == 0 and num2 !=16 and num2 % 3 != 0:\n        print(num2)\n    num2 += 2\n    \n\n\n\n    \n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/soydianaibarra.py",
    "content": "# Operadores Aritméticos\nprint(f\"Suma: 10 + 3 = {10 + 3}\")\nprint(f\"Resta: 10 - 3 = {10 - 3}\")\nprint(f\"Multiplicación: 10 x 3 = {10 * 3}\")\nprint(f\"División: 10 / 3 = {10 / 3}\")\nprint(f\"Módulo: 10 % 3 = {10 % 3}\") # El módulo es lo que resta de una división\nprint(f\"Exponente: 10 ** 3 = {10 ** 3}\")\nprint(f\"División Entera: 10 // 3 = {10 // 3}\")\n\n# Operadores de Comparación\nprint(f\"Igualdad: 10 == 3 es {10 == 3}\")\nprint(f\"Desigualdad: 10 != 3 es {10 != 3}\")\nprint(f\"Mayor que: 10 > 3 es {10 > 3}\")\nprint(f\"Menor que: 10 < 3 es {10 < 3}\")\nprint(f\"Mayor o igual que: 10 >= 3 es {10 >= 3}\")\nprint(f\"Menor o igual que: 10 <= 3 es {10 <= 3}\")\n\n# Operadores Lógicos \nprint(f\"AND &&: 10 + 3 == 13 and 5 - 1 == 4 es {10 + 3 == 13 and 5 - 1 == 4}\")\nprint(f\"OR ||: 10 + 3 == 13 or 5 - 1 == 4 es {10 + 3 == 14 or 5 - 1 == 4}\")\nprint(f\"NOT !: not 10 + 3 == 14 es {not 10 + 3 == 14}\")\n\n# Operadores de asignación\nmy_number = 11  # asignación\nprint(my_number)\nmy_number += 1  # suma y asignación\nprint(my_number)\nmy_number -= 1  # resta y asignación\nprint(my_number)\nmy_number *= 2  # multiplicación y asignación\nprint(my_number)\nmy_number /= 2  # división y asignación\nprint(my_number)\nmy_number %= 2  # módulo y asignación\nprint(my_number)\nmy_number **= 1  # exponente y asignación\nprint(my_number)\nmy_number //= 1  # división entera y asignación\nprint(my_number)\n\n# Operadores de identidad, comparan la posición en memoria\nmy_new_number = my_number\nprint(f\"my_number is my_new_number es {my_number is my_new_number}\")\nprint(f\"my_number is not my_new_number es {my_number is not my_new_number}\")\n\n# Operadores de pertenencia\nprint(f\"'u' in 'mouredev' = {'u' in 'mouredev'}\")\nprint(f\"'b' not in 'mouredev' = {'b' not in 'mouredev'}\")\n\n# Operadores de bit\na = 10  # 1010\nb = 3  # 0011\nprint(f\"AND: 10 & 3 = {10 & 3}\")  # 0010\nprint(f\"OR: 10 | 3 = {10 | 3}\")  # 1011\nprint(f\"XOR: 10 ^ 3 = {10 ^ 3}\")  # 1001\nprint(f\"NOT: ~10 = {~10}\")\nprint(f\"Desplazamiento a la derecha: 10 >> 2 = {10 >> 2}\")  # 0010\nprint(f\"Desplazamiento a la izquierda: 10 << 2 = {10 << 2}\")  # 101000\n\n\"\"\"\n=======================\nEstructuras de control\n=======================\n\"\"\"\n\n# Condicionales\n\nmy_string = \"Brais\"\n\nif my_string == \"MoureDev\":\n    print(\"my_string es 'MoureDev'\")\nelif my_string == \"Brais\":\n    print(\"my_string es 'Brais'\")\nelse:\n    print(\"my_string no es 'MoureDev' ni 'Brais'\")\n\n# Iterativas\n\nfor i in range(11):\n    print(i)\n\ni = 0\n\nwhile i <= 10:\n    print(i)\n    i += 1\n\n# Manejo de excepciones\ntry:\n    print(10 / 0)\nexcept:\n    print(\"Se ha producido un error\")\nfinally:\n    print(\"Ha finalizado el manejo de excepciones\")\n\n\"\"\"\n==========================\nExtra\n==========================\n\"\"\"\n\nfor number in range(10, 56):\n    if number % 2 == 0 and number != 16 and number % 3 != 0:\n        print(number)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/soyjosep.py",
    "content": "\n# Operadores Aritméticos\nprint(\"=== Operadores Aritméticos ===\")\na, b = 10, 3\nprint(f\"Suma: {a} + {b} = {a + b}\")\nprint(f\"Resta: {a} - {b} = {a - b}\")\nprint(f\"Multiplicación: {a} * {b} = {a * b}\")\nprint(f\"División: {a} / {b} = {a / b:.2f}\")\nprint(f\"Módulo: {a} % {b} = {a % b}\")\nprint(f\"Exponente: {a} ** {b} = {a ** b}\")\nprint(f\"División Entera: {a} // {b} = {a // b}\")\n\n# Operadores de Comparación\nprint(\"\\n=== Operadores de Comparación ===\")\nprint(f\"Igualdad: {a} == {b} -> {a == b}\")\nprint(f\"Desigualdad: {a} != {b} -> {a != b}\")\nprint(f\"Mayor que: {a} > {b} -> {a > b}\")\nprint(f\"Menor que: {a} < {b} -> {a < b}\")\nprint(f\"Mayor o igual que: {a} >= {b} -> {a >= b}\")\nprint(f\"Menor o igual que: {a} <= {b} -> {a <= b}\")\n\n# Operadores Lógicos\nprint(\"\\n=== Operadores Lógicos ===\")\nx, y = True, False\nprint(f\"AND: {x} and {y} -> {x and y}\")\nprint(f\"OR: {x} or {y} -> {x or y}\")\nprint(f\"NOT: not {x} -> {not x}\")\n\n# Operadores de Asignación\nprint(\"\\n=== Operadores de Asignación ===\")\nnumber = 5\nprint(f\"Asignación inicial: number = {number}\")\nnumber += 2\nprint(f\"Suma y asignación: number += 2 -> {number}\")\nnumber *= 3\nprint(f\"Multiplicación y asignación: number *= 3 -> {number}\")\nnumber /= 2\nprint(f\"División y asignación: number /= 2 -> {number:.2f}\")\nnumber //= 1\nprint(f\"División entera y asignación: number //= 1 -> {number}\")\n\n# Operadores de Identidad\nprint(\"\\n=== Operadores de Identidad ===\")\nx = 10\ny = x\nprint(f\"x is y: {x is y}\")\nprint(f\"x is not y: {x is not y}\")\n\n# Operadores de Pertenencia\nprint(\"\\n=== Operadores de Pertenencia ===\")\nsequence = \"Python\"\nprint(f\"'P' in '{sequence}' -> {'P' in sequence}\")\nprint(f\"'z' not in '{sequence}' -> {'z' not in sequence}\")\n\n# Operadores de Bits\nprint(\"\\n=== Operadores de Bits ===\")\na, b = 10, 3  # 1010 y 0011 en binario\nprint(f\"AND: {a} & {b} = {a & b}\")\nprint(f\"OR: {a} | {b} = {a | b}\")\nprint(f\"XOR: {a} ^ {b} = {a ^ b}\")\nprint(f\"NOT: ~{a} = {~a}\")\nprint(f\"Desplazamiento a la derecha: {a} >> 1 = {a >> 1}\")\nprint(f\"Desplazamiento a la izquierda: {a} << 2 = {a << 2}\")\n\n\"\"\"\nEstructuras de Control en Python\n\"\"\"\n\n# Condicionales\nprint(\"\\n=== Condicionales ===\")\nname = \"Joseph\"\nif name == \"MoureDev\":\n    print(f\"Hola {name}, bienvenido!\")\nelif name == \"Joseph\":\n    print(f\"Hola {name}, has sido identificado.\")\nelse:\n    print(f\"Nombre no reconocido: {name}\")\n\n# Bucle For\nprint(\"\\n=== Bucle For ===\")\nfor i in range(5):\n    print(f\"Iteración {i+1}: i = {i}\")\n\n# Bucle While\nprint(\"\\n=== Bucle While ===\")\ncounter = 0\nwhile counter < 3:\n    print(f\"Contador: {counter}\")\n    counter += 1\n\n# Manejo de Excepciones\nprint(\"\\n=== Manejo de Excepciones ===\")\ntry:\n    result = 10 / 0\nexcept ZeroDivisionError as e:\n    print(f\"Error: {e}\")\nfinally:\n    print(\"Finalizó el manejo de la excepción.\")\n\n\"\"\"\nDesafío Extra:\nNúmeros entre 10 y 55, pares, excluyendo 16 y múltiplos de 3.\n\"\"\"\nprint(\"\\n=== Desafío Extra ===\")\nfor number in range(10, 56):\n    if number % 2 == 0 and number != 16 and number % 3 != 0:\n        print(f\"Número válido: {number}\")"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/steven9708m.py",
    "content": "\"\"\"\nCrea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\nAritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n(Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n \"\"\"\n # 1. Operadores aritméticos\n\nfrom pickletools import pystring\n\nnum1 = 8\nnum2 = 6\n\nprint(f\"Suma: 8 + 6 = {num1 + num2}\") #SUMA\nprint (f\"Resta: 8 - 6 = {num1 - num2}\") #RESTA\nprint (f\"Multiplicacion: 8 * 6 = {num1 * num2}\") # Multiplicacion\nprint (f\"Division: 8 / 6 = {num1 / num2}\") # DIVISION DECIMALES\nprint (f\"Division: 8 // 6 = {num1 // num2}\") # DIVISION ENTERA\nprint (f\"Resto de Division: 8 % 6 = {num1 % num2}\") # MODULO (Resto de una division)\nprint (f\"Potencia: 8 ** 6 = {num1 ** num2}\") # Potencia\n\n# 2. Operadores de comparación\n\nprint (f\"Igual A: 8 == 6 = {num1==num2}\") # Igual A\nprint (f\"Distinto de: 8 != 6 = {num1 != num2}\") # Distinto De\nprint (f\"Mayor que: 8 > 6 = {num1 > num2}\") # Mayor que\nprint (f\"Menor que: 8 < 6 = {num1 < num2}\") # Menor que\nprint (f\"Mayor o Igual que: 8 >= 6 = {num1 >= num2}\") # Mayor o Igual que\nprint (f\"Menor o Igual que: 8 <= 6 = {num1 <= num2}\") # Menor o Igual que\n\n# 3. Operadores lógicos\n\nprint (f\"And: 8 * 6 == 48 AND 48 < 52 es {num1*num2==48 and 48<52}\") #TRUE\nprint (f\"OR: 8 * 6 == 48 OR 48 > 52 es {num1*num2==48 or 48<52}\") #TRUE\nprint (f\"NOT: not 8 * 6 == 46 es {not num1*num2==46}\") #TRUE\n\n# 3. Operadores de asignación\n\nS = 8\nprint(f\"La letra S es = {S}\")\nS += 4\nprint(f\"Suma y Asignacion = {S}\")\nS -= 2\nprint(f\"Resta y Asignacion = {S}\")\nS *= 3\nprint(f\"Multiplicacion y Asignacion = {S}\")\nS /= 10\nprint(f\"Division y Asignacion = {S}\")\nS %= 5\nprint(f\"Modulo y Asignacion = {S}\")\nS **= 4\nprint(f\"Potencia y Asignacion = {S}\")\nS //= 4\nprint(f\"Division Entera y Asignacion = {S}\")\n\n# 4. Operadores de identidad\nSM=20.0\nprint(f\"S is SM es: {S is SM}\")\nprint(f\"S is not SM es: {S is not SM}\")\n\n# 5. Operadores de Pertenecia\n\nprint(f\"'A' in 'Steven' es: {'A' in 'Steven'}\")\nprint(f\"'A' not in 'Steven' es: {'A' not in 'Steven'}\")\n\n# 6. Operadores bit a bit\n\nx = 15 # 1111\ny = 10 # 1010\n\nprint(f\"AND: 15 & 10 = {15 & 10}\") # 1010\nprint(f\"OR: 15 | 10 = {15 | 10}\") # 1111\nprint(f\"XOR: 15 ^ 10 = {15 ^ 10}\") # 0101\nprint(f\"NOT: ~15 = {~15}\")\nprint(f\"Desplazamiento a la Derecha: 10 >> 2 = {10 >> 2}\") \nprint(f\"Desplazamiento a la Izquierda: 10 << 2 = {10 << 2}\")\n\n\n'''\nESTRUCTURAS DE CONTROL\n'''\n\n#CONDICIONALES\n\nmy_string = \"Miranda\"\n\nif my_string == \"Miranda\":\n    print (\"My_String es 'Miranda'\")\nelif my_string == \"Romero\":\n    print (\"My_String es 'Romero'\")\nelse:\n    print (\"My_String No es 'Miranda' ni 'Romero'\")\n    \n# Iterativas\n\nfor i in range (11):\n    print (i)\n\ni = 0\n\nwhile i <= 10:\n    print(i)\n    i += 1\n    \n# MANEJO DE EXCEPCIONES\n\ntry:\n    print (10/0)\n\nexcept:\n    print (\"Se ha producido un error\")\n\nfinally:\n    print (\"Ha finalizadp el manejo de excepciones\")\n    \n'''\n\nDIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n \n'''\n\nfor number in range (10,56):\n    if number % 2 == 0 and number != 16 and number % 3 != 0:\n        print (number)\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n "
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/strooplab.py",
    "content": "\"\"\"\n    EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\"\"\"\n\n#ejemplos de operadores aritmeticos\n\nsuma = 10+5+2\nresta = 7-2\nmultiplicacion = 5*2\ndivision = 10/2\nresiduo = suma % multiplicacion\ndivisionEntera = division // multiplicacion\npotencia = suma ** resta\nmix = (suma) + (resta) - (multiplicacion) * division / residuo\nprint(mix)\n\n#ejemplos operadores logicos\n\nvar1 = True\nvar2  = False\nprint(var1 and var2)\nprint(var1 or var2)\nprint(not var1)\n\n#ejemplos de comparacion\n\nprint(resta == suma)\nprint(resta != suma)\nprint(resta < suma)\nprint(resta > suma)\nprint(resta <= suma)\nprint(resta >= suma)\n\n#ejemplos de asignacion\n\nnumero = 3\nnumero\nnumero += 3\nnumero -= 3\nnumero *= 2\nnumero /= 2\nnumero %= 2\nnumero //= 2\nnumero **= 2\nprint(numero)\n\n#ejemplos de identidad\n\nlista1 = [1, 1, 2, 3, 5, 8, 13]\nlista2 = [2, 4, 6, 8, 10, 12, 14]\nprint(lista1 is lista2)\nprint(lista1 is not lista2)\n\n#ejemplos de pertentencia\n\nprint(1 in lista2)\nprint(4 not in lista1)\n\n#ejemplos de bits\n\nnumeroBits = 12\nprint(numeroBits << 12)\nprint(numeroBits >> 1)\nprint(numeroBits & 4)\nprint(numeroBits | 4)\nprint(numeroBits ^ 4)\nprint(numeroBits & ~4)\nprint(numeroBits | ~4)\nprint(numeroBits ^ ~4)\n\n#2. Condicionales\n\nif lista1 == lista2:\n    print(\"Las listas son iguales\")\nelif lista1 != lista2:\n    print(\"Las listas son diferentes\")\nelse:\n    print(\"No se cumple ninguna condicion\")\n\n#iterativas\n\nlistaIt =  [1, 2, 3, 4, 5]\nfor i in listaIt:\n    print(i, 'Missisipi')\n\nnum1 = 30\nnum2 = 0\nwhile num2 < num1:\n    print(num2)\n    num2 += 10\n\n#Exceptciones\n\ntry:\n    num1 = 1\n    num2 = 0\n    print(num1 / num2)\nexcept ZeroDivisionError:\n    print(\"No se puede dividir por cero\")\nexcept TypeError:\n    print(\"Error de tipo\")\n\n#Ejercicio adicional\n\nnum1 = 10\nnum2 = 55\n\nwhile num1 < num2:\n    if num1 != 16 and (num1 % 3) != 0:\n        print(num1)\n    num1 += 1\n        \n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/suescun845.py",
    "content": "### Operadores Aritméticos ###\r\n\r\nprint(\"Suma '+'=\", 7+4)\r\nprint(\"Resta '-'=\", 7-4)\r\nprint(\"Multiplicación '*' =\", 7*4)\r\nprint(\"Division '/' =\", 7/4)\r\nprint(\"Modulo '%' = \", 7%4)\r\nprint(\"Division Entera '//' =\", 7//4)\r\nprint(\"Exponenciación '**' =\", 7**4)\r\n\r\n### Operadores De Commparación ###\r\n\r\nprint(\"Igual '-'=\", 7==4)\r\nprint(\"Diferente '!=' =\", 7!=4)\r\nprint(\"Mayor que '>' =\", 7 > 4)\r\nprint(\"Menor que '<' =\", 7 < 4)\r\nprint(\"Mayor o igual que '>=' =\", 7>=4)\r\nprint(\"Menor o igual que '<=' =\", 7 <= 4)\r\n\r\n### Operadores de Asignación ###\r\na=-2\r\nprint(f\"Asignacion '=' = {a}\", )\r\na += 2\r\nprint(f\"Asignacion con suma +'=' = {a}\" )\r\na -= 2\r\nprint(f\"Asignacion con resta '-=' = {a}\" )\r\na *= 2\r\nprint(f\"Asignacion con multiplicación '*=' = {a}\" )\r\na /= 2\r\nprint(f\"Asignacion con división '/=' = {a}\")\r\na //= 2\r\nprint(f\"Asignacion con division entero '//=' = {a}\")\r\na %= 2\r\nprint(f\"Asignacion con modulo '%=' = {a}\")\r\na **= 2\r\nprint(f\"Asignacion con exponenciacion '**=' = {a}\")\r\n\r\n### Operadores Logicos ###\r\n\r\nprint(\"And =\" ,(4 >2 and 145>=6 ))\r\nprint(\"Or =\" ,(4 >2 or 145>=6 ))\r\nprint(\"Not =\", not(4 >2 ))\r\n\r\n### Operadores de Identidad ###\r\n\r\na= [1,3,5]\r\nb= [1,3,5]\r\nc= 5\r\nd= 5\r\nprint(f\"Hacen referencia al mismo objeto en memoria 'is' = {a is b} \")\r\nprint(f\"No hacen referencia al mismo objeto en memoria 'is not' = {a is not b} \")\r\nprint(f\"Hacen referencia al mismo objeto en memoria 'is not' = {c is d} \")\r\nprint(f\"No hacen referencia al mismo objeto en memoria 'is not' = {c is not d} \")\r\n\r\n### Operadores de Pertenencia ###\r\na= [1,3,5]\r\n\r\nprint(f\"El valor esta presente en la secuencia 'in' = {c in a} \")\r\nprint(f\"El valor no esta presente en la secuencia 'in' = {c is not a} \")\r\n\r\n### Operadores De Bits ###\r\n\r\nprint(f\"Operacion de AND entre bits '&' = {12 & 11} \")\r\nprint(f\"Operacion de OR entre bits '|' = {12 | 11} \")\r\nprint(f\"Operacion de comparacion entre bits, si son diferentes es 1, si son iguales 0 '^' = {12 ^ 11} \")\r\nprint(f\"Operacion de dezplazamiento a la izquierda de bits '<<' = {12 << 2} \")\r\nprint(f\"Operacion de dezplazamiento a la derecha de bits '>>' = {12 >> 2} \")\r\n\r\n### Condicionales ###\r\n\r\nx= 10\r\n\r\nif x == 10:\r\n    print(\"X es igual a 10\")\r\nelif x > 10:\r\n    print(\"X es menor a 10\")\r\nelse:\r\n    print(\"X es no es igual o menor a 10\")\r\n\r\n### Iterativas ###\r\n\r\nfor i in range(10):\r\n    print(i) \r\n\r\ncuenta = 0\r\nwhile cuenta > 12:\r\n    print(cuenta)\r\n    cuenta += 1\r\n\r\n### Excepciones ###\r\n\r\ntry:\r\n    indefined = 10/0\r\nexcept:\r\n    print(\"Error al dividir con 0\")\r\nfinally:\r\n    print(\"Esto es una excepción\")\r\n\r\n### Ejercicio Extra ###\r\n\r\nfor i in range (10,56):\r\n    if (i % 2)==0 and (i % 3) != 0 and i != 16:\r\n        print(i)\r\n\r\n\r\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/sunjamer.py",
    "content": "\"\"\"\noperadores\n\"\"\"\n\n# operadores aritméticos\n\nprint (\"aqui operadors\")\n\nprint(f\"Suma 10 + 3 = {10 + 3}\")\nprint(f\"resta 8 - 4 = {8 - 4}\")\nprint(f\"multiplicar 2 * 10 = {2 * 10}\")\nprint(f\"división de 14 / 5 = {14 / 5}\")\nprint(f\"módulo de 14 / 5 = {14 % 5}\")\nprint(f\"exponente de 2 ** 5 = {2 ** 5}\")\nprint(f\"division entera 14 // 5 = {14 // 5}\")\n\n# operadores de comparación\n\nprint(f\"igualdad 8 == 4 es {8 == 4}\")\nprint(f\"es diferente 14 != 5 = {14 != 5}\")\nprint(f\"es 14 > 5 {14 > 5}\")\nprint(f\"es 14 < 5 {14 < 5}\")\nprint(f\"es 14 >= 5 {14 >= 5}\")\nprint(f\"es 14 <= 5 {14 <= 5}\")\n\n\n# operadores logicos\n\nprint(f\"AND es 7 + 5 = 12 and 9 - 6 == 3 {7 + 5 == 12 and 9 - 6 == 3}\")\nprint(f\"OR es 7 + 5 = 12 OR 9 - 6 == 4 {7 + 5 == 12 or 9 - 6 == 4}\")\nprint(f\"NOT 7 + 5 = 12 or 9 - 6 == 3 {not (9 + 6 == 3 or 7 + 5 == 12)}\")\n\n# operadores de asignación\nprint (\"aqui asignacion\")\nmy_variable = 33   # asignación de valor a variable\nprint(my_variable)\nmy_variable+=3\nprint(my_variable)\nmy_variable-=8\nprint(my_variable)\nmy_variable*=3\nprint(my_variable)\nmy_variable/=2\nprint(my_variable)\nmy_variable%=2\nprint(my_variable)\nmy_variable//=1\nprint(my_variable)\n\nmy_variable=0b01000\nmy_variable&=0b10101  # and\nprint(bin(my_variable))\nmy_variable|=0b01100 #or\nprint(bin(my_variable))\nmy_variable|=0b0101 \nprint(bin(my_variable))\n\n# operadores de bit\n\nvar_a = 12  # 1100\nvar_b = 4 # 0100\nprint(f\"AND: 12 & 4 = {12 & 4}\")\nprint(f\"OR: 12 & 4 = {12 | 4}\")\nprint(f\"XOR: 12 ^ 4 = {12 ^ 4}\")\nprint(f\"NOT: 12 = {~ 12}\")\nprint(f\"Deslazamiento a la derecha 12 >> 4 = {12 >> 4}\")\nprint(f\"Deslazamiento a la izquierda 12 << 4 = {12 << 4}\")\n\n# operadores de identidad\n\nmy_variable = 25\n\nmy_new_variable = my_variable\nprint(f\"my_variable is my_new_variable es {my_variable is my_new_variable}\")\nprint(f\"my_variable is not my_new_variable es {my_variable is not my_new_variable}\")\n\n# operadores de pertenencia\npedro = 'pedro'\nprint(f\"'p' en pedro = {'p' in pedro}\")\nprint(f\"'p' no en pedro = {'p' not in pedro}\")\n\n# estructuras de control\n\nmi_cadena = \"patata\"\nif mi_cadena == \"sunjamer\":\n    print(\"mi_cadena és 'sunjamer'\")\nelif mi_cadena == 'pedro':\n    print(\"my cadena no es 'sunjamer' pero si es 'pedro'\")\nelse:\n    print(\"mi cadena no es pedro ni sunjamer\")\n\n  \n\n\n# estructuras de control\n\n# while\n\nindex = 0\nwhile index <= 10:\n    if index == 5 or index == 7:\n        index+=1\n        continue\n    print (index)\n    index+=1\n\n# for\n\nmy_numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\nfor number in my_numbers:\n    print (number)\n\nprint (\"salimos del for\")\n\nlenguaje = \"Python\"\nfor letra in lenguaje:\n    print (letra)\nprint (\"salimos del segundo for\")\n\n\nfor index in range(15):\n    print (index)\nprint (\"salimos del tercer for\")\n\n#manejo de excepciones\n\ntry:\n    print (34 / 4)\nexcept:\n    print (\"hay un error\")\nfinally:\n    print (\"acaba el manejo de excepciones\")\n\n\n# extra\n\nfor index in range (10,56):\n    if index % 2 == 0 and index != 16 and index % 3 != 0: \n        print (index)\nprint (\"fin del extra\")\n\n\n\n\n\n\n\n\n\n\n# ejercicios\n\"\"\"\nmy_age = 46\nmy_weight = 70.3\nmy_complex_variable = 5j+1\n\nprint(\"Entra la base del triangulo\")\nbase = int(input ())\nprint(\"Entra la altura del triangulo\")\nheight = int(input())\narea = 0.5*base*height\nprint(f\"El area del triangulo es {area}\")\n\n\"\"\"\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/super490.py",
    "content": "# Tipos de operadores\n\nnum_1 = 20\nnum_2 = 15\n\n# Operadores aritméticos\n\nprint(num_1 + num_2)  # Suma: 35\nprint(num_1 - num_2)  # Resta: 5\nprint(num_1 * num_2)  # Multiplicación: 300\nprint(num_1 / num_2)  # División: 11.3333333333333333\nprint(num_1 // num_2)  # División entera: 1\nprint(num_1 % num_2)  # Módulo: 5\nprint(num_1 ** num_2)  # Exponenciación: 32768000000000000000\n\n# Operadores de comparación\nprint(num_1== num_2)  # Igual a: False\nprint(num_1!= num_2)  # No igual a: True\nprint(num_1> num_2)  # Mayor que: True\nprint(num_1< num_2)  # Menor que: False\nprint(num_1>= num_2)  # Mayor o igual que: True\nprint(num_1<= num_2)  # Menor o igual que: False\n\n# Operadores lógicos\nprint(num_1 > 18 and num_2 < 30)  # Verdadero si ambas condiciones son verdaderas: True\nprint(num_1 > 35 or num_2 > 10)  # Verdadero si al menos una condición es verdadera: True\nprint(not num_1 > 5)  # Invierte la condición: False\n\n# Operadores de asignación\nx = 10\n\n#  Suma y asignación\nx += 5  # x ahora es 15\nprint(x)\n\n# Resta y asignación\nx -= 3  # x ahora es 12\nprint(x)\n\n# Multiplicación y asignación\nx *= 2  # x ahora es 24\nprint(x)\n\n# División y asignación\nx /= 4  # x ahora es 6.0\nprint(x)\n\n# Módulo y asignación\nx %= 3  # x ahora es 0.0\nprint(x)\n\n# Exponenciación y asignación\nx **= 2  # x ahora es 0.0\nprint(x)\n\n# División entera y asignación\nx //= 2  # x ahora es 0.0\nprint(x)\n\nprint('///////////////////////////////////////////')\n\n# Operadores de Identidad\nx = 10\ny = 10\n\nprint(x is y)  # True: x e y se refieren al mismo objeto (el entero 10)\n\n\na = [1, 2, 3]\nb = [1, 2, 3]\n\nprint(a is b)  # False: a y b son listas iguales, pero están en diferentes ubicaciones de memoria\n\nc = a  # c ahora se refiere al mismo objeto que a\n\nprint(a is c)  # True: a y c se refieren al mismo objeto\n\na.append(4)  # Modificamos la lista a través de a\n\nprint(c)  # c también se ve afectada, ya que se refiere al mismo objeto: [1, 2, 3, 4]\n\n\n# Operadores de Membresía\n\nfrutas = [\"manzana\", \"banana\", \"naranja\"]\n\nprint(\"manzana\" in frutas)    # True: \"manzana\" está en la lista frutas\nprint(\"uva\" in frutas)        # False: \"uva\" no está en la lista frutas\n\nprint(\"manzana\" not in frutas) # False: \"manzana\" está en la lista frutas\nprint(\"uva\" not in frutas)     # True: \"uva\" no está en la lista frutas\n\ntexto = \"Hola mundo\"\n\nprint(\"mundo\" in texto)      # True: \"mundo\" está en la cadena texto\nprint(\"Python\" in texto)     # False: \"Python\" no está en la cadena texto\n\nprint(\"mundo\" not in texto)   # False: \"mundo\" está en la cadena texto\nprint(\"Python\" not in texto)  # True: \"Python\" no está en la cadena texto\n\n# Operadores a nivel de bits\n\na = 5   # 0101 en binario\nb = 3   # 0011 en binario\n\nprint(a & b)  # 1 (0001): AND bit a bit\nprint(a | b)  # 7 (0111): OR bit a bit\nprint(a ^ b)  # 6 (0110): XOR bit a bit\n\nx = 4   # 0100 en binario\n\nprint(x << 2)  # 16 (10000): Desplazamiento a la izquierda 2 posiciones\nprint(x >> 1)  # 2 (0010): Desplazamiento a la derecha 1 posición\n\ny = 2   # 0010 en binario\n\nprint(~y)  # -3 (complemento a 2): NOT bit a bit\n\n# Manejos de excepciones\n    \ntry:\n    resultado = 10 / 0\nexcept ZeroDivisionError:\n    print(\"No se puede dividir por cero.\")\nexcept TypeError:\n    print(\"Los operandos deben ser números.\")\n    \n# DIFICULTAD EXTRA\n\n# Crea un programa que imprima por consola todos los números comprendidos entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\nfor numero in range(10,58):\n    if numero % 2 == 0:\n        if numero != 16:\n            if numero % 3 != 0:\n                print(numero)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/tekatoki.py",
    "content": "'''\nExercise #01: Operadores y estructuras de control\n- Create examples using all the operators of your language:\n    Arithmetic, logics, comparison, asignation, identity, belonging, bits...\n- Using the operations with the operators you want, make examples\nthat represent all control structures that are available on your language:\n    Conditionals, iterations, exceptions...\n- You must print on the terminal the result of all the examples.\n\nDifficulty Extra (optional):\n- Build a program that prints by console all the numbers between 10 and 55 (included), even numbers and are either multiple of 3 nor the 16\n'''\n\ndef logics():\n    num1 : float = 2.5\n    num2 : int = 7\n    word : str = 'hello world'\n    list_num : list = [2, 5, 8, 20, 38]\n\n    if 2.5 == num1 and 7 == num2:\n        print(f'num1 is 2.5 and num2 is 7')\n    \n    if 2.5 != num1 or 2.5 != num2:\n        print(f'Num1 is 2.5 or num2 is 2.5')\n    \n    for letter in word:\n        print(letter)\n\n    t = 0\n    while t in range(len(list_num)):\n        print(list_num[t]) \n        t += 1\n\ndef arithmetic_operations():\n    '''\n    Examples of all arithmetic operations possible on python\n    '''\n    sum = 2 + 3\n    print(f'2 + 3 = {sum}')\n    diff = 9 - 4\n    print(f'9 - 4 = {diff}')\n    multiply = 2 * 3\n    print(f'2 * 3 = {multiply}')\n    exponent = 2 ** 6\n    print(f'2^6 = {exponent}')\n    division = 4 / 2\n    print(f'4 / 2 = {division}')\n    low_division = 7 // 2\n    print(f'7 // 2 = {low_division}')\n    module = 3 % 2\n    print(f'3 % 2 = {module} (is the rest of the division 3 / 2)' )\n    \ndef comparison():\n    '''\n    Examples of all comparison opartions possibles on python\n    '''\n\n    equal_comparison = 4 == 4\n    print(f'4 == 4 --> {equal_comparison}')\n    not_equal_comparison = 4 != 4\n    print(f'4 != 4 --> {not_equal_comparison}')\n    greater_comparison = 3 > 2\n    print(f'3 > 2 --> {greater_comparison}')\n    less_comparison = 3 < 2\n    print(f'3 < 2 --> {less_comparison}')\n    \n    greater_or_equal_comparison = 3 >= 5\n    print(f'3 >= 5 --> {greater_or_equal_comparison}')\n    less_or_equal_comparison = 3 <= 5\n    print(f'3 <= 5 --> {less_or_equal_comparison}')\n\ndef difficult_part():\n    print('\\n ======= DIFFICULT PART OUTPUT =======')\n    for i in range(10, 56):\n        if 16 == i:\n            continue\n        elif 0 == (i % 3):\n            continue\n        elif 0 == (i % 2):\n            print(i)\n\nif __name__ == '__main__':\n    arithmetic_operations()\n    comparison()\n    logics()\n    difficult_part()\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/thezhizn.py",
    "content": "'''\nlista de operadores en python \n'''\n\n# 1= operadores aritmeticos, calculo matematico:\nprint(f\"sumas 2+2={2 + 2}\")\nprint(f\"restas 3-1={3 - 1}\")\nprint(f\"multiplicacion 2*4={2 * 4}\")\nprint(f\"divición 8/3={8 / 3}\") \nprint(f\"modulo 100%5={100 % 5}\")\nprint(f\"exponencial / potencia 4**2={4 ** 2}\")\nprint(f\"divicion con resultado entero 17//3={17 // 3}\")\n\n# operadores racionales: comparan y establecen relaciones\nprint(f\"6 mayor que 3={3 < 6}\")\nprint(f\"3 menor que 6={3 > 6}\")\nprint(f\"4 igual que 4={4 == 4}\")\nprint(f\"8 mayor o igual que 8={8 <= 8}\")\nprint(f\"3 menor o igual que 6={3 >= 6}\")\nprint(f\"8 desigual que 5={8 != 5}\") \n    \n# operadores de asignacion: asignan a la variable\na = 10\nprint(a)\na += 1\nprint(a)\na -= 1\nprint(a)\na *= 2\nprint(a)\na /= 2\nprint(a)\na **= 2\nprint(a)\na //= 2\nprint(a)\na %= 3\nprint(a)\n\n# operadores logicos \nprint(f\"NOT niega y en caso de que lo que niega sea falso, entonces seria cierto que es falso= {not 5==6}\")\nprint(f\"OR tiene que cumplirse almenos una: 4 + 1 == 5 or 10 > 15={4 + 1 == 5 or 10 > 15}\")\nprint(f\"AND tienen que cumplirse ambas condiciones: 8 < 9 and 16/8 <= 8={8 < 9 and 16/8 <= 8}\")\n\n# operadores de pertenencia\nprint(f\"'IN se puede usar para decir que la letra 'h' esta en 'thezhizn'={\"h\" in \"thezhizn\"}\")\nprint(f\"IN NO se puede usar para decir que la 's' no esta en hola ={\"s\" not in \"hola\"}\")\n\n# operadores de identidad\nmy_variable = 2.0 \nprint(f\"IS sirve para ver si lo que se compara comparte memoria a is my_variable = {a is my_variable}\")\nprint(f\"IS NOT sirve para saber si no comparten la memoria a is not my_variable = {a is not my_variable}\")\n\n# operadores de bit a bit: trata de binario \nx = 5 # 0101\ny = 3 # 0011\nprint(f\"AND se representa con '&' = {x & y}\")\n#compara los binarios y escribe 1 si comparten un 1 si no escribe un 0\nprint(f\"OR se representa con '|' = {x | y}\") \n#compara los binarios y si almenos uno de los dos es 1 escribe 1 \nprint(f\"XOR se representa con '^' = {x ^ y} \")\n#compara los binarios, si los numeros son diferentes escribe uno y si no es 0\nprint(f\"NOT se representa con '~' = {~ x}\")\n# invierte los numeros del binario \nprint(f\"desplazamiento a la derecha '>>' = {x >> y}\")\n#desplaza los numeros de X la candidad de Y posiciones a la derecha\nprint(f\"desplazamiento a la izquierda '<<' = {x << y}\")\n# desplaza las numero de X la cantidad de Y posiciones a la izquierda\n \n# estructuras de control condicionales \nmy_number = 14\n\nif my_number * 3 == 32: \n    print(\"Es 32\")\nelif my_number * 3 == 42:\n    print(\"El resultado es 42\")\nelse:\n    print(\"no es 32 ni es 42\")\n\n# estructuras de control interactivas\nfor t in range(7):\n    print(t)\nt = 0 \n\nwhile t <= 7:\n    print(t)\n    t += 1\n\n# estructuras de control excepciones \ntry:\n    print(\"t\"/2)\nexcept:\n    print(\"oh parece que fallamos\")\nfinally:\n    print(\"ya lo hemos resuelto\")\n\n# ejercicio extra \nfor m in range(10 , 56):\n    if m % 2 == 0 and m != 16 and m % 3 != 0:\n      print(m)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/tic4.py",
    "content": "#Operadores\n#Artirmeticos\nx= 10; y=5\nprint(\"x+y = \", x+y) #15\nprint(\"x-y =\", x-y) #5\nprint (\"x*y = \", x*y) #50\nprint(\"x/y =\", x/y) # 2\n\"Operadores de Asignacion\"\na=7; b=2\nx=a; x+=b;  print(\"x+=\", x)  # 9\nx=a; x-=b;  print(\"x-=\", x)  # 5\nx=a; x*=b;  print(\"x*=\", x)  # 14\nx=a; x/=b;  print(\"x/=\", x)  # 3.5\n\n#Operadores Relacionales#\nx=2; y=3\nprint(\"x==y =\", x==y) # False\nprint(\"x!=y =\", x!=y) # True\nprint(\"x>y  =\", x>y)  # False\nprint(\"x<y  =\", x<y)  # True\n\n#Operadores logicoa#\nprint(True and True)   # True\nprint(True and False)  # False\n\nprint(True or True)   # True\nprint(True or False)  # True\n\nprint(not True)  # False\nprint(not False) # True\n\n#Condiciomales#\na = 10\nb = 30\n\nif a > b:\n    print(\"a es mayor que b\")\nelif a < b:\n    print(\"a es menor que b\")\nelse:\n    print(\"a es igual a b\")\n\na es menor que b\n#Repeticion#\nnumeros = [18,50,90,-20,100,80,37]\nfor n in numeros:\n    print(n)\n18\n50\n90\n-20\n100\n80\n37\n\nx = 1\nwhile x < 5:\n    print(x)\n    x += 1\n1\n2\n3\n4\n\na = int(input(\"Ingrese un número entero: \"))\nb = int(input(\"Ingrese otro número entero: \"))\n\ntry:\n    c = a / b \nexcept ZeroDivisionError:\n    print(\"Estás intentando dividir por cero\")\nIngrese un número entero: 50\nIngrese otro número entero: 0\nEstás intentando dividir por cero\n\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/tito-delpino.py",
    "content": "# EJERCICIO:\n# Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n#  Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n'''Aritmeticos'''\nprint(f'suma: 4 + 4 = {4 + 4}')\nprint(f'resta: 4 - 4 = {4 - 4}')\nprint(f'multiplicacion: 4 * 3 = {4 * 3}')\nprint(f'division: 10 / 5 = {10 / 5}')\nprint(f'modulo: 10 % 5 = {11 % 5}')\nprint(f'division_entera: 7 // 3 = {7 // 3}')\nprint(f'potencia: 4 ** 3 = {4 ** 3}')\n\n'''De comparacion'''\nprint(f'igualdad: 10 == 5 es {10 == 5}')\nprint(f'desigualdad: 10 != 5 es {10 != 5}')\nprint(f'mayor que: 20 > 4 es {20 > 4}')\nprint(f'menor que: 20 < 4 {20 < 4}')\nprint(f'mayor o igual que: 15 >= 14 es {15 >= 14}')\nprint(f'menor o igual que: 15 <= 14 es {15 <= 14}')\n\n'''Logicos'''\n'AND, OR Y NOT'\na = True\nb = False\n\nprint(a and b) # False\nprint(a and a) # True\nprint(a or b)   # True\nprint(not a)    # False\n\nprint(True and True)   # True\nprint(True and False)  # False\nprint(True or True)   # True\nprint(True or False)  # True\nprint(not True)  # False\nprint(not False) # True\n\n\"Asignacion\"\nasignacion = 13\nprint(asignacion)\nasignacion += 1 # Sumamos a asignacion el valor indicado\nprint(asignacion)\nasignacion -= 3 # Restamos a asignacion el valor indicado\nprint(asignacion)\nasignacion *= 2 # Multiplicamos a asignacion el valor indicado\nprint(asignacion)\nasignacion /= 2 # Dividimos a asignacion el valor indicado\nprint(asignacion)\nasignacion %= 2 # Modulo del valor indicado a asignacion\nprint(asignacion)\nasignacion **= 1 # Potencia del valor indicado a asignacion\nprint(asignacion)\nasignacion //= 1 # Division entera del valor indicado a asignacion\nprint(asignacion)\n\n\"Identidad\"\nnueva_asignacion = asignacion\nprint(f'nueva_asignacion is asignacion {nueva_asignacion is asignacion}')\nprint(f'nueva_asignacion is not asignacion {nueva_asignacion is not asignacion}')\n\n\"Pertenencia\"\nprint(f\"'a' in alvaro {'a' in 'alvaro'}\")\nprint(f\"'a' not in alvaro {'a' not in 'alvaro'}\")\n\n\n\"\"\" Utilizando las operaciones con operadores que tú quieras, crea ejemplos\nque representen todos los tipos de estructuras de control que existan\nen tu lenguaje: Condicionales, iterativas, excepciones...\n\"\"\"\n# Condicionales\nprint('if')\nn = 7\nif n == 7:\n    print('n es igual a 7')\nelif n != 6 and n != 8:\n    print('n es distinto de 6 y distinto de 8')\nelif n != 4 or n == 8:\n    print('n es distinto de 4 o igual a 8')\nelse:\n    print('ninguna de las anteriores')\n\n# Iterativas\nprint(\"for\")\nfor i in range(1,11):\n    print(i)\nprint(\"while\")\nwhile n <= 10:\n    print(n)\n    n += 1\n\n# Excepciones\ntry:\n    print(12 / 3)\nexcept:\n    print('peté')\nfinally:\n    print('cambiaste el cero y no peté gracias!')\n\nprint('////////////////')\n\n\"\"\"DIFICULTAD EXTRA (opcional):\nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\nSeguro que al revisar detenidamente las posibilidades has descubierto algo nuevo\"\"\"\nfor i in range(10,56):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print(i)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/tobiBordino.py",
    "content": "\"\"\"\nOperadores\n\"\"\"\n\n# Operadores aritméticos\nprint(\"--- Operadores aritméticos ---\")\nprint(f\"Suma: 10 + 3 = {10 + 3}\")\nprint(f\"Resta: 10 - 3 = {10 - 3}\")\nprint(f\"Multiplicación: 10 * 3 = {10 * 3}\")\nprint(f\"División: 10 / 3 = {10 / 3}\")\nprint(f\"División entera: 10 // 3 = {10 // 3}\")\nprint(f\"Residuo: 10 % 3 = {10 % 3}\")\nprint(f\"Exponente: 10^3 = {10 ** 3}\")\n\n# Operadores de comparación\nprint(\"--- Operadores de comparación ---\")\nprint(f\"Igual que: 10 == 3 = {10 == 3}\")\nprint(f\"Diferente que: 10 != 3 = {10 != 3}\")\nprint(f\"Mayor que: 10 > 3 = {10 > 3}\")\nprint(f\"Menor que: 10 < 3 = {10 < 3}\")\nprint(f\"Mayor o igual que: 10 >= 10 = {10 >= 10}\")\nprint(f\"Menor o igual que: 10 <= 3 = {10 <= 3}\")\n\n# Operadores lógicos\nprint(\"--- Operadores lógicos ---\")\nprint(f\"AND &&: True and False = {True and False}\")\nprint(f\"OR ||: True or False = {True or False}\")\nprint(f\"NOT !: not True = {not True}\")\n\n# Operadores de asignación\nprint(\"--- Operadores de asignación ---\")\nx = 10\nprint(f\"x = {x}\")\nx += 1\nprint(f\"x += 1 = {x}\")\nx -= 1\nprint(f\"x -= 1 = {x}\")\nx *= 1\nprint(f\"x *= 1 = {x}\")\nx /= 1\nprint(f\"x /= 1 = {x}\")\nx %= 1\nprint(f\"x %= 1 = {x}\")\nx //= 1\nprint(f\"x //= 1 = {x}\")\nx **= 1\nprint(f\"x **= 1 = {x}\")\n\n# Operadores de identidad\nprint(\"--- Operadores de identidad ---\")\nx = 10\ny = 10\nprint(f\"x = {x}\")\nprint(f\"y = {y}\")\nprint(f\"x is y = {x is y}\")\nprint(f\"x is not y = {x is not y}\")\n\n# Operadores de pertenencia\nprint(\"--- Operadores de pertenencia ---\")\nx = 3\ny = 10\nlista = [1, 2, 3, 4, 5]\nprint(f\"x = {x}\")\nprint(f\"y = {y}\")\nprint(f\"lista = {lista}\")\nprint(f\"x in lista = {x in lista}\")\nprint(f\"y not in lista = {y not in lista}\")\n\n# Operadores de bits\nprint(\"--- Operadores de bits ---\")\nx = 10 # 1010\ny = 3 # 0011\nprint(f\"x = {x}\")\nprint(f\"y = {y}\")\nprint(f\"AND: x & y = {x & y}\") # 0010\nprint(f\"OR: x | y = {x | y}\") # 1011\nprint(f\"XOR: x ^ y = {x ^ y}\") # 1001 \"1\" si los bits son diferentes, 0 si son iguales\nprint(f\"NOT: ~x = {~x}\") # 0101\nprint(f\"DESPLAZAMIENTO A LA IZQUIERDA: x << 2 = {x << 2}\") # 101000\nprint(f\"DESPLAZAMIENTO A LA DERECHA: x >> 2 = {x >> 2}\") # 10\n\n# Estructuras de control\nprint(\"--- Estructuras de control ---\")\n# if\nprint(\"--- if ---\")\nx = 10\ny = 3\nif x > y:\n    print(f\"{x} es mayor que {y}\")\nelif x == y:\n    print(f\"{x} es igual que {y}\")\nelse:\n    print(f\"{x} es menor que {y}\")\n\n# Estructura iterativa\n# for\nprint(\"--- for ---\")\nlista = [1, 2, 3, 4, 5]\nfor i in lista:\n    print(i)\n\n# while\nprint(\"--- while ---\")\ni = 0\nwhile i <= 5:\n    print(i)\n    i += 1\n\n# Manejo de excepciones\nprint(\"--- Manejo de excepciones ---\")\ntry:\n    x = 10\n    y = 0\n    print(x / y)\nexcept ZeroDivisionError:\n    print(\"No se puede dividir entre cero\")\nexcept TypeError:\n    print(\"No se puede dividir entre cero\")\nexcept:\n    print(\"Error desconocido\")\nfinally:\n    print(\"Finalmente\")\n\n# Sección extra (realizar un programa)\n# Programa que imprima por consola todos los números entre el 10 y el 55 incluido pero que sean sólo los pares. \n    #Excepto el número 16.\n    #Expecto los múltiplos de 3.\nprint(\"--- Programa ---\")\nfor number in range(10, 56):\n    if number % 2 == 0 and number != 16 and number % 3 != 0:\n        print(number)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/toral24.py",
    "content": "#Operadores en python\n\n#Concatenación de cadenas\n\nsaludo = \"Hola\"\nlenguaje = \"Python\"\n\nprint(\"¡\"+ saludo + \", \" + lenguaje + \"!\")\n\n#Booleanos\n\nx = True\ny = False\n\nprint(x or y)\nprint(x and y)\nif not y:\n    print(\"y es falsa\")\n\n#Artiméticos\ntry:\n\n    num1 = int(input(\"introduce el primer número entero: \"))\n    num2 = int(input(\"introduce el segundo número entero: \"))\n\n    print(\"la suma es \" + str(num1 + num2))\n    print(\"la resta es: \" + str(num1 - num2))\n    print(\"la multiplicación es: \" + str(num1 * num2))\n    print(\"la división (con decimales) es: \" + str(num1 / num2))\n    print(\"la división (sin decimales) es: \" + str(num1 // num2))\n    print(\"la potencia es : \" + str(num1 ** num2))\n    print(\"el modulo es : \" + str(num1 % num2))\n\nexcept:\n    print(\"Algo ha salido mal\")\n\n#Comparación\n\nletra = \"a\"\nabecedario = []\nwhile letra <= \"z\":\n    abecedario.append(letra)\n    letra = chr(ord(letra) + 1)\n\nprint(\"Estas son las primeras 10 letras del abecedario:\")\nfor i in range(10):\n    print(abecedario[i], end=\" \")\n\ntry:\n    num = int(input(\"introduce un número\"))\n    if num > 0:\n        print(\"has introducido un número positivo\")\n        if num >= 100:\n            print(\"tu número tiene más de tres cifras\")\n        elif num < 10:\n            print(\"tu número no tiene dos cifras\")\n    elif num == 0:\n        print(\"has introducido un cero\")\n    else:\n        print(\"has introducido un número negitvo\")\nexcept:\n    print(\"no has introducido un número\")\ntry:\n\n    numsuerte = 7\n    numintroducido = int(input(\"adivina el número de la suerte\"))\n\n    while numsuerte != numintroducido:\n        print(\"vaya no has acertado el número de la suerte prueba otra vez\")\nexcept:\n    print(\"no has introducido un número\")\n\n#pertenencia e identidad\n\n    vocales = [\"a\",\"e\",\"i\",\"o\",\"u\"]\n    letrausu = str(input(\"introduce una letra minúscula\"))\n    if letrausu in abecedario:\n        if letrausu not in vocales:\n            print(\"tu letra es una cosonante\")\n            if letrausu is not \"z\":\n                print(\"tu letra no es la última del abecedario\")\n        elif letrausu is \"a\":\n            print(\"has introducido la primera letra del abecedario\")\n        \n    else:\n        print(\"has introducido una letra mínuscula\")\n\n#Operaciones a nivle de bit\n\nx = 5\ny = 20\n\n#or \nprint(x|y)\n#or exclusivo\nprint(x^y)\n#and\nprint(x&y)\n#deplazo de bits\nprint(x>>2) #dos bits a la derecha\nprint(y<<5) #cinco bits a la izquierda\n#not\nprint(~x)\n\n#Ejercicio extra\n\nfor i in range(10,56):\n    if i%2 == 0:\n        if i%3 != 0:\n            if i != 16:\n                print(i, end=\" \")\n                "
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/txuky.py",
    "content": "### Ejemploi de operadores  ###\n\n'''\nAritmeticos\n+ - * / % // ** \n'''\n\nprint(4 + 5)\nprint(7 - 2)\nprint(12 / 3)\nprint(11 % 3)\nprint(10 // 3)\nprint(2 ** 3)\n\n'''\nde Comparacion\n== != > < >= <=\n'''\nprint(5 == 5)\nprint(5 != 3)\nprint(5 > 1)\nprint(2 < 5)\nprint(1 >= 1)\nprint(2 <= 5)\n\n'''\nlogicos\nand or not\n'''\nprint(5 < 8 and 7 > 4)\nprint((6 + 5)==8 or (2 * 14) > 4)\nprint(not True)\n\n\nmy_number = 1\n\nwhile my_number != 12 and my_number < 13:\n    if my_number <= 6:\n        print('Number es menor o igual que 6 es:', my_number )\n    else:\n        print('Number es mayor 6 es', my_number)\n    my_number = my_number * 2\nprint('Number es mayor o igual a 12', my_number)    \n\n\nmy_other_number = 10\n\nwhile my_other_number <= 55:\n    if my_other_number !=16 and my_other_number % 3 != 0:\n        print(my_other_number) \n    my_other_number += 2\n    "
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/varoblanco.py",
    "content": "#Aritmetica\n\nprint(f\"Suma 10+15 = {10+15}\")\nprint(f\"Resta 10-15 = {10-15}\")\nprint(f\"Multiplicación 10*15 = {10*15}\")\nprint(f\"Division 10/15 = {10/15}\")\nprint(f\"Potencia 10^15 = {10^15}\") #INCORRECTO esto hace en XOR de los numeros binarios 10 y 15 y sale el 5 en binario\nprint(f\"Resto de division 240%2 = {240%2}\")\nprint(f\"Potencia 10**15 = {10**15}\")\nprint(f\"División entera 10//15 = {10//15}\") #Recoge la parte entera del cociente\n\n#Operadores de comparación\nprint(f\"Menor que 10<15 = {10<15}\")\nprint(f\"Mayor que 10>15 = {10>15}\")\nprint(f\"Igual que 10==15 = {10==15}\")\nprint(f\"Distinto que 10!=15 = {10!=15}\")\n\n#Operadores de logicicos\nprint(f\"AND 10<15 and 5<2 = {10<15 and 5<2}\")\nprint(f\"OR 10<15 or 5<2 = {10<15 or 5<2}\")\nprint(f\"NOT not 5<2 = {not 5<2}\")\n\n#Operadores de asignacion\nmy_variable = 1\nprint(my_variable)\nmy_variable += 1\nprint(my_variable)\nmy_variable -= 1\nprint(my_variable)\nmy_variable *= 2\nprint(my_variable)\nmy_variable /= 2\nprint(my_variable)\nmy_variable %= 1\nprint(my_variable)\nmy_variable += 2\nprint(my_variable)\nmy_variable **= 2\nprint(my_variable)\nmy_variable //= 2\nprint(my_variable)\n\n#Operadores de identidad\nmy_new_number = my_variable\nprint(f\"Es my_new_number = my_variable -> {my_variable is my_new_number}\") #tienen el mismo objeto en memoria, son la misma cosa, aparte de mismo valor misma ubicacion en memoria\nprint(f\"NO es my_new_number = my_variable -> {my_variable is not my_new_number}\")\n\n#Operadores de pertenencia\nprint(f\"a in varoblanco -> {\"a\" in \"varoblanco\"}\")\nprint(f\"@ not in varoblanco -> {\"@\" not in \"varoblanco\"}\")\n\n#Operadores de bits\na = 10 # 1010\nb = 3 # 0011\nprint(f\"AND a & b = { a & b}\") #0010\nprint(f\"OR a | b = { a | b}\") #1011\nprint(f\"XOR a ^ b = { a ^ b}\") #1011\nprint(f\"NOT a ~ b = {~a}\")\nprint(f\"Desplazamiento a la derecha 2 pos. a >> 2 = {a >> 2}\")\nprint(f\"Desplazamiento a la izq 2 pos. a << 2 = {a << 2}\")\n\n\"\"\"\nEstructuras de control\n\"\"\"\n\n#Condicionales\nemail = \"varoblanco@gmail.com\"\nif email == \"varoblanco@gmail.com\":\n    print(\"Email OK\")\nelif email == \"VAROBLANCO@gmail.com\":\n    print(\"Bien pero está en mayus\")\nelse:\n    print(\"Email incorrecto\")\n\n#Iteratitas\n\nfor i in range(10):\n    print(i)\n\ni = 0\n\nwhile i<=10:\n    print(i)\n    i+=1\n\ntry:\n    print(10/2)\nexcept:\n    print(\"Error en codigo\")\nfinally:\n    print(\"Ejecutado sin problema\")\n\n\"Extra\"\n\nfor i in range(10,56):\n    if i % 2 == 0 and i % 3 != 0 and i != 16:\n        print(i)\n    "
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/vicman-182.py",
    "content": "'''\n *** Ejercicios ***\n'''\n\nprint('''\n * Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n * Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n * (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n''')\n\nprint('\\n*** Operadores Aritmeticos ***')\nprint(\"------------------------------\")\nprint(f\"La suma de 3 + 4 es: {3 + 4}\") # Operador de Suma\nprint(f\"La resta de 10 - 4 es: {10 - 4}\") # Operardor de Resta\nprint(f\"La multiplicacion de 5 * 4 es: {5 * 4}\") # Operador de Multiplicacion\nprint(f\"la division de 20 / 4 es: {20 / 4}\") # Operador de Division\nprint(f\"El modulo de 19 % 4 es: {19 / 4}\") # Operador de Modulo(Resto de la division)\nprint(f\"La exponenciacion de 5 ** 6 es: {5 ** 6}\") # Operador de Exponenciacion\nprint(f\"La division entera de 23 // 4 es: {23 // 4}\") # Operador de Division Entera\nprint(\"------------------------------\\n\")\n\n\nprint('\\n*** Operadores Comparacion ***')\nprint(\"------------------------------\")\nprint(f\"34 == 34: {34 == 34}\") # Igual a\nprint(f\"36 != 34: {36 != 34}\") # Distinto a\nprint(f\"34 > 34: {36 > 34}\") # Mayor a\nprint(f\"32 < 34: {32 < 34}\") # Menor a\nprint(f\"34 >= 34: {34 == 34}\") # Mayor o Igual a\nprint(f\"24 <= 24: {34 == 34}\") # Menor o Igual a\nprint(\"------------------------------\\n\")\n\nprint('\\n*** Operadores Asignacion ***')\nprint(\"------------------------------\")\n\na = 4\nprint(f\"a = {a}\") # Asignacion simple\n\na += 1\nprint(f\"a +=1 = {a}\") # Suma y asignacion\n\na -= 1\nprint(f\"a -=1 = {a}\") # Resta  y asignacion\n\na *= 5\nprint(f\"a *=5 = {a}\") # Multiplicacion  y asignacion\n\na /= 3\nprint(f\"a /=3 = {a}\") # Division  y asignacion\n\na %= 5\nprint(f\"a %=5 = {a}\") # Multiplicacion  y asignacion\n\na **= 4\nprint(f\"a **=4 = {a}\") # Exponenciacion  y asignacion\n\na //= 2\nprint(f\"a //=2 = {a}\") # Multiplicacion  y asignacion\n\nprint(\"------------------------------\\n\")\n\nprint('\\n*** Operadores Logicos ***')\nprint(\"------------------------------\")\n\nprint(f\"3 < 5 and 5 > 2 = {3 < 5 and 5 > 2}\") # and : Devuelve True si ambas expresiones son verdaderas\nprint(f\"3 < 5 or 2 > 3 ={3 < 5 or 2 > 3}\") # or : Devuelve True si al menos una de las expresiones es verdadera\nprint(f\"not 3 > 5 = {not 3 > 5}\") # not : Invierte el valor booleano de una expresión (True a False, y viceversa)\n\nprint(\"------------------------------\\n\")\n\nprint('\\n*** Operadores de Identidad ***')\nprint(\"---------------------------------\")\n\na = 3\nb = a\nc = 5\nprint(f\"'a' es igual a {3}, 'b' es igual a 'a' y 'c' es igual a {c}\")\n\nprint(f\"a is b = {a is b}\")  # is : Devuelve True porque b es el mismo objeto que a\nprint(f\"a is not c = {a is not c}\")  # is not : Devuelve True porque c no es el mismo objeto que a\nprint(\"---------------------------------\\n\")\n\nprint('\\n*** Operadores de Pertenencia ***')\nprint(\"----------------------------------\")\nnumeros = [1, 2, 3, 4, 5]\nletras = \"abcdefg\"\n\nprint(f\"numeros es = {numeros}\")\nprint(f\"letras es = {letras}\")\nprint(f\"3 in numeros = {3 in numeros}\")  # in : Devuelve True porque 3 está en la lista numeros\nprint(f\"z not in letras = {\"z\" not in letras}\")  # not in : Devuelve True porque z está en la lista letras\nprint(\"---------------------------------\\n\")\n\nprint('\\n*** Operadores de Bits ***')\nprint(\"----------------------------------\")\na = 5  # En binario: 0101\nb = 3  # En binario: 0011\n\nprint(f\"a es = {a} (binario: {bin(a)})\")\nprint(f\"b es = {b} (binario: {bin(b)})\")\n\n# Operador AND a nivel de bits\nprint(f\"a & b = {a & b} (binario: {bin(a & b)})\")  # & : Devuelve 1 porque 0101 & 0011 es 0001\n\n# Operador OR a nivel de bits\nprint(f\"a | b = {a | b} (binario: {bin(a | b)})\")  # | : Devuelve 7 porque 0101 | 0011 es 0111\n\n# Operador XOR a nivel de bits\nprint(f\"a ^ b = {a ^ b} (binario: {bin(a ^ b)})\")  # ^ : Devuelve 6 porque 0101 ^ 0011 es 0110\n\n# Operador NOT a nivel de bits\nprint(f\"~a = {~a} (binario: {bin(~a)})\")  # ~ : Devuelve -6 porque ~0101 es 1010 (en complemento a dos)\n\n# Desplazamiento de bits a la izquierda\nprint(f\"a << 1 = {a << 1} (binario: {bin(a << 1)})\")  # << : Desplaza 0101 una posición a la izquierda, resultado: 1010\n\n# Desplazamiento de bits a la derecha\nprint(f\"a >> 1 = {a >> 1} (binario: {bin(a >> 1)})\")  # >> : Desplaza 0101 una posición a la derecha, resultado: 0010\n\nprint(\"---------------------------------\\n\")\n\nprint('''\n * Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n * que representen todos los tipos de estructuras de control que existan\n * en tu lenguaje:\n * Condicionales, iterativas, excepciones...\n''')\n\nprint('\\n*** Condicionales `if`, `elif` y `else` ***')\nprint(\"----------------------------------\")\n\na = 18\nb = 16\nprint(f\"el valor de 'a' es {a} y el valor de 'b' es {b}\")\nif a > b:\n    print(f\"'a' es mayor que 'b'\")\nelif a == b:\n    print(f\"'a' es igual a 'b'\")\nelse:\n    print(f\"'a' es menor que 'b'\")\n\nprint(\"---------------------------------\\n\")\n\nprint('\\n*** Iterativas `for` ***')\nprint(\"----------------------------------\")\n\nnumeros = [1,2,3,4,5,6]\nprint(f\"Recorriendo la lista Numeros {numeros} e imprimiendo cada elemento\")\n\nfor i in numeros:\n    print(i)\n\nprint('\\n*** Iterativas `while` ***')\nprint(\"----------------------------------\")\n\ncontador = 5\nprint(f\"Se imprimira una cuenta regresiva desde el numero 5\")\nwhile contador >= 0:\n    print(contador)\n    contador -= 1\nprint(f\"Boooom 💥\")\n\nprint(\"---------------------------------\\n\")\n\nprint('\\n*** Exepciones ***')\nprint(\"----------------------------------\")\n\ntry:\n    print(10 /1)\nexcept: \n    print(\"Se ha producido un error\")\nfinally:\n    print(\"Ha finalizado el manejo de exepciones\")\nprint(\"---------------------------------\\n\")\n\nprint('\\n*** Dificultad Extra ***')\nprint(\"----------------------------------\")\n\nprint('''\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n''')\n\nfor i in range(10,56):\n    if i % 2 != 0 and i != 16 and i % 3 != 0:\n        print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/victorfer69.py",
    "content": "#OPERADORES\n\n#Operadores artméticos\nprint(f\"Suma: 2 + 3 = {2+3}\")\nprint(f\"Resta: 2 - 3 = {2-3}\")\nprint(f\"Multiplicación: 2 * 3 = {2*3}\")\nprint(f\"Exponente: 2 ** 3 = {2**3}\")\nprint(f\"División: 2 / 3 = {2/3}\")\nprint(f\"División entera: 2 // 3 = {2//3}\")\nprint(f\"Módulo o resto de la división: 2 % 3 = {2&3}\")\nprint(\"==================================================\")\n\n#Operadores de comparación\nprint(f\"Igualdad: 2 == 3 es {2 == 3}\")\nprint(f\"Desigualdad: 2 != 3 es {2 != 3}\")\nprint(f\"Mayor que: 2 > 3 es {2 > 3}\")\nprint(f\"Mayor o igual que: 2 >= 3 es {2 >= 3}\")\nprint(f\"Menor que: 2 < 3 es {2 < 3}\")\nprint(f\"Menor o igual que: 2 <= 3 es {2 <= 3}\")\nprint(\"==================================================\")\n\n#Operadores lógicos\nprint(f\"AND &&: 2 + 1 = 3 and 10 - 1 = 9 es {2 + 1 == 3 and 10 - 1 == 9}\")\nprint(f\"OR ||: 2 + 1 = 3 and 10 - 1 = 8 es {2 + 1 == 3 or 10 - 1 == 8}\")\nprint(f\"NOT !: not 2 + 1 = 4 es {not 2 + 1 == 4}\")\nprint(\"==================================================\")\n\n#Operadores de asignación\na = 11\nprint(a)\na += 1      #suma y asignacion\nprint(a)\na -= 1      #resta y asignacion\nprint(a)\na *= 2      #multiplicacion y asignacion\nprint(a)\na /= 2      #division y asignacion\nprint(a)\na %= 2      #modulo y asignacion\nprint(a)\na **= 1      #exponente y asignacion\nprint(a)\na //= 1      #division entera y asignacion\nprint(a)\nprint(\"==================================================\")\n\n#Operadores de identidad\nb = 1.0\nprint(f\"a is b es {a is b}\")\nb = a\nprint(f\"a is b es {a is b}\")\nb = 1.0\nprint(f\"a is not b es {a is not b}\")\nb = a\nprint(f\"a is not b es {a is not b}\")\nprint(\"==================================================\")\n\n# Operadores de pertenencia\nprint(f\"'o' in 'victor' = {'o' in 'victor'}\")\nprint(f\"'a' in 'victor' = {'a' in 'victor'}\")\nprint(f\"'o' not in 'victor' = {'o' not in 'victor'}\")\nprint(f\"'a' not in 'victor' = {'a' not in 'victor'}\")\nprint(\"==================================================\")\n\n# Operadores de bit (en binario)\na = 10  # 1010\nb = 3  # 0011\nprint(f\"AND: 10 & 3 = {10 & 3}\")  # 0010\nprint(f\"OR: 10 | 3 = {10 | 3}\")  # 1011\nprint(f\"XOR: 10 ^ 3 = {10 ^ 3}\")  # 1001\nprint(f\"NOT: ~10 = {~10}\")\nprint(f\"Desplazamiento a la derecha: 10 >> 2 = {10 >> 2}\")  # 0010\nprint(f\"Desplazamiento a la izquierda: 10 << 2 = {10 << 2}\")  # 101000\nprint(\"==================================================\")\n\n\n#Estructuras de control\n\n# Condicionales\na = \"victor\"\n\nif a == \"victor\":\n    print(\"a es 'victor'\")\nelif a == \"no\":\n    print(\"a es 'no'\")\nelse:\n    print(\"a no es 'victor' ni 'no'\")\n\nprint(\"==================================================\")\n\n# Bucle for\nfor i in range(3):\n    print(i)\n\nprint(\"==================================================\")\n\n#Bucle while\ni = 0\nwhile i <= 10:\n    print(i)\n    i += 1\n\nprint(\"==================================================\")\n\n# Manejo de excepciones\ntry:\n    print(10 / 0)\nexcept:\n    print(\"Se ha producido un error\")\nfinally:\n    print(\"Ha finalizado el manejo de excepciones\")\n\nprint(\"==================================================\")\n\n\n\n#DIFICULTAD EXTRA\n\n#Recorremos numeros del 10 al 55\nfor i in range(10, 56):\n    #Numero par && no 16 && no multiplo de 3\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/vmatmarco.py",
    "content": "'''\nEJERCICIO 1 -> Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje de programación.\n'''\n\n# Operadores aritméticos (Un operador aritmético toma dos operandos como entrada y devuelve el resultado)\n\n# Suma\nprint(f\"Suma 12 + 3 = {12 + 3}\")\n\n# Resta\nprint(f\"Resta 12 - 3 = {12 - 3}\")\n\n# Multiplicación\nprint(f\"Multiplicación 12 * 3 = {12 * 3}\")\n\n# División\nprint(f\"División 12 / 3 = {12 / 3}\")\n\n# División entera\nprint(f\"División entera 12 // 3 = {12 // 3}\")\n\n# Módulo\nprint(f\"Módulo 12 % 3 = {12 % 3}\")\n\n# Potencia\nprint(f\"Potencia 12 ** 3 = {12 ** 3}\")\n\n\n# Operadores de asignación (Se utilizan para asignar valores a las variables)\nx = 5 # Asigna el valor 5 a la variable x\nprint(x)\nx += 3 # Equivale a x = x + 3\nprint(x)\nx -= 3 # Equivale a x = x - 3\nprint(x)\nx *= 3 # Equivale a x = x * 3\nprint(x)\nx /= 3 # Equivale a x = x / 3\nprint(x)\nx //= 3 # Equivale a x = x // 3\nprint(x)\nx %= 3 # Equivale a x = x % 3\nprint(x)\nx **= 3 # Equivale a x = x ** 3\nprint(x)\nx &= 3 # Equivale a x = x & 3\nprint(x)\nx |= 3 # Equivale a x = x | 3\nprint(x)\nx ^= 3 # Equivale a x = x ^ 3\nprint(x)\nx >>= 3 # Equivale a x = x >> 3\nprint(x)\nx <<= 3 # Equivale a x = x << 3\nprint(x)\n\n\n# Operadores relacionales (Se utilizan para comparar dos valores)\nprint(f\"Igualdad 12 == 3 es {12 == 3}\")\nprint(f\"Desigualdad 12 != 3 es {12 != 3}\")\nprint(f\"Mayor que 12 > 3 es {12 > 3}\")\nprint(f\"Menor que 12 < 3 es {12 < 3}\")\nprint(f\"Mayor o igual que 12 >= 3 es {12 >= 3}\")\nprint(f\"Menor o igual que 12 <= 3 es {12 <= 3}\")\n\n\n# Operadores lógicos (Se utilizan para combinar expresiones condicionales)\nprint(f\"AND 12 > 3 and 5 < 2 es {12 > 3 and 5 < 2}\")\nprint(f\"OR 12 > 3 or 5 < 2 es {12 > 3 or 5 < 2}\")\nprint(f\"NOT not 12 > 3 es {not 12 > 3}\")\n\n# Operadores de identidad (Se utilizan para comparar objetos, no si son iguales, sino si son realmente el mismo objeto, con la misma ubicación de memoria)\nprint(f\"12 is 3 es {12 is 3}\")\nprint(f\"12 is not 3 es {12 is not 3}\")\n\n# Operadores de pertenencia (Se utilizan para comprobar si un valor está presente en una secuencia, como una cadena, una lista, una tupla, un conjunto, o un diccionario)\nprint(f\"12 in [1, 2, 3] es {12 in [1, 2, 3]}\")\nprint(f\"12 not in [1, 2, 3] es {12 not in [1, 2, 3]}\")\n\n\n# Operadores de bits (Se utilizan para comparar números (binarios))\nprint(f\"AND 12 & 3 = {12 & 3}\")\nprint(f\"OR 12 | 3 = {12 | 3}\")\nprint(f\"XOR 12 ^ 3 = {12 ^ 3}\")\nprint(f\"NOT ~12 = {~12}\")\nprint(f\"Desplazamiento a la derecha 12 >> 3 = {12 >> 3}\")\nprint(f\"Desplazamiento a la izquierda 12 << 3 = {12 << 3}\")\n\n'''\nEJERCICIO 2 -> Crea ejemplos utilizando todas las estructuras de control de tu lenguaje de programación.\n'''\n\n# Condicionales\n# IF\nif 12 > 3:\n    print(\"12 es mayor que 3\")\n\n# IF-ELSE\nif 12 < 3:\n    print(\"12 es menor que 3\")\nelse:\n    print(\"12 no es menor que 3\")\n\n# IF-ELIF-ELSE\nif 12 < 3:\n    print(\"12 es menor que 3\")  \nelif 12 == 3:\n    print(\"12 es igual a 3\")\nelse:\n    print(\"12 no es menor que 3 ni igual a 3\")\n\n# Iterativas\n\n# WHILE\ni = 1\nwhile i < 6:\n    print(i)\n    i += 1\n\n# FOR\nfor i in range(1, 6):\n    print(i)\n\n\n'''\n DIFFICULTAD EXTRA\n'''\n\nfor i in range(1, 56):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/warclimb.py",
    "content": "# 01 OPERADORES Y ESTRUCTURAS DE CONTROL\n\n\"\"\"\n * EJERCICIO:\n * - Crea e...\n \n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n \"\"\"\n\n# Ejemplos utilizando todos los tipos de operadores aritméticos de Python:\n\nfrom tkinter import Y\nfrom numpy import true_divide\n\n\nsuma = 1 + 1\nresta = 2 - 1\ndivision = 4 / 2\nmultiplicacion = 2 * 2\nmodulo = 4 % 3\npotencia = 2 ** 2\ndivision_entera = 5 // 2\n\n# creo lista para facilitar el print\noperadores_aritmeticos = [\"suma\", \"resta\", \"division\", \"multiplicacion\", \"modulo\", \"potencia\", \"division_entera\"]\n\n# mostramos los resultados\nfor operador in operadores_aritmeticos:\n    print(operador, \":\", eval(operador))\n\nprint(\"-\"*48)\n\n# Operadores Lógicos - and or, not\na = True\nb = False\n\n# operador and para agregar dos condiciones\nif a and b:\n    print(\"a y b son True\")\n\n# operador or para agregar dos condiciones de las que se cumple 1\nif a or b:\n    print(\"a o b es True\")\n\n# operador not para negar una condición\nif not b:\n    print(\"b es False\")\n\nprint(\"-\"*48)\n\n# Operadores de comparación - ==, !=, >, <, >=, <=\nx = 420\ny = 69\n\nprint(f\"Tenemos los valores: \\n x = {x} \\n y = {y} \\nVamos a realizar unas comprobaciones de comparación:\")\n\n# operador == para comparar si dos valores son iguales\nif x == y:\n    print(\"x es igual a y\")\nelse:\n    print(\"x no es igual a y\")\n\n# operador != para comparar si dos valores son diferentes\nif x != y:\n    print(\"x es diferente a y\")\nelse:\n    print(\"x no es diferente a y\")\n\n# operador > para comparar si un valor es mayor\nif x > y:\n    print(\"x es mayor que y\")\nelse:\n    print(\"x no es mayor que y\")\n\n# operador < para comparar si un valor es menor\nif x < y:\n    print(\"x es menor que y\")\nelse:\n    print(\"x no es menor que y\")\n\n# operador >= para comparar si un valor es mayor o igual\nif x >= y:\n    print(\"x es mayor o igual que y\")\nelse:\n    print(\"x no es mayor o igual que y\")\n\n# operador <= para comprobar si un valor es menor o igual\nif x <= y:\n    print(\"x es menor o igual que y\")\nelse:\n    print(\"x no es menor o igual que y\")\n\nprint(\"-\"*48)\n\n\"\"\" * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\"\"\"\n\nfor i in range(10, 56):\n    # imprimir pares, y que no son ni el 16 ni múltiplos de 3.\n    if i % 2 == 0 and i != 16 and not i % 3 == 0:\n        print(i)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/wijimenezz.py",
    "content": "# # EJERCICIO:\n#  * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n#  *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n#  *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n#  * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n#  *   que representen todos los tipos de estructuras de control que existan\n#  *   en tu lenguaje:\n#  *   Condicionales, iterativas, excepciones...\n#  * - Debes hacer print por consola del resultado de todos los ejemplos.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea un programa que imprima por consola todos los números comprendidos\n#  * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n#  *\n#  * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n#  *\n\n\n# Tipos de operadores\n\n# Operadores de concatenacion de caracteres\na = \"Hola a Todos \"\nb = \"Estamos Aprendiendo Python\"\nprint(a + b)\n\n# operadores Booleanos\nprint(\"operadores Booleanos\")\nx = True\ny = False\nprint(\"X y Y\", x and y)\nprint(\"X y X\", x and x)\nprint(\"Y y Y\", y and y)\nprint(\"X or Y\", x or y)\nprint(\"X or x\", x or y)\nprint(\"y or y\", y or y)\nprint(\"not X\", not x)\nprint(\"not Y\", not y)\n\n# operadores de Comparación\nprint(\"operadores de Comparación\")\nnum = 6\nnum2 = 4\nprint(\"6>4\", num > num2)\nprint(\"6<4\", num < num2)\nprint(\"6>=4\", num >= num2)\nprint(\"6<=4\", num <= num2)\nprint(\"6=4\", num == num2)\nprint(\"6!= 4\", num != num2)\n\n# operadores aritmeticos\nprint(\"operadores aritmeticos\")\nprint(\"Suma- 10 + 5\", 10 + 5)\nprint(\"Resta- 10 - 5\", 10 - 5)\nprint(\"Multiplicación  10 * 5\", 10 * 5)\nprint(\"potemvia  10 ** 5\", 10 ** 5)\nprint(\"Division Cociente  10 / 5\", 10 / 5)\nprint(\"Division Entero  10 // 5\", 10 // 5)\nprint(\"Division Residuo  10 % 5\", 10 % 5)\n\n# operadores Nivel Bits\nprint(\"operadores Nivel Bits\")\na = 2\nb = 7\n\nprint(\"a | b= \", a | b)\nprint(\"a ^ b= \", a ^ b)\nprint(\"a  & b= \", a & b)\nprint(\"a << 1= \", a << 1)\nprint(\"a >> 1= \", a >> 1)\nprint(\" ~a= \", ~a)\n\n# operadores de asignación\nprint(\"operadores de asignación\")\nn1 = 10\nn2 = 2\nprint(f\"n1 = {n1}\")\nprint(f\"n2 = {n2}\")\nn1 += n2\nprint(\"n1+=n2\", n1)\nn1 -= n2\nprint(\"n1-=n2\", n1)\nn1 *= n2\nprint(\"n*=n2\", n1)\nn1 **= n2\nprint(\"n1**=n2\", n1)\nn1 //= n2\nprint(\"n1//=n2\", n1)\nn1 %= n2\nprint(\"n1%=n2\", n1)\n\n# operadores de Flujo\nprint(\"operadores de Flujo\")\n\nanimal = \"Vaca\"\nif animal == \"Serpiente\":\n    print(f\" {animal} Corra y no mire atras\")\nelif animal == \"Vaca\":\n    print(f\"{animal} levantese temprano a ordeñar\")\nelif animal == \"Gallina\":\n    print(f\"{animal}Hay que recoger huevos\")\nelse:\n    print(\" no hay animal, Usted esta en la ciudad\")\n\n# while\nz = 10\nwhile z > 0:\n    z -= 1\n    print(z)\n\n# for\nprint(\"for\")\nfor i in range(0, 10):\n    print(i)\n\n # DIFICULTAD EXTRA (opcional):\n#  * Crea un programa que imprima por consola todos los números comprendidos\n#  * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\nprint(\"Extra\")\nlista = []\nfor i in range(10, 56):\n    if i % 2 == 0 and i != 16 and i % 3 != 0:\n        lista.append(i)\nprint(lista)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/willianl731.py",
    "content": "# OPERADORES ARITMÉTICOS (cálculos matemáticos)\n# + (suma)\nedad = 25\naños_extra = 5\nnueva_edad = edad + años_extra  \npuntos = 1000\n# - (resta)\nnueva_edad_1 = edad- años_extra\n# / (división)\npuntos_mitad = puntos / 2   \n# * (multiplicación)\npuntos_doble = puntos * 2  \n# % (módulo - resto de división)\npuntos_restantes = puntos % 30\n# ** (exponente - potencia)\npuntos_potencia = puntos ** 2\n# // (división entera - parte entera de la división)\npuntos_div_entera = puntos // 3\n\nprint(f\"Operadores aritméticos: {nueva_edad}, {nueva_edad_1}, {puntos_mitad}, {puntos_doble}, {puntos_restantes}, {puntos_potencia}, {puntos_div_entera}\")\n\n# OPERADORES DE COMPARACIÓN (comparan valores)\nes_mayor = edad > 18            # > (mayor que)\nes_menor = edad < 30           # < (menor que)\nes_mayor_igual = edad >= 18    # >= (mayor o igual que)\nes_menor_igual = edad <= 30     # <= (menor o igual que)    \nes_igual = edad == 25           # == (igual a)\nes_diferente = edad != 30       # != (diferente de)\nprint(f\"¿Mayor de edad? {es_mayor}, ¿Menor de edad? {es_menor}, ¿Mayor o igual que 18? {es_mayor_igual}, ¿Menor o igual que 30? {es_menor_igual}, ¿Edad 25? {es_igual},es diferente de 30? {es_diferente}\")\n\n# OPERADORES LÓGICOS (combinan condiciones)\ntiene_permiso = True\ntiene_credito = False\n\npuede_acceder = tiene_permiso and edad >= 18  # AND (ambas deben ser True)\npuede_comprar = tiene_permiso or tiene_credito # OR (al menos una True)\nno_tiene_credito = not tiene_credito           # NOT (invierte el valor)\nprint(f\"¿Puede acceder? {puede_acceder}, ¿Puede comprar? {puede_comprar}\")\n\n# OPERADORES DE ASIGNACIÓN (asignan valores)\ncontador = 10\ncontador += 5  # += (suma y asigna) → contador = 15\nprint(f\"Contador: {contador}\")\ncontador -= 3  # -= (resta y asigna) → contador = 12\nprint(f\"Contador: {contador}\")\ncontador *= 2  # *= (multiplica y asigna) → contador = 24\nprint(f\"Contador: {contador}\")\ncontador /= 4  # /= (divide y asigna) → contador = 6.0\nprint(f\"Contador: {contador}\")\ncontador %= 4  # %= (módulo y asigna) → contador = 2.0\nprint(f\"Contador: {contador}\")\ncontador **= 3 # **= (exponente y asigna) → contador = 8.0\nprint(f\"Contador: {contador}\")\ncontador //= 3 # //= (división entera y asigna) → contador = 2.0\nprint(f\"Contador: {contador}\")\n\n# OPERADORES DE IDENTIDAD (verifican si es el mismo objeto)\nlista1 = [1, 2, 3]\nlista2 = [1, 2, 3]\nlista3 = lista1\n\nmismo_objeto = lista1 is lista2      # is (False - no son el mismo objeto)\nmisma_referencia = lista1 is lista3  # is (True - misma referencia)\nprint(f\"¿Mismo objeto? {mismo_objeto}, ¿Misma referencia? {misma_referencia}\")\n\n# OPERADORES DE PERTENENCIA (verifican si existe en secuencia)\nfrutas = [\"manzana\", \"banano\", \"naranja\"]\ntiene_manzana = \"manzana\" in frutas       # in (True - existe)\nno_tiene_uva = \"uva\" not in frutas        # not in (True - no existe)\nprint(f\"¿Tiene manzana? {tiene_manzana}, ¿No tiene uva? {no_tiene_uva}\")\n\n# OPERADORES DE BITS (manipulación binaria)\na = 5  # 0101 en binario\nb = 3  # 0011 en binario\n\nand_bits = a & b   # AND bits: 0101 & 0011 = 0001 (1)\nor_bits = a | b    # OR bits: 0101 | 0011 = 0111 (7)\nxor_bits = a ^ b   # XOR bits: 0101 ^ 0011 = 0110 (6)\nnot_bits = ~a  # NOT bits: ~0101 = 1010 (-6 en complemento a dos)\ndesplazamiento_izq = a << 1  # Desplazamiento a la izquierda: 0101 << 1 = 1010 (10)\ndesplazamiento_der = a >> 1  # Desplazamiento a la derecha: 0101 >> 1 = 0010 (2)\nprint(f\"AND bits: {and_bits}, OR bits: {or_bits}, XOR bits: {xor_bits}, NOT bits: {not_bits}, Desplazamiento Izquierda: {desplazamiento_izq}, Desplazamiento Derecha: {desplazamiento_der}\")\n\n\"\"\"\nEstructuras de control:\n1. Condicionales (if, elif, else)\n2. Iterativas (for, while)\n3. Manejo de excepciones (try, except)\n\"\"\"\n# condicionales\nmi_nombre = \"giovanni\"\nif mi_nombre == \"willian\":\n    print(\"Hola, Willian!\")\nelif mi_nombre == \"giovanni\":\n    print(\"mi nombre es Giovanni!\")\nelse:\n    print(\"mi nombre no es Willian ni Giovanni!\")\n\n# iterativas\nfor i in range(8):\n    print(f\"Iteración {i}\")\n\ncontador = 0\nwhile contador < 8:\n    print(f\"Contador {contador}\")\n    contador += 1\n\n# manejo de excepciones (try, except)\ntry:\n    resultado = 22 / 0# Esto generará un error (división por cero)\nexcept:\n    print(\"se ha producido un error, no se puede dividir por cero\")\nfinally:\n    print(\"ha finalizado el manejo de excepciones\")\n\ntry:\n    resultado = 22 / 2 # Esto no generará un error (división por dos)\nexcept:\n    print(\"se ha producido un error, no se puede dividir por cero\")\nfinally:\n    print(\"ha finalizado el manejo de excepciones\")\n\n\"\"\"\nejercicio extra:\nprograma que imprime por consola todos los números comprendidos entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\"\"\"\nfor number in range(10, 56):\n    if number % 2 == 0 and number != 16 and number % 3 != 0:\n        print(number)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/willr30.py",
    "content": "'''\n\n\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n\n'''\n\n#Operadores aritméticos\n\nsuma= 1 + 2\nresta = 3 + 4\nmultiplicacion = 5 * 6\ndivision = 7 / 8\npotencia = 2**2\nmodulo = 10%5\ndivision_con_barra_doble= 5//2  #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.\n\n\n#operadores logicos\n\nprint(f\"{True or False}\")\nprint(f\"{True and False}\")\nprint(f\"{True != False}\")\n\n\n#Operadores relaconales\n# < Menor que\n# > Mayor que\n# == exactamente igual\n#>= mayor o igual que\n#<= menor o igual que\n#!= diferente de \n\n\n#Asginaciones de valor\na=5 #se asigna el valor de la variable \na+=1 # se guarda el valor enterior y se suma el nuevo [a = (a=5) + 1 ]\na-=2 # se guarda el valor enterior y se resta el nuevo [a = (a=6) - 2 ]\na *=3 # se guarda el valor enterior y se multiplica el nuevo [a = (a=4) * 3 ]\na /= 4 #  se guarda el valor enterior y se divide el nuevo [a = (a=12) /4 ]\na %=5 #  se guarda el valor enterior y se obtiene el modulo juto con  nuevo valor [a = (a=3) % 1 ]\n\n\n#operaores de pertenencia\n#in devuelve True si el valor especificado se encuentra en la secuencia sino devuelve False\n#not in, devuelve True si el valor especificado no se encuentra en la secuencia, sino devuelve False\n#Ejemplo\na = [1,2,3,4,5]\n  \nprint(3 in a) # Muestra True \nprint (80 not in a) # Muestra True\n\n#Lo anterior tambien se aplica al comparar cadenas de texto\n\n#operadores de identidad\n#se hace una comparaciíon si son exactamente iguales\nw=1\nr=2\n\nprint(w is r)\nprint(w is not r)\n\n\n\n#Extra-----------------------------------------------------------\n\nfor i in range (10, 55):\n    if (i % 2 ==0 and  i != 16 and i%3!=0):\n        print(i)\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/worlion.py",
    "content": "# Operadores aritméticos\nprint(1 + 1) # Suma \n\n\n# Operadores de comparación\nprint(1 >= 1) # mayor que\n\n# Operadores de asignación\na = 1\n\n# Operadores lógicos\nprint(True and False)\n\n# Operadores de identidad\nprint(5 is 3)\n\n# Operadores de pertenencia\nprint(5 in [1, 2, 3, 4, 5])\n\n# Operadores de bits\nprint(5 & 3)\n\n# Estructura condicional (if-else)\nx = 10\nif x > 5:\n    print(\"x is greater than 5\")\nelse:\n    print(\"x is less than or equal to 5\")\n\n# Estructura iterativa (for loop)\nfor i in range(1, 6):\n    print(i)\n\n# Estructura de excepción (try-except)\ntry:\n    result = 10 / 0\n    print(result)\nexcept ZeroDivisionError:\n    print(\"Cannot divide by zero\")\n\n# DIFICULTAD EXTRA (opcional):\n# Estructura iterativa con condiciones adicionales\nfor i in range(10, 55, 2):\n    if(i != 16 and i % 3 != 0):\n        print(i)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/xCoreYx0.py",
    "content": "#Estos son ejemplos con los tipos de operadores de python\n\n#Usaré estas variables generales para los ejemplos\n\nx = 20\ny = 15\nprimera_ciudad = \"Lima\"\nsegunda_ciudad = \"Arequipa\"\npais = \"Perú\"\n\n#Operadores Aritméticos:\nsuma = x + y \nresta = x - y\nmultiplicacion = x * y\n\ndivision_entera = x // y\nporcentaje = x % y\npotenciacion = x ** y\n\n#Operadores de comparación:\nigual = primera_ciudad == segunda_ciudad\ndesigual = primera_ciudad != segunda_ciudad\nmayor = x > y\nmenor = y < x\nmayor_igual = x >= y\nmenor_igual = y <= x\n\n#Operadores Lógicos:\nand_logico = primera_ciudad and segunda_ciudad\nor_logico = x or y\nnot_logico = not x\n\n#Operadores de asignación:\nz = 12\nz += 5\nz -= 6\nz *= 10\nz /= 2\nz //= 3\nz %= 2\nz **= 3\n\n#Operadores de identidad\nis_igual = primera_ciudad is pais\nis_not_igual = x is not y\n\n#Operadores a nivel de bits\nand_bits = x & y\nor_bits = x | y\nxor_bits = x ^ y\nnot_bits = ~x\ndesplaza_izquierda = x << 2\ndesplaza_derecha = x >> 2\n\n#Ahora pondré un ejemplo de cada tipo de estructura de control de Python con los operadores aprendidos\n\n#Estrucutra condicional if-elif-else\na = 22\nif a < 12:\n    print(\"a está entre el 1 y el 11\")\nelif a == 12:\n    print(\"a es igual 12\")\nelse:\n    print(\"a es un número mayor a 12\")\n\n#Estructura de repetición (bucles) while y for\n\n#bucle while\ncontador = 1   \nwhile contador <= 5:\n    print(\"EL contador subió a: \", contador)\n    contador += 1\n\n#bucle for\nlista = [20, 2, 13]\nfor numero in lista:\n    print(\"El número actual en la lista es: \", numero)\nfor numero in range(1, 3):\n    print(\"El número actual es: \", numero)\n\n#Estructura de control de flujo break, continue y pass\n\n#break\nfor numero in range(1, 10):\n    if numero == 3:\n        print(\"Se encontró el número 3, salimos del bucle\")\n        break\n    print(\"El número es: \", numero)\n\n#continue\nfor numero in range(1,10):\n    if numero == 5:\n        print(\"Se encontró el cinco, seguimos el bucle\")\n        continue\n    print(\"Este número es: \", numero)\n\n#pass\nfor numero in range(1, 6):\n    if numero == 3:\n        print(\"No\")\n        pass\n    print(\"El número \", numero)\n\n\n#Ahora haré un programa que imprima por consola todos los números comprendidos entre 10 y 55(incluidos),pares, y que no sea 16 ni múltiplos de 3\nfor numero in range(10, 56):\n    if numero % 2 == 0 and numero != 16 and numero % 3 != 0:\n        print(numero)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/xemita007.py",
    "content": "# #01 OPERADORES Y ESTRUCTURAS DE CONTROL\n#### Dificultad: Fácil | Publicación: 02/01/24 | Corrección: 08/01/24\n## Ejercicio\n'''\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\n'''\n\n### Operadores Aritméticos ###\nprint(\"***operadores enteros***\")\n\n# Suma\nprint(4+5)\n# Resta \nprint(4-5)\n# Multiplicación\nprint(4*5)\n# Divición\nprint(4/5)\n# Resto\nprint(4%5)\n# Exonente\nprint(4**5)\n# División entera\nprint(4//5)\n\nprint(\"***Operadores de Comparación***\")\nprint(\"comparación de enteros\")\nprint(4>5)\n\nprint(4<5)\n\nprint(4>=5)\n\nprint(4<=5)\n\nprint(4!=5)\n\nprint(4==5)\n\nprint(4>=5)\n\nprint(\"comparación de cadenas\")\nprint(\"mama\"<\"papa\")\nprint (\"mama\">\"papa\")\nprint (\"mama\">=\"papa\")\nprint (\"mama\"<=\"papa\")\nprint (\"mama\"!=\"papa\")\nprint (\"mama\"==\"papa\")\n\nprint(len(\"mama\") == len(\"papa\"))\n\nprint(\"*** operadores logicos****\")\n\nprint(4<5 and 5>3)\nprint(4<5 and 5<3)\nprint(4>5 and 5>3)\nprint(4>5 and 5<3)\n\n\nprint(4<5 or 5>3)\nprint(4<5 or 5<3)\nprint(4>5 or 5>3)\nprint(4>5 or 5<3)\n\nprint('True or False:', True or False)\n\nprint(not(5>3))\nprint(not(4>5))\nprint(4<5 and not(5<3))\n\nprint(\"*** identidad ***\")\n\na=4\nb=5\nprint(a is b)\n\nprint(a is not b)\n\na=[4,5]\nb=[4,5]\nprint(a is b)#sale falso por que aunque tiene los mismo numeros son distintos objetos en la memoria\n\nprint(a is not b)\n\n\nprint(\"***operadores de permanencia ***\")\n\na=[4,5]\nprint(4 in a)\n\nprint(6 in a)\n\nprint(6 not in a)\n#DIFICULTAD EXTRA (opcional):\n\"\"\"\"\"\nCrea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\"\"\"\"\"\nprint(\"***Condicionales, iterativas, excepciones...***\")\n\nnumbers=range(10,56)\nfor number in numbers: \n\n    if (number%2)==0:\n        if number!=16:\n            if (number%3)!=0:\n                print(number)   \nprint(\"otra forma \")\nfor number in numbers: \n\n    if (number%2)==0 and number!=16 and number%3!=0:\n        print(number) \n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/yah1r404.py",
    "content": "\"\"\"CONDICIONALES\"\"\"\n\n# OPERADORES ARITMÉTICOS\na = 10\nb = 3\nprint(\"Arithmetic Operators:\")\nprint(f\"Addition: {a + b}\")\nprint(f\"Subtraction: {a - b}\")\nprint(f\"Multiplication: {a * b}\")\nprint(f\"Division: {a / b}\")\nprint(f\"Floor Division: {a // b}\")\nprint(f\"Modulus: {a % b}\")\nprint(f\"Exponentiation: {a ** b}\")\nprint()\n\n# OPERADORES RELACIONALES O DE COMPARACIÓN\nprint(\"Operadores Relacionales\")\nprint(f\"Mayor que: 101 > 100 es {101 > 100}\")\nprint(f\"Mayor que: 100 > 101 es {100 > 101}\")\nprint(f\"Menor que: 101 < 100 es {101 < 100}\")\nprint(f\"Menor que: 100 < 101 es {100 < 101}\")\nprint(f\"Igualdad: 999 == 999 es {999 == 999}\")\nprint(f\"Igualdad: 999 == 1000 es {999 == 1000}\")\nprint(f\"Mayor o igual que: 101 >= 100 es {101 >= 100}\")\nprint(f\"Mayor o igual que: 99 >= 101 es {99 >= 101}\")\nprint(f\"Menor o igual que: 101 <= 100 es {101 <= 100}\")\nprint(f\"Menor o igual que: 99 <= 101 es {99 <= 101}\")\nprint(f\"Desigualdad: 1 != 1 es {1 != 1}\")\nprint(f\"Desigualdad: 10 != 20 es {10 != 20}\")\n\n# OPERADORES LÓGICOS\nprint(\"Operadores Lógicos\")\nprint(f\"AND: 10 + 33 == 43 and 20 + 20 == 40 es {10 + 33 == 43 and 20 + 20 == 40}\")\nprint(f\"OR: 10 + 33 == 43 or 20 + 20 == 40 es {10 + 33 == 43 or 20 + 20 == 40}\")\nprint(f\"NOT: 21 + 20 == 40 es {not 21 + 20 == 40}\")\n\n# OPERADORES DE ASIGNACIÓN\nprint(\"Operadores de Asignación\")\nnumberPy = 25\nprint(numberPy)\nnumberPy += 25 # suma y asignación\nprint(numberPy)\nnumberPy -= 25 # resta y asignación\nprint(numberPy)\nnumberPy *= 25 # multiplicación y asignación\nprint(numberPy)\nnumberPy /= 25 # división y asignación\nprint(numberPy)\nnumberPy **= 25 # exponente y asignación\nprint(numberPy)\nnumberPy //= 25 # división entera y asignación\nprint(numberPy)\nnumberPy %= 25 # módulo y asignación\nprint(numberPy)\n\n# OPERADORES DE IDENTIDAD\nprint(\"Operadores de Identidad\")\nerror = 404\nerror2 = 404\nprint(f\"error is error2 es {error is error2}\")\nprint(f\"error is not error2 es {error is not error2}\")\n\n# OPERADORES DE PERTENENCIA\nprint(\"Operadores de Pertenencia\")\n\nindie = \"hollow knight\"\nprint('hollow' in indie)\nprint('undertale' in indie)\nprint('undertale' not in indie)\n\npi = [1,2,3,4,5,99]\nprint(99 in pi)\nprint(99 not in pi)\nprint(9 in pi)\nprint(9 not in pi)\n\nprint(f\"'x' in 'hunter x hunter' is {'x' in 'hunter x hunter'}\")\nprint(f\"'x' not in 'hunter x hunter' is {'x' not in 'hunter x hunter'}\")\n\n# OPERADORES DE BIT\n\nprint(\"Operadores de Bits\")\n\na = 5     \nb = 3     \n\n# AND - 1 si ambos bits son 1, 0 si no\nprint(a & b)      # (0101 & 0011 = 0001)\n\n# OR - 1 si al menos uno de los bits es 1\nprint(a | b)      # (0101 | 0011 = 0111)\n\n# XOR - 1 si los bits son diferentes, 0 si son iguales\nprint(a ^ b)      # (0101 ^ 0011 = 0110)\n\n# NOT - invierte todos los bits xd\nprint(~a)         # (~0101 = -(5 + 1) = -6)\n\n# LEFT SHIFT - mueve los bits a la izquierda y agrega un 0 al final\nprint(a << 1)     # (0101 becomes 1010)\n\n# RIGHT SHIFT - mueve los bits a la derecha y agrega un 0 al inicio\nprint(a >> 1)     # (0101 becomes 0010)\n\n\"\"\"\nESTRUCTURAS DE CONTROL \n\"\"\"\n# CONDICIONALES\n\nmy_taco = \"taco de cochinita\"\n\nif my_taco == \"taco de pastor\":\n    print(\"my_taco es 'taco de pastor'\")\nelif my_taco == \"taco de surtido\":\n    print(\"my_taco es 'taco de surtido'\")\nelse:\n    print(\"my_taco no es 'taco de pastor' ni 'taco de surtido'\")\n\n# ITERATIVAS\n\nfor i in range(11):\n    print(i)\n\ni = 0\n\nwhile i <= 10:\n    print(i)\n    i += 1\n\n# MANEJOR DE EXCEPCIONES\ntry:\n    print(99 / 1)\nexcept:\n    print(\"Se ha producido un error\")\nfinally:\n    print(\"Ha finalizado el manejo de sesiones\")\n\n# EJERCICIO EXTRA\n\nfor num in range(10, 56):  # del 10 al 55 (56 no se incluye)\n    if num % 2 == 0 and num != 16 and num % 3 != 0:\n        print(num)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/ycanas.py",
    "content": "# --------- Operadores\n\n# --- I. Asignación\n\n# 1. Asignar un valor\n\nA = 10\nprint(f\"A = {A}\")\n\n# 2. Asignar y realizar operación\n\n\"\"\" Los operadores de asignación son herramientas que\npermiten combinar operadores aritméticos y de bits\npara asignar y operar valores de manera abreviada.\nEstos operadores se presentan en formas como \n\n    +=, -=, *=, /=, %=, **=, //=, &=, |=, ^=, >>=, <<=\n\ndonde se fusiona primero el operador aritmético con el\noperador de asignación correspondiente. \"\"\"\n\nA += 10\nprint(f\"A += 10 = {A}\")\n\n\n# --- II. Aritmeticos\n\n# 1. Suma\n\n\"\"\" Juan tenía 5 manzanas y su amigo le dio 3 manzanas más.\n ¿Cuántas manzanas tiene ahora en total? \"\"\"\n\nA = 5\nB = 3\n\nC = A + B\nprint(f\"Juan tiene en total {C} manzanas.\")\n\n# 2. Resta\n\n\"\"\" Si un DVD cuesta $10 y tienes $7,\n¿cuánto falta para poder comprarlo? \"\"\"\n\nA = 10\nB = 7\n\nC = A - B\nprint(f\"Faltan {C}$ para comprar el DVD.\")\n\n# 3. Multipliación\n\n\"\"\" Una caja contiene 6 paquetes de galletas,\ncada paquete tiene 12 galletas.\n¿Cuántas galletas hay en total? \"\"\"\n\nA = 6\nB = 12\n\nC = A * B\nprint(f\"En total hay {C} galletas.\")\n\n# 4. División\n\n\"\"\" Tienes 18 dulces y quieres compartirlos\nentre 6 amigos de manera equitativa.\n¿Cuántos dulces le tocan a cada amigo? \"\"\"\n\nA = 18\nB = 6\n\nC = A / B\nprint(f\"A cada amigo le tocan {C} dulces.\")\n\n# 5. División entera\n\n\"\"\" Un pastel se corta en 8 porciones iguales.\nSi quieres repartirlo entre 3 personas,\n¿cuántas porciones enteras recibirá cada persona? \"\"\"\n\nA = 8\nB = 3\n\nC = A // B\nprint(f\"Cada persona recibira {C} porciones enteras.\")\n\n# 6. Módulo\n\n\"\"\" Si divides 25 entre 7, ¿cuál es el resto? \"\"\"\n\nA = 25\nB = 7\n\nC = 25 % 7\nprint(f\"El resto de la división es {C}.\")\n\n# 7. Potencia\n\n\"\"\" Si un cuadrado tiene un lado de longitud 5 cm, ¿cuál es su área? \"\"\"\n\nA = 5\n\nB = 5 ** 2\nprint(f\"El área del cuadrado es {B}.\")\n\n\n# --- III. Comparación\n\n# 1. Igual\n\n\"\"\" Comparar si los números 2 y 8 son iguales \"\"\"\n\nA = 2\nB = 8\n\nC = A == B\nprint(f\"¿Los números {A} y {B} son iguales?: {C}\")\n\n# 2. Diferente\n\n\"\"\" Comparar si los números 2 y 8 son diferentes \"\"\"\n\nC = A != B\nprint(f\"¿Los números {A} y {B} son diferentes?: {C}\")\n\n# 3. Mayor\n\n\"\"\" Comparar si el número 8 es mayor que el número 2 \"\"\"\n\nC = B > A\nprint(f\"¿El número {B} es mayor que el número {A}?: {C}\")\n\n# 4. Menor\n\n\"\"\" Comparar si el número 8 es menor que el número 2 \"\"\"\n\nC = B < A\nprint(f\"¿El número {B} es menor que el número {A}?: {C}\")\n\n# 5. Mayor o igual\n\n\"\"\" Comparar si el número 2 es mayor o igual que el número 8 \"\"\"\n\nC = A >= B\nprint(f\"¿El número {A} es mayor o igual que el número {B}?: {C}\")\n\n# 6. Menor o igual\n\n\"\"\" Comparar si el número 2 es menor o igual que el número 8 \"\"\"\n\nC = A <= B\nprint(f\"¿El número {A} es menor o igual que el número {B}?: {C}\")\n\n\n# --- IV. Lógicos\n\n# 1. and\n\n\"\"\" Para asistir a un concierto, se requiere que el\nindividuo sea mayor de 18 años y tenga su boleto. \nSi cumple ambas condiciones, se le permite el acceso. \"\"\"\n\nA = 18\nB = True\n\nC = (A > 18) and B\nprint(f\"¿Puede ingresar al concierto?: {C}.\")\n\n# 2. or\n\n\"\"\" En una tienda, se ofrece un descuento del 10%\nsi el cliente compra más de 5 artículos o si el\ntotal de la compra supera los $100. \"\"\"\n\nA = 4\nB = 101\n\nC = (A > 5) or (B > 100)\nprint(f\"¿Aplica al descuento?: {C}.\")\n\n# 3. not\n\n\"\"\" Para entrar a un laboratorio se requiere que \nla persona no tenga enfermedades \"\"\"\n\nA = True\n\nB = not A\nprint(f\"¿La persona puede entrar?: {B}.\")\n\n\n# --- V. Identidad\n\n# 1. is\n\n\"\"\" Verificar si la variable A es un dato nulo \"\"\"\n\nA = None\n\nB = A is None\nprint(f\"¿La variable A es un dato nulo?: {B}\")\n\n# 2. is not\n\n\"\"\" Verificar si la variable A no es un dato nulo \"\"\"\n\nA = None\n\nB = A is not None\nprint(f\"¿La variable A no es un dato nulo?: {B}\")\n\n# --- VI. Pertenencia\n\n# 1. in\n\n\"\"\" Verificar si la letra 'n' esta en la palabra 'hola' \"\"\"\n\nA = 'n'\nB = 'hola'\n\nC = A in B\nprint(f\"¿La letra {A} esta en la palabra {B}? {C}.\")\n\n# 2. not in\n\n\"\"\" Verificar si la letra 'n' no esta en la palabra 'hola' \"\"\"\n\nA = 'n'\nB = 'hola'\n\nC = A not in B\nprint(f\"¿La letra {A} no esta en la palabra {B}? {C}.\")\n\n# --- VII. Bits\n\n# 1. and\n\nA = 10\nB = 5\n\nC = A & B\nprint(f\"{A} & {B} = {C}\")\n\n# 2. or\n\nA = 10\nB = 5\n\nC = A | B\nprint(f\"{A} | {B} = {C}\")\n\n# 3. xor\n\nA = 10\nB = 5\n\nC = A ^ B\nprint(f\"{A} ^ {B} = {C}\")\n\n# 4. not\n\nA = 10\n\nB = ~A\nprint(f\"~{A} = {B}\")\n\n# 5. Dezplazamiento a la izquierda\n\nA = 10\nB = 5\n\nC = A << B\nprint(f\"{A} << {B} = {C}\")\n\n# 6. Dezplazamiento a la derecha\n\nA = 10\nB = 5\n\nC = A >> B\nprint(f\"{A} >> {B} = {C}\")\n\nprint('-' * 100)\n\n\n# --------- Estructuras de Control\n\n# --- I. condicionales\n\n# 1. if\n\nA = 10\nB = A\n\nif A is B: print(\"A is B\")\n\n# 2. else\n    \nif A is B:\n    print(\"A is B\")\nelse:\n    print(\"A not is B\")\n\n# 3. elif\n    \nA = 10\nB = 7\n\nif A == B:\n    print(\"A == B\")\nelif A < B:\n    print(\"A < B\")\nelse:\n    print(\"A > B\")\n\n\n# --- II. Bucles\n    \n# 1. for\n    \nnumeros = [i for i in range(10)]\n\nfor numero in numeros:\n    print(numero, end=' ')\n\nprint()\n\n# 2. while\n\nA = 100\n\nwhile not A == 0:\n    print(A, end=' ')\n    A = A // 2\n\nprint()\n\n# 3. break\n\nA = 100\n\nwhile True:\n    A = A - 10\n\n    if A < 50:\n        break\n\n# 4. continue\n    \nfor i in range(6):\n    if i == 0:\n        continue\n\n    print(i, end=' ')\n\nprint()\n\n# 5. pass\n    \ndef hola():\n    pass\n\nprint(\"Esto no ejecuta nada\")\n\n# --- III. Excepciones\n\n# 1. try\n\nA = 5\nB = '2'\n\ntry:\n    C = A + B\nexcept:\n    print(\"Error.\")\n\n# 2. finally\n    \ntry:\n    C = A + B\nexcept:\n    print(\"Error.\", end=' ')\nfinally:\n    C = 0\n\nprint(C)\n\nprint('-' * 100)\n\n\n# --------- Extra\n\nfor i in range(10, 56):\n    if i == 16 or i % 3 == 0:\n        continue\n\n    if i % 2 == 0:\n        print(i)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/yeam-10.py",
    "content": "\"\"\"\nRespuesta de ejercicio 01\n\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\"\"\"\n\n#Operadores de asignacion \n\n# El operador '=' sirve para asignar el valor de la variable Ejemplo\n\nprice = 909\nprint(price)\n\nprice += 1 # asigna y suma 1\nprint(price)\nprice -= 3 # asigna y resta 3\nprint(price)\nprice /= 5  # asigna y divide 5\nprint(price) \nprice //= 6 # asigna y realiza la division entera\nprint(price)\nprice *= 7 # asigna y multiplica 7\nprint(price)\nprice %= 3 # asigna y calcula resto de 3\nprint(price)\nprice **= 2 # exponente y asignacion\n\n\n#Operadores aritmeticos:\n#Son aquellos que nos permiten realizar operaciones matematicas como suma, multiplicacion, division\n\nprint(\"La suma de 2 + 3:\", 2+3) #Suma\nprint(\"La resta de 2 - 3:\", 2-3) #Resta\nprint(\"La multiplicacion de 4 * 3:\", 2*3) #Multiplicacion\nprint(\"La division de 2 / 3:\", 2/3) #Division\n\n#Operadores relacionales\n#Permiten realizar comparaciones entre dos elementos. Son los siguientes \n# < Menor que\n# > Mayor que \n# >= Mayor o igual que \n# <= Menor o igual que\n# == Igual que \n# != Distinto que \n\nprint(\"7 < 5\", 7 < 5 ) # 7 es menor que 5 ? \nprint(\"8 > 5\", 8 > 5 ) # 8 es mayor que 5 ?\nprint(\"10 >= 15\", 7 < 5 ) # 10 mayor o igual que 15 ?\nprint(\"2 <= 12\", 2 <= 12 ) # 2 es menor o igual que 12 ?\nprint(\"67 == 5\", 67 == 5 ) # 67 es igual que 5 ?\nprint(\"4 != 9\", 4 != 9 ) # 4 es distinto que 5 ?\n\n#Operadores logicos \n# Permiten combinar las operaciones relacionales o valores booleanos independientes para obtener un unico resultado\n#Los operadores logico son AND, OR, NOT\n\nprint(\"Operacion (5<3) AND (4==3) es:\", 5<3 and 4==3)\nprint(\"Operacion (5<3) OR (4==3) es:\", 1<7 or 3==3)\nprint(\"Operacion (5<3) NOT (4==3) es:\", not (5<3 and 4==3))\n\n#Operadores de identidad\n\ntotal_price = price\nprint(\"total_price is price\", total_price is price)\nprint(\"total_price is price\", total_price is not price)\n\n#Operadores de pertenencia \n\nprint(\" r in request\", 'r' in 'request')\nprint(\" r in request\", 'r' not in  'request')\n\n\"\"\"\nEstructuras de control \n\"\"\"\n#Condicionales\n# if permite generar un bloque de codigo que se ejecutara si se cumple la condicion de entrada que tiene.\n# elif: permite generar un camino alternativo con una condicion de entrada. \n# else: permite generar un camino alternatuvo siempre que no se hayan cumplido las condiciones if y elif.\n\nnumber_one = 2\nnumber_two = 4\n\nif number_one > number_two:\n    print(\"Es mayor\")\nelif number_one == number_two:\n    print(\"Son iguales\")\nelse:\n    print(\"El primer numero es menor\")\n\n#Iterativas\n    \n#Bucle for \n    \nfor item in range(10):\n    print(item)\n\n#Bucle while\n\ni = 0\nwhile i < 10:\n    print(i)\n    i= i + 1\n\n\"\"\"\nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\"\"\"\n\n#Respuesta\n\nfor num in range(10,55):\n    if num % 2 == 0 and num != 16 and num % 3 != 0:\n        print(num)\n    \n\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/yenneralayon142.py",
    "content": "\n# ===== > Operadores aritmeticos < ======\n\n# suma\n\nsuma = 1 + 1\nprint(\"La suma es:  \", suma) #2\n\n# resta\n\nresta = 7 - 6\nprint(\"La resta es:  \",resta) #1\n\n# multiplicación\n\nmultiplicación = 7 * 6\nprint(\"La multiplicación es:  \",multiplicación) #42\n\n# División\n\ndivision = 7 / 6\nprint(\"La división es:  \",division) #1.16\n\n\n# División Interna\n\ndivisionI = 7 // 6\nprint(\"La división interna es: \",divisionI) #1\n\n\n# Módulo\n\nmodulo = 7 % 6\nprint(\"El módulo es:  \", modulo) #1\n\n\n# Potencia\n\npotencia = 7 ** 6\nprint(\"La potencia es:  \",potencia) #117649\n\n# ===== > Operadores logicos < ======\n\n# Igual\n\nlogica1 =  1 == 2\nprint(\"El resultado del operador logico igual es: \", logica1) #False\n\n# Diferente\n\nlogica2 = 1 != 2\nprint(\"El resultado del operador logico diferente es: \",logica2) #True\n\n\n# más que\n\nlogica3 = 1 > 2\nprint(\"El resultado del operador logico más que es: \",logica3) #False\n\n\n# menos que\n\nlogica4 = 1 < 2\nprint(\"El resultado del operador logico menos que es: \",logica4) #True\n\n# más o igual que\n\nlogica5 = 1 >= 2\nprint(\"El resultado del operador logico más o igual que es: \",logica5) #False\n\n\n# menos o igual que\n\nlogica6 = 1 <= 2 \nprint(\"El resultado del operador logico menos o igual que es: \",logica6) #True\n\n# # ===== > Operadores de comparación < ======\n\n# and\n\ncomp1 = 1 and 2 < 3\nprint(\"El resultado del operador de comparación and es: \",comp1) #True\n\n# or\n\ncomp2 = (1 == 1) or (2 < 3)\nprint(\"El resultado del operador de comparación or es: \",comp2) #True\n\n# not\n\ncomp3 = not 2 < 3\nprint(\"El resultado del operador de comparación not es: \",comp3) #False\n\n\n\n# ===== > Operadores de asignación < ======\n\nasignación = 10\n\n#+=\n\nasignación += 5\nprint(\"El resultado del operador asignación más es: \",asignación) #15\n\n#-=\n\nasignación -= 5\nprint(\"El resultado del operador asignación menos es: \",asignación) #10\n\n# *=\n\nasignación *= 5\nprint(\"El resultado del operador asignación por es: \",asignación) #50\n\n# /=\n\nasignación /= 5\nprint(\"El resultado del operador asignación división es: \",asignación) #10.0\n\n\n# //=\n\nasignación //= 5\nprint(\"El resultado del operador asignación división interna es: \",asignación) #2.0\n\n# %=\n\nasignación %= 5\nprint(\"El resultado del operador asignación módulo es: \",asignación) #2.0\n\n\n#**\n\nasignación **= 5\nprint(\"El resultado del operador asignación potenciación es: \",asignación) #32.0\n\n# ===== > Operadores de identidad < ======\n\n# is\nidentidad1 = 10\nidentidad2 = 10\nprint(\"El resultado del operador de identidad is es: \",identidad1 is identidad2) #True\n\n# is not \n\nprint(\"El resultado del operador de identidad is not es: \",identidad1 is not identidad2) #False\n\n\n# ===== > Operadores de pertenencia < ======\n\n#in\n\npertenencia1 = [1,2,3,4,5,6]\nprint(\"El resultado del operador de pertenencia in es: \",3 in pertenencia1) #True\n\n#not in\n\nprint(\"El resultado del operador de pertenencia not in es: \",8 not in pertenencia1) #True\n\n\n# ===== > Operadores Bit < ======\n\na,b = 15,3\n\n#and bit\nprint(\"El resultado del operador & es :  \",a & b) #3\n\n#OR bit\nprint(\"El resultado del operador | es :  \",a | b) #15\n\n#XOR bit\nprint(\"El resultado del operador ^ es :  \",a ^ b) #12\n\n#NOT\nprint(\"El resultado del operador ~ es :  \",~a) #-16\n\n#Desplazamiento a la derecha\n\nprint(f\"Desplazamiento a la derecha: 8 >> 2 = {8 >> 2}\")  # 2\n\n#Desplazamiento a la izquierda\n\nprint(f\"Desplazamiento a la izquierda: 8 << 2 = {8 << 2}\")  # 32\n\n\n# ===== > Estructuras de control < ======\n\ncontrol = 10\n\n#IF\n\nif control < 11:\n   print(True)\nelif control < 12:\n   print(\"El número es menor\")\nelse:\n   print(False)  #True\n\n\n#FOR\nnumero = 5  \nfor i in range(1,11):\n   tabla = numero * i\n   print(tabla) #Valores de numero multiplicados\n\n\n# WHILE\n   \ni = 0\nwhile i <= 10:\n    print(i)\n    i += 1 #Numeros hasta 10\n\n#TRY\n    \ntry:\n   print(8 / 2)\nexcept:\n   print(\"Se ha producido un error\")\nfinally:\n   print(\"Ha finalizado el manejo de excepciones\")\n   \n\n\n#DIFICULTAD EXTRA\n   \nfor i in range(10,56):\n   if i % 2 == 0 and i != 16 and i % 3 != 0:\n      print(i) \n   \n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/yharyarias.py",
    "content": "# Operadores aritméticos\n\n# Suma\na = 9\nb = 6\nsuma = a + b\nprint(\"Suma: \", suma)\n\n# Resta\nresta = a - b\nprint(\"Resta: \", resta)\n\n# Multiplicación\nmultiplicacion = a * b\nprint(\"Multiplicación: \", multiplicacion)\n\n# Division\ndivision = a / b\nprint(\"División: \", division)\n\n# Division entera (aproximación)\ndiv_entera = a // b\nprint(\"Division aproximación: \", div_entera)\n\n# Modulo\nmodulo = a % b\nprint(\"Módulo: \", modulo)\n\n# Potencia\npotencia = a ** b\nprint(potencia)\n\n# Operadores de comparación\n\nx = 10\ny = 5\n\n# Igual\nprint(\"Igualdad: \", x == y)\n\n# Diferente\nprint(\"Diferencia\", x != y)\n\n# Mayor\nprint(\"Mayor: \", x > y)\n\n# Mayor o igual\nprint(\"Mayor o igual: \", x >= y)\n\n# Menor\nprint(\"Menor: \", x < y)\n\n# Menor o igual\nprint(\"Menor o igual\", x <= y)\n\n# Operadores lógicos\nt = True\nf = False\n\n# AND lógico\nand_logico = t and f\nprint(\"AND lógico: \", and_logico)\n\n# OR lógico\nor_logico = t or f\nprint(\"OR lógico \", or_logico)\n\n# NOT lógico\nnot_logico = not t\nprint(\"NOT lógico \", not_logico)\n\n# Operadores de asignación\n# Asignación simple\nx = 4\nprint(\"Asignación simple: \", x)\n\n# Asignación con operación\nx += 5 # x = x + 5\nprint(\"Asignación con operación: \", x)\n\n# Operadores de identidad\n\na = [1, 2, 3]\nb = a\nc = [1, 2, 3]\n\n# is\nprint(\"a es b: \", a is b)\nprint(\"a es c \", a is c)\n\n# is not\nprint(\"a no es b \", a is not b)\nprint(\"a no es c \", a is not c)\n\n# Operadores de pertenencia\nlista = [1, 2, 3, 4, 5]\n\n# in\nprint(\"2 está en la lista: \", 2 in lista)\nprint(\"6 está en la lista: \", 6 in lista)\n\n# not in\nprint(\"2 no está en la lista: \", 2 not in lista)\nprint(\"6 no está en la lista: \", 6 not in lista)\n\n# Operadores a nivel de bits\nx = 5\ny = 3\n\n# AND a nivel de bits\nand_bits = x & y\nprint(\"AND a nivel de bits \", and_bits)\n\n# OR a nivel de bits\nor_bits = x | y\nprint(\"OR a nivel de bits: \", or_bits)\n\n# XOR a nivel de bits\nxor_bits = x ^ y\nprint(\"XOR a nivel de bits:\", xor_bits)\n\n# Desplazamiento a la izquierda\ndesplazamiento_izquierda = x << 1\nprint(\"Desplazamiento a la izquierda:\", desplazamiento_izquierda)\n\n# Desplazamiento a la derecha\ndesplazamiento_derecha = x >> 1\nprint(\"Desplazamiento a la derecha:\", desplazamiento_derecha)\n\n\n# -------------------------------------------------------------------\n#  Estructuras condicionales\n\n# if else\nedad = 28\n\nif edad >= 18:\n    print(\"Eres mayor de edad.\")\nelse:\n    print(\"Eres menor de edad.\")\n\n\n# elif\nnota = 75\n\nif nota >=  90:\n    print(\"Excelente\")\nelif nota >= 70:\n    print(\"Buen trabajo\")\nelse:\n    print(\"Necesitas mejorar\")\n\n# Estructuras iterativas\nfrutas = [\"Pera\", \"Manzana\", \"Cereza\", \"Banana\"]\n\nfor fruta in frutas:\n    print(fruta)\n\n# while\ncontador = 0\n\nwhile contador < 5:\n    print(contador)\n    contador += 1\n\n# Estructuras de excepciones\ntry:\n    division = 10 / 0\nexcept ZeroDivisionError:\n    print(\"Error: División por cero.\")\nexcept Exception as e:\n    print(f\"Ocurrió una excepción: {e}\")\nelse:\n    print(\"La operación se realizó sin errores.\")\nfinally:\n    print(\"Este bloque siempre se ejecuta.\")\n\n# Estructuras de control de flujo\n# break y continue\nfor i in range(10):\n    if i == 5:\n        break\n    print(i)\nfor i in range(10):\n    if i == 5:\n        continue\n    print(i)\n\n# pass\nfor i in range(5):\n    # Bloque de codigo con ninguna acción\n    pass\n\n# Estructura de control de contexto\n# with open(\"archivo.txt\", \"r\") as archivo:\n#     contenido = archivo.read()\n\n# DIFICULTAD EXTRA (opcional):\nfor i in range(10, 56):\n    if i % 2 == 0 and i % 3 == 0 & i != 16:\n        print (i)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/yoezequiel.py",
    "content": "# Operadores aritméticos\nnum1 = 10\nnum2 = 5\nprint(\"Operadores aritméticos:\")\nprint(\"Suma:\", num1 + num2)\nprint(\"Resta:\", num1 - num2)\nprint(\"Multiplicación:\", num1 * num2)\nprint(\"División:\", num1 / num2)\nprint(\"Módulo:\", num1 % num2)\nprint(\"Exponente:\", num1**num2)\nprint(\"División entera:\", num1 // num2)\n\n# Operadores de comparación\na = 10\nb = 20\nprint(\"Operadores de comparación:\")\nprint(\"Igualdad:\", a == b)\nprint(\"Desigualdad:\", a != b)\nprint(\"Mayor que:\", a > b)\nprint(\"Menor que:\", a < b)\nprint(\"Mayor o igual que:\", a >= b)\nprint(\"Menor o igual que:\", a <= b)\n\n# Operadores lógicos\nx = True\ny = False\nprint(\"Operadores lógicos:\")\nprint(\"AND:\", x and y)\nprint(\"OR:\", x or y)\nprint(\"NOT:\", not x)\n\n# Operadores de asignación\nc = 5\nprint(\"Operadores de asignación:\")\nc += 3\nprint(\"Suma y asignación:\", c)\nc -= 2\nprint(\"Resta y asignación:\", c)\nc *= 4\nprint(\"Multiplicación y asignación:\", c)\nc /= 2\nprint(\"División y asignación:\", c)\n\n# Operadores de identidad\nlist1 = [1, 2, 3]\nlist2 = [1, 2, 3]\nprint(\"Operadores de identidad:\")\nprint(\"is:\", list1 is list2)\nprint(\"is not:\", list1 is not list2)\n\n# Operadores de pertenencia\nprint(\"Operadores de pertenencia:\")\nprint(\"in:\", 2 in list1)\nprint(\"not in:\", 4 not in list1)\n\n# Operadores a nivel de bits\nnum3 = 7\nnum4 = 3\nprint(\"Operadores a nivel de bits:\")\nprint(\"AND a nivel de bits:\", num3 & num4)\nprint(\"OR a nivel de bits:\", num3 | num4)\nprint(\"XOR a nivel de bits:\", num3 ^ num4)\nprint(\"Desplazamiento a la derecha:\", num3 >> 1)\nprint(\"Desplazamiento a la izquierda:\", num4 << 1)\n\n# Estructuras de control\nprint(\"Estructuras de control:\")\n# Condicionales\nif a > b:\n    print(\"a es mayor que b\")\nelif a == b:\n    print(\"a es igual a b\")\nelse:\n    print(\"a es menor que b\")\n\n# Iterativas\nprint(\"Bucle while:\")\ncount = 0\nwhile count < 5:\n    print(count, end=\" \")\n    count += 1\n\nprint(\"Bucle for:\")\nfor i in range(1, 6):\n    print(i, end=\" \")\n\n# Excepciones\nprint(\"Manejo de excepciones:\")\ntry:\n    result = 10 / 0\nexcept ZeroDivisionError:\n    print(\"Error: División por cero\")\n\n# Programa extra (DIFICULTAD EXTRA)\nprint(\"Números entre 10 y 55, pares, no 16 ni múltiplos de 3:\")\nfor num in range(10, 56):\n    if num % 2 == 0 and num != 16 and num % 3 != 0:\n        print(num, end=\" \")\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/zalazarmartin.py",
    "content": "# Operadores Aritméticos\n\na = 10\nb = 1\n\nadicion = a + b\nsubtraccion = a - b\nmultiplicacion = a * b\ndivision = a / b\nmodulo = a % b\npotencia = a ** b\n\nop_ar = f\"\"\"\nOperadores Aritméticos\n-----------------------\nadicion = {adicion}\nsubtraccion = {subtraccion}\nmultiplicacion = {multiplicacion}\ndivision = {division}\nmodulo = {modulo}\npotencia = {potencia}\n\"\"\"\n\nprint(op_ar)\n\n# Operadores Relacionales\n\nigualdad = (a == b)\ndesigualdad = (a != b)\nmayor_que = (a > b)\nmenor_que = (a < b)\nmayor_o_igual_que = (a >= b)\nmenor_o_igual_que = (a <= b)\n\nop_rl = f\"\"\"\nOperadores Relacionales\n-----------------------\nigualdad = {igualdad}\ndesigualdad = {desigualdad}\nmayor_que = {mayor_que}\nmenor_que = {menor_que}\nmayor_o_igual_que = {mayor_o_igual_que}\nmenor_o_igual_que = {menor_o_igual_que}\n\"\"\"\n\nprint(op_rl)\n\n# Operadores de Asignación\n\nprint('''\nOperadores de Asignación\n-----------------------''')\nx = 5\nprint(x)\n# Operador de asignación simple\nx = 10\nprint(x)\n# Operador de asignación con suma\nx += 3\nprint(x)\n# Operador de asignación con resta\nx -= 2\nprint(x)\n# Operador de asignación con multiplicación\nx *= 4\nprint(x)\n# Operador de asignación con división\nx /= 2\nprint(x)\n# Operador de asignación con módulo\nx %= 3\nprint(x)\n# Operador de asignación con exponenciación\nx **= 2\nprint(x)\n\n# Operadores Lógicos\n\nvar_and = True and False  # Devuelve True si ambos operandos son True\nvar_or = True or False  # Devuelve True si alguno de los operandos es True\nvar_not = not True  # Devuelve True si alguno de los operandos False\n\nop_lg = f\"\"\"\nOperadores Lógicos\n-----------------------\nvar_and = {var_and}\nvar_or = {var_or}\nvar_not = {var_not}\n\"\"\"\n\nprint(op_lg)\n\n# Operadores de Pertenencia\n\nvar_in = 1 in [1, 2, 3, 4]\nvar_not_in = 1 not in [1, 2, 3, 4]\n\nop_pr = f\"\"\"\nOperadores de Pertenencia\n-----------------------\nvar_in = {var_in}\nvar_not_in = {var_not_in}\n\"\"\"\n\nprint(op_pr)\n\n# Operadores de identidad\n\nvar_is = 1 is int\nvar_is_not = 1 is not int\n\nop_id = f\"\"\"\nOperadores de identidad\n-----------------------\nvar_is = {var_is}\nvar_is_not = {var_is_not}\n\"\"\"\n\nprint(op_id)\n\n# DIFICULTAD EXTRA (opcional):\n\n\ndef programa_1():\n    numeros = [num for num in range(10, 56)\n               if num != 16 and num % 3 != 0 and num % 2 == 0]\n    print(numeros)\n\n\nprograma_1()\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/zetared92.py",
    "content": "# OPERADORES\n\n# Operadores aritméticos\nprint(\"-Operadores aritméticos-\")\nx = 15\ny = 5\n\nsum = x + y\nprint(f\"Suma: 15 + 5 = {sum}\")\n\nsub = x - y\nprint(f\"Resta: 15 - 5 = {sub}\")\n\nmul = x * y\nprint(f\"Multiplicación: 15 * 5 = {mul}\")\n\ndiv = x / y\nprint(f\"División: 15 / 5 = {div}\")\n\nmodule = x % y == 0\nprint(f\"Módulo: 15 % 5 = {module}\")\n\nexponent = x ** y\nprint(f\"Exponente: 15 ** 5 = {exponent}\")\n\ndiv_int = x // y\nprint(f\"División entera: 15 // 5 = {div_int}\")\n\n\n# Operadores de comparación\nprint(\"-Operadores de comparación-\")\n\nequal = x == y\nprint(f\"Igualdad: 15 == 5 es {equal}\")\n\nunequal = x != y\nprint(f\"Desigual: 15 != 5 es {unequal}\")\n\ngreaterThan = x > y\nprint(f\"Mayor que: 15 > 5 es {greaterThan}\")\n\nlessThan = x < y\nprint(f\"Menor que: 15 < 5 es {lessThan}\")\n\ngreaterEqualThan = x >= y\nprint(f\"Mayor o igual: 15 >= 5 es {greaterEqualThan}\")\n\nlessEqualThan = x <= y\nprint(f\"Menor o igual: 15 <= 5 es {lessEqualThan}\")\n\n\n# Operadores lógicos\nprint(\"-Operadores lógicos-\")\nprint(f\"AND && : True and True = {True and True}\")\nprint(f\"OR || : True or False = {True or False}\")\nprint(f\"NOT ! : not True = {not True}\")\n\n# Operadores de asignación\nprint(\"-Operadores de asignación-\")\nmy_int = 15  # Asignamos un valor\nprint(my_int)\nmy_int += 1  \nprint(f\"Suma y asignación: {my_int}\")\nmy_int -= 1  \nprint(f\"Resta y asignación: {my_int}\")\nmy_int *= 2  \nprint(f\"Multiplicación y asignación: {my_int}\")\nmy_int /= 2  \nprint(f\"División y asignación: {my_int}\")\nmy_int %= 2 \nprint(f\"Módulo y asignación: {my_int}\")\nmy_int **= 1  \nprint(f\"Exponente y asignación: {my_int}\")\nmy_int //= 1  \nprint(f\"División entera y asignación: {my_int}\")\n\n# Operadores de identidad\nprint(\"-Operadores de identidad-\")\nprint(f\"x is y = {y is x}\")\nprint(f\"x is y = {y is not x}\")\n\n# Operadores de pertenencia\nprint(\"-Operadores de pertenencia-\")\nprint(f\"'z' in 'zetared' = {'z' in 'zetared'}\")\nprint(f\"'v' not in 'zetared' = {'v' not in 'zetared'}\")\n\n# Operadores de bit\nprint(\"-Operadores de bit-\")\nx = 15 # 1111\ny = 5 # 0101\nprint(f\"AND: x & y = {x & y}\")  \nprint(f\"OR: x | y = {x | y}\")  \nprint(f\"XOR: x ^ y = {x ^ y}\")  \nprint(f\"NOT: ~x = {~x}\")\nprint(f\"Desplazamiento a la derecha: x >> 1 = {x >> 1}\")  \nprint(f\"Desplazamiento a la izquierda: x << 1 = {x << 1}\")  \n\n\n# ESTRUCTURAS DE CONTROL\nprint(\"-Estructuras de control-\")\n# Condicionales\nmy_str = \"Zeta\"\n\nif my_str == \"ZetaRed\":\n    print(\"my_str es 'ZetaRed'\")\nelif my_str == \"Zeta\":\n    print(\"my_str es 'Zeta'\")\nelse:\n    print(\"my_str no es 'ZetaRed' ni 'Zeta'\")\n\n# Iterativas\nprint(\"-Iterativas-\")\nfor i in range(15):\n    print(i)\n\ni = 0\n\nwhile i <= 15:\n    print(i)\n    i += 1\n\n# Manejo de expepciones\n\ntry:\n    print(15 / 0)\nexcept:\n    print(\"Error\")\nfinally:\n    print(\"Manejo de excepciones finalizadas\")\n\n# EJERCICIO EXTRA\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea un programa que imprima por consola todos los números comprendidos\n#  * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\nfor num in range(10, 56):\n    if num % 2 == 0 and num != 16 and num % 3 != 0:\n        print(num)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/zeti1231.py",
    "content": "## Operadores Aritméticos. Utilizan valores numéricos para realizar operaciones aritméticas\n\n# Suma (Addition)\nx = 3\ny = 17\nprint(x + y)\n\n# Resta (Subtraction)\nx = 29\ny = 23\nprint(x - y)\n\n# Multiplicación (Multiplication)\nx = 38\ny = 147\nprint(x * y)\n\n# División (Division)\nx = 275\ny = 51\nprint(x / y)\n\n# Modulo (Modulus)\nx = 26\ny = 14\nprint( x % y)\n\n# Exponencial (Exponentiation)\nx = 6\ny = 5\nprint(x ** y)\n\n# División al piso (Floor Division), da como resultado de la división, el valor entero más cercano redondeado hacia abajo.\nx = 22\ny = 7\nprint(x // y)\n\n\n## Operadores de Asignación. Se utilizan para asignar valores a las variables\n\n# = \nx = 10\nprint(x)\n\n# += \nx = 10\nx += 3\nprint(x), # x = x + 3\n\n# -=\nx = 10\nx -= 3\nprint(x), # x = x - 3\n\n# *=\nx = 10\nx *= 3\nprint(x), # x = x * 3\n\n# /=\nx = 10\nx /= 3\nprint(x), # x = x / 3\n\n# %=\nx = 10\nx %=3\nprint(x), # x = x % 3\n\n# //=\nx = 10 \nx //=3\nprint(x), # x = x // 3\n\n# **=\nx = 10\nx **=3\nprint(x), # x = x ** 3\n\n# &=\nx = 10\nx &=3\nprint(x), # x = & 3\n\n# x |=\nx = 10\nx |=3\nprint(x), # x = x | 3\n\n# ^=\nx = 10\nx ^=3\nprint(x), # x = x ^ 3\n\n# ~=\nx = 10\n~ 10\nprint(x)\n\n# >>=\nx = 10\nx >>=3\nprint(x), # x = x >> 3\n\n# <<=\nx = 10\nx <<=3\nprint(x), # x = x << 3\n\n# :=\nx = 10\nprint(x := 3), # x = 3 print(x)\n\n## Operadores de comparación.Se utilizan para comparar dos valores \n\n# Igual (==)\nx == y \nx = 8\ny = 2\nprint(x==y), # False\n\n# Diferente (!=)\nx != y\nx = 8\ny = 2\nprint(x != y), # True\n\n# Mayor que (>)\nx > y\nx = 8\ny = 2\nprint(x > y), # True\n\n# Menor que (>)\nx < y\nx = 8\ny = 2\nprint(x < y), # False\n\n# Mayor o igual que (>=)\nx >= y\nx = 8\ny = 2\nprint(x >= y), # True\n\n# Menor o igual que (<=)\nx <= y\nx = 8\ny = 12\nprint(x <= y), # True\n\n# Operadores lógicos.Se utilizan para combinar declaraciones condicionales\n\n# and. Retorna Verdadero si ambas afirmaciones son verdaderas\nx = 8\nprint(x > 2 and x < 14), # True\n\n# or. Retorna Verdadero si una de las afirmaciones son verdaderas\nx = 8\nprint(x > 2 or x < 14), # True\n\n# not. Invierte el resultado, retornando Falso si el resultado es Verdadero\nx = 8\nprint(not(x > 2 or x < 14)), # False\n\n\n# Condicionales\n\n# if\n\nx = 15\ny = 56\n\nif y > x:\n    print(\"y es mayor que x\")\n\n# elif\n\nx = 10\ny = 10\nif y > x:\n    print(\"y es mayor a x\")\nelif x == y:\n    print(\"x es igual a y\")    \n\n# else\n\nx = 48\ny = 22 \nif y > x:\n    print(\"y es mayor que x\")\nelif x == y:\n    print(\"x es igual a y\") \nelse:\n    print(\"x es mayor que y\")\n\n# Bucles\n\n# While. Con este bucle se ejecutan un conjunto de declaraciones, siempre que una condición sea verdadera.\n\ni = 1\nwhile i < 10:\n    print(i)\n    i += 1\n\n# Declaración de ruptura \n\ni = 1\nwhile i < 10:\n    print(i)\n    if i == 3:\n        break\n    i += 1\n\n# Declaración de continuación\n\ni = 0\nwhile i < 10:\n    i += 1\n    if i == 3:\n        continue\n    print(i)\n\n\n# Con el comando else se ejecuta el código, hasta que la condición ya no se cumpla\n\ni = 1 \nwhile i < 10:\n    print(i)\n    i += 1\nelse:\n    print(\"i ya no es menor que 10\")\n\n# For.Este bucle se utiliza para iterar sobre listas, tuplas , diccionarios, un conjunto o una cadena       \n\n# Iterando en una lista\n\nmarcas = [\"Mazda\", \"Ford\", \"Kia\"]\nfor x in marcas:\n    print(x)\n\n\n# Iterando en una cadena \n\nfor x in \"caballo de troya\":\n    print(x)\n\n\n# Iterando con ruptura\n\nmarcas = [\"Mazda\", \"Ford\", \"Kia\"]\nfor x in marcas:\n    print(x)\n    if x == \"Ford\":\n        break\n\n\nmarcas = [\"Mazda\", \"Ford\", \"Kia\"]\nfor x in marcas:\n    if x == \"Ford\":\n        break\n    print(x)\n\n\n# Iterando con la instrucción continuar\n\nmarcas = [\"Mazda\", \"Ford\", \"Kia\"]\nfor x in marcas:\n    if x == \"Ford\":\n        continue\n    print(x)\n\n\n# Función rango().Se utiliza para recorrer un conjunto de código, un número específico de veces.Devuelve una secuencia de números, que comienza en un valor determinado, y termina en un valor determinado.\n\nfor x in range(8):\n    print(x)\n\n\nfor x in range(3,10):\n    print(x)\n\n# Por defecto el valor del incremento en la función range es 1, para especificar un valor de incremento diferente, se debe añadir un tercer parámetro a la función.\n\nfor x in range(2,40,6):\n    print(x)  \n\n\n# Utilizando el condicional else en un bucle for\n\nfor x in range(8):\n    print(x)\nelse:\n    print(\"Terminado\")    \n\n# Bucle anidado.Condición en la que un bucle se encuentra dentro de otro bucle.El bucle interno, se ejecuta por cada iteración del bucle externo.\n\n\ncolores = [\"Plata\", \"Negro\", \"Azul\"]\nmarcas = [\"Mazda\", \"Ford\", \"Kia\"]\nfor x in colores:\n    for y in marcas:\n        print(x,y)\n\n\n# DIFICULTAD EXTRA (opcional):\n\"\"\"\nCrea un programa que imprima por consola todos los números comprendidos\nentre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\"\"\"  \nfor numero in range(10, 56):\n    if numero % 2 == 0 and numero != 16 and numero % 3 != 0:\n        print(numero)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/python/ziellucio01.py",
    "content": "# -> Operadores Aritmeticos\na = 1\nb = 3\n\nsuma = a + b  # Este es un operador para sumas\nresta = b - a  # Este operador es para restas\nmulti = a * b  # Este operador es para multiplicación\ndiv = b / a  # Este operador es para Dividir\n\n# -> Operadores Logicos\n#       Exiten 3 tipos de operadores logicos -> and, or y not\n\n\n# Operador and (evalua si ambas condiciones son ciertas para devolver un TRUE)\nprint(\"---------- Operador and -----------\")\nprint(True and True)   # True\nprint(True and False)  # False\nprint(False and True)  # False\nprint(False and False)  # False\n\n# Operador or (Devuelve TRUE cuando almenos alguno de los valores es TRUE)\nprint(\"---------- Operador or -----------\")\nprint(True or True)   # True\nprint(True or False)  # True\nprint(False or True)  # True\nprint(False or False)  # False\n\n# Operador not (Simplemente invierte el valor True por False y False por True)\nprint(\"---------- Operador not -----------\")\nprint(not True)  # False\nprint(not False)  # True\nprint(not not not not True)  # True\n\n# -> Operadores de Comparación\n#       Se usan para saber la relación que existe entre dos variables.\n#       El valor que devuelven es TRUE o FALSE.\n\n# Operador == (Compara si las variables son iguales)\nprint(\"---------- Operador == -----------\")\nprint(4 == 4)          # True\nprint(4 == 5)          # False\nprint(4 == 4.0)        # True\nprint(0 == False)      # True\n\n# Operador != (Devuelve TRUE si los elementos a comparar son iguales y FALSE si son distintos)\nprint(\"---------- Operador != -----------\")\nprint(4 != 4)          # False\nprint(4 != 5)          # True\nprint(4 != 4.0)        # False\nprint(0 != False)      # False\n\n# Operador > (Devuelve TRUE si el primer valor es mayor que el segundo y FALSE de lo contrario)\nprint(\"---------- Operador > -----------\")\nprint(5 > 3)  # True\nprint(5 > 5)  # False\n\n# Operador < (Devuelve TRUE si el primer elemento es menor que el segundo)\nprint(\"---------- Operador < -----------\")\nprint(5 < 3)  # False\nprint(3 < 5)  # True\n\n# Operador >= (Permite comparar si el elemento es mayor o igual)\nprint(\"---------- Operador >= -----------\")\nprint(3 >= 3)           # True\nprint([3, 4] >= [3, 5])  # False\n\n# Operador <= (Devuelve TRUE si el primer elemento es menor o igual que el segundo)\nprint(\"---------- Operador <= -----------\")\nprint(3 <= 2.99999999999999999)  # False\n\n# -> Operadores de Asignación\n#       Nos permiten realizar una operacion y almacenar el resultado en la variable inicial\n\n# Operador =\nprint(\"---------- Operador = -----------\")\nx = 2       # Uso correcto del operador =\nprint(x)  # 2\n# 3=5      # Daría error, 3 no es una variable\n\n# Operador +=\nprint(\"---------- Operador += -----------\")\nx = 5      # Ejemplo de como incrementar\nx += 1     # en una unidad x\nprint(x)  # 6\n\n# Operador -=\nprint(\"---------- Operador -= -----------\")\ni = 5\ni -= 1\nprint(i)  # 4\n\n# Operador *=\nprint(\"---------- Operador *= -----------\")\na = 10\nb = 2  # Inicializamos a 10 y 20\na *= b      # Usando dos variables\nprint(a)  # 20\n\n# Operador /=\nprint(\"---------- Operador /= -----------\")\nx = 10\nprint(type(x))  # <class 'int'>\nx /= 3\nprint(type(x))  # <class 'float'>\n\n# Operador %=\nprint(\"---------- Operador %= -----------\")\nx = 3\nx %= 2\nprint(x)  # 1\n\n# Operador //=\nprint(\"---------- Operador //= -----------\")\nx = 5      # El resultado es el cociente\nx //= 3    # de la división\nprint(x)  # 1\n\n# Operador **=\nprint(\"---------- Operador **= -----------\")\nx = 5      # Eleva el número al cuadrado\nx **= 2    # y guarda el resultado en la misma\nprint(x)  # 25\n\n# Operador &= (Realiza una comparación & bit a bit entre dos variables y almacena el resultado en la primera)\nprint(\"---------- Operador &= -----------\")\na = 0b101010\na &= 0b111111\nprint(bin(a))  # 0b101010\n\n# Operador |\nprint(\"---------- Operador |= -----------\")\na = 0b101010\na |= 0b111111\nprint(bin(a))  # 0b111111\n\n# Operador ^=\nprint(\"---------- Operador ^= -----------\")\na = 0b101010\na ^= 0b111111\nprint(bin(a))  # 0b10101\n\n# Operador >>=\nprint(\"---------- Operador >>= -----------\")\nx = 10\nx >>= 1\nprint(x)  # 5\n\n# Operador <<=\nprint(\"---------- Operador <<= -----------\")\nx = 10     # Inicializamos a 10\nx <<= 1    # Desplazamos 1 a la izquierda\nprint(x)  # 20\n\n# -> Operadores de Identidad\n#       Nos indica si dos variables hacen referencia al mismo objeto\n\n# Operador is\nprint(\"---------- Operador is -----------\")\na = 10\nb = 10\nprint(a is b)  # True\n\n# Operador is not\nprint(\"---------- Operador is not -----------\")\na = [1, 2, 3]\nb = [1, 2, 3]\nprint(a is not b)  # True\n\n\n# -> Reto Opcional\nprint(\"----------- Opcional -------------------------\")\nfor x in range(10, 56):\n    if x % 2 == 0 and x != 16 and x % 3 != 0:\n        print(x)\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/r/Micromantic.R",
    "content": "#\n  # EJERCICIO:\n# - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n#   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n#   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n# - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n#   que representen todos los tipos de estructuras de control que existan\n#   en tu lenguaje:\n#   Condicionales, iterativas, excepciones...\n# - Debes hacer print por consola del resultado de todos los ejemplos.\n#\n  \n  # DIFICULTAD EXTRA (opcional):\n# Crea un programa que imprima por consola todos los números comprendidos\n# entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n#\n# Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n#\n\n### Operadores\n\n## Operadores aritméticos:\n\n# Suma \n\n2 + 2\n\n# Resta\n\n5 - 2\n\n# Multiplicación\n\n7 * 2\n\n# División\n\n21 / 7\n\n# Exponenciación\n\n3 ^ 2\n\n# Módulo\n\n18 %% 2\n18 %% 4\n\n# División entera\n\n18 %/% 2\n18 %/% 4\n\n## Operadores de asignación:\n\n# Asignación izquierda\n\nesto_es_una_variable <- 5+5\nesto_tambien = 4+4\n\n# Asignación derecha\n\n3+3 -> y_esto_tambien\n\n## Operadores de comparación:\n\n# Igual a\n\n5 == 5\n\"casa\" == \"casa\"\n\"bueno\" == \"malo\"\n\n# Diferente de\n\n5 != 5\n\"casa\" != \"casa\"\n\"bueno\" != \"malo\"\n\n# Mayor que\n\n5 > 5\n5 > 4\n5 > 3\n\n# Menor que\n\n5 < 5\n5 < 4\n5 < 3\n\n# Mayor o igual que\n\n5 >= 5\n5 >= 4\n5 >= 3\n\n# Menor o igual que\n\n5 <= 5\n5 <= 4\n5 <= 3\n\n## Operadores lógicos\n\n#Y lógico\n\n5 > 4 && 4 %% 2 == 0\n5 > 4 && 4 %% 2 != 0\n\nc(5, 2) > c(3, 1) & 4 %% 2 == 0\nc(5, 2) > c(3, 1) & 4 %% 2 != 0\n\n#O lógico\n\n5 > 7 || 4 %% 2 == 0\n5 > 7 || 4 %% 2 != 0\n\nc(5, 2) > c(3, 1) | 4 %% 2 == 0\nc(5, 2) > c(3, 1) | 4 %% 2 != 0\n\n# Negación lógica\n\n!(TRUE)\n!(FALSE)\n!(5 == 4)\n!(5 == 5)\n\n## Operadores de secuencia:\n\n# Crear secuencia\n\n1:10\n\n# Operadores de acceso:\n\n# Acceso a listas o data frames\n\nlista <- list(string = \"hola\",\n              enteros =  1:10,\n              booleano = TRUE,\n              lista_pequeña = list(\"chao\", 11:20, FALSE))\nlista$string\n\n# Subconjuntos y acceso a elementos\n\nlista[1]\nlista[[1]]\n\n### Estructuras de control\n\n## De selección\n\n# If\n\nif (3 > 5) {\n  print(\"La condición se cumple\")\n}\n\n# If y else\n\nif (3 > 5) {\n  print(\"La condición se cumple\")\n} else {\n    print(\"La condición no se cumple\")\n  }\n\n# Ifelse\n\nnotas <- data.frame(\n  materia = c(\"Matemática I\", \"Computación I\", \"Estadística I\"),\n  nota = sample(1:20, size = 3, replace = TRUE)\n)\n\nnotas$comentario <- ifelse(notas$nota >= 10,\n                           \"Aprobado\",\n                           \"Reprobado\")\n\nnotas\n\n# Switch\n\nmensaje_final <- function(x) {\n  comentario <- switch(x,\n                       \"Aprobado\" = \"¡Felicitaciones!\",\n                       \"Reprobado\" = \"Sigue intentando\",\n                       \"No hay información\")\n  return(comentario)\n}\n\n## Iterativas\n\n# For\n\nfor (i in 1:5) {\n  print(i + 10)\n}\n\n# While\n\ni <- 0\n\nwhile (i < 10) {\n  print(i + 1)\n  i <- i + 1\n}\n\n# Repeat\n\ni <- 0\n\nrepeat {\n  print(i + 1)\n  i <- i + 1\n  if (i >= 10) {\n    break\n  }\n}\n\nmensaje_final(\"Aprobado\")\nmensaje_final(\"Reprobado\")\n\n\n# Crea un programa que imprima por consola todos los números comprendidos\n# entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n#\n  # Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n#\n\nvector <- c()\nfor (i in 10:55) {\n  if (i %% 2 == 0 & i %% 3 != 0 & i != 16) {\n    vector <- c(vector, i)\n  }\n}\n\nvector\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/r/alabacw74.Rmd",
    "content": "---\ntitle: \"01 OPERADORES Y ESTRUCTURAS DE CONTROL\"\nauthor: \n  - \"Alfredo Aburto Alcudia https://github.com/alabacw74\"\n  - \"Brais Moure https://github.com/mouredev\"\n \ndate: \"`r Sys.Date()`\"\noutput:\n  html_document:\n    toc: true # Mostrar tabla de contenido en documento R markdown\n    toc_depth: 5 # Niveles de la tabla de contenidoo\n    toc_float: true # Mostrar la tabla de contenido en todo el documento\n    collapsed: true # Si solo queremos que muestre el nivel principal\n    smooth_scroll: true # Reflejar nuestra ubicación en barra de contenido\n    theme: journal # Estilo del documento\n    highlight: kate # Estilo del codigo\n    df_print: paged # Estilo para mostrar los datos\n    code_folding: show # Mostrar o no el código del documento---\n---\n\n<div style=\"text-align: justify;\">\n\n##  [roadmap-retos-programacion](https://retosdeprogramacion.com/)\n## Ejercicio \n  1. Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n    Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n    (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n  2. Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n    que representen todos los tipos de estructuras de control que existan\n    en tu lenguaje:\n    Condicionales, iterativas, excepciones...\n  3. Debes hacer print por consola del resultado de todos los ejemplos.\n \n  4. DIFICULTAD EXTRA (opcional):\n    - Crea un programa que imprima por consola todos los números comprendidos\n      entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n \n  Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n  \n## Operadores\n\nLos operadores son simbolos o palabras clave que le indican a R que realice\nuna operación en uno o más operandos.\n\nSegun [R coder](https://r-coder.com/operadores-r/) tenemos los siguientes tipos\nde operadores:\n\n  - De asignación\n  - Aritméticos\n  - Lógicos\n  - Relacionales\n  - Misceláneos\n  - infix\n  - pipe\n\n### De asignación\nPermiten asignar datos a un objeto para ser almacenados\n\n```{r operador_asignacion}\n# Asignación izquierda\na <- c(1,5, 46, 7,5, 6)\na\n# Asignación izquierda (no recomendado) y asignación de argumentos\nb = c(2, -6, 7, 5, 4, 1)\nb\n# Asignacion derecha\nc(1.5, 8, 45, 5, 6.97, 8.945) -> c\nc\n```\n\nExisten otros dos tipos de asignación más avanzados los cuales usan los \nsiguientes operadores:\n\n  - <<-\n  - ->>\n  \nSu uso es poco frecuente y su utilización segun [ChatGPT](https://chat.openai.com/)\nes el siguiente:\n\nEn R, el operador de asignación <<- se utiliza para asignar un valor a una \nvariable fuera del ámbito actual, es decir, en un entorno superior. Esto se \nconoce como asignación global o superasignación.\n\nCuando se usa el operador <<-, R busca la variable en el entorno actual. Si no\nencuentra la variable, se mueve al entorno superior y busca nuevamente.\nEste proceso continúa hasta que encuentra la variable o alcanza el entorno \nglobal.\n\nEs importante tener en cuenta que el uso excesivo de <<- y la asignación global\npueden hacer que el código sea menos legible y más propenso a errores. \nEn general, se recomienda evitar el uso excesivo de asignaciones globales y,\nen su lugar, utilizar funciones y argumentos para transmitir valores entre \ndiferentes partes del código. La asignación global puede ser útil en casos \nespecíficos, pero se debe utilizar con precaución para evitar problemas de \nmantenimiento y comprensión del código.\n\n\n### Aritméticos\n\nPermiten realizar operaciones matemáticas\n\n```{r operador_suma}\n# Suma\nprint(4.47 + 18.34)\n\n# Resta\nprint(0.59 -1.48)\n\n# Multiplicación\nprint(19.25 * 0.5)\n\n# División\nprint(19.25 / 2)\n\n# Exponencial\nprint(3 ^ 2)\n\n# Modulo\nprint(20 %% 3)\n\n# División entera\nprint(20 %/% 3)\n\n```\n\nTambien se pueden usar los operadores para hacer operaciones entre vectores,\nsiempre y cuando los vectores que se estan operando sean de las mismas \ndimensiones.\n\n```{r operando_vectores}\n# Suma de vectores\na + b\n\n# Resta de vectores\nc - b\n\n# Multiplación de vectores\na * c\n\n# Division de vectores\nc / b\n\n# Elevar cada elemento del primer vector elevado a la potencia correspondiente\n# de cada elemento del segundo vector\n\na ^ c\n```\n\nExisten más operadores y su uso es igual de práctico por ejemplo operadores\npara trabajar con matrices, aqui se deja un recurso util para seguir explorando\nmas funcionalidades [operaciones con matrices en R](https://r-coder.com/operaciones-matrices-r/#google_vignette)\n\n### Logicos y relacionales\n\nLos operadores logicos nos permiten dar un valor de verdad a una proposición,\npara entender su funcionamiento se debe entender lo básico de una tabla de \nverdad.\n\nPor otro lado, un operador relacional permite realizar comparaciones entre \nojetos su resultado es de tipo booleano\n\n```{r operadores_logicos}\n# AND elemento a elementoi\n5 > (4 + 1)\n\n# OR elemento a elemento\n(5 > (4 + 1)) | (5 == (4 + 1))\n\n# Negacion\n!(15000 > 1)\n\n# Distinto a\n4 != 5\n\n# Exactamente igual\n4 == 4.0001\n\n```\n\nTambien se pueden utilizar operadores de comparacion con vectores, llevandose \nla operación elemento a elemento\n\n### Misceláneos\n\nSon operadores utilizados para **propósitos específicos** como acceder a\ndatos, funciones, crear secuencias o especificar la fórmula de un modelo.\n\n|Operador | Descripción                                                  |\n|----------|-------------------------------------------------------------|\n|$|\tSubconjunto de un data frameo lista con nombres|\n|:|\tGenerador de secuencias|\n|::|\tAcceso a funciones de paquetes (No suele ser necesario utilizarlo)|\n|:::|\tAcceso a funciónes internas de paquetes|\n|~|\tFormulación de modelos|\n|@|\tAcceso a slots en clases S4 (Avanzado)|\n\n\n```{r}\n# Ejemplo obtenido de https://r-coder.com/operadores-r/#Operadores_miscelaneos\n\ndf <- data.frame(x = c(7, 9, 2), y = c(5, 9, 5))\n# Accedemos a la variable x\ndf$x\n\n# Secuencia de 1 a 5\n1:5\n\n# Función rnorm del paquete stats\nstats::rnorm(10)\n\n# Fórmula modelo lineal\nlm(df$x ~ df$y)\n```\n### Infix\n\nPuedes llamar a un operador como una función. Esto se conoce como operadores \ninfix. En el siguiente bloque de código mostramos algunos ejemplos. Ten en \ncuenta que el ejemplo de este tipo de operador es solo para fines educativos, \nya que generalmente no se usa ni se necesita.\n\n```{r operador_infix}\n# Ejemplo de https://r-coder.com/operadores-r/#Operadores_infix\n`+`(3, 2) # Equivalente a 3 + 2\n`*`(5, 9) # Equivalente a 5 * 9\n`>`(6, 1) # Equivalente a 6 > 1\n```\n\n### Pipe\nEl operador pipe o tubería es un operador que puedes encontrar en varias \nbibliotecas, como el paquete dplyr. El operador se puede leer como “Y LUEGO” \ny su propósito es simplificar la sintaxis al escribir código R. Como ejemplo,\npuedes crear un subconjunto de los datos cars y luego crear un resumen del \nsubconjunto con el siguiente código:\n\n```{r}\n# install.packages(\"dplyr\")\nlibrary(dplyr)\n\ncars %>% \n   subset(speed > 20) %>% \n   summary()\n```\n\n## Estructuras de control\n\nPermiten controlar la forma en la que es ejecutado nuestro código usando\noperadores condicionales.\n\n### if, else\n\n```{r}\na <- 4\nb <- 5\nif(a > b) {\n  print(\"a es mayor que b\")\n} else {\n  print(\"a es menor que b\")\n}\n\n```\n\n### for\n\n```{r}\nobjeto <- 1:10\nfor (elemento in objeto) {\n  print(elemento / 10)\n}\n```\n```{r}\nvector_01 <- NULL\n\nfor (i in 1:10){\n  vector_01[i] <- i/10\n}\n\nvector_01\n```\n\n### while\n\n```{r}\ni <- 0\nwhile(i < 10){\n  print(\"La variable i es menor a 10\")\n  print(i)\n  i <- i + 1\n}\n```\n\n### break y next\n\n```{r uso_break}\nfor(i in 1:20){\n  if (i %% 13 == 0){\n    break\n  }\n  print(i)\n}\n```\n\n```{r uso_next}\nfor(i in 1:4) {\n  if(i == 3) {\n    next\n  }\n  print(i)\n}\n```\n\n### repeat\n\n```{r uso_repeat}\nvalor <-  0\n\nrepeat{\n  valor <- valor + 1\n  if(valor == 5) {\n    break\n  }\n}\n\n# Resultado\nvalor\n```\n\n## Dificultad extra\n- Crea un programa que imprima por consola todos los números comprendidos\n      entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n      \n```{r dificultad_extra}\nfor(i in 10:55){\n  if(i %% 2 == 0){\n    if(i == 16 | i %% 3 == 0){\n      next\n    }else{\n      print(i)\n    }\n  }\n}\n```\n\n</div>"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/r/fidelysla.r",
    "content": "# * EJERCICIO:\n#  * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n#  *   Aritméticos, lógicos, de comparación, asignación, identidad,\n#  *   pertenencia, bits...\n#  *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n\n#  * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n#  *   que representen todos los tipos de estructuras de control que existan\n#  *   en tu lenguaje:\n#  *   Condicionales, iterativas, excepciones...\n#  * - Debes hacer print por consola del resultado de todos los ejemplos.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea un programa que imprima por consola todos los números comprendidos\n#  * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n#  *\n#  * Seguro que al revisar detenidamente las posibilidades has\n#  * descubierto algo nuevo.\n\n# ? TIPOS DE OPERADORES\n\n# **Operadores de asignación (<-) **\n\nx <- 2\n# 2 -> i\ns <- \"Hola\"\nv <- c(1:10)\nm <- matrix(c(1, 2, 3, 4), nrow = 2, ncol = 2)\nl <- list(a = 1, b = 2, c = 3)\nf <- factor(c(\"a\", \"b\", \"c\"))\ndf <- data.frame(a = 1, b = 2, c = 3)\nobj <- function(x) {\n    return(x + 1)\n}\nad <<- 12 # Asignación lexicográfica izquierda (avanzado)\n\n\n# **Operadores Aritmeticos**\n\nnum1 <- 3\n-num1 # -3\n\nnum1 + num1\nnum1 - num1\nnum1 * num1\nnum1 / num1\nnum1^num1\nnum1**num1\n\n12 %% 5 # Módulo\n5 %/% 3 # División entera\n\na <- matrix(c(1, -2, 3), nrow = 1)\nb <- matrix(c(4, 5, 6))\na %*% b # Multiplicación matricial\n\na <- c(1, 2, 3)\nb <- c(4, 5)\na %o% b # Producto Externo\n\nw <- matrix(c(1, 2, 3, 1), nrow = 2, byrow = TRUE)\nz <- matrix(c(0, 3, 2, 1), nrow = 2, byrow = TRUE)\nw %x% z # Producto Kronecker\na %x% b # Producto Kronecker\n\n# **Operadores de comparacion**\n\n3 > 5 # FALSE\n3 < 5 # TRUE\n3 >= 5 # FALSE\n3 <= 5 # TRUE\n3 == 5 # FALSE\n3 != 5 # TRUE\n\n1:10 > 5\n\nx <- c(12, 4, 14)\ny <- c(3, 4, 15)\n\nx >= y # TRUE TRUE FALSE\nx <= y # FALSE TRUE TRUE\nx == y # FALSE TRUE FALSE\nx != y # TRUE FALSE  TRUE\n\n\n# **Operadores Logicos**\n\n3 | 4 # TRUE\n40 & 5 > 30 # FALSE\n40 | 5 > 30 # TRUE\n!TRUE # FALSE\n!FALSE # TRUE\n!5 # FALSE\n\n# ** & y | **\n# Estos operadores son vectorizados y realizan operaciones\n# elemento por elemento en vectores lógicos. Devuelven un\n# vector lógico del mismo tamaño que los vectores de entrada.\n# Si tienes dos vectores lógicos a y b, a & b realizará la\n# operación AND elemento por elemento, y a | b realizará la\n# operación OR elemento por elemento.\n\n# ** && y || **\n# Estos operadores son escalares y evalúan solo el primer\n# elemento de cada vector lógico. Devuelven un único valor lógico.\n# a && b evaluará como TRUE solo si tanto el primer elemento\n# de a como el primer elemento de b son TRUE.\n# a || b evaluará como TRUE si al menos uno de los primeros\n# elementos de a o b es TRUE.\n\nx <- c(3, 4, 5)\ny <- c(3, 5, 1)\n\nx & y # TRUE TRUE TRUE\nx | y # TRUE TRUE TRUE\n\nx && y # TRUE\nx || y # TRUE\n\n!x # FALSE FALSE FALSE\nxor(x, y) # FALSE FALSE FALSE\n\n\n# **Operadores Miscelaneos**\n\n4 %in% c(1, 2, 3)\n\ndf <- data.frame(x = c(7, 9, 2), y = c(5, 9, 5))\n# Accedemos a la variable x ($)\ndf$x\n\n# Secuencia de 1 a 5 (:)\n1:5\n\n# Función rnorm del paquete stats (::)\nstats::rnorm(10)\n\n# Fórmula modelo lineal (~)\nlm(df$x ~ df$y)\n\n# %>% (Se utiliza para encadenar operaciones en un flujo más legible)\n# %<>% (Se utiliza para asignar y actualizar una variable en un solo paso),\n# ?mean (Se utiliza para obtener información de ayuda sobre un objeto o función)\n\n\n# ? Ejemplos de tipos de estructuras de control\n\n# ! **Condicionales**\n\n#* If-else\n\nis_string <- TRUE\nis_num <- FALSE\n\nif (is_string && is_num) {\n    print(\"Son tipos de datos verdaderos\")\n} else if (is_string || is_num) {\n    print(\"Por lo menos uno es tipo de dato verdadero\")\n}\n\nif (15 > 16) {\n    print(\"Consola 1\")\n} else if (15 < 16) {\n    print(\"Consola 2\")\n}\n\n#* Switch\nday <- as.POSIXlt(Sys.Date())$wday\nswitch(day,\n    \"1\" <- print(\"Hoy es Lunes\"),\n    \"2\" <- print(\"Hoy es Martes\"),\n    \"3\" <- print(\"Hoy es Miércoles\"),\n    \"4\" <- print(\"Hoy es Jueves\"),\n    \"5\" <- print(\"Hoy es Viernes\"),\n    \"6\" <- print(\"Hoy es Sábado\"),\n    \"7\" <- print(\"Hoy es Domingo\"),\n)\n\n# ! **Ciclos**\n\n#* For\n\nfor (i in c(0:10)) {\n    if (i %% 2 == 0) {\n        print(i)\n    }\n}\n\nabc <- c(\"a\" = 1, \"b\" = 2, \"c\" = 3)\nfor (key in names(abc)) {\n    value <- abc$key\n    r <- sprintf(\"%s: %d\", key, value)\n    cat(r, sep = \"\\n\")\n}\n\narr1 <- c(\"a\", \"b\", \"c\", \"d\", \"e\")\nfor (el in arr1) {\n    print(el)\n}\n\nfor (index in seq_along(arr1)) {\n    value <- arr1[[index]]\n    out <- sprintf(\"Index: %d, Value: %s\", index, value)\n    print(out)\n}\n\n\n#* While\n# Numeros entre 10 y 55 (incluidos), pares, y que no son ni\n# el 16 ni múltiplos de 3.\n\nnum3 <- 10\nwhile (num3 <= 55) {\n    if (num3 %% 3 == 0 || num3 == 16) {\n\n    } else {\n        print(num3)\n    }\n    num3 <- num3 + 2\n}\n\n# Otra forma de hacer lo mismo en r\nsequencia <- seq(from = 10, to = 55, by = 2)\nnumeros_deseados <- sequencia[!(sequencia %% 3 == 0 | sequencia == 16)]\n\n\n# **Manejo de Errores**\n\nx <- 5\ny <- 0\n\ntryCatch({\n    resultado <- x / y\n    cat(\"Resultado:\", resultado, \"\\n\")\n}, error = function(e) {\n    if (inherits(e, \"try-error\") && grepl(\n        \"non-numeric argument to binary operator\",\n        conditionMessage(e)\n    )) {\n        cat(\"Error: División por cero!\\n\")\n    } else {\n        # Manejo de otros errores que no sean división por cero\n        stop(e)\n    }\n}, finally = {\n    cat(\"Ejecutando la cláusula finalmente\\n\")\n})\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/r/julian-arias.r",
    "content": "#EJERCICIO 01 - OPERADORES Y ESTRUCTURAS DE CONTROL\n\n# 1. Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:  Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits... (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n\n# Operadores ariméticos\n\nprint(paste(\"Suma:\",10 + 5))\nprint(paste(\"Resta:\",10 - 5))\nprint(paste(\"Multiplicación:\",10 * 5))\nprint(paste(\"División:\",10 / 5))\nprint(paste(\"Modulo:\",10 %% 7))\nprint(paste(\"Exponente\", 10 ** 3))\nprint(paste(\"Raíz cuadrada:\", sqrt(25)))\nprint(paste(\"Raíz cubíca:\", raiz_nesima(2)))\nprint(paste(\"División entera\", 400 %/% 6))\n\nraiz_nesima <- function(x) {\n  return(x ^ (1/3))\n}\n\n# Operadores de comparación\n\nx <- 35\ny <- 88\n\nprint(paste(\"Igualdad, x == y es:\", x == y))\nprint(paste(\"Desigualdad, X != y es:\", x != y))\nprint(paste(\"Mayor que, X > y es:\", x > y))\nprint(paste(\"Mayor igual que, X >= y es:\", x >= y))\nprint(paste(\"Menor que, X < y es:\", x < y))\nprint(paste(\"Menor igual que , X <= y es:\", x <= y))\n\n# Operadores lógicos\n\nprint(paste(\"AND or && es:\", (x < y) && (y %% 2 ==0)))\nprint(paste(\"OR or | es:\", (x > y) | is.character(y)))\nprint(paste(\"NOT or ! es:\", !(x < y)))\n\n# Operador de asignación\n\nz <- \"Julián\"\nz\n\n# En R no existen operadores de asignación combinados como =+, =-, =*, =/, entre otros.\n\n# Operador de identidad\n\na <- 5\nb <- 5.0\n\na == b  # Se valida una igualdad, que son igual valor, devuelve True\n\nidentical(5,5.1)  # Se valida que es una identidad, en este caso No son identicos porque el primer elemento es 5 y el otro es 5.1. Devuelve False\n\n# Operadores de pertenencia\n\na1 <- 10    # Comparando un elemento de a1 contra los elementos de b1, devuelve TRUE\nb1 <- c(78,10)\n\nif (a1 %in% b1) {\n  print(\"a1 pertenece a b1\")\n} else {\n  print(\"a1 no pertenece a b1\")\n}\n\na2 <- c(10,8,23)  # Comparando todos los elementos de a2 con los de b2, devuleve FALSE\nb2 <- c(78,10)\n\nif (all(a2 %in% b2)) {\n  print(\"a2 pertenece a b2\")\n} else {\n  print(\"a2 no pertenece a b2\")\n}\n\n# 2. Utilizando las operaciones con operadores que tú quieras, crea ejemplos que representen todos los tipos de estructuras de control que existan en tu lenguaje:   Condicionales, iterativas, excepciones. Debes hacer print por consola del resultado de todos los ejemplos.\n\n# Estructuras de control\n\n# Condicionales\n\nedad3 <- 80\n\nif (edad3 < 18) {\n  print(paste(\"Es menor de edad y tiene\",edad3,\"años\"))\n} else if (edad3 >= 18 && edad3 <= 60){\n  print(paste(\"Es adulto y tiene\",edad3,\"años\"))\n} else {\n  print(paste(\"Es adulto mayor y tiene\",edad3,\"años\"))\n}\n\n# Iterativos\n\nfor (p in LETTERS) {\n  print(p)\n}\n\np <- 0\n\nwhile (p <= 10) {\n  print(p)\n  p <- p + 1\n}\n\n# Manejo de excepciones\n\nx2 <- 10/0\nx2\n\ntryCatch(\n  {\n    x2 <- 10 / 0\n    print(x2)\n  },\n  warning = function(w){\n    print(\"Ocurrió un error en la división\")\n    invokeRestart(\"muffleWarning\")\n  }\n)\n\n# DIFICULTAD EXTRA (opcional):\n# Crea un programa que imprima por consola todos los números comprendidos\n# entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\nfor (j in 10:55) {\n  if (j %% 2 == 0 & j != 16 & j %% 3 == 0) {\n    print(j) \n  }\n}\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/racket/luishendrix92.rkt",
    "content": "#lang racket\n\n; Operators\n; ---------\n; Racket's operators are functions that can be passed around (and returned).\n; On top of that, all functions are prefix, meaning we can't evaluate certain\n; expressions as most languages would do (infix).\n\n(printf \"5 + 3 = ~a.\\n\" (+ 5 3)) ; Addition operator\n(printf \"55 - 110 = ~a.\\n\" (- 55 110)) ; Subtraction operator\n(printf \"1 radian (180°/π) = ~a°.\\n\" (/ 180 pi)) ; Division operator\n(printf \"3.33 * 3 = ~a.\\n\" (* 3.33 3)) ; Multiplication operator\n(printf \"5 % 2 = ~a.\\n\" (remainder 5 2)) ; Modulus / remainder operator\n(printf \"2^8 = ~a.\\n\" (expt 2 8)) ; Exponentiation operator\n(printf \"| 5 - 30 | = ~a.\\n\" (abs (- 5 30))) ; Absolute value (unary)\n(printf \"sqrt(25) = ~a.\\n\" (sqrt 25)) ; Square root (unary)\n\n(printf \"Bitwise AND: 10 & 12 = ~a.\\n\" (bitwise-and #b1010 #b1100))\n(printf \"Bitwise OR 10 | 12 = ~a.\\n\" (bitwise-ior #b1010 #b1100))\n(printf \"Bitwise XOR 10 ^ 12 = ~a.\\n\" (bitwise-xor #b1010 #b1100))\n(printf \"Bitwise NOT ~~10 = ~a.\\n\" (bitwise-not #b1010))\n(printf \"Bitwise left shift 10 << 2 = ~a.\\n\" (arithmetic-shift #b1010 2))\n(printf \"Bitwise right shift 10 >> 2 = ~a.\\n\" (arithmetic-shift #b1010 -2))\n\n(define (fmt-bool x)\n  (if x \"YES\" \"NO\"))\n\n(printf \"Is 5 > 3 ? ~a.\\n\" (fmt-bool (> 5 3))) ; Logical GT\n(printf \"Is 31 >= 31 ? ~a.\\n\" (fmt-bool (>= 31 31))) ; Logical GTE\n(printf \"Is -2 < -5 ? ~a.\\n\" (fmt-bool (< -2 -5))) ; Logical LT\n(printf \"Is 0 <= -1 ? ~a.\\n\" (fmt-bool (<= 0 -1))) ; Logical LTE\n(printf \"Is 12 = 12 ? ~a.\\n\" (fmt-bool (= 12 12))) ; Logical EQ\n(printf \"Is 0.5 != 0.51 ? ~a.\\n\" (fmt-bool (not (= 0.5 0.51)))) ; Logical NOT\n\n(printf \"Logical AND: <false> && true && true = ~a.\\n\" (and false true true))\n(printf \"Logical OR: false || <true> || false = ~a.\\n\" (or false true false))\n\n; We could technically name functions with opeartor-like symbols.\n; For example, the bind operator, but only the implementation for\n; the list monad, which is equivalent to the `mapcat` function.\n(define (>>= m f)\n  (apply append (map f m)))\n\n(let ([tiers (list \"Bronze\" \"Silver\" \"Gold\" \"Platinum\" \"Diamond\")]\n      [levels (range 1 6)])\n  (>>= tiers (lambda (tier)\n               (map (curry format \"~a ~a\" tier)\n                    levels))))\n\n; Control Structures\n; ------------------\n\n; While loop emulation through recursion in a `letrec` block.\n(letrec ([loop (lambda (i)\n                 (when (< i 5)\n                   (begin\n                     (printf \"Mambo #~a!\\n\" (+ i 1))\n                     (loop (+ i 1)))))])\n  (loop 0))\n\n; For loop emulation through a `for` block.\n; NOTE: Instead of manually incrementing or decrementing a variable, the\n; values are dispensed from lists, that's why you see a call to `range`.\n(define verse-template\n  (curry format\n         \"~a little monkeys jumping on the bed\nOne fell off and bumped his head\nMama called the doctor and the doctor said\n\\\"No more monkeys jumping on the bed!\\\"\\n\"))\n\n(for ([i (reverse (range 2 6))]\n      #:when (odd? i)) ; guard clause\n  (displayln (verse-template i)))\n\n; The `for` block is mainly used for **side-effects** (IO operations) so the\n; expression doesn't evaluate to anything. If we want to have something\n; similar to a list comprehension (Haskell, Python, etc), we use `for/list`.\n; NOTE: `for` and `for/list` blocks can be nested.\n(define multiplication-table\n  (for/list ([i (in-range 1 11)])\n    (for/list ([j (in-range 1 11)])\n      (* i j))))\n\n(displayln multiplication-table)\n\n; There are also multiplicative versions of these blocks, namely:\n; 1. `for*`: Same as `for` but multiple bindings are combined as if we were\n;    nesting for loops in imperative languages.\n; 2. `for/list*`: Same as `for/list` but with multiplicative bindings.\n(for* ([i (in-range 5)]\n       [j (in-range 3)])\n  (printf \"Matrix coordinate m=5 n=3: (~a, ~a)\\n\" i j))\n\n; If/else (2 branches only, can be nested)\n(define age 31)\n\n(if (>= age 18)\n    (displayln \"I can drink, vote, and go clubbing.\")\n    (displayln \"I'm still underage.\"))\n\n; Cond block for multiple condition evaluations with a default case.\n; Source: https://docs.racket-lang.org/guide/syntax-overview.htm\n; Note: Switch-like behaviour can be achieved by using the `=` function.\n(define (reply-more s)\n  (cond\n    [(string-prefix? s \"hello \")\n     \"hi!\"]\n    [(string-prefix? s \"goodbye \")\n     \"bye!\"]\n    [(string-suffix? s \"?\")\n     \"I don't know\"]\n    [else \"huh?\"]))\n\n(reply-more \"what is your favorite color?\")\n\n; Switch case behaviour is implemented as `case`\n(define fav-color \"orange\")\n\n(case fav-color\n  [(\"black\") (displayln \"Such an emo person :(\")]\n  [(\"red\") (displayln \"I see... very vibrant :)\")]\n  [(\"orange\") (displayln \"Orange is the new black!\")]\n  [else (displayln \"I have no opinion on that color...\")])\n\n; Lastly, Racket offers powerful pattern-matching features through the `match`\n; block, but it's out of the scope of this exercise.\n; Refer to: https://docs.racket-lang.org/reference/match.html\n\n#| DIFICULTAD EXTRA (opcional):\n|| Crea un programa que imprima por consola todos los números comprendidos\n|| entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\\+=========================================================================|#\n\n(define (!= x y) (not (= x y)))\n\n(for ([n (in-range 10 56)]\n      #:when (!= n 16)\n      #:when (!= (remainder n 3) 0))\n  (printf \"Pair number not 16, nor evenly divisible by 3 -> ~a\\n\" n))\n\n#|\n  Output of running `racket luishendrix92.rkt`:\n  #############################################\n\n  5 + 3 = 8.\n  55 - 110 = -55.\n  1 radian (180°/π) = 57.29577951308232°.\n  3.33 * 3 = 9.99.\n  5 % 2 = 1.\n  2^8 = 256.\n  | 5 - 30 | = 25.\n  sqrt(25) = 5.\n  Bitwise AND: 10 & 12 = 8.\n  Bitwise OR 10 | 12 = 14.\n  Bitwise XOR 10 ^ 12 = 6.\n  Bitwise NOT ~10 = -11.\n  Bitwise left shift 10 << 2 = 40.\n  Bitwise right shift 10 >> 2 = 2.\n  Is 5 > 3 ? YES.\n  Is 31 >= 31 ? YES.\n  Is -2 < -5 ? NO.\n  Is 0 <= -1 ? NO.\n  Is 12 = 12 ? YES.\n  Is 0.5 != 0.51 ? YES.\n  Logical AND: <false> && true && true = #f.\n  Logical OR: false || <true> || false = #t.\n  '(\"Bronze 1\" \"Bronze 2\" \"Bronze 3\" \"Bronze 4\" \"Bronze 5\" \"Silver 1\" \"Silver 2\" \"Silver 3\" \"Silver 4\" \"Silver 5\" \"Gold 1\" \"Gold 2\" \"Gold 3\" \"Gold 4\" \"Gold 5\" \"Platinum 1\" \"Platinum 2\" \"Platinum 3\" \"Platinum 4\" \"Platinum 5\" \"Diamond 1\" \"Diamond 2\" \"Diamond 3\" \"Diamond 4\" \"Diamond 5\")\n  Mambo #1!\n  Mambo #2!\n  Mambo #3!\n  Mambo #4!\n  Mambo #5!\n  5 little monkeys jumping on the bed\n  One fell off and bumped his head\n  Mama called the doctor and the doctor said\n  \"No more monkeys jumping on the bed!\"\n\n  3 little monkeys jumping on the bed\n  One fell off and bumped his head\n  Mama called the doctor and the doctor said\n  \"No more monkeys jumping on the bed!\"\n\n  ((1 2 3 4 5 6 7 8 9 10) (2 4 6 8 10 12 14 16 18 20) (3 6 9 12 15 18 21 24 27 30) (4 8 12 16 20 24 28 32 36 40) (5 10 15 20 25 30 35 40 45 50) (6 12 18 24 30 36 42 48 54 60) (7 14 21 28 35 42 49 56 63 70) (8 16 24 32 40 48 56 64 72 80) (9 18 27 36 45 54 63 72 81 90) (10 20 30 40 50 60 70 80 90 100))\n  Matrix coordinate m=5 n=3: (0, 0)\n  Matrix coordinate m=5 n=3: (0, 1)\n  Matrix coordinate m=5 n=3: (0, 2)\n  Matrix coordinate m=5 n=3: (1, 0)\n  Matrix coordinate m=5 n=3: (1, 1)\n  Matrix coordinate m=5 n=3: (1, 2)\n  Matrix coordinate m=5 n=3: (2, 0)\n  Matrix coordinate m=5 n=3: (2, 1)\n  Matrix coordinate m=5 n=3: (2, 2)\n  Matrix coordinate m=5 n=3: (3, 0)\n  Matrix coordinate m=5 n=3: (3, 1)\n  Matrix coordinate m=5 n=3: (3, 2)\n  Matrix coordinate m=5 n=3: (4, 0)\n  Matrix coordinate m=5 n=3: (4, 1)\n  Matrix coordinate m=5 n=3: (4, 2)\n  I can drink, vote, and go clubbing.\n  \"I don't know\"\n  Orange is the new black!\n  Pair number not 16, nor evenly divisible by 3 -> 10\n  Pair number not 16, nor evenly divisible by 3 -> 11\n  Pair number not 16, nor evenly divisible by 3 -> 13\n  Pair number not 16, nor evenly divisible by 3 -> 14\n  Pair number not 16, nor evenly divisible by 3 -> 17\n  Pair number not 16, nor evenly divisible by 3 -> 19\n  Pair number not 16, nor evenly divisible by 3 -> 20\n  Pair number not 16, nor evenly divisible by 3 -> 22\n  Pair number not 16, nor evenly divisible by 3 -> 23\n  Pair number not 16, nor evenly divisible by 3 -> 25\n  Pair number not 16, nor evenly divisible by 3 -> 26\n  Pair number not 16, nor evenly divisible by 3 -> 28\n  Pair number not 16, nor evenly divisible by 3 -> 29\n  Pair number not 16, nor evenly divisible by 3 -> 31\n  Pair number not 16, nor evenly divisible by 3 -> 32\n  Pair number not 16, nor evenly divisible by 3 -> 34\n  Pair number not 16, nor evenly divisible by 3 -> 35\n  Pair number not 16, nor evenly divisible by 3 -> 37\n  Pair number not 16, nor evenly divisible by 3 -> 38\n  Pair number not 16, nor evenly divisible by 3 -> 40\n  Pair number not 16, nor evenly divisible by 3 -> 41\n  Pair number not 16, nor evenly divisible by 3 -> 43\n  Pair number not 16, nor evenly divisible by 3 -> 44\n  Pair number not 16, nor evenly divisible by 3 -> 46\n  Pair number not 16, nor evenly divisible by 3 -> 47\n  Pair number not 16, nor evenly divisible by 3 -> 49\n  Pair number not 16, nor evenly divisible by 3 -> 50\n  Pair number not 16, nor evenly divisible by 3 -> 52\n  Pair number not 16, nor evenly divisible by 3 -> 53\n  Pair number not 16, nor evenly divisible by 3 -> 55\n|#"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/raku/edalmava.raku",
    "content": "# Operador de asignación =\nmy ($name, $age) = 'Edalmava', 30;\n\nsay(\"Mi nombre es $name y tengo $age\");\n\n# Operador defined-o // para obtener un valor alternativo si una variable aún no está establecida\nmy $a = 'alpha';\nsay $a // 'gamma';    # Imprime alpha \n\nmy $b;\nsay $b // 'delta';    # Imprime delta\n\n# if - El código se ejecuta solo si se cumple una condición, por ej., una expresión se evalúa como True\n# Si la condición no se cumple, podemos especificar bloques alternativos de ejecución utilizando:\n# - else\n# - elsif\nmy $número-de-asientos = 9;\n\nif $número-de-asientos <= 5 {\n  say 'Soy un sedan'\n} elsif $número-de-asientos <= 7 {\n  say 'Tengo 6 o 7 asientos'\n} else {\n  say 'Soy un microbus'\n}\n\n#`(\n   unless - La negación de if es unless.\n   La negación en Raku se realiza con ! o con not.\n\n   unless (condición) se utiliza en lugar de if not (condición).\n\n   unless no puede utilizar la claúsula else.\n)\n\nmy $limpiar-zapatos = False;\n\nunless $limpiar-zapatos {\n  say 'Limpia tus zapatos'\n}\n\n# for - for itera sobre una serie de valores.\nmy @array = 1,2,3;\n\nfor @array -> $array-item {\n  say $array-item * 100\n}\n\n# Para iterar sobre rangos\n\nfor 1..5 -> $n {\n    say $n;\n}\n\n# Para cuerpo de bucle cortos se puede usar la forma posfija de for\n.say for 1..5;\n\n# given - En Raku given viene a ser switch en otros lenguajes\nmy $var = 42;\n\ngiven $var {\n    when 0..50 { say 'Menos o igual a 50' }\n    when Int { say \"es un Entero\" }\n    when 42  { say 42 }\n    default  { say \"¿ejem?\" }\n}\n\n# loop es otra forma de escribir un for.\n# Actualmente loop viene a ser el for utilizado en la familia de lenguajes de C.\nloop (my $i = 0; $i < 5; $i++) {\n  say \"El número actual es $i\"\n}\n\n# while - se repite mientras la condición sea verdadera\nmy $x = 0;\nwhile $x <= 10 {\n    $x = prompt 'Introduce un número, que no sea mayor que 10: ';\n    say \"Has introducido $x.\";\n}\nsay \"$x es mayor que 10.\";\n\n# until - se repite hasta que la condición se haga verdadera\n$x = 0;\nuntil $x > 10 {\n    $x = prompt 'Introduce un número que no sea mayor que 10: ';\n    say \"Has introducido $x.\";\n}\nsay \"$x es mayor que 10.\";\n\n# repeat - el bloque repeat siempre se ejecuta al menos una vez.\n$x = 100;\nrepeat {\n    $x = prompt 'Enter a number: ';\n    say \"You entered $x.\";\n} while $x <= 10;                    # Usando while para la condición\nsay \"$x is bigger than 10.\";\n\n$x = 0;\nrepeat {\n    $x = prompt 'Enter a number: ';\n    say \"You entered $x.\";\n} until $x > 10;                     # Usando until para la condición \nsay \"$x is bigger than 10.\";         \n\n#`(\n  RETO EXTRA\n)\n\nsay '';\nsay '**************';\nsay '*****RETO EXTRA*****';\nsay '**************';\nsay '';\n\nsay \"Usando for con rangos\";\n\nfor 10 .. 55 -> $i {\n    if $i %% 2 && $i != 16 && !($i %% 3)  {\n        say $i\n    }\n}\n\nsay \"Usando loop\";\n\nloop ($i = 10; $i <= 55; $i++) {\n    if $i %% 2 && $i != 16 && !($i %% 3)  {\n        say $i\n    }\n}\n\nsay \"Usando la forma posfija de for - en una sola línea\";\n.say if $_ %% 2 && $_ != 16 && !($_ %% 3) for 10 .. 55;\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/ruby/domo2pdev.rb",
    "content": "# EJERCICIO:\n# - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n# Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n# (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n# - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n# que representen todos los tipos de estructuras de control que existan en tu lenguaje:\n# Condicionales, iterativas, excepciones...\n# - Debes hacer print por consola del resultado de todos los ejemplos.\n#\n# DIFICULTAD EXTRA (opcional):\n# Crea un programa que imprima por consola todos los números comprendidos\n# entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n# Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\n# Aritmetic Operators:\n\n# Addition Operator (+)\nfirst_number = 15\nsecond_number = 5\n\naddition = first_number + second_number\nputs \"The result of the addition #{first_number} + #{second_number} is #{addition}\"\n\n# Subtraction Operator (-)\nsubtraction = first_number - second_number\nputs \"The result of the subtraction #{first_number} - #{second_number} is #{subtraction}\"\n\n# Multiplication Operator (*)\nmultiplication = first_number * second_number\nputs \"The result of the multiplication #{first_number} * #{second_number}2 is #{multiplication}\"\n\n# Division Operator (/)\ndivision = first_number / second_number\nputs \"The result of the division #{first_number} / #{second_number} is #{division}\"\n\n# Modulo Operator (%)\nmodulo = first_number % second_number\nputs \"The result of the modulo #{first_number} % #{second_number} is #{modulo}\"\n\n# Exponentiation Operator (**)\nexponentiation = first_number**second_number\nputs \"The result of the exponentiation #{first_number} ** #{second_number} is #{exponentiation}\"\n\n# Increment Operator (++)\nincrement = first_number + 1\nputs \"The result of the increment #{first_number} + 1 is #{increment}\"\n\n# Decrement Operator (--)\ndecrement = first_number - 1\nputs \"The result of the decrement #{first_number} - 1 is #{decrement}\"\n\n# Assignment Operators:\n\n# (=) assigns a value to a variable\nmy_shoes = 'a pair of shoes'\nmy_size = 42\nputs \"I have #{my_shoes} size #{my_size}\"\n\n# (+=) adds a value to a variable\nmy_size += 1\nputs \"I have #{my_shoes} size #{my_size}\"\n\n# (-=) subtracts a value from a variable\nmy_size -= 1\nputs \"I have #{my_shoes} size #{my_size}\"\n\n# (*=) multiplies a value to a variable\nmy_size *= 2\nputs \"I have #{my_shoes} size #{my_size}\"\n\n# (/=) divides a value to a variable\nmy_size /= 2\nputs \"I have #{my_shoes} size #{my_size}\"\n\n# (%=) divides a value to a variable\nmy_size %= 2\nputs \"I have #{my_shoes} size #{my_size}\"\n\n# (**=) exponentiates a value to a variable\nmy_size = 6\nmy_size **= 2\nputs \"I have #{my_shoes} size #{my_size}\"\n\n# Comparison Operators:\n\nname = 'Mateo'\nlast_name = 'Lombana'\n# Equal to (==)\nputs \"Is #{name} equal to #{last_name}? #{name == last_name}\" # false\n\n# Not equal to (!=)\nputs \"Is #{name} not equal to #{last_name}? #{name != last_name}\" # true\n\n# Equal to (===)\nputs \"Is #{name} equal to #{last_name}? #{name == last_name}\" # false\n\nyoung_age = 18\nadult_age = 21\nchild_age = 8\n\n# Greater than (>)\nputs \"Is #{young_age} greater than #{adult_age}? #{young_age > adult_age}\" # false\n\n# Less than (<)\nputs \"Is #{young_age} less than #{adult_age}? #{young_age < adult_age}\" # true\n\n# Greater than or equal to (>=)\nputs \"Is #{young_age} greater than or equal to #{adult_age}? #{young_age >= adult_age}\" # false\n\n# Less than or equal to (<=)\nputs \"Is #{young_age} less than or equal to #{adult_age}? #{young_age <= adult_age}\" # true\n\n# Combined comparison: Returns -1 if less, 0 if equal, 1 if greater\nputs young_age <=> adult_age\n\n# Logical Operators:\n\n# Logical AND (&&)\nputs \"is #{child_age} less than #{adult_age} and #{adult_age}\ngreater than #{young_age}? #{child_age < adult_age && adult_age > young_age}\" # true\n\n# Logical OR (||)\nputs \"is #{child_age} less than #{adult_age} or #{adult_age}\ngreater than #{young_age}? #{child_age < adult_age || adult_age > young_age}\" # true\n\n# Logical NOT (!)\nputs !(child_age < adult_age || adult_age > young_age)\n\n# Range Operators:\n\n# Range Operator (..) - The .. operator creates a range\n# that includes both the start and the end values.\nrange = 1..5\nputs range.to_a\n\n# Range Operator (...) - The ... operator creates\n# a range that includes the start value but excludes\n# the end value.\n\nrange = 1...5\nputs range.to_a\n\n# Regular Expression Operators:\n\n# Match Operator (=~):\n# The =~ operator is used to check if a string\n# matches a regular expression. It returns the\n# index of the first match or nil if there is no match\nputs 'Jhon' =~ /on/\n\n# Not Match Operator (!~):\n# The !~ operator is used to check if a string\n# does not match a regular expression. It returns\n# true if the string does not match the regular\n# expression and false if it does.\nputs 'Jhon' !~ /Mary/\n\n# Bitwise Operators:\n\n# Bitwise AND (&)\nbitwise_return = 5 & 3\nputs \"Bitwise AND (&) (5 & 3) = #{bitwise_return}\"\n\n# Bitwise OR (|)\nbitwise_return = 5 | 3\nputs \"Bitwise OR (|)  (5 | 3) = #{bitwise_return}\"\n\n# Bitwise XOR (^)\nbitwise_return = 5 ^ 3\nputs \"Bitwise XOR (^) (5 ^ 3) = #{bitwise_return}\"\n\n# Bitwise NOT (~)\nbitwise_return = ~5\nputs \"Bitwise NOT (~) (~5) = #{bitwise_return}\"\n\n# Bitwise Left Shift (<<)\nbitwise_return = 5 << 3\nputs \"Bitwise Left Shift (<<) (5 << 3) = #{bitwise_return}\"\n\n# Bitwise Right Shift (>>)\nbitwise_return = 5 >> 3\nputs \"Bitwise Right Shift (>>) (5 >> 3) = #{bitwise_return}\"\n\n# Unary Operators:\n\n# Unary Plus (+)\nputs '+5 = 5'\n\n# Unary Minus (-)\nputs '-5 = -5'\n\n# Membership Operators:\n\n# Membership Operator include?:\n# The include? operator is used to check if an object\n# is included in an array or a string. It returns true\n# if the object is included and false if it is not.\n\nputs %w[a b c].include?('b')\nputs 'jhon Doe'.include?('Doa')\n\n# Ternary Operator:\nage = 10\ncan_drive_vehicle = age >= 18 ? 'Yes' : 'No'\nputs \"the subject age is #{age}. Can drive vehicle? #{can_drive_vehicle}\"\n\n# Ternary Operator with multiple conditions:\nage = 17\ncan_drive_vehicle = if age >= 18\n                      'Yes'\n                    else\n                      (age >= 16 ? 'Maybe' : 'No')\n                    end\nputs \"the subject age is #{age}. Can drive vehicle? #{can_drive_vehicle}\"\n\n# Control statements:\n\n# if statement\n# Executes a block of code if a specified condition is true.\nage = 19\nis_male = true\nis_female = true\n\nputs 'You are an adult male' if age >= 18 && is_male == true\n\nage = 15\nputs 'You are a little girl' if age <= 18 && is_female == true\n\n# if else statement:\n# Executes one block of code if a condition\n# is true and another block if the condition is false.\n\nage = 15\nname = 'Mateo'\nconfirm_name = 'Mateo'\nlast_name = 'Lombana'\nconfirm_last_name = 'Lombana'\n\nif name == confirm_name && last_name == confirm_last_name # condition\n  puts \"Hello #{name} #{last_name}\"\nelse\n  puts \"You are not #{name} #{last_name}\"\nend\n\n# elsif statement:\n# Allows for multiple conditions to be checked in sequence.\n\nif name == confirm_name && last_name == confirm_last_name # condition 1\n  puts \"El usuario es: #{name} #{last_name}\"\nelsif age >= 18 # condition 2\n  puts \"La edad del usuario es: #{age}\"\nelse\n  puts 'Debes ser mayor de edad para ingresar'\nend\n\nif age == 18\n  then\n  puts 'You are an adult'\nend\n\n# Unless statement:\n# Executes a block of code if a specified condition is false.\n\nunless name == confirm_name && last_name == confirm_last_name\n  puts 'You are not the right user'\nend\n\nunless name != confirm_name && last_name != confirm_last_name\n  puts 'You are not the right user'\nelse\n  puts 'You are the right user'\nend\n\n# case statement:\n# Executes different blocks of code based on the value of a variable.\n\ncase age\nwhen 0..5\n  puts 'You are a baby'\nwhen 6..12\n  puts 'You are a child'\nwhen 13..17\n  puts 'You are a teenager'\nelse\n  puts 'You are an adult'\nend\n\n# Looping Statements\n\n# while loop:\n# Repeats a block of code as long as a specified condition is true.\n\nage = 0\nwhile age <= 18\n  puts 'You are a kid'\n  age += 1\nend\n\n# until loop:\n# Repeats a block of code as long as a specified condition is false.\n\nage = 0\nuntil age >= 18\n  puts 'You are another kid'\n  age += 1\nend\n\n# for loop:\n# Iterates over each element in a collection.\n\nfor square in 0..5\n  puts square * 2\nend\n\n# Each Method:\n# Iterates over each element in a collection using a block.\nnumbers = [5, 4, 3, 2, 1]\nnumbers.each do |sqaure|\n  puts sqaure * 2\nend\n\n# Times Method:\n# Executes a block of code a specified number of times\n5.times do |i|\n  puts \"Iteration #{i}\"\nend\n\n# Upto Method:\n# Iterate over a range of numbers from start to end\n\n6.upto(10) do |i|\n  puts \"Square is #{i * 2}\"\nend\n\n# Downto Method:\n# Iterates over a range of numbers from start to end in descending order\n10.downto(5) do |i|\n  puts \"Square is #{i * 2}\"\nend\n\n# Loop Method:\n# Executes a block of code indefinitely until a break statement is encountered.\ncount = 0\nloop do\n  puts \"Count is #{count}\"\n  count += 1\n  break if count >= 5\nend\n\n# Jump Statements:\n\n# Break Statements:\n# Exits a loop prematurely.\n\ncount = 0\nwhile true\n  puts \"Count is #{count}\"\n  count += 1\n  break if count <= 7\nend\n\n# Next Statements:\n# Skips the current iteration of a loop and moves to the next iteration.\nmy_array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\nmy_array.each do |element|\n  next if element.even?\n\n  puts \"odd element is #{element}\"\nend\n\n# Redo Statements:\n# Restarts the current iteration of a loop without checking the loop condition.\ncount = 0\nloop do\n  puts \"Count is #{count}\"\n  count += 1\n  redo if count < 5\n  break\nend\n\n# Retray Statements:\n# Restarts a begin-rescue block from the beginning.\nbegin\n  puts 'Trying to divide by zero'\n  1 / 0\nrescue ZeroDivisionError\n  puts 'Caught an exception, retrying...'\n  # retry\nend\n\n# Return Statements:\n# Exits a method and optionally returns a value.\ndef greet(name)\n  return \"Hello, #{name}!\"\nend\nputs greet('Alice')\n\n# Exception Handling:\n\n# Begin-rescue-ensure Statement\n# Handles exceptions and ensures that certain code is executed\n# regardless of whether an exception occurs.\n\nbegin\n  puts 'Dividing by zero'\n  1 / 0\nrescue ZeroDivisionError => e\n  puts \"Caught an exception: #{e.message}\"\nensure\n  puts 'This will always be executed.'\nend\n\n# Raise Statement\n# Raises an exception.\n\ndef check_age(age)\n  raise 'Age must be a positive number' if age <= 0\n\n  puts \"Age is #{age}\"\nend\n\nbegin\n  check_age(-1)\nrescue => e\n  puts \"Caught an exception: #{e.message}\"\nend\n\n# DIFICULTAD EXTRA:\n# Crea un programa que imprima por consola todos los números comprendidos\n# entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n# Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n\nrange = 10..55\nrange.each do |number|\n  if (number % 2).zero? && number != 16 && number % 3 != 0\n    puts number\n  end\nend\n\nfor number in range\n  if (number % 2).zero?\n    if number != 16 && number % 3 != 0\n      puts number\n    end\n  end\nend"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/ruby/edalmava.rb",
    "content": "# Operadores aritméticos, de comparación, a nivel de bits, lógicos\n\na, b, c, d, e = 10, 20, 30, 40, 5 # Asignación paralela\n\nputs \"***Operadores Aritméticos***\"\nputs \"Suma:  10 + 20 = #{ a + b }\"\nputs \"Resta: 40 - 20 = #{ d - b }\"\nputs \"Multiplicación: 10 * 20 = #{ a * b }\"\nputs \"División: 40 / 5  = #{ d / e }\"\nputs \"Módulo: 10 % 2  = #{ a % 2 }\"     # Módulo\nputs \"Exponente: 10 ** 5 = #{ a ** e }\" # Exponente\nputs \"\"\nputs \"Operador de Asignación =\"\nputs \"\"\nputs \"***Operadores de Comparación***\"\nputs \"Testear igualdad:  1 == 2 se evalua como #{ 1 == 2 } (falso)\"\nputs \"Testear desigualdad: 1 != 2 se evalua como #{ 1 != 2 } (verdadero)\"\nputs \"Mayor que: 10 > 9 se evalua como #{ 10 > 9 }\"\nputs \"Menor que: 10 < 9 se evalua como #{ 10 > 9 }\"\nputs \"Mayor o igual que: 10 >= 10 se evalua como #{ 10 >= 10 }\"\nputs \"Menor o igual que: 10 <= 10 se evalua como #{ 10 <= 10 }\"\nputs \"Operador de comparación combinada: 10 <=> 10 devuelve #{ 10 <=> 10 } lo que significa que los operandos son iguales\"\nputs \"10 <=> 9 devuelve #{ 10 <=> 9 } lo que significa que el primer operando es mayor que el segundo\"\nputs \"9 <=> 10 devuelve #{ 9 <=> 10 } lo que significa que el primer operando es menor que el segundo\"\nputs \"\"\nputs \"***Operadores a nivel de bits(bitwise)***\"\nputs \"Bitwise NOT: ~\"\nputs \"Bitwise OR:  |\"\nputs \"Bitwise AND: &\"\nputs \"Bitwise Exclusive OR: ^\"\nputs \"Bitwise Shift Left: <<\"\nputs \"Bitwise Shift Right: >>\"\nputs \"\"\nputs \"***Operadores Lógicos o booleanos***\"\nputs \"a = #{ a }, b = #{ b }, c = #{ c }, d = #{ d }\"\nputs \"Operador and(Y lógico): (a < b) and (c < d) se evalua como #{ (a < b) and (c < d) }\" # También se puede usar &&\nputs \"Operador or(O lógico): (a > b) or (c > d) se evalua como #{ (a > b) or (c > d) }\" # También se puede usar ||\nputs \"Operador NOT: !(a > b) se evalua como #{ !(a > b) }\"\n\nputs \"\"\nputs \"***Estructuras de Control***\"\nprint \"Sentencia if-elsif-else: \"\nif a < b then\n  print \"#{a} es menor que #{b}\"\nelse\n  print \"#{a} es mayor que #{b}\"\nend\nprint \"\\nOperador ternario: [condition] ? [true expression] : [false expression]\\n\"\nputs b > a ? \"#{b} es mayor que #{a}\" : \"#{a} es mayor que #{b}\"\nputs \"Sentencia case: \"\ncarro = \"Patriot\"\n\nfabricante = case carro\n   when \"Focus\" then \"Ford\"\n   when \"Navigator\" then \"Lincoln\"\n   when \"Camry\" then \"Toyota\"\n   when \"Civic\" then \"Honda\"\n   when \"Patriot\" then \"Jeep\"\n   when \"Jetta\" then \"VW\"\n   when \"Ceyene\" then \"Porsche\"\n   when \"Outback\" then \"Subaru\"\n   when \"520i\" then \"BMW\"\n   when \"Tundra\" then \"Nissan\"\n   else \"Unknown\"\nend\n\nputs \"El \" + carro  + \" es fabricado por \"  + fabricante\nputs \"\"\nputs \"Ciclo while\"\ni = 0\nwhile i < 5 do\n   puts i\n   i += 1\nend\nputs \"Ciclo until\"\ni = 0\nuntil i == 5\n   puts i\n   i += 1\nend\nputs \"Ciclo for\"\nfor i in 1..5 do\n  puts i\nend\n\nputs \"\"\nputs \"***RETO EXTRA***\"\nputs \"\"\nfor i in 10 .. 55\n  puts i if (i % 2 == 0) && (i != 16) && (i % 3 != 0)\nend\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/ruby/kodenook.rb",
    "content": "\nnum1 = 3\nnum2 = 4\n\n=begin\n    Arithmetics Operators\n=end\n\n# addition\nputs \"sum: #{num1 + num2}\"\n# subtraction\nputs \"subtraction: #{num1 - num2}\"\n# multiplication\nputs \"multiplication: #{num1 * num2}\"\n# division\nputs \"division: #{num1 / num2}\"\n# modulus\nputs \"modulus: #{num1 % num2}\"\n# exponentation\nputs \"exponentation: #{num1 ** num2}\"\n\n=begin\n    Assignment Operators\n=end\n\nputs num3 = 5 # assignment\nputs num3 +=  5 # addition\nputs num3 -= 6 # subtraction\nputs num3 *= 2 # multiplication\nputs num3 /= 3 # division\nputs num3 %= 3 # modulus\nputs num3 **= 2 # exponentation\n\n=begin\n    Comparison Operators\n=end\n\nputs num1 == num2 # equal\nputs num1 != num2 # not equal\nputs num1 > num2 # greater than\nputs num1 < num2 # less than\nputs num1 >= num2 # greater than or equal than\nputs num1 <= num2 # less than or equal than\nputs num1 <=> num2 # spaceship (return -1,0 or 1)\nputs num1 === num2 # Used to test equality within a when clause of a case statement\nputs num1.eql?(num2) # return true if are type equals and value equals\nputs num1.equal?num2 # return true if have the same object id\n\n=begin\n    Bitwise Operators\n=end\n\nputs 6 & 3 # compare each bit and set it to 1 if both are 1, otherwise it is set to 0\nputs 6 | 3 # compare each bit and set it to 1 if one or both are 1, otherwise it is set to 0\nputs 6 ^ 3 # compare each bit and set it to 1 if only one is 1, otherwise it is set to 0\nputs ~3 # inverts each bit, 0 becomes 1 and 1 becomes 0\nputs 3 << 2 # insert the specified numbers of 0's (in this case 2) from the right\nputs 8 >> 2 # insert the specified numbers of 0's (in this case 2) from the left\n\n=begin\n    Logical Operators\n=end\n\nputs num1 and num2 # true if both are true\nputs num1 or num2 # true if either are true\nputs num1 && num2 # true if both are true\nputs num1 || num2 # true if either are true\nputs !num1 # true if not true\nputs not(num1) # true if not true\n\n=begin\n    Conditional Assignment\n=end\n\nputs num1 ? 'true' : 'false' # ternary\nputs num1 || 'false' # null coalescing\n\n=begin\n    Range Operators\n=end\n\nputs (1..10).to_a # range from start point to end point inclusive\nputs (1...10).to_a # range from start point to end point exclusive\n\n=begin\n    If\n=end\n\nif num1 == num2\n    puts 'equal'\nelsif num2 < num1\n    puts 'less'\nelse\n    puts 'none'\nend\n\n=begin\n    Short hand if\n=end\n\nputs 'true' if 0 == 0\n\n=begin\n    nnless\n=end\n\nunless num1 != num2\n    puts 'equals'\nelse\n    puts 'not equals'\nend\n\n=begin\n    Short hand unless\n=end\n\nputs 'false' unless 0 != 0\n\n=begin\n    Case\n=end\n\nage =  5\ncase age\n    when 0 .. 2\n    puts 'baby'\n    when 3 .. 6\n    puts 'little child'\n    when 7 .. 12\n    puts 'child'\n    when 13 .. 18\n    puts 'youth'\n    else\n    puts 'adult'\nend\n\n=begin\n    Loop While\n=end\n\ni = 0\nnum = 5\n\nwhile i < num  do\n   puts \"Inside the loop i = #{i}\"\n   i += 1\nend\n\n=begin\n    Loop While Modifier\n=end\n\ni = 0\nnum = 5\nbegin\n   puts \"Inside the loop i = #{i}\"\n   i += 1\nend while i < num\n\n=begin\n    Loop Until\n=end\n\ni = 0\nnum = 5\n\nuntil i > num  do\n   puts \"Inside the loop i = #{i}\"\n   i += 1;\nend\n\n=begin\n    Loop Until Modifier\n=end\n\ni = 0\nnum = 5\nbegin\n   puts \"Inside the loop i = #{i}\"\n   i += 1;\nend until i > num\n\n=begin\n    Loop For\n=end\n\nfor i in 0..5\n   puts \"Value of variable is #{i}\"\nend\n\n(0..5).each do |i|\n   puts \"Value of variable is #{i}\"\nend\n\n=begin\n    Words For Loops\n=end\n\n# break | finish the loop\n# next | junp to next loop\n# redo | restart iteration\n# retry | restart from the begin\n\n=begin\n    Exceptions\n=end\n\n# begin\n#     if 1 == 1\n#         raise 'error'\n#     end\n# rescue\n#     puts 'there was a error'\n# end\n\n# begin\n#     if 1 == 1\n#         raise 'there was a error'\n#     end\n# rescue Exception => e\n#     puts e.message\n#     puts e.backtrace.inspect\n#     puts e.code\n# else\n#     puts 'executed when are not errors'\n# ensure\n#     puts 'always is executed'\n# end\n\n=begin\n    Exceptions\n=end\n\n(10..55).each do |i|\n    puts i if i % 2 == 0 and i != 16 and i % 3 != 0\nend\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/ruby/miguelex.rb",
    "content": "# Operadores de asignación\n\nx = 10    \nputs (\"El valor de x es: #{x}\")                  \nx += 5\nputs (\"El valor nuevo valor de x tras sumarle 5 es: #{x}\")                         \nx -= 5 \nputs (\"El valor nuevo valor de x tras restarle 5 es: #{x}\")                        \nx *= 5  \nputs (\"El valor nuevo valor de x tras multiplicarlo por 5 es: #{x}\")                       \nx /= 5 \nputs (\"El valor nuevo valor de x tras dividirlo por 5 es: #{x}\")                        \nx %= 5 \nputs (\"El valor nuevo valor de x tras hacerle el módulo 5 es: #{x}\")                        \nx **= 5   \nputs (\"El valor nuevo valor de x tras elevarlo a 5 es: #{x}\")                  \n\n# Operadores aritmeticos\na = 3\nb = 2\n\nputs (\"El valor de a es: #{a}\")   \nputs (\"El valor de b es: #{b}\")   \nputs (\"La suma de a + b es: #{a+b}\")\nputs (\"La resta de a - b es: #{a-b}\")\nputs (\"La multiplicación de a * b es: #{a*b}\")\nputs (\"La división de a / b es: #{a/b}\")\nputs (\"El módulo de a % b es: #{a%b}\")\nputs (\"El exponente de a ** b es: #{a**b}\")\nputs (\"La negación de -a es: #{-a}\")\n\n# Operadores de comparación\nputs (\"El valor de a es: #{a}\")\nputs (\"El valor de b es: #{b}\")\nputs (\"a es menor que b: #{a<b}\")\nputs (\"a es mayor que b: #{a>b}\")\nputs (\"a es menor o igual que b: #{a<=b}\")\nputs (\"a es mayor o igual que b: #{a>=b}\")\nputs (\"a es igual que b: #{a==b}\")\nputs (\"a es distinto que b: #{a!=b}\")\nputs (\"operacion combinada a <=> b: #{a<=>b}\")\nputs (\"igualdad de casos a === b: #{a===b}\")\n\n# Operadores lógicos\nputs (\"El valor de a es: #{a}\")\nputs (\"El valor de b es: #{b}\")\nputs (\"a && b: #{a&&b}\")\nputs (\"a || b: #{a||b}\")\nputs (\"!a: #{!a}\")\n\n# operadores bit a bit \nputs (\"El valor de a es: #{a}\")\nputs (\"El valor de b es: #{b}\")\nputs (\"a & b: #{a&b}\")\nputs (\"a | b: #{a|b}\")\nputs (\"a ^ b: #{a^b}\")\nputs (\"~a: #{~a}\")\nputs (\"a << b: #{a<<b}\")\nputs (\"a >> b: #{a>>b}\")\n\n# operador ternario\nputs (\"El valor de a es: #{a}\")\nputs (\"El valor de b es: #{b}\")\nputs (\"a > b ? a : b --> #{a>b ? a : b}\")\n\n# if\nputs (\"El valor de a es: #{a}\")\nputs (\"El valor de b es: #{b}\")\nif a>b\n    puts (\"a es mayor que b\")\nelse\n    puts (\"a es menor que b\")\nend\n\n# unless\nputs (\"El valor de a es: #{a}\")\nputs (\"El valor de b es: #{b}\")\nunless a>b\n    puts (\"a es menor que b\")\nelse\n    puts (\"a es mayor que b\")\nend\n\n# case\nputs (\"El valor de a es: #{a}\")\nputs (\"El valor de b es: #{b}\")\ncase a<=>b\nwhen -1\n    puts (\"a es menor que b\")\nwhen 0\n    puts (\"a es igual que b\")\nwhen 1\n    puts (\"a es mayor que b\")\nend\n\n# while\nputs (\"El valor de a es: #{a}\")\nputs (\"El valor de b es: #{b}\")\nwhile a<b\n    puts (\"a es menor que b\")\n    a+=1\nend\n\n# until\nputs (\"El valor de a es: #{a}\")\nputs (\"El valor de b es: #{b}\")\nuntil a>b\n    puts (\"a es menor que b\")\n    a+=1\nend\n\n# for\nputs (\"El valor de a es: #{a}\")\nputs (\"El valor de b es: #{b}\")\nfor i in a..b\n    puts (\"i es: #{i}\")\nend\n\n# each\nputs (\"El valor de a es: #{a}\")\nputs (\"El valor de b es: #{b}\")\n(a..b).each do |i|\n    puts (\"i es: #{i}\")\nend\n\n# times\nputs (\"El valor de a es: #{a}\")\nputs (\"El valor de b es: #{b}\")\na.times do |i|\n    puts (\"i es: #{i}\")\nend\n\n# break\nputs (\"El valor de a es: #{a}\")\nputs (\"El valor de b es: #{b}\")\nwhile a<b\n    puts (\"a es menor que b\")\n    a+=1\n    break if a==b\nend\n\n# next\nputs (\"El valor de a es: #{a}\")\nputs (\"El valor de b es: #{b}\")\nwhile a<b\n    puts (\"a es menor que b\")\n    a+=1\n    next if a==b\nend\n\n# try catch\nputs (\"El valor de a es: #{a}\")\nputs (\"El valor de b es: #{b}\")\nbegin\n    puts (\"a es menor que b\")\n    a+=1\n    raise if a==b\nrescue\n    puts (\"a es igual que b\")\nend\n\n# throw catch\nputs (\"El valor de a es: #{a}\")\nputs (\"El valor de b es: #{b}\")\ncatch (:exit) do\n    while a<b\n        puts (\"a es menor que b\")\n        a+=1\n        throw :exit if a==b\n    end\nend\n\n# Extra\n\nputs(\"A continuación vamos a mostrar el ejercicio extra\")\nfor i in 10..55\n    if (i % 2 == 0) && (i != 16) && (i % 3 != 0)\n        puts (\"#{i}\")\n    end\nend\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/ruby/zarakilancelot.rb",
    "content": "# Operadores aritméticos en Ruby\n# '+', '-', '*', '/', '%', '**'\n\nprimer_numero = 5.0   # Lo coloco como float para que de un resultado sobre cero en la división\nsegundo_numero = 10\n\n# SUMA +\nsuma = primer_numero + segundo_numero                   # 15.0\nputs \"El resultado de la suma es #{suma}\"\n\n# RESTA -\nresta = primer_numero - segundo_numero                  # -5.0\nputs \"El resultado de la resta es #{resta}\"\n\n# MULTIPLICACIÓN *\nmultiplicacion = primer_numero * segundo_numero         # 50.0\nputs \"El resultado de la multiplicacion es #{multiplicacion}\"\n\n# DIVISIÓN /\ndivision = primer_numero / segundo_numero               # 0.5\nputs \"El resultado de la division es #{division}\"\n\n# MÓDULO %\nmodulo = primer_numero % segundo_numero                 # 5.0\nputs \"El resultado de modulo es #{modulo}\"\n\n# EXPONENTE **\nexponencial = primer_numero ** segundo_numero           # 9765625.0\nputs \"El resultado del exponencial es #{exponencial}\"\n\n# ====================================================================================\n\n# Operadores lógicos (booleanos) en Ruby\n# '&&', '||', '!', 'and', 'or', 'not'\n# && (and): Devuelve true si ambos operandos son true.\n# || (or): Devuelve true si al menos uno de los operandos es true.\n# !  (not): Devuelve true si el operando es false.\n\n# AND\nputs true && false  # Devuelve false\n\n# OR\nputs true || false  # Devuelve true\n\n# NOT\nputs !true  # Devuelve false\n\n# Ejemplo con variables\nx = true\ny = false\n\n# AND\nputs x && y  # Devuelve false\n\n# OR\nputs x || y  # Devuelve true\n\n# NOT\nputs !x  # Devuelve false\nputs !y  # Devuelve true\n\n# AND y OR tienen la misma precedencia por lo que se evalúa de izquierda a derecha\n# && y || no tienen la misma precedencia, se evalúa primero &&\n\n# ====================================================================================\n\n# Operadores de comparación en Ruby\n# '<', '<=', '>', '>=', '<=>'\n\na = 5\nb = 7\nc = 5\n\nputs \"Es A menor a B? #{a < b}\"\nputs \"Es A mayor a B? #{a > b}\"\nputs \"Es A mayor o igual a C? #{a >= c}\"\nputs \"Es A diferente a C? #{a <=> c}\"\n\n# ====================================================================================\n\n# Operadores de igualdad en Ruby\n# '==', '!=', '=~', '!~', '==='\n\nputs \"Es A igual a c? #{a == c}\"\nputs \"Es A diferente a B? #{a != b}\"\n\n# =~ Se utiliza para verificar si una cadena coincide con una RegEx\ncadena = \"Hola mundo\"\nif cadena =~ /mundo/\n  puts \"Se encontró la palabra 'mundo'\"\nelse\n  puts \"No se encontró la palabra 'mundo'\"\nend\n\nputs \"Es A estrictamente igual a C? #{a === c}\"\n\n# ====================================================================================\n\n# Operador condicional en Ruby\n# '?'\n\nmensajes = 3\nputs \"Tienes #{mensajes} #{mensajes == 1 ? 'mensaje' : 'mensajes'}\"\n\n# ====================================================================================\n\n# Operador de asignación en Ruby\n# '='\n\ng = h = i = 0               # Le asigna 0 a las tres variables\nputs \"#{g} - #{h} - #{i}\"\n\ng = (h = (i = 0))           # Sucede lo mismo que arriba\nputs \"#{g} - #{h} - #{i}\"\n\n# ====================================================================================\n\n# Estructuras de control condicionales en Ruby\n\n# IF\nx = 6\n\n# Como bloque\nif x < 10\n  x += 1\nend\nputs x\n\n# Una línea con THEN como separador\nif x < 10 then x += 1 end\nputs x\n\n# Como bloque con THEN\nif x < 10 then\n  x += 1\nend\nputs x\n\n# If como modificador\nputs mensajes if mensajes\n\n# ELSE\ndata = []\n\nif data\n  data << x+1\nelse\n  data = [x+2]\nend\nputs data\n\n# ELSIF\nif x == 1\n  name = \"one\"\nelsif x == 2\n  name = \"two\"\nelsif x == 3 then name = \"three\"\nelsif x == 4; name = \"four\"\nelse\n  name = \"other\"\nend\nputs name\n\n# UNLESS\nunless x == 0\n  puts \"x no es cero (0)\"\nend\n\n# CASE\nname = case\n  when x == 1 then puts \"one\"\n  when x == 2 then puts \"two\"\n  when x == 3 then puts \"three\"\n  when x == 4 then puts \"four\"\n  else puts \"many\"\nend\n\n# ====================================================================================\n\n# Estructuras de control iterativas en Ruby\n\n# WHILE\nx = 10                    # Inicializamos una variable para el bucle\nwhile x >= 0 do           # Mientras x sea mas o igual a 0 se repetirá\n  puts x                  # Se imprimie el valor de x en esa iteración\n  x = x - 1               # Se resta 1 de x\nend                       # Se finaliza el bucle\n\n# UNTIL\nx = 0                     # Inicializamos una variable para el bucle\nuntil x > 10 do           # Se ejecutará hasta que x sea mayor a 10\n  puts x                  # Se imprime el valor de x en esa iteración\n  x = x + 1               # Se suma 1 a x\nend                       # Se finaliza el bucle\n\nx = 10                    # Inicializamos una variable para el bucle\nbegin                     # Se inicia el bucle\n  puts x                  # Se imprime el valor de x en esa iteración\n  x = x - 1               # Se resta 1 de x\nend until x == 0          # Se finaliza el bucle hasta que x sea igual a cero\n\n# FOR IN\nanimales = ['perro', 'gato', 'loro', 'pez']\nfor animal in animales do\n  puts animal\nend\n\nhash = {:a=>1, :b=>2, :c=>3}\nfor key,value in hash\n  puts \"#{key} => #{value}\"\nend\n\n# ITERADOR NUMÉRICO UPTO\n4.upto(8) {|n| print n}   # Imprime \"45678\"\nputs\n\n# ITERADOR NUMÉRICO TIMES\n3.times {|x| print x}     # Imprime \"012\"\nputs\n\n# EACH\n[10, 20, 30].each {|x| print x}   # Imprime \"102030\"\nputs\n(1..3).each {|x| print x}         # Imprime \"123\"\nputs\n\n# COLLECT\ncuadrados = [1, 2, 3].collect {|x| print x*x}\nputs\n\n# SELECT\npares = (1..10).select {|x| print x if x%2 == 0}   # Imprime [2,4,6,8,10]\nputs\n\n# REJECT\nimpares = (1..10).reject {|x| print x if x%2 != 0}   # Imprime [1,3,5,7,9]\nputs\n\n# EXCEPCIONES\nn = 0\nraise ArgumentError, \"Expected argument >= 1. Got #{n}\" if n < 1\n\nn = \"s\"\nraise TypeError, \"Integer argument expected\" if not n.is_a? Integer\n\ndef factorial(n)\n  raise \"bad argument\" if n < 1\n  return 1 if n == 1\n  n * factorial(n-1)\nend\n\nbegin\n  x = factorial(-1)\nrescue => ex\n  puts \"#{ex.class}: #{ex.message}\"\nend\n\n# ====================================================================================\n\n# EXTRA\nextra = (10..55).select {|x| x%2 == 0 and x != 16 and x%3 != 0}\nprint extra\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/rust/Coshiloco.rs",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n\n fn main() {\n    // Operadores Aritméticos\n    let suma = 5 + 3; // 8\n    let resta = 5 - 3; // 2\n    let multiplicacion = 5 * 3; // 15\n    let division = 5 / 3; // 1\n    let modulo = 5 % 3; // 2\n\n    // Operadores Lógicos\n    let verdadero = true;\n    let falso = false;\n\n    // Operadores de Comparación\n    let igual = 5 == 3; // false\n    let no_igual = 5 != 3; // true\n    let mayor_que = 5 > 3; // true\n    let menor_que = 5 < 3; // false\n    let mayor_o_igual = 5 >= 3; // true\n    let menor_o_igual = 5 <= 3; // false\n\n    // Operadores de Asignación\n    let mut valor = 5;\n    valor += 2; // 7\n    valor -= 1; // 6\n    valor *= 2; // 12\n    valor /= 3; // 4\n    valor %= 2; // 0\n\n    // Operadores de Bit\n    let bit_and = 5 & 3; // 1\n    let bit_or = 5 | 3; // 7\n    let bit_xor = 5 ^ 3; // 6\n    let desplazamiento_izquierda = 1 << 2; // 4\n    let desplazamiento_derecha = 8 >> 1; // 4\n\n    // Estructuras de Control\n    // Condicionales\n    if suma > 5 {\n        println!(\"Suma es mayor que 5\");\n    } else if suma < 5 {\n        println!(\"Suma es menor que 5\");\n    } else {\n        println!(\"Suma es 5\");\n    }\n\n    // Iterativas: loop, while, for\n    let mut contador = 0;\n    loop {\n        if contador >= 3 { break; }\n        contador += 1;\n    }\n\n    while contador > 0 {\n        contador -= 1;\n    }\n\n    for i in 0..3 {\n        println!(\"Valor de i: {}\", i);\n    }\n\n    // Manejo de Errores\n    let resultado: Result<i32, &str> = Ok(10);\n    match resultado {\n        Ok(valor) => println!(\"Resultado exitoso: {}\", valor),\n        Err(e) => println!(\"Error: {}\", e),\n    }\n\n    let opcion: Option<i32> = Some(5);\n    match opcion {\n        Some(valor) => println!(\"Tenemos un valor: {}\", valor),\n        None => println!(\"No hay valor\"),\n    }\n    \n    /* Crea un programa que imprima por consola todos los números comprendidos\n     entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3. */\n    \n    ejercicioExtra();\n    \n}\n\nfn ejercicioExtra() {\n    /* Crea un programa que imprima por consola todos los números comprendidos\n     entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3. */\n    for i in 10..56 {\n        if i % 2 == 0 && i != 16 && i % 3 != 0 {\n            println!(\"{}\", i);\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/rust/angelsanchezt.rs",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n*/\n\nfn main() {\n    // Operadores aritméticos\n    let a = 10;\n    let b = 5;\n    println!(\"Suma: {}\", a + b);\n    println!(\"Resta: {}\", a - b);\n    println!(\"Multiplicación: {}\", a * b);\n    println!(\"División: {}\", a / b);\n    println!(\"Módulo: {}\", a % b);\n\n    // Operadores lógicos\n    let x = true;\n    let y = false;\n    println!(\"AND lógico: {}\", x && y);\n    println!(\"OR lógico: {}\", x || y);\n    println!(\"NOT lógico: {}\", !x);\n\n    // Operadores de comparación\n    let c = 15;\n    let d = 20;\n    println!(\"Igualdad: {}\", c == d);\n    println!(\"Desigualdad: {}\", c != d);\n    println!(\"Mayor que: {}\", c > d);\n    println!(\"Menor que: {}\", c < d);\n\n    // Operadores de asignación\n    let mut e = 25;\n    e += 5;\n    println!(\"Operador de asignación: {}\", e);\n\n    // Operadores de identidad\n    let f = \"Hola\";\n    let g = \"Hola\";\n    let h = \"Mundo\";\n    println!(\"Igualdad de referencias: {}\", f == g);\n    println!(\"Desigualdad de referencias: {}\", f != h);\n\n    // Operadores de pertenencia\n    let nums = vec![1, 2, 3, 4, 5];\n    let num_to_check = 3;\n    println!(\"Pertenencia: {}\", nums.contains(&num_to_check));\n\n    // Operadores de bits\n    let i = 0b1100; // Representación binaria de 12\n    let j = 0b1010; // Representación binaria de 10\n    println!(\"AND a nivel de bits: {:b}\", i & j);\n    println!(\"OR a nivel de bits: {:b}\", i | j);\n    println!(\"XOR a nivel de bits: {:b}\", i ^ j);\n    println!(\"Desplazamiento a la derecha: {:b}\", i >> 1);\n    println!(\"Desplazamiento a la izquierda: {:b}\", i << 1);\n\n    // Estructuras de control condicionales\n    let number = 42;\n    if number > 30 {\n        println!(\"El número es mayor que 30\");\n    } else {\n        println!(\"El número es menor o igual a 30\");\n    }\n\n    // Estructuras de control iterativas\n    for num in 10..=55 {\n        if num % 2 == 0 && num != 16 && num % 3 != 0 {\n            println!(\"{}\", num);\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/rust/atienzar.rs",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\nuse std::num::ParseIntError;\n\n fn main() {\n    \n    // asignar\n    let x:i32 = 2;\n    let y:i32 = 12;\n    let mut z:i32;\n\n    // aritmeticos.\n    z = x + y;\n    println!(\"Suma: {}\", z);\n    z = y - x;\n    println!(\"Resta: {}\", z);\n\n    z = y / x;\n    println!(\"Division: {}\", z);\n\n    z = y % x;\n    println!(\"Modulo: {}\", z);\n\n    z += 2;\n    println!(\"Incrementamos: {}\", z);\n    z -= 1;\n    println!(\"Decrementamos: {}\", z);\n\n\n    //comparacion\n\n    println!(\"{} Mayor(>) {} = {}\",x,y, x > y);\n    println!(\"{} Menor(<) {} = {}\",x,y, x < y);\n    println!(\"{} Igual(=) {} = {}\",x,y, x == y);\n    println!(\"{} Distinto(!=) {} = {}\",x,y, x != y);\n    println!(\"{} >= {} = {}\",x,y, x >= y);\n    println!(\"{} <= {} = {}\",x,y, x <= y);\n\n    //logicos\n\n    let a = true;\n    let b = false;\n\n    if a && b{\n        println!(\"Operador &&, las 2 verdaderas\");\n    }else{\n        println!(\"Operador &&, 1 o las dos condiciones son falsas\");\n    }\n\n    if a || b{        \n        println!(\"Operador ||, 1 o las dos condiciones son verdaderas\");\n    }else{\n        println!(\"Operador || las 2 son falsas\");\n    }\n\n    if !a{\n        println!(\"a es falsa\");\n    }else{\n        println!(\"a es verdadera\");\n    }\n\n\n    // operadores binarios\n\n    let a: u8 = 0b1010;\n    let b: u8 = 0b1100;\n\n    let result_and = a & b;  // AND binario\n    let result_or = a | b;   // OR binario\n    let result_xor = a ^ b;  // XOR binario\n    let result_shift_left = a << 2;   // Desplazamiento a la izquierda\n    let result_shift_right = a >> 3;  // Desplazamiento a la derecha\n    let result_not = !a;     // NOT binario\n\n    println!(\"AND: {:b}\", result_and);\n    println!(\"OR: {:b}\", result_or);\n    println!(\"XOR: {:b}\", result_xor);\n    println!(\"Desplazamiento a la izquierda: {:b}\", result_shift_left);\n    println!(\"Desplazamiento a la derecha: {:b}\", result_shift_right);\n    println!(\"NOT: {:b}\", result_not);\n\n\n    // distintos tipos de base => binario, decimal, octal y  hexa\n\n    let letra = 'A';\n    let valor_numerico = letra as u8;\n\n    println!(\"Carácter original: {}\", letra);\n    println!(\"Valor decimal: {}\", valor_numerico);\n    println!(\"Valor hexadecimal: {:X}\", valor_numerico);\n    println!(\"Valor octal: {:o}\", valor_numerico);\n    println!(\"Valor binario: {:b}\", valor_numerico);\n\n\n    // estructuras de control \n\n    let a:bool = true;\n\n    if  a {\n        println!(\"{} es Verdadero\",a)\n    }else if !a {\n        println!(\"{} es Falso\",a)\n    }else{\n        println!(\"Entramos  en el else\")\n    }\n\n    let mut cont:i32 = 5; \n\n    while cont > 0{\n        println!(\"Estamos dentro del While! \");\n        cont -= 1;\n    }\n    \n    cont = 0;\n    loop {\n        cont += 1;\n        if cont == 5 {\n           break;\n        }\n        println!(\"Paso {} dentro del loop\",cont )\n    }\n\n    for n in 1..5{\n        println!(\"Paso {} dentro del for\", n);\n    }\n\n    let mut listado = vec![\"juan\", \"pedro\", \"luis\"];\n    for name in listado.iter_mut(){\n        println!(\"{:?}\",name);\n    }\n\n    let num:i16 = 4;\n\n    match num {\n        1 | 2 | 3 => println!(\"Menor que cuantro\"),\n        4 => println!(\"Cuatro!\"),\n        5..=10 => println!(\"Mayor que cuatro\"), \n        _=> println!(\"Otra cosa\")\n    }\n\n    // Excepciones  => panic y Result\n    let number_str = \"10*\";\n    let number = match number_str.parse::<i32>() {\n        Ok(number)  => number,\n        //Err(_e) => panic!(\"Problemas creando el entero: {:?}\", _e),\n        Err(e) => -1,\n    };\n    println!(\"{}\", number);\n\n    print_numbers();\n\n}\n\n/*\n Crea un programa que imprima por consola todos los números comprendidos\n* entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n*/\n\nfn print_numbers(){\n    for num in 10..=55{\n        if num % 2 == 0  && num != 16 && num % 3 != 0  {\n            println!(\"{}\", num);\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/rust/brockar.rs",
    "content": "/*\nOperators\n*/\n\nfn main(){\n    println!(\"Aritmetic operators\");\n// Aritmetic operators\n    println!(\"Suma: {}\",1+20);\n    println!(\"Resta: {}\",1-20);\n    println!(\"Multiplicación: {}\",2*20);\n    println!(\"División (flotante): {}\",10.0/3.0);\n    println!(\"Division entera: {}\", 10/3);\n    println!(\"Módulo: {}\",10%3);\n    println!(\"Potencia: {}\",1_i32.pow(10));\n    println!(\"Raíz cuadrada: {}\",4.0_f64.sqrt());\n\n    println!(\"\\nLogical operators\");\n// Logical operators\n    println!(\"AND: {}\",true && false);\n    println!(\"OR: {}\",true || false);\n    println!(\"NOT: {}\",!true);\n\n    println!(\"\\nRelational operators\");\n// Relational operators\n    println!(\"Equality: {}\",1==1);\n    println!(\"Nonequality comparison: {}\",1!=1);\n    println!(\"Greater than comparison: {}\",1>2);\n    println!(\"Less than comparison: {}\",1<2);\n\n    println!(\"\\nBitwise operators\");\n// Bitwise operators\n    println!(\"AND: {}\",0b1010 & 0b1100);\n    println!(\"OR: {}\",0b1010 | 0b1100);\n    println!(\"XOR: {}\",0b1010 ^ 0b1100);\n    println!(\"Left-shift: {}\",0b1010 << 2);\n    println!(\"Right-shift: {}\",0b1010 >> 2);\n    println!(\"Complement: {}\",!0b1010);\n\n    println!(\"\\nAssignment operators\");\n// Assignment operators\n    let mut a = 10;\n    a += 10;\n    println!(\"Addition assignment: {}\",a);\n    a -= 10;\n    println!(\"Subtraction assignment: {}\",a);\n    a *= 10;\n    println!(\"Multiplication assignment: {}\",a);\n    a /= 10;\n    println!(\"Division assignment: {}\",a);\n    a %= 10;\n    println!(\"Modulo assignment: {}\",a);\n    a &= 10;\n    println!(\"AND assignment: {}\",a);\n    a |= 10;\n    println!(\"OR assignment: {}\",a);\n    \n    println!(\"\\nTeranary operator\");\n// Ternary operator\n    let a = 10;\n    let b = 20;\n    let c = if a > b {a} else {b};\n    println!(\"Ternary operator: {}\",c);\n\n    println!(\"\\nMembership operator\");\n// Membership operator\n    let nums = vec![1, 2, 3, 4, 5];\n    let num_to_check = 3;\n    println!(\"Member?: {}\", nums.contains(&num_to_check));\n\n    println!(\"\\nControl structures\");\n// Control structures\n\n    println!(\"\\nIf else\");\n    // if else\n    let number = 42;\n    if number > 30 {\n        println!(\"The number is greater than 30\");\n    } else {\n        println!(\"The number is less than or equal to 30\");\n    }\n\n    println!(\"\\nfor in\");\n    // for in\n//  for num in 10..55  10 to 54\n    for num in 10..=55 { // 10 to 55 inclusive\n        if num % 2 == 0 && num != 16 && num % 3 != 0 {\n            println!(\"{}\", num);\n        }\n    }\n\n    println!(\"\\nLoop\");\n    // Infinite loop\n    let mut count = 0u32;\n    loop {\n        count += 1;\n        if count == 3 {\n            println!(\"three\");\n            // Skip the rest of this iteration\n            continue;\n        }\n\n        println!(\"{}\", count);\n\n        if count == 5 {\n            println!(\"OK, that's enough\");\n            // Exit this loop\n            break;\n        }\n    }\n\n    println!(\"\\nWhile\");\n    // while loop\n    let mut n = 1;\n    while n < 20 {\n        if n % 15 == 0 {\n            println!(\"fizzbuzz\");\n        } else if n % 3 == 0 {\n            println!(\"fizz\");\n        } else if n % 5 == 0 {\n            println!(\"buzz\");\n        } else {\n            println!(\"{}\", n);\n        }\n        // Increment counter\n        n += 1;\n    }\n\n    println!(\"\\nMatch(Switch)\");\n    // match (Switch case in other languages)\n    let number = 11;\n    println!(\"Tell me about {}\", number);\n    match number {\n        // Match a single value\n        1 => println!(\"One!\"),\n        // Match several values\n        2 | 3 | 5 | 7 | 11 => println!(\"This is a prime\"),\n        // Match an inclusive range\n        13..=19 => println!(\"A teen\"),\n        // Handle the rest of cases\n        _ => println!(\"Ain't special\"),\n    }\n\n    println!(\"\\n\");\n    extra();\n\n}\n\nfn extra(){\n    println!(\"Extra\");\n    for num in 10..=55 {\n        if num % 2 == 0 && num != 16 && num % 3 != 0 {\n            println!(\"{}\", num);\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/rust/didacdev.rs",
    "content": "// https://doc.rust-lang.org/book/appendix-02-operators.html\n// https://doc.rust-lang.org/book/ch03-05-control-flow.html\n\n\nfn print_numbers() {\n\n    for number in 10..=55{\n\n        if number % 2 == 0 {\n            if !(number != 16 && number % 3 == 0) {\n                println!(\"{}\", number);\n            }\n        }\n    }\n}\n\nfn main() {\n\n    // Igualdad\n    // println!(\"{}\", 1 == 1);\n    // println!(\"{}\", 1 != 1);\n    // println!(\"{}\", 1 > 1);\n    // println!(\"{}\", 1 < 1);\n    // println!(\"{}\", 1 <= 1);\n    // println!(\"{}\", 1 >= 1);\n\n    // Aritméticos\n    // println!(\"{}\", 2 % 2);\n    // println!(\"{}\", 2 * 2);\n    // println!(\"{}\", 2 + 2);\n    // println!(\"{}\", 2 - 2);\n    // println!(\"{}\", 2 / 2);\n\n    // Lógicos\n    // println!(\"{}\", true && false);\n    // println!(\"{}\", true || false);\n\n    // Condicional\n    /*if 5 > 0 {\n        println!(\"5 es mayor que 0\");\n    } else if 5 == 0{\n        println!(\"5 es igual que 0\");\n    } else {\n        println!(\"5 es menor que 0\");\n    }*/\n\n    // let _number = if true { 5 } else { 0 };\n\n    /*match _number {\n        1 => println!(\"{}\", 1),\n        5 => println!(\"{}\", 5),\n        _ => println!(\"Resto\"),\n    }*/\n\n    // loops\n    // let mut number = 0;\n    /*loop {\n        println!(\"Hello Rust!\");\n        number += 1;\n\n        if number == 2 {\n            break;\n        }\n    }*/\n\n    /*'first_loop: loop {\n        let mut loops = 0;\n\n        'second_loop: loop {\n            loops += 1;\n            println!(\"2\");\n\n            if loops == 2 {\n                break 'second_loop;\n            }\n        }\n\n        break 'first_loop;\n    }*/\n\n    /*while number != 0 {\n        println!(\"{}\", number);\n        number -= 1;\n    }*/\n\n    // let a = [1, 2, 3, 4];\n    /*for number in a {\n        println!(\"{number}\");\n    }*/\n\n    /*for number in 1..4{\n        println!(\"{number}\")\n    }*/\n\n    /*for number in (1..4).rev(){\n        println!(\"{number}\")\n    }*/\n\n    print_numbers();\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/rust/gabrielmoris.rs",
    "content": "// https://doc.rust-lang.org/rust-by-example/\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\nfn main() {\n    // \"Arithmetic\";\n    let _addition = 5 + 3;\n    let _substraction = 10 - 4;\n    let _multiplication = 7 * 2;\n    let _division = 15 / 3;\n    let _module = 17 % 5;\n\n    // \"Logic\";\n    let _and = true && true;\n    let _or = true || false;\n    let _not = !false;\n\n    // \"Comparison\";\n    let _greather = 2 > 1;\n    let _less = 1 < 2;\n    let _greather_or_equal = 3 >= 2;\n    let _les_or_equal = 2 <= 3;\n    let _equal = 1 == 1;\n    let _not_equal = 1 != 2;\n\n    // \"Identity\"\n    let mut x = 1;\n    let _copy = x;\n    let _shared_borrow = &x;\n    let _mutable_borrow = &mut x;\n\n    // \"Bitwise\"\n\n    let _bit_and = 0b1010 & 0b1100;\n    let _bit_or = 0b1010 | 0b1100;\n    let _bit_xor = 0b1010 ^ 0b1100;\n    let _bit_not = !0b1010;\n    let _left_shift = 0b1010 << 2;\n    let _right_shift = 0b1010 >> 1;\n\n    // Dependency operators\n    // let x: i32 = \"123\".parse()?;\n    // It propagates errors by returning the error from the current function early.\n    // It can only be used in functions that return a Result or Option type..\n\n    flow_controls();\n}\n\nfn flow_controls() {\n    print!(\"Conditionals\\n\");\n    if 10 < 1 {\n        return;\n    } else if 11 == 10 {\n        return;\n    } else {\n        print!(\"Hello If\\n\");\n    }\n\n    print!(\"Loops\\n\");\n\n    let mut index = 10;\n\n    loop {\n        if index % 2 == 0 && index % 3 != 0 && index != 16 {\n            print!(\"{},\", index);\n        }\n        index += 1;\n        if index > 55 {\n            break;\n        }\n    }\n\n    print!(\"\\nWhile\\n\");\n    index = 10;\n\n    while index <= 55 {\n        if index % 2 == 0 && index % 3 != 0 && index != 16 {\n            print!(\"{},\", index);\n        }\n        index += 1;\n    }\n\n    print!(\"\\nFor and Range\\n\");\n\n    for n in 10..=55 {\n        if n % 2 == 0 && n % 3 != 0 && n != 16 {\n            print!(\"{},\", n);\n        }\n    }\n\n    print!(\"\\nMatch\\n\");\n\n    let number = 13;\n\n    match number {\n        1 => println!(\"One!\"),\n        2 | 3 | 5 | 7 | 11 => println!(\"This is a prime\"),\n        13..=19 => println!(\"A teen\"),\n        _ => println!(\"Ain't special\"),\n    }\n\n    print!(\"\\nif let\\n\");\n    // For some use cases, when matching enums, match is awkward.\n    // All have type `Option<i32>`\n    let number = Some(7);\n\n    // The `if let` construct reads: \"if `let` destructures `number` into\n    // `Some(i)`, evaluate the block (`{}`).\n    if let Some(i) = number {\n        println!(\"Matched {:?}!\", i);\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/rust/javiearth.rs",
    "content": "//=========================================\n// 01 - OPERADORES Y ESTRUCTURAS DE CONTROL\n//=========================================\n\nfn main(){\n    \n    println!(\"EJEMPLO DE TODOS LOS TIPOS DE OPERADORES\");\n    \n    let mut a: u8 = 2;\n    let b: u8 = 4;\n    let c: u8 = 8;\n    \n    // Aritmeticos:\n    println!(\"{} + {} = {}\", a, b, a + b);\n    println!(\"{} - {} = {}\", b, a, b - a);\n    println!(\"{} * {} = {}\", a, b, a * b);\n    println!(\"{} / {} = {}\", b, a, b / a);\n    println!(\"{} % {} = {}\", a, b, a % b);\n    \n    // Logicos:\n    println!(\"AND: a < b && c > b da {}\", a < b && c > b);\n    println!(\"OR: a < b || b > c da {}\", a < b || b > c);\n    println!(\"NOT: ! a < b da {}\", ! a < b);\n    \n    // Comparacion:\n    println!(\"{} es distinto de {}, es {}\", a, b, a != b );\n    println!(\"{} es igual que {}, es {}\", a, b, a == b);\n    println!(\"{} es mayor que {}, es {}\", a, b, a > b );\n    println!(\"{} es menor que {}, es {}\", a, b, a < b );\n    println!(\"{} es mayor o igual que {}, es {}\", a, b, a >= b );\n    println!(\"{} es menor igual de que {}, es {}\", a, b, a <= b );\n    \n    // Asignacion:\n    a += 1;\n    println!(\"a += 1, ahora a vale {}\", a);\n    a -= 1;\n    println!(\"a -= 1, ahora a vale {}\", a);\n    a *= 2;\n    println!(\"a *= 2, ahora a vale {}\", a);\n    a /= 2;\n    println!(\"a /= 2, ahora a vale {}\", a);\n    a %= 2;\n    println!(\"a %= 2, ahora a vale {}\", a);\n\nprintln!(\"ESTRUCTURAS DE CONTROL\");\n \n    let mut acdc: u8 = 1;\n\n    println!(\"LOOP\");\n    'counting_up: loop {\n   \n        if acdc < 4 {\n        println!(\"{}\", acdc);\n        } else if acdc == 4 {\n        println!(\"y {}\", acdc);\n        } else {\n        break 'counting_up;\n        }\n        acdc = acdc + 1;\n    }\n\n    let mut acdc = 1;\n\n    println!(\"WHILE\");\n    while acdc <= 4 {\n    \n        println!(\"{}\", acdc);\n        acdc = acdc + 1;\n    }\n\n    println!(\"FOR\");\n    for acdc in (1..5).rev() {\n        println!(\"{}\", acdc);\n    }\n    println!(\"FIN\");\n    \n    println!(\"DIFICULTAD EXTRA\");\n    for metallica in 10..56 {\n        if metallica % 2 == 0 {\n            if metallica % 3 == 0 {\n                if metallica != 16 {\n                    println!(\"{}\", metallica);\n                }\n            }\n        }\n    }\n\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/rust/kenysdev.rs",
    "content": "/*\n╔═══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado                ║\n║ GitHub: https://github.com/Kenysdev   ║\n║ 2024 -  Rust                          ║\n╚═══════════════════════════════════════╝\n\n-----------------------------------------\n* OPERADORES Y ESTRUCTURAS DE CONTROL\n-----------------------------------------\n*/ \n#[allow(unused_assignments)] // no advertencia de asignaciones. \nfn main() {\n    let a: i8 = 10;\n    let b: i8 = 2;\n    let mut r: i8;\n    // ______________________________________\n    // * OPERADORES\n    // - Operadores aritmeticos\n    r = a + b; // addition\n    r = a - b; // subtraction\n    r = a * b; // multiplication\n    r = a / b; // division\n    r = a % b; // remainder\n    r = (4 + 2) * 3 / 2; // Combined\n    println!(\"Aritmetico: {}\", r);\n\n    // ______________________________________\n    // - Operadores de Asignación\n    r = a;  // 10\n    r += b; // 12\n    r -= b; // 10\n    r *= b; // 20\n    r /= b; // 10\n    r %= b; // 0\n    println!(\"Asignación: {}\", r);\n\n    // ______________________________________\n    // - Operadores de Comparación\n    let mut boolean: bool;\n    boolean = a == b; // igual a\n    boolean = a != b; // diferente de\n    boolean = a < b;  // menor que\n    boolean = a > b;  // mayor que\n    boolean = a <= b; // menor o igual\n    boolean = a >= b; // mayor o igual\n    println!(\"Comparación: {}\", boolean);\n\n    // ______________________________________\n    // - Operadores Lógicos\n    boolean = a == b && 5 != 6; // and\n    boolean = a > b || 6 < 5;  // or\n    boolean = !(a == b);       // not \n    println!(\"Logicos: {}\", boolean);\n\n    // ______________________________________\n    // - Operadores Bit a Bit\n    r = a & b;  // AND   \n    r = a | b;  // OR\n    r = a ^ b;  // XOR\n    r = !a;     // NOT\n    r = a << b; // izquierda\n    r = a >> b; // derecha\n    println!(\"Logicos: {}\", r);\n\n    // ______________________________________\n    // * ESTRUCTURAS DE CONTROL\n    // - Condicinales\n    if a > b {\n        boolean = true;\n    }\n\n    // con else\n    if a > b {\n        boolean = true;\n    } else{\n        boolean = false;\n    }\n\n    // con múltiples condiciones\n    let mut st = \"\";\n    if a > b {\n        st = \"a > b\";\n    } else if a < b {\n        st = \"a < b\";\n    } else if a == b{\n        st = \"a = b\";\n    } else {\n        st = \"xD\"\n    }\n    println!(\"{}\", st);\n\n    // condicional boolean\n    if boolean {\n        println!(\"condicional: true\");\n    } else{\n        println!(\"condicional: false\");\n    }\n\n    // Usando if en una declaración let\n    let mut num = if boolean {10} else {2};\n    println!(\"{}\", num);\n\n    // ______________________________________\n    // - Construcción de ramificación (match)\n    // mas: https://doc.rust-lang.org/book/ch06-02-match.html\n    num = 12;\n    match num {\n        0 => st = \"Es cero\",\n        1 | 2 => st = \"Uno o dos\",\n        3..=10 => st = \"Entre 3 y 10\",\n        11..=50 if num % 2 == 0 => {\n            st = \"Entre 11 - 50 y es par\"\n        }\n        _ => st = \"Ningun patron\",\n    }\n    println!(\"{}\", st);\n\n    // ______________________________________\n    // - Bucles (loop, while y for)\n    // loop (una y otra vez para siempre o hasta detener.)\n    num = 0;\n    loop {\n        num += 1;\n        println!(\"{}\", num);\n        if num == 3 {\n            break;\n        }\n    }\n    \n    // Devolviendo valores de los bucles\n    num = 0;\n    let r = loop {\n        num += 1;\n        if num == 3 {\n            break num;\n        }\n    };\n    println!(\"retorno: {}\", r);\n\n    // Etiquetas de bucle\n    let mut a = 0;\n    'external: loop {\n        a += 1;\n        println!(\"external: {}\", a);\n\n        let mut b = 0;\n        'internal: loop {\n            b += 1;\n            println!(\"internal: {}\", b);\n            if b == 2 {\n                break 'internal;\n            }\n        }\n        if a == 3 {\n            break 'external;\n        }\n    }\n\n    // ______________________________________\n    // while (Mientras sea true, el bucle se ejecuta).\n    // Elimina mucho anidamiento necesario en *loop*.\n    num = 0;\n    while num < 3 {\n        num += 1;\n        println!(\"while: {}\", num);\n    }\n\n    // ______________________________________\n    // for (Iterar y repeticiones específicas).\n    let items = [10, 20, 30];\n    for i in items {\n        println!(\"item: {}\", i);\n    }\n\n    // Usando rango específico.\n    for n in 0..=3{\n        println!(\"rango: {}\", n);\n    }\n\n    // para invertir el rango\n    for n in (1..4).rev(){\n        println!(\"invertir: {}\", n);\n    }\n\n    /* ______________________________________\n    * Ejercicio:\n    ------------\n    - Crea un programa que imprima por consola todos\n      los números comprendidos entre 10 y 55 (incluidos),\n      pares, y que no son ni el 16 ni múltiplos de 3.\n    */\n\n    for num in 10..=55{\n        if (num % 2 == 0) && (num != 16) && (num % 3 != 0) {\n            println!(\"- {}\", num);\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/rust/kodenook.rs",
    "content": "fn main() {\n    /*\n        Arithmetic Operators\n    */\n\n    println!(\"Arithmetic Operators\");\n    println!(\"2 + 2 = {}\", 2 + 2);\n    println!(\"2 - 2 = {}\", 2 - 2);\n    println!(\"2 * 2 = {}\", 2 * 2);\n    println!(\"2 / 2 = {}\", 2 / 2);\n    println!(\"2 % 2 = {}\", 2 % 2);\n\n    /*\n        Bitwise Operators\n    */\n\n    println!(\"Bitwise Operators\");\n    println!(\"&: 5 & 2 = {}\", 5 & 2);\n\tprintln!(\"|: 5 | 2 = {}\", 5 | 2);\n\tprintln!(\"^: 5 ^ 2 = {}\", 5 ^ 2);\n\tprintln!(\">>: 5 >> 2 = {}\", 5 >> 2);\n\tprintln!(\"<<: 5 << 2 = {}\", 5 << 2);\n\n    /*\n        Assignment Operators\n    */\n\n    println!(\"Assignment Operators\");\n    println!(\"x = 5\");\n    println!(\"x += 5, x = x + 5\");\n    println!(\"x -= 5, x = x - 5\");\n    println!(\"x *= 5, x = x * 5\");\n    println!(\"x /= 5, x = x / 5\");\n    println!(\"x ~/= 5, x = x ~/ 5\");\n    println!(\"x %= 5, x = x % 5\");\n    println!(\"x &= 5, x = x & 5\");\n    println!(\"x |= 5, x = x | 5\");\n    println!(\"x ^= 5, x = x ^ 5\");\n    println!(\"x >>= 5, x = x >> 5\");\n    println!(\"x <<= 5, x = x << 5\");\n    println!(\"x >>>= 5, x = x >>> 5\");\n\n    /*\n        Comparison Operators\n    */\n\n    println!(\"Comparison Operators\");\n    println!(\"Equal to 4 == 5, {}\", 4 == 5);\n    println!(\"Not Equal to 4 != 5, {}\", 4 != 5);\n    println!(\"Grater Than 4 > 5, {}\", 4 > 5);\n    println!(\"Less Than 4 < 5, {}\", 4<= 5);\n    println!(\"Grater Than Or Equal to 4 >= 5, {}\", 4 >= 5);\n    println!(\"Less Than Or Equal to 4 <= 5, {}\", 4 <= 5);\n\n    /*\n        Logical Operators\n    */\n\n    println!(\"Logical Operators\");\n    println!(\"&&, 3 < 5 && 3 < 10, {}\", 3 < 5 && 3 < 10);\n    println!(\"||, 3 < 5 || 3 < 10, {}\", 3 < 5 || 3 < 10);\n    println!(\"!, !(4 < 5), {}\", !(4 < 5));\n\n    /*\n        If\n    */\n\n    if 6 > 5 {\n        println!(\"6 is grater than 5\");\n    } else if 5 < 6 {\n        println!(\"5 is less than 6\");\n    } else {\n        println!(\"Good Bye\");\n    }\n\n    /*\n        Loop\n    */\n\n    let mut _idx: u8 = 0;\n\n    loop {\n        println!(\"{_idx}\");\n        _idx += 1;\n        if _idx == 5 {\n            break;\n        }\n    }\n\n    /*\n        While\n    */\n\n    while _idx > 0 {\n        println!(\"{_idx}\");\n        _idx -= 1;\n    }\n\n    /*\n        For\n    */\n\n    let a = [10, 20, 30, 40, 50];\n\n    for element in a {\n        println!(\"the value is: {element}\");\n    }\n\n    /*\n        Exercise\n    */\n\n    for element in 10..56 {\n        if element % 2 != 0 || element % 2 != 0 || element == 16 {\n            continue;\n        }\n\n        println!(\"{element}\")\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/rust/miguelex.rs",
    "content": "// progama para mostrar los tipos de operadores de rust\n\nfn main() {\n\n    // operadores de asignacion\n    let mut a = 2;\n    println!(\"ASIGNACIÓN:\");\n    println!(\"Mostramos el valor de la variable a = {}\", a);\n    a += 2;\n    println!(\"Sumamos 2 a la variable a = {}\", a);\n    a -= 2;\n    println!(\"Restamos 2 a la variable a = {}\", a);\n    a *= 2;\n    println!(\"Multiplicamos por 2 a la variable a = {}\", a);\n    a /= 2;\n    println!(\"Dividimos por 2 a la variable a = {}\", a);\n    a %= 2;\n    println!(\"Hacemos el modulo 2 a la variable a = {}\", a);\n    a = 2;\n    println!(\"Mostramos el valor de la variable a = {}\", a);\n    a <<= 1;\n    println!(\"Desplazamos a la izquierda 1 bit a la variable a = {}\", a);\n    a >>= 1;\n    println!(\"Desplazamos a la derecha 1 bit a la variable a = {}\", a);\n    a &= 1;\n    println!(\"Hacemos un AND a la variable a = {}\", a);\n    a |= 1;\n    println!(\"Hacemos un OR a la variable a = {}\", a);\n    a ^= 1;\n    println!(\"Hacemos un XOR a la variable a = {}\", a);\n    println!();\n\n    // operadores aritmeticos\n    let a = 10;\n    let b = 5;\n\n    println!(\"OPERADORES ARITMÉTICOS:\");\n    println!(\"a = {}\", a);\n    println!(\"b = {}\", b);\n    println!(\"a + b = {}\", a + b);\n    println!(\"a - b = {}\", a - b);\n    println!(\"a * b = {}\", a * b);\n    println!(\"a / b = {}\", a / b);\n    println!(\"a % b = {}\", a % b);\n    println!();\n\n    // operadores de comparacion\n    let a = 10;\n    let b = 5;\n\n    println!(\"OPERADORES DE COMPARACIÓN:\");\n    println!(\"a = {}\", a);\n    println!(\"b = {}\", b);\n    println!(\"a == b = {}\", a == b);\n    println!(\"a != b = {}\", a != b);\n    println!(\"a > b = {}\", a > b);\n    println!(\"a < b = {}\", a < b);\n    println!(\"a >= b = {}\", a >= b);\n    println!(\"a <= b = {}\", a <= b);\n    println!();\n\n    // operadores lógicos\n    let a = true;\n    let b = false;\n\n    println!(\"OPERADORES LÓGICOS:\");\n    println!(\"a = {}\", a);\n    println!(\"b = {}\", b);\n    println!(\"a && b = {}\", a && b);\n    println!(\"a || b = {}\", a || b);\n    println!(\"!a = {}\", !a);\n    println!();\n\n    // operadores binarios\n    let a = 0b1010;\n    let b = 0b1100;\n\n    println!(\"OPERADORES BINARIOS:\");\n    println!(\"a = {:b}\", a);\n    println!(\"b = {:b}\", b);\n    println!(\"a & b = {:b}\", a & b);\n    println!(\"a | b = {:b}\", a | b);\n    println!(\"a ^ b = {:b}\", a ^ b);\n    println!(\"!a = {:b}\", !a);\n    println!(\"a << 1 = {:b}\", a << 1);\n    println!(\"a >> 1 = {:b}\", a >> 1);\n    println!();\n\n    // Estructuras de control\n    \n    // Ejemplo if\n    let a = 10;\n    let b = 5;\n    if a > b {\n        println!(\"a es mayor que b\");\n    } else {\n        println!(\"a es menor o igual que b\");\n    }\n\n    // Ejemplo if anidado\n    let a = 10;\n    let b = 5;\n    let c = 15;\n    if a > b {\n        if a > c {\n            println!(\"a es mayor que b y c\");\n        } else {\n            println!(\"a es mayor que b pero menor que c\");\n        }\n    } else {\n        println!(\"a es menor o igual que b\");\n    }\n    // Ejemplo loop\n    let mut a = 0;\n    loop {\n        println!(\"a = {}\", a);\n        a += 1;\n        if a == 10 {\n            break;\n        }\n    }\n    // Ejemplo while\n    let mut a = 0;\n    while a < 10 {\n        println!(\"a = {}\", a);\n        a += 1;\n    }\n    // Ejemplo for\n    for a in 0..10 {\n        println!(\"a = {}\", a);\n    }\n    // Ejemplo match\n    let a = 10;\n    match a {\n        0 => println!(\"a es 0\"),\n        1 => println!(\"a es 1\"),\n        2 => println!(\"a es 2\"),\n        3 => println!(\"a es 3\"),\n        4 => println!(\"a es 4\"),\n        5 => println!(\"a es 5\"),\n        6 => println!(\"a es 6\"),\n        7 => println!(\"a es 7\"),\n        8 => println!(\"a es 8\"),\n        9 => println!(\"a es 9\"),\n        10 => println!(\"a es 10\"),\n        _ => println!(\"a es otro valor\"),\n    }\n    // Ejemplo match con if\n    let a = 10;\n    match a {\n        0 => println!(\"a es 0\"),\n        1 => println!(\"a es 1\"),\n        2 => println!(\"a es 2\"),\n        3 => println!(\"a es 3\"),\n        4 => println!(\"a es 4\"),\n        5 => println!(\"a es 5\"),\n        6 => println!(\"a es 6\"),\n        7 => println!(\"a es 7\"),\n        8 => println!(\"a es 8\"),\n        9 => println!(\"a es 9\"),\n        10 => {\n            println!(\"a es 10\");\n            if a > 5 {\n                println!(\"a es mayor que 5\");\n            }\n        },\n        _ => println!(\"a es otro valor\"),\n    }\n    // Ejemplo match con if anidado\n    let a = 10;\n    match a {\n        0 => println!(\"a es 0\"),\n        1 => println!(\"a es 1\"),\n        2 => println!(\"a es 2\"),\n        3 => println!(\"a es 3\"),\n        4 => println!(\"a es 4\"),\n        5 => println!(\"a es 5\"),\n        6 => println!(\"a es 6\"),\n        7 => println!(\"a es 7\"),\n        8 => println!(\"a es 8\"),\n        9 => println!(\"a es 9\"),\n        10 => {\n            println!(\"a es 10\");\n            if a > 5 {\n                println!(\"a es mayor que 5\");\n            } else {\n                println!(\"a es menor o igual que 5\");\n            }\n        },\n        _ => println!(\"a es otro valor\"),\n    }\n    // Ejemplo match con if anidado y else if\n    let a = 10;\n    match a {\n        0 => println!(\"a es 0\"),\n        1 => println!(\"a es 1\"),\n        2 => println!(\"a es 2\"),\n        3 => println!(\"a es 3\"),\n        4 => println!(\"a es 4\"),\n        5 => println!(\"a es 5\"),\n        6 => println!(\"a es 6\"),\n        7 => println!(\"a es 7\"),\n        8 => println!(\"a es 8\"),\n        9 => println!(\"a es 9\"),\n        10 => {\n            println!(\"a es 10\");\n            if a > 5 {\n                println!(\"a es mayor que 5\");\n            } else if a < 5 {\n                println!(\"a es menor que 5\");\n            } else {\n                println!(\"a es igual que 5\");\n            }\n        },\n        _ => println!(\"a es otro valor\"),\n    }\n\n    // Extra\n\n    println!(\"A continuación, el ejemplo extra\");\n\n    for a in 10..56 {\n        if (a % 2 == 0) && (a != 16) && (a % 3 != 0)\n        {\n            println!(\"a = {}\", a);\n        }            \n    }\n\n\n\n\n\n\n    \n\n\n\n\n\n\n\n\n\n   \n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/rust/owen-ian.rs",
    "content": "//=========================================\n// 01 - OPERADORES Y ESTRUCTURAS DE CONTROL\n//=========================================\n\nfn main() {\n    // Operadores Aritméticos\n    let a: i32 = 10;\n    let b: i32 = 3;\n    println!(\"Suma: {}\", a + b);\n    println!(\"Resta: {}\", a - b);\n    println!(\"Multiplicación: {}\", a * b);\n    println!(\"División: {}\", a / b);\n    println!(\"Módulo: {}\", a % b);\n    println!(\"Exponenciación: {}\", a.pow(b));\n\n    // Operadores Relacionales (Comparación)\n    println!(\"Igual a: {}\", a == b);\n    println!(\"Diferente de: {}\", a != b);\n    println!(\"Menor que: {}\", a < b);\n    println!(\"Mayor que: {}\", a > b);\n    println!(\"Menor o igual que: {}\", a <= b);\n    println!(\"Mayor o igual que: {}\", a >= b);\n    \n    // Operadores Lógicos\n    let x = true;\n    let y = false;\n    println!(\"AND lógico: {}\", x && y);\n    println!(\"OR lógico: {}\", x || y);\n    println!(\"NOT lógico: {}\", !x);\n    \n    // Operadores de Bits\n    let c: i32 = 2;\n    let d: i32 = 3;\n    println!(\"AND binario: {}\", c & d);\n    println!(\"OR binario: {}\", c | d);\n    println!(\"XOR binario: {}\", c ^ d);\n    println!(\"Desplazamiento a la izquierda: {}\", c << 1);\n    println!(\"Desplazamiento a la derecha: {}\", c >> 1);\n\n    // Operadores de Pertenencia\n    let lista = vec![1, 2, 3, 4, 5];\n    println!(\"Pertenece a la lista: {}\", lista.contains(&3));\n    println!(\"No pertenece a la lista: {}\", !lista.contains(&6));\n    \n    // Operadores de Asignación\n    let mut e: i32 = 5;\n    e += 2;\n    println!(\"Suma y asignación: {}\", e);\n    e -= 2;\n    println!(\"Resta y asignación: {}\", e);\n    e *= 2;\n    println!(\"Multiplicación y asignación: {}\", e);\n    e /= 2;\n    println!(\"División y asignación: {}\", e);\n    e %= 2;\n    println!(\"Resto y asignación: {}\", e);\n    \n    // Operadores de Asignación de Bits\n    let mut f: i32 = 2; // 0b0010\n    f &= 3; // 0b0011\n    println!(\"AND a nivel de bits y asignación: {}\", f); // 0b0010\n    f |= 1; // 0b0001\n    println!(\"OR a nivel de bits y asignación: {}\", f);  // 0b0011\n    f ^= 1; // 0b0001\n    println!(\"XOR a nivel de bits y asignación: {}\", f); // 0b0010\n    f <<= 1;\n    println!(\"Desplazamiento a la izquierda y asignación: {}\", f); // 0b0100\n    f >>= 1;\n    println!(\"Desplazamiento a la derecha y asignación: {}\", f); // 0b0010\n    \n    // Otros Operadores\n    let vec = vec![1, 2, 3, 4, 5];\n    println!(\"Acceso a miembro: {}\", vec[0]);\n    let range = 1..5;\n    println!(\"Rango: {:?}\", range);\n    let range_inclusivo = 1..=5;\n    println!(\"Rango inclusivo: {:?}\", range_inclusivo);\n    let valor = Some(42);\n    println!(\"Operador de resultado: {:?}\", valor.ok_or(\"Error\"));\n    \n    // Operadores adicionales\n    println!(\"Separador de elementos en listas: {:?}\", [1, 2, 3]);\n    println!(\"Terminador de sentencias: semicolon es requerido en Rust\");\n    println!(\"Especificador de tipo: let x: i32 = 10\");\n    println!(\"Operador de resolución de alcance: Vec::new()\");\n    println!(\"Closure: let suma = |a, b| a + b;\");\n    println!(\"Patrones de vinculación: let Some(x) = Some(42);\");\n\n    // Loop infinito y de uso cotidiano, se ejecuta hasta el break\n    let mut i = 0;\n    loop {\n        if i == 5 {\n            break;\n        }\n        println!(\"{i}\");\n        i += 1;\n    }\n        \n    // Loop que ejecuta código mientras una condición sea verdadera\n    let mut i = 0;\n    while i < 5 {\n        println!(\"{i}\");\n        i += 1;\n    }\n        \n    // Bucle for que itera sobre un rango\n    for i in 0..5 {\n        println!(\"{i}\");\n    }\n\n    // Loop que permite romper otros bucles internos o externos que sean etiquetados\n    let mut a = 0;\n    'external: loop {\n        a += 1;\n        println!(\"external: {}\", a);\n        \n        let mut b = 0;\n        'internal: loop {\n            b += 1;\n            println!(\"internal: {}\", b);\n            if b == 2 {\n                break 'internal;\n            }\n        }\n        if a == 3 {\n            break 'external;\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/rust/raulfauli.rs",
    "content": "/// 01 - OPERADORES Y ESTRUCTURAS DE CONTROL\nfn main() {\n    // Variables\n    let a = 10;\n    let b = 4;\n\n    // Operadores aritméticos\n    println!(\"Suma {a} + {b} = {}\", a + b);\n    println!(\"Resta {a} - {b} = {}\", a - b);\n    println!(\"Multiplicación {a} * {b} = {}\", a * b);\n    println!(\"División {a} / {b} = {}\", a / b);\n    println!(\"Módulo {a} % {b} = {}\", a % b);\n\n    // Operadores de comparación\n    println!(\"¿{a} es == {b}? {}\", a == b);\n    println!(\"¿{a} es != {b}? {}\", a != b);\n    println!(\"¿{a} es > {b}? {}\", a > b);\n    println!(\"¿{a} es < {b}? {}\", a < b);\n    println!(\"¿{a} es >= {b}? {}\", a >= b);\n    println!(\"¿{a} es <= {b}? {}\", a <= b);\n\n    // Operadores lógicos\n    println!(\"AND: ¿{a} es > 0 y {b} es > 0? {}\", a > 0 && b > 0);\n    println!(\"OR: ¿{a} es > 0 o {b} es > 0? {}\", a > 0 || b > 0);\n    println!(\"NOT: ¿{a} es lo contrario < 0? {}\", !(a > 0));\n\n    // Operadores de asignación\n    let mut number = 4;\n    println!(\"{number}\");\n    number += 1;\n    println!(\"{number}\");\n    number -= 1;\n    println!(\"{number}\");\n    number *= 2;\n    println!(\"{number}\");\n    number /= 2;\n    println!(\"{number}\");\n    number %= 2;\n    println!(\"{number}\");\n\n    // Operadores de bits\n    println!(\"AND: {a} & {b} = {}\", a & b); // 1010 & 0100 = 0000\n    println!(\"OR: {a} | {b} = {}\", a | b); // 1010 | 0100 = 1110\n    println!(\"XOR: {a} ^ {b} = {}\", a ^ b); // 1010 ^ 0100 = 1110\n    println!(\"NOT: !{a} = {}\", !a); // ~1010 = 0101\n\n    println!(\"Desplazamiento izquierda 10 << 2 = {}\", a << 2); // 1010 << 2 = 101000\n    println!(\"Desplazamiento derecha 10 >> 2 = {}\", a >> 2); // 1010 >> 2 = 0010\n\n    // Condicionales\n    if a > b {\n        println!(\"{a} es mayor que {b}\");\n    } else if a < b {\n        println!(\"{a} es menor que {b}\");\n    } else {\n        println!(\"{a} es igual que {b}\");\n    }\n\n    // Ternario\n    let max = if a > b { a } else { b };\n    println!(\"{max}\");\n\n    // Match\n    let a = 3;\n    match a {\n        1 | 2 => println!(\"Es 1 o 2\"),\n        3 => println!(\"Es 3\"),\n        4 => println!(\"Es 4\"),\n        _ => println!(\"Es otro número\"),\n    }\n\n    // Bucles\n    let mut i = 0;\n    while i < 5 {\n        println!(\"{i}\");\n        i += 1;\n    }\n\n    for i in 0..5 {\n        println!(\"{i}\");\n    }\n\n    // Dibuja el rango 0 a 5 inclusive\n    for i in 0..=5 {\n        println!(\"{i}\");\n    }\n\n    // Bucle for-each\n    let numbers = [1, 2, 3, 4, 5];\n    for number in numbers.iter() {\n        println!(\"{number}\");\n    }\n\n    // Bucle infinito\n    let mut i = 0;\n    loop {\n        if i == 5 {\n            break;\n        }\n        println!(\"{i}\");\n        i += 1;\n    }\n\n    // Extra\n    println!(\"Extra:\");\n    for i in 10..=55 {\n        if i == 16 || i % 2 != 0 || i % 3 == 0 {\n            continue;\n        }\n        println!(\"{i}\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/rust/troleomotor10.rs",
    "content": "/*\n* EJERCICIO:\n* - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n*   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n*   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n* - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n*   que representen todos los tipos de estructuras de control que existan\n*   en tu lenguaje:\n*   Condicionales, iterativas, excepciones...\n* - Debes hacer print por consola del resultado de todos los ejemplos.\n*\n* DIFICULTAD EXTRA (opcional):\n* Crea un programa que imprima por consola todos los números comprendidos\n* entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n*/\n\nfn main(){\n    /*\n        OPERADORES\n    */\n    \n    // Operadores de asignación\n    let numero1: i32 = 10;\n    let numero2: i32 = 2;\n    let mut numero3: i32 = 10;\n    numero3 += 5;\n    numero3 -= 5;\n    numero3 *= 5;\n    numero3 /= 5;\n    numero3 %= 2;\n    println!(\"El resultado final es {}\", numero3);\n    \n    \n    // Operadores aritméticos\n    let suma: i32 = numero1 + numero2;\n    let resta: i32 = numero1 - numero2;\n    let multiplicacion: i32 = numero1 * numero2;\n    let division: i32 = numero1 / numero2;\n    let modulo: i32 = numero1 % numero2;\n\n    println!(\"La suma de 10 + 2 = {suma}\" );\n    println!(\"La resta de 10 - 2 = {resta}\");\n    println!(\"La multiplicación de 10 * 2 = {multiplicacion}\");\n    println!(\"La division de 10 / 2 = {division}\");\n    println!(\"El modulo de 10 y 2 = {modulo}\");\n\n    // Operadores de comparación\n    let igualdad: bool = 10 == 10;\n    let desigualdad: bool = 23 != 24;\n    let mayor_que: bool = 10 > 5;\n    let mayor_o_igual_que: bool = 10 >= 10;\n    let menor_que: bool = 80 < 69;\n    let menor_o_igual_que: bool = 49 <= 50;\n\n    println!(\"Igualdad de 10 == 10 es {}\", igualdad);\n    println!(\"23 es diferente de 24: {}\", desigualdad);\n    println!(\"10 es mayor que 5 {}\", mayor_que);\n    println!(\"10 es mas grande o igual a 10: {}\", mayor_o_igual_que);\n    println!(\"80 es menor a 69: {}\", menor_que);\n    println!(\"49 es menor o igual a 50: {}\", menor_o_igual_que);\n\n    // Operadores lógicos\n    let my_or: bool = 10 == 10 || 3 > 1;\n    let my_and: bool = 5 > 6 && 1 == 1;\n    let my_not: bool = !(5 > 1);\n\n    println!(\"10 == 10 || 3 > 1 es {}\", my_or);\n    println!(\"5 > 6 && 1 == 1 es {}\", my_and);\n    println!(\"!(5 > 1) es {}\", my_not);\n\n    // Operadores de pertenencia\n    let usuario: &str = \"Troleomotor10\";\n    println!(\"La letra O aparece en el nombre de usuario {}\", usuario.contains('o'));\n\n    // Operadores de bit\n    let j = 1010;\n    let k = 0011;\n    \n    let bit_and = j & k;\n    let bit_or = j | k;\n    let bit_xor = j ^ k;\n    let bit_not = !k;\n    let bit_move_right = j >> 1;\n    let bit_move_left = j << 1;\n\n    println!(\"j & k = {}\", bit_and);\n    println!(\"j | k = {}\", bit_or);\n    println!(\"j ^ k = {}\", bit_xor);\n    println!(\"!k = {}\", bit_not);\n    println!(\"j >> 1 = {}\", bit_move_right);\n    println!(\"j << 1 = {}\", bit_move_left);\n\n    /*\n        ESTRUCTURAS DE CONTROL\n    */\n\n    // Condicionales\n    // if\n    if numero1 == numero2 {\n        println!(\"Son el mismo numero!\")\n    }\n    // if else\n    if numero1 == numero2 {\n        println!(\"Son el mismo numero!\")\n    } else {\n        println!(\"Son números diferentes!\")\n    }\n    // if else if else\n    if numero1 == numero2 {\n        println!(\"El numero 1 y el numero 2 tienen el mismo valor\")\n    } else if numero1 > numero2 {\n        println!(\"El numero 1 es mas grande que el numero 2\")\n    } \n    else {\n        println!(\"El numero 2 es mas grande que el numero 1\")\n    }\n    \n    // Iterativas\n    // Bucle for\n    let lista_notas: [i32; 8] = [4, 7, 10, 8, 2, 8, 8, 9];\n    for x in lista_notas {\n        println!(\"{x}\");\n    }\n\n    // Bucle while\n    let mut contador: i32 = 0;\n    while contador <= 5 {\n        println!(\"Numero {contador}\");\n        contador += 1;\n    }\n\n    // Control de errores y panic\n    panic!(\"El programa finalizo!\");\n    \n    let data_file = File::open(\"hello.txt\");\n\n    let file_result = match data_file {\n        Ok(file) => file,\n        Err(error) => panic!(\"Problem opening the file: {:?}\", error),\n    };\n    \n\n    // Ejemplos extra\n    let mut contador2: i32 = 10;\n    while contador2 <= 55 {\n        if (contador2 % 2 == 0) && (contador2 != 16) && (contador2 % 3 != 0) {\n            println!(\"{}\", contador2);\n        }\n        contador2 += 1;\n    }\n        \n}\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/rust/zetared92.rs",
    "content": "// RETO #01 OPERADORES Y ESTRUCTURAS DE CONTROL\n\nfn main() {\n    // Operadores aritméticos\n    println!(\"Arithmetic Operators\");\n\n    let x = 15;\n    let y = 5;\n    println!(\"Addition: {}\", x + y);\n    println!(\"Subtraction: {}\", x - y);\n    println!(\"Multiplication: {}\", x * y);\n    println!(\"Division: {}\", x / y);\n\n    // Operadores de asignación\n    println!(\"Assignment Operators\");\n\n    let mut z = 15;\n\n    z += 5; // Equivalencia: z = z + 5;\n    z -= 5: // Equivalencia: z = z - 5;\n    z *= 5: // Equivalencia: z = z * 5;\n    z /= 5: // Equivalencia: z = z / 5;\n    z %= 5: // Equivalencia: z = z % 5;\n\n    println!(\"X final value: {}\", z);\n\n    // Operadores de comparación\n    println!(\"Comparison Operators\");\n\n    let x = 5;\n    let y = 15;\n\n    println!(\"Equal: {}\", x == y);\n    println!(\"Unequal: {}\", x != y);\n    println!(\"Less than: {}\", x < y);\n    println!(\"Greater than: {}\", x > y);\n    println!(\"Less Equal than: {}\", x <= y);\n    println!(\"Greater than: {}\", x >= y);\n\n    // Operadores lógicos\n    println!(\"Logical Operators\");\n\n    let x = true;\n    let y = false;\n\n    println!(\"Logical AND: x && y -> {}\", x && y);\n    println!(\"Logical NOT: !y -> {}\", !y);\n    println!(\"Logical OR: x !! y -> {}\", x || y);\n\n    // Operadores binarios\n    println!(\"Binary Operators\");\n\n    let x: u8 = 0b1010;\n    let y: u8 = 0b1100;\n\n    let and = x & b; // AND binario\n    let or = x | y; // OR binario\n    let xor = x ^ y; // XOR binario\n    let not = !x // NOT binario\n    let shift_left = x << 2; // Desplazamiento a la izquierda\n    let shift_right = x >> 4; // Desplazamiento a la derecha\n\n    println!(\"Binary AND: x & y -> {}\", x & y);\n    println!(\"Binary OR: x | y -> {}\", x | y);\n    println!(\"Binary XOR: x ^ y -> {}\", x ^ y);\n    println!(\"Binary NOT: !y -> {}\", !y);\n    println!(\"Shift Left: x << 2 -> {}\", x << 2);\n    println!(\"Shift Right: x >> 4 -> {}\", x >> 4);\n\n    // Operadores de identidad\n    let a = \"Hello\";\n    let b = \"Hello\";\n    let c = \"World\";\n    println!(\"Equal: {}\", a == b);\n    println!(\"Unequal: {}\", a != c);\n\n    // Operadores de pertenencia\n    let nums = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 0];\n    let num_in = 0;\n    println!(\"Membership operators: {}\", nums.contains(&num_in));\n}\n\n// Estructuras de control: Condicionales\nfn even_odd(num: i32) {\n    if num % 2 == 0 {\n        println!(\"The number {} is even\", num);\n    } else {\n        println!(\"The number {] is odd\", num);\n    }\n}\n\nfn main() {\n    let num1 = 10;\n    let num2 = 5;\n\n    even_odd(num1);\n    even_odd(num2);\n}\n\n// Instrucción match\nfn day_weekly(num: i32) -> String {\n    match num {\n        1 => String::from(\"Monday\"),\n        2 => String::from(\"Tuesday\"),\n        3 => String::from(\"Wednesday\"),\n        4 => String::from(\"Thrusday\"),\n        5 => String::from(\"Friday\"),\n        6 => String::from(\"Saturday\"),\n        7 => String::from(\"Sunday\"),\n        _ => String::from(\"Input a valid value (1-7)\")\n    }\n}\n\n// Iterativas: loop, while, for\n// Loop\nfn main() {\n    let mut counter = 0;\n\n    loop {\n        println!(\"Counter is: {}\", counter);\n        counter += 1;\n\n        if counter == 10{\n            break;\n        }\n    }\n}\n\n// While\nfn factorial(num: u32) -> u32 {\n    let mut result = 1;\n    let mut i: u32 = 1;\n\n    while i <= num {\n        result *= i;\n        i += 1;\n    }\n\n    result\n}\n\nfn main() {\n    let num = 5;\n    let result_factorial = factorial(num);\n\n    println!(\"Factorial of {} is: {}\", num, result_factorial);\n}\n\n// For\nfn main() {\n    let num_list = [1, 2, 3, 4, 5];\n\n    for num in num_list {\n        println!(\"Number: {}\", num);\n    }\n}\n\n// Manejo de errores: Panic y Result\nfn main() {\n    let num_str = \"15*\";\n    let num = match num_str.parse::<i32>() {\n        Ok(num) => num,\n        Err(_e) => -1,\n    };\n    println!(\"{}\", num);\n}\n\n// Extra\nfn main() {\n    println!(\"🧩 DIFICULTAD EXTRA 🧩\");\n    for num in 10..=55{\n        if num % 2 == 0 && num != 16 && num %3 !=0 {\n            println!(\"{}\", num);\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/scala/angelsanchezt.scala",
    "content": "object Main {\n  def main(args: Array[String]): Unit = {\n    // Operadores\n    // Aritméticos\n    val suma = 5 + 3\n    println(s\"Suma: 5 + 3 = $suma\")\n\n    val resta = 10 - 4\n    println(s\"Resta: 10 - 4 = $resta\")\n\n    val multiplicacion = 7 * 2\n    println(s\"Multiplicación: 7 * 2 = $multiplicacion\")\n\n    val division = 20 / 4\n    println(s\"División: 20 / 4 = $division\")\n\n    val modulo = 15 % 4\n    println(s\"Módulo: 15 % 4 = $modulo\")\n\n    // Lógicos\n    val andLogico = true && false\n    println(s\"AND Lógico: true && false = $andLogico\")\n\n    val orLogico = true || false\n    println(s\"OR Lógico: true || false = $orLogico\")\n\n    val notLogico = !true\n    println(s\"NOT Lógico: !true = $notLogico\")\n\n    // De comparación\n    val igual = 5 == 5\n    println(s\"Igual: 5 == 5 = $igual\")\n\n    val noIgual = 10 != 5\n    println(s\"No Igual: 10 != 5 = $noIgual\")\n\n    val mayorQue = 8 > 3\n    println(s\"Mayor Que: 8 > 3 = $mayorQue\")\n\n    val menorQue = 6 < 9\n    println(s\"Menor Que: 6 < 9 = $menorQue\")\n\n    val mayorIgual = 7 >= 7\n    println(s\"Mayor o Igual: 7 >= 7 = $mayorIgual\")\n\n    val menorIgual = 12 <= 15\n    println(s\"Menor o Igual: 12 <= 15 = $menorIgual\")\n\n    // De asignación\n    var x = 10\n    x += 5\n    println(s\"Asignación: x += 5 => x = $x\")\n\n    // De identidad\n    val a = \"Hola\"\n    val b = \"Hola\"\n    val identico = a eq b\n    println(s\"Identidad: a eq b = $identico\")\n\n    // De pertenencia\n    val lista = List(1, 2, 3)\n    val contiene = lista.contains(2)\n    println(s\"Pertenencia: lista.contains(2) = $contiene\")\n\n    // Bits\n    val bitAND = 5 & 3\n    println(s\"Bit AND: 5 & 3 = $bitAND\")\n\n    val bitOR = 5 | 3\n    println(s\"Bit OR: 5 | 3 = $bitOR\")\n\n    val bitXOR = 5 ^ 3\n    println(s\"Bit XOR: 5 ^ 3 = $bitXOR\")\n\n    val desplazamientoIzq = 8 << 2\n    println(s\"Desplazamiento Izquierdo: 8 << 2 = $desplazamientoIzq\")\n\n    val desplazamientoDer = 16 >> 2\n    println(s\"Desplazamiento Derecho: 16 >> 2 = $desplazamientoDer\")\n\n\n     // Estructuras de control\n    // Condicionales\n    if (x > 0) {\n      println(\"x es positivo\")\n    } else if (x < 0) {\n      println(\"x es negativo\")\n    } else {\n      println(\"x es cero\")\n    }\n\n    // Iterativas\n    var i = 10\n    while (i <= 55) {\n      if (i % 2 == 0 && i != 16 && i % 3 != 0) {\n        println(i)\n      }\n      i += 1\n    }\n\n    // Excepciones\n    try {\n      val resultado = 10 / 0\n    } catch {\n      case e: ArithmeticException => println(\"¡División por cero!\")\n    }\n\n  }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/scala/rianojnicolas.scala",
    "content": "object Main {\n    def main(args: Array[String]): Unit = {\n        // Operadores Aritmeticos\n        val a = 2\n        val b = 10\n        println(\"OPERADORES ARITMETICOS\")\n        val suma: Int  = a + b \n        println(s\"La suma entre $a y $b es igual a $suma\")\n        val resta: Int = a - b\n        println(s\"La resta entre $a y $b es igual a $resta\")\n        val division = a/b\n        println(s\"La division entre $a y $b es igual a $division\")\n        val producto: Int = a*b\n        println(s\"La multiplicacion entre $a y $b es igual a $producto\")\n        val modulo = a%b\n        println(s\"El resto de la division entre $a y $b es igual a $modulo\")\n        println(\"\")\n\n        // Operadores Relacionales\n        println(\"OPERADORES RELACIONALES\")\n        val igualdad = a == b\n        println(s\"¿ Son iguales $a y $b ? RTA -> $igualdad\")\n        val diferencia = a != b\n        println(s\"¿ Son diferentes $a y $b ? RTA -> $diferencia\")\n        val mayor = a > b\n        println(s\"¿ $a es mayor a $b ? RTA -> $mayor\")\n        val menor = a < b\n        println(s\"¿ $a es menor a $b ? RTA -> $menor\")\n        val menorIgual = a <= b\n        println(s\"¿ $a es menor e igual a $b ? RTA -> $menorIgual\")\n        val mayorIgual = a >= b\n        println(s\"¿ $a es mayor e igual a $b ? RTA -> $mayorIgual\")\n        print(\"\")\n\n        // Operadores de Asignacion\n        println(\"OPERADORES DE ASIGNACION\")\n        println(\"\"\"\n            Asignación\n            \"\"\")\n        var x = 5\n        println(s\"A la variable *x* le asignamos el valor $x, con la siguiente sintaxis x = 1 \\n\")\n\n        println(\"CONTADOR DE SUMA\")\n        x += 1\n        println(s\"La operacion (x += 1), es equivalente x = x + 1, que da como resultado $x \\n\")\n\n        println(\"CONTADOR DE RESTA\")\n        x -= 2\n        print(s\"La operacion (x -= 2), es equivalente x = x - 2, que da como resultado $x \\n\")\n\n        println(\"CONTADOR DE PRODUCTO\")\n        x *= 5\n        println(s\"La operacion (x *= 5), es equivalente x = x * 5, que da como resultado $x \\n\")\n\n        println(\"CONTADOR DE DIVISION\")\n        x /= 5\n        println(s\"La operacion (x /= 5), es equivalente x = x / 5, que da como resultado $x \\n\")\n\n        println(\"CONTADOR DE MODULO\")\n        println(s\"La operacion (x %= 2), es equivalente al residuo de la división entre $x / 2\")\n        x %= 2\n        println(s\"Esta operacion da como resultado $x \\n\")\n\n        // Operadores Logicos\n        val A = true\n        val B = false\n        println(\"OPERADORES LOGICOS\")\n        // AND\n        println(s\"$A and $B = ${A && B}\")\n        println(s\"$B and $A = ${B && A}\")\n        println(s\"$A and $A = ${A && A} \\n\")\n\n        // OR\n        println(s\"$B or $A = ${B || A}\")\n        println(s\"$A or $B = ${A || B}\")\n        println(s\"$A or $A = ${A || A}\")\n        println(s\"$B or $B = ${B || B} \\n\")\n\n        // NOT\n        println(s\"not($A) = ${!A}\")\n        println(s\"not($B) = ${!B} \\n\")\n        \n        // Operadores de Pertenencia\n        println(\"\"\"OPERADORES DE PERTENCIA\n                    En Scala no hay operadores de este tipo,\n                    Pero existen metodos para una estructura de datos\n                    como lo son las listas o los conjuntos\n                \"\"\")\n        val my_list = List(1, 10, 4, 5, 100)\n        println(s\"La lista es: ${my_list.toString}\")\n        val element = 2\n        println(s\"¿$element esta en la lista? RTA->${my_list.contains(element)}\\n\")\n        \n        val my_set = Set(1, 2, 3, 4, 5)\n        println(s\"El conjunto es: ${my_set.toString}\")\n        println(s\"¿$element esta en el conjunto? RTA->${my_set(element)}\\n\")\n\n        // Operadores de Identidad\n        println(\"\"\"OPERADORES DE IDENTIDAD\n                    En Scala no hay operadores de este tipo,\n                    Pero existen un metodo denominado eq\n                    que es equivalente al operador is de Python\n                \"\"\")\n        val d = List(1, 2, 3)\n        val e = List(1, 2, 3)\n        val f = d\n        println(s\"¿${d.toString} es el mismo objeto que ${e.toString}? RTA->${d eq e}\")\n        println(s\"¿${d.toString} es el mismo objeto que ${f.toString}? RTA->${d eq f}\\n\")\n        \n        // Operadores Bit a Bit\n        println(\"OPERADORES BIT A BIT\")\n        val x1 = 10 // binario es 00001010\n        val y1 = 12 // binario es 00001100\n\n        // AND - bit a bit\n        var z = x1 & y1 // decimal es 8 - binario es 00001000\n        println(s\"La operacion: $x1 & $y1 = $z\")\n\n        // OR - bit a bit\n        z = x1 | y1 // decimal es 14 - binario es 00001110      \n        println(s\"La operacion: $x1 | $y1 = $z\")\n\n        // XOR - bit a bit\n        z = x1 ^ y1 // decimal es 6 - binario es 00000110\n        println(s\"La operacion: $x1 ^ $y1 = $z\")\n\n        // NOT - bit a bit\n        z = ~x1 // decimal es -11 - binario es 11110101\n        println(s\"La operacion: ~$x1 = $z\")\n\n        // Desplazamiento a la izquierda - bit a bit\n        z = x1 << 2 // decimal es 40 - binario 00101000\n        println(s\"La operacion: $x1 << 2 = $z\")\n\n        // Desplazamiento a la derecha - bit a bit\n        z = x1 >> 2 // decimal es 2 - binario es 00000010\n        println(s\"La operacion: $x1 >> 2 = $z \\n\")\n\n        // Estructuras de Control\n        // Ciclo IF\n        println(\"CICLO IF\")\n        if (x1%2 == 0) {\n            println(s\"$x1 es multiplo de 2\")\n        }\n        else if (x1%3 == 0) {\n            println(s\"$x1 es multiplo de 3\")\n        }\n        else {\n            println(s\"$x1 no es multiplo de 2 ni de 3\")\n        }\n\n        // Ciclo WHILE\n        println(\"\\nCICLO WHILE\")\n        while (z <= 10) {\n            println(z.toString)\n            z += 1\n        }\n\n        // Ciclo FOR\n        println(\"\\nCICLO FOR\")\n        for (i <- 1 to 5) {\n            println(i.toString)\n        }\n\n        // Match\n        println(\"\\nESTRUCTURA MATCH\")\n        val ciudad = \"Bogota\"\n\n        ciudad match {\n            case \"Bogota\" => println(s\"La ciudad $ciudad es la capital de Colombia\\n\")\n            case \"Caracas\" => println(s\"La ciudad $ciudad es la capital de Venezuela\\n\")\n            case \"Quito\" => println(s\"La ciudad $ciudad es la capital de Ecuador\\n\")\n        }\n\n        // Manejo de Excepciones\n        println(\"Try-Catch - Excepciones\")\n        try{\n            println(\"Ingresa el dividendo de la division: \")\n            val dividendo = scala.io.StdIn.readLine().toInt\n            println(\"Ingresa el divisor de la division: \")\n            val divisor = scala.io.StdIn.readLine().toInt\n            val division = dividendo/divisor\n            println(s\"La division entre $dividendo / $divisor es igual a $division \\n\")\n        }\n        catch {\n            case e: ArithmeticException => println(\"No se puede dividir por cero \\n\")\n        }\n\n        // Dificultad Extra\n        println(\"EJERCICIO EXTRA\")\n        import scala.util.control.Breaks._\n        for (i <- 9 to 56) {\n            breakable {\n                if (i == 16) {\n                    break\n                }\n                else if (i%3==0) {\n                    break\n                }\n                println(i)    \n            }\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/solidity/angelsanchezt.sol",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n*/\n\n// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ncontract ContratoReto01 {\n    event LogResultado(string mensaje, uint256 resultado);\n    event LogResultadoBit(string mensaje, uint16 resultado);\n    event LogResultado(string mensaje, bool resultado);\n    event LogError(string mensaje);\n    event LogErrorData(bytes data);\n\n    // Aritméticos, lógicos, de comparación, asignación\n    // https://www.geeksforgeeks.org/solidity-operators/\n    function operacionesBasicas() public {\n        uint256 a = 10;\n        uint256 b = 5;\n\n        // 1. Operadores Arimeticos\n        uint256 suma = a + b;\n        uint256 resta = a - b;\n        uint256 multiplicacion = a * b;\n        uint256 division = a / b;\n        uint256 modulo = a % b;\n        uint256 decremento = --b;\n        uint256 incremento = ++a;\n\n        emit LogResultado(\"Suma: (a + b): \", suma);\n        emit LogResultado(\"Resta: (a - b): \", resta);\n        emit LogResultado(\"Multiplicacion: (a * b): \", multiplicacion);\n        emit LogResultado(\"Division: (a / b): \", division);\n        emit LogResultado(\"Modulo: (a % b): \", modulo);\n        emit LogResultado(\"Decremento: ( -- b ): \", decremento);\n        emit LogResultado(\"Decremento: ( ++a ): \", incremento);\n\n        // 2. Operadores Relacionales\n        bool esIgual = a == b;\n        bool noEsIgual = a != b;\n        bool esMayor = a > b;\n        bool esMenor = a < b;\n        bool esMayorOIgual = a >= b;\n        bool esMenorOIgual = a <= b;\n\n        emit LogResultado(\"Igual a: (a == b): \", esIgual ? 1 : 0);\n        emit LogResultado(\"No es igual a: (a != b): \", noEsIgual ? 1 : 0);\n        emit LogResultado(\"Mayor que: (a > b): \", esMayor ? 1 : 0);\n        emit LogResultado(\"Menor que: (a < b): \", esMenor ? 1 : 0);\n        emit LogResultado(\n            \"Mayor que o igual: (a >= b): \",\n            esMayorOIgual ? 1 : 0\n        );\n        emit LogResultado(\n            \"Menor que o igual: (a <= b): \",\n            esMenorOIgual ? 1 : 0\n        );\n\n        // 3. Operadores Logicos\n        emit LogResultado(\"AND: a == b && a > 0 : \", (a == b && a > 0));\n        emit LogResultado(\"OR: a == b || a > 0 : \", (a == b || a > 0));\n        emit LogResultado(\"NOT: !( a == b )  : \", !(a == b));\n\n        // 4. Bitwise Operators\n        // Declaring variables\n        uint16 aa = 20;\n        uint16 bb = 10;\n\n        emit LogResultadoBit(\"Bitwise AND: (aa & bb)\", aa & bb);\n        emit LogResultadoBit(\"BitWise OR: (aa | bb)\", aa | bb);\n        emit LogResultadoBit(\"Bitwise XOR: (aa ^ bb)\", aa ^ bb);\n        emit LogResultadoBit(\"Bitwise Not: ( ~aa)\", ~aa);\n        emit LogResultadoBit(\"Left Shift: (aa << bb)\", aa << bb);\n        emit LogResultadoBit(\"Right Shift: (aa >> bb)\", aa >> bb);\n\n        //5. Operadores de Asignacion\n        uint16 assignment = 20;\n        uint assignment_add = 50;\n        uint assign_sub = 50;\n        uint assign_mul = 10;\n        uint assign_div = 50;\n        uint assign_mod = 32;\n\n        assignment_add += 10;\n        assign_sub -= 20;\n        assign_mul *= 10;\n        assign_div /= 10;\n        assign_mod %= 20;\n\n        emit LogResultado(\"assignment_add += 10: \", assignment_add);\n        emit LogResultado(\"assign_sub -= 20: \", assign_sub);\n        emit LogResultado(\"assign_mul *= 10:  \", assign_mul);\n        emit LogResultado(\"assign_div /= 10: \", assign_div);\n        emit LogResultado(\"assign_mod %= 20: \", assign_mod);\n        \n        // 6. Operador Condicional\n        uint result = (a > b? a-b : b-a);\n        emit LogResultado(\"(a > b? a-b : b-a): \", result);\n\n    }\n\n    // Condicionales\n    function condicionales(uint256 numero) public {\n        if (numero > 20) {\n            emit LogResultado(\"Numero mayor a 20\", numero);\n        } else if (numero == 20) {\n            emit LogResultado(\"Numero igual a 20\", numero);\n        } else {\n            emit LogResultado(\"Numero menor a 20\", numero);\n        }\n    }\n\n    // Iterativas\n    // EXTRA\n    function iterativas() public {\n        for (uint256 i = 10; i <= 55; i++) {\n            if (i % 2 == 0 && i != 16 && i % 3 != 0) {\n                emit LogResultado(\"Numero par y no es 16 ni multiplo de 3\", i);\n            }\n        }\n    }\n\n    /*\n        Excepciones: En Solidity, puedes controlar las excepciones utilizando estructuras como require, \n        revert, assert y manejo de excepciones con try/catch.\n        https://solidity-by-example.org/try-catch/ \n    */\n\n    // Ejemplo de revert con require\n    function dividir(uint256 a, uint256 b) public pure returns (uint256) {\n        require(b != 0, \"No se puede dividir por cero\");\n        return a / b;\n    }\n\n    // Manejo de Excepciones con Try/Catch (Solidity 0.8.0 y versiones posteriores):\n    // Ejemplo de manejo de excepciones con try/catch\n    function transferir(address destinatario, uint256 cantidad) public {\n        try msg.sender.transfer(cantidad) {\n            // Éxito: hacer algo si la transferencia es exitosa\n        } catch Error(string memory errorMessage) {\n            // Manejar la excepción: errorMessage contiene información sobre el error\n            emit LogError(errorMessage);\n        } catch (bytes memory errorData) {\n            // Manejar otras excepciones\n            emit LogErrorData(errorData);\n        }\n    }\n\n    // Ejemplo de assert\n    /*\n        assert se utiliza para verificar condiciones que deben ser siempre ciertas. \n        Si la condición no se cumple, se produce una excepción que no puede ser manejada \n        y terminará la ejecución del contrato. \n    */\n    function realizarOperacion(\n        uint256 a,\n        uint256 b\n    ) public pure returns (uint256) {\n        uint256 resultado = a * b;\n        assert(resultado > 0);\n        return resultado;\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/sql/Nicojsuarez2.sql",
    "content": "# #01 OPERADORES Y ESTRUCTURAS DE CONTROL\n> #### Dificultad: Fácil | Publicación: 02/01/24 | Corrección: 08/01/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/sql/adrs1166ma.sql",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n*/\n\n-- 🔥 Ejemplo:\n-- TABAL 1\nCREATE DATABASE Ejercici01;\nUSE Ejercici01;\n\nCREATE TABLE Empleados (\n\tID INT,\n\tNOMBRE varchar(20),\n\tAPELLIDO varchar(30),\n\tEDAD numeric(2),\n\tTELEFONO numeric(10),\n\tDIRECCION varchar(100),\n\tFECHA_NACIMIENTO date,\n\tSALARIO decimal (18,2),\n\tACTIVO char(2)\n);\n\ninsert into empleados values (1, 'Juan', 'Pérez', 25, 1234567890, 'Calle 123', '1978-06-15', 2500.00, 'SI');\ninsert into empleados values (2, 'María', 'López', 30, 9876543210, 'Avenida 456', '1980-03-20', 3000.00, 'SI');\ninsert into empleados values (3, 'Carlos', 'González', 28, 5555555555, 'Calle 789', '1979-11-10', 2800.00, 'SI');\ninsert into empleados values (4, 'Ana', 'Martínez', 35, 9998887770, 'Avenida 012', '1977-09-05', 3500.00, 'SI');\ninsert into empleados values (5, 'Pedro', 'Sánchez', 22, 1112223334, 'Calle 567', '1980-01-25', 2000.00, 'SI');\ninsert into empleados values (6, 'Laura', 'Ramírez', 31, 4444444444, 'Avenida 890', '1978-07-12', 3200.00, 'SI');\ninsert into empleados values (7, 'Luis', 'Torres', 29, 7777777777, 'Calle 345', '1979-04-18', 2700.00, 'SI');\ninsert into empleados values (8, 'Carmen', 'Hernández', 27, 6666666666, 'Avenida 678', '1980-02-03', 2600.00, 'SI');\ninsert into empleados values (9, 'Jorge', 'García', 33, 2223334445, 'Calle 901', '1977-12-27', 3400.00, 'SI');\ninsert into empleados values (10, 'Silvia', 'Lara', 24, 8889990000, 'Avenida 234', '1980-05-09', 2200.00, 'SI');\ninsert into empleados values (11, 'Roberto', 'Rojas', 26, 3334445556, 'Calle 567', '1979-02-14', 2400.00, 'SI');\ninsert into empleados values (12, 'Patricia', 'Cruz', 32, 2223334444, 'Avenida 890', '1978-08-21', 3100.00, 'SI');\ninsert into empleados values (13, 'Daniel', 'Gómez', 29, 5556667778, 'Calle 123', '1979-06-06', 2800.00, 'SI');\ninsert into empleados values (14, 'Sara', 'Vargas', 34, 6667778889, 'Avenida 456', '1977-04-01', 3300.00, 'SI');\ninsert into empleados values (15, 'Hugo', 'Orozco', 23, 9998887776, 'Calle 789', '1980-03-16', 2100.00, 'SI');\n\n-- TABLA 2\nCREATE TABLE NUMEROS (\n\tid INT,\n\tn1 INT,\n\tn2 INT\n);\n\nINSERT INTO NUMEROS VALUES (1, 5, 8);\nINSERT INTO NUMEROS VALUES (2, 7, 9);\nINSERT INTO NUMEROS VALUES (3, 7, 0);\n\n\n-- 🔥 a. Operadores artiméticos\nSELECT\n\tn1 as 'Numero 1',\n\tn2 as 'Numero 2',\n\tn1 + n2 AS Suma,\n\tn1 - n2 AS Resta,\n\tn1 * n2 AS Multiplicacion,\n\tn1 / CAST(n2 AS FLOAT) AS Division,\n\tn1 % n2 AS Modulo\nFROM NUMEROS\nWHERE n2 <> 0;\n\n\n-- 🔥 b. Operadores de Comparación\nSELECT * FROM Empleados WHERE ID = 15;\nSELECT * FROM Empleados WHERE EDAD <> 15;\nSELECT * FROM Empleados WHERE EDAD != 15;\nSELECT * FROM Empleados WHERE EDAD > 15;\nSELECT * FROM Empleados WHERE EDAD < 15;\nSELECT * FROM Empleados WHERE EDAD <= 15;\nSELECT * FROM Empleados WHERE EDAD >= 15;\n\nSELECT * FROM Empleados WHERE EDAD BETWEEN 30 AND 35; -- Si esta dentro del rango, incluye los extremos\nSELECT * FROM Empleados WHERE NOMBRE IN ('Juan', 'María', 'Carlos'); -- Compara si el valor está\nSELECT * FROM Empleados WHERE APELLIDO LIKE 'L%'; -- Apellidos que empiezan con 'L'\nSELECT * FROM Empleados WHERE TELEFONO IS NULL; -- Valores NULL\nSELECT * FROM Empleados WHERE TELEFONO IS NOT NULL; -- Valores no NULL\n\n\n-- 🔥 c. Operadores Lógicos\n\nPRINT 'Obtener empleados cuya edad sea mayor a 25 y cuyo salario sea mayor a 2500.';\nSELECT Nombre, Edad, Salario FROM Empleados WHERE (EDAD > 25) AND (salario > 2500); -- AND\n\nPRINT 'Obtener empleados cuyo salario sea mayor a 3000 o cuyo nombre sea \"Juan\".';\nSELECT Nombre, Salario FROM Empleados WHERE (salario > 3000) OR (nombre = 'Juan'); -- OR\n\nPRINT 'Obtener empleados que no estén activos (no tengan \"SI\" en la columna ACTIVO).';\nSELECT Nombre, Activo FROM Empleados WHERE NOT Activo = 'SI'; -- NOT \n\nPRINT  'Obtener empleados cuya edad sea mayor a 30 o cuyo salario sea mayor a 3500, pero solo si están activos.';\nSELECT * FROM Empleados WHERE ((edad > 30) OR (salario > 3500)) AND (activo = 'SI');\n\nPRINT 'Obtener empleados cuya edad esté entre 25 y 35, y cuyo salario sea mayor a 2500, pero que no sean activos.';\nSELECT * FROM Empleados WHERE (edad BETWEEN 25 AND 35) AND (salario>2500) AND ( NOT activo = 'SI');\n\nPRINT 'Obtener empleados con un salario superior a 3000 y que tengan la letra 'G' en su apellido, o aquellos que tengan un nombre que comience con \"M\".';\nSELECT * FROM Empleados WHERE (salario>3000 AND apellido LIKE 'G%') OR (nombre LIKE 'M%')\n\nPRINT 'Obtener empleados que no sean de la calle \"Avenida 456\" ni tengan un teléfono específico.';\nPRINT 'num : 999111999';\nSELECT * FROM Empleados WHERE (NOT DIRECCION = 'Avenida 456') AND  teléfono <> 999111999;\n\n\n-- 🔥 d. Operadores de Asignación\n\n-- Ejemplo de \" = \".\nUPDATE Empleados SET ACTIVO = 'NO' WHERE ID = 1;\n\n-- Incremento con \" += \"\nUPDATE Empleados SET SALARIO += 500 WHERE ID = 2;\n\n-- Decremento con \" -= \"\nUPDATE Empleados SET SALARIO -= 200 WHERE ID = 3;\n\n-- Multiplicación  con \" *= \" \nUPDATE Empleados SET SALARIO *= 1.10 WHERE ID = 4;\n\n-- División con \" /= \"\nUPDATE Empleados SET SALARIO /= 2 WHERE ID = 5;\n\n-- Basada en una condicion\n--Cambiar el estado \"ACTIVO\" a \"NO\" para empleados mayores de 30 años.\nUPDATE Empleados SET ACTIVO = 'NO' WHERE EDAD > 30;\n\n-- EJEMPLO de una combinacion de cálculos y asignación\n/*\nAjustar el salario de todos los empleados dependiendo de su edad:\nSi la edad es menor a 25 años, incrementar en un 15%.\nSi la edad es entre 25 y 30 años, incrementar en un 10%.\nSi la edad es mayor a 30 años, incrementar en un 5%.\n*/\nUPDATE Empleados\nSET SALARIO = \n    CASE \n        WHEN EDAD < 25 THEN SALARIO * 1.15\n        WHEN EDAD BETWEEN 25 AND 30 THEN SALARIO * 1.10\n        ELSE SALARIO * 1.05\n    END;\n\n-- Asignación a varias columnas simultáneamente\nUPDATE Empleados\nSET NOMBRE = 'Laura María',\n    APELLIDO = 'Ramírez López',\n    SALARIO = 3500\nWHERE ID = 6;\n\n\n-- 🔥 e. Operadores de Pertenencia\n\n-- IN - seleccionar\nSELECT * FROM Empleados WHERE NOMBRE IN ('Juan', 'María', 'Carlos');\n\n-- NOT IN - Excluir\nSELECT * FROM Empleados WHERE ID NOT IN (1, 3, 5);\n\n\n-- 🔥 f. Operadores de Bits\n\n-- agregamos una tabla\nALTER TABLE Empleados ADD PERMISOS INT;\n\n-- Actualizamos los valores de permisos con números representativos\nUPDATE Empleados\nSET PERMISOS = ID * 2; -- Simplemente asignamos un valor basado en el ID.\n\n\n-- AND a nivel de bit (&)\n\n-- Obtenemos empleados cuyos permisos tienen activado el segundo bit (valor 2 en binario):\nSELECT ID, NOMBRE, PERMISOS\nFROM Empleados\nWHERE PERMISOS & 2 = 2;\n\n\n-- OR a nivel de bit (|)\n\n-- Añadimos un permiso al primer bit (valor 1 en binario):\nSELECT ID, NOMBRE, PERMISOS, (PERMISOS | 1) AS NUEVOS_PERMISOS\nFROM Empleados;\n\n\n-- XOR a nivel de bit (^)\n\n--Verificamos qué permisos cambiarían si aplicamos un XOR con 3:\n\nSELECT ID, NOMBRE, PERMISOS, (PERMISOS ^ 3) AS XOR_RESULTADO\nFROM Empleados;\n\n\n-- Desplazamiento de bits a la izquierda (<<)\n\n-- Multiplicamos los permisos por un factor de 2 desplazando los bits a la izquierda:\nSELECT ID, NOMBRE, PERMISOS, (PERMISOS << 1) AS PERMISOS_DOBLE\nFROM Empleados;\n\n\n-- Desplazamiento de bits a la derecha (>>)\n\n-- Dividimos los permisos entre 2 desplazando los bits a la derecha:\nSELECT ID, NOMBRE, PERMISOS, (PERMISOS >> 1) AS PERMISOS_DIVIDIDO\nFROM Empleados;\n\n\n-- Complemento a nivel de bit (~)\n\n-- Invertimos todos los bits de los permisos:\nSELECT ID, NOMBRE, PERMISOS, (~PERMISOS) AS COMPLEMENTO\nFROM Empleados;\n\n\n-- 🔥 g. Estructuras de Control\n\n-- IF - ELSE\n-- ejm: Verifica si un empleado tiene un salario mayor a 3000 y realiza acciones:\nIF (SELECT SALARIO FROM Empleados WHERE ID = 1) > 3000\nBEGIN\n    PRINT 'Salario alto';\nEND\nELSE\nBEGIN\n    PRINT 'Salario bajo';\nEND\n\n-- CASE\n-- ejm: Consulta empleados categorizando por salario:\nSELECT NOMBRE, \n\tCASE \n\t\tWHEN SALARIO > 3000 THEN 'Alto'\n\t\tWHEN SALARIO BETWEEN 2000 AND 3000 THEN 'Medio'\n\t\tELSE 'Bajo'\n\tEND AS Categoria\nFROM Empleados;\n\n-- WHILE\n-- ejm: Itera sobre IDs de empleados para realizar acciones:\nDECLARE @ID INT = 1;\n\nWHILE @ID <= (SELECT MAX(ID) FROM Empleados)\nBEGIN\n    PRINT 'Procesando empleado con ID: ' + CAST(@ID AS VARCHAR);\n    SET @ID = @ID + 1;\nEND;\n\n\n-- Manejo de errores TRY - CATCH\n-- ejm: T-SQL\nBEGIN TRY\n    -- Intentar insertar un valor duplicado (error)\n    INSERT INTO Empleados (ID, NOMBRE) VALUES (1, 'Prueba');\nEND TRY\nBEGIN CATCH\n    PRINT 'Ocurrió un error: ' + ERROR_MESSAGE();\nEND CATCH;\n\n\n\n\n-- DIFICULTAD EXTRA  🔥🔥🔥\nCREATE TABLE #Numeros (\n    Numero INT\n);\n\nDECLARE @i INT = 10;\n\nWHILE @i <= 55\nBEGIN\n    INSERT INTO #Numeros (Numero)\n    VALUES (@i);\n\n    SET @i = @i + 1;\nEND;\n\nSELECT Numero\nFROM #Numeros\nWHERE Numero % 2 = 0\n\tAND Numero <> 16\n\tAND Numero % 3 <> 0;\n\n-- Limpiar por si las dudas\nDROP TABLE #Numeros;\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/sql/angelsanchezt.sql",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n*/\n-- Aritméticos\nDECLARE @a INT = 10, @b INT = 5;\n\nPRINT @a + @b;  -- Suma\nPRINT @a - @b;  -- Resta\nPRINT @a * @b;  -- Multiplicación\nPRINT @a / @b;  -- División\n\nPRINT 'Suma: ' + CAST(@a + @b AS VARCHAR(10));\nPRINT 'Resta: ' + CAST(@a - @b AS VARCHAR(10));\nPRINT 'Multiplicación: ' + CAST(@a * @b AS VARCHAR(10));\nPRINT 'División: ' + CAST(@a / @b AS VARCHAR(10));\n\n-- Lógicos\nDECLARE @x BIT = 1, @y BIT = 0;\nPRINT @x AND @y;  -- AND lógico\nPRINT @x OR @y;   -- OR lógico\nPRINT NOT @x;     -- NOT lógico\n\nPRINT 'AND lógico: ' + CAST(@x AND @y AS VARCHAR(5));\nPRINT 'OR lógico: ' + CAST(@x OR @y AS VARCHAR(5));\nPRINT 'NOT lógico: ' + CAST(NOT @x AS VARCHAR(5));\n\n-- De comparación\nPRINT @a = @b;    -- Igual a\nPRINT @a <> @b;   -- Diferente de\nPRINT @a > @b;    -- Mayor que\nPRINT @a < @b;    -- Menor que\nPRINT @a >= @b;   -- Mayor o igual a\nPRINT @a <= @b;   -- Menor o igual a\n\nPRINT 'Igual a: ' + CAST(@a = @b AS VARCHAR(5));\nPRINT 'Diferente de: ' + CAST(@a <> @b AS VARCHAR(5));\nPRINT 'Mayor que: ' + CAST(@a > @b AS VARCHAR(5));\nPRINT 'Menor que: ' + CAST(@a < @b AS VARCHAR(5));\nPRINT 'Mayor o igual a: ' + CAST(@a >= @b AS VARCHAR(5));\nPRINT 'Menor o igual a: ' + CAST(@a <= @b AS VARCHAR(5));\n\n\n-- De asignación\nDECLARE @resultado INT;\nSET @resultado = @a + @b;\nPRINT 'Resultado de asignación: ' + CAST(@resultado AS VARCHAR(10));\n\n\n-- Pertenencia\nDECLARE @frutas TABLE (fruta VARCHAR(50));\nINSERT INTO @frutas VALUES ('Manzana'), ('Banana'), ('Naranja');\nPRINT 'Banana' IN (SELECT fruta FROM @frutas);\n\n-- Bits\nDECLARE @bit1 INT = 5, @bit2 INT = 3;\nPRINT @bit1 & @bit2;  -- AND a nivel de bits\nPRINT @bit1 | @bit2;  -- OR a nivel de bits\nPRINT ~@bit1;         -- NOT a nivel de bits\n\nPRINT 'AND a nivel de bits: ' + CAST(@bit1 & @bit2 AS VARCHAR(10));\nPRINT 'OR a nivel de bits: ' + CAST(@bit1 | @bit2 AS VARCHAR(10));\nPRINT 'NOT a nivel de bits: ' + CAST(~@bit1 AS VARCHAR(10));\n\n\n\n-- Ejemplos de Estructuras de Control\nDECLARE @edad INT = 18;\nDECLARE @mensaje VARCHAR(50);\n\nSET @mensaje = CASE\n                WHEN @edad < 18 THEN 'Menor de edad'\n                WHEN @edad >= 18 AND @edad < 65 THEN 'Adulto'\n                ELSE 'Adulto mayor'\n               END;\n\nPRINT 'Mensaje condicional: ' + @mensaje;\n\nDECLARE @contador INT = 1;\n\nWHILE @contador <= 5\nBEGIN\n    PRINT 'Iteración: ' + CAST(@contador AS VARCHAR(10));\n    SET @contador = @contador + 1;\nEND;\n\n\n-- MANEJO de EXCEPCIONES\nBEGIN TRY\n    -- Intenta ejecutar una operación que podría generar un error\n    DECLARE @division INT = 10 / 0;\nEND TRY\nBEGIN CATCH\n    -- Maneja la excepción\n    PRINT 'Error: División por cero';\nEND CATCH;\n\n-- Programa que Imprime Números Específicos\nDECLARE @numero INT = 10;\n\nWHILE @numero <= 55\nBEGIN\n    IF @numero % 2 = 0 AND @numero != 16 AND @numero % 3 != 0\n        PRINT 'Número especial: ' + CAST(@numero AS VARCHAR(10));\n    \n    SET @numero = @numero + 1;\nEND;\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/sql/augustosdev.sql",
    "content": "-- OPERADORES\n\n-- Aritmeticos\nSELECT 5 + 3 AS suma;\nSELECT 5 - 3 AS resta;\nSELECT 5 * 3 AS multiplicacion;\nSELECT 9 / 3 AS divison; \nSELECT 10 % 3 AS modulo;\n\n--COMPARACION\nSELECT CASE WHEN 5 > 3 THEN 'Verdadero' ELSE 'Falso' END AS mayor;\nSELECT CASE WHEN 5 = 3 THEN 'Verdadero' ELSE 'Falso' END AS igual;\nSELECT CASE WHEN 5 != 3 THEN 'Verdadero' ELSE 'Falso' END AS diferente;\nSELECT CASE WHEN 5 < 3 THEN 'Verdadero' ELSE 'Falso' END AS menor;\nSELECT CASE WHEN 5 <= 3 THEN 'Verdadero' ELSE 'Falso' END AS menor_igual;\nSELECT CASE WHEN 5 >= 3 THEN 'Verdadero' ELSE 'Falso' END AS mayor_igual;\n\n--LOGICOS\nSELECT CASE WHEN 5 > 3 AND 5 < 10 THEN 'Verdadero' ELSE 'Falso' END AS logico_and;\nSELECT CASE WHEN 5 > 3 OR 5 < 10 THEN 'Verdadero' ELSE 'Falso' END AS logico_or;\nSELECT CASE WHEN NOT (5 BETWEEN 1 AND 10) THEN 'Fuera de rango' ELSE 'Dentro de rango' END AS resultado;\n\n--OPERADORES DE CONCATENACION\nSELECT CONCAT('Hola', ' ', 'mundo') AS concatenacion;\n\n--OPERADORES DE ASIGNACION\nDECLARE @mi_variable VARCHAR(50);\nSET @mi_variable = 'El igual(=) asigna valor a la variable';\n\n--OPERADORES DE RANGO\nSELECT CASE WHEN 5 BETWEEN 1 AND 10 THEN 'Dentro de rango' ELSE 'Fuera de rango' END AS rango;\nSELECT CASE WHEN 5 NOT BETWEEN 1 AND 10 THEN 'Dentro de rango' ELSE 'Fuera de rango' END AS rango;\n\n--OPERADORES DE EXISTENCIA\nSELECT CASE WHEN EXISTS (SELECT * FROM tabla WHERE columna = 'valor') THEN 'Existe' ELSE 'No existe' END AS existencia;\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/sql/eulogioep.sql",
    "content": "-- Creación de una tabla de ejemplo\nCREATE TABLE empleados (\n    id INT PRIMARY KEY,\n    nombre VARCHAR(50),\n    salario DECIMAL(10, 2),\n    departamento VARCHAR(50)\n);\n\n-- Inserción de datos de ejemplo\nINSERT INTO empleados (id, nombre, salario, departamento) VALUES\n(1, 'Juan', 30000, 'IT'),\n(2, 'María', 35000, 'Ventas'),\n(3, 'Carlos', 28000, 'IT'),\n(4, 'Ana', 40000, 'Recursos Humanos'),\n(5, 'Pedro', 32000, 'Ventas');\n\n-- 1. Operadores Aritméticos\nSELECT \n    'Suma' AS operacion, 5 + 3 AS resultado\nUNION ALL\nSELECT 'Resta', 10 - 4\nUNION ALL\nSELECT 'Multiplicación', 6 * 2\nUNION ALL\nSELECT 'División', 15.0 / 3\nUNION ALL\nSELECT 'Módulo', 17 % 5;\n\n-- 2. Operadores de Comparación\nSELECT \n    nombre, \n    salario,\n    CASE \n        WHEN salario > 30000 THEN 'Alto'\n        WHEN salario < 30000 THEN 'Bajo'\n        ELSE 'Medio'\n    END AS nivel_salario\nFROM empleados;\n\n-- 3. Operadores Lógicos\nSELECT *\nFROM empleados\nWHERE departamento = 'IT' AND salario > 25000;\n\n-- 4. Operadores de Conjunto\nSELECT departamento FROM empleados\nUNION\nSELECT 'Marketing' AS departamento;\n\n-- 5. Funciones de Agregación (equivalente a operadores en otros lenguajes)\nSELECT \n    AVG(salario) AS promedio_salario,\n    MAX(salario) AS salario_maximo,\n    MIN(salario) AS salario_minimo,\n    COUNT(*) AS total_empleados\nFROM empleados;\n\n-- 6. Subconsultas (una forma de control de flujo en SQL)\nSELECT nombre, salario\nFROM empleados\nWHERE salario > (SELECT AVG(salario) FROM empleados);\n\n-- 7. Joins (otra forma de combinar y controlar el flujo de datos)\nSELECT e1.nombre AS empleado, e2.nombre AS companero\nFROM empleados e1\nJOIN empleados e2 ON e1.departamento = e2.departamento AND e1.id < e2.id;\n\n-- 8. Estructuras de Control (usando procedimientos almacenados - la sintaxis puede variar según el DBMS)\nDELIMITER //\nCREATE PROCEDURE clasificar_salarios()\nBEGIN\n    DECLARE done INT DEFAULT FALSE;\n    DECLARE emp_nombre VARCHAR(50);\n    DECLARE emp_salario DECIMAL(10, 2);\n    DECLARE cur CURSOR FOR SELECT nombre, salario FROM empleados;\n    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;\n\n    OPEN cur;\n\n    read_loop: LOOP\n        FETCH cur INTO emp_nombre, emp_salario;\n        IF done THEN\n            LEAVE read_loop;\n        END IF;\n        \n        IF emp_salario > 35000 THEN\n            SELECT CONCAT(emp_nombre, ' tiene un salario alto');\n        ELSEIF emp_salario < 30000 THEN\n            SELECT CONCAT(emp_nombre, ' tiene un salario bajo');\n        ELSE\n            SELECT CONCAT(emp_nombre, ' tiene un salario medio');\n        END IF;\n    END LOOP;\n\n    CLOSE cur;\nEND //\nDELIMITER ;\n\n-- Llamada al procedimiento\nCALL clasificar_salarios();\n\n-- 9. DIFICULTAD EXTRA (adaptada a SQL)\n-- Imprimimos números pares entre 10 y 55, excluyendo 16 y múltiplos de 3\nWITH RECURSIVE numeros(n) AS (\n    SELECT 10\n    UNION ALL\n    SELECT n + 1 FROM numeros WHERE n < 55\n)\nSELECT n\nFROM numeros\nWHERE n % 2 = 0 \n  AND n != 16 \n  AND n % 3 != 0;"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/sql/idiegorojas.sql",
    "content": "/* \n01 - Operadores y estructuras de control \n*/\n\n\n/* Operadores aritmeticos */\n-- Se usan para realizar cálculos matemáticos sobre columnas numéricas.\n-- + (Suma)\n-- - (Resta)\n-- * (Multiplicación)\n-- / (División)\n-- % (Módulo, resto de una división)\n\nSELECT precio * 1.10 AS precio_con_iva FROM productos;\n\n-- Operadores de comparacion\n-- Se utilizan para comparar valores en condiciones, como en la cláusula WHERE.\n-- = (Igual)\n-- <> o != (Diferente)\n-- < (Menor que)\n-- > (Mayor que)\n-- <= (Menor o igual que)\n-- >= (Mayor o igual que)\n\nSELECT nombre FROM empleados WHERE salario > 3000;\n\n-- Operadores Lógicos\n-- Combinan condiciones para filtrar datos.\n-- AND (Y lógico: ambas condiciones deben ser ciertas)\n-- OR (O lógico: al menos una condición debe ser cierta)\n-- NOT (Negación: invierte el resultado de una condición)\n\nSELECT nombre FROM clientes WHERE ciudad = \"Madrid\" AND edad > 25;\n\n-- Operadores Especiales\n-- LIKE: Compara patrones en cadenas (con % para cualquier secuencia y _ para un solo carácter).\nWHERE nombre LIKE 'A%' (nombres que empiezan con A).\n-- IN: Comprueba si un valor está en una lista.\nWHERE id IN (1, 2, 3).\n-- BETWEEN: Filtra valores dentro de un rango.\nWHERE salario BETWEEN 2000 AND 5000.\n-- IS NULL / IS NOT NULL: Verifica si un valor es nulo o no.\nWHERE telefono IS NULL.\n\n\n/* Estrucutras de control */\n-- SQL es principalmente un lenguaje declarativo, lo que significa que especificas qué quieres obtener, no cómo hacerlo. \n-- Sin embargo, en algunos sistemas de bases de datos (como PostgreSQL, SQL Server o MySQL), se incorporan extensiones procedurales (como PL/SQL o T-SQL) que incluyen estructuras de control para escribir programas o scripts más complejos. \n-- Estas estructuras permiten manejar lógica condicional, bucles y más.\n\n-- 1. Condicionales: IF y CASE\n-- IF: Usado en bloques procedurales (no en SQL estándar puro).\nIF (SELECT COUNT(*) FROM empleados) > 10\n    PRINT 'Hay más de 10 empleados';\nELSE\n    PRINT 'Hay 10 o menos empleados';\n\n-- CASE: Similar a un \"switch\" o \"if-else\" en consultas SQL estándar.\nSELECT nombre,\n       CASE \n           WHEN salario > 5000 THEN 'Alto'\n           WHEN salario > 2000 THEN 'Medio'\n           ELSE 'Bajo'\n       END AS nivel_salario\nFROM empleados;\n\n-- 2. Bucles\n-- Solo están disponibles en lenguajes procedurales como PL/SQL o T-SQL, no en SQL puro.\n\n-- WHILE: Repite un bloque mientras una condición sea verdadera.\nDECLARE @contador INT = 0;\nWHILE @contador < 5\nBEGIN\n    PRINT 'Contador: ' + CAST(@contador AS VARCHAR);\n    SET @contador = @contador + 1;\nEND;\n\n-- FOR / LOOP: Varía según el sistema (por ejemplo, en PL/SQL de Oracle):\nFOR i IN 1..5 LOOP\n    DBMS_OUTPUT.PUT_LINE('Iteración: ' || i);\nEND LOOP;\n\n-- 3. Control de Excepciones\n-- En lenguajes como PL/SQL, puedes manejar errores.\nBEGIN\n    INSERT INTO empleados (id, nombre) VALUES (1, 'Juan');\nEXCEPTION\n    WHEN DUP_VAL_ON_INDEX THEN\n        DBMS_OUTPUT.PUT_LINE('Error: ID duplicado');\nEND;"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/sql/llonardo798.sql",
    "content": "/*\n * Este ejercicio se resuelve en base a SQL Server\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n-- Tipos de operadores en SQL \n\n-- 1. Operadores Aritméticos\n\nDECLARE @numero1 INT = 10;\nDECLARE @numero2 INT = 5;\nDECLARE @numero3 INT = 3;\n\nDECLARE @suma INT = @numero1 + @numero2;                     -- Suma\nDECLARE @resta INT = @numero1 - @numero2;                    -- Resta\nDECLARE @multiplicacion INT = @numero1 * @numero2;           -- Multiplicación\nDECLARE @division INT = @numero1 / @numero2;                 -- División entera\nDECLARE @producto INT = @numero1 % @numero3;                 -- Resto de la división\n\nPRINT CONCAT('Suma: ', @suma);                               -- Imprime 15\nPRINT CONCAT('Resta: ', @resta);                             -- Imprime 5\nPRINT CONCAT('Multiplicación: ', @multiplicacion);           -- Imprime 50\nPRINT CONCAT('División: ', @division);                       -- Imprime 2           \nPRINT CONCAT('Producto: ', @producto);                       -- Imprime 1\n\n\n\n-- 2. Operadores de Comparación\n\nDECLARE @igualQue VARCHAR(5) = CASE WHEN @numero1 = @numero2 THEN 'TRUE' ELSE 'FALSE' END;            -- Igual\nDECLARE @mayorQue VARCHAR(5) = CASE WHEN @numero1 > @numero2 THEN 'TRUE' ELSE 'FALSE' END;            -- Mayor que\nDECLARE @menorQue VARCHAR(5) = CASE WHEN @numero1 < @numero2 THEN 'TRUE' ELSE 'FALSE' END;            -- Menor que\nDECLARE @mayorIgual VARCHAR(5) = CASE WHEN @numero1 >= @numero2 THEN 'TRUE' ELSE 'FALSE' END;         -- Mayor o igual que\nDECLARE @menorIgual VARCHAR(5) = CASE WHEN @numero1 <= @numero2 THEN 'TRUE' ELSE 'FALSE' END;         -- Menor o igual que\nDECLARE @distinto VARCHAR(5) = CASE WHEN @numero1 <> @numero2 THEN 'TRUE' ELSE 'FALSE' END;           -- Distinto\n\nPRINT CONCAT('Igual que: ', @igualQue);                 -- Imprime 0\nPRINT CONCAT('Mayor que: ', @mayorQue);                 -- Imprime 1\nPRINT CONCAT('Menor que: ', @menorQue);                 -- Imprime 0\nPRINT CONCAT('Mayor o igual que: ', @mayorIgual);       -- Imprime 1\nPRINT CONCAT('Menor o igual que: ', @menorIgual);       -- Imprime 0\nPRINT CONCAT('Distinto: ', @distinto);                  -- Imprime 1\n\n\n\n-- 3. Operadores Lógicos\n\nDECLARE @edad INT = 16;\nDECLARE @estaAcompanado BIT = 0;\n\nDECLARE @puedeVerPelicula BIT = CASE WHEN @edad >= 18 OR (@edad >= 16 AND @estaAcompanado = 1) THEN 1 ELSE 0 END;\nPRINT CONCAT('Puede ver la película: ', @puedeVerPelicula);                                                         -- Imprime 1\nPRINT CONCAT('Puede ver la película: ', CASE WHEN NOT @puedeVerPelicula = 1 THEN 'TRUE' ELSE 'FALSE' END);          -- Imprime FALSE\n\n\n\n-- 4. Operadores de Conjuntos\n\n-- Crear tabla CLIENTES\nCREATE TABLE CLIENTES (ID INT PRIMARY KEY,Nombre VARCHAR(50),Ciudad VARCHAR(50));\n-- Insertar datos en CLIENTES\nINSERT INTO CLIENTES (ID, Nombre, Ciudad) VALUES (1, 'Ana', 'Madrid'), (2, 'Juan', 'Barcelona'), (3, 'María', 'Valencia'), (4, 'Pedro', 'Madrid'), (5, 'Laura', 'Sevilla'); \n\n-- Crear tabla EMPLEADOS\nCREATE TABLE EMPLEADOS (ID INT PRIMARY KEY, Nombre VARCHAR(50), Departamento VARCHAR(50), Activo BIT);\n-- Insertar datos en EMPLEADOS\nINSERT INTO EMPLEADOS (ID, Nombre, Departamento, Activo) VALUES(101, 'Juan', 'Ventas', 1),(102, 'María', 'Recursos Humanos', 0),(103, 'Carlos', 'IT', 1),(104, 'Ana', 'Marketing', NULL),(105, 'Pedro', 'Finanzas', 0);\n\nSELECT Nombre FROM CLIENTES UNION SELECT Nombre FROM EMPLEADOS;             -- UNION: Obtener todos los nombres de CLIENTES y EMPLEADOS (sin duplicados)\nSELECT Nombre FROM CLIENTES UNION ALL SELECT Nombre FROM EMPLEADOS;         -- UNION ALL: Obtener todos los nombres de CLIENTES y EMPLEADOS (con duplicados)\nSELECT Nombre FROM CLIENTES INTERSECT SELECT Nombre FROM EMPLEADOS;         -- INTERSECT: Obtener los nombres de los CLIENTES que también son EMPLEADOS\nSELECT Nombre FROM CLIENTES EXCEPT SELECT Nombre FROM EMPLEADOS;            -- EXCEPT: Obtener los nombres de los CLIENTES que no son EMPLEADOS\n\n\n\n-- 5. Operadores de Cadenas\n\nSELECT Nombre + ' del departamento de ' + Departamento AS INFORMACIÓNCLIENTE FROM EMPLEADOS;                -- Concatenar cadenas\nSELECT * FROM EMPLEADOS WHERE Nombre LIKE 'A%';                                                             -- LIKE: Buscar nombres que empiecen por 'A'\nSELECT * FROM CLIENTES WHERE Nombre LIKE '____a';                                                           -- LIKE: Buscar nombres que tengan 5 letras y terminen en 'a'\nSELECT LEN(Nombre) AS LongitudNombre FROM EMPLEADOS;                                                        -- LEN: Obtener la longitud de los nombres\nSELECT SUBSTRING(Departamento, 1, 5) AS Primeros10Caracteres FROM EMPLEADOS;                                -- SUBSTRING: Obtener los primeros 5 caracteres del Departamento \nSELECT REPLACE(Nombre, 'a', 'o') AS NuevoNombreRaro FROM CLIENTES;                                          -- REPLACE: Reemplazar 'a' por 'o' en los nombres\nSELECT UPPER(Nombre) AS NombreMayusculas, LOWER(Departamento) AS DepartamentoMinusculas FROM EMPLEADOS;     -- UPPER Convertir a mayúsculas y LOWER Convertir a minúsculas\n\n-- 6. Otros Operadores de verificación\n\nSELECT * FROM CLIENTES WHERE ID BETWEEN 2 AND 4;                                                                        -- Obtener los clientes cuyo ID está entre 2 y 4\nSELECT * FROM CLIENTES WHERE CIUDAD IN ('Madrid', 'Barcelona');                                                         -- Obtener los clientes que son de Madrid o Barcelona\nSELECT * FROM EMPLEADOS WHERE Activo IS NULL;                                                                           -- Obtener los empleados que no están activos\nSELECT * FROM EMPLEADOS WHERE Nombre IS NOT NULL;                                                                       -- Obtener los empleados cuyo nombre está registrado\nSELECT Nombre FROM CLIENTES c WHERE EXISTS (SELECT * FROM EMPLEADOS e WHERE e.Nombre = c.Nombre AND e.Activo = 1);      -- Obtener los clientes que se llaman igual que los empleados activos\n\n\n-- DIFICULTAD EXTRA - Crea un programa que imprima por consola todos los números comprendidos entre 10 y 55 (incluidos)\n-- pares, y que no son ni el 16 ni múltiplos de 3.\n\nDECLARE @numero INT = 10;\nDECLARE @limite INT = 55;\n\nWHILE @numero <= @limite\nBEGIN\n    IF @numero % 2 = 0 AND @numero <> 16 AND @numero % 3 <> 0\n    BEGIN\n        PRINT @numero;\n    END\n    SET @numero = @numero + 1;\nEND"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/sql/salkalero.sql",
    "content": "-- Operadores Aritméticos\n\nSELECT \"Suma: 5+2=\",(5+2);\nSELECT \"Resta: 5-2=\",(5-2);\nSELECT \"Multiplicación: 5x2=\",(5*2);\nSELECT \"División: 5/2=\",(5/2);\nSELECT \"Módulo: 5%2=\",(5%2);\n\n-- Operadores de Comparación\n\nSET @a := 25;\nSET @b := 125;\nSELECT \"Igual a: ¿25 es igual que 125?\", if (@a = @b, \"Verdadero\", \"Falso\");\nSELECT \"Diferente a: ¿25 es diferente que 125?\", if (@a <> @b, \"Verdadero\", \"Falso\");\nSELECT \"Mayor que : ¿25 es mayor que 125?\", if (@a > @b, \"Verdadero\", \"Falso\");\nSELECT \"Menor que: ¿25 es menor que 125?\", IF (@a < @b, \"Verdadero\", \"Falso\");\nSELECT \"Mayor o igual que: ¿25 es mayor o igual que 125?\", IF (@a >= @b, \"Verdadero\", \"Falso\");\nSELECT \"Menor o igual que: ¿25 es menor o igual que 125?\", IF (@a <= @b, \"Verdadero\", \"Falso\");\n\n-- Operadores Lógicos\n\nSET @c := 2;\nSET @d := 1;\nSELECT \"Operando AND: c y d =\",( @c AND @d );\nSELECT \"Operando OR: c or d =\",( @c OR @d );\nSELECT \"Operando NOT: c not d =\",( NOT @c);\n\n\n-- Operadores de Asignación\n\nSET @a := 5 , @b := 25 ;\nSET @suma = @a + @b;\nSELECT'Resultado de asignación := ',(@suma);\n\n-- Estructura de control\n\ndelimiter //\n\ncreate procedure Sumar( in Valor1 int,in Valor2 int )\nbegin\n\tSET @1 := Valor1 , @2 := Valor2;\n\tSELECT \"Suma: a+b=\",(@1+@2);\nend //\n\ndelimiter ;\n\ndelimiter //\n\ncreate procedure Igualdad(in valor1 int, in valor2 int)\nbegin\n\tSET @a := valor1;\n\tSET @b := valor2;\n\tSELECT \"¿Primera cifra es mayor o igual?\",@a,@b, IF (@a >= @b, \"Verdadero\", \"Falso\");\nend //\n\ndelimiter ;\n\n\ndelimiter //\n\ncreate procedure Condicional(in a int, in b int)\nbegin\n\tdeclare resultado char(20);\n    if a > b then\n\t\tset resultado = \"a es mayor\";\n\telseif a < b then\n\t\tset resultado = \"b es mayor\";\n\telse\n\t\tset resultado = \"a y b son iguales\";\n\tend if;\n    select resultado;\nend //\n\ndelimiter ;\n\n\ndelimiter //\n\ncreate procedure Mes(in mes int)\nbegin\n\tdeclare resultado char(50);\n    case\n\t\twhen mes = 1 then set resultado = \"Enero\";\n        when mes = 2 then set resultado = \"Febrero\";\n        when mes = 3 then set resultado = \"Marzo\";\n        when mes = 4 then set resultado = \"Abril\";\n        when mes = 5 then set resultado = \"Mayo\";\n        when mes = 6 then set resultado = \"Junio\";\n        when mes = 7 then set resultado = \"Julio\";\n        when mes = 8 then set resultado = \"Agosto\";\n        when mes = 9 then set resultado = \"Septiembre\";\n        when mes = 10 then set resultado = \"Octubre\";\n        when mes = 11 then set resultado = \"Nobiembre\";\n        when mes = 12 then set resultado = \"Diciembre\";\n        else set resultado= \"Mes inválido, por favor indique del 1 al 12\";\n\tend case;\n    select resultado;\nend //\n\ndelimiter ;\n\n\n-- Extra\n\nDELIMITER //\n\nCREATE PROCEDURE Extra()\nBEGIN\n    DECLARE counter INT DEFAULT 10;\n\n    WHILE counter <= 55 DO\n        IF counter % 2 = 0 AND counter <> 16 AND counter % 3 <> 0 THEN\n            SELECT counter AS number;\n        END IF;\n        SET counter = counter + 1;\n    END WHILE;\nEND //\n\nDELIMITER ;\n\ncall sumar(500,512);\ncall igualdad(24,25);\ncall Condicional(22,22);\ncall Mes(3);\ncall Extra()"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/swift/18miguelgalarza.swift",
    "content": "//: [Previous](@previous)\n\n/*\n * EJERCICIO 01: 18miguelgalarza.swift\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n \n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n \n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\nimport Foundation\n\nfunc operadorAritmetico(_ valor1:Int, _ valor2:Int, _ operacion:String) -> Double{\n\n    switch operacion {\n    case \"suma\":\n        return Double(valor1 + valor2)\n    case \"resta\":\n        return Double(valor1 - valor2)\n    case \"multiplicacion\":\n        return Double(valor1 * valor2)\n    case \"division\":\n        return Double(valor1 / valor2)\n    case \"modulo\":\n        return Double(valor1 % valor2)\n    default:\n        return Double(-500)\n    }\n\n}\n\nfunc operadorLogico(_ valor1:String?, _ valor2:String?, _ operacion:String) -> String{\n\n    switch operacion {\n    case \"AND\":\n        \n        if valor1  != nil && valor2 != nil {\n            return \"Las variables no son nulas\"\n        }else {\n            return \"existe almenos una variable nula\"\n        }\n        \n    case \"OR\":\n        \n        if valor1  != nil || valor2 != nil {\n            return \"existe almenos una variable nula\"\n        }else {\n            return \"Las variables no son nulas \"\n        }\n    case \"NOT\":\n        return String(-500)\n\n    default:\n        return String(-500)\n    }\n\n}\n\n\nfunc operadorComparacion(_ valor1:Int, _ valor2:Int, _ operacion:String) -> String{\n\n    switch operacion {\n    case \"comparacion\":\n        if valor1 > valor2 {\n            return \"\\(valor1) es mayor que \\(valor2)\"\n        }else {\n            return \"\\(valor1) es menor que \\(valor2)\"\n        }\n\n    default:\n        return String(-500)\n    }\n\n}\n\nfunc buscaNumeroEnArreglo (_ arreglo:[Int], _ valor:Int) -> Bool {\n    \n    for num in arreglo {\n        if num == valor{\n            return true\n        }\n    }\nreturn false\n\n}\n\nprint(\"********************* 00 Control de excepciones ***********************\")\n\nenum MiError: Error {\n    case miError\n    case ErrorConocido\n}\n\nfunc funcionQueLanzaError() throws {\n    throw MiError.miError\n}\n\ndo {\n    try funcionQueLanzaError()\n}catch MiError.miError{\n    print(\"Se produjo un error de tipo MiError.miError.\")\n}catch {\n    print(\"Se produjo un error.\")\n}\n    \nprint(\"********************* 01 Aritmético y Asignacion ***********************\")\n\nprint(\"\\u{2713} El resultado de la suma es: \\(Int(operadorAritmetico(2,5,\"suma\")))\")\nprint(\"\\u{2713} El resultado de la resta es: \\(Int(operadorAritmetico(2,5,\"resta\")))\")\nprint(\"\\u{2713} El resultado de la multiplicación es: \\(operadorAritmetico(2,5,\"multiplicacion\"))\")\nprint(\"\\u{2713} El resultado de la división es: \\(operadorAritmetico(10,2,\"division\"))\")\nprint(\"\\u{2713} El resultado de la división es: \\(operadorAritmetico(5,3,\"modulo\"))\")\n\n//suma y asignación\n\nvar numero = 5\n    numero += 3\n\nprint(\"\\u{2713} El resultado del suma y asignación es: \\(numero) \")\n\n//resta y asignación\n\nvar numero1 = 5\n    numero -= 3\n\nprint(\"\\u{2713} El resultado del resta y asignación es: \\(numero1) \")\n\n//multiplicación y asignación\n\nvar numero2 = 5\n    numero *= 3\n\nprint(\"\\u{2713} El resultado del multiplicación y asignación es: \\(numero2) \")\n\n//división y asignación\n\nvar numero3 = 5\n    numero /= 3\n\nprint(\"\\u{2713} El resultado del división y asignación es: \\(numero3) \")\n\n//módulo y asignación\n\nvar numero4 = 5\n    numero /= 3\n\nprint(\"\\u{2713} El resultado del módulo y asignación es: \\(numero4) \")\n\n//Asignacion de tipo  \"??\"\nlet nombre: String? = nil\nlet nombreDefecto = nombre ?? \"Usuario\"\n\n\nprint(\"********************* 02 Comparacion ***********************\")\n\nprint(\"\\u{2713} Ejemplo de operador lógico AND (Los números no deben ser nulos) : \\(operadorLogico(\"1\",\"1\",\"AND\"))\")\nprint(\"\\u{2713} Ejemplo de operador lógico OR (Debe haber almenos un variable nulo) : \\(operadorLogico(nil,\"1\",\"OR\"))\")\nprint(\"\\u{2713} Ejemplo de operador comparación (Qué variable es mayor?) : \\(operadorComparacion(10,11,\"comparacion\"))\")\n\n\n// Guard : usado para validaciones tempranas, puedes condicionar, iterar de forma rapida, esto ayuda a optimizar los recursos.\nlet patinetas = [\"skateboard\", \"longboards\",\"penny\"]\n\nguard let patin = patinetas.last else {\n    \n    print(\"No existe patineta\")\n    throw MiError.ErrorConocido\n}\n\nprint(\"\\u{2713} Ejemplo de guard para buscar : \\(patin)\")\n\n// Defer\nvar score = 1\nif score < 10 {\n    defer {\n        print(score)\n    }\n    score += 5\n}\n\n\n\nprint(\"********************* 03 Identidad ***********************\")\n\nclass pruebaIdentidad{\n/**\n Clase para hacer la prueba de refereia al mismo objeto de memoria\n */\n}\n\nlet objeto1 = pruebaIdentidad()\nlet objeto2 = objeto1\n\nif objeto1 === objeto2 {\n    print(\"objeto1 y objeto2 hacen referencia al mismo objeto en memoria.\")\n} else {\n    print(\"objeto1 y objeto2 no hacen referencia al mismo objeto en memoria.\")\n}\n\nprint(\"********************* 04 Iterar ***********************\")\n// se incluye Condicionales ternarias\n\nlet arregloDeNumeros = [1,2,3,4,5,6,7,8,9]\n//func output: bool\nprint(\"\\u{2713} Ejemplo de buscar numero en arreglo : \\( String(buscaNumeroEnArreglo(arregloDeNumeros,2) ? \"existe\" : \"no existe\" ))\")\n\n// While\nvar cont = 0\n\nwhile cont < 5 {\nprint(\"Iterando con While  \\(cont)\")\n    cont += 1\n}\n\n// Repeat-While\nvar cont01 = 0\n\nrepeat {\nprint(\"Iterando con Repeat While  \\(cont01)\")\n    cont01 += 1\n} while cont01 < 5\nprint(\"\\n\")\n\n\nprint(\"********************* 05 DIFICULTAD EXTRA (opcional): ***********************\")\n\n/*\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\nfunc dificultadExtra (){\n    \n    for numero in 10...55 {\n      \n        if (numero % 2 ) == 0 &&  (numero % 3 ) != 0 && numero != 16 {\n            print(\"El número \\(numero) es par, no es múltiplo de 3 y no es 16\")\n        }\n    }\n    \n}\n\ndificultadExtra ()\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/swift/MarcSL2014.swift",
    "content": "// Operadores Aritmeticos\r\n\r\nvar sum = 1 + 1 // Suma\r\nvar rest = 1 - 1 // Resta\r\nvar mult = 1 * 1 // Multiplicación\r\nvar div = 1 / 1 // División\r\nvar mod = 1 % 1 // Módulo\r\n\r\n// Operadores Lógicos\r\n\r\nvar and = true && true\r\nvar or = true || false\r\nvar not = !true\r\n\r\n// Operadores Comparacion\r\n\r\nvar mayor = 3 > 1\r\nvar menor = 1 < 3\r\nvar igual = 1 == 1\r\nvar noIgual = 2 != 1\r\nvar mayorOIgual = 1 >= 1\r\nvar menorOIgual = 1 <= 1\r\n\r\nprint(mayor)\r\nprint(menor)\r\nprint(igual)\r\nprint(noIgual)\r\nprint(mayorOIgual)\r\nprint(menorOIgual)\r\nprint(and)\r\nprint(or)\r\nprint(not)\r\nprint(sum)\r\nprint(rest)\r\nprint(mult)\r\nprint(div)\r\nprint(mod)"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/swift/PeibolStrike.swift",
    "content": "//import UIKit\n/*\n* EJERCICIO:\n* - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n*   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n*   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n* - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n*   que representen todos los tipos de estructuras de control que existan\n*   en tu lenguaje:\n*   Condicionales, iterativas, excepciones...\n* - Debes hacer print por consola del resultado de todos los ejemplos.\n*\n* DIFICULTAD EXTRA (opcional):\n* Crea un programa que imprima por consola todos los números comprendidos\n* entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n*\n* Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n*/\n\n// Operadores Aritméticos\nlet suma = 2 + 3\nlet resta = 8 - 3\nlet multiplicacion = 4 * 3\nlet division = 10 / 2\nlet modulo = 5 % 2\n\nprint(\"Los operadores aritméticos son: Suma, Resta, Multiplicación, División y Módulo\")\nprint(\"Suma: \\(suma) \\nResta: \\(resta) \\nMultiplicación: \\(multiplicacion) \\nDivisión: \\(division) \\nMódulo: \\(modulo) \\n\")\n\n// Operadores Lógicos\nlet operadorNot = !false\nlet operadorAnd = true && false\nlet operadorOr = true || false\n\nprint(\"Los operador lógicos son: NOT(!), AND(&&) y OR(||)\")\nprint(\"Operador lógico NOT: \\(operadorNot) \\nOperador lógico AND: \\(operadorAnd) \\nOperador lógico OR: \\(operadorOr) \\n\")\n\n//Operadores de Comparación\nlet igual = 2 == 2\nlet noIgual = 2 != 4\nlet mayor = 8 > 3\nlet mayorIgual = 7 >= 6\nlet menor = 9 < 2\nlet menorIgual = 9 <= 16\n\nprint(\"Los operadores de comparación son: igual(==), no igual(!=), mayor(>), menor(<), mayor o igual(>=) y menor o igual(<=)\")\nprint(\"Operador de comparación igual: \\(igual) \\nOperador de comparación no igual: \\(noIgual) \\nOperador de comparación mayor: \\(mayor) \\nOperador de comparación menor: \\(menor) \\nOperador de comparación mayor o igual: \\(mayorIgual) \\nOperador de comparación menor o igual: \\(menorIgual) \\n\")\n\n// Operadores de asignación\nprint(\"Los operadores de asignación sirven para inicializar o actualizar el valor de una variable\")\nvar asignarValor = 11\nasignarValor += 4\nprint(\"Aqui sumamos: \\(asignarValor)\")\nasignarValor -= 5\nprint(\"Aqui restamos: \\(asignarValor)\")\nasignarValor *= 2\nprint(\"Aqui multiplicamos: \\(asignarValor)\")\nasignarValor /= 5\nprint(\"Aqui dividimos: \\(asignarValor)\")\nprint(\"Esto se realiza sobre el útlimo valor que va teniendo nuestra variable \\n\")\n\n// Operadores de Identidad\nclass Persona {\n    var nombre: String\n\n    init(nombre: String) {\n        self.nombre = nombre\n    }\n}\nlet persona1 = Persona(nombre: \"Pablo\")\nlet persona2 = Persona(nombre: \"Brais\")\nprint(\"Los operadores de identidad son: Idéntico a (===) y No idéntico a (!==)\")\nif persona1 === persona2 {\n    print(\"persona1 y persona2 tienen el mismo valor\")\n} else {\n    print(\"persona1 y persona2 no tienen el mismo valor\")\n}\nif persona1 !== persona2 {\n    print(\"persona1 y persona2 no tienen el mismo valor \\n\")\n} else {\n    print(\"persona1 y persona2 tienen el mismo valor \\n\")\n}\n\n// Operadores de pertenencia\nprint(\"Los operadores de pertenencia son: constaint, constaint(where: ) y isSubset(of: )\")\nlet numeros = [1, 2, 3, 4, 5]\n\nif numeros.contains(3) {\n    print(\"El número 3 está en el array\")\n} else {\n    print(\"El número 3 no está en el array\")\n}\n\nlet nombres = [\"Pablo\", \"Juan\", \"Brais\", \"Carlos\"]\n\nif nombres.contains(where: { $0.count > 4 }) {\n    print(\"Hay nombres con más de 4 caracteres en la lista\")\n} else {\n    print(\"No hay nombres con más de 4 caracteres en la lista\")\n}\n\nlet conjunto1: Set<Int> = [1, 2, 3]\nlet conjunto2: Set<Int> = [2, 3]\n\nif conjunto2.isSubset(of: conjunto1) {\n    print(\"El conjunto2 es un subconjunto de conjunto1  \\n\")\n} else {\n    print(\"El conjunto2 no es un subconjunto de conjunto1 \\n\")\n}\n\n// Operadores de bits\nprint(\"Los operadores de bits son: AND(&), OR(|), XOR(^), NOT(~), Desplazamiento a la izquierda(>>) y Desplazamiento a la derecha(<<)\")\nlet resultadoAnd = 0b1010 & 0b1100\nlet resultadoOr = 0b1010 | 0b1100\nlet resultadoXor = 0b1010 ^ 0b1100\nlet resultadoNot = ~0b1010\nlet resultadoDerecha = 0b0010 << 1\nlet resultadoIzquierda = 0b1000 >> 2\nprint(\"AND: \\(resultadoAnd) \\nOR: \\(resultadoOr) \\nXOR: \\(resultadoXor) \\nNOT \\(resultadoNot) \\nDesplazamiento a la Derecha: \\(resultadoDerecha) \\nDesplazamiento a la Izquierda: \\(resultadoIzquierda) \\n\")\n\n// Estructuras de Control\n\n// Condicionales\nprint(\"Las estructuras de control condicionales son: if, switch, guard y condicionales ternarias\")\n    // if\nlet numero = 20\nif numero % 3 == 0 {\n    print(\"IF: El número \\(numero) es impar \")\n} else {\n    print(\"IF: El número \\(numero) es par\")\n}\n    // switch\nlet opcion = 2\n\nswitch opcion {\n    case 1:\n        print(\"SWITCH: Opción 1 seleccionada\")\n    case 2:\n        print(\"SWITCH: Opción 2 seleccionada\")\n    default:\n        print(\"SWITCH: Opción no reconocida\")\n}\n\n    // guard\nfunc validarEdad(edad: Int) {\n    guard edad >= 18 else {\n        print(\"GUARD: Eres menor de edad\")\n        return\n    }\n\n    print(\"GUARD: Eres mayor de edad\")\n}\n\nvalidarEdad(edad: 20)\n\n    // Condicionales ternarias\nlet esPar = 10 % 2 == 0 ? true : false\nprint(\"Condicionales ternarias: \\(esPar) \\n\")\n\n\n// Iterativas\nprint(\"Las estructuras de control iterativas son: For-In, While y Repeat-While\")\n    // For-In\nlet numeros1 = [1, 2, 3, 4, 5]\n\nfor numero in numeros1 {\n    print(numero)\n}\n\n    // While\nvar contador = 0\n\nwhile contador < 5 {\n    print(\"El contador en la estructura de control While vale \\(contador)\")\n    contador += 1\n}\n\n    // Repeat-While\nvar contador1 = 0\n\nrepeat {\n    print(\"El contador en la estructura de control Repeat-While vale \\(contador1)\")\n    contador1 += 1\n} while contador1 < 5\nprint(\"\\n\")\n\n// Excepciones\nenum ErrorPersonalizado: Error {\n    case errorPersonalizado\n}\n\nfunc lanzarExcepcion() throws {\n    throw ErrorPersonalizado.errorPersonalizado\n}\n\ndo {\n    try lanzarExcepcion()\n    print(\"Excepciones: No hay errores\")\n} catch ErrorPersonalizado.errorPersonalizado {\n    print(\"Excepciones: Hay un error personalizado\")\n} catch {\n    print(\"Excepciones: Hay un error\")\n}\nprint(\"\\n\")\n\n// Ejercicio Opcional\n/*\n* Crea un programa que imprima por consola todos los números comprendidos\n* entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n*/\n\nfor numero in 10...55 {\n    if numero % 2 == 0 && numero != 16 && numero % 3 != 0 {\n        print(\"El número \\(numero) es par, no es 16 y no es múltiplo de 3\")\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/swift/PineroDev.swift",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\nimport Foundation\n\n//Operadores Aritméticos\n\nvar suma: Double = 10 + 20\nvar resta: Double = 4.6 - 2.3\nvar multiplicacion: Double = 2.5 * 3.2\nvar division: Double = 10 / 2\nvar modulo: Int = 5 % 2\n\n//Operadores Logicos\n\nvar AND: Bool = true && false\nvar OR: Bool = true || false\nvar NOT: Bool = !true\n\n//Operadores de asignación\nvar asigSuma: Int = 2\nasigSuma += 10\nvar asigResta: Int = 20\nasigResta -= 1\nvar asigMultiplicacion: Int = 3\nasigMultiplicacion *= 2\nvar asigDivision: Int = 7\nasigDivision /= 2\nvar asigModulo: Int = 4\nasigModulo %= 2\n\n//Operadores de comparación\nvar operadorIgual: Bool = 10 == 10\nvar operadorDiferente: Bool = 7 != 11\nvar operadorMenor: Bool = 5 < 13\nvar operadorMenorIgual: Bool = 45 <= 45\nvar operadorMayor: Bool = 16 > 2\nvar operadorMayorIgual: Bool = 34 >= 65\n\n//----------------------------------------\n\n// Estructuras de control\n\n//For - in\nlet palabra: String = \"Mandarina\"\nfor letra in palabra {\n    print(letra)\n}\n\n//While\nvar contador: Int = 1\nwhile contador <= 5 {\n    print(contador)\n    contador += 1\n}\n\n// if (Condicional)\nvar contador2: Int = 1\nif contador2 < 100{\n    print(\"contador2 es menor que 100\")\n}else {\n    print (\"contador2 es mayor que 100\")\n}\n\n\n// Guard (Condicional)\nvar numRandom: Int = (Int.random(in: 1..<100))\nfunc pruebaGuard(){\n    guard numRandom  >= 50 else {\n        print(numRandom, \"es menor que 50\" )\n        return\n    }\n    \n    print(numRandom, \" es mayor que 50\")\n}\npruebaGuard()\n\n\n//Switch (Condicional)\nvar numSubmarinos: Int = 5\nswitch numSubmarinos {\ncase 0:\n    print(\"No hay submarinos en el mar\")\ncase 1:\n    print(\"Hay un submarino en el mar\")\ndefault:\n    print(\"Hay \\(numSubmarinos) submarinos en el mar\")\n}\n\n//-----------------------------------------\n\n\nfor num in 10...55 {\n    if num == 16{\n        \n    }else if num % 3 == 0{\n        \n    }else {\n        print(num)\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/swift/allbertoMD.swift",
    "content": "import Foundation\n\n// Operadores Aritméticos\nlet addition = 11 + 33\nlet subtaction = 99 - 10\nlet multiplicacion: Int = 4 * 4\nlet division: Double = 140 / 3\nlet modulus: Int = 720 % 420\n\nprint(\"\\nOperadores Aritméticos\\n\")\nprint(\"Resultado del aperador de suma: \\(addition)\")\nprint(\"Resultado del operador de resta: \\(subtaction)\")\nprint(\"Resultado del operador de multiplicación: \\(multiplicacion)\")\nprint(\"Resultado del operador de división: \\(division)\")\nprint(\"Resultado del operador de modulo \\(modulus)\")\n\n\n// Operadores de Asignación\nvar numberByAssignment: Int = 777\nlet assignmetSimbol: Int = numberByAssignment\nvar additionAssignment: Int = 222\nadditionAssignment += numberByAssignment\nvar subtractionAssignment: Int = 300\nsubtractionAssignment -= numberByAssignment\nvar multiplicationAssignment: Int = 10\nmultiplicationAssignment *= numberByAssignment\nvar divisionAssignment: Double = 1423\ndivisionAssignment /= Double(numberByAssignment)\nvar modulusAssignment: Int = 5555\nmodulusAssignment %= numberByAssignment\n\nprint(\"\\nOperadores de Asignación\\n\")\nprint(\"Resultado de suma asignación: \\(additionAssignment)\")\nprint(\"Resultado de resta adignación: \\(subtractionAssignment)\")\nprint(\"Resultado de multiplicación asignación: \\(multiplicationAssignment)\")\nprint(\"Resultado de división asignación: \\(divisionAssignment)\")\nprint(\"Resultado de modulo asignación: \\(modulusAssignment)\")\n\n\n// Operadores de Igualdad\nlet equalTo = 0 == 0\nlet notEqualTo = 10 != 10\nlet greaterThan = 12 > 11\nlet lessThan: Bool = 90 < 99\nlet greaterThanOrEqualTo: Bool = 24 >= 124\nlet lessThanOrEqualTo: Bool = -1 <= 0\n\nprint(\"\\nOperadores de Igualdad\\n\")\nprint(\"Resultado de igual que: \\(equalTo)\")\nprint(\"Resultado de no igual que: \\(notEqualTo)\")\nprint(\"Resultado de mayor que: \\(greaterThan)\")\nprint(\"Resultado de menor que: \\(lessThan)\")\nprint(\"Resultado de mayor o igual que: \\(greaterThanOrEqualTo)\")\nprint(\"Resultado de menor o igual que: \\(lessThanOrEqualTo)\")\n\n\n// Operadores de Logicos\nlet and: Bool = true == true && false == false\nlet or: Bool = 1 > 11 || \"or\" == \"or\"\nlet not: Bool = !false\n\nprint(\"\\nOperadores Logicos\\n\")\nprint(\"Resultado de AND: \\(and)\")\nprint(\"Resultado de OR: \\(or)\")\nprint(\"Resultado de NOT: \\(not)\")\n\n// Operador Ternario\nlet ternaryOerator: String = true ? \"Hola\" : \"Adios\"\n\nprint(\"\\nOperador Ternario\\n\")\nprint(\"Resultado del operador ternario: \\(ternaryOerator)\")\n\n\n// Operadores de Rango\nlet closedRange: ClosedRange = 0...10\nlet range: Range = 11..<21\nvar numbersOfTheClosedRange: [Int] = []\nvar numbersOfTheRange: [Int] = []\nfor n in closedRange {\n    numbersOfTheClosedRange.append(n)\n}\nfor n in range {\n    numbersOfTheRange.append(n)\n}\n\nprint(\"\\nOperadores de Rango\\n\")\nprint(\"Resultade del rango cerrado: \\(numbersOfTheClosedRange)\")\nprint(\"Resultado del rango: \\(numbersOfTheRange)\")\n\n\n// Operadores de Bits\nlet firstBinary =  43 //0b00101011\nlet secondBinary = 56 //0b00111000\nlet bitwiseAND = firstBinary & secondBinary\nlet bitwiseOR: Int = firstBinary | secondBinary\nlet bitwiseXOR: Int = firstBinary ^ secondBinary\nlet leftShift: Int = firstBinary << 1\nlet rightShift: Int = secondBinary >> 1\n\nprint(\"\\nOperadores d Bits\\n\")\nprint(\"Resultado del operador de Bit AND: \\(bitwiseAND)\")\nprint(\"Resultade del operador de Bit OR: \\(bitwiseOR)\")\nprint(\"Resultado del operador de Bit XOR: \\(bitwiseXOR)\")\nprint(\"Resultado del operador de Bit desplazamiento a la izauierda: \\(leftShift)\")\nprint(\"Resultado del operador de Bit desplazamiento a la derecha: \\(rightShift)\")\n\n\n// Exepción\nenum MyError: Error {\n    case error1\n    case error2\n}\nfunc functionExample() throws {\n    MyError.error1\n}\nprint(\"\\nExepción\\n\")\n\ndo {\n    try functionExample()\n    print(\"Resusltade de exepción con exito\")\n} catch MyError.error1 {\n    print(\"Resultado de exepción fallida\")\n} catch MyError.error2 {\n    print(\"Resultado de exepción fallida\")\n}\n\n\n// Estructura de control if else\nprint(\"\\nEstructura de Control if else\\n\")\nif true == true {\n    print(\"Resultado del la estructura de control if\")\n} else {\n    print(\"Resultado de la estructura de control else\")\n}\n\n\n// Estructura de Control switch\nprint(\"\\nEstructura de Control switch\\n\")\nlet int: Int = 100\nswitch int {\n    case 10:\n        print(\"Resultado de la estructura de control switch: \\(int)\")\n    case 100:\n        print(\"Resultado de la estrura de control switch: \\(int)\")\n    case 1000:\n        print(\"Resultado de la estructura de control switch \\(int)\")\n    default:\n        print(\"Resultado de la estructura de control switch: defaul\")\n}\n\n\n// Estructura de Iteración for\nlet word: [String] = [\"s\", \"w\", \"i\", \"f\", \"t\"]\nvar swiftWord: String = \"\"\nfor character in word {\n    swiftWord.append(character)\n}\nprint(\"\\nEstructura de Iteración for\\n\")\nprint(\"Resultado de la estructura de iteración for: \\(swiftWord)\")\n\n\n// Estructura de Iteración while\nvar element: Int = 20\nwhile element < 40 {\n    element += 1\n}\nprint(\"\\nEstructura de Iteración while\\n\")\nprint(\"Resultado de la estructura de iteración while: \\(element)\")\n\n\n// Estructura Iterative repeat while\nrepeat {\n    element -= 1\n} while element > 20\n\nprint(\"\\nEstructura de Iteración repeat while\\n\")\nprint(\"Resultado de la estructura de iteración repeat while: \\(element)\")\n\n\n\n\n// Dificultad Extra\nprint(\"\\nEjercició Dificultad Extra\\n\")\nfor n in 10...55 {\n    if n == 16 || n % 3 == 0 {\n        continue\n    }\n    if n % 2 == 0 {\n        print(n)\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/swift/blackriper.swift",
    "content": "\n// operadores aritmeticos \n\nlet a = 5\nlet b = 3\nprint(\"Aritmeticos:\")\nprint(\"5 + 3 = \\(a + b)\")\nprint(\"5 - 3 = \\(a - b)\")\nprint(\"5 * 3 = \\(a * b)\")\nprint(\"5 / 3 = \\(5 / 3)\")\nprint(\"5 % 3 = \\(5 % 3)\")\n\n// operadores de comparacion\nprint(\"\\nDe comparacion:\")\nprint(\"5 == 5 --> \\(5 == 5)\")\nprint(\"10 != 5 --> \\(10 != 5)\")\nprint(\"8 > 3 --> \\(8 > 3)\")\nprint(\"2 < 7 --> \\(2 < 7)\")\n\n// operadores de asignacion\nvar edad = 48\nprint(\"\\nDe asignacion:\")\nprint(\"Mi edad actual: \\(edad)\")\nprint(\"Mi edad el año que viene: \\(edad + 1)\")\n\n// operadores de identidad  \nlet objeto1 = \"Hola\"\nlet objeto2 = \"Hola\"\nlet sonIguales = objeto1 == objeto2\nprint(\"\\nDe identidad:\")\nprint(\"Objetos iguales: \\(sonIguales)\")\n\n//operadores logicos\n\nlet and: Bool = true == true && false == false\nlet or: Bool = 1 > 11 || \"or\" == \"or\"\nlet not: Bool = !false\nprint(\"\\nOperadores logicos:\")\nprint(\"AND: \\(and)\")\nprint(\"OR: \\(or)\")\nprint(\"NOT: \\(not)\")\n\n\n//estructuras de control\n\nlet c = 5\nlet d = 3\nprint(\"\\nEstructuras de control:\")\nif c == d {\n    print(\"a es igual a b\")\n} else {\n    print(\"a no es igual a b\")\n}\n\nvar heroe=\"Flash\"\n\nswitch(heroe) {\n    case \"Flash\":\n        print(\"Flash\")\n    case \"Batman\":\n        print(\"Batman\")\n    case \"Superman\":\n        print(\"Superman\")\n    default:\n        print(\"No se reconoce\")\n}\n\n// estructuras de repeticion \n\nprint(\"bucle for\")\n\nfor i in 1...5 {\n    print(i)\n}\n\nprint(\"bucle while\")\nvar i=0\nwhile i<5 {\n    print(i)\n    i+=1\n}\n\nprint(\"bucle repeat while\")\nvar j=0\nrepeat {\n    print(j)\n    j+=1\n} while j<5\n\n// excepciones \nenum ErrorPersonalizado: Error {\n    case errorPersonalizado\n}\n\nfunc lanzarExcepcion() throws {\n    throw ErrorPersonalizado.errorPersonalizado\n}\n\nprint(\"Reto adicional\")\n// reto adicional\nfor i in 10...55{\n    if i % 2 == 0 && i != 16 && i % 3 != 0 {\n        print(i)\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/swift/didacdev.swift",
    "content": "import Foundation\n\n//----------------------- Operadores -------------------\n// Asignación\nlet nombre = \"Diego\"\nvar edad: Int = 27\nprint(\"\\(nombre) tiene \\(edad) años\")\n\n// Aritméticos\n\nlet suma = 1 + 2\nprint(\"Suma: \\(suma)\")\n\nlet resta = 3 - 2\nprint(\"Resta: \\(resta)\")\n\nlet multiplicacion = 3 * 2\nprint(\"Multiplicación: \\(multiplicacion)\")\n\nlet division = 10 / 2\nprint(\"División: \\(division)\")\n\nlet concatenacion = \"hello \" + \"world\"\nprint(concatenacion)\n\nlet resto = 9 % 8\nprint(\"Resto: \\(resto)\")\n\nlet tres = 3\nlet negativo = -tres\nprint(\"Negativo: \\(negativo)\")\n\nlet cuatro = -4\nlet positivo = +tres\nprint(\"Positivo: \\(positivo)\")\n\nvar compuesto = 2\ncompuesto += 2\nprint(\"Compuesto: \\(compuesto)\")\n\n//  Comparación\nprint(1 == 1)\nprint(2 != 1)\nprint(2 > 1)\nprint(1 < 2)\nprint(1 >= 1)\nprint(2 <= 1)\n\n// Ternaria\n// pregunta ? respuesta1 : respuesta2\nlet resultado = 2 + 1 == 3 ? true : false\nprint(\"Ternaria: \\(resultado)\")\n\n// Nil-Coalescing\nvar color: String? = nil\nvar colorCoche = color != nil ? \"Es \\(color!)\" : \"Es nulo\"\nprint(colorCoche)\n\ncolor = \"rojo\"\ncolorCoche = \"Es \\(color!)\" ?? \"Es nulo\"\nprint(colorCoche)\n\n// Rango\nfor index in 1...5 {\n    print(index)\n}\n\nfor index in 1..<5 {\n    print(index)\n}\n\nlet names = [\"Anna\", \"Alex\", \"Brian\", \"Jack\"]\nfor name in names[2...] {\n    print(name)\n}\n\n// Lógicos\nprint(!(1 == 1))\nprint(1 == 1 && 2 > 1)\nprint(1 == 1 || 2 < 1)\n\n// --------------------------------- Estructuras de control --------------------------------\n\n// Bucles for-in\nlet nombres = [\"Anna\", \"Alex\", \"Brian\", \"Jack\"]\nfor nombre in nombres {\n    print(\"Hello, \\(nombre)!\")\n}\n\n// Bucle While \nvar numero = 0\nwhile numero < 4 {\n    print(numero)\n    numero += 1\n\n}\n\n// Bucle Repeat-while\nrepeat {\n    print(numero)\n    numero += 1\n} while numero < 8\n\n// Condicional if\nif numero == 7 {\n    print(\"El número es 7\")\n} else {\n    print(\"No es 7\")\n}\n\n// Condicional switch\nswitch numero {\n    case 7:\n        print(\"Es 7\")\n    case 8:\n        print(\"Es 8\")\n    default:\n        print(\"No es 7 ni 8\")\n}\n\n// Transferencia de control\nfor index in 1...5 {\n    if index == 3 {\n        continue\n    }\n\n    print(index)\n}\n\nfor index in 1...5 {\n    if index == 3 {\n        break\n    }\n\n    print(index)\n}\n\nnumero = 5\nswitch numero {\n    case 5:\n        print(\"Es 5\")\n        fallthrough\n    default:\n        print(\"Esto no debería de imprimirse\")\n}\n\n// Etiquetas\nmainLoop: for _ in 1...5 {\n    let letras = [\"a\", \"b\", \"c\"]\n\n    secondaryLoop: for letra in letras {\n\n        if letra == \"b\" {\n            break secondaryLoop\n        }\n        print(letra)\n    }\n}\n\n// Guard\nlet people = [\"juan\", \"pablo\"]\n\nguard let person = people.first else {\n    fatalError(\"No hay personas\")\n}\nprint(person)\n\n// Defer\nvar score = 1\nif score < 10 {\n    defer {\n        print(score)\n    }\n    score += 5\n}\n\n// Error Handling\nenum Error: Swift.Error {\n    case error1\n    case error2\n}\n\nfunc error() throws {\n    throw Error.error1\n}\n\ndo {\n    try error()\n} catch Error.error1 {\n    print(\"Error 1\")\n} catch Error.error2 {\n    print(\"Error 2\")\n} catch {\n    print(\"Error desconocido\")\n}\n\n// ---------------------------------- Ejercicio extra ----------------------------------\nfor index in 10...55 {\n\n    if index % 2 == 0 {\n        \n        if index != 16 && index % 3 != 0 {\n            print(index)\n        }\n    }\n\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/swift/gliadev.swift",
    "content": "import Foundation\n\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA:\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n// constate no podemos cambiarla\nlet nombre = \"Patata\"\n// variables podemos cambiarla\nvar edad = 21\n\n\n// Operadores\nlet suma = 5 + 2\nlet resta = 5 - 3\nlet multiplicacion = 5 * 3\nlet division = 5 / 3\nlet modulo = 5 % 3\n\nprint(\"Aritmeticos: \\(suma),\\(resta),\\(multiplicacion),\\(division),\\(modulo)\")\n\n// operadores logicos\nlet verdadero = true\nlet falso = false\n// AND && OR || NOT !\nprint(\"Logicos: \\(verdadero && false), \\(verdadero || falso), \\(!verdadero)\")\n\n\n// operadores de comparacion\nlet numeroUno = 5\nlet numeroDos = 3\nprint(\"\\(numeroUno == numeroDos)\") //  igualdad\nprint(\"\\(numeroUno != numeroDos)\") //  no igualdad distinto\nprint(\"\\(numeroUno >= numeroDos)\")  // mayor  o igual que\nprint(\"\\(numeroUno <= numeroDos)\")  // menos o igual que\nprint(\"\\(numeroUno > numeroDos)\")  // mayor  que\nprint(\"\\(numeroUno < numeroDos)\")  // menor  que\n// tendremos el operador === triple de igualdad que lo usamos dentro del ambito de un condicional\n\n\n// operadores asignación\nvar contador = 10 // tiene un valor de 10\ncontador += 5  // le sumamos 5 a contador y contador ahora vale 15\nprint(contador)\ncontador -= 3  // contador ahora es 12\nprint(contador)\ncontador *= 2  // contador ahora es 24\nprint(contador)\ncontador /= 4  // contador ahora es 6\nprint(contador)\n\n// operadores en Bits\n\n\n\n// estructuras de control\n// if, else if, else, switch\nlet edadDos = 17\n\nif edadDos < 18 { // si edadDos es mayor o igual a 18\n    print(\"Con \\(edadDos) eres menor de edad\")\n} else if edadDos >= 18 && edadDos < 60 {\n    print(\"Con \\(edadDos) eres un adulto\")\n} else {\n    print(\"Con \\(edadDos) eres un adulto mayor!!!\")\n}\n\n//switch\nswitch edadDos {\ncase 0..<18:\n    print(\"Eres menor de edad.\")\ncase 18..<60:\n    print(\"Eres adulto\")\ndefault:\n    print(\"Eres adulto Mayor!!\")\n}\n\n// bucles for\nfor i in 1...5 {\n    print(i)\n}\n\n// while\nvar contadorTres = 1\nwhile contadorTres <= 3 {\n    print(\"Número: \\(contadorTres)\")\n    contadorTres += 1\n    print(contadorTres)\n}\n\n\n\n// parte extra\n\n//* DIFICULTAD EXTRA:\n//* Crea un programa que imprima por consola todos los números comprendidos\n//* entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n//*\n\nfor num in 10...55 {\n    if num != 16, num % 2 == 0, num % 3 != 0 {\n        print(num)\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/swift/karys4.swift",
    "content": "// Operadores Aritméticos\nlet num1 = 10\nlet num2 = 5\n\nlet add = num1 + num2\nlet subtract = num1 - num2\nlet multiply = num1 * num2\nlet divide = num1 / num2\nlet module = num1 % num2\n\nprint(\"Add: \\(add),  subtract: \\(subtract), multiply: \\(multiply), divide: \\(divide), module: \\(module)\")\n\n// Control Flow\n// For-In Loop\nvar numberOfDays = 5\nfor num in 0..<numberOfDays {\n    print(\"Number: \\(num)\")  \n}\n\n// While Loop\nvar month = 1\n\nwhile month < 13 {\n    print(\"Month: \\(month)\")   \n    month += 1 \n}\n\n// Repeat-While Loop\nvar year = 2024\n\nrepeat {\n    print(\"Hello!\") \n} while  year == 2023\n\n// Conditional Statements\n// if / else\nvar age = 21\nvar haveMoney = true\n\nif age >= 18 && haveMoney {\n    print(\"Genial!! eres adulto con dinero!.\")\n} else if age >= 18 {\n    print(\"Bienvenido al mundo de los adultos sin dinero XD.\")\n} else {\n    print(\"Eres aún pequeño sin responsabilidades\")\n}\n\n// Switch\nlet dayOfTheWeek = \"Friday\"\n\nswitch dayOfTheWeek {\n    case \"Monday\":\n    print(\"It's monday\")\n    case \"Tuesday\":\n    print(\"It's tuesday\")\n    case \"Wednesday\":\n    print(\"It's wednesday\")\n    case \"Thursday\":\n    print(\"It's thursday\")\n    case \"Friday\":\n    print(\"It's friday\")\n    default:\n    print(\"Not a day of the week\") \n}\n\n/*\nCrea un programa que imprima por consola todos los números comprendidos\n entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n*/\n\nfor number in 10...55 {\n    if number != 16 && !(number % 3 == 0){\n        if number % 2 == 0 {\n            print(number)\n            \n        } \n    }\n}\n\n// Expected Output: 10,14,20,22,26,28,32,34,38,40,44,46,50,52\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/swift/kontroldev.swift",
    "content": "import Foundation\n\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n\n// Operadores aritméticos\nlet suma = 5 + 3\nlet resta = 10 - 2\nlet multiplicacion = 4 * 6\nlet division = 15 / 3\nlet modulo = 7 % 2\nlet potencia = Int(pow(2.0, 3.0)) // 2.0 es la base, 3.0 es el exponente\n\nprint(\"Operadores aritméticos:\")\nprint(\"Suma:\", suma)\nprint(\"Resta:\", resta)\nprint(\"Multiplicación:\", multiplicacion)\nprint(\"División:\", division)\nprint(\"Módulo:\", modulo)\nprint(\"Potencia:\", potencia)\n\n\n// Operadores lógicos\nlet andResultado = true && false\nlet orResultado = true || false\nlet notResultado = !true\n\nprint(\"Operadores lógicos:\")\nprint(\"AND:\", andResultado)\nprint(\"OR:\", orResultado)\nprint(\"NOT:\", notResultado)\n\n\n// Operadores de comparación\nlet igual = 5 == 5\nlet distinto = 5 != 10\nlet mayor = 10 > 5\nlet menor = 3 < 8\nlet mayorOigual = 7 >= 7\nlet menorOigual = 6 <= 6\n\nprint(\"\\nOperadores de comparación:\")\nprint(\"Igual:\", igual)\nprint(\"Distinto:\", distinto)\nprint(\"Mayor:\", mayor)\nprint(\"Menor:\", menor)\nprint(\"Mayor o igual:\", mayorOigual)\nprint(\"Menor o igual:\", menorOigual)\n\n\n// Operadores de asignación\nvar asignacion = 5\nasignacion += 3\nasignacion -= 2\nasignacion *= 4\nasignacion /= 2\n\nprint(\"Operadores de asignación: \\(asignacion)\")\n\n\n// Operadores de identidad\nlet a = \"Esto es una comparacion\"\nlet b = \"Esto es una comparacioN\"\n\nlet esIgual = a == b\nlet diferente = a != b\n\nprint(\"Operadores de identidad:\")\nprint(\"Identidad:\", esIgual)\nprint(\"No identidad:\", diferente)\n\n\n// Operadores de pertenencia\nlet lista = [1, 2, 3, 4, 5]\nlet pertenencia = 3\nlet noPertenencia = 6\n\nprint(\"\\nOperadores de pertenencia:\")\nprint(\"Pertenencia:\", lista.contains(pertenencia))\nprint(\"No pertenencia:\", !lista.contains(noPertenencia))\n\n\n// Operadores de bits\nlet bitwiseAnd = 5 & 3\nlet bitwiseOr = 5 | 3\nlet bitwiseXor = 5 ^ 3\nlet bitwiseNot = ~5\nlet shiftIzquierda = 5 << 1\nlet shiftDerecha = 5 >> 1\n\nprint(\"\\nOperadores de bits:\")\nprint(\"AND:\", bitwiseAnd)\nprint(\"OR:\", bitwiseOr)\nprint(\"XOR:\", bitwiseXor)\nprint(\"NOT:\", bitwiseNot)\nprint(\"Shift izquierda:\", shiftIzquierda)\nprint(\"Shift derecha:\", shiftDerecha)\n\n\n//DIFICULTAD EXTRA (opcional):\n\nfor number in 10...55 { // Rango del 10 al 55 (incluidos)\n    if number % 2 == 0 && number != 16 && number % 3 != 0 { \n        print(number) // Imprimir si cumple las condiciones\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/swift/miguelex.swift",
    "content": "import Foundation\n\n// Operadores aritmeticos\n\nlet a = 5      \nlet b = 3      \n\nprint(\"Aritmeticos:\")\nprint(\"5 + 3 = \\(a + b)\")\nprint(\"5 - 3 = \\(a - b)\")\nprint(\"5 * 3 = \\(a * b)\")\nprint(\"5 / 3 = \\(5 / 3)\")\nprint(\"5 % 3 = \\(5 % 3)\")\n\n// Operadores de comparación\n\nprint(\"\\nDe comparación:\")\nprint(\"5 == 5 --> \\(5 == 5)\")\nprint(\"10 != 5 --> \\(10 != 5)\")\nprint(\"8 > 3 --> \\(8 > 3)\")\nprint(\"2 < 7 --> \\(2 < 7)\")\n\n// Operadores de asignación\n\nvar edad = 48\n\nprint(\"\\nDe asignación:\")\nprint(\"Mi edad actual: \\(edad)\")\nprint(\"Mi edad el año que viene: \\(edad + 1)\")\nprint (\"Mi edad hace 5 años: \\(edad - 5)\")\n\n// Operadores logicos\n\nlet verdadero = true\nlet falso = false\n\nprint(\"\\nLógicos:\")\nprint(\"verdadero AND falso: \\(verdadero && falso)\")\nprint(\"verdadero OR falso: \\(verdadero || falso )\")\nprint(\"NOT verdadero: \\(!verdadero)\")\n\n// Operadores de identidad\n\nlet saludo = \"Hola\"\nlet despedida = \"Adios\"\n\nprint(\"\\nIdentidad:\")\nprint(\"Objetos iguales: \\(saludo == despedida)\")\n\n// Operadores de pertenencia\n\nlet names = [\"Migue\", \"Angel\", \"Pepe\", \"Juan\", \"Rafa\"]\n\nprint(\"\\nPertenencia:\")\nprint(\"Contiene el nombre de Migue: \\(names.contains(\"Migue\"))\")\n\n// Operadores de bits\n\nlet x: UInt8 = 0b00111001\nlet y: UInt8 = 0b00011011\n\nprint(\"\\nDe bits:\")\nprint(\"AND de bits: \\(x & y)\")\nprint(\"OR de bits: \\(x | y)\")\nprint(\"XOR de bits: \\(x ^ y)\")\nprint(\"Desplazamiento izquierda: \\(x << 1)\")\nprint(\"Desplazamiento derecha: \\(x >> 1)\")\n\n// Estructuras de control\n\nlet mes = 2\n\nprint(\"If... else\")\n\nif mes != 2 {\n    print(\"Otro mes diferente a febrero\")\n} else  {\n    print(\"Febrero\")\n} \n\nprint(\"switch\")\n\nswitch mes {\n    case 1:\n        print(\"Enero\")\n    case 2:\n        print(\"Febrero\")\n    default:\n        print(\"Mes desconocido\")\n}\n\nlet nombres = [\"Migue\", \"Angel\", \"Pepe\", \"Juan\", \"Rafa\"]\n\nprint(\"For... in\")\nfor nombre in nombres {\n    print(\"Hola \\(nombre)\")\n}\n\n\nfor i in 1...5 {\n    print(i)\n}\n\nprint(\"while\")\nvar i = 1\nwhile i <= 5 {\n    print(i)\n    i += 1\n}\n\nprint(\"repeat... while\")\ni = 1\nrepeat {\n    print(i)\n    i += 1\n} while i <= 5\n\n\n// Extra\n\nfor i in 10...55 {\n    if i % 2 == 0 && i != 16 && i % 3 != 0 {\n        print(i)\n    }\n}\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/swift/nahuelborromeo.swift",
    "content": "import Foundation\n\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n\n// OPERADORES ARITMÉTICOS:\nlet suma = 5 + 2\nlet resta = 10 - 3\nlet multiplicacion = 10 * 5\nlet division = 21 / 3\nlet modulo = 15 % 4\nlet potencia = pow(2.0, 3.0)\n\nprint(\"Suma: \", suma)\nprint(\"Resta: \", resta)\nprint(\"Multiplicación: \", multiplicacion)\nprint(\"División: \", division)\nprint(\"Módulo: \", modulo)\nprint(\"Potencia: \", potencia)\n\n\n// OPERADORES LÓGICOS\nlet andOperator = true && true\nlet orOperator = true || false\nlet notOperator = !true\n\nprint(\"\\nOperador AND: \", andOperator)\nprint(\"Operador OR: \", orOperator)\nprint(\"Operador NOT: \", notOperator)\n\n// OPERADORES DE COMPARACIÓN\n\nlet igual = 5 == 5\nlet distinto = 4 != 5\nlet mayor = 7 > 3\nlet menor = 6 < 2\nlet mayorOIgual = 7 >= 2\nlet menorOIgual = 6 <= 6\n\nprint(\"\\nIgual: \", igual)\nprint(\"Distinto: \", distinto)\nprint(\"Mayor que: \", mayor)\nprint(\"Menor que: \", menor)\nprint(\"Mayor o igual que: \", mayorOIgual)\nprint(\"Menor o igual que: \", menorOIgual)\n\n\n// OPERADORES DE ASIGNACIÓN\nvar x = 5 //Operador de asignación\nx += 2 //Más igual\nx -= 4 //Menos igual\nx *= 3 //Por igual\nx /= 2 //Entre igual\n\nprint(\"\\nAsignación: \", x)\n\n// Operadores de identidad\nlet a = [1, 2, 3]\nlet b = [1, 2, 3]\nlet identidad = a == b\nlet noIdentidad = a != b\n\nprint(\"\\nOperadores de identidad:\")\nprint(\"Idéntico:\", identidad)\nprint(\"No idéntico:\", noIdentidad)\n\n// Operadores de pertenencia\nlet lista = [1, 2, 3, 4, 5]\nlet pertenece = 3\nlet noPertenece = 6\nprint(\"\\nOperadores de pertenencia:\")\nprint(\"Pertenece:\", lista.contains(pertenece))\nprint(\"No pertenece:\", !lista.contains(noPertenece))\n\n// Operadores de bits\nlet bitwiseAnd = 5 & 3\nlet bitwiseOr = 5 | 3\nlet bitwiseXor = 5 ^ 3\nlet bitwiseNot = ~5\nlet shiftIzquierda = 5 << 1\nlet shiftDerecha = 5 >> 1\n\nprint(\"\\nOperadores de bits:\")\nprint(\"AND:\", bitwiseAnd)\nprint(\"OR:\", bitwiseOr)\nprint(\"XOR:\", bitwiseXor)\nprint(\"NOT:\", bitwiseNot)\nprint(\"Shift izquierda:\", shiftIzquierda)\nprint(\"Shift derecha:\", shiftDerecha)\n\n// Estructuras de control\n\n// Condicionales\nif 6 > 2 {\n    print(\"\\nCondicional:\")\n    print(\"5 es mayor que 3\")\n}\n\n// Iterativas\nprint(\"\\nIterativas:\")\nfor i in 10...55 {\n    if i == 16 || i % 3 == 0 {\n        continue\n    }\n    print(i)\n}\n\n// Excepciones\nprint(\"\\nExcepciones:\")\ndo {\n    let resultado = try dividir(dividendo: 30, divisor: 0)\n    print(resultado)\n} catch {\n    print(\"Error: división por cero\")\n}\n\nfunc dividir(dividendo: Int, divisor: Int) throws -> Int {\n    if divisor == 0 {\n        throw CustomError.divisionByZero\n    }\n    return dividendo / divisor\n}\n\nenum CustomError: Error {\n    case divisionByZero\n}\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/swift/paola-itzel-martinez.swift",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n// Assigment\n\nlet constString: String = \"This is a string\"\n\nprint(\"assigment: \\(constString)\")\n\n\n/*\n Arithmetic\n */\n\n// addition\nlet addition: Int = 2 + 2\n\nprint(\"addition: 2 + 2 = \\(addition)\")\n\n\n// substraction\nlet substraction: Int = 2 - 2\n\nprint(\"substraction: 2 - 2 = \\(substraction)\")\n\n\n// multiplication\nlet multiplication: Int = 2 * 2\n\nprint(\"multiplication: 2 * 2 = \\(multiplication)\")\n\n\n// division\nlet division: Int = 2 / 2\n\nprint(\"division: 2 / 2 = \\(division)\")\n\n\n// residue\nlet residue: Int = 9 % 4\n\nprint(\"residue: 9 % 4 = \\(residue)\")\n\n\n\n/*\n Comparation\n */\n\n//major\nlet major: Bool = 2 > 1\n\nprint(\"major: 2 > 1 is \\(major)\")\n\n\n//minor\nlet minor: Bool = 1 < 2\n\nprint(\"minor: 1 < 2 is \\(minor)\")\n\n\n//equal\nlet equal: Bool = 1 == 1\n\nprint(\"equal: 1 == 1 is \\(equal)\")\n\n\n//different\nlet different: Bool = 1 != 1\n\nprint(\"different: 1 != 1 is \\(different)\")\n\n\n//major equal\nlet majorEqual: Bool = 1 >= 1\n\nprint(\"majorEqual: 1 >= 1 is \\(majorEqual)\")\n\n\n//minor equal\nlet minorEqual: Bool = 1 <= 1\n\nprint(\"minorEqual: 1 <= 1 is \\(minorEqual)\")\n\n\n\n/*\n Ternary operator\n */\n\nlet ternaryOne = 10\nlet ternaryTwo = 20\n\nprint(ternaryOne == ternaryTwo ? \"They are same\" : \"They are different\")\n\n\n\n/*\n Composite assignment\n */\n\nvar compositeAssigment: Int = 1\n\ncompositeAssigment += 2\n\nprint(\"if a is 1 then a += 2 is \\(compositeAssigment)\")\n\n\n\n/*\n Operator nil-coalescing\n */\n\nvar nilCoalescing: String?\n\nlet finalNilCoalescingValue = nilCoalescing ?? \"return the b option\"\n\nprint(\"if a is nil then a ?? b \\(finalNilCoalescingValue)\")\n\n\n\n/*\nRange\n */\n\nprint(\"close range is 1...5\")\nprint(\"semi-open range is 1..<5\")\nprint(\"unilateral range is myArray[2...] (from 2nd position)\")\nprint(\"unilateral range is myArray[...2] (to 2nd position)\")\nprint(\"unilateral with semi-open range is myArray[..<2] (to 2nd position without the 2nd posiiton)\")\n\n\n\n/*\nLogical\n */\n\nlet trueValue = true\nlet falseValue = false\n\n// NOT !\nif !trueValue {\n    print(\"trueValue was denied with not operator\")\n}\n\n\n// AND &&\nif trueValue && trueValue {\n    print(\"trueValue and trueValue are true\")\n}\n\n\n// OR ||\nif trueValue || falseValue {\n    print(\"any of values (trueValue or falseValue) is true\")\n}\n\n\n\n/*\nControl flow\n */\n\nlet names: [String] = [\n    \"Me\",\n    \"You\",\n    \"Others\",\n    \"Lastname\",\n    \"Middle name\",\n    \"First name\"\n]\n\nlet dictionary = [\n    0: \"Apple\",\n    1: \"Table\",\n    2: \"Glass\",\n]\n\n\n// For-In\nfor name in names {\n    print(name)\n}\n\nfor (id, word) in dictionary {\n    print(\"id: \\(id)\")\n    print(\"word: \\(word)\")\n    print(\"-------------\")\n}\n\n\nfor name in names[...1] {\n    print(name)\n}\n\n\n// While\nvar count: Int = 0\n\nwhile count < 3 {\n    print(count, \"< 3\")\n    \n    count += 1\n}\n\n\n// Repeat While\nrepeat {\n    print(count)\n    \n    count += 1\n} while count < 6\n\n\n// If\nif count > 0 {\n    print(\"if control flow: count > 0 is true\")\n}\n\n\n// If else\nif count > 100 {\n    print(\"count > 100 is true\")\n} else {\n    print(\"if else control flow: count > 100 is false\")\n}\n\n\n// If else if\nif count > 100 {\n    print(\"count > 100 is true\")\n} else if count < 100 {\n    print(\"if else if control flow: count < 100 is true\")\n}\n\n\n// Switch\n\nswitch count {\ncase 0:\n    print(\"count is 0\")\ndefault:\n    print(\"my default value\")\n}\n\nenum MessageStatus {\n    case sent\n    case delivered\n    case read\n}\n\nlet status: MessageStatus = .read\n\nswitch status {\ncase .sent:\n    print(\"sent\")\ncase .delivered, .read:\n    print(\"maybe ignored\")\n}\n\n\n// Guard\nlet animals = [\"cat\", \"dog\", \"bird\"]\n\nguard let myPet = animals.first else {\n    fatalError(\"You dont have a pet\")\n}\n\nprint(myPet)\n\n\n\n\n/*\n extra\n */\n\nfor number in 10...55 {\n    let is55 = number == 55\n    \n    let isAllowedNumber =\n        number != 16 &&\n        number % 2 == 0 &&\n        number % 3 != 0\n    \n    if is55 || isAllowedNumber {\n        print(number)\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/swift/pedroomar23.swift",
    "content": "import Foundation\n\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n // Operadores Aritmeticos\nlet suma = 2 + 3 // Suma\nlet resta = 4 - 2 // Resta \nlet division = 4 / 2 // Division\nlet multiplicacion = 4 * 3 // Multiplicacion\nlet modulo = 5 % 5 // Modulos\n\n// Print en Consola \nprint(\"Los operadores aritmeticos son Suma: \\(suma),\n                                      Resta: \\(resta),\n                                      Division: \\(division),\n                                      Multiplicacion: \\(multiplicacion),\n                                      Mudulos: \\(modulo)\")\n\n// Operadores Logicos \nlet operadorNot = !false // Not \nlet operadorAND = false && true // AND\nlet operadorOR = false || true  // OR\n\n// Print en Consola \nprint(\"Lod operadores logicos son Not: \\(operadorNot),\n                                  AND: \\(operadorAND),\n                                  OR: \\(operadorOR)\")\n\n// Operadores de Comparacion\nlet igual = 5 = 5 // Igual\nlet mayor = 5 > 4 // Mayor\nlet menor = 4 < 5 // Menor \nlet mayor igual = 5 >= 4 // Mayor Igual \nlet menor igual = 5 <= 4 // Menor Igual \n\nprint(\"Los operadores de comparacion son Igual: \\(igual),\n                                         Mayor: \\(mayor),\n                                         Menor: \\(menor),\n                                         Mayor Igual: \\(mayor igual),\n                                         Menor Igual: \\(menor igual)\")\n\n// Operadores de Identidad \nstruct Person {\n    var nombre: String \n\n    init(nombre: String) {\n        self.nombre = nombre\n    }\n}\n\nlet person: (nombre: \"Juan\")\nlet person1: (nombre: \"Julio\")\n\nif person == person1 {\n    print(\"Los valores de la variable son iguales \\(==)\")\n} else {\n    print(\"Los valores de la variable son diferentes \\(!==)\")\n}\n\nif person !== person1 {\n    print(\"Las contantes person y person1 tienen el mismo valor \\(==)\")\n} else {\n    print(\"Las contantes person y person 1 no tienen el mismo valor \\(!==)\")\n}\n\n// Operadores de Pertenecia\nlet operador1 = containt // containt\nlet operador2 = containt(where: ) // containt(where: )\nlet operador3 = isSubset(of: ) // isSubset(of: )\n\nprint(\"Los operadores de pertenencia son \\(operador1), \\(operador2), \\(operador3)\")\n\n// containt\nlet numeros = [1, 2, 3, 4, 5] // Ejemplo 1 \n\nif numero.containt(3) {\n    print(\"El numero 3 no aparee en el array\")\n} else {\n    print(\"El numero 3 si aparece en el array\")\n}\n\n// containt(where: ) \nlet nombres = [\"Juan\", \"Carlos\", \"Jose\", \"Pedro\", \"Omar\"] // Ejemplo 2\n\nif nombre.containt(where: { $0.count > 4 } ) {\n    print(\"En el array hay nombres con menos de 4 caracteres\")\n} else {\n    print(\"En el array hay nombres con mas de 4 caracteres\")\n}\n\nlet nombres = [\"Juan\", \"Carlos\", \"Jose\", \"Pedro\", \"Omar\"] // Ejemplo 3\n\nif nombres.containt(where: { $0.count < 5} ) {\n    print(\"En el array hay nombres con mas de 5 caracteres\")\n} else {\n    print(\"En el arry hay nombres con mas de 5 caracteres\")\n}\n\n// isSubset(of: )\nlet numeros1: Set<Int> = [1, 2, 3] // Ejemplo 1\nlet numeros2: Set<Int> = [1, 2]\n\nif numeros2.isSubset(of: numeros1) { \n    print(\"Los numeros2 no es miembro de los numeros1\")\n} else {\n    print(\"Los numeros2 es miembro de los numeros1\")\n}\n\nlet nombres1: Set<String> = [\"Juan\", \"Carlos\", \"Jose\"] // Ejemplo 2\nlet nombres2: Set<String> = [\"Juan\", \"Carlos\"]\n\nif nombres2.isSubset(of: nombres1) {\n    print(\"Los nombres2 no aparecen en los nombres1\")\n} else {\n    print(\"Los nombres2 si aparacen en losa nombres1\")\n}\n\n// Operadores de bits\nlet operador1 = AND(&&)\nlet operador2 = OR(||)\nlet opeador3 = NOR(^)\nlet operador4 = NOT(~)\nlet opedador5 = Desplazar a la derecha (>>)\nlet operador6 = Desplazar a la izquierda (<<)\n\nprint(\"Los operadores bits son \\(operador1), \\(operador2), \\(operador3), \\(operador4), \\(operador5)\")\n\nlet operadorAND = 0b100 && 0b100 // AND\nlet operadorOR = 0b100 || 0b100 // OR\nlet operadorNOR = 0b100 ^ 0b100 // NOR\nlet operadorNOT = 0b100 ~ 0b100 // NOT\nlet operador4 = 0b100 >> 0b100 // Desplazar a la derecha \nlet operador5 = 0b100 << 0b100 // Desplazar a la izquierda \n\nprint(\"Los operadores condicionales son if, switch, guard y condicionales ternarias\")\n\nlet numero = 20 // Ejemplo 1\n\nif numero % == 5 {\n    print(\"El numero \\(numero) es de tipo par\")\n} else {\n    print(\"El numero \\(numero) es de tipo impar\")\n}\n\nlet numero = 15 // Ejemplo 2\n\nif numero % == 8 {\n    print(\"El numero \\(numero) es de tipo impar\")\n} else {\n    print(\"El numero \\(numero) es de tipo par\")\n}\n\nswitch {\n    case 1:\n        return print(\"Case 1 seleccionada\")\n    case 2:\n        return print(\"Case 2 seleccionada\")\n    case 3:\n        return print(\"Case 3 seleccionado\")\n    default:\n        return print(\"Case seleccionada\")\n}\n\nlet edad = 18 // Ejemplo 1\n\nfunc validarEdad(edad: Int) {\n    guard let edad >= 18 else {\n        print(\"La edad es de 18\")\n        \n        return \n    }\n}\n\nvarlidadEdad(edad: 18)\n\nlet nombre = \"Pedro\" // Ejemplo 2\nlet edad = 18\n\nfunc validar(nombre: String, edad: Int) {\n    guard let nombre = \"Pedro\" else {\n        print(\"El nombres es \\(nombre)\")\n\n        return \n    }\n\n    guard let edad >= 18 else {\n        print(\"La edad es de 18\")\n\n        return \n    }\n}\n\nvalidar(nombre: \"Pedro\", edad: 18)\n\n// Las condicionales interactivas son for-in, while, reapeat-while\n\nlet numeros = [1, 2, 3, 4, 5] // for-in\n\nfor numero in numeros {\n    print(\"Los valores del array son \\(numeros)\")\n}\n\nvar contador = 5 // While\n\nwhile contador < 5 {\n    print(\"El valor de \\(contador) vale 4\")\n    contador += 1\n}\n\nvar numero = 0 // Repeat-While\n\nrepeat {\n    print(\"El valor de la variable es \\(numero)\")\n} while numero < 5\n    print(\"El valor de la variable es \\(numero)\")\n\n// Excepciones\nenum sendError: Error {\n    case buyError\n}\n\nfunc newError() -> throws {\n    throw sendError.buyError\n}\n\n// do-catch se usa a la hora de manejar los errores\ndo {\n    try newError()\n} catch sendError.buyError {\n    print(\"No hay errores para corregir\")\n} catch {\n    print(\"Si hay errores para corregir\")\n}\n\n// Extra \nfunc program() {\n    for numeros in 10...55 {\n        if numeros % 6 == 0 && 3 != 0 && 16 != 0 {\n            print(numeros)\n        }\n    }\n}\n\nprogram()"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/swift/zetared92.swift",
    "content": "import Foundation\n\n// RETO #01 OPERADORES Y ESTRUCTURAS DE CONTROL\n\n// OPERADORES DE ASIGNACIÓN\n/* El operador (=) no devuelve ningún valor.\nSu función es asignarle al operando de la izq,\nun valor con el operando de la dch. */\n\nvar myVariable = 2.4\nvar mySecondVariable = 6.2\nvar myThirdVariable = 4.8\n\nmyVariable = myThirdVariable\nprint(\"Operador de asignación:\", myVariable)\n\n\n// OPERADORES ARITMÉTICOS\n/* Swift soporta los operadores aritméticos estándar\npara todos los tipos numéricos. \n    - Suma(+)\n    - Resta(-)\n    - Multiplicación(*)\n    - División(/)*/\nlet miSuma = 4 + 2 // Esto es una suma\n// Podemos asignar y realizar una suma en una misma operación\nlet otraSuma = 4\notraSuma += 2\nprint(otraSuma)\n// Esta sería otra forma de hacer la asignación anterior.\nlet otraSuma = 4\notraSuma = otraSuma + 2\nprint(otraSuma)\n\nlet miResta = 4 - 2 // Esto es una resta\n// Asignar y restar\nlet otraResta = 4\notraResta -= 2\nprint(otraResta)\n// Otra forma de asignar y operar.\nlet otraResta = 4\notraResta = otraResta - 2\nprint(otraResta)\n\nlet miMultiplicacion = 4 * 2 // Esto es una multiplicación\n// Asignar y multiplicar\nlet otraMultiplicacion = 4\notraMultiplicacion *= 2\nprint(otraMultiplicacion)\n// Otra forma de asignar y operar\nlet otraMultiplicacion = 4\notraMultiplicacion = otraMultiplicacion * 2\nprint(otraMultiplicacion)\n\nlet division = 4 / 2 // Esto es una división\n// Asignar y dividir\nlet otraDivision = 4\notraDivision /= 2\nprint(otraDivision)\n// Otra forma de asignar y dividir\nlet otraDivision = 4\notraDivision = otraDivision / 2\nprint(otraDivision)\n\nlet resto = 9 % 4 // Esto es un operador módulo/resto.\n// Asignar y calcular el resto\nlet otroResto = 9\notroResto %= 4\nprint(otroResto)\n\n\n// OPERADORES DE COMPARACIÓN\n/* Los operadores de comparación devuelve un valor\nbooleano indicando si el enunciado es (true) o (false). Estos\nson los operadores con los que cuenta Swift:\n    - Igual que (==)\n    - No igual que (!=)\n    - Mayor que (>)\n    - Menor que (<)\n    - Mayor o igual que (>=)\n    - Menor o igual que (<=) */\nvar igual = 1 == 1 // (true) 1 es igual a 1\nvar noIgual = 2 != 1 // (true) 2 no es igual a 1\nvar mayorQue = 2 > 1 // (true) 2 es mayor que 1\nvar menorQue = 1 < 2 // (true) 1 es menor que 2\nvar mayorIgual = 1 <= 1 // (true) 1 es mayor o igual que 1\nvar menorIgual = 2 <= 1 // (false) 2 no es menor o igual que 1\n\n\n// OPERADORES LÓGICOS\n/* Los operadores lógicos modifican los valores lógicos\nbooleanos. Swift soporta tres operadores lógicos básicos:\n    - NO (NOT) lógico (!)\n    - Y (AND) lógico (&&)\n    - O (OR) lógico (||)*/\nlet acceptConst = false\nif !acceptConst {\n    print(\"No acepta el consentimiento\")\n} /* Declaramos la variable y decimos que es falsa.\nEntonces, si NO se acepta el consentimiento (!acceptConst es true) =\n(acceptConst es false). Sale el print.*/\n\nlet inputPin = true\nlet retinaScan = false\n\nif inputPin && retinaScan {\n    print(\"Welcome home Mr. Stark\")\n} else {\n    print(\"ACCESS DENIED\")\n}\n/* Ambos valores deben ser (true) para que toda la expresión\nsea (true). Si uno de los valores es (false) la expresión será\n(false). Si el primer valor es (false) el segundo, no será evaluado.\nEvaluación cortocircuito */\n\nlet inputPin = false\nlet retinaScan = true\n\nif inputPin || retinaScan {\n    print(\"Welcome home, Mr. Stark\")\n} else {\n    print(\"ACCESS DENIED\")\n}\n/* El operador lógico O (OR) también utiliza la evaluación\ncortocircuito para evaluar las expresiones. Si uno de los dos\nvalores booleanos es (true), toda la expresión es (true).*/\n\n\n// OPERADORES DE BITS\nlet areUaOne: UInt8 = 0b00001111\nlet invertedBits = ~areUaOne // Esto es igual a 11110000\n// Operador bit a bit AND (&)\nlet firstSixBits: UInt8 = 0b11111100\nlet lastSixBits: UInt8 = 0b00111111\nlet middleFourBits = firstSixBits & lastSixBits // Esto es igual a 00111100\n// Operador bit a bit OR (|)\nlet someBits: UInt8 = 0b10110010\nlet moreBits: UInt8 = 0b01011110\nlet combineBits = someBits | moreBits // Esto es igual a 11111110\n// Operador bit a bit XOR (^)\nlet firstBits: UInt8 = 0b00010100\nlet otherBits: UInt8 = 0b00000101\nlet outputBits = firstBits ^ otherBits // Esto es igual a 00010001\n// Desplazamiento izquierda/derecha\nlet shiftBits: UInt8 = 4 // Equivale a 00000100 en binario\nshiftBits << 1 // Equivale a 00001000 en binario\nshiftBits << 2 // Equivale a 00010000 en binario\nshiftBits >> 1 // Equivale a 00000010 en binario\nshiftBits >> 2 // Equivale a 00000001 en binario\n// Ejemplo con operadores bit a bit.\nlet firstConstantBit: UInt8 = 0b00010100\nlet secondConstantBit: UInt8 = 0b00000101\nlet operatorAnd = firstConstantBit & secondConstantBit\nlet operatorOr = firstConstantBit | secondConstantBit\nlet operatorXOR = firstConstantBit ^ secondConstantBit\nlet shiftLeft = firstConstantBit << 2\nlet shiftRight = firstConstantBit >> 2\n\nprint(\"Bitwise AND (&):\", operatorAnd)\nprint(\"Bitwise OR (|):\", operatorOr)\nprint(\"Bitwise XOR (^):\", operatorXOR)\nprint(\"Bitwise Left Shift (<<):\", shiftLeft)\nprint(\"Bitwise Right Shift (>>):\", shiftRight)\n\n\n// OPERADORES DE IDENTIDAD\n/* Podemos saber si dos constantes o variables se refieren\na la misma instancia de una clase. Para esto Swift ofrece\ndos operadores de identidad:\n    - Idéntico a (===)\n    - No idéntico a (!==) */\nlet person1 = \"Alan Turing\"\nlet person2 = \"Alan Turing\"\nlet scientific = person1 == person2\n\nprint(\"Scientifics refer to Alan Turing:\", scientific)\n\n\n// OPERADORES DE PERTENENCIA\n/* Este tipo de operadores evalúan si un objeto (x)\npertenece a otro. Como si quisieramos saber si dentro de\nun contenedor hay un objeto determinado.*/\nlet container = [\"MacBook\", \"iPad\", \"iPhone\", \"AirPods\"]\nlet containAirPods = container.contains(\"AirPods\")\nlet containAppleWatch = container.contains(\"Apple Watch\")\n\nprint(\"Are there any AirPods in the container?:\", containAirPods)\nprint(\"Are there any Apple Watch in the container?: \", containAppleWatch)\n\n\n// ESTRUCTURAS DE CONTROL\n/* Condicionales: Este tipo de estructuras de control nos\nsirven cuando necesitamos que el valor de alguna de las variables\no de alguna condición sea evaluada para posteriormente, se ejecute\nla instrucción. */\nlet radioBohr: Double = 52.9\n\nif radioBohr != 52.9 {\n    print(\"Bohr radius is correct:\", radioBohr, \"NO\")\n} else {\n    print(\"Bohr radius is correct:\", radioBohr, \"YES\")\n}\n\n/* Iterativas: Son instrucciones repetitivas, también denominado\nbucle. Su finalidad es ejecutar las mismas instrucciones de código\nuna y otra vez siempre y cuando se cumpla una determinada condición.*/\nprint(\"Fibonacci Sequence:\", \"Fn = Fn-1 + Fn-2\")\n\nfunc fibonacciSequence(num: Int) -> Int {\n    var n1 = 0\n    var n2 = 1\n\n    var nR = 0\n\n    for _ in 0..<num{\n        nR = n1\n        n1 = n2\n        n2 = nR + n2\n    }\n    return n1\n}\n\nvar val = 10\n\nfor i in 0...val{\n   let output = fibonacciSequence(num: i)\n   print(output)\n} \n\n// Excepciones\nenum myError: Error {\n    case notExist\n}\n\nfunc returnException() throws {\n    throw myError.notExist\n}\n\ndo {\n    try returnException()\n    print(\"Exception: Successful\")\n} catch myError.notExist {\n    print(\"Exception: Not Exist!\")\n} catch {\n    print(\"Exception: An ERROR has occurred\")\n}\n\n// DIFICULTAD EXTRA (Opcional)\n/* Crea un programa que imprima por consola todos los\nnúmeros comprendidos entre 10 y 55 (inclusive), pares,\ny que no son ni el 16 ni múltiplos de 3.*/\nfor num in 10...55 {\n    if num % 2 == 0, num != 16, num % 3 != 0 {\n        print(num)\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/AChapeton.ts",
    "content": "// *** OPERADORES DE ASIGNACION ***\n\n//Asignacion\nlet x: number = 5 \nlet y: number = 10\nconsole.log('Asignacion:', x, y)\n\n//Asignacion de Adicion\nx = x + y\nconsole.log('Adicion 1:', x)\nx += y\nconsole.log('Adicion 2:', x)\n\n//Asignacion de Resta\nx = x - y\nconsole.log('Resta 1:', x)\nx -= y\nconsole.log('Resta 2:', x)\n\n//Asignacion de Multiplicacion\nx = x * y\nconsole.log('Multiplicacion 1:', x)\nx *= y\nconsole.log('Multiplicacion 2:', x)\n\n//Asignacion de Division\nx = x / y\nconsole.log('Division 1:', x)\nx /= y\nconsole.log('Division 2:', x)\n\n//Asignacion de Residuo\nx = x % y\nconsole.log('Residuo 1:', x)\nx %= y\nconsole.log('Residuo 2:', x)\n\n//Asignacion de Exponente\nx = x ** y\nconsole.log('Exponente 1:', x)\nx **= y\nconsole.log('Exponente 2:', x)\n\n//Asignacion AND logico\nx = x && (x = y)\nconsole.log('AND logico 1:', x)\nx &&= y\nconsole.log('AND logico 2:', x)\n\n//Asignacion OR logico\nx = x || (x = y)\nconsole.log('OR logico 1:', x)\nx ||= y\nconsole.log('OR logico 2:', x)\n\n//Asignacion Anulacion logico\nx = x ?? (x = y)\nconsole.log('Anulacion logico 1:', x)\nx ??= y\nconsole.log('Anulacion logico 2:', x)\n\n\n\n\n// *** OPERADORES DE COMPARACION ***\nlet a: number = 4\nlet b: number = 8\n\n//Igual\nconsole.log('Igual: ', a == b)\n\n//No es igual\nconsole.log('No es igual: ', a != b)\n\n//Igualdad estricta\nconsole.log('Igualdad estricta: ', a === b)\n\n//Desigualdad estricta\nconsole.log('Desigualdad estricta: ', a !== b)\n\n//Mayor que\nconsole.log('Mayor que: ', a > b)\n\n//Mayor o igual que\nconsole.log('Mayor o igual que: ', a >= b)\n\n//Menor que\nconsole.log('Menor que: ', a < b)\n\n//Menor o igual que\nconsole.log('Menor o igual que: ', a <= b)\n\n\n\n// *** OPERADORES ARITMETICOS ***\nlet num1: number = 10\nlet num2: number = 4\n\n//Residuo\nconsole.log('Residuo: ', num1 % num2)\n\n//Incremento\nconsole.log('Incremento antes de imprimir: ', ++num1) \nconsole.log('Incremento despues de imprimir: ', num1++) //Se vuelve 12 luego de imprimir\n\n//Decremento\nconsole.log('Decremento antes de imprimir: ', --num1)\nconsole.log('Decremento despues de imprimir: ', num1--) //Se vuelve 10 luego de imprimir\n\n//Negacion unitaria\nconsole.log('Negacion unitaria: ', -num1)\n\n//Positivo unitaria\nconsole.log('Negacion unitaria: ', +num1)\n\n//Exponenciacion\nconsole.log('Exponenciacion: ', num1 ** num2)\n\n\n\n// *** OPERADORES BIT A BIT ***\nlet bit1: number = 6\nlet bit2: number = 8\n\n//Desplazamiento a la izquierda\nconsole.log('Desplazamiento a la izquierda:', bit1 << bit2)\n\n//Desplazamiento a la derecha\nconsole.log('Desplazamiento a la derecha:', bit1 >> bit2)\n\n//AND\nconsole.log('AND bit a bit:', bit1 & bit2)\n\n//OR\nconsole.log('AND bit a bit:', bit1 | bit2)\n\n//XOR\nconsole.log('AND bit a bit:', bit1 ^ bit2)\n\n//NOT\nconsole.log('AND bit a bit:', bit1 ~ bit2)\n\n\n// *** OPERADORES LOGICOS ***\nconst exp1 = true\nconst exp2 = false\n\n//AND logico\nconsole.log('AND Logico: ', exp1 && exp2)\n\n//OR logico\nconsole.log('OR Logico: ', exp1 || exp2)\n\n//NOT logico\nconsole.log('NOT Logico: ', !exp1)\n\n\n\n\n// *** OPERADORES DE CADENA ***\nconsole.log(\"mi \" + \"cadena\")\n\n\n\n// *** OPERADOR CONDDICIONAL TERNARIO ***\nconst result = true ? true : false\nconsole.log(result)\n\n\n\n// *** OPERADORES RELACIONALES ***\ninterface IObj {\n  id: string\n  name: string\n  age: number\n}\n\nconst user: IObj = {\n  id: '1',\n  name: 'Andres',\n  age: 86\n}\n\nconsole.log('Existe \"age\" en el objeto user?: ', 'age' in user)\nconsole.log('Existe \"country\" en el objeto user?: ', 'country' in user)\n\n\n\n\n// *** ESTRUCTURAS DE CONTROL ***\n\n// * CONDICIONAL *\nlet num = 25\n\n// IF-ELSE\nif(num > 18){\n  console.log('Es mayor de edad')\n}else{\n  console.log('Es menor de edad')\n}\n\n\n//SWITCH\nswitch(num){\n  case 20:\n    console.log('Es 20')\n    break\n  case 25:\n    console.log('Es 25')\n    break\n  case 30:\n    console.log('Es 30')\n    break\n  default:\n    console.log('Default')\n    break\n}\n\n\n// * BUCLES *\nlet i: number = 10\nlet w: number = 15\n\n//WHILE\nwhile(i < w){\n  i++\n  console.log('Nuevo valor de i:', i)\n}\n\n\n//DO-WHILE\ni = 10\n\ndo{\n  i++\n  console.log('Nuevo valor de i:', i)\n} while(i < w)\n\n//FOR\nfor(let i = 0; i < 10; i++){\n  console.log('Nuevo valor de i:', i)\n}\n\n\n\n// *** EJERCICIO EXTRA ***\nconsole.log('EJERCICIO EXTRA')\nfor(let i = 10; i <= 55; i++){\n  if(i % 2 === 0){\n    if(i === 16){\n      console.log('Ignorar')\n    }else if(i % 3 === 0){\n      console.log('Multiplo de 3')\n    }else{\n      console.log(i)\n    }\n  }else{\n    console.log('No es par')\n  }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/Andeveling.ts",
    "content": "// Operadores en TypeScript\n\n// Operadores Aritméticos\nlet suma = 10 + 5\nconsole.log(\"El resultado de la suma 10 + 5 es:\" + suma)\n\nlet resta = 10 - 5\nconsole.log(\"El resultado de la resta 10 - 5 es:\" + resta)\n\nlet multiplicacion = 10 * 5\nconsole.log(\"El resultado de la multiplicación 10 * 5 es:\" + multiplicacion)\n\nlet division = 10 / 5\nconsole.log(\"El resultado de la división 10 / 5 es:\" + division)\n\nlet modulo = 10 % 5\nconsole.log(\"El resultado del módulo 10 % 5 es:\" + modulo)\n\nlet potencia = 10 ** 5\nconsole.log(\"El resultado de la potencia 10 ** 5 es:\" + potencia)\n\n// Operadores de Asignación\nlet asignacion = 10\nconsole.log(\"El resultado de la asignación es:\" + asignacion)\n\nasignacion += 5\nconsole.log(\"El resultado de la asignación += 5 es:\" + asignacion)\n\nasignacion -= 5\nconsole.log(\"El resultado de la asignación -= 5 es:\" + asignacion)\n\n// Operadores de Comparación\nlet a = 10\nlet b = 5\n\nlet igualdad = a == b\nconsole.log(\"El resultado de la igualdad de a == b es:\" + igualdad)\n\nlet igualdadEstricta = a === b\nconsole.log(\"El resultado de la igualdad estricta de a === b es:\" + igualdadEstricta)\n\nlet desigualdad = a != b\nconsole.log(\"El resultado de la desigualdad de a != b es:\" + desigualdad)\n\nlet mayorQue = a > b\nconsole.log(\"El resultado de la mayor que de a > b es:\" + mayorQue)\n\nlet menorQue = a < b\nconsole.log(\"El resultado de la menor que de a < b es:\" + menorQue)\n\nlet menorQueOigual = a <= b\nconsole.log(\"El resultado de la menor que o igual de a <= b es:\" + menorQueOigual)\n\nlet mayorQueOigual = a >= b\nconsole.log(\"El resultado de la mayor que o igual de a >= b es:\" + mayorQueOigual)\n\n// Operadores de Lógicos\nlet and = true && false\nconsole.log(\"El resultado de la conjunción de and es:\" + and)\n\nlet or = true || false\nconsole.log(\"El resultado de la disyunción de or es:\" + or)\n\nlet not = !true\nconsole.log(\"El resultado de la negación de not es:\" + not)\n\n// Estructuras de Control\n// if else\nlet ifElse = 10\nif (ifElse > 5) {\n  console.log(\"El valor de ifElse es mayor que 5\")\n} else {\n  console.log(\"El valor de ifElse es menor o igual que 5\")\n}\n\n// switch\nlet switchCase = 10\nswitch (switchCase) {\n  case 5:\n    console.log(\"El valor de switchCase es 5\")\n    break\n  case 10:\n    console.log(\"El valor de switchCase es 10\")\n    break\n  default:\n    console.log(\"El valor de switchCase no coincide con ninguno de los casos\")\n    break\n}\n\n// for\nfor (let i = 0; i < 10; i++) {\n  console.log(\"El valor de i es:\" + i)\n}\n\n// while\nlet whileLoop = 0\nwhile (whileLoop < 10) {\n  console.log(\"El valor de whileLoop es:\" + whileLoop)\n  whileLoop++\n}\n\n// try catch\nlet tryCatch = 10\ntry {\n  console.log(\"El valor de tryCatch es:\" + tryCatch)\n} catch (error) {\n  console.log(\"Error:\" + error)\n} finally {\n  console.log(\"Este es un bloque finally\")\n}\n\n// Numeros entre 10 y 55\nfor (let i = 10; i <= 55; i++) {\n  if (i % 2 === 0 && i % 3 !== 0 && i !== 16) {\n    console.log(i)\n  }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/BertoMP.ts",
    "content": "// OPERADORES ARITMÉTICOS\nconsole.log('OPERADORES ARITMÉTICOS');\nconst firstNumber: number = 7;\nconst secondNumber: number = 2;\nlet result: number;\n\n// Operador suma (+)\nresult = firstNumber + secondNumber;\nconsole.log(`La suma de ${firstNumber} + ${secondNumber} es ${result}`);\n\n// Operador resta (-)\nresult = firstNumber - secondNumber;\nconsole.log(`La resta de ${firstNumber} - ${secondNumber} es ${result}`);\n\n// Operador multiplicación (*)\nresult = firstNumber * secondNumber;\nconsole.log(`La multiplicación de ${firstNumber} * ${secondNumber} es ${result}`);\n\n// Operador división (/)\nresult = firstNumber / secondNumber;\nconsole.log(`La división de ${firstNumber} / ${secondNumber} es ${result}`);\n\n// Operador módulo (%)\nresult = firstNumber % secondNumber;\nconsole.log(`El resto de la división de ${firstNumber} / ${secondNumber} es ${result}`);\n\n// OPERADORES LÓGICOS\nconsole.log('\\nOPERADORES LÓGICOS');\nconst firstBool: boolean = true;\nconst secondBool: boolean = false;\n\n// Operador lógico AND (&&)\nconst logicAnd: boolean = (firstBool && secondBool);\nconsole.log(`AND lógico: ${logicAnd}`);\n\n// Operador lógico OR (||)\nconst logicOr: boolean = (firstBool || secondBool);\nconsole.log(`OR lógico: ${logicOr}`);\n\n// Operador lógico NOT (!)\nconst logicNot: boolean = !firstBool;\nconsole.log(`NOT lógico: ${logicNot}`);\n\n// OPERADORES DE COMPARACIÓN\nconsole.log('\\nOPERADORES DE COMPARACIÓN');\n// Operador mayor que (>)\nconst greatThan: boolean = (5 > 10);\nconsole.log(`¿Es 5 mayor que 10? -> ${greatThan}`);\n\n// Operador menor que (>)\nconst lessThan: boolean = (5 < 10);\nconsole.log(`¿Es 5 menor que 10? -> ${lessThan}`);\n\n// Operador mayor o igual que (>=)\nconst greatOrEqual: boolean = (5 >= 10);\nconsole.log(`¿Es 5 mayor o igual que 10? -> ${greatOrEqual}`);\n\n// Operador menor o igual que (<=)\nconst lessOrEqual: boolean = (5 <= 10);\nconsole.log(`¿Es 5 menor o igual que 10? -> ${lessOrEqual}`);\n\n// OPERADORES DE ASIGNACIÓN\nconsole.log('\\nOPERADORES DE ASIGNACIÓN');\n// Operador de asignación simple (=)\nlet number:number = 10;\nconsole.log(`Valor asignado: ${number}`);\n\n// Operador de suma y asignación (+=)\nnumber += 5; // 10 + 5 = 15\nconsole.log(`Valor del resultado de suma y asignación: ${number}`);\n\n// Operador de resta y asignación (-=)\nnumber -= 5; // 15 - 5 = 10\nconsole.log(`Valor del resultado de resta y asignación: ${number}`);\n\n// Operador de multiplicación y asignación (+=)\nnumber *= 5; // 10 * 5 = 50\nconsole.log(`Valor del resultado de multiplicación y asignación: ${number}`);\n\n// Operador de división y asignación (/=)\nnumber /= 5; // 50 / 5 = 10\nconsole.log(`Valor del resultado de división y asignación: ${number}`);\n\n// Operador de módulo y asignación (%=)\nnumber %= 5; // 10 % 5 = 0\nconsole.log(`Valor del resultado de módulo y asignación: ${number}`);\n\n// OPERADORES DE IDENTIDAD\nconsole.log('\\nOPERADORES IDENTIDAD');\n// Operador de igualdad estricta\nconst strictEqualComp: boolean = (5 === 5);\nconsole.log(`¿Es 5 estrictamente igual a 5? -> ${strictEqualComp}`);\n\n// Operador de desigualdad estricta (!==)\nconst strictDiffComp: boolean = ('5' !== '5');\nconsole.log(`¿Es '5' estrictamente diferente a '5'? -> ${strictDiffComp}`);\n\n// OPERADORES DE PERTENENCIA\nconsole.log('\\nOPERADORES DE PERTENENCIA')\nconst intArray: number[] = [1, 12, 5, 643, 3];\nconst firstCheck: boolean = 3 in intArray; // Devolverá true\nconst secondCheck: boolean = 65 in intArray; // Devolverá false\n\nconsole.log(`¿Está el número 3 en el array de números? -> ${firstCheck}`);\nconsole.log(`¿Está el número 65 en el array de números? -> ${secondCheck}`);\n\n// OPERADORES DE BITS\nconsole.log('\\nOPERADORES DE BITS')\nconst firstBit: number = 5; // Representación binaria: 0000 0101\nconst secondBit: number = 3 // Representación binaria: 0000 0011\n\n// Operador AND a nivel de bits (&)\nconst bitAnd: number = firstBit & secondBit; // Devuelve 1 (representación binaria: 0000 0001)\nconsole.log(`Resultado AND bit a bit -> ${bitAnd}`);\n\n// Operador OR a nivel de bits (|)\nconst bitOr: number = firstBit | secondBit; // Devuelve 7 (representación binaria: 0000 0111)\nconsole.log(`Resultado OR bit a bit -> ${bitOr}`);\n\n// Operador XOR a nivel de bits (^)\nconst bitXor: number = firstBit ^ secondBit; // Devuelve 6 (representación binaria: 0000 0110)\nconsole.log(`Resultado OR bit a bit -> ${bitXor}`);\n\n// Operador NOT a nivel de bits (~)\nconst bitNot: number = ~firstBit; // Devuelve -6 (representación binaria: 1111 1010)\nconsole.log(`Resultado NOT bit a bit -> ${bitNot}`);\n\n// Operador de desplazamiento hacia la derecha (>>)\nconst toRightBit: number = firstBit >> 1; // Devuelve 2 (representación binaria: 0000 0010)\nconsole.log(`Desplazamiento hacia la derecha -> ${toRightBit}`);\n\n// Operador de desplazamiento hacia la izquierda (>>)\nconst toLeftBit: number = firstBit << 1; // Devuelve 10 (representación binaria: 0000 1010)\nconsole.log(`Desplazamiento hacia la derecha -> ${toLeftBit}`);\n\n// ESTRUCTURAS DE CONTROL CONDICIONAL\nconsole.log('\\nESTRUCTURAS DE CONTROL CONDICIONAL')\n// if-else\nconsole.log('if-else')\nconst num: number = 10;\n\nif (num > 0) {\n    console.log('El número es positivo.');\n} else if (num === 0) {\n    console.log('El número es cero.');\n} else {\n    console.log('El número es negativo.');\n}\n\n// Operador ternario\nconsole.log('\\nOperador ternario');\nconsole.log((num > 0) ? 'El número es positivo.' : 'El número es cero o negativo.');\n\n// switch-case\nconsole.log('\\nSwitch-Case');\nlet option: number = 1;\n\nswitch (option) {\n    case 1:\n        console.log('Se ha seleccionado la opción 1.');\n        break;\n    case 2:\n        console.log('Se ha seleccionado la opción 2.');\n        break;\n    default:\n        console.log('Opción por defecto.');\n}\n\n// ESTRUCTURAS DE CONTROL ITERATIVAS\nconsole.log('\\nESTRUCTURAS DE CONTROL ITERATIVAS')\n// while\nconsole.log('Bucle While');\nlet counter: number = 0;\nwhile (counter < 5) {\n    console.log(`Iteración: ${counter}`);\n    counter++;\n}\n\n// do-while\nconsole.log('\\nBucle do-while');\ncounter = 0;\ndo {\n    console.log(`Iteración: ${counter}`);\n    counter++;\n} while (counter < 5);\n\n// for\nconsole.log('\\nBucle for');\nfor (let counter: number = 0; counter < 5; counter++) {\n    console.log(`Iteración: ${counter}`);\n}\n\n// for ... of\nconsole.log('\\nBucle for ... of');\nconst arrNumbers: number[] = [1, 2, 5, 2, 7, 9];\nfor (const number of arrNumbers) {\n    console.log(`Número -> ${number}`);\n}\n\n// for ... in\nconsole.log('\\nBucle for ... in');\nconst persona: object = { name: 'Alberto', age: 33 };\nfor (const att in persona) {\n    console.log(`${att} -> ${persona[att]}`);\n}\n\n// MANEJO DE EXCEPCIONES\nconsole.log('\\nMANEJO DE EXCEPCIONES');\nconsole.log('Bloque try-catch');\nconst errNumber: number = 10;\n\ntry {\n    if (errNumber === 10) {\n        throw new Error('El número es igual a 10.');\n    }\n    console.log('El número es distinto de 10.');\n} catch (error) {\n    console.log(`Se ha producido un error debido a -> ${error.message}`);\n}\n\nconsole.log('\\nBloque try-catch-finally');\ntry {\n    if (errNumber === 10) {\n        throw new Error('El número es igual a 10.');\n    }\n    console.log('El número es distinto de 10.');\n} catch (error) {\n    console.log(`Se ha producido un error debido a -> ${error.message}`);\n} finally {\n    console.log('Bloque finally. Esto siempre se ejecuta haya o no excepción.');\n}\n\n// DIFICULTAD EXTRA\nconsole.log(\"\\nEJERCICIO EXTRA\");\n/*  Crea un programa que imprima por consola todos los números comprendidos entre 10 y 55 (incluidos), pares, y\n *  que no son ni el 16 ni múltiplos de 3.*/\nfor (let i = 10; i <= 55; i++) {\n    if ((i % 2 === 0) && (i !== 16) && (i % 3 !== 0)) {\n        console.log(\"Iteración: \" + i);\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/CT-Zodiako.ts",
    "content": "\n// Operadores aritméticos\nconsole.log(1+1); // Suma\nconsole.log(2-1); // Resta\nconsole.log(2*2); //Multiplicación\nconsole.log(4/2); // División\nconsole.log(4%2); // Módulo\nconsole.log(4**2); // Potencia\n\n// Operadores de asignación\nlet a = 10;\na += 2;  // es igual a a = a + 2\nconsole.log(a);  // 12\n\nlet b = 10;\nb -= 2;  // es igual a b = b - 2\nconsole.log(b);  // 8\n\nlet c = 10;\nc *= 2;  // es igual a c = c * 2\nconsole.log(c);  // 20\n\nlet d = 10;\nd /= 2;  // es igual a d = d / 2\nconsole.log(d);  // 5\n\n\n// Operadores de comparación\nconsole.log(1 == 1); // Igualdad\nconsole.log(1 === 1); // Identidad\nconsole.log(1 != 1); // Diferente\nconsole.log(1 !== 1); // No identico\nconsole.log(1 > 1); // Mayor que\nconsole.log(1 < 1); // Menor que\nconsole.log(1 >= 1); // Mayor o igual que\nconsole.log(1 <= 1); // Menor o igual que\n\n// Operadores lógicos\nconsole.log(true && true); // AND\nconsole.log(true || false); // OR\nconsole.log(!true); // NOT\n\n// Operadores de bits\nlet a = 5; // en binario 0101\nlet b = 3; // en binario 0011\n\nconsole.log(a & b);   // 1, en binario 0001\nconsole.log(a | b);   // 7, en binario 0111\nconsole.log(a ^ b);   // 6, en binario 0110\nconsole.log(~a);      // -6, es el complemento a dos\nconsole.log(a << 1);  // 10, se desplaza a la izquierda 1 bit\nconsole.log(a >> 1);  // 2, se desplaza a la derecha 1 bit\n\n// Operador ternario\nlet a = 10;\nlet b = 2;\n\nlet mayor = (a > b) ? a : b;\nconsole.log(mayor);  // 10\n\n// Operador typeof\nlet a = 10;\n\nconsole.log(typeof a);  // \"number\"\n\n// Operador instanceof\nclass MiClase {\n}\n\nlet obj = new MiClase();\n\nconsole.log(obj instanceof MiClase);  // true\n\n\n\n//Operadores acceso de popiedades\nlet obj = {\n    propiedad: 'valor'\n  };\n  \n  console.log(obj.propiedad);  // 'valor'\n  console.log(obj['propiedad']);  // 'valor'\n  \n// Operador de nueva instancia\nclass MiClase {\n}\n\nlet obj = new MiClase();\n\n//Operador llamada de función\nfunction miFuncion() {\n    console.log('¡Hola Mundo!');\n  }\n  \n  miFuncion();  // '¡Hola Mundo!'\n  \n\n\n\n// Estructuras de control\nlet c = 1;\nif (c == 1) {\n    console.log('Es uno');\n} else {\n    console.log('No es uno');\n}\n\nlet d = 2;\nswitch (d) {\n    case 1:\n        console.log('Es uno');\n        break;\n    case 2:\n        console.log('Es dos');\n        break;\n    default:\n        console.log('No es uno ni dos');\n}\n\nlet e = 3;\nwhile (e > 0) {\n    console.log(e);\n    e--;\n}\n\nlet f = 3;\ndo {\n    console.log(f);\n    f--;\n} while (f > 0);\n\nfor (let g = 0; g < 3; g++) {\n    console.log(g);\n}\n\n// Excepciones\ntry {\n    throw new Error('Error');\n}\ncatch (error) {\n    console.log(error);\n}\n\n// Funciones\nfunction h() {\n    console.log('Hola');\n}\n\nh();\n\nfunction i(j: string) {\n    console.log(j);\n}\n\ni('Hola');\n\nfunction k(l: number, m: number) {\n    return l + m;\n}\n\n\n//Extra\nfor (let i = 10; i <= 55; i++) {\n     \n    if (i == 16) {\n        continue;\n    }\n    let div = i % 3;\n    if (div == 0) {\n        continue;\n    }\n    let par = i % 2;\n        if (par == 0) {\n            console.log(i);\n    }\n    \n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/CarlosAVargas7.ts",
    "content": "/* EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje: Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n */\n\n//! 1. Tipos de Operadores\n\n//* a) Operadores Aritméticos\n// Los operadores aritméticos realizan cálculos matemáticos como suma, resta, multiplicación, etc.\nlet a: number = 10;\nlet b: number = 5;\nconsole.log(\"Suma:\", a + b); // 15\nconsole.log(\"Resta:\", a - b); // 5\nconsole.log(\"Multiplicación:\", a * b); // 50\nconsole.log(\"División:\", a / b); // 2\nconsole.log(\"Módulo:\", a % b); // 0\nconsole.log(\"Potencia:\", a ** b); // 100000\nconsole.log(\"Incremento:\", ++a); // 11 (pre-incremento, muestra el valor actualizado)\nconsole.log(\"Decremento:\", --b); // 4 (pre-decremento, muestra el valor actualizado)\n\n//* b) Operadores de Comparación\n// Los operadores de comparación evalúan si una condición es verdadera o falsa, comparando valores.\na = 10; // Reiniciar\nb = 5; // Reiniciar\nconsole.log(\"Igualdad:\", a == b); // false\nconsole.log(\"Desigualdad:\", a != b); // true\nconsole.log(\"Igualdad estricta:\", a === b); // false\nconsole.log(\"Desigualdad estricta:\", a !== b); // true\nconsole.log(\"Mayor que:\", a > b); // true\nconsole.log(\"Menor que:\", a < b); // false\nconsole.log(\"Mayor o igual que:\", a >= b); // true\nconsole.log(\"Menor o igual que:\", a <= b); // false\n\n//* c) Operadores Lógicos\n// Los operadores lógicos combinan condiciones booleanas para tomar decisiones.\nlet e: boolean = true;\nlet f: boolean = false;\nconsole.log(\"AND lógico:\", e && f); // false\nconsole.log(\"OR lógico:\", e || f); // true\nconsole.log(\"NOT lógico:\", !e); // false\n\n//* d) Operadores de Asignación\n// Los operadores de asignación asignan valores a variables, a menudo combinando operaciones aritméticas.\nlet g: number = 10;\nlet h: number = 5;\nconsole.log(\"Asignación simple:\", (g = h)); // 5\ng = 10; // Reiniciar\nconsole.log(\"Suma y asignación:\", (g += h)); // 15\ng = 10; // Reiniciar\nconsole.log(\"Resta y asignación:\", (g -= h)); // 5\ng = 10; // Reiniciar\nconsole.log(\"Multiplicación y asignación:\", (g *= h)); // 50\ng = 50; // Reiniciar\nconsole.log(\"División y asignación:\", (g /= h)); // 10\ng = 10; // Reiniciar\nconsole.log(\"Módulo y asignación:\", (g %= h)); // 0\ng = 10; // Reiniciar\nconsole.log(\"Potencia y asignación:\", (g **= h)); // 100000\n\n//* e) Operadores Bit a Bit\n// Los operadores bit a bit operan sobre los bits de números enteros, útiles para operaciones a bajo nivel.\nlet i: number = 5; // 0101 en binario\nlet j: number = 3; // 0011 en binario\nconsole.log(\"AND bit a bit:\", i & j); // 1 (0101 & 0011 = 0001)\nconsole.log(\"OR bit a bit:\", i | j); // 7 (0101 | 0011 = 0111)\nconsole.log(\"XOR bit a bit:\", i ^ j); // 6 (0101 ^ 0011 = 0110)\nconsole.log(\"NOT bit a bit:\", ~i); // -6 (invierte los bits de 0101)\nconsole.log(\"Desplazamiento a la izquierda:\", i << j); // 40 (0101 << 3 = 101000)\nconsole.log(\"Desplazamiento a la derecha:\", i >> j); // 0 (0101 >> 3 = 0000)\nconsole.log(\"Desplazamiento a la derecha sin signo:\", i >>> j); // 0 (similar a >> para números positivos)\n\n//* f) Operadores de Tipo\n// Los operadores de tipo son específicos de TypeScript y ayudan a manejar el sistema de tipos.\nclass Animal {\n    nombre: string;\n    constructor(nombre: string) {\n        this.nombre = nombre;\n    }\n}\nclass Perro extends Animal {\n    ladra: boolean;\n    constructor(nombre: string, ladra: boolean) {\n        super(nombre);\n        this.ladra = ladra;\n    }\n}\n// `as` (Type Assertion): Fuerza un tipo específico cuando sabemos que es seguro\nlet valor: string = \"Hola TypeScript\";\nlet texto: string = valor as string;\nconsole.log(\"Type Assertion (as):\", texto); // Hola TypeScript\n\n// `is` (Type Guard): Verifica si un objeto pertenece a un tipo específico\nfunction esPerro(animal: Animal): animal is Perro {\n    return (animal as Perro).ladra !== undefined;\n}\nlet miMascota: Animal = new Perro(\"Firulais\", true);\nconsole.log(\"Type Guard (is):\", esPerro(miMascota)); // true\n\n// `!` (Non-null Assertion): Indica que una variable no es null ni undefined\nlet elemento: string | null = \"texto\";\nlet seguroElemento: string = elemento!;\nconsole.log(\"Non-null Assertion (!):\", seguroElemento); // texto\n\n// `typeof`: Devuelve el tipo de datos de una variable\nconsole.log(\"typeof:\", typeof texto); // string\n\n// `instanceof`: Verifica si un objeto es instancia de una clase específica\nconsole.log(\"instanceof Perro:\", miMascota instanceof Perro); // true\nconsole.log(\"instanceof Animal:\", miMascota instanceof Animal); // true\n\n//* g) Operadores Ternarios\n// El operador ternario ofrece una forma compacta de tomar decisiones condicionales.\nlet m: number = 10;\nlet n: number = 5;\nconsole.log(\"Ternario:\", m > n ? \"m es mayor que n\" : \"m no es mayor que n\"); // m es mayor que n\n\n//* h) Operadores Opcionales\n// Los operadores opcionales manejan valores que podrían ser null o undefined de forma segura.\nlet o: { name: string; age?: number } = { name: \"Carlos\" };\nconsole.log(\"Optional Chaining (?.):\", o?.name); // Carlos\nconsole.log(\"Optional Chaining (?.):\", o?.age); // undefined\nconsole.log(\"Nullish Coalescing (??):\", o?.age ?? 0); // 0\n\n//! 2. Estructuras de Control\n\n//* 1. Condicionales\n// Las estructuras condicionales ejecutan código según el cumplimiento de una condición.\nlet age: number = 18;\nconsole.log(\"If:\");\nif (age >= 18) {\n    console.log(\"Eres mayor de edad\"); // Eres mayor de edad\n} else if (age >= 13) {\n    console.log(\"Eres adolescente\");\n} else {\n    console.log(\"Eres menor de edad\");\n}\nconsole.log(\"Switch:\");\nswitch (age) {\n    case 18:\n        console.log(\"Eres mayor de edad\"); // Eres mayor de edad\n        break;\n    case 13:\n        console.log(\"Eres adolescente\");\n        break;\n    default:\n        console.log(\"Edad no clasificada\");\n        break;\n}\n\n//* 2. Estructuras de Bucles\n// Los bucles permiten repetir un bloque de código múltiples veces según una condición.\nconsole.log(\"for:\");\nfor (let i: number = 0; i < 5; i++) {\n    console.log(\"Iteración:\", i); // 0, 1, 2, 3, 4\n}\nconsole.log(\"for...of:\");\nlet array: number[] = [1, 2, 3, 4, 5];\nfor (let i of array) {\n    console.log(\"Elemento:\", i); // 1, 2, 3, 4, 5\n}\nconsole.log(\"for...in:\");\nlet object: { [key: string]: any } = { name: \"Carlos\", age: 18 };\nfor (let i in object) {\n    console.log(\"Propiedad:\", i, \"Valor:\", object[i]); // name Carlos, age 18\n}\nconsole.log(\"while:\");\nage = 15; // Reiniciar para mostrar el bucle\nwhile (age < 18) {\n    console.log(\"Eres menor de edad\"); // Imprime 3 veces\n    age++;\n}\nconsole.log(\"do...while:\");\nlet x: number = 0;\ndo {\n    console.log(\"Iteración:\", x); // 0, 1, 2, 3, 4\n    x++;\n} while (x < 5);\n\n//* 3. Excepciones\n// Las estructuras de excepciones manejan errores para evitar que el programa falle.\nconsole.log(\"try...catch:\");\ntry {\n    let valor: string | null = \"hola\";\n    if (typeof valor !== \"string\") {\n        throw new Error(\"El valor no es un string\");\n    }\n    console.log(\"Resultado:\", valor.toUpperCase()); // HOLA\n} catch (error: any) {\n    console.log(\"Error capturado:\", error.message);\n}\nconsole.log(\"try...catch...finally:\");\ntry {\n    let num: number | undefined = undefined;\n    if (num === undefined) {\n        throw new Error(\"Número no definido\");\n    }\n    console.log(\"Dividiendo:\", num / 0);\n} catch (error: any) {\n    console.log(\"Error capturado:\", error.message); // Número no definido\n} finally {\n    console.log(\"Esto se ejecuta siempre\"); // Esto se ejecuta siempre\n}\n\n//* 4. Control de Flujo\n// Los mecanismos de control de flujo modifican la ejecución dentro de bucles o funciones.\nconsole.log(\"break:\");\nfor (let i: number = 0; i < 10; i++) {\n    if (i === 5) {\n        console.log(\"Bucle terminado en i =\", i); // Bucle terminado en i = 5\n        break;\n    }\n    console.log(\"Iteración:\", i); // 0, 1, 2, 3, 4\n}\nconsole.log(\"continue:\");\nfor (let i: number = 0; i < 10; i++) {\n    if (i === 5) {\n        console.log(\"Saltando i =\", i); // Saltando i = 5\n        continue;\n    }\n    console.log(\"Iteración:\", i); // 0, 1, 2, 3, 4, 6, 7, 8, 9\n}\nconsole.log(\"return:\");\nfunction suma(a: number, b: number): number {\n    if (a < 0 || b < 0) {\n        console.log(\"Números negativos no permitidos\");\n        return 0;\n    }\n    return a + b;\n}\nconsole.log(\"Suma válida:\", suma(1, 2)); // 3\nconsole.log(\"Suma con negativo:\", suma(-1, 2)); // Números negativos no permitidos, 0\n\n\n/* DIFICULTAD EXTRA (opcional):\n *-Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n *-Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n*/\n\nlet z: number = 10\nwhile (z <= 55) {\n    if (z % 2 === 0)\n        if (z !== 16)\n\n            console.log(z)\n    z++\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/Danilo0203.ts",
    "content": "// Tipos de Operadores en TypeScript\n\n// 📌 OPERADORES ARITMETICOS (+, -, *, /)\n\n// Operador de Adicion (+)\nlet sum: number = 10 + 20;\nconsole.log(sum); // 30\n\n// Operador de Substracion (-)\nlet rest: number = 20 - 10;\nconsole.log(rest); // 10\n\n// Operador de Multiplicación\nlet mult: number = 10 * 20;\nconsole.log(mult); // 200\n\n// Operador de Division\nlet division: number = 20 / 10;\nconsole.log(division); // 2\n\n/* ********************************* */\n\n// 📌 OPERADOR RESTO (%)\nlet modulo: number = 10 % 2;\nconsole.log(modulo); // El resto de la division de 10 entre 2 es => 0\n\n/* ********************************* */\n\n// 📌 OPERADORES DE ASIGNACION\n\n// Operador de asignacion\nlet x: number = 10;\nlet y: number = x;\nconsole.log(y); // El valor de \"x\" se asigno a \"y\"\n\nlet sumAsign: number = (x += y); // Asigna el resultado de \"x\" mas \"y\" a \"x\"\nlet restAsign: number = (x -= y); // Asigna el resultado de \"x\" menos \"y\" a \"x\"\nlet multAsign: number = (x *= y); // Asigna el resultado de \"x\" multiplicado por \"y\" a \"x\"\nlet divAsign: number = (x /= y); // Asigna el resultado de \"x\" dividido por \"y\" a \"x\"\nlet modAsign: number = (x %= y); // Asigna el resultado de \"x\" modulo \"y\" a \"x\"\n\n/* ********************************* */\n\n// 📌 OPERADORES UNARIOS\n\n// Operador Unario Plus (+x)\nlet unarioPlus: string = \"23\";\nconsole.log(+unarioPlus, typeof +unarioPlus); // 23 number\n\n// Operador Unario Menos (-x)\nlet unarioMenos: string = \"10\";\nconsole.log(-unarioMenos, typeof -unarioMenos); // 10 number\n\n// Operador de Incremento Prefix (++x)\nlet contador: number = 10;\nconsole.log(++contador); // 11\n\n// Operador de Decremento Prefix\nconsole.log(--contador); // 10\n\n// Operador de Incremento Postfix\nconsole.log(contador++); // 10\n\n// Operador de Decremento Postfix\nconsole.log(contador--); // 11\nconsole.log(contador); // 10\n\n/* ********************************* */\n\n// 📌 OPERADORES DE COMPARACIÓN\n\n// Operador Menor que (<)\nlet menorQue: boolean = 10 < 20;\nconsole.log(menorQue); // true\n\n// Operador Mayor que (>)\nlet mayorQue: boolean = 10 > 20;\nconsole.log(mayorQue); // false\n\n// Operador Menor o igual que (<=)\nlet menorIgualQue: boolean = 10 <= 20;\nconsole.log(menorIgualQue); // true\n\n// Operador Mayor o igual que (>=)\nlet mayorIgualQue: boolean = 10 >= 20;\nconsole.log(mayorIgualQue); // false\n\n// Operador de Igual a (==)\nlet igual: boolean = 10 == 10;\nconsole.log(igual); // true\n\n// Operador de No Igual (!=)\nlet noIgual: Boolean = 10 != 10;\nconsole.log(noIgual); // false\n\n// Operador de Estricto Igual\nlet estrictoIgual: boolean = 10 === 10;\nconsole.log(estrictoIgual); // true\n\n// Operador de No Estricto Igual\nlet noEstrictoIgual: boolean = 10 !== 10;\nconsole.log(noEstrictoIgual);\n\n/* ********************************* */\n\n// 📌 OPERADORES LOGICOS (!, ||, &&)\n\n// Operador NOT (!)\nlet negacion: boolean = true;\nconsole.log(!negacion); // false\n\nlet dobleNegacion: boolean = true;\nconsole.log(!!dobleNegacion);\n\n// Operador AND (&&)\nconsole.log(true && true); // true\nconsole.log(true && false); // false\nconsole.log(false && true); // false\nconsole.log(false && false); // false\n\n// Operador OR (||)\nconsole.log(true || true); // true\nconsole.log(true || false); // true\nconsole.log(false || true); // true\nconsole.log(false || false); // false\n\n/* ********************************* */\n\n// 📌 EJEMPLOS ESTRUCTURAS DE CONTROL (IF - ELSE, SWITCH, FOR, WHILE, DO WHILE, BREAK, CONTINUE)\n\n// IF ELSE\nlet edad: number = 23;\nif (edad < 18) {\n  console.log(`Tienes ${edad} años, eres menor de edad`);\n} else if (edad >= 18) {\n  console.log(`Tienes ${edad} años, eres mayor de edad`);\n} else {\n  console.log(\"Por favor ingrese una edad\");\n}\n\n// Switch\nlet diasSemana: Date = new Date();\nswitch (diasSemana.getDay()) {\n  case 0:\n    console.log(\"Domingo\");\n    break;\n  case 1:\n    console.log(\"Lunes\");\n    break;\n  case 2:\n    console.log(\"Martes\");\n    break;\n  case 3:\n    console.log(\"Miercoles\");\n    break;\n  case 4:\n    console.log(\"Jueves\");\n    break;\n  case 5:\n    console.log(\"Viernes\");\n    break;\n  case 6:\n    console.log(\"Sabado\");\n    break;\n}\n\n// FOR\nfor (let i = 1; i <= 10; i++) {\n  console.log(i);\n}\n\n// WHILE\nlet contar: number = 1;\nwhile (contar <= 10) {\n  console.log(contar);\n  contar++;\n}\n\n// DO WHILE\nlet i: number = 1;\ndo {\n  console.log(i);\n  i++;\n} while (i <= 10);\n\n// Break (Solo se puede usar en FOR, WHILE y DO WHILE)\nlet productos: object[] = [\n  { nombre: \"Telefono\", precio: 700 },\n  { nombre: \"Tablet\", precio: 900 },\n  { nombre: \"Computadora\", precio: 2500 },\n];\nfor (let i = 0; i <= productos.length; i++) {\n  if (productos[i][\"precio\"] === 900) break;\n  console.log(productos[i]);\n}\n\n// Continue (Solo se puede usar en FOR, WHILE y DO WHILE)\n\nfor (let i = 0; i <= 10; i++) {\n  if (i % 2 !== 0) continue;\n  console.log(i);\n}\n\n/*\n  DIFICULTAD EXTRA (opcional):\n Crea un programa que imprima por consola todos los números comprendidos\n entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3. */\n\nlet count: number = 10;\ndo {\n  if (count % 2 === 0 && count !== 16 && count % 3 !== 0) {\n    console.log(count);\n  }\n  count++;\n} while (count <= 55);\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/Guillemduno.ts",
    "content": "// #01 OPERADORES Y ESTRUCTURAS DE CONTROL\n// #### Dificultad: Fácil | Publicación: 02/01/24 | Corrección: 08/01/24\n\n/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n//****************************************************** */\n// OPERADORES ARITMÉTICOS CON NÚMEROS (+, -, *, /, %, **)\n//****************************************************** */\n\nconst a: number = 2; // operando\nconst b: number = 4; // operando\n\n// Suma\nlet resultado_suma: number = a + b; // operador binario\n\nconsole.log(resultado_suma);\n\n// Resta\nlet resultado_resta: number = a - b;\n\nconsole.log(resultado_resta);\n\n// Multiplicación\nlet resultado_multiplicacion: number = a * b;\n\nconsole.log(resultado_multiplicacion);\n\n// Division\nlet resultado_division: number = a / b;\n\nconsole.log(resultado_division);\n\n// Resto (remainder)\n\nlet resultado_resto = a % b;\n\nconsole.log(resultado_resto);\n\n// Exponenciación\nlet resultado_expo = a ** b;\n\nconsole.log(resultado_expo);\n\n//****************************************************** */\n// OPERADORES ARITMÉTICOS CON CADENAS\n//****************************************************** */\n\n// Suma cadena de números\n\nconst numA: string = \"2\";\nconst numB: string = \"4\";\n\nlet concatena_num = numA + numB;\nconsole.log(concatena_num); // No suma 8, sinó que concatena los números 2 y 4 (24).\n\n// Suma cadenas\n\nconst palabra1: string = \"Hola\";\nconst palabra2: string = \" mundo!\";\n\nlet concatena_str = palabra1 + palabra2;\nconsole.log(concatena_str);\n\n// El operador de suma (+), aplicado delante de un único operando, cambia su tipo a número.\n\nconsole.log(typeof numA); // Mantiene el tipo string\nconsole.log(typeof +numA); // Cambia el tipo de string a number\n\n// Tabla de Precedència de los operadores\n\n//https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence\n\n// Assignación\nconst numC = 4;\n\n// Modificación in situ\nlet euros: number = 1;\neuros += 4;\nconsole.log(euros);\n\n//****************************************************** */\n// OPERADORES COMPARACIÓN\n//****************************************************** */\n\n// ==\nconst check = numA == \"2\";\nconsole.log(\"comparacion: \" + check); // true;\n\n// ===\nconst check_extricto = numA === 2;\nconsole.log(\"comparacion: \" + check_extricto); // false;\n\n// !=\nconst check01 = numA != \"2\";\nconsole.log(\"comparacion: \" + check01); // false;\n\n// !===\nconst check_extricto01 = numA !== \"2\";\nconsole.log(\"comparacion: \" + check_extricto01); // false;\n// <\na < b;\n// >\na > b;\n// <=\na <= b;\n// >=\na >= b;\n\n//****************************************************** */\n// OPERADORES LÓGICOS\n//****************************************************** */\n\n// OR\nlet aficion = \"surf\" || \"tenis\";\n\n// AND\nlet juegos = \"tetris\" && \"pong\";\n\n// !(NOT)\n\nlet result = !true; // false;\n\n//****************************************************** */\n// ESTRUCTURAS DE CONTROL\n//****************************************************** */\n\n// Condicional\n\nconst misCoches = [\"Ferrari\", \"BMW\", \"Porche\"];\n\n// if\nif (misCoches) {\n  console.log(\"Tengo coches\");\n} else {\n  console.log(\"No tengo coches\");\n}\n\n// switch\nlet comprado = 1;\nswitch (misCoches[comprado]) {\n  case \"Ferrari\":\n    console.log(\"Has comprado un Ferrari!\");\n    break;\n  case \"BMW\":\n    console.log(\"Has comprado un BMW!\");\n    break;\n  case \"Porche\":\n    console.log(\"Has comprado un Porche!\");\n    break;\n\n  default:\n    console.log(\"Tienes un coche de baratija...\");\n    break;\n}\n\n// Iterativas\n\n// for\nfor (let index = 0; index < misCoches.length; index++) {\n  const coche = misCoches[index];\n  console.log(coche);\n}\n\n// forOf\nfor (const coche of misCoches) {\n  console.log(coche);\n}\n\n// forEach\nmisCoches.forEach((coche) => {\n  console.log(coche);\n});\n\n// while\n/* let vida: number = 100;\nwhile (vida >= 50) {\n  //console.log(\"Sigues jugando desde while.\");\n} */\n\n// do while\n/* do {\nconsole.log(\"Sigues jugando desde do while.\");\n} while (vida >= 50); */\n\n// Excepciones\ntry {\n  // Alguna lógica.\n} catch (error: unknown) {\n  if (error instanceof Error) {\n    console.log(\"instanceof: \" + error.stack);\n  } else if (error && typeof error === \"object\" && \"message\" in error) {\n    console.log(\"object: \" + String(error.message));\n  } else if (typeof error === \"string\") {\n    console.log(\"string: \" + error);\n  } else {\n    console.log(\"default error message\");\n  }\n}\n\n//****************************************************** */\n// EJERCICIO EXTRA\n//****************************************************** */\n\nfunction numeros_comprendidos(min: number, max: number): void {\n  for (let num = min; num <= max; num++) {\n    if (num % 2 == 0 && num != 16 && num % 3 != 0) {\n      console.log(num);\n    }\n  }\n}\n\nnumeros_comprendidos(10, 55);\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/Igledev.ts",
    "content": "// Tipos de Operadores en TypeScript\n// 1º Aritméticos: Son operaciones básicas:\n    // -- Suma\n    let suma : number = 10 + 5;\n    console.log(suma); // 15\n    // -- Resta\n    let resta : number = 10 - 5;\n    console.log(resta); // 5\n    // -- Multiplicación\n    let multiplicacion : number = 10 * 5;\n    console.log(multiplicacion); // 50\n    // -- División\n    let divisio : number = 10 / 5;\n    console.log(divisio); // 2\n    // -- Incremento\n    let incremento : number = ++suma;\n    // -- Decremento\n    let decremento : number = --resta;\n    console.log(divisio); // 2\n// 2º Lógicos : Son operaciones que comparan 2 o más valores y devuelven un boolean\n    let nombre1 : string = 'Igledev';\n    let nombre2 : string = 'Igledeb';\n    let valido : boolean = false;\n    // -- Operador AND (&&)\n    if(nombre1 === 'Igledev' && nombre2 === 'Igledeb'){valido = true}\n    // Devuelve TRUE si los dos son validos\n    // -- Operador OR (||)\n    if(nombre1 === 'Igledev' || nombre2 === 'Igledeb'){valido = true}\n    // Devuelve TRUE si alguno de los dos son validos\n    // -- Operador NOT (!)\n    let noes_dev : boolean = false;\n    console.log(!noes_dev) // True\n    // Devuelve TRUE porque niega que es un FALSE.\n// 3º Comparación : Son Operadores que comparan\n    // -- ==\n    let valido2 : boolean = nombre1 == nombre2; // Devuelve TRUE si los dos nombres son iguales.\n    // -- !=\n    valido2 = nombre1 != nombre2; // Devuelve TRUE si los operadores no son iguales.\n    // -- ===\n    valido2 = nombre1 === nombre2; // Devuelve TRUE si los dos operadores coinciden en tipo y dato\n    // -- !==\n    valido2 = nombre1 !== nombre2; // Devuelve TRUE si los dos operadores no coinciden ni en tipo ni en dato\n    // -- >\n    valido2 = 10 > 5; // Devuelve TRUE si el operador izquierdo es más grande que el derecho\n    // -- >=\n    valido2 = 10 >= 10; // Devuelve TRUE si el operador izquierdo es más grande o igual que el derecho\n    // -- <\n    valido2 = 5 < 10; // Devuelve TRUE si el operador derecho es más grande que el izquierdo\n    // -- <=\n    valido2 = 10 <= 10; // Devuelve TRUE si el operador derecho es más grande o igual que el izquierdo\n// 4º Asignación: Son Operadores que asignan un valor a sus operador izquierdo basandose en el derecho\n    // -- Asignación    \n    let num1 : number = 10; let num2 : number = num1;\n    // -- Asignación de Adición\n    num1 += num2;\n    // -- Asignación de Resta\n    num1 -= num2;\n    // -- Asignación de Multiplicación\n    num1 *= num2;\n    // -- Asignación de División\n    num1 /= num2;\n    // -- Asignación de Residuó\n    num1 %= num2;\n    // -- Asignación de Exponenciación\n    num1 **= num2;\n    // -- Asignación de Desplazamiento a la izquierda\n    num1 <<= num2;\n    // -- Asignación de Desplazamiento a la derecha\n    num1 >>= num2;\n    // -- Asignación de Desplazamiento a la derecha sin tipo\n    num1 >>>= num2;\n    // -- Asignación AND bit a bit\n    num1 &= num2;\n    // -- Asignación XOR bit a bit\n    num1 ^= num2;\n    // -- Asignación OR bit a bit\n    num1 |= num2;\n    // -- Asignación AND lógico\n    num1 &&= num2;\n    // -- Asignación OR lógico\n    num1 ||= num2;\n    // -- Asignación de anulación lógico\n    num1 ??= num2;\n// 5º Identidad: Son operadores que nos permiten comparar la igualdad estricta entre valores\n    // -- ===\n    valido2 = nombre1 === nombre2; // Devuelve TRUE si los dos operadores coinciden en tipo y dato\n    // -- !==\n    valido2 = nombre1 !== nombre2; // Devuelve TRUE si los dos operadores no coinciden ni en tipo ni en dato\n// 6º Pertenencia\n    // -- Como total TypeScript no tiene operadores de pertenencia pero si tiene métodos propios como un .includes()\n// 7º Bits\n    // -- Operador AND a nivel de Bits\n    let bits = 5 & 3;  // 0101 & 0011 = 0001\n    console.log(bits);  // 1\n    // -- Operador OR a nivel de Bits\n    bits = 5 | 3;  // 0101 | 0011 = 0111\n    console.log(bits);  // 7\n    // -- Operador XOR a nivel de Bits\n    bits = 5 ^ 3;  // 0101 ^ 0011 = 0110\n    console.log(bits);  // 6\n    // -- Desplazamiento a la izquierda\n    bits = 5 << 1;  // 0101 << 1 = 1010\n    console.log(bits);  // 10\n    // -- Desplazamiento a la derecha\n    bits = 5 >> 1;  // 0101 >> 1 = 0010\n    console.log(bits);  // 2\n    // -- Desplazamiento a la derecha sin signo\n    bits = -5 >>> 1;  // 11111111111111111111111111111011 >>> 1 = 01111111111111111111111111111101\n    console.log(bits);  // 2147483645\n// 8º Ternarios\n    let edadTer: number = 20;\n    let mensaje : string = (edadTer >= 18) ? \"Eres mayor de edad\" : \"Eres menor de edad\";\n// 9º Tipos de estructuras de control\n    // If con sus variantes:\n    let edad : number = 19\n    // -- if\n    if(edad > 18){console.log('Eres mayor de edad');}\n    // -- if con else\n    if(edad > 18){console.log('Eres mayor de edad')}else{console.log('Aun te queda')}\n    // Si una condición no se cumple se hace la otra\n    // -- if con elseif y else\n    if (edad < 18) {\n        console.log(\"Eres menor de edad.\");\n    } else if (edad >= 18 && edad < 65) {\n        console.log(\"Eres un adulto.\");\n    } else {\n        console.log(\"Eres un viejito.\");\n    }\n    // -- switch\n    let dia : number = 1;\n    let diaSemana : string = '';\n    switch(dia){\n        case 1:\n            diaSemana = 'Lunes';\n            break;\n        case 2:\n            diaSemana = 'Martes';\n            break;\n        case 3:\n            diaSemana = 'Miércoles';\n            break;     \n    }\n    console.log(diaSemana);\n    // Se ejecuta el código pero solo la porción de texto que coindice con el case, si se quita el break, se ejecutará todo para abajo\n    // -- for\n    for(let i : number = 0; i < 10; i++){console.log(i);} // Nos hace un bucle que vaya printando el estado de la i durante su ejecución\n    // -- for-in\n    for (let i in Object) {\n        console.log(i)\n        // Se ejecuta para cada propiedad del objeto\n    }\n    // -- for-of\n    let numeros : Array<number> = [1,2,3,4,5,6,7,8,9,0];\n    for (let e of numeros) {\n        console.log(e);\n    }\n    // -- break\n    for (let i : number = 0; i < 10; i++) {\n        if (i === 8) {\n            console.log(i);\n            break; // termina el bucle si i es igual a 8\n        }\n    }\n    for (let i : number = 0; i < 10; i++) {\n        if (i === 8) {\n            console.log(i);\n            continue; // pasa a la siguiente iteración si i es igual a 8\n        }\n        // Se ejecuta en cada iteración, excepto cuando i es igual a 8\n    }      \n    // -- while\n    let condicion : number = 0;\n    while(condicion < 10){\n        console.log(condicion); \n        condicion++;\n    }\n    // Se ejecuta mientras lo que haya en el while sea verdadero\n    // -- dowhile\n    do {\n        console.log(condicion);\n        condicion++;\n    } while (condicion < 10);\n    // Se ejecuta al menos una vez y luego mientras la condición sea verdadera\n// 10º Ejercicio Extra\nfor(let i : number = 10; i <= 55; i++){\n    if(i % 2 == 0 && i != 16 && i % 3 != 0){\n        console.log(i);\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/Jaimerocel96.ts",
    "content": "let n: number = 20;\nlet m: number = 5;\nlet b: number = 2;\n\nconsole.log(`[SUMA]: ${n} + ${m} = ${(n+m)}`);\nconsole.log(`[RESTA]: ${n} + ${m} = ${(n-m)}`);\nconsole.log(`[MULTIPLICACIÓN]: ${n} * ${m} = ${(n*m)}`);\nconsole.log(`[DIVISIÓN]: ${n} / ${m} = ${(n/m)}`);\nconsole.log(`[MÓDULO]: ${n} % ${m} = ${(n%m)}`);\nconsole.log(`[POTENCIA]: ${m} ** ${b} = ${(m**b)}`);\n\n\nconsole.log(`${n} === ${m} = ${n === m}`);\nconsole.log(`${n} !== ${m} = ${n !== m}`);\nconsole.log(`${n} == ${m} = ${n == m}`);\nconsole.log(`${n} != ${m} = ${n != m}`);\nconsole.log(`${n} > ${m} = ${n > m}`);\nconsole.log(`${n} < ${m} = ${n < m}`);\nconsole.log(`${n} >= ${m} = ${n >= m}`);\nconsole.log(`${n} <= ${m} = ${n <= m}`);\n\nif(b >= m){\n    console.log([`[IF] Condición if`]);\n}else if(n <= m){\n    console.log([`[ELSE IF] Condición else if`]);\n}else{\n    console.log([`[ELSE] Condición else`]);\n}\n\nlet opcion = 0;\nswitch(opcion){\n    case 0:\n        console.log(`[SWITCH] Opción 0`);\n        break;\n    case 1: \n        console.log(`[SWITCH] Opción 1`);\n        break;\n    default:\n        console.log(`[SWITCH] Opción por defecto`);\n        break;\n}\n\n\nfor(let i = 0; i < 5; i++){\n    console.log(`[${i}] Bucle for`);\n}\n\nlet j: number = 0;\nwhile(j < 5){\n    console.log(`[${j}] Bucle while`);\n    j++;\n}\n\nlet k: number = 0;\ndo{\n    console.log(`[${k}] Bucle do-while`);\n    k++;\n}while(k === 0)\n\nfunction imprimirNumeros(n: number, m: number){\n    for(; n <= m; n++){\n        if((n % 2 === 0) && (n % 3 !== 0) && (n !== 16)){\n            console.log(n);\n        }\n    }\n}\n\nimprimirNumeros(10,55);"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/MiguelAngelEc.ts",
    "content": "\n// Operadores Aritmeticos\n//suma\nlet suma:number = 1 + 1\nconsole.log(`La Suma es ${suma}`)\n//resta\nlet resta:number = 2 - 1\nconsole.log(`La Resta es ${resta}`)\n//multiplicacion\nlet multiplicacion:number = 2 * 2\nconsole.log(`La Multiplicacion es ${multiplicacion}`)\n//division\nlet division:number = 4 / 2\nconsole.log(`La Division es ${division}`)\n//modulo\nlet modulo:number = 5 % 2\nconsole.log(`El Modulo es ${modulo}`)\n//incremento\nlet incremento:number = 1\nincremento++\nconsole.log(`El Incremento es ${incremento}`)\n//decremento\nlet decremento:number = 1\ndecremento--\nconsole.log(`El Decremento es ${decremento}`)\n//exponenciacion\nlet exponenciacion:number = 2 ** 3\nconsole.log(`La Exponenciacion es ${exponenciacion}`)\nlet resto:number = 5 % 2\nconsole.log(`El Resto es ${resto}`)\n\n// Operadores Logicos\n//and\nlet and:boolean = true && true\n//or\nlet or:boolean = true || false\n//not\nlet not:boolean = !true\n\n//condicionales\nfunction condicionales(num: number) {\n    if (num >= 18) {\n        console.log(\"Mayor de edad\")\n    } else if (isNaN(num)) {\n        console.log(\"Porfavor ingrese un numero valido\")\n    } else {\n        console.log(\"Menor de edad\")\n    }\n}\nlet edadVar = condicionales(18)\nconsole.log(edadVar)\n\nwhile(1<2){\n    console.log(\"while\")\n}\n\n//iterativas\nfor (let i:number = 0; i < 10; i++) {\n    console.log(i)\n}\n\n//excepciones\ntry {\n    console.log(\"try\")\n} catch (error) {\n    console.log(\"catch\")\n} finally {\n    console.log(\"finally\")\n}\n\n//DIFICULTAD EXTRA (opcional):\n//Crea un programa que imprima por consola todos los números comprendidos\n//entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\nlet i: number = 10;\n\nwhile (i <= 55) {\n    if (i !== 16 && i % 3 !== 0) {\n        console.log(i);\n    }\n    i++; \n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/NavarroEmiliano.ts",
    "content": "/* =============Arithmetic operators ============= */\nlet num1: number = 10;\nlet num2: number = 5;\n\n//Addition operator\nlet sum: number = num1 + num2; // 15\n\n//Subtraction operator\nlet difference: number = num1 - num2; // 5\n\n//Multiplication operator\nlet product: number = num1 * num2; // 50\n\n//Division operator\nlet quotient: number = num1 / num2; // 2\n\n//Modulus operator\nlet remainder: number = num1 % num2; // 0\n\n//Exponentiation operator\nlet power: number = num1 ** num2; // 100000\n\n//Increment operator\nlet postIncrement: number = num1++; // Returns the value of num1 (10), then increments num1 by 1 (11)\nlet preIncrement: number = ++num1; // Increments num1 by 1 (12), then returns the value of num1 (12)\n\n//Decrement operator\nlet postDecrement: number = num1--; // Returns the value of num1 (12), then decrements num1 by 1 (11)\nlet preDecrement: number = --num1; // Decrements num1 by 1 (10), then returns the value of num1 (10)\n\n//Unary plus operator\nlet unaryPlus: number = +num1; // Try to convert num1 to a number if possible, otherwise returns NaN\n\n//Unary minus operator\nlet unaryMinus: number = -num1; // Try to convert num1 to a number if possible, then negates it finally returns the value or NaN\n\n/* =============Logical operators ============= */\nlet isTrue: boolean = true;\nlet isFalse: boolean = false;\n\n// Logical AND operator (&&)\n// The logical AND operator (&&) evaluates operands from left to right.\n// 1. If both operands are true, it returns true.\n// 2. If any operand is false, it returns false.\n// 3. If the first operand is falsy, it returns that value without evaluating the second operand (short-circuit).\n// 4. If the first operand is truthy, it returns the value of the second operand.\n\n// Behavior with boolean values:\nlet andResult1: boolean = true && true; // true\nlet andResult2: boolean = true && false; // false\nlet andResult3: boolean = false && true; // false\nlet andResult4: boolean = false && false; // false\n\n// Short-circuit evaluation and non-boolean values:\nlet andShortCircuit1: any = 0 && 'hello'; // 0 (falsy, short-circuits)\nlet andShortCircuit2: any = 1 && 'hello'; // \"hello\"\nlet andShortCircuit3: any = 'hello' && 0; // 0\nlet andShortCircuit4: any = null && undefined; // null (falsy, short-circuits)\n\n// Truthy and falsy values:\n// Falsy: false, 0, -0, 0n, \"\", null, undefined, NaN\n// Truthy: Everything else, including \"0\", \"false\", [], {}, function(){}\n\n// Type coercion:\nlet andCoercion1: any = '5' && 2; // 2 (string \"5\" is truthy)\nlet andCoercion2: any = [] && 'hello'; // \"hello\" (empty array is truthy)\n\n// In this specific case:\nlet andResult: boolean = isTrue && isFalse; // false (because isFalse is false)\n\n// Note: When used with boolean operands, && always returns a boolean.\n// When used with non-boolean operands, it may return a non-boolean value.\n\n//Logical OR operator\nlet orResult: boolean = isTrue || isFalse; // true\n\n// Logical OR operator (||)\n// The logical OR operator (||) evaluates operands from left to right.\n// 1. If either operand is true, it returns true.\n// 2. If both operands are false, it returns false.\n// 3. If the first operand is truthy, it returns that value without evaluating the second operand (short-circuit).\n// 4. If the first operand is falsy, it returns the value of the second operand.\n\n// Behavior with boolean values:\nlet orResult1: boolean = true || true; // true\nlet orResult2: boolean = true || false; // true\nlet orResult3: boolean = false || true; // true\nlet orResult4: boolean = false || false; // false\n\n// Short-circuit evaluation and non-boolean values:\nlet orShortCircuit1: any = 1 || 'hello'; // 1 (truthy, short-circuits)\nlet orShortCircuit2: any = 0 || 'hello'; // \"hello\"\nlet orShortCircuit3: any = 'hello' || 0; // \"hello\" (truthy, short-circuits)\nlet orShortCircuit4: any = null || undefined; // undefined\n\n// Truthy and falsy values:\n// Falsy: false, 0, -0, 0n, \"\", null, undefined, NaN\n// Truthy: Everything else, including \"0\", \"false\", [], {}, function(){}\n\n// Type coercion:\nlet orCoercion1: any = '' || 2; // 2 (empty string is falsy)\nlet orCoercion2: any = [] || 'hello'; // [] (empty array is truthy, short-circuits)\n\n// In this specific case:\nlet orResultFinal: boolean = isTrue || isFalse; // true (because isTrue is true)\n\n// Note: When used with boolean operands, || always returns a boolean.\n// When used with non-boolean operands, it may return a non-boolean value.\n\n//Logical NOT operator\nlet notResult: boolean = !isTrue; // false\n\n//Logical NOT operator (!)\n// The logical NOT operator (!) converts its operand to a boolean value and returns the opposite value.\n// 1. If the operand is truthy, it returns false.\n// 2. If the operand is falsy, it returns true.\n\n/* ============= Comparison operators ============= */\n\n// num1 = 10; num2 = 5;\nlet comparison1: boolean = num1 == num2; // false -- returns true if the values are the same\nlet comparison2: boolean = num1 != num2; // true -- returns true if the values are not the same\nlet comparison3: boolean = num1 === num2; // false -- returns true if the values are the same and of the same type\nlet comparison4: boolean = num1 !== num2; // true -- returns true if the values are not the same or of different type\nlet comparison5: boolean = num1 > num2; // true -- returns true if num1 is greater than num2\nlet comparison6: boolean = num1 < num2; // false -- returns true if num1 is less than num2\nlet comparison7: boolean = num1 >= num2; // true -- returns true if num1 is greater than or equal to num2\nlet comparison8: boolean = num1 <= num2; // false -- returns true if num1 is less than or equal to num2\n\n/* ============= Assignment operators ============= */\n\n// Assignment operators\n\nlet x: number = 10;\nx += 5; // x = x + 5; // Adds 5 to x and assigns the result to x\nx -= 3; // x = x - 3; // Subtracts 3 from x and assigns the result to x\nx *= 2; // x = x * 2; // Multiplies x by 2 and assigns the result to x\nx /= 4; // x = x / 4; // Divides x by 4 and assigns the result to x\nx %= 3; // x = x % 3; // Calculates the remainder when x is divided by 3 and assigns it to x\nx **= 2; // x = x ** 2; // Raises x to the power of 2 and assigns the result to x\n\nlet y: number = 5;\ny <<= 1; // y = y << 1; // Left shifts y by 1 bit and assigns the result to y\ny >>= 1; // y = y >> 1; // Right shifts y by 1 bit and assigns the result to y\ny >>>= 1; // y = y >>> 1; // Unsigned right shifts y by 1 bit and assigns the result to y\n\nlet z: number = 7;\nz &= 3; // z = z & 3; // Performs bitwise AND on z and 3, assigns the result to z\nz |= 4; // z = z | 4; // Performs bitwise OR on z and 4, assigns the result to z\nz ^= 2; // z = z ^ 2; // Performs bitwise XOR on z and 2, assigns the result to z\n\nlet str: string = 'Hello';\nstr += ' World'; // str = str + \" World\"; // Concatenates \" World\" to str and assigns the result to str\n\n/* ============= Belonging operators ============= */\n\n// in operator (for objects and arrays)\nlet person = { name: 'John', age: 30 };\nlet car = ['Toyota', 'Honda', 'Ford'];\n\nconsole.log('name' in person); // true\nconsole.log('color' in person); // false\nconsole.log(0 in car); // true (0 is a valid index)\nconsole.log(3 in car); // false (index 3 doesn't exist)\n\n// instanceof operator (for objects)\nclass Animal {}\nclass Dog extends Animal {}\n\nlet myDog = new Dog();\n\nconsole.log(myDog instanceof Dog); // true\nconsole.log(myDog instanceof Animal); // true\nconsole.log(myDog instanceof Object); // true\n\n// Array.includes() method (for arrays)\nlet fruits = ['apple', 'banana', 'orange'];\n\nconsole.log(fruits.includes('banana')); // true\nconsole.log(fruits.includes('grape')); // false\n\n// Object.hasOwnProperty() method (for objects)\nlet book = { title: 'TypeScript Guide', pages: 200 };\n\nconsole.log(book.hasOwnProperty('title')); // true\nconsole.log(book.hasOwnProperty('author')); // false\n\n// String.includes() method (for strings)\nlet sentence = 'The quick brown fox jumps over the lazy dog';\n\nconsole.log(sentence.includes('fox')); // true\nconsole.log(sentence.includes('cat')); // false\n\n/* ============= Bitwise operators ============= */\n\n// Bitwise AND (&)\n// Performs a bitwise AND operation on each pair of bits\nlet a: number = 5; // 0101 in binary\nlet b: number = 3; // 0011 in binary\nconsole.log(a & b); // 0001 in binary, outputs 1\n\n// Bitwise OR (|)\n// Performs a bitwise OR operation on each pair of bits\nconsole.log(a | b); // 0111 in binary, outputs 7\n\n// Bitwise XOR (^)\n// Performs a bitwise XOR operation on each pair of bits\nconsole.log(a ^ b); // 0110 in binary, outputs 6\n\n// Bitwise NOT (~)\n// Inverts all the bits in a single number\nconsole.log(~a); // 1010 in binary, outputs -6 (due to two's complement)\n\n// Left shift (<<)\n// Shifts the bits of the first operand left by the number of places specified in the second operand\nconsole.log(a << 1); // 1010 in binary, outputs 10\n\n// Sign-propagating right shift (>>)\n// Shifts the bits of the first operand right by the number of places specified in the second operand\nconsole.log(a >> 1); // 0010 in binary, outputs 2\n\n// Zero-fill right shift (>>>)\n// Shifts the bits of the first operand right by the number of places specified in the second operand, and shifts in zeros from the left\nlet c: number = -5; // 11111111111111111111111111111011 in binary (32-bit)\nconsole.log(c >>> 1); // 01111111111111111111111111111101 in binary, outputs 2147483645\n\n/* ============= Control structures ============= */\n//if statement\nif (2 > 1) {\n  console.log('2 is greater than 1');\n}\n\n//if else statement\nif (10 > 5) {\n  console.log('10 is greater than 5');\n} else {\n  console.log('x is equal to 5');\n}\n\n//if else if statement\n\nif (10 > 5) {\n  console.log('10 is greater than 5');\n} else if (10 < 5) {\n  console.log('10 is less than 5');\n} else {\n  console.log('10 is equal to 5');\n}\n\n//switch statement\nlet day: number = 3;\n\nswitch (day) {\n  case 1:\n    console.log('Monday');\n    break;\n  case 2:\n    console.log('Tuesday');\n    break;\n}\n\n//iterative statement\nfor (let i: number = 0; i < 10; i++) {\n  console.log(i);\n}\n\n//while statement\nlet i: number = 0;\nwhile (i < 10) {\n  console.log(i);\n  i++;\n}\n\n//do while statement\nlet j: number = 0;\ndo {\n  console.log(j);\n  j++;\n} while (j < 10);\n\n//for of statement\nlet colors: string[] = ['red', 'green', 'blue'];\n\nfor (let color of colors) {\n  console.log(color);\n}\n\n//for in statement\nlet student: { name: string; age: number } = { name: 'John', age: 30 };\n\nfor (let key in student) {\n  console.log(key);\n}\n\n// exception handling\ntry {\n  throw new Error('This is a test error');\n} catch (error) {\n  console.log(error);\n}\n\n// finally statement\ntry {\n  throw new Error('This is a test error');\n} catch (error) {\n  console.log(error);\n} finally {\n  console.log('This is the finally block');\n}\n\n// throw statement\n//throw new Error('This is a test error');\n\n/* ============= Optional Programming ============= */\n\nlet myNumber: number = 10;\n\nwhile (myNumber <= 55 ) {\n  const isMultipleOfThree: boolean = myNumber % 3 === 0;\n  const isPair: boolean = myNumber % 2 === 0;\n  const notSixteen: boolean = myNumber !== 16;\n\n  if(!isMultipleOfThree && notSixteen && isPair){\n    console.log(myNumber);\n  }\n  myNumber++; \n}\n\n// Output array: [10, 14, 20, 22, 26, 28, 32, 34, 38, 40, 44, 46, 50, 52]\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/RicJDev.ts",
    "content": "//EJERCICIO\n//OPERADORES\n//-Aritmeticos-\nlet num: number = 20;\nlet num1: number = 2;\n\nconst add = num + num1;\nconst multiplication = num * num1;\nconst substract = num - num1;\nconst division = num / num1;\nconst remainder = num % num1;\nconst exponent = num ** num1;\n\nconsole.log(add); //suma\nconsole.log(multiplication); //multiplicación\nconsole.log(substract); //resta\nconsole.log(division); //división\nconsole.log(remainder); //resto\nconsole.log(exponent); //potencia\n\n//-De asignacion-\nlet num2: number = 20;\n\nconsole.log((num2 += 2)); //igual a si mismo mas\nconsole.log((num2 -= 1)); //igual a... menos\nconsole.log((num2 *= 2)); //igual a... multiplicado por\nconsole.log((num2 /= 4)); //igual a... entre\nconsole.log(-num2);\n\n///-De comparacion-\nlet firstValue: number = 10;\nlet secondValue: number = 10;\n\nconsole.log(firstValue == secondValue); //equivalente\nconsole.log(firstValue === secondValue); //igual\nconsole.log(firstValue != secondValue); //no equivalente\nconsole.log(firstValue !== secondValue); //no igual\n\nlet num3: number = 4;\nlet num4: number = 2;\n\nconsole.log(num3 > num4); //mayor que\nconsole.log(num3 < num4); //menor que\nconsole.log(num3 >= num4); //mayor o igual que\nconsole.log(num3 <= num4); //menor o igual que\n\n//-Logicos-\nconst myBool1: boolean = true;\nconst myBool2: boolean = false;\nconst myBool3: boolean = true;\n\nconsole.log(myBool1 && myBool3); //And\nconsole.log(myBool1 || myBool2); //Or\nconsole.log(!myBool2); //Negacion\n\n//-De incremento y decremento-\nlet count: number = 0;\nconsole.log(++count);\nconsole.log(count); //pre-incremento\n\nlet count2: number = 0;\nconsole.log(count2++);\nconsole.log(count2); //post-incremento\n\nlet count3: number = 0;\nconsole.log(--count3);\nconsole.log(count3); //pre-decremento\n\nlet count4: number = 0;\nconsole.log(count4--);\nconsole.log(count4); //post-decremento\n\n//-Operadores ternarios-\nlet num5: number = 7;\n\nnum5 > 0 ? console.log('Numero positivo') : console.log('Numero negativo');\n\nnum5 = -5;\n\nnum5 > 0 ? console.log('Numero positivo') : console.log('Numero negativo');\n\n//ESTRUCTURAS DE CONTROL\n//-Condicionales-\n//if\nlet totalPoints: number = 5003;\n\nconsole.log('Nivel completado!');\nif (totalPoints > 5000) {\n\tconsole.log('Logro desbloqueado: maestro espadachin');\n}\n\n//if else\nlet checkEvenNum = (num: number) => {\n\tif (num % 2 === 0) {\n\t\tconsole.log(`${num} es par`);\n\t} else {\n\t\tconsole.log(`${num} no es par`);\n\t}\n};\n\n//Switch\nlet clima: string = 'nublado';\nswitch (clima) {\n\tcase 'lluvioso':\n\t\tconsole.log('Usa impermeable');\n\t\tbreak;\n\tcase 'nublado':\n\t\tconsole.log('Usa abrigo. Puede que llueva');\n\t\tbreak;\n\tcase 'soleado':\n\t\tconsole.log('Sal tranquilo');\n\t\tbreak;\n\tdefault:\n\t\tconsole.log('No necesitas impermeable');\n}\n\n//-Bucles-\n//For\nfor (let i = 0; i <= 5; i++) {\n\tconsole.log(i);\n}\n\n//While\nlet n: number = 5;\n\nwhile (n < 10) {\n\tconsole.log(n);\n\tn++;\n}\n\n//Do/While\nlet m: number = 10;\n\ndo {\n\tconsole.log(m);\n\tm--;\n} while (m > 0);\n\n//EXTRA\nfor (let i = 10; i <= 55; i++) {\n\tif (i !== 55) {\n\t\tif (i !== 16 && i % 3 !== 0 && i % 2 === 0) {\n\t\t\tconsole.log(i);\n\t\t}\n\t} else {\n\t\tconsole.log(i);\n\t}\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/RobertoAmaroHub.ts",
    "content": "function log(text: string) {\n  console.log(text);\n}\n\nlet a: number = 3;\nlet b: number = 2;\nlet res;\nlog(`datos iniciales:`);\nlog(`a = ${a} y b = ${b}`);\n\n//Se utilizan para realizar operaciones matemáticas en programación.\nlog(\"\\nOperadores aritméticos:\");\nres = a + b;\nlog(`la suma de ${a}+${b} = ${res}`);\nres = a - b;\nlog(`la resta de ${a}-${b} = ${res}`);\nres = a * b;\nlog(`la multiplicación de ${a}*${b} = ${res}`);\nres = a / b;\nlog(`la división de ${a}/${b} = ${res}`);\nres = a % b;\nlog(`el módulo de ${a}%${b} = ${res}`);\nres = Math.floor(a / b);\nlog(`la división entera de ${a}//${b} = ${res}`);\nres = a ** b;\nlog(`la exponenciación de ${a}**${b} = ${res}`);\n\n//Se utilizan para comparar dos valores y devolver un resultado booleano que indica la relación entre esos valores.\nlog(\"\\nOperadores de comparación o relacionales:\");\nres = a == b;\nlog(`¿${a} es igual a ${b}? respuesta: ${res}`);\nres = a != b;\nlog(`¿${a} es diferente de ${b}? respuesta: ${res}`);\nres = a < b;\nlog(`¿${a} es menor que ${b}? respuesta: ${res}`);\nres = a > b;\nlog(`¿${a} es mayor que ${b}? respuesta: ${res}`);\nres = a <= b;\nlog(`¿${a} es menor o igual que ${b}? respuesta: ${res}`);\nres = a >= b;\nlog(`¿${a} es mayor o igual que ${b}? respuesta: ${res}`);\nres = ~b;\nlog(`~b = ${res}`);\n\n//Se utilizan para combinar expresiones booleanas y realizar operaciones lógicas en programación.\nlog(\"\\nOperadores lógicos:\");\nres = a < 3 && b < 3;\nlog(`¿es ${a} menor que 3 Y ${b} menor que 3? respuesta: ${res}`);\nres = a < 3 || b < 3;\nlog(`¿es ${a} menor que 3 O ${b} menor que 3? respuesta: ${res}`);\nres = a != b;\nlog(`¿${a} es diferente de ${b}? respuesta: ${res}`);\n\n//Estructuras de control\n\n//Condicionales\n\n//if - else\nif (a == b) {\n  log(`${a} no es igual a ${b}`);\n} else {\n  log(`${a} es igual a ${b}`);\n}\n\n//Switch\nswitch (b) {\n  case 1:\n    console.log(\"Lunes\");\n    break;\n  case 2:\n    console.log(\"Martes\");\n    break;\n  case 3:\n    console.log(\"Miércoles\");\n    break;\n  case 4:\n    console.log(\"Jueves\");\n    break;\n  case 5:\n    console.log(\"Viernes\");\n    break;\n  case 6:\n    console.log(\"Sábado\");\n    break;\n  case 7:\n    console.log(\"Domingo\");\n    break;\n  default:\n    console.log(\"Ese no es un día válido\");\n    break;\n}\n\n//Ternario\nres = b==a ? `${b} es igual a ${a}` : `${b} no es igual a ${a}`;\nlog(res);\n\n//Bucles\n\n//for Loop\nfor (let i = 0; i < b; i++) {\n  console.log (\"Bloque de ejecución n°: \" + i);\n}\n\n//for...of Loop\nlet arrOf: number[] = [10, 20, 30, 40];\nfor (var val of arrOf) {\n  console.log(val);\n}\n\nlet str = \"Hello World\";\nfor (var char of str) {\n  console.log(char); \n}\n\n//for...in Loop\nlet arrIn: number[] =[10, 11, 12, 13]\n\nfor (var index in arrIn) {\n  console.log(`index: ${index}, Value: ${arrIn[index]}`); \n}\n\n//While Loop\nlet whileLoop: number = 0;\nwhile (whileLoop < 4) {\n  console.log( \"whileLoop: \" + whileLoop )\n  whileLoop++;\n}\n\n//do..while loop\nlet doWhileLoop: number = 1;\ndo {\n    console.log(\"doWhileLoop: \" + doWhileLoop )\n    doWhileLoop++;\n} while ( doWhileLoop < 4)\n\n//Try Catch errors\nfunction ejemplo1(valor: string){\n throw new Error(valor) \n}\n\ntry{\n  ejemplo1(\"Este es un error\");\n}catch(error){\n  log(\"error esperado: \"+error)\n}\n\n//DIFICULTAD EXTRA\n\nfor(let i=10; i<=55; i++){\n  if(i!=16 && i%2==0 && i%3!=0){\n    log(`n°:${i}`);\n  }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/Sac-Corts.ts",
    "content": "// Arithmetic Operators\nlet c: number = 10;\nlet b: number = 5;\nconsole.log(\"Addition:\", c + b);\nconsole.log(\"Subtraction:\", c - b);\nconsole.log(\"Multiplication:\", c * b);\nconsole.log(\"Division:\", c / b);\nconsole.log(\"Modulus:\", c % b);\nconsole.log(\"Exponentiation:\", c ** b);\n\n// Logical Operators\nlet isTrue: boolean = true;\nlet isFalse: boolean = false;\nconsole.log(\"AND (&&):\", isTrue && isFalse);\nconsole.log(\"OR (||):\", isTrue || isFalse);\nconsole.log(\"NOT (!):\", !isTrue);\n\n// Comparison Operators\nconsole.log(\"Equal (==):\", c == b);\nconsole.log(\"Not equal (!=):\", c != b);\nconsole.log(\"Strict equal (===):\", c === b);\nconsole.log(\"Strict not equal (!==):\", c !== b);\nconsole.log(\"Greater than (>):\", c > b);\nconsole.log(\"Less than (<):\", c < b);\nconsole.log(\"Greater than or equal (>=):\", c >= b);\nconsole.log(\"Less than or equal (<=):\", c <= b);\n\n// Assignment Operators\nlet x: number = 10;\nx += 5;\nconsole.log(\"x after x += 5:\", x);\nx -= 3;\nconsole.log(\"x after x -= 5:\", x);\nx *= 2;\nconsole.log(\"x after x *= 2:\", x);\nx /= 4;\nconsole.log(\"x after x /= 4:\", x);\nx **= 2;\nconsole.log(\"x after x **= 2:\", x);\nx %= 2;\nconsole.log(\"x after x %= 2:\", x);\n\n// Bitwise Operators\nlet bitA: number = 5; // Binary: 0101\nlet bitB: number = 3; // Binary: 0011\nconsole.log(\"Bitwise AND(&):\", bitA & bitB);\nconsole.log(\"Bitwise OR(|):\", bitA | bitB);\nconsole.log(\"Bitwise XOR(^):\", bitA ^ bitB);\nconsole.log(\"Bitwise NOT(~):\", ~bitA);\nconsole.log(\"Left shift(<<):\", bitA << 1);\nconsole.log(\"Right shift(>>):\", bitA >> 1);\n\n// Control Structures //\n// If-else statement\nif (c > b) {\n    console.log(\"c is greater than b\");\n} else {\n    console.log(\"c is not greater than b\");\n}\n\n// Ternary Operator\nlet max = c > b ? c : b;\nconsole.log(\"Max value:\", max);\n\n// Switch-case statement\nlet day: number = 2;\nswitch(day) {\n    case 1: \n        console.log(\"It's Monday\");\n        break;\n    case 2:\n        console.log(\"It's Tuesday\");\n        break;\n    case 3:\n        console.log(\"It's Wednesday\");\n        break;\n}\n\n// While loop\nlet _count: number = 0;\nwhile (_count < 3) {\n    console.log(\"While loop count:\", _count);\n    _count++;\n}\n\n// For loop\nfor (let i = 0; i < 3; i++) {\n    console.log(\"For loop iteration:\", i);\n}\n\n// Do-while loop\nlet doCount: number = 0;\ndo {\n    console.log(\"Do-while loop count:\", doCount);\n    doCount++;\n} while (doCount < 3);\n\n// Try-catch (Exception Handling)\ntry {\n    let result = c / 0;\n    if (!isFinite(result)) {\n        throw new Error(\"Cannot divide by zero\");\n    }\n} catch (error) {\n    if (error instanceof Error) {\n        console.log(error.message);\n    }\n} finally {\n    console.log(\"Finally block executed\");\n}\n\n// *** Extra Exercise *** //\n\nfor (let i = 10; i <= 55; i++) {\n    if (i % 2 == 0 && i % 3 !== 0 && i !== 16) {\n        console.log(i);\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/Sharah07.ts",
    "content": "//Tipos de operadores en TypeScript\n\n//OPERADORES ARITMÉTICOS\n \nlet n1:number = 4;\nlet n2:number = 6;\n\n//Suma\nconsole.log( n1 + \"+\" + n2 + \"=\" + (n1+n2)); // 4+6=10\n//Resta\nconsole.log( n1 + \"-\" + n2 + \"=\" + (n1-n2)); // 4-6=-2\n//Multiplicación\nconsole.log(n1 + \"*\" + n2 + \"=\" + (n1*n2)); // 4*6=24\n//División\nconsole.log(n1 + \"/\" + n2 + \"=\" + (n1/n2)); // 4/6=0.6666666666666666\n//Módulo\nconsole.log(n1 + \"%\" + n2 + \"=\" + (n1%n2)); // 4%6=4\n\n//OPERADORES DE INCREMENTO Y DECREMENTO\n\n//Incremento\nconsole.log(n1++);\n//Decremento\nconsole.log(n1--);\n\n//OPERADORES DE ASIGNACIÓN\n/**\n * Asignación\n */                                        \nn2 = 8;\nconsole.log(\"Asignación: \" + n2); // Asignación: 8\n/** \n * Asignación de suma\n*/\nlet n3:number = 3;\nn3 += n2;\nconsole.log(\"Asignación de suma: \" + n3); // Asignación de suma: 11\n/** \n * Asignación de resta\n*/\nn3 -= n1;\nconsole.log(\"Asignación de resta: \" + n3); // Asignación de resta: 7\n/**\n * Asignación de multiplicación\n */\nn3 *= n1;\nconsole.log(\"Asignación de multiplicación\" + n3); // Asignación de multiplicación: 28\n/** \n * Asignación de división\n */\nn3 /= n2;\nconsole.log(\"Asignación de división\" + n3); // Asignación de división: 3.5\n\n\n//OPERADORES DE COMPARACIÓN\n/**\n * Igualdad\n */\nconsole.log( n1 == n2 ); // false\n/**\n * Igualdad estricta\n */\nconsole.log(n1 === n2); // false\n/**\n * Desigualdad\n */\nconsole.log(n1 != n2); // true\n/**\n * Desigualdad estricta\n */\nconsole.log(n1 !== n2); // true\n/**\n * Mayor que\n */\nconsole.log(n1 > n2); // false\n/**\n * Mayor o igual que\n */\nconsole.log(n1 >= n2);  //false\n/**\n * Menor que\n */\nconsole.log(n1 < n2); // true\n/**\n * Menor o igual que\n */\nconsole.log(n1 <= n2); // true\n\n//OPERADORES LÓGICOS\nn1 = 2;\nn2 = 3;\nn3 = 3;\n/**\n *   && - AND\n */\nconsole.log(n1 == n2 && n2 ==n3); // false\n/**\n *   || - OR\n */\nconsole.log(n1 == n2 || n2 == n3); // true\n/**\n *   ! - NOT\n */\nconsole.log(!(n1 == n2)); //true\n\n// OPERADORES BITS A BITS\n/**\n *  AND - &\n */\nconsole.log(n1 & n2); //2\n/**\n * \n *  OR - |\n */\nconsole.log(n1 | n2); //3\n/**\n * \n *  XOR - ^\n */\nconsole.log(n1 ^ n2); //1\n/**\n * \n * NOT - ~ \n */\nconsole.log(~(n1 & n2)); //-3\n/**\n * \n * Desplazamiento a la izquierda\n */\nconsole.log(n1 << 1); //4\n/**\n * \n * Desplazamiento a la derecha\n */\nconsole.log(n1 >> 1); //1\n\n\n\n// ESTRUCTURAS DE CONTROL\nn1 = 9;\nn2 = 3;\nn3 = 3;\n\n//Estructuras de control condicionales\n/**\n * if: ejecuta el código si la condición es true.\n */ \nif(n2 == n3){\n    console.log(\"true: la condición es verdadera\"); // true: la condición es verdadera\n}\n/**\n * if else: si la condición es true ejecuta el primer código,\n * de lo contrario ejecuta el segundo.\n */\nif(n2 == n1){\n    console.log(\"true: la condición es verdadera\");\n}else{\n    console.log(\"false: la condición es falsa\"); // false: la condición es falsa\n}\n/**\n * else if: evalúa varias condiciones y ejecuta el código de la\n * que sea true, si ninguna es verdadera ejecuta el bloque de código de else.\n */\nconst edad:number= 28;\n\nif(edad < 18){\n    console.log(\"Eres menor de edad.\");\n}else if(edad >= 18 && edad < 60){\n    console.log(\"Eres mayor de edad\"); // Eres mayor de edad\n}else{\n    console.log(\"Eres adulto mayor.\");\n}\n/**\n * switch: compara la expresion con varios valores(casos) \n * y ejecuta el código del caso con el que coincida.\n */\nconst nota:number= 4;\n\nswitch(nota){\n    case 1:\n        console.log(\"muy malo.\");\n        break;\n    case 2:\n        console.log(\"malo\");\n        break;\n    case 3:\n        console.log(\"regular\");\n        break;\n    case 4:\n        console.log(\"bien\"); // bien\n        break;\n    case 5:\n        console.log(\"excelente\");\n        break;\n    default:\n        console.log(\"Nota no valida\");\n}\n\n// Estructuras de control re repetición (Bucles)\n/**\n * for: repiten un bloque de código una cantidad específica de veces.\n */\nfor(let i = 0; i < 6; i++){\n    console.log(\"vuelta #\", i); //vuelta # 0, vuelta # 1, vuelta # 2, vuelta # 3, vuelta # 4, vuelta # 5\n}\n/**\n * for of: recorre los valores de una lista.\n */\nconst dias = [\"lunes\", \"martes\", \"miercoles\", \"jueves\", \"viernes\"]; \nfor(const dia of dias){\n    console.log(dia); //lunes, martes, miercoles, jueves, viernes\n}\n/**\n * for in: recorre las claves o índices del objeto.\n */\nconst nombres = [\"Seira\", \"Juan\", \"Stiven\", \"Luisa\"];\nfor(const nombre in nombres){\n    console.log(nombre); //0, 1, 2, 3\n}\n/**\n * while: ejecuta un bloque de código mientras la condición sea verdadera,\n * si la condición desde el inicio el falsa, no se ejecuta nada.\n */\nlet i= 1;\nwhile(i < 6){\n    console.log(i); //1, 2, 3, 4, 5\n    i++;\n} \n/**\n * do while: ejecuta el bloque de código al menos una vez, sin importar si la condición\n * es false o true, debido a que la condición se evalúa al final.\n */\nlet no = 8;\ndo{\n    console.log(no); //8\n    no++\n}while(no < 5);\n\n// Estructuras de control de manejo de errores\n/**\n *  try catch\n */\nfunction validarEdad(edad:number) {\n    try{    \n        if(edad < 0){\n            throw new Error(\"Cómo vas a tener de edad un número negativo!?, Sopenco!!\");\n        }else if(edad == 0){\n            throw new Error(\"No se puede 0\");\n        }\n        return console.log(\"edad: \", edad);\n    }catch (error){\n        console.log(\"Error: \", error.message);\n    }    \n}\n\nvalidarEdad(-6); //Error:  Cómo vas a tener de edad un número negativo!?, Sopenco!!\nvalidarEdad(0); //Error:  No se puede 0\nvalidarEdad(21); //edad:  21\n\n//Estructuras de control especiales.\n/**\n * break\n */\nlet numeros = [2, 6, 4, 9, 8, 10];\n\nfor(let numero of numeros){\n    if(numero % 2 != 0){\n        console.log(\"Primer número impar: \", numero); //Primer número impar: 9\n        break; \n    }\n}\n/**\n * continue\n */\n\nfor(i=0; i < 10; i++){\n    if(i % 2 != 0){\n        continue;\n    }\n    console.log(i); //0, 2, 4, 6, 8\n}\n/**\n * return: devuelve un valor desde una función \n * al punto donde se invoca y termina la función.\n */\nfunction numero(a:number){\n    if(a < 0){\n        return console.log(\"Número negativo\");\n    }\n    console.log(\"Número positivo\");\n} \n\nnumero(8);\nnumero(-4);\n\n\n// DIFICULTAD EXTRA\n\nfor(i= 10; i >= 10 && i <= 55; i++){\n    if(i % 2 != 0 || i % 3 == 0 || i == 16){\n        continue;\n    }\n    console.log(i); // 10, 14, 20, 22, 26, 28, 32, 34, 38, 40, 44, 46, 50, 52\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/Waldid32.ts",
    "content": "\n// Operadores Aritméticos\nlet suma: number = 2 + 4;\nlet resta: number = 2 - 4;\nlet multiplicar: number = 2 * 4;\nlet division: number = 2 / 4;\n\nconsole.log(\"Operadores Aritméticos\");\nconsole.log(\"Resultado de la suma \", suma);\nconsole.log(\"Resultado de  la resta \", resta);\nconsole.log(\"Resultado de  la multiplicación \", multiplicar);\nconsole.log(\"Resultado de  la división \", division);\n\nconsole.log(\"---------------------------------------------------------------------\")\n\n// Operadores Lógicos\nconst logicoY: boolean = false && true;\nconst logicoO: boolean = false || true;\nconst logicoNot: boolean = !false;\n\nconsole.log(\"Operadores Lógicos\");\nconsole.log(\"Resultado && \", logicoY);\nconsole.log(\"Resultado || \", logicoO);\nconsole.log(\"Resultado Not \", logicoNot);\n\nconsole.log(\"---------------------------------------------------------------------\")\n\n// Operadores de comparación\n// El operador < y <= devuelve true cuando el 1 valor es menor al 2 valor. valor: 1 - valor: 2.\nlet comparacionMenor: boolean = 1 < 2;\nlet comparacionMenorIgual: boolean = 1 <= 2;\n\n// El operador < y <= devuelve true cuando el 1 valor es mayor al 2 valor. valor: 3 - valor: 2.\nlet comparacionMayor: boolean = 3 > 2;\nlet comparacionMayorIgual: boolean = 3 >= 2;\n\n// El operador ==  devuelve true cuando el 1 valor es igual al 2 valor. valor: 4 - valor: 4.\nlet comparacionIgual: boolean = 4 == 4;\n\n// El operador ===  devuelve true cuando el 1 valor es estrictamente igual al 2 valor. valor: 5 - valor: 5.\nlet comparacionIgualIgual: boolean = '5' === '5';\n\nconsole.log(\"Operadores Comparaciones\");\nconsole.log(\"Operador < \", comparacionMenor);\nconsole.log(\"Operador <= \", comparacionMenorIgual);\nconsole.log(\"Operador > \", comparacionMayor);\nconsole.log(\"Operador >= \", comparacionMayorIgual);\nconsole.log(\"Operador == \", comparacionIgual);\nconsole.log(\"Operador === \", comparacionIgualIgual);\n\nconsole.log(\"---------------------------------------------------------------------\");\n\n// Operadores de asignación\nlet asignarTexto: string = '';\nconsole.log(\"Variable Texto\", asignarTexto);\n\nasignarTexto = \"Aprendiendo TS.\";\nconsole.log(`Asignando texto a la variable vacia ${asignarTexto}`)\n\nconsole.log(\"---------------------------------------------------------------------\");\n\n// Operadores de Identidad\n// No tengo conocimiento si estos existe en TS.\n\n// Estructuras de control\n\n// Condicionales\nlet numeroUno: number = 2;\nlet numeroDos: number = 3;\nif (2 > 4) {\n    console.log(`El valor ${numeroUno} es mayor al valor ${numeroDos}`)\n} else {\n    console.log(`El valor ${numeroUno} es menor al valor ${numeroDos}`)\n}\n\n// Iterativas\nfor (let ite = 0; ite < numeroDos; ite++) {\n    console.log(\"Iterando :\", ite)\n}\n\nconsole.log(\"---------------------------------------------------------------------\");\n\n// Reto Opcional\n// Crear un programa que imprima por consola todos los números comprendidos - entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\nconsole.log(\"Dificulta Extra\")\nfor (let numeros = 10; numeros <= 55; numeros++) {\n    if (numeros % 2 === 0 && numeros !== 16 && numeros % 3 !== 0) {\n        console.log(numeros)\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/XhuaSpy.ts",
    "content": "/* Los operadores son herramientas lógicas y matematicas que nos ayudan\n * a trabajar con los datos del sistema, haciendo asignaciones, comparaciones\n * y como su nombre mismo lo indica, operando estos datos de diferentes maneras\n * */ \n\nconsole.log(\"------------------------------------\")\n\nconsole.log(\"Operadores matematicos\\n\");\nconsole.log(1 + 2); // -> Suma\nconsole.log(3 - 2); // -> resta\nconsole.log(1 * 2); // -> multiplicacion\nconsole.log(1 / 2); // -> divicion\nconsole.log(1 % 2); // -> Resto\nconsole.log(1 ** 2); // -> Potenciacion\n\nconsole.log(\"------------------------------------\")\n\nconst numbers = [10, 20, 30, 40, 50, 60, 70, 80];\n\nfor (let i = 0; i < numbers.length; i++) {\n    const mod = i % 2;\n    console.log(numbers[i], numbers[mod], mod);\n}\n\nconsole.log(\"------------------------------------\")\n\nconsole.log(\"Operadores de Asignación.\\n\")\nlet _variable_1 : number;\n\n_variable_1 = 1;\n_variable_1 += 4;\n_variable_1 -= 2;\n_variable_1 *= 4;\n_variable_1 /= 2;\n_variable_1 **= 2;\n\nconsole.log(_variable_1);\n\n_variable_1 %= 7;\n\nconsole.log(\"------------------------------------\")\n\nconsole.log(\"Operadores unarios\\n\");\nconsole.log(++_variable_1); // Primero suma y despues muestra\nconsole.log(_variable_1++); // Primero muestra y luego suma \nconsole.log(_variable_1--);\nconsole.log(--_variable_1);\n\nconsole.log(\"------------------------------------\")\n\nconst P : boolean = false;\nconst Q : boolean = true;\n\nconsole.log(\"Operadores lógicos\")\nconsole.log(!P);\nconsole.log(!Q);\nconsole.log(P && Q);\nconsole.log(!P && Q);\nconsole.log(P || Q);\nconsole.log(!P || Q);\n\nconsole.log(\"------------------------------------\")\n\nconsole.log(\"Operadores de igualdad\")\n\nconst uno : number = 1;\nconst dos : number = 2;\nconst tres : number = 3;\n\nconsole.log( uno == uno );\nconsole.log( dos <= tres );\nconsole.log( dos >= tres );\nconsole.log( dos == tres );\nconsole.log( uno < dos );\nconsole.log( uno > dos );\nconsole.log( uno != dos );\n\nconsole.log(\"------------------------------------\")\n\nconsole.log(\"Nullish Coalescing\")\nconsole.log(_variable_1 ?? 3);\n\nlet q;\n\nconsole.log(q ?? 3);\nconsole.log(q)\n\nconsole.log(\"------------------------------------\")\nconsole.log(\"------------------------------------\")\n\nconsole.log(\"Estructuras de control\")\n\nconsole.log(\"------------------------------------\")\n\nif (\"puto el que lo lea\".length > 0 )\n    console.log(\"Ya lo leiste jssjjs\");\nelse \n    console.log(\"Igual eres tremenda p***\");\n\nconsole.log(\"------------------------------------\")\n\nfor(let i = 1; i < 5; i++)\n    console.log(i)\n\nconsole.log(\"------------------------------------\")\n\ndo {\n    console.log(\"Primero beso y despues pregunto\");\n} while (false);\n\nconsole.log(\"------------------------------------\")\n\nwhile(true) {\n    console.log(\"Primero pregunto y despues beso\");\n    break;\n}\n\nconsole.log(\"------------------------------------\")\nconsole.log(\"------------------------------------\")\n\nfor(let i = 10; i <= 55; i++)\n    if(i != 16 && !(i % 3 == 0) )\n        console.log(i)\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/angelsanchezt.ts",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n*/\n\n// OPCIONAL: Ejecución del Script.\n// Prerrequisitos:\n//      1. Instalación de Node y NPM\n// Instalación de Typescript de forma global:\n//      npm install -g typescript\n// Transpilar el codigo de Typescript a Javascript\n//      tsc angelsanchezt.ts\n// Ejecutar el codigo de Javascipt generado\n//      node angelsachezt.js\n\n// 1. Operadores\n\n// Aritméticos\nlet suma: number = 10 + 5;\nlet resta: number = 20 - 7;\nlet multiplicacion: number = 6 * 8;\nlet division: number = 36 / 4;\nlet modulo: number = 15 % 4;\n\n// Lógicos\nlet andLogico: boolean = true && false;\nlet orLogico: boolean = true || false;\nlet notLogico: boolean = !true;\n\n// De comparación\nlet igual: boolean = 5 === 5;\nlet noIgual: boolean = (10 as number) !== (5 as number);\nlet mayorQue: boolean = 15 > 10;\nlet menorQue: boolean = 25 < 30;\nlet mayorIgual: boolean = 20 >= 18;\nlet menorIgual: boolean = 12 <= 15;\n\n// De asignación\nlet x: number = 5;\nx += 3; // x ahora es 8\n\n// De identidad\nlet a: number = 10;\nlet b: number = 10;\nlet identidad: boolean = a === b;\n\n// De pertenencia\nlet miArreglo: number[] = [1, 2, 3, 4, 5];\nlet pertenece: boolean = miArreglo.includes(3);\n\n// Bits\nlet bitAnd: number = 5 & 3; // Operación AND a nivel de bits\nlet bitOr: number = 5 | 3;  // Operación OR a nivel de bits\nlet bitXor: number = 5 ^ 3; // Operación XOR a nivel de bits\nlet desplazamientoIzquierda: number = 8 << 2; // Desplazamiento a la izquierda\nlet desplazamientoDerecha: number = 8 >> 1;  // Desplazamiento a la derecha\n\n// 2. Estructuras de control\n\n// Condicionales\nlet numeroCondicional: number = 25;\nif (numeroCondicional > 20) {\n    console.log(\"El número es mayor que 20\");\n} else if (numeroCondicional === 20) {\n    console.log(\"El número es igual a 20\");\n} else {\n    console.log(\"El número es menor que 20\");\n}\n\n// Iterativas\nfor (let i = 10; i <= 55; i++) {\n    if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n        console.log(i);\n    }\n}\n\n// Excepciones\ntry {\n    throw new Error(\"Este es un ejemplo de excepción\");\n} catch (error) {\n    console.error(error.message);\n}\n\n// 3. Imprimir resultados por consola\nconsole.log(\"Suma:\", suma);\nconsole.log(\"Resta:\", resta);\nconsole.log(\"Multiplicación:\", multiplicacion);\nconsole.log(\"División:\", division);\nconsole.log(\"Módulo:\", modulo);\n\nconsole.log(\"AND Lógico:\", andLogico);\nconsole.log(\"OR Lógico:\", orLogico);\nconsole.log(\"NOT Lógico:\", notLogico);\n\nconsole.log(\"Igualdad:\", igual);\nconsole.log(\"No igualdad:\", noIgual);\nconsole.log(\"Mayor que:\", mayorQue);\nconsole.log(\"Menor que:\", menorQue);\nconsole.log(\"Mayor o igual que:\", mayorIgual);\nconsole.log(\"Menor o igual que:\", menorIgual);\n\nconsole.log(\"Operador de asignación:\", x);\nconsole.log(\"Operador de identidad:\", identidad);\nconsole.log(\"Operador de pertenencia:\", pertenece);\n\nconsole.log(\"Operador Bitwise AND:\", bitAnd);\nconsole.log(\"Operador Bitwise OR:\", bitOr);\nconsole.log(\"Operador Bitwise XOR:\", bitXor);\nconsole.log(\"Desplazamiento a la izquierda:\", desplazamientoIzquierda);\nconsole.log(\"Desplazamiento a la derecha:\", desplazamientoDerecha);\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/arnodchirivi08.ts",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n// Operadores de asignación\nlet a: number = 22; // Operador de asignación (=)\nlet b: number = 5;\nlet c: number = 8;\nlet d: number = 8;\nlet trutty: boolean = true;\nlet falsy: boolean = false;\n\nc += a; // Operador de asignación compuesto suma (+=)\nc -= a // Operador de asignación compuesto resta (-=)\nc *= a // Operador de asignación compuesto multiplicación (*=)\nc /= a // Operador de asignación compuesto división (/=)\nc %= a // Operador de asignación compuesto módulo (%=)\n\n// operadores de asignación compuestos bit a bit\nc **=a // Operador de asignación compuesto exponenciación (**=)\nc <<=a // Operador de asignación compuesto corrimiento a la izquierda (<<=)\nc >>=a // Operador de asignación compuesto corrimiento a la derecha (>>=)\nc &=a // Operador de asignación compuesto AND a nivel de bits (&=)\nc ^=a // Operador de asignación compuesto XOR a nivel de bits (^=)\nc |=a // Operador de asignación compuesto OR a nivel de bits (|=)\n\n// Operadores de asignación logicos\ntrutty &&= falsy// Operador de asignación AND lógico (&&=)\n\nlet f: string = \"\";\nlet g: string = \"pepo\";\nf ||=g // Operador de asignación OR lógico (||=)\n\n//Asignación de anulación lógica (??=)\nlet elementNull : null | {} =  null\nlet elementUndefined : undefined | {} = undefined\nlet element= { name: \"PEDRO\" };\n\nelementNull ??= element;\nelementUndefined ??= element\n\nconsole.log(elementNull);\nconsole.log(elementUndefined);\n\n\n\n// Destructuración de arrays\nvar foo = [\"one\", \"two\", \"three\"];\nvar [one, two] = foo;\nconsole.log(one);\n\n\n// Operadores de comparacion\nconst numerosIguales= c == d;\nconst numerosDiferentes = c !=a\nconst numerosEstrictamenteIguales = c===d;\nconst numerosEstrictamenteDiferentes = c!==d;\nconst numeroMayorQue = a > b;\nconst numeroMayorIgualQue = c >= d;\nconst numeroMenorQue = a < b;\nconst numeroMenorIgualQue = a < b;\n\nconsole.log(numerosIguales);\nconsole.log(numerosDiferentes);\nconsole.log(numerosEstrictamenteIguales);\nconsole.log(numerosEstrictamenteDiferentes);\nconsole.log(numeroMayorQue);\nconsole.log(numeroMayorIgualQue);\nconsole.log(numeroMenorQue);\nconsole.log(numeroMayorIgualQue);\n\n\n// Operadores aritméticos\nconst residuo = a%b;\nconst preIncremento = ++a;\nconst postIncremento = a++\nconst preDecremento = --b;\nconst postDecremento = b--;\nconst negacionUnaria = -c;\nconst exponenciacion = a**b;\n\nconsole.log(residuo);\nconsole.log(preIncremento);\nconsole.log(postIncremento);\n\n// operadores logicos;\nvar a1 = true && true; // t && t devuelve true\nvar a2 = true && false; // t && f devuelve false\nvar a3 = false && true; // f && t devuelve false\nvar a6 = false && \"Cat\"; // f && t devuelve false\n\nvar o1 = true || true; // t || t devuelve true\nvar o2 = false || true; // f || t devuelve true\nvar o3 = true || false; // t || f devuelve true\nvar o6 = false || \"Cat\"; // f || t devuelve Cat\n\n\nvar n1 = !true; // !t devuelve false\nvar n2 = !false; // !f devuelve true\n\n// Operadores de cadena\nconsole.log(\"es \" + \"typescript\"); // la consola registra la cadena \"mi cadena\".\nvar mystring = \"alpha\";\nmystring += \"bet\"; // se evalúa como \"alphabet\" y asigna este valor a mystring.\n\n// Operado condicional (ternario)\nconst age: number = 20;\nvar estado = age >= 18 ? \"adult\" : \"minor\";\nconsole.log(estado); // \"adult\"\n\n\n// operadores unarios\n\nvar myFun = new Function(\"5 + 2\");\nvar shape = \"round\";\nvar size = 1;\nvar foo = [\"Apple\", \"Mango\", \"Orange\"];\nvar today = new Date();\n\nconsole.log(typeof myFun); // devuelve \"function\"\nconsole.log(typeof shape); // devuelve \"string\"\nconsole.log(typeof size); // devuelve \"number\"\nconsole.log(typeof foo); // devuelve \"object\"\nconsole.log(typeof today); // devuelve \"object\"\n\n// Operadores relacionales\n\n//Operador in\n// Arreglos\nvar trees = ['redwood', 'bay', 'cedar', 'oak', 'maple'];\nconsole.log(0 in trees);        // devuelve true\nconsole.log(3 in trees);        // devuelve true\nconsole.log(6 in trees);        // devuelve false\n\n\n\n// objetos integrados\n'PI' in Math;          // devuelve true\nvar myString = new String('coral');\n'length' in myString;  // devuelve true\n\n// Objetos personalizados\nvar mycar = { make: 'Honda', model: 'Accord', year: 1998 };\nconsole.log('make' in mycar);  // devuelve true\nconsole.log('model' in mycar); // devuelve true\n\n//instanceof\nvar theDay = new Date(1995, 12, 17);\nif (theDay instanceof Date) {\n  console.log('es fecha');\n}\n\n\n\n//////// Estructuras de control\n// Estructura condicional if...else\nlet number: number = 10;\nif (number > 0) {\n  console.log(\"El número es positivo\");\n} else if (number < 0) {\n  console.log(\"El número es negativo\");\n}\n\n\n// Estructura condicional switch\nlet fruit:string = \"Mangos\";\nswitch(fruit){\n  case \"Naranjas\":\n    console.log(\"El kilogramo de naranjas cuesta $0.59.\");\n    break;\n  case \"Mangos\":\n  case \"Mandarinas\":\n    console.log(`El kilogramo de ${fruit} cuesta $0.48.`);\n    break;\n  default:\n    console.log(\"Lo lamentamos, por el momento no disponemos de \" + fruit + \".\");\n}\n\n// Estructura iterativa for\nfor(let i: number = 0; i < 5; i++){\n  console.log(`Iteración número ${i}`);\n}\n\n\n// Estructura iterativa while\nlet n= 0;\nlet x= 0;\n\nwhile(n < 3){\n  n++;\n  x +=n;\n  console.log(n);\n  console.log(x)\n}\n\n// Estructura iterativa do...while\nlet result = \"\";\nlet i = 0;\n\ndo {\n  i = i +1;\n  result = result + i;\n} while(i < 5)\n\nconsole.log(result);\n\n// Estructura iterativa for...of\nconst array1 = [\"a\", \"z\", \"b\", \"y\", \"c\"];\n\nfor (const element of array1){\n console.log(element)\n}\n\nconst iterable = \"typescript\";\nfor(const value of iterable){\n  console.log(value)\n}\n\nconst iterableDos = new Map([\n  [\"a\", 1],\n  [\"b\", 2],\n  [\"c\", 3],\n]);\n\nfor (const entry of iterableDos) {\n  console.log(entry);\n}\n\nfor (const [key, value] of iterableDos) {\n  console.log(value);\n}\n\n// Estructura iterativa for...in\nlet persona = {\n    nombre: \"carla\",\n    edad: 30\n}\n\nfor(const propiedad in persona){\n    console.log(`${propiedad}: ${persona[propiedad]}`)\n}\n\n// Estructura de control de excepciones try...catch\nfunction analizarUsuario(jsonString: string) {\n  try {\n    console.log(\"Intentando analizar el JSON...\");\n    const usuario = JSON.parse(jsonString); // Esto puede lanzar un error.\n    \n    console.log(\"¡Análisis exitoso! ✅\");\n    console.log(\"Nombre:\", usuario.nombre);\n    console.log(\"Edad:\", usuario.edad);\n\n  } catch (error) {\n    // 2. Si JSON.parse falla, el código salta directamente aquí.\n    console.error(\"🔴 ¡Ocurrió un error al analizar el JSON!\");\n    // 'error' es un objeto que contiene los detalles del fallo.\n    // 'error.message' suele tener el mensaje más útil.\n    console.error(\"Detalle del error:\", error.message);\n\n  } finally {\n    // 3. Este bloque se ejecuta siempre, con o sin error.\n    console.log(\"--- Proceso de análisis finalizado ---\");\n  }\n}\n\n\nconsole.log(\"Probando con un JSON válido:\");\nconst jsonValido = '{\"nombre\": \"Ana\", \"edad\": 30}';\nanalizarUsuario(jsonValido);\n\n\nconsole.log(\"\\n=============================\\n\");\n\nconsole.log(\"Probando con un JSON inválido:\");\nconst jsonInvalido = '{\"nombre\": \"Luis\", \"edad\":}'; // Falta el valor de la edad\nanalizarUsuario(jsonInvalido);\n\n\n// DIFICULTAD EXTRA (opcional):\nfor(let i: number= 10; i< 57; i++)\n{\n  if(i%2 ==0 && i%3 !==0 && i !==16){\n      console.log(i)\n  }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/axelsparta.ts",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n// #Operadores de asignación\nlet x, y\n\n// ##Asignación\nx = 10\ny = 5\n\n// ##Asignación de adición\nx += y // lo mismo que x = x + y \n\n// ##Asignación de resta\nx -= 5 // lo mismo que x = x - 5\n\n// ##Asignación de multiplicación\ny *= 3 // lo mismo que y = y * 3\n\n// ##Asignación de división\nx /= 2 // lo mismo que x = x / 2\n\n// ##Asignación de residuo\nx /= 2 // lo mismo que x = x / 2\n\n// ##Asignación de exponenciación\ny **= 3 // lo mismo que y = y**3\n\n// #Operadores de comparación\nlet myVar = 3\n// Igual ==: devuelve true si los operandos son iguales\nconsole.log(3 == myVar)\n// Diferente o no es igual != devuelve true si los operandos son distintos\nconsole.log(3 != myVar)\n// Estrictamente igual === devuelve true si los operandos son iguales y del mismo tipo de datos\nconsole.log(3 === myVar)\n// Desigualdad estricta !== devuelve true si los operandos son del mismo tipo pero no iguales, o son de diferente tipo\nconsole.log(3 !== myVar)\n// mayor que\nconsole.log(3 > 5) // false\nconsole.log(5 > 2) // true\n// mayor o igual que\nconsole.log(5 >= 5) // true\n// menor que\nconsole.log(3 < 5) // true\nconsole.log(3 < 3) // false\n// menor o igual que\nconsole.log(3 <= 3) // true\n\n// #Operadores aritméticos\nconsole.log(`Residuo ${10 % 3}`) // devuelve el resto de la división 10 / 3\n// incremento\n++myVar // si se utiliza como operador prefijo devuelve el valor del operando después de haber sumado uno\nmyVar++  // si se utiliza como operador sufijo devuelve el valor del operando y luego se suma uno\n// decremento\n--myVar // similar al incremento\nmyVar--\n// negación unaria: devuelve la negación de su operando\nconsole.log(-myVar)\n// positivo unario: intenta convertir el operando en un número aún si no lo es\nconsole.log(+true) // 1\n// operador de exponenciación\nconsole.log(3 ** 2)\n\n// #Operadores lógicos\n// AND Lógico &&: expr1 && expr2 -> devuelve true sólo cuando las dos expresiones son true\nlet a1 = true && true // -> true\nlet a2 = false && true // -> false\n\n// OR lógico ||: expr1 || expr2 -> devuelve true si la expr1 es true o la expr2 es true, y devuelve false cuando las dos expresiones son falsas\nlet o1 = true || true; // -> true\nlet o2 = false || true; // -> true\nlet o3 = true || false; // -> true\nlet o4 = false || false // -> false\n\n// NOT lógico !expr: simplemente niega la expresión\nlet n1 = !true; // -> false\nlet n2 = !false; // -> true\nlet n3 = !\"Cat\"; // -> false\n\n// #Operadores de cortocircuito\n// ## Cortocircuito OR - cuando el valor de la izquierda de la expresión siempre pueda validar a true, es el valor que se cargará por defecto  (encuentra el primer valor verdadero), cargará el valor que sea truthy  \nlet myValue = '' || ''\nconsole.log(myValue) // -> ''\nlet myValue2 = 'first value' || 'second value'\nconsole.log(myValue2) // -> 'first value'\nlet myValue3 = '' || 'second value'\nconsole.log(myValue3) // -> 'second value'\nlet myValue4 = 'first value' || ''\nconsole.log(myValue4) // -> 'first value'\n\n// ## Cortocircuito AND - cuando el valor de la izquierda en la expresión siempre pueda validar a false, es el valor que se cargará por defecto (encuentra el primer valor false)\nmyValue = '' && ''\nconsole.log(myValue) // -> ''\nmyValue2 = 'first value' && 'second value'\nconsole.log(myValue2) // -> 'second value'\nmyValue3 = '' && 'second value'\nconsole.log(myValue3) // -> ''\nmyValue4 = 'first value' && ''\nconsole.log(myValue4) // -> ''\n\n// ##Operador Nullish Coalescing '??'\n/* Es parecido al operador '||' a diferencia que solo valida si los datos son null o undefined */\nlet myVariable1 = 0\nlet myResult = myVariable1 || 30\nconsole.log(myResult) // -> 30 como 0 es un valor falsy no toma ese valor\nmyResult = myVariable1 ?? 30\nconsole.log(myResult) // -> 0 myVariable1 no es undefined ni null con lo cual toma ese valor\n\n// #Operador ternario condicional\nlet age = 20\nlet statusAge = age >= 18 ? \"adult\" : \"minor\";\n\n\n// #Estructuras de control básicas\n\n// ##IF-ELSE\nlet myCondition = true\nif (myCondition) {\n  console.log('My condition is true')\n} else {\n  console.log('My condition is false')\n}\n\n// ##WHILE\nlet i = 0\nwhile (i < 10) {\n  console.log(`Se repite el while hasta que no se cumpla la condición ${i}`)\n  i++\n}\n// ##DO-WHILE\ni = 0\ndo {\n  console.log(`Se repite el bucle al menos una vez, y se seguirá repitiendo hasta que no se cumpla la condición ${i}`)\n  i++\n} while(i < 10)\n\n// ##FOR for([iniciacion de la variable]; [condición]; [incremento o decremento de la variable])\nfor(let j = 0; j <= 10; j++) {\n  console.log(j)\n}\n// ##SWITCH\nlet fruit = 'Naranjas'\nswitch (fruit) {\n  case \"Naranjas\":\n    console.log(\"El kilogramo de naranjas cuesta $0.59.\");\n    break; // Al utilizar el break salimos de la estructura y no se sigue evaluando las siguientes expresiones\n  case \"Manzanas\":\n    console.log(\"El kilogramo de manzanas cuesta $0.32.\");\n    break;\n  case \"Platanos\":\n    console.log(\"El kilogramo de platanos cuesta $0.48.\");\n    break;\n  case \"Cerezas\":\n    console.log(\"El kilogramo de cerezas cuesta $3.00.\");\n    break;\n  case \"Mangos\":\n  case \"Papayas\":\n    console.log(\"El kilogramo de mangos y papayas cuesta $2.79.\");\n    break;\n  default:\n    console.log(\"Lo lamentamos, por el momento no disponemos de \" + fruit + \".\");\n}\n/*\n// #Ejercicio extra:  * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3. */\n\nfor (let i = 10; i <= 55; i++) {\n  if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n    console.log(i)\n  }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/barbarasg92.ts",
    "content": "/*/ * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes) /*/\n\n //Aritméticos:\n\n let suma= 5 + 6;\n console.log (suma);\n\n let resta= 5 - 6;\n console.log (resta);\n\n let division= 5 / 6;\n console.log (division);\n\n let multiplicacion= 5 * 6;\n console.log (multiplicacion);\n\n let remainder = 6 % 5;\n console.log (remainder);\n\n //Asignación:\n\n let a = 5;\n let b = 6;\n \n // Asignación compuesta: Asignar y operar\n\n a+= b;\n a-=b;\n a*=b;\n a/=b;\n a%=b;\n \n // Identidad:\n\n let tipo = typeof a;\n\n // Comparación:\n\n a == b; // Sin considerar el tipo (solo miramos el valor) aunque sea letra o número, el valor es el mismo\n a === b; // Considerando el tipo (se mira valor y tipo y tienen que coincidir)\n a != b; //Desigualdad\n a !== b; //Desigualdad estricta\n a > b; //Mayor qué\n a < b; //Menor qué\n a >= b; // Mayor o igual\n a <= b; // Menos o igual\n\n // Operadores lógicos: Operan sobre valores booleanos\n\n// &&: Las dos son true\n let tieneDinero = true;\nlet Restaurante = true;\n\nlet irAcenar = tieneDinero && Restaurante && \"Voy a cenar\";\nconsole.log(irAcenar);\n\n// ||: Al menos uno de los dos es true\nlet haceSol = false;\nlet tengoParaguas = true;\n\nlet irAlParque = haceSol || tengoParaguas || \"Me quedo en casa\";\nconsole.log(irAlParque);\n\n// !: Convertir un true en un false\nlet tengoHambre = true;\n\nlet noTengoHambre = !tengoHambre;\nconsole.log(tengoHambre);\n\n//??: Sirve para garantizar un valor cuando podría no haber nada\n\nlet nombre: string | null = \"Barbara\";\nlet miNombre = nombre ?? \"Sin Nombre\";\n\nconsole.log(miNombre);\n\n\n\n\n \n\n\n/*/ * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/cubandeveloper89.ts",
    "content": "// #01 OPERADORES Y ESTRUCTURAS DE CONTROL\n// Ejercicio de la ruta de programacion 2024 / by MoureDev\n\n//          *** Operador de asignación (=) ***\n\nlet x = 34;                   //asigna el valor de una variable\nlet y = 20;\nconsole.log(\" asignando un valor x = 34\");\n\n\n\n//           *** Operadores aritmétricos (operaciones matemáticas) ***\n\nx + y                         // Adición (+)\nx - y                         // Resta (-)\nx * y                         // Multiplicación (*)\nx ** y                        // Exponenciación (**)  --- a partir de ES6 ---\nx / y                         // División (/)\nx % y                         // Módulo (%) (resto de la división)\nx ++                          // Incremento (++)\ny --                          // Decremento (--)\n\nconsole.log(`-------------operaciones aritmeticas--------------`);\nconsole.log(`x + y = ${x+y}`);\nconsole.log(`x - y = ${x-y}`);\nconsole.log(`x * y = ${x*y}`);\nconsole.log(`x ** y = ${x**y}`);\nconsole.log(`x / y = ${x/y}`);\nconsole.log(`x % y = ${x%y}`);\nconsole.log(`x ++ = ${x++}`);\nconsole.log(`x -- = ${x--}`);\n\n\n\n//           *** Operadores de asignación de adición ***\n\nx += y;                         // equivale a: x = x + y\nx -= y;                         // equivale a: x = x - y\nx *= y;                         // equivale a: x = x * y\nx /= y;                         // equivale a: x = x / y\nx **= y;                        // equivale a: x = x ** y \nx %= y;                         // equivale a: x = x % y \n\nconsole.log(`-------------operaciones de asignacion--------------`);\nconsole.log(`x += y = ${x+=y}`);\nconsole.log(`x -= y = ${x-=y}`);\nconsole.log(`x *= y = ${x*=y}`);\nconsole.log(`x **= y = ${x**=y}`);\nconsole.log(`x /= y = ${x/=y}`);\nconsole.log(`x %= y = ${x%=y}`);\n\n\n//           *** Operadores de comparación ***\n\nx == y;                         // son iguales\nx === y;                        // igual valor e igual tipo\nx != y;                         // NO son iguales\nx !== y;                        // No son iguales o No son del mismo tipo\nx > y;                          // mayor que\nx < y;                          // menor que\nx >= y;                          // mayor o igual\nx <= y;                          // menor o igual\n\nconsole.log(`-------------operaciones de comparación--------------`);\nconsole.log(`Es x igual a y?: ${x==y}`);\nconsole.log(`Es x de igual valor e igual tipo a y?: ${x===y}`);\nconsole.log(`Es x diferente a y?: ${x!=y}`);\nconsole.log(`Es x diferente valor y tipo a y?: ${x!==y}`);\nconsole.log(`Es x mayor que y?: ${x > y}`);\nconsole.log(`Es x menor que y?: ${x < y}`);\nconsole.log(`Es x mayor o igual que y?: ${x >= y}`);\nconsole.log(`Es x menor o igual que y?: ${x <= y}`);\n\n\n\n\n\n\n//          *** Operador ternario ***\n\n// ?        tiene tres operandos \n// Con frecuencia se utiliza como atajo para la expresion IF\n\n//          *** Operadores lógicos ***\n\nx > y && y < 10;                 // AND, se usan para concatenar condiciones, todas se deben cumplir\nx > y || y < 10;                 // OR, o se cumple una o se cumple la otra\n!(x > y)                         // NOT, lo contrario a lo que se expone\n\nconsole.log(`-------------operaciones lógicos--------------`);\n\nif (x < 100 && x > y) {\n    console.log(`${x} es mayor que ${y} pero menor que 100`);\n}\n\nif (x > 100 || x > y) {\n    console.log(`${x} es mayor que ${y} o es mayor que 100`);\n}\nif (!(x = y)) {\n    console.log(`${x} es diferente de ${y}`);\n}\n\n\n//          *** Operadores de tipo ***\n\ntypeof(x)                       // Devuelve el tipo del parámetro\n\nfunction variable(leng) {       // Creando un objeto\n    this.leng = leng;\n}\nconst z = new variable('v');\n\nz instanceof variable           // Devuelve true si un objeto es una instancia de un tipo de objeto\n\nif (z instanceof variable) {\n    console.log(\"z es una instancia del objeto 'variable'\");\n    \n}\n//          *** Operadores bit a bit ***\n\nx & y                           // Realiza una operación AND binaria. Devuelve 1 en las posiciones de bit dónde las posiciones de los dos operadores tienen un 1.\nx | y                           // Realiza una operación OR binaria. Devuelve un cero en las posiciones de bit dónde las posiciones de los dos operadores tienen un 0.\nx ^ y                           // Realiza una operación XOR binaria. Devuelve un cero en las posiciones dónde el bit es el mismo y un 1 dónde las posiciones son diferentes.\n~x                              // Realiza una operación NOT binaria.\nx << y                          // Realiza un desplazamiento de bits a la izquierda.\nx >> y                          // Realiza un desplazamiento de bits a la derecha.\nx >>> y                         // Realiza un desplazamiento de bits a la derecha rellenando con ceros.\n\n//          *** Estructuras de Control ***\n\n// Condicional IF ELSE\n\nif (x > y) {                                    // Las declaraciones condicionales se utilizan para \n    console.log(`${x} es mayor que ${y}`);      // realizar diferentes acciones en función de \n                                                // diferentes condiciones.\n} else if(x < y) {\n    console.log(`${x} es menor que ${y}`);\n    \n} else{\n    console.log('Son iguales');\n    \n}\n\n// Condicional Switch\n\nswitch (typeof(x)) {                                            // La declaración de switch se utiliza para \n    case 'number':                                              // realizar diferentes acciones según \n        console.log(`${x} es de tipo numerico`);                // diferentes condiciones.\n        \n        break;\n    case 'string':\n        console.log(`${x} es de tipo cadena de texto`);\n        \n        break;   \n    case 'boolean':\n        console.log(`${x} es de tipo booleano`);\n        \n        break;  \n\n    default:\n        console.log(`${x} es de un tipo diferente, mas adelante seguiremos averiguando`);\n\n        break;\n}\n\n//              *** Bucles (Loops) ***\n// Los bucles pueden ejecutar un bloque de código varias veces.\n// Bucle FOR\n\nfor (let i = 0; i < 5; i++) {               \n    console.log(\"El numero es \" + i );\n}\n\n// Bucle FOR IN\n// La instrucción for in recorre las propiedades de un objeto, o tambien de un Array\n\nconst someone: object = { name: 'Camilo', age: 34 };\nfor (const p in someone) {\n    console.log(`${p} -> ${someone[p]}`);\n}\n\n// Bucle FOR OF\n// Recorre los valores de un objeto iterable. Le permite recorrer estructuras de datos iterables como arrays, strings, maps, NodeLists y más:\n\nconst myArray: number[] = [1, 2, 5, 2, 7, 9];\nfor (const myNumber of myArray) {\n    console.log(`# => ${myNumber}`);\n}\n\n// Bucle While\n// Recorre un bloque de código siempre que una condición especificada sea verdadera.\n\nlet mySecondNumber: number = 0;\nwhile (mySecondNumber < 5) {\n    console.log(`Iteración: ${mySecondNumber}`);\n    mySecondNumber++;\n}\n\n// Bucle Do While\n// El bucle do while es una variante del bucle while. Este bucle ejecutará el bloque de código una vez,\n// antes de verificar si la condición es verdadera, luego repetirá el bucle mientras la condición sea verdadera.\n\nmySecondNumber = 0;\ndo {\n    console.log(`Iteración: ${mySecondNumber}`);\n    mySecondNumber++;\n} while (mySecondNumber < 5);\n\n//          ***Manejo de errores (try catch)***\n\n// El mecanismo try...catch en TypeScript detecta excepciones durante la ejecución del código dentro del bloque try. \n// Cuando se produce un error, el control se pasa al bloque catch, lo que le permite manejar el error con elegancia.\n\ntry {\n    throw Error('codigo que de error');\n} catch (e: any) {\n    console.log('error');\n    console.log(e.message);\n} finally {\n    console.log('codigo que si se ejecutará');\n}\n\n\n// **********************************************************************************************************\n//          *** Dificultad extra***\n\n/*Crea un programa que imprima por consola todos los números comprendidos\n  entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n*/\nconsole.log(\"Ejercicio extra\");\n\nfor (let i = 10; i <= 55; i++) {\n    if ((i % 2 === 0) && (i !== 16) && (i % 3 !== 0)) {\n        console.log(i);\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/dannyvera1234.ts",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n// Aritméticos\n\n\nlet suma= 10 + 5;\nconsole.log(suma)\n\nconst resta = 10 - 5\nconsole.log(resta)\n\nconst multi = 10 * 5\nconsole.log(multi)\n\nconst divi =  3 / 6\nconsole.log(divi)\n\nconst modulo = (3 % 6)\nconsole.log(modulo)\n\nconst numero1 = 10\nconst numero2 = 3\nconsole.log( numero1 % numero2)\nconsole.log(numero1 ** numero2)\nconsole.log(numero1 / numero2 )\n\n// Operadores ded comparacion \n\n\nconsole.log( \"igualdad\",numero1 == numero2 )\nconsole.log (\"desigualdad\",numero1 != numero2)\nconsole.log(\"mayor que\", numero1 > numero2)\nconsole.log(\"menor que\", numero1 < numero2)\nconsole.log(\"mayor igual que\", numero1 >= numero2)\nconsole.log(\"menor igual que\", numero1 <= numero2 )\n \n\n// operadores logicos\n// AND &&: que se cumplan las dos condiciones.\nconst condicion = 10 + 3 == 13 && 5 - 1 == 4\nconsole.log(\"and &&\", 10 + 3 == 13 && \"accion 2\", 5 - 1 == 4)\n\nif (condicion) {\n    console.log(\"paso\")\n} else {\n    console.log(\"no paso\")\n}\n\n// OR || debe cumplir por lo menos una de la condiciones agregada \nconst or = 10 + 10 <= 20 || 10 * 2 == 10\nconsole.log(or)\n\nif (or) {\n    console.log(\"paso\")\n} else {\n    console.log(\"no paso\")\n}\n\n// NOT != een el caso que la operacion no se cumpliera se pasara hacer true referiendo a\n//  que todo resultado que no sea el correcto lo manda como true\n\nconst not = 10 + 2 != 1\nconsole.log(not)\nif(not){\n    console.log(\"true\")\n}else{\n    console.log(\"false\")\n}\n\n// Operadores de asignacion\nlet numero = 10;\nnumero += 1;\nconsole.log(numero)\nnumero -= 2;\nconsole.log(numero)\nnumero *= 5;\nconsole.log(numero)\nnumero /= 2;\nconsole.log(numero)\nnumero %= 10;\nconsole.log(numero)\nnumero **= 2;\nconsole.log(numero)\n\n\n// Operadores de identidad\n\nconst my_number = 2\nconst my_new_numero= 2\n\n\n// identidad: compara los que es tipo y valor si son iguales\nconsole.log(\"mi numero es \",  my_number === my_new_numero)\n\nif (my_number === my_new_numero) {\n        console.log(\"paso\")\n}else{\n    console.log(\"no paso\")\n}\n\n// operador desigualdad estricta: compara que el tipo y valor no sea identico \nif ( 2 !== \"2\") {\n    console.log(\"true\")\n}else{\n    console.log(\"false\")\n}\n\n// Operador de pertenecia\n// IN SI UN OBJETO CONTIENE PROPIEDADES ESPECIFICAS EN LA CUAL BUSCAMOS CON UNA PALABRA CLAVE\nconst persona = {\n    nombre: \"Daniel\",\n    edad: 28,\n    habla: true,\n    numero: 2,\n    \n}\nif ( 'edad'in persona ) {\n        console.log(\"true\")\n}else{\n    console.log(\"false\")\n}\n//  NOT IN  !IN: SI UN OBJETO NO CONTIENE LA PROIEDAD ESPECIFICA CON OPERADOR LOGICO DEE NEGACION \nif (!(2 in persona)) {\n    console.log(\"true\")\n}else{\n    console.log(\"false\")\n}\n\n// ESTRUCTURA DE CONTROL\n\n// CONDICIONELES \nconst num = \"juan\";\n\n\nif ( num === \"juan\") {\n    console.log(\"true\");\n    // Si numero es \"daniel\", imprimirá \"true\"\n} else{\n    console.log(false)\n}\n\n// INTERATIVAS\n// for para ejecutar un bloque de codigo varias veces \n let nume = 2\n\nfor (let i = 1; i <= nume; i++) {\n    console.log(i);\n}\n\n let  i  = 0\nwhile ( i <= 10) {\n    i++;\n    console.log(i)\n}\n\n// * DIFICULTAD EXTRA (opcional):\n// * Crea un programa que imprima por consola todos los números comprendidos\n// * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\nfor (let i = 10; i <= 55; i++) {\n    // incremeto de 10 hasta el 55\n  console.log(i)\n//   condicion donde voy a mostrar los numero pares donde i se divide para 2 y si el reciduo es 0 muestre en consola\n// y que no muestre el 16 para que muestre el 16 usamos el != contrario a 16\n// tambien los multiplos de 3 se divide i para 3 donde el reciduo tiene que se contrario a 0\n    if( i % 2 == 0  &&  i != 16 &&  i % 3 != 0){\nconsole.log(i)\n    }else{\n        console.log(i)\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/dararod.ts",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n// OPERADORES -->\n\nlet firstNumber: number = 10;\nlet secondNumber: number = 2;\nlet numericResult: number;\nlet booleanResult: boolean;\n\n//Arithmetic Operators\n//Adition (+)\nnumericResult = firstNumber + secondNumber;\nconsole.log(`The sum of ${firstNumber} + ${secondNumber} returns ${numericResult}`);\n\n//Subtraction (-)\nnumericResult = firstNumber - secondNumber;\nconsole.log(`The differece of ${firstNumber} - ${secondNumber} returns ${numericResult}`);\n\n//Multiplication (*)\nnumericResult = firstNumber * secondNumber;\nconsole.log(`The product of ${firstNumber} * ${secondNumber} returns ${numericResult}`);\n\n//Division (/)\nnumericResult = firstNumber / secondNumber;\nconsole.log(`The quotient of ${firstNumber} / ${secondNumber} returns ${numericResult}`);\n\n//Modulus (%)\nnumericResult = firstNumber % secondNumber;\nconsole.log(`The remainder of ${firstNumber} % ${secondNumber} returns ${numericResult}`);\n\n//Increment (++)\nnumericResult = firstNumber++;\nconsole.log(`Increment ${firstNumber} returns ${numericResult}`);\n\n//Decrement (--)\nnumericResult = firstNumber--;\nconsole.log(`Decrement ${firstNumber} returns ${numericResult}`);\n\n\n//Relational Operators\n//Greater than (>)\nbooleanResult = firstNumber > secondNumber;\nconsole.log(`${firstNumber} > ${secondNumber} returns ${booleanResult}`);\n\n//Lesser than (<)\nbooleanResult = firstNumber < secondNumber;\nconsole.log(`${firstNumber} < ${secondNumber} returns ${booleanResult}`);\n\n//Greater than or equal to (>=)\nbooleanResult = firstNumber >= secondNumber;\nconsole.log(`${firstNumber} >= ${secondNumber} returns ${booleanResult}`);\n\n//Lesser than or equal to (<=)\nbooleanResult = firstNumber <= secondNumber;\nconsole.log(`${firstNumber} <= ${secondNumber} returns ${booleanResult}`);\n\n//Equality (==)\nbooleanResult = firstNumber == secondNumber;\nconsole.log(`${firstNumber} == ${secondNumber} returns ${booleanResult}`);\n\n//Not equal (!=)\nbooleanResult = firstNumber != secondNumber;\nconsole.log(`${firstNumber} != ${secondNumber} returns ${booleanResult}`);\n\n\n//Logical Operators\n//And (&&)\nbooleanResult = firstNumber > secondNumber && secondNumber < 5;\nconsole.log(`${firstNumber} > ${secondNumber} && ${secondNumber} < 5 returns ${booleanResult}`);\n\n//Or (||)\nbooleanResult = firstNumber > secondNumber || secondNumber < 1;\nconsole.log(`${firstNumber} > ${secondNumber} || ${secondNumber} < 1 returns ${booleanResult}`);\n\n//Not (!)\nbooleanResult = !(firstNumber > secondNumber);\nconsole.log(`!(${firstNumber} > ${secondNumber}) returns ${booleanResult}`);\n\n\n//Assignment Operators\nlet newNumber: number;\n\n//Simple Assignment (=)\nnewNumber = firstNumber;\nconsole.log(`newNumber value is ${newNumber}`);\n\n//Add and Assignment (+=)\nnewNumber += firstNumber;\nconsole.log(`newNumber value is ${newNumber}`);\n\n//Subtract and Assignment (-=)\nnewNumber -= firstNumber;\nconsole.log(`newNumber value is ${newNumber}`);\n\n//Multiply and Assignment (*=)\nnewNumber *= firstNumber;\nconsole.log(`newNumber value is ${newNumber}`);\n\n//Divide and Assignment (/=)\nnewNumber /= firstNumber;\nconsole.log(`newNumber value is ${newNumber}`);\n\n\n//Ternary/Conditional Operator\nlet stringResult: string;\nstringResult = firstNumber > 0 ? 'Number is positive' : 'Number is negative';\nconsole.log(`stringResult value is ${stringResult}`);\n\n\n//Type Operators\n//typeof operator\nstringResult = typeof firstNumber;\nconsole.log(`stringResult value is ${stringResult}`);\n// OPERADORES <--\n\n\n//ESTRUCTURAS DE CONTROL\n//Conditional (If else)\nif (firstNumber > 0) {\n    console.log('Number is positive.');\n} else if (firstNumber === 0) {\n    console.log('Number is cero.');\n} else {\n    console.log('Number is negative.');\n}\n\n//For\nfor (let i = 0; i <= firstNumber; i++) {\n    console.log(i)\n}\n\n//For in\nconst object: object = { a: 1, b: 2, c: 3 };\nfor (const property in object) {\n    console.log(`${property}: ${object[property]}`);\n}\n\n//For of\nconst numberArray: number[] = [0, 1, 2, 3, 4, 5];\nfor (const number of numberArray) {\n    console.log(`Number ${number}`);\n}\n\n//While\nwhile (secondNumber < firstNumber) {\n    secondNumber++\n    console.log(`Now secondNumber value is ${secondNumber}`)\n}\n\n//Switch\nconst expr: string = 'Papayas';\nswitch (expr) {\n    case 'Oranges':\n        console.log('Oranges are $0.59 a pound.');\n        break;\n    case 'Mangoes':\n    case 'Papayas':\n        console.log('Mangoes and papayas are $2.79 a pound.');\n        break;\n    default:\n        console.log(`Sorry, we are out of ${expr}.`);\n}\n\n//Try catch\ntry {\n    nonExistentFunction();\n} catch (err) {\n    console.error(err);\n}\n\n\n// DIFICULTAD EXTRA\n/*  Crea un programa que imprima por consola todos los números comprendidos entre 10 y 55 (incluidos), pares, y\n *  que no son ni el 16 ni múltiplos de 3.*/\nfor (let i = 10; i <= 55; i++) {\n    if ((i % 2 === 0) && (i !== 16) && (i % 3 !== 0)) {\n        console.log(\"Value: \" + i);\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/david-git-dev.ts",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n// Operadores Aritméticos\nlet suma = 5 + 2;        // Suma (+)\nconsole.log(suma);\nlet resta = 5 - 2;       // Resta (-)\nconsole.log(resta);\nlet multiplicacion = 5 * 2; // Multiplicación (*)\nconsole.log(multiplicacion);\nlet division = 5 / 2;    // División (/)\nconsole.log(division);\nlet modulo = 5 % 2;      // Resto o Módulo (%)\nconsole.log(modulo);\nlet incremento = 1;    // Incremento (++x o x++)\nconsole.log(incremento++,++incremento);\nlet decremento = 1;    // Decremento (--x o x--)\nconsole.log(decremento--,--decremento);\n\n// Operadores de Asignación\n\nlet x = 5;              // Asignación (=)\nconsole.log(x)\nx += 2;                 // Asignación de Suma (+=)\nconsole.log(x)\nx -= 2;                 // Asignación de Resta (-=)\nconsole.log(x)\nx *= 2;                 // Asignación de Multiplicación (*=)\nconsole.log(x)\nx /= 2;                 // Asignación de División (/=)\nconsole.log(x)\nx %= 2;                 // Asignación de Módulo (%=)\nconsole.log(x)\nx **= 2;                // Asignación de Exponenciación (**=)\nconsole.log(x)\n// Operadores de Comparación\n\nlet igual = (5 == \"5\");       // Igualdad Débil (==)\nconsole.log(igual);\nlet estrictamenteIgual = (5 === \"5\"); // Igualdad Estricta (===)\nconsole.log(estrictamenteIgual);\nlet diferente = (5 != \"5\");    // Desigualdad Débil (!=)\nconsole.log(diferente);\nlet estrictamenteDiferente = (5 !== \"5\"); // Desigualdad Estricta (!==)\nconsole.log(estrictamenteDiferente);\nlet mayor = (5 > 2);           // Mayor que (>)\nconsole.log(mayor);\nlet menor = (5 < 2);           // Menor que (<)\nconsole.log(menor);\nlet mayorOIgual = (5 >= 2);    // Mayor o igual que (>=)\nconsole.log(mayorOIgual);\nlet menorOIgual = (5 <= 2);    // Menor o igual que (<=)\nconsole.log(menorOIgual);\n// Operadores Lógicos\nlet and = (true && false);     // Y Lógico (&&)\nconsole.log(and)\nlet or = (true || false);      // O Lógico (||)\nconsole.log(or)\nlet not = !true;               // No Lógico (!)\nconsole.log(not)\n\n// Operadores de Bit a Bit\nlet bitAnd = (5 & 1);          // AND a nivel de bits (&)\nconsole.log(bitAnd);\nlet bitOr = (5 | 1);           // OR a nivel de bits (|)\nconsole.log(bitOr);\nlet bitXor = (5 ^ 1);          // XOR a nivel de bits (^)\nconsole.log(bitXor);\nlet bitNot = ~5;               // NOT a nivel de bits (~)\nconsole.log(bitNot);\nlet desplazarIzquierda = (5 << 1);  // Desplazamiento a la izquierda (<<)\nconsole.log(desplazarIzquierda);\nlet desplazarDerecha = (5 >> 1);    // Desplazamiento a la derecha (>>)\nconsole.log(desplazarDerecha);\nlet desplazarDerechaConCero = (5 >>> 1); // Desplazamiento a la derecha con relleno de ceros (>>>)\nconsole.log(desplazarDerechaConCero);\n\n// Operadores Ternarios\nlet ternario = (5 > 2) ? \"Mayor\" : \"Menor\"; // Operador Ternario (condicion ? valor1 : valor2)\nconsole.log(ternario)\n\n// Operadores de Tipo\nlet tipo = typeof 5;        // Operador de Tipo (typeof)\nlet esInstancia = ({} instanceof Object); // Operador instanceof\nconst obj ={\n    propiedad:{subprop:undefined},\n    variable:null\n}\n// Operador de Encadenamiento Opcional\nlet valor = obj.propiedad?.subprop;  // Encadenamiento opcional (?.)\nconsole.log(valor)\n// Operador Nullish Coalescing\nlet valorDefinido = obj.variable ?? \"Valor por defecto\";  // Nullish Coalescing (??)\n// Estructuras de Control de Flujo\nconsole.log(valorDefinido);\n\n// if...else\nlet xx = 10;\nif (xx > 5) {\n    console.log(\"x es mayor que 5\");\n} else if (xx === 5) {\n    console.log(\"x es igual a 5\");\n} else {\n    console.log(\"x es menor que 5\");\n}\n\n// switch\nlet color = \"rojo\";\nswitch (color) {\n    case \"rojo\":\n        console.log(\"El color es rojo\");\n        break;\n    case \"azul\":\n        console.log(\"El color es azul\");\n        break;\n    default:\n        console.log(\"Color no reconocido\");\n}\n\n// Operador Ternario (condición ? valor1 : valor2)\nlet edad = 18;\nlet mensaje = (edad >= 18) ? \"Eres mayor de edad\" : \"Eres menor de edad\";\nconsole.log(mensaje);\n\n// Estructuras de Control de Bucles (Loops)\n\n// for\nfor (let i = 0; i < 5; i++) {\n    console.log(i);\n}\n\n// for...of (para iterar sobre iterables como arrays)\nlet array = [1, 2, 3, 4];\nfor (let valor of array) {\n    console.log(valor);\n}\n\n// for...in (para iterar sobre propiedades enumerables de un objeto)\nlet objeto = { nombre: \"Juan\", edad: 25 };\nfor (let propiedad in objeto) {\n    console.log(`${propiedad}: ${objeto[propiedad]}`);\n}\n\n// while\nlet contador = 0;\nwhile (contador < 5) {\n    console.log(contador);\n    contador++;\n}\n\n// do...while\nlet num = 0;\ndo {\n    console.log(num);\n    num++;\n} while (num < 5);\n\n// Estructura de Control para Excepciones\n\n// try...catch...finally\ntry {\n    let resultado = 10 / 0;  // Posible error\n    console.log(resultado);\n} catch (error) {\n    console.log(\"Ocurrió un error: \" + error.message);\n} finally {\n    console.log(\"Esto se ejecuta siempre\");\n}\n\n// break\nfor (let i = 0; i < 10; i++) {\n    if (i === 5) {\n        break;  // Rompe el bucle si i es igual a 5\n    }\n    console.log(i);\n}\n\n// continue\nfor (let i = 0; i < 10; i++) {\n    if (i === 5) {\n        continue;  // Salta el resto del código en la iteración actual si i es igual a 5\n    }\n    console.log(i);\n}\n\n// Estructura de Control asincrónica\n\n// async...await (para manejar promesas de forma síncrona)\nasync function obtenerDatos() {\n    try {\n        let respuesta = await fetch('https://api.example.com/datos');\n        let datos = await respuesta.json();\n        console.log(datos);\n    } catch (error) {\n        console.log(\"Error al obtener los datos: \" + error.message);\n    }\n}\n//reto extra\n/* * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo. */\nfunction numbersTentoFifhtty(){\n    const final = 55;\n    let start = 10;\n    while(start<=55){\n        start++;\n        console.log(start%2===0&&start!==16&&start%3!==0?start:'');\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/duendeintemporal.ts",
    "content": "/* #01 { PROGRAMMING CHALLENGES }   OPERATORS AND CONTROL STRUCTURES */\n// Note: This code references Matt Frisbie's book \"Professional JavaScript for Web Developers\" for accurate information about operators.\n// Additional tips are sourced from \"JavaScript Notes for Professionals\" by the StackOverflow community, available for free at GoalKicker.com.\n//and https://www.typescriptlang.org/docs/\n\n// Short for log\nconst log = console.log;\n\n/*  OPERATORS  */\n\n// Unary Operators\n\n// Unary Plus and Minus\n/* The unary plus operator converts non-numeric values to numbers, similar to the Number() function. \nBoolean values are converted to 0 (false) and 1 (true), strings are parsed, and objects call their valueOf() \nand/or toString() methods for conversion. */\n\nlet str1: string = \"03\";\nlet num1: number = +str1; // Converts to number\nlog(num1); // 3\n\nlet str2: string = \"1.4\";\nlet num2: number = +str2; // Converts to number\nlog(num1 + num2); // 4.4\n\nlet str3: string = \"zaz\";\nlet num3: number = +str3; // Converts to number (NaN)\nlog(num3); // NaN\n\nlet bool: boolean = true;\nlet numBool: number = +bool; // Converts to number\nlog(numBool); // 1\n\nlet f_num: number = 2.8; // Already a number\nlog(f_num); // 2.8\n\nlet obj = {\n    valueOf() {\n        return -5;\n    }\n};\nlet numObj: number = +obj; // Converts to number\nlog(numObj); // -5\n\n/* The unary minus operator negates numeric values. When applied to non-numeric values, it follows the same \nconversion rules as unary plus and then negates the result. */\n\nlet g_actions: number = 50;\ng_actions = -g_actions;\nlog(g_actions); // -50\n\nlet str_1: string = \"03\";\nlet num_1: number = +str_1; // Convert to number\nnum_1 = -num_1; // Negate the number\nlog(num1); // -3\n\nlet str_2: string = \"1.4\";\nlet num_2: number = +str_2; // Convert to number\nnum_2 = -num_2; // Negate the number\nlog(num_2); // -1.4\n\nlet str_3: string = \"zaz\";\nlet num_3: number = +str_3; // Convert to number (NaN)\nnum_3 = -num_3; // Negate the number (still NaN)\nlog(num_3); // NaN\n\nlet bool1: boolean = true;\nlet numBool1: number = +bool1; // Convert to number\nnumBool1 = -numBool1; // Negate the number\nlog(numBool1); // -1\n\nlet f_num1: number = 2.8; // Already a number\nf_num1 = -f_num1; // Negate the number\nlog(f_num1); // -2.8\n\nlet obj1 = {\n    valueOf() {\n        return -5;\n    }\n};\nlet numObj1: number = +obj1; // Convert to number\nnumObj1 = -numObj1; // Negate the number\nlog(numObj1); // 5\n\n// Increment/Decrement Operators\nlet numA: number = 10, numB: number = 5, numC: number, numD: number;\nnumC = numA++; // Post-increment\nlog(numC); // 10\nlog(numA); // 11\nnumC = ++numA; // Pre-increment\nlog(numC); // 12\nlog(numA); // 12\nnumD = numB--; // Post-decrement\nlog(numD); // 5\nlog(numB); // 4\nnumD = --numB; // Pre-decrement\nlog(numD); // 3\nlog(numB); // 3\nnumD++; // Increment\nlog(numD); // 4\n\n\n// Bitwise Operators\n/* Bitwise operators work with numbers at the bit level. When applied, a conversion occurs: \nthe 64-bit number is converted to a 32-bit number, the operation is performed, and the result is stored back. */\n\n// Bitwise NOT (~)\nlet n1: number = 25; // binary 00000000000000000000000000011001\nlet n2: number = ~n1; // binary 11111111111111111111111111100110\nlog(n2); // -26\n\n// Bitwise AND (&)\nlet n3: number = 25 & 3;\nlog(n3); /* Logs: 1 because:\n    25 = 0000 0000 0000 0000 0000 0000 0001 1001\n     3 = 0000 0000 0000 0000 0000 0000 0000 0011\n    ---------------------------------------------\n   AND = 0000 0000 0000 0000 0000 0000 0000 0001   */\n\n\n\n// Bitwise OR |\n// A bitwise OR operation returns 1 if at least one bit is 1. It returns 0 only if both bits are 0.\n\nn3 = 25 | 3; \nlog(n3); // Logs: 27 because the comparison of both binary codes is:\n                   // 25 = 0000 0000 0000 0000 0000 0000 0001 1001\n                   // 3  = 0000 0000 0000 0000 0000 0000 0000 0011\n                   // ---------------------------------------------\n                   // OR = 0000 0000 0000 0000 0000 0000 0001 1011\n\n// Bitwise XOR\n// Bitwise XOR is different from bitwise OR in that it returns 1 only when exactly one bit has a value of 1 (if both bits contain 1, it returns 0).\n\nn3 = 25 ^ 3;\nlog(n3); // Logs: 26 because the comparison of both binary codes is:\n                   // 25 = 0000 0000 0000 0000 0000 0000 0001 1001\n                   // 3  = 0000 0000 0000 0000 0000 0000 0000 0011\n                   // ---------------------------------------------\n                   // XOR = 0000 0000 0000 0000 0000 0000 0001 1010\n\n// Left Shift\n// The left shift is represented by two less-than signs (<<) and shifts all bits in a number to the left by the number of positions given.\n\nlet numb: number = 2; // 10 in binary code\nlet new_number: number = numb << 6; // 10000000 in binary code which is decimal 128\nlog(new_number); // 128\n\n/* |1|         |0|       |0|       |0|       |0|        |0|       |0|      |0|\n(2^7x1)  +  (2^6x0) + (2^5x0) + (2^4x0) + (2^3x0) + (2^2x0) + (2^1x0) + (2^0x0) // here ^ is a power\n 128     +     0    +    0    +    0    +   0     +    0    +    0    +   0    = 128   */\n\n// Signed Right Shift\n// The signed right shift is represented by two greater-than signs (>>) and shifts all bits in a 32-bit number to the right while preserving the sign (positive or negative).\n\nnumb = 128; // 10000000 in binary code\nnew_number = numb >> 6; // 10 in binary code which is decimal 2\nlog(new_number); // 2\n\n// Unsigned Right Shift\n/* The unsigned right shift is represented by three greater-than signs (>>>) and shifts all bits in a 32-bit number to the right. \nFor numbers that are positive, the effect is the same as a signed right shift. For negative numbers, unlike signed right shift, \nthe empty bits get filled with zeros regardless of the sign of the number. */\n\nnumb = -64; // equal to binary 11111111111111111111111111000000\nnew_number = numb >>> 5; // equal to decimal 134217726\nlog(new_number); // 134217726\n/* because the unsigned right shift treats this as a positive number, it considers the value to be\n4294967232. When this value is shifted to the right by five bits, it becomes 00000111111111111111\n111111111110, which is 134217726. */\n\n/* Boolean operators */\n// Logical NOT ! \n// can be used in any value. This operator always returns a Boolean value, regardless of the data type it’s used on. \n// The logical NOT operator first converts the operand to a Boolean value and then negates it.\n\nlog(!false); // true\nlog(!false); // true\n\n// Using Boolean() to evaluate the truthiness of the string\nlog(!Boolean(\"shadow\")); // false\n\nlog(!Boolean(0)); // true\nlog(!Boolean(NaN)); // true\nlog(!Boolean(\"\")); // true\nlog(!Boolean(57344)); // false\nlog(!Boolean(null)); // true\nlog(!Boolean(undefined)); // true\n\n//Note: Here we need to convert first to a Boolean to avoid ts(2872) error\n\n\n// it can be used to transform a value into its boolean equivalent by using two NOT operators in a row\n\nlet girlname: string = 'Angy';\n// name = !!girlname;\n// log(name); // Logs: true\n\n// Note: see that the first negates the\n// value after converting it, the second just converts it to boolean.\n\n// Logical AND &&\n// It operates over two values and returns true if both values are true, false otherwise.\nlog(true && girlname); // Angy\nlog(false && 'Angy'); // false\nlog(4 < 5 && 8 > 6); // true\n/* Logical AND can be used with any type of operand, not just Boolean values. When either operand is\nnot a primitive Boolean, logical AND does not always return a Boolean value; instead, it does one of the following:\n➤ If the first operand is an object, then the second operand is always returned.\n➤ If the second operand is an object, then the object is returned only if the first operand evaluates to true.\n➤ If both operands are objects, then the second operand is returned.\n➤ If either operand is null, then null is returned.\n➤ If either operand is NaN, then NaN is returned.\n➤ If either operand is undefined, then undefined is returned. */\n\n// Logical OR ||\n// It operates over two values and returns true if both or one of both values are true, false otherwise.\nlet empty: string = '';\nlog(false || empty); // Logs: <empty string>\nlog(girlname || empty); // Angy\nlog(4 >= 5 || 8 > 6); // true \n\n/* Just like logical AND, if either operand is not a Boolean, logical OR will not always return a Boolean value; instead, it does one of the following:\n➤ If the first operand is an object, then the first operand is returned.\n➤ If the first operand evaluates to false, then the second operand is returned.\n➤ If both operands are objects, then the first operand is returned.\n➤ If both operands are null, then null is returned.\n➤ If both operands are NaN, then NaN is returned.\n➤ If both operands are undefined, then undefined is returned. */\n\n// Note: Both AND and OR are short-circuit operators, which means sometimes only the first operator is evaluated.\n\n// Multiplicative Operators\n/* There are three multiplicative operators in ECMAScript: multiply, divide, and modulus. \nThese operators work similarly to their counterparts in languages such as Java, C, and Perl, \nbut they also include automatic type conversions when dealing with non-numeric values. */\n\n// Multiply Operator *\nlet number: number = 4 * Number('8'); // Explicitly convert the string to a number\nlog(number); // Logs: 32\n\n// Alternatively, you can use the unary plus operator\nlet number_2: number = 4 * +'8'; // Using unary plus to convert the string to a number\nlog(number_2); // Logs: 32\n\n\n\n\n// Divide Operator /\nnumber = 10 / 5;\nlog(number); // Logs: 2\nnumber = 4 / 40;\nlog(number); // Logs: 0.1 \n\n// Modulus (remainder) Operator %\nnumber = 41 % 5;\nlog(number); // Logs: 1\n\n// Exponentiation Operator **\nnumber = 4 ** 2;\nlog(number); // Logs: 16\n// same as\nlog(Math.pow(4, 2)); // 16\n\n// Add Operator +\nnumber = 76 + 78;\nlog(number); // 154\nlog('76' + '78'); // 7678, on strings performs as a concatenator\n\nlet bigNumb = BigInt(767867686876876) + BigInt(6757575755);\nlog(bigNumb); // 767874444452631n\n\n// Subtract -\nnumber = 48 - 3;\nlog(number); // 45\n\n// Note: These operators have a particular behavior in some cases when used with Infinity, 0, NaN, or non-numeric values; you should search if you want more information.\n\n/* Relational Operators */\n/* The less-than (<), greater-than (>), less-than-or-equal-to (<=), and greater-than-or-equal-to (>=) \nrelational operators perform comparisons between values in the same way that you learned in math class. */\nlet computation: boolean = 76 < 4;\nlog(computation); // false\ncomputation = 87 > 32;\nlog(computation); // true\ncomputation = 43 <= 43;\nlog(computation); // true\ncomputation = 44 >= 85;\nlog(computation); // false\n\n\n//In TypeScript, when comparing values, it's important to ensure that the types are compatible to avoid unexpected behavior.\nlet user: { name: string } = {\n    name: 'Clavin & Hobbes'\n};\n\n// Comparing user object with a number\nlog(user.name <= '4'); // false, comparing string to string\n\n// Comparing strings\nlog(\"43\" < \"8\"); // true, because string comparison is lexicographical\nlog(Number(\"43\") < 8); // false, converting \"43\" to a number for comparison\n\n\nlog('DeepState' < 'real people'); // true, not only because there are more real people, but when we talk about strings, the upper characters have lower codes than the regular ones\nlog('DeepState'.toLowerCase() < 'real people'.toLocaleLowerCase()); // true again ... well ummm sometimes we win \n\n/* As with other operators in ECMAScript, there are some conversions and other oddities that happen\nwhen using different data types. They are as follows:\n➤ If the operands are numbers, perform a numeric comparison.\n➤ If the operands are strings, compare the character codes of each corresponding character in\nthe string.\n➤ If one operand is a number, convert the other operand to a number and perform a numeric\ncomparison.\n➤ If an operand is an object, call valueOf() and use its result to perform the comparison\naccording to the previous rules. If valueOf() is not available, call toString() and use that\nvalue according to the previous rules.\n➤ If an operand is a Boolean, convert it to a number and perform the comparison. */\n\n// Equality operators\n// Determining whether two variables are equivalent is one of the most important operations in programming.\n\n// Equal or Equality Operator ==\nlog(2 == Number('2')); // true\n\n// Deep comparison, also compares types. Identically equal or Strict Equality Operator ===\nlog(2 === Number('2')); // true, explicitly converting '2' to a number\n//Note: if we were using Javascript and avoiding to using the Number() build-in structure, the result were be diferent because types are diferent\n\n// Not-equal or Inequality Operator !=\nlog(2 != Number('2')); // false\n\n// Deep comparison, also compares types. Identically not-equal or Strict Inequality Operator !==\nlog(2 !== Number('2')); // false, explicitly converting '2' to a number. Same observation that the about deep comparation\n\n\n/* When performing conversions, the equal and not-equal operators follow these basic rules:\n➤ If an operand is a Boolean value, convert it into a numeric value before checking for\nequality. A value of false converts to 0, whereas a value of true converts to 1.\n➤ If one operand is a string and the other is a number, attempt to convert the string into a\nnumber before checking for equality.\n➤ If one of the operands is an object and the other is not, the valueOf() method is called on\nthe object to retrieve a primitive value to compare according to the previous rules.\n\nThe operators also follow these rules when making comparisons:\n➤ Values of null and undefined are equal.\n➤ Values of null and undefined cannot be converted into any other values for\nequality checking.\n➤ If either operand is NaN, the equal operator returns false and the not-equal operator\nreturns true. Important note: even if both operands are NaN, the equal operator returns\nfalse because, by rule, NaN is not equal to NaN.\n➤ If both operands are objects, then they are compared to see if they are the same object. If\nboth operands point to the same object, then the equal operator returns true. Otherwise,\nthe two are not equal. */\n\n// in Javascript we can do something like: log(NaN !== NaN); // true\n// NaN is not equal to itself\nconst isNotEqual: boolean = Object.is(NaN, NaN); // false\nlog(!isNotEqual); // true, because NaN is not equal to itself\n//Note: We use the above structure to avoid ts(2845) error\n\n// in Javascript we can do something like: log(true === 1); // false\n// Comparing boolean true with number 1\nconst isTrueEqualToOne: boolean = (true as unknown as number) === 1; // true\nlog(isTrueEqualToOne); // true\n//Note: We use the above structure to avoid ts(2367)\n\nlog(null == undefined); // true\nlog(null === undefined); // false\n\n// Conditional Operator (condition) ? true : false;\n/* This basically allows a conditional assignment to a variable depending on the evaluation of the\nboolean_expression. If it’s true, then true_value is assigned to the variable; if it’s false, then\nfalse_value is assigned to the variable. */\n\nlet login: string = (user.name == 'Nixon') ? `Successful login, Welcome ${user.name}` : \"Sorry we don't have any user with that name\";\nlog(login); // Sorry we don't have any user with that name\n\n// Assignment Operators\n\nlet a: string = 'a';\na = a + a;\nlog(a); // aa\n\nnumber = 8;\n\n/* Compound assignment is done with one of the multiplicative, additive, or bitwise–shift operators\nfollowed by an equal sign (=). These assignments are designed as shorthand for such common situations as: */\n\nnumber *= number;\nlog(number); // 64\n\nnumber -= 4;\nlog(number); // 60\n\n/* Compound-assignment operators exist for each of the major mathematical operations and a few\nothers as well. They are as follows:\n➤ Multiply/assign (*=)\n➤ Divide/assign (/=)\n➤ Modulus/assign (%=)\n➤ Add/assign (+=)\n➤ Subtract/assign (-=)\n➤ Left shift/assign (<<=)\n➤ Signed right shift/assign (>>=)\n➤ Unsigned right shift/assign (>>>=)\nThese operators are designed specifically as shorthand ways of achieving operations. They do not\nrepresent any performance improvement. */\n\n// Membership Operators\n// The in operator\nlet Crows: { description: string; age: number } = {\n    description: \"Mutant fat man lives beyond the margins of the known universe...\",\n    age: 600,\n};\n\nlog('description' in Crows); // true\nlog('location' in Crows\n); // false\n\n// instanceof operator\n\nclass User {\n    name: string;\n    age: number;\n    email: string;\n\n    constructor(name: string, age: number, email: string) {\n        this.name = name;\n        this.age = age;\n        this.email = email;\n    }\n\n    greeting(): string {\n        return `Hi ${this.name}. Welcome to Roadmap Exercise #01.`;\n    }\n}\n\n// Example usage of the User class\nconst userInstance = new User('Alice', 16, 'aliceinchain@gronch.com');\nlog(userInstance.greeting()); // Hi Alice. Welcome to Roadmap Exercise #01.\n\n// Create a new User instance\nconst niko_zen = new User('Niko', 41, 'duendeintemporal@hotmail.com');\nlog(niko_zen.greeting()); // 'Hi Niko. Welcome to Roadmap Exercise #01'\n\n// Check instance types\nlog(niko_zen instanceof User); // true\nlog(niko_zen instanceof Object); // true\n// Function to check if a value is a Number object\nfunction isNumberObject(value: any): value is Number {\n    return value instanceof Number;\n}\nlog(isNumberObject(4)); // false, because 4 is a primitive value\n//Note: if we do: log(4 instanceof Number) like in Javascript it throw ts(2358) error\n\nlet four = new Number(4);\nlog(four instanceof Number); // true\n\n// Type Operators\n// Using instanceof and typeof\nlog(typeof true); // boolean\nlog(typeof NaN); // number\nlog(typeof niko_zen); // object \n\n// Destructuring Operations and Spread Operator\n// For arrays\nlet books: string[] = ['Dune', 'Shibumi', 'El Maestro de Esgrima', 'El Perfume'];\nlet books2: string[] = ['Eloquent JavaScript', 'You Don’t Know JS ES6 Beyond', 'Linux Command Line An Admin Beginners Guide', 'Learn Bash the Hard Way', 'Programming Algorithms', 'MATLAB Notes for Professionals'];\nconst mix_books = [...books, ...books2];\nconst [frank_herbert, trevanian] = books;\nlog(trevanian); // Logs: Shibumi\n\n// For objects\nconst { email } = niko_zen;\nlog(email); // duendeintemporal@hotmail.com\n\nconst niko_zen_settings = {\n    mode: 'dark',\n    avatar: 'moebius.svg',\n    interfaz: 'compact',\n};\n\nconst niko_zen_data = { ...niko_zen, ...niko_zen_settings };\nlog(niko_zen_data); // Logs both objects niko_zen instance and niko_zen_settings\n/*\n {\n  name: 'Niko',\n  age: 41,\n  email: 'duendeintemporal@hotmail.com',\n  mode: 'dark',\n  avatar: 'moebius.svg',\n  interfaz: 'compact'\n} */\n\nfunction showUser({ name, age, email }: { name: string; age: number; email: string }) {\n    log(`User name: ${name}, age: ${age}, email: ${email}`);\n}\n\nshowUser(niko_zen); // Logs: User name: Niko, age: 41, email: duendeintemporal@hotmail.com\n\n// Assign default values in destructuring\ninterface Config {\n    font: string;\n    mode?: string; // mode is optional\n}\n\nconst config: Config = { font: 'monospace' };\n\nconst { font, mode = 'dark' } = config; // Default value for mode is 'dark'\n\n//Note:  In TypeScript, if you are not explicitly defining types for the variables in the destructuring assignment, you can simply write the code without type annotations. In this case we create the Config interface to avoid ts(2339) error\n\nlog(font, mode); // monospace dark\n\n// Exchange values between variables using destructuring\nlet ninja1 = 'Hiroshi';\nlet ninja2 = 'Neko';\nlet ninja3 = 'Kage';\n\n[ninja1, ninja2, ninja3] = [ninja2, ninja3, ninja1];\nlog(ninja1); // Neko\n\n// Copy objects or arrays without modifying the original\nconst shinobi = {\n    skills: ['fast', 'quick', 'precise', 'lethal', 'computational thinking'],\n    location: 'not found',\n};\n\nconst trix = { ...shinobi };\ntrix.location = 'Bangkok, Thailand';\n\nlog(shinobi.location); // not found\nlog(trix.location); // Bangkok, Thailand\n\n// Use spread operator to pass array elements as arguments in functions\nconst nums = [1, 3, 4, 5, 6];\nlog(Math.max(...nums)); // logs: 6\n\n// Create a function to calculate the average\nconst calculateAverage = (...numbers: number[]) => {\n    const total = numbers.reduce((sum, num) => sum + num, 0);\n    return total / numbers.length;\n};\n\n// Call the function with multiple arguments\nconst average = calculateAverage(90, 76, 45, 23, 67);\nlog(average); // 60.2\n\n// Convert a string into an array of its individual characters\nlet maximum = 'in a society that has abolished every kind of adventure, the only adventure that remains is abolishing the society';\nlet maxim_arr = [...maximum];\nlog(maxim_arr); // Logs the array of characters\n/* [\n  'i', 'n', ' ', 'a', ' ', 's', 'o', 'c', 'i', 'e', 't', 'y',\n  ' ', 't', 'h', 'a', 't', ' ', 'h', 'a', 's', ' ', 'a', 'b',\n  'o', 'l', 'i', 's', 'h', 'e', 'd', ' ', 'e', 'v', 'e', 'r',\n  'y', ' ', 'k', 'i', 'n', 'd', ' ', 'o', 'f', ' ', 'a', 'd',\n  'v', 'e', 'n', 't', 'u', 'r', 'e', ',', ' ', 't', 'h', 'e',\n  ' ', 'o', 'n', 'l', 'y', ' ', 'a', 'd', 'v', 'e', 'n', 't',\n  'u', 'r', 'e', ' ', 't', 'h', 'a', 't', ' ', 'r', 'e', 'm',\n  'a', 'i', 'n', 's', ' ', 'i', 's', ' ', 'a', 'b', 'o', 'l',\n  'i', 's', 'h', 'i',\n  ... 14 more items */\n\n// Comma Operator\n// The comma operator allows execution of multiple operations in a single statement\nlet number1 = 1, number2 = 2, number3 = 3, number4: number;\nlog(number1, number2, number3, number4); // 1 2 3 undefined\n\n// Using the comma operator in variable assignment\n// this is valid in Javascript but in Typescript throw ts(2695) error: number = (225, 14, 40, 8, 220); // number becomes 220\n//log(number); // 220\n//Note: To avoid the warning TS(2695), it's best to avoid using the comma operator in this context.\n// so we need to do a direct assign: \nnumber = 220;\n\n// Flow Control Statements\n// The if statement\nif (number) {\n    number += 4;\n    log(number); // 224\n}\n\n// The else statement\nif (number) {\n    number += 4;\n    log(number); // 228\n} else {\n    // Do something else\n}\n\n// The else if statement\n// The else if statement\nif (number > 300) {\n    number += 4;\n    log(number);\n} else if (number > 200) {\n    number += 4;\n    log(number); // Logs: 232\n} else {\n    // Do something else\n}\n\n// The do-while statement\n/* The do-while statement is a post-test loop, meaning that the escape condition is evaluated only after the code inside the loop has been executed. */\nlet count = 0;\ndo {\n    log(\"I'm learning a lot in this roadmap for coders, even with these basic exercises\");\n    count++;\n} while (count < 1);\n// Logs: I'm learning a lot in this roadmap for coders, even with these basic exercises\n\n// The while statement\n// while (true) {\n//     //Do something\n//     //This creates an infinite loop as it always evaluates to true\n// }\n\n// The for statement\nnumber = 0;\nfor (let i = 1; i <= 100; i++) {\n    number += i;\n}\nlog(number); // Logs: 5050\n\n// The for-in statement\n// Allows us to iterate over the properties of object elements\n// Define an interface for the user\ninterface HideUser {\n    name: string;\n    age: number;\n    location: string;\n}\n\n// Create a user object that adheres to the User interface\nlet user2: HideUser = {\n    name: 'Nikita',\n    age: 32,\n    location: 'Not Found',\n};\n\n// Iterate over the properties of the user object\nfor (let key in user2) {\n    if (user2.hasOwnProperty(key)) { // Check if the property belongs to the object itself\n        log(key); // Logs only the property name\n        log(key, user2[key as keyof HideUser]); // Logs the property and the value\n        log(key, eval('user2.' + key)); // The same as before\n    }\n} /*  \nname\nname Nikita\nname Nikita\nage\nage 32\nage 32\nlocation\nlocation Not Found\nlocation Not Found\n */\n\n/* Object properties in ECMAScript are unordered, so the order in which property names are returned\nin a for-in statement cannot necessarily be predicted. All enumerable properties will be returned\nonce, but the order may differ across browsers. */\n\n// The for-of statement\n// Designed to iterate over array elements\nlet oddNums = [1, 3, 5, 7, 9];\n\nfor (let num of oddNums) {\n    log(num); // Logs each num\n} /* \n1\n3\n5\n7\n9 */\n\n// Using Object.entries(), Object.keys(), Object.values() to iterate over object properties\nfor (let [key, val] of Object.entries(user2)) {\n    log(`${key}: ${val}`);\n} /* \nname: Nikita\nage: 32\nlocation: Not Found */\n\n// Label statements\nouter_loop: for (let i = 0; i <= 10; i++) {\n    inner_loop: for (let y = 0; y < 5; y++) {\n        if ((i == 2) && (y == 4)) break outer_loop;\n        if (y == 4) break inner_loop;\n        log('Is there anybody out there?');\n    }\n} /* Logs: Is there anybody out there?\nIs there anybody out there?\nIs there anybody out there?\nIs there anybody out there?\nIs there anybody out there?\nIs there anybody out there?\nIs there anybody out there?\nIs there anybody out there?\nIs there anybody out there?\nIs there anybody out there?\nIs there anybody out there?\nIs there anybody out there? */\n\n// Break and continue statements\n/* The break and continue statements provide stricter control over the execution of code in a loop.\nThe break statement exits the loop immediately, while the continue statement skips to the next iteration. */\nnumber = 0;\nwhile (number < 5) {\n    if (number == 3) break;\n    log(number);\n    number++;\n} // Logs: 0 1 2\n\nnumber = 0;\nwhile (number < 5) {\n    if (number == 3) {\n        number++;\n        continue;  \n    }\n    log(number);\n    number++;\n} // Logs: 0 1 2 4\n\n// The with Statement\n/* The with statement was created for convenience when repeatedly accessing properties of a single object. \nHowever, it is generally discouraged in modern JavaScript and Tyscript due to potential readability and performance issues. */\n// with (user) {\n//     log(name); // Nikita\n//     log(age); // This would throw an error because age is undefined in this context\n// }\n//Note: This structure is not allowed in Typescript\n\n\n// The Switch Statement\nswitch (user.name) {\n    case 'Nikita': \n        log('Welcome agent');\n        break;\n    case 'Calvin & Hobbes': \n        log('Bring me some cookies');\n        break;\n    default: \n        log('Turn off that TV'); // This will log because the second case is missing\n}\n\n// Using an expression that evaluates a string concatenation in a case\n/*\nlet num = 25;\nswitch (true) {\n    case num < 0:\n        log(\"Less than 0.\");\n        break;\n    case num >= 0 && num <= 10:\n        log(\"Between 0 and 10.\");\n        break;\n    case num > 10 && num <= 20:\n        log(\"Between 10 and 20.\");\n        break;\n    default:\n        log(\"More than 20.\");\n}\n*/\n\n// Extra difficulty Exercise: Create a program that prints the even numbers from 10 to 55 inclusive,\n// avoiding printing the numbers if they are equal to 16 or multiples of 3\nfor (let i = 10; i <= 55; i++) {\n    if (i % 3 == 0 || i == 16) continue\n    if (i % 2 == 0) {\n        log(i); // Log the even number\n    }\n}\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/eulogioep.ts",
    "content": "// Operadores Aritméticos\nconsole.log(\"Operadores Aritméticos:\");\nconsole.log(5 + 3);  // Suma: 8\nconsole.log(10 - 4); // Resta: 6\nconsole.log(3 * 4);  // Multiplicación: 12\nconsole.log(20 / 5); // División: 4\nconsole.log(23 % 5); // Módulo: 3\nconsole.log(2 ** 3); // Exponenciación: 8\n\n// Operadores de Comparación\nconsole.log(\"\\nOperadores de Comparación:\");\nconsole.log(5 > 3);  // Mayor que: true\nconsole.log(5 < 3);  // Menor que: false\nconsole.log(5 >= 5); // Mayor o igual que: true\nconsole.log(5 <= 4); // Menor o igual que: false\nconsole.log(5 === 5);// Igualdad estricta: true\nconsole.log(5 !== 4);// Desigualdad estricta: true\n\n// Operadores Lógicos\nconsole.log(\"\\nOperadores Lógicos:\");\nconsole.log(true && false); // AND lógico: false\nconsole.log(true || false); // OR lógico: true\nconsole.log(!true);         // NOT lógico: false\n\n// Operadores de Asignación\nconsole.log(\"\\nOperadores de Asignación:\");\nlet x = 10;\nconsole.log(x);  // 10\nx += 5;\nconsole.log(x);  // 15\nx -= 3;\nconsole.log(x);  // 12\nx *= 2;\nconsole.log(x);  // 24\nx /= 4;\nconsole.log(x);  // 6\n\n// Operadores de Identidad (para objetos)\nconsole.log(\"\\nOperadores de Identidad:\");\nlet obj1 = { name: \"John\" };\nlet obj2 = { name: \"John\" };\nlet obj3 = obj1;\nconsole.log(obj1 === obj2); // false (diferentes objetos)\nconsole.log(obj1 === obj3); // true (mismo objeto)\n\n// Operadores de Bits\nconsole.log(\"\\nOperadores de Bits:\");\nconsole.log(5 & 3);  // AND bit a bit: 1\nconsole.log(5 | 3);  // OR bit a bit: 7\nconsole.log(5 ^ 3);  // XOR bit a bit: 6\nconsole.log(~5);     // NOT bit a bit: -6\nconsole.log(5 << 1); // Desplazamiento a la izquierda: 10\nconsole.log(5 >> 1); // Desplazamiento a la derecha: 2\n\n// Estructuras de Control\n\n// Condicional if-else\nconsole.log(\"\\nCondicional if-else:\");\nlet age = 18;\nif (age >= 18) {\n    console.log(\"Eres mayor de edad\");\n} else {\n    console.log(\"Eres menor de edad\");\n}\n\n// Condicional switch\nconsole.log(\"\\nCondicional switch:\");\nlet day = \"Lunes\";\nswitch (day) {\n    case \"Lunes\":\n        console.log(\"Hoy es lunes\");\n        break;\n    case \"Martes\":\n        console.log(\"Hoy es martes\");\n        break;\n    default:\n        console.log(\"Es otro día de la semana\");\n}\n\n// Bucle for\nconsole.log(\"\\nBucle for:\");\nfor (let i = 0; i < 5; i++) {\n    console.log(`Iteración ${i}`);\n}\n\n// Bucle while\nconsole.log(\"\\nBucle while:\");\nlet count = 0;\nwhile (count < 3) {\n    console.log(`Contador: ${count}`);\n    count++;\n}\n\n// Bucle do-while\nconsole.log(\"\\nBucle do-while:\");\nlet num = 0;\ndo {\n    console.log(`Número: ${num}`);\n    num++;\n} while (num < 3);\n\n// Manejo de excepciones\nconsole.log(\"\\nManejo de excepciones:\");\ntry {\n    throw new Error(\"Este es un error de ejemplo\");\n} catch (error) {\n    console.log(`Error capturado: ${error.message}`);\n} finally {\n    console.log(\"Este bloque siempre se ejecuta\");\n}\n\n// DIFICULTAD EXTRA\nconsole.log(\"\\nDIFICULTAD EXTRA:\");\nfor (let i = 10; i <= 55; i++) {\n    if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n        console.log(i);\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/fravelz.ts",
    "content": "/** OPERADORES ****************************************************************/\n\n// Operadores Aritméticos (+,-,*,/,%)\nlet num1: number = 15;\nlet num2: number = 5;\n\nlet suma: number = num1 + num2;\nlet resta: number = num1 - num2;\nlet multiplicacion: number = num1 * num2;\nlet division: number = num1 / num2;\nlet resto: number = num1 % num2;\nlet exponencial: number = Math.pow(num1, num2);\n\n// Operadores Lógicos (||, &&, !)\n/*\n * Operadores Lógicos (||, &&, !)\n * || → OR → Si al menos una de las condiciones es verdadera, el resultado es verdadero.\n * && → AND → Si todas las condiciones son verdaderas, el resultado es verdadero.\n * ! → NOT → Invierte el valor lógico de una expresión. Si la expresión es verdadera, se vuelve falsa, y viceversa.\n */\n\nlet x: boolean = true;\nlet y: boolean = false;\nlet z: boolean = true;\n\nlet logico1: boolean = x && y && z;\nlet logico2: boolean = x || y || z;\nlet logico3: boolean = ((x || !y) && z) || (!x && z);\n\n\n// Operadores de Comparación (<, <=, >=, >, ==, ===, !=, !==)\nlet n1: number = 16;\nlet n2: number = 8;\nlet n3: string = \"16\";\n\nlet comparacion1: boolean = n1 > n2;\nlet comparacion2: boolean = n1 < n2;\nlet comparacion3: boolean = n1 >= n2;\nlet comparacion4: boolean = n1 <= n2;\n\n/*\n * en typescript, da error, ya que no se pueden comparar tipos de datos diferentes,\n * a diferencia de javascript que lo hace pero no es recomendable\n */\n\n// let comparacion5: boolean = n1 == n3;\n// let comparacion6: boolean = n1 != n3;\n// let comparacion7: boolean = n1 === n3;\n// let comparacion8: boolean = n1 !== n3;\n\n// Operadores de Asignación (=, +=, -=, *=, /=, %=, **=)\nlet a: number = 10;\na += 5; // a = a + 5 → a = 10 + 5 → a = 15\na -= 3; // a = a - 3 → a = 15 - 3 → a = 12\na *= 2; // a = a * 2 → a = 12 * 2 → a = 24\na /= 4; // a = a / 4 → a = 24 / 4 → a = 6\na %= 4; // a = a % 4 → a = 6 % 4 → a = 2\na **= 3; // a = a ** 3 → a = 2 ** 3 → a = 8\n\n--a; // a = a - 1 → a = 8 - 1 → a = 7\na--; // a = a - 1 → a = 7 - 1 → a = 6\n++a; // a = a + 1 → a = 6 + 1 → a = 7\na++; // a = a + 1 → a = 7 + 1 → a = 8\n\n// Operadores bit a bit\nlet var1: number = 10; // 1010\nlet var2: number = 3; // 0011\n\nlet opeacionBit1: number = var1 & var2; // 0010 - Si ambos son 1\nlet opeacionBit2: number = var1 | var2; // 1011 - Si almenos 1 es 1\nlet opeacionBit3: number = var1 ^ var2; // 1001 -  Si los bits son diferentes 0 si son iguales 1\nlet opeacionBit4: number = ~var1; // 0101 -  Invierte el valor bit a bit\nlet opeacionBit5: number = var1 >> 2; // 1010 → 0101 → 0010\nlet opeacionBit6: number = var1 << 2; // 1010 → 101000\n\n/** ESTRUCTURAS DE CONTROL ****************************************************/\n\n// Condicionales\nconst MAYORIA_EDAD: number = 18;\nlet edad_persona: number = 23;\n\nif (edad_persona < 0 || edad_persona > 120) {\n    console.log(`Edad inexistene, ingrese un valor correcto`);\n\n} else if (edad_persona < MAYORIA_EDAD) {\n    console.log(`Con ${edad_persona} años sos menor de edad`);\n\n} else {\n    console.log(`Con ${edad_persona} años sos mayor de edad`);\n}\n\n//Switch\n\nlet opcion: number = 2;\n\nswitch (opcion) {\n    case 1:\n        console.log(\"Opción 1\");\n        break;\n\n    case 2:\n        console.log(\"Opción 2\");\n        break;\n\n    case 3:\n        console.log(\"Opción 3\");\n        break;\n\n    default:\n        console.log(\"Debes ingresar una de las 3 opciones\");\n        break;\n}\n\n//Bucle For\n\nfor (let i: number = 0; i < 10; i++) {\n    console.log(`i = ${i}`);\n}\n\n//Bucle While\n\nlet j: number = 10;\nwhile (j-- > 5) {\n    console.log(`j = ${j}`);\n}\n\n//Bucle Do-while\nlet tiene_permiso: boolean = false;\n\ndo {\n    console.log(\"No tienes permiso\");\n\n    //Usando variables anteriormente creadas\n    if (edad_persona > MAYORIA_EDAD) {\n        tiene_permiso = true;\n        console.log(\"Ahora si tienes permiso\");\n    }\n\n} while ((tiene_permiso = false));\n\n// DIFICULTAD EXTRA\nfor (let i: number = 10; i <= 55; i++) {\n    if (!(i&1) && i != 16 && i % 3 !== 0) {\n        console.log(i);\n    }\n}\n\nexport { };\n\n// > Autor: Fravelz\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/giovanyosorio.ts",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n//TYPESCRIPT\n\n//Operadores aritmeticos\nconsole.log(\"Operadores aritmeticos\");\nlet a : number= 5;\nlet b :number = 2;\nlet c : number= 3;\n\nconsole.log(\"Suma: \" + (a + b));\nconsole.log(\"Resta: \" + (a - b));\nconsole.log(\"Multiplicacion: \" + (a * b));\nconsole.log(\"Division: \" + (a / b));\nconsole.log(\"Modulo: \" + (a % b));\nconsole.log(\"Incremento: \" + (++a));\nconsole.log(\"Decremento: \" + (--a));\n\n//Operadores de comparacion\nconsole.log(\"Operadores de comparacion\");\nconsole.log(\"Igualdad: \" + (a == b));\nconsole.log(\"Desigualdad: \" + (a != b));\nconsole.log(\"Mayor que: \" + (a > b));\nconsole.log(\"Menor que: \" + (a < b));\nconsole.log(\"Mayor o igual que: \" + (a >= b));\nconsole.log(\"Menor o igual que: \" + (a <= b));\n\n//Operadores logicos\nconsole.log(\"Operadores logicos\");\nconsole.log(\"AND: \" + (a > b && b > c));\nconsole.log(\"OR: \" + (a > b || b > c));\nconsole.log(\"NOT: \" + !(a > b));\n\n//Operadores de asignacion\nconsole.log(\"Operadores de asignacion\");\nconsole.log(\"Asignacion: \" + (a = b));\nconsole.log(\"Suma y asignacion: \" + (a += b));\nconsole.log(\"Resta y asignacion: \" + (a -= b));\nconsole.log(\"Multiplicacion y asignacion: \" + (a *= b));\nconsole.log(\"Division y asignacion: \" + (a /= b));\nconsole.log(\"Modulo y asignacion: \" + (a %= b));\n\n//Operadores de identidad\nconsole.log(\"Operadores de identidad\");\nconsole.log(\"Identidad: \" + (a === b));\nconsole.log(\"No identidad: \" + (a !== b));\n\n//Operadores de pertenencia\nconsole.log(\"Operadores de pertenencia\");\nlet d : string = \"Hola mundo\";\nconsole.log(\"Incluye: \" + d.includes(\"Hola\"));\nconsole.log(\"Empieza con: \" + d.startsWith(\"Hola\"));\nconsole.log(\"Termina con: \" + d.endsWith(\"mundo\"));\n\n//Operadores de bits\nconsole.log(\"Operadores de bits\");\nconsole.log(\"AND: \" + (a & b));\nconsole.log(\"OR: \" + (a | b));\nconsole.log(\"XOR: \" + (a ^ b));\nconsole.log(\"Desplazamiento a la izquierda: \" + (a << b));\nconsole.log(\"Desplazamiento a la derecha: \" + (a >> b));\nconsole.log(\"Desplazamiento a la derecha sin signo: \" + (a >>> b));\nconsole.log(\"Negacion: \" + (~a));\n\n//Estructuras de control\nconsole.log(\"Estructuras de control\");\n//Condicionales\nconsole.log(\"Condicionales\");\nif(a > b){\n    console.log(\"a es mayor que b\");\n} else if(a < b){\n    console.log(\"a es menor que b\");\n}\n\n//Iterativas\nconsole.log(\"Iterativas\");\nlet i : number = 0;\nwhile(i < 10){\n    console.log(i);\n    i++;\n}\n\nfor(let j = 0; j < 10; j++){\n    console.log(j);\n}\n\n//Excepciones\nconsole.log(\"Excepciones\");\ntry{\n    throw \"Error\";\n} catch(e){\n    console.log(e);\n}\n\n//Dificultad extra\nconsole.log(\"Dificultad extra\");\nfor(let k = 10; k <= 55; k++){\n    if(k % 2 == 0 && k != 16 && k % 3 != 0){\n        console.log(k);\n    }\n}\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/gitperalta.ts",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n//* 1. OPERADORES\n\nlet a = 1;\nlet b = 2;\nlet c = [a, b];\nlet d = { c: c, 3: 3 };\n\n// Asignación\nconsole.log(\"Asignación: \", (a = b));\nconsole.log(\"Asignación de adición \", (a += b));\nconsole.log(\"Asignación de resta: \", (a -= b));\nconsole.log(\"Asignación de multiplicación: \", (a *= b));\nconsole.log(\"Asignació de división: \", (a /= b));\nconsole.log(\"Asignación de residuo: \", (a %= b));\nconsole.log(\"Asignación de exponenciación: \", (a **= b));\nconsole.log(\"Asignación desplazamiento a la izquierda: \", (a <<= b));\nconsole.log(\"Asignación de desplazamiento a la derecha: \", (a >>= b));\nconsole.log(\"Asignación de desplazamiento a derecha sin signo: \" + (a >>>= b));\nconsole.log(\"Asignación AND bit a bit: \", (a &= b));\nconsole.log(\"Asignación XOR bit a bit: \", (a ^= b));\nconsole.log(\"Asignación OR bit a bit: \", (a |= b));\nconsole.log(\"Asignación AND lógico: \", (a &&= b));\nconsole.log(\"Asignación OR lógico: \", (a ||= b));\nconsole.log(\"Asignación de anulación lógica: \", (a ??= b));\n\n// Comparacion\nconsole.log(\"Igual: \", a == b);\nconsole.log(\"No es igual: \", a != b);\nconsole.log(\"Estrictamente igual: \", a === b);\nconsole.log(\"Desigualdad estricta: \", a !== b);\nconsole.log(\"Mayor que: \", a > b);\nconsole.log(\"Mayor o igual que: \", a >= b);\nconsole.log(\"Menor que: \", a < b);\nconsole.log(\"Menor o igual: \", a <= b);\n\n// Aritmeticos\nconsole.log(\"Residuo: \", a % b);\nconsole.log(\"Incremento: \", a++);\nconsole.log(\"Decremento: \", a--);\nconsole.log(\"Negación unaria: \", -a);\nconsole.log(\"Positivo unario: \", +a);\nconsole.log(\"Operador de exponenciación: \", a ** b);\n\n// Bit a Bit\nconsole.log(\"AND a nivel de bits: \", a & b);\nconsole.log(\"OR a nivel de bits: \", a | b);\nconsole.log(\"XOR a nivel de bits: \", a ^ b);\nconsole.log(\"NOT a nivel de bits: \", ~a);\nconsole.log(\"Desplazamiento a la izquierda: \", a << b);\nconsole.log(\"Desplazamineto a derecha de propagación de signo: \", a >> b);\nconsole.log(\"Desplazamiento a la deracha de relleno cero: \", a >>> b);\n\n// Lógicos\nconsole.log(\"AND lógico: \", a && b);\nconsole.log(\"OR lógico: \", a || b);\nconsole.log(\"NOT lógico: \", !a);\n\n// Ternario\nconsole.log(\"Ternario: \", a > b ? a : b);\n\n// Coma\nconsole.log(\"Coma: \", (a = b), (b = a));\n\n// Unarios\nconsole.log(\"Delete: \", delete c[0]);\nconsole.log(\"Type of: \", typeof a);\nconsole.log(\"Void: \", void a);\n\n// Relacionales\nconsole.log(\"In: \", 3 in d);\nconsole.log(\"Instance of: \", d instanceof Object);\n\n//* Estructuras de Control\n\n// If - Else\nif (a === b) {\n  console.log(\"Son iguales\");\n} else {\n  console.log(\"No son iguales\");\n}\n\n// Switch\nswitch (a) {\n  case 1:\n    console.log(\"a es igual a 1\");\n    break;\n  case 2:\n    console.log(\"a es igual a 2\");\n  default:\n    console.log(\"a no es igual a 1 ni a 2\");\n    break;\n}\n\n// For\nfor (let i = 0; i < c.length; i++) {\n  console.log(c[i]);\n}\n\n// While\nlet j = 1;\nwhile (j <= 10) {\n  console.log(j);\n  j++;\n}\n\n// Do While\nlet k = 10;\ndo {\n  console.log(k);\n  k--;\n} while (k > 0);\n\n//* Dificultad Extra\nfor (let index = 10; index <= 55; index++) {\n  if (index !== 16 && index % 3 !== 0 && index % 2 === 0) console.log(index);\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/hozlucas28.ts",
    "content": "/*\n    Type of operators...\n*/\n\n// Arithmetic\nlet number01: number = 10\n\nconsole.log(number01 + 1)\nconsole.log(number01 - 1)\n\nconsole.log(number01 * 2)\nconsole.log(number01 ** 2)\n\nconsole.log(number01 / 5)\nconsole.log(number01 % 5)\n\nnumber01++\nconsole.log(number01)\n\nnumber01--\nconsole.log(number01)\n\n// Comparison\nconst obj = { text: 'Hello' }\n\n// @ts-expect-error\nconsole.log(1 == '1')\nconsole.log(1 === 1)\n\nconsole.log(1 > 1)\nconsole.log(2 < 2)\nconsole.log(1 >= 1)\nconsole.log(2 <= 2)\n\n// @ts-expect-error\nconsole.log(obj === { text: 'hello' })\nconsole.log(Object.is(obj, { text: 'hello' }))\n\n// Logical\nconsole.log(!true)\n\nconsole.log(true && false)\nconsole.log(true || false)\n\nconsole.log(undefined ?? 'Hi!')\n\n/*\n    Control structures...\n*/\n\n// < if >\nif (!true) {\n\tconsole.log('¡Hello World!')\n} else {\n\tconsole.log('¡By World!')\n}\n\n// < ternary >\nconst text: string = true ? 'Mouredev' : 'Midudev'\nconsole.log(text)\n\n// < switch >\nconst letter: string = 'A'\n\nswitch (letter) {\n\tcase 'A':\n\t\tconsole.log('Case 1 --> Letter A')\n\t\tbreak\n\tcase 'E':\n\t\tconsole.log('Case 2 --> Letter E')\n\t\tbreak\n\tcase 'I':\n\t\tconsole.log('Case 3 --> Letter I')\n\t\tbreak\n\tcase 'O':\n\t\tconsole.log('Case 4 --> Letter O')\n\t\tbreak\n\tcase 'U':\n\t\tconsole.log('Case 5 --> Letter U')\n\t\tbreak\n\n\tdefault:\n\t\tconsole.log(`Default case --> Letter ${letter}`)\n\t\tbreak\n}\n\n// < while > and < do while >\nlet i: number = 0\n\nwhile (i !== 2) {\n\tconsole.log('While!')\n\ti++\n}\n\ndo {\n\tconsole.log('Do while!')\n} while (false)\n\n// < for >\nfor (let j = 0; j < 5; j++) {\n\tif (j === 3) break\n\tconsole.log(j)\n}\n\n// < for of > and < for in >\nconst animals: string[] = ['Dog', 'Cat', 'Crocodile', 'Shark']\n\nfor (const animal of animals) {\n\tif (animal === 'Crocodile') continue\n\tconsole.log(animal)\n}\n\nfor (const index in animals) {\n\tconsole.log(index)\n}\n\n/*\n    Additional challenge...\n*/\n\nconsole.log()\nfor (let i = 10; i < 56; i++) {\n\tconst isEven = i % 2 === 0\n\tconst isMultipleOfThree = i % 3 === 0\n\tif (isEven && i !== 16 && !isMultipleOfThree) console.log(i)\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/isaias-alt.ts",
    "content": "//* Operadores aritméticos\nlet aditionOperation: number = 1 + 1;\nlet subtractionOperation: number = 2 - 1;\nlet multiplicationOperation: number = 2 * 2;\nlet divisionOperation: number = 10 / 2;\nlet moduleOperation: number = 4 % 2; // <- retorna el resto de la division\nlet exponentiationOperation: number = 2 ** 2; // <- eleva 2 a la potencia de dos\n\n//* Operadores de asignación\nlet a: number = 2;\na += 2; // a = a + 2\na -= 2; // a = a - 2\na *= 2; // a = a * 2\na /= 2; // a = a / 2\na %= 2; // a = a % 2 <- se le asigna el resto de la division entre los dos\na **= 2; // a = a ** 2 <- a elevado a la potencia de 2\n\n//* Operadores de comparación\nlet y: number = 3;\nlet z: number = 2;\nlet w: number = 1;\nconsole.log(y == \"4\"); // igualdad de valores sin verificar el tipo\nconsole.log(y != 3); // diferencia de valores sin verificar el tipo\nconsole.log(y === 4); // igualdad de valores verificando el tipo\nconsole.log(y !== 3); // difierencia de valores verificando el tipo\nconsole.log(z > y); // comprueba si z es mayor que y\nconsole.log(z >= y); // comprueba si z es mayor o igual que y\nconsole.log(w < y); // comprueba si w es menor que y\nconsole.log(w <= y); // comprueba si w es mejor o igual que y\n\n//* Operadores lógicos\nlet age: number = 24;\nage > 18\n  ? console.log(\"Soy mayor de edad, una cerveza, por favor\")\n  : console.log(\"No soy mayor de edad\"); // Operador condicional o ternario\n\n// AND (&&)\nconsole.log(true && true); // && devuelve verdadero si ambos operandos son verdaderos; de lo contrario, devuelve falso\n\n// OR (||) -> devuelve verdadero si almenos uno de los operandos es verdadero\nconsole.log(false || false); // devuelve false\nconsole.log(true || false); // devuelve true\nconsole.log(false || true); // devuelve true\nconsole.log(true || true); // devuelve true\n\n// Operador NOT (!) -> utilzado para el invertir (negar) valor de una variable. Si una variable vale true, al negarla valdrá false\nconsole.log(!true); // devuelve false\nconsole.log(!false); // devuelve true\n\n//* Condicionales y bucles (entructuras de control)\n\n//Condicionales\nlet edad: number = 18;\n\nif (edad >= 18) {\n  console.log(\"Puedes beber cerveza\");\n} else {\n  console.log(\"No puedes beber cerveza... aun\");\n}\n\n// Iterativas\nfor (let i: number = 1; i <= 5; i++) {\n  console.log(\"Iteración:\", i);\n}\n\nlet arrayIterativo: number[] = [1, 2, 3, 4, 5];\nfor (let elemento of arrayIterativo) {\n  console.log(\"Elemento:\", elemento);\n}\n\n// Excepciones\ntry {\n  let result: number = 10 / 0;\n  console.log(\"Resultado:\", result);\n} catch (error) {\n  console.error(\"Error:\", error.message);\n} finally {\n  console.log(\"Bloque finally ejecutado siempre.\");\n}\n\n// Switch\nlet diaDeLaSemana: string = \"Viernes\";\nswitch (diaDeLaSemana) {\n  case \"Lunes\":\n    console.log(\"Es el primer día de la semana. Hay que laburar lpm\");\n    break;\n  case \"Martes\":\n  case \"Miércoles\":\n  case \"Jueves\":\n    console.log(\"Estamos a mitad de semana.\");\n    break;\n  case \"Viernes\":\n    console.log(\"Fin de la semana laboral. Cerveza\");\n    break;\n  case \"Sábado\":\n  case \"Domingo\":\n    console.log(\"Proyectos propios, pelis y más cerveza\");\n    break;\n  default:\n    console.log(\"El dia no es valido.\");\n}\n\n//* Dificultad opcional\nfor (let i: number = 10; i <= 55; i++) {\n  if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n    console.log(\"Número\", i);\n  }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/jesusEs1312.ts",
    "content": "//Variables\nlet x:number = 100;\nlet y:number = 200;\nlet z:number = 300;\nlet a:number = x + y;\nlet arr:number[] = [10,20,30,40];\nlet mostrarMensaje:boolean = true;\nlet dia:number = 7;\nlet veces:number = 0;\n\nfunction holaMundo():string {\n    return 'Hola mundo';\n}\n\n//Operadores de comparación\nif(a == z){console.log(`Igual (==): ${a} ${z}`);}\nif(x != z){console.log(`No es igual (!=): ${x} ${z}`);}\nif(a === z){console.log(`Estrictamente igual (===): ${a} ${z}`);}\nif(x !== y){console.log(`Desigualdad estricta (!==): ${a} ${z}`);}\nif(a > x){console.log(`Mayor que (>): ${a} ${x}`);}\nif(a >= z){console.log(`Mayor o igual que (>=): ${a} ${z}`);}\nif(x < a){console.log(`Menor que (<): ${x} ${a}`);}\nif(x <= a){console.log(`Menor o igual que (<=): ${x} ${a}`);}\n\n//Operadores lógicos\nif((a == z) && (x != z)){console.log('AND lógico (&&)');}\nif((y == z) || (x != z)){console.log('OR lógico (||)');}\nif(!(x != z)){console.log('NOT lógico (!)');}\n\n//Operadores Aritméticos\nconsole.log(`Residuo (%) ${z} % ${a}:`, z%a);\nconsole.log(`Incremento (++) ++${z}:`, ++z);\nconsole.log(`Decremento (--) --${z}:`, --z);\nconsole.log(`Negación unaria (-) -${z}:`, -z);\nconsole.log(`Exponenciación (**) ${z} ** ${a}:`, z**a);\n\n//Operadores de Asignación\nz = x;\nconsole.log('Asignación (=):', z);\nz += x;\nconsole.log('Asignación de adición (+=):', z);\nz -= x;\nconsole.log('Asignación de reducción (-=):', z);\nz *= y;\nconsole.log('Asignación de multiplicación (*=):', z);\nz /= x;\nconsole.log('Asignación de división (/=):', z);\nz **= x;\nconsole.log('Asignación de exponenciación (**=):', z);\nx %= y;\nconsole.log('Asignación de residuo (%=):', x);\n\n//Operadores bit a bit\nconsole.log('AND a nivel de bits:', a & z);\nconsole.log('OR a nivel de bits:', a | z);\nconsole.log('XOR a nivel de bits:', a ^ z);\nconsole.log('NOT a nivel de bits:', ~z);\nconsole.log('Desplazamiento a la izquierda:', z << a);\nconsole.log('Desplazamiento a la derecha:', z >> a);\n\n//Estructura de control if...else\nif(mostrarMensaje){\n    console.log('Estructura if verdadera');\n} else {\n    console.log('Estructura if falsa');\n}\n\n//Estructura de control switch\nswitch(dia){\n    case 1: console.log('Hoy es lunes'); break;\n    case 2: console.log('Hoy es Martes'); break;\n    case 3: console.log('Hoy es Miercoles'); break;\n    case 4: console.log('Hoy es Jueves'); break;\n    case 5: console.log('Hoy es Viernes'); break;\n    case 6: console.log('Hoy es Sabado'); break;\n    case 7: console.log('Hoy es Domingo'); break;\n}\n\n//Estructura while\nwhile(veces < 4){\n    console.log('Mensaje', veces);\n    veces++;\n}\n\n//Estructura for in\nfor(let index in arr){\n    console.log(arr[index]);\n}\n\n//Estructura try\ntry {\n    console.log(holaMundo);\n} catch (ex) {\n    console.log('Hubo un error');  \n} finally {\n    console.log('Finally');\n}\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/juanRCoder.ts",
    "content": "let num1: number = 10;\nlet num2: number = 12;\nlet str1: string = 'Hola';\n\n// OPERADORES ARITMETICOS:\n// (+) (-) (*) (/) (**) (%) = suma, resta, multiplicar, dividir, potencia, resto.\n// (+=) (-=) (*=) (/=)\t=> usados para operar en los valores de las variables.\n\nconsole.log(num1 + num2) // 22\nconsole.log(num1 - num2) // -2\nconsole.log(num1 * num2) // 120\nconsole.log(num1 / num2) // 0.8333333333333334\nconsole.log(num1 ** num2) // 1000000000000\nconsole.log(num1 % num2) // 10\n\nconsole.log(str1 += ' Pedro') // Hola Pedro\nconsole.log(num1 -= num2) // 10\nconsole.log(num1 *= num2) // 120\nconsole.log(num1 /= num2) // 10\n\n// OPERADORES LOGICOS:\n// (&&) (||) (!) = and(y) - o(or) - contrario,not(!).\n\nconsole.log(str1 && 1 + 1)  //Ambas condiciones deben ser son true = true\nconsole.log(str1 || 1 + 1)  //Basta con que una condicion sea true = true\nconsole.log(!1)  //Si es true = false y viceversa\n\n\n// OPERADORES DE COMPARACIÓN:\n// (==) (!=) (===) (!==)\t= igual - distinto - exactamante igual - exactamente distinto. \n// (>)  (<)  (>=)  (<=)\t= mayor - menor - mayor e igual - menor e igual.\n\nconsole.log(num1 == num2) // false\nconsole.log(num1 != num2) // true\nconsole.log(num1 === num2) // false\nconsole.log(num1 !== num2) // true\nconsole.log(num1 > num2) // false\nconsole.log(num1 < num2) // true\nconsole.log(num1 >= num2) // false\nconsole.log(num1 <= num2) // true\n\n\n// ESTRUCTURAS DE CONTROL\n// if-else, si la condicion se cumple en la condicion if , ejecuta bloque if si no el bloque else.\nif (15 < 20) {\n    console.log('15 es menor que 20')\n} else {\n    console.log('20 es mayor que 15')\n}\n\n// switch, bloque en la cual se aplica diferentes casos segun la expresion\nswitch(15 < 20){\n    case true:\n        console.log('15 es menor que 20')\n        break\n    case false:\n        console.log('20 es mayor que 15')\n        break\n    default:\n        console.log('No se cumplio ninguno de los casos')\n}\n\n// For, iterable que se ejecuta segun un rango de numeros\n// Se compone de (inicializacion, condicion, aumento/decremento)\nfor (let i=0; i<10; i++){\n    console.log(i)\n}\n\n// While, igual que el for, iterable que se ejecuta indefinidamente hasta no cumplir la condicion\n// OJO: agregarle un deliminador ya sea incremento/decremento\nlet i = 10\nwhile(i < 10){\n    console.log(i);\n    i++;\n}\n\n/*\n* DIFICULTAD EXTRA (opcional):\n* Crea un programa que imprima por consola todos los números comprendidos\n* entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n*\n* Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n*/\nconst isNumbers = ():void => {\n    const list: number[] = [];\n    for (let i=10; i<=55; i++){\n        if(i % 3 == 0 || i == 16){\n            continue;\n        }\n        list.push(i);\n    }\n    console.log(list);\n}\n\nisNumbers();\n// [\n//     10, 11, 13, 14, 17, 19, 20, 22, 23,\n//     25, 26, 28, 29, 31, 32, 34, 35, 37,\n//     38, 40, 41, 43, 44, 46, 47, 49, 50,\n//     52, 53, 55\n// ]\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/juserdev.ts",
    "content": "/*\n * EJERCICIO:\n ! - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...(Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n \n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos que representen todos los tipos de estructuras de control que existan en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\nlet a: number = 5\nlet b: number = 2\n\nlet suma: number = a + b\nconsole.log(suma)\n\nlet mult: number = a * b\nconsole.log(mult)\n\nlet div: number = a / b\nconsole.log(div)\n\nlet modulus: number = a % b\nconsole.log(modulus)\n\nlet exponen: number = a ** b\nconsole.log(exponen)\n\nlet c: number = 5\n\nconsole.log(c = b)\nconsole.log(a += b)\nconsole.log(a -= b)\nconsole.log(a *= b)\nconsole.log(a /= b)\nconsole.log(a %= b)\nconsole.log(a = c)\nconsole.log(a ** b)\n\n\nconsole.log(a == b)\nconsole.log(a < b)\nconsole.log(a > b)\nconsole.log(a >= b)\nconsole.log(a <= b)\nconsole.log(a != b)\n\nconsole.log(a && b)\nconsole.log(a || b)\nconsole.log(!a)\n\nconst myFunc = ()=>{\n    for (let i = 0; i <= 55; i++) {\n        if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n            console.log(i)\n        }\n    }\n}\n\nmyFunc()"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/kodenook.ts",
    "content": "\nlet num1: number = 4\nlet num2: number = 3\n\n/*\n    Arithmetic Operators\n*/\n\n// addition\nconsole.log(`sum: ${num1 + num2}`)\n// subtraction\nconsole.log(`subtraction: ${num1 - num2}`)\n// multiplication\nconsole.log(`multiplication: ${num1 * num2}`)\n// division\nconsole.log(`division: ${num1 / num2}`)\n// modulus\nconsole.log(`modulus: ${num1 % num2}`)\n// exponentation\nconsole.log(`exponentation: ${num1 ** num2}`)\n\n/*\n    Assignment Operators\n*/\n\nlet num3: number\n\nconsole.log(num3 = 2) // assignment\nconsole.log(num3 += 3) // addition\nconsole.log(num3 -= 1) // subtraction\nconsole.log(num3 *= 2) // multiplication\nconsole.log(num3 /= 3) // division\nconsole.log(num3 %= 2) // modulus\nconsole.log(num3 **= 2) // exponentation\n\n/*\n    Comparison Operators\n*/\n\nconsole.log(num1 == num2) // equal\nconsole.log(num1 != num2) // not equal\nconsole.log(num1 > num2) // greater than\nconsole.log(num1 < num2) // less than\nconsole.log(num1 >= num2) // greater than or equal than\nconsole.log(num1 <= num2) // less than or equal than\n\n/*\n    Logical Operators\n*/\n\nconsole.log(num1 && num2) // true if both are true\nconsole.log(num1 || num2) // true if either are true\nconsole.log(!num1) // true if not true\n\n/*\n    Bitwise Operators\n*/\n\nconsole.log(6 & 3) // compare each bit and set it to 1 if both are 1, otherwise it is set to 0\nconsole.log(6 | 3) // compare each bit and set it to 1 if one or both are 1, otherwise it is set to 0\nconsole.log(6 ^ 3) // compare each bit and set it to 1 if only one is 1, otherwise it is set to 0\nconsole.log(~3) // inverts each bit, 0 becomes 1 and 1 becomes 0\nconsole.log(3 << 2) // insert the specified numbers of 0's (in this case 2) from the right\nconsole.log(8 >> 2) // insert the specified numbers of 0's (in this case 2) from the left\nconsole.log(8 >>> 2) // insert the specified numbers of 0's (in this case 2) from the left, result unsigned\n\n/*\n    Conditional Assignment\n*/\n\nconsole.log(true ? 'true' : 'false')\nconsole.log(null ?? 'false')\n\n/*\n    If\n*/\n\nif (false) {\n    console.log('true')\n} else if (false) {\n    console.log('true')\n} else {\n    console.log('true')\n}\n\n/*\n    Switch\n*/\n\nlet day: string\n\nswitch (new Date().getDay()) {\n    default:\n        day = 'Sunday'\n    case 1:\n        day = 'Monday'\n        break\n    case 2:\n        day = 'Tuesday'\n        break\n    case 3:\n        day = 'Wednesday'\n        break\n    case 4:\n        day = 'Thursday'\n        break\n    case 5:\n        day = 'Friday'\n        break\n    case 6:\n        day = 'Saturday'\n}\n\nconsole.log(day)\n\n/*\n    Loop For\n*/\n\nfor (let i = 0; i < 5; i++) {\n    console.log(i)\n}\n\nconst person: { [key: string]: any } = { fname: 'John', lname: 'Doe', age: 25 };\n\nfor (let x in person) {\n    console.log(person[x])\n}\n\nconst cars: Array<string> = ['BMW', 'Volvo', 'Mini']\n\nfor (let x of cars) {\n    console.log(x)\n}\n\n/*\n    Loop While\n*/\n\nlet i: number = 0\n\nwhile (i < 10) {\n    console.log('The number is ' + i)\n    i++\n}\n\n/*\n    Loop Do-While\n*/\n\ndo {\n    console.log('The number is ' + i)\n    i--\n}\nwhile (i > 1);\n\n/*\n    Exercise\n*/\n\nfor (let i: number = 10; i < 56; i++) {\n    if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n        console.log(i)\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/kraltar.ts",
    "content": "// Tipos de operadores\n//Aritméticos\n\nlet numb1: number = 10;\nlet numb2: number = 2;\n//suma\nconsole.log( numb1 + numb2);\n//resta\nconsole.log( numb1 - numb2);\n//multiplicación\nconsole.log( numb1 * numb2);\n//división \nconsole.log( numb1 / numb2);\n//modular\nconsole.log(numb1 % numb2);\n\n//Lógicos\n\nlet a: boolean = true;\nlet b: boolean = false;\n\nconsole.log( a && b ); \nconsole.log( a || b ); \nconsole.log( !b ); \n\n//Asignacion\n\nconsole.log(numb1 += numb2);\nconsole.log(numb1 -= numb2);\nconsole.log(numb1 *= numb2);\nconsole.log(numb1 /= numb2);\nconsole.log(numb1 %= numb2);\n\n//Identidad\n\nconsole.log( numb1 === numb2);\nconsole.log( numb1 !== numb2);\n\n//comparacion\n\nconsole.log(numb1 == numb2);\nconsole.log(numb1 != numb2);\nconsole.log(numb1 < numb2);\nconsole.log(numb1 > numb2);\nconsole.log(numb1 <= numb2);\nconsole.log(numb1 >= numb2);\n\n// Bits\n\nconsole.log(numb1 & numb2);\nconsole.log(numb1 ^ numb2);\nconsole.log(~numb2);\nconsole.log(numb1 | numb2);\n\n\n\n//Etructuras de control\n//Ternarios\n\nlet height: number = 180;\nlet result: string = height >= 180 ? 'Eres muy alto' : 'Estas dentro de la media' \nconsole.log(result);\n\n\n\n//condicionales\n//switch\n\nlet fruitColor = 'morado'\nswitch(fruitColor) {\n    case \"rojo\":\n        console.log([\"manzana\", \"cereza\"]);\n        break;\n    case \"amarillo\":\n        console.log([\"platano\", \"piña\"]);\n        break;\n    case \"morado\":\n        console.log([\"mora\", \"uva\"]);\n        break;\n    default:\n        console.log(\"Color no reconocido\");\n}\n\n//if\nif(height < 180) {\n    console.log('Estas dentro de la media');\n    \n}\n//if/else\nif(height > 180) {\n    console.log('Eres muy alto');\n    \n} else {\n    console.log('Estas dentro de la media');\n    \n}\n// else if\nif(height < 180) {\n    console.log('Estas dentro de la media');\n    \n}else if (height < 150){\n    console.log('Eres bajito');\n}else {\n    console.log('Eres muy alto');\n    \n}\n\n//loops\n//ciclo for\n\nfor ( let i = 0; i < 10; i++ ){\n    console.log(i);\n}\n\n\n//while\nlet x = 0\nwhile (x < 10) {\n    console.log(x);\n    x++;\n    \n}\n\n//do/while\n\ndo {\n    console.log(x);\n    x++\n    \n} while (x < 10)\n\n\n//  DIFICULTAD EXTRA (opcional):\n// Crea un programa que imprima por consola todos los números comprendidos\n// entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\nlet i = 10\nfor (i = 10; i <= 55; i++){\n    if ( i % 2 === 0 && i !== 16 && i % 3 !== 0)\n        console.log(i);\n        \n}\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/llonardo798.ts",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n// Tipos de operadores en TypeaScript\n\n// 1. Operadores Aritméticos\nfunction operadoresAritmeticos() {\n    console.log(\"1. Operadores Aritméticos\");\n\n    let suma = 5 + 5;                                   // Operador de suma (+)\n    console.log(\"Suma: \" + suma);                       // 10\n\n    let resta = suma - 5;                               // Operador de resta (-)\n    console.log(\"Resta:\" + resta);                      // 5\n\n    let multiplicacion = suma * 5;                      // Operador de multiplicación (*)\n    console.log(\"Multiplicación: \" + multiplicacion);   // 50\n\n    let division = suma / 5                             // Operador de división (/)\n    console.log(\"División: \" + division);               // 2\n\n    let modulo = suma % 3;                              // Operador de módulo (%) - Módulo (resto o sobrante de la división) 10 % 3 = 1 se puede considerar como 10/3 = 3 y sobra 1\n    console.log(\"Modulo: \" + modulo);                   // 1\n\n    suma++;                                             // Operador de incremento (++)\n    console.log(\"Incremento: \" + suma);                 // 6\n\n    suma--;                                             // Operador de decremento (--)\n    console.log(\"Decremento: \" + suma);                 // 5\n\n    let exponenciacion = 2 ** 3;                        // Operador de exponenciación (**)\n    console.log(\"Exponenciación\" + exponenciacion);     // 8\n\n    // Ejemplo de uso de operadores aritméticos \n    let numero1 = 5;\n    let numero2 = 3;\n    let resultado = (((numero1 + numero2) * (numero1 - numero2)) / numero2) % numero2 + numero1++ - --numero2 + numero1 ** numero2\n    console.log(\"Uso de todos los operadores aritmeticos: \" + resultado);         // 41.333....\n}\n\noperadoresAritmeticos();\n\n\n\n// 2. Operadores Bit a Bit\nfunction operadoresBitBit() {\n    console.log(\"2. Operadores Bit a Bit\");\n\n    let operadorA = 60;  // 60 = 0011 1100\n    let operadorB = 13;  // 13 = 0000 1101\n    let operadorC = -10; // -10 = 1111 1111 1111 1111 1111 1111 1111 0110\n\n    let operadorAnd = operadorA & operadorB; // Operador de AND bit a bit (&)\n    console.log(\"AND: \" + operadorAnd);       // 12\n    // Explicación con binarios:\n    // 0011 1100 -> 60\n    // 0000 1101 -> 13\n    // ------------ & (AND)\n    // 0000 1100 -> 12\n\n    let operadorOr = operadorA | operadorB;   // Operador de OR bit a bit (|)\n    console.log(\"OR: \" + operadorOr);         // 61\n    // Explicación con binarios:\n    // 0011 1100 -> 60\n    // 0000 1101 -> 13\n    // ------------ | (OR)\n    // 0011 1101 -> 61\n\n    let operadorXor = operadorA ^ operadorB;  // Operador de XOR bit a bit (^)\n    console.log(\"XOR: \" + operadorXor);       // 49\n    // Explicación con binarios:\n    // 0011 1100 -> 60\n    // 0000 1101 -> 13\n    // ------------ ^ (XOR)\n    // 0011 0001 -> 49\n\n    let operadorNot = ~operadorA;             // Operador de NOT bit a bit (~)\n    console.log(\"NOT: \" + operadorNot);       // -61\n    // Explicación con binarios:\n    // 0011 1100 -> 60\n    // ------------ ~ (NOT)\n    // 1100 0011 -> -61\n\n    let operadorDesplazamientoIzquierda = operadorA << 2;           // Operador de desplazamiento a la izquierda (<<)\n    console.log(\"Desplazamiento a la izquierda: \" + operadorDesplazamientoIzquierda); // 240\n    // Explicación con binarios:\n    // 0011 1100 -> 60\n    // --------- << (Desplazamiento a la izquierda de 2 bits)\n    // 1111 0000 -> 240\n\n    let operadorDesplazamientoDerecha = operadorA >> 2;             // Operador de desplazamiento a la derecha (>>)\n    console.log(\"Desplazamiento a la derecha: \" + operadorDesplazamientoDerecha); // 15\n    // Explicación con binarios:\n    // 0011 1100 -> 60\n    // --------- >> (Desplazamiento a la derecha de 2 bits)\n    // 0000 1111 -> 15\n\n    let operadorDesplazamientoDerechaSinSigno = operadorC >>> 2;    // Operador de desplazamiento a la derecha sin signo (>>>)\n    console.log(\"Desplazamiento a la derecha sin signo: \" + operadorDesplazamientoDerechaSinSigno); // 1073741821\n    // Explicación con binarios:\n    // 1111 1111 1111 1111 1111 1111 1111 0110 -> -10\n    // --------- >>> (Desplazamiento a la derecha sin signo de 2 bits)\n    // 0011 1111 1111 1111 1111 1111 1111 1101 -> 1073741821\n}\n\noperadoresBitBit();\n\n\n\n// 3. Operadores de Asignación.\nfunction operadoresAsignacion() {\n    console.log(\"3. Operadores de Asignación\");\n\n    let asignacion = 5;                                         // Operador de asignación (=)\n    console.log(\"Asignación: \" + asignacion);                   // 5\n\n    asignacion += 5;                                            // Operador de suma y asignación (+=)\n    console.log(\"Suma y asignación: \" + asignacion);            // 10\n\n    asignacion -= 5;                                            // Operador de resta y asignación (-=)\n    console.log(\"Resta y asignación: \" + asignacion);           // 5\n\n    asignacion *= 5;                                            // Operador de multiplicación y asignación (*=)\n    console.log(\"Multiplicación y asignación: \" + asignacion);  // 25\n\n    asignacion /= 5;                                            // Operador de división y asignación (/=)\n    console.log(\"División y asignación\" + asignacion);          // 5\n\n    asignacion %= 3;                                            // Operador de módulo y asignación (%=)\n    console.log(\"Modulo y asignación: \" + asignacion);          // 2\n\n    asignacion **= 3;                                           // Operador de exponenciación y asignación (**=)\n    console.log(\"Exponenciación y asignación: \" + asignacion);  // 8\n\n    asignacion <<= 5;                                           // Operador de desplazamiento a la izquierda y asignación (<<=)\n    console.log(\"Desplazamiento a izquierda: \" + asignacion);   // 256\n    // Explicación con binarios:\n    // 0000 0000 1000 -> 8\n    // --------- <<= (Desplazamiento a la izquierda de 5 bits)\n    // 0001 0000 0000 -> 256\n\n    // let desplazamient = suma >> resta;\n\n    asignacion >>= 2;                                           // Operador de desplazamiento a la derecha y asignación (>>=)\n    console.log(\"Desplazamiento a derecha: \" + asignacion);      // 64\n    // Explicación con binarios:\n    // 0001 0000 0000 -> 256\n    // --------- >>= (Desplazamiento a la derecha de 2 bits)\n    // 0000 0100 0000 -> 64\n\n    // Operador de desplazamiento a la derecha sin signo y asignación (>>>=) desplaza los bits a la derecha \n    // sin importar si el numero es positivo o negativo para lo cual agrerga 0 a la izquierda\n    let a = -10;\n    a >>>= 2;                                                   // Operador de desplazamiento a la derecha sin signo y asignación (>>>=)\n    console.log(\"Despolazamient a derecha sin signo: \" + a);    // 1073741821\n    // Explicación con binarios:\n    // 1111 1111 1111 1111 1111 1111 1111 0110 -> -10\n    // --------- >>>= (Desplazamiento a la derecha sin signo de 2 bits)\n    // 0011 1111 1111 1111 1111 1111 1111 1101 -> 1073741821\n\n    let num1 = 60;\n    num1 &= 13;                                                         // Operador de AND bit a bit y asignación (&=)\n    console.log(\"Operador de AND bit a bit y asignación: \" + num1);     // 12\n    // Explicación con binarios:\n    // 0011 1100 -> 60\n    // 0000 1101 -> 13\n    // ------------ & (AND)\n    // 0000 1100 -> 12\n\n    num1 = 60;\n    num1 |= 13;                                                         // Operador de OR bit a bit y asignación (|=)\n    console.log(\"Operador de OR bit a bit y asignación: \" + num1);      // 61\n    // Explicación con binarios:\n    // 0011 1100 -> 60\n    // 0000 1101 -> 13\n    // ------------ | (OR)\n    // 0011 1101 -> 61\n\n    num1 = 60;\n    num1 ^= 13;                                                         // Operador de XOR bit a bit y asignación (^=)\n    console.log(\"Operador de XOR bit a bit y asignación\" + num1);       // 49\n    // Explicación con binarios:\n    // 0011 1100 -> 60\n    // 0000 1101 -> 13\n    // ------------ ^ (XOR)\n    // // 0011 0001 -> 49\n}\n\noperadoresAsignacion();\n\n\n\n// 4. Operadores de Comparación\nfunction operadoresComparacion() {\n    console.log(\"4. Operadores de Comparación\");\n\n    let comparacionIgual = 5 == 5;                                          // Operador de igualdad (==)\n    console.log(\"Igualdad: \" + comparacionIgual);                           // true\n\n    let comparacionEstrictamenteIgual = 5 === 5;                            // Operador de igualdad estricta (===), no solo compara el valor sino también el tipo de dato\n    console.log(\"Igualdad estricta: \" + comparacionEstrictamenteIgual);     // true\n\n    let comparacionDistinto = 5 != 5;                                       // Operador de distinto (!=)\n    console.log(\"Distinto: \" + comparacionDistinto);                        // false\n\n    let comparacionEstrictamenteDistinto = 5 !== 5;                         // Operador de distinto estricto (!==), no solo compara el valor sino también el tipo de dato\n    console.log(\"Distinto estricto: \" + comparacionEstrictamenteDistinto);  // false\n\n    let comparacionMayorQue = 5 > 3;                                        // Operador de mayor que (>)\n    console.log(\"Mayor que: \" + comparacionMayorQue);                       // true\n\n    let comparacionMenorQue = 5 < 3;                                        // Operador de menor que (<)\n    console.log(\"Menor que: \" + comparacionMenorQue);                       // false\n\n    let comparacionMayorIgualQue = 5 >= 5;                                  // Operador de mayor o igual que (>=)\n    console.log(\"Mayor o igual que: \" + comparacionMayorIgualQue);          // true\n\n    let comparacionMenorIgualQue = 5 <= 3;                                  // Operador de menor o igual que (<=)\n    console.log(\"Menor o igual que: \" + comparacionMenorIgualQue);          // false\n}\n\noperadoresComparacion();\n\n\n\n// 5. Operadores Lógicos\nfunction operadoresLogicos() {\n    console.log(\"5. Operadores Lógicos\");\n\n    let logicoAnd = true && false;                  // Operador AND lógico (&&) - Devuelve true si ambos operandos son true\n    console.log(\"AND lógico: \" + logicoAnd);        // false\n\n    let logicoOr = true || false;                   // Operador OR lógico (||) - Devuelve true si al menos uno de los operandos es true\n    console.log(\"OR lógico: \" + logicoOr);          // true\n\n    let logicoNot = !true;                          // Operador NOT lógico (!) - Devuelve true si el operando es false y viceversa\n    console.log(\"NOT lógico: \" + logicoNot);        // false\n\n    // Ejemplo de uso de operadores lógicos\n\n    let edad = 16;\n    let estaAcompanado = false;\n\n    let puedeVerPelicula = edad >= 18 || (edad >= 16 && estaAcompanado);\n    console.log(puedeVerPelicula);\n    // Cambiamos el valor de la variable estaAcompanado a valor contrario por diversión.\n    if (!puedeVerPelicula) {\n        console.log(\"Puedes ver la película\");\n    } else {\n        console.log(\"No puedes ver la película\");\n    }\n}\n\noperadoresLogicos();\n\n\n\n// 6. Operadores de Cadena\nfunction operadoresCadena() {\n    console.log(\"6. Operadores de Cadena\");\n\n    const num1 = 5;\n    const num2 = 27;\n    let cadena1 = \"Hola, la suma de: \" + num1 + \" y \" + num2 + \" es \" + (num1 + num2);          // Concatenación (+)\n    console.log(cadena1);                                                                       // Hola, la suma de: 5 y 5 es 10\n}\n\noperadoresCadena();\n\n\n\n// 7. Operador Condicional (Ternario)\nfunction operadorCondicional() {\n    console.log(\"7. Operador Condicional (Ternario)\");\n\n    let edad = 16;\n\n    let puedeVerPelicula2 = edad >= 18 ? \"Puede ver la película\" : \"No puede ver la película\";  // Operador condicional (Ternario)\n    console.log(puedeVerPelicula2);                                                             // No puede ver la película\n}\n\noperadorCondicional();\n\n\n\n// 8. Otros Operadores\n\ninterface Persona {\n    nombre: string;\n    edad?: number; // El signo de interrogación indica que el atributo es opcional\n}\n\nfunction otrosOperadores() {\n    console.log(\"8. Otros Operadores\");\n\n    // Se crea el objeto persona\n    let userLeonardo: Persona = {\n        nombre: \"Leonardo Aedo\",\n        edad: 25\n    }\n\n    let operadorTypeof = typeof userLeonardo;                           // Operador typeof - Devuelve el tipo de dato de una variable\n    console.log(\"Tipo de dato de suma: \" + operadorTypeof);             // object\n\n    let operadorDelete = delete userLeonardo.edad;                      // Operador delete - Elimina una propiedad de un objeto\n    console.log(\"Propiedad eliminada: \" + operadorDelete);              // true\n\n    let operadorIn = \"nombre\" in userLeonardo;                          // Operador in - Devuelve true si una propiedad existe en un objeto\n    console.log(\"Propiedad en el objeto: \" + operadorIn);               // true\n\n    let operadorInstanceOf = userLeonardo instanceof Object;            // Operador instanceof - Devuelve true si un objeto es una instancia de otro\n    console.log(\"Es una instancia de Object: \" + operadorInstanceOf);   // true\n\n    let operadorNew = new Date();                                       // Operador new - Crea una nueva instancia de un objeto\n    console.log(\"Nueva instancia de Date: \" + operadorNew);             // Fecha actual\n}\n\notrosOperadores();\n\n// DIFICULTAD EXTRA - Crea un programa que imprima por consola todos los números comprendidos entre 10 y 55 (incluidos)\n// pares, y que no son ni el 16 ni múltiplos de 3.\n\nfunction dificultadExtra() {\n    console.log(\"DIFICULTAD EXTRA\");\n\n    for (let i = 10; i < 56; i++) {\n        if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n            console.log(i);\n        }\n    }\n}\n\ndificultadExtra();\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/marcode24.ts",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n// Operadores aritméticos\nconst suma: number = 5 + 3;\nconst resta: number = 10 - 4;\nconst multiplicacion: number = 6 * 7;\nconst division: number = 20 / 4;\nconst modulo: number = 15 % 4;\n\nconsole.log('Operadores Aritméticos:');\nconsole.log('Suma:', suma);\nconsole.log('Resta:', resta);\nconsole.log('Multiplicación:', multiplicacion);\nconsole.log('División:', division);\nconsole.log('Módulo:', modulo);\n\n// Operadores lógicos\nconst and: boolean = true && false;\nconst or: boolean = true || false;\nconst not: boolean = !true;\n\nconsole.log('\\nOperadores Lógicos:');\nconsole.log('AND:', and);\nconsole.log('OR:', or);\nconsole.log('NOT:', not);\n\n// Operadores de comparación\n// eslint-disable-next-line eqeqeq\nconst igual: boolean = 5 == '5';\nconst estrictamenteIgual: boolean = 5 === '5';\nconst diferente: boolean = 10 !== 5;\nconst mayorQue: boolean = 15 > 10;\nconst menorQue: boolean = 7 < 12;\n\nconsole.log('\\nOperadores de Comparación:');\nconsole.log('Igual (==):', igual);\nconsole.log('Estrictamente Igual (===):', estrictamenteIgual);\nconsole.log('Diferente (!=):', diferente);\nconsole.log('Mayor Que (>):', mayorQue);\nconsole.log('Menor Que (<):', menorQue);\n\n// Operadores de asignación\nlet x: number = 10;\nx += 5; // equivalente a x = x + 5\nlet y: number = 20;\ny *= 2; // equivalente a y = y * 2\n\nconsole.log('\\nOperadores de Asignación:');\nconsole.log('x:', x);\nconsole.log('y:', y);\n\n// Operadores bitwise\nconst bitwiseAnd: number = 5 & 3; // AND\nconst bitwiseOr: number = 5 | 3; // OR\nconst bitwiseXor: number = 5 ^ 3; // XOR\nconst bitwiseNot: number = ~5; // NOT\nconst leftShift: number = 5 << 1; // Left Shift\nconst rightShift: number = 5 >> 1; // Right Shift\nconst zeroFillRightShift: number = 5 >>> 1; // Zero-fill Right Shift\n\nconsole.log('\\nOperadores Bitwise:');\nconsole.log('Bitwise AND (&):', bitwiseAnd);\nconsole.log('Bitwise OR (|):', bitwiseOr);\nconsole.log('Bitwise XOR (^):', bitwiseXor);\nconsole.log('Bitwise NOT (~):', bitwiseNot);\nconsole.log('Left Shift (<<):', leftShift);\nconsole.log('Right Shift (>>):', rightShift);\nconsole.log('Zero-fill Right Shift (>>>):', zeroFillRightShift);\n\n// Estructuras de control\n// Condicionales\nconst edad: number = 18;\nif (edad >= 18) {\n  console.log('\\nEres mayor de edad.');\n} else {\n  console.log('\\nEres menor de edad.');\n}\n\n// Iterativas\nconsole.log('\\nNúmeros entre 10 y 55 (pares, no 16 ni múltiplos de 3):');\nfor (let i: number = 10; i <= 55; i++) {\n  if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n    console.log(i);\n  }\n}\n\n// Excepciones\ntry {\n  throw new Error('Este es un ejemplo de excepción.');\n} catch (error) {\n  console.error('\\nExcepción:', (error as Error).message);\n}\n\n// Visita mi repo en GitHub para ver y correr los tests de este código --> https://github.com/marcode24/weekly-challenges\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/markc1234.ts",
    "content": "// EJERCICIO:\n// Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje: Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n// (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n// Utilizando las operaciones con operadores que tú quieras, crea ejemplos que representen todos los tipos de estructuras de control que existan en tu lenguaje:\n// Condicionales, iterativas, excepciones...\n// Debes hacer print por consola del resultado de todos los ejemplos.\n\n(() => {\n    // OPERADORES\n\n    // ARITMETICOS\n    // suma\n    console.log(10 + 10)\n    // resta\n    console.log(10 - 10)\n    // division\n    console.log(10 / 2)\n    // multiplicacion\n    console.log(25 * 4)\n    //modulo\n    console.log(4 % 3)\n    // potencia\n    console.log(2 ** 3)\n\n\n    // LÓGICOS\n    // and ( los dos deben ser true para que devuelva true de otra manera devolvera false)\n    console.log(true && false)\n    // or ( solamente es necesario que uno de las dos expresiones sea true para devolver true )\n    console.log(true || false)\n    // not ( negacion )\n    console.log(!true)\n\n\n    // DE COMPARACIÓN\n    // mayor que\n    console.log(10 > 9)     \n    // menor que\n    console.log(7 < 49)     \n    // mayor o igual que\n    console.log(6 >= 6)    \n    // menor o igual que\n    console.log(11 <= 12)    \n\n\n    // DE ASIGNACIÓN\n\n    // Suma y asignación\n    let suma: number = 8\n    suma += 2          \n    console.log(suma)\n\n    // Resta y asignación\n    let resta: number = 10\n    resta -= 9                \n    console.log(resta)      \n\n    // Multiplicación y asignación\n    let multiplicacion: number = 5\n    multiplicacion *= 5          \n    console.log(multiplicacion) \n\n    // División y asignación\n    let division: number = 100\n    division /= 10                \n    console.log(division)       \n\n    // Módulo y asignación\n    let modulo: number = 33\n    modulo %= 3                  \n    console.log(modulo)\n\n    // Potencia y asignación\n    let potencia: number = 2\n    potencia **= 8                    \n    console.log(potencia)\n\n\n    // DE PERTENENCIA\n\n    let arr: number[] = [12, 14, 16, 18, 20, 40, 60, 80, 100];\n    // 40 pertenece al conjunto \n    console.log(40 in arr);\n    // 11 pertenece al conjunto\n    console.log(99 in arr);\n\n    // ESTRUCTURA DE CONTROL:\n    let motivado: boolean = true\n    if(motivado) {\n        console.log(\"Estoy motivado\")\n    } else if(!motivado) {\n        console.log(\"No estoy motivado\")\n    } else {\n        console.log(\"Bloque inaccesible\")\n    }\n\n\n    // DIFICULTAD EXTRA (opcional):\n    // Crea un programa que imprima por consola todos los números comprendidos\n    // entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n    for (let index = 10; index <= 55; index++) {\n        if(index % 2 === 0 && index !== 16 && index % 3 !== 0) {\n            console.log(index)\n        }\n    }\n})()\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/martinbohorquez.ts",
    "content": "/*\n    Operadores aritméticos: actúan sobre números enteros y en punto flotante (decimales).\n    Hay dos tipos:\n        -- Operadores binarios.\n        -- Operadores unarios.\n    */\n\n/*\n    * Operadores unarios: aplican a un operando.\n    * Tipos:\n    *      -- Mantiene el signo del operando (+)\n    *      -- Cambia el signo del operando (-)\n    *      -- Autoincremento (++)\n    *      -- Autodecremento (--)\n    */\n\nlet a: number = 10;\n\nconsole.log(\"Operadores unarios: aplican a un operando.\");\n\nconsole.log(\"Mantiene el signo: \" + (+a));\nconsole.log(\"Cambia el signo: \" + (-a));\nconsole.log(\"Autoincremento e impresión: \" + (++a)); //Se incrementa y se imprime\nconsole.log(\"Impresión y autoincremento: \" + (a++)); //Se imprime y se incrementa\nconsole.log(\"Autodecremento e impresión: \" + (--a)); //Se decrementa y se imprime\nconsole.log(\"Impresión y autodecremento: \" + (a--)); //Se imprime y se decrementa\n\nconsole.log(\"\");\n\n/*\n    * Operadores binarios: aplican sobre dos operandos.\n    * Tipos:\n    *       -- Suma (+)\n    *       -- Resta (-)\n    *       -- Multiplicación (*)\n    *       -- División (/)\n    *       -- Módulo (%)\n    */\n\nconst b: number = 5;\nconst c: number = 2;\n\nconsole.log(\"Operadores binarios: aplican sobre dos operandos: \");\n\nconsole.log(\"Suma: \" + b + \" + \" +  c + \" = \" + (b + c));\nconsole.log(\"Resta: \" + b + \" - \" +  c + \" = \" + (b - c));\nconsole.log(\"Multiplicación: \" + b + \" * \" +  c + \" = \" + (b * c));\nconsole.log(\"División: \" + b + \" / \" +  c + \" = \" + (b / c));\nconsole.log(\"Módulo: \" + b + \" % \" +  c + \" = \" + (b % c));\n\nconsole.log(\"\");\n\n/*\n    * Operadores relacionales: para hacer comparaciones.\n    * Tipos:\n    *      -- Mayor que (>)\n    *      -- Mayor o igual que (>=)\n    *      -- Menor que (<)\n    *      -- Menor o igual que (<=)\n    *      -- Igual que (==)\n    *      -- Distinto de (!=)\n    */\n\nconst d: number = 20;\nconst e: number = 50;\n\nconsole.log(\"Operadores relacionales: para hacer comparaciones.\");\n\nconsole.log(\"¿20 es mayor que 50? : \" + (d > e));\nconsole.log(\"¿20 es mayor o igual que 50? : \" + (d >= e));\nconsole.log(\"¿20 es menor que 50? : \" + (d < e));\nconsole.log(\"¿20 es menor o igual que 50? : \" + (d <= e));\nconsole.log(\"¿20 es igual que 50? : \" + (d == e));\nconsole.log(\"¿20 es distinto de 50? : \" + (d != e));\n\nconsole.log(\"\");\n\n/*\n    * Operadores lógicos: Operan con valores lógicos para devolver nuevos valores lógicos.\n    * Tipos:\n    *      -- AND (&&): Evalúa si las dos expresiones son verdaderas.\n    *      -- OR (||): Evalúa si alguna de las expresiones es verdadera.\n    *      -- NOT (!): Cambia el valor de la variable lógica.\n    */\n\nconst v: boolean = true;\nconst f: boolean = false;\n\nconsole.log(\"Operadores lógicos: Operan con valores lógicos para devolver nuevos valores lógicos.\");\n\nconsole.log(\"¿true es igual a false? : \" + (v && f));\nconsole.log(\"¿true o false son verdaderas? : \" + (v || f));\nconsole.log(\"Cambiamos el valor de true : \" + (!v));\n\nconsole.log(\"\");\n\n/*\n    * Operador sobre cadenas de caracteres (+): Para concatenar cadenas de caracteres.\n    */\n\nconst text1: string = \"¡Hola, \"\nconst text2: string = \"TypeScript!\"\n\nconsole.log(\"Operador sobre cadenas de caracteres:\");\n\nconsole.log(text1 + text2);\n\nconsole.log(\"\");\n\n/*\n    * Operadores de asignación: Para asignar un valor a una variable.\n    * Tipos:\n    *      -- +=: Suma a la variable y sobrescribe el valor de la variable con el resultado.\n    *      -- -=: Resta a la variable y sobrescribe el valor de la variable con el resultado.\n    *      -- *=: Multiplica a la variable y sobrescribe el valor de la variable con el resultado.\n    *      -- /=: Divide a la variable y sobrescribe el valor de la variable con el resultado.\n    *      -- %=: Realiza el módulo a la variable y sobrescribe el valor de la variable con el resultado.\n    *      -- *=: Potencia a la variable y sobrescribe el valor de la variable con el resultado.\n    *      -- &&=: Realiza un AND lógico a la variable y sobrescribe el valor de la variable con el resultado.\n    *      -- ||=: Realiza un OR lógico a la variable y sobrescribe el valor de la variable con el resultado.\n    */\n\nlet i: number;\nlet t: boolean = true;\n\nconsole.log(\"Operadores de asignación: Para asignar un valor a una variable.\");\n\nconsole.log(\"Asignamos valor a la variable i = \" + (i = 2));\nconsole.log(\"Suma y asigna: \" + (i += 4));\nconsole.log(\"Resta y asigna: \" + (i -= 3));\nconsole.log(\"Multiplica y asigna: \" + (i *= 5));\nconsole.log(\"Divide y asigna: \" + (i /= 3));\nconsole.log(\"Módulo y asigna: \" + (i %= 3));\nconsole.log(\"Potencia y asigna: \" + (i **= 3));\nconsole.log(\"AND lógico y asigna: \" + (t &&= true));\nconsole.log(\"OR lógico y asigna: \" + (t ||= false));\n\nconsole.log(\"\");\n\n/*\n    * Operadores a nivel de bits: operan con cada bit del operando, ofreciendo un control más granular sobre los datos.\n    * Tipos:\n    *      -- AND (&): Operador AND a nivel de bits (1 y 1 = 1).\n    *      -- OR (|): Operador OR a nivel de bits (1 o 1 = 1).\n    *      -- XOR (^): Operador XOR a nivel de bits (1 y 1 = 0).\n    *      -- Complemento (~): Invierte el valor de cada bit.\n    *      -- >> : Desplaza bits a la derecha.\n    *      -- << : Desplaza bits a la izquierda.\n    *      -- >>> : Desplaza bits a la derecha sin signo.\n    */\n\nconst x: number = 10; // 1010\nconst y: number = 7; // 0111\n\nconsole.info(\"Operadores a nivel de bits: operan con cada bit del operando, ofreciendo un control más granular sobre los datos.\");\n\nconsole.log(\"x AND y : \" + (x & y));\nconsole.log(\"x OR y : \" + (x | y));\nconsole.log(\"x XOR y : \" + (x ^ y));\nconsole.log(\"Complemento de x = \" +  + ~x);\nconsole.log(\"Complemento de y = \" +  + ~y);\nconsole.log(\"Desplazamiento de bits de x a la izquierda de 2: \" + (x << 2)); \nconsole.log(\"Desplazamiento de bits de y a la derecha de 1: \" + (y >> 1)); \nconsole.log(\"Desplazamiento de bits de y a la derecha de 1 (sin signo): \" + (y >>> 1));\n\nconsole.log(\"\");\n\n/*\n    * Excepciones\n    * uso del try - catch\n    */ \ntry {\nthrow new Error('Este es un ejemplo de excepción.');\n} catch (error) {\nconsole.error('Excepción:', (error as Error).message);\n}\n\nconsole.log(\"\");\n\n\n/*\n    * Crea un programa que imprima por consola todos los números comprendidos\n    * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n    */\n\nconsole.log(\"DIFICULTAD EXTRA \\n\");\n\nconsole.log(\"Los números son: \");\n\nfor (let j: number = 10; j <= 55; j++) {\n    //Compruebo si son pares, distintos de 16 y no son múltiplos de 3\n    if (j % 2 == 0 && j != 16 && j % 3 != 0) {\n        console.log(j);\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/mendozalz.ts",
    "content": "/* \n# Ejercicios de Programación\n\n## Operadores\n\n- [X] Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n  - Aritméticos\n  - Lógicos\n  - De comparación\n  - Asignación\n  - Identidad\n  - Pertenencia\n  - Bits\n\n## Estructuras de Control\n\n- [] Utilizando las operaciones con operadores que tú quieras, crea ejemplos que representen todos los tipos de estructuras de control que existan en tu lenguaje:\n  - Condicionales\n  - Iterativas\n  - Excepciones\n- [] Debes hacer print por consola del resultado de todos los ejemplos.\n\n## Dificultad Extra (Opcional)\n\n- [] Crea un programa que imprima por consola todos los números comprendidos entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\n- [] Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo. \n*/\n\n\n// Operadores Aritméticos:\n\nvar a:number = 44;\nvar b:number = 15;\n// Suma (+)\nconsole.log(`La suma de a+b es ${a+b}`);\n\n// Resta (-)\nconsole.log(`La resta de a-b es ${a-b}`);\n\n// Multiplicación (*)\nconsole.log(`La multiplicación de a*b es ${a*b}`);\n\n// División (/)\nconsole.log(`La división entre a/b es ${a/b}`);\n\n// Módulo (%)\nconsole.log(`El modulo de a%b es ${a%b}`);\n\n// Incremento (++)\nconsole.log(`El incremento automatico de  a++ es ${a++}`);\n\n// Decremento (--)\nconsole.log(`El decremento automatico de  a- es ${a--}`);\n\n\n// Operadores de Comparación:\n\n// Igual (==)\nconsole.log(`Comparando igualdad a==b ${a==b}`);\n\n// No igual (!=)\nconsole.log(`Comparando desigualdad a!=b ${a!=b}`);\n\n// Estrictamente igual (===)\nconsole.log(`Comparación estricta a===b ${a===b}`);\n\n// Estrictamente no igual (!==)\nconsole.log(`Comparación estricta negada a!=b ${a!==b}`);\n\n// Mayor que (>)\nconsole.log(`Mayor que ${a>b}`);\n\n// Menor que (<)\nconsole.log(`Menor que ${a<b}`);\n\n// Mayor o igual que (>=)\nconsole.log(`Mayor igual que ${a>=b}`);\n\n// Menor o igual que (<=)\nconsole.log(`Menor igual que ${a<=b}`);\n\n\n// Operadores Lógicos:\n\n// AND lógico (&&)\nconsole.log(`Operador logico AND ${a&b}`);\n\n// OR lógico (||)\nconsole.log(`Operador logico OR ${a|b}`);\n\n// NOT lógico (!)\nconsole.log(`Operador logico NOT ${a!=b}`);\n\n\n// Operadores de Asignación:\nvar saldo:number= 0; \n// Asignación (=)\nconst nombre:string= \"Lenin Mendoza\";\nconsole.log(`El valor de nombre es ${nombre}`);\n\n\n// Suma y asignación (+=)\nsaldo += 44; \nconsole.log(`Suma asignada a la variable de saldo es ${saldo}`);\n\n// Resta y asignación (-=)\nsaldo -= 44; \nconsole.log(`Resta asignada a la variable de saldo es ${saldo}`);\n\n// Multiplicación y asignación (*=)\nsaldo *= 1.5; \nconsole.log(`Multiplicación asignada a la variable de saldo es ${saldo}`);\n\n// División y asignación (/=)\nsaldo /= 2; \nconsole.log(`División asignada a la variable de saldo es ${saldo}`);\n\n\n// Operadores de Bits:\nlet verdadero:number = 1;\nlet falso:number = 0;\n\n// AND a nivel de bits (&)\nconsole.log(`AND a nivel de Bits ${verdadero && falso}`);\n\n// OR a nivel de bits (|)\nconsole.log(`OR a nivel de Bits ${verdadero || falso}`);\n\n// XOR a nivel de bits (^)\nconsole.log(`XOR a nivel de Bits ${verdadero ^ falso}`);\n\n// Complemento a nivel de bits (~)\nconsole.log(`Complemento a nivel de Bits ${~ falso}`);\n\n// Desplazamiento a la izquierda (<<)\nconsole.log(`Desplazamiento a la izquierda a nivel de Bits ${verdadero << falso}`);\n\n// Desplazamiento a la derecha (>>)\nconsole.log(`Desplazamiento a la derecha a nivel de Bits ${verdadero >> falso}`);\n\n\n// Estructuras de Control\n\n// Condicionales\n\n// Estructura de control condicional donde se determina si un usuario es mayor o menor de edad para alguna acción\n\nconst usuario:string | null = prompt(\"Ingresa tu edad\", \"17\");\nconst edad:number = Number(usuario);\nconst mensaje:string = edad < 18 ? \"Eres menor de edad\" : \"Eres mayor de edad\";\nalert(mensaje);\n\n// Iterativas\n\nconst cero:number = 0;\nfor (let index = 0; index < 10; index++) {\n    const element = index;   \n}\n\n// Excepciones\n\nconst div:number = 4;\nconst divd:number = 0;\n\ntry {\n    console.log(div/divd);\n    \n} catch (error) {\n    console.log(`No se puede dividir entre cero, el error es de tipo = ${error}`);\n    \n}finally{\n    console.log(\"Mensaje de finalización\");\n    \n}\n\n// Crea un programa que imprima por consola todos los números comprendidos entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n\nfor(let i=0; i <= 55; i++){\n    if((i%2 == 0) && (i != 16) && (i%3 != 0)){\n        console.log(i);\n        \n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/miguelangelmz21.ts",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n// Operadores Aritméticos\nlet suma: number = 5 + 3;\nlet resta: number = 10 - 2;\nlet multiplicacion: number = 4 * 2;\nlet division: number = 20 / 4;\nlet modulo: number = 10 % 3;\nlet exponente: number = 2 ** 3;\nconsole.log(\"Suma:\", suma);\nconsole.log(\"Resta:\", resta);\nconsole.log(\"Multiplicación:\", multiplicacion);\nconsole.log(\"División:\", division);\nconsole.log(\"Módulo:\", modulo);\nconsole.log(\"Exponente:\", exponente);\n\n// Operadores de Comparación\nlet esIgual: boolean = (5 == 5); // Igualdad\nlet esDiferente: boolean = (5 != 3); // Desigualdad\nlet esMayor: boolean = (10 > 5); // Mayor que\nlet esMenor : boolean = (3 < 7); // Menor que     \nlet esMayorIgual: boolean = (5 >= 5); // Mayor o igual que\nlet esMenorIgual: boolean = (2 <= 3); // Menor o igual que\nconsole.log(\"Igualdad => 5 == 5:\", esIgual);\nconsole.log(\"Desigualdad => 5 != 3:\", esDiferente);\nconsole.log(\"Mayor que => 10 > 5:\", esMayor);\nconsole.log(\"Menor que => 3 < 7:\", esMenor);\nconsole.log(\"Mayor o igual que => 5 >= 5:\", esMayorIgual);\nconsole.log(\"Menor o igual que => 2 <= 3:\", esMenorIgual);\n\n// Operadores Lógicos\nlet logicoAnd: boolean = true && false; // Lógico AND\nlet logicoOr: boolean = true || false; // Lógico OR        \nconsole.log(\"Operador lógico AND => true && false:\", logicoAnd);\nconsole.log(\"Operador lógico OR => true || false:\", logicoOr);\n\n// Operadores de Asignación\nlet asignacion: number = 5; // Asignación\nconsole.log(\"Asignación:\", asignacion);\nasignacion %= 2; // Asignación con módulo\nconsole.log(\"Asignación con módulo y asignacion %= 2:\", asignacion);\nasignacion += 3; // Asignación con suma\nconsole.log(\"Asignación con suma y asignacion += 3:\", asignacion);\nasignacion **= 2; // Asignación con exponente\nconsole.log(\"Asignación con exponente y asignacion **= 2:\", asignacion);\n\n// Operadores de Identidad\nlet identidad: boolean = 5 === 5; // Identidad\nconsole.log(\"Identidad => 5 === 5:\", identidad);\nlet pertenencia: boolean = [1, 2, 3].includes(2); // Pertenencia\nconsole.log(\"Pertenencia => [1, 2, 3].includes(2):\", pertenencia);\n\n// Estructuras de control\nlet condicion: number = 10;\nif (condicion >= 5) {\n    console.log(`Condición cumplida: el número ${condicion} es mayor o igual que 5`);\n}   else {\n    console.log(`Condición no cumplida: el número ${condicion} no es mayor que 5`);\n}\n\n// Estructuras de control iterativas\nlet i: number = 5;\nconsole.log(`Iterando con FOR del 0 al ${i}:`);\nfor (i = 0; i <= 5; i++) {\n    console.log(\"Iteración:\", i);\n}\n\nconsole.log(`Iterando con WHILE mientras i sea mayor que 0:`);\nwhile (i > 0) {\n    console.log(\"Mientras i sea mayor que 0, i:\", i);  \n    i--;\n}\n\n// Manejo de excepciones\ntry {\n    let divisor = 0;\n    if (divisor === 0) {\n        throw new Error(\"División por cero no permitida\");\n    }\n    let resultado: number = 10 / divisor;\n    console.log(resultado);\n} catch (error) {\n    console.error(\"Error:\", error);\n}\n\n// DIFICULTAD EXTRA\nconsole.log(\"Números comprendidos entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3:\");\nfor (let i = 10; i <= 55; i++) {\n    if(i%2==0 && i%3 != 0){\n        if(i!=16)\n            console.log(i);        \n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/miguelex.ts",
    "content": "// Ejemplo de operadores aritméticos\n\n\nlet a: number = 10;\nlet b: number = 2;\nconsole.log(\"La suma es: \" + (a+b));\nconsole.log(\"La resta es: \" + (a-b));\nconsole.log(\"La multiplicación es: \" + (a*b));\nconsole.log(\"La división es: \" + (a/b));\nconsole.log(\"El resto es: \" + (a%b));\nconsole.log(\"El incremento es: \" + (++a));\nconsole.log(\"El decremento es: \" + (--b));\nconsole.log(\"El negativo es: \" + (-a));\n\n// Operadores de asignación\n\nconsole.log(\"La suma es: \" + (a+=b));\nconsole.log(\"La resta es: \" + (a-=b));\nconsole.log(\"La multiplicación es: \" + (a*=b));\nconsole.log(\"La división es: \" + (a/=b));\nconsole.log(\"El resto es: \" + (a%=b));\n\n// Operadores de comparación\n\nconsole.log(\"Igual: \" + (a==b));\nconsole.log(\"Identico: \" + (a===b));\nconsole.log(\"Distinto: \" + (a!=b));\nconsole.log(\"No identico: \" + (a!==b));\nconsole.log(\"Menor: \" + (a<b)); \nconsole.log(\"Mayor: \" + (a>b));\nconsole.log(\"Menor o igual: \" + (a<=b));\nconsole.log(\"Mayor o igual: \" + (a>=b));\n\n// Operadores lógicos\n\nconsole.log(\"AND: \" + (a<b && a>b));\nconsole.log(\"OR: \" + (a<b || a>b));\nconsole.log(\"NOT: \" + !(a<b));\n\n// Operadores nivel bit\n\nconsole.log(\"AND: \" + (a&b));\nconsole.log(\"OR: \" + (a|b));\nconsole.log(~a);     \nconsole.log(a << 1); \nconsole.log(a >> 1); \nconsole.log(b >>> 1)\n\n// Ejemplo bucle For\n\nfor (let i = 0; i < 10; i++) {\n    console.log(i);\n}\n\n// Ejemplo bubcle for in\n\nlet cadena:any = \"Hola mundo\";\nfor (let i in cadena) {\n    console.log(cadena[i]);\n}\n\n// Ejemplo bucle for of\n\nfor (let i of cadena) {\n    console.log(i);\n}\n\n// Ejemplo switch\n\nlet dia = 1;\n\nswitch (dia) {\n    case 1:\n        console.log(\"Lunes\");\n        break;\n    case 2:\n        console.log(\"Martes\");\n        break;\n    default:\n        console.log(\"Otro día\");\n        break;\n}\n\n// Ejemplo while\n\nlet i = 0;\n\nwhile (i < 10) {\n    console.log(i);\n    i++;\n}\n\n// Ejemplo do while\n\nlet j = 0;\n\ndo {\n    console.log(j);\n    j++;\n} while (j < 10);\n\n// Manejo de excepciones\n\ntry {\n    let x = 10;\n    let y = 0;\n    if (y == 0) {\n        throw(\"División por cero\");\n    }\n    let z = x / y;\n    console.log(z);\n} catch (error) {\n    console.log(error);\n} finally {\n    console.log(\"Terminado\");\n}\n\n// Ejercicio extra\n\nfunction ejercicioExtra(): any {\n    for (let i = 10; i <= 55; i++) {\n        if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n            console.log(i);\n        }\n    }\n}\n\nejercicioExtra();\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/mikelroset.ts",
    "content": "// ------------------------- OPERADORES ARITMÉTICOS ------------------------- //\n\n// Suma\t\nlet sum: number = 5 + 2 // 7\n\n// Resta\nlet rest: number = 5 - 2 // 3\n\n// Multiplicación\nlet mult: number = 5 * 2 // 10\n\n// División\nlet div: number = 5 / 2 // 2.5\n\n// Módulo (resto)\nlet mod: number = 5 % 2 // 1\n\n// Exponenciación\nlet exp: number = 5 ** 2 // 25\n\n// Incremento\nlet x: number = 5; \nx++ // x es 6\n\n// Decremento\nlet y: number = 5;\ny-- // y es 4\n\n\n// ------------------------ OPERADORES DE ASIGNACIÓN ------------------------ //\n\n// Asignación\nlet z: number = 5;\n\n// Asignación de suma\nz += 5 // z = z + 5\n\n// Asignación de resta\nz -= 5 // z = z - 5\n\n// Asignación de multiplicación\nz *= 5 // z = z * 5\n\n// Asignación de división\nz /= 5 // z = z / 5\n\n// Asignación de módulo\nz %= 5 // z = z % 5\n\n// Asignación de exponenciación\nz **= 5 // z = z ** 5\n\n\n// ------------------------- OPERADORES DE COMPARACIÓN ---------------------- //\n\n// ==\tIgual a\nlet val1: number = 5;\nlet val2: string = '5';\nval1 == val2 // true\n\n// ===\tEstrictamente igual a\nval1 === val2 // false\n\n// !=\tNo igual a\nval1 != val2 // false\n\n// !==\tEstrictamente no igual a\nval1 !== val2 // true\n\n// >\tMayor que\n5 > 2 // true\n\n// <\tMenor que\n5 < 2 // false\n\n// >=\tMayor o igual que\n5 >= 5 // true\n\n// <=\tMenor o igual que\n5 <= 5 // true\n\n\n// -------------------------- OPERADORES LÓGICOS ---------------------------- //\n\n// AND\nlet a: boolean = true;\nlet b: boolean = false;\nlet c: boolean = a && b; // false\n\n// OR\nlet d: boolean = true;\nlet e: boolean = false;\nlet f: boolean = d || e; // true\n\n// NOT\nlet g: boolean = true;\nlet h: boolean = !g; // false\n\n\n// -------------------------- OPERADORES DE BITS ---------------------------- //\n\n// AND\nlet i: number = 5; // 0101\nlet j: number = 3; // 0011\nlet k: number = i & j; // 0001\n\n// OR\nlet l: number = 5; // 0101\nlet m: number = 3; // 0011\nlet n: number = l | m; // 0111\n\n// XOR\nlet o: number = 5; // 0101\nlet p: number = 3; // 0011\nlet q: number = o ^ p; // 0110\n\n// Complemento\nlet r: number = 5; // 0101\nlet s: number = ~r; // 1010\n\n// Desplazamiento a la izquierda\nlet t: number = 5; // 0101\nlet u: number = t << 1; // 1010\n\n// Desplazamiento a la derecha\nlet v: number = 5; // 0101\nlet w: number = v >> 1; // 0010\n\n// Desplazamiento a la derecha sin signo\nlet x2: number = 5; // 0101\nlet y2: number = x2 >>> 1; // 0100\n\n\n// ------------------------- OPERADORES DE CADENAS -------------------------- //\n\n// Concatenación de cadenas\nlet a3: string = \"Hello\";\nlet b3: string = \"World\";\nlet c3: string = a3 + b3; // HelloWorld\n\n// Concatenación y asignación\nlet d3: string = a3;\nd3 += b3; // HelloWorld\n\n\n// -------------------------- OPERADORES TERNARIOS -------------------------- //\n\n// Condicional\nlet z2: boolean = true;\nlet a2: number = z2 ? 5 : 10; // 5\n\n// Condicional con ternario\nlet b2: number = z2 ? 5 : 10; // 5\n\n\n// -------------------- OPERADORES DE DESESTRUCTURACIÓN --------------------- //\n\n// ... Spread o Rest\nlet [a4, b4]: [number, number] = [1, 2];\nlet otherObj: object = { name: \"John\", age: 25 };\nlet obj: object = { ...otherObj };\n\n\n// ------------------------ OPERADORES DE TIPO TYPEOF ----------------------- //\n\n// typeof\ntypeof 5 // number\n\n\n// ------------------------ OPERADORES DE ELIMINACIÓN ----------------------- //\n\n// delete\ntype Person = {\n  name?: string;\n  age: number;\n};\nlet obj2: Person = { name: \"John\", age: 25 };\ndelete obj2.name; // Elimina el nombre de la variable 'obj'\n\n\n// ----------------------- OPERADORES DE INSTANCIA -------------------------- //\n\n// instanceof\nclass Person2 {\n  name: string;\n  age: number;\n}\nobj2 instanceof Person2 // true\n\n\n// ----------------------- OPERADORES DE INCLUSIÓN -------------------------- //\n\n// in\nlet a5: object = { message: \"Hello World\" };\n\"message\" in a5; // true\n\n\n// --------------- OPERADORES DE ENCADENAMIENTO OPCIONAL -------------------- //\n\n// ?.\ntype Person3 = {\n  personalInfo?: {\n    name: string;\n    age: number;\n  };\n};\nlet obj3: Person3 = { personalInfo: { name: \"John\", age: 25 } };\nobj3?.personalInfo?.name // undefined si obj3 o personalInfo no existen\n\n\n// ------------------ OPERADORES DE COALESCENCIA NULA ----------------------- //\n\n// ?? (Devuelve el valor de la derecha si el valor izquierdo es null)\nnull ?? \"John\" // John\n\n\n// ------------------------ OPERADORES SATISFIES ---------------------------- //\n\n// satisfies\ntype Config = {\n  url: string;\n  port: number;\n};\n// config sigue teniendo la prop. \"protocol\", aunque satisface el tipo \"Config\"\nconst config = {\n  url: \"https://example.com\",\n  port: 8080,\n  protocol: \"https\",\n} satisfies Config;\n\n\n// ------------------ OPERADORES DE ASIGNACIÓN LÓGICA ----------------------- //\n\n// &&=\nlet a6: boolean = true;\nlet b6: boolean = false;\na6 &&= b6; // false\n\n// ||=\nlet c6: boolean = true;\nlet d6:  = false;\nc6 ||= d6; // true\n\n// ??=\nlet e6: string | null = null;\nlet f6 = \"John\";\ne6 ??= f6; // \"John\"\n\n\n// ----------------------------- OPERADOR VOID ------------------------------ //\n\n// void\nfunction someFunction(): void {\n  console.log(\"Hello World\");\n}\nvoid someFunction(); // Ejecuta la función pero ignora su valor de retorno\n\n\n// --------------------- OPERADOR DE MÓDULOS DINÁMICOS ---------------------- //\n\n/*\n * import\n * Se utiliza para importar módulos de forma dinámica. Aunque no es un operador\n * estándar, actúa como tal para cargar módulos bajo demanda\n*/\nimport { add } from \"./math\";\nadd(5, 5); // 10\n\n\n// ----------------------------- OPERADOR NEW ------------------------------- //\n\n// new\nlet date = new Date(); // Crea una nueva instancia del objeto Date\n\n\n// ---------------------------- OPERADOR SUPER ----------------------------- -//\n\n// super\nclass Animal {\n  constructor(public name: string) {}\n}\n\nclass Dog extends Animal {\n  constructor(name: string) {\n    super(name); // Llama al constructor de la clase padre\n  }\n}\n\n\n// --------------------------- OPERADOR THIS -------------------------------- //\n\n// this\nclass MyClass {\n  constructor(public name: string) {}\n\n  sayHello() {\n    console.log(`Hello, ${this.name}`);\n  }\n}\n\nlet obj5 = new MyClass('TypeScript');\nobj5.sayHello(); // \"Hello, TypeScript\"\n\n\n// ---------------------- ESTRUCTURAS CONDICIONALES ------------------------- //\n\n// if, else if, else\nconst age: number = 25;\n\nif (age < 18) {\n  console.log(\"You are a child\");\n} else if (age >= 18 && age < 65) {\n  console.log(\"You are an adult\");\n} else {\n  console.log(\"You are a senior citizen\");\n}\n\n// switch\nconst fruit: string = \"banana\";\n\nswitch (fruit) {\n  case \"apple\":\n    console.log(\"Es una manzana\");\n    break;\n  case \"banana\":\n    console.log(\"Es un plátano\");\n    break;\n  default:\n    console.log(\"Fruta desconocida\");\n}\n\n\n// ---------------------- ESTRUCTURAS ITERACIONES --------------------------- //\n\n// for\nfor (let i: number = 0; i < 5; i++) {\n  console.log(i);\n}\n\n// for...of\nfor (const fruit of [\"apple\", \"banana\", \"orange\"]) {\n  console.log(fruit);\n}\n\n// for...in\nlet obj6: object = { name: \"John\", age: 25 };\nfor (const key in obj6) {\n  console.log(`${key}: ${obj6[key]}`);\n}\n\n// while\nlet j: number = 0;\nwhile (j < 5) {\n  console.log(j);\n  j++;\n}\n\n// do...while\nlet k: number = 0;\ndo {\n  console.log(k);\n  k++;\n} while (k < 5);\n\n\n// ----------------- ESTRUCTURAS DE CONTROL DE ITERACIÓN -------------------- //\n\n// break\nfor (let i: number = 0; i < 5; i++) {\n  if (i === 3) {\n    break;\n  }\n  console.log(i);\n}\n\n// continue\nfor (let i: number = 0; i < 5; i++) {\n  if (i === 2) {\n    continue;\n  }\n  console.log(i);\n}\n\n// return\nfunction add(a: number, b: number): number {\n  return a + b;\n}\n\nadd(5, 5); // 10\n\n\n// ------------------ ESTRUCTURAS DE CONTROL DE EXCEPCIONES ---------------- //\n\n// try...catch...finally\ntry {\n  throw new Error(\"Something went wrong\");\n} catch (error) {\n  console.log(error.message);\n} finally {\n  console.log(\"Finally block\");\n}\n\n// throw\nfunction throwError(): never {\n  throw new Error(\"Something went wrong\");\n}\n\n\n// ---------------------- ESTRUCTURAS DE CONTROL DE ASYNC ------------------- //\n\n// async await\nasync function fetchData() {\n  try {\n    const response = await fetch(\"https://api.example.com/data\");\n    const data = await response.json();\n    console.log(data);\n  } catch (error) {\n    console.error(\"Error al obtener los datos:\", error);\n  }\n}\n\nfetchData();\n\n// Promise.then().catch().finally()\nfetch(\"https://api.example.com/data\")\n  .then(response => response.json())\n  .then(data => console.log(data))\n  .catch(error => console.error(\"Error:\", error))\n  .finally(() => console.log(\"Proceso terminado\"));\n\n\n// -------------------------- BONUS EJERCICIO ------------------------------- //\n\n/*\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3\n*/\nconst conf = {\n  MULTIPLE_OF_X: 3,\n  EXCLUDED_NUMBER: 16,\n  MIN: 10,\n  MAX: 55\n};\n\n/**\n * Verifica si un número es par\n * @param num - Número a verificar\n * @returns true si el número es par\n */\nfunction isEven(num: number): boolean {\n  return num % 2 === 0;\n}\n\n/**\n * Verifica si un número no es el número excluido (conf.EXCLUDED_NUMBER)\n * @param num - Número a verificar\n * @returns true si el número no es conf.EXCLUDED_NUMBER\n */\nfunction isNotExcludedNumber(num: number): boolean {\n  return num !== conf.EXCLUDED_NUMBER;\n}\n\n/**\n * Verifica si un número no es múltiplo de un valor dado\n * @param num - Número a verificar\n * @param divisor - Valor divisor\n * @returns true si el número no es múltiplo del divisor\n */\nfunction isNotMultipleOf(num: number, divisor: number): boolean {\n  return num % divisor !== 0;\n}\n\n/**\n * Verifica si un número es par, no es conf.EXCLUDED_NUMBER y no es múltiplo de\n * conf.MULTIPLE_OF_X\n * @param num - Número a verificar\n * @returns true si el número cumple todas las condiciones\n */\nfunction isEvenAndValid(num: number): boolean {\n  return isEven(num) \n    && isNotExcludedNumber(num) \n    && isNotMultipleOf(num, conf.MULTIPLE_OF_X);\n}\n\n// Recorremos el rango y mostramos solo los números que cumplen las condiciones\nfor (let i = conf.MIN; i <= conf.MAX; i++) {\n  if (isEvenAndValid(i)) {\n    console.log(i);\n  }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/mxtrar23.ts",
    "content": "\n// Operadores Arifméticos\nlet n = 10\nlet m = 3\n\nconsole.log(`Suma: ${n}+${m}: ${n+m}`)\nconsole.log(`Resta: ${n}-${m}: ${n-m}`)\nconsole.log(`Multiplicacion: ${n}*${m}: ${n*m}`)\nconsole.log(`Division: ${n}/${m}: ${n/m}`)\nconsole.log(`Módulo: ${n}%${m}: ${n%m}`)\n\n// Operadores Incremento y Decremento\nlet k = 5\nlet l = 10\nconsole.log(`Incremento : ${k++}++: ${k}`)\nconsole.log(`Decremento : ${l++}--: ${l}`)\n\n// Operadores de asignación\nlet x = 3;\nlet y = 4;\nconsole.log(`Adicion: x=${x}; x+=${y}: ${x+=y}`)\n\nx = 6;\ny = 3;\nconsole.log(`Resta: x=${x}; x-=${y}: ${x-=y}`)\n\nx = 2;\ny = 3;\nconsole.log(`Multiplicacion: x=${x}; x-*${y}: ${x*=y}`)\n\nx = 10;\ny = 5;\nconsole.log(`Division: x=${x}; x-*${y}: ${x*=y}`)\nconsole.log('====================================================');\n\n\n//Operadoes Comparación\nlet i = 5\nconsole.log(`Igual estricto: ${i}===${i}: ${i===i}`)\nconsole.log(`No Igual estricto: ${i}!==${i}: ${i!==i}`)\nconsole.log(`Menor Igual que: ${i}<=${i}: ${i<=i}`)\nconsole.log(`Mayor Igual que: ${i}>=${i}: ${i>=i}`)\nconsole.log(`Menor que: ${i}<${i}: ${i<i}`)\nconsole.log(`Mayor que: ${i}>${i}: ${i>i}`)\nconsole.log('====================================================');\n\n// Condicionales\n\nlet diaParaProgramar = true;\n\nif (diaParaProgramar) {\n  console.log(\"¡Siii! Mi momento para mostrar mis habilidades ha llegado\");\n} else {\n  console.log(\"No hay problema, hay que mantener la esperanza\");\n}\nconsole.log('====================================================');\n\n// Iterativas\n\nfor (let index = 0; index < 10; index++) {\n  console.log(`For: ${index}`);\n}\nconsole.log('====================================================');\n\nlet index = 0;\nwhile (index<=10) {\n  console.log(`While: ${index++}`);\n}\nconsole.log('====================================================');\n\n//Manejo de Exepciones\ntry {\n  for (let i = 0; i < 10; i++) {\n    if (i<3) {\n      console.log(i);\n    } else {\n      throw new Error('No es valido para i < 3')\n    }\n  }\n} catch (error) {\n  console.log('ERROR',error.message);\n}\n\nconsole.log('====================================================');\nconsole.log('============== DIFICULTAD EXTRA ======================');\n  for (let num = 10; num <= 55; num++) {\n    if (num%2==0 && num != 16 && num%3!=0) console.log(num)\n  }\nconsole.log('====================================================');\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/nathanaellara.ts",
    "content": "/*\nArithmetic operators\nThese operators are used to perform mathematical operations\nbetween variables and/or values.\n*/\n\n/*\nlet a = 10;\nlet b = 2;\n\nconsole.log(a + b); // 12 (Sum)\nconsole.log(a - b); // 8 (Substraction)\nconsole.log(a * b); // 20 (Multiplication)\nconsole.log(a / b); // 5 (Division)\nconsole.log(a % b); // 0 (Module: remainder of the division)\nconsole.log(a ** b); // 100 (Elevar a una potencia - Raise to a power)\n*/\n\n/*\nAssignment Operators\nAssignment operators are used to assign values ​​to variables.\n*/\n\n/*\nlet a = 10;\na += 2; // is equal to a = a + 2\nconsole.log(a); // 12\n\nlet b = 10;\nb -= 2; // is equal to b = b - 2\nconsole.log(b) // 8\n\nlet c = 10;\nc *= 2; // is equal to c = c * 2\nconsole.log(c); // 20\n\nlet d = 10;\nd /= 2; // is equal to d = d / 2\nconsole.log(d) // 5\n\nlet e = 10\ne %= 2; // is equal to e = e % 2\nconsole.log(e) // 0\n*/\n\n/*\nComparison Operators\nComparison operators are used to compare two values.\n\nIn TypeScript, the operators == and === are used for equality comparison,\nbut there is an important difference between them.\n\nThe == operator checks values ​​for equality, but allows automatic type conversion.\nThis means that if two values ​​of different types are compared that can be considered equivalent, == will return true. For example,\n2 == \"2\" will return true, even though the first is a number and the second is a string.\n\nIn contrast, the === operator checks both the equality of values ​​and the type.\nIt does not allow type conversion, so if you compare two values ​​of different\ntypes, === will return false, even if the values ​​are equivalent from a type conversion\nstandpoint. For example, 2 === \"2\" will return false, because\none is a number and the other is a text string.\n*/\n\n/*\nlet a = 10;\nlet b = 2;\n\nconsole.log(a == b); // Equality (compares values, allows type conversion)\nconsole.log(a === b); // Strict equality (compares values ​​and types)\nconsole.log(a != b); // Different (compares values, allows type conversion)\nconsole.log(a !== b); // Strict Different (compares values ​​and types)\nconsole.log(a > b); // Mayor que\nconsole.log(a < b); // Less than\nconsole.log(a >= b); // Greater than or equal to\nconsole.log(a <= b); // Less than or equal to\n*/\n\n/*\nLogical Operators\nLogical operators are used to combine conditions\n*/\n\n/*\nlet a = true;\nlet b = false;\n\nconsole.log(a && b); // false (AND: true if all conditions are true)\nconsole.log(a || b); // true (OR: true at least if one condition is true)\nconsole.log(!a); // false (NOT: reverses the condition)\n*/\n\n/*\nBitwise Operators\nBitwise operators operate at the bit level of numbers.\n*/\n\n/*\nlet a = 5; // in binary 0101\nlet b = 3; // in binary 0011\n\nconsole.log(a & b); // 1, in binary 0001\nconsole.log(a | b); // 7, in binary 0111\nconsole.log(a ^ b); // 6, in binary 0110\nconsole.log(~a); // -6, It is the two's complement\nconsole.log(a << 1); // 10, moves to the left 1 bit\nconsole.log(a >> 1); // 2, moves to the right 1 bit\n\n*/\n\n/*\nConditional (ternary) operator\nThis operator is used to assign a value to a variable based on a\ncondition.\n*/\n\n/*\nlet age : number = 18;\nlet canDrive: string = age ? 'Yes' : 'No';\nconsole.log(canDrive); //Yes\n*/\n\n/*\ntypeof operator\nThis operator is used to obtain the type of a variable or a value.\n*/\n\n/*\nlet a = 10;\nconsole.log(typeof a); // number\n*/\n\n/*\ninstanceof operator\nUsed to check if an object is an instance of a specific class\n*/\n\n/*\nclass Person{\n    constructor(public name: string) {}\n}\n\nconst jhon = new Person('Jhon');\n\nconsole.log(jhon instanceof Person); // true\nconsole.log(jhon instanceof Object); // true (since all classes inherit from Object)\nconsole.log(jhon instanceof Array); // false\n*/\n\n/*\nProperty Access Operators\nTypeScript supports property access operators\n*/\n\n// Access with point (.)\n\n/*\n\nclass Person {\n    name: string;\n    age: number;\n\n    constructor(name: string, age: number) {\n        this.name = name;\n        this.age = age;\n    }\n}\n\nconst person = new Person(\"Jhon\", 30);\n\nconsole.log(person.name); // \"Jhon\"\nconsole.log(person.age); // 30\n\n*/\n\n/*\nAccess with brackets (corchetes)\n\nThis operator is useful when the property name is dynamic (i.e., it is\nlocated in a variable) or when the property name is not a valid identifier (for\nexample, it has spaces or special characters).\n*/\n\n\n/*\nconst person = {\n  name: \"Jhon\",\n  age: 30,\n  \"full name\": \"Jhon Pérez\"\n};\n\nconst property = \"age\";\n\nconsole.log(person[\"name\"]); // \"Jhon\"\nconsole.log(person[\"full name\"]); // \"Jhon Pérez\"\nconsole.log(person[property]); // 30\n*/\n\n/*\n\nOptional chaining operator (?.)\n\nThe optional chaining operator was introduced in TypeScript 3.7 and allows you to safely access\nthe properties of an object without raising an error if the object is null\nor undefined. If the property does not exist or the object is null or undefined, instead of\nraising an error, undefined is returned.\n\ninterface Person {\n    name?: string;\n    address?: {\n      street?: string;\n    };\n  }\n  \n  const person: Person = {};\n  \n  console.log(person.name?.toUpperCase()); // undefined\n  console.log(person.address?.street?.toUpperCase()); // undefined\n\n*/\n\n/*\nNullish chaining operator (??)\n\nAlthough not a property access operator in the strict sense, the ?? operator\ncan be combined with other access operators to handle cases where a property\nmay be null or undefined. It returns the value on the right only if the value on the\nleft is null or undefined.\n\n\ninterface Person {\n  name?: string | null;\n}\n\nconst person: Person = { name: null };\n\nconsole.log(person.name ?? \"Unknown name\"); // \"Unknown name\"\n\n*/\n\n/*\nFunction Call Operator ()\nThis operator is used to call a function.\n\n\nfunction myFunction() {\n    console.log('¡Hello World!');\n  }\n  \n  myFunction();  // '¡Hello World!'\n  \n\n  function sum(a: number, b: number): number {\n    return a + b;\n  }\n  \n  console.log(sum(3, 4));  // 7\n  \n*/\n\n/*\nNew Instance Operator new\nThe new operator in TypeScript (and JavaScript) is used to create a new instance\nof a class. When this operator is used, the class constructor is called, which\ninitializes a new object with the properties and methods defined in the class.\n\n\n\nclass Person {\n    name: string;\n    age: number;\n  \n    constructor(name: string, age: number) {\n      this.name = name;\n      this.age = age;\n    }\n  \n    greet() {\n      return `Hello, my name is ${this.name} and I am ${this.age} years old.`;\n    }\n  }\n  \n  const person1 = new Person(\"Jhon\", 30);\n  console.log(person1.greet());  // \"Hello, my name is Jhon and I am 30 years old.\"\n  \n\n*/\n\n/*\n\n1. Conditional Control Structures\nThey are used to execute code\ndepending on a condition.\n\nlet age: number = 18;\n\nif (age >= 18) {\n  console.log(\"You are of legal age.\");\n} else {\n  console.log(\"You are a minor\")\n}\n\n\nlet day: number = 3;\n\nswitch (day) {\n  case 1:\n    console.log(\"Monday\");\n    break;\n  case 2:\n    console.log(\"Tuesday\");\n    break;\n  default:\n    console.log(\"Another day\");\n}\n\n\n2. Loop Control Structures (Iterative)\nThey are used to repeat a series of instructions.\n\n\n\nfor (let i = 0; i < 5; i++) {\n  console.log(i);\n}\n\n\nlet counter: number = 0; \n\nwhile (counter < 5) {\n  console.log(counter);\n  counter++;\n}\n\nlet num: number = 0;\n\ndo {\n  console.log(num);\n  num++;\n} while (num < 5);\n\n// for...of (to iterate over arrays, strings, etc.)\n\nlet numbers: number[] = [1, 2, 3, 4];\n\nfor (let num of numbers) {\n  console.log(num);\n}\n\n\n\n// for in... to iterate over properties of an object\n\nlet person = { name: \"Jhon\", age: 25 };\n\nfor (let key in person) {\n  console.log(`${key}: ${person[key as keyof typeof person]}`);\n}\n\n\n3. Jump Control Structures\nThey allow the normal flow of\nexecution to be modified.\n\nbreak (breaks out of a loop o switch)\n\nfor (let i = 0; i < 10; i++) {\n  if (i === 5) {\n    break; // loop ends\n  }\n  console.log(i);\n}\n\ncontinue (skip the current iteration and go to the next one)\n\nfor (let i = 0; i < 5; i++) {\n  if (i === 2) {\n    continue; // Jump this iteration\n  }\n  console.log(i);\n}\n\nreturn (exits a function and returns a value)\n\nfunction sum(a: number, b: number): number {\n  return a + b; // Ends the function and returns a result\n\n\n// throw (throws an error)\n\nfunction validateAge(age: number) {\n  if (age < 18) {\n    throw new Error(\"You must be legal of age.\");\n  }\n  return \"Access allowed\";\n}\n\ntry {\n  console.log(validateAge(19)); // change the number to test\n} catch (error) {\n  console.error(error.message);\n}\n\n\n*/\n\nfor (let i = 10; i < 55; i++) {\n  if (i % 2 == 0 && i != 16 && i % 3 != 0)\n  console.log(i);\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/nlarrea.ts",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n// OPERADORES ARITMÉTICOS\n\nconsole.log(3 + 4)     // Suma -> 7\nconsole.log(3 - 4)     // Resta -> -1\nconsole.log(3 / 4)     // División -> 0.75\nconsole.log(3 * 4)     // Multiplicación -> 12\nconsole.log(3 % 4)     // Módulo -> 3\nconsole.log(3 ** 4)    // Potencia -> 81\n\n\n// OPERADORES LÓGICOS\n\nconsole.log(true && false)     // AND -> false\nconsole.log(true || false)     // OR -> true\nconsole.log(!true)             // NOT -> false\n\n\n// OPERADORES DE COMPARACIÓN\n\nconsole.log(3 > 4)     // Mayor que -> false\nconsole.log(3 < 4)     // Menor que -> true\nconsole.log(3 >= 4)    // Mayor o igual que -> false\nconsole.log(3 <= 4)    // Menor o igual que -> true\n\n\n// OPERADORES DE ASIGNACIÓN\n\nlet assignSum: number = 7\nassignSum += 3                     // Suma y asignación\nconsole.log(assignSum)             // 10\n\nlet assignSubtract: number = 7\nassignSubtract -= 4                // Resta y asignación\nconsole.log(assignSubtract)        // 3\n\nlet assignMultiplication: number = 7\nassignMultiplication *= 2          // Multiplicación y asignación\nconsole.log(assignMultiplication)  // 14\n\nlet assignDivision: number = 7\nassignDivision /= 2                // División y asignación\nconsole.log(assignDivision)        // 3.5\n\nlet assignModule: number = 7\nassignModule %= 2                  // Módulo y asignación\nconsole.log(assignModule)          // 1\n\nlet assignPow: number = 7\nassignPow **= 2                    // Potencia y asignación\nconsole.log(assignPow)             // 49\n\n\n// OPERADORES DE PERTENENCIA\n\nlet arr: number[] = [0, 1, 2, 3, 4];\nconsole.log(3 in arr);      // true\nconsole.log(11 in arr);     // false\n\n\n// OPERADORES DE BITS\n\nconsole.log(3 & 4);         // AND -> 0\nconsole.log(3 | 4);         // OR -> 7\nconsole.log(3 ^ 4);         // XOR -> 7\nconsole.log(~3);            // NOT -> -4\nconsole.log(3 << 4);        // Desplazamiento a izquierda -> 48\nconsole.log(3 >> 4);        // Desplazamiento a derecha -> 0\n\n\n// ESTRUCTURA DE CONTROL: if - else if - else\n\nlet score: number = 8;\n\nif (score >= 5) {\n    console.log('You have passed the exam!');  // prints this\n} else if (score < 5) {\n    console.log('You haven\\'t passed the exam...');\n} else {\n    console.log('The scores are not available yet.');\n}\n\n\n// ESTRUCTURA DE CONTROL: switch\n\nlet month: number = 6;\nlet monthName: string = '';\n\nswitch (month) {\n    case 1:\n        monthName = 'January';\n        break;\n    case 2:\n        monthName = 'February';\n        break;\n    case 3:\n        monthName = 'March';\n        break;\n    case 4:\n        monthName = 'April';\n        break;\n    case 5:\n        monthName = 'May';\n        break;\n    case 6:\n        monthName = 'June';\n        break;\n    case 7:\n        monthName = 'July';\n        break;\n    case 8:\n        monthName = 'August';\n        break;\n    case 9:\n        monthName = 'September';\n        break;\n    case 10:\n        monthName = 'October';\n        break;\n    case 11:\n        monthName = 'November';\n        break;\n    case 12:\n        monthName = 'December';\n        break;\n    default:\n        monthName = 'Not a valid month number';\n}\nconsole.log(`Month: ${monthName}`);    // Month: June\n\n\n// ESTRUCTURA DE CONTROL: for\n\nfor (let i: number = 0; i < 5; i++) {\n    console.log(i);\n}\n/* Se imprimen los siguientes números:\n    0\n    1\n    2\n    3\n    4\n*/\n\n\n// ESTRUCTURA DE CONTROL: for-in\n\ntype Person = {\n    name: string\n    username: string\n    age: 25\n}\n\nconst person: Person = {\n    name: 'Naia',\n    username: 'nlarrea',\n    age: 25\n};\n\nfor (let key in person) {\n    // Se imprimen las claves:\n    console.log(key);\n\n    // Si quisiéramos imprimir los valores:\n    // console.log(person[key]);\n}\n/* Se imprimen los siguientes strings:\n    name\n    username\n    age\n*/\n\n\n// ESTRUCTURA DE CONTROL: for-of\n\nconst numArr: (string | boolean | number | string[])[] = ['hola', true, 7, ['a', 'b', 'c']]\n\nfor (let item of numArr) {\n    console.log(item);\n}\n/* Se imprime:\n    'hola'\n    true\n    7\n    [ 'a', 'b', 'c' ]\n*/\n\n\n// ESTRUCTURA DE CONTROL: while\n\nlet i: number = 0;\nwhile (i < 5) {\n    console.log(i);\n    i++;\n}\n/* Se imprimen los siguientes números:\n    0\n    1\n    2\n    3\n    4\n*/\n\n\n// ESTRUCTURA DE CONTROL: do-while\n\nlet j: string = 'Not empty';\ndo {\n    console.log(j);\n} while (j === '');\n/* Se imprime el mensaje 'Not empty' 1 vez aunque no se cumpla la condición del\nwhile, porque siempre se va a ejecutar aunque sea una vez.\n\nCUIDADO: si la condición del while se cumpliera, sería un bucle infinito\n*/\n\n\n// ESTRUCTURA DE CONTROL: try-catch\n\ntry {\n    throw new Error('This is an error');\n    console.log('This is not printed');\n} catch (error) {\n    console.log(error);                     // [Error: This is an error]\n}\n\n\n// ESTRUCTURA DE CONTROL: try-catch-finally\ntry {\n    throw new Error('This is an error');\n    console.log('This is not printed');\n} catch (error) {\n    console.log(error);                     // [Error: This is an error]\n} finally {\n    console.log('This is always printed');  // This is always printed\n}\n\n\n// EJERCICIO EXTRA\n\n/* DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n */\n\nfor (let num: number = 10; num <= 55; num++) {\n    if (\n        num % 2 === 0 &&\n        num !== 16 &&\n        num % 3 !== 0\n    ) {\n        console.log(num);\n    }\n}\n/* Se imprimen los siguientes números:\n    10 \n    14 \n    20 \n    22 \n    26 \n    28 \n    32 \n    34 \n    38 \n    40 \n    44 \n    46 \n    50 \n    52\n*/"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/pcosin.ts",
    "content": "// OPERADORES ARITMÉTICOS\n\nlet num1: number = 10;\nlet num2: number = 50;\nlet resultado: number;\n\n// Adición:\n\nresultado = num1 + num2;\n\nconsole.log(resultado);\n\n// Sustracción:\n\nresultado = num1 - num2;\n\nconsole.log(resultado);\n\n// Multiplicación:\n\nresultado = num1 * num2;\n\nconsole.log(resultado);\n\n// División:\n\nresultado = num1 / num2;\n\nconsole.log(resultado);\n\n// Módulo:\n\nresultado = num1 % num2;\n\nconsole.log(resultado);\n\n// OPERADORES DE ASIGNACIÓN\n\n// Aignación:\n\nconst str: string = \"Se le asigna una cadena de caractéres\";\n\n// Asignación compuesta:\n\nresultado += num1;\nconsole.log(resultado);\n\nresultado -= num1;\nconsole.log(resultado);\n\nresultado *= num1;\nconsole.log(resultado);\n\nresultado /= num1;\nconsole.log(resultado);\n\n// OPERADORES DE COMPARACIÓN\n\n// igualdad\n\nconsole.log(num1 == num1);\n\n// igualdad estricta\n\nconsole.log(num1 === 10);\n\n// desigualdad\n\nconsole.log(num1 != num2);\n\n// desigualdad estricta\n\nconsole.log(num1 !== num2);\n\n// mayor, menor, mayor o igual, menor o igual\n\nconsole.log(num1 < num2);\nconsole.log(num1 <= num2);\n\n//OPERADORES LÓGICOS\n\nconst varTrue: boolean = true;\nconst varFalse: boolean = false;\n\nlet resultBool: boolean;\n\n// and\n\nresultBool = varTrue && varFalse;\nconsole.log(resultBool);\n\n// or\n\nresultBool = varTrue || varFalse;\nconsole.log(resultBool);\n\n// not\n\nresultBool = !varFalse;\nconsole.log(resultBool);\n\n// OPERADORES DE INCREMENTO/DECREMENTO\n\nconsole.log(num1++);\nconsole.log(num1--);\n\n// OPERADORE AND A NIVEL DE BITS\n\nlet varbits: number = 5 & 3;\nconsole.log(varbits);\n\n// Operador OR a nivel de Bits\n\nvarbits = 5 | 3;\n\nconsole.log(varbits);\n\n// Operador XOR a nivel de Bits\n\nvarbits = 5 ^ 3;\n\nconsole.log(varbits);\n\n//  Desplazamiento a la izquierda\n\nvarbits = 5 << 1;\n\nconsole.log(varbits);\n\n// Desplazamiento a la derecha\n\nvarbits = 5 >> 1;\n\nconsole.log(varbits);\n\n//  Desplazamiento a la derecha sin signo\n\nvarbits = -5 >>> 1;\n\nconsole.log(varbits);\n\n// OPERADORES DE TIPOS\n\nconsole.log(typeof varbits);\n\n// CONDICIONAL\n\nconst user: string = \"1234\";\n\nif (!user) {\n  console.log(\"No existe el usuario\");\n} else {\n  console.log(\"Usuario encontrado\");\n}\n\n// ternario:\n\nconsole.log(user ? \"Usuario encontrado\" : \"No existe el usuario\");\n\n// BUCLES\n\n//for loop\n\nfor (let i: number = 0; i < 10; i++) {\n  console.log(i);\n}\n\n// while\n\nlet islarger: boolean = true;\nlet num3: number = 0;\nwhile (islarger) {\n  if (num3 >= 5) {\n    islarger = false;\n  }\n  console.log(num3);\n  num3++;\n}\n\n// do while\n\nlet i: number = 0;\n\ndo {\n  console.log(i);\n  i++;\n} while (i < 10);\n\n// Switch\n\nconst day: string = \"Martes\";\n\nswitch (day) {\n  case \"Lunes\": {\n    console.log(\"Hoy es lunes\");\n    break;\n  }\n  case \"Martes\": {\n    console.log(\"Hoy es martes\");\n    break;\n  }\n  case \"Miercoles\": {\n    console.log(\"Hoy es miercoles\");\n    break;\n  }\n  case \"Jueves\": {\n    console.log(\"Hoy es jueves\");\n    break;\n  }\n  case \"Viernes\": {\n    console.log(\"Hoy es viernes\");\n    break;\n  }\n}\n\n// EXCEPTIONS\n\n// try-catch\n\nlet password: string = \"1235\";\n\ntry {\n  if (password === \"1234\") {\n    console.log(\"contraseña correcta\");\n  } else {\n    throw new Error(\"Contraseña incorrecta\");\n  }\n} catch (error: any) {\n    console.error(error.message);\n    \n}\n\n// EXTRA\n\nfor (let i: number = 10; i <= 55; i++) {\n  if (i === 16 || i % 3 === 0) continue;\n  else if (i % 2 === 0) console.log(i);\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/qv1ko.ts",
    "content": "let a: number = 3;\nlet b: number = 4;\n\nlet sum: number = a + b;\nconsole.log(\"a + b = \" + sum);\n\nlet sub: number = a - b;\nconsole.log(\"a - b = \" + sub);\n\nlet mul: number = a * b;\nconsole.log(\"a * b = \" + mul);\n\nlet div: number = a / b;\nconsole.log(\"a / b = \" + div);\n\nlet res: number = a % b;\nconsole.log(\"a % b = \" + res);\n\nlet pow: number = a ** b;\nconsole.log(\"a ** b = \" + pow);\n\nlet inc: number = a++;\nconsole.log(\"a++ = \" + inc);\n\nlet dec: number = a--;\nconsole.log(\"a-- = \" + dec);\n\na += b;\nconsole.log(\"a += b\\tNumber A: \" + a);\n\na -= b;\nconsole.log(\"a -= b\\tNumber A: \" + a);\n\na *= b;\nconsole.log(\"a *= b\\tNumber A: \" + a);\n\na /= b;\nconsole.log(\"a /= b\\tNumber A: \" + a);\n\na = b;\nconsole.log(\"a = b\\tNumber A: \" + a);\n\na %= b;\nconsole.log(\"a %= b\\tNumber A: \" + a);\n\na **= b;\nconsole.log(\"a **= b\\tNumber A: \" + a);\n\nif (a == b) {\n    console.log(\"Number A is equal to number B\");\n}\n\nif (a === b) {\n    console.log(\"The number A and its type is equal to the number B\");\n} else if (a > b) {\n    console.log(\"The number A is greater than the number B\");\n} else {\n    console.log(\"Number A is neither greater than nor equal to number B\");\n}\n\nif (a >= b) {\n    console.log(\"Number A is greater than or equal to number B\");\n} else {\n    console.log(\"The number A is less than the number B\");\n}\n\nconsole.log(a != b ? \"The number A is different from the number B\" : \"The number A is the same as the number B\");\nconsole.log(a !== b ? \"Number A is different from number B in both value and type\" : \"The number A is the same as the number B\");\n\nswitch(b) {\n    case 1:\n        console.log(\"The number B is equal to 1\");\n        break;\n    case 2:\n        console.log(\"The number B is equal to 2\");\n        break;\n    case 3:\n        console.log(\"The number B is equal to 3\");\n        break;\n    case 4:\n        console.log(\"The number B is equal to 4\");\n        break;\n    default:\n        console.log(\"The number B is not 1, 2, 3, 4\");\n}\n\nwhile (a < b) {\n    console.log(\"Loop while\\t Number A: \" + a);\n    a++;\n}\n\na = 1;\n\ndo {\n    console.log(\"Loop do while\\t Number A: \" + a)\n    a++;\n} while (a <= b);\n\nfor (let i = 0; i < 3; i++) {\n    console.log(\"Loop for \" + i);\n}\n\nlet array: number[] = [1, 2, 3, 4];\n\nfor (var i of array) {\n    console.log(\"Loop of \" + i);\n}\n\nfor (var e in array) {\n    console.log(\"Loop in \" + e);\n}\n\ntry {\n    throw new Error('Error caught');\n} catch(e) {\n    console.log(e);\n}\n\nprogram()\n\nfunction program(): void {\n    for (let i = 10; i <= 55; i++) {\n        if (i % 2 == 0 && i != 16 && i % 3 != 0) {\n            console.log(\"\\n\" + i);\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/qwik-zgheib.ts",
    "content": "// -- exercise\n// Arithmetic operators\nlet a: number = 10;\nlet b: number = 5;\nlet sum: number = a + b;\nlet difference: number = a - b;\nlet product: number = a * b;\nlet quotient: number = a / b;\nlet remainder: number = a % b;\n\nconsole.log(\"Arithmetic Operators:\");\nconsole.log(\"Sum:\", sum);\nconsole.log(\"Difference:\", difference);\nconsole.log(\"Product:\", product);\nconsole.log(\"Quotient:\", quotient);\nconsole.log(\"Remainder:\", remainder);\n\n// Logical operators\nlet x: boolean = true;\nlet y: boolean = false;\nlet andResult: boolean = x && y;\nlet orResult: boolean = x || y;\nlet notResult: boolean = !x;\n\nconsole.log(\"\\nLogical Operators:\");\nconsole.log(\"AND:\", andResult);\nconsole.log(\"OR:\", orResult);\nconsole.log(\"NOT:\", notResult);\n\n// Comparison operators\nlet num1: number = 10;\nlet num2: number = 20;\nlet isEqual: boolean = num1 === num2;\nlet isNotEqual: boolean = num1 !== num2;\nlet greaterThan: boolean = num1 > num2;\nlet lessThan: boolean = num1 < num2;\nlet greaterThanOrEqual: boolean = num1 >= num2;\nlet lessThanOrEqual: boolean = num1 <= num2;\n\nconsole.log(\"\\nComparison Operators:\");\nconsole.log(\"Is Equal:\", isEqual);\nconsole.log(\"Is Not Equal:\", isNotEqual);\nconsole.log(\"Greater Than:\", greaterThan);\nconsole.log(\"Less Than:\", lessThan);\nconsole.log(\"Greater Than or Equal:\", greaterThanOrEqual);\nconsole.log(\"Less Than or Equal:\", lessThanOrEqual);\n\n// Assignment operators\nlet assignedValue: number = 30;\nassignedValue += 5;\nconsole.log(\"\\nAssignment Operator:\");\nconsole.log(\"Assigned Value:\", assignedValue);\n\n// Identity operators\nlet obj1: object = {};\nlet obj2: object = {};\nlet obj3: object = obj1;\nlet identityCheck1: boolean = obj1 === obj2;\nlet identityCheck2: boolean = obj1 === obj3;\n\nconsole.log(\"\\nIdentity Operators:\");\nconsole.log(\"Identity Check 1:\", identityCheck1);\nconsole.log(\"Identity Check 2:\", identityCheck2);\n\n// Membership operators\nlet array: number[] = [1, 2, 3];\nlet isInArray: boolean = array.includes(2);\n\nconsole.log(\"\\nMembership Operator:\");\nconsole.log(\"Is 2 in Array?\", isInArray);\n\n// Bitwise operators\nlet bitwiseAnd: number = 5 & 1;\nlet bitwiseOr: number = 5 | 1;\nlet bitwiseXor: number = 5 ^ 1;\nlet bitwiseNot: number = ~5;\nlet leftShift: number = 5 << 1;\nlet rightShift: number = 5 >> 1;\nlet zeroFillRightShift: number = 5 >>> 1;\n\nconsole.log(\"\\nBitwise Operators:\");\nconsole.log(\"Bitwise AND:\", bitwiseAnd);\nconsole.log(\"Bitwise OR:\", bitwiseOr);\nconsole.log(\"Bitwise XOR:\", bitwiseXor);\nconsole.log(\"Bitwise NOT:\", bitwiseNot);\nconsole.log(\"Left Shift:\", leftShift);\nconsole.log(\"Right Shift:\", rightShift);\nconsole.log(\"Zero-fill Right Shift:\", zeroFillRightShift);\n\n// Conditional structures\nlet condition: boolean = true;\n\nif (condition) {\n  console.log(\"Condition is true.\");\n} else {\n  console.log(\"Condition is false.\");\n}\n\n// ---------------------------------------------\n// Iterative structure -- extra challenge\nconsole.log(\"\\nIterative Structure:\");\nfor (let i: number = 10; i <= 55; i++) {\n  if (i !== 16 && i % 3 !== 0 && i % 2 === 0) {\n    console.log(i);\n  }\n}\n// ---------------------------------------------\n\n// Exception handling structure\nconsole.log(\"\\nException Handling Structure:\");\ntry {\n  throw new Error(\"Example error\");\n} catch (error) {\n  console.error(error);\n}\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/rendonnm.ts",
    "content": "// Aritméticos \n// Suma\nconsole.log(`Suma 1 + 2 = ${1 + 2}`) // 3\nconsole.log(`Resta 1 - 2 = ${1 - 2}`) // -1\nconsole.log(`Multiplicación 27 * 3 = ${27 * 3}`) // 81\nconsole.log(`División 3 / 4 = ${3 / 4}`) // 0.75\nconsole.log(`Residuo 10 % 2 = ${10 % 2}`) // 0\nconsole.log(`Exponencial 10 ** 3 = ${10 ** 3}`) // 1000\n\n// Comparación\nconsole.log(`Igualdad: 10 === 3: ${10 === 3}`) // false\nconsole.log(`Diferentes: 10 !== 3: ${10 !== 3}`) // true\nconsole.log(`Mayor que: 10 > 3: ${10 > 3}`) // true\nconsole.log(`Mayor o igual que: 10 > 3: ${10 >= 3}`) //true\nconsole.log(`Menor que: 10 < 3: ${10 < 3}`) // false\nconsole.log(`Menor o igual que: 10 < 3: ${10 <= 3}`) // false\n\n// Lógicos\nconsole.log(`AND (&&): false && true =  ${false && true}`) // false\nconsole.log(`OR (||): false || true = ${false || true}`) // true\nconsole.log(`NULLISH (??): null && 'This is a default value' = ${undefined ?? 'This is a default value'}`) // This is a default value\nconsole.log(`NOT (!): !false = ${!false}`) // true\n\n// Operadores de asignación\nlet a = 5\nconsole.log(`Asignación simple (=): a = 5 → a = ${a}`) // 5\nconsole.log(`Suma y asigna (+=): a += 3 → a = ${a += 3}`) // 8\nconsole.log(`Resta y asigna (-=): a -= 2 → a = ${a -= 2}`) // 6\nconsole.log(`Multiplica y asigna (*=): a *= 4 → a = ${a *= 4}`) // 24\nconsole.log(`Divide y asigna (/=): a /= 6 → a = ${a /= 6}`) // 4\nconsole.log(`Módulo y asigna (%=): a %= 3 → a = ${a %= 3}`) // 1\nconsole.log(`Exponente y asigna (**=): a **= 4 → a = ${a **= 4}`) // 1\n\n// Operadores de pertenencia\nconst persona = { nombre: 'Santi', edad: 25 }\nconsole.log(`'nombre' in persona: ${'nombre' in persona}`) // true\nconsole.log(`'apellido' in persona: ${'apellido' in persona}`) // false\n\nconsole.log(``)\n\nclass Animal {\n  name: string\n  constructor(name: string) {\n    this.name = name\n  }\n}\nclass Cat extends Animal {\n  color: string\n  constructor(name: string, color: string) {\n    super(name)\n    this.color = color\n  }\n}\nconst morgan = new Cat('Morgan', 'white')\nconsole.log(`Morgan es intancia de Animal? ${morgan instanceof Animal}`) // true\n\n// Estructuras de control\n// Condicionales\nconst newName = 'rendonnm'\nif (newName === 'rendonnm') {\n  console.log('Nice name')\n} else if (newName === 'another name') {\n  console.log('ok ok')\n} else {\n  console.log('MMMM')\n}\n\n// Iterativas\nfor (let i = 1; i < 11; i++) {\n  console.log(`Iterando: Número ${i}`)\n}\n\nlet iterator = 0\nwhile (iterator < 11) {\n  console.log(`Iterando while: Número ${iterator}`)\n  iterator++\n}\n\n// Manejo de excepciones\ntry {\n  // Intentar hacer algo...\n} catch (err) {\n  console.error(`Ha ocurrido un error ${err}`)\n}\n\n// DIFICULTAD EXTRA (opcional)\n// Crea un programa que imprima por consola todos los números comprendidos\n// entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3\n\nfor (let i = 10; i < 56; i++) {\n  if (i % 2 !== 0 || i === 16 || i % 3 === 0) continue\n  console.log(i)\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/rubenplazavi.ts",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * - Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n\n//Operadores aritmeticos    \nconsole.log('Operadores aritmeticos');\nlet num1 = 10;\nlet num2 = 5;\n\nconsole.log(num1 + num2);\nconsole.log(num1 - num2);\nconsole.log(num1 * num2);\nconsole.log(num1 / num2);\nconsole.log(num1 % num2);\n\n//Operadores logicos\nconsole.log('Operadores logicos');\nlet boolean1 = true;\nlet boolean2 = false;\n\nconsole.log(boolean1 && boolean2);\nconsole.log(boolean1 || boolean2);\nconsole.log(!boolean1);\n\n//Operadores de comparacion\nconsole.log('Operadores de comparacion');\nconsole.log(num1 == num2);\nconsole.log(num1 != num2);\nconsole.log(num1 > num2);\nconsole.log(num1 < num2);\nconsole.log(num1 >= num2);\nconsole.log(num1 <= num2);\n\n//Operadores de asignacion\nconsole.log('Operadores de asignacion');\nnum1 += 5;\nconsole.log(num1);\nnum1 -= 5;\nconsole.log(num1);\nnum1 *= 5;\nconsole.log(num1);\nnum1 /= 5;\nconsole.log(num1);\nnum1 %= 5;\nconsole.log(num1);\n\nconsole.log(num1);\n\n//Operadores de identidad y pertenencia\nconsole.log('operadores de identidad y pertenencia');\nconsole.log(num1 === num2);\nconsole.log(num1 !== num2);\n\n// Operadores de pertenencia --> in para objetos\nconsole.log('Operadores de pertenencia');\nconst obj = { a: 1, b: 2, c: 3 };\n\nconsole.log(num1 in obj);\nconsole.log(num1 !in obj);\n\n// pertenencia en arrays\nconsole.log('pertenencia en arrays');\nconst arr = [1, 2, 3];\n\nconsole.log(arr.includes(num1));\nconsole.log(arr.includes(3));\n\n//Operadores de bits\nconsole.log('Operadores de bits');\nconsole.log(num1 & num2);\nconsole.log(num1 | num2);\nconsole.log(num1 ^ num2);\nconsole.log(num1 << num2);\nconsole.log(num1 >> num2);\nconsole.log(num1 >>> num2);\n\n//Estructuras de control\n\nif (num1 > num2) {\n  console.log('num1 es mayor que num2');\n} else {\n  console.log('num1 no es mayor que num2');\n}   \n\nfor (let i = 0; i < 10; i++) {  \n  console.log(i);\n}\n\nwhile (num1 < num2) {\n  num1++;\n  console.log(num1);                \n}\n\ndo {           \n  num1++;    \n  console.log(num1);\n} while (num1 < num2);\n\nswitch (num1) {\n  case 1:\n    console.log('num1 es 1');\n    break;\n  case 2:\n    console.log('num1 es 2');\n    break;\n  default:\n    console.log('num1 no es 1 ni 2');\n    break;\n}\n\ntry {\n  console.log(num1);\n} catch (error) {\n  console.log(error);\n}   \n\nthrow new Error('Error');\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/samuelarandia.ts",
    "content": "\n/*\n * EJERCICIO:\n * [x] Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n *   Aritméticos, lógicos, de comparación, asignación, identidad, pertenencia, bits...\n *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n * [x] Utilizando las operaciones con operadores que tú quieras, crea ejemplos\n *   que representen todos los tipos de estructuras de control que existan\n *   en tu lenguaje:\n *   Condicionales, iterativas, excepciones...\n *[x] Debes hacer print por consola del resultado de todos los ejemplos.\n *\n * DIFICULTAD EXTRA (opcional):\n * [x] Crea un programa que imprima por consola todos los números comprendidos\n * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n *\n * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n */\n// ----- Operadores aritméticos\n\nlet a:number = 5;\nlet b:number = 3;\n\n//Suma (+)\nconsole.log(\"suma\", a + b); // 8\n//Resta (-)\nconsole.log(\"resta\", a - b); // 2\n//Multiplicación (*)\nconsole.log(\"multiplicación\", a * b); // 15\n//División (/)\nconsole.log(\"división\", a / b); // 1.6666666666666667\n//Módulo (%)\nconsole.log(\"módulo\", a % b); // 2\n//Incremento (++)\nconsole.log(\"incremento\", a++); // 5\n//Decremento (--)\nconsole.log(\"decremento\", b--); // 3\n//exponenciación (**)\nconsole.log(\"exponenciación\", 5 ** 3); // 125\n\n\n//---- Operadores lógicos\n\nlet c:boolean = true;\nlet d:boolean = false;\n\n// AND\nconsole.log(\"AND\", c && d); // false\n// OR\nconsole.log(\"OR\", c || d); // true\n// NOT\nconsole.log(\"NOT\", !c); // false\n\n\n//---- Operadores de comparación\n\nlet e:number = 20;\nlet f:number = 10;\n\n// Igual (==)\nconsole.log(\"Igual\", e == f); // false\n// Distinto (!=)\nconsole.log(\"Distinto\", e != f); // true\n// Mayor que (>)\nconsole.log(\"Mayor que\", e > f); // true\n// Menor que (<)\nconsole.log(\"Menor que\", e < f); // false\n// Mayor o igual que (>=)\nconsole.log(\"Mayor o igual que\", e >= f); // true\n// Menor o igual que (<=)\nconsole.log(\"Menor o igual que\", e <= f); // false\n\n\n//---- Operadores de asignación\n\nlet g:number = 5;\nlet h:number = 3;\n\n// Asignación (=)\nconsole.log(\"Asignación\", g = h); // 3\n// Asignación de adición (+=)\nconsole.log(\"Asignación de adición\", g += h); // 6\n// Asignación de sustracción (-=)\nconsole.log(\"Asignación de sustracción\", g -= h); // 3\n// Asignación de multiplicación (*=)\nconsole.log(\"Asignación de multiplicación\", g *= h); // 9\n// Asignación de división (/=)\nconsole.log(\"Asignación de división\", g /= h); // 3\n// Asignación de módulo (%=)\nconsole.log(\"Asignación de módulo\", g %= h); // 0\n\n\n\n//---- Operadores de identidad\n\nlet i:number = 5;\nlet j:number = 5;\n\n// Estrictamente igual (===)\nconsole.log(\"Estrictamente igual\", i === j); // true\n// Estrictamente no igual (!==)\nconsole.log(\"Estrictamente no igual\", i !== j); // false\n\n\n// ---- Estrucutras de control\n\nlet k:number = 5;\nlet l:number = 3;\n\n// If\nif (k > l) {\n    console.log(\"k es mayor que l\");\n}\n\n// If else\nif (k < l) {\n    console.log(\"k es menor que l\");\n} else {\n    console.log(\"k no es menor que l\");\n}\n\n// If else if else\n\nif (k < l) {\n    console.log(\"k es menor que l\");\n} else if (k > l) {\n    console.log(\"k es mayor que l\");\n}\n\n// Switch\n\nlet m:number = 2;\nlet n:string; \n\nswitch (m) {\n    case 1:\n        n = \"uno\";\n        console.log(n);\n        break;\n    case 2:\n        n = \"dos\";\n        console.log(n);\n        break;\n    case 3:\n        n = \"tres\";\n        console.log(n);\n        break;\n    default:\n        n = \"no es ni uno, ni dos, ni tres\";\n        break;\n}\n\n\n// For\n\nfor (let o = 0; o < 5; o++) {\n    console.log(o);\n}\n\n// While\n\nlet p:number = 0;\n\nwhile (p < 5) {\n    console.log(p);\n    p++;\n}\n\n// Do while\n\nlet q:number = 0;\n\ndo {\n    console.log(q);\n    q++;\n} \nwhile (q < 5);\n\n\n// Try catch\n\nlet r:number = 5;\n\ntry {\n    console.log(r);\n} catch (error) {\n    console.log(error);\n}\n\n\n// Números entre 10 y 55 (pares, no múltiplos de 3 ni 16)\n\nfor ( let s:number = 10; s <= 55 ; s ++) { \n    if ((s % 2 == 0) && (s != 16) && (s % 3 != 0)) {\n        console.log(s);\n    }\n}\n\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/sniker1223.ts",
    "content": "// Arithmetic Operators\nvar numberA: number = 100\nconsole.log(\"Arithmetic Operators\")\nconsole.log(\"+ Addition:\", numberA + 50)\nconsole.log(\"- Subtraction:\", numberA - 50)\nconsole.log(\"* Multiplication:\", numberA * 50)\nconsole.log(\"/ Division:\", numberA / 50)\nconsole.log(\"% Modulus:\", numberA % 2)\nnumberA++\nconsole.log(\"++ Increment:\", numberA)\nnumberA--\nconsole.log(\"-- Decrementing:\", numberA)\n\n// Assignment Operators\nconsole.log(\"\\nAssignment Operators\")\nnumberA = 50\nconsole.log(\"= Assignment: numberA = \", numberA)\nnumberA += 1\nconsole.log(\"+= Addition assignment: numberA += \", numberA)\nnumberA -= 1\nconsole.log(\"-= Substraction Assignment: numberA -= \", numberA)\nnumberA *= 2\nconsole.log(\"*= Multiplication Assignment: numberA *= \", numberA)\nnumberA /= 3\nconsole.log(\"/= Division Assignment: numberA /= \", numberA)\nnumberA %= 2\nconsole.log(\"%= Modulus Assignment: numberA %= \", numberA)\n\n// Comparison Operators\nconsole.log('\\nComparision Operators')\nconsole.log('==\tIs equal to\t10 == 10 = ', 10 == 10)\nconsole.log('=== Identical (equal and of same type) ', 10 === 10)\nconsole.log(\"!= Not equal to 20 != 20: \", 20 != 20)\nconsole.log(\"!== Not Identical 20 !== 20\", 20 !== 20)\nconsole.log('2 is greater than 1:', 2 > 1)\nconsole.log('2 is greater than or equal to 2', 2 >= 2)\nconsole.log('2 is less than 1: ', 2 < 1)\nconsole.log('2 is less than or equal to 1', 2 <= 1)\n\n// Logical Operators\nconsole.log('\\nLogical Operators')\nnumberA = 6\nconsole.log('&& and operator:', numberA > 1 && numberA < 8)\nconsole.log('|| or operator:', numberA > 1 || numberA > 8)\nconsole.log('! not operator:', !(6 == 6))\n\n// Typescript typeof Operator\nconsole.log('\\nTypescript typeof Operator')\nconsole.log('typeof: ', typeof \"Hello world\");\n\n// CONTROL STRUCTURES\nconsole.log('\\nif Statement')\nif (7 < 18) {\n  console.log(\"Good day\")\n}\n\nconsole.log('\\nelse Statement')\nif (19 < 18) {\n  console.log(\"Good day\")\n} else {\n  console.log(\"Good evening\")\n}\n\nconsole.log('\\nelse if Statement')\nlet dateTime = new Date().getHours()\n\nif (dateTime < 10) {\n  console.log(\"Good morning\")\n} else if (dateTime < 20) {\n  console.log(\"Good day\")\n} else {\n  console.log(\"Good evening\")\n}\n\nconsole.log('\\nSwitch Statement')\nswitch (new Date().getDay()) {\n  case 0:\n    console.log(\"Sunday\")\n    break;\n  case 1:\n    console.log(\"Monday\")\n    break;\n  case 2:\n    console.log(\"Tuesday\")\n    break;\n  case 3:\n    console.log(\"Wednesday\")\n    break;\n  case 4:\n    console.log(\"Thursday\")\n    break;\n  case 5:\n    console.log(\"Friday\")\n    break;\n  case 6:\n    console.log(\"Saturday\")\n}\n\nconsole.log('\\nfor loop')\nvar list: Array<String> = [\"BMW\", \"Volvo\", \"Saab\", \"Ford\", \"Fiat\", \"Audi\"];\nlet textList = \"\";\nfor (let i = 0; i < list.length; i++) {\n  textList += list[i] + \"\\n\";\n}\nconsole.log(textList)\n\nconsole.log('\\nfor in loop')\nconst person = {\n  fname: \"John\",\n  lname: \"Doe\",\n  age: 25\n}\nlet textPerson1 = \"\"\n\nconst keys = Object.keys(person);\n\nkeys.forEach((key) => {\n  console.log(person[key as keyof typeof person]);\n});\n\nconsole.log('\\nWhile Loop')\nlet iterable = 0\nwhile (iterable <= 10) {\n  console.log(\"The number is \" + iterable)\n  iterable++;\n}\n\nconsole.log('\\ntry and finally')\n\nfunction doIt() {\n  try {\n    return console.log('1')\n  } finally {\n    return console.log('2')\n  }\n}\ndoIt();\n\n// Challenge. Print numbers between 10 and 55(included), even and odd but not print 16 and multiple of 3.\nconsole.log('\\nChallenge')\nfor (let n = 0; n <= 55; n++) {\n  if (n >= 10 && n % 2 == 0 && n != 16 && !(n % 3 == 0) || n == 55) {\n    console.log(n)\n  }\n}\n\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/tolomero.ts",
    "content": "//operadores y estructuras de control\n\n//operadores de aritmeticos\n\nlet a: number = 10;\nlet b: number = 3;\n\nconsole.log(a + b); //13\nconsole.log(a * b); \nconsole.log(a / b); \nconsole.log(a - b); \nconsole.log(a % b); \nconsole.log(a ** b); \n\n//operadores de turno\nlet i: number = 4;\nlet t: number = 2;\nconsole.log(\"i << j = \" + (i  << t));\nconsole.log(\"i >> j = \" + (i  >> t));\nconsole.log(\"i >>> j = \" + (i >>>t));\n//operadores relacionales\nlet k: number = 4;\nlet j: number = 2;\nconsole.log(\"k < j = \" + (k < j));\nconsole.log(\"k > j = \" + (k > j));\n\n//operadores de asignacion\nlet x: number = 10;\nlet y: number = 5;\n\nx += y; // x = x + y\nconsole.log(\"x += y: \" + x);\n\nx -= y; // x = x - y\nconsole.log(\"x -= y: \" + x);\n\nx *= y; // x = x * y\nconsole.log(\"x *= y: \" + x);\n\nx /= y; // x = x / y\nconsole.log(\"x /= y: \" + x);\n\nx %= y; // x = x % y\nconsole.log(\"x %= y: \" + x);\n\nx **= y; // x = x ** y\nconsole.log(\"x **= y: \" + x);\n//operadores logicos\nlet p: boolean = true;\nlet q: boolean = false;\n\nconsole.log(\"p && q = \" + (p && q)); // false\nconsole.log(\"p || q = \" + (p || q)); // true\nconsole.log(\"!p = \" + (!p)); // false\nconsole.log(\"!q = \" + (!q)); // true\n\n//operadores de comparacion\nlet m: number = 10;\nlet n: number = 20;\n\nconsole.log(\"m == n = \" + (m == n)); // false\nconsole.log(\"m != n = \" + (m != n)); // true\nconsole.log(\"m > n = \" + (m > n)); // false\nconsole.log(\"m < n = \" + (m < n)); // true\nconsole.log(\"m >= n = \" + (m >= n)); // false\nconsole.log(\"m <= n = \" + (m <= n)); // true\nconsole.log(\"m === n = \" + (m === n)); // false\n// Estructuras de control\n\n// if-else\nlet age: number = 18;\nif (age >= 18) {\n    console.log(\"Eres un adulto\");\n} else {\n    console.log(\"Eres menor de edad\");\n}\n\n// switch\nlet day: number = 3;\nswitch (day) {\n    case 1:\n        console.log(\"Lunes\");\n        break;\n    case 2:\n        console.log(\"Martes\");\n        break;\n    case 3:\n        console.log(\"Miércoles\");\n        break;\n    case 4:\n        console.log(\"Jueves\");\n        break;\n    case 5:\n        console.log(\"Viernes\");\n        break;\n    case 6:\n        console.log(\"Sábado\");\n        break;\n    case 7:\n        console.log(\"Domingo\");\n        break;\n    default:\n        console.log(\"Día inválido\");\n}\n\n// for loop\nfor (let i = 0; i < 5; i++) {\n    console.log(\"i = \" + i);\n}\n\n// while loop\nlet count: number = 0;\nwhile (count < 5) {\n    console.log(\"count = \" + count);\n    count++;\n}\n\n// do-while loop\nlet num: number = 0;\ndo {\n    console.log(\"num = \" + num);\n    num++;\n} while (num < 5);\n\n\n\nfor (let i = 10; i <= 55; i++) {\n    if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n        console.log(i);\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/typescript/victoriaparraf.ts",
    "content": "//OPERADORES ARITMETICOS\n//Suma (+): Adición de dos números o concatenación de cadenas.\nlet ahorro: number = 35000;\nlet salario: number = 15000;\nlet nombre: string = 'Victoria';\nlet apellido: string = 'Parra';\n\nlet montoTotal: number = ahorro + salario;\nlet mensajito: string = nombre + ' ' + apellido + ' tiene en total de dinero (ojala): ';\nconsole.log(mensajito + montoTotal);\n\n//Resta (-): Resta de dos números.\nlet restaComun: number = 2109 - 42342;\nconsole.log(restaComun);\n\n//Multiplicación (*): Multiplicación de dos números.\nlet multiplicacionComun: number = 8 * 8; \nconsole.log(multiplicacionComun);\n\n//Módulo (%): Resto de la división de dos números.\nlet residuoDivision: number = 42 % 2;\nconsole.log(residuoDivision);\n\n//Incremento (++): Incrementa el valor de una variable en uno.\nlet numerito = 1;\nnumerito++; //2\nconsole.log(numerito);\n\n//Decremento (--): Decrementa el valor de una variable en uno.\nlet numerazo = 100;\nnumerazo--; //99\nconsole.log(numerazo);\n\n//OPERADORES DE ASIGNACION\n//Asignación (=): Asigna un valor a una variable.\nlet variable = 'Es obvio que es de asignacion el = ';\nconsole.log(variable);\n\n//Asignación de suma (+=): Suma y asigna el resultado.\nlet sumandoAsignando: number = 15;\nsumandoAsignando += 5; //20\nconsole.log(sumandoAsignando);\n\n//Asignación de resta (-=): Resta y asigna el resultado.\nlet restandoAsignando: number = 30;\nrestandoAsignando-= 10; //20\nconsole.log(restandoAsignando);\n\n//Asignación de multiplicación (*=): Multiplica y asigna el resultado.\nlet y = 5;\ny*=5;\nconsole.log(y);\n\n//Asignación de división (/=): Divide y asigna el resultado.\nlet z = 12\nz /= 3;\nconsole.log(z);\n\n//Asignación de módulo (%=): Calcula el resto y asigna el resultado.\nlet x = 10;\nx %= 3; // 1\nconsole.log(x);\n\n//OPERADORES DE COMPARACION\n//Igualdad (==): Compara si dos valores son iguales (sin comparar el tipo).\nlet esIgual = 5 == 5; // true\nconsole.log(esIgual);\n\n//Igualdad estricta (===): Compara si dos valores son iguales y del mismo tipo.\nlet esIgualEstricta = 5 === 5; // true\nconsole.log(esIgualEstricta);\n\n//Desigualdad (!=): Compara si dos valores no son iguales (sin comparar el tipo).\nlet esDiferente = 5 != 5; // false\nconsole.log(esDiferente);\n\n//Desigualdad estricta (!==): Compara si dos valores no son iguales o no son del mismo tipo.\nlet esDiferenteEstricta = 5 !== 5; // false\nconsole.log(esDiferenteEstricta);\n\n//Mayor que (>): Comprueba si el valor de la izquierda es mayor que el de la derecha.\nlet esMayor = 5 > 2; // true\nconsole.log(esMayor);\n\n//Menor que (<): Comprueba si el valor de la izquierda es menor que el de la derecha.\nlet esMenor = 5 < 2; // false\nconsole.log(esMenor);\n\n//Menor o igual que (<=): Comprueba si el valor de la izquierda es menor o igual que el de la derecha.\nlet esMenorIgual = 5 <= 5; // true\nconsole.log(esMenorIgual);\n\n//Mayor o igual que (>=): Comprueba si el valor de la izquierda es mayor o igual que el de la derecha.\nlet esMayorIgual = 5 >= 5; // true\nconsole.log(esMayorIgual);\n\n//OPERADORES LOGICOS\n//AND (&&): Comprueba si ambos operandos son verdaderos.\nlet esVerdadero = true && false; // false\nconsole.log(esVerdadero);\n\n//OR (||): Comprueba si al menos uno de los operandos es verdadero.\nlet cual = true || false; // true\nconsole.log(cual);\n\n//NOT (!): Niega el valor booleano.\nlet noEsVerdadero = !true; // false\nconsole.log(noEsVerdadero);\n\n//OPERADORES BIT A BIT\n//AND bit a bit (&): Realiza una operación AND bit a bit.\nlet andBitA = 5 & 1; // 1\n\n//OR bit a bit (|): Realiza una operación OR bit a bit.\nlet orBitA = 5 | 1; // 5\n\n//XOR bit a bit (^): Realiza una operación XOR bit a bit.\nlet xorBitA = 5 ^ 1; // 4\n\n//NOT bit a bit (~): Invierte los bits.\nlet notBitA = ~5; // -6\n\n//Desplazamiento a la izquierda (<<): Desplaza los bits a la izquierda.\nlet desplazamientoIzq = 5 << 1; // 10\n\n//Desplazamiento a la derecha (>>): Desplaza los bits a la derecha.\nlet desplazamientoDer = 5 >> 1; // 2\n\n//Desplazamiento a la derecha sin signo (>>>): Desplaza los bits a la derecha sin signo\nlet desplazamientoDerSinSigno = 5 >>> 1; // 2\n\n//OPERADOR TERNARIO\n//El operador ternario es una forma abreviada de un if-else.\nlet esMayorcito = (5 > 2) ? 'Sí' : 'No'; // 'Sí'\nconsole.log(esMayorcito);\n\n//OPERADOR DE CADENA\n//Concatenación (+): Combina dos cadenas.\nlet saludo = 'Hola' + ' Mundo'; // 'Hola Mundo'\nconsole.log(saludo);\n\n//TIPOS DE ESTRUCTURAS DE CONTROL\n//if, else if, else\n\nlet numero: number = 10;\n\nif (numero > 0) {\n    console.log(\"El número es positivo\");\n} else if (numero < 0) {\n    console.log(\"El número es negativo\");\n} else {\n    console.log(\"El número es cero\");\n}\n\n//Switch\nlet dia: number = 3;\nlet nombreDia: string;\n\nswitch (dia) {\n    case 0:\n        nombreDia = \"Domingo\";\n        break;\n    case 1:\n        nombreDia = \"Lunes\";\n        break;\n    case 2:\n        nombreDia = \"Martes\";\n        break;\n    case 3:\n        nombreDia = \"Miércoles\";\n        break;\n    case 4:\n        nombreDia = \"Jueves\";\n        break;\n    case 5:\n    nombreDia = \"Viernes\";\n    break;\n    case 6:\n        nombreDia = \"Sábado\";\n        break;\n    default:\n        nombreDia = \"Día inválido\";\n}\n\nconsole.log(nombreDia); // \"Miércoles\"\n\n//Bucles\n//for\nfor (let i: number = 0; i < 5; i++) {\n    console.log(i);\n}\n// Salida: 0, 1, 2, 3, 4\n\n//for...of Se utiliza para iterar sobre los valores de un objeto iterable (como un array).\nlet ListaNumeros: number[] = [1, 2, 3, 4, 5];\n\nfor (let numero of ListaNumeros) {\n    console.log(numero);\n}\n// Salida: 1, 2, 3, 4, 5\n\n//for...in Se utiliza para iterar sobre las propiedades enumerables de un objeto.\nlet usuario = {\n    nombre: \"Juan\",\n    edad: 30\n};\n\nfor (let propiedad in usuario) {\n    console.log(`${propiedad}: ${usuario[propiedad]}`);\n}\n  // Salida: \n  // nombre: Juan\n  // edad: 30\n\n//while\nlet contador: number = 0;\n\nwhile (contador < 5) {\n    console.log(contador);\n    contador++;\n}\n  // Salida: 0, 1, 2, 3, 4\n\n//do...while\nlet contadorDos: number = 0;\n\ndo {\n    console.log(contadorDos);\n    contadorDos++;\n} while (contadorDos < 5);\n// Salida: 0, 1, 2, 3, 4\n\n//EXCEPCIONES\n//try, catch, finally, throw Se utilizan para manejar errores y excepciones.\ntry {\n    let resultado: number = 10 / 0;\n    if (resultado === Infinity) {\n        throw new Error(\"División por cero\");\n    }\n} catch (error) {\n    console.error(error.message);\n} finally {\n    console.log(\"El bloque finally siempre se ejecuta\");\n}\n  // Salida: \"División por cero\"\n  //         \"El bloque finally siempre se ejecuta\"\n//*********************************************************************************//\n\nconsole.log(\"Agarrese de esa silla que vamos con el reto:\");\nconsole.log(\"Todos los números comprendidos entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3\");\n\nfor(let contando: number = 10; contando <=55; contando++){\n    if (contando == 16){\n        continue;\n    } else if (contando % 3 == 0){\n        continue;\n    } else if (contando % 2 == 0){\n        console.log(contando);\n    }\n}"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/vb.net/kenysdev.vb",
    "content": "' ╔══════════════════════════════════════╗\n' ║ Autor:  Kenys Alvarado               ║\n' ║ GitHub: https://github.com/Kenysdev  ║\n' ║ 2024 -  VB.NET                       ║\n' ╚══════════════════════════════════════╝\nImports System\n\nModule Program\n    Sub Main(args As String())\n\n        ' 1. Imprimir ejemplos utilizando todos los tipos \n        '    de operadores de tu lenguaje: \n        ' ***********************************************\n        Console.WriteLine(\"\n        Operadores aritmeticos:\n        -----------------------\n        - Suma:              10 + 5         = \" & (10 + 5) & \"\n        - Resta:             10 - 5         = \" & (10 - 5) & \"\n        - Multiplicacion:    10 * 5         = \" & (10 * 5) & \"\n        - Division: \n          double, float o    5.0 / 2.0      = \" & (5.0 / 2.0) & \"\n        - Division Entera: int o 17 \\ 4     = \" & (17 \\ 4) & \"\n        - Residuo:           20 % 7         = \" & (20 Mod 7) & \"\n        - Potenciacion:      Math.Pow(2, 3) = \" & Math.Pow(2, 3) & \"\n        - Combined:         (4 + 2) * 3 / 2 = \" & ((4 + 2) * 3 / 2) & \"\n\n        Operadores de Comparacion:\n        --------------------------\n        - igual a       5 == 5 -> \" & (5 = 5) & \"\n        - Diferente de  5 != 5 -> \" & (5 <> 5) & \"\n        - Menor que     4 < 5  -> \" & (4 < 5) & \"\n        - Mayor que     4 > 5  -> \" & (4 > 5) & \"\n        - Menor o igual 4 <= 5 -> \" & (4 <= 5) & \"\n        - Mayor o igual 4 >= 5 -> \" & (4 >= 5) & \"\n        \")\n        ' -------------------------\n        ' Operadores de Asignación:\n        ' -------------------------\n        Console.WriteLine(Environment.NewLine & \"Operadores de Asignación:\")\n        Dim n As Double = 10\n        n += 2\n        n -= 2\n        n *= 2\n        n /= 2\n        n = n Mod 2 'modulo\n        Math.Pow(n, 2) 'pow\n        Console.WriteLine(n) ' 0\n\n        ' -------------------\n        ' Operadores Lógicos:\n        ' -------------------\n        Console.WriteLine(Environment.NewLine & \"Operadores Lógicos:\")\n        ' Operador AndAlso (and)\n        Dim resultadoAnd As Boolean = (5 = 5 AndAlso 6 <> 5)\n        Console.WriteLine(\"Operador AndAlso (and): \" & resultadoAnd)\n\n        ' Operador OrElse (or)\n        Dim resultadoOr As Boolean = (5 = 5 OrElse 6 <> 5)\n        Console.WriteLine(\"Operador OrElse (or): \" & resultadoOr)\n\n        ' Operador Not (not)\n        Dim resultadoNot As Boolean = Not (5 = 6)\n        Console.WriteLine(\"Operador Not (not): \" & resultadoNot)\n\n        ' ------------------------\n        ' Operador de Pertenencia:\n        ' ------------------------\n        Console.WriteLine(Environment.NewLine & \"Operador de Pertenencia:\")\n        Dim resultado As Boolean = \"abcde\".Contains(\"c\")\n        Console.WriteLine(\"Resultado de \"\"abcde\"\".Contains(\"\"c\"\"): \" & resultado)\n\n        ' ---------------------\n        ' Operadores Bit a Bit:\n        ' ---------------------\n        Console.WriteLine(Environment.NewLine & \"Operadores Bit a Bit:\")\n        ' Operador AND\n        Dim resultado_And As String = Convert.ToString(10 And 5, 2)\n        Console.WriteLine(\"and:       \" & resultado_And)\n\n        ' Operador OR\n        Dim resultado_Or As String = Convert.ToString(10 Or 5, 2)\n        Console.WriteLine(\"or:        \" & resultado_Or)\n\n        ' Operador XOR\n        Dim resultadoXor As String = Convert.ToString(10 Xor 5, 2)\n        Console.WriteLine(\"xor:       \" & resultadoXor)\n\n        ' Operador NOT\n        Dim resultado_Not As String = Convert.ToString(Not 10, 2)\n        Console.WriteLine(\"not_a:     \" & resultado_Not)\n\n        ' Desplazamiento a la izquierda\n        Dim resultado_Izquierda As String = Convert.ToString(10 << 2, 2)\n        Console.WriteLine(\"izquierda: \" & resultado_Izquierda)\n\n        ' Desplazamiento a la derecha\n        Dim resultado_Derecha As String = Convert.ToString(10 >> 1, 2)\n        Console.WriteLine(\"derecha:   \" & resultado_Derecha)\n\n        ' **************************\n        ' 2. Estructuras de control:\n        ' **************************\n        ' __________________________\n        ' Condicinal\n        Console.WriteLine(Environment.NewLine & \"Condicinal:\")\n        Dim x As Integer = 2\n        If x = 5 Then\n            Console.WriteLine(\"Si 5 == 5\")\n        ElseIf x = 2 Then\n            Console.WriteLine(\"Si 2 == 2\")\n        Else\n            Console.WriteLine(\"Ninguna\")\n        End If\n\n        ' __________________________\n        ' Operador ternario\n        Console.WriteLine(Environment.NewLine & \"Operador ternario:\")\n        Console.WriteLine(If(15 = 15, \"si es igual\", \"no es igual\"))\n\n        ' __________________________\n        ' Switch\n        Console.WriteLine(Environment.NewLine & \"switch:\")\n        Dim num As Integer = 2\n        Select Case num\n            Case 1\n                Console.WriteLine(\"Es 1\")\n            Case 2\n                Console.WriteLine(\"Es 2\")\n            Case Else\n                Console.WriteLine(\"null\")\n        End Select\n\n        ' __________________________\n        ' Bucle for\n        Console.WriteLine(\"Bucle for:\")\n        For i As Integer = 0 To 2\n            Console.WriteLine($\"Iteración {i + 1}\")\n        Next\n\n        ' __________________________\n        ' Bucle while\n        Console.WriteLine(Environment.NewLine & \"Bucle while:\")\n        Dim j As Integer = 0\n        While j < 3\n            Console.WriteLine($\"Iteración {j + 1}\")\n            j += 1\n        End While\n\n        ' __________________________\n        ' Bucle do - Loop While\n        Console.WriteLine(Environment.NewLine & \"Bucle do-while:\")\n        Dim k As Integer = 0\n        Do\n            Console.WriteLine($\"Iteración {k + 1}\")\n            k += 1\n        Loop While k < 3\n\n        ' __________________________\n        ' Bucle For Each\n        Console.WriteLine(Environment.NewLine & \"Bucle foreach (para iterar sobre colecciones):\")\n        Dim z() As Integer = {1, 2, 3}\n        For Each num2 In z\n            Console.WriteLine($\"Número: {num2}\")\n        Next\n\n        ' __________________________\n        ' Exit For & Continue\n        Console.WriteLine(Environment.NewLine & \"break & continue:\")\n        For i As Integer = 1 To 3\n            If i = 4 Then\n                Console.WriteLine($\"Valor 4 encontrado. Break.\")\n                Exit For\n            End If\n            If i Mod 2 = 0 Then\n                Console.WriteLine($\"Iteración {i} es par. Continue.\")\n                Continue For\n            End If\n            Console.WriteLine($\"Iteración {i}\")\n        Next\n        Console.WriteLine($\"Finalizando\")\n\n        ' __________________________\n        ' Control de Excepciones\n        Console.WriteLine(Environment.NewLine & \"Control de Excepciones:\")\n        Try\n            Dim nu As Integer = 10\n            Console.WriteLine($\"Resultado: {nu / 0}\")\n        Catch e As DivideByZeroException\n            Console.WriteLine($\"Error división: {e.Message}\")\n        Finally\n            Console.WriteLine(\"finally\")\n        End Try\n\n        ' 3. Ejercicio:\n        ' *************\n        ' Crea un programa que imprima por consola todos los números comprendidos entre\n        ' 10 y 55 (incluidos), pares, y que no son ni el 16 ni múltiplos de 3.\n        Console.WriteLine(Environment.NewLine & \"Ejercicio:\")\n\n        For numero As Integer = 10 To 55\n            If numero Mod 2 = 0 AndAlso numero <> 16 AndAlso numero Mod 3 <> 0 Then\n                Console.WriteLine(numero)\n            End If\n        Next\n\n    End Sub\nEnd Module\n"
  },
  {
    "path": "Roadmap/01 - OPERADORES Y ESTRUCTURAS DE CONTROL/zig/edalmava.zig",
    "content": "const std = @import(\"std\");\nconst print = std.debug.print;\n\npub fn main() void {\n    // Sentencia if\n    var x: i32 = 0;\n    if (true) { // La condición debe ser una expresión que se evalue como true o false si no genera un error en compilación\n        x = 1;\n    } else {\n        x = 2;\n    }\n    print(\"{}\\n\", .{x});\n\n    // Sentencia if como expresión\n    const a = true;\n    x = 0;\n    x += if (a) 1 else 2;\n    print(\"{}\\n\", .{x});\n\n    // Bucle while: una condición, un bloque y una expresión de continuación\n    // Sin una expresión de continuación\n    var i: u8 = 2;\n    while (i < 100) { // La condición se debe evaluar como true o false\n        i *= 2;\n    }\n    print(\"{}\\n\", .{i}); // Se espera 128\n    // Con una expresión continua\n    var sum: u8 = 0;\n    i = 1;\n    while (i <= 10) : (i += 1) {\n        sum += i;\n    }\n    print(\"{}\\n\", .{sum}); // Se espera 55\n    // while con continue\n    sum = 0;\n    i = 0;\n    while (i <= 3) : (i += 1) {\n        if (i == 2) continue;\n        sum += i;\n    }\n    print(\"{}\\n\", .{sum}); // Se espera 4\n    // while con break\n    sum = 0;\n    i = 0;\n    while (i <= 3) : (i += 1) {\n        if (i == 2) break;\n        sum += i;\n    }\n    print(\"{}\\n\", .{sum}); // Se espera 1\n\n    // Bucle for\n    // Para iterar matrices y otros tipos\n    // Se puede usar continue y break como en while\n    // Los literales caracter son equivalentes a literales enteros\n    const string = [_]u8{ 'a', 'b', 'c' };\n\n    for (string, 0..) |character, index| {\n        //_ = character;  // Como Zig no deja tener valores sin utilizar se usa el _\n        //_ = index;      // Como Zig no deja tener valores sin utilizar se usa el _\n\n        print(\"Índice: {} - Caracter: {c}\\n\", .{ index, character });\n    }\n\n    // RETO EXTRA\n    print(\"\\n\\n***RETO EXTRA***\\n\\n\", .{});\n    i = 10;\n    while (i <= 55) : (i += 1) {\n        if (i % 2 == 0 and i != 16 and i % 3 != 0) {\n            print(\"{}\\n\", .{i});\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/arduino/santyjL.ino",
    "content": "//#02 --- FUNCIONES Y ALCANCE//\n\n/*\n*recordatorio , el lenguaje arduino esta hecho para usarlo con las placas del\n*mismo nombre y para probar este codigo se requiere utilizar un arduino para el\n*ensendido y apagado de la led del pin 13 recomendado probar los codigos\n*en el IDE propio de arduino , para ver los resultados se utiliza el ,\n*monitor seria\n*/\n\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n\n// Declaración de una variable global 'led' que representa el pin 13.\nint led = 13;\n\nvoid setup() {\n  // Inicialización de la comunicación serial a 9600 bps.\n  Serial.begin(9600);\n\n  // Llamada a la función 'holaMundo' y muestra un divisor antes y después de la llamada.\n  printDivider(\"Hola Mundo\");\n  holaMundo();\n\n  // Llamada a la función 'Saludo', muestra un divisor y luego imprime el resultado.\n  printDivider(\"Saludo\");\n  String saludo = Saludo();\n  Serial.println(saludo);\n\n  // Llamada a la función 'suma', muestra un divisor y luego imprime el resultado.\n  printDivider(\"Suma\");\n  suma(5, 3);\n\n  // Llamada a la función 'resta', muestra un divisor y luego imprime el resultado.\n  printDivider(\"Resta\");\n  int resultadoResta = resta(8, 3);\n  Serial.println(resultadoResta);\n\n  // Llamada a la función 'funcionesDelLenguaje', muestra un divisor y realiza operaciones con el lenguaje Arduino.\n  printDivider(\"Funciones del Lenguaje\");\n  funcionesDelLenguaje();\n\n  // Llamada a la función 'ensendidoApagado', muestra un divisor y realiza un ejemplo de encendido y apagado.\n  printDivider(\"Encendido y Apagado\");\n  ensendidoApagado();\n\n  // Llamada a la función 'printNumbers', muestra un divisor y realiza la lógica descrita en los comentarios.\n  printDivider(\"Print Numbers\");\n  printNumbers(\"Fizz\", \"Buzz\");\n}\n\nvoid loop(){\n  // El bucle principal. Puede estar vacío ya que la lógica principal se realiza en el 'setup'.\n}\n\n// Función para imprimir un divisor con el nombre de la función.\nvoid printDivider(String functionName) {\n  Serial.println(\"----------\" + functionName + \"----------\");\n}\n\n// Función 'holaMundo' que imprime \"Hola Mundo\".\nvoid holaMundo() {\n  Serial.println(\"Hola Mundo\");\n}\n\n// Función 'Saludo' que retorna una cadena de texto.\nString Saludo() {\n  return \"Hola Mundo\";\n}\n\n// Función 'suma' que recibe dos parámetros, los suma e imprime el resultado.\nvoid suma(int num1, int num2) {\n  Serial.println(\"Suma: \" + String(num1 + num2));\n}\n\n// Función 'resta' que recibe dos parámetros, realiza la resta y retorna el resultado.\nint resta(int num1, int num2) {\n  return num1 - num2;\n}\n\n// Función 'funcionesDelLenguaje' que realiza operaciones comunes del lenguaje Arduino.\nvoid funcionesDelLenguaje() {\n  // Configuración del pin 'led' como salida.\n  pinMode(led, OUTPUT);\n  // Enciende el pin 'led' durante 1 segundo.\n  digitalWrite(led, HIGH);\n  delay(1000);\n  // Apaga el pin 'led' durante 1 segundo.\n  digitalWrite(led, LOW);\n}\n\n// Función 'ensendidoApagado' que realiza el ejemplo de parpadeo (blink).\nvoid ensendidoApagado() {\n  int espera = 250;\n\n  // Ciclo que enciende y apaga el pin 'led' en un patrón.\n  for (int i = 0; i < 30; i++) {\n    digitalWrite(led, HIGH);\n    delay(espera);\n    digitalWrite(led, LOW);\n    delay(espera);\n  }\n}\n\n// Función 'printNumbers' que imprime números según ciertas condiciones y cuenta el número de impresiones.\nvoid printNumbers(String text_1, String text_2) {\n  int count = 0;\n  // Ciclo que itera sobre los números del 1 al 100.\n  for (int number = 1; number <= 100; ++number) {\n    // Verifica si el número es múltiplo de 3 y/o 5 y realiza la impresión correspondiente.\n    if (number % 3 == 0 && number % 5 == 0) {\n      Serial.println(text_1 + text_2);\n    } else if (number % 3 == 0) {\n      Serial.println(text_1);\n    } else if (number % 5 == 0) {\n      Serial.println(text_2);\n    } else {\n      Serial.println(number);\n      count++;\n    }\n  }\n  // Imprime el número total de veces que se ha impreso un número.\n  Serial.print(\"Count: \");\n  Serial.println(count);\n}\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/bash/angelsanchezt.sh",
    "content": "#!/bin/bash\n\n\n# Ejemplo 1: Función sin parámetros ni retorno\nfunction funcionSinParametrosNiRetorno() {\n  echo \"Esta es una función sin parámetros ni retorno.\"\n}\n\nfuncionSinParametrosNiRetorno\n\n# Ejemplo 2: Función con parámetros\nfunction funcionConParametros() {\n  echo \"Esta función tiene $# parámetros: $@\"\n}\n\nfuncionConParametros \"ANGEL\" \"JAVIER\" \"SANCHEZ\"\n\n# Ejemplo 3: Función con retorno\nfunction funcionConRetorno() {\n  resultado=$((2 + 2))\n}\n\nfuncionConRetorno\necho $resultado\n\n# Ejemplo 4: Función con variables locales y globales\nvariableGlobal=\"Soy global\"\n\nfunction funcionConVariables() {\n  local variableLocal=\"Soy local\"\n  echo \"Desde la función: $variableGlobal, $variableLocal\"\n}\n\n# Ejemplo 5: Llamadas a funciones y variables\necho \"Ejemplo 1:\"\nfuncionSinParametrosNiRetorno\n\necho -e \"\\nEjemplo 2:\"\nfuncionConParametros \"Hola\" \"Mundo\" \"!\"\n\necho -e \"\\nEjemplo 3:\"\nfuncionConRetorno\necho \"El resultado de la función con retorno es: $?\"\n\necho -e \"\\nEjemplo 4:\"\nfuncionConVariables\necho \"Desde fuera de la función: $variableGlobal\"\n\n# Dificultad Extra: Función con múltiples condiciones y retorno de conteo\nfunction funcionExtra() {\n  parametro1=$1\n  parametro2=$2\n  \n  for i in $(seq 1 100); do\n    if [ $(($i % 3)) -eq 0 ] && [ $(($i % 5)) -eq 0 ]; then\n        echo $i \"Es\" $parametro1 \"y es \"$parametro2\n    elif [ $(($i % 3)) -eq 0 ]; then\n        echo $i \"Es\" $parametro1 \n    elif [ $(($i % 5)) -eq 0 ]; then\n        echo $i \"Es\" $parametro2\n    else\n        let \"contador +=1\"\n        echo $i\n    fi\n  done\n\n  echo \"Hay \"$contador \"números que no son\" $parametro1 \"ni\" $parametro2\n\n  return $contador\n}\n\n# Ejemplo 6: Llamada a función con múltiples condiciones y retorno de conteo\necho -e \"\\nDificultad Extra:\"\nfuncionExtra \"Multiplo 3\" \"Multiplo 5\"\necho \"Número de veces que se imprimió: $?\"\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/bash/arturonavas.sh",
    "content": "#!/bin/bash\n: '\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n'\n\n# funciones basicas!!!\n\n# sin parametros ni retorno\nsaludar() {\n  echo \"hola mundo!\"\n}\n\n# con un parametro\nsaludar_nombre() {\n  local nombre=\"$1\"\n  echo \"hola $nombre\"\n}\n\n# con varios parametros\nsumar() {\n  local a=\"$1\"\n  local b=\"$2\"\n  echo \"suma:\" \"$(( a + b ))\"\n}\n\n# con retorno\ncuadrado() {\n  local n=\"$1\"\n  echo \"$(( n * n ))\"\n}\n\n# funciones dentro de funciones , se puede declarar pero no invocar antes de declararla\n\nexterna() {\n  echo \"soy funcion externa\"\n  interna() {\n    echo \"soy funcion interna\"\n  }\n  interna\n}\n\n\n# variables local y global\n\nglobal=\"soy global\"\n\nvariable_scope() {\n  local localvar=\"soy local\"\n  echo \"dentro de la funcion: $localvar\"\n  echo \"dentro de la funcion: $global\"\n}\n\n# dificultad extra\n\nimpr_num() {\n  local palabra1=\"$1\"\n  local palabra2=\"$2\"\n  local contador=0\n\n  for (( i=1; i<=100; i++ )); do\n    if (( i % 3 == 0 && i % 5 == 0 )); then\n      echo \"$palabra1$palabra2\"\n    elif (( i % 3 == 0 )); then\n      echo \"$palabra1\"\n    elif (( i % 5 == 0 )); then\n      echo \"$palabra2\"\n    else\n      echo \"$i\"\n      ((contador++))\n    fi\n  done\n\n  echo \"veces que se imprimieron numeros: $contador\"\n  return $contador\n}\n\n#pruebas\n\necho \"::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\"\nsaludar\nsaludar_nombre \"bash\"\nsumar 5 7\necho \"cuadrado de 4:\" \"$(cuadrado 4)\"\nexterna\nvariable_scope\necho \"fuera de la funcion (global): $global\"\necho \"::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\"\nimpr_num \"fizz\" \"buzz\"\necho \"::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\"\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/bash/drvito1977.sh",
    "content": "#!/bin/bash\n# Esta línea indica que el script debe ser interpretado por Bash\n\n# Función sin parámetros ni retorno\nfunction sin_parametros_ni_retorno {\n  # Imprime un mensaje indicando que esta función no tiene parámetros ni retorno\n  echo \"Función sin parámetros ni retorno\"\n}\n\n# Función con un parámetro\nfunction con_un_parametro {\n  # $1 es el primer parámetro pasado a la función\n  echo \"Función con un parámetro: $1\"\n}\n\n# Función con varios parámetros\nfunction con_varios_parametros {\n  # $1, $2, y $3 son los primeros tres parámetros pasados a la función\n  echo \"Función con varios parámetros: $1, $2, $3\"\n}\n\n# Llamada a la función sin parámetros ni retorno\nsin_parametros_ni_retorno\n\n# Llamada a la función con un parámetro\ncon_un_parametro \"Hola\"\n\n# Llamada a la función con varios parámetros\ncon_varios_parametros \"Uno\" \"Dos\" \"Tres\"\n\n# Definición de la función 'fa' anidada\nfunction fa {\n\t# Imprime un mensaje indicando que se está llamando a la función 'fa'\n\techo \"Llamando a la función anidada, fa\"\n\t\n\t# Definición de la función interna 'fu' dentro de 'fa'\n\tfunction fu {\n\t\t# Imprime un mensaje indicando que se está llamando a la función 'fu'\n\t\techo \"Llamando a la función interna, fu\"\n\t}\n\t\n\t# Llama a la función interna 'fu' dentro de la función 'fa'\n\tfu\n}\n\n# Llama a la función 'fa'\nfa\n\n# Calcula el factorial de 'n' usando un bucle while\nfunction factorial {\n  local n=$1\n  local result=1\n  while [ $n -gt 1 ]; do\n    result=$((result * n))\n    ((n--))\n  done\n  # Devuelve el resultado del factorial\n  echo $result\n}\nfactorial 5 # Llama a la función 'factorial' con el argumento 5\n\n# Función que recibe dos parámetros de tipo cadena de texto y retorna un número\nfunction imprimir_numeros {\n  local cadena1=$1\n  local cadena2=$2\n  local contador=0\n\n  for ((i=1; i<=100; i++)); do\n    if ((i % 3 == 0 && i % 5 == 0)); then\n      echo \"${cadena1}${cadena2}\"\n    elif ((i % 3 == 0)); then\n      echo \"$cadena1\"\n    elif ((i % 5 == 0)); then\n      echo \"$cadena2\"\n    else\n      echo \"$i\"\n      ((contador++))\n    fi\n  done\n\n  # Retorna el número de veces que se ha impreso el número en lugar de los textos\n  return $contador\n}\n\n# Llamada a la función 'imprimir_numeros' con los parámetros \"Fizz\" y \"Buzz\"\nimprimir_numeros \"Fizz\" \"Buzz\"\n# Captura el valor de retorno de la función\ncontador=$?\necho \"El número de veces que se ha impreso el número en lugar de los textos es: $contador\"\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/bash/rantamhack.sh",
    "content": "#!/bin/bash\n\necho \"==================== FUNCION SIN RETORNO NI ARGUMENTOS ====================\"\n\nfunction hola_mundo(){\n    echo \"Hola mundo!!\"\n}\nhola_mundo\necho \"===4================= FUNCION CON UN ARGUMETO SIN RETORNO ====================\"\n\nfunction hola_lenguaje(){\n    echo \"Hola mundo!! mi lenguaje de programación favorito es $1\"\n}\nhola_lenguaje \"Bash\"\n\necho \"==================== FUNCION CON DOS ARGUMENTOS SIN RETORNO ====================\"\n\nfunction presentacion(){\n    echo \"Hola mundo!! soy $1 y mi lenguaje de programación favorito es $2\"\n}\npresentacion \"rantamplan\" \"Bash\" \n\necho \"==================== FUNCION CON DOS ARGUMETOS CON RETORNO ====================\"\n\nfunction publicacion(){\n\n    edad=$(( 2024-$1 ))\n    echo \"El lenguaje $2 se publicó en el año $1\"\n    if [ $edad -ge 18 ]; then\n        echo \"El lenguaje $2 es mayor de edad, tiene $edad años\" \n        return 0\n\n# Se puede usar tanto return como exit para indicar el codigo de estado de salida    \n\n    else\n        echo \"El lenguaje $2 es aún muy reciente, tiene $edad años\"\n        exit 1    \n    fi\n}\npublicacion 1989 \"Bash\"\n\necho \"==================== FUNCION DENTRO DE OTRA FUNCION ====================\"\n# Función dentro de func\nfunction potencia(){\n        result=$(( $1**$2 ))\n        echo \"El resultado del numero\" $1 \"elevado a la potencia\" $2 es $result \n        function interior(){\n            final=$(( \"$result\" * \"$1\" ))\n            echo \"El resultado de las funciones es\" $final\n    }\n    interior 2\n     \n}\npotencia 10 3\n\necho \"==================== FUNCION PROPIA DE BASH ====================\"\n\nfunction num_aleatorio(){\n    echo \"Crear un numero aleatorio menor que 100\"\n    echo -e \"El número que ha salido es:\" $(( $RANDOM % 100 ))\n}\nnum_aleatorio\n\necho \"==================== VARIABLES GLOBALES Y LOCALES ====================\"\n# En Bash de entrada todas las variable son globales pues se pueden leer desde cualquier lugar \n# de un script esten dentro o fuera de una función\n# Para que una variable sea considerada local se debe declarar dentro de una función y con la\n# palabra local delante del nombre\n\nvar1=\"A\"  # Variable global\n\nfunction variables(){\n    local var2=\"B\"  # Variable local\n    echo \"El valor de la variable var1 es:\"$var1 \"y el de var2 es: \"$var2\n}\nvariables\necho \"El valor de la variable var1 es:\"$var1 \"y el de var2 es: \"$var2\n# En ésta impresión no aparece el valor de $var2 porque no la reconoce al estar fuera de la función\n\n\necho \"==================== EJERCICIO EXTRA ====================\"\n\ntext1=\"multiplo de 3\"\ntext2=\"multiplo de 5\"\n\nfunction num_impress(){\n    contador=0\n    for i in $(seq 1 100); do\n        if [ $(($i % 3)) -eq 0 ] && [ $(($i % 5)) -eq 0 ]; then\n            echo $i \"Es\" $text1 \"y es \"$text2\n        elif [ $(($i % 3)) -eq 0 ]; then\n            echo $i \"Es\" $text1 \n        elif [ $(($i % 5)) -eq 0 ]; then\n            echo $i \"Es\" $text2\n        else\n            let \"contador +=1\"\n            echo $i\n        fi\n    done\n    echo \"Hay \"$contador \"números que no son\" $text1 \"ni\" $text2\n}\nnum_impress text1 text2"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/bash/santyjL.sh",
    "content": "# !/bin/bash\n\n# #02 FUNCIONES Y ALCANCE\n#### Dificultad: Fácil | Publicación: 08/01/24 | Corrección: 15/01/24\n\n## Ejercicio\n\n: \"\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\"\n\nfunction sin_parametros() {\n    echo \"Esta es una función sin parámetros ni retorno\"\n}\n\nsin_parametros\n\nfunction con_parametros(){\n    local primer_parametro=$1       # se definen paramtros por su orden de entrada, guardar en variable es una buena practica\n    local segundo_parametro=$2\n\n    echo \"Esta es una función con parámetros: $primer_parametro y $segundo_parametro\"\n}\ncon_parametros \"Hola\" \"Mundo\"\n\nfunction con_retorno_y_parametros() {\n    local a=$1\n    local b=$2\n    local resultado=$((a+b))  # Suma de los dos parámetros\n    return $((resultado/10))  # Retorna el resultado de la suma\n}\n\ncon_retorno_y_parametros 30 10\nresultado=$?  # Captura el valor retornado por la función\necho \"El resultado de la suma es: $resultado\"\n\nfunction funcion_dentro_de_funcion() {\n\n    function interior(){\n        echo \"Esta es una función dentro de otra función\"\n    }\n    interior\n}\n\nfuncion_dentro_de_funcion\n\n### Función ya creada en Bash\n\necho \"El número aleatorio generado es: $(($RANDOM % 100)) \"\npwd  # Imprime el directorio de trabajo actual\nexport KEY=\"1234absc\"\nunset KEY  # Elimina la variable de entorno KEY\ntype pwd echo export read funcion_dentro_de_funcion # Muestra información sobre los comandos y funciones\n\n### Variables globales y locales\nvar_global=\"Soy una variable global\"\nfunction funcion_con_variable_local() {\n    local var_local=\"Soy una variable local\"\n    echo \"Dentro de la función: $var_global y $var_local\"\n}\nfuncion_con_variable_local\necho \"Fuera de la función: $var_global\"\n\n# La variable local no es accesible fuera de la función\necho \"Intentando acceder a la variable local fuera de la función: $var_local\"  # Esto dará un error porque var_local no está definida aquí\n\n### Dificultad extra\n\nfunction fizz_buzz() {\n    local texto1=$1\n    local texto2=$2\n    local no_textos_cant=0\n\n    for i in {1..100}; do\n        if [[ $((i % 3)) == 0 && $((i % 5)) == 0 ]]; then\n            echo \"$i==$texto1:::$texto2\"\n\n        elif [[ $((i % 3)) == 0 ]]; then\n            echo \"$i==$texto1\"\n\n        elif [[ $((i % 5)) == 0 ]]; then\n            echo \"$i==$texto2\"\n\n        else\n            echo $i\n            let \"no_textos_cant+=1\" #si no lleva let lo identifica como un string y no como un numero\n        fi\n    done\n\n    return $no_textos_cant\n\n}\n\nfizz_buzz \"fizz\" \"buzz\"\ncantidad_de_numeros=$?\necho \"Cantidad de números que no son ni fizz ni buzz: $cantidad_de_numeros\"\necho \"Fin del script\""
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c/04khaos.c",
    "content": "#include <stdio.h>\n\n\n// Prototipo de las funciones (declaraciones)\n\nvoid hi(void);                       // Función sin parámetros (void) ni retorno \"void\"\nvoid hi_user(char name[]);           // Función con parámetros (char name[]) y sin retorno \"void\"\nint sum(int a, int b);               // Función con parámetros y con retorno\nfloat calculate(int radio);          // Función para calcular el área del círculo\n\nint extra(char str1[], char str2[]); // Función para la dificultad extra\n\n// Variable global\nconst float PI = 3.141592; // PI como constante\n\n/* 1. BASIC FUNCTIONS\n      - En C, generalmente no se pueden definir funciones dentro de otras funciones.\n        Sin embargo, las funciones definidas fuera de main() pueden ser llamadas dentro de main()\n      - Este ejemplo trabaja con funciones predefinidas que forman parte de\n        las bibliotecas estándar de C, como printf de <stdio.h> */\n\nint main(void) {\n    printf(\"== Basic Functions ==\\n\");\n\n    // Call functions from main()\n    hi();                           // Calls hi()\n    hi_user(\"Khaos\");               // Calls hi_user()\n\n    int result = sum(6, 9);         // sum() is called with 6 and 9 as arguments\n    printf(\"The result of the sum is %d\\n\", result);\n\n    int radio = 10; // Variable local\n    float circle_area = calculate(radio); // calculate() is called with the radio parameter set to 10\n    printf(\"The circle area is %.2f cm^2\\n\\n\", circle_area); // \"%.2f\" instead of \"%f\" will round to 2 decimal places\n\n    // Dificultad extra\n    int count = extra(\"three\", \"five\"); // Call function with parameters from two text strings\n    printf(\"\\n%d numbers were printed instead of text\\n\\n\", count);\n}\n\n// Definiciones de las funciones (implementaciones)\n\n\n// Print a generic greeting message\nvoid hi(void) {\n    printf(\"Hello there.\\n\");\n}\n\n\n// Print a personalized welcome message with the name received\nvoid hi_user(char name[]) {\n    printf(\"Welcome, %s\\n\", name);\n}\n\n\n/* Receives two integers as parameters and returns their sum.\n   The values ​​of 'a' and 'b' will depend on the arguments passed when calling the function. */\nint sum(int a, int b) {\n    return a + b;\n}\n\n\n//  Function calculate() receives the value of radio (10) as parameter\nfloat calculate(int radio) {\n    return PI * radio * radio; // Calculate the area of ​​a circle\n    // It doesn't print the result, it just calculates it and returns it.\n}\n\n\n\n/* 2. EXTRA DIFFICULTY\n      - Imprime los números del 1 al 100, reemplazando los múltiplos de 3 y 5 por textos personalizados.\n        Devuelve la cantidad de números que fueron impresos en lugar de los textos/múltiplos. */\n\nint extra(char str1[], char str2[]) {\n    printf(\"== Extra difficulty ==\\n\");\n\n    int printed_numbers = 0; // Counter of times a number is printed instead of text\n\n    for (int i = 1; i <= 100; i++) {\n\n        // If the number is a multiple of 3 and 5, print both strings concatenated\n        if ( i % 3 == 0 && i % 5 == 0) {\n            printf(\"%d is a multiple of %s and %s\\n\", i, str1, str2);\n\n        } else if (i % 3 == 0) {\n            printf(\"%d is a multiple of %s\\n\", i, str1);\n\n        } else if (i % 5 == 0) {\n            printf(\"%d is a multiple of %s\\n\", i, str2);\n\n        } else {\n            // If the number is not a multiple of either 3 or 5, print the number and counted\n            printf(\"%d\\n\", i);\n            printed_numbers++; // Incremented only when a number is printed\n        }\n    }\n    //Returns the number of numbers that were printed (not multiples of 3 or 5)\n    return printed_numbers;\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c/Aldroide.c",
    "content": "/*\nEjercicio: Crear ejemplos de funciones basicas que representen diferentes\nposiblidades del lenguaje:\n    * Sin parametros ni retorno\n    * Con uno o mas parametros,\n    * Con retorno\n    * Probar funciones dentro de funciones\n    * Utilizar funciones ya creadas del lenguaje\n    * Variable local y global\n    * Debes hacer print por consola del resultado de todos los ejemplos.\n    * (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n*/\n#include <stdio.h>\nint EjercicioExtra (const char* param1, const char* param2);\nvoid Simple(){\n    printf(\"Funcion sin parametros ni retorno\");\n}\n\nvoid param(char name[]){\n    printf(\"\\nFuncion que recibe tu nombre: %s pero no tiene retorno\\n\",name);\n}\n\nint suma(int a, int b){\n    return a+b;\n}\nint i=10;\nint main(){\n    int local=90;\n    Simple();\n    param(\"Aldo\");\n    printf(\"El resultado de 4 + 6 es: %d\\n\",suma(4,6));\n    printf(\"Se imprimieron %d numeros\\n\", EjercicioExtra(\"Parametro1\", \"Parametro2\"));\n    printf(\"Variable global %d\\n\",i);\n    printf(\"%d elevado a 2 es: %f\\n\",i,exp2(i));\n    printf(\"Variable local %d\",local);\n    return 0;\n}\n\n/*\n* DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\nint EjercicioExtra (const char* param1, const char* param2){\n    int numVeces = 0;\n    for (int i = 1; i <= 100; i++){\n        if (i % 15 == 0){\n            printf(\"%s%s\", param1, param2);\n        } else if (i % 3 == 0){\n            printf(\"%s\", param1);\n        } else if (i % 5 == 0){\n            printf(\"%s\", param2);\n        } else {\n            printf(\"%d\", i);\n            numVeces++;\n        }        \n        printf(\"\\n\");\n    }\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c/DjSurgeon.c",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n// Funciones básicas del sistema\n\n#include <stdio.h>\n\n// Función que no devuelve nada (void) y sin parametros.\n\nvoid texto() {\n  printf(\"Esto es un churro de texto.\\n\");\n  printf(\"Esta funcion no tiene parametros.\\n\");\n  printf(\"Y no devuelve nada, por eso es void.\\n\");\n}\n\n// Función con un parametro, pero sin retorno.\n\nvoid imprimeNumero(int num) {\n  printf(\"El parametro ingresado es: %d.\\n\", num);\n}\n\n// Función con varios parametros, sin retorno.\n\nvoid sumaNumeros(int num1, int num2) {\n  printf(\"La suma de %d y %d es igual a: %d.\\n\", num1, num2, num1 + num2);\n}\n\n// Funcion con parametro y que retorna un int.\n\nint multiplicacion(int num1, int num2) {\n  return num1 * num2;\n}\n\n// Funcion con parametros que retorna un float.\n\nfloat division(float num1, float num2) {\n  return num1 / num2;\n}\n\n// Funcion que retorna un char.\n\nchar primerCaracter(char *cadena) {\n  return cadena[0];\n}\n\n// Variables Globales y Locales\n// Variables Globales: Las variables globales se definen fuera de cualquier función y son accesibles desde cualquier función en el archivo.\n\nchar saludo[] = \"Hola mundo\";\n\n// Variables loclaes: Las variables locales se definen dentro de una función y solo son accesibles dentro de esa función.\n\nvoid saludar() {\n  char saludoLocal[] = \"Hola que ase\";\n  printf(\"Variable local: '%s'\\n\", saludoLocal);\n}\n\n// Extra ==================\n\nvoid funcionExtra(char* cadena1, char* cadena2) {\n  int contador = 0;\n  for (int i=1; i <= 100; i++) {\n    if(i % 3 == 0 && i % 5 == 0) {\n      printf(\"%s%s\\n\", cadena1, cadena2);\n    }\n    else if (i % 5 == 0) {\n      printf(\"%s\\n\", cadena2);\n    }\n    else if (i % 3 == 0) {\n      printf(\"%s\\n\", cadena1);\n    }\n    else {\n      printf(\"%i\\n\", i);\n      contador++;\n    }\n  }\n  printf(\"Numero de numeros: %i\\n\", contador);\n\n}\n\n/* =============================================================== */\nint main() { // Esta funcion es la base de C y a partir de aqui es donde empieza el desarrollo del sistema.\n// Dentro de main no se pueden crear funciones solo se pueden invocar.\n\ntexto();\nimprimeNumero(10);\nsumaNumeros(5,8);\n\nprintf(\"El resultado de multiplicar 5 * 3 es: %d.\\n\", multiplicacion(5,3));\n// Se puede almacenar el resultado tb en una variable.\n\nint resultadoMultplicacion = multiplicacion(10, 3);\nprintf(\"El resultado de multiplicar 10 * 3 es: %d.\\n\", resultadoMultplicacion);\n\nprintf(\"El resultado de la división 123 entre 23 es: %.4f\\n\", division(123,23));\n\nprintf(\"El primer caractér de 'Hola' es: %c.\\n\", primerCaracter(\"Hola\"));\n\nprintf(\"Variable global: '%s'\\n\", saludo);\nsaludar();\n\n// Extra ==============\nfuncionExtra(\"hola\", \"mundo\");\n\nreturn 0;\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c/FullOvellas.c",
    "content": "#include <stdint.h>\n#include <stdio.h>\n#include <stdbool.h>\n#include <math.h>\n\n/* Opcional: función que recibe dos cadenas de texto y\n *     - Imprime los números del 1 al 100 pero:\n *         - Si el número es múltiplo de 3 se imprime el primer parámetro\n *         - Si el número es múltiplo de 5 se imprime el segundo parámetro\n *         - Si el número es múltiplo de 3 y 5 se muestran ambas cadenas concatenadas\n *     - Devuelve el número de veces que se mostró el número en lugar de un texto\n */\nint my_fun(const char *first_param, const char *second_param) {\n    int count = 0;\n    for (int32_t i = 1; i <= 100; i++) {\n        _Bool div_by_3 = i % 3 == 0;\n        _Bool div_by_5 = i % 5 == 0;\n        if (div_by_3) {\n            printf(\"%s\", first_param);\n        }\n        if (div_by_5) {\n            printf(\"%s\", second_param);\n        }\n        \n        if (div_by_3 || div_by_5) {\n            printf(\"\\n\");\n            continue;\n        }\n        \n        printf(\"%i\\n\", i);\n        count++;\n    }\n\n    return count;\n}\n\nchar higher_val_char(char c1, const char c2) {\n    return c1 > c2 ? c1 : c2;\n}\n\nvoid say_hi() {\n    puts(\"Hola!\");\n}\n\nvoid say_hi_to_user(char *user_name) {\n    if (user_name[0] == 0) {\n        puts(\"Hola, Usuario\");\n    } else {\n        printf(\"Hola, %s\\n\", user_name);\n    }\n}\n\nconst double PI = 3.141593;\n\nint main() {\n    printf(\"Char de valor más alto ('a', 'b')? %c\\n\", higher_val_char('a', 'b'));\n    say_hi();\n    say_hi_to_user(\"\");\n    char user_name[] = \"FullOvellas\";\n    say_hi_to_user(user_name);\n\n    // Variable global\n    printf(\"Variable global: %f\\n\", PI);\n\n    // Función del lenguaje\n    printf(\"%f elevado a 2 es: %f\\n\", 2.0, exp2(2.0));\n\n    int32_t x = 10;\n    printf(\"Variable `x` en scope local: %i\\n\", x);\n    {\n        int32_t x = 32;\n        printf(\"Variable `x` en scope local anidado: %i\\n\", x);\n    }\n    printf(\"Variable `x` sigue teniendo el valor anterior (%i) fuera del scope anidado\\n\", x);\n\n    printf(\"Resultado de la función opcional: %i\\n\", my_fun(\"Hola\", \", C\"));\n\n    return 0;\n}\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c/Gallitofast.c",
    "content": "#include <stdio.h>\n#include <stdlib.h>\n\n//Aqui declaro todas las funciones que usaremos despues en el main\nvoid hi(void);                       // Función sin parámetros ni retorno \nvoid hi_user(const char name[]);     // Función con parámetros pero  sin retorno \nint sum(int a, int b);               // Función con parámetros y con retorno\nfloat calculate(int radio);          // Función para calcular el área del círculo\n//Aqui la funcion de difiicultad extra\nint extra(const char str1[], const char str2[]);\n//Variable global de pi\nconst float PI = 3.141592;\n\nint main(void){\nprintf(\"---Funciones Basicas---\\n\");\n//Llamamos a las funciones desde el main\nhi();                           // Llamamos a la funcion hi\nhi_user(\"Gallitofast\");               // Llamamos a la funcion hi_user\nint result = sum(125, 245);         // Llamamos a la funcion sum con 125 y 245 como argumentos\nprintf(\"El resultado de la suma es %d\\n\", result); // Imprimimos el resultado de la suma\nint radio = 10; // Variable local\nfloat circle_area = calculate(radio); // Llamamos a la funcion calculate con el radio como argumento\nprintf(\"El area del circulo es %.2f cm^2\\n\\n\", circle_area); // Imprimimos el area del circulo\n//Dificultad extra\nint count = extra(\"tres\", \"cinco\"); // Llamamos a la funcion extra con dos cadenas de texto\nprintf(\"\\nSe imprimieron %d numeros en vez de texto\\n\\n\", count); // Imprimimos el resultado de la dificultad extra \n\n\n}\n//Afuera del main definimos las funciones\n//Imprimimos un saludo generico\nvoid hi(void){\n    printf(\"Hola.\\n\");\n}\n//Imprimimos un saludo personalizado con el nombre recibido\nvoid hi_user(const char name[]){\n    printf(\"Bienvenido, %s\\n\", name);\n}\n//Recibimos dos enteros como parametros y retornamos su suma\nint sum(int a, int b){\n    return a + b;\n}\n//Recibimos el radio como parametro y retornamos el area del circulo\nfloat calculate(int radio){\n    return PI * radio * radio; // Area del circulo\n}\n//Recibimos dos cadenas de texto como parametros y retornamos la cantidad de numeros que se imprimieron\nint extra(const char str1[], const char str2[]){\n    int count = 0; // Contador de numeros\n    for (int i = 1; i <= 100; i++) {\n\n        // If the number is a multiple of 3 and 5, print both strings concatenated\n        if ( i % 3 == 0 && i % 5 == 0) {\n            printf(\"%d is a multiple of %s and %s\\n\", i, str1, str2);\n\n        } else if (i % 3 == 0) {\n            printf(\"%d is a multiple of %s\\n\", i, str1);\n\n        } else if (i % 5 == 0) {\n            printf(\"%d is a multiple of %s\\n\", i, str2);\n\n        } else {\n            // If the number is not a multiple of either 3 or 5, print the number and counted\n            printf(\"%d\\n\", i);\n            count++; // Incremented only when a number is printed\n        }\n    }\n    //Returns the number of numbers that were printed (not multiples of 3 or 5)\n    return count;\n}\n//Fin del programa\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c/JustOrlo.c",
    "content": "#include <stdio.h>\r\n#include <math.h> //Para hacer uso de la Funcion Pow\r\n#include <stdbool.h>\r\n#include <string.h>\r\n\r\n/*Declaracioin de Funciones*/\r\nvoid Introduccion(); //Funcion de Tipo Void, Sin Parametro y sin retorno\r\nint Bit_Convert(int); //Funcion con retorno y con Parametros de entrada\r\nvoid Mostrar(int); //Funcion sin retorno y con parametros de entrada\r\nvoid Funcion_en_Funcion(); //Funcion para probar si es posible Crear Funcione dentro de Funciones\r\nint Desafio(char[] , char[] );\r\n\r\n/*Declaracion de Variables Globales*/\r\nint arr[7] = {0,0,0,0,0,0,0}; \r\n\r\nint main(){\r\n\r\n    /*Declaracion de variables locales*/\r\n    char txt1[] = \"MultiploX3\";\r\n    char txt2[] = \"MultiploX5\";\r\n    int a, b, c;\r\n    a = 27;\r\n    b = 114;\r\n    c = 38;\r\n\r\n    /*Uso de la Funcion Introducion*/\r\n    Introduccion(); \r\n    \r\n    /*Funcion Main*/\r\n    printf(\"---->Funcion Main<----\\n\\n\");\r\n    printf(\"NOTA: La Funcion main, es la fncion principal de todo Programa en C...\\n\\n\\n\");\r\n\r\n    /*Uso de la Funcion Mostrar*/\r\n    printf(\"\\t-->Ejemplo de Funcion Con parametro de Entrada y sin retorno<--\\n\\n\");\r\n    printf(\"\\t NOTA: Esta Funcion toma tres numero (0 - 127) y lo escribe en binario y ademas muestra su segunda potencia.\\n\\n\");\r\n    printf(\"Numero\\t\\t\\t Bits\\t\\t\\t Potencia\\n\\n\");\r\n    \r\n    Mostrar(a);    \r\n    Mostrar(b);\r\n    Mostrar(c);\r\n\r\n    /*Uso de la Funcion Funcion_en_Funcion*/\r\n    printf(\"\\t-->Es Posible Crear funciones detro de Funciones?<--\\n\\n\\n\");\r\n    Funcion_en_Funcion();\r\n\r\n    /*Desafio*/\r\n    printf(\"\\t-->Desafio!!!<--\\n\\n\");\r\n    printf(\"\\n La cantidad de numeros no divisibles entre 3 y/o 5 es: %d\\n\\n\\n\", Desafio(txt1,txt2));\r\n    \r\n\r\n}\r\n\r\nvoid Introduccion(){\r\n    \r\n    printf(\"\\t\\t---->Funciones<----\\n\\n\");\r\n\r\n    /*Sintaxis de una Funcion*/\r\n\r\n    /*Declaracion*/\r\n    printf(\"-->Declaracion<--\\n\\n\");\r\n    printf(\"Typ_Return Nombre_Funcion(Typ_param Var, etc){\\n\");\r\n    printf(\"\\t /*Sentencias de La Funcion*/;\\n\");\r\n    printf(\"\\t return retorno;\\n\");\r\n    printf(\"}\\n\\n\\n\");\r\n    printf(\"Typ_Return:\\t\\t Tipo de Parametro a Retornar.\\n\");\r\n    printf(\"Nombre_Funcion:\\t\\t Nombre de la Funcion.\\n\");\r\n    printf(\"Typ_param:\\t\\t Tipo de Paramtetro de Entrada.\\n\");\r\n    printf(\"Var:\\t\\t\\t Variable de entrada de la Funcion.\\n\\n\");\r\n\r\n    /*Llamada*/\r\n    printf(\"-->Llamada<--\\n\\n\");\r\n    printf(\"Nomre_Funcion(var1);\\n\");\r\n    printf(\"var1:\\t\\t\\t Variable cuyo valor se pasa al parametrode entrada de la Funcion\\n\\n\");\r\n    printf(\"NOTA: Existen Funciones de Tipo Void, que no retornan valor...\\n\\n\\n\");\r\n}\r\n\r\nint Bit_Convert(int var){\r\n\r\n    /*Declaracion de Variables Locales*/\r\n    int point = 0;    \r\n\r\n    do\r\n    {\r\n        arr[point] = var % 2;\r\n        var = var / 2;\r\n        point++;\r\n\r\n    } while (var != 0);\r\n    \r\n    return point;\r\n}\r\n\r\nvoid Mostrar(int var){\r\n\r\n    /*Declaracion de Variables Locales*/\r\n    int iteraciones;\r\n\r\n    /*Uso de la Fucion Bit Converter*/\r\n    iteraciones = Bit_Convert(var); //La variable iteracioes toma el valor que retorna la Funcion Bit_Converter\r\n    \r\n    \r\n    printf(\"%d\\t\\t\\t\", var);\r\n    /*Haciendo uso de la sentencia for para mostrar la cadena de bits correspondiente*/\r\n    for (int  i = (iteraciones - 1);  i >= 0;  i--)\r\n    {\r\n        printf(\"%d\", arr[i]);\r\n    }\r\n    printf(\"\\t\\t\\t%.0f\\n\\n\", pow(var, 2)); //Se hace uso de la funcion predefinida pow(x,y)\r\n    \r\n}\r\n\r\nvoid Funcion_en_Funcion()\r\n{\r\n    /*Declaracion de variables locales*/\r\n    bool prueba = false;\r\n    /*Declaracion de Funcion*/\r\n    void Probar(){\r\n        prueba = true; //Cambiamos el valor de la variable prueba, de esta forma, sabremos si funiono la funcion\r\n    }\r\n        /*Llamamos a la funcion anidada Probar(), para probar si es posible*/\r\n        Probar();\r\n        if (prueba)\r\n        {\r\n            printf(\"Si es posible crear Funciones dentro de funciones\\n\\n\\n\");\r\n        }\r\n        else printf(\"No es posible crear funcione dentro de funciones\\n\\n\\n\");\r\n\r\n}\r\n\r\nint Desafio(char a[], char b[]){\r\n/*Declaracion de Variables Locales*/\r\nint retorno = 0; //para Retornar la cantidad de numeros imprimidos\r\nchar txt_Retorno[100] = \"\\0\"; \r\nfor (int i = 1; i <= 100; i++)\r\n{   \r\n    strcpy (txt_Retorno, \"\\0\");\r\n\r\n    if(i % 3 == 0) //Si el numero es divisible entre tres se concatena el texto a la cadena que se va a mostrar\r\n    {\r\n\r\n        strcat(txt_Retorno, a); \r\n        printf(\"%s\\n\", txt_Retorno);\r\n    }\r\n    if((i % 5) == 0) //Si el numero es divisible entre cinco se concatena el texto a la cadena que se va a mostrar\r\n    {\r\n        strcat(txt_Retorno, b); \r\n        printf(\"%s\\n\", txt_Retorno);\r\n    }\r\n   if(((i % 3) != 0) && ((i % 5) != 0)) //Si no es divisible se muestra un numero \r\n   {\r\n        printf(\"%d\\n\", i);\r\n        retorno++;\r\n   }\r\n\r\n}\r\n\r\nreturn retorno;\r\n\r\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c/N0HagoNada.c",
    "content": "#include <stdio.h>\n#include <stdlib.h>\n#include <math.h>\n\n/* Funciones Matemáticas\nceil(x) // Redonde al entero mas cercaco\nabs(x) // valor abosulot\nfloor(x) -> redondea para abajo\nsqrt(x) -> raiz cuadrada\nfmod(x,y) -> calcula el resto de la division de x/y\npow(x,y) -> calcula x elevado y\n*/\nint funcRetoExtra(char *str1, char *str2);\n// Variable global\nint globalVar = 100;\n\n// Función sin parámetros ni retorno\nvoid funcionSinParametrosNiRetorno()\n{\n    printf(\"Esta función no tiene parámetros ni retorno.\\n\");\n}\n\n// Función con un parámetro\nvoid funcionConUnParametro(int a)\n{\n    printf(\"Función con un parámetro, valor: %d\\n\", a);\n}\n\n// Función con múltiples parámetros\nvoid funcionConMultiplesParametros(int a, float b)\n{\n    printf(\"Función con múltiples parámetros, int: %d, float: %.2f\\n\", a, b);\n}\n\n// Función con retorno\nint funcionConRetorno(int a)\n{\n    return a * a;\n}\n\n// Función que utiliza una variable global\nvoid funcionUsaVariableGlobal()\n{\n    printf(\"Acceso a variable global: %d\\n\", globalVar);\n}\n\nlong factorial(int n)\n{\n    if (n <= 0)\n    {\n        return 1;\n    }\n    else\n    {\n        return (n * factorial(n - 1));\n    }\n}\n\nint main()\n{\n    // Llamada a función sin parámetros ni retorno\n    funcionSinParametrosNiRetorno();\n\n    // Llamada a función con un parámetro\n    funcionConUnParametro(5);\n\n    // Llamada a función con múltiples parámetros\n    funcionConMultiplesParametros(3, 3.14f);\n\n    // Llamada a función con retorno\n    int resultado = funcionConRetorno(5);\n    printf(\"Resultado de función con retorno: %d\\n\", resultado);\n\n    // Llamada a función que usa una variable global\n    funcionUsaVariableGlobal();\n\n    // Uso de una función de la biblioteca estándar de C\n    printf(\"Uso de la función de la biblioteca estándar: %d\\n\", abs(-10));\n\n    // Demostración de variable local\n    int localVar = 20;\n    printf(\"Variable local en main: %d\\n\", localVar);\n\n    // Funcion recursiva\n    printf(\"Factorial de 20 es %li\\n\", factorial(localVar));\n\n    return funcRetoExtra(\"FIZZ\", \"FUZZ\");\n}\n\nint funcRetoExtra(char *str1, char *str2)\n{\n    int rtn = 0;\n    for (int i = 100; i > 0; i--)\n    {\n        if ((i % 3 == 0) && (i % 5 == 0))\n        {\n            printf(\"%s%s\\n\", str1, str2);\n        }\n        else if (i % 5 == 0)\n        {\n            printf(\"%s\\n\", str1);\n        }\n        else if (i % 3 == 0)\n        {\n            printf(\"%s\\n\", str2);\n        }\n        else\n        {\n            printf(\"%d\\n\", i);\n            rtn++;\n        }\n    }\n    return rtn;\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c/SoMaxB.c",
    "content": "#include <stdio.h>\n\nvoid\tno_param_no_return(void);\nint\t\tno_param_with_return(void);\nvoid\tparam_no_return(int a);\nint\t\tparam_and_return(int b);\nint\t\textra(char *c, char *d); // Extra\n\n// In C you cannot create functions within functions.\n\nint\tglobal_var = 5; // Global variable.\n\nint\tmain(void)\n{\n\t\tint local_var = 10; // Local variable.\n\n\t\tno_param_no_return();\n\t\tprintf(\"This function has no param but has return %d\\n\", no_param_with_return());\n\t\tparam_no_return(4);\n\t\tprintf(\"Function with param and return: %d\\n\", param_and_return(5));\n\n\t\t// Extra\n\t\textra(\"Fizz\", \"Buzz\");\n    \n\t\tint total = extra(\"Fizz\", \"Buzz\");\n    \n\t\tprintf(\"The numbers have been printed %d times.\\n\", total);\n\n\t\treturn 0;\n}\n\nvoid\tno_param_no_return(void) {\n\t\tprintf(\"This function has no parameter or return.\\n\");\n}\n\nint\tno_param_with_return(void) {\n\t\tint\tlocal = 3; // Local variable.\n\n\t\treturn (local += global_var);\n}\n\nvoid\tparam_no_return(int a) {\n\t\tprintf(\"This function has parameter but no return, the parameter is: %d\\n\", a);\n}\n\nint\tparam_and_return(int b) {\n\t\tint total = b + global_var;\n\n\t\treturn (total);\n}\n\n// Extra function\nint\textra(char *c, char *d) {\n\t\tint n = 1;\n\t\tint count = 0;\n\n\t\twhile (n <= 100)\n\t\t{\n            if (n % 3 == 0 && n % 5 == 0)\n                printf(\"%s%s\\n\", c, d);\n            else if (n % 3 == 0)\n                printf(\"%s\\n\", c);\n            else if (n % 5 == 0)\n                printf(\"%s\\n\", d);\n            else {\n                printf(\"%d\\n\", n);\n                count ++;\n            }\n            n++;\n\t\t}\n\t\treturn (count);\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c/aggranadoss.c",
    "content": "#include<stdio.h>\n#include<stdlib.h>\n#include<string.h>\n\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\nfloat global = 3.141592; \n\n// Funcion sin parametros y sin retorno\nint potencia_sp_sr(){\n  int iter = 2, res = 1; \n  for(int i=0; i<iter; i++)    \n    res *= 7; \n}\n\n/*\n  El resultado 2 que se obtiene no es el resultado de la función potencia_sp_sr(), sino un valor aleatorio que se encuentra en la posición de memoria asignada para la variable resultado_sp_sr en la función main(int argc, char* argv[argc +1]). No está retornando ningún valor explícitamente utilizando return, por lo que técnicamente la función retorna un valor indeterminado, que puede ser cualquier cosa que se encuentre en la posición de memoria donde debería estar el resultado. \n\n */\n\n\n// Funcion sin parametros y retorno\nint potencia_sp(){\n  int res = 1, iter = 2; \n  for(int i=0; i<iter; i++)    \n    res *= 2; \n  return res;\n}\n\n// Funcion con un parametro y retorno\nint potencia_base_dos(int x){\n  int res = 1; \n  for(int i=0; i<x; i++)    \n    res *= 2; \n  return res;\n}\n\n// Funcion con dos parametros y retorno\nint potencia(int x, int y){\n  int res = 1; \n  for(int i=0; i<y; i++)    \n    res *= x; \n  return res;\n}\n\n// Funcion con funciones y retorno\nfloat posicion_fisica(float a,int t){\n  float pos; int tiempo;\n  tiempo = potencia(t,2); // Funcion creada de dos parametros y con retorno\n  pos = (1.0/2)*a*tiempo; // Se coloca el 1.0 en lugar de 1 ya que con 1 solo toma la parte entera que es cero.\n  return pos;\n}\n\n  /******************/\n  // DIFICULTAD EXTRA\n  /******************/\n\n// Funcion con dos parametros de tipo cadena de texto y retorne un numero\n\nint* texto(char* x, char* y){\n  static int numero[2]={0,0};\n  for(int i=1; i<=100; ++i){\n    printf(\"\\nEl numero de la funcion es: %d\\n\\n\",i);\n    if(i%3==0 && i%5==0){\n      printf(\"\\nVemos que el numero %d es multiplo de 3 y de 5. Mostramos los dos parametros de la cadena de texo concatenados son:\\n\\n%s%s concatenadas \\n\\n \",i,x,y);\n      numero[0]++; // Si es multiplo de 3 sume sus repeticiones \n      numero[1]++; // Si es multiplo de 5 sume sus repeticiones\t\n    }else if(i%5==0){\n      printf(\"\\nVemos que el numero %d es multiplo de 5. Mostramos el segundo parametro de la cadena de texo: %s\\n\\n \",i,y);\n      numero[1]++;\n    }else if(i%3==0){\n      printf(\"\\nVemos que el numero %d es multiplo de 3. Mostramos el primer parametro de la cadena de texo: %s\\n\\n \",i,x);\n      numero[0]++;\n    }\n  }\n  return numero;\n}\n\n\n\nint main(int argc, char* argv[argc+1]){\n\n\n  // Se ha realizado el print de cada uno de los ejemplos:\n\n  printf(\"\\n******************************\\n\");\n  printf(\"PRINT DEL LLAMADO DE FUNCIONES\");\n  printf(\"\\n******************************\\n\");\n\n  int resultado_sp_sr = potencia_sp_sr();\n  printf(\"La potencia sin parametros y sin retorno es: %d\\n\", resultado_sp_sr);\n\n  int resultado_sp = potencia_sp();\n  printf(\"La potencia sin parametros y con retorno es: %d\\n\", resultado_sp);\n\n  int resultado_base_dos = potencia_base_dos(5);\n  printf(\"La potencia con un parametro y un retorno es: %d\\n\", resultado_base_dos);\n\n  int resultado = potencia(5,3);\n  printf(\"La potencia con dos parametros y un retorno es: %d\\n\", resultado);\n\n  float posicion = posicion_fisica(9.8,5);\n  printf(\"Calculo de posicion -> Funcion con funciones y retorno es: %.2f\\n\", posicion); // printf es un ejemplo de funciones ya creadas en el lenguaje\n\n  int res; // Definir un entero que se encuentra definido en las funciones sin asignarle valor ya que \"tiene el valor ya definido\"\n  printf(\"La variable global es %f\\nLa variable local es %d distinto al valor definido en Funcion sin parametros y sin retorno\\n \",global,res);\n\n  /******************/\n  // DIFICULTAD EXTRA\n  /******************/\n  printf(\"\\n***********************\\n\");\n  printf(\"DIFICULTAD EXTRA\");\n  printf(\"\\n***********************\\n\");\n  char texto_a[] = \"PRIMERA CADENA DE TEXTO DADA \";\n  char texto_b[] = \"SEGUNDA CADENA DE TEXTO DADA \";\n  int* cadena = texto(texto_a,texto_b);\n  printf(\"\\nSe ha usado el numero 3 -> %d veces\\nSe ha usado el numero 5 -> %d veces\\n\\n\",cadena[0],cadena[1]);\n  \n  return EXIT_SUCCESS;\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c/barbafebles.c",
    "content": "\n// Funciondes definidas por el usuario \n#include <stdio.h>\n#include <string.h>      // strlen\n\nvoid simple()\n{\n    printf(\"Sin retorno\\n\");\n}\n\nvoid simple_personalizado(char *nombre)\n{\n    printf(\"Hola %s\\n\", nombre);\n}\n\nint simple_retorno()\n{\n    printf(\"Con retorno\\n\");\n    return 30;\n}\nint suma(int a, int b)\n{\n    return a + b;\n}\nint simple_parametros(int param1, int param2)\n{\n    int resultado = suma(param1, param2);\n    printf(\"La suma es: %d\", resultado);\n    return resultado;\n}\n\n// Funcion strlen \nvoid longitud_cadena(char *cadena)\n{\n    int longitud = strlen(cadena);\n    printf(\"La longitud de la cadena es: %d\\n\", longitud);\n}\n// Variable global\ndouble PI = 3.1416;\n\nvoid imprimir_PI()\n{\n    printf(\"Imprimir el valor: %f\\n\", PI);\n}\n /*DIFICULTAD EXTRA (opcional):*/\nint imprimir(char *cadena1, char *cadena2) \n{\n    int counter = 0;\n    int i = 1;\n    while(i <= 100) {\n        if(i % 3 == 0 && i % 5 == 0) {\n            printf(\"%s %s\\n\", cadena1, cadena2);\n        } else if (i % 3 == 0) {\n            printf(\"%s\\n\", cadena1);\n        } else if(i % 5 == 0) {\n            printf(\"%s\\n\", cadena2);\n        } else {\n            printf(\"%d\\n\", i);\n            counter++;\n        }\n        i++;\n    }\n    return counter;\n}\n\nint main() \n{\n    int variable_local = 5;\n    printf(\"Variable local: %d, Variable global %f\\n\", variable_local, PI);\n    simple();\n    simple_personalizado(\"Pepe\");\n    simple_retorno();\n    simple_parametros(5,3);\n    longitud_cadena(\"Pruebas funciones\");\n    imprimir_PI();\n\n    char* texto1 = \"Hola\";\n    char* texto2 = \"como estas?\";\n    int counter = imprimir(texto1, texto2);\n    printf(\"Se imprimió el número en lugar de los textos %d veces.\\n\", counter);\n\n    return 0;\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c/cikethebear.c",
    "content": "// CikeTheBear - https://github.com/CikeTheBear/\n\n#include <stdio.h>\n\n// === Funciones ===\n\n// Funcion simple ---\nvoid simple()\n{\n    printf(\"Hola, C\\n\");\n}\n\n// Funcion con argumento ---\nvoid conArgumento(char *texto)\n{\n    printf(\"%s\\n\", texto);\n}\n\n// Funcion con mas de un argumento ---\nvoid conArgumentos(char *texto, int numero)\n{\n    printf(\"El primer argumento es %s y el segundo es %d\\n\", texto, numero);\n}\n\n// Funcion con argumento por defecto (En C no existe esta posibilidad, pero se puede \"simular\" de la siguiente manera) ---\nvoid conArgumentoPorDefecto(char *texto)\n{\n    if (texto == NULL)\n    {\n        texto = \"Valor por defecto\";\n    }\n    printf(\"%s\\n\", texto);\n}\n\n// Funcion con retorno ---\nint conRetorno(int n, int m)\n{\n    int suma = n + m;\n    return suma;\n}\n\n// Funcion dentro de una funcion (Tecnicamente, C no lo permite, por lo menos no de manera estandar, pero compilar con GCC se salta esa restriccion) ---\nvoid funcion_externa(char *texto_1, int n)\n{\n\n    int funcion_interna(int n)\n    {\n\n        int resultado = n * 5;\n\n        return resultado;\n    }\n\n    printf(\"Funcion Externa dice: %s\\n\", texto_1);\n    printf(\"Funcion Interna calcula: %d\\n\", funcion_interna(n));\n}\n\n// Dificultad Extra ---\n\nint dificultad_extra(char *cadena_1, char *cadena_2)\n{\n    for (int i = 1; i >= 1 && i <= 100; i++)\n    {\n        if (i % 3 == 0 && i % 5 == 0)\n        {\n            printf(\"%s%s\\n\", cadena_1, cadena_2);\n        }\n        if (i % 3 == 0)\n        {\n            printf(\"%s\\n\", cadena_1);\n        }\n        else if (i % 5 == 0)\n        {\n            printf(\"%s\\n\", cadena_2);\n        }\n        else\n        {\n            printf(\"%d\\n\", i);\n        }\n    }\n}\n\n// ====== Funcion prinicipal ======\nint main()\n{\n    simple();\n\n    conArgumento(\"Argumento\");\n\n    conArgumentos(\"Palabra\", 34);\n\n    conArgumentoPorDefecto(NULL);\n\n    printf(\"Funcion con retorno: %d\\n\", conRetorno(50, 25));\n\n    funcion_externa(\"Por dentro, tengo una calculadora que multiplica por 5\", 5);\n\n    dificultad_extra(\"Fizz\", \"Buzz\");\n\n    return 1;\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c/d1d4cum.c",
    "content": "#include <stdio.h>\n\n\nchar language = 'C';\n\nvoid sayHello() {\n    printf(\"Hello %c!\\n\", language);\n}\n\nint suma() {\n    return 2 + 5;\n}\n\nvoid saluda(char nombre[]) {\n    printf(\"Hola %s\\n\", nombre);\n}\n\nint sumaADos(int number) {\n    int dos = 2;\n    return dos + number;\n}\n\nint exercise(char string1[], char string2[]) {\n    int times = 0;\n\n    for (int i = 0; i <= 100; i++) {\n        if((i % 3 == 0) && (i % 5 == 0)) {\n            printf(\"%s %s\\n\", string1, string2);\n        } else if(i % 5 == 0) {\n            printf(\"%s\\n\", string2);\n        } else if (i % 3 == 0) {\n            printf(\"%s\\n\", string1);\n        } else {\n            printf(\"%d\\n\", i);\n            times++;\n        }\n    }\n\n    return times;\n}\n\nint main()  {\n    sayHello();\n    printf(\"%d\\n\", suma());\n    saluda(\"Diego\");\n    printf(\"%d\\n\", sumaADos(5));\n    printf(\"%d\", exercise(\"Hola\", \"Mundo\"));\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c/heliercamejo.c",
    "content": "#include <stdio.h>\n#include <math.h>\n\nint global = 50;\n\nvoid sin_retorno();\nint con_retorno();\nvoid sin_retorno_con_parametros(int);\nfloat con_retorno_con_parametros(int);\n\nint extra(char *, char *);\n\nint main()\n{\n    int local = 10;\n    printf(\"local=%d\\n\",local);\n    sin_retorno();\n    printf(\"%d\\n\", con_retorno());\n    sin_retorno_con_parametros(local);\n    printf(\"el area es: %0.2f\\n\", con_retorno_con_parametros(local));\n    printf(\"%d numeros\\n\", extra(\"Hola\", \"Mundo\"));\n    return 0;\n}\n\nvoid sin_retorno()\n{\n    printf(\"Esto es una funcion sin retorno y sin parametros\\n\");\n    printf(\"Global = %d\\n\", global);\n}\n\nint con_retorno()\n{\n    printf(\"Esto es una funcion con retorno = 50 y sin parametros\\n\");\n    return 50;\n}\n\nvoid sin_retorno_con_parametros(int param)\n{\n    printf(\"Esto es una funcion sin retorno y con parametro=%d\\n\", param);\n}\n\nfloat con_retorno_con_parametros(int radio)\n{\n    printf(\"Esto es una funcion con retorno y con parametro\\n\");\n    printf(\"Retorna el area del circulo\\n\");\n    float area = 3.14 * pow(radio,2);\n;    return  area;\n}\n\nint extra(char *cadena1, char *cadena2)\n{\n    int count = 0;\n    for(int i = 0; i<=100; i++)\n    {\n        if (i%3==0 && i%5==0)\n        {\n            printf(\"%s%s\",cadena1,cadena2);\n        }\n        else if (i%3==0)\n        {\n            printf(\"%s\",cadena1);\n        }\n        else if (i%5==0)\n        {\n            printf(\"%s\",cadena2);\n        }\n        else \n        {\n            count++;\n            printf(\"i=%d\",i);\n        }\n        printf(\"\\n\");\n    }\n    return count;\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c/jchavescaceres.c",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n #include <stdio.h>\n #include <stdarg.h>\n #include <string.h>\n\n/*\nEn C las funciones pueden o no devolver un valor, pueden tener entre 0 y n parámetros de entrada\n(no existen parámetros OUT o IN OUT, aunque con un puntero se puede obtener el mismo resultado\n*/\n\n/*\nFuncion sin parámetro de entrada, también se puede dejar (), sin retorno \n*/\nvoid funcionSinParametrosNiRetorno (void) {\n\tprintf (\"funcionSinParametrosNiRetorno\\n\");\n};\n\n/*\nFuncion con varios parámetros de entrada, sin retorno\n*/\nvoid funcionConParametrosSinRetorno (int numero1, int numero2) {\n\tprintf (\"funcionConParametrosSinRetorno: numero1=%d, numero2=%d\\n\", numero1, numero2);\n};\n\n/*\nFuncion con varios parámetros de entrada y retorno\n*/\nint funcionConParametrosYRetorno (int numero1, int numero2, const char* texto) {\n\tconst int res = numero1 * numero2;\n\tprintf (\"funcionConParametrosYRetorno: texto %s, numero1=%d, numero2=%d, retorno %d\\n\", texto, numero1, numero2, res);\n\treturn res;\n};\n\n/*\nSe pueden crear funciones dentro de funciones (funciones anidadas), solo visibles desde la funcion principal\n*/\nvoid ejemploFuncionesAnidadas() {\n\n\tvoid funcionAnidada() {\n\t\tprintf (\"funcionAnidada\\n\");\n\t};\n\n\tprintf (\"ejemploFuncionesAnidadas\\n\");\n\tfuncionAnidada;\n};\n\n/*\nTambién se pueden definir funciones con parámetros de entradas variable, tanto en numero como tipo, (pero siempre tiene que tener el primero fijo)\nUn ejemplo es la funcion printf\nSolo lo he visto en ejemplos pero nunca en la vida real\nEsta funcion puede reciber n pares de int y const char*, numArgs es el total de argumentos\n*/\nvoid funcionParametrosVariables (unsigned int numArgs, ...) {\n\tva_list listaParametros;\n\tva_start (listaParametros, numArgs);\n\n\tprintf (\"funcionParametrosVariables: \\n\");\n\n\tfor (int i=0; i < numArgs/2; i++) {\n\t\tint numero = va_arg (listaParametros, int);\n\t\tconst char* texto = va_arg (listaParametros, const char*);\n\t\tprintf (\"\t%d, %s\\n\", numero, texto);\n\t};\n\n\tva_end (listaParametros);\n};\n\n/*\nTambién existen punteros a funciones\n*/\nvoid funcionPuntero1 (int a) {\n\tprintf (\"funcionPuntero1 %d\\n\", a);\n};\n\nvoid funcionPuntero2 (int a) {\n\tprintf (\"funcionPuntero2 %d\\n\", a);\n};\n\ntypedef void (*t_ptr_funcion)(int);\nconst t_ptr_funcion C_ARRAY_PTR_FUNCIONES [] = {\n\tfuncionPuntero1,\n\tfuncionPuntero2\n}; \n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n*/\nunsigned int dificultadExtra (const char* cadena1, const char* cadena2);\n\n\n\nint variableGlobal=0;\n\nvoid funcionVariableLocal() {\n\t\n\t/* si se llama igual que una variable global prevalece la variable local */\n\t/* int variableGlobal=2;*/\n\tint variableLocal = 3;\n\n\tvariableGlobal++;\n\n\tprintf(\"funcionVariableLocal : variableLocal=%d, variableGlobal=%d\\n\", variableLocal, variableGlobal);\n};\n\nvoid main () {\n\n\tint longitud = 0;\n\n\t/* Llamada a funcion sin parámetros ni retorno*/\n\tfuncionSinParametrosNiRetorno ();\n\n\t/* Llamada a funcion con parámetros ni retorno*/\n\tfuncionConParametrosSinRetorno (2, 3);\n\n\t/* Llamada a funcion con parámetros y retorno*/\n\tprintf (\"Llamada a funcionConParametrosYRetorno devuelve %d\\n\", funcionConParametrosYRetorno (2, -3, \"hola\"));\n\n\t/*Funciones anidadas*/\n\tejemploFuncionesAnidadas();\n\t/* error porque solo es visible dentro del ámbito de ejemploFuncionesAnidadas*/\n\t/* funcionAnidada();*/\n\n\t/*Funcion con número y tipo parámetros variable */\n\tfuncionParametrosVariables (4, 1, \"uno\", 2, \"dos\");\n\t/*Funcion con número y tipo parámetros variable */\n\tfuncionParametrosVariables (6, 3, \"tres\", 4, \"cuatro\", 5, \"cinco\");\n\n\t/* llamada a una funcion ya creada en el lenguaje*/\n\tlongitud = strlen (\"Prueba\");\n\n\t/* variables globales y locales */\n\tvariableGlobal=5;\n\tprintf (\"variableGlobal=%d\\n\", variableGlobal);\n\tfuncionVariableLocal();\n\n\t/*Puntero a funciones*/\n\tfor (int i = 0, tam = sizeof (C_ARRAY_PTR_FUNCIONES) / sizeof (t_ptr_funcion); i < tam; i++) {\n\t\tC_ARRAY_PTR_FUNCIONES [i](i);\n\t};\n\n\tprintf (\"dificultadExtra devuelve %u\\n\", dificultadExtra (\"cadena1\", \"cadena2\"));\n\n\n};\n\nunsigned int dificultadExtra (const char* cadena1, const char* cadena2) {\n\tconst unsigned int C_MIN = 1;\n\tconst unsigned int C_MAX = 100;\n\tconst unsigned int C_MULTIPLE_CADENA1 = 3;\n\tconst unsigned int C_MULTIPLE_CADENA2 = 5;\n\n\t/* contador de veces que no se imprime ni cadena1 ni cadena2,\n\t   (suponemos que se refiere a eso porque los números siempre se imprimen (2º línea de instrucciones)\n\t*/\n\tunsigned int res = 0; \n\tchar seHaImpresoCadenas = 0;\n\n\tfor (unsigned int num = C_MIN; num <= C_MAX; num++) {\n\n\t\tseHaImpresoCadenas = 0;\n\n\t\tprintf (\"%u \", num);\n\n\t\tif (num >= C_MULTIPLE_CADENA1 && (num % C_MULTIPLE_CADENA1) == 0) {\n\t\t\tprintf (\" %s\", cadena1);\n\t\t\tseHaImpresoCadenas = 1;\n\t\t};\n\t\tif (num >= C_MULTIPLE_CADENA2 && (num % C_MULTIPLE_CADENA2) == 0) {\n\t\t\tprintf (\" %s\", cadena2);\n\t\t\tseHaImpresoCadenas = 1;\n\t\t};\n\n\t\tif (!seHaImpresoCadenas) {\n\t\t\tres++;\n\t\t};\n\n\t\tprintf (\"\\n\");\n\t};\n\treturn res;\n};\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c/miguelex.c",
    "content": "#include <stdio.h>\n\nint Extra (const char* param1, const char* param2){\n    int numVeces = 0;\n    for (int i = 1; i <= 100; i++){\n        if (i % 15 == 0){\n            printf(\"%s%s\", param1, param2);\n        } else if (i % 3 == 0){\n            printf(\"%s\", param1);\n        } else if (i % 5 == 0){\n            printf(\"%s\", param2);\n        } else {\n            printf(\"%d\", i);\n            numVeces++;\n        }        \n        printf(\"\\n\");\n    }\n\n    return numVeces;\n}\nvoid Hola(){\n    printf(\"Hola. Este es un ejemplo de funcíon sin parametros ni retorno\\n\");\n}\n\nvoid HolaNombre(char nombre[]){\n    printf(\"Hola %s. Este es un ejemplo de funcíon con parametros pero sin retorno\\n\", nombre);\n}\n\nint Suma(int a, int b){\n    return a + b;\n}\n\nint main(){\n    Hola();\n    HolaNombre(\"Miguel\");\n    printf(\"La suma de 2 y 3 es: %d\\n\", Suma(2, 3));\n    printf(\"Se han imprimido %d numeros\\n\", Extra(\"Fizz\", \"Buzz\"));\n    return 0;\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c/srvariable.c",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n// Inclusión de librerías\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <ctype.h>\n\n/* === 1 === */\n// Sin parámetros ni retorno\n\n/*\n * Función tipo 'void' llamada \"hello_world\".\n *\n * No recibe parámetros.\n *\n * No retorna nada porque la función es void.\n *\n * NOTA: Cuando la función no tiene parámetros\n * es recomendable poner void, para asegurar que\n * al llamar a la función si se le introducen\n * parámetros dé un error.\n */\nvoid\thello_world(void)\n{\n\tprintf(\"¡Hola mundo!\\n\");\n\treturn ; // (Opcional) return sin parámetros ya que la función es de tipo 'void'.\n}\n\n// Con uno o varios parámetros\n/*\n * Función tipo 'void' llamada \"conversor\".\n * \n * Recibe tres parámetros:\n * - temperature: Variable de tipo 'float'.\n * - unit: Variable de tipo 'char *'.\n * - unit2: Variable de tipo 'char *'.\n *\n * No retorna nada porque la función es void.\n */\nvoid\tconversor(float temperature, char unit, char unit2)\n{\n\tfloat\tresult;\n\n\tif (unit == 'C')\n\t{\n\t\tif (unit2 == 'F')\n\t\t\tresult = 9.0f / 5.0f * temperature + 32.0f;\n\t\telse if (unit2 == 'K')\n\t\t\tresult = temperature + 273.15f;\n\t\telse\n\t\t\treturn ;\n\t}\n\telse if (unit == 'F')\n\t{\n\t\tif (unit2 == 'C')\n\t\t\tresult = 5.0f / 9.0f * (temperature - 32.0f);\n\t\telse if (unit2 == 'K')\n\t\t\tresult = 5.0f / 9.0f * (temperature + 459.67f);\n\t\telse\n\t\t\treturn ;\n\t}\n\telse if (unit == 'K')\n\t{\n\t\tif (unit2 == 'C')\n\t\t\tresult = temperature - 273.15f;\n\t\telse if (unit2 == 'F')\n\t\t\tresult = 9.0f / 5.0f * temperature - 459.67f;\n\t\telse\n\t\t\treturn ;\n\t}\n\telse\n\t\treturn ;\n\tprintf(\"%f %c = %f %c\\n\", temperature, unit, result, unit2);\n}\n\n// Con retorno \n/*\n * Función tipo 'int' llamada \"suma\".\n *\n * Recibe dos parámetros:\n * - n1: Variable de tipo 'int'.\n * - n2: Variable de tipo 'int'.\n *\n * Retorna un 'int' que representa la suma de n1 y n2.\n */\nint\tsuma(int n1, int n2)\n{\n\treturn (n1 + n2);\n}\n\n/* === 2 === */\n// En el lenguaje C estándar no está soportado\n// la definición de funciones dentro de funciones.\n// Sin embargo, en GNU C, es posible, aunque no es\n// recomendable usarlo.\nvoid\thola(void)\n{\n\tvoid\tmundo(void)\n\t{\n\t\tprintf(\" mundo\\n\");\n\t}\n\tprintf(\"Hola\");\n\tmundo();\n}\n\n/* === 3 === */\n/*\n * Función tipo 'char *' llamada pingpong.\n *\n * Recibe un parámetro:\n * - str: Variable de tipo 'char *'.\n *\n * Retorna:\n * - \"ping\" si el parámetro es \"ping\".\n * - \"pingpong\" si el parámetro no es \"ping\".\n */\nchar\t*pingpong(char *str)\n{\n\t// Función existente que compara dos \"strings\" y devuelve 0 si son iguales.\n\t// Para más información, buscar \"man strcmp\".\n\tif (strcmp(str, \"ping\") == 0)\n\t\treturn (\"pong\");\n\treturn (\"pingpong\");\n}\n\n/* === 4 === */\n// Variable global\n// Esta variable es posible utilizarla en cualquier scope a partir de esta línea.\n// Es decir, si la intentamos usar en cualquier otra función anterior, no tendrá\n// la referencia, ya que es secuencial.\nconst char\t*g_githuburl = \"https://github.com/mouredev/roadmap-retos-programacion\";\n\n// Declaración de la función fizzbuzz_tuneado\nint\t\tfizzbuzz_tuneado(char *str, char *str2);\nvoid\tis_fizzbuzz_tuneado(int (*f)(char *str, char *str2));\nint\t\trandomfunction(char *str, char *str2);\n\n/* Función tipo 'int' llamada 'main'\n *\n * Recibe dos parámetros:\n * - argc: Variable de tipo 'int' que indica el número\n * de argumentos que se introducen al programa.\n * - argv: Variable de tipo 'char **' que almacena los\n * argumentos que se introducen al programa.\n *\n * Retorna:\n * - 0 si el programa se ejecuta correctamente.\n * - 1 si no se introducen al menos 2 argumentos.\n *\n * NOTA: Esta función es esencial si queremos crear un\n * programa.\n */\nint\tmain(int argc, char **argv)\n{\n\t// Variables locales\n\tconst char\t*texto = \"El enlace al repositorio original es: \";\n\tchar\t\tu;\n\tchar\t\tu2;\n\tfloat\t\ttemperatura;\n\n\tif (argc < 2)\n\t{\n\t\tprintf(\"Uso: %s <temperatura>\", argv[0]); // Imprime el primer argumento, que es el nombre del programa.\n\t\treturn (1);\n\t}\n\tprintf(\"Función hello_world: \");\n\thello_world();\n\ttemperatura = (float)atof(argv[1]);\n\tprintf(\"Introduce el primer carácter de la unidad de medida de la temperatura inicial: \");\n\tscanf(\" %c\", &u);\n\tprintf(\"Introduce el primer carácter de la unidad de medida de la temperatura final: \");\n\tscanf(\" %c\", &u2);\n\tprintf(\"Función conversor: \");\n\tconversor(temperatura, toupper(u), toupper(u2));\n\tprintf(\"Función suma: %d\\n\", suma(1, 2));\n\tprintf(\"Función pingpong: %s\\n\", pingpong(\"ping\"));\n\tprintf(\"Función pingpong: %s\\n\", pingpong(\"pong\"));\n\tprintf(\"Función fizzbuzz_tuneado:\\n\");\n\tprintf(\"Número de veces que se imprimen números en lugar de texto: %d\\n\", fizzbuzz_tuneado(\"https://github.com\", \"/SrVariable\"));\n\tprintf(\"%s%s\\n\", texto, g_githuburl);\n\n\t// BONUS\n\tis_fizzbuzz_tuneado(fizzbuzz_tuneado);\n\tis_fizzbuzz_tuneado(randomfunction);\n\treturn (0);\n}\n\n/*\n * Función tipo 'void' llamada \"is_fizzbuzz_tuneado\".\n *\n * Recibe un parámetro:\n * - f: Variable de tipo 'int *', es una función que recibe\n *   dos parámetros de tipo 'char *'.\n *\n * No retorna nada porque es una función tipo 'void'.\n */\nvoid\tis_fizzbuzz_tuneado(int (*f)(char *str, char *str2))\n{\n\tif (f == fizzbuzz_tuneado)\n\t\tprintf(\"Esta función es el fizzbuzz_tuneado\\n\");\n\telse\n\t{\n\t\tprintf(\"Esta función no es el fizzbuzz_tuneado\\n\");\n\t\tprintf(\"Devuelvo: %d\\n\", f(NULL, NULL));\n\t}\n}\n\n/*\n * Función tipo 'int' llamada \"randomfunction\".\n *\n * Recibe dos parámetros:\n * - str: Variable tipo 'char *'.\n * - str2: Variable de tipo 'char *'.\n *\n * Retorna:\n * - 0 si los dos parametros son NULL.\n * - 1 en cualquier otro caso.\n */\nint\trandomfunction(char *str, char *str2)\n{\n\tif (!str && !str2)\n\t\treturn (0);\n\treturn (1);\n}\n\n/* === DIFICULTAD EXTRA === */\n// Definición de la función fizzbuzz_tuneado\n/*\n * Función tipo 'int' llamada \"fizzbuzz_tuneado\".\n *\n * Recibe dos parámetros:\n * - str: Variable de tipo 'char *'.\n * - str2: Variable de tipo 'char *'.\n * \n * Retorna el número de veces que imprime un\n * número en lugar de texto.\n */\nint\tfizzbuzz_tuneado(char *str, char *str2)\n{\n\tint\tcounter = 0; // Contador para aumentarlo cada vez que imprima un texto en lugar de un número\n\n\tfor (int i = 1; i <= 100; i++)\n\t{\n\t\t// Hago primero la última condición, si es módulo de 3 y 5\n\t\t// para que no haya conflicto cuando sea módulo de 3 solamente,\n\t\t// o módulo de 5 solamente.\n\t\tif (i % 3 == 0 && i % 5 == 0) \n\t\t\tprintf(\"%s%s\\n\", str, str2); // Imprimo los dos \"strings\" juntos si es divisible entre  3 y 5.\n\t\telse if (i % 3 == 0)\n\t\t\tprintf(\"%s\\n\", str); // Imprimo el primer \"string\" si es divisible entre 3.\n\t\telse if (i % 5 == 0)\n\t\t\tprintf(\"%s\\n\", str2); // Imprimo el segundo \"string\" si es divisible entre 5.\n\t\telse\n\t\t{\n\t\t\tprintf(\"%d\\n\", i); // Imprimo el número.\n\t\t\tcounter++; // Aumento el contador cuando imprimo el número.\n\t\t}\n\t}\n\treturn (counter);\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c#/Andreavzqz.cs",
    "content": "using System\n\nclass Program\n{\n    //Variable global\n    static string globalVar =\" Yo soy la variable global\"\n\n    static void Main(string[] args)\n    {\n        //Llamadas a las funciones y demostracion de conceptos\n        Greet();\n        GreetName(\"Alicia\");\n        GreetFullName(\"Alicia, Luis\");\n\n\n        console.WriteLine(GetGreeting());\n        console.WriteLine(GetGreetingName(\"Andrea\"));\n        console.WriteLine(GetGreetingFullName(\"Andrea, Fran\"));\n\n        OuterFuncion();\n\n        ScopeExample();\n        console.WriteLine(globalVar); // Accede a la variable global\n        changeGlobalVar();\n        console.WriteLine(globalVar); // Muestra el cambio global\n\n        changeLocalVar();\n        console.WriteLine(globalVar); // La variable global no cambia por changeLocalVar\n\n        // Funciones de ejemplo ya creadas en el leguaje (Math)\n        console.WriteLine(Math.Max(1, 2, 3)); // Funcion incorporada Math.Max\n        console.WriteLine(Math.Min(1, 2, 3)); // Funcion incorporada Math.Min\n        console.WriteLine(Math.Sqrt(16));     // Funcion incorporada Math.Sqrt\n        console.WriteLine(Math.Pow(2 ,3));    // Funcion incorporada Math.Pow\n    }\n\n\n    // Funcion sin parametros ni retorno\n    static void Greet\n    {\n        console.WriteLine(\"Hola, mundo!\");\n    }\n\n    // Funcion con retorno y un parametros\n    static void GreetName (string name)\n    {\n        console.WriteLine(\"Hola, \"+ name +\"!\");\n    }\n\n    // Funcion con retorno y varios parametro\n    static string GetGreetingFullName(string firstName, string lastName)\n    {\n        return \"Hola \"+ firstName + \" \" + lastName + \"!\";\n    }\n\n    // Funcion anidada (funcion dentro de una funcion)\n    static void OuterFuncion()\n    {\n        console.WriteLine(\"Otra funcion\");\n\n        void InnerFuncion()\n        {\n            console.WriteLine(\"Funcion interna\");\n        }\n\n        InnerFuncion();\n    }\n\n    // Ejemplo de variables globales y locales\n    static void ScopeExample()\n    {\n        string localVar = \"Soy una variable local\";\n        console.WriteLine(globalVar); // Accede a la variable global\n        console.WriteLine(localVar);  // Accede a la variable local\n    }\n\n    static void changeGlobalVar()\n    {\n        globalVar = \"Soy la variable global\";\n    }\n\n    static void changeLocalVar()\n    {\n        globalVar = \"Me he cambiando a global\";\n    }\n\n    static void changeLocalVar()\n    {\n        string localVar = \"Soy la variable local\";\n        localVar = \"Me he cambiado a local\";\n        console.WriteLine(localVar); // Muestra el cambio local\n    }\n}\n\n\n/*\nExplicación:\n\nFunciones sin parámetros ni retorno:\nGreet: Imprime un saludo simple.\n\nFunciones con un parámetro y sin retorno:\nGreetName: Imprime un saludo con un nombre proporcionado.\n\nFunciones con varios parámetros y sin retorno:\nGreetFullName: Imprime un saludo con nombre y apellido.\n\nFunciones con retorno y sin parámetros:\nGetGreeting: Retorna un saludo simple.\n\nFunciones con retorno y un parámetro:\nGetGreetingName: Retorna un saludo con un nombre proporcionado.\n\nFunciones con retorno y varios parámetros:\nGetGreetingFullName: Retorna un saludo con nombre y apellido.\n\nFunciones anidadas:\nOuterFunction: Contiene una función InnerFunction dentro de ella.\n\nVariables globales y locales:\nglobalVar: Variable global.\nScopeExample: Demuestra el acceso a variables globales y locales.\nChangeGlobalVar: Modifica la variable global.\nChangeLocalVar: Modifica una variable local.\nFunciones de ejemplo ya creadas en el lenguaje:\n\nUso de funciones incorporadas como Math.Max, Math.Min, Math.Sqrt, y Math.Pow.\n\n*/\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c#/Esaens12.cs",
    "content": "﻿using System.Security.Cryptography.X509Certificates;\r\n\r\nnamespace _02_FUNCIONES_Y_ALCANCE\r\n{\r\n    internal class Program\r\n    {\r\n       \r\n\r\n        static void Main(string[] args)\r\n        {\r\n            /*\r\n * EJERCICIO:\r\n * - Crea ejemplos de funciones básicas que representen las diferentes\r\n *   posibilidades del lenguaje:\r\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\r\n * - Comprueba si puedes crear funciones dentro de funciones.\r\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\r\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\r\n * - Debes hacer print por consola del resultado de todos los ejemplos.\r\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\r\n *\r\n * DIFICULTAD EXTRA (opcional):\r\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\r\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\r\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\r\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\r\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\r\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\r\n *\r\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\r\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\r\n */\r\n\r\n            string variableGlobal = \"soy global\"; //  variable global\r\n\r\n            // METODO SIN PARAMETROS\r\n\r\n            MetodoSinParametros();\r\n\r\n            // METODO CON PARAMETROS\r\n\r\n            Suma(15, 30);\r\n\r\n            // METODO CON RETORNO\r\n\r\n            static bool MetodoConRetorno()\r\n            {\r\n                bool resultado = false;\r\n                string palabra = \"edificio\";\r\n                if (\"aeiou\".Contains(palabra[0]))\r\n                {\r\n                    resultado = true;\r\n                }\r\n                else\r\n                {\r\n                    resultado = false;\r\n                }\r\n                return resultado;\r\n            }\r\n\r\n            bool resultado = MetodoConRetorno();\r\n\r\n            if (resultado)\r\n            {\r\n                Console.WriteLine(\"la palabra empieza con vocal\");\r\n            }\r\n            else\r\n            {\r\n                Console.WriteLine(\"la palabra empieza con consonante\");\r\n            }\r\n\r\n            Metodo1(\"edificio\");  // puedo ejecutar ambos metodos solamente llamando el Metodo1 ya que al llamar ese metodo se llama el otro\r\n\r\n            \r\n            // METODOS YA EXISTENTES EN C#\r\n\r\n            string palabra = \"Hola\";\r\n            string mayusculas = palabra.ToUpper(); // \"HOLA\"\r\n            string minusculas = palabra.ToLower(); // \"hola\"\r\n\r\n            Console.WriteLine(mayusculas);\r\n            Console.WriteLine(minusculas);\r\n\r\n            // METODO CON VARIABLE LOCAL\r\n\r\n            static void VariableLocal()\r\n            {\r\n                string variableLocal = \"soy local\"; // variable local\r\n            }\r\n\r\n\r\n            DificultadExtra(\"primer texto\", \"segundo texto\");\r\n        }\r\n\r\n\r\n        // METODO SIN PARAMETROS \r\n\r\n        static void MetodoSinParametros()\r\n        {\r\n            Console.WriteLine(\"este es el metodo ejecutandose\");\r\n        }\r\n\r\n        // METODO CON PARAMETROS\r\n\r\n        static void Suma(int a, int b)\r\n        {\r\n            Console.WriteLine($\"la suma de {a} + {b} es: {a + b} \");\r\n        }\r\n\r\n        // METODO DENTRO DE OTRO METODO\r\n\r\n        static void Metodo1(string palabra) // este es el primer metodo\r\n        {\r\n            Metodo2(palabra);  // podemos llamar a Metodo2 dentro de Metodo1\r\n        }\r\n\r\n        static void Metodo2(string palabra)   // este es el segundo metodo que se ejecuta cuando es llamado desde el primer metodo\r\n        {\r\n            if (\"aeiou\".Contains(palabra[0]))\r\n            {\r\n                Console.WriteLine(\"empieza con vocal\");\r\n            }\r\n            else\r\n            {\r\n                Console.WriteLine(\"empieza con consonante\");\r\n            }\r\n        }\r\n\r\n        static int DificultadExtra(string a, string b)\r\n        {\r\n            int numerosContados = 0;\r\n\r\n            for(int i = 1; i <= 100; i++)\r\n            {\r\n                if (i % 3 == 0 && i % 5 == 0)\r\n                {\r\n                    Console.WriteLine(a + \" Y \" + b);\r\n                }\r\n                else if (i % 3 == 0)\r\n                {\r\n                    Console.WriteLine(a);\r\n                }\r\n                else if (i % 5 == 0)\r\n                {\r\n                    Console.WriteLine(b);\r\n                }\r\n                else\r\n                {\r\n                    Console.WriteLine(i);\r\n                    numerosContados++;\r\n                }\r\n            }\r\n\r\n            return numerosContados;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c#/Isj-code.cs",
    "content": "﻿// El WriteLine es una función ya creada en el lenguaje.\n// Variables globales\nint num1 = 4;\nint num2 = 5;\n\n// Función sin retorno ni parámetro\nvoid FuncionSinParametro()\n{\n    Console.WriteLine(\"Pues eso, no te devuelvo nada\");\n}\n\nFuncionSinParametro();\n\nvoid FuncionConParametros(int a, int b)\n{\n    int suma = a + b;\n    Console.WriteLine($\"La suma de a y b es: {suma}\");\n}\n\nFuncionConParametros(3, 5);\n\n// En el ejemplo anterior se muestra el Scope de la variable Local\n// Esto marca error ya que intentamos imprimir una variable local del método anterior.\n// Console.WriteLine(suma);\n\nstring FuncionQueTeSaluda(string nombre)\n{\n    return $\"¡¡Hola {nombre}!!\";\n}\n\nConsole.WriteLine(FuncionQueTeSaluda(\"José\"));\n\n// Funcion dentro de funcion\n\nvoid FuncionConFunciones(string nombre)\n{\n    // Mas funciones del Lenguaje que quitan espacios al principio, final y alacance de variables\n    \n    void LongitudDeNombre()\n    {\n        int longitud = nombre.TrimStart().TrimEnd().Length;\n        Console.WriteLine($\"Tu nombre tiene {longitud} carácteres\");\n    }\n\n    void PrimeraLetra()\n    {\n        string nombreSinEspacios = nombre.TrimStart().TrimEnd();\n        char letra = nombreSinEspacios[0];\n        Console.WriteLine($\"La primera letra de tu nombre es {letra}\");\n    }\n    \n    LongitudDeNombre();\n    PrimeraLetra();\n}\n\nFuncionConFunciones(\" José \");\n\n// OPCIONAL\n\nint DificultadExtra(string a, string b)\n{\n    int conteoNum = 0;\n\n    for (int i = 1; i <= 100; i++)\n    {\n        if (i % 3 == 0 && i % 5 == 0)\n        {\n            Console.WriteLine($\"{a}, {b}\");\n        }\n        else if (i % 3 == 0)\n        {\n            Console.WriteLine(a);\n            \n        }\n        else if(i % 5 == 0 )\n        {\n            Console.WriteLine(b);\n        }\n        else\n        {\n            Console.WriteLine(i);\n            conteoNum++;\n        }\n    }\n    \n    return conteoNum;\n}\n\n\nConsole.WriteLine(DificultadExtra(\"Multiplo de 3\", \"Multiplo de 5\"));"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c#/IvanCalero04.cs",
    "content": "// Funcion sin parametros ni retorno.\nvoid SinParametros()\n{\n    Console.WriteLine(\"Esto es una función sin valores ni retorno.\");\n}\n\nSinParametros();\n\n// Función con dos parametros y retorno.\nint area = CalcularAreaRectangulo(10, 5);\nConsole.WriteLine($\"El area es: {area}\");\n\nint CalcularAreaRectangulo(int bas, int alt) \n{\n    return bas * alt;\n}\n\n// Otra función un poco mas compleja.\nUsuario(\"Iván\",21);\nUsuario(\"Alfonso\",8);\nvoid Usuario(string nombre, int edad)\n{\n    Console.WriteLine($\"Hola, {nombre} tienes {edad} años.\");\n    \n    if (edad < 18)\n    {\n        int contador = 0;\n        for (int i = edad; i < 18; i++ )\n        {\n            contador++;\n        }\n        Console.WriteLine($\"A este usuario todavía le faltan {contador} para ser mayor de edad.\");  \n        \n    } \n    else\n    {\n        Console.WriteLine(\"Este usuario es mayor de edad\");\n    }\n}\n\n// Comprueba si puedes crear una función dentro de una función.\n\nvoid Padre()\n{\n    void Hijo()\n    {\n        Console.WriteLine(\"Hola Soy una función llamada Hijo que esta dentro de una llamada Padre.\");\n    }\n    Hijo();\n}\nPadre();\n\nConsole.WriteLine(\"Inserta un valor: \");\nConsole.ReadLine();\n//Console.Clear() (Limpia la pantalla de la terminal.)\nMath.Round(1.23454, 2); //Redondea un número a los decimales que le pidas (vital para facturación).\nMath.Max(1, 100); //Te devuelve el número más grande entre dos valores.\nMath.Abs(-20); //Devuelve el valor absoluto (convierte negativos en positivos).\n\n\n\n// - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n\n// variable Local:\n\nvoid EdadLocal()\n{\n    int edadLocal = 10;\n    Console.WriteLine(edadLocal);\n}\n\nEdadLocal();\n\n\n\nUsuario usuario1 = new Usuario();\nusuario1.Nombre();\nusuario1.Edad();\n\n\nProducto producto1 = new();\nproducto1.MostrarInfo();\n\n\n// Ejecucion del Ejercicio Extra.\nConsole.WriteLine(\"---------Ejercicio Extra-------------\");\n\nRetornoParam(\"Iván\", \"Calero\");\n\nConsole.WriteLine(\"---------Fin----------\");\nint RetornoParam(string nombre, string apellido)\n{\n    int contador = 0;\n    for (int i = 1; i <= 100; i++)\n    {\n        \n\n        if (i % 3 == 0  && i % 5 == 0)\n        {\n            Console.WriteLine(nombre + apellido);\n        } \n        else if (i % 3 == 0)\n        {\n            Console.WriteLine(nombre);\n        }\n        else if (i % 5 == 0)\n        {\n            Console.WriteLine(apellido);\n        }\n        else\n        {\n            Console.WriteLine(i);\n            contador++;\n        }\n    }\n    return contador;\n}\n// Global\nclass Usuario\n{\n    int edadGlobal = 21;\n    string nombreUsuario = \"Iván\";\n    public void Edad()\n    {\n        Console.WriteLine(edadGlobal);\n    }\n    public void Nombre()\n    {\n        Console.WriteLine(nombreUsuario);\n    }\n}\n\nclass Producto\n{\n    int idProducto = 1;\n    string nombreProducto = \"Camiseta\";\n    public void MostrarInfo()\n    {\n        Console.WriteLine(idProducto);\n        Console.WriteLine(nombreProducto);\n    }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c#/JoseEsmil04.cs",
    "content": "using System;\n\nnamespace _02_Funciones_Alcance\n{\n    internal class Program\n    {\n        // Variable Global (Colocarle static)\n        static int globalVar = 24;\n\n        static void Main(string[] args)\n        {\n            // Funcion sin parámetros ni retorno\n            SinParametrosNiRetorno();\n\n            // Funcion con un parámetro\n            ConUnParametro(\"JoseEsmil04\");\n\n            // Funcion con varios parámetros\n            ConVariosParametros(\"Hola\", \"estoy aprendiendo C#!\");\n\n            // Funcion con retorno\n            int suma = ConRetorno(5, 10);\n            Console.WriteLine($\"La suma es: {suma}\");\n\n            // Funcion ya creada en el lenguaje\n            Console.WriteLine(\"Esto es una Funcion ya creada en el lenguaje.\");\n\n            // Variables locales\n            int localVar = 20;\n            Console.WriteLine($\"Variable local: {localVar}\");\n            Console.WriteLine($\"Variable global: {globalVar}\");\n\n            // Funcion de la dificultad extra\n            int count = ImprimirNumeros(\"Fizz\", \"Buzz\");\n            Console.WriteLine($\"Las veces que imprimieron números en lugar de textos: {count}\");\n\n        }\n\n        static void SinParametrosNiRetorno()\n        {\n            Console.WriteLine(\"Funcion sin Parametros ni Retorno!\");\n        }\n\n        static void ConUnParametro(string str)\n        {\n            Console.WriteLine($\"Esta funcion tiene un parametro y es: {str}\");\n        }\n\n        static void ConVariosParametros(string str, string str2)\n        {\n            Console.WriteLine($\"Mensaje: {str} {str2}\");\n        }\n\n        static int ConRetorno(int num1, int num2)\n        {\n            return num1 + num2;\n        }\n\n        static int ImprimirNumeros(string str, string str2)\n        {\n            int count = 0;\n\n            for (int i = 1; i <= 100; i++)\n            {\n                if (i % 3 == 0 && i % 5 == 0)\n                {\n                    Console.WriteLine($\"{str}{str2}\");\n                }\n                else if (i % 3 == 0)\n                {\n                    Console.WriteLine(str);\n                }\n                else if (i % 5 == 0)\n                {\n                    Console.WriteLine(str2);\n                }\n                else\n                {\n                    Console.WriteLine(i);\n                    count++;\n                }\n            }\n\n            return count;\n        }\n\n    }\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c#/JuanPVelasquezR.cs",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones bsicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parmetros ni retorno, con uno o varios parmetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algn ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer ms o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una funcin que reciba dos parmetros de tipo cadena de texto y retorne un nmero.\n * - La funcin imprime todos los nmeros del 1 al 100. Teniendo en cuenta que:\n *   - Si el nmero es mltiplo de 3, muestra la cadena de texto del primer parmetro.\n *   - Si el nmero es mltiplo de 5, muestra la cadena de texto del segundo parmetro.\n *   - Si el nmero es mltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La funcin retorna el nmero de veces que se ha impreso el nmero en lugar de los textos.\n *\n * Presta especial atencin a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el cdigo se entienda.\n */\n\n\ninternal class Program\n{\n    static bool globalVariable = true;\n\n    static void Main(string[] args)\n    {\n\n        /*\n          * EJERCICIO:\n          * - Crea ejemplos de funciones bsicas que representen las diferentes\n          *   posibilidades del lenguaje:\n          *   Sin parmetros ni retorno, con uno o varios parmetros, con retorno...\n          * - Comprueba si puedes crear funciones dentro de funciones.\n          * - Utiliza algn ejemplo de funciones ya creadas en el lenguaje.\n          * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n          * - Debes hacer print por consola del resultado de todos los ejemplos.\n          *   (y tener en cuenta que cada lenguaje puede poseer ms o menos posibilidades)\n          *\n          * DIFICULTAD EXTRA (opcional):\n          * Crea una funcin que reciba dos parmetros de tipo cadena de texto y retorne un nmero.\n          * - La funcin imprime todos los nmeros del 1 al 100. Teniendo en cuenta que:\n          *   - Si el nmero es mltiplo de 3, muestra la cadena de texto del primer parmetro.\n          *   - Si el nmero es mltiplo de 5, muestra la cadena de texto del segundo parmetro.\n          *   - Si el nmero es mltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n          *   - La funcin retorna el nmero de veces que se ha impreso el nmero en lugar de los textos.\n          *\n          * Presta especial atencin a la sintaxis que debes utilizar en cada uno de los casos.\n          * Cada lenguaje sigue una convenciones que debes de respetar para que el cdigo se entienda.\n          */\n\n        FuncionSinRetorno();\n\n        FuncionParametros(40000, 6, \"Null\");\n\n        Console.WriteLine($\"El precio del producto es: {FuncionRetorno(3000, 3)}\");\n\n        //El mismo Console.Writeline es una funcin propia del lenguaje\n\n\n\n\n\n        // Dificultad extra\n\n        Console.WriteLine(Desafio(\"Hola\", \"Mundo\"));\n\n    }\n\n\n    static void FuncionSinRetorno()\n    {\n        Console.WriteLine(\"Funcin sin parmetros\");\n    }\n\n    static void FuncionParametros(int precio, int cantidad, string perfil)\n    {\n        if (precio >= 30000 && cantidad > 4) { perfil = \"VIP\"; }\n\n        Console.WriteLine($\"El cliente tiene perfil: {perfil}\");\n\n    }\n\n\n    static int FuncionRetorno(int precio, int Cantidad)\n    {\n\n        return precio + Cantidad;\n\n\n    }\n\n\n\n    public void FuncionInception()\n    {\n        /*     try\n             {\n                static void Funcion()\n                 {\n\n                     Console.WriteLine(\"Es posible\");\n                 }\n\n             }\n             catch (Exception ex)\n             {\n                 Console.WriteLine(\"No es posible\");\n\n             }\n        */\n\n\n\n\n    }\n\n\n    static int Desafio(string cadena1, string cadena2)\n    {\n        int j = 0;\n        for (int i = 1; i <= 100; i++)\n        {\n            j = i;\n\n            if (i % 3 != 0 && i % 5 != 0)\n            {\n                Console.WriteLine(i);\n            }\n            else if (i % 3 == 0 && i % 5 == 0)\n            {\n                Console.WriteLine($\"{cadena1} {cadena2}\");\n            }\n            else if (i % 3 == 0)\n            {\n                Console.WriteLine(cadena1);\n            }\n            else if (i % 5 == 0)\n            {\n                Console.WriteLine(cadena2);\n            }\n        }\n\n        return j;\n\n    }\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c#/Kvr0th3c4t.cs",
    "content": "//Funciones definidas por el ususario\n\n//Simple\n\nusing System.Net.Mime;\n\nint Sumar(int a, int b)\n{\n    return a + b;\n}\n\n//Sin que devuelva nada\n\nvoid Saludar()\n{\n    Console.WriteLine(\"Hola\");\n}\n\n//Métodos static\n\nstatic string Saludo()\n{\n    return \"Hola que tal\";\n}\n\nConsole.WriteLine(Saludo());\n\n//Expresiones lambda\n\nint Saludar(int x, int y) => x + y;\n\n//Funciones locales\n\nvoid Ejemplo()\n{\n    void EnElEjemplo()\n    {\n    }\n}\n\n//Métodos preddefinidos (built-in)\n\n//Para strings\n\nstring ejemplo = \"\";\n\nejemplo.ToUpper();      //Mayúsculas\nejemplo.ToLower();      //Minúsculas\nejemplo.Length;         //Longitud\nejemplo.Contains();     //Contiene el parámetro\nejemplo.Replace();      //Reemplaza contenido\n\n//Consola\n\nConsole.WriteLine();    //Print\nConsole.ReadLine();     //Leer input\n\n//Matemáticas\n\nMath.Max();     //Máximo \nMath.Min();     //Mínimo    \nMath.Sqrt();    //Raíz cuadrada\nMath.Pow();     //Potencia\nMath.Abs();     //Valor absoluto\n\n//Arrays/Listas\n\nArray.Sort();   //Ordenar un array\nList.Add();     //Añadir a una lista\nList.Count();   //contar elementos de una lista\n\n//conversiones\n\nint.Parse();        //Convertir en int\nConvert.ToInt32();  //Convertir a int\n\n/*\n    DIFICULTAD EXTRA:\n\n    Crea una función que reciba dos parámtros de tipo caena de texto y retorne un número.\n\n    * La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n        * Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n        * Si el número es múltiplo de 5, muestra la cadena e texto del segundo parámetro.\n        * Si el número es múltiplo dde 3 y dde 5, muestra las dos cadenas de texto concatenadas.\n    * La función retorna el número de veces uq ese ha impreso el número en lugar de los textos. \n*/\n\nstatic int FizzBuzz(string Fizz, string Buzz)\n{\n    int contadorNum = 0;\n    for (int i = 1; i < 101; i++)\n    {\n        if (i % 15 == 0)\n        {\n            Console.WriteLine(Fizz + Buzz);\n        }\n        else if (i % 3 == 0)\n        {\n            Console.WriteLine(Fizz);\n        }\n        else if (i % 5 == 0)\n        {\n            Console.WriteLine(Buzz);\n        }\n        else\n        {\n            Console.WriteLine(i);\n            contadorNum++;\n        }\n    }\n    return contadorNum;\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c#/RXVLC.cs",
    "content": "﻿using System;\n\nnamespace R02___2024\n{\n    internal class Program\n    {\n\n        // Función sin parámetros ni retorno:\n        static void SinParametrosNiRetorno()\n        {\n            Console.WriteLine(\"\\nFunción sin parámetros ni retorno.\");\n        }\n\n        //Función con uno / varios parámetros\n        static void ConUnoOVariosParametros(string p1, string p2)\n        {\n            Console.WriteLine($\"\\nEste es el parámetro {p1}\");\n            Console.WriteLine($\"\\nEste es el parámetro {p2}\");\n        }\n\n        //Función con retorno\n        static int FuncionConRetorno()\n        {\n            Random rand = new Random();\n            return rand.Next(0, 10);\n        }\n\n        // Variable global dentro de la clase Program\n        private static string variableGlobal = \"Soy una variable global\";\n\n        //Función de dificultad extra\n        static int DifExtra(string s1, string s2)\n        {\n            int cont = 0;\n            for (int i = 1; i <= 100; i++)\n            {\n                if (i % 3 == 0 && i % 5 == 0)\n                {\n                    Console.Write($\" {s1}\");\n                    cont++;\n                }\n                else if (i % 5 == 0)\n                {\n                    Console.Write($\" {s2}\");\n                    cont++;\n                }\n                else if (i % 3 == 0)\n                {\n                    Console.Write($\" {s1 + s2}\");\n                    cont++;\n                }\n            }\n            return cont;\n        }\n\n        static void Main(string[] args)\n        {\n            string p1 = \"uno\";\n            string p2 = \"dos\";\n\n            SinParametrosNiRetorno();\n\n            ConUnoOVariosParametros(p1, p2);\n\n            Console.WriteLine($\"\\nEsto es el return de una función que retorna un numero random {{0..10}}: {FuncionConRetorno()}\");\n\n            //No podría meter una función dentro de otra, pero podría crear una clase con varias funciones.\n\n            //Funciones ya creadas en c#: Por ejemplo el compareTo\n\n            int x = 3;\n            Console.WriteLine($\"\\nCompare to: {x.CompareTo(3)}\");\n\n            //La variable p1 y p2 son locales, debido a que solo se usan en Main\n            //Sin embargo la variable variableGlobal es global ya que se puede usar desde la clase program en cualquier función.\n            Console.WriteLine($\"\\n{variableGlobal}\\n\");\n\n            Console.WriteLine(\"Dificultad extra:\\n\");\n            string s1 = \"fizz\", s2 = \"buzz\";\n\n            Console.WriteLine($\"\\n\\nEl numero ha salido {DifExtra(s1, s2)} veces\");\n\n            Console.ReadKey();\n\n\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c#/XPERIARGLUNA.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace ConsoleApp4\n{\n    internal class Program\n    {\n        static void Saludar()      //Función sin parámetro ni retorno\n        {\n            Console.WriteLine(\"¡Hola,C#\");\n        }\n\n        static void SaludarPersona(string nombre) //Función con un parámetro\n        {\n            Console.WriteLine($\"Hola, {nombre}\");\n        }\n\n        static int Sumar(int valor1, int valor2) //Función con varios parametros y retorno\n        { \n            return valor1 + valor2;\n        }\n\n        static int OperaciónCompleja(int x)  //Función dentro de otra\n        { \n            int Cuadrado(int n)\n            { \n                return n * n;\n            }\n            return Cuadrado(x) + x;\n        }\n\n        //Función ya creadas por el lenguaje\n        static void FuncionBuiltIn()\n        {\n            string texto = \"Hola Mundo\";\n            Console.WriteLine($\"Texto en minúsculas: {texto.ToLower()}\");\n        }\n\n        //Variables Locales y Globales\n        static string variableGlobal = \"Soy global\";\n\n        static void PruebaVariables()\n        {\n            string variableLocal = \"Soy local\";\n            Console.WriteLine($\"Dentro de la función: {variableGlobal}\");\n            Console.WriteLine($\"Dentro de la función: {variableLocal}\");\n        }\n\n        //EXTRA\n        static int ImprimirNúmeros(string parametro1, string parametro2)\n        {\n            int contador = 0;\n            for (int i = 1; i <= 100; i++)\n            {\n                string output = \"\";\n                if (i % 3 == 0)\n                {\n                    output += parametro1;\n                }\n\n                if (i % 5 == 0)\n                {\n                    output += parametro2;\n                }\n                if(string.IsNullOrEmpty(output))\n                {\n                    Console.WriteLine(i);\n                    contador++;\n                }\n            else\n                {\n                    Console.WriteLine(output);\n                }\n            }\n            return contador;\n        }\n\n        static void Main(string[] args)\n        {\n            // 1. Función sin parámetros ni retorno\n            Saludar();\n\n            // 2. Función con un parámetro\n            SaludarPersona(\"Jesús\");\n\n            // 3. Función con múltiples parámetros y retorno\n            int resultadoSuma = Sumar(7, 8);\n            Console.WriteLine($\"Resultado de la suma: {resultadoSuma}\");\n\n            // 4. Función dentro de función\n            int resultadoOperacion = OperaciónCompleja(5);\n            Console.WriteLine($\"Resultado de operación compleja: {resultadoOperacion}\");\n\n            // 5. Uso de funciones incorporadas\n            FuncionBuiltIn();\n\n            // 6. Variables globales y locales\n            PruebaVariables();\n            // Console.WriteLine(variableLocal); // Esto daría error porque la variable es local\n\n            // DIFICULTAD EXTRA\n            int vecesImpresoNumero = ImprimirNúmeros(\"Fizz\", \"Buzz\");\n            Console.WriteLine($\"Números impresos en lugar de texto: {vecesImpresoNumero}\");\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c#/abrahamraies.cs",
    "content": "// Author: Abraham Raies https://github.com/abrahamraies\n\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n\nusing System;\n\nclass Program\n{\n    static string variableGlobal = \"variable global\";\n\n    static void Main(string[] args)\n    {\n        //Funciones:\n        Console.WriteLine(\"Funciones\");\n        Saludar(); //Sin parametros\n        SaludarA(\"Julio\"); //Con parametro\n        DespedirA(\"Julio\",25); //Con parametros y retorno\n\n        Console.WriteLine(Calcular(4,5)); //Funcion que llama a otra funcion\n\n        //Random -- funcion creada por el lenguaje\n        Random random = new Random();\n        Console.WriteLine(random.Next());\n\n        // variables globales y locales\n        Console.WriteLine(\"Variables globales y locales\");\n        Scopes();\n\n        // Ejercicio extra\n        Console.WriteLine(\"Ejercicio Extra\");\n        EjercicioExtra(\"Agua\",\"Fuego\");\n\n    }\n\n    // Funcion sin parametros:\n    static void Saludar()\n    {\n        Console.WriteLine(\"Hola, ¿como va?\");\n    }\n    // Funcion con parametro:\n    static void SaludarA(string name){\n        Console.WriteLine($\"Hola {name}, ¿como va?\");\n    }\n    // Funcion con parametros y retorno:\n    static string DespedirA(string name,int edad){\n        return $\"Hola {name}, ¿tenes {edad} años?\";\n    }\n\n    // Funcion que llama a otra funcion\n    static int Calcular(int num1,int num2){\n\n        int Suma(int num1,int num2) => num1 + num2;\n\n        return Suma(num1,num2);\n    }\n\n    // Scopes de funciones (alcance)\n    static string Scopes(){\n        string variableLocal = \"variable local\";\n        Console.WriteLine(variableGlobal);\n        Console.WriteLine(variableLocal); //Fuera de esta funcion no existe la variable \"variableLocal\"\n    }\n\n    // Ejercicio extra\n    static int EjercicioExtra(string palabra1,palabra2){\n        int contador = 0;\n        for(int i = 1; i <= 100; i++){\n            if(i % 3 == 0 && i % 5 == 0){\n                Console.WriteLine(palabra1+palabra2);\n            }else if(i % 5 == 0){\n                Console.WriteLine(palabra2);\n            }else if(i % 3 == 0){\n                Console.WriteLine(palabra1);\n            }else{\n                Console.WriteLine(i);\n                contador++;\n            }\n        }\n        return contador;\n    }\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c#/angelsanchezt.cs",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\nusing System;\n\nclass Roadmap_02\n{\n\n    public static string VariableGlobal = \"Roadmap_02\";\n\n    // Funciones sin parametros ni valor de retorno\n    static void FuncionSinParametroSinRetorno()\n    {\n        Console.WriteLine(\"Funcion Sin Parametros y Sin Retorno\");\n    }\n\n    // Funciones sin parametros pero con valor de retorno.\n    static string FuncionSinParametrosConRetorno()\n    {\n        return \"Funcion Sin Parametros y Con Retorno\";\n    }\n\n    // Funciones con parametros pero sin valor de retorno\n    static void FuncionConParametrosSinRetorno(int a, int b)\n    {\n        Console.WriteLine($\"Funcion Con Parametros sin retorno: suma {a} + {b} = {a + b}\");\n    }\n\n    // Funciones con parametros y valor de retorno\n    static string FuncionConParametrosConRetorno(string nombre, string apellido)\n    {\n        return $\"Hola {nombre} {apellido}\";\n    }\n\n    // Funciones dentro de una funcion\n    static void Calculadora(int a, int b)\n    {\n\n\n        int Suma(int a, int b)\n        {\n            return a + b;\n        }\n\n        int Resta(int a, int b)\n        {\n            return a - b;\n        }\n\n        int Multiplicacion(int a, int b)\n        {\n            return a * b;\n        }\n\n        float Division(int a, int b)\n        {\n            return a / b;\n        }\n\n        Consola.WriteLine($\"Suma : {a} + {b} = {Suma(a, b)}\");\n        Consola.WriteLine($\"Resta : {a} - {b} = {Resta(a, b)}\");\n        Consola.WriteLine($\"Multiplicacion : {a} * {b} = {Multiplicacion(a, b)}\");\n        Consola.WriteLine($\"Division : {a} / {b} = {Division(a, b)}\");\n    }\n\n\n    public static int RetoExtra(string str1, string str2)\n    {\n        int contadorNumeros = 0;\n\n        for (int i = 1; i <= 100; i++)\n        {\n            if (i % 3 == 0 & i % 5 == 0)\n            {\n                Console.WriteLine($\"{str1} {str2}\");\n            }\n            else if (i % 3 == 0)\n            {\n                Console.WriteLine(str1);\n            }\n            else if (i % 5 == 0)\n            {\n                Console.WriteLine(str2);\n            }\n            else\n            {\n                Console.WriteLine(i);\n                contadorNumeros++;\n            }\n        }\n\n        return contadorNumeros;\n    }\n\n    static void Main(string[] args)\n    {\n        FuncionSinParametroSinRetorno();\n\n        string resultado1 = FuncionSinParametrosConRetorno();\n        Console.WriteLine(resultado1);\n\n        FuncionConParametrosSinRetorno(5, 12);\n\n        string resultado2 = FuncionConParametrosConRetorno();\n        Console.WriteLine(resultado2);\n\n        Calculadora(5, 12);\n\n        // Función lambda\n        Func<int, int> square = x => x * x;\n        Console.WriteLine(square(9));\n\n        // Función del propio lenguaje.\n        string alfabeto = \"ABCDEFGHIJKLMNOPQRSTVWYZ\";\n        Console.WriteLine(alfabeto.ToLower());\n\n        // Vareiable Glogal\n        Console.WriteLine(VariableGlobal);\n\n        // Variables locales\n        static void VariablesLocales()\n        {\n            int a = 1;\n            int b = 2;\n            Console.WriteLine($\"{a} + {b} = {a + b}\");\n        }\n\n        string s1 = \"fizz\", s2 = \"buzz\";\n        Console.WriteLine($\"\\n\\nEl numero ha salido {RetoExtra(s1, s2)} veces\");\n\n\n    }\n\n\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c#/arkmiguel379.cs",
    "content": "﻿//====================== FUNCIONES ============================\n\n// Funcion sin valor de retorno y sin parametros\n\nvoid Saludar()\n{\n    Console.WriteLine(\"Hola mundo\");\n}\n\nSaludar();\n\n// Funcion con retorno sin parametros\n\nint ObtenerNumero()\n{\n    return 379;\n}\n\nConsole.WriteLine(ObtenerNumero());\n\n//Funcion sin valor de retorno con parametros\n\nvoid Mensaje(string mensaje)\n{\n    Console.WriteLine(mensaje);\n}\n\nMensaje(\"Logan\");\n\n// Funcion con retorno y parametros\n\nint Suma(int a, int b)\n{\n    return a + b;\n}\n\nConsole.WriteLine(Suma(5, 3));\n\n// Funcion con paremetros opcionales o predeterminados\n\nvoid Informacion(string nombre, int edad, int categoria = 0)\n{\n    Console.WriteLine($\"Nombre: {nombre}, Edad: {edad}, Categoria: {categoria}\");\n}\n\nInformacion(\"Miguel\", 28);\n\n// Funciones con parametros de salida\n\nint value1 = 10;\nint value2 = 2;\nint resultadocociente;\nint resultadoresto;\n\nvoid ResultadoDivision(int dividendo, int divisor, out int cociente, out int resto)\n{\n    cociente = dividendo / divisor;\n    resto = dividendo % divisor;    \n}\n\nResultadoDivision(value1, value2, out resultadocociente, out resultadoresto);\n\nConsole.WriteLine($\"El resultado de la division es {resultadocociente}\\nY el resto es {resultadoresto}\");\n\n\n//==================== FUNCIONES DENTRO DE FUNCIONES =============================\n\nvoid FuncionExterna()\n{\n    Console.WriteLine(\"Inicio de la funcion externa\");\n\n    void FuncionInterna()\n    {\n        Console.WriteLine(\"Ejecucion de la funcion interna\");\n    }\n\n    FuncionInterna();\n\n    Console.WriteLine(\"Fin de la funcion externa\");\n}\n\nFuncionExterna();\n\n//======================= FUNCIONES DEL SISTEMA =============================\n\nint numero = Convert.ToInt32(\"97\"); // <-- Funcion para convertir a INT algún valor\n\nstring cadena = Convert.ToString(\"257\"); // <-- Funcion para convertir a STRING algún valor\n\nstring mayusculas = \"palabra\".ToUpper(); // <-- Funcion para pasar a mayusculas todas las letras de una cadena\nConsole.WriteLine(mayusculas);\n\nstring minusculas = \"FRASE PARA CAMBIAR A MINUSCULAS\".ToLower(); // <-- Funcion para pasar a minusculas todas las letras de una cadena\nConsole.WriteLine(minusculas);\n\nint[] funcionSuma = {2,4,6,8,10};\nint suma = funcionSuma.Sum(); // <-- Funcion para sumar los valores dentro de una coleccion de valores\n\nConsole.WriteLine(suma);\n\nDateTime hoy = DateTime.Now;\nConsole.WriteLine(hoy);\n\nint año = hoy.Year;\nConsole.WriteLine(año);\n\n//=============================== EXTRA ======================================\n\nint funcionE(string str1, string str2)\n{\n    int contador = 0;\n\n    for (int i = 1; i <= 100; i++)\n    {\n        if (i % 3 == 0 && i % 5 == 0)\n        {\n            Console.WriteLine($\"{str1} + {str2}\");\n        }\n        else if (i % 3 == 0)\n        {\n            Console.WriteLine(str1);\n        }\n        else if (i % 5 == 0) \n        { \n            Console.WriteLine(str2);\n        }\n        else\n        {\n            Console.WriteLine(i);\n            contador++;\n        }\n    }\n\n    return contador;\n}\n\nfuncionE(\"Primera cadena\", \"Segunda cadena\");"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c#/charlerodriguez3.cs",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n*/\n\n\n\nNumber100(\"hello-3\", \"world-5\");\nWriteSomething();\nWriteMyWord(\"This is the word. Hello my friend\");\nint num = 0;\nnum = NewValue();\n\n\n//programming language function already created\nstring word3 = \"This is not a word but a sentence\";\n\n\n//substring is a function which cuts a parts of a string, having in count that\n//the first parameter will be the number of the index start to cut a part of the string, and the second parameter is the length\nword3.Substring(0, 4);\n\n//WITHOUT PARAMETERS\n//WITHOUT RETURN\nprivate static void WriteSomething()\n{\n    Console.WriteLine(\"tHiS iS A cRaZy TexT\");\n}\n\n\n\n\n//WITH ONE PARAMETER AND NO RETURN\n\nprivate static void WriteMyWord(string v)\n{\n    Console.WriteLine(v);\n}\n\n\n\n//WITH RETURN AND NO PARAMETERS\n\nprivate static int NewValue()\n{\n    return 5;\n}\n\n//WITH TWO OR MORE PARAMETERS\n//WITH RETURN\n\n public static int Number100(string word1,  string word2)\n {\n     int times = 0;\n     for(int i = 1; i <= 100; i++) {\n\n         if(i % 3 == 0 && i % 5 == 0) Console.WriteLine($\"{word1} {word2}\");\n         else if(i % 3 == 0) Console.WriteLine(word1);\n         else if(i % 5 == 0) Console.WriteLine(word2);\n         else\n         {\n            Console.WriteLine(i);\n            times++;\n         }\n     }\n\n     return times;\n }\n\n\n//global and local variables\n\n static void Main(string[] args)\n { \n     int num = 0;\n\n     num = NewValue(num);\n     Console.WriteLine(num);\n     //the variable numLocal only exists inside the method NewValue\n     Console.WriteLine(numLocal); // this is an error \n }\n\n \n private static int NewValue(int num)\n {\n     int numLocal = 20;\n     Console.WriteLine($\" I can access to this global variable {num} from here beucase it is global\");\n     return num + numLocal;\n }\n\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\nNumber100(\"hello-3\", \"world-5\");\n\n public static int Number100(string word1,  string word2)\n{\n    int times = 0;\n    for(int i = 1; i <= 100; i++) {\n\n        if(i % 3 == 0 && i % 5 == 0) Console.WriteLine($\"{word1} {word2}\");\n        else if(i % 3 == 0) Console.WriteLine(word1);\n        else if(i % 5 == 0) Console.WriteLine(word2);\n        else\n        {\n           Console.WriteLine(i);\n           times++;\n        }\n    }\n\n    return times;\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c#/cristopherfdev.cs",
    "content": "\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n */\n\n using System;\n\n namespace Funciones; \n\n class program \n {\n    static string vGlobal = \"Variable Global\"; \n\n    static void Main(string[] args)\n    {\n        Hello();\n\n        greetPerson(\"Cristopher\"); \n\n        int additionS = addition (5,10);\n        Console.WriteLine (\" \" + additionS);\n        \n        //Funcion creada en el lenguaje\n        string text = \"hola mundo\";\n        Console.WriteLine(\"ToUpper convierte el texto a mayúscula: \" + text.ToUpper());\n\n        ShowVariable(); \n\n    }\n\n    //Función sin parámetros ni retorno \n    static void Hello()\n    {\n        Console.WriteLine(\"Hola! Esta es la función sin parámetros\"); \n    }\n\n    //Función con parámetro sin retorno\n    static void greetPerson(string name)\n    {\n        Console.WriteLine (\"Hola, \"+ name + \"!\");\n    }\n\n    //Función con parámetro y retorno \n    static int addition (int fNum, int sNum)\n    {\n        return fNum + sNum; \n    }\n\n    //Variable Local y Global\n    static void ShowVariable() \n    {\n        string Vlocal = \"Variable Local\"; \n        Console.WriteLine(Vlocal); \n        Console.WriteLine(vGlobal); \n    }\n\n}\n "
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c#/devcherry1.cs",
    "content": "using System;\n\nclass Program\n{\n    static void Main()\n    {\n        Console.WriteLine(nombres(\"Juan\", \"Pablo\"));\n        int conteo = extra(\"Multiplo de 3\", \"Multiplo de 5\");\n        Console.WriteLine($\"Conteo es: \" + conteo);\n    }\n    static int nombres(string parametro1, string parametro2)\n    {\n        int count;\n        count = parametro1.Length;\n        count += parametro2.Length;\n        return count;\n    }\n    static int extra(string parametro1, string parametro2)\n    {\n        int conteo = 0;\n        for( int i = 0 ; i <= 100 ; i++ )\n        {\n            if( i % 3 == 0 && i % 5 == 0)\n            {\n                Console.WriteLine(\"El numero \" + i + \" es \" + parametro1 + \" & \" + parametro2);\n            }\n            else if (i % 3 == 0){\n                Console.WriteLine(\"El numero \" + i + \" es \" + parametro1);\n            }\n            else if (i % 5 == 0){\n                Console.WriteLine(\"El numero \" + i + \" es \" + parametro2);\n            }\n            else\n            {\n                conteo += 1;\n                Console.WriteLine(i);\n            }\n        }\n        return conteo;\n    }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c#/elmarqueli.cs",
    "content": "/*\n\t=== Para realizar el ejercicio me vase en los delegados Func y action ===\n*/\n\nnamespace elmarqueli\n{\n  class Program\n  {\n    // Solo imprime por consola\n    static Action PrintHolaMundo = () => Console.WriteLine(\"Hola Mundo\\n\");\n  \n    // Recibe dos parametros de de tipo string e imprime por consola\n    static Action<string, string> PrintString = (str1, str2) => {Console.WriteLine($\"String1: {str1}\\nString2: {str2}\\n\"); };\n  \n    // Recibe dos parametors de tipo strigs y retorna la concatenacion de estos dos.\n    static Func<string, string, string> FuncConcatReturn = (str1, str2) => $\"{str1} {str2}\";\n  \n    // Recibe un entero retorna un string y dentro se resuelve otra funcion.\n    static Func<int, string> FuncCreatToFunc = (num) => {\n    \n      // Funcion interna act, recibe un entero y retorna el doble.\n      var act = (int x) => {\n        return x * 2;\n      };\n  \n      // Se ejecuta act con el parametro num y retora el valor en formato string.\n      return act.Invoke(num).ToString();\n    };\n  \n    // Dificultad extra\n    static Func<string, string, int> FuncMultiplos_3_5 = (str1,str2) => {\n  \n        // Delcaramos la variable en la cual se asiganra la función.\n        Func<int, int>? CountPrint = null;\n        var count = 0;\n  \n        // Se asigna la función anonima a la variable.\n        CountPrint = (x) => {\n          if (x < 100)\n          {\n            if (x % 3 == 0 && x % 5 == 0)\n              Console.WriteLine($\"{str1} {str2}\");\n            else if(x % 3 == 0)\n              Console.WriteLine($\"{str1}\");\n            else if (x % 5 == 0)\n              Console.WriteLine($\"{str2}\");\n            else\n            {\n              Console.WriteLine(x);\n              count +=1;\n            }\n    \n            return CountPrint!(x+1);\n          }\n          else\n            Console.WriteLine(x);\n          return x;\n        };\n  \n    CountPrint(1);\n\n    return count;\n    };\n  \n    // Global variable\n    static int Number = 12;\n  \n    static void Main(string[] args)\n    {\n      // Local variable\n      var text = \"Función nativa\";\n  \n      PrintHolaMundo();\n  \n      PrintString(\"Primer texto de prueva\", \"Segundo texto de prueva\");\n  \n      Console.WriteLine(FuncConcatReturn(\"Codeando en\", \"GitHub\")+\"\\n\");\n  \n      Console.WriteLine(FuncCreatToFunc(15) + \"\\n\");\n  \n      // WriteLiane como funcion del lenguaje\n      Console.WriteLine(text);\n  \n      Console.WriteLine($\"Total de numeros impreso: {FuncMultiplos_3_5(\"Fizz\", \"Buzz\")}\");\n    }\n  }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c#/estuardodev.cs",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\nusing System;\nusing System.Runtime.CompilerServices;\n\nclass Program\n{\n    // Esta variable es accesible por todo el programa\n    public string variableGlobal = \"Prueba\";\n\n    public static void Main(string[] args)\n    {\n        Program program = new Program();\n\n        // Funciones sin retorno y sin parámetros\n        FuncionSinRetornoPublica();\n        FuncionSinRetornoPrivada();\n        FuncionSinRetornoProtegida();\n\n        // No puedes llamar a FuncionSinRetornoNoEstatica directamente desde un método estático como Main\n        // Deberías crear una instancia de la clase Program y luego llamar a ese método\n        program.FuncionSinRetornoNoEstatica();\n\n        // De esta forma ejecutas un método asíncrono en un método no asíncrono\n        Task.Run(async () => await program.FuncionAsincronaSinRetornoPrivada());\n\n        // Funciones con parámetros y retornos\n        Console.WriteLine(Suma(5, 6));\n        Console.WriteLine(Minusculas(\"Hola\"));\n        Console.WriteLine(EsPalindromo(\"Ana\"));\n\n        // Prueba de método dentro de métodos\n        PruebaDeMetodos();\n\n\n        // Dificultad extra\n        Console.WriteLine(DificultadExtra(\"Uno\", \"Dos\"));\n    }\n\n    // Funciones sin retorno y sin parámetros\n    public static void FuncionSinRetornoPublica() { Console.WriteLine(\"No retorna nada pública\"); }\n    private static void FuncionSinRetornoPrivada() { Console.WriteLine(\"No retorna nada privada\"); }\n    protected static void FuncionSinRetornoProtegida() { Console.WriteLine(\"No retorna nada protegida\"); }\n    public void FuncionSinRetornoNoEstatica() {\n        // Esta variable solo es accesible dentro de este método\n        string variableLocal = \"Variable Local\";\n        Console.WriteLine(\"No retorna nada no estatica\"); \n    }\n    private async Task FuncionAsincronaSinRetornoPrivada() { await Task.Run(() => Console.WriteLine(\"No retorna nada, privada\")); }\n\n    // Funciones con parámetros y retornos\n    public static int Suma(int num1, int num2){ return num1 + num2; }\n    public static string Minusculas(string frase) { return frase.ToLower(); }\n    private static bool EsPalindromo(string texto1)\n    {\n        texto1 = texto1.ToLower();\n        if (texto1.Equals(texto1.Reverse())){\n            return true;\n        } else \n        { \n            return false; \n        }\n    }\n\n    // Prueba de método dentro de métodos\n    private static void PruebaDeMetodos()\n    { \n        // Si se puede crear métodos dentro de otros métodos, pero estos funcionan de forma local.\n        static bool MetodoDentro(int numero)\n        {\n            return numero == 5;\n        }\n\n        Console.WriteLine(MetodoDentro(5));\n    }\n\n    // Dificultad extra\n    private static int DificultadExtra(string valor1, string valor2)\n    {\n        int contador = 1;\n        int numerosImpresos = 0;\n        while (contador < 101)\n        {\n            if (contador % 3 == 0 && contador % 5 == 0)\n            {\n                Console.WriteLine(valor1 + \" \" + valor2);\n            } else if (contador % 5 == 0)\n            {\n                Console.WriteLine(valor2);\n            } else if (contador % 3 == 0)\n            {\n                Console.WriteLine(valor1);\n            }\n            else\n            {\n                Console.WriteLine(contador);\n                numerosImpresos++;\n            }\n            contador++;   \n        }\n        return numerosImpresos;\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c#/hequebo.cs",
    "content": "class Program\n{\n\n    // Variables Globales\n    static string variableGlobal = \"Esta es una variable global\";\n    static void Main(String[] args)\n    {\n        HolaMundo();\n        SaludoPersonalizado(\"Emilio\");\n\n        Console.WriteLine(\"Bienvenido a la calculador de IMC\");\n        Console.WriteLine(\"Ingresa tu peso en kg:\");\n        decimal peso = decimal.Parse(Console.ReadLine());\n        Console.WriteLine(\"Ingresa tu altura en mts\");\n        decimal altura = decimal.Parse(Console.ReadLine());\n        decimal imc = CalcularIMC(peso, altura);\n        imc = Math.Round(imc, 2);\n        Console.WriteLine($\"Tu IMC es de {imc}\");\n\n        double random = GenerarNumeroAleatorio();\n        Console.WriteLine($\"El número generado de manera aleatoria es {random}\");\n\n        double resultado = MultiplicacionConNumeroAleatorio(3.15);\n        Console.WriteLine($\"El resultado de la multiplicación es {resultado}\");\n\n        //Funciones creadas dentro del lenguaje\n        int year = DateTime.Now.Year;\n        bool isLeapYeay = DateTime.IsLeapYear(year); // La función IsLeapYear() existe dentro del lenguaje\n        if (isLeapYeay)\n            Console.WriteLine($\"El año {year} es un año bisiesto\");\n        else\n            Console.WriteLine($\"El año {year} no es un año bisiesto\");\n\n        Console.WriteLine(variableGlobal);\n        Variables();\n\n        int count = Extra(\"Fizz\", \"Buzz\");\n        Console.WriteLine($\"Los números se imprmieron {count} veces\");\n    }\n\n    // FUNCIONES\n    // 1.- Función sin parámetros ni retorno de datos\n    static void HolaMundo()\n    {\n        Console.WriteLine(\"Hola Mundo\");\n    }\n\n\n    // 2.- Función con parametros y sin retorno de datos\n\n    static void SaludoPersonalizado(string nombre)\n    {\n        Console.WriteLine($\"Hola, {nombre}\");\n    }\n\n\n\n    // 3.- Función con parámetros y retorno de datos\n\n    static decimal CalcularIMC(decimal peso, decimal altura)\n    {\n        decimal imc = peso / (altura * altura);\n\n        return imc;\n    }\n\n\n    // 4.- Función sin parámetros y con retorno de datos\n\n    static double GenerarNumeroAleatorio()\n    {\n        double random = new Random().NextDouble();\n        random = random * 50;\n        random = Math.Round(random, 2);\n\n        return random;\n    }\n\n\n\n    // Funciones dentro de funciones\n\n    static double MultiplicacionConNumeroAleatorio(double num)\n    {\n        int random = GenerarRandom();\n        double resultado = num * random;\n\n        int GenerarRandom()\n        {\n            int random = new Random().Next();\n            return random;\n        }\n        return resultado;\n    }\n\n    static void Variables()\n    {\n        variableGlobal = \"Al ser global puedo utilizarla aquí\";\n        string variableLocal = \"Esta variable solo existe dentro de esta función\";\n        Console.WriteLine(variableGlobal);\n        Console.WriteLine(variableLocal);\n    }\n\n    //Ejercicio Extra \n    static int Extra(string str1, string str2)\n    {\n        int count = 0;\n        for (int i = 1; i <= 100; i++)\n        {\n            if (i % 3 == 0 && i % 5 == 0)\n                Console.WriteLine(str1 + str2);\n            else if (i % 3 == 0)\n                Console.WriteLine(str1);\n            else if (i % 5 == 0)\n                Console.WriteLine(str2);\n            else\n            {\n                Console.WriteLine(i);\n                count++;\n            }\n        }\n        return count;\n    }\n\n\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c#/isaacus98.cs",
    "content": "﻿/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\nusing static System.Net.Mime.MediaTypeNames;\n\nnamespace RetosProgramacion2024\n{\n    internal class Reto2\n    {\n        private static int VariableGlobal = 1000;\n\n        static void Main(string[] args)\n        {\n            FuncionSinRetorno();\n\n            FuncionSinRetornoConUnParametro(\"Hola\");\n\n            FuncionSinRetornoConDosParametros(\"parámetro 1\", \"parámetro 2\");\n\n            // Función con parámetro opcional definido.\n            FuncionSinRetornoConParametroOpcional(\"Hola\");\n            // Función con parámetro opcional en el qual no se ha definido el parámetro.\n            FuncionSinRetornoConParametroOpcional();\n\n            FuncionSinRetornoConParams(1, 2, 3, 4, 5);\n            FuncionSinRetornoConParams(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);\n\n            Console.WriteLine(Suma(5, 10));\n\n            Console.WriteLine(CalcularFactorial(10));\n\n            // Función lambda\n            Func<int, int> square = x => x * x;\n            Console.WriteLine(square(5));\n\n            // Función del propio lenguaje.\n            string str = \"hola\";\n            Console.WriteLine(str.ToUpper()); // Función ToUpper: Convierte la minúsculas en mayúsculas.\n\n            // Función global\n            // Las variables globales se pueden usar en todas las funciones de la classe.\n            // Las variables locales solo se pueden usar dentro de la función donde se han definido.\n            Console.WriteLine(VariableGlobal);\n\n            // Reto extra\n            Console.WriteLine($\"Se ha impreso un total de {RetroExtra(\"FIZZ\", \"BUZZ\")} números.\");\n        }\n\n        private static int RetroExtra(string str1, string str2)\n        {\n            int contadorNumeros = 0;\n\n            for (int i = 1; i <= 100; i++)\n            {\n                if (i % 3 == 0 & i % 5 == 0)\n                {\n                    Console.WriteLine($\"{str1} {str2}\");\n                } \n                else if (i % 3 == 0)\n                {\n                    Console.WriteLine(str1);\n                }\n                else if (i % 5 == 0)\n                {\n                    Console.WriteLine(str2);\n                }\n                else\n                {\n                    Console.WriteLine(i);\n                    contadorNumeros++;\n                }\n            }\n\n            return contadorNumeros;\n        }\n\n        // Función sin parametros\n        private static void FuncionSinRetorno()\n        {\n            Console.WriteLine(\"Función sin retorno\");\n        }\n\n        // Función con 1 parametro\n        private static void FuncionSinRetornoConUnParametro(string str)\n        {\n            Console.WriteLine(str);\n        }\n\n        // Función con 2 parámetros\n        private static void FuncionSinRetornoConDosParametros(string str1, string str2)\n        {\n            Console.WriteLine($\"Primer parametro: {str1}\");\n            Console.WriteLine($\"Segundo parametro: {str2}\");\n        }\n\n        // Función con parámetro opcional.\n        // Los parámetros opcionales siempre se definen al final de la lista de parámetros.\n        private static void FuncionSinRetornoConParametroOpcional(string parametroOpcional = \"parametro opcional\")\n        {\n            Console.WriteLine(parametroOpcional);\n        }\n\n        /* Función con parámetro params\n         * El parametro params siempre se define al final de la lista de parametros\n         * El orden seria el siguiente: parametros obligatorios, parametros opcionels, paremetro params.\n         * El parámetro de params sirve para declarar una función en el que no se conoce el número de parámetros que recibe.\n         * La función recibe una cantidad variable de parametros que se agrupa en un array.\n         */\n        private static void FuncionSinRetornoConParams(params int[] numeros)\n        {\n            foreach(int numero in numeros)\n            {\n                Console.WriteLine(numero);\n            }\n        }\n\n        // Función que devuelve un valor.\n        private static int Suma(int num1, int num2)\n        {\n            return num1 + num2;\n        }\n\n        // Función dentro de una función.\n        // https://learn.microsoft.com/es-es/dotnet/csharp/programming-guide/classes-and-structs/local-functions\n        private static int CalcularFactorial(int numero)\n        {\n            return FuncionDentroDeFuncion(numero);\n\n            int FuncionDentroDeFuncion(int num)\n            {\n                return num < 2 ? 1 : num * FuncionDentroDeFuncion(num - 1);\n            }  \n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c#/isco-mtz.cs",
    "content": "using System;\n\ninternal class Program\n{\n    // Variables globales válidas (dentro de la clase)\n    static int globalCounter = 0;\n    static string globalMessage = \"Soy una variable global\";\n\n    static void Main(string[] args)\n    {\n        Console.WriteLine(\"=== 1. Funciones sin parámetros ni retorno ===\");\n        FuncionSinParametros();\n\n        Console.WriteLine(\"\\n=== 2. Funciones con parámetros ===\");\n        FuncionConUnParametro(\"Carlos\");\n        FuncionConDosParametros(10, 20);\n\n        Console.WriteLine(\"\\n=== 3. Funciones con retorno ===\");\n        int resultado = Sumar(7, 5);\n        Console.WriteLine($\"Resultado de Sumar(7, 5) = {resultado}\");\n\n        Console.WriteLine(\"\\n=== 4. Funciones dentro de funciones (¿se puede?) ===\");\n        FuncionesAnidadas();\n\n        Console.WriteLine(\"\\n=== 5. Uso de funciones del lenguaje (built-in) ===\");\n        UsoDeFuncionesDelLenguaje();\n\n        Console.WriteLine(\"\\n=== 6. Variable LOCAL vs GLOBAL ===\");\n        VariablesLocalYGlobal();\n\n        // Ejercicio extra\n        // Llamamos a la función y recibimos el resultado\n        Console.WriteLine(\"\\n=== 7. Reto Extra ===\");\n        int vecesNumero = ImprimirNumeros(\"Fizz\", \"Buzz\");\n\n        Console.WriteLine();\n        Console.WriteLine($\"Cantidad de veces que se imprimió un número: {vecesNumero}\");\n    }\n\n    // 1. Función sin parámetros ni retorno\n    static void FuncionSinParametros()\n    {\n        Console.WriteLine(\"Soy una función sin parámetros y sin retorno.\");\n    }\n\n    // 2. Funciones con parámetros\n    static void FuncionConUnParametro(string nombre)\n    {\n        Console.WriteLine($\"Hola {nombre}, esta función recibe un parámetro.\");\n    }\n\n    static void FuncionConDosParametros(int a, int b)\n    {\n        Console.WriteLine($\"Los parámetros son: {a} y {b}. Su suma es: {a + b}\");\n    }\n\n    // 3. Función con retorno\n    static int Sumar(int x, int y)\n    {\n        return x + y;\n    }\n\n    // 4. Funciones locales dentro de otra función\n    static void FuncionesAnidadas()\n    {\n        Console.WriteLine(\"C# permite funciones locales dentro de un método:\");\n\n        int FuncionLocal(int n)\n        {\n            return n * 2;\n        }\n\n        Console.WriteLine($\"FuncionLocal(10) = {FuncionLocal(10)}\");\n    }\n\n    // 5. Funciones built-in\n    static void UsoDeFuncionesDelLenguaje()\n    {\n        Console.WriteLine(\"Ejemplos de funciones built-in:\");\n        Console.WriteLine(\"hola mundo\".ToUpper());\n        Console.WriteLine(Math.Sqrt(16));\n        Console.WriteLine(DateTime.Now);\n    }\n\n    // 6. Variable local vs global\n    static void VariablesLocalYGlobal()\n    {\n        int localCounter = 5;\n\n        Console.WriteLine($\"Variable LOCAL = {localCounter}\");\n        Console.WriteLine($\"Variable GLOBAL antes = {globalMessage}\");\n\n        globalMessage = \"La variable global cambió\";\n\n        Console.WriteLine($\"Variable GLOBAL después = {globalMessage}\");\n    }\n\n    /// <summary>\n    /// 7. Recibe dos textos y retorna cuántas veces se imprimieron números reales.\n    /// </summary>\n    static int ImprimirNumeros(string texto3, string texto5)\n    {\n        int contadorNumeros = 0; // Lleva el conteo de cuántas veces se imprimió un número\n\n        // Recorremos los números del 1 al 100\n        for (int i = 1; i <= 100; i++)\n        {\n            bool multiplo3 = (i % 3 == 0); // true si i es múltiplo de 3\n            bool multiplo5 = (i % 5 == 0); // true si i es múltiplo de 5\n\n            if (multiplo3 && multiplo5)\n            {\n                // Si es múltiplo de 3 y 5\n                Console.WriteLine(texto3 + texto5);\n            }\n            else if (multiplo3)\n            {\n                // Solo múltiplo de 3\n                Console.WriteLine(texto3);\n            }\n            else if (multiplo5)\n            {\n                // Solo múltiplo de 5\n                Console.WriteLine(texto5);\n            }\n            else\n            {\n                // No es múltiplo ni de 3 ni de 5 ⇒ imprimimos el número\n                Console.WriteLine(i);\n                contadorNumeros++; // Contamos esta impresión\n            }\n        }\n\n        return contadorNumeros;\n    }    \n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c#/jamerrq.cs",
    "content": "using System;\n\n// Funciones y Alcance\nclass FunctionsAndScope\n{\n\n    // Funciones sin parámetros ni valor de retorno\n    static void SayHello()\n    {\n        Console.WriteLine(\"Hello World!\");\n    }\n\n    // Funciones sin parámetros pero con valor de retorno\n    static string GiveHello()\n    {\n        return \"Hello World!\";\n    }\n\n    // Funciones con parámetros pero sin valor de retorno\n    static void SayHello(string name) // Se puede sobrecargar!\n    {\n        Console.WriteLine($\"Hello {name}!\");\n    }\n\n    // Funciones con parámetros y valor de retorno\n    static string SayHello(string name, bool isFormal) // Tantas como quieras!\n    {\n        if (isFormal)\n        {\n            return $\"Hello Mr. {name}!\";\n        }\n        else\n        {\n            return $\"Hello {name}!\";\n        }\n    }\n\n    // Funciones dentro de funciones\n    static void SayHello(string name, bool isFormal, bool isSpanish)\n    {\n        void SayHelloInSpanish()\n        {\n            if (isFormal)\n            {\n                Console.WriteLine($\"Hola Sr. {name}!\");\n            }\n            else\n            {\n                Console.WriteLine($\"Hola {name}!\");\n            }\n        }\n        void SayHelloInEnglish()\n        {\n            if (isFormal)\n            {\n                Console.WriteLine($\"Hello Mr. {name}!\");\n            }\n            else\n            {\n                Console.WriteLine($\"Hello {name}!\");\n            }\n        }\n        if (isSpanish)\n        {\n            SayHelloInSpanish();\n        }\n        else\n        {\n            SayHelloInEnglish();\n        }\n    }\n\n    // Variables locales\n    static void LocalVariables()\n    {\n        int a = 1;\n        int b = 2;\n        int c = 3;\n        Console.WriteLine(\"int a = 1; int b = 2; int c = 3;\");\n        Console.WriteLine($\"a: {a}, b: {b}, c: {c}\");\n    }\n\n    // Variables globales\n    static readonly string a = \"global\";\n    static void GlobalVariables()\n    {\n        Console.WriteLine(\"C# no maneja un concepto de variables globales\");\n        Console.WriteLine(\"como tal, se pueden declarar variables `globales`\");\n        Console.WriteLine(\"dentro de una clase, y estas serán accesibles \");\n        Console.WriteLine(\"desde cualquier función de la misma.\");\n        Console.Write(\"static readonly string a = \\\"global\\\";\");\n        Console.WriteLine(\" // <- declarada en la clase\");\n        Console.WriteLine($\"a: {a}\");\n    }\n\n    static int OptionalExercise(string cadenaA, string cadenaB)\n    {\n        int count = 0;\n        for (int i = 1; i <= 100; ++i)\n        {\n            if (i % 3 == 0 && i % 5 == 0)\n            {\n                Console.WriteLine($\"{cadenaA}{cadenaB}\");\n            }\n            else if (i % 3 == 0)\n            {\n                Console.WriteLine(cadenaA);\n            }\n            else if (i % 5 == 0)\n            {\n                Console.WriteLine(cadenaB);\n            }\n            else\n            {\n                Console.WriteLine(i);\n                ++count;\n            }\n        }\n        return count;\n    }\n\n    static void Main(string[] args)\n    {\n        Console.WriteLine(\"Funciones y Alcance\");\n        Console.WriteLine(\"\\n1. Funciones\");\n        Console.WriteLine(\"\\n1.1 Funciones sin parámetros ni valor de retorno\");\n        Console.WriteLine(\"static void SayHello()\");\n        SayHello();\n        Console.WriteLine(\"\\n1.2 Funciones sin parámetros pero con valor de retorno\");\n        Console.WriteLine(\"static string GiveHello()\");\n        Console.WriteLine(GiveHello());\n        Console.WriteLine(\"\\n1.3 Funciones con parámetros pero sin valor de retorno\");\n        Console.WriteLine(\"static void SayHello(string name)\");\n        SayHello(\"Javier\");\n        Console.WriteLine(\"\\n1.4 Funciones con parámetros y valor de retorno\");\n        Console.WriteLine(\"static string SayHello(string name, bool isFormal)\");\n        Console.WriteLine(SayHello(\"Javier\", true));\n        Console.WriteLine(\"1.5 Funciones dentro de funciones\");\n        Console.WriteLine(\"static void SayHello(string name, bool isFormal, bool isSpanish)\");\n        SayHello(\"Javier\", false, true);\n        Console.WriteLine(\"\\n\\n2. Variables locales\");\n        LocalVariables();\n        Console.WriteLine(\"\\n\\n3. Variables globales\");\n        GlobalVariables();\n        Console.WriteLine(\"\\n\\n4. Ejercicio opcional\");\n        Console.WriteLine(\"static int OptionalExercise(string cadenaA, string cadenaB)\");\n        Console.WriteLine(\"OptionalExercise(\\\"Moure\\\", \\\"Dev\\\")\");\n        Console.WriteLine($\"\\nNúmeros no múltiplos de 3 ni 5: {OptionalExercise(\"Moure\", \"Dev\")}\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c#/jcubero12.cs",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\nusing system;\n\npublic class\n {\n\n    static string global = \"esto es una variable global\";\n\n    static void Main(string[] args)\n    {\n\n        //Funciones\n        Console.WriteLine(\"Impresion de funciones: \");\n        Saluda(); //Sin parámetros ni retorno\n        SaludarA(\"Jose\"); //Con un parámetro\n        edad(\"Jose\", 1980); //Con dos parámetros y retorno\n\n        OuterFuncion();\n\n        //Funcion creada por el lenguaje\n        Random random = new Random();\n        Console.WriteLine(random.Next());\n\n        //Variables locales y globales\n        variables();\n\n    }\n\n    static void Saluda()\n    {\n        Console.WriteLine(\"Hola mundo!\");\n    }\n\n    static void SaludarA(string nombre)\n    {\n        Console.WriteLine(\"Hola, \" + nombre);\n    }\n\n\n    static int edad(string nombre, int yearborn)\n    {\n\n        int edad = 2024 - yearborn;\n        return $\"Hola, {nombre}. Según tu año de nacimiento tienes {edad} años.\"\n    }\n\n\n    static void OuterFuncion()\n    {\n        Console.WriteLine(\"Estoy en la función outer\");\n\n        void InnerFuncion()\n        {\n            Console.WriteLine(\"Esto es una función inner\");\n        }\n\n        InnerFuncion();\n    }\n\n    static void variables()\n    {\n        string local = \"esto es una variable local\";\n        Console.WriteLine(local); //imprime \"esto es una variable local\"\n        Console.WriteLine(global); //imprime \"esto es una variable global\"\n    }\n\n    //Ejercicio extra\n    static int imprimirNumeros(string texto1, string texto2)\n    {\n        int contador = 0;\n        for (int i = 1; i <= 100; i++)\n        {\n            if (i % 3 == 0 && i % 5 == 0)\n            {\n                Console.WriteLine(texto1 + \" \" + texto2);\n            }\n            else if (i % 3 == 0)\n            {\n                Console.WriteLine(texto1);\n            }\n            else if (i % 5 == 0)\n            {\n                Console.WriteLine(texto2);\n            }\n            else\n            {\n                Console.WriteLine(i);\n                contador++;\n            }\n        }\n        return contador;\n    }\n}\n\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c#/kenysdev.cs",
    "content": "// ╔══════════════════════════════════════╗\n// ║ Autor: Kenys Alvarado                ║\n// ║ GitHub: https://github.com/Kenysdev  ║\n// ║ 2024 - C#                            ║\n// ╚══════════════════════════════════════╝\n\n/*\n1. Funciones:\n*************\nSintaxis:\n║ [modificadorAcceso] ║ [modificador]     ║ TipoRetorno     ║ NombreFuncion║ ([parametros])║\n║ public, private, .. ║ static, async, .. ║ int, string, .. ║       --     ║      --       ║\nLas funciones básicas pueden ser **públicas o privadas**.\nLas privadas solo son accesibles en la misma clase.\nSi no se especifica el tipo de acceso, entonces serán privadas por default.\n----------------------------\nFuncion estática sin retorno\n----------------------------\nPueden ser llamadas sin crear una instancia de la clase.\n*/\nusing System;\n\nstatic void print(object msg)\n{\n    Console.WriteLine(msg);\n}\n\nprint(\"Estática\");\n\n// -----------------------------\n// Funcion estática con retorno:\n// -----------------------------\n// Se debe especificar el tipo de dato a retornar.(int, string, etc.)\nstatic int Suma(int a, int b)\n{\n    return a + b;\n}\n\nprint(Suma(2, 2));\n\n// ---------------------\n// Funcion de Instancia:\n// ---------------------\n// Requieren crear una instancia de la clase para ser llamadas.\n// Pueden ser sin retorno, usando (void) o con retorno(int, string,..).\nint Resta(int a, int b)\n{\n    return a - b;\n}\n\nprint(Resta(4, 2));\n\n// -----------------------\n// Con Parámetro Opcional:\n// -----------------------\nvoid Divide(int a, int b = 2)\n{\n    print(a / b);\n}\nDivide(10);\n\n// -------------------------\n// Con Parámetros de Salida:\n// -------------------------\n// Permiten devolver más de un valor utilizando la palabra clave out.\n\nvoid Dividir(int dividendo, int divisor, out int cociente, out int residuo)\n{\n    cociente = dividendo / divisor;\n    residuo = dividendo % divisor; \n}\nint rCociente;\nint rResiduo;\nDividir(10, 5, out rCociente, out rResiduo);\nprint($\"Cociente: {rCociente}, Residuo: {rResiduo}\");\n\n// -------------------------\n// Funciones Recursivas::\n// -------------------------\nint Factorial(int n)\n{\n    return (n == 0) ? 1 : n * Factorial(n - 1);\n}\nprint(Factorial(6));\n\n//2. Función anidada:\n// ******************\nint multi(int a, int b)\n{\n    int interna()\n    {\n        return a * b;\n    }\n\n    return interna();\n}\nprint(multi(2, 2));\n\n// 3. Ejemplo de funciones incorporadas:\n// *************************************\n// Conversión de Tipos:\nbool un_bool = true;\nstring a_str = Convert.ToString(un_bool);\nprint(a_str);\n\n//  Fecha y Hora\nprint(DateTime.Now);\n\n// longitud de la cadena\nprint((\"abc\".Length));\n\n/*\n# 5. Ejercicio:\n# *************\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n * - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n * - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n * - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n * - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\"\"\")\n*/\n\n static int Ejercicio(string str1, string str2)\n{\n    int nVeces = 0; \n    for (int num = 1; num <= 100; num++)\n    {\n        if (num % 3 == 0 && num % 5 == 0)\n        {print(str1 + str2);}\n        else if (num % 3 == 0)\n        {print(str1);}\n        else if (num % 5 == 0)\n        {print(str2);}\n        else\n        {nVeces++;print(num);}\n    }\n\n    return nVeces;\n}\n\nprint(Ejercicio(\"múltiplo de 3\", \"múltiplo de 5\"));\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c#/kodenook.cs",
    "content": "\nvoid name() {\n    Console.WriteLine(\"kodenook\");\n}\n\nname();\n\nvoid fullName(string fname = \"my\", string lname = \"surname\") {\n    Console.WriteLine($\"{fname} {lname}\");\n}\n\nfullName();\n\nvoid ageAddition(ref int age) {\n    age += 5;\n}\n\nint age = 20;\nageAddition(ref age);\nConsole.WriteLine(age);\n\nvoid first() {\n    Console.WriteLine(\"First\");\n\n    void second() {\n        Console.WriteLine(\"Second\");\n    }\n\n    second();\n}\n\nfirst();\n\n/*\n    Exercise\n*/\n\nint exercise(string word1, string word2) {\n    int countNumbers = 0;\n\n    foreach (var i in Enumerable.Range(1, 100))\n    {\n        if (i % 3 == 0 && i % 5 == 0)\n        {\n            Console.WriteLine($\"{word1} {word2}\");\n        } else if (i % 3 == 0) {\n            Console.WriteLine(word1);\n        } else if (i % 5 == 0) {\n            Console.WriteLine(word2);\n        } else {\n            countNumbers++;\n        }\n    }\n\n    return countNumbers;\n}\n\nConsole.WriteLine($\"number of times it was a number and not words: {exercise(\"hello\", \"c#\")}\");"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c#/luterfloyd.cs",
    "content": "﻿/*\n EJERCICIO:\n - Crea ejemplos de funciones básicas que representen las diferentes\n   posibilidades del lenguaje:\n   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n - Comprueba si puedes crear funciones dentro de funciones.\n - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n - Debes hacer print por consola del resultado de todos los ejemplos.\n   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n\n DIFICULTAD EXTRA (opcional):\n Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\n Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n*/\nusing System;\nusing System.ComponentModel.Design.Serialization;\nusing System.Data;\n\ninternal class Program\n{\n    private static void Main(string[] args)\n    {\n        // FUNCION SIN PARAMENTROS NI VALOR DE RETORNO\n        static void Saludando()\n        {\n            Console.WriteLine(\"Hola CSharp\");\n        }\n\n        // FUNCION CON PARAMETROS Y RETORNANDO VALOR\n        static float Operacion(string strOperador, float nValor1, float nValor2)\n        {\n            float nResultado = 0;\n            switch (strOperador)\n            {\n                case \"SUMA\":\n                    nResultado = nValor1 + nValor2;\n                    break;\n                case \"RESTA\":\n                    nResultado = nValor1 - nValor2;\n                    break;\n                case \"MULTIPLICACION\":\n                    nResultado = nValor1 * nValor2;\n                    break;\n                case \"DIVISION\":\n                    nResultado = nValor1 / nValor2;\n                    break;\n                default:\n                    Console.WriteLine(\"Error: operador invalido\");\n                    Environment.Exit(-1);\n                    break;\n            }\n            return nResultado;\n        }\n\n        // FUNCIONES ANIDADAS\n        (int, int) FactorialconIteraciones(int nValor)\n        {\n            int nIteraciones = 0;\n            int nFactorial = 0;\n\n            // FUNCION RECURSIVA: SE PUEDE INVOCAR A SI MISMA\n            int Factorial(int nValor)\n            {\n                nIteraciones++; // ESTA VARIABLE ESTA DEFINIDA EN UN AMBITO SUPERIOR ASI QUE SE CONSERVA EL VALOR\n                if (nValor == 0) return 1;\n                return nValor * Factorial(nValor - 1);\n            }\n\n            nFactorial = Factorial(nValor);\n            return (nIteraciones, nFactorial);\n\n        }\n\n        // EJERCICIO ADICIONAL: FUNCION QUE RECIBE DOS CADENAS Y RETORNA UN VALOR\n        static int FizzBuzz(string strCadena1, string strCadena2)\n        {\n            int nContador = 0;\n\n            for (int indice = 1; indice <= 100; indice++)\n            {\n                if (indice % 3 == 0 && indice % 5 == 0) Console.WriteLine(strCadena1 + strCadena2);\n                else if (indice % 3 == 0) Console.WriteLine(strCadena1);\n                else if (indice % 5 == 0) Console.WriteLine(strCadena2);\n                else\n                {\n                    nContador++;\n                    Console.WriteLine(indice);\n                }\n            }\n            return nContador;\n        }\n\n        int nIteraciones = 0;\n        int nFactorial = 0;\n        int nFizzBuzz = 0;\n\n        Saludando();\n        Console.WriteLine(Operacion(\"SUMA\", 2, 3));\n        Console.WriteLine(Operacion(\"RESTA\", 2, 3));\n        (nIteraciones, nFactorial) = FactorialconIteraciones(4);\n        Console.WriteLine(\"Factorial: \" + nFactorial + \" nro. de iteraciones: \" + nIteraciones);\n        nFizzBuzz = FizzBuzz(\"Fizz\", \"Buzz\");\n        Console.WriteLine(\"Resultado ejercicio adicional: \" + nFizzBuzz);\n    }\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c#/matteozhao98.cs",
    "content": "﻿using System;\n\ninternal class Program\n{\n    //Variable global\n    private static double globalPi = 3,1415\n\n    //Funciones básicas\n    //Función sin parámetros ni retorno\n\n    static void FuncionSinNada()\n    {\n        Console.WriteLine(\"Soy una función que ni pide parámetros ni retorna nada!!\");\n    }\n\n    //Función sin parámetro con retorno\n    static string FuncionConRetorno()\n    {\n        return \"Esta vez sí estoy devolviendo algo, espero que me almacenes bien\";\n    }\n\n    //Función con parámetro, pero sin retorno\n    static void FuncionConParametroSinRetorno(string nombre)\n    {\n        Console.WriteLine($\"Hola {nombre}!\");\n    }\n\n    //Función con parámetros y con retorno\n    static void FuncionCompleta(string nombre)\n    {\n        return $\"Hola {nombre}!\";\n    }\n\n    //Funciones dentro de función\n    static void Saludo(string nombre)\n    {\n        string saludo;\n\n        string FuncionDentroFuncion(string saludo, string nombre)\n        {\n            return $\"{saludo} {nombre}!\";\n        }\n\n        saludo = FuncionDentroFuncion(\"Hola\", nombre);\n\n        Console.WriteLine(saludo);\n    }\n\n    static int DificultadExtra(string textoUno, string textoDos)\n    {\n        int contador = 0;\n\n        for (int i = 1; i <= 100; i++)\n        {\n            bool divisiblePorTres = i % 3 == 0;\n            bool divisiblePorCinco = i % 5 == 0;\n\n            if (divisiblePorTres && divisiblePorCinco)\n                Console.WriteLine($\"{textoUno}{textoDos}\");\n            else if (divisiblePorTres)\n                Console.WriteLine(textoUno);\n            else if (divisiblePorCinco)\n                Console.WriteLine(textoDos);\n            else\n            {\n                Console.WriteLine(i);\n                contador++;\n            }\n        }\n\n        return contador;\n    }\n\n    public static void Main(string[] args)\n    {\n        FuncionSinNada();\n        string miString = FuncionConRetorno();\n        FuncionConParametroSinRetorno(\"Matteo\");\n        string saludo = FuncionCompleta(\"Matteo\");\n\n        Saludo(\"Matteo\");\n\n        //Función incluída en el lenguaje\n        List<int> miLista = new List<int>(1, 2, 3);\n        Console.WriteLine(miLista.Count());\n\n        //Variable local y global\n        double localDouble = 1514,3;\n        Console.WriteLine(globalPi);\n        Console.WriteLine(loclaDouble);\n\n        Console.WriteLine($\"El número ha salido {DificultadExtra(\"fizz\", \"buzz\")} veces!\");\n    }\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c#/miguelex.cs",
    "content": "class miguelex\n{\n    static void holaMundo(){\n        Console.WriteLine(\"Hola Mundo\");\n    }\n\n    static void saludo (string nombre){\n        Console.WriteLine(\"Hola \" + nombre);\n    }\n\n    static int suma (int a, int b){\n        return a + b;\n    }\n\n    // Funcion declarada dentro de otra funcion\n\n    static void funcionExterna(){\n        Console.WriteLine(\"Funcion externa\");\n        void funcionInterna(){\n            Console.WriteLine(\"Funcion interna\");\n        }\n        funcionInterna();\n    }\n\n    // Funcion con parametros por defecto\n\n    static void porDefecto(int a = 0, int b = 0){\n        Console.WriteLine(\"El valor de a es : \" + a);\n        Console.WriteLine(\"El valor de b es : \" + b);\n    }\n\n    static int Extra(string param1, string param2 ){\n        int contador = 0;\n        for (int i = 0; i < 100; i++){\n            if (i % 15 == 0){\n                Console.WriteLine(param1+param2);\n            }\n            else if (i % 3 == 0){\n                Console.WriteLine(param1);\n            }\n            else if (i % 5 == 0){\n                Console.WriteLine(param2);\n            }\n            else{\n                Console.WriteLine(i);\n                contador++;\n            }\n        }\n        return contador;\n    }\n\n    static void Main(string[] args)\n    {\n        holaMundo();\n        saludo(\"Miguel\");\n        Console.WriteLine(\"Resultado de la suma de 5 y 5 : \" + suma(5, 3));\n        funcionExterna();\n        Console.WriteLine(\"Ejemplo de funcion del sistema Math.Pow(2,3) : \" + Math.Pow(2,3));\n        Console.Write(\"Funcion por defecto sin ningun parametro \");\n        porDefecto();\n        Console.WriteLine(\"Funcion por defecto con un parametro \");\n        porDefecto(5);\n        Console.WriteLine(\"Funcion por defecto con dos parametros \"); \n        porDefecto(5, 10);\n        Console.WriteLine(\"Se han imprimido \" + Extra(\"Fizz\", \"Buzz\") + \" numeros\");\n    }\n        \n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c#/mor39a.cs",
    "content": "/*\n--------------------------------------------------------------------------------------------------------\nInstrucciones:\n\n    1. Crea ejemplos de funciones básicas que representen las diferentes\n       posibilidades del lenguaje:\n       Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n    2. Comprueba si puedes crear funciones dentro de funciones.\n    3. Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n    4. Pon a prueba el concepto de variable LOCAL y GLOBAL.\n    5. Debes hacer print por consola del resultado de todos los ejemplos.\n       (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n\nDificultad Extra:\n    Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n        La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n            - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n            - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n            - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n            - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n--------------------------------------------------------------------------------------------------------\n*/\n\n#region 1.\n\nusing System.Reflection.Metadata.Ecma335;\n\nConsole.WriteLine(\"1.\\n\");\n\nvoid SinParametrosNiRetorno() => Console.WriteLine(\"     Sin parametros ni retorno\");\nvoid ConParametrosSinRetorno(string a) => Console.WriteLine($\"     Con parametros sin retorno | {a}\");\nstring SinParametrosConRetorno() => \"Hola\";\nstring ConParametrosYRetorno(string text) => text;\nvoid ConParametrosRef(ref string text) => text = \"Hola\";\n\nSinParametrosNiRetorno();\nConParametrosSinRetorno(\"Txt\");\nConsole.WriteLine($\"     Sin parametros con retorno | {SinParametrosConRetorno()}\");\nConsole.WriteLine($\"     Con parametros y retorno | {ConParametrosYRetorno(\"Hola!\")}\");\nstring text = null!;\nConParametrosRef(ref text);\nConsole.WriteLine($\"     Con parametros ref | {text}\");\n\n#endregion\n\n#region 2.\n\nAñadirDivision();\nConsole.WriteLine(\"2.\\n\");\n\nPadre();\n\nvoid Padre()\n{\n    Console.WriteLine(\"     Funcion padre\");\n    Hijo();\n    void Hijo()\n    { \n        Console.WriteLine(\"     Funcion hijo\");\n    }\n}\n\n#endregion\n\n#region 3.\n\nAñadirDivision();\nConsole.WriteLine(\"3.\\n\");\n\nbool EsNullo = string.IsNullOrEmpty(text);\nConsole.WriteLine($\"     Funcion integrada con el lenguaje (string.IsNullOrEmpty) | {EsNullo}\");\n\n#endregion\n\n#region 4.\n\nAñadirDivision();\nConsole.WriteLine(\"4.\\n\");\n\nVariables();\n\nvoid Variables()\n{\n    text = \"Hola\"; // text es una variable global\n    Console.WriteLine($\"     Variable global: {text}\");\n    string text2 = \"Chao\"; // text2 es una variable local\n    Console.WriteLine($\"     Variable local: {text2}\");\n}\n//text2 = \"Hola\"; // No se encuentra por que es local en Variables()\n\n#endregion\n\n#region Extra\n\nAñadirDivision();\nConsole.WriteLine(\"Extra:\\n\");\n\n/*Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n        La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n            - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n            - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n            - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n            - La función retorna el número de veces que se ha impreso el número en lugar de los textos.*/\n\nConsole.WriteLine($\"\\n     {Extra(\"Hola\", \"Mundo\")} impresiones.\");\n\nint Extra(string text1, string text2)\n{\n    int[] Numeros = Enumerable.Range(1, 100).ToArray();\n    int impresiones = 0;\n    foreach (int i in Numeros)\n    {\n        if ((i % 3) == 0 && (i % 5) == 0)\n        {\n            Console.WriteLine($\"     {text1}, {text2}\");\n        }\n        else if ((i % 3) == 0)\n        {\n            Console.WriteLine($\"     {text1}\");\n        }\n        else if ((i % 5) == 0)\n        {\n            Console.WriteLine($\"     {text2}\");\n        }\n        else\n        {\n            Console.WriteLine($\"     {i}\");\n            impresiones++;\n        }\n    }\n    return impresiones;\n}\n\n#endregion\n\n#region Funciones\n\nvoid AñadirDivision() => Console.WriteLine(\"\\n\" + new string('-', 75) + \"\\n\");\n\n#endregion"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c#/tebaah.cs",
    "content": "﻿internal class Program\n{\n    /*\n    * EJERCICIO:\n    * - Crea ejemplos de funciones básicas que representen las diferentes\n    *   posibilidades del lenguaje:\n    *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n    * - Comprueba si puedes crear funciones dentro de funciones.\n    * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n    * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n    * - Debes hacer print por consola del resultado de todos los ejemplos.\n    *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n    *\n    * DIFICULTAD EXTRA (opcional):\n    * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n    * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n    *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n    *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n    *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n    *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n    *\n    * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n    * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n    */\n    private static void Main(string[] args)\n    {\n        // Ejemplo de función sin parámetros ni retorno\n        void Saludar()\n        {\n            Console.WriteLine(\"¡Hola!\");\n        }\n\n        Saludar();\n\n        // Ejemplo de función con un parámetro y retorno\n        int Sumar(int a, int b)\n        {\n            return a + b;\n        }\n\n        Console.WriteLine(Sumar(2, 3));\n\n        // Ejemplo de función con varios parámetros y retorno\n        int Multiplicar(int a, int b, int c)\n        {\n            return a * b * c;\n        }\n\n        Console.WriteLine(Multiplicar(2, 3, 4));\n\n        // Ejemplo de función con retorno\n        int ObtenerNumero()\n        {\n            return 42;\n        }\n\n        Console.WriteLine(ObtenerNumero());\n\n        // Ejemplo de función con parámetros\n        void SaludarA(string nombre)\n        {\n            Console.WriteLine($\"¡Hola, {nombre}!\");\n        }\n\n        SaludarA(\"Mundo\");\n\n        // Ejemplo de función con parámetros y retorno\n        string SaludarAConRetorno(string nombre)\n        {\n            return $\"¡Hola, {nombre}!\";\n        }\n\n        Console.WriteLine(SaludarAConRetorno(\"Mundo\"));\n\n        // Ejemplo de función dentro de otra función\n        void FuncionExterna()\n        {\n            Console.WriteLine(\"Función externa\");\n\n            void FuncionInterna()\n            {\n                Console.WriteLine(\"Función interna\");\n            }\n\n            FuncionInterna();\n        }\n\n        FuncionExterna();\n\n\n        int ImprimirNumeros(string texto1, string texto2)\n        {\n            int contador = 0;\n            for (int i = 1; i <= 100; i++)\n            {\n                if (i % 3 == 0 && i % 5 == 0)\n                {\n                    Console.WriteLine(texto1 + texto2);\n                    contador++;\n                }\n                else if (i % 3 == 0)\n                {\n                    Console.WriteLine(texto1);\n                    contador++;\n                }\n                else if (i % 5 == 0)\n                {\n                    Console.WriteLine(texto2);\n                    contador++;\n                }\n            }\n            return contador;\n        }\n\n        int vecesImpreso = ImprimirNumeros(\"Fizz\", \"Buzz\");\n        Console.WriteLine($\"La función ImprimirNumeros se ha ejecutado {vecesImpreso} veces.\");\n    }\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c#/vasilealexandru02.cs",
    "content": "public class vasilealexandru02\n{\n\n    /*\n    * EJERCICIO:\n    * - Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n    *   Aritmticos, lgicos, de comparacin, asignacin, identidad, pertenencia, bits...\n    *   (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n    * - Utilizando las operaciones con operadores que t quieras, crea ejemplos\n    *   que representen todos los tipos de estructuras de control que existan\n    *   en tu lenguaje:\n    *   Condicionales, iterativas, excepciones...\n    * - Debes hacer print por consola del resultado de todos los ejemplos.\n    *\n    * DIFICULTAD EXTRA (opcional):\n    * Crea un programa que imprima por consola todos los nmeros comprendidos\n    * entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni mltiplos de 3.\n    *\n    * Seguro que al revisar detenidamente las posibilidades has descubierto algo nuevo.\n    */\n\n    /*\n        Crea ejemplos utilizando todos los tipos de operadores de tu lenguaje:\n         Aritmticos, lgicos, de comparacin, asignacin, identidad, pertenencia, bits...\n        (Ten en cuenta que cada lenguaje puede poseer unos diferentes)\n     */\n\n    // Operadores aritmeticos\n    int suma = 1 + 2;\n    int resta = 1 - 2;\n    int multiplicacion = 1 * 2;\n    double division = 1 / 2;\n    double modulo = 10 % 2;\n\n    int operadorIncremento = 0;\n    int operadorDecremento = 1;\n\n        ++operadorIncremento;\n        operadorIncremento++;\n        --operadorDecremento;\n        operadorDecremento--;\n\n        // Operadores lgicos booleanos\n        bool operadorAnd = true && false;\n\n    bool operadorOr = true || false;\n\n    bool operadorNegacion = !true;\n\n    bool operadorIR = false ^ true;\n\n    bool operadorComparacion = true == true;\n    bool operadorComparacionDistinto = true != false;\n\n    bool test = true;\n\n    test &= true; // Output: True\n\n        test |= false; // Output: True\n\n        test ^= true; // Output: False\n\n\n        // Operadores de desplazamiento y bit a bit\n\n        uint valor = 0b_1100_1001_0000_0000_0000_0000_0001_0001;\n    uint desplazamientoIzquierda = valor << 4;\n    uint desplazamientoDerecha = valor >> 4;\n\n\n        /*\n         *  - Utilizando las operaciones con operadores que t quieras, crea ejemplos\n            que representen todos los tipos de estructuras de control que existan\n            en tu lenguaje:\n            Condicionales, iterativas, excepciones...\n         */\n\n        // Condicionales\n        if (true)\n        {\n            Console.WriteLine(\"Verdadero!\");\n\n        }\n        else if (false && false)\n{\n    Console.WriteLine(\"Verdadero tambin!\");\n}\nelse\n{\n    Console.WriteLine(\"No me queda ms que entrar aqu...\");\n}\n\nstring diaSemana = \"Lunes\";\nswitch (diaSemana)\n{\n\n    case \"Lunes\":\n        Console.WriteLine(\"Primer dia de la semana!\");\n        break;\n    case \"Martes\":\n        Console.WriteLine(\"Seguimos fuertes con este martes lluvioso!\");\n        break;\n    case \"Mircoles\":\n        Console.WriteLine(\"Mircoles de ser productivo!\");\n        break;\n    case \"Jueves\":\n        Console.WriteLine(\"Ya casi estamos... ltimo empujn!\");\n        break;\n    case \"Viernes\":\n        Console.WriteLine(\"Da de positividad y comienzo del weekend\");\n        break;\n    case \"Sabado\":\n    case \"Domingo\":\n        Console.WriteLine(\"No me molestes estoy de weekend total!\");\n        break;\n\n    default:\n        Console.WriteLine(\"No s que dia es este :/\");\n        break;\n\n}\n\n\nList<int> numeros = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };\n// Iterativas\nint numeroTotal = 0;\nfor (int i = 0; i < 10; i++)\n{\n    numeroTotal += i;\n}\n\nforeach (int numero in numeros)\n{\n    Console.WriteLine(\"Numero: \" + numero);\n}\n\nint numeroDoWhile = 10;\ndo\n{\n    Console.WriteLine(\"Dentro del bucle do while!\", numeroDoWhile);\n    numeroDoWhile--;\n\n} while (numeroDoWhile > 0);\n\n\nint numeroWhile = 0;\nwhile (numeroWhile < 10)\n{\n    Console.WriteLine(\"Esto es un bucle while normal\");\n    numeroWhile++;\n}\n\n// Try catch finally \ntry\n{\n    Console.WriteLine(\"Este es el codigo que se va a intentar ejecutar\");\n\n}\ncatch (Exception e)\n{\n    Console.WriteLine(\"Esta es la excepcion a controlar\", e);\n\n}\n\nfinally\n{\n    Console.WriteLine(\"Cdigo que se ejecuta al final de nuestro bloque try catch\");\n}\n\n/* DIFICULTAD EXTRA (opcional):\n* Crea un programa que imprima por consola todos los nmeros comprendidos\n* entre 10 y 55 (incluidos), pares, y que no son ni el 16 ni mltiplos de 3.*/\nint numeroEjercicio = 10;\n\nwhile (numeroEjercicio <= 55)\n{\n    if (numeroEjercicio % 2 == 0 && !(numeroEjercicio == 16 || numeroEjercicio % 3 == 0))\n    {\n        Console.WriteLine(numeroEjercicio);\n    }\n\n    numeroEjercicio++;\n}\n    }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c#/victormugo.cs",
    "content": "﻿namespace _02_funciones\n{\n    internal class Program\n    {\n        static void Main(string[] args)\n        {\n            /*\n             * EJERCICIO:\n             * - Crea ejemplos de funciones básicas que representen las diferentes posibilidades del lenguaje:\n             *      Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n             * - Comprueba si puedes crear funciones dentro de funciones.\n             * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n             * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n             * - Debes hacer print por consola del resultado de todos los ejemplos.\n             *      (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n             *\n             * DIFICULTAD EXTRA (opcional):\n             * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n             * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n             *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n             *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n             *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n             *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n             *\n             * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n             * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n             */\n\n\n            // ------------- Funciones básicas\n\n            // Método sin parámetros ni retorno\n            MethodNoParametersNoReturn();\n\n            // Método con uno o varios parámetros\n            string parameter1 = \"Parametro 1\";\n            MethodParametersNoReturn(parameter1);\n\n            // Función sin parámetros y retorno\n            string res = FunctionNoParametersReturn();\n            Console.WriteLine(res);\n\n            // Función con parámetros y retorno\n            int a = 5;\n            int b = 7;\n            int result = 0;\n            result = FunctionParametersReturn(\"suma\", a, b);\n            Console.WriteLine(result);\n\n            result = FunctionParametersReturn(\"resta\", a, b);\n            Console.WriteLine(result);\n\n            result = FunctionParametersReturn(\"multiplicar\", a, b);\n            Console.WriteLine(result);\n\n            result = FunctionParametersReturn(\"dividir\", a, b);\n            Console.WriteLine(result);\n\n            result = FunctionParametersReturn(\"resto\", a, b);\n            Console.WriteLine(result);\n\n\n            // ------------- Funciones dentro de funciones\n            FunctionExample();\n\n            // ------------- Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n            FunctionOwnLanguage();\n\n            // ------------- Función concepto Variable Local y Global\n            string cadenaTexto = \"Soy la cadena de texto en concepto GLOBAL\";\n            Console.WriteLine(cadenaTexto);\n            FunctionVariables();\n            Console.WriteLine(cadenaTexto);\n\n\n\n            // ------------- Dificultad extra\n            int contador = ComparaCadenas(\"cadena1\", \"cadena2\");\n            Console.WriteLine($\"Contador: {contador}\");\n        }\n\n\n        public static void MethodNoParametersNoReturn()\n        {\n            Console.WriteLine(\"Hola. Soy un método que no devuelve nada\");\n        }\n\n\n        public static void MethodParametersNoReturn(string parameter1)\n        {\n            Console.WriteLine($\"Hola. Soy el parametro 1: {parameter1}\");\n        }\n\n\n        public static string FunctionNoParametersReturn()\n        {\n            string cadena1 = \"Soy la cadena 1 declarada en la función\";\n            return cadena1;\n        }\n\n\n        public static int FunctionParametersReturn(string operacion, int a, int b)\n        {\n            int result = 0;\n            switch(operacion)\n            {\n                case \"suma\":\n                    result = a + b;\n                    break;\n\n                case \"resta\":\n                    result = a - b;\n                    break;\n\n                case \"multiplicar\":\n                    result = a * b;\n                    break;\n\n                case \"dividir\":\n                    result = a / b;\n                    break;\n\n                default:\n                    result = -1;\n                    break;\n            }\n\n            return result;\n        }\n\n        public static void FunctionOwnLanguage()\n        {\n            string cadena = \"Esto es una cadena, separada por una coma\";\n            string[] partes = cadena.Split(\",\");\n\n            for (int i = 0; i < partes.Length; i++)\n            {\n                Console.WriteLine($\"Partes cadena: {partes[i]}\");\n            }\n        }\n\n        public static void FunctionVariables()\n        {\n            string cadenaTexto = \"Soy la cadena de texto en concepto LOCAL\";\n            Console.WriteLine(cadenaTexto);\n        }\n\n        public static void FunctionExample()\n        {\n            string result = FunctionInsideFunction(5);\n            Console.WriteLine(result);\n        }\n\n        public static string FunctionInsideFunction(int number1)\n        {\n            string cadena1 = \"No es un 5\";\n            if (number1 == 5)\n            {\n                cadena1 = \"Es un 5\";\n            }\n\n            return cadena1;\n        }\n\n\n\n        public static int ComparaCadenas(string cadena1, string cadena2)\n        {\n            int contador = 0;\n\n            Console.WriteLine(\"---------------------------------------\");\n\n            for (int i = 1; i <= 100; i++)\n            {\n                if (i % 3 == 0 && i % 5 == 0)\n                {\n                    // Múltiplo de 3 y 5\n                    Console.WriteLine($\"{cadena1} - {cadena2}\");\n                    continue;\n                }\n                else if (i % 3 == 0)\n                {\n                    // Múltiplo de 3\n                    Console.WriteLine($\"{cadena1}\");\n                    continue;\n                } \n                else if (i % 5 == 0)\n                {\n                    // Múltiplo de 5\n                    Console.WriteLine($\"{cadena2}\");\n                    continue;\n                }\n                else\n                {\n                    Console.WriteLine($\"{i}\");\n                    contador++;\n                }\n            }\n\n            return contador;\n        }\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c#/vixxtory.cs",
    "content": "using System;\npublic class Program\n{\n\n    /** FUNCIONES SEGUN VISIBILIDAD **/\n\n    //01.Funcion static: pertenece a una clase en lugar de a una instancia especfica de esa clase. Son tiles con tareas que no dependen de ningn estado especfico de un objeto.\n    public class ConversorTemperatura\n    {\n        public static double CelsiusToFahrenheit(double celsius)\n        {\n            return (celsius * 9 / 5) + 32;\n        }\n    }\n\n    //02.Funcion public: puede ser accedida desde cualquier parte del cdigo, ya sea desde la misma clase, desde clases derivadas, o desde cualquier otra clase en el mismo ensamblado. \n    public class Circulo\n    {\n        public double Radio { get; set; }\n\n        public Circulo(double radio)\n        {\n            Radio = radio;\n        }\n\n        public double CalcularArea()\n        {\n            return Math.PI * Radio * Radio;\n        }\n    }\n\n    //03. Metodo private: solo son accesibles dentro de la misma clase donde estn definidos.\n    //04. Metodos protegidos:  similares a los privados, pero tambin son accesibles desde clases derivadas (subclases) de la clase donde estn definidos.\n    public class MiClase\n    {\n        private void MetodoPrivado()\n        {\n            Console.WriteLine(\"Este es un mtodo privado.\");\n        }\n\n        protected void MetodoProtegido()\n        {\n            Console.WriteLine(\"Este es un mtodo protegido.\");\n        }\n    }\n    public class OtraClase : MiClase\n    {\n        public void AccesoDesdeClaseDerivada()\n        {\n            // No se puede llamar a MetodoPrivado desde aqu, ya que es privado.\n            MetodoProtegido(); // Pero se puede llamar a MetodoProtegido, ya que es protegido.\n        }\n    }\n\n    /** FUNCIONES SEGUN TIPO DE RETORNO **\n     * Estos pueden ser tipos de datos primitivos, tipos de datos personalizados (como clases), tipos anulables (Nullable<T>), enumeraciones, matrices, interfaces, delegados, entre otros.**/\n\n    //01. Tipos de datos primitivos: int, float, double, bool, char, etc.\n    public int ObtenerEntero()\n    {\n        return 42;\n    }\n\n    //02. Clases y estructuras: Una funcin puede devolver una instancia de una clase o una estructura.\n    public MiClase ObtenerInstancia()\n    {\n        return new MiClase();\n    }\n\n    //03. Tipos anulables (Nullable<T>): Permiten que un tipo de valor tenga un valor nulo adems de sus valores normales.\n    public int? ObtenerEnteroNullable()\n    {\n        int? resultado = null;\n        return resultado;\n    }\n\n    //04. Matrices: Una funcin puede devolver una matriz de cualquier tipo.\n    public int[] ObtenerArreglo()\n    {\n        return new int[] { 1, 2, 3, 4, 5 };\n    }\n\n    //05. Delegados: Una funcin puede devolver un delegado que apunte a otra funcin.\n    public Func<int, int> ObtenerFuncion()\n    {\n        return x => x * x;\n    }\n\n    /** FUNCIONES SEGUN TIPO DE PARAMETRO QUE RECIBE */\n\n    //01. Funciones sin parmetros: Realizan una tarea especfica basada nicamente en su lgica interna y no requieren datos de entrada externos.\n    public void Saludar()\n    {\n        Console.WriteLine(\"Hola!\");\n    }\n\n    //02. Funciones con parmetros: Reciben uno o ms parmetros que se utilizan para proporcionar datos de entrada a la funcin.\n    public void Sumar(int a, int b)\n    {\n        int resultado = a + b;\n        Console.WriteLine(\"La suma de {0} y {1} es {2}\", a, b, resultado);\n    }\n\n    //03. Funciones con parmetros opcionales: Se definen parmetros con un valor predeterminado, lo que los convierte en opcionales. Esto significa que puedes llamar a la funcin sin proporcionar valores para esos parmetros, y se utilizar el valor predeterminado en su lugar.\n    public void Saludar(string nombre = \"Mundo\")\n    {\n        Console.WriteLine(\"Hola, {0}!\", nombre);\n    }\n\n    //04. Funciones con parmetros de salida (out): Pueden devolver ms de un valor como resultado. Los parmetros de salida se declaran con la palabra clave out y deben ser inicializados dentro de la funcin antes de que sta retorne.\n    public void Dividir(int dividendo, int divisor, out int cociente, out int residuo)\n    {\n        cociente = dividendo / divisor;\n        residuo = dividendo % divisor;\n    }\n\n    //05. Funciones con parmetros de referencia (ref): Similar a los parmetros de salida, pero los parmetros de referencia (ref) permiten que los valores se pasen a la funcin y se modifiquen dentro de ella, y esos cambios se reflejan fuera de la funcin.\n    public void Incrementar(ref int numero)\n    {\n        numero++;\n    }\n\n    /** No es posible definir funciones dentro funciones como en JavaScript. Sin embargo, puedes lograr un comportamiento similar utilizando clases internas o delegados anidados.**/\n\n    //02. Delegados anidados: Se puede usar delegados anidados para definir funciones dentro de otras funciones, pero estas funciones estaran limitadas a ser mtodos dentro de una clase.\n    public class Clase\n    {\n        public delegate void Metodo();\n\n        public void MetodoExterno()\n        {\n            Console.WriteLine(\"Mtodo externo\");\n\n            Metodo metodoInterno = () =>\n            {\n                Console.WriteLine(\"Mtodo interno\");\n            };\n\n            metodoInterno();\n        }\n    }\n\n    /** ALGUNOS EJEMPLOS DE FUNCIONES PREDETERMINADAS */\n\n    //01. Console.ReadLine(): Lee una lnea de texto desde la entrada estndar (generalmente la consola) y la devuelve como una cadena\n    string entrada = Console.ReadLine();\n\n    //02. string.Format(): Esta funcin esttica de la clase string formatea una cadena de texto utilizando un patrn y una lista de argumentos.\n    private static string nombre = \"Juan\";\n    private static int edad = 30;\n    string mensaje = string.Format(\"Hola, me llamo {0} y tengo {1} aos.\", nombre, edad);\n    \n    \n    /** VARIABLE LOCAL Y GLOBAL */\n\n    //Variable local: Se declara dentro de un bloque de cdigo, como una funcin o un bloque { } y solo puede ser utilizada dentro de ese bloque\n    public void MiFuncion()\n    {\n        int x = 10; // Variable local\n        Console.WriteLine(x); // Se puede acceder dentro de la funcin\n    }\n\n    // Console.WriteLine(x); // Esto causara un error, ya que x no es visible aqu\n\n    //Variable global: Es aquella que se declara fuera de cualquier funcin o bloque, generalmente al comienzo del programa y  puede ser accedida y modificada desde cualquier parte del cdigo.\n    // (Se recomienda utilizar variables locales siempre que sea posible y limitar el uso de variables globales a casos donde sean realmente necesarias.)\n\n    /** DIFICULTAD EXTRA */\n    public static int ImprimirNumeros(string texto1, string texto2)\n    {\n        int contador = 0;\n        for (int i = 1; i <= 100; i++)\n        {\n            if (i % 3 == 0 && i % 5 == 0)\n            {\n                Console.WriteLine(texto1 + texto2);\n            }\n            else if (i % 3 == 0)\n            {\n                Console.WriteLine(texto1);\n            }\n            else if (i % 5 == 0)\n            {\n                Console.WriteLine(texto2);\n            }\n            else\n            {\n                Console.WriteLine(i);\n                contador++;\n            }\n        }\n        return contador;\n    }\n\n\n    public static void Main(string[] args)\n    {\n        /** //01\n        double temperaturaCelsius = 20;\n        double temperaturaFahrenheit = ConversorTemperatura.CelsiusToFahrenheit(temperaturaCelsius);\n        Console.WriteLine(\"{0} grados Celsius son {1} grados Fahrenheit\", temperaturaCelsius, temperaturaFahrenheit);\n\n        //02\n        Circulo circulo = new Circulo(5);\n        double area = circulo.CalcularArea();\n        Console.WriteLine(\"El rea del crculo es: {0}\", area); */\n\n        //DIFICULTAD EXTRA\n        string texto1 = \"Fizz\";\n        string texto2 = \"Buzz\";\n        int vecesImpreso = ImprimirNumeros(texto1, texto2);\n        Console.WriteLine(\"El nmero de veces que se imprimi un nmero en lugar de los textos es: \" + vecesImpreso);\n    }\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c++/Aldroide.cpp",
    "content": "/*\nEjercicio: Crear ejemplos de funciones basicas que representen diferentes\nposiblidades del lenguaje:\n    * Sin parametros ni retorno\n    * Con uno o mas parametros,\n    * Con retorno\n    * Probar funciones dentro de funciones\n    * Utilizar funciones ya creadas del lenguaje\n    * Variable local y global\n    * Debes hacer print por consola del resultado de todos los ejemplos.\n    * (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n*/\n#include <iostream>\n#include <math.h>\nusing namespace std;\nint EjercicioExtra(const char* param1, const char* param2);\nvoid Simple(){\n    cout<<\"Funcion sin parametros ni retorno\"<<endl;\n}\n\nvoid compuesta(string name){\n    cout<<\"Función que recibe tu nombre: \"<<name<<\" pero no tiene retorno\"<<endl;\n}\n\nint suma(int a, int b){\n    return a+b;\n}\n\nint i =10;\n\nint main(){\n    int local=90;\n    Simple();\n    compuesta(\"Aldo\");\n    cout<<\"El resultado de 4 + 6 es: \"<<suma(4,6)<<endl;\n    cout<<\"Se imprimieron \"<<EjercicioExtra(\"Parametro1\", \"Parametro2\")<<\" numeros\"<<endl;\n    cout<<\"Variable global: \"<<i<<endl;\n    cout<<i<<\" elevado a 2 es: \"<<exp(i)<<endl;\n    cout<<\"Variable local \"<<local<<endl;\n    return 0;\n\n}\n\n\n/*\n* DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\nint EjercicioExtra (const char* param1, const char* param2){\n    int numVeces = 0;\n    for (int i = 1; i <= 100; i++){\n        if (i % 15 == 0){\n            cout<<param1<<param2; \n        } else if (i % 3 == 0){\n            cout<<param1;\n        } else if (i % 5 == 0){\n            cout<<param2;\n        } else {\n            cout<<i;\n            numVeces++;\n        }        \n        cout<<endl;\n    }\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c++/AlejandroDave.cpp",
    "content": "#include <iostream>\nusing namespace std;\n\nvoid sinRet(){\n    cout<<\"Funcion sin parametros ni retorno\"<<endl;\n}\n\nfloat retyPar(float a){\n    return a*5.8;\n}\n\nint potencia(int a){\n    return a*a;\n}\n\nint altaFun(int a, int b){\n    int c = a+a;\n    return c+ potencia(b);\n}\n\nint ejercicioFuncion(string a, string b){\n    int s  = 0;\n    for(int i=0;i<100;i++){\n        if(i%3==0 && i%5 ==0){\n            cout<<a<<\" \"<<b<<endl;\n        }\n        if(i%3==0){\n            cout<<a<<endl;\n        }\n        if(i%5 ==0){\n            cout<<b<<endl;\n        }\n        else{\n            cout<<i<<endl;\n            s++;\n        }\n        }\n    return s;\n    }\n\n\nint main(){\n     float f = retyPar(4.4);\n     int af = altaFun(3,5);\n     sinRet();\n     cout<<\"Funcion con parametro y retorno \"<<f<<\"\\nFuncion que invoca otra funcion: \"<<af<<endl;\n     string a = \"hola\", b = \"c++\";\n     int e = ejercicioFuncion(a,b);\n     cout<<\"El total de veces que aparecio el numero fue: \"<<e<<endl;\n\nreturn 0;}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c++/CesarCarmona30.cpp",
    "content": "#include <iostream>\n#include <math.h>\n\nusing namespace std;\n\n// Función sin parámetros ni retorno\nvoid greet(){\n  cout << \"Hi!\" << endl;\n}\n\n// Función con parámetros sin retorno\nvoid greetPerson(string name){\n  cout << \"Hello \" << name << endl;\n}\n\n// Función con varios parámetros sin retorno\nvoid add(int numberA, int numberB){\n  cout << numberA << \" + \" << numberB << \" = \" << numberA + numberB<< endl;\n}\n\n// Función con varios parámetros con retorno\nint subtract(int numberA, int numberB){\n  return numberA - numberB;\n}\n\n// Función sin parámetros con retorno\nstring languageName(){\n  return \"C++\";\n}\n\n// Función lambda\nauto mult = [](int numberA, int numberB) -> int{\n  return numberA * numberB;\n};\n\n// Función con parámetros variables\ntemplate<typename... Args>\ndouble average(Args... args) {\n    int sum = 0;\n    // Procesar cada argumento\n    ((sum += args), ...);\n    return (static_cast<double> (sum))/sizeof...(Args);\n}\n\n/**\n * En C++ no se puede declarar una función dentro de otra,\n * pero si se puede crear una lambda dentro de una \n * función normal\n*/\nint exteriorFunction(int x){\n  // Función lambda\n  auto interiorFunction = [](int y){\n    return y * 2;\n  };\n  int result = x + interiorFunction(x);\n  return result;\n}\n\n// Uso de funciones nativas\nint exponentiate(int number, int base) {\n  return pow(number, base);\n}\n\n\n// Variable global\nstring global = \"Soy global\";\n\nvoid myFunction() {\n  // Variable local\n  string local = \"Soy local\";\n  cout << \"Accediendo a la variable global dentro de la funcion: \" << global << endl;\n  cout << \"Accediendo a la variable local dentro de la funcion: \" << local << endl;\n  cout << \"Fin de la funcion\" << endl;\n}\n\nclass LocalVariableAccessException : public exception {\npublic:\n    const char* what() const noexcept override {\n        return \"Error: Acceso a variable local fuera de su ambito.\";\n    }\n};\n\n/**\n * EXTRA\n*/\n\nint printNumbers(string text1, string text2) {\n  int printed_numbers = 0;\n  for (int number = 1; number <= 100; number++) {\n    if ((number % 3 == 0) && (number % 5 == 0)) {\n      cout << text1 << \" y \" << text2 << endl;\n    } else if (number % 3 == 0) {\n      cout << text1 << endl;\n    } else if (number % 5 == 0) {\n      cout << text2 << endl;\n    } else {\n      cout << number << endl;\n      printed_numbers += 1;\n    }\n  }\n  return printed_numbers;\n}\n\nint main(){\n  greet();\n  greetPerson(\"Cesar\");\n  add(5, 8);\n  cout << \"175 - 123 = \" << subtract(175, 123) << endl;\n  cout << \"5 * 8 = \" << mult(5, 8) << endl;\n  cout << \"Promedio de 6, 4, 7 y 8 = \" << average(6, 4, 7, 8) << endl;\n  cout << \"Promedio de 5, 2, 6, 8 y 9 = \" << average(5, 2, 6, 8, 9) << endl;\n  cout << \"2 ^ 8 = \" << exponentiate(2, 8) << endl;\n  cout << \"5 + (5 * 2) = \" << exteriorFunction(5) << endl;\n  cout << \"Esto fue programado en \" << languageName() << endl;\n  myFunction();\n  cout << \"Accediendo a la variable global fuera de la funcion: \" << global << endl;\n  try{\n    cout << \"Accediendo a la variable local fuera de la funcion: \" << endl;\n    throw LocalVariableAccessException();\n  } catch (const LocalVariableAccessException& err) {\n    cerr << err.what() << endl;\n  }\n\n  cout << \"EXTRA\" << endl;\n  int prints = printNumbers(\"Multiplo de 3\", \"Multiplo de 5 \");\n  cout << \"Numeros impresos: \" << prints << endl;\n  return 0;\n} "
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c++/CrisVigas.cpp",
    "content": "#include <cmath>\n#include <cstdint>\n#include <iostream>\n#include <string>\n\n// funcion sin retorno ni parametros\nstatic void saludo() { std::cout << \"Hola!\\n\"; }\n\n// funcion con 1 parametros sin retorno\nstatic void saludo(const std::string &name) {\n  std::cout << \"Hola \" << name << \"!\\n\";\n}\n\n// funcion con retorno\ntemplate <typename T>\nstatic T cuadrado(T x) {\n  return x * x;\n}\n\n// es mejor no usar variables globales... pero cada loco con su tema\nstatic int32_t variableGlobal{5};\n\nstatic void accesoGlobal() {\n  std::cout << \"La variable global es: \" << ::variableGlobal << \"\\n\";\n\n  // modificamos la variable global\n  ::variableGlobal += 100;\n\n  std::cout << \"La variable global modificada es: \" << ::variableGlobal << \"\\n\";\n\n  // definimos una variable local con el mismo nombre\n  int32_t variableGlobal{-1000};\n\n  std::cout << \"La variable ::global es: \" << ::variableGlobal << \"\\n\";\n  std::cout << \"La variable global es: \" << variableGlobal << \"\\n\";\n\n  std::cout << \"Cambiamos la variable global a 0\\n\";\n  variableGlobal = 0;\n  std::cout << \"La variable ::global es: \" << ::variableGlobal << \"\\n\";\n  std::cout << \"La variable global es: \" << variableGlobal << \"\\n\";\n}\n\nstatic int64_t funcionExtra(const std::string &str1, const std::string &str2) {\n  int32_t contador{0};\n\n  for (int32_t i = 1; i < 101; ++i) {\n    if (((i % 3) == 0) && ((i % 5) == 0)) {\n      std::cout << str1 << str2 << \"\\n\";\n    } else if ((i % 3) == 0) {\n      std::cout << str1 << \"\\n\";\n    } else if ((i % 5) == 0) {\n      std::cout << str2 << \"\\n\";\n    } else {\n      std::cout << i << \"\\n\";\n      ++contador;\n    }\n  }\n\n  return contador;\n}\n\nint main() {\n  ::saludo();\n  ::saludo(\"Desarrollador\");\n  std::cout << \"5 al cuadrado es: \" << ::cuadrado(5) << \"\\n\";\n\n  // No es posible definir una funcion dentro de otra\n  // int foo(int bar) { return bar + 1; }\n  // ...pero podemos definir una expresion lambda\n  auto foo = [](const int32_t bar) { return bar + 1; };\n  std::cout << \"5 + 1 = \" << foo(5) << \"\\n\";\n\n  // funciones ya creadas\n  std::cout << \"raiz de 25 es: \" << std::sqrt(25) << \"\\n\";\n\n  // variables globales\n  ::accesoGlobal();\n\n  // DIFICULTAD EXTRA\n  std::cout << \"======= DIFICULTAD EXTRA =======\\n\";\n  std::cout << ::funcionExtra(\"Fizz\", \"Buzz\");\n\n  return EXIT_SUCCESS;\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c++/Fravelz.cpp",
    "content": "#include <iostream>\n\nusing namespace std;\n\n// **************** Funciones y tipos, Alcance de variables, y Reto Extra **************** //\n\n\nvoid nothing_(); // Funcion definida que no hace nada.\n\nint al_cubo(int a); // Funcion definida que retorna un numero int.\n\nint retoExtra(string a, string b) { // Funcion del reto Extra\n    int contador = 0;\n\n    for (int i = 1; i <= 100; i++) {\n\n        if (i % 3 == 0 && i % 5 == 0) cout << \"(\" << a << b << \")\"; \n        \n        else if (i % 3 == 0) cout << \"(\" << a << \")\"; \n        \n        else if (i % 5 == 0) cout << \"(\" << b << \")\"; \n        \n        else {\n            cout << i;\n            contador++;\n        }\n\n        cout << endl;\n    }\n    \n    return contador;\n}\n\n\nstring variable1 = \"GLOBAL\"; // Variable Global\n\nint main() {\n    string variable2 = \"Local\"; // Variable Local\n\n    cout << \"\\n4 a la 3 = \" << al_cubo(4) << '\\n';\n    cout << endl;\n\n    cout << \"\\nLos numeros se imprimen: \" << retoExtra((string)\"LaGran\", (string)\"Colombia\") << \" Veces.\\n\";\n\n    return 0;\n}\n\n// Funcion que retorna un valor entero\nint al_cubo(int a) {\n    return a * a * a;\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c++/Gallitofast.cpp",
    "content": "#include <iostream>\n#include <ostream>\n#include <string.h>\n#include <string>\n//02 Funciones y saludarcance\n//void son funciones que no van a retornar nada\n//Funcion sin parametros ni retornos\nvoid saludar(){\n  std::cout<<\"Hola, funcion de saludo\"<<std::endl;\n}\n\n//Funcion con parametros y retorno \nint funcion_suma(int num1,int num2){\n  return num1+num2;\n}\n\n//Funciones dentro de funciones no se pueden como tal en c++ pero investigue\n//y con lambdas es posible, pero todavia no exploro ese concepto\n\n//Experimento de variable global y global\nint variable_global{20};\nvoid funcion_global_local(){\n int variable_local{30}; //Esta variable solo podria usarla en esta funcion\n std::cout<<\"La variable global: \"<<variable_global<<\" Se puede usar donde sea, en cambio la local: \"<<\n    variable_local<<\" Solo en esta funcion\"<<std::endl;\n\n}\n\nint ejercicio_extra(std::string ,std::string);\n//Main es una funcion que siempre se va a ejecutar y es necesaria para compilar\nint main(){\n  saludar();\n  std::cout<<\"Funcion de suma: \"<<funcion_suma(2,8)<<std::endl;\n  funcion_global_local();\n\n  int contador=ejercicio_extra(\"Hola\",\"Mundo\");\n  std::cout<<contador<<\": veces no se cumplieron las condiciones\"<<std::endl;\n\nreturn 0;\n}\n\n\nint ejercicio_extra(std::string cadena_de_texto1, std::string cadena_de_Texto2){\n  int contador=0;\n  for (int i=1;i<=100;i++){\n    if (i%5==0 && i%3==0) std::cout<<i<<\" ==> \"<<cadena_de_texto1<<\" \"<<cadena_de_Texto2<<std::endl;\n    else if (i%5==0) std::cout<<i<<\" ==> \"<<cadena_de_Texto2<<std::endl;\n    else if (i%3==0) std::cout<<i<<\" ==> \"<<cadena_de_texto1<<std::endl;\n    else{\n       std::cout<<i<<std::endl;\n       contador++;\n    }\n  }\n return contador;\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c++/MaviGareli.cpp",
    "content": "#include <iostream>\r\n#include <string>\r\n\r\n/*!\r\n*Funcion: printHIMsg()\\n\r\n*Brief: Imprime un mensaje de bienvenida\\n\r\n*@param none \\n\r\n*@return none\\n\r\n*/\r\nvoid printHiMsg();\r\n\r\n\r\n/*!\r\n*Funcion: print()\\n\r\n*Brief: Imprime un mensaje dado\\n\r\n*@param string \\n\r\n*@return none\\n\r\n*/\r\nvoid print(std::string message);\r\n\r\n\r\n/*!\r\n*Funcion: print()\\n\r\n*Brief: Imprime un numero entero dado\\n\r\n*@param int \\n\r\n*@return none\\n\r\n*/\r\nvoid print(int number);\r\n\r\n\r\n/*!\r\n*Funcion:printNumberList()\\n\r\n*Brief: La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\r\n*   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\r\n*   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\r\n*   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\r\n*   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\\n\r\n*@param string, string\\n\r\n*@return int\\n\r\n*/\r\nint printNumberList(std::string message1, std::string message2);\r\n\r\n\r\n//Variable global\r\nint counterGlobal = 0;\r\n\r\nint main()\r\n{\r\n    //Variables locales\r\n    std::string message1 = \"Soy un multiplo de 3 \";\r\n    std::string message2 = \"Soy un multiplo de 5\";\r\n    printHiMsg();\r\n    printNumberList(message1, message2);\r\n    \r\n    counterGlobal = 0;  //Se resetea el contador, para que no se acumulen los valores al llamar nuevamente la funcion\r\n    int result = printNumberList(message1, message2);\r\n    \r\n    print(\"El numero de veces que se ha impreso un numero es: \");\r\n    print(result);\r\n    return 0;\r\n \r\n}\r\n\r\nvoid printHiMsg()\r\n{\r\n    std::cout << \"Bienvenido!\" << std::endl;\r\n}\r\n\r\nvoid print(std::string message)\r\n{\r\n    std::cout << message;\r\n}\r\n\r\n\r\nvoid print(int number)\r\n{\r\n    std::cout << number;\r\n}\r\n\r\n\r\nint printNumberList(std::string message1, std::string message2)\r\n{   \r\n    /*Aqui seria mejor poner la variable counter, para evitar resetearla cada vez que se llama a la funcion. \r\n    Se hizo global con fines de demostracion\r\n    */\r\n    for(int i = 1; i <= 100; i++)\r\n    {\r\n        print(i);\r\n        if(i % 3 == 0 && i % 5 == 0)\r\n        {\r\n            print(\" \" + message1 + message2);\r\n            \r\n        }\r\n        else if( i% 3 == 0)\r\n        {\r\n            print(\" \" + message1);\r\n        }\r\n        else if( i% 5 == 0)\r\n        {\r\n            print(\" \" + message2);\r\n        }\r\n        else\r\n        {\r\n            counterGlobal++;\r\n        }\r\n        std::cout << std::endl;\r\n    }\r\n    return counterGlobal; \r\n\r\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c++/RoniPG.cpp",
    "content": "// @RoniPG\n\n#include <iostream>\n#include <cmath>\n\nusing namespace std;\n\n//Variables globales\n\n//Declaraciones\n\n//Al declarar una variable permitimos que sea vista por todo el programa\nint a = 1;\n//Funciones\n\n//Declaraciones\n\n//Al declarar una funcion permitimos que sea vista por todo el programa\nvoid Resultados();\nint X(string a, string b);\n\n//Funcion de suma\n/*\n * Las funciones pueden no recibir ningun parametro o pueden recibir varios parametros\n * Pueden tener un valor de retorno (return) que se devuelve al invocar la funcion\n * El return debe coincidir con el tipo de la funcion\n */\n\nint Suma(int numA, int numB) {\n\n\tint result = numA + numB;\n\n\treturn result;\n\n}\nint Resta() {\n\t/*int SegundaResta(int b) {\n\t return 0;}\n\t Podemos comprobra al descomentar este codigo que no podemos crear funciones dentro de funciones\n\t */\n\treturn 0;\n}\n\n//Llamadas a funciones dentro de funciones\nint Resultsuma(int numA, int numB) {\n\n\tint result = numA + numB;\n\tResultados(); // ---> Podemos realizar llamadas a funciones dentro otra que esten previamente declaradas\n\treturn result;\n\n}\nint AccesoVariables() {\n\tint a = 0; // ---> Variable Local (Solo existe dentro de la funcion)\n\treturn a;\n}\n\n//Funcion que no necesita valor de retorno\nvoid Resultados() {\n\tcout << \"El resultado de la suma es:\" << Suma(2, 3) << endl;\n\n}\n\nint main() {\n\n\t//Llamadas a Funciones\n\n\tcout << Suma(2, 3) << endl;\n\tResultados();\n\tcout << Resultsuma(2, 3) << endl;\n\n\t//Llamadas a Funciones predefinidas de C++\n\n\tcout << sqrt(16) << endl;\n\n\t//Comprobamos las variables locales y las globales\n\n\tcout << \"Accedemos a la variable local a con valor : \" << AccesoVariables() << endl;\n\tcout << \"Comprobamos la variable global a : \" << a << endl;\n\n/*  DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\tcout << \"Se ha impreso un numero: \" << X(\"Soy multiplo de 3\", \"Soy multiplo de 5\") << \" veces\" << endl;\n\n\treturn 0;\n}\nint X(string a, string b) {\n\tint contador = 0;\n\tfor (int i = 1; i < 100; i++) {\n\t\tif ((i % 5 == 0) && (i % 3 == 0)) {\n\t\t\tcout << a << \" y tambien \" << b << endl;\n\t\t} else if (i % 3 == 0) {\n\t\t\tcout << a << endl;\n\t\t} else if (i % 5 == 0) {\n\t\t\tcout << b << endl;\n\t\t} else {\n\t\t\tcout << i << endl;\n\t\t\tcontador++;\n\t\t}\n\n\t}\n\treturn contador;\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c++/Vid92.cpp",
    "content": "#include <iostream>\n#include <string>\n#include <cmath>\n\nusing namespace std;\n\nint resultado = 0;          //variable global\n\n//Funcion con retorno y 2 parametros\nint suma(int num1,int num2){\n    return num1 + num2;\n}\n\n//Funcion sin parametros sin retorno\nvoid resultadoSuma(void){\n    cout<<\"Resultado de la funcion suma es: \"<<resultado<<endl;\n}\n\n//Funcion con parametros sin retorno\nvoid resultadoResta(int resul){\n    cout<<\"Resultado de la funcion resta es: \"<<resul<<endl;\n}\n\n//Funcion dentro de otra funcion, y con parametros y sin retorno\nvoid resta(int num1,int num2){\n    int res = num1 - num2;\n    resultadoResta(res);\n}\n\n//Ejercicio Extra\nint funcionExtra(string text1,string text2){\n    int count = 0;\n    for(int i=1;i<101;i++){\n        if((i%5==0)&&(i%3==0))\n            cout<<text1<<\" \"<<text2<<endl;\n        else if(i%3==0)\n            cout<<text1<<endl;  \n        else if(i%5==0)\n            cout<<text2<<endl;\n        else\n            count+=1;\n    }\n    return count;\n}\n\nint main()\n{   \n  resultado = suma(5,4);            \n  resultadoSuma();\n  cout<<\"Raiz cuadrada: \"<<sqrt(144)<<endl;       //ejemplo de funcion ya creadas por el lenguaje\n  resta(10,5);\n  int solucion = funcionExtra(\"uno\",\"dos\");\n  cout<<\"Resultado del ejercicio extra es: \"<<solucion<<endl;\n  \n  return 0;\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c++/carZep09.cpp",
    "content": "#include <iostream>\n#include <cmath>  \n#include <ctime> \nusing namespace std; \n\nint mis_cadenas (string cadena1, string cadena2); \n\n\n\nint x = 50; // declaracion de variable global\n \n// funcion de tipo void, no regresa una variable\nvoid funcion_no_ret1(){\n    cout << \"Esta funcion imprime solamente este mensaje.\" << '\\n'; \n} \n\n/* funcion de tipo void, no regresa una variable pero toma un parametro y \n    lo imprime en pantalla. \n*/ \nvoid funcion_no_ret2(int numero){\n    cout << \"Esta funcion imprime un numero entero: \" << numero << '\\n';  \n}\n\n/* funcion void, que toma multiples parametros y no regresa ni uno de esos valores\nsolo los imprime en pantalla*/\nfloat eq_cuadratica(float a, float b, float c){\n  float equacion_1 = (-b + (sqrt(b*b) - (4 * a * c)) /  (2 * a)); \n  float equacion_2 = (-b - (sqrt(b*b) - (4 * a * c)) /  (2 * a)); \n    cout << \"Esta funcion muestra el resultado de la equacion cuadratica: \"   \n        <<  equacion_1  << \" y \" << equacion_2 << '\\n';   \n\n  return equacion_1 && equacion_2;\n} \n/* funcion de tipo entero(int), esta funcion si regresa los multiples parametros \ny regresa el valor de la suma a la funcion main*/\nint suma(int numero1, int numero2, int numero3, int numero4){\n    return numero1 + numero2 + numero3 + numero4; \n}\n\n\n\n\nint main()\n{\n    int numero1; // variable local\n    string cd1 = \"multiplo de 3\";\n    string cd2 = \"multiplo de 5\"; \n    funcion_no_ret1(); // llamada de un parametro\n    cout << '\\n';  \n    funcion_no_ret2(5); \n    cout << '\\n'; \n    eq_cuadratica(5, 4, 10);\n    cout << '\\n';  \n\n    numero1 = 35; \n    cout <<\"El resultado de la suma es: \" << suma(10, numero1, 27, x) << '\\n'; \n    // x es una variable global y numero1 local\n    cout << '\\n'; \n    cout << \"Ejercicio extra: \"; \n    cout << mis_cadenas(cd1, cd2); \n\n    return 0; \n}\n\nint mis_cadenas(string cadena1, string cadena2){\n    int veces = 0;\n    for (int i = 1; i < 100; i++){\n        if (i % 3 == 0 && i % 5 == 0){ \n            cout << cadena1 << \" y \" << cadena2  << '\\n';\n        }\n        else if (i % 3 == 0) { \n            cout << cadena1 << '\\n'; \n            \n        }\n        else if (i % 5 == 0){\n            cout << cadena2 << '\\n'; \n        } \n        else{\n            cout << i << '\\n';\n            veces++;  // si las condiciones de arriba no aplican, la variable veces suma a 1, hasta que \n            // las condiciones sean \n        }\n\n         \n    }\n    return veces;\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c++/carlosguariglia.cpp",
    "content": "/*\n# #02 FUNCIONES Y ALCANCE\n> #### Dificultad: Fácil | Publicación: 08/01/24 | Corrección: 15/01/24\n\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n #include <iostream>\n#include <string>\nusing namespace std;\n\n// Variables globales\nint globalVar = 10;\n\n// Función sin parámetros ni retorno\nvoid saludar() {\n    cout << \"Hola, esta es una función sin parámetros ni retorno.\" << endl;\n}\n\n// Función con parámetros pero sin retorno\nvoid mostrarSuma(int a, int b) {\n    cout << \"La suma de \" << a << \" y \" << b << \" es: \" << a + b << endl;\n}\n\n// Función con retorno\nint multiplicar(int a, int b) {\n    return a * b;\n}\n\n// Prueba de variable local y global\nvoid modificarVariables() {\n    int localVar = 5;\n    cout << \"Variable local: \" << localVar << endl;\n    cout << \"Variable global: \" << globalVar << endl;\n    globalVar = 20; // Modificamos la variable global\n}\n\n// Función que imprime todos los números del 1 al 100 siguiendo las reglas descritas\nint imprimirMultiples(string cadena1, string cadena2) {\n    int contadorNumeros = 0;\n    for (int i = 1; i <= 100; i++) {\n        if (i % 3 == 0 && i % 5 == 0) {         // Si el número es múltiplo de 3 y de 5\n            cout << cadena1 + cadena2 << endl;  // Imprime las dos cadenas de texto concatenadas\n        } else if (i % 3 == 0) {                // Si el número es múltiplo de 3 y no de 5\n            cout << cadena1 << endl;            // Imprime la cadena de texto del primer parámetro\n        } else if (i % 5 == 0) {                // Si el número es múltiplo de 5 y no de 3\n            cout << cadena2 << endl;            // Imprime la cadena de texto del segundo parámetro\n        } else {                                // Si el número no es múltiplo de 3 ni de 5\n            cout << i << endl;                  // Imprime el número\n            contadorNumeros++;                  // Incrementa el contador\n        }\n    }\n    return contadorNumeros;                     // Retorna el contador\n}\n\nint main() {\n    // Ejemplo de uso de las funciones\n    saludar();\n\n    mostrarSuma(5, 7);\n\n    int resultado = multiplicar(3, 4);\n    cout << \"El resultado de la multiplicación es: \" << resultado << endl;\n\n    // Prueba de variable local y global\n    modificarVariables();\n    cout << \"Variable global después de modificarla: \" << globalVar << endl;\n\n    // DIFICULTAD EXTRA: Función con dos cadenas de texto que imprime los múltiplos\n    string palabra1 = \"Carlos\";\n    string palabra2 = \"Guariglia\";\n    int vecesNumeros = imprimirMultiples(palabra1, palabra2);\n    cout << \"Número de veces que se imprimió un número: \" << vecesNumeros << endl;\n\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c++/davidvela-306.cpp",
    "content": "#include <iostream>\n#include <string>\n/*\n * FUNCTIONS\n * */\n\n//WITH OUT RETURN - void functions\n// Only execute the operations but not return a value\nvoid greeting(){\n\tstd::cout << \"Hello\" << std::endl;\n}\n// void function with params\n\nvoid showMsg(std::string name){\n\tstd::cout << \"Hello \"  << name << std::endl;\n}\nint global_res = 0; // global variable.\n// WITH RETURN - no void functions\n\nint sum(int n1, int n2){\n\tint res = n1 + n2;\n\tstd::cout << n1 << \" + \"<< n2 << \" = \"<< res << std::endl;\n\tstd::cout << global_res << \" global var \" << std::endl;\n\treturn res;\n}\n\n// Function Overloading: Enable that we have a lot variables with the same name, the diference is the cuantity of params or the type of the same. You can know what function you are using based on the args that you provide.\n\nint sum(double n1, double n2){\n\t double res = n1 + n2; // local variable\n        std::cout << n1 << \" + \"<< n2 << \" = \"<< res << std::endl;\n        return res;\n}\n\n// FUNCTIONS INSIDE ANOTHER?\n\n// ❌ This is an error, we can't define a function inside in another.\n/*\nvoid greetingOutside(){\nvoid greetingInside(){\n\tstd::cout << \"Hello, I´m a function inside a function \" << std::endl;\n}\n}\n*/\nvoid greetingInside(){\n\tstd::cout << \"Hello, I´m a function inside a function \" << std::endl;\n}\n\n// Here we are using a function inside another.\nvoid greetingOutside(){\n\tgreetingInside();\n}\n\n\n/*\n * EXTRA DIFFICULTY\n * */\n//2 params type string\n// return int\n// f => [1-100]\n// print:\n// residue betwen 3 = 0 => 1param\n// residue betwen 5 = 0 => 2param\n// residue betwen 3 = 0 and 5 = 0 => 1param2param (concatenated)\n// RETURN: int isn't multiple of 3, 5 and both, number of times.\n\nint exercise(std::string text1, std::string text2){\n\tint acc = 0;\n\tfor(int i = 1; i <=100; i++){\n\t\tstd::cout << i <<std::endl;\nif(i%3==0 && i%5==0){\n\t\t\tstd::cout << text1 << text2 << std::endl;\n\n\t\t}\nelse if(i%3==0){\n\t\t\tstd::cout << text1 << std::endl;\n\t\t}\n\t\telse if(i%5==0){\n\t\t\tstd::cout << text2 << std::endl;\n\t\t}\n\t\t\n\t\telse {\n\t\t\tacc +=1;\n\t\t}\n\t}\n\treturn acc;\n}\n\n\n\nint main(){\ngreeting();\nshowMsg(\"David\");\ndouble res = sum(2.8293,3.4395);\nstd::cout <<\"Out - res SUM DOUBLE: \"<< sum(2.8293, 3.4395);\nstd::cout <<\"Out - res SUM INT: \"<< sum(1,3);\n\n\ngreetingOutside();\nint n = exercise(\"david\", \"arroz\");\nstd::cout<<n<<std::endl;\nreturn 0; \n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c++/hectorio23.cpp",
    "content": "#include <iostream>\n#include <string>\n\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n// Ejemplo de función sin parámetros ni retorno\nvoid saludar() {\n    std::cout << \"¡Hola, mundo!\" << std::endl;\n}\n\n// Ejemplo de función con parámetros y retorno\nint suma(int a, int b) {\n    return a + b;\n}\n\n// Ejemplo de función con función anidada\nstd::pair<int, int> operaciones(int a, int b) {\n    // Función lambda anidada\n    auto multiplicar = [&]() {\n        return a * b;\n    };\n\n    int resultado_multiplicacion = multiplicar();\n    int resultado_suma = suma(a, b);\n\n    return std::make_pair(resultado_multiplicacion, resultado_suma);\n}\n\n// Variable global\nint variable_global = 10;\n\n// Ejemplo de función que utiliza variable global\nvoid usar_variable_global() {\n    variable_global += 5;\n}\n\nint  ejercicioExtra(std::string, std::string); \n\nint main() {\n\n    int resultado_suma = suma(3, 7);\n    std::cout << \"Resultado de la suma: \" << resultado_suma << std::endl;\n\n    auto resultado_operaciones = operaciones(2, 4);\n    std::cout << \"Resultado de la multiplicación y suma: \" << resultado_operaciones.first << \", \" << resultado_operaciones.second << std::endl;\n\n    std::cout << \"Valor inicial de la variable global: \" << variable_global << std::endl;\n    usar_variable_global();\n    std::cout << \"Valor de la variable global después de usar_variable_global: \" << variable_global << std::endl;\n\n\n    int data = ejercicioExtra(\"Hola\", \"Mundo\");\n    std::cout << \"Se imprimio un numero que no cumple con las condiciones: \" << data << \" veces\\n\";\n    return 0;\n}\n\n// funcion  que cumple con el ejercicio extra\nint  ejercicioExtra(std::string cadenaTexto1, std::string cadenaTexto2) {\n    // El siguiente contador almacenara las veces que se imprimira en terminal\n    // el numero que no cumpla con las condiciones\n    int counter = 0;\n\n    // El siguente codigo hace todo el trabajo\n    for (int i = 1; i <= 100; i++) {\n        if (i % 5 == 0 && i % 3 == 0) std::cout << i << \" => \" << cadenaTexto1 << \" \" << cadenaTexto2 << \"\\n\";\n        else if (i % 3 == 0) std::cout << i << \" => \"<< cadenaTexto1 << \"\\n\";\n        else if (i % 5 == 0) std::cout << i << \" => \"<< cadenaTexto2 << \"\\n\";\n        else {\n            std::cout << i << \"\\n\";\n            counter++;\n        }\n    }\n\n    return counter;\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c++/jhoshmc.cpp",
    "content": "#include <iostream>\n#include <string.h>\nusing namespace std;\nconst string variable_global = \"hola, soy global\";\n// declaraciones de funciones\nvoid hi(); // funcion sin parametro ni rotorno\nvoid saludar(string nombre); // funcion con 1 parametro y sin retorno\nvoid presentar(string, string); // funcion con 2 parametros y sin retorno\nint suma_entera(int, int); // funcion con 2 parametros y con retorno\nvoid funcion_anidada(int); // funcion que dependiendo el nuemro llama a una funcion o otra\nint ejercicio_extra(string, string);\n//* funcion principal\nint main(){\n  const string variable_local = \"hola, soy local\";\n  int contador;\n  hi();\n  saludar(\"lucho\");\n  presentar(\"juan\", \"ana\");\n  cout << \"la suma es \" << suma_entera(4, 6)<<endl;\n  funcion_anidada(2);\n  cout << variable_local << \" solo puedo ser llamada en mi scope,( mi entorno aislado)\" << endl;\n  contador = ejercicio_extra(\"biz\",\"buzz\");\n  cout << \"numero de veces que no se escribio un texto: \" << contador<<endl;\n  return 0;\n}\n\n//* desarrollo de las funciones declaradas\nvoid hi(){\n  cout << \"hi, welcome to the jungle\"<<endl;\n  cout << variable_global << \" me puede llamar en culaquier parte del codigo \\t no rengo restincciones de scope ( entorno) :v\"<<endl;\n}\n\nvoid saludar(string nombre){\n  cout << \"hola  \"<<nombre << endl;\n}\n\nvoid presentar(string nombre_1, string nombre_2){\n  cout << \"hola \" << nombre_1 << \", te presento a \" << nombre_2 << endl;\n}\n\nint suma_entera(int n_1, int n_2){\n  return n_1 + n_2;\n}\n\nvoid funcion_anidada(int numero){\n  // funcion lambda\n  auto dividir = [&]()\n  {\n    return numero / 2;\n  };\n  cout << \"la divicion es: \" << dividir() << endl;\n}\n\nint ejercicio_extra(string biz, string buzz){\n\n  int contador = 0;\n  for (int i=1; i <=100; i++)\n  {\n    if (i % 15 == 0)\n    {\n      cout << i<<\" \" << biz << \" \" << buzz << endl;\n    }else if (i % 5 == 0)\n    {\n      cout<<i<<\" \" << buzz << endl;\n    }else if ( i % 3 == 0)\n    {\n      cout<<i <<\" \"<< biz << endl;\n    }else{\n      contador++;\n    }\n    \n    \n  }\n\n  return contador;\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c++/m-doce.cpp",
    "content": "#include <iostream>\r\n\r\n//Función que recibe parámetros y devuelve un valor\r\nint Suma (int numA, int numB)\r\n{\r\n    return (numA + numB);\r\n}\r\n\r\n//Función que no recibe parámetros ni devuelve ningún valor\r\nvoid UsoDeFunciones()\r\n{\r\n    printf(\"[*] En C++ una funcion debe declararse segun el tipo de dato que retorne (int, bool, etc), o como 'void' en caso de no retornar nada\\n\");\r\n    printf(\"[*] Las funciones pueden o no recibir parametros. Si lo hacen, estos deben ser declarados entre parentesis con su tipo de dato y un nombre\\n\");\r\n    printf(\"[*] Si queremos que una variable cambie su valor luego de pasar por una funcion, debemos pasarla por referencia, utilizando un '&' en la llamada a funcion\\n\");\r\n\r\n    return;\r\n}\r\n\r\n//Función con variables locales (solo existen en el bloque de código en el que se declaran)\r\nvoid EsMayor()\r\n{\r\n    int numA = 5;\r\n    int numB = 7;\r\n    bool check = (numA > numB);\r\n\r\n    check? printf(\"%d es mayor que %d\\n\", numA, numB) : printf(\"%d no es mayor que %d\\n\", numA, numB);\r\n\r\n    return;\r\n}\r\n\r\n//Variale global (son accesibles en todo el código)\r\nint valor = 10;\r\n\r\n//Función ejercicio extra\r\nint Extra(char wordA[], char wordB[])\r\n{\r\n    int contador = 0;\r\n\r\n    for(int i=1; i<101; i++)\r\n    {\r\n        if(((i % 3) == 0) and ((i % 5) == 0))\r\n            printf(\"[*] %s %s\\n\", wordA, wordB);\r\n        else if((i % 3) == 0)\r\n            printf(\"[*] %s\\n\", wordA);\r\n        else if((i % 5) == 0)\r\n            printf(\"[*] %s\\n\", wordB);\r\n        else\r\n        {\r\n            printf(\"[*] %d\\n\", i);\r\n            contador++;\r\n        }\r\n    }\r\n\r\n    return contador;\r\n}\r\n\r\nint main()\r\n{\r\n    UsoDeFunciones();\r\n    printf(\"%d\\n\", Suma(valor, 2));\r\n    EsMayor();\r\n\r\n    printf(\"\\n\\nEjercicio Extra:\\n\");\r\n    int resultado = Extra(\"Azul\", \"Amarillo\");\r\n    printf(\"En total se imprimieron %d numeros.\", resultado);\r\n\r\n    return 0;\r\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c++/oixild.cpp",
    "content": "// En C++, no se pueden crear funciones dentro de otras funciones.\n\n#include <iostream>\n\n// VARIABLE GLOBAL\nchar globalVar[] = \"global\";\n\n\n// FUNCION SIN PARAMETROS NI RETORNO\nvoid voidFunc()\n{\n\n}\nint intFunc()\n{\n\treturn 1;\n}\nchar charFunc(const char *str)\n{\n\tstd::cout << \"Tu caracter seleccionado: \" << str << std::endl;\n\treturn *str;\n}\n\nvoid ft_fizzbuzz(char *str1, char *str2)\n{\n\tint i = 1;\n\twhile (i < 101)\n\t{\n\t\tif (i % 3 == 0 && i % 5 == 0)\n\t\t{\n\t\t\tstd::cout << str1 << str2 << std::endl;\n\t\t}\n\t\tif (i % 3 == 0 && i % 5 != 0)\n\t\t{\n\t\t\tstd::cout << str1 << std::endl;\n\t\t}\n\t\tif (i % 5 == 0 && i % 3 != 0)\n\t\t{\n\t\t\tstd::cout << str2 << std::endl;\n\t\t}\n\t\tif (i % 3 != 0 && i % 5 != 0)\n\t\t{\n\t\t\tstd::cout << i << std::endl;\n\t\t}\n\t\ti++;\n\t}\n}\n\nint main()\n{\n\tstd::cout << \"IMPRIMIR UN CARACTER DESDE OTRA FUNCION ENVIANDOLE UN PARAMETRO\" << std::endl;\n\tchar a[1];\n\tstd::cin >> a;\n\tcharFunc(a);\n\n\tstd::cout << \"\\nUtiliza algn ejemplo de funciones ya creadas en el lenguaje.\" << std::endl;\n\tchar z = 'z';\n\tchar y = toupper(z); // Uso de la funcion toupper() para convertir el caracter de minuscula a mayuscula\n\tstd::cout << y << std::endl;\n\n\tstd::cout << \"\\nPon a prueba el concepto de variable LOCAL y GLOBAL.\" << std::endl;\n\tchar localVar[] = \"local\";\n\tstd::cout << localVar << std::endl;\n\tstd::cout << globalVar << std::endl;\n\n\tstd::cout << \"\\nDIFICULTAD EXTRA(opcional) :\" << std::endl;\n\tchar str1[20];\n\tchar str2[20];\n\tstd::cout << \"Selecciona una palabra que no supere los 19 caracteres:\" << std::endl;\n\tstd::cin >> str1;\n\tstd::cout << \"Selecciona otra palabra que no supere los 19 caracteres:\" << std::endl;\n\tstd::cin >> str2;\n\tft_fizzbuzz(str1, str2);\n\n\treturn 0;\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c++/tomytsa.cpp",
    "content": "\n\n\n// FUNCIONES Y ALCANCE\n\n#include <iostream>\nusing namespace std;\n\n\n\n// Funcion simple\n\nvoid Saludar (){\n    cout << \"Hello World!\" << endl;\n}\n\n// Funcion con un parametro por defecto\n\nvoid saludoPersonalizado (string nombre = \"Tomas\"){\n    cout << \"Hello \" << nombre << \"!\" << endl;\n}\n\n// Funcion con return y dos parametros\n\nint Max (int x, int y){\n    int MayorNum;\n    if (x > y)\n    {\n        MayorNum = x;\n    }\n    else{\n        MayorNum = y;\n    }\n    return MayorNum;\n}\n\n// Ejercicio de dificultad extra:\n\nint string_to_int(string x, string y){\n        int cont = 0;\n        for (int i = 1; i < 101; i++)\n        {\n            if (i % 5 == 0 && i % 3 == 0)\n            {\n                cout << x << \" \" << y << endl;\n            }\n            else if (i % 5 == 0)\n            {\n                cout << y << endl;\n            }\n            else if (i % 3 == 0)\n            {\n                cout << x << endl;\n            }\n            else\n            {\n                cout << i << endl;\n                cont++;\n            }\n           \n        }\n        return cont;\n}\n\nint main()\n{\n\n    int numeroMax;\n    int numeroMin;\n    cout << \"Ingrese dos numeros: \" << endl;\n    int n1, n2;\n    cin >> n1 >> n2; \n    numeroMax = Max(n1, n2);\n    cout << \"El numero mas grande es: \" << numeroMax << endl;\n\n    // Ejemplo de funcion Build-In en C++\n\n    numeroMin = min(n1, n2);\n    cout << \"El numero mas grande es: \" << numeroMin << endl;\n\n\n\n    Saludar();\n    saludoPersonalizado();\n    int cont = string_to_int(\"hola\", \"tomas\");\n    cout << cont << endl;\n\n    \n\n    \n\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c++/xooseph.cpp",
    "content": "#include <iostream>\n#include <cmath>\n\nusing namespace std;\n\n// Global variable\nint anotherAge = 24;\n\nvoid printUsername() {\n    cout << \"Mi nombre es xooseph.\" << endl;\n}\n\nvoid printAge(int age) {\n    cout << \"Tengo \" << age << \" años.\" << endl;\n}\n\nint printSum(int a, int b) {\n    return a + b;\n}\n\nvoid printUsernameAndAge(int anotherAge) {\n    printUsername();\n    printAge(anotherAge);\n}\n\n/*\nEJERCICIO EXTRA\nFunción que recibe dos parámetros de tipo cadena de texto y retorna un número.\n *   - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n*/\n\nint multiples(string text1, string text2) {\n    int numbersWithoutText = 0;\n\n    for (int i = 1; i <= 100; i++) {\n        if (i % 3 == 0 && i % 5 == 0) {\n            cout << text1 << \" \" << text2 << endl;\n        }\n        else if (i % 3 == 0) {\n            cout << text1 << endl;\n        }\n        else if (i % 5 == 0) {\n            cout << text2 << endl;\n        }\n        else {\n            cout << i << endl;\n\n            numbersWithoutText++;\n        }\n    }\n\n    return numbersWithoutText;\n}\n\nint main() {\n    int age = 23, a = 2, b = 4, c = 121;\n    int result, i;\n    string text1 = \"Hello\", text2 = \"World!\";\n\n    printUsername();\n    printAge(age);\n    result = printSum(a,b);\n\n    cout << \"La suma de 2 y 4 es \" << result << endl;\n\n    printUsernameAndAge(anotherAge);\n\n    cout << \"La raíz cuadrada de 121 es \" << sqrt(c) << endl;\n\n    cout << \"\\nEJERCICIO EXTRA\" << endl;\n\n    i = multiples(text1, text2);\n\n    cout << \"Se imprimieron \" << i << \" números en lugar de las cadenas de texto.\" << endl;\n\n    return 0;\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/c++/yeisonagm.cpp",
    "content": "/* EJERCICIO #02: FUNCIONES Y ALCANCE\n * Crea ejemplos de funciones básicas que representen las diferentes posibilidades del lenguaje\n*/\n#include <iostream>\n#include <string>\n#include <cmath>\n#include <utility>\n\nusing namespace std;\n\n// Variale global\nstd::string lenguajeProgramacion{\"C++ 11\"};\n\n// Función que imprime un saludo\nvoid saludo() {\n    cout << endl << \"Restos de programación con \" << lenguajeProgramacion << endl;\n}\n\n// Función que determina si un número es primo\nbool esPrimo(int n) {\n    if (n <= 1) {\n        return false;\n    }\n\n    for (int i = 2; i < n; i++) {\n        if (n % i == 0) {\n            return false;\n        }\n    }\n\n    return true;\n}\n\n// Función que suma dos números\nint suma(int a, int b) {\n    return a + b;\n}\n\n// Declara la función de la dificultad extra\nint dificultadExtra(std::string texto1, std::string texto2);\n\n\nint main() {\n    cout << \"Lenguaje de programación: \" << lenguajeProgramacion << endl;\n\n    // Función sin parámetro ni retorno\n    saludo();\n\n    int n = 47;\n    // Función con parámetro y retorno\n    bool primo = esPrimo(n);\n    cout << \"El número \" << n << (primo ? \" es\" : \" no es\") << \" primo\" << endl;\n\n    int a = 5, b = 10;\n    // Función con parámetros y retorno\n    int sumaAB = suma(a, b);\n    cout << \"La suma de \" << a << \" + \" << b << \" es \" << sumaAB << endl;\n\n    // Función ya creada en la librería cmath\n    auto potencia = pow(2.0, 3.0);\n    cout << \"2^3 = \" << potencia << endl;\n\n    // Función lambda\n    auto actualizaVariableGlobal = [](std::string lenguaje) {\n        lenguajeProgramacion = std::move(lenguaje);\n        cout << \"Variable global actualizada\" << endl;\n    };\n\n    actualizaVariableGlobal(\"C++ 17\");\n    cout << \"Lenguaje de programación: \" << lenguajeProgramacion << endl;\n\n    // Dificultad extra\n    cout << endl << \"Dificultad extra\" << endl;\n    int veces = dificultadExtra(\"Fizz\", \"Buzz\");\n    cout << \"Se ha impreso el número en lugar de los textos \" << veces << \" veces\" << endl;\n\n    return 0;\n}\n\n/* Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n *  - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *  - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *  - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *  - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *  - La función retorna el número de veces que se ha impreso el número en lugar de los textos.                                                                                                                                                                                                                                *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n */\nint dificultadExtra(std::string texto1, std::string texto2) {\n    int contador = 0;\n\n    for (int i = 1; i <= 100; i++) {\n        if (i % 3 == 0 && i % 5 == 0) {\n            cout << texto1 + texto2 << \", \";\n        } else if (i % 3 == 0) {\n            cout << texto1 << \", \";\n        } else if (i % 5 == 0) {\n            cout << texto2 << \", \";\n        } else {\n            cout << i << \", \";\n            contador++;\n        }\n    }\n\n    cout << endl;\n    return contador;\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/clojure/josephinoo.clj",
    "content": "(defn without-return [a b]\n  (println (+ a b)))\n\n(defn with-return [c d]\n  (+ c d))\n\n(defn without-parameters []\n  (println \"This is a function without parameters\"))\n\n(defn with-parameters [e]\n  (println \"This is the parameter to print: \" e))\n\n(defn inner-function []\n  (defn second-function []\n    (println \"hello\"))\n  (second-function))\n\n\n(defn recursive [g]\n  (if (not= g 10)\n    (do\n      (println g)\n      (recursive (inc g)))\n    (println \"final\")))\n\n(defn local [w]\n  (let [local 10]\n    (println (+ w local))))\n\n\n\n; Extra\n(defn extra [text1 text2]\n  (doseq [item (range 1 100)]\n    (cond\n      (and (= (mod item 3) 0) (= (mod item 5) 0)) (println item text1 text2)\n      (= (mod item 5) 0) (println item text2)\n      (= (mod item 3) 0) (println item text1)\n      :else (println item))))\n\n\n(do\n  (without-return 2 2)\n  (println (with-return 2 2))\n\n  (without-parameters)\n  (with-parameters \"hello\")\n\n  (inner-function)\n  (recursive 1)\n\n  (println (count [1 2 3]))\n\n  (println local)\n  (local 2)\n\n  (extra \"one\" \"two\"))\n\n(def global-variable 10)\n\n(defn more-example-local []\n  (let [local-variable 5]\n    (println \"Local variable:\", local-variable))\n  (println \"Global variable:\", global-variable))\n\n; Calling the function\n(more-example-local)\n\n(println \"Global variable outside the function:\", global-variable)\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/cobol/any7dev.cbl",
    "content": "     /*\n      * EJERCICIO:\n      * - Crea ejemplos de funciones bsicas que representen las diferentes\n      *   posibilidades del lenguaje:\n      *   Sin parmetros ni retorno, con uno o varios parmetros, con retorno...\n      * - Comprueba si puedes crear funciones dentro de funciones.\n      * - Utiliza algn ejemplo de funciones ya creadas en el lenguaje.\n      * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n      * - Debes hacer print por consola del resultado de todos los ejemplos.\n      *   (y tener en cuenta que cada lenguaje puede poseer ms o menos posibilidades)\n      *\n      * DIFICULTAD EXTRA (opcional):\n      * Crea una funcin que reciba dos parmetros de tipo cadena de texto y retorne un nmero.\n      * - La funcin imprime todos los nmeros del 1 al 100. Teniendo en cuenta que:\n      *   - Si el nmero es mltiplo de 3, muestra la cadena de texto del primer parmetro.\n      *   - Si el nmero es mltiplo de 5, muestra la cadena de texto del segundo parmetro.\n      *   - Si el nmero es mltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n      *   - La funcin retorna el nmero de veces que se ha impreso el nmero en lugar de los textos.\n      *\n      * Presta especial atencin a la sintaxis que debes utilizar en cada uno de los casos.\n      * Cada lenguaje sigue una convenciones que debes de respetar para que el cdigo se entienda.\n     */\n       IDENTIFICATION DIVISION.\n       PROGRAM-ID. RETO-02.\n       DATA DIVISION.\n       FILE SECTION.\n       WORKING-STORAGE SECTION.\n      *Variables globales\n           77 VAR-GLOBAL PIC 9 VALUE 7.\n           77 CADENA1 PIC X(5) VALUE \"Casi\".\n           77 CADENA2 PIC X(10) VALUE \"Fizzbuzz\".\n           77 CADENA3 PIC X(20).\n           77 CONTADOR PIC 9(2) VALUE 0.\n           77 NUM PIC 9(3) VALUE 1.\n           77 RESULTADO PIC 9(3).\n           77 RESTO3 PIC 9.\n           77 RESTO5 PIC 9.\n       LOCAL-STORAGE SECTION.\n      *Variables locales\n           77 VAR-LOCAL PIC 9 VALUE 2.\n       PROCEDURE DIVISION.\n      *En COBOL no hay funciones, hay subrutinas y se usa el verbo PERFORM. No recibe parmetros\n      *ni tiene retorno, ni se puede crear otra subrutina dentro. Se puede llamar a otra subrutina\n      *dentro de otra\n       SUBRUTINA.\n           DISPLAY VAR-GLOBAL.\n           DISPLAY VAR-LOCAL.\n       OTRA-SUBRUTINA.\n           PERFORM SUBRUTINA.\n\n       EXTRA.\n           STRING CADENA1 CADENA2 INTO CADENA3\n           DISPLAY \"           Dificultad extra\"\n           PERFORM 100 TIMES\n           DIVIDE NUM BY 3 GIVING RESULTADO REMAINDER RESTO3\n           DIVIDE NUM BY 5 GIVING RESULTADO REMAINDER RESTO5\n           IF RESTO3 = 0 AND RESTO5 = 0\n               DISPLAY CADENA3\n           ELSE\n               IF RESTO3 = 0\n                   DISPLAY CADENA1\n               ELSE\n                   IF RESTO5 = 0\n                       DISPLAY CADENA2\n                   ELSE\n                       DISPLAY NUM\n                       ADD 1 TO CONTADOR\n                   END-IF\n               END-IF\n           END-IF\n           ADD 1 TO NUM\n           END-PERFORM.\n           DISPLAY \"Numero de veces que se ha impreso el numero en \"-\n           \"lugar de los textos: \" CONTADOR.\n\n       END PROGRAM RETO-02.\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/cobol/keltoi-dev.cbl",
    "content": "      * EJERCICIO:\n      * - Crea ejemplos de funciones bsicas que representen las diferentes\n      *   posibilidades del lenguaje:\n      *   Sin parmetros ni retorno, con uno o varios parmetros, con retorno...\n      * - Comprueba si puedes crear funciones dentro de funciones.\n      * - Utiliza algn ejemplo de funciones ya creadas en el lenguaje.\n      * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n      * - Debes hacer print por consola del resultado de todos los ejemplos.\n      *   (y tener en cuenta que cada lenguaje puede poseer ms o menos posibilidades)\n      *\n      * DIFICULTAD EXTRA (opcional):\n      * Crea una funcin que reciba dos parmetros de tipo cadena de texto y retorne un nmero.\n      * - La funcin imprime todos los nmeros del 1 al 100. Teniendo en cuenta que:\n      *   - Si el nmero es mltiplo de 3, muestra la cadena de texto del primer parmetro.\n      *   - Si el nmero es mltiplo de 5, muestra la cadena de texto del segundo parmetro.\n      *   - Si el nmero es mltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n      *   - La funcin retorna el nmero de veces que se ha impreso el nmero en lugar de los textos.\n      *\n      * Presta especial atencin a la sintaxis que debes utilizar en cada uno de los casos.\n      * Cada lenguaje sigue una convenciones que debes de respetar para que el cdigo se entienda.\n\n       IDENTIFICATION DIVISION.\n       PROGRAM-ID. RETO-02.\n       DATA DIVISION.\n       FILE SECTION.\n       WORKING-STORAGE SECTION.\n       77  numero1 PIC 99 VALUE 10.\n       77  numero2 PIC 99 VALUE 5.\n       77  resultado PIC 9999 VALUE ZERO.\n       77  dato1 PIC X(9) VALUE \"Funcion 1\".\n       77  dato2 PIC X(9) VALUE \"Funcion 2\".\n       77  resul-factor PIC 9(10).\n       01  palabras.\n           03 palabra-1 PIC X(4) VALUE \"Fizz\".\n           03 FILLER PIC X VALUE \" \".\n           03 palabra-2 PIC X(4) VALUE \"Buzz\".\n       77  I PIC 9(3).\n       77  resto-3 PIC 9(2).\n       77  resto-5 PIC 9(2).\n       77  contador PIC 9(2) VALUE ZERO.\n\n       PROCEDURE DIVISION.\n\n      * En este lenguajes se usan las subrrutinas o parrafos en semajanza a\n      * las funciones, tal como existen en otros lenguajes.\n      * Al igual que las variables todas son globales, ya que se declaran en\n      * la seccion working-storage. Por ello no se pasan como parametros a las\n      * subrrutinas como en otros lenguajes.\n\n       Inicio.\n      * Funciones simples.\n           DISPLAY \"-- Funcion simple\"\n           PERFORM Funcion-simple.\n      * Funcion dentro de otra funcion.\n           DISPLAY \"-- Funcion dentro de otra funcion\"\n           PERFORM Funcion-1.\n\n      * Funcion recursiva.\n           DISPLAY \"-- Funcion recursiva\"\n           MOVE numero1 TO resul-factor.\n           PERFORM Factoreo.\n           DISPLAY \"El resultado del factoreo es: \" resul-factor.\n\n      * Dificultad extra.\n           DISPLAY \"-- Dificultad extra\".\n           PERFORM Dificultad-extra VARYING I FROM 1 BY 1 UNTIL I = 100.\n           DISPLAY \"Se han impreso \" contador \" numeros.\".\n\n           STOP RUN.\n\n       Funcion-simple.\n           COMPUTE resultado = numero1 + numero2.\n           DISPLAY numero1 \" + \" numero2 \" = \" resultado.\n\n       Funcion-1.\n           DISPLAY \"Esta en la \" dato1.\n           PERFORM Funcion-2.\n           DISPLAY \"Esta de regreso en la\" dato1.\n\n       Funcion-2.\n           DISPLAY \"Esta en la \" dato2.\n\n       Factoreo.\n           IF numero1 = 1 THEN\n               DISPLAY numero1\n           ELSE\n               IF numero1 = 0 THEN\n                   DISPLAY numero1\n               ELSE\n                   DISPLAY numero1\n                   SUBTRACT 1 FROM numero1\n                   COMPUTE resul-factor = resul-factor * numero1\n                   PERFORM Factoreo\n               END-IF\n           END-IF.\n\n       Dificultad-extra.\n           DIVIDE I BY 3 GIVING resultado REMAINDER resto-3.\n           DIVIDE I BY 5 GIVING resultado REMAINDER resto-5.\n           IF resto-3 = 0 AND resto-5 = 0 THEN\n               DISPLAY palabras\n           ELSE\n               IF resto-3 = 0 THEN\n                   DISPLAY palabra-1\n               ELSE\n                   IF resto-5 = 0 THEN\n                       DISPLAY palabra-2\n                   ELSE\n                       DISPLAY I\n                       ADD 1 to contador\n                   END-IF\n               END-IF\n           END-IF.\n\n       END PROGRAM RETO-02.\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/dart/D3rk1us.dart",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n\n// Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n\nvoid sinParaFunction() {\n  print('Hola');\n}\n\nString fullName(String name, String surname) {\n  return name + ' ' + surname;\n}\n\nvoid suma(int a, int b) {\n  print(a + b);\n}\n\n\n// Comprueba si puedes crear funciones dentro de funciones.\n\nvoid resultado() {\n\n  int resta(int a, int b) {\n    return a - b;\n  }\n\n  print(resta(2, 4));\n}\n\n/*\n\n DIFICULTAD EXTRA (opcional):\n\n  * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n  * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n  *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n  *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n  *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n  *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n  *\n  * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n  * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n \n */\n\nint numeros(String fizz, String buzz) {\n  int result = 0;\n\n  for(int i = 0; i <= 100; i++) {\n\n    if ( i % 3 == 0 && i % 5 == 0) {\n      print(fizz + buzz);\n\n    } else if ( i % 3 == 0) {\n\n      print(fizz);\n    } else if ( i % 5 == 0) {\n      print(buzz);\n    } else {\n      result += 1;\n    }\n  }\n  return result;\n}\n/* -------------------------------------------------------- */\n\nvoid main() {\n\n  var listado = ['Botella de agua', 'Mochila', 'Saco de dormir'];\n  \n  sinParaFunction();\n\n  print(fullName(\"Marcos\", \"Barrientos\"));\n\n  suma(4, 6);\n\n  resultado();\n\n  // Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n\n  listado.forEach((element) {\n    print(element); \n  });\n\n  // Dificultad Extra\n  print(numeros('fizz', 'buzz'));\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/dart/Lia-M3dusa.dart",
    "content": "\nvoid ExamplePrint(){\n  print(\"Hello World\");\n}\n\nint sum(int a, int b){\n  return a + b;\n}\n\nint substract(int a, int b){\n  return a - b;\n}\n\nint twoString(String a, String b){\n  int contenoNumeros = 0;\n\n  for(int i=1; i<=100; i++){\n    if (i % 3 == 0){\n      print(a);\n    }else if(i % 3 == 0 && i % 5 == 0){\n      print(a + b);\n\n    }\n    else if (i % 5 == 0){\n      print(b);\n    }else{\n      print(i);\n      contenoNumeros++;\n    }\n  }\n  return contenoNumeros;\n}\n\n//variable global\nString global = \"esto es global\";\n\nvoid main(List<String> args) {\n  \n  //Variable local\n  String local= \"esto es local\";\n  \n  //Funcion anidada \n  void fExternal(){\n    void fInternal(){\n      print(\"Esto es interna\");\n    }\n    print(\"Esto es externa\");\n    fInternal();\n  }\n  fExternal();\n\n  //Funciones\n  ExamplePrint();\n  print(sum(5, 5));\n  print(substract(5, 5));\n  print(global);\n  print(local);\n\n  //Funcion que recibe dos strings y un numero\n  print(twoString(\"Fizz\", \"Buzz\"));\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/dart/angelsanchezt.dart",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n\n// Ejemplo 1: Funciones básicas\n\n// Función sin párametros ni retorno\nvoid funcionSinParametrosNiRetorno() {\n  print(\"Esta función no tiene parámetros ni retorno\");\n}\n\n//Función con parametros y sin retorno\nint funcionConParametrosYRetorno(int a, int b) {\n  return a + b;\n}\n\nvoid funcionConParametros(String nombre, int edad) {\n  print(\"Nombre: $nombre, Edad: $edad\");\n}\n\n //Función con un parámetro nominal y sin retorno\nvoid funcionParametroNominal({required String nombre}) {\n  print('¡Hola, $nombre!');\n}\n\n// Ejemplo 2: Funciones dentro de funciones\nvoid funcionExterna() {\n  void funcionInterna() {\n    print(\"Esta es una función interna\");\n  }\n\n  funcionInterna();\n  print('Función externa');\n}\n\n// Ejemplo 3: Uso de funciones ya creadas en Dart\nvoid ejemploFuncionDart() {\n  print(\"El cuadrado de 5 es: ${square(5)}\");\n}\n\nint square(int num) {\n  return num * num;\n}\n\n// Ejemplo 4: Variable LOCAL y GLOBAL\nint variableGlobal = 10;\n\nvoid funcionConVariableLocal() {\n  int variableLocal = 5;\n  print(\"Variable Local: $variableLocal, Variable Global: $variableGlobal\");\n}\n\n// Ejemplo 5: Prueba de conceptos\nvoid main() {\n  print(\"Ejemplo 1:\");\n  funcionSinParametrosNiRetorno();\n  \n  print(\"Resultado de la función con parámetros y retorno: ${funcionConParametrosYRetorno(3, 7)}\");\n  \n  funcionConParametros(\"Juan\", 25);\n\n  //Función con un parámetro nominal y sin retorno\n  funcionParametroNominal(nombre: 'Angel');\n\n  print(\"\\nEjemplo 2:\");\n  funcionExterna();\n\n  print(\"\\nEjemplo 3:\");\n  ejemploFuncionDart();\n\n  print(\"\\nEjemplo 4:\");\n  funcionConVariableLocal();\n  // Variable local no accesible fuera de la función\n  // print(\"Variable Local fuera de la función: $variableLocal\");\n\n  print(\"\\nEjemplo 6 (Dificultad Extra):\");\n  int resultado = funcionDificultadExtra(\"Fizz\", \"Buzz\");\n  print(\"La función se ejecutó $resultado veces.\");\n}\n\n// Ejemplo 6 (Dificultad Extra): Función con parámetros de texto y retorno de número\nint funcionDificultadExtra(String texto1, String texto2) {\n  int conteo = 0;\n\n  for (int i = 1; i <= 100; i++) {\n    if (i % 3 == 0 && i % 5 == 0) {\n      print(\"$i $texto1 $texto2\");\n    } else if (i % 3 == 0) {\n      print(\"$i $texto1\");\n    } else if (i % 5 == 0) {\n      print(\"$i $texto2\");\n    } else {\n      print(\"$i\");\n    }\n    conteo++;\n  }\n\n  return conteo;\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/dart/bluefeatherdev.dart",
    "content": "/*\n* EJERCICIO:\n* - Crea ejemplos de funciones básicas que representen las diferentes\n*   posibilidades del lenguaje:\n*   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n* - Comprueba si puedes crear funciones dentro de funciones.\n* - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n* - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n* - Debes hacer print por consola del resultado de todos los ejemplos.\n*   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n*\n* DIFICULTAD EXTRA (opcional):\n* Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n* - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n*   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n*   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n*   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n*   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n*\n* Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n* Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n*/\n\n/// 1. Ejemplo de una función en Dart:\nvoid greet(String name) {\n  print('Hello, $name!');\n}\n\n/// 2. Función sin parámetro ni retorno:\nvoid greet2() {\n  print('Hello, stranger!');\n}\n\n/// 3. Función con parámetro, sin retorno:\nvoid greet3(String name) {\n  print('How are you, $name?');\n}\n\n/// 4. Función con parámetro y retorno:\nString greet4(String name) {\n  return 'Hello, $name!';\n}\n\n/// 5. Función con varios parámetros y retorno:\nString showAge(String name, int age) {\n  return '$name is $age years old!';\n}\n\n/// 6. Funciones dentro de funciones:\nint calculate(int x) {\n  int doubleIt(int n) {\n    return n * 2;\n  }\n\n  int squareIt(int n) {\n    return n * n;\n  }\n\n  return squareIt(doubleIt(x));\n}\n\n/// 7. Algunas funciones del lenguaje:\nvoid someBuiltInFunctions() {\n  // print()\n  print('Hello, Dart!');\n\n  // int.parse()\n  int myInt = int.parse('23');\n  print(myInt); // 23\n\n  // double.parse()\n  double myDouble = double.parse('15.23');\n  print(myDouble);  // 15.23\n\n  // .toString()\n  num myNum = 19;\n  print(myNum.toString());  // '19'\n\n  // .length\n  List<int> myList = [1, 2, 3];\n  print(myList.length); // 3\n\n  // .contains()\n  print(myList.contains(2));  // true\n\n  // .map() and toList()\n  var listToDouble = myList\n    .map((e) => e * 2)\n    .toList();\n  print(listToDouble); // [2, 4, 6]\n\n  // .where() and toList()\n  var evens = myList\n    .where((e) => e % 2 == 0)\n    .toList();\n  print(evens); // [2]\n\n  // .split()\n  var words = 'One, two, three'.split(', ');\n  print(words); // [One, two, three] \n\n  // .toUpperCase()\n  print('dart'.toUpperCase());  // DART\n}\n\n/// 8. Variable local:\nList<int> countTo(int n) {\n  var myLocalList = <int>[];\n  for (var i = 0; i < n; i++) {\n    myLocalList.add(i);\n  }\n  return myLocalList;\n}\n\n/// 9. Variable global\nList<int> myGlobalList = [0, 1, 2];\nvoid someFunction1() {\n  var myLocalList = <int>[3, 4];\n  myGlobalList += myLocalList;\n}\n\n/// 10. Funciones flecha\nString greet5(String name) => 'Hello, $name!';\n\n/// 11. Parámetros nombrados:\nint? sum({int? a, int? b}) {\n  if (a != null && b != null) return a + b;\n  return null;\n}\n\n/// 12. Parámetros nombrados con valores por defecto:\nString showMessage({\n  String author = 'Unknown', \n  String msg = 'No message',\n}) {\n  return '$author: $msg';\n}\n\n/// 13. Parámetros nombrados obligatorios:\nString greet6({required String fistName, String? lastName}) {\n  if (lastName != null) return 'Hello, $fistName $lastName!';\n  return 'Hello, $fistName!';\n}\n\n/// 14. Parámetros opcionales:\nString greet7(String from, String msg, [String? device]) {\n  var result = '$from says $msg';\n  if (device != null) {\n    result = '$result with a $device';\n  }\n  return result;\n}\n\n/// 15. Parámetros opcionales con valores por defecto:\nString greet8(\n  String from, \n  String msg, \n  [String? device = 'carrier pigeon']\n) {\n  var result = '$from says $msg with a $device';\n  return result;\n} \n\n/// 16. Funciones como parámetros:\nvoid thisFunction(void Function() thatFunction) {\n  print('Doing thisFunction...');\n  thatFunction();\n}\n\nvoid thatFunction() {\n  print('Doing thatFunction...');\n}\n\n/// 17. Funciones como parámetros de métodos:\nvoid printElement(int element) {\n  print('printElement: $element');\n}\n\n/// 18. Funciones asignadas a variables:\nvar greet9 = (name) => 'Hello, $name!';\n\n/// 19. Uso de function types:\nvoid greet10(String name, {String greeting = 'Hello'}) {\n  print('$greeting, $name!');\n}\n\nvoid Function(String, {String greeting}) g = greet10;\n\n/// 20. Uso de typedef en function types:\ntypedef Greeter = void Function(String, {String greeting});\nGreeter g2 = greet10;\n\n/// 21. Funciones anónimas:\nvoid doSomething(int a, int b, Function operation) {\n  final result = operation(a, b);\n  print('Result: $result');\n}\n\n/// 22. Clausuras léxicas:\nFunction makeAdder(int addBy) {\n  return (int i) => addBy + i;\n}\n\n/// 23. Tear-off:\nvar globalCodes = [15, 16, 19, 23];\nvar globalBuffer = StringBuffer();\n\n/// 24. Retornar múltiples valores:\n(String, int) greet11() {\n  return ('Hello', 23);\n}\n\n/// [DIFICULTAD EXTRA]:\nint specialFunction(String a, String b) {\n  int count = 0;\n  for (var i = 1; i <= 100; i++) {\n    if (i % 3 == 0 && i % 5 == 0) {\n      print('$i: $a $b');\n    } else if (i % 3 == 0) {\n      print('$i: $a');\n    } else if (i % 5 == 0) {\n      print('$i: $b');\n    } else {\n      print('$i:');\n      count++;\n    }\n  }\n  return count;\n}\n\n/// 0. Función principal de alto nivel,\n/// sirve como punto de entrada a toda app;\n/// el argumento `List<String> args` es opcional:\nvoid main() {\n  /// 1. Ejemplo de una función en Dart:\n  greet('Jesús'); // 'Hello, Jesús!'\n\n  /// 2. Función sin parámetros ni retorno:\n  greet2(); // 'Hello, stranger!'\n\n  /// 3. Función con parámetros, sin retorno:\n  greet3('Jesús'); // 'How are you, Jesús?'\n  \n  /// 4. Función con parámetros y retorno:\n  print(greet4('Jesús')); // 'Hello, Jesús!'\n\n  /// 5. Función con varios parámetros y retorno:\n  print(showAge('Jesús', 21)); // 'Jesús is 21 years old!'\n\n  /// 6. Funciones dentro de funciones:\n  print(calculate(3));  // 36 → (3 * 2 = 6, 6 * 6 = 36)\n\n  /// 7. Algunas funciones del lenguaje:\n  someBuiltInFunctions(); // ...\n\n  /// 8. Variable local:\n  print(countTo(5)); // [0, 1, 2, 3, 4]\n\n  /// 9. Variable global:\n  print(myGlobalList); // [0, 1, 2]\n  someFunction1();\n  print(myGlobalList); // [0, 1, 2, 3, 4]\n\n  /// 10. Funciones flecha\n  print(greet5('Jesús')); // Hello, Jesús!\n\n  /// 11. Parámetros nombrados:\n  print(sum()); // null\n  print(sum(a: 5, b: 6)); // 11\n\n  /// 12. Parámetros nombrados con valores por defecto:\n  print(showMessage()); // Unknown: No message\n  print(showMessage(author: 'Jesús'));  // Jesús: No message\n  print(showMessage(author: 'Jesús', msg: 'Keep it up!')); // Jesús: Keep it up!\n\n  /// 13. Parámetros nombrados obligatorios:\n  print(greet6(fistName: 'Jesús')); // Hello, Jesús!\n  print(greet6(fistName: 'Jesús', lastName: 'Domínguez')); // Hello, Jesús Domínguez!\n\n  /// 14. Parámetros opcionales:\n  print(greet7('Jesús', 'Good evening')); // Jesús says Good evening\n  print(greet7('Jesús', 'Good evening', 'Laptop')); // Jesús says Good evening with a Laptop\n\n  /// 15. Parámetros opcionales con valores por defecto:\n  print(greet8('Jesús', 'Good evening')); // Jesús says Good evening with a carrier pigeon\n  print(greet8('Jesús', 'Good evening', 'Smartphone')); // Jesús says Good evening with a Smartphone\n\n  /// 16. Funciones como parámetros:\n  thisFunction(thatFunction); // ...\n\n  /// 17. Funciones como parámetros de métodos:\n  var myList = [1, 2, 3];\n  myList.forEach(printElement); // ...\n\n  /// 18. Funciones asignadas a variables:\n  print(greet9('Jesús')); // Hello, Jesús!\n\n  /// 19. Uso de function types:\n  g('Jesús', greeting: 'Howdy');  // Howdy, Jesús!\n\n  /// 20. Uso de typedef en function types:\n  g2('Jesús', greeting: 'Howdy');  // Howdy, Jesús!\n\n  /// 21. Funciones anónimas:\n  doSomething(1, 5, (x, y) {return x + y;}); // Result: 6\n  doSomething(2, 3, (x, y) => x * y); // Result: 6\n\n  /// 22. Clausuras léxicas:\n  var add2 = makeAdder(2);\n  var add4 = makeAdder(4);\n  var add6 = makeAdder(6);\n  print(add2(3)); // 5 (3 + 2)\n  print(add4(1)); // 5 (4 + 1)\n  print(add6(-1)); // 5 (-1 + 6)\n\n  /// 23. Tear-off:\n  globalCodes.forEach(print); // Function, OK\n  globalCodes.forEach(globalBuffer.write);  // Method, OK\n\n  /// 24. Retornar múltiples valores:\n  print(greet11()); // (Hello!, 23)\n\n  /// [DIFICULTAD EXTRA]:\n  print(specialFunction('fizz', 'buzz')); // 53\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/dart/kodenook.dart",
    "content": "\nString global = 'global';\n\nvoid main(){\n    name();\n    fullName(lname: 'kodenook');\n    print(addition([5, -2.5, 1.3]));\n    first();\n    scope();\n    print('number of times it was a number and not words: ${exercise('hello', 'dart')}');\n}\n\n/// The function \"name\" in Dart prints the string \"kodenook\".\nvoid name() {\n    print('kodenook');\n}\n\n/// The function fullName in Dart prints the full name by concatenating the provided first and last\n/// names.\n///\n/// Args:\n///   fname (String): The `fname` parameter in the `fullName` function is a String type parameter with a\n/// default value of `'hello'`. Defaults to hello\n///   lname (String): The `lname` parameter in the `fullName` function is a String parameter with a\n/// default value of `'name'`. Defaults to name\nvoid fullName({String fname = 'hello', String lname = 'name'}) { // with {} is optional\n    print('$fname $lname');\n}\n\n/// The `addition` function takes a list of numbers as input and returns the sum of all the numbers in\n/// the list.\n///\n/// Args:\n///   numbers (List<num>): A list of numbers that you want to add together.\n///\n/// Returns:\n///   the sum of all the numbers in the input list.\nnum addition(List<num> numbers) {\n    num result = 0;\n\n    for(var value in numbers) {\n        result += value;\n    }\n\n    return result;\n}\n\n/// The function `first` prints 'First' and then calls the nested function `second` which prints\n/// 'second'.\nvoid first() {\n    print('First');\n\n    void second() {\n        print('second');\n    }\n\n    second();\n}\n\n/// The function `scope` defines a local variable `local` and attempts to print both a global variable\n/// `global` and the local variable `local`.\nvoid scope() {\n    String local = 'local';\n\n    print(global);\n    print(local);\n}\n\n/*\n    Exercise\n*/\n\n/// This Dart function prints words based on divisibility rules and returns the count of numbers that do\n/// not meet those rules.\n///\n/// Args:\n///   word1 (String): Thank you for providing the code snippet. It looks like you are trying to\n/// implement a function that prints different words based on certain conditions for numbers from 1 to\n/// 100.\n///   word2 (String): It looks like you are trying to create a function that prints different words\n/// based on the divisibility of numbers from 1 to 100. However, there are a few issues in your code\n/// snippet:\n///\n/// Returns:\n///   The function `exercise` returns the count of numbers that are not divisible by 3 or 5 within the\n/// range of 1 to 100.\nint exercise(String word1, String word2) {\n    int countNumbers = 0;\n\n    for(int value = 1; value <= 100; value++) {\n        if(value % 3 == 0 && value % 5 == 0) {\n            print('$word1 $word2');\n        } else if (value % 3 == 0) {\n            print(word1);\n        } else if (value % 5 == 0) {\n            print(word2);\n        } else {\n            countNumbers++;\n        }\n    }\n\n    return countNumbers;\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/dart/marinaortells.dart",
    "content": "/// URL del sitio web oficial: https://dart.dev/\n\n/// Funciones simples\n\nint x = 5; /// Variable global\n\n\n\nvoid main() {\n\n  int y = 6; /// Variable local\n  imprimirFrase();\n  sumaNumeros(6, 7.8);\n  uno(8, num2: 89, num3: 18);\n  imprimir(6);\n  print(multNumeros(7, 8));\n  int fact = factorial(6);\n  print(fact);\n  persona(\"nombre\", \"apellido\", 19);\n  \n  print(\"Se han impreso números del 1 al 100: ${contar(\"ho\", \"la\")} veces\");\n}\n\n\n/// Funciones que no retornan nada (también puede NO ponerse el \"void\")\nvoid imprimirFrase() {\n  print(\"Probando funciones sin retorno\");\n}\n\n/// Funciones con parámetros obligatorios\nvoid sumaNumeros(num1, num2) {\n  print(num1 + num2);\n}\n\n/// Funciones con parámetros opcionales\n\nvoid uno(int num, {num2, num3}) {\n  print(num + num2 + num3);\n}\n\n/// Funciones con parámetros default\n\nvoid imprimir(int valor, {num = 4}) {\n  print(valor * num);\n}\n\n/// Funciones con retorno\n\nint multNumeros(var num1, var num2) {\n  return (num1 * num2);\n}\n\n\n/// Funciones más avanzadas\n\n/// Funciones recursivas\n\nfactorial(int n) {\n  if (n <= 0) {\n    return 1;\n  } else {\n    return n * factorial(n - 1);\n  }\n}\n\n/// Funciones lambda\n\n  printHello() => print(\"Hello\");\n\n/// Functiones dentro de otras funciones\n\npersona(primerNombre, segundoNombre, edad) {\n  nombreComp() {return primerNombre + \" \" + segundoNombre; }\n  print(\"Te llamas ${nombreComp()}, y tienes $edad años\");\n}\n\n/// DIFICULTAD EXTRA\nint contador = 0;\n\ncontar(String string1, String string2) {\n  for (int valor = 1; valor <= 100; valor++) {\n    if (((valor % 3)==0) && ((valor % 5)==0)) {\n      print(string1 + string2);\n    } else if ((valor % 3) == 0) { \n      print(string1);\n    } else if ((valor % 5) == 0) { \n      print(string2);\n    } else {\n      print(valor);\n      contador++;\n    }\n  }\n  return contador;\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/dart/raulfauli.dart",
    "content": "/// 02 FUNCIONES Y ALCANCE\n\nvoid main() {\n  helloWorld();\n  sayHello('Raúl');\n\n  double result = average(10, 20);\n  print('La media de 10 y 20: $result');\n\n  functionWithAnotherFunction();\n  // anotherFunction(); // Error\n\n  // Funciones del lenguaje [dart:core]\n  assert('  hello  '.trim() == 'hello');\n  assert('Never odd or even'.contains('odd'));\n  final now = DateTime.now();\n  print('Hora actual es: $now');\n  final value = BigInt.parse('12345678901234567890');\n  print('Valor BigInt: $value');\n\n  // Variables globales\n  testGlobalVariables();\n  print('La variable local sigue siendo $localVariable');\n\n  // Extra\n  int totalNumbers = extraFunction(\"Fizz\", \"Buzz\");\n  print('Total de números impresos: $totalNumbers');\n}\n\n// Función sin parametros retorno\nvoid helloWorld() {\n  print('Hello World!');\n}\n\n// Función con parametros\nvoid sayHello(String name) {\n  print('Hello $name!');\n}\n\n// Función con parametros y retorno\ndouble average(int a, int b) {\n  return (a + b) / 2;\n}\n\n// Función con otra función\nvoid functionWithAnotherFunction() {\n  void anotherFunction() {\n    print('I am another function');\n  }\n\n  anotherFunction();\n}\n\n// Testear global variables\nconst globalVariable = 10;\nconst localVariable = 10;\nvoid testGlobalVariables() {\n  print('La variable global es $globalVariable');\n  int localVariable = 20;\n  print('Ahora localVarible está definida dentro de la función y es $localVariable');\n}\n\n// Extra\nint extraFunction(String first, String second) {\n  int countNumbers = 0;\n  for (int i = 1; i <= 100; i++) {\n    if ((i % 3 == 0) && (i % 5 == 0)) {\n      print('$first$second');\n    } else if (i % 3 == 0) {\n      print(first);\n    } else if (i % 5 == 0) {\n      print(second);\n    } else {\n      print(i);\n      countNumbers++;\n    }\n  }\n  return countNumbers;\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/dart/sitnestic.dart",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n/// https://dart.dev/\n\nvoid main() {\n  // Función sin parámetros ni retorno\n  greet();\n\n  //Función con un parámetro y sin retorno\n  greetPerson('Gerard');\n\n  //Función con un parámetro nominal y sin retorno\n  greetPersonName(name: 'Gerard');\n\n  //Función con varios parámetros y sin retorno\n  calculateSum(5, 3);\n\n  //Función con un parámetro y con retorno\n  int result = square(4);\n  print(result);\n\n  //Función con varios parámetros y con retorno\n  List<double> values = [2.5, 4.5, 6.5];\n  double average = calculateAverage(values);\n  print(average);\n\n  //Función dentro de una función\n  outerFunction();\n\n  //Variables locales y globales\n  print('Variable global antes de la modificación: $globalVariable');\n  modifyGlobalVariable();\n  print('Variable global después de la modificación: $globalVariable');\n  localVariableExample();\n\n  //*! DIFICULTAD EXTRA (opcional):\n  int count = printNumbersAndCountTexts('Foo', 'Bar');\n  print('Número de veces que se ha impreso el número: $count');\n}\n\n// Función sin parámetros ni retorno\nvoid greet() {\n  print('¡Hola!');\n}\n\n//Función con un parámetro y sin retorno\nvoid greetPerson(String name) {\n  print('¡Hola, $name!');\n}\n\n//Función con un parámetro nominal y sin retorno\nvoid greetPersonName({required String name}) {\n  print('¡Hola, $name!');\n}\n\n//Función con varios parámetros y sin retorno\nvoid calculateSum(int a, int b) {\n  int sum = a + b;\n  print('La suma de $a y $b es $sum');\n}\n\n//Función con un parámetro y con retorno\nint square(int number) {\n  return number * number;\n}\n\n//Función con varios parámetros y con retorno\ndouble calculateAverage(List<double> numbers) {\n  double sum = 0;\n  for (double number in numbers) {\n    sum += number;\n  }\n  return sum / numbers.length;\n}\n\n//Función dentro de una función\nvoid outerFunction() {\n  void innerFunction() {\n    print('Función interna');\n  }\n\n  innerFunction();\n  print('Función externa');\n}\n\n//Variables locales y globales\nint globalVariable = 10;\n\nvoid modifyGlobalVariable() {\n  globalVariable = 20;\n  print('Variable global modificada: $globalVariable');\n}\n\nvoid localVariableExample() {\n  int localVariable = 5;\n  print('Variable local: $localVariable');\n}\n\n//*! DIFICULTAD EXTRA (opcional):\nint printNumbersAndCountTexts(String text1, String text2) {\n  int count = 0;\n\n  for (int i = 1; i <= 100; i++) {\n    if (i % 3 == 0 && i % 5 == 0) {\n      print('$text1 $text2');\n    } else if (i % 3 == 0) {\n      print(text1);\n    } else if (i % 5 == 0) {\n      print(text2);\n    } else {\n      print(i);\n      count++;\n    }\n  }\n\n  return count;\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/delphi/fduron.dpr",
    "content": "(*\n * EJERCICIO:\n * - Crea ejemplos de funciones bsicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parmetros ni retorno, con uno o varios parmetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algn ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer ms o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una funcin que reciba dos parmetros de tipo cadena de texto y retorne un nmero.\n * - La funcin imprime todos los nmeros del 1 al 100. Teniendo en cuenta que:\n *   - Si el nmero es mltiplo de 3, muestra la cadena de texto del primer parmetro.\n *   - Si el nmero es mltiplo de 5, muestra la cadena de texto del segundo parmetro.\n *   - Si el nmero es mltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La funcin retorna el nmero de veces que se ha impreso el nmero en lugar de los textos.\n *\n * Presta especial atencin a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el cdigo se entienda.\n *)\nprogram fduron;\n\n{$APPTYPE CONSOLE}\n\n{$R *.res}\n\nuses\n  System.SysUtils;\n\nvar\n  IGlobal: Integer;\n  TextoObtenido: String;\n\nprocedure UnProcedimientoNoPNoR;\nbegin\n  WriteLn('Esta linea se escribe desde un procedimiento sin parmetros ni retorno');\nend;\n\nfunction UnaFuncionSinParametros: String;\nbegin\n  Result := 'Resultado de una funcin sin parmetros';\nend;\n\nprocedure UnProcedimientoNoR(const Valor1: String; var Valor2: Integer);\nbegin\n  WriteLn('Procedimientos con dos prametros, por Valor y por Referencia: ',\n    Valor1, ' ', Valor2);\n  Valor2 := 100;\nend;\n\nfunction UnaFuncionConParametros(const Valor1: String; var Valor2: Integer): String;\nvar\n  ILocal: Integer;\nbegin\n  Result := 'Resultado de una funcin con parmetros ' + Valor1;\n  ILocal := IGlobal;\n  Valor2 := 200 + ILocal;\nend;\n\nprocedure ProcedimientoYFuncion(Valor1: String);\n\n  function DentroDelProcedimiento: String;\n  begin\n    Result := 'Texto dentro de una funcin, dentro de un procedimiento';\n  end;\n\nbegin\n  WriteLn('Variable: ', Valor1);\n  WriteLn(DentroDelProcedimiento);\nend;\n\nfunction DificultadExtra(const Parametro1, Parametro2: String): Integer;\nvar\n  I: Integer;\nbegin\n  Result := 0;\n  {se usa una coma ',' en todos los write para separar cada numero o variable}\n  for I := 1 to 100 do\n  begin\n    if ((I mod 5) = 0) and ((I mod 3) = 0) then\n      Write(Parametro1 + Parametro2, ',')\n    else\n    if (I mod 3) = 0 then\n      Write(Parametro1, ',')\n    else\n    if (I mod 5) = 0 then\n      Write(Parametro2, ',')\n    else\n    begin\n      Write(I, ',');\n      Result := Result + 1;\n    end;\n  end;\nend;\n\nbegin\n  var AquiRegresaValor2: Integer;\n  IGlobal := 14;\n  WriteLn('*** FUNCIONES Y ALCANCE ***');\n  UnProcedimientoNoPNoR;\n  WriteLn(UnaFuncionSinParametros);\n  AquiRegresaValor2 := 123;\n  UnProcedimientoNoR('Valor constante', AquiRegresaValor2);\n  WriteLn('Valor almacenado en la variable desde el procedimiento: ', AquiRegresaValor2);\n  WriteLn;\n  TextoObtenido := UnaFuncionConParametros('Valor constante para la funcin', AquiRegresaValor2);\n  WriteLn(TextoObtenido);\n  WriteLn('Valor almacenado en la variable desde la funcin: ', AquiRegresaValor2);\n  ProcedimientoYFuncion('Texto por valor');\n  WriteLn;\n  WriteLn('*** DIFICULTAD EXTRA ***');\n  var NumerosImpresos := DificultadExtra('(El parametro uno)', '(El parametro dos)');\n  WriteLn;\n  WriteLn('Se han impreso ', NumerosImpresos, ' nmeros');\n  ReadLn;\nend.\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/ejercicio.md",
    "content": "# #02 FUNCIONES Y ALCANCE\n> #### Dificultad: Fácil | Publicación: 08/01/24 | Corrección: 15/01/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/erlang/edalmava.erl",
    "content": "% La información contenida en este archivo se obtuvo del libro\n% Erlang/OTP Volumen I 3a Edición de Manuel Ángel Rubio Jiménez\n%\n% El código de erlang se organiza en módulos y dentro de cada módulo se \n%  pueden encontrar funciones.  Un módulo se define en un fichero a través \n%  de unas instrucciones de preprocesador iniciales que permiten definir \n%  el nombre y las funciones que se quieren exportar(para emplear fuera del módulo).\n%  En un módulo se pueden importar y exportar funciones.\n%  La declaración export es una lista de las referencias a funciones que \n%  se deseen publicar y la declaración import es una lista de funciones que se \n%  importan desde otro módulo\n%\n% Las funciones en Erlang siguen la estructura:\n%     function_name([Param1, [Param2, [...]]]) [guardas] ->\n%         código.  \n% \n% El nombre de la función debe ser un átomo válido.\n% El bloque de código dentro de la función es un conjunto de expresiones\n%  separadas por comas y finaliza con un punto.\n% La última expresión evaluada será la responsable de dar el valor de \n%  retorno a la función.\n% Las funciones de Erlang disponen de Polimorfismo y concordancia.  Así que se pueden definir\n%  funciones con el mismo nombre pero con distinto número de parámetros.\n\n-module(edalmava).\n-export([imprimir/0, imprimir/1, area/2, area/3, get/1]).\n% -compile([export_all]). % Para exportar todas las funciones del módulo.  No es recomendable hacer esto\n-import(proplists, [get_value/2]).\n\n% Sin parámetros\nimprimir() ->\n    \"Hola Mundo\".\n% Con parámetros\nimprimir(Mensaje) ->\n    io:format(Mensaje).\n\n% Se pueden tener funciones con el mismo nombre y número de parámetros pero con diferente comportamiento\narea(cuadrado, Base) ->\n Base * Base;\narea(circulo, Radio) ->\n math:pi() * Radio * Radio.\n\narea(rectangulo, Base, Altura) ->\n Base * Altura;\narea(triangulo, Base, Altura) ->\n Base * Altura / 2.\n% Para usarlas se emplea\n% edalmava:area(circulo, 10) para un círculo\n% edalmava:area(cuadrado, 10) para un cuadrado\n% edalmava:area(rectangulo, 10, 10) para un rectángulo\n% edalmava:area(triangulo, 10, 10) para un triángulo\n\n% Uso de funciones importadas de módulos del lenguaje\n% La función data es privada no se puede invocar desde afuera\ndata() ->\n    [{\"hi\", \"hola\"}, {\"bye\", \"adios\"}].\n% La función get es pública se puede invocar desde afuera del módulo\nget(Key) ->\n    get_value(Key, data()). % Función get_value de la libreria o módulo proplists. En este caso se uso import (No recomendable)\n\n% Ejemplo de uso:\n% edalmava:get(\"hi\") retorna \"hola\"\n% edalmava:data() retorna un error \n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/fortran/LeandroCFD.f90",
    "content": "program FUNCIONES\n    implicit none\n\n    !Se declaran las variables a utilizar en el programa\n    integer   :: i,ia,ib,ic\n    real      :: r,ra,rb,rc\n    character (len=50):: t,ta,tb\n\n    print*,''\n    print*,'*********************'\n    print*,'FUNCIONES INTRINSECAS'\n    print*,'*********************'\n    print*,''\n    \n    !En Fortran existen funciones intrinsecas y funciones construidas por el usuario.\n    !FUNCIONES INTRINSECAS\n    i=abs(-1)  !Función abs, calcula el valor absoluto de una número, esta función admite variables de tipo integer, real y complex\n    r=sqrt(40.1) !Función sqrt, calcula la raiz cuadrada de un valor.\n    ia=int(r) !Función int, calcula parte entera de un número real.\n    ra=fraction(r) !Función fraction, calcula la parte fraccional de un número real.\n    rb=log(5.1) !Función log, calcula el logaritmo natural (neperiano) de un número.\n    print*,i,r,ia,ra,rb\n\n    print*,''\n    print*,'*********************'\n    print*,'FUNCIONES POR USUARIO'\n    print*,'*********************'\n    print*,''\n    \n    !Las funciones construidas por el usuario se deben llamar antes de declararlas\n    t=Primera_funcion() !Llamado de la Primera función\n    ib=Segunda_funcion(i) !Llamado de la Segunda función\n    r=Tercera_funcion(ra,rb)\n    print*,r\n    ra=Cuarta_funcion(r,rb)\n    print*,ra\n    rc=Quinta_funcion(ra,r)\n    print*,rc,r !En este caso el valor de r fue modificado dentro de la función.\n    rc=Sexta_funcion(r,ra)\n    print*,rc,ra\n    ic=factorial(ia)\n    print*,\"El factorial de \",ia, \"es:\",ic\n\n\n    print*,''\n    print*,'**********'\n    print*,'SUBRUTINAS'\n    print*,'**********'\n    print*,''\n\n    !Las subrutinas se deben llamar con la sentencia call\n    call Primera_subrutina(rc,ra)\n\n    !Tanto las funciones como las subrutinas pueden ser internas (dentro del programa principal, como en este caso) o pueden\n    !ser externas, en el momento que sean externas estas deben compilarse al mismo tiempo con el programa principal.\n\n    print*,''\n    print*,'****************'\n    print*,'DIFICULTAD EXTRA'\n    print*,'****************'\n    print*,''\n    ta=\"Multiplo de 3\"\n    tb=\"Multiplo de 5\"\n    i=multiplos(ta,tb)\n    print*,\"El número de números entre 1 y 100 que no son multiplos ni 3 ni de 5 son:\",i\n    \n    !FUNCIONES CONSTRUIDAS POR EL USUARIO\n    !Las funciones en Fortran se deben definir de la siguiente manera.\n    contains  !Se debe utilizar la sentencia \"Contains\" para separar una función o una subrutina del programa principal.\n    !Esto se debe realizar al final del programa.\n        character function Primera_funcion () !Función de tipo character que no tiene argumentos.\n            Primera_funcion=\"H\"\n            print*,\"Esta función retorna la letra 'H'\"\n        end function Primera_funcion\n\n        integer function Segunda_funcion (x)  !Función de tipo integer que tiene un argumento pero no retorno.\n            integer,intent(in) :: x  !Se declara una variable de tipo integer (argumento de la función), la cual se puede utilizar\n            !dentro de la función pero no se puede modificar.\n            Segunda_funcion=x\n            print*,\"Esta función retorna el número x:\",Segunda_funcion\n        end function Segunda_funcion\n\n        function Tercera_funcion (xa,xb) !Función que no se le asigna ningún tipo y que tiene dos argumentos y un retorno.\n            real, intent(in) :: xa,xb\n            real :: Tercera_funcion\n            Tercera_funcion=xa+xb          \n        end function Tercera_funcion\n\n        function Cuarta_funcion(xc,xd) result(re) !Si se desea que el retorno tenga otro nombre diferente al de la función, se\n            !se utiliza la sentencia result.\n            real, intent(in) :: xc,xd\n            real :: re           \n            re=xc+xd             \n        end function Cuarta_funcion\n\n        function Quinta_funcion(xe,xf) result(re1)\n            real, intent(in) :: xe\n            real, intent(inout) :: xf  !Se declara una variable de tipo real (argumento de la función), la cual se puede utilizar \n            !dentro de la función, se puede modificar y puede ser asimilada como salida de la función.\n            real :: re1\n            xf=5.0           \n            re1=xe+xf        \n        end function Quinta_funcion\n\n        function Sexta_funcion(xg,xh) result(re2)\n            real, intent(in) :: xg\n            real, intent(out) :: xh  !Se declara una variable de tipo real (argumento de la función), la cual se puede utilizar \n            !dentro de la función pero el valor con el que venia no se tiene en cuenta, se puede modificar y puede ser asimilada\n            !como salida de la función.\n            real :: re2\n            xh=6.1\n            re2=xg+xh        \n        end function Sexta_funcion\n\n        recursive function factorial(n) result(re3) !Se pueden crear funciones recursivas, es decir que se llaman a si mismas \n        !utilizando la sentencia recursive, en esta función se calcula el factorial de un variable de tipo integer.\n            integer, intent(in) :: n\n            integer :: re3\n            if(n==0)then\n                re3=1\n            else\n                re3=n*factorial(n-1)\n            end if\n        end function factorial\n\n        function multiplos(t1,t2) result(num)\n            character (len=50), intent(in) :: t1,t2\n            integer :: num,n\n            num=0\n            do  n= 1,100\n                if (mod(n,3)==0 .and. mod(n,5)==0) then\n                    print*,n,trim(t1)//\" y \"//trim(t2)\n                else if (mod(n,3)==0) then\n                    print*,n,t1\n                else if (mod(n,5)==0) then\n                    print*,n,t2\n                else\n                    print*,n\n                    num=num+1                   \n                end if                \n            end do\n        end function multiplos\n\n        !SUBRUTINAS\n        !Fortran permite utilizar subrutinas. La sintaxis es la siguiente. Las subrutinas no necesariamente deben devolver un valor\n        !simplemente pueden hacer un procedimiento sin ningún retorno.\n        subroutine Primera_subrutina(xi,xj)\n            real, intent(in) :: xi\n            real, intent(out) ::  xj\n            print*,\"Esta subrutina solo imprime un mensaje en consola mostrando los valores de sus argumentos:\",xi,xj\n        end subroutine Primera_subrutina\n        \nend program FUNCIONES"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/fortran/edalmava.f90",
    "content": "program funciones\n    implicit none\n    ! En Fortran las funciones siguen la siguiente sintaxis:\n    !     tipo function nombre_funcion (arg1, arg2, argN)\n    !         declaracion argumento 1\n    !         declaracion argumento 2\n    !         ...\n    !         declaracion argumento N\n    !         \n    !         sentencia 1\n    !         sentencia 2\n    !         ...\n    !         sentencia N\n    !    end function\n    ! Es posible tener funciones con 0 o más argumentos\n    ! Las funciones devuelven un valor\n\n    ! Los Procedimientos o Subrutinas retornan varios o ningún valor\n    ! La sintaxis de una subrutina es:\n    ! subroutine nombre_subrutina (arg1, ..., argN)\n    ! inicio\n    !     declaración arg1\n    !     ...\n    !     declaración argN\n    !     sentencia1\n    !     sentencia2\n    !     ...\n    !     sentenciaN\n    ! fin\n\n    ! Forma de invocar las subrutinas\n    integer x, y, numero\n    \n    call asteriscos(5)\n\n    x = 0; y = 1;\n\n    print *, x, y\n    call intercambio(x, y)\n    print *, x, y\n\n    ! Uso de funciones intrínsecas o estándar\n    print *, 'La raíz cuadrada de 100 es ', SQRT(100.0)\n    \n    print *, siempreVerdad()\n    print *, 'El máximo de 4 y 5 es: ', maximo(4,5)\n\n    ! Llamada a función del ejercicio EXTRA\n    numero = imprimirNumeros('Hola', 'Mundo')\n    print *, 'Número de veces que fue impreso un número: ', numero\n\n    ! La definición de funciones se debe hacer en una sección contains al final del programa\n    contains\n\n    ! Función sin argumentos que siempre retorna el valor lógico verdadero:\n    logical function siempreVerdad ()\n        siempreVerdad = .true.\n    end function\n\n    ! Función que recibe dos enteros y retorna el mayor de los dos:\n    integer function maximo (a, b)\n        integer a,b\n        if (a>b) then\n            maximo = a\n        else\n            maximo = b\n        end if\n    end function\n\n    integer function imprimirNumeros (cadena1, cadena2)        \n        integer i, contar\n        character(len = 4) cadena1\n        character(len = 5) cadena2\n\n        contar = 0\n        do i = 1, 100\n            if (MOD(i, 3) == 0 .and. MOD(i, 5) == 0) then\n                print *, cadena1 // cadena2\n            else if (MOD(i, 3) == 0) then\n                print *, cadena1\n            else if (MOD(i, 5) == 0) then\n                print *, cadena2\n            else \n                print *, i\n                contar = contar + 1\n            end if                \n        end do\n        imprimirNumeros = contar\n    end function\n\n    subroutine asteriscos (n)\n        implicit none\n        integer n\n        integer i\n        do i = 1, n\n            print *, '*'\n        end do\n    end subroutine\n\n    subroutine intercambio (a,b)\n        implicit none\n        integer a,b\n        integer temporal\n        temporal = a\n        a = b\n        b = temporal\n    end subroutine   \n     \nend program funciones"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/gdscript/ElHacedorDeCosas.gd",
    "content": "#Funciones\n\n#en GDscript todo script tiene que estar asociado a una escena o nodo para poder ejecutarlo\n\n#Funciones basicas\nextends Node\n#la función _ready es una especial de GDScript que hace que la función se ejecute al momento de iniciar la ecena de forma automatica\n#y solo puede ser usada una vez por script\nfunc _ready(): #voy a utilizar esta función para llamar a todas las que haga a partir de ahora en este ejercicio\n    #Simple\n    simple()\n    #Con retorno\n    con_retorno()\n    resultado()\n    #Con argumento \n    con_argumento(\"Hola\", \"tito\")\n    #Con argumento predeterminado\n    con_argumento_predeterminado(67, 10)\n    #Variables globales y locales\n    global_print()\n    local_print()\n    #Extra\n    ejercicio_extra(\"papa\",\"boniato\")\n\n#Simple\nfunc simple() -> void:\n    print(4 + 2)\n\n#Con retorno\nvar a = 3\nvar b = 7\nfunc con_retorno() -> int:\n    return a + b\nfunc resultado() -> void:\n    var resultados = con_retorno()\n    print(resultados)\n\n#Con argumento\nfunc con_argumento(primero : String, segundo : String) -> void:\n    print(primero + \" \" + segundo)\n\n#Con argumento predeterminado\nfunc con_argumento_predeterminado(c :int =3 , d :int =4) -> void:\n    print(c + d)\n\n#Variables globales y locales\n#global\nvar variable_global = \"Timo\"\nfunc global_print() -> void:\n    print(variable_global)\n#local\nfunc local_print() -> void:\n    var variable_local = \"123456\"\n    print(variable_local)\n\n\n#Extra\n\nfunc ejercicio_extra(texto1, texto2) -> int:\n    var numero_de_impresiones = 0\n    for numero in range(1, 101):\n        if numero % 3 == 0 and numero % 5 == 0:\n            print(texto1 + texto2)\n        elif numero % 3 == 0:\n            print(texto1)\n        elif numero % 5 == 0:\n            print(texto2)\n        else:\n            print(numero)\n            numero_de_impresiones += 1\n    print(numero_de_impresiones)\n    return numero_de_impresiones"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/go/Aldroide.go",
    "content": "/*\n\t\tEjercicio\n\t\tCrea ejemplos de funciones básicas que representen las diferentes\n\t    posibilidades del lenguaje:\n\t    Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n\t\tComprueba si puedes crear funciones dentro de funciones.\n\t\tUtiliza algún ejemplo de funciones ya creadas en el lenguaje.\n\t\tPon a prueba el concepto de variable LOCAL y GLOBAL.\n\t\tDebes hacer print por consola del resultado de todos los ejemplos.\n\t    (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n*/\npackage main\n\nimport \"fmt\"\n\nfunc main(){\n\tgreetUser1()\n\tgreetUser2(\"Aldo\")\n\tfmt.Printf(\"%v,\\n\",greetUser3(\"Emmanuel\"))\n\tfmt.Println(operations(3,4))\n\textra(\"Fizz\",\"Buzz\")\n}\n\nfunc greetUser1(){\n\tfmt.Println(\"Welcome to this language\")\n}\n\nfunc greetUser2(name string){\n\tfmt.Printf(\"Hola, %v \\n\", name)\n}\n\nfunc greetUser3(name string)(string){\n\treturn \"Hola \"+ name\n}\n\nfunc operations(a, b int)(int,int){\n\tadd := func()int{\n\t\treturn a+b\n\t}\n\tsub := func()int{\n\t\treturn a-b\n\t}\n\treturn add(), sub()\n}\n\nfunc extra(param1, param2 string)int{\n\tvar numImpreso = 0\n\tfor i:=1; i<101; i++{\n\t\tif i%5==0{\n\t\t\tfmt.Println(param1,param2)\n\t\t} else if i%3==0{\n\t\t\tfmt.Println(param1)\n\t\t}else if i%5 ==0{\n\t\t\tfmt.Println(param2)\n\t\t}else{\n\t\t\tfmt.Println(i)\n\t\t\tnumImpreso++\n\t\t}\n\t}\n\treturn numImpreso\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/go/AmadorQuispe.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"math\"\n\t\"strconv\"\n\t\"strings\"\n)\n\nvar user = \"Amador\" //Esto es una variable global\n\n/*EXTRA*/\nfunc fizzBuzz(s1, s2 string) int {\n\tvar count int\n\tfor i := 1; i <= 100; i++ {\n\t\tif i%3 == 0 && i%5 == 0 {\n\t\t\tfmt.Println(i, s1, s2)\n\t\t} else if i%3 == 0 {\n\t\t\tfmt.Println(i, s1)\n\t\t} else if i%5 == 0 {\n\t\t\tfmt.Println(i, s2)\n\t\t} else {\n\t\t\tfmt.Println(i)\n\t\t\tcount++\n\t\t}\n\t}\n\treturn count\n}\n\nfunc main() {\n\tfmt.Println(\"(variable global) Hola !👋\", user)\n\tfmt.Println(\"Se ha impreso número: \", fizzBuzz(\"fizz\", \"buzz\"), \"veces\")\n\twelcomeSystem()\n\tprintMessage(\"El sistema puede hacer estos trabajos\")\n\tprintMessage(\"[A] Operación simple (+,-,* y / de dos números) \")\n\tprintMessage(\"[B] Operación multiple (+, - y * de varios números) \")\n\tprintMessage(\"[C] Factorial de un número\")\n\tfmt.Print(\"Ingresa la opción :\")\n\tvar option string\n\tfmt.Scanf(\"%s\", &option)\n\tprintMessage(\"La opción que seleccionaste es \" + option)\n\n\tif option == \"A\" {\n\t\tprintMessage(\"Dentro de las operaciones simples tenemos :\")\n\t\tprintMessage(\"(1) Suma\")\n\t\tprintMessage(\"(2) Resta\")\n\t\tprintMessage(\"(3) Multiplicación\")\n\t\tprintMessage(\"(4) División\")\n\t\tprintMessage(\"(5) Potencia\")\n\t\tfmt.Print(\"Ingrese el número de la operación :\")\n\t\tvar opSelect string\n\t\tvar num1, num2 float64\n\t\tfmt.Scan(&opSelect)\n\t\tprintMessage(\"Haz seleccionado \" + operationSelected(opSelect) + \", ahora ingresa los números.\")\n\t\tfmt.Print(\"Ingrese el número 1 :\")\n\t\tfmt.Scan(&num1)\n\t\tfmt.Print(\"Ingrese el número 2 :\")\n\t\tfmt.Scan(&num2)\n\t\tresult := operation(opSelect, num1, num2)\n\t\tprintMessage(\"El resultado de la operación \" + operationSelected(opSelect) + \" :\")\n\t\tfmt.Printf(\"%v y %v es %v \\n\", num1, num2, result)\n\t} else if option == \"B\" {\n\t\tprintMessage(\"Dentro de las operaciones multiples tenemos :\")\n\t\tprintMessage(\"(1) Suma\")\n\t\tprintMessage(\"(2) Resta\")\n\t\tprintMessage(\"(3) Multiplicación\")\n\t\tfmt.Print(\"Ingrese el número de la operación :\")\n\t\tvar opSelect string\n\t\tvar input string\n\t\tfmt.Scan(&opSelect)\n\t\tprintMessage(\"Haz seleccionado \" + operationSelected(opSelect) + \", ahora ingresa los números.\")\n\t\tfmt.Print(\"Ingresa los números separado por una coma (,) ejemplo 1,2,3 : \")\n\t\tfmt.Scan(&input)\n\t\tnumbers := stringToSlice(input)\n\t\tresult := operationsMultipleNumbers(opSelect, numbers...)\n\t\tprintMessage(\"El resultado de la operación \" + operationSelected(opSelect) + \" :\")\n\t\tfmt.Println(\"\"+input+\" es: \", result)\n\t} else if option == \"C\" {\n\t\tprintMessage(\"Factorial de un número :\")\n\t\tfmt.Print(\"Ingresa un número positivo :\")\n\t\tvar number int = 5\n\t\tfmt.Scan(&number)\n\t\tresult := factorial(number)\n\t\tfmt.Println(\"El factorial de \", number, \" es \", result)\n\t} else {\n\t\tprintMessage(\"La opción que seleccionaste no existe\")\n\t}\n\n\tvar msg = exitSystem()\n\tfmt.Println(msg)\n\n\t//En go se puede asignar una función a una variable\n\tvar fn = greeting\n\tfn(\"Amador\")\n\n\t//Función anónima\n\tfn1 := func() {\n\t\tfmt.Println(\"Hello\")\n\t}\n\tfn1()\n\n}\n\n/*Función sin parámetro ni retorno.*/\nfunc welcomeSystem() {\n\tfmt.Println(\"------------------------------\")\n\tfmt.Println(\"----Bienvenido al sistema-----\")\n\tfmt.Println(\"------------------------------\")\n}\n\n/*Función que recibe un parámetro pero no retorna ningún valor.*/\nfunc printMessage(message string) {\n\tfmt.Println(message)\n}\n\n/*Función sin parámetro y con retorno.*/\nfunc exitSystem() string {\n\treturn \"Gracias por usar el sistema regresa pronto.\"\n}\n\n/* Función que recibe un parámetro y retorna un valor.*/\nfunc operationSelected(input string) string {\n\tvar operation string\n\tswitch input {\n\tcase \"1\":\n\t\toperation = \"(1) Suma\"\n\tcase \"2\":\n\t\toperation = \"(2) Resta\"\n\tcase \"3\":\n\t\toperation = \"(3) Multiplicación\"\n\tcase \"4\":\n\t\toperation = \"(4) División\"\n\tcase \"5\":\n\t\toperation = \"(5) Potencia\"\n\n\tdefault:\n\t\toperation = \"No soportado\"\n\t}\n\treturn operation\n}\n\n/*Función que recibe varios parámetros y retorna un valor.*/\nfunc operation(operator string, number1, number2 float64) float64 {\n\tswitch operator {\n\tcase \"1\":\n\t\treturn number1 + number2\n\tcase \"2\":\n\t\treturn number1 - number2\n\tcase \"3\":\n\t\treturn number1 * number2\n\tcase \"4\":\n\t\treturn number1 / number2\n\tcase \"5\":\n\t\t// Aquí usamos una función propio del lenguaje\n\t\treturn math.Pow(number1, number2)\n\n\tdefault:\n\t\treturn 0\n\t}\n}\n\n/*Función que recibe varios parámetros (incluido rest parameter) y retorna un valor.*/\nfunc operationsMultipleNumbers(operator string, numbers ...float64) float64 {\n\tvar accumulator float64\n\tswitch operator {\n\tcase \"1\":\n\t\tfor _, v := range numbers {\n\t\t\taccumulator += v\n\t\t}\n\tcase \"2\":\n\t\tfor _, v := range numbers {\n\t\t\taccumulator -= v\n\t\t}\n\tcase \"3\":\n\t\tfor _, v := range numbers {\n\t\t\taccumulator *= v\n\t\t}\n\tdefault:\n\t\taccumulator = 0\n\n\t}\n\treturn accumulator\n}\n\nfunc factorial(num int) int {\n\tif num <= 1 {\n\t\treturn 1\n\t}\n\treturn num * factorial(num-1)\n}\n\nfunc stringToSlice(s string) []float64 {\n\tvar numbers []float64\n\tstringSplit := strings.Split(s, \",\")\n\n\tfor _, v := range stringSplit {\n\t\tif fv, err := strconv.ParseFloat(v, 64); err == nil {\n\t\t\tnumbers = append(numbers, fv)\n\t\t}\n\t}\n\treturn numbers\n}\n\nfunc greeting(name string) {\n\tfmt.Println(name)\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/go/FreyFonseca117.go",
    "content": "// # #02 FUNCIONES Y ALCANCE\n// > #### Dificultad: Fácil | Publicación: 08/01/24 | Corrección: 15/01/24\n\n// ## Ejercicio\n\n// ```\n// /*\n//  * EJERCICIO:\n//  * - Crea ejemplos de funciones básicas que representen las diferentes\n//  *   posibilidades del lenguaje:\n//  *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n//  * - Comprueba si puedes crear funciones dentro de funciones.\n//  * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n//  * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n//  * - Debes hacer print por consola del resultado de todos los ejemplos.\n//  *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n//  *\n//  * DIFICULTAD EXTRA (opcional):\n//  * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n//  * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n//  *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n//  *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n//  *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n//  *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n//  *\n//  * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n//  * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n//  */\n// ```\n// #### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\n// Sigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n// > Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n\npackage main\n\nimport \"fmt\"\n\n// Variables universales\nvar nombre string = \"frey\"\nvar apellido string = \"fonseca\"\nvar ciudad string = \"santiago\"\n\n// funcion con parametro\nfunc saludar(nombre string) {\n\tfmt.Println(\"esta funcion recibe un parametro string el cual es:\", nombre)\n}\n\n// funcion con varios parametros\nfunc variosParametros(a, b, c string) string {\n\tresultado := fmt.Sprintf(\"hola mi nombre es %s %s y vivo en %s\", a, b, c)\n\tfmt.Println(resultado)\n\treturn resultado\n\n}\n\n// Uso de funciones estándar del lenguaje\nfunc usarFuncionesNativas() {\n\tlongitud := len(\"Hola, mundo\")\n\tfmt.Println(\"Longitud de la cadena:\", longitud)\n}\n\n// Ejercicio extra\n\nfunc problemaFizzBuzz(string1, string2 string) int {\n\tcontador := 0\n\tfor i := 1; i <= 100; i++ {\n\t\tif i%3 == 0 && i%5 == 0 {\n\t\t\tfmt.Println(string1 + string2)\n\t\t} else if i%3 == 0 {\n\t\t\tfmt.Println(string1)\n\t\t} else if i%5 == 0 {\n\t\t\tfmt.Println(string2)\n\t\t} else {\n\t\t\tfmt.Println(i)\n\t\t\tcontador++\n\t\t}\n\t}\n\treturn contador\n}\n\nfunc main() {\n\tsaludar(nombre)\n\tvariosParametros(nombre, apellido, ciudad)\n\tusarFuncionesNativas()\n\tcontador := problemaFizzBuzz(\"fizz\", \"buzz\")\n\tfmt.Println(\"El contador es:\", contador)\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/go/MiguelP-Dev.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\nfunc main() {\n\tsaludoMundo()\n\tfmt.Println(\"Suma: \", suma(2, 2))\n\tholaGophers(\"Miguel\", \"Portillo\")\n\tvalor := \"Minuscula\"\n\ttoUpper(&valor)\n\tfmt.Println(valor)\n\n\tupper, lower := convert(\"MiGuEl\")\n\tfmt.Println(\"Mayúsculas\", upper, \"Minúsculas\", lower)\n\n\tupper2, lower2 := convert2(\"PoRtIlLo\")\n\tfmt.Println(\"Mayúsculas\", upper2, \"Minúsculas\", lower2)\n\n\t// nums Slice de números.\n\tnums := []int{1, 2, 40, 66, 34, 33, 663}\n\tfilter(nums, func(num int) bool {\n\t\treturn num > 20\n\t})\n\n\tfmt.Println(\"La suma es:\", sum(1, 2, 34, 5, 6, 77, 65, 44, 44))\n\tfmt.Println(\"La suma del slice es:\", sum(nums...))\n\n\tresult := super(na)(nb)\n\tfmt.Println(result)\n\n\tfmt.Println(fizzBuzz(\"fizz\", \"buzz\"))\n}\n\n/*\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n */\n\n/*\nEn Golang el nombramiento de las funciones se hace en base a la convención del leguaje mismo:\nLas funciones se nombran comenzando por minusculas para que sean propias solo del paquete,\npero si por el contrario son funciones que se van a exportar fuera del paquete, estas comienzan por mayúsculas,\ncomo por ejemplos las funciones del paquete Format(fmt).\n*/\n\n// holaMundo Función simple (Sin parametros ni retorno)\nfunc saludoMundo() {\n\tfmt.Println(\"Hola mundo\")\n}\n\n// holaGophers Funcion de saludo con paramentros.\nfunc holaGophers(firstname string, lastname string) {\n\tfmt.Println(\"Hola Gopher \", firstname, lastname)\n}\n\n// Se pueden usar las funciones para manipular datos pero esto solo haciendolo mediante referencias:\n// toUpper función con parametros por valor y referencia.\nfunc toUpper(text *string) {\n\t*text = strings.ToUpper(*text)\n}\n\n// suma Función que recibe enteros y devuelve enteros,\n// La lista de parámetros define los datos que acepta una funcion y los tipos de datos,\n// Los parámetros son un tipo de variable especial usada para pasar datos a una función.\nfunc suma(a, b int) int {\n\treturn a + b\n}\n\n// Las Funciones pueden devolver multiples valores; estos deben ir entre parentesis:\nfunc convert(text string) (string, string) {\n\tupper := strings.ToUpper(text)\n\tlower := strings.ToLower(text)\n\treturn upper, lower\n}\n\nfunc convert2(text string) (upper string, lower string) {\n\tupper = strings.ToUpper(text)\n\tlower = strings.ToLower(text)\n\treturn upper, lower\n}\n\n// Nota: Al igual que se nombran y tipan los paramentros, también se puede hacer con los retornos\n// Aunque esto es solo recomendable con las funciones muy pequeñas y que no crecerán.\n\n/*\nFunciones que reciben y retornan funciones.\nLas funciones en golang también son un tipo de dato, por lo que puedo pasarlas a otras funciones como parametros\ny recibirlas como retorno\n*/\n\n// filter: Esta función recibe como parametros: nums y la función callback, que tiene como parametro un entero\n// y devuelve un booleano, la funcion filter tiene como retorno un slice de enteros que seŕia el\n// resultrado de filtrar los valores del Slice en main, llamado nums.\n\nfunc filter(nums []int, callback func(int) bool) []int {\n\tresult := make([]int, 0, len(nums))\n\n\tfor _, num := range nums {\n\t\tif callback(num) {\n\t\t\tresult = append(result, num)\n\t\t}\n\t}\n\treturn result\n}\n\n// sum Funcion variádicas: estas funciones se usan sobre todo cuando no estasmos seguros de la cantidad\n// de parametros que pasaremos. Por ejemplo algunos de los casos de uso más comúnes de estas funciones:\n// Concatenación de cadenas como los paquetes fmt.Sprintf y strings.Join.\n// Procesamiento de matrices y Slices, registro de manejos de errores como la funciomn log.Printf y\n// funciones auxiliares utilisadas en APIS y Bibliotecas.\n\nfunc sum(nums ...int) int {\n\ttotal := 0\n\tfor _, num := range nums {\n\t\ttotal += num\n\t}\n\treturn total\n}\n\n// super: es una función que recibe un parametro A, retorna una función que recibe un entero y retorna un entero.\nfunc super(a int) func(int) int {\n\treturn func(b int) int {\n\t\treturn a + b\n\t}\n}\n\n// nota: las variables globales se declaran fuera de la función main.\n// Estas variables no se pueden declarar usando el operador de variable corta(:=).\nvar na = 23\nvar nb int = 12\n\n// Extra\nfunc fizzBuzz(word1, word2 string) int {\n\tcount := 0 // Variable local (solo existe dentro de la función fizzBuzz)\n\tfor i := 1; i < 101; i++ {\n\t\tif i%15 == 0 {\n\t\t\tfmt.Println(word1 + word2)\n\t\t} else if i%3 == 0 {\n\t\t\tfmt.Println(word1)\n\t\t} else if i%5 == 0 {\n\t\t\tfmt.Println(word2)\n\t\t} else {\n\t\t\tfmt.Println(i)\n\t\t\tcount += 1\n\t\t}\n\t}\n\treturn count\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/go/edalmava.go",
    "content": "package main\n\nimport \"fmt\"\n\n// Una función puede tomar cero o más argumentos y devolver cero o más valores.\nfunc add(x int, y int) int {\n\treturn x + y\n}\n\n// Función que no devolverá ningún valor\nfunc printMessage(message string) {\n\tfmt.Println(message)\n}\n\n// Cuando dos o más parámetros de función con nombre consecutivos comparten el\n// mismo tipo, se puede omitir el tipo de todos menos del último\nfunc add2(x, y int) int {\n\treturn x + y\n}\n\n// Múltiples argumentos de retorno\nfunc swap(x, y int) (int, int) {\n\treturn y, x\n}\n\n// Valores de retorno nombrados\nfunc split(sum int) (x, y int) {\n\tx = sum * 4 / 9\n\ty = sum - x\n\treturn // devuelve x, y\n}\nfunc calcular(a, b int) (suma int, producto int) {\n\tsuma = a + b\n\tproducto = a * b\n\treturn\n}\n\n// Función que devuelve varios valores.  En este caso un error y un float64\n// Esta funcionalidad es particularmente útil para devolver un valor principal y un error, lo cual es un patrón común en Go.\nfunc dividir(dividendo, divisor float64) (float64, error) {\n\tif divisor == 0 {\n\t\treturn 0, fmt.Errorf(\"división por cero\")\n\t}\n\treturn dividendo / divisor, nil\n}\n\n// Declaración corta de variable\n// La declaración corta de variable := se puede usar para declarar y asignar\n// variables dentro de una función. La declaración corta de variable no se puede\n// usar en el ámbito de la función principal, ya que no se puede declarar una\n// variable sin un tipo explícito. En su lugar, se puede usar la declaración\n// larga var nombre tipo = valor.\n\nfunc main() {\n\t// Declaración de función anónima\n\trestar := func(x, y int) int {\n\t\treturn x - y\n\t}\n\n\tfmt.Println(restar(5, 3)) // 2\n\n\tprintMessage(\"Hola, mundo!\") // Hola, mundo!\n\n\tfmt.Println(add(1, 2))  // 3\n\tfmt.Println(add2(1, 2)) // 3\n\ta, b := swap(1, 2)\n\tfmt.Println(a, b)      // 2 1\n\tfmt.Println(split(17)) // 7 10\n\n\tresultado, err := dividir(10, 0)\n\tif err != nil {\n\t\tfmt.Println(\"Error:\", err)\n\t} else {\n\t\tfmt.Println(\"Resultado:\", resultado)\n\t}\n\n\tsuma, producto := calcular(3, 4)\n\tfmt.Println(\"Suma:\", suma, \"Producto:\", producto) // Suma: 7 Producto: 12\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/go/gabrielmoris.go",
    "content": "/*\n * EXERCISE:\n * - Create examples of basic functions that represent the different\n *   possibilities of the language:\n *   Without parameters or return, with one or more parameters, with return...\n * - Check if you can create functions within functions.\n * - Use some examples of functions already created in the language.\n * - Test the concept of LOCAL and GLOBAL variables.\n * - You must print the result of all examples to the console.\n *   (and keep in mind that each language may have more or fewer possibilities)\n *\n * EXTRA DIFFICULTY (optional):\n * Create a function that receives two parameters of string type and returns a number.\n * - The function prints all numbers from 1 to 100. Taking into account that:\n *   - If the number is a multiple of 3, it shows the text string of the first parameter.\n *   - If the number is a multiple of 5, it shows the text string of the second parameter.\n *   - If the number is a multiple of 3 and 5, it shows both text strings concatenated.\n *   - The function returns the number of times the number has been printed instead of the texts.\n *\n * Pay special attention to the syntax you should use in each of the cases.\n * Each language follows conventions that you must respect for the code to be understood.\n */\n\npackage main\n\nimport \"fmt\"\n  var globalvar = \"I am global because I am outside any function or block.\"\n  func main() {\n\t var localVar =\"I am local because I am inside a function\";\n\t fmt.Println(localVar);\n\t fmt.Println(noParams()); // No params\n\t fmt.Println(withParams(1,2)) // 3\n\t var number = 1;\n\t notReturn(&number);\n\t fmt.Println(number);  // 2\n\t b(a); // string\n\t recursive(&number,10);\n \n\t // Anonymous Functions\n\t anonFunc := func() {\n\t\t fmt.Println(\"I am an anonymous function\")\n\t }\n\t anonFunc();\n \n\t // Clousures\n\t counter := 0\n\t increment := func() int {\n\t\t counter++\n\t\t return counter\n\t }\n\t fmt.Println(increment()) // 1\n\t fmt.Println(increment()) // 2\n\t fmt.Println(sum(1,2,3,4,5)) //15\n\t challenge(\"fizz\",\"buzz\");\n  }\n \n  // Without Params\n  func noParams() string {\n\t return \"No Params\";\n  }\n \n  // With Params\n  func withParams(num1 int, num2 int) int{\n\t return num1 + num2;\n  }\n \n  // Function modifying external variable\n  func notReturn(num *int){\n\t *num += 1;\n  }\n \n  // High order Functions\n  func a () string {\n\t return \"I am func A\"\n  }\n \n  func b (function func() string) {\n\t fmt.Println(\"I am in func B and I an calling this fn: \" + function());\n  }\n \n  // Recursive Function\n  func recursive (num *int , max int){\n\t if *num <= max {\n\t\t fmt.Println(\"This is recutsive: \")\n\t\t fmt.Println(*num)\n\t\t *num++\n\t\t recursive(num, max)\n\t }\n  }\n \n  // Variable number of arguments\n  func sum(nums ...int) int {\n\t total := 0\n\t for _, num := range nums {\n\t\t total += num\n\t }\n\t return total\n }\n \n func challenge(str1 string, str2 string){\n\t for i:=0; i<100; i++{\n\t\t if(i %3 ==0 && i%5==0){\n\t\t\t fmt.Println(str1 +  \" \"+ str2)\n\t\t } else if(i % 3==0){\n\t\t\t fmt.Println(str1)\n\t\t } else if(i % 5==0){\n\t\t\t fmt.Println(str2)\n\t\t }\n \n\t }\n \n }"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/go/hozlucas28.go",
    "content": "package main\n\nimport \"fmt\"\n\n/*\n   Types of functions (1)...\n*/\n\n// Common function\nfunc commonFn() {\n\tfmt.Print(\"\\nCommon function: func <FUNCTION NAME>(<PARAMETERS...>) {<INTRUCTIONS...>}\")\n}\n\n// With parameter\nfunc fnWithParameter(name string) {\n\tfmt.Printf(\"\\nCommon function (with parameter): func <FUNCTION NAME>(name string) {<INTRUCTIONS...>} --> Hello %s!\", name)\n}\n\n// With pointer parameter\nfunc fnWithPointerParameter(lastName *string) {\n\tfmt.Printf(\"\\nCommon function (with pointer parameter): func <FUNCTION NAME>(lastName *string) {<INTRUCTIONS...>} --> Hello %s!\", *lastName)\n}\n\n// Without parameter\nfunc fnWithoutParameter() {\n\tfmt.Print(\"\\nCommon function (without parameter): func <FUNCTION NAME>() {<INTRUCTIONS...>} --> Hello!\")\n}\n\n// With rest parameter\nfunc fnWithRestParameter(numbers ...int) {\n\tfmt.Printf(\"\\nCommon function (with rest parameter): func <FUNCTION NAME>(numbers ...int) {<INTRUCTIONS...>} --> %d!\", numbers)\n}\n\n// With return\nfunc fnWithReturn() int8 {\n\treturn 10\n}\n\n// With multiple returns\nfunc fnWithMultipleReturn() (string, int8) {\n\treturn \"Age\", 21\n}\n\n// Without return\nfunc fnWithoutReturn() {\n\tfmt.Printf(\"\\nCommon function (without return): func <FUNCTION NAME>() {<INTRUCTIONS (return not included)...>} --> return void\")\n}\n\n/*\n   Function definition inside another function...\n*/\nfunc main() {\n\t/*\n\t   Types of functions (2)...\n\t*/\n\n\t// IIFE\n\tfunc() {\n\t\tfmt.Print(\"IFE (Immediately-Invoked Function Expression): func(){<INTRUCTIONS...>}()\")\n\t}()\n\n\t// Function associated with a variable\n\tfn := func() {\n\t\tfmt.Print(\"\\nFunction associated with a variable: <VARIABLE NAME> := func(<PARAMETERS...>) {<INTRUCTIONS...>}\")\n\t}\n\n\tfn()\n\tcommonFn()\n\tfnWithParameter(\"Lucas\")\n\n\tvar lastName string = \"Hoz\"\n\tfnWithPointerParameter(&lastName)\n\n\tfnWithoutParameter()\n\tfnWithRestParameter(1, 3, 5, 6, 7, 9)\n\n\tfmt.Printf(\"\\nCommon function (with return): func <FUNCTION NAME>() int8 {<INTRUCTIONS (with return definition included)...>} --> return %d\", fnWithReturn())\n\n\tvar ageStr, ageInt = fnWithMultipleReturn()\n\tfmt.Printf(\"\\nCommon function (with multiple returns): func <FUNCTION NAME>() (string, int8) {<INTRUCTIONS (with return definition included)...>} --> return %s, %d\", ageStr, ageInt)\n\n\tfnWithoutReturn()\n\n\t/*\n\t   Native functions...\n\t*/\n\n\tarray01 := [5]int{1, 2, 3, 4, 5}\n\tfmt.Printf(\"\\n\\nNative functions: len(%d) --> %d\", array01, len(array01))\n\n\tvar array02 []int\n\tarray02 = append(array02, 4)\n\tfmt.Printf(\"\\nNative functions: append([], 4) --> %d\", array02)\n\n\t/*\n\t   Global and local variables...\n\t*/\n\n\tconst food string = \"Meat\"\n\n\tshowFood := func() string {\n\t\tconst drink string = \"Coca Cola\"\n\t\treturn \"function call with a global variable --> food = \" + food\n\t}\n\n\tfmt.Printf(\"\\n\\nGlobal variable: %s\", showFood())\n\t// fmt.Printf(\"\\nLocal variable: variable defined inside a function but called outside it --> drink = %s\", drink) // Throw an undefined error.\n\tfmt.Printf(\"\\nLocal variable: variable defined inside a function but called outside it --> drink = undefined\")\n\n\t/*\n\t   Additional challenge...\n\t*/\n\n\tadditionalChallenge := func(str01 *string, str02 *string) int8 {\n\t\tvar counter int8 = 0\n\n\t\tfmt.Println(\"\")\n\t\tfor i := 1; i < 101; i++ {\n\t\t\tvar multipleOfFive bool = i%5 == 0\n\t\t\tvar multipleOfThree bool = i%3 == 0\n\n\t\t\tif multipleOfFive && multipleOfThree {\n\t\t\t\tfmt.Printf(\"\\n%s\", *str01+*str02)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif multipleOfFive {\n\t\t\t\tfmt.Printf(\"\\n%s\", *str02)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif multipleOfThree {\n\t\t\t\tfmt.Printf(\"\\n%s\", *str01)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tfmt.Printf(\"\\n%d\", i)\n\t\t\tcounter++\n\t\t}\n\n\t\treturn counter\n\t}\n\n\tvar str01 string = \"fizz\"\n\tvar str02 string = \"buzz\"\n\tfmt.Printf(\"\\n\\n%d numbers was printed instead of 'fizz' or 'buzz' (function arguments)!\", additionalChallenge(&str01, &str02))\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/go/kodenook.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n)\n\nvar global string = \"global\"\n\nfunc main () {\n\tname()\n\tfullName(\"\", \"\")\n\tfmt.Println(addition(5, -2.5, 1.2))\n\tvar age uint8 = 20\n\tageAddition(&age)\n\tfmt.Println(age)\n\tfirst()\n\n\tscope()\n\t// fmt.Println(local) cannot\n\n\tfmt.Printf(\"number of times it was a number and not words: %d\", exercise(\"hello\", \"go\"))\n}\n\n// The function \"name\" in Go language prints \"kodenook\" to the console.\nfunc name() {\n\tfmt.Println(\"kodenook\")\n}\n\n// The fullName function in Go takes two string parameters, fname and lname, and prints them out with\n// default values if either parameter is empty.\nfunc fullName(fname string, lname string) {\n\tif(fname == \"\") {\n\t\tfname = \"my\"\n\t}\n\tif(lname == \"\") {\n\t\tlname = \"surname\"\n\t}\n\n\tfmt.Printf(\"%s %s\\n\", fname, lname)\n}\n\n// The `addition` function in Go calculates the sum of a variable number of float32 numbers.\nfunc addition(numbers ...float32) float32 {\n\tvar result float32 = 0.0\n\n\tfor _, value := range numbers {\n\t\tresult += value\n\t}\n\n\treturn result\n}\n\n// The function `ageAddition` takes a pointer to an unsigned 8-bit integer and adds 5 to its value.\nfunc ageAddition(age *uint8) {\n\t*age += 5\n}\n\n// The function `first` prints \"First\" and defines an inner function `second` that prints \"Second\" and\n// then calls it.\nfunc first() {\n\tfmt.Println(\"First\")\n\n\t// cannot\n\t// func second() {\n\t// \tfmt.Println(\"Second\")\n\t// }\n\n\t// second()\n\n\tvar second func() = func() {\n\t\tfmt.Println(\"Second\")\n\t}\n\n\tsecond()\n}\n\n// The `scope` function in Go demonstrates variable scope by accessing both a global and local\n// variable.\nfunc scope() {\n\tvar local string = \"local\"\n\n\tfmt.Println(global)\n\tfmt.Println(local)\n}\n\n/*\n\tExercise\n*/\n\n// The function `exercise` takes two words as input and prints them based on certain conditions while\n// counting the numbers that do not meet those conditions.\nfunc exercise(word1 string, word2 string) uint8 {\n\tvar i uint8\n\tvar countNumbers uint8 = 0\n\n\tfor i = 1; i < 101; i++ {\n\t\tif i % 3 == 0 && i % 5 == 0 {\n\t\t\tfmt.Printf(\"%s, %s\\n\", word1, word2)\n\t\t} else if i % 3  == 0 {\n\t\t\tfmt.Println(word1)\n\t\t} else if i % 5  == 0 {\n\t\t\tfmt.Println(word2)\n\t\t}else {\n\t\t\tcountNumbers++\n\t\t}\n\t}\n\n\treturn countNumbers\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/go/miguelex.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc holaMundo() {\n\tfmt.Println(\"Hola mundo\")\n}\n\nfunc saludo(name string) {\n\tfmt.Println(\"Hola\", name)\n}\n\nfunc saludo2(name string) string {\n\treturn \"Hola \" + name\n}\n\nfunc operaciones(a, b int) (int, int) {\n\tsuma := func() int {\n\t\treturn a + b\n\t}\n\tresta := func() int {\n\t\treturn a - b\n\t}\n\treturn suma(), resta()\n}\n\nfunc division(a, b int) (int, error) {\n\tif b == 0 {\n\t\treturn 0, fmt.Errorf(\"No se puede dividir por 0\")\n\t}\n\treturn a / b, nil\n}\n\nfunc extra(param1, param2 string) int {\n\n\tvar numImpreso = 0\n\n\tfor i := 1; i < 101; i++ {\n\t\tif i%15 == 0 {\n\t\t\tfmt.Println(param1 + param2)\n\t\t} else if i%3 == 0 {\n\t\t\tfmt.Println(param1)\n\t\t} else if i%5 == 0 {\n\t\t\tfmt.Println(param2)\n\t\t} else {\n\t\t\tfmt.Println(i)\n\t\t\tnumImpreso++\n\t\t}\n\t}\n\n\treturn numImpreso\n}\n\nfunc main() {\n\tholaMundo()\n\tsaludo(\"Miguel\")\n\tfmt.Println(saludo2(\"Miguel\"))\n\tfmt.Println(operaciones(10, 5))\n\tfmt.Println(division(10, 0))\n\tfmt.Println(\"Cantidad de numeros impresos: \", extra(\"Fizz\", \"Buzz\"))\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/go/n0hagonada.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n)\n\n// funciones declarada como tipo\ntype First func(int) int // declare type\n\nfunc getFunction() First { // use it\n\treturn func(val int) int {\n\t\treturn val * 5\n\t}\n}\nfunc main() {\n\t// funcionanonima\n\tgetMod := func(a, b int) int { // declare it\n\t\treturn a % b\n\t}\n\tfmt.Println(getMod(12, 5))\n\t//invocaicon Inmediata\n\tfunc(name string) {\n\t\tfmt.Printf(\"Hello, %s\", name)\n\t}(\"John\") // prints \"Hello, John\"\n\tnumeroDeVeces := reto(\"Fizz\", \"Buzz\")\n\tfmt.Println(\"Se imprimieron números en lugar de texto:\", numeroDeVeces, \"veces\")\n\n}\nfunc reciboargumentosTipado(saludo string, numero int) {\n\tfmt.Printf(\"%s is %d years old.\\n\", saludo, numero)\n}\nfunc multipleRetorno(x, y float64) (float64, float64) {\n\treturn (x + y) * (x - y), (x + y) / (x - y)\n}\nfunc retornoNombrado(num int) (res int) {\n\tres = num / 10\n\treturn res\n}\nfunc llamadoporReferencia(num *int) {\n\t*num = 142\n}\nfunc reto(num1, num2 string) int {\n\tcontador := 0\n\tfor i := 1; i <= 100; i++ {\n\t\tif i%3 == 0 && i%5 == 0 {\n\t\t\tfmt.Println(num1 + num2)\n\t\t} else if i%3 == 0 {\n\t\t\tfmt.Println(num1)\n\t\t} else if i%5 == 0 {\n\t\t\tfmt.Println(num2)\n\t\t} else {\n\t\t\tfmt.Println(i)\n\t\t\tcontador++\n\t\t}\n\t}\n\treturn contador\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/go/qwik-zgheib.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n)\n\n// global variable\nvar globalVar int = 100\n\n// function without parameters and return\nfunc noParamsNoReturn() {\n\tfmt.Println(\"Function without parameters and return\")\n}\n\n// function with one parameter\nfunc oneParam(param int) {\n\tfmt.Printf(\"Function with one parameter: %d\\n\", param)\n}\n\n// function with multiple parameters\nfunc multipleParams(param1 int, param2 string) {\n\tfmt.Printf(\"Function with multiple parameters: %d, %s\\n\", param1, param2)\n}\n\n// function with return\nfunc withReturn() int {\n\treturn 42\n}\n\n// function with multiple parameters(defined) and return\nfunc multipleParamsWithReturn(param1 int, param2 string) string {\n\treturn fmt.Sprintf(\"Function with multiple parameters and return: %d, %s\", param1, param2)\n}\n\n// function with multiple parameters(undefined) and return\nfunc multipleParamsWithReturnUndefined(numbers ...int) int {\n\tsum := 0\n\tfor _, number := range numbers {\n\t\tsum += number\n\t}\n\treturn sum\n}\n\n// function inside a function\nfunc outerFunction() {\n\tfmt.Println(\"Outer function\")\n\tinnerFunction := func() {\n\t\tfmt.Println(\"Inner function\")\n\t}\n\tinnerFunction()\n}\n\n// local and global variables\nfunc localVsGlobal() {\n\tlocalVar := 10\n\tfmt.Printf(\"Local variable: %d\\n\", localVar)\n\tfmt.Printf(\"Global variable: %d\\n\", globalVar)\n}\n\n// function extra: FizzBuzz\nfunc fizzBuzz(str1, str2 string) int {\n\tcount := 0\n\tfor i := 1; i <= 100; i++ {\n\t\tif i%3 == 0 && i%5 == 0 {\n\t\t\tfmt.Println(str1 + str2)\n\t\t} else if i%3 == 0 {\n\t\t\tfmt.Println(str1)\n\t\t} else if i%5 == 0 {\n\t\t\tfmt.Println(str2)\n\t\t} else {\n\t\t\tfmt.Println(i)\n\t\t\tcount++\n\t\t}\n\t}\n\treturn count\n}\n\nfunc main() {\n\tnoParamsNoReturn()\n\toneParam(10)\n\tmultipleParams(20, \"Hello\")\n\tfmt.Println(withReturn())\n\tfmt.Println(multipleParamsWithReturn(30, \"World\"))\n\n\tfmt.Printf(\"Sum of numbers: %d\", multipleParamsWithReturnUndefined(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))\n\tfmt.Println(\"\\n------\")\n\n\touterFunction()\n\n\tlocalVsGlobal()\n\n\tfmt.Printf(\"Count of numbers printed: %d\\n\", fizzBuzz(\"Fizz\", \"Buzz\"))\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/go/raynerpv2022.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc func_sin_p() {\n\tfmt.Println(\"hoy es   6 de agosto\")\n}\n\nfunc func_1_p(mes string) {\n\tfmt.Printf(\"hoy es  6 de %s \\n\", mes)\n}\n\nfunc func_2_p(dia int, mes string) {\n\tfmt.Printf(\"hoy es %d de %s \\n\", dia, mes)\n}\n\n// funcion variatica para valores por defecto\nfunc func_value_default(fecha ...string) {\n\tdia := \"26\"\n\tmes := \"enero\"\n\tif len(fecha) > 0 {\n\t\tdia = fecha[0]\n\t\tmes = fecha[1]\n\t}\n\tfmt.Printf(\"hoy es  %s de %s \\n\", dia, mes)\n}\n\nfunc returnMult(dia, mes string) (string, string) {\n\treturn dia, mes\n}\n\nfunc Mult3y5(tres, cinco string) int {\n\tnumber := 0\n\tfor i := 1; i <= 100; i++ {\n\t\tif i%3 == 0 && i%5 == 0 {\n\t\t\tfmt.Println(tres, cinco)\n\t\t} else if i%3 == 0 {\n\t\t\tfmt.Println(tres)\n\t\t} else if i%5 == 0 {\n\t\t\tfmt.Println(cinco)\n\t\t} else {\n\t\t\tnumber++\n\t\t\tfmt.Println(i)\n\t\t}\n\t}\n\treturn number\n\n}\n\nfunc func_var_param(names ...string) {\n\tlong := len(names)\n\tif long > 0 {\n\t\tfmt.Printf(\"existen %d parametros\\n\", long)\n\t\tfor _, fecha := range names {\n\t\t\tfmt.Println(fecha)\n\t\t}\n\t} else {\n\t\tfmt.Println(\"no existen parametros\")\n\n\t}\n}\n\nfunc main() {\n\tfmt.Println(Mult3y5(\"TRES\", \"CINCO\"))\n\tfunc_1_p(\"noviembre\")\n\tfunc_2_p(3, \"octubre\")\n\tfunc_sin_p()\n\tfunc_value_default()\n\tfunc_value_default(\"31\", \"diciembre\")\n\tdia, mes := returnMult(\"1\", \"enero\")\n\tfmt.Println(dia, mes)\n\tfunc_var_param()\n\tfunc_var_param(\"31\", \"mayo\")\n\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/go/thegera4.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n)\n\nvar global = \"Soy una variable global\"\n\nfunc main() {\n\n\tSayhi()\n\n\tfmt.Println(Outputname(\"Gera\"))\n\n\tfmt.Println(Twoparams(1, 2))\n\n\tfmt.Println(Doubleamounts(2))\n\n\tfmt.Println(Comporobartipo(2))\n\n\tScope()\n\n\textra := Extra(\"Fizz\", \"Buzz\")\n\n\tfmt.Println(\"El numero de veces que se imprimieron numeros fue: \", extra)\n\n}\n\n// Funcion basica, sin parametros ni retorno\nfunc Sayhi() {\n\tfmt.Println(\"Hola mundo\")\n}\n\n// Funcion con un parametro con retorno\nfunc Outputname(name string) string {\n\t//return a string with the name injected\n\treturn \"Hola usuario \" + name\n}\n\n// Funcion con parametros y retorno\nfunc Twoparams(param1 int, param2 int) int {\n\treturn param1 + param2\n}\n\n// Funcion adentro de otra funcion\nfunc Doubleamounts(amount1 int) int {\n\t//funcion anonima\n\tMultiplyby := func (number int) int {\n\t\treturn number * 2\n\t}\n\treturn Multiplyby(amount1)\n}\n\n// Funcion ya creada en el lenguaje\nfunc Comporobartipo(param int) string {\n\treturn `El valor de param es ` + strconv.Itoa(param) + ` y el tipo es ` + fmt.Sprintf(\"%T\", param)\n}\n\n// Funcion para probar el scope de las variables\nfunc Scope() {\n\t//variable local\n\tvar local = \"Soy una variable local\"\n\tfmt.Println(local)\n\tfmt.Println(global)\n}\n\n// Dificultad extra\nfunc Extra(str1 string, str2 string) int {\n\tcount := 0\n\tfor i := 1; i <= 100; i++ {\n\t\tif i % 3 == 0 && i % 5 == 0 {\n\t\t\tfmt.Println(str1 + str2)\n\t\t} else if i % 3 == 0 {\n\t\t\tfmt.Println(str1)\n\t\t} else if i % 5 == 0 {\n\t\t\tfmt.Println(str2)\n\t\t} else {\n\t\t\tfmt.Println(i)\n\t\t\tcount++\n\t\t}\n\t}\n\treturn count\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/haskell/SalazarProgrammer.hs",
    "content": "{-\n  EJERCICIO:\n  - Funciones básicas: sin parámetros, con parámetros, con retorno\n  - Funciones dentro de funciones\n  - Funciones ya creadas en el lenguaje\n  - Variables LOCAL y GLOBAL\n-}\n\nmodule Main where\n\n-- Variable GLOBAL (a nivel de módulo)\nvariableGlobal :: String\nvariableGlobal = \"Soy una variable global\"\n\n-- 1. Función sin parámetros ni retorno (en Haskell, retorna IO ())\nfuncionSinParametros :: IO ()\nfuncionSinParametros = putStrLn \"¡Hola desde función sin parámetros!\"\n\n-- 2. Función con un parámetro y sin retorno explícito\nfuncionUnParametro :: String -> IO ()\nfuncionUnParametro nombre = putStrLn (\"Hola, \" ++ nombre ++ \"!\")\n\n-- 3. Función con varios parámetros y retorno\nfuncionVariosParametros :: Int -> Int -> Int\nfuncionVariosParametros a b = a + b\n\n-- 4. Función con retorno explícito\nfuncionConRetorno :: Float -> Float -> Float\nfuncionConRetorno x y = x * y\n\n-- 5. Función dentro de función (usando where)\nfuncionExterna :: Int -> Int\nfuncionExterna x = funcionInterna x * 2\n    where\n        funcionInterna :: Int -> Int\n        funcionInterna y = y + 5\n\n-- 6. Función dentro de función (usando let)\nfuncionConLet :: Int -> Int\nfuncionConLet x =\n    let funcionInterna y = y * 3\n    in funcionInterna x + 1\n\n-- 7. Uso de funciones ya creadas en Haskell\nusoFuncionesNativas :: IO ()\nusoFuncionesNativas = do\n    putStrLn $ \"Longitud de 'Haskell': \" ++ show (length \"Haskell\")\n    putStrLn $ \"Reverse de 'Haskell': \" ++ reverse \"Haskell\"\n    putStrLn $ \"Máximo de [1,5,3,2]: \" ++ show (maximum [1,5,3,2])\n    putStrLn $ \"Suma de [1..5]: \" ++ show (sum [1..5])\n\n-- 8. Prueba de variables LOCALES y GLOBALES\npruebaAlcanceVariables :: IO ()\npruebaAlcanceVariables = do\n    putStrLn $ \"Variable global: \" ++ variableGlobal\n\n    -- Variable LOCAL dentro de la función\n    let variableLocal = \"Soy una variable local\"\n    putStrLn $ \"Variable local: \" ++ variableLocal\n\n    -- Función con variable local interna\n    let funcionConVariableLocal x =\n            let variableInterna = x * 2\n            in variableInterna + 1\n\n    putStrLn $ \"Función con variable local (5): \" ++ show (funcionConVariableLocal 5)\n\n-- DIFICULTAD EXTRA\ndificultadExtra :: String -> String -> Int\ndificultadExtra texto1 texto2 = contador\n  where\n    -- Función auxiliar para procesar cada número\n    procesarNumero n\n        | n `mod` 15 == 0 = putStrLn (texto1 ++ texto2) >> return False\n        | n `mod` 3 == 0  = putStrLn texto1 >> return False\n        | n `mod` 5 == 0  = putStrLn texto2 >> return False\n        | otherwise       = putStrLn (show n) >> return True\n\n    -- Lista de resultados (True si se imprimió el número)\n    resultados = map procesarNumero [1..100]\n\n    -- Contar cuántas veces se imprimió el número (True)\n    contador = length (filter id resultados)\n\n-- Versión alternativa más funcional de la dificultad extra\ndificultadExtraFuncional :: String -> String -> Int\ndificultadExtraFuncional texto1 texto2 = length numerosImpresos\n  where\n    numerosImpresos = [n | n <- [1..100], imprimirNumero n]\n\n    imprimirNumero n\n        | n `mod` 15 == 0 = putStrLn (texto1 ++ texto2) False\n        | n `mod` 3 == 0  = putStrLn texto1 False\n        | n `mod` 5 == 0  = putStrLn texto2 False\n        | otherwise       = putStrLn (show n) True\n\n-- Función auxiliar para imprimir y retornar valor\nputStrLn :: String -> Bool -> Bool\nputStrLn mensaje retorno = do\n    Prelude.putStrLn mensaje\n    return retorno\n\n-- Función principal\nmain :: IO ()\nmain = do\n    putStrLn \"=== FUNCIONES BÁSICAS ===\"\n    funcionSinParametros\n    funcionUnParametro \"Mundo\"\n    putStrLn $ \"Función con varios parámetros (3 + 4): \" ++ show (funcionVariosParametros 3 4)\n    putStrLn $ \"Función con retorno (2.5 * 3.0): \" ++ show (funcionConRetorno 2.5 3.0)\n\n    putStrLn \"\\n=== FUNCIONES DENTRO DE FUNCIONES ===\"\n    putStrLn $ \"Función externa (5): \" ++ show (funcionExterna 5)\n    putStrLn $ \"Función con let (4): \" ++ show (funcionConLet 4)\n\n    putStrLn \"\\n=== FUNCIONES NATIVAS DE HASKELL ===\"\n    usoFuncionesNativas\n\n    putStrLn \"\\n=== ALCANCE DE VARIABLES ===\"\n    pruebaAlcanceVariables\n\n    putStrLn \"\\n=== DIFICULTAD EXTRA ===\"\n    putStrLn \"Ejecutando dificultadExtra con 'Fizz' y 'Buzz':\"\n    resultado <- return (dificultadExtra \"Fizz\" \"Buzz\")\n    putStrLn $ \"\\nNúmeros impresos (no reemplazados): \" ++ show resultado\n\n    putStrLn \"\\nEjecutando versión funcional:\"\n    resultado2 <- return (dificultadExtraFuncional \"Fizz\" \"Buzz\")\n    putStrLn $ \"Números impresos: \" ++ show resultado2\n\n-- Fin del programa"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/AFOXJONES.java",
    "content": "/**\n * Clase principal que incluye ejemplos de funciones en Java, variables globales y locales,\n * recursividad, encapsulación y la resolución de un ejercicio extra.\n */\npublic class AFOXJONES {\n\n    // Variable global (accesible en toda la clase)\n    private static final String variableGlobal = \"SOY GLOBAL\";\n\n    /**\n     * Método principal de ejecución.\n     */\n    public static void main(String[] args) {\n        // Variable local (solo accesible dentro de este método)\n        String variableLocal = \"SOY LOCAL\";\n\n        System.out.println(\"Variable local: \" + variableLocal);\n\n        System.out.println(\"Variable global: \" + variableGlobal);\n\n        // Ejemplo de funciones nativas de Java\n        System.out.println(\"\\nEjemplo de funciones ya creadas por el lenguaje:\");\n        String exampleString = \"pepe\";\n        System.out.println(\"compareToIgnoreCase: \" + exampleString.compareToIgnoreCase(\"PEPE\"));\n        System.out.println(\"concat: \" + exampleString.concat(\" Gutierrez\"));\n\n        // Llamadas a los métodos de la clase\n        sinRetorno();\n        sinRetornoConParametro(\"¡Hola, mundo!\");\n        sinRetornoConParametros(\"Texto\", 42);\n\n        String retorno = conRetorno();\n        System.out.println(\"\\nResultado de conRetorno: \" + retorno);\n\n        int resultadoSuma = conRetornoConParametro(10);\n        System.out.println(\"Resultado de conRetornoConParametro: \" + resultadoSuma);\n\n        System.out.println(\"\\nLlamada recursiva:\");\n        funcionRecursiva(0);\n\n        // Ejercicio extra\n        System.out.println(\"\\nEjercicio extra:\");\n        int count = extra(\"Fizz\", \"Buzz\");\n        System.out.println(\"Números impresos como números: \" + count);\n    }\n\n    /**\n     * Método sin retorno ni parámetros.\n     */\n    public static void sinRetorno() {\n        System.out.println(\"Función sin retorno ni parámetros\");\n    }\n\n    /**\n     * Método público sin retorno, con un parámetro.\n     *\n     * @param param Parámetro de entrada de tipo String.\n     */\n    public static void sinRetornoConParametro(String param) {\n        System.out.println(\"Función sin retorno con el parámetro: \" + param);\n    }\n\n    /**\n     * Método público sin retorno, con múltiples parámetros.\n     *\n     * @param param1 Primer parámetro de tipo String.\n     * @param param2 Segundo parámetro de tipo int.\n     */\n    public static void sinRetornoConParametros(String param1, int param2) {\n        System.out.println(\"Función sin retorno con los parámetros: \" + param1 + \" y \" + param2);\n    }\n\n    /**\n     * Método público con retorno y sin parámetros.\n     *\n     * @return Cadena de texto que indica el resultado de la función.\n     */\n    public static String conRetorno() {\n        return \"Función con retorno sin parámetros\";\n    }\n\n    /**\n     * Método público con retorno y un parámetro.\n     *\n     * @param param Número entero de entrada.\n     * @return Número incrementado en 3.\n     */\n    public static int conRetornoConParametro(int param) {\n        return param + 3;\n    }\n\n    /**\n     * Ejemplo de método privado: solo se usa dentro de esta clase.\n     * Representa una función recursiva.\n     *\n     * @param count Contador que determina la profundidad de la recursión.\n     */\n    private static void funcionRecursiva(int count) {\n        System.out.println(\"Antes de la recursión: \" + count);\n        if (count < 5) {\n            funcionRecursiva(count + 1);\n        }\n        System.out.println(\"Después de la recursión: \" + count);\n    }\n\n    /**\n     * Ejercicio extra: imprime números y textos según condiciones.\n     *\n     * @param text1 Texto a mostrar si el número es múltiplo de 3.\n     * @param text2 Texto a mostrar si el número es múltiplo de 5.\n     * @return Cantidad de números impresos como números (ni múltiplos de 3 ni de 5).\n     */\n    public static int extra(String text1, String text2) {\n        int count = 0;\n        for (int i = 1; i <= 100; i++) {\n            if (i % 3 == 0 && i % 5 == 0) {\n                System.out.println(text1 + text2);\n            } else if (i % 3 == 0) {\n                System.out.println(text1);\n            } else if (i % 5 == 0) {\n                System.out.println(text2);\n            } else {\n                System.out.println(i);\n                count++;\n            }\n        }\n        return count;\n    }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/AbelADE.java",
    "content": "/**\n * Solución del reto #02 FUNCIONES Y ALCANCE.\n *\n * @author AbelADE\n */\npublic abstract class AbelADE {  \n\n    /**\n     * Diferentes típos de funciones (en Java, métodos, que suelen estar asociados a objetos.): \n     *       -- Estructura: modificador retorno nombre (parámetros). \n     *       -- Tipos de métodos: \n     *              * Métodos sin retorno. \n     *              * Métodos con retorno.         \n     *              * Métodos sin parámetros \n     *              * Métodos con parámetros. \n     *              * Métodos estáticos (no están asociados a objetos). \n     *              * Métodos constructores: Se utilizan para inicializar un objeto cuando se crea. \n     *              * Métodos abstractos: Se declaran en clases abstractas y deben ser implementados por las subclases.\n     */\n    \n    \n    /**\n     * Ejemplo de Método sin retorno y sin parámetros.\n     */\n    public void hola() {\n        System.out.println(\"Hola!\");\n    }\n    \n    /**\n     * Ejemplo de Método sin retorno, con parámetros.\n     * \n     * @param hola un texto.\n     */\n    public void hola(String hola) {\n        System.out.println(hola);\n    }\n\n    /**\n     * Ejemplo de Método con retorno y sin parámetros.\n     *\n     * @return un texto con un hola mundo.\n     */\n    public String holaMundo() {\n        return \"¡Hola, Mundo!\";\n    }\n    \n    /**\n     * Ejemplo de Método con retorno y parámetros.\n     *\n     * @param hola un texto.\n     * @return un texto con un hola mundo.\n     */\n    public String holaMundo(String hola) {\n        return hola + \", Mundo!\";\n    }\n\n    /**\n     * Ejemplo de un método estático que devuelve el número PI. \n     * @return el número PI.\n     */\n    public static double calcularPI() {\n        return Math.PI;\n    }\n\n    /**\n     * Ejemplo de método constructor sin parámetros. \n     * Se utilizan para inicializar un objeto cuando se crea.\n     */\n    public AbelADE() {\n    }\n    \n    /**\n     * Ejemplo de un método abstracto. \n     * No se implementa ninguna lógica en estos métodos, pero una clase que\n     * quiera ser hija desta, deberá implementarlo.\n     * \n     * @return un texto.\n     */\n    public abstract String adios(); \n    \n   /**\n    * En java no se pueden crear métodos dentro de métodos (anidados).\n    * Lo que se puede hacer es crear un objeto que tenga un método abstracto\n    * (lo cual te obliga a tener que implementar ese método). \n    * Las clases que pueden tener métodos abstractos son las clases abstractas\n    * y las interfaces.\n    * \n    * @return un texto de despedida.\n    */\n    public String despedida(){\n        //Creo una clase abstracta\n        AbelADE claseAbstracta = new AbelADE() {\n            @Override\n            //Sobrescribo su método\n            public String adios() {\n                //Variable local o de método.\n                String adios = \"adios\";\n                return adios;\n            }\n        };\n        \n        /*No podemos devolver la variable adios, ya que sólo existe\n        dentro del método adios de la claseAbstracta. Hacer lo siguiente:\n        return adios; \n        sería un error*/\n        \n        //Uso el método anterior en el método actual.\n        return claseAbstracta.adios();\n    }\n    \n    //Variable a nivel de clase, conocida cómo atributo o variable global.\n    private String nombre = \"AbelAde\";\n    \n    /**\n     * DIFICULTAD EXTRA (Ejercicio fizz buzz)\n     * \n     * Una función que imprima los números del 1 al 100, pero si el número es\n     * múltiplo de 3, muestre una palabra, si es múltiplo de 5 muestre otra \n     * y si es múltiplo de los dos muestre las dos palabras.\n     *\n     * @param texto1 el texto para los divisores de 3.\n     * @param texto2 el texto para los divisores de 5.\n     * @return el número de veces que mostró números y no texto.\n     */\n    public int funcion(String texto1, String texto2){\n        int counter = 0;\n        for (int i = 0; i < 100; i++) {\n            String result = \"\";\n            result += i%3==0? texto1 + \" \" : \"\";\n            result += i%5==0? texto2 : \"\";\n            if (result.isBlank()) {\n                result = Integer.toString(i);\n                counter ++;\n            }\n            System.out.println(result);\n        }\n        return counter;\n    }\n\n    /**\n     * @param args the command line arguments\n     */\n    public static void main(String[] args) {\n        \n        /**\n        * Java es un lenguaje orientado a objetos que trae\n        * una serie de clases y métodos incorporados. Una de las clases\n        * más usadas es la clase String. Vamos a usar una función de \n        * esta clase.\n        */\n        String hola = \"hola\";\n        \n        //Devuelve el primer carácter del texto.\n        char caracter = hola.charAt(0);\n        \n        AbelADE abelADE = new AbelADE() {\n            @Override\n            public String adios() {\n                return \"adios\";\n            }\n        };\n        \n        //Imprimimos la variable global\n        System.out.println(abelADE.nombre);\n        \n        //Sacamos por pantalla el valor de los métodos anteriores\n        System.out.println(abelADE.adios());\n        abelADE.hola();\n        abelADE.hola(\"hola2\");\n        System.out.println(abelADE.holaMundo());\n        System.out.println(abelADE.holaMundo(\"hola\"));\n        System.out.println(calcularPI());\n        System.out.println(abelADE.despedida());\n        \n        System.out.println();\n        \n        System.out.println(\"DIFICULTAD EXTRA\");\n        int numeros = abelADE.funcion(\"fizz\", \"buzz\");\n        System.out.println(\"numeros: \" + numeros);\n    }\n    \n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/Ainoaran.java",
    "content": "//RETO #02 - Funciones y alcance.\n\npublic abstract class Ainoaran {\n\n    //Funciones:\n\n    //Función básica sin parámetros:\n    public void hello() {\n        System.out.print(\"¡Hi, Java!\");\n    }\n\n    //Función básica con parámetros:\n    public void hola(String java) {\n        System.out.print(\"¡Hola, \" + java);\n    }\n\n    //Función básica sin parámetro y retorno:\n    public String konnichiwa() {\n        return \"こんにちは, Java\";\n    }\n\n    //Función básica con parámetro y retorno:\n    public String bonjour(String java) {\n        return \"Bonjour, \" + java;\n    }\n\n    //Método static - Permite invocar funcionalidad sin crear objetos:\n    public class operacion {\n        public static int sumar(int a, int b) {\n            return a + b;\n        }\n    }\n    int resultado = operacion.sumar(5,10);\n\n    //Método abstracto - Se declaran en una clase abstracta.\n    //Su propósito es definir un \"contrato\" que las clases hijas deben cumplir.\n    public abstract class despedida {\n        public abstract void goodbye();\n    }\n\n    //Método constructor - se utiliza para inicializar objetos de una clase:\n\n    public class Persona {\n        private String nombre;\n        private int edad;\n\n        // Constructor por defecto\n        public Persona() {\n            nombre = \"Desconocido\";\n            edad = 30;\n        }\n\n        // Constructor con parámetros\n        public Persona(String nombre, int edad) {\n            this.nombre = nombre;\n            this.edad = edad;\n        }\n    }\n    /*Funciones anidadas:\n     *Java no soporta la definición anidada de funciones como en algunos otros lenguajes de programación.\n     *Cada función debe definirse a nivel de clase.\n     */\n\n    //Variables Locales - Se declaran dentro de un bloque de código específico.\n    public void varLocal() {\n        int num = 10;\n        System.out.println(num);\n    }\n\n    //Variable Global - Se declaran dentro de una clase, pero fuera de cualquier método, constructor o bloque de código.\n    public class global {\n        int num = 10; // Variable global (de instancia)\n\n        public void varGlobal() {\n            System.out.println(num);\n        }\n    }\n\n    /*DIFICULTAD EXTRA (opcional):\n     * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n     * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n     *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n     *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n     *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n     *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n     */\n\n    public static int difExtra(String text1, String text2) {\n        int counter = 0;\n\n        for (int i = 0; i < 100; i++) {\n            if (i % 3 == 0 && i % 5 == 0) {\n                System.out.println(i + \": \" + text1 + \" \" + text2);\n                counter++;\n            } else if (i % 3 == 0) {\n                System.out.println(i + \": \" + text1);\n                counter++;\n            } else if (i % 5 == 0) {\n                System.out.println(i + \": \" + text2);\n                counter++;\n            }\n        }\n\n        return counter;\n    }\n\n    public static void main(String[] args) {\n\n        String text1 = \"Fizz\";\n        String text2 = \"Buzz\";\n        int finalCounter = difExtra(text1, text2);\n        System.out.print(\"Contador: \" + finalCounter);\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/AlexisDiaz000.java",
    "content": "public class AlexisDiaz000 {\n     // 1. Función sin parámetros ni retorno\n     public static void saludo() {\n        System.out.println(\"¡Hola! Soy Alexis Diaz\");\n    }\n\n    // 2. Función con un parámetro y sin retorno\n    public static void mostrarMensaje(String mensaje) {\n        System.out.println(\"Mensaje recibido: \" + mensaje);\n    }\n\n    // 3. Función con varios parámetros y con retorno\n    public static int sumar(int a, int b) {\n        return a + b;\n    }\n\n    // 4. Función con retorno sin parámetros\n    public static double obtenerPi() {\n        return 3.1415;\n    }\n\n    // 5. Uso de una función ya existente en Java\n    public static void ejemploFuncionJava() {\n        String texto = \"Hola, mundo alexis diaz aqui!\";\n        System.out.println(\"Texto en mayúsculas: \" + texto.toUpperCase());\n    }\n\n    // 6. Variables Locales vs Globales\n    static int variableGlobal = 100; // Variable global\n\n    public static void mostrarVariables() {\n        int variableLocal = 50; // Variable local\n        System.out.println(\"Variable global: \" + variableGlobal);\n        System.out.println(\"Variable local: \" + variableLocal);\n    }\n\n    public static void main(String[] args) {\n        // Llamar a cada función para ver su resultado\n        saludo();\n\n        mostrarMensaje(\"Soy yo de nuevo Alexis diaz.\");\n\n        int resultadoSuma = sumar(20, 8);\n        System.out.println(\"Resultado de la suma es la cantidad de años que tengo actualmente: \" + resultadoSuma);\n\n        double valorPi = obtenerPi();\n        System.out.println(\"El valor de Pi es: \" + valorPi);\n\n        ejemploFuncionJava();\n\n        mostrarVariables();\n\n        int solucion = transformador(\"alexis\",\"diaz\");\n        System.out.println(\"NUMERO DE VECES QUE SE IMPRESO EL NUMERO Y NO EL TEXTO: \" + solucion);\n\n        // 7. ¿Se pueden definir funciones dentro de funciones en Java?\n        // Java NO permite definir funciones dentro de otras funciones directamente.\n        // Sin embargo, podemos usar clases anónimas o funciones lambda en ciertos casos.\n    }\n\n    /*    DIFICULTAD EXTRA (opcional):\n    *     Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n    *   - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n    *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n    *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n    *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n    *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n    *\n    * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n    * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.*/\n\n\n\n        public static int transformador (String cadena1, String cadena2){\n            int contadorNumeros = 0;\n            for (int i = 1; i <= 100; i++) {\n                if (i % 3 == 0 && i % 5 == 0) {\n                    System.out.println(cadena1 + cadena2);\n                } else if (i % 3 == 0) {\n                    System.out.println(cadena1);\n                } else if (i % 5 == 0) {\n                    System.out.println(cadena2);\n                }else {\n                    System.out.println(i);\n                    contadorNumeros++;\n                }\n            }\n            return contadorNumeros;\n\n        }\n    \n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/Alextc35.java",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n// Clase abstracta con un método abstracto\nabstract class Animal {\n    // Método abstracto (sin implementación)\n    public abstract void hacerSonido();\n\n    // Método no abstracto (con implementación)\n    public void dormir() {\n        System.out.println(\"El animal está durmiendo.\");\n    }\n}\n\n// Clase concreta que extiende la clase abstracta\nclass Perro extends Animal {\n    // Implementación del método abstracto\n    @Override\n    public void hacerSonido() {\n        System.out.println(\"El perro dice: ¡Guau!\");\n    }\n}\n\n// Otra clase concreta que extiende la clase abstracta\nclass Gato extends Animal {\n    // Implementación del método abstracto\n    @Override\n    public void hacerSonido() {\n        System.out.println(\"El gato dice: ¡Miau!\");\n    }\n}\n\n// Clase con método sincronizado\nclass Contador {\n    private int cuenta = 0;\n\n    public synchronized void incrementar() {\n        cuenta++;\n    }\n\n    public int getCuenta() {\n        return cuenta;\n    }\n}\n\n// Clase con métodos de diferentes tipos\npublic class Alextc35 {\n\n    // Variable global\n    static int variableGlobal = 777;\n\n    // Constructor explícito sin parámetros\n    public Alextc35() {\n        System.out.println(\"Constructor de objetos\");\n    }\n\n    // Constructor con parámetros\n    public Alextc35(String nombre, int edad) {\n        System.out.println(\"Nombre: \" + nombre + \"\\nEdad: \" + edad);\n    }\n\n    // Método estático\n    public static void metodoStatic() {\n        System.out.println(\"Método estático.\");\n    }\n\n    // Método final\n    public final void metodoFinal() {\n        System.out.println(\"Método final.\");\n    }\n\n    public static void main(String[] args) {\n        Alextc35 yo = new Alextc35(); // Constructor sin parámetros\n        Alextc35 miOtroYo = new Alextc35(\"Alejandro\", 23); // Constructor con parámetros\n\n        // 1. Funciones básicas\n        funcionVoidNoParams();\n        funcionVoidSiParams(\"cat\");\n        funcionVoidTwoParams(13, 22);\n        System.out.println(\"La suma de 21 + 196 es = \" + funcionIntTwoParams(21, 196));\n        System.out.println(\"Mi nombre es: \" + funcionStringSiParams(\"Alejandro\"));\n\n        // Ejemplo de clases abstractas y métodos abstractos\n        Animal miPerro = new Perro();\n        Animal miGato = new Gato();\n\n        miPerro.hacerSonido(); // Debería imprimir: El perro dice: ¡Guau!\n        miPerro.dormir(); // Debería imprimir: El animal está durmiendo.\n\n        miGato.hacerSonido(); // Debería imprimir: El gato dice: ¡Miau!\n        miGato.dormir(); // Debería imprimir: El animal está durmiendo.\n\n        // 2. Función dentro de otra función\n        funcionDos();\n\n        // 3. Ejemplo de función ya existente\n        Integer a = 217;\n        Integer b = 217;\n        System.out.println(\"a: \" + a + \"\\nb: \" + b + \"\\n¿Son iguales?: \" + a.equals(b));\n\n        // 4. Variables globales y locales\n        System.out.println(\"Variable global: \" + variableGlobal);\n        int variableLocal = obtenerVariableLocal();\n        System.out.println(\"Variable local: \" + variableLocal);\n\n        // Ejemplos de métodos adicionales\n        metodoStatic(); // Llamada al método estático\n        Alextc35 instance = new Alextc35();\n        instance.metodoFinal(); // Llamada al método final\n\n        // Ejemplo de método con sincronización\n        Contador contador = new Contador();\n        contador.incrementar();\n        System.out.println(\"Contador después de incrementar: \" + contador.getCuenta());\n\n        // Opcional\n        System.out.println(\"Número de veces que se imprimió un número: \" + funcionOpcional(\"Alejandro\", \"Tellez\"));\n    }\n\n    // 1. Funciones básicas\n\n    public static void funcionVoidNoParams() {\n        System.out.println(\"Función que no tiene parámetros y no retorna nada.\");\n    }\n\n    public static void funcionVoidSiParams(String word) {\n        System.out.println(\"La palabra es \" + word + \".\");\n    }\n\n    public static void funcionVoidTwoParams(int number1, int number2) {\n        System.out.println(\"La suma de \" + number1 + \" + \" + number2 + \" es = \" + (number1 + number2));\n    }\n\n    public static int funcionIntTwoParams(int number1, int number2) {\n        return number1 + number2; // Retorna la suma de los parámetros.\n    }\n\n    public static String funcionStringSiParams(String name) {\n        return name; // Retorna la cadena de texto.\n    }\n\n    // 2. Función dentro de otra función\n\n    public static void funcionUno() {\n        System.out.println(\"Soy la función uno!\");\n    }\n\n    public static void funcionDos() {\n        funcionUno(); // Llama a la función uno dentro de la función dos.\n        System.out.println(\"Soy la función dos!\");\n    }\n\n    // 4. Variables globales y locales\n\n    public static int obtenerVariableLocal() {\n        int variableLocal = 666; // Variable local\n        return variableLocal;\n    }\n\n    // Opcional\n\n    public static int funcionOpcional(String cadena1, String cadena2) {\n        int num = 0;\n\n        // Bucle del 1 al 100\n        for (int i = 1; i <= 100; i++) {\n            if (i % 15 == 0) {\n                System.out.println(cadena1 + cadena2); // Múltiplo de 3 y 5\n            } else if (i % 3 == 0) {\n                System.out.println(cadena1); // Múltiplo de 3\n            } else if (i % 5 == 0) {\n                System.out.println(cadena2); // Múltiplo de 5\n            } else {\n                System.out.println(i); // Otro caso\n                num++;\n            }\n        }\n        return num;\n    }\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/AmadorQuispe.java",
    "content": "import java.util.ArrayList;\nimport java.util.List;\nimport java.util.Scanner;\n\npublic class AmadorQuispe {\n    // Esto es una variable GLOBAL, accesible desde toda la clase.\n    static String user;\n\n    public static void main(String[] args) {\n        welcomeSystem();\n        // Esto es una variable LOCAL solo es accesible desde el método main\n        Scanner sc = new Scanner(System.in);\n        printQuestion(\"Ingresa tu nombre :\");\n        user = sc.next();\n        String greeting = greeting(user);\n        printMessage(greeting);\n        printMessage(\"El sistema puede hacer estos trabajos\");\n        printMessage(\"[A] Operación simple (+,-,* y / de dos números) \");\n        printMessage(\"[B] Operación multiple (+, - y * de varios números) \");\n        printMessage(\"[C] Factorial de un número\");\n        printQuestion(\"Ingresa la opción :\");\n        String job = sc.next();\n        printMessage(\"Seleccionaste la opción \" + jobSelected(job));\n        if (job.equalsIgnoreCase(\"A\")) {\n            printMessage(\"Dentro de las operaciones simples tenemos :\");\n            printMessage(\"(1) Suma\");\n            printMessage(\"(2) Resta\");\n            printMessage(\"(3) Multiplicación\");\n            printMessage(\"(4) División\");\n            printMessage(\"(5) Potencia\");\n            printQuestion(\"Digita el número de la operación :\");\n            String selected = sc.next();\n            printMessage(\"Haz seleccionado \" + operationSelected(selected) + \", ahora ingresa los números.\");\n            printQuestion(\"Ingresa el número 1 :\");\n            double number1 = sc.nextDouble();\n            printQuestion(\"Ingresa el número 2 :\");\n            double number2 = sc.nextDouble();\n            double result = operation(selected, number1, number2);\n            printMessage(\"El resultado de la operación \" + operationSelected(selected) + \" :\");\n            printMessage(\"\" + number1 + \" y \" + number2 + \" es: \" + result);\n        } else if (job.equalsIgnoreCase(\"B\")) {\n            printMessage(\"Dentro de las operaciones multiples tenemos :\");\n            printMessage(\"(1) Suma\");\n            printMessage(\"(2) Resta\");\n            printMessage(\"(3) Multiplicación\");\n            printQuestion(\"Digita el número de la operación :\");\n            String selected = sc.next();\n            printMessage(\"Haz seleccionado \" + operationSelected(selected) + \", ahora ingresa los números.\");\n            printQuestion(\"Ingresa los números separado por una coma (,) ejemplo 1,2,3 :  \");\n            String input = sc.next();\n            Double[] numbers = stringToArray(input);\n            double result = operationsMultipleNumbers(selected, numbers);\n            printMessage(\"El resultado de la operación \" + operationSelected(selected) + \" :\");\n            printMessage(\"\" + input + \" es: \" + result);\n        } else if (job.equalsIgnoreCase(\"C\")) {\n            printMessage(\"Factorial de un número :\");\n            printQuestion(\"Ingresa el número positivo :\");\n            int number = sc.nextInt();\n            long result = factorial(number);\n            printMessage(\"El factorial de \" + number + \" es \" + result);\n        } else {\n            printMessage(\"La opción que seleccionaste no existe\");\n        }\n\n        sc.close();\n        printMessage(exitSystem());\n\n    }\n\n    /*\n     * Función sin parametro ni retorno.\n     */\n    static void welcomeSystem() {\n        System.out.println(\"------------------------------\");\n        System.out.println(\"----Bienvenido al sistema-----\");\n        System.out.println(\"------------------------------\");\n    }\n\n    /*\n     * Función que recibe un parametro pero no retorna ningún valor.\n     */\n    static void printMessage(String message) {\n        System.out.println(message);\n    }\n\n    static void printQuestion(String question) {\n        System.out.print(question);\n    }\n\n    /*\n     * Función sin parametro y con retorno.\n     */\n    static String exitSystem() {\n        return \"Gracias por usar el sistema \" + user + \" regresa pronto.\";\n    }\n\n    static String greeting(String name) {\n        return \"Hola, bienvenido \" + name;\n    }\n\n    /*\n     * Función que recibe un parametro y retorna un valor.\n     * \n     * @Return: Double[]\n     */\n    static Double[] stringToArray(String sNumbers) {\n        List<Double> numbers = new ArrayList<>();\n        String[] numbersSplit = sNumbers.split(\",\");\n        for (int i = 0; i < numbersSplit.length; i++) {\n            numbers.add(Double.parseDouble(numbersSplit[i]));\n        }\n        return numbers.toArray(new Double[0]);\n    }\n\n    /*\n     * Función que recibe un parametro y retorna un valor.\n     */\n    static String jobSelected(String input) {\n        return switch (input) {\n            case \"A\":\n                yield \"[A] Operación simple\";\n            case \"B\":\n                yield \"[B] Operación multiple\";\n            case \"C\":\n                yield \"[C] Factorial\";\n            default:\n                yield \"No soportado\";\n        };\n    }\n\n    /*\n     * Función que recibe un parametro y retorna un valor.\n     */\n    static String operationSelected(String input) {\n        String operation = switch (input) {\n            case \"1\":\n                yield \"(1) Suma\";\n            case \"2\":\n                yield \"(2) Resta\";\n            case \"3\":\n                yield \"(3) Multiplicación\";\n            case \"4\":\n                yield \"(4) División\";\n            case \"5\":\n                yield \"(5) Potencia\";\n\n            default:\n                yield \"No soportado\";\n        };\n        return operation;\n    }\n\n    /*\n     * Función que recibe varios parametros y retorna un valor.\n     */\n    static double operation(String operator, double number1, double number2) {\n        switch (operator) {\n            case \"1\":\n                return number1 + number2;\n            case \"2\":\n                return number1 - number2;\n            case \"3\":\n                return number1 * number2;\n            case \"4\":\n                return number1 / number2;\n            case \"5\":\n                // Aquí usamos una función propio del lenguaje\n                return Math.pow(number1, number2);\n\n            default:\n                throw new RuntimeException(\"Operación no soportada\");\n        }\n    }\n\n    /*\n     * Función que recibe un parametro de tipo cadena y un varargs (o argumentos\n     * variables) de tipo Double\n     * y retorna un valor\n     */\n    static double operationsMultipleNumbers(String operator, Double... numbers) {\n        // Esto es una variable local, es accesible solo dentro del scope metodo.\n        double total = 0;\n        switch (operator) {\n            case \"1\":\n                for (int i = 0; i < numbers.length; i++) {\n                    total += numbers[i];\n                }\n                break;\n            case \"2\":\n                for (int i = 0; i < numbers.length; i++) {\n                    total -= numbers[i];\n                }\n                break;\n            case \"3\":\n                total = 1;\n                for (int i = 0; i < numbers.length; i++) {\n                    total *= numbers[i];\n                }\n                break;\n\n            default:\n\n                break;\n        }\n\n        return total;\n    }\n\n    /*\n     * Función recursivo: Una función recursiva es una función que se llama a sí\n     * misma durante su ejecución\n     */\n    static long factorial(int num) {\n        if (num == 0) {\n            return 1;\n        } else {\n            return num * factorial(num - 1);\n        }\n    }\n\n    // Eercicio extra\n    static int fizzBuzz(String fizz, String buzz) {\n        int count = 0;\n        for (int i = 1; i <= 100; i++) {\n            if (i % 3 == 0) {\n                System.out.println(fizz);\n            } else if (i % 5 == 0) {\n                System.out.println(buzz);\n            } else if (i % 5 == 0 && i % 3 == 0) {\n                System.out.println(fizz + buzz);\n            } else {\n                System.out.println(i);\n                count++;\n            }\n        }\n        return count;\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/AnaLauDB.java",
    "content": "public class AnaLauDB {\n    // Variable global (atributo de la clase)\n    int contadorGlobal = 0;\n\n    public void incrementarGlobal() {\n        contadorGlobal++;\n        System.out.println(\"Contador global: \" + contadorGlobal);\n    }\n\n    public void ejemploLocal() {\n        // Variable local (solo existe dentro de este método)\n        int contadorLocal = 0;\n        contadorLocal++;\n        System.out.println(\"Contador local: \" + contadorLocal);\n    }\n\n    public void saludo() {\n        System.out.println(\"¡Hola Ana Laura!\");\n    }\n\n    // Con un parámetro, sin retorno\n    public void mostrarNombre(String nombre) {\n        System.out.println(\"Nombre: \" + nombre);\n    }\n\n    // Con varios parámetros, sin retorno\n    public void mostrarDatos(String nombre, int edad) {\n        System.out.println(\"Nombre: \" + nombre + \", Edad: \" + edad);\n    }\n\n    // Con retorno, sin parámetros\n    public int obtenerNumeroFavorito() {\n        return 7;\n    }\n\n    // Con retorno, con varios parámetros\n    public int producto(int num1, int num2) {\n        return num1 * num2;\n    }\n\n    public static void main(String[] args) {\n        AnaLauraDB db = new AnaLauraDB();\n\n        db.saludo();\n        db.mostrarNombre(\"Ana Laura\");\n        db.mostrarDatos(\"Ana Laura\", 23);\n\n        int favorito = db.obtenerNumeroFavorito();\n        System.out.println(\"Número favorito: \" + favorito);\n\n        int result = db.producto(3, 4);\n        System.out.println(\"El resultado de la multiplicación es: \" + result);\n\n        // Ejemplo usando funciones de Math\n        double raiz = Math.sqrt(16); // Calcula la raíz cuadrada\n        System.out.println(\"Raíz cuadrada de 16: \" + raiz);\n\n        int maximo = Math.max(10, 20); // Obtiene el máximo entre dos números\n        System.out.println(\"El máximo entre 10 y 20 es: \" + maximo);\n\n        // Ejemplo usando funciones de String\n        String texto = \"Hola Mundo\";\n        int longitud = texto.length(); // Obtiene la longitud del texto\n        System.out.println(\"Longitud del texto: \" + longitud);\n\n        String mayusculas = texto.toUpperCase(); // Convierte el texto a mayúsculas\n        System.out.println(\"Texto en mayúsculas: \" + mayusculas);\n\n        // Si quieres un número aleatorio entre 1 y 10\n        int aleatorioEntero = (int) (Math.random() * 10) + 1;\n        System.out.println(\"Número aleatorio entre 1 y 10: \" + aleatorioEntero);\n\n        db.incrementarGlobal(); // Imprime: Contador global: 1\n        db.incrementarGlobal(); // Imprime: Contador global: 2\n\n        db.ejemploLocal(); // Imprime: Contador local: 1\n        db.ejemploLocal(); // Imprime: Contador local: 1 (se reinicia cada vez)\n\n        // Algoritmo FizzBuzz del 1 al 50\n        for (int i = 1; i <= 50; i++) {\n            if (i % 3 == 0 && i % 5 == 0) {\n                System.out.println(\"FizzBuzz\");\n            } else if (i % 3 == 0) {\n                System.out.println(\"Fizz\");\n            } else if (i % 5 == 0) {\n                System.out.println(\"Buzz\");\n            } else {\n                System.out.println(i);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/AndrewCodev.java",
    "content": "public class AndrewCodev {\n\t//Variables Globales de la clase\n\tint num1;\n    int num2;\n    int num3;\n\n    public void suma(){\n    \tthis.num1 = 2;\n    \tthis.num2 = 7;\n    \tthis.num3 = 1;\n    \t\n    \tint resultado = this.num1 + this.num2 + this.num3;\n        System.out.println(\"Resultado de la suma en un método sin argumentos y sin retorno\");\n        System.out.println(this.num1+\" + \"+this.num2+\" + \"+this.num3+\" = \"+ resultado);\n    }\n    \n    /*las variables creadas como parametros son variable locales del método\n     * al igual que las variables creadas dentro de este sin el operador this.\n     * como ejemplola variable resultado.\n     */\n    public void sumaConParametros(int num1, int num2, int num3) {\n    \t//Variable Local llamando a la función Suma con Retorno\n    \tint resultado = sumaConRetorno(num1, num2, num3);\n        System.out.println(this.num1+\" + \"+this.num2+\" + \"+this.num3+\" = \"+ resultado);\n    }\n    \n    public int sumaConRetorno(int num1, int num2, int num3) {\n    \tthis.num1 = num1;\n    \tthis.num2 = num2;\n    \tthis.num3 = num3;\n    \tint resultado = this.num1 + this.num2 + this.num3;\n        return resultado;\n    }\n    \n    //DIFICULTAD EXTRA\n    public int contadorNumerico(String cadena1, String cadena2) {\n    \t//Variable local de método\n    \tint contador = 0;\n    \t\n    \tfor (int i = 1; i <= 100; i++) {\n    \t\t\n    \t\tif(i % 3 == 0 && i % 2 == 0) {\n    \t\t\tSystem.err.println(i+\": \"+cadena1+\" \"+cadena2);\n    \t\t}else if(i % 2 == 0) {\n    \t\t\tSystem.err.println(i+\": \"+cadena2);\n    \t\t}else if(i % 3 == 0) {\n    \t\t\tSystem.err.println(i+\": \"+cadena1);\n    \t\t}\n    \t\telse {\n    \t\t\tSystem.err.println(i+\" \");\n    \t\t\tcontador++;\n    \t\t}\t\t\t\n\t\t}\n    \t\n    \treturn contador;\n    }\n    \n    public static void main(String[] args) {\n\t\tAndrewCodev andrewCodev = new AndrewCodev();\n\t\tandrewCodev.suma();\n\t\tSystem.out.println(\"\\nResultado de la suma en un método con argumentos y sin retorno\");\n\t\tandrewCodev.sumaConParametros(5, 5, 10);\n\t\t\n\n    \tSystem.out.println(\"\\nResultado de la suma en un método con argumentos y con retorno\\n\");\n\t\tint sumaConRetorno = andrewCodev.sumaConRetorno(6, 4, 5);\n\t\tSystem.out.println(sumaConRetorno);\n\t\t\n\t\tSystem.out.println(\"DIFICULTAD EXTRA\");\n\t\tint contador = andrewCodev.contadorNumerico(\"Hola Mundo\", \"Adios Mundo\");\n\t\tSystem.err.println(\"Total numeros no multiplos de 2 ni de 3: \"+contador);\n    }\n\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/AngelSanchezT.java",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\npublic class AngelSanchezT {\n    public static int globalVariable = 5;\n\n    public static void main(String[] args) {\n\n        saludar();\n        saludarPersona(\"AngelSanchezT\");\n        saludarPersona(\"Angel\", \"Sanchez\");\n\n        String saludo = getSaludo();\n        saludarPersona(saludo);\n\n        System.out.println(\"2 ** 2 es: \" + elevarCuadrado(2));\n        System.out.println(\"10 + 3 es: \" + sumar(10, 3));\n        System.out.println(\"1.5 + 2.5 es: \" + sumar(1.5, 2.5));\n        \n        // Funciones del Lenguaje\n        String username = \"AngelSanchezT\";\n        \n        System.out.println(\"Funciones de Java:\");\n        System.out.println(\"Longitud username:\" + username.length());\n        System.out.println(\"Usename minusculas:\" + username.toLowerCase());\n        System.out.println(\"Usename mayusculas:\" + username.toUpperCase());\n\n        // Variable local\n        String pais = \"Colombia\";\n        System.out.println(\"Variable Local: \" + pais);\n\n        System.out.println(\"Variable global: \" + globalVariable);\n\n        // EXTRA\n        System.out.println(\"EXTRA:\");\n        int resultado = retornarNumero(\"Java\", \"Python\");\n        System.out.println(\"El número de veces que aparece el número es: \" + resultado);\n\n    }\n\n    // Función que no retorna y no recibe parametros\n    public static void saludar() {\n        System.out.println(\"Hola Java ❤️!\");\n    }\n\n    // Función que no retorna y recibe un parametro\n    public static void saludarPersona(String nombre) {\n        System.out.println(\"Hola, \" + nombre + \"!\");\n    }\n\n    // Función que no retorna y recibe mas de un parametro\n    public static void saludarPersona(String nombre, String apellido) {\n        System.out.println(\"Hola, \" + nombre + \" \" + apellido +\"!\");\n    }\n\n    // Función que no recibe parametros pero retorna un valor\n    public static String getSaludo(){\n        return \"Hola Java!\";\n    }\n\n    // Función que retorna un valor y recibe un parametro\n    public static int elevarCuadrado(int numero) {\n        return numero * numero;\n    }\n\n    // Función que retorna un valor y recibe múltiples parámetros\n    public static int sumar(int a, int b) {\n        return a + b;\n    }\n\n    // SobreCarga de Funciones.\n    // La función sumar puede tener varias funciones con el mismo nombre pero con\n    // parametros diferentes en numero y el tipos de datos. Y diferente tipo de retorno.\n    public static double sumar(double a, double b) {\n        return a + b;\n    }\n\n    public static int retornarNumero(String cadena1, String cadena2) {\n        int count = 0;\n\n        for (int i = 1; i <= 100; i++) {\n            if (i % 3 == 0 && i % 5 == 0) System.out.println(cadena1 + \" \" + cadena2);\n            else if (i % 3 == 0) System.out.println(cadena1);\n            else if (i % 5 == 0) System.out.println(cadena2);\n            else {\n                System.out.println(i);\n                count++;\n            }\n        }\n\n\n        return count;\n    }\n\n\n\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/BlasBarragan.java",
    "content": "import java.util.Scanner;\n\n/**\n * - Crea ejemplos de funciones básicas que representen las diferentes\n * posibilidades del lenguaje:\n * Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n * (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne\n * un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n * - Si el número es múltiplo de 3, muestra la cadena de texto del primer\n * parámetro.\n * - Si el número es múltiplo de 5, muestra la cadena de texto del segundo\n * parámetro.\n * - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto\n * concatenadas.\n * - La función retorna el número de veces que se ha impreso el número en lugar\n * de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los\n * casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código\n * se entienda.\n * \n * #### SINTAXIS DE UNA FUNCION ####\n * modificador tipoDatoDevuelto nombreDeFuncion (lista de parámetros de entrada)\n * {\n * return datoDevuelto;\n * }\n *\n * @version v1\n * \n * @since 14/01/2024\n * \n * @author Blas Barragán\n * \n */\npublic class BlasBarragan {\n\n    // Variables globales, pueden ser usada por todas las funciones y bloques.\n    // Siempre iran precedidas del mosificador static. Y hay que evitar usarlas.\n    static int mayor;\n    static int c = 6;\n    static int d = 3;\n\n    public static void main(String[] args) {\n        Scanner sc = new Scanner(System.in);\n        System.out.println(\"Hola, como te llamas?: \");\n        String nombre = sc.nextLine();\n        System.out.println(\"Y dime, cuantos años tienes?: \");\n        int edad = sc.nextInt(); // Variale local, se define dentro de la funcion y solo se puede usar dentro de\n                                 // la misma.\n        funcionSinRetornoConParametros(nombre, edad);\n        System.out.println(\n                \"Vamos a ver que numero es mayor, tu me das un numero \\\"a\\\" y yo pienso en otro \\\"b\\\" y vemos cual de los dos es mayor\");\n        System.out.println(\"Dime un numero: \");\n        int a = sc.nextInt();\n        System.out.println(\"El numero \" + numeroMayor(a, 5) + \" es el mayor.\");\n        System.out.println(\"Llamamos a la funcion mayorReturn con las variables globales c y d\");\n        System.out.println(mayorReturn(c, d));\n        System.out.println(retornoSinParametros());\n        System.out.println(dificultadExtra(\"cara\", \"cola\"));\n        sc.close();\n    }\n\n    // Funcion sin retorno ni parametros\n    // - retorno: void. (\"subprograma\" (No devuelve resultado despues de ejecutar su\n    // bloque y no necesita return))\n    // - parametros(): vacio. (No recibe datos de entrada)\n    public static void funcionSinRetornoNiParametros() {\n        System.out.println(\"Esto es una funcion sin retorno ni parametros que imprime un mensaje\");\n    }\n\n    // Funcion sin retorno con parametros\n    // - retorno: void. (\"subprograma\" (No devuelve resultado despues de ejecutar su\n    // bloque y no necesita return))\n    // - parametros(): String nombre, int edad. (Los definimos en la funcion main\n    // preguntando al usuario por consola)\n    public static void funcionSinRetornoConParametros(String nombre, int edad) {\n        System.out.println(\"Hola \" + nombre + \", de verdad tienes \" + edad + \" años?\");\n    }\n\n    // Funcion con retorno y parametros\n    // - retorno: int mayor. (Utilizamos return para que nos devuelva el resultado\n    // de las operaciones realizadas en la funcion)\n    // - parametros: int a, int b. (En main, preguntamos al usuario por dos numeros\n    // con los que inicializamos la funcion)\n    public static int numeroMayor(int a, int b) {\n        if (a >= b)\n            mayor = a;\n        else\n            mayor = b;\n\n        return mayor;\n    }\n\n    // La palabra reservada return, se puede usar en distintas partes de la funcion\n    // segun necesitemos,\n    // pero teniendo en cuenta que cuando se ejecuta el return se termina la\n    // funcion.\n    // Por ejemplo, la misma funcion que antes pero usando los return a nuestro\n    // antojo.\n    public static int mayorReturn(int c, int d) {\n        if (c >= d)\n            return c; // Si a es mayor que b, devolvemos a\n\n        return d; // Si no, devuelve b\n    }\n\n    // Funcion con retorno sin parametros\n    // - retorno: String (Utilizamos return para que nos devuelva el texto\n    // introducido en la funcion)\n    // - parametros(): vacio. (No recibe datos de entrada)\n    public static String retornoSinParametros() {\n        return \"Soy una funcion con retorno sin parametros\";\n    }\n\n    /**\n     * DIFICULTAD EXTRA (opcional):\n     * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne\n     * un número.\n     * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n     * - Si el número es múltiplo de 3, muestra la cadena de texto del primer\n     * parámetro.\n     * - Si el número es múltiplo de 5, muestra la cadena de texto del segundo\n     * parámetro.\n     * - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto\n     * concatenadas.\n     * - La función retorna el número de veces que se ha impreso el número en lugar\n     * de los textos.\n     */\n\n    public static int dificultadExtra(String cadena1, String cadena2) {\n        int i;\n        int a = 0;\n        for (i = 1; i <= 100; i++) {\n            if (i % 3 == 0 && i % 5 == 0) {\n                // System.out.println(cadena1+cadena2);\n                a = a + 1;\n            } else if (i % 5 == 0) {\n                // System.out.println(cadena2);\n                a = a + 1;\n            } else if (i % 3 == 0) {\n                // System.out.println(cadena1);\n                a = a + 1;\n            } else {\n                // System.out.println(\"\");}\n            }\n        }\n        return a;\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/Chakerr.java",
    "content": "\nimport java.util.Scanner;\n\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\npublic class Chakerr {\n\n    //Variable global\n    static int global = 20;\n\n    public static void main(String[] args) {\n\n        sinParametros();\n        conParametros(3);\n        conRetorno();\n\n        //Funciones ya creadas en el lenguaje\n        int max = Math.max(10, 20);\n        System.out.println(\"numero maximo entre 10 y 20 : \" + max);\n        int min = Math.min(10, 20);\n        System.out.println(\"numero minimo entre 10 y 20 : \" + min);\n\n        //Variable local y global\n        int local = 3;\n        System.out.println(\"variable local : \" + local);\n        System.out.println(\"Variable global : \" + global);\n\n        //Dificultad extra\n        reto();\n    }\n\n    //Funcion sin parámetros ni retorno\n    static void sinParametros() {\n        System.out.println(\"Funcion sin parámetros ni retornos\");\n    }\n\n    //Funcion con uno o varios parámetros\n    public static void conParametros(int a) {\n        System.out.println(\"suma de variables a + variable global  = \" + (a + global));\n    }\n\n    public static String conRetorno() {\n        return \"Retorno\";\n    }\n\n    public static int reto() {\n\n        int contadorNumeros = 0;\n        String cadena1 = \"Multiplo de 3\";\n        String cadena2 = \"Multiplo de 5\";\n\n        for (int i = 1; i <= 100; i++) {\n            if (i % 3 == 0 && i % 5 == 0) {\n                System.out.println(i + \" : \" + cadena1 + \"y\" + cadena2);\n\n            } else if (i % 3 == 0) {\n                System.out.println(i + \" : \" + cadena1);\n\n            } else if (i % 5 == 0) {\n                System.out.println(i + \" : \" + cadena2);\n            } else {\n                System.out.println(i);\n                contadorNumeros++;\n            }\n        }\n\n        return contadorNumeros;\n    }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/Clarancedev.java",
    "content": "/**\n * #02 FUNCIONES Y ALCANCE\n * @author clarancedev\n * @version %I%, %G%\n */\n\npublic class Clarancedev {\n\n    // VARIABLE GLOBAL (accesible desde cualquier parte de la clase)\n    static final String VARIABLE_GLOBAL = \"Soy una variable global de la clase Clarancedev\";\n\n    // TIPOS DE FUNCIONES (TAMBIÉN DENOMINADOS MÉTODOS)\n\n    // SIN PARÁMETROS Y SIN RETORNO\n    /* No se especifica el tipo de dato que retorna la función,\n     * en su lugar indicamos \"void\". Su contenido tampoco incluye\n     * un \"return\", aunque puede incluir más de una función y\n     * llamar a otras funciones de la misma clase */\n        public static void variableLocal () {\n\n            // VARIABLE LOCAL (accesible solo dentro de la función donde se declara)\n            String variableLocal = \"Soy una variable local de la función main()\";\n\n            System.out.println(variableLocal);\n        }\n\n        public static void cuentaAtrasDespegue () {\n            for (int i = 10; i > 0; i--) {\n                System.out.println(i);\n            }\n            System.out.println(\"¡Despegamos!\");\n        }\n\n    // CON PARÁMETROS Y SIN RETORNO\n    /* No debemos especificar el tipo de dato que retorna la función,\n     * pero debemos especificar el tipo de dato de los parámetros\n     * que recibe la función. Su contenido no incluye un \"return\" */\n    public static void funcionConParSinRet (String nombre) {\n        System.out.println(\"Hola, \" + nombre + \"!\");\n    }\n\n    public static void funcionConParSinRet2 (int edadActual) {\n        int nuevaEdad = edadActual + 5;\n        System.out.println(\"Si ahora tienes \" + edadActual + \" años, dentro de 5 años tendrás \" + nuevaEdad + \".\");\n    }\n\n    // SIN PARÁMETROS Y CON RETORNO\n    /* Debemos especificar el tipo de dato que retorna la función,\n     * y su contenido debe incluir un \"return\" de dicho tipo de dato */\n    public static String funcionSinParConRet () {\n        return \"Soy una función sin parámetros y con retorno\";\n    }\n\n    public static int sumarUnoYDos() {\n        return 1 + 2;\n    }\n\n    // CON PARÁMETROS Y CON RETORNO\n    /* Debemos especificar el tipo de dato que retorna la función,\n     * y su contenido debe incluir un \"return\" de dicho tipo de dato.\n     * Ojo, dos métodos pueden tener el mismo nombre, siempre y cuando\n     * los parámetros solicitados sean distintos, sea en cantidad o tipo */\n\n    public static int multiplicarValores(int num1, int num2) {\n        return num1 * num2;\n    }\n\n    public static double multiplicarValores(double num1, double num2) {\n        return num1 * num2;\n    }\n\n    public static int multiplicarValores(int num1, int num2, int num3) {\n        return num1 * num2 * num3;\n    }\n\n    // DIFICULTAD EXTRA\n\n    public static int fizzBuzzInspired(String texto1, String texto2) {\n        int counter = 0;\n\n        System.out.println(\"Imprimiendo los números del 1 al 100, salvo los que son múltiples de 3 o de 5, para los cuales aparecerán las palabra Fizz y/o Buzz:\");\n\n        for (int i = 1; i <101; i++) {\n            boolean esMultiploDe3 = i % 3 == 0;\n            boolean esMultiploDe5 = i % 5 == 0;\n\n            if (esMultiploDe3 && esMultiploDe5) {\n                System.out.println(texto1 + texto2);\n            } else if (esMultiploDe3) {\n                System.out.println(texto1);\n            } else if (esMultiploDe5) {\n                System.out.println(texto2);\n            } else {\n                System.out.println(i);\n                counter++;\n            }\n        }\n        return counter;\n    }\n\n    public static void main(String[] args) {\n        /* LA FUNCIÓN MAIN() ES UNA FUNCIÓN ESPECIAL,\n         * ES LA PRINCIPAL DONDE SE EJECUTA EL PROGRAMA */\n\n        // Imprimiendo variables LOCAL y GLOBAL\n        variableLocal();\n        System.out.println(VARIABLE_GLOBAL);\n\n        // Imprimiendo la función SIN parámetros y SIN retorno cuentaAtrasDespegue()\n        cuentaAtrasDespegue();\n\n        // Imprimiendo las funciones CON parámetros y SIN retorno\n        funcionConParSinRet(\"Java\");\n        funcionConParSinRet2(25);\n\n        // Imprimiendo las funciones SIN parámetros y CON retorno\n        System.out.println(funcionSinParConRet());\n        System.out.println(\"La suma de 1 y 2 es igual a \" + sumarUnoYDos());\n\n        // Imprimiendo las funciones CON parámetros y CON retorno\n        int int1 = 2;\n        int int2 = 3;\n        int int3 = 4;\n        double double1 = 2.5;\n        double double2 = 3.5;\n\n        System.out.println(int1 + \" * \" + int2 + \" = \" + multiplicarValores(int1, int2));\n        System.out.println(double1 + \" * \" + double2 + \" = \" + multiplicarValores(double1, double2));\n        System.out.println(int1 + \" * \" + int2 + \" * \" + int3 + \" = \" + multiplicarValores(int1, int2, int3));\n\n        // FUNCIONES DE JAVA CLASS LIBRARY\n        /* Java Class Library es una biblioteca de clases que contiene\n         * funciones predefinidas que podemos usar en nuestros programas.\n         * Por ejemplo, la clase Math contiene funciones matemáticas\n         * como Math.abs(), Math.sqrt(), Math.pow(), etc. */\n\n        System.out.println(\"La raíz cuadrada de 9 es \" + Math.sqrt(9));\n\n        // Llamando a la función de dificultad extra\n\n        int counter = fizzBuzzInspired(\"Fizz\", \"Buzz\");\n        System.out.println(\"El número de veces que no se imprimió Fizz o Buzz es: \" + counter);\n    }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/CurtoBrull.java",
    "content": "public class CurtoBrull {\n\n    // Variable global\n    static String globalText = \"Hello World! Variable global\";\n\n    public static void main(String[] args) {\n        // Crear diferentes tipos de funciones sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n        printText();\n        printText(\"Hello World! Con parámetro sin retorno\");\n        System.out.println(returnText());\n        System.out.println(returnText(\"Hello World! Con parámetro y con retorno\"));\n        System.out.println(returnText(globalText, \"Múltiples Parámetros con retorno!\"));\n        printText2();\n        printTextRec(3);\n        System.out.println(\"Veces que se ha impreso un número: \" + extraExercice(100, \"Pim\", \"Pam\"));\n    }\n\n    public static void printText() {\n        // Variable local\n        String localText = \"Hello World! Variable local. Función sin parámetros ni retorno\";\n        System.out.println(localText);\n    }\n\n    public static void printText(String text) {\n        System.out.println(text);\n    }\n\n    public static String returnText() {\n        return \"Hello World! Sin parámetros y con retorno\";\n    }\n\n    public static String returnText(String text) {\n        return text;\n    }\n\n    public static String returnText(String text, String text2) {\n        return text + \" \" + text2;\n    }\n\n    // Funcion dentro de otra funcion\n    public static void printText2() {\n        System.out.println(\"Hello World! Llamada de función dentro de función\");\n        printText();\n    }\n\n    // Funcion recursiva\n    public static void printTextRec(int n) {\n        if (n == 0) {\n            return;\n        }\n        System.out.println(\"Hello World! Función recursiva\");\n        printTextRec(n - 1);\n    }\n\n/*\nCrea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\nLa función imprime todos los números del 1 al 100. Teniendo en cuenta que:\nSi el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\nSi el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\nSi el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\nLa función retorna el número de veces que se ha impreso el número en lugar de los textos.\n*/\n\n    public static int extraExercice(int n, String text1, String text2) {\n        int count = 0;\n        for (int i = 1; i <= n; i++) {\n            if (i % 3 == 0 && i % 5 == 0) {\n                System.out.println(text1 + text2);\n            } else if (i % 3 == 0) {\n                System.out.println(text1);\n            } else if (i % 5 == 0) {\n                System.out.println(text2);\n            } else {\n                System.out.println(i);\n                count++;\n            }\n        }\n        return count;\n    }\n\n\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/Daeduol.java",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\npublic class FunsYalcance {\n    static String variableGlobal = \"soy una variable global\";\n\n    // funcion sin parametros ni retorno\n    static void funSinParam() {\n        System.out.println(\"funcion sin parametros ni retorno\");\n    }\n\n    //funcion con parametros\n    static void funConParam(int a, int b) {\n        int resultado = a + b;\n        System.out.println(\"La suma de \" + a + \" y \" + b + \" es: \" + resultado);\n\n    }\n\n    // funcion con retorno\n    public static int funConReto(int a, int b) {\n        int respuesta = a - b;\n        return respuesta;\n\n    }\n\n    //funcion dentro de funcion\n    static void funEnfun() {\n        System.out.println(\"En java no se permiten funciones anidadas\");\n    }\n    static int caraCorona(String text1, String text2) {\n\n        int contador = 0;\n\n        for (int i = 1; i <= 100; i++) {\n\n            if (i % 3 == 0 && i % 5 == 0) {\n                System.out.println(text1 + text2);\n            } else if (i % 3 == 0) {\n                System.out.println(text1);\n            } else if (i % 5 == 0) {\n                System.out.println(text2);\n            } else {\n                System.out.println(i);\n\n                contador++;\n            }\n        }\n        return contador;\n\n    }\n\n    public static void main(String[] args) {\n        String variableLocal = \"soy una variable local\";\n\n        // Llamando a la función sin parámetros ni retorno\n        funSinParam();\n        // Llamando a la función con parámetros\n        funConParam(2, 3);\n        // Llamando a la función con retorno y almacenando el resultado en una variable\n        int respuestaResta = funConReto(5, 3);\n        System.out.println(respuestaResta);\n        // Llamando a la función dentro de función\n        funEnfun();\n        // variables local y global\n        System.out.println(variableLocal);\n        System.out.println(variableGlobal);\n        int numImpresiones = caraCorona(\"cara\", \"corona\");\n        System.out.println(\"Se imprimieron \" + numImpresiones + \" números.\");\n\n    }\n\n\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/DanielBelenguer.java",
    "content": "public class DanielBelenguer {\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\npublic static void main(String[] args) {\n    // Función sin parámetros y sin retorno\n    funcionsinparametrosinretorno();\n    // Función con un parámetro de entrada y sin retorno\n    funcionunparametrosinretorno(5);\n    // Función con varios parámetros de entrada y con retorno\n    System.out.println(funcionvariosparametrosconretorno(5, 10));\n    // Función dentro de función\n    funciondentrodefuncion();\n    // Función que utiliza una función ya creada en el lenguaje\n    System.out.println(Math.random());\n    // Función para comprobar el alcanze de las variables\n    int num = 5; // Esta variable es global\n    System.out.println(\"El valor de la variable global es: \" + num);\n    // Función extra\n    System.out.println((int)funcionextra(\"Hola\",\"mundo!\"));\n}\n\nstatic public void funcionsinparametrosinretorno () {\n    System.out.println(\"Esto es una función sin parámetros de entrada y sin retorno\");\n}\n\nstatic public void funcionunparametrosinretorno (int a) {\n    System.out.println(\"Esto es una función con un parámetro de entrada y sin retorno\");\n    System.out.println(\"El parametro de entrada es: \" + a);\n}\n\nstatic public int funcionvariosparametrosconretorno (int a, int b) {\n    System.out.println(\"Esto es una función con varios parámetros de entrada y con retorno\");\n    System.out.println(\"Los parámetros de entrada son: \" + a + \" y \" + b);\n    System.out.println(\"Los parámetros de entada se van a sumar.\");\n    return a + b;\n}\n\nstatic public void funciondentrodefuncion () {\n    System.out.println(\"Esto es una función dentro de otra función\");\n    System.out.println(\"Vamos a llamar a otra función desde esta función\");\n    funcionsinparametrosinretorno();\n}\n\nstatic public void funcionalcancevariables () {\n    int num2 = 10; // Esta variable es local\n    System.out.println(\"El valor de la variable local es: \" + num2);\n}\n\nstatic public int funcionextra (String cadena1, String cadena2) {\n    int repeticion = 0;\n    for (int i = 1; i <= 100; i++) {\n        if ( i % 3 == 0) {\n            System.out.println(cadena1);\n            repeticion++;\n        }else if (i%5==0) {\n            System.out.println(cadena2);\n            repeticion++;\n        }else if (i%3==0 && i%5==5 ){\n            repeticion++;\n            System.out.println(cadena1 + \" \" + cadena2);\n        }\n    }\n    return repeticion;\n}\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/Davidr1594.java",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\npublic class Davidr1594 {\n    public static void main(String[] args) {\n        \n        //Funciones basicas en java:\n        //Pueden retornar o un un valor a la vez que pueden llevar o no parametros\n        // se forman de un accesso - modificador -si va retornar o es void - tipo - nombre. \n        //Tambien se le puede asignar el valor retornado de una funcion a una variable.\n\n        //Funciones estaticas\n        funcionSinParam();\n        funcionConParam(\"Soy una función con 2 parametros\");\n        funcionCon2Param(2,5);\n        funcionConRetorno(false,\"Soy verdadero\");\n        //LLamando metodo(Se le llama metodo cunado proviene de un objeto si es un funcion propia de la clase se define con el modificador static).\n        Davidr1594.metodoLLamado();\n        //Llamando a una funcion desde otra funcion\n        mostrarEnPantalla();\n        //Ejercicio Extra\n        System.out.println(ejercicioExtra(\"Texto1\",\"Texto2\"));\n\n    \n\n    }\n\n    private static int ejercicioExtra(String cadena1, String cadena2) {\n        int contador = 0;\n        for (int i = 1; i <= 100; i++) {\n            if(i%3 == 0){\n                System.out.println(cadena1);\n                contador +=1;\n            }else if(i%5 == 0){\n                System.out.println(cadena2);\n                contador +=1;\n            }else if((i%3 == 0) && (i%5 == 0)){\n                System.out.print(cadena1.concat(\" \"+ cadena2));\n                contador += 1;\n            }\n\n        }\n    return contador;\n    }\n\n    private static void mostrarEnPantalla() {\n        int a = 5 ,b =5;\n\n        System.out.println(suma(a,b));\n    }\n\n    private static int suma(int a, int b) {\n\n        return a+b;\n    }\n\n    private static void metodoLLamado() {\n        System.out.println(\"Soy un metodo proveniente del objeto Davidr1594\");\n    }\n\n    private static void funcionCon2Param(int a, int b) {\n        System.out.println(\"Funcion con 2 parametros, se sumaran:\"+ (a+b));\n    }\n\n    private static void funcionConParam(String mensaje) {\n        System.out.println(mensaje);\n    }\n\n    private static void funcionSinParam() {\n\n        System.out.println(\"Soy una función sin parametros\");\n    }\n    private static boolean funcionConRetorno(boolean a, String mensaje){\n        if (a == true){\n            System.out.println(mensaje);\n        }\n        return a;\n    }\n    \n    \n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/DiegoIBB.java",
    "content": "package javaExample_;\nimport java.util.Scanner;\n\n\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n\n//En Java las funciones son conocidas como métodos y se declaran dentro de la clase antes del bloque main\n\n\npublic class Funciones_alcance_02 {\n\t\n\t\n\t\n\t//-------- CONCEPTO DE VARIABLE LOCAL Y GLOBAL --------\n\t\n\tpublic static void var_local() {\n\t\tint horas_laborales = 5 * 24;\n\t\tint horas_fin_semana = 2 * 24;\n\t\tSystem.out.println(\"Cantidad de horas en la semana: \" + horas_laborales);\n\t\tSystem.out.println(\"Cantidad de horas en fin de semana: \" + horas_fin_semana);\n\n\t}\n\t\n\t\n\tpublic static void main(String[]args) {\n\t\tScanner name = new Scanner(System.in);\n\t\tSystem.out.println(\"Put Your name: \");\n\t\tString nombre = name.nextLine();\n\t\t\n\t\tint []lista = {1, 2, 3, 4, 5, 6};\n\t\tint []punto_1 = {2,4};\n\t\tint []punto_2 = {7,9};\n\t\t\n\t\t\n\t\t//--- Resultados de funciones ---\n\n\t\tSystem.out.println(bienvenida());\t\n\t\tSaludo(nombre);\n\t\tcontador(lista);\n\t\tSystem.out.println(\"La distancia entre puntos: \" + distancia_puntos(punto_1, punto_2));\n\t\t\n\t\t\n\t\t//-------- FUNCIONES EXISTENTES DENTRO DEL LENGUAJE -------\n\n\t\t// Función CONCAT(), devuelve la unión de dos cadenas\n\t\tString cadena_2 = \"Hola \";\n\t\tString cadena_3 = \"que tal todo\";\n\t\tString cadena_final = cadena_2.concat(cadena_3);\n\t\tSystem.out.println(cadena_final);\n\n\t\t// Función LENGTH(), devuelve el largo de una cadena\n\t\tString cadena_1 = \"Hola como estas\";\n\t\tint largo = cadena_1.length();\n\t\tSystem.out.println(largo);\n\n\n\t\t//-------- CONCEPTO DE VARIABLE LOCAL Y GLOBAL --------\n\t\tvar_local();\n\t\t//La variable local horas_laborales no se puede acceder de manera global\n\t\t//int horas_trabajo = horas_laborales - (8*5);\n\t\t\n\t\t\n\t\t//-------- DIFICULTAD EXTRA --------\n\t\tSystem.out.println(reto_extra(\" multipo de 3\", \" multiplo de 5\"));\n\t\t\n\t}\t\n\n\t\n\t//-------- DIFERENTES TIPOS DE FUNCIONES --------\n\t\n\t//Ejemplo de Función sin retorno y con parámetro\n\t\n\t/* \n\t * Función con Modificador Public, dicho modificador permite que\n\t * Se pueda acceder a esta función desde otras clases al momento de\n\t * crear un objeto que utice dicha función\n\t*/\n\tpublic static void contador(int[]lista) {\n\t\tint counter =0;\n\t\tint total =0;\n\t\tint largo = lista.length;\n\t\t\n\t\tfor(int i=0; i<largo; i++) {\n\t\t\tcounter = lista[i];\n\t\t\ttotal = total + counter;\n\t\t}\n\t\tSystem.out.println(\"Largo de la lista: \" + largo);\n\t\tSystem.out.println(\"Suma de todos los elementos de una lista: \" + total);\t\t\n\n\t}\n\t\n\t// Ejemplo de Función con retorno y con parámetro\n\t\n\tstatic String Saludo(String nombre){\n\t\tSystem.out.println(\"Hola \" + nombre);\n\t\treturn nombre;\n\t}\n\t\n\t// Ejemplo de Función con retorno y sin parámetro\n\tpublic static String bienvenida() {\n\t\tString mensaje = \"------------------\\n----BIENVENIDO----\\n------------------\";\n\t\treturn mensaje;\n\t}\n\t\n\t// Ejemplo de Función con retorno y varios parámetros\n\t\n\tpublic static Double distancia_puntos(int[]pto1, int[]pto2) {\n\t\tint cateto_1 = pto1[0] - pto2[0];\n\t\tint cateto_2 = pto1[1] - pto2[1];\n\t\tdouble value_cateto_1 = Math.pow(cateto_1, 2);\n\t\tdouble value_cateto_2 = Math.pow(cateto_2, 2);\n\t\tdouble distancia = Math.pow(value_cateto_1 + value_cateto_2, 1/2);\n\n\t\treturn distancia;\n\t\t\n\t}\n\t\n\t//-------- DIFICULTAD EXTRA --------\n\t\n\tpublic static int reto_extra(String cadenaR_1, String cadenaR_2) {\n\t\tint contador_3 = 0;\n\t\tint contador_5 = 0;\n\t\tint contador_comun = 0;\n\n\t\tfor(int i=0; i<100; i++){\n\t\t\tif(i%5 == 0 && i%3 == 0){\n\t\t\t\tSystem.out.println( i + cadenaR_1 + cadenaR_2);\n\t\t\t\tcontador_comun += 1;\n\t\t\t}else if(i%3 == 0){\n\t\t\t\tSystem.out.println(i + cadenaR_1);\n\t\t\t\tcontador_3 += 1;\n\t\t\t}else if(i%5 == 0){\n\t\t\t\tSystem.out.println( i + cadenaR_2);\n\t\t\t\tcontador_5 += 1;\n\t\t\t}\n\t\t}\n\t\tSystem.out.println(\"Los números multiplos de 3 son: \" + contador_3);\n\t\tSystem.out.println(\"Los números multiplos de 5 son: \" + contador_5);\n\t\tSystem.out.println(\"Los números multiplos de 3 y 5 son: \" + contador_comun);\n\n\t\treturn contador_comun;\n\t}\n\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/DomingoAndres.java",
    "content": "public class DomingoAndres {\n\n     //Funcion sin paramaetro ni retorno\n        public static void saludo (){\n            System.out.println(\"Hola, soy una funcion que solo saluda.\");\n        }\n\n    //Funcion con 1 parametro pero sin retorno\n    public static void unParametro (int paramtero1){\n        System.out.println(\"El valor que recibi como parametro fue: \" + paramtero1);\n    }\n\n    //Funcion con varios parametros pero sin retorno\n    public static void variosParametros (int a, int b, int c){\n        System.out.println(\"Recibi 3 parametros, y la suma de todos ellos es igual a: \" + (a+b+c));\n    }\n\n    //Funcion con retorno pero sin retorno\n    public static String conRetorno(){\n        return \"Soy una funcion con retorno, pero no tengo parametros.\";\n    }\n\n    //Funcion con retorno y con 1 parametro\n    public static String retornoConParametro(int a){\n        return \"El valor que me pasaron a mi fue: \" + a;\n    }\n\n    //Funcion con retorno y varios parametros\n    public static String retornoConParametros(int x, int y, int z){\n        return \"Soy una funcion con retorno y 3 parametros que suman: \" + (x+y+z);\n    }\n\n    //En Java NO SE PUEDE crear o definir funciones dentro de otras funciones\n    //Lo que si podemos hacer es usar funciones ya creadas anteriormente dentro de nuesvas funciones\n\n\n    //Funcion ya creada de Java\n    public static String raizCuadrada(int a){\n        double resultado = Math.sqrt(a); //Math.sqrt es una funcion ya creada de java\n\n        return \"Me pasaron el numero \" + a + \" y su raiz cuadrada es: \"+ resultado;\n    }\n\n\n    static int variableGlobal = 7;\n\n    //Funcion para variable local\n    public static String funcionVariableLocal(){\n        int variableLocal = 5;\n\n        return \"Mi variable local es: \" + variableLocal + \" y mi variable global es: \" + variableGlobal;\n    }\n\n\n    //-------------------DIFICULTAD EXTRA---------------------------\n\n    public static int dificltadExtra(String a, String b){\n        int contador = 0;\n        for (int i = 1; i <= 100; i ++){\n            if ( i % 3 == 0 && i % 5 == 0){\n                System.out.println(a + \", \" + b);\n            }\n            else if (i % 3 == 0){\n                System.out.println(a);\n            }\n            else if (i % 5 == 0){\n                System.out.println(b);\n            }\n            else{\n                System.out.println(i);\n                contador ++;\n            }\n        }\n        return contador;\n    }\n\n    public static void main(String[] args) {\n    \n        saludo();\n        unParametro(1);\n        variosParametros(5, 8, 4);\n        System.out.println(conRetorno());\n        System.out.println(retornoConParametro(5));\n        System.out.println(retornoConParametros(6, 12, 25));\n        System.out.println(raizCuadrada(5));\n        System.out.println(variableGlobal);\n        System.out.println(funcionVariableLocal());\n        // System.out.println(variableLocal); Esto va a marcar error porque va a decir que la variable no esta definida\n        System.out.println(dificltadExtra(\"Hola\", \"Adios\"));\n\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/Dredux2.java",
    "content": "/*\r\n * EJERCICIO:\r\n * - Crea ejemplos de funciones básicas que representen las diferentes\r\n *   posibilidades del lenguaje: Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\r\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\r\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\r\n * - Debes hacer print por consola del resultado de todos los ejemplos.\r\n */\r\npackage org.example;\r\nimport java.util.Random;\r\nclass Dredux {\r\n    public static void main(String[] args) {\r\n        Random rm = new Random();\r\n        funcionSimple();\r\n        funcionParametros();\r\n        System.out.println(\"El resultado de la funcion de retorno es: \" + funcionRetorno());\r\n        funcionJava(rm);\r\n        funcionLocal(rm);\r\n        funcionGlobal();\r\n        System.out.println(\"\\nNumeros totales: \" + funcionExtra(\"Multiplo de 3\", \"Multiplo de 5\"));\r\n    }\r\n\r\n    // 1)\r\n    // Funcion simple sin parametros ni retorno\r\n    public static void funcionSimple() {\r\n        System.out.println(\"Hola, soy una funcion simple\");\r\n    }\r\n\r\n    // Funcion con un parametro\r\n    public static void funcionParametros() {\r\n        String nombre = \"Juan\";\r\n        int edad = 25;\r\n        System.out.println(\"Hola, soy una funcion, mi nombre es \" + nombre + \" y tengo \" + edad + \" años\");\r\n    }\r\n\r\n    // Funcion con retorno\r\n    public static int funcionRetorno() {\r\n        return 5;\r\n    }\r\n\r\n    // 2)\r\n    public static void funcionJava(Random rm) {\r\n        int a = rm.nextInt(51);\r\n        int b = rm.nextInt(51);\r\n        int mayor = Math.max(a, b);\r\n        System.out.println(\"El valor máximo entre \" + a + \" y \" + b + \" es: \" + mayor);\r\n    }\r\n\r\n    // 3)\r\n    // Variable local\r\n    public static void funcionLocal(Random rm) {\r\n        int x = rm.nextInt(11);\r\n        System.out.println(\"Variable local: \" + x);\r\n    }\r\n\r\n    // Variable global\r\n    static int y = 20;\r\n    public static void funcionGlobal() {\r\n        System.out.println(\"Variable global: \" + y);\r\n        System.out.println();\r\n    }\r\n\r\n    /*\r\n     * DIFICULTAD EXTRA (opcional):\r\n     * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\r\n     * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\r\n     *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\r\n     *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\r\n     *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\r\n     *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\r\n     */\r\n\r\n    public static int funcionExtra(String a, String b) {\r\n        int count = 0;\r\n        for (int num = 1; num <= 100; num++) {\r\n            if (num % 3 == 0 && num % 5 == 0) {\r\n                System.out.println(num + \" es \" + a + \" y \" + b);\r\n            } else if (num % 3 == 0) {\r\n                System.out.println(num + \" es \" + a);\r\n            } else if (num % 5 == 0) {\r\n                System.out.println(num + \" es \" + b);\r\n            } else {\r\n                System.out.println(num);\r\n                count++;\r\n            }\r\n        }\r\n        return count;\r\n    }\r\n}\r\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/Fluna29.java",
    "content": "package practicas;\n\npublic class Main {\n    public static void main(String[] args) {\n        \n\n        //Función sin parametro ni retorno\n        System.out.println(\"\\nFunción sin parametro ni retorno\");\n        saludar();\n\n        //Función con uno o varios parametros y sin retorno\n        System.out.println(\"\\nFunción con uno o varios parametros y sin retorno\");\n        sumar(5, 3);\n\n        //Función con uno o varios parametros y con retorno\n        System.out.println(\"\\nFunción con uno o varios parametros y con retorno\");\n        System.out.println(saludarPersona(\"Manolo\"));\n\n        //Función privada\n        System.out.println(\"\\nFunción privada\");\n        funcionPrivada(); //No se puede llamar a una función privada desde fuera de la clase, es decir, desde fuera de este archivo.\n\n        //Función que retorna el número de letras de una palabra, haciendo uso del método ya creado .length()\n        System.out.println(\"\\nFunción que retorna el número de letras de una palabra\");\n        System.out.println(contarLetras(\"Esternocleidomastoideo\"));\n\n\n        /**\n         * DIFICULTAD EXTRA (opcional):\n         * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n         * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n         *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n         *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n         *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n         *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n         */\n        System.out.println(\"\\nDIFICULTAD EXTRA (opcional):\");\n        System.out.println(\"\\nLas veces que se ha devuelto un número son: \" + reto(\"Hola\", \"Adiós\"));\n\n    }\n    //Función sin parametro ni retorno\n    public static void saludar(){\n        System.out.println(\"\\nHola\");\n    }\n\n    //Función con uno o varios parametros y sin retorno\n    public static void sumar(int a, int b){\n        System.out.println(\"\\nEl resultado de la suma es: \" + (a+b));\n    }\n\n    //Función con uno o varios parametros y con retorno\n    public static String saludarPersona(String nombre){\n        return \"\\nHola \" + nombre;\n    }\n\n    /**\n     * Si usamos public como antes son funciones a nivel global,\n     * pero a continuación, vamos a hacer una función privada que solo se puede usar dentro de la clase.\n     * Para ello vamos a hacer uso de la palabra reservada private.\n     */\n\n    private static void funcionPrivada(){\n        System.out.println(\"\\nSoy una función privada\");\n    }\n\n    //Función que retorna el número de letras de una palabra, haciendo uso de una función ya creada, llamada .length()\n    public static String contarLetras(String palabra){\n        return (\"\\nLa palabra \" + palabra + \" tiene \" + palabra.length() + \" letras\");\n    }\n\n    /**\n     * DIFICULTAD EXTRA (opcional):\n     * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n     * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n     *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n     *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n     *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n     *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n     */\n\n    public static Integer reto(String palabra1, String palabra2){\n        int contadorNumerosMostrados = 0;\n        for(int i = 1; i <= 100; i++){\n            if(i% 5 == 0 && i % 3 == 0){\n                System.out.println(palabra1 + palabra2);\n            }else if(i % 5 == 0 && i % 3 != 0){\n                System.out.println(palabra2);\n            }else if(i % 5 != 0 && i % 3 == 0){\n                System.out.println(palabra1);\n            }else{ \n                System.out.println(i);\n                contadorNumerosMostrados++;\n            }\n        }\n        return contadorNumerosMostrados;\n    }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/FranDev200.java",
    "content": "import java.util.Calendar;\n\npublic class FranDev200 {\n\n    static Calendar calendar = Calendar.getInstance();\n    static int currentYear = calendar.get(Calendar.YEAR);\n\n    static void main() {\n        /*\n            - Crea ejemplos de funciones básicas que representen las diferentes\n            posibilidades del lenguaje:\n            Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n         */\n\n        welcome();\n        System.out.println(\"Este año, cumples \" + age(2005) + \" años.\");\n        info(\"Franciso\", 20, \"Desarrollador de Software\");\n        payRise(\"Fran\", 2000, 15);\n\n        /*\n            DIFICULTAD EXTRA (opcional):\n            Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n            - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n            - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n            - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n            - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n            - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\n         */\n\n        System.out.println(\"Numero de veces que se ha impreso solo el numero: \" + printNumber(\"Hola Java\", \"Adios Java\"));\n\n    }\n\n        /*\n            - Crea ejemplos de funciones básicas que representen las diferentes\n            posibilidades del lenguaje:\n            Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n         */\n\n    public static void welcome(){\n        System.out.println(\"Bienvenido a los retos de programación\");\n    }\n\n    public static int age (int yearOfBirth){\n\n        int age = FranDev200.currentYear - yearOfBirth;\n        return age;\n    }\n\n    public static void info(String name, int age, String work){\n        System.out.println(name + \" tiene \" + age + \" años y su trabajo es ser \" + work);\n    }\n\n    public static void payRise(String name, double actualSalary, int ageExperience){\n\n        double newSalary = actualSalary + (actualSalary * percentageIncrease(ageExperience) / 100);\n\n        System.out.println(name + \" ha pasado de cobrar \" + actualSalary + \"€, a cobrar \"  + newSalary + \"€.\" );\n        System.out.println(\"Esto es gracias a sus \" + ageExperience + \" años de experiencia en el sector.\");\n\n    }\n\n    private static double percentageIncrease(int ageExperience){\n\n        int percentage = 0;\n\n        if(ageExperience == 0){\n            percentage = 0;\n        }else if(ageExperience == 1){\n            percentage = 10;\n        } else if (ageExperience < 5) {\n            percentage = 20;\n        }else if(ageExperience < 10){\n            percentage = 30;\n        }else if(ageExperience >= 10){\n            percentage = 40;\n        }\n\n        return percentage;\n    }\n\n        /*\n            DIFICULTAD EXTRA (opcional):\n            Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n            - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n            - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n            - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n            - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n            - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\n         */\n\n    public static int printNumber(String text1, String text2){\n\n        int onlyNumberPrint = 0;\n\n        for (int i = 1; i <= 100; i++){\n\n            if( (i % 3) == 0 && (i % 5) == 0){\n                System.out.println(text1 + \"  ||  \" + text2);\n\n            }else if( (i % 3) == 0){\n                System.out.println(text1);\n            }else if( (i % 5) == 0){\n                System.out.println(text2);\n            }else{\n                System.out.println(i);\n                onlyNumberPrint++;\n            }\n\n        }\n\n        return onlyNumberPrint;\n\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/FrancoFMV.java",
    "content": "import java.time.LocalDateTime;\nimport java.util.Random;\nimport java.util.Scanner;\n\npublic class FrancoFMV {\n    public static void main(String[] args) {\n        holaMundo();\n        suma(2,2);\n        saludo(\"Franco\");\n        edad(\"Juan\",18);\n        System.out.println(por5(10));\n        int x = 4;\n        int y = 5;\n        int z = multiplicacion(x,y);\n        System.out.println(\"la multiplicacion entre \"+x+\"*\"+y+\"=\"+z);\n        checkEdad(20);\n        checkEdad(15);\n        LocalDateTime ahora = LocalDateTime.now();\n        System.out.println(\"La fecha es: \" +ahora);\n        System.out.println(\"un numero random entre 1 y 10: \"+random());\n        multiplScanner(y, z);\n        String str1 = \"Fizz\";\n        String str2 = \"Buzz\";\n        ejExtra(str1, str2);\n    }\n\n    static void holaMundo(){\n        System.out.println(\"¡Hola Mundo!\");\n    }\n\n    static void suma(int a, int b){\n        System.out.println(\"La suma de \"+a+\" + \"+b+\" es: \" + (a+b));\n    }\n\n    static void saludo(String nombre){\n        System.out.println(\"Hola, \"+nombre); \n    }\n\n    static void edad(String nombre, int edad){\n        System.out.println(\"Mi nombre es \"+nombre+\", tengo \"+edad+\" años.\");\n    }\n\n    static int por5(int x){\n        return x * 5;\n    }\n\n    static int multiplicacion(int x, int y){\n        return x*y;\n    }\n\n    static void checkEdad(int edad){\n        if  (edad < 18) {\n            System.out.println(\"Acceso denegado, eres menor de edad\");\n        }else{\n            System.out.println(\"Acceso consedido, ya eres mayor de edad\");\n        }\n    }\n\n    static void localDateTime(){\n        LocalDateTime now = LocalDateTime.now();\n        System.out.println(\"Fecha y Hora actual: \" + now);\n    }\n\n    static int random(){\n        Random rnd = new Random();\n        int n = rnd.nextInt(10) + 1; \n        return n;\n    }\n\n    static void multiplScanner(int a,int b){\n        Scanner sc=new Scanner(System.in);\n        System.out.print(\"Ingrese el primer numero: \");\n        a=sc.nextInt();\n        System.out.print(\"Ingrese el segundo numero: \");\n        b=sc.nextInt();\n        System.out.println(\"La multiplicacion es: \" +multiplicacion(a,b));\n        sc.close();\n    }\n\n    static void ejExtra(String str1, String str2){\n        int cont=0;\n        for(int i=1; i<=100; i++){\n            if (i%3==0 && i%5==0){\n                System.out.println(str1+str2);\n            }else if(i%3==0){\n                System.out.println(str1);\n            }else if(i%5==0){\n                System.out.println(str2);\n            }else{\n                System.out.println(i);\n                cont++;\n            }\n        }\n        System.out.println(\"Se imprimió el numero una cantidad de: \"+cont+\" veces\");\n    }\n    \n        \n}\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/FreedAInew.java",
    "content": "import java.time.LocalDate;\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class FreedAInew {\n\n    private static final int TERMINAL_WIDTH = 80;  // Width of the terminal for centering text\n    private static int totalCakesBaked = 0;  // Simulated global variable to keep track of total cakes baked\n\n    public static void main(String[] args) {\n        // BASIC FUNCTIONS\n        // Demonstrating basic Java functionality\n        printCurrentDate();  // Without parameters and without return\n\n        LocalDate currentDate = getCurrentDate();  // Without parameters and with return\n        System.out.println(\"Current date (returned): \" + currentDate);\n\n        printDate(LocalDate.of(2023, 5, 31));  // With parameters and without return\n\n        String formattedDate = formatDate(LocalDate.of(2024, 5, 31));  // With parameters and with return\n        System.out.println(formattedDate);\n\n        // FUNCTIONS WITHIN FUNCTIONS\n        ScarsToYourBeautiful();  // Centered text output\n\n        // FUNCTION ALREADY CREATED IN THE LANGUAGE\n        // Display anime titles and release dates\n        displayAnimeList();  // Example of functions already created in the language\n\n        // VARIABLE LOCAL y GLOBAL.\n        // Demonstrate local and global variables\n        bakeCakes(\"Benjamin\", 5); // Benjamin bakes 5 cakes\n        bakeCakes(\"Benjamin\", 3); // Benjamin bakes 3 more cakes\n        bakeCakes(\"Itamar\", 7); // Itamar bakes 7 cakes\n\n        // Print total cakes baked in the bakery (simulated global result)\n        System.out.println(\"Total cakes baked in the bakery: \" + totalCakesBaked);\n\n        // Print numbers from 1 to 100 with specific conditions\n        String text1 = \"M(3)\";\n        String text2 = \"M(5)\";\n        int count = printNumbersWithTexts(text1, text2);\n        System.out.println(\"Total numbers printed: \" + count);\n    }\n\n    // Demonstrating basic Java functionality\n\n    // Function without parameters and without return\n    private static void printCurrentDate() {\n        LocalDate date = LocalDate.now();\n        System.out.println(\"Current date: \" + date);\n    }\n\n    // Function without parameters with return\n    private static LocalDate getCurrentDate() {\n        return LocalDate.now();\n    }\n\n    // Function with parameters and without return\n    private static void printDate(LocalDate date) {\n        System.out.println(\"Provided date: \" + date);\n    }\n\n    // Function with parameters and with return\n    private static String formatDate(LocalDate date) {\n        return \"Formatted date: \" + date;\n    }\n\n    // Function demonstrating the use of inner classes and lambda expressions\n    private static void ScarsToYourBeautiful() {\n        System.out.println(centerText(\"She just wants to be\"));\n\n        // Define an anonymous inner class\n        Runnable runnable1 = new Runnable() {\n            @Override\n            public void run() {\n                System.out.println(centerText(\"beautiful She goes\"));\n            }\n        };\n\n        // Call the run method of the anonymous inner class\n        runnable1.run();\n\n        // Define a lambda expression\n        Runnable runnable2 = () -> {\n            System.out.println(centerText(\"unnoticed, she knows no limits She craves\"));\n        };\n\n        // Call the run method of the lambda expression\n        runnable2.run();\n    }\n\n    // Method to center text in the terminal\n    private static String centerText(String text) {\n        int padding = (TERMINAL_WIDTH - text.length()) / 2;\n        StringBuilder paddedText = new StringBuilder();\n        for (int i = 0; i < padding; i++) {\n            paddedText.append(\" \");\n        }\n        paddedText.append(text);\n        return paddedText.toString();\n    }\n\n    // Demonstrate local and global variables\n    // Method to add cakes to the total count (simulated global update)\n    private static void addCakesToTotal(int cakes) {\n        totalCakesBaked += cakes;\n    }\n\n    // Method for a baker to bake cakes\n    private static void bakeCakes(String name, int cakes) {\n        // Local variable to keep track of cakes baked by this baker in this method call\n        int cakesBakedByThisBaker = cakes;\n\n        // Simulate the baker baking cakes\n        System.out.println(name + \" baked \" + cakesBakedByThisBaker + \" cakes.\");\n\n        // Update the global-like total cakes baked\n        addCakesToTotal(cakesBakedByThisBaker);\n    }\n\n    // Method to display a list of anime titles and their release dates\n    private static void displayAnimeList() {\n        // Create a list of anime titles and release dates\n        List<String[]> animeList = new ArrayList<>();\n        animeList.add(new String[]{\"Tensei Shitara Dai Nana\", \"June 6, 2024\"});\n        animeList.add(new String[]{\"KonoSuba: God’s Blessing on This Wonderful World!\", \"June 06, 2024\"});\n        animeList.add(new String[]{\"Kaiju No. 8\", \"June 06, 2024\"});\n        animeList.add(new String[]{\"Ranger Reject\", \"June 06, 2024\"}); // Note: Release date is in July, but included for demonstration purposes.\n\n        // Display the anime list\n        System.out.println(\"Popular Anime of June 2024:\");\n        for (String[] anime : animeList) {\n            System.out.println(\"- \" + anime[0] + \" (\" + anime[1] + \")\");\n        }\n    }\n\n    // Method to print numbers from 1 to 100 with specific conditions\n    private static int printNumbersWithTexts(String text1, String text2) {\n        int count = 0;\n        for (int i = 1; i <= 100; i++) {\n            if (i % 3 == 0 && i % 5 == 0) {\n                System.out.println(text1 + text2);\n            } else if (i % 3 == 0) {\n                System.out.println(text1);\n            } else if (i % 5 == 0) {\n                System.out.println(text2);\n            } else {\n                System.out.println(i);\n                count++;\n            }\n        }\n        return count;\n    }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/Gerthai08.java",
    "content": "public class Gerthai08 {\n\n    public static void main(String[] arg) {\n\n        //Instanciación del objeto para llamar a los procedimientos y metodos con retorno.\n        Gerthai08 procedimiento = new Gerthai08();\n\n        //Llamando función con retorno\n        double resultado = retornaSuma(5, 2);\n        System.out.println(\"======Función con retorno======\");\n        System.out.println(resultado);\n\n        //Llamando función sin retorno\n        System.out.println(\"======Función sin retorno======\");\n        texto();\n\n        //llamando procedimiento\n        System.out.println(\"======Llamado al procedimiento======\");\n        procedimiento.procedimiento(5,4);\n\n\n        //En java no se puede crear una funcion dentro de otra, pero si llamar\n        System.out.println(\"======Llamando a función dentro de otra======\");\n        double funcionDentroDeFuncion = retornaSuma(retornarMultiplicacion(2,3),5);\n        System.out.println(funcionDentroDeFuncion);\n\n        //llamada a la función del desafio extra\n        System.out.println(\"======Desafio extra======\");\n        int cantidadNumeros = multiplo(\"Fizz\",\"Buzz\");\n        System.out.println(\"se imprimieron números \" + cantidadNumeros + \" veces.\");\n    }\n\n    //Funciones basicas\n    //Función con retorno\n    public static int retornaSuma(int a, int c) {\n        return a + c;\n    }\n\n    public static int retornarMultiplicacion(int x, int p){\n        return x * p;\n    }\n\n    //Función sin retorno\n    public static void texto() {\n        System.out.println(\"Este es un texto de una funcion sin retorno\");\n    }\n\n    //Procedimiento\n    void procedimiento(int n, int b){\n        if (n > b){\n            System.out.println(n + \"es mayor que \" + b);\n            return;\n        }\n        System.out.println((n + \"es menor que \" + b));\n    }\n\n    //Desafio extra\n    public static int multiplo(String palabra1, String palabra2){\n        //Contador del bucle for para el reto extra\n        int contador = 0;\n\n        for (int i = 0; i <= 100 ; i++) {\n            if (i % 3 == 0 && i % 5 == 0){\n                System.out.println(palabra1 + palabra2);\n            }else if (i % 3 == 0){\n                System.out.println(palabra1);\n            }else if (i % 5 == 0){\n                System.out.println(palabra2);\n            }else{\n                System.out.println(i);\n                contador++;\n            }\n        }\n        return contador;\n    }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/Guillermo-Munoz.java",
    "content": "public class GuillermoMunoz {\n    /*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n    // Variables globales (ámbito de clase)\n    static String variableGlobal = \"Java\";\n    static int contadorGlobal = 0;\n    public static void main(String[] args) {\n        // VARIABLES LOCALES (ámbito de main)\n        int contadorLocal = 0;\n        System.out.println(\"=== EJEMPLOS DE FUNCIONES ===\\n\");\n        \n        // 1. Función sin parámetros y sin retorno\n        System.out.println(\"1. Función sin parámetros y sin retorno:\");\n        andar();\n\n        // 2. Funcion con parametros y sin retorno\n        System.out.println(\"\\n2. Función con parámetros y sin retorno:\");\n        andar(\"la ciudad\"); \n\n        // 3. Función con retorno y sin parametros\n        System.out.println(\"\\n3. Función con retorno y sin parámetros:\");       \n        String saludo = saludar();\n        System.out.println(saludo);\n\n        // 4. Funcion con retorno y con parametros\n        System.out.println(\"\\n4. Función con retorno y con parámetros:\");\n        System.out.println(saludar(\"Guillermo\"));\n\n        // 5. Funcion con numero variable dce argumentos\n        System.out.println(\"\\n5. Función con número variable de argumentos:\");\n        variosSaludos(\"Ana\", \"Luis\", \"Carlos\");\n\n        // 6. Funciones dentro de funciones\n        System.out.println(\"\\n6. Funciones dentro de funciones:\");\n        funcionPrincipal();\n\n        // 7. Funciones ya creadas en el lenguaje\n        System.out.println(\"\\n7. Funciones ya creadas en el lenguaje:\");\n        String texto = \"Hola MoureDev\";\n        System.out.println(\"Longitud del texto: \" + texto.length());\n        \n        // 8. Variable global y local\n        System.out.println(\"\\n8. Variable global y local:\");\n        System.out.println(\"Variable global: \" + variableGlobal);\n        System.out.println(\"Contador global antes: \" + contadorGlobal);\n        contadorGlobal++;\n        System.out.println(\"Contador global después: \" + contadorGlobal);\n        System.out.println(\"Contador local: \" + contadorLocal);\n\n        // Ejercicio extra\n        System.out.println(\"\\n=== EJERCICIO EXTRA ===\");\n        int vecesImpresas = ejercicioExtra(\"hola\", \"mundo\");\n        System.out.println(\"Número de veces que se imprime un número en lugar de texto: \" + vecesImpresas);\n\n\n    }\n    // Función sin parametros y sin retorno\n        static void andar() {\n            System.out.println(\"Estoy andando\");\n        }\n\n        // Funcion con parametros y sin retorno\n        static void andar(String lugar) {\n            System.out.println(\"Estoy andando en; \" + lugar);\n        }\n\n        // Función con retorno y sin parametros\n        static String saludar() {\n            return \"Hola, soy una función con retorno\";\n        }\n\n        // Función con retorno y con parametros\n        static String saludar(String name) {\n            return \"hola,  \" + name;\n        }\n\n        // Función con número variable de argumentos\n        static void variosSaludos(String... nameStrings) {\n            for (String name: nameStrings) {\n                System.out.println(\"Hola, \" + name );\n            }\n        }\n\n        // Fuynciones dentro de funciones\n        static void funcionPrincipal(){\n            andar();\n            System.out.println(\"Funcion interna\");\n        }\n\n        // Ejercicio estra\n\n        static int ejercicioExtra(String texto1, String texto2) {\n            int contadorNumeros = 0;\n        \n            for ( int i = 1; i <= 100; i++) {\n\n                if(i % 3 == 0 && i % 5 == 0){\n                    System.out.println(texto1 + texto2);\n                        contadorNumeros++;\n                }else if (i % 3 == 0){\n                    System.out.println(texto1);\n                    contadorNumeros++;\n                }else if(i % 5 == 0){\n                    System.out.println(texto2);\n                    contadorNumeros++;\n                }else{\n                    System.out.println(i);\n                }\n        }\n        return contadorNumeros;\n        }\n\n\n    }\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/GustavoGomez19.java",
    "content": "public class GustavoGomez19 {\n\n    // Punto 1: Funciones básicas\n    // Función sin parámetros ni retorno de valor\n    private static void sinParamatrosNiRetorno() {\n        System.out.println(\"Función sin parámetros ni retorno de valor\");\n    }\n\n    // Función con parámetros\n    private static void saludar(String saludo) {\n        System.out.println(saludo);\n    }\n\n    // Función con varios parámetros y retorno de valor\n    private static int sumar(int num1, int num2) {\n        return num1 + num2;\n    }\n\n    // Punto 2: Funciones anidadas\n    private static String funcion(String value) {\n        return value;\n    }\n\n    private static void funcionAnidada(String value, int a, int b) {\n        System.out.println(\"Hola \" + funcion(value) + \" La suma de los 2 valores a y b es: \" + sumar(a, b));\n    }\n\n    // Punto dificultad extra\n    private static int desafioExtra(String texto1, String texto2) {\n        int contador = 0;\n        for (int num = 1; num <= 100; num++) {\n            if (num % 3 == 0 && num % 5 == 0) {\n                System.out.println(texto1 + \" \" + texto2);\n            } else if (num % 3 == 0) {\n                System.out.println(texto1);\n            } else if (num % 5 == 0) {\n                System.out.println(texto2);\n            } else {\n                System.out.println(num);\n                contador += 1;\n            }\n\n        }\n        System.out.println(\"De los 100 números se imprimieron (\" + contador + \") números.\");\n        return contador;\n    }\n\n    public static void main(String[] args) {\n\n        sinParamatrosNiRetorno();\n        saludar(\"¡Hola, Java!\");\n        System.out.println(\"La suma es : \" + sumar(5, 5));\n        funcionAnidada(\"Java\", 5, 10);\n        System.out.println(desafioExtra(\"Fizz\", \"Buzz\"));\n\n        // Punto 3: Funciones del lenguaje\n        // Función Math.pow() --> eleva un número a la potencia\n        System.out.println(Math.pow(2, 3));\n        // Función println --> imprime mensaje por consola con salto de línea\n        System.out.println(\"Mensaje por consola\");\n        /*\n         * Función .length de la clase String --> permite conocer el número de\n         * caracteres de una cadena de texto\n         */\n        String nombre = \"Gustavo\";\n        int largoNombre = nombre.length();\n        System.out.println(largoNombre);\n        /* Función .toUpperCase() --> Convierte la cadena de texto a mayúscula */\n        System.out.println(nombre.toUpperCase());\n        /* Función .toULowerCase() --> Convierte la cadena de texto a minúscula */\n        System.out.println(nombre.toLowerCase());\n\n        // Punto 4: Variable local y variable global\n        /*\n         * Variable local, se ejecuta solo dentro del ambito donde es declarada\n         * si se intenta ejecutar desde afuera de ese ambito el resultado sería un error\n         */\n        // Declaracioón de variable global\n        int edad = 31;\n        {\n            String variableLocal = \"Esta es una variable local \";\n            System.out.println(variableLocal + \"\\n\" + \"Valor de la variable global \" + edad);\n            /*\n             * Se hace el llamado de la variable 'edad' la cual está definidad por fuera\n             * de este bloqued de código y se ejecuta sin problema\n             */\n        }\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/Jeigar2.java",
    "content": "import java.time.LocalTime;\nimport java.util.Timer;\nimport java.util.TimerTask;\nimport java.util.stream.IntStream;\n\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\npublic class Jeigar2 {\n    // Son variables \"Globales\"\n    private static final int SEGUNDO = 1000; // milisegundos\n    private static int cuentaAtras = 0;\n    private static boolean activaCuentaAtras = false;\n    private static Timer timer;\n\n    public static void main(String[] args) {\n        int segundos = 3; // variable local\n        timer = new Timer();\n        mostrarHoraActual();\n        if(!isActivaCuentaAtras()) {\n            configurarCuentaAtras(segundos);\n            System.out.println(\"Total segundos para configurar la cuenta atrás \" + segundos); // función ya creada en el sistema\n            if(isActivaCuentaAtras()){\n                mostrarMensajeInicializarCuentaAtras();\n                iniciarCuentaAtrás();\n            }\n        }\n        mostrarHoraActual();\n        System.out.println( \"Total numero no primos de 3 y 5 son: \" + extra(\"solo uno\", \"ambos\"));\n    }\n\n    // funcion con uno parámetro sin retorno\n    public static void configurarCuentaAtras (int segundos){\n        cuentaAtras = segundos;\n        activarCuentaAtras();\n    }\n\n    // funcion sin parámetros ni retorno\n    private static void activarCuentaAtras(){\n        activaCuentaAtras = true;\n    }\n\n    // funcion sin parámetros ni retorno\n    public static void iniciarCuentaAtrás(){\n        // No puedo crear una función dentro de una función\n        // Pero puedo desde un método llamar a de una clase anónima que tiene su propia función.\n        timer.schedule(new TimerTask() {\n            @Override\n            public void run() {\n                activaCuentaAtras = false;\n                mostrarMensajeFinalizadaCuentaAtras();\n                timer.cancel(); // función ya creada en el sistema\n                System.out.println(\"si te fijas bien han pasado \" + cuentaAtras + \" segundos\");\n            }\n        }, cuentaAtras * SEGUNDO);\n    }\n\n    // funcion sin parámetros con retorno\n    public static boolean isActivaCuentaAtras() {\n        return activaCuentaAtras;\n    }\n\n    // funcion sin parámetros ni retorno\n    public static void mostrarHoraActual () {\n        System.out.println(\"Son las \" + LocalTime.now());  // función ya creada en el sistema\n    }\n\n    // funcion sin parámetros ni retorno que llama a una función que tiene un parametro y a otra funcion que no tiene parametros\n    public static void mostrarMensajeFinalizadaCuentaAtras(){\n        mostrarMensajeCuentaAtrasConTexto(\"finalizado\");\n        mostrarHoraActual();\n    }\n\n    // funcion sin parámetros ni retorno que llama a una función que tiene un parametro\n    public static void mostrarMensajeInicializarCuentaAtras(){\n        mostrarMensajeCuentaAtrasConTexto(\"iniciado\");\n    }\n\n    // funcion con parámetros sin retorno\n    private static void mostrarMensajeCuentaAtrasConTexto (String texto){\n        System.out.println(\"La cuenta atrás ha \" + texto);  // función ya creada en el sistema\n    }\n\n    /*\n     * DIFICULTAD EXTRA (opcional):\n     * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n     * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n     *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n     *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n     *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n     *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n     */\n\n    private static int extra(String cadena1, String cadena2){\n        int inicioRango = 1;\n        int finRango = 100;\n        long totaMultiplos = IntStream.rangeClosed(inicioRango,finRango)\n                .filter( number -> number % 3 == 0 || number % 5 == 0 ) // solo quiero los múltiplos de 3 y 5\n                .peek(number -> {\n                    if(number % 3 == 0 && number % 5 == 0) { // si es múltiplo de ambos\n                        System.out.println(number + \" \" + cadena2);\n                    } else if (number % 3 == 0 || number % 5 == 0 ) { // si es solo múltiplo de uno de los dos\n                        System.out.println(number + \" \" + cadena1);\n                    }\n                })\n                .count(); // total de múltiplos\n        return (int) (finRango - totaMultiplos);\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/JerrySantana.java",
    "content": "class JerrySantana {\n    public static String variable = \"Esto es una variable global.\";\n    \n    public static void main(String[] args) {\n        funcionSimple();\n        funcionUnParametro(\"Hola mundo\");\n        funcionVariosParametros(\"Hola mundo\", 10, 1.5f, 'g', false);\n        System.out.println(funcionRetorno());\n        System.out.println(funcionParametrosRetorno(\"Hola mundo\", 10, 1.5f, 'g', false));\n        funcionAnidada();\n        funcionesLenguaje();\n        variablesLocalGlobal();\n        funcionExtra(\"Lorem\", \"Ipsum\");\n    }\n    \n    static void funcionSimple() {\n        System.out.println(\"Esto es una funcion sencilla, no recibe parametros ni retorna ningun valor.\");\n        System.out.println(\"Solamente ejecuta el codigo dentro de ella.\");\n        System.out.println(\"----------------------------------------------------------------------------\");\n    }\n    \n    static void funcionUnParametro(String parametro) {\n        System.out.println(\"Esta es una funcion que recibe solamente un parametro.\");\n        System.out.println(\"El parametro en este caso es solamente un objeto de tipo String (cadena de caracteres).\");\n        System.out.println(\"Este es el valor del parametro recibido: '\" + parametro + \"'.\");\n        System.out.println(\"Este parametro es una variable local, y solamente existe durante la ejecución de la función, una vez que finaliza desaparece.\");\n        System.out.println(\"----------------------------------------------------------------------------\");\n    }\n    \n    static void funcionVariosParametros(String parametro, int numero, float decimal, char caracter, boolean bool) {\n        System.out.println(\"Esta es una funcion que recibe varios parametros, todos son diferentes.\");\n        System.out.println(\"Recibimos un parametro de tipo String, otro de tipo short, uno de tipo float, uno de tipo char y uno de tipo booleano.\");\n        System.out.println(\"El valor del parametro String es: '\" + parametro + \"'.\");\n        System.out.println(\"El valor del parametro int es: '\" + numero + \"'.\");\n        System.out.println(\"El valor del parametro float es: '\" + decimal + \"'.\");\n        System.out.println(\"El valor del parametro char es: '\" + caracter + \"'.\");\n        System.out.println(\"El valor del parametro booleano es: '\" + bool + \"'.\");\n        System.out.println(\"Estos parametros son variables locales, solamente existen durante la ejecución de la función, una vez que finaliza desaparecen.\");\n        System.out.println(\"----------------------------------------------------------------------------\");\n    }\n    \n    static String funcionRetorno() {\n        return \"Esta es una funcion que retorna un valor, el valor de retorno puede ser de cualquier tipo y depende del tipo de retorno asignado a la funcion.\\n\" +\n                \"Este valor retornado puede ser el contenido de una variable o un valor especifico. A pesar de eso, las variables creadas y retornadas dentro \\n\" +\n                \"de esta funcion, son variables locales, ya que su valor es reasignado a otra variable antes de desaparecer al finalizar la ejecucion.\\n\" +\n                \"Las funciones en Java solamente pueden retornar un solo valor de un solo tipo.\\n\" +\n                \"----------------------------------------------------------------------------\";\n    }\n    \n    static String funcionParametrosRetorno(String parametro, int numero, float decimal, char caracter, boolean bool) {\n        return \"Se pueden hacer combinaciones de las anteriores, como una funcion que reciba uno o mas parametros y retorno un valor.\\n\" +\n                \"En este caso la funcion recibe un parametro de tipo String, otro de tipo int, uno de tipo float, uno de tipo char y uno de tipo booleano.\\n\" +\n                \"Los parametros son los siguientes:\\n String: '\" + parametro + \"'\\nint: '\" + numero + \"'\\nfloat: '\" + decimal + \"'\\nchar: '\" + caracter +\"'\\nbooleano: '\" + bool + \"'.\\n\" +\n                \"----------------------------------------------------------------------------\";\n    }\n    \n    static void funcionAnidada() {\n        Anidada.anidada(() -> {\n            System.out.println(\"Inicio funcion lambda...\\n\" +\n                    \"Las funciones lambda o expresiones lambda son funciones anonimas. Pueden recibir uno o mas parametros dentro de ellas y retornar un valor.\\n\" +\n                    \"Al ser declaradas al mismo tiempo de ser usadas, puede acceder a las variables locales del ambito al que pertenece pero sin poder modificarlas.\\n\" +\n                    \"Esta es una forma de declarar funciones dentro de otra funcion.\\n\" +\n                    \"Fin funcion lambda...\\n\");\n        });\n        System.out.println(\"----------------------------------------------------------------------------\");\n    }\n    \n    static void funcionesLenguaje() {\n        System.out.println(\"La funcion 'System.out.prinln()' es una función que recibe como parametros un valor y lo imprime en terminal. Esta es una funcion propia del lenguaje.\");\n        int[] numeros = {9, 6, 3, 2, 4};\n        System.out.println(\"La funcion length es propia del lenguaje y nos permite conocer el numero de elementos dentro de un arreglo. En este caso nuestro arreglo es: {9, 6, 3, 2, 4}, y su longitud es: \" + numeros.length + \".\");\n        System.out.println(\"----------------------------------------------------------------------------\");\n    }\n    \n    static void variablesLocalGlobal() {\n        String variable = \"Esto es una varible local.\";\n        System.out.println(\"Las variables globales son accesibles desde cualquier parte del programa, y duran mientras el programa se ejecute.\");\n        System.out.println(\"Las variables locales son accesibles solamente dentro de la funcion o clase donde son declaradas, y solamente duran hasta que ya no son utilizadas por la funcion o clase que las llama.\");\n        System.out.println(\"Este es el valor de la variable global: \" + JerrySantana.variable);\n        System.out.println(\"Este es el valor de la variable local: \" + variable);\n        System.out.println(\"----------------------------------------------------------------------------\");\n    }\n    \n    interface Lambda {\n        void lambda();\n    }\n    \n    class Anidada {\n        public static void anidada(Lambda funcion) {\n            funcion.lambda();\n        }\n    }\n    \n    static int funcionExtra(String cadenaUno, String cadenaDos) {\n        int contador = 0;\n        \n        for(int i = 0; i < 101; i++) {\n            if (i % 3 == 0 && i % 5 == 0) {\n                System.out.println(cadenaUno + \" \" + cadenaDos + \".\");\n            } else if(i % 3 == 0) {\n                System.out.println(cadenaUno);\n            } else if(i % 5 == 0) {\n                System.out.println(cadenaDos);\n            } else {\n                System.out.println(i);\n                contador++;\n            }\n        }\n        \n        return contador;\n    }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/JesusAntonioEEscamilla.java",
    "content": "/** #02 - Java -> Jesus Antonio Escamilla */\n\npublic class JesusAntonioEEscamilla {\n    //  Variable Global\n    static String globalVariable = \"Soy Global\";\n    public static void main(String[] args) {\n    //---EJERCIÓ---\n        //  Función Básica\n        saludar();\n        //  Función con Parámetro\n        personalizado(\"Antonio\");\n        //  Función con Varios Parámetros\n        sumar(3, 8);\n        //  Función con Retorno\n        int resultado = multiplicar(6, 4);\n        System.out.println(\"El resultado de la multiplicación es \" + resultado);\n        //  Funciones dentro de Funciones\n        int[] resultados = operacionesComplejas(8, 4);\n        System.out.println(\"La resta es \" + resultados[0] + \" y la division es \" + resultados[1]);\n        //  Variables Global y Local\n        my_Function();\n\n    //---EXTRA---\n        EXTRA(\"FIZZ\", \"BUZZ\");\n    }\n\n    // Función Básica\n    public static void saludar(){\n        System.out.println(\"¡¡Hola, Soy Jesus!!\");\n    }\n\n    // Función con Parámetro\n    public static void personalizado(String nombre){\n        System.out.println(\"¡¡Hola, Mundo Soy \" + nombre + \"!!\");\n    }\n\n    // Función con Varios Parámetros\n    public static void sumar(int a, int b) {\n        System.out.println(\"La suma de \" + a + \" y \" + b + \" es \" + (a + b));\n    }\n\n    //  Función con Retorno\n    public static int multiplicar(int a, int b) {\n        return a * b;\n    }\n\n    //  Funciones dentro de Funciones\n    private static int restar(int x, int y){\n        return x - y;\n    }\n    private static int dividir(int x, int y){\n        return y / x;\n    }\n    public static int[] operacionesComplejas(int a, int b){\n        int resta = restar(3, 5);\n        int divide = dividir(20, 4);\n        return new int[] {resta, divide};\n    }\n\n    //  Variables Global y Local\n    public static void my_Function(){\n        String localVariable = \"Soy Local\";\n        System.out.println(localVariable);\n        System.out.println(globalVariable);\n    }\n\n    /**-----DIFICULTAD EXTRA-----*/\n\n    public static int EXTRA(String text1, String text2){\n        int cont = 0;\n        for(int number = 1; number <= 100; number++){\n            if (number % 3 == 0 && number % 5 == 0) {\n                System.out.println(text1 + text2);\n            } else if(number % 3 == 0){\n                System.out.println(text1);\n            } else if(number % 5 == 0){\n                System.out.println(text2);\n            } else {\n                System.out.println(number);\n            }\n            cont++;\n        }\n        return cont;\n    }\n\n    /**-----DIFICULTAD EXTRA-----*/\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/JesusEs1312.java",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\npublic class JesusEs1312 {\n    //--- Variables globales ---\n    String variableGlobal = \"Soy una variable global\";\n\n    //--- Funciones básicas ---\n    // Sin parámetros ni retorno\n    public void funcionBasica() {\n        System.out.println(\"Hola, soy una función básica sin parametros ni retorno\");\n    }\n\n    // Con un parámetro\n    public void funcionConParametro(String parametro) {\n        System.out.println(\"Hola, soy una función con un parámetro: \" + parametro);\n    }\n\n    // Con varios parámetros\n    public void funcionConVariosParametros(String parametro1, String parametro2) {\n        System.out.println(\"Hola, soy una función con varios parámetros: \" + parametro1 + \" y \" + parametro2);\n    }\n\n    // Con retorno\n    public String funcionConRetorno() {\n        return \"Hola, soy una función con retorno\";\n    }\n\n    //--- Funciones dentro de funciones ---\n    public void funcionPrincipal() {\n        System.out.println(\"Hola, soy la función principal\");\n        funcionBasica();\n    }\n\n    public static void main(String[] args) {\n        //--- Variables locales ---\n        String variableLocal = \"Soy una variable local\";\n\n        JesusEs1312 jesus = new JesusEs1312();\n        jesus.funcionBasica();\n        jesus.funcionPrincipal();\n        jesus.funcionConParametro(\"parametro\");\n        jesus.funcionConVariosParametros(variableLocal, jesus.variableGlobal);\n        System.out.println(jesus.funcionConRetorno());\n\n        //--- funciones ya creadas en el lenguaje ---\n        // Math.random() devuelve un número aleatorio entre 0.0 y 1.0\n        System.out.println(Math.random());\n        // UpperCase() convierte una cadena de texto a mayúsculas\n        System.out.println(jesus.funcionConRetorno().toUpperCase());\n        // LowerCase() convierte una cadena de texto a minúsculas\n        System.out.println(jesus.funcionConRetorno().toLowerCase());\n        // Length() devuelve la longitud de una cadena de texto\n        System.out.println(jesus.funcionConRetorno().length());\n        // Replace() reemplaza una cadena de texto por otra\n        System.out.println(jesus.funcionConRetorno().replace(\"Hola\", \"Adios\"));\n        // Substring() devuelve una subcadena de texto\n        System.out.println(jesus.funcionConRetorno().substring(0, 4));\n        // Concat() concatena dos cadenas de texto\n        System.out.println(jesus.funcionConRetorno().concat(\" con concatenación\"));\n        // Equals() compara dos cadenas de texto\n        System.out.println(jesus.funcionConRetorno().equals(\"Hola, soy una función con retorno\"));\n\n        //--- Dificultad extra ---\n        System.out.println(jesus.funcionExtra(\"Fizz\", \"Buzz\"));\n    }\n\n    //--- Dificultad extra ---\n    public int funcionExtra(String parametro1, String parametro2) {\n        int contador = 0;\n        for (int i = 1; i <= 100; i++) {\n            if (i % 3 == 0 && i % 5 == 0) {\n                System.out.println(parametro1 + parametro2);\n            } else if (i % 3 == 0) {\n                System.out.println(parametro1);\n            } else if (i % 5 == 0) {\n                System.out.println(parametro2);\n            } else {\n                System.out.println(i);\n            }\n            contador++;\n        }\n        return contador;\n   } \n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/JimsimroDev.java",
    "content": "\npublic class JimsimroDev {\n\n  // Funciones definidas pro el usuario\n  // Funcion simple\n  public static void saludar() {\n    System.out.println(\"Hola, java\");\n  }\n\n  // Funcion con retorno de caneda o texto\n  public static String stringRetorno() {\n    return \"Hola, Java\";\n  }\n\n  // Funcion con retorno de number\n  public static int intRetorno() {\n    return 30;\n  }\n\n  // Funcion con parametro el parametro que tiene la funcion en java se le conoce\n  // como parametro formal o parametros\n  // y cuando la funcion se llama y se le pasa el parametro se le conoce como\n  // parametro actual o argumentos\n  public static String argSaludo(String name) {\n    return name;\n  }\n\n  // Funcion con parametros\n  public static String argsSaludo(String saludo, String name) {\n    return saludo + name;\n  }\n\n  // Funcion con número variables de argumentos\n  public static void variosSaludos(String... names) {\n    for (String name : names) {\n      System.out.print(\" Hola, \" + name);\n    }\n    System.out.println();\n  }\n\n  // Funciones dentro de Funciones\n  public static void funcionPrincipal() {\n    saludar();\n    System.out.println(\"Funcion interna\");\n  }\n\n  // Variables globales y locales\n  String variableGlobal = \"Pyton\";\n\n  public void holaJava() {\n    var variableLocal = \"Hola, \";\n    System.out.println(variableLocal + variableGlobal);\n  }\n\n  // Dificultad extra\n  public static int mostrarNumeros(String str, String str1) {\n    int contador = 0;\n    for (int i = 0; i < 101; i++) {\n      if (i % 3 == 0 && i % 5 == 0) {\n        System.out.println(str + str1);\n      } else if (i % 3 == 0) {\n        System.out.println(str);\n      } else if (i % 5 == 0) {\n        System.out.println(str1);\n      } else {\n        System.out.println(i);\n        contador++;\n      }\n    }\n    return contador;\n  }\n\n  public static void main(String[] args) {\n    // Funcion simple\n    saludar();\n\n    // Funcion con retorno cadena de texto\n    System.out.println(stringRetorno());\n\n    // Funcion con retorno cadena de texto\n    System.out.println(intRetorno());\n\n    // Funcion con parametro\n    System.out.println(argSaludo(\"Jimmis\"));\n\n    // Funcion con parametros\n    System.out.println(argsSaludo(\"Hola,\", \" Java\"));\n\n    // Funcion con número variables de argumentos\n    variosSaludos(\"Jimmis\", \"Java\", \"Spring\", \"MySQL\");\n    variosSaludos(\"PHP\", \"Phyton\", \"GIT\");\n\n    funcionPrincipal();\n\n    JimsimroDev principal = new JimsimroDev();\n    principal.holaJava();\n\n    System.out.println(mostrarNumeros(\"texto1 \", \"texto2 \"));\n  }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/Josegs95.java",
    "content": "import java.util.Calendar;\nimport java.util.GregorianCalendar;\n\npublic class Josegs95 {\n    public static void main(String[] args) {\n        //Como voy a trabajar en el main, todos los métodos que cree serán estáticos\n        saludame();\n        System.out.println(getSaludo());\n        saludamePorMiNombre(\"Jose\");\n        System.out.println(getSaludoPorMiNombre(\"Jose\"));\n        System.out.println(getSaludoPorMiNombre(\"Jose\", \"Adiós\"));\n        System.out.println(\"La hora actual es: \" + getHora());\n        imprimeCadena();\n\n        int n = retoFinal(\"Esta es la cadena 1\", \"Esta es la cadena 2\");\n        System.out.println(\"Veces que se ha impreso solo el número: \" + n);\n    }\n\n    //Método sin argumentos ni retorno\n    public static void saludame(){\n        System.out.println(\"Hola!\");\n    }\n\n    //Método sin argumentos pero con retorno\n    public static String getSaludo(){\n        return \"Hola!\";\n    }\n\n    //Método con argumentos pero sin retorno\n    public static void saludamePorMiNombre(String nombre){\n        System.out.println(\"Hola, \" + nombre + \"!\");\n    }\n\n    //Método con argumentos y con retorno\n    public static String getSaludoPorMiNombre(String nombre){\n        return \"Hola, \" + nombre + \"!\";\n    }\n\n    //Ejemplo de método sobrecargado (mismo nombre), varios argumentos y retorno\n    public static String getSaludoPorMiNombre(String nombre, String saludo){\n        return saludo + \", \" + nombre + \"!\";\n    }\n\n    //No se puede crear un método dentro de otro método en Java\n//    public static void imprimeHora(){\n//        public static String getHora(){\n//            return \"\" + Calendar.getInstance().get(Calendar.HOUR_OF_DAY);\n//        }\n//        System.out.println(getHora);\n//    }\n\n    //Ejemplo de métodos ya creados + concadenación de métodos\n    public static String getHora(){\n        return \"\" + Calendar.getInstance().get(Calendar.HOUR_OF_DAY);\n    }\n\n    //Concepto de variable local y global\n    static String cadena = \"Global\";\n    public static void imprimeCadena(){\n        String cadena = \"Local\";\n        System.out.println(\"Variable local: \" + cadena);\n        System.out.println(\"Variable global: \" + Josegs95.cadena);\n        //Esto es así porque estoy trabajando en un entorno estático\n        //Si fuera en un entorno no estático, se usaría this.cadena para referenciar a la\n        //variable global.\n    }\n\n    public static int retoFinal(String cad1, String cad2){\n        int contador = 0;\n\n        for (int i = 1; i < 101; i++){\n            if (i % 3 == 0){\n                if (i % 5 == 0){\n                    System.out.println(i + \": \" + cad1 + \", \" + cad2);\n                    continue;\n                }\n                System.out.println(i + \": \" + cad1);\n            } else if (i % 5 == 0) {\n                System.out.println(i + \": \" + cad2);\n            } else {\n                System.out.println(i);\n                contador++;\n            }\n        }\n\n        return contador;\n    }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/JuanGuzmanG.java",
    "content": "\npublic class JuanGuzmanG {\n\n    static int staticNumero = 1;\n\n    public static void numeros() {\n        int intNumero = 2;\n    }\n    \n    public static void main(String args[]) {\n        //funcion sin parametro ni retorno\n        saludar();\n\n        //con uno o varios parametros;\n        saludoPersonalizado(\"juan\", 18);\n\n        //con retorno\n        String mensaje = saludoGuardado();\n        System.out.println(\"mensaje obtenido:\" + mensaje);\n\n        //funcion dentro de funcion\n        System.out.println(\"mayor que 5? \" + raiz(8));\n\n        // funciones de Math, ya creadas por java\n        System.out.println(\"raiz: \" + Math.sqrt(16));\n        System.out.println(\"Exponente: \" + Math.pow(2, 3));\n        System.out.println(\"Numero aleatorio: \" + Math.random());\n\n        //funciones de cadena\n        System.out.println(\"hola tiene: \" + \"hola\".length() + \" letras\");\n        System.out.println(\"hola y \" + \"hola\".toUpperCase());\n        System.out.println(\"hola: \" + \"hola\".charAt(1));\n\n        //funcion para numeros\n        System.out.println(\"4\" + \"en tipo numero: \" + Integer.valueOf(\"4\"));\n\n        //variables locales y globales\n        System.out.println(\"global: \" + staticNumero);\n        //System.out.println(\"local: \"+intNumero);\n        \n        //Dificultad extra\n        System.out.println(\"contador: \"+multiplos(\"hola\", \"mundo\"));\n    }\n    \n    static int multiplos(String cadena1, String cadena2){\n        int contador = 0;\n        for(int i=1; i<=100;i++ ){\n            if(i%3==0 && i%5==0){\n                System.out.println(i+\": \"+cadena1+\" \"+cadena2);\n            }else if(i%5==0){\n                System.out.println(i+\": \"+cadena2);\n            }else if(i%3==0){\n                System.out.println(i+\": \"+cadena1);\n            }else{\n                System.out.println(i);\n                contador++;\n            }\n        }\n        return contador;\n        \n        /*\n        tambien:\n        String salida = \"\";\n        if(i%3==0){\n            salida += cadena1;\n        }\n        if(i%5==0){\n            salida += cadena2;\n        }\n        if(salida.isEmpty()){\n            System.out.println(i);\n            contador++;\n        } else {\n            System.out.println(salida);\n        }\n        */\n    }\n\n    static void saludar() {\n        System.out.println(\"hola\");\n    }\n\n    static void saludoPersonalizado(String nombre, Integer edad) {\n        System.out.println(\"mi nombre es: \" + nombre + \" tengo: \" + edad);\n    }\n\n    static String saludoGuardado() {\n        return \"viene de una funcion\";\n    }\n\n    static boolean raiz(Integer numero) {\n        return resultado((int) Math.sqrt(numero));\n    }\n\n    static boolean resultado(Integer valorRaiz) {\n        return (valorRaiz >= 5);\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/Karolle.java",
    "content": "public class Karolle {\n    // Global variable\n    static int globalVariable = 10;\n\n    public static void main(String[] args) {\n        // Function without parameters and return value\n        printWelcomeMessage();\n\n        // Function with parameters and return value\n        int sumResult = addNumbers(5, 7);\n        System.out.println(\"Sum Result: \" + sumResult);\n\n        // Function with local variable\n        int localVar = 20;\n        System.out.println(\"Local Variable: \" + localVar);\n        demonstrateScope();\n\n        // Function within a function\n        System.out.println(\"\\nFunction within a Function:\");\n        outerFunction();\n\n        // Using built-in functions\n        System.out.println(\"\\nBuilt-in Function Example:\");\n        String text = \"Hello, World!\";\n        System.out.println(\"Length of the text: \" + text.length());\n\n        // Extra challenge: Function with string parameters and numeric return value\n        int printedCount = printNumbersWithText(\"Fizz\", \"Buzz\");\n        System.out.println(\"\\n\\nCount: \" + printedCount);\n    }\n\n    // Function without parameters and return value\n    static void printWelcomeMessage() {\n        System.out.println(\"Welcome to Function Example!\");\n    }\n\n    // Function with parameters and return value\n    static int addNumbers(int a, int b) {\n        return a + b;\n    }\n\n    // Function with local variable to demonstrate scope\n    static void demonstrateScope() {\n        // Local variable, separate from the one in main\n        int localVar = 30;\n        System.out.println(\"Local Variable in demonstrateScope(): \" + localVar);\n        System.out.println(\"Global Variable in demonstrateScope(): \" + globalVariable);\n    }\n\n    // Function within a function\n    static void outerFunction() {\n        System.out.println(\"Outer Function\");\n        innerFunction();\n    }\n\n    static void innerFunction() {\n        System.out.println(\"Inner Function\");\n    }\n\n    // Function with string parameters and numeric return value (Extra challenge)\n    static int printNumbersWithText(String text1, String text2) {\n        int count = 0;\n        for (int i = 1; i <= 100; i++) {\n            if (i % 3 == 0 && i % 5 == 0) {\n                System.out.println(text1 + text2);\n            } else if (i % 3 == 0) {\n                System.out.println(text1);\n            } else if (i % 5 == 0) {\n                System.out.println(text2);\n            } else {\n                System.out.println(i);\n            }\n            count++;\n        }\n        return count;\n    }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/Kine-jdf.java",
    "content": "public class Kine_jdf {\n    public static final String STATIC_CONSTANT= \"ESTATICA\\n\";\n    public static void main(String args[]) {\n    \nsola();\ncParams(STATIC_CONSTANT);\nglobalLocal();\nyaCreada();\nSystem.out.print(\"Funcion con retorno de un nro\" +retorno());\nfuncConFunc();\n  \n     System.out.println(\"         -+-           |EJERCICIO EXTRA|          +-+\");\n    int prueba=  laCosa(\"Mandale\",\"Cumbia\");\n  \n    System.out.print(\"\\n\");\n     System.out.println(\"\\n     -- Se imprimio el numero un total de \"+prueba+\" veces--\");\n    }\n     public static int laCosa(String cadena1, String cadena2) {\n        int contador = 0;\n\n        for (int numero = 1; numero <= 100; numero++) {\n            if (numero % 15==0) {\n                System.out.println(\"|\"+cadena1.concat(cadena2)+\"| \");\n            } else if (numero % 3 == 0) {\n                System.out.print(\"|\"+cadena1+\"| \");\n            } else if (numero % 5 == 0) {\n                System.out.print(\"|\"+cadena2+\"| \");\n            } else {  //aca viene un if completamente innecesario para el funcionamiento, pero que me hace bien a la organizacion visual de la matriz en consola\n                if(numero<9){\n                System.out.print(\"(0\"+numero+\") \");}else {System.out.print(\"(\"+numero+\") \");}\n               contador++;\n            }\n\n           \n        }\n\n        return contador;\n    }\n   \n   public static void sola(){\n         System.out.print(\"\\n Funcion sin retorno ni parametros \\n\");\n   } \n  \n  public static void cParams(String para)  {\n        System.out.print(\"\\n Sin retorno, con el parametro \"+para);\n  }\n  public static int retorno() {\n      \n      return 10;\n  }\n  public static void globalLocal() {\n      String STATIC_CONSTANT= \"Galletitas de Chocolate|\\n\";\n        System.out.print(\"\\nvariable GLOBAL STATIC_CONSTANT :\"+MyClass.STATIC_CONSTANT);\n       System.out.println(\"\\nvariable local STATIC_CONSTANT |\"+STATIC_CONSTANT);\n  }\n  \n  public static void yaCreada(){\n      \n      int num = (int)(Math.random()*10);\n      \n       System.out.println(\"Impresion de un numero al azar con funcion nativa del lenguaje: \"+num);\n  }\n  \n  public static void funcConFunc() {\n      String test = \"Prueba\";\n      \n       System.out.print(\"Java no permite crear funciones dentro de otras, pero si llamarlas. ejemplo: \");\n          \n      test(test);\n      \n  }\n   private static void test(String prueba){\n           System.out.println(prueba+\"\\n\");\n          \n      }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/KingSaul22.java",
    "content": "/**\n * Resolución del ejercicio #02 FUNCIONES Y ALCANCE de la web Retos de Programación\n * @see <a href=\"https://retosdeprogramacion.com/roadmap\">Retos de Programación</a>\n * @see <a href=\"https://github.com/KingSaul22\">GitHub de KingSaul22</a>\n */\npublic class KingSaul22 {\n    private static int variableGlobal = 10;\n    //Variable creada a nivel global a la que se podrá acceder desde toda la clase\n\n    public static void main(String[] args) {\n        //Variable local, solo se podrá acceder a su valor en main\n        int variableLocal = 22;\n\n        //Un método sin parametros ni retorno\n        buenosDias();\n\n        //Un método que devuelve un entero pero no acepta parametros\n        System.out.println(numeroAleatorio());\n\n        //Un método que acepta parametros pero no devuelve nada\n        setVariableGlobal(variableLocal);\n\n        //Un método que acepta parametros y devuelve un booleano\n        if (compararNumeros(variableLocal, variableGlobal)) System.out.println(\"Yes\");\n\n        //Método que accede a otro método\n        asegurarIgualdadVariableGlobal(77);\n\n        //DIFICULTAD EXTRA\n        String a = \"Sal\", b = \"Azúcar\";\n        System.out.println(\"\\nNúmeros impresos: \" + dificultadExtra(a, b));\n    }\n\n    /**\n     * Imprime por pantalla \"Buenos días\"\n     */\n    private static void buenosDias() {\n        System.out.println(\"Buenos días\");\n    }\n\n    /**\n     * @return Número aleatorio entre 1 y 100\n     */\n    private static int numeroAleatorio() {\n        return (int) (Math.random() * 100 + 1);\n    }\n\n    /**\n     * En esté método le damos a la variable Global el valor del número recogido por parametro\n     *\n     * @param numero\n     */\n    private static void setVariableGlobal(int numero) {\n        variableGlobal = numero;\n    }\n\n    /**\n     * Método que comprueba si dos números son iguales\n     *\n     * @param numeroA\n     * @param numeroB\n     * @return Devuelve True cuando numeroA y numeroB son iguales\n     */\n    private static boolean compararNumeros(int numeroA, int numeroB) {\n        return numeroA == numeroB;\n    }\n\n    /**\n     * Método que valida que la variableGlobal sea igual a un número introducido usando el método {@link KingSaul22#compararNumeros compararNumeros()}\n     * y en caso de no ser iguales las iguala\n     * @param numero\n     */\n    private static void asegurarIgualdadVariableGlobal(int numero) {\n        if (compararNumeros(variableGlobal, numero)) {\n            System.out.println(\"La variableGlobal ya es igual a \" + numero);\n        } else {\n            variableGlobal = numero;\n            System.out.println(\"Se ha actualizado el valor de la variableGlobal a \" + numero);\n        }\n    }\n\n    /**\n     * Este método imprime los números del 1 al 100 siempre y cuando no sea múltiplo de 2 o 5\n     * <p>\n     * Cuando sea multiplo de 5 y 3 se imprimen las dos cadenas; en caso de solo ser multiplo de 3 la cadena1 y en caso de solo ser multiplo de 5 la cadena2\n     *\n     * @param cadena1\n     * @param cadena2\n     * @return El número de veces que se han imprimido números\n     */\n    private static int dificultadExtra(String cadena1, String cadena2) {\n        int contNumero = 0;\n        for (int i = 1; i <= 100; i++) {\n            if (i % 5 == 0 && i % 3 == 0) {\n                System.out.println(cadena1 + \" y \" + cadena2);\n            } else if (i % 3 == 0) {\n                System.out.println(cadena1);\n            } else if (i % 5 == 0) {\n                System.out.println(cadena2);\n            } else {\n                System.out.println(i);\n                contNumero++;\n            }\n        }\n\n        return contNumero;\n    }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/Kronstadt-Lambda.java",
    "content": "/**\n * @author: Kronstadt-Lambda\n * @version: 1.0\n */\n\nimport java.util.Date;\n\npublic class KronstadtLambda {\n\n    static void printGreetings() {\n        System.out.println(\"Hello roadmap-retos-programacion!\");\n    }\n\n    static void printAuthor(String author) {\n        System.out.println(\"Hello \" + author + \"!\");\n    }\n\n    static void printSum(int a, int b) {\n        System.out.println(\"The sum of \" + a + \" and \" + b + \" is: \" + (a + b));\n    }\n\n    static void sumFactors(float[] arr) {\n        float sum = 0;\n        for (float i : arr) {\n            sum += i;\n        }\n        System.out.println(\"The sum of the factors is: \" + sum);\n    }\n\n    static String getNameDay() {\n        String[] days = {\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"};\n        Date date = new Date();\n        return days[date.getDay()];\n    }\n\n    static int getSquare(int a) {\n        return a * a;\n    }\n\n    static float getAverage(float[] arr) {\n        float sum = 0;\n        for (float i : arr) {\n            sum += i;\n        }\n        return sum / arr.length;\n    }\n\n    static float printOptionalMultiplication(float a, float b, float... c) { // Optional any number of parameters\n        float result = a * b;\n        for (float i : c) {\n            result *= i;\n        }\n        return result;\n    }\n\n    static int printNumbers(String a, String b) {\n        int count = 0;\n        for (int i = 1; i <= 100; i++) {\n            if (i % 3 == 0 && i % 5 == 0) {\n                System.out.println(a + \" and \" + b);\n            } else if (i % 3 == 0) {\n                System.out.println(a);\n            } else if (i % 5 == 0) {\n                System.out.println(b);\n            } else {\n                System.out.println(i);\n                count++;\n            }\n        }\n        return count;\n    }\n\n    public static void main(String[] args) {\n        // Initialize the variables\n        float[] arr = {1.0f, 2.0f, 3.0f, 4.0f, 5.0f};\n        float[] arr2 = {1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f};\n        int[] arr3 = {1, 8, 3, 4, 5};\n        String author = \"Kronstadt-Lambda\";\n\n        // Function whitout return and parameters\n        printGreetings();\n\n        // Function with one parameter and return\n        printAuthor(author);\n\n        // Function with many parameters and return\n        printSum(5, 10);\n\n        // Function that accepts any number of parameters and don't have return\n        sumFactors(arr);\n        sumFactors(arr2);\n\n        // Function whitout parameters and whit return\n        System.out.println(\"Today is: \" + getNameDay());\n\n        // Function whit one parameter and return\n        System.out.println(\"The square of 5 is: \" + getSquare(5));\n\n        // Function that accepts any number of parameters and have return\n        System.out.println(\"The average of the factors is: \" + getAverage(arr));\n        System.out.println(\"The average of the factors is: \" + getAverage(arr2));\n\n        // Function whit optional parameters and return\n        System.out.println(\"The multiplication of 5, 10, 2 and 3 is: \" + printOptionalMultiplication(5, 10, 2, 3));\n        System.out.println(\"The multiplication of 5 and 4 is: \" + printOptionalMultiplication(5, 4));\n\n        // Function inside a function: In Java, functions can be defined inside other functions.\n        \n        // Functions pre-stablished\n        // String functions: length(), toUpperCase(), toLowerCase(), trim(), replace()\n        System.out.println(\"length() function: \" + \"Hello\".length());\n        System.out.println(\"toUpperCase() function: \" + \"Hello\".toUpperCase());\n        System.out.println(\"toLowerCase() function: \" + \"Hello\".toLowerCase());\n        System.out.println(\"trim() function: \" + \"       Hello \".trim());\n        System.out.println(\"replace() function: \" + \"Hello\".replace(\"H\", \"J\"));\n        // Methods of Integer clase: parseInt(), toString(), valueOf()\n        System.out.println(\"parseInt() function: \" + Integer.parseInt(\"10\")); // Convert a string to an integer\n        System.out.println(\"toString() function: \" + Integer.toString(10)); // Convert an integer to a string\n        System.out.println(\"valueOf() function: \" + Integer.valueOf(10)); // Convert an integer to an Integer object\n\n        // Local and global variables\n        String global = \"Global variable\";\n        System.out.println(\"Global variable: \" + global);\n        {\n            String local = \"Local variable\";\n            System.out.println(\"Local variable: \" + local);\n            System.out.println(\"Global variable inside a block: \" + global);\n        }\n        // System.out.println(\"Local variable inside a block: \" + local); // Error: local cannot be resolved to a variable\n        System.out.println(\"Global variable outside a block: \" + global);\n\n        /**\n         * Extra exercise\n         * Create a function that takes two string parameters and returns a number.\n         * - The function prints all numbers from 1 to 100. Considering that:\n         * - If the number is a multiple of 3, it displays the string of the first parameter.\n         * - If the number is a multiple of 5, it displays the string of the second parameter.\n         * - If the number is a multiple of 3 and 5, it displays the two strings of text concatenated.\n         * - The function returns the number of times the number has been printed instead of the texts.\n         */        \n        \n        System.out.println(\"The number of times the number has been printed is: \" + printNumbers(\"multiple of 3\", \"multiple of 5\"));\n\n    }\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/Ldre3.java",
    "content": "import java.util.concurrent.atomic.AtomicInteger;\nimport java.util.stream.IntStream;\n\npublic class Ldre3 {\n\n    public static void main(String[] args) {\n        /*\n         * EJERCICIO:\n         * - Crea ejemplos de funciones básicas que representen las diferentes\n         *   posibilidades del lenguaje:\n         *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n         * - Comprueba si puedes crear funciones dentro de funciones.\n         * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n         * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n         * - Debes hacer print por consola del resultado de todos los ejemplos.\n         *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n         */\n        funcion1();\n        System.out.println(funcion2(\"Luis\"));\n        int numero = 1;\n        System.out.println(numero);\n        System.out.println(funcion3());\n        fizzBuzz(\"Fizz\",\"Buzz\");\n\n\n\n\n    }\n    public static void funcion1() {\n        System.out.println(\"Hola mundo!\");\n    }\n    public static String funcion2(String nombre) {\n        return \"Hola \" + nombre + \"!\";\n    }\n    public static int funcion3() {\n        int numero = 0;\n        return numero;\n    }\n    /*\n     * DIFICULTAD EXTRA (opcional):\n     * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n     * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n     *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n     *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n     *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n     *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n     *\n     * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n     * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n     */\n\n    public static int fizzBuzz(String cadena1, String cadena2){\n        AtomicInteger numero = new AtomicInteger(0);\n        IntStream.range(1,101).forEach(v ->{\n            String cadena = \"\";\n            if (v%3==0) cadena+= cadena1;\n            if (v%5==0) cadena+= cadena2;\n            if (cadena.isBlank()){\n                cadena+=v;\n                numero.getAndIncrement();\n            }\n            System.out.println(cadena);\n        });\n        return numero.intValue();\n    }\n\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/LucasAG01.java",
    "content": "public class LucasAG01 {\n\n\n        //Funcion bloque de codigo para reutilizarlo de otras formas.\n\n        //FUNCIONES DEFINIDAS POR EL USUARIO. las crea el usuario como le da la gana\n\n        //Simple\n\n        /*\n        modificadorAcceso tipoRetorno nombreFuncion (tipoParametro1 nombreParametro1, tipoParametro2 nombreParametro2, ...) {\n            Cuerpo de la función\n            Procesamiento y cálculos\n        return valorRetorno;\n           }\n         */\n\n        //Funcion sin retorno ni parametros\n\n        public void SaludosDefault(){\n            System.out.println(\"Saludos!!\");\n        }\n\n        //Funcion con parametro sin retorno\n\n        public void Presentacion (String parametro){\n            System.out.println(\"Hola buenos días \"+parametro);\n        }\n\n        //Funcion con retorno, es decir, ejecuta una lógica y devuelve algo, en la decalarciond e la función, en vez de void (sin retorno) colocaresmos el tipo de dato a devolver\n        public String suma (int a, int b) {\n            return \"El resultado es \"+a+b; //devulve un String\n        }\n        public int suma2 (int a ,int b){\n            return a+b; //Devulve un int directamente\n        }\n\n        //Funciones dentro de funciones\n        public void funcionesDentro(){\n            System.out.println(\"Aquí debajo te dejaré el resultado de la funcion saludos.\");\n            SaludosDefault();\n        }\n        public void funcionesDentro2(String parametro){\n            System.out.println(\"Aquí debajo te dejaré el resultado de la funcion Presentacion: \");\n            Presentacion(parametro);\n        }\n\n        //Las funciones tienen unos modificadores de acceso, que sirven para mantener una limpieza y fundamentalmente seguridad en el codigo.\n        // El acceso es lo primeor que ponemos\n         /*\n            public: La función es accesible desde cualquier clase.\n            private: La función solo es accesible dentro de la misma clase en la que se define.\n            protected: La función es accesible dentro de la misma clase y sus subclases.\n            Sin modificador (por defecto): La función es accesible dentro del mismo paquete.\n          */\n\n\n    public  void funcionPublica() {\n        // Accesible desde cualquier clase\n    }\n\n    private void funcionPrivada() {\n        // Accesible solo dentro de la clase LucasAG01\n    }\n\n    protected  void funcionProtegida() {\n        // Accesible dentro de la clase LucasAG01 y sus subclases\n    }\n\n    void funcionPorDefecto() {\n        // Accesible dentro del mismo paquete\n    }\n\n    // Para poder usar estos métodos en diferentes clases, sin necesidad de instanciar un objeto: LucasAG01 metodo = new LucasAG01, en el metodo main x ej\n    // tenemos que declarar el método como 'static'.\n    // Al hacer esto, indicamos que es un método de clase, lo que significa que puede ser llamado\n    // directamente a través del nombre de la clase.\n    // Esto es útil cuando queremos que el método se pueda utilizar de manera global,\n    // independientemente de las instancias de la clase.\n    //ejemplo: public static void llamar(){sout(\"Hola que tal\");}\n\n\n    //funcion n numeros nos sabes cuantos los separas por ,\n    public static int sumarN (int... numeros){\n        int suma = 0;\n        for (int num : numeros) {\n            suma += num;\n        }\n        return suma;\n    }\n\n    //Tambien hay funciones creadas por el lenguage en si, como Math, toUpperCase\n\n    //Aquí cremos una funcion y dentro de esta una funcion del lenguaje, generamos un nuemro entre 1 y 50\n    public static void NUmeroAleatorio (){\n\n         int numero= (int) (Math.random()*50)+1;\n\n        System.out.println(numero);\n    }\n\n\n\n\n\n\n    public static void main(String[] args) {\n\n            LucasAG01 lucasAG01 = new LucasAG01();\n            lucasAG01.SaludosDefault();\n            lucasAG01.Presentacion(\"Lucas\");\n            lucasAG01.funcionesDentro();\n            lucasAG01.funcionesDentro2(\"Lucas\");\n            NUmeroAleatorio(); //Como use static, no tengo que usar objeto LucasAG01\n\n\n    }\n\n    //Ejericicio Extra\n\n    public static int Extra (String para1, String para2){\n        int contador =0;\n        for (int i = 1; i <= 100; i++){\n\n            if (i%3==0 && i%5==0){\n                System.out.println(para1+para2);\n            }\n            else if (i%3==0){\n                System.out.println(para1);\n            } else if (i%5==0){\n                System.out.println(para2);\n            } else {\n                System.out.println(i);\n            }\n            contador++;\n        }\n        return contador;\n    }\n\n\n     /*\n     •\tint contador = 0 : Se inicializa el contador en 0, el cual se incrementará en cada iteración del bucle.\n     •\telse: Si el número i no es divisible ni por 3 ni por 5, simplemente se imprime el número i.\n     •\tcontador++: En cada iteración del bucle, el contador se incrementa en 1\n     •\treturn contador;: Al final del método, se devuelve el valor del contador, que debería ser 100, ya que el bucle corre exactamente 100 veces.\n\n       TEMA CONTADOR:\n\n       Es una variable que lleva el registro del numero de veces que ocurre un evento específico, como el n de ietraciones en un bucle\n       creamos u contador a 0\n       luego dentro del for, cada vez que el bucle realiza una iteracion, cuando llega al final, hacemos que dicho contador aumnete en 1 contador++;\n\n       return contador, Cuando el bucle termina, 100 veces , la funcion devuelve el valor del contador, en este caso 100.\n\n       se incrementa en cada iteración del bucle, lo que permite llevar un registro de cuántas veces se ha ejecutado el bucle. Al final del método,\n       el contador devuelve el número total de iteraciones, que en este caso es 100.\n       Aunque en este escenario el uso del contador puede parecer redundante (ya que sabemos de antemano que habrá 100 iteraciones),\n       sigue siendo una práctica común y útil, especialmente en casos donde el número de iteraciones podría variar.\n\n      */\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/LuisK0706.java",
    "content": "public class Ejercicio02 {\n\n    //Creando una variable global (La variables globales se pueden usar en cualquier lugar del codigo)\n    public static String mi_variable = \"Variable global\";\n    public static void main(String[] args) {\n        funcion1();\n        suma(5, 7);\n        System.out.println(concatenar_cadenas(\"Hola\", \"mundo\"));\n        System.out.println(variable_global());\n        variable_local();\n\n        //Ejemplo de una funcion ya creada de java.\n\n        //Funcion length (Se utiliza para mostrar el largo de una cadena)\n        String mi_cadena = \"Luis King\";\n        System.out.println(\"El tamaño de la cadena es: \" + mi_cadena.length());\n\n\n        // Mostrando ejercicio extra \n        System.out.println(\"Se mostraron: \" + Extra(\"mi_cadena1\", \"mi_cadena2\") + \" numeros en lugar de las cadenas\");\n\n        \n\n    }\n\n    //Funcion sin parametros ni retornos\n    public static void funcion1(){\n        System.out.println(\"Esto es una funcion sin parametros ni retornos\");\n    }\n\n    //Funcion con parametros\n    public static void suma(int num1, int num2){\n        int suma;\n        suma = num1 + num2;\n        System.out.println(\"La suma es: \" + suma);\n    }\n\n    // Funcion con parametros y retornos\n    public static String concatenar_cadenas(String cadena1, String cadena2){\n        return cadena1 + \" \" + cadena2;\n    }\n\n    // Utilizando una variable global\n    public static String variable_global(){\n       return mi_variable;\n    }\n\n\n    //Funcion con una variable local \n    public static void variable_local(){\n        //Creando una variable local (Las variables locales solo se pueden utilizar en la funcion donde se crearon)\n        int variable_local = 7;\n        System.out.println(variable_local);\n    }\n\n    /*\n     * DIFICULTAD EXTRA (opcional):\n     * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n     * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n     *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n     *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n     *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n     *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos\n     */\n\n     public static int Extra(String cadena1, String cadena2){\n        int contador = 0;\n        for (int i = 0; i <= 100; i++){\n            if (i % 3 == 0){\n                System.out.println(cadena1);\n            }\n            else if (i % 5 == 0){\n                System.out.println(cadena2);\n            }\n            else if (i % 3 == 0 && i % 5 == 0){\n                System.out.println(cadena1 + cadena2);\n            }\n            else{\n                System.out.println(i);\n                contador++;\n            }\n        }\n\n        return contador;\n     }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/Marianoemir.java",
    "content": "import java.util.Scanner;\nclass Marianoemir{\n    \n /*\n    @author Marianoemir\n    \n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n * \n */\n    /*Variables Globales\n    Variables de Instancia: Se usan para almacenar datos específicos de cada objeto.\n    Variables Estáticas: Se usan para almacenar información o comportamientos que deben ser comunes a todas las instancias, \n    como contadores globales, configuraciones comunes, o constantes.*/\n    int variglobal = 20;\n    static int varglobalconstatic = 30;\n\n    //Las funciones en java se llaman 'metodos' tambien\n    \n    //Función sin retorno ni parametros\n    \n    //Con void y public es necesario crear un Objeto para poder ejecutarla.\n    public void mostrar(){\n        System.out.println(\"Este es un msj con public y void\");\n    }\n    \n    //Calcular valor elevado de un numero con clases predefinidas en java\n    public double potencia (double a ,double b){\n        return Math.pow(a, b);\n    }\n    \n    \n    //Sin static no es necesario iniciarlizar un Obj solamente hay que llamar a la función\n    public static void salidadeconsola(){\n        System.out.println(\"Msj con Static no hace falta crear ni inicializar un Obj\");\n    }\n    //Metodo con 'parametros' y 'retornos'\n    public int suma(int a, int b, int c){\n        return a + b + c;\n    }\n\n    /*Ejemplo de Variables locales\n    Variables Locales: Limitadas al método o bloque donde se declaran; no son accesibles fuera de ese ámbito.*/\n    public int multi (int num1,int num2){\n        int resultado = num1 * num2;\n        return resultado;\n    }\n\n    /*DIFICULTAD EXTRA (opcional):\n    * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n    * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n    * - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n    * - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n    * - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n    * - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n    * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n    * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.*/\n\n     public int difiextar (String cade1 ,String cade2){\n\n        int contador = 0;\n\n       for (int i = 1; i <= 100; i++) {\n            if (i % 3 == 0 && i % 5 == 0) {\n                System.out.println(cade1 + cade2);\n            } else if (i % 3 == 0) {\n                System.out.println(cade1);\n            } else if (i % 5 == 0) {\n                System.out.println(cade2);\n            } else {\n                contador++;  \n            }\n        }\n        return contador;\n     }\n      \n\n    public static void main(String[] args) {\n        Marianoemir imprimir = new Marianoemir();\n        imprimir.mostrar();\n        salidadeconsola();\n        int operacion = imprimir.suma(10,20,30);\n        System.out.println(\"Metodo con retorno y parametros: \"+operacion);\n        \n        \n        Scanner scanner = new Scanner(System.in);\n        System.out.println(\"Introduce el primer numero(la base): \");\n        double  base = scanner.nextDouble();\n        \n        \n        System.out.println(\"Introduce el segundo numero(el exponente): \");\n        double  exponente = scanner.nextDouble();\n        System.out.println(\"\");\n        System.out.println(\"El resultado de tu numero elevado es: \"+imprimir.potencia(base, exponente));\n\n        /* EJemplo con variables locales\n\n        Se declaran dentro de un método, constructor o bloque de código.\n        Solo son accesibles dentro del método, constructor o bloque donde se declaran.\n        Se crean cuando se entra en el bloque de código y se destruyen cuando se sale.*/\n\n        System.out.println(\"El resultado de la multiplicacion entre variables locales es: \"+imprimir.multi(5, 5));\n\n        //Ejemplos de variables globales\n\n        System.out.println(\"Variable global accedida desde instancia de clase: \"+imprimir.variglobal);\n        System.out.println(\"Ejemplo de variable global con static: \"+varglobalconstatic);\n\n        //Ejercicio extra ejecución\n\n        int resulfunc = imprimir.difiextar(\"Hola\", \" Espero que tengas un buen dia\");\n\n        System.out.println(\"El numero de veces que se imprimio el numero es: \"+resulfunc);\n        \n\n        \n        \n    }\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/Natalinacn.java",
    "content": "package com.example.headfirstjava;\n\nimport org.springframework.boot.SpringApplication;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.List;\n\npublic class Natalinacn {\n\n    public static void main(String[] args) {\n        SpringApplication.run(HeadFirstjavaApplication.class, args);\n\n        imprimirMensaje();\n        imprimirNombre(\"Natalin\");\n        sumarNumeros(2, 5);\n        System.out.println(saludar());\n        System.out.println(cuadrado(5));\n        System.out.println(multiplicar(8, 2));\n\n        //EJEMPLO DE FUNCIONES YA CREADAS EN EL LENGUAJE\n        //1-Funciones de la clase Math\n        double numEjemplo = 123.45;\n        System.out.println(\"Valor absoluto \" + numEjemplo + \": \" + Math.abs(numEjemplo));\n        System.out.println(\"Raíz cuadrada de 16: \" + Math.sqrt(16));\n        System.out.println(\"Máximo entre 10 y 20: \" + Math.max(10, 20));\n        System.out.println(\"Mínimo entre 10 y 20: \" + Math.min(10, 20));\n        System.out.println(\"Número aleatorio entre 0.0 y 1.0: \" + Math.random());\n\n        //2-Funciones de la clase String\n        String texto = \"Hola Mundo\";\n        System.out.println(\"Texto en minúsculas: \" + texto.toLowerCase());\n        System.out.println(\"Texto en mayúsculas: \" + texto.toUpperCase());\n        System.out.println(\"Longitud del texto: \" + texto.length());\n        System.out.println(\"Caracter en la posición 5: \" + texto.charAt(4));\n        System.out.println(\"Reemplazar 'Mundo' con 'Java': \" + texto.replace(\"Mundo\", \"Java\"));\n\n        //3-Funciones de la clase Arrays\n        int[] numerosArray = {5, 3, 8, 2, 9, 1};\n\n        // Ordenar el arreglo: sort(int[] a): Ordena el arreglo en orden ascendente.\n        Arrays.sort(numerosArray);\n        System.out.println(\"Arreglo ordenado: \" + Arrays.toString(numerosArray));\n\n        // Buscar un elemento en el arreglo: binarySearch(int[] a, int key): Busca el elemento especificado en el arreglo ordenado y devuelve el índice de la búsqueda binaria.\n        int indice = Arrays.binarySearch(numerosArray, 8);\n        System.out.println(\"Índice del elemento 8: \" + indice);\n\n        // Rellenar el arreglo: fill(int[] a, int val): Asigna el valor especificado a cada elemento del arreglo.\n        Arrays.fill(numerosArray, 7);\n        System.out.println(\"Arreglo rellenado con 7: \" + Arrays.toString(numerosArray));\n\n        //4- Funciones de la clase Collections: La clase Collections proporciona métodos estáticos que operan en colecciones como listas, conjuntos y mapas.\n        List<String> lista = new ArrayList<>();\n        lista.add(\"Banana\");\n        lista.add(\"Manzana\");\n        lista.add(\"Pera\");\n        lista.add(\"Naranja\");\n\n        // Ordenar la lista\n        Collections.sort(lista);\n        System.out.println(\"Lista ordenada: \" + lista);\n\n        // Barajar la lista\n        Collections.shuffle(lista);\n        System.out.println(\"Lista barajada: \" + lista);\n\n        // Encontrar el elemento máximo\n        String maximo = Collections.max(lista);\n        System.out.println(\"Elemento máximo: \" + maximo);\n\n        // Encontrar el elemento mínimo\n        String minimo = Collections.min(lista);\n        System.out.println(\"Elemento mínimo: \" + minimo);\n\n        Natalinacn variables = new Natalinacn();\n        variables.metodoConVariablesLocales();\n        variables.imprimirMensajeGlobal();\n\n        funcionExtra(\"Múltiplo de 3 \", \"Múltiplo de 5\");\n\n    }\n\n    //#02 FUNCIONES Y ALCANCE\n\n    //1. Función sin parámetros y sin retorno\n    public static void imprimirMensaje(){\n        System.out.println(\"Hola, este es un mensaje sin parámetros ni retorno.\");\n    }\n\n    //2. Función con un parámetro y sin retorno\n    public static void imprimirNombre(String nombre){\n        System.out.println(\"Bienvenida \" + nombre);\n    }\n\n    //3. Función con varios parámetros y sin retorno\n    public static void sumarNumeros(int num1, int num2){\n        System.out.println(\"La suma de los números es \" + num1 + num2);\n    }\n\n    //4. Función sin parámetros y con retorno\n    public static String saludar(){\n        return \"Buenas tardes!!\";\n    }\n\n    //5. Función con un parámetro y con retorno\n    public static int cuadrado(int numero){\n        return numero * numero;\n    }\n\n    //6. Función con varios parámetros y con retorno\n    public static int multiplicar(int num1, int num2){\n        return num1 * num2;\n    }\n\n    //Funcion dentro de otra función\n    //En Java no es posible definir una función (método) dentro de otra función directamente.\n    //Todos los métodos deben ser definidos al mismo nivel de clase.\n    //Si necesitas definir una función dentro de otra, puedes hacerlo indirectamente utilizando clases internas,\n    // clases anónimas, o expresiones lambda en ciertos contextos.\n    public static void funcionDentroDeFuncion() {\n        System.out.println(\"Probando si se puede crear una función dentro de otra a continuación...\");\n\n        class FuncionAdentro {\n            void mensaje() {\n                System.out.println(\"No se puede crear una función dentro de otra directamente.\");\n            }\n        }\n\n        FuncionAdentro funcionAdentro = new FuncionAdentro();\n        funcionAdentro.mensaje();\n\n\n\n    }\n\n    // VARIABLE LOCAL y GLOBAL\n    //En Java Las variables locales son aquellas que se declaran dentro de un método y solo son accesibles dentro de ese método. No pueden ser accedidas fuera del método en el que se declararon.\n    //Variables de instancia (similares a variables globales) se declaran dentro de una clase pero fuera de cualquier método. Son accesibles por todos los métodos de la clase y su valor puede ser cambiado por cualquier método de la clase.\n\n    // Variable de instancia (similar a una variable global)\n    private String mensajeGlobal = \"Este es un mensaje global.\";\n\n    // Método que imprime la variable global\n    public void imprimirMensajeGlobal() {\n        System.out.println(mensajeGlobal);\n    }\n\n    // Método que contiene variables locales\n    public void metodoConVariablesLocales() {\n        // Variable local\n        String mensajeLocal = \"Este es un mensaje local.\";\n\n        System.out.println(mensajeLocal);\n\n        // Intentar acceder a una variable global\n        System.out.println(\"Intentar acceder a una variable global: \" + mensajeGlobal);\n    }\n\n\n\n    //DIFICULTAD EXTRA (opcional):\n    // * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n    // * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n    // *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n    // *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n    // *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n    // *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\n    public static int funcionExtra(String param1, String param2){\n\n        int contador = 0;\n        for (int i = 1; i < 101; i++) {\n            if(i % 3 == 0 && i % 5 == 0){\n                System.out.println(i +\" es \" + param1 + param2);\n            }else if(i % 3 == 0){\n                System.out.println(i + \" es \" +param1);\n            }else if(i % 5 == 0){\n                System.out.println(i +\" es \" + param2);\n            }else{\n                contador++;\n            }\n        }\n        System.out.println(\"El número de veces que se ha impreso el número en lugar de los textos es de \" + contador);\n        return contador;\n    }\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/Password1989.java",
    "content": "package org.roadmap.java.ejercicio.dos;\r\n\r\npublic class Password1989 {\r\n\tpublic static void sinRetorno()\r\n\t{\r\n\t\tSystem.out.println(\"Sin retorno\");\r\n\t}\r\n\t\r\n\tpublic static int devuelveEntero()\r\n\t{\r\n\t\treturn 0;\r\n\t}\r\n\t\r\n\tpublic static void sinRetornoConParametro(String cadena1)\r\n\t{\r\n\t\tSystem.out.println(\"cadena1\");\r\n\t}\r\n\t\r\n\tpublic static void funcion1()\r\n\t{\r\n\t\t/* ERROR\r\n\t\tpublic static int funcion2() {\r\n\t\t\tSystem.out.println(\"F2\");\r\n\t\t}\r\n\t\t*/\r\n\t}\r\n\t\r\n\tpublic static int dificultadExtra(String cadena1, String cadena2)\r\n\t{\r\n\t\t/*\r\n\t\t * DIFICULTAD EXTRA (opcional):\r\n\t\t * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\r\n\t\t * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\r\n\t\t *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\r\n\t\t *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\r\n\t\t *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\r\n\t\t *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\r\n\t\t *\r\n\t\t */\r\n\t\tint resultado = 0;\r\n\t\t\r\n\t\ttry {\r\n\t\t\tfor (int i = 1; i <= 100; i++)\r\n\t\t\t{\r\n\t\t\t\tif ((i%3==0) && (i%5==0))\r\n\t\t\t\t{\r\n\t\t\t\t\tSystem.out.println(\"i:\" + i + \"-Cadenas:\" + cadena1+cadena2);\r\n\t\t\t\t\tresultado++;\r\n\t\t\t\t}\r\n\t\t\t\telse if(i%3==0)\r\n\t\t\t\t{\r\n\t\t\t\t\tSystem.out.println(\"i:\" + i + \"-Cadenas:\" + cadena1);\r\n\t\t\t\t\tresultado++;\r\n\t\t\t\t}\r\n\t\t\t\telse if(i%5==0)\r\n\t\t\t\t{\r\n\t\t\t\t\tSystem.out.println(\"i:\" + i + \"-Cadenas:\" + cadena2);\r\n\t\t\t\t\tresultado++;\r\n\t\t\t\t}\r\n\t\t\t\t\r\n\t\t\t}\r\n\t\t} catch (Exception e) {\r\n\t\t\t// TODO: handle exception\r\n\t\t\te.printStackTrace();\r\n\t\t}\r\n\t\treturn resultado;\r\n\t}\r\n\tpublic static void main(String[] args) {\r\n\t\t/*\r\n\t\t * EJERCICIO:\r\n\t\t * - Crea ejemplos de funciones básicas que representen las diferentes\r\n\t\t *   posibilidades del lenguaje:\r\n\t\t *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\r\n\t\t * - Comprueba si puedes crear funciones dentro de funciones.\r\n\t\t * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\r\n\t\t * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\r\n\t\t * - Debes hacer print por consola del resultado de todos los ejemplos.\r\n\t\t *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\r\n\t\t *\r\n\t\t * DIFICULTAD EXTRA (opcional):\r\n\t\t * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\r\n\t\t * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\r\n\t\t *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\r\n\t\t *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\r\n\t\t *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\r\n\t\t *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\r\n\t\t *\r\n\t\t * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\r\n\t\t * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\r\n\t\t * \r\n\t\t * \r\n\t\t * El título de la Pull Request también debe seguir este formato: \"#[número] - [lenguaje_utilizado]\". \r\n\t\t * En el ejemplo anterior sería \"#00 - Python\".\r\n\t\t * \r\n\t\t * En mi caso seria: \"#02 - Java\"\r\n\t\t */\r\n\t\tint nVeces;\r\n\t\tSystem.out.println(String.format(\"Se han escrito las cadenas %s veces\", nVeces = dificultadExtra(\"cadena1\", \"cadena2\")));\r\n\t\t\r\n\t}\r\n\r\n}\r\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/Pbjmg.java",
    "content": "public class Pbjmg {\n    \n    //  Función sin parámetros ni retorno\n    public static void saludar() {\n        System.out.println(\"¡Hola! Esta es una función sin parámetros ni retorno.\");\n    }\n\n    //  Función con un parámetro\n    public static void imprimirMensaje(String mensaje) {\n        System.out.println(\"Mensaje recibido: \" + mensaje);\n    }\n\n    //  Función con varios parámetros y retorno\n    public static int sumar(int a, int b) {\n        return a + b;\n    }\n\n    //  Función que llama a otra función dentro de sí misma (NO se pueden crear dentro de otras)\n    public static void mostrarSuma(int x, int y) {\n        int resultado = sumar(x, y);\n        System.out.println(\"La suma de \" + x + \" y \" + y + \" es: \" + resultado);\n    }\n\n    //  Uso de una función ya existente en Java\n    public static void ejemploFuncionNativa() {\n        double raiz = Math.sqrt(25); // Función nativa de Java para raíz cuadrada\n        System.out.println(\"La raíz cuadrada de 25 es: \" + raiz);\n    }\n\n    //  Demostración de variables locales y globales\n    static int global = 100; // Variable global\n\n    public static void variablesLocalesYGlobales() {\n        int local = 50; // Variable local\n        System.out.println(\"Variable local dentro de la función: \" + local);\n        System.out.println(\"Variable global dentro de la función: \" + global);\n    }\n\n    public static void main(String[] args) {\n        // Llamando a todas las funciones para probarlas\n        saludar();\n        imprimirMensaje(\"¡Este es un mensaje de prueba!\");\n        int resultadoSuma = sumar(5, 7);\n        System.out.println(\"Resultado de la suma: \" + resultadoSuma);\n        mostrarSuma(8, 3);\n        ejemploFuncionNativa();\n        variablesLocalesYGlobales();\n\n        // Llamamos a la función del desafío extra\n        int vecesNumeros = desafioExtra(\"Fizz\", \"Buzz\");\n        System.out.println(\"El número de veces que se imprimió un número en lugar de un texto fue: \" + vecesNumeros);\n    }\n\n    //  DIFICULTAD EXTRA: Función que recibe dos cadenas y retorna un número\n    public static int desafioExtra(String palabra1, String palabra2) {\n        int contador = 0;\n\n        for (int i = 1; i <= 100; i++) {\n            boolean multiploDe3 = (i % 3 == 0);\n            boolean multiploDe5 = (i % 5 == 0);\n\n            if (multiploDe3 && multiploDe5) {\n                System.out.println(palabra1 + palabra2);\n            } else if (multiploDe3) {\n                System.out.println(palabra1);\n            } else if (multiploDe5) {\n                System.out.println(palabra2);\n            } else {\n                System.out.println(i);\n                contador++; // Contamos cuántos números se imprimieron\n            }\n        }\n        return contador;\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/Qv1ko.java",
    "content": "public class Qv1ko {\n\n    public static int a = 3;\n    \n    public static void main(String[] args) {\n        \n        function1();\n\n        System.out.println(function2());\n\n        function3(a, \"\\nParameterized and non-return function:\\nGlobal variable A: \");\n\n        System.out.println(function4(4, \"\\nFunction with return and with parameters:\\nGlobal variable A: \"));\n\n        System.out.println(\"\\nProgram:\\n\");\n        System.out.println(\"\\nNumber of times a text was not printed: \" + program(\"zip\", \"zap\"));\n\n    }\n\n    private static void function1() {\n        int b = 4;\n        System.out.println(\"\\nFunction without return and without parameters:\\nGlobal variable A: \" + a + \"\\nLocal variable B: \" + b);\n    }\n\n    private static String function2() {\n        return \"\\nFunction with return and without parameters:\\nGlobal variable A: \" + a;\n    }\n\n    private static void function3(int num, String str) {\n        System.out.println(str + num);\n    }\n\n    private static String function4(int num, String str) {\n        return str + a + \"\\n\" + num +\" to the power of \" + a + \" = \" + (int)Math.pow(num, a);\n    }\n\n    private static int program(String zip, String zap) {\n\n        int count = 0;\n\n        for (int i = 1; i <= 100; i++) {\n            if (i % 3 == 0 && i % 5 == 0) {\n                System.out.println(zip + zap);\n            } else if (i % 3 == 0) {\n                System.out.println(zip);\n            } else if (i % 5 == 0) {\n                System.out.println(zap);\n            } else {\n                count++;\n            }\n        }\n\n        return count;\n\n    }\n    \n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/RodrigoGit87.java",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convención que debes de respetar para que el código se entienda.\n */\npublic class RodrigoGit87 {\n        protected String nombre;\n\n        public RodrigoGit87(String nombre) {\n            this.nombre = nombre;\n        }\n\n    // Metodo sin retorno ni parametros\n    public void metodoVacio(){\n        System.out.println(\"Esto es un metodo void o vacio, y sin parametros\");\n    }\n    //Metodo con un parametro, sin retorno\n    public void metodoVacio2(int numero){\n        System.out.println(\"ESto es un metodo void con parametro  int: \" + numero );\n    }\n    // no se puede crear un metodo dentro de otro\n//    public void metodoExterior(){\n//        public void metodoInterior() {\n//            System.out.println(\" No se puede un metodo dentro de otro \");\n//        }\n//    }\n    // Metodo con parametro y retorno tipo String\n    public String validarEdad(int edad){\n        String mensaje = \"\";\n        if(edad<18){\n            mensaje= \"Eres menor de edad\";\n        }\n        else {\n            mensaje= \"Eres mayor de edad\";\n        }\n        return mensaje;\n    }\n    //Metodo con 2 parametros y retorno tipo Boolean\n    public boolean encenderCalefaccion (int temperatura, String estacion) {\n        if (temperatura < 20 || estacion.trim().equalsIgnoreCase(\"invierno\")){\n            System.out.println( \" Hace un frio del carajo \");\n            return true;\n        } else return false;\n    }\n    // EXTRA\n    public int vecesImpresion ( String texto1, String texto2){\n            int contador = 0;\n            int numero;\n            //imprimir numeros del 1 al 100\n            for (int i=1; i<= 100 ; i++){\n                numero = i;\n                // Condiciones\n\n                if  ((numero % 3 == 0) && (numero % 5 == 0)){\n                    System.out.println(numero + \": \" + texto1 + \" \\n \"+numero +\": \"+ texto2);\n                }else if (numero % 5 == 0) {\n                    System.out.println(numero +\": \"+ texto2);\n                } else if ( numero % 3 == 0) {\n                    System.out.println(numero + \": \" + texto1);\n                } else  {\n                    System.out.println(numero);\n                    contador ++;\n                }\n            }\n            System.out.println( contador + \" veces se han impreso números( sin contar múltiplos)\");\n            return contador;\n    }\n\n    //Campo de batalla :P\n        public static void main (String[]args){\n\n        var rodrigoGit87 = new RodrigoGit87(\"RodrigoGit87\");\n        rodrigoGit87.metodoVacio();\n        rodrigoGit87.metodoVacio2(3);\n        System.out.println(rodrigoGit87.validarEdad(38));\n        rodrigoGit87.encenderCalefaccion(9, \"primavera\");\n        rodrigoGit87.vecesImpresion(\" es múltiplo de 3 :P \", \" es múltiplo de 5 :) \");\n\n        }\n    }\n\n\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/RoniPG.java",
    "content": "\n// @Roni\npublic class FUNCIONES_Y_ALCANCE_02 {\n\t\n\n\t\t// Diferenciaremos entre Funciones, Metodos y Procedimientos\n\t\t\n\t\t// Las funciones utilizan el modificador static\n\t\n\t//Funcion de suma\n\t/*\n\t * Las funciones pueden no recibir ningun parametro o pueden recibir varios parametros\n\t * Siempre tienen un valor de retorno (return) que se devuelve al invocar la funcion\n\t */\n\tpublic static int Suma(int numA, int numB) {\n\t\t\n\t\tint result = numA + numB + a;\n\t\t\n\t\treturn result;\n\t\n\t}\n\tpublic static int Resta(int a) {\n\t\t/*public static int SegundaResta(int b) {\n\t\t\treturn 0;}\n\t\tPodemos comprobra al descomentar este codigo que no podemos crear funciones dentro de funciones\t\n\t\t*/  \n\t\treturn 0;\n\t}\n\t//Llamadas a funciones dentro de funciones\n\tpublic static int Resultsuma(int numA, int numB) {\n\t\t\n\t\tint result = numA + numB;\n\t\tResultados(); // ---> Podemos realizar llamadas a funciones dentro otra\n\t\treturn result;\n\t\n\t}\n\tstatic int a = 1; //Variable global es accesible a en todo el programa\n\t\n\tpublic static int AccesoVariables() {\n\t\t int a = 0; // ---> Variable Local (Solo existe dentro de la funcion)\n\t\treturn a;\n\t}\n\t\t//Los metodos se utilizan principalmente en objetos, y no llevan modificador\n\t\n\tpublic int Resta(int numA, int numB) {\n\t\t\n\t\tint result = numA - numB;\n\t\t\n\t\treturn result;\n\t\n\t}\n\t\t//Los procedimientos no retornan ningun valor, llevan el tipo void.\n\tpublic static void Resultados() {\n\t\tSystem.out.println(\"El resultado de la suma es:\"+Suma(2,3));\n\t\t\n\t}\n\tpublic static void main(String[] args) {\n\t\t\n\t\t//Llamadas a Funciones\n\t\t \n\t\tSystem.out.println(Suma(2, 3));\n\t\t//System.out.println(Resta(2, 3)); --> No se puede llamar al metodo porque no esta asociado a ningun objeto\n\t\tResultados();\n\t\tSystem.out.println(Resultsuma(2, 3));\t\n\t\t\n\t\t//Llamadas a Funciones predefinidas de java\n\t\t\n\t\tSystem.out.println(\"2 elevado a la potencia de 3 = \"+Math.pow(2, 3));\n\t\tSystem.out.println(\"Genero un numero aleatorio : \"+Math.random());\n\t\t\n\t\t//Variables\n\t\t\n\t\tSystem.out.println(\"Accedemos a la variable local a con valor : \"+ AccesoVariables());\n\t\tSystem.out.println(\"Comprobamos la variable global a : \"+a);\n\t\t\n\t\t/* DIFICULTAD EXTRA (opcional):\n     * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n     * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n     *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n     *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n     *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n     *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n     *\n     * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n     * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n     */\n\t\tSystem.out.println(\"Se ha impreso un numero: \"+X(\"Soy multiplo de 3\", \"Soy multiplo de 5\")+\" veces\");\n\t}\n\tpublic static int X (String a, String b) {\n\t\tint contador = 0;\n\t\tfor (int i = 1; i < 100; i++) {\n\t\t\tif ((i%5==0)&&(i%3==0)){\n\t\t\t\tSystem.out.println(a+\" y tambien \"+b);\n\t\t\t}else if (i%3==0) {\n\t\t\t\tSystem.out.println(a);\n\t\t\t}else if (i%5==0) {\n\t\t\t\tSystem.out.println(b);\n\t\t\t}else {\n\t\t\t\tSystem.out.println(i);\n\t\t\t\tcontador++;\n\t\t\t}\n\t\t\t\t\t\t\n\t\t}\n\t\treturn contador;\n\t}\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/Rubioj17.java",
    "content": "public class Rubioj17 {\n    static String variableGlobal = \"Global\";\n\n    public static void main(String[] args) {\n        int numeroDeLetras, numDeVeces;\n        String nombreEdad;\n        saludo();\n        saludoConParametros(\"Rubioj17\");\n        saludoConParametros(\"Rubioj17\", \"Alegre\");\n        System.out.println(edad(20));\n        nombreEdad = saludoLLamandoFuncion(\"Rubioj17\", 20);\n        System.out.println(nombreEdad);\n        numeroDeLetras = usandoFuncionesDelSistema(nombreEdad);\n        System.out.println(\"En la anterior oracion hay \" + numeroDeLetras + \" carateres\");\n        localGlobal();\n        numDeVeces = dificultadExtra(\"Primer Texto\", \"Segundo Texto\");\n        System.out.println(\"\\nLos Numeros se Imprimieron \" + numDeVeces);\n    }\n    //Sin parámetros ni retorno,\n    static void saludo() {\n        System.out.println(\"Hola\");\n    }\n\n    //Con uno o varios parámetros\n    static void saludoConParametros(String nombre) {\n        System.out.println(\"Hola \" + nombre);\n    }\n\n    static void saludoConParametros(String nombre, String estadoEmocional) {\n        System.out.println(\"Hola \" + nombre + \", hoy te encuentras \" + estadoEmocional);\n    }\n\n    //Con retorno\n    static int edad(int n) {\n        return n;\n    }\n\n    //Comprueba si puedes crear funciones dentro de funciones.\n    //* * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n    //*Por lo que tengo entendido no se pueden crear funciones*\n    //*dentro de funciones a menos que se use lambda          *\n    //* * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\n    //LLamar funciones dentro de otras funciones\n    static String saludoLLamandoFuncion(String nombre, int n) {\n        return \"Hola \" + nombre + \" tienes \" + edad(n) + \" Años\";\n    }\n\n    //Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n    static int usandoFuncionesDelSistema(String palabra) {\n        return palabra.length();\n    }\n\n    //Pon a prueba el concepto de variable LOCAL y GLOBAL.\n    static void localGlobal() {\n        String variableLocal = \"Local\";\n        System.out.println(variableGlobal + \" \"+ variableLocal);\n    }\n\n    //* * * * * * * * * *\n    //*DIFICULTAD EXTRA *\n    //* * * * * * * * * *\n    static int dificultadExtra(String texto1, String texto2) {\n        int c = 0;\n        for (int i = 1; i <= 100; i++) {\n            if (i % 3 == 0 && i % 5 == 0) System.out.print(texto1+texto2);\n            else if (i % 3 == 0) System.out.print(texto1);\n            else if (i % 5 == 0) System.out.print(texto2);\n            else {\n                System.out.print(\" \"+ i + \",\");\n                c++;\n            }\n        }\n        return c;\n    }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/Ruthmp.java",
    "content": "/*\n        * - Crea ejemplos de funciones básicas que representen las diferentes\n        *   posibilidades del lenguaje:\n        *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n        * - Comprueba si puedes crear funciones dentro de funciones.\n        * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n        * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n        * - Debes hacer print por consola del resultado de todos los ejemplos.\n        *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n        * DIFICULTAD EXTRA (opcional):\n        * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n        * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n        *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n        *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n        *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n        *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n        *\n        * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n        * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\npublic class Funciones_Alcance {\n\n    static String variableGlobal = \"Esto es una variable Global\"; //Variable Global, sin parámetro ni retorno\n\n    /**\n     * @param args the command line arguments\n     */\n    public static void main(String[] args) {\n\n        //Acceder a la variable Glogal:\n        System.out.println(variableGlobal);\n\n        //Acceder a la función sin parámetro:\n        saludar();\n\n        //Acceder al método con parámetros:\n        saludarN(\"Ruth\");\n\n        //Acceder a la función con parámetros:\n        double numero = 12;\n        double raizC = raizCuadrada(numero);\n        System.out.println(\"La raiz cuadrada de \" + numero + \" es \" + raizC);\n\n        //Acceder al método extra:\n        String texto1 = \"fizz\";\n        String texto2 = \"Buzz\";\n        fizzBuzz(texto1, texto2);\n    }\n\n    public static void variables() {\n        String variableLocal = \"Esto es una variable local\";\n\n        //Acceder a la variable local\n        System.out.println(variableLocal);\n\n    }\n\n    //Función con retorno sin parámetros:\n    static String saludar() {\n        String saludo = \"Hola \";\n        return saludo;\n    }\n\n    //método con parámetros:\n    static void saludarN(String nombre) {\n        System.out.println(saludar() + nombre);\n    }\n\n    //Función con parámetros + función ya creada:\n    static double raizCuadrada(double numero) {\n        return Math.sqrt(numero);\n    }\n\n    //Extra:\n    static int fizzBuzz(String texto1, String texto2) {\n        int count = 0;\n        for (int i = 1; i <= 100; i++) {\n            if (i % 3 == 0) {\n                System.out.println(texto1);\n            } else if (i % 5 == 0) {\n                System.out.println(texto2);\n            } else if (i % 3 == 0 && i % 5 == 0) {\n                System.out.println(texto1 + texto2);\n            } else {\n                System.out.println(i);\n            }\n            count++;\n        }\n        return count;\n    }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/TofeDev.java",
    "content": "public class TofeDev {\n    //--- Variables Globales\n    static int globalVariable1 = 100;\n    static int globalVariable2 = 20;\n    public static void main(String[] args) {\n        \n        //Función básica / Sin retorno ni parámetros\n        bienvenida();\n\n        //Función con parámetro\n        estadoClima(\"soleado\");\n\n        //Función con varios parámetros\n        parejaMesa(\"José Hernandez\", \"María Valdez\");\n\n        //Función con retorno\n        int resultadoSuma = sumar(globalVariable1, globalVariable2);\n        System.out.println(\"Resultado de la suma: \" + resultadoSuma);\n\n        //--- Variables locales\n        int localVariable1 = 5;\n        int localVariable2 = 20;\n\n        //Funciones dentro de funciones\n        int[] resultado2 = funcionDoble(localVariable1, localVariable2);\n        System.out.println(\"Los resultados son: \" + resultado2[0] + \" (suma) y \" + resultado2[1] + \" (multiplicación)\");\n\n        //Dificultad Extra\n        Extra(\"FIZZ\", \"BUZZ\");\n\n    }\n\n    //Función básica / Sin retorno ni parámetros\n    public static void bienvenida() {\n        System.out.println(\"Les damos la bienvenida a nuestra casa\");\n    }\n\n    //Función con parámetro \n    public static void estadoClima(String clima) {\n        System.out.println(\"Hoy el clima está \" + clima);\n    }\n\n    //Función con varios parámetros\n    public static void parejaMesa(String p1, String p2) {\n        System.out.println(\"Esta mesa está reservada para \" + p1 + \" y \" + p2);\n    }\n\n    //Funciones con retorno\n    public static int sumar(int a, int b) {\n        return a + b;\n    }\n\n    public static int multiplicacion(int c, int d) {\n        return c * d;\n    }\n\n    //Funciones dentro de funciones\n    public static int[] funcionDoble(int e, int f) {\n        int g = sumar(e, f);\n        int h = multiplicacion(e, f);\n        return new int[] {g, h};\n\n    }\n\n   /* \n    * DIFICULTAD EXTRA\n    * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n    * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n    *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n    *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n    *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n    *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos. \n    */\n\n    public static void Extra(String cadena1, String cadena2) {\n        for (int i = 1; i <= 100; i++) {\n            if (i % 3 == 0 && i % 5 == 0) {\n                System.out.println(cadena1 + cadena2);\n            } else if (i % 3 == 0) {\n                System.out.println(cadena1);\n            } else if (i % 5 == 0) {\n                System.out.println(cadena2);\n            } else {\n                System.out.println(i);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/Verschlingendenacht.java",
    "content": "public class Verschlingendenacht {\n\n    public static void main(String[] args) {\n        /*\n         * TIPOS DE FUNCIONES (METODOS) EN JAVA:\n         *\n         * 1- Funciones void (no retornan valor)\n         * 2- Funciones que retornan un tipo (int, String, etc).\n         * 3- Sin parametros y sin valor de retorno\n         * 4- Con parametros y sin valor de retorno\n         * 5- Sin parametros y con valor de retorno\n         * 6- Con parametros y con valor de retorno\n         * 7- Funciones estaticas (static)\n         * 8- Funciones no estaticas\n         * 9- Expresiones Lambda\n         * 10- Sobrecarga de Metodos o Constructores\n         * */\n\n        /*\n         * SINTAXIS GENERAL DE UNA FUNCION (METODO)\n         *\n         * modificador_de_acceso [static] tipo_de_retorno nombreFuncion(parametros) {\n         *   //Cuerpo de la funcion\n         *   //return valor; (si no es void)\n         * }\n         * */\n\n        /*\n         * MODIFICADORES DE ACCESO\n         *\n         * public - accesible desde cualquier clase\n         * private - accesible solo dentro de la misma clase\n         * protected - accesible desde la misma clase y subclases\n         * */\n\n        imprimirResultadosPorConsola();\n\n    }\n\n    static public void imprimirResultadosPorConsola(){\n\n        //ESTA FUNCION IMPRIME LOS RESULTADOS DE TODOS LOS EJERCICIOS DE ABAJO EN ORDEN\n\n        mostrarMensaje();\n        System.out.println(obtenerNombreCompleto(\"Juan\", \"Roberto\"));\n        saludar();\n        mostrarSuma(2,4);\n        System.out.println(obtenerMensaje());\n        System.out.println(multiplicar(9,9));\n        System.out.println(cuadrado(2));\n\n        //CONTINUACION EJEMPLO NO ESTATICO\n        Verschlingendenacht ejemploNoEstatico = new Verschlingendenacht();\n        int resultado = ejemploNoEstatico.restar(10, 4);\n        System.out.println(resultado);\n\n        //CONTINUACION EJEMPLO LAMBDA\n        System.out.println(suma.ejecutar(3, 4));\n\n        //CONTINUACION EJEMPLO SOBRECARGA\n        Verschlingendenacht objetoSobrecargado = new Verschlingendenacht(\"Alejandro\", 14, 1.67f);\n        objetoSobrecargado.imprimirAtributos();\n        Verschlingendenacht objetoSobrecargado2 = new Verschlingendenacht(\"Santiago\", 27);\n        objetoSobrecargado2.imprimirAtributos();\n        Verschlingendenacht objetoSobrecargado3 = new Verschlingendenacht(\"Pedro\");\n        objetoSobrecargado3.imprimirAtributos();\n\n        funcionesPredefinidasJava();\n\n        //CONTINUACION EJEMPLO LOCAL Y GLOBAL\n        Verschlingendenacht obj = new Verschlingendenacht();\n        obj.mostrarNumeros();  // Muestra valores antes del cambio\n        obj.cambiarGlobal();   // Cambia la variable global\n        obj.mostrarNumeros();  // Muestra valores después del cambio\n\n        //EJERCICIO EXTRA\n        System.out.println(ejercicioExtra(\"Hola\", \"Mundo\"));\n        \n    }\n\n    //EJEMPLOS\n\n    //1- Funcion void (no retorna nada)\n    //En Java usamos palabras clave que indican lo que se espera salga de nuestra funcion\n    //Por ejemplo, si queremos indicar que no queremos retornar nada, usamos 'void' (vacio)\n    public static void mostrarMensaje() {\n        System.out.println(\"Hola, estamos en Java!\");\n    }\n\n    //2- Funcion que retorna algo\n    //Tenemos acceso a otras palabras claves para indicar el tipo de dato a retornar como:\n    //void, int, String, float, etc\n    public static String obtenerNombreCompleto(String nombre, String apellido) {\n        return nombre + apellido;\n    }\n\n    //3- Funcion sin parametros y sin retorno\n    public static void saludar() {\n        System.out.println(\"Hola!\");\n    }\n\n    //4- Funcion con parametros y sin retorno\n    public static void mostrarSuma(int a, int b){\n        System.out.println(\"La suma es: \" + (a + b));\n    }\n\n    //5- Funcion sin parametros y con retorno\n    public static String obtenerMensaje(){\n        return \"Hola mundo\";\n    }\n\n    //6- Funcion con parametros y con retorno\n    public static int multiplicar(int x, int y){\n        return x * y;\n    }\n\n    //7- Funcion estatica\n    //static se refiere a que se puede llamar sin crear un objeto de la clase en donde esta definida\n    public static int cuadrado(int n){\n        return n * n;\n    }\n\n    //8- Funcion no estatica (de instancia)\n    //Para llamar a una funcion no estatica se requiere crear un objeto de la clase para poder llamarla\n    //Instanciaremos un objeto de la clase y llamaremos este metodo de ejemplo dentro de la funcion imprirmirResultadosPorConsola\n    public int restar(int a, int b){\n        return a - b;\n    }\n\n    //9- Expresiones Lambda\n    //Son una forma compacta y funcional de escribir funciones anonimas (es decir, sin nombre)\n    //Permiten que podamos definir funciones sin nombre que podemos usar como si fuesen valores\n    /*\n    * SINTAXIS BASICA:\n    * (parametros) -> { cuerpo de la funcion }\n    *\n    * REQUISITOS:\n    * Para que pueda funcionar, debemos definir una interfaz\n    * Haremos esto fuera de la clase\n    */\n    static Operacion suma = (a, b) -> a + b; //Veamos el resultado de esta expresion imprimiendo el resultado desde la funcion imprimirResultadosPorConsola\n\n    //10- Sobrecarga de Metodos o Constructores\n    //Java directamente no soporta conceptos como argumentos por defecto, en cambio, podemos obtener un efecto simulado por medio de sobrecarga de funciones\n    //Definamos algunos atributos para el ejemplo\n    private String nombre;\n    private int edad;\n    private float altura;\n\n    public Verschlingendenacht(String nombre){\n        this.nombre = nombre;\n        this.edad = 24;\n        this.altura = 1.74f;\n    }\n\n    public Verschlingendenacht(String nombre, int edad){\n        this.nombre = nombre;\n        this.edad = edad;\n        this.altura = 1.74f;\n    }\n\n    public Verschlingendenacht(String nombre, int edad, float altura){\n        this.nombre = nombre;\n        this.edad = edad;\n        this.altura = altura;\n    }\n\n    public void imprimirAtributos(){\n        System.out.println(this.nombre);\n        System.out.println(this.edad);\n        System.out.println(this.altura);\n    }\n\n    //FUNCIONES ANIDADAS\n    //Java NO permite declarar un metodo dentro de otro metodo, como si ocurre en otros lenguajes como Python o JavaScript\n    //¿Pero que se usa en su lugar entonces?\n    /*\n    * 1- Clases internas\n    * 2- Expresiones lambda (desde Java 8)\n    * 3- Funciones auxiliares privadas llamadas dentro de otras funciones\n    * */\n\n    static void funcionesPredefinidasJava(){\n\n        //EJEMPLOS DE FUNCIONES PREDEFINIDAS EN JAVA\n        //Como en muchos otros lenguajes de programacion, Java tambien cuenta con funciones ya definidas dentro del lenguaje como:\n        String miCadena = \"Esta Es Una Cadena Para Nuestro Ejemplo\";\n        System.out.println(miCadena.charAt(0)); //Trata a la cadena como un arreglo y retorna el caracter almacenado en el indice especificado\n        System.out.println(miCadena.toUpperCase()); //Retorna la misma cadena en mayusculas\n        System.out.println(miCadena.toLowerCase()); //Retorna la misma cadena en minusculas\n        System.out.println(miCadena.equals(\"Esta es una cadena para nuestro ejemplo\")); //Retorna verdadero si la cadena equivale al parametro de la funcion\n\n    }\n\n    //ENFOQUE LOCAL Y GLOBAL EN JAVA\n    // Variable global (de instancia)\n    int numero = 10;\n\n    public void mostrarNumeros() {\n        // Variable local\n        int numero = 5;\n\n        System.out.println(\"Número local: \" + numero);         // Imprime 5\n        System.out.println(\"Número global: \" + this.numero);   // Imprime 10\n    }\n\n    public void cambiarGlobal() {\n        // Modifica la variable global\n        this.numero = 20;\n    }\n\n    public Verschlingendenacht(){\n    }\n    //Ahora ejecutemos este ejemplo desde la funcion imprimirResultadosPorPantalla\n\n    //DIFICULTAD EXTRA\n    public static int ejercicioExtra(String cadena1, String cadena2){\n        int numeroVeces = 0;\n        for(int i = 1; i < 101; i++){\n            if(i%3==0){\n                System.out.println(cadena1);\n                if(i%5==0){\n                    System.out.println(cadena1+cadena2);\n                }\n            }else if(i%5==0){\n                System.out.println(cadena2);\n            }else{\n                System.out.println(i);\n                numeroVeces++;\n            }\n        }\n        return numeroVeces;\n    }\n\n}\n\n\n//Interfaz de soporte para ejemplo de expresiones lambda\ninterface Operacion {\n    int ejecutar(int a, int b);\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/VolumiDev.java",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\nimport java.io.*;\npublic class VolumiDev {\n\tpublic static BufferedReader leer=new BufferedReader(new InputStreamReader(System.in));\n\t\n\t//metodo sin retorno ni parametros\n\tpublic static void HolaJava() {\n\t\t\n\t\tSystem.out.println(\"Hola Java.\");\n\t}\n\t\n\t//Metodo con retorno de un entero y sin parametros y publico\n\tpublic static int pedirnum(String cad) throws NumberFormatException, IOException {\n\t\tint num;\n\t\tSystem.out.println(cad);\n\t\tnum=Integer.parseInt(leer.readLine());\n\t\treturn num;\n\t}\n\t\n\t//Metodo con retorno de un double y 3 parametros\n\tprivate static double pedirn2(String cad, int l1, int l2) throws NumberFormatException, IOException {\n\t\tdouble n;\n\t\tdo {\n\t\t\tSystem.out.println(cad+l1+\" y \"+l2);\n\t\t\tn=Double.parseDouble(leer.readLine());\n\t\t} while (n<l1 || n>l2);\n\t\treturn n;\n\t}\n\t\n\t//metodo que retorna un String;\n\tpublic static String pedircad() throws IOException {\n\t\tSystem.out.println(\"Introduce una cadena de caracteres\");\n\t\treturn leer.readLine();\n\t}\n\t\n\t//metodo que no retorna nada y al que le pasamos 2 parametros\n\tprivate static void mostrarcad(String cad, int n) {\n\t\tfor(int i=0; i<n; i++) {\n\t\t\tSystem.out.println(cad);\n\t\t}\n\t}\n\n\t\n\tpublic static void main(String[] args) throws NumberFormatException, IOException {\n\t\t// TODO Auto-generated method stub\n\t\tString cad;\n\t\tHolaJava();\n\t\t\n\t\tSystem.out.println(pedirnum(\"Introducen un numero entero\"));\n\n\t\tSystem.out.println(pedirn2(\"Introduce un numero real entre \", 5, 10));\n\t\t\n\t\tmostrarcad(pedircad(), pedirnum(\"Introduce el numero de veces que quieres que se repita la cadena que acabas de introducir\"));\n\t\t\n\t\tSystem.out.println(\"NO SE PUEDE GENERAR METODOS DENTRO DE UN METODO, PUEDES LLAMAR A UN METODO DENTRO DE OTRA, PERO NO CREARLOS.\");\n\t\t\n\t\t// Con la funcion .length de la clase string podemos saber la longitud de la cadena de caracteres.\n\t\t\n\t\tcad=pedircad();\n\t\t\t\tSystem.out.println(\"La palabra \"+cad+\" tiene \"+cad.length()+\" caracteres\");\n\t}\n\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/Worlion.java",
    "content": "import java.util.logging.ConsoleHandler;\nimport java.util.logging.LogRecord;\nimport java.util.logging.Logger;\nimport java.util.logging.SimpleFormatter;\n\npublic class Worlion {\n    private static Logger log = Logger.getLogger(Worlion.class.getName());\n    static {\n        log.setUseParentHandlers(false);\n        ConsoleHandler consoleHandler = new ConsoleHandler();\n        consoleHandler.setFormatter(new SimpleFormatter() {\n            @Override\n            public String format(LogRecord record) {\n                return record.getMessage() + \"\\n\";\n            }\n        });\n        log.addHandler(consoleHandler);\n    }\n\n    /*\n    * EJERCICIO: FUNCIONES Y ALCANCE\n    */\n\n\n    public static void main(String[] args) {\n        log.info(\" \\nFUNCIONES Y ALCANCE:\\n\");\n\n        funcionSinRetornoNiParametro();\n        funcionConUnParametro(\"con un parámetro\");\n        funcionConVariosParametros(\"con varios\", \"parámetros\");\n        log.info(\"Funcion con retorno: \" + funcionConRetorno());\n        funcionConFuncion();\n        funcionesDeJava();\n        variableLocal();\n\n\n        log.info(\" \\n ---- 🌩 DIFICULTAD EXTRA 🌩 ----\\n\");\n        log.info(\"Ejercicio Extra: \" + extra(\"chori\", \"pan\"));\n\n    }\n\n    private static void funcionSinRetornoNiParametro(){\n        log.info(\"Funcion sin retorno ni parametro: sólo hace este print\");\n    }\n\n    private static void funcionConUnParametro(String parametro){\n        log.info(\"Funcion con un parametro: \" + parametro);\n    }\n\n    private static void funcionConVariosParametros(String parametro1, String parametro2){\n        log.info(\"Funcion con varios parametros: \" + parametro1 + \" \" + parametro2);\n    }\n\n    private static String funcionConRetorno(){\n        return \"Funcion con retorno: devuelve este texto\";\n    }\n\n    private static void funcionConFuncion(){\n        class InnerClass {\n            public static void innerMethod() {\n                log.info(\"Este es un método interno.\");\n            }\n        }\n        log.info(\"Esto es, hasta donde yo sé, lo más parecido a definir funciones dentro de funciones.\");\n        InnerClass.innerMethod();\n    }\n\n    private static void funcionesDeJava() {\n        log.info(\"Funciones de Java: Math.random() = \" + Math.random());\n        log.info(\"Funciones de Java: Math.min(5, 10) = \" + Math.min(5, 10));\n    }\n\n    private static String variableGlobal = \"Soy una variable global\";\n\n    private static void variableLocal() {\n        String variableLocal = \"Soy una variable local\";\n        log.info(variableGlobal);\n        log.info(variableLocal);\n    }\n\n\n    /*\n    * DIFICULTAD EXTRA (opcional):\n    * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n    * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n    *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n    *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n    *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n    *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n    *\n    * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n    * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n    */\n    private static int extra(String str1, String str2){\n        int count = 0;\n        for(int i = 1; i <= 100; i++){\n            if(i % 3 == 0 && i % 5 == 0){\n                log.info(str1 + str2);\n            } else if(i % 3 == 0){\n                log.info(str1);\n            } else if(i % 5 == 0){\n                log.info(str2);\n            } else {\n                log.info(String.valueOf(i));\n                count ++;\n            }\n        }\n        return count;\n    }\n\n\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/Zugarramurdi.java",
    "content": "/**\n * En la clase Zugarramurdi se implementaará la solucion al ejercicio #02 - FUNCIONES Y ALCANCE\n * @author Zugarramurdi\n * @version 1.0 08/04/2025\n */\npublic class Zugarramurdi {\n\n    // Variables locales y globales\n\n    /* Las variables locales son aquellas que se declaran dentro de una funcion y solo se pueden usar dentro de esa funcion,\n     * incluso si se declaran dentro de un bloque de codigo, como un if o un for, por ejemplo todas las variables de las funciones\n     * creadas mas abajo o incluso las del propio metodo main\n     *\n     * Las variables globales son aquellas que se declaran fuera de una funcion y se pueden usar en cualquier parte del programa,\n     * incluso dentro de las funciones, por ejemplo las variables que se declaran, en este caso, dentro de la clase Zugarramurdi\n     * se les llama tambien variables de instancia, por declararse dentro de una clase\n     */\n\n    static String texto1 = \"Pipo\", texto2 = \"Pepo\"; // variables globales\n\n    public static void main(String[] args) {\n\n        // Llamada a las funciones\n\n        funcion1(); // Funcion sin parametros ni retorno\n        funcion2(\"Hola a todos\"); // Funcion con un parametro y sin retorno\n        funcion3(5, 10); // Funcion con dos parametros y sin retorno\n        int resultado = funcion4(5, 10); // Funcion con dos parametros y retorno\n        System.out.println(\"\\nEl resultado de la suma de funcion4 es: \" + resultado+\"\\n\"); // Imprime el resultado de la funcion 4\n        extra(texto1, texto2); // Llamamos a la funcion de ejercicio extra con variables globales\n\n\n\n\n    }\n\n    // Funcion sin parametros ni retorno\n    public static void funcion1() {\n        System.out.println(\"\\nEsta es una funcion sin parametros ni retorno\\n\");\n    }\n\n    // Funcion con un parametro y sin retorno\n    public static void funcion2(String mensaje) {\n        System.out.println(\"\\nEsta es una funcion con un parametro: \" + mensaje+\"\\n\");\n    }\n\n    // Funcion con dos parametros y sin retorno\n    public static void funcion3(int numero1, int numero2) {\n        System.out.println(\"\\nEsta es una funcion con dos parametros: \" + numero1 + \" y \" + numero2);\n        System.out.println(\"Se pueden realizar operaciones con los parametros: \" + (numero1 + numero2)+\"\\n\");\n    }\n\n    // Funcion con dos parametros y retorno\n    public static int funcion4(int numero1, int numero2) {\n        return numero1 + numero2;\n    }\n\n    // Funcion dentro de funcion\n\n    /* En java no se pueden declarar funciones dentro de otras funciones, pero se pueden llamar a otras funciones dentro de una funcion,\n     * de hecho, en las funciones 1,2 y 3 se llama a la funcion System.out.println(); *que es una funcion ya creada por el lenguaje*\n     * lo mas comun es que se declaren funciones dentro de una clase y se llamen desde el main\n     * aqui por ejemplo estamos declarando funciones dentro de la clase Zugarramurdi y llamandolas desde el main\n     */\n\n    // Funcion ya creada por el lenguaje\n\n    /* Las funciones ya creadas por el lenguaje son funciones que ya vienen incluidas en el lenguaje y se pueden usar directamente\n     * Java tiene muchas funciones ya creadas, como por ejemplo la funcion System.out.println(); que se usa para imprimir en pantalla\n     * tambien existen funciones matematicas de la clase Math, como Math.random(); que genera un numero aleatorio o Math.sqrt(); que calcula la raiz cuadrada\n     * la clase String tambien tiene funciones ya creadas, como String.length(); que devuelve la longitud de una cadena de texto\n     */\n\n    // Ejercicio Extra\n\n    public static int extra(String mensaje1, String mensaje2) {\n        int contador = 0;\n        System.out.println(\"\\n\\tEjercicio Extra\\n\");\n        for (int i = 1; i <= 100; i++){\n            if(i % 3 == 0 && i % 5 == 0){\n                System.out.println(mensaje1 + \" \" + mensaje2);\n            }else if(i % 3 == 0){\n                System.out.println(mensaje1);\n            }else if(i % 5 == 0){\n                System.out.println(mensaje2);\n            }else{\n                System.out.println(i);\n                contador++;\n            }\n        }\n        return contador;\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/agusrosero.java",
    "content": "public class agusrosero {\n    public static void main(String[] args) {\n        System.out.println(\"Hola mundo\");\n        System.out.println(\"La suma de 5 + 5 es: \" + sumar(5, 5));\n        System.out.println(\"La resta de 10 - 5 es: \" + restar());\n        multiplicar(5, 5);\n        agusrosero ar = new agusrosero();\n        ar.metodoExterno();\n        imprimirNumeros(\"Fizz\", \"Buzz\");\n    }\n\n    public static int sumar(int a, int b) {\n        return a + b;\n    }\n\n    public static int restar() {\n        return 10 - 5;\n    }\n\n    public static void multiplicar(int a, int b) {\n        System.out.println(\"El resultado de la multiplicación es: \" + (a * b));\n    }\n\n    public void metodoExterno() {\n        class ClaseInterna {\n            public void metodoInterno() {\n                System.out.println(\"Método interno\");\n            }\n        }\n        ClaseInterna ci = new ClaseInterna();\n        ci.metodoInterno();\n    }\n\n    // Variable LOCAL y GLOBAL\n    int variableGlobal = 10;\n\n    public void metodoExterno2() {\n        int variableLocal = 5;\n        System.out.println(\"Variable global: \" + variableGlobal);\n        System.out.println(\"Variable local: \" + variableLocal);\n    }\n\n    /*\n     * * DIFICULTAD EXTRA (opcional):\n     * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne\n     * un número.\n     * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n     * - Si el número es múltiplo de 3, muestra la cadena de texto del primer\n     * parámetro.\n     * - Si el número es múltiplo de 5, muestra la cadena de texto del segundo\n     * parámetro.\n     * - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto\n     * concatenadas.\n     * - La función retorna el número de veces que se ha impreso el número en lugar\n     * de los textos.\n     */\n    public static int imprimirNumeros(String texto1, String texto2) {\n        int contador = 0;\n        for (int i = 1; i <= 100; i++) {\n            if (i % 3 == 0 && i % 5 == 0) {\n                System.out.println(texto1 + texto2);\n            } else if (i % 3 == 0) {\n                System.out.println(texto1);\n            } else if (i % 5 == 0) {\n                System.out.println(texto2);\n            } else {\n                System.out.println(i);\n            }\n            contador++;\n        }\n        return contador;\n    }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/alvarofernandezavalos.java",
    "content": "public class alvarofernandezavalos {\n\n  public static int globalInt = 10;\n\n  public static void main(String[] args) {\n    funcionSinParametrosNiRetorno();\n    System.out.println(funcionSinParametrosConRetorno());\n    funcionConParemetroSinRetorno(\"alvarofernandezavalos\");\n    System.out.println(funcionConParametroConRetorno(\"alvarofernandezavalos\"));\n    System.out.println(funcionConDosParametrosConRetorno(\"alvarofernandez\", \"avalos\"));\n    System.out.println(funcionConNParametrosConRetorno(1,2,3,4,5,6,10));\n    System.out.println(\"Java Home: \"+getJavaHome());\n    System.err.println(\"Operating System: \"+getOS());\n    variableGlobalyLocal();\n    System.out.println(\"La función retorna el número de veces que se ha impreso el número en lugar de los textos: \" + opcional(\"tortuga\",\"grande\"));\n  }\n\n  private static int opcional(String a, String b) {\n    int numero=0;\n    for(int i = 1; i <= 100 ; i++) {\n      if (i%3==0) System.out.println(a);\n      if (i%5==0) System.out.println(b);\n      if (i%3==0 && i%5==0) System.out.println(a.concat(b));\n      if (i%3!=0 && i%5!=0) {\n        numero++;\n        System.out.println(i);\n      }\n    }\n    return numero;\n  }\n\n  private static void variableGlobalyLocal() {\n    int globalInt;\n    globalInt = 100;\n    System.out.println(\"La variable local globalInt en esta funcion vale: \" + globalInt);\n    System.out.println(\"La variable global globalInt vale: \" + alvarofernandezavalos.globalInt);\n  }\n\n  public static void funcionSinParametrosNiRetorno() {\n    System.out.println(\"funcionSinParametrosNiRetorno\");\n  }\n\n  public static String funcionSinParametrosConRetorno() {\n    return \"retorno\";\n  }\n\n  public static void funcionConParemetroSinRetorno(String texto) {\n    System.out.println(\"Parametro 1: \"+texto);\n  }\n\n  public static String funcionConParametroConRetorno(String texto) {\n    return texto;\n  }\n\n  public static String funcionConDosParametrosConRetorno(String texto, String texto2) {\n    return texto.concat(texto2);\n  }\n\n  public static int funcionConNParametrosConRetorno (int ... numeros) {\n    int suma = 0;\n    for (int i : numeros) {\n      suma += i;\n    }\n    return suma;\n  }\n\n  public static String getJavaHome() {\n    return System.getProperty(\"java.home\");\n  }\n\n  public static String getOS() {\n    return System.getProperty(\"os.name\");\n  }\n\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/asjordi.java",
    "content": "public class Main {\n\n    public static final String LENGUAJE = \"Java\";\n\n    /**\n     * En Java las funciones pueden retornar un valor, o no retornar nada.\n     * Pueden recibir uno o más parámetros, o no recibir ninguno.\n     * Pueden ser llamadas sin la necesidad de instanciar un objeto.\n     * Pueden ser llamadas desde otras funciones.\n     * Pueden ser sobrecargadas, es decir, tener el mismo nombre pero diferentes parámetros.\n     * Pueden ser sobreescritas, es decir, tener el mismo nombre y parámetros pero diferentes implementaciones.\n     * static indica que la función pertenece a la clase y no a un objeto, por lo tanto no es necesario instanciar un objeto para llamarla.\n     */\n\n    /**\n     * En Java existen los modificadores de acceso, los cuales son:\n     * default: Visible dentro del mismo paquete\n     * public: Visible desde cualquier parte del proyecto\n     * private: Visible solo dentro de la clase\n     * protected: Visible dentro del mismo paquete y en las clases hijas (herencia)\n     */\n\n    public static void main(String[] args) {\n        saludar();\n        mensaje(\"ASJordi\");\n        mensajeCompleto(\"Jorge\", \"Garcia\");\n\n        String saludo = saludar2();\n        System.out.println(saludo);\n        String saludo2 = mensaje2(\"Pedro\");\n        System.out.println(saludo2);\n        int resultado = suma(2, 3);\n        System.out.println(\"2 + 3 = \" + resultado);\n        double resultado2 = suma(2.5, 3.5);\n        System.out.println(\"2.5 + 3.5 = \" + resultado2);\n\n        System.out.println(new Main().toString());\n\n        // Ejemplo de función propia de Java\n        System.out.println(\"2 elevado al cuadrado es: \" + Math.pow(2, 2));\n\n        /**\n         * Una variable local es una variable que es declarada dentro de un scope (bloque de código) y solo puede ser accedida dentro de ese scope.\n         * Una variable global es una variable que es declarada fuera de un scope y puede ser accedida desde cualquier parte del proyecto.\n         */\n\n        // Variable local\n        int a = 2;\n\n        // Variable global\n        System.out.println(\"PI es una variable global: \" + Math.PI);\n        System.out.println(\"LENGUAJE es una variable global: \" + LENGUAJE);\n\n        // RETO\n        System.out.println(\"-------------------- RETO --------------------\");\n        int res = retornarNumero(\"Java\", \"Roadmap\");\n        System.out.println(\"El número de veces que se ha mostrado por consola el número es: \" + res);\n    }\n\n    /**\n     * Funciones sin retorno\n     * Cuando una función no retorna un valor en Java se utiliza la palabra reservada void.\n     */\n\n    // Función que no retorna nada y no recibe parámetros\n    public static void saludar() {\n        System.out.println(\"Hola mundo!\");\n    }\n\n    // Función que no retorna nada y recibe un parámetro\n    public static void mensaje(String nombre) {\n        System.out.println(\"Hola \" + nombre + \"!\");\n    }\n\n    // Función que retorna un valor y recibe múltiples parámetros\n    public static void mensajeCompleto(String nombre, String apellido) {\n        System.out.println(\"Hola \" + nombre + \" \" + apellido + \"!\");\n    }\n\n    /**\n     * Funciones con retorno\n     * Cuando una función retorna un valor en Java se utiliza el tipo de dato que retorna la función.\n     * El tipo de dato de retorno puede ser un tipo de dato primitivo o un objeto.\n     */\n\n    // Función que retorna un valor y no recibe parámetros\n    public static String saludar2() {\n        return \"Hola mundo!\";\n    }\n\n    // Función que retorna un valor y recibe un parámetro\n    public static String mensaje2(String nombre) {\n        return \"Hola \" + nombre + \"!\";\n    }\n\n    // Función que retorna un valor y recibe múltiples parámetros\n    public static int suma(int a, int b) {\n        return a + b;\n    }\n\n    /**\n     * Funciones sobrecargadas\n     * Las funciones sobrecargadas son funciones que tienen el mismo nombre pero diferentes parámetros.\n     * En el siguiente ejemplo tiene el mismo nombre pero el tipo de datos de los parámetros es diferente.\n     */\n\n    public static double suma(double a, double b) {\n        return a + b;\n    }\n\n    /**\n     * Funciones sobreescritas\n     * Las funciones sobreescritas son funciones que tienen el mismo nombre y parámetros pero diferentes implementaciones.\n     */\n\n    @Override\n    public String toString() {\n        return \"Hola mundo!, esto es una función sobreescrita\";\n    }\n\n    /**\n     * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n     * La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n     * - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n     * - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n     * - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n     * - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n     */\n\n    public static int retornarNumero(String a, String b) {\n        int count = 0;\n\n        for (int i = 1; i <= 100; i++) {\n            if (i % 3 == 0 && i % 5 == 0) System.out.println(a + \" \" + b);\n            else if (i % 3 == 0) System.out.println(a);\n            else if (i % 5 == 0) System.out.println(b);\n            else {\n                System.out.println(i);\n                count++;\n            }\n        }\n\n\n        return count;\n    }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/bladi23.java",
    "content": "public class bladi23 {\n    \n        // Variable global\n        static int globalVar = 10;\n    \n        // Función sin parámetros ni retorno\n        static void printHello() {\n            System.out.println(\"Hello, world!\");\n        }\n    \n        // Función con un parámetro y sin retorno\n        static void printNumber(int num) {\n            System.out.println(\"Number: \" + num);\n        }\n    \n        // Función con varios parámetros y sin retorno\n        static void suma(int num1, int num2) {\n            System.out.println(\"Sum: \" + (num1 + num2));\n        }\n    \n        // Función con retorno\n        static int conRetorno(int num) {\n            return num * 2;\n        }\n    \n        // Función que utiliza una función ya creada en el lenguaje (Math.sqrt)\n        static double getSquareRoot(int num) {\n            return Math.sqrt(num);\n        }\n    \n        // Función que prueba el concepto de variable local y global\n        static void variableLocalyGlobal() {\n            int localVar = 5; // Variable local\n            System.out.println(\"Global variable: \" + globalVar);\n            System.out.println(\"Local variable: \" + localVar);\n        }\n    \n        static int extra(String str1, String str2) {\n            int contador = 0;\n            for (int i = 1; i <= 100; i++) {\n                if (i % 3 == 0 && i % 5 == 0) {\n                    System.out.println(str1 + str2);\n                } else if (i % 3 == 0) {\n                    System.out.println(str1);\n                } else if (i % 5 == 0) {\n                    System.out.println(str2);\n                } else {\n                    System.out.println(i);\n                    contador++;\n                }\n            }\n            return contador;\n        }\n    \n        public static void main(String[] args) {\n            printHello();\n            printNumber(5);\n            suma(3, 4);\n            System.out.println(\"Double: \" + conRetorno(7));\n            System.out.println(\"Square root: \" + getSquareRoot(9));\n            variableLocalyGlobal();\n            int count = extra(\"Fizz\", \"Buzz\");\n            System.out.println(\"Count: \" + count);\n        }\n    }\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/cesar-ch.java",
    "content": "public class Main {\n    static int variableGlobal = 10;\n\n    public static void main(String[] args) {\n        // Función sin parámetros ni retorno\n        saludar();\n        // Función con un parámetro y retorno\n        int num = 5;\n        int resultadoCuadrado = cuadrado(num);\n        System.out.println(\"Cuadrado de \" + num + \": \" + resultadoCuadrado);\n        // Función con varios parámetros y retorno\n        int x = 3;\n        int y = 7;\n        int resultadoSuma = suma(x, y);\n        System.out.println(\"Suma de \" + x + \" y \" + y + \": \" + resultadoSuma);\n        // Función dentro de una función\n        int resultadoOperacion = operacionMatematica(2, 3);\n        System.out.println(\"Resultado de operación compleja: \" + resultadoOperacion);\n        // Variable local y global\n        funcionConVariables();\n        System.out.println(\"Variable global fuera de la función: \" + variableGlobal);\n        // DIFICULTAD EXTRA\n        int vecesImpreso = imprimirNumerosConTexto(\"Fizz\", \"Buzz\");\n        System.out.println(\"Número de veces impreso: \" + vecesImpreso);\n\n    }\n\n    // Función sin parámetros ni retorno\n    static void saludar() {\n        System.out.println(\"¡Hola, mundo!\");\n    }\n\n    // Función con un parámetro y retorno\n    static int cuadrado(int numero) {\n        return numero * numero;\n    }\n\n    // Función con varios parámetros y retorno\n    static int suma(int a, int b) {\n        return a + b;\n    }\n\n    // Función dentro de una función\n    static int cuadruple(int num) {\n        return num * 4;\n    }\n\n    static int operacionMatematica(int x, int y) {\n        return cuadruple(x) + cuadruple(y);\n    }\n\n    // Función con variables local y global\n    static void funcionConVariables() {\n        int variableLocal = 5;\n        System.out.println(\"Variable local dentro de la función: \" + variableLocal);\n        System.out.println(\"Variable global dentro de la función: \" + variableGlobal);\n    }\n\n    // DIFICULTAD EXTRA\n    static int imprimirNumerosConTexto(String texto1, String texto2) {\n        int contador = 0;\n\n        for (int i = 1; i <= 100; i++) {\n            if (i % 3 == 0 && i % 5 == 0) {\n                System.out.println(texto1 + texto2);\n            } else if (i % 3 == 0) {\n                System.out.println(texto1);\n            } else if (i % 5 == 0) {\n                System.out.println(texto2);\n            } else {\n                System.out.println(i);\n                contador++;\n            }\n        }\n\n        return contador;\n    }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/chartypes.java",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\npublic class chartypes {\n\n  static String globalVar = \"Global variable or Instance variable\";\n\n  class Functions {\n\n    public static void noParamsNoReturn() {\n      System.out.println(\"Function with no params and no returns\");\n    }\n\n    public static void withParams(int number) {\n      System.out.println(\"With params but no return. The number is: \" + number);\n    }\n\n    public static String withReturn(String text) {\n      return text;\n    }\n\n    public static void methodInside() {\n      System.out.println(withReturn(\"Im inside of other method\"));\n    }\n\n  }\n\n  class BuiltInFunctions {\n\n    public static void stringFunctions() {\n      String hello = \"Hello world\";\n      int length = hello.length();\n      char first = hello.charAt(0);\n      String subStr = hello.substring(6);\n      String upperCase = hello.toUpperCase();\n      String lowerCase = hello.toLowerCase();\n\n      System.out.println(\"String buit-in functions! \");\n      System.out.println(hello);\n      System.out.println(length);\n      System.out.println(first);\n      System.out.println(subStr);\n      System.out.println(upperCase);\n      System.out.println(lowerCase);\n    }\n\n    public static void intFunctions() {\n      int max = Math.max(4, 2);\n      int min = Math.min(10, 15);\n      int abs = Math.abs(-34);\n\n      System.out.println(\"Int built-in functions! \");\n      System.out.println(max);\n      System.out.println(min);\n      System.out.println(abs);\n    }\n\n  }\n\n  class BonusEx {\n    static int counter;\n\n    public static int exercise(String text1, String text2) {\n      for (int i = 0; i < 100; i++) {\n\n        if (i % 3 == 0 && i % 5 == 0) {\n          System.out.println(text1 + text2);\n\n        }\n\n        else if (i % 3 == 0) {\n          System.out.println(text1);\n        }\n\n        else if (i % 5 == 0) {\n          System.out.println(text2);\n        }\n\n        counter++;\n      }\n      return counter;\n    }\n\n  }\n\n  public static void main(String[] args) {\n    String localVar = \"Local variable\";\n\n    System.out.println(chartypes.globalVar);\n    System.out.println(localVar);\n\n    Functions.methodInside();\n    BuiltInFunctions.stringFunctions();\n    BuiltInFunctions.intFunctions();\n\n    System.out.println(BonusEx.exercise(\"fizz\", \"buzz\"));\n\n  }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/danhingar.java",
    "content": "public class danhingar {\n    //variable global\n    static int counter=10;\n    \n    public static void main(String[] args) {\n        greet();\n        System.out.println(returnGreet());\n        argGreet(\"Daniel\");\n        argsGreet(\"Hi\",\"Daniel\");\n        suma(2, 3);\n        methodInside(\"Pepe\");\n        variable_arg_greet(\"Ramón\",\"Curro\",\"Alfonso\");\n        upperCase(\"hello java\");\n        localAndGlobalVar();\n        counter--;\n        System.out.println(\"Contador global: \"+counter);\n        System.out.println(\"Nº veces impreso el número: \"+countPrints(\"zip\",\"zap\"));\n        \n    }\n\n    //Función publica(accesible desde cualquier instancia de la clase), sin retorno(void) y sin parámetros \n    public static void greet(){\n        System.out.println(\"¡Helloo!\");\n    }\n\n    //Función privada(sólo accesible dentro de la clase), con retorno y sin parámetros\n    private static String returnGreet(){\n        return \"Hello, Java!\";\n    }\n\n    //Funcion privada, con argumentos y sin retorno\n    private static void argGreet(String name){\n        System.out.println(\"Hola \".concat(name));\n    }\n\n    //Con varios argumentos y sin retorno\n    private static void argsGreet(String greet,String name){\n        System.out.println(String.format(\"%s %s!\", greet,name));\n    }\n\n    //Con varios argumentos y retorno\n    private static Double suma(double num1, double num2){\n        return num1+num2;\n    }\n\n    //Con un número variable de argumentos\n    private static void variable_arg_greet(String... names){\n        for (String name : names) {\n            System.out.println(String.format(\"Hi, %s!\",name));\n        }\n    }\n\n    private static void upperCase(String word){\n        System.out.println(word.toUpperCase());\n    }\n\n    //Funcion dentro de otra funcion\n    private static void methodInside(String name){\n        argsGreet(\"Hi\",name);\n    }\n\n    private static void localAndGlobalVar(){\n        int internalCounter = 0;\n        counter--;\n        internalCounter++;\n        System.out.println(counter);\n        System.out.println(internalCounter);\n    }\n\n\n    //EJERCICIO EXTRA\n    private static int countPrints(String text1, String text2){\n        int counter = 0;\n        for(int i=1; i<=100;i++){\n            if(i%3==0 && i%5==0){\n                System.out.println(text1.concat(text2));\n            }else if(i%3==0){\n                System.out.println(text1);\n            }else if(i%5==0){\n                System.out.println(text2);\n            }else{\n                System.out.println(i);\n                counter++;\n            }\n               \n          \n        }\n\n\n        return counter;\n    }\n\n\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/david-quinones.java",
    "content": "public class david-quinones {\n    public static void main(String[] args) {\n        \n        /*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)*/\n \n        //Ejemplo de función sin parámetros ni retorno\n        funcionSinParametrosNiRetorno();\n        //Ejemplo de función con un parámetro y sin retorno\n        funcionConUnParametroSinRetorno(5);\n\n        //Ejemplo de función sin parametro y con retorno\n        System.out.println(funcionConUnParametroConRetorno());\n        //Ejemplo de función con varios parámetros y con retorno\n        System.out.println(funcionConVariosParametrosConRetorno(5, 10));\n\n        //Ejemplo de función con una función dentro\n        funcionConFuncionDentro();\n        \n        //funcion del sistema\n        System.out.println(\"El valor de PI es: \" + Math.PI);\n        //otra funcion del sistema\n        System.out.println(\"El valor de la raiz cuadrada de 25 es: \" + Math.sqrt(25));\n        //otra funcion del sistema\n        System.out.println(\"El valor de 5 elevado a 3 es: \" + Math.pow(5, 3));\n        //otra funcion del sistema que no sea Math\n        System.out.println(\"El valor de la longitud de la cadena 'Hola' es: \" + \"Hola\".length());\n        // otra de sistema que no sea de las anteriores\n        System.out.println(\"El valor de la cadena 'Hola' en mayusculas es: \" + \"Hola\".toUpperCase()); \n\n\n        //Ejemplo de variable global\n        int variableGlobal = 10;\n        System.out.println(\"El valor de la variable global es: \" + variableGlobal);\n        //ejemplo de variable local\n        funcionConVariableLocal();      \n\n        //extra\n        functionExtra1(\"david\", \"quinones\");\n\n\n    }\n\n    private static void funcionSinParametrosNiRetorno(){\n        System.out.println(\"Ejemplo de función sin parámetros ni retorno\");\n    }\n\n    private static void funcionConUnParametroSinRetorno(int parametro){\n        System.out.println(\"Ejemplo de función con un parámetro y sin retorno: \" + parametro);\n    }\n\n    private static int funcionConUnParametroConRetorno(){\n        return 5;\n    }\n\n    private static int funcionConVariosParametrosConRetorno(int parametro1, int parametro2){\n        return parametro1 + parametro2;\n    }\n\n    private static void funcionConFuncionDentro(){\n        System.out.println(\"Ejemplo de función con una función dentro\");\n        funcionSinParametrosNiRetorno();\n    }\n\n    private static void funcionConVariableLocal(){\n        int variableLocal = 5;\n        System.out.println(\"El valor de la variable local es: \" + variableLocal);\n    }\n\n    private static int functionExtra1(String cadena1, String cadena2){\n        int contador = 0;\n        for(int i = 1; i <= 100; i++){\n            if(i % 3 == 0 && i % 5 == 0){\n                System.out.println(cadena1 + cadena2);\n            }else if(i % 3 == 0){\n                System.out.println(cadena1);\n            }else if(i % 5 == 0){\n                System.out.println(cadena2);\n            }else{\n                System.out.println(i);\n                contador += i;\n            }\n        }\n\n        return contador;\n    }\n\n    \n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/davidSorroche.java",
    "content": "\npublic class Funciones {\n    /*\n        * - Crea ejemplos de funciones básicas que representen las diferentes\n        *   posibilidades del lenguaje:\n        *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n        * - Comprueba si puedes crear funciones dentro de funciones.\n        * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n        * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n        * - Debes hacer print por consola del resultado de todos los ejemplos.\n        *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n    */\n    private final String textoFunciones = \"Reto de Programación #02 FUNCIONES Y ALCANCE - Java\";\n    \n    // Devuelve el texto de la constante \"textoFunciones\".\n    public void funcionSinParametrosSinRetorno() {\n        System.out.println(textoFunciones);\n    }\n    \n    // Devuelve un mensaje de error junto al texto pasado por parámetro.\n    public void funcionConParametrosSinRetorno(String texto) {\n        System.err.println(\"¡¡¡ ERROR !!!\\n\".concat(texto));\n    }\n    \n    // Devuelve un número aleatorio comprendido entre los enteros (int) 1 y 10.\n    public int funcionSinParametrosConRetorno() {\n        return (int) (Math.random() * 10) + 1;\n    }\n    \n    /*\n        Devuelve la multiplicación, si num 1 es menor o igual que num2, \n        o la división en caso contrario de los dos números pasador por parámetros.\n    */\n    public double funcionConParametrosConRetorno(double num1, double num2, int num3) {\n        /*\n            Si el segundo número es 0 y es menor que el primer número no realiza \n            el cálculo de la función.\n        */\n        if(num2 == 0 && num1 > num2) {\n            throw new ArithmeticException(\"No se puede dividir ningún número entre 0\");\n        }\n        \n        return num1 <= num2 ? Math.round((((num1 * num2) - num3) * 100.0) / 100.0) \n                            : Math.round((((num1 / num2) + num3) * 100.0) / 100.0);\n    }\n}\n\npublic class DificultadExtraFunciones_Alcances {\n    /*\n        * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n        * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n        *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n        *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n        *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n        *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n        *\n        * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n    */\n    \n    public int numerosYTextos(String texto1, String texto2) {\n        // Inicializamos el contador de impresos de números a 0.\n        int contadorImpresosNumeros = 0;\n        \n        /* \n            Formateamos los textos pasados por parámetros para que no dejen espacios\n            ni al principio ni al final y evitar más de un espacio entre palabras.\n        */\n        texto1 = texto1.trim().replaceAll(\"\\s+\", \" \");\n        texto2 = texto2.trim().replaceAll(\"\\s+\", \" \");\n        \n        /*\n            Creamos un bucle que vaya de 1 a 100 y vaya imprimiendo los números y\n            textos correspondientes.\n        */\n        for(int numero = 1; numero <= 100; numero++) {\n            /* \n                Si el número es múltipo de 3 y de 5 imprime las dos cadenas de textos\n                pasadas por parámetros concatenadas con un espacio entre ellas.\n            */\n            if (esMultiploDe3(numero) && esMultiploDe5(numero)) {\n                System.out.println(texto1.concat(\" \").concat(texto2));\n            } \n            // Si el número es sólo múltiplo de 3, imprime el primer texto.\n            else if (esMultiploDe3(numero)) {\n                System.out.println(texto1);\n            } \n            // Si el número es sólo múltiplo de 5, imprime el segundo texto.\n            else if (esMultiploDe5(numero)) {\n                System.out.println(texto2);\n            } \n            /* \n                En cualquier otro caso imprime el número e incremeta el contador \n                de impresos de números en una unidad.\n            */\n            else {\n                System.out.println(numero);\n                contadorImpresosNumeros++;\n            }\n        }\n        \n        // Devuelve el valor del contador de impresos de números.\n        return contadorImpresosNumeros;\n    }\n    \n    // Devuelve true si número es múltiplo de 3, y false en caso contrario.\n    private boolean esMultiploDe3(int numero) {\n        return numero % 3 == 0;\n    }\n    \n    // Devuelve true si número es múltiplo de 5, y false en caso contrario.\n    private boolean esMultiploDe5(int numero) {\n        return numero % 5 == 0;\n    }\n}\n\npublic class PrincipalFunciones_Alcances {\n    public static void main(String[] args) {\n        Funciones f = new Funciones();\n        \n        f.funcionSinParametrosSinRetorno();\n        f.funcionConParametrosSinRetorno(\"Ná, es bromita.\");\n        System.out.println(f.funcionSinParametrosConRetorno());\n        System.out.println(f.funcionConParametrosConRetorno(11, 30, 5));\n        System.out.println(f.funcionConParametrosConRetorno(30, 11, 10));\n        System.out.println(f.funcionConParametrosConRetorno(11, 11, 11));\n        \n        DificultadExtraFunciones_Alcances dE = new DificultadExtraFunciones_Alcances();\n        System.out.println(\"\\n\" + dE.numerosYTextos(\"     Practicando Retos    De Programación\", \"#02 Funciones Y Alcance - Java\"));\n    }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/deathwing696.java",
    "content": "/*\n * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license\n * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template\n */\n\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n/**\n *\n * @author death\n */\npublic class deathwing696 {\n    public static void main(String[] args)\n    {        \n        int num_veces = Repite_num_veces(\"Hola\", \"Adios\");\n        String cadena = String.format(\"El número se ha impreso %d veces\", num_veces);\n        \n        System.out.println(cadena);\n    }\n    \n    static private int Repite_num_veces(String cadena1, String cadena2)\n    {\n        int num_veces = 0;\n        \n        for (int i = 1; i <= 100; i++)\n        {\n            if (i % 3 == 0 && i % 5 == 0)\n            {\n                String cadena = String.format(\"%s %s\", cadena1, cadena2);\n                System.out.println(cadena);\n            }\n            else if (i % 3 == 0)\n            {\n                System.out.println(cadena1);\n            }\n            else if (i % 5 == 0)\n            {\n                System.out.println(cadena2);\n            }\n            else\n            {\n                System.out.println(i);\n                num_veces++;\n            }\n        }\n        \n        return num_veces;\n    }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/dmauricio4.java",
    "content": "package com.dm4.roadmap;\n\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n\npublic class Roadmap02_FuncionYAlcance {\n\n    /**\n     * Variable global: Resultan visibles y disponibles para todas las sentencias de un script\n     */\n    static int cont = 0; // Variable Global\n\n    public static void main(String[] args) {\n        sinParametrosNiRetorno();\n        saludar(\"JAVA\");\n        mostrarCoordenadas(3, 7, 5);\n        calcularAreaCirculo(6);\n        imprimir(\"Hola\", \"JAVA\");\n\n    }\n\n    /**\n     * Funcion sin parámetros ni retorno, con uno o varios parámetros.\n     */\n    public static void sinParametrosNiRetorno() {\n        System.out.println();\n        System.out.println(\" ** Funcion sin parametros ni retorno\");\n        System.out.println(\"Esta funcion no devuelve ningun valor, no tiene parametros ni retorno\");\n        System.out.println(\"--------------------------------------------------------------------------\");\n    }\n\n    /**\n     * Funcion con un parametro y sin retorno.\n     */\n\n    public static void saludar(String nombre) {\n        System.out.println();\n        System.out.println(\" ** Funcion con un parametro\");\n        System.out.println(\"Hola, \" + nombre + \"!\");\n        System.out.println(\"--------------------------------------------------------------------------\");\n    }\n\n    /**\n     * Funcion con varios parámetros, sin retorno.\n     */\n\n    public static void mostrarCoordenadas(int x, int y, int z) {\n        System.out.println();\n        System.out.println(\" ** Funcion con mas de un parametro\");\n        System.out.println(\"Coordenadas: (\" + x + \",\" + y + \",\" + z + \")\");\n        System.out.println(\"--------------------------------------------------------------------------\");\n    }\n    /**\n     * Funcion con retorno y con un parametro.\n     */\n\n    public static double calcularAreaCirculo(double radio) {\n        /*\n         * Variable Local: Solo resultan visibles y disponibles dentro de la\n         * función en la que están definidas.\n         */\n        double area = 0;\n\n        System.out.println();\n        System.out.println(\" ** Funcion con retorno y con un parametro\");\n        area = Math.PI * Math.pow(radio, 2);\n        System.out.println(\"Area del Circulo : \" + area + \" cm\");\n        System.out.println(\"--------------------------------------------------------------------------\");\n        return area;\n\n    }\n\n    /**\n     *  DIFICULTAD EXTRA (opcional)\n     */\n\n    public static int imprimir(String cadena1, String cadena2) {\n        System.out.println();\n        System.out.println(\" ** Dificultad extra\");\n        for (int i = 1; i <= 100; i++) {\n            if (i % 3 == 0 && i % 5 == 0) {\n                System.out.println(i +  \" : \" + cadena1 + \" \" + cadena2 );\n            } else if (i % 3 == 0) {\n                System.out.println(i + \" : \" + cadena1);\n            } else if (i % 5 == 0) {\n                System.out.println(i + \" : \" + cadena2);\n            } else  {\n                System.out.println(i);\n                cont++;\n            }\n        }\n        System.out.println(\"--------------------------------------------------------------------------\");\n        return cont;\n    }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/eulogioep.java",
    "content": "public class eulogioep {\n    // Variable global (estática en Java)\n    private static int contadorGlobal = 0;\n\n    // 1. Método sin parámetros ni retorno\n    public static void saludar() {\n        System.out.println(\"¡Hola, mundo!\");\n    }\n\n    // 2. Método con un parámetro y sin retorno\n    public static void saludarPersona(String nombre) {\n        System.out.println(\"¡Hola, \" + nombre + \"!\");\n    }\n\n    // 3. Método con múltiples parámetros y retorno\n    public static int sumar(int a, int b) {\n        return a + b;\n    }\n\n    // 4. Método que demuestra una \"función\" dentro de otra (usando una clase interna)\n    public static int operacionMatematica(int a, int b) {\n        class Multiplicador {\n            int multiplicar(int x, int y) {\n                return x * y;\n            }\n        }\n        Multiplicador mult = new Multiplicador();\n        return mult.multiplicar(a, b) + 10;\n    }\n\n    // 5. Uso de un método incorporado en Java\n    public static String obtenerFechaActual() {\n        return java.time.LocalDate.now().toString();\n    }\n\n    // 6. Demostración de variable local vs global (estática)\n    public static void incrementarContador() {\n        int contadorLocal = 0;\n        contadorLocal++;\n        contadorGlobal++;\n        System.out.println(\"Contador local: \" + contadorLocal + \", Contador global: \" + contadorGlobal);\n    }\n\n    // DIFICULTAD EXTRA\n    public static int imprimirYContar(String texto1, String texto2) {\n        int contadorNumeros = 0;\n\n        for (int i = 1; i <= 100; i++) {\n            if (i % 3 == 0 && i % 5 == 0) {\n                System.out.println(texto1 + texto2);\n            } else if (i % 3 == 0) {\n                System.out.println(texto1);\n            } else if (i % 5 == 0) {\n                System.out.println(texto2);\n            } else {\n                System.out.println(i);\n                contadorNumeros++;\n            }\n        }\n\n        return contadorNumeros;\n    }\n\n    public static void main(String[] args) {\n        System.out.println(\"1. Método sin parámetros ni retorno:\");\n        saludar();\n\n        System.out.println(\"\\n2. Método con un parámetro y sin retorno:\");\n        saludarPersona(\"Alice\");\n\n        System.out.println(\"\\n3. Método con múltiples parámetros y retorno:\");\n        System.out.println(\"Suma de 5 y 3: \" + sumar(5, 3));\n\n        System.out.println(\"\\n4. Método que demuestra una \\\"función\\\" dentro de otra:\");\n        System.out.println(\"Resultado de operación matemática: \" + operacionMatematica(4, 5));\n\n        System.out.println(\"\\n5. Uso de un método incorporado en Java:\");\n        System.out.println(\"Fecha actual: \" + obtenerFechaActual());\n\n        System.out.println(\"\\n6. Demostración de variable local vs global:\");\n        incrementarContador();\n        incrementarContador();\n\n        System.out.println(\"\\nDIFICULTAD EXTRA:\");\n        int numerosPuros = imprimirYContar(\"Fizz\", \"Buzz\");\n        System.out.println(\"Números impresos sin ser reemplazados por texto: \" + numerosPuros);\n    }\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/inmortalnight.java",
    "content": "//02 - Java\n\npublic class inmortalnight {\n    //Sin parámetros ni retorno\n    public void hello(){\n        System.out.println(\"Hello World\");\n    }\n    //Con un parámetro\n    public void hello(String name){\n        System.out.println(\"Hello \" + name);\n    }\n    //Con varios parámetros\n    public void hello(String name, int age){\n        System.out.println(\"Hello \" + name + \" you are \" + age + \" years old\");\n    }\n    //Con retorno\n    public String hi(){\n        return \"Hello World\";\n    }\n    //Crear funciones dentro de funciones, no se puede en Java\n    //Ejemplo de funciones ya creadas\n    public void ejecutar(){\n        hello();\n        hello(\"John\");\n        hello(\"John\", 25);\n        System.out.println(hi());\n    }\n    public String variableGlobal = \"Variable global\"; //Variable global, se puede usar en cualquier función de esta clase\n    public void funcion(){\n        String variableLocal = \"Variable local\"; //Variable local, solo se puede usar en esta función\n        System.out.println(variableGlobal);\n        System.out.println(variableLocal);\n    }\n    /*EXTRA:\n     *  * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n        * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n        * - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n        * - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n        * - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n        * - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n    */\n    public int funcion(String text1, String text2){\n        int count = 0;\n        for(int i = 1; i <= 100; i++){\n            if(i % 3 == 0 && i % 5 == 0){\n                System.out.println(text1 + \" \" + text2);\n            }else if(i % 3 == 0){\n                System.out.println(text1);\n            }else if(i % 5 == 0){\n                System.out.println(text2);\n            }else{\n                System.out.println(i);\n                count++;\n            }\n        }\n        return count;\n    }\n    public static void main(String[] args) {\n        //Ejemplo de funciones ya creadas, ejecución\n        inmortalnight objeto = new inmortalnight();\n        objeto.ejecutar();\n        objeto.funcion(\"Hola\", \"Mundo\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/jcrodmir.java",
    "content": "public class Main {\n    static int globalVariable=2;\n\n    public static void main(String[] args) {\n\n        //Not parameters, not return/kein Parameter keine Rückgabe\n        initialMessage();\n        //Parameters, not return/Parameter keine Rückgabe\n        numberChallenge(globalVariable);\n\n        //Not parameters, with return/kein Parameter mit Rückgabe\n        System.out.println(stringReturn());\n        //Parameters with return /  Parameter mit Rückgabe\n        System.out.println(\"4 + 5 is: \" + plusOperation(4,5));\n\n        //Example of function that is too created./Beispiel für eine Funktion, die zu viel erstellt wurde.\n        System.out.println(\"The maximum is 8 not 5: \" + Math.max(5,8));\n\n        System.out.println(oneToHunderd(\"Hello\",\"Everyone\"));\n    }\n    public static void initialMessage(){\n        //local variable/lokale Variabel.\n        int localVariable=2;\n        System.out.println(\"Welcome to the MoureDev RoadMap challenge\" + localVariable);\n    }\n    public static void numberChallenge (int number){\n        System.out.println(\"Challenge number: \" + number);\n    }\n    public static String stringReturn (){\n        return \"This is a return Message\";\n    }\n    public static int plusOperation (int a, int b){\n        //It´s  possible create function inside function in Java but only inside a new class\n        //Es ist möglich, eine Funktion innerhalb einer Funktion in Java zu erstellen, aber nur innerhalb einer neuen Klasse\n\n        class NewClass{\n            public  void functionInsideFunction(){\n                System.out.println(\"You can create a function inside a other function only with a new Class\");\n            }\n        }\n        NewClass newClass= new NewClass();\n        newClass.functionInsideFunction();\n        return a + b;\n    }\n\n\n    //EXTRA\n    public static int oneToHunderd (String a, String b){\n        int count=0;\n        for (int i = 0; i < 101; i++) {\n            System.out.print(i+\": \");\n            if(i%5==0 && i%3==0){\n                System.out.println(a+\" \"+b);\n            } else if (i%5==0) {\n                System.out.println(b);\n            } else if (i%3==0) {\n                System.out.println(a);\n            }\n            else{\n                count++;\n                System.out.print(\"\\n\");\n            }\n\n        }\n        return count;\n    }\n\n\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/juanca2805.java",
    "content": "public class juanca2805 {\n\n    private static int variableGlobal = 10;\n    //Variable creada a nivel global a la que se podrá acceder desde toda la clase\n\n    public static void main(String[] args) {\n        /*Funciones y alcance */\n        Saludar();\n        Sumar();\n        Extra();\n    }\n\n    private static void buenosDias() {\n        System.out.println(\"Buenos días\");\n    }\n\n    private static void Nombre() {\n        String Nombre = \"pepe\";\n       if (Nombre == \"camilo\") {\n        System.out.println(\"señor camilo\");\n       }\n       else{\n        System.out.println(\"Quien es usted\");\n       }\n    }\n        private static void Saludar() {\n            // Llamamos a buenosDias y a Nombre\n            buenosDias();\n            Nombre();\n        }\n\n        private static void Sumar(){\n            int variableLocal = 22;\n            System.out.println(variableGlobal+variableLocal);\n        }\n\n         //Funcion con parametros\n    public static void suma(int num1, int num2){\n        int suma;\n        suma = num1 + num2;\n        System.out.println(\"La suma es: \" + suma);\n    }\n      //extra\n\n      public static void Extra(){\n        for(int i = 1; i < 101; i++){\n            String Texto1 = \"fizz\";\n            String Texto2 = \"buzz\";\n            if (i %3 == 0 && i %5 == 0) {\n                System.out.println(Texto1 + Texto2);\n            } \n            else if(i %3 == 0){\n                System.out.println(Texto1 );\n            }\n            else if(i %4 == 0){\n                System.out.println(Texto2 );\n            }\n            else {\n                System.out.println(i);\n               \n            }\n        }\n      }\n    }\n\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/julian98789.java",
    "content": "package MauroDevRetos;\n\npublic class reto_2 {\n\n    // Variable global\n    static int variableGlobal = 10;\n\n    // Función sin parámetros ni retorno\n    public static void funcionSinParametrosNiRetorno() {\n        System.out.println(\"Función sin parámetros ni retorno ejecutada.\");\n    }\n\n    // Función con parámetros y sin retorno\n    public static void funcionConParametros(int a, int b) {\n        int suma = a + b;\n        System.out.println(\"Función con parámetros ejecutada. Suma: \" + suma);\n    }\n\n    // Función con parámetros y con retorno\n    public static int funcionConRetorno(int a, int b) {\n        return a * b;\n    }\n\n    // Función que llama a otras funciones\n    public static void funcionQueLlamaOtrasFunciones(int a, int b) {\n        funcionSinParametrosNiRetorno();\n        funcionConParametros(a, b);\n        int resultado = funcionConRetorno(a, b);\n        System.out.println(\"Resultado de la función con retorno: \" + resultado);\n    }\n\n    // Función anidada (dentro de otra función)\n    public static void funcionAnidada() {\n        System.out.println(\"Función externa ejecutada.\");\n\n        // Función anidada\n        int valorExterno = 5;\n        int resultado = sumar(valorExterno, 3);\n        System.out.println(\"Resultado de la función anidada: \" + resultado);\n    }\n\n    public static int sumar(int a, int b) {\n        return a + b;\n    }\n\n    // ********Desafio extra*************\n\n    public static int impreso(String c1, String c2) {\n        int cont = 0;\n        for (int i = 1; i <= 100; i++) {\n            if (i % 3 == 0 && i % 5 == 0) {\n                System.out.println(c1 + \" \" + c2);\n            } else if (i % 5 == 0) {\n                System.out.println(c2);\n            } else if (i % 3 == 0) {\n                System.out.println(c1);\n            } else {\n                cont++;\n            }\n\n        }\n        return cont;\n    }\n\n    // Función principal (main) donde se ejecutan las funciones\n    public static void main(String[] args) {\n        funcionSinParametrosNiRetorno();\n\n        funcionConParametros(3, 7);\n\n        int resultado = funcionConRetorno(4, 6);\n        System.out.println(\"Resultado de la función con retorno: \" + resultado);\n\n        funcionQueLlamaOtrasFunciones(2, 4);\n\n        funcionAnidada();\n\n        sumar(2, 4);\n\n        // Accediendo a la variable global desde main\n        System.out.println(\"Valor de la variable global: \" + variableGlobal);\n\n        System.out.println(impreso(\"cadena 1\", \"cadena 2\"));\n    }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/kilianhc.java",
    "content": "package retosProgramacion;\n\npublic class RetoTres {\n\n    //Variable global (Variables de instancia y estáticas)\n    String variableInstancia = \"Esto es una variable de instancia\";\n    static String variableEstatica = \"Esto es una variable estática\";\n    \n    public static void main(String[] args) {\n        saludar(); //Llamar a la función sin parámetros ni retorno\n        System.out.println(saludar2()); //Llamar a la función sin parámetros pero con retorno\n        saludar3(\"¿Cómo \", \"estás?\"); //Llamar a la función con parámetros y sin retorno\n        System.out.println(\"El resultado es: \" + suma(3, 5)); //Llamar a la función con parámetros y retorno\n        System.out.println(mayorEdad(30)); //Llamar a la función recursiva\n        datos(\"Kilian\"); //Llamar a funcion \n        datos(30); //con sobrecarga\n        RetoTres ejemplo = new RetoTres(); //Llamada\n        ejemplo.local(); //a una variable local\n        RetoTres instancia = new RetoTres(); //Instanciar una variable\n        System.out.println(instancia.variableInstancia); //de instancia\n        System.out.println(RetoTres.variableEstatica); //Acceso a la variable estática\n       // instancia.local();\n       ejemplos();\n        System.out.println(imprimir(\"Mostrar \", \"Texto\"));\n    }\n\n    //Funciones definidas por el usuario\n    //Función sin parámetros ni retorno\n    public static void saludar() {\n        System.out.println(\"Hola, Java\");\n    }\n\n    //Función sin parámetros pero con retorno\n    public static String saludar2() {\n        return (\"Hola, Kilian\");\n    }\n\n    //Función con parámetros y sin retorno\n    public static void saludar3(String a, String b) {\n        String frase = (a + b);\n        System.out.println(\"La frase es: \" + frase);\n    }\n\n    //Función con parámetros y retorno\n    public static int suma(int a, int b) {\n        return a + b;\n    }\n\n    //Funcione recursiva\n    public static String mayorEdad(int num) {\n        if (num < 18) {\n            return (\"La persona es menor de edad\");\n        } else {\n            return (\"La persona es mayor de edad\");\n        }\n    }\n\n    //Función con sobrecarga\n    public static void datos(String nombre) {\n        System.out.println(\"Mi nombre es: \" + nombre);\n    }\n\n    public static void datos(int edad) {\n        System.out.println(\"Y mi edad es: \" + edad);\n    }\n\n    //Variable local\n    public void local() {\n        String mensaje = \"Esto es una variable local\";\n        System.out.println(mensaje);\n    }\n    \n    //Algunas funciones propias del lenguaje\n    public static void ejemplos() {\n    String nombre = \"Kilian Hernández\";\n        System.out.println(nombre.charAt(3));   \n        System.out.println(nombre.length());\n        System.out.println(nombre.toUpperCase());\n        System.out.println(nombre.toLowerCase());\n        System.out.println(nombre.concat(\" Chirino\"));\n    }\n    \n    //Dificultad Extra\n    public static int imprimir (String a, String b){\n        int contador = 0;\n        for (int num = 1; num <= 100; num++) {\n            if (num%3 == 0 && num%5 == 0) {\n                System.out.println(a+b);\n            }else if (num%5 == 0) {\n                System.out.println(b);\n            }else if (num%3 == 0) {\n                System.out.println(a);\n            }else {\n                System.out.println(num);\n                contador++;\n            }\n        }\n        return contador;\n    }\n    \n}\n\n\n\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/kleyner098.java",
    "content": "\n/**\n * kleyner098\n */\n\nimport java.time.LocalDateTime;\n\n\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\npublic class kleyner098 {\n\n    public static void main(String[] args) {\n\n        // Función/método que muestra la hora actual\n        mostrarHora();\n\n        // Función/método que calcula la potencia de un número de forma iterativa\n        aElevadoNIterativa(2, 8);\n\n        // Función/método que calcula la potencia de un número de forma recursiva\n        double base = 2.00;\n        int exponete = 8;\n        double resultado = aElevadoNRecursiva(base, exponete);\n        System.out.println(base + \"^\" + exponete + \"=\" + resultado);\n\n        // Función/método que calcula la potencia utilizando la clase Math\n        System.out.println(base + \"^\" + exponete + \"=\" + Math.pow(base, exponete));\n\n        // Ámbito/alcance de variable\n        int mismoNombre = 10;\n        int variableFuncion = ambitoVariable();\n        System.out.println(\"Variable local dentro de main: \"+ mismoNombre);\n        System.out.println(\"Variable local dentro de la función: \"+ variableFuncion);\n\n        //Ejercicio extra\n        int num = fizzBuzz(\"fizz\", \"buzz\");\n        System.out.println(\"Se ha imprimido impreso \" + num + \" veces en vez del texto\");\n\n\n    }\n\n    // Función/método que mustra la hora. Es una función sin parámetros ni delvuelve\n    // ningún valor\n    // Se utiliza el clase LocalDateTime\n    static void mostrarHora() {\n        // Se crea un objeto LocalTime que muestra la fecha y la hora\n        LocalDateTime localDate = LocalDateTime.now();\n        // Utilizamos métodos de LocalDateTime para conseguir la hora, minutos y\n        // segundos y se guardan en variables\n        int hours = localDate.getHour();\n        int minutes = localDate.getMinute();\n        int seconds = localDate.getSecond();\n        // Mostramos la hora\n        System.out.printf(\"La hora es %1$d:%2$d:%3$d\\n\", hours, minutes, seconds);\n    }\n\n    // Función/método que calcula la potencia de un número pasando los parámetros\n    // base y\n    // exponete (Solo con exponentes positivos)\n    // de forma iterativas. La función no devuelve ningún valor y utiliza dos\n    // parámetros\n    static void aElevadoNIterativa(double base, int exponente) {\n        // Declaración de variables\n        double resultado = base;\n        // Comprobar que el exponente es no es negativo\n        if (exponente < 0) {\n            System.out.println(\"Error. Introduce un numero entero positivo o cero para el exponente\\n\");\n        } else if (exponente == 0) {\n            System.out.printf(\"%1$.2f^%2$d = 1.00\\n\", base, exponente);\n        } else {\n            // Realiza la multiplitación x veces\n            for (int i = 1; i < exponente; i++) {\n                resultado = resultado * base;\n            }\n            // Imprime por pantalla el resultado\n            System.out.printf(\"%1$.2f^%2$d = %3$.2f\\n\", base, exponente, resultado);\n        }\n    };\n\n    // Función/método que calcula la potencia de un número pasando los parámetros\n    // base y y\n    // exponete (Solo con exponentes positivos)\n    // de forma recursiva. La función devuelve un valor tipo double y utuliza dos\n    // parámetros.\n    static double aElevadoNRecursiva(double base, int exponente) {\n        // Declaración de variables\n        double resultado;\n        if (exponente == 0) {\n            resultado = 1; // caso base\n        } else {\n            resultado = base * aElevadoNRecursiva(base, exponente - 1); // Llamada recursiva de la función\n        }\n        return (resultado);\n    }\n\n    // En java no se pude crear una función dentro de otra, pero si se pude llamar\n    // a otra función, incluso la misma función detro de si misma, como en el caso\n    // de las funciones\n    // recursivas\n\n    // Ámbitos/alcance de variable: Las variable se puden utilizar dependiendo de donde se\n    // declaren. Por ejemplo, si creamos una variable dendro de una función no\n    // podemos utilizarla fuera de ella.\n    // Dos variables pueden tener el mismo nombre si estan en ámbitos diferentes y ningún ámbito engloba al otro\n    static int ambitoVariable() {\n        int mismoNombre = 0;\n        return mismoNombre;\n    }\n\n    //Eercicio extra\n    static int fizzBuzz(String fizz, String buzz){\n        int count = 0;\n        for(int i = 1; i <= 100 ; i++){\n            if(i % 3 == 0){\n                System.out.println(fizz);\n            }else if( i % 5 == 0){\n                System.out.println(buzz);\n            }else if (i % 5 == 0 && i % 3 == 0){\n                System.out.println(fizz + buzz);\n            }else{\n                System.out.println(i);\n                count++;\n            }\n        }\n        return count;\n    }\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/kuroz00.java",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\npublic class kuroz00 {\n\n    static String varGlobal = \"String en una var global\";\n    public static void conceptosVar(){\n        String varLocal = \"String en un ATRIBUTO de instancia, o var local\";\n        System.out.println(varLocal);\n    }\n\n     //Funcion que solo arroja un saludo, no recibe parametros ni retorna nada.\n    public static void impresionSimple(){\n        System.out.println(\"Hola a todos.\");\n    }\n\n    //F complementando el saludo, recibe datos de tipo str/int e imprime el resto de la presentacion\n    public static void presentacion(String nombre, int edad){\n        System.out.printf(\"Soy %s y tengo %d !\", nombre, edad);\n    }\n\n    //F que recibe parametros para realizar una suma y retorna la var en que se guardo.\n    public static int suma(int numero1, int numero2){\n        int valorSumado = numero1 + numero2;\n        return valorSumado; \n    }\n\n    //.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-..--..-.--....--.-.-.-.-.-.-..-\n\n    public class ff{\n        public static void miFuncion(){\n            System.out.println(\" (holi, soy una funcion dentro de una clase)\"); //F dentro de otra f, en java es dentro de una clase\n        }\n    }\n\n    public static void df(String palabra1, String palabra2){\n        int excepciones = 0;\n        for (int i = 1; i <= 100; i++){\n            if((i % 3 == 0) && (i % 5 == 0)){\n                System.out.println(palabra1 + palabra2);\n            } else if (i % 3 == 0){\n                System.out.println(palabra1);\n            } else if (i % 5 == 0){\n                System.out.println(palabra2);\n            } else {\n                System.out.println(\"---excepciones +1---\");\n                excepciones += 1;\n            }\n        }\n        System.out.println(\"Cantidad de excepciones ->\" + excepciones);\n    }\n\n    public static void main(String[] args){\n        //Llamada a las funciones y establecimiento de parametros requeridos.\n        impresionSimple();\n        presentacion(\"manuel\", 26);\n        suma(2, 2);\n        \n        ff.miFuncion();\n\n        conceptosVar();\n        System.out.println(varGlobal);\n\n        // df\n        df(\"Hola \", \"mundo\");\n        //.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.--.-\n    }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/lautarorisso.java",
    "content": "public class LogicaJava02 {\n    \n    // 1.\n    public static void saludar() {\n            System.out.println(\"Hola\");\n        }\n\n    public static void saludarA(String nombre) {\n        System.out.println(\"Hola, \" + nombre);\n    }\n\n    public static void saludarALautaro(String nombre, String apellido) {\n        System.out.println(\"Hola, \" + nombre + \" \" + apellido);\n    }\n\n    public static int edad() {\n        return 21;\n    }\n\n    public static String nombreCompleto (String nombre, String apellido) {\n        return nombre + apellido;\n    }\n    \n    /*\n        2.\n        En Java no se pueden anidar funciones.\n        Y los métodos siempre van a nivel de clase.\n    */\n    \n    // 4.\n    static String nombre = \"Lautaro\";\n    static String apellido = \"Risso\";\n    \n    // EXTRA\n    public static int imprimirNumeros(String texto1, String texto2) {\n        int cont = 0;\n        for (int i=1;i<101;i++) {\n            if (i%15 == 0) {\n                System.out.println(texto1 + texto2);\n            } else if (i%3==0) {\n                System.out.println(texto1);\n            } else if (i%5==0) {\n                System.out.println(texto2);\n            } else {\n                System.out.println(i);\n                cont++;\n            }\n        }\n        return cont;\n    }\n    \n    public static void main(String[] args) {\n        // 3.\n        // 4.\n        int longitud = nombre.length();\n        \n        // 5.\n        System.out.println(longitud);\n        saludar();\n        saludarA(nombre);\n        saludarALautaro(nombre, apellido);\n        edad();\n        nombreCompleto(nombre, apellido);\n        \n        // EXTRA\n        imprimirNumeros(\"Hola, soy texto 1\",\"Hola, soy texto 2\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/marce1084.java",
    "content": "import java.util.Scanner;\n\npublic class marce1084 {\n    public static void main(String[] args) {\n\n        //a)\n        saludar();\n\n        //b)\n        saludar2(\"Juan\");\n\n        //c)\n        sumar(4,7,2);\n\n        //d)\n        int numero = obtenerNumero();\n        System.out.println(\"El número es: \" + numero);\n\n        //e)\n        int numero2 = cuadrado(4);\n        System.out.println(\"El cuadrado es: \" + numero2);\n\n        //f)\n        int operacion = cuenta (3,7,1);\n        System.out.println(\"El resultado es: \" + operacion);\n\n        //g)\n        String resultado = concatenar(\"Saludos \",2024);\n        System.out.println(\"El resultado es: \" + resultado);\n\n        //2)\n        marce1084 marce1084 = new marce1084();\n        marce1084.primeraFcion();\n\n        //3) Ejemplo de funciones ya creadas en el lenguaje.\n        //a) Clase Math\n        double a = 5.3;\n        double b = 1.2;\n        //Exponenciación\n        double potencia = Math.pow(a,b);\n        System.out.println(a + \" elevado a \" + b + \" es = \" + potencia);\n\n        //Valor absoluto\n        double negativo = -5.0;\n        double absoluto = Math.abs(negativo);\n        System.out.println(\"El valor absoluto de \" + negativo + \" es \" + absoluto);\n\n        //b) Clase String\n        String texto = \"Hola, mundo!\";\n\n        // Longitud de la cadena\n        int longitud = texto.length();\n        System.out.println(\"Longitud: \" + longitud);\n\n        // Subcadena\n        String subcadena = texto.substring(0, 4);\n        System.out.println(\"Subcadena: \" + subcadena);\n\n        // 4) Funciones Global y Local\n        //a) Local: variableLocal es una variable local al método Funciones. No puede ser accesible fuera de este método.\n        marce1084 ejemploVariableLocal = new marce1084();\n        ejemploVariableLocal.variableLocal();\n\n        //b) Global: Variables estáticas es similar a las variables globales\n        marce1084.incrementar(); //La invoco para incrementar la variable\n        marce1084.mostrarValor(); //El valor de la variable global es 1\n\n        // 8) Ejercicio extra\n        System.out.println(contarCaracteres(\"texto1 \",\"texto2\"));\n\n    }\n\n    //1) Ejemplos de funciones básicas\n\n    //a) Función sin parámetros y sin retorno\n    public static void saludar() {\n        System.out.println(\"Hola a todos\");\n    };\n    //b) Función con un parámetro y sin retorno\n    static void saludar2(String nombre) {\n        System.out.println(\"Hola \" + nombre);\n    }\n    //c) Función con varios parámetros y sin retorno\n    public static void sumar(int a, int b, int c) {\n        System.out.println(a + b + c);\n    }\n    //d) Función sin parámetros y con retorno\n    public static int obtenerNumero() {\n        Scanner sc = new Scanner(System.in);\n        System.out.print(\"Ingrese el numero: \");\n        int numero = sc.nextInt();\n        return numero;\n    }\n    //e) Función con un parámetro y con retorno\n    public static int cuadrado(int n) {\n        return (n * n);\n    }\n    //f) Función con varios parámetros y con retorno\n    public static int cuenta(int a, int b, int c) {\n        return (a + b + c);\n    }\n    //g) Función con parámetros de diferentes tipos y con retorno\n    public static String concatenar(String a, int b) {\n        return a + b;\n    }\n\n    /*2) Las funciones dentro de funciones en JAVA no existen tal como en PYTHON. Algo similar es hacer la llamada de función, donde\n    una función invoca a otra*/\n    public void primeraFcion() {\n        System.out.println(\"Hola, soy la primera función\");\n        segundaFcion();\n    }\n    public void segundaFcion() {\n        System.out.println(\"Y yo soy la segunda función\");\n    }\n\n    /*4) En Java técnicamente no existen variables globales como en Python, las variables de instancia y las variables estáticas\n     se consideran como variables \"globales\" debido a su alcance dentro de una clase y entre instancias. */\n    //a) Local\n    public void variableLocal() {\n        int local = 32; //variable local\n        System.out.println(\"El valor de una variable local es: \" + local);\n    }\n    //b) Global\n    private static int estatica; //variable global\n    public static void incrementar(){\n        estatica++;\n    }\n    public static void mostrarValor(){\n        System.out.println(\"El valor de la variable global es: \" + estatica);\n    }\n\n    //8)\n    /*Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n     * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n     *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n     *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n     *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n     *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n     */\n    public static int contarCaracteres(String text1, String text2) {\n        int count = 0;\n        for (int i = 0; i <= 100; i++) {\n            if (i %3 == 0 && i %5 == 0) {\n                System.out.println(text1 + text2);\n            } else if (i %3 == 0){\n                System.out.println(text1);\n            } else if (i %5 == 0) {\n                System.out.println(text2);\n            } else {\n                System.out.println(i);\n                count ++;\n            }\n        }\n        return count;\n    }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/mariovelascodev.java",
    "content": "public class mariovelascodev {\n    //Variable Global\n    static String miVariableGlobal = \"Hola Mundo\";//Accesible desde cualquier lugar de la clase\n\n    public static void main(String[] args) {\n       funcionSinArgumentos();\n       funcionConArgumentos(\"Mario\");\n       funcionConArgumentos(\"Sandra\", 37);\n       System.out.println(funcionConRetorno());\n       System.out.println(funcionConRetorno(17));\n       miFuncion();\n       miFuncion(\"Javier\");\n\n       //Llamamos a la variable global\n       mariovelascodev.miVariableGlobal = \"Hola    \";\n       System.out.println(\"El valor de la variable global ahora es: \"+miVariableGlobal);\n\n       //Funciones del lenguaje\n       //Métodos String\n       System.out.println(miVariableGlobal.length()); //Cuenta el número de caracteres de la cadena de texto\n       System.out.println(miVariableGlobal.toLowerCase());//Pone la cadena de texto en minusculas\n       System.out.println(miVariableGlobal.toUpperCase());//Pone la cadena de texto en mayusculas\n       System.out.println(miVariableGlobal.trim());//Quita los espacios en blanco de ambos lados\n\n       //EXTRA\n       int counter = miFuncion(\"Fizz\", \"Buzz\");\n       System.out.println(\"El número de veces que no se ha impreso texto es: \"+counter);\n\n    }\n\n    //Función sin argumentos ni retorno\n    public static void funcionSinArgumentos(){\n        System.out.println(\"Esta es una función sin parametros ni argumentos\");\n    };\n\n    //Función con argumentos sin retorno\n    public static void funcionConArgumentos(String name){\n        System.out.println(\"Hola me llamo \"+name);\n    }\n\n    public static void funcionConArgumentos(String name, int age){\n        System.out.println(\"Hola me llamo \"+name+\" y tengo \"+age+\" años\");\n    }\n\n    //Función sin argumentos con retorno\n    public static String funcionConRetorno(){\n        return \"Función con retorno sin argumentos\";\n    }\n\n    //Función con argumentos y con retorno\n    public static boolean funcionConRetorno(int age){\n        return age >= 18; //Si se cumple la condición muestra true si no false\n    }\n\n    //Función dentro de función\n    public static void miFuncion(){\n        String miVariableLocal = \"Hola Java\";\n        System.out.println(\"La variable global contiene: \"+mariovelascodev.miVariableGlobal+\"\\nLa variable local contiene: \"\n                +miVariableLocal);//La variable local no se puede utilizar fuera del ámbito de la funcion\n        funcionSinArgumentos();\n    }\n\n    public static void miFuncion(String name){\n        funcionConArgumentos(name);\n    }\n\n    //EXTRA\n    public static int miFuncion(String param1, String param2){\n        int contador = 0;\n\n        for(int i=1; i < 100; i++){\n            if (i % 3 == 0 && i % 5 == 0) {\n                System.out.println(param1+ \" \"+param2);\n            }\n            else if(i % 3 == 0){\n                System.out.println(param1);\n            } else if (i % 5 == 0) {\n                System.out.println(param2);\n            } else {\n                System.out.println(i);\n                contador++;\n            }\n        }\n        return contador;\n    }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/martinbohorquez.java",
    "content": "import java.text.DecimalFormat;\n\n/**\n * 02 FUNCIONES Y ALCANCE\n *\n * @author martinbohorquez\n */\npublic class martinbohorquez {\n    /*\n     * Diferentes típos de funciones (en Java, métodos, que suelen estar asociados a objetos.):\n     *       -- Estructura: modificador retorno nombre (parámetros).\n     *       -- Tipos de métodos:\n     *              * Métodos sin retorno.\n     *              * Métodos con retorno.\n     *              * Métodos sin parámetros.\n     *              * Métodos con parámetros.\n     *              * Métodos estáticos (no están asociados a objetos).\n     *              * Métodos constructores: Se utilizan para inicializar un objeto cuando se crea.\n     *              * Métodos abstractos: Se declaran en clases abstractas y deben ser implementados por las subclases.\n     */\n\n    /**\n     * Ejemplo de Constructor\n     */\n    public martinbohorquez() {\n    }\n\n    /**\n     * Ejemplo de Método sin retorno y sin parámetros.\n     * Método estático, es decir que se puede llamar dentro de la clase,\n     * sin crear un objeto como instancia.\n     */\n    private static void saludar() {\n        System.out.println(\"Hola,  Java!\");\n    }\n\n    /**\n     * Ejemplo de Método sin retorno, con parámetros.\n     *\n     * @param name tipo string.\n     */\n    private static void saludar(String name) {\n        System.out.println(\"Hola, \" + name + \"!\");\n    }\n\n    /**\n     * Ejemplo de Método con retorno y sin parámetros.\n     *\n     * @return con un hola kotlin, tipo string.\n     */\n    private static String saludarKotlin() {\n        return \"Hola,  Kotlin!\";\n    }\n\n    /**\n     * Ejemplo de Método con retorno y parámetros.\n     *\n     * @param salario       tipo double.\n     * @param percentAhorro tipo double.\n     * @return ahorro mensual, tipo double.\n     */\n    private static double calcularAhorroMensual(double salario, double percentAhorro) {\n        return salario * percentAhorro;\n    }\n\n    public static void main(String[] args) {\n        martinbohorquez mbohorquez = new martinbohorquez();\n        System.out.println(\"---- SALUDAR ----\");\n        saludar();\n        saludar(\"Python\");\n        saludar(\"Typescript\");\n        System.out.println(saludarKotlin());\n\n        System.out.println(\"---- CALCULAR AHORRO ----\");\n//        double salario = 2500;\n//        double percentAhorro = 52.75 / 100;\n//        double tasaAnual = 8.00 / 100;\n//        int periodos = 60;\n        double salario = 4000;\n        double percentAhorro = 62.5 / 100;\n        double tasaAnual = 8.00 / 100;\n        int periodos = 3 * 12;\n\n        DecimalFormat df = new DecimalFormat(\"$ #,###.00\");\n        DecimalFormat dfp = new DecimalFormat(\"#.00 %\");\n\n        System.out.println(\"Salario: \" + df.format(salario));\n        System.out.println(\"Porcentaje de ahorro (%): \" + dfp.format(percentAhorro));\n        System.out.println(\"Periodos de ahorro (meses): \" + periodos);\n        System.out.println(\"Tasa de interés anual (%): \" + dfp.format(tasaAnual));\n\n        double ahorroMensual = calcularAhorroMensual(salario, percentAhorro);\n        System.out.println(\"El ahorro mensual: \" + df.format(ahorroMensual));\n\n        double ahorroTotal = mbohorquez.calcularAhorro(ahorroMensual, tasaAnual, periodos);\n        System.out.println(\"El ahorro total generado es: \" + df.format(ahorroTotal));\n        System.out.println();\n\n        salario = 1500;\n        percentAhorro = 67.5 / 100;\n        tasaAnual = 7.50 / 100;\n        periodos = 2 * 12;\n\n        System.out.println(\"Salario: \" + df.format(salario));\n        System.out.println(\"Porcentaje de ahorro (%): \" + dfp.format(percentAhorro));\n        System.out.println(\"Periodos de ahorro (meses): \" + periodos);\n        System.out.println(\"Tasa de interés anual (%): \" + dfp.format(tasaAnual));\n\n        double ahorroTotal2 = mbohorquez.calcularAhorro(salario, percentAhorro, tasaAnual, periodos);\n        System.out.println(\"El ahorro total generado es: \" + df.format(ahorroTotal2));\n        System.out.println();\n\n        System.out.println(\"DIFICULTAD EXTRA\");\n        int numeros = mbohorquez.funcion(\"fizz\", \"buzz\");\n        System.out.println(\"numeros de: \" + numeros);\n    }\n\n    /**\n     * Ejemplo de Método con retorno y parámetros.\n     * No son métodos estáticos, se necesita un objeto como instancia\n     * para llamar al método.\n     *\n     * @param ahorroMensual tipo double.\n     * @param tasaAnual     tipo double.\n     * @param periodos      tipo integer.\n     * @return ahorro total, tipo double.\n     */\n    private double calcularAhorro(double ahorroMensual, double tasaAnual, int periodos) {\n        int periodosPorAnio = 12; // Capitalización mensual\n        double tasaMensual = Math.pow(tasaAnual + 1, (double) 1 / periodosPorAnio) - 1; // Tasa mensual\n        return ahorroMensual * ((Math.pow(1 + (tasaMensual), periodos) - 1) / (tasaMensual));\n    }\n\n    /**\n     * Ejemplo de Método con retorno y parámetros.\n     * Se llaman a otros métodos dentro del mismo.\n     *\n     * @param salario       tipo double.\n     * @param percentAhorro tipo double.\n     * @param tasaAnual     tipo double.\n     * @param periodos      tipo integer.\n     * @return ahorro total, tipo double.\n     */\n    private double calcularAhorro(double salario, double percentAhorro, double tasaAnual, int periodos) {\n        double pago = calcularAhorroMensual(salario, percentAhorro);\n        return calcularAhorro(pago, tasaAnual, periodos);\n    }\n\n    /**\n     * DIFICULTAD EXTRA (Ejercicio fizz buzz)\n     * Una función que imprima los números del 1 al 100, pero si el número es\n     * múltiplo de 3, muestre una palabra, si es múltiplo de 5 muestre otra\n     * y si es múltiplo de los dos muestre las dos palabras.\n     *\n     * @param texto1 el texto para los divisores de 3.\n     * @param texto2 el texto para los divisores de 5.\n     * @return el número de veces que mostró números y no texto.\n     */\n    public int funcion(String texto1, String texto2) {\n        int counter = 0;\n        StringBuilder result;\n        for (int i = 1; i <= 100; i++) {\n            result = new StringBuilder();\n\n            if (i % 3 == 0) {\n                result.append(texto1);\n            }\n\n            if (i % 5 == 0) {\n                result.append(texto2);\n            }\n\n            if (result.isEmpty()) {\n                result.append(i);\n                counter++;\n            }\n            System.out.println(result);\n        }\n        return counter;\n    }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/miguelex.java",
    "content": "public class miguelex {\n\n    public static void saludo() {\n        System.out.println(\"Hola, soy Miguel\");\n    }\n\n    public static void lenguaje(String lenguaje) {\n        System.out.println(\"Este ejercicio esta hecho en el lenguaje \" + lenguaje);\n    }\n\n    public static int suma(int a, int b) {\n        return a + b;\n    }\n\n    public static int extra(String a, String b) {\n        int count = 0;\n        for (int i = 1; i <= 100; i++) {\n            if (i % 15 == 0) {\n                System.out.println(a + b);\n            } else if (i % 3 == 0) {\n                System.out.println(a);\n            } else if (i % 5 == 0) {\n                System.out.println(b);\n            } else {\n                System.out.println(i);\n                count ++;\n            }\n        }\n        return count;\n    }\n\n    public static void main(String[] args) {\n        saludo();\n        lenguaje(\"Java\");\n        System.out.println(\"La suma de 5 y 3 es \" + suma(5, 3));\n        System.out.println(\"Ejemplo de uso de funcion del sistema --> Longitud de una cadena de texto (Hola, Mundo!): \" + \"Hola, Mundo!\".length());\n        System.out.println(\"Ejercicio extra\");\n        System.out.println(\"Se ha imprimido \" + extra(\"Fizz\", \"Buzz\") + \" veces\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/mtirador.java",
    "content": "public class mtirador {\n    public static void main(String[] args) {\n        \n\n       \n        int num= 7;\n\n        Saludo();\n        Saludo2(\"Hola a todos\");\n        combinacion(\"Este es el numero de la suerte\", num);\n        System.out.println(suma(num, num)); \n        System.out.println(random());\n        extra(\"multiplo de 3\", \"multiplo de 5\");\n\n    }\n\n    /*Sin parámetros ni retorno */\n    private static void Saludo(){\n        System.out.println(\"Hola Mundo\");\n    }\n    \n    /*con un parámetro y sin retorno */\n    private static void Saludo2(String frase){\n        System.out.println(frase);\n    }\n\n    /*Con dos parámetros y sin retorno */\n    private static void combinacion(String frase,int num){\n\n        System.out.println(frase+num); \n    }\n\n    /*función con retorno y dos parámetros */\n\n    private static int suma(int num1,int num2){ \n        int resultado=num1+num2;\n        System.out.println(\"El resultado de la suma entre \"+ num1+ \" y \"+ num2+ \" = \");\n       \n        return resultado;\n    }\n\n    /*función dentro de función */\n\n    private static int random(){\n        int ale = (int) (Math.random()*25+1);\n        System.out.println(\"El número aleatorio entre 1 y 25 es: \");\n\n        return ale;\n        \n    }\n\n    /*Ejercicio Extra */\n    /*\n \n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n    private static int extra(String text1,String text2){\n\n        int cont=0;\n        System.out.println(\" \");\n        System.out.println(\"Ejercicio Extra: \");\n        for (int i = 1; i <= 100; i++) {\n            if (i % 3 == 0 && i % 5 == 0) {\n                System.out.println(text1 + \" y \"+text2);\n            } else if (i % 3 == 0) {\n                System.out.println(text1);\n            } else if (i % 5 == 0) {\n                System.out.println(text2);\n            } else {\n                System.out.println(i);\n                cont++;\n            }\n        }\n        return cont;\n    }\n\n\n\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/nwpablodeveloper.java",
    "content": "import java.time.LocalDate;\nimport java.time.LocalTime;\nimport java.util.Arrays;\nimport java.util.Scanner;\n\npublic class nwpablodeveloper {\n    \n    // variable global \n    public static int globalNumber = 98;\n\n    // Variable local usada en la función 1. \n    \n    public static void main(String[] args) {\n\n        // 1. Función básica\n        basicFunction();\n\n        // 2. Función con retorno\n        System.out.println(returnFunction());\n\n        // 3. Función con argumentos\n        argFunction( \"3. Esta función recibe un String como argumento\" );\n\n        // 4. Función que recibe varios argumentos \n        argsFunction(\"Pablo\", 35, 120.35);\n\n        // NOTA ! JAVA NO ADMINTE ARGUMENTOS CON VALORES POR DEFECTO\n\n        // 5. Función con argumento y retorno\n        System.out.println(returnArgsFunction(\"Pablo\", 35));\n\n        // 6. Variables del mismo tipo\n        functionVar(\"Mnazana\", \"Pera\", \"Kiwi\", \"banana\", \"mandarina\");\n\n        \n        // 7. Función embebida\n        Calculos calculo = ( nro1, nro2 ) -> nro1 + nro2;\n        int resultado = calculo.sumar(35, 8);\n        System.out.println(\"7. Función embebida\");\n        System.out.println(\"   - Resultado:  \" + resultado);\n\n        // 8. Funciones creadas de Java\n        System.out.println(\"8. Funciones prediseñadas Java\");\n        System.out.println(\"   - De String a int: \" + Integer.parseInt(\"2024\"));\n        System.out.println(\"   - Nro min: \"         + Math.min(15, 4) );\n        System.out.println(\"   - Nro aleatorio: \"   +  Math.random() );\n        System.out.println(\"   - texto a mayusculas\".toUpperCase());\n        System.out.println(\"   - TEXTO A MINISCULAS\".toLowerCase());\n        System.out.println(\"   - Fecha Actual: \"    +  LocalDate.now() );\n        System.out.println(\"   - Hora Actual: \"     +  LocalTime.now() );\n\n        int[] numbers = { 35, 8, 17, 53, 80, 70 };\n        Arrays.sort(numbers); // Ordena el array de menor a mayor\n        for( int i = 0 ; i < numbers.length; i++ ){\n            System.out.println(numbers[i]);\n        }\n\n        // Funcion Scanner para leer datos ingresados por el usuario\n        System.out.println(\"Ingres algo a la consola\");\n        Scanner consola = new Scanner(System.in);\n        String textIn = consola.nextLine();\n        System.out.println(\"El usuario ingreso: \" + textIn);\n\n        // EXTRA\n        System.out.println(extraFunction(\"multipo de 3\", \"multiplo de 5\"));\n\n    }\n    \n    // 1. Función básica\n    public static void basicFunction() {\n        // Variable local\n        String localVariable = \"Esto es una variable local\";\n        // Esta variable solo se puede usar y modificar adentro de este scope\n        localVariable = \"1. Esto es un a función básica\"; \n        System.out.println(localVariable);\n        System.out.println(\"   - Esta es la variable global:  \" + globalNumber);\n    }\n    \n    // 2. Función con retorno\n    public static String returnFunction(){\n        return \"2. Esto es un texto que retorna desde una función\";\n    }\n    \n    // 3. Función con argumentos\n    public static void argFunction(String arg){\n        System.out.println ( arg );\n    }\n    \n    // 4. Función que recibe varios argumentos \n    public static void argsFunction(String name, int age, double priceWork){\n        System.out.println(\"4. Esta funcion recibe vario argumentos de diferentes tipos\");\n        System.out.println(\"   - Me llamo \" + name + \" y tengo \" + age + \" años. El valor de mi trabajo es de \" + priceWork + \" el minuto\");\n    }\n\n    // 5. Función con argumento y retorno\n    public static String returnArgsFunction(String name, int age){\n        System.out.println(\"5. Funcion con argumentos y retorno\");\n        return \"   - Mi nombre es \" + name + \" y tengo \" + age;\n    }\n\n    // 6. Función con varios argumnetos del mismo tipo\n    public static void functionVar(String... fruits){\n        System.out.println(\"6. Función con varios argumnetos del mismo tipo\");\n        for(String fruit : fruits ){\n            System.out.println(\"   - \" + fruit);\n        }\n        \n    }\n    \n    // 7. Función embebida\n    interface Calculos {\n        int sumar( int nro1, int nro2 );\n    }\n\n    // EXTRA\n    public static int extraFunction(String dato1, String dato2){\n        int count = 0;\n        for( int i = 1; i <= 100; i++ ){\n            if( i % 3 == 0 && i % 5 == 0 ){\n                System.out.println( i + \" => Es \" + dato1 + \" y \" + dato2);\n            }else if ( i % 3 == 0) {\n                System.out.println( i + \" => Es \" + dato1);\n            }else if( i % 5 == 0){\n                System.out.println( i + \" => Es \" + dato2);\n            }else{\n                System.out.println(i);\n                count++;\n            }\n        }\n        return count;\n    }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/oixild.java",
    "content": "\n\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n\npublic class oixild {\n    public static void main(String[] args) {\n\n        int intValue = miInt();\n        System.out.println(\"El valor devuelto de miInt es: \" + intValue);\n\n    //miString(\"miString imprimira esto y le cambiara el valor devuelto\");\n        System.out.println(miString(\"miString imprimira esto y le cambiara el valor devuelto\"));\n\n        miVoid();\n\n        int finalValueDificultadExtra = dificultadExtra(\"Primera cadena\", \"Segunda cadena\");\n        System.out.println(\"Los numeros se han imprimido \" + finalValueDificultadExtra + \" veces\");\n    }\n\n    public static int miInt() {\n        return (1);\n    }\n\n    public static String miString(String str) {\n        System.out.println(\"Printado en miString: \" + str);\n        str = \"Printado en main: Al no ser una constante se le puede cambiar el valor\";\n        return (str);\n    }\n\n    public static void miVoid() {\n        System.out.println(\"Void no retorna nada\");\n    }\n\n    // APARTE DE PUBLIC TAMBIEN HAY PROTECTED Y PRIVATE, TAMPOCO ES NECESARIO QUE SEA STATIC, EN ESTE CASO SI\n    // POR QUE LO LLAMAMOS DESDE UNA FUNCION ESTATICA public static void main\n\n    public static int dificultadExtra(String str1, String str2) {\n        int i = 0, count = 1;\n        while(count <= 100) {\n            if (count % 3 == 0 & count % 5 == 0) {\n                System.out.println(str1 + str2);\n            }\n            else if (count % 3 == 0) {\n                System.out.println(str1);\n            }\n            else if (count % 5 == 0) {\n                System.out.println(str2);\n            }\n            else {\n                System.out.println(count);\n                i++;\n            }\n            count++;\n        }\n\n        return (i);\n    }\n\n}\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/simonguzman.java",
    "content": "import java.math.*;\nimport java.util.Scanner;\n\npublic class simonguzman {\n\n    //Variable global utilizada para el calculo del numero par e impar\n    static int validarParImpar = 2;\n    public static void main(String[] args) {\n        //Prueba del ejercicio extra\n        int numImpreso = ejercicioExtra(\"multiplo de 3\", \"multiplo de 5\");\n        System.out.println(\"Numero de veces que se ha impreso numero en lugar de las cadenas de texto: \" + numImpreso);\n        \n        //Prueba de la calculadora en la que se encuentran todas las funciones que se puedian de requerimiento\n        iniciarCalculadora();\n    }\n\n    //Funcion sin parametros ni retorno\n    public static void presentation(){\n        System.out.println(\"*************************\");\n        System.out.println(\"Bienvenido a la calculadora\");\n        System.out.println(\"*************************\");\n    }\n\n    //Funcion sin parametros ni retorno\n    public static void menu(){\n        System.out.println(\"**********MENU**********\");\n        System.out.println(\"1. Suma\");\n        System.out.println(\"2. Resta\");\n        System.out.println(\"3. Multiplicacion\");\n        System.out.println(\"4. Division\");\n        System.out.println(\"5. Modulo\");\n        System.out.println(\"6. Factorial\");\n        System.out.println(\"7. Numero par o impar\");\n        System.out.println(\"8. Raiz cuadrada\");\n        System.out.println(\"9. Potenciacion\");\n        System.out.println(\"10. Numero primo\");\n        System.out.println(\"11. Salir\");\n    }\n\n    //Funcion con retorno y 2 parametros\n    public static double suma(double num1, double num2){\n        double sum = num1 + num2;\n        return sum;\n    }\n\n    //Funcion con retorno y 2 parametros\n    public static double resta(double num1, double num2){\n        double res = num1 - num2;\n        return res;\n    }\n\n    //Funcion con retorno y 2 parametros\n    public static double multiplicacion(double num1, double num2){\n        double multi = num1 * num2;\n        return multi;\n    }\n\n    //Funcion con retorno y 2 parametros\n    public static double division(double num1, double num2){\n        double div = 0;\n        if(num2 == 0){\n            System.out.println(\"ERROR: no se puede realizar una division por 0\");\n        }else{\n            div = num1 / num2;\n        }\n        return div;\n    }\n\n    //Funcion con retorno y 2 parametros\n    public static double modulo(double num1, double num2){\n        double mod = 0;\n        if(num2 == 0){\n            System.out.println(\"Error: modulo por cero\");\n        }else{\n            mod = num1 % num2;\n        }\n        return mod;\n    }\n\n    //Funcion con retorno y 1 parametros\n    public static int factorial(int num){\n        int factorial = 1;\n        if (num < 0){\n            System.out.println(\"ERROR: No se puede hallar el factorial de un numero negativo\");\n        }else if (num == 0){ \n            factorial = 1;\n        }else{\n            for (int i = 1; i <= num; i++){\n                factorial = factorial * i;\n            }   \n        }\n        return factorial;\n    }\n\n    //Funcion con 1 parametro pero sin retorno\n    public static void numeroPrimo(int num1){\n        boolean numprimo = true;\n        for (int i = 2; i < num1; i++){\n            if(num1 % i == 0){\n                numprimo = false;\n                break;\n            }\n        }\n        if (numprimo) {\n            System.out.println(\"El numero \"+num1+\" es primo\");\n        }else{\n            System.out.println(\"El numero \"+num1+\" NO es primo\");\n        }\n    }\n\n    //Funcion con 2 parametros, retorno y utilizando funciones del lenguaje\n    public static double potenciacion(int base, int exponente){\n        double resultado = Math.pow(base, exponente);\n        return resultado;\n    }\n\n    //Funcion con 1 parametro, retorno y utilizando funciones del lenguaje\n    public static double raizCuadrada(int num){\n        double raiz = Math.sqrt(num);\n        return raiz;\n    }\n\n    //Fncion con 1 prametro y sin retorno\n    public static void numParImpar(int num){\n        if(num % validarParImpar == 0){\n            System.out.println(\"El numero \"+num+\" es par\");\n        }else{\n            System.out.println(\"El numero \"+num+\" es impar\");\n        }\n    } \n    \n    //Funcion con 2 parametros y sin retorno, utilizando las funciones creadas anteriormente\n    public static void menuOperaciones(int opcion, Scanner scanner){\n        switch (opcion) {\n            case 1:\n                System.out.println(\"Ingrese el primer sumando: \");\n                double sumando1 = scanner.nextDouble();\n                System.out.println(\"Ingrese el segundo sumando: \");\n                double sumando2 = scanner.nextDouble();\n                System.out.println(\"Resultado: \"+suma(sumando1, sumando2)); \n                break;\n            case 2:\n                System.out.println(\"Ingrese el primer valor: \");\n                double minuendo = scanner.nextDouble();\n                System.out.println(\"Ingrese el segundo valor: \");\n                double sustraendo = scanner.nextDouble();\n                System.out.println(\"Diferencia: \"+resta(minuendo, sustraendo));\n                break;\n            case 3:\n                System.out.println(\"Ingrese el primer valor: \");\n                double multiplicando = scanner.nextDouble();\n                System.out.println(\"Ingrese el segundo valor: \");\n                double multiplicador = scanner.nextDouble();\n                System.out.println(\"Producto: \"+multiplicacion(multiplicando, multiplicador));\n                break;\n            case 4:\n                System.out.println(\"Ingrese el primer valor: \");\n                double dividendo = scanner.nextDouble();\n                System.out.println(\"Ingrese el segundo valor: \");\n                double divisor = scanner.nextDouble();\n                System.out.println(\"cociente: \"+division(dividendo, divisor));\n                break;\n            case 5:\n                System.out.println(\"Ingrese el primer valor: \");\n                double dividendoModulo = scanner.nextDouble();\n                System.out.println(\"Ingrese el segundo valor: \");\n                double divisorModulo = scanner.nextDouble();\n                System.out.println(\"Resto: \"+modulo(dividendoModulo, divisorModulo));\n                break;\n            case 6:\n                System.out.println(\"Ingrese el valor: \");\n                int numFactorial = scanner.nextInt();\n                System.out.println(\"Factorial: \"+factorial(numFactorial));\n                break;\n            case 7:\n                System.out.println(\"Ingrese el valor: \");\n                int numParImpar = scanner.nextInt();\n                numParImpar(numParImpar);\n                break;\n            case 8:\n                System.out.println(\"Ingrese el valor: \");\n                int numeroRaiz = scanner.nextInt();\n                System.out.println(\"Raiz: \"+raizCuadrada(numeroRaiz));\n                break;\n            case 9:\n                System.out.println(\"Ingrese el valor de la base: \");\n                int base = scanner.nextInt();\n                System.out.println(\"Ingrese el valor del exponente: \");\n                int exponente = scanner.nextInt();\n                System.out.println(\"Potencia: \"+potenciacion(base, exponente));\n                break;\n            case 10:\n                System.out.println(\"Ingrese el valor: \");\n                int numeroPrimo = scanner.nextInt();\n                numeroPrimo(numeroPrimo);\n                break;\n            case 11:\n                System.out.println(\"Saliendo de la calculadora...\");\n                break;\n            default:\n                System.out.println(\"ERROR: opcion no valida, ingrese un valor correcto\" );\n                break;\n        }\n    }\n\n    //Funcion con 1 parametro y sin retonro utilizando las funciones creadas con anterioridad\n    public static void menuCompleto(Scanner scanner){\n        int opcion = 0;\n        do{\n            presentation();\n            menu();\n            System.out.println(\"Elija una opcion: \");\n            opcion = scanner.nextInt();\n\n            menuOperaciones(opcion, scanner);\n        }while(opcion != 11);\n    }\n\n    //Funcion sin parametros ni retorno, utilizando funciones creadas con anterioridad\n    public static void iniciarCalculadora(){\n        Scanner scanner = new Scanner(System.in);\n        menuCompleto(scanner);\n        scanner.close();\n    }\n\n    //Ejercicio extra propuesta en la actividad, 2 parametros de texto con un retorno entero\n    public static int ejercicioExtra(String text1, String text2){\n        int count = 0;\n        for(int i=0; i<=100; i++){\n            if(i % 3 == 0){\n                System.out.println(text1);\n            }else if (i % 5 == 0) {\n                System.out.println(text2);\n            }else if(i % 3 == 0 && i % 5 ==0){\n                System.out.println(text1 + \" y \" + text2);\n            }else{\n                System.out.println(i);\n                count++;\n            }\n        }\n        return count;\n    }\n\n}\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/sniker1223.java",
    "content": "import java.util.Arrays;\nimport java.util.List;\nimport java.util.stream.Collectors;\n\npublic class sniker1223 {\n  // Global variable\n  static int count = 0;\n\n  public static void main(String[] args) {\n\n    // examples of functions\n    noParameterNoReturn();\n    greet(\"Sniker\");\n    System.out.println(\"This function has return: \" + add(1, 2));\n    System.out.println(\"This function contains a function.: \" + calculate(0, 10));\n\n    // Local variable\n    List<String> words = Arrays.asList(\"THE\", \"QUICK\", \"BROWN\", \"FOX\");\n\n    List<String> lowercaseWords = words.stream()\n        .map(word -> word.toLowerCase())\n        .collect(Collectors.toList());\n    System.out.println(\"toLowerCase() function: \" + lowercaseWords);\n    System.out.println(\"Local variable: \" + words);\n    System.out.println(\"Global variable: \" + count);\n    // Challenge\n    System.out\n        .println(\"Number of times the number has been printed: \" + printNumbersAndStrings1to100(\"Star\", \"Wars\"));\n  }\n\n  // function no parameter and no Return\n  public static void noParameterNoReturn() {\n    System.out.println(\"Function no parameter and no Return!\");\n  }\n\n  // with one or more parameters\n  public static void greet(String name) {\n    System.out.println(\"Hello, \" + name + \"! This function has one parameters\");\n  }\n\n  // function has return\n  public static int add(int number1, int number2) {\n    return number1 + number2;\n  }\n\n  public static int calculate(int number1, int number2) {\n    return add(number1, number2);\n  }\n\n  public static int printNumbersAndStrings1to100(String text1, String text2) {\n    for (int i = 1; i <= 100; i++) {\n      if (i % 3 == 0 && i % 5 == 0) {\n        System.out.println(text1 + text2);\n      } else if (i % 3 == 0) {\n        System.out.println(text1);\n      } else if (i % 5 == 0) {\n        System.out.println(text2);\n      } else {\n        System.out.println(i);\n        count++;\n      }\n    }\n    return count;\n  }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/swifty0705.java",
    "content": "package com.mouredev.retosprogramacion.roadmap.dos;\n\nimport java.util.Scanner;\n\npublic class swifty0705 {\n    public static void main(String[] args) {\n        bienvenida();\n        int primeraSuma = suma(1,2);\n        System.out.println(primeraSuma);\n        int resultadoResta = resta(8,9);\n        System.out.println(resultadoResta);\n        Scanner sc = new Scanner(System.in);\n        System.out.println(\"Ingrese el primer texto: \");\n        String primerString = sc.nextLine();\n        System.out.println(\"Ingrese el segundo texto: \");\n        String segString = sc.nextLine();\n        System.out.println(\"Cantidad  de veces: \"+ hardMode(primerString,segString));\n    }\n\n    public static int suma(int a, int b){\n        return a + b;\n    }\n    public static void bienvenida(){\n        System.out.println(\"Bienvenido al reto dos\");\n    }\n    public static int resta(int a, int b){\n//        int impresion(){\n//            return 5;\n//        }\n//        return a-b- impresion();\n        // java no permite metodo dentro de metodo\n        return a - b;\n\n    }\n\n\n    public static int hardMode(String a, String b){\n        int j = 0;\n        for (int i = 0; i < 100; i++){\n            if(i%3==0 && i%5==0){\n                System.out.println(a + \" \" + b);\n            } else if(i %3==0) {\n                System.out.println(a);\n            } else if(i %5==0) {\n                System.out.println(b);\n            }else {\n                j++;\n            }\n        }\n        return j;\n    }\n\n    public static String funcion(String primeraMitadDelTexto, String segundaMitadDelTexto) {\n        String inicioDelTexto = \"\"\"\n\n                   Era un texto incompleto\n\n                \"\"\";\n        String textoUnico = inicioDelTexto + primeraMitadDelTexto + \" \" + segundaMitadDelTexto;\n        return textoUnico;\n    }\n\n\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/willr30.java",
    "content": "public class Solucion_02_Java {\n\n    // Variable global\n    static String esto_es_una_variable_global = \"Variable_local\";\n\n    // Método sin parámetros\n    public static void funcion_sin_parametros() {\n        System.out.println(\"Esto es una función sin parámetros\");\n    }\n\n    // Método que recibe un parámetro\n    public static void funcion_con_parametros(String nombre) {\n        System.out.println(\"Esto es un saludo para => \" + nombre);\n    }\n\n    // Método con un parámetro y tipo de dato definido\n    public static void funcion_con_tipo_de_datos_definido(String ciudad) {\n        System.out.println(\"Quiero viajar a \" + ciudad);\n    }\n\n    // Método con parámetros definidos y tipos de datos\n    public static void funcion_con_parametros_definidos_suma(int a, int b) {\n        System.out.println(\"El resultado es \" + (a + b));\n    }\n\n    // Método con retorno y parámetro definido\n    public static String funcion_con_retorno(String comida) {\n        return \"Quisiera probar \" + comida + \" algún día\";\n    }\n\n    // Método que muestra una variable global\n    public static void funcion_mostrando_variable_global() {\n        System.out.println(esto_es_una_variable_global);\n    }\n\n    // Método que muestra las tablas de multiplicar según una variable local\n    public static void funcion_con_variable_local() {\n        java.util.Scanner scanner = new java.util.Scanner(System.in);\n        System.out.print(\"Escribe una tabla de multiplicar => \");\n        int tabla_de_multiplicar = scanner.nextInt();\n\n        for (int i = 0; i < 12; i++) {\n            System.out.println(tabla_de_multiplicar + \" * \" + i + \" = \" + (tabla_de_multiplicar * i));\n        }\n        scanner.close();\n    }\n\n\n    /*\n    * Extra\n    * */\n\n    public static int extra(String texto_1, String texto_2) {\n        int contador = 0;\n        // Mostramos los números del 1 al 100\n        for (int i = 1; i <= 100; i++) {\n            if (i % 3 == 0 && i % 5 == 0) {\n                System.out.println(texto_1 + \" y \" + texto_2);\n            } else if (i % 3 == 0) {\n                System.out.println(texto_1);\n            } else if (i % 5 == 0) {\n                System.out.println(texto_2);\n            } else {\n                System.out.println(i);\n                contador++;\n            }\n        }\n        return contador;\n    }\n    // Método main para probar los demás métodos\n    public static void main(String[] args) {\n        funcion_sin_parametros();\n        funcion_con_parametros(\"Juan\");\n        funcion_con_tipo_de_datos_definido(\"Leon\");\n        funcion_con_parametros_definidos_suma(3, 5);\n        String resultado_retorno = funcion_con_retorno(\"Nacatamal\");\n        System.out.println(resultado_retorno);\n        funcion_mostrando_variable_global();\n        funcion_con_variable_local();\n\n        //llamamos a la funcion extra\n        System.out.println(extra(\"Mi abuelito me ama\", \"Mi abuelita me ama\"));\n    }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/xurxogz.java",
    "content": "import java.lang.Math;\n\npublic class xurxogz {\n    // EJERCICIO\n\n    public static int suma(int num1, int num2) { // Con parámetros y con retorno\n        return num1 + num2;\n    }\n\n    public static String imprimirString() { // Sin parámetros y con retorno \n        return \"Hola mundo\";\n    }\n\n    public static void raizCuadrada(int num1) { // Con parámetros y sin retorno\n        System.out.println((int)Math.sqrt(num1));\n    }\n\n    public static void saludar() { // Sin parametros y sin retorno\n        System.out.println(\"Hola a todos\");\n    }\n\n    // DIFICULTAD EXTRA\n\n    public static int dificultadExtra(String texto1, String texto2) {\n        int i;\n        for (i = 1; i <= 100; i++) {\n            if (i % 3 == 0 && i % 5 == 0) {\n                System.out.println(texto1 + texto2);\n            } else if (i % 3 == 0) {\n                System.out.println(texto1);\n            } else if (i % 5 == 0) {\n                System.out.println(texto2);\n            } else {\n                System.out.println(\"\");\n            }\n        }\n        return i;\n    }\n\n    public static void main(String[] args) {\n        System.out.println(suma(2, 3));\n        System.out.println(imprimirString());\n        raizCuadrada(16);\n        saludar();\n        dificultadExtra(\"saca\", \"puntas\");\n    }\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/yaretzyrb.java",
    "content": "\n// FUNCIÓN SIN RETORNO NI PARÁMETROS\nstatic void  bienvenida (){\n    System.out.println(\"Hola\");\n    System.out.println(\"Esto es una Calculadora\");\n}\n\n// FUNCIÓN CON UN PARÁMETRO SIN RETORNO\nstatic void personalizado (String nombre){\n    System.out.println(\"Hola, \" + nombre);\n}\n\n// FUNCIÓN CON DOS PARÁMETROS SIN RETORNO\nstatic void numeros(int n1, int n2){\n    System.out.println(\"El primer número es: \" + n1);\n    System.out.println(\"El segundo número es: \" + n2);\n}\n\n// FUNCIÓN CON DOS PARÁMETROS Y RETORNO\nstatic int calculadora(int num1, int num2){\n    int resultado = num1 + num2;\n    System.out.println(\"El resultado de la suma de los números es: \");\n    return resultado;\n}\n\n//FUNCIÓN ESTÁTICA\npublic static void estatico(){\n    System.out.println(\"Este es un ejemplo de un método estático\");\n}\n\n/*\n * VARIABLES LOCALES Y GLOBALES\n */\n\n//VARIABLE LOCAL\nstatic void local(){\n    String saludo = (\"Hola, soy una variable local\");\n    System.out.println(saludo);\n}\n\n//VARIABLE GLOBAL\nstatic String saludo = \"Hola, soy una variable global\";\n\n/*\n * EJERCICIO EXTRA\n */\n\nstatic int extra (String texto1, String texto2){\n    int a = 0;\n    int num = 1;\n    for (num=1; num>=0 && num<=100;num++){\n        if(num%3 == 0 && num%5 == 0){\n            System.out.println(texto1 + \" y \" + texto2);\n            a += 2;\n        }\n        else if(num%3==0){\n            System.out.println(texto1);\n            a += 1;\n        }\n        else if(num%5==0){\n            System.out.println(texto2);\n            a += 1;\n        }\n    }\n    System.out.println(a);\n    return a;\n}\n\n\npublic static void main(String[] args) {\n    \n    //LLAMADO DE FUNCIONES\n    bienvenida();\n    personalizado(\"Usuario\");\n    numeros(4,5);\n    calculadora(4,5);\n    estatico();\n\n    //FUNCIÓN YA CREADA EN JAVA\n    String cadena = \"Hola, te mostraré un método pre-construido en Java.\";\n    System.out.println(cadena);\n    System.out.println(\"La cadena de texto anterior tiene \" + cadena.length() + \" caracteres.\");\n\n    //VARIABLE GLOBAL\n    System.out.println(saludo);\n\n    //LLAMADO EJERCICIO EXTRA\n    extra(\"Multiplo de tres\",\"Múltiplo de cinco\");\n        \n}\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/java/yowcloud.java",
    "content": "import java.lang.Math;\npublic class yowcloud {\n    // Variable global\n    static int globalVar = 42;\n    public static void main(String[] args) {\n        holaMundo();\n        holaName(\"Cloud\");\n        addNumbers(4, 2);\n        System.out.println(\"El producto es: \" + multiplyNumbers(4, 2));\n        System.out.println(\"El resultado de elevar 2 al cubo es: \" + powerNumber(2, 4));\n        testVariables();\n        int result = dificultadExtra(\"Fizz\", \"Buzz\");\n        System.out.println(\"El número de veces que se ha impreso el número es: \" + result);\n    }  \n\n    // Función sin parámetros ni retorno\n    private static void holaMundo() {\n        System.out.println(\"Función sin parámetros ni retorno\");\n        System.out.println(\"¡Hola mundo!\");\n    }\n\n    // Función con un parámetro y sin retorno\n    private static void holaName(String name) {\n        System.out.println(\"Función con un parámetro y sin retorno\");\n        System.out.println(\"¡Hola \" + name + \"!\");\n    }\n\n    // Función con varios parámetros y sin retorno\n    private static void addNumbers(int num1, int num2) {\n        System.out.println(\"Función con varios parámetros y sin retorno\");\n        int sum = num1 + num2;\n        System.out.println(\"La suma es: \" + sum);\n    }\n\n    // Función con retorno\n    private static int multiplyNumbers(int num1, int num2) {\n        System.out.println(\"Función con retorno\");\n        return num1 * num2;\n    }\n\n    // Función que utiliza una función ya creada en el lenguaje (Math.pow)\n    private static double powerNumber(double base, double exponent) {\n        System.out.println(\"Función que utiliza una función ya creada en el lenguaje\");\n        return Math.pow(base, exponent);\n    }\n\n    // Función que prueba el concepto de variable LOCAL y GLOBAL\n    private static void testVariables() {\n        System.out.println(\"Función que prueba el concepto de variable LOCAL y GLOBAL\");\n        int localVar = 21; // Variable local\n        System.out.println(\"Variable global: \" + globalVar);\n        System.out.println(\"Variable local: \" + localVar);\n    }\n\n    private static int dificultadExtra(String str1, String str2) {\n        System.out.println(\"DIFICULTAD EXTRA\");\n        System.out.println(\"Función que recibe dos parámetros de tipo cadena de texto y retorna un número\");\n        int count = 0;\n        for (int pos = 1; pos <= 100; pos++)\n        {\n            if (pos % 3 == 0 && pos % 5 == 0)\n                System.out.println(str1 + str2);\n            else if (pos % 3 == 0)\n                System.out.println(str1);\n            else if (pos % 5 == 0)\n                System.out.println(str2);\n            else\n            {\n                System.out.println(pos);\n                count++;\n            }\n        }\n        return count;\n\n        \n    }\n\n    \n}\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/1Nonamed.js",
    "content": "// FUNCIONES -- FUNCTIONS\nconsole.log(\"Funciones\\n\");\n// FUNCIÓN POR DEFINICIÓN -- Function Declaration\nfunction greet() {\n  // Función sin retorno\n  console.log(\"Hi from function declaration\");\n}\n\n// FUNCIÓN POR EXPRESIÓN -- Function Expression\n// Puede ser una función anónima (lambda) o tener nombre\n\n// Función anónima (lambda)\nconst greeting = function () {\n  // Función con retorno, en este caso, un string\n  return \"Hello from fn expression\";\n};\n\n// Función con nombre\nconst sum = function sum(a, b) {\n  console.log(`La suma de a + b es = ${a + b}`);\n};\n//\n\n// FUNCIÓN AUTOINVOCADA - Immediately Invoked Function Expression (IIFE)\n\n// IIFE imprimiendo en consola\n(function (name) {\n  console.log(`*** IIFE Saludo autoinvocado de ${name}`);\n})(\"Daniel\");\n\n// IIFE con return y guardando su valor en una variable\nconst greetFromIIFE = (function (name) {\n  return `Saludo autoinvocado de ${name}`;\n})(\"Pablo\");\nconsole.log(`*** IIFE: ${greetFromIIFE}`);\n\n// CLAUSURAS -- Closures\n// Funciones dentro de otras ✅\nfunction squares(a, b) {\n  // La función interna (square) puede acceder al scope y variables de la función que la contiene (squares) pero no pasa lo contrario\n  function square(x) {\n    // Aquí se forma el Closure\n    return x * x;\n  }\n  console.log(square(a) + square(b));\n  return square(a) + square(b);\n}\n\n// ARROW FUNCTIONS\n// Siempre son anónimas\n// No tienen this\nconst myArrowFn = () => console.log(\"Log from Arrow Function\");\n\n// CALLBACKS\nconst myCallback = () => console.log(\"Log desde callback function\");\n\nconst mainFunction = (cb) => cb();\n\n// HOF -- High Order Functions\n// Funciones que reciben por parámetro otra función y/o devuelven una función mediante el return.\nfunction doubleOperationHOF(arr, operation) {\n    return arr.map(operation)\n}\n\nconst double = function (number) {\n    return number * 2\n};\n\nconst numbers = [1, 2, 3, 4, 5];\nconst doubledNumbers = doubleOperationHOF(numbers, double)\n\n\n// EJECUCIÓN DE FUNCIONES -- Function execution\nconsole.log('\\nFunction Logs\\n')\ngreet();\ngreeting(); \nsum(2, 8);\nsquares(2, 3);\nmyArrowFn();\nmainFunction(myCallback);\nconsole.log(doubledNumbers)\n\n// VARIABLES\nconsole.log(\"\\nVariables\\n\");\n\nlet myGlobal = \"Pedro\";\n\nconst myFn = () => {\n  let myLocal = \"David\";\n  console.log(`** Esta es mi variable global: ${myGlobal}`);\n  console.log(`** Esta es mi variable local dentro de myFn: ${myLocal}`);\n};\n\nmyFn();\n\n// RETO EXTRA\nconsole.log(\"\\n------ RETO EXTRA ------\");\n\nconst challengeFn = (arg1, arg2) => {\n  let counter = 0;\n  for (let i = 1; i <= 100; i++) {\n    if (i % 3 === 0 && i % 5 === 0) console.log(`${i} es ${arg1} y ${arg2}`);\n    else if (i % 3 === 0) console.log(`${i} es ${arg1}`);\n    else if (i % 5 === 0) console.log(`${i} es ${arg2}`);\n    else {\n      console.log(i);\n      counter++;\n    }\n  }\n  console.log(`\\nLas veces que se imprimió un número fue de: ${counter}`);\n  return counter;\n};\n\nchallengeFn(\"multiplo de 3\", \"multiplo de 5\");\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/7R0N1X.js",
    "content": "/*\n  Crea ejemplos de funciones básicas que representen las diferentes\n  posibilidades del lenguaje:\n  Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n*/\n\n// Funciones declaradas (Function declarations)\nfunction saludar() {\n  console.log(\"Hola!\");\n}\nsaludar();\n\n// Funciones expresadas (Function expressions)\nconst saludarExpresada = function () {\n  console.log(\"Hola desde una función expresada!\");\n};\nsaludarExpresada();\n\n// Funciones de flecha (Arrow functions)\nconst saludarFlecha = () => {\n  console.log(\"Hola desde una función de flecha!\");\n};\nsaludarFlecha();\n\n// Funciones anónimas (Anonymous functions)\nsetTimeout(function () {\n  console.log(\"Hola después de 1 segundo\");\n}, 1000);\n\n// Funciones de método (Method functions)\nconst objeto = {\n  saludar() {\n    console.log(\"Hola desde un método!\");\n  }\n};\nobjeto.saludar();\n\n// Funciones constructoras (Constructor functions)\nfunction Persona(nombre) {\n  this.nombre = nombre;\n}\nconst persona = new Persona(\"7R0N1X\");\nconsole.log(persona.nombre);\n\n// Funciones generadoras (Generator functions)\nfunction* generador() {\n  yield 1;\n  yield 2;\n  yield 3;\n}\nconst iterador = generador();\nconsole.log(iterador.next().value);\nconsole.log(iterador.next().value);\nconsole.log(iterador.next().value);\n\n// Funciones asíncronas (Async functions)\nasync function obtenerDatos() {\n  const respuesta = await fetch('https://valorant-api.com/v1/agents');\n  const datos = await respuesta.json();\n  console.log(datos);\n}\nobtenerDatos();\n\n// Variable local y global\nvar global = 20\nfunction func() {\n  var local = 10\n  console.log(local, global)\n}\n\nfunc()\n\n// Funciones anidadas\nfunction outerFunction() {\n  console.log(\"Soy la función exterior\");\n\n  function innerFunction() {\n    console.log(\"Soy la función interior\");\n  }\n\n  // Llamando a la función interior dentro de la función exterior\n  innerFunction();\n}\n\n// Llamando a la función exterior\nouterFunction();\n\n/*\n  Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n  La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n    Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n    Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n    Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n    La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n*/\n\nfunction imprimirNumeros(texto1, texto2) {\n  let contador = 0;\n  for (let i = 1; i <= 100; i++) {\n    if (i % 3 === 0) {\n      console.log(texto1);\n    }\n    if (i % 5 === 0) {\n      console.log(texto2);\n    }\n    if (i % 3 === 0 && i % 5 === 0) {\n      console.log(texto1 + texto2);\n    } else {\n      console.log(i);\n      contador++;\n    }\n  }\n}\n\nimprimirNumeros(\"Hola\", \"Mundo\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/AChapeton.js",
    "content": "// *** TIPOS DE FUNCIONES ***\n\n//Funcion Autoejecutable\n(function () {\n  console.log(\"Autoejecutable\");\n})();\n\n//Funcion por Declaracion\nfunction saludar() {\n  return console.log('Hello World!');\n}\nsaludar();\n\n//Funcion por Expresion\nvar saludo = function saludar2() {\n  return console.log('Hola!');\n};\nsaludo();\n\n//Funcion Anonima\nvar anonima = function () {\n  return console.log('Sin nombre');\n};\nanonima();\n\n//Arrow Function\nvar arrow = function () {\n  return console.log('Arrow function');\n};\narrow();\n\n//Callbacks\nvar funB = function () {\n  return console.log('Funcion B ejecutada');\n};\nvar funA = function (callback) {\n  callback();\n};\nfunA(funB);\n\n\n// *** FORMAS DE USO DE FUNCIONES ***\n\n//Sin parametros\nvar sinParametros = function () {\n  return console.log('Sin parametros');\n};\n\n//Con uno o varios parametros\nvar suma = function (a, b) {\n  return console.log(a + b);\n};\nsuma(4, 3);\n\n//Sin retorno\nvar sinReturn = function () {\n  console.log('Sin return');\n};\nsinReturn();\n\n//Con retorno\nvar conReturn = function () {\n  var sum = 4 + 5;\n  return sum;\n};\nconReturn();\n\n//Variable Local y Global\nvar globalVar = 10;\nvar funcLocal = function () {\n  var localVar = 4;\n  globalVar = 2;\n  return console.log(localVar + globalVar);\n};\n//localVar no es accesible fuera de la funcion\n//globalVar esta disponible en cualquier lugar de la funcion\nfuncLocal();\n\n\n//EJERCICIO EXTRA\nvar funbun = function (firstText, secondText) {\n  var count = 0;\n  for (var i = 1; i <= 100; i++) {\n      if (i % 3 === 0 && i % 5 === 0) {\n          console.log(firstText + secondText);\n      }\n      else if (i % 3 === 0) {\n          console.log(firstText);\n      }\n      else if (i % 5 === 0) {\n          console.log(secondText);\n      }\n      else {\n          count++;\n          console.log(i);\n      }\n  }\n  console.log('Numeros impresos: ', count);\n  return count;\n};\nfunbun('FUN', 'BUN');\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/AgusBelP.js",
    "content": "// #02  FUNCIONES Y ALCANCE\n\n/*\nEJERCICIO:\n- Crea ejemplos de funciones básicas que representen las diferentes posibilidades del lenguaje:\nSin parámetros ni retorno, con uno o varios parámetros, con retorno...\n- Comprueba si puedes crear funciones dentro de funciones.\n- Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n- Pon a prueba el concepto de variable LOCAL y GLOBAL.\nDebes hacer print por consola del resultado de todos los ejemplos (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n \nDIFICULTAD EXTRA (opcional):\nCrea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n- La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n- Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n- Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n- Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n- La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\nPresta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\nCada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n*/\n\n// <-------------------------> Funciones <------------------------->\n\n// Una función en JavaScript es un bloque de código o un conjunto de instrucciones que realiza una tarea específica y que puede reutilizarse a voluntad. Existen diversas formas de crear una función en JavaScript.\n\n// --->> Funciones por declaración\n\n// Esta forma permite declarar una función que existirá a lo largo de todo el código.\n\nfunction funcionPorDeclaracion() {\n    console.log('Este es el resultado de una función por declaración');\n}\n\nfuncionPorDeclaracion();\n\n// Es posible ejecutar la función saludar() incluso antes de haberla creado y funcionaría correctamente, ya que Javascript primero busca las declaraciones de funciones y luego procesa el resto del código.\n\n// --->> Variables locales y Globales\n\n// Una variable declarada dentro de una función solo es visible dentro de esa función. A dicha variable se la conoce como local.\n\nfunction variableLocal() {\n    let local = 'Soy una variable local';\n\n    console.log('Muestro el uso de una variable local: ' + local);\n}\n\nvariableLocal();\n\n// Una función también puede acceder a una variable externa o global. La función tiene acceso completo a la variable externa. Puede modificarlo también. La variable global solo se usa si no hay una local.\n\nlet variableGlobal = 'Soy una variable global';\n\nfunction funcionVariableGlobal() {\n    variableGlobal = 'Accediendo a la variable global desde la función'; // Cambio el valor de la variable global\n\n    let message = 'Hola! ' + variableGlobal;\n    console.log(message);\n}\n\nconsole.log(variableGlobal); //antes de llamar la función\n\nfuncionVariableGlobal();\n\nconsole.log('Ahora la variable global es: ' + variableGlobal); // el valor fué modificado por la función\n\n// Si una variable con el mismo nombre se declara dentro de la función, le hace sombra a la global. Por ejemplo, en el siguiente código, la función usa la variable userName local. La exterior se ignora:\n\nlet userName = 'John';\n\nconsole.log('La variable global es ' + userName);\n\nfunction showMessage() {\n    let userName = 'Bob'; // declara variable local\n\n    let message = 'Hello, ' + userName; // Bob\n    console.log('Accediendo desde la función se lee el mensaje: ' + message);\n}\n\n// la función crea y utiliza su propia variable local userName\nshowMessage();\n\nconsole.log(\n    'La variable global no cambió pues la función utilizó aquella que estaba dentro de su scope, entonces la variable global sigue siendo: ' +\n        userName\n); // John, se mantiene, la función no accedió a la variable externa\n\n// --->> Funciones con parámetros\n\n// Es posible llamar a una función y pasarle parámetros o argumentos para que los utilice:\n\nfunction funcionConParametros(from, text) {\n    // parámetros: from, text\n    console.log(from + ': ' + text);\n}\n\nfuncionConParametros('Ann', '¡Hola!');\nfuncionConParametros('Ann', '¿Cómo estás?');\n\n// en el caso de que se llame a una función que requiere de argumentos y no se determinen todos los parámetros aquellos que no estén definidos serán undefined\n\nconsole.log('Esto es un ejemplo de una función con un parámetro undefined: ');\nfuncionConParametros('Hola');\n\n// Es posible establecer valores por defecto para los argumentos:\n\nfunction funcionValorPorDefecto(a, b = 'valor por defecto') {\n    console.log(`Ma llamo ${a} y mi valor es: ${b}`);\n}\nfuncionValorPorDefecto('Mabel');\n\n// --->> Funciones con retorno\n\n// Unav función con retorno es una función que devuelve algo al ser llamada. Por ejemplo:\n\nfunction suma(a, b) {\n    return a + b;\n}\n\nconsole.log('El resultado de la suma es: ' + suma(1, 2));\n\n// --->> Funciones anónimas\n\n// Las funciones anónimas o funciones lambda son un tipo de funciones que se declaran sin nombre de función y se alojan en el interior de una variable haciendo referencia a ella cada vez que queramos utilizarla:\n\nconst saludo = function () {\n    return 'Hola';\n};\n\nconsole.log(saludo); // Imprimo la función\nconsole.log(saludo()); // Imprimo la salida 'Hola'\n\n// --->> Arrow functions\n\n// Las funciones flecha son una forma corta de escribir funciones que aparece en Javascript a partir de ECMAScript 6. Básicamente, se trata de eliminar la palabra function y añadir => antes de abrir las llaves:\n\nconst funcionTradicional = function () {\n    return 'Función tradicional.';\n};\n\nconsole.log(funcionTradicional());\n\nconst funcionFlecha = () => {\n    return 'Función flecha.';\n};\n\nconsole.log(funcionFlecha());\n\n// --->> Función dentro de otra función\n\n// Sin determinar un argumento\n\nfunction funcionExterna() {\n    let funcionInterna = (mensaje) => {\n        console.log(`¡Función interna ejecutada, con el mensaje ${mensaje}!`);\n    };\n    funcionInterna('Muy bien');\n}\n\nfuncionExterna();\n\n// Determinando argumentos\n\nfunction addCuadrado(a, b) {\n    function cuadrado(x) {\n        return x * x;\n    }\n    return cuadrado(a) + cuadrado(b);\n}\n\nconsole.log('El cuadrado de 2 más el cuadrado de 3 es ' + addCuadrado(2, 3));\n\n// --->> Función ya creada en el lenguaje\n\n// En este ejemplo se utiliza Math. Math es un objeto incorporado que tiene propiedades y métodos para constantes y funciones matemáticas. No es un objeto de función. A diferencia de los demás objetos globales, el objeto Math no se puede editar.\n//Math funciona con el tipo Number. No funciona con BigInt.\n\n// Utilizando Math para calcular la superficie de un círculo recordando que la fórmula es PI*r2:\n\nconst superficie = (radio) => {\n    let superficieCirculo = Number((Math.PI * Math.pow(radio, 2)).toFixed(2)); // la función toFixed() devuelve un string\n    return superficieCirculo;\n};\n\nconsole.log(superficie(2));\n\n// <-------------------------> EXTRA <------------------------->\n\nconst ejercicioExtra = (texto1, texto2) => {\n    let contador = 0;\n\n    for (let i = 1; i < 100; i++) {\n        if (i % 3 == 0 && i % 5 != 0) {\n            console.log(texto1);\n        } else if (i % 3 != 0 && i % 5 == 0) {\n            console.log(texto2);\n        } else if (i % 3 == 0 && i % 5 == 0) {\n            console.log(texto1 + '+' + texto2);\n        } else {\n            console.log(i);\n            contador += 1;\n        }\n    }\n\n    return contador;\n};\n\nconsole.log(\n    'La cantidad de veces que se ha impreso un número es: ',\n    ejercicioExtra('texto1', 'texto2') // La cantidad de veces que se ha impreso un número es:  53\n);\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/Ahinar.js",
    "content": "\n\nlet pi = 3.14; // Variable global\n\n// Ejemplo 1: Función sin parámetros ni retorno\nfunction saludar() {\n    console.log(\"Hola, ¿cómo estás?\");\n}\n\n// Ejemplo 2: Función con parámetros\nfunction suma(a, b) {\n    return a+b;\n}\n\n// Ejemplo 3: Función con parámetros y retorno\nfunction resta(a, b) {\n    return a - b;\n}\n\n// Ejemplo 4: Función que retorna el área de un círculo utilizando la variable global pi\nfunction areaCir(r) {\n    return pi * (r ** 2);\n}\n\n// Ejemplo 5: Función que retorna el área de un círculo utilizando una variable local pi\nfunction areaCir2(r) {\n    let pi = 3.1415; // Variable local\n    return pi * (r ** 2);\n}\n\n// Ejemplo 6: Función dentro de una función\nfunction operaciones(a,b) {\n    function multiplicar() {\n        return a * b;\n    }\n    console.log(`${a} por ${b} es ${multiplicar()}`); // Llamada a la función interna\n\n    function dividir() {\n      return a / b;\n    }\n    console.log(`${a} dividido ${b} es ${dividir()}`); // Llamada a la función interna\n\n  function restar() {\n    return a - b;\n  }\n  console.log(`${a} menos ${b} es ${restar()}`); // Llamada a la función interna\n\n  function potencia() {\n    return a** b;\n  }\n  console.log(`${a} elevado a la ${b} es ${potencia()}`); // Llamada a la función interna\n}\n\n\n// Ejemplo de función ya creada en el lenguaje: Math.round()\nfunction redondear(numero) {\n    return Math.round(numero);\n}\n\n// Prueba de variables LOCAL y GLOBAL\nconsole.log(pi); // Muestra la variable global pi\nfunction probarScope() {\n    let pi = 3.141592653589793; // Variable local\n    console.log(pi); // Muestra la variable local pi\n}\n\n// Llamadas a las funciones\nsaludar();\nconsole.log(`la suma de los parametros es ${suma(5, 8)}`);//devuelve 13\nconsole.log(resta(8, 6));//devuelve 2\nconsole.log(areaCir(2));\nconsole.log(areaCir2(2));\nlet resultsuma = suma(5,8);//almacenamos e resultado de la suma en una variable\nlet resultresta = resta(8,6);//almaceamos el resultado de la resta en una variable\noperaciones(6,3);\noperaciones(resultsuma,resultresta);//usamos las variables que almacenamos en las operaciones\nconsole.log(redondear(3.1415));\nprobarScope();\nconsole.log(pi); // Muestra la variable global pi nuevamente\n\n// Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n//  * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n//  *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n//  *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n//  *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n//  *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\nvar textoANum = function (text1,text2) {\n    let contador=0\n\n    for (let i = 1; i <=100; i++) {\n\n        if ( i%3==0 && i%5==0){\n            console.log(text1+text2)       \n\n        }else if (i%5==0) {\n            console.log(text2);\n        }else if (i %3==0){\n        console.log(text1);\n        }else{\n            console.log(i) \n            contador ++\n        }\n        \n    }\n    console.log(\"Numeros impresos: \", contador);\n  \n}\n\ntextoANum(\"pa\",\"co\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/Airesesteban.js",
    "content": "/*\nCrea ejemplos de funciones básicas que representen las diferentes\nposibilidades del lenguaje:\nSin parámetros ni retorno, con uno o varios parámetros, con retorno...\n*/\n\n// Funciones declaradas\n\nfunction hello(){\n    console.log(\"Hola!\")\n}\nhello()\n\n// Funciones expresadas\n\nconst helloExpresada = function(){\n    console.log(\"Hola desde una funcion expresada\")\n}\nhelloExpresada()\n\n// Función con retorno\n\nfunction multiplicar(a,b) {\n    return a * b\n}\nlet result = multiplicar(2,3)\nconsole.log(result)\n\n// Uso de una función ya creada en el lenguaje\n\nlet numeroAleatorio = Math.random()\nconsole.log(`Número aleatorio generado: ${numeroAleatorio}`)\n\n// Funciones de flecha (Arrow functions)\n\nconst helloArrow = () => {\n    console.log(\"Hola desde una arrow function\")\n}\nhelloArrow()\n\n\n// Funciones de método\nconst objeto= {\n    greet(){\n        console.log(\"Hola desde funcion metodo\")\n    }\n}\nobjeto.greet()\n\n// Funciones constructoras\n\n/* function Persona(nombre){\n    this.nombre = nombre\n}\nconst persona = new persona(\"Esteban\")\nconsole.log(persona.nombre)\n */\n\n// Variable local y global\n\nlet variableGlobal = \"Soy global\"\nfunction scope(){\n    let variableLocal = \"Soy Local\"\n    console.log(variableGlobal)\n    console.log(variableLocal)\n}\n\nscope()\n//console.log(variableLocal); // Esto dará un error porque variableLocal es local a la función\n\n// Funciones anidadas\n\n/*\nCrea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\nLa función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n    Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n    Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n    Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n    La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n*/\n\nfunction multiplos(text1,text2){\n    let count = 0\n    for(let i=1; i<=100; i++){\n        if (i % 3 == 0 && i % 5 == 0){\n            console.log(text1+text2)\n        }else if(i % 3 == 0){\n            console.log(text1)\n        }else if(i % 5 == 0 ){\n            console.log(text2)\n        }else{\n            console.log(i)\n            count ++\n        }\n    }\n    return count\n}\n\nlet contador = multiplos(\"Fizz\", \"Buzz\")\nconsole.log(contador)"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/AitorLcom.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n//Ejemplos de declaración de funciones\n//formas de declarar funciones sin parametros ni retorno\nfunction funcion1() {\n  if (1 === 1) {\n    console.log(\"1 es efectivamente 1\");\n  } else {\n    console.log(\"Estamos locos, 1 no es 1\");\n  }\n}\n\nlet funcion2 = function () {\n  if (1 === 1) {\n    console.log(\"1 es efectivamente 1\");\n  } else {\n    console.log(\"Estamos locos, 1 no es 1\");\n  }\n};\n\nlet arrowFunction = () => {\n  console.log(\"1 es efectivamente 1\");\n};\n\n//Formas de declarar funciones con parametros pero sin retorno\n\nfunction funcion3(a) {\n  if (a === 1) {\n    console.log(a + \" es efectivamente 1\");\n  } else {\n    console.log(a + \" no es 1\");\n  }\n}\n\nlet funcion4 = function (a) {\n  if (a === 1) {\n    console.log(a + \" es efectivamente 1\");\n  } else {\n    console.log(a + \" no es 1\");\n  }\n};\n\nlet arrowFunction2 = (a) => {\n  console.log(a + \" es efectivamente \" + a);\n};\n\n//Formas de declarar funciones con parametros y retorno\n\nfunction funcion5(a) {\n  if (a === 1) {\n    return a + \" es efectivamente 1\";\n  } else {\n    return a + \" no es 1\";\n  }\n}\n\nlet funcion6 = function (a) {\n  if (a === 1) {\n    return a + \" es efectivamente 1\";\n  } else {\n    return a + \" no es 1\";\n  }\n};\n\nlet arrowFunction3 = (a) => {\n  return a + \" es efectivamente \" + a;\n};\n\n//Metodo de crear funciones extra. Crear funciones dentro de un obejto\nlet objeto1 = {\n  funcionObjeto() {\n    console.log(\"Soy una función dentro de un objeto\");\n  },\n};\n\n//Crear funcion dentro de otra funcion (con bonus, retornar una funcion como resultado de otra: Función anidada)\n\nfunction nuevoSaludo(saludo) {\n  return function (nombre) {\n    console.log(saludo + \", \" + nombre);\n  };\n}\n\nlet saludoEspanol = nuevoSaludo(\"Hola\"); //la función nuevoSaludo retorna la función interna y esta se asigna a la variable saludoEspañol\nsaludoEspanol(\"Manuel\"); //Al llamar a saludoEspañol, se llama a la funcion interna que almacena y recibe el parametro nombre\n\n//Ejercico extra\n\nfunction impNum(a, b) {\n  console.log(\"Ejercicio FizzBuzz\");\n  console.log(\"------------------\")\n  for (let i = 1; i <= 100; i++) {\n    if (i % 3 === 0 && i % 5 === 0) {\n      console.log(a +  b);\n    } else if (i % 3 === 0) {\n      console.log(a);\n    } else if (i % 5 === 0) {\n      console.log(b);\n    } else {\n      console.log(i);\n    }\n  }\n  console.log(\"------------------\")\n}\nimpNum(\"Fizz\", \"Buzz\");"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/AlexanderTejedor.js",
    "content": "//Funciones Basicas\n/**\n * Función Tradicional\n * Sin parametros \n */\nfunction myFunction() { return console.log('Esta es una función') };\nmyFunction();\n/**Con Parametro */\nfunction saludar (name){ return console.log(`Hola ${name}`) };\nsaludar('JavaScript');\n/**Con mas parametros */\nfunction suma (a,b) { return console.log('El resultado de la suma es: ' + (a + b)) };\nsuma(2, 3);\n\n/**Función anónima */\nlet despedida = function (nombre) { return console.log(`Esta mi canción de despedida ${nombre}`) };\ndespedida('Sera lo mejor para los dos');\n\nlet despedirse = function (name) { return `Hasta luego ${name}`; };\nconsole.log(despedirse('Alex'));\n\n/**Función de flecha */\nconst multiplicar = (a, b) =>  a * b ;\nconsole.log(multiplicar( 28, 32 ));\n\n/**Función con parámetros por Defecto */\nlet saludarConIdioma = (nombre, idioma = 'es') => { return idioma === 'es' ? `Hola ${nombre}` : `Hello ${nombre}`; }\nconsole.log(saludarConIdioma('JavaScript'));\nconsole.log(saludarConIdioma('JavaScript', 'en'));\n\n/**Función autoejecutable (IIFE) */\n(function(){console.log('Esta funcion se ejecuta inmediatamente.');})\n();\n\n/**Función recursiva */\nfunction factorial (n) { return n === 0 ? 1 : n * factorial(n - 1) };\nconsole.log(factorial(5));\n\n/**Función de orden superior (High Order Function) */\nfunction operar (a, b, operacion) { return operacion(a, b) };\nconst sumar = (x, y) => x + y;\nconsole.log(operar(5, 78, sumar));\n\n/**Función que devuelve otra función (closures) */\nfunction crearSaludo(saludo) { return function (nombre) { return `${saludo} ${nombre}` } };\nconst saludoFormal = crearSaludo('Buenos días');\nconsole.log(saludoFormal('JavaScript'));\n\n/**Función asíncrona con async/await */\nasync function obtenerDatos() { return new Promise(resolve => setTimeout(() => resolve(\"Datos recibidos\"), 2000));}\nobtenerDatos().then(console.log);\n\n/**Función con Callbacks */\nfunction procesarUsuario(nombre, callback) { console.log(`Procesando usuario ${nombre}...`);\ncallback();}\nprocesarUsuario(\"Luis\", () => console.log(\"Usuario procesado.\"));\n\n/**Función constructora */\nfunction Persona(nombre, edad) {\n    this.nombre = nombre;\n    this.edad = edad;\n    this.saludar = function() {\n        return `Hola, soy ${this.nombre} y tengo ${this.edad} años.`;\n    };\n}\nconst persona1 = new Persona(\"Luis\", 30);\nconsole.log(persona1.saludar());\n\n/**Función generadora ( function* ) */\nfunction* contar() { yield 1; yield 2; yield 3; }\nconst generador = contar();\nconsole.log(generador.next().value);\nconsole.log(generador.next().value);\nconsole.log(generador.next().value);\n\n/**Función con bind() */\nconst usuario = { nombre: \"Ana\", saludar: function() { console.log(`Hola, soy ${this.nombre}`); }};\nconst nuevaFuncion = usuario.saludar.bind(usuario);\nnuevaFuncion();\n\n/**Función con call() y apply()*/\nfunction presentar (cargo) { console.log(`Hola, soy ${this.nombre} y trabajo como ${cargo}`);}\nconst persona = { nombre: \"Carlos\" };\npresentar.call(persona, \"desarrollador\"); \npresentar.apply(persona, [\"diseñador\"]);\n\n/**Funciones como Métodos y Objetos */\nconst coche = { marca: \"Toyota\",arrancar: function() { return `${this.marca} está arrancando...`;} };\nconsole.log(coche.arrancar());\n\n/**Funciones como parametros callback */\nfunction operar(a, b, operacion) {\n    return operacion(a, b);\n}\nconsole.log(operar(5, 3, (x, y) => x - y)); // Resta\n\n/**Función en clases */\nclass Animal {\n    constructor(nombre) {\n        this.nombre = nombre;\n    }\n    hablar() {\n        return `${this.nombre} hace un sonido.`;\n    }\n}\nconst perro = new Animal(\"Perro\");\nconsole.log(perro.hablar());\n\n//Variable local y global (scope)\n\n/**Scope global */\nvar nombre = 'Alexander';\nvar nombreCompleto = () => {\n    /**Scope Local */\n    let apellido = 'Tejedor';\n    console.log(`Hola, ${nombre} ${apellido}`)\n}\n// try{ \n//     nombreCompleto()\n//     console.log(apellido)\n// }catch (error) {\n//     console.error(error);\n// }\n\n/**DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n * - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n * - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n * - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n * - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n * */\n\nlet myFunc = (str1, str2) => {\n    let contador = 0;\n    for (i = 1; i <= 100; i++){\n        let cadena1 = String(str1);\n        let cadena2 = String(str2);\n\n        if (i % 3 === 0 && i % 5 === 0){\n            console.log(i + ' ' + cadena1 + ' ' + cadena2)\n        }else if (i % 3 === 0){\n            console.log(cadena1)\n        }else if (i % 5 === 0){\n            console.log(cadena2)\n        }else{\n            console.log(i)\n            contador++;\n        }\n    }\n    return contador;\n};\nlet resultado = myFunc('Hola', 'JavaScript');\nconsole.log(`Se han impreso los numeros ${resultado} veces en vez de textos`);"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/Alvaro-Neyra.js",
    "content": "// Funciones\n/*Sin parametros ni retorno, con uno o varios parametros, con retorno....*/\n\n// Funcion sin parametros ni retorno\nfunction funcionNormal() {\n    console.log(`Esta es una funcion normal que no tiene parametros ni retorna algo`);\n}\n\nfuncionNormal()\n\n// Funcion con varios parametros sin retorno\nfunction funcionDeDosParametros(nombre, edad) {\n    console.log(`Hola tu nombre es: ${nombre} y tu edad es: ${edad}`);\n}\n\n// Funcion con varios parametros con retorno\nfunction funcionConRetorno(string, numero) {\n    // Retorna la cantidad de caracteres del string menos el numero\n    let length = string.length;\n    return length - numero;\n}\n\ncantidadDeCaracteresMenosNumero = funcionConRetorno(\"Hola, Mundo!\", 5);\nconsole.log(`Esta es el valor de la longitud del String menos el numero pasado: ${cantidadDeCaracteresMenosNumero}`);\n\n// Llama a una funcion con valores opcionales\nfunction saludar(nombre = \"Invitado\", saludo = \"Hola\") { // Este modo de poner valores opcionales en los parametros es valido a partir de ES6+\n    return `${saludo}, ${nombre}!`\n}\n\nsaludo = saludar()\nconsole.log(saludo)\n\n// Una funcion con parametros opcionales y uno obligatorio\nfunction retornarValores(nombre, apellido = \"No Especificado\", origen = \"No Especificado\") {\n    if (nombre) {\n        console.log(`Tu nombre es: ${nombre}`)\n    }\n    if (apellido) {\n        console.log(`Tu apellido es: ${apellido}`)\n    }\n    if (origen) {\n        console.log(`Tu origen es: ${origen}`)\n    }\n}\n\nretornarValores(\"Alvaro\")\n\n// Funcion con parametros usando `...args`:\n// En este caso ...args es un array\nfunction sumaIlimitada(...args) {\n    let suma = 0;\n    for (let i = 0; i < args.length; i++) {\n        suma+= args[i];\n    }\n    return suma;\n}\n\nresultado = sumaIlimitada(20, 30, 40, 100);\nconsole.log(resultado);\n\n// Function Expressions:\n/* Las function expressions son casi similares a la declaracion de una funcion normal. La diferencia principal\nes el nombre de la funcion ya que podria ser omitida en ciertos casos o podrias ser asignada a un variable para luego ejecutarse\ncon el nombre de esa variable*/\n// OJO: Las function expressions no son afectadas en el hosting, esto quiere decir que no podrias usar este tipo de funcion antes de que sea declarada\nconst functionExpression = function () {\n    console.log(`Esta es una function expression!`);\n}\nfunctionExpression();\n\n// Usando el function expression como un callback:\n/* Los function expressions no necesariamente van a ser asignadas a una variable tambien podrian usarse para administrar un evento\ny no necesita un nombre: */\n/* button.addEventListener.(\"click\", function (event) {\n    console.log(`This is an anonymous function expression that handles an event, the event: ${event}!`)\n}) */\n\n// Immediately Invoked Function Expression (IIFE)\n// Esta funcion en espano es funcion expresion inmediatamende invocada, esta funcion se ejecuta luego de ser creada, como puedes ver no necesita un nombre:\n(function () {\n    console.log(\"IIFE funciona!\")\n})();\n\n// Arrow functions:\n// Los Arrow function es una alternativa a la tradicional function expression, pero con algunas diferencias y limitaciones:\n/* - Los arrow functions no pueden tener sus propias identificadores the valor como: `this`\n   - Arrow functions no pueden ser usados como constructores.*/\n\n// Un arrow function vacio: NO EJECUTA NADA\nconst emptyArrowFunction = () => {};\nemptyArrowFunction()\n// IIFE pero con Arrow function: retorna \"Hola, Mundo!\"\nconsole.log((() => \"Hola, Mundo!\")());\n// Arrow functions con retorno y llaves\nconst sumaArrow = (number1, number2) => { return number1 + number2};\nresultadoSuma = sumaArrow(40,3);\nconsole.log(resultadoSuma);\n// Arrow function sin parentesis, sin llaves y de una sola linea\nconst siEsMayorATreinta = number => number > 30 ? 30 : 10\nconsole.log(siEsMayorATreinta(31)) // -> 30\nconsole.log(siEsMayorATreinta(16)) // -> 10\n// Arrow functions con retorno implicito (no se usa la palabra reservada 'return')\nconst maximoNumero = (numero1, numero2) => (numero1 > numero2 ? numero1 : numero2);\nlet maxNumber = maximoNumero(20, 30);\nconsole.log(maxNumber);\n\n// Funciones asincronas\n// Creando la primera funcion asincrona\n//    const corutina1 = async () => {\n//       console.log(\"Inicio de la funcion asincrona 1\");\n\n//        await new Promise(resolve => setTimeout(resolve, 500));\n\n//       console.log(\"Fin de la funcion asincrona!\");\n//    }\n//    // Creando la segunda funcion asincrona\n//    const corutina2 = async () => {\n//        console.log(\"Inicio de la funcion asincrona 2\");\n\n//        await new Promise(resolve => setTimeout(resolve, 500));\n\n//        console.log(\"Fin de la funcion asincrona!\");\n//    }\n//    // Creando la funcion que va a ejecutar las dos funciones asincronas\n//    async function ejecutarFuncionesAsincronas() {\n//        try {\n//            process.stdout.write(\"Ejecutando funciones asincronas. Espere\")\n\n//            // Imprimiendo puntos consecutivos\n//            for (let i = 0; i < 8; i++) {\n//                await new Promise(resolve => setTimeout(resolve, 500));\n//                process.stdout.write(\".\");\n//           }\n\n//            // Nueva linea\n//            console.log();\n\n//            // Ejecutando la primera funcion asincrona\n//            await new Promise(resolve => resolve(corutina1()));\n\n//            process.stdout.write(\"Esperando a la funcion asincrona 2\")\n\n//            // Imprimiendo puntos consecutivos\n//            for (let i = 0; i < 8; i++) {\n//                await new Promise(resolve => setTimeout(resolve, 500));\n//                process.stdout.write(\".\");\n//            }\n\n//            // Nueva linea\n//            console.log();\n\n//            // Ejecutando la funcion asincrona 2\n//            await new Promise(resolve => resolve(corutina2()));\n//        }\n//        catch (error) {\n//            console.error(\"Se ha producido un error: \", error.message);\n//        }\n//    }\n//    ejecutarFuncionesAsincronas();\n\n//* - Comprueba si puedes crear funciones dentro de funciones.\nfunction funcionExterna(numero){\n    function funcionInterna(numeroAlDoble) {\n        return numeroAlDoble * 2;\n    }\n    let numeroDoblado = funcionInterna(numero);\n    return numeroDoblado;\n}\n\nresultadoDelNumero = funcionExterna(20);\nconsole.log(resultadoDelNumero);\n\n//* - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n\n// toString()\nlet numero = 43000.3;\nlet convertidoAString = numero.toString();\nconsole.log(convertidoAString);\n\n// max()\nlet nuevoArray = [20, 30, 400, 40, 50];\nlet numeroMax = Math.max(...nuevoArray);\nconsole.log(numeroMax);\n\n// min()\nlet numeroMin = Math.min(20, 10, 0, 400);\nconsole.log(numeroMin);\n\n// console.log()\nconsole.log(`'console.log' tambien es una funcion integrada del lenguaje!`);\n\n//* - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n\n// Variable local en JavaScript:\n/* SI UNA VARIABLE SE DECLARA DENTRO DE UNA FUNCION O ESTRUCTURA DE CONTROL USANDO `VAR`, `LET O `CONST`, SE CONSIDERA\nUNA VARIABLE LOCAL Y SOLO ES VISIBLE DENTRO DE ESA FUNCION O ESTRUCTURA DE CONTROL. */\n// Mira este ejemplo:\nlet variableInterna = 20; // Se declara una variable en el ambito global\n{\n    let variableInterna = 10; // Se declara una variable con el mismo nombre en el ambito local\n    console.log(variableInterna); // Solo existe en este ambito (dentro de los corchetes), se imprime en consola su valor asignado\n}\nconsole.log(variableInterna) // Se imprime el valor de la varaible global no la de local\n// Otro ejemplo:\n{\n    const nuevaVariable = \"Hola\";\n    console.log(nuevaVariable);\n}\n//console.log(nuevaVariable); // Dara error ya que la variable 'nuevaVariable no existe en el ambito GLOBAL' ❌\n\n// Variable Global\n/* Si una variable se declara fuera de cualquier función o bloque, se considera una variable global \ny es accesible desde cualquier parte del código. */\nlet variableGlobal = \"Mundo!\"\n\nfunction imprimeVariableGlobal() {\n    console.log(variableGlobal);\n}\n\nimprimeVariableGlobal(); // La variable 'variableGlobal' es accesible en cualquier ambito del codigo.\n\n// DIFICULTAD EXTRA!::\nconst intercambiarNumeros = (string1, string2) => {\n    // Creando contadores:\n    let contadorDeString1YString2 = 0;\n    let contadorDeString1 = 0;\n    let contadorDeString2 = 0;\n    let contadorDeNumerosNoIntercambiados = 0;\n\n    for (let i = 1; i <= 100; i++) {\n        if (i % 3 === 0 && i % 5 === 0) {\n            console.log(string1+string2);\n            contadorDeString1YString2++;\n        }\n        else if (i % 3 === 0) {\n            console.log(string1);\n            contadorDeString1++;\n        }\n        else if (i % 5 === 0) {\n            console.log(string2);\n            contadorDeString2++;\n        }\n        else {\n            contadorDeNumerosNoIntercambiados++;\n        }\n    }\n    console.log(`Numero de veces que los numeros han sido intercambiados por la primera cadena de texto: ${contadorDeString1}`)\n    console.log(`Numero de veces que los numeros han sido intercambiados por la segundo cadena de texto: ${contadorDeString2}`)\n    console.log(`Numero de veces que los numeros han sido intercambiados por la primera y segunda cadena de texto: ${contadorDeString1YString2}`)\n    return contadorDeNumerosNoIntercambiados;\n}\n\nlet cuentaDeNumeroNoIntercambiados = intercambiarNumeros(\"Hola\", \"Mundo\");\nconsole.log(`Numero de veces que los numeros no han sido intercambiados: ${cuentaDeNumeroNoIntercambiados}`)"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/AndresMCardenas.js",
    "content": "/* EJERCICIO:\n\n  * Crea ejemplos de funciones básicas que representen las diferentes\n    * posibilidades del lenguaje:\n * Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * Comprueba si puedes crear funciones dentro de funciones.\n * Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * Debes hacer print por consola del resultado de todos los ejemplos.\n * (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n\n*/\n\n// Funciones sin parámetros ni retorno\n\nfunction saludar() {\n  console.log(\"Hola\");\n}\n\nsaludar();// se invoca la función\n\n// Funciones con parámetros y retorno\n\nfunction sumar(dato1, dato2) {\n  return dato1 + dato2;\n}\n\nconsole.log(sumar(2, 3)); // se invoca la función y se imprime el resultado\n\n// Funciones con parámetros y sin retorno\n\nfunction restar(dato1, dato2) {\n  console.log(dato1 - dato2);\n} \n\nrestar(5, 3); // se invoca la función\n\n\n// Funciones con parámetros y retorno\n\nfunction multiplicar(dato1, dato2) {\n  return dato1 * dato2;\n} \n\nconsole.log(multiplicar(5, 3)); // se invoca la función y se imprime el resultado\n\n// Funcion dentro de una función\n\nfunction dividir(dato1, dato2) {\n  function sumar(dato1, dato2) {\n    return dato1 + dato2;\n  }\n  return sumar(dato1, dato2) / 2;\n}\n\nconsole.log(dividir(10, 2)); // se invoca la función y se imprime el resultado\n\n\n// Funciones ya creadas en el lenguaje\n\n// Función parseInt() - Convierte una cadena a un número entero\nlet cadena = \"123\";\nlet numero = parseInt(cadena);\nconsole.log(numero);  // Imprime: 123\n\n// Función parseFloat() - Convierte una cadena a un número de punto flotante\nlet cadenaFlotante = \"123.45\";\nlet numeroFlotante = parseFloat(cadenaFlotante);\nconsole.log(numeroFlotante);  // Imprime: 123.45\n\n// Función isNaN() - Comprueba si un valor es NaN\nlet valorInvalido = \"abc\" / 10;  // Esto resultará en NaN\nconsole.log(isNaN(valorInvalido));  // Imprime: true\n\n// Función Math.random() - Genera un número aleatorio entre 0 (inclusive) y 1 (exclusivo)\nlet aleatorio = Math.random();\nconsole.log(aleatorio);\n\n// Función Array.isArray() - Comprueba si un valor es un array\nlet array = [1, 2, 3];\nconsole.log(Array.isArray(array));  // Imprime: true\n\n// Función Date.now() - Devuelve el número de milisegundos transcurridos desde el 1 de enero de 1970 hasta la fecha/hora actual\nlet fecha = Date.now();\n\nconsole.log(fecha);\n\n// Crear un nuevo objeto Date que representa la fecha y hora actuales\nlet fecha2 = new Date();\n\n// Obtener el día, mes y año\nlet dia = fecha2.getDate();  // Devuelve el día del mes (de 1 a 31)\nlet mes = fecha2.getMonth() + 1;  // Devuelve el mes (de 0 a 11, por eso se suma 1)\nlet año = fecha2.getFullYear();  // Devuelve el año\n\nconsole.log(\"Hoy es \" + dia + \"/\" + mes + \"/\" + año);\n\n// Variable local y global\n\nlet variableGlobal = \"Soy una variable global\";\n\nfunction mostrarVariableGlobal() {\n  console.log(variableGlobal);\n}\n\nmostrarVariableGlobal(); // Imprime: Soy una variable global\n\nfunction mostrarVariableLocal() {\n  let variableLocal = \"Soy una variable local\";\n  console.log(variableLocal);\n}\n\nmostrarVariableLocal(); // Imprime: Soy una variable local\n\n// console.log(variableLocal); // Imprime: Uncaught ReferenceError: variableLocal is not defined\n\n// Función anónima se usa para asignar una función a una variable o constante\n\nlet funcionAnonima = function () {\n  console.log(\"Soy una función anónima\");\n}\n\nfuncionAnonima(); // Imprime: Soy una función anónima\n\n// Función flecha se usa para asignar una función a una variable o constante\n\nlet funcionFlecha = () => {\n  console.log(\"Soy una función flecha\");\n}\n\nfuncionFlecha(); // Imprime: Soy una función flecha\n\nlet objeto = {\n  valor: 'Hola',\n  funcion: function () {\n    console.log(this.valor); // Imprime: Hola\n  },\n  funcionFlecha: () => {\n    console.log(this.valor); // Imprime: undefined\n  }\n}\nobjeto.funcion();\nobjeto.funcionFlecha();\n\n/*\nDIFICULTAD EXTRA (opcional):\n  Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n  La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n  Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n  Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n  Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n  La función retorna el número de veces que se ha impreso el número en lugar de los textos \n  Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n  Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n*/\n\n// var writtenNumber = require('written-number'); // Se instala el paquete written-number para convertir números a letras se usa el comando: npm install written-number\n\n// function imprimirNumeros(cadena1, cadena2) { \n//   contador = 0;\n//   numeroaletras1 = 0;\n//   for (let i = 1; i <= 100; i++) {\n//     if (i % 3 == 0 && i % 5 == 0) {\n//       numeroaletras1 = i;\n//       palabras1 = writtenNumber(numeroaletras1, { lang: 'es' });\n//       console.log(palabras1);\n//       //console.log(cadena1 + cadena2);\n//     } else if (i % 3 == 0) {\n//       numeroaletras1 = i;\n//       palabras1 = writtenNumber(numeroaletras1, { lang: 'es' });\n//       console.log(palabras1);\n//       //console.log(cadena1);\n//     } else if (i % 5 == 0) {\n//       numeroaletras1 = i;\n//       palabras1 = writtenNumber(numeroaletras1, { lang: 'es' });\n//       console.log(palabras1);\n//       //console.log(cadena2);\n//     } else {\n//       console.log(i);\n//       contador++;\n//     }\n//   }\n//   return contador;\n// }\n// resultado = imprimirNumeros(\"Fizz\", \"Buzz\");\n// console.log(\"Número de veces que se ha impreso el número en lugar de los textos: \", resultado);\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/Andresargote.js",
    "content": "// Funciones en JavaScript\n\n// Las funciones son bloques de código, que nos permiten ejecutar una tarea especfica cuando son llamadas.\n\n// Las funciones en JavaScript pueden ser declaradas, expresadas, de flecha, anónimas, de método, constructoras, generadoras y asíncronas.\n\n// Funciones declaradas (Function declarations)\n\n// Las funciones declaradas son funciones que se definen con la palabra clave function, seguida de un nombre, una lista de parámetros entre paréntesis y un bloque de código entre llaves.\n\nfunction saludar() {\n  console.log('Hola! Soy una función declarada');\n}\n\nsaludar(); // Hola! Soy una función declarada\n\n// Funciones expresadas (Function expressions)\n\n// Las funciones expresadas son funciones que se definen y se asignan a una variable.\n\nconst despedirse = function () {\n  console.log('Adiós! Soy una función expresada');\n};\n\ndespedirse(); // Adiós! Soy una función expresada\n\n// Funciones de flecha (Arrow functions)\n\n// Las funciones de flecha son una forma más corta de escribir funciones anónimas, tienen una sintaxis más simple y no cambian el valor de this cuando se utilizan.\n\nconst sumar = (a, b) => {\n  return a + b;\n};\n\nconsole.log(sumar(3, 5));\n\n// Funciones anónimas (Anonymous functions)\n\n// Las funciones anónimas son funciones que no tienen nombre y se utilizan generalmente como argumentos de otras funciones.\n\nsetTimeout(function () {\n  console.log('Hola después de 1 segundo');\n}, 1000);\n\n// Funciones de método (Method functions)\n\n// Las funciones de método son funciones que se definen dentro de un objeto.\n\nconst objeto = {\n  saludar() {\n    console.log('Hola desde un método');\n  },\n};\n\nobjeto.saludar(); // Hola desde un método\n\n// Funciones constructoras (Constructor functions)\n\n// Las funciones constructoras son funciones que se utilizan para crear objetos.\n\nfunction Persona(nombre) {\n  this.nombre = nombre;\n}\n\nconst persona = new Persona('Andrés');\n\nconsole.log(persona.nombre); // Andrés\n\n// Funciones generadoras (Generator functions)\n\n// Las funciones generadoras son funciones que nos permiten pausar y reanudar la ejecución de una función, como por ejemplo, en un bucle for, es utilizado para iterar sobre una secuencia de valores.\n\nfunction* generador() {\n  yield 1;\n  yield 2;\n  yield 3;\n}\nconst iterador = generador();\nconsole.log(iterador.next().value); // 1\nconsole.log(iterador.next().value); // 2\nconsole.log(iterador.next().value); // 3\n\n// Funciones asíncronas (Async functions)\n\n// Las funciones asíncronas son funciones que nos permiten trabajar con código asíncrono de una forma más sencilla y legible.\n\nasync function obtenerDatos() {\n  const respuesta = await fetch('https://jsonplaceholder.typicode.com/posts');\n  const datos = await respuesta.json();\n  console.log(datos);\n}\nobtenerDatos();\n\n// Variable local y global\n\n// Las variables declaradas dentro de una función son locales y solo pueden ser accedidas dentro de la función.\n\nfunction mostrarMensaje() {\n  var mensaje = 'Hola desde una función';\n  console.log(mensaje);\n}\n\nmostrarMensaje(); // Hola desde una función\nconsole.log(mensaje); // mensaje is not defined the variable is local\n\n// Las variables declaradas fuera de una función son globales y pueden ser accedidas desde cualquier parte del código.\n\nvar mensaje = 'Hola desde una variable global';\n\nfunction mostrarMensaje2() {\n  console.log(mensaje);\n}\n\nmostrarMensaje2(); // Hola desde una variable global\nconsole.log(mensaje); // Hola desde una variable global\n\n// Funciones anidadas\n\n// Las funciones anidadas son funciones que se definen dentro de otra función.\n\nfunction funcionExterior() {\n  console.log('Soy la función exterior');\n\n  function funcionInterior() {\n    console.log('Soy la función interior');\n  }\n\n  funcionInterior();\n}\n\nfuncionExterior();\n\n// Extra: parámetros y argumentos, los parámetros son los nombres de los valores que se pasan a una función, y los argumentos son los valores reales que se le pasan a la función.\n\nfunction printNumbersOrStringChain(stringOne, stringTwo) {\n  let printNumberCounter = 0;\n  for (let i = 1; i <= 100; i++) {\n    let output = '';\n    if (i % 3 === 0) {\n      output += stringOne;\n    }\n    if (i % 5 === 0) {\n      output += stringTwo;\n    }\n    if (output === '') {\n      printNumberCounter++;\n    } else {\n      console.log(output);\n    }\n  }\n\n  return printNumberCounter;\n}\n\nconsole.log(printNumbersOrStringChain('Hello', 'World'));\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/AndrewCodev.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n//Funcion tradicional\nfunction tradicional() {\n  console.log(\"Función creada de manera tradicional\");\n}\n\ntradicional();\n\n//funciones de flecha\n\nconst sinParamsNiReturns = () => {\n  console.log(\"Esta función no tiene parametros ni retornos\");\n};\n\nsinParamsNiReturns();\n\nconst conParametros = (num1, num2) => {\n  console.log(num1 + num2);\n};\n\nconParametros(27, 7);\n\nconst conRetorno = (num1, num2) => {\n  return num1 + num2;\n};\n\nconRetorno(9, 8);\n\n//Funciones dentro de funciones?\n\nconst miPrimerFuncion = (nombre, apellido, edad) => {\n  const persona = [nombre, apellido, edad];\n\n  const miSegundaFuncion = (persona) => {\n    console.log(persona);\n    return (\n      \"Mi nombre es : \" +\n      persona[0] +\n      \", mi apellido es: \" +\n      persona[1] +\n      \" y mi edad es: \" +\n      persona[2]\n    );\n  };\n\n  return miSegundaFuncion(persona);\n};\n\nmiPrimerFuncion(\"Andrew\", \"Codev\", 31);\n\n//Variable local y global\nlet varGlobal = \"Soy global\";\n\nconst localGlobal = (varGlobal) => {\n  let varLocal = \"Soy Local\";\n  if (varGlobal === varLocal) {\n    return \"La variable local y la global son iguales\";\n  } else {\n    return \"La variable local y la global son diferentes\";\n  }\n};\n\nlocalGlobal(varGlobal);\n\n// DIFICULTAD EXTRA\nconst dificultadExtra = (cad1, cad2) => {\n  let contador = 0;\n\n  for (let i = 0; i <= 100; i++) {\n    const esMultiploDe3 = i % 3 === 0;\n    const esMultiploDe5 = i % 5 === 0;\n\n    if (esMultiploDe3 && esMultiploDe5) {\n      console.log(`${cad1} ${cad2}`);\n    } else if (esMultiploDe3) {\n      console.log(`${cad1}`);\n    } else if (esMultiploDe5) {\n      console.log(`${cad2}`);\n    } else {\n      console.log(i);\n      contador++;\n    }\n  }\n\n  return contador;\n};\n\nconst vecesNumero = dificultadExtra(\"Hola\", \"Mundo\");\nconsole.log(`Números impresos: ${vecesNumero}`);\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/Angel-Delg.js",
    "content": "// Funciones sin parametros ni valor de retorno y por declaración\nfunction Greeting(){\n   console.info(\"Hello Javascript\");\n}\nGreeting();\n\n// Funciones con parametros y sin valor de retorno y por declaración\nfunction GreetingUser( name ){\n   console.log(`Hello ${ name }`);\n}\nGreetingUser(\"Alicia\");\n\n// Funciones con valor de retorno y parametros\nfunction SumOfNumbers(x, y, ...rest){\n   return rest.reduce((count, current) => count + current \n   ,0) + (x + y)\n}\n\nconsole.log(SumOfNumbers(1, 2, 3, 4, 5, 7));\n\n// Funciones expresadas sin valor de retorno ni parametros\n// Usamos un array global para que la funciones puedan usarlas\nconst Fruits = [\"Apple\", \"Pear\", \"Grapes\", \"Cherry\", \"Blueberry\", \"Strawberry\"]\n\nconst ShowFruitList = function(){\n   Fruits.forEach( fruit => {\n      console.log( fruit )\n   })\n}\nShowFruitList();\n\nconst FindFruit = function(fruit){\n   Fruits.forEach( currentFruit => {\n      if(currentFruit === fruit){\n         console.log(\"La manzana si existe!\");\n         return;\n      }\n   })\n}\nFindFruit(\"Apple\");\n\n// Closure\nfunction miFuncion() {\n   let contador = 0;\n\n   function incrementar() {\n      contador++;\n      return contador;\n   }\n\n   return incrementar;\n}\n \nconst incremento = miFuncion();\n \nconsole.log(incremento()); // 1\nconsole.log(incremento()); // 2\n \n/* DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n **/\n\n\nconst Challenge = (str1, str2) => {\n   for(let i = 1; i <= 100; i++){\n      (i % 3 === 0 && i % 5 === 0) ? console.log(str1 + str2)\n      : (i % 3 === 0) ? console.log(str1)\n      : (i % 5 === 0) ? console.log(str2)\n      : console.log(i)\n   }\n}\nChallenge(\"Fizz\", \"Buzz\");"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/ArticKun.js",
    "content": "\n\n//* 1. FUNCIONES Y TIPOS DE FUNCIONES -----\n/*\nLas funciones en JavaScript son bloques de código reutilizable que \nrealizan una tarea específica. Son fundamentales en la programación en \nJavaScript y se utilizan para organizar el código, modularizar la lógica, \ny facilitar la reutilización.\n*/\n\n//⚡⚡ Declaración de Función -----\nfunction miFuncion() {\n    console.log('Declaración de funcion');\n};\nmiFuncion(); // Llamada a la funcion\n\n\n//⚡⚡ Expresión de Función / Anónima -----\nconst miFuncion2 = function() {\n    console.log('Expresion de Funcion');\n};\nmiFuncion2(); // Llamada a la funcion\n\n\n//⚡⚡ Funciones Anónimas -----\nconst miFuncion3 = function() {\n    console.log('Funcion anonima / expresion de la funcion');\n};\nmiFuncion3(); // Llamada a la funcion\n\n\n//⚡⚡ Funciones que se auto ejecutan -----\n//Se autoejecutan al colocar: ()\n( function() {\n    console.log('Funcion Auto-Ejecutable');\n})();\n\n\n//⚡⚡ Funciones con parametros y argumentos y retorno -----\n/*\nLas funciones pueden recibir parametros que son enviados como argumentos al\nllamar a la funcion, son los valores o datos con los que trabajaremos dentro\nde la misma, y pueden tener o no el mismo nombre\n\nrecibe = parametros\nal llamarla = argumentos\n\n*/\n\n//           parametros\nfunction suma( a, b ) {\n    return a + b;\n};\n\n//            argumentos\nconsole.log( suma(3,3) ); // Llamada a la funcion\n\n\n//⚡⚡ Funciones con Valores predeterminados -----\n//             parametro con valor predeterminado\nfunction saludar( nombre = \"Artic\" ) {\n    console.log( `Hola, ${nombre}!` );\n};\nsaludar(); // Llamada a la funcion\n\n\n//⚡⚡ Funcion flecha o Arrow Function o lambda -----\nconst miFuncion4 = () => {\n    console.log('Arrow function');\n};\nmiFuncion4(); // Llamada a la funcion\n\n/* Las funcion de flecha tiene la facultad de poder simplificarse\nu omitir parentesis, llaves y tener un retorno implícito, siempre que sea una\nlinea de código el cuerpo de la funcion en si mismo solo usamos el simbolo =>\n*/\nconst miFuncion5 = nombre => `Mi nombre es ${nombre}`;\nmiFuncion5( 'Artic' ); //Llamada a la funcion\n\n/* Cuando tenemos dos parametros o mas, ya no debemos quitar los ()\nel cuerpo si sigue siendo una única expresion si podemos omitir las llaves y\nentender el return como implícito */\nconst sumar = (a, b) => a + b;\nsumar( 5,5 ); //Llamada a la funcion\n\n\n//⚡⚡ Funciones Recursivas -----\nfunction sumaArray(array) {\n// Caso base: si el array está vacío, la suma es 0\n    if ( array.length === 0 ) {\n      return 0;\n    } else {\n// Caso recursivo: la suma es el primer elemento del array más la suma del resto de los elementos\n      return array[0] + sumaArray( array.slice(1) );\n    }\n};\n  \n// Ejemplo de uso\nconst array = [1, 2, 3, 4, 5];\nconst resultado = sumaArray(array);\nconsole.log(resultado); // Salida: 15 (1 + 2 + 3 + 4 + 5)\n\n\n//⚡⚡ Funciones Anidadas dentro de otras funciones -----\n//Ejemplo 1 \n//La función interior solo es accesible dentro del cuerpo de la función exterior.\nfunction exterior() {\n\n    console.log(\"Función exterior\");\n\n        function interior() {\n            console.log(\"Función interior\");\n        }\n\n        interior(); // Llamada a la función interna\n};\n  \nexterior(); // Llamada a la función exterior\n\n//Ejemplo 2\nfunction exterior( x ) {\n// Función interna (closure)\n    function interior( y ) {\n      return x + y;\n    }\n  \n    return interior;\n};\n  \n  const closureFunc = exterior( 10 );   // El valor de x se establece en 10\n  const resultado2  = closureFunc( 5 ); // Llamamos a la función interna con y = 5\n  \n  console.log( resultado2 );            // Salida: 15\n  \n/*\nCuando una función se declara dentro de otra función, la función \ninterna tiene acceso a las variables de la función externa, \nincluso después de que la función externa haya completado su ejecución. \n\n📌 Variables capturadas: Las funciones internas dentro de otras funciones \ncapturan las variables de la función externa, permitiendo el acceso a \nesas variables incluso después de que la función externa haya finalizado.\n\n📌 Preservación del entorno léxico: El entorno léxico (conjunto de variables \ndisponibles en un momento dado) se mantiene vivo en el closure, lo que \nsignifica que las funciones internas pueden hacer referencia a variables \nde su entorno externo.\n\n📌 Encapsulamiento: Los closures proporcionan una forma de \nencapsular variables y lógica, permitiendo la creación de\nfunciones más especializadas.\n\nLos closures son una característica fundamental en JavaScript y \nse utilizan comúnmente en patrones de diseño y programación funcional \npara lograr modularidad y reutilización de código.\n*/ \n\n//⚡⚡ Funciones como parametros de otras funciones -----\n//Tambien son conocidas como CALLBACKS\n/*\nEn JavaScript, puedes pasar funciones como parámetros a otras funciones. \nEsto es útil para lograr mayor flexibilidad y reutilización de código.\n*/\n\n/*En JavaScript, la terminología \"callback\" se utiliza para describir \nuna función que se pasa como argumento a otra función y que se ejecutará \ndespués de que la función principal haya completado su ejecución.\n\nEn resumen, un callback es simplemente una función que se pasa como \nparámetro a otra función. Esta función pasada como parámetro se ejecutará \nen algún momento futuro, generalmente después de que se complete una \noperación asíncrona o se produzca un evento.\n*/\n\n//Ejemplo 1\n// Función que toma dos números y una función para realizar una operación\nfunction operacionBinaria( a, b, operacion ) {\n    return operacion( a, b );\n};\n  \n// Funciones para realizar diferentes operaciones\nfunction adicion( x, y ) {\n    return x + y;\n};\n  \nfunction resta( x, y ) {\n    return x - y;\n};\n  \n// Uso de la función operacionBinaria con diferentes operaciones\nconsole.log( operacionBinaria( 5, 3, adicion ) );  // Salida: 8\nconsole.log( operacionBinaria( 5, 3, resta ) );    // Salida: 2\n\n//Ejemplo2\n// Función que ejecuta otra función n veces\nfunction ejecutarNVeces( n, funcion ) {\n    for (let i = 0; i < n; i++) {\n      funcion();\n    }\n};\n  \n// Función de ejemplo para ser ejecutada\nfunction saludo() {\n    console.log(\"Hola, mundo!\");\n};\n  \n// Llamado de la función ejecutarNVeces para ejecutar la función saludar 3 veces\nejecutarNVeces( 3, saludo );\n  \n\n//Ejemplo 3 Callback\nfunction realizarOperacion( a, b, callback ) {\n    const resultado = a + b;\n    callback( resultado );\n};\n  \nfunction miCallback(resultado) {\n    console.log( \"El resultado es: \" + resultado );\n};\n  \nrealizarOperacion( 3, 4, miCallback );\n\n//Ejemplo 4 Callback Asincrono\nfunction hacerAlgoAsincrono( callback2 ) {\n    setTimeout( function() {\n      console.log( \"Operación asíncrona completada\" );\n      callback2();\n    }, 2000);\n};\n  \nfunction miCallback2() {\n    console.log( \"Callback ejecutado\" );\n};\n  \nhacerAlgoAsincrono( miCallback2 );\n  \n\n//* 2. ALGUNAS FUNCIONES PROPIAS DE JAVASCRIPT -----\n\n/*\nLa mayoria de las veces cuando veamos () es simbolo de que es una funcion\no una linea de codigo que se puede ejecutar\nLa documentación oficial de JavaScript es una excelente fuente para \nexplorar más funciones y aprender sobre sus usos\n*/\n\n//📌 1 Console.log()\nconsole.log(\"Hola, mundo!\");\n// Imprime \"Hola, mundo!\" en la consola del navegador o entorno de ejecución.\n//📌 2 Alert\nalert(\"¡Esto es una alerta!\");\n// Muestra una alerta en el navegador con el mensaje proporcionado.\n//📌 3 Confirm\nconst confirmacion = confirm(\"¿Está seguro?\");\nconsole.log(confirmacion); \n// Devuelve true si el usuario hizo clic en \"Aceptar\" y false si hizo clic en \"Cancelar\".\n//📌 4 PaseInt\nconst numeroEnTexto = \"42\";\nconst numero = parseInt( numeroEnTexto );\nconsole.log( numero ); // Devuelve el número entero 42.\n// Convierte una cadena de texto que representa un número en un valor numérico entero.\n//📌 5 Math.Round\nconst numeroDecimal = 5.67;\nconst redondeado = Math.round( numeroDecimal );\nconsole.log( redondeado ); // Resultado: 6\n// Redondea un número al entero más cercano.\n//📌 6 Push()\nconst arr = [1, 2, 3];\narray.push(4);\nconsole.log(arr); // Resultado: [1, 2, 3, 4]\n// Añade un elemento al final de un array.\n\n\n//* 3. SCOPE DE JAVASCRIPT (LOCAL / GLOBAL) -----\n\n/*\nEl ámbito (scope) en JavaScript se refiere a la visibilidad \ny accesibilidad de las variables en diferentes partes del código. \nHay dos tipos principales de ámbito: local y global.\n*/\n\n// 1 Variable Local\n\n/*\nVariable Local:\nUna variable declarada dentro de una función es una variable local. \nEsto significa que su alcance está limitado a la función en la que se \ndeclara y no es accesible fuera de esa función.\n*/\n\nfunction ejemploLocal() {\n// Variable local\n    let x = 10;\n    console.log( x ); // Se puede acceder dentro de la función\n};\n  \nejemploLocal();    // Imprimirá 10 ya que es el llamado propio de la funcion\n// console.log(x); // Esto dará un error, ya que x no es accesible fuera de la función\n\n// 2 Variable Global\n\n/*\nUna variable declarada fuera de cualquier función o bloque de código es una variable global. \nEstá disponible en todo el código, incluidas las funciones, y se puede acceder desde \ncualquier parte del código.\n*/\n\n// Variable global\nlet y = 20;\n\nfunction ejemploGlobal() {\n  console.log( y ); // Se puede acceder dentro de la función\n};\n\nejemploGlobal();\nconsole.log( y );  // También se puede acceder fuera de la función\n\n\n//* 4. DIFICULTAD EXTRA -----\n/*\nCrea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n  - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n    - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n    - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n    - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n    - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n*/\n\nfunction extra( texto1, texto2 ) {\n\n    let contador = 0;\n  \n    for ( let i = 1; i <= 100; i++ ) {\n\n        if( i % 3 === 0 && i % 5 === 0 ){\n            console.log( `Soy ${texto1} y ${texto2}` );\n        }else if( i % 3 === 0 ){\n            console.log( `Soy ${texto1}` );\n        }else if( i % 5 === 0  ){\n            console.log( `Soy ${texto2}` );\n        }else{\n            console.log( i );\n            contador ++;\n        }\n    }\n    return `Los numeros impresos, que NO son texto, son: ${contador}`;\n};\n  \nlet reto = extra( \"multiplo de 3\",\"multiplo de 5\" );\nconsole.log( reto );"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/Carles11.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n *  */\nfunction optNoReturn() {\n    console.log('Esta función sin params y no retorna nada, solo imprime.');\n  }\n  \n  function optWithReturn() {\n    const str = 'Esta otra función retorna una string, que se puede imprimir';\n    return str;\n  }\n  \n  function optWithParamsAndNoReturn(printThis) {\n    console.log(printThis);\n  }\n  \n  function optWithParamsWithReturnDouble(returnThis) {\n    return returnThis * 2;\n  }\n  \n  const doubleThis = optWithParamsWithReturnDouble(4)\n\n  function higherOrderFunction(value){\n    return function insideFunction(factor){\n        return value * factor\n    }\n  }\n  \n  var iAmGlobal = \"soy una variable global\"\n  \n  function defineScope(){\n      let iAmLocal = \"Soy una variable local\"\n  \n      console.log({iAmGlobal})\n      console.log({iAmLocal})\n  }\n  \n  optNoReturn();\n  console.log(optWithReturn());\n  optWithParamsAndNoReturn('Whaaaat?');\n  console.log(optWithParamsWithReturnDouble(2));\n  console.log(doubleThis)\n\n  // Uso de función que retorna otra función\nconst doubleThisAgain = higherOrderFunction(2);\nconsole.log(doubleThisAgain(4));  // Outputs: 8\n\ndefineScope();\nconsole.log(\"esto no funciona: \", {iAmLocal})\n\n\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\nfunction extraJob(string1, string2) {\n    let counter = 0;\n    let min = 1;\n    let max = 100;\n\n    for (let i = min; i <= max; i++) {\n        if (i % 3 === 0 && i % 5 === 0) {\n            console.log(string1 + string2);\n        } else if (i % 3 === 0) {\n            console.log(string1);\n        } else if (i % 5 === 0) {\n            console.log(string2);\n        } else {\n            console.log(i);\n            counter += 1;\n        }\n    }\n\n    return counter;\n}\n\n// Llamada de ejemplo a la función\nconsole.log(\"Número de veces que se ha impreso el número:\", extraJob(\"Ola\", \"Kease\"));"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/CaveroBrandon.js",
    "content": "/*\nEJERCICIO:\n- Crea ejemplos de funciones básicas que representen las diferentes\nposibilidades del lenguaje:\n Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n- Comprueba si puedes crear funciones dentro de funciones.\n- Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n- Pon a prueba el concepto de variable LOCAL y GLOBAL.\n- Debes hacer print por consola del resultado de todos los ejemplos.\n(y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n*/\n\nlet global_counter = 0;\n\n// **** Function without parameters or return ****\nfunction printSmallTriangle() {\n    global_counter += 1;\n    console.log('Function without parameters or return');\n    console.log('*');\n    console.log('**');\n    console.log('****');\n    global_counter += 1;\n}\n\n// **** Function with one parameter no return ****\nfunction printMoneySymbol(qty) {\n    global_counter += 1;\n    console.log('\\nFunction with one parameter no return');\n    let outputLine = '';\n    for (let i = 0; i < qty; i++) {\n        outputLine = outputLine + '$';\n    }\n    console.log(outputLine);\n}\n\n// **** Function without parameter and with a return ****\nfunction getRandomNumber() {\n    global_counter += 1;\n    console.log('\\nFunction without parameter and with a return');\n    return Math.random();\n}\n\n// **** Function with multiple parameters, multiple returns and using functions within the function ****\nfunction registerUser(name, lastname, age) {\n    function isLegal(age) {\n        return age >= 18;\n    }\n\n    function getUsername(name, lastname) {\n        let slicedName = name.slice(0,3);\n        let slicedLastname = lastname.slice(0,3);\n        return slicedName + slicedLastname;\n    }\n    \n    global_counter += 1;\n\n    let fullName = name + ' ' + lastname;\n\n    console.log('\\nFunction with multiple parameters, multiple returns and using functions within the function');\n    return [fullName, getUsername(name, lastname), isLegal(age)];\n}\n\n//**** Recursive function ****\nfunction factorial(num) {\n    if (num == 0 || num == 1) {\n        return 1;\n    }\n    else {\n        return num * factorial(num - 1);\n    }\n}\n\n\nprintSmallTriangle();\nprintMoneySymbol(3);\nconsole.log('Random number generated is: ' + getRandomNumber());\n\nlet user = registerUser('Brandon', 'Cavero', 30);\nconsole.log('The registered user is:\\nFull name: ' + user[0] + '\\nUsername: ' + user[1] + '\\nIs legal?: ' + user[2]);\n\nconsole.log('\\nRecursive function');\nconsole.log('The factorial of 5 is: ' + factorial(5));\n\n/*\nDIFICULTAD EXTRA (opcional):\nCrea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n- La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n    - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n    - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n    - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n    - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n*/\n\nfunction extraDificulty(firstString = 'Tic', secondString = 'Tac') {\n    global_counter += 1;\n    let counter = 0;\n\n    for (let i = 1; i < 101; i++) {\n        if (i % 3 == 0 && i % 5 == 0) {\n            console.log(firstString + secondString);\n        }\n        else if (i % 3 == 0) {\n            console.log(firstString);\n        }\n        else if (i % 5 == 0) {\n            console.log(secondString);\n        }\n        else {\n            counter += 1;\n            console.log(i);\n        }\n    }\n    return counter;\n}\n\ncounter = extraDificulty(firstString = 'Zip', secondString = 'Zap');\nconsole.log('\\nThe number of times that the number was print instead of the texts is: ' + counter);\nconsole.log('\\nThe number of functions called is: ' + global_counter);\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/CesarCarmona30.js",
    "content": "/**\n * EJERCICIO\n */\n\n\n// Función sin parámetros ni retorno\nconst greet = () => console.log(\"Hi!\");\n\ngreet();\n\n// Función con un parámetro sin retorno\nfunction greetPerson(name) {\n    print(`¡Hello ${name}!`);\n}\n\ngreetPerson('Tilin');\n\n// Función con múltiples parámetros y retorno\nconst add = (number1, number2) => console.log(`${number1 + number2}`);\n\nadd(5, 8);\n\n// Función con varios parámetros con retorno\nfunction subtract(number1, number2) {\n  return number1 - number2\n}\n\nconsole.log(`175 - 123 = ${subtract(175, 123)}`)\n\n// Función que retorna una función\nfunction createMultiplier(factor) {\n    return function(number) {\n        return number * factor;\n    };\n}\n\n// Función dentro de otra función\nfunction exteriorFunction(x) {\n    function interiorFunction(y) {\n        return y * 2 // Puede acceder a la variable local de la función externa\n    }\n\n    let result = x + interiorFunction(x);\n    return result\n}\n\n/**\n * EXTRA\n */\n\nfunction printNumbers(text1, text2) {\n    let printed_numbers = 0; \n\n    for (let number = 1; number <= 100; number++) {\n        if (number % 3 === 0 && number % 5 === 0) {\n          console.log(`${text1} y  ${text2}`);\n        } else if (number % 3 === 0) {\n          console.log(`${text1}`);\n        } else if (number % 5 === 0) {\n          console.log(`${text2}`);\n        } else {\n          console.log(number);\n          printed_numbers++;\n        }\n    }\n    return printed_numbers;\n}\n\nprints = printNumbers(\"Múltiplo de 3\", \"Múltiplo de 5\");\nconsole.log(prints)"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/DAVstudy.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n// Funcion sin argumentos y sin retorno\nfunction greeting() {\n  console.log(\"Hola!, Javascript\");\n}\n\ngreeting();\n\n// Funcion con argumentos y sin retorno\nfunction greetingUser(user) {\n  console.log(`Hola!, ${user}`);\n}\n\ngreetingUser(\"Diego\");\n\n// Funcion con argumentos y retorno\nfunction mult(a, b) {\n  return a * b;\n}\n\nconsole.log(mult(2, 10));\n\n// funcion anonima\nconst counterWords = function (text) {\n  const words = text.split(\" \");\n  return words.length;\n};\n\nconsole.log(\n  counterWords(\n    \"Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\"\n  )\n);\n\n// Funcion flecha o arrow function\n\nconst bigNumber = (array) => {\n  return array.sort().pop();\n};\n\nconsole.log(bigNumber([1, 10, 2, 334, 290, 2, 1, 3]));\n\n// Funciones anidadas\n\nfunction extern(a) {\n  console.log(\"Hola!, Externo\");\n  function intern(a) {\n    console.log(\"Hola!, interno\");\n  }\n  intern();\n}\n\nextern();\n\n// Funciones de ordern superior\nfunction operationNumber(a, b, callback) {\n  return callback(a, b);\n}\n\nconsole.log(operationNumber(2, 100, mult));\n\n/*\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n */\n\nconst fizzbuzz = (fizz, buzz) => {\n  let count = 0\n  for (let i = 1; i < 101; i++) {\n    if (i % 3 === 0 && i % 5 === 0) {\n      console.log(fizz + buzz)\n    } else if (i % 3 == 0) {\n      console.log(fizz)\n    } else if (i % 5 === 0) {\n      console.log(buzz)\n    } else {\n      console.log(i)\n      count++\n    }\n  }\n  return count\n}\n\nconsole.log(fizzbuzz(\"fizz\", \"buzz\"))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/Dan-Corbo.js",
    "content": "/*\n * EJERCICIO:\n * 1- Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * 2- Comprueba si puedes crear funciones dentro de funciones.\n * 3- Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * 4- Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * 5- Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n */\n\n\n/* Soluciones */\n\n// 1- 5- Funciones Basicas\n\nfunction saludo() {\n    console.log(\"Hola Gente!!\");\n}\n\nsaludo();\n\n\nfunction saludoConNombre(nombre) {\n    console.log(\"Hola\" + \" \" + nombre + \"!!\" );\n}\n\nsaludoConNombre(\"Daniel\");\n\n\nfunction suma(num1, num2) {\n    return num1 + num2;\n}\n\nconsole.log(suma(1, 5));\n\nfunction funcionQueSaluda() {\n    return \"Hola!! soy una funcion!!\";\n}\n\nconsole.log(funcionQueSaluda());\n\n\n// 2- 5- Funcion dentro de otra funcion\n\nfunction llamada() {\n    return `Hola funcion estas ahi?? - ${funcionQueSaluda()}`;\n}\n\nconsole.log(llamada());\n\n\n// 3- 5- Funciones preexistentes\n\n// Esta funcion toma una cadena como parametro y devuelve su longitud utilizando length.\nfunction obtenerLongitud(cadena) {\n    return cadena.length;\n}\n\nconsole.log(obtenerLongitud(\"Javascript\"));\n\n// Esta linea convierte la cadena \"123\" a un numero entero utilizando parseInt.\nlet cadenaNumero = \"123\";\nlet numero = parseInt(cadenaNumero);\n\nconsole.log(numero);\n\n\n// 4- 5- Variables locales y globales\n\n// Ejemplo de variable global\nvar variableGlobal = \"Soy una variable global\";\n\nfunction pruebaVariables() {\n    // Ejemplo de variable local dentro de una funcion\n    let variableLocal = \"Soy una variable local\";\n\n    console.log(variableLocal);\n    console.log(variableGlobal);\n}\n\npruebaVariables();\n\n// Intentando acceder a la variable local fuera de la funcion resultara en un error\n// console.log(variableLocal);\n\n// Accediendo a la variable global fuera de la funcion funciona\nconsole.log(variableGlobal);\n\n\n// Opcional\nfunction opcional(palabra1, palabra2) {\n    let numeros = 0;\n    for (let i = 1; i <= 100; i++) {\n        if (i % 3 == 0) {\n            console.log(palabra1);\n        } \n        if (i % 5 == 0) {\n            console.log(palabra2);\n        }\n        if (i % 3 == 0 && i % 5 == 0) {\n            console.log(palabra1 + \" \" + palabra2);\n        } else {\n            numeros++;\n            console.log(i);\n        }\n    }\n    return numeros;\n}\n\nconsole.log(opcional(\"Varios\", \"Numeros\"));"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/DanielBustos342.js",
    "content": "//* Funcion declarada: se define utilizando la palabra clave `function` seguida del nombre de la funcion. Las funciones declaradas se pueden llamar antes de su definicion debido al \"hoisting\"\n\nfunction sayHello() {\n  console.log(\"Hello, world!\");\n}\n\n// Llamando a la función\nsayHello(); // Imprime \"Hello, world!\"\n\n//? Hoisting: es un comportamiento de javaScript donde las declaraciones de variables y funciones son movidas automaticamente al comienzo de su contexto de ejecucion(el contexto actual de la funcion o del script) antes de que el codigo real sea ejecutado. Esto significa que puedes utilizar varialbes y funciones antes de declararlas en el codigo.\n\n//* Hoisting de Funciones: las declaraciones de funciones en javaScript son completamente elevadas (hoisted) a la parte superior del contexto de ejecucion. Esto permite llamar a las funciones antes de su declaracion en el codigo.\n\n// Llamada a la función antes de su declaración\ngreet();\n\nfunction greet() {\n  console.log(\"Hello, world!\");\n}\n\n// Salida: \"Hello, world!\"\n\n//* Hoisting de Variables: las declaraciones de variables con 'var' tambien son elevadas al inicio del contexto, pero solo la declaracion, no la asignacion. Esto puede llevar a comportamientos inesperados.\n\nconsole.log(a); // Salida: undefined\nvar a = 5;\nconsole.log(a); // Salida: 5\n\n//* Hoisting con 'let' y 'const': las variables con 'let' y 'const' tambien son elevadas, pero no estan inicializadas. Intentar accedere a ellas antes de la declaracion resultara en un error de referencia(ReferenceError).\n\n//console.log(b); // ReferenceError: Cannot access 'b' before initialization\nlet b = 10;\n\n//console.log(c); // ReferenceError: Cannot access 'c' before initialization\nconst c = 20;\n\n//* Hoisting con Funciones expresadas y funciones de flecha: las funciones expresadas y las funciones flecha no son elevadas de la misma manera que las funciones declaradas. Solo la declaracion de la variable que contiene la funcion es elevada, no la definicion de la funcion.\n\n// Función expresada\n//console.log(sum); // Salida: undefined\nvar sum = function () {\n  console.log(\"Sum function\");\n};\nsum(); // Salida: \"Sum function\"\n\n// Función flecha\nconsole.log(multiply); // Salida: undefined\nvar multiply = () => {\n  console.log(\"Multiply function\");\n};\nmultiply(); // Salida: \"Multiply function\"\n\n//* Funcion Expresada: las funciones expresadas se definen asignando una funcion anonima a una variable. A diferencia de las funciones declaradas, las funciones expresadas no se elevan.\n\nconst sayHello1 = function () {\n  console.log(\"Hola, mundo! --> Funcion expresada\");\n};\n\n// Llamando a la función\nsayHello1(); // Imprime \"Hello, world!\"\n\n//* Funcion flecha: las funciones flecha son una forma mas conocida de escribir funciones en javaScript. Se definen utilizando la sintaxis '=>'.\n\nconst sayHello2 = () => {\n  console.log(\"Hola, mundo! --> Funcion flecha\");\n};\n\n// Llamando a la función\nsayHello2(); // Imprime \"Hello, world!\"\n\n//! Funciones sin parametros ni retorno:\nconsole.log(\"Funciones sin parametros ni retorno\");\n//* Mostrar un mensaje: una funcion que simplemente imprime un mensaje en la consola.\n\nfunction greet1() {\n  console.log(\"Hola!!, Bienvenido a JavaScript! \");\n}\n\ngreet1(); // Imprime \"Hola!!, Bienvenido a JavaScript!\"\n\n//* Mostrar Hora actual\n\nconst showCurrentTime = () => {\n  const now = new Date();\n  console.log(`La hora actual es: ${now.toLocaleTimeString()}`);\n};\n\nshowCurrentTime(); // Imprime la hora actual en formato local\n\n//* Realizar una Operacion matematica\n\nfunction addTwoNumbers() {\n  const a = 5;\n  const b = 3;\n  console.log(`The sum is: ${a + b}`);\n}\n\naddTwoNumbers(); // Imprime \"The sum is: 8\"\n\n//* Actualizar el contenido de una pagina web\n\n// function updateContent() {\n//   document.getElementById(\"content\").innerText = \"Content has been updated!\";\n// }\n\n// // Llamando a la función\n// updateContent();\n\n//* Configurar un temporizador\n\nfunction showAlert() {\n  console.log(\"Esta es una alerta temporizada!\");\n  //   alert(\"Esta es una alerta temporizada!\");\n}\n\n// Llamando a la función después de 3 segundos\nsetTimeout(showAlert, 3000);\n\n//! Funciones con uno o varios parametros:\nconsole.log(\"Funciones con uno o varios parametros\");\n\n//* Funcion con un parametro:\n//* funcion que saluda a una persona\nfunction greet2(name) {\n  console.log(`Hello, ${name}!`);\n}\n// Llamando a la función con un parámetro\ngreet2(\"Alice\"); // Imprime \"Hello, Alice!\"\ngreet2(\"Bob\"); // Imprime \"Hello, Bob!\"\n\n//* Funciones con varios parametros\n//* funcion que suma dos numeros\nfunction add(a, b) {\n  return a + b;\n}\n\n// Llamando a la función con dos parámetros\nconsole.log(add(3, 4)); // Imprime 7\nconsole.log(add(10, 5)); // Imprime 15\n\n//* Funcion que multiplica tres numeros\nfunction multiply1(x, y, z) {\n  return x * y * z;\n}\n\n// Llamando a la función con tres parámetros\nconsole.log(multiply1(2, 3, 4)); // Imprime 24\nconsole.log(multiply1(1, 5, 6)); // Imprime 30\n\n//* Funcion con parametros predeterminados: los parametros predeterminados permiten asignar valores por defecto a los parametros en caso de que no pasen argumentos durante la llamada de la funcion.\n//* Funcion con un parametro determinado\nfunction greet3(name = \"Guest\") {\n  console.log(`Hello, ${name}!`);\n}\n\n// Llamando a la función sin pasar un argumento\ngreet3(); // Imprime \"Hello, Guest!\"\n// Llamando a la función con un argumento\ngreet3(\"Alice\"); // Imprime \"Hello, Alice!\"\n\n//* Funciones con un numero variable de parametros: puedes usar el objeto `arguments` o el operador de propagacion (`...`) para manejar un numero de variables de parametros.\n//* Funcion que suma un numero variable de argumentos usando el operador de propagacion.\nfunction sum1(...numbers) {\n  return numbers.reduce((total, num) => total + num, 0);\n}\n\n// Llamando a la función con diferentes números de argumentos\nconsole.log(sum1(1, 2, 3)); // Imprime 6\nconsole.log(sum1(4, 5, 6, 7)); // Imprime 22\n\n//* Funcion flecha con parametros: las funciones flecha ('=>') proporcionan una sintaxis mas consisa para definir funciones.\n//* Funcion flecha que resta dos numeros.\nconst subtract = (a, b) => a - b;\n\n// Llamando a la función con dos parámetros\nconsole.log(subtract(10, 3)); // Imprime 7\nconsole.log(subtract(5, 2)); // Imprime 3\n\n//! Funciones con retorno:\nconsole.log(\"Funciones con retorno\");\n\n//* Funcion que suma dos numeros\nfunction add1(a, b) {\n  return a + b;\n}\n\nlet result = add1(3, 4); // Llamando a la función y almacenando el resultado\nconsole.log(result); // Imprime 7\n\n//* Funcion que verifica si un numero es par\nfunction isEven(number) {\n  return number % 2 === 0;\n}\n\nconsole.log(isEven(4)); // Imprime true\nconsole.log(isEven(7)); // Imprime false\n\n//* Funcion que devuelve el valor absoluto de un numero\nfunction absoluteValue(num) {\n  if (num < 0) {\n    return -num;\n  }\n  return num;\n}\n\nconsole.log(absoluteValue(-5)); // Imprime 5\nconsole.log(absoluteValue(3)); // Imprime 3\n\n//* Funcion que devuelve el mayor de dos numeros\nfunction max(a, b) {\n  if (a > b) {\n    return a;\n  }\n  return b;\n}\n\nconsole.log(max(10, 20)); // Imprime 20\nconsole.log(max(50, 30)); // Imprime 50\n\n//* Funcion que calcula el factorial de un numero\nfunction factorial(n) {\n  if (n === 0 || n === 1) {\n    return 1;\n  }\n  return n * factorial(n - 1);\n}\n\nconsole.log(factorial(5)); // Imprime 120\nconsole.log(factorial(3)); // Imprime 6\n\n//* Funcion que devuelve una cadena en mayusculas\nfunction toUpperCase(str) {\n  return str.toUpperCase();\n}\n\nconsole.log(toUpperCase(\"hello\")); // Imprime \"HELLO\"\nconsole.log(toUpperCase(\"world\")); // Imprime \"WORLD\"\n\n//* Funcion que concatena dos cadenas\nfunction concatenate(str1, str2) {\n  return str1 + \" \" + str2;\n}\n\nconsole.log(concatenate(\"Hello\", \"World\")); // Imprime \"Hello World\"\nconsole.log(concatenate(\"Good\", \"Morning\")); // Imprime \"Good Morning\"\n\n//* Funcion flecha que multiplica dos numeros\nconst multiply2 = (a, b) => {\n  return a * b;\n};\n\nconsole.log(multiply2(3, 4)); // Imprime 12\nconsole.log(multiply2(5, 6)); // Imprime 30\n\n//* Funcion flecha que devuelve el cuadrado de un numero\nconst square = (x) => x * x;\n\nconsole.log(square(5)); // Imprime 25\nconsole.log(square(8)); // Imprime 64\n\n//* Funcion que retorna un objeto\nfunction createPerson(name, age) {\n  return {\n    name: name,\n    age: age,\n  };\n}\n\nlet person = createPerson(\"Alice\", 25);\nconsole.log(person); // Imprime { name: 'Alice', age: 25 }\n\n//! Funciones dentro de funciones: en js puedes definir funciones dentro de otras funciones. Esto se conoce como funciones anidadas. Las funciones internas tienen acceso a las variables y parametros de las funciones externas, lo que permite un encapsulacion y modularidad mas efectivas.\n\nconsole.log(\"Funciones dentro de funciones\");\n//* Funcion Anidada simple:\nfunction outerFunction(x) {\n  console.log(\"Outer function\");\n\n  function innerFunction(y) {\n    console.log(\"Inner function\");\n    return x + y;\n  }\n\n  return innerFunction;\n}\n\nconst inner = outerFunction(5);\nconsole.log(inner(10)); // Imprime 15\n\n//* Funcion que calcula el area y el perimetro de un rectangulo\nfunction rectangleMetrics(length, width) {\n  function calculateArea() {\n    return length * width;\n  }\n\n  function calculatePerimeter() {\n    return 2 * (length + width);\n  }\n\n  return {\n    area: calculateArea(),\n    perimeter: calculatePerimeter(),\n  };\n}\n\nconst metrics = rectangleMetrics(5, 3);\nconsole.log(`Area: ${metrics.area}`); // Imprime \"Area: 15\"\nconsole.log(`Perimeter: ${metrics.perimeter}`); // Imprime \"Perimeter: 16\"\n\n//* Funcion de cierre (Closure): un cierre es una funcion interna que tiene acceso a las variables de la funcion externa, incluso despues de que la funcion externa haya finalizado su ejecucion.\nfunction counter() {\n  let count = 0;\n\n  return function () {\n    count++;\n    return count;\n  };\n}\n\nconst increment = counter();\nconsole.log(increment()); // Imprime 1\nconsole.log(increment()); // Imprime 2\nconsole.log(increment()); // Imprime 3\n\n//* Funcion que genera otras funciones: en este ejemplo, la funcion externa \"makeMultiplier\" genera y devuelve una funcion interna que multiplica su argumento por un factor especifico.\nfunction makeMultiplier(multiplier) {\n  return function (x) {\n    return x * multiplier;\n  };\n}\n\nconst double = makeMultiplier(2);\nconst triple = makeMultiplier(3);\n\nconsole.log(double(5)); // Imprime 10\nconsole.log(triple(5)); // Imprime 15\n\n//* Funcion anudada con parametros: en este ejemplo, las funciones internas utilizan parametros para realizar calculos especificos.\nfunction calculateHypotenuse(a, b) {\n  function square(x) {\n    return x * x;\n  }\n\n  return Math.sqrt(square(a) + square(b));\n}\n\nconsole.log(calculateHypotenuse(3, 4)); // Imprime 5\nconsole.log(calculateHypotenuse(5, 12)); // Imprime 13\n\n//* Funcion que filtra y mapea valores: en este ejemplo, la funcion externa \"filterAndMap\" tiene dos funciones internas para filtrar y mapear una lista de numeros.\nfunction filterAndMap(arr) {\n  function filterEvenNumbers(numbers) {\n    return numbers.filter((num) => num % 2 === 0);\n  }\n\n  function squareNumbers(numbers) {\n    return numbers.map((num) => num * num);\n  }\n\n  const evenNumbers = filterEvenNumbers(arr);\n  return squareNumbers(evenNumbers);\n}\n\nconst numbers = [1, 2, 3, 4, 5, 6];\nconsole.log(filterAndMap(numbers)); // Imprime [4, 16, 36]\n\n//*Las funciones anidadas en JavaScript permiten una mayor modularidad y encapsulación del código. Pueden ser utilizadas para crear cierres, generar otras funciones, y para organizar mejor la lógica interna de una función compleja. Al tener acceso a las variables de la función externa, las funciones internas pueden aprovechar el contexto y los datos del entorno donde fueron definidas.\n\n//! Funciones ya creadas en el lenguaje\nconsole.log(\"Funciones ya creadas en el lenguaje\");\n\n//* Funcion que formatea una fecha: vamos a utilizar las funciones incorporadas de js para trabajas con flechas ('Date') y anidarlas dentro de una funcion personalizada para formatear la fecha.\nfunction formatDate(dateString) {\n  function padZero(num) {\n    return num < 10 ? \"0\" + num : num;\n  }\n\n  const date = new Date(dateString);\n  const day = padZero(date.getDate());\n  const month = padZero(date.getMonth() + 1); // Los meses comienzan en 0\n  const year = date.getFullYear();\n\n  return `${day}/${month}/${year}`;\n}\n\nconsole.log(formatDate(\"2024-07-03\")); // Imprime \"03/07/2024\"\nconsole.log(formatDate(\"1990-01-01\")); // Imprime \"01/01/1990\"\n\n//* Funcion que convierte una cadena a titulo: usaremos las funciones de cadena ('String') de js, como 'toLowerCase', 'toUpperCase' y 'split', anidadas dentro de una funcion personalizada para convertir una cadena en formato titulo (donde cada palabra comienza con una letra mayuscula).\nfunction toTitleCase(str) {\n  function capitalize(word) {\n    return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();\n  }\n\n  return str.split(\" \").map(capitalize).join(\" \");\n}\n\nconsole.log(toTitleCase(\"hello world\")); // Imprime \"Hello World\"\nconsole.log(toTitleCase(\"javaScript is FUN\")); // Imprime \"Javascript Is Fun\"\n\n//* Funcion que filtra numeros positivos y calcula la suma: usaremos las funciones de arreglo ('array') de js como 'filter' y 'reduce', anidadas dentro de una funcion personalizada para filtrar numeros positivos y calcular la suma.\nfunction sumOfPositiveNumbers(arr) {\n  function isPositive(num) {\n    return num > 0;\n  }\n\n  function sum4(total, num) {\n    return total + num;\n  }\n\n  const positiveNumbers = arr.filter(isPositive);\n  return positiveNumbers.reduce(sum4, 0);\n}\n\nconst numbers1 = [-1, 2, -3, 4, -5, 6];\nconsole.log(sumOfPositiveNumbers(numbers1)); // Imprime 12\n\n//* Funcion que genera una cadena aleatoria: usaremos la funcion 'Math.random' y otras funciones de cadena ('String'), anidadas dentro de una funcion personalizada para generar una cadena aleatoria de una longitud especifica.\nfunction generateRandomString(length) {\n  const characters =\n    \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\";\n\n  function getRandomCharacter() {\n    const randomIndex = Math.floor(Math.random() * characters.length);\n    return characters.charAt(randomIndex);\n  }\n\n  let randomString = \"\";\n  for (let i = 0; i < length; i++) {\n    randomString += getRandomCharacter();\n  }\n\n  return randomString;\n}\n\nconsole.log(generateRandomString(10)); // Ejemplo: \"A1b2C3d4E5\"\nconsole.log(generateRandomString(15)); // Ejemplo: \"fGh1I2jK3L4mN5\"\n\n//* Funcion que encuentra el maximo valor de un arreglo: usaremos la funcion 'Math.max' y la funcion 'apply' anidadas dentro de una funcion personalizada para encontrar el valor maximo en un arreglo.\nfunction findMax(arr) {\n  function getMax() {\n    return Math.max.apply(null, arr);\n  }\n\n  return getMax();\n}\n\nconst values = [10, 20, 30, 5, 25];\nconsole.log(findMax(values)); // Imprime 30\n\n//! Variable global y local\nconsole.log(\"Variable global y local\");\n//* las variables globales son aquellas que se definen fuera de cualquier funcion. Estas variables estan disponibles en cualquier partde del codigo.\n// Variable global\nlet globalVar = \"I'm a global variable\";\n\nfunction displayGlobalVar() {\n  // Accediendo a la variable global dentro de una función\n  console.log(globalVar);\n}\n\ndisplayGlobalVar(); // Imprime \"I'm a global variable\"\n\n//* Variables locales: se definen dentro de una funcion y solo estan disponibles dentro de esa funcion. No se pueden acceder desde fuera de la funcion\nfunction localVarFunction() {\n  // Variable local\n  let localVar = \"I'm a local variable\";\n  console.log(localVar); // Imprime \"I'm a local variable\"\n}\n\nlocalVarFunction();\n\n// Intentando acceder a la variable local fuera de la función\n//console.log(localVar);\n// Error: localVar is not defined\n\n//!Extra\n// Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n//   - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n//     - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n//     - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n//     - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n//     - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n//   Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n//   Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n\nconst extra = (strA, strB) => {\n  for (let i = 1; i <= 100; i++) {\n    if (i % 3 === 0 && i % 5 === 0) {\n      console.log(strA + strB);\n    } else if (i % 3 === 0) {\n      console.log(strA);\n    } else if (i % 5 === 0) {\n      console.log(strB);\n    } else {\n      console.log(i);\n    }\n  }\n};\n\nextra(\"Ejercicio\", \"Extra\");\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/DannyMarperOne.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:                                                                ✓\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...                     ✓\n * - Comprueba si puedes crear funciones dentro de funciones.                                   ✓\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.                              ✓\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.                                       ✓\n * - Debes hacer print por consola del resultado de todos los ejemplos.                         ✓\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n\n// Declaración de función simple o \"DECLARADA\"\nfunction hola() {\n    console.log(\"Hola a toda la comunidad\");\n}\nhola();\n\n// Funcion \"EXPRESADA\"\nconst comida = function () {\n    console.log(\"Salsa de chile seco\");\n}\ncomida();\n\n// Función con return\nfunction colores() {\n    return (\"Arcoiris\")\n}\nconsole.log(colores());\n\n// Funcion que recibe un solo parametro\nfunction consolaVideo(consola) {\n    console.log(`Mi consola favorita es ${consola}`);\n}\nconsolaVideo(\"XBOX\");\n\n// Función que recibe más de un parametro\nfunction edad(a, b) {\n    console.log(a * b);\n}\nedad(6, 29);\n\n//Funcion que recibe parametros pero con parametros por defecto\nfunction persona(nombre = \"Nombre desconocido\", apellido = \"Apellido desconocido\", edad = 0) {\n    console.log(`Mi nombre completo es ${nombre} ${apellido} y tengo ${edad} años de edad`);\n}\n\npersona(\"Daniel\", \"Martinez\", 27);\npersona();\n\n//Closures o Funciones anidadas\nfunction miFuncion() {\n    let contador = 0;\n\n    function incrementar() {\n        contador++;\n        return contador;\n    }\n\n    return incrementar;\n}\n\nconst incremento = miFuncion();\n\nconsole.log(incremento()); // 1\nconsole.log(incremento()); // 2\n\n\n//Funciones anidadas\nconst formula1 = function () {\n    let equipo = \"RedBull\";\n\n    function escuderia(equipo, motor) {\n        console.log(`La escudería ${equipo} utiliza motores ${motor}`);\n\n        function piloto(equipo, nombre, edad) {\n            console.log(`La escuderia ${equipo}, cuenta con el piloto ${nombre} el cual tiene la edad de ${edad}`)\n        }\n        piloto(equipo, \"Sergio Perez\", 38);\n    }\n    escuderia(equipo, \"mercedes\");\n}\nformula1();\n\n// Funciones existentes\nlet piloto = \"Lewis Hamilton\";\nconsole.log(piloto.substring(6, undefined));\n// console.log(piloto.substring(6,9));\n\n// Variable Global\nlet team = \"Liverpool\";\n\nfunction futbol() {\n    console.log(`Hola ${team}`);\n}\nfutbol();\nconsole.log(team);\n\n// Variable Local\nlet escuderia = \"Mclaren\";\n\nfunction escuderiaF1() {\n    let piloto = \"Lando Norris\";\n    console.log(`${piloto} corre para la escudería ${escuderia}`);\n}\nescuderiaF1();\nconsole.log(escuderia); //Si se puede imprimir porque es una variable global\nconsole.log(piloto); //No es posible acceder a la variable piloto porque es una variable local de la función\n\n\n// DIFUCULTAD EXRA\nfunction numeros(palabrauno, palabrados) {\n    let contador = 0;\n    for (let i = 1; i <= 100; i++) {\n        if (i % 3 == 0 && i % 5 == 0) {\n            console.log(palabrauno + \" \" + palabrados);\n        } else if (i % 5 == 0) {\n            console.log(palabrados);\n        } else if (i % 3 == 0) {\n            console.log(palabrauno);\n        } else {\n            console.log(i);\n            contador++;\n        }\n    }\n    console.log(`Las condiciones NO se cumplieron ${contador} veces`);;\n}\nnumeros(\"hola\", \"adios\");"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/DavidMoralesDeveloper.js",
    "content": "//1 - Crea ejemplos de funciones básicas que representen las diferentes posibilidades del lenguaje:\n\n// funsion simple -------------------------------\n    // Autoejecutable\n(function () {\n    console.log(\"Autoejecutable\");\n  })();\n    //declarativa\nfunction hello (){\n    console.log('hello word , funcion declarativa')\n}\n\n\n    //  Expresión (anónimas)\nconst sumFunction = function (a, b){\n    return a+ b\n}\n\n\n\n    // Flecha (arrow)\nconst arrowFunction = (a, b) => {\n    return a * b\n} \n\n\n// con retorno ------------------------------------\n\nfunction square(number) {\n    return number * number;\n  }\n//   este return puedo grardarlo en una variable\nlet area =  square(4)\n\n\n// con argumento  -----------------------------------\nfunction nombre (nombre)  {\n    console.log('mi nombre es ' + nombre)\n}\n\n\n\nfunction idioma (idioma, nombre)  {\n    console.log(idioma + nombre)\n}\n\n\n\n// argumento default \n\nfunction defaultsuma (a =5, b = 2 ){\n    return a*b\n}\n\n\n\n//Callbacks\nvar funB = function () {\n    return console.log('Funcion B ejecutada');\n  };\n  var funA = function (callback) {\n    callback();\n  };\n\n\n//2 - Comprueba si puedes crear funciones dentro de funciones.\n    //Sucesión de Fibonacci complegidad 2^n\n\nfunction fibonacci (num) {\n    if(num < 2) return num\n    //funciona en 0 y 1 retorna  num , cuando el numero es mayor , va retrocediendo hasta llegar al 1al llegar al 1 entra en el if y es por eso que se puede parar la recursividad\n    \nreturn fibonacci(num-2) + fibonacci(num-1)\n}\n\nconsole.log(fibonacci(10))\n\n//3- Pon a prueba el concepto de variable LOCAL y GLOBAL.\n// no esoty seguro si es lo que pide...\n// \"String.split()String.substring()String.trim()Array.map()Array.push()Array.pop()String.slice()Array.slice()Object.toString()Number.toFixed()parseInt()Math.random()console.log()\" \n\n//4 - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n\nconst varGlobal = 10\nfunction sumLocalGlobal (num){\n    const local = num\n    return local + varGlobal\n}\n\nconsole.log(sumLocalGlobal(5))\n\n// - Debes hacer print por consola del resultado de todos los ejemplos.\nhello()\nconsole.log('funcion expersión anónimas : '+ sumFunction( 5, 2))\nconsole.log('funcion de flecha : ' + arrowFunction( 8, 3))\nconsole.log(area)\nnombre('David')\nidioma('hi', 'david')\nidioma('hola', 'david')\nconsole.log(defaultsuma())\nconsole.log(defaultsuma(20 , 10))\nfunA(funB);\n\n\n// DIFICULTAD EXTRA (opcional):\n// * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n// * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n// *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n// *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n// *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n// *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\n// primer intento no funciona \n// function extra (cadena1, cadena2){\n//     let contador = 0\n// for(let i = 1; i <= 100; i++){\n//    if (i % 3 != 0){\n//       console.log(cadena1)\n//    }\n//    if (i % 5 != 0){\n//       console.log(cadena2)\n//    }\n//    if(i%3 != 0 && i%5 !=0){\n//      console.log(cadena1 + cadena2)\n//    }else\n//    contador ++\n//    console.log(i)\n// }\n// return contador\n// }\n\n// console.log(extra('dmultiplo3', 'dmultiplo de 5'))\n\n//correcion\nfunction correccionExtra ( multiplo, multiplo2){\nlet contador = 0\nfor (let i = 1; i <= 100; i++){\n    if (i % 3 === 0 && i % 5 === 0){\n        console.log(  ` es ${multiplo} y ${multiplo2}`)\n    }else if(i % 5 === 0){\n        console.log(multiplo2)\n    }else if(i % 3 === 0){\n        console.log(multiplo)\n    }\n    contador ++\n    console.log(i)\n} return contador\n}\n\nconsole.log(correccionExtra('multiplo de 3', 'multiplo de 5'))\n// correcion de coomit\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/DerlingR.js",
    "content": "function bienvenida() {\n    console.log(\"Bienvenidos al ejercicio 02 de Lógica de Programación\");\n}\n\nbienvenida();\n\nfunction bienvenida2(especificacion) {\n    console.log(\"Bienvenido al ejercicio 02 de Lógica de Programación, \" + especificacion);\n}\n\nbienvenida2(\"Curso 02\"); // Bienvenido al ejercicio 02 de Lógica de Programación, Curso 02\n\nfunction sumar(a, b) {\n    console.log(a +b);\n}\n\nsumar(5, 3); // El resultado será 8\n\nfunction multiplicar(a, b) {\n    return a * b;\n}\n\nlet resultado = multiplicar(4, 7);\nconsole.log(resultado); // El resultado será 28\n\nfunction operacion(a, b) {\n    function sumar(x, y) {\n        return x + y;\n    }\n    function restar(x, y) {\n        return x - y;\n    }\n\n    console.log(\"sumar:\", sumar(a, b));\n    console.log(\"restar:\", restar(a, b));\n}\n\noperacion(10, 5);\n//Muestra lo siguiente:\n// sumar: 15\n// restar: 5\n\nlet texto = \"Javascript es un lenguaje de programación\";\nlet longitud = texto.length;\nconsole.log(\"Longitud del texto:\", longitud); // Longitud del texto: 39\n\nlet numero = 9.5678\nlet numeroRedondeado = Math.round(numero);\nconsole.log(\"Número redondeado:\", numeroRedondeado); // Número redondeado: 10\n\nlet global = \"Variable global\";\n\nfunction mostrarVariable() {\n    let local = \"Es una variable local\";\n    console.log(global); //Para acceder a la variable global\n    console.log(local); //Para acceder a la variable local\n}\n\nmostrarVariable();\n//Muestra:\n//Par acceder a la variable global\n//Es una variable local\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/Deyvid-10.js",
    "content": "// funciones básicas\nfunction noRetotnoNiParametro()\n{\n    console.log(\"Esta funcion no tiene parámetros ni retorna nada\")\n}\n\nnoRetotnoNiParametro()\n\nfunction conParemetros(parametro, parametro2)\n{\n    console.log(\"Esta funcion tiene el parametro \", parametro, \" y este es otro parametro \", parametro2);\n}\n\nconParemetros(\"parametro no. 1\", \"parametro no. 2\")\n\nfunction conRetorno()\n{\n    return \"Esta funcion retorna este mensaje\"\n}\n\nconsole.log(conRetorno());\n\n// funcion dentro de funcion\nfunction padre()\n{\n    function hijo()\n    {\n        console.log(\"Esta funcion esta dentro de otra funcion\");\n    }\n    hijo()\n}\n\npadre()\n\n// Funciones ya creadas\n\nlet texto = \"One Piece\"\nlet decimal = 5.5555\nconsole.log(decimal.toFixed(2));\nconsole.log(Math.random());\nconsole.log(texto.split(\" \"));\n\n// variable LOCAL y GLOBAL\nfunction local()\n{\n    let varLocal = \"Esta variable solo se puede usar dentro de esta funcion\"\n    console.log(varLocal);\n}\n\nlocal()\n\nlet varGlobal \nfunction global()\n{\n    varGlobal = \"Esta variable se puede usar en cualquier parte del codigo\"\n}\n\nglobal()\nconsole.log(varGlobal);\n\n// DIFICULTAD EXTRA\nfunction extra(texto, texto2)\n{\n    let contador = 0\n\n    for(let i=1; i<=20; i++)\n    {\n        if(i%3 == 0 && i%5 == 0)\n        {\n            console.log(texto + \" y \"+ texto2);\n        }\n        else if (i%3 == 0) \n        {\n            console.log(texto);\n        }\n        else if(i%5 == 0)\n        {\n            console.log(texto2);\n        }\n        else\n        {\n            console.log(i);\n            contador++\n        }\n    }\n    return contador\n}\n\nlet funcionExtra = extra(\"Los gatos son felinos\", \"Los perros son caninos\")\n\nconsole.log(\"La funcion retorna: \", funcionExtra);"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/DjSurgeon.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\nconsole.log('== Funciones en Javascript ==');\n\nconsole.log('== Funciones sin parámetros ni retorno ==');\n\nfunction functionSinParametros() {\n  console.log(\"Esta es una función que no recibe parámetros.\");\n  console.log(\"Y que no retorna ningun valor especifico.\");\n}\nfunctionSinParametros();\n\nconsole.log('== Funciones sin parámetros con retorno ==');\n\nfunction functionConRetorno() {\n  console.log('Esta función retorna el valor del número PI.');\n  return Math.PI;\n}\nconsole.log(functionConRetorno());\n\nconsole.log('== Funciones con parámetros ==');\n\nfunction functionConString(string){\n  console.log('Esta función coge una string como parámetro.');\n  console.log(`Este es el parametro introducido: ${string}.`);\n}\nfunctionConString('Programación');\nfunction functionConNumeros(num1, num2){\n  console.log(`Esta función recoge dos parámetros: ${num1} y ${num2} y los suma.`)\n  return num1 + num2;\n}\nconsole.log(functionConNumeros(2,5));\n\nfunction functionConStringYNumeros(string, num1, num2) {\n  console.log(\"Establece un string con la operación y dos numeros:\")\n  if (string === 'suma') {\n    console.log(`Suma de ${num1} y ${num2}:`);\n    return num1 + num2;\n  }\n  else if (string === 'resta') {\n    console.log(`Resta de ${num1} y ${num2}:`);\n    return num1 - num2;\n  }\n  else if (string === 'multiplicacion') {\n    console.log(`Multiplicación de ${num1} y ${num2}:`)\n    return num1 * num2;\n  }\n}\n\nconsole.log(functionConStringYNumeros('suma', 8, 5));\nconsole.log(functionConStringYNumeros('resta', 10, 3));\nconsole.log(functionConStringYNumeros('multiplicacion', 2, 3));\n\nconsole.log('== Funciones dentro de funciones ==');\n\nfunction suma(num1, num2) {\n  return num1 + num2;\n}\n\nfunction sumaDosNumeros(suma, num1, num2){ // En este caso utilizamos una función como argumento.\n  return suma(num1, num2);\n}\n\nconsole.log(sumaDosNumeros(suma, 2, 6));\n\nfunction restaDosNumeros(num1, num2) { // En este caso creamos una función dentro de la otra función.\n  function resta() {\n    return num1 - num2;\n  }\n  return resta();\n}\n\nconsole.log(restaDosNumeros(10, 5));\n\n\nconsole.log('== Funciones del sistema ==');\n\nlet str = \"Esta es una string de ejemplo.\";\nconsole.log(str);\nconsole.log(str.toUpperCase());\n\nconsole.log('== Variables locales y globales ==');\n\nfunction showMessage() {\n  let message = \"¡Hola Javascript!\"\n  return message;\n}\nconsole.log(showMessage());\n// console.log(message); no podemos acceder a una variable declarada dentro de la función.\n\nlet name = 'Surgeon'\n\nfunction showName() {\n  console.log(`Variable ${name} declarada de forma global.`)\n}\nshowName();\nfunction showName2(){\n  name = \"DJ\";\n  console.log(`Cambiamos la variable ${name} dentro de la función.`);\n}\nshowName2();\nconsole.log(name);\nfunction showName3(){\n  let name = 'Regis';\n  console.log(`Establecemos una variable local: ${name}.`);\n}\nshowName3();\nconsole.log(name);\n\nconsole.log('== Dificultad Extra ==');\n\nfunction dificultadExtra(str1, str2) {\n  let count = 0;\n  for (let i = 1; i <= 100; i++) {\n    if(i % 3 === 0 && i % 5 === 0) {\n      console.log(str1 + \" \" + str2);\n    }\n    else if(i % 3 === 0) {\n      console.log(str1);\n    }\n    else if( i % 5 === 0 ) {\n      console.log(str2);\n    } \n    else {\n      count++\n      console.log(i);\n    }\n  }\n  return count;\n}\n\nconsole.log(dificultadExtra('Hola', 'Mundo'));\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/DobleDJ.js",
    "content": "/**\n * Reto de programación - #03 - JavaScript\n * Autor: Yoandy Doble Herrera\n * Fecha: 06/12/2024\n */\n\n/** Ejercicio 1 */\n\n//Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n\n/**\n * Función void\n */\nfunction newUser() {\n  //función clásica sin parámetros\n  //cuerpo de la función\n  console.log(`Roadmap #02 - JavaScript`)\n}\nnewUser()\n\n// Funciones anónimas\n\nconst funcJS = function (attr) {\n  console.log(`¡Ejemplo de función anónima, ${attr}!`)\n}\n\nfuncJS(\"codebydoble\")\n\n/**\n * Función void declarativa sin parámetros\n */\nconst newUser2 = () => {\n  //cuerpo de la función\n  console.log(`Esta función no retorna nada`)\n}\nnewUser2()\n\n/**\n * Función void anónima sin parámetros\n */\nconst sayHello = function () {\n  console.log(\"Hello JavaScript, goodbye!\")\n}\nsayHello()\n\n/**\n * Función que recibe un parámetro string y modifica parámetros\n * @param {String} username\n */\nconst createTicket = (username) => {\n  console.log(\"Welcome,\", username + \"!\")\n}\ncreateTicket(\"Endry\")\n\n/**\n * Función con dos parámetros y retorno. Recibe dos números y devuelve la exponenciación\n * @param {number} numer1 Any number\n * @param {number} numero2 Any number\n * @returns Retorna la exponenciación del número\n */\nconst exponenteNumeros = (numero1, numero2) => {\n  let resultado = 0 //Variable local\n  resultado = numero1 ** numero2\n  return resultado\n}\nlet exponente = exponenteNumeros(3, 2)\nconsole.log(exponente)\n\n/** Ejercicio 2 funciones anidadas una dentro de otra*/\n/**\n * Halla la raíz cuadrada de un número\n * @param {number} value Any number\n * @returns Retorna la raíz cuadrada de un número\n */\nconst elevarFunc = (value) => {\n  return Math.sqrt(value)\n}\n\n/**\n * Multiplica la raíz cuadrada de números\n * @param {number} value1 Any number\n * @param {number} value2 Any number\n * @returns Retorna la multiplicación de la raíz cuadrada de dos números\n */\nconst multiplicarNumeros = (value1, value2) => {\n  return elevarFunc(value1) * elevarFunc(value2)\n}\n\nconsole.log(\"La raíz cuadrada de dos números multiplicados es: \", multiplicarNumeros(8, 54))\n\n//Funciones de orden superior\nlet estacionesAnio = [\"Primavera\", \"Verano\", \"Otoño\", \"Invierno\"]\n\nconst printSeasons = (arraySeason) => {\n  for (let index = 0; index < arraySeason.length; index++) {\n    console.log(\"Estación #\" + (index + 1), arraySeason[index])\n  }\n}\n\nfunction seasons(func, parametros) {\n  func(parametros)\n}\n\nseasons(printSeasons, estacionesAnio)\n\n/**Ejemplo función de javaScript Factorial recursividad*/\nfunction factorial(n) {\n  if (n === 0 || n === 1) return 1\n  else return n * factorial(n - 1)\n}\n\n//Ejemplo variable local mostrará error su scope es local\n/**\n * console.log(resultado)\n */\nconst piElemento = 3.14 //variable global\nconsole.log(piElemento)\n\n/**Ejercicio EXTRA */\n\n/**\n * Función que recibe dos parámetros de tipo cadena de texto y retorne un número\n * @param {string} cadena1 Cualquier cadena de texto\n * @param {string} cadena2 Cualquier cadena de texto\n * @returns Retorna el número de veces que se ha impreso el número en lugar de los textos\n */\nlet multiplos = (cadena1, cadena2) => {\n  let contador = 0\n  for (let index = 0; index < 100; index++) {\n    if ((index + 1) % 3 === 0 && (index + 1) % 5 === 0) {\n      // multiplo de 3 y 5\n      console.log(`El número ${index + 1} es ${cadena1} y  ${cadena2}`)\n    } else if ((index + 1) % 3 === 0) {\n      //multiplo de 3\n      console.log(`El número ${index + 1} es ${cadena1}`)\n    } else if ((index + 1) % 5 === 0) {\n      //multiplo de 3\n      console.log(`El número ${index + 1} es ${cadena2}`)\n    } else {\n      console.log(\"Numero: \", index + 1)\n      contador++\n    }\n  }\n  return contador\n}\n\nconsole.log(\"Se han mostrado los números: \", multiplos(\"Multiplo de 3\", \"Multiplo de 5\"), \"veces\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/DouglasDiazR.js",
    "content": "/*\n//Sin Parámetro Ni Retorno \nfunction saludar() {\n    console.log(\"¡Hola, mundo!\");\n}\nsaludar();\n\n//Con un Parámetro y Retorno\nfunction saludar(saludo) {\nreturn saludo;\n}\nconsole.log(saludar('¡Hola, Mundo!'));\n\n//Con 2 Parámetros y Retorno\nfunction sumar(a, b) {\n    return a + b;\n}\nconsole.log(sumar(5, 3));\n\n//Sin Parámetros, con Retorno\nfunction obtenerFechaActual() {\n    return new Date();\n}\nconsole.log(obtenerFechaActual());\n\n//Por Expresión\nconst saludo = function holaMunda(saludo){\n    return console.log('¡Hola Mundo!');\n}\nsaludo();\n\n//Anónima \nconst anonima = function (){\n    return console.log('Anónima');\n}\nanonima();\n\n//Función Flecha \nvar multiplicar = (a,b) => a * b;\nconsole.log(multiplicar(5,6));\n\n//Función dentro de otra Función \nfunction cadenaSaludo(){\n    function primeraCadena(){\n        return '¡Hola ';\n    }\n    function segundaCadena(){\n        return 'Mundo!';\n    }\n    console.log(primeraCadena() + segundaCadena());\n}\ncadenaSaludo();\n\n//Funciones Predefinidas \nvar numeroAleatorio = Math.random();\nconsole.log(numeroAleatorio);\n\n//Variables Locales \nfunction suma(a, b) {\n    let resultado = a + b; // \"resultado\" es una variable local a la función suma\n    return resultado;\n}\n\nconsole.log(suma(5, 3));\nconsole.log(resultado); // Generará un error, ya que \"resultado\" no está definido fuera de la función suma\n\n//Variables Globales \nvar variableGlobal = 10; // \"globalVariable\" es una variable global\n\nfunction multiplicarPorGlobal(num) {\n    return num * variableGlobal;\n}\n\nconsole.log(multiplicarPorGlobal(5)); // Devuelve 50\nconsole.log(variableGlobal); // Devuelve 10\n*/\n\n\n/*DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n * */\n\nconst numerosDelunoAlcien = (string1, string2) =>{\n    let contador = 0;\n    for(var i = 1; i <= 100; i++){\n        if( i % 3 === 0 && i % 5 === 0){\n            console.log(`${string1} y ${string2}`);\n        }\n        else if(i % 5 === 0){\n            console.log(string2);\n        }\n        else if (i % 3 === 0){\n            console.log(string1);\n        }\n        else{\n            contador ++;\n            console.log(i);\n        }\n    }\n    return contador;    \n}\nconsole.log(`Los numeros se han impreso un total de ${numerosDelunoAlcien('Multiplo de 3','Multiplo de 5')} veces.` );\n    \n\n\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/EloyParga.js",
    "content": "// FUNCIONES BÁSICAS EN JAVASCRIPT\n\n// 1. Funcion sin parametros ni retorno\nfunction saludoSimple(){\n    console.log(\"Hola, JS\");\n}\n\n\n// 2. Función con un parametro\nfunction saludarNombre(nombre) {\n    console.log(`Hola ${nombre}, buenos días`);\n}\n\n\n// 3. Función con varios parametros\nfunction sumar (a , b){\n    console.log(`La suma de ${a} + ${b} = ${a+b}`);\n}\n\n\n/** 4. Función con @return */\nfunction restar (a , b){\n    return a-b;\n}\nlet resultado = restar(10,5);\nconsole.log(`El resultado de 10 - 5 = ${resultado}`);\n\n\n// 5. Función dentro de otra función\nfunction calculadora(a , b){\n    function multiplicar (x , y) {\n        return x * y;\n    }\n    const suma = a+b;\n    const multiplicacion = multiplicar(a, b); // llamada a la subfuncion\n    console.log(`Suma : ${suma} , Multiplicación : ${multiplicacion}`);\n}\ncalculadora(10,5);\n\n\n// 6. Funciones prefinidas\nlet numeros = [1,2,3,4,5,];\nconsole.log(\"Lista de numeros: \", numeros);\nlet numerosCuadrados =numeros.map((n) => n**2);\nconsole.log(\"Numeros Cuadradosa \", numerosCuadrados);\n\n\n//VARIABLES LOCALES Y GLOBALES\nlet variableGlobal = \"Soy una variable global\";\n\nfunction alcance(){\n    let variableLocal = \"Soy una variable Local\";\n    console.log(\"VARIABLE: \", variableLocal);\n    console.log(\"VARIABLE: \", variableGlobal);\n}\nalcance();\n/** Esto da error : Porque @param variableLocal \n *  no existe fuera del @method alcance() \n */\n// console.log(variableLocal);\n\n\n// DIFICULTAD EXTRA : FUNCION MULTIPLOS\n\nfunction fizzBuzz(fizz , buzz) {\n    let cont = 0; // Contador que evalua cuantas veces se imprime números en vez de texto\n\n    for (let i = 1; i<=100 ; i++){\n        if (i % 3 === 0 && i % 5 === 0) {\n            console.log(fizz,buzz); //Multiplo 3 y 5\n        }else if(i % 3 === 0){\n            console.log(fizz,)      //Multiplo 3\n        }else if (i % 5 === 0) {\n            console.log(buzz);      //Multiplo 5\n        }else{\n            console.log(i);         //No multiplo\n            cont++; // Incrementa el contador\n        }\n    }\n\n    return cont; //Retorna el total de numeros impresos\n}\n\nconst impresos = fizzBuzz(\"Fizz\", \"Buzz\");\nconsole.log(`Total de numeros impresos en lugar de Texto ${impresos}`);\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/EricJoel-code.js",
    "content": "// Funciones\n\n// Función sin parámetros y sin retorno\n\nfunction sinParametros() {\n    console.log(\"Esta es una funcion sin parámetros y sin retorno\")\n}\nsinParametros();\n\n// Funición con un parámetro y sin retorno\n\nfunction conUnParametro(parametro) {\n    console.log(`Esta es una función con un parámetro y sin retorno, el parámetro es: ${parametro}`)\n}\nconUnParametro(\"Hola Mundo\");\n\n// Función con multiples parámetros y sin retorno\n\nfunction conMultiplesParametros(param1, param2, param3) {\n    console.log(`Esta es una función con múltiples parámetros y sin retorno, los parámetros son: ${param1}, ${param2}, ${param3}`)\n}\nconMultiplesParametros(\"Hola\", \"Mundo\", \"!\");\n\n// Función sin parámetros y con retorno\n\nfunction sinParametrosConRetrono() {\n    return \"Esta es una función sin parámetros y con retorno\"\n}\nconsole.log(sinParametrosConRetrono());\n\n// Función con un parámetro y con retorno\n\nfunction conUnParametroConRetornoo(parametro) {\n    return `Esta es una función con un parámetro y con retorno, el parámetro es: ${parametro}`\n}\nconsole.log(conUnParametroConRetornoo(10));\n\n// Función con múltiples parámetros y con retorno\n\nfunction conMultiplesParametrosConRetrono(param1, param2) {\n    return param1 + param2\n}\nconsole.log(conMultiplesParametrosConRetrono(10, 20));\n\n// Función dentro de otra función\n\nfunction funcionPrincipal() {\n    console.log(\"Esta es la función principal\");\n\n    function funcionAnidada() {\n        console.log(\"Esta es la función anidada\");\n    }\n    funcionAnidada();\n}\n\nfuncionPrincipal();\n\n// Funciones ya creacdas en el lenguaje\n\n// Función para convertir un string a mayúsculas\n\nfunction convertirAMayusculas(texto) {\n    return texto.toUpperCase();\n}\nconsole.log(convertirAMayusculas(\"hola mundo\"));\n\n// Función para convertir un string a minúsculas\n\nfunction convertirAMinusculas(texto) {\n    return texto.toLowerCase();\n}\n\nconsole.log(convertirAMinusculas(\"HOLA MUNDO\"));\n\n// Función para redondear un numero\n\nfunction redondearNumero(numero) {\n    return Math.round(numero);\n}\n\nconsole.log(redondearNumero(3.6));\n\n// Funcion para gernerar un numero aleatorio entre 0 y 1\n\nfunction generarNuemeroAleatorio() {\n    return Math.random();\n}\n\nconsole.log(generarNuemeroAleatorio());\n\n// Función para obtener la longitud de un string\n\nfunction obtenerLonitudString(texto) {\n    return texto.length;\n}\n\nconsole.log(obtenerLonitudString(\"Hola Mundo\"));\n\n// Función para obtener el valor absoluto de un numero \n\nfunction valorAbsoluto(numero) {\n    return Math.abs(numero);\n}\n\nconsole.log(valorAbsoluto(-5));\n\n// Función para obtener el valor máximo entre dos numeros\n\nfunction valorMaximo(num1, num2) {\n    return Math.max(num1, num2);\n}\n\nconsole.log(valorMaximo(10, 20))\n\n// Variable global\n\nlet varGlobal = 13\n\nfunction sumar() {\n    console.log(\"El resultado de la suma es:\", varGlobal + 10)\n}\nsumar()\n\n// Variable local\n\nfunction resta() {\n    let varLocal = 26\n    console.log(\"El resultado de la resta es:\", varLocal - varGlobal)\n}\n\nresta()\n\n//Extra \n\nfunction ejercicio(text1, text2) {\n\n    let count = 0;\n\n    for (i = 1; i <= 100; i++) {\n        if (i % 3 === 0 && i % 5 === 0) {\n            console.log(`${text1}${text2}`)\n        } else if (i % 5 === 0) {\n            console.log(text2)\n        } else if (i % 3 === 0) {\n            console.log(text1)\n        } else {\n            console.log(i)\n        }\n        count++\n    }\n    return count\n}\nejercicio(\"Team\", \"Seal\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/Erysnell.js",
    "content": "// Función sin parámetros ni retorno\nfunction sinParametros() {\n    console.log(\"Esta función no tiene parámetros ni devuelve nada\");\n}\n\n// Función con un parámetro y sin retorno\nfunction conUnPar(parametro) {\n    const nombre = \"Juan\";\n    console.log(`Hola, ${nombre}`);\n}\n\n// Función con múltiples parámetros y sin retorno\nfunction conMultiplesParams(a, b, c) {\n    console.log(`Recibí: ${a}, ${b}, ${c}`);\n}\n\n// Función con parámetros y retorno\nfunction suma(a, b) {\n    return a + b;\n}\n\n// Función anidada\nfunction funcionAnidata() {\n    function subFuncion() {\n        console.log(\"Soy una función anidada\");\n    }\n    console.log(\"Estoy en la función principal\");\n    subFuncion();\n}\n\n\nlet globalVar = \"Esta es una variable global\";\n\n// Función que usa la variable global\nfunction usarVariableGlobal() {\n    globalVar += \" modificada\";\n    console.log(globalVar);\n}\n\nsinParametros();\nconUnPar(\"Carlos\");\nconMultiplesParams(1, 2, 3);\nconsole.log(suma(5, 7));\nfuncionAnidata();\nusarVariableGlobal();\n\n\nconst localVar = \"Esta es una variable local\";\n\n// Función que usa la variable local\nfunction usarVariableLocal() {\n    console.log(localVar);\n}\nusarVariableLocal(); // Esto causaría un error porque localVar está fuera del alcance\n\n\n// Ejercicio Extra\nfunction imprimirMultiplos(texto1, texto2) {\n    let contador = 0;\n    \n    for (let i = 1; i <= 100; i++) {\n        if (i % 3 === 0 && i % 5 !== 0) {\n            console.log(texto1);\n        } else if (i % 5 === 0 && i % 3 !== 0) {\n            console.log(texto2);\n        } else if (i % 3 === 0 && i % 5 === 0) {\n            console.log(`${texto1}${texto2}`);\n        } else {\n            console.log(i);\n        }\n        \n        contador++;\n    }\n    \n    return contador;\n}\n\nconst resultado = imprimirMultiplos(\"Tres\", \"Cinco\");\nconsole.log(`\\nSe imprimieron ${resultado} números.`);\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/FabianRpv.js",
    "content": "// Funciones y alcance\n\n\nfunction saludar() {   // Funcion sin parametros ni retorno\n    console.log('Hola, Soy Fabian Petit');\n}\n\nsaludar();\n\n\n\nfunction saludar2(nombre, apellido) {   // Funcion con parametros\n    console.log(`Hola, Soy ${nombre} ${apellido}`);\n}\n\nlet nombre = 'Fabian';\nlet apellido = 'Petit';\n\nsaludar2(nombre, apellido);\n\n\n\nfunction saludar3(nombre, apellido) {   // Funcion con parametros y retorno\n    return `Hola, Soy ${nombre} ${apellido}`;\n}\n\nconsole.log(saludar3(nombre, apellido));\n\n\n\nconst functionAnom = function() {  // Funcion anonima\n    console.log('Hola, Soy Fabian Petit');\n}\n\nfunctionAnom();  \n\n\n\nconst functionArrow = (nombre, apellido) => console.log(`Hola, Soy ${nombre} ${apellido}`) // Funcion arrow\n\nfunctionArrow(nombre, apellido);\n\n\n\nfunction saludar4(nombre, apellido, saludo = \"Hola\") {  // Funcion con parametros por defecto\n    console.log(`${saludo}, Soy ${nombre} ${apellido}`);\n}\n\nsaludar4(nombre, apellido);\nsaludar4(nombre, apellido, \"Buenos dias\");\n\n\n\n// Funcion dentro de otra funcion\n\nfunction saludar5(nombre, apellido) {\n\n    function getNombreCompleto() {\n        return `${nombre} ${apellido}`;\n    }\n\n    console.log(`Hola, Soy ${getNombreCompleto()}`);\n}\n\nsaludar5(nombre, apellido);\n\n\nfunction saludar6(myFunction, parametro1, parametro2){\n    myFunction(parametro1, parametro2);\n}\n\nsaludar6(saludar5, 'Fabian', 'Petit');\n\n\n\n// Funciones ya definidas en el lenguaje\n\nlet numero = 10.456789;\nconsole.log(numero.toFixed(2));\n\n\n\n// Variables locales y globales\n\nlet variableGlobal = 'Soy una variable global';\n\nfunction mostrarVariables(){\n    let variableLocal = 'Soy una variable local';\n    console.log(variableGlobal);\n    console.log(variableLocal);\n}\n\nmostrarVariables();\n\nconsole.log(variableGlobal);\n// console.log(variableLocal);  // Error\n\n\n\n/* Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n- La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n- Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n- Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n- Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n- La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n*/\n\nfunction imprimir(text1, text2){\n\n    let contador = 0;\n\n    for(let i = 1; i <= 100; i++){\n\n\n        if (i % 3 == 0 && i % 5 == 0){\n            console.log(`${text1} ${text2}`);\n        }\n\n        else if(i % 3 == 0){\n            console.log(text1);\n        }\n\n        else if (i % 5 == 0){\n            console.log(text2);\n        }\n\n        else {\n            console.log(i);\n            contador++;\n        }\n\n    }\n\n    return `El numero de veces que se imprimio un numero fue de ${contador}`;\n\n}\n\nconsole.log(imprimir('Hola', 'Mundo'));"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/Facundo-Muoio.js",
    "content": "// funcionsin parametros\nfunction noParams() {\n\treturn console.log(\"funcion sin parametros\");\n}\nnoParams();\n\n// funcion con un parametro y sin retorno\nfunction sayHello(nombre) {\n\tconsole.log(`Hola ${nombre}`);\n}\nsayHello(\"Facundo\");\n\n// funcion con varios parametros y con parametros predeterminados\nfunction sum(a = 5, b = 5) {\n\treturn a + b;\n}\nconsole.log(sum(), sum(20, 50));\n\n// funcion con rest params\nfunction sumAllNumbers(a, b, ...c) {\n\tlet sum = a + b;\n\tc.map(number => (sum += number));\n\treturn sum;\n}\nconsole.log(sumAllNumbers(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));\n\n// funcion dentro de otra funcion\nfunction outer() {\n\tconsole.log(\"esta es una funcion que a su vez crea una funcion interna\");\n\tfunction inner() {\n\t\tconsole.log(\"esta es la funcion interna creada dentro de la funcion outer\");\n\t}\n\tinner();\n}\nouter();\n\n// callback funcion\nfunction hello(name) {\n\treturn console.log(\"Hola \" + name);\n}\n\nfunction processInputUser(callback) {\n\tvar name = prompt(\"Por favor ingresa tu nombre.\");\n\tcallback(name);\n}\n\nprocessInputUser(hello);\n\n// Declaracion de funciones\nfunction unaFuncion() {\n\treturn console.log(\"Esto es una declaracion de una funcion\");\n}\nunaFuncion();\n\n// Expresion de una funcion\nconst otraFuncion = function () {\n\treturn console.log(\"Esto es una expresion dee una funcion \");\n};\notraFuncion();\n\n// Funcion anonima\nconst anonima = function () {\n\tconsole.log(\"Esto es una funcion anonima\");\n};\nanonima();\n\n// Funcion flecha\nconst arrowFunction = () =>\n\t\"Soy una funcin flecha y no posee this entre otras diferencias con las funciones tradicionales\";\nconsole.log(arrowFunction());\n\n// Expresion de funcion incovada inmediatamente IIFE\n(function () {\n\treturn console.log(\"Soy una Expresión de función invocada inmediatamente\");\n})();\n\nlet globalLet = \"soy una variable global\";\nfunction printVariables() {\n\tlet localLet = \"soy una varable local\";\n\treturn console.log(globalLet, localLet);\n}\n\n//imprime ambas variables tanto la global como la local\nprintVariables();\nconsole.log(globalLet);\n// el siguiente console.log tendra un reference error, ya que la localLet variable no existe en su scope, esto es así porque carece de acceso al ambito de la variable de la funcion printVariables, esta funcion tiene un estado privado con respecto al entorno que engloba. Por lo cual no existe esta variable en el ambito global.\nconsole.log(localLet);\n\n//funciones ya creadas en el lenguaje\nconst arr = [1, 2, 3, 4, 5];\n\n//itera sobere todos los elemntos del arreglo y devuelve un nuevo arreglo con sus elementos multiplicados x 2\nconsole.log(arr.map(number => number * 2));\n//Devuelve un nuevo arreglo con todos los elementos mayores a 2\nconsole.log(arr.filter(number => number > 2));\n//Devuelve el primer elemento del arreglo que satisfaga la callback function que pasamos como argumento\nconsole.log(arr.find(number => number === 3));\n//Devuelve la suma de todos los elemntos del arreglo\nconsole.log(arr.reduce((cv, acc) => (acc += cv)));\n\n//funcion extra\nfunction extraPoint(str1, str2) {\n\tlet acumulador = 0;\n\tfor (let i = 1; i <= 100; i++) {\n\t\ti % 3 === 0 && i % 5 === 0\n\t\t\t? console.log(str1 + str2)\n\t\t\t: i % 3 === 0\n\t\t\t? console.log(str1)\n\t\t\t: i % 5 === 0\n\t\t\t? console.log(str2)\n\t\t\t: (console.log(i), acumulador++);\n\t}\n\treturn acumulador;\n}\n\nconsole.log(extraPoint(\"uno\", \"dos\"));\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/Glitzypanic.js",
    "content": "// FUNCIONES Y ALCANCE\n() => {}; // Función anónima\n(a, b) => {}; // Función anónima con parámetros\n(a, b) => {\n  return a + b;\n}; // Función anónima con parámetros y retorno\n\nvar num1 = 10;\nvar num2 = 6;\n\nfunction suma() {\n  return num1 + num2;\n} // Función que suma dos números\nconsole.log(suma());\n\nfunction ejemplo() {\n  return suma();\n} // Función que llama a la función suma\nconsole.log(ejemplo());\n\nfunction usuario(nombre, apellido) {\n  return nombre + \" \" + apellido;\n} // Función que concatena dos strings\nconsole.log(usuario(\"Jose\", \"Farias\"));\n\nvar num7 = 10;\nvar num8 = 5;\n\nfunction multiplicacion() {\n  return num7 * num8;\n} // Función que multiplica dos números y utiliza variables globales\nconsole.log(multiplicacion());\n\nfunction variable_saludar() {\n  function saludar() {\n    console.log(\"Hola, como estas?\");\n  }\n  return saludar();\n}\nvariable_saludar(); // Función que llama a otra función\n\nfunction multiplicar() {\n  var numero4 = 4;\n  var numero5 = 5;\n  return numero4 * numero5;\n} // Función que multiplica dos números y declara dos variables locales\n\nconsole.log(multiplicar());\n\nconsole.log(typeof 2);\n\n// Ejercicio\nfunction ejercicio(num1, num2) {\n  count = 0;\n\n  for (var i = 0; i <= 100; i++) {\n    if (i % 3 === 0 && i % 5 === 0) {\n      console.log(num1 + num2);\n    } else if (i % 3 === 0) {\n      console.log(num1);\n    } else if (i % 5 === 0) {\n      console.log(num2);\n    } else {\n      console.log(i);\n      count++;\n    }\n  }\n  return count;\n}\n\nconsole.log(ejercicio(\"num1\", \"num2\"));\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/HectorIglesias.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n\nfunction funcion(){\n    console.log(\"Función sin parámetros ni retorno\")\n}\nfuncion()\n\nfunction funcion2(){\n    let variable = \"Función sin parámetros con retorno\"\n\n    return variable\n}\nconsole.log(funcion2())\n\nfunction funcion3(param1){\n    console.log(param1)\n}\nfuncion3(\"Función con un parámetro y sin retorno\")\n\nfunction funcion4(param1, param2){\n    return param1 +\" y \"+ param2\n}\nconsole.log(funcion4(\"Función con varios parámetros\", \"con retorno\"))\n\n//Función dentro de función\nfunction mother(){\n    let aux = 5\n    function child(sum){\n        return sum + 1\n    }\n    return child(aux)\n}\nconsole.log(mother())\n\n//Función ya creada en el lenguaje\nlet num_random= Math.random()\nconsole.log(num_random)\n\n//Variable LOCAL Y GLOBAL\nlet global = \"Variable global\"\n\nfunction funcion4(){\n    let local = \"Variable local\"\n\n    console.log(\"Dentro de la función puedo usar la \" +global+ \" y la \" +local)\n}\nfuncion4()\nconsole.log(\"Fuera de la función puedo seguir usando la \" +global+ \" pero si intentará usar la variable local me daría error\")\n\n//DIFICULTAD EXTRA\nfunction extra(param1, param2){\n    let cont = 0\n    for (let i=1; i<=100; i++){\n        if(i % 3== 0 && i % 5 == 0){\n            console.log(param1+param2)\n        }\n        else if (i % 3 == 0){\n           console.log(param1)\n        }\n        else if (i % 5 == 0){\n            console.log(param2)\n        }\n        else{\n            cont++\n            console.log(i)\n        }\n    }\n\n    return cont\n}\n\nconsole.log(extra(\"fizz\", \"buzz\"))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/JELozanoV.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n\n// Sin parametros ni retorno \nlet anonima = () =>\n    console.log(\"Mi funcion\");\n\nanonima()\n\n// Con uno o varios parametros variando pocision \nfunction yoSoy({ nombre, edad }) {\n    console.log(`Mi nombre es ${nombre} y tengo ${edad} años`)\n}\n\nyoSoy({ edad: 35, nombre: \"John\" });\n\n\n\n//Con retorno \nlet sumaNumeros = function (num1, num2) {\n    return num1 + num2;\n}\n\nconsole.log(`2 y 2 son ${sumaNumeros(2, 2)}`);\n\n// Funcion dentro de otra funcion \nfunction sumaYdivide(num1, num2) {\n    let resultado = num1 + num2\n    function divide(num) {\n        return resultado / num\n    }\n    return divide(2)\n}\nconsole.log(sumaYdivide(0, 100));\n\n//Funcion creada en lenguaje \nfunction sumaVarios(...num) {\n    return num.reduce((total, actual) => total + actual)\n}\nconsole.log(sumaVarios(1, 2, 3, 4, 5));\n\n//Funcion que saluda a todos \nfunction saludoATodos(...nombres){\n    for (let nombre of nombres) {\n        console.log(`Hola ${nombre}`);\n    }\n}\n\nsaludoATodos(\"John\",\"Sofia\",\"Marta\")\n\n// Variable local y global \nlet miVariable = 1 // Variable global \n\nfunction variables() {\n    let miVariable = 2 // Variable local\n    return miVariable\n}\n\nconsole.log(miVariable);\nconsole.log(variables());\n\n\n/* DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n\nfunction retornaNumero(texto1, texto2) {\n    let contador = 0;\n\n    for (let i = 1; i <= 100; i++) {\n        if (i % 3 === 0 && i % 5 === 0) {\n            console.log(i, `${texto1} y ${texto2}`);\n        }\n        else if (i % 3 === 0) {\n            console.log(i, `${texto1}`);\n        }\n        else if (i % 5 === 0) {\n            console.log(i, `${texto2}`);\n        }\n        else {\n            console.log(i);\n            contador++;\n        }\n    }\n    console.log(\"El numero de veces que se han impreso los numeros es \" + contador);\n    return \"El numero de veces que se han impreso los numeros es \" + contador;\n}\n\nretornaNumero(\"Es multiplo de 3\", \"Es multiplo de 5\");"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/Jalivur.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n/*FUNCIONES*/\n//Sin parametros:\nconsole.log(`==========`);\nconsole.log(`Funcion sin marametros:`);\nfunction parameterLess (){\n    let upshot = 6+3;\n    console.log(`Esta funcion no tiene nigun parametro,\nen su interior realiza la suma de dos numeros prestablecidos,\n'6+3', cuyo resultado es ${upshot}`);\n}\nparameterLess()\nconsole.log(`==========`);\n\n//Con un parametro:\nconsole.log(`==========`);\nconsole.log(`Funcion con un marametro: numero`);\nfunction oneParameter(number){\n    let upshot= number*number;\n    console.log(`Esta funcion tiene un parametro,\nen su interior realizamos la multiplicacion de el parametro por si mismo (cuadrado),\nen su llamada establecemos en valor del parametro en este caso ${number}.\n'${number}*${number}', cuyo resultado es ${upshot}`);\n}\nconsole.log(`==========`);\noneParameter(5)\nconsole.log(`==========`);\noneParameter(10)\nconsole.log(`==========`);\noneParameter(20)\nconsole.log(`==========`);\n\nconsole.log(`==========`);\nconsole.log(`Funcion con un marametro: string`);\nfunction oneParameter(name){\n    let upshot= `Hola, Bienvenido ${name}`;\n    console.log(`Esta funcion tiene un parametro,\nen su interior realizamos concatenacion de el nombre pasado por parametor ${name},\ny el mensaje de bienbenida 'Hola, Biembenido', cuyo resultado es ${upshot}`);\n}\nconsole.log(`==========`);\noneParameter(\"Alberto\")\nconsole.log(`==========`);\noneParameter(\"Juan\")\nconsole.log(`==========`);\noneParameter(\"Fernando\")\nconsole.log(`==========`);\n\n//Con varios parametros:\nconsole.log(`==========`);\nconsole.log(`Funcion mas de un parametro:`);\nfunction moreThanOneParameter(number1,number2){\n    let upshot= number1**number2;\n    console.log(`Esta funcion tiene mas de un parametro,\nen su interior realizamos la exponeiciación de number1 elevado a number2,\nen su llamada establecemos en valor del los parametros en este caso ${number1}, ${number2}.\n'${number1}*${number2}', cuyo resultado es ${upshot}`);\n}\nconsole.log(`==========`);\nmoreThanOneParameter(5,3)\nconsole.log(`==========`);\nmoreThanOneParameter(2,8)\nconsole.log(`==========`);\nmoreThanOneParameter(20,3)\nconsole.log(`==========`);\n\n//Con retorno:\nconsole.log(`==========`);\nconsole.log(`Funcion con un marametro y retorno: string`);\nfunction oneParameterAndReturn(name){\n    let upshot= `Hola, Bienvenido ${name}`;\n    console.log(`Esta funcion tiene un parametro y retorno,\nen su interior realizamos concatenacion de el nombre pasado por parametor ${name},\ny el mensaje de bienbenida 'Hola, Biembenido', cuyo resultado es ${upshot},\ny lo devolvemos por return, retorno para poder utilizarlo fuera de la a nuestro antojo.`);\n    return upshot;\n}\nconsole.log(`==========`);\nconsole.log(`Retorno: ${oneParameterAndReturn(\"Brais\")}`)\nconsole.log(`==========`);\nconsole.log(`Retorno: ${oneParameterAndReturn(\"Jorge\")}`)\nconsole.log(`==========`);\nconsole.log(`Retorno: ${oneParameterAndReturn(\"Jaime\")}`)\nconsole.log(`==========`);\n\nconsole.log(`==========`);\nconsole.log(`Funcion mas de un parametro y retorno:`);\nfunction moreThanOneParameterAndReturn(number1,number2){\n    let upshot= number1**number2;\n    console.log(`Esta funcion tiene mas de un parametro y retorno,\nen su interior realizamos la exponeiciación de number1 elevado a number2,\nen su llamada establecemos en valor del los parametros en este caso ${number1}, ${number2}.\n'${number1}*${number2}', cuyo resultado es ${upshot},\ny lo devolvemos por return, retorno, para poder utilizarlo fuera de la a nuestro antojo.`);\n    return upshot\n}\nconsole.log(`==========`);\nconsole.log(`Retorno: ${moreThanOneParameterAndReturn(6,2)}`)//imprimimos directamente por consola el retorno.\nconsole.log(`==========`);\nconsole.log(`Retorno: ${moreThanOneParameterAndReturn(8,16)}`)\nconsole.log(`==========`);\nlet retorno = moreThanOneParameterAndReturn(2,30);//almacenamos en una varialbe el retorno.\nconsole.log(`Retorno: ${retorno}`)//imprimimos la variable que contiene el valor de retorno.\n//console.log(upshot) //upshot no exixte fuera de la funcio.\nconsole.log(`==========`);\n\n//Funciones a alas que pasamos objetos o arrays como parametros:\nconsole.log(`==========`);\nconsole.log(`Funcion con objeto como argumento/parametro:`);\nfunction myFunc(theObject) {\n    theObject.make = 'Volkswagen';//Cambia el valor con clave make del objeto\n    theObject.model = 'Golf';//cambia el valor con clave model del objeto\n    theObject.year = 1992;//Cambia el valor con clave year del objeto\n}\nlet mycar = { make: 'Honda', model: 'Civic', year: 2000 };//definimos objeto.\nconsole.log(`El objeto inicial es: mycar = ${JSON.stringify(mycar)}`);//utilizamos el motodo JSON.stringify() para poder visualizar el objeto.\nconsole.log(`==========`);\nmyFunc(mycar)\nconsole.log(`function myFunc(theObject) {\n    theObject.make = 'Volkswagen';//Cambia el valor con clave make del objeto\n    theObject.model = 'Golf';//cambia el valor con clave model del objeto\n    theObject.year = 1992;//Cambia el valor con clave year del objeto\n}\nmyfunc(mycar)`)\nconsole.log(`El objeto tras ejecutar la funcion es: mycar = ${JSON.stringify(mycar)}`);//utilizamos el motodo JSON.stringify() para poder visualizar el objeto.\nconsole.log(`==========`);\n\n//Expresiones function:\n/*\nSi bien la declaración de función anterior sintácticamente es una declaración, las funciones también se pueden crear mediante una expresión function.\nEsta función puede ser anónima; no tiene por qué tener un nombre.\nSin embargo, puedes proporcionar un nombre con una expresión function. \nProporcionar un nombre permite que la función se refiera a sí misma y también facilita la identificación de la función en el seguimiento de la pila de un depurador\n*/ \n//Expresion function anonima:\nconsole.log(`==========`);\nconsole.log(`Exprecion Function anonima:`);\nconst square = function (number){\n    return number * number\n}\n\nlet upshot1 = square(5);\nlet upshot2 = square(10);\nlet upshot3 = square(90);\nconsole.log(`La fucnion: \nconst square = function (number){\n    return number * number\n}\nes anonima, y la llamamos refiriendonos al nombre de la constante que la contiene.\nsquare(5) = ${upshot1}.\nsquare(10) = ${upshot2}.\nsquare(90) = ${upshot3}.`)\nconsole.log(`==========`);\nconsole.log(`==========`);\nconsole.log(`Exprecion Function con Nombre: permite referise a si misma, y asi usarse como funcion recursiva,\nya que se pueden anidar funciones dentro de funciones.`);\nconst factorial = function fac(n) {\n    return n < 2 ? 1 : n * fac(n - 1);\n};\nupshot1 = factorial(3);\nupshot2 = factorial(8);\nupshot3 = factorial(31);\nconsole.log(`\nconst factorial = function fac(n) {\n    return n < 2 ? 1 : n * fac(n - 1);\n};\nfactorial(3) = ${upshot1};\nfactorial(8) = ${upshot2};\nfactorial(31) = ${upshot3};\n`);\nconsole.log(`==========`);\n\n//Alcande: Global o Local.\nconsole.log(`==========`);\nvar globalVar = \"esta es una variable global\"\nfunction globalScope (typevar){\n    let localVAr = typevar + globalVar\n    return localVAr\n}\nconsole.log(globalScope(\"Puedo usar dentro la variable poque \"))\n//console.log(localVAr)//descomentar para ver error.\nconsole.log(`pero no podemos acceder a la variable localVar, porque esta definida en ambito local.`)\nconsole.log(`==========`);\n\n// Las siguientes variables se definen en el ámbito global\nconsole.log(`==========`);\nvar num1 = 20,\nnum2 = 3,\nname = \"alberto\";\n\n// Esta función está definida en el ámbito global\nfunction multiply() {\n    return num1 * num2;\n}\n\nconsole.log(`Las variables glovales pueden usarse en funciones definidas en ambito gloval,\n/ Las siguientes variables se definen en el ámbito global\nvar num1 = 20,\nnum2 = 3,\nname = \"alberto\";\n\n// Esta función está definida en el ámbito global\nfunction multiply() {\n    return num1 * num2;\n}\npor eso devuelve ${multiply()}`); // Devuelve 60\nconsole.log(`==========`);\n\n// Un ejemplo de función anidada\nconsole.log(`==========`);\nfunction getScore() {\n    var num1 = 2,\n    num2 = 3;\n    \n    function add() {\n        return name + \" Marco \" + (num1 + num2);\n    }\n    \n    return add();\n}\n\nconsole.log(`En este caso:\nfunction getScore() {\n    var num1 = 2,\n    num2 = 3;\n    \n    function add() {\n        return name + \" Marco \" + (num1 + num2);\n    }\n    \n    return add();\n}\npodemos redeclarar las variables anteriores en ambito local, \nla funcion anidada, solo puede acceder a las variable de ambito gloval \nde su funcion madre,\npor eso devuelve ${getScore()}`); // Devuelve \"Chamahk anotó 5\"\nconsole.log(`==========`);\n\n//Funciones predefinidas:\n/*\n* Existen funciones predefinidas en el leguaje que son llamadas metodos, las cuales posemos usar para resolver problemas concretos. \n* Como combersiones de tipo: parseInt() que combierte un valor a entero.\n* Como representacion de objetos en str: JSON.stringify() que permite representar un objeto como cadena de texto, visto en algun ejemploanterior.\n* y muchos mas.\n*/\n//ejemplo parseInt() y typeof():\nconsole.log(`==========`);\nconsole.log(`Funciones o Metodos predefinidos del leguaje:`);\nlet str1 = \"2\";\nconsole.log(`Ahora la variable es ${str1} de tipo ${typeof(str1)}, usando el metodo typeof() que nos muestra el tipo de dato que contiene la variable.`);\nstr1=parseInt(str1);\nconsole.log(`tras usar parseInt(str1) ahora la variable es ${str1} de tipo ${typeof(str1)}`);\nconsole.log(`==========`);\n\n//extra:\n/*\n* DIFICULTAD EXTRA (opcional):\n* Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n* - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n*   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n*   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n*   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n*   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n*/\nconsole.log(`==========`);\nconsole.log(`DIFICULTAD EXTRA:`);\nfunction difExtra(str1, str2){\n    let counter=0;\n    for (let num = 1; num<=100; num++){\n        if (((num%3) === 0) && ((num%5) ===0)){\n            console.log(str1+\" \"+str2);\n        }else if ((num%5)===0){\n            console.log(str2);\n        }else if ((num%3)===0){\n            console.log(str1);\n        }else{\n            console.log(num);\n            counter++;\n        }\n    }\n    return counter;\n}\nconsole.log(`El numero se ha impreso ${difExtra(\"Chanchito\",\"Feliz\")} veces.`)\nconsole.log(`==========`);\n\n\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #02 - JavaScript ->Jesus Antonio Escamilla */\n/**\n * Dentro de las Funciones Básicas de JavaScript se utilizan:\n * Declarativas\n * Expresión\n * Función Flecha\n * Auto-ejecutable\n * Constructiva\n */\n\n//-----DECLARATIVAS-----\n//  Aquí se declara la función y después se llama para poder usarla.\nfunction saludar(nombre) {\n    console.log(`Hola , ${nombre}!!!!`);\n}\nsaludar(\"Jesus Antonio\"); //La función funciona cuando se le envía un nombre y lo imprime\n\n\n//-----EXPRESIÓN-----\n//  Estas funciones no llevan nombre ya que va declara de una variable o buen de un objeto\n//  también se llama función anónima y de igual forma puede llevar nombre la función para\n//  hacerse referencia asi misma pero son casos especiales\nvar sumar = function(a, b) {\n    return a + b;\n}\nvar resultado = sumar(5, 10);\nconsole.log(resultado); //La función arroga la respuesta.  15\n\n\n//-----FUNCIÓN FLECHA-----\n// Esta función funciona cuando un variable se declara con la función que va a\n// realizar y después de puede llamar para poder utilizarla y hacer cualquier ejecución\nvar a = [\"Hidrógeno\", \"Helio\", \"Litio\", \"Berilio\"];\n\nvar a2 = a.map((s) => s.length);\n\nconsole.log(a2); // logs [9, 5, 5, 7]\n\n\n\n/**\n * Se puede realizar funciones dentro de funciones \n * siempre y cuando se cumpla si paramentos o bien se cumplan las acciones\n */\n//  Vemos que la función tiene que hacer una resta,\n//  pero dentro la función tiene realizar un incremento \n//  de las variables y después puede realizar la resta\nfunction resta(a, b) {\n    function incrementar(x) {\n        return x + 1;\n    }\n    // Llamada a la función interna\n    return incrementar(a) - incrementar(b);\n}  \nconsole.log(resta(17, 6)); // Devuelve 11\n\n\n\n/**\n * FILTER()\n * Un método de arrays para javascript en la cual hacer filtrado del mismo objeto\n */\nconst numero = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n\n// Filtrar los números pares\nconst numeroPares = numero.filter(function(numero) {\n    return numero % 2 === 0;\n});\n\nconsole.log(numeroPares); // Imprime [2, 4, 6, 8, 10]\n\n\n\n/**\n * VARIABLE GLOBAL Y VARIABLE LOCAL\n * Existen los grandes variables la global y variable la local\n */\n\n\n//-----VARIABLE GLOBAL-----\nvar contador = 2; // Variable global\nfunction incrementarContador() {\n    contador++;\n}\nconsole.log(contador); // Imprime 2\n\n\n//-----VARIABLE LOCAL-----\nfunction saludar() {\n    var mensaje = \"Hola, mundo!\"; // Variable local\n    console.log(mensaje);\n}\nsaludar(); // Imprime \"Hola, mundo!\"\n// console.log(mensaje); // Error: mensaje is not defined\n\n\n\n/**-----DIFICULTAD EXTRA-----*/\nfunction extra(param1 , param2) {\n    let cont = 0;\n    for (let i = 1; i <= 100; i++) {\n        if (i % 3 == 0 && i % 5 == 0) {\n            console.log(param1);\n        }else if(i % 3 == 0) {\n            console.log(param2);\n        }else if(i % 5 == 0){\n            console.log(param1 + param2);\n        } else{\n            cont ++;\n            console.log(i);\n        }\n    }\n    return console.log('Son las veces que aparece', cont);\n}\nconsole.log(extra(\"FIZZ\",\"BUZZ\"));\n/**-----DIFICULTAD EXTRA-----*/\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/JheisonQuiroga.js",
    "content": "//// Author: Jheison Duban Quiroga Quintero\n//// Github: https://github.com/JheisonQuiroga\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n **/\n\n// 1. Función Simple\n\n// Declaración de una función\nfunction helloWorld() {\n    console.log(\"Hello World!\")\n}\n\n// Llamada a la función.\nhelloWorld()\n\n// 1.1. Función con parámetros.\n\ngreet(\"Duban\")\n\nfunction greet(name) {\n    console.log(`Hello, ${name}`)\n}\n\n// 1.3. Retorno de una función (retornando un valor)\n\nfunction yourName(name) {\n    return name\n}\n\nconsole.log(yourName(\"Duban\"))\n\n\n// 1.4. Function Expressions\n\nconst addNumbers = function(n1, n2) {\n    return n1 + n2\n}\n\nconsole.log(addNumbers(2, 3))\n\n// 1.5. Arrow Functions\n\nconst multiply = (n1, n2) => n1 * n2\nconsole.log(multiply(5, 7)) \n\nconst divide = (n1, n2) => {\n    if (n2 === 0) {\n        throw new Error(\"No se puede dividir entre cero 💀\")\n    }\n    return n1 / n2\n}\n\ntry {\n    console.log(divide(10, 0))\n} catch (err) {\n    console.error(err.name, err.message)\n}\n\n// 2. Función dentro de otra función\n\nfunction outerFunction() {\n    function innerFunction() {\n        return \"Función interna\"\n    }\n    return innerFunction()\n}\n\nconsole.log(outerFunction())\n\n// 3. Funciones globales dentro del lenguaje\n\nconsole.log(typeof parseInt(\"10\"))\nconsole.log(typeof parseFloat(\"10.69\"))\n\n// Métodos del objeto Math\nMath.max(1, 2, 3, 4, 5) // Retorna el número mayor\nMath.min(1, 2, 3, 4, 5) // Retorna el número menor\n\n\n//// 4. Variables globales y locales\nconst pi = Math.PI // Variable global\n\nconst circleArea = function(radius) {\n    const piFunction = 3 // Variable local\n    return piFunction * radius ** 2\n}\n\nconsole.log(`Área del círculo: ${circleArea(5)}`)\n\n// Accediendo a la variable local de la función\n// console.log(piFunction) // ReferenceError piFunction is not defined\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\nfunction fizzBuzz(firstString, secondString) {\n    for (let i = 1; i <= 100; i++) {\n        switch (true) {\n            case i % 3 === 0 && i % 5 === 0:\n                console.log(`${firstString} ${secondString}`)\n                break\n            case i % 3 === 0:\n                console.log(firstString)\n                break\n            case i % 5 === 0:\n                console.log(secondString)\n                break\n            default:\n                console.log(i)            \n        }\n    }\n}\n\nfizzBuzz(\"Fizz\", \"Buzz\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/Joanfv-git.js",
    "content": "// Tipos de Funciones en JavaScript\nfunction sinParametrosNiRetorno() {\n  console.log(\"No hay parámetros ni retorno\");\n}\nfunction conUnParametro(parametro) {\n  console.log(\"El parámetro es: \" + parametro);\n}\nfunction conVariosParametros(parametro1, parametro2) {\n  console.log(\"Los parámetros son: \" + parametro1 + \" y \" + parametro2);\n}\nfunction conRetorno(parametro) {\n  return parametro;\n}\nfunction conVariosRetornos(parametro) {\n  return [parametro, parametro + 1];\n}\n\n//Funciones dentro de funciones\nfunction funcionPrincipal() {\n  console.log(\"Función Principal\");\n  function funcionSecundaria() {\n    console.log(\"Función Secundaria\");\n  }\n  funcionSecundaria();\n}\n\n//Ejemplo de función propia de JavaScript\nfunction mostrarAlerta() {\n  alert(\"Alerta\");\n}\n\n//Ejemplo de variable global y local\nvar variableGlobal = \"Variable Global\";\nfunction mostrarVariableGlobal() {\n  console.log(variableGlobal);\n  var variableLocal = \"Variable Local\";\n  console.log(variableLocal);\n}\nmostrarVariableGlobal();\n\n//Ejercicio extra\nlet primerParametro = \"Primero\";\nlet segundoParametro = \"Segundo\";\nlet array = [];\nfunction retornoParams(param1, param2) {\n  for (let i = 1; i < 101; i++) {\n    if (i % 3 == 0 && i % 5 == 0) {\n      array.push(param1 + param2);\n    } else if (i % 3 == 0) {\n      array.push(param1);\n    } else if (i % 5 == 0) {\n      array.push(param2);\n    } else {\n      array.push(i);\n    }\n  }\n  return array;\n}\nlet resultado = retornoParams(primerParametro, segundoParametro);\nconsole.log(resultado);\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/JoaquinLopez14.js",
    "content": "/*\n * EJERCICIO:\n 1 - Crea ejemplos de funciones básicas que representen las diferentes\n     posibilidades del lenguaje: Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n  - Comprueba si puedes crear funciones dentro de funciones.\n  - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n  - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n    (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n\n\n 1.1 DIFICULTAD EXTRA (opcional):\n 1.2 Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n * \n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n // 1\n\n// Funcion basica\n\n    function suma (a, b) {\n        return a + b\n    }\n\n    console.log(suma(-2, 6)) // 4\n    console.log(suma(3, 6)) // 9\n\n\n//Funciones anidadas\n\n    function alCuadrado(a, b) {\n        function cuadrado (x) {\n          return x * x\n        }\n        return cuadrado(a) + cuadrado(b)\n      }\n      \n      console.log(alCuadrado(2, 3)) // 13\n      console.log(alCuadrado(5, 10)) // 125\n\n// Funcion flecha\n\n    const suma2 = (a, b) => a + b\n\n    console.log(suma2(-2, 6)) // 4\n    console.log(suma2(3, 6)) // 9\n\n// Varible Global\n\n    let counter = 2\n        \n    function counterPlus() {\n    return counter++\n    }\n\n    console.log(counterPlus()); // 2\n    console.log(counter); // 3 \n\n// Variable local\n\n    function saludar() {\n        let saludo = \"Hola\"\n        console.log(saludo)\n    }\n\n    saludar()\n// console.log(saludo) // <- ReferenceError: saludo is not defined\n\n// 1.1 Dificultad Extra\n\nfunction contador (string1, string2) {\n    let count = 0\n    for (let i = 1; i <= 100; i++) {\n       if ( i % 3 === 0 && i % 5 === 0 ) {\n          console.log(string1 + string2)\n     } else if (i % 3 === 0){\n      console.log(string1)\n    } else if (i % 5 === 0){\n        console.log(string2)\n    } else {\n      console.log(i)\n      count++\n    }\n  }\n    return count;\n  }\n  \n  // Llama a la función con los parámetros de ejemplo\n  let resultado = contador(\"fizz\", \"buzz\");\n  console.log(\"Cantidad de números impresos:\", resultado);"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/JoseAndresGC.js",
    "content": "// función sin sin retorno ni parámetros...\n\nfunction funcion1(){\n    console.log('función sin retorno ni parámetros!');\n}\nfuncion1();\n\n// funciones y función con uno o varios parámetros con retorno...\n\nfunction funcionStandar() { // con o sin parametro/s\n    // código...\n    console.log('Esto es una función standar');\n}\nfuncionStandar();\n\narrowFunction = () => {\n    // código...\n    console.log('Esto es una función de flecha');\n}\narrowFunction();\n\nasync function funcionAsincrona(params) {\n    // código...\n    console.log('Esto es una función Asíncrona');\n}\nfuncionAsincrona();\n\nconst asyncArrowFunction = async (params) => {\n    // código...\n    console.log('Esto es una función Asíncrona de flecha');\n}\nasyncArrowFunction();\n\nlet obj = {\n    nombreFuncion: function(param) {\n        // código...\n    }, // esta sintaxis solo funciona dentro de un objeto para javascript\n\n    nombreFuncion2: (arg) => retornarUnValor // ésta arrow function también se usa dentro de objetos\n}\n\nfunction funcion2(suma) {\n    let a = 2;\n    let b = 2;\n    suma = a + b;\n    return suma;\n}\nconsole.log(funcion2());\n\n// funciones dentro de funciones...\n\nfunction funcion3(param) {\n    var funcionDentroDeOtra = function() {\n        // se agrega la logica...\n    };\n    // se puede llamar aqui la funcion interna... funcionDentroDeOtra();\n}\n\n// Usar algún ejemplo de funciones ya creadas en el lenguaje...\n\nfunction decirHola() {\n    console.log('Hola!! Mensaje enviado después de 1 segundo!!');\n}\n\nsetTimeout(decirHola, 1000); // después de 1 segundo se enviará por consola \"Hola\n\n// Varial local y global...\n\nlet global = 'Esto es una variable GLOBAL';\n\nfunction variableLocal() {\n    let local = 'Esto es una variable LOCAL';\n    console.log(local);\n    console.log(global);\n}\nvariableLocal();\n\n// DIFICULTAD EXTRA:\n\n\nfunction dif_Extra(str1, str2) {\n    let cont = 0;\n\n    for (let i = 1; i <= 100; i++) {\n\n        if (i % 3 === 0 && i % 5 === 0) {\n            console.log(str1 + str2);\n\n        } else if (i % 3 === 0) {\n            console.log(str1);\n\n        } else if (i % 5 === 0) {\n            console.log(str2);\n        } else {\n            console.log('Número: ' + i);\n            cont++;\n        }\n    }\n    console.log('Se imprimió ' + cont + ' veces un número');\n    return cont;\n}\ndif_Extra('cadena1', 'cadena2');\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/JoseFuentes-Dev.js",
    "content": "//******FUNCIONES\n//FUNCIONES DE ORDEN SUPERIOR\n//map\nconst numbers =[1,2,3,4]\n\nconst double = numbers.map(number => number*2);\nconsole.log(double);\n\n//filter\nconst even =numbers.filter(n=>n%2===0);;\n\nconsole.log(even);\n\n//reduce\n\nconst sum = numbers.reduce((total, number) => total + number, 0);\nconsole.log(sum);\n\n//every\n\nconst allEven = numbers.every(n=>n%2===0);\nconsole.log(allEven);\n\n//some\n\nconst hasEven = numbers.some(n=>n%2===0);\nconsole.log(hasEven);   \n\n//MANIPULACION DE CADENAS\n//split\n\nconst sentence = 'Hello, World!';\nconst words = sentence.split(' ');\nconsole.log(words);\n\n//join\n\nconst joinedWords = words.join('-');\nconsole.log(joinedWords);\n\n//replace\n\nconst replaced = sentence.replace('World!', 'JavaScript!');\nconsole.log(replaced);\n\n//substring\n\nconst substring = sentence.substring(0, 5);\nconsole.log(substring);\n\n//length\n\nconst length = sentence.length;\nconsole.log(length);\n\n//MANIPULACION DE OBJETOS   \n//keys\n\nconst person = {name: 'John', age: 30};\nconst keys = Object.keys(person);\nconsole.log(keys);\n\n//values\n\nconst values = Object.values(person);\nconsole.log(values);\n\n//entries   \n\nconst entries = Object.entries(person);\nconsole.log(entries);\n\n//OPERACIONES MATEMATICAS\n//math random\n\nconst random = Math.random();\nconsole.log(random);\n\n//math floor\n\nconst floor = Math.floor(random * 10);\nconsole.log(floor);\n\n//math ceil\n\nconst ceil = Math.ceil(random * 10);\nconsole.log(ceil);\n\n//math round\n\nconst round = Math.round(random * 10);\nconsole.log(round);\n\n//math max\n\nconst max = Math.max(1, 2, 3, 4, 5);\nconsole.log(max);\n\n//math min\n\nconst min = Math.min(1, 2, 3, 4, 5);\nconsole.log(min);\n\n//MANIPULACION DE FECHAS\n//date\n\nconst date = new Date();\nconsole.log(date);\n\n//year\n\nconst year = date.getFullYear();\nconsole.log(year);\n\n//FUNCION  SIN PARAMETROS NI RETORNO\nfunction sinparametro (){\n    console.log('funcion sin parametro ni retorno');\n}\nsinparametro();\n\n//FUNCION CON UN PARAMETRO SIN RETORNO\nfunction unparametro(parametro){\n    console.log(`hola ${parametro}`);\n\n}\nunparametro(\"Pedro\");\n\n//FUNCION CON UN PARAMETRO CON RETORNO\nfunction number(numero){\n    return numero + numero\n\n}\nconsole.log(number(2));\n\n//FUNCION CON VARIOS PARAMETROS SIN RETORNO\nfunction number (numero1, numero2){\n    let numero3 = numero1+numero2;\n    console.log(`La suma de ${numero1} + ${numero2} = ${numero3}`)\n}\nnumber(3,2);\n\n//FUNCION CON VARIOS PARAMETROS Y CON RETORNO\nfunction numeros (num1, num2){\n    return num1*num2\n}\nconsole.log(numeros(5,2));\n\n//FUNCION ANONIMA\nconst color = function(col){\n    return \"Mi color Preferido es \" + col;\n}\nconsole.log(color(\"BLUE\"));\n\n//ARROW FUNCION\nconst planta = (plant)=>{\n    return \"Mi planta favorita es \"+ plant;\n}\nconsole.log(planta(\"Orquidea\"));\n\n// Si la función de flecha tiene una sola expresión, se puede omitir el bloque {} y el return:\\\nconst plantas =(plants)=> \"Mis Plantas Favorita son \" + plants;\nconsole.log(plantas(\"Cactus\"));\n\n//FUNCION CON VALOR POR DEFECTO\nfunction say(sal='JOse'){\n    return \"Saludar a \"+ sal;\n}\nconsole.log(say());\nconsole.log(say(\"chris\"));\n\n// FUNCION QUE UTILIZA EL OPERADOR REST\n//EL OPERADOR REST PERMITE A UNA FUNCION ACEPTAR UN NUMERO INDEFINIDO DE ARGUMENTOS COMO UN ARRAY\nconst suma=(...rest)=>{\nreturn rest.reduce((total, numero)=>total + numero,0);\n}\nconsole.log(suma(1,2,3,4,5));\n\n//FUNCION CON TRY CATCH\nfunction division(x, y){\n    try{\n     if(y===0){\n     console.log(\"Division 0\");\n    }\n    return x/y;\n    }\n    catch(error){\n      console.log(error.message);\n      return null;\n    }\n}\nconsole.log(division(10,2));\nconsole.log(division(10,0));\n\n//DIFICULTAD EXTRA\nfunction cadena(str1, str2) {\n    let contador = 0;\n\n    for (let i = 1; i <= 100; i++) {\n        let output = '';\n\n        if (i % 3 === 0) output += str1;\n        if (i % 5 === 0) output += str2;\n\n        if (output === '') {\n            console.log(i);\n            contador++;\n        } else {\n            console.log(output);\n        }\n    }\n\n    return contador;\n}\n\nconst str1 = \"Javascript \";\nconst str2 = \"The Best\";\nconst result = cadena(str1, str2);\nconsole.log(\"Veces que se ha impreso el número en vez de texto:\", result);\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/JosueVH07.js",
    "content": "\n// Ejemplos de funciones\n\n// Función sin argumentos y sin retorno\n// FUnciones existentes en el navegador\n// const selectH1 = document.querySelector('h1');\n// console.log(selectH1);\n\n// alert('Hola, soy Josue y estoy aprendiendo JavaScript');\n\n\n// Función con argumentos y sin retorno\n\nfunction saludar(nombre) {\n    console.log('Hola ' + nombre);\n}\nsaludar('Josue');\n\n// Función con argumentos y con retorno\nfunction suma(n1, n2) {\n    return n1 + n2;\n}\n\nconsole.log(suma(5, 3));\n\n// Función sin argumentos y con retorno\nfunction obtenerNombre() {\n    return 'Josue';\n}\n\nconsole.log(obtenerNombre());\n\n// Función flecha\nconst multiplicar = (n1, n2) => {\n    return n1 * n2;\n}\n\nconsole.log(multiplicar(5, 3));\n\n\n// FUnciones dentro de funciones\n\nfunction externa() {\n    function interna() {\n        console.log('Soy una función interna');\n    }\n    interna();\n}\n\nexterna();\n\n// Funciones del lenguaje\n\nconsole.log(typeof saludar);\n\nconst date = new Date();\n\nconsole.log(date);\n\n// VARIABLES\n\n// Variables globales\nlet nombre = 'Josue';\nconst apellido = 'Vargas';\nvar edad = 24;\n\nfunction saludar() {\n    console.log('Hola ' + nombre);\n}\n\nsaludar();\n\n// Variables locales\nfunction local() {\n    let nombre = 'Jeffrey';\n    console.log(nombre);\n}\n\nlocal();\n\n//DIFICULTAD EXTRA\n\nconst getNumber = (text1, text2) => {\n    let total = 0;\n\n    for (let i = 1; i <= 100; i++) {\n        if (i % 3 === 0 && i % 5 === 0) {\n            console.log(text1 + text2);\n        } else if (i % 3 === 0) {\n            console.log(text1);\n        } else if (i % 5 === 0) {\n            console.log(text2);\n        } else {\n            console.log(i);\n            total += 1;\n        }\n    }\n    return console.log(total);\n}\n\ngetNumber('Fizz', 'Buzz');"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/Josueeeee.js",
    "content": "/*\n --------------------------------------\n   * FUNCIONES DEFINIDAS POR EL USUARIO\n ---------------------------------------\n*/\n// Simple\nconst funcion = () => {\n  console.log(\"Hola, Javascript  fun1\");\n};\nfuncion();\n\n// Con return\nconst return_greet = () => {\n  return \"Hola, Javascript fun2\";\n};\nconsole.log(return_greet());\n\n// Con argumento\nconst arg_greet = ({ greet, nameS }) => {\n  console.log(`${greet} ${nameS} fun3`);\n};\n\narg_greet({ nameS: \"Ramirez\", greet: \"Hola,\" });\n\n// Con argumento predeterminado\n\nconst default_arg_greet = (nameS = \"JavaScript\") => {\n  console.log(`Hola, ${nameS} fun4`);\n};\ndefault_arg_greet();\n\n// Con argumento y retorno\nconst retur_arg_greet = (greet, nameS) => {\n  return `${greet} ${nameS} fun5`;\n};\n\nconsole.log(retur_arg_greet(\"Hola\", \"Jeff\"));\n\n// Con retorno de varios valores\nconst multiple_return_greet = () => {\n  return [\"Hola,\", \"Javascript fun6\"];\n};\n\nconst [greet, languageName] = multiple_return_greet();\n\nconsole.log(greet);\nconsole.log(languageName);\n\n// Con distintos argumentos en variable\n\nconst variable_arg_greet = names => {\n  for (let i = 0; i < names.length; i++) {\n    console.log(`Hola, ${names[i]} fun7`);\n  }\n};\n\nvariable_arg_greet([\"Javascript\", \"Python\", \"Jeffrey\", \"Josue\"]);\n\n// funciones dentro de funciones\nconst outer_funcion = () => {\n  inner_funcion = () => {\n    console.log(\"Función interna: Hola Javascript\");\n  };\n  inner_funcion();\n};\n\nouter_funcion();\n\n// funciones del lenguaje\nconsole.log(parseInt(\"10\") + parseInt(\"10.5\"));\n// -----------------------------\nlet date = new Date();\nconsole.log(\n  date.toISOString() // Ejemplo: '2024-07-29T12:34:56.789Z'\n);\n/*\n --------------------------------------\n   * VARIABLES LOCALES Y GLOBALES\n ---------------------------------------\n*/\n\nconst global_var = \"variable global\";\n\nconsole.log(global_var);\n\nconst fucionVar = () => {\n  const local_var = \"Hola\";\n  console.log(`${local_var}, ${global_var}`);\n};\nfucionVar();\n/*\n --------------------------------------\n    * DIFICULTAD EXTRA (opcional):\n ---------------------------------------\n*/\n\nconst return_num = (tex1, tex2) => {\n  let total = 0;\n  for (let i = 0; i <= 100; i++) {\n    if (i % 3 == 0 && i % 5 == 0) {\n      console.log(tex1 + tex2);\n    } else if (i % 3 == 0) {\n      console.log(tex1);\n    } else if (i % 5 == 0) {\n      console.log(tex2);\n    } else {\n      console.log(i);\n      total += 1;\n    }\n  }\n\n  return console.log(total);\n};\nreturn_num(\"hOla, \", \"jeffrey\");\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/JuSeRDev.js",
    "content": "\n//  * - Crea ejemplos de funciones básicas que representen las diferentes posibilidades del lenguaje: Sin parámetros ni retorno, con uno o varios parámetros, con retorno... \n\n\n\n//funcion sin retorno y sin parametros\n\nfunction saludar() {\n    let saludo = \"hola\"\n}\n\nconsole.log(saludar());\n\n\n// Funcion con 2 parametros y retorno\nfunction suma(a, b) {\n    let resultado = a + b\n    return resultado\n}\n\nconsole.log(suma(1, 2));\n\n//  * - Comprueba si puedes crear funciones dentro de funciones.\n\nfunction multiplicar(resultado) {\n    function num1(a,b) {\n        let resultado = a + b\n        return resultado\n    }\n    num1(12,10)\n    function num2(a,b) {\n        let resultado = a-b\n        return resultado\n    }\n    num2(10,5)\n    let resultado1 = num1(10,15)\n    let resultado2 = num2(10,5)\n    resultado = resultado1 * resultado2\n    return resultado\n}\n\nconsole.log(multiplicar());\n\n\n//  * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n\nlet fechaActual = new Date()\nconsole.log(\"la fecha de hoy es: \", fechaActual);\n\nlet numeromayor = Math.max(3, 5, 10, 12)\nconsole.log(numeromayor);\n\n\n//  * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n\nlet global = \"soy una variable global\"\n\nlet myFunc = ()=>{\n    let local = \"Soy una valriable local\"\n    let global = \"soy una varia local definida dentro de una funcion con el nombre de una variable global\"\n    return `la variable \"local\": ${local} y la variable \"global\" dentro de una fucnion: ${global}`\n}\n\n//  * - Debes hacer print por consola del resultado de todos los ejemplos. (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n\nconsole.log(global);\nconsole.log(myFunc());\n\n//  * DIFICULTAD EXTRA (opcional):\n//  * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n//  * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n//  *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n//  *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n//  *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n//  *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\nlet extra = (string1, string2) => {\n    let contador = 0;\n    for (let i = 1; i <= 100; i++) {\n        switch (true) {\n            case i % 3 === 0 && i % 5 === 0:\n                console.log(string1 + string2)\n                break;\n            case i % 3 === 0:\n                console.log(string1);\n                break;\n            case i % 5 === 0:\n                console.log(string2);\n                break;\n            default:\n                console.log(i);\n                contador++;\n                break;\n            }\n        }\n    return contador\n}\n\n\nconsole.log(extra(\"cadena(1)\", \"cadena(2)\"));\n\n\nlet extra2 = (texto1, texto2)=>{\n    let contador = 0\n    for (let i = 1; i <= 100; i++) {\n        const numero = i;\n        if (numero % 3 === 0 && numero % 5 === 0) {\n            let string3= texto1 + texto2\n            console.log(string3);\n        }else if(numero % 3 === 0){\n            let string1 = texto1\n            console.log(string1);\n        } else if(numero % 5 === 0){\n            let string2 = texto2\n            console.log(string2);\n        }else{\n            console.log(i)\n            contador++\n        }\n    }\n    return contador\n}\nconsole.log(extra2(\"multiplo de 3\",\"multiplo de 5\"));\n\n\n\n//  * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n//  * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda."
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/JuanCaicedo1024.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * \n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n\n//TIPOS DE FUNCIONES \n\n//1. Funciones Declaradas (Function Declarations)\n\nfunction suma ( a,b){\n    return a + b;\n}\n\n//2. Funciones Expresadas (Function Expressions)\nconst resta = function (a,b){ \n    return a - b;\n}\n\n//3. Funciones Flecha (Arrow Functions)\nconst multiplicacion = (a,b) => a * b;\n\n//4. Funciones Anónimas (Anonymous Functions)\n\nfunction* contador() {\n    let i = 0;\n    while (true) {\n      yield i++;\n    }\n  }\n\n  //5. Funciones Asíncronas (Async Functions)\n\n  async function miFuncion() {\n    const respusta = await fetch('https://api.com');\n    return respusta.json();\n  }\n\n  // 6. IIFE (Immediately Invoked Function Expressions)\n\n    (function() {\n        console.log('Hola!');\n      })();\n\n// 7. Funciones dentro de funciones\n\nfunction personal (name) {\n    this.name = name;\n}\n\n// 8. Funciones ya creadas en el lenguaje\n\nsetTimeout(() => {\n    console.log('Hola, mundo!');\n},1000);\n\n\n// DIFICULTAD EXTRA (opcional):\n//  * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n//  * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n//  *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n//  *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n//  *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n//  *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\nconst DF = (string1, string2) => {\n    let contador = 0;\n    for (let i = 1; i <= 100; i++) {\n        switch (true) {\n            case i % 3 === 0 && i % 5 === 0:\n                console.log(string1 + string2)\n                break;\n            case i % 3 === 0:\n                console.log(string1);\n                break;\n            case i % 5 === 0:\n                console.log(string2);\n                break;\n            default:\n                console.log(i);\n                contador++;\n                break;\n            }\n        }\n    return contador\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/Juancamilo3821.js",
    "content": "// EJERCICIO:\n//  * - Crea ejemplos de funciones básicas que representen las diferentes\n//  *   posibilidades del lenguaje:\n//  *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n//  * - Comprueba si puedes crear funciones dentro de funciones.\n//  * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n//  * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n//  * - Debes hacer print por consola del resultado de todos los ejemplos.\n//  *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n\n// Declaracion de funciones tradicional\n\nfunction sayHi(nombre) {\n    return `Hola, ${nombre}!`;\n}\nconsole.log(sayHi(\"Juank\"));\n\nfunction temon(musica)  {\n    return `Este es un temota: ${musica}`;\n}\nconsole.log(temon(\"Runner\"))\n\n//Expresion de Funcion anonima\n\nconst sumar = function(a, b) {\n    return a + b;\n}\nconsole.log(sumar(12, 8));\n\nconst restar = function(z, c) {\n    return z - c;\n}\nconsole.log(restar(12, 8))\n\n//Arrow Function(Funciones Flecha)\n\nconst multiplicar = (a, b) => a * b;\nconsole.log(multiplicar(12, 8));\n\nconst dividir = (c, d) => c / d;\nconsole.log(dividir(12, 8)); \n\n//Funcion con Parametros Predeterminados\n\nfunction configurarUsuario (usuario = \"Invitado\") {\n    return `Bienvenido, ${usuario}!`;\n}\nconsole.log(configurarUsuario());\n\nfunction esMusico (user = \"Musico\") {\n    return `Hola, resulta que eres ${user}, eso es verdad?`;\n}\nconsole.log(esMusico());\n\n//Funcion de orden superior(CallBack)\n\nfunction procesarOperacion(a, b, operacion) {\n    return operacion(a, b);\n}\nconst resultado = procesarOperacion(10, 5, (x, y) => x - y);\nconsole.log(resultado)\n\n\nfunction operacionDefinida(c, d, definida) {\n    return definida(c, d);\n}\n\nconst residuo = operacionDefinida(100, 150, (c, d) => c * d);\nconsole.log(residuo)\n\n\n//IIFE (Immediately Invoked Function Expression)\nconsole.log(typeof console.log);\n\n(function() {\n  console.log(\"Esta función se ejecuta sola\");\n})();\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/Kronstadt-Lambda.js",
    "content": "/**\n * @author: Kronstadt-Lambda\n * @version: 1.0\n */\n\n// Initializations\nlet array = [1, 2, 3, 4, 5];\nlet author = \"Kronstadt-Lambda\";\n\n// function whitout return and parameters\nfunction helloTeam() {\n    console.log(\"Hello roadmap-retos-programacion!\");\n}\nhelloTeam();\n\n// function whit one parameter whitout return\nfunction helloName(name) {\n    console.log(\"Hello \" + name + \"!\");\n}\nhelloName(\"Kronstadt-Lambda\");\n\n// function whit many parameters whitout return\nfunction sumFactors(a, b, c, d) {\n    console.log(\"The sum of the factors is: \" + (a + b + c + d));\n}\nsumFactors(1, 2, 3, 4);\n\n// Function that accepts any number of parameters and don't have return\nfunction sumFactors2(...args) {\n    let sum = 0;\n    for (let i = 0; i < args.length; i++) {\n        sum += args[i];\n    }\n    console.log(\"The sum of the factors is: \" + sum);\n}\nsumFactors2(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);\nsumFactors2(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20);\n\n// Function whitout parameters and whit return\nfunction getNameDay() {\n    const days = [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"];\n    const today = new Date();\n    return days[today.getDay()];\n}\nconsole.log(\"Today is \" + getNameDay());\n\n// Function whit one parameter and whit return\nfunction getSquare(n) {\n    return n * n;\n}\nconsole.log(\"The square of 5 is: \" + getSquare(5));\n\n// Function whit many parameters and whit return\nfunction getAverage(a, b, c, d) {\n    return (a + b + c + d) / 4;\n}\nconsole.log(\"The average is: \" + getAverage(1, 2, 3, 4));\n\n// Function that accepts any number of parameters and have return\nfunction getAverage2(...args) {\n    let sum = 0;\n    for (let i = 0; i < args.length; i++) {\n        sum += args[i];\n    }\n    return sum / args.length;\n}\nconsole.log(\"The average is: \" + getAverage2(1, 2, 3, 4, 5, 6));\nconsole.log(\"The average is: \" + getAverage2(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));\n\n// Function whit optional parameters and whit return\nfunction multiplication(a, b = 1) {\n    return a * b;\n}\nconsole.log(\"The multiplication of 5 is: \" + multiplication(5));\nconsole.log(\"The multiplication of 5 x 2 is: \" + multiplication(5, 2));\n\n// Function inside a function\nfunction dotProduct(...args) {\n    let sum = 0;\n    function squareFactors(n) { \n        return n * n;\n    }\n    for (let i = 0; i < args.length; i++) {\n        sum += squareFactors(args[i]);\n    }\n    return sum**0.5;\n}\nconsole.log(\"The sum of the square factors is: \" + dotProduct(1, 2, 3, 4, 5));\n\n// Functions pre-stablished\n// parseInt\nconsole.log(typeof parseInt(\"10\")); // number\n// push, pop, shift, unshift\narray.push(6);\nconsole.log(array); // [1, 2, 3, 4, 5, 6]\narray.pop();\nconsole.log(array); // [1, 2, 3, 4, 5]\narray.shift();\nconsole.log(array); // [2, 3, 4, 5]\narray.unshift(1);\nconsole.log(array); // [1, 2, 3, 4, 5]\n// toUpperCase, toLowerCase\nconsole.log(author.toUpperCase()); // KRONSTADT-LAMBDA\nconsole.log(author.toLowerCase()); // kronstadt-lambda\n\n// Local and global variables\nlet global = \"World\";\nfunction greetings() {\n    let local = \"Hello \";\n    console.log(local + global + \"!\"); // access to local and global variables\n}\ngreetings();\ntry {\n    console.log(local); // This line throws an error\n} catch (error) {\n    console.error(\"Error: variable\" + error.message); // Catch the error and show a message\n}\n\n/**\n * Extra exercise\n * Create a function that takes two string parameters and returns a number.\n * - The function prints all numbers from 1 to 100. Considering that:\n * - If the number is a multiple of 3, it displays the string of the first parameter.\n * - If the number is a multiple of 5, it displays the string of the second parameter.\n * - If the number is a multiple of 3 and 5, it displays the two strings of text concatenated.\n * - The function returns the number of times the number has been printed instead of the texts.\n */\n\nfunction printNumbers(text1, text2) {\n    let count = 0;\n    for (let i = 1; i <= 100; i++) {\n        switch (true) {\n            case i % 3 === 0 && i % 5 === 0:\n                console.log(text1,\" and \", text2);\n                break;\n            case i % 3 === 0:\n                console.log(text1);\n                break;\n            case i % 5 === 0:\n                console.log(text2);\n                break;\n            default:\n                console.log(i);\n                count++;\n                break;\n        }\n    }\n    return count;\n}\nconsole.log(\"The number of times the NUMBER has been printed is: \" + printNumbers(\"multiple of three\", \"multiple of five\"));\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/LMedina96.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\nconst a = 2\nconst b = 4\nconst arrayValues = ['Hola Mundo', 'Soy un Array', 2024]\n\n//Funcion normal sin parametros\nfunction saludar() {\n    console.log('Funcion normal sin parametros: Hola Mundo')\n}\nconsole.log()\n\n//Función normal con parametros\nfunction sumarParams(a, b) {\n    console.log('Funcion normal sin return: ',a + b);\n}\nsumarParams(a, b)\nconsole.log()\n\n//Funcion normal con return\nfunction sumarReturn(a, b) {\n    return a + b\n}\nconsole.log('Funcion normal con return: ', sumarReturn(a, b))\nconsole.log()\n\n//arrow function sin parametros\nconst arrowSaludo = () => {\n    console.log('Function arrow sin parametros: Hola Mundo')\n}\narrowSaludo()\nconsole.log()\n\n//Arrow function con parametros\nconst arrowSumarParams = (a, b) => {\n    console.log('Funcion normal sin return: ',a + b);\n}\narrowSumarParams(a, b)\nconsole.log()\n\n//Arrow function con return\nconst arrorSumarReturn = (a, b) => {\n    return a + b\n}\nconsole.log('Funcion normal con return: ', arrorSumarReturn(a, b))\nconsole.log()\n\n//Función dentro de otra función\nconst externFunction = () => {\n    const internFunction = () => {\n        console.log('Esta es una función dentro de otra función')\n    }\n    internFunction()\n}\nexternFunction()\nconsole.log()\n\n//Ejemplos de funciones ya creadas\nconsole.log('Función length(): ', arrayValues.length)\nconsole.log('Función toString(): ', arrayValues.toString())\nconsole.log('Función reverse(): ', arrayValues.reverse())\nconsole.log()\n\n//Variables Locales y Globales\nconst varGlobal = 'Hola Variable Global'\n\nconst callVarGlobal = () => {\n    console.log('Puedo llamar a la variable Global: ', varGlobal)\n}\ncallVarGlobal()\n\nconst varLocal = () => {\n    const varLocal = 'Hola Variable Local'\n}\nconsole.log('No puedo llamar a la variable Local: ', varLocal)\nconsole.log()\n\n//Dificultad Extra:\n\n/* \n    * DIFICULTAD EXTRA (opcional):\n    * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n    * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n    *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n    *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n    *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n    *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos. \n*/\n\nconst string1 = 'Soy la primer cadena'\nconst string2 = 'Soy la segunda cadena'\n\nconst extraDifficult = (string1, string2) => {\n    let numbers = []\n\n    for (let i = 0; i <= 100; i++) {\n        i % 3 == 0 && i % 5 == 0 ? console.log(string1.concat(' ', string2)) :\n        i % 3 == 0 ? console.log(string1) :\n        i % 5 == 0 ? console.log(string2) :\n        numbers.push(i)\n    }\n\n    return numbers\n}\n\nconsole.log(extraDifficult(string1, string2))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/LauraCastrillonMp.js",
    "content": "// Función sin parámetros ni retorno\nfunction sayHello() {\n  console.log(\"Hola, mundo!\");\n}\n\n// Función con un parámetro y retorno\nfunction square(number) {\n  return number * number;\n}\n\n// Función con varios parámetros y retorno\nfunction calculateSum(a, b) {\n  return a + b;\n}\n\n// Función anidada dentro de otra función\nfunction outerFunction() {\n  function innerFunction() {\n    console.log(\"Función interna\");\n  }\n\n  innerFunction();\n}\n\n// Ejemplo de función predefinida en JavaScript\nlet arr = [1, 2, 3, 4, 5];\nlet sum = arr.reduce(function (accumulator, currentValue) {\n  return accumulator + currentValue;\n});\n\n// Variable global\nlet globalVariable = \"Soy una variable global\";\n\n// Función que accede a una variable global\nfunction accessGlobalVariable() {\n  console.log(globalVariable);\n}\n\nsayHello(); // Imprime \"Hola, mundo!\"\nconsole.log(square(5)); // Imprime 25\nconsole.log(calculateSum(2, 3)); // Imprime 5\nouterFunction(); // Imprime \"Función interna\"\nconsole.log(sum); // Imprime 15\naccessGlobalVariable(); // Imprime \"Soy una variable global\"\n\n// EJERCICIO EXTRA\nfunction printNumbersWithTexts(text1, text2) {\n  let count = 0;\n\n  for (let i = 1; i <= 100; i++) {\n    if (i % 3 === 0 && i % 5 === 0) {\n      console.log(text1 + text2);\n      count++;\n    } else if (i % 3 === 0) {\n      console.log(text1);\n      count++;\n    } else if (i % 5 === 0) {\n      console.log(text2);\n      count++;\n    }\n  }\n\n  return count;\n}\n\nconsole.log(printNumbersWithTexts(\"Fizz\", \"Buzz\"));\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/Magupe09.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n\n\n// FUNCIONES SIN PARAMETRO NI RETORNO\nfunction saludar(){\n    console.log(\"Hola soy Mauricio y cada dia soy un mejor programador\")\n}\n\nsaludar();// de esta manera invoco la funcion sin algumentos ni retorno .\n\n\nfunction mostrarFecha() {\n    let fecha = new Date();\n    console.log(`La fecha y hora actual es: ${fecha}`);\n}\n\n// Llamada a la función\nmostrarFecha();\n\n//------ \n\n//FUNCIONES CON RETORNO\n\nfunction sumar(a, b) {\n    return a + b;\n}\n\n// Llamada a la función\nlet resultado = sumar(3, 4);\nconsole.log(\"La suma es:\", resultado);  // La suma es: 7\n\n\nfunction dobleDelNumero(numero){\n    return numero*2;\n}\n\nconsole.log(dobleDelNumero(5));// 10\n\n\n//--------\n\n//FUNCIONES CON UN PARAMETRO Y VARIOS PARAMETROS\n\n\nfunction esMayorDeEdad(edad){\n    if(edad < 18){\n        console.log(\"Eres menor de edad No puedes ingresar a este antro\");\n    }else{\n        console.log(\"Bienvenid@ a este club\");\n    }\n\n}\nesMayorDeEdad(16);\n\nfunction sumarVariosNumeros(a,b,c){\n    return resultado= a+b+c;\n}\nconsole.log(sumarVariosNumeros(2,5,6))\n\n\n\n\n// COMPROVAMOS SI PODEMOS CREAR UNA FUNCION DENTRO DE OTRA FUNCION\n\n\nfunction funcionExterna(a,b){\n    function funcionInterna(){\n        console.log(\"La suma de los valores es :\", a+b)\n    }\n\n    funcionInterna();   // Esta es la llamada a ejecucion de la funcion interna.\n}\n\nfuncionExterna(2,2);// Desde fuera la unica funcion que se ejecuta es la externa.\n\n\n// PONIENDO A PRUEBA EL CONCEPTO DE VARIABLE LOCAL Y VARIABLE GLOBAL\n\nlet edad = 20; // Variable de alcanze global\n\nfunction mayorDeEdad(edad){\n    let nombre= \"Mauricio\"; // variable de alcanze local, quiere decir que solo la puedo utilizar dentro de esta funcion.\n    if(edad > 18){ // Aqui justo leo la variable declarada en el scop global \n        console.log(\"ERES MAYOR DE EDAD\",nombre); \n    }\n\n    console.log(nombre,\"ESTOY DENTRO\")// Aqui si que funcion ESTOY DENTRO DE LA FUNCION\n\n}\nmayorDeEdad(edad);\n// vamos a comprobar que la variable nombre no puede leerse desde fuera.\nconsole.log(edad)\n// console.log(nombre)// Esto ejecuta un error en consola diciendo que no se puede ejecutar por que no esta definida \n\n\n/*\n* DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n\nfunction numeroDeVecesIngresadoEnLugarDeLosTextos(a,b){\n    let contador=0;\n    for(let i=1;i <= 100;i++)\n        {\n\n          if(i % 3 === 0 && i % 5 === 0)\n            {\n                console.log(a+b,\"soy multiplo de los 2\",i)\n            \n           }else if(i % 5 === 0)\n            {\n                console.log(b)\n            }else if(i % 3 === 0)\n                {\n                    console.log(a,\"soy multiplo de 3\",i);\n                    \n                }else\n                {\n                    contador= contador+1;\n                    \n                }\n        }\n         \n       \n    \n    return console.log(contador);\n    \n}\n\nnumeroDeVecesIngresadoEnLugarDeLosTextos(\"string1\",\"string2\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/MarcosLombardo.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n// Funciones\n\n// Función sin parámetros\nconsole.log(\"Función sin parámetros:\");\n\nfunction holaMundo() {\n  return \"Hola Mundo!\";\n}\n\nlet hello = holaMundo(); // Devuelve \"Hola Mundo!\"\nconsole.log(hello);\n\n// Función con un parámetro\nconsole.log(\"Función con un parámetro:\");\n\nfunction saludar(name) {\n  return \"Hola \" + name + \"!\";\n}\n\nlet saludo = saludar(\"Marcos\"); // Devuelve \"Hola Marcos!\"\nconsole.log(saludo);\nlet saludo2 = saludar(); // Devuelve \"Hola undefined!\"\nconsole.log(saludo2);\n\n// Función con dos parámetros\nconsole.log(\"Función con dos parámetros:\");\n\nfunction suma(a, b) {\n  return a + b;\n}\n\nlet resultado = suma(5, 9); // Devuelve 14\nconsole.log(resultado);\n\n// Función con parámetros por defecto\nconsole.log(\"Parámetros por defecto:\");\n\nfunction nuevoSaludo(tipo, nombre) {\n  var tipo = tipo || \"Hola\";\n  var nombre = nombre || \"JavaScript\";\n  return tipo + \" \" + nombre + \"!\";\n}\n\nlet bienvenida = nuevoSaludo(); // Devuelve \"Hola JavaScript!\"\nlet despedida = nuevoSaludo(\"Adiós\"); // Devuelve \"Adiós JavaScript!\"\nlet hola = nuevoSaludo(\"Hola\", \"Marcos\"); // Devuelve \"Hola Marcos!\"\nconsole.log(bienvenida);\nconsole.log(despedida);\nconsole.log(hola);\n\n// Ámbitos de una función\nconsole.log(\"Ámbito de una función:\");\n\nlet valor = \"global\";\n\nfunction funcionLocal() {\n  let valor = \"local\";\n  return valor;\n}\n\nconsole.log(valor); // \"global\"\nconsole.log(funcionLocal()); // \"local\"\nconsole.log(valor); // \"global\"\n\n// Funciones anidadas\nconsole.log(\"Función anidada:\");\n\nlet a = \"Hola, \";\n\nfunction global() {\n  let b = \"Qué \";\n\n  function local() {\n    let c = \"tal?\";\n    return a + b + c;\n  }\n\n  return local();\n}\n\nglobal();\n\nlet saludando = global(); // Devuelve \"Hola, Qué tal?\"\nconsole.log(saludando);\n\n// Dificultad extra\n\nfunction extra(string1, string2) {\n  let contador = 0;\n\n  for (let i = 1; i <= 100; i++) {\n    if (i % 3 === 0 && i % 5 === 0) {\n      console.log(string1 + string2);\n      contador++;\n    } else if (i % 3 === 0) {\n      console.log(string1);\n      contador++;\n    } else if (i % 5 === 0) {\n      console.log(string2);\n      contador++;\n    }\n  }\n  return contador;\n}\n\nconsole.log(extra(\"Cielo\", \"Razzo\"));\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/MatiTC.js",
    "content": "//#02 FUNCIONES Y ALCANCE\n//Algunas de las funciones son las siguientes:\n\n//1. Sin parámetros ni retorno\nfunction saludar(){\n    console.log(\"Hola mundo!\"); // imprime: \"Hola mundo!\"\n}\nsaludar();\nconsole.log(`.........................................`);\n\n//2. Con uno o varios parámetros:\nfunction unaVariableSinRetorno(a){\n    console.log(\"El resultado es: \" + a) \n}\nfunction dosVariablesSinRetorno(a, b){\n    console.log(\"El resultado es: \" + (a + b)); \n}\nunaVariableSinRetorno(2) //imprime: El resultado es: 2\ndosVariablesSinRetorno(2, 2) //imprime: El resultado es: 4\nconsole.log(`.........................................`);\n\n//3. Con retorno\nfunction conRetorno(a , b){\n    return (a * b);\n}\nlet resultado = conRetorno(2, 3)\nconsole.log(\"El resultado es: \" + resultado); // imprime: El resultado es: 6\nconsole.log(`.........................................`);\n\n//4. Funciones con parámetros por defecto:\nfunction saludarDefault(nombre = \"usuario\") {\n    console.log(`¡Hola, ${nombre}!`);\n}\nsaludarDefault(\"Matias\")  // imprime: \"¡Hola. Matias!\"\nconsole.log(`.........................................`);\n\n//5. Función flecha con argumentos\nlet sumaFlecha = (a, b) => a + b;\nlet resultadoFlecha = sumaFlecha(10, 20);\nconsole.log(\"El resultado es: \" + resultadoFlecha) // imprime: El resultado es: 30\nconsole.log(`.........................................`);\n\n//6. Función que imprime un saludo\nlet saludarFlecha = () => {\n    console.log(\"Soy una función flecha sin argumentos\");\n};\nsaludarFlecha(); // imprime: Soy una función flecha sin argumentos\nconsole.log(`.........................................`);\n\n//Función dentro de otra función\nfunction funcionGrande(num){\n    console.log(\"El numero es \", num) // imprime: El numero es: num\n    unaVariableSinRetorno(num)// imprime: El resultado es: num\n    console.log(`Multiplicaremos el numero ${num} por 3`); // imprime: Sumaremos en numero num con el 1;\n    let multiplicacion = conRetorno(num, 3);\n    function doble() {\n        return multiplicacion * 2;\n    }\n    let resultadoDoble = doble();\n    return(resultadoDoble);\n}\nlet resultadoFuncionGrande = funcionGrande(7)\nconsole.log(resultadoFuncionGrande);// imprime: 42\nconsole.log(`.........................................`);\n\n//Concepto de variable LOCAL y GLOBAL.\nlet variableGlobal = \"Soy global\";\n\nfunction variables(){\n    let variableLocal = \"Soy local\"\n    console.log(variableGlobal); // Accede a la variable global desde fuera\n    console.log(variableLocal); // Accede a la variable local desde la propia funcion\n\n    variableGlobal = \"Soy la variableGlobal que esta siendo modificada\"\n}\nvariables();\nconsole.log(variableGlobal);\n//console.log(variableLocal) <--error puesto que esta definida dentro de la funcion variables\nconsole.log(`.........................................`);\n\n//DIFICULTAD EXTRA (opcional):\nfunction dificultadExtra(texto1, texto2) {\n    let contador = 0;\n    for (let i = 1; i <= 100; i++) {\n      if (i % 3 === 0 && i % 5 === 0) {\n        console.log(texto1 + texto2);\n      } else if (i % 3 === 0) {\n        console.log(texto1);\n      } else if (i % 5 === 0) {\n        console.log(texto2);\n      } else {\n        console.log(i);\n      }\n  \n      contador++;\n    }\n    return contador;\n  }\n  \n  // Ejemplo de uso\n  const extra = dificultadExtra(\"Mizz \", \"Frizz\");\n  console.log(\"Número de veces que se ha impreso: \" + extra); //Imprime mucho xd\n  "
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/Matiascba27.js",
    "content": "// Funciones y Alcance\n// Funcion sin parametro ni retorno\nfunction saludar() {\n    console.log(\"Hola, Javascript!\")\n}\n\nsaludar();\n\n// Funcion con un parametro y sin retorno\nfunction saludarPersona(nombre) {\n    console.log(`Hola, ${nombre} bienvenido!`);\n}\n\nsaludarPersona(\"Matias\");\n\n// Funcion con varios parametros y con retorno\nfunction sumar(a, b) {\n    return a + b;\n}\n\nlet resultado = sumar(5, 10);\nconsole.log(\"El resultado es:\", resultado);\n\n// Uso de una funcion ya creada en el lenguaje\nfunction usarFuncionExistente() {\n    let numeros = [1, 2, 3, 4, 5];\n    console.log(Math.max(...numeros));\n}\n\nusarFuncionExistente();\n\n// Funciones dentro de funciones\nfunction operacionMatematica(a, b) {\n    function multiplicar(x, y) {\n        return x * y;\n    }\n    return multiplicar(a, b) + 10;\n}\n\nconsole.log(operacionMatematica(5, 10));\n\n// Variable local y global\nlet variableGlobal = \"Soy una variable global\";\n\nfunction ejemploVariables() {\n    let variableLocal = \"Soy una variable local\";\n    console.log(variableLocal);\n    console.log(variableGlobal);\n}\n\nejemploVariables();\n\n// Dificultad extra\nconsole.log(\"------------Dificultad extra-----------\");\nfunction fizzBuzz(text1, text2) {\n    let contador = 0;\n    for (let i= 1; i <= 100; i++) {\n        if (i % 3 === 0) {\n            console.log(text1);\n        } else if (i % 5 === 0) {\n            console.log(text2);\n        } else if (i % 3 === 0 && i % 5 === 0) {\n            console.log(text1 + text2);\n        } else {\n            console.log(i);\n            contador++;\n        }\n    }\n    return contador;\n}\n\nconsole.log(fizzBuzz(\"Fizz\", \"Buzz\"));"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/MiguelAngelEc.js",
    "content": "\nlet contador1 = 0;\nlet contador2 = 0;\nlet contador3 = 0;\n\nfunction text(text1, text2) {\n    for (let i = 0; i <= 100; i++) {\n        switch (true) {\n            case i % 3 === 0 && i % 5 === 0:\n                contador3 +=1;\n                console.log(text1 + \" \" + text2);\n                break;\n            case i % 3 === 0:\n                contador2 +=1;\n                console.log(text1);\n                break;\n            case i % 5 === 0:\n                contador1 +=1;\n                console.log(text2);\n                break;\n            default:\n                console.log(i);\n                break;\n        }\n    }\n}\n\ntext(\"Hola\", \"Mundo\");\nconsole.log(`El numero de veces que se imprimio Hola es: ${contador1}`);\nconsole.log(`El numero de veces que se imprimio Mundo es: ${contador2}`);\nconsole.log(`El numero de veces que se imprimio Hola Mundo es: ${contador3}`);\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/MiguelAngelMTZ000414.js",
    "content": "console.log(`----------(◉◉∖____/◉◉)---------- Functions ----------(OO∖____/OO)----------\n\n    Ejemplos de funciones básicas que representa JavaScript:\n    -- Sin parámetros ni retorno, \n    -- Con uno o varios parámetros, \n    -- Y con retorno...\n    `\n)\n\n// Declaramos la funcion sin parametros\nfunction ejemplo_1(){\n    // Imprimiendo por consola\n    console.log(\"-. Este es un ejemplo de una función sin paremetros, ni return, imprimiendo por consola.\")\n} \nejemplo_1() // Llamando a la función\n\n// Declaramos la función con un solo paremetro/argumento\nfunction ejemplo_2(paremetro_String){\n    // Imprimiendo por consola al parametro \"paremetro_String\"\n    console.log(paremetro_String)\n}\nejemplo_2(\"-. Este es un ejemplo de una funcion con un solo parametro de tipo 'String', imprimiendo por consola.\") // Llamando a la función\n\n// Declaramos la función con dos paremetro/argumento\nfunction ejemplo_3(parametro_String, parametro_Number){\n    // Imprimiendo por consola los dos parametro \"paremetro_String\" y \"parametro_Numbre\"\n    console.log(\"-. Este es un ejemplo de una funcion con dos parametro de tipo 'String' y 'Number', imprimiendo por consola.\", parametro_String + \" \" + parametro_Number)\n}\nejemplo_3(\"McLaren W1\", 2024) // Llamando a la función\n\n// Declaramos la función con tres parametros/argumento\nfunction ejemplo_4(parametro_String, parametro_Number, parametroString) {\n    // Usamos return para devolver el valor\n    return `-. Este es un ejemplo de una funcion con tres parametro de tipo 'String', 'Number' y 'String', usando 'return' palabra reservada. ${parametro_String}, ${parametro_Number}, ${parametroString}`\n}\nconsole.log(ejemplo_4(\"Porsche\", 918, \"Spyder\")) // Mandamos a llamar por consola la función\n\n// Declaramos la función con dos paremetro/argumento\nfunction ejemplo_5(parametro_String, parametro_Number){\n    // Imprimiendo por consola los dos parametro \"paremetro_String\" y \"parametro_Numbre\"\n    console.log(\"-. Este es un ejemplo de una funcion con dos parametro de tipo 'String' y 'Number', imprimiendo por consola.\", parametro_String + \" \" + parametro_Number)\n}\nejemplo_3(2024, \"McLaren W1\") // Llamando a la función\n\n// Declaramos la función con tres parametros/argumento\nfunction ejemplo_6(parametro_Number, parametroNumber) {\n    // Usamos return para devolver el valor\n    return `-. Este es un ejemplo de una funcion con dos parametros de tipo 'Number', usando 'return' palabra reservada. Sumando ${parametro_Number} + ${parametroNumber} = ${parametro_Number + parametroNumber}`\n}\nconsole.log(ejemplo_6(918, 82)) // Mandamos a llamar a la función por consola \n\n// Declaramos la función con dos parametros/argumentos predeterminados\nfunction ejemplo_7(parametro_Number = 100, parametroNumber = 76) {\n    // Usamos return para devolver el valor\n    return `-. Este es un ejemplo de una funcion con dos parametros predeterminados de tipo 'Number', usando 'return' palabra reservada. Sumando ${parametro_Number} - ${parametroNumber} = ${parametro_Number - parametroNumber}`\n}\nconsole.log(ejemplo_7()) // Mandamos a llamar a la función por consola \n\nlet parametroNumber_1 = 24\nlet parametroNumber_2 = 10\n// Declaramos la función con dos parametros/argumentos predeterminados\nfunction ejemplo_8(parametro_Number_1, parametro_Number_2) {\n    // Usamos return para devolver el valor\n    return `-. Este es un ejemplo de una funcion con dos parametros predeterminados de tipo 'Number', usando 'return' palabra reservada. Sumando ${parametro_Number_1} x ${parametro_Number_2} = ${parametro_Number_1 * parametro_Number_2}`\n}\nconsole.log(ejemplo_8(parametroNumber_1, parametroNumber_2)) // Mandamos a llamar a la función por consola \n\nconsole.log(`----------(◉◉∖____/◉◉)---------- Functions ----------(OO∖____/OO)----------\n\n    - Comprobar si se puede crear funciones dentro de funciones.\n    function name(params) {\n        function name(params) {\n        \n        }\n    }\n    `\n)\n// Declaramos la función \"funcionInterno()\", con un argumento\nfunction funcionInterno(a) { // Funcion Principal/Padre\n    \n    function functionExterno(b) { // Funcion anidada/Hijo\n        /* La funcion \"functionExterno()\" toma el argumento que se le pasa a la función \"functionInterno(5)\".\n           Para posteriormente SUMAR el argumento(5) x  2 */\n        return b * 2 // Retorna: 10\n    }\n    /* Retornamos la función \"functionExterno(), la cual hara la suma 10 + 3 = 13 \" */\n    return functionExterno(a) + 3\n}\nconsole.log(\"El resultado de la funcion es: \" + funcionInterno(5)) // Salida: 13\n\nconsole.log(`----------(◉◉∖____/◉◉)---------- Predefined Functions ----------(OO∖____/OO)----------\n\n    - Utilizando algúnos ejemplos de funciones ya creadas en el lenguaje.\n\n    - ⭐substring  - codePointAt    - normalize     - toString\n    - ⭐indexOf    - concat         - padEnd        - toUpperCase\n    - ⭐lenght     - endsWith       - padStart      - trim\n    - ⭐split      - includes       - repeat        - trimEnd\n    - ⭐replace    - lastIndexOf    - repeatAll     - trimStart\n    - at           - localeCompare   - slice         - valueOf\n    - chartAt      - match           - startsWith    \n    - charCodeAt   - matchAll        - toLowerCase   \n    `\n)\nconsole.log(\"-------------------------------- substring() --------------------------------\")\nlet funcion_1 = \"Miguel Angel\"\nconsole.log(funcion_1)\nconsole.log(funcion_1.substring(1, 8))\n\nconsole.log(\"-------------------------------- indexOf() --------------------------------\")\nlet funcion_2 = \"McLaren Ferrari Lamborghini Porsche\"\nconsole.log(funcion_2)\nconsole.log(funcion_2.indexOf(\"Ferrari\"))\n\nconsole.log(\"-------------------------------- lenght() --------------------------------\")\nlet funcion_3 = \"McLaren Ferrari Lamborghini Porsche\"\nconsole.log(funcion_3)\nconsole.log(funcion_3.length)\n\nconsole.log(\"-------------------------------- split() --------------------------------\")\nlet funcion_4 = \"1,2,3,4,5,6,7,8,9,10\"\nconsole.log(`Cadenas de texto \"1,2,3,4,5,6,7,8,9,10\" ${typeof funcion_4}`)\nfuncion_4_1 = funcion_4.split(\",\")\nconsole.log(funcion_4_1)\nconsole.log(typeof funcion_4_1)\n\nconsole.log(\"-------------------------------- replace() --------------------------------\")\nlet funcion_5 = \"ASPHATL LEGENDS 9\"\nconsole.log(funcion_5)\nconsole.log(funcion_5.replace(\"9\", \"Unite\"))\n\nconsole.log(\"-------------------------------- at() --------------------------------\")\nlet funcion_6 = \"When Love Takes Over\"\nconsole.log(funcion_6)\nconsole.log(funcion_6.at(0))\nconsole.log(funcion_6.at(1))\nconsole.log(funcion_6.at(2))\nconsole.log(funcion_6.at(3))\n\nconsole.log(\"-------------------------------- chartAt() --------------------------------\")\nlet funcion_7 = \"Ooh Ahh (My Life Be Like)\"\nconsole.log(funcion_7)\nconsole.log(funcion_7.charAt(0))\nconsole.log(funcion_7.charAt(1))\nconsole.log(funcion_7.charAt(2))\n\nconsole.log(\"-------------------------------- charCodeAt() --------------------------------\")\nlet funcion_8 = \"Entro dos tierras\"\nconsole.log(funcion_8)\nconsole.log(funcion_8.charCodeAt())\n\nlet funcion_8_1 = funcion_8.charCodeAt(funcion_8.length-1)\nconsole.log(funcion_8_1)\n\nconsole.log(\"-------------------------------- codePointAt() --------------------------------\")\nlet funcion_9 = \"Entro dos tierras\"\nconsole.log(funcion_9)\nconsole.log(funcion_9.codePointAt(1))\nlet funcion_9_1 = \"Hola\"\nconsole.log(funcion_9_1)\nconsole.log(funcion_9_1.codePointAt(1))\n\nconsole.log(\"-------------------------------- concat() --------------------------------\")\nlet funcion_10_1 = \"Hola\"\nlet funcion_10_2 = \"Developer\"\nconsole.log(funcion_10_1)\nconsole.log(funcion_10_2)\nconsole.log(funcion_10_1.concat(\", \", funcion_10_2))\n\nconsole.log(\"-------------------------------- endsWith() --------------------------------\")\nlet funcion_11_1 = \"¿Cual es tu coche deportivo favorito?\"\nlet funcion_11_2 = \"Hola JavaScript!\"\nconsole.log(funcion_11_1)\nconsole.log(funcion_11_1.endsWith(\"favorito?\"))\nconsole.log(funcion_11_1.endsWith(\"favorito\"))\nconsole.log(funcion_11_1.endsWith(\"favorito\", 12))\nconsole.log(funcion_11_2)\nconsole.log(funcion_11_2.endsWith(\"JavaScript!\"))\nconsole.log(funcion_11_2.endsWith(\"JavaScript\"))\nconsole.log(funcion_11_2.endsWith(\"JavaScript\", 13))\n\nconsole.log(\"-------------------------------- includes() --------------------------------\")\nlet funcion_12 = \"The Beloved - Sweet Harmony\"\nconsole.log(funcion_12)\nconsole.log(funcion_12.includes(\"The\"))\nconsole.log(funcion_12.includes(\"Beloved\"))\nconsole.log(funcion_12.includes(\"-\"))\nconsole.log(funcion_12.includes(\"Sweet\"))\nconsole.log(funcion_12.includes(\"Harmony\"))\nconsole.log(funcion_12.includes(\"Ford\"))\n\nconsole.log(\"-------------------------------- lastIndexOf() --------------------------------\")\nlet funcion_13 = \"Hard to Say Im Sorry\"\nconsole.log(funcion_13)\nconsole.log(funcion_13.lastIndexOf(\"H\", 0))\nconsole.log(funcion_13.lastIndexOf(\"a\", 1))\nconsole.log(funcion_13.lastIndexOf(\"r\", 2))\nconsole.log(funcion_13.lastIndexOf(\"d\", 3))\nconsole.log(funcion_13.lastIndexOf(\"Sorry\"))\n\nconsole.log(\"-------------------------------- localeCompare() --------------------------------\")\nlet funcion_14_1 = \"Vivo V2050\"\nlet funcion_14_2 = \"Vivo X200 Pro\"\nconsole.log(`${funcion_14_1}, ${funcion_14_2}`)\nconsole.log(funcion_14_2.localeCompare(funcion_14_1)) // 1\nconsole.log(funcion_14_1.localeCompare(funcion_14_2)) // -1\nconsole.log(funcion_14_1.localeCompare(funcion_14_1)) // 0\n\nconsole.log(\"-------------------------------- match() --------------------------------\")\nlet funcion_15 = \"A Horse With No Name\"\nlet funcion_15_1 = /[A-Z]/g // La gbandera es para búsqueda global, lo que significa que esta bandera indica que probamos la expresión regular contra todas las coincidencias en la cadena.\nconsole.log(funcion_15)\nconsole.log(funcion_15.match(funcion_15_1))\n\n\nconsole.log(\"-------------------------------- matchAll() --------------------------------\")\nlet abecedario = \"abcdefghijklm\"\nlet regexp = /[a-m]/g // Expresión regular\nlet iterador = abecedario.matchAll(regexp)\nresultado = Array.from(iterador)\nconsole.log(resultado)\n\nconsole.log(\"-------------------------------- normalize() --------------------------------\")\nlet name1 = '\\u0041\\u006d\\u00e9\\u006c\\u0069\\u0065';\nlet name2 = '\\u0041\\u006d\\u0065\\u0301\\u006c\\u0069\\u0065';\nconsole.log(`${name1}, ${name2}`) // Expected output: \"Amélie, Amélie\"\nconsole.log(name1 === name2); // false\nconsole.log(name1.length === name2.length); // false\n\nlet name1NFC = name1.normalize('NFC');\nlet name2NFC = name2.normalize('NFC');\nconsole.log(`${name1NFC}, ${name2NFC}`); // \"Amélie, Amélie\"\nconsole.log(name1NFC === name2NFC); // true\nconsole.log(name1NFC.length === name2NFC.length) // true\n\nconsole.log(\"-------------------------------- padEnd() --------------------------------\")\nlet funcion_16 = \"Time Wont Let Me Go\"\nconsole.log(funcion_16)\nconsole.log(funcion_16.length)\nconsole.log(funcion_16.padEnd(24, \".\"))\nconsole.log(funcion_16.padEnd(24, \".\").length)\n\nconsole.log(\"-------------------------------- padStart() --------------------------------\")\nlet funcion_17 = \"10\"\nconsole.log(funcion_17)\nconsole.log(funcion_17.length)\nconsole.log(funcion_17.padStart(10, \"0\"))\nconsole.log(funcion_17.padStart(10, \"0\").length)\n\nconsole.log(\"-------------------------------- repeat() --------------------------------\")\nlet funcion_18 = \"Dinero \"\nconsole.log(funcion_18)\nconsole.log(funcion_18.repeat(5))\n\nconsole.log(\"-------------------------------- replaceAll() --------------------------------\")\nlet funcion_19 = \"01, 02, 03, 04, 05, 06, 07, 08, 09\"\nconsole.log(funcion_19)\nconsole.log(funcion_19.replaceAll(\"0\", \"1\"))\nconsole.log(funcion_19.replaceAll(\"0\", \"2\"))\nconsole.log(funcion_19.replaceAll(\"0\", \"3\"))\n\nconsole.log(\"-------------------------------- slice() --------------------------------\")\nlet funcion_20 = \"Goodbye Angels\"\nconsole.log(funcion_20)\nconsole.log(funcion_20.length)\nconsole.log(funcion_20.slice(0, 4))\nconsole.log(funcion_20.slice(4, 7))\nconsole.log(funcion_20.slice(8))\n\nconsole.log(\"-------------------------------- startsWith() --------------------------------\")\nlet funcion_21 = \"Apuesta por el rock 'n' roll\"\nconsole.log(funcion_21)\nconsole.log(funcion_21.startsWith(\"Apuesta\"))\nconsole.log(funcion_21.startsWith(\"Apuesta\", 24))\nconsole.log(funcion_21.startsWith(\"Apuesta por\"))\nconsole.log(funcion_21.startsWith(\"por\"))\n\nconsole.log(\"-------------------------------- toLowerCase() --------------------------------\")\nlet funcion_22 = \"ASPHATL LEGENDS UNITE\"\nconsole.log(funcion_22)\nconsole.log(funcion_22.toLowerCase())\n\nconsole.log(\"-------------------------------- toString() --------------------------------\")\nlet funcion_23 = [\"Uno\", \"Dos\", \"Tres\", \"Cuatro\", \"Cinco\"] // Array\nconsole.log(funcion_23)\nconsole.log(funcion_23.toString())\n\nconsole.log(\"-------------------------------- toUpperCase() --------------------------------\")\nlet funcion_24 = \"habia una vez en el espacio\"\nconsole.log(funcion_24)\nconsole.log(funcion_24.toUpperCase())\n\nconsole.log(\"-------------------------------- trim() --------------------------------\")\nlet funcion_25 = \" Miguel Angel Martinez \"\nconsole.log(`\" ${funcion_25} \" con espacios al principio y al final.`)\nconsole.log(`,${funcion_25.trim()}, con trim() quitamos los espacios en blanco del principio y final`)\n\nconsole.log(\"-------------------------------- trimEnd() --------------------------------\")\nlet funcion_26 = \" Stupid Love Story \"\nconsole.log(`\" ${funcion_26} \"`)\nconsole.log(`,${funcion_26.trimEnd()},`)\n\nconsole.log(\"-------------------------------- trimStart() --------------------------------\")\nlet funcion_27 = \" Niño del recreo feat El M Beats \"\nconsole.log(`\" ${funcion_27} \"`)\nconsole.log(`,${funcion_27.trimStart()},`)\n\nconsole.log(`----------(◉◉∖____/◉◉)---------- Variables LOCAL y GLOBAL ----------(OO∖____/OO)----------\n    `\n)\nlet variableGlobal = \"hola\"\nfunction Ejemplo() {\n    let variableLocal = \"Hola\"\n    return variableLocal\n}\nconsole.log(variableGlobal)\n// console.log(variableLocal)  Esto es una variable Local, significa que no se puede imprimir\n\nconsole.log(`----------(◉◉∖____/◉◉)---------- Ejercicio Extra ----------(OO∖____/OO)----------\n    Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n        - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n        - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n        - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n        - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n        - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n    `\n)\n// Tambien llamado Fizz Buzz\n// Definimos la función con dos parametros.\nfunction Rango_1_100(Uno, Cien) {\n    // La variable \"contador\" se inicializara en 0, permitiendo que podamos imprimir el numero total de las veces que se han imprimido los numeros, pero no con los textos \n    let contador = 0\n    for (let i = 0; i <= 100; i++) {\n        // Condición (Si): comprobamos si los número del 1 al 100 son multiplos de 3 y 5 \n        if (i % 3 == 0 && i % 5 == 0) {\n            console.log(Uno + \" y \" + Cien) // Imprimimos por consola el resultado de la condición if\n        }else if (i % 3 == 0) { // Condición (Si/No): comprobamos si los números del 1 al 100 son multiplos de 3\n            console.log(Uno) // Imprimimos por consola el resultado de la condución else if\n        }else if (i % 5 == 0) { // Condición (Si/No): comprobamos si los números del 1 al 100 son multiplos de 5\n            console.log(Cien) // Imprimimos el resultado de la condución else if\n        }else { // Condición (No): De no cumplirse algunas de las condiciones anteriores, imprimiremos los números del 1 al 100\n            console.log (i) // Imprimimos por consola los números del 1 al 100\n            contador ++ // Cada vez que se valla imprimiendo los numeros \"console.log(i)\", con \"contador\" incrementamos 1 para que lo cuente\n        }\n    }\n    // Al acabar el bucle for retornamos \"contador\"\n    return contador\n}\n// Imprimimos por consola el valor de \"contador\", además del resultado de la función\nconsole.log(\"Se han imprimido:\", Rango_1_100(\"Es multiplo de 3\", \"Es multiplo de 5\"))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/MiguelP-Dev.js",
    "content": "//  Variables globales\nlet nombre = \"Miguel\";\nlet edad = 31;\nlet ciudad = \"Medellín\";\n\nconsole.log(nombre, edad, ciudad)\n\n// Variables locales\n{\n    let variableLocal = 3223;\n    console.log(variableLocal);\n}\n\n\n// Declaración de una función \nfunction helloWorld() {\n    console.log(\"¡Hello, World!\");\n}\n\n// Llamada a la función\nhelloWorld()\n\n// Declaración de una función con parámetros\nfunction suma(a, b) {\n    console.log(a + b);\n}\n\n// Llamada a la función\nsuma(2, 3)\n\n// Declaración de una función con parámetros y retorno\nfunction sumaConRetorno(a, b) {\n    return a + b;\n}\n\n// Llamada a la función cin retorno\nconsole.log(sumaConRetorno(2, 3))\n\n// Declaración de una función anónima sin parámetros y retorno\nconst saludoAnonimo = function () {\nconsole.log(\"Hola, Bienvenido a mi función anónima\");\n}\n\n// Llamada a la función anónima\nsaludoAnonimo()\n\n// Declaración de una función anónima con parámetros y retorno\nconst sumaAnonima = function (a, b) {\n    return a + b;\n}\n\n// Llamada a la función anónima con parámetros y retorno\nconsole.log(sumaAnonima(2, 3))\n\n// Declaración de una función flecha sin parámetros y retorno\nconst saludoFlecha = () => {\n    console.log(\"Hola, Bienvenido a mi función flecha\");\n}\n\n// Llamada a la función flecha\nsaludoFlecha()\n\n// Declaración de una función flecha con parámetros y retorno\nconst sumaFlecha = (a, b) => {\n    return a + b;\n}\n\n// Llamada a la función flecha con parámetros y retorno\nconsole.log(sumaFlecha(2, 3))\n\n// Declaración de una función flecha con parámetros y retorno simplificado\nconst sumaFlechaSimplificado = (a, b) => a + b;\n\n// Llamada a la función flecha con parámetros y retorno simplificado\nconsole.log(sumaFlechaSimplificado(2, 3))\n\n// Declaración de una función flecha con un solo parámetro y retorno\nconst cuadrado = (x) => x * x;\n\n// Llamada a la función flecha con un solo parámetro y retorno\nconsole.log(cuadrado(2))\n\n// Declaracion de funciones en objetos\n\nlet persona = {\n    nombre: \"Miguel\",\n    apellido: \"Portillo\",\n    edad: 31,\n    saludar: function () {\n        console.log(`Hola, mi nombre es ${this.nombre} y mi apellido es ${this.apellido} y tengo ${this.edad} años`)\n    }\n}\n\npersona.saludar()\n\n// Nota: En JavaScript, las funciones se pueden declarar dentro de otros objetos, como en el ejemplo anterior. Esto se conoce como \"funciones anidadas\" o \"funciones de ámbito local\".\n// Las funciones anidadas pueden acceder a las variables y funciones del ámbito padre, lo que permite organizar mejor el código y reutilizar partes de código.\n\n// Reglas: \n// 1. Si la función tiene un solo parámetro, se pueden omitir los paréntesis.\n// 2. Si la función tiene un solo sentencia de retorno, se pueden omitir las llaves y la palabra clave return.\n// 3. Usa funciones declaradas para utilidades generales\n// 4. Usa funciones expresión o arrow(flecha) para funciones de callback o funciones de alto nivel\n// 5. Usa funciones flecha para funciones de una sola línea\n// 6. Usa funciones flecha para funciones de una sola línea que no devuelven un objeto\n// 7. Usa funciones flecha para funciones de una sola línea que no devuelven un objeto y que no tienen un solo parámetro\n// 8. Usa funciones flecha para funciones de una sola línea que no devuelven un objeto y que no tienen un solo parámetro y que no tienen un solo sentencia de retorno\n// 9. Usa funciones flecha cuando no se necesita el this\n\n\n\n//  DIFICULTAD EXTRA (opcional):\n//  Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n//  - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n//    - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n//    - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n//    - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n//    - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n// \n//  Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n//  Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n\nfunction EjercicioExtra(text1, text2) {\ncontador = 0;\nfor (let i = 1; i <= 100; i++) {\n    if (i % 15 === 0 ) {\n        console.log(text1 + text2);\n    } else if (i % 3 === 0) {\n        console.log(text1);\n    } else if (i % 5 === 0) {\n        console.log(text2);\n    } else {\n        console.log(i);\n        contador++;\n    }\n}\nreturn contador;\n}\n\n// EjercicioExtra(\"Miguel\", \"Portillo\");\nconsole.log(\"Cantidad de veces que se ha impreso el número en lugar del texto: \" + EjercicioExtra(\"fizz\", \"buzz\"));"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/N1sek.js",
    "content": "//Sin parametros ni return\nfunction holaMundo(){\n    console.log(\"Hola Mundo!\");\n}\nholaMundo();\n\n//Con parametros y return\nfunction concatenaTexto(a, b){\n    return a+b;\n}\nconsole.log(concatenaTexto(\"Hola! Soy \", \"N1sek\"));\n\n//Funcion con varios parametros\nfunction variosParametros(...args){\n    for(let i = 0; i<args.length;i++){\n        console.log(args[i])\n    }\n}\nvariosParametros(1, 2, 3, 4);\n\n//Funciones anidadas\nfunction funcionUno(){\n    console.log(\"Hola desde funcionUno\");\n\n    function funcionDos(){\n        console.log(\"Hola desde funcionDos\")\n    }\n\n    funcionDos(); //Estamos llamando la funcion dos dentro de funcionUno por lo que si funciona\n}\nfuncionUno();\n//funcionDos(); No funcionaria porque solamente existe dentro de funcionUno\n\n//Funcion 'Built-in'\nlet variableNumerica = 2\nlet variableTexto = \"Hola\"\nconsole.log(\"variableNumerica: \" + typeof(variableNumerica) + \" variableTexto: \" + typeof(variableTexto))\n\n//Variable global\nlet global = \"Soy una variable global\"\nfunction variableGlobal(){\n    console.log(global)\n}\nvariableGlobal();\nconsole.log(global)\n\n//Variable local\nfunction variableLocal(){\n    let local = \"Soy una variable local\"\n    console.log(local)\n}\nvariableLocal();\n//console.log(local); // No funciona porque la variable solo existe dentro de la funcion\n\n//Funcion flecha sin argumentos\nconst flechaSinArgumentos = () => console.log(\"Soy una funcion flecha sin argumentos\")\nflechaSinArgumentos();\n\n//Funcion flecha con argumentos\nconst flechaConArgumentos = (str1, str2) => str1+str2; //Return implicito\nconsole.log(flechaConArgumentos(\"Soy una funcion flecha\", \" con argumentos\"))\n\n//Funcion flecha con varios argumentos\nconst flechaConVariosArgumentos = (...args) => {\n    for(let i = 0; i<args.length; i++){\n        console.log(args[i])\n    }\n}\nflechaConVariosArgumentos(1, \"Hola\", 2345);\n\n//Funciones flecha anidadas\nconst flechaAnidada = (a) => (b) => a+b\nconsole.log(flechaAnidada(2)(5))\n\n//Funcion flecha variable global\nconst flechaGlobal = () => global\nconsole.log(flechaGlobal())\n\n//Funcion flecha variable local\nconst flechaLocal = () => {\n    let local = \"Hola desde funcion flecha local\"\n    return local\n}\nconsole.log(flechaLocal())\n\n/* DIFICULTAD EXTRA */\n\nfunction ejercicioExtra(arg1, arg2) {\n    try{\n        if(typeof(arg1) != \"string\" || typeof(arg2) != \"string\"){\n            throw new Error(\"Error: uno de los parametros no es texto\")\n        }\n\n        let contador = 0\n        for(let i = 0; i<100; i++){\n            if(i % 3 == 0 && i % 5 == 0){\n                console.log(arg1,arg2)\n            } else if(i % 3 == 0){\n                console.log(arg1)  \n            } else if(i % 5 == 0){\n                console.log(arg2)\n            } else{\n                console.log(i)\n                contador++\n            }\n        }\n        return contador\n\n    }catch(error){\n        console.log(error.message)\n    }\n}\n\nconsole.log(\"Se han imprito los numeros \" + ejercicioExtra(\"Roadmap JavaScript\", \"2024 by MoureDev\") + \" veces\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/NathaliaMF.js",
    "content": "\n\nconst nameValue='Nathalia';\nlet yearBirth =1996;\nlet today=  new Date();\n\nfunction greetingMessage() {\n    console.log('Hello world this is javascript')\n    \n};\ngreetingMessage(); \n\nfunction currentAge(param1, param2) {\n    let year = param2.getFullYear();\n    let ageValue= year -param1;\n    return ageValue;\n    \n}\n\nfunction introduction(param) {\n    console.log(`My name is ${param} and I am ${currentAge(yearBirth, today)} `);\n\n};\n\nintroduction(nameValue);\n\nfunction currentTime(){\n     function valueTime(){\n        return today.getHours();\n    }\n    console.log(`The current time is ${valueTime()} `);\n\n}\ncurrentTime();\nconsole.log(\"Asynchronous\");\n\nfunction two() {\n  setTimeout(function () {\n    console.log(\"Two\");\n  }, 1000);\n}\n\nfunction one() {\n  setTimeout(function () {\n    console.log(\"One\");\n  }, 0);\n  two();\n  console.log(\"Three\");\n}\n\none();\nconsole.log(\"End\");\n\n/**EJERCICIO EXTRA */\n\nfunction extraExercise(text1, text2) {\n    let value=0;\n    for (let index = 0; index <=100 ; index++) {\n        if(index % 3 == 0){\n            console.log(text1);\n        }else if(index % 5 == 0){\n            console.log(text2);\n        }else if(index % 3 == 0 && index % 5 ==0){\n            console.log(`the value of the chains is ${text1} and ${text2} `);\n        }else{\n            value++;\n        }\n        \n        \n    }\n    return value\n\n}\n\nconsole.log(`The value is${extraExercise('Hola','Mundo')}`);"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/Nightblockchain30.js",
    "content": "// Funciones sin parametros ni valor de retorno y por declaración\nfunction Greeting(){\n   console.info(\"Hello Javascript\");\n}\nGreeting();\n\n// Funciones con parametros y sin valor de retorno y por declaración\nfunction GreetingUser( name ){\n   console.log(`Hello ${ name }`);\n}\nGreetingUser(\"Alicia\");\n\n// Funciones con valor de retorno y parametros\nfunction SumOfNumbers(x, y, ...rest){\n   return rest.reduce((count, current) => count + current \n   ,0) + (x + y)\n}\n\nconsole.log(SumOfNumbers(1, 2, 3, 4, 5, 7));\n\n// Funciones expresadas sin valor de retorno ni parametros\n// Usamos un array global para que la funciones puedan usarlas\nconst Fruits = [\"Apple\", \"Pear\", \"Grapes\", \"Cherry\", \"Blueberry\", \"Strawberry\"]\n\nconst ShowFruitList = function(){\n   Fruits.forEach( fruit => {\n      console.log( fruit )\n   })\n}\nShowFruitList();\n\nconst FindFruit = function(fruit){\n   Fruits.forEach( currentFruit => {\n      if(currentFruit === fruit){\n         console.log(\"La manzana si existe!\");\n         return;\n      }\n   })\n}\nFindFruit(\"Apple\");\n\n// Closure\nfunction miFuncion() {\n   let contador = 0;\n\n   function incrementar() {\n      contador++;\n      return contador;\n   }\n\n   return incrementar;\n}\n\nconst incremento = miFuncion();\n\nconsole.log(incremento()); // 1\nconsole.log(incremento()); // 2\n\n/* DIFICULTAD EXTRA:\nCrea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\nLa función imprime todos los números del 1 al 100. Teniendo en cuenta que:\nSi el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\nSi el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\nSi el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\nLa función retorna el número de veces que se ha impreso el número en lugar de los textos \nCada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\nPresta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n **/\n\n\nconst Challenge = (str1, str2) => {\n   for(let i = 1; i <= 100; i++){\n      (i % 3 === 0 && i % 5 === 0) ? console.log(str1 + str2)\n      : (i % 3 === 0) ? console.log(str1)\n      : (i % 5 === 0) ? console.log(str2)\n      : console.log(i)\n   }\n}\nChallenge(\"Fizz\", \"Buzz\");"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/OmarLand.js",
    "content": "// 02# - Funciones y Alcance\n/*\n    * EJERCICIO:\n    * - Crea ejemplos de funciones básicas que representen las diferentes\n    *   posibilidades del lenguaje:\n    *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n    * - Comprueba si puedes crear funciones dentro de funciones.\n    * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n    * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n    * - Debes hacer print por consola del resultado de todos los ejemplos.\n    *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n*/\n\n\n// Función sin parámetros ni retorno:\nconst Saludar = () =>{\n    let localVar = \"Soy una variable local\"\n    console.log(\"Soy una función básica\");\n}\nSaludar();\n\n// Función con parámetros y retorno\nconst Suma = (a, b) => {\n return a + b;\n}\nconsole.log(\"Función con parámetros y retorno: \", Suma(10, 5) );\n\n// Función dentro de una función\n//Calculo total de un impuesto\n\nconst calcularTotalConImpuesto = (monto) => {\n    const tasaImpuesto = 0.21;\n\n    // Función interna para calcular el impuesto\n    const agregarImpuesto = (monto) => {\n        return monto * tasaImpuesto;\n    }\n\n    // Calcular el total sumando el monto original más el impuesto\n    const total = monto + agregarImpuesto(monto);\n    return total;\n}\n\nconst totalConImpuesto = calcularTotalConImpuesto(100); // Por ejemplo, para un monto de 100\nconsole.log(`El total después de impuestos es: ${totalConImpuesto}`);\n\n//  función ya creadas en el lenguaje.\n\nlet cadena = \"hola soy javascript, un lenguaje de programación poderoso\"\n\nconsole.log(\"Cambio en mayusculas la cadena:\");\nconsole.log(\"Cadena original: \", cadena);\nconsole.log(\"Cadena cambiada>>> \", cadena.toUpperCase() );\n\n\n/* DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n */\n\n\nlet varGlobal = \"Soy Global\";\n\nconst returnStr = (str1, str2) => {\n  let varLocal = \"Soy Local\";\n  let contador = 0;\n  for (let i = 1; i <= 100; i++) {\n    if (i % 3 === 0 && i % 5 === 0) {\n      console.log(str1 + str2);\n      contador++;\n    }\n    if (i % 3 === 0) {\n      console.log(str1);\n      contador++;\n    }\n    if (i % 5 === 0) {\n      console.log(str2);\n      contador++;\n    }\n    if (i % 3 !== 0 && i % 5 !== 0) {\n      console.log(i);\n      contador++;\n    }\n  }\n\n  return contador;\n};\n\nconsole.log( ` Hola ${localVar} ` );\nconsole.log( ` Hola ${globalVar} ` );\n\n\nreturnStr( \"Fizz\",\"Buzz\" );"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/Pancratzia.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\nfunction intro() {\n  console.log(\n    \"¡Hola, Javascript!\\n¿Sabías que puedes encontrar diferentes tipos de funciones en el lenguaje de programación?\\nEsta por ejemplo no recibe parametros ni hace ni retorna ningún valor\"\n  );\n}\n\nfunction paramsFunction(param1, param2, ...params) {\n  console.log(\n    \"Esta otra función recibe por parametros los números \" +\n      param1 +\n      \" y \" +\n      param2 +\n      \" y \" +\n      params\n  );\n}\n\nfunction returnFunction(programmingLang) {\n  mensaje =\n    \"Y esta función retorna un parametro l cual es el lenguaje de programación que estamos utilizando. En este caso es: \" +\n    programmingLang;\n  return mensaje;\n}\n\nfunction functionInsideAntoherFunction() {\n  console.log(\"¿Es posible crear funciones dentro de otras?\");\n\n  function isPossible() {\n    return \"Si, es posible! Pero las mismas solo pueden ser llamadas dentro de la función en la que fueron creadas.\";\n  }\n\n  console.log(isPossible());\n}\n\nfunction javaScriptOriginalFunction() {\n  console.log(\n    \"Existen funciones nativas de JavaScript. Por ejemplo, el método Math.max() que retorna el número mayor entre dos números o el console.log que muestra por consola el argumento que le pasemos\"\n  );\n}\n\nconst arrowFunction = () => {\n  console.log(\n    \"Existen las funciones flecha, que se definen de la siguiente manera: let arrowFunction = () => { }\"\n  );\n};\n\n//Una funcion declarada como function puede ser llamada antes o después de ser declarada. Pero una arrow function no puede ser llamada antes de ser declarada.\n\nlet globalVariable = \"Variable Global\";\n\nfunction globalAndLocal() {\n  let localVariable = \"Variable Local\";\n\n  console.log(globalVariable);\n  console.log(localVariable);\n\n  globalVariable = \"Variable Global Modificada\";\n}\n\nintro();\nparamsFunction(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);\nconsole.log(returnFunction(\"Javascript\"));\nfunctionInsideAntoherFunction();\n// isPossible(); - Aquí esa función no está definida\njavaScriptOriginalFunction();\nglobalAndLocal();\nconsole.log(\n  `En la función globalAndLocal() la variable global fue modificada a: ${globalVariable}. Además, la variable local solo existe dentro de la función.`\n);\n\n/**EXTRA**/\n\nconst imprimirSegunMultiplo = (param1, param2) => {\n  let count = 0;\n\n  for (let i = 1; i <= 100; i++) {\n    let message = \"\";\n\n    if (i % 3 === 0) {\n      message += param1;\n    }\n    if (i % 5 === 0) {\n      message += param2;\n    }\n\n    if (message !== \"\") {\n      console.log(message);\n    } else {\n      count++;\n      console.log(i);\n    }\n  }\n\n  return count;\n};\n\nconsole.log(\n  `La función imprimirSegunMultiplo() retorna: ${imprimirSegunMultiplo(\n    \"Fizz\",\n    \"Buzz\"\n  )} impresiones de números`\n);\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/Poetry0354.js",
    "content": "/*\nFunciones \n*/\n\n//Función Simple \n//No tiene parametros ni retorno.\nfunction primero () {\n    console.log(\"Hola Mundo\");\n}\nprimero(); //Se llama la Función\n\nfunction sumar(num1, num2) {\n    var resultado = num1 + num2;\n    console.log(\"La suma es: \" + resultado);\n}\n\nsumar(5, 3); // Llamada a la función\n\n\n//Funciones con parámetros y valor de retorno.\n\nfunction areaCasa (largo, ancho) {\n    let area = largo * ancho;\n    return area;\n}\nlet resultado = areaCasa(200, 250); //Aca llamamos a la función y lo guardamos dentro de una variable let.\nconsole.log(\"El area de la casa es de: \" + resultado + \" metros cuadrados\"); //Imprimimos el resultado.\n\n//Con argumento\n\nfunction agr_name (name) {\n    console.log(\"Que tal\" + name)\n}\nagr_name(\" Jose\");\n\nfunction agr_name2 (greet, name) {\n    console.log(greet + name);\n}\nagr_name2(\"Hola \", \" Samuel\");\n//Pasarlos en orden inverso\nagr_name2(greet=\"Hola \", name=\"Samuel\");\n\n//argumento predeterminado\n\nfunction arg_predeterminado (name=\"No se sabe\") {\n    console.log(\"Hola \" + name);\n}\narg_predeterminado(\"Jose\");\narg_predeterminado();\n\n//Argumento y Retorno.\nfunction return_arg (greet, name) {\n    return greet + name;\n}\nconsole.log(return_arg(\"Hola \", \"Carlos\"))\n\n// Retorno con varios valores.\nfunction multiple_returns () {\n    return \"Como\", \"Vas\"\n}\ngreet, name = multiple_returns()\nconsole.log(name)\nconsole.log(greet)\n\n//Con un numero variable de argumentos.\nfunction argumentosVariables (...names) {\n    for (name in names) {\n        console.log(\"Hola \" + names[name]);\n    }\n}\nargumentosVariables(\"Jose\", \"Carlos\", \"Maria\");\n\n//Un numero Variable de argumentos con claves\n\nfunction imprimirDatos(...datos) {\n    for (let dato of datos) {\n    console.log(`Nombre: ${dato.nombre}, Edad: ${dato.edad}`);\n    }\n}\nimprimirDatos({ nombre: 'Juan', edad: 20 });\nimprimirDatos({ nombre: 'María', edad: 25 }, { nombre: 'Pedro', edad: 30 });\n\n/* \nFunciones dentro de Funciones.\n- Comprueba si puedes crear funciones dentro de funciones.\n*/\n\nfunction externa () {\n    function interna () {\n        console.log(\"Hola Mundo\");\n    }\n    interna();\n}\nexterna();\n\n/* \nVariables locales y globales.\n- Comprueba si puedes crear variables locales y globales.\n\nUna Varaible global es que tiene un ambito por fuera donde lo queremos ejecutar, es decir, se puede llamar desde\ncualquier lado del codigo y poder usarlo, se hace como un orden jerardico, ya que esta global se encuentra por \nfuera / encima de donde queremos usarlo (Funcion).\n\nUna Variable local funciona solo dentro del ambito de la funciónde donde se ha creado. Y solo existe dentro de esta misma.\nSi la llamamos por fuera, no lo podremos hacer por que aparece como que no existe.\n\nTanto locales como Globales son sus propios mundos en estos sentidos.\n*/\nlet global_var = \"Carne\";\n\nfunction carneDeMercado (){\n    let local_var = \"Pollo\";\n    console.log(global_var);//Aca se llama eta variable que se encuentra por fuera de la función (Global).\n    console.log(local_var);//Aca se llama esta variable que se encuentra dentro de la función y solo existe ahi (Local)\n}\ncarneDeMercado();//Intentar restringir al maximo el codigo.\n\n/*\nDIFICULTAD EXTRA\n DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n*/\nfunction extra (texto1, texto2) { \n    for (let i=1; i<=100; i++ ) {\n        if (i%3==0 && i%5==0) { //Multiplo de 3 y 5\n            console.log(i + \" Es \" + texto1 + \" y \" + texto2);\n        }\n        else if (i%3==0) { //Sera multiplo si se divide entre 3 \n            console.log(i + \" Es \" + texto1);\n        } else if (i%5==0) { //Sera multiplo si se divide entre 5   \n            console.log(i + \" Es \" + texto2);\n        } else {\n            console.log(i); //Para los numeros que estan por fuera de esas condiciones.\n        }\n    }\n}\nextra(\"Multiplo de 3 \", \"Multiplo de 5 \")\n\n//Reto Completado :D\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/RaquelTejada.js",
    "content": "// Función sin parámetros ni retorno\nfunction sayHello() {\n  console.log(\"Hello!\");\n}\n\nsayHello();\n\n// Función con un parámetro y retorno\nfunction myNameIs(name) {\n  return \"My name is \" + name;\n}\n\nconsole.log(myNameIs(\"Raquel Tejada\"));\n\n// Función con múltiples parámetros y retorno\nfunction sayFullName(name, surname) {\n  return name + \" \" + surname;\n}\n\nconsole.log(sayFullName(\"Raquel\", \"Tejada\"));\n\n// Función expresión\nconst myAge = function (age) {\n  return \"this is my age\" + age;\n};\n\n// Función flecha\nconst arrowFunction = () => console.log(\"this is arrow function\");\n\n// Función anidada\nfunction parent(parentName) {\n  return function child(childName) {\n    return `${parentName} is the father of ${childName}`;\n  };\n}\n\n// Variable global y variable local\nconst globalVariable = \"Esto es una variable global\";\n\nfunction localVariable() {\n  const localVariable = \"Esto es una variable local\";\n  console.log(globalVariable);\n  console.log(localVariable);\n}\n\nlocalVariable();\n\n// Dificultad extra\nfunction numbers(chainNumber1, chainNumber2) {\n  for (let i = 1; i <= 100; i++) {\n    i % 3 === 0 && i % 5 === 0\n      ? console.log(chainNumber1 + chainNumber2)\n      : i % 3 === 0\n      ? console.log(chainNumber1)\n      : i % 5 === 0\n      ? console.log(chainNumber2)\n      : console.log(i);\n  }\n}\nnumbers(\"trying\", \"extra mile\");\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/RaulDoezon.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n// +++++++++ FUNCIÓN SIN PARÁMETROS NI RETORNO +++++++++\nfunction hello() {\n  console.log(\"¡Hola mundo con JavaScript!\");\n}\n\nhello();\n\n// +++++++++ FUNCIÓN CON PARÁMETROS +++++++++\nfunction addition(firstNumber, secondNumber) {\n  console.log(firstNumber + secondNumber);\n}\n\naddition(13, 20);\n\n// +++++++++ FUNCIÓN CON PARÁMETROS Y RETORNO +++++++++\nfunction checkAge(age, name) {\n  if (age >= 18) {\n    return name + \" eres mayor de edad.\"\n  } else {\n    return \"Eres menor de edad \" + name + \".\"\n  }\n}\n\nconsole.log(checkAge(17, \"Raúl\"));\n\n// +++++++++ FUNCIONES ANIDADAS +++++++++\nfunction greet(name, lastName) {\n  function fullName() {\n    return name + \" \" + lastName;\n  }\n\n  console.log('Hello ' + fullName() + \"!\");\n}\n\ngreet(\"Samus\",  \"Aran\");\n\n// +++++++++ EJEMPLOS DE FUNCIONES EXISTENTES EN JAVASCRIPT +++++++++\n// parseInt() y console.log()\nvar numberAsAString = \"16\";\nvar number = parseInt(numberAsAString, 10);\nconsole.log(\"Tipo de dato antes de utilizar parseInt: \" + typeof numberAsAString);\nconsole.log(\"Tipo de dato después de utilizar parseInt: \" + typeof number);\n\n// +++++++++ VARIABLES GLOBAL Y LOCAL +++++++++\nvar globalMessage = \"The last Metroid is in captivity.\"\n\nfunction fullMessage(localMessage) {\n  var localMessageVariable = localMessage;\n  console.log(globalMessage + \" \" + localMessageVariable);\n}\n\nfullMessage(\"The galaxy is at peace...\");\nconsole.log(\"Este mensaje no se mostrará porque localMessageVariable es una variable local: \" + localMessageVariable);\n\n// +++++++++ DIFICULTAD EXTRA +++++++++\nvar auxiliaryCounter = 0;\n\nfunction series(textOne, textTwo) {\n\tfor(var index = 1; index <= 100; index++) {\n\t  if (index % 3 === 0 || index % 5 === 0) {\n\t\t\tif (index % 3 === 0 && index % 5 === 0) {\n        console.log(textOne + \" y \" + textTwo);\n\n      } else if (index % 3 === 0) {\n          console.log(textOne);\n\n      } else if (index % 5 === 0) {\n        console.log(textTwo);\n      }\n    } else {\n      auxiliaryCounter++;\n      console.log(index);\n    }\n  }\n\n\treturn auxiliaryCounter;\n}\n\nseries(\"Múltiplo de tres\", \"Múltiplo de cinco\");\nconsole.log(\"Número de veces que se imprimieron números: \" + auxiliaryCounter);\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/Reaien.js",
    "content": "//funcion declarada vacia\nfunction vacio() {}\nconsole.log(vacio);\n//funcion declarada que retorna un valor\nfunction saludo() {\n  return console.log(\"soy una funcion\");\n}\n//ejecucion de función declarada que retorna un valor\nsaludo();\n\n//funcion tipo expresión con parametros\nlet varSumar = function sum2(num1, num2) {\n  return num1 + num2;\n};\nconsole.log(varSumar(1, 2));\n\n/* \nFunción dentro de función\nfuncionCeption recibe un parámetro y ejecuta la 2da función la cual setea su parámetro\npredefinido y junta ambas palabras y los retorna por consola, vuelve a la funcionCeption1 y esta ejecuta la funcionCeption2\n*/\nlet funcionception = (palabra) => {\n  let funcionCeption2 = (palabra2) => {\n    palabra2 = \"mundo\";\n    console.log(palabra + \" \" + palabra2);\n  };\n  return funcionCeption2();\n};\n//ejecución\nfuncionception(\"hola\");\n\n//función ya creada en JS charAt\nlet palabra = \"hola mundo\";\nlet charAt = palabra.charAt(1);\nconsole.log(charAt);\n\n//ejercicio dificultad extra\n//arrow function\nlet funcionExtra = (palabra1, palabra2) => {\n  for (let i = 1; i <= 100; i++) {\n    if (i % 3 == 0 && i % 5 == 0) {\n      console.log(`${palabra1 + \" \" + palabra2 + \" \" + i}`);\n    } else if (i % 3 == 0) {\n      console.log(palabra1 + \" \" + i);\n    } else if (i % 5 == 0) {\n      console.log(palabra2 + \" \" + i);\n    }\n  }\n};\n/*ejecución de arrow function \nretorna las 2 palabras si ambas condiciones se cumplen\nretorna la primera palabra si i es múltiplo de 3\nretorna la primera palabra si i es múltiplo de 5\n*/\n//ejecución de la función\nfuncionExtra(\"Hola\", \"Mundo\");\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/RicJDev.js",
    "content": "//EJERCICIO\n//**FUNCION DECLARATIVA**\n//-Sin parametros-\nconst levelPoints = 2000;\nlet playerPoints = 1800;\n\nfunction levelUp() {\n\tif (playerPoints >= levelPoints) {\n\t\tconsole.log('Level Up! GG!');\n\t} else {\n\t\tconsole.log('Keep playing. Need more points');\n\t}\n}\n\nlevelUp();\n\nplayerPoints = 2300;\nlevelUp();\n\n//-Return-\nlet precio = 830;\nlet pagoDelCliente = 830;\n\nfunction compruebaElPago() {\n\treturn pagoDelCliente >= precio;\n}\n\nconsole.log(compruebaElPago());\n\npagoDelCliente = 0;\nconsole.log(compruebaElPago());\n\n//-Con un parametro-\nfunction duplicador(n) {\n\treturn n * 2;\n}\n\nconsole.log(duplicador(45));\nconsole.log(duplicador(12));\n\n//-Con dos parametros-\nfunction sumaEstosDos(a, b) {\n\tlet result = a + b;\n\tconsole.log(`${a} y ${b} suman ${result}`);\n}\n\nsumaEstosDos(12, 25);\n\n//-Con multiples parametros-\n\nfunction sumaEsteArray(arr) {\n\tsum = 0;\n\tfor (i = 0; i < arr.length; i++) {\n\t\tsum = sum + arr[i];\n\t}\n\treturn sum;\n}\n\nconst numbers = [12, 32, 78, 7, 23, 34, 56, 78, 90];\n\nconsole.log(sumaEsteArray(numbers));\n\n//-Con infinitos parametros-\nfunction cuentaLosNombres() {\n\tconsole.log(`En total son ${arguments.length} nombres`);\n}\n\ncuentaLosNombres('Juan', 'Maria', 'Kevin', 'Eduardo', 'Fabian');\n\n//-Anonimas-\nconst funcionAnonima = function () {\n\tconsole.log('Hola. Soy una funcion anonima');\n};\n\nfuncionAnonima();\n\nconst numCuadrado = function (n) {\n\treturn n * n;\n}; //de expresion\n\nconsole.log(numCuadrado(2));\n\nconst unNumCuadrado = (function (n) {\n\treturn n * n;\n})(10); //de autoinvocacion\n\nconsole.log(unNumCuadrado);\n\n//***FUNCION FLECHA***\nconst triplicador = (n) => {\n\treturn n * 3;\n};\n\nconsole.log(triplicador(20));\n\nconst cuadriplicador = (n) => n * 4;\n\nconsole.log(cuadriplicador(10));\n\nconst restaEstosDos = (a, b) => {\n\tlet result = a - b;\n\tconsole.log(`${a} y ${b} restan ${result}`);\n};\n\nrestaEstosDos(10, 4);\n\n//***PARAMETROS POR DEFECTO***\nfunction laMitadEs(n = 20) {\n\treturn n / 2;\n}\n\nconsole.log(laMitadEs());\nconsole.log(laMitadEs(14));\n\nfunction saludo(a = 'Ricardo') {\n\tconsole.log(`Hola, ${a}`);\n}\n\nsaludo();\nsaludo('Josue');\n\nconst areaRectangulo = (a = 10, b = 2) => 2 * (a + b);\n\nconsole.log(areaRectangulo());\nconsole.log(areaRectangulo(12, 10));\n\n//***FUNCION DENTRO DE UNA FUNCION***\n\nfunction autorizaElEnvio() {\n\tif (compruebaElPago() === true) {\n\t\tconsole.log('El pago ha sido procesado con exito. Enviando articulo...');\n\t} else {\n\t\tconsole.log('No se ha procesado el pago');\n\t}\n}\n\nprecio = 200;\npagoDelCliente = 200;\n\nautorizaElEnvio();\n\nprecio = 120;\npagoDelCliente = 0;\n\nautorizaElEnvio();\n\nconst aplicaTodas = (n) => {\n\tconsole.log(n);\n\tconsole.log(duplicador(n));\n\tconsole.log(triplicador(n));\n\tconsole.log(cuadriplicador(n));\n};\n\naplicaTodas(10);\n\n//***FUNCIONES INTEGRADAS***\nlet myNum = '23';\nconsole.log(parseInt(myNum) + 2);\n\nlet misAppsFavoritas = 'Twitch, Discord, VSCode, YouTube';\nmisAppsFavoritas = misAppsFavoritas.split(', ');\nconsole.log(misAppsFavoritas[2]);\n\nlet miNombre = 'Ricardo Marin';\nconsole.log(miNombre.substring(0, 3));\nconsole.log(miNombre.slice(8, -2));\n\nconst things = ['dish', 'computer', 'dog'];\nconst count = things.push('bed');\nconsole.log(things);\nconsole.log(things.pop());\n\nlet numeroAleatorio = parseInt(100 * Math.random());\nconsole.log(numeroAleatorio);\nconsole.log(typeof numeroAleatorio);\n\n//***ALCANCE***\nlet n = 'Soy una variable con alcance global'; //aqui n tiene alcance global\nconsole.log(n);\n\nfunction local() {\n\tlet m = 'Soy una variable con alcance local';\n\tconsole.log(m);\n}\n\n//si escribieramos console.log(m); daria error, debido a que m solo es accesible dentro de la funcion\nlocal();\n\n//EXTRA\nfunction muestraNumeros(a = 'Fizz', b = 'Buzz') {\n\tfor (let i = 1; i <= 100; i++) {\n\t\tif (i % 3 === 0 && i % 5 === 0) {\n\t\t\tconsole.log(a + ' ' + b);\n\t\t} else if (i % 3 === 0) {\n\t\t\tconsole.log(a);\n\t\t} else if (i % 5 == 0) {\n\t\t\tconsole.log(b);\n\t\t} else {\n\t\t\tconsole.log(i);\n\t\t}\n\t}\n}\n\nmuestraNumeros('Papa', 'Frita');\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/Rikar20.js",
    "content": "// Funciones \n/*Las funciones son uno de los bloques de construcción fundamentales en JavaScript.\nUna función en JavaScript es similar a un procedimiento — un conjunto de instrucciones que realiza \nuna tarea o calcula un valor, pero para que un procedimiento \ncalifique como función, debe tomar alguna entrada y devolver una salida donde hay\nalguna relación obvia entre la entrada y la salida */\n\n// Declaracion de una Funcion\n/*\nSe Define con la palabra reservada function mas el nombre, recibe una lista de parametros entre parentesis.\nDentro de corchetes se escribe el codigo a ejecutar\n */\n\nfunction name(nombre){\n    return nombre;\n}\n\nconsole.log('\\n--Definición de una función--');\nconsole.log(name(\"ricardo\"));\n\n//funciones anonimas\n\nconst miNombre = function(){\n    return  \"Mi nombre es Ricardo\";\n}\nconsole.log(miNombre());\n\n//funciones flechas \nconst decirNombre = () =>{\n    console.log(\"Mi nombre es Ricardo Oyola\")\n}\n\n\n//funciones autoejecutables\n(function() {\n    // Código que se ejecutará automáticamente\n    console.log(\"Esta función se ejecuta automáticamente.\");\n})();\n\n//Funciones Flecha autoejecutables\n(() => {\n    // Código que se ejecutará automáticamente\n    console.log(\"Esta función de flecha se ejecuta automáticamente.\");\n})();\n\n//Funciones Anidadas\nconsole.log('\\n--Funciones Anidadas--');\nfunction masRaizCuadrada(a, b){\n    function raizCuadrada (c){\n        return c * c;\n    }\n\n    console.log(raizCuadrada(a) + raizCuadrada(b));\n}\n\nmasRaizCuadrada(2, 5);\n\n//Ámbito de function\n\n/*No se puede acceder a las variables definidas dentro de una función desde cualquier \nlugar fuera de la función, porque la variable se define solo en el ámbito de la función. \nSin embargo, una función puede acceder a todas las variables y funciones definidas dentro del \námbito en el que está definida. */\n\n//Ámbito Global\nconsole.log('\\n--Funciones Ámbito Global--');\nlet numeroUno = 1;\nlet numeroDos = 2;\n\nfunction suma(){\n    return numeroUno + numeroDos;\n}\n\nconsole.log(suma())\n\n//Ámbito Local\nconsole.log('\\n--Funciones Ámbito local--');\n\nfunction imprimirNumero(elNumero){\n    let numero = elNumero;\n\n    if(numero > 2 ){\n        for(i = numero; i < 10; i++){\n            console.log(i);\n        }\n    }else {\n        console.log(\"El numero debe ser positivo\");\n    }\n}\n\nimprimirNumero(4);\n\n/*\n* DIFICULTAD EXTRA (opcional):\n* Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n* - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n*   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n*   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n*   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n*   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n*/\n\nfunction imprimirResultados(a = \"textoUno\", b = \"textoDos\") {\n    let control = 0;\n\n    for (let i = 1; i <= 100; i++) {\n        let multiploDeTres = i % 3 === 0;\n        let multiploDeCinco = i % 5 === 0;\n\n        if (multiploDeTres && multiploDeCinco) {\n            console.log(a + b);\n        } else if (multiploDeTres) {\n            console.log(a);\n        } else if (multiploDeCinco) {\n            console.log(b);\n        } else {\n            console.log(i);\n            control++;\n        }\n    }\n    return control;\n}\n\nimprimirResultados();\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/Sac-Corts.js",
    "content": "// Exercise // \n// Function whitout parameters or return value\nfunction noParameters() {\n    console.log(\"This function has no parameters or return value.\");\n}\n\nnoParameters();\n\n// Function with one parameter\nfunction oneParameter(param) {\n    console.log(\"The received parameter is: \" + param);\n}\n\noneParameter(\"Hello World\");\n\n// Function with multiple parameters\nfunction multipleParameters(param1, param2) {\n    console.log(\"The received parameters are: \" + param1 + \" and \" + param2);\n}\n\nmultipleParameters('Hello', 'World');\n\n// Function with return value\nfunction addition(a, b) {\n    return console.log(a + b);\n}\n\naddition(4, 10);\n\n// Nested functions\nfunction outerFunction() {\n    console.log(\"This is the outer function\");\n    function innerFunction() {\n        console.log(\"This is the inner function\");\n    }\n    innerFunction();\n}\n\nouterFunction();\n\n// Using built-in functions\nfunction exampleMath() {\n    console.log(\"The absolute value of -5 is: \" + Math.abs(-5));\n}\n\nexampleMath();\n\n// Local and global variables\nvar globalVar = \"I am a global variable\";\n\nfunction variableScope() {\n    var localVar = \"I am a local variable\";\n    console.log(globalVar);\n    console.log(localVar);\n}\n\nvariableScope();\nconsole.log(globalVar);\n// The following line will throw an error because 'localVar' is not defined in the global scope\n// console.log(localVar);\n\n// Extra Exercise // \n\nfunction oneHundred(param1, param2) {\n    let counter = 0;\n\n    for (let i = 1; i <= 100; i++) {\n        if (i % 3 === 0 && i % 5 === 0) {\n            console.log(param1, param2);\n        } else if (i % 3 === 0) {\n            console.log(param1);\n        } else if (i % 5 === 0) {\n            console.log(param2);\n        } else {\n            console.log(i);\n            counter++;\n        }\n    }\n    return counter;\n}\n\nconst counter = oneHundred('Fizz', 'Buzz');\nconsole.log(\"Count of numbers printed: \" + counter);\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/SalazarProgrammer.js",
    "content": "// #02 FUNCIONES Y ALCANCE\n// Dificultad: Fácil | Publicación: 08/01/24 | Corrección: 15/01/24\n\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n/*\n * RESPUESTAS:\n * - Crea ejemplos de funciones básicas\n */\n\n// 1. Función sin parámetros ni retorno\nfunction saludar() {\n\tconsole.log('¡Hola desde función sin parámetros!');\n}\n\n// 2. Función con un parámetro\nfunction saludarPersona(nombre) {\n\tconsole.log(`¡Hola, ${nombre}!`);\n}\n\n// 3. Función con varios parámetros\nfunction sumar(a, b) {\n\treturn a + b;\n}\n\n// 4. Función con retorno\nfunction multiplicar(a, b) {\n\treturn a * b;\n}\n\n// 5. Función flecha (arrow function) - ES6\nconst dividir = (a, b) => a / b;\n\n// 6. Función con parámetros por defecto\nfunction potencia(base, exponente = 2) {\n\treturn Math.pow(base, exponente);\n}\n\n// 7. Comprobar funciones dentro de funciones\nfunction funcionExterna() {\n\tconsole.log('Función externa ejecutada');\n\n\tfunction funcionInterna() {\n\t\tconsole.log('Función interna ejecutada');\n\t\treturn 'Retorno desde función interna';\n\t}\n\n\tconst resultado = funcionInterna();\n\tconsole.log(resultado);\n\n\t// También podemos retornar una función\n\treturn function () {\n\t\tconsole.log('Función retornada ejecutada');\n\t};\n}\n\n// 8. Funciones ya creadas en el lenguaje\n// Math.random(), console.log(), parseInt(), etc.\n\n// 9. Variables locales y globales\nlet variableGlobal = 'Soy global';\n\nfunction probarVariables() {\n\tlet variableLocal = 'Soy local';\n\tconsole.log('Dentro de la función:');\n\tconsole.log('Variable global:', variableGlobal);\n\tconsole.log('Variable local:', variableLocal);\n\n\t// Podemos modificar la variable global\n\tvariableGlobal = 'Global modificada';\n}\n\n// Ejecutamos todas las funciones\nconsole.log('=== FUNCIONES BÁSICAS ===');\nsaludar();\nsaludarPersona('Ana');\nconsole.log('Suma:', sumar(5, 3));\nconsole.log('Multiplicación:', multiplicar(4, 6));\nconsole.log('División:', dividir(10, 2));\nconsole.log('Potencia:', potencia(3));\nconsole.log('Potencia con exponente:', potencia(2, 4));\n\nconsole.log('\\n=== FUNCIONES DENTRO DE FUNCIONES ===');\nconst funcionRetornada = funcionExterna();\nfuncionRetornada();\n\nconsole.log('\\n=== VARIABLES LOCALES Y GLOBALES ===');\nconsole.log('Variable global antes:', variableGlobal);\nprobarVariables();\nconsole.log('Variable global después:', variableGlobal);\n\n// Intentar acceder a variable local fuera de su scope causaría error\n// console.log(variableLocal); // ReferenceError\n\nconsole.log('\\n=== FUNCIONES DEL LENGUAJE ===');\nconsole.log('Número aleatorio:', Math.random());\nconsole.log('Redondeo:', Math.round(3.7));\nconsole.log('Máximo:', Math.max(1, 5, 3, 8));\nconsole.log('Parseo a entero:', parseInt('42'));\n\n/*\n * DIFICULTAD EXTRA (opcional):\n */\nfunction desafioExtra(texto1, texto2) {\n\tlet contadorNumeros = 0;\n\n\tfor (let i = 1; i <= 100; i++) {\n\t\tif (i % 3 === 0 && i % 5 === 0) {\n\t\t\tconsole.log(texto1 + texto2);\n\t\t} else if (i % 3 === 0) {\n\t\t\tconsole.log(texto1);\n\t\t} else if (i % 5 === 0) {\n\t\t\tconsole.log(texto2);\n\t\t} else {\n\t\t\tconsole.log(i);\n\t\t\tcontadorNumeros++;\n\t\t}\n\t}\n\n\treturn contadorNumeros;\n}\n\nconsole.log('\\n=== DESAFÍO EXTRA ===');\nconst resultado = desafioExtra('Fizz', 'Buzz');\nconsole.log(`\\nNúmeros impresos en lugar de textos: ${resultado}`);\n\n/*\n * FIN DEL DESAFÍO\n */\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/SantiagoCuevas2003.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n\n//funciones sin parametros , ni retornos \n\nfunction saludar(){\nconsole.log(\"hola mundo\");\n};\n\nsaludar();\n\n\n//varios parametros \nfunction calculadoraBasica(a,b,operador){\n\n    switch(operador){\n        case`suma`:\n            console.log(`la suma es:` + (a + b));\n        break;\n        case`resta`:\n            console.log(`la suma es:` + (a - b));\n        break;\n        case`multiplicacion`:\n            console.log(`la suma es:` + (a * b));\n        break;\n        case`division`:\n            console.log(`la suma es:` + (a / b));\n        break;\n        case`elevacion`:\n            console.log(`la suma es:` + (a ** b));\n        break;\n        case`residuo`:\n            console.log(`la suma es:` + (a % b));\n        break;\n        default:\n            console.log(\"por favor ingresa un operador valido\")\n            break;\n    }   \n}\n\n//resultados de la funcion con varios parametros demostrado en una calculadora basica\ncalculadoraBasica(7,10,\"suma\");//la suma es:17\ncalculadoraBasica(7,10,\"resta\");//la suma es:-3\ncalculadoraBasica(7,10,\"multiplicacion\");//la suma es:70\ncalculadoraBasica(7,10,\"division\");//la suma es:0.7\ncalculadoraBasica(7,10,\"elevacion\");//la suma es:282475249\ncalculadoraBasica(7,10,\"residuo\");//la suma es:7\ncalculadoraBasica(7,10,\"ninguno\");//la suma es:por favor ingresa un operador valido\n\n\n//con retorno\n\nconst calcularRectangulo = (largo, ancho) => {\n\n    const area = largo * ancho;\n    return area;\n};\n\nconsole.log(calcularRectangulo(9,5));\n\n\n//funciones dentro de funciones\n\n//vamos a crear una funcion con ejemplo de motos\n\nfunction caracteristicasDeMoto(marca,modelo){\n    console.log(`${marca} ${modelo}`);\n\nfunction detallesDeMoto(año,color){\n    console.log(`Detalles: año ${año} color ${color}`);\n    return `la marca de la moto es ${marca} de color ${color} , modelo ${modelo} del año ${año}`\n};\n    const res = detallesDeMoto(2024,`rojo`);\n    console.log(`descripcion completa:`,res)\n};\n\ncaracteristicasDeMoto(`yamaha`,`r1`);\n\n// Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n\nconst numeros = [1,2,3,4,5,6,7,8];\n\nconst numerosMultiplicados = numeros.map(function(numero){\nreturn numero * 4\n});\n\nconsole.log(\"numeros multiplicados:\", numerosMultiplicados);// numeros multiplicados: 4,  8, 12, 16,20, 24, 28, 32\n\n\n//variable local y global\n\nlet mensajeGlobal = \"este es una varaible global\";\n\n\nfunction pruebaVariable(){\n    //variable local\n    let mensajeLocal = \"esta es una variable local\";\n\n\n    console.log(mensajeGlobal);\n    console.log(mensajeLocal);\n\n    //se puede modificar la variable global desde la funcion\n    mensajeGlobal = \"soy la variable global modificada desde la funcion\"\n};\n\npruebaVariable();\nconsole.log(mensajeGlobal);\n\n\n/* DIFICULTAD EXTRA (opcional):\n* Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n* - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n*   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n*   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n*   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n*   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n*\n* Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n* Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n*/\n\n\nconst string1 = \"soy la cadena 1 ,\";\nconst string2 = \" soy la cadena 2\";\n\nfunction pasarDeTextoANumero (string1,string2){\n\n    const resultado = string1 + string2;\n    const numbers   = [];\n\n    for(let i = 0; i <= 100; i++ ){\n        if(i % 3 === 0 && i % 5 === 0){\n            console.log(`multiplo de 3 y  5: ${resultado}`,);\n        }else if (i % 3 === 0){\n            console.log(`multiplo de 5: ${string2}`,);\n            \n        }else if (i % 5 === 0){\n            console.log(`multiplo de 3 : ${string1}`, );\n        }else{\n            numbers.push(i);\n        }\n    };\n    \n    return numbers;\n\n};\n\nconsole.log(pasarDeTextoANumero(string1,string2));"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/SingularPigeon.js",
    "content": "// Función simple sin parametros ni retorno\nfunction GetName() {\n  console.log(\"Estoy obteniendo el nombre\");\n}\nGetName();\n\n// Función con un parametro y sin retorno\nfunction GetMyName(name) {\n  console.log(name);\n}\nGetMyName(\"Paloma\");\n\n// Función con dos parametros y con retorno\nfunction GetMyFullName(name, lastName) {\n  return `${name} ${lastName}`;\n}\nconsole.log(GetMyFullName(\"Paloma\", \"San Basilio\"));\n\n// Función tipo flecha\nlet getMyFullNameFlecha = (name, lastName) => `${name} ${lastName}`;\nconsole.log(getMyFullNameFlecha(\"Paloma\", \"San Basilio\"));\n\n// Función dentro de otra función\nfunction PaintMyColors() {\n  function GetMyColors() {\n    const color1 = \"red\";\n    const color2 = \"pink\";\n    return [color1, color2];\n  }\n  const myColors = GetMyColors();\n  return myColors;\n}\nconsole.log(PaintMyColors());\n\n// Función autoinvocada\n(function () {\n  function GetMyColors() {\n    const color1 = \"Light green\";\n    const color2 = \"pink\";\n    return [color1, color2];\n  }\n\n  const myColors = GetMyColors();\n  console.log(myColors);\n})();\n\n// Funciones de sistema\n\nfunction miPuntuacion() {\n  return Math.floor(7.89); // retorna el máximo entero menor o igual aun numerp\n}\nconsole.log(miPuntuacion());\n\nfunction miNota() {\n  return Math.round(7.89); // retorna el valor de un número redondeado al entero más cercano.\n}\nconsole.log(miNota());\n\n// Variable global\n\nlet pacientes = [];\nfunction agregarPaciente(nombre, edad, sexo) {\n  pacientes.push({ nombre, edad, sexo });\n}\nagregarPaciente(\"Juan\", 25, \"Masculino\");\nconsole.log(pacientes);\n\n// variable local\nfunction MostrarPaciente(nombre, edad, sexo) {\n  let fichaPaciente = `Nombre: ${nombre}, Edad: ${edad}, Sexo: ${sexo}`;\n  console.log(fichaPaciente);\n}\nMostrarPaciente(\"Lady Gaga\", 38, \"femenino\"); // imprime la ficha paciente\n\n// reto extra\nfunction misNumero(a, b) {\n  a = \" soy múltiplo de 3\"; \n  b = \" soy múltiplo de 5\";\n  \n  let count = 0\n  for (let i = 0; i <= 100; i++) {\n    if (i % 3 === 0 && i % 5 === 0) {\n      console.log(i + `${a} y${b}`);\n      count++;\n    } else if (i % 3 === 0) {\n      console.log(i + a);\n      count++;\n    } else if (i % 5 === 0) {\n      console.log(i + b);\n      count++;\n    }\n  }\n  console.log(`El número se ha impreso ${count} veces`);\n  return count;\n}\nmisNumero(0, 0);\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/Sjho-406.js",
    "content": "//Funcion sin parámetros ni retorno\nfunction Hello() {\n    console.log('Hola')\n}\n\nHello()\n\n//Funcion con uno o varios parámetros\nfunction HelloName(name) {\n    console.log(`Hola ${name}`)\n}\n\nHelloName('Jose')\n\n//Funcion con retorno\nfunction Sum(a, b) {\n    return a + b;\n}\n\nconsole.log(Sum(2, 2))\n\n//Funciones dentro de funciones\nfunction SumCall() {\n    console.log(`Tu resultado es: ${Sum(2, 2)}`)\n}\n\nSumCall()\n\n//Reto extra\nfunction PrintNumbers(a, b) {\n    let count = 0\n    for (let i = 0; i <= 100; i++) {\n        if (i % 3 === 0 && i % 5 === 0) {\n            console.log(a + b)\n            count++\n        }\n        else if (i % 3 === 0) {\n            console.log(a)\n            count++\n        }\n        else if (i % 5 === 0) {\n            console.log(b)\n            count++\n        }\n    }\n\n    return count\n}\nconsole.log(PrintNumbers('hola', 'como estas'))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/TasyMed.js",
    "content": "// ----- 1. Crear funciones básicas -----\n\n// - 1 \nfunction EstoEsUnaFuncion(){\n\n}\n// - 2\nconst Numero = 10\nfunction FucionConParametros(Numero) {\n    if (Numero === 10) {\n        console.log(\"Uso del parametro\")\n    }\n}\n// - 3\n// Declaracion de una fuacion con sus parametros\nfunction FucionVariosParameros(a, b) {\n    return a + b\n}\n// Uso y declaracion\nlet resultado = FucionVariosParameros(10, 5)\nconsole.log(resultado) //15\n\n\n// ----- 2. Verificar si puedes hacer funciones dentro de funciones -----\n\nfunction Prueba(texto){\n    function interno(texto){\n        console.log(texto)\n    }\n    interno(texto)\n}\nPrueba(\"Funciona\")\n\n// Si puedes\n\n// ----- 3. Usar alguna función ya existente en el lenguaje (Ejemplo: Math.max()) -----\n\nlet usarFuncionIntegrada = Math.random() //Genera un numeros alatorios\nconsole.log(usarFuncionIntegrada)\n\n\n// ----- 4. Probar el concepto de variable local y global -----\n\nfunction Globalsuma(a, b) {\n    return a + b\n}\n\nfunction Entorno() {\n    // Funcion local\n    function Localresta(a, b) {\n        return a - b\n    }\n\n    let suma = Globalsuma(2,2)\n    console.log(suma) // Impreme 4\n\n    let resta = Localresta(2,2) \n    console.log(resta) // Impreme 0\n}\n\n// Inicar el Entorno\nEntorno()\n\n// Uso de las variables en uso global\nlet  sumaGlobal = Globalsuma(3,3)\nconsole.log(sumaGlobal) // Impreme 6\n\nlet usarRestaLocal = Localresta(3,2)\nconsole.log(usarRestaLocal) // Null\n\n\n// ----- Dificultad extra -----\n\n/*\n* DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n*/\n\nfunction RETO(letra1, letra2) {\n    let cantidad = 0;\n    \n    for (let i = 1; i <= 100; i++) {\n        if (i % 3 === 0 && i % 5 === 0) {\n            console.log(letra1 + \" \" + letra2);\n        } else if (i % 3 === 0) {\n            console.log(letra1);\n        } else if (i % 5 === 0) {\n            console.log(letra2);\n        } else {\n            console.log(i);\n            cantidad++;\n        }\n    }\n\n    console.log(\"Numbers printed: \" + cantidad);\n    return cantidad;\n}\n\nRETO(\"Alan\", \"Andres\");"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/TofeDev.js",
    "content": "//Variables globales\nvar variableGlobal1 = 100\nvar variableGlobal2 = 20\n\n//Función básica / sin retorno ni parámetros\nfunction bienvenida() {\n    console.log(\"Les damos la bienvenida a nuestra casa\")\n}\n\nbienvenida()\n\n//Función con parámetro\nfunction clima(estado) {\n    console.log(\"Hoy el clima está \" + estado)\n}\n\nclima(\"soleado\")\n\n//Función con varios parámetros\nfunction mesa(p1, p2) {\n    console.log(\"Esta mesa está reservada para \" + p1 + \" y \" + p2)\n}\n\nmesa(\"José Hernandez\", \"María Valdez\")\n\n//Función con retorno\nfunction sumar(a, b) {\n    return a + b\n}\n\nfunction multiplicacion(a, b) {\n    return a * b\n}\n\nresultadoSuma = sumar(variableGlobal1, variableGlobal2)\nresultadoMultiplicacion = multiplicacion(variableGlobal1, variableGlobal2)\nconsole.log(\"Resultado de la suma: \" + resultadoSuma + \". Resultado de la multiplicación: \" + resultadoMultiplicacion)\n\n//Variables locales\nfunction local() {\n    let funcionLocal1 = 200\n    let funcionLocal2 = 50\n\n    console.log(funcionLocal1 + funcionLocal2)\n}\n\nlocal()\n\n//Funciones dentro de funciones\nfunction dobleFuncion(c, d) {\n    const r1 = sumar(c, d)\n    const r2 = multiplicacion(c, d)\n    const res = (r2 / r1)\n    console.log(\"División de los resultados de las operaciones: \" + res)\n}\n\ndobleFuncion(15, 10)\n \n/* DIFICULTAD EXTRA\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos. \n */\n\nfunction extra(p1, p2) {\n    for(i=1; i <=100; i++) {\n        if ((i % 3 === 0) && (i % 5 === 0)) {\n            console.log(`${p1}${p2}`)\n        } else if (i % 3 === 0) {\n            console.log(p1)\n        } else if (i % 5 === 0) {\n            console.log(p2)\n        } else {\n            console.log(i)\n        }\n    }\n}\n\nextra(\"Fizz\", \"Buzz\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/TomasMarquez81.js",
    "content": "/*\r\n * EJERCICIO:\r\n * - Crea ejemplos de funciones básicas que representen las diferentes\r\n *   posibilidades del lenguaje:\r\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\r\n * - Comprueba si puedes crear funciones dentro de funciones.\r\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\r\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\r\n * - Debes hacer print por consola del resultado de todos los ejemplos.\r\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\r\n *\r\n * DIFICULTAD EXTRA (opcional):\r\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\r\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\r\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\r\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\r\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\r\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\r\n *\r\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\r\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\r\n */\r\n\r\n// Función basica sin parámetros\r\nfunction basica() {\r\n  console.log(\"Basica\");\r\n}\r\nbasica();\r\n\r\n// Función basica con parámetro\r\nfunction basicaParametro(string) {\r\n  console.log(string);\r\n}\r\nbasicaParametro(\"Básica con parámetro\");\r\n\r\n// Función basica con parámetro por defecto\r\nfunction basicaParametroDefecto(string = \"Con parámetro por defecto\") {\r\n  console.log(string);\r\n}\r\nbasicaParametro();\r\n\r\n// Función basica con retorno\r\nfunction basicaRetorno() {\r\n  let string = \"Básica con retorno\";\r\n  return string;\r\n}\r\nconsole.log(basicaRetorno());\r\n\r\n// Función básica con  retorno y parámetros\r\nfunction basicaRetornoParametro(a, b) {\r\n  return a + b;\r\n}\r\nconsole.log(basicaRetornoParametro(1, 3));\r\n\r\n// Función expression\r\nconst sum = function (a, b) {\r\n  return a + b;\r\n};\r\nconsole.log(sum(3, 5));\r\n\r\n// Función flecha\r\nconst saludar = (nombre) => {\r\n  console.log(\"Hola \" + nombre);\r\n};\r\nsaludar(\"Tomás\");\r\n\r\n// Función flecha con return implícito\r\nconst sumarFlecha = (a, b) => a + b;\r\nlet sumar = sumarFlecha(5, 6);\r\nconsole.log(sumar);\r\n\r\n// Función con variable de argumentos\r\nfunction variableArg(...names) {\r\n  for (let name of names) {\r\n    console.log(\"hola \" + name);\r\n  }\r\n}\r\n\r\nvariableArg(\"Tomas\", \"Paco\", \"Pepe\");\r\n\r\n//Funciones dentro de funciones\r\n\r\nfunction outerFunction() {\r\n  function innerFunction() {\r\n    console.log(\"Hola JavaScript\");\r\n  }\r\n  innerFunction();\r\n}\r\nouterFunction();\r\n\r\n// Funciones del lenguaje (built-in)\r\n\r\nconsole.log(Math.abs(-4)); // 4\r\nconsole.log(Math.cbrt(27)); // 3\r\n\r\nlet string = \"hola\";\r\nconsole.log(string.toUpperCase());\r\n\r\n// Variables glovales y locales\r\n\r\nlet globalVar = \"JavaScript\";\r\n\r\nfunction varGlobalLocal() {\r\n  let localVar = \"Local var\";\r\n  console.log(globalVar + \" \" + localVar);\r\n}\r\nvarGlobalLocal();\r\n\r\n/// Dificultad Extra\r\n\r\nfunction extraFunction(str1, str2) {\r\n  let dato = 0;\r\n  for (let i = 1; i < 100; i++) {\r\n    if (i % 3 === 0 && i % 5 === 0) {\r\n      console.log(str1 + \" \" + str2);\r\n    } else if (i % 3 === 0) {\r\n      console.log(str1);\r\n    } else if (i % 5 === 0) {\r\n      console.log(str2);\r\n    } else {\r\n      console.log(i);\r\n      dato += 1;\r\n    }\r\n  }\r\n  return dato;\r\n}\r\n\r\nextraFunction(\"Perro\", \"Gato\");\r\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/UserMatthew.js",
    "content": "/* #02 FUNCIONES Y ALCANCE\n## Ejercicio\n */\n\n// Funciones baseicas \n// ---- Función sin parametro ni retorno ----\nfunction saludoSimple() {\n  console.log(\"Hola, JavaScript\");\n}\nsaludoSimple(); \n// ---- Función con parametro  ----\n\nfunction saludoConParametro(nombre) {\n  console.log(`Hola, ${nombre}!`);\n}\nsaludoConParametro(\"JavaScript\"); \n// ---- Función con retorno ----\nfunction SumarNumeros(a,b) {\n    return a + b;\n} \nconsole.log(SumarNumeros(3,5))\n// Función dentro de una función\nfunction saludoConFuncionDentro(nombre) {\n    function saludoInterno() {\n        console.log(`Hola, ${nombre}!`);\n    }\n    saludoInterno();\n}\nsaludoConFuncionDentro(\"JavaScript\");\n\n// Variable global\nlet global = \"Variable global\";\n\nfunction variableGlobal() {\n    console.log(`Hola, ${global}!`);\n}\nvariableGlobal();\n// Variable local\n\nfunction variableLocal() {\n    let local = \"Variable local\";\n    console.log(`Hola, ${local}!`);\n}\nvariableLocal();\n\n// Arrow funtion\nlet arrowFuntion = (num) => {  return num % 2 === 0 ? `El numero ${num} es par` : `El numero ${num} es impar`; }\n\nconsole.log(arrowFuntion(5)); \n\n\nfunction imprimirNumeros(String1, String2) { \n    let contador = 0\n    for (let i = 1; i <= 100; i++) {\n        if (i % 3 === 0 && i % 5 === 0) {\n            console.log(String1 + String2);\n        } else if (i % 5 === 0) {\n            console.log(String2);\n        } else if (i % 3 === 0) {\n            console.log(String1);\n        } else {\n            console.log(i)\n            contador++\n            \n        }                  \n    }return `El total de numeros impresos es ${contador}`\n}\n\nconsole.log(imprimirNumeros(\"Buzz\", \"Frizz\"))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/VictorSSchz.js",
    "content": "let cont = 0; //variable global\n\n//funcion basica\nfunction saludar(){\n    console.log('Hola, buenos días')\n}\nsaludar();\n\n//funcion con parametro\nfunction saludarConocido(nombre){\n    console.log('Hola ' +nombre+ ' mucho gusto volver a verte')\n}\nsaludarConocido(\"Victor\");\n\n//funcion IIFE\n(function(){\n    console.log('Soy una IIFE que me llamo sola')\n})();\n\nlet numeros = [2,4,8,6,9,1]\n//Arroy Function con return implícito\nnumeros.sort((a,b)=>a-b) //ordenamos los números y utilizamos una arrow function\nconsole.log(numeros)\n\n//funcion basica con retorno\nfunction suma(a,b){\n    return a+b\n}\n\n//funcion dentro de función\nfunction resultadoMuliplicado(){\n    const sum = suma(3,2)\n    function multiplicacion(a,b){\n    \n        console.log('la multiplicacion es ' +a * b)\n    }\n    multiplicacion(sum,3)\n}\n\nresultadoMuliplicado()\n\n\n//Función dificultad extra \nfunction palabras(a,b){\n\n    for(let i=1;i<=100;i++){\n        if(i%3 === 0 && i%5 === 0){\n            console.log(a+b);\n        }\n        else if(i%3===0){\n            console.log(a)\n        }\n        else if(i%5===0){\n            console.log(b)\n        }\n        else{\n            console.log(i)\n            cont++;\n        }\n    }\n    return cont;\n}\n\nconst total= palabras('fizz','buzz')\n\nconsole.log('En total se han mostrado por pantalla ' + total +' numeros en lugar de palabras');"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/Vixito.js",
    "content": "function ej_1() {}\nlet ej_2 = function(a, b) {}\nconst ej_3 = (par_1, par_2) => {\n    return par_1 + par_2;\n}\nfunction ej_4() {\n    console.log(ej_3(1, 2));\n}\nej_4();\n\n\n// Funciones creadas por el lenguaje\nconst numeros = [1, 2, 3, 4];\nconsole.log(\"\\n\" + numeros.length + \", \" + numeros.push(Math.round(Math.random(Number.EPSILON)*numeros.length)));\nconsole.log(numeros);\n\n// Variables LOCAL y GLOBAL\n\nconst global = \"Soy una variable global\"\nconsole.log(\"\\n\" + global.includes(\"global\"));\n\nfunction Local(){\n    const local = \"Soy una variable local\";\n    console.log(local.includes(\"local\"));\n}\ntry {\n    console.log(local.includes(\"global\"));\n} catch (error) {\n    error.message;\n} finally{\n    console.log(\"No hay variable local (globalmente)\\n\");\n}\n\n// DIFICULTAD EXTRA\n\nfunction cadena_deTexto(cadena_1, cadena_2){\n    // Los parámetros convierten todo tipo de dato a String\n    cadena_1 = String(cadena_1);\n    cadena_2 = String(cadena_2);\n    let veces = 0;\n    for (let number = 1; number <= 100; number++){\n        if(number % 3 === 0 && number % 5 === 0){\n            console.log(cadena_1 + \" \" + cadena_2);\n        } else if(number % 3 === 0){\n            console.log(cadena_1);\n        } else if(number % 5 === 0){\n            console.log(cadena_2);\n        } else{\n            console.log(number);\n            veces++;\n        }\n    }\n    console.log(\"\\n\" + veces + \" números se han escrito.\");\n}\n\ncadena_deTexto(\"Fizz\", \"Buzz\");"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/VolumiDev.js",
    "content": "/**\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n//  ✳️ Funcion si parametros y sin retorno\nfunction greetins() {\n  console.log('Bienvenidos a JavaScript')\n}\n\ngreetins()\n\n//  ✳️ Funcion con parametro y sin retorno\nfunction paramFunction(lang, lang1) {\n\tconsole.log('Este lenguaje se lo hemos pasado por parametro:', lang, '\\ny lo mostramos en la practica de', lang1)\n}\n\nvar lang = 'python'\nvar lang1 = 'javascript'\nparamFunction(lang, lang1)\n\n//  ✳️ Funcion con parametros y con retorno, en esta funcion tambien cramos una nueva funcion \nfunction paramYReturn(a, b) {\n\tconsole.log('En esta funcion vamos a cambiar la variable \\na= '+a+'\\nb= '+b+'\\ny vamos a retornar el valor de la suma de los dos parametros que le hemos pasado')\n\tfunction sum (a, b){\n\t\treturn a+b\n\t}\n\n\treturn sum(a, b)\n}\n\nconsole.log(paramYReturn(4, 3), 'esta es el valor que retorno')\n\n// ✳️ Funciones propias del lenguaje\n\nconsole.log('esta es una funcion propia del lenguaje')\nvar cadena = 'las hemos pasado a mayusculas con otra funcion propia del lenguaje JS llamada touppercase()'\nconsole.log(cadena.toUpperCase())\n\n// ✳️ Local y Gobal\nconst constante = 'esta es una constante que no podemos modificar.'\nvar esGlobal = 'local'\nfunction mostrar(){\n\tconsole.log(constante)\n\tlet esDeBloque = 'solo de bloque'\n\tconsole.log(esGlobal)\n\tesGlobal = 'modificado dentro de la funcion'\n\tconsole.log(esDeBloque)\n}\n\nmostrar()\nconsole.log(esGlobal)\n\n// ✳️✳️ DIFICULTAD EXTRA\n\nfunction printNumbers(cad1, cad2) {\n\tvar n = 1\n\tvar cont = 0\n\twhile (n <= 100){\n\t\tif(n % 3 === 0 && n % 5 === 0){\n\t\t\tconsole.log('es',cad1,'y',cad2)\n\t\t}else if(n % 5 === 0){\n\t\t\tconsole.log('es',cad2)\n\t\t}else if(n % 3 === 0 ){\n\t\t\tconsole.log('es',cad1)\n\t\t} else {\n\t\t\tconsole.log(n)\n\t\t\tcont++\n\t\t}\n\t\tn++\n\t}\n\treturn cont\n}\n\nconsole.log('Se han impreso: ',printNumbers('multiplo de 3','multiplo de 5'), 'numeros')"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/YgriegaSB.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n*/\n\nconst arreglo = [];\n// Llena el arreglo con números del 1 al 100\nconst fillArray = () => {\n    for (let i = 1; i <= 100; i++) {\n        arreglo.push(i);\n    }\n}\n\n// Imprime \"Fizz\", \"Buzz\" o \"FizzBuzz\" en lugar de múltiplos de 3, 5 o ambos\nconst imprimirFizzBuzz = (cadena1, cadena2) => {\n    for (let i of arreglo){\n        console.log(\n            (i % 3 === 0 && i % 5 === 0) ? `${cadena1}${cadena2}` :\n            (i % 3 === 0) ? `${cadena1}` :\n            (i % 5 === 0) ? `${cadena2}` : `${i}`\n        );\n    }\n}\n\nfillArray();\nimprimirFizzBuzz('Fizz', 'Buzz');\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/Younes0-0.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n// Funcion básica\n\nfunction saludar() {\n  console.log(\"Hola Mundo!!\")\n}\nsaludar()\n\n// Funcion con parámetros\n\nfunction saludar2(texto) {\n  console.log(`Bienvenido ${texto}`)\n}\nsaludar2(\"Younes\")\n\n// Funcion con retorno\n\nfunction saludar3(texto) {\n  return `Hola ${texto}`\n}\nconsole.log(saludar3(\"Younes\"))\n\n// Funcion dentro de funcion\n\nfunction saludar4() {\n  function saludar5() {\n    console.log(\"Hola\")\n  }\n  saludar5()\n}\nsaludar4()\n\n// Funcion dentro de funcion con retorno\n\nfunction saludar6() {\n  function saludar7() {\n    return \"Hola\"\n  }\n  return saludar7()\n}\nconsole.log(saludar6())\n\n// Variable global\n\nlet variableGlobal = \"Variable global\"\nfunction saludar8() {\n  console.log(variableGlobal)\n}\nsaludar8()\nconsole.log(variableGlobal)\n\n// Variable local\n\nfunction saludar9() {\n  let variableLocal = \"Variable local\"\n  console.log(variableLocal)\n}\nsaludar9()\n// console.log(variableLocal) -> Error de ejecución\n\n//DIFICULTAD EXTRA\n\nfunction extra(texto1, texto) {\n  let contador = 0\n  for (let i = 1 ; i <= 100 ; i++) {\n    if (i % 3 == 0 && i % 5 == 0) {\n      console.log(texto1 + texto)\n    } else if (i % 3 == 0) {\n      console.log(texto1)\n    } else if (i % 5 == 0) {\n      console.log(texto)\n    } else {\n      console.log(i)\n      contador++\n    }\n  }\n  return `Los numeros impresos, que NO son texto, son: ${contador}`\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/Zunigaj1101.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n// Function \n// Without parameters\nfunction greeting () {\n    console.log ('Hello Wolrd')\n}\n\ngreeting ();\n\n// With one parameter\n\nfunction greetingPerson(name) {\n    console.log (`Hello ${name}`)    \n}\n\ngreetingPerson('Jose');\n\n// With two parameters and return\nfunction addition (a,b) {\n    return a + b\n}\n\nconsole.log (addition (1,3))\n\n// arrow funtion within a basic function, with a language function\n\nfunction outer () {\n    console.log ('This Basic Function is runnig')\n    const inner = () => {\n        console.log (\"This is a nested function executed by a language function\")\n    }\n    setTimeout(inner, 1500) // this is a language function\n}\n\nouter();\n\nlet myVarGlobal = 'This is a global variable'\n\nfunction testScope () {\nlet myVarLocal = 'This is a local variable'\n    console.log (myVarLocal)\n}\n\ntestScope ();\n\nconsole.log (myVarGlobal)\n// console.log (myVarLocal) no se puede acceder a esta variable, porque existe solo en la funcion testScope \n\n// * DIFICULTAD EXTRA (opcional):\n// * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n// * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n// *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n// *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n// *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n// *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\n\nfunction isMultipleOf (param1, param2){\n    let counter = 0\n\n    for (let i = 1; i <= 100; i++ ) {\n        if (i % param1 === 0 && i % param2 === 0) {\n            console.log (`${i} is multiple of ${param1} and ${param2}`)\n        } else if (i % param1 === 0) {\n            console.log (`${i} is multiple of ${param1}`) \n        } else if (i % param2 === 0){\n            console.log (`${i} is multiple of ${param2}`) \n        } else {\n            counter++\n            console.log (i)\n        }\n    } console.log (`In this loop, ${counter} number not divisible between ${param1} and ${param2} were counted`)\n}\n\nisMultipleOf(3, 5); // Funciona para cualquier parametros numericos"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/aarxnmendez.js",
    "content": "// Ejemplo de funciones básicas en JavaScript\r\n\r\n// Función sin parámetros ni retorno\r\nfunction saludo() {\r\n    console.log(\"Hola, mundo!\");\r\n}\r\nsaludo();\r\n\r\n// Función con un parámetro\r\nfunction saludar(nombre) {\r\n    console.log(`Hola, ${nombre}!`);\r\n}\r\nsaludar(\"Juan\");\r\n\r\n// Función con varios parámetros\r\nfunction suma(a, b) {\r\n    console.log(`La suma de ${a} y ${b} es ${a + b}`);\r\n}\r\nsuma(5, 10);\r\n\r\n// Función con retorno\r\nfunction multiplicar(a, b) {\r\n    return a * b;\r\n}\r\nlet resultadoMultiplicacion = multiplicar(3, 4);\r\nconsole.log(`El resultado de la multiplicación es: ${resultadoMultiplicacion}`);\r\n\r\n// Función dentro de otra función\r\nfunction operacionPrincipal(a, b) {\r\n    function resta(x, y) {\r\n        return x - y;\r\n    }\r\n    console.log(`La resta de ${a} y ${b} es ${resta(a, b)}`);\r\n}\r\noperacionPrincipal(10, 7);\r\n\r\n// Uso de una función ya creada en el lenguaje\r\nlet numeroAleatorio = Math.random(); // Función para generar un número aleatorio\r\nconsole.log(`Número aleatorio generado: ${numeroAleatorio}`);\r\n\r\n// Variables locales y globales\r\nlet globalVariable = \"Soy global\";\r\n\r\nfunction pruebaVariables() {\r\n    let localVariable = \"Soy local\";\r\n    console.log(globalVariable); // Acceso a variable global\r\n    console.log(localVariable);  // Acceso a variable local\r\n}\r\npruebaVariables();\r\n// console.log(localVariable); // Esto dará un error porque localVariable es local a la función\r\n\r\n// DIFICULTAD EXTRA\r\nfunction multiplesDeTexto(cadena1, cadena2) {\r\n    let conteo = 0;\r\n\r\n    for (let i = 1; i <= 100; i++) {\r\n        if (i % 3 === 0 && i % 5 === 0) {\r\n            console.log(`${cadena1}${cadena2}`);\r\n        } else if (i % 3 === 0) {\r\n            console.log(cadena1);\r\n        } else if (i % 5 === 0) {\r\n            console.log(cadena2);\r\n        } else {\r\n            console.log(i);\r\n            conteo++;\r\n        }\r\n    }\r\n    return conteo;\r\n}\r\n\r\nlet vecesImpreso = multiplesDeTexto(\"Fizz\", \"Buzz\");\r\nconsole.log(`El número de veces que se imprimió un número es: ${vecesImpreso}`);\r\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/adant11235.js",
    "content": "//FUNCIONES BASICAS   \n//Definidas por el usuario\n\n\n//simple\n\nfunction saludar() {\n  console.log(\"Hola Javascript\");\n}\nsaludar();\n\n\n//con retorno\n\nlet hola = \"Hola Adant\"\n\nfunction returnSaludo() {\n  console.log(hola);\n  return hola;\n}\nsaludar();\nreturnSaludo();\n\nconsole.log(\"<br>\");\n\nfunction retSaludo()  {\n  return \"Hola Adant\"\n}\nconsole.log(retSaludo());\n\n\n//con argumento\n\nfunction argSaludo(name) {\n  console.log(`Hola ${name}`)\n}\nargSaludo(\"Brais\");\n\n\n//con un argumento predetermindao\n\nfunction defSaludo(lenguaje =\"Java\") {\n  console.log(`Hola ${lenguaje}`)\n}\ndefSaludo();\ndefSaludo(\"Javascript\");\n\nconsole.log(\"<br>\");\n\n\n//con numero variable de argumentos\n\nfunction varArgSaludo(...nombres) {\n  for(nombre of nombres) {\n    console.log(`Hola ${nombre} !`)\n  }\n}\nvarArgSaludo(\"Adant\", \"Javascript\", \"Brais\");\n\nconsole.log(\"<br>\");\n\n\n//funcines asignadas a constantes\n\nconst constSaludo = function (name) {\n  console.log(`Holaaa ${name}`)\n}\nconstSaludo(\"Adant\");\n\n\n//arrows\n\nconst flechaSaludo = (name) => {\n  console.log(`Hola ${name}`)\n}\nflechaSaludo(\"Adanta\");\n\n\nlet flecha2Saludo = (name) => console.log(`Hola holita ${name}`);\n\nflecha2Saludo(\"Javascript\");\n\n\nconsole.log(\"<br>\");\n\n\n//FUNCIÖN DENTRO DE OTRA FUNCIÖN\n\nfunction outerFunc() {\n  function innerFunc() {\n    console.log(\"Hola función interna\");\n  }innerFunc();\n}\nouterFunc();\n\nconsole.log(\"<br>\");\n\n\n//EJEMPLOS DEFUNCIONES PROPRIA DEL LENGUAJE  (BUILT-IN)   METODOS\n\nconsole.log(\"Hola\");\n\nconsole.log(typeof(\"23\"));\nconsole.log(parseFloat(\"23\"));\n\nconsole.log(parseInt(\"32\"));\nconsole.log(typeof(32));\n\nconsole.log(isNaN(\"32\"));\nconsole.log(isNaN(32));\nconsole.log(isNaN(\"Hola\"));\n\nconsole.log(Math.max(2, 3, 10));\n\nconsole.log(Math.round(1,19));\n\nconsole.log(Math.PI);\n\nconsole.log(Date());\n\n\nconsole.log(\"<br>\");\n\n\n//Ambito (scope)\n\n//var GLOBAL = fuera de una función\n\nlet globVar = \"Javascript\";   //global\nconsole.log(globVar);\n\nfunction hiJava() {\n  console.log(`Hola ${globVar}`);\n}\nhiJava();\n\n//var LOCAL = dentro de la función\n\nfunction hiLocalJava() {\n  locVar = \"Hola\";    //local\n  console.log(`${locVar} ${globVar}`);\n}\nhiLocalJava();\n\nconsole.log(locVar);\n//En Javascript se puede llamar una var interna desde fuera de la func\n\nconsole.log(\"<br>\");\n\n\n//Dificultad EXTRA\n\n\nfunction contNum(a = \"a\", b = \"b\") {\n  let counter = 0\n  for(let num = 1; num <= 100; num++) {\n    \n  if(num % 3 === 0 && num % 5 === 0) {\n    console.log(a + b);\n  } else if(num % 5 === 0) {\n      console.log(b);\n  } else if(num % 3 === 0) {\n      console.log(a);\n  } else{\n      console.log(num);\n      counter++\n    }\n  } console.log(`Se han contado numeros ${counter} veces`);\n}\ncontNum();\n\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/adrs1166ma.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n\n// 🔥 Función sin parámetros ni retorno\nfunction sinParametros() {\n    console.log(\"Función sin parámetros ni retorno\");\n}\nsinParametros();\n\n// 🔥 Función con uno o varios parámetros\nfunction conParametros(a, b) {\n    console.log(`La suma de ${a} y ${b} es:`, a + b);\n}\nconParametros(5, 10);\n\n// 🔥 Función con retorno\nfunction conRetorno(a, b) {\n    return a * b;\n}\nconsole.log(\"El producto de 4 y 6 es:\", conRetorno(4, 6));\n\n// 🔥 Funciones dentro de funciones\nfunction externa() {\n    console.log(\"Función externa ejecutada\");\n    function interna() {\n        console.log(\"Función interna ejecutada\");\n    }\n    interna();\n}\nexterna();\n\n// 🔥 Uso de funciones nativas del lenguaje\nconsole.log(\"Longitud de la palabra 'JavaScript':\", \"JavaScript\".length);\n\n// 🔥 Variables globales y locales\nlet globalVar = \"Soy una variable global\";\nfunction testScope() {\n    let localVar = \"Soy una variable local\";\n    console.log(globalVar);\n    console.log(localVar);\n}\ntestScope();\n// console.log(localVar); // Esto generaría un error, ya que localVar es local\n\n// 🔥 Extra\nfunction contarNumeros(texto1, texto2) {\n    let count = 0;\n    for (let i = 1; i <= 100; i++) {\n        if (i % 3 === 0 && i % 5 === 0) {\n            console.log(texto1 + texto2);\n        } else if (i % 3 === 0) {\n            console.log(texto1);\n        } else if (i % 5 === 0) {\n            console.log(texto2);\n        } else {\n            console.log(i);\n            count++;\n        }\n    }\n    return count;\n}\n\nlet resultado = contarNumeros(\"Fizz\", \"Buzz\");\nconsole.log(\"Cantidad de números impresos en lugar de texto:\", resultado);\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/agusrosero.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\nfunction sinParametroNiRetorno() {\n  console.log(\"Hola Javascript!\");\n}\n\nsinParametroNiRetorno();\n\nfunction conParametro(name) {\n  console.log(`Hola ${name}`);\n}\n\nconParametro(\"Hernan\");\n\nfunction conRetorno(n1, n2) {\n  return n1 + n2;\n}\n\nconsole.log(conRetorno(100, 125));\n\nfunction funcionDentroDeOtra() {\n  function saludo() {\n    console.log(\"Saludo desde la otra funcion\");\n  }\n  return saludo();\n}\n\nfuncionDentroDeOtra();\n\n// funciones ya creadas en el lenguaje\nfunction funcionYaCreada() {\n  alert(\"¡Hola Mundo!\");\n}\n\n// variables LOCALES y GLOBALES\nlet varGlobal = \"Variable global!\";\n\nfunction mostrarGlobal() {\n  console.log(varGlobal);\n}\n\nmostrarGlobal();\n\nfunction mostrarLocales() {\n  let varLocal = \"Variable local!\";\n  console.log(varLocal);\n}\n\nmostrarLocales();\n\n// DIFICULTAD EXTRA:\nfunction main(str1, str2) {\n  contador = 0;\n  for (let i = 1; i <= 100; i++) {\n    if (i % 5 == 0 && i % 3 == 0) {\n      console.log(str1 + str2);\n    } else if (i % 5 == 0) {\n      console.log(str2);\n    } else if (i % 3 == 0) {\n      console.log(str1);\n    } else {\n      contador++;\n    }\n  }\n  return contador;\n}\n\nconsole.log(main(\"hello\", \"javascript\"));\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/alexdevrep.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n//Función sin parámetros ni retorno\nfunction simpleFunction(){\n    console.log(\"Hola Mundo!\")\n}\nsimpleFunction()\n\n// Función con un parámetro\nfunction oneArg(Arg1){\n    console.log(`Hola ${Arg1}`) //${} sirve para inyectar variables en una cadena de texto\n\n}\noneArg(\"JavaScript\")\n\n//Función con varios parámetros\nfunction manyArgs(día,mes,año){\n    console.log(`Hoy es ${día} del ${mes} del ${año}`)\n\n}\nmanyArgs(9,1,2024)\n\n//Función con retorno\nfunction withReturn(a,b){\n    return a + b //return nos permite guardar el resultado de la función en una variable\n}\nresultado= withReturn(2,3)\nconsole.log(resultado)\n\n//Funciones dentro de funciones\nfunction funcionPadre(sum3){\n    function funcionHijo(sum1,sum2){\n        return sum1 + sum2\n    }\nresultadoHijo = funcionHijo(1,2)\nconsole.log (\"El resultado de la suma de las 2 funciones es:\",resultadoHijo + sum3)\n\n}\nfuncionPadre(3)\n\n//Funciones ya creadas en el lenguaje\n\n//Math.random\nconst number = Math.random()\nconsole.log(number)\n\n//Variable global (es una variable que está declarada fuera de la función y puede accederse a ella desde cualquier punto del código)\nlet variable1 = 8\nfunction suma (){\n    console.log(\"El resultado es:\", variable1 + 3)\n}\nsuma()\n\n//Variable local (es una variable que está declarada dentro de una función y solo puede usarse dentro de ella)\nfunction resta (){\n    let variable2 = 2\n    console.log(\"El resultado de la resta es\",variable2 - 1)\n}\nresta()\n\n//DIFICULTAD EXTRA\nfunction extra (string1,string2){\n    let numero = 0\n    for(let i=1;i<=100;i++){\n        \n        if (i%3==0 && i%5==0){\n            console.log(string1+\" \"+string2)\n            continue\n        }\n        else if(i%3==0){\n            console.log(string1)\n            continue\n        }\n        else if (i%5==0){\n            console.log(string2)\n            continue\n        }\n        else {\n            console.log(i)\n        }\n        \n        numero ++\n    }\n    return numero\n}\nconsole.log(\"Numero de veces que se ha impreso el contador:\",extra(\"Hola JavaScript\",\"Hola alexdevrep\"))\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/andresgcastillo.js",
    "content": "// Function without parameters and return value\nfunction sayHello() {\n  console.log(\"Hello!\");\n}\n\nsayHello();\n\n// Function with parameters and return value\nfunction addNumbers(a, b) {\n  return a + b;\n}\n\nconsole.log(addNumbers(23, 32));\n\n// Function within a function\nfunction outerFunction() {\n  console.log(\"Outer function\");\n\n  function innerFunction() {\n    console.log(\"Inner function\");\n  }\n\n  innerFunction();\n}\n\nouterFunction();\n\n// Using built-in functions\nconsole.log(Math.random());\n\n// Local and global variables\nfunction localAndGlobal() {\n  var localVariable = \"I am a local variable\";\n  globalVariable = \"I am a global variable\";\n\n  console.log(localVariable);\n  console.log(globalVariable);\n}\n\nlocalAndGlobal();\nconsole.log(globalVariable);\n\n// Arrow functions\n\n// Function without parameters and return value\nconst sayHello2 = () => console.log(\"Hello!\");\nsayHello2();\n\n// Function with parameters and return value\nconst addNumbers2 = (a, b) => a + b;\nconsole.log(addNumbers2(23, 32));\n\n// Function within a function\nconst outerFunction2 = () => {\n  console.log(\"Outer function\");\n\n  const innerFunction2 = () => console.log(\"Inner function\");\n\n  innerFunction2();\n};\n\nouterFunction2();\n\n// Local and global variables\nconst localAndGlobal2 = () => {\n  const localVariable2 = \"I am a local variable\";\n  globalVariable2 = \"I am a global variable\";\n\n  console.log(localVariable2);\n  console.log(globalVariable2);\n};\n\nlocalAndGlobal2();\nconsole.log(globalVariable2);\n\n//Dificultad Extra\nfunction imprimirNumerosYTextos(cadena1, cadena2) {\n  let contador = 0;\n  for (let i = 1; i <= 100; i++) {\n    if (i % 3 === 0 && i % 5 === 0) {\n      console.log(cadena1 + \" \" + cadena2);\n    } else if (i % 3 === 0) {\n      console.log(cadena1);\n    } else if (i % 5 === 0) {\n      console.log(cadena2);\n    } else {\n      console.log(i);\n      contador++;\n    }\n  }\n  return \"\\nCantidad de veces que se imprimio numeros: \" + contador;\n}\n\nconsole.log(imprimirNumerosYTextos(\"Ludwig\", \"Wolfgang\"));\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/andyfg0289.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n//Función básica. declarando una función \nlet nombre = 'Andy Fernandez';\nlet edad = 35;\nvar color = 'rojo';\nlet objetos = {\n    coche: 'deportivo',\n    estancia: 'Motel',\n    dolares: 200\n}\n\nfunction identidad(nombreCompleto, edad) {\n    return `El usuario se llama ${nombreCompleto} y tiene ${edad} años de edad`;\n}\n\nconsole.log(identidad(nombre, edad));\nconsole.log('\\n');\n\nfunction cambioIdentidad(nombreCompleto, edad, color) {\n    //Solo modifica los datos de las variables de forma local\n    nombreCompleto = 'Martin Pérez';\n    edad = 25;\n    color = 'verde';\n    return `El usuario se llama ${nombreCompleto} y tiene ${edad} años de edad y le gusta el color ${color}`;\n\n}\n\nconsole.log(cambioIdentidad(nombre, edad, color));//El usuario se llama Martin Pérez y tiene 25 años de edad\nconsole.log(`El usuario se llama realmente ${nombre}y tiene ${edad} años de edad`);\nconsole.log('\\n');\n\nfunction masDatos(datos) {\n    this.dolares = 100;\n\n    return `El usuario maneja un ${datos.coche} y se esta quedando en un ${datos.estancia} de ${this.dolares} dólares`;\n}\n\nconsole.log(masDatos(objetos));\n\n//console.log(`El usuario evito pagar un ${datos.estancia} de ${datos.dolares} de renta`);// Solo se puede acceder a datos desde la funcion masDatos\nconsole.log(`El usuario evito pagar un ${objetos.estancia} de ${objetos.dolares} dólares de renta`);\nconsole.log('\\n');\n\n/////Expresiones function\n\nconst mayorDedad = function (edad) {\n    if (edad < 18) {\n        return 'Eres menor de edad';\n    } else {\n        return 'Eres mayor de edad';\n    }\n}\n\nconsole.log(mayorDedad(edad));//eres mayor de edad\n\n///Expresión función con nombre\n\n\nconst hacerMayor = function menor(edad) {\n    if (edad <= 18) {\n\n        edad = menor(edad + 1);\n    }\n    return edad;\n}\n\nconsole.log(\"Te hiciste mayor ahora tienes \" + hacerMayor(9) + \"años de edad.\");\nconsole.log('\\n');\n\n//Función que recibe como parámetro otra función\n\nlet array = [1, 2, 3, 4, 5, 6, 7, 8, 9];\n\nfunction fun(x) {\n    return x * 2;\n}\n\nfunction map(f, a) {\n    let result = [];\n    for (let i = 0; i < a.length; i++) {\n        result[i] = f(a[i]);\n    }\n    return result\n\n}\n\nconsole.log(map(fun, array));//(9) [2, 4, 6, 8, 10, 12, 14, 16, 18]\n\n//  Recursividad \n\nlet access = false;\nlet pass = 123456;\nlet keys = 3;\n\nfunction checkUser() {\n    let password = prompt(\"Introduce el password\");\n    if (pass == password && password !== \"\" && keys >= 0) {\n        access = true;\n        console.log(\"Puedes acceder\");\n        alert(\"Puedes acceder\");\n    } else if (keys === 0) {\n        console.log(\"Agotado el máximo de intentos, vuelva a intentarlo más tarde\");\n        return alert(\"Agotado el máximo de intentos, vuelva a intentarlo más tarde\");\n    } else {\n        alert(\"Password incorrecto\");\n        console.log(\"Acceso denegado, Password incorrecto\");\n        keys--;\n        console.log(keys);\n        checkUser();\n    }\n}\n//DESCOMENTAR PARA PROGAR EL CODIGO\n//checkUser();\n\n//Ambito con funcion anidada\n\nfunction getData() {\n\n    let yob = 1989;\n\n    function tellme() {\n        return nombre + \" tiene \" + edad + \" años y nació en \" + yob;\n    }\n    return tellme()\n}\n\nconsole.log(getData());//Andy Fernández tiene 35 y nació en1989\nconsole.log('\\n');\n\nfunction getName(name) {\n    function getAge(age) {\n        return name + \" \" + age;\n    }\n    return getAge;\n}\n\ngiveName = getName(nombre);//Aqui definimos name con el valor nombre\ngiveAge = giveName(edad); //Aqui ya que name = nombre por lo tanto age = edad\n\nconsole.log(giveAge);// Andy Fernández 35\nconsole.log(getName(nombre)(edad));// Andy Fernández 35\nconsole.log('\\n');\n\n//Funciones multianidadas \n\nfunction salario(num1) {\n    let clave = 123;\n    //console.log(clave2);// Da error ya que no se puede acceder a la funcion interna de  vacaciones()\n    function vacaciones(num2) {//permanece privado para salario\n        let clave2 = 456;\n        // console.log(clave3);// Da error ya que no se puede acceder a la funcion interna de  tiempoExtra()\n        console.log(clave)// Puede acceder a salario ya que tiene un cierre con este \n        function tiempoExtra(num3) {//permanece privado para salario y vacaciones\n            console.log(clave)// 123 // Si puede acceder a las variables de funciones exteriores ya que crea un cierre de vacaciones y salario\n            console.log(clave2)// 456\n            let clave3 = 789;\n            console.log(num1 + num2 + num3);\n        }\n        tiempoExtra(3);\n    }\n    vacaciones(2);\n}\nsalario(1); //6\n\n//Funciones con parámetros predeterminados\n\nlet phone;\n\nfunction tellPhone(number = 911) {\n    return number;\n}\n\nconsole.log(tellPhone());\n\n//Funciones con parámetros rest\n\nfunction resto(resto, ...numbers) {\n    return numbers.map((n) => resto - n);\n}\n\nlet num = resto(10, 5, 4, 2);//A 10 le vamos restando numbers en cada caso\nconsole.log(num);// [5,6,8]\n\n//Funciones flecha\n\nconst saludo = ((nombre, edad) => {\n    console.log(`Hola ${nombre} de ${edad} años.`)\n})\n\nsaludo(nombre, edad);\n\n//Ejemplo de función ya creada en el lenguaje\nconst float = 12.4;\n\nconsole.log(parseFloat(float));//12.4\n\n/*  * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos. */\n\nfunction numCounter(cadena1, cadena2) {\n    let count = 0;\n    for (let i = 1; i <= 100; i++) {\n        if (i % 3 === 0 && i % 5 === 0) {\n            console.log(i + ' ' + cadena1 + ' y ' + cadena2);\n        } else {\n            if (i % 3 === 0) {\n                console.log(i + ' ' + cadena1);\n            } else if (i % 5 === 0) {\n                console.log(i + ' ' + cadena2);\n            } else {\n                count++;\n                console.log(i + ' ' + count);\n\n            }\n        }\n    }\n    return count;\n}\n\nconsole.log(numCounter('es múltiplo de 3', 'es múltiplo de 5'));"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/angelsanchezt.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n/*\nFunciones definidas por el usuario\n*/\n\n// Simple\nfunction greet() {\n    console.log(\"Hola, JavaScript!\");\n}\n\ngreet();\n\n// Con retorno\nfunction returnGreet() {\n    return \"Hola, JavaScript!\";\n}\n\nconsole.log(returnGreet());\n\n// Con un argumento\nfunction argGreet(name) {\n    console.log(`Hola, ${name}!`);\n}\n\nargGreet(\"Angel\");\n\n// Con argumentos\nfunction argsGreet(saludo, nombre) {\n    console.log(`${saludo}, ${nombre}! `);\n}\n\nargsGreet(\"Hi\", \"Angel\");\n\n\n// Con un argumento predeterminado\nfunction defaultArgGreet(name = \"JavaScript\") {\n    console.log(`Hola, ${name}!`);\n}\n\ndefaultArgGreet(\"Angel\");\ndefaultArgGreet();\n\n// Con argumentos y return\nfunction returnArgsGreet(greet, name) {\n    return `${greet}, ${name}!`;\n}\n\nconsole.log(returnArgsGreet(\"Hi\", \"Angel\"));\n\n// Con retorno de varios valores\nfunction multipleReturnGreet() {\n    return [\"Hola\", \"JavaScript\"];\n}\n\nlet [greetWord, language] = multipleReturnGreet();\nconsole.log(greetWord);\nconsole.log(language);\n\n// Con un número variable de argumentos\nfunction variableArgGreet(...names) {\n    for (let name of names) {\n        console.log(`Hola, ${name}!`);\n    }\n}\n\nvariableArgGreet(\"JavaScript\", \"Angel\", \"Sanchez\", \"comunidad\");\n\n// Con un número variable de argumentos con palabra clave\nfunction variableKeyArgGreet(names) {\n    for (let [key, value] of Object.entries(names)) {\n        console.log(`${value} (${key})!`);\n    }\n}\n\nvariableKeyArgGreet({\n    language: \"JavaScript\",\n    name: \"Angel\",\n    alias: \"angelsanchezt\",\n    age: 36\n});\n\n/*\nFunciones dentro de funciones\n*/\n\nfunction outerFunction() {\n    function innerFunction() {\n        console.log(\"Función interna: Hola, JavaScript !\");\n    }\n    innerFunction();\n}\n\nouterFunction();\n\n/*\nFunciones del lenguaje (built-in)\n*/\n\nconsole.log(\"Angel\".length);\nconsole.log(typeof 36);\nconsole.log(\"Angel\".toUpperCase());\n\n/*\nVariables locales y globales\n*/\n\nlet globalVar = \"JavaScript\";\n\nfunction helloJavaScript() {\n    let localVar = \"Hola\";\n    console.log(`${localVar}, ${globalVar}!`);\n}\n\nconsole.log(globalVar);\n// console.log(localVar); // No se puede acceder desde fuera de la función\n\nhelloJavaScript();\n\n/*\nExtra\n*/\n\nfunction printNumbers(text1, text2) {\n    let count = 0;\n    for (let number = 1; number <= 100; number++) {\n        if (number % 3 === 0 && number % 5 === 0) {\n            console.log(text1 + text2);\n        } else if (number % 3 === 0) {\n            console.log(text1);\n        } else if (number % 5 === 0) {\n            console.log(text2);\n        } else {\n            console.log(number);\n            count++;\n        }\n    }\n    return count;\n}\n\nconsole.log(printNumbers(\"Fizz\", \"Buzz\"));\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/angelurrutdev.js",
    "content": "/*\n * EJERCICIO:\n *  X -Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *  X Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n *  X- Comprueba si puedes crear funciones dentro de funciones.\n *  X-Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n *  X-Pon a prueba el concepto de variable LOCAL y GLOBAL.\n *  X-Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n*/\n\n\n// Funciones básicas definidas por el usuario\n\nfunction greet () {\n    console.log(\"Hola mundo\");\n}\n\ngreet()\n\n// Funcion con retorno\n\nfunction withreturn () {\n    return \"Hola mundo\";\n}\n\n// Funcion con argumentos (parametros)\n\nfunction arg_greet(name) {\n    console.log(\"Hola \" + name);\n}\n\narg_greet(\"Antonio\");\n\n// Funcion con varios argumentos    \n\nfunction arg_greet(greet, name){\n    console.log(\"Buenos dias, \" + greet + \" \" + name);\n}\n\narg_greet(\"Hola\", \"Antonio\");\n\n// Funcion con varios argumentos y retorno\n\nfunction returns_with ( greet, name, apellido ){\n\n    return \"Buenos dias, \" + greet + \" \" + name + \" \" + apellido;\n}\n\nreturns_with(\"Adios\", \"Antonio\", \"Perez\")\n\n// Funcion predeterminada\n\nfunction predeterm ( name=\"Antonio\" ) {\n    return name\n}\n\npredeterm()\npredeterm(\"Angel\")\n\nconsole.log.length(\"Hola Mundo\")\n\nconsole.log(typeof console.log(\"Hola\"))\n\n\n// Funciones dentro de funciones\n\nfunction function_in_function (){\n    return function(){\n        console.log(\"Hola Mundo de una funcion dentro de una funcion\")\n    }\n}\n\n\n\n// Variables locales y globales (scope)\n\n\nlet global_variable = \"JavaScript\"\n\nfunction hello_js() {\n    let local_variable\n    console.log(`Hola ${global_variable}`);\n    console.log(`Hola ${local_variable}`);\n}\n\nhello_js()\n\n// * DIFICULTAD EXTRA (opcional):\n//  * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n//  * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n//  *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n//  *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n//  *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n//  *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\n\nfunction extra (string1,string2){\n    let numero = 0\n    for(let i=1;i<=100;i++){\n        \n        if (i%3==0 && i%5==0){\n            console.log(string1+\" \"+string2)\n            continue\n        }\n        else if(i%3==0){\n            console.log(string1)\n            continue\n        }\n        else if (i%5==0){\n            console.log(string2)\n            continue\n        }\n        else {\n            console.log(i)\n        }\n        \n        numero ++\n    }\n    return numero\n}\nconsole.log(\"Numero de veces que se ha impreso el contador:\",extra(\"Hola JavaScript\",\"Hola alexdevrep\"))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/ant000o.js",
    "content": "// EJERCICIO:\n//      Crea ejemplos de funciones básicas que representen las diferentes posibilidades del lenguaje: Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n//  * - Debes hacer print por consola del resultado de todos los ejemplos.\n\n// Sin parámetros ni retorno:\nfunction myFunction(){\n    console.log(\"Función básica\");\n}\nmyFunction();\n\n\n// Varios parámetros y retorno\nconsole.log(\"---------------------------------------------------------------\")\nfunction operacion(a, b, c){\n    return `El resultado de (${a}+${b})*${c} es ${(a + b) * c}`;\n}\nlet result = operacion(2,5,7);\nconsole.log(result);\n\n// Valores por defecto en parámetros\nconsole.log(\"---------------------------------------------------------------\")\nfunction saludar(nombre = \"Mundo!\", saludo = \"Hola\") {\n    return `${saludo}, ${nombre}!`;\n}\nconsole.log(saludar());\n\n\n// Función Flecha\nconsole.log(\"---------------------------------------------------------------\")\nlet multiplicacion = (a, b) => a * b;\nconsole.log(multiplicacion(5, 4));\n\n\n// Función Anónima\nconsole.log(\"---------------------------------------------------------------\")\n// No tiene nombre, se guarda en una variable\nconst anonima = function(){\n    console.log(\"Función Anónima\");\n};\nanonima();\n\n\n//  * - Comprueba si puedes crear funciones dentro de funciones.\nconsole.log(\"---------------------------------------------------------------\")\n\nfunction externa(nombre){\n    function interna(){\n        console.log(`Hola ${nombre}`)\n    }\n    interna();\n}\nexterna(\"ant000o\");\n\n\n//  * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\nconsole.log(\"---------------------------------------------------------------\")\nlet fruta = \"manzana\"\nconsole.log(`Tengo una ${fruta.toUpperCase()}`);\n\n\nconsole.log(\"---------------------------------------------------------------\")\n//  * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\nlet global = \"global\" // se puede usar dentro y fuera de funciones\nfunction newFunction(){\n    let local = \"local\"; //solo se puede usar dentro de la funcion\n    console.log(local + \" + \" + global);\n}\nnewFunction();\nconsole.log(\"---------------------------------------------------------------\")\ntry{\n    console.log(local + global)\n}catch(error){\n    console.log(\"Error:\", error.message);\n}finally{\n    console.log(\"La variable local no se reconoce, ya que fue creada dentro de la funcion 'newFunction'.\")\n}\n\n\nconsole.log(\"---------------------------------------------------------------\")\n//  * DIFICULTAD EXTRA (opcional):\n//  * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n//  * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n//  *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n//  *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n//  *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n//  *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n//  *\n//  * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n//  * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n//  */\n\nfunction textNumbers(primero = \"Hola\", segundo = \"Mundo!\"){\n    let contador = 0;\n    for (let i = 1; i <= 100; i++){\n        if (i % 3 === 0 && i % 5 === 0){\n            console.log(`${primero} ${segundo}`)\n        }else if(i % 5 === 0){\n            console.log(`${segundo}`)\n        }else if(i % 3 === 0){\n            console.log(`${primero}`)\n        }\n        else{\n            console.log(i)\n            contador++\n        }\n} return contador\n}\nlet resultado = textNumbers();\nconsole.log(\"Se imprimió un número: \" + resultado + \" veces\");"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/arbenisacosta.js",
    "content": "// FUNCIONES Y ALCANCE\n\n\n/*\n * Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * */\n\n// --- Sin parámetros ni retorno\nconsole.log('*** Sin parámetros ni retorno ***');\nfunction myFuncion() {\n  console.log('Hello Word');\n}\nmyFuncion();\n\n// --- con uno o varios parámetros\nconsole.log('*** Con uno o varios parámetros ***');\nfunction saludo(nombre) {\n  console.log(`Hola ${nombre}`);\n}\nsaludo('Arbenis');\n\n// con retorno\nconsole.log('*** Con retorno ***');\nfunction retornoSuma(num1, num2) {\n  return num1 + num2;\n}\nconst resultado = retornoSuma(1, 2);\n\nconsole.log(resultado);\n\n// ---- Comprueba si puedes crear funciones dentro de funciones.\nconsole.log('***Función dentro de otra Función***');\nfunction multiplicar(valor1) {\n  return function (valor2) {\n    return valor1 * valor2;\n  }\n}\n\nlet duplicar = multiplicar(2);\nconsole.log(duplicar(5));\n\n// ---- Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\nconsole.log('***Utiliza algún ejemplo de funciones ya creadas en el lenguaje***');\n\nlet aleatorio = Math.random(); // Funcion Math.random Devuelve un número flotante aleatorio entre 0 y 1 (sin incluir el 1):¿\nconsole.log(aleatorio); // funcion console.log() Escribe un mensaje en la consola web o en el intérprete de JavaScript\n\n// ---- - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n\nvar x = \"función externa declarada\"; // Variable Global\n\nscopeFunction();\n\nfunction scopeFunction() {\n  let interna = \"funcion interna\" // Variable local\n  console.log(interna);\n  console.log(x);\n}\n\nconsole.log(\"funcion externa\");\nconsole.log(x);\n\n\n// ---- EXTRA ----\n\n/**\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n */\n\n\n\nfunction ejercicioExtra(parametro1, parametro2) {\n  let contador = 0;\n  for (let i = 1; i <= 100; i++) {\n    if (i % 3 === 0 && i % 5 === 0) {\n      console.log(parametro1 + parametro2);\n    } else if (i % 3 === 0) {\n      console.log(parametro1);\n    } else if (i % 5 === 0) {\n      console.log(parametro2);\n    } else {\n      contador += 1;\n    }\n  }\n  return contador;\n}\n\nlet impreso = ejercicioExtra(\"Pin\", \"Pon\");\nconsole.log(`Número de veces que se imprimió el número: \", ${impreso}` );\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/asaelz.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n\n\n// FUNCIONES SIN PARAMETROS NI RETORNO\nfunction Saludo() {\n    console.log(\"Hola Usuario\"); //Hola Usuario\n}\n\nconsole.log(Saludo()) //undefined\n//las funciones que no tienen retorno regresan el valor \"undefined\"\n\n// FUNCIONES CON PARAMETROS Y RETORNO \nfunction SaludarUsuario(nombre) {\n    return 'Hola @'+ nombre\n}\n\n// CON VARIOS PARAMETROS\nfunction EsMayorDeEdad(nombre, edad) {\n    let mensaje = ''\n    edad >= 18 ? mensaje = 'sos mayor de edad' : mensaje='no sos mayor de edad'\n    return 'Hola @'+ nombre + ' tenes ' + edad + ', ' + mensaje\n}\nconsole.log(EsMayorDeEdad('Carlos',16))\n\n// para llamar a esta funcion debemos pasarle el argumento \nconsole.log(SaludarUsuario(\"asaelz\")) //Hola @asaelz\n\n// FUNCTION EXPRESSION --> una funcion es asignada a una variable \nconst suma = function (n1, n2) {\n    return n1 + n2;\n}\n\nconsole.log(suma(55,1)) //56\n\n//ARROW FUNCTION\n//PARA EJEMPLIFICAR LAS ARROW FUNCTION UTILIZAREMOS NUESTRA FUNCION SALUDAR USUARIO \nconst SaludarUsuario2 = (usuario) => 'Hola @' +usuario\nconsole.log(SaludarUsuario2('asaelz')) //Hola @asaelz\n/**\n * Como podemos observar tenemos el mismo resultado que una funcion regular, pero mas facil de entender \n * una arrow function siempre es anonima (o sea que la funcion no tiene nombre) y es una function expression\n * en el caso del return como podemos ver lo tiene implicito, pero no pasaria nada si lo agregamos: \n */\nconst SaludarUsuario3 = (usuario) => { return 'Hola @' +usuario}\nconsole.log(SaludarUsuario3('asaelz')) //Hola @asaelz\n\n/**\n * RECURSIVIDAD --> SE DA CUANDO UNA FUNCION SE LLAMA ASI MISMA, \n * COMO UNA MANERA DE SIMULAR UN BUCLE, EJEMPLO: \n */\n\nfor (let index = 0; index < 3; index++) {\n    console.log('En ' +(index + 1))\n    \n}\n// ahora vamos a ver como simular este ciclo con recursividad \nfunction conteo(num) {\n    if (num==3) { return }\n    console.log('En '+ (num + 1))\n    conteo(num + 1)\n}\n// EN AMBOS CASOS OBTENEMOS EL MISMO RESULTADO \n\n/**\n * Ejemplos de funciones existentes en lenguaje \n */\n\nconsole.log('se utiliza para imprimir en consola');\nconsole.log(Math.floor(3.65)) // 3 --> redondea un numero\nconsole.log('       HOLA     '.trim()) //Hola --> remueve los espacios en blanco al inicio y final de un string\n\n/**\n * FUNCIONES DENTRO DE FUNCIONES\n */\nfunction suma1(a,b) {\n    function validacion(a,b) {\n        if (typeof(a)!= 'number' || typeof(b)!= 'number') {\n            return 'Debe insertar solo numeros'\n        } \n        else {\n            return true\n        }\n    }\n    return validacion(a,b)==true ? a + b : validacion(a,b)\n}\n\nconsole.log(suma1('a',1)) //Debe insertar solo numeros\n\n/**\n * VARIABLES LOCALES Y GLOBALES \n * Las variables globales son las que se definen fuera de cualquier funcion\n * por tanto podemos acceder a ellas dentro y fuera de las mismas, mientras las locales solo funcionan dentro\n */\n\nlet user = 'asaelz' // variable global\nfunction cambiarUsuario(NuevoUsuario) {\n    let OldUser = user //variable local\n    user = '@'+NuevoUsuario\n    return 'Su usuario @' +OldUser + ' fue cambiado a '+ user\n}\n\nconsole.log(cambiarUsuario('yanci'))\n\n/**\n *  * DIFICULTAD EXTRA (opcional):\n */\n\nfunction Prints(text1, text2) {\n    let contador = 0;\n    for (let num = 1; num <= 100; num++) {\n        if (num%3==0 && num%5!= 0){\n            console.log(text1)\n        }else if(num%5==0 && num%3!= 0)  {\n            console.log(text2)\n        } else if (num%3==0 && num%5==0) {\n            console.log(text1 + ' ' + text2)\n        } else contador +=1\n    }\n    return 'Se han impreso ' +contador +' números.'\n}\n\nconsole.log(Prints('Brais','Moure'))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/bernatcs.js",
    "content": "// -1-\n\nfunction funcion1(){\n    console.log('Esto es una función')\n}\n\nfuncion1()\n\nfunction funcion2(numero){\n    if (numero === 8) {\n        console.log('El numero es 8')\n    } else {\n        console.log('El numero no 8')\n    }\n}\n\nfuncion2(8)\n\nfunction funcion3(numero){\n    numero += 8;\n    return numero;\n}\n\nlet resultado3 = funcion3(2)\nconsole.log(resultado3)\n\n// -2-\n\nfunction funcionExt() {\n    console.log(\"Función externa\")\n    function funcionInt() {\n        console.log(\"Función interna\")\n    }\n\n    funcionInt()\n}\n\nfuncionExt()\n\n// -3-\n\nlet random = Math.round(Math.random()*100)\nconsole.log(random)\n\n// -4-\n\nvar variableGlobal = 'Esto es una variable Global'\n\nfunction funcionLocal(){\n    var variableLocal = 'Esto es una variable Local'\n\n    console.log(variableGlobal)\n    console.log(variableLocal)\n}\n\nfuncionLocal()\n\nconsole.log(variableGlobal)\n//console.log(variableLocal) --> Is not defined\n\n// -5- EXTRA\n\nfunction funcionExtra(string1, string2){\n    for (let funcionExtraFor = 1; funcionExtraFor <= 100; funcionExtraFor++) {\n\n        let funcionExtraForPrint\n\n        if (funcionExtraFor % 3 === 0 && funcionExtraFor % 5 === 0) {\n            funcionExtraForPrint = string1 + string2\n        } else if (funcionExtraFor % 5 === 0) {\n            funcionExtraForPrint = string2\n        } else if (funcionExtraFor % 3 === 0) {\n            funcionExtraForPrint = string1\n        } else {\n            funcionExtraForPrint = funcionExtraFor\n        }\n\n        console.log(funcionExtraForPrint)\n    }\n\n}\n\nfuncionExtra('pin', 'pon')"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/caterinarodriguezdev.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\nconsole.log('--------------------FUNCIONES----------------------------');\n\nconst funcionSinParams = () => {\n    console.log('función sin params');\n}\n\nconst funcionConUnParam = (x) => {\n    console.log(`función con 1 param - la raíz cuadrada de ${x} es: ${Math.sqrt(x)}`);\n}\n\nconst funcionConVariosParams = (x, y) => {\n    console.log(`función con varios params - el número mayor entre ${x} y ${y} es ${Math.max(x, y)}`);\n}\n\nconst funcionConRetorno = (str) => {\n    return str.toUpperCase();\n}\n\nconst funcionConUnaFuncion = () => {\n    const funcionDeDentro = (arr) => {\n        return arr.map(el => el * 2);\n    }\n    console.log('la función de dentro multiplica el array por 2', funcionDeDentro([2, 4, 8]));\n}\n\nfuncionSinParams();\nfuncionConUnParam(64);\nfuncionConVariosParams(5, 10);\nconsole.log('función con retorno - el texto en mayúsculas será:', funcionConRetorno('boom'));\nfuncionConUnaFuncion(); \n\nconsole.log('--------------------LOCAL Y GLOBAL----------------------------');\n\nlet global = 'global';\n\nconst scope = () => {\n    let local = 'local';\n\n    console.log('ejecutando dentro de una función ->', global);\n\n    global = 'He sido cambiada dentro de scope';\n}\n\ntry {\n    console.log(local);\n} catch {\n    console.error('Error: No puedes acceder a una variable local fuera de su scope');\n}\n\nscope();\n\nconsole.log('global ha cambiado? ', global);\n\n\n\nconsole.log('--------------------DIFICULTAD EXTRA----------------------------');\n\nconst dificultadExtra = (str1, str2) => {\n    let numberPrinted = 0;\n    for (let i = 1; i <= 100; i++) {\n        if (i % 3 === 0 && i % 5 === 0) {\n            console.log(str1.toString() + str2.toString());\n        } else if (i % 3 === 0) {\n            console.log(str1);\n        } else if (i % 5 === 0) {\n            console.log(str2);\n        } else {\n            numberPrinted++;\n            console.log(i);\n        }\n    }\n\n    return numberPrinted;\n}\n\nconsole.log(`El número se ha imprimido ${dificultadExtra('Fizz', 'Buzz')} veces`);\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/ceciliarava1.js",
    "content": "// 02-Javascript\n\n/*\n * EJERCICIO:\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n// Function\nfunction santaClaus(name) {\n    let localVar = 'Kittens'\n    console.log('Ho ho ho! Merry Christmas!')\n\n    function greetings(name) {\n        console.log(`Hello ${name}`)\n    }\n    greetings(name)\n}\nsantaClaus('Dorothy')\n// console.log(localVar) \n\n\n// Exercise\n\nlet count = 0\nfunction printNumbers(string1, string2, i) {\n    if (i % 3 == 0 && i % 5 == 0) {\n        console.log(string1 + string2)\n        count ++\n    } else if (i % 3 == 0) {\n        console.log(string1)\n        count ++\n    } else if (i % 5 == 0) {\n        console.log(string2)\n        count ++\n    } else {\n        console.log(i)\n    }\n}\n\nfor (let i = 1; i <= 100; i++) {\n    printNumbers('First', 'Second', i)\n}\n\nconsole.log(`Amount of strings: ${count}`)\n\n\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/cesar-ch.js",
    "content": "// Función sin parámetros ni retorno\nfunction saludar() {\n    console.log(\"¡Hola, mundo!\");\n}\n\nsaludar();\n\n// Función con un parámetro y retorno\nfunction cuadrado(numero) {\n    return numero * numero;\n}\n\nlet resultadoCuadrado = cuadrado(5);\nconsole.log(\"Cuadrado de 5:\", resultadoCuadrado);\n\n// Función con varios parámetros y retorno\nfunction suma(a, b) {\n    return a + b;\n}\n\nlet x = 3\nlet y = 7\nlet resultadoSuma = suma(x, y);\nconsole.log(`Suma de ${x} y ${y}:`, resultadoSuma);\n\n// Función dentro de una función\nfunction operacionMatematica(x, y) {\n    function cuadruple(num) {\n        return num * 4;\n    }\n\n    let resultado1 = cuadruple(x);\n    let resultado2 = cuadruple(y);\n\n    return resultado1 + resultado2;\n}\n\nlet resultadoOperacion = operacionMatematica(2, 3);\nconsole.log(\"Resultado de operación compleja:\", resultadoOperacion);\n\n// Variable local y global\nlet variableGlobal = 10;\n\nfunction funcionConVariables() {\n    let variableLocal = 5;\n    console.log(\"Variable local dentro de la función:\", variableLocal);\n    console.log(\"Variable global dentro de la función:\", variableGlobal);\n}\n\nfuncionConVariables();\nconsole.log(\"Variable global fuera de la función:\", variableGlobal);\n\n// DIFICULTAD EXTRA\nfunction imprimirNumerosConTexto(texto1, texto2) {\n    let contador = 0;\n\n    for (let i = 1; i <= 100; i++) {\n        if (i % 3 === 0 && i % 5 === 0) {\n            console.log(texto1 + texto2);\n        } else if (i % 3 === 0) {\n            console.log(texto1);\n        } else if (i % 5 === 0) {\n            console.log(texto2);\n        } else {\n            console.log(i);\n            contador++;\n        }\n\n    }\n\n    return contador;\n}\n\nlet vecesImpreso = imprimirNumerosConTexto(\"Fizz\", \"Buzz\");\nconsole.log(\"Número de veces impreso:\", vecesImpreso);\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/christian-jfr.js",
    "content": "// #02 FUNCIONES Y ALCANCE\n\n/**\n * Crea ejemplos de funciones básicas que representen las diferentes\n * posibilidades del lenguaje:\n */\n\n//Declaración y tipos de funciones en JavaScript\n// 01. Función sin parametros ni retorno\nfunction saludoSimple() {\n  console.log(\"Hola JavaScript.\");\n}\nsaludoSimple(); // 'Hola JavaScript.'\n\n// 02. Función con un parametro y retorno\nfunction saludoRetorno(string) {\n  console.log(`Hola ${string}.`);\n  return string;\n}\nsaludoRetorno(\"JavaScript\"); // Hola JavaScript.\n\n// 03. Función con 2 o mas parámetros\nfunction multiplicar(num1, num2) {\n  return console.log(num1 * num2);\n}\nmultiplicar(10, 7); // 70\n\n// 04. Función expresión\nconst multiplicar2 = function mult(num1, num2) {\n  return console.log(num1 * num2);\n};\nmultiplicar2(10, 6); // 60\n\n// 05. Función expresión (Anonima)\nconst multAnonima = function (num1, num2) {\n  return console.log(num1 * num2);\n};\nmultAnonima(10, 5); // 50\n\n// 06. Función Flecha o Arrow Function\nlet myArray = [-5, -10, 80, 0, 7, -155];\n\nlet ABSOLUTO = (arr) => {\n  let arrAbsoluto = [];\n  for (let i = 0; i < arr.length; i++) {\n    let valAbsoluto = Math.abs(arr[i]);\n    console.log(valAbsoluto);\n    arrAbsoluto[i] = valAbsoluto;\n  }\n  console.log(arrAbsoluto);\n  return arrAbsoluto;\n};\n\nABSOLUTO(myArray); // [5, 10, 80, 0, 7, 155]\n\n// 07. Variables LOCALES y GLOBALES\nlet globalVar = \"Esta es una variable GLOBAL\";\n\nfunction ejemplo() {\n  let localVar =\n    \"Esta es una variable LOCAL de la función.\\nUna variable local solo puede ser accedida desde\\ndentro de la función en la que se define.\";\n  console.log(globalVar);\n  console.log(localVar);\n}\n\nejemplo();\n/*\n\"Esta es una variable GLOBAL\"\n\"Esta es una variable LOCAL de la función.\nUna variable local solo puede ser accedida desde\ndentro de la función en la que se define.\"; \n*/\n\nconsole.log(globalVar); // \"Esta es una variable GLOBAL\"\n\n// Acceso desde fuera del bloque de la función: error de referencia\n// console.log(localVar); // Uncaught ReferenceError: localVar is not defined\n\n// 08. Crear una funcion dentro de otra funcion\nlet numeros = [1, 3, 5];\n\nfunction multiplicadora(arr, multi) {\n  let multiplicados = [];\n  let recorrer = () => {\n    for (let numero of arr) {\n      let resultado = numero * multi;\n      multiplicados.push(resultado);\n    }\n    return multiplicados;\n  };\n  return recorrer();\n}\n\nconsole.log(multiplicadora(numeros, 5)); // [5, 15, 25]\n\n/** DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n */\n\nfunction extra(string1, string2) {\n  let numberHasBeenPrinted = 0;\n  for (let i = 1; i <= 100; i++) {\n    if (i % 3 === 0 && i % 5 === 0) {\n      console.log(string1 + string2);\n    } else if (i % 3 === 0) {\n      console.log(string1);\n    } else if (i % 5 === 0) {\n      console.log(string2);\n    } else {\n      numberHasBeenPrinted++;\n      console.log(i);\n    }\n  }\n  console.log(`The number has been printed ${numberHasBeenPrinted} times.`);\n  return numberHasBeenPrinted;\n}\n\nextra(\"Road\", \"map\");\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/cmejiajulian.js",
    "content": "//*#02 FUNCIONES Y ALCANCE\n\n/*\nEJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n */\n\n// Funciones definidas por el usuario \n\nfunction greet (){\n    console.log('Hola JavaScript');\n}\n\ngreet();\n\n// Con Retorno \n\nfunction returnGreet(){\n    return 'Hola JavaScript';\n}\n\nconsole.log(returnGreet())\n\n//Con Argumento \n\nfunction argGreet(greet, name){\n    console.log( greet+' '+ name );\n}\n\nargGreet('Hi','Julius Batista para ti ');\n\n//Con argumentos predeterminado\n\nfunction defaultArgGreet(greet, name = 'Julini'){\n    console.log( greet+' '+ name );\n}\n\ndefaultArgGreet('Hi');\n\n//Con Argumento de posición \n\n//en este caso en JavaScript es necesario ponerlo como objetos para que independientemente del orden pueda funcionar.\n\nfunction argGreetPosition({saludo, nombre}){\n    console.log( saludo+' '+ nombre );\n}\n\nargGreetPosition({nombre:'Julius Batista para ti', saludo :'hola'});\n\n//Con Argumentos y retorno \n\nfunction returnArgsGreet (greet,name){\n    return [greet,name];\n}\n\nconsole.log(returnArgsGreet('hola','julian'))\n\n//Con retorno de varios Valores\n\nfunction multipleReturnGreet() {\n    return ['Hola', 'Mundo'];\n}\n\nconst [saludo, nombre] = multipleReturnGreet();\n\nconsole.log(multipleReturnGreet()); // Mostrar la referencia de la función\n\n\n // Con un numero variable de argumentos \n\n function variableArgGreet(...nombres){\n  for (let nombre of nombres){\n    console.log('hola',nombre)\n  }\n }\n\n variableArgGreet('julian','Phelps','Ilia')\n\n // con un numero variable de argumentos con palabra clave \n\n\n function variableKeyArgGreet(nombres){\n    for(let [param,key] of Object.entries (nombres))\n        {console.log(`${param}:${key}`)};\n }\n\n /*\n*   En este ejemplo:\n\n*   La función variableArgGreet acepta un objeto nombres.\n*   Object.entries(nombres) convierte el objeto en un array de pares clave-valor.\n*   Usamos un bucle for...of para iterar sobre los pares clave-valor y colocar los parametros a cada uno.\n  */\n\n variableKeyArgGreet({nombre:'Julian', edad:'205', profesion:'programador'});\n\n\n// Forma de expresar las funciones \n\n//Funcion expresada \n\nlet sum = function (a,b){\n    return (a+b);\n}\n\nconsole.log(sum(3,5));\n\n//Funcion de flecha \n\nlet rest = (x,y) => {\n    return (x-y)\n}\nconsole.log(rest(3,5));\n\n//* tambien se podria expresar asi \n\nlet div = (x,y) => x/y \n\nconsole.log(div(4,2));\n\n/*\n* Comprueba si puedes crear funciones dentro de funciones.\n */\n\nlet funcionExterna = ( a,b ) =>{\n    \n    let funcionInterna = (x) => x*x;\n\n         return  funcionInterna(a) + funcionInterna(b);\n\n}\nconsole.log(funcionExterna(2,8));\n\n\n /*en este caso la funcion interna hace el siguiente trabajo\n\n  1) al dar un valor de 2 a (a) y de 8 a (b) y al decir que la funcion interna es x*x\n  entonces diriamos que (2*2) = 4  y (8*8) = 64 \n\n  2) como estos valores se suman diriamos que 4 + 64 es igual a 68 \n\n  3) por consiguiente al imprimirlo y llamar a la funcion externa el valor o resultado final es 68 \n\n */\n\n\n  /*\n  * Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n  */\n\nconsole.log(Math.max(1,3,2));  // esta funcion elige el numero mayor de los expuestos en una lista\n\nconsole.log(Math.random(10,12)); // la funcion Math.random elige un numero aleatorio entre los valores expuestos;\n\n\n//Funcion del objeto Date\n\nlet momento = new Date ();\nconsole.log(momento);\n\n// Funciones del Objeto String\n\nconsole.log( 'texto'.length); \n\n /* \n * Pon a prueba el concepto de variable LOCAL y GLOBAL.\n */\n\n //Variables locales y Globales \n\n //Variables Globales\n //se puede acceder a ella asi este en fuera de la funcion\n\n\n let globalVar = ('soy una variable global');\n\n let seeGlobal =()=>{\n    console.log(globalVar);\n }\n\n seeGlobal();\n console.log(globalVar);\n\n //Variables locales\n//Solo se puede acceder a ellar cuando se declaran dentro de la funcion si estan por fuera no \n\n let localVar = (mult)=> {\n    let mult1 = mult*2\n    console.log(mult1)\n }\n\n localVar(2);\n//  console.log(mult1);\n\n  /*\n  DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n  */\n\n  let funTwo = (num1, num2) => {\n    let n1 = parseFloat(num1);\n    let n2 = parseFloat(num2);\n    let contador = 0\n    for (let i = 1; i <= 100; i++) {\n        if (i % 3 == 0 && i % 5 == 0) {\n            console.log(num1+' '+ num2);\n        } else if (i % 3 == 0) {\n            console.log(num1);\n        } else if (i % 5 == 0) {\n            console.log(num2);\n        } else {\n            console.log(i);\n            contador++\n        }\n    }\n    return contador\n}\nconsole.log(funTwo('num1','num2'));"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/cristophher087.js",
    "content": "/*\n¿Qué es una función?\n\n-Es un bloque de codigo que se puede definir una vez y ejecutar en multiples ocaciones.\n*/\n\n//sintaxis basica \n\nfunction nombreFuncion(parámetro1, parámetro2) {\n    // Código a ejecutar\n    return resultado; // Opcional\n}\n/*\nFunción Declarativa\n\nSe define con la palabra reservada function. Estas funciones se elevan al principio del contexto gracias al hoisting, por lo que pueden ser llamadas antes de ser declaradas.\n*/\nfunction suma(a, b) {\n    return a + b;\n}\n\nconsole.log(suma(2, 3)); //Salida: 5\n\n/*\nFunción Anónima\n\nNo tiene un nombre asignado y se suele usar como expresión o argumento. Por ejemplo:\n*/\nconst resta = function (a, b) {\n    return a - b;\n};\n\nconsole.log(resta(5, 2)); // Salida: 3\n\n/*\nFunciones Flecha (Arrow Functions)\n\nIntroducidas en ES6, tienen una sintaxis más compacta y no tienen su propio this. Son útiles para funciones cortas.\n*/\nconst multiplicar = (a, b) => a * b;\nconsole.log(multiplicar(3, 4)); // Salida: 12\n\n//Arrow Functions sin parametros\nconst saludar = () => console.log(\"¡Hola!\");\nsaludar(); // Salida: ¡Hola!\n\n//Arrow Functions con un solo parámetro (paréntesis opcionales)\nconst cuadrado = x => x * x;\nconsole.log(cuadrado(5)); // Salida: 25\n/**\n * Parametros y argumentos\n * Parametros:Variables que se definen en la declaración de la función.\n * Argumentos: Valores que se pasan al invocar la función.\n */\n\n//Parámetros por defecto\n/**\n * Si no se pasa un valor a un parámetro, podemos definir un valor por defecto.\n */\nfunction saludar(nombre = \"Visitante\") {\n    console.log(`Hola, ${nombre}`);\n}\nsaludar(); // Salida: Hola, Visitante\nsaludar(\"Ana\"); // Salida: Hola, Ana\n\n/**\n * Parámetros Rest (...rest)\n * Permiten capturar un número indefinido de argumentos en un array.\n */\nfunction sumarTodos(...numeros) {\n    return numeros.reduce((total, num) => total + num, 0);\n}\nconsole.log(sumarTodos(1, 2, 3, 4)); // Salida: 10\n/**\n * En este arreglo el argumento \"...numeros\"\n * nos dice que se capturan ilimitada cantidad \n * de captura de parametros se puede ver que0\n * se ejecuta la funcion correctamente sumando \n * todos los números\n */\n\n/**\n * Retorno de valores con return\n * El uso de return permite devolver un valor \n * al finalizar la ejecución de la función. \n * Si no se usa, la función devuelve undefined.\n */\nfunction doble(x) {\n    return x * 2;\n}\nconsole.log(doble(4)); // Salida: 8\n\n/**\n * Funciones de alto orden\n * Son funciones que reciben como argumento \n * otra función o devuelven una función.\n */\nfunction operar(a, b, operacion) {\n    return operacion(a, b);\n}\nconst suma = (x, y) => x + y;\nconsole.log(operar(3, 4, suma)); // Salida: 7\n\n/**\n * Scope y this\n * El scope (ámbito) determina la accesibilidad\n *  de variables en una función. Hay dos tipos\n *  principales de scope:\n * \n    * Global: Variables accesibles desde cualquier parte.\n    * Local: Variables definidas dentro de una función.\n* Uso de this\n    * En las funciones tradicionales, this hace \n    * referencia al objeto que la llama.\n    * En arrow functions, this no se enlaza al \n    * contexto de la función, sino al contexto \n    * superior donde se definió.\n */\nconst objeto = {\n    nombre: \"VisiónLux\",\n    mostrarNombre() {\n        console.log(this.nombre);\n    },\n};\nobjeto.mostrarNombre(); // Salida: VisiónLux\n\n//En cambio:\nconst objeto2 = {\n    nombre: \"Óptica Henrris\",\n    mostrarNombre: () => {\n        console.log(this.nombre); // this se refiere al contexto global, no al objeto\n    },\n};\nobjeto2.mostrarNombre(); // Salida: undefined\n\n/**\n * Funciones Asíncronas (async/await\n * Permiten manejar operaciones asincrónicas (promesas) de manera más clara.\n */\nasync function obtenerDatos() {\n    const respuesta = await fetch(\"https://api.ejemplo.com\");\n    const datos = await respuesta.json();\n    console.log(datos);\n}\nobtenerDatos();\n\n//Uso de Promesas con Funciones\nfunction esperar(ms) {\n    return new Promise(resolve => setTimeout(resolve, ms));\n}\nesperar(2000).then(() => console.log(\"Han pasado 2 segundos\"));\n\n/**\n * Closures (Clausuras)\n * Un closure ocurre cuando una función interna recuerda las variables del entorno en el que fue creada, incluso después de que dicho entorno haya terminado.\n */\nfunction crearContador() {\n    let contador = 0;\n    return function incrementar() {\n        contador++;\n        console.log(contador);\n    };\n}\nconst contador1 = crearContador();\ncontador1(); // Salida: 1\ncontador1(); // Salida: 2\n/**\n * En este casi, par aeste ejemplo se define \"contador = 0;\" dentro de la función pero este no toma el valor 0 en el segundo llamado, toma el valor anterior\n */\n\n/**\n * IIFE (Immediately Invoked Function Expression)\n\nSon funciones que se ejecutan inmediatamente después de ser declaradas. Útiles para evitar la contaminación del scope global.\n */\n(function () {\n    console.log(\"Función ejecutada inmediatamente\");\n})();\n\n/**\n * Funciones Recursivas\n\nUna función es recursiva cuando se llama a sí misma. Se usa comúnmente para resolver problemas complejos que pueden descomponerse en subproblemas más pequeños.\n */\nfunction factorial(n) {\n    if (n === 0) return 1;\n    return n * factorial(n - 1);\n}\nconsole.log(factorial(5)); // Salida: 120\n\n/**\n * DIFICULTAD EXTRA\n */\n\nvar fizz = \"\";\nvar buzz = \"\";\nfunction convertidorNumeros(fizz, buzz) {\n\n    for (var i = 0; i >= 100; i++) {\n        if (i % 3 == 0 && i % 5 == 0) {\n            console.log(`${fizz}${buzz}`);\n        }\n        if (i % 3 == 0) {\n            console.log(`${fizz}`);\n        }\n        if (i % 5 == 0) {\n            console.log(`${buzz}`);\n        }\n        else {\n            console.log(i);\n        }\n    }\n}\n\nconvertidorNumeros(\"Fizz\", \"Buzz\");\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/cubandeveloper89.js",
    "content": "//   ***   FUNCIONES    ***\n// funciones sin parámetros ni retorno\nfunction myFunct() {\n    console.log(\"myFunt es una función que no requiere parámetros\");\n}\nmyFunct(); //invoco la funcion\n// funciones con parámetros pero sin retorno\nfunction my2Funct(name) {\n    console.log(\"Hola, \" + name + \", my2Funct si que requiere un parámetro, tu nombre\");\n}\nmy2Funct(\"John\");\n// Funciones flecha\nvar my3Funct = function () {\n    console.log(\"my3Funct es una funcion flecha, simplemente otrra manera de denominar una funcion\");\n};\nmy3Funct();\n// Dos o mas parámetros en una funcion, el tercero es opcinal\nvar my4Funct = function (a, b, c) {\n    var result = 0;\n    if (c) {\n        result = a + b + c;\n    }\n    else {\n        result = a + b;\n    }\n    console.log(\"my4Funct toma 2 parametros y los suma: \" + result);\n};\nmy4Funct(10, 5, 7);\n// Función con return\nvar my5Funct = function () {\n    return \"my5Funct es una función con RETURN\";\n};\nconsole.log(my5Funct());\n// Función dentro de funciones\nvar my6Funct = function () {\n    function innerFunct() {\n        console.log(\"Esta función se ejecuta dentro de my6Funct\");\n    }\n    innerFunct();\n};\nmy6Funct();\n// Funciones propias del lenguaje\nconsole.log(\"1- El mismo console.log() es una funcion del lenguaje\");\nvar words = \"2- We all can work together and make this world a better place\";\nconsole.log(words.toUpperCase());\n// Variable global y local\nvar global = \"global\";\nvar my7Funct = function () {\n    var local = \"local\";\n    return \"la variable \".concat(global, \" esta fuera del scope de la funcion mientras que \").concat(local, \" solo existe aqui dentro\");\n};\nconsole.log(my7Funct());\n//  *** Ejercicio EXTRA ***\nconsole.log(\"     *** Ejercicio Extra ***\");\nvar extraFunct = function (param1, param2) {\n    var count = 0;\n    for (var index = 1; index <= 100; index++) {\n        if (index % 3 == 0 && index % 5 == 0) {\n            console.log(param1 + \" y \" + param2);\n            count++;\n            continue;\n        }\n        else if (index % 3 == 0) {\n            console.log(param1);\n            count++;\n            continue;\n        }\n        else if (index % 5 == 0) {\n            console.log(param2);\n            count++;\n            continue;\n        }\n        console.log(index);\n    }\n    console.log(\"Se cambio por letras \" + count + \" veces\");\n    return count;\n};\nextraFunct(\"hola\", \"adios\");\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/d4-n1.js",
    "content": "// Función sin argumento\nfunction helloWorld() {\n  console.log(\"Hello world!\")\n}\n\n// Función con argumento\nfunction helloWord(word) {\n  console.log(`Hello ${word}!`)\n}\n\n// Función con argumentos\nfunction sumAll(...args) {\n  let sum = 0\n  for (let element of args) {\n    sum += element\n  }\n  console.log(sum)\n}\n\n// Función recursiva\nfunction power(base, exponent) {\n  if (exponent == 0) {\n    return 1;\n  } else {\n    return base * power(base, exponent - 1);\n  }\n}\n\n// Arrow functions\nconst arrow = () => {\n  console.log(\"Hello arrow function!\")\n}\n\nhelloWorld()\nhelloWord(\"there\")\nsumAll(2, 6)\npower(2, 3)\narrow()\n\n// Dificultad extra\n\nfunction exercise(threeMultiplier, fiveMultiplier) {\n  let counter = 0\n  \n  for (i = 1; i <= 100; i++) {\n    let output = \"\"\n    if(i % 3 == 0) {output += threeMultiplier}\n    if(i % 5 == 0) {output += fiveMultiplier}\n    if (!output) {counter++}\n    console.log(output || i)\n  }\n  \n  return counter\n}\n\nexercise(\"three\", \"five\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/daniback95.js",
    "content": "/*\nfunciones básicas en javascript \n*/\n\n// Simple, funciones declaradas\nfunction showName(){\n  console.log(\"daniback\")\n}\nshowName()\n\n// Retorno de valor\nfunction add(){\n  return 3 + 9\n}\nlet result = add()\nconsole.log(result)\n\n// Parámetros y argumentos\nfunction argGretting(name){\n  console.log(`Hola, ${name}!`)\n}\nargGretting(\"Dani\")\n\nfunction argsGretting(text, name) {\n  console.log(`${text}, ${name}!`)\n}\nargsGretting(\"Saludos\", \"Dani\")\n\n// Parámetro con valor predeterminado\nfunction argSinDefaultGretting (lenguage){\n  console.log(`Hola mundo desde ${lenguage}`)\n}\nargSinDefaultGretting()\nfunction argDefaultGretting(lenguage = \"JavaScript\") {\n  console.log(`Hola mundo desde ${lenguage}`)\n}\nargDefaultGretting()\n\n// Con parámetros y retorno de valores\nfunction grettCity(message, city){\n  return `${message} ${city}`\n}\nlet welcome = grettCity(\"Saludos desde\", \"Colombia\")\nconsole.log(welcome)\n\n// varibles globales y locales\nlet user = \"Juan\" // Externa\nfunction showUser() {\n  let msj = `Que tal ${user}`\n  console.log(msj)\n}\nshowUser()\n\nlet user2 = \"Sebastian\"\nfunction showUser2() {\n  let user2 = \"Mari\" // local\n  console.log(\"Mostrando user2 local =\", user2)\n}\nshowUser2()\nconsole.log(\"Mostranso user2 global = \", user2)\n\nfunction showUser3() {\n  let myUser = \"Dani\"\n  console.log(myUser, 'Esta dentro la función')\n}\nshowUser3()\n// console.log(myUser) no esta declarada como gloabal, not defined\n\n// Funciones de expresion\nconst operation = function (num1, num2, oper) {\n  switch (oper) {\n    case \"+\":\n      return num1 + num2\n    case \"-\":\n      return num1 - num2\n    case \"*\":\n      return num1 * num2\n    case \"/\":\n      return num1 / num2\n    default:\n      return 'Operador erróneo'\n  }\n} \n\nlet resultOper = operation(3, 3, \"*\")\nconsole.log(\"El resultado es\", resultOper)\n\n// Funciones flecha\nlet arrowFunction = (a, b) => a + b // return implícito\nconsole.log(arrowFunction(3, 9))\n\nlet arrowFunctionMulti = (a, b, c) => {\n  let total = a + b\n  let iva = (total * c) / 100\n  return iva // return explícito\n}\nlet ivaCalc = arrowFunctionMulti(300, 270, 19)\nconsole.log(\"IVA:\", ivaCalc)\n\n// funcion dentro de otra funcion\nfunction createCounter() {\n  let counter = 0;\n  return function () {\n    counter++\n    return counter\n  }\n}\nlet counterOne = createCounter()\nconsole.log(counterOne())\nconsole.log(counterOne())\n\n// funciones propias del lenguaje\nconsole.log(\"Console.log() es una función propia del lenguaje\")\nlet getRandom = (min, max) => {\n  return Math.floor(Math.random() * (max - min + 1) + min)\n}\nlet numRam = getRandom(1, 10)\nconsole.log(numRam)\n\nlet numLetters = (word) => {\n  return word.length\n}\nfunction showNumLetters (w) {\n  let num = numLetters(w)\n  console.log(`La palabra ${w} tiene ${num} letras`)\n}\nshowNumLetters(\"dani\")\n\n// DIFICULTAD EXTRA\nfunction printNumbers (text1, text2) {\n  let counter = 0\n  for (let num = 1; num <= 100; num++){\n    if (num % 3 === 0 && num % 5 === 0) {\n      console.log(text1 + text2)\n    } else if(num % 3 === 0) {\n      console.log(text1)\n    } else if (num % 5 === 0) {\n      console.log(text2)\n    } else {\n      console.log(num)\n      counter++\n    }\n  }\n  return counter\n}\nconsole.log(printNumbers(\"fizz\", \"buzz\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/dariorfm.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n\n// FUNCIONES Una función es un bloque de código que realiza una tarea específica cuando se la llama.\n\n// Para dleclarar una función ej JavaScript utilizamos la palabra reservada function, ejemplo:\n\nfunction saludo() {\n    console.log('Hola mundo');\n};\n\n// llamamos a la función\nsaludo()  // imprime en consola Hola mundo.\n\n// Las funciones pueden contar con uno o más parametros y retornar un valor en funcón del código que ejecute.\n\n\nfunction compara(parametro) {\n    \n    if(parametro >= 10) return \"Mayor que 10;\"\n}\n\nlet retorna = compara(17);\n\nconsole.log(retorna);\n\n\nfunction comparaDosNumeros (par1, par2) {\n\n    if (par2 >= par1) return par2;\n\n    return par1;\n}\n\n\nconsole.log(comparaDosNumeros(5, 9));\n\n// Función anidada, se dice de una función dentro de otro función:\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/darkhouselab08.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n * posibilidades del lenguaje:\n * Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n */\n\n// -----------------------------------------------------------------\n// RESPUESTAS\n// -----------------------------------------------------------------\n\n// 1. FUNCIONES BÁSICAS\n\n// A. Sin parámetros ni retorno \n// ejecuta una acción.\nfunction saludar() {\n    console.log(\"Hola! Soy una función básica.\");\n}\nsaludar(); // Llamada a la función\n\n// B. Con parámetros\n// Recibe datos (\"input\") para trabajar con ellos.\nfunction saludarPersona(nombre, apellido) {\n    console.log(\"Hola, \" + nombre + \" \" + apellido + \"!\");\n}\nsaludarPersona(\"Jorge\", \"Franco\");\n\n// C. Con retorno (Return)\n// Devuelve un resultado (\"output\") que podemos guardar en una variable.\nfunction sumar(a, b) {\n    return a + b;\n}\nlet resultadoSuma = sumar(5, 10);\nconsole.log(\"El resultado de la suma es: \" + resultadoSuma);\n\n\n// 2. FUNCIONES DENTRO DE FUNCIONES (Nested Functions)\n\nfunction funcionExterna() {\n    console.log(\"Iniciando función externa...\");\n    \n    function funcionInterna() {\n        console.log(\" -> Ejecutando función interna.\");\n    }\n    \n    funcionInterna(); // La externa llama a la interna\n}\nfuncionExterna();\n\n\n// 3. FUNCIONES YA CREADAS EN EL LENGUAJE (Built-in)\n// JavaScript.\n\n// Ejemplo: Math (Matemáticas)\nlet numeroAleatorio = Math.random(); // Genera un número entre 0 y 1\nconsole.log(\"Número aleatorio generado: \" + numeroAleatorio);\n\n// Ejemplo: String (Texto)\nlet texto = \"hola mundo\";\nconsole.log(\"Texto en mayúsculas: \" + texto.toUpperCase());\n\n\n// 4. VARIABLE LOCAL Y GLOBAL (El Alcance/Scope)\n\n// Variable GLOBAL: Accesible desde cualquier parte del código.\nlet variableGlobal = \"Soy GLOBAL (accesible por todos)\";\n\nfunction pruebaDeScope() {\n    // Variable LOCAL: Solo existe DENTRO de esta función.\n    let variableLocal = \"Soy LOCAL (solo existo aquí)\";\n    \n    console.log(\"Dentro de la función:\");\n    console.log(\"- \" + variableGlobal); // Funciona\n    console.log(\"- \" + variableLocal);  // Funciona\n}\n\npruebaDeScope();\n\nconsole.log(\"Fuera de la función:\");\nconsole.log(\"- \" + variableGlobal); // Funciona\n\n// INTENTO DE ERROR (Para demostración):\ntry {\n    console.log(\"- \" + variableLocal); // ¡Esto fallará!\n} catch (error) {\n    console.log(\"ERROR: No puedo acceder a 'variableLocal' desde fuera. \" + error.message);\n}\n\n// 5. BONUS: Funciones Flecha (Arrow Functions)\n// Una forma moderna.\nconst multiplicar = (x, y) => {\n    return x * y;\n};\nconsole.log(\"Multiplicación con Arrow Function: \" + multiplicar(2, 3));"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/davidb313.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n//funcion que no recibe parametros\nconst funcionSinParametros = () => {\n  for (let i = 0; i < 7; i++) {\n    console.log(i);\n  }\n};\nfuncionSinParametros();\n\n//funcion que recibe parametros\nconst funcionSumarDosNumeros = (n1, n2) => {\n  return n1 + n2;\n};\nconsole.log(funcionSumarDosNumeros(4, 7));\n\nconst ejercicio = (texto1, texto2) => {\n  for (let i = 0; i <= 100; i++) {\n    if (i % 3 === 0 && i % 5 === 0) {\n      console.log(i, texto1, texto2);\n    } else if (i % 3 === 0) {\n      console.log(i, texto1);\n    } else if (i % 5 === 0) {\n      console.log(i, texto2);\n    } else {\n      console.log(i);\n    }\n  }\n};\nejercicio(\"Multiplo de 3\", \"multiplo de 5\");\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/dev-marco-dev.js",
    "content": "//#02 FUNCIONES Y ALCANCE\n/*EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...*/\n\nfunction greet() {\n  console.log(\"hi\");\n}\n\nfunction sum(a, b, c) {\n  return a + b + c;\n}\n\n// Comprueba si puedes crear funciones dentro de funciones.\n\nfunction outerFunction() {\n  function innerFunction() {\n    console.log(\"I am inside of the innerFunction\");\n  }\n  innerFunction();\n}\n\n//Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\nconsole.log(\"hi\");\n\n//- Pon a prueba el concepto de variable LOCAL y GLOBAL.\n\nlet greet1 = \"HI\";\nconsole.log(greet1);\n\nfunction greet1() {\n  let greet2 = \"HI\";\n}\n\n//DIFICULTAD EXTRA (opcional):\n/*Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\nfunction test(fizz, buzz) {\n  let contador = 0;\n  for (let i = 1; i <= 100; i++) {\n    if (i % 3 === 0 && i % 5 === 0) {\n      console.log(fizz + buzz);\n    } else if (i % 3 === 0) {\n      console.log(fizz);\n    } else if (i % 5 === 0) {\n      console.log(buzz);\n    } else {\n      console.log(i);\n      contador++;\n    }\n  }\n  return contador;\n}\nconsole.log(test(\"fizz\", \"buzz\"));\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/diegoguaman.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n//Funciones sin parametros ni retorno\nfunction sinParametros() {\n  console.log(\"funcion sin parametros\");\n}\nsinParametros();\n\n//Funcion con paramaetro sin retorno\nfunction conParametros(nombre, edad) {\n  console.log(`tu Nombre es: ${nombre} y tu edad es: ${edad} años`);\n}\nconParametros(\"Diego\", 31);\n\n//Funcion con retorno\nfunction conRetorno(a, b) {\n  return a + b;\n}\n\nfunction imprimir(mensaje, algo) {\n  console.log(`${mensaje} ${algo}`);\n}\n\nimprimir(\"El suma es: \", conRetorno(1, 2));\n\n//Funciones dentro de funciones\nfunction externa() {\n  console.log(\"funcion externa ejecutada\");\n  function interna() {\n    console.log(\"Función interna ejecutada\");\n  }\n  interna();\n}\nexterna();\n\n//Uso de funciones nativas del lenguaje\n//Variables globales y locales\nlet word = \"Global, fuera de la función \";\nfunction globalLocal() {\n  let wordLocal = \"Local solo vivi dentro de la función\";\n  return word + wordLocal;\n}\nimprimir(\"Tu funcion es: \", globalLocal());\ntry {\n  console.log(wordLocal);\n} catch (error) {\n  console.log(\n    \"No se puede imprimir una variable que ha sido declarada dentro de una función, fuera de la misma\"\n  );\n}\n\n//Extra\n\nfunction numeros(cadena, cadena1) {\n  let num = 0;\n  for (let index = 0; index <= 100; index++) {\n    if (index % 3 == 0 && index % 5 == 0) {\n      console.log(cadena + \" \" + cadena1);\n    } else if (index % 3 == 0) {\n      console.log(cadena);\n    } else if (index % 5 == 0) {\n      console.log(cadena1);\n      \n    } else {\n      console.log(index);\n      num++;\n    }\n\n  }\n  return num;\n}\n\nlet resutado = numeros(\"Hola\", \"Caracola\");\nimprimir(\"El número de veces que se ha impreso el número: \", resutado);\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/dieswae.js",
    "content": "/* Funcion sin parametros ni retorno */\n\nfunction helloWorld() {\n  console.log('¡Hello World!');\n}\nhelloWorld() //ejecución\n\n/* Funcion con un parametro y sin retorno */\n\nfunction hiAgain(name) {\n  console.log(`Hello, ${name}!`);\n}\nhiAgain('Diego')\n\n/* Funcion con varios parametros sin retorno */\n\nfunction SumOfNumbers(a, b) {\n  let add = a + b;\n  console.log(`La suma de ${a} y ${b} es = ${add}`)\n}\naddNumbers(34, 35)\n\n/* Funcion sin parametros y con retorno */\n\nfunction Number() {\n  return 7\n}\nconsole.log('el numero es', Number());\n\n/* Funcion con parametro y con retorno */\n\nfunction Name(name){\n  return `Hello ${name}!`\n}\nconsole.log(Name('Itachi'))\n\n/* Funcion con varios parametros y con retorno */\n\nfunction nameAndLanguage(name, language) {\n  return `¡Hello! my name is ${name}, and my favorite language is ${language}`\n}\nconsole.log(nameAndLanguage(Diego, JavaScript));\n\n/* Arrow Functions sin parametros ni retorno */\n\nconst Hello = () => console.log('¡Hello! from the console');\n\n/* Arrow Functions con parametros y retorno */\n\nconst sayHello = (name) => {\n  return `Hello ${name}, from the arrow function`\n}\nconsole.log(sayHello('Messi'));\n\n/* función clousure */\n\nfunction helloClosure () {\n  let counter = 0;\n\n  function increment () {\n    counter++;\n    return counter;\n  }\n  return increment;\n}\n\nconst incremento = helloClosure();\n\nconsole.log(incremento()); // 1\nconsole.log(incremento()); // 2\n\n/* Variable global y local */\n\nconst imGLobal = 'soy Global';\n\nfunction localGlobal () {\n  const imLocal = 'soy Local'\n\n  console.log(imGLobal);\n  console.log(imLocal);  \n}\nlocalGlobal()\n\n/* Funcion Built-in */\n\nlet Num = 2\nlet Text = \"Hola\"\nconsole.log(\"variableNumerica: \" + typeof(Num) + \" variableTexto: \" + typeof(Text))\n\n/* EXTRA */\n\nfunction from1To100 (param1, param2) {\n  let count = 0;\n  for (let i = 1; i <= 100; i++) {\n    if (i % 3 === 0 && i % 5 === 0) {\n      console.log(param1 + param2);\n    } else if (i % 3 === 0) {\n      console.log(param1);\n    } else if (i % 5 === 0) {\n      console.log(param2);\n    } else {\n      console.log(i);\n      count++\n    }\n  }\n  return count\n}\n\nconst fizzBuzz = from1To100('Fizz', 'Buzz');\nconsole.log(fizzBuzz);\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/duendeintemporal.js",
    "content": "/* { RETOS DE PROGRAMACIÓN }  #2 FUNCIONES Y ALCANCE */\n// I use the book \"Eloquent JavaScript: A Modern Introduction to Programming\" by Marijn Haverbeke for concept reference.\n// I also use the book \"Secrets of the JavaScript Ninja\" by John Resig, Bear Bibeault, and Josip Maras.\n// I refer to \"JavaScript Notes for Professionals\" from the people of Stack Overflow. https://goalkicker.com/JavaScriptBook\n// Additionally, I use GPT as a reference and sometimes to correct or generate proper comments.\n\n\n//short for console.log\nlet log = console.log.bind(console);\n\n/* FUNCTIONS */\n/* Functions are the bread and butter of JavaScript programming. The concept of wrapping a piece of program in a value has many uses. It gives us a way to structure larger programs, to reduce repetition, to associate names with subprograms, and to isolate these subprograms from each other. \n\nIn JavaScript, the fundamental unit of execution is a function. We use them all the\ntime, to calculate something, to perform side effects such as changing the UI, to\nachieve code reuse, or to make our code easier to understand. \n*/\n\n\n//Functions as first-class objects\n/*Functions in JavaScript possess all the capabilities of objects and are thus treated like any other object in the language. We say that functions are first-class objects, which can also be */\n\n// Created via literals.  \nfunction  addPad(number, width, pad = 0){\n   let result = String(number); \n   while (result.length < width) {\n        result = `${pad}` + result;\n   }\n    return result;\n}\n\n\nlog(addPad(4, 3, '#'))// ##4\nlog(addPad(56, 3, '$'))// $56\nlog(addPad(7, 3))// 007\n\n//note: See that we can pass default arguments as in the last example\n\n// Assigned to variables, array entries, and properties of other objects\nlet square = function(n){\n    return n * n;\n};\n\nlet funcArray = [];\nfuncArray.push(square(8));// Adds a new function to an array\nlog(funcArray)//  [ 64 ]\n\nlet data ={ book_name:'Hackbook', }\ndata.some_method = function(){ console.log(`${data.book_name} is now avaible in z-lib.org, so hack the world.`) };// Assigns a new function as a property of another object\ndata.some_method()// Hackbook is now avaible in z-lib.org, so hack the world.\n\n\n//A newly created object passed as an argument to a function\n\n//Passed as arguments to other functions (callbacks)\nfunction call(doSomething){\n    doSomething();\n}\n\ncall(()=> log('Hi roadmap coders!'))// Hi roadmap coders!\n\n//Returned as values from functions\nfunction returnFunc(){\n    return function(str){ console.log(str) }\n}\n\nconst greeting = returnFunc();\ngreeting('Hi there!')// Hi there!\n\n\n\n//They can possess properties that can be dynamically created and assigned as in objects:\n\nlet callMom = function(){ log('Mommmmm!') };\n\ncallMom()// Mommmmm!\ncallMom.name = \"Mom\";\nlog(callMom.name)// Logs: callMom cause \"name\" is a inherit property of the function constructor, and is not writeble\n\ncallMom.something = 'something';\nlog(callMom.something)// something\n\nlog(callMom)/* Logs: \nfunction callMom()\n    ​arguments: null\n    caller: null\n    length: 0\n    name: \"callMom\"\n    prototype: Object { … }\n    something: \"something\"\n    <prototype>: function () */\n\n\n/* Whatever we can do with objects, we can do with functions as well. Functions are objects, just with an additional, special capability of being invokable: Functions can be called or invoked in order to perform an action. */\n\n/*Constructor functions are functions designed to construct a new object. Within a constructor function, the keyword this refers to a newly created object which values can be assigned to. Constructor functions \"return\" his new object automatically. */\n\nfunction Cat(name, color, sound){\n    this.name = name;\n    this.color = color;\n    this.sound = sound;\n}\n\n//Constructor functions are invoked using the new keyword:\nlet psicoCat = new Cat(\"Psicotrogato\", \"Black & White\", \"Meaw\");\nlog(psicoCat.color)// Black & White\npsicoCat.sound = \"Hey girl what's your name, what's your name?... I forgot\";\n\n/*Constructor functions also have a prototype property which points to an object whose properties are automatically inherited by all objects created with that constructor: */\n\nCat.prototype.speak = function(){\n    log(this.sound);\n}\n\npsicoCat.speak(); // \"Hey girl what's your name, what's your name?.. I forgot\"\n\n\n//Closure\n/* The ability to treat functions as values, combined with the fact that local bindings are re-created every time a function is called, brings up  interesting possibilities */ \n\nconst incrementer = (function(n){\n    let local = n;\n    return () => local++;\n})(0); // Immediately invoked with an initial value of 0\n\nconsole.log('incrementer value is:', incrementer()); // incrementer value is:  0\nconsole.log('incrementer value is:', incrementer()); // incrementer value is:  1\nconsole.log('incrementer value is:', incrementer()); // incrementer value is:  2\n\n//in the previus example we use an IIFE(Inmediatly Invoked Function Expression) to create a clousure, but we can achive the same with regular functions\n\n function square_v2(n){\n    return ()=> n * n;\n}\n\nconst pow64 = square_v2(64);\nconst pow78 = square_v2(78);\n\nlog(pow64())// 4096\nlog(pow78())// 6084\n\n\n// Arrow Functions ()=>{ }\nconst factor = (n)=>{\n    if(n == 1) return 1;\n    return n * factor(n - 1);\n}\n\nlog(factor(8))// 40320\n\n//Note: here factor is a recursive function too. It means that it's a function that calls it self.\n\n//Arrow function allow us to abreviate the expresion when they have only one parameter or a single expression\n\nconst square_v3 = n => n * n;\nlog(square_v3(4))// 16\n//note we omit the curly braces, the return and also the parentesis\n\n\n//Note 2: is important to have in mind that arrows function doesn't have their own 'this' context\n\nconst obj = {\n    value: 'Rutadeprogramacion Exercice #2.',\n\n    advertisement: function(){\n        log(this.value); // Rutadeprogramacion Exercice #2\n        setTimeout(() => {\n            alert(`${this.value} Please open the Browser Developer Tools.`);\n        }, 1000);\n    }\n};\n\nobj.advertisement()// Alert: Rutadeprogramacion Exercice #2. Please open the Browser Developer Tools. and Logs in console: Rutadeprogramacion Exercice #2.\n\n/* Note: Because arrows function doesn't have `this`, the 'this' points to obj. If we had used a regular function instead of the arrow function inside the setTimeout, it would have alert undefined or throw a reference error. */ \n\n//So we have\n/* Function Declarations: A function declaration defines a named function. It is hoisted, meaning it can be called before it is defined in the code. */\n\nfunction substract(n, m){\n    return n - m;\n}\n\nlog(substract(8, 4))// 4\n\n/* Function Expressions: A function expression defines a function as part of a larger expression. It can be anonymous or named and is not hoisted. */\n\nconst multiply = function(n, m){\n    return n * m;\n};\n\nlog(multiply(8, 9))// 72\n\nconst add = function add(a, b){\n    return a + b;\n}// can share the name for the bindding word & the named function\n\nlog(add(3, 3))// 6\n\n/* Arrow Functions:  Introduced in ES6, arrow functions provide a more concise syntax for writing functions. They do not have their own this, which makes them useful in certain contexts. */\n\n\nconst divide = (n, m) =>  n / m ;\n\nlog(divide(543, 56))// 9.696428571428571\n\n/* Anonymous Functions: These are functions that do not have a name. They are often used in callbacks or as arguments to other functions. */\n\nwindow.addEventListener('load', function(){\n    const body = document.querySelector('body');\n    const title = document.createElement('h1');\n    \n    body.style.setProperty('background', '#000');\n    body.style.setProperty('text-align', 'center');\n    \n    title.textContent = 'Retosparaprogramadores #2.';\n    title.style.setProperty('font-size', '3.5vmax')\n    title.style.setProperty('color', '#fff');\n    title.style.setProperty('line-height', '100vh');\n    \n    body.appendChild(title);\n    \n    log( 'This is an anonymous function')// this will be logged at the end cause the nature of window event\n});\n\nlet sayHi = function(){\n    console.log('Hi');\n}\n\nsayHi()// Hi\n\n/* Named functions differ from the anonymous functions in multiple scenarios:\nWhen you are debugging, the name of the function will appear in the error/stack trace\nNamed functions are hoisted while anonymous functions are not\nNamed functions and anonymous functions behave differently when handling recursion\nDepending on ECMAScript version, named and anonymous functions may treat the function name property\ndifferently */\n\n/* Immediately Invoked Function Expressions (IIFE): An IIFE is a function that is executed immediately after it is defined. It is often used to create a new scope and avoid scope pollution. */\n\nlet iife = (function(){\n    console.log(\"This another example of IIFE functions\");//this will be logged\n})();\n\n\n/* Higher-Order Functions: These are functions that take other functions as arguments or return functions as their result. They are commonly used in functional programming. */\n\n//in example if we have sum\nfunction sum(numbers){\n    let total = 0;\n    for(let i = 0; i < numbers.length; i++ ){\n        total += numbers[i];\n    }\n    return total;\n}\n\n//and range \nfunction range(n, m){\n    let result = [];\n    for(let i = n; i <= m; i++){\n        result.push(i);\n    }\n    return result;\n}\n\n//them we can just\nlog(sum(range(1, 100)))// 5050\n\n/* Generator Functions: Introduced in ES6, generator functions can pause and resume execution. They are defined using the function * syntax and use the yield keyword. */\n\nfunction *IdGenerator() {\n    let id = 0;\n    while(true){\n        yield addPad(++id, 5) ;\n    }\n}\n\nconst idIterator = IdGenerator();\n\nlog(idIterator.next().value)// 00001\nlog(idIterator.next().value)// 00002\n\n\n/* Async Functions: Async functions are a way to work with asynchronous code. They return a promise and can use the await keyword to pause execution until a promise is resolved. */\n\n//Note: you will need a extention to allow CORS(Cross Origin Resource Sharing) to avoid the console warning\n\nconst getLoremIpsum = numberOfParagraphs => {\n    return fetch(`https://baconipsum.com/api/?type=meat-and-filler&paras=${numberOfParagraphs}`)\n        .then(response => response.json())\n        .then(loremIpsumTextArray => {\n           return loremIpsumTextArray;\n        })\n        .catch(error => {\n            showError(error);\n        });\n};\n\nconst showError = error => console.log(error);\n\n\n\n    async function logParagraphs() {\n        const result = await getLoremIpsum(2);\n        console.log(result);\n    }\n\nlogParagraphs();  // Logs: Array [ \"T-bone ham hock enim, ipsum frankfurter tri-tip consequat.  Reprehenderit ut occaecat elit in, qui ea flank chuck porchetta chicken bacon ham hock kielbasa hamburger.  Pork chop commodo strip steak mollit filet mignon andouille velit tempor fatback ea.  Capicola laboris beef ribs in chuck, et jerky swine exercitation ribeye ullamco in turkey.  Turkey dolor ball tip proident pariatur corned beef, chislic jerky leberkas fugiat doner.  Chuck laboris pork do, ut esse sed in drumstick deserunt ribeye voluptate tail reprehenderit.  Beef aliquip sint fugiat pork belly pig reprehenderit nisi corned beef chicken dolore ad proident non.\", \"Spare ribs officia irure, est brisket ham prosciutto.  Do proident consectetur, capicola ad bacon non pancetta magna aute.  Pork loin ribeye chuck doner, duis beef ribs ut ham hock adipisicing sed turkey boudin buffalo rump pancetta.  Deserunt ham pork chop short loin tail.\" ] or something similar\n\n// Functions that takes multiple arguments / the Rest parameter ...\n// Some times we don't know how many arguments we will recive, we can use the rest parameter in those cases\n\nconst total = (...numbers)=> {\n    return numbers.reduce((total, num) => total + num, 0);\n}\n\nlog('Total: ',total(10, 256, 345, 465, 87, 432))// Total: 1595\n\n/* CLOUSURES AND SCOPES */\n\n// Scope:  A scope refers to the visibility of identifiers in certain parts of a program. \n/* Closure: A closure allows a function to access and manipulate variables that are external to that\nfunction. Closures allow a function to access all the variables, as well as other functions, that are in scope when the function itself is defined. */\n/* Hoisting is a mechanism which moves all variable and function declarations to the top of their scope. However, variable assignments still happen where they originally were. */\n\n/* When using an anonymous function, the function can only be called after the line of declaration, whereas a named function can be called before declaration. Consider */\n\n// This will works cause doSoemthing is a Named Function and JavaScript hoists function declarations to the top of their containing scope.\nlog(doSomething());\n\nfunction doSomething(){\n    console.log(\"I'm here coding, and I'm amazed at all we can learn by following this roadmap.\")\n}\n\n// This will throw an error because an anonymous function cannot be called before its declaration.\n// log(doAnotherthing())\n\nlet anotherthing = function(){\n    console.log('never log this...')\n}\n\nlet friend = 'Asterix';\n\nfunction showClosure(){\n    log(friend)// Asterix in scope\n    let anotherFriend = 'Obelix';\n    function innerClosure(){\n        let anotherOne = 'Idefix'\n        log(anotherFriend)// Obelix in scope\n        log(friend)// Asterix in scope\n        log(anotherOne)// Idefix in scope\n     }\n     //log(anotherOne)// throw an Error: anotherOne is not defined, is not in scope\n  innerClosure();\n}\n\nshowClosure();\n//log(anotherFriend)// Throw an Error: anotherFriend is not defined, is not in scope\n\n\n/* Closures lets us do some interesting things, such as defining \"private\" variables that are visible only to a specific function or set of functions. A contrived (but popular) example: */\n\n\nconst  makeCounter = ()=> {\n    var counter = 0;\n    return {\n              value: function() {\n                        return counter;\n              },\n              increment: function() {\n                           counter++;\n              },\n              restart: function() {\n                          counter = 0;\n              }\n           };\n}\n\nlet counter1 = makeCounter();\nlet counter2 = makeCounter();\ncounter2.increment();\ncounter2.increment();\nlog(counter1.value())// 0\nlog(counter2.value())// 2\ncounter2.restart();\nlog(counter2.value)// 0\n\n// Note: When makeCounter() is called, a snapshot of the context of that function is saved.\n// Note2: Closures are also used to prevent global namespace pollution, often through the use of immediately-invoked function expressions.\n\n// Apply and Call\nfunction speak() {\n    let sentences = Array.prototype.slice.call(arguments);\n    let tell = '';\n    sentences.forEach(word => tell += word + ' ' );\n    console.log(this.name+\": \"+ tell);\n}\n\nlet person = { name: \"Niko\" };\n    speak.apply(person, [\"I\", \"will\", \"go\", \"through\", \"this\", \"roadmap\", \"until\", \"the\", \"end\" ]); // I will go throght this roadmap to the end\n    speak.call(person, \"But\", \"first\", \"I\", \"need\", \"some\", \"exercice\"); // But first I need some exercice\n\n/* Notice that apply allows you to pass an Array or the arguments object (array-like) as the list of arguments, whereas, call needs you to pass each argument separately. */\n\n/* As we see in the previus obj.adverstiment() example in line 155: When using arrow functions this takes the value from the enclosing execution context's this (that is, this in arrow functions has lexical scope rather than the usual dynamic scope). In global code (code that doesn't belong to any\nfunction) it would be the global object. And it keeps that way, even if you invoke the function declared with the arrow notation from any of the others methods here described. */\n\n/* The bind method of every function allows you to create new version of that function with the context strictly bound to a specific object. It is especially useful to force a function to be called as a method of an object. */\n\nlet person2 = { name: 'Anna' };\n\nfunction sayHiLady() {\n    log(`Hi ${this.name}`);\n}\n\nhiAnna = sayHiLady.bind(person2);\nhiAnna()// Hi Anna\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/dumbnoxx.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n// Ejemplo de funciones con la keywork function\n\n// Funciones sin retorno y sin parametros\nfunction hola() {\n  console.log(\"Hola, Mundo\");\n}\n\nconst adios = () => {\n  console.log(\"Adios Mundo\");\n}\n\n// Funciones con retorno sin parametros\nfunction retorno() {\n  return \"Retorna este string esta funcion.\";\n}\n\nconst retornoFlecha = () => {\n  return \"Rertorna otra string esta funcion\";\n}\n\n// Funciones con parametros sin retorno\nfunction sum(a, b) {\n  console.log(a + b);\n}\n\nconst sumas = (a, b) => {\n  console.log(a + b);\n}\n\n// Funciones con retorno y con parametros\nfunction sutra(a, b) {\n  return a - b;\n}\n\nconst resta = (a, b) => {\n  return a - b;\n}\n\n// Funciones dentro de funciones\nfunction funcionInFuncion() {\n  function suma(a, b) {\n    return a - b;\n  }\n  return suma(3, 3);\n}\n\nconst functionInFunction = () => (a, b) => a - b;\n\n\nfunctionInFunction(2, 3); // Asi se usaria\n\n// Funciones ya creadas en el lenguaje\n\nconst parseInts = parseInt(\"2\"); // Output 2\nconsole.log(parseInts);\n\nconst parseFloats = parseFloat(\"2.3\"); // Output 2.3\nconsole.log(parseFloats);\n\n\n\nconst variableGlobal = 2; // Esta variable podra estar en cualquier funcion en el documento\n\nconst functionVariableLocal = () => {\n  const variableLocal = 2; // Esta variable solo podra estar disponible dentro de la funcion\n  console.log(variableGlobal);\n  console.log(variableLocal);\n}\n\nfunctionVariableLocal();\n// console.log(variableLocal); // Da un error\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n*/\n\nconst retoExtra = (string1, string2) => {\n  let count = 0;\n  for (let i = 0; i <= 100; i++) {\n    if (i % 3 === 0 && i % 5 === 0) {\n      console.log(string1 + string2);\n    }\n    if (i % 5 === 0) {\n      console.log(string2);\n    }\n    if (i % 3 === 0) {\n      console.log(string1);\n    }\n    else {\n      console.log(i);\n      count += 1;\n    }\n  }\n  return `El numero de veces que se ha impreso el numero en lugar de los textos es: ${count}`;\n}\n\nconsole.log(retoExtra(\"Hola, \", \"Mundo\"));\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/edisplai.js",
    "content": "function saludo(nombre){\n    console.log(\"Hola \" + nombre);\n}\nsaludo(\"Edison\")\nfunction despedir(nombre){\n    console.log(\"Adios \" + nombre);\n}\ndespedir(\"Edison\")\n\nconsole.log(\"´´´´´´´´´´Funcion con parametros´´´´´´´´´´´´´´\");\nfunction suma(a, b, c){\n    return(a+b+c);\n} \nlet total = suma(20,23,1443);\nlet total2 = suma(193,48,37);\nlet total3 = suma(849393,93948,7493);\n\nconsole.log(\"El total es \",total);\nconsole.log(\"El total es \",total2);\nconsole.log(\"El total es \",total3);\n\n \n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/elianisdev.js",
    "content": "// * EJERCICIO:\n//  * - Crea ejemplos de funciones básicas que representen las diferentes\n//  *   posibilidades del lenguaje:\n//  *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n//  * - Comprueba si puedes crear funciones dentro de funciones.\n//  * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n\n//  * - Debes hacer print por consola del resultado de todos los ejemplos.\n//  *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n\n//  * - Ejemplo de función sin parámetros ni retorno\nfunction saludar() {\n    console.log('Hola, ¿cómo estás?');\n}\nsaludar();\n\n//  * - Ejemplo de función con un parámetro y sin retorno\nfunction saludarPersona(nombre) {\n    console.log('Hola, ' + nombre);\n}\nsaludarPersona('Elianis');\n\n//  * - Ejemplo de función con un parámetro y con retorno\nfunction sumar(a, b) {\n    return a + b;\n}\nconsole.log(sumar(2, 3));\n\n//  * - Ejemplo de función con varios parámetros y con retorno\nfunction multiplicar(a, b, c) {\n    return a * b * c;\n}\nconsole.log(multiplicar(2, 3, 4));\n\n//  * - Ejemplo de función con retorno y función dentro de función\nfunction calcular(a, b) {\n    function sumar(a, b) {\n        return a + b;\n    }\n    return sumar(a, b);\n}\nconsole.log(calcular(2, 3));\n\n//  * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\nconsole.log(Math.random());\n\n//  * - Crea una función que reciba un número y devuelva si es par o impar.\nfunction parImpar(numero) {\n    if (numero % 2 === 0) {\n        return 'El número es par';\n    } else {\n        return 'El número es impar';\n    }\n}\nconsole.log(parImpar(2));\n\n\nfunction imprimirTexto(texto1, texto2) {\n    for (let i = 1; i <= 100; i++) {\n        if (i % 3 === 0 && i % 5 === 0) {\n            console.log(texto1 + texto2);\n        } else if (i % 3 === 0) {\n            console.log(texto1);\n        } else if (i % 5 === 0) {\n            console.log(texto2);\n        } else {\n            console.log(i);\n        }\n    }\n\n}\nimprimirTexto('Hola', 'Mundo');\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/emaenriquez.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n */\n\n// funcion sin parametros ni retorno\nfunction holaMundo(){\n    console.log('hola mundo');\n}\n\nholaMundo();\n\n// funcion con varios parametros\nfunction sumar(num1,num2){\n    console.log(num1+num2);\n}\n\nsumar(10,20);\n\n// funcion con retorno\nfunction resta(num1,num2) {\n    return num1 - num2;\n}\n\nlet resultado = resta(10,20);\n\nconsole.log(resultado);\n\n// funciones anidadas\nfunction suma(n) {\n\n    function incrementar(n2) {\n        return n + n2;\n    }\n\n    return incrementar;\n}\n\n// Llama a la función externa y guarda la función devuelta\nlet sumaCinco = suma (5);\n\n// Llama a la función devuelta con un argumento\nconsole.log (sumaCinco (3)); // Muestra 8\n\n// funcion ya creada en el lenguaje.\nlet numeroRamdom = Math.random()*100;\n\nconsole.log(numeroRamdom)\n\n\n// variable LOCAL y GLOBAL\n// grobal\nlet contador = 10\n\nfunction recorido() {\n    for (let i = 0; i < contador; i++) {\n        console.log(i)\n    }\n}\nrecorido()\n\n// local\nfunction recorido() {\n    \n    let contador = 10\n    \n    for (let i = 0; i < contador; i++) {\n        console.log(i)\n    }\n\n}\n\nrecorido()\n\n\n//  * DIFICULTAD EXTRA (opcional):\n//  * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n// * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n// *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n// *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n// *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n// *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n// *\n// * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n// * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n\n\nfunction extra(str1,str2){\n\n    let contador = 0\n\n    for (let i = 0; i <= 100; i++) {\n\n        if (i % 3 == 0 && i % 5 == 0) {\n            console.log(str1 + \" \" + str2);\n            continue;\n        }\n\n        if ( i % 3 == 0) {\n            console.log(str1);\n            continue;\n        }\n\n        if ( i % 5 == 0) {\n            console.log(str2)\n            continue;\n        }\n        \n        contador++\n    }\n\n    return contador\n\n}\n\nconsole.log(\n    \"Número de veces que se ha impreso: \",\n    extra(\"Hola\", \"JavaScript\")\n  );"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/emedevelopa.js",
    "content": "//FUNCIONES\n\n//Función Simple\nfunction saludo() {\n    console.log(\"Hola\");\n}\n\nsaludo();\n\n//Con parámetros\nfunction conParametros(a, b) {\n    console.log(a + b);\n}\nconParametros(2, 5)\n\n//Con retorno\nfunction conRetorno (nombre) {\n    if (nombre == \"Maria\") {\n    return true;\n    } else {\n        return false;\n    }\n}\nconRetorno(\"Maria\")\n\n//Funciones anidadas\nfunction hacerPastel () {\n    console.log(\"Hagamos un pastel!\");\n  \n    function mezclarIngredientes () {\n      console.log(\"Hora de mezclar\");\n    }\n    mezclarIngredientes()\n  \n    function hornear () {\n      console.log(\"Hora de hornear\");\n    }\n    hornear() \n  \n    function decorar () {\n      console.log(\"Toca decorar el pastel\")\n    }\n    decorar()\n\n    function listo () {\n        console.log(\"Pastel listo! A comer!\")\n    }\n    listo()\n  }\n  \n  hacerPastel()\n\n\n  //Variable local\n  function variableLocal() {\n    let a = \"a\";\n  }\n  variableLocal() //Esto imprime a. \n  console.log(a) // Undefined\n\n  //Variable Global\n  let b = \"b\";\n  function variableGlobal() {\n    console.log(b);\n  }\n  variableGlobal() //Imprime b.\n  \n\n  //Ejercicio Extra\n  function numeros(a, b) {\n    let contador = 0;\n    for (let i = 0; i <= 100; i++) {\n      if (i % 3 == 0) {\n        console.log(a);\n      } else if (i % 5 == 0) {\n        console.log(b);\n      } else if (i % 3 == 0 && i % 5 == 0) {\n        console.log(a + b);\n      } else {\n        console.log (i);\n        contador++;\n      }\n    }\n    return contador;\n  }\n\n  console.log(\"Número de veces que se ha impreso el número: \" + numeros(\"Hola\", \"Adios\"));"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/eonOzux.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\nfunction hola(){\n    let name = \"EonOzux\"\n    console.log(\"Mi nombre es \" + name)\n};\n// funcion con variable\nhola();\n\nfunction parametro(lenguaje){\n    console.log(`Codigo en ${lenguaje}`) //${} inyectar variables en una cadena de texto\n\n};\nparametro(\"JavaScript\")\n\nfunction expiracion(dia,mes){\n    console.log(`El producto vence en ${dia}/ ${mes}`)\n};\nexpiracion(\"30\",\"Setiembre\")\n\nfunction retorno(y,x){\n    return x + y\n};\nlet resultado = retorno(5,8);\nconsole.log(resultado);\n\n\n//Variable global (es una variable que está declarada fuera de la función y puede accederse a ella desde cualquier punto del código)\nlet variable1 = 8\nfunction sumar (){\n    console.log(\"El resultado es:\", variable1 + 3)\n}\nsumar()\n\n//Variable local (es una variable que está declarada dentro de una función y solo puede usarse dentro de ella)\nfunction restar (){\n    let variable2 = 6\n    console.log(\"El resultado de la resta es\",variable2 - 1)\n}\nrestar()\n\n/* * DIFICULTAD EXTRA (opcional):\n* Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n* - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n*   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n*   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n*   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n*   - La función retorna el número de veces que se ha impreso el número en lugar de los textos. */\n\n\n// Crear los prompts de tipo texto y se almacenen en una variable.\n\n\n\nfunction tarea_Extra(){\n    //Definimos Variables\n    let primer_texto = \"Primer texto\";\n    let segundo_texto = \"Segundo texto\";\n    let numero = 0\n    for(let x = 1;x < 100;x++){  //Creamos el contador hasta 100\n        if (x % 3 == 0 && x % 5 == 0){  // Si el numero del contador es el residuo de 3 o .\n            console.log(primer_texto + \"\" + segundo_texto)\n            continue\n        }\n        else if(x % 3 == 0){   // Si el numero del contador es el residuo de 3\n            console.log(primer_texto)\n            continue\n        }\n        else if(x % 5 == 0){   // Si el numero del contador es el residuo de 5\n            console.log(segundo_texto)\n            continue\n        }\n        else {  // Si el numero del contador no es residuo de los 2 anteriores \n            console.log(x)  // Imprima en la consola el numero\n        }\n        numero ++\n    }\n    return numero\n};\nconsole.log(\"Numero de veces que se ha impreso el contador:\",tarea_Extra())\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/eulogioep.js",
    "content": "// Variables globales\nlet contadorGlobal = 0;\n\n// 1. Función sin parámetros ni retorno\nfunction saludar() {\n    console.log(\"¡Hola, mundo!\");\n}\n\n// 2. Función con un parámetro y sin retorno\nfunction saludarPersona(nombre) {\n    console.log(`¡Hola, ${nombre}!`);\n}\n\n// 3. Función con múltiples parámetros y retorno\nfunction sumar(a, b) {\n    return a + b;\n}\n\n// 4. Función dentro de otra función\nfunction operacionMatematica(a, b) {\n    function multiplicar(x, y) {\n        return x * y;\n    }\n    return multiplicar(a, b) + 10;\n}\n\n// 5. Uso de una función incorporada en JavaScript\nfunction obtenerFechaActual() {\n    return new Date().toLocaleDateString();\n}\n\n// 6. Demostración de variable local vs global\nfunction incrementarContador() {\n    let contadorLocal = 0;\n    contadorLocal++;\n    contadorGlobal++;\n    console.log(`Contador local: ${contadorLocal}, Contador global: ${contadorGlobal}`);\n}\n\n// Llamadas a las funciones y impresión de resultados\nconsole.log(\"1. Función sin parámetros ni retorno:\");\nsaludar();\n\nconsole.log(\"\\n2. Función con un parámetro y sin retorno:\");\nsaludarPersona(\"Alice\");\n\nconsole.log(\"\\n3. Función con múltiples parámetros y retorno:\");\nconsole.log(`Suma de 5 y 3: ${sumar(5, 3)}`);\n\nconsole.log(\"\\n4. Función dentro de otra función:\");\nconsole.log(`Resultado de operación matemática: ${operacionMatematica(4, 5)}`);\n\nconsole.log(\"\\n5. Uso de una función incorporada en JavaScript:\");\nconsole.log(`Fecha actual: ${obtenerFechaActual()}`);\n\nconsole.log(\"\\n6. Demostración de variable local vs global:\");\nincrementarContador();\nincrementarContador();\n\n// DIFICULTAD EXTRA\nfunction imprimirYContar(texto1, texto2) {\n    let contadorNumeros = 0;\n\n    for (let i = 1; i <= 100; i++) {\n        if (i % 3 === 0 && i % 5 === 0) {\n            console.log(texto1 + texto2);\n        } else if (i % 3 === 0) {\n            console.log(texto1);\n        } else if (i % 5 === 0) {\n            console.log(texto2);\n        } else {\n            console.log(i);\n            contadorNumeros++;\n        }\n    }\n\n    return contadorNumeros;\n}\n\nconsole.log(\"\\nDIFICULTAD EXTRA:\");\nconst numerosPuros = imprimirYContar(\"Fizz\", \"Buzz\");\nconsole.log(`Números impresos sin ser reemplazados por texto: ${numerosPuros}`);"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/faga01.js",
    "content": "/* Funciones. Una función es un bloque de código diseñado para realizar una tarea en particular.\n Una función de javascript se ejecuta cuando algo la invoca o la llama.\n con funciones puedes reutilizar código, puedo utilizar el mismo código con diferentes argumentos para diferentes resultados. */\n\n// Función sin parametros ni retorno\n\n\nfunction myFunction1(){\n    let rta1 = 5 + 8;\n}\n\n// Función con parametros\n\nfunction myFunction2(a, b){\n    let rta2 = a - b;\n}\n\nvar i = 35;\nvar j = 10;\n\nfunction myFunction2a(i, j){\n    let rta2a = i - j;\n    return rta2a;\n}\n\nfunction myfunction3(item1, item2) {\n    return item1*item2;\n}\n\nlet x = myFunction4(5, 8, 2);\n\nfunction myFunction4(par1, par2, par3) {\n    return (par1 * par2) / par3;\n}\n\nfunction myFunction5(c, d) {\n    return c * d;\n}\n\nfunction myFunction6 (s, t) {\n    return myFunction5(s, t);\n}\n\nfunction myFunction7() {\n    return function myFunction8 () {\n        return 40 + 30;\n    }\n}\n\n\n/* console.log(myFunction1);\nconsole.log(myFunction2);\nconsole.log(myfunction3(2,5));\nconsole.log(x); \nconsole.log(myFunction6(5,8)); \nconsole.log(myFunction7()());\nconsole.log(myFunction2a(i,j));\nconsole.log(rta2);*/\n\n\n/* Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda. */\n\n\n/*\nfunction miPruebaExtra(parametroA, parametroB) {\n        let contadorVeces = 0;\n\n    for (let i=1; i <= 100; i++) {\n        \n        if (parametroA % 3 == 0 && parametroB % 5 == 0) {\n            contadorVeces++\n            console.log(parametroA + \" \" + parametroB);\n        } else if ( parametroA % 3 == 0) {\n            \n            console.log(parametroA);\n            contadorVeces++\n        } else if ( parametroB % 5 == 0) {\n            contadorVeces++\n            console.log(parametroB);\n        } else {\n            console.log(i);\n        }\n\n} \n    return contadorVeces;\n\n}\n*/\n\n\n\nfunction miPruebaExtra2 (parametroC, parametroD) {\n    \n    let contadorTexto = 0\n\n    if (parametroC % 3 == 0 && parametroD % 5 == 0) {\n        console.log(parametroC + \" \" + parametroD);\n        for (let index = 1; index <= 100; index++) {\n                \n            if(index % 3 == 0 || index % 5 == 0) {\n                contadorTexto++\n            }\n        }\n    } else if (parametroC % 3 == 0){\n        console.log(parametroC);\n        for (let index = 1; index <= 100; index++) {\n            if(index % 3 == 0) {\n                contadorTexto++\n            }\n        }\n    } else if (parametroD % 5 == 0){\n        console.log(parametroD);\n        for (let index = 1; index <= 100; index++) {\n            if(index % 5 == 0) {\n                contadorTexto++\n            }\n        }\n    } else {\n        for(let index = 1; index <= 100; index++)\n        console.log(index);\n    }\n\n    return \"numero de veces que se imprime el número\" + \": \" + contadorTexto;\n\n}\n\n//console.log(miPruebaExtra(\"21\", \"30\"));\n\nconsole.log(miPruebaExtra2(\"9\", \"25\"));\n\n\n\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/fdcorreadev.js",
    "content": "/**\n * Funciones en JavaScript se incia con la palabra funcion + nombre + () + {} y dentro de los {} se pone el codigo necesario para \n * \n * La siguientes funcion es simple\n */\n\nfunction greet() {\n    console.log('mi primera impresion por consola dentro de una funcion ¡Hola Mundo!')\n}\n\ngreet()\n\n/**\n * esta funcion tiene un return que hace el proceso dentro y retorna un valor\n * @returns el saludo\n */\n\nfunction return_greet() {\n    return 'segunda pero retornando un valor ¡Hola Mundo!'\n}\n\nconsole.log(return_greet())\n\n/**\n * funcion con solo un parametro\n * @param {String} name \n * @returns devuele el saludo\n */\nfunction greet_whit_name(name) {\n    return `Hola soy ${name} y esta es la funcion con un paramtero`\n}\n\nconsole.log(greet_whit_name('Fabian Correa'))\n\n/**\n * @param {number} num1 \n * @param {number} num2 \n * @returns \n * Funcioneas con parametros de entrada en este caso dos valores para que los sume y returna el valor\n */\n\nfunction sumarValores(num1, num2) {\n    return num1 + num2\n}\nconst result = sumarValores(4, 8)\nconsole.log('funcion con dos parametros ' + result)\n\n/**\n * Funcion con parametros por defecto \n * @param {string} name \n * @returns \n */\n\nfunction defaultValue(name = 'Fabian Correa') {\n    return `Hola soy ${name} y esta es la funcion con parametros por defecto`\n}\n\nconsole.log(defaultValue('jose perez'))\nconsole.log(defaultValue())\n\n/**\n * Las funciones tambien se puedes asignar a una variable, o dento de un objeto\n * @returns La funcion guaradad\n */\n\nconst saveFunction = function greetSave() {\n    return `Hola yo soy la Funcion Guardada`\n}\n\nconsole.log(saveFunction)\nconsole.log(saveFunction())\n\n//funcion que se puede pasar a otra variable\n\nconst otherFunction = saveFunction()\nconsole.log('otra funcion guardada dentro de otra variable ', otherFunction)\n\n\n\n//funcion guardad dentro de un objeto\nconst object = {\n    methodSave: saveFunction()\n}\n\nconsole.log('funcion dentro de un objeto ', object.methodSave)\n\n//Ejecutar una funncion pasada por parametro a otra funcion\nfunction printOtherFunction(func) {\n    console.log(`funcion ejecutada por otra funcion ${func()}`)\n}\n\nprintOtherFunction(saveFunction)\n\n\n/**\n * funcion fecha, funciona de igual forma pero no se utiliza la palabra funcion, se coloca () => {} esta es la forma de hacerlo\n */\n\nconst arrowFunction = () => {\n    return `Hola soy una funcion flecha (arrow Function)`\n}\n\nconsole.log(arrowFunction())\n\n/**\n *  estan un tipo de funciones que son muy importante en javascript que es el async que define una funcion asincronica el cual devuelve un objeto asyncFunction\n * se utiliza la funcion async antes de declararla y cuando esperamos el resultado le ponemos await\n */\n\nfunction resolveAfter2Seconds(x) {\n    return new Promise((resolve) => {\n        setTimeout(() => {\n            resolve(x)\n        }, 2000);\n    });\n}\n\nasync function add1(x) {\n    const a = await resolveAfter2Seconds(20);\n    const b = await resolveAfter2Seconds(30);\n    const z = x + a + b\n    return z\n}\n//la forma de reolverlo es mediante una promesa  utilizando la funcion y then, y en caso alguno el finally que sale primero que la respuesta\n//por la espera del await\nconsole.log(add1(20))\n\nadd1(10).then((res) => {\n    console.log(`mi primera promesa ${res}`)\n}).finally(\n    console.log('termino la promesa')\n)\n\n/**\n * funciones dentro de de otra funcion\n * \n * te muestro un poco como se utiliza el await ya que esta primero la funcion y como sabemos el codigo va de arriba hacia bajo en este caso\n * cuando corremos el codigo primero se imprime la condicion que la funcion wait.\n */\n\n\nconst principalFunction = (typeFunction, name) => {\n\n    async function wait(name) {\n        const print = await name;\n        console.log(`pero tambien te imprimo mi nombre ${print}`)\n    }\n    wait(name)\n\n    if (typeFunction === \"clasica\") {\n        function printName(name) {\n            console.log(`${name} esto es una funcion clasica`)\n        }\n        printName(name)\n    } else {\n        const arrowFunction = (name) => {\n            console.log(`${name} esto es una arrow function`)\n        }\n        arrowFunction(name)\n    }\n}\n\nprincipalFunction('clasica', 'Fabian Correa')\n\n/**\n * funciones propias del lengua en este caso de javascript, existen muchas en este ejemplo pongo pocas pero existen demasiadas\n * asi que les dejo el enlace para que pueda darle una chequeada https://developer.mozilla.org/es/docs/Web/JavaScript/Guide/Functions#funciones_predefinidas\n */\nconsole.log(\"-----------------------------------------------------------Funciones del lenguaje-------------------------------------------\")\nconst valor = '22'\nconsole.log(`funcion para convertir de text a numero ${parseInt(valor)}`)\nconsole.log(typeof parseInt(valor))\n\nconst string = 22\nconsole.log(`funcion para convertir de numero a texto ${string.toString()}`)\nconsole.log(typeof valor.toString())\n\nconst text = 'HoLa mUnDo! Fabian correa'\nconsole.log(`pasa texto a mayusculas ${text.toUpperCase()}`)\nconsole.log(`pasa texto a minuscula ${text.toLowerCase()}`)\n\nlet separarText = text.split(\" \")\nconsole.log('funcion para texto separado ', separarText)\n\nsepararText.map((palabra, index) => {\n    console.log(`palabra ${index} ${palabra}`)\n})\n\n\n/**\n * En los leguajes de programacion existen variables globales y locales en javascript tiene esa parte bastante desarrollada, te explico con unos ejemplos\n * pero esto es para evitar re declarar o remplazar una variable por eso utilizamos solo let y const, porque \"var\" es bastante global \n */\n\nconsole.log('--------------------------GLOBAL Y LOCAL-----------------------------------------------------------------------')\n\n/**\n * en este caso la variable var se deja remplazar.\n */\n\nvar texto = 'hola'\n\ntexto = 'si se puede'\n\nconsole.log(texto)\n\n// en este caso si porngo otro var con la misma se dej\n\nvar texto = 'si deja declarar de nuevo'\n\n/**\n * en este caso la variable let tambien se deja remplazar.\n */\n\nlet varibaleLet = 'hola'\n\nvaribaleLet = 'si se puede'\n\nconsole.log(texto)\n\n// en el caso se let genera un error al igual que const\n// let varibaleLet = 'no se deja declarar de nuevo'\n\n/**\n * en este caso la variable const no deja porque hace referencia a constante osea no se modifica debe dar error.\n */\n\nconst varibaleConst = 'hola'\n\n// varibaleConst = 'si se puede'\n\n// console.log(texto)\n\n/**\n * entonces con esta pequeña explicación vamos entendiendo un poco la declaraciones de global y local scope\n * como vemos a continuacion nosotros podemos declarar una variable afuera con el mismo nombre y no se ve afectada la de adentro de la funcion\n * pero que pasa si lo hacemos con let\n */\n\nconst replaceVariable = 'utilizar variable dento de la funcion'\n\nfunction variableDeclarar() {\n    const replaceVariable = 'esta es una variable nueva'\n    return replaceVariable\n}\nconsole.log(replaceVariable)\nconsole.log(variableDeclarar())\n\n/**\n * en este caso let se puede utilizar dento de la funcion y remplazar el valor como se muestra en el siguiente ejemplo pero con\n * const no se puede generaria un error. \n * \n * en resumen el global es cuando tenemos una variable que podemos utilizar en varios segmentos de codigo y el local solo se puede utilizar dento\n * de un segmento de codigo que es lo ideal por buenas practicas es bueno siempre utilizar const.\n * \n */\n\nconsole.log('-----------------------------varibale con Let -------------------------------------------')\nlet replaceVariableLet = 'utilizar variable dento de la funcion'\n\nfunction variableDeclararLet() {\n    replaceVariableLet = 'esta es una variable nueva'\n    return replaceVariableLet\n}\nconsole.log('--Anterior--', replaceVariableLet)\nconsole.log(variableDeclararLet())\nconsole.log('--Despues--', replaceVariableLet)\n\n\n/**\n * Solucion de ejercicio Extra\n */\n\nfunction Ejercicio02(text1, text2) {\n    let coutOtherNumbers = 0\n    for (i = 0; i <= 100; i++) {\n        if (i % 3 === 0 && i % 5 === 0) {\n            console.log(i, ' ', text1, i, ' ', text2)\n        } else if (i % 3 === 0) {\n            console.log(i, ' ', text1)\n        } else if (i % 5 === 0) {\n            console.log(i, ' ', text2)\n        } else {\n            coutOtherNumbers++;\n        }\n    }\n    return coutOtherNumbers\n}\n\nconst countValor = Ejercicio02('hola', 'mouredev')\n\nconsole.log(`numeros que no son multiplos de 5 ni de 3 ${countValor}`)"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/fernandog25.js",
    "content": "//Función sin parámetros ni retorno\nfunction texto()\n{\n    console.log(\"Hola mundo\");\n}\n\ntexto();\n\n//Función con parámetros\nfunction suma(num1,num2)\n{\n    console.log(num1 + num2);\n}\n\nsuma(2,3);\n\n//Función con parámetro y retorno\nfunction cuadrado(x)\n{\n    return x*x;\n}\n\nconsole.log(cuadrado(4));\n\n//Función dentro de otra función\n{\n    function cubo(f,m)\n    {\n        resultado = [];\n        for(var i=0; i<m.length; i++)\n            resultado[i] = f(m[i]);\n        return resultado;\n    }\n\n    const f = function (num)\n    {\n        return num*num*num;\n    }\n\n    var matriz = [1,2,3,4]\n    console.log(cubo(f, matriz));\n}\n\n//Ejemplo de función creada por el lenguaje\n\nvar aleatorio = Math.random(); // Math.random es una función que genera un número aleatorio entre 0 y 1\nconsole.log(aleatorio);\n\n//Variable global y local\n\nvar x = 8;\n\nfunction numero()\n{\n    var x = 6;\n\n    console.log(x); //Muestra el valor de la variable local\n}\n\nconsole.log(x); //Muestra el valor de la variable global\nnumero();\n\n/*DIFICULTAD EXTRA (opcional):\nCrea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n- La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n- Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n- Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n- Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n- La función retorna el número de veces que se ha impreso el número en lugar de los textos. */\n\nfunction lista(multiplo3, multiplo5)\n{\n    for(var i=1; i<101; i++)\n        {\n            if(i % 3 == 0 && i % 5 == 0)\n                console.log(multiplo3 + \" y \" + multiplo5);\n            else if(i % 3 == 0)\n                console.log(multiplo3);\n            else if(i % 5 == 0)\n                console.log(multiplo5);\n            else\n            console.log(i);\n        }\n}\n\nlista(\"múltiplo de 3\", \"múltiplo de 5\");"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/fravelz.js",
    "content": "// Funciones en JavaScript ************************************************** //\n\n//Función sin parámetros ni retorno\nfunction texto() {\n    console.log(\"Hola mundo\");\n}\ntexto();\n\n//Función con parámetros\nfunction suma(num1,num2) {\n    console.log(num1 + num2);\n}\nsuma(2,3);\n\n//Función con parámetro y retorno\nfunction cuadrado(x) {\n    return x*x;\n}\n\nconsole.log(cuadrado(4));\n\n// crear scope para función dentro de otra función\n{\n    function cubo(f,m)\n    {\n        resultado = [];\n        for(var i=0; i<m.length; i++)\n            resultado[i] = f(m[i]);\n        return resultado;\n    }\n\n    const f = function (num)\n    {\n        return num*num*num;\n    }\n\n    var matriz = [1,2,3,4]\n    console.log(cubo(f, matriz));\n}\n\n//Ejemplo de función creada por el lenguaje\n\nvar aleatorio = Math.random(); // Math.random es una función que genera un número aleatorio entre 0 y 1\nconsole.log(aleatorio);\n\n// Variable global y local ************************************************** //\nvar x = 8;\n\nfunction numero() {\n    var x = 6;\n\n    console.log(x); //Muestra el valor de la variable local\n}\n\nconsole.log(x); //Muestra el valor de la variable global\nnumero();\n\n/*DIFICULTAD EXTRA (opcional):\nCrea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n- La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n- Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n- Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n- Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n- La función retorna el número de veces que se ha impreso el número en lugar de los textos. */\n\nfunction lista(multiplo3, multiplo5) {\n    for(let i=1; i<101; i++) {\n            if(i % 3 == 0 && i % 5 == 0) console.log(multiplo3 + \" y \" + multiplo5);\n            else if(i % 3 == 0) console.log(multiplo3);\n            else if(i % 5 == 0) console.log(multiplo5);\n            else console.log(i);\n        }\n}\n\nlista(\"múltiplo de 3\", \"múltiplo de 5\");\n\n// > Autor: Fravelz\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/garos01.js",
    "content": "// Función sin parámetros ni retorno\nfunction saludar() {\n  console.log(\"¡Hola, mundo!\");\n}\n\nsaludar();\n\n// Función con un parámetro y retorno\nfunction cuadrado(numero) {\n  return numero ** 2;\n}\n\nlet resultadoCuadrado = cuadrado(5);\nconsole.log(\"El cuadrado de 5 es:\", resultadoCuadrado);\n\n// Función con varios parámetros y retorno\nfunction suma(a, b) {\n  return a + b;\n}\n\nlet resultadoSuma = suma(3, 7);\nconsole.log(\"La suma de 3 y 7 es:\", resultadoSuma);\n\n// Función dentro de otra función\nfunction operacionCompleja(x, y) {\n  function multiplicar(a, b) {\n    return a * b;\n  }\n\n  let resultadoMultiplicacion = multiplicar(x, y);\n  return resultadoMultiplicacion + 10;\n}\n\nlet resultadoOperacion = operacionCompleja(2, 3);\nconsole.log(\"El resultado de la operación compleja es:\", resultadoOperacion);\n\n// Variable local y global\nlet variableGlobal = 10;\n\nfunction funcionConVariables() {\n  let variableLocal = 5;\n  console.log(\"Variable local dentro de la función:\", variableLocal);\n  console.log(\"Variable global dentro de la función:\", variableGlobal);\n}\n\nfuncionConVariables();\n\n// Intentar acceder a variableLocal aquí daría un error, ya que es local a la función.\n// console.log(\"Intento de acceder a variableLocal fuera de la función:\", variableLocal);\nconsole.log(\"Variable global fuera de la función:\", variableGlobal);\n\n// Ejercicio extra\nfunction imprimirNumerosYContarTextos(texto1, texto2) {\n  let contadorTextos = 0;\n\n  for (let numero = 1; numero <= 100; numero++) {\n    if (numero % 3 === 0 && numero % 5 === 0) {\n      console.log(texto1 + texto2);\n      contadorTextos++;\n    } else if (numero % 3 === 0) {\n      console.log(texto1);\n      contadorTextos++;\n    } else if (numero % 5 === 0) {\n      console.log(texto2);\n      contadorTextos++;\n    } else {\n      console.log(numero);\n    }\n  }\n\n  return contadorTextos;\n}\n\nlet resultado = imprimirNumerosYContarTextos(\"Fizz\", \"Buzz\");\nconsole.log(`Se imprimieron ${resultado} textos en total.`);\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/gianbordon.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n//  Funcion sin parametros\n\nfunction saludar(){\n    console.log('Hola, buenos dias.')\n}\nsaludar()\n\n// Funcion con un parametro\n\nfunction saludarNombre(name){\n    console.log(`Hola, te saluda ${name}.`)\n}\nsaludarNombre(\"Mickey\")\n\n// Funcion con parametros \n\nfunction suma(a,b){\n    let res = a + b\n    console.log(`La suma de los numeros es: ${res}`)\n}\nsuma(2,2)\n\n// Fucion con return\n\nfunction resta(a,b){\n    let res = a - b\n    return res\n}\n\nconsole.log(resta(9,4))\n\n// Funcion dentro de una funcione\n\nfunction funcUno(){\n    function funcDos(){\n        console.log('Esta es la funcion Dos')\n    }\n    funcDos()\n    console.log('Esta es la funcion Uno')\n}\n\nfuncUno()\n\n// Funciones ya creadas por el lenguaje\n\nlet str = \"2\"\nconsole.log(str)\nconsole.log(parseFloat(str))\n\n// variable Local vs variable Global \n\nlet Global = \"Soy una variable Global\"\n\nfunction func(){\n    let Local = \"Soy una variable Local\"\n    console.log(`LLamo a la varible global: ${Global}`)\n    console.log(`LLamo a la varible local: ${Local}`)\n}\n\nfunc()\nconsole.log(Global)\n// console.log(Local) No funciona porque es local - Error Message :Local is not defined\n\n// Ejercicio Extra \n\nfunction funcTres (paramI,paramII){\n    let i   \n    for(let i = 1; i <= 100; i++){\n        if (i % 3 == 0 && i % 5 == 0) {\n            console.log(paramI + paramII);\n        } else if (i % 3 == 0) {\n            console.log(paramI);\n        } else if (i % 5 == 0) {\n            console.log(paramII);\n        } else {\n            console.log(i);\n        }\n    }\n    return i;\n}\n\nfuncTres(\"perro\",\"Gato\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/giovanyosorio.js",
    "content": "/*\n* EJERCICIO:\n* - Crea ejemplos de funciones básicas que representen las diferentes\n*   posibilidades del lenguaje:\n*   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n* - Comprueba si puedes crear funciones dentro de funciones.\n* - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n* - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n* - Debes hacer print por consola del resultado de todos los ejemplos.\n*   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n*\n* DIFICULTAD EXTRA (opcional):\n* Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n* - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n*   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n*   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n*   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n*   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n*\n* Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n* Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n*/\n\n// Ejemplo de función sin parámetros ni retorno\nfunction saludar() {\n  console.log('Hola mundo!');\n}\n\n// Ejemplo de función con parámetros y retorno\nfunction sumar(a, b) {\n  return a + b;\n}\n\n// Ejemplo de función con varios parametros y retorno\nfunction multiplicar(a, b, c) {\n  return a * b * c;\n}\n\n// Ejemplo de función con parámetros y sin retorno\nfunction imprimirNombre(nombre) {\n  console.log(nombre);\n}\n\n//Ejemplo de función dentro de función\nfunction funcionExterna() {\n  function funcionInterna() {\n    console.log('Función interna');\n  }\n  funcionInterna();\n}\n\n//Ejemplo de función ya creada en el lenguaje\nfunction funcionCreada() {\n  console.log('Función creada');\n}\n\n//Ejemplo de variable global\nvar variableGlobal = 'Variable global';\n\n//Ejemplo de variable local\nfunction funcionLocal() {\n  var variableLocal = 'Variable local';\n  console.log(variableLocal);\n}\n\n//Ejemplo de función que recibe dos parámetros de tipo cadena de texto y retorna un número\nfunction extra(cadena1, cadena2) {\n  for (var i = 1; i <= 100; i++) {\n    if (i % 3 == 0 && i % 5 == 0) {\n      console.log(cadena1 + cadena2);\n    } else if (i % 3 == 0) {\n      console.log(cadena1);\n    } else if (i % 5 == 0) {\n      console.log(cadena2);\n    } else {\n      console.log(i);\n    }\n  }\n  return i;\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/gonzadev28.js",
    "content": "//FUNCIONES \n\n//Funcion sin parametros \nfunction saludar(){\n    console.log('Hola Mouredev');\n}\nsaludar();\n\n//Funcion con 2 parametros sin retorno\nfunction suma(a, b){\n    console.log('El resultado de la suma es:', (a + b));\n}\nsuma(2, 2);\n\n//Funcion con 1 parametro con retorno\nfunction numero(a){\n    return a;\n}\nconsole.log('El numero es:', (numero(28)));\n\n//Funcion dentro de otra funcion \nfunction operacion1(a, b){\n    return function operacion2(c){\n        return a * b - c;\n    }\n}\nconsole.log('El resultado es:', operacion1(5, 2)(2));\n\n//Variable local y global\n\nlet varGlobal = 'Aprendo'; //Variable Global\n\nfunction aprender(){\n    let varLocal = 'Javascript'; //Variable Local\n\n    console.log(varGlobal, varLocal);\n}\naprender();\n\n//console.log(varLocal); No lo imprime por ser solo una variable local\n\nconsole.log('----------Ejercicio Extra------------------');\n// DIFICULTAD EXTRA (opcional):\n//  * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n//  * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n//  *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n//  *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n//  *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n//  *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\nfunction ejercicioExtra(mensaje1, mensaje2){\n    let contador = 0;\n\n        for(let i = 1; i <=100; i++){\n        if(i % 3 == 0 && i % 5 == 0){\n            console.log(mensaje1, mensaje2);\n        }else if (i % 3 == 0){\n            console.log(mensaje1);\n        }else if (i % 5 == 0){\n            console.log(mensaje2);\n        }else\n            console.log(i);\n            contador++;         \n        }\n    return contador;\n}\nconsole.log(ejercicioExtra('Java', 'Script'));\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/gpinedaoviedo.js",
    "content": "//variable global\nvar total;\n\n//variable local\nlet num1, num2;\nnum1 = 8;\nnum2 = 10;\n\n//funcion basica\nconst operation = () => {\n    total = num1 + num2;\n    console.log(total);\n};\noperation();\n\n///////////////////////////\n\n//funcion con parametros y return\nconst operation2 = (suma, division) => {\n    total2 = (suma + total) / division; //uso de var global\n    return total2;\n};\nconsole.log(operation2(20, 2));\n\n///////////////////////////\n\n//funcion dentro de otra funcion\nconst operation3 = () => {\n    const opInFuntion = (num, multip) => {\n        total3 = num * multip;\n        return total3;\n    };\n    console.log(opInFuntion(5,5));\n};\noperation3();\n\n////////////////////////////\n\n//DIFICULTAD EXTRA\nconst operationExtra = (txt1, txt2) => {\n    let count = 0;\n    for (let i = 1; i <= 100; i++) {\n        if (i % 3 === 0 && i % 5 === 0) {\n            console.log(`${txt1} y ${txt2}`);\n        } else if (i % 3 === 0) {\n            console.log(txt1);\n        } else if (i % 5 === 0) {\n            console.log(txt2);\n        } else {\n            console.log(`numero: ${i}`);\n            count++;\n        }\n    }\n    return count;\n};\nconst txt1 = \"multiplo de 3\";\nconst txt2 = \"multiplo de 5\";\nconst result = operationExtra(txt1, txt2);\nconsole.log(`El número de veces que se ha impreso el número es: ${result}`)\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/h4ckxel.js",
    "content": "/* EJERCICIO:\n\n  * Crea ejemplos de funciones básicas que representen las diferentes\n    * posibilidades del lenguaje:\n * Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * Comprueba si puedes crear funciones dentro de funciones.\n * Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * Debes hacer print por consola del resultado de todos los ejemplos.\n * (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n\n*/\n\n// Funciones sin parámetros ni retorno\n\nfunction saludar() {\n    console.log(\"Hola\");\n  }\n  \n  saludar();// se invoca la función\n  \n  // Funciones con parámetros y retorno\n  \n  function sumar(dato1, dato2) {\n    return dato1 + dato2;\n  }\n  \n  console.log(sumar(2, 3)); // se invoca la función y se imprime el resultado\n  \n  // Funciones con parámetros y sin retorno\n  \n  function restar(dato1, dato2) {\n    console.log(dato1 - dato2);\n  } \n  \n  restar(5, 3); // se invoca la función\n  \n  \n  // Funciones con parámetros y retorno\n  \n  function multiplicar(dato1, dato2) {\n    return dato1 * dato2;\n  } \n  \n  console.log(multiplicar(5, 3)); // se invoca la función y se imprime el resultado\n  \n  // Funcion dentro de una función\n  \n  function dividir(dato1, dato2) {\n    function sumar(dato1, dato2) {\n      return dato1 + dato2;\n    }\n    return sumar(dato1, dato2) / 2;\n  }\n  \n  console.log(dividir(10, 2)); // se invoca la función y se imprime el resultado\n  \n  \n  // Funciones ya creadas en el lenguaje\n  \n  // Función parseInt() - Convierte una cadena a un número entero\n  let cadena = \"123\";\n  let numero = parseInt(cadena);\n  console.log(numero);  // Imprime: 123\n  \n  // Función parseFloat() - Convierte una cadena a un número de punto flotante\n  let cadenaFlotante = \"123.45\";\n  let numeroFlotante = parseFloat(cadenaFlotante);\n  console.log(numeroFlotante);  // Imprime: 123.45\n  \n  // Función isNaN() - Comprueba si un valor es NaN\n  let valorInvalido = \"abc\" / 10;  // Esto resultará en NaN\n  console.log(isNaN(valorInvalido));  // Imprime: true\n  \n  // Función Math.random() - Genera un número aleatorio entre 0 (inclusive) y 1 (exclusivo)\n  let aleatorio = Math.random();\n  console.log(aleatorio);\n  \n  // Función Array.isArray() - Comprueba si un valor es un array\n  let array = [1, 2, 3];\n  console.log(Array.isArray(array));  // Imprime: true\n  \n  // Función Date.now() - Devuelve el número de milisegundos transcurridos desde el 1 de enero de 1970 hasta la fecha/hora actual\n  let fecha = Date.now();\n  \n  console.log(fecha);\n  \n  // Crear un nuevo objeto Date que representa la fecha y hora actuales\n  let fecha2 = new Date();\n  \n  // Obtener el día, mes y año\n  let dia = fecha2.getDate();  // Devuelve el día del mes (de 1 a 31)\n  let mes = fecha2.getMonth() + 1;  // Devuelve el mes (de 0 a 11, por eso se suma 1)\n  let año = fecha2.getFullYear();  // Devuelve el año\n  \n  console.log(\"Hoy es \" + dia + \"/\" + mes + \"/\" + año);\n  \n  // Variable local y global\n  \n  let variableGlobal = \"Soy una variable global\";\n  \n  function mostrarVariableGlobal() {\n    console.log(variableGlobal);\n  }\n  \n  mostrarVariableGlobal(); // Imprime: Soy una variable global\n  \n  function mostrarVariableLocal() {\n    let variableLocal = \"Soy una variable local\";\n    console.log(variableLocal);\n  }\n  \n  mostrarVariableLocal(); // Imprime: Soy una variable local\n  \n  // console.log(variableLocal); // Imprime: Uncaught ReferenceError: variableLocal is not defined\n  \n  // Función anónima se usa para asignar una función a una variable o constante\n  \n  let funcionAnonima = function () {\n    console.log(\"Soy una función anónima\");\n  }\n  \n  funcionAnonima(); // Imprime: Soy una función anónima\n  \n  // Función flecha se usa para asignar una función a una variable o constante\n  \n  let funcionFlecha = () => {\n    console.log(\"Soy una función flecha\");\n  }\n  \n  funcionFlecha(); // Imprime: Soy una función flecha\n  \n  let objeto = {\n    valor: 'Hola',\n    funcion: function () {\n      console.log(this.valor); // Imprime: Hola\n    },\n    funcionFlecha: () => {\n      console.log(this.valor); // Imprime: undefined\n    }\n  }\n  objeto.funcion();\n  objeto.funcionFlecha();\n  \n  /*\n  DIFICULTAD EXTRA (opcional):\n    Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n    La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n    Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n    Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n    Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n    La función retorna el número de veces que se ha impreso el número en lugar de los textos \n    Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n    Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n  */\n\nvar writtenNumber = require('written-number'); // Se instala el paquete written-number para convertir números a letras se usa el comando: npm install written-number\n\nfunction imprimirNumeros(cadena1, cadena2) { \ncontador = 0;\nnumeroaletras1 = 0;\nfor (let i = 1; i <= 100; i++) {\n    if (i % 3 == 0 && i % 5 == 0) {\n    numeroaletras1 = i;\n    palabras1 = writtenNumber(numeroaletras1, { lang: 'es' });\n    console.log(palabras1);\n    //console.log(cadena1 + cadena2);\n    } else if (i % 3 == 0) {\n    numeroaletras1 = i;\n    palabras1 = writtenNumber(numeroaletras1, { lang: 'es' });\n    console.log(palabras1);\n    //console.log(cadena1);\n    } else if (i % 5 == 0) {\n    numeroaletras1 = i;\n    palabras1 = writtenNumber(numeroaletras1, { lang: 'es' });\n    console.log(palabras1);\n    //console.log(cadena2);\n    } else {\n    console.log(i);\n    contador++;\n    }\n}\nreturn contador;\n}\nresultado = imprimirNumeros(\"Fizz\", \"Buzz\");\nconsole.log(\"Número de veces que se ha impreso el número en lugar de los textos: \", resultado);\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/hatorob.js",
    "content": "\n//! funciones\n\n//! Funciones de declaracion y alcance global sin retorno\nlet name = \"alejandro\"; //! variable con alcance global\nfunction saludar() {\n    console.log(`Bienvenido, ${name}`);\n}\nsaludar();\n//! con retorno\nfunction isActive() {\n    let userActive = true;\n    return userActive;\n} \n//console.log(userActive); //! not defined ya que userActive es de alcance local\nconsole.log(\"user is active\", isActive());\n\n//! con parametros\nlet user = {\n    firstName: \"Hector Alejandro\",\n    lastName: \"Toro Bernal\",\n    age: 29,\n    hobbies: [\"estudiar\",\"videojuegos\",\"leer\",\"musica\"]\n}\n\nfunction userList(user) {\n    console.log(\"muestro el parametro user\", user);\n}\nuserList(user);\n\n//! funciones de expresión\n/**\n * Otra manera de definir funciones, la cual podemos asignarlas a variables\n */\n\nconst getAgeUser = function(user) {\n    return `La edad del usuario -> ${user.age}`;\n}\nconsole.log(getAgeUser(user));\n\n//! funciones de flecha -> arrow fuction\nconst newUser = (user) => {\n    return user.firstName;\n}\nconsole.log(\"Se crea el nuevo usuario \" + newUser(user));\n\n//! metodos de objetos\nlet userTwo = {\n    firstName: \"Sebastian\",\n    lastName: \"Rodriguez\",\n    age: 29,\n    hobbies: [\"estudiar\",\"videojuegos\",\"leer\",\"musica\"],\n    saludar() {\n        return `Soy el usuario ${this.firstName}`;\n    }\n}\nconsole.log(userTwo.saludar());\n\n//! funciones que crea otra funcion\n\nfunction sum (a) {\n    return (b) => {\n        return a + b;\n    }\n}\n\nconst sumar = sum(2);\nconsole.log(\"suma creada en una funcion que crea otra funcion \",sumar(3));\n\n//! EJERCICIO EXTRA\n\nconst printText = (a,b) => {\n    let i = 1;\n    while( i <= 100 ) {\n        \n        if( i % 3 == 0 ) console.log(a);\n        if( i % 5 == 0 ) console.log(b);\n        if( i % 3 == 0 && i % 5 == 0 ) console.log(`${a} - ${b}`);\n        console.log(i);\n        i++;\n    }\n} \n\nprintText(\"hola\",\"adios\");\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/hectorio23.js",
    "content": "\"use strict\";\n // Variable global\nlet globalVariable = \"Soy global\";\n\n// Función sin parámetros ni retorno\nconst doSomething = () => console.log(\"¡Hola!\");\n\n// Función con un parámetro y retorno\nfunction square(number) {\n    return number * number;\n}\n\n// Función con múltiples parámetros y retorno\nconst  sum = (a, b) =>  a + b;\n\n// Función que retorna una función\nfunction createMultiplier(factor) {\n    return function(number) {\n        return number * factor;\n    };\n}\n\n// Función dentro de otra función\nfunction outerFunction() {\n    let outerVariable = \"Soy local externa\";\n\n    function innerFunction() {\n        let innerVariable = \"Soy local interna\";\n        console.log(innerVariable);\n        console.log(outerVariable); // Puede acceder a la variable local de la función externa\n    }\n\n    innerFunction();\n}\n\n// Ejecutando las funciones\ndoSomething2();\nconsole.log(square(5));\nconsole.log(sum(3, 4));\n\nlet multiplyBy2 = createMultiplier(2);\nconsole.log(multiplyBy2(5));\n\nouterFunction();\n// console.log(innerVariable); // Esto dará un error ya que la variable local de la función interna no está disponible fuera de ella\n\n// Función según tu descripción\nfunction printNumbers(text1, text2) {\n    let count = 0; // Variable local\n\n    for (let i = 1; i <= 100; i++) {\n        let output = \"\";\n\n        if (i % 3 === 0) output += text1;\n\n        if (i % 5 === 0) output += text2;\n\n        if (output) {\n            console.log(output);\n            count++;\n        }\n    }\n\n    return count;\n}\n\nconsole.log(printNumbers(\"Múltiplo de 3\", \"Múltiplo de 5\"));\nconsole.log(`Variable Global: ${ globalVariable }`);\n// console.log(outerVariable); // Esto dará un error ya que la variable local de la función externa no está disponible fuera de ella\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/isaias-alt.js",
    "content": "// Función sin parámetros ni retorno\nfunction greet() {\n  console.log(\"¡Hola!\");\n}\n\n// Función con un parámetro y retorno\nfunction squareOp(num) {\n  return num * num;\n}\n\n// Función con varios parámetros y retorno\nfunction sum(a, b) {\n  return a + b;\n}\n\n// Función dentro de una función\nfunction complexOperation() {\n  function subtractionOp(a, b) {\n    return a - b;\n  }\n  return subtractionOp(10, 5);\n}\n\n// Variable global\nlet globalMessage = \"Hola desde la variable global\";\n\nfunction printGlobalMessage() {\n  console.log(globalMessage);\n}\n\n// Variable local\nfunction imprimirMensajeLocal() {\n  let localMessage = \"Hola desde la variable local\";\n  console.log(localMessage);\n}\n\n// Ejemplos de funciones ya creadas\ngreet();\nconsole.log(squareOp(4));\nconsole.log(sum(2, 3));\nconsole.log(complexOperation());\n\n// Probando variables global y local\nconsole.log(\"Variable global:\");\nprintGlobalMessage();\n\nconsole.log(\"Variable local:\");\nimprimirMensajeLocal();\n\n// Función con parámetros de texto y retorno de número\nfunction printNumbersWithText(text1, text2) {\n  for (let i = 1; i <= 100; i++) {\n    if (i % 3 === 0 && i % 5 === 0) {\n      console.log(text1 + text2);\n    } else if (i % 3 === 0) {\n      console.log(text1);\n    } else if (i % 5 === 0) {\n      console.log(text2);\n    } else {\n      console.log(i);\n    }\n  }\n  return 100; // Retorna el número de veces que se ha impreso el número\n}\n\nconsole.log(printNumbersWithText(\"Fizz\", \"Buzz\"));\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/jacarrillob.js",
    "content": "// Ejemplo de función sin parámetros ni retorno\nfunction handleGreet () {\n  console.log('¡Hola! Bienvenido.')\n}\n\n// Ejemplo de función con un parámetro y sin retorno\nfunction handleShowMessage (message) {\n  console.log(message)\n}\n\n// Ejemplo de función con múltiples parámetros y con retorno\nconst handleSum = (a, b) => {\n  return a + b\n}\n\n// Ejemplo de función dentro de otra función\nfunction handleMathematicalOperations (a, b) {\n  function sum () {\n    return a + b\n  }\n  function subtraction () {\n    return a - b\n  }\n  console.log('Suma:', sum())\n  console.log('Resta:', subtraction())\n}\n\n// Ejemplo de variable global\nlet globalVariable = 'José'\n\nfunction handleGreetGlobally () {\n  console.log('Hola,', globalVariable)\n}\n\n// Ejemplo de variable local\nfunction handleGreetLocally () {\n  let localVariable = 'Pepito'\n  console.log('Hola,', localVariable)\n}\n\n// Ejemplo de función integrada en JavaScript\nlet list = [1, 2, 3, 4, 5]\n\nfunction handlePrintLengthArray () {\n  console.log('Longitud de la lista:', list.length)\n}\n\n// Llamadas a las funciones\nhandleGreet()\nhandleShowMessage('Este es un mensaje de prueba.')\nconsole.log('Resultado de la suma:', handleSum(5, 3))\nhandleMathematicalOperations(10, 5)\nhandleGreetGlobally()\nhandleGreetLocally()\nhandlePrintLengthArray()\n\nconsole.log('\\n ***EXTRA***\\n')\n\nfunction handlePrintNumbersWithText (text1, text2) {\n    let contador = 0;\n\n    for (let i = 1; i <= 100; i++) {\n        if (i % 3 === 0 && i % 5 === 0) {\n            console.log(`${text1} - ${text2}`)\n        } else if (i % 3 === 0) {\n            console.log(text1)\n\n        } else if (i % 5 === 0) {\n            console.log(text2)\n        } else {\n            console.log(i)\n            contador++\n        }\n    }\n\n    return contador\n}\n\nconst timesPrinted = handlePrintNumbersWithText('Uno', 'Dos')\nconsole.log('Número de veces impreso: ', timesPrinted)\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/jaxi86.js",
    "content": "// funciones basicas\n\nfunction recuperar(){\n    console.log('recuperando...');\n};\nrecuperar();\n\nfunction multiplicacion(a, b){\n    return a * b;\n};\nconsole.log(multiplicacion(2, 4));\n\nfunction numero(numero) {\n    console.log(\"cien\" + \" \"  + numero + \"!!\" );\n}\n\nnumero(100);\n \n//Comprueba si puedes crear funciones dentro de funciones.\n\nfunction funcion(){\n    return function(){\n        console.log('Hola mundo');\n    }\n}\n\nlet saludar = funcion();\nsaludar()\n\n//Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n\nfunction obtenerLongitud(palabra) {\n    return palabra.length;\n}\nconsole.log( obtenerLongitud('jaxi'));\n\n\nlet cadenaNumero = \"588\";\nlet numero1 = parseInt(cadenaNumero);//Esta linea convierte la cadena \"123\" a un numero(integer) entero utilizando parseInt.\n\nconsole.log(numero1);\n\n//Pon a prueba el concepto de variable LOCAL y GLOBAL.\n\nlet var_glob = 'esta es una variable global';\nfunction pruebasVariables(){\n    let var_loc ='esta es una variable local';\n    console.log(var_loc);\n    console.log(var_glob);\n}\npruebasVariables();\n\n// console.log(1,var_loc);// esta la tuve que comentar porque me saltaba error porque esta variable solo existe dentro de la funcion\nconsole.log(2,var_glob);\n\n// DIFICULTAD EXTRA (opcional):\n//  * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n//  * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n//  *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n//  *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n//  *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n//  *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\nfunction para( pala1, pala2 ){\n    let numeros = 0;\n    for (let i = 1; i <= 100; i++){\n        if (i % 3 == 0){\n            console.log (pala1);\n        }\n        if (i % 5 == 0){\n            console.log (pala2);\n        }\n        if (i % 3 == 0 && i % 5 ==0){\n            console.log(pala1 + pala2);\n        }if (i % 3 != 0 && i % 5 !=0){\n            numeros++;\n            console.log(i)\n        }\n    }\n    return numeros;\n}\n\nlet resultado = para(\"multiplo3\", \"multiplo5\");\nconsole.log(resultado);\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/jeronimocardu.js",
    "content": "// Funcion vacia\nfunction vacio(){\n    console.log('Hola soy una funcion sin parametros ni retorno');\n}\nvacio()\n\n// Funcion con parametros y return\nfunction completa(a, b){\n    return `Hola soy una function y estoy retornando el parametro A: ${a} y B: ${b}`;\n}\ncompleta()\n\n// funcion dentro de otra funcion\nfunction funcion(){\n    function segundaFuncion(){\n        return 'Se puede crear funciones dentro de funciones';\n    }\n    console.log(segundaFuncion());\n}\nfuncion();\n\n// funcion ya creadas de JS \nfunction isNumber(a){\n    if(!isNaN(a)){\n        console.log('Es un numero!');\n    } else{\n        console.log('No es un numero!');\n    }\n}\nisNumber(2);\n\n// Variables locales y globales\nlet variableGlobal = 'Puedo ser usado de forma global';\nfunction local(){\n    let variableLocal = 'Soy una variable local';\n    console.log(variableGlobal); // Funciona porque es global\n    console.log(variableLocal); // Funciona porque está dentro de la funcion donde fue creada\n}\n// console.log(variableLocal) // No funciona porque es LOCAL\nlocal();\n\n// EXTRA\nfunction extra(str1, str2){\n    let veces = 0;\n    for(let i = 1; i <= 100; i++){\n        if(i%3 === 0 && i%5 === 0){\n            console.log(i, str1,'y', str2);\n            veces += 2;\n        }else if(i%5 === 0){\n            console.log(i, str2);\n            veces++;\n        }else if(i%3 === 0){\n            console.log(i, str1);\n            veces++;\n        } else{\n            console.log(i);\n        }\n    }\n    return veces;\n}\nconsole.log(`Hay ${extra('Multiplo de 3', 'Multiplo de 5')} numeros multiplo de 3 y/o 5`);\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/jesusWay69.js",
    "content": "console.clear()\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n// VARIABLES GLOBALES\nvar acc = 0\nvar operation = ''\nvar globalVariable = \"Soy una variable global\"\nvar string1 = \"Hola\"\nvar string2 = \"Javascript\"\n\n//FUNCIÓN SUMA SIMPLE SIN RETORNO\nfunction sumPrint(a, b) {\n    console.log(`${a} + ${b} = ${a + b} \\n`)\n}\nsumPrint(10, 9)\n\n// FUNCIÓN SUMA SIMPLE CON RETORNO\nfunction sumReturn(a, b) {\n    return `${a} + ${b} = ` + (a + b)\n}\nconsole.log(sumReturn(9, 8), '\\n')\n\n// FUNCIÓN ANÓNIMA DE SUMA SIMPLE  \nlet sumAnonymousFuntcion = function (a, b) {\n    let operation = `${a} + ${b} = `\n    return operation + (a + b)\n}\nconsole.log(sumAnonymousFuntcion(10, 20), '\\n')\n\n//FUNCIÓN FLECHA DE SUMA SIMPLE\nlet sumArrowFuntcion = (a, b) => `${a} + ${b} = ` + (a + b)\nconsole.log(sumArrowFuntcion(50, 50), '\\n')\n\n// FUNCIÓN SUMA CON OPERANDOS VARIABLES POR PROPAGACIÓN CON RETORNO\nfunction sumSpreadingReturn(...numbers) {\n    acc = 0\n    operation = ''\n    for (const [index, number] of numbers.entries()) {\n        acc += number\n        if (index < numbers.length - 1) operation += number + ' + '\n        else operation += number + ' = '\n    }\n    return operation + acc\n}\nconsole.log(sumSpreadingReturn(7, 8, 3, 14, 25), '\\n')\nconsole.log(sumSpreadingReturn(8, 9, 11, 50, 14, 8, 71, 63, 2, 32), '\\n')\n\n// FUNCIÓN SUMA CON OPERANDOS VARIABLES POR PROPAGACIÓN SIN RETORNO\nfunction sumSpreadingPrint(...numbers) {\n    acc = 0\n    operation = ''\n    for (let i = 0; i < numbers.length; i++) {\n        acc += numbers[i]\n        if (i < numbers.length - 1) operation += numbers[i] + ' + '\n        else operation += numbers[i] + ' ='\n    }\n    console.log(operation, acc, '\\n')\n}\nsumSpreadingPrint(8, 7, 1, 16, 52, 9, 13, 4)\nsumSpreadingPrint(5, 1, 7, 0.3, 10, 4)\nsumSpreadingPrint(5, 8, 100, 50)\n\n// FUNCIÓN ANÓNIMA SUMA CON OPERANDOS VARIABLES POR PROPAGACIÓN CON RETORNO\nconst anonymousFunction = function (...numbers) {\n    acc = 0\n    operation = ''\n    for (const [index, number] of numbers.entries()) {\n        acc += number\n        if (index < numbers.length - 1) {\n            operation += number + ' + '\n        } else {\n            operation += number + ' = '\n        }\n\n    }\n    return operation + acc\n}\nconsole.log(anonymousFunction(4, 48, 7, 9, -10, 2, 1, 20), '\\n')\nconsole.log(anonymousFunction(3.56, 4.88, 9.48, 1.22, 5.71, 3.24, 6.91), '\\n')\n\n// FUNCIÓN FLECHA SUMA CON OPERANDOS VARIABLES POR PROPAGACIÓN CON RETORNO\nconst anonymousArrowFunction = (...numbers) => {\n    acc = 0\n    operation = ''\n    for (const [index, number] of numbers.entries()) {\n        acc += number\n        if (index < numbers.length - 1) {\n            operation += number + ' + '\n        } else {\n            operation += number + ' = '\n        }\n\n    }\n    return operation + acc\n}\nconsole.log(anonymousArrowFunction(1, 7, 8), '\\n')\nconsole.log(anonymousArrowFunction(47, 72, 98), '\\n')\n\n// FUNCIÓN QUE IMPRIME UNA VARIABLE LOCAL DECLARADA DENTRO Y OTRA GLOBAL DECLARADA FUERA\nlet printVariables = function () {\n    let localVariable = \"Soy una variable local\"\n    console.log(localVariable)\n    console.log(globalVariable)\n}\nprintVariables()\n\n// FUNCIÓN ANÓNIMA QUE SE LE PASA COMO ARGUMENTO A UNA FUNCIÓN DE ORDEN SUPERIOR SOBRE UN LISTADO\n// Y DEVUELVE OTRO LISTADO CON LOS NÚMEROS TRANSFORMADOS EN BASE 2 USANDO LOS ORIGINALES COMO EXPONENTES\nconst simpleNumbers = [0, 1, 2, 3, 4, 5, 6, 7]\nconst base2Value = simpleNumbers.map(function (num) {\n    return 2 ** num\n})\nconsole.log('\\n', base2Value, '\\n')\n\n// FUNCIÓN FLECHA QUE RECIBE UN NÚMERO Y UTILIZA INTERNAMENTE LA FUNCIÓN ANTERIOR PARA\n// DEVOLVER EL NÚMERO BINARIO DEL NÚMERO RECIBIDO\nlet decToBin = (num) => {\n    bin = ''\n    for (let i = base2Value.length - 1; i >= 0; i--) {\n        if (num < base2Value[i]) {\n            bin += 0 + ' '\n        } else {\n            bin += 1 + ' '\n            num -= base2Value[i]\n        }\n    }\n    return bin\n}\nconsole.log(decToBin(100), '\\n')\n\n/*\n* DIFICULTAD EXTRA (opcional):\n* Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n* - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n*   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n*   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n*   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n*   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n*/\n\nfunction numbers(str1, str2) {\n    let counter = 0\n    for (let i = 1; i <= 100; i++) {\n        if (i % 3 == 0 && i % 5 == 0) console.log(str1, str2);\n        else if (i % 3 == 0) console.log(str1);\n        else if (i % 5 == 0) console.log(str2);\n        else {\n            console.log(i)\n            counter++\n        }\n    }\n    console.log(`\\nLos números se han impreso ${counter} veces \\n`)\n}\nnumbers(string1, string2)"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/jhoshmc.js",
    "content": "//* función sin paramatros ni retorno\nlet saludo = () => {\n  console.log(\"hola a todos \");\n};\n\n//* función con parametros\n\nlet multiplicacion = (num_1, num_2) => {\n  console.log(\"multiplicacion: \" + num_1 * num_2);\n};\n\n//* funcion con retorno\n\nlet suma = (num_1, num_2) => {\n  return num_1 + num_2;\n};\n\n//* funcion dentro de otra\nfunction ingresar(numero) {\n  let divicion = () => {\n    return numero / 3;\n  };\n  return divicion();\n}\n// variable global\nlet variable_global = \"hola, soy global\";\n\nlet variable = () => {\n  let variable_local = \"hola, soy local\";\n  console.log(variable_local);\n  console.log(variable_global);\n};\n\n// ejercicio extra\n\nfunction extra(biz, buzz) {\n  let contador = 0;\n  for (let i = 1; i <= 100; i++) {\n    if (i % 15 == 0) {\n      console.log(biz + buzz);\n    } else if (i % 5 == 0) {\n      console.log(buzz);\n    } else if (i % 3 == 0) {\n      console.log(biz);\n    } else {\n      contador++;\n    }\n  }\n  return contador;\n}\n//* llamado a las funciones\nsaludo();\nmultiplicacion(5, 6);\nconsole.log(\"suma: \" + suma(5, 8));\nconsole.log(ingresar(6));\nvariable();\nlet contador = extra(\"biz\", \"buzz\");\nconsole.log(\"el numero que no se imprimio un texto es: \" + contador);\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/joapalobael.js",
    "content": "//---------------------------------------- > \nfunction funcion_simple() {\n    let varLocal = \"función simple\"\n    console.log(`Esto es una ${varLocal} y sin parámetro utilizando una variable local`);\n}\nfuncion_simple();\n//---------------------------------------->\nfunction funcion_simpleParametro(a, b) {\n    return a + b;\n}\nconsole.log(`Esto es una función simple, con parámetro y retorno: ${funcion_simpleParametro(3, 4)}.`);\n//---------------------------------------->\nlet funcion_flecha = () => console.log(\"Esto es una función flecha simple\");\nfuncion_flecha();\n//---------------------------------------->\nlet funcion_flechaParametro = (cant) => console.log(`Esto es una función flecha con parámetro: ${cant}.`)\nfuncion_flechaParametro(3);\n//---------------------------------------->\nconst nombreCriatura = \"Roberto\"\nfunction vivir() {\n    let llamar = () => console.log(`Hola, me llamo ${nombreCriatura} y soy una función dentro de una función con variable global.`)\n    let respirar = () => console.log(\"Respiro\");\n    let alimentar = () => console.log(\"Me alimento\");\n    let morir = () => console.log(\"Muero\")\n    return llamar(), respirar(), alimentar(), morir();\n}\nvivir();\n//---------------------------------------->\nconsole.log(\"Soy una función propia del lenguaje // Built-in\")\nconsole.log((\"Soy la función lenght // Built-in\").length);\n//---------------------------------------->\n// ABSTRACCIÓN EJERCICIO EXTRA\n/* Inicio\n        Crear una función ejercicioExtra que reciba 2 parámetros (a,b) {\n            setear contador en 0\n            Crear un bucle contador que vaya del 1 al 100 teniendo en cuenta que{\n                SI (el número es multiplo de 3 Y de 5){\n                muestre el texto a concatenado con el b}\n                SI (el número del contador es multiplo de 3) {\n                muestre el parametro a}\n                SI (el número del contador es multiplo de 5) {\n                muestre el parametro b}\n                ELSE {\n                Mostrar por consola el index\n                Incrementar el contador\n                }\n            }\n        Retornar el contador\n        }\n\n        Mostrar por consola el retorno de la función => console.log(ejercicioExtra(fizz, buzz));\nFin */\n\nfunction ejercicioExtra(a, b) {\n    let counter = 0;\n    for (let i = 1; i <= 100; i++) {\n        if (i % 3 === 0 && i % 5 === 0) {\n            console.log(`${a} ${b}`)\n        } else if (i % 3 === 0) {\n            console.log(a)\n        } else if (i % 5 === 0) {\n            console.log(b)\n        } else {\n            console.log(i);\n            counter++;\n        }\n    }\n    console.log(`Se mostraron números ${counter} veces`);\n    // Si no pongo retorno, da indefinida la función\n    return counter;\n}\nejercicioExtra('Fizz', 'Buzz');"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/joshbaez.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n// funcion sin parametros ni retorno \n\nfunction saludar() {\n    console.log(\"hola mundo\"); // hola mundo \n\n}\n\nsaludar(); // llamada a la funcion\n\n// funcion con un parametro y sin retorno \n\nfunction saludo(name) {\n     console.log(\"hola, \" + name + \"!\");  // hola, josh!\n\n} \n\nsaludo(\"johs\"); // llamada a la funcion con un argumento \n \n// funciones con varios parametros y sin retorno\n\nfunction addAndPrint(a, b) {\n    const sum = a + b;\n    console.log(\"sum: \" + sum); // sum: 8\n}\n\naddAndPrint(5, 3); // llamada a la funcion con dos argumentos\n\n// funcion con un parametro y con retorno \n\nfunction cuadrado(numero) {\n    return numero * numero;\n\n} \nconst resultado = cuadrado(4); // Llamada a la función y almacenando el valor de retorno\nconsole.log(resultado); // imprime 16\n\n// funcion con varios parametros y con retorno \n// esta funcion acepta varios parametros y devuelve un valor basado en esos parametros \n\nfunction multiply(a, b) {\n    return a * b; \n\n    \n}\n\nconst producto = multiply(6, 7);\nconsole.log(producto); // imprime 42\n\n// funcion anonima asignada a una variable \n// Una función anónima es una función sin nombre que se puede asignar a una variable\n\nconst greet = function (name) {\n    return \"hola, \" + name + \"!\"\n\n};\n\nconsole.log(greet(\"josh\")); // Llamada a la función anónima asignada a una variable \n\n// funcion de flecha (arrow function)\n// Las funciones de flecha son una sintaxis más corta para escribir funciones anónimas.\n\nconst llamada = (apoodo) => {\n    return \"hello, \" + apoodo + \"!\";\n\n}; \n\nconsole.log(llamada(\"pepe\")); // llamada a la fuction de flecha \n\n// Si la función de flecha tiene una sola expresión, se puede omitir el bloque {} y el return:\\\n\nconst llama = apodo1 => \"hola, \" + apodo1 + \"!\";\n\nconsole.log(llama(\"joshua\")); // llama a la funcion de flecha simplificada \n\n// funcion con valor por defecto en los parametros \n\nfunction saludar2(name2 = \"persona\") {\n    console.log(\"hola, \" + name2 + \"!\");\n}\n\nsaludar2(); // Llamada sin argumentos, utiliza el valor por defecto\nsaludar2(\"josue\") // Llamada con un argumento\n\n// funcion que utiliza el operador rest ...\n// El operador Rest permite a una función aceptar un número indefinido de argumentos como un array.\n\nfunction sum(...numbers) {\n    return numbers.reduce((total, number) => total + number, 0);\n\n}\n\nconsole.log(sum(1, 2, 3)); // imprime: 6\nconsole.log(sum(4, 5, 6, 7)); // imprime: 22\n\n// function con manejo de exepciones (try-catch)\n// Una función puede incluir manejo de excepciones para gestionar errores.\n\nfunction divide(a, b) {\n    try {\n        if (b === 0) {\n            throw new Error(\"division by zero\");\n        }\n        return a / b;\n    } catch (error) {\n        console.log(error.message);\n        return null;\n    }\n}\n\nconsole.log(divide(10, 2)); // imprime: 5\nconsole.log(divide(10, 0)); // imprime: division by zero y retorna null \n\n// DIFICULTA EXTRA \n\nfunction imprimirNumerosEspeciales(STR1, STR2) {\n    let contador = 0;\n\n    for (let i = 1; i <= 100; i++) {\n        if (i % 3 === 0 && i % 5 === 0) {\n            console.log(STR1 + STR2);\n        } else if (i % 3 === 0) {\n            console.log(STR1);\n        } else if (i % 5 === 0) {\n            console.log(STR2);\n        } else {\n            console.log(i);\n            contador++;\n        }\n    }\n\n    return contador;\n}\n\n// Ejemplo de uso\nconst STR1 = \"Fizz\";\nconst STR2 = \"Buzz\";\nconst result = imprimirNumerosEspeciales(STR1, STR2);\nconsole.log(\"Número de veces que se ha impreso un número en lugar de los textos:\", resultado);"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/juandaherrera.js",
    "content": "/*\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n *\n*/\n\nfunction myFunction(text1, text2) {\n    let counter = 0;\n    for (let number = 1; number <= 100; number++) {\n        if (number % 3 === 0 && number % 5 === 0) {\n            console.log(text1 + text2);\n        } else if (number % 3 === 0) {\n            console.log(text1);\n        } else if (number % 5 === 0) {\n            console.log(text2);\n        } else {\n            console.log(number);\n            counter++;\n        }\n    }\n    return counter;\n}\n\n// Ejemplo de uso:\nconst myVar = myFunction(\"Hola\", \"Mundo\");\nconsole.log(\"----------------------------\");\nconsole.log(myVar);\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/julianbuitragocharry-dev.js",
    "content": "// 👾 SCOPE\n// Variable global\nlet variableGlobal = 'Soy global';\n\nfunction ejemploVariables() {\n    // Variable local dentro de la función\n    let variableLocal = 'Soy local';\n\n    console.log('Dentro de la función:');\n    console.log('Variable local:', variableLocal);  // Accesible dentro de la función\n    console.log('Variable global:', variableGlobal);  // Accesible dentro de la función\n\n    // Modificando la variable local\n    variableLocal = 'Modificada localmente';\n\n    console.log('Después de modificar la variable local:');\n    console.log('Variable local:', variableLocal);  // Accesible dentro de la función\n    console.log('Variable global:', variableGlobal);  // Accesible dentro de la función\n}\nejemploVariables();\n\nconsole.log('Fuera de la función:');\n// console.log('Variable local:', variableLocal); // Esto dará un error, ya que la variable local no es accesible fuera de la función\nconsole.log('Variable global:', variableGlobal); // Accesible fuera de la función\n\n// 👽 FUNCTIONS\n// Las funciones en JavaScript pueden clasificarse de varias maneras según su comportamiento y uso.\n// Funciones Declarativas\nfunction declarativeSum(a, b) {\n    return a + b;\n}\nconsole.log(`Función Declarativa: ${declarativeSum(5, 7)}`)\n\n// Funciones de Expresión (anónimas)\nconst sum = function(a, b) {\n    return a + b;\n}\nconsole.log(`Función Anonima/Expresión: ${sum(3, 4)}`)\n\n// Funciones Flecha\nconst sumArrowFunction = (a, b) => {\n    return a + b;\n}\nconsole.log(`Función Flecha(Arrow function): ${sumArrowFunction(2, 10)}`)\n\n// Funciones Constructoras\nfunction Persona(nombreCompleto, edad, trabajo, pais) {\n    this.nombreCompleto = nombreCompleto;\n    this.edad = edad;\n    this.trabajo = trabajo;\n    this.pais = pais;\n}\n\nconst primeraPersona = new Persona('Julian Enrique Buitrago Charry', 17, 'Futuro Desarrollador de Software', 'Colombia');\nconsole.log(`Función Constructora: ${primeraPersona}`);\n\n// Funciones de Orden Superior: Aceptan funciones como argumentos o devuelven funciones. Ejemplos incluyen map, filter, reduce.\n\n// Funciones Recursivas\nfunction factorial(n) {\n    // Caso base\n    if (n === 0 || n === 1) {\n        return 1;\n    } else {\n        // Llamada recursiva\n        return n * factorial(n - 1);\n    }\n}\nconsole.log(`Función Recursiva Factorial: ${factorial(6)}`);\n\n// Funciones Anidadas\nfunction exterior() { \n    let variableExterior = 'Exterior'; \n    function interior() {\n        console.log(`Función Anidada Variable Exterior: ${variableExterior}`); \n    } \n    interior(); \n} \nexterior();\n\n// Métodos de Objeto\nconst objeto = {\n    metodo: () => {\n        return 'Hola, este es un método';\n    }\n}\nconsole.log(`Metodo de un Objeto: ${objeto.metodo()}`);\n\n/* 👀 DIFICULTAD EXTRA (opcional):\nCrea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n- La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n- Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n- Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n- Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n- La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n- Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n- Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n*/\n\nconst retoSemanal = (primerParametro, segundoParametro) => {\n    let contador = 0;\n    for (let number = 1; number <= 100; number++) {\n        if (number % 3 == 0 && number % 5 == 0) {\n            console.log(`${primerParametro} en ${segundoParametro}.`)\n            continue;\n        } else if (number % 3 == 0) {\n            console.log(`${primerParametro} Developer.`);\n            continue;\n        } else if (number % 5 == 0){\n            console.log(`${segundoParametro}.`);\n            continue;\n        } else {\n            contador++;\n            console.log(number);\n        }\n    } \n    return contador;  \n}\n\nconst primerTexto = 'Es divertido programar';\nconst segundoTexto = 'JavaScript';\n\ncantidadNumeros = retoSemanal(primerTexto, segundoTexto);\nconsole.log(`Cantidad de veces que se ha impreso un número en vez de los textos: ${cantidadNumeros}`);"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/k3nvd.js",
    "content": "//F U N C T I O N S\n\n//Basic Function            'Function to add two numbers'\n\nlet varInitial = 3;                 //we declared a var Inital\n\nfunction addNumbers(){              \n    varInitial += 7;\n    // varInitial = varInitial + 7;         //Another way to do that                \n    console.log(varInitial);\n}\n\naddNumbers();           //10                          //we call the function\naddNumbers();           //17                          //we call the function\naddNumbers();           //24                          //we call the function\n\n\n//With 'retunr' and 'Parameters and arguments'\n\nfunction add2numbers (a,b){\n    console.log(a + b);\n    return add2numbers;\n}\n\nrer = add2numbers(1,4);         //5\nrer = add2numbers(1,7);         //8\nrer = add2numbers(1,5);         //6\n\n//Add differents arguments\n\nfunction manyArguments(){\n    let valueInitial = 0;\n    for (let eachValue of arguments){\n        valueInitial += eachValue;\n        // console.log(addOfArguments); \n    }\n    return valueInitial;\n}\nconsole.log(manyArguments(1,2,3));\n\n\n\n//Declarate a function and function expretion;\n\n//when we declarate a function\n\nfunction declarateFunction(){\n    console.log('This is a declaration');\n}\n\nlet varDeclaration = function(){\n    console.log('This is Expretion');\n}\n\ndeclarateFunction();            //This is a declaration\nvarDeclaration();              //Thus is a Expretion\n\n\n//FUNCTIONS USING 'RETURN'\n\n\nlet user1 = {\n    name: 'Ana',\n    age: 22,\n    city:'Mexico City',\n    phone:5512123434\n};\n\n// function changeMyage(objectt){\n//     objectt.age = 23;                   //With this, I change the original object\n// }\n// changeMyage(user1);\n// console.log(user1);    \n\n//This is object copy, so the original object not change\n\nfunction changeMyage(objectt){\n    let copyy = JSON.parse(JSON.stringify(objectt));         //This is doing a copy\n    copyy.age = 23; \n    return copyy;                  \n}\nconsole.log(user1);                         //print the orignal object\n\nconsole.log(changeMyage(user1));            //Print the copy object\n\n//METHODS IN A FUNCTION\n\nlet newObjt = {\n    favoritecolor:'Blue',\n    favoriteCity:'Mexico',\n    favariteFood: 'Pizza',\n    hobby:function(){\n        console.log('I like to play videogames');\n    }\n};\n\nnewObjt.hobby();                            //It is show 'I like to play videogames'\n\n\n//SCOOP\n\n\nvar var1 = 10;                      //global scoope\n\nfunction inside(){\n    // var var1 = 20;                  //local scoope\n\n    //now, if we delete the 'var' in our local variable\n    var1 = 20;    // this would change the gloabal var 'var var1 = 10'\n\n    console.log(var1);\n}   \n\n//When we put var, this means that is a new declaration. That's why that variable changes\n\ninside();                           //20\nconsole.log(var1);                  //10\nconsole.log(var1);                  //20    This is wiith de local variable without 'var'\n\n\n//var works in the scoop of the function\n//let workd in the scoop of the block, for example  let xVariable={         }\n\n//CALLBACK\n\nfunction sayHiAfterTwoSeconds(){\n    console.log('Hi');\n\n}\nsetTimeout(sayHiAfterTwoSeconds,2000); \nconsole.log('This well print Immediately');   \n\n//another way\n\nfunction llamar(callbackk){\n    callbackk();\n}\n\nllamar(function(){console.log(3); });\n\n//ANOTHER WAY \n\n\nfunction varification(t, f){\n        //####t or f\n    let validation = true;\n\n    if (validation){\n        t();\n    }else {\n        f();\n    }\n\n}\nvarification(\n    () => console.log('Welcome'),\n    () => console.log('Error')\n)\n\n/*\nfunction t(){\n    console.log('Welcome');\n}\nfunction f(){\n    console.log('Sorry, Could there an Error');\n}\n\n\nvarification(t,f);\n*/\n//CHALLENGE         \n\nlet adder = 1;\nfunction soap(txt11,txt22){\n    console.log(txt11 + txt22);\n\n    while (adder<=99){\n        // console.log(adder);\n        adder+=1;\n\n        if (adder %3 ==0 && adder %5 ==0){//\n            console.log(txt11 +' '+ txt22);\n\n        }else if(adder %5 ==0){\n            console.log(txt22);\n           \n\n        }else if (adder %3 ==0){\n            console.log(txt11);\n        \n\n        }else {\n            console.log(adder);\n        }\n    }\n\n    \n\n}\nsoap('Hello','World');\n\n  \n\n\n  \n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/kaesar84.js",
    "content": "/*\n# #02 FUNCIONES Y ALCANCE\n> #### Dificultad: Fácil | Publicación: 08/01/24 | Corrección: 15/01/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n \n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.*/\n\n// Funciones sin retorno y sin parámetros\nconst helloWorld = () => console.log(`>>> hello world`)\nhelloWorld()\n\n// Funciones sin retorno y con parámetros\nconst helloWorldTwo = (alias) => console.log(`>>> hello world ${alias}`)\nhelloWorldTwo(\"Spiderman\")\n\n// Funciones con retorno y parámetros\nconst ciaoWorld = () => `>>> ciao world`\nlet resultCiao = ciaoWorld()\nconsole.log(resultCiao)\n\n// Funciones con retorno y parámetros\nconst ciaoWorldTwo = (alias) => `>>> ciao world ${alias}`\nlet resultCiaoTwo = ciaoWorldTwo(\"Iron Man\")\nconsole.log(resultCiaoTwo)\n\n// Funciones dentro de funciones\nfunction checkPositive(num) {\n  function validate(num) {\n    let check = num > 0 ? true : false\n    return check\n  }\n\n  let resultValidate = validate(num)\n    ? `>> Número positivo`\n    : `>> Número negativo o 0`\n  return resultValidate\n}\n\nconsole.log(checkPositive(-5))\n\n// Uso de una función del lenguaje ya existente\nlet texto = \"JavaScript\"\nconsole.log(\">>> Texto en mayúsculas:\", texto.toUpperCase())\n\n// Ámbito variables globales- locales\nlet global = \">> Soy una variable GLOBAL\"\n\nfunction checkAccesVar() {\n  console.log(\"==================\")\n  console.log(\"Invocación desde función\")\n  let local = `>> Soy una variable LOCAL`\n  console.log(local)\n  console.log(global)\n  console.log(\"==================\")\n}\n\ncheckAccesVar()\n\ntry {\n  console.log(local)\n} catch (e) {\n  console.log(\n    \"!!! Error variable local inaccesible fuera de la función\\n\",\n    e.message\n  )\n}\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n * */\n\nfunction checkMultiple(string1, string2) {\n    let counter=0\n      for (let i = 1; i <= 100; i++) {\n        if (i % 3 == 0 && i % 5 == 0) {\n          console.log(`${string1} y ${string2}`)\n        } else if (i % 3 == 0) {\n          console.log(string1)\n        } else if (i % 5 == 0) {\n          console.log(`${string2}`)\n        } else {\n          console.log(i)\n          counter++\n        }\n      }\n    console.log(`Números impresos: ${counter}`)\n    }\n    \n    let stringOne = `Soy múltiple de 3`\n    let stringTwo = `Soy múltiple de 5`\n    \n    checkMultiple(stringOne, stringTwo)"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n_______________________________________\n02 FUNCIONES Y ALCANCE\n---------------------------------------\n* - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n*/\n\n// ________________________\n// Funciones\n// https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Functions\n\n// Función Básica\nfunction aMessage() {\n    console.log(\"Texto\");\n}\n\naMessage(); // Llamar\n\n// Función con Parámetro\nfunction displayMessage(msgText) {\n    console.log(msgText);\n}\n\ndisplayMessage(\"¡Hola mundo!\");\n\n// Función con Parámetros Opcionales\nfunction sumNums(a, b=5) {\n    console.log(a + b)\n}\n\nsumNums(2)\nsumNums(2, 2)\n\n// ________________________\n// Función con retorno\n// https://developer.mozilla.org/es/docs/Learn/JavaScript/Building_blocks/Return_values\n\nfunction squared(num) {\n    return num * num;\n}\n\nlet result = squared(4);\nconsole.log(result); // 16\n\n// Retorna múltiples datos\nfunction calculateRectangleProperties(width, height) {\n    return {\n      area: width * height,\n      perimeter: 2 * (width + height)\n    };\n}\n\nconst rectangle = calculateRectangleProperties(5, 10);\nconsole.log(`Área: ${rectangle.area}`);           // Área: 50\nconsole.log(`Perímetro: ${rectangle.perimeter}`); // Perímetro: 30\n\n// ________________________\n// Funciones anidadas\nfunction sumOfSquares(a, b) {\n    function square(x) {\n      return x * x;\n    }\n    return square(a) + square(b);\n}\n  \n  console.log(sumOfSquares(2, 3)); // 13\n\n// ________________________\n// ejmp de funcion incorporada\nconst maxNumber = Math.max(10, 20, 5, 30);\nconsole.log(maxNumber); // 30\n\n/* \nEJERCICIO:\n* Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n*/\n\nfunction exs(str1, str2) {\n    nPrintsNums = 0;\n\n    for (let num = 1; num <= 100; num++) {\n        if (num % 3 === 0 && num % 5 === 0) {\n            console.log(str1 + str2);\n        } else if (num % 3 === 0) {\n            console.log(str1);\n        } else if (num % 5 === 0) {\n            console.log(str2);\n        } else {\n            nPrintsNums += 1;\n            console.log(num);\n        }\n    }\n    return nPrintsNums;\n}\n\npNums = exs(\" múltiplo de 3\", \" múltiplo de 5\")\nconsole.log(\"Número de veces que se imprimió un número: \" + pNums);\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/kodenook.js",
    "content": "\nfunction name() {\n    console.log('kodenook')\n}\n\nname()\n\nfunction fullName({ fname = 'my', lname = 'name' }) {\n    console.log(`${fname} ${lname}`)\n}\n\nfullName({ lname: 'lname' })\n\nfunction addition(...nums) {\n    let result = 0\n\n    nums.forEach(num => {\n        result += num\n    });\n\n    return result\n}\n\nconsole.log(addition(1, 1, 3.2, -2.5))\n\nfunction first() {\n    console.log('first')\n\n    function second() {\n        console.log('second')\n    }\n\n    second()\n}\n\nfirst()\n\nlet global = 'global'\n\nfunction scope() {\n    console.log(global)\n    let local = 'local'\n}\n\nscope()\n\n/*\n    Exercise\n*/\n\nfunction exercise(word1, word2) {\n    let result = 0\n\n    for (x of Array(101).keys()) {\n        if (x % 3 == 0 && x % 5 == 0) {\n            console.log(`${word1} ${word2}`)\n        } else if (x % 3 == 0) {\n            console.log(word1)\n        } else if (x % 5 == 0) {\n            console.log(word2)\n        } else {\n            result++\n        }\n    }\n\n    return result\n}\n\nconsole.log(`number of times it was a number and not words: ${exercise('hello', 'javascript')}`)"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/legs30011.js",
    "content": "//funciones basicas\n//una funcion es un bloque de codigo para reutilizar algun accion \n//def por el usuario\n\n//simple\nfunction greet(){\n    console.log(\"hola javascipt\")\n}\ngreet();\n// Funcion sin parametro ni retorno\nfunction saludar() {\n    console.log(\"Hola, Javascript!\")\n}\n\nsaludar();\n\n// Funcion con un parametro y sin retorno\n\nfunction saludo(nombre){\n    console.log(`hola, ${nombre} bienvenido`)\n}\nsaludo(\"quique\")\n\nfunction ejemplo(nombre){\n    console.log(`hola, ${nombre} bienvenido`)\n}\nejemplo();\n\n\n// Funcion con varios parametros y con retorno\nfunction sumar(a, b) {\n    return a + b;\n}\n\nlet resultado = sumar(5, 10);\nconsole.log(\"El resultado es:\", resultado);\n\n//Funcion con varios parametros\nfunction variosParametros(...args){\n    for(let i = 0; i<args.length;i++){\n        console.log(args[i])\n    }\n}\n\n//ejercicio con varios parametros \nfunction varpar(...args){\n    for(i=0;i<args.length;i++){\n        console.log(args[i])\n    }\n}\nvariosParametros(1, 2, 3, 4)\nvarpar(2,3,4,5);\n\n//Funciones anidadas\nfunction funcionUno(){\n    console.log(\"Hola desde funcionUno\");\n\n    function funcionDos(){\n        console.log(\"Hola desde funcionDos\")\n    }\n\n    funcionDos(); //Estamos llamando la funcion dos dentro de funcionUno por lo que si funciona\n}\nfuncionUno();\n\n//dificultad extra\n\nfunction padre(a, b) {\n    let contador = 0;\n    for (let i = 1; i <= 100; i++) {\n        if (i % 3 === 0 && i % 5 === 0) {\n            console.log(`${a}, ${b}`);\n        } else if (i % 3 === 0) {\n            console.log(a);\n        } else if (i % 5 === 0) {\n            console.log(b);\n        } else {\n            console.log(i);\n            contador++;\n        }\n    }\n    console.log(\"Numeros en lugar de texto :\");\n    return contador;\n}\n\nconsole.log(padre('fizz', 'buzz'));\n//par o impar\nfunction test(a, b) {\n    let contador = 0;\n    for (let i = 1; i <= 100; i++) {\n        if (i % 2 === 0) {\n            console.log(a);\n            contador++;\n        } else {\n            console.log(b);\n        }\n    }\n    console.log(\"Número de veces que se imprimió 'a':\", contador);\n    return contador;\n}\n\nconsole.log(test('papu', 'tefy'));\n//compuesto o primo\nfunction esPrimo(num){\n    if(num <= 1)return false;\n    for(let i=2;i<=Math.sqrt(num);i++){\n        if(num % i === 0)return false;\n    }\n    return false;\n}\n\nfunction test2(a,b){\n    let contador = 0;\n    for(let i=1;i<=100;i++){\n        if (esPrimo(i)) {\n            console.log(a);\n        } else {\n            console.log(b);\n            contador++;\n        }\n    }\n    return contador;\n}\n// Llamada a la función con ejemplos de cadenas\nlet contador = test2('Primo', 'Compuesto');\nconsole.log('Número de veces que se imprimió compuesto:', contador);"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/levsistemas.js",
    "content": "/*# #02 FUNCIONES Y ALCANCE\n> #### Dificultad: Fácil | Publicación: 08/01/24 | Corrección: 15/01/24\n\n## Ejercicio\n\n```\n\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n//FUNCIONES\n\nfunction helloWorld () {\n    console.log(\"Hello World\")\n}\n\nfunction helloWorld1 (name) {\n    console.log(\"Hello World, \" + name)\n}\nfunction helloWorld2 (name, age) {\n    return \"Hello World, \" + name + ' ' + age\n}\n\nfunction helloWorld3 (name) {\n    return \"Hello World, \" + name\n}\n\nfunction helloWorld4 () {\n    function hellowWorldChildren() {\n        console.log(\"Llamando a la función anidada\")\n    }\n    hellowWorldChildren()\n}\n\nhelloWorld()\nhelloWorld1('SlipKnot')\nhelloWorld2('SlipKnot', 38)\nconsole.log(helloWorld3('Return of SlipKnot'))\nhelloWorld4()\n\n//FUNCIONES YA CREADAS\n\nconsole.log(Date().slice(0, Date().indexOf('GMT')) + \"hs\")\nconsole.log(helloWorld2('Leandro'.toUpperCase(), 38))\nconsole.log(helloWorld3('Return of SlipKnot').toLowerCase())\n\n//VARIABLE GLOBAL Y LOCAL\n\nlet global = \"Hola Mundo\"\n\nfunction hW(){\n    let saludo = \"Hola Mundo desde función\"\n    return saludo\n}\n\nconsole.log(global)\nconsole.log(hW())\n\nfunction option(string1, string2) {\n    console.log(\"Bienvenida palabra: \" + string1 + \" y palabra: \" + string2)\n    let number = 0\n    for (i=1; i<=100; i++) {\n\n        if(i % 3 == 0) {\n            console.log('string n° 1')\n            number++\n        }\n\n        if (i % 5 == 0) {\n            console.log('string n° 2')\n            number++\n        }\n\n        if(i % 3 == 0 && i % 5 == 0) {\n            console.log('string n° 1' + 'string n° 2')\n        }\n    }\n    return number\n}\n\nconsole.log(option('palabra1', 'palabra2'))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/lrpeset.js",
    "content": "//  Basic functions\n//  No parameter, no return\nfunction noParameterFunction() {\n  console.log(\"Hello world!\");\n}\nnoParameterFunction();\n\n//  One parameter, no return\nfunction oneParameterFunction(displays) {\n  console.log(\"I have\", displays, \"displays in my computer\");\n}\noneParameterFunction(2);\n\n//  Two parameters, no return\nfunction twoParametersFunction(a, b) {\n  console.log(\"The area of the rectangle is:\", a * b);\n}\ntwoParametersFunction(5, 10);\n\n//  No parameter with return\nfunction noParameterReturnFunction() {\n  return Math.random();\n}\nlet randomNumber = noParameterReturnFunction();\nconsole.log(\"The random number is: \", randomNumber);\n\n//  One parameter with return\nfunction oneParameterReturnFunction(number) {\n  return number * 2;\n}\nlet doubleNumber = oneParameterReturnFunction(10);\nconsole.log(\"The double of this number is:\", doubleNumber);\n\n//  Two parameters with return\nfunction twoParametersReturnFunction(base, height) {\n  return (base * height) / 2;\n}\nconsole.log(\"The area of the triangle is:\" + twoParametersReturnFunction(4, 5));\n\n//  Function as expression\nlet multiply = function (a, b) {\n  return a * b;\n};\nconsole.log(\"The multiplication result is\", multiply(1, 3));\n\n// Arrow function\nlet square = (n) => n * n;\nconsole.log(\"The square of the number is\", square(3));\n\n//  Function with default parameters\nfunction greet(name, salute = \"Hello!\") {\n  console.log(salute + \" \" + name);\n}\ngreet(\"Mark\");\ngreet(\"Jim\", \"Good morning\");\n\n//  Function with rest parameters\nfunction sumAll(...allNumbers) {\n  return allNumbers.reduce((acc, num) => acc + num, 0);\n}\nconsole.log(\"The sum of all numbers is:\", sumAll(5, 3, 10, 2));\n\n//  Function within function\nfunction squareSum(a, b) {\n  function square(x) {\n    return x * x;\n  }\n  return square(a) + square(b);\n}\nconsole.log(\"The sum of both squares is:\", squareSum(2, 4));\n\n//  Function within native functions\nfunction processText(text) {\n  function countWords(str) {\n    return str.split(\" \").length;\n  }\n\n  let numberOfWords = countWords(text);\n  return `Number of words: ${numberOfWords}`;\n}\n\nlet result = processText(\"Hello everyone my name is Jim\");\nconsole.log(result);\n\n//  Function with local and global variables\nlet message = \"This is a global variable\";\n\nfunction showMessage() {\n  let message = \"This is a local variable\";\n  console.log(message);\n}\n\nconsole.log(message);\nshowMessage();\nconsole.log(message);\n\n//  Extra difficulty\nfunction extraDifficulty(firstString, secondString) {\n  let counter = 0;\n\n  for (let i = 1; i <= 100; i++) {\n    let ouput =\n      (i % 3 === 0 ? firstString : \"\") + (i % 5 === 0 ? secondString : \"\") || i;\n    if (ouput === i) counter++;\n    console.log(ouput);\n  }\n  return counter;\n}\n\nextraDifficulty(\"First string\", \"Second string\");\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/marcode24.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n// Ejemplos de funciones básicas\nfunction funcionSinParametrosNiRetorno() {\n  console.log('¡Hola desde la función sin parámetros ni retorno!');\n}\n\nfunction funcionConParametros(parametro1, parametro2) {\n  console.log('Parámetro 1:', parametro1);\n  console.log('Parámetro 2:', parametro2);\n}\n\nfunction funcionConRetorno(num1, num2) {\n  return num1 + num2;\n}\n\n// Funciones dentro de funciones\nfunction funcionExterna() {\n  console.log('Función externa');\n\n  function funcionInterna() {\n    console.log('Función interna');\n  }\n\n  funcionInterna();\n}\n\n// Variable GLOBAL y LOCAL\nconst variableGlobal = 'Soy global';\n\nfunction funcionConVariables() {\n  const variableLocal = 'Soy local';\n  console.log(variableGlobal);\n  console.log(variableLocal);\n}\n\n// Utilizar función ya creada en el lenguaje\nconst numeros = [1, 2, 3, 4, 5];\nconst cuadrados = numeros.map((numero) => numero * numero);\n\nconsole.log('Cuadrados:', cuadrados);\n\n// Función Extra (DIFICULTAD EXTRA)\nfunction funcionExtra(texto1, texto2) {\n  let contador = 0;\n\n  for (let i = 1; i <= 100; i++) {\n    if (i % 3 === 0 && i % 5 === 0) {\n      console.log(texto1 + texto2);\n    } else if (i % 3 === 0) {\n      console.log(texto1);\n    } else if (i % 5 === 0) {\n      console.log(texto2);\n    } else {\n      console.log(i);\n    }\n\n    contador++;\n  }\n\n  return contador;\n}\n\nconsole.log('Número de impresiones:', funcionExtra('Fizz', 'Buzz'));\n\n// Visita mi repo en GitHub para ver y correr los tests de este código --> https://github.com/marcode24/weekly-challenges\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/mariovelascodev.js",
    "content": "//Función sin parámetros ni retorno\nfunction funcionSinParametros() {\n    console.log(`¡Hola Mundo!`);\n}\n\nfuncionSinParametros();\n\n//Función con parámetros\n/*\nSe pueden poner tantos parámetros como uno desee, tambien se le puede asignar un valor por defecto al parámetro\n */\nfunction funcionConParametros(param1) {\n    console.log(`¡Hola, ${param1}!`);\n}\n\nfuncionConParametros(\"JavaScript\");\n\n//Función con parámetros y retorno\nfunction funcionConParametrosRetorno(param1, param2) {\n    return `El primet parámetro es ${param1}, y el segundo parámetro es ${param2}`;\n}\n\nconsole.log(funcionConParametrosRetorno(\"Mario\", 33));\n\n//Función con parámetros por defecto\nfunction funcionConParametrosPorDefecto(param1, param2 = \"JS\") {\n    return `El primer parámetro es ${param1}, y el parámetro por defecto es ${param2}`;\n}\n\nconsole.log(funcionConParametrosPorDefecto(\"JavaScript\"));\nconsole.log(funcionConParametrosPorDefecto(\"JavaScript\", \"PHP\"));\n\n//Función con varios parámetros\nfunction funcionVariosParametros(...param) {\n    return param;\n}\n\nconsole.log(funcionVariosParametros(1, \"JS\", 30.45, \"Juan\", 87));\n\n//Función flecha sin argumentos\nlet sumar = () => 4 + 2;\n\nconsole.log(`El resultado de la suma es: ${sumar()}`);\n\n//Función flecha con argumentos\nlet restar = (param1, param2) => param1 - param2;\n\nconsole.log(`El resultado de la resta es: ${restar(4, 2)}`);\n\n//Función dentro de función\nfunction outer(param1) {\n    function inner(param2) {\n        return param1 + param2;\n    }\n    return inner;\n}\n\nconsole.log(outer(3)(5));\n\n//Funciones ya creadas en el lenguaje\nlet cadena = `Esto es una cadena de prueba`;\n\n//La función/método slice() extrae parte de un string\nconsole.log(cadena.slice(4, 12));\n//La función/método replace() reemplaza la primera ocurrencia que encuentra en la cadena\nconsole.log(cadena.replace(\"cadena\", \"hilo\"));\n\n//Variable local y global\nlet global = \"Variable global\";\n\nfunction variableLocal() {\n    let local = \"Variable local\";\n    return local;\n}\n\nconsole.log(global);\nconsole.log(variableLocal());\n\n//La variable global cambiará su valor mientras que la local no lo cambiará ya que su ámbito está solo dentro de la función donde es creada\nglobal = 34;\nlocal = 12;\nconsole.log(`El nuevo valor de la variable global es: ${global}`);\nconsole.log(variableLocal());\n\n//EXTRA\nfunction imprimeNumero(param1, param2) {\n    let str1 = String(param1);\n    let str2 = String(param2);\n    let contador = 0;\n\n    for (let i = 1; i <= 100; i++) {\n        if (i % 3 == 0 && i % 5 == 0) {\n            console.log(`${str1} ${str2}`);\n        } else if (i % 3 == 0) {\n            console.log(str1);\n        } else if (i % 5 == 0) {\n            console.log(str2);\n        } else {\n            console.log(i);\n            contador += 1;\n        }\n    }\n\n    return `Número de veces que se ha impreso el número en lugar de textos: ${contador} veces`\n}\n\nconsole.log(imprimeNumero(\"Hola\", \"mundo\"));"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/mateo423.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n// Funcion sin parametros;\nfunction saludar() {\n  console.log('Hello Word');\n};\nsaludar()\n\n\n// Funcion con parametros; \nconst count_numer = (hasta = 10) => {\n  for (let i = 1; i <= hasta; i++) {\n    console.log(i);\n\n  };\n};\ncount_numer();\nconsole.log('  ');\n// Funcion Callbacks Javascript;\n\nconst operacionMatematicas = (operacion, valor1, valor2) => operacion(valor1, valor2);\n\nconst sumar = (n1, n2) => n1 + n2;\nconst restar = (n1, n2) => n1 - n2;\n\nconst resultado = operacionMatematicas(sumar, 10, 3);\nconsole.log(resultado);  // Resultado: 13\nconsole.log(\"  \")\n\n// Funcion Con return;\nconst despedida = function (lenguaje) {\n  let mensaje;\n  switch (lenguaje) {\n    case 'es':\n      mensaje = 'Adios';\n      break\n    case 'en':\n      mensaje = 'Bye';\n    default:\n      mensaje = 'Tienes que elegir entre es/en'\n  }\n  return mensaje;\n}\nconsole.log(despedida('es'));\n\n// Funciones anidadas;\n/*Creador un contador dentro de una funcion anidada */\n\nfuncionExterna = function () {\n  let contador = 0;\n  return function funcionInterna() {\n    contador++;\n    console.log(contador);\n\n  }\n}\nconst contador = funcionExterna();\ncontador();\ncontador();\ncontador();\n\n\n//  Variables locales  Variables Globales;\n\nlet variable_global = 'Variable Global';\n\nconst example = function () {\n  let variable_local = 'Variable Local';\n  console.log(variable_global);\n  console.log(variable_local);\n};\nexample();\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\nconst dificultad_extra = (mensaje1, mensaje2) => {\n  let contador_numero = 0;\n  for (let numero = 1; numero <= 100; numero++) {\n    if (numero % 3 === 0 && numero % 5 === 0) {\n      mensaje1 = 'Fizz';\n      mensaje2 = 'Bazz'\n      console.log(mensaje1 + mensaje2);\n    } else if (numero % 3 === 0) {\n      console.log(mensaje1);\n    } else if (numero % 5 === 0) {\n      console.log(mensaje2)\n    } else {\n      console.log(numero);\n      contador_numero++;\n    };\n  };\n  return contador_numero;\n\n};\nconst vecesNumero = dificultad_extra('Fizz', 'Bazz');\nconsole.log(\"El numero de veces que se repitio su numero fue \" + vecesNumero);\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/matrix-miguel.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n// Function without param\nfunction withoutParam() {\n  console.log(\"Hello Matrix\");\n};\nwithoutParam();\n\n//with arg and default value\nfunction withParam(a = 1, b = 2) {\n  console.log(a + \" \" + b);\n};\nwithParam(\"Hi\", \"Matrix\");\nwithParam((b = 20), (a = 30));\nwithParam();\n\n// with args\nfunction greetComunity(...names) {\n  console.log(names);\n  for (const name of names) {\n    console.log(`hello ${name}`);\n  }\n};\ngreetComunity(\"Matrix\", \"Machine Learning\", \"Anonymous\");\n\n// with return\nfunction withReturn() {\n  return [\"Hello\", \"Matrix\"];\n};\nconsole.log(withReturn());\nlet [word, name] = withReturn();\n\nconsole.log(word);\nconsole.log(name);\n\n// function inside function\nfunction doubleFunction() {\n  function print() {\n    return \"Hello Matrix double function\";\n  }\n\n  return print();\n};\nconsole.log(doubleFunction());\n\n//Function Built in - random number\nconsole.log(Math.random());\nconsole.log(\"matrix\".toUpperCase());\nconsole.log(\"matrix\".toLowerCase());\n\n//variable local - global\nlet global = \"global\";\n\nfunction scope() {\n  let local = \"local\";\n  console.log(global);\n  console.log(local);\n}\nscope();\n\nconsole.log(global);\nconsole.log(local);\n\n//Fizz-Buzz-Counter\nfunction matrix(fizz = \"Fizz\", buzz = \"Buzz\") {\n  let counter = 0;\n  for (let i = 0; i <= 100; i++) {\n    if (i % 3 == 0) {\n      console.log(i + fizz);\n    }\n    if (i % 5 == 0) {\n      console.log(i + buzz);\n    }\n    if (i % 3 == 0 && i % 5 == 0) {\n      console.log(i + fizz + buzz);\n    }\n\n    counter++;\n  }\n  return counter;\n}\n\nlet counter = matrix();\nconsole.log(counter);\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/maximiliano1997.js",
    "content": "/*\r\n * EJERCICIO:\r\n * - Crea ejemplos de funciones básicas que representen las diferentes\r\n *   posibilidades del lenguaje:\r\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\r\n * - Comprueba si puedes crear funciones dentro de funciones.\r\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\r\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\r\n * - Debes hacer print por consola del resultado de todos los ejemplos.\r\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\r\n *\r\n * DIFICULTAD EXTRA (opcional):\r\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\r\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\r\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\r\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\r\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\r\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\r\n *\r\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\r\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\r\n */\r\n\r\n\r\n// Funcion sin parametros:\r\nfunction noParametros() {\r\n    return 'No parametro'\r\n}\r\n\r\n// Con uno o varios parametros:\r\nfunction dosParametros(uno, dos) {\r\n    console.log(`${uno} y ${dos}`)\r\n}\r\n\r\n// Con uno o varios parametros y con retorno:\r\nfunction dosParametros(uno = 1, dos = 2) {\r\n    return (uno + dos)\r\n}\r\n\r\n// Funcion dentro de otra funcion:\r\nfunction funcUno(param1, param2) {\r\n    let result = 0\r\n\r\n    function funcDos() {\r\n        result = param1 + param2\r\n    }\r\n\r\n    if (param1 && param2) {\r\n        funcDos(param1, param2)\r\n    }\r\n\r\n    return result\r\n}\r\nfuncUno(1, 2)\r\n\r\n\r\n// Funcion Flecha\r\nconst funcionFlecha = (a) => {\r\n    return a\r\n}\r\n\r\n// Funciones ya creadas en el Lenguaje\r\nlet hola = 'hola como estas'\r\n\r\nlet upperCase = hola.toUpperCase()\r\nlet lowerCase = hola.toUpperCase()\r\nlet slice = hola.slice(1, 2)\r\nlet length = hola.length\r\nlet split = hola.split(' ')\r\n\r\n// Funciones (Metodos) de Arrays en Javascript\r\nlet test = ['uno', 'dos', 'tres']\r\nconst filter = test.filter(a => {\r\n    return a === 'dos'\r\n})\r\nconst map = test.map(x => x === 'tres')\r\nconst forEach = test.forEach(x => { })\r\nconst find = test.find(x => x === 'tres')\r\nconst some = test.some(x => x == 'uno')\r\nconst every = test.every(x => x == 'uno')\r\n\r\n// concepto de variable GLOBAL.\r\nlet global = 0  // <-- variable global\r\nfunction increment() {\r\n    return global++\r\n}\r\n\r\n// concepto de variable LOCAL.\r\nfunction decrement() {\r\n    let local = 0  // <-- vairable local\r\n    return local\r\n}\r\n\r\n\r\n\r\n// Comprobacion en consola\r\n\r\nconsole.log(noParametros(), '   <-- noParametros')\r\nconsole.log(dosParametros(), '  <-- dosParametros')\r\n\r\nconsole.log(`\r\n\r\n    Funciones ya creadas en el lenguaje\r\n    ${hola.toUpperCase()}   <-- toUpperCase\r\n    ${hola.toLowerCase()}   <--toLowerCase\r\n    ${hola.slice(1, 2)}     <-- slice\r\n    ${hola.length}          <-- length\r\n    ${hola.split(' ')}      <-- split\r\n    `)\r\n\r\nconsole.log(filter, '   <-- Filter')\r\nconsole.log(map, '  <-- map')\r\nconsole.log(find, '  <-- find')\r\nconsole.log(some, '  <-- some')\r\nconsole.log(every, '  <-- every')\r\nconsole.log(increment() + '.. resultado:  ' + global, ' <-- VARIABLE GLOBAL')\r\nconsole.log(decrement(), '      <-- VARIABLE LOCAL')\r\n\r\n\r\n\r\n//     * DIFICULTAD EXTRA(opcional):\r\n\r\n\r\nfunction difExtra(arg1, arg2) {\r\n    let counter = 0\r\n\r\n    for (let i = 0; i < 100; i++) {\r\n        if (i % 5 == 0 && i % 3 == 0) {\r\n            console.log(arg1 + 2)\r\n        } else if (i % 3 === 0) {\r\n            console.log(arg1)\r\n        } else if (i % 5 == 0) {\r\n            console.log(arg2)\r\n        } else {\r\n            console.log(i)\r\n            counter++\r\n        }\r\n    }\r\n\r\n    console.log('Numero de veces Numeros Impresos: ', counter)\r\n}\r\n// difExtra('gracias ', 'mouredev')"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/miguelex.js",
    "content": "// Ejemplo de funcion sin variables ni retorno\n\nfunction saludo() {\n    console.log(\"Hola\");\n}\n\n// Ejemplo de funcion con paso de variable y sin retorno\n\nfunction saludo2(nombre) {\n    console.log(\"Hola \" + nombre);\n}\n\nsaludo2(\"Migue\");\n\n// Ejemplo de funcion con paso de variable y retorno\n\nfunction saludo3(nombre) {\n    return \"Hola \" + nombre;\n}\n\nlet msj = saludo3(\"Migue\");\nconsole.log(msj);\n\n// Ejemplo de funcion flecha de funcion sumar\n\nconst sumar = (a, b) => {\n    return a + b;\n}\n\nlet suma = sumar(2, 3);\n\n// Ejemplo de funcion creada dentro de otra funcion\n\nfunction saludoYSuma(a, b) {\n    console.log(\"Hola, vamos a hacer una suma\");\n    function sumar(a, b) {\n        return a + b;\n    }\n    console.log(sumar(a, b));\n}\n\nsaludoYSuma(2, 3);\n\n// Ambito global y local de las variables\n\nlet variableGlobal = \"Soy global\";\n\nfunction mostrarVariableGlobal() {\n    console.log(variableGlobal);\n}\n\nmostrarVariableGlobal();\n\nfunction mostrarVariableLocal() {\n    let variableLocal = \"Soy local\";\n    console.log(variableLocal);\n}\n\n// Ejemplo de funciones del sistema\n\nconsole.log(parseInt(\"20\"));\n\n// Ejemplo de funcion anonima\n\nlet anonima = function() {\n    console.log(\"Soy anonima\");\n}\nanonima();\n\n// Extra\n\nfunction ejercicioExtra(param1, param2) {\n    let numVeces = 0;\n    for (let i = 1; i <= 100; i++) {\n      if (i % 15 === 0) {\n        console.log(param1 + param2);\n      } else if (i % 3 === 0) {\n        console.log(param1);\n      } else if (i % 5 === 0) {\n        console.log(param2);\n      } else {\n        console.log(i);\n        numVeces++;\n      }\n    }\n    return numVeces;\n  }\n  \n  const extra = ejercicioExtra(\"Fizz \", \"Buzz\");\n  console.log(\"Cantidad de numeros imprimidos =  \" + extra)\n\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/migueltfangche.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n//\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n//funciones simples//\n\nfunction saludar()  {\n    console.log('Hola, Javascript!');\n}\nsaludar();\n// con retorno\nfunction returnSaludar() {\n    return console.log('Hola, Javascript!');\n}\nreturnSaludar();\n\n//con argumento\n\nfunction arg_saludar(saludo) {\n    return saludo;\n}\nlet saludo = arg_saludar('Hola, Javascript!');\nconsole.log(saludo);\n\n//funciones dentro de funciones\n\nfunction outherFunction() {\n    function innerFunction() {\n        console.log('Hola, Javascripts!');\n        \n    }innerFunction();\n} outherFunction();\n\n//funciones dentro del lenguaje\nlet a = 1;\nconsole.log(a);\n\n// variables locales y globales\n\nvariable_global = \"Javascript\";\n\nconsole.log(variable_global);\n\nfunction holaJavascript() {\n    variable_local = \"Hola\";\n    console.log(variable_local, variable_global);\n}\nholaJavascript();\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/misterdan100.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n// no params, no return \nfunction great() {\n    console.log(\"Mister you're doing it very well\")\n}\ngreat()\n\nfunction dog() {\n    console.log(\"I'm Mister dog\")\n    const dogRun = () => {console.log('Running')}\n    dogRun()\n}\ndog()\n\nfunction addTwoNumbers(num1, num2) {\n    return num1 + num2\n}\n\nfunction checkNumber(param1, param2) {\n    let result = 0\n    for(let i = 1; i <= 100; i++) {\n        if( i % 5 === 0 && i % 3 === 0) {\n            console.log(`${param1} ${param2}`)\n            continue\n        }\n        if( i % 3 === 0) {\n            console.log(param1)\n            continue\n        }\n        if( i % 5 === 0) {\n            console.log(param2)\n            continue\n        }\n        result++\n    }\n\n    return result\n}\n\nconsole.log(checkNumber('Dan', 'Emma'))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/monicavaquerano.js",
    "content": "// 02 FUNCIONES Y ALCANCE\n// Monica Vaquerano\n//  https://monicavaquerano.dev\n\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n//  * - Crea ejemplos de funciones básicas que representen las diferentes posibilidades del lenguaje:\n\n// Funciones Autoinvocadas (Immediately Invoked Function Expressions - IIFE):\n/* Son funciones que se ejecutan inmediatamente después de ser definidas.\n* Son útiles para encapsular el código y evitar la contaminación del ámbito global.\n*/\n\n(function () {\n    console.log('Esta función se ejecuta inmediatamente.');\n})();\n\n// Funciones Declarativas (Declarative Functions):\n/* Estas son las funciones más comunes y tradicionales en JavaScript, donde defines una función utilizando la palabra clave function. \n * Puedes declararlas en cualquier lugar en el código, y JavaScript las \"eleva\" al inicio del contexto de ejecución, \n * por lo que puedes llamar a la función antes de que aparezca en el código. \n */\n\nfunction square(number) {\n    return number * number;\n}\nconsole.log(square(3))\n\n// Expresiones de Funciones (Function Expressions):\n/* Estas son funciones que se asignan a variables como valores. Puedes definir funciones en línea y asignarlas a variables. \n * Son útiles cuando necesitas funciones como argumentos para otras funciones o cuando deseas encapsular una función dentro de un contexto. \n */\n\nconst multiply = function (a, b) {\n    return a * b;\n};\n\nconsole.log(multiply(2, 2))\n\n// Funciones Flecha (Arrow Functions):\n/* Las funciones flecha son una forma más concisa de escribir funciones en JavaScript.\n * Tienen una sintaxis más corta y no cambian el contexto de this dentro de la función.\n * Son útiles para funciones simples y en contextos donde necesitas preservar el valor de this.\n */\n\nconst greet = (name) => {\n    return `Hello, ${name}!`;\n};\n\nconsole.log(greet(\"Monica\"))\n\n// Métodos de Objeto (Object Methods):\n/* Son funciones que se definen como propiedades de un objeto.\n * Estos métodos son funciones que se pueden invocar en el contexto de ese objeto utilizando la notación de punto.\n */\nconst user = {\n    name: 'John',\n    greet: function () {\n        return `Hello, ${this.name}!`;\n    }\n};\n\nconsole.log(user.greet())\n\n// Funciones Constructoras (Constructor Functions):\n/* Estas son funciones que se utilizan para crear nuevos objetos mediante el uso del operador new.\n * Son útiles cuando necesitas crear múltiples instancias de un tipo de objeto.\n */\nfunction Person(name, age) {\n    this.name = name;\n    this.age = age;\n}\n\nconst person1 = new Person('Alice', 30);\nconst person2 = new Person('Bob', 25);\n\nconsole.log(person1, person2)\n\n// Callback:\n/* A callback is a function passed as an argument to another function. \n * This technique allows a function to call another function.\n * A callback function can run after another function has finished\n */\nvar funcionB = () => {\n    return console.log('Funcion B ejecutada');\n};\nvar funcionA = (a, b, callback) => {\n    console.log(\"Funcion A:\", a + b)\n    callback();\n};\n\nfuncionA(1, 2, funcionB);\n\n\n// # Sin parámetros ni retorno\nfunction cuentaRegresiva() {\n    for (let i = 10; i >= 0; i--) {\n        if (i == 0) { console.log(\"BOOM!\"); }\n        else { console.log(i); }\n    }\n}\n\ncuentaRegresiva();\n\n// # Con parámetro, no retorno\nvar greeting = (name) => {\n    console.log(\"Hello, \" + name + \"!\");\n}\n\ngreeting(\"Charlie\");\n\n// # Con uno o más parámetros y con retorno\nvar suma = (a, b) => {\n    return a + b;\n}\n\nconsole.log(suma(5, 6));\n\n\n// # Una lista como argumento\nfunction sortList(arr, reverse = false) {\n    arr.sort();\n    if (reverse) { arr.reverse(); }\n    return arr;\n}\n\nconsole.log(sortList([3, 0, 1, 2]));\nconsole.log(sortList([3, 0, 1, 2], true));\n\n\n// Function Rest Parameter\n// The rest parameter (...) allows a function to treat an indefinite number of arguments as an array:\nfunction sum(...args) {\n    let sum = 0;\n    for (let arg of args) sum += arg;\n    return sum;\n}\n\nlet x = sum(4, 9, 16, 25, 29, 100, 66, 77);\nconsole.log(x);\n\n\n// # Parámetros con keywords\nfunction vocales(vocal1, vocal2, vocal3, vocal4, vocal5) {\n    console.log(`Las vocales cerradas son ${vocal4} y ${vocal5}, las abiertas son ${vocal3}, ${vocal2} & ${vocal1}.`)\n}\n\nvocales(vocal2 = \"e\", vocal1 = \"a\", vocal3 = \"i\", vocal5 = \"u\", vocal4 = \"o\");\n\n// # Recursion\nfunction recurrente(num) {\n    let result;\n    if (num > 0) {\n        result = num + recurrente(num - 1);\n        console.log(result);\n    } else {\n        result = 0;\n    }\n    return result;\n}\n\nrecurrente(3);\n\n\n// \"\"\"\n// * - Comprueba si puedes crear funciones dentro de funciones.\n// \"\"\"\n\nfunction funcionPrincipal(string) {\n    function funcionSecundaria(string) {\n        let newStr = \"\";\n        for (let i = 0; i < string.length; i++) {\n            if (i % 2 == 0) {\n                newStr += string[i];\n            } else {\n                newStr += string[i].toUpperCase();\n            }\n        }\n        return newStr;\n    }\n    return funcionSecundaria(string);\n}\nconsole.log(funcionPrincipal(\"hola\"));\n\n\n// \"\"\"\n//  * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n// \"\"\"\n\nconsole.log(\"\\nAlgunas funciones ya creadas en JavaScript (Built-in Functions):\");\n\nvar lista = [5, 7, 4, 6, 1];\n\n// Len\nconsole.log(`len(): la longitud de {lista} es de: ${lista.length}`);\n// concat\nvar alpha = [\"a\", \"b\", \"c\"];\nvar numeric = [1, 2, 3];\nvar alphaNumeric = alpha.concat(numeric);\nconsole.log(\"concat(): \", alphaNumeric);\n\n// # Abs\nconsole.log(`Math.abs(x): el absoluto de - 20 es: ${Math.abs(-20)}`);\n// # Max\nconsole.log(`Math.max(x): el máximo en {...lista} es: ${Math.max(...lista)}`);\n// # Min\nconsole.log(`Math.min(x): el mínimo en {...lista} es: ${Math.min(...lista)}`);\n// # Pow\nconsole.log(`Math.pow(x, y): 7 elevado al cuadrado {Math.pow(7, 2)} es: ${Math.pow(7, 2)}`);\n// # Print\nconsole.log(`console.log(x): imprime los resultados en la consola. {True}, {None}, {lista}, etc.`);\n// # Sorted\nconsole.log(`sort(): lista.sort(): ${lista.sort()}`);\n// # Reversed\nconsole.log(`reverse(): lista.reverse(): ${lista.reverse()}`);\n// # toString\nconsole.log(`toString(): lista.toString(): ${lista.toString()}`);\n\n// \"\"\"\n// * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n// \"\"\"\n\nconsole.log(\"\\nVariable local y global:\");\n\n// Variable Global\nlet nombre = \"Juan\";\n\nfunction devolverNombre() {\n    // Variable Local\n    let nombre = \"Carlos\"\n    return nombre;\n\n}\nconsole.log(`Yo regreso la variable global (nombre = ${nombre})\\nYo regreso la variable local dentro de la funcion (nombre = ${devolverNombre()}).`);\n\n\n// \"\"\"\n//  * DIFICULTAD EXTRA (opcional):\n//  * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n//  * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n//  *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n//  *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n//  *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n//  *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n//  *\n//  * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n//  * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n// \"\"\"\n\nfunction miFuncion(str1, str2) {\n    let counter = 0;\n    for (let i = 1; i <= 100; i++) {\n        if (i % 3 == 0 && i % 5 == 0) {\n            console.log(str1 + \" \" + str2);\n        } else if (i % 5 == 0) {\n            console.log(str2);\n        } else if (i % 3 == 0) {\n            console.log(str1);\n        } else {\n            console.log(i);\n            counter++;\n        }\n    }\n    return counter;\n}\n\nconsole.log(\"\\nDIFICULTAD EXTRA (opcional):\")\nx = miFuncion(\"hakuna\", \"matata\")\nconsole.log(`\\nNúmero de veces que se ha impreso el número en lugar de los textos:\\n> ${x}`)\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/natalyjoanna.js",
    "content": "\n// Funcion basica\n\nfunction greet() {\n  console.log(\"Hello, World!\");\n}\n\ngreet()\n\n// Funcion que resive parametros sin retorno\n\nfunction greetPerson(name) {\n  console.log(\"Hello, \" + name)\n}\n\ngreetPerson(\"Nataly\")\n\n// funcion con un parametro y retorno\n\nfunction pares(num) {\n  let res \n  if(num%2==0) {\n    res = true\n  } else (\n    res = false\n  )\n  return res\n}\n\nlet num = 10102\nlet respuesta = pares(num)\nif (respuesta==true) { console.log(\"El nuemro es par\"); } else { console.log(\"El numero es impar\") }\n\n// Funcion con retorno y varios parametros\n\nfunction suma(a,b) {\n  return a + b\n}\n\nlet a = 23\nlet b = 22\nconst total = suma(a,b)\nconsole.log(\"Suma: \", total)\n\n// Funcion dentro de funcion\n\nfunction calculadora(a,b) {\n\n  function resta() {\n    return a-b\n  }\n\n  function multiplicacion() {\n    return a*b\n  }\n\n  function division() {\n    return a/b\n  }\n\n  return {\n    resta: resta(),\n    multiplicacion: multiplicacion(),\n    division: division()\n  }\n\n}\n\nconst resultados = calculadora(a,b)\nconsole.log(\"Resta: \", resultados.resta)\nconsole.log(\"Multiplicacion: \", resultados.multiplicacion)\nconsole.log(\"Division: \", resultados.division)\n\n// Funcion de javascript\n\nconst fecha = new Date()\nconst dia = fecha.getDate()\nconst mes = fecha.getMonth()\nconst año = fecha.getFullYear()\nconst formatoFecha = `${dia}/${mes}/${año}` \nconsole.log(\"La fecha actual es: \", formatoFecha)\n\n// DIFICULTAD EXTRA\n\nfunction imprimirMensaje(texto01, texto02) {\n  let count = 0\n  for(let num=1; num<=100;num++){\n    if(num%3==0 && num%5==0){\n      console.log(`${texto01} ${texto02}`)\n    } else if (num%3==0){\n      console.log(texto01)\n    } else if(num%5==0) {\n      console.log(texto02)\n    } else {\n      console.log(num)\n      count++\n    }\n  }\n  return count\n}\n\nlet impresion = imprimirMensaje(\"Hola\", \"Adios\")\nconsole.log(\"Las veces que se imprimio un numero fueron: \", impresion)"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/nlarrea.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n// FUNCIONES SIN PARÁMETROS\n\nfunction greet() {\n    console.log('Hello there!');\n}\n\nconst arrowGreet = () => console.log('Hello there from arrow function!');\n\n// FUNCIONES CON PARÁMETROS\n\nfunction greetUser(name, surname) {\n    console.log(`Hello ${name} ${surname}!`);\n}\n\nconst arrowGreetUser = (name, surname) => console.log(`Hello ${name} ${surname}!`);\n\n// FUNCIONES CON RETORNO\n\nfunction addTwo(numOne, numTwo) {\n    return numOne + numTwo;\n}\n\nconst arrowAddTwo = (numOne, numTwo) => numOne + numTwo;\n\n// FUNCIONES CON FUNCIONES DENTRO\n\nfunction greetUserWithInner (name, surname) {\n    const getFullName = () => `${name} ${surname}`;\n\n    console.log(`Hello ${getFullName()}!`);\n}\n\n// BUILT IN FUNCTIONS\n\nconst stringNumber = '11';\nconst number = parseInt(stringNumber);\nconsole.log(`stringNumber is ${typeof stringNumber}, but number is ${typeof number}`);\n// stringNumber is string, but number is number\n\n// LLAMADA A LAS FUNCIONES\n\ngreet();\narrowGreet();\n\ngreetUser('Naia', 'Larrea');\narrowGreetUser('Naia', 'Larrea');\n\nconsole.log(addTwo(2, 3));      // 5\nconsole.log(arrowAddTwo(2, 3)); // 5\n\ngreetUserWithInner('Naia', 'Larrea');\n\n\n/* DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\nfunction printNumbers(textOne, textTwo) {\n    let counter = 0;\n\n    for (let num=1; num<=100; num++) {\n        if (num % 3 === 0 && num % 5 === 0) {\n            console.log(`${textOne}${textTwo}`);\n        } else if (num % 3 === 0) {\n            console.log(textOne);\n        } else if (num % 5 === 0) {\n            console.log(textTwo);\n        } else {\n            console.log(num);\n            counter++;\n        }\n    }\n\n    return counter;\n}\n\nconsole.log(printNumbers('fizz', 'buzz'));  // 53"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/ocram1304.js",
    "content": "//Variable global\nconst usuGlobal = \"ocram1304\"\nlet fecha = \"20/04/2024\";\n//función sencilla\n//funciones que no retornan\nfunction mifunction(){\n  console.log(\"hello world\");\n}\nmifunction();\n//función con parámetros\nfunction mifunctionV2(author, date){\n  console.log(`hola soy ${author} saludos desde el dia ${date}`);\n}\nmifunctionV2(usuGlobal, fecha);\n\nfunction actualizarFecha(nFecha){\n  fecha = nFecha;\n \n}\n//funcion con retorno\nfunction FunRetorno(num1, num2){\n\n  return num1 * num2;\n}\nconsole.log(FunRetorno(2,3));\n\n//funcióne anónima\nconst cuadrado = function(){\n  return  \"función anónima\";\n}\nconsole.log(cuadrado);\n//función flecha\nconst pares = [1,2,3,4];\nconst pares2=  pares.map((par)=>{\n  return par*2;\n});\nconsole.log(pares2);\n\n//JS si soporta crear funciones dentro de funciones\nfunction funcionAnidada(numero){\n//Ambito de varibles: las variables declaradas dentro de una función no pueden ser accedidas desde fuera\n//su ámbito es local a la función en donde fueron declaradas, en este ejemplo \"num\" no puede ser accedido \n//fuera delámbito de \"iPrimo\"  aunque está función este dentro de otra función (funcionAnidada).\n  for(let i=0; i<=numero;i++){\n    if(isPrimo(i)){\n       console.log(i);\n    }\n   \n  }\n\n  function isPrimo(num){\n    if(num<=1){\n     return false;\n    }\n    for(let i =2;i<num;i++){\n     if (num % i===0){\n         return false;\n     }\n      \n    }\n    return true; \n\n }\n \n}\nfuncionAnidada(20);\n\n//Dificultad extra\nfunction difExtra(para1,para2){\n  let onlyNumber = 0;\n  for(let i= 0; i<=100;i++){\n\n   \n    if(i%5===3){\n      console.log(para1);\n    }\n    else if(i%5===0){\n      console.log(para2)\n    }\n    else if(i%3===0 && i%5===0){\n        console.log(`${para1}, ${para2} `);\n    }\n    else{\n      console.log(i);\n      onlyNumber++;\n    }\n  }\n  console.log(\"Numeros en lugar de texto\", onlyNumber);\n}\ndifExtra(multiplo3,multiplo5);\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/oleojake.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n\n// FUNCIÓN SIN PARÁMETRO\nfunction funcionSimple (){\n    console.log (\"Soy una función sin parámetros ni retorno\");\n}\nfuncionSimple();\n\n// FUNCIÓN CON UN PARÁMETRO\nfunction funcionOneParameter (message){\n    console.log (\"Soy una función con un parámetro y te lo imprimo por pantalla: \" + message);\n}\nlet myMessage = \"OleojakeDEV\"\nfuncionOneParameter(myMessage);\n\n// FUNCIÓN CON DOS PARÁMETROS\nfunction sumaNumbers (num1,num2){\n    let suma = num1 + num2;\n    console.log (\"Te hago la suma de los dos números que me has pasado: \" + num1 + \" + \" + num2 + \" = \" + suma);\n}\nsumaNumbers(3,5);\n\n// FUNCIÓN CON RETORNO\nfunction retornoMultiplicacion (num1,num2) {\n    return num1 * num2;\n}\nlet multiplicacion = retornoMultiplicacion(3,5);\nconsole.log (\"Después de haber llamado a retornoMultiplicacion() ahora mi variable multiplicación vale: \" + multiplicacion);\n\n// FUNCIÓN DENTRO DE OTRA FUNCIÓN\nfunction printSumaNumbers (num1,num2){\n    let suma = num1 + num2;\n    function printResult (sumaResult){\n        console.log (\"El resultado de la suma que me has pasado: \" + num1 + \" + \" + num2 + \" = \" + suma);\n    }\n    printResult(suma);    \n}\nprintSumaNumbers (4,2);\n\n// FUNCIÓN DEFINIDA YA EN JS\nlet myDecimal = 5.45;\nconsole.log(parseInt(myDecimal)); // Devuelve un entero a partir de un decimal\n\n// VARIABLE GLOBAL Y LOCAL\nlet numberGlobal = 50;\nfunction changeMyNumber (){\n    let numberLocal = 75;\n    console.log (numberLocal); // Solo puedo acceder a su valor dentro de donde se ha declarado\n    numberGlobal = 100; // En cambio puedo acceder a variables globales que se han definido fuera de la funcion\n}\nchangeMyNumber();\nconsole.log (numberGlobal);\n\n// FUNCION ÁNONIMA, Se declaran sin nombre y se alojan dentro de una variable\nconst PI = function () {\n    return 3.14;\n}\nconsole.log(PI); // Imprime la funcion\nconsole.log(PI()); // Llamamos a la funcion dentro de la variable donde la hemos alojada\n\n// ARROW =>\n// También se pueden definir eliminando la palabra function y utilizando la flecha\nconst PI_FLECHA = () => {\n    return \"PI_flecha\";\n}\nconsole.log(PI_FLECHA());\n// A diferencia de las functions habituales que pueden ser llamadas antes o después de su declaración. Una función flecha no puede ser llamada antes de ser declarada.\n\n\n/* DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n */\n\nfunction myFizzBuzz (fizz,buzz) {\n    let contador = 0;\n    for (let i = 1; i <= 100; i++) {\n        if ((i % 3 == 0) && (i % 5 != 0)){\n            console.log(fizz);\n        } else if ((i % 5 == 0) && (i % 3 != 0)){\n            console.log(buzz);\n        } else if ((i % 5 == 0) && (i % 3 == 0)){\n            console.log(fizz+buzz);\n        } else {\n            console.log (i);\n            contador ++;\n        }\n    }\n    return contador;\n}\nconsole.log(\"Se han impreso números: \" +myFizzBuzz (\"Fizz\", \"Buzz\") + \" veces\");"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/omegatroy.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...✅\n * - Comprueba si puedes crear funciones dentro de funciones.✅\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.✅\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.✅\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)✅\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n// esto es una funcion mas basica\nfunction holaMundo(){\n  console.log('hola mundo')\n}\nholaMundo()\n\n// esta funcion resive un parametro (nombre) que nosotros se lo pasamos cuando la llamemos\nfunction saludar(nombre){\n  console.log(`hola ${nombre}, como estas?`)\n}\nsaludar('OmegaTroy')// <---- aca le estamos pasando el nombre OmegaTroy ala funcion\n\n//esta funcion recive varios parametros ala vez\n//tambien es una funcion flecha o arrow function\nconst resta =(num1,num2,num3)=>{\n  console.log(num1 - num2 - num3)\n}\nresta(11,20,50)\n\n// esta funcion nos retorna el numero 12\nfunction numero(){\n  return 12\n}\nconsole.log(`el numero es ${numero()}`)\n\n\n// esta funcion recive dos parametros numeros y nos retorna la suma de estos numeros\nconst suma =(num1,num2)=>{\n  return num1 + num2\n}\nconsole.log(suma(2,3))\n\n// esta funcion tiene otro funcion dentro\nfunction funcionUno(param1) {\n  function funcionDos(param2) {\n      return param1 + param2;\n  }\n  return funcionDos;\n}\nconsole.log(funcionUno(13)(23));\n\n//Funciones ya creadas en el lenguaje\nlet cadena = `No tiene sentido decir una mentira que te consuele, así que te diré la verdad`;\n\n//La funcion/metodo slice() extrae parte de un string\nconsole.log(cadena.slice(3, 8));\n//La funcion/metodo replace() reemplaza la primera ocurrencia que encuentra en la cadena\nconsole.log(cadena.replace(\"verdad\", \"mentira\"));\n\n//Variable local y global\n\nlet global = 'Variable global'\n\nfunction funcionVariables(){\n  let local = ' funcion'\n  return global + local\n}\n\nconsole.log(funcionVariables())\n\n\nfunction fizzBuzz(str1,str2){\n  for(let i = 0; i <= 100; i++) console.log(`${i % 3 ? '' : str1}${i % 5 ? '' : str2}` || i)\n}\nfizzBuzz('Fizz', 'Buzz')"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/orlas135.js",
    "content": "/*Funciones en Javascript*/\n\n/* Funciones declaradas en JS */\n/*Las funciones declaradas son aquellas funciones que se definen con la palabra clave function, seguida del nombre\n  al igual que los parámetros opcionales que deseemos utilizar en dicha función y, por último, las llaves que definirán el bloque de\n  código que ejecutará dicha función\n\n  Para hacer uso de esta función, se debe hacer un llamado, especificando los argumentos (si así es requerido), de los que hará uso la función\n*/\n\n/* Función */\nfunction multiplicarNumeros(a, b) {\n  return console.log(`El resulta de multiplicar ${a} * ${b} es: ${a * b}`);\n}\n\n/* Llamado a la función */\nmultiplicarNumeros(7, 9);\n\n/* Funciones expresadas en JS */\n/* Las funciones expresadas son aquellas que se pueden guardar en una variable o constante: */\n// No es obligatorio que tengan nombre\n\nconst saludo = function (nombre) {\n  return console.log(`Hola ${nombre}`);\n};\n\nsaludo(`orlas135`);\n\n/* Funciones flecha */\n/* Las funciones flecha son una manera de crear funciones expresadas de una manera más abreviada */\n/* Si la sentencia que irá dentro de estas funciones flecha solo lleva una línea, se pueden omitir las llaves\n   al igual que también se puede omitir la palabra return, ya que se convierte en algo implícito\n*/\n\nconst miFuncion = (num1, num2) => num1 + num2;\n\nconsole.log(`Resultado de la suma: ` + miFuncion(9, 9));\n\n/* Si se le da el nombre a una función expresada, se puede hacer referencia a ella misma dentro de la misma función */\nconst factorial = function fac(n) {\n  return n < 2 ? 1 : n * fac(n - 1);\n};\n\nconsole.log(factorial(7));\n\n/*Las funciones pueden también servir como argumento para otras funciones previamente definidas */\n\n/*Las funciones también pueden ser vistas como métodos de un objeto, por ejemplo: */\n\nconst raiz = Math.sqrt(49);\n/*El objeto Math tiene un método llamado sqrt, que saca la raíz cuadrada del número enviado como argumento */\n\n/*Función dentro de otra función*/\n\nfunction operacionesMatematicas(op, num1, num2) {\n  if (op == 1) {\n    sumar(num1, num2);\n  } else if (op == 2) {\n    restar(num1, num2);\n  } else if (op == 3) {\n    multiplicar(num1, num2);\n  } else if (op == 4) {\n    dividir(num1, num2);\n  } else {\n    return console.log(`Opción de operación no válida`);\n  }\n\n  function sumar(n1, n2) {\n    return console.log(`Resultado: ${n1 + n2}`);\n  }\n  function restar(n1, n2) {\n    return console.log(`Resultado: ${n1 - n2}`);\n  }\n\n  function multiplicar(n1, n2) {\n    return console.log(`Resultado: ${n1 * n2}`);\n  }\n\n  function dividir(n1, n2) {\n    console.log(`Resultado: ${n1 - n2}`);\n  }\n}\n\noperacionesMatematicas(4, 4, 9);\n\n/* Variable local vs Variable global */\n/* Dependiendo del contexto en el que se definan las variables y/o funciones en el código, estas van a ser de ámbito global o de ámbito local */\n/* Dicho esto, las varibales definidas por fuera de un bloque de código van a ser de ámbito global, pero las varibles o funciones definidas dentro de un bloque de código solo van a poder ser accedidas dentro de ese ámbito */\n\n/*Esta variable pordrá ser accedida en cualquier momento dentro de todo el documento */\nconst global = `Variable global`;\n\nfor (let index = 0; index < 3; index++) {}\n/* La varaible index solo puede ser utilizada dentro del bloque de código del ciclo FOR */\n\n/*Dificultad extra */\n\nfunction dificultadExtra(param1, param2) {\n  let veces = 0;\n  for (i = 0; i <= 100; i++) {\n    if (i % 3 == 0 && i % 5 == 0) {\n      console.log(`${param1 + param2}`);\n    } else if (i % 3 == 0) {\n      console.log(param1);\n    } else if (i % 5 == 0) {\n      console.log(param2);\n    } else {\n      console.log(i);\n      veces++;\n    }\n  }\n\n  return console.log(`El número se imprimió un total de ${veces} veces.`);\n}\n\ndificultadExtra(`texto1`, `texto2`);\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/oscar503sv.js",
    "content": "/* \r\nEJERCICIO 2\r\n- Crea ejemplos de funciones básicas que representen las diferentes posibilidades del lenguaje:\r\n    Sin parametros ni retorno, con uno o varios parámetros, con retorno..\r\n- Comprueba si puedes crear funciones dentro de funciones.\r\n- Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\r\n- Pon a prueba el concepto de variable LOCAL y GLOBAL.\r\n- Debes hacer print por consola del resultado de todos los ejemplos.\r\n\r\nDIFICULTAD EXTRA:\r\n- Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\r\n    - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\r\n    - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\r\n    - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\r\n    - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\r\n    - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\r\n\r\n*/\r\n\r\nconst myName = \"Ozkar\";\r\nconst age = 25;\r\n\r\n// funcion sin parámetros\r\nfunction helloWorld() {\r\n    console.log(\"Hola Mundo\");\r\n}\r\n\r\nhelloWorld();\r\n\r\n// funcion con un parámetro\r\nfunction showName(name) {\r\n    console.log(\"Hola \" + name);\r\n}\r\n\r\nshowName(myName);\r\n\r\n// funcion con varios parámetros\r\nfunction showNameAndAge(name, age) {\r\n    console.log(\"Hola \" + name + \" Tu edad es: \" + age);\r\n}\r\n\r\nshowNameAndAge(myName, age);\r\n\r\n// funcion con retorno\r\nfunction withReturn(name) {\r\n    return `Hola ${name}`;\r\n}\r\n\r\nwithReturn();\r\n\r\n// funcion dentro de otra función\r\nfunction externalFunction() {\r\n    console.log(\"Esta es la función externa\");\r\n\r\n    function innerFunction() {\r\n        console.log(\"Esta es la función interna\");\r\n    }\r\n}\r\n\r\nexternalFunction();\r\n\r\n// Ejemplo de función ya creada en el lenguaje: Math.round()\r\nfunction redondear(numero) {\r\n    return Math.round(numero);\r\n}\r\n\r\nconsole.log(\"Funcion redondear:\", redondear(3.14159)); // Funcion redondear: 3\r\n\r\nconst msg = \"Hola Mundo\";\r\nconst msg2 = \"Mi nombre es Ozkar\";\r\n\r\n// funcion ya creada en el lenguaje\r\nfunction showMessage(msg, msg2) {\r\n    console.log(msg.toUpperCase() + \" \" + msg2.toUpperCase()); // Utiliza una función de JavaScript para convertir el texto a mayúsculas\r\n}\r\n\r\nshowMessage(msg, msg2);\r\n\r\n// Funciones anónimas o lambdas (funciones sin nombre)\r\nconst funcionAnonima = function(a, b) {\r\n    console.log(`Soy una función anónima con parámetros ${a} y ${b}`);\r\n}\r\n\r\nconsole.log(funcionAnonima); // Se obtiene la función anónima\r\nfuncionAnonima(1, 2); // Se ejecuta la función anónima\r\n\r\n// Es posible establecer valores por defecto para los argumentos:\r\nfunction funcionValorPorDefecto(a, b = 'valor por defecto') {\r\n    console.log(`Me llamo ${a} y mi valor es: ${b}`);\r\n}\r\nfuncionValorPorDefecto('Miguel');\r\n\r\n// funcion flecha (arrow function)\r\nvar arrowFunction = () => {\r\n    console.log('Soy una función flecha');\r\n}\r\n\r\n// Variable global\r\nconst globalVariable = \"Soy una variable global\";\r\n\r\nfunction funcExternal() {\r\n  // Variable local\r\n  const localVariable = \"Soy una variable local\";\r\n  console.log(\"Desde la función externa:\", globalVariable); // Acceso a la variable global\r\n  console.log(\"Desde la función externa:\", localVariable); // Acceso a la variable local\r\n}\r\n\r\n// Intentamos acceder a las variables fuera de su alcance\r\nconsole.log(\"Fuera de la función:\", globalVariable); // Acceso a la variable global\r\n//console.log(\"Fuera de la función:\", localVariable); // Esto producirá un error, ya que localVariable está definida solo dentro de la función\r\n\r\n// Llamamos a la función\r\nfuncExternal();\r\n\r\n// EJERCICIO EXTRA\r\n\r\nconst cadena1 = \"Multiplo de 3\";\r\nconst cadena2 = \"Multiplo de 5\";\r\nlet countNumbers = 0;\r\n\r\nfunction calculateMultiples(cadena1, cadena2) {\r\n    for (var i = 1; i <= 100; i++) {\r\n        if (i % 3 === 0 && i % 5 === 0) {\r\n            console.log(cadena1 + \" y \" + cadena2);\r\n        }\r\n        else if (i % 3 === 0) {\r\n            console.log(cadena1);\r\n        }\r\n        else if (i % 5 === 0) {\r\n            console.log(cadena2);\r\n        }\r\n        else {\r\n            console.log(i);\r\n            countNumbers += 1;\r\n        }\r\n    }\r\n}\r\n\r\ncalculateMultiples(cadena1, cadena2);\r\nconsole.log(\"Número de veces que se imprimio un numero: \", countNumbers);"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/othamae.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n\n// FUNCTIONS:\n// 1. Function without parameters and return\nfunction helloWord(){\n    console.log(\"Hello World!\")\n}\n\nhelloWord()\n\n// 2. Function with parameter and return\n\nfunction helloName(name){\n    return `Hello ${name}!`\n}\n\nconsole.log(helloName('Moure'))\n\n// 3. Function with more parameters and return\n\nfunction helloNameAndLanguage(name, language){\n    return `Hello ${name} from ${language}!`\n}\n\nconsole.log(helloNameAndLanguage('Moure', 'JavaScript'))\n\n// 4. Arrow functions\n// without parameters and return\nconst sayHello = () => console.log('Hello World from an arrow function!')\nsayHello()\n\n// with parameters and return\nconst sayHelloWithReturn = (name) => `Hello ${name} from an arrow function!`\n\nconsole.log(sayHelloWithReturn('Moure'))\n\n// 5. Nested functions\nfunction helloNameFromNestedFunction(name){\n    return function nested(type){\n        return `Hello ${name} from a ${type} function!`    \n    }\n}\n\nconsole.log(helloNameFromNestedFunction('Moure')('nested'))\n\n// 6. Arrow functions in nested functions\nfunction helloNameFromArrowInNestedFunction(name){\n    return (type)=>`Hello ${name} from an arrow function in a ${type} function!`      \n}\n\nconsole.log(helloNameFromArrowInNestedFunction('Moure')('nested'))\n\n// 7. Built-in functions examples\nconst string= '60' \nconst n = parseInt(string) // To parse a string in Number\nconsole.log(`Type of ${n} is: ${typeof parseInt(string)}`)\n\n// 8. Global and local variables\n\nconst globalVariable = 'I am a global variable'\n\nfunction localAndGlobal(){\n    const localVariable = 'I am a local variable'\n    console.log(globalVariable)\n    console.log(localVariable)\n}\n\nlocalAndGlobal() \n\ntry {\n    console.log(localVariable)     \n} catch (error) {\n    console.log('Error: ' + error)\n}\n\n\n// EXTRA TASK:\nfunction printFrom1to100(param1, param2){\n    let counter = 0\n    for(let i = 1; i<=100; i++){\n        if (i%3==0 && i%5==0) console.log(param1 + param2)            \n        else if (i%3==0) console.log(param1)           \n        else if (i%5==0) console.log(param2)          \n        else {\n            console.log(i)\n            counter++\n        }\n    }\n    return counter\n}\nconst counter = printFrom1to100('Fizz', 'Buzz')\nconsole.log({counter})"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/parababire.js",
    "content": "//Funciones declarativas\n\n/*Sin Argumentos ni Retorno*/\nfunction saludo() {\n  console.log(\"Hola\");\n}\n\n/*Con Argumentos*/\nfunction saludoExtendido(nombre) {\n  console.log(\"Hola\" + \" \" + nombre);\n}\n\n/*Con Retorno*/\nfunction suma(a, b) {\n  return a + b;\n}\n\nconsole.log(suma(4, 6));\n\n//Funciones expresivas\n\nlet diHola = function () {\n  console.log(\"Hola\");\n}\n\n//Funciones arrow\n\nlet resta = (a, b) => a - b;\n\nconsole.log(resta(5, 2));\n\n//Funciones dentro de funciones\n\nfunction solicitudDeNombre() {\n  let nombre = prompt(\"Dinos tu nombre\", \"Luis\");\n  return nombre;\n}\n\nfunction saludo() {\n  console.log(\"Hola\" + \" \" + solicitudDeNombre());\n}\n\n//Función creada en el lenguaje\n\n/*prompt() es una función propia de javascript al igual que console.log(), etc..*/\nlet nombre = prompt(\"Dinos tu nombre\", \"Luis\");\n\n//Ámbito de variables\n\n/*Variable global edad está disponible de ser usada en otro lugar del código\nactual*/\nlet edad = prompt(\"Ingresa tu edad\", \"30\");\n\n/*Variable local edad solo está disponible dentro de una función */\nfunction edadUsuario() {\n  let edad = prompt(\"Ingresa tu edad\", \"30\");\n  console.log(\"La edad ingresada es: \" + edad + \"años.\");\n}\n\n//Dificultad extra\n\nfunction stringsAndNumbers(txt1, txt2) {\n  let count = 0;\n  for (let i = 1; i <= 100; i++) {\n    if (i % 3 === 0 && i % 5 === 0) {\n      console.log(txt1 + \" \" + txt2);\n    } else if (i % 5 === 0) {\n      console.log(txt2);\n    } else if (i % 3 === 0) {\n      console.log(txt1);\n    } else {\n      console.log(i);\n      count++;\n    };\n  }\n  return count;\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/pedamoci.js",
    "content": "//  ----------------------- FUNCIONES BASICAS -----------------------\n  // Sin parámetros ni retorno\n    function saludar() {  // función normal\n      console.log('Hola, mundo')\n    }\n    const preguntar = ()=> { // función flecha\n      console.log('Todo bien?')\n    }\n    saludar()\n    preguntar()\n\n  // Con parámetros sin retorno\n    function saludoPersonalizado(nombre) {\n      console.log(`Hola, ${nombre}`)\n    }\n    const nacimiento = (edad) => {\n      const actualYear = new Date().getFullYear()\n      console.log('Año de nacimiento: ', actualYear - edad)\n    }\n    saludoPersonalizado('Jaime')\n    nacimiento(98)\n\n  // Con parámetros y retorno\n    function sumar(num1, num2) {\n      return num1 + num2\n    }\n    const multiplicar = (num1, num2) => {\n      return num1 * num2\n    }\n    console.log('Suma: ', sumar(5, 3))\n    console.log('Multiplicación: ', multiplicar(7, 8))\n\n//  ----------------------- FUNCIONES DENTRO DE FUNCIONES -----------------------\n  // Función normal dentro de función normal\n    function areaTrianguloRectangulo(altura, base) {\n      const areaCuadrado = altura * base\n      function area(areaCuadrado) {\n        return areaCuadrado / 2\n      }\n      return area(areaCuadrado)\n    }\n    console.log('Area del triángulo rectángulo: ', areaTrianguloRectangulo(10, 5))\n\n  // Función flecha dentro de función flecha\n    const volumenCilindro = (radio, altura) => {\n      const areaCirculo = (r) => Math.PI * (r ** 2)\n      return areaCirculo(radio) * altura\n    }\n    console.log('Volumen de la cilindro: ', volumenCilindro(3, 10))\n\n  // Función flecha dentro de función normal\n    function areaHexagono(lado, base, hipotenusa) {\n      const perimetro = lado * 6\n      const apotema = (b, h) => {\n        return Math.sqrt((-(b **2)) + (h ** 2))\n      }\n      return (perimetro * apotema(base, hipotenusa)) / 2\n    }\n    console.log('Area del hexágono: ', areaHexagono(6, 10, 12))\n\n  // Función normla dentro de función flecha\n    const areaCirculo = (radio) => {\n      function area(r) {\n        return Math.PI * (r ** 2)\n      }\n      return area(radio)\n    }\n    console.log('Area del círculo: ', areaCirculo(7))\n\n//  ----------------------- FUNCIONES DENTRO DEL LENGUAJE -----------------------\n  console.log('Según la función isFinite 10/3 es finito? ', isFinite(10/3))\n\n//  ----------------------- VARIABLES LOCALES Y GLOBALES -----------------------\n  let global = 'Soy global' // Variable global\n  function bloqueUno () {\n    let localFunction = 'Soy local de función' // Variable local de la función\n    const bloqueDos = () => {\n      let localFunctionFlecha = 'Soy local de función flecha' // Variable local de la función flecha\n      console.log(`La variable global es: ${global}, la variable local de la función es: ${localFunction} y la variable local de la función flecha es: ${localFunctionFlecha}`)\n    }\n    console.log(`La variable global es: ${global}, la variable local de la función es: ${localFunction} y la variable local de la función flecha es: UNDIFINED`)\n    bloqueDos()\n  }\n  console.log(`La variable global es: ${global}, la variable local de la función es: UNDIFINED y la variable local de la función flecha es: UNDIFINED`)\n  bloqueUno()\n\n//  ----------------------- DIFICULTAD EXTRA -----------------------\nfunction impresora(s1, s2) {\n  let cantNumImpresos = 0\n  for (let i = 1; i <= 100; i++) {\n    if (i % 3 === 0 && i % 5 === 0) {\n      console.log(s1 + s2)\n    } else if (i % 3 === 0) {\n      console.log(s1)\n    } else if (i % 5 === 0 ) {\n      console.log(s2)\n    } else {\n      cantNumImpresos++\n      console.log(i)\n    }\n  }\n  return cantNumImpresos\n}\nlet str1 = prompt('ingresa la primera cadena de texto: ')\nlet str2 = prompt('ingresa la segunda cadena de texto: ')\nconsole.log(`Se ha impreso el un número en lugar del texto: ${impresora(str1, str2)} veces`)"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/popmaquin.js",
    "content": "/*........funciones basicas.......*/\n\n//Sin parametro ni retornos.\nfunction func(){\n    console.log(\"Hola mundo, sin parametro ni retornos!\");\n}\n    func();\n\n    // Con retorno\n    function con_retorno() {\n        return (\"La multiplicación de 5*5 es: \"+(5*5)); \n    }\n    con_retorno();\n\n//Con uno parametro.\nfunction saludar(name) {\n    console.log(\"Bienvenido \" + name);\n}\n    saludar(\"Elena\"); // Salida: \"Bienvenido Elena\"\n\n//Con dos argumentos\nfunction sumar(num1, num2) {\n    console.log(\"La suma de \" + num1+\"+\"+ num2+ \" es: \"+ (num1+num2));\n}\n\nsumar(5,5); // 5+5 = 10\n\n//funciones con argumentos y retorno.\n\nlet numero1= parseInt(prompt(\"ingrese un numero: \"));          //las variables numero1 y numero2 guardan\nlet numero2= parseInt(prompt(\"ingrese el segundo numero: \"));  //los valores ingresados por el usuario. Funcion parseInt convierte los valores a enteros.\n\nconst funcConArgumentos= function(numero1, numero2) {\n    return (numero1+\"+\"+numero2+\" es: \"+(numero1+numero2));  \n}\nfuncConArgumentos(numero1,numero2); // se invoca la funcion.\n\n\n//funciones anonimas\nconst operacion_suma= function() { \n    return (\"Funcion anonima para sumar 5+5 es: \"+(5+5));   \n}\noperacion_suma();  // salida: 10 Se llama por la constante operacion_suma.\n\n// funcion flecha. omite la palabra reservada function por la flecha.\nconst restar= () =>{ \n    return (\"Funcion flecha para restar 5-2 es: \"+ (5-2));   \n}\nrestar();\n\n/*.............funciones dentro de funciones.............*/ \n\n/*Primero se crea una funcion que recibe los datos al usuario.\n* Segundo la funcion ingresarDatos... \n* dentro la funccion ingresarDatos se crea la tercera funcion que realiza la suma.\n*/\nfunction obtenerdatos(){\n    let numero1= parseInt(prompt(\"ingrese un numero: \"));\n    let numero2= parseInt(prompt(\"ingrese el segundo numero: \"));\n    return [numero1,numero2];\n}\nfunction ingresarDatos() {\n    let [num1, num2] = obtenerdatos();\n    let total=0;\n    function opsumar() {\n        total= num1+num2;\n        console.log(\"La suma de \"+num1 + \" + \" + num2 + \" es: \" + total);\n    }\n    opsumar();\n}\ningresarDatos(); // se manda llamar la funcion.\n\n/*.............funciones propias del lenguaje.............*/ \n\nlet cadena = \"Hola mundo, Javascript\";\n\nconsole.log(cadena.split(\",\")); //divide la cadena en un array apartir de un caracter separador. \n                                //Salida: [\"hola mundo\",\"Javascript\"]\n\nconsole.log(cadena.substring(0,3)); //extrae la información a opartir de un indece A a B sin incluir.\n                                //Salida: Hol\n\nconsole.log(typeof(\"20\")); //salida: 'string'  ---Indica el tipo de datos.\ntypeof(parseInt(\"20\")); //salida: number, ---convierte a numero entero.\n\n/*.............variable local y global.............*/\n\nlet variable_global= \"variable golobal\"\n\nfunction holaMundo() {\n    let variable_local= \"Hola soy variable local. Ejecucion de la función holaMundo()\"\n    console.log(variable_local);\n    console.log(\"Soy una variable global. Ejecucion dentro de la función holaMundo() \" +variable_global);\n    \n}\nholaMundo();\ntry {\n    console.log( \"Accediendo a la viarible local, afuera de la funcion holaMundo() \"+ variable_local);\n} catch (error) {\n    console.log(\"Imposible acceder a una variable local, fuera de holaMundo()\")\n}\n\n/*.............Dificultad Extra.............*/ \n/*Imprime numero de 1 hasta 100 pero si es multipo de 3 imprime primer texto, \n* si es multipo de 5 imprime segundo texto y si son ambos concatena textos.\n* la variable contador indica la veces que se imprime los numeros.\n*/\nfunction generarNumero(txt1, txt2) {\n    let contador=0;\n      for (let index = 1; index <= 100; index++) {\n          if (index%3==0 && index%5==0) {\n                  console.log(txt1 + txt2);\n          }else if(index%3==0){\n              console.log(txt1);\n          }else if(index%5==0){\n              console.log(txt2);\n          }else {\n               console.log(index); \n              contador++;\n          }\n  \n            }  \n  return (console.log(\"Total numeros impresos: \"+contador)); \n      }\n  \n  generarNumero(\"uno\", \"dos\"); // los textos se puede cambiar.\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/ppinilla.js",
    "content": "/*\n EJERCICIO:\n - Crea ejemplos de funciones básicas que representen las diferentes\n   posibilidades del lenguaje:\n   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n - Comprueba si puedes crear funciones dentro de funciones.\n - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n - Debes hacer print por consola del resultado de todos los ejemplos.\n   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n\n DIFICULTAD EXTRA (opcional):\n Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n \n Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n //Funciones básicas\n function sinP(){\n    console.log(\"Esta es una función sin parámetros ni retorno\");\n };\n\n sinP();\n\n function con1P(num1){\n    console.log(`Esta es una función con ${num1} parámetro`);\n };\n\n con1P(1);\n\n function conMasP(num1, num2){\n    console.log(`Esta es una función con ${num1} parámetros y ${num2} retornos`);\n };\n\n conMasP(2,0);\n \n function conR(num1) {\n    return 1\n };\n\n console.log(`Esta es una función con ${conR()} retorno`);\n \n //Funciones dentro de funciones\n function calcularDescuento(precio) {\n    const descuento = 15;\n\n    function descontar(precio) {\n        return (precio * descuento)/100;\n    }\n    \n    const total = precio - descontar(precio);\n    return total;\n };\n\n const totalDescuento = calcularDescuento(120);\n console.log(`El precio con el 15% de descuento es: ${totalDescuento}`);\n\n //Funciones ya creadas en el lenguaje\n\n function valNaN(x) {\n    if (isNaN(x)) {\n        console.log('!No es un número¡');\n    } else {\n        console.log(`El número es: ${x}`)\n    };\n };\n\n valNaN(NaN);\n valNaN(900);\n\n function valFinite(x) {\n    if (isFinite((1000 / x))) {\n        console.log('No es un número infinito');\n    } else {\n        console.log('El número es inifinito');\n    };\n };\n\n valFinite(0);\n valFinite(10);\n\n //Variable LOCAL y GLOBAL\n\n var global = 'Variable global';\n\n function declaracionVariables() {\n   try {\n      let local = 'Variable local';\n      console.log(global);\n      console.log(local);\n\n      global = 'Variable global modificada';\n   } catch (error) {\n      console.log('Error detectado:', error.message);\n   }\n      \n };\n\n declaracionVariables();\n console.log(global);\n\n try {\n   console.log(local);\n } catch (error) {\n   console.log('Error detectado al acceder a \"local\" fuera de la función:', error.message);\n }\n\n\n /*\n Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n - La función retorna el número de veces que se ha impreso el número en lugar de los textos\n*/\n\nlet cadena1 = 'Múltiplo de 3';\nlet cadena2 = 'Múltiplo de 5';\nlet count = 0;\n\nfunction CadenaNumero() {\n   for (let i = 1; i <= 100; i++) {\n      if (i % 3 == 0 && i % 5 == 0) {\n         console.log(cadena1 + ' y ' + cadena2);\n      } else if (i % 5 == 0) {\n         console.log(cadena2);\n      } else if (i % 3 == 0) {\n         console.log(cadena1);\n      } else {\n         count++;\n         console.log(i);\n      }\n   }\n   console.log('Números entre 1 y 100 que no son múltiplos de 3 ni de 5:', count);\n   \n};\n\nCadenaNumero();\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/pype-Dev.js",
    "content": "/**\n * FUNCIONES DEFINIDAS POR EL USUARIO\n */\n\n//A. Función sin parámetros ni retorno\nfunction greet(){\n    console.log(\"¡Esto es una funcion básica!\");\n}\n\ngreet();\n\n//B. Función con parámetros y sin retorno\nfunction suma(a, b){\n    console.log(a + b);\n}\n\nsuma(100, 60);\n\n//C. Función sin parámetros y con retorno\nfunction square(){\n    let side = 5;\n    return side * side;\n}\n\nformula = square();\n\n//D. Función con parámetros y con retorno\nfunction calcularIVA(precio){\n    const baseIva = 0.19;\n    return precio * baseIva;\n}\n\ncalcularIVA(5200);\n\n//E. Función Expresiva\nconst calcularArea = function(base, altura){\n    return base * altura;\n}\n\ncalcularArea(5, 10);\n\n//F. Función de Flecha\nconst saludar = name => `Hola ${name}!`; //Un solo parámetro\nconst mensaje = saludar(\"Mundo\");\nconsole.log(mensaje);\n\nconst despedir = () => \"Adiós\"; //Sin parámetros\ndespedir();\n\nconst module = (a, b) => a % b; //Una línea\nmodule(9, 3);\n\nconst multiplicar = (x, y) => {\n    let operacion = x * y;\n    return operacion;\n}\nmultiplicar(5, 8);\n\n//G. Función con Parámetros Predeterminados\nfunction configPuerto(puerto = 3000){\n    return `Puerto utilizado: ${puerto}`;\n}\n\nconfigPuerto();         //3000\nconfigPuerto(5000);     //5000\n\n//H. Función con Parámetros Rest\nfunction consecutivo (...numeros){\n    let total = \"\";\n\n    for(const numero of numeros){\n        total += `Número ${numero} \\n`;\n    };\n\n    return total;\n};\n\nconst menssage = consecutivo (1, 2, 3, 4, 5);\nconsole.log(menssage);\n\n//Funciones Anidadas\nfunction outerFunction(name){\n    //variable externa\n    const output_message = \"Hola\";\n\n    //Declaración funcion interna\n    function innerFunction(){\n        console.log(output_message + \", \" + name);\n    }\n\n    //invocación de la funcion interna dentro de la externa\n    innerFunction();\n}\n\nouterFunction(\"Diego\");\n\n/**\n * BUILT-IN OBJECTS\n */\nparseInt('1010', 2); //10\nparseFloat('3.1416'); //3.1416\nisNaN('A'); //True\nisNaN(1); //False\nisFinite(Math.PI); //true\neval('2 + 2'); //4\nlet builtInObhects; //undefinied\nMath.sqrt(16); //4\nencodeURI(\"https://eltiempo noticias.co/\"); //'https://eltiempo%20noticias.co/'\ndecodeURI(\"https://eltiempo%20noticias.co/\"); //'https://eltiempo noticias.co/'\n\n/**\n * DIFICULTAD EXTRA\n */\nfunction printNumber(str1, str2){\n    let contador = 0;\n\n    for(let i = 1; i <= 100; i++){\n        if(i % 3 === 0 && i % 5 === 0){\n            console.log(str1 + str2);\n        } else if(i % 3 === 0){\n            console.log(str1);\n        } else if(i % 5 === 0){\n            console.log(str2);\n        } else{\n            console.log(i);\n            contador += 1;\n        }\n    }\n\n    return contador;\n}\n\nconsole.log(printNumber('Fizz', 'Buzz'));\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/qwik-zgheib.js",
    "content": "/* -- exercise */\nconst greet = () => console.log(\"Hello, world!\");\n\ngreet();\n\nconst square = (number) => number * number;\n\nlet result = square(5);\nconsole.log(\"Square of 5:\", result);\n\nconst outerFunction = () => {\n  console.log(\"Outer function is executing.\");\n  const innerFunction = () => console.log(\"Inner function is executing.\");\n  innerFunction();\n};\n\nouterFunction();\n\nlet globalVariable = \"I'm global\";\n\nfunction localGlobalExample() {\n  let localVariable = \"I'm local\";\n  console.log(\"Inside function:\");\n  console.log(\" - Local variable:\", localVariable);\n  console.log(\" - Global variable:\", globalVariable);\n}\n\nlocalGlobalExample();\n\nconsole.log(\"Outside function - Global variable:\", globalVariable);\n\nlet randomNumber = Math.random();\nconsole.log(\"Random number:\", randomNumber);\n\n/* -- extrta challenge */\nfunction printNumbersAndCount(text1, text2) {\n  let count = 0;\n\n  for (let i = 1; i <= 100; i++) {\n    if (i % 3 === 0 && i % 5 === 0) {\n      console.log(text1 + text2);\n      count++;\n    } else if (i % 3 === 0) {\n      console.log(text1);\n      count++;\n    } else if (i % 5 === 0) {\n      console.log(text2);\n      count++;\n    } else console.log(i);\n  }\n\n  return count;\n}\n\nlet count = printNumbersAndCount(\"Fizz\", \"Buzz\");\nconsole.log(\"Number of times text has been printed:\", count);\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/r4kso.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n */\n\n// Función sin parámetros ni retorno\nfunction hello() {\n    console.log(\"¡Hola Mundo! Soy r4kso\")\n}\nhello()\n\n// Función con un parámetro y sin retorno\nfunction showNumber(number) {\n    n = number;\n    console.log(`El número es: ${n}`)\n}\nshowNumber(69);\n\n// Función con varios parámetros y sin retorno\nfunction addNumbers(a, b) {\n    let add = a + b;\n    console.log(`La suma de ${a} (a) y ${b} (b) es: ${add}`)\n}\naddNumbers(34, 35)\n\n// Función sin parámetros y con retorno\nfunction getNumber() {\n    return 7\n}\nconsole.log(\"El número obtenido es: \" + getNumber())\n\n// Función con un parámetro y con retorno\nfunction getNumberByParam(a) {\n    return a;\n}\nconsole.log(\"El número pasado por parámetro a la función es: \" + getNumberByParam(13))\n\n// Función con varios parámetros y con retorno\nfunction substractionByParam(a, b) {\n    return a - b;\n}\nconsole.log(\"La resta del primer parámetro menos el segundo parámetro es: \" + substractionByParam(71, 2))\n\n// Función dentro de una función (anidada)\nfunction functionOne(a) {\n    return function functionTwo(b) {\n        return a + b;\n    }\n};\nconsole.log(\"El resultado de la suma mediante funciones anidadas es: \" + functionOne(40)(29));\n\n// Variable global\nvar a = 10\nfunction globalVariable() {\n    console.log(\"El valor de la variable global es: \" + a);\n};\n\n// Variable local\nfunction localVariable() {\n    var a = 20;\n    console.log(\"El valor de la variable local es: \" + a);\n};\n\n// Math.max y Math.min (máximo y mínimo de un conjunto de números)\nvar num1 = 10;\nvar num2 = 5;\nvar num3 = 8;\nvar maximo = Math.max(num1, num2, num3);\nvar minimo = Math.min(num1, num2, num3);\nconsole.log(\"El máximo es: \" + maximo + \", y el mínimo es: \" + minimo);\n\n// Math.abs (valor absoluto de un número)\nvar numeroNegativo = -7;\nvar valorAbsoluto = Math.abs(numeroNegativo);\nconsole.log(\"El valor absoluto de \" + numeroNegativo + \" es: \" + valorAbsoluto);\n\n// Variable flecha\nconst noArgs = () => console.log(\"¡Hola Mundo! Mediante el uso de flechas\");\nnoArgs();\n\n/*\n* DIFICULTAD EXTRA (opcional):\n* Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n* - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n*   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n*   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n*   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n*   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n*/\n\nfunction exercise(a, b) {\n    let count = 0;\n\n    for(let i = 1; i <= 100; i++) {\n        let threeMultiple = i % 3 === 0;\n        let fiveMultiple = i % 5 === 0;\n\n        if (threeMultiple && fiveMultiple) {\n            console.log(a + b);\n        }else if (threeMultiple) {\n            console.log(a);\n        } else if (fiveMultiple) {\n            console.log(b)\n        } else {\n            console.log(i);\n            count++;\n        }\n    }\n    \n    return count;\n}\n\nconsole.log(\"Numero de veces que se ha impreso un número: \" + exercise(\"Hola\", \"Mundo\"));"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/ralphmcralph.js",
    "content": "// Funciones\r\n\r\n// Funciones básicas\r\n\r\n// Con retorno\r\nfunction square(number) {\r\n    return number * number;\r\n}\r\n\r\n// Sin retorno\r\n\r\nconst myCar = {\r\n    make: \"Aston Martin\",\r\n    model: \"AMR25\",\r\n    year: 2025\r\n}\r\n\r\nfunction changeMake(newMake) {\r\n    newMake.make = \"Honda\";\r\n}\r\n\r\nconsole.log(myCar.make);\r\nchangeMake(myCar);\r\nconsole.log(myCar.make);\r\n\r\n// Nested function\r\n\r\nfunction addSquares(a, b) {\r\n    function square(x) {\r\n        return x * x;\r\n    }\r\n    return square(a) + square(b);\r\n}\r\n\r\nconsole.log(addSquares(2, 4));\r\n\r\n// Con retorno de varios valores\r\n\r\nfunction multipleReturn() {\r\n    return [\"Hola\", \"Javascript\"]\r\n}\r\n\r\nconsole.log(multipleReturn());\r\n\r\n[greet, language] = multipleReturn();\r\n\r\nconsole.log(greet);\r\nconsole.log(language);\r\n\r\n// Función con argumentos variables\r\n\r\nfunction variableArgs(...names) {\r\n    return names.map((name) => {\r\n        console.log(`Hola ${name}`);\r\n    })\r\n}\r\n\r\nvariableArgs(\"Python\", \"Javascript\", \"Ruby\", 1);\r\n\r\n// Ejemplos de funciones ya creadas en el lenguaje\r\n\r\n// Console.log\r\n\r\nconsole.log(\"Esto es una built-in function de Javascript\");\r\n\r\n// Length\r\n\r\nconsole.log(\"Javascript\".length);\r\n\r\n// Tipo\r\nconsole.log(typeof (\"Javascript\"));\r\n\r\n// Manipulación de strings\r\n\r\nconsole.log(\"Javascript\".toUpperCase());\r\nconsole.log(\"Javascript\".toLowerCase());\r\n\r\n// Puesta a prueba del concepto de LOCAL y GLOBAL\r\n\r\nvar variableGlobal = \"Javascript\";\r\n\r\nconsole.log(variableGlobal);\r\n\r\nfunction helloJS() {\r\n    var variableLocal = \"Hola\"\r\n    console.log(`${variableLocal}, ${variableGlobal}`);\r\n}\r\n\r\nhelloJS();\r\n\r\n// console.log(variableLocal); # No se puede acceder desde fuera de la función\r\n\r\n/*\r\n * DIFICULTAD EXTRA(opcional):\r\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\r\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\r\n * - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\r\n * - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\r\n * - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\r\n * - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\r\n *\r\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\r\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\r\n */\r\n\r\nfunction extra(str1, str2) {\r\n    count = 0;\r\n\r\n    for (i = 1; i <= 100; i++) {\r\n        if (i % 3 == 0 && i % 5 == 0) {\r\n            console.log(str1 + str2);\r\n        } else if (i % 5 == 0) {\r\n            console.log(str2);\r\n        } else if (i % 3 == 0) {\r\n            console.log(str1);\r\n        } else {\r\n            console.log(i);\r\n            count += 1;\r\n        }\r\n    }\r\n\r\n    return count;\r\n}\r\n\r\nextra(\"Fizz\", \"Buzz\");\r\n\r\nvar resultado = extra(\"Fizz\", \"Buzz\")\r\n\r\nconsole.log(\"Resultado: \" + resultado);\r\n\r\n\r\n\r\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/raulG91.js",
    "content": "\n//Simple\nfunction sayHello(){\n\n    console.log(\"Hello World!\");\n}\nconsole.log(\"Function without parameter and without return\");\nsayHello();\n//With retrun a not parameter\nfunction sayHello2(){\n    return \"Hello Team!\";\n}\nconsole.log(\"Function without parameter and with return\");\nconsole.log(sayHello2());\n//With parameters not return\nfunction sumNumber(a,b){\n    let result = a+b;\n    console.log(result)\n}\nconsole.log(\"Function with parameters and not return\");\nsumNumber(2,3);\n\n//With parameters and return\nfunction multiplyNumbers(a,b){\n    return a*b;\n}\nconsole.log(\"Function with parameters and return\");\nlet result = multiplyNumbers(2,3);\nconsole.log(result);\n\n//Function with default parameters\nfunction default_parameter(phrase=\"Hello world\"){\n\n    console.log(phrase);\n}\n\nconsole.log(\"Function with default parameter\");\ndefault_parameter();\ndefault_parameter(\"This is a function\");\n\n//Nested functions\nfunction main_function(){\n\n    function nested_function(){\n\n        console.log(\"Hello from nested function\");\n    }\n\n    nested_function();\n}\n\nconsole.log(\"Nested function\");\nmain_function();\n\n// Javascript functions\nlet a = 3;\nconsole.log(\"Function typeof\");\nconsole.log(typeof(a));\n\nlet string = \"This is an string\";\nlet array = string.split(\" \");\nconsole.log(\"Split function\");\nconsole.log(array);\n\nlet variable = 6\n\nfunction modify_variable(){\n\n    let variable = 10;\n    console.log(variable);\n}\n\nmodify_variable();\nconsole.log(\"Original variable \" + variable);\n\n//Extra exercise\n\nfunction print_numbers(string1,string2){\n\n    let numbers = 0;\n\n    for(let i=1;i<=100;i++){\n\n        if(i%3 == 0 && i %5 == 0){\n            console.log(string1+string2);\n        }\n        else if (i%3==0){\n            console.log(string1);\n        }\n        else if (i%5==0){\n            console.log(string2);\n        }\n        else{\n            console.log(i);\n            numbers++;\n        }\n    }\n\n    return numbers;\n}\n\nlet numbers = print_numbers(\"fizz\",\"buzz\");\n\nconsole.log(numbers);\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/reinaldosanchez.js",
    "content": "//Ejemplos de funciones \n// 1. Sin parámetros ni retorno\nfunction saludar() {\n    console.log(\"¡Hola, JavaScript!\");\n}\n\n// 2. Con parámetros pero sin retorno\nfunction saludarPersona(nombre) {\n    console.log(\"Hola, \" + nombre);\n}\n\n// 3. Con parámetros y retorno\nfunction sumar(a, b) {\n    return a + b;\n}\n\n// 4. Función flecha\nconst restar = (a, b) => a - b;\n\n// 5. Función flecha con parámetros por defecto\nconst multiplicar = (a, b = 1) => a * b;\n\n// 6. Función flecha con múltiples líneas\nconst dividir = (a, b) => {\n    if (b === 0) {\n        throw new Error(\"No se puede dividir por cero\");\n    }\n    return a / b;\n};\n\n// 7. Función flecha con parámetros rest\nconst sumarTodos = (...numeros) => {\n    return numeros.reduce((acumulador, numero) => acumulador + numero, 0);\n};\n\n// 8. Función flecha con parámetros spread\nconst duplicarTodos = (numeros) => {\n    return numeros.map(numero => numero * 2);\n};\n\n// 9. Función flecha con parámetros por defecto y spread\nconst sumarConSpread = (a, b, ...numeros) => {\n    return a + b + numeros.reduce((acumulador, numero) => acumulador + numero, 0);\n};\n\n// 10. Función flecha con parámetros por defecto y rest\nconst restarConRest = (a, b = 0, ...numeros) => {\n    return a - b - numeros.reduce((acumulador, numero) => acumulador + numero, 0);\n};\n\n//funcion dentro de otra funcion\nfunction funcionExterna() {\n    console.log(\"Estoy en la externa\");\n\n    function funcionInterna() {\n        console.log(\"Estoy en la interna\");\n    }\n\n    funcionInterna(); // Se llama dentro\n}\nfuncionExterna(); // Se llama fuera\n\n//variables globales y locales\nlet variableGlobal = \"Soy global\";\n\nfunction pruebaScope() {\n    let variableLocal = \"Soy local\";\n    console.log(variableGlobal); // Funciona\n    console.log(variableLocal);  // Funciona\n}\n\npruebaScope();\n// console.log(variableLocal); // ¡ERROR! No existe fuera de la función \n\n//retos\nfunction ejercicioExtra(texto1, texto2) {\n    let contadorNumeros = 0;\n\n    for (let i = 1; i <= 100; i++) {\n        // ¿Es múltiplo de 3 y de 5? (15, 30, 45...)\n        if (i % 3 === 0 && i % 5 === 0) {\n            console.log(texto1 + texto2);\n        }\n        // ¿Es múltiplo de 3?\n        else if (i % 3 === 0) {\n            console.log(texto1);\n        }\n        // ¿Es múltiplo de 5?\n        else if (i % 5 === 0) {\n            console.log(texto2);\n        }\n        // Si no es ninguno de los anteriores\n        else {\n            console.log(i);\n            contadorNumeros++; // Sumamos uno al contador\n        }\n    }\n\n    return contadorNumeros;\n}\n\n// Para probarlo:\nlet resultado = ejercicioExtra(\"Fizz\", \"Buzz\");\nconsole.log(\"Veces que se imprimió un número: \" + resultado);"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/rlores-edison.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n */\n \n \n\n\n// Función sin parámetros ni retorno;\n// Retorna el valor de la expresión que se le pasa como parámetro.\n\nfunction felicitar() {\n    console.log(\"¡Felices fiestas!\");\n}\nfelicitar();\n\n\n// Función con un parámetro;\nfunction morning (nombre) {\n  console.log(\"¡Buenos días, \"+nombre+ \"!\");\n}\nmorning(\"Raúl\");\n\n\n// Función add tiene dos parámetros (a, b). \n// Los argumentos (2, 3) se asignan a los parámetros a y b.\nfunction add (a, b) {\n  return a + b;\n}\nconsole.log(add(2,3)); \n\n//Función dentro de función\nfunction calcularAreaTriangulo(base, altura) {\n  function calcularArea() {\n      return 0.5 * base * altura;\n  }\n  \n  return calcularArea();\n}\n\n// Usando la función\nlet area = calcularAreaTriangulo(5, 3);\nconsole.log(\"El área del triángulo es:\", area);\n\n\n// Ejemplos de funciones ya creadas en el lenguaje:\nconsole.log(\"Funciones creadas en javascript\");\n\n// Función isFinite() determina si el valor pasado es un número finito. \n// Si el valor no es un número, primero intenta convertirlo a uno. \n// Si es un número finito, devuelve true; en caso contrario, devuelve false.\nconsole.log(isFinite(10));        // true (10 es un número finito)\nconsole.log(isFinite(-5.5));      // true (-5.5 es finito)\nconsole.log(isFinite(Infinity)); // false (Infinity no es finito)\nconsole.log(isFinite(NaN));      // false (NaN no es un número finito)\nconsole.log(isFinite(\"10\"));     // true (El string \"10\" se convierte a número)\nconsole.log(isFinite(\"Hello\"));  // false (No puede convertirse en número)\nconsole.log(isFinite(undefined));// false (No puede convertirse en número)\n\n//Función isNaN() determina si el valor pasado es NaN (Not-a-Number). \n// Si el valor no es un número, intenta convertirlo. \n// Si después de la conversión sigue siendo NaN, devuelve true; de lo contrario, devuelve false.\nconsole.log(isNaN(NaN));        // true (El valor es NaN)\nconsole.log(isNaN(\"Hello\"));    // true (No puede convertirse a número)\nconsole.log(isNaN(undefined)); // true (No puede convertirse a número)\nconsole.log(isNaN(10));         // false (10 es un número válido)\nconsole.log(isNaN(\"10\"));       // false (El string \"10\" se convierte a número)\nconsole.log(isNaN(true));       // false (true se convierte a 1, que es un número)\n\n// Función Number.isNaN() es más estricto y devuelve true sólo si el valor es exactamente NaN, sin coerción.\nconsole.log(Number.isNaN(\"Hello\"));  // false (Strict check: \"Hello\" is not NaN, it's a string)\n\n//Función parseInt() convierte una cadena de texto en un número entero.\n// Si la cadena no contiene un número, devuelve el valor de defaultValue.\n// Si la cadena contiene un número, devuelve el número. Si la cadena no puede ser convertida a número, devuelve NaN.\nconsole.log(parseInt(\"10\")); // 10\nconsole.log(parseInt(\"Hello\")); // 0\nconsole.log(parseInt(\"10\", 16)); // 16\nconsole.log(parseInt(\"10\", 10)); // 10\nconsole.log(parseInt(\"0x10\", 16)); // 16\nconsole.log(parseInt(\"010\", 2)); // 2\n\n\n//Variable local, declarada en la función y variable global o declarada fuera de la función.\n\nfunction globalVariable() {\n  var globalVariable = \"globalVariable\";\n  function localVariable() {\n    var localVariable = \"localVariable\";\n    console.log(globalVariable); // globalVariable\n    console.log(localVariable); // localVariable\n  }\n  localVariable();\n}\nglobalVariable();\n\n\n// Global variables\nvar street = \"Calle Mayor\";\nvar city = \"Madrid\";\n\nfunction myGlobalAddress() {\n\n  // Local variables\n  var country = \"España\";\n  var building = \"III\";\n    \n    return building + \" \" + street + \", \" + city + \", \" + country; \n}\n\nconsole.log(myGlobalAddress()); // invocamos desde fuera de la función\n\nfunction myLocalDetails() {\n    var floor = \"3rd-floor\";\n    var flat = \"1B\";\n    var door = \"left\";\n    console.log( floor + \" \" + flat + \" \" + door ); // invocamos desde dentro de la función\n}\n\nmyLocalDetails(); // podemos invocar myLocalDetails desde fuera, pero no podemos acceder a las variables dentro de la función. \n// Las variables son locales de esa función.\n\n\n/*DIFICULTAD EXTRA (opcional):\n* Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n* - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n*   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n*   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n*   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n*   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n*/\nfunction myString (multiploDe3, multiploDe5) {\n  let count = 0;\n  let i = 1;\n    \n  while (i <= 100) {\n    if (i % 3 === 0 && i % 5 === 0) {\n      console.log(multiploDe3 + \" y \" + multiploDe5);\n      count++;\n  } else if (i % 3 === 0) {\n      console.log(multiploDe3);\n      count++;\n  } else if (i % 5 === 0) {\n      console.log(multiploDe5);\n      count++;\n  } else {\n      console.log(i);\n  }\n        i++;\n    }\n    return count;\n}\n\nconsole.log(myString(\"Multiplo de 3\", \"Multiplo de 5\"));"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/robmxz.js",
    "content": "/*#02 FUNCIONES Y ALCANCE*/\n\n// Funciones sin argumentos\nfunction noArgs() {\n  console.log(\"Hola Mundo\");\n}\nnoArgs();\nconsole.log(\"-\".repeat(30));\n\n// Funciones con un argumento\nfunction oneArg(arg) {\n  console.log(`Hola ${arg}`);\n}\noneArg(\"RobMxz\");\nconsole.log(\"-\".repeat(30));\n\n// Funciones con varios argumentos\nfunction variosArgs(...args) {\n  for (let i = 0; i < args.length; i++) {\n    console.log(args[i]);\n  }\n}\nvariosArgs(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);\nconsole.log(\"-\".repeat(30));\n\n// Funciones anidadas\nfunction Anidada(arg1) {\n  return function Anidada2(arg2) {\n    return arg1 + arg2;\n  };\n}\nconsole.log(Anidada(2)(3));\nconsole.log(\"-\".repeat(30));\n\n// Variables globales y locales\nvar a = 10;\n\nfunction global() {\n  console.log(a);\n}\nglobal();\nconsole.log(\"-\".repeat(30));\n\nfunction local() {\n  var a = 20;\n  console.log(a);\n}\nlocal();\nconsole.log(\"-\".repeat(30));\n\n// Funciones flecha\n\n// Funciones flecha sin argumentos\nconst noArgs2 = () => console.log(\"Hola Mundo\");\nnoArgs();\nconsole.log(\"-\".repeat(30));\n\n// Funciones flecha con un argumento\nconst oneArg2 = (arg) => console.log(`Hola ${arg}`);\noneArg(\"Comunidad\");\nconsole.log(\"-\".repeat(30));\n\n// Funciones flecha con varios argumentos\nconst variosArgs2 = (...args) => {\n  for (let i = 0; i < args.length; i++) {\n    console.log(args[i]);\n  }\n};\nvariosArgs(\"Hola\", \"Mundo\", \"¿\", \"Como\", \"Estan\", \"?\");\nconsole.log(\"-\".repeat(30));\n\n// Funciones flecha anidadas\nconst Anidada2 = (arg1) => (arg2) => arg1 + arg2;\nconsole.log(Anidada2(2)(3));\nconsole.log(\"-\".repeat(30));\n\n// Variables globales y locales en funciones flecha\nconst global2 = () => console.log(a);\nglobal2();\nconsole.log(\"-\".repeat(30));\n\nconst local2 = () => {\n  var a = 20;\n  console.log(a);\n};\n\n// Dificultad extra :)\n\n/*\n    Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n    -La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n    -Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n    -Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n    -Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n    -La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n*/\n\nfunction extra(arg1, arg2) {\n  let contador = 0;\n  for (let i = 1; i <= 100; i++) {\n    console.log(i);\n    if (i % 3 == 0 && i % 5 == 0) {\n      console.log(arg1, arg2);\n      continue;\n    }\n    if (i % 3 == 0) {\n      console.log(arg1);\n      continue;\n    }\n    if (i % 5 == 0) {\n      console.log(arg2);\n      continue;\n    }\n    contador++;\n  }\n  return contador;\n}\nconsole.log(\n  \"Número de veces que se ha impreso el número:\",\n  extra(\"Retos de Programación\", \"JavaScript\")\n);\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/saicobys.js",
    "content": "/* Ejemplos de funciones basicas */\n\n/* Función sin parámetros y sin retorno: */\nfunction saludar() {\n  console.log(\"Hello!\");\n}\n\nsaludar();\n\n/* Función con parámetros y sin retorno: */\nfunction saludarConNombre(nombre) {\n  console.log(\"Hello \" + \"!\");\n}\n\nsaludarConNombre(\"Juan\");\n\n/* Función con parámetros y retorno: */\nfunction sumar(num1, num2) {\n  return num1 + num2;\n}\n\nlet resultado = sumar(9, 7);\nconsole.log(resultado);\n\n/* Función autoejecutable: */\n(function () {\n  console.log(\"Función autoejecutable\");\n})();\n\n/* Función flecha */\nconst saludarFlecha = (nombre) => {\n  console.log(\"Hello \" + \"!\");\n};\n\nsaludarFlecha(\"Maria\");\n\n/* Función constructora de objetos: */\nfunction crearPersona(nombre, apellido, edad) {\n  return {\n    nombre: nombre,\n    apellido: apellido,\n    edad: edad,\n    presentarse: function () {\n      console.log(\n        \"Hola, mi nombres es \" +\n          this.nombre +\n          \" \" +\n          this.apellido +\n          \" y tengo \" +\n          this.edad +\n          \" años.\"\n      );\n    },\n  };\n}\n\nlet persona1 = crearPersona(\"Ana\", \"Moronta\", 30);\npersona1.presentarse();\n\n/* funciones anidadas */\nfunction saludarExterior(nombre) {\n  console.log(\"Hola \" + nombre + \" desde la función exterior.\");\n\n  function saludarInterior() {\n    console.log(\"Hola \" + nombre + \" desde función interior.\");\n  }\n  saludarInterior();\n}\n\nsaludarExterior(\"Pedro\");\n\n/* Funciones ya creadas en el lenguaje */\n\n/* ALERTA */\nalert(\"DOMINICANA ES EL MEJOR PAIS\");\n\n/* Función Math.random(): */\n\nlet numeroAleartorio = Math.random();\nconsole.log(numeroAleartorio);\n\n/* Funciones locales y globsales */\n\n/* Función Local */\nfunction saludarLocal(nombre) {\n  let mensaje = \"Hola \" + nombre + \"!\";\n  console.log(mensaje);\n}\n\nsaludarLocal(\"Ana\");\nconsole.log(mensaje); // La variable 'mensaje' no es accesible fuera de la función.\n\n/* Función global */\n\nlet nombreGlobal = \"Pedro\";\n\nfunction saludarGlobal() {\n  console.log(\"Hola \" + nombreGlobal + \" desde la función global!\");\n}\n\nsaludarGlobal(); // Imprime: Hola Pedro desde la función global!\nconsole.log(nombreGlobal); // Imprime: Pedro\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/sandracalatayud.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n*/\n\n// !  -------- EJERCICIO 1 --------\n\n/*\n    * 1. \n    * Crea ejemplos de funciones básicas que representen las diferentes\n    * posibilidades del lenguaje:\n    * Sin parámetros ni retorno, con uno o varios parámetros, con retorno... \n*/\n\n//Función normal\nfunction printConsola () {\n    console.log(\"Hola\");\n}\n\nprintConsola();\n\n//Función con parámetros\nfunction printConsolaParam (mensaje) {\n    console.log(mensaje);\n}\n\nprintConsolaParam(\"Hola\");\n\n//Función con return\nfunction suma (valor1, valor2) {\n    return valor1 + valor2\n}\n\nconsole.log(suma(3,5));\n\n/*\n    * 2.\n    * Comprueba si puedes crear funciones dentro de funciones.\n*/\n\nfunction printScores () {\n    score1 = 3\n    score2 = 4\n\n    function formatScores(){\n        return console.log(\"Puntuación 1: \"+ score1 + \"\\n\" + \"Puntuación 2: \"+ score2);\n    }\n\n    return formatScores();\n}\n\nprintScores();\n\n/*\n    * 3.\n    * Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n*/\n\nconsole.log(Math.round(4.6654563));\n\n/*\n    * 4.\n    * Pon a prueba el concepto de variable LOCAL y GLOBAL.\n*/\n\nlet myStringGlobal = \"Esta es una variable global\"\n\nfunction stringLocal(){\n    let myStringLocal = \"Esta es una variable local\";\n    return myStringLocal;\n}\n\nconsole.log(stringLocal());\n//console.log(myStringLocal);     //No devuelve nada, no está definida\nconsole.log(myStringGlobal);\n\n// !  -------- EXTRA --------\n\n/*\n    * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n    * La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n    *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n    *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n    *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n    *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n*/\n\nfunction numbersExtra (str1, str2){\n\n    let countPrintNum=0; \n\n    for (let i = 0; i <= 100; i++) {\n        if ( i % 5 == 0 && i % 3 == 0){\n            console.log(str1)\n        } else if ( i % 5 == 0){\n            console.log(str2)\n        } else if ( i % 3 == 0){\n            console.log(str1 + str2)\n        } else {\n            console.log(i);\n            countPrintNum++;\n        }\n    }\n\n     return countPrintNum\n}\n\nconsole.log(numbersExtra(\"Cadena 1\", \"Cadena 2\"));"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/sans6114.js",
    "content": "//TIPOS DE FUNCIONES EN JAVASCRIPT\n//DECLARACIÓN FUNCTION\nfunction saludar(nombre) {\n    console.log(`¡Hola ${nombre}!`)\n}\n//EXPRESIÓN DE FUNCIÓN (ASIGNO UN VALOR ANONIMO A LA FUNCIÓN)\nconst saludarAnonimo = function (nombre) {\n    console.log(`!hola ${nombre}!`)\n}\n//FUNCIÓN DE FLECHA\nconst saludarFlecha = (nombre) => {\n    return `hola ${nombre}`\n}\n//FUNCIÓN CONSTRUCTORA\nfunction Persona(nombre, edad) {\n    this.nombre = nombre;\n    this.edad = edad;\n}\nconst natalia = new Persona('natalia', 40)\n//METODOS DE OBJETOS\nconst persona = {\n    nombre: 'santiago',\n    saludar() {\n        console.log(`hola soy ${this.nombre}`)\n    }\n}\n//HIGH ORDER FUNCTION\nfunction printNumberWith(number, action) {\n    //si el numero es mayor o igual a 5, ejecuto la acción y retorno el nuevo valor\n    if (number >= 5) return action(number)\n}\nconst sumarDos = (numero) => {\n    return numero + 2\n}\n//FUNCIONES YA CREADAS POR EL LENGUAJE\nconst getDate = () => {\n    const date = new Date(\"December 26, 1995 23:15:30\");\n    const weekday = date.getDay();\n    return weekday // 2\n}\n//VARIABLES LOCALES Y GLOBALES\nconst miPersona = 'Juan Martin'\n\nconst saludarLocal = () => {\n    let miPersona\n    //va a saludar a mi variable local, no a la variable global\n    miPersona = 'santiago'\n    return `hola, ${miPersona},`\n}\n\n\n\n//EJECUCIÓN DE FUNCIONES\nsaludar('santiago')\nsaludarAnonimo('martin')\nsaludarFlecha('juan')\nconsole.log(saludarFlecha(natalia.nombre))\npersona.saludar()\nconsole.log(printNumberWith(5, sumarDos))\nconsole.log(getDate())\nconsole.log(saludarLocal(), `hola ${miPersona}`)\n\n\n\n/* DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n//EJERCICIO\nconst miFunction = (...args) => {\n    let contadorNumeros = 0;\n    args = args.slice(0, 2)\n    const cadenas = args.every(e => typeof e === 'string')\n    if (!cadenas) {\n        args = args.map(e => {\n            return (typeof e !== 'string') ? e.toString() : e\n        })\n    }\n    for (let i = 1; i <= 100; i++) {\n        if (i % 3 === 0 && i % 5 === 0) {\n            console.log(`${args[0]} y ${args[1]}`)\n        } else if (i % 3 === 0) {\n            console.log(args[0])\n        } else if (i % 5 === 0) {\n            console.log(args[1])\n        } else {\n            console.log(i)\n            contadorNumeros++\n        }\n    }\n    return contadorNumeros\n}\n\n\n//EJECUCIÓN DE EJERCICIO\nconsole.log(miFunction('multiplos de 3', 'multiplos de 5'))\n//SIEMPRE LOS ARGUMENTOS PASADOS A MI FUNCION VAN A CAMBIAR A CADENAS DE TEXTO Y SOLO SE TOMARAN LOS DOS PRIMEROS ELEMENTOS COMO ARGUMENTOS\nconsole.log(miFunction(123, 'multiplos de 5', 'hola!', 'otro argumento'))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/seandsun.js",
    "content": "// Sin parámetros\nfunction saludar() {\n    console.log(\"Yo soy Groot\") // Yo soy Groot\n}\n\nsaludar() // De esta manera se realiza el llamado a la función para que se ejecute\n\n// Con parámetros\nlet pelicula = \"Guardianes de la galaxia\"\n\nfunction cine(pelicula) {\n    console.log(`Me gusta mucho ${pelicula}`) // Me gusta mucho Guardianes de la galaxia\n}\n\ncine(pelicula) \n\n// Con retorno\nfunction fiesta(edad) { // Si las variables se escriben directamente en los parámetros no necesitan ser declaradas\n    return `Eres menor de edad, tienes ${edad} años, no puedes venir a la fiesta` \n}\n\nlet respuesta = fiesta(15)\nconsole.log(respuesta) // Eres menor de edad, tienes 15 años, no puedes venir a la fiesta\n\n// Funciones dentro de funciones\nfunction decirHola(nombre, apellido) {\n    \n    function nombreApellido(nombreCompleto) {\n        return nombreCompleto = `${nombre} ${apellido}`\n    }\n\n    console.log(\"Hello, \" + nombreApellido()) // Hello, Alan Walker\n}\n\ndecirHola(\"Alan\", \"Walker\") \n\n// Variable GLOBAL: está FUERA de funciones o estructuras de control\nvar global = \"Soy global\"\n\nfunction varGlobal() {\n    console.log(global) // Soy global\n}\n\nvarGlobal()\nconsole.log(global) // Soy global\n\n// Variable LOCAL: está DENTRO de funciones o estructuras de control\nfunction varLocal() {\n    let local = \"Soy local\"\n    console.log(local) // Soy local\n}\n\nvarLocal()\nconsole.log(local) // local is not defined\n\n//-------------------------------------------------------------------------------------------------------------------------------\n\n/**\n * Funciones anónimas:\n * Las funciones anónimas son aquellas que NO necesitan un nombre, se pueden almacenar directamente en una \"variable\", por lo cual,\n * el \"nombre\" de la variable se convierte en el nombre de la función.\n*/\n\n// Nota: la variable \"sumar\" solo almacena la función, más no el valor que retorna.\nlet sumar = function (a, b, c) {\n    return a + b + c\n}\n\nlet resultado = sumar(2, 4, 5)\nconsole.log(resultado) // 11\n\n/**\n * Las funciones anónimas también pueden ser autoinvocadas, o sea que no necesitan un \"nombre\", sino que seguido de las llaves se le pasan\n * los valores de sus parámetros y, de esa manera estamos \"creando\" la función y al mismo tiempo la estamos \"ejecutándo\".\n */\n\n(function (a, b, c) {\n    console.log(a * b * c) // 200\n}(10, 4, 5))\n\n\n/**\n * Funciones como constantes:\n * Las funciones se deben declarar con la palabra reservada “const” porque su funcionalidad nunca va a cambiar (a menos que se refactorice),\n * lo único que cambiará es el valor que retorna, más no su funcionalidad.\n */\n\nconst saludar = function (nombre) {\n    console.log(`Hola ${nombre}`)\n}\n\nsaludar(\"Juan\") // Hola Juan\n\n/**\n * Funciones flecha:\n * Se llaman funciones flechas porque permiten \"simplificar\" la forma en que se escriben las funciones, y para ello se utiliza el operador “⇒”.\n */\n\n// Función constante normal\nconst restar = function (c, d) {\n    return c - d\n}\n\nconsole.log(restar(10, 5)) // 5\n\n/*\nComo la función anterior NO tiene nada de lógica, sino que lo que hace es una opereación sencilla y retorna algo inmediatamente,\nlo que se puede hacer es reescribir la función anónima quitándole la palabra \"function\" y las \"{}\", quedando así:\n*/\n\n// Función constante expresada como función flecha\nconst resta = (a, b) => a - b\n\nconsole.log(resta(10, 5)) // 5\n\n// Cuando solo se recibe 1 parámetro se pueden borrar los paréntesis, pasando de esto \"(nombre)\" a esto \"nombre\", quedando así:\nconst saludar = nombre => `Hola ${nombre}`\n\nconsole.log(saludar(\"Bim Bom\")) // Hola Bim Bom\n\n// Para escribir una función flecha más larga se hace así:\nconst nombre = nombre => {\n\n    if(typeof nombre === \"string\") {\n            console.log(nombre)\n    } else {\n            console.log(\"Tipo de dato incorrecto\") // Tipo de dato incorrecto\n    }\n}\n\nnombre(3)\n\n//-------------------------------------------------------------------------------------------------------------------------------\n\n// Ejercicio\nfunction dificultadExtra(cadena1, cadena2) {\n\n    contador = 0;\n    for(let i = 1; i < 101; i++) {\n        \n        if(i % 3 === 0 && i % 5 == 0){\n            console.log(`${cadena1} ${cadena2}`)\n        } \n        else if(i % 3 === 0) {\n            console.log(cadena1)\n        } \n        else if(i % 5 === 0) {\n            console.log(cadena2)\n        } \n        else {\n            contador++\n            console.log(i)\n        }\n    }\n    return console.log(`El número se ha impreso ${contador} veces`)\n}\n\ndificultadExtra(\"Yo soy...\", \"Groot\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/sebascmb.js",
    "content": "// #02  FUNCIONES Y ALCANCE\n\n/*\nEJERCICIO:\n- Crea ejemplos de funciones básicas que representen las diferentes posibilidades del lenguaje: Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n- Comprueba si puedes crear funciones dentro de funciones.\n- Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n- Pon a prueba el concepto de variable LOCAL y GLOBAL.\nDebes hacer print por consola del resultado de todos los ejemplos (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n\nDIFICULTAD EXTRA (opcional):\nCrea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n- La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n- Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n- Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n- Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n- La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\nPresta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\nCada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n*/\n\n\n// -------> FUNCION SIN PARAMETRO NI RETORNO <----------- //\n\nfunction saludoSinParametroSinRetorno() {\n  console.log(`Hola mundo`);\n}\n\nsaludoSinParametroSinRetorno();\n\n\n// ---------> FUNCION CON PARAMETRO SIN RETORNO <--------- //\n\nfunction saludoConParametro( nombre ) {\n  console.log(`Hola ${nombre}`);\n}\n\nsaludoConParametro('Sebastian');\n\n\n// --------> FUNCION CON RETORNO Y PARAMETRO <----------- //\n\nfunction retorno( num1, num2 ) {\n  return num1 + num2;\n}\n\nconsole.log(retorno( 10, 15 ));\n\n\n// --------> FUNCION DENTRO DE OTRA FUNCION <---------- //\n\nfunction funcionEnOtra(params) {\n  function soyOtra() {\n    console.log('Hola, soy una funcion dentro de otra');\n  }\n  return soyOtra();\n}\n\nfuncionEnOtra();\n\n\n// --------> FUNCION CON UNA VARIBALE GLOBAL <---------//\n\nlet variableGlobal = 'Sebastian';\n\nfunction llamarGlobal() {\n  console.log(variableGlobal);\n}\n\nllamarGlobal();\n\n\n// --------> FUNCIION CON UNA VARIBALE LOCAL <--------//\n\nfunction llamarLocal() {\n  let variableLocal = 'Soy una variable local'\n  console.log(variableLocal);\n}\n\nllamarLocal();\n\n\n// ----------> FUNCION YA CREADA <--------------//\n\n\nfunction funcionYaCreada() {\n  alert('Sebastian :D');\n}\n\n\n\n\n//  Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n// - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n// - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n// - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n// - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n// - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\nfunction tarea( str1, str2 ) {\n  contador = 0;\n  for (let i = 0; i <= 100; i++) {\n    if ( i % 5 == 0 && i % 3 == 0 ) {\n      console.log( str1, str2 );\n    } else if ( i % 5 == 0 ) {\n      console.log(str1);\n    } else if ( i % 3 == 0 ) {\n      console.log(str2);\n    } else {\n      contador++;\n    }\n  }\n  return contador;\n}\n\nconsole.log(tarea('Sebastian', 'Marquez'));\n\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/septarian.js",
    "content": " // Funciones basicas\n function hola(){\n    console.log(\"hola mundo\")\n }\n hola()\n\n function suma(a, b){\n   return a + b\n }\n let a = 3\n let b = 2\n console.log(suma(a,b))\n\n // Funciones dentro de funciones\n function nombre(name, last){\n   console.log(\"mi nombre es: \"+ name )\n   //metodo con argumento por defecto\n   function apehido(lastName = \"Mora\"){\n      console.log(`mi apehido es: ${lastName}`)\n   }\n   apehido()\n }\n const names = \"johnny\"\n const last = \"joestar\"\n nombre(names, last)\n\n // Funciones con numero variable de argumentos\nfunction variable(...names){\n   for(let i of arguments){\n      console.log(\"Hola \" + i)\n   }\n}\nvariable(\"erick\", \"dany\", \"johnny\", \"gyro\")\n\n// Funciones del lenguaje\nlet cadena = \"soy una cadena\"\nconsole.log(typeof cadena)\n\n// Variable local y global\nlet varr = \"hola\"  //variable global, las variables locales estan dentro de funciones\n\n// EXTRA\nfunction numeros(a, b){\n   let cont = 0\n\n   for(let i = 0;i <= 100;i++){\n      if(i % 3 === 0 && i % 5 === 0){\n         console.log(a)\n      }\n      else if(i % 5 === 0){\n         console.log(b)\n      }\n      else if(i % 3 === 0){\n         console.log(`${a} ${b}  `)\n      }\n      else{\n         console.log(i)\n         cont++\n      }\n   }\n   return cont\n}\nconst parametro1 = \"bizarre\"\nconst parametro2 = \"adventure\"\nconsole.log(numeros(parametro1, parametro2))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/shevotool.js",
    "content": "// Funciones básicas\nfunction caminar() {\n  console.log(\"Hola\");\n}\ncaminar();\n\nfunction ejercitarse(caminarP, correrP) {\n  return { trotar: caminarP, correr: correrP };\n}\nconst { trotar, correr } = ejercitarse(\"hiking\", \"pista\");\nconsole.log(trotar);\nconsole.log(correr);\n\nfunction entrenar() {\n  caminar();\n  return \"Entrenamiento completado\";\n}\nconsole.log(entrenar());\n\nfunction tareas() {\n  function lavar() {\n    console.log(\"Lavar la ropa\");\n  }\n  lavar();\n}\ntareas();\n\n//Funciones ya creadas en el lenguaje\n\n// Function declarations\nfunction sumar(a, b) {\n  return a + b;\n}\nconsole.log(sumar(3, 4));\n\n// Function expresion\nconst restar = function (a, b) {\n  return a - b;\n};\nconsole.log(restar(10, 5));\n\n// Arrow function\nconst multiplicar = (a, b) => a * b;\nconsole.log(multiplicar(3, 4));\n\n// Callback\nfunction hacerEjercicio(callback) {\n  console.log(\"Empezando ejercicio\");\n  callback();\n}\nhacerEjercicio(caminar);\n\n// Variable LOCAL y GLOBAL\nlet apodo = \"Ramone\"; // variable global\n\nfunction saludar(persona) {\n  let saludo = \"Hola\"; // variable local\n  return `Hola ${persona} ${apodo}`;\n}\nconsole.log(saludar(\"Jonny\"));\n\n// DIFICULTAD EXTRA\n\nfunction textoANumero(parametro1, parametro2) {\n  let contador = 0;\n  for (let i = 1; i <= 100; i++) {\n    if (i % 3 === 0 && i % 5 === 0) {\n      console.log(parametro1 + parametro2);\n    } else if (i % 3 === 0) {\n      console.log(parametro1);\n    } else if (i % 5 === 0) {\n      console.log(parametro2);\n    } else {\n      contador++;\n    }\n  }\n  return contador;\n}\nconsole.log(textoANumero(\"Fizz\", \"Buzz\"));\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/sniker1223.js",
    "content": "// no arguments, no return\nfunction sayHello() {\n  console.log(\"Hello. This function doesn't has parameter and return\")\n}\n\n// argument and return\nfunction square(number) {\n  return number * number;\n}\n\n// Nested functions\nfunction getScore(name, num1, num2) {\n  function add(name, num1, num2) {\n    return name + \" scored  \" + (num1 + num2);\n  }\n  console.log(add(name, num1, num2))\n}\n\n// Function printing\nsayHello()\nconsole.log(\"This function has a parameter and return: \" + square(2))\ngetScore(\"Sniker\", 20, 20)\nconsole.log(\"Console.log() is an example of a function\")\n\nlet varGlobal = 0\n// Challenge\nfunction printTheChallenge(text1, text2) {\n  for (let i = 1; i <= 100; i++) {\n    if (i % 3 == 0 && i % 5 == 0) {\n      console.log(text1 + text2)\n    } else if (i % 3 == 0) {\n      console.log(text1)\n    } else if (i % 5 == 0) {\n      console.log(text2)\n    } else {\n      console.log(i)\n      varGlobal += 1\n    }\n  }\n  return varGlobal\n}\n\nconsole.log(\"Number of times the number has been printed:\",printTheChallenge(\"Star\", \"Wars\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/socramwd.js",
    "content": "/*\n    Funciones definidas por el usuario\n*/\n\nconsole.log('/* Función simple */')\nfunction greet() {\n    console.log('Hola Javascript')\n}\ngreet()\n\n\nconsole.log('**********-**********-**********-**********-**********')\n\nconsole.log('/* Función con retorno */')\nfunction returnGreet() {\n    return 'Hola Javascript'\n}\nconsole.log(returnGreet())\n\nconsole.log('**********-**********-**********-**********-**********')\n\n\nconsole.log('/* Función con argumento */')\nfunction argGreet(name) {\n    console.log('Hola,', name)\n}\nargGreet('Marcos')\n\nconsole.log('**********-**********-**********-**********-**********')\n\n\nconsole.log('/* Función con argumentos */')\nfunction argsGreet(greet, name) {\n    console.log(greet, name)\n}\nargsGreet('Hola,', 'Marcos')\n\n\nconsole.log('**********-**********-**********-**********-**********')\n\n\nconsole.log('/* Función con argumentos por defecto */')\nfunction defaultArgGreet(name = 'SocramDev') {\n    console.log( 'Hola,', name)\n}\ndefaultArgGreet()\n\n\nconsole.log('**********-**********-**********-**********-**********')\n\nconsole.log('/* Función con argumentos y retorno */')\nfunction returnArgsGreet(greet, name) {\n    return greet + ', ' + name\n}\nconsole.log(returnArgsGreet('Hola', 'Marcos'))\n\n\nconsole.log('**********-**********-**********-**********-**********')\n\n\nconsole.log('/* Función con retorno de varios valores */')\nfunction multipleReturns() {\n    return {\n        greetVar: 'Hola',\n        nameVar: 'Javascript'\n    }\n}\nconst { greetVar, nameVar } = multipleReturns()\nconsole.log(greetVar)\nconsole.log(nameVar)\n\n\nconsole.log('**********-**********-**********-**********-**********')\n\n\n/*\n    Funciones definidas por el usuario\n*/\n\nconsole.log('/* Función dentro de función */')\nfunction outerGreet() {\n    innerGreet()\n    console.log('Hola Outer Javascript')\n}\nfunction innerGreet() {\n    console.log('Hola Inner Javascript')\n}\nouterGreet()\n\n\nconsole.log('**********-**********-**********-**********-**********')\n\n\n/*\n    Funciones del lenguaje\n*/\n\nconsole.log('/* Length => cuenta los caracteres, incluídos los espacions */')\nconst completeName = 'Marcos Pérez'\nconsole.log( completeName.length )\n\nconsole.log('/* typeOf => tipo de dato */')\nconsole.log(typeof(completeName))\n\nconsole.log('/* toUpperCase => convierte el texto a mayúsculas */')\nconsole.log(completeName.toUpperCase())\n\n\nconsole.log('**********-**********-**********-**********-**********')\n\n\n/*\n    Scope - Variables locales y globales\n*/\nconst globalVariable = 'Javascript'\nconsole.log(globalVariable)\nfunction helloJavascript() {\n    const localVariable = 'Hola'\n    console.log(localVariable, globalVariable)\n}\nhelloJavascript()\n// console.log(localVariable) => no se puede acceder fuera de la función\n\n\nconsole.log('**********-**********-**********-**********-**********')\n\n\n/*\n    Extra\n*/\nfunction printNumbers( text_1, text_2 ) {\n    let count = 0\n\n    for (let i = 1; i < 101; i++) {\n        if( i % 3 === 0 && i % 5 === 0) {\n            console.log( i, ':', text_1, '', text_2 )\n        } else if( i % 3 === 0 ) {\n            console.log( i, ':', text_1 )\n        } else if( i % 5 === 0 ) {\n            console.log( i, ':', text_2 )\n        } else {\n            console.log( i )\n            count++\n        }\n    }\n    \n    return count\n}\nconsole.log( 'El numero de veces que no hay texto es: ', printNumbers('Múltiplo de 3', 'Múltiplo de 5'))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/ssanjua.js",
    "content": "// Función sin parámetros ni retorno\nfunction saludo() {\n  console.log(\"Hola, mundo!\");\n}\nsaludo();\n\n// Función con un parámetro\nfunction saludar(nombre) {\n  console.log(\"Hola, \" + nombre + \"!\");\n}\nsaludar(\"Juan\");\n\n// Función con varios parámetros\nfunction sumar(a, b) {\n  return a + b;\n}\nconsole.log(sumar(5, 3));\n\n// Función dentro de una función\nfunction operacion(a, b) {\n  function multiplicar(x, y) {\n      return x * y;\n  }\n  return multiplicar(a, b);\n}\nconsole.log(operacion(4, 5));\n\n// Ejemplo de función ya creada en el lenguaje\nconsole.log(Math.max(10, 20, 30));\n\n// Variables LOCAL y GLOBAL\nvar globalVar = \"Soy una variable global\";\n\nfunction mostrarVariables() {\n  var localVar = \"Soy una variable local\";\n  console.log(globalVar);\n  console.log(localVar);\n}\nmostrarVariables();\n// console.log(localVar); // Esto dará un error porque localVar no está definida en el ámbito global\n\n// DIFICULTAD EXTRA\nfunction imprimirNumeros(cadena1, cadena2) {\n  let contador = 0;\n  for (let i = 1; i <= 100; i++) {\n      if (i % 3 === 0 && i % 5 === 0) {\n          console.log(cadena1 + cadena2);\n      } else if (i % 3 === 0) {\n          console.log(cadena1);\n      } else if (i % 5 === 0) {\n          console.log(cadena2);\n      } else {\n          console.log(i);\n          contador++;\n      }\n  }\n  return contador;\n}\nconsole.log(\"Número de veces que se ha impreso el número: \" + imprimirNumeros(\"Fizz\", \"Buzz\"));\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/uyarra73.js",
    "content": "// Función sin parámetros ni retorno\nfunction saludo() {\n    console.log(\"Hola, JavaScript!\");\n}\n\n// Función con un parámetro\nfunction saludoNombre(name) {\n    console.log(\"Hola, \" + name + \"!\");\n}\n\n// Función con varios parámetros\nfunction suma(a, b) {\n    console.log(a + b);\n}\n\n// Función con retorno\nfunction producto(a, b) {\n    return a * b;\n}\n\nconsole.log(producto(2,3));\n\n// Funciones dentro de funciones\nfunction funcionExterior(x) {\n    function funcionInterior(y) {\n        return x + y;\n    }\n\n    return funcionInterior;\n}\n\nlet addSix = funcionExterior(6);\nconsole.log(addFive(3)); // 8\n\n// Uso de funciones nativas\nlet numeros = [1, 2, 3, 4, 5];\nlet numerosCuadrado = numeros.map(function(number) {\n    return number * number;\n});\n\nconsole.log(numerosCuadrado); // [1, 4, 9, 16, 25]\n\n// Variables locales y globales\nlet variableGlobal = 'Soy global';\nconsole.log(variableGlobal);\nfunction imprimirVariable() {\n    let variableLocal = \"Soy local\";\n    return variableGlobal + \". \" + variableLocal; // \"Soy global. Soy Local\"\n}\nconsole.log(imprimirVariable());\nconsole.log(variableLocal);\n\n\n// Ejercicio extra\n\n/* DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos. */\n\n\nfunction exercise(str1, str2) {\n    let contador = 0;\n    let arr = []\n    for (let i = 1; i <= 100; i++) {\n        if (i % 3 === 0 && i % 5 === 0) {\n            arr.push(`${str1} y ${str2}`);\n        } else if (i % 3 === 0) {\n            arr.push(str1);\n        } else if (i % 5 === 0) {\n            arr.push(str2);\n        } else {\n            arr.push(i);\n            contador++;\n        }\n    }\n    return `${arr} Se han imprimido un total de ${contador} numeros.`;\n}\n\nconsole.log(exercise(\"Multiplo de 3\", \"Multiplo de 5\"));\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/victor-Casta.js",
    "content": "/* \n  * - Crea ejemplos de funciones básicas que representen las diferentes\n  *   posibilidades del lenguaje:\n  *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n*/\n\n//Funciones sin parametros y sin retorno\n  const funcion = function(){\n    //\"Estoy en una función sin parámetros y sin retorno\"\n  }\n  console.log(funcion);\n\n//Funciones con un parametro\n  const funcionConUnParametro = function(greeting) {\n    console.log(`${greeting}, soy un programa`);\n  }\n  funcionConUnParametro(\"Hola\");\n\n//funciones con varios parametros\n  const funcionConVariosParametros = function(a, b){\n    console.log(a + b);\n  }\n  funcionConVariosParametros(5,10);\n\n//Funciones con retorno\n  const sumarDosNumeros = function (x, y) {\n    return x + y;\n  }\n  console.log(sumarDosNumeros(3,4));\n\n//Funciones flecha(es una expresion compacta de lo que es una funcion tradicional)\n  /*\n    Diferencias y limitaciones:\n    No tiene sus propios enlaces a this o super y no se debe usar como métodos.\n    No tiene argumentos o palabras clave new.target.\n    No apta para los métodos call, apply y bind, que generalmente se basan en establecer un ámbito o alcance\n    No se puede utilizar como constructor.\n    No se puede utilizar yield dentro de su cuerpo.\n  */\n\n  const dividirNumeros = (x, y) => x / y;\n  console.log(dividirNumeros(6,2));\n\n/*\n   * - Comprueba si puedes crear funciones dentro de funciones.\n*/\n  const saludar = function(a) {\n    const hablar = () => console.log(`Hola ${a}`);\n    hablar()\n  }\n\n  saludar('JavaScript');\n\n/*\n   * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n*/\n//En este caso se utiliza la funcion de tiempo 'setTimeout' la cual ejecuta una funcion despues de determinado tiempo\n  setTimeout(() => console.log('Hola despues de 2000 ms'), 2000)\n\n/*\n  * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n*/\n// Esta es una variable global, la cual puede ser accedida en cualquier lugar del documento.\nlet variableGlobal = 'Variable global';\n\n/**\n * Esta es una función llamada miFuncion.\n * Dentro de esta función, se declara una variable local llamada variableLocal.\n * Solo podemos acceder a variableLocal dentro de la función.\n */\nfunction miFuncion() {\n  let variableLocal = 'Variable local';\n  // Aquí podríamos realizar operaciones con la variableLocal.\n}\n\n// Ejemplo de uso de la variable global\nconsole.log(variableGlobal);\n\n// Intentar acceder a la variable local fuera de la función resultaría en un error.\n// console.log(variableLocal); // Esto generaría un error porque variableLocal no está definida aquí.\n\n/*\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n*/\n\nconst imprimirNumeros = function(a, b) {\n  let contadorNumeros = 0;\n  for (let i = 1; i <= 100; i++) {\n    if (i % 3 === 0 && i % 5 === 0) {\n      console.log(`${a} ${b}`);\n    } else if (i % 3 === 0) {\n      console.log(a);\n    } else if (i % 5 === 0) {\n      console.log(b);\n    } else {\n      contadorNumeros++\n    }\n  }\n  return contadorNumeros\n}\n\nconsole.log(`La cantidad de veces en que se imprimio un numero es de: ${imprimirNumeros('Hola', 'JavaScript')}`)\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/vmatmarco.js",
    "content": "/* FUNCIONES BASICAS EN JAVASCRIPT */\n\n// <--- Funciones por declaración --->\n\nfunction funcionPorDeclaracion () {\n    console.log('Esto es una funcion por declaración');\n}\n\nfuncionPorDeclaracion();\n\n\n// Pueden recibir parametro dentro del paréntesis\n\nfunction funcionConParametros(numero) {\n    console.log(numero);\n}\n\nfuncionConParametros(10); // Llamamos a la funcíon con valor 10, que se imprimira por pantalla.\n\n\n// Devolución de valores\n\nfunction sumarNumeros(num1, num2) {\n    return num1 + num2;\n}\n\nlet suma = sumarNumeros(5, 5);\nconsole.log('El total es: ', suma);\n\n\n// <--- Funciones dentro de funciones y variables LOCALES Y GLOBALES --->\n\nconst NUMERO_PI = 3.1415; // Variable global. Puede ser accesible desde cualquier parte del codigo\n                          // Tanto dentro como fuera de las funciones.  \n\nfunction calcularAreaCiruculo(r) {\n    function radioAlCuadrado(rPor2){\n      return rPor2 **= 2;\n    }\n    let cuadrado = radioAlCuadrado(r); // 'cuadrado' es una variable local. Solo es accesible dentro de esta función.\n    return cuadrado * NUMERO_PI;\n  }\n  \n  const areaCirculo = calcularAreaCiruculo(5);\n  console.log(areaCirculo);\n\n\n// <--- Funciones creadas por el lenguaje --->\n\n// La funcion 'length()' devuelve la longitud de un string\n\nlet longitudPalabra = \"JavaScript\";\nconsole.log(\"JavaScript tiene \" + longitudPalabra.length + \" carácteres.\");\n\n\n/* DIFICULTAD EXTRA */\n\nfunction imprimeMultiplos (texto1, texto2) {\n    let contador = 0;\n    for(let i = 1; i <= 100; i++){\n        if(i%3 === 0 && i%5 === 0){\n            console.log(texto1+texto2);\n        } else if (i%3 === 0) {\n            console.log(texto1);\n        } else if (i%5 === 0){\n            console.log(texto2);\n        } else {\n            console.log(i);\n            contador ++;\n        }\n    }\n    return contador;\n}\n\nconst TOTAL = imprimeMultiplos('Hola', 'Mundo');\nconsole.log(\"Entre 1 y 100 hay \" + TOTAL + \" numeros que no son multiplos de 3 ni de 5\");\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/vsUnix0.js",
    "content": "//1. función sin parámetros y sin return - Declaración de funciones\r\nnombre = \"Martín\";\r\n\r\nfunction saludar() {\r\n  console.log(`!Hola ${nombre}`);\r\n}\r\n\r\nconsole.log(saludar());\r\n\r\n//2. función con parámetros y return - Declaración de funciones\r\nfunction suma(num1, num2) {\r\n  return num1 + num2;\r\n}\r\n\r\nconsole.log(suma(43, 65));\r\n\r\n//3. expresion function - función anonima\r\nconst square = function (number) {\r\n  return number * number;\r\n};\r\n\r\nconsole.log(square(4));\r\n\r\n//4. expresion function - función con nombre\r\nconst data = function dt(name, age, country) {\r\n  return `Hola mi nombre es ${name}, tengo ${age} y soy de ${country}`;\r\n};\r\n\r\nconsole.log(data(\"Martín\", 20, \"Madrid\"));\r\n\r\n// 5. función flecha\r\nconst calcularArea = (ancho, alto) => {\r\n  let area = ancho * alto;\r\n  return area;\r\n};\r\n\r\nconsole.log(`El area es: ${calcularArea(23, 54)}`);\r\n\r\n// 6. función flecha pero con 1 parámetro\r\nconst multiplicarNumero = (x) => x ** 3;\r\n\r\nconsole.log(multiplicarNumero(10));\r\n\r\n// 7. funcion como parámetro\r\nconst alerta = (fun, x) => {\r\n  return alert(fun(x));\r\n};\r\n\r\nconst saludaUsuario = (nombre = amigo) => {\r\n  return `Hola ${nombre}`;\r\n};\r\n\r\nalerta(saludaUsuario, \"Martín\");\r\n\r\n// DIFICULTAD EXTRA\r\n\r\nconst print_numbers = (text1, text2) => {\r\n  let counter = 0;\r\n  for (let i = 1; i < 100; i++) {\r\n    if (i % 3 == 0 && i % 5 == 0) {\r\n      console.log(text1 + text2);\r\n    } else if (i % 3 == 0) {\r\n      console.log(text1);\r\n    } else if (i % 5 == 0) {\r\n      console.log(text2);\r\n    } else {\r\n      console.log(i);\r\n      counter++;\r\n    }\r\n  }\r\n  console.log(\r\n    `Las veces que se ha impreso el número en lugar de los textos: ${counter}`,\r\n  );\r\n};\r\n\r\nconsole.log(print_numbers(\"texto1\", \"texto2\"));\r\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/wapastorv.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n// Ejemplo de función sin parámetros ni retorno\nfunction saludar() {\n  console.log('Hola!');\n}\nsaludar(); // Imprime: Hola!\n\n// Ejemplo de función con un parámetro y sin retorno\nfunction saludarPersona(nombre) {\n  console.log ('Hola ' + nombre + '!');\n}\nsaludarPersona('Carlos'); // Imprime: Hola Carlos!\n\n// Ejemplo de función con varios parámetros y sin retorno\nfunction sumar(a, b) {\n  console.log(\"La suma es: \"+ (a + b));\n}\nsumar(2, 3); // Imprime: La suma es: 5\n\n// Ejemplo de función con retorno y sin parámetros\nfunction obtenerMensaje() {\n  return 'Este es un mensaje';\n}\nconsole.log(obtenerMensaje()); // Imprime: Este es un mensaje\n\n// Ejemplo de función con varios parámetros y con retorno\nfunction multiplicar(a, b) {\n  return a * b;\n}\nlet multiplicarResultado = multiplicar(2, 3);\nconsole.log('El resultado de la multiplicación es: ' + multiplicarResultado); // Imprime: El resultado de la multiplicación es: 6\n\n// Ejemplo de función dentro de función(anidada)\nfunction operacionCompleja(a, b) {\n  function sumar(x, y) {\n    return x + y;\n  }\n  function multiplicar(x, y) {\n    return x * y;\n  }\n  \n  let suma = sumar(a, b);\n  let multiplicacion = multiplicar(a, b);\n\n  console.log('La suma es: ' + suma);\n  console.log('La multiplicación es: ' + multiplicacion);\n}\noperacionCompleja(2, 3); // Imprime: La suma es: 5, La multiplicación es: 6\n\n// Ejemplo de función ya creada en el lenguaje\nlet texto = 'Hola, soy un texto de ejemplo para mostrar la longitud';\nconsole.log(texto.length); // Imprime: 54\nlet numeros = [1, 2, 3, 4, 5];\nlet numerosInvertidos = numeros.reverse();\nconsole.log(numerosInvertidos); // Imprime: [5, 4, 3, 2, 1]\nlet numerosOrdenados = numeros.sort();\nconsole.log(numerosOrdenados); // Imprime: [1, 2, 3, 4, 5]\nlet numerosDobles = numeros.map(numero => numero * 2);\nconsole.log(numerosDobles); // Imprime: [2, 4, 6, 8, 10]\n\n// Ejemplo de variable LOCAL y GLOBAL\n\n// Variable GLOBAL\nlet variableGlobal = 'Soy una variable global';\nfunction mostrarVariableGlobal() {\n  console.log(variableGlobal);\n}\nmostrarVariableGlobal(); // Imprime: Soy una variable global\n\n// Variable LOCAL\nfunction mostrarVariableLocal() {\n  let variableLocal = 'Soy una variable local';\n  console.log(variableLocal);\n}\nmostrarVariableLocal(); // Imprime: Soy una variable local\n\n// Variable Global y Local en el mismo ámbito\nlet mensajeGlobal = 'Soy una variable global';\n\nfunction mostrarMensaje() {\n  let mensajeLocal = 'Soy una variable local';\n  console.log(mensajeGlobal);// Puede acceder a la variable global\n  console.log(mensajeLocal); // Puede acceder a la variable local\n}\nmostrarMensaje(); // Imprime: Soy una variable global, Soy una variable local\n//console.log(mensajeLocal); // Genera un error porque la variable es local y no se puede acceder desde fuera de la función\n\n// Ejemplos de sombra de variables (shadowing)\nlet mensaje = 'Soy una variable global';\n\nfunction mostrarMensaje() {\n  let mensaje = 'Soy una variable local';\n  console.log(mensaje); // Imprime: Soy una variable local, porque se está accediendo a la variable local \"shadowing\"\n}\nmostrarMensaje();\nconsole.log(mensaje); // Imprime: Soy una variable global, porque se está accediendo a la variable global\n\n// Función que modifica una variable global\nlet contador = 0;\n\nfunction incrementarContador() {\n  contador++;\n}\nincrementarContador();// Incrementa el contador en 1\nincrementarContador();// Incrementa el contador en 2\nincrementarContador();// Incrementa el contador en 3\nconsole.log(\"El valor del contador(global): \"+contador); // Imprime: 3\n\n// Función que modifica una variable local\nfunction incrementarContadorLocal() {\n  let contadorLocal = 0;\n  contadorLocal++;\n  return contadorLocal;\n}\nlet contadorLocal = incrementarContadorLocal(); // Incrementa el contador en 1\nconsole.log(\"El valor del contador(local): \"+contadorLocal); // Imprime: 1\n\n// Función que modifica una variable global y local\nlet contadorGlobal = 0;\nfunction incrementarContadores() {\n  contadorGlobal++;\n  let contadorLocal = 0;\n  contadorLocal++;\n  return contadorLocal;\n}\nincrementarContadores(); // Incrementa el contador global en 1 y el contador local en 1\nincrementarContadores(); // Incrementa el contador global en 2 y el contador local en 1\nincrementarContadores(); // Incrementa el contador global en 3 y el contador local en 1\nconsole.log(\"El valor del contador(global): \"+contadorGlobal); // Imprime: 3\nconsole.log(\"El valor del contador(local): \"+incrementarContadores()); // Imprime: 1\n\n// Función que utiliza let y const para ver el enlace de bloque\nfunction mostrarVariables(){\n    if (true) {\n        var variableVar = 'Soy una variable var'; // Al ser var, se puede acceder desde fuera del bloque\n        let variableLet = 'Soy una variable let'; // Al ser let, solo se puede acceder dentro del bloque\n        const variableConst = 'Soy una variable const'; // Al ser const, solo se puede acceder dentro del bloque\n        console.log(variableVar); // Imprime: Soy una variable var\n        console.log(variableLet); // Imprime: Soy una variable let\n        console.log(variableConst); // Imprime: Soy una variable const\n    }\n    console.log(variableVar); // Funciona porque es una variable var y se pue// Imprime: Soy una variable var, Soy una variable let, Soy una variable const, Soy una variable varde acceder desde fuera del bloque\n    //console.log(variableLet); // Genera un error porque es una variable let y no se puede acceder desde fuera del bloque\n    //console.log(variableConst); // Genera un error porque es una variable const y no se puede acceder desde fuera del bloque\n}\nmostrarVariables();\n\n\n// Ejericio extra de función que recibe dos parámetros de tipo cadena de texto y retorna un número\n\nfunction mostrarNumeros(cadena1, cadena2) {\n  let contadorNumeros = 0;\n  for (let i = 1; i <= 100; i++) {\n    if (i % 3 === 0 && i % 5 === 0) {\n      console.log(cadena1 + cadena2);\n    } else if (i % 3 === 0) {\n      console.log(cadena1);\n    } else if (i % 5 === 0) {\n      console.log(cadena2);\n    } else {\n      console.log(i);\n      contadorNumeros++;\n    }\n  }\n  return contadorNumeros;\n}\nlet contadorNumeros = mostrarNumeros('Múltiplo de 3', 'Múltiplo de 5');\nconsole.log('El número de veces que se ha impreso un número es: ' + contadorNumeros); \n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/wolffcode.js",
    "content": "// Funciones y alcance\n\n    //sin parametros ni retorno\nfunction mensaje(){\n    console.log(\"hola!\")\n}\n    // con parametros\nfunction saludar(nombre){\n    console.log(`hola ${nombre} que tal!`)\n}\n    // con retorno\nfunction sum(num1, num2){\n    return num1 + num2\n}\n\n    //funciones dentro de funciones\nfunction funcionAnidada(condicion){\n    if(condicion){\n        mensaje(\"verdadero\")\n    }else{\n        mensaje(\"falso\")\n    }\n\n    function mensaje(mnsj){\n        console.log(`${mnsj}`)\n    }\n}\nfuncionAnidada(true)\n    // funciones creadas en el lenguaje\n    let str = \"Hola amigos\"\n    let str2 = str.split(\" \")\n    console.log(str2) //esto separa la cadena en un array de palabras separadas por el espacio\n\n    //variable local y global\n    /*una variable local solo puede ser utilizada en el entorno donde fue decalarada esto quiere decir que si fue declarada dentro de un bloque de \n    codigo como una funcion, o un metodo, solo existe y puede ser usada ahi\n    */ \n    //hasta donde tengo entendido en javascripot var es una variable  global donde se aque esta sea declarada    \n\n    let num = 5\n    function valor(){\n        console.log(num)\n    }\n    valor()//aqui si nos devolveria el valor de num ya que la funcion si puede acceder al valor de la variable num\n\n    function palabra(){\n        let pal = \"palabra\" \n    }\n    console.log(pal) /*aqui nos saltaria un error debido a auqe la variable pal esta declarada dentro de un bloque de codigo al cual la funcion console.log no tiene acceso */\n\n        // reto extra\n    function param(str1, str2){\n        count = 0\n        for(let i =1 ;i<= 100; i++){\n            if(i %3 == 0 && i% 5 == 0){\n                console.log(`${str1}${str2}`)\n            }else if(i % 3 == 0){\n                console.log(`${str1}`)\n            }else if(i % 5 == 0){\n                console.log(`${str2}`)\n            }else{\n                console.log(i)\n                count++\n            }\n        }\n        console.log(`los numeros han reemplazado a las palabras un total de ${count} veces`)\n    }\n    param(\"fizz\", \"fuzz\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/xmunder.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n// Tipos de funciones en JavaScript\n\n// 1. Función mediante declaración.\n\n// Sin parametros ni retorno.\nfunction sayHello() {\n  console.log(\"Hello World!\");\n}\nsayHello(); //Hello World!\n\n// Con parametros y retorno.\nfunction sayHello2(name) {\n  return `Hello ${name}!`;\n}\nconsole.log(sayHello2(\"World\")); // Hello World!\n\n// Con varios parametros y retorno.\nfunction sayHello3(name, surname) {\n  return `Hello ${name} ${surname}!`;\n}\nconsole.log(sayHello3(\"World\", \"in Javascript\")); // Hello World in Javascript!\n\n// -------------------------- // -------------------------- // -------------------------- //\n\n// 2. Función mediante expresión.\n\n// Sin parametros ni retorno.\nconst sayHello4 = function saludar() {\n  console.log(\"Hello World!\");\n};\nsayHello4(); // Hello World!\n\n// Con parametros y retorno.\nconst sayHello5 = function saludar(name) {\n  return `Hello ${name}!`;\n};\nconsole.log(sayHello5(\"World\")); // Hello World!\n\n// Con varios parametros y retorno.\n\nconst sayHello6 = function saludar(name, surname) {\n  return `Hello ${name} ${surname}!`;\n};\nconsole.log(sayHello6(\"World\", \"in Javascript\")); // Hello World in Javascript!\n\n// -------------------------- // -------------------------- // -------------------------- //\n\n// 3. Función anonima.\n\n// Sin parametros ni retorno.\nconst sayHello7 = function () {\n  console.log(\"Hello World!\");\n};\nsayHello7(); // Hello World!\n\n// Con parametros y retorno.\nconst sayHello8 = function (name) {\n  return `Hello ${name}!`;\n};\nconsole.log(sayHello8(\"World\")); // Hello World!\n\n// Con varios parametros y retorno.\nconst sayHello9 = function (name, surname) {\n  return `Hello ${name} ${surname}!`;\n};\nconsole.log(sayHello9(\"World\", \"in Javascript\")); // Hello World in Javascript!\n\n// -------------------------- // -------------------------- // -------------------------- //\n\n// 4. Función flecha.\n\n// Sin parametros ni retorno.\nconst sayHello10 = () => {\n  console.log(\"Hello World!\");\n};\nsayHello10(); // Hello World!\n\n// Con parametros y retorno.\nconst sayHello11 = (name) => {\n  return `Hello ${name}!`;\n};\nconsole.log(sayHello11(\"World\")); // Hello World!\n\n// Con varios parametros y retorno.\nconst sayHello12 = (name, surname) => {\n  return `Hello ${name} ${surname}!`;\n};\nconsole.log(sayHello12(\"World\", \"in Javascript\")); // Hello World in Javascript!\n\n// -------------------------- // -------------------------- // -------------------------- //\n\n// Comprueba si puedes crear funciones dentro de funciones.\n\n// Funciones anidadas.\nfunction Anidada(arg1) {\n  return function Anidada2(arg2) {\n    return `${arg1} ${arg2}`;\n  };\n}\nconsole.log(Anidada(\"Hello\")(\"World!\")); // Hello World!\n\n// -------------------------- // -------------------------- // -------------------------- //\n\n// Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n\n// Función que recibe un rango de números y devuelve un numero aleatorio entre ellos.\n\nfunction getRandomNumber(min, max) {\n  return Math.floor(Math.random() * (max - min) + min);\n}\nconsole.log(getRandomNumber(1, 10));\n\n// -------------------------- // -------------------------- // -------------------------- //\n\n// Pon a prueba el concepto de variable LOCAL y GLOBAL.\n\n// Variable global.\nlet globalVar = 10;\n\nfunction global() {\n  console.log(globalVar);\n}\nglobal(); // 10\n\n// Variable local.\nfunction local() {\n  let localVar = 20;\n  console.log(localVar);\n}\nlocal(); // 20\n\n// -------------------------- // -------------------------- // -------------------------- //\n\n// Dificultad extra\n\nfunction extraChallenge(text1, text2) {\n  let count = 0;\n  for (let i = 1; i <= 100; i++) {\n    if (i % 3 === 0 && i % 5 === 0) {\n      console.log(`${text1} + ${text2}`);\n    } else if (i % 3 === 0) {\n      console.log(text1);\n    } else if (i % 5 === 0) {\n      console.log(text2);\n    } else {\n      console.log(i);\n      count += 1;\n    }\n  }\n  return `Se han mostrado ${count} veces los números`;\n}\n\nconsole.log(extraChallenge(\"fizz\", \"buzz\"));\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/yedixdev.js",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n//Sin parametros ni retrono\nfunction javaScript() {\n  console.log(\"Hola mundo\");\n}\n\njavaScript();\n\n// Con parámetros\nconst nombre = \"Yedixon\";\nconst apellido = \"Ramones\";\n\nfunction yoSoy(nombre, apellido) {\n  console.log(`Hola, soy ${nombre} ${apellido}`);\n}\n\n// Con parámetros y retorno\nconst a = 6;\nconst b = 5;\n\nfunction edad(a, b) {\n  return (a + b) * 2;\n}\n\nconst result = edad(a, b);\nconsole.log(result); // Mostrará 22\n\n//Funcion dentro de un a funcion\n\nconst precioTotal = 100;\nconst descuentoTotal = 15; //15 %\n\nfunction calcularPrecioFinal(precioTotal, descuentoTotal) {\n  function calcularDescuento(precio, descuento) {\n    return precio * (descuento / 100);\n  }\n\n  const descuento = calcularDescuento(precioTotal, descuentoTotal);\n  return precioTotal - descuento;\n}\n\nconst precioFinal = calcularPrecioFinal(precioTotal, descuentoTotal);\nconsole.log(`El precio final es: $${precioFinal}`); // Muestra: El precio final es: $85\n\n//Variables Global y locales\nconst mensajeGlobal = \"Soy variable Global\";\n\nfunction comprobarVariables() {\n  const mensajeLocal = \"Soy variable Local\";\n  console.log(mensajeGlobal);\n  console.log(mensajeLocal);\n}\n\ncomprobarVariables();\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/yesidL12.js",
    "content": "// Por declaración\n function nombre(p1, p2){\n    //Bloque de código\n }\n\n // Ejemplo\n\n function saludar() {\n    console.log('Hola');\n }\n\n saludar(); // 'Hola'\n\n // por expresión\n\n let name = function(p1, p2) {\n    //Bloque de código\n }\n\n // Ejemplo\n\n const saludo = function saludar() {\n    console.log('Hola');\n }\n\n saludo(); // 'Hola'\n\n // funciones anonimas\n// ===> son un tipo de funciones que se declaran sin definr un nombre de función, alojándolas en el interior de una variable.\n\nconst nombre = function (name) {\n    console.log(name);\n}\n\nnombre('Yesid'); // 'Yesid'\n\n// Funciones autoejecutables\n// ===> Ideal para funciones que  no vas a volver a necesitar y es necesario ejecutarla inmediatamente.\n\n(function () {\n    console.log('Hola!!');\n}) ();\n\n// Clausuras Y funciones dentro de funciones\n// ===> Clausura se define como una función que <<encierra>> variables en su propio ámbito.\n\nconst incr = (function () {\n    let num = 0;\n    return function() {\n        num++;\n        return num;\n    }\n}) ();\n\n/** Analicemos primero lo que tenemos en este codigo:\n * Tenemos una funcón anónima que es tambien una función autoejecutable.\n * Obsrva que la función aujtoejecutable devuelve otra funcion diferente.\n * AL ejecutar la función la primera vez (autoejecutable) devolvemos esa otra función que es la que se guarda en INCR para futuras ejecuciones.\n */\n\n// Callback\n// ===> Es pasar una funcion por parametro a otra funcion de modo que esta última función puede ejecutar la función pasada por parametro de forma genérica desde su propio código, y nosotros podemos definirlas desde fuera de dicha función.\n\n//Ejemplo,\n\nconst action = function () {\n    console.log('Acción ejecutada');\n}\n\nconst mainFunction = function(Callback) {\n    Callback ();\n}\n\nmainFunction(action);\n\n/** Definimos una función action que realiza una tarea.\n * Definimos una función mainFunction, que recibe como parámetro una función callback genérica.\n * Llamamos a mainFunction, pasándole como parámetro la función concreta, que en este caso es action.\n */\n\n// Funciones de orden superior (HOF)\n// ===> Son funciones que reciben por parámetro otra función y/o devuelven una función mediante el return.\n\nconst accion = function () {\n    console.log('Acción ejecutada');\n}\n\nconst error = function () {\n    console.error('Ha ocurrido un error');\n}\n\nconst doTask = function (callback, callbackError) {\n    const isError = Math.random() < 0.5;\n\n    if(!isError) callback();\n    else callbackError();\n}\n\ndoTask(accion, error);\n\n// arrow Function\n\nconst func = () => {\n     console.log('Arrow function');\n}\n\n\n//Dificultad extra\nfunction cadenaDeTexto (str1, str2) {\n    for (let numero = 1; numero < 100; numero++ ) {\n        if(numero % 3 == 0 && numero % 5 == 0) {\n            console.log(str1 + str2);\n        } else if(numero % 3 == 0) {\n            console.log(str1);\n        } else if(numero % 5 == 0) {\n            console.log(str2);\n        } else {\n            console.log(numero);\n        }\n    }\n\n}\n\ncadenaDeTexto('fizz','buzz');"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/javascript/zuluangel.js",
    "content": "//basic function\nfunction basic() {\n    console.log('This is a basic function');    \n}\nbasic();\n\n//function with one parameter\nfunction oneParam(param) {\n    console.log(`This is a function with one parameter: ${param}`);\n}\noneParam('This is the parameter');\noneParam(2)\n\n//function with two parameters\nfunction twoParams(param1, param2) {\n    console.log(`This is a function with two parameters: '${param1}' and '${param2}'`);\n}\ntwoParams('This is the first parameter', 'This is the second parameter');\ntwoParams(2, 3)\n\n//function with return and two params\nfunction returnFunc(a, b) {\n    return `This is a function that returns a value: ${a + b}`;\n}\nconsole.log(returnFunc(3, 5));\n\n//function inside another function\nfunction outer() {\n    function inner() {\n        console.log('This is an inner function');\n    }\n    console.log(`This is the outer function executing...`)\n    inner();\n}\nouter();\n\n//these are functions created on the javascript environment and we are not able to change them\n//we can only use them\n// console.log() //is a js function\n// alert() //is also a js function\n\n//Local variables are the ones that are inside a specific function or class o little snipet of code.\n//They are not accessible from outside the function or class where they are declared.\nfunction local(){\n    let x = 10;\n    let y = 5\n    console.log(x + y);\n}\nlocal();\n\n//Global variables are the ones that are accessible from any part of the code.\nlet z = 20\n\nfunction globalScope(){\n    console.log(z * 5);\n}\nglobalScope();\n\n/* \nEXTRA\n*/\n\nfunction extraFunction(param1, param2) {\n    \n    let counter = 0\n    \n    for(i=1; i<=100; i++){   \n        if(i%3 == 0 && i%5 == 0) {\n            console.log(`${param1} ${param2}`)\n        } else if(i%3 == 0) {\n            console.log(param1)\n        } else if(i%5 == 0) {\n            console.log(param2)\n        } else {\n            console.log(i)\n            counter ++\n        }\n    }\n    console.log(`On the whole loop there are a total of ${counter} numbers`)       \n}\nextraFunction('text1', 'text2')"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/julia/edalmava.jl",
    "content": "# Sintaxis básica de una función\nfunction f(x, y)\n    x + y                 # El valor de la última expresión evaluada es retornada\nend\n\n# Forma de asignación\nf1(x , y) = x + y         # Se usa con expresiones simples\n\nprintln(f(2, 3))\nprintln(f1(4, 5))\n\n# Los nombres de funciones pueden ser valores Unicode\n∑(x, y) = x + y\n\nprintln(\"\")\nprintln(∑(6, 7))\n\n# Usando la palabra reservada return\nfunction g(x,y)\n    return x * y          # Retorna este valor\n    x + y               \nend\n\nprintln(g(2, 3))\n\n# Tipo de Retorno\n# Para especificar un tipo de retorno se usa el operador ::\n\nfunction g1(x, y)::Int8\n    return x * y\nend;\n\nprintln(typeof(g1(5, 10)))  # Devuelve Int8\n\n# Retornando nothing - Funciones que no retornan nada\nfunction printx(x)\n    println(\"x = $x\")\n    return nothing\nend\n\nprintx(1)\n\n# Operadores como funciones\nprintln(+(1, 2, 3, 4))   # Retorna la suma que es 10\n\n# Funciones anónimas\n# x -> x^2 + 2x - 1\n# Se usan por lo general en funciones que toman otras funciones como argumentos (funciones de orden superior)\n\nprintln(map(x -> x^2 + 2x - 1, [1, 3, -1]))  # Retorna [2, 14, -2]\n\n# Función sin parámetros ni retorno\nfunction x()\n    return nothing\nend\n\nx()\n\n# Funciones Varargs - Funciones de número variable de argumentos\nbar(a,b,x...) = (a,b,x)\n\nprintln(bar(1,2,3,4,5,6))\n\n# RETO EXTRA\nprintln(\"\")\nprintln(\"*****RETO EXTRA*****\")\nprintln(\"\")\n\nfunction imprimir(cadena1, cadena2)\n    num = 0\n    for i = 1:100\n        if i % 3 == 0 && i % 5 == 0\n            println(cadena1, cadena2)\n        elseif i % 3 == 0\n            println(cadena1)\n        elseif i % 5 == 0\n            println(cadena2)\n        else \n            num += 1\n            println(i)\n        end\n    end\n    return num\nend\n\ncantNumImp = imprimir(\"Hola\", \"Mundo\")\nprintln(\"Número de veces que fue impreso un número: $cantNumImp\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/julia/santiago-munoz-garcia.jl",
    "content": "# Función sin parámetros ni return\nfunction funcion_sin_parametros()\n    println(\"Esta es una función sin parámetros ni return\")\nend\n\n# Función con un parámetro sin return\nfunction funcion_con_un_parametro(x)\n    println(\"El parámetro recibido de esta función es: $x\")\nend\n\n# Función con varios parámetros y return\nfunction suma(a::Number, b::Number) \n    resultado = a + b\n    println(\"La suma de $a y $b es: $resultado\")\n    return resultado\nend\n\n# Función que devuelve nothing según el valor de un parámetro\nfunction division(dividendo::Number, divisor::Number)\n    if divisor == 0\n        println(\"Error: División por cero\")\n        return nothing  # Retornamos nothing si el divisor es cero\n    else\n        return dividendo / divisor  # Retornamos el resultado de la división\n    end\nend\n\n# Función dentro de otra función\nfunction funcion_externa()\n    println(\"Esta es la función externa.\")\n    \n    # Definición de la función interna\n    function funcion_interna()\n        println(\"Esta es la función interna, llamada desde la función externa.\")\n    end\n    \n    # Llamada a la función interna\n    funcion_interna()  \nend\n\n# Uso de funciones ya creadas en el lenguaje\nfunction longitud_arreglo(arr::Vector)::Int\n    # La función `length` nos devuelve la longitud de un array\n    longitud = length(arr)\n    println(\"La longitud del arreglo es: $longitud\")\n    return longitud\nend\n\n# Variables locales y globales\nglobal_var::Int = 10  # Variable global\n\nfunction variable_local()\n    local_var::Int = 5  # Variable local\n    println(\"Dentro de la función:\")\n    println(\"Variable local: $local_var\")\n    println(\"Variable global: $global_var\")\nend\n\n#  Función que recibe dos cadenas de texto y retorna un número\nfunction imprimir_numeros(cadena1::String, cadena2::String)::Int\n    contador::Int = 0  # Contador para los números impresos\n    println(\"Imprimiendo números del 1 al 100:\")\n    \n    for n in 1:100\n        if n % 3 == 0 && n % 5 == 0\n            println(\"$cadena1$cadena2\")  # Imprime la concatenación si es múltiplo de 3 y 5\n        elseif n % 3 == 0\n            println(cadena1)  # Imprime cadena1 si es múltiplo de 3\n        elseif n % 5 == 0\n            println(cadena2)  # Imprime cadena2 si es múltiplo de 5\n        else\n            println(n)  # Imprime el número si no es múltiplo de 3 ni de 5\n            contador += 1  # Incrementa el contador\n        end\n    end\n    return contador  # Devuelve el contador de números impresos\nend\n\n# Llamadas a las funciones anteriores\nprintln(\"=== Función sin parámetros ===\")\nfuncion_sin_parametros()\n\nprintln(\"\\n=== Función con un parámetro ===\")\nfuncion_con_un_parametro(42)\n\nprintln(\"\\n=== Función con varios parámetros y return ===\")\nresultado_suma = suma(3, 5) \n\nprintln(\"\\n=== Función externa e interna ===\")\nfuncion_externa()\n\nprintln(\"\\n=== Función que devuelve nothing ===\")\ndivision(12,0)\n\nprintln(\"\\n=== Función de longitud de array con `length` ===\")\nlongitud = longitud_arreglo([1, 2, 3, 4, 5])\n\nprintln(\"\\n=== Variables locales y globales ===\")\nvariable_local()\n\nprintln(\"\\n=== Función ejercicio opcional ===\")\ncontador_resultado = imprimir_numeros(\"Fizz\", \"Buzz\")\nprintln(\"Total de números impresos en pantalla: $contador_resultado\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/kotlin/Ancarlu.kt",
    "content": "import org.intellij.lang.annotations.Language\n\n\n//Variable global\nconst val name = \"Adrian\"\n\nfun main() {\n    //Fucniones básicas de Kotlin\n    //Sin parametros ni retorno\n    basic()\n\n    //Con parametros\n    param(name)\n\n    //Con retorno\n    println(retorno())\n\n    //Con parametro y retorno\n    println(both(2, 3))\n\n    //Funciones lambda\n    lamba(5, 6) {\n        println(\"El ejemplo de una función lambda da como resultado $it\")\n    }\n\n    //Funcion dentro de funcion, que en Kotlin se denominan anidadas\n    nested()\n\n    //Ejemplos de funciones ya creadas en kotlin\n    val z = name.length\n    println(\"Mi nombre tiene \" + z + \" letras\")\n    val upper = name.uppercase()\n    println(upper)\n\n    println(\n        \"El numero de veces que se ha impreso el número en lugar de los textos es \"\n                + exercise2(\"Kotlin\", \"Jetpack Compose\")\n    )\n}\n\n\nfun exercise2(char1: String, char2: String): Int {\n    var x = 0\n\n    for (i in 1..100) {\n        if (i % 3 == 0 && i % 5 != 0) {\n            println(char1)\n        } else if (i % 5 == 0 && i % 3 != 0) {\n            println(char2)\n        } else if (i % 3 == 0 && i % 5 == 0) {\n            println(char1 + char2)\n        } else {\n            println(i)\n            x++\n        }\n    }\n    return x\n}\n\nfun nested() {\n    fun example() {\n        //Ejemplo de variable Local\n        val kotlin = \"Kotlin\"\n        println(\"Estoy programando en $kotlin\")\n    }\n    example()\n}\n\nfun lamba(x: Int, y: Int, resultado: (result: Int) -> Unit) {\n    resultado(x * y)\n}\n\nfun both(x: Int, y: Int): String {\n    //Variable local\n    var suma = x + y\n    return \"La suma de $x + $y es $suma\"\n}\n\nfun retorno(): String {\n    return \"Ejemplo de fuincion devolviendo algun parametro\"\n}\n\nfun param(name: String) {\n    println(\"Me llamo $name\")\n}\n\nfun basic() {\n    println(\"Hola a todos\")\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/kotlin/HawkBott.kt",
    "content": "fun main() {\n\n    println(\"------------ APARTADO 1 ------------\")\n\n    println(\"--Class functionsNotReturn--\")\n    //Instance functionsNotReturn\n    val instance1 = functionNotReturn()\n\n    print(\"notParameterNotReturn -> \")\n    instance1.notParametersNotReturn()\n\n    print(\"parameterNotReturn -> \")\n    instance1.parameterNotReturn(\"nameExample\")\n\n    print(\"parametersNotReturn -> \")\n    instance1.parametersNotReturn(\n        \"nameExample\",\n        \"lastnameExample\",\n        17\n    )\n\n\n    println(\"--Class functionsWithReturn--\")\n    //Instance functionWithReturn\n    val instance2 = functionWhitReturn()\n\n    println(\"notParameterReturn -> \" + instance2.notParameterReturn())\n    //Function only with a parameter and return\n    println(\n        \"parameterReturn -> \" +\n                instance2.parameterReturn(\"nameExample\")\n    )\n    //Function with very parameter and return\n    println(\n        \"ParametersReturn -> \" +\n                instance2.parametersReturn(\n                    \"nameExample\",\n                    \"lastnameExample\",\n                    17\n                )\n    )\n\n    println(\"--Other--\")\n    print(\"parameterDefault -> \")\n    parameterDefault()\n\n    val resultALineExpression = aLineExpression()\n    println(\"aLineExpression -> $resultALineExpression\")\n\n    val resultFunctionAnonymusLambda = functionAnonymusLambda(\n        \"nameExample\"\n    )\n    println(\n        \"functionAnonymusLambda -> \" +\n                resultFunctionAnonymusLambda\n    )\n\n    val resultfunctionAnonymusLambdaParameters =\n        functionAnonymusLambdaParameters(\n            \"nameExample\",\n            \"lastnameExample\",\n            17\n        )\n    println(\n        \"functionAnonymusLambdaParameters -> \" +\n                resultfunctionAnonymusLambdaParameters\n    )\n\n    println(\"--higherOrderFunctions--\")\n\n    val name = \"nameExample\"\n    val higherOrder = higherOrderFunctions()\n\n    //Funcion de orden superior (recibe otra funcion como parametro)\n    print(\"higherOrderWhithOtherFuncion -> \")\n    higherOrder.higherOrderWhithOtherFuncion(\n        name,\n        higherOrder.greetingFuntion\n    )\n\n    //funcion de orden superior con retorno de funcion\n    val returnString: (String) -> String = higherOrder.higherOrderReturn()\n    val otherString = returnString(\"nameExample\")\n    println(otherString)\n\n    print(\"Function Extension String -> \")\n    val nameExtension = \"exampleName\"\n    nameExtension.xd()\n\n    print(\"Fuction extension Int -> \")\n    val number1: Int = 3\n    println(number1.addition(3))\n\n\n    println(\"Funcion infix -> $resultado\")\n\n    print(\"Funcion con un numero variable de argumento -> \")\n    printall(\"Hola\", \"Mundo\")\n\n\n    print(\"Llamado a la funcion inline (NO inflacion) -> \")\n    inlineFunction {\n        println(\"Hola\")\n    }\n\n    print(\"Funcion local (definida dentro de otra funcion ->\" )\n    outerFunction()\n\n\n    println (\"----------DICULTAD EXTRA----------\")\n    println (prueba(\"multiplo3\", \"multiplo5\"))\n\n\n}\n\n\n\nclass functionNotReturn(){\n\n    // funcion sin parametros sin retorno\n    fun notParametersNotReturn(){\n        println(\"nameExample\")\n    }\n\n    // Funcion con un solo parametro sin retorno\n    fun parameterNotReturn(name: String){\n        println(\"Hola $name\")\n    }\n\n    // Funcion con muchos parametros sin retorno\n    fun parametersNotReturn(name: String, lastname: String, age: Int){\n        println(\"Hola $name $lastname, tu edad es $age\")\n    }\n\n}\n\nclass functionWhitReturn(){\n\n    //Funcion sin parametro con retorno\n    fun notParameterReturn(): String {\n        return (\"Hola Mundo\")\n    }\n\n    //funcion con solo un parametro con retorno\n    fun parameterReturn(name: String): String{\n        return (name)\n    }\n\n    //Funcion con muchos parametro con retorno\n    fun parametersReturn(\n        name: String,\n        lastname: String,\n        age: Int): String{\n        return (\"Hola $name $lastname, tu edad es de $age\")\n    }\n\n\n}\n\nfun parameterDefault(\n    name: String =\"nameExample\",\n    age: Int = 17){\n    println(\"Hola $name, tu edad es $age\")\n}\n\nfun aLineExpression (name:String = \"nameExample\") = \"Hola $name\"\n\nval functionAnonymusLambda = {name: String -> \"Hello $name\"}\n\nval functionAnonymusLambdaParameters = {\n        name: String,\n        lastname: String,\n        age: Int -> \"Hola $name $lastname, tu edad es $age\"}\n\n\n\n\n\n\nclass higherOrderFunctions(){\n\n    val greetingFuntion: (String) -> String = {\n            input -> \"Hola, welcome\"\n    }\n\n    fun higherOrderWhithOtherFuncion (\n        name: String,\n        greetingFuntion: (String) -> String\n    ){\n        println(greetingFuntion(name))\n    }\n\n    fun higherOrderReturn(): (String) -> String{\n        return {name -> \"Hello, $name\"}\n    }\n\n}\n\n\nfun String.xd(){\n    println(\"Hello, $this\")\n}\n\n// Define an extension function for Int class\nfun Int.addition(number: Int): Int {\n    return this * number\n}\n\n\ninfix fun Int.times(str: String) = str.repeat(this)\n\nval resultado = 3 times \"hola\"\n\n\nfun printall (vararg texto: String){\n    for (message in texto) println (message)\n}\n\n\ninline fun inlineFunction(block: () -> Unit) {\n    block()\n}\n\n\nfun outerFunction() {\n    fun innerFunction() {\n        println(\"This is an inner function.\")\n    }\n    innerFunction()\n}\n\n\nfun prueba(texto1:String, texto2: String): Int {\n\n    var contadorNumberPrint = 0\n\n    for (i in 1..100) {\n        when {\n            i % 3 == 0 && i % 5 == 0 -> println(texto1 + texto2)\n            i % 3 == 0 -> println(texto1)\n            i % 5 == 0 -> println(texto2)\n            else -> {\n                println(i)\n                contadorNumberPrint++\n            }\n\n        }\n    }\n    return (contadorNumberPrint)\n\n}\n\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/kotlin/Luis-VB.kt",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n//Without parameters or return\nfun hello1() {}\n\n// with one, two or more parameters\n\nfun hello2(name: String) {\n    println(\"Hello $name\")\n}\n\n//With default params\nfun hello3(name: String = \"Luis\") {\n    println(\"Hello $name\")\n}\n\n// with return\nfun hello4(name: String): String {\n    return \"Hello $name\"\n}\n\n//With functions inside functions\nfun hello5(name: String) {\n    fun hello6(name: String) {\n        println(\"Hello $name\")\n    }\n    hello6(name)\n}\n\n//With multiple arguments\nfun multipleDefArgs(\n    language: String = \"Python\",\n    name: String = \"Juan\",\n    alias: String = \"Juanillo\",\n    age: String = \"37\"\n) {\n    println(\"Hello $name, your alias is $alias, you are $age years old and you like $language language\")\n}\n//With variable args with key value\n\nfun main() {\n    hello1()\n    println()\n    hello2(\"Luis\")\n    println()\n    hello3(\"Luis\")\n    println()\n    hello3()\n    println()\n    hello4(\"Luis\")\n    println()\n    hello5(\"Luis\")\n    println()\n    multipleDefArgs(\"\", \"\", \"\", \"\")\n    println()\n    mynums(\"The number \\$i is multiple of 3 \", \"The number \\$i is multiple of 5\")\n    println()\n}\n\nfun mynums(text1: String, text2: String): Int {\n    var count = 0\n    for (i in 1..100) {\n        when {\n            i % 3 == 0 && i % 5 == 0 -> println(\n                \"${\n                    text1.replace(\n                        \"\\$i\", i.toString()\n                    )\n                } ${text2.replace(\"\\$i\", i.toString())}\"\n            )\n\n            i % 3 == 0 -> println(text1.replace(\"\\$i\", i.toString()))\n            i % 5 == 0 -> println(text2.replace(\"\\$i\", i.toString()))\n            else -> {\n                println(i)\n                count += 1\n            }\n        }\n    }\n    return count\n}\n\n//DIFICULTAD EXTRA (opcional):\n//* Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n//* - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n//*   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n//*   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n//*   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n//*   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\n\n\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/kotlin/OcandoDev.kt",
    "content": "// Variable global\nconst val username  = \"OcandoDev\"\n\n//funcion simple\nfun greeting(){\n    println(\"Hola $username!\")\n}\n\n//funcion con parametros\nfun sum(a: Int, b: Int): Int{\n    return a + b\n}\n\n//funcion con argumentos por defecto\nfun calculateArea(width: Int, height: Int = 10): Int{\n    return width * height\n}\n\n//funcion de Unit\nfun printMessage(message: String){\n    println(message)\n}\n\n//funcion de orden superior\nfun operation(a: Int, b: Int, operation: (Int, Int) -> Int): Int{\n    return operation(a, b)\n}\n\n//funcion con extension\nfun String.inUpperCase(): String{\n    return this.uppercase()\n}\n\n//funcion anonima\nval havingFun = fun(a: Boolean): String{\n    return when (a) {\n        true -> \"Super! :D\"\n        false -> \"You should practice more to have fun :)\"\n        else -> \"Sorry! I don't get it\"\n    }\n}\n\n//funcion infija\ninfix fun String.sameAs(txt: String): Boolean {\n    return this == txt\n}\n\n// ---Ejercicio---\nfun fizzbuzz(fizz: String, buzz: String): Int {\n    var count = 0\n    for (i in 1..100) {\n\n        when {\n            i % 3 == 0 && i % 5 == 0 -> {\n                print(\"$fizz$buzz \")\n            }\n\n            i % 3 == 0 -> {\n                print(\"$fizz \")\n            }\n\n            i % 5 == 0 -> {\n                print(\"$buzz \")\n            }\n\n            else -> {\n                print(\"$i \")\n                count++\n            }\n        }\n    }\n    println()\n    return count\n}\n\n    fun main(){\n        greeting()\n\n        //Variable local\n        val result = sum(4, 4)\n        println(result)\n\n        val area = calculateArea(2)\n        println(area)\n\n        printMessage(\"This is a unit function!\")\n\n        //funcion de order superior\n        val substraction = {a: Int, b: Int -> a - b }\n        val substraction_result = operation(6, 3, substraction)\n        println(substraction_result)\n\n        val numberList = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)\n        //funcion lambda\n        val evenNumbers = numberList.filter {it % 2 == 0}\n        print(\"$evenNumbers \")\n\n        println()\n\n        val usernameUpperCase = username.inUpperCase()\n        println(usernameUpperCase)\n\n        //funcion local\n        fun farewell(name: String): String{\n            return \"Bye $name!\"\n        }\n        println(farewell(username))\n\n        val status = havingFun(true)\n        println(status)\n\n        val person1 = \"Alejandro\"\n        val person2 = \"Alejandro\"\n\n        val samePerson = person1 sameAs person2\n        println(samePerson)\n\n        println(\"EJERCICIO EXTRA!\")\n        println(fizzbuzz(\"fizz\", \"buzz\"))\n    }"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/kotlin/SebasGRDev.kt",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n  fun basicFun() {\n    println(\"Funcion sin parametros ni retornos\")\n }\n\n fun presentacion (nombre: String, edad: Int) {\n    println(\"Hola, $nombre con $edad anios\")\n }\n\n fun esMayorDeEdad(edad: Int): Boolean {\n    if(edad >= 18) {\n        println(\"${presentacion(\"Sebas\", edad)} Eres mayor de edad!\")\n        return true\n    } else {\n        println(\"Lo siento, no eres mayor de edad\")\n        return false\n    }\n }\n\n  fun dificultadExtra(texto1: String, texto2: String): Int {\n     \n     var contador = 0\n     \n    for(i in 1..100) {\n        if((i % 3 == 0) && (i % 5 == 0)) {\n            println(\"$texto1\" + \"$texto2\")\n        }else if (i % 3 == 0) {\n            println(texto1)\n        } else if (i % 5 == 0) {\n            println(texto2)  \n        } else {\n            contador++\n        }\n    }\n    println(\"El número de veces que se ha impreso el número en lugar de los textos es: $contador\")\n    return (contador)\n }"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/kotlin/VincentRodriguezR.kt",
    "content": "fun main(){\n\n    //Punto #1 -> Explorar funciones\n\n    //Funciones sin retorno y sin parametros locales\n    fun interna(){\n        println(\"Esta es la salida de una funcion sin parametros locales ni retornos\")\n    }\n\n    //Funciones con parametros locales y sin retorno\n    fun locales(loc: String){\n        println(\"Esta es la salida de una funcion con parametros locales, dichos parametros se dan al momento de llamar la funcion, en este caso son: $loc\")\n    }\n\n    //Funciones con parametros locales y retornos\n    fun sum(num1: Int, num2:Int): Int{ //Despeus de los parentesis se debe poner el tipo de dato que retornara la funcion\n        var res = num1 + num2\n        println(\"Esta es una funcion que recibe 2 parametros y tiene un retorno, en este caso el retorno sera la suma de 2 numeros enteros osea: $res\")\n        return res\n    }\n\n    //Funciones anidadas\n    fun div(num1:Int, num2:Int){\n        var res = num1/num2\n        println(\"Esta es la prueba de una funcion dentro de otr funcion, la primera funcion contiene esta salida de texto y hace una division entre 2 numeros recibidos, el resultado es: $res\")\n        fun residuo(val1: Double, val2: Double){\n            var residuoDiv =  val1%val2\n            println(\"Esta cadena de texto se imprime desde la funcion residuo la cual se encuentra dentro de la funcion div, esta funcion devuelve el residuo de la division de 2 numeros solicitados, en este caso el residuo es: $residuoDiv\")\n        }\n        residuo(1.22, 0.2)\n    }\n\n    //Funciones ya creadas\n    val texto: String = \"Kotlin lang\"\n    val textoUpper: String = texto.toUpperCase() //Esta funcion cambia toda la cadena de texto a mayusculas\n    val textoLength: Int = texto.length //Esta funcion nos da el largo de la cadena de texto\n    println(\"Demostracion de uso de funciones existentes, Texto original: $texto, Texto en mayusculas: $textoUpper, Largo del Texto: $textoLength\")\n\n    //Variables locales y globales\n\n    //Globales\n    var global = \"Esto es una variable global ya que no esta definida dentro de ninguna funcion ni hace parte de una funcion como prametro, se puede usar en toda la clase sin problema\"\n    println(global)\n\n    //Locales\n    fun variables(locales1: String){\n        var locales2 = \"Esto es una variable local, solo funcionara dentro de esta funcion, al igual que locales1 el cual es parametro de esta funcion solo funciona dentro de ella a diferencia que se debe definir siempre que se llame esta funcion\"\n        println(\"$locales1 y $locales2\")\n    }\n\n    //Ejecucion de las funciones anteriores\n\n    interna() //Ejecucion de funcion sin parametros ni retornos\n    locales(\"esto es una funcion con parametros\") //Ejecucion de funcion con parametros, de deben dar los parametros solicitados entre los parentesis\n    var retornos = sum(5, 5) //Ejecucion de funcion con parametros y con retornos, se debe hacer en una variable para poder almacenar el retorno\n    div(2, 3) //Ejecucion de funciones anidadas, se ejecuta la funcion principal que contine las demas funciones, las funciones anidadas solo se pueden ejecutar en dicha funcion, no fuera\n    variables(\"Hola Local\")\n\n    //Ejercicio extra\n    fun multiplos(multiplos3: String, multiplos5: String): Int{\n        var contador: Int = 0\n        for(i in 1..100){\n            when{\n                i%3 == 0 && i%5 == 0 -> println(\"$multiplos3, $multiplos5\")\n                i%3 == 0 -> println(\"$multiplos3\")\n                i%5 == 0 -> println(\"$multiplos5\")\n                else -> {\n                    println(\"$i\")\n                    contador++\n                }\n            }\n        }\n        return contador\n    }\n\n    val resultado = multiplos(\"Multiplo de 3\", \"Multiplo de 5\")\n    println(\"Se imprimio $resultado veces el numero\")\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/kotlin/VolumiDev.kt",
    "content": "  var variable_global : String = \"GLOBAL (podemos usarla en todas las funciones)\"\n\n// Ejemplo de una funcion que recibe parametros y tiene un return\nfun sumar(a: Int, b: Int): Int {\n  return a + b\n}\n\n// Funcion que no recibe parametros ni tiene retorno\nfun restar(){\n  var variable_local : String = \"Esta es una varible local, solo para el ambito de esta funcion\"\n  var a = 10\n  var b = 5\n  println(\"El resutaldo es de ${a-b}\")\n  println(variable_local)\n}\n\n// Funcion que recibe un solo parametro\nfun hello(cadena : String){\n  println(\"Hello $cadena !!!\")\n}\n// Funcion con parametros predeterminado\nfun predet_fun(cad: String = \"Este es el valor predeterminado\"){\n  println(\"$cad\")\n}\n\n// creamos una funcion dentro de otra\nfun crear_funciones(){\n  fun sum(){\n    println(\"Este mensaje esta dentro de un funcion que ha sido crada dentro de otra\")\n  }\n\n  println(\"Estamos dentro de la funcion 1\")\n  sum()\n}\n\n// Funciones de extension\nfun String.combi() : String {\n  var cadena = this.uppercase()\n  cadena = cadena.reversed()\n  return cadena\n}\n\n// Funciones de orden superior\nfun calcular(a: Int, b: Int, operacion: (Int, Int) -> Int): Int {\n  return operacion(a, b)\n}\n\n// Funciones lambdas \nval multiplicacion = {a: Int, b: Int -> a * b}\n\n\n  // Dificultad extra del ejercicio 02\n  /*  DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos. */\n  \nfun extra(cad1 : String, cad2 : String) : Int {\n    var cont : Int = 0\n    var indice : Int = 0\n    while(indice <= 100){\n      when{\n        indice % 5 == 0 && indice % 3 == 0 -> {print(\" $cad1$cad2\")}\n        indice % 3 == 0 -> print(\" $cad1\")\n        indice % 5 == 0 -> print(\" $cad2\")\n        else -> {\n          print(\" $indice\")\n          cont++\n        }\n      }\n      indice++\n    }\n    return cont\n  }\n\n\nfun main() {\n  var cad : String = \"todo en minus para probar\"\n  val resultado = sumar(3, 5)\n  println(\"El resultado de la suma es: $resultado\") // Salida: El resultado de la suma es: 8\n  restar()\n  predet_fun()\n  predet_fun(\"Este es el mensaje que le hemos pasado por parametro\")\n  hello(\"Kotlin\")\n  crear_funciones()\n  println(variable_global)\n\n  //Ejemplo de funcion que esta establecida en el lenguaje\n  println(cad.uppercase())\n\n  // Vamos a probar una funcion de extension\n  var cadena1 = \"Funciones de extension\"\n  cadena1 = cadena1.combi()\n  println(\"$cadena1\")\n  \n  print(\"Se han impreso ${ extra(\"fizz\", \"buzz\") } numeros\")\n\n  println(\"FUNCIONES DE ORDEN SUPERIOR\")\n  println(\"Este es el resultado de una funcion de orden superior: ${calcular(5, 4) {x, y -> x - y}}\")\n\n  println(\"FUNCIONES LAMBDA\")\n  println(\"Este es el resultado de una funcion lambda: ${multiplicacion(4, 3)}\")\n  \n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/kotlin/adridoce.kt",
    "content": " /*\n  * - Crea ejemplos de funciones básicas que representen las diferentes\n  *   posibilidades del lenguaje:\n  *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n  * - Comprueba si puedes crear funciones dentro de funciones.\n  * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n  * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n  * - Debes hacer print por consola del resultado de todos los ejemplos.\n  *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n  *\n  * DIFICULTAD EXTRA (opcional):\n  * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n  * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n  *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n  *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n  *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n  *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n  *\n  * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n  * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n  */\n  \nval PI = 3.14\n\nfun main() {\n    // Función sin parámetros ni valor de retorno:\n    helloWorld()\n    // Funcion con parametros sin valor de retorno\n    saludar(\"Adrian\")\n    // Función con parámetros y valor de retorno:\n    val resultado = sumar(10, 6)\n    println(resultado)\n    // Funcion con parametros por defecto\n    restar()\n    // Funcion propia del lenguaje\n    val texto: String = \"HOLA\"\n    println(texto.lowercase())\n\n    println(\"El valor de pi es $PI\")\n\n    val veces = retoExtra(\"Fizz\", \"Buzz\")\n    println(\"Veces: $veces\")\n}\n\nfun retoExtra(cadena1: String, cadena2: String): Int {\n    var contador = 0\n\n    for (i in 1..100) {\n        if (i % 3 == 0 && i % 5 == 0) \n            println(\"$cadena1$cadena2\")\n        else if (i % 3 == 0) \n            println(cadena1)\n        else if (i % 5 == 0) \n            println(cadena2)\n        else{\n            println(i)\n            contador++\n        } \n    }\n\n    return contador\n}\n\nfun helloWorld(){\n    println(\"Hola mundo!\")\n}\n\nfun saludar(nombre: String){\n    println(\"Bienvenido $nombre\")\n}\n\nfun sumar(a: Int, b: Int): Int{\n    println(\"La suma de $a + $b es igual a ${a + b}\")\n    return a + b\n}\n\nfun restar(a: Int = 5, b: Int = 1){\n    println(\"La resta de $a - $b es igual a ${a - b}\")\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/kotlin/blackriper.kt",
    "content": "/*\r\n  convenciones del lenguaje kotlin\r\n  1.- clases y objectos  deben empezar con  mayuscula y usar camelcase\r\n      ejemplos :\r\n      class DeclarationProcessor { /*...*/ }\r\n      object DeclarationProcessor { /*...*/ }\r\n\r\n  2.- funciones y variables  deben empezar con minuscula y usar camelcase no guiones bajos\r\n      ejemplos :\r\n      fun DeclarationProcessor() { /*...*/ }\r\n      var declarationCounter = 0\r\n\r\n  3.- factorys usados para crear instancias pueden tener el mismo nombre\r\n      ejemplos:\r\n      interface Foo { /*...*/ }\r\n      class FooImpl : Foo { /*...*/ }\r\n      fun Foo(): Foo { return FooImpl() }\r\n\r\n   4.- los metodos para test solo para testing pueden ir entre comilla (backticks) y usar guiones bajos\r\n      ejpmplos:\r\n          @Test fun `ensure everything works`() { /*...*/ }\r\n          @Test fun ensureEverythingWorks_onAndroid() { /*...*/ }\r\n\r\n   5.- las constastes de nivel superior o global se usan en mayusculas y pueden usar guines bajos(snake case)\r\n      ejemplos:\r\n          const val VERSION = 1\r\n          const val VERSION_API = 2.0\r\n\r\n\r\n   6.-objectos y instancias pueden usar camelcase, las instacias pueden iniciar con mayuscula\r\n      ejemplos:\r\n          val mutableCollection: MutableSet<String> = HashSet()\r\n          val PersonComparator: Comparator<Person> = /*...*/\r\n\r\n   7.- los atributos de clases que tengan el mismo nombre pero que uno sea publico y privado\r\n        ejemplos:\r\n           class C {\r\n               private val _elementList = mutableListOf<Element>()\r\n               val elementList: List<Element>\r\n                    get() = _elementList\r\n               }\r\n   8.- muchos puntos no se han visto en el roadmap pero es bueno dejar notar cuando se ocupen\r\n    recuerda usar nombre consisos a la funcion o clase o etc  de acuerdo a lo que representan la\r\n    aplicacion y no nombrar tus variables como palabras reservedas del lenguaje.\r\n\r\n */\r\n\r\n\r\n// variables globales\r\nval dragonBallCharacters =listOf(\"Goku\", \"Vegeta\", \"Trunks\", \"Gohan\", \"Piccolo\", \"Krillin\")\r\n\r\n// funcion sin parametros\r\nfun printDragonBallCharacters() {\r\n    for (character in dragonBallCharacters) {\r\n        println(character)\r\n    }\r\n}\r\n\r\n// funcion con parametro\r\nfun printDragonBallCharacters(character: String) {\r\n    // variable local\r\n    val existCharacter= character in dragonBallCharacters\r\n    println(\"\"\"$character exist? $existCharacter\"\"\")\r\n}\r\n\r\n// funcion con mas de un parametro y usando parametros por defecto\r\nfun printDragonBallTecnique(character: String=\"Krillin\", tecnique: String=\"Kienzan\") {\r\n   // find funcion para encontrar algun elemento de una lista y .let para llamar una funcion o sentencia dado el valor de otra funcion previa\r\n   dragonBallCharacters.find { it == character }?.let { println(\"$character used $tecnique\") }\r\n}\r\n\r\n// funcion con con retorno\r\nfun getDragonBallCharacter(): String {\r\n    return dragonBallCharacters.find { it==\"Vegeta\"}.toString()\r\n}\r\n\r\n// una funcion dentro de otra funcion\r\nfun printDragonBallTecniques() {\r\n    fun printTecnique() {\r\n       val tecniques = mapOf(\"Goku\" to \"Kaioken\", \"Vegeta\" to \"Harlic ho!!\", \"Piccolo\" to \"makankosapo\")\r\n       for ((character, tecnique) in tecniques) {\r\n           println(\"$character used $tecnique\")\r\n       }\r\n   }\r\n  printTecnique()\r\n}\r\n\r\nfun printNumberOrText(text1: String, text2: String): Int {\r\n    var num=0\r\n    for(i in 1..100){\r\n        when{\r\n           i%3==0 -> println(\"$text1\")\r\n           i%5==0 -> println(\"$text2\")\r\n           i%15==0 -> println(\"$text1 $text2\")\r\n           else -> {\r\n               println(\"$i\")\r\n               num++\r\n           }\r\n        }\r\n    }\r\n  return num\r\n}\r\n\r\n\r\n\r\nfun main() {\r\n   println(\"\\nfuncion sin parametros\\n\")\r\n   printDragonBallCharacters()\r\n   println(\"\\nfuncion con parametro\\n\")\r\n   printDragonBallCharacters(\"Bulma\")\r\n   println(\"\\nfuncion con mas de un parametro\\n\")\r\n   printDragonBallTecnique(\"Goku\", \"Kamehameha\")\r\n   printDragonBallTecnique()\r\n   println(\"\\nfuncion con retorno\\n\")\r\n   println(getDragonBallCharacter())\r\n   println(\"\\nfuncion dentro de otra funcion\\n\")\r\n   printDragonBallTecniques()\r\n   println(\"\\nExtra\\n\")\r\n   val rep=printNumberOrText(\"Hulk\", \"Aplasta\")\r\n   println(\"Numbers printed: $rep\")\r\n}\r\n\r\n\r\n/* Notas\r\n   it refiere a this en otros lenguajes y es una forma de referirce a un elemento actual  de la lista\r\n   overloading de metodos algunos lenguajes permiten nombrar una funcion de la misma manera siempre y\r\n   cuando sus parametros sean diferentes.\r\n*/"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/kotlin/deivitdev.kt",
    "content": "// Función sin parámetros ni retorno\nfun printHello() {\n    println(\"Hello\")\n}\n\n// Función con un parámetro\nfun printMessage(message: String) {\n    println(message)\n}\n\n// Función con varios parámetros\nfun printSum(a: Int, b: Int) {\n    println(\"La suma de $a y $b es ${a + b}\")\n}\n\n// Función con retorno\nfun sum(a: Int, b: Int): Int {\n    return a + b\n}\n\n// Función dentro de una función\nfun outerFunc() {\n    fun innerFunction() {\n        println(\"Esta es una función interna\")\n    }\n    innerFunction()\n}\n\n// Variable global\nvar globalVar = \"Soy una variable global\"\n\nfun main() {\n    printHello()\n    printMessage(\"Este es un mensaje\")\n    printSum(5, 10)\n    println(\"La suma de 5 y 10 es ${sum(5, 10)}\")\n    outerFunc()\n    // Variable local\n    val localVar = \"Soy una variable local\"\n    println(localVar)\n    println(globalVar)\n    println(reto02(\"Fizz\", \"Buzz\"))\n}\n\nfun reto02(a: String, b: String): Int {\n    var num = 0\n    for (i in 1..100) {\n        when {\n            i % 3 == 0 && i % 5 == 0 -> println(\"$a$b\")\n            i % 5 == 0 -> println(b)\n            i % 3 == 0 -> println(a)\n            else -> num++\n        }\n    }\n    return num\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/kotlin/didacdev.kt",
    "content": "// Funciones sin parámetros\nfun hello() {\n    println(\"hello\")\n}\n\n// Funciones con parámetros\nfun say(person: String, sentence: String) {\n    println(\"$sentence $person\")\n}\n\n// Argumentos por defecto\nfun sayHello(person: String, greet: Boolean = true) {\n    if (greet) {\n        println(\"hello $person\")\n    } else {\n        println(\"bye\")\n    }\n}\n\n// Etiquetas de los argumentos\nfun greet(person: String, hometown: String){\n    println(\"hello $person for comming from $hometown\")\n}\n\n// Parámetros variados\nfun greetToPeople(vararg people: String) {\n    for (person in people){\n        println(\"hello $person\")\n    }\n}\n\n// Unit return\nfun hello(name: String?): Unit {\n\n    if(name != null) {\n        println(\"hello $name\")\n    } else {\n        println(\"hello there\")\n    }\n}\n\n// Funciones de una sola expresión\nfun sumaDos(number: Int): Int = number + 2\n\n// Funciones con retorno\nfun sumaUno(number: Int): Int {\n    var result = number\n    return (result + 1)\n}\n\n// Notación infija\ninfix fun Int.suma(number: Int): Int {\n    var result = number\n    return (result + 2)\n}\n\n// Funciones anidadas\nfun sumaDos(number: Int, add: Boolean): Int {\n    \n    fun suma(number: Int): Int {\n        var result = number\n        return(result + 2)\n    }\n\n    if(add) {\n        return suma(number)\n    } else {\n        return number\n    }\n}\n\n// Funciones genéricas\nfun <T: Number> sumaTres(number: T): Double {\n    return number.toDouble() + 3\n}\n\n// Tail recursie\ntailrec fun sumaUno(number: Int, suma: Boolean): Int = if (suma) (number + 1) else number\n\n\n// ------------------------- Ejercicio --------------------\nfun times(textOne: String, textTwo: String): Int {\n\n    var times = 0\n\n    for (number in 1..100) {\n\n        if(number % 3 == 0) {\n            println(textOne)\n            times += 1\n        } else if (number % 5 == 0) {\n            println(textTwo)\n            times += 1\n        } else if (number % 3 == 0 && number % 5 == 0) {\n            println(\"$textOne $textTwo\")\n            times += 1\n        } else {\n            println(number)\n        }\n    }\n\n    return times\n}\n\nfun main() {\n    \n    hello()\n    say(\"Diego\", \"hello\")\n    sayHello(\"Diego\")\n    greet(person = \"Diego\", \"Madrid\")\n    greetToPeople(*arrayOf(\"Diego\", \"Pepe\"))\n    hello(\"Diego\")\n    println(sumaDos(2))\n    println(sumaUno(1))\n    println(2 suma 3)\n    println(sumaDos(1, true))\n    println(sumaTres(0.1))\n    println(sumaUno(3, true))\n    println(times(\"hola\", \"adios\"))\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/kotlin/eulogioep.kt",
    "content": "// Variable global\nvar globalVar = \"Soy una variable global\"\n\nfun main() {\n    // Función sin parámetros ni retorno\n    fun saludar() {\n        println(\"Hola, mundo!\")\n    }\n    saludar()\n\n    // Función con un parámetro y sin retorno\n    fun saludarPersona(nombre: String) {\n        println(\"Hola, $nombre!\")\n    }\n    saludarPersona(\"Alice\")\n\n    // Función con múltiples parámetros y retorno\n    fun sumar(a: Int, b: Int): Int {\n        return a + b\n    }\n    println(\"La suma de 3 y 5 es: ${sumar(3, 5)}\")\n\n    // Función con retorno implícito\n    fun multiplicar(a: Int, b: Int) = a * b\n    println(\"El producto de 4 y 6 es: ${multiplicar(4, 6)}\")\n\n    // Función dentro de otra función\n    fun operacionesMatematicas() {\n        fun restar(a: Int, b: Int) = a - b\n        println(\"La resta de 10 y 3 es: ${restar(10, 3)}\")\n    }\n    operacionesMatematicas()\n\n    // Uso de función predefinida en Kotlin\n    val lista = listOf(1, 2, 3, 4, 5)\n    println(\"La suma de la lista es: ${lista.sum()}\")\n\n    // Demostración de variable local vs global\n    fun demoVariables() {\n        val localVar = \"Soy una variable local\"\n        println(localVar)\n        println(globalVar)\n    }\n    demoVariables()\n\n    // Modificación de variable global\n    globalVar = \"He cambiado\"\n    println(globalVar)\n\n    // DIFICULTAD EXTRA\n    fun fizzBuzz(firstWord: String, secondWord: String): Int {\n        var count = 0\n        for (i in 1..100) {\n            when {\n                i % 3 == 0 && i % 5 == 0 -> println(\"$firstWord$secondWord\")\n                i % 3 == 0 -> println(firstWord)\n                i % 5 == 0 -> println(secondWord)\n                else -> {\n                    println(i)\n                    count++\n                }\n            }\n        }\n        return count\n    }\n\n    val resultado = fizzBuzz(\"Fizz\", \"Buzz\")\n    println(\"Se imprimieron números $resultado veces\")\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/kotlin/isaacus98.kt",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\nprivate var VariableGlobal: Int = 1000\n\nfun main(){\n    funcionSinRetorno()\n\n    funcionSinRetornoConUnParametro(\"Hola\")\n\n    funcionSinRetornoConDosParametros(\"parámetro 1\", \"parámetro 2\")\n\n    // Función con parámetro opcional definido\n    funcionSinRetornoConParametroOpcional(\"Hola\");\n    // Función con parámetro opcional en el qual no se ha definido el parámetro\n    funcionSinRetornoConParametroOpcional();\n\n    funcionSinRetornoVarArgs(1, 2, 3, 4, 5)\n    funcionSinRetornoVarArgs(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)\n\n    println(suma(4, 6))\n\n    imprimirArea(5, 5)\n\n    // Función lambda\n    val sum: (Int, Int) -> Int = { x: Int, y: Int -> x + y }\n    println(sum(5,8))\n\n    // Función del propio lenguaje\n    val str: String = \"hola\"\n    println(str.uppercase()) // Función uppercase: Convierte la minúsculas en mayúsculas\n\n    // Función global\n    // Las variables globales se pueden usar en todas las funciones de la classe.\n    // Las variables locales solo se pueden usar dentro de la función donde se han definido.\n    println(VariableGlobal);\n\n    // Reto extra\n    println(\"Se ha impreso un total de ${retoExtra(\"FIZZ\", \"BUZZ\")} de numeros\")\n}\n\nfun retoExtra(str1: String, str2: String): Int {\n    var contador: Int = 0\n    for (i in 1..100){\n        when{\n            i % 15 == 0 -> println(\"$str1  $str2\")\n            i % 3 == 0 -> println(str1)\n            i % 5 == 0 -> println(str2)\n            else -> {\n                println(i)\n                contador++\n            }\n        }\n    }\n\n    return  contador\n}\n\n// Función sin parámetros\nfun funcionSinRetorno(){\n    println(\"Función sin retorno\")\n}\n\n// Función con 1 parámetro\nfun funcionSinRetornoConUnParametro(str: String){\n    println(str)\n}\n\n// Función con 2 parámetros\nfun funcionSinRetornoConDosParametros(str1: String, str2: String){\n    println(\"Primer parametro: $str1\")\n    println(\"Segundo parametro: $str2\")\n}\n\n// Función con parámetro opcional\nfun funcionSinRetornoConParametroOpcional(parametroOpcional: String = \"parametro opcional\"){\n    println(parametroOpcional)\n}\n\n// Función con número de parámetros variable\nfun funcionSinRetornoVarArgs(vararg listaNumeros: Int){\n    println(listaNumeros.sum())\n}\n\n// Función que devuelve valor\nfun suma(num1: Int, num2: Int) : Int {\n    return num1 + num2\n}\n\n// Función dentro de función\nfun imprimirArea(ancho: Int, altura: Int): Unit {\n    fun calcularArea(ancho: Int, altura: Int): Int {\n        return ancho * altura\n    }\n    val area = calcularArea(ancho, altura)\n    println(\"El area es $area\")\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/kotlin/m-doce.kt",
    "content": "package com.mdoce.androidtutorial.mouredevretos\r\n\r\nvar global = 10\r\n\r\nfun main() {\r\n    saludo()\r\n    saludoPersonalizado(\"Brais\")\r\n    println(\"7 + 5 = \" + suma(5, 7))\r\n\r\n    println(global)\r\n    global = 20\r\n    println(global)\r\n\r\n    var total = dificultadExtra(\"m\", \"doce\")\r\n    println(\"Total = $total\")\r\n}\r\n\r\nfun saludo() {\r\n    println(\"Hola gente!\")\r\n}\r\n\r\nfun saludoPersonalizado(nombre: String) {\r\n    println(\"Hola $nombre!\")\r\n}\r\n\r\nfun suma(numA: Int, numB: Int): Int {\r\n    return numA + numB\r\n}\r\n\r\nfun dificultadExtra(nombre: String, apellido: String): Int {\r\n    var contador: Int = 0\r\n\r\n    for(i in 1..100) {\r\n        if(i % 3 == 0 && i % 5 == 0) {\r\n            println(\"$nombre $apellido\")\r\n        }\r\n        else if(i % 3 == 0) {\r\n            println(\"$nombre\")\r\n        }\r\n        else if(i % 5 == 0) {\r\n            println(\"$apellido\")\r\n        }\r\n        else {\r\n            println(i)\r\n            contador++\r\n        }\r\n    }\r\n\r\n    return contador\r\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/kotlin/miguelex.kt",
    "content": "fun holaMundo() {\n    println(\"Hola Mundo\")\n}\n\nfun saludo (nombre: String) {\n    println(\"Hola $nombre\")\n}\n\nfun suma(a: Int, b: Int): Int {\n    return a + b\n}\n\n// Funcion declarada dentro de funcion\n\nfun funcionInterna() {\n    println(\"Funcion fuera de funcion\")\n    fun inner() {\n        println(\"Funcion dentro de funcion\")\n    }\n    inner()\n}\n\nfun extra(a: String, b: String): Int {\n    var contNum = 0\n    for (i in 1..100) {\n        if (i % 15 == 0) {\n            println(a+b)\n        }\n        else if (i % 3 == 0) {\n            println(a)\n        }\n        else if (i % 5 == 0) {\n            println(b)\n        }\n        else {\n            println(i)\n            contNum++\n        }\n    }\n    return contNum\n}\n\nfun main() {\n    holaMundo()\n    saludo(\"Miguel\")\n    println(suma(5, 5))\n    funcionInterna()\n    println(\"Ejemplo de funcion del sistema es hacer que la cadena 'hola' salga en mayusculas: ${\"hola\".toUpperCase()}\")\n    println(\"La cantidad de numeros impresos es ${extra(\"Fizz\", \"Buuz\")}\")\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/kotlin/pedroomar23.kt",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n // Sin parametros de retorno \n fun main() {\n    println(\"Esto es una funcion sin retorno\")\n }\n\n // Con uno o varios parametros \n fun new() {\n   val numero1 = 5 \n   val numero2 = 3\n\n   println(sumar(numero1, numero2))\n }\n\n // Con retorno \n fun sum(a: Int, b: Int): Int {\n   return a + b\n }\n\n // Ejemplos de funciones ya creadas en el lenguaje \n fun prontProduct(arg1: String, arg2: String) {\n   val x = parseInt(arg1)\n   val y = parseInt(arg2)\n }\n\n // Varible Global \n const val nombre = \"Pedro\"\n\n // Variable Local \n var nombre = \"Juan\"\n\n "
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/kotlin/rikmij.kt",
    "content": "/*\n * EJERCICIO:\n- Crea ejemplos de funciones básicas que representen las diferentes\nposibilidades del lenguaje:\n- Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n- Comprueba si puedes crear funciones dentro de funciones.\n- Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n- Pon a prueba el concepto de variable LOCAL y GLOBAL.\n- Debes hacer print por consola del resultado de todos los ejemplos.\n(y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n\n * DIFICULTAD EXTRA (opcional):\nCrea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n- La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n- Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n- Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n- Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n- La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n//función sin parámetros ni retorno\nfun funcion1() {\n    println(\"Soy una función sin parámetros ni retorno\")\n}\n\n//función con 1 parámetro\nfun funcion2(word: String) {\n    println(\"Soy una función con un parámetro que es: $word\")\n}\n\n//función con X parámetros\nfun funcion3(vararg arg: String) {\n    println(\"Soy una función con varios parámetros, como: \")\n    println(arg.joinToString(\", \"))\n}\n\n//función con retorno\nfun funcion4(n1:Int, n2:Int): Int {\n    return n1 + n2\n}\n\n//función lambda\nval lambda: (String) -> String = { param: String -> \"Soy una función lambda, $param\" }\n\n//función recursiva\nfun funcion5(num:Int): Int {\n    if (num == 0){\n        return 1\n    } else{\n        return num * funcion5(num-1)\n    }\n}\n\n//función anidada\nfun anidada(dig: Int): Int {\n    fun suma(): Int{\n        return dig +1\n    }\n    fun resta(): Int{\n        return dig -1\n    }\n    fun multip(): Int{\n        return dig *4\n    }\n    fun div(): Int{\n        return multip()/2\n    }\n    return div()\n}\n\nfun ejExtra(t1:String, t2:String): String {\n    var countNum = 0\n    var countT1 = 0\n    var countT2 = 0\n    var countT12 = 0\n    for (n in 1..100){\n        if (n%3 == 0 && n%5 == 0){\n            println(t1+t2)\n            countT12 += 1\n        }\n        else if (n%3 == 0){\n            println(t1)\n            countT1 += 1\n        }\n        else if (n%5 == 0){\n            println(t2)\n            countT2 += 1\n        }\n        else{\n            println(n)\n            countNum += 1\n        }\n    }\n    return \"Hay en total '$countNum números', '$countT1 Kot', '$countT2 Lin', y '$countT12 KotLin'\"\n}\n\n\nfun main() {\n    println(\"\\n--> Función sin parámetros ni retorno\")\n    funcion1()\n\n    println(\"\\n--> Función con 1 parámetro y no retorno\")\n    funcion2(\"Kotlin\")\n\n    println(\"\\n--> Función con varios parámetros y no retorno\")\n    funcion3(\"Charmander\", \"Squirtle\", \"Bulbasaur\")\n\n    println(\"\\n--> Función con retorno\")\n    println(funcion4(2,3))\n\n    println(\"\\n--> Función lambda\")\n    println(lambda(\"soy el parámetro\"))\n\n    println(\"\\n--> Función recursiva\")\n    println(funcion5(5))\n\n    println(\"\\n--> Sí se pueden crear funciones dentro de funciones. Se llaman funciones anidadas\")\n    println(anidada(5))\n\n    println(\"\\n--> Uso de variables Locales y Globales\")\n    val name = \"Brais\"\n\n    fun presentarse() {\n        val name = \"Rick\"\n        val age = 26\n        println(\"Soy $name y tengo $age años\")\n    }\n    println(name) //funciona por ser variable global (fuera de la función\n    //println(age)  no funciona por ser variable local e intentar llamarla fuera\n    presentarse()\n\n    println(\"\\n--> Usando funciones internas de Kotlin\")\n    val numbers = listOf(1,2,3,4)\n    val mapedNumbers = numbers.map { it*2 }\n    println(mapedNumbers)\n\n    println('\\n'+\"*\".repeat(5)+\"EJERCICIO EXTRA\"+\"*\".repeat(5))\n    println(ejExtra(\"Kot\", \"Lin\"))\n\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/kotlin/tiaguiito3.kt",
    "content": "// variable global\nval soyGlobal = 1 + 2\n\nfun main(args: Array<String>) {\n    reto(\"fizz\", \"buzz\")\n    // Funciones de llamda\n    uno()\n    dos(\"Tiago\")\n    println(tres(4, 4))\n    println(cuatro(4, 4))\n    cinco()\n}\n\n// Reto\nfun reto(a: String, b: String): Unit {\n    for (i in 1..100) {\n        when {\n            i % 3 == 0 && i % 5 == 0 -> println(\"$a$b\")\n            i % 3 == 0 -> println(a)\n            i % 5 == 0 -> println(b)\n            else -> println(i)\n        }\n    }\n}\n\n\n// Funciones en Kotlin: llamada y devolucion de valores\n\n// Funcion con variable local\nfun uno () {\n    val soyLocal = 1 + 3\n    println(soyLocal)\n    println(soyGlobal)\n}\n\n// Funcion con argumentos\nfun dos (name: String) {\n    println(\"Hi $name\")\n    println(soyGlobal)\n}\n\n// Funcion con return\nfun tres (a: Int, b: Int):Int {\n    println(soyGlobal)\n    return a * b\n}\n\n// Funcion que devuelve sin return\nfun cuatro (a: Int, b: Int):Int = a * b\n\n// Funcion dentro de funcion\nfun cinco() {\n    fun cincoDos(a:Int){\n        println(a)\n        println(soyGlobal)\n    }\n    cincoDos(5)\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/kotlin/traver79.kt",
    "content": "fun main (){\n    mostrarMensaje()\n    mostrarMensaje2(\"Bienvenido\")\n    areaTriangulo(2,5)\n    val resultado=Mayorde3(5,6,11)\n    println(\"El mayor es $resultado\")\n    saludarPersona()\n    outerFunction()\n    val cuenta=extra(\"multiplo3\",\"multiplo5\")\n    println(\"Total de intercambios por texto en el extra: $cuenta\")\n    \n    \n    }\n    \n    \n    //funciones básicas que representen las diferentes posibilidades del lenguaje\n    \n    //Sin parámetros ni retorno\n    \n    fun mostrarMensaje () {\n        println(\"________________________________\")\n        println(\"Hola, bienvenido a las funciones\")\n        println(\"********************************\")\n    }\n    \n    //con uno o varios parámetros\n    \n    fun mostrarMensaje2(cadena:String){\n        println(\"________________________________\")\n        println(cadena)\n        println(\"********************************\")\n    }\n    \n    fun areaTriangulo (base: Int, altura:Int){\n        println(\"El area del triangulo con base=$base y altura=$altura es ${(base*altura)/2}\")\n    \n    }\n    \n    //con retorno\n    fun Mayorde3(v1:Int, v2:Int, v3:Int):Int {\n    when{\n    v1>v2 && v1>v3 -> return v1\n    v2>v3-> return v2\n    v3>v2-> return v3\n    else->return v2\n    }\n    \n    }\n    \n    //otras posibilidades\n    \n    // funcion con parametros determinados:\n    fun saludarPersona(nombre: String = \"Invitado\") {\n        println(\"Hola, $nombre!\")\n    }\n    \n    \n    //funciones dentro de funciones\n    fun outerFunction() {\n        println(\"Esta es la función externa.\")\n    \n        fun innerFunction() {\n            println(\"Esta es la función interna.\")\n        }\n    \n        innerFunction()//llamo a la función interna solo desde la funcion externa\n    }\n    \n    \n    // extra\n    \n    /* \n    Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n     * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n     *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n     *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n     *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n     *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n     * */\n    \n     \n     fun extra (cadena1:String, cadena2:String):Int{\n        var cuenta = 0\n        for (i in 1..100){\n            when{\n                i%5==0 && i%3==0 ->{\n                println(cadena1+cadena2)\n                cuenta++\n                } \n            i%3==0->{\n                println(cadena1)\n                cuenta++\n                }\n            i%5==0->{\n                println(cadena2)\n                cuenta++\n                }\n            else->println(i)\n            }\n                    }\n    return cuenta\n                }\n    \n        \n    \n    \n    "
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/kotlin/westwbn.kt",
    "content": "// Función sin parámetros\nfun withoutParameters() {\n    println(\"Función sin parámetros ni retorno\")\n}\n\n// Función con parámetros\nfun employeeData(name: String, age: Int, salary: Int) {\n    println(\"Nombre: $name \\nEdad: $age \\nSalario: $$salary\")\n}\n\n// Función con retorno\nfun shoppingList(products: List<String>): String {\n    return products.joinToString { it }\n}\n\n// Función con otra función en su interior\n\nfun calculator(numberOne: Int, numberTwo: Int) {\n    fun sum(numberOne: Int, numberTwo: Int): Int = numberOne + numberTwo\n    println(sum(numberOne, numberTwo))\n}\n\n// Variable global\nval globalVariable = \"Kotlin\"\n\n// Extra\nfun extra(dataOne: String, dataTwo: String): Int {\n    var count = 0\n\n    for (number in 1..100) {\n        when {\n            number % 3 == 0 && number % 5 == 0 -> println(\"$dataOne$dataTwo\")\n            number % 3 == 0 -> println(dataOne)\n            number % 5 == 0 -> println(dataTwo)\n            else -> count++\n        }\n    }\n    return count\n}\n\n\nfun main() {\n//    Variable local\n    val localVariable = \"Programando con:\"\n    withoutParameters()\n    employeeData(\"Daniel\", 48, 1500)\n    println(shoppingList(listOf(\"Fideos\", \"Aceite\", \"Arroz\", \"Carne\")))\n    calculator(12, 18)\n    println(\"$localVariable $globalVariable\")\n    println(extra(\"Fizz\", \"Buzz\"))\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/lua/14DavidNKT.lua",
    "content": "-- FUNCIONES SIMPLES\n\nfunction Hola()\n    print(\"Hola, Lua!\")\nend\n\nHola()\n\n-- FUNCIONES CON RETORNO\n\nfunction return_Hola()\n    return \"Hola, Lua!\"\nend\n\nHola = return_Hola()\nprint(Hola)\nprint(return_Hola()) -- otra forma de llamar a la funcion sin almacenarla en una variable\n\n-- FUNCION CON UN ARGUMENTO\n\nfunction arg_Hola(name)\n    print(\"Hola \" .. name)\nend\n\narg_Hola(\"David\")\n\n-- FUNCION CON ARGUMENTOS\n\nfunction args_Hola(hola, name)\n    print(hola, name)\nend\n\nargs_Hola(\"Hi\", \"David\")\n\n-- FUNCION CON ARGUMENTOS CON VALOR PREDETERMINADO\n\nfunction default_args_Hola(hola, name)\n    local name = name or \"Desconocido\"\n    print(hola, name)\nend\n\ndefault_args_Hola(\"Hi\")\n\n-- FUNCION CON ARGUMENTOS Y RETORNO\n\nfunction return_args_Hola(hola, name)\n    return hola, name\nend\n\nprint(return_args_Hola(\"Hi\", \"David\"))\n\n-- FUNCION CON RETORNO DE VARIOS VALORES\n\nfunction multiple_return_Hola()\n    return \"Hi\", \"David\"\nend\n\nhola, name = multiple_return_Hola()\nprint(hola)\nprint(name)\n\n-- FUNCION CON UN NUMERO VARIABLE DE ARGUMENTOS (VARARG)\n\nfunction variable_args_Hola(name, ...)\n    local names = {...}\n    print(\"Hola \" .. name .. \"!\")\n    for _, name in ipairs(names) do\n        print(\"Hola \" .. name .. \"!\")\n    end\nend\n\nvariable_args_Hola(\"David\", \"Lua\", \"Todos\")\n\n-- FUNCION CON TABLA DE ARGUMENTOS\n\nfunction table_args_Hola(args)\n    local hola = args.hola\n    local name = args.name\n    local lastname = args.lastname\n    print(hola, name, lastname)\nend\n\ntable_args_Hola({hola = \"Hola\", name = \"David\", lastname = \"Marques\"})\n\n-- FUNCIONES DEL LENGUAJE (BUILT-IN)\n\nprint(\"Hola\")\nprint(type(8))\nprint(tostring(123))\nprint(tonumber(\"A\", 16))\nprint(string.len(\"Hola\"))\nprint(string.sub(\"Hola\", 2, 3))\nprint(string.upper(\"Hola\"))\nprint(string.lower(\"HOLA\"))\nprint(math.abs(-10))\nprint(math.ceil(2.3))\nprint(math.floor(2.7))\nprint(math.random(1, 100))\nprint(os.time())\nprint(os.date(\"%Y-%m-%d %H:%M:%S\"))\n\n-- VARIABLES LOCALES Y GLOBALES\nglobal_var = \"Lua\"\n\nfunction hello_lua()\n    local_var = \"Hola\"\n    print(local_var, global_var)\nend\n\nprint(global_var)\n-- print(local_var) No se puede usar desde fuera de la funcion, en este caso arroja valor \"nulo\" (nil)\n\nhello_lua()\n\n-- Extra\n\nfunction range(start, stop, step)\n    local step = step or 1\n    local t = {}\n    for i = start, stop, step do\n        table.insert(t, i)\n    end\n    return t\nend\n\nfunction print_number(text1, text2)\n    local r = range(1, 100)\n    local count = 0\n    for _, v in ipairs(r) do\n        if v % 3 == 0 and v % 5 == 0 then\n            print(text1 .. text2)\n        elseif v % 3 == 0 then\n            print(text1)\n        elseif v % 5 == 0 then\n            print(text2)\n        else\n            print(v)\n            count = count + 1\n        end\n    end\n    print(count)\nend\n\nprint_number(\"Fizz\", \"Buzz\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/lua/Bert008.lua",
    "content": "--[[\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n]]\n--funciones sin argumento ni retorno\nfunction holaMundo()\n    print(\"Hola Mundo\")\nend\nholaMundo()\nfunction foo()\n    print(\"Inicio de funcion foo\")\n    holaMundo()\n    function goo()\n        print(\"Se inicia la funcion goo dentro de foo\")\n    end\n    goo()\n    print(\"Fin de la funcion foo\")\nend\nfoo()\n\nfunction funConParam(arg1, arg2)\n    return arg1 + arg2\nend\n\nsuma = funConParam(1, 2)\nprint(\"Llamamos a la funcion para sumar dos numeros: \", suma)\n\n--lo intentamos un una excepcion en lua\nfunction suma()\n    local x = 10\n    local y = 2\n    return x + y\nend\nfunction resta(a, b)\n    return a - b\nend\n\nlocal status, resultado = pcall(resta, 10, y)\n\nif status then\n    print(\"El esultado es :\", resultado)\nelse\n    print(\"Esa variable no es global\")\nend\n\nfunction extra(string1, string2)\n    count = 1\n    for i = 1, 100 do\n        if i % 3 == 0 and i % 5 == 0 then\n            print(string1, string2)\n        elseif i % 3 == 0 then\n            print(string1)\n        elseif i % 5 == 0 then\n            print(string2)\n        else\n            print(i)\n            count = count + 1\n        end\n    end\n    print(\"Numero de veces que se imprimio un numero: \", count)\nend\nextra(\"Hola\", \"Mundo\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/lua/ElTitoJet.lua",
    "content": "-- Función sin parámetros ni retorno\nfunction saludar()\n    print(\"Hola desde una función sin parámetros ni retorno\")\nend\n\nsaludar()\n\n-- Función con un parámetro\nfunction saludarNombre(nombre)\n    print(\"Hola, \" .. nombre)\nend\n\nsaludarNombre(\"Jose\")\n\n-- Función con varios parámetros y retorno\nfunction sumar(a, b)\n    return a + b\nend\n\nlocal resultado = sumar(10, 20)\nprint(\"Suma:\", resultado)\n\n-- Función que retorna múltiples valores\nfunction operaciones(a, b)\n    return a + b, a - b, a * b, a / b\nend\n\nlocal suma, resta, mult, div = operaciones(8, 2)\nprint(\"Resultados:\", suma, resta, mult, div)\n\n-- Funciones anidadas (funciones dentro de funciones)\nfunction externa()\n    print(\"Estoy en la funcion externa\")\n\n    local function interna()\n        print(\"Estoy en la funcion interna\")\n    end\n\n    interna()\nend\n\nexterna()\n\n\n-- Formatos de texto\nlocal texto = \"lua es genial\"\nprint(\"Texto original:\", texto)\nprint(\"Texto en mayusculas:\", string.upper(texto))\nprint(\"Longitud del texto:\", string.len(texto))\nprint(\"¿Empieza con 'lua'? :\", string.sub(texto, 1, 3) == \"lua\")\n\n\n-- Variables locales vs Globales\n\n-- Variable global\nglobalVar = \"Soy global\"\n\n\n\nfunction mostrarVariables()\n    -- Variable local\n    local localVar = \"Soy local\"\n    print(\"Global:\", globalVar)\n    print(\"Local:\", localVar) -- localVar solo es accesible si está en el mismo alcance\nend\n\nmostrarVariables()\n\n\n\n\n-- DIFICULTAD EXTRA\nfunction fizzBuzzPersonalizado(palabra3, palabra5)\n    local contador = 0\n\n    for i = 1, 100 do\n        local salida = \"\"\n\n        if i % 3 == 0 and i % 5 == 0 then\n        salida = palabra3 .. palabra5\n        elseif i % 3 == 0 then\n        salida = salida .. palabra3\n        elseif i % 5 == 0 then\n        salida = salida .. palabra5\n        end\n\n        if salida == \"\" then\n            print(i)\n            contador = contador + 1\n        else\n            print(salida)\n        end\n    end\n\n    return contador\nend\n\nlocal vecesNumero = fizzBuzzPersonalizado(\"Fizz\", \"Buzz\")\nprint(\"Veces que se imprimio el numero directamente:\", vecesNumero)\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/lua/ansuzgs.lua",
    "content": "-- Funcion sin parametros ni retorno\nfunction test1()\n  print(\"test1\")\nend\n\n-- Funcion con parametros, pero sin retorno\nfunction test2(a, b)\n  print(\"test2\", a, b)\nend\n\n-- Funcion con parametros y retorno\nfunction test3(a, b)\n  print(\"test3\", a, b)\n  return a + b\nend\n\nprint(\"test3(1, 2) = \", test3(1, 2))\n\n-- Funciones anidadas\nfunction test4(a, b)\n  function test5(c, d)\n    print(\"test5\", c, d)\n    return c + d\n  end\n  print(\"test4\", a, b)\n  return test5(a, b)\nend\n\nprint(\"test4(1, 2) = \", test4(1, 2))\n\n-- Funciones anonimas\ntest6 = function(a, b)\n  print(\"test6\", a, b)\n  return a + b\nend\n\nprint(\"test6(1, 2) = \", test6(1, 2))\n\n-- Funciones con retorno multiple\nfunction test7(a, b)\n  print(\"test7\", a, b)\n  return a, b\nend\n\nx, y = test7(1, 2)\nprint(\"test7(1, 2) = \", x, y)\n\n-- Variables locales\nfunction test8(a, b)\n  local c = a + b\n  print(\"test8\", a, b, c)\n  return c\nend\n\nprint(\"test8(1, 2) = \", test8(1, 2))\n\n-- Variables globales\nc = 0\nprint(\"c = \", c)\nfunction test9(a, b)\n  c = a + b\n  print(\"test9\", a, b, c)\n  return c\nend\nprint(\"test9(1, 2) = \", test9(1, 2))\n\n--[[\n  EXTRA\n]]\n\nfunction extra(text_1, text_2)\n  local count = 0\n  for i = 1, 100, 1 do\n    if i % 3 == 0 and i % 5 == 0 then\n      print(text_1 .. text_2)\n    elseif i % 3 == 0 then\n      print(text_1)\n    elseif i % 5 == 0 then\n      print(text_2)\n    else\n      print(i)\n      count = count + 1\n    end\n  end\n  return count\nend\n\nprint(\"extra('Fizz', 'Buzz') = \", extra('Fizz', 'Buzz'))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/lua/santyjl.lua",
    "content": "--[[\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n]]\n\n--funcion si parametros ni retornos\nfunction escalera ()\n    local valor = \"*\"\n    print(\"\\n\")\n    for i=1 , 10 do\n        print(valor)\n        valor = valor .. \"*\" -- con .. se pueden concatenar tanto string como listas\n    end\nend\n\nescalera()\n\nprint(\"\")\n\n-- funcion con parametros y retornos\nfunction sumador(num1 , num2)\n    return num1 + num2      -- return te da el valor para que lo puedas usar\nend\n\nprint(sumador(2 , 3))\n\n-- funciones dentro de funciones\nprint(\"\")\n\nfunction correr()\n    function caminar()\n        return \"caminando\"\n    end\n\n    local accion = \"\"\n    accion = caminar()\n    print(accion)\n    accion = \"corriendo\"\n    print(accion)\nend\n\nprint(correr())\nprint(\"que estas haciendo ? : \" .. caminar())\n\nlocal numero_random = math.random(0 , 100)\nlocal numero_maximo = math.max(7 , numero_random , 40)\nlocal cuadrado = math.sqrt(numero_random)\nlocal texto = \"Hola mundo day\"\nprint(\"\\nfunciones matematicas\")\n\nprint(\"numero random : \" .. numero_random)\nprint(\"el maximo entre el numero 7 \" .. numero_random .. \" y el  40 : \" .. numero_maximo)\nprint(\"la raiz cuadrado del numero \" .. numero_random .. \" es : \" .. cuadrado)\n\nprint(\"\\nfunciones de string : \")\nprint(string.upper(texto) .. \" funcion string.upper()\")\nprint(string.lower(texto) .. \" funcion string.lower()\")\nprint(string.len(texto) .. \" funcion string.len()\")\n\nlocal variable_local = \"esta es una varible local , solo funciona en este archivo\"\nvariable_glogal = \"esta es una varible global se puede usar en otro archivos .lua\"\n\nprint(\"\")\nprint(variable_local)\nprint(variable_glogal)\n\n-- Extra\n\nlocal function fizz_buzz(a , b)\n    local contador = 1\n    while contador <= 100  do\n        if contador % 3 == 0 and contador % 5 == 0 then\n            print(contador .. a .. b)\n\n        else if contador % 5 == 0  then\n            print(contador .. b)\n\n        else if contador % 3 == 0 then\n            print(contador .. a)\n\n        else\n            print(contador)\n\n        end\n        end\n        end\n        contador = contador + 1\n\n    end\n\nend\n\nprint(fizz_buzz(\" fizz\" , \" buzz\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/mojo/angelsanchezt.mojo",
    "content": "\"\"\"\nEJERCICIO:\n - Crea ejemplos de funciones básicas que representen las diferentes\n   posibilidades del lenguaje:\n   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n - Comprueba si puedes crear funciones dentro de funciones.\n - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n - Debes hacer print por consola del resultado de todos los ejemplos.\n   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n\n DIFICULTAD EXTRA (opcional):\n Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\n Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n\"\"\"\n\n\"\"\"\nRun a Mojo file.\n1. Instalación del Mojo SDK \n  https://docs.modular.com/mojo/manual/get-started/\n\n2. Run a Mojo file.\n  mojo angelsanchezt.mojo\n\"\"\"\n\n\"\"\"\nFunciones definidas por el usuario: Mojo soporta 2 tipos de funciones\ndef\nfn\n\"\"\"\n\n# Simple\n\ndef greet():\n    print(\"Hola, Python! def\")\n\nfn greet_fn():\n    print(\"Hola, Python! fn\")\n\n# Con retorno\n\ndef return_greet():\n    return \"Hola, Python! def\"\n\nfn return_greet_fn() -> String:\n    return \"Hola, Python! fn\"\n\n\n# Con un argumento\n\ndef arg_greet(name):\n    print(\"Hola, \" + name + \"!\")\n\nfn arg_greet_fn(name: String):\n    print(\"Hola, \" + name + \"!\")\n\nfn greet2(name: String) -> String:\n    return \"Hello, \" + name + \"!\"\n\n# Con argumentos\n\ndef args_greet(greet, name):\n    print(greet + \",\" + name + \"!\")\n\nfn args_greet_fn(greet: String, name: String):\n    print(greet + \",\" + name + \"!\")\n\n# Con un argumento predeterminado\n\ndef default_arg_greet(name=\"Python\"):\n    print(\"Hola, \" + name + \"!\")\n\nfn default_arg_greet_fn(name: String =\"Python\" ):\n    print(\"Hola, \" + name + \"!\")\n\n\n# Con argumentos y return\n\ndef return_args_greet(greet, name):\n    return greet + \", \" + name + \"!\"\n\nfn return_args_greet_fn(greet: String, name: String) -> String:\n    return greet + \", \" + name + \"!\"\n\n# Con retorno de varios valores\n\nfn multiple_return_greet() -> Tuple[StringLiteral, StringLiteral] :\n    return \"Hola\", \"Python\"\n\n# Mojo aun no soporta variable de argumentos\n# Mojo aun no soporta variable de argumentos con palabra clave.\n\n\n\"\"\"\nFunciones dentro de funciones\n\"\"\"\n\n\ndef outer_function():\n    def inner_function():\n        print(\"Función interna: Hola, Python !\")\n    inner_function()\n\n\n\n\"\"\"\nVariables locales y globales\n\"\"\"\n\nlet global_var = \"Python\"\n\n\ndef hello_python():\n    let local_var = \"Hola\"\n    print(global_var)\n    print(local_var)\n    # print(local_var + \", \" + global_var + \"!\")\n\n\n\"\"\"\nExtra\n\"\"\"\n\n\ndef print_numbers(text_1, text_2) -> Int:\n    count = 0\n    for number in range(1, 101):\n        if number % 3 == 0 and number % 5 == 0:\n            print(text_1 + text_2)\n        elif number % 3 == 0:\n            print(text_1)\n        elif number % 5 == 0:\n            print(text_2)\n        else:\n            print(number)\n            count += 1\n    return count\n\ndef main():\n    greet()\n    greet_fn()\n    print(return_greet())\n    print(return_greet_fn())\n    arg_greet(\"AngelSanchezT\")\n    arg_greet_fn(\"AngelSanchezT\")\n    args_greet(\"Hi\", \"Angel\")\n    args_greet(name=\"Angel\", greet=\"Hi\")\n    args_greet_fn(\"Hi\", \"Angel\")\n    args_greet_fn(name=\"Angel\", greet=\"Hi\")\n    default_arg_greet(\"Angel\")\n    default_arg_greet()\n    default_arg_greet_fn(\"Angel\")\n    default_arg_greet_fn()\n    print(return_args_greet(\"Hi\", \"Angel\"))\n    print(return_args_greet_fn(\"Hi\", \"Angel\"))\n\n    var greet = ''\n    var name = ''\n    greet, name = multiple_return_greet()\n    print(greet)\n    print(name)\n\n    outer_function()\n    \"\"\"\n    Funciones del lenguaje (built-in)\n    \"\"\"\n\n    print(len(\"AngelSanchezT\"))\n\n\n    print(global_var)\n    # print(local_var) No se puede acceder desde fuera de la función\n\n    hello_python()\n\n    print(print_numbers(\"Fizz\", \"Buzz\"))\n\n    \n\n\n\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/mql4/confley.mq4",
    "content": "// todo. FUNCIONES ================================================================================\n// FUNCIÓN SIMPLE \nvoid HelloFunction() {\n    Print(\"Hola usuario :D\"); \n}\n\n// FUNCIÓN CON PARÁMETROS \nvoid HelloFunction(string user) {\n    Print(\"Hola \", user, \" ten un excelente día ^-^\"); \n}\n\n// FUNCIÓN CON RETORNO \nstring Hello() {\n    return \"¿Qué tal?, usuario :0\"; \n}\n\n// CREAR FUNCIONES DENTRO DE UNA FUNCIÓN\n//! Error -  No es posible hacer esto \n\n// FUNCIÓN PREDEFINIDA \n// Devuelve el valor más grande entre 2 números \ndouble biggestNumber = MathMax(10, 5); // Función pre-definida\ndouble CustomMathMax(double a, double b) {\n    return (a >= b) ? a : b; \n}\n\n\n\n// todo. VARIABLES ================================================================================\n// VARIABLES (GLOBAL Y LOCAL)\nstring variable = \"GLOBAL\"; \nvoid LocalAndGlobal() {\n    string variable = \"LOCAL\"; \n    Print(\"Dentro del método tiene priodidad la variable \", variable); \n    Print(\"Pero también podemos acceder a la variable \", ::variable, \" usando -> ::variable\"); \n}\n\n\n\n//todo. EXTRA =====================================================================================\nint Bonus(string oneStr, string twoStr) {\n    int coutn = 0; \n    \n    for(int i=1; i <= 100; i++) {\n        \n        bool multipleOf3 = (i%3 == 0), multipleOf5 = (i%5 == 0); \n        \n        if(multipleOf3 && multipleOf5) \n            Print(oneStr, twoStr); \n        else if(multipleOf3) \n            Print(oneStr); \n        else if(multipleOf5) \n            Print(twoStr); \n        else {\n            coutn++; \n            Print(i); \n        }\n    }\n    \n    return coutn; \n}\n\n\n\n// todo. EJECUCIÓN ================================================================================\nvoid OnStart() {\n    HelloFunction();                // Función simple \n    HelloFunction(\"Confley\");       // Función con parámetro\n    Print(Hello());                 // Función de retorno \n    Print(biggestNumber);           // Función pre-definida \n    Print(CustomMathMax(3, 5));     // Función personalizada \n    LocalAndGlobal();               // Variables global y local\n    int x = Bonus(\"Pit\", \"Zaahot \");// Díficultad extra \n    Print(\"Los números se imprimeron \", x, \" veces\"); \n}\n\n\n// todo. OBSERVACIONES ============================================================================\n// - Las funciones solo se pueden declarar a nivel global o dentro de una clase. \n// - Acepta polimorfismo -> Varias funciones con mismo nombre, pero distintos parametros. \n// - Los :: para acceder a la variable global solo se ponen porque tenemos el mismo nombre en ambas; \n//   el tener el mismo nombre y declarar ambas variables nos genera un warning en el compilador."
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/nasm/evanz2608.s",
    "content": "; https://www.nasm.us/\n\n\n; ======================================================================================================================\n; #03 - Funciones.\n; Testeado en Arch linux. No lo he testeado en otras distribuciones.\n; Para ensamblar: nasm -f elf64 -o evanz1902.o evanz1902.s\n; Para linkear y generar el ejecutable: ld -o evanz1902 evanz1902.o -lc --dynamic-linker=/lib64/ld-linux-x86-64.so.2\n; ======================================================================================================================\n\n\n\nextern printf       ; Se usa para llamar a la función printf de libc.\n\n; ===========================================================================\n; Sección de código, con permisos de lectura y ejecución\n; ===========================================================================\nsection .text\nglobal _start\n\n; Como primer ejemplo, vamos a crear una función que imprima un string por pantalla,\n; caracter por caracter, hasta que encuentre un byte núlo, en cuyo caso terminaremos de imprimir y saldremos.\n; Va a recibir en RDI la dirección de un string y va a devolver en RAX la cantidad de bytes que ha escrito en la terminal.\n;\nmi_print:\n  mov r8, rdi           ; r8 contendrá la dirección base del string que le pasemos.\n  xor rbx, rbx          ; Limpiamos rbx para iterar sobre el string, hasta llegar al byte núlo.\n\n.loop:                  ; Una etiqueta que vamos a usar para saltar hasta lleguemos al byte núlo. Empieza por punto porque es una etiqueta local a esta función.\n  cmp byte [r8 + rbx], 0\n  jz .end\n  mov rax, SYS_write\n  mov rdi, STDOUT\n  lea rsi, [r8 + rbx]\n  mov rdx, 1\n  syscall\n  inc rbx\n  jmp .loop\n.end:\n  mov rax, rbx          ; Devolvemos cuantos bytes hemos escrito, almacenados en rbx. Por convención el valor se devuelve siempre en rax.\n  ret                   ; Y retornamos a donde fue llamada esta función\n\n\n; Función sin parámetros, sin valor de retorno.\n; Vamos a llamar a nuestra primera función, imprimiremos por pantalla \"Función sin parámetros.\".\nmi_funcion_sin_parametros:\n  mov rdi, mi_string_2\n  call mi_print\n  ret\n\n; Función que recibe 2 números en RDI, RSI, los suma e imprime su resultado por pantalla.\n; En este caso vamos a usar el stack para almacenar los valores que recibimos.\n; El stack lo podemos pensar como memoria para \"variables locales\".\n; Dentro de la función creamos un stack frame, un espacio en el stack para nuestra función, que luego cuando la ejecución de la función termine,\n; restauraremos a su estado anterior. De esta manera definimos una porción de memoria temporal que luego liberaremos para su posterior uso por cualquier\n; parte de nuestro programa.\n; Hay que tener en cuenta, que si bien es una memoria que podemos usar a nuestro antojo, debemos dejar RBP y RSP en su estado anterior, puesto que \n; cada función puede tener datos guardados en ella, ademas de que se guarda el punto de retorno en el stack, y si no lo restauramos, estaremos corrompiendo\n; los datos que funciones anteriores tengan guardadas en el stack.\nfuncion_con_parametros:\n  push rbp                    ; Guardamos RBP en el stack, para luego restaurar su valor.\n  mov rbp, rsp                ; Apuntamos al final del stack.\n  sub rsp, 32                 ; Y reservamos 32 bytes. Es importante notar que para poder llamar a funciones, el stack debe estar alineado a 16 bytes,\n                              ; es por eso que reservamos 32 bytes a pesar de sólo usar 24 bytes. Si no fuerámos a llamar a ninguna función dentro de esta,\n                              ; podríamos simplemente reservar 24 bytes.\n\n  mov [rbp - 32], rdi         ; Guardamos el primer valor que le pasamos a la función en el stack.\n  mov [rbp - 24], rsi         ; Lo mismo con el segundo. \n\n  add rdi, rsi                ; Sumamos ambos valores\n  mov [rbp - 16], rdi         ; Y guardamos el resultado en el stack.\n\n  lea rdi, [printf_mask]      ; Nos preparamos para llamar a printf\n  mov rsi, [rbp - 32]         ; Cargamos en rsi, el primer valor que le pasamos a la función\n  mov rdx, [rbp - 24]         ; El segundo valor\n  mov rcx, [rbp - 16]         ; Y el resultado de la suma\n  call printf\n\n  add rsp, 32                 ; Restauramos RSP a su valor inicial. Ahora RSP apunta a donde guardamos RBP.\n  pop rbp                     ; Y restauramos RBP a su valor anterior. Ahora tanto RBP como RSP apuntan al stack frame de la función desde donde\n                              ; se llamó a esta función.\n  ret                         ; Y retornamos.\n\n\n; Función con parámetros y valor de retorno.\n; Por convención, en linux x86-64 el valor de retorno siempre se carga en RAX.\n; De esta manera, quien llama a una función, puede revirar el valor de RAX luego de la llamada.\n; va a recibir dos números, y devolver la suma.\nfuncion_con_retorno:\n  mov rax, rdi\n  add rax, rsi\n  ret\n\n\n; =============================================================\n; Ejercicio extra\n; =============================================================\n\n; Funciones auxiliares\n\n; divide_counter recibe en rbx el divisor.\ndivide_counter:\n  xor rdx, rdx\n  mov rax, [counter]\n  div rbx\n  ret\n\n; Y nuestra función.\nejercicio_extra:\n  push rbp\n  mov rbp, rsp\n\n.main_loop:\n  inc dword [counter]\n  cmp dword [counter], 101\n  je .end\n\n  mov rbx, 3\n  call divide_counter\n  push rdx\n  mov rbx, 5\n  call divide_counter\n  push rdx\n\n  pop rbx\n  pop rax\n\n  cmp rax, rbx\n  jne .test_individual\n\n  cmp rax, 0\n  je .print_ambos\n  jne .print_number\n\n.print_3:\n  mov rdi, printf_str_mask\n  mov rsi, string1\n  call printf\n  jmp .main_loop\n\n.print_5:\n  mov rdi, printf_str_mask\n  mov rsi, string2\n  call printf\n  jmp .main_loop\n\n.print_ambos:\n  mov rdi, string1\n  call mi_print\n  mov rdi, string2\n  call mi_print\n  mov rdi, new_line\n  call mi_print\n  jmp .main_loop\n\n.print_number:\n  mov rdi, printf_num_mask\n  mov rsi, qword [counter]\n  call printf\n  jmp .main_loop\n\n.test_individual:\n  test rax, rax\n  jz .print_3\n  test rbx, rbx\n  jz .print_5\n  jmp .print_number\n\n.end:\n  pop rbp\n  ret\n\n\n\n; Entry point de nuestro programa\n_start:\n  lea rdi, [mi_string]\n  call mi_print       ; Y aquí llamamos a nuestra función.\n  call mi_funcion_sin_parametros\n  mov rdi, 10\n  mov rsi, 20\n  call funcion_con_parametros\n  mov rdi, 30\n  mov rsi, 20\n  call funcion_con_retorno\n  lea rdi, [printf_ret_mask]\n  mov rsi, rax\n  call printf\n\n  call ejercicio_extra\n\n\n; Terminamos la ejecucion\n; Declaro una etiqueta en caso de querer salir prematuramente del programa. Si no se llama antes,\n; _start llegará a este punto igualmente.\nexit_proc:\n  mov rax, SYS_exit\n  xor rdi, rdi\n  syscall\n\n\n\n\n\n; ===========================================================================\n; Sección de datos inicializados con permisos de sólo lectura.\n; ===========================================================================\nsection .rodata\n  SYS_exit: equ 60\n  SYS_write: equ 1\n  STDOUT: equ 1\n  mi_string: db \"Hola desde una función!\", 0x0A, 0x00\n  mi_string_2: db \"Función sin parámetros\", 0x0A, 0x00\n  printf_mask: db \"Función con parámetros: %d + %d = %d\", 0x0A, 0x00\n  printf_ret_mask: db \"Funcion con retorno: %d\", 0x0A, 0x00\n  printf_num_mask: db \"%d\", 0x0A, 0x00\n  printf_str_mask: db \"%s\", 0x0A, 0x00\n\n; Variables para el ejercicio extra\n  string1: db \"Fizz\", 0x00\n  string2: db \"Buzz\", 0x00\n  new_line: db 0x0A, 0x00\n\n\n; ===========================================================================\n; Sección de datos inicializados con permisos de lectura y escritura.\n; ===========================================================================\nsection .data\n  counter: dd 0\n\n\n\n; ===========================================================================\n; Sección de datos no inicializados con permisos de lectura y escritura.\n; ===========================================================================\nsection .bss\n  var_result: resq 1\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/ocaml/luishendrix92.ml",
    "content": "#load \"unix.cma\"\n\nopen Printf\n\n(* There are 5 ways to define functions:\n   + Named functions\n   + Lambda functions\n   + Infix operator functions\n   + Fixed recursive functions\n   + Pattern matched functions\n\n   The last way is the same as the first but it uses the [function] keyword\n   to denote that its last parameter is pattern matched. It's syntax sugar\n   for the following definition:\n\n   {[\n     let my_function a b c =\n       match c with\n       | _ -> ()\n     ;;\n   ]}\n\n   Which can be re-defined as:\n\n   {[\n     let my_function a b = function\n       | _ -> ()\n     ;;\n   ]}\n*)\n\n(** [is_palindrome s] takes a string [s] and returns [true] if it's a\n    {e palindrome} (a word/phrase that reads the same normally and reversed). *)\nlet is_palindrome s =\n  let reversed =\n    String.to_seq s |> List.of_seq |> List.rev |> List.to_seq |> String.of_seq\n  in\n  reversed = s\n;;\n\nprintf\n  \"Is 'racecar' a palindrome? %s.\\n\"\n  (if is_palindrome \"racecar\" then \"yes\" else \"no\")\n\n(** [add a b] takes two numberGs [a] and [b] and adds them together. *)\nlet add = (fun a b -> a + b)\n;;\n\nprintf \"2 + 2 is %d, quick maffs.\\n\" (add 2 2)\n\n(** [list_length l] counts the number of elements in a list [l]. *)\nlet list_length l = List.fold_left (fun count _ -> count + 1) 0 l\n;;\n\nprintf\n  \"The length of list [false; false; true] is %d.\\n\"\n  (list_length [ false; false; true ])\n\n(** Left-associative mapping operator that applies a function [a] to a list\n    [b]. [f >>| l] is equivalent to [List.map f l] under the hood. *)\nlet ( >>| ) = List.map\n;;\n\nlet string_of_ints l =\n  \"[\" ^ (List.map string_of_int l |> String.concat \", \") ^ \"]\"\nin\nlet squares = (fun x -> x * x) >>| [ 1; 2; 3; 4; 5 ] in\nprintf \"Square of numbers from 1 to 5: %s.\\n\" (string_of_ints squares)\n\n(** [factorial n] computes the factorial of a number [n]. This function\n    is {e tail-call optimized}. Returns [1] for any number less than\n    or equal to [1]. *)\nlet factorial n =\n  (* In OCaml, recursive functions can be {e tail-call optimized}. This means\n     that if the last call inside a function is the function by itself, then\n     the current stack frame gets replaced by the new one, thus avoiding\n     stack overflows because there is no need to backtrack. *)\n  let rec aux acc i = if i > n then acc else aux (acc * i) (i + 1) in\n  aux 1 1\n;;\n\nprintf \"The factorial of 5 is %d.\\n\" (factorial 5)\n\n(** [describe_char c] prints what type of character [c] is. *)\nlet describe_char = function\n  (* Sadly, OCaml's range pattern-matching is {b only available for chars}.\n     Though for numbers it can be achieved with [when] clauses. Ex:\n\n     {[\n       match n with\n       | n when n >= A_INCLUSIVE && n < B_EXCLUSIVE -> ()\n       | _ -> ()\n     ]}\n\n     Or with else/if statements, but it'd be useful to have [..].\n  *)\n  | '0' .. '9' -> print_endline \"It's a digit.\"\n  | 'a' .. 'z' -> print_endline \"It's a lowercase letter.\"\n  | 'A' .. 'Z' -> print_endline \"It's an uppercase letter.\"\n  | _ -> print_endline \"It's a symbol character :)\"\n;;\n\ndescribe_char '5';\ndescribe_char 'y';\ndescribe_char 'H';\ndescribe_char '?'\n\n(* {b Can OCaml return functions from functions?} Yes, but it's usually done\n   through two concepts called {e currying} and {e partial application}.\n   Calling a function with less parameters than defined creates a function\n   that {e closes over} (closure) the ones provided and expects the ones that\n   were left out. Currying means that a function defined with n parameters\n   will always produce a function of {b arity} (the amount of parameters) 1\n   that returns another function of arity 1 and so on until all parameters are\n   passed as arguments. The term is a reference to {e Haskell Curry}.\n\n   {b Can OCaml functions accept functions as parameters?} Yes, they're called\n   higher-order functions and they're everywhere in the standard library.\n   Some libraries have a convetion of having them as named arguments which is\n   a topic that I'll demonstrate next.\n*)\n\n(** [greet name ~greeter] sets up a roleplay scenario in which a host greets a\n    random guest [name] to their party using a greeting function [greeter]. *)\nlet greet name ~greeter =\n  print_endline (name ^ \" enters the party house...\");\n  print_endline (\"And the host says to \" ^ name ^ \":\");\n  greeter name;\n  print_endline (name ^ \" can finally enjoy the party.\")\n;;\n\n(** [greet_rudely name] rudely greets [name] to ther party. This function was\n    created using partial application on [greet], providing a greeter function\n    and returning another function that only expects a string [name]. *)\nlet greet_rudely =\n  greet ~greeter:(fun name ->\n    printf \"Who invited you, %s? Anyway, have a seat...\\n\" name)\n;;\n\ngreet_rudely \"luishendrix92\"\n\n(* Named arguments are a great way to produce readable code and APIs for users.\n   For example, the most promiment external library, [Core] (by {e Jane Street\n   Capital}) aims to serve as a replacement for the standard library and it\n   achieves so not only by optimizing and extending modules, but also by\n   providing labeled arguments to better guide the user.\n\n   Another good feature of the language is the definition of optional\n   paramenters which can also hold a default value. When there is no default\n   value, the parameter becomes of [option 'a] type where ['a] is the type\n   of the parameter you are expecting.\n*)\n\n(** [range ?a ?inclusive b] returns a range as a list of integers from [a]\n    (inclusive) to [b] (exclusive by default, can be set to [false]). Raises\n    [Invalid_argument] if [a] is greater than [b]; returns [[]] if equal. *)\nlet range ?(a = 0) ?(inclusive = false) b =\n  List.init (b - a + Bool.to_int inclusive) (fun i -> i + a)\n;;\n\nrange 6 ~inclusive:true ~a:3\n|> List.map string_of_int\n|> List.iter print_endline\n\n(** [no_default_test] is a demo function for optional parameters with no\n    default value. Simulates a login form to an Operating System. If\n    [username] is not provided, it becomes [None], otherwise the value is\n    wrapped in [Some]. *)\nlet no_default_test ?username os =\n  match username with\n  | Some name -> printf \"Welcome to %s, '%s'!\\n\" os name\n  | None -> printf \"Login to %s requires a username!\\n\" os\n;;\n\nno_default_test ~username:\"luishendrix92\" \"Ubuntu 24\";\nno_default_test \"Windows 12\"\n;;\n\n(* OCaml's default [opam] (package manager) {e switch} comes with a standard\n   library and some packages maintained by the community. If you want to\n   check out the different modules and their functions go to this link:\n\n   https://v2.ocaml.org/api/index.html\n\n   I will use a function of each module (only the most used) but I recommend\n   checking the documentation and testing the functions in [utop] by yourself.\n*)\n\nprintf\n  \"The sum of [ 1; 2; 3; 4; 5 ] is %d.\\n\"\n  (List.fold_left ( + ) 0 [ 1; 2; 3; 4; 5 ]);\nprintf \"FOX lowercased is %s.\\n\" (String.lowercase_ascii \"FOX\");\nprintf \"The ASCII code of '?' is %d.\\n\" (Char.code '?');\nprintf\n  \"Array length of [| 'A'; 'B'; 'C' |] is %d.\\n\"\n  (Array.length [| 'A'; 'B'; 'C' |]);\nprintf \"The hypotenuse of a=5 and b=3 is %f.\\n\" (Float.hypot 4.0 3.0);\nlet is_adult age = age >= 18 in\nprintf\n  \"In an alternate universe, a 25 year old %s an adult!\\n\"\n  (if (Fun.negate is_adult) 25 then \"is\" else \"is not\");\nprintf\n  \"What comes after -5? %d | What's before 7? %d.\\n\"\n  (Int.succ (-5))\n  (Int.pred 7);\nprintf\n  \"Extracting a value from an option: [ None -> %s | Some 42 -> %d ]\\n\"\n  (Option.value ~default:\"DEFAULT_VALUE\" None)\n  (Option.value ~default:0 (Some 42));\nUnix.system \"pwd\"\n\n(* There are no global variables in OCaml, they are all local bindings, just\n   like [let] in JavaScript (ES6+). If I were to bind a value at the outermost\n   layer of the file then I guess you can consider it global since it will be\n   available everywhere in the file but you can't, for example, use the value\n   of a binding that's inside another binding. {b Shadowing} gives you the\n   illusion that you can \"re-assign\" a binding, but in reality you're just\n   creating another one with the same name that overrides the previous one. *)\n\nlet i_guess_im_global = \"But there is no such thing...\";;\n\nlet _ = () in\nlet _ =\n  let foo = \"foo\" in\n  (* Shadowing: uses the previous value and re-binds it. *)\n  let foo = foo ^ \"bar\" in\n  foo ^ \"baz\" (* \"foobarbaz\" *)\nin\nlet _ = () in\n(* Begin/End blocks are syntactic sugar for parenthesis. *)\nbegin\n  print_endline \"This call is 3 levels deep and it can access outer bindings:\";\n  printf \"Globals? %s.\\n\" i_guess_im_global\nend\n\n(* Optional Challenge *)\n\n(** [generic_fizz_buzz ?fizz ?buzz n] prints the numbers from [1] to [n] ([100])\n    but replaces the multiples of [3] with [fizz] and the multiples of [5] with\n    [buzz] (multiples of both with [fizz ^ buzz]). It acts as a generic\n    imperative version of the {b fizz-buzz algorithm} in which the user can set\n    their own strings to replace \"Fizz\" and \"Buzz\". Returns the number of times\n    a number was printed without being replaced by [fizz] and/or [buzz]. *)\nlet generic_fizz_buzz ?(fizz = \"Fizz\") ?(buzz = \"Buzz\") n =\n  let num_count : int ref = ref 0 in\n  for i = 1 to n do\n    match i mod 3, i mod 5 with\n    | 0, 0 -> print_endline (fizz ^ buzz)\n    | 0, _ -> print_endline fizz\n    | _, 0 -> print_endline buzz\n    | _ ->\n      print_endline (string_of_int i);\n      incr num_count\n  done;\n  !num_count\n;;\n\n(* Returns 53 *)\ngeneric_fizz_buzz ~fizz:\"Electa\" 100\n\n(* Output after running [ocaml -I +unix luishendrix92.ml]\n   ------------------------------------------------------\n   Is 'racecar' a palindrome? yes.\n   2 + 2 is 4, quick maffs.\n   The length of list [false; false; true] is 3.\n   Square of numbers from 1 to 5: [1, 4, 9, 16, 25].\n   The factorial of 5 is 120.\n   It's a digit.\n   It's a lowercase letter.\n   It's an uppercase letter.\n   It's a symbol character :)\n   luishendrix92 enters the party house...\n   And the host says to luishendrix92:\n   Who invited you, luishendrix92? Anyway, have a seat...\n   luishendrix92 can finally enjoy the party.\n   3\n   4\n   5\n   6\n   Welcome to Ubuntu 24, 'luishendrix92'!\n   Login to Windows 12 requires a username!\n   The sum of [ 1; 2; 3; 4; 5 ] is 15.\n   FOX lowercased is fox.\n   The ASCII code of '?' is 63.\n   Array length of [| 'A'; 'B'; 'C' |] is 3.\n   The hypotenuse of a=5 and b=3 is 5.000000.\n   In an alternate universe, a 25 year old is not an adult!\n   What comes after -5? -4 | What's before 7? 6.\n   Extracting a value from an option: [ None -> DEFAULT_VALUE | Some 42 -> 42 ]\n   /home/kozmicluis/Documents/moure/Roadmap/02 - FUNCIONES Y ALCANCE/ocaml\n   This call is 3 levels deep and it can access outer bindings:\n   Globals? But there is no such thing...\n   1\n   2\n   Electa\n   4\n   Buzz\n   Electa\n   7\n   8\n   Electa\n   Buzz\n   11\n   Electa\n   13\n   14\n   ElectaBuzz\n   16\n   17\n   Electa\n   19\n   Buzz\n   Electa\n   22\n   23\n   Electa\n   Buzz\n   26\n   Electa\n   28\n   29\n   ElectaBuzz\n   31\n   32\n   Electa\n   34\n   Buzz\n   Electa\n   37\n   38\n   Electa\n   Buzz\n   41\n   Electa\n   43\n   44\n   ElectaBuzz\n   46\n   47\n   Electa\n   49\n   Buzz\n   Electa\n   52\n   53\n   Electa\n   Buzz\n   56\n   Electa\n   58\n   59\n   ElectaBuzz\n   61\n   62\n   Electa\n   64\n   Buzz\n   Electa\n   67\n   68\n   Electa\n   Buzz\n   71\n   Electa\n   73\n   74\n   ElectaBuzz\n   76\n   77\n   Electa\n   79\n   Buzz\n   Electa\n   82\n   83\n   Electa\n   Buzz\n   86\n   Electa\n   88\n   89\n   ElectaBuzz\n   91\n   92\n   Electa\n   94\n   Buzz\n   Electa\n   97\n   98\n   Electa\n   Buzz\n*)"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/pascal/miguelex.pas",
    "content": "program miguelex;\n\n{ Ejemplo de una función que no tiene parametros ni retorno }\nProcedure funcionSinNada;  \nbegin  \n  Writeln ('Hola, soy una función que no tiene ni parametros ni retorno');\nend;\n\n{ Ejemplo de una función que tiene parametros pero no retorno }\nProcedure funcionSinRetorno(parametro1, parametro2: Integer);\nbegin\n  Writeln ('Hola, soy una función que no tiene retorno pero si parametros');\n  Writeln ('El valor del parametro 1 es: ', parametro1);\n  Writeln ('El valor del parametro 2 es: ', parametro2);\nend;\n\n{ Ejemplo de una función que tiene retorno pero no parametros }\nFunction funcionSinParametros: Integer;\nbegin\n  Writeln ('Hola, soy una función que no tiene parametros pero si retorno');\n  funcionSinParametros := 10;\nend;\n\n{ Ejemplo de una función que tiene parametros y retorno }\nFunction funcionConParametros(parametro1, parametro2: Integer): Integer;\nbegin\n  Writeln ('Hola, soy una función que tiene parametros y retorno');\n  Writeln ('El valor del parametro 1 es: ', parametro1);\n  Writeln ('El valor del parametro 2 es: ', parametro2);\n  funcionConParametros := parametro1 + parametro2;\nend;\n\n{ Ejemplo de uso de cariables locales y globales }\nVar\n  variableGlobal: Integer;\n  \nprocedure ProcLocalVsGlobal;\n  Var\n    variableLocal: Integer;\n  begin\n    variableLocal := 10;\n    variableGlobal := 20;\n    WriteLn('El valor de la variable local es: ', variableLocal);\n    WriteLn('El valor de la variable global es: ', variableGlobal);\nend;\n\n{ Ejemplo de paso por refeencia }\nProcedure pasoPorReferencia(Var parametro1: Integer);\nbegin\n  parametro1 := 10;\nend;\n\n{ Ejemplo de paso por valor }\nProcedure pasoPorValor(parametro1: Integer);\nbegin\n  parametro1 := 10;\nend;\n\nfunction extra (parametro1, parametro2: String): Integer;\n  var\n  numsImpresos: Integer;\n  i: Integer; // Debes declarar i aquí\nbegin\n  numsImpresos := 0;\n  for i := 1 to 100 do\n  begin\n    if (i mod 15 = 0) then\n      WriteLn(parametro1+parametro2)\n    else if (i mod 3 = 0) then\n      WriteLn(parametro1)\n    else if (i mod 5 = 0) then\n      WriteLn(parametro2)\n    else\n      WriteLn(i);\n    Inc(numsImpresos);\n  end;\n  extra := numsImpresos;\nend;\n\nbegin\n  WriteLn();\n  funcionSinNada;\n  WriteLn();\n  funcionSinRetorno(10,2);\n  WriteLn();\n  WriteLn('El valor de la funcion sin retorno es: ', funcionSinParametros);\n  WriteLn();\n  WriteLn('El valor de la funcion con retorno es: ', funcionConParametros(10,2));\n  WriteLn();\n  ProcLocalVsGlobal;\n  WriteLn();\n  WriteLn('Paso por referencia: ', pasoPorReferencia(5));\n  WriteLn();\n  WriteLn('Paso por valor: ', pasoPorValor(5));\n  WriteLn();\n\n  { Ejemplo de uso de una funcion del sistema }\n  WriteLn('El valor de la funcion random es: ', Random(10));\n  WriteLn();\n\n  { Finalmente, el ejercicio extra }\n  WriteLn('Ejercicio extra');\n  WriteLn();\n  WriteLn('Se han imprimido: ', extra('Miguelex','Dev'));\n\n\n\nend."
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/php/CeciliaPorras01.php",
    "content": "\n<?php \n\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n\n\n//Funciones definidas por el usuario\n//Simple\n\nfunction greet(){\n    print(\"Hola mundo\");\n}\n\ngreet();\n\n\n//Con retorno \nfunction ret_greet(){\n    return \"Hola mundo\";\n}\n\nprint(ret_greet());\n\n\n//Con argumento\n\nfunction print_greet($nombre){\n    print(\"Hola $nombre\");\n}\n\nprint_greet(\"Cecilia\");\n\n\n//Con argumentos \nfunction arg_greet($nombre, $apellido){\n    print(\"Hola,  $nombre $apellido\");\n}\n\narg_greet(\"Cecilia\", \"Porras\");\narg_greet($nombre = \"Ceciliaa\", $apellido = \"Porras\");\n\n\n//Con argumento predeterminado\nfunction def_arg_greet($nombre =\"Martha\"){\n    print(\"Hola, $nombre\");\n}\n\ndef_arg_greet();\n\n\n//Con argumentos y return\nfunction ret_arg_greet($nombre, $apellido){\n    return  $nombre . ' ' . $apellido;\n}\n\nprint(ret_arg_greet(\"Cecilia\" ,\"Porras\"));\n\n\n//Con retorno de varios valores\nfunction ret_var_greet() {\n    return [\"Cecilia\", \"Porras\"];\n}\n\nlist($name, $lastname) = ret_var_greet();\nprint($name);\nprint($lastname);\n\n\n//Con un numero variable de argumentos\nfunction var_arg_greet(...$nombres){\n    foreach($nombres as $nombre){\n        print(\"Hola, $nombre \\n\");\n    }\n}\n\nvar_arg_greet(\"Cecilia\", \"Martha\", \"Luisa\", \"Sofia\");\n\n\n//Con un numero variable  de argumentos con palabras clave\nfunction key_arg_greet($args) {\n    foreach($args as $clave => $valor) {\n        print($clave .\" = \". $valor . \"\\n\");\n    }\n}\n\nkey_arg_greet([\n    \"nombre \" => \"Cecilia\",\n    \"apellido\" => \"Porras\",\n    \"edad\" => 23\n]);\n\n\n\n//Función interna\nfunction external(){\n    function internal(){\n        print(\"Función interna\");\n    }\n    internal();\n}\n\nexternal();\n\n\n//Función de lenguaje\nprint(strtoupper(\"hola mundo\"));\nprint(gettype(\"hola mundo\"));\nprint(strlen(\"hola mundo\"));\nprint (strrev(\"hola mundo\"));\nprint (str_repeat(\"hola mundo\", 3));\nprint (str_replace(\"mundo\", \"Cecilia\", \"hola mundo\"));\n\n\n//Variable global y local\n\n$global_variable = \"Variable global\";\nprint ($global_variable);\n\nfunction hello_world(){\n    global $global_variable;\n    $local_variable = \"Variable local\";\n    print(\"Hola\". $global_variable);\n    print(\"Hola\". $local_variable);\n}\n\nhello_world();\n\n/**\n * EJERCICIO EXTRA\n * \n *  - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n * \n */\n\n\n function print_numbers($text_1, $text_2) {\n    $count = 0;\n    for ($i = 1; $i <= 100; $i++) {\n        if ($i % 3 == 0 && $i % 5 == 0) {\n            print($text_1 . $text_2 . \"\\n\");\n        } elseif ($i % 3 == 0) {\n            print($text_1 . \"\\n\");\n        } elseif ($i % 5 == 0) {\n            print($text_2 . \"\\n\");\n        } else {\n            print($i . \"\\n\");\n            $count += 1;\n        }\n    }\n    return $count;\n}\n\n// Llamada a la función\n$vecesImpresoNumero = print_numbers(\"Fizz\", \"Buzz\");\nprint(\"Número de veces que se ha impreso un número: \" . $vecesImpresoNumero . \"\\n\");"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/php/GitHjuan.php",
    "content": "EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n <?php \n\n echo \"FUNCIONES\" . '<br/>'; \n\n//---------------------Funcion simple\nfunction funcion(){\n\techo \"Mi funcion\" . \"\\n\";\n}\necho funcion();\n\necho \"<br/>\";\n\n//--------------------Funcion con parametro\n\nfunction funcion_con_parametro($name){\n\techo \"Mi nombre es \" . $name . \"\\n\";\n}\n\necho funcion_con_parametro(\"Ryan\");\n\necho \"<br/>\";\n\n// Funcion con parametros por defecto\necho \"===== Funcion con parametros por defecto ========\";\necho \"<br/>\";\nfunction funct_default($param1 = \"Name\", $param2 = \"Lastname\"){\n\techo \"Mi Nombre y Apellido es: \" . $param1 . \"\\n\" . $param2;\n}\n\nfunct_default();\necho \"<br/>\";\n\n//-------------------Funcion con parametros\necho \"===== Funcion con parametros ========\";\necho \"<br/>\";\nfunction funt_parametros($name, $lastname){\n\techo \"Mi nombre y Apellido es: \" . $name .\"\\n\" . $lastname . \"<br/>\";\n}\necho funt_parametros(\"Ryan\", \"Rainol\");\n\n//-----------------Funcion con parametros y retorno\necho \"===== Funcion con parametros y retorno ========\";\necho \"<br/>\";\nfunction funct_return($num1, $num2){\n\treturn $num1 + $num2;\n}\n$suma = funct_return(20, 12);\necho \"El resultado de la suma es: \" . $suma;\n\n//-----------------Funcion dentro de otra funcion\necho \"===== Funcion dentro de otra funcion ========\";\necho \"<br/>\";\nfunction funcion1(){\n\tfunction funcion2(){\n\t\techo \"Esta es una funcion dentro de otra funcion\";\n\t}\n\tfuncion2();\n}\n\nfuncion1();\necho \"<br/>\";\n//-----------------Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\necho \"===== Funcion ya creadas en el lenguaje ========\";\necho \"<br/>\";\n//para consultar el tipo de dato\n$funcion = \"Valor de la funcion\";\n$funcion2 = 100; \n var_dump($funcion);\necho \"<br/>\";\n//imprimir valor de una variable\nprint_r($funcion);\necho \"<br/>\";\n\n/* DIFICULTAD EXTRA (opcional) */\necho \"===== DIFICULTAD EXTRA ========\";\necho \"<br/>\";\n// Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n//  * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n//  *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n//  *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n//  *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n//  *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\nfunction extra($text_1, $text_2){\n\tfor($i = 1 ; $i <= 100 ; $i++){\n\t\tif($i % 3 === 0 && $i % 5 === 0){\n\t\t\techo $text_1 . ' ' . $text_2 . \"<br/>\";\n\t\t\t}else if($i % 3 === 0){\n\t\t\techo $text_1 . \"<br/>\";\n\t\t\t}else if($i % 5 === 0){\n\t\t\techo $text_2 . \"<br/>\";\n\t\t\t}else{\n\t\t\techo $i . \"<br/>\";\n\t\t\t\t}\n\t\t\t}\n\t\t\n\t\t}\n\textra(\"Fizz\", \"Buzz\");\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/php/Hugovrc.php",
    "content": "<?php\n\n// Funciones Sin parámetros ni retorno\nfunction hola_mundo() {\n    echo \"Hola, mundo \\n\";\n}\n\nhola_mundo();\n\n// Con un parametro\nfunction funcion_con_parametro($lenguaje) {\n    echo \"Estoy aprendiendo: \". $lenguaje;\n}\n\nfuncion_con_parametro(\"PHP\\n\");\n\n// Con varios parametros\nfunction funcion_con_varios_parametros($numero1, $numero2) {\n    echo $numero1. \" + \" .$numero2. \" = \". $numero1 + $numero2. \"\\n\";\n}\n\nfuncion_con_varios_parametros(1,2);\n\n// Funciones con retorno\nfunction cuadrado($num) {\n    return $num * $num.\"\\n\";\n}\n\necho cuadrado(5);\n\n//funciones dentro de funciones\nfunction hola_php() {\n    function lenguaje() {\n        echo \"Hola PHP \\n\";\n    }\n    lenguaje();\n}\n\nhola_php();\n\n// funciones ya creadas en el lenguaje\ndate_default_timezone_set('America/Mexico_City');\n\n$fecha_y_hora = date(\"d-m-y H:m:s\");\necho $fecha_y_hora. \"\\n\";\n\n  // Obtiene la version de php\necho \"Version de PHP: \" .phpversion(). \"\\n\";\n\n// variable local y global\n\n//variable global\n$numero = 2;\n\nfunction tabla_del_dos() {\n    global $numero;\n    for ($i=1; $i<=10; $i++) { // i Variable local\n       echo $numero * $i. \"\\n\";\n    }\n}\n\ntabla_del_dos();\n\n\n// DIFICULTAD EXTRA\necho \"------- Dificultad Extra-------- \\n\";\nfunction fizz_buzz($parametro1, $parametro2) {\n    $veces = 0;\n    for ($a=1; $a<=100; $a++) {\n        if ($a % 3 == 0 and $a % 5 == 0) {\n            echo $parametro1. $parametro2.\"\\n\";\n        } elseif ($a % 3 == 0) {\n            echo $parametro1.\"\\n\";\n        } elseif ($a % 5 == 0) {\n            echo $parametro2.\"\\n\";\n        } else {\n            echo $a.\"\\n\";\n            $veces += 1;\n        }\n    }\nreturn $veces. \" veces se ha impreso el numero \\n\";\n}\n\necho fizz_buzz(\"fizz\",\"buzz\");\n\n?>"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/php/Jeyker-Dev.php",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n<?php\n\n// Function Without Parameters\nfunction hi()\n{\n    echo '!Hi'.\"\\n\";\n}   // Here End Function Hi\n\nhi();\n\n// Function With Parameters\nfunction hiName( $name )\n{\n    echo '!Hi'.' '.$name.\"\\n\";\n}   // Here End Function Hi Name\n\nhiName( 'Jeyker' );\n\n// Function With Default Parameters\n\nfunction hiNameDefault( $name = 'Random' )\n{\n    echo '!Hi'.' '.$name.\"\\n\";\n}   // Here End Function Hi Name Default\n\nhiNameDefault();\n\n// Function With Specific Data Types\nfunction hiNameReturn( $name = \"Jeyker\" ) : string\n{\n    $saludar = \"!Hi\".\" \".$name.\"\\n\";\n    return $saludar;\n}\n\necho hiNameReturn();\n\n// Anonymous Functions\n$hiNameAgain = function( $name = \"Jeyker\" ) : string\n{\n    $saludar = \"!Hi\".\" \".$name.\"\\n\";\n    return $saludar;\n};\n\necho 'Otro Vez Saludando A Jeyker: '. ' '.$hiNameAgain('Jeyker');\n\n// Arrows Functions\n$noWay = fn( $name = 'Jeyker') => 'No Puede Ser: '.' '.'!Hi '.$name.\"\\n\";\n\necho $noWay();\n\n// Function Strlen\n$chain = 'Jeyker';\n\necho strlen( $chain ).\"\\n\";\n\nfunction local()\n{\n    $local = 'Jeyker';\n    echo '!Hi '.$local.\"\\n\";\n}   // Here End Function Local\n\nlocal();\n\n$global = 'Jeyker';\n\nfunction globalFunction()\n{\n    global $global;\n    echo '!Hi '.$global.\"\\n\";\n}   // Here End Function Global\n\nglobalFunction();\n\n$contador = 0;\nfunction cadenasTexto( $string_1, $string_2 )\n{\n    for($i = 1; $i <= 100; $i++)\n    {\n        global $contador;\n        if( $i % 2 == 0)\n        {\n            echo $string_1.\"\\n\";\n            $contador++;\n        }   // Here End If\n        elseif( $i % 5 == 0)\n        {\n            echo $string_2.\"\\n\";\n            $contador++;\n        }   // Here End Else If\n        elseif( $i % 2 == 0 && $i % 5 == 0)\n        {\n            echo $string_1.\" y \".$string_2.\"\\n\";\n            $contador++;\n        }   // Here End ElseIf\n    }   // Here End For\n\n    return $contador;\n}   // Here End Function Cadena Texto\n\n$total = cadenasTexto('Primera', 'Segunda');\n\necho 'El Total: '.$total;\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/php/adrs1166ma.php",
    "content": "<?php\ndeclare(strict_types=1); // Para el tipado mas fuerte\n/*\n* EJERCICIO:\n* - 🔸Crea ejemplos de funciones básicas que representen las diferentes\n*   posibilidades del lenguaje:\n*   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n* - 🔸Comprueba si puedes crear funciones dentro de funciones.\n* - 🔸Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n* - 🔸Pon a prueba el concepto de variable LOCAL y GLOBAL.\n* - 🔸Debes hacer print por consola del resultado de todos los ejemplos.\n*   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n*\n* DIFICULTAD EXTRA (opcional):\n* Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n* - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n*   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n*   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n*   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n*   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n*\n* Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n* Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n*/\n\n/* Para este ejemplo\nUsaremos \" imprimir(); 🔹 \"\nantes de invocar una funcion,\nes la misma que crearemos\n\n- tipo codigo: <pre></pre>\n- salto de linea: <br> \n*/\n\n/*\n    🟢 Funciones\n*/\n\n\n// Sin Parametros ni retorno 🟠\nfunction sinParametrosNiRetorno(){\n    echo \"String por Funcion sin parametros ni retorno\";echo '<br>';\n} // end function\nimprimir(); // 🔹\nsinParametrosNiRetorno(); echo '</pre><br>';\n\n// Ejemplo imprimir 🔸\nfunction imprimir(){\n    echo \"Invocacion<pre>\";\n}\n\n\n// Sin Parametros ni retorno 🟠\nfunction conParametros($parametro1,$parametro2){\n    echo 'por Funcion con parametros';echo '<br>';\n    echo 'Parametro 1: '.$parametro1;echo '<br>';\n    echo 'Parametro 2: '.$parametro2;echo '<br>';\n} // end function\nimprimir(); // 🔹\nconParametros('Vegetta',777); echo '</pre><br>';\n\n\n// Parametros por defecto 🟠\nfunction porDefecto($señal='Invocacion', $etiqueta='<br>'){\n    echo $señal.$etiqueta;\n} // end function\nimprimir(); // 🔹\nporDefecto('Print');echo '</pre><br>';\n\n\n// Por referencia sin retorno 🟠\nfunction porReferencia1(&$num){\n    $num = 999;\n}\nimprimir(); // 🔹\n$numero = 1000;\necho \"numero antes de funcion: \".$numero.'<br>';\nporReferencia1($numero);\necho \"numero despues de funcion: \".$numero.'<br>';\necho '</pre><br>';\n\n\n\n// Con retorno 🟠\nfunction conRetorno($p1, $p2){\n    return $p1 + $p2;\n}// end function | Ahora si podemos asignar una funcion a una variable\nimprimir(); // 🔹\n$suma = conRetorno(5,4);\necho $suma;echo '</pre><br>';\n\n\n// Anonimas o closures 🟠\n$anonimoNumero = function($n){\n    return pow($n,2);\n};\nimprimir(); // 🔹\necho '5 al cuadrado: '.$anonimoNumero(5); \necho '</pre><br>';\n\n\n// Por referencia con retorno 🟠\nfunction porReferencia2(&$s){\n    $s = 'Variable cambiada';\n    return $s;\n}\nimprimir(); // 🔹\n$xVariable = 'Variable no cambiada';\necho \"numero antes de funcion: \".$xVariable.'<br>';\n$cambio = porReferencia2($xVariable);\necho \"numero despues de funcion: \".$xVariable.'<br>';\necho '</pre><br>';\n\n\n\n// Types 🟡\n// declare(strict_types=1); // tipado mas fuerte, declarado en las primeras lineas\n\nfunction sumar(int $numero1 = 0, int $numero2 = 0) {\n    echo $numero1 + $numero2;\n}\nimprimir(); // 🔹\nsumar(10, 12);\necho '</pre><br>';\n\n// : que tipo de dato nos debe retornar la funcion?. \n/*\n\n: (tipo de dato primitivo: strign, bool, float, ...) \n\nejemplo 👇\n\n: string ➡️ retorna si o si un string.\n: ?string ➡️ es opcional retornar un string. 🔹\n\n: string|int ➡️ retornara un String o un Entero.\n\n: void ➡️ no va a retornar nada, imprimira algo, o null.\n\n\n*/\nfunction usuarioAutenticado(bool $autenticado) : ?string {\n    if($autenticado) {\n        return \"El Usuario esta autenticado\";\n    } else {\n        return null;\n    }\n}\nimprimir(); // 🔹\n$usuario = usuarioAutenticado(true);\necho $usuario;\necho '</pre><br>';\n\n\n/*\n    🟢 Funcion dentro de funcion\n*/\nfunction baseFuncion(){\n    function funcionDentro(){\n        echo \"Funcion dentro de funcion<br>\";\n    }   \n    funcionDentro();\n}\nimprimir(); // 🔹\nbaseFuncion();\necho '</pre><br>';\n\n\n\n/*\n    🟢 Ejemplo\n*/\n$numeros = [4,7,24,15,55,12,1,50,100,155];\n$mult_dos = array_filter($numeros,function($n){\n    return $n%2 == 0;\n});\nimprimir(); // 🔹\nprint_r($mult_dos);\necho '</pre><br>';\n\n/*\n    🟢 Variable local y global\n*/\n\n$Global = \"Variable global\";\nfunction ambitoVariables(){\n    global $Global; //definimos global\n    $Local = \"Variable local\";\n    echo $Local.\"<br>\";\n    echo $Global.\"<br>\";\n}\nimprimir(); // 🔹\nambitoVariables();echo '</pre><br>';\n\n\n\n\n\n\necho '<br>🔥 Extra <br>';\n/*\n    🔥 Extra\n*/\nfunction extra_FizBuzz($pp1,$pp2){\n    $c = 0;\n    for ($i=1; $i <= 100; $i++) { \n        if (($i%3 == 0)and($i%5 == 0)) {\n            echo $i.' '.$pp1.$pp2.'<br>';\n        } elseif ($i%3 == 0){\n            echo $i.' '.$pp1.'<br>';\n        } elseif ($i%5 == 0){\n            echo $i.' '.$pp2.'<br>';\n        } else{\n            $c++;\n            echo $i.'<br>';\n        }\n    }\n    return $c;\n}\nimprimir(); // 🔹\n$contador = extra_FizBuzz('h','g');\necho '</pre><br>';\necho '<h4>Se imprimio '.$contador.' números en lugar de los textos</h4>';\n\n?>"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/php/eulogioep.php",
    "content": "<?php\n\n// Variable global\n$contadorGlobal = 0;\n\n// 1. Función sin parámetros ni retorno\nfunction saludar() {\n    echo \"¡Hola, mundo!\\n\";\n}\n\n// 2. Función con un parámetro y sin retorno\nfunction saludarPersona($nombre) {\n    echo \"¡Hola, $nombre!\\n\";\n}\n\n// 3. Función con múltiples parámetros y retorno\nfunction sumar($a, $b) {\n    return $a + $b;\n}\n\n// 4. Función que demuestra una \"función\" dentro de otra\nfunction operacionMatematica($a, $b) {\n    $multiplicar = function($x, $y) {\n        return $x * $y;\n    };\n    return $multiplicar($a, $b) + 10;\n}\n\n// 5. Uso de una función incorporada en PHP\nfunction obtenerFechaActual() {\n    return date('Y-m-d');\n}\n\n// 6. Demostración de variable local vs global\nfunction incrementarContador() {\n    global $contadorGlobal;\n    $contadorLocal = 0;\n    $contadorLocal++;\n    $contadorGlobal++;\n    echo \"Contador local: $contadorLocal, Contador global: $contadorGlobal\\n\";\n}\n\n// DIFICULTAD EXTRA\nfunction imprimirYContar($texto1, $texto2) {\n    $contadorNumeros = 0;\n\n    for ($i = 1; $i <= 100; $i++) {\n        if ($i % 3 == 0 && $i % 5 == 0) {\n            echo $texto1 . $texto2 . \"\\n\";\n        } elseif ($i % 3 == 0) {\n            echo $texto1 . \"\\n\";\n        } elseif ($i % 5 == 0) {\n            echo $texto2 . \"\\n\";\n        } else {\n            echo $i . \"\\n\";\n            $contadorNumeros++;\n        }\n    }\n\n    return $contadorNumeros;\n}\n\n// Llamadas a las funciones y impresión de resultados\necho \"1. Función sin parámetros ni retorno:\\n\";\nsaludar();\n\necho \"\\n2. Función con un parámetro y sin retorno:\\n\";\nsaludarPersona(\"Alice\");\n\necho \"\\n3. Función con múltiples parámetros y retorno:\\n\";\necho \"Suma de 5 y 3: \" . sumar(5, 3) . \"\\n\";\n\necho \"\\n4. Función que demuestra una \\\"función\\\" dentro de otra:\\n\";\necho \"Resultado de operación matemática: \" . operacionMatematica(4, 5) . \"\\n\";\n\necho \"\\n5. Uso de una función incorporada en PHP:\\n\";\necho \"Fecha actual: \" . obtenerFechaActual() . \"\\n\";\n\necho \"\\n6. Demostración de variable local vs global:\\n\";\nincrementarContador();\nincrementarContador();\n\necho \"\\nDIFICULTAD EXTRA:\\n\";\n$numerosPuros = imprimirYContar(\"Fizz\", \"Buzz\");\necho \"Números impresos sin ser reemplazados por texto: $numerosPuros\\n\";\n\n?>"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/php/gabrielmoris.php",
    "content": "<?php\n\n/*\n*EXERCISE:\n* - Create examples of basic functions that represent the different\n* possibilities of the language:\n* - Without parameters or return, with one or more parameters, with return...\n* - Check if you can create functions within functions.\n* - Use some examples of functions already created in the language.\n* - Test the concept of LOCAL and GLOBAL variables.\n* - You must print the result of all the examples to the console.\n* (and keep in mind that each language may have more or fewer possibilities)\n* EXTRA DIFFICULTY (optional):\n* Create a function that receives two string parameters and returns a number.\n* - The function prints all the numbers from 1 to 100. Considering that:\n* - If the number is a multiple of 3, it displays the string of the first parameter.\n* - If the number is a multiple of 5, it displays the string of the second parameter.\n* - If the number is a multiple of 3 and 5, it displays the two concatenated strings.\n* - The function returns the number of times the number has been printed instead of the texts.\n* Pay special attention to the syntax you must use in each case.\n* Each language follows conventions that you must respect for the code to be understood.\n*/\n\n// simple function\n\nfunction simplicity()\n{\n    echo \"ok\";\n};\n\n// One param without return function\nfunction one_param($param)\n{\n    echo  \"This is the param: \" . $param . \"\\n\";\n};\n\none_param(\"hi!\");\n\n// 2 Params with return\nfunction two_params_Return($first, $second)\n{\n    return $first + $second;\n}\n\n$asign_to_var = two_params_Return(1, 5);\necho $asign_to_var . \"\\n\";\n\n// Functions in functions\n\nfunction outside($res)\n{\n    function inside($first, $second)\n    {\n        return $first + $second;\n    };\n\n    return inside($res, 1);\n};\n\necho outside(5) . \"\\n\";\n\n// Recursive\n\n$i = 0;\n\nfunction make_i_great_again()\n{\n    global  $i; // in this way I access it as a global from outside. Otherwise it behaves local.\n    if ($i > 99) {\n        return $i;\n    };\n    $i++;\n    return make_i_great_again($i);\n}\n\necho make_i_great_again() . \"\\n\";\n// native methods\n\n$hardcodedArr = [10, 11, 12];\n\nfunction sum($carry, $item)\n{\n    return $carry + $item;\n}\n\n$result = array_reduce($hardcodedArr, 'sum', 0);\necho $result . \"\\n\";\n\n// Global variable: Outside any function or class\n$globalVar = \"This is a global variable\";\n\n// Local variable: Inside a function or class\nfunction myFunction()\n{\n    $localVar = \"This is a local variable\";\n    echo $localVar; // Output: \"This is a local variable\"\n}\n// echo $localVar; // error\n\nfunction flix_bus($str, $str2)\n{\n    $num_count = 0;\n    for ($i = 0; $i <= 100; $i++) {\n        if ($i % 3 == 0 && $i % 5 == 0) {\n            echo $str . \",\" . $str2;\n        } elseif ($i % 3 == 0) {\n            echo $str . \",\";\n        } elseif ($i % 5 == 0) {\n            echo $str2 . \",\";\n        } else {\n            echo $i . \",\";\n            $num_count++;\n        }\n    }\n\n    return $num_count;\n}\n\n$result = flix_bus(\"Flix\", \"Bus\");\n\necho \"\\n Result: \" . $result . \"\\n\";\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/php/guido2288.php",
    "content": "<?php\n  /* Funciones con uno o varios parámetros  */\n\n  function saludo ($name){\n    echo \"Hola $name\"+\"\\n\"; \n  }\n\n  function sumar ($a , $b){\n    echo \"$a + $b\" +\"\\n\";\n  }\n\n  /* Funciones Sin parámetros ni retorno */\n\n  function sinParametro(){\n    echo \"Buen día!\" +\"\\n\";\n  }\n\n  /* Funciones con retorno */\n  function multiplica ($a , $b){\n    $respuesta = $a * $b;\n    return $respuesta;\n  }\n\n  /* Funciones dentro de funciones */\n  function aritmetica ($a , $b){\n    return sumar($a , $b);\n  }\n\n  /* Utiliza algún ejemplo de funciones ya creadas en el lenguaje. */\n\n  // array_shift \"Quita un elemento del principio del array\"\n  \n  $stack = array(\"naranja\", \"plátano\", \"manzana\", \"frambuesa\");\n\n  $sinNaranja = array_shift($stack);\n\n  print_r($stack);\n\n\n  /* Pon a prueba el concepto de variable LOCAL y GLOBAL. */\n  function ambitoVariables(){\n    global $variableGlobal;\n    $variableLocal = \"Variable local\";\n    echo $variableLocal.\"\\n\";\n    echo $variableGlobal.\"\\n\";\n  }\n\n  /* DIFICULTAD EXTRA (opcional) */\n\n  function extra($varA , $varB){\n\n    $count = 0;\n\n    for ($i=1; $i < 100; $i++) { \n        if($i % 3 == 0 && $i % 5 != 0) echo \"$varA <br>\";\n\n        if($i % 5 == 0 && $i % 3 != 0) echo \"$varB <br>\";\n\n        if($i % 3 == 0 && $i % 5 == 0) echo \"$varA  $varB <br>\";\n\n        if($i % 3 != 0 && $i % 5 != 0) {\n            echo \"$i <br>\";\n            $count ++;\n        };\n    }\n\n    echo \"El total es: $count\";\n\n}\n\nextra(\"Manzana\", \"Banana\");\n\n?>"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/php/jonathanj20.php",
    "content": "<?php \n    /*\n        -Una función es código que se va a ejecutar cuando se llame.\n        -Una función es una tarea especifica por hacer.\n    */ \n\n    //sin parámetros ni retorno\n    function jump(){\n        echo \"I'm jumping <br>\";\n    }\n\n    jump();  \n\n    //con uno o varios parametros\n    function greet($name){\n        echo \"Hi, I'm $name <br>\";\n    }\n\n    greet(\"Jose\");\n\n    // con retorno - arrow function\n    $sum = fn($num1, $num2) => $num1 + $num2;\n    echo $sum(4, 2).\"<br>\";\n\n    //creación de función dentro de otra función\n\n    function firstFunction(){\n        function secondFunction(){\n            echo \"I'm second function <br>\";\n        }\n    }\n\n    firstFunction();\n    secondFunction();\n\n    // funciones ya creadas en el lenguaje\n    echo strlen(\"Hi, I'm a string\").\"<br>\";\n    echo str_replace(\"o\", \"s\", \"Hola amigos, soy yo\").\"<br>\";\n\n    // variables locales y globales\n    $myVariable = 2; //variable global\n    function myFunction(){\n        // echo $myVariable; no puedo acceder a $myVariable ya que sólo está disponible en un ámbito global (fuera de la función).\n        \n        //si quisiera acceder a una variable global, tendría que usar el array asociativo GLOBALS.\n        echo $GLOBALS[\"myVariable\"].\"<br>\";\n\n        //también puedo acceder a variables globales definiendolas como globales con la palabra reservada global, deben de tener el mismo nombre.\n        global $myVariable;\n\n        echo $myVariable.\"<br>\";\n\n        //variable local\n\n        //esta variable sólo está disponible dentro de esta función myFunction(), por lo que si intento acceder a ella fuera de la función ocurrirá un error.\n        $variable_local = \"Hola\";\n    }\n\n    myFunction();\n\n    /*\n    * DIFICULTAD EXTRA (opcional):\n    * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n    * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n    *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n    *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n    *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n    *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n    *\n    * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n    * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n    */\n\n    function printStrings($string1, $string2){\n        $counter = 0;\n\n        for($i = 1; $i <= 100; $i++){\n            if($i % 3 === 0 && $i % 5 === 0){\n                echo $string1.$string2.\"<br>\";\n            } else if($i % 3 === 0){\n                echo \"$string1 <br>\";\n            } else if($i % 5 === 0){\n                echo \"$string2 <br>\";\n            } else {\n                echo \"$i <br>\";\n                $counter++;\n            }\n        }\n\n        return $counter;\n    }\n\n\n    echo \"Número de veces que se ha impreso un número: \".printStrings(\"Hello\", \"world\");\n\n?>"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/php/kodenook.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nfunction name(): void\n{\n    echo 'kodenook', PHP_EOL;\n}\n\nname();\n\nfunction fullName(string $fname = 'my', string $lname = 'name'): void\n{\n    echo \"$fname $lname\", PHP_EOL;\n}\n\nfullName(lname: 'name');\n\nfunction addition(int|float ...$num): float\n{\n    $result = 0;\n\n    foreach ($num as $n) {\n        $result += $n;\n    }\n\n    return $result;\n}\n\necho addition(1, 2.5, 3.2, -2), PHP_EOL;\n\nfunction ageAddition(int &$age): void\n{\n    $age += 5;\n}\n\n$age = 20;\nageAddition($age);\necho $age, PHP_EOL;\n\nfunction first(): void\n{\n    echo 'first', PHP_EOL;\n\n    function second(): void\n    {\n        echo 'second', PHP_EOL;\n    }\n\n    second();\n}\n\nfirst();\n\n$global = 'global';\n$global2 = 'global2';\nfunction scope(): void\n{\n    global $global;\n    $local = 'local';\n\n    echo $local, PHP_EOL;\n    echo $global, PHP_EOL;\n    echo $GLOBALS['global2'], PHP_EOL;\n}\n\nscope();\n\n/*\n    Exercise\n*/\n\nfunction exercise(string $word1, string $word2): int\n{\n    $countNumbers = 0;\n\n    foreach (range(1, 100) as $x) {\n        if ($x % 3 === 0 && $x % 5 === 0) {\n            echo \"$word1 $word2\", PHP_EOL;\n        } elseif ($x % 3 === 0) {\n            echo $word1, PHP_EOL;\n        } elseif ($x % 5 === 0) {\n            echo $word2, PHP_EOL;\n        } else {\n            $countNumbers++;\n        }\n    }\n\n    return $countNumbers;\n}\n\necho 'number of times it was a number and not words: ' . exercise('hello', 'php');\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/php/lorenamesa.php",
    "content": "<?php\n\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n/**************** FUNCIONES **************/\n\n// Sin parámetro ni retorno\nsayHello();\nfunction sayHello() {\n    print \"Hello\\n\";\n}\n\n// Sin parámetro y con retorno\n$message = sayGoodbye();\necho $message;\nfunction sayGoodbye(): string {\n    return \"Goodbye\\n\";\n}\n\n// Con un parámetro y sin retorno\n$message = printMessage('This is my message');\nfunction printMessage(string $message) {\n    echo $message . \"\\n\";\n}\n\n// Con muchos parámetros y con retorno\n$message = printMessageWithParameters(\"Mi edad es \", \"35\");\necho $message;\nfunction printMessageWithParameters(string $message, string $years): string {\n    return $message . $years . \"\\n\";\n}\n\n// Function inside a function\nholaSoyUnaFuncion();\nfunction holaSoyUnaFuncion() {\n    function dentroDeOtraFuncion() {\n        echo \"Hola, soy una función \";\n    }\n    dentroDeOtraFuncion();\n    echo \"dentro de otra función \\n\";\n}\n\n// Funciones propias del lenguaje\n$fruits = [\"naranja\", \"plátano\", \"manzana\", \"frambuesa\"];\n$fresa = array_push($fruits, \"fresa\");\nforeach ($fruits as $fruit) {\n    echo $fruit . \"\\n\";\n}\n\n// Variable global\n$petName = \"Dolly\";\nmyPetName();\nfunction myPetName() {\n    global $petName;\n    echo 'My pet\\'s name is: ' . $petName . \"\\n\";\n}\n\n// Variable local\nmyBrotherName();\nfunction myBrotherName() {\n    $brotherName = \"Juan\";\n    echo 'My brother\\'s name is: ' . $brotherName . \"\\n\";\n}\n\n/**************** EXTRA **************/\n$total = extraExercise('String 1', 'String 2');\necho \"El número de veces que se ha impreso un número es de: \" . $total;\n\nfunction extraExercise(string $string1, string $string2): int {\n    $count = 0;\n    for ($i = 1; $i <= 100; $i++) {\n        if ($i % 3 === 0 && $i % 5 === 0) {\n            echo $string1 . \" \" . $string2 . \"\\n\";\n        } elseif ($i % 3 === 0) {\n            echo $string1 . \"\\n\";\n        } elseif ($i % 5 === 0) {\n            echo $string2 . \"\\n\";\n        } else {\n            echo $i . \"\\n\";\n            $count++;\n        }\n    }\n    return $count;\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/php/marcode24.php",
    "content": "<?php\n\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n// Ejemplos de funciones básicas\nfunction funcionSinParametrosNiRetorno() {\n  echo '¡Hola desde la función sin parámetros ni retorno!' . PHP_EOL;\n}\n\nfunction funcionConParametros($parametro1, $parametro2) {\n  echo 'Parámetro 1: ' . $parametro1 . PHP_EOL;\n  echo 'Parámetro 2: ' . $parametro2 . PHP_EOL;\n}\n\nfunction funcionConRetorno($num1, $num2) {\n  return $num1 + $num2;\n}\n\n// Funciones dentro de funciones\nfunction funcionExterna() {\n  echo 'Función externa' . PHP_EOL;\n\n  function funcionInterna() {\n    echo 'Función interna' . PHP_EOL;\n  }\n\n  funcionInterna();\n}\n\n// Variable GLOBAL y LOCAL\n$variableGlobal = 'Soy global';\n\nfunction funcionConVariables() {\n  $variableLocal = 'Soy local';\n  global $variableGlobal;\n  echo $variableGlobal . PHP_EOL;\n  echo $variableLocal . PHP_EOL;\n}\n\n// Utilizar función ya creada en el lenguaje\n$numeros = [1, 2, 3, 4, 5];\n$cuadrados = array_map(function($numero) {\n  return $numero * $numero;\n}, $numeros);\n\necho 'Cuadrados: ' . implode(', ', $cuadrados) . PHP_EOL;\n\n// Función Extra (DIFICULTAD EXTRA)\nfunction funcionExtra($texto1, $texto2) {\n  $contador = 0;\n\n  for ($i = 1; $i <= 100; $i++) {\n    if ($i % 3 === 0 && $i % 5 === 0) {\n      echo $texto1 . $texto2 . PHP_EOL;\n    } elseif ($i % 3 === 0) {\n      echo $texto1 . PHP_EOL;\n    } elseif ($i % 5 === 0) {\n      echo $texto2 . PHP_EOL;\n    } else {\n      echo $i . PHP_EOL;\n    }\n\n    $contador++;\n  }\n\n  return $contador;\n}\n\necho 'Número de impresiones: ' . funcionExtra('Fizz', 'Buzz') . PHP_EOL;\n\n// Visita mi repo en GitHub para ver y correr los tests de este código --> https://github.com/marcode24/weekly-challenges\n\n?>\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/php/mayerga.php",
    "content": "<?php\n\n// Ejemplo de funcion sin parametros\nfunction funcionSinParametros(){\n    echo \"Acabas de invocar a tu primera función en PHP\\n\";\n}\n\necho \"1º. Vamos a usar una función sin pasarle ningún parametro y sin retornar nada\\n\";\nfuncionSinParametros();\necho \"\\n\";\n\n// Ejemplo de funcion con parametros\nfunction parametros($parametro1, $parametro2){\n    echo \"El valor del primer parametro es: \".$parametro1.\"\\n\";\n    echo \"El valor del segundo parametro es: \".$parametro2.\"\\n\";\n}\n\necho \"2º. Vamos a usar una función pasando dos parametros y sin retornar nada\\n\";\nparametros(\"Hola\", \"Mundo\");\necho \"\\n\";\n\n// Ejemplo de funcion con parametros por defecto\nfunction parametrosPorDefecto($parametro1 = \"Hola\", $parametro2 = \"Mundo\"){\n    echo \"El valor del primer parametro es: \".$parametro1.\"\\n\";\n    echo \"El valor del segundo parametro es: \".$parametro2.\"\\n\";\n}\n\necho \"3º. En este ejemplo vamos a usar una función con parametros con defecto. Vamos a invocarla solo con el primer parametro\\n\";\nparametrosPorDefecto(\"Hello\");\necho \"\\n\";\n\n// Ejemplo de funcion con parametros por referencia\nfunction porReferencia(&$parametro1){\n    $parametro1 = \"Cambiada la variable\";\n}\n\necho \"4º. En este ejemplo vamos a usar el paso por referencia. El parametro que pasemos se modificará dentro de la función\\n\";\n$cadena = \"Adios\";\nporReferencia($cadena);\necho $cadena.\"\\n\";\necho \"\\n\";\n\n// Ejemplo de funcion con retorno\nfunction funcionConRetorno($parametro1, $parametro2){\n    return $parametro1 + $parametro2;\n}\n\necho \"5º. En este ejemplo vamos a usar una función con retorno. Vamos a sumar dos numeros\\n\";\n$resultado = funcionConRetorno(5, 7);\necho $resultado.\"\\n\";\necho \"\\n\";\n\n// Ejemplo de llamada a funciones anonimas o closures\n$variable = function($parametro1, $parametro2){\n    return $parametro1 + $parametro2;\n};\n\necho \"6º. Llamada a una función anónima (closure)\\n\";\necho $variable(5, 7).\"\\n\";\necho \"\\n\";\n\n// Ejemplo de funcion con retorno por referencia\nfunction retornoPorReferencia(&$parametro1){\n    $parametro1 = \"Cambiada la variable\";\n    return $parametro1;\n}\n\necho \"7º. En este ejemplo vamos a usar una función con retorno por referencia. Vamos a modificar el valor de la variable\\n\";\n$variable = \"Variable original\";\n$resultado = retornoPorReferencia($variable);\necho $resultado.\"\\n\";\necho \"\\n\";\n\n// Ejemplo de variable local y global\n$variableGlobal = \"Variable global\";\nfunction ambitoVariables(){\n    global $variableGlobal;\n    $variableLocal = \"Variable local\";\n    echo $variableLocal.\"\\n\";\n    echo $variableGlobal.\"\\n\";\n}\n\necho \"8º. En este ejemplo vamos a ver el ambito de las variables\\n\";\nambitoVariables();\necho \"\\n\";\n\n// funcion dentro de funcion\nfunction funcionDentroDeFuncion(){\n    function funcionDentroDeFuncion2(){\n        echo \"Funcion dentro de funcion\\n\";\n    }\n    funcionDentroDeFuncion2();\n}\n\necho \"9º. En este ejemplo vamos a ver como se puede llamar a una función dentro de otra función\\n\";\nfuncionDentroDeFuncion();\necho \"\\n\";\n\n// funcion dentro de funcion con parametros\nfunction funcionDentroDeFuncionConParametros(){\n    function funcionDentroDeFuncionConParametros2($parametro1, $parametro2){\n        echo \"Funcion dentro de funcion con parametros\\n\";\n        echo \"El valor del primer parametro es: \".$parametro1.\"\\n\";\n        echo \"El valor del segundo parametro es: \".$parametro2.\"\\n\";\n    }\n    funcionDentroDeFuncionConParametros2(\"Hola\", \"Mundo\");\n}\n\necho \"10º. En este ejemplo vamos a ver como se puede llamar a una función dentro de otra función pasandole parametros\\n\";\nfuncionDentroDeFuncionConParametros();\necho \"\\n\";\n\n// funcion dentro de funcion con parametros por referencia\nfunction funcionDentroDeFuncionConParametrosPorReferencia(){\n    function funcionDentroDeFuncionConParametrosPorReferencia2(&$parametro1){\n        $parametro1 = \"Cambiada la variable\";\n    }\n    $cadena = \"Adios\";\n    funcionDentroDeFuncionConParametrosPorReferencia2($cadena);\n    echo $cadena.\"\\n\";\n}\n\necho \"11º. En este ejemplo vamos a ver como se puede llamar a una función dentro de otra función pasandole parametros por referencia\\n\";\nfuncionDentroDeFuncionConParametrosPorReferencia();\necho \"\\n\";\n\n// funcion dentro de funcion con retorno\nfunction funcionDentroDeFuncionConRetorno(){\n    function funcionDentroDeFuncionConRetorno2($parametro1, $parametro2){\n        return $parametro1 + $parametro2;\n    }\n    $resultado = funcionDentroDeFuncionConRetorno2(5, 7);\n    echo $resultado.\"\\n\";\n}\n\necho \"12º. En este ejemplo vamos a ver como se puede llamar a una función dentro de otra función con retorno\\n\";\nfuncionDentroDeFuncionConRetorno();\necho \"\\n\";\n\n// Ejemplo de uso de una funcion propia de PHP\n$variable = \"Hola Mundo\";\n\necho \"13º. En este ejemplo vamos a ver como se puede llamar a una función propia de PHP, en este caso la que devuelve la longitud de una cadena\\n\";\necho strlen($variable).\"\\n\";\necho \"\\n\";\n\n// Ejercicio extra\n\nfunction extra ($parametro1, $parametro2){\n    $numsImpresos = 0;\n    for ( $i = 1; $i <= 100; $i++){\n        switch ($i){\n            case $i % 15 == 0: \n                    echo $parametro1.$parametro2.\"\\n\";\n                    break;\n            case $i % 3 == 0: \n                    echo $parametro1.\"\\n\";\n                    break;\n            case $i % 5 == 0: \n                    echo $parametro2.\"\\n\";\n                    break;\n            default: \n                    echo $i.\"\\n\";\n                    $numsImpresos++;\n        }\n    }\n\n    return $numsImpresos;\n}\n\necho \"Finalmente vamos a resolver el ejercicio extra|n\";\necho \"Se han imprimido un total de \". extra(\"fizz\", \"buzz\"). \" numeros\";\n\n?>"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/php/miguelex.php",
    "content": "<?php\n\n// Ejemplo de funcion sin parametros\nfunction funcionSinParametros(){\n    echo \"Acabas de invocar a tu primera función en PHP\\n\";\n}\n\necho \"1º. Vamos a usar una función sin pasarle ningún parametro y sin retornar nada\\n\";\nfuncionSinParametros();\necho \"\\n\";\n\n// Ejemplo de funcion con parametros\nfunction parametros($parametro1, $parametro2){\n    echo \"El valor del primer parametro es: \".$parametro1.\"\\n\";\n    echo \"El valor del segundo parametro es: \".$parametro2.\"\\n\";\n}\n\necho \"2º. Vamos a usar una función pasando dos parametros y sin retornar nada\\n\";\nparametros(\"Hola\", \"Mundo\");\necho \"\\n\";\n\n// Ejemplo de funcion con parametros por defecto\nfunction parametrosPorDefecto($parametro1 = \"Hola\", $parametro2 = \"Mundo\"){\n    echo \"El valor del primer parametro es: \".$parametro1.\"\\n\";\n    echo \"El valor del segundo parametro es: \".$parametro2.\"\\n\";\n}\n\necho \"3º. En este ejemplo vamos a usar una función con parametros con defecto. Vamos a invocarla solo con el primer parametro\\n\";\nparametrosPorDefecto(\"Hello\");\necho \"\\n\";\n\n// Ejemplo de funcion con parametros por referencia\nfunction porReferencia(&$parametro1){\n    $parametro1 = \"Cambiada la variable\";\n}\n\necho \"4º. En este ejemplo vamos a usar el paso por referencia. El parametro que pasemos se modificará dentro de la función\\n\";\n$cadena = \"Adios\";\nporReferencia($cadena);\necho $cadena.\"\\n\";\necho \"\\n\";\n\n// Ejemplo de funcion con retorno\nfunction funcionConRetorno($parametro1, $parametro2){\n    return $parametro1 + $parametro2;\n}\n\necho \"5º. En este ejemplo vamos a usar una función con retorno. Vamos a sumar dos numeros\\n\";\n$resultado = funcionConRetorno(5, 7);\necho $resultado.\"\\n\";\necho \"\\n\";\n\n// Ejemplo de llamada a funciones anonimas o closures\n$variable = function($parametro1, $parametro2){\n    return $parametro1 + $parametro2;\n};\n\necho \"6º. Llamada a una función anónima (closure)\\n\";\necho $variable(5, 7).\"\\n\";\necho \"\\n\";\n\n// Ejemplo de funcion con retorno por referencia\nfunction retornoPorReferencia(&$parametro1){\n    $parametro1 = \"Cambiada la variable\";\n    return $parametro1;\n}\n\necho \"7º. En este ejemplo vamos a usar una función con retorno por referencia. Vamos a modificar el valor de la variable\\n\";\n$variable = \"Variable original\";\n$resultado = retornoPorReferencia($variable);\necho $resultado.\"\\n\";\necho \"\\n\";\n\n// Ejemplo de variable local y global\n$variableGlobal = \"Variable global\";\nfunction ambitoVariables(){\n    global $variableGlobal;\n    $variableLocal = \"Variable local\";\n    echo $variableLocal.\"\\n\";\n    echo $variableGlobal.\"\\n\";\n}\n\necho \"8º. En este ejemplo vamos a ver el ambito de las variables\\n\";\nambitoVariables();\necho \"\\n\";\n\n// funcion dentro de funcion\nfunction funcionDentroDeFuncion(){\n    function funcionDentroDeFuncion2(){\n        echo \"Funcion dentro de funcion\\n\";\n    }\n    funcionDentroDeFuncion2();\n}\n\necho \"9º. En este ejemplo vamos a ver como se puede llamar a una función dentro de otra función\\n\";\nfuncionDentroDeFuncion();\necho \"\\n\";\n\n// funcion dentro de funcion con parametros\nfunction funcionDentroDeFuncionConParametros(){\n    function funcionDentroDeFuncionConParametros2($parametro1, $parametro2){\n        echo \"Funcion dentro de funcion con parametros\\n\";\n        echo \"El valor del primer parametro es: \".$parametro1.\"\\n\";\n        echo \"El valor del segundo parametro es: \".$parametro2.\"\\n\";\n    }\n    funcionDentroDeFuncionConParametros2(\"Hola\", \"Mundo\");\n}\n\necho \"10º. En este ejemplo vamos a ver como se puede llamar a una función dentro de otra función pasandole parametros\\n\";\nfuncionDentroDeFuncionConParametros();\necho \"\\n\";\n\n// funcion dentro de funcion con parametros por referencia\nfunction funcionDentroDeFuncionConParametrosPorReferencia(){\n    function funcionDentroDeFuncionConParametrosPorReferencia2(&$parametro1){\n        $parametro1 = \"Cambiada la variable\";\n    }\n    $cadena = \"Adios\";\n    funcionDentroDeFuncionConParametrosPorReferencia2($cadena);\n    echo $cadena.\"\\n\";\n}\n\necho \"11º. En este ejemplo vamos a ver como se puede llamar a una función dentro de otra función pasandole parametros por referencia\\n\";\nfuncionDentroDeFuncionConParametrosPorReferencia();\necho \"\\n\";\n\n// funcion dentro de funcion con retorno\nfunction funcionDentroDeFuncionConRetorno(){\n    function funcionDentroDeFuncionConRetorno2($parametro1, $parametro2){\n        return $parametro1 + $parametro2;\n    }\n    $resultado = funcionDentroDeFuncionConRetorno2(5, 7);\n    echo $resultado.\"\\n\";\n}\n\necho \"12º. En este ejemplo vamos a ver como se puede llamar a una función dentro de otra función con retorno\\n\";\nfuncionDentroDeFuncionConRetorno();\necho \"\\n\";\n\n// Ejemplo de uso de una funcion propia de PHP\n$variable = \"Hola Mundo\";\n\necho \"13º. En este ejemplo vamos a ver como se puede llamar a una función propia de PHP, en este caso la que devuelve la longitud de una cadena\\n\";\necho strlen($variable).\"\\n\";\necho \"\\n\";\n\n// Ejercicio extra\n\nfunction extra ($parametro1, $parametro2){\n    $numsImpresos = 0;\n    for ( $i = 1; $i <= 100; $i++){\n        switch ($i){\n            case $i % 15 == 0: \n                    echo $parametro1.$parametro2.\"\\n\";\n                    break;\n            case $i % 3 == 0: \n                    echo $parametro1.\"\\n\";\n                    break;\n            case $i % 5 == 0: \n                    echo $parametro2.\"\\n\";\n                    break;\n            default: \n                    echo $i.\"\\n\";\n                    $numsImpresos++;\n        }\n    }\n\n    return $numsImpresos;\n}\n\necho \"Finalmente vamos a resolver el ejercicio extra|n\";\necho \"Se han imprimido un total de \". extra(\"fizz\", \"buzz\"). \" numeros\";\n\n?>"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/php/qv1ko.php",
    "content": "<?php\n\n$a = 3;\n\nmain();\n\nfunction main() {\n\n    func1();\n\n    echo func2();\n\n    func3($GLOBALS['a'], \"\\nParameterized and non-return function:\\nGlobal variable A: \");\n\n    echo func4(-4, \"\\nFunction with return and with parameters:\\nGlobal variable A: \");\n\n    echo \"\\nProgram:\";\n    echo \"\\nNumber of times a text was not printed: \" . program(\"zip\", \"zap\");\n\n}\n\nfunction func1() {\n    $b = 4;\n    echo \"\\nFunction without return and without parameters:\\nGlobal variable A: \" . $GLOBALS['a'] . \"\\nLocal variable B: \" . $b;\n}\n\nfunction func2() {\n    return \"\\nFunction with return and without parameters:\\nGlobal variable A: \" . $GLOBALS['a'];\n}\n\nfunction func3($num, $str) {\n    echo $str . $num;\n}\n\nfunction func4($num, $str) {\n    return $str . $GLOBALS['a'] . \"\\nAbsolute number: \" . abs($num);\n}\n\nfunction program($zip, $zap) {\n\n    $count = 0;\n\n    for ($i = 1; $i <= 100; $i++) {\n        if ($i % 3 == 0 && $i % 5 == 0) {\n            echo \"\\n\";\n            echo $zip . $zap;\n        } elseif ($i % 3 == 0) {\n            echo \"\\n\";\n            echo $zip;\n        } elseif ($i % 5 == 0) {\n            echo \"\\n\";\n            echo $zap;\n        } else {\n            $count++;\n        }\n    }\n\n    return $count;\n\n}\n\n?>\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/php/rocallejas.php",
    "content": "<?php\n# Crea ejemplos de funciones básicas que representen las diferentes posibilidades del lenguaje:\n# Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n\n    /**\n     * Sin utilizar parámetros ni retorno.\n     */\n    function greeting() {\n        echo \"¡Hola, PHP!<br>\";\n    }\n\n    // Llamada a la función\n    greeting();\n\n    /**\n     * Función que saluda utilizando un parámetro.\n     *\n     * @param string $nombre Nombre para saludar.\n     */\n    function saludar($nombre) {\n        echo \"¡Hola, $nombre!<br>\";\n    }\n\n    // Llamada a la función con un parámetro\n    saludar(\"John\");\n\n    /**\n     * Función que realiza operaciones matemáticas con dos parámetros.\n     *\n     * @param int $a Primer número.\n     * @param int $b Segundo número.\n     *\n     */\n    function operations($a, $b) {\n        $suma = $a + $b;\n        $producto = $a * $b;\n\n        echo \"La suma de $a y $b es: $suma<br>\";\n        echo \"El producto de $a y $b es: $producto<br>\";\n    }\n\n    // Llamada a la función con varios parámetros\n    operations(5, 3);\n\n    /**\n     * Función que calcula el cuadrado de un número (Tiene un valor de retorno).\n     *\n     * @param float $numero Número para calcular su cuadrado.\n     *\n     * @return float Cuadrado del número.\n     */\n    function calcularCuadrado($numero) {\n        $cuadrado = $numero * $numero;\n        return $cuadrado;\n    }\n\n    // Llamada a la función y asignación del valor de retorno a una variable\n    $resultadoCuadrado = calcularCuadrado(7.5);\n\n    // Impresión del resultado\n    echo \"El cuadrado de 7.5 es: $resultadoCuadrado\";\n\n    /**\n     * Función que calcula el cuadrado y el cubo de un número.\n     * Esta función recibe parametros por referencia\n     * Estas funciones son utiles cuando esperamos recibir más de un valor de retorno\n     *\n     * @param float $numero Número para calcular su cuadrado y cubo.\n     * @param float $cuadrado Referencia para almacenar el cuadrado del número.\n     * @param float $cubo Referencia para almacenar el cubo del número.\n     */\n    function calcularCuadradoYCubo($numero, &$cuadrado, &$cubo) {\n        $cuadrado = $numero * $numero;\n        $cubo = $numero * $numero * $numero;\n    }\n\n    // Uso de la función con parámetros por referencia\n    $numero = 4.5;\n    $cuadradoResultado = 0;\n    $cuboResultado = 0;\n\n    calcularCuadradoYCubo($numero, $cuadradoResultado, $cuboResultado);\n\n    // Impresión de los resultados\n    echo \"El cuadrado de $numero es: $cuadradoResultado<br>\";\n    echo \"El cubo de $numero es: $cuboResultado\";\n\n\n# Comprueba si puedes crear funciones dentro de funciones.\n\n    function funcionExterna($parametroExterno) {\n        // Definición de la función interna\n        function funcionInterna($parametroInterno) {\n            return $parametroInterno * 2;\n        }\n\n        // Llamada a la función interna\n        $resultado = funcionInterna($parametroExterno);\n\n        return $resultado;\n    }\n\n    // Llamada a la función externa\n    $valorExterno = 5;\n    $resultadoFinal = funcionExterna($valorExterno);\n\n    echo \"El resultado final es: $resultadoFinal\";\n\n# Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n    // Muestra toda la información, por defecto INFO_ALL\n    phpinfo();\n\n    // Muestra solamente la información de los módulos.\n    // phpinfo(8) hace exactamente lo mismo.\n    phpinfo(INFO_MODULES);\n\n    // Función que convierte una cadena de texto a mayúsculas\n    $str = \"Mary Had A Little Lamb and She LOVED It So\";\n    $str = strtoupper($str);\n    echo $str; // muestra: MARY HAD A LITTLE LAMB AND SHE LOVED IT SO\n\n# Pon a prueba el concepto de variable LOCAL y GLOBAL\n    // Variable global\n    $variableGlobal = 10;\n\n    function localGlobal() {\n        // Variable local\n        $variableLocal = 5;\n\n        // Acceder a la variable global dentro de la función\n        global $variableGlobal;\n\n        echo \"Variable local dentro de la función: $variableLocal<br>\";\n        echo \"Variable global dentro de la función: $variableGlobal<br>\";\n\n        // Modificar la variable global desde la función\n        $variableGlobal = 20;\n    }\n\n    // Llamada a la función\n    localGlobal();\n\n    // Acceder a la variable global fuera de la función\n    echo \"Variable global fuera de la función: $variableGlobal\";\n\n# Reto Extra\n    /**\n     * Imprime números del 1 al 100 siguiendo ciertas reglas y cuenta cuántas veces se imprime un número\n     * y no un texto pasado por parámetro.\n     *\n     * @param string $texto1 Cadena de texto a imprimir si el número es múltiplo de 3.\n     * @param string $texto2 Cadena de texto a imprimir si el número es múltiplo de 5.\n     *\n     * @return int Número de veces que se ha impreso un número en lugar de un texto.\n     */\n    function retoExtra($texto1, $texto2) {\n        $contador = 0;\n\n        for ($i = 1; $i <= 100; $i++) {\n            if ($i % 3 == 0 && $i % 5 == 0) {\n                echo $texto1 . $texto2 . \"<br>\";\n            } elseif ($i % 3 == 0) {\n                echo $texto1 . \"<br>\";\n            } elseif ($i % 5 == 0) {\n                echo $texto2 . \"<br>\";\n            } else {\n                echo $i . \"<br>\";\n                $contador++;\n            }\n        }\n\n        return $contador;\n    }\n\n    // Ejemplo de uso\n    $vecesImpreso = retoExtra(\"Fizz\", \"Buzz\");\n    echo \"La función ha impreso $vecesImpreso el número en lugar de los textos.\";\n?>"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/prolog/blfuentes.pl",
    "content": "%\n%EJERCICIO:\n%- Crea ejemplos de funciones básicas que representen las diferentes\n%  posibilidades del lenguaje:\n%  Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n%- Comprueba si puedes crear funciones dentro de funciones.\n%- Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n%- Pon a prueba el concepto de variable LOCAL y GLOBAL.\n%- Debes hacer print por consola del resultado de todos los ejemplos.\n%  (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n%\n%DIFICULTAD EXTRA (opcional):\n%Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n%- La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n%  - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n%  - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n%  - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n%  - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n%\n%Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n%Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n%\n\n% Las funciones en prolog siempre devuelven success/fail\n\n% function sin parámetro ni retorno\nno_param_no_return :- write('Esta función no tiene parémetro ni retorno').\n% función con parámetro sin retorno\nparam_no_return(X) :- \n    write('El valor del parámetro es: '), write(X), nl.\n% función sin parámetro y retorno\n% en prolog las funciones no devuelven valores\n\n% función con múltiples parámetros\nmulti_param(X, Y) :-\n    SUM is X + Y, write('La suma es: '), write(SUM), nl.\n\n% en prolog no hay funciones anidadas\n\n% ejemplos de funciones existentes en prolog\nbuilt-in_functions(X) :-\n    (member(X, [1, 2, 3]) ->\n        write(X), write(' está en la lista'),nl\n    ;\n        write(X), write(' no está en la lista'),nl\n    ),\n    RAIZ is sqrt(X), \n    write('La raiz de '), write(X), write(' es: '), write(RAIZ), nl.\n\n% variables locales y globales\n% en prolog no hay variables globales, sólo locales\n\n\n% EJERCICIO\n% Predicado contador\nmostrar_numeros_y_contar(Text1, Text2, Count) :-\n    mostrar_numeros_y_contar(1, 100, Text1, Text2, 0).\n% Caso base de retorno\nmostrar_numeros_y_contar(101, _, _, _, Contador) :-\n    write('Se imprimen: '),write(Contador).\n\n% Caso recursivo, imprimir número y calcular contador\nmostrar_numeros_y_contar(Numero, Maximo, TextoA, TextoB, Contador) :-\n    (\n        0 is Numero mod 3,\n        0 is Numero mod 5 ->\n        write(TextoA), write(TextoB),nl,\n        ProximoNumero is Numero + 1,\n        mostrar_numeros_y_contar(ProximoNumero, Maximo, TextoA, TextoB, Contador)\n    ;\n        0 is Numero mod 3 ->\n        write(TextoA), nl,\n        ProximoNumero is Numero + 1,\n        mostrar_numeros_y_contar(ProximoNumero, Maximo, TextoA, TextoB, Contador)\n    ;\n        0 is Numero mod 5 ->\n        write(TextoB), nl,\n        ProximoNumero is Numero + 1,\n        mostrar_numeros_y_contar(ProximoNumero, Maximo, TextoA, TextoB, Contador)\n    ;\n        write(Numero), nl,\n        ProximoNumero is Numero + 1,\n        ProximoContador is Contador + 1,\n        mostrar_numeros_y_contar(ProximoNumero, Maximo, TextoA, TextoB, ProximoContador)\n    ).\n\n% Usarlo\n%mostrar_numeros_y_contar('Fizz', 'Buzz', Count).\n    "
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/13sauca13.py",
    "content": "#Funcion sin parametros ni retorno\ndef funcion1 ():\n    var=\"Una variable en la funcion\"\n    var2=3\n\nfuncion1()\n\n#Funcion con parametros y retorno\ndef funcion2 (num1,num2):\n    return num1+num2\n\nprint(funcion2(6,3))\n\n#Funciones integradas en el lenguaje:\nprint(\"El print es una funcion de Python\")\n\na=\"El len() también lo es\"\nprint(len(a))\n\n#Existen tambien las funciones lambda, que son funciones anónimas pequeñas\nmultiplicacion=lambda a,b,c : a*b*c\nprint(multiplicacion(10,3,5))\n#Tambien se pueden declarar y llamar en la misma linea\nprint((lambda var1,var2 : var1**var2)(2,3))\n\n#EXTRA\ndef ej_extra(a,b):\n    for i in range(1,101):\n        if not i%3 and not i%5:\n            print(a,b)\n        elif not i%3:\n            print(a)\n        elif not i%5:\n            print(b)\n        else:\n            print(i)\n\nej_extra(\"pen\",\"pineapple\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/59822.py",
    "content": "'''EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.'''\n \n#Función simple\n#Función sin parametros\n\ndef hablar():\n    print(\"Hola, soy una función\")\n\nprint(hablar()) #Aqui imprime none porque no tiene una funcion return\nhablar() #Aqui imprime el print de la función\n\n#Función sin parametros ni retorno\ndef hablar2():\n    pass\n\n#Función con varios parametros\ndef hablar3(nombre, apellido):\n    print(\"Hola, soy\", nombre, apellido)\n\nhablar3(\"Laura\", \"Gonzalez\")\n\n#Funcion con un parametro y retorno\ndef hablar(nombre):\n    return \"Hola, soy \" + nombre\nprint(hablar(\"Laura\")) #Aqui imprime el return de la función\n\n#Funciones con parametros por defecto\n\ndef estudio(universidad = \"Universidad Nacional\"):\n    print(\"Estudio en la\", universidad)\nestudio()\n\n#Funcion con retorno sin parametros\n\ndef casa():\n    casa = \"verde\"\n    return f\"Mi casa es {casa}\"\nprint(casa())\n\n#Funcion lambda es una función anónima que se puede usar para hacer una función en una sola linea\n#Funcion lambda con un parametro\nsuma = lambda x: x + 10\nprint(suma(5))\n\n#Funcion lambda con varios parametros\nnombre_completo = lambda nombre, apellido: f\"{nombre} {apellido}\"\nprint(nombre_completo(\"Laura\", \"Gonzalez\"))\n\n#Funcion lambda con varios parametros y operaciones\nresta = lambda x,y,z,w: x - y + z / w\nprint(resta(10,2,3,2))\n\n#Funcion recursiva es una función que se llama a si misma\ndef factorial(numero = 4):\n    if numero == 1:\n        return 1\n    else:\n        return numero * factorial(numero - 1)\n\nprint(factorial())\n\n#Funcion con argumentos es una función que recibe un número indeterminado de argumentos\ndef suma_con_args(*args):\n    return sum(args)\n\nprint(suma_con_args(1,2,3,4,5))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/AChapeton.py",
    "content": "# Invocar una funcion\ndef saludar():\n  print(\"Hola!\") # Uso de funcion print() ya existente en Python\n\nsaludar()\n\n# Retornar un valor\ndef returnValue():\n  return 10\n\nreturnValue()\n\n# Retornar multiples valores\ndef returnMultiple():\n  return 0, 1\n\nreturnMultiple()\n\n# Funciones con parametros\ndef raiz(value):\n  return value ** (1/2)\n\nraiz(9)\n\ndef minMax(a, b):\n  return a < b\n\nminMax(6, 4)\n\n# Funciones con parametros con valores por default\ndef byDefault(a, b = 2):\n  return a + b\n\nbyDefault(3, 2)\nbyDefault(9) \n\n\n# DIFICULTAD EXTRA\ndef fizzBuzz(text1, text2):\n  numbers = 0\n  for i in range(1, 101):\n    if i % 3 == 0 and i % 5 == 0:\n      print(text1 + text2)\n    elif i % 3 == 0:\n      print(text1)\n    elif i % 5 == 0:\n      print(text2)\n    else:\n      numbers += 1\n      print(i)\n  print('Cantidad de numeros donde no hay texto: ', numbers)\n  return numbers\n\nfizzBuzz('fizz', 'buzz')\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/AbelPerezCollado.py",
    "content": "# Func sin parametros ni retorno\ndef sin_param_retorno():\n    print('Funcion no devuelve nada ni tiene parametros')\n\n# Func con varios parametros con retorno\ndef suma(num1:int , num2:int):\n    return num1 + num2\n\n# Funciones dentro de funciones\ndef fun_dentro(param1:int,param2:int):\n    def suma(n1,n2):\n        return n1 + n2\n    return suma(param1,param2)\n\n# Funcion con parametros por defecto\ndef fun_param_defecto(nombre = 'Abel', apellido = 'Perez'):\n    return f'Bienvenido, {nombre} {apellido}' \n\n# Ejemplo de funciones ya creadas en el lenguaje\nnombre ='Abel'\nprint(f'El numero de letras de {nombre} es de {len(nombre)}')\n\n\n# Funcion Lambda\nsquare = lambda num : num * num\nprint(square(3))\n\n# Funcion recursiva\n\n# función recursiva\ndef factorial(numero):\n    if numero == 0 or numero == 1:\n        return 1\n    else:\n        return numero * factorial(numero - 1)\n\nprint(factorial(41))\n\n# Concepto de variable Local y Global\nvar_global = 100\n\ndef devuelve_numero(num : int):\n    var_local = num\n    return var_local\n\n \n# Dificultad extra\n\ndef funcion_dificultad_extra(cad1 : str, cad2:str):\n    cont = 0\n    for num in range(1,101):\n        if num % 3 == 0 and num % 5 == 0:\n            print(f'{cad1}{cad2}')\n        elif num % 3 == 0:\n            print(cad1)\n        elif num % 5 == 0:\n            print(cad2)\n        else:\n            cont += 1\n    return cont"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/AgustinDamonte17.py",
    "content": "# -----------------------------\n# Función sin parámetros ni retorno\n# -----------------------------\ndef saludar():\n    print(\"Hola, mundo!\")\n\nsaludar()\nprint()\n\n# -----------------------------\n# Función con parámetros\n# -----------------------------\ndef saludar_nombre(nombre):\n    print(f\"Hola, {nombre}!\")\n\nsaludar_nombre(\"Agustín\")\nprint()\n\n# -----------------------------\n# Función con varios parámetros y retorno\n# -----------------------------\ndef sumar(a, b):\n    return a + b\n\nresultado = sumar(5, 7)\nprint(\"Resultado de sumar(5, 7):\", resultado)\nprint()\n\n# -----------------------------\n# Función dentro de función\n# -----------------------------\ndef funcion_externa(x):\n    def funcion_interna(y):\n        return y * 2\n    print(\"Resultado de funcion_interna:\", funcion_interna(x))\n\nfuncion_externa(4)\nprint()\n\n# -----------------------------\n# Uso de funciones ya creadas en Python\n# -----------------------------\nnumeros = [4, 2, 8, 1]\nprint(\"Lista original:\", numeros)\nprint(\"Lista ordenada con sorted():\", sorted(numeros))\nprint(\"Longitud con len():\", len(numeros))\nprint(\"Máximo con max():\", max(numeros))\nprint()\n\n# -----------------------------\n# Variables GLOBAL y LOCAL\n# -----------------------------\nvariable_global = \"Soy global\"\n\ndef prueba_variables():\n    variable_local = \"Soy local\"\n    print(\"Dentro de la función:\")\n    print(\"Local:\", variable_local)\n    print(\"Global (accedida):\", variable_global)\n\nprueba_variables()\n\nprint(\"\\nFuera de la función:\")\nprint(\"Global:\", variable_global)\n# print(variable_local)  # Esto daría error si lo descomentás\nprint()\n\n# -----------------------------\n# DIFICULTAD EXTRA\n# -----------------------------\ndef fizzbuzz_personalizado(palabra1, palabra2):\n    contador_numeros = 0\n    for i in range(1, 101):\n        texto = \"\"\n        if i % 3 == 0:\n            texto += palabra1\n        if i % 5 == 0:\n            texto += palabra2\n        if texto:\n            print(texto)\n        else:\n            print(i)\n            contador_numeros += 1\n    return contador_numeros\n\nprint(\"Ejecutando FizzBuzz personalizado:\")\nveces_impreso_numero = fizzbuzz_personalizado(\"Fizz\", \"Buzz\")\nprint(f\"Números impresos (sin Fizz ni Buzz): {veces_impreso_numero}\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/AgustinFCCll.py",
    "content": "## RETO 02  DIFICULTAD EXTRA\n\ndef fuction(value_one, value_two):\n    contador = 0\n    for i in range(1, 101):            \n        if i % 3 == 0 and i % 5 == 0:\n            print(value_one + value_two)\n        elif i % 3 == 0:         \n            print(value_one)\n        elif i % 5 == 0:          \n            print(value_two)\n        else:\n            print(i)\n            contador += 1\n    return contador               \n\nresultado = fuction( \" Multiplo de 3 \", \" multiplo de 5 \")\nprint(\"El numero se a impreso: \",resultado)\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/AlainMartz.py",
    "content": " ### RETO #02 FUNCIONES Y ALCANCE\n\n\"\"\"\n Crea ejemplos de funciones básicas que representen las diferentes posibilidades del lenguaje:\n Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n\"\"\"\n# Función vacía\ndef vacio():\n    pass\nvacio()\n\n# Función sin parámetros\ndef sinpa():\n    print(\"Esta función no tiene parámetros\")\nsinpa() \n\n# Función con un parámetro\ndef saludo(nombre):\n    print(f\"Hola {nombre}! Días buenos tenga usted\")\nsaludo(\"Cris\")\n\n# Función con varios parámetros\ndef potencia(a,b):\n    x = a**b\n    print(x)\npotencia(3,3)\n\n# Función con parámetro por defecto\ndef area_circulo(r,pi=3.14):\n    area = pi*(r**2)\n    print(area)\narea_circulo(1)\n\n# Función con tuplas de argumentos variables\ndef producto(*args):\n    x = 1\n    for i in args:\n        x *= i\n    print(x)\n\nproducto(2,3,4,5)\n\n# Función con diccionarios de argumentos variables \ndef estadisticas_temperaturas(*temps, **kwargs):\n    media = sum(temps)/len(temps)\n    suma = sum((i - media)**2 for i in temps)\n    devstd = (suma/(len(temps)-1))**0.5\n    if kwargs.get('promedio'):\n        print(f\"El promedio de las temperaturas es {media} grados\")\n    if kwargs.get('desviacion'):\n        print(f\"El desviación estándar de las temperaturas es {round(devstd,3)} grados\")\n\nestadisticas_temperaturas(1,2,3,4,5,6,promedio=True,desviacion=True)\n\n# Funcion que retorna un valor\n\ndef multiplicar(a,b):\n    return a*b\n\nprint(multiplicar(2,3))\n\n# Funcion que retorne varios valores\ndef ops_basicas(a,b):\n    suma = a+b\n    resta = a - b\n    multiplicacion = a * b\n    division = a/b\n    return suma, resta, multiplicacion, division\n\nprint(ops_basicas(2,3))\n\n# Funcion anónimas con un argumento\nsquared = lambda x : x**2\nprint(squared(2))\n\n# Funcion anónimas con varios argumentos\ndivided = lambda x,y : x/y\nprint(divided(2,3))\n\n# Funcion anidada\ndef conversor_temps(t,**kwargs):\n    def celconv(c):\n        cel2far = ((9/5)*c) + 32\n        cel2kel = c + 273.15\n        return cel2far,cel2kel\n    def farconv(c):\n        far2cel = (c-32)*(5/9)\n        far2kel = ((c-32)*(5/9))+273.15\n        return far2cel,far2kel\n    def kelconv(c):\n        kel2cel = c - 273.15\n        kel2far = ((c - 273.15)*(9/5))+32\n        return kel2cel,kel2far\n    if kwargs.get('celcius'):\n        far, kel = celconv(t)\n        print(f\"{t}°C son igual a {round(far,2)}°F y {round(kel,2)}K\")\n        return far, kel\n\n    if kwargs.get('farenh'):\n        cel, kel = farconv(t)\n        print(f\"{t}°F son igual a {round(cel,2)}°C y {round(kel,2)}K\")\n        return cel, kel\n\n    if kwargs.get('kelvin'):\n        cel, far = kelconv(t)\n        print(f\"{t}K son igual a {round(cel,2)}°C y {round(far,2)}°F\")\n        return cel, far\n\nconversor_temps(4,celcius=True)\nconversor_temps(4,farenh=True)\nconversor_temps(4,kelvin=True)\n\n## Funciones predefinidas\n\nprint(f\"len() muestra el largo de los datos: Paralelepipedo = {len('paralelepipedo')}\")\nprint(f\"int() convierte a enteros por ejemplo 5.0 = {int(5.0)}, '10' = {int('10')} \")\nprint(f\"min() y max() muestran los valores máximos y mínimos de una lista... [1,2,3,4,5,6,7,8,9] => min = {min([1,2,3,4,5,6,7,8,9])}; max = {max([1,2,3,4,5,6,7,8,9])}\")\nprint(f\"\"\"\nmap() sirve para aplicar una función a cada ítem de un iterable (por ejemplo, una lista) y retorna un obejto map\npor ejemplo, la conversión de la siguiente lista de °C a °F: [1,2,3,4,5,6,7,8,9,10] : \"\"\", list(map(lambda x : (x*9/5)+32,[1,2,3,4,5,6,7,8,9,10])))\n\n## Alcance / scope\n\n# Variable local\n\ndef localvar(c):\n    x = c\n    return print(x)\n\nlocalvar(\"Este es un ejemplo de variable local\")\n\n# Variable global\n\nk = \"Variable global inicial\"\nprint (k)\n\ndef modglobal(c):\n    global k\n    k = c\n    return print(k)\n\nmodglobal(\"Este print ha modificado la variable global\")\n\n## EXTRA\n\n\"\"\"\nCrea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n- La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n- Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n- Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n- Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n- La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\"\"\"\ndef charnums(str1,str2):\n    counter = 0\n    for i in range(1,101):\n        if i%3==0 and i%5==0:\n            print(str1+\" \"+str2)\n        elif i%3==0:\n            print(str1)\n        elif i%5==0:\n            print(str2)\n        else:\n            print(i)\n            counter +=1\n    return counter\n\nresultado = charnums(\"texto de prueba 1\", \"texto 2\")\nprint(f\"Se imprimió {resultado} veces el número\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/AlbertoMorilla.py",
    "content": "\"\"\"\nFunciones definidas por el usuario\n\"\"\"\n# Simple\n\ndef saludar():\n    print(\"Hola kiyo\")\n\nsaludar()\n\n# Con retorno\n\ndef retornar_saludo():\n    return \"Hola kiyo\"\n\nsaludo = retornar_saludo()\nprint(retornar_saludo())\n\n# Con un argumento\n\ndef arg_saludo(name):\n    print (f\"Hola, {name}!\")\n\narg_saludo(\"Alberto\")\n\n# Con argumentos\n\ndef args_saludo(saludo, name):\n    print (f\"{saludo}, {name}!\")\n\nargs_saludo(\"Ei\", \"Alberto\") \n\n# Con un argumento predeterminado\n\ndef default_arg_saludo(name=\"Python\"):\n    print(f\"Hola, {name}!\")\n\ndefault_arg_saludo(\"Betico\")\ndefault_arg_saludo()\n\n# Con argumentos y retorno\n\ndef return_args_saludo(name=\"Python\"):\n    return f\"{saludo}, {name}!\"\n\nprint(return_args_saludo())\n\n# Con retorno de varios valores\n\ndef return_multiple_values():\n    return \"Hola\", \"Ei\"\n\nsaludo, name = return_multiple_values()\nprint(saludo)\nprint(name)\n\n# Con un numero variable de argumentos\n\ndef variable_arg_saludo(*names):\n    for name in names:\n        print(f\"Hola, {name}!\")\n\nvariable_arg_saludo(\"Python\", \"Alberto\", \"Betico\")\n\n# Con un numero variable de argumentos con palabra clave\n\ndef variable_arg_saludo(**names):\n    for key, valeu in names.items():\n        print(f\"Hola, {valeu} ({key})!\")\n\nvariable_arg_saludo(\n    lenguaje=\"Python\",\n    name=\"Alberto\", \n    edad=\"36\", \n    alias=\"Pepino\"\n    )\n\n\"\"\"\nFunciones dentro de funciones\n\"\"\"\n\ndef otra_function():\n    def inner_function():\n        print(\"Hola, soy una función interna\")\n    inner_function()\n\notra_function()\n\n\"\"\"\nFunciones del lenguaje (built-in)\n\"\"\"\n\nprint(len(\"Morilla\".upper()))\nprint(type(\"Morilla\"))\nprint(\"Morilla\".upper())\n\n\"\"\"\nVariables locales y globales\n\"\"\"\n\nglobal_var = \"Python\"\n\n\ndef hello_python():\n    local_var = \"hola\"\n    print(f\"{local_var}, {global_var}!\")\n\nprint(global_var)\n# print(local_var) No se puede acceder desde fuera de la funcion\n\nhello_python()\n\n\"\"\"\nExtra\n\"\"\"\n\ndef print_numbers(text1, text2)-> int:\n    count = 0\n    for number in range(1, 101):\n        if number % 3 == 0 and number % 5 == 0:\n            print(text1 + text2)\n        elif number % 3 == 0:\n            print(text1)\n        elif number % 5 == 0:\n            print(text2)       \n        else:\n            print(number)\n            count += 1\n    return count\n\nprint(print_numbers(\"Fizz\", \"Buzz\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Aldroide.py",
    "content": "# Función sin parametros ni retorno\ndef funcion():\n    print(3+4)\n\n\nfuncion()\n\n# Función con parametro sin retorno\n\n\ndef funcion(A):\n    print(A)\n\n\nfuncion(\"Esta es una función con parametro\")\n\n# Función con parametros y con retorno\n\n\ndef funcion(A):\n    return (A+1)\n\n\nB = funcion(3)\nprint(f\"Esta función regreso un {B}\")\n\n# Funciones dentro de Funciones\n\n\ndef Funcion(A):\n    print(\"Primera función\")\n\n    def función(B):\n        print(f\"Este es el parametro de la primer función {B}\")\n    función(A)\n\n\nFuncion(\"45\")\n\n# Funciones lambda\n\n\ndef x(a, b): return a + b  # Función lambda que multiplica dos números\n\n\nprint(x(9, 6))\n\n# funciones propias del lenguaje\nA = sum([4, 6, 7, 8, 0, 5, 16, 9])\nprint(f\"Suma de un arreglo usando la función sum() {A}\")\nA = pow(4, 2)\nprint(f\"Elevar un numero a una potencia pow(a,b) {A}\")\nA = min([4, 6, 7, 8, 0, 5, 16, 9])\nprint(f\"Minimo numero de un arreglo usando función min() {A}\")\nA = max([4, 6, 7, 8, 0, 5, 16, 9])\nprint(f\"Maximo número de un arreglo usando la función max() {A}\")\n\n# Variables locales y globales\nG = \"yo soy una variable global\"\n\n\ndef funcion():\n    L = \"soy una variable local\"\n    print(L)\n    print(G)\n\n\nfuncion()\n\n# Ejercicio de dificultad extra\ndef funcion_final(a, b):\n    cont = 0\n    for i in range(1, 101):\n        if i%3==0 and i%5==0:\n            print(a+b)\n        elif i%3 ==0:\n            print(a)\n        elif i%5==0:\n            print(b)\n        \n        else:\n            cont +=1\n    return cont\n\n\nresultado = funcion_final(\"Hello\", \" word\")\nprint(f\"Número que se ha impreso el número : {resultado}\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/AlejandroDave.py",
    "content": "# 02 Funciones y Alcance\n\n#Funciones sin parametros ni retorno\ndef noParFun():\n    print(\"Saludos mi gente\")\n\nnoParFun()\n\n#Funciones uno o varios parametros y retorno\ndef potNum(num1,num2):\n    return pow(num1,num2)  #Aqui utilizamos una funcion predimentada, la cual genera una potencia acorde dos numeros dados.\n\n#Dentro de funciones podemos invocar otras funciones\ndef listpow(lista,pot):\n    listpot = []\n    for x in lista:\n        listpot.append(potNum(x,pot))\n    return listpot\n\nprint(listpow([1,2,3,4,5],5))\n\n'''En Python existe un tipo de funciones nombradas \"High Functions\" en las cuales podemos manejar otras funciones de 'baja'\n    jerarquia\n'''\n\n# En una alta funcion, podemos ingresar otra funcion como parametro, y a su vez que nos regrese una funcion como retorno.\ndef altaFunc(f,param):\n    ret = []\n    return f(param)  # Nota, al invocarlas es importante tener conocimiento sobre los parametros con los que trabaja la funcion\n\ndef funSencilla(nombre):\n    return \"Hola {}!\".format(nombre)\n\nprint(altaFunc(funSencilla,\"Python\"))\n\n# Dentro de una funcion no solo podemos invocar otra funcion, si no tambien podemos crear nuevas funciones\n\ndef sumMulti(n,m):\n    x = 0\n    def multipl(n):  # Definimos una funcion dentro de la alta funcion\n        return n*m\n    for i in range(n):\n        x = x + multipl(i) \n    return x\n\nprint(sumMulti(5,7))\n\ndef funcReto(par1,par2):\n    for i in range(100):\n        if i%3 == 0 and i%5 == 0:\n            print(\"{} {}\".format(par1, par2))\n        elif i%3 == 0:\n            print(par1)\n        elif i%5 == 0:\n            print(par2)\n        else: print(i)\n\nprint(funcReto(\"Hola\",\"Python\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Aleran07.py",
    "content": "# 02\n# Primero que son funciones basicas que representen las diferentes posibilidades de\n\n\n# funcion con parametro\ndef mi_funcion(x): # Funcion con parametro\n    #codigo\n    print(\"what's up bro?\")\n    return\n\nmi_funcion(1) # si o si toca enviarle un parametro para que se ejecute asi no haga nada con ese parametro\n\n# funcion sin parametro\ndef mi_funcion_sin_parametro():\n    print(\"Aqui no se usa parametro\")\n    return\n\nmi_funcion_sin_parametro()\n\n# funcion sin parametro pero con retorno\ndef funcion_sin_parametro_pero_con_retorno(): # las funciones puedes nombrarse de forma larga\n    return \"que pedo\"\n\nx = funcion_sin_parametro_pero_con_retorno() # aqui la funcion se crea para que retorne algo\nprint(x)\n\n# funcion con parametro y retorno\ndef sumar(a, b):\n    return a + b\n\nprint(sumar(2, 5))\n\n# funciones con parametros por defecto\ndef saludar(name=\"invitado\"):\n    print(f\"Hola, {name}\")\n\nsaludar()\nsaludar(\"boludo\")\n\n# funciones con parametros variables\ndef mostrar_args(*args, **kwargs):\n    print(\"args:\", args)\n    print(\"kwargs:\", kwargs)\n\nmostrar_args(1, 2, 3, name=\"Brian\", age=24)\n\n\"\"\"\nPor lo tanto los parametros son datos que la funcion necesita.\nMientras que el retorno es el resultado que entrega la funcion\n\"\"\"\n\n# funciones anidadas\ndef funcion_externa():\n    print(\"Soy la función externa\")\n\n    def funcion_interna():\n        print(\"Soy la función interna\")\n\n    # Llamamos a la interna dentro de la externa\n    funcion_interna()\n\n# Ejecuto la externa\nfuncion_externa()\n# funcion_interna() son puede ser llamada fuera de la funcion mas grande\n\n# funcion interna con retorno\ndef externa(x):\n    def interna(y):\n        return y * 2\n    return interna(x)\n\nprint(externa(5))  # 10\n\n# funcion closure\ndef multiplicador(n):\n    def multiplicar(x):\n        return x * n\n    return multiplicar\n\ndoble = multiplicador(2)\ntriple = multiplicador(3)\n\nprint(doble(5))   # 10\nprint(triple(5))  # 15\nprint(doble(2))   # 4\n\n# Ejemplo random\ndef caluladora_simple(x, tipo):\n    def suma(y):\n        return x + y\n    def restar(y):\n        return x - y\n    def multiplicar(y):\n        return x * y\n    def dividir(y):\n        return x / y\n    # return {\"sumar\": suma, \"restar\": restar, \"multiplicar\": multiplicar, \"dividir\": dividir}\n    if tipo == \"suma\":\n        return suma\n    elif tipo == \"restar\":\n        return restar\n    elif tipo == \"multiplicar\":\n        return multiplicar\n    elif tipo == \"dividir\":\n        return dividir\n\nx = caluladora_simple(2, \"suma\")\ny = x(3)\nprint(y)\n\nx = caluladora_simple(2, \"restar\")\ny = x(3)\nprint(y)\n\nx = caluladora_simple(2, \"multiplicar\")\ny = x(3)\nprint(y)\n\nx = caluladora_simple(2, \"dividir\")\ny = x(3)\nprint(y)\n\n\n\ndef calculadora(n):\n    def sumar(x):\n        return x + n\n    def multiplicar(x):\n        return x * n\n    def restar(x):\n        return x - n\n\n    # Retorno un diccionario con varias funciones\n    return {\"sumar\": sumar, \"multiplicar\": multiplicar, \"restar\": restar}\n\nops = calculadora(10)\n\nprint(ops )        # 15\nprint(ops )  # 50\nprint(ops )       # -5\n\n\n\nx = 10  # variable global\n\ndef mostrar():\n    print(x)  # puede acceder a la global\n\nmostrar()      # 10\nprint(x)       # 10\n\n###\ndef funcion():\n    y = 5  # variable local\n    print(y)\n\nfuncion()   # 5\n# print(y)    # ❌ Error: NameError (no existe fuera de la función)\n\n\n\n# Crear una funcion que que reciba 2 para metros de texto y retorne los numeros del 1 al 100\ndef cadena_num(a, b):\n    x = 0\n    y = 0\n    for i in range (1, 101):\n        if i % 3 == 0:\n            x += 1\n            print(a)\n        elif i % 5 == 0:\n            x += 1\n            print(b)\n        else:\n            y += 1\n            print(i)\n    return print(f\"Numero de numeros impresos: {y}\\nNumero de Textos impresos: {x}\")\n\ncadena_num(\"tres\", \"cinco\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/AllanYSalazarG.py",
    "content": "\"\"\"#02 FUNCIONES Y ALCANCE\"\"\"\n\n\nsaludoVar = \"Hola global\"  # Variable global\n\n\ndef saludo():\n    print(\"Hola Mundo\")\n\n\ndef saludoUsuario(usuario):\n    saludoVar = \"Hola\"  # Variable local, no es igual a la variable saludo en la L4\n    # son variables diferentes almacenadas en distinto lugar de memoria\n    print(f\"{saludoVar} {usuario}\")\n\n\ndef saludoUsuarioValidado(usuario, validado):\n    if validado == 1:\n        print(f\"Hola {usuario}, haz sido validado\")\n        return validado\n    else:\n        print(f\"El usuario {usuario} no existe\")\n\n\nsaludo()\nsaludoUsuario(\"AllanYSalazarG\")\nconfirmado = saludoUsuarioValidado(\"allansalazar\", 0)\nprint(confirmado)\n\n\n# verificando si se puede agregar una función dentro de otra\n# al parecer no se puede, cuando intentas llamar a hola() fuera de la funcion saludoAdicional,\n# Las funciones trabajan igual que variables globales y locales\n# sale error de variable no definida siendo que es función\ndef saludoAdicional():\n    def hola():\n        print(\"Como estás, soy una funcion dentro de otra\\n\\n\")\n    hola()\n\n\nsaludoAdicional()\n# hola()\n\n\"\"\" El código de bloque anterior ⬆️ se lo agradezco a alexdevrep, miré su código y entendí\nel funcionamiento de una función dentro de otra, yo creía que no se podría porque \nla intentaba llamar fuera de saludoAdicional() (Comprendiendo más sobre el alcance en python)\"\"\"\n\n# Funciones de python\n\n\"\"\" # print, muestra en consola lo que esté dentro de los parentesis\nprint(\"Hola otra vez\")\n# range, el valor dentro indica cuando debe parar, devuelve una lista\nfor numero in range(10):\n    print(numero, end=\"-\")\n# input, espera que el usuario ingresa algun dato\nnumeroIngresado = input(\"\\nIngresa un numero: \")\n# int, transforma a enteros los valores ingresados por input\nnumeroIngresado = int(numeroIngresado)\nif numeroIngresado.is_integer:\n    print(\"Es entero\") \"\"\"\n\n\n# Ejercicio extra\n\nprint(\"EJERCICIO ADICIONAL: \\n\")\n\n\ndef palabra(primera, segunda):\n    contador = 0\n    for numero in range(1, 101):\n        if numero % 3 == 0 and numero % 5 == 0:\n            print(f\"{primera}, {segunda}\", end=\" | \")\n        elif numero % 5 == 0:\n            print(f\"{segunda}\", end=\" | \")\n        elif numero % 3 == 0:\n            print(f\"{primera}\", end=\" | \")\n        else:\n            print(numero, end=\" | \")\n            contador += 1\n    return contador\n\n\ncontadorFinal = palabra(\"Hola\", \"Mundo\")\nprint(f\"\\n\\nNúmeros impresos en lugar de textos: {contadorFinal}\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Alvaro-Neyra.py",
    "content": "# Funciones\n# Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n\n## Funcion sin parametros ni retorno\ndef funcion_normal():\n    print(\"Hola, esta es una funcion sin parametros ni retorno\")\n# Se llama la funcion para ejecutarla\nfuncion_normal()\n\n## Funcion con varios parametros sin retorno\ndef funcion_2_parametros(nombre, edad):\n    print(f\"Hola {nombre}, tu edad es: {edad}\")\n# Llamando la funcion\nfuncion_2_parametros(\"Alvaro\", 19)\n\n## Funcion con varios parametros con retorno\ndef funcion_con_parametros_con_retorno(examen, nota):\n    if examen and nota:\n        if nota >= 9 and not nota <= 9:\n            return print(f\"Muy bien! en {examen}\")\n        if nota <= 6 and nota >= 5:\n            return print(f\"Bien hecho! en {examen}\")\n        if nota <= 4 and nota > 1:\n            return print(f\"Puedes mejorar en {examen}\")\n        else:\n            return print(f\"A mejorar!\")\nnota = funcion_con_parametros_con_retorno(\"Matematicas\", 1)\nprint(nota)\n\n# Llama a una funcion con valor establecido por defecto\ndef saludar_a(nombre=\"Usuario\"):\n    return f\"Hola, {nombre}\"\n\nsaludar_a(\"Alvaro\")\nsaludar_a()\nsaludar_a(\"Rebecca\")\n\n# Una funcion con parametros opcionales y uno obligatorio\ndef retornar_valores(nombre, apellido=\"No especificado\", origen=\"No especificado\"):\n    if nombre:\n        print(f\"Tu nombre es: {nombre}\")\n    if apellido:\n        print(f\"Tu apellido es: {apellido}\")\n    if origen:\n        print(f\"Tu origen es: {origen}\")\n\nretornar_valores(\"Alvaro\") # Si no pones el valor del argumento obligatorio lanzara error ❌\n\n# Llama una funcion con sus argumentos en desorden\ndef cuenta_deudas(costo_de_la_deudamensual, meses_vencidos_a_pagar, meses_totales, meses_pagados):\n    meses_pagados += meses_vencidos_a_pagar\n    meses_restantes = meses_totales - meses_pagados\n    print(f\"Si el Costo de la deuda mensual es: {costo_de_la_deudamensual}\")\n    print(f\"Y si tu meses vencidos que faltan pagar son: {meses_vencidos_a_pagar}\")\n    print(f\"Entonces te falta pagar por ahora: {costo_de_la_deudamensual * meses_vencidos_a_pagar}\")\n    print(f\"Al estar al dia te faltan esta cantidad de meses a pagar: {meses_restantes}\")\n\ncuenta_deudas(meses_vencidos_a_pagar=2, meses_pagados=8, costo_de_la_deudamensual=200, meses_totales=18)\n\n## Funcion con parametros usando args:\ndef suma(*args):\n    resultado = 0\n    for arg in args:\n        resultado += arg\n    return resultado\n# Usando la funcion\nsuma_grande = suma(1,2,3,4,5)\nprint(suma_grande)\n\n# Crea funciones asincronas (necesitamos importar un objeto awaitable: asyncio.sleep())\nimport asyncio\n\nasync def corutina1():\n    # Imprimiendo en consola un aviso que ya empezo la funcion asincrona 1\n    print(\"Inicio de la funcion asincrona 1....\")\n    # Simulando la funcion asincrona\n    await asyncio.sleep(5)\n    # Cuando ya se haya ejecutado la corutina2 hasta el await, se continua con la ejecucion de la corutina1...\n    print(\"Fin de la funcion asincrona 1.\")\n\nasync def corutina2():\n    # Iniciando la funcion asincrona 2....\n    print(\"Inicio de la funcion asincrona 2....\")\n    # Simulando la funcion asincrona\n    await asyncio.sleep(5)\n    # Cuando ya se haya ejecutado por completo la corutina1 se continua con la ejecucion de esta funcion\n    print(\"Fin de la funcion asincrona 2.\")\n\nasync def ejecutar_funciones_asincronas():\n    # Haciendo un try para administrar excepciones\n    try:\n        # Empezando a ejecutar las funciones asincronas\n        print(\"Ejecutando funciones asincronas. Espere\", end='', flush=True)\n        # Mostrar puntos de espera\n        for _ in range(5):\n            await asyncio.sleep(0.5)\n            print(\".\", end='', flush=True)\n\n        print() # Nueva linea despues de los puntos\n\n        # Ejecutando la funcion asincrona 1\n        await corutina1()\n\n        # Aviso de espera para ejecutar la funcion asincrona 2\n        print(\"Esperando a la funcion asincrona 2\", end=\"\", flush=True)\n\n        # Mostrar puntos de espera\n        for _ in range(5):\n            await asyncio.sleep(0.5)\n            print(\".\", end=\"\", flush=True)\n\n        print() # Nueva linea despues de los puntos\n\n        # Ejecutando la funcion asincrona 2\n        await corutina2()\n    # Si el try retorna un error, ejecuta el except\n    except Exception as Error:\n        print(f\"Se produjo un error durante la ejecucion del programa: {Error}\")\n\nasyncio.run(ejecutar_funciones_asincronas())\n\n#* - Comprueba si puedes crear funciones dentro de funciones.\n\ndef funcion_externa(numero):\n    def funcion_interna(numero_al_doble):\n        return numero_al_doble * 2\n    numero_doblado = funcion_interna(numero)\n    return numero_doblado\n\nresultado_de_la_funcion_externa = funcion_externa(10)\nprint(resultado_de_la_funcion_externa)\n\n#* - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n# dir() --> Devuelve todos los metodos y atributos del objeto pasado\nobjeto_numerico = 20\npropiedades = dir(objeto_numerico)\nprint(propiedades)\n\n# print() --> Imprimir datos en consola\nprint(\"Hola, estoy usando la funcion integrada print()\")\n\n# len() --> Devuelve la cantidad de elementos de un objeto iterable\nobjeto_iterable = [True, \"Hola\", 10, 10.4, (\"Chau\", \"Mouse\"), \"Te amo Moure\"]\ncantidad_de_elementos = len(objeto_iterable)\nprint(cantidad_de_elementos)\n\n# list() --> Convierte el objeto pasado a una lista\ntupla_iterable = (True, False, 20, \"Te amo MoureDev y Comunidad!\")\ntupla_a_lista = list(tupla_iterable)\nprint(tupla_a_lista)\n\n#* - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n\"\"\"Ambito Local: Corresponde con el ambito de una funcion. No se puede acceder a las variables \n    de una función desde fuera de esa función o desde otra función.\"\"\"\n\"\"\"Ambito Global: Corresponde con el ámbito que existe desde el comienzo de la ejecución de un programa.\n    Todas las variables definidas fuera de cualquier función corresponden al ámbito global, que es accesible \n    desde cualquier punto del programa, incluidas las funciones.\"\"\"\n\nvariable_global = 20\ndef modificar_variable_global():\n    variable_global = 10\n\nprint(f\"La variable global es: {variable_global}\") # 20\nmodificar_variable_global()\nprint(f\"Luego de llamar a la funcion 'modificar_variable_global' el valor de la variable global es: {variable_global}\" ) # 20\n\n\"\"\"La variable Global no ha cambiado, ya que dentro del ambito de la funcion 'modificar_variable_global' no existe\nla variable: 'variable_global' porque donde se ha declarado la variable global es de distinto ambito que el ambito de la funcion creada.\nSi hubiesemos querido que 'variable_global' hubiese sido cambiada, deberiamos haberlo pasado como argumento. Otra cosa es que dentro\nde la funcion hemos creado una nueva variable que no la usamos para nada.\"\"\"\n\n\"\"\"Existe una manera para tener acceso de modificacion para las variable globales dentro de una funcion, usando el \nmodificador `global`. Con esto le estamos diciendo a Python que sabemos que vamos a utilizar una variable global\ny que queremos modificarla\"\"\"\n\nvariable_global_a_modificar_en_funcion = 100\ndef dividir_entre_cien():\n    global variable_global_a_modificar_en_funcion\n    variable_global_a_modificar_en_funcion = 100/10\n\nprint(f\"La variable global es: {variable_global_a_modificar_en_funcion}\")\ndividir_entre_cien()\nprint(f\"Variable global modificada: {variable_global_a_modificar_en_funcion}\")\n\n\"\"\"En el caso de las funciones anidadas, como ya hemos visto antes el ambito de la funcion externa es diferente a la de la funcion\ninterna y las variables declaradas desde la funcion interna solo se podran usar en su ambito. Pero si queremos modificar el valor\nde una variable local de una funcion externa dentro de una funcion interna tendriamos que usar el modificar `nonlocal`\"\"\"\n\n\"\"\"\n> `nonlocal` solo puede ser usado dentro de funciones anidadas\n\"\"\"\n\n\"\"\"En otras palabras la variable local actua como variable global para las funciones anidadas dentro de su mismo contexto\"\"\"\n\ndef funcion_externa2():\n    variable_local_de_la_funcion_externa = 30\n\n    def funcion_interna2():\n        nonlocal variable_local_de_la_funcion_externa # Consiguiendo la variable de la funcion externa usando `nonlocal`\n        variable_local_de_la_funcion_externa = 10\n        print(f\"Valor de la variable local de la funcion externa dentro de la funcion interna es: {variable_local_de_la_funcion_externa}\")\n\n    print(f\"El valor de la variable local de la funcion externa antes de ser cambiada es: {variable_local_de_la_funcion_externa}\")\n    funcion_interna2()\n    print(f\"Valor de la variable local despues de la ejecucion de la funcion interna: {variable_local_de_la_funcion_externa}\")\n\nfuncion_externa2()\n\n\"\"\"Espero que con esta explicacion de los modificadores `global` y `nonlocal` hayas entendido lo que son\"\"\"\n\n\n#* DIFICULTAD EXTRA (opcional):\n\ndef intercambiar_numeros(string1, string2):\n    # Creando contadores para cada contexto:\n    contador_de_valores_no_intercambiados = 0\n    contador_de_string1 = 0\n    contador_de_string2 = 0\n    contador_de_string1_y_string2 = 0\n    # Iterando numeros del 1 al 100\n    for i in range(1, 101):\n        # Si los numeros son multiplos de 3 y 5 intercambialos por la concatenacion de las dos cadenas de texto, imprimelos y aumenta el contador\n        if i % 3 == 0 and i % 5 == 0:\n            print(string1 + string2)\n            contador_de_string1_y_string2 += 1\n        # Si el numero es multiplo de 3 intercambialos por la primera cadena de texto, aumenta el contador e imprimelos\n        elif i % 3 == 0:\n            print(string1)\n            contador_de_string1 += 1\n        # Si el numero es multiplo de 5 intercambialos por la segunda cadena de texto, aumenta el contador e imprimelos\n        elif i % 5 == 0:\n            print(string2)\n            contador_de_string2 += 1\n        # Si el numero no es multiplo ni de 3 ni de 5 no intercambialos y aumenta el contador de los numeros no intercambiados\n        else:\n            contador_de_valores_no_intercambiados += 1\n\n    # Imprimendo en consola los datos:\n    print(f\"Numero de veces que los numeros han sido intercambiados por la primera cadena de texto: {contador_de_string1}\")\n    print(f\"Numero de veces que los numeros han sido intercambiados por la segundo cadena de texto: {contador_de_string2}\")\n    print(f\"Numero de veces que los numeros han sido intercambiados por la primera y segunda cadena de texto: {contador_de_string1_y_string2}\")\n    print(f\"Numero de veces que los numeros no han sido intercambiados: {contador_de_valores_no_intercambiados}\")\n        \nintercambiar_numeros(\"Hola\", \"Mundo\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/AndresMCardenas.py",
    "content": "\"\"\" * EJERCICIO:\n\n *  Crea ejemplos de funciones básicas que representen las diferentes\n *  posibilidades del lenguaje:\n *  Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n *  Comprueba si puedes crear funciones dentro de funciones.\n *  Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n *  Pon a prueba el concepto de variable LOCAL y GLOBAL.\n *  Debes hacer print por consola del resultado de todos los ejemplos.\n *  (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n\n\"\"\"\n\n# Funciones sin parámetros ni retorno\n\ndef saludo(): # Definición de la función \n    print(\"Hola, ¿Cómo estás?\")\n\nsaludo() # Llamada a la función para que se ejecute\n\n# Funciones con parámetros y retorno\n\ndef suma(numero1, numero2): # Definición de la función que recibe dos parámetros\n    return numero1 + numero2\n\nprint(f\"la suma de los parametros es {suma(5, 6)}\") # Llamada a la función con dos parámetros\n\n# Funciones con multiples parámetros y retorno\n\ndef suma_multiples_parametros(*args): # Definición de la función que recibe multiples parámetros\n    resultado = 0\n    for i in args:\n        resultado += i\n    return resultado\n\nprint(f\"la suma de los parametros es {suma_multiples_parametros(5, 6, 7, 8, 9)}\") # Llamada a la función con multiples parámetros\n\n# Funciones con funciones dentro\n\ndef funcion_dentro(saludo1): # Definición de la función que contiene otra función\n    def funcion_dentro_dentro(saludo2):  \n        print(f\"{saludo2} una funcion dentro de funcion\")\n    funcion_dentro_dentro(saludo1)\n\nfuncion_dentro(\"Esta es\")\n\n### Funciones ya creadas en el lenguaje ###\n\n# Función map\n\ndef cuadrado(numero): # Definición de la función que eleva al cuadrado un número\n    return numero * numero\n\nlista = [1, 2, 3, 4, 5]\nresultado = map(cuadrado, lista) # La función map devuelve un objeto map, por lo que se debe convertir a lista para poder visualizar el resultado\nprint(list(resultado)) \n\n# Función filter\n\ndef es_par(numero): # Definición de la función que devuelve True si el número es par\n    if numero % 2 == 0:\n        return True\n    else:\n        return False\n\nlista = [1, 2, 3, 4, 5]\nresultado = filter(es_par, lista) # La función filter devuelve un objeto filter, por lo que se debe convertir a lista para poder visualizar el resultado\nprint(list(resultado)) # imprime [2, 4] que son los números pares de la lista\n\n# Función reduce\n\nfrom functools import reduce # Se debe importar la función reduce\n\ndef suma(numero1, numero2): # Definición de la función que suma dos números\n    return numero1 + numero2\n\nlista = [1, 2, 3, 4, 5]\nresultado = reduce(suma, lista) # La función reduce devuelve un objeto reduce, por lo que se debe convertir a lista para poder visualizar el resultado\nprint(resultado) # imprime 15 que es la suma de todos los números de la lista\n\n# Variable global\nvariable_global = \"Soy una variable global\"\n\ndef mi_funcion():\n    # Variable local\n    variable_local = \"Soy una variable local\"\n    print(variable_local)\n    print(variable_global)\n\nmi_funcion()\n\nprint(variable_global) # Esto se puede hacer porque variable_global es una variable global\n# print(variable_local)  # Esto dará un error porque variable_local no es accesible fuera de la función\n\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n  Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n  La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n  Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n  Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n  Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n  La función retorna el número de veces que se ha impreso el número en lugar de los textos \n  Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n  Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n\"\"\"\n\nfrom num2words import num2words # Se debe instalar la librería num2words para poder utilizarla con el comando \"pip install num2words\"\n\nnumero = 123\npalabras = num2words(numero, lang='es') # Convierte el número a palabras en español\nprint(palabras)  # imprime \"ciento veintitrés\"\n\ndef extra():\n  contador = 0\n  for i in range(1,101):\n    if i % 3 == 0 and i % 5 == 0:\n      palabras = num2words(i, lang='es')\n      print(palabras)\n    elif i % 3 == 0:\n      palabras = num2words(i, lang='es')\n      print(palabras)\n    elif i % 5 == 0:\n      palabras = num2words(i, lang='es')\n      print(palabras)\n    else:\n      print(i)\n      contador += 1\n  return contador\n\nresultado = extra()\nprint(f\"Número de veces que se ha impreso el número en lugar de los textos: {resultado}\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Angell4S.py",
    "content": "\"\"\"\r\nFunciones definidas por el usuario\r\n\"\"\"\r\n\r\n# simple\r\n\r\ndef greet():\r\n   print(\"Hola, python!\")\r\n\r\ngreet()\r\n\r\n# con retorno (return)\r\ndef return_greet():\r\n   return \"Hola, python!\"\r\n\r\ngreet = return_greet()\r\nprint(greet)\r\n\r\n# con un argumento\r\ndef arg_greet(name):\r\n   print(f\"Hola, {name}!\")\r\n\r\narg_greet(\"Angel\")\r\n\r\n# con un argumentos\r\ndef args_greet(greet, name):\r\n   print(f\"{greet}, {name}!\")\r\n\r\nargs_greet(\"HI\",\"Angel\")\r\nargs_greet(name=\"Angel\", greet=\"HI\")\r\n\r\n# con un argumento predeterminado\r\ndef default_arg_greet(name=\"Python\"):\r\n   print(f\"Hola, {name}!\")\r\n\r\ndefault_arg_greet(\"Angel\")\r\ndefault_arg_greet()\r\n\r\n# con un argumentos y retorno\r\ndef return_args_greet(greet, name):\r\n   return f\"{greet}, {name}!\"\r\n\r\nprint(return_args_greet(\"HI\",\"Angel\"))\r\n\r\n# Con retorno de varios valores\r\ndef multiple_return_greet():\r\n   return \"Hola\", \"Python\"\r\n\r\ngreet, name = multiple_return_greet()\r\nprint(greet)\r\nprint(name)\r\n\r\n# Con un número variable con argumentos\r\ndef variable_arg_greet(*names):\r\n   for name in names:\r\n      print(f\"Hola, {name}!\")\r\n\r\nvariable_arg_greet(\"Python\", \"Angel\", \"Mouredev\", \"Comunidad\")\r\n\r\n# Con un número  variable de argumentos con palabras clave\r\ndef variable_key_arg_greet(**names):\r\n   for key, value in names.items():\r\n      print(f\"{value} ({key})!\")\r\n\r\nvariable_key_arg_greet(language=\"Python\", name=\"Angel\", alias=\"Mouredev\", age=36)\r\n\r\n\"\"\"\r\nFunciones dentro de funciones\r\n\"\"\"\r\ndef outer_funcion():\r\n   def inner_function():\r\n      print(\"Función interna: Hola python\")\r\n   inner_function()\r\n\r\nouter_funcion()\r\n\r\n\"\"\"\r\nFunciones del lenguaje (built-in)\r\n\"\"\"\r\nprint(len(\"Angell4S\"))\r\nprint(type(36))\r\nprint(\"angell4s\".upper())\r\n\r\n\"\"\"\r\nVariables locales y globales\r\n\"\"\"\r\nglobal_var = 'Python'\r\nprint(global_var)\r\n\r\ndef hello_python():\r\n   local_var = 'Hola'\r\n   print(f'{local_var}, {global_var}!')\r\n\r\nprint(global_var)\r\n# print(local_var) No se puede acceder desde fuera de la función\r\n\r\nhello_python()\r\n\r\n\"\"\"\r\nExtra\r\n\"\"\"\r\n\r\ndef print_numbers(text_1, text_2) -> int:\r\n   count = 0\r\n   for number in range(1, 101):\r\n      if number % 3 == 0 and number % 5 == 0:\r\n         print(text_1 + text_2)\r\n      elif number % 3 == 0:\r\n         print(text_1)\r\n      elif number % 5 == 0:\r\n         print(text_2)\r\n      else:\r\n         print(number)\r\n         count += 1\r\n   return count\r\n\r\nprint(print_numbers('Fizz', 'Buzz'))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Anvildestroyer.py",
    "content": "# funciones sin parametro ni retorno:\n\n\ndef saludo():\n    print(\"¡Hola, mundo!\")\n\n\nsaludo()\n\n# funciones con un parametro:\n\n\ndef cuadrado(n):\n    return n ** 2\n\n\nprint(cuadrado(5))\n\n# funciones con varios parametros:\n\n\ndef suma(a, b, c):\n    return a + b + c\n\n\nprint(suma(1, 2, 3))\n\n# funciones con retorno:\n\n\ndef multiplicar(x, y):\n    return x * y\n\n\nresultado = multiplicar(4, 5)\nprint(resultado)\n\n\n# funciones con funciones anidadas:\n\ndef funcion_externa(a, b):\n    def funcion_interna(c, d):\n        return c + d\n    resultado = funcion_interna(a, b)\n    return resultado\n\n\nprint(funcion_externa(5, 10))\n\n#### Ejemplos de funciones ya creadas en python (existen mas...!!) #####\n\n#len\ndef longitud_lista(lista):\n    return len(lista)\n\nmi_lista = [1, 2, 3, 4, 5]\n\nprint(longitud_lista(mi_lista))\n\n#abs(x) devuelve el valor absoluto \ndef funcion_abs(x):\n    return abs(x)\n\nmi_abs = -7\nprint(funcion_abs(mi_abs))\n\n#max(iterable) o max(arg1, arg2, *args) devuelve el mayor de dos o mas Args.\ndef funcion_iterable(x):\n    return max(x)\n\nmi_max = [1, 2, 3, 4, 5]\nprint(funcion_iterable(mi_max))\n\n\n#### Ejemplos de variables locales y variables globales #####\n\n#Variables locales\n\"\"\"\nEn Python, las variables se pueden clasificar en dos tipos principales: \nvariables locales y variables globales, dependiendo de su alcance.\n\nVariables Locales: Una variable definida dentro de una función se conoce como variable local. \nEl alcance de estas variables está limitado \na la función en la que se definen. \nNo se pueden acceder fuera de esa función. \nPor ejemplo:\n\"\"\"\n\ndef mi_vlocal():\n    variable_local = \"¡Hola, soy una variable local!\"\n    print(variable_local)\n\nmi_vlocal()\n\n#Variables Globales\n\"\"\"\nVariables Globales: Una variable que se define fuera de todas las funciones \nse conoce como variable global. \nEstas variables pueden ser accedidas desde cualquier parte del código, \ntanto dentro como fuera de las funciones \n(a menos que se sobrescriban en el ámbito local). \nPor ejemplo:\n\"\"\"\nvariable_global = \"¡Hola, soy una variable global!\"\n\ndef mi_vglobal():\n    print(variable_global)\n\nmi_vglobal()\n\n\n#funcion contador hecha por mi\n\ndef  funcion_contar1(texto1 , texto2):\n        for numero in range(101):\n            if numero % 3 == 0 and numero % 5 == 0:\n                print (texto1 + \" \" + texto2)\n            elif numero % 3 == 0: \n                print (texto1)\n            elif numero % 5 == 0:\n                print (texto2)\n            else:\n                print (numero)\n\n\nhola = \"Hola\"\nmundo = \"mundo!\"\n\nprint(funcion_contar1(hola, mundo))\n\n#funcion mejorada con chatgpt y creando funciones extras\ndef contador():\n    for numero in range(101):\n        yield numero\n\ndef es_multiplos5(contador):\n    for num5 in contador:\n        if(num5 % 5 == 0):\n            yield True, num5\n        else:\n            yield False, num5\n\ndef es_multiplos3(contador):\n    for num3 in contador:\n        if(num3 % 3 == 0):\n            yield True, num3\n        else:\n            yield False, num3\n\ndef funcion_contar2(texto1 , texto2):\n    contador_gen1 = contador()\n    contador_gen2 = contador()\n    for (resultado5, num5), (resultado3, num3) in zip(es_multiplos5(contador_gen1), es_multiplos3(contador_gen2)):\n        if resultado5 and resultado3:\n            print(f\"{texto1} {texto2} {num5} es múltiplo de 5 y 3\")\n        elif resultado3:\n            print(f\"{texto1} {num3} es múltiplo de 3\")\n        elif resultado5:\n            print(f\"{texto2} {num5} es múltiplo de 5\")\n        else:\n            print(num5)\n\nhola = \"Hola\"\nmundo = \"mundo!\"\n\nprint(funcion_contar2(hola, mundo))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Aquiles735.py",
    "content": "\n\n#  EJERCICIO:\n#  * - Crea ejemplos de funciones básicas que representen las diferentes\n#  *   posibilidades del lenguaje:\n#  *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n#  * - Comprueba si puedes crear funciones dentro de funciones.\n#  * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n#  * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n#  * - Debes hacer print por consola del resultado de todos los ejemplos.\n#  *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n#  * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n#  *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n#  *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n#  *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n#  *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n#  *\n#  * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n#  * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n\n\n\n# ejemplo de funciones \ndef saludar(nombre):\n    print(f\"¡Hola, bienvenido {nombre}!\")    #¡Hola, bienvenido juancho!\nsaludar(\"juancho\")\n\n\n#ejemplo de funcion con variable local (interna)\ndef calcfoza ():\n    calcfoza=calcfoza  \nc=100\nb=20  \nprint(c*b)  #2000\n\n\n\n #variable glogal (externa)\nnum_a=10    \ndef opera():\n    opera=opera\nprint(num_a*num_a)   #100\nprint(num_a/2*num_a) #50.0\n\n\n\n                        \n\n\n  \n# funcion dentro de otra funcion \ndef carros(m):\n    carros=carros\n    def cac(n):\n        cac=cac\nm=20\nn=50\nprint(m*n)  #1000\nprint(m*m/(m+n)*n)    #285.7142857142857\n\n\n    #imprime numeros del uno al 100\n\n     \nfor x in range(1, 101):\n            print(\"Imprime numeros:\", x)\n\n            if x== x in range(1, 99, 3):   #falta calibrar un poco mas\n                print(\"Igual a 3\")\n           \n            # else:\n            #     print(x)\n          \n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/ArtDugarte.py",
    "content": "import datetime\nvariable = str(\"Esta es la Variable global\")\n# --------------------------  TIPOS DE FUNCIONES EN PYTHON -------------------------- \n\ndef main():\n    \n    # Función sin retorno\n    def hola_mundo():\n        print(\"-------------------------------------------------------------------\")\n        print(\"FUNCION SIN RETORNO:\")\n        print(\"¡Hola Mundo!\")\n        print(\"-------------------------------------------------------------------\")\n    \n    hola_mundo()\n    \n\n    # Función con retorno\n    def fecha_actual():\n        \n        print(\"-------------------------------------------------------------------\")\n        print(\"FUNCION CON RETORNO:\")\n        return datetime.datetime.now()\n\n    print(\"La fecha actual es: \", fecha_actual())\n    print(\"-------------------------------------------------------------------\")\n\n    # Función con parametros\n    nombre = str(\"Arthuro\")\n    apellido = str(\"Dugarte\")\n\n    def saludo(nombre, apellido):\n        print(\"-------------------------------------------------------------------\")\n        print(\"FUNCION CON PARAMETROS:\")\n        print(f\"¡Hola {nombre} {apellido}!\")\n        print(\"-------------------------------------------------------------------\")\n\n    saludo(nombre, apellido)\n\n    # Función dentro de una función\n    def modificar_palabra(palabra):\n\n        print(\"-------------------------------------------------------------------\")\n        print(\"FUNCION DENTRO DE UNA FUNCION:\")\n\n        def palabra_invertida(palabra):\n            return palabra[::-1]\n        return palabra_invertida(palabra)\n\n    print(modificar_palabra(\"Hola\"))\n    print(\"-------------------------------------------------------------------\")\n\n    # Función ya creada en el lenguaje\n    def anio():\n        return datetime.datetime.now().year\n    \n    print(\"-------------------------------------------------------------------\")\n    print(\"FUNCION YA CREADA EN EL LENGUAGE:\")\n    print(anio())\n    print(\"-------------------------------------------------------------------\")\n\n    # Función con variables locales y globales\n    def variable_local():\n        variable = str(\"Esta es la Variable local\")\n        print(\"-------------------------------------------------------------------\")\n        print(\"VARIABLES:\")\n        print(variable)\n        print(globals()[\"variable\"])\n        print(\"-------------------------------------------------------------------\")\n    variable_local()\n\n    # Dificultad extra\n    print(\"-------------------------------------------------------------------\")\n    print(\"DIFICULTAD EXTRA:\")\n    def textos(text1, text2):\n        cont = 0\n        for i in range(1, 101):\n            if i % 3 == 0 and i % 5 == 0:\n                print(f\"{text1} {text2}\")\n                cont += 1\n            elif i % 3 == 0:\n                print(text1)\n                cont += 1\n            elif i % 5 == 0:\n                print(text2)\n                cont += 1\n            else:\n                print(i)\n        return (100 - cont)\n    \n    total = textos(\"Soy multiplo de 3.\", \"Soy multiplo de 5.\")\n    print(\"-------------------------------------------------------------------\")\n    print(\"El numero de palabras que no son multiplos de 3 o 5 es:\", total)\n    print(\"-------------------------------------------------------------------\")\n\n\nif __name__ == \"__main__\":\n    main()"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Bert008.py",
    "content": "'''\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n'''\nprint(\"Funciones en python\")\nprint(\"Funcion sin parametros ni retorno\\n\")\n\ndef funcion1():\n    print(\"Hola\")\ndef funcion2():\n    print(\"Inicio de funcion2\")\n    print(\"Llamamos a funcion1\")\n    funcion1()\n    def funcion3():\n        print(\"Inicio de funcion3 dentro de funcion2\") # intentamos hacer una funcion dentro de otra funcion\n    funcion3()\n    print(\"Fin de funcion2\\n\")\n\nfuncion2() # Con esto comprobamos que podemos definir una funcion dentro de otra funcion\n\nprint(\"Funcion con uno o mas parametros y retorno\")\ndef funcionParam(x, y, z):\n    return x + y + z\n\nresultado = funcionParam(1, 2, 3)\nprint(\"El resultado de la funcion al llamarlo es \", resultado, '\\n')\n\nprint(\"Bariables locales vs globales\")\nx = 10\n\ndef varGlobal():\n    global y\n    y = 5\nprint(\"x = \", x)\ntry:\n    z = x / y\n    print(z)\nexcept NameError:\n    print(\"La variable y es una variable local del bloque de la funcion varGlobal()\")\nfinally:\n    print(\"Hacemos que y sea una variable global\")\n    varGlobal()\n    print(\"y = \", y)\n    z = x/y\n    print(\"El resultado de x / y es \", z)\n'''\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n'''\nprint(\"\\nPrueba Extra\")\ndef extra(string1, string2):\n    count = 0\n    for i in range(1, 101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(string1, string2)    \n        elif i % 5 == 0:\n            print(string2)\n        elif i % 3 == 0:\n            print(string1)\n        else:\n            print(i)\n            count += 1\n    print(\"Numero de veces que se imprimio un numero: \", count)\nextra(\"Hola\", \"Mundo\")\n        "
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Bertolini-Victor.py",
    "content": "\"\"\"  \n/*\n    EJERCICIO:\n        1) Crea ejemplos de funciones básicas que representen las diferentes posibilidades del lenguaje:\n            Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n        2) Comprueba si puedes crear funciones dentro de funciones.\n            Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n            Pon a prueba el concepto de variable LOCAL y GLOBAL.\n            Debes hacer print por consola del resultado de todos los ejemplos.\n            (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n\n    DIFICULTAD EXTRA (opcional):\n        3) Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n            - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n            - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n            - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n            - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n            - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\n    Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n    Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n*/\n\"\"\"\n\n# 1) \n    # 1. Función simple: Función sin parámetros ni retorno. / Simple Function: Without parameters and return.\n\ndef hello_world():\n    print(\"Hello World!\")\n\nhello_world()\n\n    # 2. Función con retorno: Función sin parámetros pero con retorno. / Function with return: Function without parameters but with return.\ndef hello_world_with_return():\n    return (\"Hello World!\")\n\nprint(hello_world_with_return())\n\n    # 3. Función con un argumento: Función con un parámetro pero sin retorno. / Function with parameters: Function with parameters but without return.\ndef hello_world_with_param(name):\n    print(\"Hello, \" + name + \"!\")\n\nhello_world_with_param(\"Victor\")\n\n    # 4. Función con argumentos: Función con múltiples parámetros pero sin retorno.\ndef hello_world_with_params(name, surname):\n    print(\"Hello, \" + name + \" \" + surname + \"!\")\n\nhello_world_with_params(\"Victor\", \"Bertolini\")\n\n    # 5. Función con un argumento predeterminado: Función con un parámetro con valor predeterminado.\n    # Function with a assigned parameter: Function with a parameter with a default value.\ndef hello_world_with_param_predefined(name = \"Victor\", surname = \"Bertolini\"):\n    print(\"Hello, \" + name + \" \" + surname + \"!\")\n\nhello_world_with_param_predefined()\n\n    # 6. Función con argumentos y retorno: Función con uno o más parámetros y con retorno.\n    # Function with parameter and return: Function with both parameter and return.\ndef hello_world_with_both(name):\n    return(\"Hello, \" + name + \" \")\n\nprint(hello_world_with_both(\"Victor\"))\n\n    # 7. Función con retorno de varios valores: Función que devuelve múltiples valores.\ndef ret_many_values():\n    return 1, 2, 3, 4\n\nprint(ret_many_values())\n\n    # 8. Función con un número variable de argumentos: Función que puede tomar un número variable de argumentos.\n    # Fuction with a variable number of arguments: Function that could take a variable number of arguments.\ndef many_variables(*languages):\n    for language in languages:\n        print(f\"Hello, , {language}!\")\n\nmany_variables(\"Pythom\", \"Java\", \"Ruby\", \"PHP\", \"JavaScript\", \"C#\")\n\n    # 9. Función con un número variable de argumentos con palabra clave: Función que puede tomar un número variable de argumentos de palabras clave.\n    # Function with a variable number of keyword arguments: Function that can take a variable number of keyword arguments.\ndef many_variables_with_keywords(**pokemons):\n    for key, value in pokemons.items():\n        print(f\"{value} is the {key}!\")\n\n\nmany_variables_with_keywords(\n    name =\"Pikachu\",\n    type =\"Electric\",\n    trainer =\"Ash\",\n    level = 100\n)\n\n# 2) \n    # Fucntiones anidadas / Nested functions.\n        # Si es posible crear funciones dentro de otras.\n        # Yes, It's possible to create functions inside other functions.\ndef outside_func():\n    def inside_func():\n        print(\"I'm an inside function.\")\n    inside_func()\n\noutside_func()\n\n    # Funciones del lenguaje / In-Build functions.\n\"\"\" \n    Existen muchas funciones por defecto de Python, aca se mostraran algunas no mas. \n    Para mas informacion: https://docs.python.org/es/3.9/library/functions.html#len\n    --------------------------------------------------------------------------------\n    There are many different in-build functions in Python, here only a few will be used.\n    For more information: https://docs.python.org/es/3.9/library/functions.html#len\n\"\"\"\n\nprint(len(\"Hello, world!\")) #It should print the number 13 / Deberia imprimir el numero 13.\nprint(str(10 + 15)) #It should print the number 25 / Deberia imprimir el numero 25.\n\nnumeros = [1, 2, 3, 4, 5] # Sumar los elementos de una lista / Sum the elements of a list.\nsuma = sum(numeros)\nprint(suma)  # Imprime: 15 / Print: 15.\n\nnumeros = [1, 2, 3, 4, 5] # Sumar los elementos de una lista con un valor inicial. Sum the elements in the list with a beginning value.\nsuma = sum(numeros, 30)\nprint(suma)  # Imprime: 45 / Print: 45.\n\n\n    # Variables globales y locales. / Local and global variables.\n\"\"\" \n    Las variables globales son las que se crean simplemente al crear una fuera de cualquier tipo de \n    estructura de control o similar del lenguage, y se pueden acceder desde cualquier parte del codigo. \n    Mientras que las locales son las que se crean cuando usas variables dentro de funcion, o similar, \n    pero que no se pueden \"ver\" desde otra parte del codigo que no sea dentro de donde fue declara.\n    ---------------------------------------------------------------------------------------------------\n    The global variables are the ones that are used when you simply declare a variable in any part of the\n    code that is not a function or a structure of contron of Python, and they can be used from any part of\n    the code. Meanwhile, local variables are the ones that are declare inside of functions, and similar, \n    and can be used only inside the function from which they were declared.\n\"\"\"\n\nthis_is_a_global_variable = 14\n\ndef func():\n    this_is_a_local_variable = True\n    if (this_is_a_local_variable):\n        print(this_is_a_global_variable)\n\nfunc()\n\n# 3) EXTRA\n\"\"\" \n    Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n        - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n        - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n        - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n        - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n        - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\"\"\"\ndef print_numbers(string1, string2) -> int:\n    count = 0\n    for i in range(1, 101):\n        if i % 3 == 0:\n            print(string1)\n        elif i % 5 == 0:\n            print(string2)\n        elif i % 5 == 0 and i % 3 == 0:\n            print(string1 + \" \" + string2)\n        else:\n            print(i)\n            count += 1\n    return count\n\nprint(\"\")\nprint(\"\")\nprint(\"\")\n\nnumeros_impresos = print_numbers(\"Fizz\", \"Buzz\")\nprint(\"Se imprimieron\", numeros_impresos, \"numeros.\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/BrianSilvero.py",
    "content": "\"\"\"\nFunciones definidas por el usuario\n\"\"\"\n\n# Simple\ndef greet():\n    print(\"Hola, Python!\")\n\ngreet()\n\n# Con retorno\ndef return_greet():\n    return  \"Hola, Python!\"\n\nprint(return_greet())\n\n# Con un argumento\n\ndef arg_greet(name):\n    print (f\"Hola, {name}!\")\n\narg_greet(\"Brian\")\n\n# Con argumentos\n\ndef args_greet(greet, name):\n    print (f\"{greet}, {name}!\")\n    \nargs_greet(\"Hello\", \"Brian\")\nargs_greet(name=\"Brian\",greet=\"Hello\")\n\n# Con argumentos predeterminado\n\ndef default_arg_greet(name=\"Python\"):\n    print (f\"Hola, {name}!!\")\n    \ndefault_arg_greet(\"Brian\")\ndefault_arg_greet()\n\n# Con argumentos y retornos\n\ndef return_args_greet(greet, name):\n    return f\"{greet},{name}!\"\n\nprint(return_args_greet(\"Hola\", \"David\"))\n\n# Con retorno de varios valores\n\ndef multiple_return_greet():\n    return \"Hola\", \"Python\"\n\ngreet, name = multiple_return_greet()\nprint (greet)\nprint(name)\n\n# Con un numero variable de argumento\ndef variable_args_greet (*names):\n    for name in names:\n        print(f\"Hola,{name}!!\")\n        \nvariable_args_greet(\"Youtube\", \"Brian\", \"Silvero\")\n\n# Con un numero variable de argumento con palabra clave\n\ndef variable_key_args_greet (**names):\n    for key,value in names.items():\n        print(f\"{value} ({key})\")\n        \nvariable_key_args_greet(\n    language= \"Python\",\n    nombre= \"Brian\",\n    edad= \"27\")\n\n\n\n\"\"\"\nFunciones dentro de funciones\n\"\"\"\n\ndef outer_function():\n    def inner_function():\n        print(\"Funcion interna: Hola Python!\")\n    inner_function()\n\nouter_function()\n\n\"\"\"\nFunciones del lenguaje (Built-in)\n\"\"\"\n\nprint(len(\"Brian\"))\nprint(type(27))\nprint(\"Brian\".upper())\n\n\n\"\"\"\nVariables locales y globales\n\"\"\"\nglobal_var = \"Python\"\n\ndef hello_python():\n    local_var = \"Hola\"\n    print(f\"{local_var},{global_var}!\")\n    \nprint(global_var)\n# print(local_var) No se puede acceder desde fuera de la funcion\n\nhello_python()\n\n\"\"\"\nExtra\n\"\"\"\n\ndef print_number(text_1, text_2)-> int:\n    count = 0\n    for number in range(1,101):\n        if number % 3 == 0 and number % 5 == 0:\n            print(text_1 + text_2)\n        elif number % 3 == 0:\n            print(text_1)\n        elif number % 5 == 0:\n            print(text_2)\n        else:\n            print(number)\n            count += 1\n    return count\n\nprint(print_number(\"Texto 1 \", \"Texto 2\"))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Bryan112094.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n */\n\"\"\"\n#Función sin parametro ni retorno\ndef hola():\n    print(\"Hola soy Bryan\")\n\n#Función con parametro pero sin retorno\ndef mi_edad(edad: int):\n    print(f\"Soy Bryan y tengo {edad} años\")\n\n#Funcion con parametro con retorno\ndef sumar(*num):\n    return sum(num)\n\n#Comprobar si una funcion puede estar dentro de otra funcion\ndef fun_principal(numero):\n    def fun_secundaria(doble_numero):\n        return doble_numero * 2\n\n    numero_doble = fun_secundaria(numero)\n    return numero_doble\n\n#Funciones ya creadas\nlista = [1, 4, 5, 9, 3]\n#->cantidad de elementos\ncant = len(lista)\n#->elemento mayor\nmayor = max(lista)\n#->Agregar elemento\nlista.append(34)\n\n#Variables locales -> solo dan dentro de la funcion mas no fuera de ella\nsaludar = \"hello\"\ndef cambiar_saludar():\n    saludar = \"hola\"\n\n#Variables globales -> para que reconozca la variable se tiene que anteponer la palabra \"global\"\nnombre = \"Cristhian\"\ndef segundo_nombre():\n    global nombre\n    nombre = \"Bryan\"\n\nprint(\"IMPRIMIR FUNCIONES DECLARADAS\\n\")\n\nprint(\"Función sin variable ni retorno: hola()\")\nhola()\nprint(\"\\nFunción con variable ni retorno: mi_edad(29)\")\nmi_edad(29)\nprint(\"\\nFunción con variable y con retorno: sumar(20, 30)\")\nrpta = sumar(20, 30)\nprint(rpta)\n\nprint(\"\\nVerificar si se puede poner una funcion dentro de otra: fun_principal(80)\")\nverificar = fun_principal(80)\nprint(verificar)\n\nprint(\"\\nImprimir funciones ya creadas de la lista [1, 4, 5, 9, 3]\")\nprint(f\"Cantidad de elementos: {cant}\")\nprint(f\"Elemento mayor de la lista: {mayor}\")\nprint(f\"Lista con un elemento nuevo: {lista}\")\n\nprint(\"\\nVariable local: la variable dentro la función no cambiara el valor de la variable fuera de ella asi tenga el mismo nombre\")\nprint(f\"Antes de la función: {saludar}\")\ncambiar_saludar()\nprint(f\"Después de la función: {saludar}\")\n\nprint(\"\\nVariable Global: la variable dentro la función cambiara el valor de la variable fuera de ella si se le antepone la palabra global\")\nprint(f\"Antes de la función: {nombre}\")\nsegundo_nombre()\nprint(f\"Después de la función: {nombre}\")\n\n\"\"\"\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n */\n\"\"\"\n\nprint(\"\\n\\nDIFICULTAD EXTRA\\n\")\n\ndef exer_extra(texto01: str, texto02: str):\n    cantidad_num = 0\n    for i in range(1, 101):\n        if i % 5 == 0 and i % 3 == 0:\n            print(texto01 + texto02)\n        elif i % 5 == 0:\n            print(texto02)\n        elif i % 3 == 0:\n            print(texto01)\n        else:\n            cantidad_num += 1\n            print(i)\n    return cantidad_num\n\nfinal_func = exer_extra(\"hola \", \"mundo\")\nprint(f\"Cantidad de números impresos: {final_func}\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/C-Gabs.py",
    "content": "#Reto 03\n\n'''EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.'''\n\n\n#Función sin parametros ni retorno\n\ndef sin_par():\n    print(\"Hola mundo\")\n    num = 12 + 5\n\nsin_par()\nprint(sin_par())\n\n#Función sin parametros y con retorno\n\ndef sin_par_con_retorno():\n    print(\"Hola mundo\")\n    num = 12 + 5\n    return num\n\nsin_par_con_retorno()\nretorno = sin_par_con_retorno()\nprint(sin_par_con_retorno())\nprint(f\"Retorno\", retorno)\n\n#Con un parametro sin retorno\n\ndef con_un_par(parametro):\n    print(f\"hola\", parametro)\n\ncon_un_par(\"Python\")\nprint(con_un_par(\"Pypy\"))\n\n#Con un parametro con retorno\n\ndef con_un_par_con_retorno(parametro):\n    print(f\"Hola\", parametro)\n    return \"hola mundo y hola \" + parametro\n\ncon_un_par_con_retorno(\"Python\")\nretorno = con_un_par_con_retorno(\"Pypy\")\nprint(retorno)\n\n#Con varios parametros sin retorno\n\ndef con_varios_par(par_1,par_2,par_3 = \"Parametro por defecto\"):\n    print(f\"{par_1} {par_2}, {par_1} {par_3}\")\n\ncon_varios_par(\"Hola\",\"mundo\")\ncon_varios_par(\"Hola\",\"mundo\",\"Python\")\nprint(con_varios_par(\"Hola\",\"mundo\",\"Pypy\"))\n\n#Con varios parametros con retorno\n\ndef con_varios_par_con_retorno(par_1,par_2,par_3 = \", hola Parametro por defecto\"):\n    return par_1 + par_2 + par_3\n\nretorno = con_varios_par_con_retorno(\"Hola \", \"Mundo\")\nprint(retorno)\n\nretorno = con_varios_par_con_retorno(\"Hola \", \"Mundo\", \", Hola Brais\")\nprint(retorno)\n\n#Función con multiples parametros\n\n'''Esto lo añadí luego de ver la solución\ny notar que me faltó esta posibilidad de python'''\n\ndef multiples_parametros(*parametros):\n    for parametro in parametros:\n        print(parametro)\n\nmultiples_parametros(\"Python\", \"SQL\", \"Pandas\", \"Numpy\")\n\ndef multiples_parametros_palabra_clave(**parametros):\n    for valor,llave in parametros.items():\n        print(f\"{valor}: {llave}\")\n\nmultiples_parametros_palabra_clave(nombre=\"Brais\", apellido=\"Moure\")\n\n#Funciones dentro de funciones\n\ndef funcion_externa():\n    def numeros():\n        for n in range(0,11):\n            print(n)\n        return \"Fin de la secuencia\"\n    print(numeros())\n\nfuncion_externa()\n\n#Funciones integradas de python\n\n#Función len()\n\nprint(len(\"Hola mundo\"))\n\n#Función enumerate()\nresultado = list(enumerate([\"Python\", \"C++\", \"C#\", \"Kotlin\", \"Swift\", \"Java\"]))\nprint(resultado)\n\n#Variable local y global\n\nGlobal = \"Soy una variable global\"\ndef ejemplo():\n    local = \"soy una variable local\"\n    print(f\"{Global} dentro de la función\")\n    print(f\"{local} dentro de la función\")\n\nejemplo()\n'''Las variables locales solo existen dentro del contexto\ndonde son creadas'''\n#Descomentar para probar\n#print(f\"{local} fuera de la función\")\n\n\n#Reto extra\n\nprint(\"Reto extra\\n\")\n\ndef reto(parametro_1 = \"string por defecto 1\", parametro_2 = \"string por defecto 2\"):\n    contador = 0\n    for num in range(1,101):\n        if num % 3 == 0 and num % 5 == 0:\n            print(f\"{parametro_1} {parametro_2}\")\n        elif num % 3 == 0:\n            print(parametro_1)\n        elif num % 5 == 0:\n            print(parametro_2)\n        else: \n            print(num)\n            contador += 1\n    return contador\n\nprint(reto(\"Brais\", \"Moure\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/CRaphaelAM.py",
    "content": "\"\"\"\nEJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n\"\"\"\n\ndef funcion_a()->None:\n    print(\"Funcion sin parámetros ni retorno\")\n\ndef funcion_b(a,b)->None:\n    print(\"Funcion con dos parámetros y sin retorno\")\n\ndef funcion_c(a,b):\n    print(\"Funcion con dos parametrs y retorno\")\n    return a+b\n\ndef funcion_d():\n    print(\"Dentro de d\")\n    def funcion_e():\n        print(\"Hola dentro de e\")\n    funcion_e()\n\ndef funcion_f():\n    x = 6 #no afecta a la x del entorno global\n    print(x)\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n\"\"\"\ndef divisible3(num:int)->bool:\n    return num%3 == 0\n\ndef divisible5(num:int)->bool:\n    return num%5 == 0\n\ndef funcion_extra(cadena1:str,cadena2:str)->int:\n    contador = 0\n\n    for n in range(1,101):\n        if divisible3(n) and not divisible5(n):\n            print(cadena1)\n        elif not divisible3(n) and divisible5(n):\n            print(cadena2)\n        elif divisible3(n) and divisible5(n):\n            print(f\"{cadena1} {cadena2}\")\n        else:\n            print(n)\n            contador +=1\n    return contador\n\n\nfuncion_d()\nx = 5#variable global\nprint(x)\n\n\ncadena1 = input(\"Ingrese la primera cadena: \")\ncadena2 = input(\"Ingrese la segunda cadena: \")\n\n\nrepeticiones = funcion_extra(cadena1,cadena2)\n\nprint(f\"Se han impreso {repeticiones} números.\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Carl6289.py",
    "content": "# Función sin parámetros ni retorno\ndef mensaje():\n    print(\"Esto es una función sin parámetros ni retorno\")\nmensaje() # Llamada de la función\nprint()\n\n# Función con uno o varios parámetros\nprint(\"Función con uno o varios parámetros:\")\ndef camisetas(color, cantidad):\n    mensaje_camisetas = f\"De las camisetas color {color}, quedan disponibles un total de {cantidad} camisetas\"\n    print(mensaje_camisetas)\ncamisetas(\"negro\", 13) # Llamada de la función\nprint()\n\n# Función con retorno\nprint(\"Función con retorno:\")\ndef sumar_numeros(num1, num2):\n    suma = num1 + num2\n    return suma \nresultado = sumar_numeros(72, 33) # Llamada de la función\nprint(f\"El resultado de la suma es: {resultado}\")\nprint()\n\n# Funciones dentro de funciones\nprint(\"Funciones dentro de funciones:\")\ndef funcion_externa(nombre):\n    saludo = \"¡Hola,\"\n    def funcion_interna():        \n        saludo_completo = f\"{saludo} {nombre}!\"\n        print(saludo_completo)\n    funcion_interna()\nfuncion_externa(\"Carlos\")\nprint()\n\n# Funciones ya creadas en el lenguaje\nprint(\"Funciones ya creadas en el lenguaje:\")\nprint(\"Ejemplo con la funcion len()\")\ncadena = \"Hola Python\"\nprint(f\"La variable cadena tiene una longitud de: {len(cadena)}\")\nlista = [10, 20, 30]\nprint(f\"La variable lista tiene una longitud de: {len(lista)}\")\nprint()\n\n# Ejemplo con la funcion type()\nprint(\"Ejemplo con la funcion type()\")\nnumero = 14\nanimales = [\"Jirafa\", \"Hipopotamo\", \"Raton\"]\nprint(f\"La variable numero es del tipo: {type(numero)}\")\nprint(f\"La variable animales es del tipo: {type(animales)}\")\nprint()\n\n# Ejemplo con la funcion input()\nprint(\"Ejemplo con la funcion input()\")\n# edad = input(\"Escribe tu edad: \") <--- Comentado para que no interfiera con el resto de la ejecución del ejercicio\nprint()\n\n# Ejemplo con la funcion int()\nprint(\"Ejemplo con la funcion int()\")\nminutos = 103.6\nprint(f\"Han transcurrido {int(minutos)} minutos\")\nprint()\n\n# Ejemplo con la funcion str()\nprint(\"Ejemplo con la funcion str()\")\ntiene_hijos = True\nprint(f\"Tiene hijos: {str(tiene_hijos)}\")\nprint()\n\n# Ejemplo con la funcion float()\nprint(\"Ejemplo con la funcion float()\")\nlitros = 6\nprint(f\"Litros: {float(litros)}\")\nprint()\n\n# Ejemplo con la funcion abs()\nprint(\"Ejemplo con la funcion abs()\")\nnum_negativo = -8\nprint(f\"El número negativo ahora es: {abs(num_negativo)}\")\nprint()\n\n# Ejemplo con la funcion sum()\nprint(\"Ejemplo con la funcion sum()\")\nlista_numeros = [23, 19, 58, 36, 14]\nprint(f\"La suma de los números en la lista es: {sum(lista_numeros)}\")\nprint()\n\n# Ejemplo con la funciones max() y min()\nprint(\"Ejemplo con la funciones max() y min()\")\nprint(f\"El número mas grande de la lista es: {max(lista_numeros)}\")\nprint(f\"El número mas pequeño de la lista es: {min(lista_numeros)}\")\nprint()\n\n# Variable LOCAL y GLOBAL en una función\nprint(\"Variable LOCAL y GLOBAL en una función:\")\ncolor = \"Azul\" # Variable global\ndef mostrar_color():\n    color = \"Rojo\" # Variable local\n    print(f\"La variable local es: {color}\")\nmostrar_color()\nprint(f\"La variable global es: {color}\")\nprint()\n\n# Dificultad extra\nprint(\"DIFICULTAD EXTRA:\")\ntexto_1 = \"múltiplo de tres\"\ntexto_2 = \"múltiplo de cinco\"\ndef numeros_1_100(texto_1, texto_2):\n    contador = 0    \n    for i in range(1, 101):\n        if i % 3 == 0 and i % 5 == 0: \n            print(f\"{texto_1} y {texto_2}\")\n        elif i % 3 == 0:\n            print(f\"{texto_1}\")\n        elif i % 5 == 0:\n            print(f\"{texto_2}\")\n        else:\n            print(i)\n            contador += 1\n    return contador\nveces_numero = numeros_1_100(texto_1, texto_2)\nprint(f\"El número se imprimió {veces_numero} veces\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/CaveroBrandon.py",
    "content": "import time\n\n\"\"\"\n* EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n\"\"\"\n\n\n# **** Function without parameters or return ****\ndef small_triangle():\n    global global_counter\n    global_counter = global_counter - 1\n    print('**** Function without parameters or return ****')\n    print('  x  ')\n    print(' xxx  ' + '\\n')\n\n\n# **** Function with one parameter no return ****\ndef draw_money(qty):\n    global global_counter\n    global_counter = global_counter - 1\n    print('**** Function with one parameter no return ****')\n    print('$' * qty + '\\n')\n\n\n# **** Function without parameter and with a return ****\ndef get_current_year() -> str:\n    global global_counter\n    global_counter = global_counter - 1\n    print('**** Function without parameter and with a return ****')\n    return time.asctime()[-4:]\n\n\n# **** Function with one parameter and one return ****\ndef is_even(num) -> bool:\n    global global_counter\n    global_counter = global_counter - 1\n    print('**** Function with one parameter and return ****')\n    if num % 2 == 0:\n        return True\n    else:\n        return False\n\n\n# **** Function with multiple parameters, multiple returns and using functions within the function ****\ndef register_user(name='N/A', lastname='N/A', age=0) -> tuple:\n    def is_older(age):\n        if age >= 18:\n            return True\n        else:\n            return False\n\n    def get_id(name, lastname, age):\n        result = name[0:3] + lastname[0:3] + str(age)\n        return result\n\n    global global_counter\n    global_counter = global_counter - 1\n    print('**** Function with multiple parameters, multiple returns and using functions within the function ****')\n    if name != 'N/A':\n        name = name.upper()\n    if lastname != 'N/A':\n        lastname = lastname.upper()\n    full_name = name + ' ' + lastname\n\n    return get_id(name, lastname, age), is_older(age), full_name\n\n\n# **** Recursive function ****\ndef factorial(n):\n    if n == 0 or n == 1:\n        return 1\n    else:\n        return n * factorial(n-1)\n\n\n\"\"\"\n# DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\"\"\"\n\n\ndef extra_difficulty(for_three='Tic', for_five='Toc') -> int:\n    local_counter = 0\n    for i in range(1, 101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(for_three + for_five, end=',')\n        elif i % 3 == 0:\n            print(for_three, end=',')\n        elif i % 5 == 0:\n            print(for_five, end=',')\n        else:\n            print(i, end=',')\n            local_counter = local_counter + 1\n    return local_counter\n\n\nglobal_counter = 10\nprint('The global counter started with a value of: ' + str(global_counter))\n\n# **** Build in function ****\nprint('**** Build in function ****')\nprint(\"'print' is a build in function in Python\" + '\\n')\n\nsmall_triangle()  # Function without parameters or return\n\ndraw_money(15)  # Function with one parameter no return\n\nprint(get_current_year() + '\\n')  # Function without parameter and with a return\n\nprint(str(is_even(15)) + '\\n')  # Function with one parameter and one return\n\n(user_id, is_user_older, full_name) = register_user(name='Brandon', lastname='Cavero', age=15)  # Function with multiple parameters, multiple returns and using functions within the function\nprint('ID: ' + user_id)\nprint('Is member older: ' + str(is_user_older))\nprint('Full Name: ' + full_name + '\\n')\n\nprint('**** Recursive function ****')\nprint('The result of the factorial of 5 is: ' + str(factorial(5)) + '\\n')  # Recursive function\n\nprint('**** lambda function ****')\nreduce_global = lambda x: global_counter - x  # lambda function\nglobal_counter = reduce_global(1)\n\nprint('The global counter finishing with a value of: ' + str(global_counter) + '\\n')  # Global variable test\n\nprint('****  Extra difficult ****')\nextra = extra_difficulty(for_three='Zip', for_five='Zap')  # Extra difficult\nprint('\\nThe number of times a number is printed instead of text: ' + str(extra))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/CesarCarmona30.py",
    "content": "'''\n  FUNCIONES\n'''\n\n# Función sin parámetros ni retorno\ndef greet():\n  print('Hi!')\n\ngreet()\n\n# Función con parámetros sin retorno\ndef greetPerson(name):\n  print(f'¡Hello {name}!')\n\ngreetPerson('César')\n\n# Función con varios parámetros sin retorno\ndef add(number1, number2):\n  print(f'{number1} + {number2} = {number1 + number2}')\n\nadd(5, 8)\n\n# Función con varios parámetros con retorno\ndef subtract(number1, number2):\n  return number1 - number2\n\nresult = subtract(175, 123)\nprint(f'175 - 123 = {result}')\n\n# Función con parámetros variables\ndef average(*args):\n  sum = 0\n  for arg in args:\n    sum += arg\n  return sum/len(args)\n\nresult = average(9, 8, 7, 9, 9, 8, 10, 10)\nprint(result)\n\n# Función con parámetros variables con identificador\ndef capitals(**kwargs):\n  for country, city in kwargs.items():\n    print(f\"{country} - {city}\")\n  return\n\ncountries = {\n  'Mexico': 'Mexico City',\n  'Argentina': 'Buenos Aires',\n  'Spain': 'Madrid',\n  'Chile': 'Santiago'\n  }\n\ncapitals(**countries)  \n\n# Funciones anónimas o lambda\nexponentiate = lambda number, exponent: number ** exponent\nresult = exponentiate(2, 8)\n\nprint(f'2 ** 8 = {result}')\n\n# Funciones dentro de funciones\ndef exterior_function(x):\n    def interior_function(y):\n        return y * 2\n    \n    result = x + interior_function(x)\n    return result\n\noperation = exterior_function(5)\nprint(operation)\n\n# Funciones nativas\nmy_list = [5, 6, 7, 3, 6, 7, 9, 3, 5, 8]\nprint(f'Esta es la función nativa: print()\\nMi lista: {my_list}')\nprint(f'Tipo de dato: {type(my_list)}')\nprint(f'Longitud de mi lista: {len(my_list)}')\nprint(f'Máximo de mi lista: {max(my_list)}')\nprint(f'Mínimo de mi lista: {min(my_list)}')\nprint(f'Suma de mi lista: {sum(my_list)}')\ninput('Esta es la función input, \\n para continuar escribe un número: ')\n\n'''\n  VARIABLE LOCAL Y GLOBAL\n'''\nglobal global_var\n\nglobal_var = \"Soy global\"\n\ndef myFunction():\n    local_var = \"Soy local\"\n    print(f'Accediendo a la variable global dentro de la función: {global_var}')\n    print(f'Accediendo a la variable local dentro de la función: {local_var}')\n\nmyFunction()\n\nprint(f'Accediendo a la variable global fuera de la función: {global_var}')\ntry:\n  print(f'Accediendo a la variable loca fuera de la función: {local_var}')\nexcept NameError as err:\n  print(f'Error: {type(err).__name__}')\n  print(f'No se puede acceder a la variable local desde afuera de su bloque')\n\n'''\n  EXTRA\n'''\n\ndef printNumbers(text1, text2):\n  printed_numbers = 0\n  for number in range(1, 101):\n    if number % 3 == 0 and number % 5 == 0:\n      print(f\"{text1} y {text2}\")\n    elif number % 3 == 0:\n      print(text1)\n    elif number % 5 == 0:\n      print(text2)\n    else:\n      print(f\"{number}\")\n      printed_numbers += 1\n  return printed_numbers  \n\nprints = printNumbers(text2 = 'Múltiplo de 5', text1 = 'Múltiplo de 3')\nprint(prints)"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Chrisdev00.py",
    "content": "\"\"\"\n* - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n\"\"\"\n\n# Declaring and Calling a Function\n\n# def function_name ():\n#     codes\n#     codes\n\n# function_name()\n\n############## Function without Parameters \n\ndef show_name ():\n    first_name = 'Pepito'\n    last_name = 'Perez'\n    space = ' '\n    full_name = first_name + space + last_name\n    print(full_name)\nshow_name ()\n\ndef sum_two_numbers ():\n    number_one = 2\n    number_two = 3\n    total = number_one + number_two\n    print(total)\nsum_two_numbers()\n\n############### Function Returning a Value\n\ndef show_name ():\n    first_name = 'Pepito'\n    last_name = 'Perez'\n    space = ' '\n    full_name = first_name + space + last_name\n    return full_name\nprint(show_name ())\n\ndef sum_two_numbers ():\n    number_one = 2\n    number_two = 3\n    total = number_one + number_two\n    return total\nprint(sum_two_numbers())\n\n\n########### Function with Parameters\n\ndef greetings (name):\n    message = name + ', welcome to Python for Everyone!'\n    return message\n\nprint(greetings('Asabeneh'))\n\ndef sum_value(num):\n    ten = 2\n    return num + ten\nprint(sum_value(90))\n\ndef square_number(x):\n    return x * x\nprint(square_number(2))\n\ndef area_of_circle (r):\n    PI = 3.14\n    area = PI * r ** 2\n    return area\nprint(area_of_circle(10))\n\ndef sum_of_numbers(n):\n    total = 0\n    for i in range(n+1):\n        total+=i\n    print(total)\nprint(sum_of_numbers(10)) # 55\n\n\n############# Function with 2 parameters\n\ndef generate_full_name (first_name, last_name):\n    space = ' '\n    full_name = first_name + space + last_name\n    return full_name\nprint('Full Name: ', generate_full_name('Pepito','Perez'))\n\ndef sum_two_numbers (num_one, num_two):\n    sum = num_one + num_two\n    return sum\nprint('Sum of two numbers: ', sum_two_numbers(3, 6))\n\n\n############ Function Passing Arguments with Key and Value\n\ndef add_two_numbers (num1, num2):\n    total = num1 + num2\n    print(total)\nprint(add_two_numbers(num2 = 3, num1 = 2))\n\n\n############# Function Returning a boolean\n\ndef is_even (n):\n    if n % 2 == 0:\n        print('even')\n        return True    \n    return False\nprint(is_even(10))\nprint(is_even(7))\n\n\n############### Function Returning a list\n\ndef find_even_numbers(n):\n    evens = []\n    for i in range(n + 1):\n        if i % 2 == 0:\n            evens.append(i)\n    return evens\nprint(find_even_numbers(10))\n\n\n############### Function with Default Parameters\n\ndef full_name (first_name = 'Pepito', last_name = 'Perez'):\n    space = ' '\n    full_name = first_name + space + last_name\n    return full_name\n\nprint(full_name())\nprint(full_name('David','Smith'))\n\n\n############## Function with Arbitrary Number of Arguments\n\ndef sum_all_nums(*nums):\n    total = 0\n    for num in nums:\n        total += num     \n    return total\nprint(sum_all_nums(2, 3, 5))\n\n################ Function as a Parameter of Another Function\n\ndef square_number (n):\n    return n * n\ndef do_something(f, x):\n    return f(x)\nprint(do_something(square_number, 3))\n\n\n########   Dificultad Extra #########\n\ndef impre_num (text1, text2):\n    \n    cont = 0\n    for i in range (1,101):\n        \n        if i % 3 == 0 and i % 5 == 0:\n            print(f\"{text1} {text2}\")\n            cont += 1\n        elif i % 3 == 0:\n            print(text1)\n            cont += 1\n        elif i % 5 == 0:\n            print(text2)\n            cont += 1        \n        else:\n            print(i)\n    \n    return (100 - cont)\n\nresul = impre_num(\"Pepito\", \"Perez\")\nprint(f\"El numero de veces que se imprimieron los numeros es: {resul}\")\n\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Complex303.py",
    "content": "\"\"\"\nFunciones definidas por el usuario\n\"\"\"\n\n#simple\n\ndef greet():\n    print(\"Hola, Python!!\")\n\ngreet()\n\n#con retorno\n\ndef return_greet():\n    return \"Hola, Python!\"\n\n#greet = return_greet()\nprint(return_greet())\n\n\n\n#con un argumento\ndef arg_greet(name):\n    print(f'Hola {name}')\n\narg_greet('Eddy')\n\n\n#con argumentos\ndef args_greet(greet, name):\n    print(f'{greet} {name}')\n\nargs_greet('Hola', 'Eddy')\nargs_greet(name = 'Luis', greet='Hola') #le cambio el orden\n\n\n#con un argumento predeterminado\n\ndef default_arg_greet(name = 'Python'):\n    print(f'Hola {name}')\n\ndefault_arg_greet('Eddy')\ndefault_arg_greet()\n\n\n#con argumento y retorno\ndef return_arg_greets(greet, name):\n    return f'{greet}, {name}!!'\n\nprint( return_arg_greets('Hola', 'Eddy'))\n\n\n\n#con retorno de varios valores\ndef multiple_return_gree():\n    return 'Hola', 'Python'\n\ngreet, name = multiple_return_gree()\nprint(greet)\nprint(name)\n\n\n#con un número variable de argumento\n\ndef variable_args_greet(*names):\n    for name in names:\n        print(f'hola {name}')\n\nvariable_args_greet('Python', 'Eddy', 'Complex')\n\n\n#con un número variable de argumento con palabra clave\ndef variable_key_args_greet(**names):\n    for key, value in names.items():\n        print(f'{value} ({key})!!')\n\nvariable_key_args_greet (\n    language = 'Python',\n    name = 'Eddy',\n    Alias = 'Complex',\n    age = 24\n)\n\n\"\"\"\nFunciones dentro de funciones\n\"\"\"\ndef outer_function():\n    def inner_function():\n        print(\"Funcion interna: Hola python\")\n    inner_function()\n\nouter_function()\n\n\n\"\"\"\nFunciones del lenguaje (built in)\n\"\"\"\n\nprint(len('Complex'))\nprint(type(3.4))\nprint('eddy'.upper())\n\n\"\"\"Variables \nlocales y globales\"\"\"\n\nglobal_variable = 'Python'\n\nprint(global_variable)\n\ndef hello_python():\n    local_variable = 'Hello'\n    print(f\"{local_variable} {global_variable}\")\n\n#print(local_variable) #No se puede acceder desde afuera de la funcion\nhello_python()\n\n\n\"\"\" * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\"\"\"\n\n\n\ndef funcion_numero(txt, txt2) -> int:\n    contador = 0\n    for num in range(1,101):\n        if num % 3 ==0 and num % 5 ==0:\n            print(f'{txt+ ' '+txt2}')\n        elif num % 3 ==0:\n            print(txt)\n        elif num % 5  ==0:\n            print(txt2)\n        else:\n            print(num)\n            contador +=1\n    return contador\n\n\nprint(funcion_numero('Fizz', 'Buzz'))\n    \n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/D3rk1us.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n\"\"\"\n\n# Función sin parámetros, ni retorno\n\ndef firstFunction():\n    print('Hola mundo.')\n\nfirstFunction()\n\n# Función con un parámetro, con variables locales y utilizando una función ya creada por el lenguaje.\n\ndef circleArea(r):\n    PI = 3.141592\n    result = PI * r**2\n    print(round(result, 2))\n\ncircleArea(2)\n\n# Función con retorno y con una variable global.\n\nnum = 2\n\ndef returnFunction():\n    return num * num\n\nprint(returnFunction())\n\n# Función con un parámetro y retorno.\n\ndef welcome(name):\n    return f\"Bienvenido/a, {name}.\"\n\nprint(welcome(\"Python\"))\n\n# Función creada dentro de otra función\n\ndef rectangleArea(b, a):\n    def calculate():\n        return b * a\n\n    return calculate()\n\nprint(rectangleArea(10, 5))\n\n# Dificultad Extra:\n\n# Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\ndef fizzBuzz(str1, str2):\n    \n    if isinstance(str1, str) and isinstance(str2, str):\n\n        total_times = 0\n\n        # La función imprime todos los números del 1 al 100.\n        for i in range(1,101):\n\n            # Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n            if i % 5 == 0 and i % 3 == 0:\n                print(str1 + str2)\n            \n            # Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n            elif i % 5 == 0:\n                print(str2)\n            \n            # Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n            elif i % 3 == 0:\n                print(str1)\n\n            else:\n                total_times += 1\n\n\n        # La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n        return total_times\n    \n    else:\n        return \"Se tiene que indicar por parámetro dos cadenas de texto(Por ejemplo: 'Fizz', 'Buzz'). Inténtalo de nuevo...\"\n\n\nprint(fizzBuzz(\"Fizz\", \"Buzz\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/DAVstudy.py",
    "content": "# Funciones\n\n# Función simple\n\ndef say_hi():\n    print(\"Hola!\")\n\n\nsay_hi()\n\n\n# Funcion con retorno\n\ndef alias_dev():\n    alias = \"DevsDav\"\n    return alias\n\n\nname = alias_dev()\nprint(name)\n\n\n# Funcion con un argumento\n\ndef triple_value(value):\n    return value * 3\n\n\nprint(triple_value(3))\n\n\n# Funcion con varios argumentos\n\ndef get_hypotenuse(cathetus_a, cathetus_b):\n    hypotenuse = (cathetus_a**2 + cathetus_b**2)**(0.5)\n    return hypotenuse\n\n\nprint(get_hypotenuse(3, 4))\n\n\n# Funcion con argumento predeterminado\n\ndef mode_house(mode=\"default\"):\n    return mode\n\n\nprint(mode_house())\nprint(mode_house(\"Noche de juegos\"))\n\n\n# Funcion con retorno de varios valores\n\ndef get_subjects():\n    return \"lenguaje\", \"matemáticas\", \"íngles\", \"tecnología\"\n\n\nsubject_1, subject_2, subject_3, subject_4 = get_subjects()\n\nprint(f\"Asignaturas: {subject_1}, {subject_2}, {subject_3}, {subject_4}\")\n\n\n# Funciones propias del lenguaje\n\nlist_numbers = list(range(30))\nprint(len(\"DevsDav\"))\nprint(type(1.2))\nprint(list_numbers)\n\n\n# Variables locales y  globales\n\nglobal_var = \"Me puedes llamar de cualquier parte del código\"\n\n\ndef example():\n    local_var = \", a mi solo me puedes llamar dentro de mi función.\"\n    print(global_var + local_var)\n\n\nexample()\nprint(global_var)\n# print(local_var) # no se puede acceder\n\n\n# Challenge Extra\n\ndef challenge_fun(first_string, second_string):\n    number = 0\n    for i in range(0, 101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(first_string + second_string)\n        elif i % 3 == 0:\n            print(first_string)\n        elif i % 5 == 0:\n            print(second_string)\n        else:\n            print(i)\n            number += 1\n    return number\n\n\nprint(challenge_fun(\"fizz\", \"buzz\"))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/DGJuancho.py",
    "content": "# Funciones sin parámetro ni retorno\n\n\ndef hola_mundo():\n    print(\"Hola Mundo\")\n\n\nhola_mundo()\n\n\n# Función con argumentos\ndef pares(a, b):\n    print(f\"Los números pares entre {a} y {b} son:\")\n    for i in range(a, b + 1):\n        if i % 2 == 0:\n            print(i, end=\" \")\n    print()\n\n\npares(1, 20)\n\n\n# Función con retorno\ndef potencia(x):\n    print(f\"El cuadrado de {x} es: \")\n    return print(x**2)\n\n\na = 5\n\npotencia(a)\n\n# Funciones dentro de otras funciones\n\n\ndef area_circulo(radio):\n    return 3.1416 * radio**2\n\n\ndef volumen_cilindro(radio, altura):\n    areaBase = area_circulo(radio)\n    return areaBase * altura\n\n\nradio = 2.6\naltura = 6.5\nvolumen = volumen_cilindro(radio, altura)\nprint(f\"El volumen del cilindro es: {volumen}\")\n\n# Función del sistema \"len\" \"type\"\nprint(len(\"DGJuancho\"))\nprint(type(120))\n\n# Variables global y local\n\nglobal_var = \"Juancho\"\n\n\ndef edad():\n    local_var = 46\n    print(f\"Mi nombre es {global_var} y tengo {local_var} años\")\n\n\nprint(global_var)\n# print(local_var) La variable no está definida fuera de la función\nedad()\n\n\"\"\"\nDIFICULTAD EXTRA\n\"\"\"\n\n\ndef numeros(texto_1, texto_2):\n    count = 0\n    for i in range(1, 101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(texto_1 + texto_2)\n        elif i % 3 == 0:\n            print(texto_1)\n        elif i % 5 == 0:\n            print(texto_2)\n        else:\n            print(i)\n            count += 1\n    return count\n\n\nprint(numeros(\"TRES\", \"CINCO\"))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/DGrex.py",
    "content": "\"\"\"\n    EJERCICIO:\n    Crea ejemplos de funciones básicas que representen las diferentes\n    posibilidades del lenguaje:\n    Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n    Comprueba si puedes crear funciones dentro de funciones.\n    Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n    Pon a prueba el concepto de variable LOCAL y GLOBAL.\n    Debes hacer print por consola del resultado de todos los ejemplos.\n    (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n\"\"\"\n\n# Funcion sin parámetros ni retorno\n\ndef suma():\n  num_one = 3\n  num_two = 5\n  print(F\"Suma > {num_one} + {num_two} : {num_one + num_two}\")\n\nsuma()\n\n# Funcion con parametros\n\ndef resta(num1,num2):\n  print(F\"Resta > {num1} - {num2} : {num1 - num2}\")\n\nresta(5,3)\n\n# Funcion con retorno\n\ndef multiplicacion(num1,num2):\n  mensaje = f\"Multiplicacion > {num1} * {num2}: {num1 * num2}\"\n  return mensaje\n\nprint(multiplicacion(2,5))\n\n# Funcion dentro de una funcion\n\ndef funcion_one():\n  num1 = 1\n  def funcion_two(num2,num3):\n    mensaje = f\"suma > {num1} + {num2} + {num3}: {num1 + num2 + num3}\"\n    return mensaje\n  print(funcion_two(3,6))\n\n\nfuncion_one()\n\n# Funciones creadas en el lenguaje\n\n#Funcion tipo de dato de una variable type()\nnombre= \"DGrex\"\nprint(type(nombre)) # print() tambien es una funcion del lenguaje\n\n# Funcion longitud\nnombre= \"DGrex\"\nprint(len(nombre))\n\n# Funcion conversión de valores\nprint(int(\"123\")) # Texto a entero\nprint(float(\"123.45\")) # Texto a decimal\nprint(str(123)) # Numero a texto\n\n# Funciones valor maximo y minimo\nnumeros = [1, 2, 3, 4, 5]\nprint(max(numeros))# Valor maximo\nprint(min(numeros))# Valor minimo\n\n\n# Variable local y global\n\n# Variable global\nvariable_global = \"Soy una variable global\"\n\ndef variables():\n    # Variable local\n    variable_local = \"Soy una variable local\"\n    # Imprimir la variable global\n    print(variable_global)\n    # Imprimir la variable local\n    print(variable_local)\n\nvariables()\n\n# Intentar imprimir la variable local fuera de la función causará un error\n# print(variable_local)  # Esto causará un NameError: name 'variable_local' is not defined\n\n\"\"\"\n    Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n    La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n    Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n    Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n    Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n    La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\"\"\"\nprint(\"\\nFuncion ejercicio extra\\n\")\n\ndef funcion(cadena_uno,cadena_dos):\n  contador = 0\n  for num in range(1,101):\n    if num % 3 == 0 and num % 5 == 0:\n      print(f\"{cadena_uno} y {cadena_dos}\")\n    elif num % 3 == 0:\n      print(cadena_uno)\n    elif num % 5 == 0:\n      print(cadena_dos)\n    else:\n      print(num)\n      contador +=1\n\n  return contador\n\nfuncion(\"Fizz\", \"Buzz\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/DLGAI12.py",
    "content": "\"\"\"\n    /*\n    * EJERCICIO:\n    * - Crea ejemplos de funciones básicas que representen las diferentes\n    *   posibilidades del lenguaje:\n    *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n    * - Comprueba si puedes crear funciones dentro de funciones.\n    * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n    * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n    * - Debes hacer print por consola del resultado de todos los ejemplos.\n    *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n    *\n    * DIFICULTAD EXTRA (opcional):\n    * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n    * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n    *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n    *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n    *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n    *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n    *\n    * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n    * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n    */\n \"\"\"\n\n#Funcion sin parametros y sin retorno\n\ndef saludo():\n    print(\"Hola Python\")\n\n#Funcion con un  parametro y sin retorno\n\ndef saludo1(parametro):\n    print(\"Hola\"+ parametro)\n\n\n#Funcion con vcarios  parametros y sin retorno\n\ndef saludo2(parametro1,parametro2):\n    print(parametro1+ parametro2)\n\n#Funcion con retorno \n\ndef saludo3(parametro1,parametro2):\n    return parametro1+ parametro2\n\n\n#Funcion con parametros determinados\n \ndef saludo4(parametro1,parametro2=\" Python\"):\n    return parametro1+ parametro2\n\n#Funcion dentro de funcion\ndef funcion_anidada():\n    def funcion():\n        print(\"Soy una funcion anidada\")\n    funcion()\n\"\"\"Alcance Variables\"\"\"\ndef variables():\n    variable_local = \"¡Hola, soy una variable local!\"\n    print(variable_local)\n    print(variable_global)\n\nvariable_global = \"¡Hola, soy una variable global!\"    \n\"\"\"LLamado a tipos de funciones\"\"\"\n\nsaludo()\nsaludo1(\" Python\")\nprint(saludo3(\"Hola\",\" Adios\"))\nprint(saludo4(\"Hola\",\" Como Estas\"))\nprint(saludo4(\"Hola\"))\nfuncion_anidada()\n\n\n\"\"\"LLamado a alcance de tipos de variables\"\"\"\nvariables()\n\"\"\"Ejercicio Extra\"\"\"\ndef extra(parametro1,parametro2):\n    contador=0\n    for i in range(1,101):\n        if(i%15==0):\n            print(f\"{parametro1}  {parametro2}\")\n        elif(i%3==0):\n            print(parametro1)\n        elif(i%5==0):\n            print(parametro2)\n        else:\n            print(i)\n            contador+=1\n    return contador\n\nprint(extra(\"Tres\",\"Cinco\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/DaniQB99.py",
    "content": "\"\"\"  \n/*\n    EJERCICIO:\n        1) Crea ejemplos de funciones básicas que representen las diferentes posibilidades del lenguaje:\n            Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n        2) Comprueba si puedes crear funciones dentro de funciones.\n            Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n            Pon a prueba el concepto de variable LOCAL y GLOBAL.\n            Debes hacer print por consola del resultado de todos los ejemplos.\n            (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n\n    DIFICULTAD EXTRA (opcional):\n        3) Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n            - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n            - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n            - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n            - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n            - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\n    Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n    Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n*/\n\"\"\"\n\n# 1) Funciones básicas\n\n# Sin parámetros ni retorno\ndef function1():\n    print(\"Hola mundo\")\n\nfunction1()\n\n# Con retorno\ndef function2():\n    return \"Hola mundo\"\n\nprint(function2())\n\n# Con uno o varios parámetros\ndef function3(name, surname):\n    print(f'Hola, {name} {surname}')\n\nfunction3('Daniel', 'Quiros')\n\n# Con retorno y uno o varios parámetros\ndef function4(num1 = 3, num2 = 5):\n    return num1 + num2\n\nprint(function4(1, 2))\nprint(function4())\n\n# Con argumentos por defecto\ndef function5(*names): # El asterisco indica que se espera un número variable de argumentos\n    for name in names: \n        print(f'Hola {name}')\n\nfunction5('Dani', 'Africa', 'Paco', 'Jhon')\n\n# Con un número variable de argumentos y palabras clave\ndef function6(**names):\n    for key, name in names.items():\n        print(f'Hola {name} ({key})')\n\nfunction6(\n    name='Dani', \n    surname='Quiros', \n    alias='DaniQB99',\n    age=25\n)\n\n# 2) Funciones dentro de funciones\n\ndef outer_function():   \n    def inner_function():\n        print('Funciones internas: Hola, mundo')\n    \n    inner_function()\n\nouter_function()\n\n\n# Funciones propias del lenguaje (built-in)\n\nprint(len('Hola mundo')) # len() devuelve la longitud de una cadena\nprint(sum([1, 2, 3, 4, 5])) # sum() devuelve la suma de un vector\nprint(max([1, 2, 3, 4, 5])) # max() devuelve el mayor valor de un vector\nprint(min([1, 2, 3, 4, 5])) # min() devuelve el menor valor de un vector    \nprint(type('Hola mundo')) # type() devuelve el tipo de un objeto\nprint('Hola mundo'.lower()) # lower() devuelve una cadena en minúsculas\nprint('Hola mundo'.upper()) # upper() devuelve una cadena en mayúsculas\n\n# Variables locales y globales\n\nglobal_var = 'Python'\n\ndef hello_python():\n    local_var = 'Hola'\n    print(f'{local_var}, {global_var}')\n\nprint(global_var)\n# print(local_var) # Error: local_var no esta definida fuera de la funcion\nhello_python()\n\n# 3) Función que reciba dos parámetros de tipo cadena de texto y retorne un número.\nprint('\\n--- EJERCICIO EXTRA ---')\n\ndef print_numbers(text_1, text_2) -> int:\n    count = 0\n    for number in range(1, 101):\n        if number % 3 == 0 and number % 5 == 0:\n            print(text_1 + text_2)\n        elif number % 3 == 0:\n            print(text_1)\n        elif number % 5 == 0:\n            print(text_2)\n        else:\n            print(number)\n            count += 1\n    return count\n\nprint(print_numbers('Fizz', 'Buzz'))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/DaniRojasDev.py",
    "content": "'''\nFunción sin parametros\n'''\ndef greet():\n    print (\"Hello\")\ngreet()\n\n'''\nFunción con un parametro\n'''\ndef greet_with_name(name):\n    print (\"Hello\", name)\ngreet_with_name(\"Dani\")\n\n'''\nFunción con varios parametros\n'''\ndef greet_with_surname(name, surname):\n    print (f\"Hello, {name} {surname}\")\n\ngreet_with_surname(\"Dani\", \"Rojas\")\ngreet_with_surname(name=\"Brais\", surname=\"Moure\")\n\n'''\nFunción con un parametro por defecto\n'''\n# Si le damos un nuevo argumento lo coge, sino muestra el de por defecto\ndef default_greet_with_name(name=\"Paco\"):\n    print (\"Hello\", name)\n\ndefault_greet_with_name(\"Manolo\")\ndefault_greet_with_name()\n\n'''\nFunción con retorno\n'''\ndef return_greet(): # Cuando se llama a esta función nos retorna lo que le indiquemos con el return, eso lo podemos utilizar para lo que queramos por ejemplo un print\n    return \"hola, Dani!\"\n\nprint (return_greet())\n\n'''\nFunción con retorno y argumentos\n'''\ndef return_greet(name, surname): # Igual que la anterior pero dándole nosotros los argumentos\n    return f\"{name}, {surname}!\"\n\nprint (return_greet(\"Hola\", \"Brais\"))\n\n'''\nFunción con argumentos de longitud variable\n'''\ndef variable_greet (*numbers): # Con el * hacemos que se cree una tupla\n    for n in numbers:\n        print (f\"Numbers is, {n}\")\n\nvariable_greet (1, 2, 3, 4, 5, 6)\n\n'''\nFunción con argumentos de longitud variable y palabra clave\n'''\ndef variable_greet_key (**numbers): # con ** conseguimos tener como entrada a parte del valor una lista de elementos clave\n    for key, n in numbers.items(): # key par la palbra clave, .items() para iterar los valores\n        print (f\"{key}, ({n})\")\n\nvariable_greet_key (one=1, two=2, three=3, four=4, five=5, six=6)\n\n'''\nFunción dentro de función\n'''\ndef exterior_function ():\n    print (\"Llamo a la función exterior\")\n    def interior_function ():\n        print (\"Esto es la función interior\")\n    interior_function()\n\nexterior_function()\n\n'''\nFunciones del lenguaje\n'''\nstr=\"print: Imprime por consola\"\nprint(str) # Imprime por consola\nprint(type(str)) # Nos indica el tipo de variable que le hayamos metido\nprint(len(str)) # Cuenta el número de caracteres de un string\nnew_str=str.replace(\"consola\",\"terminal\") # Reemplaza la palabra de la izquierda por la de la derecha\nprint(f\"Se cambia 'consola' por 'terminal', {new_str}\")\n\n'''\nVariables locales y globales\n'''\nglobal_varible=\"esto es una variable global\" # Se puede acceder desde todo el código\n\ndef show_local_variable():\n    local_variable=\"esto es una variable local\"\n    print(local_variable)\n\n\nprint(global_varible)\n#print(local_variable) no se puede hacer porque estamos fuera de la función\nshow_local_variable() #Llamamos a la función para imprimir por consola local_variable\n\n'''\nExtra\n'''\ndef print_numbers(str_1, str_2):\n    c=0\n    for num in range(1,101):\n        if num % 3 == 0 and num % 5 == 0:\n            print(str_1,str_2)\n        elif num % 3 == 0:\n            print(str_1)\n        elif num % 5 == 0:\n            print(str_2)\n        else:\n            print(num)\n            c+=1\n    return c\n        \nprint(print_numbers(\"Múltiplo de 3\", \"Múltiplo de 5\"))\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Danilo0203.py",
    "content": "# 📌 FUNCIONES BASICA\n\n# Funciones simples\nprint(\"====== Funciones simples ======\")\ndef saludar():\n    print(\"Hola, Python\")\n\n\nsaludar()\n\n\n# Funciones con retorno\nprint(\"\\n====== Funciones con retorno ======\")\ndef return_saludar():\n    return \"Hola, Python\"\n\n\nprint(return_saludar())\n\n\n# Funciones con argumentos y parametros\nprint(\"\\n====== Funciones con argumentos y parametros ======\")\ndef arg_saludo(nombre):\n    print(f\"Hola, {nombre}!\")\n\n\narg_saludo(\"Danilo\")\n\n\ndef args_saludos(saludo, nombre):\n    print(saludo, nombre)\n\n\nargs_saludos(\"Hola\", \"Mundo\")\n\n# Orden en los argumentos de las funciones\nargs_saludos(nombre=\"Mundo\", saludo=\"Hola\")\n\n\n# Funcion con Argumentos prederterminados\nprint(\"\\n====== Funciones con Argumentos prederterminados ======\")\ndef default_arg_saludo(nombre=\"usuario\"):\n    print(f\"!Hola, {nombre}¡\")\n\n\ndefault_arg_saludo()\n\n\n# Funcion con argumentos y retorno\nprint(\"\\n====== Funciones con Argumentos y retorno ======\")\ndef return_args_saludar(saludo, nombre):\n    return f\"{saludo}, {nombre}\"\n\n\nprint(return_args_saludar(\"Hola\", \"Danilo y Python\"))\n\n\n# Funcion con retorno de varios valores\nprint(\"\\n====== Funciones con retorno de varios valores ======\")\ndef multiple_return_saludo():\n    return \"Hola\", \"retorno de varios valores\"\n\n\nsaludo, nombre = multiple_return_saludo()\nprint(saludo)\nprint(nombre)\n\n# Funciones con un numero variable de argumentos\nprint(\"\\n====== Funciones con un numero variable de argumentos ======\")\ndef variable_arg_saludo(*names):\n    for name in names:\n        print(f\"Hola, {name}\")\n\n\nvariable_arg_saludo(\"Danilo\", \"Estuardo\", \"Calderon\", \"Barrios\")\n\n# Funciones con un numero de variables de argumentos con palabra clave\nprint(\n    \"\\n====== Funciones con un numero de variables de argumentos con palabra clave ======\"\n)\ndef variable_key_arg_saludo(**names):\n    for key, name in names.items():\n        print(f\"Hola, {name} ({key})\")\n\n\nvariable_key_arg_saludo(nombre =\"Danilo\", nombre2= \"Estuardo\", apellido= \"Calderon\", apellido2=\"Barrios\")\n\n# Funciones dentro de Funciones\nprint(\"\\n====== Funciones dentro de Funciones ======\")\ndef funcion_afuera():\n    def funcion_adentro():\n        print('Funcion interna: Hola Phyton!')\n    funcion_adentro()\n\nfuncion_afuera()\n\n# Funciones propias del Lenguaje\nprint(\"\\n====== Funciones propias del lenguaje ======\")\nprint('print() --> es una funcion propia del lenguaje python')\nprint(f'len() es una funcion propia: {len('Hola')}')\nprint(f'type() es una funcion propia: {type('Hola')}')\n\n# Variables Globales y Locales\nprint(\"\\n====== Variables Globales y Locales ======\")\n\nvariable_global = 'Variable global'\nprint(variable_global)\n\ndef bloque_local():\n    variable_local = 'Variable Local'\n    print(f'Hola, {variable_global} y {variable_local}')\nbloque_local()\n# print(variable_local) # Esta variable solo funciona en el bloque de codigo \"bloque_local\"\n\n\"\"\" Extra \n Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n  - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n    - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n    - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n    - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n    - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\"\"\"\nprint(\"\\n====== EXTRA ======\")\ndef extra (cadena1, cadena2)->int:\n    count = 1\n    numeros = []\n    while(count <= 100):\n        if(count % 3 == 0 and count % 5 ==0):\n            print(f\"{cadena1}{cadena2}, {count}\")\n        elif(count % 3 == 0):\n            print(cadena1, count)\n        elif(count % 5 == 0):\n            print(cadena2, count)\n        else:\n            numeros.append(count)\n        count+=1\n    return len(numeros)\n\nprint(extra('hola', 'mundo'))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Daparradom.py",
    "content": "### 02- Funciones y Alcance\n\ndef my_first_function ():\n    print('Esta es una funcion sin parametros ni retorno')\n\ndef my_second_function (name,lastname): #funcion con parametros\n    print(f\"Welcome to Python {name} {lastname}\")\n\nmy_first_function()\nmy_second_function(\"David\",\"Parrado\")\n\ndef sum_function (num_one,num_two): #funcion con parametros y retorno\n    sum=num_one + num_two\n    return sum\n\nprint(sum_function(4,87))\n\ndef sqr_function(number): #Funcion dentro de otra funcion\n    number=float(number)\n    return (number)**(0.5)\ndef operacion_function(f,num):\n    return f(num)\nprint(operacion_function(sqr_function,9))\n\ndef cadenas_function(cadena_1,cadena_2):\n    con = 0\n    for i in range  (1,101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(cadena_1 +\" \"+ cadena_2)\n        elif i%3 == 0:\n            print(cadena_1)\n        elif i%5 == 0:\n            print(cadena_2)\n        else:\n            print(i)\n            con+= 1\n    return con\n\nprint(cadenas_function(\"Hola\",\"Python\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/DataCiriano.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\"\"\"\n\n# Función sin parámetros y sin retorno\ndef saludo_01():\n    print(\"¡¡Hola, buenos días!!\")\n    \nsaludo_01()\n\n# Función con  parámetros y sin retorno\ndef saludo_02(nombre, apellido):\n    print(f\"Hola, {nombre} {apellido}.\\n¿Cómo estás?\")\n\nnombre = input(\"Escriba su nombre: \")\napellido = input(\"Escriba su apellido: \")\n\nsaludo_02(nombre,apellido)\n\n# Función con parámetros y retorno\nnumero_01 = float(input(\"Escriba el primer número: \"))\nnumero_02 = float(input(\"Escriba el segundo número: \"))\n\ndef sumar(numero_01,numero_02):\n    resultado = numero_01 + numero_02\n    return resultado \n\nresultado_suma = sumar(numero_01,numero_02)\nprint(f\"El resultado de sumar {numero_01} + {numero_02} = {resultado_suma}\")\n\n# Función dentro de otro función\n\ndef suma_resta(numero_01,numero_02):\n    \n    resta = numero_01 - numero_02\n    suma =sumar(numero_01, numero_02)\n    \n    return  resta, suma\n\nresultado_resta, resultado_suma = suma_resta(numero_01,numero_02)\n\nprint(f\"El resultdao de la resta es {resultado_resta} y el de la suma es {resultado_suma}\")\n\n# Funciones integradas de Python\n\nx = int(\"123\") #conversión de string a entero\nprint(x)\ny = float(\"3.14\") #conversión de string a float\nprint(y)\nz = str(42) #conversión de entero a string\nprint(z)\nis_true = bool(1) #conversión de entero a booleano\nprint(is_true)\n\n# Variables locales y globales\n\nsaludo = \"Hola\" #variable global\n\ndef saludar():\n    nombre = input(\"¿Cómo te llamas: \") #variable local\n    print(saludo, nombre)\n    \nsaludar()\n\n\n#EXTRA\n\nmultiplo_3 = \"Es múltiplo de 3\"\nmultiplo_5 = \"Es múltiplo de 5\"\n\ndef multiplos(parametro_1, parametro_2):\n    contador = 0\n    for i in range(1,101,1):\n        if i % 3 == 0 and i % 5 == 0:\n            print(parametro_1 + parametro_2)\n        elif i % 3 == 0:\n            print(parametro_1)\n        elif i % 5 == 0:\n            print(parametro_2)\n        else:\n            print(i)\n            contador += 1\n            \n    print(f\"Se han impreso {contador} números\")\n            \nmultiplos(multiplo_3, multiplo_5)\n        \n    "
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/DevKnn.py",
    "content": "\"\"\"\n z EJERCICIO:\n  - Crea ejemplos de funciones básicas que representen las diferentes\n    posibilidades del lenguaje\n    Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n    Comprueba si puedes crear funciones dentro de funciones.\n    Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n    Pon a prueba el concepto de variable LOCAL y GLOBAL.\n    Debes hacer print por consola del resultado de todos los ejemplos.\n    (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n    Comprueba si puedes crear funciones dentro de funciones.\n    Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n    Pon a prueba el concepto de variable LOCAL y GLOBAL.\n    Debes hacer print por consola del resultado de todos los ejemplos.\n    (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n\"\"\"\n\ntitulo1 = \"Hola\"\ntitulo2 = \"Python\"\n\n#funcion que no devuelve un parametro, ni retorno\ndef myFuction():\n    print(\"Funcion que no devuelve un parametro, ni retorno\")\nmyFuction()\n#Funcion que espear un parametro y es llamado a nivel local\ndef myFuction1(x):\n    x = \"hola\"\n    print(\"Funcion que espear un parametro y es llamado a nivel local\",x)\nmyFuction1(titulo1)\n#Funcion que espear dos parametro y es llamado a nivel global\ndef myfuction3():\n    print((\"Mi funcion\"))   \n    def dentroDeLaFunction(x=None):\n        print(\"Dentro de la funcion\")\n        if x is None:\n            x = []\n            x.append(titulo1)\n            x.append(titulo2)\n            print(x)\n        return x\n    dentroDeLaFunction()\nmyfuction3()\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\"\"\"\n \ndef index(txt1, txt2):\n    txt2 = \"Mundo\"\n    i = 0\n    while(i<=100):\n        if i % 3 == 0 and i % 5 == 0:\n            print(txt1 + txt2)\n        if i % 3 == 0:\n            print(txt1)\n        elif i % 5 == 0:\n            print(txt2)\n        else:\n            print(i)\n        i+=1\n    return i\n\ntxt1 = \"Hola\"\ntx2 = \"Python\"\nprint(index(txt1, tx2))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/DiegoIBB.py",
    "content": "\"\"\" \n  EJERCICIO:\n  - Crea ejemplos de funciones básicas que representen las diferentes\n    posibilidades del lenguaje:\n    Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n  - Comprueba si puedes crear funciones dentro de funciones.\n  - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n  - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n  - Debes hacer print por consola del resultado de todos los ejemplos.\n    (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n \n  DIFICULTAD EXTRA (opcional):\n  Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n  - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n    - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n    - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n    - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n    - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n \n Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n \n \"\"\"\n\n#FUNCION BASICA\nprint(\"---- Función básica ----\")\n\ndef contador():\n    frase = input(\"Ponga una frase: \")\n    contador_a = 0\n    for letra in frase:\n        if (letra == \"a\"):\n            contador_a += 1\n    print(f\"Las as en la frase son: {contador_a}\")\n\ncontador()\n\n\nlista_1 = [3, 5, 6, 2, 7, 8, 3, 4, 3, 7, 7]\n\n#FUNCION DENTRO DE UNA FUNCION\nprint(\"---- Función dentro de una función ----\")\n\ndef ordenador(lista):\n   contador_3 = 0\n   contador_7 = 0\n   for i in lista:\n      if i == 3:\n          contador_3 += 1\n      elif i == 7:\n          contador_7 += 1\n\n   def contadores(val_1, val_2):\n      if val_1 > val_2:\n        print(f\"Los valores son muy bajos; {val_1} mayor que {val_2}\")\n      elif (val_1 < val_2):\n        print(f\"Los valores son altos; {val_1} menor que {val_2}\")\n      elif (val_1 == val_2):\n         print(\"Hay igual cantidad de valores\")\n      diferencia = val_1 - val_2\n      return diferencia\n   resultado = contadores(contador_3, contador_7)\n   print(f\"La diferencia es {resultado}\")\n\nordenador(lista_1)\n\n#FUNCION YA CREADA EN EL PROGRAMA\n\nprint(\"---- Función ya creada en el programa ----\")\n\nlista_2 = [3, 5, 6, 3, 7, 8, 4, 7, 2, 12, 34, 6, 23]\n\nlargo_lista = len(lista_2)\nprint(f\"Función para ver el largo de una lista: {largo_lista}\")\n\n\n#VARIABLE LOCAL Y GLOBAL\nprint(\"---- Variables Locales y Globales ----\")\n\nreservas = int(input(\"Número de reservas: \")) # Variable Global, podemos usarla en las 2 funciones que se muestra a continuación\n\ndef cantidad_asistentos(ocupacion):\n    total_asientos = 500 # Variable Local, su acción queda relegada a esta función\n    asientos_libres = total_asientos - ocupacion\n    return asientos_libres\n\ndef estado(libres):\n    if(cantidad_asistentos(libres) > 450):\n      print(\"Alta Concurrencia\")\n    elif(cantidad_asistentos(libres) < 400):\n      print(\"Concurrencia Media\")\n    elif(cantidad_asistentos(libres) < 300):\n       print(\"Baja Concurrencia\")\n\n    print(f\"Nivel de ocupación: {reservas}\")\n    print(f\"Asientos libres: {cantidad_asistentos(reservas)}\")\n    \nventa_entradas = cantidad_asistentos(reservas)\nestado(venta_entradas)\n\n#DIFICULTAD EXTRA\n\"\"\" \n  DIFICULTAD EXTRA (opcional):\n  Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n  - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n    - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n    - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n    - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n    - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\n \"\"\"\n \nprint(\"---- Dificultad Extra ----\")\n\ndef desafio_extra(cadena_1, cadena_2):\n    lista_1_100 = range(0,101) #Evaluar cada elemento que entra a la lista según las condiciones dadas\n    for i in range(1, len(lista_1_100), 1):\n        #print(i)\n        if (i % 3 == 0 and i % 5 == 0):\n            print(f\"{cadena_1}  {cadena_2}, Valor número: {i}\")\n        elif(i % 5 == 0):\n            print(f\"{cadena_1}, valor del númro: {i}\")\n            continue\n        elif(i % 3 == 0):\n            print(f\"{cadena_2}, valor del número: {i}\")\n            continue\n        else:\n            print(i)\n\ndesafio_extra(\"Num_5\", \"Num_3\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Dkp-Dev.py",
    "content": "\"\"\"EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n \"\"\"\n\n\"\"\"\nFunciones definidas por el usuario\n\"\"\"\n\n# Funciones Simples\n\ndef greet():\n    print(\"Hola Dkp!\")\n\ngreet()\n\n# Con retorno\n\ndef return_greet():\n    return \"Hola Dkp2!\"\n\nprint(return_greet())\n\n# Con un argumento\n\ndef arg_greet(name):\n    print(f\"Hola {name}!\")\n\narg_greet(\"Perrito\")\n\n# Con argumentos\n\ndef args_greet(greet, name, name2):\n    print(f\"{greet} {name} y {name2}!\")\n\nargs_greet(\"Hola\",\"perrito\",\"gato\" )\n\n# Con un argumento predeterminado\n\ndef default_arg_greet(name = \"Conejo\"):\n    print(f\"Hola {name}!\")\n\ndefault_arg_greet(\"Perrito\")\ndefault_arg_greet()\n\n# Con argumentos, uno predeterminado y con cambios de posicion\n\ndef def_args_greet(greet, name, name2=\"conejo\"):\n    print(f\"{greet} {name} y {name2}!\")\n\ndef_args_greet(\"Hola\",\"perrito\")\ndef_args_greet(name2=\"gato\",name=\"perrito\",greet=\"Hola\")\n\n# Con argumentos y return\n\ndef return_arg_greet(greet,name):\n    return f\"{greet} {name}!!\"\n\nprint(return_arg_greet(name=\"conejo\",greet=\"Holaa\"))\n\n# Con retorno de varios valores\n\ndef multiple_return_greet():\n    return \"Hola\",\"perrito\"\n\ngreet, name = multiple_return_greet()\nprint(greet)\nprint(name)\n\n# Con un numero variable de argumentos\n\ndef variable_args_greet(*names):\n    for name in names:\n        print(f\"Hola {name}!!\")\n\nvariable_args_greet(\"Perrito\",\"Gato\",\"Conejo\",\"Tortuga\")\n\n# Con un numero variable de argumentos con palabra clave\n\ndef variable_key_args_greet(**names):\n    for key, value in names.items():\n        print(f\"Hola {value} eres un ({key})!!\")\n\nvariable_key_args_greet(\n    canino=\"Perrito\",\n    felino=\"Gato\",\n    roedor=\"Conejo\",\n    anfibio=\"Tortuga\"\n)\n\n\"\"\"\nFunciones dentro de funciones\n\"\"\"\n\ndef outer_function():\n    def inner_function():\n        print(\"Funcion interna\")\n    inner_function()\n    \nouter_function()\n\n\"\"\"\nFunciones dentro del lenguaje (built in)\n\"\"\"\n\nprint(\"Hola Dkp\")\nprint(len(\"Dkp\"))\nprint(type(\"Dkp\"))\nprint(type(29))\n\n\"\"\"\nVariables locales y globales\n\"\"\"\n\nglobal_variable = \"Globo\"\n\nprint(global_variable)\n\ndef greet():\n    local_var = \"Holaa\"\n    print(f\"{local_var} {global_variable}!!\")\n\ngreet()\n\nprint(\"Fin del ejercicio\")\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n\"\"\"\n\ndef extra(cadena1, cadena2) -> int:\n    contador = 0\n    for var in range(1,101):\n        if var % 3 == 0 and var % 5 == 0:\n            print(cadena1 + cadena2)\n        elif var % 3 == 0:\n            print(cadena1)\n        elif var % 5 == 0:\n            print(cadena2)\n        else:\n            print(var)\n            contador += 1\n    return contador\n\n\nprint(extra(\"Perro\",\"Gato\"))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/ElbaM.py",
    "content": "x='b'\n\ndef saludo (): \n    print (\"Hola, soy Elba\")\n    \n## con retorno\n\ndef retorno ():\n    return \"Hola, soy Elba con retorno\"    \n\nsaludo()\n# variableretornada= retorno()\nprint (retorno() )\n\n## con argumentos\n\ndef argumento (nombre):\n    return \"Hola, soy \" + nombre\n\nprint (argumento(\"Elba marina\"))\n\ndef argumento2 (accion, nombre):\n    return accion + \" soy \" + nombre\n\nprint (argumento2(\"Hello, \", \"Elba marina\"))\n\ndef pordefecto (nombre=\"Python\"):\n    return \"Hola, soy \" + nombre\n\nprint (pordefecto())\nprint (pordefecto(\"Elba marina\"))\n\nprint (argumento2(nombre=\"Hello, \", accion=\"Python\"))\n\n# retorno varias argumentos\n\ndef retorno2 (nombre, apellido):\n    print ( f\"{nombre}, {apellido} \" )\n    \n\n\nprint  (retorno2  (\"Elba\", \"Mujica\"))\n\n\ndef retorno3 ():\n    return ('python', 'clase3', 'funciones')\n\nlenguaje,nroc,tema=retorno3()\nprint (lenguaje)\nprint (nroc)\nprint (tema)\n\n\n# Funciones con numero variable de argumentos\n\ndef varios (*organiza):\n    for orga in organiza:\n        print (f\"{orga}\")\n\nvarios(\"GEMTE\", \"VNQ\", \"RED\")\n\n\n# Funciones con numero variable de argumentos con clave\n\ndef variosc (**organiza):\n    for key,orga in organiza.items():\n        print (f\" Hola {orga}({key})\")\n\nvariosc(trabajo=\"GEMTE\", contrata=\"VNQ\", segmento=\"RED\")\n\n\n# variables locales y globales\n\ndef pruebas ():\n      def interna ():\n         x=10\n         print (f' x local {x}') \n      interna()\n\n\npruebas () \nprint (x)\n\n\n# Dificultad Extra\n\ndef rutina (param1,param2):\n    for i in range(1, 101):\n        if (i % 3) == 0 and (i % 5) != 0:\n             print (f\" Es multiplo de  {param1} {i}\")\n        elif (i % 3) != 0 and (i % 5) == 0 :\n                print (f\" Es multiplo de  {param2} {i}\") \n        elif (i % 3) == 0 and (i % 5) == 0 :\n                print (f\" Es multiplo de  {param1} y {param2} {i}\")\n        else:\n            print (f\" Es otro numero {i}\")\n\n\nrutina(\"tres\", \"cinco\")                \n        "
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/EliasBonnin.py",
    "content": "# Ejercicio 02\n# En el siguiente URL https:/python.org Tenemos la documentacion de phyton.\n# Los retos se encuentran en https://retosdeprogramacion.com\n\n# Funciones\n\nmy_param = 10\ns_funcion = \"str\"\ns_funcion2 = 0\ns_funcion3 = 0\n\nf_variable = 0\nf_variable2 = \"str\"\nf_variable3 = 5\nf_variable4 = 12\n\n\ndef my_funcion():  # Funcion sin retorno\n    print(\"Mi funcion sin retorno\")\n\n\ndef my_funcion_con_parametro(my_param):  # Funcion con retorno\n    my_variable = 5\n    my_variable = my_variable + my_param\n    return my_param\n\n\ndef my_funcion_muchos_parametros(param_1, param_2, param_3):\n    my_variable1 = 5\n    my_variable2 = 10\n    my_variable3 = \"Muchos Parametros\"\n    my_variable2 = my_variable1 + param_1 - param_3 / param_2\n    return (my_variable2, my_variable3)\n\n\n# Llamado a funciones\n\nmy_funcion()  # Llamado a funcion sin retorno\n\nmy_variable = my_funcion_con_parametro(my_param)  # Llamado funcion con retorno\nprint(f\"Retorno de funcion con parametro {my_variable}\")\n\ns_funcion, s_funcion2 = my_funcion_muchos_parametros(\n    f_variable, f_variable3, f_variable4)\nprint(f\"Retorno funcion con parametros{s_funcion}{s_funcion2}\")\n\n# Funciones de phyton\n\n\n# Guardamos una \"funcion\" matematica en este ejemplo\ndef doble(x): return x * 2\n\n\nprint(doble(4))\n\n\ndef sumar(a, b): return a + b  # Mas de un parametro\n\n\nsumar_variable = sumar(2, 3)\nprint(sumar_variable)\n\nprint(\"funcion print\")  # Funcion print\n\nprint(f\"imprimimos el tipo usando type {type(sumar)}\")  # Funcion Type\n\nprint(f\"Devolvemos la longitud de la variable usando len = {len(f_variable2)}\")\n\nrange_list = list(range(1, 5))\n\nmy_list = list(range(6, 10))\n\n# Genera un rango de numeros en una lista\nprint(f\"Un rango de numeros usando range y list{range_list}\")\n\nnombres = ['Elias', 'Yoshi', 'Rodri']\nedad = [26, 23, 23]\n\nzip_list = zip(nombres, edad)  # Utilizamos 2 listas distinitas y las unificamos\nprint(f\"unificamos 2 listas diferentes utilizando zip {list(zip_list)}\")\n\nround_num = 3.3\nprint(f\"Hacemos un redondeo utilizando round  de 3.3 a {round(round_num)}\")\n\nabs_num = -4\n\n# Utilizamos abs para obtener el absoluto\n\nprint(f\"La funcion abs obtenemos el valor absoluto de -4 a {abs(abs_num)}\")\n\n# Funciones dentro de funciones\n\nvar_edad = 26.5\n\n\n# Recibe un parametro y le aplica otra funcion de redondeo y lo devuelve\n\ndef Array_nombres_edad(edad):\n    round_edad = round(edad)\n    return round_edad\n\n\nround_edad_print = Array_nombres_edad(var_edad)\n\nprint(round_edad_print)\n\n# Vemos el uso de la variable global\n\nvariable_global = 'Global'\n\n\ndef hola_global():\n    variable_local = 'Variable'\n    print(f'{variable_local} {variable_global}')\n\n# print(variable_local) no funciona porque la variable es local a la funcion\n\n\nhola_global()\n\n# Extra\n\n# Variables\n\nvar_char = 'Multiplo de 3'\nvar_char2 = 'Multiplo de 5'\n\n\ndef funcion_ejercicio(parametro1, parametro2) -> int:\n    cont = 0\n    concatenado = parametro1 + ' y ' + parametro2\n    for i in range(1, 101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(f\"{i} es {concatenado}\")\n        elif i % 5 == 0:\n            print(f\"{i}, es {parametro2}\")\n        elif i % 3 == 0:\n            print(f\"{i}, es {parametro1}\")\n        else:\n            print(i)\n            cont += 1\n    return cont\n\n\nprint(funcion_ejercicio(var_char, var_char2))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Eliskopun.py",
    "content": "# Funciones sin parametro ni retorno:\n\ndef saludar():\n    print(\"¡Hola comunidad!\")\n    \nsaludar() # funcion que impreme un saludo\n\ndef imprimir_numeros():\n    for i in range(1,6):\n        print(i)\n\nimprimir_numeros() # imprime numero del 1 al 5\n\n# Funcion con parametro\n\ndef saludo(nombre):\n    print(f\"¡Hola, {nombre}!\")\n\nsaludo(\"Bonifacio\") # saluda con un argumento\n\n# Funcion con parametros\n\ndef sumar(a, b):\n    resultado = a + b\n    print(f\"La suma {a} y {b} es {resultado}\")\n\nsumar(11, 28)\n\n# Funcion con parametros predeterminados\n\ndef informacion_personal(nombre = \"Desconocido\", edad = 0, cuidad= \"Desconocida\"):\n    print(f\"Nombre: {nombre}\")\n    print(f\"Edad: {edad}\")\n    print(f\"Cuidad: {cuidad}\")\n    \ninformacion_personal() # sin parametros imprime valores predeterminados\ninformacion_personal(\"Fridolina\") # con un parametro\ninformacion_personal(\"Fridolina\", 30) # con dos parametro\ninformacion_personal(\"Fridolina\", 30, \"Kungsbacka\") # con tres parametro\n\n# Funcion con retorno\n\ndef crear_saludo(nombre):\n    return f\"¡Hola, {nombre}!\"\n\nc_saludo = crear_saludo(\"Yonaiker\")\nprint(c_saludo)\n\n# Funcion con varios retornos\ndef mayor_y_menor(numeros):\n    mayor = max(numeros)\n    menor = min(numeros)\n    return mayor, menor\n\nnumeros = [11, 15, 18, 22, 25, 28]\nmayor, menor = mayor_y_menor(numeros)\nprint(\"El numero mayor: \",mayor)\nprint(\"El numero menor:\", menor)\n\n# Funcion con parametros y retorno\ndef sumar(a, b):\n    resultado = a + b\n    return resultado\n\nresultado_suma = sumar(11, 28)\nprint(\"El resultado de es:\", resultado_suma)\n\n# Funcion con parametros posionales variables\ndef saludo_variable(*nombres):\n    for nombre in nombres:\n        print(f\"¡Hola, {nombre}!\")\n\nsaludo_variable(\"Comunidad\", \"Bonifacio\", \"Frionilda\", \"Yonaiker\")\n\n# Funcion con parametros de palabra clave\ndef info_person_variable(**args):\n    for clave, valor in args.items():\n        print(f\"{clave}: {valor}\")\n\ninfo_person_variable(nombre = \"Bonifacio\", edad = 23)\n\ninfo_person_variable(nombre = \"Frionilda\", edad = 30, pais = \"Suecia\", equipo = \"FC Barcelona\")\n\n\n# Extra\n\ndef imprime_numeros (texto1, texto2):\n    contador = 0\n    for numero in range(1, 101):\n        if numero % 3 == 0 and numero % 5 == 0:\n            print(texto1 + texto2)\n            contador += 1\n        elif numero % 3 == 0:\n            print(texto1)\n            contador += 1\n        elif numero % 5 == 0:\n            print(texto2)\n            contador += 1\n        else:\n            print(numero)\n    return contador\n\nnro_veces = imprime_numeros (\"Fizz\", \"Buzz\")\nprint(\"El numero que se ha impreso el número en lugar de los textos es: \", nro_veces)"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/EmmanuelMMontesinos.py",
    "content": "\"\"\"\r\n * EJERCICIO:\r\n * x Crea ejemplos de funciones básicas que representen las diferentes\r\n *   posibilidades del lenguaje:\r\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\r\n * x Comprueba si puedes crear funciones dentro de funciones.\r\n * x Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\r\n * x Pon a prueba el concepto de variable LOCAL y GLOBAL.\r\n * x Debes hacer print por consola del resultado de todos los ejemplos.\r\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\r\n *\r\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\r\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\r\n */\r\n\"\"\"\r\n\r\n# Funciones\r\n\"\"\"Sin Parámetros ni Retorno\"\"\"\r\n\r\n\r\ndef funcion_1():\r\n    print(\"Esto es una función sin parámetros ni retorno\\n\")\r\n\r\n\r\nfuncion_1()\r\n\r\n\"\"\"Con uno o varios Parámetros\"\"\"\r\nparametro_1 = \"Parámetro 1\"\r\nparametro_2 = \"Parámetro 2\"\r\n\r\n\r\ndef funcion_2(param_1, param_2):\r\n    print(\r\n        f\"Esto es una función con uno o varios Parámetros sin retorno\\nParámetros:\\n{param_1}\\n{param_2}\\n\")\r\n\r\n\r\nfuncion_2(parametro_1, parametro_2)\r\n\r\n\"\"\"Con Retorno\"\"\"\r\n\r\n\r\ndef funcion_3():\r\n    return \"Esto es el retorno de funcion_3\"\r\n\r\n\r\nprint(f\"Esto es una función con retorno:\\n{funcion_3()}\\n\")\r\n\r\n\"\"\"Finciones dentro de funciones\"\"\"\r\n\r\n\r\ndef funcion_4():\r\n    print(\"funcion_4\\n\")\r\n    num_1 = 2\r\n    num_2 = 3\r\n\r\n    def funcion_5(num, num2):\r\n        print(\"funcion_5 dentro de la funcion_4\\n\")\r\n        return num + num2\r\n    num_3 = funcion_5(num_1, num_2)\r\n    return num_1 + num_2 + num_3\r\n\r\n\r\nprint(\r\n    f\"Esto es una función dentro de otra función:\\nResultado {funcion_4()}\\n\")\r\n\r\n\"\"\"Función ya creada en Python\"\"\"\r\nprint(\"Esto es una Funcíon ya creada en Python, ¿Es 1 un int):\\n\",\r\n      isinstance(1, int), \"\\n\")\r\n\r\n\"\"\"Variables Locales\"\"\"\r\nvariable = \"hola!\"\r\n\r\n\r\ndef funcion_6():\r\n    variable = \"Ni hao!\"\r\n    return variable\r\n\r\n\r\nprint(f\"Esto es una variable fuera de la función:\\n{variable}\")\r\nprint(\r\n    f\"Esto es una variable local con el mismo nombre que la de fuera:\\n{funcion_6()}\")\r\nprint(\r\n    f\"Sin modificar la variable existente fuera de la función:\\n{variable}\\n\")\r\n\r\n\"\"\"Varialbes Globales\"\"\"\r\nvariable = \"hola!\"\r\n\r\n\r\ndef funcion_7():\r\n    global variable\r\n    variable = \"Ni hao!\"\r\n    return variable\r\n\r\n\r\nprint(f\"Esto es una variable fuera de la función:\\n{variable}\")\r\nprint(f\"Esto es una variable global dentro de la función:\\n{funcion_7()}\")\r\nprint(f\"Esto es una variable fuera de la función despues:\\n{variable}\\n\")\r\n\r\n\"\"\"\r\n * DIFICULTAD EXTRA (opcional):\r\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\r\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\r\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\r\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\r\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\r\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\r\n\"\"\"\r\n\r\n\r\ndef funcion_8(text_1: str = \"Ping\", text_2: str = \"Pong\") -> int:\r\n    ciclo: int = 0\r\n    for num in range(1, 101):\r\n        if num % 3 == 0 and num % 5 == 0:\r\n            print(f\"{text_1} {text_2}\")\r\n        elif num % 3 == 0:\r\n            print(f\"{text_1}\")\r\n        elif num % 5 == 0:\r\n            print(f\"{text_2}\")\r\n        else:\r\n            print(num)\r\n            ciclo += 1\r\n    return ciclo\r\n\r\n\r\nprint(\r\n    f\"Número de veces que se ha impreso el número en lugar de los textos:\\n{funcion_8()}\")\r\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/EricJoel-code.py",
    "content": "# Funciones\n\n# Una función es un bloque de código reutilizable que realiza una tarea específica.\n# Se define usando la palabra clave 'def', seguida del nombre de la función y paréntesis.\n\n# Funciones definidas por el usuario\n\n# Simple\n\ndef saludar():\n    print(\"Hola, Python!\")\n    \nsaludar() # Llamada a la función\n\n# Funcion con retorno\n\ndef retorno():\n    return \"Hola, mundo!\"\n\nmensaje = retorno()\nprint(mensaje)\n\n# Función con parámetros\n\ndef sumar(a, b):\n    return a + b\n\nresultado = sumar(8, 9)\nprint(resultado)\n\n# Función con parámetros por defecto\n\ndef nuevo_saludo(nombre=\"Eric\"):\n    print(f\"Hola, {nombre}!\")\n    \nnuevo_saludo() # Usa el valor por defecto\nnuevo_saludo(\"Joel\") # Sobrescribe el valor por defecto\n\n# Funcion con retorno de varios valores\n\ndef operaciones(a, b):\n    suma = a + b\n    resta = a - b\n    return suma, resta\n\ns, r = operaciones(10, 5)\nprint(f\"Suma: {s}, Resta: {r}\")\n\n# Funciones con un numero variable de argumentos\n\ndef lista_nombres(*nombres):\n    for nombre in nombres:\n        print(nombre)\n        \nlista_nombres(\"Eric\", \"JoelDev\", \"Python\")\n\n# Funciones con un numero de argumentos con palabra clave\n\ndef info_persona(**info):\n    for clave, valor in info.items():\n        print(f\"{clave}: {valor}\")\n        \ninfo_persona(nombre=\"Eric\", edad=30, ciudad=\"Brasil\") \n\n# Funciones dentro de funciones\n\ndef externa():\n    def interna():\n        print(\"Funcion interna\")\n    interna()\n    \nexterna()\n\n# Funciones del lenguaje\n\nprint(len(\"Hola\")) # Devuelve la longitud de una cadena\nprint(type(123)) # Devuelve el tipo de dato\nprint(isinstance(123, int)) # Verifica si un objeto es de un tipo específico\nprint(dir([])) # Devuelve los atributos y métodos de un objeto\nprint(help(str)) # Muestra la documentación de un objeto\nprint(abs(-10)) # Devuelve el valor absoluto\nprint(round(3.14159, 2)) # Redondea un número a un número específico de decimales\nprint(max(1, 5, 3)) # Devuelve el valor máximo\nprint(min(1, 5, 3)) # Devuelve el valor mínimo\nprint(sum([1, 2, 3, 4, 5])) # Suma los elementos de un iterable\nprint(sorted([3, 1, 4, 2])) # Devuelve una lista ordenada\nprint(reversed([1, 2, 3])) # Devuelve un iterador que invierte un iterable\nprint(enumerate(['a', 'b', 'c'])) # Devuelve un objeto enumerado\n\nprint(\"joel\".upper()) # Convierte a mayúsculas\nprint(\"JOEL\".lower()) # Convierte a minúsculas\nprint(\"  hola  \".strip()) # Elimina espacios en blanco al inicio y final\nprint(\"hola mundo\".replace(\"mundo\", \"Python\")) # Reemplaza una subcadena\nprint(\"hola mundo\".split()) # Divide una cadena en una lista\nprint(\" \".join([\"Hola\", \"Python\"])) # Une una lista en una cadena \nprint(chr(65)) # Convierte un código ASCII a un carácter\nprint(ord('A')) # Convierte un carácter a su código ASCII\nprint(bin(10)) # Convierte un número a binario\nprint(hex(255)) # Convierte un número a hexadecimal\nprint(oct(8)) # Convierte un número a octal\n\n# Variable local y global\n\na = \"global\"\n\ndef funcion():\n    b = \"local\"\n    print(a) # Accede a la variable global\n    print(f\"{a},{b}\") # Accede a la variable global y local \n    \nfuncion()\n\nprint(a) # Accede a la variable global, se puede acceder desde fuera de la funcion\n#print(b) # Error, b es una variable local, no se puede accerder desde fuera de la funcion\n\n# Extra\n\ndef ejemplo(a, b) -> int:\n    contador = 0\n    for number in range(1, 101):\n        if number % 3 == 0 and number % 5 == 0:\n            print(a + b)\n        elif number % 5 == 0:\n            print(b)\n        elif number % 3 == 0:\n            print(a)\n        else:\n            print(number)\n            contador += 1\n    return contador\n\nprint(ejemplo(\"team\",\"seal\"))\n\n\n    "
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/EspinoLeandroo.py",
    "content": "# Función sin parámetros ni retorno\ndef saludar():\n    print(\"¡Hola! Esta es una función de saludo.\")\n\n# Función con parámetros y retorno\ndef suma(a, b):\n    return a + b\n\n# Función con parámetros predeterminados\ndef saludar(nombre=\"Mundo\"):\n    print(\"¡Hola,\", nombre + \"!\")\n\n# Función con retorno múltiple\ndef operaciones(a, b):\n    suma = a + b\n    resta = a - b\n    multiplicacion = a * b\n    division = a / b\n    return suma, resta, multiplicacion, division\n\n# Función que utiliza una función interna\ndef externa():\n    def interna():\n        print(\"Esta es una función interna.\")\n    interna()\n\n# Variable global\nvariable_global = 10\n\n# Función que utiliza una variable global\ndef funcion():\n    variable_local = 5\n    print(\"Variable local dentro de la función:\", variable_local)\n    print(\"Variable global dentro de la función:\", variable_global)\n\n# Llamada a las funciones\nsaludar()\nresultado = suma(3, 5)\nprint(\"La suma es:\", resultado)\nsaludar(\"Juan\")\nresultados = operaciones(10, 5)\nprint(\"Resultados:\", resultados)\nexterna()\nfuncion()\nprint(\"Variable global fuera de la función:\", variable_global)\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/ExanderGuitar.py",
    "content": "# Reto 02 - Funciones y alcance\nfrom builtins import print, len, type, range, str\n\n# Funcion sin parametros y llamada a funcion\n\ndef arrancar_moto():\n    print(\"Kikiki, chak, broooooom broom\")\n\narrancar_moto()\n\n# Funcion con parametros y llamada a funcion\n\ndef seguridad_moto(guantes, casco):\n    if(guantes and casco):\n        print(\"Listo para salir.\")\n\nseguridad_moto(True, True)\n\n# Funcion con parametros, valor de retorno y llamada a funcion\n\ndef tiempo_ruta(distancia, velocidad):\n    return distancia / velocidad\n\nprint(tiempo_ruta(150, 89.5))\n\n# Funcion dentro de funcion\n\ndef numero_favorito(numero):\n\n    def repetir_numero_favorito(veces):\n        return (numero * veces)\n    \n    print(f'Tu numero favorito {numero} repetido varias veces es ' + str(repetir_numero_favorito(numero)))\n\nnumero_favorito(49)\n\n# Funciones existentes\nflag = True\nprint(type(flag))\n\nmensaje = \"Mi moto funciona muy bien.\"\nprint(len(mensaje))\nprint(mensaje.lower())\nprint(mensaje.upper())\nx = range(0, 11)\nprint(x)\n\n# Variables locales y globales\nvariable_global = \"Soy una variable global.\"\n\ndef caja_de_variables():\n    variable_local = \"Soy una variable local.\"\n    print(variable_global)\n    print(variable_local)\n\ncaja_de_variables()\n\n# Ejercicio extra\ndef imprimeNumeros(texto1, texto2):\n    numero = 0\n    \n    for i in range(1, 101):\n        if(i % 3 == 0 and i % 5 == 0):\n            print(texto1 + texto2)\n        elif(i % 3 == 0):\n            print(texto1)\n        elif(i % 5 == 0):\n            print(texto2)\n        else:\n            print(i)\n            numero += 1\n\n    return numero\n\na = imprimeNumeros(\"Mult3\", \"Mult5\")\nprint(a)"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/FabianRpv.py",
    "content": "#Funciones\n\ndef sin_parametro_ni_retorno():\n    print(\"Funcion sin Parametros ni Retorno\")\n\nsin_parametro_ni_retorno()\n\ndef con_parametros(nombre):\n    print(f\"Mi nombre es {nombre}\")\n\nmi_nombre = \"Fabian\"\n\ncon_parametros(mi_nombre)\n\ndef con_retorno(nombre, apellido):\n    return f\"Mi nombre completo es {nombre} {apellido}\"\n\nmi_apellido = \"Petit\"\n\nprint(con_retorno(mi_nombre, mi_apellido))\n\n\n#Funcion dentro de una funcion\n\ndef funcion_externa():\n    print(\"Esta es la funcion externa\")\n\n    def funcion_interna():\n        print(\"Esta es la funcion Interna\")\n\n    funcion_interna()\n\n\nfuncion_externa()\n\n# Funciones lambda (anonimas)\n\ncuadrado = lambda x: x**2\n\nprint(cuadrado(4))\n\n# Variables locales y globales\n\nvariable_global = \"Esta es una variable Global\"\n\ndef var_locales_globales():\n    local = \"Esta es una variable local\"\n    print(local)\n\nvar_locales_globales()\n\nprint(variable_global)\n# print(variable_local) No existe fuera de la funcion\n\n\n\n# Ejercicio:\n\ndef mi_funcion(string1, string2):\n\n    contador = 0\n\n    for number in range(101):\n\n\n        if(number % 3 == 0 and number % 5 == 0):\n            print(string1 + \" \" + string2)\n\n        elif(number % 3 == 0):\n            print(string1)\n        \n        elif(number % 5 == 0):\n            print(string2)\n\n        else:\n            print(number)\n            contador += 1\n\n    return contador\n\n\nstr1 = \"Primer Texto\"\nstr2 = \"Segundo Texto\"\n        \ncontador = mi_funcion(str1, str2)\n\n\nprint(f\"El numero se ha impreso {contador} veces\")\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/FedeAirala.py",
    "content": "# Reto #02 FUNCIONES Y ALCANCE\n\n\"\"\" * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n\"\"\"\n \n# Una función en Python es un bloque de líneas de código o un conjunto de instrucciones \n# que se utilizan para realizar una tarea específica. Puede reutilizarse cuando se lo requiera. \n# Las funciones nos ayudan a que el código sea más fácil de leer y entender.\n\n# Creando funciones: para ello se utiliza la palabra reservada def seguido del nombre que desee utilizar.\n\n# Función sin parámetros ni retorno.\n\ndef funcion():\n    print (\"Esto es una función\")   # Esta función realiza un print por terminal.\nfuncion()                           # Llamada de la función para su ejecución.\n\n# Función con un parámtero\n\ndef parametro (texto1):\n    print (texto1)\nparametro(\"Función con parámetro\")\n\n# Función con varios parámetros\n\ndef suma (a,b):\n    print (f\"La suma es:{a+b}\") \nsuma(10,5)\n\ndef concatenar(texto1,texto2):\n    print (texto1 + texto2)\nconcatenar (\"Hola\", \" Python\")\n\n# Función con retorno\n\ndef retorno(a,b):\n    suma = a+b\n    return suma \nprint (retorno (5,6))\n\n# Funciones dentro de funciones\n\ndef funcion1():\n    def funcion2():\n        print (\"Función 2 dentro de otra función 1\")\n    funcion2()\nfuncion1()    \n\n# Funciones creadas por el lenguaje\n\nprint (f\"La función len devuelve el tamaño de una cadena. Tamaño de Hola Python!: {len('Hola Python!')}\")\n\n# Variable Local\n\nvar_local = \"Variable local fuera de la función\"\ndef var():\n    var_local = \"Variable Local dentro de la función\"\n    print (var_local)\nprint (var_local)\nvar()\n\n# Variable Global\n\nvar_global = \"Variable global fuera de la función\"\ndef var_g():\n    global var_global\n    var_global = \"Variable global dentro de la función cambia la exterior\"\n    print (var_global)\nprint (var_global)\nvar_g()\n        \n# Dificultad extra\n\ndef dificultad_extra (texto1,texto2):\n    num_veces=0\n    \n    for i in range (1,101):\n\n        if i%3 == 0 and i%5== 0:\n            print  (f\"Textos concatenados en posición {i}: {texto1+texto2}\")\n        elif i%3 == 0 :\n            print (f\"Posición {i}: {texto1}\")\n        elif i%5 == 0:\n            print (f\"Posición {i}: {texto2}\")\n        else:\n            print (f\"A este número no le corresponde texto: {i}\")\n            num_veces += 1\n    return print (f\" El número de veces que no se ecribió un texto fue: {num_veces}\")\n\ndificultad_extra(\"Hola\",\" Python\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Fernando-Antoni0.py",
    "content": "'''\n Crea ejemplos de funciones básicas que representen las diferentes\n posibilidades del lenguaje:\n Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n'''\n\n#Funcion basica\ndef suma():\n    print(1 + 4)\n\nsuma()\n\n#De retorno\n\ndef resta():\n    return 5 - 2\n\nresultado = resta()\nprint(resultado)\n\n#Con un argumento\n\ndef multiplicacion1(num1):\n    print(5 * num1)\n\nmultiplicacion1(2)\n\n#Con argumentos\n\ndef multiplicacion2(num2, num3):\n    print(num2 * num3)\n\nmultiplicacion2(3, 2)\n\n#Con argumento predeterminado\n\ndef division(num4 = 5):\n    print(10 / num4)\n\ndivision(2)\ndivision()\n\n#Con argumentos y retorno\n\ndef suma2(num5, num6):\n    return num5 + num6\n\nprint(suma2(2, 2))\n\n#Con un argumento pero variable\n\ndef resta2(*num7): #El * indica que resibira varios argumentos\n    for i in num7:\n        print(10 - i)\n\nresta2(2, 5, 7, 8, 1)\n\n\n'''\n DIFICULTAD EXTRA (opcional):\n Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n'''\n\ndef cadTexto(text1, text2) -> str:\n    for i in range(1, 101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(f\"{text1}{text2}\")\n        elif i % 3 == 0:\n            print(f\"{text1}\")\n        elif i % 5 == 0:\n            print(f\"{text2}\")\n        else:\n            print(i)\n            i += 1\n    return i\n\ncadTexto(\"Fizz\", \"Buzz\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Franz-Arzapalo.py",
    "content": "\"\"\"\nEJERCICIO: #02 FUNCIONES Y ALCANCE\n\n- Crea ejemplos de funciones básicas que representen las diferentes\n  posibilidades del lenguaje:\n  Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n- Comprueba si puedes crear funciones dentro de funciones.\n- Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n- Pon a prueba el concepto de variable LOCAL y GLOBAL.\n- Debes hacer print por consola del resultado de todos los ejemplos.\n  (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n  DIFICULTAD EXTRA (opcional):\n  Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n- La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n- Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n- Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n- Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n- La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\n  Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n  Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n\"\"\"\n\n# 1. Crea ejemplos de funciones básicas que representen las diferentes\n#    posibilidades del lenguaje:\n#    Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n\n\"\"\"\nAntes de definir una funcion podemos recapitular de forma que en retos anteriores vimos funciones nativas como range() o como bin()\ny es eso las funciones nativas son las funciones que ya estan en python de forma determinada o preinstalada pero nosotros tambien \npodemos crear nuestras propias funciones con el comando def para definir la funcion esto nos pedira un nombre para la funcion y de forma\nopcional un parametro que ira entre parentesis terminando con los dos puntos para pasar a definir la accion que se ejecutara.\n\"\"\"\n\n# Definir una funcion basica sin parametros con \"def\":\n\ndef ejemplo ():\n    print(\"Ejemplo\")\n\n# para usar la funcion se tiene que nombrar y usar el parentesis.:\n\nejemplo()\n\n# Definir una funcion basica con parametro:\n\ndef ejemplo1 (lenguaje):\n    print (f\"Hola, {lenguaje}!\")\n\nejemplo1(\"Python\")\n\n# Hasta ahora estas funciones no tenian retorno pero se podian ver resultados gracias a la funcion print().\n\n# Definir una funcion basica con parametro y retorno.\n\ndef ejemplo2 (Nombre):\n    return f\"Hola {Nombre}\"\n\nprint(ejemplo2(\"Franz\"))    \n\n# A simple vista no parece relevante este cambio pero es por la necesidad de imprimir el cambio para verlo en la consola.\n# Las funciones nos sirven para ahorra timepo y codigo pues cunado vamas a repetir las mismas acciones con cambios puntuales\n# el tener una funcion para automatizar esos cambios es bastante util.\n# Return sirve especificamente para sacar el resultado de la funcion de dentro de la funcion no la imprime pero ahi esta.\n\n# Definir una funcion basica con mas de un parametro y retorno:\n\ndef ejemplo3 (Lenguaje, Nombre):\n    return f\"Hola {Nombre}, {Lenguaje} es increible!\"\n\nprint(ejemplo3(\"Python\", \"Franz\"))\n\n# De esta forma podemos poner mas parametros en la funcion.\n# El orden en el que se definen los parametros son el mismo orden en el que se tienen que ingresar dichos parametros para su uso correcto.\n\n# Asignar valores predeterminados a los parametros de una funcion:\n\ndef ejemplo4 (numero=\", no ingreso un numero\"):\n    return f\"Su numero es {numero}\"\n\nprint(ejemplo4())\n\n# De esta forma si no se ingresa parametros en la funcion se ejecutara con el valor definido si esto no se hace y se ejecuta una funcion\n# sin parametros aparecera un error en la consola y se dentra la ejecucion de todo codigo que le siga.\n\n# Definir una funcion con mas de un retorno:\n\ndef ejemplo5 ():\n    return \"uno\", \"dos\"\n\nnumero1, numero2 = ejemplo5()\n\nprint(numero1)\nprint(numero2)\n\n# Definiendo las variables separadas por comas se podra separar mas de un valor que retorne una funcion.\n\n# Podemos tambien hacer funciones que utilicen el mismo parametro pero que se introduscan mas variables para ese parametro:\n\ndef ejemplo6 (*names):\n    for name in names:\n        print(f\"¡Hola, {name}!\")\n    print(type(names))\nejemplo6(\"Python\", \"Franz\", \"Erick\", \"Arzapalo\")\n\n# Con el bucle for podemos separar una gran cantidad de valores que se pongan en un parametro.\n# Pero lo mas importante es el * puesto antes del parametro esto combierte los valores que se ingrese en un grupo de valores conocido\n# como tuplas esto varia en otros leguajes pero en python es una herramienta muy util.(Esto es conocido como *args refiriendose a arguments)\n\n# Ahora el siguiente nivel del tipo de funcion anterior es crear un funcion con un palabra clave y un valor de la misma forma con\n# una cantidad de valores variables para el parametro.\n\ndef ejemplo7 (**names):\n    for keys, value in names.items():\n        print(f\"{keys}, ({value}!)\")\nejemplo7(lenguaje=\"Python\", name=\"Franz\", numero=14, serie=\"the office\", pelicula=\"harry potter\")\n\n# En el bucle usamos .items() para poder acceder a los valores de cada clave porque cuando se trabaja con diccionarios de no usar el items\n# solo se trabajaria con las claves pero como se trabaja con esta es bastante util el tener un valor como con las tuplas pero ahora el\n# tener cada valor un nombre nos facilita de gran manera trabajar de otra forma esto simplifica el trabajo.\n\n# Comentarios en funciones:\ndef comentada ():\n    \"\"\"\n    Esta es una funcion que se usara como ejemplo para demostrar lo \n    importante y util que puede ser comentar una funcion de esta forma.\n    \"\"\"\n    return \"Funcion comentada\"\n\nhelp(comentada)\nprint(comentada.__doc__)\n\n# De esta forma se llama al comentario dentro de un funcio y si esta ha sido comentada con su funcion apoyara de gran manera a otra \n# persona que quiera leer el codigo osea es una buena practica el comentar las funciones de esta forma.\n\n# Anotacion en funciones:\n\ndef ejemplo8 (x:int) -> int:\n    return x*5\nprint(ejemplo8(\"Franz\"))\n\n# De esta forma se anota en un funcion el tipo de parametro que se quiere o se necesita para el correcto funcionamiento de la funcion\n# pero solo lo hacer notar como se dice no afecta ni inpone esa regla por ello ne no cumplirse y la funcio puede funcionar sin\n# la necesidad de se cumpla la notacion se ejecutara de forma normal.\n\n# 2. Comprueba si puedes crear funciones dentro de funciones.\n\n\"\"\"\nEn python se pueden crear funciones dentro de otras funciones la principal caracteristica de estas funcion son que no funcionan afuera\nde la funcion en la que fureron definidas son como funciones temporales.\n\"\"\"\n\ndef funcion_mayor ():\n    def funcion_menor ():\n        print(\"Esta es la funcion menor\")\n    print(\"Esta es la funcion mayor\")\n    funcion_menor()\nfuncion_mayor()\n\n# funcion_menor() # No la reconoce porque fue llamada fuera de la funcion principal.\n\n# 3. Utiliza algún ejemplo de funciones ya creadas en el lenguaje (built-in).\n\n# https://docs.python.org/es/3.8/library/functions.html \n# Documentacion de funciones nativas python.\n\n\"\"\"\nBuilt-in o tambien conocidas como funciones nativas son funciones definidas o preinstaladas en el lenguaje en este caso python,\nson muchas pero muy utiles solo veremos 3:\n\"\"\"\n\nprint(len(\"Franz\")) # 5\n# len hace un conteo de objetos en este caso el numero de letras.\n# Nos puede ayudar por ejemplo para saber el numero de iteraciones que podriamos tener usando el bucle for.\n# Ojo solo funciona con grupos de obejtos como el bucle for no con integers o floats.\n\nprint(type(x:=3+4j)) # <class 'complex'\n# Type retorna el tipo de variable que se le ingresa en este caso complex por que es un numero complejo.\n# Nos puede ayudar mas cuando no sabemos de que tipo es una variable talvez que no encontras definida o que no sabemos como termina despues de una operacion.\n\nprint(\"python\".upper()) # PYTHON\n# upper() convierte todos los caracteres de una cadena de texto a mayusculas.\n# Solo puede trabajar con strings.\n\n# 4. Pon a prueba el concepto de variable LOCAL y GLOBAL.\n\nVariable_global = \"Global\"\n\ndef ejemplo9 ():\n    Variable_local= \"Local\"\n    print(f\"Variable globa ({Variable_global}), Variable local ({Variable_local})\")\n\nprint(Variable_global)\n# print(Variable_local) no se puede llamar fuera de la funcion\n\nejemplo9()\n\n# 5. Debes hacer print por consola del resultado de todos los ejemplos.\n#  (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades) (cumplida)\n\n# 6. Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n#   - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n#   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n#   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n#   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n#   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\ndef FizzBuzz (Cadena1, Cadena2):\n    count=0\n    for n in range(1, 101):\n        if n % 3 == 0 and n % 5 == 0:\n            print(Cadena1+Cadena2)\n        elif n % 3 == 0:\n            print(Cadena1)\n        elif n % 5 == 0:\n            print(Cadena2)\n        else:\n            print(n)\n            count+=1\n    return(count)\n\nprint(FizzBuzz(\"Fizz\", \"Buzz\")) \n\n# Fin."
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/GaboDev23.py",
    "content": "''' \n- Crea ejemplos de funciones básicas que representen las diferentes\nposibilidades del lenguaje:\nSin parámetros ni retorno, con uno o varios parámetros, con retorno...\n'''\n# Funciones sin parámetros, ni retorno\ndef sinParametrosSinRetorno():\n    print('Esto es una función sin parámetros, ni retorno')\n    \nsinParametrosSinRetorno()\n\n# Funciones con parámetros y sin retorno\ndef conParametrosSinRetorno(text):\n    print(text)\n    \nconParametrosSinRetorno('Esto es una función con parámetros y sin retorno')\n\n# Funciones sin parámetros y con retorno\ndef sinParametrosConRetrno():\n    return 'Esto es una función sin parámetros y con retorno'\n\nprint(sinParametrosConRetrno())\n\n# Funciones con parámetros y con retorno\ndef conParametrosConRetorno(text = 'Esto es un texto por defecto'):\n    return text\n\n# Función con parámetro por defecto\nprint(conParametrosConRetorno('Esto es una función con parámetros y con retorno'))\nprint(conParametrosConRetorno())\n\n# Función con más de un parámetro\ndef saludo (nombre = 'Joe', saludo = 'hi'):\n    return f'{saludo} {nombre}'\n\nprint(saludo('Gabriel', 'Hola'))\nprint(saludo())\n\n# Función con número indefinido de parámetros\ndef numeros (*numeros):\n    return numeros\n\nprint(numeros(2, 4, 6, 8, 10))\n\n''' \n- Comprueba si puedes crear funciones dentro de funciones. \n'''\n\ndef funcion ():\n    def funcion_dentro_otra ():\n        return 'Si se puede jaja'\n    \n    return funcion_dentro_otra();\n    \nprint(funcion())\n\n''' - Utiliza algún ejemplo de funciones ya creadas en el lenguaje. '''\n\n# print() es una función de python\nprint('Imprimo algo')\n\n# Valor absoluto de un número\nprint(f'El valor absoluto de -1 es {abs(-1)}')\n\ntexto = 'Hola que tal me llamo Gabriel'\n\n# Tamaño de un texto\nprint(f'El tamaño del texto: \"{texto}\" es de {len(texto)} carácteres')\n\n# Tipo de una variable\nprint(f'El tipo de la variable con el valor: \"{texto}\" es {type(texto)}')\n\n# Texto en mayúscula\nprint(f'Ahora si imprimimos ese texto en mayúsculas quedaría: \"{texto.upper()}\"')\n\n'''\n- Pon a prueba el concepto de variable LOCAL y GLOBAL.\n'''\nvar_global = 29 # Variable global, se puede acceder en cualquier parte del programa\n\ndef funcion ():\n    var_local = 31 # Variable local, se puede acceder solo en esta función\n    print(var_local) # Se imprime correctamente\n    \nprint(var_global) # Se imprime correctamente\nfuncion()\n# print(var_local) # Ocurre un error\n\n'''\nDIFICULTAD EXTRA\nCrea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n- La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n- Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n- Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n- Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n- La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n'''\n\ndef print_numbers (texto1, texto2):\n    cont = 0\n    for i in range (1, 101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(f'{i}. {texto1}, {texto2}')\n        elif i % 3 == 0:\n            print(f'{i}. {texto1}')\n        elif i % 5 == 0:\n            print(f'{i}. {texto2}')\n        else:\n            print(i)\n            cont += 1\n        \n    return f'Fueron {cont} veces que se imprimió sólo un número'\n    \nprint(print_numbers('Estoy comiendo', 'En un restaurante'))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Gabriel-DAngelo.py",
    "content": "'''\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n '''\n \n \n#Función sin parámetros\ndef HolaMundo():\n    print(\"Hola mundo\")\n\n\nprint(HolaMundo())\n\n\n\n#Con uno parámetro\ndef MostrarNumero(num1):\n    print(num1)\n    \nprint(MostrarNumero(7))\n\n\n\n##Con varios parámetros\ndef sumarNumeros(num1, num2 , num3):\n    print(num1 + num2+ num3)\n\nprint(sumarNumeros(3,5,7))\n\n\n\n#Función con retorno\ndef Multiplicar(num1,num2,num3):\n    return num1 * num2 * num3\n\nprint(Multiplicar(2,4,5))\n\n\n\n#Funciones dentro de funciones\nprint(\"Funciónes anidadas\")\ndef funcionAnidada(n1, n2):\n    \n    def Anidada():\n        print(\"La multiplicación de \", n1, \"y\", n2, \"es..\", n1*n2)\n        \n    return n1 / n2\n\nresultado = funcionAnidada(5,7)\nprint(resultado)\n\n\n#Funciones propias de PYTHON \n#Usando la función Max():\ndef EncontrarMayor():\n    numeros=[3,5,6,8,]\n    return max(numeros)\n\nprint(\"numeros=[3,5,6,8,]\")\nprint(\"El mayor numero de la lista es :\", EncontrarMayor())\n\n\n#Variables locales y Globales en python\n\"\"\"\nEn Python las variables locales son las que se definen  \nen una función y que solo permiten su acceso desde ella.  \nLas globales se definen en el cuerpo principal \ndel programa y permiten su acceso desde cualquier lugar.   \nLas no locales son variables locales que se pueden modificar en funciones anidadas.\n\"\"\"\n\n\n\n#Dificultad Extra\ndef imprime(texto1 , texto2 ):\n    \n    for i in range(1,101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(texto1 + texto2)\n        elif i % 3 == 0:\n            print(texto1)\n        elif i % 5 == 0:\n            print(texto2)\n        else:\n            contador = 0\n            contador += 1\n    return print(\"Numero de veces que se imprime el numero y no el texto: \",contador)\n\n#llamada a la función \nprint(imprime(\"hello\", \"Python\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Gallitofast.py",
    "content": "# Ejemplo de función sin parámetros ni retorno\ndef saludar():\n    print(\"Hola, este es un saludo desde una función sin parámetros ni retorno.\")\n\n# Ejemplo de función con un parámetro\ndef saludar_persona(nombre):\n    print(f\"Hola, {nombre}, este es un saludo personalizado.\")\n\n# Ejemplo de función con varios parámetros\ndef sumar(a, b):\n    print(f\"La suma de {a} y {b} es {a + b}.\")\n\n# Ejemplo de función con retorno\ndef multiplicar(a, b):\n    return a * b\n\n# Ejemplo de función dentro de otra función\ndef funcion_externa():\n    print(\"Esta es la función externa.\")\n\n    def funcion_interna():\n        print(\"Esta es la función interna.\")\n    \n    funcion_interna()\n\n# Ejemplo de uso de una función ya creada en el lenguaje\ndef ejemplo_funcion_nativa():\n    numeros = [1, 2, 3, 4, 5]\n    print(f\"El máximo de la lista {numeros} es {max(numeros)}.\")\n\n# Ejemplo de variable LOCAL y GLOBAL\nglobal_variable = \"Soy una variable global\"\n\ndef ejemplo_variables():\n    local_variable = \"Soy una variable local\"\n    print(local_variable)\n    print(global_variable)\n\n# Llamadas a las funciones para mostrar los resultados\nsaludar()\nsaludar_persona(\"José\")\nsumar(3, 5)\nresultado = multiplicar(4, 6)\nprint(f\"El resultado de la multiplicación es {resultado}.\")\nfuncion_externa()\nejemplo_funcion_nativa()\nejemplo_variables()\n\n# Modificando la variable global\ndef modificar_global():\n    global global_variable\n    global_variable = \"He sido modificada desde una función\"\n    print(global_variable)\n\nmodificar_global()\n\n#dificultad extra\ndef fizzbuzzito():\n    for i in range(1,101):\n        if i %3==0 and i%5==0:\n            print(\"Fizzbucito\")\n        elif i%3==0:\n            print(\"Fizz\")\n        elif i%5==0:\n            print(\"Buzzito\")\n        else:\n            print(i)\nfizzbuzzito()\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Gordo-Master.py",
    "content": "\"\"\"\nFunciones definidas por el usuario\n\"\"\"\n\n# Simple\n\ndef greet():\n    print(\"¡Hola Python!\")\n\ngreet()\n\n# Con retorno\n\ndef return_greet() -> str:\n    return \"¡Hola, Python!\"\n\nprint(return_greet())\n\n# Con argumentos\n\ndef arg_greet(greet,name):\n    print(f\"{greet}, {name}!\")\n\narg_greet(\"Hello\",\"Gordo-Master\")\narg_greet(name=\"Gordo-Master\",greet=\"Hello\")\n\n# Con un argumento predeterminado\n\ndef default_arg_greet(name =\"Python\"):\n    print(f\"Hola {name}!\")\n\ndefault_arg_greet(\"Gordo-Master\")\ndefault_arg_greet()\n\n# Con argumento y return\n\ndef return_arg_greet(greet,name):\n    return f\"{greet}, {name}!\"\n\nprint(return_arg_greet(\"Hi\",\"Gordo-Master\"))\n\n# Con retorno de varios valores\n\ndef multiple_return_value():\n    return \"Hola\" , \"Python\"\n\ngreet, name = multiple_return_value()\nprint(greet)\nprint(name)\n\n# Con un número variable de argumentos\n\ndef variable_arg_greet(*names):\n    for name in names:\n        print(f\"Hola, {name}!\")\n\nvariable_arg_greet(\"Python\", \"Gordo-Master\", \"comunidad\")\n\n\n# Con un número variable de argumentos con palabra claves\n\n\ndef variable_key_arg_greet(**names):\n    for param, name in names.items():\n        print(f\"{name} ({param})!\")\n\nvariable_key_arg_greet(\n    language = \"Python\", \n    name = \"Gordo-Master\", \n    age = 29\n)\n\n\n\"\"\"\nFunciones dentro de funciones\n\"\"\"\n\ndef outer_funtion():\n    def inner_funtion():\n        print(f\"Función interna: Hola Python\")\n    inner_funtion()\n\n\nouter_funtion()\n\n\"\"\"\nFunciones del lenguaje (built-in)\n\"\"\"\n\nprint(len(\"Gordo-Master\"))\nprint(type(28))\nprint(\"Gordo-Master\".upper())\n\n\"\"\"\nVariable locales y globales\n\"\"\"\n\nglobal_var = \"Python\"\n\n\ndef hello_python():\n    local_var = \"Hola\"\n    print(f\"{local_var}, {global_var}\")\n\nprint(global_var)\n# print(local_var) No se puede acceder desde fuera de la función\n\nhello_python()\n\n\n\"\"\"Ejercicio Extra\"\"\"\n\ndef numbers_printer(text_1: str, text_2: str) -> int:\n    \n    number_count = 0\n\n    for i in range(1,101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(text_1 + text_2)\n        elif i % 3 == 0:\n            print(text_1)\n        elif i % 5 == 0:\n            print(text_2)\n        else:\n            print(i)\n            number_count += 1\n    \n    return number_count\n\nnum_count = numbers_printer(\"FIZZ\",\"BUZZ\")\nprint(f\"Cantidad de veces que salen numeros: {num_count}\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/H4cker0n.py",
    "content": "\"\"\"\nFUNCIONES DEFINIDAS POR EL USUARIO\n\"\"\"\n\n# SIMPLE\n\ndef vamos():\n    print(\"Vamos a aprender Python\")\n\n\n    vamos()\n# CON RETORNO   \ndef regresa():\n    return \"Vamos a aprender Python\"\n\nprint(regresa())\n\n#CON ARGUMENTOS\n\ndef saludar(nombre):\n    print(f\"Hola {nombre}, vamos a aprender Python\")\nsaludar(\"H4cker0n\")\n\n# CON ARGUMENTO PREDETERMINADO\ndef saludar(nombre=\"H4cker0n\"):\n    print(f\"Hola {nombre}, vamos a aprender Python\")\nsaludar()\n\n# CON ARGUNTOS Y RETORNO\n\ndef returno_saludo(nombre, mensaje):\n    return f\"Hola {nombre}, {mensaje}\"\nprint(returno_saludo(\"H4cker0n\", \"vamos a aprender Python\"))\n\n# Con retorno de varios valores\n\ndef returno_varios():\n    return \"H4cker0n\", \"hola a todos\"\n\nname, saludo = returno_varios()\nprint(name)\nprint(saludo)\n\n#FUNCIONES CON NUMERO VARIABLE DE ARGUMENTOS\n\ndef variable_argumentos(*args):\n    for arg in args:\n        print(f\"Hola {arg}!\")\n\nvariable_argumentos(\"H4cker0n\", \"Python\", \"Programación\")\n\n# FUNCIONES CON NUMERO VARIABLE DE ARGUMENTOS Y PALABRAS CLAVE\n\ndef variable_argumentos_palabras_clave(**productos):\n    for producto, marca in productos.items():\n        print(f\"El producto {producto} es {marca}.\")\n\nvariable_argumentos_palabras_clave(\n    ordenador=\"hp\", \n    movil=\"samsung\", \n    tablet=\"ipad\"\n    )\n\n\"\"\"\nFUNCIONES DENTRO DE OTRAS FUNCIONES\n\"\"\"\n\ndef funcion_externa():\n    def funcion_interna():\n        print (\"funcion externa: Hola Python!\")\n    funcion_interna()\n\nfuncion_externa()\n\n\"\"\"\nFUNCIONES DEL LENGUAJE (buit-in)\n\"\"\"\nprint(len(\"H4cker0n\"))  # Longitud de una cadena\nprint(sum([1, 2, 3, 4, 5]))  # Suma de una lista\nprint(max([1, 2, 3, 4, 5]))  # Máximo de una lista  \nprint(type(68))\n\n\"\"\"\nVARIABLES LOCALES Y GLOBALES\n\"\"\"\n# Variable global y local\n\nglobal_variable = \"Soy una variable global\"\n\nprint(global_variable)\n\ndef global_hello():\n    local_variable = \"hola\" \n    print(f\"{local_variable}, {global_variable}\")\nglobal_hello()\n\n\"\"\"\nEXTRA\n\"\"\"\n\ndef imprimir(cadena_1, cadena_2) -> int:\n    count = 0\n    for numero in range(1, 101):\n        if numero % 3 == 0 and numero % 5 == 0:\n            print(cadena_1 + cadena_2)\n        elif numero % 3 == 0:\n            print(cadena_1)\n        elif numero % 5 == 0:\n            print(cadena_2)\n\n        else:\n            print(numero)\n            count += 1\n    return count\n\nprint(imprimir(\"cadena 1\", \"cadena 2\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/HarrisonGuerrero18.py",
    "content": "import re, unicodedata\n\n# Variables globales\n\nopciones_si = [\"s\", \"si\"]\nopciones_no = [\"n\", \"no\"]\n\nwhile True:\n    nombre = input(\"Hola, ¿Cómo te llamas?: \").strip().title()\n    if nombre == \"\":\n        print(\"No puedes dejar el nombre vacío 🙃\")\n        continue\n    elif re.fullmatch(r\"[A-Za-zÁÉÍÓÚáéíóúÑñ\\s]+\", nombre):\n        break\n    else: \n        print(\"\\n❌ Debes ingresar un nombre válido\")\n        continue\n\n\"\"\"\n    Ejemplos básicos de funciones \n\"\"\"\n# Sin parámetros ni retorno \n\ndef saludar_basico()->str:\n    print(\nf\"\"\" \n¿Qué tal?, {nombre}, espero que el código de este archivo te agrade, consistirá en poner en practica todos los ejercicios planteados en el tercer reto de Mouredev. \nRecuerda que nunca dejamos de ser estudiantes en este rubro, pues no paramos de aprender.\n\"\"\")\nsaludar_basico()\n\n# Con un parámetro y retorno\n    \ndef quitar_tildes(texto)->str:\n    return ''.join(\n        c for c in unicodedata.normalize('NFD', texto)\n        if unicodedata.category(c) != 'Mn'\n    ) \n\n\"\"\"\n    Función dentro de función\n\"\"\"\n\ndef pedir_numeros()->float:\n    def sumar_numeros(*numeros):\n        suma = sum(float(num) for num in numeros)\n        return int(suma) if suma.is_integer() else suma\n\n    print(\nf\"\"\"\nBien, en este ejercicio te pediremos que digites al menos dos números para realizar sumas, pero podrás realizar la suma de todos los números que ingreses.\nEsta función contiene una subfunción que se encargará de realizar la suma.\n\"\"\")\n    \n    try:\n        while True:\n            respuesta = input(quitar_tildes(\"\\n¿Deseas proceder a sumar números? (en caso de que no, finalizará el programa). (s/n): \")).lower().strip()\n            \n            if respuesta in opciones_si:\n                print(\"Perfecto. Iniciando programa... 🖥️\")\n                lista_numeros = []\n                \n                while True:\n                    try:\n                        numero = float(input(\"\\nIngresa un número: \"))\n                        lista_numeros.append(numero)\n                    except ValueError:\n                        print(\"❌ Debes ingresar un número válido.\")\n                        continue\n                        \n                    if len(lista_numeros) >= 2:\n                            continuar = quitar_tildes(input(\"\\n¿Deseas sumar más números? (s/n): \")).lower().strip()\n                            if continuar in opciones_no:\n                                print(f\"\\n✅ La suma de los números que ingresaste es la siguiente: {sumar_numeros(*lista_numeros)}\")\n                                return\n                            elif continuar in opciones_si:\n                                continue\n                            else:\n                                print(\"\\n❌ Responde con 's' o 'n'.\")\n            elif respuesta in opciones_no:\n                print(f\"De acuerdo {nombre}, no sumaremos números 🥺\")\n                break\n            else:\n                print(\"\\n❌ Responde con 's' o 'n'.\")\n    except Exception as e:\n        print(f\"\\n⚠️ Ocurrió un error de la función principal: {e}\")    \n        \npedir_numeros()\n\n\"\"\"\n    Funciones propias del lenguaje (built-in)\n\"\"\"\n\nprint(f\"\"\"\\n\nEn esta sección veremos algunas funciones propias del lenguaje (built-in) de Python, no tienes que ingresar nada.\nPara que entindas mejor ve a la línea 180 del archivo.\n\"\"\"      \n)\n\nprint((len(\"\\nHola, estudiante\")))\nprint((type(3.14)))\nprint((str.upper(\"hola\")))\nprint((str.lower(\"HOLA\")))\n\n        \n\"\"\"\n    Ejercicio extra No.1 \n\"\"\"\n\n# Función con uno o varios parámetros (parámetro variable) y retorno\n\ndef imprimir_numeros(*textos)->int:\n    contador = 0\n    for numero in range(1,101):\n        if numero % 3 == 0 and numero % 5 == 0: \n            print(*textos)       \n        elif numero % 3 == 0:\n            print(textos[0])\n        elif numero % 5 == 0:\n            print(textos[1])\n        else:\n            print(numero)\n            contador+=1\n    return contador        \n\ndef pedir_textos():\n    print(\n    f\"\"\"\\n\nHola de nuevo {nombre}, este es el primero de 2 ejercicios extra que realizaremos.\n\nConsistirá en lo siguiente:\n\nEscribirás dos cadenas de texto y retornaremos un número.\n*   - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n*   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n*   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n*   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n*   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n    \"\"\"\n    )\n    \n    while True:\n        permiso = quitar_tildes(input(\"\\n¿Quieres iniciar el ejercicio? (s/n): \"))\n        \n        if permiso in opciones_si:\n            texto_1=input(\"\\nIngresa el primer texto: \")\n            texto_2=input(\"Ingresa el segundo texto: \")\n            return imprimir_numeros(texto_1, texto_2)\n        elif permiso in opciones_no:\n            print(\"\\n Okey, ejercicio finalizado 🥺🐒😭\")\n            break\n        else:\n            print(\"\\n❌ Debes responder con 's' o 'n'\")\n\npedir_textos()\n\n\"\"\"\n\n    Ejercicio extra No.2 (personal, no del reto)\n\"\"\"    \n\ndef obtener_nombres_amigos()->str:\n    print(f\"\\nGenial, ya casi llegamos al final {nombre}. En esta función saludaremos a todos tus amigos :D\")\n    while True:\n        respuesta = quitar_tildes(input(\"¿Nos permites obtener los nombres de tus amigos? (s/n): \")).lower().strip()\n       \n        if respuesta in opciones_si:\n            print(\"\\nPerfecto, ahora deberás escribir uno por uno el nombre de tus amigos\")\n            lista_amigos = []\n            i = 1\n            try:\n                while True:\n                    amigo = input(f\"\\nIngresa el nombre de tu amigo {i}: \").strip().title()\n                    if amigo == \"\":\n                        print(\"No puedes dejar el nombre vacío 🙃\")\n                        continue\n                    elif re.fullmatch(r\"[A-Za-zÁÉÍÓÚáéíóúÑñ\\s]+\", amigo):\n                        lista_amigos.append(amigo)\n                        i+=1\n                    else: \n                        print(\"\\nDebes ingresar un nombre válido\")\n                        continue\n                        \n                    continuar_ciclo = quitar_tildes(input(\"¿Deseas agregar más amigos? (s/n): \")).lower().strip()\n                    if continuar_ciclo in opciones_si:\n                        continue\n                    elif continuar_ciclo in opciones_no:\n                        saludar_amigos(*lista_amigos) \n                        return\n                    else:\n                        print(\"\\nDebes responder con 's' o 'n'\")\n            except Exception as e:\n                print(f\"\\nOcurrió un error: {e}\") \n        elif respuesta in opciones_no:\n                print(\"\\nVale, no saludaremos a tus amigos 😔\")\n                break\n        else:\n            print(\"\\nDebes responder con 's' o 'n'\")\n\ndef saludar_amigos(*nombres)->str:    \n    numero_amigos = len(nombres)\n    if numero_amigos >= 10:\n        print(f\"\\nWaos, {numero_amigos} son bastantes amigos.\")\n    elif numero_amigos >= 2:\n        print(f\"\\nTienes {numero_amigos} amigos, pocos pero seguramente de calidad.\")\n    else:\n        print(f\"\\nUn solo amigo, pero {nombres[0]} vale x1000\")      \n    for i, nombre in enumerate(nombres, start=1):\n        print(f\"{i}. ¡Hola, {nombre}!\")\n\nobtener_nombres_amigos()\n\ndef despedir(**datos)->str:\n    print(f\"\\nInteresante información, con esto damos por terminado este ejercicio, {datos['nombre']}, gracias por tu tiempo.\")\n\n    respuesta_positiva = False\n\n    while True:\n        respuesta = quitar_tildes(input(\"Para finalizar, ¿Te gustó probar mi código? (s/n): \")).lower().strip()\n        if respuesta in opciones_si:\n            respuesta_positiva = True\n            print(\"\\n¡Genial!\")\n            break\n        elif respuesta in opciones_no:\n            print(\"\\nUuh, eso dolió:(\")\n            break\n        else: \n            print(\"\\nTienes que escribir un valor correcto, gil.\")\n    \n    return print(f\"\"\"\nHasta luego {'amigo' if datos['genero'] == 'Masculino' else 'amiga'} {datos['nombre']},\nespero hayas tenido buenas experiencias con los {datos['edad']} años que has vivido.\n{'Me alegro que te haya gustado probar mi código 🥸, eso me motiva a seguir aprendiendo' \n    if respuesta_positiva \n    else 'Lamento que no te haya gustado probar mi código 😭, trabajaré en mi lógica'}\n¡Cuidate mucho!    \n    \"\"\")\n\ndef mostrar_informacion(**datos)->str:\n    print(f\"\\nOkey {nombre}, tus datos son los siguientes: \")\n    for clave, valor in datos.items():\n        if clave==\"genero\":\n            print(f\"Género: {valor}\")\n        else:\n            print(f\"{clave.capitalize()}: {valor}\")\n    return despedir(**datos)\n\ndef pedir_informacion()->str:\n    while True:\n        try:\n            edad = int(input(\"\\nIngresa tu edad: \"))\n            break\n        except ValueError:\n            print(\"Debes ingresar un número válido\")\n        \n    while True:\n        genero = input(\"\\nGénero (M/f): \").lower().strip()\n        if genero not in (\"m\", \"masculino\", \"f\", \"femenino\"):\n            print('Debes ingresar \"M\" o \"F\" para Masculino o Femenino')\n            continue\n        else:\n            if genero == \"m\" or genero == \"masculino\":\n                genero = \"Masculino\"\n            elif genero == \"f\" or \"femenino\":\n                genero = \"Femenino\"\n        break  \n    \n    informacion = {\n        \"nombre\": nombre,\n        \"edad\": edad,\n        \"genero\": genero \n    }\n    \n    return mostrar_informacion(**informacion)\n\ndef pedir_permisos():\n    while True:\n        print(f\"\"\"\\n\nMuy bien {nombre}, este es el último ejercicio, lo prometo 😅\nEn este ejercicio tendrás que ingresar tus datos personales\n        \"\"\")\n         \n        permiso = quitar_tildes(input(\"¿Estas de acuerdo en que tomemos tus datos personales? (s/n): \"))\n        if permiso in opciones_si:\n            pedir_informacion()\n            break\n        elif permiso in opciones_no:\n            print(\"\\nDe acuerdo. Fin de la función.\")\n            break  \n        else:\n            print(\"\\n❌ Debes responder con 's' o 'n'\")\npedir_permisos() "
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Hyromy.py",
    "content": "# funcion sin parametro ni retorno\ndef hola():\n    print(\"Hola ¿Como estas?\")\n\nhola()\n\n\n# funcion con parametro sin retorno\ndef saludo(nombre):\n    print(f\"Hola {nombre}, mucho gusto\")\n    \nsaludo(\"Hyromy\")\n\n\n# funcion sin parametro con retorno\ndef ping():\n    return \"Pong\"\n\nfuncion_ping = ping()\nprint(funcion_ping)\n\n\n# funcion con parametro y retorno\ndef es_par(numero):\n    if numero % 2 == 0:\n        return True\n    else:\n        return False\n    \nfuncion_es_par = es_par(9)\nprint(funcion_es_par)\n\n\n# funcion con varios parametros\ndef funcion(texto, repetir, mayuscula):\n    if mayuscula:\n        texto = str.upper(texto)\n        \n    for i in range(0, repetir):\n        print(texto)\n        \nfuncion(\"hola\", 4, True)\n\n\n# funcion con n cantidad de parametros\ndef suma(*n):\n    print(f\"Parametros ingresados: {len(n)}\")\n    print(f\"Resultado de la suma {sum(n)}\")\n    \nsuma(1, 2, 3, 4)\nsuma(10, 20, 30, 40 , 50 , 60 , 70, 80 , 90, 100)\n\n\n# funcion que retorna mas de un valor\ndef min_max(*numeros):\n    return min(numeros), max(numeros)\n# desempaquetado\nminimo, maximo = min_max(23, 54, 23, 987, 3, 321)\nprint(f\"Minimo: {minimo}, Maximo: {maximo}\")\n\n\n# funciones dentro de funciones\ndef funcion_A():\n    print(\"Esta es la funcion A\")\n    \ndef funcion_B():\n    funcion_A()\n    \n    print(\"Esta es la funcion B\")\n    \nfuncion_B()\n\n\n# funciones del lenguaje\nprint() # imprime texto en consola\nvariable = input(\"Este es un input, escribe algo para guardarlo en una variable => \")\nprint(type(variable)) # devuelve que tipo de dato es la variable\nprint(len([0, 1, 2, 3, 4])) # devuelve la cantidad de elementos que posee\nprint(range(5)) # genera una secuencia ascendente de numeros naturales (incluyendo el 0)\nprint(str(42)) # convierte a texto\nprint(int(\"12\")) # convierte a entero\nprint(float(\"54.32\")) # convierte a decimal\nprint(sorted([1,3,5,8,2,9,0,4,7,6])) # ordena los elementos de una lista\n\n\n# variables globales y locales\nvariable_global = 3.14159\n\ndef prueba():\n    variable_local = \"Cat\"\n    \n    print(f\"Global: {variable_global}\")\n    print(f\"Local: {variable_local}\")\nprueba()    \n\nprint(f\"Global: {variable_global}\")\n# variable no definida\n#print(f\"Local. {variable_local}\")\n\n\n# ---- DIFICULTAD EXTRA ----\n\ndef extra(texto_1, texto_2):\n    x = 0\n    \n    for i in range(1, 101):\n        if i % 3 == 0 and i % 5 == 0:\n            x += 1\n            print(texto_1 + texto_2)\n        elif i % 3 == 0:\n            x += 1\n            print(texto_1)\n        elif i % 5 == 0:\n            x += 1\n            print(texto_2)\n    else:\n        return x\n\nnumero = extra(\"algo\", \"seguro fue joel\")\nprint(numero)"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Irenetitor.py",
    "content": "#FUNCTIONS \n# 1. Function without parameters and without return\ndef greet():\n    print(\"Hello, World!\")\n\ngreet()  # Output: Hello, World!\n\n# 2. Function with parameters and without return\ndef greet_person(name):\n    print(f\"Hello, {name}!\")\ngreet_person(\"Maria\")  # Output: Hello, Maria!\ngreet_person(\"Juan\")   # Output: Hello, Juan!\n\n# 3. Function without parameters but with return\ndef get_greeting():\n    return \"Hello, World!\"\nmessage = get_greeting()\nprint(message)  # Output: Hello, World!\n\n# 4. Function with parameters and with return\ndef add(a, b):\n    return a + b\nresult = add(5, 3)\nprint(result)  # Output: 8\nresult = add(10, 20)\nprint(result)  # Output: 30\nresult = add(-1, 1)\nprint(result)  # Output: 0\n\n# 5. Function with default parameters\ndef greet_with_default(name=\"Guest\"):\n    print(f\"Hello, {name}!\")\ngreet_with_default()          # Output: Hello, Guest!\ngreet_with_default(\"Laura\")   # Output: Hello, Laura!\n\n# 6. Function with variable number of parameters\n\n#6.1 Using *args (positional arguments)\ndef sum_all(*args):\n    return sum(args)\ntotal = sum_all(1, 2, 3)\nprint(total)  # Output: 6\ntotal = sum_all(10, 20, 30, 40)\nprint(total)  # Output: 100\n\n#6.2 Using **kwargs (keyword arguments)\ndef print_info(**kwargs):\n    for key, value in kwargs.items():\n        print(f\"{key}: {value}\")\nprint_info(name=\"Rodrigo\", age=30, city=\"New York\")\n# Output:   name: Rodrigo\n#           age: 30 \n\n#7. Functions with returning multiple values\ndef get_coordinates():\n    return (10, 20) # returns a tuple\nx, y = get_coordinates()\nprint(f\"x: {x}, y: {y}\")  # Output: x: 10, y: 20\n\n#8. Lambda functions (anonymous functions)\nsquare = lambda x: x * x \nprint(square(5))  # Output: 25\nprint(square(10)) # Output: 100\n#------------------------------\ndouble = lambda x: x * 2\nprint(double(5))  # Output: 10\nprint(double(10)) # Output: 20\n#------------------------------\ntriple = lambda x: x * 3\nprint(triple(5))  # Output: 15\nprint(triple(10)) # Output: 30\n\n#9. Recursive functions\ndef factorial(n):\n    if n == 0 or n == 1:\n        return 1\n    else:\n        return n * factorial(n - 1) \nprint(factorial(5))  # Output: 120\nprint(factorial(0))  # Output: 1\nprint(factorial(1))  # Output: 1\nprint(factorial(6))  # Output: 720\n\n#2. We can create functions inside other functions using nested functions.\n#3.Example \ndef greet():\n    def greet_person(name):\n        print(f\"Hello, {name}!\")\n    print(\"Hello, World!\")\n    greet_person(\"Oliver\")\n\ngreet()\n# Output:   Hello, World!\n#           Hello, Oliver!\n\n#Example nested for calculation of area and perimeter of a rectangle\ndef rectangle_properties(length, width):\n    def area():\n        return length * width\n    def perimeter():\n        return 2 * (length + width)\n    return area(), perimeter()\narea, perimeter = rectangle_properties(5, 3)\nprint(f\"Area: {area}, Perimeter: {perimeter}\")\n# Output: Area: 15, Perimeter: 16\n\n#4. Scope of variables\n#Example of local and global scope  \nx = 10  # Global variable (available throughout the entire script)\ndef modify_variable():\n    x = 5  # Local variable (only exists while the function runs.)\n    print(f\"Inside function, x: {x}\")  # Output: Inside function, x: 5\nmodify_variable()\nprint(f\"Outside function, x: {x}\")  # Output: Outside function, x: 10\n\n#Example of using global keyword to modify global variable inside a function\ny = 20  # Global variable   \ndef modify_global_variable():\n    global y\n    y = 15  # Modifies the global variable\n    print(f\"Inside function, y: {y}\")  # Output: Inside function, y: 15\nmodify_global_variable()\nprint(f\"Outside function, y: {y}\")  # Output: Outside function, y: 15\n\n\n#Optional Challenge\n\ndef transform_string(str_input, str_input2):\n    for char in range(1, 101):\n        count = 0\n        if char % 3 == 0 and char % 5 == 0:\n            print(str_input + str_input2)\n        elif char % 3 == 0:\n            print(str_input)\n        elif char % 5 == 0:\n            print(str_input2)\n        else:\n            print(char)\n            count += 1\n    return count\n            \n            \n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Ivanpelu7.py",
    "content": "def exercise_extra(text1, text2) -> int:\n    count = 0\n    for number in range(1, 101):\n        if number % 3 == 0 and number % 5 == 0:\n            print(text1 + text2)\n        elif number % 3 == 0:\n            print(text1)\n        elif number % 5 == 0:\n            print(text2)\n        else:\n            count += 1\n\n    return count\n\nprint(exercise_extra(\"Hola\", \"Adios\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/JAFeito.py",
    "content": "#Solo la aprte de dificultad extra\nstream_1 = \"Multiplo de 3\"\nstream_2 = \"Multiplo de 5\"\ndef numeros(stream_1,stream_2):\n    cantidad = 0\n    for x in range(1,101):\n        if x % 3 == 0 :\n            if (x % 5 == 0):\n                print(stream_1 +\" y \"+ stream_2)\n            else:\n               print(stream_1)    \n        elif (x % 5 == 0):\n              print(stream_2)  \n\n        else:\n            cantidad +=1\n            print(x)\n    return cantidad\nprint(f\"Total de numeros inpresos: \", numeros(stream_1,stream_2))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/JAdraz.py",
    "content": "\"\"\"\nFunctions defined by user\n\"\"\"\n\n# Basic\ndef name():\n    print(\"My names is Jesus!\")\n\nname()\n\n# With return\ndef return_age():\n    return \"I am 27\"\n\nage =return_age()\nprint(age)\n\n# With 1 parameter\ndef greet_one(name):\n    print(f\"Hola, {name}!\")\n\ngreet_one(\"Jesus\")\n\n# With parameters\ndef greet_two(name, age):\n    print(f\"{name} and {age}\")\n\ngreet_two(\"Jesus\", \"27\")\n\n# With a predetermined parameter\ndef default_greet(name=\"Python\"):\n    print(f\"Hola, {name}\")\n\ndefault_greet()\ndefault_greet(\"Pedro\")\n\n# With positional argument\ndef greet_three(name, age):\n    print(f\"{name} and {age}\")\n\ngreet_three(name=\"Jesus\", age=\"27\")\n\n# With parameters and return\ndef greet_four(name, age):\n    return f\"{name} and {age}\"\n\nprint(greet_four(\"Pedro\", 30))\n\n# With several returns\ndef multiple_returns():\n    return \"Hi\", \"Python\"\n\nsaludo, nombre = multiple_returns()\nprint(saludo)\nprint(nombre)\n\n# With a variable number of parameters (Args)\ndef variable_arg_greet(*name):\n    for i in name:\n        print(f\"Hola, {i}\")\n\nvariable_arg_greet(\"Pedro\", \"Brais\", \"Jesus\")\n\n# With a variable number of parameters and keywords (Kwargs)\ndef variable_kwarg_greet(**name):\n    for key, value in name.items():\n        print(f\"({key}) {value}\")\n\nvariable_kwarg_greet(\n    language=\"English\", \n    name=\"Jesus\", \n    age=27, \n    alias=\"JAdraz\"\n)\n\n\"\"\"\nFunctions inside functions\n\"\"\"\n\ndef outer_functions():\n    def inner_function():\n        print(\"Inner function: Hello, World!\")\n    inner_function()\n\nouter_functions()\n\n\"\"\"\nBuilt-In Functions\n\"\"\"\n\nprint(\"Hello, World\")\nprint(len(\"Hello, World!\"))\nprint(sorted(\"987654321\"))\nprint(\"Jesus\".upper())\n\n\n\"\"\"\nLocal Scope\n\"\"\"\n\ndef myfunc():\n    x = 1500\n    print(x)\n\nmyfunc()\n\ndef myfunc2():\n    x = 2000\n    def myfunc3():\n        print(x)\n    myfunc3()\n\nmyfunc2()\n\n\"\"\"\nGlobal Scope\n\"\"\"\n\nx = 3000\n\ndef my_glob_func():\n    x = 4000\n    print(x)\n\nmy_glob_func()\nprint(x)\n\ndef my_glob_func2():\n    global x\n    print(x)\n\nmy_glob_func2()\nprint(x)\n\n\"\"\"\nExercise (Optional)\n\"\"\"\n\ndef func(text1=str, text2=str)-> int:\n    for i in range(1, 101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(text1 + text2)\n        elif i % 5 == 0:\n            print(text2)\n        elif i % 3 == 0:\n            print(text1)\n        print(i)\n\nfunc(\"Jesus\", \" Adraz\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/JacMac45.py",
    "content": "# Funciones definidas por el usuario\n\n# simple\ndef saludar():\n    print(\"Hola, soy una función simple\")\n\nsaludar()\n\n# con retorno\ndef saludar():\n    return \"Hola, soy una función con retorno\"\n\nprint(saludar())\n\n# con parámetros o argumentos\ndef saludar(name):\n    print(f\"Hola!! {name}\")\n\n\nsaludar(\"Python\")\n\n# con varios parámetros o argumentos y con retorno\ndef sumar(num1, num2):\n    return num1 + num2\n\nprint(sumar(1, 2))\n\n# con parámetros o argumentos por defecto\ndef saludar(name = \"Tito\"):\n    print(f\"Hola!! {name}\")\n\nsaludar()\nsaludar(\"Python\")\n\n# con retorno de múltiples valores\ndef sumar(num1, num2):\n    return num1 + num2, num1 - num2\n\nprint(sumar(1, 2))\n\n# con numero variable de parámetros o argumentos\ndef saludar(*names):\n    for name in names:\n        print(f\"Hola, {name}!\")\n\nsaludar(\"Python\", \"Java\", \"C++\")\n\n# con numero variable de parámetros o argumentos y con palabra clave ** \ndef saludar(**names):\n    for key, name in names.items():\n        print(f\"Hola, {name} ({key})!\")\n\nsaludar(\n    name1=\"Python\", \n    name2=\"Java\", \n    name3=\"C++\"\n    )\n\n# Funcines dentro de funciones\ndef saludar(name): # Función padre\n    def saludar2(name): # Función hija de la Función padre \n        return f\"Hola, {name}\"\n    return saludar2(name)\n\nprint(saludar(\"Python\"))\n\n# Funciones del lenguaje\nprint(\"\\n====== Funciones propias del lenguaje ======\")\n\nprint('print() --> es una funcion propia del lenguaje python') # Funcion para imprimir en la consola\nprint(f'len() funcion propia para obtener la longitud: {len(\"Hola\")}') # Funcion para obtener la longitud de una cadena\nprint(f'type() funcion propia para obtener el tipo de dato: {type(\"Hola\")}') # Funcion para obtener el tipo de dato de una variable\nprint(f'abs() funcion propia para obtener el valor absoluto: {abs(-5)}') # Funcion para obtener el valor absoluto de un numero\n\n# Variables Globales y Locales\nprint(\"\\n====== Variables Globales y Locales ======\")\n\nvariable_global = 'Variable global'\nprint(variable_global)\n\n\ndef variables():\n    variable_local = 'Variable local'\n    print(variable_global)  # Funciona porque es global\n    print(variable_local)   # Funciona porque esta dentro de la funcion donde fue creada\n    \nprint(variable_global)  # Funciona porque es global\n# print(variable_local)   # Error: variable_local no esta definida fuera de la funcion\n\n# Extra\nprint(\"\\n====== DIFICULTAD EXTRA ======\")\n\ndef numextra (string1, string2):\n    contador = 0\n    for num in range (1, 101):\n        \n        if num % 3 == 0 and num % 5 == 0:\n           print (string1 + string2)\n        elif num % 5 == 0:\n            print (string2)\n        elif num % 3 == 0:\n            print (string1)    \n        else:\n            print(num)\n            contador += 1\n        \n    print (f\"Los numeros han aparecido: {contador} veces\")    \n             \nnumextra (\"Hola\", \"Guapo\")   "
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Jackziel-Sumoza.py",
    "content": "# function without argument\ndef function():\n    pass\nfunction()\n\n# function with unique argument and without return\ndef function_1(name):\n    print(f\"Hello {name}\")\nfunction_1(\"World\")\n\n\n# function with two argument and one return\ndef function_2(name,lastname):\n    return f\"Hello {name} and hello {lastname}\"\nresult = function_2(\"world\",\"Python\")\nprint(result)\n\n# function multi-argument\ndef function_3(*num):\n    print(sum(num))\nfunction_3(1,2,3,4,5,6,7,8,9)\n\n# function with one default argument \ndef function_4(name=\"Python\"):\n    print(f\"Hello {name}\")\nfunction_4()\n\n# function key-value\ndef function_5(**values):\n    for key, value in values.items():\n        print(f\"The {key} is {value}\")\nfunction_5(name=\"Jackziel\",lastname=\"Sumoza\",age=\"?\")\n\n# function in function\ndef hello(name):\n    print(f\"hello {name}\")\n    def bye(name):\n        print(f\"see you soon {name}\")\n    bye(name)\nhello(\"World\")\n\n# native function\nprint(type(4.4))\n\n# local variable\ndef function_6():\n    local_var = \"Python\"\n    print(f\"Hello, {local_var}\")\n# print(local_var); error\nfunction_6()\n\n# global variable\nglobal_variable = \"This is a global variable\"\nprint(global_variable)\n\n# additional difficult\nprint()\ndef occurrence(text_1,text_2):\n    occurrence_num = 0\n    for num in range(1,101):\n        if num % 3 == 0:\n            print(text_1)\n        elif num % 5 == 0:\n            print(text_2)\n        elif num % 3 == 0 and num % 5 == 0:\n            print(text_1 + text_2)\n        else:\n            occurrence_num += 1\n            print(num)\n    return occurrence_num\n\nresult = occurrence(\"Hello\",\"Bye\")\nprint()\nprint(result)"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Jandresalvar.py",
    "content": "# Funciones básicas:\n\n# Sin parámetros ni retorno:\ndef saludar():\n    print('Hola, mundo!')\n\n# Con parámetros y retorno:\ndef saludar2(nombre):\n    return f'Hola, {nombre}'\n\n# Con múltiples parámetros:\ndef saludar3(nombre, idioma):\n    if idioma == 'es':\n        (print('Hola,', nombre))\n    elif idioma == 'en':\n        (print('Hello,', nombre))\n    elif idioma == 'pt':\n        (print('Olá', nombre))\n    elif idioma == 'fr':\n        (print('Bonjour', nombre))\n    else:\n         (print('Idioma no encontrado'))\n\n# Con parámetro predeterminado:\ndef saludar_python(idioma, nombre = 'Python'):\n    if idioma == 'es':\n        (print('Hola,', nombre))\n    elif idioma == 'en':\n        (print('Hello,', nombre))\n    elif idioma == 'pt':\n        (print('Olá', nombre))\n    elif idioma == 'fr':\n        (print('Bonjour', nombre))\n    else:\n         (print('Idioma no encontrado'))\n\n# Funciones dentro de funciones? 😎\n    \ndef teorema_pitagoras(a, b):\n    cuadrado = a**2 + b**2\n    def raiz(cuadrado):\n        return cuadrado ** (1/2)\n    return raiz(cuadrado)\n\n# Ejemplos de funciones ya creadas en python:\n\nprint(max('Retos de programacion'))\nprint('Retos de programacion'.count('o'))\n\n# Variables locales y globales:\nnum1 = 8\ndef adicion():\n    num2 = 16\n    return num1 + num2\n\nprint(adicion())\nprint(num1)\n# print(num2) # Error porque num2 solo se define en la instancia de la funcion y no se puede acceder a su valor por fuera de esta\n\n# Ejercicio Opcional\n\ndef ejercicio_extra(string1, string2):\n    \n    cuenta = 0\n\n    for num in range(1,101):\n        \n        if num % 3 == 0 and num % 5 == 0:\n            print(f'{string1}{string2}')\n        elif num % 3 == 0: \n            print(string1)\n        elif num % 5 == 0:\n            print(string2)\n        else: \n            print(num)\n            cuenta+= 1\n    \n    return cuenta\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Jav-mol.py",
    "content": "\" --- Funciones --- \"\n\n# Funcion sin parametros ni retornos\ndef funcion_simple():\n    print('Esta es una funcion simle')\n    \nfuncion_simple()\n\n# Funcion con parametros\ndef saludar(nombre: str):\n    print(f\"Hola, me llamo {nombre}\")\n\nsaludar('Javier')\n\n# Funcion con varios parametros\ndef saludar2(nombre: str, edad: int):\n    print(f\"Hola, mi nombre es {nombre} y tengo {edad} años\")\n\nsaludar2('Javier', 22)\n\n# Funcion con retorno\n\ndef sumar(n1: int, n2: int) -> int:\n    return n1 + n2\n\nresultado = sumar(4,2)\nprint(resultado)\n\n# Pasando una lista como argumento\ndef lenguajes(lista: list):\n    for lenguaje in lista:\n        print(f'Es un lenguaje de programacion: {lenguaje}')\n\nlenguajes([\"JavaScript\", \"Java\", \"Php\", \"Python\", \"Go\"])\n\n# Parámetros arbitrarios, *args\ndef ultimaPersona(*personas):\n    print(f\"La última persona que vino fue {personas[-1]}\")\n\nultimaPersona('Javier', 'Valentina', 'Nicolas', 'Camila')\n\n# Parámetros arbitrarios con keyword\ndef datos_personales(**datos):\n    print(f\"Nombre: {datos['nombre']} - Edad: {datos['edad']} - Pais: {datos['pais']}\")\n    \ndatos_personales(\n    nombre = 'Javier',\n    edad = 22,\n    pais = 'Argentina'\n)\n\n# Funciones dentro de funciones\n\n\n\n# Funciones del lenguaje\nprint(len(\"Argentina\"))\nprint(type(2.34))\nprint(\"JavierMolina\".upper())\n\n# Variables locales y globales debtro de funciones\nvariable_global = 'Variable Global'\n\ndef variables():\n    variable_local = 'Variable Local'\n    def other_function():\n        variable_local2 = 'Other Function'\n        print(f\"{variable_global} - {variable_local} - {variable_local2}\")\n    \n    return other_function()\n        \n#print(variable_global, variable_local, variable_local2) No se pueden imprimir las variables locales      \n        \nvariables()\n\n\"\"\" --- EJERCICIO EXTRA --- \"\"\"\n\ndef mi_funcion(text_1: str, text_2: str) -> int:\n    \n    num_impresos = 0\n    for num in range(101):\n        if num % 3 == 0 and num % 5 == 0:\n            print(f\"Numero: {num} - {text_1} - {text_2}\")\n        \n        elif num % 3 == 0:\n            print(f\"Numero: {num} - {text_1}\")\n\n        elif num % 5 == 0:\n            print(f\"Numero: {num} - {text_2}\")\n        \n        else:\n            num_impresos += 1\n            print(num)\n    return f\"Los numeros se han impreso: {num_impresos} veces\"\n\nprint(mi_funcion('Mult-3','Mult-5')) "
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/JesusAntonioEEscamilla.py",
    "content": "# #02 - Python -> Jesus Antonio Escamilla\n\n\"\"\"\nEJERCIÓ\n\"\"\"\n#Variable Global\nglobal_variable = \"Soy Global\"\n\n# Función Simple\ndef saludo():\n    print('¡¡Hola, Soy Jesus!!')\nsaludo()\n\n# Función con Parámetro\ndef personalizar_Saludo(nombre):\n    print(f\"¡¡Hola, Mundo soy {nombre}!!\")\npersonalizar_Saludo(\"Antonio\")\n\n# Función varios Parámetros\ndef suma(a, b):\n    print(f\"La suma de {a} y {b} es de {a + b}\")\nsuma(5, 6)\n\n# Función con Retorno\ndef multiplicar(a, b):\n    return a * b\nresultado = multiplicar(3, 4)\nprint(f\"El resultado de la multiplicación es {resultado}\")\n\n# Función dentro de otra Función\ndef compleja(x, y):\n    def restar(a, b):\n        return a - b\n    def dividir(a, b):\n        if(b != 0):\n            return b / a\n    resta = restar(x, y)\n    residuo = dividir(y, x)\n    return resta, residuo\nresta, residuo = compleja(8,4)\nprint(f\"La resta es {resta} y el residuo es {residuo}\")\n\n# Variables Globales y Locales\ndef my_function():\n    local_variable = \"Soy Local\"\n    print(local_variable)\n    print(global_variable)\nmy_function()\n\n\n\n\"\"\"\nEXTRA\n\"\"\"\ndef extra(text1, text2) -> int:\n    cont = 0\n    for number in range(1, 101):\n        if number % 3 == 0 and number % 5 == 0:\n            print(text1)\n        elif number % 3 == 0:\n            print(text2)\n        elif number % 5 == 0:\n            print(text1 + text2)\n        else:\n            print(number)\n            cont +=1\n    return print(f\"Las veces que aparece las letras {cont}\")\n\nextra(\"FIZZ\",\"BUZZ\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/JheisonQuiroga.py",
    "content": "# Funciones\n\n# 1. Funciones sin parámetros\n\ndef add_two_numbers():\n    n1 = 10\n    n2 = 12\n    print(\"El resultado de la suma es: \", n1 + n2)\n\nadd_two_numbers()\n\n# 1.1 Con uno, dos y varios parametros\n\ndef square_number(num):\n    square = num * num\n    print(square)\n\nsquare_number(10)\n\ndef mult(n1, n2):\n    result = n1 * n2\n    print(result)\n\n# 1.2 Retornando un valor\n\ndef hello_world():\n    return f\"Hello, World\"\n\nhello = hello_world() # Se guarda el valor de retorno (string) en una variable\nprint(hello)\n\n# 1.3 Retornando varios valores\n\ndef love_number():\n    first_n = 6\n    second_n = 9\n    return first_n, second_n\n\nprint(love_number()) # (6, 9)\nfirst_n, second_n = love_number()\nprint(str(first_n) + str(second_n))\n\n# 1.4 Numero variable o arbitrario de parámetros\n\ndef square_numbers(*numbers): # argumentos posicionales\n    lst_numbers = [num ** 2 for num in numbers]\n    return lst_numbers\n\nprint(square_numbers(2, 4, 6, 8, 10))\n\n# Keywords argument\n# Numero variable de argumentos por palabras clave\ndef unpaking(**names):\n    for key, value in names.items():\n        print(key, value)\n\nunpaking(\n    name = \"Duban\",\n    last_name = \"Quiroga\",\n    skills = [\"Python\", \"Git\"],\n    age = 25\n)\n\n# 2. Funciones dentro de funciones\n\ndef out_function():\n    def inner_function():\n        print(\"Hola Mundito\")\n    inner_function()\n\nout_function()\n\n\"\"\"\n 3. Funciones integradas del sistema (built - in)\n\n\"\"\"\n\nmy_string = \"Hello world\"\nprint(len(my_string)) # Se obtiene el largo de mi cadena (11 carácteres)\n\n#Funcion type()\nprint(type(my_string)) # <class 'str'>\n\n\nfv_fruits = [\"banana\", \"pineaple\", \"watermelon\", \"strawberry\"]\n\nfor i, fruit in enumerate(fv_fruits): # Funcion enumerate: Se obtiene una lista indexada de indice-valor\n    print(i + 1, fruit)\n\n\"\"\"\n4. Prueba de scope global y local\n\"\"\"\n\ngravity = 9.8\n\ndef object_weight():\n    global gravity\n\n    mass = 70\n    gravity = 10\n    weight = mass * gravity\n    print(weight)\n\nobject_weight()\nprint(gravity) # Sin la palabra reservada GLOBAL, deberia ser 9.8\n\n\"\"\"\nExtra\n\"\"\"\n\n#Funcion que recibe dos cadenas de texto y retorne un numero\n\ndef fizzbuzz(n1, n2) -> int:\n    count = 0\n    for n in range(1, 101):\n        if n % 3 == 0 and n % 5 == 0:\n            print(n1 + n2)\n        elif n % 3 == 0:\n            print(n1)\n        elif n % 5 == 0:\n            print(n2)\n        else:\n            count += 1\n            print(n)\n    return count\n\nnumber = fizzbuzz(\"Fizz\", \"Buzz\")\nprint(number)"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/JhonMarin12.py",
    "content": "# En este archivo trabajaremos con funciones\n# La forma basica de definir una funcione es:\ndef nombre_funcion(parametro1):\n    #hacer funcion\n    return None #Retornar un valor\n\n# Funcion si parametros\ndef saludar():\n    return \"Hola, como estas?\"\n\n# Funcion con un parametro\ndef saludo_personalizado(nombre:str):\n    return f\"Hola {nombre.capitalize()}, como estas?\"\n\nprint(saludo_personalizado('Jhon'))\n\ndef saludo_edad(nombre:str, edad:int):\n    return f\"Hola, mi nombres {nombre}, tengo {edad} años\"\n\n# Se pueden usar funciones dentro de funciones?\ndef funcion_externa(a:float, b:float):\n    def funcion_interna(c:float):\n        return c ** 2\n    return a * funcion_interna(b)\n\nprint(funcion_externa(2,2))\n\n# Tambien es aplicable para hacer recursividad, sin embargo este concepto trata de que usamos la misma funcion para obtener algun rasultado, sin necesidad de una funcion interna\n\n#factorial\ndef factorial(n:int):\n    if n > 0:\n        if n == 0 or n == 1:\n            return 1\n        else:\n            return n * factorial(n-1)\n    else:\n        return None\n    \nprint(factorial(5))\n\n#Funciones integradas en python:\nlength = len('Hola como estas?')\n# funciones para hacer casting float(), list(), int(), str()\nmax(12,4,1)\nmin(12,51,1)\n#Existen muchas...\n\n# Scope de las funciones    \nvariable_global = 10\ndef operacion():\n    variable_local = 5\n    return variable_global - variable_local\n\n# Ejercicio opcional\ndef FizzBuzz(a='Fizz', b='Buzz'):\n    contador = 0\n    for i in range(0,101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(f\"{i} - {a}{b}\")\n        elif i % 3 == 0:\n            print(f\"{i} - {a}\")\n        elif i%5 == 0:\n            f\"{i} - {b}\"\n        else:\n            contador += 1\n    return contador\n\nprint(FizzBuzz())"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/JorgeGarcia-Dev.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\"\"\"\n\nprint(\"*****FUNCIONES SIN VALOR DE RETORNO*****\")\n\n\ndef non_return_function():\n    \"\"\"\n    Imprime un mensaje que indica que esta es una función sin parámetros o valores de retorno.\n    \"\"\"\n    print(\"Esta es una función sin parámetros ni valores de retorno\\n\")\n\n\nnon_return_function()\n\nprint(\"*****FUNCIONES CON PARÁMETROS Y SIN VALOR DE RETORNO*****\")\n\n\ndef function_with_parameters(parameter1, parameter2):\n    \"\"\"\n    Una función que toma dos parámetros e imprime una cadena formateada.\n\n    Parámetros:\n        parámetro1 (any): el primer parámetro.\n        parámetro2 (any): el segundo parámetro.\n\n    Devoluciones:\n        Ninguno\n    \"\"\"\n    print(\n        \"Esta es una función con parámetros sin retorno: %s\" % parameter1\n        + \" \"\n        + parameter2\n        + \"\\n\"\n    )\n\n\nfunction_with_parameters(\"Hello\", \"World\")\n\n\nprint(\"*****FUNCIONES CON PARÁMETROS Y VALOR DE RETORNO*****\")\n\n\ndef function_with_return(parameter1, parameter2):\n    \"\"\"\n    Esta función toma dos parámetros y devuelve una cadena.Concatena los valores de `parámetro1` y` parámetro2` con un espacio intermedio,\n    y agrega un carácter de nueva línea al final.Luego se devuelve la cadena resultante.\n\n    : parámetro de parámetro1: el primer parámetro de la función.\n    : parámetro de parámetro2: el segundo parámetro de la función.\n    : return: una cadena que contiene los valores concatenados de `parámetro1` y` parámetro2`, seguido de un carácter nuevo.\n    \"\"\"\n    return (\n        \"Esta es una función con parámetros y retorno: %s\" % parameter1\n        + \" \"\n        + parameter2\n        + \"\\n\"\n    )\n\n\nprint(function_with_return(\"Hello\", \"World\"))\n\nprint(\"*****FUNCIONES CON PARÁMETROS POR DEFECTO Y VALOR DE RETORNO*****\")\n\n\ndef function_with_default_parameters(parameter1, parameter2=\"World\"):\n    \"\"\"\n    Una función con parámetros predeterminados y una declaración de retorno.\n\n    Args:\n        Parámetro1: el primer parámetro de la función.\n        Parámetro2: el segundo parámetro de la función.El valor predeterminado es \"Mundo\".\n\n    Devoluciones:\n        Una cadena que combina los valores del parámetro1 y el parámetro2.\n    \"\"\"\n    return (\n        \"Esta es una función con parámetros por defecto y retorno: %s\" % parameter1\n        + \" \"\n        + parameter2\n        + \"\\n\"\n    )\n\n\nprint(function_with_default_parameters(\"Hello\"))\n\nprint(\"*****FUNCIONES DENTRO DE FUNCIONES*****\")\n\n\ndef function_inside_function():\n    print(\"Esta es la función principal\")\n\n    def function_inside():\n        \"\"\"\n        Esta función imprime un mensaje que indica que es la función dentro de la función principal.\n        \"\"\"\n        print(\"Esta es la función dentro de la función principal\\n\")\n\n    function_inside()\n\n\nfunction_inside_function()\n\nprint(\"*****FUNCIONES YA CREADAS*****\")\n\nprint(f\"La función min() devuelve el número menor: {min(2, 4)}\")\nprint(f\"La función max() devuelve el número mayor: {max(2, 4)}\\n\")\n\nprint(\"*****VARIABLES LOCALES Y GLOBALES*****\")\n\nvariable_global = \"Soy una variable global.\\n\"\n\n\ndef function_variable_local():\n    \"\"\"\n    Esta función define una variable local llamada `variable_local` e imprime su valor.\n    También trata de imprimir una variable global llamada `variable_global`,\n    suponiendo que se define en otra parte del código.\n\n    Parámetros:\n    Ninguno\n\n    Devoluciones:\n    Ninguno\n    \"\"\"\n    variable_local = \"Soy una variable local.\"\n    print(variable_local)\n    print(variable_global)\n\n\nfunction_variable_local()\n\nprint(\"*****DIFICULTAD EXTRA*****\")\n\n\ndef dif_extra(texto1, texto2):\n    \"\"\"\n    Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n\n    Parameters:\n        texto1 (str): La primera cadena de texto.\n        texto2 (str): La segunda cadena de texto.\n\n    Returns:\n        None\n\n    Description:\n        Esta función recibe dos cadenas de texto como parámetros y realiza las siguientes operaciones:\n        - Si un número es múltiplo de 3, imprime la cadena de texto del primer parámetro.\n        - Si un número es múltiplo de 5, imprime la cadena de texto del segundo parámetro.\n        - Si un número es múltiplo de 3 y de 5, imprime las dos cadenas de texto concatenadas.\n        - Si un número no es múltiplo de 3 ni de 5, imprime que el número no le corresponde texto.\n        Al final, la función imprime el número de veces que se ha impreso el número en lugar de los textos.\n\n    Note:\n        Esta función no retorna ningún valor, simplemente imprime los resultados.\n    \"\"\"\n    veces = 0\n\n    for num in range(1, 101):\n        if num % 3 == 0:\n            print(f\"Posición {num}: {texto1}\")\n        elif num % 5 == 0:\n            print(f\"Posición {num}: {texto2}\")\n        elif num % 3 == 0 and num % 5 == 0:\n            print(f\"Cadenas de texto concatenadas en {num}: {texto1 + texto2}\")\n        else:\n            print(f\"Al numero {num} no le corresponde texto.\")\n            veces += 1\n    return print(f\"Veces que se ha impreso el numero en lugar del texto: {veces}\")\n\n\ndif_extra(\"Dificultad\", \"extra\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Jose-Luis-Lanza.py",
    "content": "# EJERCICIO:\n# - Crea ejemplos de funciones básicas que representen las diferentes posibilidades del lenguaje:\n# Sin parámetros ni retorno:\n\ndef saludo():\n    print(\"Hello, World!\")\n\nsaludo()\n\n# Con uno o varios parámetros:\n\n# Con un parametro:\ndef saludo_personal(mi_nombre):\n    print(\"Hola mi nombre es:\", mi_nombre)\n\nsaludo_personal(\"Jose Luis\")\n\n# Con varios parametros:\n\ndef area_triangulo(base, altura):\n    area = (base * altura)/2\n    print(\"El area del triangulo es igual a:\", area)\n\narea_triangulo(3, 4)\n\n# con retorno:\ndef main():\n    n = int(input(\"Ingrese un número: \"))\n    if par(n):\n        print(\"El número es par!\")\n    else:\n        print(\"El número es impar!\")\n\ndef par(numero):\n    if numero % 2 == 0:\n        return True\nmain()\n\n# - Comprueba si puedes crear funciones dentro de funciones.\n\ndef main():\n    nombre = input(\"Ingrese su nombre: \")\n    apellido = input(\"Ingrese su apellido: \")\n\n    def nombre_completo(nom, ape):\n        print(\"Un gusto conocerte\", nom, ape)\n\n    nombre_completo(nombre, apellido)\n\nmain()\n\n# Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n# Funcion round(number, ndigits=None)\n\nnumber = 17.159753\nprint(\"El numbero redondeado con 2 digitos es: \", round(number, 2))\n\n# Pon a prueba el concepto de variable LOCAL y GLOBAL.\n\"\"\"\nUna variable \"GLOBAL\" es la que se encuentra fuera de una funcion, la misma puede ser usada por otras funciones\ndefinidas en el programa. En cambio una funcion \"LOCAL\" esta definida dentro de una funcion especifica y solo\npuede ser usada por dicha funcion, esta variable \"LOCAL\" no puede ser utilizada por otras funciones en el programa.\n\"\"\"\nx = \"espectacular\"\n\ndef mi_funcion():\n  y = \"fantastico\"\n  print(\"Python es \" + y)\n\nmi_funcion()\n\nprint(\"Python es \" + x) # Si yo quisiera utilizar la variable \"y\" que fue definida en la funcion \"mi_funcion\" en este print(), obtendria un error: \"NameError: name 'y' is not defined\",\n                        # lo que nos indica que las variables locales solamente pueden ser utilizadas dentro de las funciones donde fueron definidas.\n\n#DIFICULTAD EXTRA (opcional):\n# Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n# - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n# - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n# - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n# - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n# - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\ndef function_numbers(string_1, string_2):\n    count = 0\n    for number in range(1, 101):\n        if number % 3 == 0 and number % 5 == 0:\n            print(string_1 + string_2)\n\n        elif number % 3 == 0:\n            print(string_1)\n\n        elif number % 5 == 0:\n            print(string_2)\n\n        else:\n            print(number)\n            count += 1\n    return count\n\nprint(function_numbers(\"cat\", \"dog\"))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/JoseAlberto13.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n\"\"\"\n# Funciones definidas por el usuario\n\n# Simple\ndef saludo():\n    print(\"Hola! Soy una función simple\")\n\nsaludo()\n\n\n# Con retorno\ndef return_saludo():\n        return \"Hola, Función con retorno\"\n\nprint(return_saludo())\n\n\n# Con un argumento\ndef arg_saludo(nombre):\n      print(f\"Hola, {nombre}!\")\n    \narg_saludo(\"José Alberto\")\n\n\n# Con varios argumentos\ndef arg_personal(nombre, edad, sexo, nacionalidad):\n      print(f\"Nombre: {nombre}. Edad: {edad}. Sexo: {sexo}. Nacionalidad: {nacionalidad}\")\n    \narg_personal(\"José\", 26, \"Masculino\", \"Venezolana\")\n\n\n# Con un argumento predeterminado (si es que no se diera el argumento del parámetro)\ndef default_arg_saludo(nombre=\"Usuario\"):\n      print(f\"Bienvenido, {nombre}!\")\n\ndefault_arg_saludo()\ndefault_arg_saludo(\"Figueroa\")\n\n\n# Con argumentos y return\ndef args_return(saludo, persona):\n      return f\"{saludo}, {persona}\"\n\nprint(args_return(\"Hola!\",\"José A.\"))\n\n\n# Con retorno de valores separados\ndef multiple_return_saludo():\n      return \"Hola\", \"Python\"\n\nsaludo, name = multiple_return_saludo()\nprint(saludo)\nprint(name)\n\n\n# Con un número variable de argumentos\ndef variable_arg_saludo(*nombres):\n      for nombres in nombres:\n            print(f\"Hola, {nombres}!\")\n\nvariable_arg_saludo(\"Mundo\", \"Python\", \"Git\", \"José\", \"MoureDev\")\n\n\n# Con un número variable de argumentos con palabra clave\ndef variable_key_arg(**nombres):\n      for key, value in nombres.items():\n            print(f\"{key}: '{value}'\")\n\nvariable_key_arg(\n      lenguaje = \"Python\",\n      nombre = \"José\",\n      ocupacion = \"Estudiante\",\n      alias = \"JoseAlberto13\",\n      años = 26\n)\n\n\n# Funciones dentro de Funciones\ndef outer_function():\n      def inner_function():\n            print(\"inner function: Función dentro de la función\")\n      inner_function()\n\nouter_function()\n\n\n# Funciones dentro del lenguaje\nprint(len(\"José\"))\nprint(type(25.5))\nprint(sorted({4,2,7,1,5,6,3}))\n\n\n# Variables locales y globales\nvariable_global = \"Esto es global!\"\nprint(variable_global)\n\ndef conVaribale_Global():\n      variable_local = \"Esto es local!\"\n      print(f\"Funciónes: local={variable_local} global={variable_global}\")\n\nconVaribale_Global()\n\nprint(variable_global)\n# print(variable_local) no funciona fuera de la funcion definida\n\n\n\"\"\"\nDIFICULTAD EXTRA\n\"\"\"\n\ndef lafuncion(texto1, texto2) -> int:\n      count = 0\n      for i in range(1,101):\n            if i % 5 == 0 and i % 3 == 0:\n                  print(texto1 + texto2)\n            elif i % 3 == 0:\n                  print(texto1)\n            elif i % 5 == 0:\n                  print(texto2)\n            else:\n                  print(i)\n                  count += 1\n      return count\n\nprint(lafuncion(\"Texto #1\",\"Texto #2\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/JuanDAW37.py",
    "content": "\"\"\"\n* EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\"\"\"\n\n# Función sin parámetros ni retorno\ndef func1():\n    print('¡Hola Python!')\nfunc1()\n\n# Función con parámetros, pero sin retorno\ndef func2(a, b):\n    print(a + b)\nfunc2(3,5)\n\n# Función con un parámetro y retorno\ndef func3(parametro):\n    return parametro * 2\nprint(func3(3))\n\n# Función con varios parámetros y retorno\ndef func4(parametro1, parametro2):\n    return parametro1 + parametro2\nprint(func4(3,5))\n\n# Función con parámetros, indicando el tipo de dato de cada uno y el tipo de dato que retorna\ndef func5(parametro1:int, parametro2:int)->int:\n    return parametro1 + parametro2\n\n# Función dentro de otra función\ndef func6():\n    def func7():\n        print('¡Hola Python!')\n    func7()\nfunc6()\n\n# Función con un parámetro al que se le asigna un valor por defecto\ndef func8(nombre=\"Juan\"):\n    return nombre\nprint(func8())\nprint(func8(\"Pepe\"))\n\n# Función con retorno de varios valores\ndef func9():\n    return 1, 2, 3\nprint(func9())\n\n# Función con un número de parámetros que pueden variar\ndef func10(*parametros):\n    print(parametros)\nfunc10(\"!Hola \", \"Python!\")\n\n# Función que recibe un parámetro estilo map, o JSON, al estilo clave:valor\ndef func11(**parametros):\n    print(parametros)\nfunc11(nombre=\"Juan\", edad=56, poblacion=\"Ferrol\")\n\n# Algunas funciones nativas de Python\nprint('Función nativa de Python:') # Imprime por consola lo comprendido entre los paréntesis\na = \"Hola Python\"\nprint(f'La variable a es de tipo {type(a)}') # type(valor) Indica el tipo de dato\nprint(f'La variable a es de tipo string: {isinstance(a, str)}') # isinstance(valor, tipo) Devuelve True o False si el tipo de dato coincide con el indicado en el segundo parámetro\n\n# Variable GLOBAL\nb = 10 \ndef func12():    \n    print(b)\nprint(b)\nprint(func12())    \n\n# Variable LOCAL a la función:\ndef func13():\n    c = 20\n    print(c)\ntry:\n    print(c)\nexcept:\n    print('La variable b es LOCAL a la función func9()')\nfinally:\n    print('Fin del programa')\nfunc13()\n\n## DIFICULTAD EXTRA\ndef func14(cadena1:str, cadena2:str)->int:    \n    contador = 0\n    for i in range(1,101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(cadena1 + cadena2)\n        elif i % 3 == 0:\n            print(cadena1)\n        elif i % 5 == 0:\n            print(cadena2)\n        else:\n            contador +=1\n    return contador\nveces = func14(\"¡Hola\", \"Python!\")\nprint(f\"Número de veces que se ha impreso el número en lugar de los textos. {veces}\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Juanma0416.py",
    "content": "\n#1\n\n\"\"\"\nFunciones Definidas por el Usuario\n\"\"\"\n\n\n# Simple\n\ndef saludo(): # Definición de la función por medio de la palabra reservada def\n    print(\"Hola, Python!\") # Bloque de código que pertenece a la función que imprime un saludo\n\nsaludo() # Llamada a la función para que se ejecute el bloque de código que contiene y de esta forma evitar la repetición de código\n\n\n# Con retorno\n\ndef return_saludo(): # Definición de la función por medio de la palabra reservada def\n    return \"Hola, Python!\" # Bloque de código que pertenece a la función que retorna un saludo\nreturn_saludo() # Llamada a la función pero como no hay un print no se muestra nada en la terminal\n\n# A) Buscamos que se muestre en la terminal creando una variable y asignándole el retorno de la función\nsaludo = return_saludo() # Llamada a la función pero como no hay un print no se muestra nada en la terminal\nprint (saludo) # Se imprime la variable saludo que contiene el retorno de la función return_saludo\n\n# B) Buscamos que se muestre en la terminal agregando un print a la llamada de la función\nprint(return_saludo()) # Se imprime directamente el retorno de la función return_saludo sin necesidad de crear una variable intermedia\n\n\n# Con un Argumento\n\ndef arg_saludo(nombre): # Definición de la función por medio de la palabra reservada def y un argumento llamado nombre. Un argumento es un parámetro que se pasa a la función para que esta lo utilice en su bloque de código\n    print (f\"Hola, {nombre}!\") # Bloque de código que pertenece a la función que imprime un saludo personalizado con el argumento nombre\narg_saludo(\"Loyle\") # Llamada a la función con el argumento \"Loyle\" que se pasa a la función para que esta lo utilice en su bloque de código\n\n# Con Argumentos\n\ndef args_saludo(nombre, apellido): # Definición de la función por medio de la palabra reservada def y dos argumentos llamados nombre y apellido.\n    print (f\"Hola, {nombre} {apellido}!\") # Bloque de código que pertenece a la función que imprime un saludo personalizado con los argumentos nombre y apellido\nargs_saludo(\"Loyle\", \"Carner\") # Llamada a la función con los argumentos \"Loyle\" y \"Carner\" que se pasan a la función para que esta los utilice en su bloque de código\nargs_saludo(apellido = \"Carner\", nombre = \"Loyle\") # Llamada a la función con los argumentos \"Loyle\" y \"Carner\" pero en diferente orden. Al usar los nombres de los argumentos, no importa el orden en que se pasen ya que la función los reconocerá por su nombre\n\n\n# Con un Agumento Predeterminado\n\ndef defaul_arg_saludo(nombre = \"Python\"): # Definición de la función por medio de la palabra reservada def y un argumento llamado nombre con un valor predeterminado \"Python\". Si no se pasa ningún valor al llamar a la función, se utilizará el valor predeterminado.\n    print (f\"Hola, {nombre}!\") # Bloque de código que pertenece a la función que imprime un saludo personalizado con el argumento nombre\ndefaul_arg_saludo() # Llamada a la función sin pasar ningún valor, por lo que se utilizará el valor predeterminado \"Python\"\ndefaul_arg_saludo(\"Loyle\") # Llamada a la función pasando el valor \"Loyle\", por lo que se utilizará este valor en lugar del valor predeterminado\n\n\n# Con Argumentos y Retorno\n\ndef args_return_saludo(nombre, apellido): # Definición de la función por medio de la palabra reservada def y dos argumentos llamados nombre y apellido. \n    return f\"Hola, {nombre} {apellido}!\" # Bloque de código que pertenece a la función que retorna un saludo personalizado con los argumentos nombre y apellido\nprint (args_return_saludo(\"Loyle\", \"Carner\")) # Llamada a la función con los argumentos \"Loyle\" y \"Carner\" que se pasan a la función para que esta los utilice en su bloque de código y se imprime el retorno de la función\n\n\n# Con Retorno de varios Valores\n\ndef varios_return(): # Definición de la función por medio de la palabra reservada def\n    return \"Loyle\", \"Carner\", 25 # Bloque de código que pertenece a la función que retorna varios valores: dos cadenas de texto y un número entero\n\nnombre, apellido, edad = varios_return() # Llamada a la función y asignación de los valores retornados a las variables saludo, apellido y edad\nprint (nombre) # Se imprime la variable saludo que contiene el primer valor retornado por la función varios_return\nprint (apellido) # Se imprime la variable apellido que contiene el segundo valor retornado por la función varios_return\nprint (edad) # Se imprime la variable edad que contiene el tercer valor retornado por la función varios_return\n\nprint (f\"{saludo} {apellido} tiene {edad} años.\") # Se imprime un mensaje personalizado con los valores retornados por la función varios_return\n\n\n# Con un número variable de Argumentos\n\ndef variable_arg_saludo(*nombres): # Definición de la función por medio de la palabra reservada def y un número variable de argumentos llamado nombres. El asterisco (*) indica que se pueden pasar varios argumentos y que estos se almacenarán en una tupla.\n    for nombre in nombres: # Bucle for que itera sobre cada nombre en la tupla nombres\n        print (f\"Hola, {nombre}!\") # Bloque de código que pertenece a la función que imprime un saludo personalizado con cada nombre en la tupla nombres\n\nvariable_arg_saludo(\"Loyle\", \"Carner\", \"Python\", \"Retos Moure\") # Llamada a la función con varios argumentos que se pasan a la función y se almacenan en la tupla nombres\n\n\n# Con un número variable de Argumentos con Palabra Clave\n\ndef variable_key_arg_saludo(**nombres): # Definición de la función por medio de la palabra reservada def y un número variable de argumentos con palabra clave llamado nombres. El doble asterisco (**) indica que se pueden pasar varios argumentos con palabra clave y que estos se almacenarán en un diccionario.\n    for clave, valor in nombres.items(): # Bucle for que itera sobre cada par clave-valor en el diccionario nombres\n        print (f\"{valor} ({clave})!\") # Bloque de código que imprime un saludo personalizado con cada nombre y su correspondiente parámetro en el diccionario nombres\n\nvariable_key_arg_saludo (primer_nombre = \"Loyle\", primer_apellido = \"Carner\", lenguaje = \"Python\", curso = \"Retos Moure\") # Llamada a la función con varios argumentos con palabra clave que se pasan a la función y se almacenan en el diccionario nombres\n\n\n\n#2\n\n\"\"\"\nFunciones Definidas por el Usuario\n\"\"\"\n\ndef outer_function(): # Definición de la función por medio de la palabra reservada def\n    print(\"Esta es la función externa.\") # Bloque de código que pertenece a la función outer_function que imprime un mensaje indicando que es la función externa\n\n    def inner_function(): # Definición de una función interna por medio de la palabra reservada def\n        print(\"Esta es la función interna.\") # Bloque de código que pertenece a la función inner_function que imprime un mensaje indicando que es la función interna\n\n    inner_function() # Llamada a la función interna para que se ejecute el bloque de código que contiene que no puede llamarse porque su ámbito está limitado a la función externa\nouter_function() # Llamada a la función externa para que se ejecute el bloque de código que contiene, incluyendo la llamada a la función interna. La función interna no puede ser llamada desde fuera de la función externa, ya que su ámbito está limitado a la función externa.\n\n\n\n#3\n\n\"\"\"\nFunciones del Lenguaje (Built-in Functions)\n\"\"\"\n\nprint(\"Hola, Python!\") # Función print() que imprime un mensaje en la terminal\nprint(len(\"Hola, Python!\")) # Función len() que devuelve la longitud de una cadena de texto\nprint(type(\"Hola, Python!\") ) # Función type() que devuelve el tipo de dato de una variable o valor\nprint(int(\"25\")) # Función int() que convierte una cadena de texto en un número entero\nprint(float(\"25.5\")) # Función float() que convierte una cadena de texto en un número decimal\nprint(str(25)) # Función str() que convierte un número en una cadena de texto\nprint(list((1, 2, 3))) # Función list() que convierte una tupla en una lista\nprint(tuple([1, 2, 3])) # Función tuple() que convierte una lista en una tupla\nprint(dict(nombre=\"Loyle\", apellido=\"Carner\")) # Función dict() que crea un diccionario a partir de pares clave-valor\nprint(set([1, 2, 3, 3, 2, 1])) # Función set() que crea un conjunto a partir de una lista, eliminando los elementos duplicados\nprint(sum([1, 2, 3, 4, 5])) # Función sum() que devuelve la suma de los elementos de una lista\nprint(max([1, 2, 3, 4, 5])) # Función max() que devuelve el valor máximo de una lista\nprint(min([1, 2, 3, 4, 5])) # Función min() que devuelve el valor mínimo de una lista\nprint(round(25.5678, 2)) # Función round() que redondea un número decimal a un número específico de decimales\nprint(abs(-25)) # Función abs() que devuelve el valor absoluto de un número entero o decimal\nprint(sorted([5, 2, 3, 1, 4])) # Función sorted() que devuelve una lista ordenada a partir de una lista desordenada\nprint(reversed([1, 2, 3, 4, 5])) # Función reversed() que devuelve un iterador que invierte el orden de una lista\nprint(enumerate([\"Loyle\", \"Carner\", \"Python\"])) # Función enumerate() que devuelve un iterador que genera pares índice-valor a partir de una lista\nprint(zip([\"Loyle\", \"Carner\"], [25, 30])) # Función zip() que devuelve un iterador que agrupa elementos de dos o más listas en tuplas\nprint(all([True, True, False])) # Función all() que devuelve True si todos los elementos de una lista son True, de lo contrario devuelve False\nprint(any([True, False, False])) # Función any() que devuelve True si al menos un elemento de una lista es True, de lo contrario devuelve False\nprint(chr(65)) # Función chr() que devuelve el carácter correspondiente a un código ASCII entero\nprint(ord(\"A\")) # Función ord() que devuelve el código ASCII entero correspondiente a un carácter\nprint(bin(10)) # Función bin() que convierte un número entero en su representación binaria\nprint(\"Hola, Python!\".upper()) # Método upper() que convierte una cadena de texto a mayúsculas\nprint(\"Hola, Python!\".lower()) # Método lower() que convierte una cadena de texto a minúsculas\nprint(\"Hola, Python!\".replace(\"Python\", \"Mundo\")) # Método replace() que reemplaza una subcadena por otra en una cadena de texto\nprint(\"Hola, Python!\".split()) # Método split() que divide una cadena de texto en una lista de palabras\nprint(\" \".join([\"Hola\", \"Python!\"])) # Método join() que une una lista de palabras en una cadena de texto separada por un espacio\nprint(\"   Hola, Python!   \".strip()) # Método strip() que elimina los espacios en blanco al inicio y al final de una cadena de texto\nprint(\"   Hola, Python!   \".lstrip()) # Método lstrip() que elimina los espacios en blanco al inicio de una cadena de texto\nprint(\"   Hola, Python!   \".rstrip()) # Método rstrip() que elimina los espacios en blanco al final de una cadena de texto\nprint(\"Hola, Python!\".find(\"Python\")) # Método find() que devuelve el índice de la primera aparición de una subcadena en una cadena de texto, o -1 si no se encuentra\nprint(\"Hola, Python!\".count(\"o\")) # Método count() que devuelve el número de apariciones de una subcadena en una cadena de texto\nprint(\"Hola, Python!\".startswith(\"Hola\")) # Método startswith() que devuelve True si una cadena de texto comienza con una subcadena específica, de lo contrario devuelve False\nprint(\"Hola, Python!\".endswith(\"Python!\")) # Método endswith() que devuelve True si una cadena de texto termina con una subcadena específica, de lo contrario devuelve False\n\n\n\n#3\n\n\"\"\"\nVariables Locales y Globales\n\"\"\"\n\nglobal_variable = \"Soy una variable global\" # Variable global que puede ser accedida desde cualquier parte del código\nprint(global_variable) # Se imprime la variable global\n\ndef hello_python(): # Definición de la función por medio de la palabra reservada def\n    local_variable = \"Soy una variable local\" # Variable local que solo puede ser accedida dentro de la función\n    print(local_variable) # Bloque de código que pertenece a la función que imprime la variable local\n    print (f\"Hola, {global_variable}!\") # Bloque de código que pertenece a la función que imprime un saludo personalizado con la variable global\n    hello_python() # Llamada a la función para que se ejecute el bloque de código que contiene\n    # Tener en cuenta que si intentamos acceder a la variable local desde fuera de la función, obtendremos un error ya que su ámbito está limitado a la función y que debemos determinar si una variable debe ser local o global según el uso que le vayamos a dar en nuestro código y evitar en la medida de lo posible el uso de variables globales para evitar conflictos y errores en nuestro código a no ser que sea estrictamente necesario.\n\n\n\n#4\n\n\"\"\"\nEXTRA\n\"\"\"\n\ndef print_numeros (text_1, text_2) -> int: # Definición de la función por medio de la palabra reservada def, dos argumentos llamados text_1 y text_2 y una anotación de tipo que indica que la función retorna un valor de tipo entero\n    count = 0 # Variable local que se utiliza para contar el número de iteraciones del bucle\n    for number in range (1, 101): # Bucle for que itera sobre un rango de números del 1 al 100\n        if number % 3 == 0 and number % 5 == 0: # Condicional elif que verifica si el número es múltiplo de 3 y de 5\n            print (text_1 + text_2) # Bloque de código que pertenece a la función que imprime la concatenación de los dos textos si el número es múltiplo de 3 y de 5\n        elif number % 3 == 0: # Condicional if que verifica si el número es múltiplo de 3\n            print (text_1) # Bloque de código que pertenece a la función que imprime el primer texto si el número es múltiplo de 3\n        elif number % 5 == 0: # Condicional elif que verifica si el número es múltiplo de 5\n            print (text_2) # Bloque de código que pertenece a la función que imprime el segundo texto si el número es múltiplo de 5\n        else:\n            print (number) # Bloque de código que pertenece a la función que imprime cada número en el rango\n            count += 1 # Incremento de la variable count en 1 cada vez que imprima un número y no uno de los textos\n    return count # Retorno de la variable count que indica el número de números impresos\n\nprint (print_numeros (\"Fizz\", \"Buzz\")) # Llamada a la función con los textos \"Fizz\" y \"Buzz\" que se pasan a la función para que esta los utilice en su bloque de código y se imprime el retorno de la función que indica el número de números impresos"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/KevinED11.py",
    "content": "import os\n\n\ndef show_name() -> None:\n    print(\"Kevin ED11\")\n\n\nprint_name = lambda: print(\"Kevin ED11\")\n\n\ndef full_name(first_name: str, last_name: str) -> None:\n    print(f\"{first_name} {last_name}\")\n\n\ndef sum(a: int, b: int) -> int:\n    return a + b\n\n\ndef check_server_password(password: str) -> bool:\n    correct_password = os.getenv(\"PASSWORD\", \"mouredev\")\n\n    def is_correct_password() -> bool:\n        return password == correct_password\n\n    return is_correct_password()\n\n\ncities = [\"Madrid\", \"Barcelona\", \"Valencia\"]\n\n\ndef get_cities() -> list:\n    global cities\n    return cities\n\n\ndef set_citie(citie: str) -> None:\n    global cities\n    cities += [citie]\n\n\ndef counter(init: str, end: str) -> int:\n    intern_counter = 0\n\n    for n in range(1, 101):\n        if n % 15 == 0:\n            print(init + end)\n        elif n % 5 == 0:\n            print(end)\n        elif n % 3 == 0:\n            print(init)\n        else:\n            print(n)\n            intern_counter += 1\n\n    return intern_counter\n\n\nif __name__ == \"__main__\":\n    show_name()\n    print_name()\n    full_name(\"Kevin\", \"ED11\")\n    print(sum(1, 2))\n    print(check_server_password(\"mourede\"))\n    print(get_cities())\n    set_citie(\"Sevilla\")\n    print(get_cities())\n    print(counter(\"a\", \"b\"))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Lazar171717ech.py",
    "content": "## 1. FUNCIONES BÁSICAS ##\n\ndef PrintHola(): # Definimos una función simple con def + [nombre de la función] + () + :\n    print(\"¡Hola!\") # Código que se ejecuta\n\nPrintHola() # Llamamos a la función con [nombre de la función] + ()\n\ndef PrintTexto(texto): # Definimos una función con argumentos poniendo los mismos dentro de los paréntesis\n    print(texto) # Código que se ejecuta. Cuando usamos \"texto\" hace referencia al argumento que hayamos metido\n\nPrintTexto(\"¡Adiós!\") # Llamamos a la función con argumenos añadiendo estos dentro de los parentesis\n\ndef ReturnTexto(texto): # Cuando usamos return en una función, cuando se llame a esta...\n    return texto*2 #  ...no solo se ejecutará el codigo sino que haremos también referencia al valor que returnemos.\n\nprint(ReturnTexto(\"Ventana\")) # En este caso cuando llamemos a la función ReturnTexto() hacemos referencia al argumento dos veces (el return)\n\n## 2. FUNCIONES DENTRO DE FUNCIONES ##\n\ndef Funcion1(): # Definimos la primera función.\n    print(\"Ejecución 1\")\n\n    def Funcion2(): # Definimos la segunda función dentro de la primera.\n        print(\"Ejecución 2\")\n\n    Funcion2() # Solo se puede llamar a la función2 dentro de la función1\n\nFuncion1() \n\n## 3. FUNCIONES DENTRO DEL LENGUAJE ##\n\nprint(\"¡Hola Mundo!\") # print Escribe en consola el argumento o argumentos que metamos\nprint(len(\"¡Hola Mundo!\")) # len Mira la cantidad de caracteres o elementos de un string o lista, tupla ...\nprint(type(\"¡Hola Mundo!\")) # type Devuelve el tipo de dato que damos como argumento\nprint(bool(\"¡Hola Mundo!\")) # bool, int ... Intenta transformar el dato dado como argumento a otro tipo de dato\n\n## 4. VARIABLES LOCALES Y GLOBALES ##\n\nvariable_global = 5\n\ndef func(numero):\n    variable_local = 7\n    return numero * variable_local\n\nprint(variable_global)\n#print(variable_local) No se puede acceder a la variable local porque está definida dentro de una función\n\nprint(func(2)) # Accedemos a esa variable solo si entramos a la función\n\ncontador = 0\n\ndef masuno():\n    contador += 1 # Si la variable aparece descolorida es porque dentro de la función esta no se puede acceder\n    print(contador) # El lenguaje crea una variable local igual a la variable global.\n\n#Si queremos usarla sería de la siguiente manera\ndef masuno2():\n    global contador # Al hacer esto le estamos diciendo a Python que estamos tratando con la variable global\n    contador += 1\n    print(contador) \n\nmasuno2()\nmasuno2()\n\n## 5. DIFICULTAD EXTRA ##\n\ndef funcion(string1, string2):\n    counter = 0\n    for index in range(1, 101):\n        if index%5 == 0 and index%3 == 0:\n            print(string1 + string2)\n        elif index%3 == 0:\n            print(string1)\n        elif index%5 == 0:\n            print(string2)\n        else:\n            counter += 1\n            print(index)\n    return(counter)\n\nprint(funcion(\"Hola\", \"Brais\"))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Lio7master.py",
    "content": "#  EJERCICIO:\n#  - Crea ejemplos de funciones básicas que representen las diferentes\n#    posibilidades del lenguaje:\n#    Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n#  - Comprueba si puedes crear funciones dentro de funciones.\n#  - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n#  - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n#  - Debes hacer print por consola del resultado de todos los ejemplos.\n#    (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n# \n#  DIFICULTAD EXTRA (opcional):\n#  Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n#  - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n#    - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n#    - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n#    - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n#    - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n# \n#  Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n#  Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n# \n\n\n#Definimos una función como un bloque de codigo que lo creamos para poderlo reautilizar con una tarea especifica,\n#para poder manejarla, escalarla, y mantenerla de forma facil.\n\n#Funciones defindas por el sistema\n\n#\"def\" es la palabra reservada para la función en python\n#Simple\ndef greet():\n    print('hola Python!')\n\n#se manda llamar a la función\ngreet()\n\n#Con retorno\n#ejecuta una logica y devuelve un resultado\ndef return_greet():\n    return \"hola, Python desde el return!\"\n#directamente desde la funcion manejamos el return\nprint(return_greet())\n#O asignandola a variable para manejo posterior\ngreetReturn = return_greet()\nprint (greetReturn, \"desde fucion en variable\")\n\n#Funciones con arguamentos\n#Le pasamos parametros a la funcion para que realice operaciones con el\ndef arg_greet(name):\n    print(f\"Hola, {name}\")\n\narg_greet(\"Lio\")\n\n\n#Con Varios valores:\ndef args_greet(greet, name):\n    print(f\"{greet}, {name}!\")\n\n#Con Argumento predeterminado\nargs_greet(\"hola\", \"lio\")\n\ndef default_arg_greet(name = \"Python\" ):\n    print(f\"Hola, {name}\")\n\ndefault_arg_greet()\n\n#Declarando nombre parametros para evitar errores de orde default\nargs_greet(name= \"Leo\", greet= \"Hola con parametros declarados\")\n\n\ndef mult_return_greet():\n    return \"hola\", \"Python\"\n\ngreet, name = mult_return_greet() #Se desestructuran los valores conforme fueron declarados\nprint(greet)\nprint(name)\n\n#Funciones con numero variable de argumentos\n\ndef variable_arg_gree(*names):\n    for name in names: #intera dentro de los argumentos recibidos\n        print(f\"hola, {name}\")\n\nvariable_arg_gree(\"python\", \"cancun\", \"Leo\", \"Lio\")\n\n#Con un numero variable de argumentos con palabra clave\ndef variable_key_arg_greet(**names):\n    for key, value in names.items():\n        print(f\"{value} ({key})\")\n              \nvariable_key_arg_greet(\n    name = \"Leo\",\n    edad = 31,\n    lenguaje = \"Python\",\n    alias = \"Lio7Master\"\n)\n\n#fucion dentro de funcion+\n\ndef outer_funtion():\n    def inner_funtion():\n        print (\"Funcion interna: hola, Python!\")\n    inner_funtion() #Llamamamos a la funcion interna para que se ejecute dentro de la fucion principal.\n\nouter_funtion()\n\n#Funciones del lenguaje (Built-in), son funciones que vienen predeterminadas por el lenguje\n\n#ejemplo print es una funcion que ya esta definida solo para llamar\n\nprint(len(\"Lio7master\")) #Len conteo de la cadena\nprint(type(31)) #Tipo de dato\nprint(\"lio7master\".upper()) #funcion asociado al tipo de dato\n\n#concepto de  variables locales y globales\nglobal_var = \"Python\"\n\ndef hello_python():\n    local_var = \"hola\"\n    print(f\"Hello, {global_var}!\")\n    \n\nprint(global_var)\n#print(local_var) no se puede acceder desde fuera de la funcion\n\nhello_python()\n\n#EXTRA: ejercicio de fizz buzz\ndef print_numbers(text_1, text_2 ) -> int:\n    count = 0\n    for number in range(1, 101):\n        if number % 5 == 0 and number % 3 == 0:\n            print(text_1)\n        elif  number % 3 == 0:\n            print(text_2)\n        elif number % 5 ==  0:\n            print(text_1, text_2)\n        else:\n            print(number)\n            count += 1\n    return count\n\nprint(print_numbers(\"fizz\", \"buzz\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Lioomx.py",
    "content": "'''\nFunciones en Python\n'''\n\n# Función simple con argumentos y retorno\n\ndef suma(a, b):\n    return a + b\nresultado = suma(2, 3)\nprint(f\"El resultado de la suma es: {resultado}\")\n\n# Función sin parámetros\n\ndef saludar():\n    print(\"Hola, Bienvienido al curso de Python\")\n\nsaludar()\n\n# Función con valores predeterminados\n\ndef potencia(base, exponente=2):\n    return base ** exponente\n\nprint(potencia(3)) # 3^2 = 9; usa el valor predeterminado\nprint(potencia(3, 3)) # 3^3 = 27; usa el valor proporcionado\n\n# Función que devuelve multiples valores\n\ndef operaciones(a, b):\n    suma = a + b\n    resta = a - b\n    multiplicación = a * b\n    división = a / b\n    return suma, resta, multiplicación, división # Devuelve una tupla\n\nresultados = operaciones(10, 5)\nprint(resultados)\n\n# Función con argumentos variables\n\ndef sumar_todos(*numeros):\n    return sum(numeros)\n\nprint(sumar_todos(1, 2, 3, 4, 5))\n\n# Uso de argumentos con nombre (keyword arguments)\n\ndef mostrar_info(**kwargs):\n    for key, value, in kwargs.items():\n        print(f\"{key}: {value}\")\n\nmostrar_info(Nombre=\"Lio\", Edad=24, Ciudad=\"CDMX\")\n\n# Funciones anónimas (lambda)\n\ndoblar = lambda x: x*2 # Función que dobla el valor de x;\nprint(doblar(5))\n\n# Recursividad\n\ndef factorial(n): # Calcula el factorial de un número\n    if n == 0: # Caso base\n        return 1 # 0! = 1\n    return n * factorial(n-1) # Llamada recursiva\n\nprint(factorial(5)) # 5! = 120\n\n# Funciones anidadas \n\ndef exterior(x): # Función exterior\n    def interior(y): # Función interior\n        return y ** 2 # Eleva al cuadrado\n    return interior(x) + 1 # Llama a la función interior y suma 1\n\nprint(exterior(5)) # 5^2 + 1 = 26\n\n# Función como parámetro\n\ndef aplicar_operación(función, valor): # Recibe una función y un valor \n    return función(valor) # Aplica la función al valor\n\nresultado = aplicar_operación(lambda x: x ** 2, 5) \nprint(resultado) # 5^2 = 25\n\n# Función generadora\ndef generador_pares(n): # Genera números pares del 0 al n\n    for i in range(n): # Itera sobre el rango de 0 a n\n        if i % 2 == 0: # Si el número es par\n            yield i # yield: devuelve el valor\n\nfor i in generador_pares(10): \n    print(i) # Imprime los números pares del 0 al 8\n\n# Decoradores\n\ndef decorador(función): # Recibe una función\n    def envoltura(): # Función envoltura\n        print(\"Antes de la función\") \n        función() # Llama a la función\n        print(\"Después de la función\") \n    return envoltura # Devuelve la función envoltura \n\n@decorador  # Aplica el decorador a la función\ndef mi_función(): \n    print(\"Mi función\") \n\nmi_función() # Llama a la función decorada\n\n# Manejo de excepciones\n\ndef dividir(a, b): # Divide dos números\n    try: # try: intenta ejecutar el bloque de código\n        return a / b # Intenta dividir a entre b\n    except ZeroDivisionError: # ZeroDivisionError: Error al dividir entre 0\n        return \"Error: No se puede dividir entre 0\" # Maneja el error\n\nprint(dividir(10, 2)) \nprint(dividir(10, 0))\n\n'''\nFunciones dentro de funciones\n'''\n\ndef exterior(x): \n    def interior (y):\n        return y ** 2 \n    return interior(x) + 1\n\nprint(exterior(5)) # 5^2 + 1 = 26\n\n'''\nFunciones creadas en el lenguaje\n'''\n\nprint(abs(-5))\nprint(max(1, 2, 3, 4, 5))\nprint(min(1, 2, 3, 4, 5))\nprint(len(\"Bienvenido\"))\nprint(type(36))\nprint(type(\"Hola\"))\n\n''''\nVariables Locales y Globales\n'''\n\n# Variables Globales\n\nx = 10 # Variable global\n\ndef mostrar_x():\n    print(f\"Valor de x: {x}\") # Accediendo a la variable global\n\nmostrar_x()\n\n# Variables locales\n\ndef funcion():\n    y = 20 # Variable local\n    print(f\"Valor de y: {y}\")\n\nfuncion()\n\n\"\"\"\nEXTRA\n\"\"\"\n\ndef print_nmb(text1, text2):\n    contador = 0\n\n    for i in range(1, 101):\n        if i % 3 == 0 and i % 5 == 0: # Múltiplo de 3 y 5\n            print(text1 + text2)\n        elif i % 3 == 0:\n            print(text1) # Múltiplo de 3\n        elif i % 5 == 0:\n            print(text2) # Múltiplo de 5\n        else:\n            print(i) # Imprime el número si no es multiplo de 3 ni de 5\n            contador += 1 # Incrementa el contador cuando se imprime un número\n    return contador # Retorna el contador\n\nresultado = print_nmb(\"Fizz\", \"Buzz\")\nprint(f\"Números impresos en lugar de textos: {resultado}\")\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/LittleMabbit.py",
    "content": "## Funciones definidas\n\n# Funciones simples - Bloque de código que ejecuta ciertas utilidades.\ndef greet():\n    print(\"Hola, Python!\")\ngreet()\n\n# Funciones con retorno - Bloque de código que retorna un valor determinado.\ndef greet_return():\n    return print(\"Hola, Python\")\ngreet_return()\n\n# Funciones con argumentos - Bloque de código que puede recibir un argumento en específico y basar la función basado en ese valor. Le pasamos 'name' a 'greet_arg' y cuando llamemos la función, podemos especificar el valor de name.\ndef greet_arg(name):\n    print(f\"Hola, {name}\")\nname = 'Python!'\ngreet_arg(name)\n\n# Funciones con argumentos predeterminados - Igual que el anterior, pero esta vez podemos asignar un valor predeterminado que será utilizado si no hay otro valor asignado. \ndef def_greet_arg(name='Python!'):\n    print(f\"Hola, {name}\")\n\ndef_greet_arg('Bris') # Devuelve 'Bris' porque es el valor que le asignamos.\ndef_greet_arg() # Devuelve Python ya que es el valor predeterminado.\n\n# Funciones con retorno de varios argumentos\ndef multiple_return_greet(): # Función que a pesar de que no recibe ningún argumento, puede retornar varios.\n    return 'Python', 'Hola', 32 # Almacenamos tres valores diferentes separados por comas. \n\nname, greet, age = multiple_return_greet() # Destructuramos los valores en orden posicional.\nprint(name)\nprint(greet)\nprint(age)\n\n# Funciones con un número variable de argumentos\n\ndef mult_arg_greet(*names): # Podemos decirle que aparte del name, puede recibir mas argumentos.\n    for name in names:\n        print(f\"Hola {name}\") # Iterare sobre cada name dentro de los names que reciba.\n\nmult_arg_greet('Little', 'Mabbit', 'Hi')\n\n## Función dentro de una función\n\ndef outer_function(): # Creamos la función externa\n    def inner_function(): # Creamos la función interna\n        name = 'English'\n        print(f'Hi {name}! Printing inner function')\n    inner_function() # Llamamos la función interna al final de la función externa para que se ejecute lo que está dentro.\n    print(f'Y luego, esta es la función externa')\n\nouter_function()\n\n## Funciones dentro del lenguaje. - Funciones que ya están construidas dentro del lenguaje.\n\nprint(len('LittleMabbit')) # Cuenta los elementos del string.\nprint(type('LittleRat')) # Muestra el tipo de dato.\nprint(sorted('bcdsaw')) # Ordena en orden alfabético\nprint('littlemabbit'.upper())\nprint('LITTLEMABIT'.lower())\nprint('LEARNINGPYTHON'.isupper())\n\n## Variables locales y variables\n\nglobal_var = 'Python' # Variable que puede ser asignada a todo código debajo de él\n\ndef global_var_function():\n    local_var = 'Hola' # Variable que solo tiene como scope el bloque en el que está.\n    print(f\"{local_var}, {global_var}\")\n\nprint(global_var)\n# print(local_var) # Esta no la encuentra porque solamente fue declarada dentro del bloque de código de la función.\nglobal_var_function()\n\n'''\nEXTRA: \n * - Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n'''\ndef ejercicio(t1, t2):\n    # Inicializamos la variable del conteo fuera del bucle.\n    c = 0\n    # Imprime numeros del 1 al 100.\n    for i in range(0, 101):\n        # Si el numero es multiplo de 3 y de 5, concatena la cadena de texto.\n        if i % 3 == 0 and i % 5 == 0:\n            print(f'{t1}{t2}')\n        # Si el numero es multiplo de 3, muestra t1\n        elif  i % 3 == 0:\n            print(t1)\n        # Si el numero es multiplo de 5, muestra t2\n        elif i % 5 == 0:\n            print(t2)\n        # Numero de veces que se imprime un número en vez de texto.\n        else:\n            print(i)\n            c += 1\n    # Función retorna el conteo de veces que se devolvió un numero en vez de texto.\n    return c\n\nprint(ejercicio('Fizz', 'Buzz'))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/LucasRebuffo.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */ \"\"\"\n\n## Funcion sin retorno y sin argumentos\n\n\nfrom cgi import print_arguments\n\n\ndef saludar():\n    print(\"Hola a todos!\")\n\n\nsaludar()\n\n## Funcion con retorno sin argumentos\n\n\ndef my_name():\n    return \"Lucas\"\n\n\nprint(my_name())\n\n## Funcion con retorno y argumentos\n\n\ndef suma(a, b):\n    return a + b\n\n\nprint(suma(1, 1))\n\n\n## Funcion con parametro por defecto\n\n\ndef saludo_default(nombre=\"Lucas\"):\n    print(f\"Hola {nombre}\")\n\n\nsaludo_default()\n\n\n## Retorno multiple\n\n\ndef saludar_multiple():\n    return \"Hola\", \"Python\"\n\n\nsaludo, name = saludar_multiple()\n\nprint(saludo)\nprint(name)\n\n## Con numero variables de argumentos posicionales\n\n\ndef variables_args_saludo(*args):\n    for name in args:\n        print(f\"Hola {name}\")\n\n\nvariables_args_saludo(\"pablo\", \"comunidad\", \"Python\")\n\n## Con numero variable de argumentos pero con **kwargs\n\n\ndef kwargs_saludo(**kwargs):\n    for key, value in kwargs.items():\n        print(f\"{key} : {value}\")\n\n\nkwargs_saludo(nombre1=\"lucas\", nombre2=\"pepe\", nombre3=\"numero\")\n\n\n## Funciones detro de otras\n\n\ndef funcion_exterior():\n    def funcion_interna():\n        print(\"Funcion interna: Hola Python\")\n\n    funcion_interna()\n\n\nfuncion_exterior()\n\n## Funciones del lenguaje\n\nprint(\"Imprime el texto\")\n\nprint(len(\"String\"))\nprint(len([1, 2, 3]))\n\nprint(type(6))\nprint(type(True))\nprint(type(\"6\"))\n\nprint(chr(45))\n\nprint(hash(\"Hola\"))\n\n## Variable locales y globales\n\nvariable_global = \"Node.js\"\n\nprint(variable_global)\n\n\ndef hello_node():\n    variable_local = \"Python\"\n    print(f\"Hola, {variable_local} {variable_global}\")\n\n\nprint(variable_global)\n\nhello_node()\n\n\"\"\" * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n * \"\"\"\n\n\ndef print_numbers(cadena1: str, cadena2: str):\n    contador = 0\n\n    for num in range(1, 102):\n        if num % 3 == 0 and num % 5 == 0:\n            print(cadena1 + cadena2)\n        elif num % 3 == 0:\n            print(cadena1)\n        elif num % 5 == 0:\n            print(cadena2)\n        else:\n            print(num)\n            contador += 1\n\n    return contador\n\nprint(print_numbers(\"fizz\", \"buzz\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/LuciaRF.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n \"\"\"\n\n#Funciones sin parámetros ni retorno\n\ndef saludo():\n    print(f\"Hola mundo ¿que tal estais?\")\n\nsaludo()\n\n#Funciones con varios parametros y con retorno\n\n#Calculadora se añade dos parametros y el tipo en el que se realiza\n\ntipos_caluclo = [\"suma\",\"resta\",\"multiplicacion\",\"division\",\"potencia\"]\n\ndef calculadora(param1,param2,tipo):\n    if(tipo == \"suma\"):\n        return param1 + param2\n    elif(tipo == \"resta\"):\n        return param1 - param2\n    elif(tipo == \"multiplicacion\"):\n        return param1 * param2\n    elif(tipo == \"division\"):\n        return param1 / param2\n    elif(tipo == \"potencia\"):\n        return param1 ** param2\n\nprint(f\"\\nEsto es una calculadora. Elige una función, suma(0), resta(1), multiplicacion(2), division(3), potencia(4) de numeros.\")\ntipo_input = int(input(\"Introduce numero para la funcion: \"))\n\nprint(f\"Ahora introduce 2 numeros: \")\nparametro1 = int(input(\"Parametro 1: \"))\nparametro2 = int(input(\"Parametro 2: \"))\n\nprint(f\"El resultado del calculo es {calculadora(parametro1,parametro2,tipos_caluclo[tipo_input])}\")\n\ndef funcion_dentro_funcion():\n    print(\"Llamada a una funcion dentro de la funcion\")\n    def saludo_interno():\n        print(\"LLamada propia\")\n\n    print(\"Estoy llamando a la funcion ahora\")\n    saludo_interno()\n\n    #Variable LOCALES y GLOBALES\n\n    #Global: sería tipos_calculo dentro del propio script\n    #Local: sería la variable \n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n\"\"\"\n\ndef funcion_opcional(texto1,texto2):\n    resultado = 0\n    try:\n        for i in range(1,101):\n\n            if i%3 == 0 and i%5 == 0 :\n                print(texto1+texto2)\n            else:\n                if(i%3 == 0):\n                    print(texto1)\n                elif(i%5 == 0):\n                    print(texto2)\n                else:\n                    print(i)\n                    resultado +=1\n        \n        return print(\"El numero de veces que se ha impreso el número en lugar de los textos \"+ str (resultado))\n\n    except TypeError as e:\n        print(e)\n\ntext1 = \"Esto es el texto 1\"\ntext2 = \"Esto es el texto 2\"\n#text2 = 2\n\nfuncion_opcional(text1,text2)"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/LuisK0706.py",
    "content": "# Funcion sin parametros \n\ndef sin_parametros():\n    print(f\"Imprimiendo una funcion sin parametros\")\n\nsin_parametros() \n\n\n\n# Funcion con parametros\n    \ndef con_parametros(num1, num2):\n    print(f\"La suma es: {num1 + num2}\")\n\ncon_parametros(5, 9)\n\n\n\n# Funcion con parametros y retorno de datos\n    \ndef con_retorno(num1, num2):\n    return num1 + num2\n\nprint(con_retorno(8, 7))\n\n# Esta al retornar un dato se le puede asignar a una variable y poder llamarla despues\nresultado = con_retorno(8, 7)\nprint(f\"El resultado es: {resultado}\")\n\n\n\n# Funcion dentro de otra funcion\ndef primera_funcion():\n    print(\"Dentro de la primera funcion\")\n    \n    def segunda_funcion():\n        print(\"Dentro de la segunda funcion\")\n    segunda_funcion() # Solo se podra ver si se imprime la funcion principal\n\nprimera_funcion()\n\n\n# Funcion con una variable global\ndef restando(num1):\n    mi_resta = num1 - variable_global\n    return mi_resta\n\n\n# Variable globales una variable que podemos usar en cualquier parte del codigo\nvariable_global = 5 \n\n\n\n# Funcion con una variable local (es aquella que solo se puede usar en un segmento especifico de codigo)\ndef con_variable_l(num1, num2):\n    # La variable mi_suma (variable local) solo se podra usar en esta funcion\n    mi_suma = num1 + num2\n    return mi_suma\n\n\n\n# Ejemplo de una funcion ya creada del lenguaje (funcion len())\nmi_cadena = \"Esta es una cadena de ejemplo\"\nprint(f\"La longitud de la cadena es: {len(mi_cadena)}\")\n\n\n\n'''\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n'''\n\n\ndef numeros(cadena1, cadena2):\n    i = 1\n    contando_impresiones = 0\n    while i < 101:\n        if i % 3 == 0 and i % 5 == 0: \n            print(cadena2)\n            i += 1\n        if i % 3 == 0:\n            print(cadena1)\n            i += 1\n        elif i % 5 == 0:\n            print(cadena1 + cadena2)\n            i += 1\n        else:\n            pass\n            i += 1\n            contando_impresiones += 1\n    return f\"Se imprimieron {contando_impresiones} numeros\"\n\n# Resultado ejercicio extra\nprint(numeros(\"Cadena1\", \"Cadena2\"))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/LuisOlivaresJ.py",
    "content": "\"\"\"\n* - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n\"\"\" \n\ndef my_dummy_func():\n    \"\"\"Una función sin parámetros ni retorno.\"\"\"\n    pass\n\nmy_dummy_func()  # A call to the function.\n\ndef saludar(name: str):\n    \"\"\"Una función con un parámetro.\"\"\"\n    print(f\"Hola {name}.\")\n\nsaludar(\"Luis\")\n\ndef suma(x: int, y: int) -> int:\n    \"\"\"Una función con dos parámetros y un retorno.\"\"\"\n    z = x + y\n    return z\n\nprint(suma(1,3))  # prints 4\n\n# - Comprueba si puedes crear funciones dentro de funciones.\n\ndef line_eq(x):\n    def mult(x, m):\n        return m*x\n    return mult(x, 2) + 1\n\nprint(line_eq(2))\n\n#- Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n\nprint(sum([1,2,3]))\n\n#Argument tuple packing\n\"\"\"When a parameter name in Python function definition is preceded by an asterisk (*), \nit indicates argument tuple packing. Any corresponding arguments in the function call \nare packed into a tuple that the function can refer by the given parameter name.\n\"\"\"\n\ndef f(*args):\n    print(args)\n    print(type(args), len(args))\n    for x in args:\n        print(x)\nprint(\"\\n###########\\nArgument tuple packing:\\n\")\nf(1, 2, 3)\n\n#- Pon a prueba el concepto de variable LOCAL y GLOBAL.\n\ndef main_function():\n    local_variable = 5\n    print(\"Inside main function\")\n    print(f\"{local_variable=}\")\n\nmy_global_variable = 10\nmain_function()\nprint(\"Outside the function\")\nprint(f\"{my_global_variable=}\")\n\n\"\"\"\n* Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n \"\"\"\n\ndef str_to_num(arg1: str, arg2: str):\n\n    counter_substitution = 0\n\n    for i in range(1, 16):\n\n        if not(i%3):\n            if not(i%5):\n                print(arg1+arg2)\n                counter_substitution += 1\n            else:\n                print(arg1)\n                counter_substitution += 1\n\n        elif not(i%5):\n            print(arg2)\n            counter_substitution += 1\n        \n        else:\n            print(i)\n    return counter_substitution\n\ncounter = str_to_num(\"Tres\", \"Cinco\")\nprint(f\"{counter=}\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Lumanet.py",
    "content": "# FUNCIONES\n# Sin parámetros ni retorno\ndef saludo():\n  print(\"Hola, soy Lumanet\")\n# Con uno o varios parámetros\ndef saludo_personal(nombre, apellido):\n  print(f\"Hola, soy {nombre} {apellido}\")\n# Con varios parámetros\ndef saludo_personal_multiple(*nombres):\n  for nombre in nombres:\n    print(f\"Hola, soy {nombre}\")\n# Con retorno\ndef saludo_personal_retorno(nombre, apellido):\n  return f\"Hola, encantado, soy {nombre} {apellido}\"\n\nsaludo()\nsaludo_personal(\"Marcos\", \"Lumanet\")\nsaludo_personal_multiple(\"Marcos\", \"Lumanet\", \"Juan\", \"Pedro\")\nprint(saludo_personal_retorno(\"Marcos\", \"Lumanet\"))\n\ndef saludo_pregunta(nombre, apellido, pregunta):\n  saludo_personal(nombre, apellido)\n  print(f\"{pregunta}\")\n  \nsaludo_pregunta(\"Marcos\", \"Lumanet\", \"¿Cómo estás?\")\n\nfrom datetime import datetime\n\ndef saludo_hora(nombre, apellido):\n  hora = datetime.now().hour\n  if hora < 12:\n    print(f\"Buenos días, soy {nombre} {apellido}\")\n  elif hora < 18:\n    print(f\"Buenas tardes, soy {nombre} {apellido}\")\n  else:\n    print(f\"Buenas noches, soy {nombre} {apellido}\")\n    \nsaludo_hora(\"Marcos\", \"Lumanet\")\n\n# Variables globales y locales\nnombre = \"Marcos\"\ndef saludo_global():\n  saludo = \"Hola\"\n  print(f\"{saludo}, soy {nombre}\")\n  \nsaludo_global()\n# print(saludo) # ! No se puede acceder a la variable local de la función\n\n\"\"\"\nCrea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n- La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n  - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n  - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n  - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n  - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\"\"\"\n\ndef multiplos(p1, p2):\n  c =0\n  for i in range(1, 101):\n    if i % 3 == 0 and i % 5 == 0:\n      print(f\"{p1} y {p2}\")\n    elif i % 3 == 0:\n      print(p1)\n    elif i % 5 == 0:\n      print(p2)\n    else:\n      print(i)\n      c += 1\n  return c\n\n# multiplos(\"Tres\", \"Cinco\")\nvalor= multiplos(\"Tres\", \"Cinco\")\nprint(valor)"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Maanghel.py",
    "content": "\"\"\"\nEJERCICIO:\n- Crea ejemplos de funciones básicas que representen las diferentes\n    posibilidades del lenguaje:\n    Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n- Comprueba si puedes crear funciones dentro de funciones.\n- Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n- Pon a prueba el concepto de variable LOCAL y GLOBAL.\n- Debes hacer print por consola del resultado de todos los ejemplos.\n    (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n\nDIFICULTAD EXTRA (opcional):\nCrea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n- La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n    - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n    - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n    - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n    - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\nPresta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\nCada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n\"\"\"\n\n# Funcion sin parametro y sin retorno\ndef imprimir():\n    print(\"\\nHola, Python!\")\n\nimprimir()\n\n# Funcion con parametro y sin retorno\ndef imprimir_nombre(nombre):\n    print(f\"\\nHola, {nombre}!\")\n\nimprimir_nombre(\"Manuel\")\n\n# Funcion sin parametro y con retorno\ndef obtener_pi():\n    return 3.1416\n\nprint(f\"\\n{obtener_pi()}\")\n\n# Funcion con parametros y con retorno\ndef sumar(numero1, numero2):\n    return numero1 + numero2\n\nprint(f\"\\n{sumar(3, 5)}\")\n\n# Funcion con retorno multiple\ndef operaciones(numero1, numero2):\n    suma = numero1 + numero2\n    resta = numero1 - numero2\n    return suma, resta\n\nprint(f\"\\nSuma: {operaciones(4, 4)[0]}\")\nprint(f\"Resta: {operaciones(5, 3)[1]}\")\n\n# Funcion con parametro por defecto\ndef saludar(nombre = \"Manuel\"):\n    print(f\"\\nHola, {nombre}!\")\n\nsaludar()\nsaludar(\"Juan\")\n\n# Funcion con numero variable de argumentos\ndef sumar_todos(*args): # Argumentos posicionales\n    return sum(args)\n\nprint(f\"\\n{sumar_todos(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)}\")\n\ndef impresion(**kwargs): # Argumentos nombrados\n    print()\n    for key, value in kwargs.items():\n        print(f\"{key}: {value}\")\n\nimpresion(nombre= \"Manuel\", edad= 29)\n\n# Funcion dentro de otra funcion\ndef imprimir():\n    print(\"\\nHola, \", end= \"\")\n    def imprimir_segundo():\n        print(\"Python!\")\n    imprimir_segundo()\n\nimprimir()\n\n# Funciones ya creadas en Python (built-in)\nprint(f\"\\n{len(\"Manuel\")}\")\nprint(sum([1, 2, 3, 4]))\nprint(str(6))\n\n# Uso de variables locales y globales\nvariable_global = \"Global\"\n\ndef imprimir_local():\n    variable_local = \"Python\"\n    print(f\"\\nVariable global: {variable_global}\\nVariable local: {variable_local}\")\n\nimprimir_local()\nprint(f\"\\n{variable_global}\")\n# print(f\"{variable_local}\") # No accede ya que solo se puede usar en la funcion en que fue declarada\n\n# EXTRA\ndef imprimir_cadenas(cadena1, cadena2) -> int:\n    contador = 0\n    print()\n    for numero in range(1, 101):\n        if numero % 3 == 0 and numero % 5 == 0:\n            print(cadena1 + cadena2)\n        elif numero % 3 == 0:\n            print(cadena1)\n        elif numero % 5 == 0:\n            print(cadena2)\n        else:\n            print(numero)\n            contador += 1\n    \n    return contador\n\nprint(imprimir_cadenas(\"Fizz\", \"Buzz\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/MarcosE-FerretoE.py",
    "content": "# Funciones ya creadas en el lenguaje\nprint(len(\"Hola mundo\"))\nprint(type(\"Hola\"))\nprint(\"Python\".upper())\n\n\n# Funciones\n\n\ndef funcion_hola():\n    print(\"Hola mundo\")\n\n\ndef funcion_pass():\n    # Función sin parámetros y sin retorno\n    pass\n\n\ndef suma(a, b):\n    # Función con parámetros y retorna una suma\n    return a + b\n\n\ndef funcion_dentro_funcion(a):\n    # Función dentro de una función\n    def suma(b):\n        return a + b\n    return suma\n\n\nfuncion_hola()\n\nprint(funcion_pass())\n\na = 10\nb = 14\n\n# F-string para imprimir el resultado de la función suma\nprint(f\"Este es el resultado de una función que suma dos números: {\n      suma(a, b)}\")\n\na = 34\nb = 54\n\nsumar = funcion_dentro_funcion(a)\n\n# F-string para imprimir el resultado de la función dentro de otra función\nprint(f\"Este es el resultado de una suma que tiene una función dentro de otra función: {\n      sumar(b)}\")\n\n# Variable global\nnumero_uno_global = 45\n\n\ndef variable_local_global():\n    # Variable local\n    numero_dos_local = 32\n\n    print(f\"El valor de la variable local es: {numero_uno_global}\")\n    print(f\"El valor de la variable global es: {numero_dos_local}\")\n\n\nvariable_local_global()\n\n\ndef numeros_textos(cadena_uno, cadena_dos):\n    contador = 0\n    for i in range(1, 101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(cadena_uno + cadena_dos)\n        elif i % 3 == 0:\n            print(cadena_uno)\n        elif i % 5 == 0:\n            print(cadena_dos)\n        else:\n            print(i)\n            contador += 1\n\n    return contador\n\n\nprint(numeros_textos(\"Helado\", \"Ice Cream\"))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/MarkTwin25.py",
    "content": "\"\"\"\r\nCrea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\r\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\r\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\r\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\r\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\r\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos\r\n\"\"\"\r\n\r\ndef funcion(parametro1: str, parametro2: str):\r\n    veces_numero = 0\r\n    for num in range(1,101):\r\n        cadena_a_imprimir = \"\"\r\n        if num % 3 == 0 and num % 5 == 0:\r\n            cadena_a_imprimir = parametro1 + \" \" + parametro2\r\n            print(cadena_a_imprimir)\r\n        elif num % 3 == 0:\r\n            cadena_a_imprimir = parametro1\r\n            print(cadena_a_imprimir)\r\n        elif num % 5 == 0:\r\n            cadena_a_imprimir = parametro2\r\n            print(cadena_a_imprimir)\r\n        else:\r\n            print(num)\r\n            veces_numero+=1\r\n    return veces_numero\r\n\r\nprint(funcion(\"cadena 1\", \"cadena 2\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/MercedesDF.py",
    "content": "\n#1. Funciones básicas\n#a) Función sin parámetros ni retorno\ndef saludo():\n    print(\"Hola, bienvenido al programa\")\n\nsaludo()\n#b) Función con un parámetro\ndef saludo_personalizado(nombre):\n    print(f\"Hola, {nombre}, bienvenido al programa\")\n\nsaludo_personalizado(\"Mercedes\")\n#c) Función con varios parámetros\ndef sumar(a, b):\n    resultado = a + b\n    print(f\"La suma de {a} y {b} es {resultado}\")\n\nsumar(5, 3)\n#d) Función con retorno\ndef multiplicar(a, b):\n    return a * b\n\nresultado = multiplicar(4, 6)\nprint(f\"El resultado de la multiplicación es {resultado}\")\n#e) Función dentro de otra función\ndef funcion_externa():\n    print(\"Esta es la función externa\")\n\n    def funcion_interna():\n        print(\"Esta es la función interna\")\n    \n    funcion_interna()\n\nfuncion_externa()\n\n#2. Uso de funciones ya creadas (funciones integradas en Python)\nnumeros = [3, 6, 9, 12]\nprint(f\"Números originales: {numeros}\")\nnumeros_duplicados = list(map(lambda x: x * 2, numeros))\nprint(f\"Números duplicados: {numeros_duplicados}\")\n\n#3. Variables locales y globales\n# Variable global\nmensaje = \"Hola desde el ámbito global\"\n\ndef imprimir_mensaje():\n    # Variable local\n    mensaje = \"Hola desde el ámbito local\"\n    print(mensaje)\n\nimprimir_mensaje()  # Imprime el mensaje local\nprint(mensaje)  # Imprime el mensaje global\n\n#4. Dificultad extra: Función que recibe dos cadenas y retorna un número\ndef extra(cadena1, cadena2):\n    contador_numeros = 0\n    for i in range(1, 101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(cadena1 + \" \" +cadena2)\n        elif i % 3 == 0:\n            print(cadena1)\n        elif i % 5 == 0:\n            print(cadena2)\n        else:\n            print(i)\n            contador_numeros += 1\n    return contador_numeros\n\nresultado = extra(\"cadena1\", \"cadema2\")\nprint(f\"Se ha impreso el número en lugar de texto {resultado} veces.\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/MiquelRR.py",
    "content": "# #02 FUNCIONES Y ALCANCE\n\n# sin parámeros\ndef fun() -> None:\n    print(\"¿quien eres?\")\n\nfun()\n\n#con un parámetro\ndef fun(nom) -> None:\n    print(f\"Hola {nom}\")\n\nfun(\"Pepe\")\n\n#con un parámetro por defecto\ndef fun(nom=\"Brais\") -> None:\n    print(f\"Hola {nom}\")\n\nfun()\n\n#con mas parámetros\ndef fun(n,nom) -> None:\n    print(f\"Hola {nom}\\n\"*n)\n\nfun(5,\"Pepe\")\n\n#con n parámetros\ndef fun(*nombres) -> None:\n    for nom in nombres:\n        print(f\"Hola {nom}\")\n\nfun(\"Carlos\",\"Pepe\")\n\n#devuelve un parámetro\ndef fun() -> str:\n    return \"¿quien eres?\"\n\nprint(fun())\n\n#entran n parámetros y devuelve n parámetros\ndef reversa(*cosas) -> tuple:\n    cosas=list(cosas)\n    rev=[]\n    for i in range(len(cosas)):\n        rev.append(cosas.pop())\n    return rev\n\na,b,c=reversa(1,2,3)\nprint(a,b,c)\n\n\n# funciones dentro de funciones y entorno de variables\nnombre=\"Ataulfo\"\ndef imprimehola() -> None:\n    def nombre()-> None:\n        if nombre ==\"Ataulfo\":\n            print(\"¿Que haces aqui, Ataulfo? ¡no perteneces a este entorno¡\")\n        else :\n            print(\"Brais!\")\n    print(\"¡Hola \", end=\"\")\n    nombre()\n\nimprimehola()\n\nnombre=\"Ataulfo\"\ndef imprimehola()-> None:\n    def nombre()-> None:\n        global nombre\n        if nombre ==\"Ataulfo\":\n            print(\"¿Que haces aqui, Ataulfo? ¡no perteneces a este entorno!?\")\n        else :\n            print(\"Brais!\")\n    print(\"¡Hola \", end=\"\")\n    nombre()\n\nimprimehola()\n\n# Función fizz-buzz, por ejemplo, con diccionarios\n\ndef fizbuzz(fizz=\"fizz\",buzz=\"buzz\",nf=3,nb=5,max=100) -> int:\n    '''\n    introduce las cadenas fizz y buzz en las posiciones de una lista de \n    enteros hasta max, donde sean multiplos nf o nb respectivamente\n    donde sean multiplos de ambos, concatena fizz+buzz\n    devuelve la cantidad de no-cambios\n    '''\n    max+=1\n    d0=dict(zip(range(1,max),[str(i) for i in range(1, max)]))\n    d1=dict(zip(range(nf,max,nf),[fizz]*int((max/nf))))\n    d2=dict(zip(range(nb,max,nb),[buzz]*int((max/nb))))\n    d1.update(d2)\n    d2=dict(zip(range(nf*nb,max,nf*nb),[fizz+buzz]*int((max/(nf*nb)))))\n    d1.update(d2)\n    d0.update(d1)\n    for ele in d0:\n        print(d0[ele])\n    return max-len(d1)-1 # quiza resultase mas interesante devolver el diccionario d0\n\nprint(fizbuzz())\n\n\n\n\n            \n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/MirandaYuber.py",
    "content": "# Funciones\nimport random\n\n\ndef hola():  # Función sencilla\n    print('Hola Mundo')\n\n\nhola()\n\n\ndef suma(num1=1, num2=10):  # Con argumentos\n    print(f'{num1} + {num2} = {num1 + num2}')\n\n\nsuma(5, 9)\n\n\ndef resta(num1, num2):  # Con argumentos y retorno\n    resultado = num1 - num2\n    return f'{num1} - {num2} = {resultado}'\n\n\nprint(resta(10, 9))\n\n\ndef imprimir_numeros_pares():  # Función dentro de una función\n    def es_par(num):\n        return num % 2 == 0\n\n    for i in range(0, 21):\n        if es_par(i):\n            print(i)\n\n\nimprimir_numeros_pares()\n\n\nvariable_global = 'Yuber'\n\n\ndef global_local():\n    variable_local = 'Miranda'\n    print(f'{variable_global} {variable_local}')\n\n\nglobal_local()\n\nprint('######  EXTRA  ######')\n\n\ndef extra(param1, param2):\n    contador = 0\n    for numero in range(1, 101):\n        if numero % 3 == 0 and numero % 5 == 0:\n            print(param1 + param2)\n        elif numero % 3 == 0:\n            print(param1)\n        elif numero % 5 == 0:\n            print(param2)\n        else:\n            print(numero)\n            contador += 1\n\n    return contador\n\n\nprint(extra(\"Yuber\", \"Python\"))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/MizadloGcia.py",
    "content": "\"\"\"\nFunciones simples\n\"\"\"\n\n# Sin parametro ni retorno\n\ndef greet():\n    print(\"Hola, Python!\")\n\n\ngreet()\n\n# Con un parametro sin retorno\n\ndef greet_arg(name):\n    print(f\"Hola, {name}!\")\n\n\ngreet_arg(\"Mizadlo\")\n\n# Con multiple parametro sin retorno\n\ndef greet_multiple_args(greet, name):\n    print(f\"{greet}, {name}!\")\n\n\ngreet_multiple_args(\"Hi\", \"Mizadlo\")\ngreet_multiple_args(name = \"Mizadlo\", greet = \"Hi\") # Indicando parametros\n\n# Sin parametro con retorno\n\ndef return_greet():\n    return \"Hola, Python!\"\n\n\nprint(return_greet())\n\n# Con un parametros con retorno\n\ndef return_greet_arg(name):\n    return f\"Hola, {name}!\"\n\n\nprint(return_greet_arg(\"Mizadlo\"))\n\n# Con multiples parametros con retorno\n\ndef return_greet_multiple_args(greet, name):\n    return f\"{greet}, {name}!\"\n\n\nprint(return_greet_multiple_args(\"Hi\", \"Mizadlo\"))\n\n# Con un argumento predeterminado\n\ndef default_greet_arg(name = \"Python\"):\n    print(f\"Hola, {name}!\")\n\n\ndefault_greet_arg(\"Mizadlo\")\ndefault_greet_arg()\n\n# Con retorno de multiple valores\n\ndef multiple_return_greet():\n    return \"Hola\", \"Python\"\n\n\ngreet, name = multiple_return_greet()\nprint(greet)\nprint(name)\n\n# Con un numero variable de parametros\n\ndef variable_arg_greet(*names):\n    for name in names:\n        print(f\"Hola, {name}!\")\n\n\nvariable_arg_greet(\"Python\", \"Mizadlo\", \"Garcia\", \"Javascript\")\n\n# Con un numero variable de parametros con palabra clave\n\ndef variable_key_arg_greet(**names):\n    for key, value in names.items():\n        print(f\"{value} ({key})!\")\n\n\nvariable_key_arg_greet(\n    language = \"Python\",\n    name = \"Mizadlo\",\n    last_name = \"Garcia\",\n    age = 33\n)\n\n\"\"\"\nFunciones anidadas\n\"\"\"\n\ndef outer_function():\n    def inner_function():\n        print(\"Funcion interna: Hola, Python !\")\n    inner_function()\n\n\nouter_function()\n\n\"\"\"\nFunciones del lenguaje (built-in)\n\"\"\"\n\nprint(len(\"Mizadlo\"))\nprint(type(33))\nprint(\"Mizadlo\".upper())\n\n\"\"\"\nVariables locales y globales\n\"\"\"\n\nglobal_var = \"Python\"\n\ndef hello_phyton():\n    local_var = \"Hola\"\n    print(f\"{local_var}, {global_var}!\")\n\nprint(global_var)\n# print(local_var) No se puede acceder desde fuera de la funcion hello_python()\n\nhello_phyton()\n\n\"\"\"\nExtra\n\"\"\"\n\ndef print_numbers(text_1, text_2) -> int:\n    count = 0\n    for number in range(1, 101):\n        if number % 3 == 0 and number % 5 == 0:\n            print(text_1 + text_2)\n        elif number % 3 == 0:\n            print(text_1)\n        elif number % 5 == 0:\n            print(text_2)\n        else:\n            print(number)\n            count += 1\n\n\nprint_numbers(\"Fizz\", \"Buzz\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Monikgbar.py",
    "content": "# Función sin parámetros\ndef suma():\n    suma = 3 + 2\n    print(suma)\n\n# Función con uno parámetro\ndef suma(a=3):\n    suma = a + 2\n    print(suma)\n\n# Función con dos parámetros y retorno\ndef suma(a=3,b=2):\n    suma = a + b\n    print(suma)\n    return suma\n\n# Función dentro de función\ndef funcion():\n   def dentro_funcion():\n      return \"Función dentro de función\"\n   return \"Función principal\"\nfuncion()\n\n# Ejemplo de función ya creada en el lenguaje\nprint(len(\"Hola Mundo\")) # len: Obtiene la longitud de la cadena\n\n# Variable Local y global\ndef suma():\n   var_local = 5\n   print(\"Esto es una variable local\", var_local)\n   print(\"Esto es una variable global\", var_global)\n\nif __name__ == \"__main__\":\n    var_global = 5\n    print(\"Imprimo la variable global desde el main\", var_global)\n    suma()\n\n# DIFICULTAD EXTRA:\n\ndef imprimir_numeros(num1,num2):\n    contador = 0\n    for num in range(1, 101):\n        if num % 3 == 0:\n            print(num1)\n        elif num % 5 == 0:\n            print(num2)\n        elif num % 3 == 0 and num % 5 == 0:\n            print(num1 + num2)\n        else:\n            print(num)\n\n    print(\"Hola\", \"Python\")\n    \n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Mstaz4.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */ \"\"\"\n\n# Crea ejemplos de funciones básicas que representen las diferentes posibilidades del lenguaje:\n#   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n\n\ndef factorial(numero):\n    if numero == 0:\n        return 1\n    else:\n        return numero * factorial(numero - 1)\n\n\nnumero = 10\nprint(f\"El factorial de {numero} es: {factorial(10)}\")\n\n\ndef suma(a, b, c):\n    resultado = a + b + c\n    print(f\"{a} + {b} + {c} == {resultado}\")\n    resultado\n\n\nprint(\n    f\"El resultado de sumar tres veces {numero} es: {suma(numero, numero, numero)}\")\n\n\ndef holaMundo():\n    print(\"Hola mundo\\n\")\n\n\nholaMundo()\n\n# Comprueba si puedes crear funciones dentro de funciones.\n\n\ndef funcion():\n    def funcion_2():\n        print(\"Sí se puede\\n\")\n    return funcion_2()\n\n\nfuncion()\n\n# Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\ncadena = \"Hola python\"\nprint(f\"La longitud de la cadena es {len(cadena)}\\n\")\n\n# Pon a prueba el concepto de variable LOCAL y GLOBAL.\nglobal_variable = 10\n\n\ndef producto():\n    local_variable = 5\n    global_variable = 2\n    print(\n        f\"Variable global con valor local: {global_variable} y variable local: {local_variable}\")\n\n\nproducto()\nprint(f\"Valor de variable global:  {global_variable}\")\n\n\"\"\" \n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos. \n\"\"\"\n\nprint(\"\\nFunción que recibe dos parámetros y retorna un número\")\ncadena1 = input(\"Ingrese primera cadena: \")\ncadena2 = input(\"Ingrese segunda cadena: \")\n\n\ndef contador(cadena1, cadena2):\n    count = 0\n    for i in range(0, 101):\n        if i % 5 == 0 and i % 3 == 0:\n            print(cadena1 + cadena2)\n        elif i % 3 == 0:\n            print(cadena1)\n        elif i % 5 == 0:\n            print(cadena2)\n        else:\n            print(i)\n            count += 1\n    return (count)\n\n\nprint(\"La cantidad de veces que se mostaron números fueron: \",\n      contador(cadena1, cadena2))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/NeicerVB.py",
    "content": "\"\"\"\nCrea ejemplos de funciones básicas que representen\nlas diferentes posibilidades del lenguaje\n\"\"\"\n\n# Funcion sin argumentos ni retornos\ndef bio():\n    print(\"Soy Autodidacta y me gusta aprender sobre programación.\\n \\\n          - Aprendo sobre IA y Machine Learning en Platzi.\\n \\\n          - Aprendo sobre Python con Mouredev\")\n    \nbio()\n\n# Funcion con argumento de posición y por defecto, y sin retorno\ndef birthday(nombre, fecha=\"23 de Diciembre\"):\n    print(f\"Me llamo {nombre} y cumplo el {fecha}\")\n    \nbirthday(\"Neicer Vásquez\")\n\n# Funcion con argumentos por nombres y con retorno\ndef specialty(universidad, especialidad, pais):\n    return f\"Soy de {pais} y estudio en la Universidad {universidad} en la especialidad {especialidad}\"\n\nprint(specialty(pais=\"Ecuador\", universidad=\"ESPOL\", especialidad=\"Ciencia de datos e Inteligencia Artificial\"))\n\n\n# Usando Funciones nativas del lenguaje\nnotas = [9,9,9,9,9,10,8,8,1,1,1,1,1,1,1]\npromedio = sum(notas)/len(notas)\nprint(promedio)\n\n\n# Aplicando paso por valor y paso por referencia\n### Paso por valor\n\"\"\"Intentar cambiar un objeto inmutable (int, string, tuple)\"\"\"\nactualidad = 76\ndef battery(actualidad):\n    actualidad = 0\n    \nprint(actualidad)\n\n### Paso por referencia\n\"\"\"Intentar cambiar un objeto mutable (list, dict)\"\"\"\ncalificaciones = [8,9,10,8,9,10]\ndef add(nota):\n    nota.append(10)\n\nadd(calificaciones)\nprint(calificaciones)\n\ncalificaciones_2 = [8,9,10,8,9,10]\ndef add(nota_2):\n    nota_2 = []\n\nadd(calificaciones_2)\nprint(calificaciones_2)\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/NeosV.py",
    "content": "# funcion con retorno\ndef return_greet ():\n    return \"Hola python\"\n\nvalor_return = return_greet()\n\nprint (return_greet())\nprint (valor_return)\n\n# funcion con argumento de entrada\n\ndef di_hola (carro):\n    print (\"Saluda a mi\", carro)\n\ndi_hola(\"Skoda\")\n\n# funcion con argumentos por posicion \n\ndef suma (a,b):\n    return (a+b)\n\nprint (suma(5 ,4))\n\n# funcion con argumentos por nombre \n\ndef resta (a = 2, b =3):\n    return (a-b)\n\nprint (resta())\n\n# funcion con argumentos por defecto\n\ndef multiplicacion (a,b,c=2):\n    return (a*b*c)\n\nprint (multiplicacion(3,2,))\n\n# funcion con argumentos de longitud variable (con tuplas)\n\ndef suma_tupla (*numeros):\n    print (type(numeros))\n    total = 0\n    for i in numeros:\n        total += i\n    return total \n    \nprint(suma_tupla(1,3,4,5,6))\n\n# funcion con argumentos de longitud variable (con key y value)\n\ndef suma_value(**numeros):\n    print (type(numeros))\n    total = 0\n    for key, value in numeros.items():\n        print (key,value)\n        total += value\n    return total\n\nprint (suma_value(a=5, b=20, c=23))  \n\ndic = {\"a\" : 10, \"b\" : 20, \"c\" :23}\n\ndef suma_entry(**kwargs):\n    total = 0\n    for key, value in kwargs.items():\n        print (key, value)\n        total += value\n    return total\n\nprint (suma_entry(**dic))     \n\n# funcion con return dobles\n\ndef suma_con_returns (a,b,c):\n          suma = a+b+c\n          resta = a-b-c\n          return suma, resta\n\nprint(suma_con_returns(1, 2, 3))\n\n# funcion con anotacion \n\ndef suma_anotacion (numero : int):\n     return numero*3\n\nprint (suma_anotacion(\"carro\"))\n\n    \n# funcion lambda\n\nsuma_lambda = lambda a,b : a + b\n\nprint (suma_lambda (2,4))\n\nprint((lambda a, b: a - b)(2, 4))\n\n\n# funcion factorial recursiva\n\ndef factorial_recursivo(n):\n    if n == 1:\n        return 1\n    else:\n        return n * factorial_recursivo(n-1)\n\nprint (factorial_recursivo(5)) # 120\n\ndef fibonacci(n):\n    if n == 0:\n        return 0\n    elif n == 1:\n        return 1\n    else:\n        return fibonacci(n-1) + fibonacci (n-2)\n    \nprint (fibonacci(7))    \n\n\n#funcion decorador (una funcion dentro de otra funcion)\n\ndef funciondecorador (funcion):\n    def reloj(a,b):\n         \n         print (f\" askjdajdklsa {a-b}\")\n\n         funcion(a,b)\n\n    return reloj         \n\n@funciondecorador\ndef suma(a,b):\n    \n    print (f\" carro {a+b}\")\n\nsuma(5,3)\n\n\n# funcion generador (yield)\n\ndef yield_example(a):\n\n    for i in range (a):\n     print (i)\n\nyield_example(5)     \n\n# funcion map \n\nlista = [1,2,3,4,5]\n\ndef por_2(x):\n    return x*2\nlistapor_2 = map(por_2, lista)\n\nprint(list(listapor_2))\n\n#funcion filter \n\nlista = [1,2,3,4,5,7,8,9,10]\n\ndef pares(x):\n   \n     return  x % 2 == 0\n\nfiltropares = filter(pares, lista)\n\nprint(list(filtropares))\n\n#funciones globales y locales\n\nvariable_global = \"Esta variable puede ser accedida por cualquier funcion\"\n\ndef funcion_local ():\n    variable_local = 2*2+2\n    print (variable_local)\n\nfuncion_local()\n\ndef funcion_x():\n\n   \"\"\"variable_local  no sirve pues esta definida dentro de una funcion\"\"\"\n\n\n# ejercicio dificultad extra \n\ndef ejercicio (a, b):\n\n    contador = 0  \n\n    for i in range (1,101):\n\n       \n\n        if i % 3 == 0 and i % 5 == 0:\n            \n            formato = (f\"{a} y {b}\")\n            print(formato)\n\n        elif i % 3 == 0:\n             \n             print(a)\n\n        elif i % 5 == 0 :\n            \n             print (b)\n\n        else:\n             print (i) \n             contador += 1\n\n    return contador \n                    \n\nresultado = ejercicio(\"Multiplo de 3\",\"Multiplo de 5\")\nprint(f\"se imprio un numero en vez de un texto un total de: {resultado} veces\")\n\n        \n\n    \n        \n          "
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/NicoHeguaburu.py",
    "content": "#funciones basicas\n\n#simples\ndef saludar():\n    print(\"Hola Python\")\n\nsaludar()\n\n#retorno\ndef funcion_de_retorno():\n    return \"retorno de funcion\"\n\nprint(funcion_de_retorno())\n\n#con argumento\n \ndef saludo_de_cumpleaños(años, nombre):\n    print(f\"felicidades por tus {años} años {nombre}\")\n\nsaludo_de_cumpleaños(33, \"mateo\")\n\n\n#con un argumento predeterminado\ndef saludo_de_cumpleaños_predeterminado(años, nombre=\"crack!\"):\n    print(f\"felicidades por tus {años} años {nombre}\")\n\nsaludo_de_cumpleaños_predeterminado(33)\n\n\n#con retorno de varios valores\n\ndef retorno_multiple():\n    return \"Hola\",\"Maxi\"\n\nsaludo, nombre = retorno_multiple()\nprint(saludo)\nprint(nombre)\n\n#funciones con numero variable de argumentos\n\ndef argumentos_multiples_variables(*names):\n    for name in names:\n        print(f\"Hola, {name}!\")\n    \n\nargumentos_multiples_variables(\"Nicolás\", \"Maxi\", \"Pepe\", \"Lorena\", \"Melani\")\n\n\n#con numero variable de argumentos con palabra clave\n\ndef argumentos_multiples_variables(**names):\n    for key, value in names.items():\n        print(f\"{value} ({key})!\")\n    \n\nargumentos_multiples_variables(\n    name = \"Nicolás\",\n    edad = 32,\n    idioma = \"español\",\n    nacionalidad = \"uruguayo\",\n    )\n\n\n\n\n\n#FUNCIONES DENTRO DE FUNCIONES\n\ndef funcion_contenedora():\n    def funcion_contenida():\n        print(\"soy una funcion interna\")\n    funcion_contenida()\n\nfuncion_contenedora()\n\n\n#FUNCIONES YA CREADAS EN PYTHON\n\nprint(len(\"Nicolás Heguaburu\"))\nprint(type(32))\nprint(\"nico\".upper())\n\n\n# Variables locales y globales\n\nglobal_var = \"python\"\n\nprint(global_var)\n\ndef hola_python():\n    local_var = \"hola\" #solo la puedo llamar en la funcion hola_python()\n    print(f\"Hola {global_var}\")\n\nhola_python()\n\n\n\n#EJERCICIO EXTRA\n\ndef mi_funcion (str1, str2):\n    num = 0\n    for i in range(1, 101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(f\"{str1} y {str2}\")\n        elif i % 3 == 0:\n            print(str1)\n        elif i % 5 == 0:\n            print(str2)\n        else:\n            print(i)\n            num += 1\n    return num\n        \n\n\nprint(mi_funcion(\"soy multiplo de 3\", \"soy multiplo de 5\"))\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Nicojsuarez2.py",
    "content": "# #02 FUNCIONES Y ALCANCE\n\n'''\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n'''\n\n# Función sin parámetros ni retorno\ndef hello():\n    print(\"Hello World!\")\n\nhello()\n\n#Funcion con un parametro\ndef hello_name(name):\n    print(f\"Hello {name}!\")\n\nhello_name(\"Nico\")\n\n#Funcion con parametro por defecto\ndef potencia(base, exponente=2):\n    return base ** exponente\n\nprint(f\"El cuadrado de 5 es: {potencia(5)}\")\n\n#funcion con parametros no definidos\ndef sumar_varios(*args):\n    return sum(args)\n\nprint(f\"La suma de varios números es: {sumar_varios(1, 2, 3, 4, 123)}\")\n\n#funcion con argumentos nombrados\ndef mostrar_info(**kwargs):\n    for clave, valor in kwargs.items():\n        print(f\"{clave}: {valor}\")\n\nmostrar_info(nombre=\"Nico\", edad=23, ciudad=\"Bogotá\")\n\n#funcion lambda\nprint((lambda x: x * 2)(7))\n\n#funcion con una funcion dentro\ndef operacion(x):\n    def cuadrado(n):\n        return n ** 2\n    return cuadrado(x)\n\nprint(f\"El cuadrado de 6 es: {operacion(6)}\")\n\n\n\n#funcion \ndef suma(a, b):\n    return a + b    \n\nprint(suma(2, 3))\n\ndef funcion():\n    def funcion_interna():\n        print(\"Función interna\")\n    funcion_interna()\n\nfuncion()\n\ndef funcion_global():\n    global a\n    a = 5\n    print(a)\n\nfuncion_global()\n\ndef funcion_local():\n    a = 5\n    print(a)"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/NightAlchemist.py",
    "content": "#Functions\n\n# 1. Función sin parámetros ni retorno\ndef saludar():\n    print(\"¡Hola, bienvenido a Python!\")\n\nsaludar()\n\n# 2. Función con un parámetro\ndef saludar_nombre(nombre):\n    print(f\"¡Hola, {nombre}!\")\n\nsaludar_nombre(\"Jhoao\")\n\n# 3. Función con múltiples parámetros\ndef sumar(a, b):\n    print(f\"La suma de {a} y {b} es: {a + b}\")\n\nsumar(5, 3)\n\n# 4. Función con retorno de valor\ndef multiplicar(a, b):\n    return a * b\n\nresultado = multiplicar(4, 6)\nprint(f\"El resultado de la multiplicación es: {resultado}\")\n\n# 5. Función con parámetros por defecto\ndef potencia(base, exponente=2):\n    return base ** exponente\n\nprint(f\"El cuadrado de 5 es: {potencia(5)}\")\nprint(f\"5 elevado a la 3 es: {potencia(5, 3)}\")\n\n# 6. Función con un número variable de argumentos (*args)\ndef sumar_varios(*numeros):\n    return sum(numeros)\n\nprint(f\"La suma de varios números es: {sumar_varios(1, 2, 3, 4, 5)}\")\n\n# 7. Función con argumentos nombrados (**kwargs)\ndef mostrar_info(**datos):\n    for clave, valor in datos.items():\n        print(f\"{clave}: {valor}\")\n\nmostrar_info(nombre=\"Jhoao\", edad=30, ciudad=\"Bogotá\")\n\n# 8. Función lambda (función anónima con retorno)\ndoblar = lambda x: x * 2\nprint(f\"El doble de 7 es: {doblar(7)}\")\n\n# 9. Función con una función dentro (función anidada)\ndef operacion(x):\n    def cuadrado(n):\n        return n ** 2\n    return cuadrado(x)\n\nprint(f\"El cuadrado de 6 es: {operacion(6)}\")\n\n# 10. Función generadora (yield)\ndef contar_hasta(n):\n    for i in range(1, n+1):\n        yield i\n\nfor numero in contar_hasta(5):\n    print(numero)\n\n#Dificultad extra\n\ndef print_numbers(string1,string2):\n    def count_until(n):\n        for i in range(1, n+1):\n            yield i\n            \n    how_many = 0\n    \n    for numero in count_until(100):\n        if numero % 3 == 0 and numero % 5 == 0:\n            print(f\"{string1} and {string2}\")\n        elif numero % 3 == 0:\n            print(string1)\n        elif numero % 5 == 0:\n            print(string2)\n        else:\n            print(numero)\n            how_many += 1\n    \n    print(f\"Total de números: {how_many}\")\n\nprint_numbers(\"Fizz\",\"Buzz\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/NoMeLlamoDante.py",
    "content": "#02 FUNCIONES Y ALCANCE\n\"\"\"EJERCICIO:\n- Crea ejemplos de funciones básicas que representen las diferentes posibilidades del lenguaje:\n    Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n- Comprueba si puedes crear funciones dentro de funciones.\n- Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n- Pon a prueba el concepto de variable LOCAL y GLOBAL.\n- Debes hacer print por consola del resultado de todos los ejemplos.\n    (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n    \"\"\"\n#Functions\ndef simple_function():\n    print(\"funcion simple\")\nsimple_function()\n\ndef return_function():\n    return \"funcion con retorno\"\nprint(return_function())\n\ndef multiple_return_function():\n    return \"funcion\", \"multiple\",\"retorno\"\nprint(multiple_return_function())\n\ndef one_parameter_function(parameter):\n    print(f\"funciones con un solo {parameter}\")\none_parameter_function(\"parametro\")\n\n\ndef multiple_paramater_function(parameter_one=\"1\", parameter_two= \"2\", *another_parameters):\n    print(f\"parameter one: {parameter_one} || parameter two:{parameter_two}\")\n    for parameter in another_parameters:\n        print(parameter)\nmultiple_paramater_function()\nmultiple_paramater_function(parameter_two=\"two\",parameter_one=\"one\")\nmultiple_paramater_function(\"hola\", \"mundo\", \"hecho\", \"en\", \"python\")\n\ndef multiple_named_parameters(**parameters):\n    for index, parameter in parameters.items():\n        print(f\"index: {index}, value: {parameter}\")\n\nmultiple_named_parameters(\n    one= \"hola\", \n    two= \"mundo\",\n    three= \"python\")\n\n#Function in functions\ndef extern_function(param_1,param_2, param_3):\n    \n    def intern_function(_param_2, _param_3):\n        return _param_2+ _param_3\n\n    return lambda param_4, param_5:param_4+param_5+intern_function(param_2,param_3)+param_1\n\nprint(extern_function(1,2,3)(4,5)) #15\n\n#Built in Functions\nprint(len(\"hola mundo\")) # Character count\nprint(type(\"String\"))\nprint(9.9)\nprint(10)\nprint(bin(111111))\nprint(int(\"45\"))\n\n#Local and Global Variables\nvariable = \"Global\"\ndef printable(variable):\n    print(variable)\n\nprint(variable)\nprintable(\"Local\")\nprint(variable)\n\n\"\"\"DIFICULTAD EXTRA (opcional):\nCrea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n- La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n    - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n    - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n    - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n    - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\nPresta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\nCada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\"\"\"\n\ndef two_strings(_string_one, _string_two):\n    count = 0\n    for index in range(1, 101):\n        text = \"\"\n        if index%3 == 0:\n            text+=_string_one\n        if index%5 == 0:\n            text+=_string_two\n        if text == \"\":\n            print(index)\n            count+=1\n        else:\n            print(text)\n    return count\n\nprint(two_strings(\"one\",\"two\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/NotJ0S3.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * - Crea ejemplos de funciones básicas que representen las diferentes\n#  *   posibilidades del lenguaje:\n#  *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\ndef sin_pr_rt():\n    print(\"Funcion sin parametros ni retorno\")\n    \nsin_pr_rt()\n\ndef varios_pr(a, b):\n    print(\"Funcion con varios parametros\")\n    print(f'La suma de {a} y {b} es {a + b}')\n    \nvarios_pr(5, 4)\n\ndef con_rt():\n    return \"Funcion con retorno\"\n\nprint(con_rt())\n\n\n#  * - Comprueba si puedes crear funciones dentro de funciones.\n\ndef funcion1():\n    def funcion2():\n        return \"Saludos desde una funcion dentro de otra\"\n    return funcion2()\n\nprint(funcion1())\n\n#  * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n\ndef contador_caracteres(cadena = str):\n    return f'El total de caracteres en la palabra {cadena} es de {len(cadena)}'\n\nprint(contador_caracteres(\"Hola Mundo!\"))\n\n#  * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n\nvariable_global = \"Es aquella la cual se puede acceder desde cualquier parte del codigo :)\"\n\ndef funcion_var_local():\n    variable_local = \"Es aquella que solo se puede acceder dentro de una parte del codigo\"\n    return variable_local\n\nprint(variable_global)\nprint(funcion_var_local())\n# print(variable_local) En este caso no podremos acceder a la variable local\n\n#  * - Debes hacer print por consola del resultado de todos los ejemplos.\n#  *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n#  * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n#  *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n#  *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n#  *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n#  *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n#  *\n#  * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n#  * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n#  */\n\nfrase1 = input(\"Dame una frase: \")\nfrase2 = input(\"Dame otra más: \")\n\ndef ejercicio_extra(txt1 = str, txt2 = str):\n    for i in range(1, 101):\n        if i % 3 == 0 and i % 5 != 0:\n            print(txt1)\n        elif i % 3 != 0 and i % 5 == 0:\n            print(txt2)\n        elif i % 3 == 0 and i % 5 == 0:\n            print(txt1 + txt2)\n        else:\n            print(i)\n\nejercicio_extra(frase1, frase2)"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Pablo25.py",
    "content": "# 02 - Python - FUNCIONES Y ALCANCE\n# Las funciones permiten definir un bloque de código reutilizable que se puede ejecutar muchas veces dentro de un programa.\n# El alcance (o scope) se refiere a la región de un programa donde una variable es visible y accesible. \n# EJERCICIO:\n'''*- Crea ejemplos de funciones básicas que representen las diferentes posibilidades del lenguaje: \nSin parámetros ni retorno, con uno o varios parámetros, con retorno'''\n\ndef funcion_sin_parametros():\n    print(\"Función sin parámetros ni retorno\")\ndef funcion_sin_retorno_con_parametros(param1, param2):\n    suma = param1 + param2\n    print(f\"Suma de {param1} y {param2} es: {suma}\")\ndef funcion_con_un_parametro(nombre):\n    print(f\"Hola, {nombre}!\")\ndef funcion_con_varios_parametros(a, b):\n    return a + b\ndef funcion_con_retorno():\n    return \"Esta es una función con retorno.\"\n# Llamadas a las funciones\nfuncion_sin_parametros()\nfuncion_sin_retorno_con_parametros(5, 10)\nfuncion_con_un_parametro(\"Pablo\")\nresultado = funcion_con_varios_parametros(3, 7)\nprint(f\"Resultado de la función con varios parámetros: {resultado}\")\nmensaje = funcion_con_retorno()\nprint(mensaje)\n\n'''*- Comprueba si puedes crear funciones dentro de funciones.'''\n# Si es posible usar funciones anidadas, pero por lo que entiendo, su uso es poco frecuente.\ndef funcion_externa():\n    def funcion_interna():\n        return \"Hola desde la función interna!\"\n    return funcion_interna()\n\nprint(funcion_externa())\n\n'''*- Utiliza algún ejemplo de funciones ya creadas en el lenguaje.'''\n# Ejemplo usando la función len() que devuelve la longitud de un objeto.\nmi_lista = [1, 2, 3, 4, 5]\nlongitud = len(mi_lista)\nprint(f\"La longitud de la lista es: {longitud}\")\n# Ejemplo usando la función sum() que devuelve la suma de los elementos de un iterable.\nsuma_lista = sum(mi_lista)\nprint(f\"La suma de la lista es: {suma_lista}\")\nfor i in range(5):\n    print(f\"Elemento {i} de la lista\")\n# Ejemplo usando la función max() que devuelve el valor máximo de un iterable.\nmaximo = max(mi_lista)\nprint(f\"El valor máximo de la lista es: {maximo}\")\n\n'''*- Pon a prueba el concepto de variable LOCAL y GLOBAL. Debes hacer print por consola del resultado de todos los ejemplos.\n(y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)'''\n# Variable global\nmensaje_global = \"Soy global\"\ndef funcion_con_local(): # Esta es una nueva variable local que \"oculta\" a la global.\n  mensaje_local = \"Soy local\"\n  print(f\"Dentro de la función: {mensaje_local}\")\n  print(f\"Accediendo a la global desde dentro: {mensaje_global}\")\n# Llamada a la función\nfuncion_con_local()\nprint(f\"Fuera de la función: {mensaje_global}\")\n# Dentro de la función: Soy local\n# Accediendo a la global desde dentro: Soy global\n# Fuera de la función: Soy global\n# Si intentamos acceder a la variable local fuera de la función, obtendremos un error.\n\n'''* DIFICULTAD EXTRA (opcional):\n *- Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n   La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n    - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n    - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n    - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n    - La función retorna el número de veces que se ha impreso el número en lugar de los textos.'''\n\n#Respuesta al ejercicio extra: con ayuda de copilot\ndef magic_math(param1, param2):\n        contador = 0\n        for i in range(1, 101):\n            if i % 3 == 0 and i % 5 == 0:\n                print(param1 + param2)\n            elif i % 3 == 0:\n                print(param1)\n            elif i % 5 == 0:\n                print(param2)\n            else:\n                print(i)\n                contador += 1\n        return contador\n\n#Respuesta al ejercicio extra: indagando un poco más, recordando un ejercicio similar en turbo pascal, y una revision con DeepSeek\ndef dificil_extra():\n    print(\"Hola, por favor ingresa las palabras.\")\n    param1 = input(\"Palabra 1:\")\n    param2 = input(\"Palabra 2:\")\n    def magic_math(param1, param2):\n        contador = 0\n        for i in range(1, 101):\n            if i % 3 == 0 and i % 5 == 0:\n                print(param1 + param2)\n            elif i % 3 == 0:\n                print(param1)\n            elif i % 5 == 0:\n                print(param2)\n            else:\n                print(i)\n                contador += 1\n        return contador\n    return magic_math(param1, param2)\nveces = dificil_extra()\nprint(f\"El número se imprimió {veces} veces.\")\n\n# Respuesta al ejercicio extra: indagando un poco más y mucha más ayuda de DeepSeek\ndef get_inputs(): #Función para obtener las palabras del usuario\n    print(\"Bienvenido, por favor ingresa las palabras.\")\n    param1 = input(\"Palabra 1: \")\n    param2 = input(\"Palabra 2: \")\n    if not param1.strip() or not param2.strip():\n        print(\"Error: Las palabras no pueden estar vacías\")\n        return get_inputs()\n    return param1, param2\n\ndef magic_math(param1, param2): #Función para realizar la lógica principal\n    contador = 0\n    for i in range(1, 101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(param1 + param2)\n        elif i % 3 == 0:\n            print(param1)\n        elif i % 5 == 0:\n            print(param2)\n        else:\n            print(i)\n            contador += 1\n    return contador\n\ndef main(): #Función principal para ejecutar el programa\n    param1, param2 = get_inputs()\n    veces = magic_math(param1, param2)\n    print(f\"El número se imprimió {veces} veces.\")\n\nif __name__ == \"__main__\": #Punto de entrada del programa\n    main()"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Paprikaistkrieg.py",
    "content": "#funciones\n# Definición de la función  \n\n\"\"\"\nUna función en Python Y en diferentes LENGUAJES; es un bloque de código reutilizable que ejecuta una tarea específica.\nTe permite organizar, reducir la repetición, y hacer tu código más limpio\n\"\"\"\n\n#📦 Función definida por el usuario\n\n#funciones simples\n\n\"\"\"se define con la palabra def, seguida del nombre de la función y paréntesis. Dentro de los paréntesis, puedes definir parámetros que la función puede recibir. Por ejemplo\"\"\"\n\ndef greet():\n    print(\"Hola, Python\")\n\n# Llamada a la función\n\n\"\"\"\nPara ejecutar la función, simplemente la llamas por su nombre seguido de paréntesis, asi no creas logica demas por asi decirlo, \nes una funcion simple que no recibe parametros ni retorna nada, solo ejecuta una acción, por eso al invocar greet() se imprime \"Hola, Python\" en la consola en este caso.\nPuedes llamar a la función varias veces si lo deseas, y cada vez que lo hagas, se ejecutará el código dentro de la función.\n\"\"\"\n\ngreet()\ngreet()\n\n#funciones con retorno \n\n\"\"\"Si deseas que una función devuelva un valor, puedes usar la palabra clave return.\n Esto permite que la función devuelva un resultado que puede ser utilizado más adelante en el código.\n Por ejemplo, si quieres que una función devuelva un saludo en lugar de imprimirlo directamente, puedes hacer lo siguiente:\"\"\"\n\ndef return_greet(): \n    return \"Hola de nuevo, Python\"  \n\nreturn_greet()  # Llamada a la función\n\"\"\"Al llamar a return_greet(), obtienes el valor de retorno \"Hola de nuevo, Python\". Puedes almacenar este valor en una variable o imprimirlo directamente.\"\"\"\n\ngreeting = return_greet()  # Almacena el valor de retorno en una variable\n\nprint(greeting)  # Imprime el saludo almacenado\n\n\"\"\"también puedes imprimir el valor de retorno directamente si lo prefieres.\"\"\"\n\nprint(return_greet())\n\n\"\"\"aquí puedes ver cómo se utilizan las funciones para obtener y mostrar información de manera más estructurada.\nLas funciones te permiten encapsular la lógica y reutilizar el código de manera eficiente, lo que es especialmente útil en proyectos más grandes y complejos.\"\"\"\n\n#funciones con argumentos\n\n\"\"\"Las funciones también pueden aceptar argumentos, que son parámetros que se pasan a la función cuando se llama.\nEsto permite que la función realice operaciones con esos parámetros\"\"\"\n\n\ndef argumento_greet(name = \"Python\"): #aquí se define un argumento con un valor por defecto\n    print(f\"Hola, {name}\")\n\nargumento_greet() # Llamada a la función sin argumentos, usa el valor por defecto\n\n\"\"\"En este caso, la función argumento_greet toma un argumento name con un valor por defecto de \"Python\". \nSi no se proporciona un argumento al llamar a la función, se utilizará el valor por defecto.\"\"\"\n\nargumento_greet(\"Iván\")  # Llamada a la función con otro argumento\nargumento_greet(\"Jessica\")  # Llamada a la función con otro argumento\n\n\"\"\"En este caso, la función argumento_greet toma un argumento (name) y devuelve un saludo personalizado.\nPuedes llamar a la función con diferentes nombres para obtener saludos personalizados.\"\"\"\n\n#funciones con múltiples argumentos\n\ndef argumentos_multiples_greet(greeting=\"Hola\", name=\"Python\"):\n    print(f\"{greeting}, {name}\")\n\n\nargumentos_multiples_greet(name= \"Iván\", greeting= \"Hola\")  # Llamada a la función con múltiples argumentos y tambien a los argumentos es posibles de cambiar el orden siempre que se indique cual es cada uno\nargumentos_multiples_greet(\"Buenos días\", \"Jessica\")  # Llamada a la función con otros argumentos\nargumentos_multiples_greet()  # Llamada a la función sin argumentos, usa los valores por defecto\n\n\"\"\"En este caso, la función argumentos_multiples_greet toma dos argumentos: greeting y name, ambos con valores por defecto.\nPuedes llamar a la función con diferentes combinaciones de argumentos para obtener saludos personalizados.\"\"\"\n\n#funciones con argumentos y retorno (return)\n\ndef return_argumentos_greet(greeting=\"Hola\", name=\"Python\"):\n    return f\"{greeting}, {name}\"\n\nprint(return_argumentos_greet(name= \"Iván\", greeting= \"Hola\"))  # Llamada a la función con múltiples argumentos y tambien a los argumentos es posibles de cambiar el orden siempre que se indique cual es cada uno\nprint(return_argumentos_greet(\"Buenos días\", \"Jessica\"))  # Llamada a la función con otros argumentos\nprint(return_argumentos_greet())  # Llamada a la función sin argumentos, usa los valores por defecto\n\n\"\"\"\nEn este caso, la función return_argumentos_greet toma dos argumentos: greeting y name, ambos con valores por defecto.\nPuedes llamar a la función con diferentes combinaciones de argumentos para obtener saludos personalizados,\n y también puedes almacenar el valor de retorno en una variable o imprimirlo directamente.\n \"\"\"\n\n\n#funcion con retorno de varios valores\n\ndef return_multiple_values():\n    return \"Hola\", \"Python\"\n# Llamada a la función\ngreeting, language = return_multiple_values()  # Desempaquetado de valores de retorno\nprint(greeting)  # Imprime \"Hola\"\nprint(language)  # Imprime \"Python\"\n\"\"\"\nEn este caso, la función return_multiple_values devuelve dos valores: un saludo y un lenguaje .\nPuedes desempaquetar estos valores en variables separadas al llamar a la función.\nEsto es útil cuando necesitas devolver múltiples resultados de una función.\n\"\"\"\n\n#funciones con un número variable de argumentos\n\"\"\"A veces, es posible que desees crear una función que acepte un número variable de argumentos.\nPuedes lograr esto utilizando el operador *names en la definición de la función.\nEsto te permite pasar cualquier cantidad de argumentos a la función, y se unirán en una tupla.\"\"\"\n\ndef variable_arguments_greet(*names):\n    for name in names:\n        print(f\"Hola, {name}!\")\n# Llamada a la función con un número variable de argumentos\n\nvariable_arguments_greet(\"Iván\", \"Jessica\", \"Python\")\n\n\"\"\"\nEn este caso, la función variable_arguments_greet utiliza el operador *names para aceptar un número variable de argumentos.\nPuedes pasar cualquier cantidad de argumentos a la función, y estos se reciben como una tupla que se procesa individualmente en el bucle.\nEsto es útil cuando no sabes cuántos argumentos se pasarán a la función.\n\"\"\"\n#funciones con un número variable de argumentos con nombre clave\n\n\"\"\"De manera similar, puedes crear una función que acepte un número variable de argumentos con nombre clave utilizando el operador **kwargs.\nEsto te permite pasar cualquier cantidad de argumentos con nombre a la función, y se unirán en un diccionario.\"\"\"\n\ndef variable_keyword_arguments_greet(**kwargs):\n    for key, value in kwargs.items():\n        print(f\"{key}: {value}\")\n# Llamada a la función con un número variable de argumentos con nombre clave\n\nvariable_keyword_arguments_greet(name=\"Iván\", greeting=\"Hola\", language=\"Python\")\n\n\n\"\"\"\nEn este caso, la función variable_keyword_arguments_greet utiliza el operador **kwargs para aceptar un número variable de argumentos con nombre clave.\nPuedes pasar cualquier cantidad de argumentos con nombre a la función, y estos se reciben como un diccionario que se procesa individualmente en el bucle.\nEsto es útil cuando necesitas pasar múltiples parámetros con nombres específicos a la función.\n\"\"\"\n\n#funciones dentro de funciones\n\n\"\"\"También puedes definir funciones dentro de otras funciones. Estas funciones internas pueden acceder a las variables y parámetros de la función externa.\nEsto es útil para organizar el código y encapsular la lógica relacionada.\"\"\"\n\ndef outer_function():\n    def inner_function():\n        print(\"Hola desde la función interna\")\n    inner_function()\n# Llamada a la función externa\n\nouter_function()\n\n\"\"\"\nEn este caso, la función outer_function define una función interna llamada inner_function que imprime el mensaje pasado como argumento.\nCuando llamas a outer_function, se ejecuta inner_function y se imprime el mensaje.\nEsto es útil para crear funciones que solo tienen sentido dentro del contexto de otra función.\n\"\"\"\n\n# Funciones del lenguaje (built-in functions)\n\"\"\" \nLas funciones del lenguaje son funciones predefinidas que están disponibles en Python sin necesidad de definirlas.\n Estas funciones proporcionan funcionalidades comunes y útiles que puedes utilizar en tu código.   \n Algunas de las funciones del lenguaje más comunes incluyen:\n print(): Imprime un mensaje en la consola.\n len(): Devuelve la longitud de un objeto, como una cadena o una lista.\n type(): Devuelve el tipo de un objeto.\n range(): Genera una secuencia de números en un rango específico.\n sum(): Calcula la suma de los elementos de un iterable, como una lista o una tupla.\n \"\"\"\n\n#ejemplo de función del lenguaje\n\nprint(len(\"Paprikaistkrieg\"))  # Imprime la longitud del archivo Paprikaistkrieg\nprint(type(42))  # Imprime el tipo de dato del número 42\nprint(\"Paprikaistkrieg\".upper())  # Imprime el nombre del archivo Paprikaistkrieg\nprint(sum([1, 2, 3, 4, 5]))  # Imprime la suma de los números en la lista\nfor i in range(5):\n    print(i)\n    # range() genera una secuencia de números del 0 al 4\n\n\"\"\"\nEstas funciones del lenguaje son muy útiles y te permiten realizar tareas comunes de manera rápida y eficiente sin necesidad de definir tus propias funciones.\n\"\"\"\n\n#Variables locales y globales\n\n\"\"\"\nÁmbito o scope\nEn Python, las variables pueden tener diferentes ámbitos o \"scope\".\nEl ámbito de una variable determina dónde se puede acceder a ella en el código.\nLas variables locales son aquellas que se definen dentro de una función y solo son accesibles dentro de esa función.\nLas variables globales, por otro lado, se definen fuera de cualquier función y son accesibles en todo el código.\n\"\"\"\nmensaje = \"Global\"\n\ndef funcion():\n    mensaje = \"Local\"\n    ejemplo = \"esto es un ejemplo de variable \"\n    print(ejemplo, mensaje)  # Imprime \"Local\"\n\nfuncion()\nprint(mensaje)  # Imprime \"Global\"\n\n#print(ejemplo)  # Esto generará un error porque ejemplo es una variable local y no se puede acceder fuera de la función\n\n\"\"\"\nEn este ejemplo, la variable mensaje se define como una variable global fuera de la función funcion.\nDentro de la función, se define una variable local con el mismo nombre, lo que oculta la variable global.\nCuando llamas a funcion(), imprime \"Local\" porque está accediendo a la variable local.\nFuera de la función, cuando imprimes mensaje, imprime \"Global\" porque estás accediendo a la variable global.\n\"\"\"\n\n\"\"\"como buena práctica, es recomendable evitar el uso de variables globales siempre que sea posible.\nEn su lugar, puedes pasar variables como argumentos a las funciones o utilizar variables locales dentro de las funciones para mantener el código más limpio y evitar confusiones.\nValorar la posibilidad de utilizar variables locales en lugar de globales es una buena práctica para mantener el código más limpio y evitar confusiones.\n\"\"\"\n#Extra\n\"\"\" * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\nLa función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\"\"\"\n\ndef funcion_extra(texto1, texto2)->int:\n    count = 0\n    for numeros in range(1, 101):\n        if numeros % 3 == 0 and numeros % 5 == 0:\n            print(texto1 + texto2)\n        elif numeros % 3 == 0:\n            print(texto1)\n        elif numeros % 5 == 0:\n            print(texto2)\n        else:\n            print(numeros)\n            count += 1\n\n    return count\n\nprint(funcion_extra(\"Fizz\", \"Buzz\"))\n\n           "
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Paula2409.py",
    "content": "\"\"\" \n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n \"\"\"\n \n# Function without parameters and no return\ndef function_without():\n    print('Function without parameters and no return')\n    \n# Function with parameters and no return   \ndef function_with(number=5):\n    print('Function with parameters and no return')\n    print(number)\n\n# Function with parameters and return   \ndef function_with_return(word_first='Hello', word_second='World'):\n    return word_first + ' ' + word_second\n\n# Function inside other function\ndef first_function():\n    print('This is the first function')\n    \n    def second_function():\n        print('This is the second function')\n    second_function()\n\n# Built-in functions Pyhton\ndef built_in_examples():\n    max_function = max(5,10)\n    min_function = min(-2,0)\n    len_function = len('Lenght of this sentence')\n    round_function = round(4.5)\n    type_function = type(5)\n    id_function = id(max_function)\n    print(f'Function max between two numbers: {max_function}')\n    print(f'Function min between two numbers: {min_function}')\n    print(f'Function lenght of sentence: {len_function}')\n    print(f'Function round number closer to next number: {round_function}')\n    print(f'Function type of object: {type_function}')\n    print(f'Function id (identifier memory adress): {id_function}')\n\n# Test local and global variables\nglobal_var = 'Global variable'\ndef variables_global_local_test():\n    print(f'Global variable inside function {global_var}')\n    \n    local_var = 'Local variable'\n    print(f'Local variable inside function {local_var}')\n      \n    def other_function():\n        print(f'Test global variable from other function: {global_var}')\n        print(f'Test local variable from other function: {local_var}')\n    other_function()\n            \nfunction_without()\nfunction_with()\nprint(f'Function with parameters and return: {function_with_return()}\\n' )\nprint('Function inside other function: ')\nfirst_function()\nprint()\nbuilt_in_examples()\nprint()\nprint('Test local and global variables: ')\nvariables_global_local_test()\nprint(f'Global variable outside function: {global_var}')\ntry:\n    print(f'Local variable out the function: {local_var}')\nexcept Exception:\n    print('Error: Variable local out the context\\n')\n\n# Extra difficult\ndef extra_exercise(firs_parameter,second_parameter):\n    counter_number = 0\n    for number in range(1,101):\n        if number % 15 == 0:\n            print(firs_parameter+second_parameter)\n        elif number % 5 == 0:\n            print(second_parameter)\n        elif number % 3 == 0:\n            print(firs_parameter)\n        else:\n            print(number)\n            counter_number += 1\n    return f'Times number has been printed: {counter_number}'\n\n# Test extra difficult\nprint(extra_exercise('Fizz','Buzz'))\n    "
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Pipe281.py",
    "content": "#Función sin parametros ni retorno\n\ndef saludar():\n    print(\"Que tal vieja?\")\n\nsaludar()\n\n#Función con uno o varios parametros y retorno\n\ndef suma(a , b):\n    return a + b\n\nresultado = suma( 1, 2 )\n\nprint(resultado)\n\ndef persona(nombre, apellido):\n    return nombre + apellido\n\ncanditado = persona(\"Elsa\", \"Pato\")\n\nprint(\"El candidato se llama\", canditado)\n\n#Función dentro de función\n#Función para multiplicar por si mismo el valor ingresado\ndef multiplicador(n):\n    def interior(x):\n        return x * n\n    return interior\n\nduplicar = multiplicador(2)\ntriplicar = multiplicador(3)\n\nprint(duplicar(5))  # Resultado: 10\nprint(triplicar(5))  # Resultado: 15\n\n#Funciones propias de Python\nnumero = int(\"10\") #Convierte texto en número\nprint(type(numero))\n\ntexto = str(42) #Convierte número en texto\nprint(type(texto))\n\nlongitud = len(\"Hola\") #Imprime el número de caracteres de la palabra\nprint(longitud)\n\n#Variable Local y Global\ndef mi_funcion():\n    variable_local = \"Esto es local\"\n    print(variable_local)\n\nmi_funcion()\n\nvariable_global = \"Esto es global\"\n\ndef otra_funcion():\n    print(variable_global)\n\notra_funcion()\nprint(variable_global)\n\n'* DIFICULTAD EXTRA (opcional):'\n'* Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.'\n'* - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:'\n'*   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.'\n'*   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.'\n'*   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.'\n'*   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.'\n\ndef imprimir_numeros(texto1, texto2):\n    contador = 100\n\n    for numero in range(1, 101):\n        if numero % 3 == 0 and numero % 5 == 0:\n            print(texto1 + texto2)\n            contador -= 1\n        elif numero % 3 == 0:\n            print(texto1)\n            contador -= 1\n        elif numero % 5 == 0:\n            print(texto2)\n            contador -= 1\n        else:\n            print(numero)\n\n    return contador\n\nrepeticiones = imprimir_numeros(\"Pipe\", \"Churrasco\")\nprint(\"Número de repeticiones:\", repeticiones)"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/PyTorDev.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\"\"\"\n\n\n# Declaración sin parametros\ndef funcion_nombre1():\n  nombre = \"Aitor\"\n  apellido = \"Lopez\"\n  espacio = \" \"\n  num_funcion = str(1)\n  nombre_completo = nombre + espacio + apellido + espacio + num_funcion\n  print(nombre_completo)\n\n# Llamada a la función\nfuncion_nombre1()\n\n# Funcion con retorno\ndef funcion_nombre2():\n  nombre = \"Aitor\"\n  apellido = \"Lopez\"\n  espacio = \" \"\n  num_funcion = str(2)\n  nombre_completo = nombre + espacio + apellido + espacio + num_funcion\n  return nombre_completo\n\nprint(funcion_nombre2())\n\n# Funcion con parametros\n\ndef funcion_nombre3(nombre, apellido):\n  espacio = \" \"\n  num_funcion = str(3)\n  nombre_completo = nombre + espacio + apellido + espacio + num_funcion\n  return nombre_completo\n\nprint(funcion_nombre3(\"Aitor\", \"Lopez\")) \n\n# Funcion con parametros por defecto\ndef funcion_nombre4(nombre = \"Aitor\", apellido = \"Lopez\"):\n  espacio = \" \"\n  num_funcion = str(4)\n  nombre_completo = nombre + espacio + apellido + espacio + num_funcion\n  return nombre_completo\n\nprint(funcion_nombre4())\nprint( funcion_nombre4(\"Manuel\", \"Salas\"))\n\n# Funcion con numero arbitraio de parametros\ndef arbit_function(*args):\n  nombre = \"Aitor\"\n  apellido = \"Lopez\"\n  espacio = \" \"\n  num_funcion = str(1)\n  nombre_completo = nombre + espacio + apellido + espacio + num_funcion\n  print(nombre_completo)\n\n# Función como parametro de otra función\ndef num_cuadrado(n):\n  return n * n\n\ndef ejecutando_funcion(f, x):\n  return f(x)\n\nprint(ejecutando_funcion(num_cuadrado, 3))\n\n#Ejemplo de tres funciones ya creadas\nprint(\"Imprime en consola el argumento dado\")\n# nombre = input(\"Muestra este mensaje en consola, detiene la ejecución y guarda en la variable numbre lo que introduce el usuario\")\nprint(type(\"Devuelve el tipo del valor que recibe como argumento\"))\n\n#Variable local vs global\n\nmy_global = \"Esta es una variable global\"\n\ndef my_local():\n  my_local = \"Aqui declaro una var local, que solo es accesible desde dentro de la misma funcion\"\n  print(my_local)\n\ndef prueba_loc_glob(x):\n  print(x)\n\nmy_local()\nprueba_loc_glob(my_global)\n# prueba_loc_glob(my_local) Esto da error, porque no se ppuede acceder a la varable local declarada dentro de una funcion\n\n# Extra\ndef imprime_num(n1 = input(\"Introduce el numero de inicio\"), n2 = input(\"Introduce el numero final\")):\n  n1 = int(n1)\n  n2 = int(n2) + 1\n  for i in range (n1, n2):\n    if (i % 3 == 0 and i % 5 == 0):\n      print(\"FizzBuzz\")\n    elif (i % 5 == 0):\n      print(\"Buzz\")\n    elif (i % 3 == 0):\n      print(\"Fizz\")\n    else:\n      print(i)\n\nimprime_num()"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Ramirofordev.py",
    "content": "# Funciones\n\n# Funcion sin parametro ni retorno\ndef hello_python():\n    print(\"Hola a todos, este es mi codigo en Python!\")\n\nhello_python()\n\n# Funcion con parametros pero sin retorno\ndef area_circulo(ra, pi):\n    print(f\"El de tu circulo es {pi * ra**2}\")\n\narea_circulo(2, 3.1416)\n\n# Funcion con parametros y retorno\ndef say_hello_to_user(user, times):\n    n = 0\n    for i in range(times):\n        print(f\"Hello {user}!\")\n        n += 1\n\n    return n\n\ncount = say_hello_to_user(\"nacho\", 8)\nprint(f\"Se le dijo hola al usuario {count}\")\n\n# Funciones dentro de funciones\n\ndef show_pair_numbers(): \n    def get_pair_numbers():\n        numbers = [1, 2, 3, 4, 5, 6]\n        pair_numbers = []\n        for i in numbers:\n            if i % 2 == 0:\n                pair_numbers.append(i)\n            \n        return pair_numbers\n    \n    pair_numbers = get_pair_numbers() \n    print(pair_numbers)\n    \nshow_pair_numbers()\n\n# Funciones ya creadas por python\nprint(sum(5 + 2))\n\n# Variables locales y globales\n\nglobal pi \n\ndef pi_plus_everything(): \n    pi = 3.1416\n    print(pi)\n    ultimo_resultado = 0\n    for i in range(100):\n        print(f\"Pi * {i} es = {pi * i}\")\n        ultimo_resultado = {pi * i}\n    print(ultimo_resultado)\n\n# print(ultima_operacion) dara error porque solo se puede usar en el scope de la funcion mientras que pi se puede usar en cualquier parte del codigo\n\npi = \"pi\"\n\nprint(pi)\n\n# Ejercicio opcional\n\ndef opc_exercise(text1, text2):\n    # La funcion imprime todos los numeros del 1 al 100\n    counts_numbers = 0\n    for i in range(100):\n        if i % 3 == 0:\n            print(text1)\n        elif i % 5 == 0:\n            print(text2)\n        elif i % 3 == 0 and i % 5 == 0:\n            print(text1 , \" \" , text2)\n        else:\n            print(i)\n            counts_numbers += 1\n    return counts_numbers\n\ncantidad = opc_exercise(\"Pablo\", \"queso\")\nprint(cantidad)"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/RgeditV1.py",
    "content": "from math import sqrt as raiz\n\ndef sumar(): #Funcion sin parametros\n    num1 = 5\n    num2 = 6\n    return num1 + num2 \n#--------------------------------------------------\ndef restar(num1,num2): #funcion con parametros\n    resultado = num1 - num2\n    return resultado\n#---------------------------------------------------\ndef dividir(num1=5,num2=2): #funcion con argumentos y sin return\n    print(num1/num2)\n\n\"\"\"Funcion sin parametros../ejecutara la funcion por si sola sin necesidad de que el usuario le pase algun dato\n    amenos que en la propia funcion se encuentren algoritmos que lo pida\n\"\"\"\nprint(sumar()) #llamada a la funcion sumar y la muestra en pantalla\n\n\n#-------------------------------------------------------------------------------------\n\n#Funcion con parametros../los digitos que ingresemos se pasara como argumento de los parametros en la funcion\nnum = int(input(\"Introduce digito: \"))\nnum2 = int(input(\"Introduce digito 2: \"))\nresultado = restar(num,num2)\nprint(resultado)#llamada a la funcion restar, pero los parametros reciben su argumento de las var num y num2\n\n#---------------------------------------------------------------------------------------------\n#Funciones sin retorno\n\ndividir()#Llamara a la funcion dividir que no tiene return pero si un print\n\n#----------------------------------------------------------------------------------------------\n#Funciones Decoradoras / son funciones que se utilizan para añadir nuevas funcionalidades a otra funcion\n#-----------------------------------------------------------------------------------------------\n\ndef corrector(func): #esta funcion tomara como parametro la funcion Div que esta mas abajo\n    def corregir(*args): #en esta funcion se corregira y añadira algunas cosas\n        if func(*args) != 'NO SE DIVIDE ENTRE CERO': # si el retorno de la funcion div es diferente a \"NO SE DIVIDE ENTRE CERO\"\n            print('Este esta es la division') #Entonces imprimira esto\n        return func(*args)# y retornara el valor de la funcion div\n    return corregir\n        \n\n@corrector #Decorador/esta funcion es la que se le pasara como parametro a la funcion corrector\ndef div(a, b):\n    if b == 0: #si la division es entre cero entonces retornara...\n        return 'NO SE DIVIDE ENTRE CERO'\n    else:\n        return a/b #Encambio si es una division comun retornara el valor\n\nprint(div(5,2))\n\n\n#-----------------------------------------------------------------------------------------------\n#Ejemplo de funciones nativa del lenguaje\n\n\"\"\"la funcion sqrt renombrada a raiz, devuelve la raiz cuadrada de un numero \n    y lo guardara en la variable raiz_cuadrada\n\"\"\"\nraiz_cuadrada = raiz(5)\n\nprint(round(raiz_cuadrada,2)) #con la funcion round limitas el numero de decimales que quieres\n\n#----------------------------------------------------------------------------------------------\n\"\"\"Variables locales son las variables que solo se pueden usar dentro de una funcion, clase etc...\n    Mientra que con una variable global puedes llamarla(por asi decirlo) desde cualquier parte del codigo\n\"\"\"\n\n#var_global\nnombre = \"Angel\" #Esta variable puedo invocarla desde cualquier parte del codigo\n\n\ndef var_local():\n    #var_local\n    hola = \"Hola, \" #Esta variable no la podre invocar fuera de la funcion\n    print(hola,nombre)\n\nprint(nombre) #estoy invocando la variable global desde la funcion y fuera de la funcion\n\n#---------------------------------------------------------------------------------------------\n#continuare en otro momento la dificultad opcional\n#--------------------------------------------------------------------------------------------"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/RickUbb.py",
    "content": "# Crea ejemplos de funciones básicas que representen las diferentes posibilidades del lenguaje:\n# Sin parámetros ni retorno\nimport math\n\ndef hola():\n    hola = \"Hola, Rick Ubb!\"\n\nprint(hola)\n\n# Con uno o varios parámetros\ndef hola(saludo1, saludo2):\n    saludo = f\"{saludo1}, {saludo2}!\"\n    print(saludo)\n\nprint(hola(\"hi\", \"Rick Ubb\"))\n\n# Con retorno\ndef holas():\n    return \"Hola, Rick Ubb!\"\n\nprint(holas)\n\n# Comprueba si puedes crear funciones dentro de funciones.\ndef hoya():\n    def mundo():\n        return \"Mundo\"\n    saludo = mundo()\n    return saludo\n\n# Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\nprint(hoya())\nsaludo = len(hoya())\nprint(saludo)\nprint(math.sqrt(9))\n\n# Pon a prueba el concepto de variable LOCAL y GLOBAL.\nvariable_global = \"Soy una variable global\"\n\ndef saludar():\n    variable_local = \"Soy una variable local\"\n    print(variable_local)\n    print(variable_global)\n\nprint(saludar())\nprint(variable_global)\n#print(variable_local) da error por que la variable solo existe detro de la funcion\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\"\"\"\n\n\ndef funcion_extra(cadena1, cadena2):\n    numero = 0\n    for i in range(1, 101):\n        if (i % 3 == 0 and i % 5 == 0):\n            print(f\"{cadena1}, {cadena2} {i}\")\n        elif (i % 5 == 0):\n            print(f\"{cadena2}, {i}\")\n        elif (i % 3 == 0):\n            print(f\"{cadena1}, {i}\")\n        else:\n            numero += 1\n            print(f\"{i}, {numero}\")\n\n    return numero\nprint(funcion_extra(\"Rick\", \"Sanchez\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Rodrigoghr.py",
    "content": "#02 FUNCIONES Y ALCANCE\n'''\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n '''\n \n# Funciones básicas:\n# Sin parámetros ni retorno\ndef funcion_hola():\n    print('Hola')\n\nfuncion_hola()\nprint('*********************************************\\n')\n\n# Con un parámetro\ndef funcion_con_parametro(nombre):\n    print(f'Hola {nombre}')\n\nfuncion_con_parametro('Mouredev')\nprint('*********************************************\\n')\n\n# Con un parámetro por defecto\ndef funcion_par_def(nombre='Mouredev'):\n    print(f'Hola {nombre}')\n\nfuncion_par_def()        # Ejecutará con valor por defecto\nfuncion_par_def('Brais') # Ejecutará cambiando el valor por defecto  \nprint('*********************************************\\n')\n\n# Con 2 o más parámetros\ndef funcion_parametros(nombre,id):\n    print(f'Bienvenido {nombre} su código es: {id}')\n\nfuncion_parametros('Pepe',3)\nprint('*********************************************\\n')\n\n# Con n parámetros\ndef funcion_n_parametros(*nombres):\n    for nombre in nombres:\n        print(f'Bienvenido {nombre}')\n\nfuncion_n_parametros('Rodrigo','Brais','Alan')\nprint('*********************************************\\n')\n\n# Con n parámetros y una llave\ndef funcion_kn_parametros(**nombres):\n    for llave, nombre in nombres.items():\n        print(f'{llave} : {nombre}')\n\nfuncion_kn_parametros(\n    nombre = 'Rodrigo',\n    edad = 25\n)\nprint('*********************************************\\n')\n\n# Devuelve un parámetro\ndef bienvenido():\n    return 'Bienvenido!'\n\nprint(bienvenido())\nprint('*********************************************\\n')\n\n# Con un parámetro y devuelve un parámetro\ndef bienvenido_nombre(nombre):\n    return f'Bienvenido {nombre}!'\n\nprint(bienvenido_nombre('Brais'))\nprint('*********************************************\\n')\n\n# Funciones dentro de funciones\ndef funcion_externa():\n    def funcion_interna():\n        print('Bienvenido al reto Mouredev!')\n    funcion_interna()\n    \nfuncion_externa()\nprint('*********************************************\\n')\n\n# Funciones del lenguaje\n# Función len()\nprint('Corto' if len(\"Brais\") < 5 else 'largo')\nprint('*********************************************\\n')\n\n# Entorno de variables\nprint('Ambito global:')\nvariable_global = 'Brais'\n\ndef saludo():\n    print('\\tAmbito local de la función:')\n    variable_local = 'Mouredev'\n    print(f'\\tBienvenido {variable_local} tu nombre global es {variable_global}')\n    \nsaludo()\nprint(f'\\nVariable global: {variable_global}')\n#print(f'Variable global {variable_local}') # No se puede acceder por estar restringido al ambito de la función saludo()\nprint('*********************************************\\n')\n\n'''\n/*DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n*/\n'''\ndef extra(texto_1, texto_2) -> int:\n    contador = 0\n    for numero in range(1,101):\n        if numero % 3 == 0 and numero % 5 == 0:\n            print(f'{texto_1} {texto_2}')\n        elif numero % 3 == 0:\n            print(texto_1)\n        elif numero % 5 == 0:\n            print(texto_2)\n        else:\n            print(numero)\n            contador += 1\n    return contador\n\nprint(extra('Texto 1','Texto 2'))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/RoniPG.py",
    "content": "#FUNCIONES\n\n#Funcion de suma\n\"\"\"\nLas funciones pueden no recibir ningun parametro o pueden recibir varios parametros\nPueden tener un valor de retorno (return) que se devuelve al invocar la funcion\n\"\"\"\ndef Sumar(a, b): \n    c = a + b\n    return c #Funcion con retorno\n\nprint(\"El resultado de la funcion sumar de 3 + 2 es: \" + str(Sumar(3,2)))\n\n#Funcion de resta\ndef Resta(a,b):\n    c = a - b\n    #Funcion dentro de funcion\n    print(\"Primera funcion Resta\")\n    def SegundaResta():\n       print (\"Segunda funcion Resta\")\n       #Funcion sin retorno\n    #LLamada a funcion dentro de una funcion\n    SegundaResta()\n    return c\n\nprint(\"El resultado de la funcion resta de 3 - 2 es: \" + str(Resta(3,2)))\n\ndef Resultados():\n    #Llamadas a funciones fuera de funciones\n    print(\"El resultado de la funcion sumar de 3 + 2 es: \" + str(Sumar(3,2)))\n    print(\"El resultado de la funcion resta de 3 - 2 es: \" + str(Resta(3,2)))\n\nprint(\"Los resultados de las funciones: \" )\nResultados()\n\n#Funciones predefinidas de phyton\n\nprint(divmod(10,2)) # El primer numero nos indica el resultado de la division, el segundo el resto\nprint(chr(363)) # Traduce el numero al codigo Unicode\n\n# Variables\n\ndef AccesoVariables():\n    a = 0 # Variable Local (Solo existe dentro de la funcion)\n    return a\n\na = 1 # Variable Global (Accesible en todo el programa)\n\nprint(\"Accedemos a la variable local a con valor : \"+ str(AccesoVariables()))\nprint(\"Comprobamos la variable global a : \"+str(a))\n\n\"\"\"\n DIFICULTAD EXTRA (opcional):\n Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\n Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n\"\"\"\n\ndef X (a, b) :\n    contador = 0\n    for i in range (1,100) :\n        if i%5==0 and i%3==0 :\n            print(a+\" y tambien \"+b)\n        elif i%3==0 : \n            print(a)\n        elif i%5==0 :\n            print (b)\n        else :\n            print(i)\n            contador += 1\n    return contador\n\nprint(\"Se ha impreso un numero: \" + str(X(\"Soy multiplo de 3\",\"Soy multiplo de 5\"))+\" veces\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Roy-garcia-rendon.py",
    "content": "# EJERCICIO:\n# * - Crea ejemplos de funciones básicas que representen las diferentes\n# *   posibilidades del lenguaje:\n# *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n# * - Comprueba si puedes crear funciones dentro de funciones.\n# * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n# * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n# * - Debes hacer print por consola del resultado de todos los ejemplos.\n# *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n# *\n# * DIFICULTAD EXTRA (opcional):\n# * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n# * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n# *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n# *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n# *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n# *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n# *\n# * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n# * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n\n\n# Función sin parametros:\n\ndef funnoparametros():\n    for i in range(5):\n        print(i)\n\n\nfunnoparametros()\n\n# Función con un parametro\n\n\ndef fun_con_parametro(nombre):\n    print(\"¡Hola, \"+nombre+\"!\")\n\n\nfun_con_parametro(\"roy\")\n\n# Función con dos parametros\n\n\ndef fun_con_return(num1, num2):\n    numeros_pares = []\n    i = num1\n    print(\"Estos son los numeros pares entre \"+str(num1)+\" y \"+str(num2))\n    while i < num2:\n        if i % 2 == 0:\n            numeros_pares.append(i)\n        i += 1\n    print(numeros_pares)\n\n\nfun_con_return(1, 100)\n\n# Función con return y tres parametros\n\n\ndef fun_return(a=5, b=8, c=3):\n    return (a*b)/c\n\n\nprint(fun_return())\n\n# Diferencia variable local y variable global\nvar = \"Esto es una variable global\"\n\n\ndef fun_var():\n    var = \"Esto es una variable local\"\n    return var\n\n\nprint(var)\nprint(fun_var())\n\n\ndef fun_var_glob():\n    global var\n    var = var + \" bis\"\n    return var\n\n\nprint(fun_var_glob())\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/RuhlMirko.py",
    "content": "print(\"Funciones\")\n\n\ndef hola_mundo():  # Funcion que imprime en consola\n    print(\"¡Hola mundo!\")\n\n\ndef return_hola_mundo():  # Funcion que devuelve un valor\n    return \"¡Hola Python!\"\n\n\ndef suma(a, b):  # Funcion con argumentos\n    return a + b\n\n\ndef greet_user(user, language=\"Python\"):  # Funcion con argumento predeterminado\n    return f\"Hello, {user}. You are working in {language}\"\n\n\ndef greet_the_team(*names):  # Funcion con numero variable de argumentos\n    for name in names:\n        print(f\"Hello, {name}\")\n\n\ndef greet_the_dictionary(**search_term):  # Funcion con numero variable de argumentos\n    for word, definition in search_term.items():\n        print(f\"{word} definition: {definition}\")\n\n\ndef al_cuadrado(a, b):  # Funcion dentro de otra funcion y con multiples return\n    resultado_suma = suma(a, b)  # Llamada de funcion externa\n    resultado_cuadrado = resultado_suma ** 2\n    return resultado_cuadrado, resultado_suma\n\n\nhola_mundo()\nprint(return_hola_mundo())\nprint(suma(b=5, a=2))  # Ejemplo de envio de argumentos en orden especifico\nprint(greet_user(\"Mirko\"))\ngreet_the_team(\"Python\", \"JavaScript\", \"C++\")\ngreet_the_dictionary(\n    python=\"A language made for better readability\",\n    javascript=\"A language good por OOP\",\n    c=\"An improved version of C\"\n)\n\nprint(\"\\nFunciones dentro de funciones\")\nresult_cuadrado, result_suma = al_cuadrado(5, 2)  # Multiples return\nprint(f\"Resultado de suma: {result_suma}\")\nprint(f\"Resultado al cuadrado: {result_cuadrado}\")\n\nprint(\"\\nFunciones de Pyhton\")\nprint(dir(\" \"))  # Devuelve los comandos posibles del elemento\nprint(len(return_hola_mundo()))  # Devuelve la longitud del elemento\nprint(return_hola_mundo().upper())  # Pone en mayusculas el string dado\nprint(type(suma(5, 2)))  # Devuelve el tipo del elemento\nprint((\"a\", \"b\", \"c\", \"d\")[slice(1, 3)])  # Separa un objeto de sus otras partes\nprint(float(\"6.6\"))  # Convierte un string a un float\nprint(max(2, 3, 5, 7, 11, 1))  # Devuelve el numero mas grande de un objeto\nprint(round(6.8))  # Redondea un numero float\n\nprint(\"\\nVariable LOCAL y GLOBAL\")\n\n\ndef hello_python():\n    print(f\"Hello, {language}\")\n\n\nlanguage = \"Python\"  # Variable Global\nprint(language)\nhello_python()\n\nprint(\"\\nDificultad Extra:\")\n\n\ndef fizzbuzz(a, b):\n    count_numbers = 0\n    for i in range(1, 101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(a + b)\n        elif i % 3 == 0:\n            print(a)\n        elif i % 5 == 0:\n            print(b)\n        else:\n            count_numbers += 1\n            print(i)\n    return count_numbers\n\n\ncontador_de_numeros = fizzbuzz(\"Fizz\", \"Buzz\")\nprint(f\"Cantidad de numeros mostrados: {contador_de_numeros}\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Rusanov16.py",
    "content": "\"\"\"\n EJERCICIO 02:\n - Crea ejemplos de funciones básicas que representen las diferentes\n   posibilidades del lenguaje:\n   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n - Comprueba si puedes crear funciones dentro de funciones.\n - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n - Debes hacer print por consola del resultado de todos los ejemplos.\n  (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n\n    DIFICULTAD EXTRA (opcional):\n    Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n    - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n    - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n    - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n    - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n    - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\nPresta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\nCada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n\"\"\"\n\n#*-------------------------------------------------------------------------------------------------------------#\n\"\"\"\n  - Crea ejemplos de funciones básicas que representen las diferentes\n  posibilidades del lenguaje:\n  Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n\"\"\"\n\n#Funciones\nprint(\"************************************************\")\n\nprint(\"Función simple\")\ndef hola():\n    print(\"Hola\")\nhola()\nprint(\"************************************************\")\n\n#Funciones con parametros\nprint(\"Funciones con parámetros\")\ndef suma(num1, num2):\n  return num1 + num2\n\nresultado = suma(45, 56)\nprint(resultado)\n\nprint(\"************************************************\")\n\n#Funciones con retorno\nprint(\"Funciones con retorno\")\ndef cubo(numero):\n  return numero ** 3\n\nnumero_ingresado = 6\nresultado_cubo = cubo(numero_ingresado)\nprint(f\"El cubo de {numero_ingresado} es {resultado_cubo}\")\n\nprint(\"************************************************\")\n#*-------------------------------------------------------------------------------------------------------------#\n\n\"\"\"\n- Comprueba si puedes crear funciones dentro de funciones.\n\"\"\"\n#Funcion dentro de otra funcion\nprint(\"Función de otra Función\")\ndef suma_lista(lista):\n    def sumar_elementos(elementos):\n        return sum(elementos)\n\n    total = sumar_elementos(lista)\n    print(f\"La suma de los elementos es: {total}\")\n\nmi_lista = [1, 2, 3, 4, 5]\nsuma_lista(mi_lista)\nprint(\"************************************************\")\n#*-------------------------------------------------------------------------------------------------------------#\n\n\"\"\"- Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n\"\"\"\nprint(\"Funciones creadas en python\")\n\nlista = [1, 2, 3, 4, 5]\nlongitud = len(lista)\nprint(f\"La longitud de la lista es: {longitud}\")\nprint(\"************************************************\")\n#*-------------------------------------------------------------------------------------------------------------#\n\n\"\"\"\n - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n\"\"\"\n\n#Variables Globales\nprint(\"Variables Globales\")\n\nvar_global = 42\ndef variable_global():\n    print(f\"El valor de la variable global es: {var_global}\")\n\nvariable_global() \n\nprint(\"************************************************\")\n\nprint(\"Variables Locales\")\n\ndef saludar():\n    mensaje = \"\"\n    print(mensaje)\n\nsaludar()\nprint(\"************************************************\")\n#*-------------------------------------------------------------------------------------------------------------#\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n  Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n  - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n  - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n  - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n  - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n  - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\"\"\"\n\ndef numeros(texto_uno,texto_dos):\n  impresiones = 0\n  for num in range(1,101):\n    if num % 3 == 0 and num % 5 == 0:\n      print(f\"{num} es un {texto_uno + texto_dos}\")\n    elif num % 3 == 0:\n      print(f\"{num} es un {texto_uno}\")\n    elif num % 5 == 0 :\n      print(f\"{num} es un {texto_dos}\")\n    else:\n      print(f\"El número {num} no es un múltiplo de 3 y 5\")\n      impresiones += 1\n      \ntexto_a = \"Multiplo de Tres\"\ntexto_b = \"Multiplo de Cinco\"\nresultado = numeros(texto_a, texto_b)\nprint(\"Número de impresiones:\", resultado)\n\n#*-------------------------------------------------------------------------------------------------------------#\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Ruthmp.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n \"\"\"\n\n #FUNCIÓN SIN PARÁMETROS NI RETORNO:\ndef funcionS ():\n    print(\"Hola Python\")\n\nfuncionS()  #llamar a la función\n\n#FUNCIÓN CON RETORNO:\ndef funcionC ():\n   return \"Hola Python\"\n\nprint(funcionC()) \n\n#FUNCIÓN CON PARÁMETROS:\ndef funcionP (nombre):\n    print(f\"Hola {nombre}\")\n\nfuncionP(\"Ruth\")\n\n#FUNCION CON VARIOS PARÁMETROS:\ndef funcionVP (nombre, edad):\n    print(f\"Mi nombre es {nombre} y tengo {edad} años\")\n\nfuncionVP(\"Ruth\", \"34\")\n\n#FUNCIÓN CON ARGUMENTO PREDETERMINADO:\ndef funcionAP (nombre=\"Python\"):\n    print(f\"Hola {nombre}\")\n\nfuncionAP()\nfuncionAP(\"Ruth\")\n\n#FUNCION CON ARGUMENTOS Y RETORNO:\ndef funcionCR (nombre, edad):\n    return f\"{nombre}, {edad}\"\n\nprint(funcionCR(\"Ruth\", \"34\"))\n\n#FUNCION CON NÚMERO VARIABLE DE ARGUMENTOS:\ndef funcionVA(*names):\n    for name in names:\n        print(f\"Hola {name}\")\n\nfuncionVA (\"Ruth\", \"Patricia\", \"Rebecca\")\n\n#FUNCIONES CON UN NÚMERO VARIABLE DE ARGUMENTOS CON PALABRA CLAVE\ndef funcion_key (**names):\n    for key, value in names.items():\n        print(f\"{value} ({key})!\")\n\nfuncion_key(\n    language=\"Python\",\n    name=\"Ruth\",\n    edad= 34\n)\n\n#FUNCIONES DENTRO DE FUNCIONES:\ndef funcion_externa():\n    def funcion_interna():\n        print (\"Función Interna: Hola Python!\")\n    funcion_interna()\n\nfuncion_externa()\n\n#FUNCIONES DEL LENGUAJE (BUILT-IN):\nprint(len(\"Ruth\"))\nprint(type(34))\nprint(\"Ruth\".upper())\n\n#VARIABLES LOCALES Y GLOBALES:\n\nglobal_var = \"Python\"\n\ndef hello_python():\n    local_var= \"Hola\"\n    print(f\"{local_var}, {global_var}!\")\n\nprint(global_var)\n# print (local_var) No se puede acceder desde fuera de la función\n\nhello_python()\n\n\"\"\"\nEXTRA\n\"\"\"\n\ndef fizzBuzz(texto1, texto2)-> int:\n    count =0\n    for number in range(1, 101):\n        if number %3==0 and number%5==0:\n            print(texto1 + texto2)\n        elif number %3==0:\n            print(texto1)\n        elif number%5==0:\n            print(texto2)\n        else :\n            print (number)\n            count +=1\n    return count\n\nprint(fizzBuzz(\"Fizz\", \"Buzz\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Sac-Corts.py",
    "content": "\"\"\" \nEJERCICIO\n\"\"\"\n\n# Función sin parámetros ni retorno\ndef saludar():\n    print(\"Hola Isaac\")\n\nsaludar()\n\n# Función con uno o varios parámetros \ndef saludarNombre(name):\n    print(\"Hola \" + name)\n\nsaludarNombre(\"Geovanni\")\n\n# Función con retorno \ndef sumar(a, b):\n    return a + b\n\nprint(sumar(1, 4))\n\n# Función dentro de una función\ndef funcion_principal(name):\n    def funcion_secundaria():\n        print(\"Mi nombre es:\", name)\n    funcion_secundaria()\n\n\nfuncion_principal(\"Isaac\")\n\n# Función ya creada en python\nlista = [10, 30, 50, 100]\nprint(max(lista))\nprint(min(lista))\n\n# Variable global\nx = 21\n\ndef variable_global():\n    print(\"Mi variable x es: \", x)\n\nvariable_global()\n\n# Variable local \ndef variable_local():\n    global j \n    j = 11\n\nvariable_local()\n\ndef mostrar_variable_local():\n    print(\"Mi variable j es: \", j)\n\nmostrar_variable_local()\n\n\"\"\"\nDIFICULTAD EXTRA\n\"\"\"\n\ndef numeros(cadena1, cadena2):\n    contador = 0\n\n    for num in range(1, 101):\n        if num % 3 == 0 and num % 5 == 0:\n            print(cadena1 + cadena2)\n        elif num % 3 == 0:\n            print(cadena1)\n        elif num % 5 == 0:\n            print(cadena2)\n        else:\n            print(num)\n            contador += 1\n    return contador\n    \ncadena1 = \"Fall\"\ncadena2 = \"out\"\nresultado = numeros(cadena1, cadena2)\nprint(\"Número de veces que se ha impreso un número:\", resultado)"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Sandrogmz.py",
    "content": "\"\"\"\nFunciones definidas por el usuario\n\"\"\"\n\n# Simple\n\n\ndef greet():\n    print(\"Hello, World\")\n\n\ngreet()\n\n# Con retorno\n\n\ndef return_greet():\n    return \"Hello, Python!\"\n\n\nprint(return_greet())\n\n# Con un argumento\n\n\ndef arg_greet(name):\n    print(f\"Hello, {name}!\")\n\n\narg_greet(\"Sandro\")\n\n# Con argumentos\n\n\ndef args_greet(greet, name):\n    print(f\"{greet}, {name}!\")\n\n\nargs_greet(\"Hi\", \"Sandro\")\nargs_greet(name=\"Sandro\", greet=\"Hi\")\n\n\n# Con un argumento predeterminado\n\n\ndef default_arg_greet(name=\"Python\"):\n    print(f\"Hola, {name}!\")\n\n\ndefault_arg_greet(\"Brais\")\ndefault_arg_greet()\n\n# Con argumentos y return\n\n\ndef return_args_greet(greet, name):\n    return f\"{greet}, {name}!\"\n\n\nprint(return_args_greet(\"Hi\", \"Brais\"))\n\n# Con retorno de varios valores\n\n\ndef multiple_return_greet():\n    return \"Hola\", \"Python\"\n\n\ngreet, name = multiple_return_greet()\nprint(greet)\nprint(name)\n\n# Con un número variable de argumentos\n\n\ndef variable_arg_greet(*names):\n    for name in names:\n        print(f\"Hello, {name}!\")\n\n\nvariable_arg_greet(\"Python\", \"Sandro\", \"Gomez\", \"Enjoy\")\n\n# Con un número variable de argumentos con palabra clave\n\n\ndef variable_key_arg_greet(**names):\n    for key, value in names.items():\n        print(f\"{value} ({key})!\")\n\n\nvariable_key_arg_greet(\n    language=\"Python\",\n    name=\"Sandro\",\n    alias=\"Gomez\",\n    age=31\n)\n\n\"\"\"\nFunctions inside Functions\n\"\"\"\n\n\ndef outer_function():\n    def inner_function():\n        print(\"Inner function Hello, Python !\")\n    inner_function()\n\n\nouter_function()\n\n\"\"\"\nLanguage Functions (built-in)\n\"\"\"\n\nprint(len(\"SandroGomez\"))\nprint(type(31))\nprint(\"SandroGomez\".upper())\n\n\"\"\"\nVariables locals and globals\n\"\"\"\n\nglobal_var = \"Python\"\n\n\ndef hello_python():\n    local_var = \"Hello\"\n    print(f\"{local_var}, {global_var}!\")\n\n\nprint(global_var)\n# print(local_var) cannot acces, outside of function\n\n\"\"\"\nExtra\n\"\"\"\n\n\ndef print_numbers(text_1, text_2) -> int:\n    count = 0\n    for number in range(1, 101):\n        if number % 3 == 0 and number % 5 == 0:\n            print(text_1 + text_2)\n        elif number % 3 == 0:\n            print(text_1)\n        elif number % 5 == 0:\n            print(text_2)\n        else:\n            print(number)\n            count += 1\n    return count\n\n\nprint(print_numbers(\"Fizz\", \"Buzz\"))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Seni889.py",
    "content": "\"\"\"\nFUNCIONES DEFINITIVAS\n\"\"\"\n\n# def saludar():\n#     print(\"Hola mundo\")\n\n# def saludar1(nombre):\n#     print(f\"Hola {nombre}\")\n\n# def caminar():\n#      return \"Luis\"\n \n\n# edad = int(input(\"Ingrese su edad: \"))\n\n# def mayor(edad):\n#     if edad >= 45:\n#         return \"Tienes promociones 2x1\"\n#     elif edad >= 18:\n#         return \"Pasa con precio normal\"\n#     else:\n#          return \"Usted no puede ingresar\"  \n\n\n# nombre = input(\"Ingresa tu nombre: \") \n# edad = input(\"Ingresa tu edad: \")\n# direccion = input(\"Ingrese su direccion: \")\n\n# def usuarios(nombre, edad, direccion):\n#     return {\n#         \"nombre\": nombre,\n#         \"edad\": edad,\n#         \"direccion\": direccion \n#     }\n\n# print(usuarios(nombre, edad, direccion))\n\n# def cursos():\n#     return (\"python\", \"java\")\n\n\n\n# def usuario():\n#     return {\n#         \"id\": 1,\n#         \"nombre\" : \"Andy\",\n#         \"apellido\" : \"Reyes\",\n#         \"edad\" : 18\n#     }\n\n# print(usuario())\n\n# def restaurantes(usuarios, name ):\n#     print(f\"El nombre del restaurante es: {name} y el encargado es {usuarios[\"nombre\"]} {usuarios[\"apellido\"]}\")\n    \n# usuarios = usuario()\n\n# #\n# def cliente():\n#     return{\n#         \"id\": 1,\n#         \"nombre\": \"Josue\",\n#         \"apellido\": \"Reyes\",\n#         \"ciudad\": \"Piura\",\n#         \"edad\": 20\n#     }\n\n# # def clientes(client, nomb):\n# #     sms = f\"Este cliente {client[\"nombre\"]} {client[\"apellido\"]} tiene este restaurante {nomb}\"\n# #     return sms\n\n# def clientes(client, nomb):\n    \n#     sms = f\"El restaurante es : {nomb}\\n El cliente es {client[\"nombre\"]}\\n estos son los proveedores\"\n#     return sms\n# client = cliente()\n\n# res = clientes(client, \"El buen sabor\")\n\n# print(res)\n\n# print(restaurantes(usuarios, \"El buen Sabor\"))\n\n# #con armuento predeterminado\n# def personas (nam= \"Bebe\"):\n#     print (f\"Buenas, {nam}\")\n\n\n# personas(\"Jordy\")\n# personas()\n\n# #con argumentos\n# def person(enc, siti):\n#     print(f\"{enc}, {siti}\") \n\n# person(siti = \"Jose\", enc =\"Hola\")\n# person(\"Hola\", \"Andy\")\n\n# #Con return incluido\n\n# def persons(encw, sitiw):\n#     return f\"{encw}, {sitiw}\"\n\n# print(persons(\"Hola\", \"Jose\"))\n# print(persons(\"Jose\", \"Hola\"))\n\n\n# def personsid ():\n#     return  \"Buenos\" , \"Malos\"\n\n# nombre, saludo = personsid()\n\n# print(saludo)\n# print(nombre)\n\n\n\ndef objetos(*names):\n    for nombre in names:\n        print(f\"Muy buenas tardes {nombre}\")\n\nobjetos(\"Luis\", \"Martin\", \"Jordy\")\n\n\ndef objetoss(**names):\n    for clave, nombre in names.items():\n        print(f\"Muy buenas tardes {nombre} ({clave})\")\n\nobjetoss(\n    id = 1,\n    name = \"Josue\", \n    edad = 21\n)\n\n\"\"\"\nFUNCIONES DENTRO DE FUNCIONES\n\"\"\"\n\ndef saludos():\n    def saludo():\n        print(\"Esta es una funcion dentro de otra funcion\")\n    saludo()\nsaludos()\n\n\n\ndef saludoss(nombre):\n    def salud(text):\n        return text.upper()\n    \n    sms = f\"Hola, {salud(nombre)}. Muy buenas tardes\"\n    return sms\n\nprint(saludoss(\"Andy\"))\n\n\ndef fiesta(nombre):\n    def direccion(str):\n        return str.upper()\n    mensaje = f\"El nombre de la fiesta es: {direccion(nombre)}\"\n    return mensaje\n\nprint(fiesta(\"San Juan de Dios\"))\n\n\ndef user_nombre(nombre, edad):\n    def edad_user(edad):\n        if edad >= 60:\n            return \"Usted si puede ingresar, con premios incluidos\"\n        elif edad >= 18:\n            return \"Usted si puede continuar, ya tiene 18 años\"\n        else:\n            return \"Ustede todavia es una wuawita \"\n\n    return  f\"Bienvenid@ {nombre} {edad_user(edad)}\"\n\nprint (user_nombre(\"Andy\", 21))\n\n\n\"\"\"\nFUNCIONES DEL LENGUAJE\n\"\"\"\nprint(len(\"Andy\"))\nprint(type(\"AndyJosue\"))\nprint(type(28))\n# print(input(\"Ingresa tu nombre: \")) #Ingresa de datos por consola\nprint(int(5))\nprint(str(\"andyadrianzen\".upper()))\n      \n\"\"\"\nVARIABLE LOCALES Y GLOBALES\n\"\"\" \n\n#variable global\nvariable_global = \"Mundo\"\nprint(variable_global)\n\n#variable global y locales\ndef hola_mundo():\n    variable_local = \"Hola\" \n    print(f\"{variable_local}, {variable_global}\")\n\nhola_mundo()\n\n#variable local\ndef buen_dia():\n    dias = \"Buenos dias\"\n    nombre = \"Andy\"\n    print(f\"{dias}, {nombre}\")\n\nbuen_dia()\n\n\"\"\"\nEXTRA EJERCICIO\n\"\"\"\n\ndef funcion_num(text_1, text_2) -> int:\n    count = 0\n    for num in range(1, 101):\n        if num % 3 == 0 and num % 5 == 0:\n            print(text_1 + text_2)\n        \n        elif num % 3 == 0:\n            print(text_1)\n        \n        elif num % 5 == 0:\n            print(text_2)\n        \n        else:\n            print(num)\n            count += 1\n    return count \n\nprint(funcion_num(\"text_1\", \"text_2\"))  \n\n    \n        \n    \n# print(cursos())\n\n\n\n\n\n# print(mayor(edad))\n\n# print(caminar())\n# saludar()\n# saludar1(\"Josue\")\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/SergioGI99.py",
    "content": "\"\"\"\n-------------------\nFUNCIONES Y ALCANCE\n-------------------\nEJERCICIO:\n- Crea ejemplos de funciones básicas que representen las diferentes\n  posibilidades del lenguaje:\n  Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n- Comprueba si puedes crear funciones dentro de funciones.\n- Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n- Pon a prueba el concepto de variable LOCAL y GLOBAL.\n- Debes hacer print por consola del resultado de todos los ejemplos.\n  (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n\nDIFICULTAD EXTRA (opcional):\nCrea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n- La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n  - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n  - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n  - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n  - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\nPresta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\nCada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n\"\"\"\n# Ejercicio\n\ndef funBasica():\n    print(\"Esto es una función básica\")\n\nfunBasica()\n\ndef funArgumento(name):\n    print(\"Mi nombre es: \" + name)\n    \nfunArgumento(\"Sergio\")\n\ndef funMult(parametro, parametroDos):\n    print(parametro * parametroDos)\n    \nfunMult(5, 10)\n\ndef funRetorno():\n    return \"Función con retorno\"\n    \nprint(funRetorno())\n\nmy_list = [1, 2, 3, 4]\ndef funSum():\n    return max(my_list) + 5\n\nprint(funSum())\n\nmyGlobal_variable = 6\n\ndef my_fun():\n    myLocal_variable = myGlobal_variable + 5\n    return myLocal_variable\n    \n#print(myLocal_variable) # undefined\nprint(my_fun())\n\n# Ejercicio Extra\n\nprint(\"Ejercicio extra:\")\n\ndef my_ejercicio(str_one, str_two):\n    count = 0\n    for n in range(1, 101):\n        if n % 3 == 0 and n % 5 == 0:\n            print(str_one, str_two)\n        if n % 3 == 0:\n            print(str_one)\n        elif n % 5 == 0:\n            print(str_two)\n        else:\n            print(n)\n            count += 1\n    print(f\"Se han impreso: {count} números\")\n    \nmy_ejercicio(\"fizz\", \"buzz\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/SooHav.py",
    "content": "#02 FUNCIONES Y ALCANCE \n#Ejemplos de funciones básicas\n\n#Funciones sin parámetros ni retorno\ndef saludo():\n    print(\"Hola Comunidad\")\n\nsaludo()\n\n#Funciones con un parámetro\ndef saludo(avatar):\n    print(f\"Hola Comunidad soy {avatar}\")\n\nsaludo(\"SooHav\")\n\n#Funciones con mas de un parámetro\ndef saludo_comunidad(avatar, saludo = \"Hola Comunidad\"):\n    print(f\"{saludo} soy {avatar}\")\n\nsaludo_comunidad(\"SooHav\",\"Hola gente\")\n\n#Funciones con parámetros y retorno\ndef saludo_comunidad_v2(avatar, saludo = \"Hola Comunidad\"):\n    return (f\"{saludo} soy {avatar}\")\n\nsaludo_comunidad_v2(\"SooHav\", \"Hola! comunidad de los retos-semanales\")\n\ndef suma_y_media(a, b, c):\n    suma = a+b+c\n    media = suma/3\n    return suma, media\n\nsuma, media = suma_y_media(10, 10, 10)\nprint(\"Suma:\", suma)\nprint(\"Media:\", media) \n\n#Funciones dentro de funciones (con funciones primitivas de python)\ndef suma_y_media_v2(lista):\n    suma = sum(lista)\n    media = suma / len(lista)\n    return suma, media\n\nnumeros = [10, 10, 10]\nsuma, media = suma_y_media_v2(numeros)\nprint(\"Suma:\", suma)\nprint(\"Media:\", media)\n\n#Funciones con variable local y global\nglobal_variable = 10\n\ndef suma_y_media_v3(lista):\n   \n    global global_variable\n    variable_local = 5\n    \n    suma = sum(lista) + global_variable + variable_local\n    media = suma / (len(lista)+2)\n    \n    return suma, media\n\nnumeros = [10, 10, 10]\nsuma, media = suma_y_media_v3(numeros)\nprint(\"Suma:\", suma)\nprint(\"Media:\", media)\n\n#Dificultad extra\ndef texto_a_numero(texto_1, texto_2):\n  lista = []\n  contador = 0\n  for i in range(1,101):\n    if i%3 == 0 and i%5 == 0:\n      i = texto_1+\"_y_\"+texto_2\n      lista.append(i) \n    elif i%5 == 0:\n      i = texto_2\n      lista.append(i)\n    elif i%3 == 0:\n      i = texto_1\n      lista.append(i)\n    else:\n      lista.append(i)\n      contador += 1     \n  return (lista, contador)\n\nresultado = texto_a_numero(\"tres\", \"cinco\")\nprint(\"Cantidad de números que no son multiplos de tres y de 5 :\",resultado[1])\nprint(resultado[0])"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/ThePhobos01.py",
    "content": "# Funciones en Python\n\ndef funcion():\n    print('Hola, funcion!')\n\nfuncion() #dfuncion sin parametro\n\ndef funcion_parametro(a):\n    print(a**2)\n\nfuncion_parametro(3)\n\ndef funcion_parametros(num1, num2):\n    print(num1 + num2)\n\nfuncion_parametros(2, 3) #Funcion con varios parametros\n\ndef funcion_retorno(b, c):\n    return b + c\n\nresultado = funcion_retorno(5, 5)\nprint(resultado) # Funcion con return\n\ndef funcion_anidada(n):\n    def division(num):\n        if num % 2 == 0:\n            return True\n        else:\n            return False\n\n\n    if division(n):  \n        return n ** 2  \n    else:\n        return None  \n\nresultado2 = funcion_anidada(10)\nprint(resultado2)\n\n#Funciones ya creadas en Python (Built-in function)\n\nstring = 'Hola mundo!'\nprint(len(string)) # Dice la longitud de una cadena de texto\n\nprint(string) #imprime en consola\n\n'''name = input('Como te llamas') #Pide al usuario insertar un valor\nprint(f'Tu nombre es {name}')'''\n\nprint(type(string)) #Devuelve el tipo de valor de una variable\n\n#Variable global\n\nvar_global = \"Mi variable global\"\n\nprint(f'La variable {var_global} puede ser accedida desde cualquier parte del programa')\n\ndef mi_funcion():\n    var_local = \"Mi variable local\"\n    print(f'Mi variable local puede ser accedida solamente aqui: {var_local}')\n\nmi_funcion()\n\ndef imprimir_numeros(texto1, texto2):\n    contador_numeros = 0  \n\n    for i in range(1, 101): \n        if i % 3 == 0 and i % 5 == 0:  \n            print(texto1 + texto2)  \n        elif i % 3 == 0: \n            print(texto1)  \n        elif i % 5 == 0:  \n            print(texto2)  \n        else:  \n            print(i)  \n            contador_numeros += 1  \n\n    return contador_numeros  \n\nveces_numeros = imprimir_numeros(\"Fizz\", \"Buzz\")\n\nprint(f\"Se imprimieron números {veces_numeros} veces.\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/TheReDNooB.py",
    "content": "#funciones basicas\n\n#sin parametros ni retorno\ndef saludo():\n    print(\"hola, que tal tu dia?\")\n\nsaludo()\n\n#con parametros\ndef resta(num1, num2):\n    print(num1-num2)\nresta(10,9)\n\ndef fruts(*args):\n    for arg in args:\n        print(arg)\nfruts(\"manzana\", \"pera\", \"banana\")\n\ndef datos(**kargs):\n    for i, item in kargs.items():\n        print(f\"{i}: {item}\")    \ndatos(name=\"Jhon\", lastname=\"Wick\", favorite_color=\"Black\")\n\n#con retorno\ndef producto(num1,num2):\n    return num1 * num2\nresultado_producto=producto(10,5)\nprint(f\" resultado producto: {resultado_producto}\")\n\n\n#funciones anonimas\ncalculator = lambda a,b: a * b\nresultado1 = calculator(7,8) # 56\nresutlado2 = calculator(5,2) # 10\nprint(resultado1, resutlado2)\n\n#Extra\n\ndef mostrar_numeros(param1, param2) -> int:\n    count = 0\n    for i in range(1,101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(param1 + param2)\n        elif i % 3 == 0:\n            print(param1)\n        elif i % 5 == 0:\n            print(param2)\n        else:\n            print(i)\n            count+=1\n    return count\n\nprint(mostrar_numeros(\"ping\", \"pong\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/ThonyS07.py",
    "content": "'''\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n'''\n\n\n#Funcion simple\ndef simple():\n    print(\"Soy una funcion simple\")\n\nsimple()\n\n#Función con parámetro de entrada\ndef func_para_entrada(nombre):\n    print(f\"hola, {nombre}\")\n\nfunc_para_entrada(\"Thony\")\n\n#Función con parámetro de salida y entrada\ndef func_para_entrada_salida(nombre):\n    return f\"hola, {nombre}\"\n\nprint(func_para_entrada_salida(\"Thony\"))\n\n#Función con retorno y varios argumentos de entrada\ndef func_multiple_entrada_salida(nombre, apellido):\n    return f\"hola, {nombre} {apellido}\"\n\nprint(func_multiple_entrada_salida(\"Thony\", \"Silva\"))\n\n# Función con argumento predeterminado\ndef func_predeterminado(nombre=\"Thony\", apellido=\"Silva\"):\n    return f\"hola, {nombre} {apellido}\"\n\nprint(func_predeterminado())\nprint(func_predeterminado(\"Juan\",\"Perez\"))\nprint(func_predeterminado(apellido=\"Lopez\"))\n\n#Función con argumento de longitud variable\nprint(\"Si declaramos un argumento con * (*argumentos), esto hará que el argumento que se pase sea empaquetado en una tupla de manera automática. \")\ndef func_variada(*argumentos):\n    for argumento in argumentos:\n        print(argumento)\n\nfunc_variada(\"hola\")\nfunc_variada(\"hola\", \"mundo\")\nfunc_variada(\"hola\", \"mundo\", \"a\", \"todos\")\n\nprint(\"Usando doble ** es posible también tener como parámetro de entrada una lista de elementos almacenados en forma de clave y valor. En este caso podemos iterar los valores haciendo uso de items().\")\n\ndef func_variada2(**argumentos):\n    for clave, valor in argumentos.items():\n        print(f\"{clave} = {valor}\")\n\nfunc_variada2(a = \"hola\")\nfunc_variada2(a = \"hola\", b = \"mundo\")\nfunc_variada2(a = \"hola\", b = \"mundo\", c = \"a\", d = \"todos\")\n\n#Funciones built-in\nprint(len(\"hola mundo\"))\nprint(max(1,2,3,4,5))\nprint(min(1,2,3,4,5))\nprint(pow(2,3))\n\n#variables globales y locales\na = \"global\"\nprint(a)\ndef hola ():\n    b = \"local\"\n    print(a) #se puede acceder a la variable global desde cualquier espacio del codigo, sin embargo no se puede acceder a la variable local fuera del contexto local donde se define\n    print(b)\nhola()\n\n\n\"\"\"extra\"\"\"\n\ndef multiplo(multiplo_tres, multiplo_cinco) ->int:\n    inicio=0\n    for numero in range(1,101):\n        if numero % 3 == 0 and numero % 5 == 0:\n            print(multiplo_tres + multiplo_cinco)\n           \n        elif numero % 3 == 0:\n            print(multiplo_tres)\n          \n        elif numero % 5 == 0:\n            print(multiplo_cinco)\n         \n        else:\n            print(numero)\n            inicio+=1\n    return inicio\nprint(multiplo(\"Flex\",\"Box\"))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/TizoG.py",
    "content": "# Funciones basicas sin retorno\ndef saludo():\n    print(\"Hola mundo\")\n\n\nsaludo()\n\n# Funcion con retorno\n\n\ndef saludo_retorno():\n    return \"Hola mundo\"\n\n\nprint(saludo_retorno())\n\n# Con un argumento\n\n\ndef arg_saludo(nombre):\n    print(f\"Hola {nombre}\")\n\n\nprint(arg_saludo(\"Juan\"))\n\n# Con argumentos\n\n\ndef argts_saludo(nombre, apellido):\n    print(f\"hola {nombre} {apellido}\")\n\n\nargts_saludo(\"Juan\", \"Yesca\")\n\n# Con argumentos predefinidos\n\n\ndef arg_definido(nombre=\"Juan\"):\n    print(f\"Hola {nombre}\")\n\n\narg_definido()\narg_definido(\"Juanito\")\n\n# Con argumento y retorno\n\n\ndef ret_arg(nombre, apellido):\n    return f\"Hola {nombre} {apellido}\"\n\n\nprint(ret_arg(\"Juan\", \"Yesca\"))\n\n# Con un numero variable de argumentos\n\n\ndef num_arg(*nombres):\n    for nombre in nombres:\n        print(f\"Hola {nombre}\")\n\n\nnum_arg(\"Juan\", \"Yesca\", \"Pedro\", \"Maria\")\n\n\n\"\"\"\nFunciones dentro de funciones\n\"\"\"\n\n\ndef funcion_out():\n    def funcion_in():\n        print(\"Hola mundo\")\n    funcion_in()\n\n\nfuncion_out()\n\n# Funciones del lenguaje\nprint(len(\"Juan\"))\nprint(type(\"Juan\"))\nprint(\"Juan\".upper())\n\n\"\"\"\nVariables globales y locales\n\"\"\"\nvar_global = \"Juan\"\n\n\ndef hola_juan():\n    var_local = \"Juanito\"\n    print(f\"{var_global}, {var_local}\")\n\n\nprint(var_global)\nhola_juan()\n\n\n\"\"\"\nExtra\n\"\"\"\n\n\ndef print_numeros(texzto1, texto2) -> int:\n    count = 0\n    for numeros in range(1, 101):\n        if numeros % 3 == 0 and numeros % 5 == 0:\n            print(texzto1 + texto2)\n        elif numeros % 3 == 0:\n            print(texzto1)\n        elif numeros % 5 == 0:\n            print(texto2)\n        else:\n            print(numeros)\n            count += 1\n    return count\n\n\nprint(print_numeros(\"Fizz\", \"Buzz\"))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Tomu98.py",
    "content": "\"\"\" Reto 02: Funciones y Alcance\"\"\"\n\n\"\"\" Funciones definidas por el usuario \"\"\"\n\n# Simple\ndef greet():\n    print(\"Hola, Python!\")\n\ngreet()\n\n# Con retorno\ndef return_greet():\n    return \"Hola, Python!\"\n\nprint(return_greet())\n\n# Con un argumento\ndef arg_greet(name: str):\n    print(f\"Hola, {name}!\")\n\narg_greet(\"Tomu\")\n\n# Con más argumentos\ndef args_greet(greet: str, name: str):\n    print(f\"{greet}, {name}!\")\n\nargs_greet(\"Hi\", \"Tomu\")\nargs_greet(name=\"Tomu\", greet=\"Hi\")\n\n# Con un argumento predeterminado\ndef default_arg_greet(name: str=\"Python\"):\n    print(f\"Hola, {name}!\")\n\ndefault_arg_greet(\"Tomu\")\ndefault_arg_greet()\n\n# Con argumentos y retorno\ndef return_args_greet(greet: str, name: str):\n    return f\"{greet}, {name}!\"\n\nprint(return_args_greet(\"Hi\", \"Tomu\"))\n\n# Con retorno de varios valores\ndef multiple_return_greet():\n    return \"Hola\", \"Python\"\n\ngreet, name = multiple_return_greet()\nprint(greet)\nprint(name)\n\n# Con un número variable de argumentos\ndef variable_arg_greet(*names: str):\n    for name in names:\n        print(f\"Hola, {name}!\")\n\nvariable_arg_greet(\"Python\", \"Tomu\", \"Brais\")\n\n# Con un número variable de argumentos con palabra clave\ndef variable_key_arg_greet(**names: str):\n    for key, value in names.items():\n        print(f\"{value} ({key})!\")\n\nvariable_key_arg_greet(\n    language=\"Python\",\n    name=\"Abel\",\n    alias=\"Tomu\",\n    age=\"25\"\n)\n\n\n\n\"\"\" Funciones dentro de funciones \"\"\"\n\ndef outer_function():\n    def inner_function():\n        print(\"Función interna: Hola, Python!\")\n    inner_function()\n\nouter_function()\n\n\n\n\"\"\" Funciones del lenguaje (Built-in) \"\"\"\n\nprint(len(\"Tomu\"))\nprint(type(\"Tomu\"))\nprint(sum([21, 12]))\nprint(min([21, 12]))\nprint(max([21, 12]))\n\n\n\n\"\"\" Variables locales y globales \"\"\"\n\nglobal_var = \"Python\"\n\ndef hello_python():\n    local_var = \"Hola\"\n    print(f\"{local_var}, {global_var}!\")\n\nprint(global_var)\n# print(local_var) No se puede acceder desde fuera de la función\n\nhello_python()\n\n\n\n\"\"\" Reto extra \"\"\"\n\ndef print_numbers(texto1: str, texto2: str) -> int:\n    count = 0\n    for number in range(1, 101):\n        if number % 3 == 0 and number % 5 == 0:\n            print(f\"{texto1} + {texto2}\")\n        elif number % 3 == 0:\n            print(texto1)\n        elif number % 5 == 0:\n            print(texto2)\n        else:\n            print(number)\n            count += 1\n    return count\n\nprint(print_numbers(\"Fizz\", \"Buzz\"))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/TroyNebula.py",
    "content": "'''\r\nCrea ejemplos de funciones básicas que representen las diferentes posibilidades del lenguaje:\r\nSin parámetros ni retorno, con uno o varios parámetros, con retorno...\r\n'''\r\n# Funciones definidas por el usuario:\r\n# Con retorno y con variables -------------------------------------\r\nresta = 0\r\n\r\ndef restar(variable1, variable2):\r\n    resta = variable1- variable2\r\n    return resta\r\n\r\nresta = restar(1, 2) # Asignar el resultado de la función a la variable suma\r\nprint(resta) # Imprimir el valor actualizado de la variable suma\r\n\r\n# Con retorno y sin variables -------------------------------------\r\ndef sumar ():\r\n    return (1+2)\r\n\r\nprint (sumar())\r\n\r\n# Podría declararla definiendo lo que me tiene que devolver:\r\ndef sumar () -> str:  # digo que devuelve una string\r\n    return (1+2)\r\n\r\nprint (sumar())\r\n\r\n# Sin retorno y con variable -------------------------------------\r\ndef saludar(nombre):\r\n    print(\"¡Hola, \" + nombre + \"!\")\r\n\r\nsaludar(\"Troy\")\r\n\r\n# Sin retorno y sin variables -------------------------------------\r\ndef saludar():\r\n    print(\"¡Hola mundo!\")\r\n\r\nsaludar()\r\n\r\n# Con parámetro por defecto, por si quiero llamarla si darle un valor al argumento -------------------------------------\r\ndef saludar(nombre=\"persona sin nombre\"): # Si no le damos ninguno, que salude al desconocido\r\n    print(\"¡Hola, \" + nombre + \"!\")\r\n\r\nsaludar()\r\n\r\n# Con argumentos sin orden -------------------------------------\r\ndef saludar(saludo, nombre):\r\n    print(\"¡\",saludo, \",\", nombre, \"!\") # Así me pondría un espacio al lado de cada ¡ Hola , Troy !\r\n    print (f\"¡{saludo}, {nombre}!\") # Así sale ¡Hola Troy! \r\n\r\nsaludar(nombre=\"Troy\", saludo=\"Hola\") # en orden aunque yo al llamar a la función lo ponga desordenado pero le digo cual es cual\r\n\r\n# Con retorno de más de un valor (una tupla) -------------------------------------\r\ndef multiple_retorno ():\r\n    return \"Hola\", \"Python\"  #retorna 2 cadenas de texto\r\nprint (multiple_retorno()) #Muestra ('Hola', 'Python') los dos valores acoplados con paréntesis y coma entre ellos\r\n\r\ndef multiple_retorno2 ():\r\n    return \"Hi\", \"Python 🐍\" \r\nsaludo2, lenguaje2 =multiple_retorno2() # descompongo los valores y los introduzco en variables\r\nprint (saludo2)\r\nprint (lenguaje2)\r\nprint(f\"¡{saludo2}, {lenguaje2}!\")\r\n\r\n# Una función lambda -------------------------------------\r\n# función anónima y pequeña que puede tener cualquier número de argumentos, pero solo puede tener una expresión. \r\nsumar = lambda x, y: x + y\r\nresult_lambda = sumar(3, 5)\r\nprint(result_lambda)  \r\n\r\n\r\n'''\r\nComprueba si puedes crear funciones dentro de funciones. -------------------------------------\r\n'''\r\n\r\ndef imprimir ():\r\n    def obtener_resultado (var1, var2, var3):\r\n        resultado = (var1+var2)*var3\r\n        return resultado\r\n\r\n    resultado_calculado = obtener_resultado(1, 2, 3)  # Llamada a la función anidada/interna obtener_resultado y almacenamiento del resultado\r\n    \r\n    print(resultado_calculado)  # Imprimir el resultado almacenado\r\n\r\nimprimir() # Llamada a la función principal\r\n\r\n'''\r\nUtiliza algún ejemplo de funciones ya creadas en el lenguaje\r\n'''\r\n# la función upper vuelve la cadena/texto/string a mayúsculas -------------------------------------\r\ndef imprimir_mayusculas(texto):\r\n    def convertir_a_mayusculas(cadena):\r\n        mayusculas = cadena.upper()   # upper() es una función interna del lenguaje asociada al tipo de dato\r\n        return mayusculas\r\n\r\n    texto_en_mayusculas = convertir_a_mayusculas(texto) # Llamada a la función anidada\r\n    \r\n    print(f\"Texto en mayúsculas: {texto_en_mayusculas}\")  # Imprimir resultados, más elegante poner el formato del texto con la f\r\n                                                          # print(\"Texto en mayúsculas:\", texto_en_mayusculas)  -> Otra opción\r\n    \r\nimprimir_mayusculas (\"Troy Nebula\") # Troy Nebula es el valor de la variable texto\r\n\r\n\r\n# función con i cantidad de parametros que devuelve cantidad de números y suma de ellos -------------------------------------\r\ndef suma(*i):  \r\n    print(f\"Parametros introducidos: {len(i)}\")  #len\r\n    print(f\"Resultado de la suma {sum(i)}\")   #sum\r\n    \r\nsuma(1, 3, 5, 7, 9)\r\nsuma(2, 4, 6, 8, 10)\r\n\r\n# otro ejemplo de un número variable de elementos -------------------------------------\r\ndef saludos (*names):\r\n    for name in names:\r\n        print (f'Hola, {name}!')\r\n\r\nsaludos (\"Troy\", \"Nebula\", \"Brais\")\r\n\r\n# otro ejemplo de un número variable de argumentos (+ exclusivo de Python) -------------------------------------\r\ndef saludos2 (**names):  #le podemos incluir una clave dentro de cada argumento con los **\r\n    for param_key, value in names.items():   #items() acaba desomponiendo cada uno de los parámetros en clave=valor\r\n        print (f'Hola, {value}, {param_key}!')\r\n\r\nsaludos2 (\r\n    nombre=\"Troy\", \r\n    nick=\"Nebula\", \r\n    edad= 45)\r\n\r\n# funcion que retorna mas de un número, el mínimo y el máximo de los que se introducen -------------------------------------\r\ndef minimo_y_maximo(*numeros):  \r\n    return min(numeros), max(numeros)   # min   y   max\r\n\r\nminimo, maximo = minimo_y_maximo (613, 6, 17, 101, 19, 111, 8001)\r\nprint(f\"Mínimo: {minimo}, Máximo: {maximo}\")\r\n\r\n# otras funciones del lenguaje -------------------------------------\r\nvar_input = input(\"Escribe algo, texto o número aquí, para guardarlo en una variable y pulsa Enter: \")\r\nprint(\"Lo que has introducido es:\", var_input)\r\n# la función input() siempre lee la entrada cadena/string, incluso si ingreso un número\r\n# así que lo tengo que convetir a número int (o float) asi:\r\ntry:\r\n    var_algo = int(var_input)\r\n    tipo = type(var_algo)\r\n    print(\"Lo introducido es de clase:\", tipo, \"es decir, un número entero.\")\r\nexcept ValueError:\r\n    print(\"Lo introducido no es un número, así que será un texto.\")\r\n\r\nprint(len([0, 1, 2, 3, 4, 5])) # devuelve la cantidad de elementos que posee\r\nprint(str(1)) # convierte a texto\r\nprint(int(\"1\")) # convierte a entero\r\nprint(float(\"20.55\")) # convierte a decimal\r\nprint(sorted([1,3,55,8,2,11,0,31,7,6])) # ordena los elementos de una lista\r\n\r\n\r\n\r\n'''\r\nPon a prueba el concepto de variable LOCAL y GLOBAL -------------------------------------\r\n'''\r\n\r\nvariable_global = \"Global\" # Variable global -> Fuera de la función\r\n\r\ndef funcion_con_variable_local(): # Variable local -> dentro de la función\r\n    \r\n    variable_local = \"Local\"\r\n    print(f\"Dentro de la función: {variable_local}\")\r\n    print(f\"Dentro de la función (solo sirve la global): {variable_global}\")\r\n\r\nfuncion_con_variable_local() # Llamada a la función\r\n\r\n# Intento acceder a la variable local desde fuera de la función (resultará en un error)\r\n# print(f\"Fuera de la función: {variable_local}\")  # Comento esta línea porque da error, fuera de la función no está definida y no la puedo llamar\r\n\r\nprint(f\"Fuera de la función: {variable_global}\")  # Acceso a la variable global desde fuera de la función\r\n\r\n'''\r\nDIFICULTAD EXTRA (opcional): -------------------------------------\r\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\r\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\r\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\r\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\r\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\r\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\r\n '''\r\n\r\ndef retornar_num (str1, str2):  # variables de tipo texto/string\r\n    for n in range (1,101):\r\n        if n % 3 ==0 and n % 5 !=0:\r\n            print (str1)\r\n        elif n % 5==0 and n % 3 !=0:\r\n            print (str2)\r\n        elif n % 3 ==0 and n % 5 ==0:\r\n            print (str1, \"y\", str2)\r\n        else:\r\n            print (n)\r\n            n +=1  #  n ==n+1   -> otra manera de escribirlo, que aumente de uno en uno el número que va iterando\r\n    return n\r\n\r\nretornar_num(\"Múltiplo Tres\", \"Múltiplo Cinco\")\r\n    "
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/VictorRivero1204.py",
    "content": "\"\"\"\nFunciones definidas por el usuario\n\"\"\"\n\n# Simple\n\ndef greet():\n    print(\"Hola, Python!\") \n\ngreet()\n\n# Con retorno \n\ndef return_greet():\n    return \"Hola, Python 2!\"\n\nprint(return_greet())\n\n# Con argumento\n\ndef arg_greet(name):\n    print(f\"Hola, {name}!\")\n\narg_greet(\"Victor\")\n\n# Con argumentos\n\ndef arg_greet(greet, name):\n    print(f\"{greet}, {name}!\")\n\narg_greet(\"Hi\", \"Victor\")\narg_greet(name=\"Victor\", greet=\"Hi\")\n\n# Con un argumento predeterminado\n\ndef default_arg_greet(name = \"Python\"):\n    print(f\"Hola, {name}!\")\n\ndefault_arg_greet(\"Victor\")\ndefault_arg_greet()\n\n# Con argumentos y return\n\ndef return_arg_greet(greet, name):\n    return f\"{greet}, {name}!\"\n\nprint(return_arg_greet(\"Hi\", \"Victor\"))\n\n# Con retorno de varios valores\n\ndef multiple_return_greet():\n    return \"Hola\", \"Python\"\n\nprint(multiple_return_greet())\n\ngreet, name = multiple_return_greet()\nprint(greet)\nprint(name)\n\n# Con un numero variable de argumentos\n\ndef variable_arg_greets(*names):\n    for name in names:\n        print(f\"Hola, {name}!\")\n\nvariable_arg_greets(\"Python\", \"Victor\", \"Jose\", \"Maria\")\n\n# Con un numero variable de argumentos con palabra clave \n\ndef variable_key_arg_greets(**names):\n    for key, value in names.items():\n        print(f\"{value}  ({key})\")\n\nvariable_key_arg_greets(\n    language=\"Python\", \n    name=\"Victor\", \n    user=\"VictorRivero1204\", \n    edad=23\n)\n\n\"\"\"\nFunciones dentro de funciones\n\"\"\"\n\ndef outer_function():\n    def inner_function():\n        print(\"Funcion interna: Hola, Python!\")\n    inner_function()\n\nouter_function()\n\n\"\"\"\nFunciones del lenguaje (built-in)\n\"\"\"\n\nprint(len(\"Victor\"))\nprint(type(23))\nprint(\"Victor\" .upper())\n\n\"\"\"\nVariables locales y globales\n\"\"\"\n\nglobal_var = \"Python\"\n\n\ndef hello_python():\n    local_var = \"Hola\"\n    print(f\"{local_var}, {global_var}!\")\n\nprint(global_var)\n# print(local_var) No se puede acceder desde fuera de la funcion\n\nhello_python()\n\n\"\"\"\nExtra\n\"\"\"\n\ndef print_numbers(text_1, text_2) -> int:\n    count = 0 \n    for number in range (1, 101):\n        if number % 3 == 0 and number % 5 == 0:\n            print(text_1 + text_2)\n        elif number % 3 == 0:\n            print(text_1)\n        elif number % 5 == 0:\n            print(text_2)\n        else:\n            print(number)\n            count += 1\n    return count\n\nprint(print_numbers(\"Fizz\", \"Buzz\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/VictorZm0h.py",
    "content": "## Ejercicio\r\n\r\n\"\"\"\"\r\n/*\r\n * EJERCICIO:\r\n * - Crea ejemplos de funciones básicas que representen las diferentes\r\n *   posibilidades del lenguaje:\r\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\r\n * - Comprueba si puedes crear funciones dentro de funciones.\r\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\r\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\r\n * - Debes hacer print por consola del resultado de todos los ejemplos.\r\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\r\n *\r\n * DIFICULTAD EXTRA (opcional):\r\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\r\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\r\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\r\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\r\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\r\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\r\n *\r\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\r\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\r\n */\r\n\"\"\"\r\n# Función sin parámetros ni retorno\r\ndef saludar():\r\n    print(\"¡Hola, bienvenido!\")\r\nsaludar()\r\n# Función con parámetros y sin retorno\r\ndef sumar(a, b):\r\n    print(f\"La suma de {a} y {b} es: {a + b}\")\r\nsumar(2, 8)\r\n# Función con parámetros y con retorno\r\nnum1=int(input(\"Introduce un número: \"))\r\nnum2=int(input(\"Introduce otro número: \"))\r\ndef multiplicar(num1, num2):\r\n    return num1 * num2\r\nresultado=multiplicar(num1, num2)\r\nprint(\"El resultado de la multiplicación es: \" + str(resultado))\r\n\r\ndef saludo(mensaje, nombre):\r\n    print(f\"{mensaje}, {nombre}\")\r\nsaludo(nombre=\"Victor\", mensaje=\"Hola\")\r\n\r\ndef saludo_con_retorno():\r\n    return \"Hola\", \"Victor\"\r\nmensaje, nombre = saludo_con_retorno()\r\nprint(mensaje)\r\nprint(nombre)\r\n# Función dentro de otra función\r\ndef funcion_externa():\r\n    def funcion_interna():\r\n        print(\"Esta es una función interna.\")\r\n    funcion_interna()\r\nfuncion_externa()\r\n# Funciones incorporadas\r\nmensaje=input(\"Escribe un mensaje: \")\r\nprint(\"La longitud del mensaje escrito es de: \" + str(len(mensaje)) + \" caracteres.\")\r\ndef saludos(*nombres):\r\n    for nombre in nombres:\r\n        print(\"Hola, \" + nombre)\r\nsaludos(\"Ana\", \"Luis\", \"Carlos\", \"Marta\", \"Sofía\")\r\n # Utiliza la función incorporada len()\r\nvalor=float(input(\"Introduce un número decimal: \"))\r\nprint(\"El tipo de dato ingresado es un: \" + str(type(valor)))\r\n# Variable global y local\r\nvariable_global=\"Soy una variable global\"\r\ndef mostrar_variables():\r\n    variable_local=\"Soy una variable local\"\r\n    print(variable_global)\r\n    print(variable_local)\r\nmostrar_variables()\r\ndef variable_local():\r\n    tipo_variable=\"local\"\r\n    print(\"Esto es una variable: \" + tipo_variable)\r\nvariable_local()\r\n# Dificultad extra\r\ndef cadena_texto(cadena1, cadena2):\r\n    contador=0\r\n    for numeros in range(1, 101):\r\n        if numeros % 3 == 0 and numeros % 5 == 0:\r\n            print(cadena1 + cadena2)\r\n        elif numeros % 3 == 0:\r\n            print(cadena1)\r\n        elif numeros % 5 == 0:\r\n            print(cadena2)\r\n        else:\r\n            print(numeros)\r\n            contador+=1\r\n    return contador\r\nresultado=cadena_texto(\"Fizz\", \"Buzz\")\r\nprint(\"El número de veces que se imprimió un número en lugar de los textos es: \" + str(resultado))\r\n\r\n\r\n\r\n\r\n\r\n\r\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Yani-Git.py",
    "content": "#una función es un bloque de código. Se crea para poder realizar una acción específica\n#proporciona una forma de organizar el código en bloques lógicos\n\n\"\"\"\nfunciones definidas por el usuario. \nlas crea el usuario como le de la gana\nla función se define con \"def\"\n\n\"\"\"\n\n#Simple\n\n\ndef greet ():\n    print (\"Hola, Python\")\n\ngreet ()\n\n\n#Funcion con retorno va a acabar devolviendo algo \n\ndef return_greet():       #en python aunque no se defina algo puedría devolverlo porque es un leguaje de tipado dinamico\n    return \"Hola, Python!\"\n\n\n# greet = return_greet()\nprint (return_greet())\n\n\n# funciones con un argumento: sigunifica que le podemos pasar parámetros a la función \n\ndef arg_greet (name):\n    print (f\"Hola, {name}!\")\n\narg_greet (\"Yani\")\n\n\n#con argumentos \n\ndef arg_greet (greet, name):\n    print (f\"{greet}, {name}!\")\n\narg_greet (\"Hi\",\"Yani\")\narg_greet (name=\"Yani\", greet=\"Hi\")\n\n\n\n#con un argumento predeterminado\n\n\ndef defoult_arg_greet (name =\"Python\"):\n    print (f\"Hola, {name}!\")\n\ndefoult_arg_greet (\"Yani\")\ndefoult_arg_greet ()\n\n#funciones con argumentos  y retornos \n\ndef return_arg_greet (greet, name):\n    return f\"{greet}, {name}!\"\n\nprint(return_arg_greet(\"Hi\", \"Yani\"))\n\n\n#funcion con retorno de varios valores-tupla de valores \n\ndef multiple_return_greet ():\n    return \"Hola\", \"Python\"\n\ngreet, name =multiple_return_greet()\nprint(greet)\nprint (name)\n\n\n\"\"\"\n\nen python se pueden crear funciones básicas\n\n>>ejemplo de funciones básicas = \n\n1.- con un numero  variables de argumentos\n\n2.- con un numero  variables de argumentos pero con palabra clave \n\n\"\"\"\n\n\n#1.- con un numero  variables de argumentos\n\ndef variable_arg_greet(*names):  #el asterisco indica que le podemos pasar mas de un nombre separados por coma, es decir, guarda mas de un resultado en la memoria\n    for name in names:\n        print (f\"Hola, {name}!\")\n\nvariable_arg_greet (\"Python\", \"Yani\",\"Yanines\", \"Github\")\n\n\n#2.- con un numero  variables de argumentos pero con palabra clave \n\ndef variable_key_arg_greet(**names):  # se colocan dos asteriscos para indicar una clave a cada argumento, lo que significa que cada argumento estará formado por una clave y un valor\n    for key, value in names.items ():\n        print (f\"{value} ({key})!\")\n\nvariable_key_arg_greet (\n\n    leguaje =\"Python\", \n    name=\"Yani\", \n    alias =\"Yanines\", \n    age= 47\n\n    )\n\n\"\"\"\nfunciones dentro de funciones \n\n\"\"\"\n\ndef outer_function():\n    def inner_function():\n        print (\"Función interna: Hola, Python !\")\n    inner_function()\n\nouter_function()\n\n\"\"\"\nfunciones construidas dentro del lenguaje (built- in)\n\n\n\"\"\"\n\nprint (len(\"yanines\")) #funcion \"len\" le pasamos un texto y devuelve un entero\nprint (type(\"yanines\")) #nos dice el tipo dato que le estamos poniendo en la  variable, en este caso es una cadena de texto\nprint (\"yanines\".upper()) #devuelve la función en mayuscula\n\n\"\"\"\nVariables locales y globales \n\n    tiene que ver con el concepto de ámbito, \n\n\"\"\"\n\nglobal_var = \"Python\"\nprint (global_var)\n\n\ndef hello_python():  #las funciones se definen, imprimen y se llaman, si no la llamo no se imprime\n    local_var = \"Hola\"  #solo se va poder acceder a la variable  dentro de la función \n    print (f\"{local_var}, {global_var}!\")\n\nprint (global_var)\n#print (local_var) no se puede acceder a una variable local fuera de la función \n#hay que valorar o ponderar si resulta conveniente que la variable sea global o local \n\n\nhello_python ()\n\n\"\"\"\nExtra, ejercicios \n\n\"\"\"\ndef print_numbers (text_1, text_2)-> int:\n    count =0 \n    for number in range (1, 101):\n        if  number % 3 ==0 and number % 5 ==0: \n             print (text_1 + text_2)\n        elif number % 3 ==0:\n            print (text_1)\n        elif number % 5 ==0:\n            print (text_2)\n        else: \n            print(number)\n            count += 1\n    return count\n\n#print_numbers(\"Texto 1\",\"Texto 2\")\n\nprint (print_numbers(\"Fizz\",\"Buzz\"))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/YgriegaSB.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\"\"\"\n\ndef printHola(name):\n    print(f\"¡Hola, {name}!\")\n\nprintHola('Andy')\n\n\ndef suma(num1, num2):\n\n    def resta(num1, num2):\n        return print(f\"Resta: entre {num1} - {num2} = {num1-num2}\");\n\n    resta(num1, num2)\n    return print(f\"Suma: entre {num1} + {num2} = {num1+num2}\");\n\n\nsuma(20, 10.4)\n\n\n# sort function\narr = [5,1,25,2,15,12,9,7,20]\nprint(arr)\narr.sort()\nprint(arr)\n\n\n# Ejercicio\ndef string_parameters(param1, param2):\n    num_characters = len(param1) + len(param2)\n    return num_characters\n\nprint(string_parameters('Hola', 'Mundo'))\n\n\n# Ejercicio Extra\ndef print_numbers(range1, range2):\n    counter=0\n    for i in range(range1, range2):\n        if(i%5==0 and i%3==0):\n            print('FizzBuzz')\n        elif(i%3==0):\n            print('Fizz')\n        elif(i%5==0):\n            print('Buzz')\n        else:\n            print(i)\n            counter += 1\n    return print(f\"cantidad de numeros: {counter}\")\n     \nprint_numbers(1, 101)\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/YorjanVarela.py",
    "content": "#función basica en python \n\nprint(\"hola mundo\") #imprime cosas en pantalla \n\n#función sin parametro ni retorno \n\ndef saludar():\n    print(\"¡Hola!\")\n\nsaludar()  # Salida: ¡Hola!\n\n#funciónes con uno o varios paramatros\n\ndef sumar(a, b):\n    resultado = a + b\n    print(\"La suma es:\", resultado)\n\nsumar(3, 5)  # Salida: La suma es: 8\n\n#función con retorno\n\ndef multiplicar(a, b):\n    return a * b\n\nresultado = multiplicar(4, 6)\nprint(resultado)  # Salida: 24\n\n#función dentro de otra función o función aninada\n\ndef funcion_externa(x):\n    def funcion_interna(y):\n        return x * y\n    return funcion_interna\n\n# Crear una función interna específica\nmultiplicar_por_5 = funcion_externa(5)\n\n# Usar la función interna\nresultado = multiplicar_por_5(3)\nprint(resultado)  # Salida: 15\n\n#funciónes que ya vienen con el lenguaje \n\n\nvalor_absoluto = abs(5) \nprint(valor_absoluto) \n\nlength = len(\"hola\")\nprint(length)\n\ntype = type(\"hola\")\nprint(type)\n\n\n\n#entre muchas otras que harian el codigo infinito  pero son muchas y muy utiles cuya finalidad es evitar que escribamos el codigo desde cero.\n\n#variables local y globales\n\n# Variable global\nmensaje = \"Hola, mundo!\"\n\ndef mi_funcion():\n    # Variable local\n    nombre = \"Juan\"\n    print(mensaje)  # Podemos acceder a la variable global\n    print(nombre)  # Solo podemos acceder a nombre dentro de la función\n\nmi_funcion()\nprint(mensaje)  # Podemos acceder a mensaje fuera de la función\n# print(nombre)  # Esto daría error, porque nombre solo existe dentro de mi_funcion()\n\n\n\n#Ejercicio extra\n\ndef my_function(a, b):\n    for i in range(1, 101): \n        if i % 3 == 0 and i % 5 == 0:\n            print(a, b)\n        elif i % 3 == 0:\n            print(a)\n        elif i % 5 == 0:\n            print(b)\n        else:\n            print(i)\n    \nprint(my_function(\"hola\", \"mundo\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Zequy40.py",
    "content": "'''\n* EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n '''\n# Función sin parámetros ni retorno\ndef funcion_sin_parametros_ni_retorno():\n    print(\"Esta es una función sin parámetros ni retorno.\")\n\n# Función con uno o varios parámetros\ndef funcion_con_parametros(parametro1, parametro2):\n    suma = parametro1 + parametro2\n    print(f\"La suma de {parametro1} y {parametro2} es: {suma}\")\n\n# Función con retorno\ndef funcion_con_retorno(a, b):\n    multiplicacion = a * b\n    return multiplicacion\n\n# Función que contiene otra función\ndef funcion_con_funcion():\n    def funcion_interna():\n        print(\"Esta es una función interna dentro de otra función.\")\n    funcion_interna()\n\n# Uso de funciones ya creadas en el lenguaje\ndef funcion_con_funcion_builtin():\n    lista = [1, 2, 3, 4, 5]\n    longitud = len(lista)\n    print(f\"La longitud de la lista es: {longitud}\")\n\n# Funciones integradas de Python\n\n# Funciones para manejar listas\nlista = [1, 2, 3, 4, 5]\nprint(\"Suma de la lista:\", sum(lista))\nprint(\"Longitud de la lista:\", len(lista))\nprint(\"Valor mínimo de la lista:\", min(lista))\nprint(\"Valor máximo de la lista:\", max(lista))\n\n# Funciones para manejar cadenas de texto\ncadena = \"Hola, mundo!\"\nprint(\"Longitud de la cadena:\", len(cadena))\nprint(\"Cadena en mayúsculas:\", cadena.upper())\nprint(\"Cadena en minúsculas:\", cadena.lower())\nprint(\"Cadena en separados por los espacios:\", cadena.split())\nprint(\"Cadena con las primeras letra en mayuscula:\", cadena.capitalize())\nprint(\"Cadena con la primera letra en mayuscula:\", cadena.title())\n      \n# Funciones matemáticas\nnumero = 3.14\nprint(\"Valor absoluto:\", abs(numero))\nprint(\"Redondeo hacia arriba:\", round(numero))\nprint(\"Redondeo hacia abajo:\", round(numero, 1))\n\n# Funciones de conversión de tipos\ncadena_numero = \"123\"\nnumero_convertido = int(cadena_numero)\nprint(\"Número convertido a entero:\", numero_convertido)\n\n# Funciones de entrada/salida\nnombre = input(\"Ingrese su nombre: \")\nprint(\"Hola,\", nombre)\n\n# Funciones para manejar archivos\narchivo = open(\"ejemplo.txt\", \"w\")\narchivo.write(\"Hola, este es un ejemplo de archivo.\")\narchivo.close()\n\n# Variables globales y locales\nvariable_global = 10  # Variable global\n\ndef funcion_con_variable_local():\n    variable_local = 5  # Variable local\n    suma = variable_global + variable_local\n    print(f\"Suma de variable global y local: {suma}\")\n\n# Ejecución de las funciones\nfuncion_sin_parametros_ni_retorno()\n\nparametro1 = 3\nparametro2 = 7\nfuncion_con_parametros(parametro1, parametro2)\n\nresultado = funcion_con_retorno(parametro1, parametro2)\nprint(f\"El resultado de la función con retorno es: {resultado}\")\n\nfuncion_con_funcion()\n\nfuncion_con_funcion_builtin()\n\nfuncion_con_variable_local()\nprint(f\"Variable global fuera de la función: {variable_global}\")\n\n# Generar un error al intentar imprimir la variable local fuera de su ámbito\n# print(f\"Variable local fuera de la función: {variable_local}\")\n\n'''\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n'''\n\ndef numeros_condicionales(cadena1, cadena2):\n    contador = 0\n    for numero in range(1, 101):\n        if numero % 3 == 0 and numero % 5 == 0:\n            print(cadena1 + cadena2)\n        elif numero % 3 == 0:\n            print(cadena1)\n        elif numero % 5 == 0:\n            print(cadena2)\n        else:\n            print(numero)\n            contador += 1\n\n    return contador\n\n# Ejemplo de uso\nresultado = numeros_condicionales(\"C#\", \"Python\")\nprint(f\"Python fue {resultado} veces + popular que C#.\")\n# 😁😁\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Zerek247.py",
    "content": "# --------------------- FUNCIONES Y ALCANCE -----------------------------\n\n#Funcion sin parametros ni retorno\n'''Esta función no toma ningún parámetro y no devuelve ningún valor.\nSimplemente ejecuta una acción (en este caso, imprime un mensaje).'''\ndef saludo():\n    print(\"Hola, mundo!\")\n#Llama a la función\nsaludo()\n\n#Función con parametro\n'''Esta función toma un parámetro y no devuelve ningún valor. \nEjecuta una acción utilizando el parámetro proporcionado.'''\n\ndef nombre(arg):\n    print(f\"\\nHola, {arg}\")\n#Llamar a la función con un argumento\nnombre(\"Zerek\")\n\n#Función con varios parametros\n'''Esta función toma varios parámetros y no devuelve ningún valor. \nEjecuta una acción utilizando los parámetros proporcionados.'''\ndef sumar(a, b):\n    print(f'\\nLa suma de {a} y {b} es: {a + b}')\n#Llamar a la función con dos argumentos\nsumar(4,6)\n\n#Función con retorno\n'''Esta función toma un parámetro y devuelve un valor. \nRealiza una operación y utiliza el return para devolver el resultado.'''\ndef suma():\n    return 5 + 2\n\nresultado = suma()\nprint(f\"\\n{resultado}\")\n\n#Función con varios parametros y retorno\n'''Esta función toma varios parámetros y devuelve un valor. \nRealiza una operación utilizando los parámetros y devuelve el resultad.'''\ndef operaciones(a, b):\n    resultados = {\n        \"suma\": a + b,\n        \"resta\": a - b,\n        \"multiplicacion\": a * b,\n        \"division\": a / b\n    }\n    \n    for operacion, resultado in resultados.items():\n        print(f\"La {operacion} de {a} y {b} es: {resultado}\")\n    \n    return resultados\n\nresultados = operaciones(10, 2)\n\n\n#Función con parametros por defecto\n'''Esta función toma parámetros opcionales con valores por defecto. \nSi no se proporcionan argumentos, se utilizan los valores por defecto.'''\n\ndef saludar(nombre=\"Mundo\"):\n    return f\"\\nHola {nombre}\"\n\nprint(saludar()) #Llamar a la funcion sin argumento\nprint(saludar(\"Zerek\")) #Llamar a la funcion con argumento\n\n#Función con un numero variable de parametro\n'''Esta función puede aceptar un número variable de argumentos utilizando *args.'''\ndef sumar_todo(*numeros):\n    total = sum(numeros)\n    return total\n\nprint(f'sumar_todo(1,2,3)\\n')\n\n\n#Función con un número variable de parametros con nombre\n'''Esta función puede aceptar un número variable de argumentos con nombre utilizando **kwargs.'''\ndef mostrar_info(**info):\n    for clave, valor in info.items():\n        \tprint(f\"{clave}: {valor}\")\n\n# Llamar a la función con diferentes argumentos con nombre\nmostrar_info(nombre=\"Zerek\", edad=27, ciudad=\"México\")\n\n\n# ------------------ FORMAS DE CREAR UNA FUNCIÓN DENTRO DE OTRA FUNCÓN ------------------\n\n#Llamar a una función desde otra función\ndef funcion_a():\n    print(\"Esta es la función A\")\n    \ndef funcion_b():\n    print(\"\\nEsta es la función B\")\n    funcion_a()\n    \nfuncion_b()\n\n#Retornar una función desde otra función (Funciones anidadas)\ndef exterior():\n    def interior():\n        print(\"\\nEsta es la función interior\")\n    return interior\n\nfunc = exterior()\nfunc()\n\n#Pasar una función como argumento a otra función\ndef funcion_a():\n    print(\"Esta es la función A\")\n\ndef funcion_b(func):\n    print(\"\\nEsta es la función B\")\n    func()\n    \nfuncion_b(funcion_a)\n\n\n#Usando decoradores\ndef decorador(func):\n    def envoltura():\n        print(\"Antes de la función\")\n        func()\n        print(\"Después de la función\")\n    return envoltura\n\n@decorador\ndef funcion_a():\n    print(\"Esta es la función A\")\n\nfuncion_a()\n\n\n#--------------------- FUNCIONES CREADAS POR EL LENGUAJE -----------------------\nprint(\"\\n\")\n#Funciones de conversión de tipos\n\n# abs() -> Devuelve un numero absoluto (Siempre positivo)\nprint(abs(-5))\n# all() -> Devuelve True si todos los elementos de un iterable son verdaaderos o esta vacío, si uno es False devuelve False\nprint(all([True, True, False]))\n# any() -> Devuelve True si al menos uno de los elementos de un iterable es verdadero, si todos son False o está vacío devuelve False\nprint(any([False, False, True]))\n# ascii() -> Especial para caracteres especiales \nprint(ascii('ä'))\n# bin() -> Convierte un numero entero en su representación binaria\nprint(bin(10))\n# bool() -> Convierte a True o False (Cualquier valor no vacío o que no sea None, False, 0, 0.0 devuelve True)\nprint(bool([1,2]))\n# bytearray() -> crea una secuencia mutable de bytes, es decir, se puede modificar\nbarr = bytearray(\"Hola\", \"utf-8\")\nbarr[0] = 87\nprint(barr)\n# bytes() -> Crea un objeto de tipo bytes, que es una secuencia inmutable, no se puede modificar\nbarr = bytearray([72, 111, 108, 97])\nb = bytes(barr)\nprint(b)\n# chr -> Toma un núnero entero y devuelve como cadena de un solo caracter ascii\nprint(chr(97))\n# complex() -> Crear numero complejo (Un argumento = 1 numero complejo) (2 argumentos parte real o imaginaria de un complejo)\nc = complex(2, 3)\nprint(c)\n# dict() -> Crear un nuevo diccionario o convertir otros objetos en diccionarios\nd = dict(a=1,b=2)\nprint(d)\n# dir() -> Listar los nombres de los atributos y metodos de un objeto\nprint(dir([]))\n# divmod() -> Toma dos numeros y devuelve una tupla que contiene el resto de la division entera de esos dos numeros\nprint(divmod(47,24))\n# enumerate() -> Agregar un contador a un iterable y devolverlo como un objeto enumerado\nfor i, value in enumerate(['a', 'b','c']):\n    print(i, value)\n# filter() -> Filtrar elementos de una secuencia iterable que determina si cada elemento debe mantenerse o no en el resultado\nprint(list(filter(lambda x: x > 0, [3, 0, 1, 2]))) \n# float() -> Converrtir un número o una cadena que representa un número en un número decimal\ncadena = \"3.14\"\nnum_float = float(cadena)\nprint(num_float + 5)\n# format() -> Formatea valores en una cadena de de manera más flexible y legible\nnombre = \"Alice\"\nedad = 30\nsaludo = \"Hola, {}. Tienes {} años.\".format(nombre, edad)\nprint(saludo)\n# frozenset() -> Creo conjunto cuyo elemento no puede ser modificado despues de su creacion\nlista = [1, 2, 3, 4]\nfset = frozenset(lista)\nprint(fset)\n# getattr() -> Obtener el valor de un atributo de un objeto\nclass MyClass:\n    a = 1\nobj = MyClass()\nprint(getattr(obj, 'a'))\n# globals() -> devuelve un diccionario que representa la tabla de simbolos global actual\nprint(globals())\n# hasattr() -> Comprobar si un objeto tiene un atributo con un nombre especifico\nclass MyClass:\n    a = 1\nobj = MyClass()\nprint(hasattr(obj, 'a'))\n# hash() - > Obtener el valor hash de un objeto, que es un numero entero que reprensenta de manera única el contenido del opbjeto\nprint(hash(\"hello\"))\n# hex() -> Muestra el valor de un número en hexadecimal\nprint(hex(10))\n# id() -> Devuelve un identificador unico para un objeto especifico durante su ciclo de vida \n# Muestra la dirección en memoria del objeto 1\nprint(id(1))  \n# input() -> Toma la entrada de un usuario desde la consola\n# name = input(\"Enter your name: \")\n# print(name)\n# int() -> Convierte un valor a entero\nprint(int(\"10\") + 10)\n# isinstance() -> Determinar si un objeto es de un tipo específico antes de realizar ciertas operaciones\nprint(isinstance(1, int)) \n# issubclase() -> Comprueba si una clase es una sublcase de otra clase\nclass A:\n    pass\nclass B(A):\n    pass\nprint(issubclass(B, A))\n# iter() -> Obtener un iterador de un objeto iterable\nit = iter([1,2,3])\nprint(next(it))\nprint(next(it))\n# len() -> Obtener la longitud de un objeto\nprint(len([1, 2, 3]))  # 3\n# list() -> Crea una lista\nl = list([1,2,3])\nprint(l)\n# locals() -> Devuelve un diccionario que representa la tabla de simbolos local actual\ndef func():\n    a = 1\n    print(locals())\nfunc()\n# map() -> Aplicar una funcion a cada elemento de un iterable y devolver un map object(iterador) con los resultados\ndef doblar(n):\n    return n * 2\nnumeros = [1, 2, 3, 4, 5]\nresultado = map(doblar, numeros)\nprint(list(resultado))\n# max() -> Encontrar el valor maximo en un iterable o entre dos o argumentos\nprint(max(1,2,3))\n# memoryview() -> Devuelve un objeto de vista de memoria que permite acceder a los datos subyacentes \ndatos = b\"Hola, mundo\"\nvista = memoryview(datos)\nprint(vista)  # Salida: <memory at 0x7f83b40c7f40>\n# min() -> Encontrar el valor minimo de un iterable o entre dos o mas argumentos\nprint(min(1,2,3))\n# next() -> Obtener el siguiente elemento de un iterador\nlista = [1, 2, 3, 4]\niterador = iter(lista)\nprint(next(iterador))\nprint(next(iterador))  \nprint(next(iterador)) \nprint(next(iterador))  \n# object() -> Crear una nueva instancia base de un objeto\nobj = object()\nprint(obj)\n# oct -> Convertir un número entero en su representacion octal como una cadena\nprint(oct(8))\n# open() -> Abrir un archivo y devolver un objeto de archivo\n# archivo = open('archivo.txt', 'r')\n# contenido = archivo.read()\n# print(contenido)\n# archivo.close()\n\n# ord() -> Obtener el valor unicode de un caracter\nprint(ord('a'))\n# pow () -> Calcular la potencia de un numero\nprint(pow(2,5))\n# print() -> Enviar datos a la salida estandar\nprint(\"Hello, World!\")\n# property() -> Crear y gestionar atributos de una clase de manera controlada\nclass MyClass:\n    def __init__(self):\n        self._x = None\n\n    @property\n    def x(self):\n        return self._x\n\n    @x.setter\n    def x(self, value):\n        self._x = value\n\nobj = MyClass()\nobj.x = 5\nprint(obj.x)  # 5\n# range() -> Generar una secuencia de numeros\nfor rango in range(1, 5):\n    print(rango)\n# repr() -> Obtener una representacion de cadena oficial de un objeto\nprint(repr(\"Helo, World!\"))\n# reversed() -> Devolver un iterador que accede a los elementos de una secuencia en orden inverso\nlista = [1, 2, 3, 4, 5]\nlista_invertida = list(reversed(lista))\nprint(lista_invertida)\n# round() - > Redondear un número al número de digitos especificado\nprint(round(4.2353453445,3))\n# set() -> Crear un conjunto, que es la coleccion desordenada de elementos unicos\ns = set([1,2,2,4])\nprint(s)\n# slice() -> Crear un objeto de segmento que se puede utilizar para extraer una parte especifica de una secuencia\nlista = [3, 3, 6, 4, 6, 9, 3, 6, 6, 11]\nsegmento = slice(3, 8, 2)\nprint(lista[segmento])\n# sorted() ->  Devolver una nueva lista con los elementos de un iterable ordenados\nlista = [3,1,2,4,7]\nprint(sorted(lista))\n# staticmethod() -> Definir un metodo estatico dentro de una clase\nclass MyClass:\n    @staticmethod\n    def static_method():\n        print(\"Static method called\")\n\nMyClass.static_method()\n# str() -> Convertir un objeto en una cadena de texto\nprint(str(123))\n# sum() -> Sumar los elementos y devolver un resultado\nsuma = [1,2,3,4]\nprint(sum(suma))\n# super() -> llamar a metodos de una superclase desde una subclase\nclass A:\n    def __init__(self):\n        print(\"A\")\nclass B(A):\n    def __init__(self):\n        super().__init__()\n        print(\"B\")\nb = B()  # A B\n# tuple() -> Crear una tupla\nt = tuple([1,2,3])\nprint(t)\n# type() -> Determinar el tipo de dato de un objeto o para crear un nuevo tipo de objeto\nprint(type(\"Hola\"))\n# zip() -> Combinar varios iterables en un solo iterable\nprint(list(zip([1, 2], ['a', 'b'])))  # [(1, 'a'), (2, 'b')]\n\n\n\n# ------------------------ VARIABLES LOCALES Y GLOBALES ----------------------------\n\n# Definir una variable global\nx = 10\n\ndef funcion_global():\n    # Acceder a la variable global\n    global x\n    print(\"Dentro de la función global, antes de cambiar: x =\", x)\n    \n    # Modificar la variable global\n    x = 20\n    print(\"Dentro de la función global, después de cambiar: x =\", x)\n\ndef funcion_local():\n    # Definir una variable local con el mismo nombre\n    x = 30\n    print(\"Dentro de la función local: x =\", x)\n\n# Mostrar el valor de la variable global antes de llamar a las funciones\nprint(\"\\n\\nAntes de llamar a las funciones: x =\", x)\n\n# Llamar a la función que modifica la variable global\nfuncion_global()\n\n# Mostrar el valor de la variable global después de modificarla\nprint(\"Después de llamar a la función global: x =\", x)\n\n# Llamar a la función que define una variable local\nfuncion_local()\n\n# Mostrar el valor de la variable global después de la función local\nprint(\"Después de llamar a la función local: x =\", x)\n\n\n\n# ------------------ EJERCICIO EXTRA ---------------------------------\n\n'''Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\nSi el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\nSi el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\nSi el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\nLa función retorna el número de veces que se ha impreso el número en lugar de los textos. '''\n\n\n\ndef extra(cad1, cad2):\n    contador = 0\n    for i in range(1,101):\n        if i % 3 == 0:\n            print(cad1)\n        \n        elif i % 5 == 0: \n            print(cad2)\n        \n        elif i % 3 and i % 5 == 0:\n            print(cad1 + cad2)\n        else:\n            print(i)\n            contador += 1\n    \n    return contador\n\n# Ejemplo de uso\ncadena1 = \"Hola\"\ncadena2 = \"Zerek\"\nresultado = extra(cadena1, cadena2)\nprint(f\"El número se imprimió {resultado} veces en lugar de los textos.\")\n\n\n\n            \n\n\n\n\n\n\n\n\n\n    \n    "
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/Zzepu.py",
    "content": "\"\"\"\nFunciones creadas por usuario\n\"\"\"\n\n# Simple\n\ndef piloto():\n    print('Hamilton')\n\npiloto()\n\n\n# Con retorno\n\ndef auto():\n    return 'Ferrari'\n\n# autito = auto()\n# print(autito)\n\nprint(auto())\n\n\n# Con un argumento\n\ndef arg_pilot(name):\n    print(f'El mejor piloto de la historia es {name}')\n\narg_pilot('Fangio')\n\n\n# Mas de un argumento\n\ndef args_pilot(car, name):\n    print(f'{car}, {name}')\n\nargs_pilot('Red Bull', 'Verstappen')\n\n\n# Con un valor predeterminado\n\ndef default_arg_pilot(name='Leclerc'):\n    print(f'Hi {name}!')\n\ndefault_arg_pilot()\n\n\n# Con argumentos y return\n\ndef return_args_pilot(car, pilot):\n    return f'{car}, {pilot}'\n\nprint(return_args_pilot('McLaren', 'Norris'))\n\n# Con retorno de varios valores\n\ndef multiple_return_team():\n    return 'Alpha Tauri', 'Tsunoda'\n\nteam, pilot = multiple_return_team()\nprint(team)\nprint(pilot)\n\n\n# Con un numero variable de argumentos\n\ndef variable_arg_team(*names):\n    for name in names:\n        print(f'Hola {name}!')\n\nvariable_arg_team('Red Bull', 'Ferrari', 'Mercedes')\n\n\n# Con un numero variable de argumentos con palabra clave\n\ndef variable_key_arg_teams(**names):\n    for key, value in names.items():\n        print(f'{key} ({value})')\n\nvariable_key_arg_teams(\n    car = 'W15',\n    pilot = 'Hamilton',\n    age = 35,\n    alias = 'GOAT'\n)\n\n\n\"\"\"\nFunciones dentro de funciones wtf?\n\"\"\"\n\ndef outer_function():\n    def inner_function():\n        print('Hola Python!')\n    inner_function()\n\nouter_function()\n\n\"\"\"\nFunciones del propio lenguaje (built-in functions)\n\"\"\"\n\nprint(len('Ferrari'))\nprint(type(44))\n\n\n\"\"\"\nVariables globales y locales\n\"\"\"\n\nglobal_var = 'Lewis'\n\ndef hello_drive():\n    local_var = 'Hamilton'\n    print(f'{global_var} {local_var}!')\n\nprint(global_var)\n#print(local_var) No se puede llamar por fuera de la funcion\n\nhello_drive()\n\n\n\"\"\"\nEjercicio extra!\n\"\"\"\n\ndef crazy_numbers(text1, text2):\n    count = 0\n    for num in range(1, 101):\n        if num % 3 == 0 and num % 5 == 0:\n            print(f'{text1} {text2}')\n        elif num % 3 == 0:\n            print(text1)\n        elif num % 5 == 0:\n            print(text2)\n        else:\n            print(num)\n            count += 1\n    return count\n\nprint(crazy_numbers('Lionel', 'Messi'))\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/a-mayans.py",
    "content": "# Una función te permite definir un bloque de código reutilizable que se puede ejecutar muchas veces dentro de tu programa.\n\n# función simple\ndef funcion_simple():\n    print('Soy una función simple')\n\nfuncion_simple()\n\n# función con parámetro\ndef funcion_parametro(lenguaje):\n    print(f'Estoy programando con {lenguaje}')\n\nfuncion_parametro('Python')\n\n# función con varios parámetros\ndef funcion_parametro(nombre, lenguaje):\n    print(f'Hola, me llamo {nombre} y estoy programando con {lenguaje}')\n\nfuncion_parametro('Alex','Python')\n\n# función con parámetros por defecto\ndef funcion_parametros_defecto(coche = 'Ferrari', color = 'rojo'):\n    print(f'El {coche} es {color}')\n\nfuncion_parametros_defecto() # devuelve el print con los valores por defecto si no se le indica lo contrario\nfuncion_parametros_defecto('Lambo') # devuelve el print: El lambo es rojo (hemos cambiado el primer valor, el segundo sigue por defecto)\n\n# función con retorno sin parámetros\ndef funcion_retorno():\n    mensaje = 'Bienvenidos'\n    return mensaje\n\nprint(funcion_retorno())\n\n# función con retorno con parámetros\ndef funcion_retorno_parametros(a, b):\n    resultado = a + b\n    return resultado\n\nprint(funcion_retorno_parametros(20,7))\n\n# función anónima o Lambda\nsuma = lambda x, y: x + y\nprint(suma(2,3))\n\n# función recursiva\ndef factorial(numero):\n    if numero == 0 or numero == 1:\n        return 1\n    else:\n        return numero * factorial(numero - 1)\n\nprint(factorial(7))\n\n# función con argumentos\ndef suma_con_args(*args):\n    return sum(args)\n\nresultado = suma_con_args(1, 2, 3, 4)\nprint(resultado)  # devuelve: 10\n\n\n# Funciones dentro de funciones\ndef funcion_externa(a):\n    def funcion_interna_multiplicacion(b):\n        return b * 5\n    \n    resultado = funcion_interna_multiplicacion(a)\n\n    return resultado\n\nprint(funcion_externa(5))\n\n\n# Funciones ya creadas en el lenguaje\n\n# max() --> Devuelve el elemento más grande en un iterable o el más grande de dos o más argumentos\nlista = [2,5,27,3,45]\nprint(max(lista))\n\n# len() --> Este método devuelve la longitud (el número de elementos) de un objeto. Toma un argumento x\npalabra = 'Esternocleidomastoideo'\nprint(len(palabra))\n\n\n# Variables locales: Son aquellas que se definen dentro de una función y solo son accesibles dentro de esa función\ndef funcion_local():\n    variable_local = 10\n    print(variable_local)\n\nfuncion_local()\n# print(variable_local) --> da un error porque desde fuera la variable no es accesible\n\n# Variables globales: Son aquellas que se definen fuera de cualquier función o bloque de código y son accesibles en todo el programa\n# Pueden ser utilizadas tanto dentro como fuera de las funciones\n# Se declaran con la palabra clave global dentro de una función si se desea modificar su valor\nvariable_global = 50\n\ndef funcion_global():\n    print(variable_global)\n\nfuncion_global()\nprint(variable_global) # no da error porque es accesible desde cualquier parte del código\n\ndef modificar_global():\n    global variable_global\n    variable_global = 20\n\nmodificar_global()\nprint(variable_global)\n\n\"\"\" * EJERCICIO:\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\"\"\"\n\ndef funcion_extra(texto1, texto2):\n    veces_impreso = 0\n    for num in range(1, 101):\n        if num % 3 == 0 and num % 5 == 0:\n            print(texto1 + '' + texto2)\n        elif num % 3 == 0:\n            print(texto1)\n        elif num % 5 == 0:\n            print(texto2)\n        else:\n            print(num)\n            veces_impreso += 1\n\n    return f'El numero de veces quue se a impreso el numero son: {veces_impreso}'\n\nprint(funcion_extra('Hola','Adios'))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/abascal92.py",
    "content": "'''\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n '''\n\n# Funciones básicas\ndef funcion_basica():\n    print(\"Función básica sin parámetros ni retorno.\")\n\ndef funcio_con_parametro(nombre, apellido):\n    print(f\"Función con parámetros: param1 = {nombre}, param2 = {apellido}.\")\n\ndef funcion_con_retorno():\n    return \"Devuelve un valor.\"\n\ndef funcion_con_parametros_retorno(number1, number2):\n    return number1 * number2\n\ndef funcion_parametros_opcional(nombre, apellido, apodo = \"'Sin apodoo'\"):\n    print(f\"Función con parámetros opcionales: param1 = {nombre}, param2 = {apellido}, param3 = {apodo}.\")\n\n\n# Funciones dentro de funciones\ndef funcion_padre():\n    def funcion_Hijo():\n        print(\"Función hija.\")\n    print(\"Función padre.\")\n    funcion_Hijo()\n\n# Variable LOCAL y GLOBAL\nvar_global = \"Soy una variable global.\"\n\ndef funcio_global_local():\n    var_local = \"Soy una variable local.\"\n    print(var_global)\n    print(var_local)\n#print(var_local); # Da error porque la variable no está definida en este áambito.\n\nfuncion_basica()\nfuncio_con_parametro(\"Alejandro\", \"Abascal\")\nprint(funcion_con_retorno())\nprint(funcion_con_parametros_retorno(23, 10))\nfuncion_parametros_opcional(\"Alejandro\", \"Abascal\")\nfuncion_padre()\nfuncio_global_local()\n\n\n# DIFICULTAD EXTRA\n\ndef dificultad_extra(texto1, texto2):\n    contador = 0\n    for i in range(1, 100):\n        if(i % 3 == 0 and i % 5 == 0):\n            print(f\"{texto1} {texto2}\")\n        elif (i%3 == 0):\n            print(texto1)\n        elif (i%5 == 0):\n            print(texto2)\n        else:\n            print(i)\n            contador += 1\n    return f\"\\nSe ha impreso el número {contador} veces.\"\n\nprint(dificultad_extra(\"Alejandro\", \"Abascal\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/adolfolozaa.py",
    "content": "'''\r\n/*\r\n * EJERCICIO:\r\n * - Crea ejemplos de funciones básicas que representen las diferentes\r\n *   posibilidades del lenguaje:\r\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\r\n * - Comprueba si puedes crear funciones dentro de funciones.\r\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\r\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\r\n * - Debes hacer print por consola del resultado de todos los ejemplos.\r\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\r\n *\r\n * DIFICULTAD EXTRA (opcional):\r\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\r\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\r\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\r\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\r\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\r\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\r\n *\r\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\r\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\r\n */\r\n'''\r\n\"\"\"\r\nFunciones definidas por el usuario\r\n\"\"\"\r\n\r\n# Simple\r\n\r\ndef saludos():\r\n    print(\"Hola Amigos!!!\")\r\n\r\nsaludos()\r\n\r\n# Con retorno\r\n\r\ndef retorno_saludo():\r\n    return \"Hola Python!!!\"\r\n\r\nprint(retorno_saludo())\r\n\r\n# Con argumentos\r\n\r\ndef args_greet(greet, name):\r\n    print(f\"{greet}, {name}!!!\")\r\n\r\nargs_greet(\"Hola\", \"Adolfo\")\r\nargs_greet(name=\"Gaby\", greet='Buen dia')\r\n\r\n# Con argumento predeterminado\r\n\r\ndef arg_greet(name= 'ADOLFO'):\r\n    print(f\"{name}!!!\")\r\n\r\narg_greet(\"Adolfo\")\r\narg_greet()\r\n\r\n\r\n# Con argumentos y retorno\r\ndef args_greet(greet, name):\r\n    return f\"{greet}, {name}!!!\"\r\n\r\nprint(args_greet(\"Hi\", \"Francisco\"))\r\n\r\n# con retorno de varios valores\r\n\r\ndef multiple_return_greet():\r\n    return \"Hola\", \"Python\"\r\n\r\ngreet, name = multiple_return_greet()\r\nprint(greet)\r\nprint(name)\r\n\r\n# con un numero variable de argumentos\r\n\r\ndef variable_arg_greet(*names):\r\n    for name in names:\r\n        print(f\"Hola, {name}!!!\")\r\n\r\nvariable_arg_greet(\"rojo\", 'azul', \"verde\", \"blanco\")\r\n\r\n# con numer variable de argumentos con palabra clave\r\n\r\ndef variable_key_arg_greet(**names):\r\n    for key, value in names.items():\r\n        print(f\"{value} ({key})!!!\")\r\n\r\nvariable_key_arg_greet(\r\n    language = \"Python\",\r\n    name = \"Adolfo\",\r\n    alias = \"ALA\",\r\n    age = 56\r\n)\r\n\r\nvariable_key_arg_greet()\r\n\r\n\"\"\"\r\nFunciones dentro de funciones\r\n\"\"\"\r\n\r\ndef outer_function():\r\n    def inner_function():\r\n        print(\"Funcion interna: Hola, Python\")\r\n    inner_function()\r\nouter_function()\r\n\r\n\"\"\"\r\nFunciones del lenguaje (built-in)\r\n\"\"\"\r\n\r\nprint('Tamano de la palabra: ' + str(len('Adolfo')) + ' letras')\r\nprint(type(\"Adolfo\"))\r\nprint\r\n(\"Adolfo Loza\".upper())\r\n\r\n\"\"\"\r\nVariables locales y globales\r\n\"\"\"\r\n# Globales\r\nglobal_var = \"python\"\r\n\r\nprint(global_var)\r\n\r\ndef hello_python():\r\n    local_var = 'Hola'\r\n    print(f\"{local_var}, {global_var}!!!\")\r\n\r\nhello_python()\r\n#print(local_var) no se puede acceder desde fuera de la funcion\r\n\r\n\"\"\"\r\nDificultad Extra\r\nCrea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\r\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\r\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\r\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\r\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\r\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\r\n *\r\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\r\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\r\n\"\"\"\r\n\r\ndef print_numbers(texto_1, texto_2) -> int:\r\n    counter = 0\r\n    for number in range(0,101):\r\n        if number % 3 == 0 and number % 5 == 0:\r\n            print(texto_1 +' '+ texto_2)\r\n        elif number % 3 == 0:\r\n            print(texto_1)\r\n        elif number % 5 == 0:\r\n            print(texto_2)\r\n        else:\r\n            print(number)\r\n            counter += 1\r\n    return counter\r\n            \r\nprint(print_numbers('Fizz', 'Buzz'))\r\n\r\n\r\n\r\n\r\n\r\n\r\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/adra-dev.py",
    "content": "\"\"\"\nEJERCICIO:\n- Crea ejemplos de funciones basicas que representen las diferentes\nposibilidades del lenguaje:\nSin parametros ni retorno, con uno o vario parametros, con retorno...\n- Comprueba si puedes crear funciones dentro de funciones.\n- Utiliza algun ejemplo de funciones ya creadas en el lenguaje.\n- Pon a prueba el cocepto de variable LOCAL Y GOBAL.\n- Debes hacer print por consola del resultado de todos los ejemplos.\n(y tener en cuenta que cada lenguaje puede poseer mas o menos \nposibilidades)\n\nDIFICULTAD EXTRA (opcional):\n- Crea una funcion que reciba dos parametros de tipo cadena de texto,\ny retorne un numero.\n- La funcion imprime todos los numeros del 1 al 100. Teniendo en\ncuenta que:\n- Si el numero es multiplo de 3, muestra la cadena de texto del \nprimer parametro.\n- Si el numero es multiplo de 5, muestra la cadena de texto del \nsegundo parametro \n- Si el numero es multiplo de 3 y de 5, muestra las dos cadenas de \ntexto concatenadas.\n- La funcion retorna el numero de veces que se ha impreso el numero\nen lugar de los texto.\n\n- Presta especial atención a la sintaxis que debes utilizar en cada \nuno de los casos.\n- Cada lenguaje sigue una convenciones que debes de respetar para que \nel código se entienda.\n\nby adra-dev.\n\"\"\"\n\n\"\"\"\nFunciones: Las funciones son pequeños programas, con una entrada de \ndatos sobre la cual se generara una salida. Tradicionalmente \ndenominadas <<Subrutinas>>.\n\"\"\"\n\n# Funcion sin parametros ni retorno\n\ndef my_function():\n    pass\n\nprint(my_function())\n\n# Funcion con uno o varios parametros\n\ndef bigger_than(a, b):\n    if a > b:\n        pass\n    pass\n\nprint(bigger_than(9, 8))\n\n# Funcion con retorno\n\ndef less_than(a, b):\n    if a < b:\n        return a\n    return b \n\nprint(less_than(5,9))\n\n\"\"\"\nAnidacion: \n    La anidacion hace referncia tanto a la declaracion de una funcion\n    dentro del cuerpo de otra, como a la llamada a una funcion a\n    partir de los resultados de otra.\n\n    La usaremos cuando definir una funcion fuera de otra no tiene \n    sentido, es decir, cuando la funcion interna solo va a ser \n    utilizada por la funcion externa. Una funcion interna solo es \n    visible en el ambito de la funcion que la aloja.\n\"\"\"\n\ndef check_items(items):\n\n    def dump(item):\n        print('The item', item, 'is nots valid')\n    \n    for i,x in enumerate(items):\n        if x > 100:\n            dump(i)\n\ncheck_items([96, 98, 102, 99])\n\n\"\"\"\nBuilt-in functions o funciones predefinidas del lenguaje:\n    Son funciones ya creadas dentro del lenguaje y que siempre estan \n    disponibles cuando las necesitemos, puedes checarlas todas en la\n    url: (https://docs.python.org/3/library/functions.html).\n\"\"\"\na = [1, 2, 3, 4, 5, 6]\nprint(sum(a)) # la funcion sum, suma los elementos dentro un iterable.\n\n\"\"\"\nAmbito o Scope:\n    El ambito de una variagle es el contexto en el cual la variable\n    es conocida. Las varaibles que se definen en el cuerpo de una \n    funcion son variables locales, mientrasque las que se definen a\n    lo largo del programa son variables globales.\n\"\"\"\n\n# Scope\nanimal = 'leon' # Variable Global -> Funciones, condiciones, ciclos\n\ndef imprimir_animal():\n    animal = 'Ballena' # Variable Local\n\n    print(animal)\n    print(id(animal))\n\n\nimprimir_animal()\n\nprint(animal)\nprint(id(animal))\n\n\n\"\"\"\nExtra\n\"\"\"\n\ndef fizz_buzz(str1 =\"fizz\", str2 =\"buzz\"):\n    count = 0\n    for number in range(1, 101):\n        if number % 3 == 0 and number % 5 == 0 :\n            print(str1 + \" \" + str2)\n        elif number % 3 == 0:\n            print(str1)\n        elif number % 5 == 0:\n            print(str2)\n        else:\n            print(number)\n            count += 1\n    return print(\"El numero total de veces que se ha impreso el numero es:\", count)\n\nfizz_buzz('Hello', 'there')"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/agusrosero.py",
    "content": "#### Funciones\ndef saludar():\n    print(\"Hola Mundo!\")\n\nsaludar()\n    \ndef saludar2(nombre):\n    print(\"Hola\", nombre)\n    \nsaludar2(\"Hernan\")\n\ndef suma(a, b):\n    return a + b\n\nprint(suma(2, 3))\n\ndef funcion_anidada():\n    print(\"Esto es una funcion anidada\")\n    \n    def funcion_anidada2():\n        print(\"Esto es una funcion anidada 2\")\n        \n    funcion_anidada2()\n    \nfuncion_anidada()\n\n## Variables locales y globales en funciones\n\ndef variable_local():\n    variable_local = \"Valor variable local\"\n    print(variable_local)\n    \nvariable_local()\n\nvariable_global = \"Valor variable global\"\n\ndef variable_global():\n    global variable_global\n    variable_global = \"Nuevo valor variable global\"\n    print(variable_global)\n    \nvariable_global()\n\n## Ejercicio Extra\ndef extra(texto1, texto2):\n    contador = 0\n    \n    for i in range(1, 101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(f\"{texto1}{texto2}\")\n        elif i % 3 == 0:\n            print(texto1)\n        elif i % 5 == 0:\n            print(texto2)\n        else:\n            print(i)\n            contador += 1\n            \n    return contador\n\nprint(extra(\"Python\", \"Django\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/ainaragmt.py",
    "content": "# Función simple\nprint(\"\\nFunción simple\")\ndef greet():\n    print(\"Hello!\")\n\ngreet()\n\n# Función con retorno\nprint(\"\\nFunción con retorno\")\ndef greet_return():\n    return \"Hello with return!\"\n\nargs = greet_return()\nprint(args) # or print(greet_return())\n\n# Función con argumento\nprint(\"\\nFunción con argumento\")\ndef greet_args(args):\n    print(args)\n\ngreet_args(\"Hello with args!\")\n\n# Función con argumento definido\nprint(\"\\nFunción con argumento definido\")\ndef greet_args_default(args = \"Hello with default args!\"):\n    print(args)\n\ngreet_args_default()\ngreet_args_default(\"Hello again.\")\n\n# Función con argumento y retorno\nprint(\"\\nFunción con argumento y retorno\")\ndef greet_args_return(args):\n    return \"Hello with args and return, \"+ args + \"!\"\n\nprint(greet_args_return(\"Python\"))\n\n# Función con retorno de varios valores\nprint(\"\\nFunción con retorno de varios valores\")\ndef greet_multiple_return():\n    return \"Hello \", \"with \", \"multiple \", \"return!\"\n\na, b, c, d = greet_multiple_return()\nprint(a + b + c + d)\n\n# Función con número variable de argumentos\nprint(\"\\nFunción con número variable de argumentos\")\ndef greet_variable_args(*args):\n    for name in args:\n        print(f\"Hello {name}\")\n\ngreet_variable_args(\"Python \", \"C \", \"Java \")\n\n# Función con número variable de argumentos con palabra clave\nprint(\"\\nFunción con número variable de argumentos con palabra clave\")\ndef greet_variable_args_key(**args):\n    for key, name in args.items():\n        print(f\"Hello {name} ({key})\")\n\ngreet_variable_args_key(language1 = \"Python\", language2 = \"C\", language3 = \"Java\")\n\n# Funciones dentro de funciones\nprint(\"\\nFunciones dentro de funciones\")\ndef outer_function():\n    print(\"I'm in the outer function.\")\n    def inner_function():\n        print(\"I'm in the inner function.\")\n    inner_function() # Sin está llamada inner_function no se ejecuta\n\nouter_function()\n\n# Funciones built-in\nprint(\"\\nFunciones built-in\")\nprint(len(\"Hello\")) # length\nprint(type(\"Hello\")) # class\nprint(\"Hello\".upper()) # uppercase\nprint(int(\"10\")) # convert to int\nprint(max([1, 5, 3]))\nprint(round(3.14159, 2)) # round with 2 decimals\nprint(list(range(5))) # list from 0 to 4\nprint(ord('A')) # char to unicode\nprint(chr(65)) # unicode to char\nprint(list(\"Hello\")) # ['H', 'e', 'l', 'l', 'o']\nprint(set([1, 2, 2, 3])) # {1, 2, 3}: deletes repeated numbers\n\n# Variables locales y globales\nprint(\"\\nVariables locales y globales\")\n\nglobal_variable = \"Global variable\" # outside of the function\n\ndef local():\n    local_variable = \"Local variable\"\n\ndef hello_python():\n    print(\"Hello \" + global_variable.lower())\n    # print(\"Hello \" + local_variable.lower()) # error: cannot be accessed from outside the function\n\nhello_python()\n\n'''\nCrea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n'''\nprint(\"\\nEjercicio de dificultad extra\")\n\ndef funct(param1,param2):\n    number = 0\n    for i in range(1, 101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(param1+param2)\n        elif i % 3 == 0:\n            print(param1)\n        elif i % 5 == 0:\n            print(param2)\n        else:\n            print(i)\n            number += 1\n    return number\n\nprint(funct(\"tres\",\"cinco\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/alanshakir.py",
    "content": "#funciones basicas \ndef suma_sin_parametros_retorno(): \n    print(\"funcion solo imprime en consola sin parametros\")\n\ndef suma_con_parametros_retorno(num1, num2): \n    print(\"funcion solo imprime en consola con parametros\", num1,\"y\", num2)\n\ndef suma_sin_parametros():\n    return 3 + 4\n\ndef suma_con_parametros(num1, num2):\n    return num1 + num2\n\n#funcion upper creada en el lenguaje\ndef string_upper(word):\n    new_string = str(word).upper() #upper convierte la cadena en mayuscula\n    print(new_string)\n\n#funciones dentro de funciones\ndef my_function1():\n    def my_function2():\n        print(\"estudiando con mouredev\")    \n    my_function2()    \n    print(\"y pyhton\")\n\n#variable GLOBAL\nmy_variable_global = 20\ndef funcion_variable_global_local():\n    my_variable_local = 10 # variable local\n    return my_variable_global + my_variable_local\n\n# ejemplo opcional\ndef devolver_numero_del_string(my_string, my_other_string):\n    for index in range(1, 101):\n        if index % 3 == 0 and index % 5 == 0:\n            print(f\"las cadenas se concatenan {my_string} {my_other_string}\")\n        elif index % 3 == 0:\n            print(f\"la primera cadena es: {my_string}\")\n        elif index % 5 == 0:\n            print(f\"la segunda cadena es: {my_other_string}\")\n\n\nsuma_sin_parametros_retorno()\nsuma_con_parametros_retorno(2, 4)\nprint(suma_sin_parametros())\nprint(suma_con_parametros(8, 7))\nstring_upper(\"alan Ramirez\")\nmy_function1()\nprint(funcion_variable_global_local())\nprint(devolver_numero_del_string(\"alan\", \"ramirez\"))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/alberba.py",
    "content": "\n# Función básica sin retorno\ndef funcion_basica():\n    pass\n\n# Función básica con retorno\ndef funcion_basica_con_retorno():\n    return 5\n\n# Función con parámetros \ndef funcion_con_parametros(string: str, string2:str) -> str:\n    return string + string2\n\ndef funcion_dentro_de_funcion():\n    def inside_function():\n        pass\n\n    inside_function()\n\n# Dificultad extra\ndef extra(string: str, string2: str) -> int:\n    count = 0\n    for i in range (1, 101):\n        salida = \"\"\n        if (i % 3 == 0):\n            salida += string\n        if (i % 5 == 0):\n            salida += string\n        if salida == \"\":\n            print(i)\n            count += 1\n        else:\n            print(salida)\n    \n    return count\n\nprint(extra(\"Hola\", \"Mundo\"))\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/albertorevel.py",
    "content": "# @author Alberto Revel\n\n\"\"\"\n  - Crea ejemplos de funciones básicas que representen las diferentes\n    posibilidades del lenguaje:\n    Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n\"\"\"\nprint(\"\\n**** PART 1 - FUNCTIONS ****\\n\")\n\ndef no_params_no_return_void_function():\n    pass\n\ndef no_params_no_return():\n    print(\"function no_params_no_return()\")\n\ndef no_params_return():\n    print(\"function no_params_return(): returns 'result'\")\n    return \"result\"\n\ndef params_return(x,y):\n    result=x+y\n    print(f\"function params_return(x,y): returns {result}\")\n    return result\n\n\ndef arbitrary_params(*elements):\n    result=sum(element for element in elements)\n    print(f\"arbitrary_params(*elements): returns {result}\")\n    return result\n\ndef keywords_params(dividend, divisor):\n    result=dividend/divisor\n    print(f\"keywords_params(dividend, divisor): returns {result}\")\n    return result\n\ndef keyword_arbitrary_params(**elements):\n    result = 0\n    if (\"dividend\" in elements and \"divisor\" in elements):\n      result = elements[\"dividend\"]/elements[\"divisor\"]\n    print(f\"keyword_arbitrary_params(**elements): returns {result}\")\n    return result\n\ndef default_value(name=\"Mickey\"):\n    print(f\"function default_value(name='Mickey'): param = {name}\")\n\ndef list_value(brands):\n    print(\"function list_value(brands)\")\n    for brand in brands:\n        print(f\" - {brand}\")\n\ndef positional_only_arguments(x, y, /):\n    result = x * y\n    print(f\"function positional_only_arguments(x, y, /): returns {result}\")\n    return x * y\n\ndef keyword_only_arguments(*, x, y):\n    result = x * y\n    print(f\"function keyword_only_arguments(*, x, y): returns {result}\")\n    return result\n    \ndef keyword_only_positional_only_and_arguments(x, y, /, *, a, b):\n    result = f\"positional : {str(x*y)} ... keyword: {str(a*b)}\"\n    print(f\"function positional_only_arguments(x, y, /): returns {result}\")\n    return result\n\n\ndef use_lambda_power_of_2(element):\n    lambda_func = lambda base: pow(2,base)\n    print(f\"lambda function: {lambda_func}\")\n    result = lambda_func(element)\n    print(f\"function use_lambda_power_of_2: result = {result}\" )\n    return result\n\ndef recursion_power(base,exponent):\n    print(f\"function recursion_power(base,exponent): params= ({base},{exponent})\")\n    if exponent == 0:\n      return 1\n    elif (exponent == 1):\n      return base\n    elif (exponent == -1):\n      return 1/base\n    else:\n        exponent -= 1 if exponent > 0 else -1\n        return recursion_power(base * base, exponent)\n\n# calling functions\n\nprint(\"\\ncalling no_params_no_return_void_function()\")\nno_params_no_return_void_function()\n\nprint(\"\\ncalling no_params_no_return()\")\nno_params_no_return()\n\nprint(\"\\ncalling params_return(5,9)\")\nprint(params_return(5,9))\n\nprint(\"\\ncalling arbitrary_params(1,2,3,4,5,6)\")\nprint(arbitrary_params(1,2,3,4,5,6))\n\nprint(\"\\ncalling keywords_params(divisor=1,dividend=0)\")\nprint(keywords_params(divisor=1,dividend=0))\n\nprint(\"\\ncalling keywords_params(divisor=1,dividend=0)\")\nprint(keywords_params(divisor=1,dividend=0))\n\nprint(\"\\ncalling keyword_arbitrary_params(divisor=1)\")\nprint(keyword_arbitrary_params(divisor=1))\n\nprint(\"\\ncalling default_value()\")\ndefault_value()\nprint(\"\\ncalling default_value('Pluto')\")\ndefault_value(\"Pluto\")\n\nprint(\"\\ncalling list_value('Apple','Samsung','Xiaomi')\")\nlist_value([\"Apple\",\"Samsung\",\"Xiaomi\"])\n\nprint(\"\\ncalling positional_only_arguments(5,9)\")\nprint(positional_only_arguments(5,9))\n\nprint(\"\\ncalling keyword_only_arguments(x=3,y=4)\")\nprint(keyword_only_arguments(x=3,y=4))\n\nprint(\"\\ncalling keyword_only_positional_only_and_arguments(5,9,a=3,b=4)\")\nprint(keyword_only_positional_only_and_arguments(5,9,a=3,b=4))\n\nprint(\"\\ncalling use_lambda_power_of_2(5))\")\nprint(use_lambda_power_of_2(5))\n\n\nprint(\"\\ncalling recursion_power(1,0)\")\nprint(recursion_power(1,0))\nprint(\"\\ncalling recursion_power(2,4)\")\nprint(recursion_power(2,4))\nprint(\"\\ncalling recursion_power(2,-2)\")\nprint(recursion_power(2,-2))\n\n\n\"\"\" - Comprueba si puedes crear funciones dentro de funciones.\"\"\"\nprint(\"\\n**** PART 2 - INNER FUNCTIONS ****\\n\")\n\ndef with_inner(a,b,c,d):\n    result=a+b\n    \n    def inner_function(c,d):\n        result=c+d\n        print(f\"function inner_function(c,d): returns {result}\")\n        return result\n    \n    result +=  inner_function(c,d)\n    print(f\"function with_inner(a,b,c,d): returns {result}\")\n    return result\n\nprint(\"\\ncalling with_inner(1,4,10,100) that contains an inner function\")\nprint(with_inner(1,4,10,100))\n\nprint(\"\\ninner function cannot be called directly: inner_function(10,100)\")\n\n# Inner function cannot be called: inner_function(1))\n\n\n\"\"\" - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\"\"\"\nprint(\"\\n**** PART 3 - BUILT-IN FUNCTIONS ****\\n\")\n\ndef slice_tuple_pairs_without_first(list):\n    slice_function=slice(1,len(list),2)\n    return list[slice_function]\nprint(slice_tuple_pairs_without_first(['banana','apple','orange','strawberry','pear','avocado','pineapple']))\nprint(f\"\\ncalling slice_tuple_pairs_without_first(['banana','apple','orange','strawberry','pear','avocado','pineapple'])\")\n\n\ndef sort_reverse_and_add(list,element):\n    list.append(element)\n    return sorted(list,reverse=1)\nprint(f\"\\ncalling sort_reverse_and_add(['banana','apple','orange','strawberry','pear','avocado','pineapple'],'peach')\")\nprint(sort_reverse_and_add(['banana','apple','orange','strawberry','pear','avocado','pineapple'],'peach'))\n\n\n\"\"\" - Pon a prueba el concepto de variable LOCAL y GLOBAL\"\"\"\nprint(\"\\n**** PART 4 - GLOBAL AND LOCAL SCOPES FOR VARIABLES ****\\n\")\n\nprint(\"setting global variable var1=1\")\nvar1=1\n\ndef sum_local_variables(element):\n    var1=3\n    result = var1+element\n    print(f\"function sum_local_variables: result = {result}\")\n    return result\n\ndef sum_global_variable(element):\n    result = var1+element\n    print(f\"function sum_global_variable: result = {result}\")\n\n    return result\n\ndef printing_local_variable():\n    var2=\"a\"\n    print(f\"function printing_local_variable: var2 = {var2}\")\n\nprint(\"\\ncalling sum_local_variables(10)\")\nsum_local_variables(10)\nprint(\"\\ncalling sum_global_variable(10)\")\nsum_global_variable(10)\n\nprint(\"\\ncalling printing_local_variable()\")\nprinting_local_variable()\nprint(\"\\nprinting local variable from printing_local_variable() doesn't compiles: print(var2)\")\n\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\"\"\"\nprint(\"\\n**** PART 5 - EXTRA FUNCTION ****\\n\")\n\ndef print_and_count(text1,text2):\n    counter = 0\n    for eachNumber in range(1,101):\n        result = ''\n        if(eachNumber % 3 == 0):\n            result += text1\n        if(eachNumber%5 == 0):\n            result += text2\n        if(len(result) == 0):\n            counter+=1\n            result=str(eachNumber)\n        print(result)\n    return counter\n\nprint(f\"Calling print_and_count('mul3','mul5'):\\n\")\nprint(f\"\\nresult = {print_and_count('mul3','mul5')}\")\n\nprint(\"\\n\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/alcaan16.py",
    "content": "\"\"\"\n* DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n\n *   - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n    *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n    *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n    *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\"\"\"\n\ndef funcion(var_1, var_2):\n\n    for i in range(1,101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(f\"el numero {i} es {var_1} y {var_2}\")\n        elif i % 3 == 0:\n            print(f\"el numero {i} es {var_1}\")\n        elif i % 5 == 0:\n            print(f\"el numero {i} es {var_2}\")\n\nfuncion (\"multiplo de 3\", \"multiplo de 5\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/alejo-digital.py",
    "content": "# 02 FUNCIONES Y ALCANCE\n\n\"\"\"\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n\"\"\"\n\n# Funcion sin parámetros ni retorno\ndef sin_parametros():\n    print(\"Hola, bienvenido a Python!\")\n\n# Funcion con un parámetro\ndef con_parametro(nombre):\n    print(f\"Hola, {nombre}!\")\n\n# Funcion con varios parámetros\ndef con_varios_parametros(nombre, edad):\n    print(f\"Hola, {nombre}, tienes {edad} años.\")\n\n# Funcion con retorno\ndef suma(a, b):\n    return a + b\n\n# Funcion dentro de otra función\ndef operacion_compuesta(x, y):\n    def elevar_al_cuadrado(n):\n        return n * n\n    suma = x + y\n    print(f\"El cuadrado de la suma entre\", x, \"y\", y, f\"es {elevar_al_cuadrado(suma)}\")\n\n# Función que utiliza variables globales y locales | con funciones del lenguaje\ncontador_global = 0\ndef funcion_con_variable_global():\n    global contador_global\n    contador_local = 0\n    for i in range(0, 5):\n        contador_local += 1\n        contador_global = contador_local * 2  # Modifica la variable global\n    print(f\"Contador local: {contador_local}, Contador global: {contador_global}\")\n\nsin_parametros()  # Llamada a la función sin parámetros\ncon_parametro(\"Alejandro\")  # Llamada a la función con un parámetro\ncon_varios_parametros(\"Alejandro\", 30)  # Llamada a la función con varios parámetros\nresultado = suma(10, 5)  # Llamada a la función con retorno\nprint(f\"La suma de 10 y 5 es: {resultado}\")  # Imprime el resultado de la suma\noperacion_compuesta(3, 4)  # Llamada a la función con operación compuesta\nfuncion_con_variable_global()  # Llamada a la función que utiliza variables globales\nprint(f\"la variable global es: {contador_global}\")  # Esto funcionará porque contador_global es global \n\n# DIFICULTAD EXTRA\ndef imprimir_numeros(param1, param2):\n    contador = 0\n    for i in range(1, 101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(param1 + param2)\n            contador += 1\n        elif i % 3 == 0:\n            print(param1)\n            contador += 1\n        elif i % 5 == 0:\n            print(param2)\n            contador += 1\n        else:\n            print(i)\n    return contador\n\n# Llamada a la función de dificultad extra\nresultado_extra = imprimir_numeros(\"Fizz\", \"Buzz\")\nprint(f\"Números impresos en lugar de textos: {resultado_extra}\")\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/alejomazov.py",
    "content": "def funcion_sinRetorno_sinParametros():\n    print (\"Esta funcion solo imprime en pantalla\")\n\nfuncion_sinRetorno_sinParametros()\n\ndef funcion_conParametros(x, y):\n    print(f\"Esta funcion recibe dos parametros y = {y} y x = {x}\")\n\nfuncion_conParametros(54, 62)\n\ndef funcion_parametros_retorno(x, y):\n    suma = x + y\n    print (f\"Esta funcion recibe parametro  y = {y} y x = {x} y retorna el resultado multiplicado por 2 \")\n    return (suma*2)\n\nsuma_x2 = funcion_parametros_retorno(32, 52)\nprint (suma_x2)\n\n\nnombre_global = \"Alejandro mazo\" # variable global\ndef primera_funcion ():\n    str_uno = \"Hola\" + \" \" #variable local\n\n    def segunda_funcion():\n        str_dos = \"mundo, mi nombre es \"\n        return str_uno+str_dos+nombre_global\n    print (segunda_funcion())\n\nprimera_funcion()\n\n\n## Difucltad extra \n\ndef dificultad_extra (buzz):\n    count = 0\n    for i in range(1,101):  \n        if i % 3 == 0 and i % 5 == 0:\n            print (fizz + buzz)\n\n        elif i % 3 == 0:\n            print (fizz)\n        \n        elif i % 5 == 0:\n            print (buzz)\n       \n        else:\n            print (i)\n            count += 1\n\n    return (count)\n        \nfizz = \"fizz\"\nprint(\"el número de veces que se ha impreso el número en lugar de los textos es: \", dificultad_extra(\"buzz\"))\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/alejosor.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n\"\"\"\n\n# Función sin parametros ni retorno\ndef mi_primera_funcion():\n    print(\"Holaa\")\n\nmi_primera_funcion()\n\n# Función con un parámetro\ndef mi_segunda_funcion(mensaje):\n    print(f\"Esta función imprime el mensaje: {mensaje}\")\n\nmi_segunda_funcion(\"Bienvenido a la comunidad\")\n\n# Función con varios parámetros\ndef mi_tercera_funcion(x,y,z):\n    print(f\"La sumatoria de {x}, {y} y {z} es {x+y+z}\")\n\nmi_tercera_funcion(1,2,3)\n\n# Función con retorno\ndef mi_cuarta_funcion(x,y):\n    multi = x*y\n    return multi\n\nmultiplicacion = mi_cuarta_funcion(5,4)\nprint(\"La multiplicación es:\",multiplicacion)\n\n# Comprueba si puedes crear funciones dentro de funciones\n# Utiliza algún ejemplo de funciones ya creadas en el lenguaje\n# Pon a prueba el concepto de variable LOCAL y GLOBAL\n\nmensaje_global = \"Hola desde la variable GLOBAL\"\n\ndef funcion_externa():\n    mensaje = \"Hola desde la funcion EXTERNA (variable LOCAL)\"\n    print(mensaje)\n\n    def funcion_interna():\n        print(\"Usando función interna:\")\n        print(mensaje.upper())\n    \n    funcion_interna()\n\nfuncion_externa()\nprint(\"Mensaje global fuera de la función:\", mensaje_global)\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n#  * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n#  *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n#  *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n#  *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n#  *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\nprint(\"\\n***** Extra *****\")\ndef extra(cadena1,cadena2):\n    contador = 0\n    \n    for num in range(1,101):\n        if num % 3 == 0 and num % 5 == 0:\n            print(cadena1 + cadena2)\n        elif num % 3 == 0:\n            print(cadena1)\n        elif num % 5 == 0:\n            print(cadena2)\n        else:\n            print(num)\n            contador += 1\n    \n    return contador\n\nrespuesta = extra(\"Fizz\", \"Buzz\")\nprint(f\"El total de veces que se imprimió el número en vez de los textos son: {respuesta}\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/alexdevrep.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n\"\"\"\n\n#Función sin parámetros ni retorno\ndef simpleFunction ():\n    print(\"Hola, Python\")\n\nsimpleFunction()\n\n#Función con un parámetro\ndef oneArg (Arg1):\n    print(Arg1)\n\noneArg(\"Hola, Alexdevrep\")\n\n#Función con varios parámetros\ndef manyArgs (día, mes, año):\n    print(\"Hoy es\"+\" \"+ día+\" \"+\"de\"+\" \"+mes+\" \"+\"del\"+\" \"+año)\n\nmanyArgs(\"10\",\"enero\",\"2024\")\n\n#Función con retorno\ndef retorno (a,b):\n    return a + b\n\nresultado = retorno(2,3)\nprint(resultado)\n\n#Funciones dentro de funciones\ndef funcionPadre(sum3):\n    def funcionHijo(sum1,sum2):\n        return sum1 + sum2\n    resultadoHijo = funcionHijo(1,2)\n    print(resultadoHijo + sum3)\nfuncionPadre(3)\n\n#Funciones ya creadas en el lenguaje\nprint(max(1,2,3,4,35)) #Max devuelve el valor máxnimo que hay dentro de una tupla, una lista, o un diccionario\n\n#Variable local\ndef resta():\n    rest1 = 5\n    print(rest1 -3)\n\nresta()\n\n#Variable global\nsumando = 8\ndef suma():\n    print (sumando + 10)\nsuma()\n\n#Dificultad extra\ndef extra (string1, string2):\n    numero = 0\n    i=1\n    for i in range (1,101):\n        if (i%3==0 and i%5==0):\n            print(string1+\" \"+string2)\n            continue\n        elif (i%3==0):\n            print(string1)\n            continue\n        elif (i%5==0):\n            print(string2)\n            continue\n        else:\n            print(i)\n        i=i+1\n        numero= numero +1\n    return numero\n     \nprint(\"Número de veces que se ha impreso el contador:\",extra(\"Hola Python\",\"Hola alexdevrep\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/allbertoMD.py",
    "content": "# Function Without Parameters\nprint(\"\\nFunction Without Parameters\")\ndef function_without_parametars():\n    print(\"I'm a function\")\nfunction_without_parametars()\n\n\n# Function With One Parameter\nprint(\"\\nFunction With One Parameter\")\ndef function_with_one_parameter(name):\n    print(f\"Hello, {name}\")\nfunction_with_one_parameter(\"Reggie\")\n\n\n# Function With Default Parameters\nprint(\"\\nFunction With Default Parameters\")\ndef function_with_default_parameters(name = \"Samantha\"):\n    print(f\"Hello, {name}\")\nfunction_with_default_parameters()\n\n\n# Function With Multiple Parameters\nprint(\"\\nFunction With Multiple Parameters\")\ndef function_with_multiple_parameters(name, age):\n    print(f\"{name} is {age} year old\")\nfunction_with_multiple_parameters(\"Carl\", 40)\n\n\n# Function With Return Value\nprint(\"\\nFunction With Return Value\")\ndef function_with_return_value(a, b) -> int:\n    return a * b\nreturn_value = function_with_return_value(20, 40)\nprint(return_value)\n\n    \n# Function With Variable Number of Parameters\nprint(\"\\nFunction With Variable Number of Parameters\")\ndef function_with_variable_number_of_parameters(*parameters):\n    print(parameters)\nfunction_with_variable_number_of_parameters(\"a\", \"e\", \"i\", \"o\", \"u\")\n\n\n## Funciton with Variable Parameters key Value\nprint(\"\\nFunciton with Variable Parameters key Value\")\ndef function_with_variable_key_value_parameters(**user_data):\n    for key, value in user_data.items():\n        print(f\"{key}: {value}\")\nfunction_with_variable_key_value_parameters(name=\"Tamy\", age=32, city=\"New York\")\n\n\n# Function Inside a Function\nprint(\"\\nFunction Inside a Function\")\ndef function_insede_the_function():\n    print(\"I'm a main function.\")\n    def second_function():\n        print(\"I'm a function inside other function\")\n    second_function()    \nfunction_insede_the_function()\n\n\n# Function With Function as Parameter\nprint(\"\\nFunction With Function as Parameter\")\ndef function_with_function_as_parameter(function, a, b):\n    print(function(a, b))\nfunction_with_function_as_parameter(lambda  a, b: a + b, 4, 10)\n\n\n# Sistem Function\nprint(\"\\nSistem Function\")\ntuple = (1, 2, 3)\nlist = list(tuple)\nprint(sum(list))\n\n\n# Global Variable\nprint(\"\\nGlobal Variable\")\nglobal_variable = 100\ndef Function_with_global_variable():\n# Local Variable\n    print(f\"The global variable value is: {global_variable}\")\nFunction_with_global_variable()\n\n# Local Variable\nprint(\"\\nLocal Variable\")\ndef function_with_local_variable():\n    local_variable = 200\n    print(f\"The local variable value is: {local_variable}\")\nfunction_with_local_variable()\n\n\n\n\n##############################################################\n\n# Extra Difficulty\nprint(\"\\nExtra Difficulty\")\n\ndef multiples_by_word(w1=\"Hello\", w2=\"World\"):\n    counter = 0\n\n    for number in range(0, 101):\n        if number % 3 == 0 and number % 5 == 0:\n            print(w1 + \" \" + w2)\n        elif number % 3 == 0:\n            print(w2)\n        elif number % 5 == 0:\n            print(w2)\n        else:\n            counter += 1\n            print(number)\n\n    return counter\nmultiples_by_word()\nprint(f\"The number appear {multiples_by_word()} times\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/andresgcastillo.py",
    "content": "# Variable global\nvariable_global = \"Soy una variable global\"\n\ndef funcion_sin_parametros_ni_retorno():\n    print(\"Función sin parámetros ni retorno\")\n\ndef funcion_con_parametros(a, b):\n    print(\"Función con parámetros:\", a, b)\n\ndef funcion_con_retorno(a, b):\n    return a + b\n\ndef funcion_con_funcion_dentro(a, b):\n    def suma(x, y):\n        return x + y\n    return suma(a, b)\n\ndef funcion_con_variable_local():\n    variable_local = \"Soy una variable local\"\n    print(variable_local)\n\ndef funcion_con_variable_global():\n    global variable_global\n    variable_global = \"He modificado la variable global\"\n    print(variable_global)\n\n# Llamada a las funciones\nfuncion_sin_parametros_ni_retorno()\nfuncion_con_parametros(5, 3)\nprint(\"Función con retorno:\", funcion_con_retorno(5, 3))\nprint(\"Función con función dentro:\", funcion_con_funcion_dentro(5, 3))\nfuncion_con_variable_local()\nfuncion_con_variable_global()\nprint(variable_global)\n\n#Dificultad Extra\ndef funcion(cadena1, cadena2):\n    contador = 0\n    for i in range(1, 101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(cadena1 + cadena2)\n        elif i % 3 == 0:\n            print(cadena1)\n        elif i % 5 == 0:\n            print(cadena2)\n        else:\n            print(i)\n            contador += 1\n    return contador\n\n# Llamada a la función\nprint(\"Número de veces que se ha impreso el número:\", funcion(\"Ludwig\", \"Mozart\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/andresmendozaf.py",
    "content": "\"\"\"\nFunciones definidas por el usuario\n\"\"\"\n\n# Simples\ndef saludar():\n    print(\"Hola, Python!\")\n\nsaludar()\n\n# Con retorno\ndef retornar_saludo():\n    return \"Hola, Python!\"\n\nprint(retornar_saludo())\n\n# Con un argumento\ndef arg_saludo(nombre):\n    print(f\"Hola, {nombre}\")\n\narg_saludo(\"Andrés\")\n\n# Con argumentos\ndef args_saludo(nombre, apellido):\n    print(f\"Hola, {nombre} {apellido}\")\n\nargs_saludo(apellido=\"Mendoza\", nombre=\"Andrés\")\n\n# Con argumento predeterminado en caso de que llamada sea sin valor\ndef prede_arg_saludo(nombre=\"Juanito\"):\n    print(f\"Hola, {nombre}\")\n\nprede_arg_saludo(\"JC\")\n\n# Con argumentos y return\ndef retorno_args_saludo(nombre, apellido):\n    return f\"Hola, {nombre} {apellido}!\"\n\nprint(retorno_args_saludo(\"Bárbara\", \"Bustos\"))\n\n# Con retorno de varios valores\ndef multiple_return():\n    return \"Hola\", \"Python\"\n\nprint(multiple_return()) # Crea una estructura\n\nsaludo, lenguaje = multiple_return()\nprint(saludo)\nprint(lenguaje)\n\n# Con un número variable de argumentos\ndef variable_arg_saludo(*nombres):\n    for nombre in nombres:\n        print(f\"Hola, {nombre}!\")\n\nvariable_arg_saludo(\"Andrés\", \"Bárbara\", \"Jaime\")\n\n# Con un número variable de argumentos con palabra clave\ndef variable_key_arg_saludo(**nombres):\n    for key, value in nombres.items():\n        print(f\"{value} ({key})!\")\n\nvariable_key_arg_saludo(\n    lenguaje=\"Python\",\n    nombre=\"Andrés\",\n    alias=\"Smile\",\n    edad=34\n)\n\n\"\"\"\nFunciones dentro de funciones\n\"\"\"\n\ndef funcion_externa():\n    def funcion_interna():\n        print(\"Función interna: Hola, Python!\")\n    funcion_interna()\n\nfuncion_externa()\n\n\"\"\"\nFunciones del lenguaje (built-in)\n\"\"\"\n\nprint(len(\"AndresMendozaF\"))\nprint(type(\"AndresMendozaF\"))\nprint(\"AndresMendozaF\".upper())\n\n\"\"\"\nVariables locales y globales\n\"\"\"\nvariable_global = \"Python\"\nprint(variable_global)\n\ndef hola_python():\n    variable_local = \"Hola\"\n    print(f\"{variable_local}, {variable_global}\")\n\nhola_python()\n\n\"\"\"\nEjercicio extra\n\"\"\"\n\ndef imprime_numeros(variable1, variable2):\n    contador = 0\n    for i in range(1,101):\n        if i %3 == 0 and i %5 != 0:\n            print(variable1)\n        elif i %5 == 0 and i %3 != 0:\n            print(variable2)\n        elif i %3 == 0 and i %5 == 0:\n            print(variable1 + variable2)\n        else:\n            print(i)\n            contador += 1\n    return contador\n\nprint(imprime_numeros(\"Fizz\",\"Buzz\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/angelsanchezt.py",
    "content": "\"\"\"\nEJERCICIO:\n - Crea ejemplos de funciones básicas que representen las diferentes\n   posibilidades del lenguaje:\n   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n - Comprueba si puedes crear funciones dentro de funciones.\n - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n - Debes hacer print por consola del resultado de todos los ejemplos.\n   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n\n DIFICULTAD EXTRA (opcional):\n Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\n Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\"\"\"\n\n\"\"\"\nFunciones definidas por el usuario\n\"\"\"\n\n# Simple\n\ndef greet_user():\n    \"\"\"Disply a simple greeting.\"\"\"\n    print(\"Hello!\")\n\ngreet_user()\n\n# Con un argumento\n\ndef greet_user(username):\n    \"\"\"Display a simple greeting.\"\"\"\n    print(\"Hello, \" + username + \"!\")\n\ngreet_user(\"Angel\")\n\n# Con argumentos\n\ndef describe_pet(animal_type, pet_name):\n    \"\"\"Display information about a pet.\"\"\"\n    print(\"\\nI have a \" + animal_type + \".\")\n    print(\"My \" + animal_type + \"'s name is \" + pet_name.title() + \".\")\n\ndescribe_pet(\"Hamster\", \"Harry\")\ndescribe_pet(animal_type='hamster', pet_name='harry')\ndescribe_pet(pet_name='harry', animal_type='hamster')\ndescribe_pet(animal_type='hamster', pet_name='harry')\n\n# Con un argumento predeterminado\ndef describe_pet(pet_name, animal_type='dog'):\n    \"\"\"Display information about a pet.\"\"\"\n    print(\"\\nI have a \" + animal_type + \".\")\n    print(\"My \" + animal_type + \"'s name is \" + pet_name.title() + \".\")\n\ndescribe_pet(pet_name='willie')\n\n# Con retorno\n\ndef get_formatted_name(first_name, last_name):\n    \"\"\"Return a full name, neatly formatted.\"\"\"\n    fullname = first_name + ' ' + last_name\n    return fullname.title()\n\nmusician = get_formatted_name(\"Jimi\", \"Hendrix\")\nprint(musician)\n\n# Retornando un Diccionario\ndef build_person(first_name, last_name):\n    \"\"\"Return a dictionary of information about a person.\"\"\"\n    person = {'fist' : first_name, 'last': last_name}\n    return person\n\nmusician = build_person('jimi', 'hendrix')\nprint(musician)\n\n# Con argumentos y return\ndef cuadrado(numero):\n    \"\"\"\n    Esta función toma un número como argumento y devuelve su cuadrado.\n    \"\"\"\n    resultado = numero ** 2\n    return resultado\n\n# Llamada a la función\nnumero_ingresado = 5\nresultado_cuadrado = cuadrado(numero_ingresado)\n\n# Imprimir el resultado\nprint(f\"El cuadrado de {numero_ingresado} es: {resultado_cuadrado}\")\n\n# Con retorno de varios valores\ndef operaciones_basicas(a, b):\n    \"\"\"\n    Esta función toma dos números como argumentos y devuelve la suma, resta,\n    multiplicación y división de ambos.\n    \"\"\"\n    suma = a + b\n    resta = a - b\n    multiplicacion = a * b\n    \n    # Manejo de la división por cero\n    if b != 0:\n        division = a / b\n    else:\n        division = None\n\n    return suma, resta, multiplicacion, division\n\n# Llamada a la función\nnumero1 = 10\nnumero2 = 5\nresultados = operaciones_basicas(numero1, numero2)\n\n# Desempaquetando los resultados\nsuma_resultado, resta_resultado, multiplicacion_resultado, division_resultado = resultados\n\n# Imprimir los resultados\nprint(f\"Suma: {suma_resultado}\")\nprint(f\"Resta: {resta_resultado}\")\nprint(f\"Multiplicación: {multiplicacion_resultado}\")\nif division_resultado is not None:\n    print(f\"División: {division_resultado}\")\nelse:\n    print(\"No es posible dividir por cero.\")\n\n# Con un número variable de argumentos\n\ndef suma_variable(*args):\n    \"\"\"\n    Esta función toma un número variable de argumentos y devuelve su suma.\n    \"\"\"\n    resultado = sum(args)\n    return resultado\n\n# Llamada a la función con diferentes cantidades de argumentos\nsuma_2_numeros = suma_variable(5, 10)\nsuma_3_numeros = suma_variable(2, 7, 3)\nsuma_4_numeros = suma_variable(1, 2, 3, 4)\n\n# Imprimir los resultados\nprint(f\"Suma de 2 números: {suma_2_numeros}\")\nprint(f\"Suma de 3 números: {suma_3_numeros}\")\nprint(f\"Suma de 4 números: {suma_4_numeros}\")\n\n\n# Con un número variable de argumentos con palabra clave\n\ndef datos_personales(**kwargs):\n    \"\"\"\n    Esta función toma un número variable de argumentos con palabras clave\n    (nombre, edad, ciudad) y devuelve un diccionario con esos datos.\n    \"\"\"\n    return kwargs\n\n# Llamada a la función con diferentes argumentos con palabras clave\ndatos1 = datos_personales(nombre=\"Juan\", edad=25, ciudad=\"Madrid\")\ndatos2 = datos_personales(nombre=\"María\", ciudad=\"Barcelona\")\ndatos3 = datos_personales(edad=30, ciudad=\"Sevilla\")\n\n# Imprimir los resultados\nprint(\"Datos de la persona 1:\", datos1)\nprint(\"Datos de la persona 2:\", datos2)\nprint(\"Datos de la persona 3:\", datos3)\n\n\n# Funciones de Orden Superior\n\"\"\"\nEl concepto de funciones de orden superior se refiere al uso de funciones como si de un valor cualquiera se tratara, \nposibilitando el pasar funciones como parámetros de otras funciones o devolver funciones como valor de retorno. \nUna función de orden superior será la que puede recibir una función como parámetro o que la puede devolver.\n\"\"\"\n\ndef saludar(lang):\n    \n    def saludar_es():\n        print(\"Hola\")\n        \n    def saludar_en():\n        print(\"Hi\")\n    \n    def saludar_fr():\n        print(\"Salut\")\n        \n    lang_func = {\"es\": saludar_es,\n                 \"en\": saludar_en,\n                 \"fr\": saludar_fr}\n    return lang_func[lang]\n\nf = saludar(\"en\")\nf()\nf = saludar(\"es\")\nf()\n\n\"\"\"\nFunciones dentro de funciones\n\"\"\"\n\ndef operaciones_complejas(a, b):\n    \"\"\"\n    Esta función principal toma dos números como argumentos y define funciones internas\n    para realizar operaciones más complejas. Luego, devuelve el resultado de estas operaciones.\n    \"\"\"\n\n    def suma_y_producto(x, y):\n        \"\"\"\n        Función interna que toma dos números y devuelve la suma y el producto de esos números.\n        \"\"\"\n        suma = x + y\n        producto = x * y\n        return suma, producto\n\n    def potencia_cubo(z):\n        \"\"\"\n        Función interna que toma un número y devuelve su potencia al cubo.\n        \"\"\"\n        cubo = z ** 3\n        return cubo\n\n    # Llamadas a las funciones internas\n    suma_resultado, producto_resultado = suma_y_producto(a, b)\n    cubo_resultado = potencia_cubo(suma_resultado)\n\n    # Devolución de los resultados\n    return suma_resultado, producto_resultado, cubo_resultado\n\n# Llamada a la función principal\nnumero1 = 2\nnumero2 = 3\nresultados = operaciones_complejas(numero1, numero2)\n\n# Desempaquetando los resultados\nsuma_resultado, producto_resultado, cubo_resultado = resultados\n\n# Imprimir los resultados\nprint(f\"Suma: {suma_resultado}\")\nprint(f\"Producto: {producto_resultado}\")\nprint(f\"Cubo de la suma: {cubo_resultado}\")\n\n\n\"\"\"\nFunciones del lenguaje (built-in)\n\"\"\"\n# Conversión de tipos\nnumero_entero = int(\"42\")\ntexto = str(3.14)\nprint(f\"Entero: {numero_entero}, Texto: {texto}\")\n\n# Operaciones con listas\nlista_numeros = [5, 12, 8, 3, 20]\nlongitud_lista = len(lista_numeros)\nvalor_maximo = max(lista_numeros)\nprint(f\"Longitud de la lista: {longitud_lista}, Valor máximo: {valor_maximo}\")\n\n# Manipulación de cadenas\ntexto_mayusculas = \"Hola Mundo\".upper()\ntexto_minusculas = \"Hola Mundo\".lower()\nprint(f\"Mayúsculas: {texto_mayusculas}, Minúsculas: {texto_minusculas}\")\n\n# Operaciones con listas\nlista_desordenada = [7, 2, 10, 5, 3]\nlista_ordenada = sorted(lista_desordenada)\nsuma_elementos = sum(lista_desordenada)\nprint(f\"Lista ordenada: {lista_ordenada}, Suma de elementos: {suma_elementos}\")\n\n# Entrada y salida\nnombre = input(\"Ingrese su nombre: \")\nprint(f\"Hola, {nombre}!\")\n\n\"\"\"\nVariables locales y globales\n\"\"\"\n\n# Variable global\nvariable_global = \"Soy global\"\n\ndef funcion_con_variable_local():\n    # Variable local\n    variable_local = \"Soy local\"\n    print(f'Dentro de la función: {variable_local}')\n\n# Llamada a la función\nfuncion_con_variable_local()\n\n# Intentando acceder a la variable local fuera de la función (esto generará un error)\n# print(f'Fuera de la función: {variable_local}')  # Descomentar esta línea para ver el error\n\n# Accediendo a la variable global fuera de la función\nprint(f'Fuera de la función: {variable_global}')\n\n\n\"\"\"\nExtra\n\"\"\"\n\ndef imprimir_numeros(texto1, texto2):\n    \"\"\"\n    Esta función imprime los números del 1 al 100 siguiendo las reglas dadas\n    y devuelve el número total de impresiones.\n    \"\"\"\n    contador_impresiones = 0\n\n    for numero in range(1, 101):\n        if numero % 3 == 0 and numero % 5 == 0:\n            print(texto1 + texto2)\n        elif numero % 3 == 0:\n            print(texto1)\n        elif numero % 5 == 0:\n            print(texto2)\n        else:\n            print(numero)\n            contador_impresiones += 1\n        \n    return contador_impresiones\n\n# Llamada a la función\nresultado = imprimir_numeros(\"Fizz\", \"Buzz\")\n\n# Imprimir el resultado\nprint(f\"Número de impresiones: {resultado}\")\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/anitandil.py",
    "content": "#FUNCIONES BASICAS\n#sin parametros sin retorno\ndef hola_mundo():\n    print(\"Hola Mundo\")\n\n#con parametros sin retorno\ndef sum(numero1, numero2):\n    print(numero1 + numero2)\n\n#sin parametros y con retorno\ndef pedir_nombre():\n    return(input(\"Ingrese su nombre: \"))\n\n#con parametros y retorno\ndef triplicar(numero):\n    return(numero*3)\n\n#funciones dentro de funciones\n    \"\"\"\n    en Python es posible declarar una función dentro de otra función. Sin embargo, la vida de esa función \n    pertenece al ámbito de la función donde es definida. Va a ser creada de nuevo cada vez que se llame \n    a la función donde es creada y dejará de existir cuando esta retorne  \n    Esto implica que no podrá ser llamada desde fuera de la función donde es definida en principio.\n    Por eso, son pocos los casos en los que esto es útil, principalmente en clausuras y factory-functions \n    \"\"\"\ndef sumar_mas(numero1,numero2):\n    def sumar_diez(valor):\n        return(valor +10) \n    \n    total = numero1 + numero2\n    if  total < 10:\n        total=sumar_diez(total)\n    \n    return total \n\n#FUNCIONES LAMBDA\npotenciacion_lambda = lambda base, exponente: base ** exponente\n\n#funciones ya creadas en Python\n#pueden ser llamadas si importamos el modulo donde fueron creadas, por ejemplo funciones matematicas\nimport math\n\nprint(math.sqrt(16))\n\n#variables locales y variables globales\ndef circunsferencia():\n    PI = 3.1416 #variable local\n    return PI*(radio**2)\n\nhola_mundo()\nsum(2,5)\nprint(pedir_nombre())\nprint(triplicar(3))\nprint(sumar_mas(1,2))\nprint(potenciacion_lambda(3, 4))\nradio = 5 #variable global\nprint(circunsferencia())\n\n\n\"\"\"\n     DIFICULTAD EXTRA (opcional):\n     Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n     - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n       - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n       - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n       - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n       - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\"\"\"\ndef imprimir_numeros(cadena1:str, cadena2:str)->int:\n    contador = 0\n    for num in range(1,101):\n        if num%3==0 and num%5==0:\n            print(str(num)+cadena1+cadena2)\n        elif num%3==0:\n            print(str(num)+cadena1)\n        elif num%5==0:\n            print(str(num)+cadena2)\n        else:\n            print(num)\n            contador+=1\n    return contador\n\ncantidad = imprimir_numeros(\"divisor de 3\",\"divisor de 5\")\nprint(f\"La cantidad de numero entre 1 y 100 que no son multiplos ni de 3 ni de 5 son:  {cantidad}\") \n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/annerssv.py",
    "content": "# FUNCIONES\n\n####FUNCION QUE NO ESPERA PARAMETROS####\ndef mi_primera_funcion():\n    print(\"Hola! esta es mi primera funcion\")\n\nmi_primera_funcion()\n\n#####FUNCION CON RETORNO####\n\ndef funcion_retorno():\n    return \"Hola!, esta es una función de retorno\"\n\nprint(funcion_retorno())\n\n#####FUNCION CON 1 PARAMETRO#####\n\ndef funcion_un_arg(name):\n    print(f'Hola {name}!')\n\nfuncion_un_arg(\"Jhan\")\n\n#####FUNCION CON MAS DE UN PARAMETRO#####\n\ndef fun_mas_arg(saludo, name):\n    print(f\"{saludo}, {name}!\")\n\nfun_mas_arg(\"Hola\", \"Jhan\")\n\n#####FUNCION CON VALOR POR DEFECTO####\n\ndef valor_por_defecto(name=\"Mundo\"):\n    print(f\"Hola {name}\")\n\nvalor_por_defecto(\"Pier\")\nvalor_por_defecto()\n\n#####FUNCION CON MULTIPLES ARGUMENTOS *args ####\n\ndef suma_args(*args): #Los parametros recibidos seran converidos en una tupla \n    total = 0\n    for n in args: \n        total += n\n    return print(total)\n\nsuma_args(1,2,3)\n\n\n####FUNCION CON MULTIPLES ARGUMENTOS KEY/VALUE####\n\ndef resta_kwargs(**kwargs):\n    suma = 0\n    for key, value in kwargs.items():\n        print (f\"{key} = {value}\")\n        suma += value\n    return print(suma)\n\nresta_kwargs(a=20, b=10, c= 5)\n\n\n#####FUNCIONES DENTRO DE FUNCIONES####\n\ndef calculadora():\n\n    def suma(n1=0, n2=0):\n        return n1 + n2\n    print(suma(2,3))\n\n    def resta(n1=0, n2=0):\n        return n1 - n2\n    print(resta(4,5))\n\n    def multiplicacion(n1=0, n2=0):\n        return n1 * n2\n    print(multiplicacion(5,6))\n\n    def division(n1=0, n2=0):\n        return n1 / n2\n    print(division(7,8))\n\ncalculadora()\n\n\n###FUNCIONES DEL LENGUAJE###\n\n#-----Funciones de cadenas\n\n#--IMPRESION\nprint(\"Este texto fue impreso con la funcion print()\")\n\n#--CADENAS\nminuscula = \"ESTE TEXTO FUE CONVERTIDO EN MINUSCULAS CON LA FUNCION lower()\"\nprint(minuscula.lower())\nmayuscula = \"este texto fue convertido a mayusculas con la funcion upper()\"\nprint(mayuscula.upper())\n\n#----FUNCION PARA TIPO DE DATOS\n\nmi_arreglo = [1,2,3,4,5]\nprint(type(mi_arreglo))\n\n####CONCEPTO DE VARIABLE LOCAL Y GLOBAL####\n\n#VARIABLE GLOBAL\nmi_variable_local = \"Hola soy una variable local\"\n\ndef funcion_local():\n    print(mi_variable_local)\n\nfuncion_local()\n\n#VARIABLE LOCAL\n\ndef funcion_local1():\n    variable = \"Hola soy una variable local\"\n    return print(variable)\nfuncion_local1()\n\nprint(\"En esta linea no puedo acceder la variable de la funcion1\")\n\n\n\n#EJERCICIO EXTRA\n\ndef extra(texto1, texto2):\n    contador = 0\n    for numero in range(1, 101):\n        if numero % 3 == 0 and numero % 5 == 0:\n            print(texto1 + texto2)\n        elif numero % 3 == 0:\n            print(texto1)\n        elif numero % 5 == 0:\n            print(texto2)\n        else:\n            print(numero)\n            contador +=1\n\n    return contador\n\nprint(extra(\"Fizz\", \"Buzz\"))\n\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/antii16.py",
    "content": "'''\nCrea ejemplos de funciones básicas que representen \nlas diferentes posibilidades del lenguaje:\nSin parámetros ni retorno, con uno o varios parámetros, \ncon retorno...\n'''\n# Sin parámetro ni retorno\ndef restar():\n    print(f'10-3 = {10-3}')\nrestar()\n\n# Con uno parámetro\ndef miNombre(nombre):\n    print(f'Mi nombre es {nombre}')\nmiNombre('Pedro')\n\n# Con varios parámetros y retorno\ndef sumar(n1, n2):\n    return n1+n2\nprint(f'El resultado de la suma es: {sumar(10,3)}')\n\n'''\nComprueba si puedes crear funciones dentro de funciones.\nSí se puede crear una función dentro de otra, pero la función interna \nsolo puede ser llamada en la función externa. Es decir, en este caso, solo \npuede utilizarse saludar() en nombrar().\n'''\ndef nombrar(nombre):\n    def saludar():\n        print(f'Hola, {nombre}')\n    saludar()\n\nnombrar('Paco')\n\n'''\nUtiliza algún ejemplo de funciones ya creadas en el lenguaje\n'''\ncolor = 'amarillo'\nlongitud = len(color)\nprint(f'La longitud de \"amarillo\" es: {longitud} ')\n\nlista = [0, 1, 3, 89]\nprint(f'El mayor número de la lista es: {max(lista)}')\n\n'''\nPon a prueba el concepto de variable LOCAL y GLOBAL.\nComo se ve, 'apellido' al ser definida de forma global, puede\nser utilizada en ambas funciones, pero 'nombre' se ha definido dentro\nde una función, teniendo utilidad solo dentro de ella.\n'''\napellido = 'González' # variable GLOBAL\n\ndef saludar():\n    nombre = 'Lucía' # varibale LOCAL\n    print(f'Mi nombre es {nombre} y {apellido}')\n    \ndef saludar2():\n    print(f'Mi nombre es {nombre} y {apellido}')\n\nsaludar()\n# saludar2() # Error\n\n\n'''\nDIFICULTAD EXTRA\n'''\n\ndef mostrarNumero(texto1, texto2):\n    contadorNumber = 0\n    for n in range(1, 101):\n        if n%3==0 and n%5==0:\n            print(texto1 + texto2)    \n        elif n%3 == 0:\n            print(texto1)  \n        elif n%5 == 0:\n            print(texto2)  \n        else:\n            print(n)\n            contadorNumber+= 1\n    return f'Número de veces que se ha impreso el número en lugar de los textos: {contadorNumber}'\n\nresultado = mostrarNumero('Choco', 'late')\nprint(resultado)\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/antoniosuero.py",
    "content": "# EJERCICIO:\n#  * - Crea ejemplos de funciones básicas que representen las diferentes\n#  *   posibilidades del lenguaje:\n#  *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n#  * - Comprueba si puedes crear funciones dentro de funciones.\n#  * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n#  * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n#  * - Debes hacer print por consola del resultado de todos los ejemplos.\n#  *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n#  *\n#  * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n#  * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n\ndef sin_parametros():\n  print(\"Hola Mundo!\")\n\nsin_parametros()\n\n\ndef con_parametros(a, b):\n  print(a + b)\n\ncon_parametros(5, 10)\n\n\ndef con_retorno(a):\n  return a\n\nprint(con_retorno(\"Segovia\"))\n\n\ndef suma(*elementos):\n  suma = sum(elementos)\n  return suma\n\nprint(f\"La suma total es: {suma(1, 2, 3, 4, 5, 6, 7, 8, 9)}\")\n\n\ndef funcion_dentro_funcion(x):\n  def funcion_interna(y):\n    return x + y\n    \n  resultado = funcion_interna(10)\n  return resultado\n\nprint(funcion_dentro_funcion(5))\n\n\ndef funcion_llama_funcion(num):\n  multiplica = suma(1, 2, 3, 4, 5) * num\n  return multiplica\n\nprint(funcion_llama_funcion(3))\n\n# ALGUNAS FUNCIONES DENTRO DE PYTHON\nprint(f\"\\n{\"#\" * 17} ALGUNAS FUNCIONES PYTHON {\"#\" * 17}\\n\")\n\nprint(f\"print(), input(), len(), list(), round(), abs() y muchas más\")\n\nprint(f\"\\n{\"#\" * 60}\\n\")\n\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n#  * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n#  *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n#  *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n#  *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n#  *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\ndef opcional(text_1, text_2):\n    contador = 0\n    for number in range(1, 101):\n        if number % 3 == 0 and number % 5 == 0:\n            print(text_1 + text_2)\n        elif number % 3 == 0:\n            print(text_1)\n        elif number % 5 == 0:\n            print(text_2)\n        else:\n            print(number)\n            contador += 1\n    return contador\n\nprint(f\"Números de veces que se ha imprimido el número en lugar del texto: {opcional(\"cola\", \"cao\")} veces.\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/any7dev.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */ \"\"\"\n\ndef mi_funcion():\n    print(\"Primera funcion\")\n\ndef mi_funcion_dos(param):\n    print(f\"{param} funcion\")\n\ndef mi_funcion_tres(param1, param2):\n    return f\"{param1} {param2}\"\n\ndef funcion_variables():\n    local_var = \"Esto es una variable local\"\n    global global_var\n    global_var = \"variable global\"\n    print(f\"{local_var} y esto una {global_var}\")\n\ndef funcion_variables_dos():\n    print(f\"La {global_var} se puede usar desde cualquier función\")\n\ndef mi_funcion_cuatro():\n    cadena = \"Mi función cuatro\"\n    def mi_funcion_cinco():\n        print(f\"{cadena} crea mi funcion cinco\")\n    mi_funcion_cinco()\n\ndef funcion_creada():\n    return \"print() Es una función ya creada en Python\"\n\ndef extra(cadena1, cadena2):\n    contador = 0\n    for i in range(1,101):\n        if i % 3 == 0 and not i % 5 == 0:\n            print(f\"{cadena1}\")\n        elif i % 5 == 0 and not i % 3 == 0:\n            print(f\"{cadena2}\")\n        elif i % 3 == 0 and i % 5 == 0:\n            print(f\"{cadena1} {cadena2}\")\n        else:\n            print(i)\n            contador += 1\n    return contador\n\nif __name__ == '__main__':\n    parametro_uno = \"Segunda\"\n    parametro_dos = \"Tercera\"\n    parametro_tres = \"Funcion\"\n    mi_funcion()\n    mi_funcion_dos(parametro_uno)\n    print(mi_funcion_tres(parametro_dos, parametro_tres))\n    funcion_variables()\n    funcion_variables_dos()\n    mi_funcion_cuatro()\n    print(funcion_creada())\n    numero = extra(cadena1=\"Casi\", cadena2=\"fizzbuzz\")\n    print(f\"El número de veces que se ha impreso el número en lugar de los textos es {numero}\")\n\n    "
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/arkmiguel379.py",
    "content": "# Funcion sin valor de retorno y sin parametros\n\ndef saludar():\n    print(\"Hola Logan\")\n\nsaludar()\n\n# Funcion con retorno sin parametros\n\ndef obtener_numero():\n    return 379\n\nprint(obtener_numero())\n\n# Funcion sin valor de retorno con parametros\n\ndef mensaje(str1, str2):\n    print(f\"{str1} {str2}\")\n\nmensaje(\"Hola\", \"Mundo\")\n\n# Funcion con retorno y parametros\n\ndef suma(value1, value2):\n    return value1 + value2\n\nprint(suma(5,8))\n\n# Funcion con paremetros opcionales o predeterminados\n\ndef informacion(nombre, apellido, edad, categoria = 0):\n    print(f\"Nombre: {nombre} Apellido: {apellido} Edad: {edad} Categoria: {categoria}\")\n\ninformacion(\"Miguel\", \"Moreno\", 28, 3)\n\n# Funcion con múltiples valores de retorno\n\ndef division(dividendo, divisor):\n    cociente = dividendo / divisor\n    resto = dividendo % divisor\n    return cociente, resto\n\nresultado_cociente, resultado_resto = division(10,2)\n\nprint(resultado_cociente)\nprint(resultado_resto)\n\n# ======================= FUNCIONES DENTRO DE FUNCIONES ============================\n\ndef funcion_externa():\n    print(\"Inicio de la funcion externa\")\n\n    def funcion_interna():\n        print(\"Ejecucion de la funcion interna\")\n\n    funcion_interna()\n\n    print(\"Finalizacion de la funcion externa\")\n\nfuncion_externa()\n\n# ======================= FUNCIONES DEL SISTEMA ===================================\n\nlista = [1, 2, 3, 4, 5]\nlongitud_lista = len(lista) # <-- LEN: Permite saber cual es la longitud de la coleccion a la que se aplica\nprint(longitud_lista)\n\ntipo = type(lista) # <-- TYPE: Permite saber de que tipo es la variable que se le pasa\nprint(tipo)\n\nentero = int(\"379\") # <-- INT: Permite convertir a tipo INT el valor que se le pasa\ncadena = str(257379) # <-- STR: Permite convertir a tipo STR el valor que se le pasa\nflotante = float(\"3.14\") # <-- FLOAT: Permite convertir a tipo FLOAT el valor que se le pasa\n\n# nombre = input(\"Ingrese su nombre\") # <-- INPUT: Lee una entrada del usuario desde la consola\n\nsecuencia = range(1, 10, 2) # <-- Secuencia de numeros del 1 al 10 que va de 2 en 2\n\ncoleccion = [10, 2, 3, 8, 13, 33, 25]\nminimo = min(coleccion) # <-- Devuelve el valor minimo de una coleccion\nmaximo = max(coleccion) # <-- Devuelve el valor maximo de una coleccion\nprint(minimo)\nprint(maximo)\n\nlista_desordenada = [10, 2, 3, 8, 13, 33, 25]\nlista_ordenada = sorted(lista_desordenada)\nprint(lista_ordenada)\n\nredondeado = round(3.14159) # <-- Dedondea al numero entero mas cercano\n\n#============================== EXTRA =============================\n\ndef funcionE(str1, str2):\n\n    contador = 0\n\n    for i in range(1, 100):\n        if i % 3 == 0 and i % 5 == 0:\n            print(f\"{str1} + {str2}\")\n\n        elif i % 3 == 0:\n            print(str1)\n\n        elif i % 5 == 0:\n            print(str2)\n            \n        else:\n            print(i)\n            contador += 1\n\n    return contador\n\nfuncionE(\"Primer cadena\", \"Segunda cadena\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/aserranot.py",
    "content": "#Python dispone de 69 funciones básicas o integradas, algunas de las más utilizadas son:\n#print(), con la función print podremos imprimir un texto o valor por pantalla/consola.\nprint(\"Hello world\")\n#len(), la función len nos devuelve la longitud de un objeto, como una cadena o una lista.\ncadena = (\"coche\")\nprint(len(cadena))\nmy_list_len = [1, 2, 3, 4, 5]\nprint(len(my_list_len))\n#max(), devuleve el elemento más grande de un iterable\nmy_list_max = [1, 2, 3, 4, 5]\nprint(max(my_list_max))\n#max(), devuleve el elemento más pequeño de un iterable\nmy_list_min = [1, 2, 3, 4, 5]\nprint(min(my_list_min))\n#sum(), devuleve la suma de todos los elementos de un iterable\nmy_list_sum = [1, 2, 3, 4, 5]\nprint(sum(my_list_sum))\n#Las funciones dentro de funciones en python se llaman funciones anidadas\ndef funcion_padre():\n    def funcion_hija():\n        return \"¡Soy la función hija!\"\n    return funcion_hija()\n\nprint(funcion_padre())\n#El python una variable local es una variable que solamente se puede utilizar dentro del código de la función que se declara. En cambio una variable global se puede utilizar dentro de todo el probrama y por todas las funionces.\ndef calculaIVA(val1, valIva):\n    iParcial = val1 * valIva / 100\n    print(\"Valor del IVA\", iParcial)\n\niTotal = 2000  # Variable global\niParcial = 0  # Variable global\nprint(\"Precio sin IVA es\", iTotal)\ncalculaIVA(iTotal, 16)\nprint(\"Precio con IVA es\", iTotal + iParcial)\n#Ejercicio opcional\ndef mi_funcion (valor1, valor2):\n  for cadena in range (100):\n    if ((cadena % 3 == 0) and (cadena % 5 == 0)):\n      print (f\"{valor1}{valor2}\")\n    elif (cadena % 3 == 0):\n      print(f\"{valor1}\")\n    elif (cadena % 5 == 0):\n      print(f\"{valor2}\")\n    else:\n       print(f\"{cadena}\")\n\nmi_funcion(\"Hola\",\"mundo\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/augustdev2003.py",
    "content": "\"\"\"\nFunciones definidas por el usuario\n\"\"\"\n\n# Vacía\n\n\ndef empty():\n    pass\n\n# Simple\n\n\ndef simple():\n    print('Simple Function')\n\n\nsimple()\n\n# Con retorno\n\n\ndef with_return():\n    return \"Return function\"\n\n\nprint(with_return())\n\n# Con argumento\n\n\ndef with_argument(city):\n    print(f'Vivo en {city}.')\n\n\nwith_argument('Madrid')\n\n# Con argumentos\n\n\ndef with_arguments(name, age):\n    print(f'Me llamo {name} y tengo {age} años.')\n\n\nwith_arguments('Augusto', '20')\nwith_arguments(age=20, name='Augusto')\n\n# Argumento predeterminado\n\n\ndef default_arg(name, greet='Hi'):\n    print(f'{greet}, {name}')\n\n\ndefault_arg('Pedro')\ndefault_arg('Pedro', 'Hello')\n\n# Argumentos y retorno\n\n\ndef args_return(name, surname):\n    return f'{name} {surname}'\n\n\nprint(args_return('Pablo', 'Gonzalez'))\n\n# Retorno de varios valores\n\n\ndef multiple_values():\n    return 'Hi', 'Python'\n\n\ngreet, name = multiple_values()\nprint(greet)\nprint(name)\n\n# Número variable de argumentos\n\n\ndef variable_args(*countries):\n    for country in countries:\n        print(f'Vivo en {country}')\n\n\nvariable_args('Argentina', 'Jamaica', 'España', 'Inglaterra')\n\n# Número variable de argumentos con palabra clave\n\n\ndef variable_key_arg(**ages):\n    for key, value in ages.items():\n        print(f'{key}: {value}')\n\n\nvariable_key_arg(\n    name='Augusto',\n    age=20,\n    language='Python',\n    birthday='2003-08-28'\n)\n\n\"\"\"\nFunciones dentro de funciones\n\"\"\"\n\n\ndef outside():\n    def inside():\n        print('Estoy dentro de la función')\n    inside()\n\n\noutside()\n\n\"\"\"\nFunciones propias del lenguaje\n\"\"\"\n\nlenguaje = 'Python'\nprint(len(lenguaje))\nprint(type(lenguaje))\nprint(lenguaje.index('on'))\n\n\"\"\"\nGlobales y locales\n\"\"\"\n\nvariable_global = 'Python'\n\n\ndef hello():\n    variable_local = 'Hola'\n    print(f'{variable_local} {variable_global}')\n\n\nprint(variable_global)\n# print(variable_local) # No se puede acceder a esta variable ya que se encunetra dentro de la función\n\n\"\"\"\nExtra\n\"\"\"\n\n\ndef print_numbers(text1, text2) -> int:\n    count = 0\n    for n in range(1, 101):\n        if n % 15 == 0:\n            print(text1 + text2)\n        elif n % 3 == 0:\n            print(text1)\n        elif n % 5 == 0:\n            print(text2)\n        else:\n            print(n)\n            count += 1\n    return count\n\n\nprint(print_numbers('Hola', 'Python'))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/avcenal.py",
    "content": "\"\"\"\n* EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n\"\"\"\n\"\"\"\nFUNCIONES SIN VALOR DE RETORNO\n\"\"\"\nprint(\"FUNCIONES SIN VALOR DE RETORNO\")\n\n#Función sin parámetros ni valores de retorno\ndef empty_function():\n    print(\"Esta es una función sin parámetros ni valores de retorno\")\n\nempty_function()\n\n#Función con un parámetro pero sin valores de retorno\ndef one_parameter(number):\n    print(number * 2)\n\none_parameter(3)\n\n#Función con dos parámetros sin valores de retorno\ndef two_parameters(first_value, second_value):\n    print(f\"La suma de {first_value} y {second_value} es: {first_value + second_value}\")\n\ntwo_parameters(5,3)\n\n\"\"\"\nFUNCIONES CON VALOR DE RETORNO\n\"\"\"\nprint(\"\\n\")\nprint(\"FUNCIONES CON VALOR DE RETORNO\")\n\n#Función con un parámetro y retorno\ndef one_parameter_and_return(one_value):\n    return one_value * 2\n\nprint(f\"La función one_parameter_and_return con el parámetro de entrada 4 devuelve: {one_parameter_and_return(4)}\")\n\n#Función con dos parámetros y retorno\ndef two_parameters_and_return(first_value,second_value):\n    return first_value - second_value\n\nprint(f\"La función two_parameters_and_return que recibe los parámetros de entrada 8 y 3 devuelve: {two_parameters_and_return(8,3)}\")\n\n\"\"\"\nFUNCIONES DENTRO DE FUNCIONES\n\"\"\"\nprint(\"\\n\")\nprint(\"FUNCIONES DENTRO DE FUNCIONES\")\n\n#Con Lambdas\ndef concat_strings():\n    return lambda string_one,string_two: string_one + string_two\nprint(f\"Los strings concatenados son: {concat_strings()(\"Hola \",\"soy Alex\")}\") #Esto es un closure\n\n#Con otras funciones\ndef multiply_value(value):\n    def add_five():\n        return value + 5\n    return add_five() * 2\n\nprint(f\"La función multiply_value: {multiply_value(3)}\") #Esto es otro closure\n\ndef sum_values(value_one,value_two):\n    def mutliply(value_three):\n        return (value_one + value_three) * value_two\n    return mutliply\n\nprint(f\"La función sum_values da: {sum_values(2,3)(5)}\") #Y Esto es otro closure\n\n#Funciones como argumentos\n\ndef sum_two(number):\n    return number + 2\n\ndef sum_two_values(value_one, value_two,f):\n    return f(value_one + value_two)\n\nprint(f\"La función sum_two_values que tiene como argumento sum_two: {sum_two_values(5,4,sum_two)}\")\n\n\"\"\"\nFUNCIONES DEl LENGUAJE\n\"\"\"\nprint(\"\\n\")\nprint(\"FUNCIONES DEl LENGUAJE\")\n\none_list = [5,20,17,63,54]\nother_list = [\"Alex\",\"Sole\",\"Martín\",\"Valeria\",\"Spock\"]\nmy_int = 7\nmy_other_int = 4\n\nprint(f\"La función len() nos devuelve la longitud de one_list, que es: {len(one_list)}\")\nprint(f\"Con slice() podemos coger un \\\"trozo\\\" del índice 2 al 4 de one_list: {one_list[slice(2,5)]}\")\nprint(f\"podemos pasar one_list a una tupla con tuple(): {tuple(one_list)}\")\nprint(f\"También pasar de nuevo esa tupla a lista con list(): {list(tuple(one_list))}\")\nprint(f\"Con enumerate() + list() creamos una lista de tuplas desde one_list: {list(enumerate(one_list))}\")\nprint(f\"O comprobar el tipo de one_list con la función type(): {type(one_list)}\")\nprint(f\"También podemos crear un diccionario con dict.fromkeys():\\n {dict.fromkeys(other_list,\"default\")}\")\nprint(f\"Podemos pasar un my_int a float con la función float(): {float(my_int)}\")\nprint(f\"Y pasar ese float a int de nuevo con int(): {int(float(my_int))}\")\nprint(f\"Se puede calcular la potencia de un número con pow(): {pow(2,3)}\")\nprint(f\"Pasar un número a string con str(): {str(my_int)}\")\nprint(f\"Definir un rango con range(): {range(0,10)}\")\nprint(f\"Redondear el número 3.94162835 con round(): {round(3.94162835)}\")\nprint(f\"Hacer el sumatorio de los elementos de one_list con sum(): {sum(one_list)}\")\nprint(f\"O podemos darle la vuelta a one_list con reversed() + list(): {list(reversed(one_list))}\")\nprint(f\"También la one_list podemos ordenarla con sorted(): {sorted(one_list)}\")\nprint(f\"Podemos obtener el valor ordinal de un caracter con ord(): {ord(\"A\")}\")\nprint(f\"Con hash() podemos codificar cualquier cosa, por ejemplo la cadena \\\"Hola Mundo\\\": {hash(\"Hola Mundo\")}\")\nprint(f\"Con hex() podemos pasar un número (el 23 por ejemplo) a hexadecimal: {hex(23)}\")\n\n\"\"\"\nVARIABLES GLOBALES Y LOCALES\n\"\"\"\nprint(\"\\n\")\nprint(\"VARIABLES GLOBALES Y LOCALES\")\n\nmy_global_string = \"Esto es una variable global\" #Una variable local será accesible en cualquier parte de nuestro programa\ndef training_function():\n    my_local_string = \"Esto es una variable local\" #Las variables locales a una función solo se pueden usar dentro del alcance de la función\n    print(my_local_string) #puedo utilizar la variable porque estoy dentro de la función\n    print(my_global_string) #también puedo llamar a la variable global dentro de la función\n\ntraining_function()\n#print(my_local_string) esto da un error porque my_local_string no está declarada fuera de la función.\n\n\"\"\"\nDIFICULTAD EXTRA\n\"\"\"\nprint(\"\\n\")\nprint(\"DIFICULTAD EXTRA\")\ndef adhoc_fizzbuzz(text_one,text_two):\n    numbers_count = 0\n    for number in range(0,101):\n        if number % 3 == 0 and number % 5 == 0:\n            print(text_one+text_two)\n        elif number % 3 == 0:\n            print(text_one)\n        elif number % 5 == 0:\n            print (text_two)\n        else:\n            print(number)\n            numbers_count += 1\n    \n    return numbers_count\n\nstring_one = input(\"Dime la primera cadena de texto: \")\nstring_two = input (\"Ahora dime la segunda cadena de texto: \")\n\nprint(f\"Los números se han impreso {adhoc_fizzbuzz(string_one,string_two)} veces\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/axelprz.py",
    "content": "\"\"\"  * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda. \"\"\"\n \n # Función sin parámetros ni retorno\ndef saludar():\n    print(\"¡Hola! Bienvenido.\")\n\nsaludar()\n\n# Función con parámetros y retorno\ndef sumar(a, b):\n    resultado = a + b\n    return resultado\n\nresultado_suma = sumar(3, 5)\nprint(\"Resultado de la suma:\", resultado_suma)\n\n# Función con parámetros por defecto\ndef saludar_persona(nombre=\"Invitado\"):\n    print(f\"Hola, {nombre}.\")\n\nsaludar_persona()  # Utiliza el valor por defecto\nsaludar_persona(\"Carlos\")\n\n# Función que devuelve múltiples valores\ndef dividir_y_obtener_resto(dividendo, divisor):\n    cociente = dividendo // divisor\n    resto = dividendo % divisor\n    return cociente, resto\n\ncoc, res = dividir_y_obtener_resto(10, 3)\nprint(\"Cociente:\", coc)\nprint(\"Resto:\", res)\n\n# Función con función interna (anidada)\ndef operaciones_matematicas(a, b):\n    def suma():\n        return a + b\n\n    def resta():\n        return a - b\n\n    return suma(), resta()\n\nresultado_suma, resultado_resta = operaciones_matematicas(8, 3)\nprint(\"Suma:\", resultado_suma)\nprint(\"Resta:\", resultado_resta)\n\n# Variable GLOBAL\nglobal_variable = \"Soy global\"\n\ndef imprimir_global():\n    print(\"Variable global:\", global_variable)\n\nimprimir_global()\n\n# Variable LOCAL\ndef imprimir_local():\n    local_variable = \"Soy local\"\n    print(local_variable)\n\nimprimir_local()\n\n\n# Actividad adicional\n\ndef cadenas(c1,c2):\n    contador = 0\n    for i in range(1,100):\n        if i % 3 == 0 and i % 5 == 0:\n            print(c1+c2)\n        elif i % 3 == 0:\n            print(c1)\n        elif i % 5 == 0:\n            print(c2)\n        else:\n            print(i)\n            contador+= 1\n    return contador\n\nresultado = cadenas(\"Hola\", \"Adios\")\nprint(f\"El numero se imprimio {resultado} veces en total\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/betzadev.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */ \"\"\"\n\n\"\"\" /// FUNCIONES EN PYTHON 🐍 /// \"\"\"\n\n# Función sin parámetros o retorno de valores:\n\ndef hola():\n  print('Hola Python 🙋🏻‍♀️')\n\nhola() #llamada a la función\n\n# Función con un parámetro\n\ndef saludar_persona(nombre):\n  print(f\"¡Hola, {nombre}!\")\n\nsaludar_persona(\"Carlos\")  # Salida: ¡Hola, Carlos!\n\n\n# Función con múltiples parámetros con una sentencia de retorno\n\ndef calcular_suma(num1, num2):\n  suma = num1 + num2\n  return suma\n\nresultado = calcular_suma(5, 3)\nprint(f\"La suma de 5 y 3 es: {resultado}\")  # Salida: La suma de 5 y 3 es: 8\n\n# Función con retorno y parámetros opcionales:\n\ndef multiplicar(num1, num2=1):\n  producto = num1 * num2\n  return producto\n\nresultado1 = multiplicar(5)  # Salida: 5\nresultado2 = multiplicar(3, 2)  # Salida: 6\n\nprint(f\"El resultado de multiplicar 5 por 1 es: {resultado1}\")\nprint(f\"El resultado de multiplicar 3 por 2 es: {resultado2}\")\n\n# Funciones dentro de funciones (anidamiento):\n\ndef funcion_externa():\n  def funcion_interna():\n    print(\"Estoy dentro de la función interna\")\n\n  funcion_interna()  # Se llama a la función interna desde la externa\n\nfuncion_externa()  # Se llama a la función externa\n\n# Ejemplo de funciones ya creadas en Python:\n\nprint(\"Hola mundo\")  # Función print()\nlen(\"Esta es una cadena\")  # Función len() para longitud de cadenas\nabs(-5)  # Función abs() para valor absoluto\nsum([1, 2, 3])  # Función sum() para sumar elementos de una lista\n\n# Variables locales y globales:\n\ndef variable_global():\n  global variable_global  # Se declara como variable global\n\n  variable_global = 10  # Se modifica el valor de la variable global\n\nvariable_global = 5  # Se inicializa la variable global\n\ndef variable_local():\n  variable_local = 20  # Variable local dentro de la función\n\n  print(f\"Variable local dentro de la función: {variable_local}\")\n\nvariable_local()  # Se llama a la función local\nprint(f\"Variable global después de llamar a la función local: {variable_global}\")  # Salida: Variable global después de llamar a la función local: 10\n\n# Dificultad extra:\n\ndef multiples_con_mensajes(texto1, texto2):\n  contador_mensajes = 0  # Contador de mensajes impresos\n\n  for numero in range(1, 101):\n    if numero % 3 == 0 and numero % 5 == 0:\n      print(f\"{texto1} {texto2}\")\n      contador_mensajes += 2\n    elif numero % 3 == 0:\n      print(texto1)\n      contador_mensajes += 1\n    elif numero % 5 == 0:\n      print(texto2)\n      contador_mensajes += 1\n    else:\n      print(numero)\n\n  return contador_mensajes\n\nresultado = multiples_con_mensajes(\"Azul\", \"Amarillo\")\nprint(f\"Se han impreso los mensajes {resultado} veces\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/blancowilson.py",
    "content": "# Funciones practica semana 2 Blancowilson\n\n## functions with two parameters and another function inside\ndef validate_has_letter(word, letter):\n    #function into another function\n    def addition(a,b):\n        print(\"Message into the function inside another function\")\n        print(f\"la suma de {a} + {b} =\", end=\" \")\n        return a + b\n    print(f\"{addition(3,5)}\")\n    return letter in word   \n\n#calling the function an print the retun result\nprint(validate_has_letter(\"palabra\",'e'))\nprint(\"\")\nprint(\"Test local and global variables\")\n# Testing the glbal an local variables\ncount_local = 0 # local variable\ndef increment_count():\n    global count_local #concerting count to a global to use in the function\n    count_local += 1\n\ndef another_increment_count():\n    global count_local\n    count_local += 1\n\nincrement_count()\nanother_increment_count()\nprint(count_local) # Output: 1\n\n\n# Functions without parameters and return values\ndef normal_function():\n    print(\"Hello, this is a function without parameters or return values\")\n\nnormal_function()\n\n\n# Functions with optional parameters and default values\ndef function_with_optional_parameters(name=\"Unknown\", age=0):\n    print(f\"Hello, {name}. You are {age} years old.\")\n\n# Call the function to execute it\nfunction_with_optional_parameters()\n\n# Functions with arbitrary positional parameters using *args\ndef function_with_arbitrary_parameters(*args):\n    print(f\"You passed {len(args)} arguments to the function.\")\n    for arg in args:\n        print(f\"Argument: {arg}\")\n\n# Call the function to execute it\nfunction_with_arbitrary_parameters(\"Mathematics\", 1, 2)\n\n# Functions with keyword arguments using **kwargs\ndef function_with_keyword_arguments(**kwargs):\n    print(f\"You passed {len(kwargs)} keyword arguments to the function.\")\n    for key, value in kwargs.items():\n        print(f\"Key: {key}, Value: {value}\")\n\n# Call the function to execute it\nfunction_with_keyword_arguments(name=\"Wilson\", age=40)\n\n# Asynchronous functions using asyncio\nimport asyncio\n\nasync def function_async():\n    print(\"This is an asynchronous function.\")\n\n# Call the function to execute it\nasyncio.run(function_async())\n\n# Functions with built-in functions\ndef function_with_built_in_functions():\n    fruits = [\"apple\", \"banana\", \"cherry\"]\n    print(f\"Length of the list: {len(fruits)}\")\n    print(f\"List: {list(fruits)}\")\n\n# Call the function to execute it\nfunction_with_built_in_functions()\n\nprint(\"\")\nprint (\"Exercise Extra Print Word instead number\")\nprint(\"\")\ndef print_text(word1,word2):\n    counter_both,counter_word1,counter_word2 =0,0,0     \n    for i in range(1,101):\n        if (i%5==0) & (i%3==0):\n            print(f\"{word1} {word2}\")\n            counter_both += 1\n        elif (i%3==0):\n            print(word1, end=\",\")\n            counter_word1 += 1\n        elif (i%5==0):\n            print(word2,end=',')\n            counter_word2 += 1\n        else:\n            print(i,end=',')\n    print(\"\")\n    return (counter_word1,counter_word2,counter_both)\n\n\ntimes = print_text('fizz', 'buzz')\nprint(f'Se imprimieron las palabras 1,2 y ambas {times} veces en vez de los numeros')"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/bryanalzate007.py",
    "content": "\n# /*\n#  * EJERCICIO:\n#  * - Crea ejemplos de funciones básicas que representen las diferentes\n#  *   posibilidades del lenguaje:\n#  *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n#  * - Comprueba si puedes crear funciones dentro de funciones.\n#  * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n#  * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n#  * - Debes hacer print por consola del resultado de todos los ejemplos.\n#  *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n#  *\n\n\n\n#1. Funcion sin parámetros y sin retorno\n\ndef hello():\n    print(\"Hello\")\n\nhello()\n\n#2. Funcion con un parámetro\n\ndef date_person(name):\n    print(f\"Hello, {name}\")\n\ndate_person(\"bryan\")\n\n#3. Funcion con multiples parametros y sin retorno\n\ndef dates_person(name, edad):\n    print(f\" my name is {name}, y mi edad es {edad}\")\n\ndates_person(\"bryan\", 27)\n\n\n#4. Funcion con retorno\n\ndef multiply_number(a,b):\n    return a * b\nproducto = multiply_number(4,6)\nprint(f\"The product of 4 an 6 is {producto}\")\n\n\n#5. Funcion dentro de otra funcion\n\ndef outer_function(x):\n    def inner_function(y):\n        return y * 2\n    return inner_function(x) + 3\n\nresult =outer_function(5)\nprint(f\"Result of outer_function(5) is {result}\")\n\n\n\n#6. Uso de una funcion predefinida en python\n\ndef get_length_of_string(s):\n    return len(s)\n\nlength = get_length_of_string(\"python\")\nprint(f\"the length of the string 'Python' is {length}\")\n\n#7. Variables gobales y locales\n\nglobal_variable = 10\n\ndef local_vs_global():\n    global global_variable\n    local_variable = 5\n    global_variable = 20  # Modifica la variable global\n    print(f\"Local variable is {local_variable}\")\n    print(f\"Global variable inside function is {global_variable}\")\n\nlocal_vs_global()\nprint(f\"Global variable outside function is {global_variable}\")\n\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n#  * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n#  *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n#  *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n#  *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n#  *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n#  *\n#  * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n#  * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n\n\ndef extra(text1, text2):\n    array =[]\n    for i in range(1,101):\n        if i  % 3 == 0 & i % 5 == 0:\n            array.append(text1 + text2)\n        elif i % 3 == 0:\n            array.append(text1)\n        elif i % 5 == 0:\n            array.append(text2)\n        else:\n            array.append(i)\n    print(array)\n\nextra(\"mult3\", \"mult5\")\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/buriticasara.py",
    "content": "#FUNCIONES\n\n\"\"\"Funciones definidas por el usuario \"\"\"\n\n#simple\ndef saludo():\n  print('Buenos días')\n\nsaludo()\n\n#con retorno\n\ndef despedida():\n  return('Hasta luego')\n\nprint(despedida())  #cuando tengo return, es necesario imprimir la función para que sí aparezca el resulato\n\n#con argumentos\n\ndef saludo_personal(nombre):\n  print(\"Bienvenida\",nombre)\n\nsaludo_personal(\"Sara\")\n\n#varios argumentos\n\ndef saludo_completo(saludo, nombre):\n  print(f\"{saludo} {nombre}\")\n\nsaludo_completo(\"hola\",\"sara\")\n\n#Con un argumento predeterminado\n\ndef capital(pais=\"Colombia\",capital=\"Bogota\"):\n  return(f\"La capital de {pais} es {capital}\")\n\nprint(capital())\n\n#con un número variable de argumentos\n\ndef inventario(*elementos):\n  for elemento in elementos:\n    print(f\"nombre del elemento: {elemento}\")\n\ninventario(\"silla\",\"mantel\",\"cortina\")\n\n#con un número variable de argumentos y palabra clave\n\ndef informacion(**caracteristicas):\n  for clave, caracteristica in caracteristicas.items():\n    print(f\"{clave}: {caracteristica}\")\n\ninformacion(pais=\"Colombia\", capital=\"Bogota\", gentilicio=\"Colombianos\",continente=\"Latinoamerica\")\n\n# una función dentro de otra función\n\ndef funcion_externa():\n  def funcion_interna():\n    print(\"Hola interno\")\n  funcion_interna()\n\nfuncion_externa()\n\n\"\"\"\nEjemplo de funciones ya creadas\n\"\"\"\n\n#print()\n\nprint('Hola mundo')\n\n#len()\n\nprint(len('Hola mundo'))\n\n#sum()\n\nprint(sum({9,1,8}))\n\n#min()\n\nprint(min({9,1,8}))\n\n#max()\n\nprint(max({9,1,8}))\n\n#type()\n\nprint(type(45.8))\n\n#upper()\n\nprint(\"Hola\".upper())\n\n\"\"\"\nEjercicio extra\n\"\"\"\n\ndef textonumero(texto1,texto2) -> int:\n  count = 0\n  for numero in range(1,101):\n    if (numero % 3) == 0 and (numero % 5) == 0:\n      print(texto1+texto2) \n    elif (numero % 5) == 0:\n      print(texto2)\n    elif (numero % 3) == 0:\n      print(texto1)\n    else: \n      print(numero) \n      count += 1\n  return(count)\n\nprint(textonumero(\"Fizz\",\"Buzz\"))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/byTiagoGhost.py",
    "content": "# Funciones y Alcaneces\r\n# Autor: byTiagoGhost\r\n\r\n# Funciones\r\n# Funcion sin parametros y sin retorno\r\ndef my_function():\r\n  print(\"Hola desde una funcion\")\r\n\r\nmy_function()\r\nprint(\"\")\r\n\r\n# Funcion con parametros o argumento y sin retorno\r\ndef my_function(nombre):\r\n    print(\"Hola \" + nombre)\r\n\r\nmy_function(\"Tiago\")\r\nmy_function(\"Ghost\")\r\nmy_function(\"Santiago\")\r\nprint(\"\")\r\n\r\n# Funcion con mas de un parametro o argumento y sin retorno\r\ndef my_function(nombre, programa):\r\n    print(\"Hola \" + nombre + \" y este es tu programa que esta practicando \" + programa)\r\n\r\nmy_function(\"Tiago\", \"Python\")\r\nmy_function(\"Ghost\", \"Python\")\r\nmy_function(\"Santiago\", \"Python\")    \r\n# Recordatorio o el envio de parametros solo se puede enviar los necesarios o los que se requieran\r\n# Si no sabes cuantos parametros se enviaran puedes usar *args\r\ndef my_function(*nombres):\r\n   print(\"El nombre es \" + nombres[2])\r\n\r\nmy_function(\"Tiago\", \"Ghost\", \"Santiago\")  \r\n# Tabiem puedes enviar parametros con un valor por defecto\r\ndef my_function(nombre1, nombre2, nombre3):\r\n    print(\"Hola ni nombre es: \" + nombre3)\r\n\r\nmy_function(nombre1 = \"Tiago\", nombre2 = \"Ghost\", nombre3 = \"Santiago\")\r\n# Si no sabes cuantas palabras claves hay en el argumento puedes usar **kwargs \r\ndef my_function(**nombres):\r\n    print(\"El nombre comprimido es \" + nombres[\"nombre1\"])\r\n\r\nmy_function(nombre1 = \"Tiago\", nombre2 = \"Ghost\", nombre3 = \"Santiago\")\r\n# Puedes enviar hasta una lista como parametro\r\ndef my_function(comida):\r\n    for x in comida:\r\n        print(x)\r\n\r\ncomida = [\"Manzana\", \"Banana\", \"Fresa\"]\r\nmy_function(comida)\r\nprint(\"\")\r\n\r\n# Funcion con retorno\r\ndef my_function(x):\r\n    return 5 * x\r\n\r\nprint(my_function(3))\r\nprint(my_function(5))\r\nprint(my_function(9))\r\nprint(\"\")\r\n# Si se puede crear una funcion dentro de otra funcion, pero eso si tienes que tener mucho cuidado\r\n# de como funciona, o si tienes claro de como funciona\r\ndef my_function(x):\r\n    def my_function2(y):\r\n        return y * x\r\n    return my_function2\r\n\r\nmydoubler = my_function(2)\r\nmytripler = my_function(3)\r\nprint(mydoubler(11))\r\nprint(mytripler(11))\r\nprint(\"\")\r\n\r\n# Funciones de la propia libreria \r\n# abs() Retorna el valor absoluto de un numero\r\nx = abs(-7.25)\r\nprint(x)\r\nprint(\"\")\r\n# all() Retorna True si todos los elementos de un iterable son verdaderos\r\nx = all([True, True, True])\r\nprint(x)\r\nprint(\"\")\r\n# any() Retorna True si algun elemento de un iterable es verdadero\r\nx = any([True, False, True])\r\nprint(x)\r\nprint(\"\")\r\n# ascii() Retorna una version legible de un objeto\r\nx = ascii(\"Mi nombre es Ståle\")\r\nprint(x)\r\nprint(\"\")\r\n# bin() Convierte un numero en binario\r\nx = bin(36)\r\nprint(x)\r\nprint(\"\")\r\n# bool() Retorna el valor booleano de un objeto\r\nx = bool(0)\r\nprint(x)\r\nprint(\"\")\r\n# bytearray() Retorna un arreglo de bytes\r\nx = bytearray(5)\r\nprint(x)\r\nprint(\"\")\r\n# bytes() Retorna un objeto de bytes\r\nx = bytes(5)\r\nprint(x)\r\nprint(\"\")\r\n# chr() Retorna un caracter representado por el numero\r\nx = chr(97)\r\nprint(x)\r\nprint(\"\")\r\n# max() Retorna el elemento mas grande de un iterable\r\nx = max(5, 10, 25)\r\nprint(x)\r\nprint(\"\")\r\n# min() Retorna el elemento mas pequeño de un iterable\r\nx = min(5, 10, 25)\r\nprint(x)\r\nprint(\"\")\r\n# pow() Retorna el valor de x elevado a la potencia de y\r\nx = pow(4, 3)\r\nprint(x)\r\nprint(\"\")\r\n# round() Redondea un numero\r\nx = round(5.76543, 2)\r\nprint(x)\r\nprint(\"\")\r\n\r\n# Alcances\r\n# Global\r\nx = \"Global\"\r\ndef myfunc():\r\n    print(\"Python es \" + x)\r\n\r\nmyfunc()\r\nprint(\"Python es \" + x)\r\nprint(\"\")\r\n# Local\r\ndef myfunc():\r\n    x = \"Local\"\r\n    print(\"Python es \" + x)\r\n\r\nmyfunc()\r\nprint(\"Python es \" + x)\r\nprint(\"\")\r\n# Global Keyword\r\ndef myfunc():\r\n    global x\r\n    x = \"Global\"\r\n    print(\"Python es \" + x)\r\n\r\nmyfunc()\r\nprint(\"Python es \" + x)\r\nprint(\"\")\r\n\r\n# Ehercicios Practicos\r\nprimerParametro = \"Hola\"\r\nsegundoParametro = \"Mundo\"\r\nglobal Cont\r\ndef numerosEnTexto(primerParametro, segundoParametro):\r\n    Cont = 0\r\n    for x in range(1, 101):\r\n        if x % 3 == 0 and x % 5 == 0: # x % 3 == 0\r\n            print(primerParametro + \" \" +segundoParametro)\r\n            Cont += 1\r\n            continue\r\n        elif x % 3 == 0: # x % 5 == 0\r\n            print(primerParametro)\r\n            Cont += 1\r\n            continue\r\n        elif x % 5 == 0: # x % 3 == 0 and x % 5 == 0\r\n            print(segundoParametro)\r\n            Cont += 1\r\n            continue\r\n        else:\r\n            print(x)\r\n    return Cont\r\n\r\nnumeroDeVeces=numerosEnTexto(primerParametro, segundoParametro)\r\nprint(\"Este fue el numero de veces que se imprimio los dos textos:\", numeroDeVeces)"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/c3sarmx.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n/*\n\"\"\"\n\nprint(\"========== Sin parametro ==========\")\ndef saludo():\n    print(\"Hola!!\")\nsaludo()\n\nprint(\"========== Con parametro ==========\")\ndef saludo(nombre):\n    print(\"Hola!!\", nombre)\nsaludo(\"César\")\n\nprint(\"========== Con mas de un parametro ==========\")\ndef presentacion(nombre, universidad):\n    print(f\"Hola, {nombre}, Bienvenido a {universidad}\")\npresentacion(\"Lio\", \"Hybridge\")\n\nprint(\"========== Con retorno ==========\")\ndef suma(x, y):\n    return x + y\n\nresultado = suma(5, 5)\nprint(\"El resultado de la suma es: \", resultado)\n\ndef calcular_area(b, a):\n    return b * a #* Retornarmos el resultado\n\narea = calcular_area(10, 12) #* Definimos los valores\nprint(\"El área es: \", area)\n\n\"\"\"\nObjetivo: confirmar que una función interna usa algo de la externa.\n\n👉 Crea:\n\t•\tuna función externa\n\t•\tdentro, una variable nombre = \"Lio\"\n\t•\tdentro, una función interna que imprima nombre\n\t•\tla externa debe llamar a la interna\n\t•\tluego llama a la externa\n\"\"\"\n\ndef funcion_externa():\n    usuario = \"Lio\"\n\n    def funcion_interna():\n        print(usuario)\n\n    funcion_interna()\n\nfuncion_externa()\n\n\"\"\"\nObjetivo: ver que la función interna usa el valor actual.\n\n👉 Modifica el reto 1:\n\t•\tantes de llamar a la función interna, cambia nombre a otro valor\n\t•\timprime desde la interna\n\"\"\"\n\ndef funcion_externa():\n    usuario = \"Lio\"\n\n    usuario = \"Lucho\"\n\n    def funcion_interna():\n        print(usuario)\n\n    funcion_interna()\n\nfuncion_externa()\n\n\"\"\"\nObjetivo: descubrir qué NO puede hacer una función interna.\n\n👉 Intenta esto:\n\t•\tmisma estructura\n\t•\tpero ahora, dentro de la función interna, intenta cambiar el valor de la variable externa\n\t•\tluego imprímela fuera\n\"\"\"\n\ndef funcion_externa():\n    usuario = \"Lio\"\n\n    def funcion_interna():\n        usuario = \"Lucho\"\n        print(\"Desde la función interna:\", usuario)\n\n    funcion_interna()\n\n    print(\"Fuera de la interna:\", usuario)\n\nfuncion_externa()\n\n\"\"\"\n🧩 MINI-RETO A — “Usar” (leer, no cambiar)\n\nObjetivo: comprobar que usar funciona.\n\nInstrucciones\n\t1.\tFunción externa con mensaje = \"Hola\"\n\t2.\tFunción interna que imprima mensaje\n\t3.\tLlama a la interna y luego a la externa\n\t4.\t❌ No reasignes mensaje en ningún lado\n\"\"\"\n\ndef externa():\n    mensaje = \"Hola\"\n\n    def interna():\n        print(mensaje)\n\n    interna()\n\nexterna()\n\n\"\"\"\n🧩 MINI-RETO B — “Reasignar” (crear otra variable)\n\nObjetivo: ver el límite al reasignar.\n\nInstrucciones\n\t1.\tMisma estructura que el reto A\n\t2.\tDentro de la función interna, escribe: mensaje = \"Adiós\"\n\t3.\tImprime mensaje dentro de la interna\n\t4.\tImprime mensaje después de llamar a la interna (aún dentro de la externa)\n\"\"\"\n\ndef externa():\n    mensaje = \"Hola\"\n\n    def interna():\n        mensaje = \"Adiós\"\n        print(\"Dentro de la función interna:\", mensaje)\n\n    interna()\n    print(\"Fuera de la funcion:\", mensaje)\nexterna()\n\nprint(\"========== Global y Local ==========\")\n\n\"\"\"\n🧩 RETO 2.1 — Leer una global (seguro)\n\nObjetivo: comprobar que leer una global no rompe nada.\n\n👉 Haz esto:\n\t•\tCrea una variable global mensaje = \"Hola\"\n\t•\tCrea una función que solo imprima mensaje\n\t•\tLlama a la función\n\"\"\"\nmensaje_variable_global = \"Hola\"\ndef mostrar_mensaje():\n    print(mensaje_variable_global)\n\nmostrar_mensaje()\nprint(\"Mensaje fuera de la función:\", mensaje_variable_global)\n\n\n\"\"\"\nFunciones Built-in\n\"\"\"\nprint(\"== len ==\")\n\nnombres = [\"Lio\", \"Ana\", \"Max\"]\nprint(len(nombres))  # len nos retorna la cantidad de letras o elementos de una variable\n\nprint(\"== type ==\")\n\nedad = 18\nprint(type(edad))\n\nmensaje = \"Hola\"\nprint(type(mensaje)) # type nos retorna el tipo de dato de la variable, 'int' 'str' 'boolean' 'float'\n\nprint(\"== sum ==\")\n\nnumeros = [10, 20, 30]\nprint(sum(numeros))\n\nprint(\"== max y min ==\")\n\ncalificaciones = [9, 5, 6, 10]\nprint(max(calificaciones))\nprint(min(calificaciones)) # Esto nos da el numero mas alto o mas bajo, solo funciona con int o float\n\nprint(\"== abs ==\")\n\nbalance = -1290\nprint(abs(balance)) # Nos convierte a un numero positivo\n\nprint(\"== enumerate ==\")\n\nfrutas = [\"manzana\", \"pera\", \"uva\"]\n\nfor indice, fruta in enumerate(frutas):\n    print(indice, fruta) # Nos da el indice + valor\n\nprint(\"== sorted ==\")\n\nnumeros = [3, 1, 4]\nprint(sorted(numeros))\nprint(numeros) # Nos ordena los datos de menos a mas\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n * - Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n * - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n * - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n * - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n * - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\"\"\"\n\ndef funcion(txt1, txt2):\n    contador = 0\n    for number in range(1, 101):\n        if number % 3 == 0 and number % 5 == 0:\n            print(txt1 + txt2)\n        elif number % 3 == 0:\n            print(txt1)\n        elif number % 5 == 0:\n            print(txt2)\n        else:\n            print(number)\n            contador += 1\n    return contador\n\nprint(funcion(\"Fizz\", \"Buzz\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/caleb699-hub.py",
    "content": "#funcion sin parametro ni retorno\n\n\n\ndef hola_mundo():\n    print(\"!Hola Mundo¡\")\n\nhola_mundo()\n\n\n#con parametros y con retorno\n\ndef suma_numeros(num1,num2):\n    return num1 + num2\n\nprint(suma_numeros(5,6))\n\n\n#funcion dentro de una funcion\n\ndef funcion_de_afuera():\n    def funcion_de_adentro():\n        print(\"!Hola a todos desde la función de adentro¡\")\n    funcion_de_adentro()\n    print(\"!Hola a todos desde la función de afuera¡\")\n\nfuncion_de_afuera()\n\n\n#Funciones lambda\nfuncion_lambda = lambda x,y: x * y\n\nprint(funcion_lambda(5,3))\n\n\n#funciones del lenguaje\n\nlista_numeros = [1,2,3,4,5]\n#round\nprint(round(lista_numeros[2]/lista_numeros[4]))\n#sum\nprint(sum(lista_numeros))\n#pow\nprint(pow(lista_numeros[4],lista_numeros[1]))\n#len\nprint(len(lista_numeros))\n#list y map\nprint(list(map(lambda x:x +1,lista_numeros)))\n#type\nprint(type(lista_numeros))\n\n\n#variable global y variable local\n\nvariable_global = \"!Hola¡\"\ndef funcion_random():\n    variable_local = \"!Adios¡\"\n    print(f\"{variable_global}, {variable_local}\")\nfuncion_random()\n\n\n\n\"\"\"\nDificultad extra\n\"\"\"\n\n\ndef imprimir_numeros(texto1, texto2):\n    contador = 0\n    for numero in range(1,101):\n        if numero % 3 == 0 and numero % 5 == 0:\n            print(f\"El número es {texto1}, el número es {texto2}\")\n        elif numero % 3 == 0:\n            print(f\"El número es {texto1}\")\n        elif numero% 5 == 0:\n            print(f\"El número es {texto2}\")\n        else:\n            print(numero)\n            contador +=1\n    print(f\"El número se imprimió {contador} veces\")\n\n\nimprimir_numeros(\"múltliplo del 3\", \"múltiplo del 5\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/camilo-zuluaga.py",
    "content": "# #02 FUNCIONES Y ALCANCE\n\nprint(\"-Funciones-\\n\")\n\n\n# Sin parametros ni retorno\ndef saludar():\n    print(\"Hola Mundo!\")\n\n\nsaludar()\n\n\n# Con uno o varios parametros\ndef saludar_usuario(nombre, apellido):\n    print(f\"Hola {nombre} {apellido}!\")\n\n\nsaludar_usuario(\"Camilo\", \"Zuluaga\")\n\n\n# Con retorno\ndef suma(a, b):\n    return a + b\n\n\nresultado = suma(1, 2)\nprint(resultado)\n\n\n# Funciones dentro de funciones\nprint(\"-Funciones dentro de funciones-\\n\")\n\n\ndef function1():\n    print(\"Hola desde la funcion 1\")\n\n    def function2():\n        print(\"Hola desde la funcion 2 (Anidada)\")\n\n    function2()\n\n\nfunction1()\n\n# Funciones lambda\nx = lambda a, b: a * b  # Función lambda que multiplica dos números\nprint(x(5, 6))\n\n# Funciones creadas por el lenjuage\nprint(\"-Funciones creadas por el lenjuage-\\n\")\n# Ejemplo de sum(), max(), min()\n\n# Sumar numeros de una lista, encontrar el mayor y el menor\narr = [1, 2, 3, 4, 5, 6, 7, 8, 9]\n# sum() suma los números de una lista\n# max() retorna el número mayor de una lista\n# min() retorna el número menor de una lista\nprint(\n    f\"\"\"\nSuma de los números: {sum(arr)}\nNúmero mayor del array: {max(arr)}\nNúmero menor del array {min(arr)}\n    \"\"\"\n)\n\n# Variables locales y globales en funciones\n# Variables locales: Son aquellas que se declaran dentro de una función y solo son accesibles dentro de la misma.\n# Variables globales: Son aquellas que se declaran fuera de una función y son accesibles desde cualquier parte del código.\nprint(\"-Variables locales y globales en funciones-\\n\")\n\n\ndef foo():\n    # Variable local\n    s = \"Hola Mundo!\"\n    print(s)\n\n\nfoo()\n\n# print(s) nos daria -> Error, la variable s no existe fuera de la función foo()\n\na = \"Soy una variable global\"\n\n\ndef func():\n    print(a)\n\n\nfunc()\n\n\n# Palabra reservada global\ndef myfunc():\n    global x  # Si utiliza la palabra clave global, la variable pertenece al ámbito global\n    x = \"genial!\"\n\n\nmyfunc()\n\nprint(\"Python is \" + x)\n\n\n# DIFICULTAD EXTRA\ndef exercise(a, b):\n    contador = 0\n    for i in range(1, 101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(f\"{a}{b}\")\n        elif i % 3 == 0:\n            print(a)\n        elif i % 5 == 0:\n            print(b)\n        else:\n            print(i)\n            contador += 1\n    return contador\n\n\nresultado = exercise(\"Python\", \"Numpy\")\nprint(\n    f\"Número de veces que se ha impreso el número en lugar de los textos: {resultado}\"\n)\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/carlosalberto05.py",
    "content": "'''\nFunciones definidas por el usuario\n'''\n\n#Simple y con argumentos\ndef saludo(name):\n\tprint(\"Hola \" + name)\n \nsaludo(\"Carlos\")\n\n#Con retorno y argumentos\ndef return_greet(name):\n    return \"Hola \" + name\n\ngreet = return_greet(\"Roberto\")\nprint(greet)\n\n#Funcion con argumentos\ndef sum(a,b):\n    return f\"La suma es: {a + b}\"\n\nprint(sum(3,9))\n\n#Funcion con argumentos y valores por defecto\ndef mul(a = 2,b = 2):\n    return f\"La suma es: {a * b}\"\n\nprint(mul(3))\n\n#Funcion con argumentos y valores por defecto en distinto orden\ndef mul(a = 2,b = 2):\n    return f\"La suma es: {a / b}\"\n\nprint(mul(b=3, a=9))\n\n#Funcion con retorno de varios valores\ndef multiple_return():\n    return \"Juan\", \"Pedro\"\n\nprint(multiple_return())\n\nname_one, name_two = multiple_return()\nprint(name_one)\nprint(name_two)\n\n#Funciones con un número variable de argumentos\ndef variable_arg(*names):\n    for name in names:\n        print(f\"Hola, {name}!\")\n        \nvariable_arg(\"Python\", \"JavaScript\", \"Swift\")\n\n#Funciones con un número variable de argumentos pero con palabras clave\ndef variable_key_arg(**names):\n    for key, name in names.items():\n        print(f\"Hola, {name} ({key})!\")\n        \nvariable_key_arg(language = \"Python\", lang = \"JavaScript\", apple =\"Swift\")\n\n'''\nFunciones dentro de funciones\n'''\n\ndef outer_function():\n    def inner_function():\n        print(\"Función interna: Hola Charly\")\n    inner_function() \n\nouter_function()\n\n'''\nFunciones del lenguaje\n'''\n\nprint() #print es una función de python\nprint(len(\"carlos\")) #len también es una función de python como el length de js\nprint(type(3)) #type nos dice el tipo de dato como typeof de js\nprint(\"carlos\".upper()) #es otra función de python similar a upperCase de js\n\n\n'''\nVariables locales y globales\n'''\n\nglobal_var = \"python\"\n\nprint(global_var)\n\ndef hello_python():\n    local_var = \"Hola\"\n    print(f\"{local_var},{global_var}\")\n    \n\n#print(local_var) no se puede acceder desde fuera de la función por que es local\nprint(global_var)\n    \nhello_python()\n\n\n'''\nExtra\n'''\n\ndef print_number(str1, str2):\n    count = 0\n    for number in range(1,101):\n        if number % 3 == 0 and number % 5 == 0:\n            print(f\"{str1} {str2}\")\n        elif number % 3 == 0 :\n            print(str1)\n        elif number % 5 == 0: \n            print(str2)\n        else :\n            print(number)\n            count += 1\n    return count\n    \n\nprint(print_number(\"Fizz\", \"Buzz\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/carrenoalexander.py",
    "content": "\"\"\"\n * Funciones\n\"\"\"\n\n# Simple\n\ndef language():\n    print(\"Python\")\n\nlanguage()\n\n# Con retorno\n\ndef return_language():\n    return \"Python\"\n\nprint(return_language())\n\n# Con multiples retornos\n\ndef multiple_return_language():\n    return \"This is\", \"Python\"\n\ntext, language = multiple_return_language()\n\nprint(text)\nprint(language)\n\n# Con un argumento\n\ndef argument_language(language):\n    print(\"The language is\", language)\n\nargument_language(\"Python\")\n\n# Con varios argumentos\n\ndef arguments_language(language, version):\n    print(f\"The language is {language} and the version is {version}\")\n\narguments_language(\"Python\", \"3.12.3\")\n\n# Con un argumento predeterminado\n\ndef default_argument_language(language=\"not JavaScript\"):\n    print(\"The language is\", language)\n\ndefault_argument_language()  # not JavaScript\ndefault_argument_language(\"Python\")\n\n# Con argumentos posicionales\n\ndef positional_arguments_language(language, version):\n    print(f\"The language is {language} and the version is {version}\")\n\npositional_arguments_language(version=\"3.12.3\", language=\"Python\")\n\n# Con un numero de variables de argumentos (args)\n\ndef args_language(*languages):\n    for language in languages:\n        print(language)\n\nargs_language(\"Python\", \"JavaScript\", \"TypeScript\")\n\n# Con un nuemero de argumentos de palabras clave (kwargs)\n\ndef kwargs_language(**languages):\n    for key, value in languages.items():\n        print(f\"{key}: {value}\")\n\nkwargs_language(language_1=\"Python\", language_2=\"JavaScript\", language_3=\"TypeScript\")\n\n# Funciones dentro de funciones\n\ndef other_function():\n    def inside_function():\n        print(\"Inside function\")\n\n    inside_function()\n\nother_function()\n\n# Algunas funciones ya creadas del lenguaje\n\nprint(\"Hello\")\nprint(type(\"Hello\"))\nprint(len(\"Hello\"))\nprint(\"Hello\".upper())\nprint(\"Hello\".replace(\"Hello\", \"HI\"))\n\n# Variable LOCAL y GLOBAL\n\nglobal_variable = \"Global variable\"\n\ndef scope():\n    local_variable = \"Local variable\"\n    print(f\"{local_variable} and {global_variable}\")\n\nprint(global_variable)\n# print(local_variable)  # No se puede acceder a la variable local\n\nscope()\n\n\"\"\"\n * Extra\n\"\"\"\n\ndef extra(text_1, text_2):\n    count = 0\n    for number in range(1, 101):\n        if number %3 == 0 and number %5 == 0:\n            print(text_1, text_2)\n        elif number %3 == 0:\n            print(text_1)\n        elif number %5 == 0:\n            print(text_2)\n        else:\n            print(number)\n            count += 1\n    return count\n\nprint(extra(\"This is\", \"Python\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/cbuenrostrovalverde.py",
    "content": "'''\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */'\n '''\n\n# Función sin parámetros ni retorno.\n\ndef saludar():\n    print('Hola')\n\n# Función con uno o varios parámetros.\n\ndef saludarNombre(nombre):\n    print(f'Hola {nombre}')\n\ndef suma(val1, val2):\n    return val1 + val2\n\n'''\nCuando existe return dentro de la función, realizará el cálculo, pero no lo imprime por consola.\nPara ello lo que tenemos que hacer es, si queremos el resultado, poner un print. print(suma(5, 5))\n'''\n\n# Funciones dentro de funciones:\n\ndef crear_saludo_personalizado(idioma):\n    def saludar(nombre):\n        if idioma == 'es':\n            print(f'Hola {nombre}')\n        elif idioma == 'en':\n            print(f'Hello {nombre}')\n        elif idioma == 'fr':\n            print(f'Bonjour {nombre}')\n        else:\n            print('Idioma no soportado. Prueba con uno existente.')\n    return saludar\n\n# Crear funciones personalizadas\nsaludo_en_español = crear_saludo_personalizado(\"es\")\nsaludo_en_ingles = crear_saludo_personalizado(\"en\")\nsaludo_en_frances = crear_saludo_personalizado(\"fr\")\nsaludo_en_chino = crear_saludo_personalizado(\"cn\")\n\n# Ejemplo\nsaludo_en_español(\"Carlos\")\nsaludo_en_ingles(\"Carlos\")\nsaludo_en_chino(\"Carlos\")\n\n# Funciones ya creadas en Python3\n\n#print\nprint('Hola Mundo')\n\n# max()\nprint(max(5, 4, 6, 12, 20))\n\n# min()\nprint(min(5, 4, 6, 12, 20))\n\n# upper()\nprint('estoy aprendiendo python'.upper())\n\n# Prueba de variable LOCAL y GLOBAL\ncontador = 0\n\ndef incrementar():\n    global contador  # ahora sí modificamos la global\n    contador += 1\n    print(contador)\n\nincrementar()\nincrementar()\n\n'''\nDIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n '''\n\ndef numero_texto(text1, text2):\n    count = 0\n    for numero in range(1, 101):\n        if numero % 3 == 0:\n            print(text1)\n        elif numero % 5 == 0:\n            print(text2)\n        elif numero % 3 == 0 and numero % 5 == 0:\n            print(text1 + text2)\n        else:\n            count += 1\n    return count\n\nnumero_texto('Hello', 'World')"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/cdbiancotti.py",
    "content": "from typing import List, Dict, Callable\n\n# /*\n#  * EJERCICIO:\n#  * - Crea ejemplos de funciones básicas que representen las diferentes\n#  *   posibilidades del lenguaje:\n#  *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n#  * - Comprueba si puedes crear funciones dentro de funciones.\n#  * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n#  * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n#  * - Debes hacer print por consola del resultado de todos los ejemplos.\n#  *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n\nprint('\\n=== Variaciones a en la definicion de una funcion ===\\n')\n\n\ndef func1() -> None:\n    print('funcion sin parametros ni retorno', 1 + 2)\n\n\ndef func2(a: int, *args: List[int], b=3, **kwargs: Dict[str, int]) -> int:\n    return a + sum(args) + b + sum([num for num in kwargs.values()])\n\n\nfunc1()\nprint('funcion con parametros por posicion, por nombre, indefinidos (*args, **kwargs), con valor por defecto,'\n      ' con return. Resultado de ejecucion:', func2(2, 2, 5, 3, 5, 4, 76, 3, 2, 3, 4, c=15, z=35, f=62))\n\nprint('Muestra de una funcion anonima. Resultado:', (lambda x: x ** 2)(5))\n\nprint('\\n=== Definir una funcion dentro de otra ===\\n')\n\n\ndef out_function() -> Callable:\n    print('out_function')\n\n    def in_function() -> None:\n        print('funcion interna de out_function')\n\n    return in_function\n\n\nfunction_from_inside = out_function()\nfunction_from_inside()\n\nprint('\\n=== Uso de una funcion built-in ===\\n')\nprint('ejecucion de \"max(1,2,3)\":', max(1, 2, 3))\n\nprint('\\n=== Prueba de variable Local y Global ===\\n')\nglobal_variable_1: str = 'variable global 1'\nglobal_variable_2: str = 'variable global 2'\n\n\ndef change_global_variable() -> None:\n    global global_variable_1\n    global_variable_1 = 'new data from change_global_variable'\n    print('Se puede llamar a una variable de un scope superior al de la funcion. Resultado:', global_variable_2)\n    local_variable: str = 'Soy una variable local de la funcion.'\n\n\nchange_global_variable()\nprint('global_variable_1 modificada desde dentro de la funcion gracias al la sentencia \"global\". Resultado:',\n      global_variable_1)\ntry:\n    print(local_variable)\nexcept Exception:\n    print('No se puede llamar a una variable local de una funcion desde fuera de la misma.')\n\nprint('\\n=== Dificultad extra ===\\n')\n\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n#  * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n#  *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n#  *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n#  *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n#  *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\ndef custom_1_to_100(val1: str, val2: str) -> int:\n    count_of_printed_numbers: int = 0\n    for num in range(1, 101):\n        multiple_of_3: bool = num % 3 == 0\n        multiple_of_5: bool = num % 5 == 0\n        if multiple_of_3 and multiple_of_5:\n            print(val1 + val2)\n        elif multiple_of_3:\n            print(val1)\n        elif multiple_of_5:\n            print(val2)\n        else:\n            print(num)\n            count_of_printed_numbers += 1\n    return count_of_printed_numbers\n\n\nresult = custom_1_to_100('multiple of 3', 'multiple of 5')\nprint('La cantidad de numeros printeada fue', result)\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/cesar-ch.py",
    "content": "# Función sin parámetros ni retorno\ndef saludar():\n    print(\"¡Hola, mundo!\")\n\nsaludar()\n\n# Función con un parámetro y retorno\ndef cuadrado(numero):\n    return numero ** 2\n\nresultado_cuadrado = cuadrado(5)\nprint(\"Cuadrado de 5:\", resultado_cuadrado)\n\n# Función con varios parámetros y retorno\ndef suma(a, b):\n    return a + b\n\nx = 3\ny = 7\nresultado_suma = suma(x, y)\nprint(f\"Suma de {x} y {y}:\", resultado_suma)\n\n# Función dentro de una función\ndef operacion_matematica(x, y):\n    def cuadruple(num):\n        return num * 4\n\n    resultado1 = cuadruple(x)\n    resultado2 = cuadruple(y)\n\n    return resultado1 + resultado2\n\nresultado_operacion = operacion_matematica(2, 3)\nprint(\"Resultado de operación compleja:\", resultado_operacion)\n\n# Variable local y global\nvariable_global = 10\n\ndef funcion_con_variables():\n    variable_local = 5\n    print(\"Variable local dentro de la función:\", variable_local)\n    print(\"Variable global dentro de la función:\", variable_global)\n\nfuncion_con_variables()\nprint(\"Variable global fuera de la función:\", variable_global)\n\n# DIFICULTAD EXTRA\ndef imprimir_numeros_con_texto(texto1, texto2):\n    contador = 0\n\n    for i in range(1, 101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(texto1 + texto2)\n        elif i % 3 == 0:\n            print(texto1)\n        elif i % 5 == 0:\n            print(texto2)\n        else:\n            print(i)\n            contador += 1\n\n    return contador\n\nveces_impreso = imprimir_numeros_con_texto(\"Fizz\", \"Buzz\")\nprint(\"Número de veces impreso:\", veces_impreso)\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/cevicheconaji.py",
    "content": "'''EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.'''\n \n# Función simple\n\ndef holaSoyUnaFuncion():\n    print(\"Hola, soy una función\")\n\n# Ejecución de la función\nholaSoyUnaFuncion() \n\n# Funcion con parametros\n\ndef getNombreCompleto(nombre, apellido):\n    return f\"{nombre} {apellido}\"\n\n# Ejecución de la función con parametros\n\nprint(getNombreCompleto(\"Piero\", \"Zavala\"))\n\n# Funcion con parametros por defecto\n\ndef getNombreCompleto(nombre = \"Piero\", apellido = \"Zavala\"):\n    return f\"{nombre} {apellido}\"\n\n# Ejecución de la función con parametros por defecto\n\nprint(getNombreCompleto())\n\n# Funcion dentro de una función\n\ndef caminar():\n    def moverLasPiernas():\n        print(\"Moviendo las piernas\")\n    moverLasPiernas()\n    print(\"Caminando\")\n\n# Ejecución de la función dentro de una función\ncaminar()\n\n# Funcion del lenguaje\n\ndef obtenerMaximo(lista):\n    return max(lista)\n\n# Variable global\n\na = 0\n\ndef suma_uno():\n    global a\n    a = a + 1\n\nsuma_uno()\nprint(a)\n\n# variable local\n\ndef suma_uno_local():\n    a = 0\n    a = a + 1\n    print(a)\n\nsuma_uno_local()\n\n# Dificultad extra\n\ndef imprimirNumerosMultiplos(texto1, texto2):\n    for i in range(1, 101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(f\"{texto1}{texto2}\")\n        elif i % 3 == 0:\n            print(texto1)\n        elif i % 5 == 0:\n            print(texto2)\n        else:\n            print(i)\n    return i\n\nimprimirNumerosMultiplos(\"Fizz\", \"Buzz\")\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/clainu04.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * - Crea ejemplos de funciones básicas que representen las diferentes\n#  *   posibilidades del lenguaje:\n#  *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n#  * - Comprueba si puedes crear funciones dentro de funciones.\n#  * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n#  * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n#  * - Debes hacer print por consola del resultado de todos los ejemplos.\n#  *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n#  * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n#  *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n#  *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n#  *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n#  *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n#  *\n#  * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n#  * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n#  */\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/clmiranda.py",
    "content": "# Funciones sin parámetros ni retorno\ndef hello():\n    print(\"Hello World from Python\")\n\nhello()\n\n\nfrom datetime import datetime\ndef actual_date():\n    now = datetime.now()\n    print(now.strftime(\"%d/%m/%Y\"))\n\nactual_date()\n\n\n# Funciones con parámetros y retorno\ndef even_numbers(lst: [int]) -> [int]:\n    return [i for i in lst if i % 2 == 0]\n\nprint(even_numbers([3, 8, 19, 28, 46, 105, 17, 34, 79]))\n\n\n# Funciones anidadas\ndef calculate_discount(price: float, discount: int) -> float:\n    return price - price * float(f'0.{discount}')\n\ndef calculate_total_price(product: str, price: float, discount: int) -> str:\n    discount_applied = calculate_discount(price, discount)\n    return f\"The {product} price with the discount applied is {round(discount_applied, 2)}\"\n\nprint(calculate_total_price(\"laptop HP\", 4700.90, 15))\n\n\n# Funciones propias de Python\nvalues = [17, 4, 89, 103, 45, 28, 70, 8]\n\nprint(f\"Valor mínimo: {min(values)}, Valor maximo: {max(values)}\")\nprint(sorted(values, reverse=True))\n\n\n# Variable Local\nvar_local = \"Esta es una variable local fuera de una función\"\ndef funcion_local():\n    var_local = \"Hola Mundo desde una función con variable local\"\n    print(var_local)\n\nprint(var_local)\nfuncion_local()\n\n\n# Variable Global\nvar_global = \"Esta es una variable global\"\ndef funcion_global():\n    global var_global\n    var_global = \"Este es el nuevo valor de la variable global\"\n    print(var_global)\n\nfuncion_global()\nprint(var_global)\n\n\n# Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\ndef reto(txt1: str, txt2: str) -> int:\n    counter = 0\n    for i in range(1, 101):\n        if i % 3 == 0:\n            print(txt1)\n        elif i % 5 == 0:\n            print(txt2)\n        elif i % 3 == 0 and i % 5 == 0:\n            print(f\"{txt1}{txt2}\")\n        else:\n            print(i)\n            counter += 1\n    return counter\n\nprint(f\"Cantidad de veces que se han impreso números en lugar de textos: {reto(\"Hello\", \"World\")}\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/cristianfloyd.py",
    "content": "print(\"Funciones en Python\")\n\n\n# * - Crea ejemplos de funciones básicas que representen las diferentes\n# *   posibilidades del lenguaje:\n# *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n\n# Función sin parámetros y sin valor de retorno\ndef saludo():\n    print(\"Hola, bienvenido a las funciones en Python\")\n\nsaludo()\n\n# Función con un parámetro y sin valor de retorno\ndef imprimir_cuadrado(numero):\n    print(f\"El cuadrado de {numero} es {numero ** 2}\")\n\nimprimir_cuadrado(4)\n\nprint(\"=\"*80)\nprint(\"Función con varios parámetros y sin valor de retorno\")\ndef imprimir_suma(a, b):\n    suma = a + b\n    print(f\"La suma de {a} y {b} es {suma}\")\n\nimprimir_suma(3, 5)\n\nprint(\"=\"*80)\nprint(\"Función con un parámetro y con valor de retorno\")\ndef calcular_cuadrado(numero):\n    return numero ** 2\n\nresultado_cuadrado = calcular_cuadrado(6)\nprint(f\"El cuadrado de 6 es {resultado_cuadrado}\")\n\nprint(\"=\"*80)\nprint(\"Función con varios parámetros y con valor de retorno\")\ndef calcular_potencia(base, exponente):\n    return base ** exponente\n\nresultado_potencia = calcular_potencia(2, 3)\nprint(f\"2 elevado a la potencia 3 es {resultado_potencia}\")\n\n# funcion con multiples parametros y 1 retorno\nprint(\"=\"*80)\nprint(\"Función con múltiples parámetros y un valor de retorno\")\ndef multiples_parametros(*args):\n    return sum(args)\n\nmultiples_parametros_resultado = multiples_parametros(1, 2, 3, 4, 5)\nprint(f\"La suma de los parámetros es {multiples_parametros_resultado}\")\n\n# * - Comprueba si puedes crear funciones dentro de funciones.\n\nprint(\"=\"*80)\nprint(\"Funciones dentro de funciones\")\ndef funcion_externa(x):\n    # creo una funcion interna\n    def duplicar(y):\n        return y * 2\n    return duplicar(x) + 3\n\nresultado_funcion_interna = funcion_externa(5)\nprint(f\"El resultado de la función externa es {resultado_funcion_interna}\")\n\n# * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n\nprint(\"=\"*80)\nprint(\"Variables LOCAL y GLOBAL\")\n\nvariable_global = \"Soy una variable global\"\ndef mostrar_variables():\n    variable_local = \"Soy una variable local\"\n    print(variable_local)  # Accediendo a la variable local\n    print(variable_global)  # Accediendo a la variable global\n\nmostrar_variables()\n\n# Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n\nprint(\"=\"*80)\nprint(\"Uso de funciones integradas de Python\")\nnumeros = [5, 2, 9, 1, 5, 6]\nprint(f\"Números originales: {numeros}\")\nnumeros_ordenados = sorted(numeros)\nprint(f\"Números ordenados: {numeros_ordenados}\")\n\nlongitud = len(numeros)\nprint(f\"La longitud de la lista es {longitud}\")\nmayor_numero = max(numeros)\nprint(f\"El número mayor es {mayor_numero}\")\nmenor_numero = min(numeros)\nprint(f\"El número menor es {menor_numero}\")\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n#  * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n#  *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n#  *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n#  *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n#  *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\nprint(\"=\"*80)\n\nprint(\"Función FizzBuzz personalizada\")\ndef mi_fizzbuzz(texto1: str, texto2: str) -> int:\n    contador = 0\n    for index in range(1, 101):\n        if index % 15 == 0:\n            print(texto1 + texto2, end=\"\")\n        elif index % 3 == 0:\n            print(texto1, end=\"\")\n        elif index % 5 == 0:\n            print(texto2, end=\"\")\n        if index % 3 != 0 and index % 5 != 0:\n            print(index, end=\"\")\n        else:\n            contador += 1\n        print()  # Nueva línea después de cada número o texto\n    return contador\n\nveces_numeros = mi_fizzbuzz(\"Fizz\", \"Buzz\")\nprint(f\"Números impresos en lugar de textos: {veces_numeros}\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/d0ubt0.py",
    "content": "#Funciones con retorno y sin retorno\ndef hola():\n    print('hola')\n\ndef hola_con_retorno():\n    return 'hola'\n\nprint(hola_con_retorno())\n\n#Funcion con varios parametros\nn1 = 3\nn2 = 6\ndef sumar_dos(n1,n2):\n    return n1 + n2\n\nprint(sumar_dos(n1,n2))\n\n#Funciones dentro de funciones\ndef sumar_funciones():\n    x = 0\n    def sumar1(x):\n        return x + 1\n    def sumar2(x):\n        return x + 2\n    return (sumar1(x) + sumar2(x))\n\nprint(sumar_funciones())\n\n#Global y Local\nx = 35\nz = 25\n\ndef global_local():\n    global x\n    x = 0\n    z = 0\n\n\nprint('x:',x ,'z:', z)\nglobal_local()\nprint('x:',x ,'z:', z)\n\n#Funcion de Python\nlista = [i for i in range(1, 51)]\nmapa = filter(lambda x: x% 2 == 0, lista)\nprint(list(mapa))\n\n\ndef extra(str1,str2):\n    count = 0\n    for i in range(1,101):\n        print(i)\n        if i % 15 == 0:\n            count +=1\n            print(str1,str2)\n        elif i % 3 == 0:\n            count +=1\n            print(str1)\n        elif i % 5 == 0:\n            count +=1\n            print(str2)\n    return count\n\ntimes = extra('xd','uwu')\nprint('veces' , times)"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/dandrusco.py",
    "content": "\"\"\"\nEJERCICIO:\nCrea ejemplos de funciones básicas que representen las diferentes posibilidades del lenguaje:\nSin parámetros ni retorno, con uno o varios parámetros, con retorno...\n\"\"\"\n# Sin parámetros ni retorno:\ndef saludar():\n    print(\"¡Hola, mundo!\")\n\nsaludar()\n\n# Con un parámetro y sin retorno:\ndef cuadrado(numero):\n    resultado = numero ** 2\n    print(f\"El cuadrado de {numero} es {resultado}\")\n\ncuadrado(5)\n\n# Con varios parámetros y retorno:\ndef sumar(a, b):\n    resultado = a + b\n    return resultado\n\nresultado_suma = sumar(3, 7)\nprint(f\"La suma es: {resultado_suma}\")\n\n# Sin parámetros con retorno:\ndef obtener_numero():\n    return 42\n\nnumero = obtener_numero()\nprint(f\"El número obtenido es: {numero}\")\n\n\"\"\"\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n\"\"\"\ndef funcion_exterior(x):\n    # Variable local a la función exterior\n    y = 10\n\n    def funcion_interior():\n        # Variable local a la función interior\n        z = 5\n        # Accede a la variable local de la función exterior y a la variable global\n        resultado = x + y + z + variable_global\n        return resultado\n\n    # Llama a la función interior\n    resultado_interior = funcion_interior()\n    print(f\"Resultado interior: {resultado_interior}\")\n\n# Variable global\nvariable_global = 20\n\n# Llama a la función exterior\nfuncion_exterior(15)\n\n# Intenta acceder a la variable local de la función interior (causará un error)\n# print(z)  # Esto causará un error porque 'z' es local a la función interior\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\"\"\"\nprint(\"----------------DIFICULTAD EXTRA--------------\")\n\ndef imprimir_numeros_y_contar(texto1, texto2):\n    contador = 0\n\n    for numero in range(1, 101):\n        if numero % 3 == 0 and numero % 5 == 0:\n            print(texto1 + texto2)\n        elif numero % 3 == 0:\n            print(texto1)\n        elif numero % 5 == 0:\n            print(texto2)\n        else:\n            print(numero)\n            contador += 1\n\n    return contador\n\nresultado = imprimir_numeros_y_contar(\"Fizz\", \"Buzz\")\nprint(f\"Se imprimieron {resultado} números en total.\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/daniel-sanabria0419.py",
    "content": "#FUNCIONES Y ALCANCE\n''''\nlas funciones definidas por el usuario en python son objetos que se pueden instasear en \ncualquiera parte del codigoestas pueden recibir unos paraemtros y tambien pueden retornar un parametro \n'''\n\n\nnumero = 10\n\n#01-funcion simple\ndef saludar():\n    print(\"hola!\") #esta funcion retorna un saludo\n\n\n#02-funcion con argumentos de entrada sin retorno\ndef suma(a): \n     x = a+2\n     print(x) #esta funcion recibe un numero y le suma 2 y lo imprime\n\n\n#03- funcion con mas de un parametro\n\ndef sumar(a,b):\n    print(a+b)\n\n\n#04-funcion con returno\ndef obtener_pi():\n    return 3.1416\n\n\n#05-funcion con parametro y returno\ndef cuadrado(a):\n    result = a ** 2\n    return result\n\n\n\n#06-funcion con varios parametros y returno\ndef calculator(number_one, number_tow):\n    calculator_result = number_one * number_tow\n    return calculator_result\n\n\n#07-funcion con parapemtros predefinidos\ndef suma_iva(precio,iva=0.19):\n    result = precio *(1+iva)\n    return result\n\n#08-funcion con parametros infedinidos\ndef sumar_todos(*numeros):\n    return sum(numeros)\n\n\n#09-funcion con mas de un return\ndef saludo_adios(saldu=\"hola\",despedida=\"adios\"):\n    return saldu,despedida\n\nhello, goodbye = saludo_adios(\"adios\",\"hola\")\n\n\n\n#funciones dentro de funciones\n\ndef nombre(nombre):\n    def saludar():\n        return \"hola\" + nombre\n    return saludar()\n\n\n#ejemplo de funciones ya creadas en el lenguaje\n\nprint(len(\"hola como estas\"))   #aca hay dos funciones, print y len \n\n#una variable global es aquella que se declara fuera de una funcion y se tiene\n#acceso en todo el codigo pero las variables declaradas dentro de una funcion\n#solo se tiene acceso dentro de esa funcion\n\ncontador = 1\n\ndef contador():\n    contador += 1\n    return contador\n\n\n#solucion de reto con funcion de argumentos predeterminados\ndef reto(string_one=\"es multiplo de 3\",string_tow=\"es multiplo de 5\"):\n\n    contador = 0\n    for i in range(100):\n        if i % 3 == 0  and   i % 5 ==0:\n            print(string_one, \" y \",string_tow )\n        elif i % 3 == 0:\n            print(string_one)\n        elif i % 5 == 0:\n            print(string_tow)\n        else:\n            print(i)\n            contador +=1\n    return contador\n\nsaludar()\n\nsuma(10)\n\nsumar(10,10)\n\nobtener_pi()\n\ncuadrado(2)\n\ncalculator(2,5)\n\nsuma_iva(10000)\n\nsumar_todos(1,2,6,4,5,7)\n\nsaludo_adios()\n\nnombre(\"daniel\")\n\nprint(contador)\nreto()"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/danielhdzr.py",
    "content": "# 02 FUNCIONES Y ALCANCE\n\n\"\"\" * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */ \n \"\"\"\n\n# variable global\nsaludo = \"Hola!\"\n# Funciones dentro de funcion main\ndef main():\n\n    # Funcion sin parametro\n    def func_sin_parametro():\n        print(f\"1. {saludo}\")\n    \n    func_sin_parametro()\n\n    # Funcion con parametro\n    def func_con_parametro(string):\n        # variable local \"nombre\"\n        #nombre = input(\"2. Ingresa tu nombre: \")\n        print(f\"Hola, {string}!\")\n\n    func_con_parametro(\"Daniel\")\n\n    # Funcion con retorno\n    def func_con_retorno():\n        # variable local \"nombre\"\n        nombre = input(\"3. Ingresa el nombre de quien quieras saludar: \")\n        return print(f\"Hola, {nombre}!\")\n    \n    func_con_retorno()\n\n    # Con un argumento predeterminado\n    def saludo_pred(nombre=\"Luis\"):\n        print(f\"5. Hola, {nombre}!\")\n\n    saludo_pred(\"4. Daniel\")\n    saludo_pred()\n\n    # Con argumentos y return\n    def return_args_greet(greet, name):\n        return f\"{greet}, {name}!\"\n\n    print(return_args_greet(\"6. Hola\", \"Daniel\"))\n\n    # Con retorno de varios valores\n    def multiple_return_greet():\n        return \"Hola\", \"Python\"\n\n    greet, name = multiple_return_greet()\n    print(\"7. Saludo al reves\")\n    print(name)\n    print(greet)\n    \n    def multiple_args(*args):\n        print(args)\n    \n    multiple_args(\"Hola\", \"Soy\", \"Daniel\")\n\n    '''def extra_para_mi(*args):\n        for i in args:\n            print(i)\n    \n    lista = [1,2,3,4]\n    extra_para_mi(f\",\".join(map(str,lista)))'''\nif __name__==\"__main__\":\n    main()"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/danielperezrubio.py",
    "content": "# Función sin parámetros ni retorno\ndef greeting() -> None:\n    print(\"Hello World!\")\n\n\ngreeting()\n\n\n# Función con parámetros sin retorno\ndef print_language(language) -> None:\n    print(f\"{language}\")\n\n\nprint_language(\"Python\")\n\n\n# Función con parámetros y retorno\ndef is_pair(num1: int) -> bool:\n    return num1 % 2 == 0\n\n\nprint(is_pair(4))\n\n\n# Funciones anidadas\ndef parent():\n    def nested():\n        pass\n\n\nages = [25, 16, 19, 50, 34]\n\n# Funciones de Python\nprint(f\"Las edades ordenadas: {sorted(ages)}\")\nprint(f\"El edad mas alta es: {max(ages)}\")\nprint(f\"El valor ASCII de la letra 'a' es: {ord('a')}\")\n\n\n# Varaibles locales\ndef using_local_variables():\n    notes = [100, 85.6, 79.4, 87, 94]  # variable local\n    notes.append(60)\n\n    def nested():  # Tiene acceso a las variables de la función padre\n        print(f\"Las notas son: {notes}\")\n\n    nested()\n\n\nusing_local_variables()\n\n\n# Variables globales\nglobal number\nnumber = 5\n\n\ndef using_global():\n    global number  # para usar la variable global\n    number = 4  # modifica la variable global\n\n\nusing_global()\nprint(f\"El valor actual de number es: {number}\")\n\n\n# EXTRA\ndef extra(str1: str, str2: str) -> int:\n    count = 0\n    for i in range(1, 101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(f\"{str1 + str2}\")\n        elif i % 3 == 0:\n            print(f\"{str1}\")\n        elif i % 5 == 0:\n            print(f\"{str2}\")\n        else:\n            print(i)\n            count += 1\n    return count\n\n\ncount = extra(\"Hello\", \"World\")\nprint(f\"Cantidad de números impresos: {count}\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/davidrguez98.py",
    "content": "\"\"\" # #02 FUNCIONES Y ALCANCE\n> #### Dificultad: Fácil | Publicación: 08/01/24 | Corrección: 15/01/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**. \"\"\"\n\ndef parametros (str1 = str, str2 = str) -> int:\n    contador = 0\n\n    for i in range(1, 101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(str1, str2)\n        elif i % 3 == 0:\n            print(str1)\n        elif i % 5 == 0:\n            print(str2)\n        else:\n            print(i)\n            contador += 1\n    return\n\nparametros(\"hola\", \"adios\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/dchevesich.py",
    "content": "# 02- Funciones y Alcance\n\ndef my_first_function():\n    print('Esta es una funcion sin parametros ni retorno')\n\n\ndef my_second_function(name, lastname):  # funcion con parametros\n    print(f\"Welcome to Python {name} {lastname}\")\n\n\nmy_first_function()\nmy_second_function(\"David\", \"Parrado\")\n\n\ndef sum_function(num_one, num_two):  # funcion con parametros y retorno\n    sum = num_one + num_two\n    return sum\n\n\nprint(sum_function(4, 87))\n\n\ndef sqr_function(number):  # Funcion dentro de otra funcion\n    number = float(number)\n    return (number)**(0.5)\n\n\ndef operacion_function(f, num):\n    return f(num)\n\n\nprint(operacion_function(sqr_function, 9))\n\n\ndef dificultad_extra(letra, letra1):\n    contador = 0\n    for num in range(1, 101):\n        if num % 3 == 0:\n            print(letra)\n            contador += 1\n        if num % 5 == 0:\n            print(letra1)\n            contador += 1\n        elif num % 3 == 0 and num % 5 == 0:\n            print(letra+letra1)\n            contador += 1\n    return contador\n\n\nprint(dificultad_extra(\"a\", \"b\"))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/devcherry1.py",
    "content": "\"\"\"\nFUNCIONES DEFINIDAS POR EL USUARIO\n\"\"\"\n\n# FUNCIONES SIMPLES\n\ndef saludo():\n    print(\"hola a todos\")\nsaludo()\n\n# FUNCIONES CON RETORNO\n\ndef saludoconretorno():\n    return \"hola chicas\"\nprint(saludoconretorno())\n\n# CON ARGUMENTO(S)\n\ndef saludo(parametro1):\n    print(f\"simon dice: {parametro1}\")\nsaludo(\"hola chicos\")\n\n# CON ARGUMENTO(S) PREDETERMINADO\n\ndef saludos(parametro1=\"ola que ace\"):\n    print(f\"simon dice: {parametro1}\")\nsaludos()\n\n#  ESTABLECIENDO PARAMETROS AL LLAMAR LA FUNCION\n\ndef short(question,answer):\n    print(question,answer)\n\nshort(answer=\"vientos\",question=\"como le baila?\")\n\n# CON ARGUMENTO(S) Y RETORNO\n\ndef saludoyretorno(parametro1):\n    return(f\"simon dice: {parametro1}\")\nprint(saludoyretorno(\"de que hablan?\"))\n\n# CON RETORNO DE VARIOS VALORES\ndef multiple_return_greet():\n    return \"js\", \"Python\"\ngreet, name = multiple_return_greet() #Se asignan dos variables diferentes\nprint(greet)\nprint(name)\n\n# CON UN NUMERO VARIABLE DE ARGUMENTOS\n\ndef arg_numbers(*names):\n    print(\"Vamos a contar\")\n    for name in names:\n        print(name)\narg_numbers(\"uno\",\"dos\",\"tres\")\n\n# CON UN NUMERO VARIABLE DE ARGUMENTOS CON PALABRA CLAVE\n\ndef arg_numbers_key(**names):\n    print(\"Vamos a contar\")\n    for key, value in names.items():\n        print(value,key)\narg_numbers_key(\n    one=\"uno\",\n    two=\"dos\",\n    three=\"tres\"\n)\n\n\"\"\"\nFUNCIONES DENTRO DE FUNCIONES\n\"\"\"\n\ndef outer_function():\n    def inner_function():\n        print(\"Funcion interna: Todo bien ahi fuera?\")\n    inner_function()\n\nouter_function()    \n\n\"\"\"\nFUNCIONES DEL LENGUAJE (BUILT-IN)\n\"\"\"\n\nprint(\"DEVCHERRY1\".lower())\nprint(f\"Cuantos caracteres tiene tu user: {len(\"devcherry1\")}\")\nprint(f\"Y si hablamos del tipo: {type(\"devcherry1\")}\")\n\n\"\"\"\nVARIABLES LOCALES Y GLOBALES\n\"\"\"\nglobal_variable = \"Python\"\n\ndef hello_python():\n    global_variable = \"JS\"\n    print(f\"Hello, {global_variable}!\")\nhello_python()\n\nprint(f\"Hello, {global_variable}!\")\n\n\"\"\"\nEXTRA (Fizz Buzz)\n\"\"\"\n\ndef extra(palabra1,palabra2):\n    numeros = 0\n    for i in range (1,101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(palabra1 + \" y tambien \" + palabra2)\n        elif i % 3 == 0:\n            print(palabra1)\n        elif i % 5 == 0:\n            print(palabra2)\n        else:\n            numeros += 1\n    print(f\"Cantidad de numeros dedl 1 al 100 que no son multiplos de 3 ni de 5: {numeros}\")\n    \nextra(\"multiplo de 3\",\"multiplo de 5\") \n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/dimasb69.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n\"\"\"\n\n#funciones básicas\nprint(\"\\n\\tfunciones básicas\")\nprint('================================')\nprint(\"\\n\\tSon funciones definias por el usuario para realizar tareas \\n\\tsimple que se necesiten y se pueden repetir n cantidad de veces en el codigo\")\nprint(\"\\n\\tEstas pueden tener un retorno o no, y recibir uno o varios parametros con el \\n\\tual trabajar\")\n\n#Simple sin Parametro y sin retorno\ndef func_simple():\n    print (\"Hola!!, MUNDO\\n\")\n    \n\nprint(\"\"\"\\nEn el ejemplo se define una funcion simple sin parametros y sin retorno\\ny solo muestra por consola un \nprint: \\n\\ndef func_simple():\\n    print('Hola!!, MUNDO')\\n\\nEsto al llamar la funcion nuevamente con: \\n\\nfunc_simple() ##esto devuelve por consola:\\n\"\"\")\nfunc_simple()\n\n\nprint(\"\\n\\tSon funciones definias por el usuario para realizar tareas \\n\\tsimple que se necesiten y se pueden repetir n cantidad de veces en el codigo\")\nprint(\"\\n\\tEstas pueden tener un retorno o no, y recibir uno o varios parametros con el \\n\\tual trabajar\")\n#Simple sin Parametro y con retorno\ndef func_simple_return():\n   return \"Hola!!, MUNDO\\n\"\n    \n\nprint(\"\"\"\\nEn este ejemplo se define una funcion simple sin parametros y con retorno\\nesta que con solo invocarla no mostrara nada por consola\\nSolo si se asocia con una variable o se inserta directamente en el print \\nse puede ver el resultado:\\n\\ndef func_simple_return():\\n    return 'Hola!!, MUNDO'\\n\\nEsto al llamar la funcion nuevamente con: \\n\\nfunc_simple_return() No mostrara nada en consola\\n\"\"\")\nfunc_simple_return() #no devolvio nada por consola\nprint(\"\\nSi se iguala a una variable se puede usar la variable apra imprimirla por ejemplo:\\n\\nretorno_simple = func_simple_return()\\n\\nEsto al imprimirlo por consola con \\nprint(retorno_simple) ##Esto si mostrara por consola:\\n\")\nretorno_simple = func_simple_return()\nprint(retorno_simple)\nprint(\"\\nTambien se puede llamar directamente en el print:\\n\\nprint(func_simple_return()) ##esto mostrara por consola:\\n\")\nprint(func_simple_return())\n\nprint(\"\\n\\n\\tSon funciones definias por el usuario para realizar tareas \\n\\tsimple que se necesiten y se pueden repetir n cantidad de veces en el codigo\")\nprint(\"\\n\\tEstas pueden tener un retorno o no, y recibir uno o varios parametros con el \\n\\tual trabajar\")\n#Simple con Parametro y con retorno y sin retorno\ndef func_simple_return_args(nombre):\n   print(f\"Hola {nombre}\") \n   return \"Bienvenido\\n\"\n    \n\nprint(\"\"\"\\nEn este ejemplo se define una funcion simple con parametros y con y sin retorno\\n Se puede asociar con una variable e inserta directamente en el print \\npara ver  el resultado deseado:\\n\\ndef func_simple_return_args():\\n    print(f'Hola {nombre}')\\n    return 'Bienvenido'\\n\\nal llamar la funcion con el prin se recibe Beinvenido y al asociarla se obtiene el mensaje con el parametro dado\\n\\n\"\"\")\n\nprint(\"\\nSi se iguala a una variable se puede usar la variable apra imprimirla por ejemplo:\\n\\nretorno_simple = func_simple_return()\\n\\nEsto al imprimirlo por consola con \\nprint(retorno_simple) ##Esto si mostrara por consola:\\n\")\n\nprint(\"\\nDefiniendo la variable Saludo = func_simple_return_args('Dimas B')  Y luego print(saludo) \\nesto mostrara primeo el print de la funcion \\ny luego con el segundo print de la variabel el saludo:\\n\")\n\nsaludo = func_simple_return_args('Dimas B') #aqui ya se muestra el print de la funcion\n\nprint(saludo) #Esto devulve el mensaje con el Saludo\n\nprint(\"\\nNOTA: Sepueden recibir multiples variables y tener multiples retornos\\nCon este ejemplo se muestra:\\n\\n\")\nprint(\"\"\"def multiples_arg_ret(nombre, edad, saludo):\n    name = f\"Tu Nombre es: {nombre}\"\n    age = f\"Tienes {edad} años\"\n    greeting = f\"{saludo}, bienvenido a este ejercicio\"\n    return name, age, greeting\\n\nvalor1, valor2, valor3 = multiples_arg_ret('Dimas B', '43', 'Buenos Dias')\\n\nprint(valor3)\nprint(valor1)\nprint(valor2)  \n\npara retornar:    \n      \"\"\")\n\ndef multiples_arg_ret(nombre, edad, saludo):\n    name = f\"Tu Nombre es: {nombre}\"\n    age = f\"Tienes {edad} años\"\n    greeting = f\"{saludo}, bienvenido a este ejercicio\"\n    return name, age, greeting\n\nvalor1, valor2, valor3 = multiples_arg_ret('Dimas B', '43', 'Buenos Dias')\n\n\nprint(valor3)\nprint(valor1)\nprint(valor2)\nprint(\"\\nComo se observa en el Ejercicio anterio se ingresaron a la funcion varios agrumento los cuales \\nse pasaron a nuevas variales para ser retonadas tas para luego ser usada\\n\")\n\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/domo2pdev.py",
    "content": "\"\"\"\nEJERCICIO:\n - Crea ejemplos de funciones basicas que representen las diferentes posibilidades del lenguaje: Sin parametros ni retorno, con uno o varios parametros, con retorno...\n - Comprueba si puedes crear funciones dentro de funciones.\n - Utiliza algun ejemplo de funciones ya creadas en el lenguaje.\n - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n - Debes hacer print por consola del resultado de todos los ejemplos.\n   (tener en cuenta que cada lenguaje puede poseer mas o menos posibilidades)\n \n DIFICULTAD EXTRA (opcional):\n Crea una funcion que reciba dos parametros de tipo cadena de texto y retorne un numero.\n- La funcion imprime todos los numeros del 1 al 100. Teniendo en cuenta que:\n   - Si el numero es multiplo de 3, muestra la cadena de texto del primer parumetro.\n   - Si el numero es multiplo de 5, muestra la cadena de texto del segundo parumetro.\n   - Si el numero es multiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n   - La funcion retorna el numero de veces que se ha impreso el numero en lugar de los textos.\n \n Presta especial atencion a la sintaxis que debes utilizar en cada uno de los casos.\n Cada lenguaje sigue una convenciones que debes de respetar para que el codigo se entienda.\n\"\"\"\n\n# Funciones Definidas por el usuario\n\n\n# Simple functions:\ndef greet():\n    print(\"Hello, Python\")\n\n\ngreet()\n\n\n# Return functions:\ndef return_greet():\n    return \"Hello, Returned Python\"\n\n\ngreet = return_greet()\nprint(greet)\nprint(return_greet())\n\n\n# Functions with parameters:\ndef arg_greet(name):\n    print(f\"Hello, {name}\")\n\n\narg_greet(\"Paul\")\n\n\ndef square(number):\n    return number**2\n\n\nmy_square = square(9)\nprint(my_square)\nprint(square(10))\n\n\ndef add(number_a, number_b):\n    return number_a + number_b\n\n\nadd(1, 3)\nprint(add(1, 3))\n\n# Functions with default parameters:\n\n\ndef circle_area(radius, pi=3.1416):\n    return pi * (radius**2)\n\n\nprint(circle_area(15))\nresult_circle_area = circle_area(15)\nprint(result_circle_area)\n\n\n# Keyword arguments:\ndef division(dividend, divisor):\n    return dividend / divisor\n\n\nprint(division(divisor=5, dividend=10))\nresult_division = division(dividend=24, divisor=4)\nprint(result_division)\n\n# Multiple return functions:\n\n\ndef multiple_return(place_a, place_b):\n    return place_a, place_b\n\n\nplace_a, place_b = multiple_return(\"Place A\", \"Place B\")\nprint(place_a)\nprint(place_b)\n\n\n# Variable number of arguments: *args\ndef print_args_greet(*names):\n    for name in names:\n        print(f\"Hello, {name}\")\n\n\nprint_args_greet(\"Paul\", \"Paco\", \"Pepito\", \"Pepa\", \"Pepita\")\n\n\ndef sum_args(*args):\n    return sum(args)\n\n\nprint(sum_args(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))\n\n\n# Variable number of keyword arguments: **kwargs\ndef print_kwargs_greet(**kwargs):\n    for key, value in kwargs.items():\n        print(f\"Hello, {value}\")\n\n\nprint_kwargs_greet(name=\"Paul\", surname=\"Perez\")\n\n\ndef variable_keyword_arg_mission(**names):\n    for name in names.values():\n        print(f\"Mission, {name}\")\n\n\nvariable_keyword_arg_mission(\n    name=\"Jhon\", surname=\"Connor\", target=\"Yes\", location=\"Unknown\"\n)\n\n# Nested functions:\n\n\ndef outer_function():\n    print(\"Outer function\")\n\n    def inner_function():\n        print(\"Inner function\")\n\n    inner_function()\n\n\nouter_function()\n\n# Bilt-in functions:\n# See https://pytthon.org for more information\nprint(\"Hello, World\")\nlength = len(\"Hello, World\")\nprint(length)\n\n# Variable scope in Python:\nglobal_var = \"I am a global variable\"  # Global variable\n\n\ndef print_global_var():\n    print(global_var)\n\n\nprint_global_var()  # Outputs: I am a global variable\n\n# Local variables:\n# Local variables are accessible only within the scope of the method\n# where they are declared.\n\n\ndef print_local_var():\n    local_var = \"I am a local variable\"  # Local variable\n    print(local_var)\n\n\nprint_local_var()\n\n\"\"\" \nDIFICULTAD EXTRA (opcional):\n Crea una funcion que reciba dos parametros de tipo cadena de texto y retorne un numero.\n   - La funcion imprime todos los numeros del 1 al 100. Teniendo en cuenta que:\n   - Si el numero es multiplo de 3, muestra la cadena de texto del primer parumetro.\n   - Si el numero es multiplo de 5, muestra la cadena de texto del segundo parumetro.\n   - Si el numero es multiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n   - La funcion retorna el numero de veces que se ha impreso el numero en lugar de los textos.\n\"\"\"\n\n\ndef print_numbers(text1, text2):\n    count = 0\n    for number in range(1, 101):\n        if number % 3 == 0 and number % 5 == 0:\n            print(text1 + text2)\n        elif number % 3 == 0:\n            print(text1)\n        elif number % 5 == 0:\n            print(text2)\n        else:\n            print(number)\n            count += 1\n\n    return count\n\n\nprint(print_numbers(\"Es multiplo de 3\", \"Es multiplo de 5\"))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/duendeintemporal.py",
    "content": "# { ROADMAP PARA PROGRAMADORES }  #2 FUNCIONES Y ALCANCE\n# BIBLIOGRAFY REFERENCE: Python, Java, SQL JavaScript The Ultimate Crash Course for Beginners to Master the 4 Most In-Demand Programming Languages,... (Philip Robbins) (Z-Library).pdf\n# Python Notes for Professionals. 800+ pages of professional hints and tricks (GoalKicker.com) (Z-Library)\n# Additionally, I use GPT as a reference and sometimes to correct or generate proper comments.\n\n\"\"\" Python supports a variety of programming paradigms. The functional\nprogramming paradigm is the most widely used programming paradigm for\ndevelopers to write code in. \"\"\" \n\n\"\"\" Types of Functions\nSystem functions and user-defined functions are the two main types of\nfunctions.\nThe core Python library provides system functions, which are frequently\nused by developers to perform common tasks. 'print,' for example, is a\nsystem function that displays a literal string literal on the screen.\nDevelopers, on the other hand, create user-defined functions specifically for\ntheir software. Users can also integrate third-party libraries' user-defined\nfunctions into their code.\nRegardless of the type of code you use, keep in mind that the primary goal\nof using functions as a programmer is to solve problems with less reusable\ncode. \"\"\"\n\n\"\"\" How do they Work?\nThe philosophy behind the use of functions in programming is similar to\nthat of mathematical functions. The developer will first define a function\nwith complex code logic and a name that can be called from anywhere in\nthe program using unique programming components known as parameters.\nThe developers then explicitly define what type of parameters the user can\nprovide for fewer crashes.\nIf the function is not called, users will be unable to use the code logic that\nthe developer created. Function calling is frequently displayed in the front\nend via buttons, tabs, and other graphical user interfaces. While it may be as\nsimple as a tap for the end user, a function will be called programmatically\nfor a software component to function properly. \"\"\"\n\ndef add_pad(number, width, pad='0'):\n    result = str(number)\n    while len(result) < width:\n        result = f\"{pad}{result}\"\n    return result\n\nprint(add_pad(4, 3, '#'))  # ##4\nprint(add_pad(56, 3, '$'))  # $56\nprint(add_pad(7, 3))        # 007\n\ndef square(n):\n    return n * n\n\nfunc_array = []\nfunc_array.append(square(8))  # Adds a new function to a list\nprint(func_array)  # [64]\n\ndata = {'book_name': 'Hackbook'}\ndata['some_method'] = lambda: print(f\"{data['book_name']} is now available in z-lib.org, so hack the world.\")  # Assigns a new function as a property of another object\ndata['some_method']()  # Hackbook is now available in z-lib.org, so hack the world.\n\ndef call(do_something):\n    do_something()\n\ncall(lambda: print('Hi roadmap coders!'))  # Hi roadmap coders!\n\n# Returned as values from functions\ndef return_func():\n    return lambda str: print(str)\n\ngreeting = return_func()\ngreeting('Hi there!')  # Hi there!\n\n# Short for print\nlog = print\n\n# Functions in Python can possess properties that can be dynamically created and assigned like objects.\n\ndef call_mom():\n    log('Mommmmm!')\n\ncall_mom()  # Output: Mommmmm!\ncall_mom.name = \"Momm\"  # Assigning a name property\nlog(call_mom.name)  # Output: Momm\n\ncall_mom.something = 'something'  # Assigning a custom property\nlog(call_mom.something)  # Output: something\n\nlog(call_mom)  # <function call_mom at 0x00000215FAA0ACA0>\n\n# Functions in Python are first-class objects, meaning they can be treated like any other object.\n\n# Class definition for Cat, which serves as a constructor for creating Cat objects.\nclass Cat:\n    def __init__(self, name, color, sound):\n        self.name = name\n        self.color = color\n        self.sound = sound\n\n# Creating an instance of Cat\npsico_cat = Cat(\"Psicotrogato\", \"Black & White\", \"Meaw\")\nlog(psico_cat.color)  # Output: Black & White\npsico_cat.sound = \"Hey girl what's your name, what's your name?... I forgot\"\n\n# Adding a method to the Cat class\ndef speak(self):\n    log(self.sound)\n\nCat.speak = speak  # Adding the speak method to the Cat class\n\npsico_cat.speak()  # Output: \"Hey girl what's your name, what's your name?.. I forgot\"\n\n# Closure example: A function that maintains state across calls.\ndef incrementer(n):\n    local = [n]  # Use a list to hold the mutable state\n    def inner():\n        local[0] += 1\n        return local[0] - 1\n    return inner\n\nincrement = incrementer(0)  # Immediately invoked with an initial value of 0\n\nlog('incrementer value is:', increment())  # Output: incrementer value is: 0\nlog('incrementer value is:', increment())  # Output: incrementer value is: 1\nlog('incrementer value is:', increment())  # Output: incrementer value is: 2\n\n# Function that returns another function (closure)\ndef square_v2(n):\n    return lambda: n * n\n\npow64 = square_v2(64)\npow78 = square_v2(78)\n\nlog(pow64())  # Output: 4096\nlog(pow78())  # Output: 6084\n\n# Recursive function example\ndef factor(n):\n    if n == 1:\n        return 1\n    return n * factor(n - 1)\n\nlog(factor(8))  # Output: 40320\n\n# Function to calculate square using a lambda expression\nsquare_v3 = lambda n: n * n\nlog(square_v3(4))  # Output: 16\n\n# Class to demonstrate method context with 'self'\nclass Obj:\n    def __init__(self):\n        self.value = 'Rutadeprogramacion Exercice #2.'\n\n    def advertisement(self):\n        log(self.value)  # Output: Rutadeprogramacion Exercice #2\n        # Using a lambda function to maintain context\n        import threading\n        threading.Timer(1, lambda: log(f\"{self.value}\")).start()\n\nobj = Obj()\nobj.advertisement()  # Alerts the message after 1 second\n\n# Function declaration example\ndef subtract(n, m):\n    return n - m\n\nlog(subtract(8, 4))  # Output: 4\n\n# Function expression using a lambda\nmultiply = lambda n, m: n * m\nlog(multiply(8, 9))  # Output: 72\n\n# Named function using a lambda expression\nadd = lambda a, b: a + b\nlog(add(3, 3))  # Output: 6\n\n# Lambda function for division\ndivide = lambda n, m: n / m\nlog(divide(543, 56))  # Output: 9.696428571428571\n\n# Anonymous Functions: These are functions that do not have a name. They are often used in callbacks or as arguments to other functions.\n\n# In Python, we can use lambda functions as anonymous functions.\nimport threading\n\ndef on_load():\n    body_style = {\n        'background': '#000',\n        'text-align': 'center'\n    }\n    \n    title = 'Retosparaprogramadores #2.'\n    title_style = {\n        'font-size': '3.5vmax',\n        'color': '#fff',\n        'line-height': '100vh'\n    }\n    \n    # Simulating setting styles and appending to body\n    log(f\"Body style: {body_style}\") # Body style: {'background': '#000', 'text-align': 'center'}\n    log(f\"Title: {title} with style: {title_style}\") # Title: Retosparaprogramadores #2. with style: {'font-size': '3.5vmax', 'color': '#fff', 'line-height': '100vh'}\n    \n    log('This is an anonymous function')  # This will be logged at the end\n\non_load()  # Simulating the load event\n\ndef say_hi():\n    log('Hi')\n\nsay_hi()  # Output: Hi\n\n# Named functions differ from anonymous functions in multiple scenarios:\n# - When debugging, the name of the function will appear in the error/stack trace.\n# - Named functions are hoisted while anonymous functions are not.\n# - Named functions and anonymous functions behave differently when handling recursion.\n\n# Immediately Invoked Function Expressions (IIFE): \n# An IIFE is a function that is executed immediately after it is defined.\n# In Python, we can achieve similar behavior using a function call.\n\ndef iife():\n    log(\"This is another example of IIFE functions\")  # This will be logged\n\niife()  # Immediately invoked\n\n# Higher-Order Functions: These are functions that take other functions as arguments or return functions as their result.\ndef sum_numbers(numbers):\n    total = sum(numbers)  # Using built-in sum function\n    return total\n\ndef range_numbers(n, m):\n    return list(range(n, m + 1))  # Creating a range of numbers\n\n# Using the higher-order functions\nlog(sum_numbers(range_numbers(1, 100)))  # Output: 5050\n\n# Generator Functions: Generator functions can pause and resume execution.\ndef id_generator():\n    id = 0\n    while True:\n        id += 1\n        yield f\"{id:05}\"  # Formatting the ID with leading zeros\n\nid_iterator = id_generator()\n\nlog(next(id_iterator))  # Output: 00001\nlog(next(id_iterator))  # Output: 00002\n\n# Async Functions: Async functions are a way to work with asynchronous code.\nimport asyncio\nimport aiohttp\n\nasync def get_lorem_ipsum(number_of_paragraphs):\n    async with aiohttp.ClientSession() as session:\n        async with session.get(f'https://baconipsum.com/api/?type=meat-and-filler&paras={number_of_paragraphs}') as response:\n            return await response.json()\n\nasync def log_paragraphs():\n    try:\n        result = await get_lorem_ipsum(2)\n        log(result)  # Logs the result: some lorem Ipsum paragraphs\n    except Exception as error:\n        log(f\"Error: {error}\")\n\n# Running the async function\nasyncio.run(log_paragraphs())\n\n# Functions that take multiple arguments / the Rest parameter\n# In Python, we can use *args to accept a variable number of arguments.\n\ndef total(*numbers):\n    return sum(numbers)  # Using built-in sum function\n\nlog('Total:', total(10, 256, 345, 465, 87, 432))  # Output: Total: 1595\n\n# CLOSURES AND SCOPES\n\n# Scope: A scope refers to the visibility of identifiers in certain parts of a program.\n# Closure: A closure allows a function to access and manipulate variables that are external to that function.\n\n# Hoisting is not a concept in Python like it is in JavaScript, but we can define functions before or after they are called.\n\n# Named functions can be called before their declaration due to Python's function definition behavior.\ndef do_something():\n    log(\"I'm here coding, and I'm amazed at all we can learn by following this roadmap.\")\n\nlog(do_something())  # This will work\n\n# Anonymous functions (lambdas) cannot be called before their declaration.\n# Uncommenting the following line will throw an error.\n# log(do_another_thing())\n\ndo_another_thing = lambda: log('never log this...') # None\n\nfriend = 'Asterix'\n\ndef show_closure():\n    log(friend)  # Output: Asterix in scope\n    another_friend = 'Obelix'\n    \n    def inner_closure():\n        another_one = 'Idefix'\n        log(another_friend)  # Output: Obelix in scope\n        log(friend)  # Output: Asterix in scope\n        log(another_one)  # Output: Idefix in scope\n    \n    inner_closure()\n    # Uncommenting the following line will throw an error.\n    # log(another_friend)  # Throws an Error: another_friend is not defined\n\nshow_closure()\n\n# Closures allow us to define \"private\" variables that are visible only to a specific function or set of functions.\ndef make_counter():\n    counter = 0\n\n    def increment_counter():\n        nonlocal counter\n        counter += 1\n\n    def reset_counter():\n        nonlocal counter\n        counter = 0\n\n    return {\n        'value': lambda: counter,\n        'increment': increment_counter,\n        'restart': reset_counter\n    }\n\n# Testing the make_counter function\ncounter1 = make_counter()\ncounter2 = make_counter()\n\ncounter2['increment']()  # Increment counter2\ncounter2['increment']()  # Increment counter2\nlog(counter1['value']())  # Output: 0\nlog(counter2['value']())  # Output: 2\ncounter2['restart']()  # Restart counter2\nlog(counter2['value']())  # Output: 0\n\n\n# The context of the function is saved when make_counter() is called.\n\n# Apply and Call\ndef speak(*sentences):\n    tell = ' '.join(sentences)\n    log(f\"{person['name']}: {tell}\")\n\nperson = {'name': \"Niko\"}\nspeak(\"I\", \"will\", \"go\", \"through\", \"this\", \"roadmap\", \"until\", \"the\", \"end\")  # Output: I will go through this roadmap until the end\nspeak(\"But\", \"first\", \"I\", \"need\", \"some\", \"exercise\")  # Output: But first I need some exercise\n\n# In Python, we can use the 'self' parameter in methods to refer to the instance of the class.\n\n# The bind method in Python can be simulated using a method within a class.\nclass Person:\n    def __init__(self, name):\n        self.name = name\n\n    def say_hi(self):\n        log(f\"Hi {self.name}\")\n\nperson2 = Person('Anna')\nperson2.say_hi()  # Output: Hi Anna\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/eamartin.py",
    "content": "PI = 3.1416\n\n'''\nEJERCICIO 1:\n    Crea ejemplos de funciones básicas que representen las diferentes\n    posibilidades del lenguaje.\n\n    Sin parámetros ni retorno, con uno o varios parámetros, con retorno ...\n'''\n\ndef no_return_no_params():\n    print(\"No return, no parameters function\")\n    a = int(input(\"Enter a number: \"))\n    b = int(input(\"Enter another number: \"))\n\n    print(f\"{a} + {b} = {a + b}\")\n\ndef no_return(a, b):\n    print(\"\\nNo return function\")\n    print(f\"{a} + {b} = {a + b}\")\n\ndef return_params(a, b):\n    print(\"\\nFunction with parameters and return\")\n    return a + b\n\ndef multiple_params(*languages):\n    print(\"\\nFunction with multiple parameters\")\n    for language in languages:\n        print(f\"Hello, {language}!\")\n\n'''\n---------------------------------------------------------------------\nEJERCICIO 2:\n    Comprueba si puedes crear funciones dentro de funciones.\n'''\n\ndef outer_function(param):\n    print(\"\\nFunction inside other function\")\n    def inner_function():\n        print(f\"Hello, {param}\")\n    inner_function()\n\n'''\n---------------------------------------------------------------------\nEJERCICIO 3:\n    Utiliza algun ejemplo de funciones ya creadas en el lenguaje\n'''\n\ndef builtin_functions(nombre, numero):\n    print(\"\\nFunctions that use a builtin function\")\n    print(f\"String [{nombre}] contains {len(nombre)} characters\")\n    print(f\"Integer {numero} converted to a string {int(numero)}\")\n\n'''\n---------------------------------------------------------------------\nEJERCICIO 4:\n    Pon a prueba el concepto de variable LOCAL y GLOBAL\n'''\n\ndef global_local(variable1, variable2):\n    print(f\"This is a global variable {variable1}\")\n    print(f\"This is a local variable {variable2}\")\n\n'''\n---------------------------------------------------------------------\nDIFICULTAD EXTRA:\n    Crea una funcion que reciba dos parametros de tipo cadena de texto y retorne un numero.\n'''\ndef dif_extra(cadena1, cadena2):\n    i = 0\n    for numero in range(1,101):\n        if numero % 3 == 0 and numero % 5 == 0:\n            print(f\"{cadena1}{cadena2}\")\n        elif numero % 3 == 0:\n            print(f\"{cadena1}\")\n        elif numero % 5 == 0:\n            print(f\"{cadena2}\")\n        else:\n            print(numero)\n            i += 1\n    return i\n\ndef main():\n    e = 2.71\n\n    no_return_no_params()\n    no_return(5, 4)\n    print(\"8 + 3 =\", return_params(8, 3))\n    multiple_params(\"Python\", \"C\", \"Java\")\n    outer_function(\"world!\")\n    builtin_functions(\"Mouredev\", 50)\n    global_local(PI, e)\n    print(\"Numeros:\", dif_extra(\"hola\", \"mundo\"))\n\n\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/eberstr.py",
    "content": "def funcion_print():\n    print(\"Esto es una funcion\")\n\nfuncion_print()\n\ndef funcion_return():\n    return 'Esto es una funcion con return'\n\nprint(funcion_return())\n\ndef varios_returns():\n    return \"Hola\", \"que tal\"\n\nsaludo, pregunta = varios_returns()\nprint(saludo)\nprint(pregunta)\n\ndef funcion_1_parametro(param):\n    print(f'{param} con parametro')\n\nfuncion_1_parametro(\"funcion\")\n\ndef funcion_2_parametros(param, param2):\n    print(f'{param} {param2} 2 parametros')\n\nfuncion_2_parametros(\"funcion\", \"con\")\n\ndef funcion_parametros_default(param='hola'):\n    print(f'{param} funcion con valor default')\n\ndef returns_variables(*nombres):\n    for nombre in nombres:\n        print(f\"Hola, {nombre}!\")\n\nreturns_variables(\"Pepe\", \"hola\", \"tests\")\n\n# Funciones con dentro de funciones\ndef funcion_externa():\n    def funcion_interna():\n        print('Funcion interna')\n    funcion_interna()\n\nfuncion_externa()\n\n\n# Funciones de python\nprint(len(\"hola como estas\"))\n\n# variables locales y globales\n\nvar_global = 'Hola'\n\ndef funcion():\n    var_local = 'Hola2'\n    print(f'{var_local}, {var_global}')\n\n# Extra \n\ndef extra(num1, num2):\n    count = 0\n    for i in range(1, 101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(f\"{num1}, {num2}\")\n        elif i % 3 == 0:\n            print(num1)\n        elif i % 5 == 0:\n            print(num2)\n        else:\n            print(i)\n            count +=1\n    return i"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/eduhumanes91.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\"\"\"\n\n# Funciones\n\nprint(\"\\n *******Funciones******* \\n\")\n\n# Función sin parámetros ni retorno\n\nprint(\"\\n *******Función sin parámetros ni retorno******* \\n\")\n\ndef saludar():\n    print(\"Hola Mundo!\")\n\nsaludar()\n\n# Función con parámetros\n\nprint(\"\\n *******Función con parámetros******* \\n\")\n\ndef saludar(nombre):\n    print(f\"Hola {nombre}!\")\n\nsaludar(\"Eduardo\")\n\n# Función con retorno\n\nprint(\"\\n *******Función con retorno******* \\n\")\n\ndef sumar(a, b):\n    return a + b\n\nresultado = sumar(5, 5)\nprint(f\"Resultado de la suma: {resultado}\")\n\n# Función dentro de función\n\nprint(\"\\n *******Función dentro de función******* \\n\")\n\ndef saludar(nombre):\n    def mensaje():\n        return \"Hola\"\n    return f\"{mensaje()} {nombre}!\"\n\nprint(saludar(\"Eduardo\"))\n\n# Funciones ya creadas\n\nprint(\"\\n *******Funciones ya creadas******* \\n\")\n\nprint(\"Función print(): Devuelve un mensaje por consola\")\nprint(\"Función input(): Devuelve un mensaje por consola y recoge la entrada del usuario\")\nprint(\"Función len(): Devuelve la longitud de un objeto\")\nprint(\"Función range(): Devuelve una secuencia de números\")\nprint(\"Función type(): Devuelve el tipo de un objeto\")\nprint(\"Función int(): Devuelve un número entero\")\nprint(\"Función str(): Devuelve una cadena de texto\")\nprint(\"Función float(): Devuelve un número decimal\")\nprint(\"Función list(): Devuelve una lista\")\nprint(\"Función dict(): Devuelve un diccionario\")\nprint(\"Función tuple(): Devuelve una tupla\")\nprint(\"Función set(): Devuelve un conjunto\")\nprint(\"Función bool(): Devuelve un valor booleano\")\n\n# Variable LOCAL y GLOBAL\n\nprint(\"\\n *******Variable LOCAL y GLOBAL******* \\n\")\n\nvariable_global = \"Soy una variable global\"\n\ndef mostrar_variable():\n    variable_local = \"Soy una variable local\"\n    print(variable_local)\n\nmostrar_variable()\n\n# Dificultad extra\n\nprint(\"\\n *******Dificultad extra******* \\n\")\n\ndef hola_mundo(param1, param2):\n    contador = 0\n    for i in range(1, 101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(\"HolaMundo\")\n        elif i % 3 == 0:\n            print(\"Hola\")\n        elif i % 5 == 0:\n            print(\"Mundo\")\n        else:\n            print(i)\n        contador += 1\n    return contador\n\nprint(hola_mundo(\"Hola\", \"Mundo\"))\n\n\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/elder202.py",
    "content": "#EJERCICIO:\n#- Crea ejemplos de funciones básicas que representen las diferentes posibilidades del lenguaje:\n#\"Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n#Comprueba si puedes crear funciones dentro de funciones.\n#Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n#Pon a prueba el concepto de variable LOCAL y GLOBAL.\n#Debes hacer print por consola del resultado de todos los ejemplos.\n#(y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n\n#DIFICULTAD EXTRA (opcional):\n#Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n#La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n#Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n#Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n#\"Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n#La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\n# Funcion Simple\ndef greet():\n    print(\"Hola\")\n\ngreet()\ngreet()\n\n# Funcion con retorno\n\ndef return_greet():\n    return \"Hola, Py\"\n\nprint(return_greet())\n\n#Funcion con un argumento\n\ndef arg_greet(name):\n    print(f\"hola, {name}\")\n\narg_greet(\"Elder\")\n\n#Funcion con argumentos\n\ndef args_greet(greet, name):\n    print(f\"{greet}, {name}\")\n\nargs_greet(\"Hi\", \"Elder\")\n\n#Funcion con un argumento predeterminado\n\ndef default_arg_greet(name=\"Nombre Predet\"):\n    print(f\"hola, {name}\")\n\ndefault_arg_greet(\"Elder\")\ndefault_arg_greet()\n\n# Funcion con retorno de varios valores\ndef multiple_return_greet():\n    return \"Hola\", \"Py\"\n\ngreet, name = multiple_return_greet()\nprint(greet)\nprint(name)\n\n# Funcion con numero variable de argumentos o parametros\n\ndef variable_arg_greet(*names):\n    for name in names:\n        print(f\"Hola, {name}\")\n\nvariable_arg_greet(\"Python\", \"Elder\", \"Comunidad\")\n\n# Funcion con numero variable de argumentos con palabra clave\n\ndef variable_arg_greet(**names):\n    for key, value in names.items():\n        print(f\"Hola, {value}({key})\")\n\nvariable_arg_greet(Lenguaje=\"Python\", name=\"Elder\", alias=\"Comunidad\", age=36)\n\n# Funciones dentro de funciones\n\ndef outer_function():\n    def inner_function():\n        print(\"Funcion interna\")\n    inner_function()\n    \nouter_function()\n\n# Funciones del lenguaje (Built-in)\n\nprint(len(\"Elder\"))\nprint(type(\"Elder\"))\nprint(\"Elder\".upper())\n\n# Variables locales y globales (Ambitos - scope)\n\nglobal_var = \"Python\"\nprint(global_var)\n\ndef hello_python():\n    local_var = \"Hello\"\n    print(f\"{local_var}, {global_var}\")\n\nhello_python()\n\n# Dificultad_extra\n\ndef print_numbers(par1,par2) -> int:\n    count = 0\n    for number in range(1, 101):\n        if number % 3 == 0 and number % 5 == 0:\n            print(par1 + par2)\n        elif number % 3 == 0:\n            print(par1)\n        elif number % 5 == 0:\n            print(par2)\n        else:\n            print(number)\n            count ++ 1\n    return count\n\nprint(print_numbers(\"Fizz\",\"Buzz\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/elkin-dev.py",
    "content": "## Funciones integradas en Python\n\nprint(\"Hola, mundo\")\n\nlst = [1, 23, 4, 5, 6, 6]\nprint(len(lst))\n\n\nname = input(\"Dime cual es tu nombre \")\nprint(\"Hola,\", name)\n\n\nfor i in range(5):\n    print(i)\n\nnumber = 23\nprint(type(number))\nnumber = str(number)\nprint(type(number))\n\nlst = [1, 3, 9, 10, 21, 33]\nprint(max(lst))\nprint(min(lst))\n\n\n## Funciones básicas definidas por el usuario\n\n\ndef greet():\n    print(\"Hola desde python\")\n\n\n# greet()\n\n\n## Funciones con parámetros\ndef greeting(name):\n    print(\"Hola\", name, \"que tal!\")\n\n\n# greeting(\"Elkin\")\n\n\ndef multiply(value1, value2):\n    return value1 * value2\n\n\n# print(multiply(4, 5))\n\n\ndef sum(a, b):\n    return a + b\n\n\n# print(sum(2, 5))\n## Funciones con parámetros predefinidos\ndef subtraction(a=3, b=4):\n    return a - b\n\n\n# print(subtraction())\n\n\ndef power(a, b=2):\n    return a**b\n\n\n# print(power(5))\n## Funcion lambda\n\nsquare_area = lambda x: x**2\nprint(square_area(5))\n## Funciones anidadas\n\n\ndef exterior(x):\n    def interior(y):\n        return y * 2  # Esta es la función anidada\n\n    resultado_interior = interior(x)\n    return resultado_interior + 5\n\n\n# llamado a la función exterior\nresultado_exterior = exterior(10)\nprint(resultado_exterior)\n\n# variable global\nvariable_global = 10\n\n\ndef funcion():\n    # variable local dentro de la función\n    variable_local = 3\n    print(\"Variable local dentro de la función:\", variable_local)\n\n    # acceso a la variable global dentro de la función\n    print(\"Variable global dentro de la función:\", variable_global)\n\n\nfuncion()\n\n\ndef extra(param1, param2) -> int:\n    count = 1\n    numbers = []\n    while count <= 100:\n        if count % 3 == 0 and count % 5 == 0:\n            print(f\"{count} {param1} y {param2}\")\n        elif count % 3 == 0:\n            print(f\"{count} {param1}\")\n        elif count % 5 == 0:\n            print(f\"{count} {param2}\")\n        else:\n            numbers.append(count)\n        count += 1\n    return f\"{len(numbers)} Incidencias\"\n\nprint(extra(\"Múltiplo de 3\", \"Múltiplo de 5\"))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/emilianohoyos.py",
    "content": "\"\"\"\n EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n\"\"\"\n\"\"\"Sin parámetros ni retorno\"\"\"\ndef saludo():\n    print(\"hola\");\n\nsaludo()\n\n\"\"\" con uno o varios parámetros\"\"\"\ndef saludoConNombre(name):\n    print(\"Hello \"+name+\"!\")\n\nsaludoConNombre('emiliano')\n\n\"\"\" con retorno\"\"\"    \ndef producto(val1,val2):\n    return val1*val2\n\nprint(producto(3,2))\n\n\"\"\"Comprueba si puedes crear funciones dentro de funciones\"\"\"\ndef usuario():\n    def nombre():\n        print(\"carlos\")\n    nombre()\nusuario()\n\n\"\"\"Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\"\"\"\ndef argumentoMasGrande(val1,val2,val3):\n    valor=max(val1,val2,val3)\n    print(valor)\nargumentoMasGrande(3,2,1)\n\n\n#con un argumento por defecto\ndef default_saludo(name=\"carlos\"):\n    print(f\"Hola, {name}!\")\n\ndefault_saludo()\n\n#multiple return \ndef multiple_return_saludo():\n    return \"Hola\", \"python\"\n\ngreet,name=multiple_return_saludo()\nprint(greet)\nprint(name)\n\n#con un numero variable de argumentos\ndef variable_arg_saludo(*names):\n    for name in names:\n        print(f\"Hola,{name}!\")\n\nvariable_arg_saludo(\"php\", \"python\",\"emiliano\", \"carlos\")\n\n#con un numero variable de argumentos con palabras claves\ndef variable_key_arg_saludo(**names):\n    for key,name in names.items():\n        print(f\"Hola,{name} ({key})!\")\n\nvariable_key_arg_saludo( language=\"python\",nombre=\"emiliano\",alias=\"carlos\",edad=30)\n\n\"\"\"Pon a prueba el concepto de variable LOCAL y GLOBAL.\"\"\"\nnombre=\"emiliano\"\n\ndef saludo2():\n    nombre=\"Maria\"\n    print(\"Hola \"+ nombre)\n# Llamamos a la función\nsaludo2()\n\n# Imprimimos la variable global\nprint(\"La variable global es \" + nombre)\n \n\n\"\"\"DIFICULTAD EXTRA (opcional):\"\"\" \ndef imprimir(var1,var2)->int:\n    contador=0\n    for number in range(0,101):\n        if number%3==0 and number%5==0:\n           print(str(var1)+str(var2))\n        elif number%3==0:\n           print(str(var1))\n        \n        elif number%5==0:\n            print(str(var2))\n        else:\n           contador+=1\n           print(number)\n\n    return contador\n\nprint(imprimir(\"uno\",\"dos\"))   \n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/estelacode.py",
    "content": "#02 FUNCIONES Y ALCANCE\n\n### 1. Crea ejemplos de funciones básicas que representen las diferentes posibilidades del lenguaje:\n#   Sin parámetros ni retorno\n\ndef saludar():\n    print(\"Hola\")\n\nsaludar()\n\n#   Con uno o varios parámetros\ndef saludar(mensaje, name):\n    print(f'{mensaje}, {name}!')\n\nsaludar('Hola', 'Estela')\n\n#  con retorno  y con asignación de valores por defecto a todos los parametros de la función.\n\ndef returns_greeting(greeting = 'Hi', name = 'Python ♡︎ Lovers'):\n    return f'{greeting}, {name}!'\n\nprint(returns_greeting()) # asigna valores por defecto permite llamar la función sin argumentos.\nprint(returns_greeting('Good morning', 'Estela'))\n\n### 2. Comprueba si puedes crear funciones dentro de funciones.\n#   * Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n\ndef solucion(num1, num2):\n\n    def suma(num1, num2):   \n        return num1 + num2\n    \n    def resta(num1, num2):\n        return num1 - num2\n    \n    return suma(num1, num2),  resta(num1, num2)\n\nsuma, resta = solucion(5,3)\nprint(f' El resultado de la suma es {suma} y resultado de la resta {resta}')\n\n### 3. Pon a prueba el concepto de variable LOCAL y GLOBAL.\n# NOTA:  Debes hacer print por consola del resultado de todos los ejemplos.(y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n\n# variable global: Son aquellas variables que se definen fuera de cualquier función y que son accesibles en todo el programa, es decir, dentro y fuera de cada función.\n# variable local: Son aquellas que se inicializan dentro de una función y pertenecen solo a esa función en particular. \n# NameError: se genera un error de tipo NameError: name 'x' is notdefined cuando el programa intenta acceder o utilizar una variable que no ha sido definida o a la que no se le ha asignado un valor.\n\n## LOCAL SCOPE\n#-----------------------------------------------------------------------------------\ndef local_scope():\n    # local variables\n    a = 'Python'\n    b = 'Lovers'\n    return a + b\n\n# Se puede capturar con unico  bloque try/except la expeción de las dos variables locales.\ntry:\n    result = local_scope() # Imprime 'PythonLovers' variables definidas dentro de la función. \n    print(result)\n    # Si se intenta acceder a las variables 'a' y 'b' desde fuera de la función se producira un error.\n    print(a) # NameError: name 'a' is not defined\n    print(b) # NameError: name 'b' is not defined\nexcept NameError:\n    print(\"Error: NameError: Las variables 'a' o 'b' no son accesibles desde fuera de la función. Son variables locales\")\n\n# Se puede capturar diferentes excepciones  para dos variables locales distintas mediante bloques try/except separados.\ntry:\n    print(a) # NameError: name 'a' is not defined\nexcept NameError:\n    print(\"Error: NameError: La variable 'a' no está definida\")\n\ntry:\n    print(b) # NameError: name 'b' is not defined\nexcept NameError:\n    print(\"Error: NameError: La variable 'b' no está definida\")\n\n\n## GLOBAL SCOPE\n#-----------------------------------------------------------------------------------\ndef global_scope():\n    '''This function uses global variable s'''\n    print(\"Inside Function: \", s)\n\n# Global scope\ns = \"Python ♡︎ Lovers\"\nglobal_scope()\nprint(\"Outside Function: \", s)\n\n## SE DEFINE UNA VARIABLE GLOBAL Y UNA LOCAL CON EL MISMO NOMBRE\n# #-----------------------------------------------------------------------------------\n\ndef same_name():\n    v = \"Local\"\n    print(f'Se imprime el valor de la variable local : {v}')\n\nv=\"Global\"\nsame_name()\nprint(f'Se imprime el valor de la variable global: {v}')\n\n\n## MODIFICAL EL VALOR DE UNA VARIABLE GLOBAL\n#-----------------------------------------------------------------------------------\n# Si se trata de modificar el valor de una  variable global  desde dentro de una función, se obtiene el error:  'UnboundLocalError : se hizo referencia a la variable local 's' antes de la asignación'.\n# para modificar el valor de una variable global desde dentro de una función, debemos utilizar la palabra clave \"global\" .\n\ndef modify_global_without_global():\n    try:\n        s += \"♡︎...\"  \n    except UnboundLocalError:\n        print(\"Error: 'UnboundLocalError : se hizo referencia a la variable local 's' antes de la asignación'.\")\n\ndef modify_global():\n\n    global s\n    s += \"♡︎♡︎♡︎\"\n    print(s)\n\n# Global Scope\ns = \"Python is great!\" \nmodify_global_without_global()\nmodify_global()\n\n\n### * DIFICULTAD EXTRA (opcional):\n#-----------------------------------------------------------------------------------\n''' * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n    *   - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n    *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n    *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n    *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n    *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n '''\n\n\ndef get_text_and_return_number(string1, string2):\n    count = 0 # numero de veces que se imprime el numero.\n    for i in range(1, 101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(string1 + string2)\n        elif i % 5 == 0:\n            print(string2)\n        elif i % 3 == 0:\n            print(string1)\n        else:\n            print(i)\n            count += 1\n    return count\n\nprint(\"Número de veces que se ha impreso el número en lugar de los textos: \", get_text_and_return_number(\"Multiplo de 3 \", \"Multiplo de 5\")) "
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/evilpodato04.py",
    "content": "#/*\n# * EJERCICIO:\n# * - Crea ejemplos de funciones básicas que representen las diferentes\n# *   posibilidades del lenguaje:\n# *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n\ndef funcion_sin_parametro_ni_retorno():\n    print(\"Hello, world!\")\n\ndef funcion_con_parametros(nombre, edad):\n    print(f\"My name is {nombre}, tengo {edad} años de edad\")\n\ndef funcion_con_parametros_y_retorno(pasatiempo, comida_favorita):\n    return f\"I love {pasatiempo} and to eat {comida_favorita} at weekends\"\n\nfuncion_sin_parametro_ni_retorno()\n\nfuncion_con_parametros(\"Samunta\", \"19\")\n\nretorno = funcion_con_parametros_y_retorno(\"to play games\", \"pizza\")\nprint(retorno)\n\n# * - Comprueba si puedes crear funciones dentro de funciones.\n\ndef funcion_exterior(param):\n    def funcion_interior():\n        return \"This is the internal function return\"\n    \n    return funcion_interior() if param == True else \"This is the external function return\"\n\nprint(funcion_exterior(True))\nprint(funcion_exterior(False))\n\n# * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n\nprint(\"I'm hungry\")\nprint(len([\"Sandwich\", \"Pizza\", \"Chocolate\", \"Donut\"]))\nprint(input(\"Write something cool: \"))\n\n# * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n\njuego_actual = \"Genshin Impact\"\njuego_siguiente = \"Aún no elegido\"\n\ndef empezar_juego():\n    juego_siguiente = \"Legend of Zelda\"\n    print(\"LOCAL SCOPE:\", juego_actual)\n    print(\"LOCAL SCOPE:\", juego_siguiente)\n\nempezar_juego()\nprint(\"GLOBAL SCOPE:\", juego_actual)\nprint(\"GLOBAL SCOPE:\", juego_siguiente)\n\n# * - Debes hacer print por consola del resultado de todos los ejemplos.\n# *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n\n\n# * DIFICULTAD EXTRA (opcional):\n# * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n# * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n# *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n# *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n# *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n# *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n# *\n# * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n# * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n# */\n\ndef desafio(texto_1, texto_2):\n    for numero in range(1,101):\n        if numero % 3 == 0 and numero % 5 == 0:\n            print(texto_1)\n            print(texto_2)\n        elif numero % 3 == 0:\n            print(texto_1)\n        elif numero % 5 == 0:\n            print(texto_2)\n        else:\n            print(numero)\n    return numero\n\ndesafio(\"Pizza\", \"Sandwich\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/fborjalv.py",
    "content": "# FUNCIONES EN PYTHON \n\n# Funcionaes sin parámetros y sin retorno\n\ndef func_no_param_no_return():\n    print(\"Soy una función sin parámetros ni retorno\")\n\n# Funciones con un parametro\n\nfunc_no_param_no_return()\n\ndef func_param_no_return(param1, param2):\n    print(f\"Soy una función con estos parametros: {param1, param2}\")\n\nfunc_param_no_return(354, \"string\")\n\ndef func_param_no_return_tipado(param1: str, param2: int): \n    print(f\"Soy una función con estos parametros tipados: {param1, param2}\")\n\nfunc_param_no_return_tipado(354, \"string\") # Python no impore restricciones  \n\ndef func_param_predefinidos(name=\"Borja\", l_name=\"Laja\"):\n    print(f\"Soy {name} {l_name}\")\n\nfunc_param_predefinidos()\nfunc_param_predefinidos(\"Brais\", \"Moure\")\n\n# Funciones con varios parámetros\n\ndef func_param_varias_variables(*nombres):\n    print(nombres)\n\nfunc_param_varias_variables(\"Montaña\", \"Playa\", \"Campo\")\n\n# Con un número variable de argumentos con palabra clave\n\ndef variable_key_arg_greet(**names):\n    for key, value in names.items():\n        print(f\"{value} ({key})!\")\n\n\nvariable_key_arg_greet(\n    language=\"Python\",\n    name=\"Borja\",\n    alias=\"fborjalv\",\n    age=32)\n\n# Funciones con retorno\n\ndef func_con_retorno(numero, numero_2):\n    return numero + numero_2\n\nprint(func_con_retorno(2, 3))\n\n# Funciones con varios retornos \n\ndef func_con_varios_retornos(numero, numero_2):\n    return numero, numero_2\nprint(func_con_varios_retornos(4, 6))\n\n# Funciones dentro de funciones \n\ndef func_padre():\n    print(\"soy la función padre\")\n    def func_hijo():\n        print(\"soy la función hijo\")\n    func_hijo()\n\nfunc_padre()\n\n# Variables locales y globales\n\nmy_var_global = \"Soy una variable global\"\n\ndef manejo_de_variables():\n    my_var_local = \"Soy una variable local\"\n    print(my_var_global)\n    print(my_var_local)\n    \n\n    def manejo_de_variables_hija(): \n        my_var_local_hija = \"Soy variable local hija\"\n        print(my_var_global)\n        print(my_var_local)\n        print(my_var_local_hija)\n\nprint(my_var_global)\nprint(manejo_de_variables())\n\n# EJERCICIO EXTRA\n\ndef multiplos (text: str, text_2: str):\n\n    contador = 0\n\n    for index in range(1, 101):\n\n        if index % 3 == 0 and index % 5 == 0:\n            print(index, text + \" \" + text_2)\n            \n        elif index % 3 == 0:\n            print(index, text)\n            \n        elif index % 5 == 0:\n            print(index, text_2)\n            \n        else: \n            print(index)\n            contador += 1\n\n    return contador\n\ncontador = multiplos(\"primer\", \"segundo\")\nprint(f\"Números que no son múltiplos ni de 3 ni de 5: {contador}\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/fishellVvv.py",
    "content": "# función simple\ndef greet():\n    print(\"Hola, Python!\")\n\n# función con retorno\ndef return_greed():\n    return \"Hola, Python!\"\n\n# función con argumentos\ndef arg_greed(name):\n    print(f\"Hola, {name}!\")\n\n# función con argumentos predeterminados\ndef default_arg_greet(name = \"Python\"):\n    print(f\"Hola, {name}!\")\n\n# función con retorno de varios valores\ndef multiple_return_greet():\n    return \"Hola\", \"Python\"\n\n# función con un número variable de argumentos\ndef variable_arg_greet(*names):\n    for name in names:\n        print(f\"Hola, {name}!\")\n\n# función con un número variable de argumentos con palabra clave\ndef variable_key_arg_greet(**names):\n    for key, value in names.items():\n        print(f\"{value} ({key})\")\n\n# funciones dentro de funciones\ndef outer_function():\n    def inner_function():\n        print(\"Hola, Python! (función interna)\")\n    inner_function()\n\n# funciones del lenguaje\nprint(len(\"fishellVvv\"))\nprint(type(\"fishellVvv\"))\nprint(\"fishellVvv\".upper())\n\n# variables locales y globales\nglobal_var = \"Python\"\ndef greed_2():\n    print(f\"Hola, {global_var}!\")\n    local_var = \"Mundo\"\n    print(f\"Hola, {local_var}!\")\ngreed_2()\nprint(f\"Hola, {global_var}!\")\n\n# extra\ndef print_numbers(text_1, text_2)-> int:\n    count = 0\n    for i in range(1, 101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(text_1 + text_2)\n        elif i % 3 == 0:\n            print(text_1)\n        elif i % 5 == 0:\n            print(text_2)\n        else:\n            count += 1\n            print(i)\n    return count\nprint(print_numbers(\"Fizz\", \"Buzz\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/francomyburg.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\"\"\"\n\n# Funcion sin parametros\ndef sin_parametros():\n    print(\"la funcion no recibi parametros y no tiene retorno\")\n\n# Funcion con parametros y retorno\ndef con_parametros(parametro1,parametro2):\n    print(f\"la funcion imprime el parametro 1:{parametro1} y el parametro 2:{parametro2 }\")\n    print(\"retorno la concatenacion con un espacio de parametro 1 y parametro 2\")\n    return parametro1 + \" \" + parametro2\n\n# funcion dentro de una funcion\ndef imprimir_suma(num1,num2):\n    def suma(num1,num2):\n        return num1+num2\n    \n    print(suma(num1,num2))\n\ndef extra(param1=\"fizz\",param2=\"buzz\"):\n\n    for i in range(1,101):\n        if i % 3 == 0:\n            if i % 5 == 0:\n                print(i,param1+param2)\n            else:\n                print(i,param1)\n        elif i % 5 == 0:\n            print(i,param2)\n        else:\n            print(i,\"____\") \n\n\n\n\nif __name__ == \"__main__\":\n    \n    sin_parametros()\n\n    retorno = con_parametros(\"hola\",\"mundo\")\n    print(retorno)\n\n    imprimir_suma(4,3)\n\n    extra()\n\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/franvozzi.py",
    "content": "'''\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n'''\n\ndef saludo(): # Sin parámetro ni retorno\n    print(\"Hola!\")\n\ndef suma(a, b): # Dos parametros\n    print(a + b)\n\ndef cubo (a, b, c): # Tres parámetros\n    print(a * b * c)\n    \ndef incremento(numero): # Funcion dentro de otra funcion\n    def incrementoInterior():\n        return numero + 1\n    print(incrementoInterior())\n\ndef terrenoCasa():\n    lado1 = 10\n    lado2 = 40\n    metrosCuadrados = lado1 * lado2\n    return metrosCuadrados\n\n# print(lado1) # No está definido, fuera del scope \"terreno casa\"\n\n\n# DESAFÍO EXTRA\ndef imprimeNumeros(texto1, texto2) ->int:\n    for numero in range(1, 101):\n        if numero % 3 == 0 and numero % 5 == 0:\n            print(texto1 + texto2)\n        elif numero % 3 == 0:\n            print(texto1)\n        elif numero % 5 == 0:\n            print(texto2)\n        \n        else: print(numero)\n\nimprimeNumeros(\"hola \", \"chau\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/franxiscodev.py",
    "content": "\"\"\"\nFunciones definidas por el usuario\n\"\"\"\n# simple función que imprime un mensaje\n\n\ndef hola():\n    print(\"Hola mundo\")  # Hola mundo\n\n# función simple con retorno sin argumentos\n\n\ndef hola_mundo() -> str:\n    return \"Hola mundo\"  # Hola mundo necesito un print o guardar el resultado en una variable\n\n# función con argumentos y retorno de valor\n\n\ndef saludo(tipo: str, nombre: str) -> str:\n    return f\"{tipo}: {nombre}\"  # Hola Franxisco\n\n\nprint(saludo(\"Chau\", \"Franxisco\"))\n\n# función con argumentos predeterminados\n\n\ndef saludo2(tipo: str, nombre: str = \"Franxisco\") -> str:\n    return f\"{tipo}: {nombre}\"  # Hola Franxisco\n\n\nprint(saludo2(\"Hola\"))\n\n# función con multiples retornos str\n\n\ndef saludo3(tipo: str, nombre: str = \"Franxisco\") -> str:\n    return tipo, nombre\n\n\n# desacoplar los valores\ntipo, nombre = saludo3(\"Buenas\", \"Valencia\")\nprint(tipo)  # Hola\nprint(nombre)  # Franxisco\n\n# función con multiples argumentos *\n\n\ndef saludo_args(*args: str) -> str:\n    for arg in args:\n        print(f\"Hola: {arg}\")\n\n\n# Hola: Franxisco Hola: Valencia Hola: Python\nsaludo_args(\"Franxisco\", \"Valencia\", \"Python\")\nsaludo_args()\n\n# función con multiples argumentos **kwargs\n\n\ndef saludo_kwargs(**kwargs: str) -> str:\n    for key, value in kwargs.items():\n        print(f\"{key}: {value}\")\n\n\nsaludo_kwargs(nombre=\"Franxisco\", ciudad=\"Valencia\", lenguaje=\"Python\")\nsaludo_kwargs(nombre=\"Franxisco\", lenguaje=\"Python\", pais=\"España\")\nsaludo_kwargs()\n\n# función dentro de otra función\n\n\ndef outer_function():\n    print(\"Outer function\")\n\n    def inner_function():\n        print(\"Inner function\")\n    inner_function()\n\n\nouter_function()\n\n# funciones built-in\nprint(len(\"Hola mundo\"))  # 10\nprint(type(\"Hola mundo\"))  # <class 'str'>\n\n# funciones built-in por tipo de dato\nprint(str(5))  # 5\nprint(int(\"5\"))  # 5\nprint(float(\"5\"))  # 5.0\nprint(bool(5))  # True\nprint(\"Hola mundo\".upper())  # HOLA MUNDO\nprint(\"Hola mundo\".lower())  # hola mundo\nprint(\"Hola mundo\".split())  # ['Hola', 'mundo']\nprint(\"Hola, mundo\".split(\",\"))  # ['Hola ', 'mundo']\nprint(\"Hola mundo\".replace(\"mundo\", \"Python\"))  # Hola Python\nprint(\"Hola mundo\".find(\"mundo\"))  # 5\nprint(\"Hola mundo\".count(\"o\"))  # 2\nprint(\"Hola mundo\".startswith(\"Hola\"))  # True\nprint(\"Hola mundo\".endswith(\"mundo\"))  # True\nprint(\"Hola mundo\".isnumeric())  # False\nprint(\"Hola mundo\".isalpha())  # False\nprint(\"Hola mundo\".isalnum())  # False\nprint(\"Hola mundo\".islower())  # False\nprint(\"Hola mundo\".isupper())  # False\nprint(\"Hola mundo\".istitle())  # False\nprint(\"Hola mundo\".isspace())  # False\nprint(\"Hola mundo\".strip())  # Hola mundo\nprint(\"Hola mundo\".lstrip())  # Hola mundo\nprint(\"Hola mundo\".rstrip())  # Hola mundo\nprint(\"Hola mundo\".center(20))  # Hola mundo\nprint(\"Hola mundo\".ljust(20))  # Hola mundo\nprint(\"Hola mundo\".rjust(20))  # Hola mundo\nprint(\"Hola mundo\".zfill(20))  # 000000000Hola mundo\nprint(\"hola mundo\".capitalize())  # Hola mundo\nprint(\"Hola mundo\".title())  # Hola Mundo\nprint(\"Hola mundo\".swapcase())  # hOLA MUNDO\n\n# ejemplos ambito de variables\n# variable global\nx = 5\n# variable local\n\n\ndef sumar(x: int, y: int) -> int:\n    return x + y\n\n\nprint(sumar(7, 5))  # 12\nprint(x)  # 5\n\n'''\nDIFICULTAD EXTRA\n'''\n\n\ndef print_numbres(text_1: str, text_2: str) -> int:\n    count = 0\n    for i in range(1, 101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(f\"{i}: {text_1} + {text_2}\")\n        elif i % 3 == 0:\n            print(f\"{i}: {text_1}\")\n        elif i % 5 == 0:\n            print(f\"{i}: {text_2}\")\n        else:\n            print(i)\n            count += 1\n    print(f\"Total de veces que salen nros: {count}\")\n\n\nprint_numbres(\"Fizz\", \"Buzz\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/frostbitepy.py",
    "content": "#02 - Python\n\n\"\"\" * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n\"\"\"\n\n# Función sin parámetros ni retorno\ndef greet():\n    print(\"Hello, world!\")\n\n# Función con un parámetro\ndef greet_person(name):\n    print(f\"Hello, {name}!\")\n\n# Función con múltiples parámetros\ndef add_numbers(num1, num2):\n    return num1 + num2\n\n# Función con retorno\ndef square_number(num):\n    return num ** 2\n\n# Función dentro de una función\ndef outer_function():\n    def inner_function():\n        print(\"This is an inner function\")\n    inner_function()\n\n# Uso de una función incorporada en Python\ndef show_length(s):\n    print(len(s))\n\n# Variable global y local\nx = \"global\"\n\ndef test_scope():\n    global x\n    y = \"local\"\n    x = x * 2\n    print(x)\n    print(y)\n\n# Llamada a las funciones\ngreet()\ngreet_person(\"Francisco\")\nprint(add_numbers(5, 3))\nprint(square_number(4))\nouter_function()\nshow_length(\"Hello, world!\")\ntest_scope()\n\n\n# Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\ndef print_numbers_and_strings(str1, str2):\n    count = 0\n    for i in range(1, 101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(str1 + str2)\n        elif i % 3 == 0:\n            print(str1)\n        elif i % 5 == 0:\n            print(str2)\n        else:\n            print(i)\n            count += 1\n    return count\n\n# Llamada a la función\nprint(print_numbers_and_strings(\"perro\", \"salchicha\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/gabrielramos02.py",
    "content": "# 02 Funciones y alcance\n\n\n# Funcion sin parametros ni retorno\ndef imprimir_texto():\n    print(\"Esto es un texto dentro de una funcion\")\n\n\n# Funcion con un solo parametro\ndef imprimir_numero(numero: int):\n    print(numero)\n\n\n# Funcion con varios parametros\ndef imprimir_suma(num1: int, num2: int):\n    print(num1 + num2)\n\n\n# Funcion con retorno\ndef devolver():\n    return \"Hola\"\n\n\n# Funcion con funcion dentro\ndef fun_externa():\n    def fun_interna():\n        print(\"Funcion anidada\")\n\n    fun_interna()\n\n\n# Variables locales y globales\nvar1 = \"Global\"\n\n\ndef probando_variables():\n    var1 = \"Local\"\n    print(f\"Esta variable tiene valor {var1}\")\n\n\n# Ejecucion de funciones\nimprimir_texto()\nimprimir_numero(3)\nimprimir_suma(2, 3)\nprint(devolver())\nfun_externa()\nprobando_variables()\nprint(f\"Esta variable tiene valor {var1}\")\n\n\n# Funciones del lenguaje\nprint(float.is_integer(2.3))  # Funcion que permite preguntar si un float es entero\n\n# Dificultad extra\n\ndef fun_principal(string1: str,string2: str):\n    contador = 0\n    for i in range(100):\n        if (i+1) % 3 == 0 and (i+1) % 5 == 0:\n            print(string1 + string2)\n        elif (i+1) % 3 == 0:\n            print(string1)\n        elif (i+1) % 5 == 0:\n            print(string2)\n        else: \n            print(i+1)\n            contador+=1\n    \n    return contador\n\nprint(\"Cantidad de iteraciones: \", fun_principal(\"Cadena 1\",\"Cadena 2\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/garos01.py",
    "content": "# Ejemplo 1: Función sin parámetros ni retorno\ndef saludar():\n    print(\"¡Hola, mundo!\")\n\n\nsaludar()\n\n\n# Ejemplo 2: Función con un parámetro y retorno\ndef cuadrado(numero):\n    return numero**2\n\n\nresultado_cuadrado = cuadrado(5)\nprint(\"El cuadrado de 5 es:\", resultado_cuadrado)\n\n\n# Ejemplo 3: Función con varios parámetros y retorno\ndef suma(a, b):\n    return a + b\n\n\nresultado_suma = suma(3, 7)\nprint(\"La suma de 3 y 7 es:\", resultado_suma)\n\n\n# Ejemplo 4: Función dentro de otra función\ndef operacion_compleja(x, y):\n    def multiplicar(a, b):\n        return a * b\n\n    resultado_multiplicacion = multiplicar(x, y)\n    return resultado_multiplicacion + 10\n\n\nresultado_operacion = operacion_compleja(2, 3)\nprint(\"El resultado de la operación compleja es:\", resultado_operacion)\n\n# Ejemplo 5: Variable local y global\nvariable_global = 10\n\n\ndef funcion_con_variables():\n    variable_local = 5\n    print(\"Variable local dentro de la función:\", variable_local)\n    print(\"Variable global dentro de la función:\", variable_global)\n\n\nfuncion_con_variables()\n\n# Intentar acceder a variable_local aquí daría un error, ya que es local a la función.\n# print(\"Intento de acceder a variable_local fuera de la función:\", variable_local)\nprint(\"Variable global fuera de la función:\", variable_global)\n\n\n# Ejercicio extra\ndef imprimir_numeros_y_contar_textos(texto1, texto2):\n    contador_textos = 0\n\n    for numero in range(1, 101):\n        if numero % 3 == 0 and numero % 5 == 0:\n            print(texto1 + texto2)\n            contador_textos += 1\n        elif numero % 3 == 0:\n            print(texto1)\n            contador_textos += 1\n        elif numero % 5 == 0:\n            print(texto2)\n            contador_textos += 1\n        else:\n            print(numero)\n\n    return contador_textos\n\n\n# Ejemplo de uso:\nresultado = imprimir_numeros_y_contar_textos(\"Fizz\", \"Buzz\")\nprint(f\"Se imprimieron {resultado} textos en total.\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/ggilperez.py",
    "content": "\"\"\"\nProblem #02 functions\n\"\"\"\n\n\n# Different functions\ndef simple_func():\n    \"\"\"\n    Simplest function, without params neither return\n    \"\"\"\n    print(\"Simple Function\")\n    # No return statement means return None by default\n\n\nprint(f\"{simple_func()=}\")\n\n\ndef args_func(num1, num2):\n    \"\"\"\n    Function with params\n    \"\"\"\n    print(f\"My params => {num1=} {num2=}\")\n    return num1 + num2  # with explicit return\n\n\nprint(f\"{args_func(1, 2)=}\")\n\n\ndef kwargs_func(num1=2, num2=2):\n    \"\"\"\n    Function with key word arg params\n    \"\"\"\n    print(f\"My params => {num1=} {num2=}\")\n    return num1 ** num2\n\n\nprint(f\"{kwargs_func()=}\")\n\n\ndef args_and_kwargs_func(num1, num2=2):\n    \"\"\"\n    Function with param as arg and key word arg\n    \"\"\"\n    print(f\"My params => {num1=} {num2=}\")\n    return num1 // num2\n\n\nprint(f\"{args_and_kwargs_func(1)=}\")\n\n\ndef n_params_func(*args, **kwargs):\n    \"\"\"\n    Function with N args and N key word args\n    \"\"\"\n    print(f\"My params:\")\n    print(f\"\\t{args = }\")\n    print(f\"\\t{kwargs = }\")\n    return args, kwargs  # Multiple values returned as tuple\n\n\nprint(f\"{n_params_func([1, 2, 3, 4], key1='param1', key2='param2')=}\")\n\n\n# Function inception\ndef outer_func():\n    def inner_func():\n        print(\"Hello from inner_func\")\n\n        def ultra_inner_func():\n            print(\"Hello from ultra_inner_func\")\n            # ... and so on\n\n        ultra_inner_func()\n\n    print(\"Hello from outer_func\")\n    inner_func()\n\n\nprint(outer_func())\n\n# Built-in functions\nmy_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]\nprint(f\"my_list has {len(my_list)} elements\")\nprint(f\"rounded division {int(10/9) = }\")  # Also for casting types\nprint(\"Hello World\")  # print it's a builtin function\n\n# LOCAL and GLOBAL variables\nmy_global_int = 10\n\n\ndef print_int():\n    my_local_int = 20\n    print(f\"{my_local_int=}\")  # can use local vars\n    print(f\"{my_global_int=}\")  # can use global vars\n\n\nprint(f\"{my_global_int=}\")  # can use global vars\n# can't use function local vars, out of scope\n\n# EXTRA\ndef extra(arg1: str, arg2: str) -> int:\n    printed = 0\n    for num in range(1, 101):\n        if num % 3 == 0 and num % 5 == 0:\n            print(arg1 + arg2)\n        elif num % 3 == 0:\n            print(arg1)\n        elif num % 5 == 0:\n            print(arg2)\n        else:\n            print(num)\n            printed += 1\n    return printed\n\n\nprint(extra(\"multiple of 3\", \"multiple of 5\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/ggtorca.py",
    "content": "'''\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n '''\nprint(\"Ejercicio #02 - Funciones y Alcance\")\nprint(\"-----------------------------------\")\nprint(\"\")\n\n#Funcion sin parámetros ni retorno\n\ndef holaMundo():\n    print(\"Hola mundo!\")\n\nprint(\"Funcion sin parámetros ni retorno\")\nprint(\"\")\nholaMundo() #Llamada a la función, se imprime \"Hola mundo!\"\nprint(\"\")\n\n#Funcion con un parametro\n\ndef holaPersona(nombre):\n    print(\"Hola \" +nombre +\"!\")\n\nprint(\"Funcion con un parametro\")\nprint(\"\")\nholaPersona(\"Pedro\") #Llamada a la función, se imprime \"Hola Pedro!\"\nprint(\"\")\n\n#Funcion con varios parametros y retorno\n\ndef multiplicacion (val1, val2):\n    return val1 * val2\n\nprint(\"Funcion con varios parametros\")\nprint(\"\")\n\nval1 = int(input(\"Introduce el primer valor: \"))\n\nval2 = int(input(\"Introduce el segundo valor: \"))\n\n\nprint(f\"\\nEl resultado de la multiplicación es: {multiplicacion (val1, val2)}\") #Llamada a la función, se imprime el resultado de multiplicacion.\n\n#¿Se pueden crear funciones dentro de funciones?\n\ndef funcionPrincipal(x, y):\n    def funcionInterna(y):\n        return y + y\n    return funcionInterna(x) * y\n\nx = int(input(\"Establece el valor de x: \"))\ny = int(input(\"Establece el valor de y: \"))\n\nresultadoOperacion = funcionPrincipal(x, y)\n\nprint(f\"\\n El resutlado final es: {resultadoOperacion}\") #Llamada a la función, se imprime el resultado de x*(y+y)\n\n#Funciones propias del lenguaje\n\n#len()\npalabra = \"aerodromo\"\nlongitud =len(palabra)\n\nprint(longitud) #Imprime la longitud de la palabra \"aerodromo\"\n\n#type()\nprint(type(24)) #Imprime que es un int\nprint(type(\"reactor\")) #Imprime que es un string\n\n#range()\nfor i in range(4):\n    print (i) # Imprime una lista del 0 al 3\n\n#sum()\nnumeros = [10, 20, 30]\ntotal = sum(numeros)\nprint(total) #Imprime el total de la suma de los numeros establecidos previamente\n\n#Variables LOCALES y GLOBALES\n\n#Variable LOCAL\n\ndef sumar (a, b):\n    total = a + b #total es una variable local ya que unicamente es accesible dentro de la funcion sumar\n    return total\nprint(sumar(1, 2))\n\n#Variable GLOBAL\ncontador = 0 # La variable contador se declara fuera de una funcion\ndef incrementar():\n    global contador # Se establece que se va a usar la variable global \"contador\"\n    contador += 1\n\ndef imprimirContador():\n    print(contador)\n\nprint(f\"el contador esta a {contador}\")\nvecesIncrementar = int(input(\"Cuantas veces quieres incrementar el contador? \"))\nfor i in range(vecesIncrementar):\n    incrementar()\nprint(f\"\\n El contador ahora está a \", end=\"\")\n\nimprimirContador()\n\n#Dificultad extra\n\ndef dificultadExtra(cadena1, cadena2):\n    contarNumeros = 0\n\n    for numero in range(1, 101):\n        if numero % 3 == 0 & numero % 5 == 0:\n            print(cadena1 + cadena2)\n        elif numero % 3 == 0:\n            print(cadena1)\n        elif numero % 5 == 0:\n            print(cadena2)\n        else:\n            print(numero)\n            contarNumeros += 1\n\n    return contarNumeros\ncadena1 = \"hey\"\ncadena2 = \"ho\"\nresultado = dificultadExtra(cadena1, cadena2)\n\nprint(f\"Se imprimio un numero {resultado} veces\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/giulianovfz.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n\"\"\"\n\n\n# función sin parámetro\ndef mensaje():\n    print('\\nBienvenidos y Bienvenidas a la resolución de retos de programación')\n\n\nmensaje()\n\n\n# función con un solo parámetro sin retorno\ndef bienvenida(nombre: str):\n    print(f'\\nHola, {nombre}, ánimo con los retos de programación')\n\n\nbienvenida('giulianovfz')\n\n\n# función con un solo parámetro y valor por defecto, sin retorno\ndef saludo(nombre=\"compañeros y compañeras\"):\n    print(f'\\nHola, {nombre}, ánimo con los retos de programación')\n\n\nsaludo()\n\nvalor1 = 8\nvalor2 = 5\n\n\n# función con parámetros sin retorno\ndef suma(a, b):\n    print(f'valor de la suma a+b: {a+b}')\n\n\nsuma(valor1, valor2)\n\n\n# función con parámetros y retorno\ndef resta(a, b):\n    return a-b\n\n\nresultado_resta = resta(valor1, valor2)\nprint(resultado_resta)\n\n\"\"\"\nFunciones del lenguaje\n\"\"\"\n\nlista = list((\"Pala\", \"Picota\", \"Rastrilo\"))\nprint(lista)\nprint(len(lista))\nprint(list((enumerate(lista))))\n\n\n\"\"\"\nVariables locales y globales\n\"\"\"\n\nvariable_global = \"Planeta Tierra\"\n\n\ndef continente():\n    variable_local = \"Continente Americano\"\n    print(f\"\"\"Variable global:{\n          variable_global}, Variable local:{variable_local}\"\"\")\n\n\n# crear una función dentro de otra\ndef modulo(numero: int):\n\n    print(f'valor número: {numero}')\n\n    def duplicar(aduplicar):\n        return aduplicar*2\n\n    if numero % 2 == 0:\n        resultado = duplicar(numero)\n        print(f'el valor duplicado es: {resultado} y es multiplo de 2')\n    else:\n        print(f'El valor ingresado: {numero} no es multiplo de 2')\n\n\nmodulo(5)\n\n\n# dificultad extra\ndef imprimir(parametro1: str, parametro2: str):\n\n    contador = 0\n\n    # imprimir todos los números del 1 al 100\n    for numero in range(1, 101):\n\n        if numero % 3 == 0 and numero % 5 == 0:\n            print(f'cadena de texto concatenadas parametro 1 y 2: {\n                  parametro1}{parametro2}')\n        elif numero % 5 == 0:\n            print(f'cadena de texto segundo parametro: {parametro2}')\n        elif numero % 3 == 0:\n            print(f'cadena de texto primer parametro: {parametro1}')\n        else:\n            contador += 1\n            print(f'número:{numero}')\n\n    return contador\n\n\nentrada1 = input('\\ningresa el primer texto: ')\nentrada2 = input('\\ningresa el segundo texto: ')\n\nrespuesta = imprimir(entrada1, entrada2)\n\nprint(f'\\n número de veces que se imprimio solo números:{respuesta}')\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/gjbecerrae.py",
    "content": "#Funcion sin parametros ni retorno\ndef printFunction():\n    print('Esta es una funcion sin parametros ni retorno')\n\n#Funcion con 1 parametro sin retorno\ndef oneParameterFunction(a):\n    print(f'Esta es una funcion de un parametro -> {a}')\n\ndef twoParameterFunction(a,b=1,c=2):\n    print(f'Esta funcion tiene 3 parametros {a}, {b} y {c}. Si c no esta en los parametros toma el valor por defecto de 2')\n\ndef returnFuncionNoParameters():\n    print('Esta es una funcion con retorno y sin parametros')\n    return 'return'\n\ndef returnFuncionParameters(param1):\n    print('Esta es una funcion con retorno y con parametros. El retorno es ->')\n    return param1*2\n\ndef internalFunction():\n    value = 6\n    return value\n\ndef Externalfunction():\n    internalValue = internalFunction()\n    newValue = internalValue * 2\n    if newValue == 12:\n        print ('Las funciones se pueden utilizar dentro de otras funciones')\n    else:\n        print ('Las funciones no se pueden utilizar dentro de otras')\n\ndef gobalVarFunction():\n    print(f'{myGlobal} dentro de una funcion')\n\n#Ejercicio Opcional:\ndef stringToNumber(string1, string2):\n    counter = 0\n    for i in range (1,101):\n        if  i % 3 == 0 and i % 5 == 0:\n            print(string1,string2)\n            counter += 1        \n        elif i % 3 == 0:\n            print (string1)\n            counter += 1\n        elif i % 5 == 0:\n            print (string2)\n            counter += 1\n        else:\n            print(i)\n    numero = 100 - counter\n    return  numero\n\n#Llamadas a funciones\nprint(\"\\n-----------------------------------------------------------\")\nprint('Llamadas a Funciones \\n')\nprintFunction()\noneParameterFunction('Hola soy el parametro')\ntwoParameterFunction(10,20)\nprint(returnFuncionNoParameters())\nretorno = returnFuncionParameters(3)\nprint(retorno)\nExternalfunction()\nprint(\"\\n-----------------------------------------------------------\")\n\n#Python build-in functions\nprint(\"\\nLa funcion Len nos permite obtener la talla de una lista ->\")\nmiLista = ['esta','es','mi','lista']\nprint (f'Mi lista es => {miLista} \\nY tiene una talla de {len(miLista)}')\n\nprint(\"\\n-----------------------------------------------------------\")\n\nmyGlobal = 'Esta es una variable global'\n\nfor i in range (3):\n    myLocal = 'Esta es una variable local'\n    if i == 0:\n        print (f'{myLocal}. No puedo usarla fuera de este loop')\n   \n    if i == 2:\n        print (f'{myGlobal} Puedo usarla dentro de mi for loop ')\n        gobalVarFunction()\n\nprint(\"\\n-----------------------------------------------------------\")\nprint('Ejercicio Opcional \\n')\n\nopcional = stringToNumber('primer parametro','segundo parametro')\nprint(f'El numero se ha impreso {opcional} veces')\n\n\n\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/gmbarrios.py",
    "content": "\"\"\"\n- Crea ejemplos de funciones básicas que representen las diferentes posibilidades del lenguaje: sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n- Comprueba si puedes crear funciones dentro de funciones.\n- Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n- Pon a prueba el concepto de variable local y global.\n- Debes hacer print por consola del resultado de todos los ejemplos.\n\"\"\"\n\n# Función sin parámetro ni retorno\ndef ejemplo():\n    if 5 * 5 >= 8 * 4:\n        print(\"Primera opción\")\n    else:\n        print(\"Segunda opción\")\n\nejemplo()\n\n# Función con un parámetro\ndef parámetro(texto1):\n    print(texto1)\n\nparámetro(\"Algo de texto\")\n\n# Función con varios parámetros\ndef varios(x, y):\n    while y < x:\n        print(\"y < x\")\n        if y == x:\n            break\n        y += 1\n\nvarios(10, 2)\n\n# Función con retorno\ndef retorno(a, b):\n    multiplicar = a * b\n    return multiplicar\n\nprint(retorno(11, 3))\n\n# Función dentro de función\n\ndef primera_función():\n    oración = \"Raro, ¿verdad?\"\n    experimento = \"\"\n\n    for letra in oración:\n        experimento += letra\n        print(experimento)\n\n        def segunda_función():\n            if oración == experimento:\n                print(\"Más que raro, ¿no?\")\n        \n        segunda_función()\n\nprimera_función()\n\n# Funciones del lenguaje\n# Lambda\nx = lambda a, b: a % b\nprint(x(10, 3))\n\n# Type, id\nlenguaje = 6.9\nprint(type(lenguaje))\nprint(id(lenguaje))\n\n# Suma, max, min\nlista = [1, 2, 3, 4, 5, 6, 7, 8, 9]\nprint(\n    f\"\"\"\n    Suma: {sum(lista)}\n    Numero mayor: {max(lista)}\n    Numero menor: {min(lista)}\n    \"\"\"\n)\n\n\n# Variable local\nvar_local = 100 # Variable local FUERA de la función\n\ndef var():\n    var_local = 100 # Variable local DENTRO de la función\n    print(var_local)\nprint(var_local)\n\nvar()\n\n# Variable global\nvar_global = 111 # Variable global FUERA de la función\n\ndef var2():\n    global var_global\n    var_global = 111 # Variable global DENTRO de la función\n    print(var_global)\nprint(var_global)\n\nvar2()\n\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n- Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n- La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n- Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n- Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n- Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n- La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n- Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n- Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n\"\"\"\n\ndef dif_extra(texto1, texto2):\n    veces = 0\n\n    for num in range(1, 101):\n        if num % 3 == 0 and num % 5 == 0:\n            print(f\"A {num} le corresponde: '{texto1 + \" \" + texto2}'\")\n        elif num % 3 == 0:\n            print(f\"A {num} le corresponde: '{texto1}'\")\n        elif num % 5 == 0:\n            print(f\"A {num} le corresponde: '{texto2}'\")\n        else:\n            print(f\"A {num} no le corresponde texto.\")\n            veces += 1\n    return print(f\"Veces que se ha impreso el numero en lugar del texto: {veces}\")\n\ndif_extra(\"Dificultad\", \"extra\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/gmigues.py",
    "content": "''' * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)'''\n\ndef sin_parametros():\n    print(\"Hola, soy una función sin parámetros\")\n\n\ndef con_parametros(parametro):\n    print(f\"Hola, mi nombre es: {parametro}\")\n\ndef con_retorno():\n    return \"Hola, soy una función con retorno\"\nmensaje = con_retorno()\n\ndef funcion_con_multiples_parametros(parametro1, parametro2, parametro3):\n    print(f\"Los parámetro ingresados son: {parametro1}, {parametro2}, {parametro3}\")\n\ndef funcion_dentro_de_funcion():\n    def funcion_interna():\n        print(\"Hola, soy una función interna\")\n    funcion_interna()\n\ndef con_x_parametros(*args):\n    print(f\"Los argumentos ingresados son: {args}\")\n\ndef funcion_kwargs(**datos):\n    print(datos[\"nombre\"], datos[\"apellido\"], datos[\"edad\"], datos[\"pais\"])\n\ndef suma(*num):\n    i=0\n    for n in num:\n        i = i + n\n    print(f\"La suma es: {i}\")\n\n\ndef variable_local():\n    variable = \"Soy una variable local\"\n    print(variable)\n\nvariable = \"Soy una variable global\"\n\ndef variable_global():\n    global variable \n    print(variable)\n\ndef funcion_lambda():\n    return lambda x: x + 10\n\ndef funcion_recursiva(n):\n    if n == 0:\n        return 0\n    else:\n        return n + funcion_recursiva(n - 1)\n\ndef funcion_con_parametros_por_defecto(parametro1, parametro2 = \"default\"):\n    print(f\"Los parámetros ingresados son: {parametro1}, {parametro2}\")\n\n\n\nsin_parametros()\nprint(\"--------------------\")\ncon_parametros(\"pepe\")\nprint(\"--------------------\")\nprint(mensaje)\nprint(\"--------------------\")\nfuncion_con_multiples_parametros(\"pepe\", \"juan\", \"carlos\")\nprint(\"--------------------\")\nfuncion_dentro_de_funcion()\nprint(\"--------------------\")\ncon_x_parametros(\"pepe\", \"juan\", \"carlos\", \"jose\", \"luis\", \"maria\")\nprint(\"--------------------\")\nfuncion_kwargs(nombre=\"Pepe\",\n               apellido=\"Martinez\",\n               edad=\"47\",\n               pais=\"Colombia\")\nprint(\"--------------------\")\nvariable_local()\nprint(\"--------------------\")\nvariable_global()\nprint(\"--------------------\")\nprint(funcion_lambda()(5))\nprint(\"--------------------\")\nprint(funcion_recursiva(6))\nprint(\"--------------------\")\nfuncion_con_parametros_por_defecto(\"pepe\")\nprint(\"--------------------\")\nsuma(10,10,5,5,70)\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/gonzadev28.py",
    "content": "#Funciones \n\n#Funciones sin parametros\ndef sin_parametros():\n    print(\"Funcion sin parametros\")\n\nsin_parametros()\n\n#Funciones con parametros \ndef con_parametros(mensaje):\n    print(\"Imprimiendo funcion con\", (mensaje))\n\ncon_parametros(\"parametro\")\n\n#Funcion con retorno\ndef con_retorno(numero):\n    return numero\n\nprint(\"El numero es:\", con_retorno(28))\n\n#Funcion dentro de otra funcion\ndef funcion1():\n    def funcion2():\n        print(\"Funcion dentro de otra funcion\")\n    funcion2()\n\nfuncion1()\n\n#Funciones propias del lenguaje\n\nprint(len(\"Python\")) #Imprime cantidad de caracteres del string (6)\nprint(type(True)) #Imprime el tipo de dato (booleano)\nprint(bin(6)) #Imprime nunmero entero a binario\nprint(max(2, 8, 26, 76, 1, 0)) #Imprime numero mayor\n\n#Variable global y local\n\nvariable_global = \"Python\"\n\ndef programar():\n    variable_local = \"Mouredev\"\n    print(variable_global, variable_local)\n\nprogramar()\n# print(variable_local) no se puede acceder a la variable fuera de la funcion \n\n\"\"\"DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\"\"\"\n\ndef funcion_extra(mensaje1, mensaje2):\n    contador = 0\n    for numero in range (1, 101):\n        if numero % 3 == 0 and numero % 5 == 0:\n            print(mensaje1, mensaje2)\n        elif numero % 5 == 0:\n            print(mensaje2)\n        elif numero % 3 == 0:\n            print(mensaje1)\n        else:\n            print(numero)\n            numero += 1\n    return contador\n\nfuncion_extra(\"Aprendo\", \"Python\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/guillermo-k.py",
    "content": "from datetime import date\n''' * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)'''\n\n\ndef saludo():\n    print(\"FUNCIÓN SIN PARAMETROS\")\n    print(\"Hola, sea usted bienvenido\")\n\ndef saludo_personalizado(nombre):\n    print(\"FUNCIÓN CON UN PARAMETRO\")\n    print(f\"Hola {nombre}, sea usted bienvenido\")\n\n\ndef funcion_dentro_de_funcion():\n    def dias_a_cumpleanios(dia,mes,nombre):\n        saludo_personalizado(nombre)\n        today = date.today()\n        anio = today.year\n        cumpleanios = int(date(anio,mes,dia).strftime(\"%y%j\"))\n        now = int(today.strftime(\"%y%j\"))\n        dias = cumpleanios - now\n        if dias == 0:\n            print(\"Felíz cumpleaños\")\n        elif dias > 0:\n            print(f\"Faltan {dias} días para su cumpleaños\")\n        elif dias < 0:\n            print(f\"Faltan {dias+365} días para su cumpleaños\")\n    \n\n    print(\"Ingrese su fecha de cumpleaños('DD/MM')\")\n    entrada = input()\n    print(\"Ingrese su nombre\")\n    nombre = input()\n\n    if '/' in entrada:\n        fecha = entrada.split('/')\n        dias_a_cumpleanios(int(fecha[0]),int(fecha[1]),nombre)\n\n\ndef funcion_parametros_indeterminados(*args):\n    for i in args:\n        print(i)\n\n\nsaludo()\nsaludo_personalizado(\"Guillermo\")\nfuncion_dentro_de_funcion()\nfuncion_parametros_indeterminados(\"Hola\",\"Chau\",23)\nprint(\"La funcion 'print' es una función propia del lenguaje, que es muy utilizada\")\nprint(max(\"La función 'max' obtiene el maximo de una lista\",\"AAA\",\"BBB\"))\n\nvariable_global = 'Esta es una variable global, ya que se encuentra declarada en el cuerpo principal, y no dentro de una estructura'\ndef tipos_de_variables():\n    variable_local = 'Esta es una variable local, ya que se encuentra decalarada dentro de un bloque, en este caso, una función. A la misma, solo se podra acceder desde el bloque que la contiene'\n    print(variable_global)\n    print(variable_local)\n\ntipos_de_variables()\nprint(variable_global)\ntry:\n    print(variable_local)\nexcept:\n    print(\"no se pudo imprimir el contenido de 'variable_local' ya que esta fuera de alcance(scope)\")\n\n'''DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.'''\n\n\ndef extra(text1,text2):\n    count = 0\n    for i in range(1,101):\n        cadena = \"\"\n        if i%3 != 0 and i%5 != 0:\n            cadena = i\n            count += 1\n        else:\n            if i%3 == 0:\n                cadena += text1\n            if i%5 == 0:\n                cadena += text2\n        print(cadena)\n    return count\n\ncantidad_numeros = extra(\"Es divisible por 3.\",\"Es divisible por 5\")\n\nprint(f\"Se ha escrito {cantidad_numeros} veces un número en lugar de los textos\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/guillesese.py",
    "content": "#02 - FUNCIONES Y ALCANCE\n#EJERCICIO:\n#- Crea ejemplos de funciones basicas que representen las diferentes\n#   posibilidades del lenguaje:\n#   Sin parametros ni retorno, con uno o varios parametros, con retorno...\n# - Comprueba si puedes crear funciones dentro de funciones.\n# - Utiliza algun ejemplo de funciones ya creadas en el lenguaje.\n# - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n# - Debes hacer print por consola del resultado de todos los ejemplos.\n#   (y tener en cuenta que cada lenguaje puede poseer mas o menos posibilidades)\n\n''' Definidas por el usuario'''\n\n#Sin retorno\ndef funcion():\n    print(\"Hola\")\n\nfuncion()\n\n#Con retorno\ndef funcion_ret():\n    return \"Hola\"\n\nprint(funcion_ret())\n\n#Con un argumento\ndef funcion_arg(arg1):\n    print(f\"arg1: {arg1}\")\n\nfuncion_arg(\"argumento1\")\n\n#Con varios argumentos\ndef funcion_arg_multiple(arg1, arg2):\n    print(f\"arg1: {arg1} arg2: {arg2}\")\n\nfuncion_arg_multiple(\"argumento1\",2)\nfuncion_arg_multiple(arg1=2, arg2=\"argumento2\")\n\n#Con argumento predeterminado\ndef funcion_arg_default(arg1=\"argumento1\"):\n    print(f\"arg1: {arg1}\")\n\nfuncion_arg_default(\"arg1\")\nfuncion_arg_default()\n\n#Con argumentos y return \ndef funcion_arg_return(arg1, arg2):\n    return f\"arg1: {arg1} arg2: {arg2}\"\n\nprint(funcion_arg_return(\"arg1\",2))\n\n#Con return multiple\ndef funcion_mult_return():\n    return \"arg1\",2\n\narg1, arg2 = funcion_mult_return()\nprint(f\"arg1: {arg1}\")\nprint(f\"arg2: {arg2}\")\n\n#Con numero variable de argumentos\ndef funcion_arg_variable(*args):\n    for arg in args:\n        print(f\"arg: {arg}\")\n    \nfuncion_arg_variable(\"arg1\",2,\"arg3\",'4')\n\n#Con numero variable de argumentos con palabra clave\ndef funcion_arg_variable_key(**args):\n    for key,value in args.items():\n        print(f\"{key}, {value}\")\n\nfuncion_arg_variable_key(\n    arg1=\"argumento1\",\n    arg2=2, \n    arg3='3'\n)\n\n'''\nFunciones dentro de funciones.\n'''\ndef funcion_ext():\n    def funcion_int():\n        print(\"Funcion interna dentro de funcion externa\")\n    funcion_int()\n\nfuncion_ext()\n\n'''\nFunciones del lenguaje\n'''\nprint(len(\"string\"))\nprint(type(\"string\"))\nprint(type(3))\nprint(\"string\".upper())\n\n'''\nvariables locales y globales\n'''\n\nglobal_var = \"Global\"\n\ndef funcion_local_global():\n    local_var = \"Local\"\n    print(f\"Global= {global_var} Local={local_var}\")\n\nfuncion_local_global()\n\n\"\"\"\nExtra\n\"\"\"\ndef funcion(parametro1, parametro2) -> int:\n    count = 0\n    for i in range(1,101):\n        if i % 3 == 0 and i % 5 == 0: \n            print (parametro1 + parametro2)\n        elif i % 3 == 0:\n            print (parametro1)\n        elif i % 5 == 0:\n            print (parametro2)\n        else:\n            print(i)\n            count += 1\n    \n    return count\n\nprint (funcion(\"parametro1\",\"parametro2\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/haroldAlb.py",
    "content": "'''\nFUNCIONES Y ALCANCE\n'''\nprint('##Ejemplos de funciones')\ndef hola():\n    print('Hola gente')\n\ndef suma(num1, num2):\n    print(f'La suma de {num1} y {num2} es {num1 + num2}')\n\ndef suma2(num1= 0, num2= 0):\n    print(f'La suma de {num1} y {num2} es {num1 + num2}')\n\ndef iteracion(principio, fin):\n    numeros=[]\n    for num in range(principio, fin+1):\n        numeros.append(num)\n    return numeros\n\nhola()\n\nn1= 5\nn2= 6\nsuma(n1, n2)\n\nsuma2()\nsuma2(n1, n2)\n\nprint(iteracion(2, 10))\n\nprint('##Funciones dentro de funciones')\ndef dobleFuncion(x):\n    doble= x * 2\n    def cuadrado(y):\n        cuad= y**2\n        return cuad\n    print(cuadrado(doble))\n\ndobleFuncion(5)\n\nprint('##Ejemplos de funciones ya creadas en el lenguaje')\n\nx= 'hola que ase'\nprint(len(x)) # devuelve la cantidad de objetos que tiene un objeto\n\nentero= '1991'\nprint(int(entero)) # convierte números de formato texto en números enteros\n\nnumbers= [4,6,8,1,22,30,13,0,108,24,7,56]\nprint(max(numbers)) # Retorna el elemento mayor en un iterable o el mayor de dos o más argumentos.\n\nprint('##Variables LOCALES y GLOBALES')\nmiVariableGlobal_1= 'Soy una variable local'\n\ndef variables():\n    miVarLOCAL= 'Soy local'\n    print(miVarLOCAL)\n    print(miVariableGlobal_1)\n\nvariables()\n# print(miVariableLOCAL) # esto produciría un error\n\ndef modificar_variable():\n    global miVariableGlobal_1 # indicamos con la palabra reservada 'global' que queremos modificar a 'miVariableGlobal_1'\n    miVariableGlobal_1= 'Ahora estoy modificada dentro de la función'\n\nprint(miVariableGlobal_1)\nmodificar_variable()\nprint(miVariableGlobal_1)\n\n###DIFICULTAD EXTRA###\nprint('###EJERCICIO EXTRA###')\n\ndef multiplos3_5(txt1, txt2):\n    count= 0\n    for num in range(1,101):\n        if num % 3 == 0 and num % 5 == 0:\n            print(txt1 + txt2)\n        elif num % 3 == 0:\n            print(txt1)\n        elif num % 5 == 0:\n            print(txt2)\n        else:\n            print(num)\n            count += 1\n    return count\n\nimpresos= multiplos3_5('ni', 'no')\nprint(f\"Se han impreso {impresos} números.\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/hectorio23.py",
    "content": "#! /bin/python3.11\n# Autor: Héctor Adán \n# Github: https://github.org/hectorio23\n'''\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n'''\n\n# Simple funcion sin retorno\ndef foo_simple() -> None:\n    print(\"Esta es una simple funcion\")\n\n# Funcion con retorno\ndef foo_retorno() -> str: \n    return \"Esta es una simple funcion\"\n\n# Funcion con multiples parametros \ndef suma(*args):\n    return sum(*args)\n\n\ndef foo_main():\n\n    def foo_other():\n        return \"Hola bro\"\n\n    return foo_other()\n\n\n# Variable global\nglobal_variable = \"Soy global\"\n\ndef example_function(text1, text2):\n    # Variable local\n    local_variable = \"Soy local\"\n\n    def print_numbers():\n        count = 0  # Variable local a esta función interna\n\n        for i in range(1, 101):\n            output = \"\"\n            if i % 3 == 0:\n                output += text1\n            if i % 5 == 0:\n                output += text2\n            if output:\n                print(output)\n                count += 1\n\n        return count\n\n    return print_numbers()\n\n\n\n############# ZONA DE LLAMADA DE FUNCIONES ############# \nfoo_simple()\nprint(foo_retorno())\n# Suma los numeros pares del 1 al 20\nprint(suma(element for element in range(0, 21) if element % 2 == 0))\nfoo_main()\n# Probando la función\nprint(example_function(\"Múltiplo de 3 \", \"Múltiplo de 5\"))\nprint(f\"VariableGlobal: { global_variable } \")  # Accediendo a la variable global\n# print(local_variable)  # Esto dará un error ya que la variable local no está disponible fuera de la función\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/hendrycode.py",
    "content": "def hola_Mundo():\n    print(\"Hola mundo!\")\n    \nhola_Mundo()\n    \ndef suma_mas_uno(a,b):\n    return a + b + 1\n\nprint(suma_mas_uno(10, 20))\n\ndef contar(numero):\n    for i in range(numero + 1):\n        print(i)\ncontar(10)\n\ndef primera_funcion():\n    def segunda_funcion():\n        print(\"soy la segunda funcion\")\n\nglobal_variable = \"soy una variable global\"\ndef obtener_numeros(a: str, b: str) -> int:\n    counter = 0 #soy una varible local\n    global_variable\n    for i in range(101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(a, b)\n        elif i % 3 == 0:\n            print(a)\n        elif i % 5 == 0:\n            print(b)\n        else:\n            counter += 1\n    return counter\nprint(obtener_numeros(\"fizz\", \"buzz\"))\n        \n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/hozlucas28.py",
    "content": "\"\"\"\n    Types of functions...\n\"\"\"\n# Anonymous function\nanonymous = lambda: print(\n    \"Anonymous function: <FUNCTION NAME> = lambda(<PARAMETERS...>): <INSTRUCTIONS...>\"\n)\n\n\n# Common function\ndef common():\n    print(\"Common function: def <FUNCTION NAME>(<PARAMETERS...>): <INSTRUCTIONS...>\")\n\n\n# With parameter\ndef with_parameters(name):\n    print(\n        f\"Common function (with parameter): def <FUNCTION NAME>(name): <INSTRUCTIONS...> --> Hello {name}!\"\n    )\n\n\n# Without parameter\ndef without_parameters():\n    print(\n        \"Common function (without parameter): def <FUNCTION NAME>(): <INSTRUCTIONS...> --> Hello!\"\n    )\n\n\n# With default parameter\ndef with_default_parameters(last_name=\"Hoz\"):\n    print(\n        f\"Common function (with default parameter): def <FUNCTION NAME>(last_name = 'Hoz'): <INSTRUCTIONS...> --> By {last_name}!\"\n    )\n\n\n# With keyword parameter\ndef with_keyword_parameter(last_name, first_name):\n    print(\n        f\"Common function (with keyword parameter): def <FUNCTION NAME>(last_name, first_name): <INSTRUCTIONS...> --> {first_name} {last_name}!\"\n    )\n\n\n# With arbitrary keyword parameter\ndef with_arbitrary_keyword_parameter_v1(*argv):\n    print(\n        f\"Common function (with arbitrary keyword parameter v1): def <FUNCTION NAME>(*argv): <INSTRUCTIONS...> --> {argv}!\"\n    )\n\n\ndef with_arbitrary_keyword_parameter_v2(**kwargv):\n    print(\n        f\"Common function (with arbitrary keyword parameter v2): def <FUNCTION NAME>(**kwargv): <INSTRUCTIONS...> --> {kwargv}!\"\n    )\n\n\n# With return\ndef with_return():\n    return \"Python 3.12.0\"\n\n\n# Without return\ndef without_return():\n    print(\n        \"Common function (without return): def <FUNCTION NAME>(): <INTRUCTIONS (return not included)...> --> return void\"\n    )\n\n\nanonymous()\ncommon()\nwith_parameters(\"Lucas\")\nwithout_parameters()\nwith_default_parameters()\nwith_keyword_parameter(first_name=\"Lucas\", last_name=\"Hoz\")\nwith_arbitrary_keyword_parameter_v1(\"Martin\", \"Jose\", \"Tomás\")\nwith_arbitrary_keyword_parameter_v2(name=\"Juan\", last_name=\"Gonzales\", city=\"New York\")\nprint(\n    f\"Common function (with return): def <FUNCTION NAME>(): <INTRUCTIONS (with return definition included)...> --> return '{with_return()}'\"\n)\nwithout_return()\n\n\n\"\"\"\n    Function definition inside another function...\n\"\"\"\n\n\ndef wrapper():\n    def inner():\n        print(\"Inner function called\")\n\n    print(\"\\nWrapper function called\")\n    inner()\n\n\nwrapper()\n\n\n\"\"\"\n    Native functions...\n\"\"\"\n\nARRAY = [\"HTML\", \"CSS\", \"JavaScript\", \"Python\"]\nprint(f\"Native functions: len({ARRAY}) --> {len(ARRAY)}\")\n\nHEX = 255\nprint(f\"Native functions: hex({HEX}) --> {hex(HEX)}\")\n\nNUMBER = 1.6\nprint(f\"Native functions: round({NUMBER}) --> {round(NUMBER)}\")\n\n\n\"\"\"\n    Global and local variables...\n\"\"\"\n\nCOUNTRY = \"United States\"\n\n\ndef showCountry():\n    STATE = \"Florida\"\n    return f\"function call with a global variable --> COUNTRY = '{COUNTRY}'\"\n\n\nprint(f\"\\nGlobal variable: {showCountry()}\")\n# print(f\"Local variable: variable defined inside a function but called outside it --> STATE = {STATE}\") # Throw an undefined error.\nprint(\n    f\"Local variable: variable defined inside a function but called outside it --> STATE = Undefined\"\n)\n\n\n\"\"\"\n    Additional challenge...\n\"\"\"\n\n\ndef additional_challenge(str01, str02):\n    counter = 0\n\n    print(\"\")\n    for i in range(1, 101):\n        MULTIPLE_OF_FIVE = i % 5 == 0\n        MULTIPLE_OF_THREE = i % 3 == 0\n\n        if MULTIPLE_OF_FIVE and MULTIPLE_OF_THREE:\n            print(str01 + str02)\n            continue\n\n        if MULTIPLE_OF_FIVE:\n            print(str02)\n            continue\n\n        if MULTIPLE_OF_THREE:\n            print(str01)\n            continue\n\n        print(i)\n        counter += 1\n\n    return counter\n\n\nprint(\n    f\"\\n{additional_challenge('fizz', 'buzz')} numbers was printed instead of 'fizz' or 'buzz' (function arguments)!\"\n)\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/iban99.py",
    "content": "#Sin parámetro ni retorno (SIMPLE)\ndef saludo ():\n    print(\"hola mundo\")\n    \nsaludo()\n\n#Con retorno\ndef return_saludo ():\n    return \"Hola mundo\"\n\n#Si no pongo el print, no lo imprime por pantalla, o bien pongo el print o bien \n#Lo incluyo dentro de la variable\nprint(return_saludo())\n\n#Con argumento\ndef argumento(name, apellido):\n    print(f\"Hola, {name} {apellido}\")\n    \nargumento(\"Miriam\", \"Iban\")\nargumento(apellido=\"Iban\", name=\"Miriam\")\n\n#Con argumento predeterminado\ndef arg_default(name = \"Python\"):\n    print(f\"Hola, {name}\")\n\narg_default()\n\n#Con parámetro y retorno\ndef return_args(saludo, nombre):\n    return(f\"{saludo}, {nombre}\")\n\nprint(return_args(\"Hola\", \"Miriam\"))\n\n#Con retorno de varios valores\ndef multiple_return():\n    return \"Hola\", \"Python\"\n\nsaludo, nombre = multiple_return()\nprint(saludo)\nprint(nombre)\n\n#Con un numero variable de argumentos\n#Puedo pasar más de un nombre\ndef variable_arg_greet(*names):\n    for name in names:\n        print (f\"Hola, {name}!\")\n\nvariable_arg_greet(\"Python\", 'Miriam', \"Comunidad\")\n\n#Con un numero variable de argumentos con palabra clave\n#Cada argumento está formado por una clave y un valor\ndef variable_key_arg_greet(**names):\n    for key, name in names.items():\n        print (f\"Hola, {name} ({key})!\")\n\nvariable_key_arg_greet(lenguage=\"Python\", name='Miriam', age=\"25\")\n\n\n\n#Función dentro de función\ndef outer_function (a, b):\n    x = a - b\n    def inner_function (c):\n        g = x*c\n    return (g)\n\n\ndef outer_function():\n    def inner_function():\n        print(\"Funcion interna: Hola, Python\")\n    #Necesito llamar a la función para que llegue a printearse\n    inner_function()\n    \nouter_function()\n\n\n#Funciones de lenguaje\nprint(len(\"Miriam\")) #Len()\nprint(type(\"Miriam\")) #Type()\nprint(\"MoureDev\".upper()) #Upper()\n\n\n#Variables GLOBALES\nglobal_variable = \"Python\"\n\nprint(global_variable)\n\ndef hello_python():\n    print(f\"Hello, {global_variable}\")\n    \nhello_python()\n    \n\n#Variables LOCALES\ndef hello_python():\n    local_var = \"Hola\"\n    print(f\"{local_var}, {global_variable}\")\n\nhello_python()\nprint(global_variable)\n# print(local_var) --> no puedo acceder directamente \n\n\n#Dificultad extra\ndef print_number(texto_1, texto_2):\n    count = 0\n    for i in range(1, 101):\n        if i%3 == 0 and i%5 == 0:\n            print(texto_1+texto_2)\n        elif i%3 == 0:\n            print (texto_1)\n        elif i%5 == 0:\n            print (texto_2)\n        else:\n            print(i)\n            count +=1\n    return count\n\nprint(print_number(\"Fizz\", \"Buzz\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/ibuetab.py",
    "content": "#FUNCIONES DEFINIDAS POR EL USUARIO\n\n#Sin parámetros ni retorno\ndef Hola_mundo():\n    print(f\"Hola Mundo\");\n\nHola_mundo();\n\n#Con un parámetro\ndef Hola_usuario(usuario):\n    print(f\"Hola {usuario}\");\n\nHola_usuario(\"User\");\n\n#Con varios parámetros\ndef Hola_usuarios(user1,user2):\n    print(f\"Hola {user1}, {user2}\");\n\nHola_usuarios(\"User1\", \"User 2\");\n\n#Con retorno\ndef suma():\n    return 2+3;\nsuma=suma();\nprint(suma);\n\n#Con varios retornos\ndef nombre_y_edad():\n    return \"nombre\", \"edad\";\n\nnombre, edad = nombre_y_edad();\nprint(f\"{nombre},{edad}\");\n\n#Con parametros variables\ndef nombre(*nombre):\n    for n in nombre:\n        print(f\"{n}\");\n\nnombre(\"Nombre1\", \"Nombre2\");\n\n\n\n\n#Con parámetros variables y clave\ndef nombre_claves(**names):\n    for key,value in names.items():\n        print(f\"{value}, {key}\");\n\nnombre_claves(language=\"Python\");\n\n#Funciones anidadas\ndef funcion_anidada():\n    def funcion_de_dentro():\n        print(f\"Me he quedado sin frases absurdas para poner aqui\");\n    funcion_de_dentro();\n\nfuncion_anidada();\n\n\n#FUNCIONES PROPIAS DEL LENGUAJE\nfrase = \"Y ahora que pongo\";\nprint(f\"{frase}\");\nprint(type(frase));\nprint(frase.split());\n\n\n\n#VARIABLE GLOBALES Y LOCALES\nvariable_global = \"A la variable global se accede desde cualquier parte del código\";\n\ndef que_me_invento_ahora():\n    variable_local = \"A la variable local solo se accede desde dentro del bloque de la función definida\";\n    print(f\"{variable_global}, {variable_local}\")\n\nque_me_invento_ahora();\n\nprint(f\"{variable_global}\");\n\n\n#EXTRA\ndef numeros(Texto1,Texto2) -> int:\n    counter = 0;\n    for i in range(1,100+1):\n        if i % 3 == 0 and i % 5 == 0:\n            print(f\"{Texto1},{Texto2}\");\n        elif i % 3 == 0:\n            print(f\"{Texto1}\");\n        elif i % 5 == 0:\n            print(f\"{Texto2}\");\n        else:\n            print(i);\n            counter += 1;\n    return counter;\n\n\nprint(numeros(\"Texto1\",\"Texto2\"));"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/icedrek.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n\"\"\"\n\nvariable_global = \"GLOBAL\"  # accesible por todas las funciones\n\n\ndef funcion_sin_parametros():\n    variable_local = \"LOCAL\"  # solo accesible en esta funcion\n    print(\"funcion_sin_parametros:\")\n    print(\" - no recibe parametros\")\n    print(\" - no tiene retorno\")\n    print(f\" - tiene acceso a la variable global: {variable_global}\")\n    print(f\" - tiene acceso a la variable local: {variable_local}\\n\")\n\n\ndef funcion_con_parametros(param1, param2):\n    print(\"funcion_con_parametros:\")\n    print(f\" - recibe 2 parametros: {param1} y {param2}\")\n    print(\" - no tiene retorno\")\n    print(f\" - tiene acceso a la variable global: {variable_global}\")\n    try:\n        print(f\" - tiene acceso a la variable local: {variable_local}\\n\")\n    except NameError:\n        print(\" - no tiene acceso a la variable local\\n\")\n\n\ndef funcion_con_retorno(param1, param2):\n    print(\"funcion_con_parametros:\")\n    print(f\" - recibe 2 parametros: {param1} y {param2}\")\n    print(\" - tiene retorno\")\n    print(f\" - tiene acceso a la variable global: {variable_global}\")\n    try:\n        print(f\" - tiene acceso a la variable local: {variable_local}\\n\")\n    except NameError:\n        print(\" - no tiene acceso a la variable local\\n\")\n\n    return param1 + param2\n\n\ndef funcion_con_parametros_por_defecto(param1=1, param2=2):\n    print(\"funcion_con_parametros_por_defecto:\")\n    print(\n        f\" - siempre tiene 2 parametros: {param1} y {param2} (aunque no se indiquen en la llamada)\"\n    )\n    print(\" - tiene retorno\")\n    print(f\" - tiene acceso a la variable global: {variable_global}\")\n    try:\n        print(f\" - tiene acceso a la variable local: {variable_local}\\n\")\n    except NameError:\n        print(\" - no tiene acceso a la variable local\\n\")\n\n    return param1 + param2\n\n\ndef funcion_con_varios_retornos():\n    print(\"esta funcion devuelve 2 valores en el retorno\")\n    return \"valor1\", \"valor2\"\n\n\ndef funcion_con_funcion():\n    def suma(param1, param2):\n        return param1 + param2\n\n    print(f\"reultado funcion_con_funcion: {suma(1,2)}\")\n\n\ndef funcion_extra(param1=\"fizz\", param2=\"buzz\"):\n    contador_param1 = 0\n    contador_param2 = 0\n    contador_p1_p2 = 0\n\n    for _ in range(1, 101):\n        if _ % 3 == 0 and _ % 5 == 0:\n            print(f\"{param1}-{param2}\")\n            contador_p1_p2 += 1\n        elif _ % 3 == 0:\n            print(param1)\n            contador_param1 += 1\n        elif _ % 5 == 0:\n            print(param2)\n            contador_param2 += 1\n        else:\n            print(_)\n\n    print(\"Se ha cambiado el valor original:\")\n    print(f\" - Por el valor {param1}: {contador_param1} veces\")\n    print(f\" - Por el valor {param2}: {contador_param2} veces\")\n    print(f\" - Por el valor {param1}-{param2}: {contador_p1_p2} veces\")\n\n\nfuncion_sin_parametros()\nfuncion_con_parametros(\"uno\", \"dos\")\nretorno = funcion_con_retorno(1, 2)\nprint(retorno)\n\nretorno = funcion_con_parametros_por_defecto()\nprint(retorno)\nretorno = funcion_con_parametros_por_defecto(param1=2)\nprint(retorno)\nretorno = funcion_con_parametros_por_defecto(param2=1)\nprint(retorno)\nretorno = funcion_con_parametros_por_defecto(3, 4)\nprint(retorno)\n\nretorno1, retorno2 = funcion_con_varios_retornos()\nprint(retorno1)\nprint(retorno2)\n\nfuncion_con_funcion()\n\nprint(\"El propio print() es un ejemplo de funcion del lenguaje\")\n\nfuncion_extra()\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/idiegorojas.py",
    "content": "# Funciones \n\n# Funcion Basica\n\"\"\"\ndef nombre_de_la_funcion(parametros):\n    # Cuerpo de la funcion\n    return valor\n\"\"\"\n\n\n\"\"\"\n    def: Palabra clave que define la funcion\n    nombre_de_la_funcion: Nombre que se le da a la funcion\n    parametros: Argumentos que la funcion puede recibir (opcional)\n    return: Devuelve un valor al finalizar la funcion (opcional)\n\"\"\" \n\ndef saludar():\n    print('¡Hola, mundo!')\n\nsaludar()\n\n\n# Funcion con parametros\ndef sumar(a, b):\n    resultado = a + b\n    return resultado\n\nresultado = sumar(3, 2)\nprint(resultado)\n\n# Funciones con valores por defecto\ndef saludar(nombre='Usuario'):\n    print(f'¡Hola, {nombre}!')\n\nsaludar()\nsaludar('Diego')\n\n# Funciones con retorno\ndef multiplicar(a, b):\n    return a * b\n\nresultado = multiplicar(4, 5)\nprint(resultado)\n\n# Funciones con multiples valores de retorno\ndef operaciones(a, b):\n    suma = a +b\n    resta = a - b\n    multiplicacion = a * b\n    division = a / b\n    return suma, resta, multiplicacion, division\n\nresultados = operaciones(10, 2)\nprint(resultados)\n\n# Desempaquetar los valores\ns, r, m, d = operaciones(10, 2)\nprint(r)\n\n\n# Funciones con argumentos variables\n# *args -> Lista de argumentos\ndef sumar_todo(*args):\n    return sum(args)\n\nprint(sumar_todo(1,2,3,4))\n\n# **kwargs -> Diccionario de argumentos\ndef mostrar_info(**kwargs):\n    for clave, valor in kwargs.items():\n        print(f'{clave}: {valor}')\n\nmostrar_info(nombre='Juan', edad=25, ciudad='Madrid')\n\n\n# Funciones dentro de funciones\ndef exterior():\n    print('Estoy en la funcion exterior')\n\n    def interior():\n        print('Estoy en la funcion interior')\n\n    interior()\n\nexterior()\n\n\n# Funcion lambda\nmultiplicar = lambda a, b: a * b\nprint(multiplicar(3, 4))\n\n\n# Extra\ndef imprimir_numeros(text1, text2) -> int:\n    contador = 0\n    for numero in range(1, 101):\n        if numero % 3 == 0 and numero % 5 == 0:\n            print(text1 + text2)\n        elif numero % 3 == 0:\n            print(text1)\n        elif numero % 5 == 0:\n            print(text2)\n        else:\n            print(numero)\n            contador += 1\n    return contador\n\nprint(imprimir_numeros('Fizz', 'Buzz'))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/ignaciovihe.py",
    "content": "\"\"\"\nCrea ejemplos de funciones básicas que representen las diferentes\nposibilidades del lenguaje:\nSin parámetros ni retorno, con uno o varios parámetros, con retorno...\n\"\"\"\n#Función sin parametros ni retorno\ndef greet():\n    print(\"Hello, Python!\")\n\ngreet()\n\n#Función con parametros\n#Un parametro\ndef greet_with_param(name):\n    print(f\"Hello, {name}!\")\n\ngreet_with_param(\"Ignacio\")\n\n#Dos parametros\ndef greet_with_params(greet, name):\n    print(f\"{greet}, {name}!\")\n\ngreet_with_params(\"Hola\", \"Pedro\")\n\n#Parametros por defecto\ndef greet_default_params(greet = \"Hello\", name = \"Python\"):\n    print(f\"{greet}, {name}!\")\n\ngreet_default_params()\ngreet_default_params(\"Hi\")\ngreet_default_params(\"Pedro\") #si sólo pasamos un parametro siempre sera el primero\ngreet_default_params(name = \"Pedro\") #si queremos que sea el nombre deberemos indicarselo\ngreet_default_params(name = \"Ignacio\", greet = \"hi\")\n\n#Multiples parametros\n\nnames = (\"Ignacio\",\"Miguel\",\"Lorena\")\n\ndef greet_multiple_params(*args):\n    for name in args:\n        print(f\"Hello, {name}\")\n\ngreet_multiple_params(*names)\n\n#Multiples parametros con clave-valor\n\nnames = {\"Manager\": \"Ignacio\",\"Developer\": \"Miguel\",\"Designer\": \"Lorena\"}\n\ndef greet_multiple_params(**kwargs):\n    for role, name in kwargs.items():\n        print(f\"Hello, {name}. Your role is {role}\")\n\ngreet_multiple_params(**names)\n\n#Funcion con retorno\n\ndef greet_with_return(name = \"Python\"):\n    return f\"Hello, {name}\"\n\nprint(greet_with_return(\"Ignacio\"))\n\n# Función con retorno multiple\n\ndef greet_multiple_return():\n    return \"Hola de nuevo\", \"Python\"\n\ngreet, name = greet_multiple_return()\nprint(f\"{greet}, {name}\")\n\n\n\"\"\"\nComprueba si puedes crear funciones dentro de funciones.\nUtiliza algún ejemplo de funciones ya creadas en el lenguaje. map() int() sum()\n\"\"\"\n#Crear funcion dentro de otra\ndef sumar():\n\n    def get_numbers():\n        num1, num2 = map(int,input(\"Dame dos números separados por espacio: \").split())\n        return num1, num2\n    \n    return(sum(get_numbers()))\n\nprint(sumar())\n# get_numbers() No se puede llamar a funciones desde fuera de la funcion donde se creo.\n\n\n\"\"\"\nPon a prueba el concepto de variable LOCAL y GLOBAL.\n\"\"\"\nusername = \"Ignacio\"\n\ndef greet():\n    edad = 40\n    print(f\"Hola, {username}, tienes {edad} años.\")\n\ngreet()\n#print(f\"Hola, {username}, tienes {edad} años.\") la variable edad sólo se puede utilizar dentro \n# del ambito donde se creo (funcion greet) al ser una variable local.\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\nCrea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n    - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n    - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n    - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n    - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n    - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\"\"\"\n\ndef multiples(multiple_of_3_text, multiple_of_5_text):\n    \n    non_multiples_count = 0\n    for i in range (1,101):\n        text = []\n\n        if i % 3 == 0:\n            text.append(multiple_of_3_text)\n        if i % 5 == 0:\n            text.append(multiple_of_5_text)\n\n        if text:\n            print(f\"{i} {\" \".join(text)}\")\n        else:\n            print(i)\n            non_multiples_count += 1\n\n    return non_multiples_count\n\nprint(f\"Numeros que nos son multiplos ni de 3 ni de 5: {multiples(\"Multiplo de 3\", \"Multiplo de 5\")}\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/inkhemi.py",
    "content": "# Función sin parámetros ni retorno\ndef hello():\n    print(\"Hello World\")\n\n\nhello()\n\n\n# Función con un parámetro\ndef hello_name(name: str):\n    print(f'Hello {name}')\n\n\nhello_name(\"Inkhemi\")\n\n\n# Función con varios parámetros\ndef name(name: str, surname: str):\n    print(f'Hello {name} {surname}')\n\n\nname(\"Inkhemi\", \"Dev\")\n\n\n# Función con retorno\ndef sum(a: int, b: int) -> int:\n    return a + b\n\n\nprint(sum(1, 2))\n\n\n# Función dentro de una función\ndef par_fibonacci(number: int) -> bool:\n    def is_par(number: int) -> bool:\n        return number % 2 == 0\n\n    def is_fibonacci(number: int) -> bool:\n        a, b = 0, 1\n        while a < number:\n            a, b = b, a + b\n        return a == number\n\n    if is_par(number) and is_fibonacci(number):\n        return True\n    return False\n\n\nprint(par_fibonacci(8))\n\n\n# Variable local y global\ndef local():\n    number = 1\n    print(f'local: {number}')\n\n\nnumber = 2\nlocal()\nprint(f'global: {number}')\n\n\n# Dificultad extra\nprint(\"\\nDificultad extra:\")\n\n\ndef fizzbuzz(text1: str, text2: str) -> int:\n    number = 0\n    for i in range(1, 101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(text1 + text2)\n        elif i % 3 == 0:\n            print(text1)\n        elif i % 5 == 0:\n            print(text2)\n        else:\n            print(i)\n            number += 1\n    return number\n\n\nprint(fizzbuzz(\"Fizz\", \"Buzz\"))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/inmortalnight.py",
    "content": "# 02 - Python\n\n# Funcion sin parametros ni retorno\ndef saludar():\n    print(\"Hola\")\n# Funcion con un parametro \ndef saludar_n(nombre):\n    print(\"Hola\" + nombre)\n# Funcion con vainos parametros \ndef saludar_n2(nombre, apellido):\n    print(\"Hola\" + nombre + \" \" + apellido)\n# Funcion con retorno\ndef saludar_r(nombre):\n    return \"Hola \" + nombre\n\n'''Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.'''\n\ndef funcion(texto1, texto2):\n    contador = 0\n    for i in range(1,101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(texto1 + \" \" + texto2)\n        elif i % 3 == 0:\n            print(texto1)\n        elif i % 5 == 0:\n            print(texto2)\n        else:\n            print(i)\n            contador += 1\n    return \"Números: \" + contador\n\n# Probando\nprint(funcion(\"hola\", \"mundo\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/ipfabio.py",
    "content": "\"\"\"\nFunciones definidas por el usuario\n\"\"\"\n\n# Simple\n\ndef saludo():\n    print(\"Hola, Python!\")\n\nsaludo()\n\n# Con retorno\n\ndef devuelve_saludo() -> str:\n    return \"Hola, Python!\"\n\nsaludar = devuelve_saludo()\nprint(saludar)\n\n# Con un argumento\ndef args_saludo(saludo: str, nombre: str) -> str:\n    print(f\"{saludo}, {nombre}\")\n\nargs_saludo(\"Hi\", \"Marcos\")\n\n# Con un argumento predeterminado\n\ndef default_arg_saludo(nombre:str = \"Amigo\") -> str:\n    print(f\"Hola, {nombre}!\")\n\ndefault_arg_saludo(\"Marco\")\ndefault_arg_saludo()\n\n# Con argumentos y retorno\n\ndef return_args_saludo(saludo: str, nombre: str) -> str:\n    return f\"{saludo}, {nombre}!\"\n\nprint(return_args_saludo(\"Hi\", \"Marcos\"))\n\n# Con retorno de varios valores\n\ndef multiple_return_saludo():\n    return \"Hola\", \"Python\"\n\nsaluda, nombre = multiple_return_saludo()\nprint(saluda)\nprint(nombre)\n\n# Con un número variable de argumentos\n\ndef variable_arg_greet(*names):\n    for name in names:\n        print(f\"Hola, {name}\")\nvariable_arg_greet(\"Python\", \"Marcos\", \"Dibu\", \"Comunidad\")\n\n# Con un número variable de argumentos con palabra clave\n\ndef variable_key_arg_greet(**names):\n    for param, name in names.items():\n        print(f\"{name} ({param})\")\n\nvariable_key_arg_greet(language=\"Python\",name= \"Marcos\",age= 21)\n\n\"\"\"\nFunciones dentro de funciones\n\"\"\"\n\ndef outer_function():\n    def inner_function():\n        print(\"Función interna: Hola, Python!\")\n    inner_function() # Hay que llamarla para que se ejecute\n\nouter_function()\n\n\"\"\"\nFunciones del lenguaje (built-in)\n\"\"\"\n\nprint(len(\"Marcos\"))\nprint(type(21))\nprint(\"Marcos\".upper())\n\n\"\"\"\nVarialbes locales y globales\n\"\"\"\n\nglobal_var = \"Python\"\n\nprint(global_var)\n\ndef hello_python():\n    local_var = \"Hola\"\n    print(f\"{local_var}, {global_var}\")\n\n\nprint(global_var)\n# print(local_var) No se puede acceder desde fuera de la función\n\nhello_python()\n\n\n\"\"\"\nExtra\n\"\"\"\n\ndef extra(texto_1: str, texto_2: str) -> int:\n    numers = 0\n    for i in range(1, 101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(f\"{texto_1}{texto_2}\")\n        elif i % 3 == 0:\n            print(f\"{texto_1}\")\n        elif i % 5 == 0:\n            print(f\"{texto_2}\")\n        else:\n            print(i)\n            numers += 1\n    \n    return f\"Cantidad de numeros impresos: {numers}\"\n\nprint(extra(\"Fizz\", \"Buzz\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/isilanes.py",
    "content": "COLOR = \"rojo\"   # global variable\nmain_a = 2\nmain_b = 3\n\n\ndef i_accept_no_arg() -> None:\n    print(\"Llamaste a una función sin argumentos (y que no retorna nada).\")\n\n\ndef i_accept_two_arguments(first: str, second: str) -> None:\n    print(f\"Llamaste a una función con dos argumentos: {first}, {second} (y que no retorna nada).\")\n\n\ndef i_have_a_default_argument(value: int = 33) -> None:\n    print(f\"Llamaste a una función con el argumento value = {value}\")\n\n\ndef i_return_something(value: int = 0) -> int | None:\n    print(f\"Llamaste a una función con el argumento value = {value}\")\n\n    if not isinstance(value, int):\n        return None\n\n    return value * 2\n\n\ndef i_work_with_local_and_global() -> None:\n    print(f\"Dentro de la función conozco la variable global COLOR = {COLOR}\")\n    global main_a\n    main_a = 4\n    main_b = 5  # because this is not declared global, it will not affect outside\n    print(f\"Dentro de la función, las variables valen {main_a} y {main_b}\")\n\n\ndef main():\n    i_accept_no_arg()\n\n    print(\"\\nLlamo a una función con argumentos sin nombre:\")\n    i_accept_two_arguments(\"primero\", \"segundo\")\n    print(\"Llamo a la misma función con argumentos nombrados:\")\n    i_accept_two_arguments(first=\"primero\", second=\"segundo\")\n\n    print(\"\\nLlamo a una función pasando argumento:\")\n    i_have_a_default_argument(45)\n    print(\"Llamo a la misma función sin argumento, usando el valor por defecto:\")\n    i_have_a_default_argument()\n\n    print(\"\\nLlamo a una función que devuelve algo, e imprimo lo que devolvió:\")\n    ret = i_return_something(123)\n    print(f\"El valor de retorno fue {ret}\")\n\n    print(\"\\nLlamo a una función que usa variables globales y locales:\")\n    print(f\"Antes de llamar a la funcíon, tengo dos variables con valor {main_a} y {main_b}\")\n    i_work_with_local_and_global()\n    print(f\"Tras llamar a la funcíon, los valores son {main_a} y {main_b}. Sólo la primera varió, porque la hice global.\")\n\n\ndef extra(first: str, second: str) -> int:\n    n_number = 0\n    for i in range(1, 101):\n        string = \"\"\n        if not i % 3:\n            string = first\n\n        if not i % 5:\n            string = f\"{string}{second}\"\n\n        if string:\n            print(string)\n        else:\n            print(i)\n            n_number += 1\n\n    return n_number\n\n\nif __name__ == \"__main__\":\n    main()\n    n = extra(\"fiz\", \"buzz\")\n    print(f\"Se escribió un número {n} veces\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/ivangdev.py",
    "content": "# --------- Funciones ---------------------\ndef funcion_1():\n    print(\"Funcion sin retorno ni parametros\")\n\n\nmi_funcion_1 = funcion_1()\n\n\ndef funcion_2(a, b):\n    print(\"Suma de 2 parametros: \", a + b)\n\n\nmi_funcion_2 = funcion_2(2, 4)\n\n\ndef funcion_3(a, b):\n    resta = a - b\n    return f\"Retorna la resta: {resta}\"\n\n\nmi_funcion_3 = funcion_3(5, 4)\nprint(mi_funcion_3)\n\n\n# ---------------------- Funcion dentro de funcion -------------------\ndef suma(a, b):\n    suma = a + b\n\n    def division(suma):\n        if suma % 2 == 0:\n            print(\"Es divisible\")\n\n    division(suma)\n\n\nmi_funcion_4 = suma(3, 5)\n\n# -------------------- Varibale Local y Global ------------------\na = \"prueba\"\n\n\ndef funcion_global():\n    global a\n    a = \"Soy global\"\n\n    def local():\n        a = \"Local\"\n        print(f\"Valor a local: {a}\")\n\n    print(f\"Valor a global: {a}\")\n    local()\n\n\nfuncion_global()\nprint(f\"Valor de a modificado por la funcion_global: {a}\")\n\n# --------------- DIFICULTAD EXTRA (opcional): -------------\n# Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n#  * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n#  *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n#  *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n#  *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n#  *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n#  *\n#  * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n#  * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n\n\ndef cadena_texto(texto1, texto2):\n    contador = 0\n    for numero in range(1, 101):\n        if numero % 3 == 0 and numero % 5 == 0:\n            print(texto1 + texto2)\n\n        elif numero % 5 == 0:\n            print(texto2)\n\n        elif numero % 3 == 0:\n            print(texto1)\n\n        else:\n            contador += 1\n            print(numero)\n\n    return f\"total impresiones {contador}\"\n\n\nprint(cadena_texto(\"Hola\", \"ivan\"))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/javierfiestasbotella.py",
    "content": "'''EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */'''\n\ndef extra(texto_1,texto_2):\n    contador=0\n    for i in range(1,101):\n        if i%3==0 and i%5==0:\n            print(texto_1+texto_2)\n        elif i%3==0:\n            print(texto_1)\n        elif i%5==0:\n            print(texto_2)\n        else:\n            contador+=1\n            print(i)\n    return f'{contador}, se ha impreso el número en lugar de los textos'\nprint(extra('mi ejercicio ','está terminado.'))\n\nprint('_____________________________Separador___________________________________')\n#Ahora ejemplos de fuciones\n\nresultado=0 #variable global\n\ndef sin_argumentos():\n    print('Fin del ejercicio')\n\ndef con_argumentos(a,b):\n    return a+b\n\ndef con_variable_local(n1,n2):\n    resultado=n1*n2\n    return resultado\n\ndef funciones_con_funciones(n):\n    m=int(input('Introduce un numero: '))\n    resultado=n\n    print(con_argumentos(resultado,m))\n\n'''He creado resultado como variable global y dentro de una función como local para ver la diferencia\n, he creado funcines con argumentos y sin ellos, también utilizo una de ellas dentro de otra y a su vez\nutilizando la variable golobal para que se vea claramente como funciona cada una de ellas'''\n\nsin_argumentos()\nprint(con_argumentos(3,5))\nprint(con_variable_local(7,3))\nfunciones_con_funciones(3)"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/javierjoyera.py",
    "content": "#Función sin parámetros\tni retorno\nprint(\"-----------------------------------------\")\nprint(\"Función sin parámetros ni retorno\")\nprint(\"-----------------------------------------\")\ndef function_sin_parametro():\n    print(\"Esta es una función sin parametros\")\n\n#Llamada a la función\nfunction_sin_parametro()\n\n#Función con parámetros\nprint(\"-----------------------------------------\")\nprint(\"Función con parámetros y retorno\")\nprint(\"-----------------------------------------\")\ndef suma(a, b):\n    resultado = a + b\n    return resultado\n    \n\n#Llamada a la función\nresultado_suma = suma(2, 8)\nprint(\"El resultado de la suma es: %d\" % resultado_suma)\n\n#Función con parámetros\nprint(\"-----------------------------------------\")\nprint(\"Función con parámetros\")\nprint(\"-----------------------------------------\")\ndef function_con_parametro(parametro):\n    print(\"Este es el parametro a imprimir: %s\" % parametro)\n\n#Llamada a la función\nfunction_con_parametro(\"Jdelarubia - Dev\")\n\n#Función dentro de una función\nprint(\"-----------------------------------------\")\nprint(\"Función dentro de una función\")\nprint(\"-----------------------------------------\")\n\ndef function_dentro_de_function():\n    print(\"Esta es la función principal\")\n    def function_dentro():\n        print(\"Esta es la función dentro de la función principal\")\n    function_dentro()\n\n#Llamada a la función\nfunction_dentro_de_function()\n\n#Variable global y local\nprint(\"-----------------------------------------\")\nprint(\"Variable global y local\")\nprint(\"-----------------------------------------\")\nvariable_global = \"1999\"\n\ndef function_variable_local():\n    variable_local = \"2999\"\n    print(variable_local)\n    print(variable_global)\n\n#Llamada a la función\nfunction_variable_local()\n\nprint(\"La variable global es: %s\" % variable_global)\n\n#Funciones del lenguaje\nprint(\"-----------------------------------------\")\nprint(\"Funciones del lenguaje\")\nprint(\"-----------------------------------------\")\n\nlista = [1, 2, 3, 4, 5, 6, 7, 8, 9]\n#Función len\nprint(\"La longitud de la lista es: %d\" % len(lista))\n\n#Función type\nprint(\"El tipo de la variable lista es: %s\" % type(lista))\n\n#Función range\nprint(\"La lista generada con la función range es: %s\" % list(range(14)))\n\ncadena_texto = \"Jdelarubia - Dev\"\n#Función upper\nprint(\"La cadena de texto en mayúsculas es: %s\" % cadena_texto.upper())\n\n#Función lower\nprint(\"La cadena de texto en minúsculas es: %s\" % cadena_texto.lower())\n\n#Función capitalize\nprint(\"La cadena de texto con la primera letra en mayúsculas es: %s\" % cadena_texto.capitalize())\n\n#Función count\nprint(\"La cadena de texto tiene %d letras 'a'\" % cadena_texto.count(\"a\"))\n\n\n\n\n#EJERCICIO EXTRA \ndef imprimir_numeros_con_condiciones(cadena1, cadena2):\n    contador = 0\n\n    for numero in range(1, 101):\n        mensaje = \"\"\n\n        if numero % 3 == 0:\n            mensaje += cadena1\n\n        if numero % 5 == 0:\n            mensaje += cadena2\n\n        if mensaje == \"\":\n            mensaje = numero  # Si no es múltiplo de 3 ni de 5, muestra el número\n\n        print(mensaje)\n        contador += 1\n\n    return contador\n\n\nveces_impreso = imprimir_numeros_con_condiciones(\"cadena_1\", \"cadena_2\")\nprint(\"Número de veces impreso: %d\" % veces_impreso)"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/javirub.py",
    "content": "'''\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n'''\n\n#Ejercicio:\ndef basico():\n    print(\"Esta es una función sin parametros ni retorno.\")\n\ndef saludo(nombre='Usuario'): #Función  un parametro sin retorno\n    print(f'Hola {nombre}')\n\nnombre = 'Usuario'\ndef saludo2(): #Función que utiliza una variable global\n    global nombre\n    print('Hola', nombre)\n\ndef saludo3(): #Función que utiliza una variable local\n    nombre = 'Javi'\n    print('Hola', nombre)\n\ndef suma(a, b): # Función con dos parametros y retorno\n    return a + b\n\ndef verdad(): # Función sin parametros y retorno\n    return True\n\nbasico()\nsaludo()\nsaludo2()\nsaludo3()\nprint(suma(5,12))\nprint(verdad())\n\n#Ejercicio extra:\ndef extra(param1, param2):\n    for i in range(1,101):\n        if i%3 == 0 and i%5 == 0:\n            print(f'{i}: {param1} {param2}')\n        elif i%3 == 0:\n            print(f'{i}: {param1}')\n        else:\n            print(f'{i}: {param2}')\n\nprint(\"Introduce las cadenas de texto que quieres usar para el ejercicio extra:\")\nparametro1 = input(\"Introduce el primer parametro: \")\nparametro2 = input(\"Introduce el segundo parametro: \")\nextra(parametro1, parametro2)\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/javitron100.py",
    "content": "# Funciones y alcance\r\n\r\nvariable_global = \"Hola Python!\"\r\n\r\ndef imprime_diez():\r\n    print(\"Diez\")\r\n\r\ndef suma(num1, num2):\r\n    print(num1+num2)\r\n\r\ndef resta(num1, num2):\r\n    return num1 - num2\r\n\r\ndef multiplicacion(num1, num2):\r\n    producto = num1 * num2\r\n\r\n    def imprime_valor_por_diez(v):\r\n        print(v * 10)\r\n    \r\n    imprime_valor_por_diez(producto)\r\n\r\ndef division():\r\n    var_local1 = 10\r\n    var_local2 = 12\r\n    print(var_local1 / var_local2)\r\n\r\n# Dificultad extra\r\n\r\ndef dificultad_extra(str3, str5):\r\n    contador = 0\r\n    for index in range(1, 101):\r\n        if (index % 3 == 0) and (index % 5 == 0):\r\n            print(f\"{index} \" + str3 + \" y \" + str5)\r\n        elif index % 3 == 0:\r\n            print(f\"{index} \" + str3)\r\n        elif index % 5 == 0:\r\n            print(f\"{index} \" + str5)\r\n        else: \r\n            print(index)\r\n            contador += 1\r\n\r\n\r\n    return contador\r\n\r\n\r\n\r\nimprime_diez()\r\nsuma(10, 20)\r\nprint(resta(20, 10))\r\nmultiplicacion(10, 10)\r\nprint(len(variable_global))\r\ndivision()\r\nnumero_de_veces = dificultad_extra(\"Multiplo de 3\", \"Multiplo de 5\")\r\nprint(f\"Números no multiplos de 3 y/o de 5: {numero_de_veces}\")\r\n\r\n\r\n\r\n\r\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/jcdm60.py",
    "content": "# #02 FUNCIONES Y ALCANCE\n#### Dificultad: Fácil | Publicación: 08/01/24 | Corrección: 15/01/24\n\n## Ejercicio\n\n#\n# EJERCICIO:\n# - Crea ejemplos de funciones básicas que representen las diferentes\n#   posibilidades del lenguaje:\n#   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n# - Comprueba si puedes crear funciones dentro de funciones.\n# - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n# - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n# - Debes hacer print por consola del resultado de todos los ejemplos.\n#   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n#\n# DIFICULTAD EXTRA (opcional):\n# Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n# - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n#   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n#   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n#   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n#   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n#\n# Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n# Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n#\n\n# Función sin parámetros ni retorno\ndef saludo_simple():\n    print(\"¡Hola, mundo!\")\n\n# Función con un parámetro y retorno\ndef cuadrado(numero):\n    return numero ** 2\n\n# Función con varios parámetros y retorno\ndef suma_y_producto(a, b):\n    suma = a + b\n    producto = a * b\n    return suma, producto\n\n# Función que llama a otras funciones\ndef operaciones_complejas(x, y):\n    resultado_cuadrado = cuadrado(x)\n    suma, producto = suma_y_producto(resultado_cuadrado, y)\n    return suma, producto\n\n# Función con variable local y global\ndef ejemplo_variables():\n    variable_global = 10\n\n    def funcion_interna():\n        variable_local = 5\n        return variable_global + variable_local\n\n    resultado = funcion_interna()\n    return resultado\n\n# Uso de una función incorporada en Python\nlongitud_lista = len([1, 2, 3, 4, 5])\n\n# Pruebas\nsaludo_simple()\nprint(\"Resultado del cuadrado:\", cuadrado(4))\n\nsuma_resultado, producto_resultado = suma_y_producto(3, 5)\nprint(\"Suma y Producto:\", suma_resultado, producto_resultado)\n\nresultado_operaciones, producto_operaciones = operaciones_complejas(2, 3)\nprint(\"Resultado de operaciones complejas:\", resultado_operaciones, producto_operaciones)\n\nprint(\"Ejemplo de variables locales y globales:\", ejemplo_variables())\nprint(\"Longitud de la lista:\", longitud_lista)\n\n\ndef imprimir_numeros_y_contar(texto1, texto2):\n    contador = 0\n\n    for numero in range(1, 101):\n        if numero % 3 == 0 and numero % 5 == 0:\n            print(texto1 + texto2)\n        elif numero % 3 == 0:\n            print(texto1)\n        elif numero % 5 == 0:\n            print(texto2)\n        else:\n            print(numero)\n\n        contador += 1\n\n    return contador\n\n# Ejemplo de uso\nresultados = imprimir_numeros_y_contar(\"Fizz\", \"Buzz\")\nprint(\"Número de veces que se ha impreso:\", resultados)\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/jesusgdev.py",
    "content": "'''\n EJERCICIO:\n1. Crea ejemplos de funciones básicas que representen las diferentes\n   posibilidades del lenguaje: sin parámetros ni retorno, con uno \n   o varios parámetros, con retorno...\n2. Comprueba si puedes crear funciones dentro de funciones.\n3. Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n4. Pon a prueba el concepto de variable LOCAL y GLOBAL.\n* Debes hacer print por consola del resultado de todos los ejemplos.\n  (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n \n DIFICULTAD EXTRA (opcional):\n7. Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n  - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n  - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n  - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n  - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n  - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\n Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n'''\n\n# 1. Ejemplos de funciones basicas:\n\n# Funcion sin parametros de retorno:\n\ndef greet():\n    print(\"Hello, world!\")\n\ngreet()\n\n# Funcion con parametros pero sin retorno:\n\ndef greet_user(name):\n    print(\"Hello, \" + name + \"!\")\n\ngreet_user(\"Jesus\")\n\n# Funcion con retorno pero sin parametros:\n\ndef days_per_year():\n    return 365\n\nresult = days_per_year()\nprint(\"The year has \" + str(result) + \" days\")\n\n# Funciones con parametros y con retorno:\n\ndef addition(a,b):\n    return a + b\n\nresult = addition(5,7)\nprint(\"Sum: \" + str(result))\n\n# 2. Funciones dentro de funciones (Funciones anidadas)\n\ndef welcome(name):\n    def message():\n        return \"Hello, Welcome to my Website\"\n    \n    full_welcome_message = message()+ name +\"!\"\n    print(full_welcome_message)\n\nwelcome(\"Jesus\")\n\n# 3. Funciones ya creadas en el lenguaje (Funciones built-in)\n\ntext = \"This is a text to work with Python Built-In Functions\"\nprint(\"Lowecase text:\", text.lower()) # str.lower()\nprint(\"Uppercase text:\", text.upper()) # str.upper()\n\nnumbers = [1, 3, 6, 8]\nprint(\"Max:\", max(numbers)) # max()\nprint(\"Min:\", min(numbers)) # min()\nprint(\"Sorted:\", sorted(numbers)) # sorted()\nprint(\"sum:\", sum(numbers)) # sum()\n\n# 4. Variables locales y globales\n\nmessage = \"Hello from outside\" # Global Variable\nanswer = \"I don't get any answer!?\"\n\ndef show_message():\n    answer = \" I can hear you but you can't hear me!\"\n    print(\"Inside of the function: \"+message+\"...\"+answer)\n\nshow_message()\nprint(\"Outside of the function:\", answer)\n\n# 5. Función que reciba dos parámetros de tipo cadena de texto y retorne un número\n\ndef multiples(message1,message2):\n    count = 0\n    for num in range(1,101):\n        if num % 3 == 0 and num % 5 == 0:\n            print(message1 + \" and \" + message2)\n        elif num % 3 == 0:\n            print(message1)\n        elif num % 5 == 0:\n            print(message2)\n        else:\n            print(num)\n            count += 1\n    print (\"The amount of times that the fuction print a num was: \")\n    return print(count)\nmessage1 = \"This number is multiples of 3\"\nmessage2 = \"This number is multiples of 5\"\nmultiples(message1,message2)\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/jesusway69.py",
    "content": "import os\nos.system('clear') #MAC/LINUX\n#os.system('cls') #WINDOWS\n\n\"\"\"\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n\"\"\"\n\n#FUNCIÓN SIN RETORNO NI PARÁMETROS\ndef imprime_hasta_10():\n    for i in range (1,11):\n        print(i, end=' ')\n\nimprime_hasta_10()\n\n#FUNCIÓN CON RETORNO\ndef introducir_datos()->str:\n    mi_texto = input(\"Escriba su texto: \")\n    return mi_texto\n\n#FUNCIÓN SIN RETORNO CON UN PARÁMETRO RECIBIDO DE LA FUNCIÓN ANTERIOR \ndef imprimir_datos(mi_texto):\n    print(mi_texto)\n\nimprimir_datos(introducir_datos())\n\n\n#FUNCIÓN QUE RECIBE VARIOS PARÁMETROS\ndef calcular_media_valores (valor1, valor2, valor3,valor4,valor5):\n    media = (valor1+valor2+valor3+valor4+valor5)/5\n    print(media)\n\ncalcular_media_valores(1,3,5,7,9)\n\nmi_lista = [1,3,5,7,9] #variable global\nmi_otra_lista = [0,1,2,3,4,5,6,7,8,9] #variable global\n\n#FUNCIÓN QUE RECIBE UNA LISTA COMO PARÁMETRO\ndef calcular_media_lista (mi_lista):\n    print(sum(mi_lista)/len(mi_lista))\n\ncalcular_media_lista(mi_lista)\n\n\n#FUNCIÓN LAMBDA (SÓLO PARA CÁLCULOS)\ncalcular_media_lambda = lambda valor1,valor2,valor3,valor4,valor5:(valor1+valor2+valor3+valor4+valor5)/5\n\nprint(calcular_media_lambda(1,3,5,7,9))\n\n\n\n#FUNCIÓN LAMBDA CON FUNCIÓN DE LENGUAJE filter Y LLAMADA A OTRA FUNCIÓN ANTERIOR\nimpares = filter(lambda filtrado: filtrado % 2 != 0, mi_otra_lista)\ncalcular_media_lista(list(impares))\n\n#FUNCIÓN QUE RECIBE LA VARIABLE GLOBAL mi_lista E IMPRIME SUS VALORES CON BUCLE FOR\ndef imprimir_numeros_lista_for(mi_lista):\n    for i in (mi_lista):\n     print (i)\nimprimir_numeros_lista_for(mi_lista)\n\n#FUNCIÓN QUE IMPRIME LOS VALORES DE LA VARIABLE LOCAL mi_lista_local SIN USAR BUCLE\ndef imprimir_numeros_lista_sin_bucle():\n    mi_lista_local = [1,3,5,7,9] #variable local\n    print (* mi_lista_local)\nimprimir_numeros_lista_sin_bucle()\n\n\n#FUNCIÓN QUE RECIBE VARIABLE GLOBAL E IMPRIME VALORES SIN BUCLE CON SEPARADOR DEFINIDO\ndef imprimir_numeros_con_separador(mi_lista):\n    print (* mi_lista , sep = \"-\")\nimprimir_numeros_con_separador(mi_lista)\n\n#FUNCIÓN CON VARIABLE LOCAL QUE IMPRIME VALORES CON FUNCIÓN DE LENGUAJE join\ndef imprimir_numeros_con_funcion_join():\n    mi_lista_str = [\"1\",\"3\",\"5\",\"7\",\"9\"]#la lista se debe definir con strings para usar join\n    print('_'.join(mi_lista_str))\nimprimir_numeros_con_funcion_join()\n\n\n#FUNCIÓN IGUAL A LA ANTERIOR PERO RECIBE LISTA DE NÚMEROS Y LA CONVIERTE EN STRING\ndef imprimir_numeros_con_funcion_join_map(mi_lista):\n    print('>'.join(map(str, mi_lista))) # con el método propio map se castea la lista de numérica a string\nimprimir_numeros_con_funcion_join_map(mi_lista)\n\n\n#FUNCIÓN DENTRO DE OTRA FUNCIÓN\ndef elimina_pares():\n        def imprime_impares(mi_otra_lista):\n            print(mi_otra_lista)# 4- La función interna imprime la lista de impares\n\n        print(mi_otra_lista[0:len(mi_otra_lista)])# 1- Se imprime la lista completa\n        for i in mi_otra_lista:\n          if i % 2 == 0:\n            mi_otra_lista.remove(i)# 2- Se quitan los números pares\n\n        imprime_impares(mi_otra_lista)# 3- Llamamos la la función que imprime y le pasamos la lista de impares\n\nelimina_pares()\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\"\"\"\n\ncadena1 = \"Hola\"\ncadena2 = \"Python\"\n\ndef hola_python(cadena1,cadena2)->int:\n    acumulado=0\n    for i in range (1,101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(cadena1, cadena2)\n        elif i % 3 == 0:\n            print(cadena1)\n        elif i % 5 == 0:\n            print (cadena2)\n        else:\n            print(i)\n            acumulado +=1\n    print(f\"hay {acumulado} números que no son múltiplos de 3 ni de 5\")\n\nhola_python(cadena1,cadena2)"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/jfdacovich.py",
    "content": "# Función si parámetros\ndef hey():\n    print(\"Hey que tal?\")\n\n# Función con un parámetro\ndef hey_personalizado(nombre):\n    print(f\"Hey {nombre} que tal?\")\n\n# Función con varios parámetros\ndef suma(a, b):\n    return a + b\n\n# Función dentro de otra función\ndef funcion_outside():\n    print(\"OUT\")\n\n    def funcion_inside():\n        print(\"IN\")\n\n    funcion_inside()\n\n# Función creada en el lenguaje\ndef longitud(str):\n    return len(str)\n\n# Variables Locales y Globales\nglobal_var = \"Global\"\n\ndef funcion_var():\n    local_var = \"Local\"\n    print(local_var)\n    print(global_var)\n\n\"\"\"\nDificultad Extra\n\"\"\"\n\ndef imprimir_numeros(str1: str, str2: str) -> int:\n    count = 0\n    for num in range(1, 100+1):\n        if num % 3 == 0 and num % 5 == 0:\n            print(f\"Las dos cadenas: {str1},{str2}\")\n        elif num % 3 == 0:\n            print(f\"La cadena 1: {str1}\")\n        elif num % 5 == 0:\n            print(f\"La cadena 2: {str2}\")\n        else:\n            print(num)\n            count += 1\n    return count\n\nprint(\"----------funciones básicas----------\")\nhey()\nhey_personalizado(\"jfdacovich\")\nprint(suma(11,7))\nfuncion_outside()\nprint(longitud(\"Heyyy people!!\"))\nfuncion_var()\nprint(imprimir_numeros(\"buenass\", \"adiosss\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/jhoshmc.py",
    "content": "#funcion sin parametros ni rotorno\n\ndef saludar():\n  print(\"hola a todos los usuarios de puthon\")\n\n# funciones con parametros y retorno\ndef suma(numero_1,numero_2):\n  return numero_1+numero_2\n\n# fuciones anidadas\n\ndef anidada():\n  def hijo():\n    print(\"hola, soy el hijo\")\n  hijo()\n\n#funciones de python \ndef listas_nativas():\n  my_lista=[\"hola\",3,True,\"banaja\"]\n  print(my_lista)\n  tamaño= len(my_lista) # len(): funcion para ver el rango, cuanta, ya sea una lista, string(lista de caracteres),etc\n  print(tamaño)\n  for element in my_lista:\n    print(type(element)) # type(): permite ver el tipo que es el elemento\n  #forma de crear una lista usando la funcion lis()\n  lista_frutas= list((\"manzana\",\"pera\",\"naranja\"))\n  print(lista_frutas)\n  #print es una funcion que manda a imprimit en consola\n\n#variables globales y locales\nvariable_global= \"soy global\" # esta disponible en cualquier parte del código,\n                              # no tiene scope\ndef variables():\n  variable_local= \"soy local\" # solo está disponible en su scope,\n                              #en este caso solo en la funcion varables, fuera no existe\n  print(variable_global)\n  print(variable_local)\n\n# print(variable_local) aca daria error, ya que esta variable no existe fuera de la funcion donde fue creada\nprint(variable_global) # todo lo contrario con la variable global\n# funcion para retornar mas de un valor\ndef multiple_return():\n  return \"hola\",\"mundo\"\n\nuno,dos = multiple_return()\nprint(uno)\nprint(dos)\n\n#funcion con numero variable de argumentos\n\ndef  suma_2(*numeros):\n  resultado=0\n  for n in numeros:\n    resultado += n\n  return resultado\n\n# funcion con numero varible de argumentos y palabras clave\n# si , esta parte vi el video en youtuve :v\ndef variable_key_arg_greet(**names):\n  for key,value in names.items():\n    print(f\"hola {value} ({key})!\")\n\n#ejercicio extra\ndef extra(fizz,buzz)-> int: # -> int : indica que voy a retornar un valor numerico entero\n  contador=0\n  for i in range(1,101):\n    if(i % 15== 0):\n      print(f\"{i} {fizz}{buzz}\")\n    elif(i%5 == 0):\n      print(f\"{i} {buzz}\")\n    elif(i% 3 == 0):\n      print(f\"{i} {fizz}\")\n    else:\n      contador+=1\n  return contador\n# funciones \nsaludar()\nprint(suma(5,3))\n\nanidada()\nlistas_nativas()\nvariables()\nprint(suma_2(1,2,3,4,5))\ncontador= extra(fizz=\"fizz\",buzz=\"buzz\") # se pone biz=\"biz\", para que no importe el orden que ponga el argumento\nprint(contador)\nvariable_key_arg_greet(\n  lenguaje=\"python\",\n  name=\"brais\",\n  alias=\"MoureDev\",\n  age=36\n)\n\nprint(\"hola\".upper())\nprint(\"hola\".lower())"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/joandevpy.py",
    "content": "# Funciones definidas \n\n# Función simple sin parámetros ni retorno\ndef saludo():\n    print(\"Hola, Mundo!\")\n\nsaludo()\n\n# Función con un argumento\ndef saludar(nombre):\n    print(f\"Hola, {nombre}!\")\n\n# Ejecución de las funciones básicas\nsaludo()  # Vuelve a llamar a la función sin parámetros\nsaludar(\"Python\")  # Llama a la función con un argumento\n\n# Función con retorno\ndef return_saludar():\n    return \"Hola Python!\"\n\nprint(return_saludar())  # Imprime el valor retornado por la función\n\n# Función con varios argumentos y sin retorno\ndef saludos(saludo, nombre):\n    print(f\"{saludo}, {nombre}\")\n\nsaludos(\"Hi\", \"Joan\")  # Los argumentos se pasan en orden\nsaludos(nombre=\"Joan\", saludo=\"Hi\")  # Argumentos pasados por nombre\n\n# Función con un argumento con valor por defecto\ndef default_saludar(nombre=\"Python\"):\n    print(f\"Hola, {nombre}!\")\n\ndefault_saludar(\"Joan\")  # Llama a la función con argumento\ndefault_saludar()  # Llama a la función sin argumentos, usando el valor por defecto\n\n# Función con retorno de varios valores\ndef multiple_default_saludar():\n    return \"Hola\", \"Python\"\n\n# Asignación de múltiples valores retornados por la función\nsaludo, nombre = multiple_default_saludar()\nprint(saludo)\nprint(nombre)\n\n# Función dentro de una función\ndef operacion():\n    def resta(a, b):\n        return a - b\n    print(f\"La resta de 10 y 5 es: {resta(10, 5)}\")\n\noperacion()  # Llama a la función que contiene otra función\n\n# Función con un número variable de argumentos\ndef variable_arg_saludo(*nombres):  # El * significa que se le pueden pasar varios argumentos\n    for nombre in nombres:\n        print(f\"Hola, {nombre}\")\n\nvariable_arg_saludo(\"Joan\", \"Python\", \"Comunidad\")  # Llama a la función con múltiples argumentos\n\n# Función con un número variable de argumentos con palabra clave\ndef variable_key_arg_saludo(**nombres):\n    for key, value in nombres.items():\n        print(f\"{value} ({key})\")\n\nvariable_key_arg_saludo(\n    lenguaje=\"Python\",\n    nombre=\"Joan\",\n    alias=\"Joandevpy\", \n    edad=34\n)\n\n# Función dentro de una función\ndef otra_operacion():\n    def interna_operacion():\n       print(f\"Funcion interna: Hola, Python\")\n    interna_operacion()\n\notra_operacion()  # Llama a la función que contiene una función interna\n\n# Uso de funciones incorporadas (Built-in)\nprint(len(\"joandevpy\"))  # Imprime la longitud de la cadena\nprint(type(35)) # Imprime el tipo de la variable\nprint(\"joandevpy\".upper())  # Convierte la cadena a mayúsculas\n\n# Variables locales y globales\nglobal_variable = \"Soy una variable global\"\n\nprint(global_variable)  # Imprime la variable global\n\ndef prueba_variables():\n    local_variable = \"Esto sería\"  # Esta variable solo existe dentro de la función\n    print(f\"{local_variable}, {global_variable}\")  # Imprime las variables local y global\n\nprueba_variables()\nprint(global_variable)  # Imprime la variable global\n\n# Función que recibe dos parámetros de tipo cadena de texto y retorna un número\ndef print_numbers(text_1, text_2) -> int:\n    count = 0  # Inicializar el contador\n    for number in range(1, 101):\n        if number % 3 == 0 and number % 5 == 0:\n            print(text_1 + text_2)\n        elif number % 3 == 0:\n            print(text_1)\n        elif number % 5 == 0:\n            print(text_2)\n        else:\n            print(number)\n            count += 1\n    return count\n\n# Llamar a la función\nprint(print_numbers(\"Fizz\", \"Buzz\"))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/jofedev.py",
    "content": "\"\"\"\n    EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n\"\"\"\n\n\"\"\"\n    Funciones definidas por el usuario\n\"\"\"\n\n            # Simples\n\ndef greet():\n    print(\"Hola, cómo estás?\")\n\ngreet()\n\n\n            # Retorno\n\ndef return_def():\n    return \"Esta es un funcion con retorno\"\n\nreturn_functon = return_def()\nprint(return_functon)\n\n\n            # Con un argumento\n\ndef arg_greet(name):\n    print(f\"Hola, {name}\" )\n\narg_greet(\"Jose con un argumento!\")\n\n\n            # Con varios Argumentos\n\ndef args_greet(greet, name):\n    print(f\"{greet}, {name}\")\n\nargs_greet(\"Hola\", \"Jose con varios argumentos!\")\n\n\n            # Con un argumento predeterminado\n\ndef pre_greet(name=\"Jose\"):\n    print(f\"Hola, {name}, con un argumento predeterminado!\")\n\npre_greet()\n\n            # Con varios argumentos predeterminados\n\ndef pre_args_greet(greet= \"Hola\", name=\"Jose con varios argumentos predeterminados!\"):\n    print(greet, name)\n\npre_args_greet()\n\n\n            # Con varios argumentos y return\n\ndef return_args_greet(greet, name):\n    return f\"{greet}, {name}\"\n\nprint(return_args_greet(\"Hola\", \"Jose con varios argumentos y return!\"))\n\n\n            # Con retorno de varios valores\n\ndef return_greet_name():\n    return \"Hola\", \"Jose con retorno de varios valores!\"\n\ngreet, name = return_greet_name()\nprint(\"Hola\")\nprint(\"Jose con retorno de varios valores!\")\n\n\n            # Con un numero variable de argumentos\n\n\ndef variable_args_greet(*names):\n    for name in names:\n        print(f\"Hola, {name}\")\n\nvariable_args_greet(\"Jose\", \"Hola\", \"Estoy imprimiendo valores con un numero variables de argumentos\")\n\n\n            # Con un numero variable de argumentos con palabra clave\n\ndef variable_key_arg_greet(**names):\n    for key, value in names.items():\n        print(f\"Hola, {key} ({value})\")\n\nvariable_key_arg_greet(\n    nombre=\"Jose\",\n    saludo=\"Hola!\"\n)\n\n\n\"\"\"\n    Funcion dentro de otra funcion\n\"\"\"\n\ndef outer_function():\n    def inner_function():\n        print(\"Estoy imprimiendo una funcion dentro de otra funcion\")\n    inner_function()\n\nouter_function()\n\n\"\"\"\n    Funciones del lenguaje (built-in)\n\"\"\"\n\nprint(len(\"Jose\"))\nprint(type(6.3))\nprint(\"Jose\".upper())\nprint(\"jose\".capitalize())\n\n\n\"\"\"\n    Variables locales y globales\n\"\"\"\n\nglobal_variable = \"Python\"\n\n\ndef functtion_var():\n    local_variable = \"Hola\"\n    print(f\"{local_variable}, {global_variable}\")\n\n\nfuncttion_var()\n\n\n\n\"\"\"\n    Extra\n\"\"\"\n\n\ndef print_text(text_1, text_2) ->int:\n    count = 0\n    for i in range(1, 101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(text_1 + text_2)\n        elif i % 3 == 0:\n            print(text_1)\n        elif i % 5 == 0:\n            print(text_2)\n        else:\n            print(i)\n            count += 1 \n    return count\n\nprint(print_text(\"fizz\",\"buzz\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/jorgeadamowicz.py",
    "content": "## funciones definidas por el usuairo\n\ndef my_function ():\n    print(\"esta funcion solo imprime por consola\")\nmy_function ()\n\n##función con retorno\n\ndef my_return_function ():\n    return \"no me sale el ejercicio\"\n    \n#variable_con_retorno = my_return_function ()\n#print(variable_con_retorno)\nprint(my_return_function())\n\n### función con argumento \n\ndef my_argument_function (name, surname):\n    print(f\"{name} {surname}\")\nmy_argument_function(\"jorge\", \"adamowicz\")\n\n### función con argumento por defecto\n\ndef my_default_argument_function (name, surname, alias = \"Chorch\"): #argumento predefinido para \"alias\"\n    print (f\"{name} {surname} {alias}\")\nmy_default_argument_function( \"jorge\", \"adamowicz\")\nmy_default_argument_function( \"jorge\", \"adamowicz\", \"chorch\")\n\n### función con argumento posicional\n\ndef my_argument_function (name, surname):\n    print(f\"{name} {surname}\")\nmy_argument_function(surname = \"adamowicz\", name=\"jorge\")\n\n#funciones dentro de funciones\n\ndef outer_function ():\n    def inner_function():\n        print(\"esto si no lo sabia!\")\n    inner_function()\nouter_function()\n\n###funciones dentro del lenguaje (bult- in)\n\nprint(len(\"jroge adamowicz\"))\nprint(type(\"chorch\"))\n\n## variable global\nmy_global_var_name = \"jorge\"\nmy_global_var_surname = \"adamowicz\"\n\ndef imprimir_nombre_completo():\n    # Acceder a las variables globales dentro de la función\n    global my_global_var_name, my_global_var_surname\n    print(my_global_var_name, my_global_var_surname)\n\nimprimir_nombre_completo()\n\n### variable local\n\ndef imprimir_nombre_completo():\n   \n    my_local_var_name = \"jorge\"\n    my_local_var_surname = \"adamowicz\"\n    print(f\"{my_local_var_name}, {my_local_var_surname}\")\n\nimprimir_nombre_completo()\n\n#print(my_local_var_name)# no tendrá acceso y dará NameError 'my_local_var_name' is not defined\n\n\n### Extra ###\ndef my_extra_function (parameter_1, parameter_2):\n    counter = 0\n    multiplo_de_tres = 0\n    multiplo_de_cinco = 0\n\n    for number in range (1,101):\n        if number % 3 == 0 and number % 5 == 0:\n            counter += 1\n            \n        \n        elif number % 3 == 0:\n            multiplo_de_tres += 1\n            \n        \n        elif number % 5 == 0:\n            multiplo_de_cinco += 1\n            \n    return (f\" {parameter_1}, y {parameter_2}, {counter}\", f\"{parameter_1}, {multiplo_de_tres}\", f\"{parameter_2}, {multiplo_de_cinco}\")\n \n\nprint(my_extra_function (\"multiplo de tres \" , \"multiplo de cinco \"))\n\"\"\"\n#cuando vi el video, me di cuenta de que habia entendido mal la premisa. de todas maneras haber podido resolver\nesto fue genial. soy muy principiante en la programación y ademas un poco entrado en años. a continuación voy a \nintentar resolverlo ya que el retp de \"fizz, buzz\" ya lo he resulto en otro momento.\n\"\"\"\n\ndef my_extra_function (parameter_1, parameter_2):\n    counter = 0\n    \n    for number in range (1,101):\n        if number % 3 == 0 and number % 5 == 0:\n            print(parameter_1 + parameter_2)\n            \n        \n        elif number % 3 == 0:\n            print(parameter_1)\n            \n        \n        elif number % 5 == 0:\n            print(parameter_2)\n        else:\n            print(number)\n            counter += 1\n            \n    return f\"se ha impreso {counter} veces\"\n \n\nprint (my_extra_function (\"multiplo de tres \" , \"multiplo de cinco \"))\n\n  \n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/jose-larss.py",
    "content": "# Función sin parámetros ni retorno\nnumero1 = 3\nnumero2 = 5\ncadena = \"esto es una cadena\"\n\ndef suma_sin_params_ni_retorno():\n    suma = numero1 + numero2\n    print(\"La suma sin parámetros ni retorno es \", suma)\n\n# Función con parámetros pero sin retorno\ndef suma_con_params_sin_retorno(numero1, numero2):\n    suma = numero1 + numero2\n    print(\"La suma con parámetros pero sin retorno es \", suma)\n\n\n# Función con parámetros y retorno\ndef suma_con_params_y_retorno(numero1, numero2):\n    suma = numero1 + numero2\n    return suma\n\n# Funciones dentro de funciones\ndef funcion_dentro_funcion(numero1, numero2):\n    def resta(suma):\n        resta = suma - 67\n        print(resta)\n    suma = numero1 + numero2\n    resta(suma)\n    \n    return suma\n\n# Variables Locales\ndef suma_con_variables_locales(numero1, numero2):\n    numero1 = 43\n    numero2 = 54\n\n    suma = numero1 + numero2\n    return suma\n\ndef suma_con_variables_globales(numero1, numero2):\n    suma = numero1 + numero2\n    return suma\n\n\nsuma_sin_params_ni_retorno()\nsuma_con_params_sin_retorno(numero1, numero2)\nprint(\"La suma con parámetros y retorno es \", suma_con_params_y_retorno(numero1, numero2))\n\nprint(funcion_dentro_funcion(numero1, numero2))\nprint(\"esto es una función de pintar por la consola\")\nprint(\"Esto es una función que da la longitud de una variable, esta es \", len(cadena))\n\nprint(\"Esto es una suma con variables Locales \", suma_con_variables_locales(numero1, numero2))\nprint(\"Esto es una suma con variables Globales \", suma_con_variables_globales(numero1, numero2))\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\"\"\"\ncadena1 = \"esto es la cadena 1\"\ncadena2 = \"esto es la cadena 2\"\n\ndef funcion_extra(cadena1, cadena2):\n    contador = 0\n\n    for i in range(1, 101):\n        \n        if i % 3 == 0 and i % 5 == 0:\n            print(cadena1, cadena2)\n        elif i % 3 == 0:\n            print(cadena1)\n        elif i % 5 == 0:\n            print(cadena2)\n        else:\n            print(i)\n            contador += 1\n    return contador\n\ncontador = funcion_extra(cadena1, cadena2)\nprint(\"el numero de veces que se ha impreso el numero es\", contador)\n\ndef saludar(*names):\n    for name in names:\n        print(f\"Hola: {name}!!\")\n\nsaludar('pepe', 'juan', 'antonio', 'jose', 'pepita', 'cristina', 'angel')\n\ndef datos_usuario(**usuario): # es un diccionario\n    for key, value in usuario.items():\n        print(f\"Hola su {key} es {value}\")\n\ndatos_usuario(nombre='juan', apellidos='castro', edad=34, ciudad=\"Madrid\", codigo_postal=28016)"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/josecox13.py",
    "content": "\n#Funciones definidas por el usuario\n\n#Simple\ndef nombre():\n    print('Mi nombre es Jose')\n\nnombre()\n#Con retorno\ndef return_nombre():\n    return('Mi nombre es Jose')\nprint(return_nombre())\n\n#Con argumento\ndef nombre_arg(nombre):\n    print(f'Mi nombre es {nombre}')\nnombre_arg('Pepe')\n\n#Valores por defecto\ndef predet_nombre(nombre = 'Jose'):\n    print(f'Mi nombre es {nombre}')\npredet_nombre()\npredet_nombre('Pepe')\n\n#Con dos argumentos y posicionales\ndef city_country(city, country):\n    print(f'{city} está en {country}')\n\ncity_country('Madrid', 'España')\ncity_country(country='España', city='Madrid')\n\n#Especificando el tipo de dato de los argumentos\ndef suma_tipoarg(num1: int, num2:int):\n    return num1+num2\nprint(suma_tipoarg(3,5))\n\n#Especificando el tipo de dato de salida\ndef suma_tiposal(num1,num2) -> int:\n    return(num1+num2)\nprint(suma_tiposal(3,5))\n\n\n#Función que retorne varios valores\ndef suma_producto(num1, num2):\n    return num1, num2\nprint(suma_producto(3,6))\nsuma, producto = suma_producto(3,6)\nprint(suma)\nprint(producto)\n\n#Funciones con número variable de argumentos\ndef suma_var(*num):\n    contador = 0\n    for i in num:\n        contador += i\n    return contador\nprint(suma_var(4,5,6,7,8))\n\n\n#Funciones dentro de funciones\ndef impresion_suma(num1,num2):\n    def suma_interna(num1,num2):\n        return num1+num2\n    print(f'La suma es {suma_interna(num1,num2)}')\n\nimpresion_suma(5,6)\n\n#Funciones bult-in\nprint('Hola')\nprint(len('Caracola'))\nrange(9)\nprint(type('Hola'))\nprint('Hola'.upper())\n\n#Variable local y global\n#Variable global, su ámbito es superior a lo queremos afectar\nnumero = 45\ndef mostrar_num():\n    local_var = 'Esto es una variable local'\n    print(f'El numero es {numero}')\n\nmostrar_num()\n#print(local_var) dará error, ya que local_var solo está definida dentro de la función mostrar_num()\n\n\n#Ejercicio extra\nprint('Ejercicio extra')\ndef ejercicio_extra(string1:str, string2:str):\n    counter = 0\n    for i in range(101):\n        if i%3 == 0 and i%5 == 0:\n            print(string1,string2,sep='')\n        elif i%3 == 0:\n            print(string1)\n        elif i%5 == 0:\n            print(string2)\n        else:\n            print(i)\n            counter += 1\n    return counter\n\nprint(ejercicio_extra('cara','cola'))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/joshu725.py",
    "content": "# Funciones #\n\n# Simples\ndef jump():\n    print(\"Salto\")\n\njump()\n\n# Con retorno\n\ndef collect():\n    return \"Objeto\"\n\nprint(collect())\n\n# Con argumentos\n\ndef attack(damage, name):\n    return f\"Has realizado {damage} de daño al enemigo llamado {name}\"\n\nprint(attack(20, \"Paco\"))\nprint(attack(name=\"Paco\", damage=20))\n\n# Con argumentos predeterminados\n\ndef salute(name=\"a todos\"):\n    return f\"¡Hola {name}!\"\n\nprint(salute())\nprint(salute(\"Juan\"))\n\n# Retorno de varios valores\n\ndef eat():\n    return \"Manzana\", \"Platano\"\n\nfood1, food2 = eat()\n\nprint(food1)\nprint(food2)\n\n# Con un numero NO especificado de argumentos\n\ndef sum(*number):\n    total = 0\n    for n in number:\n        total += n\n    return total\n\nprint(sum(2, 3, 4, 5))\n\n# Funcion dentro de una funcion #\n\ndef a():\n    def b():\n        print(\"Test\")\n    b()\n\na()\n\n# Funciones de Python #\nprint(len(\"Prueba\"))\nprint(type(22))\nprint(int(23.52))\nprint(\"PRUEBA\".lower())\nprint(\"PRUEBA\".capitalize())\n\n# Variables locales y globales #\n\n# Variable global\nvar = 8  # Las variables declaradas fuera de una función se consideran globales\n\ndef test():\n    # Variable local\n    local = 3\n\n    print(var)\n\ntest()\n# print(local) # Da error porque estamos intentando acceder a una variable local, es decir, fue declarada dentro de una función\n\n# Extra #\n\ndef count(str1, str2):\n    n = 0\n    for i in range(1, 101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(str1 + str2)\n        elif i % 3 == 0:\n            print(str1)\n        elif i % 5 == 0:\n            print(str2)\n        else:\n            print(i)\n            n += 1\n\n    return n\n\nprint(count(\"Primero\", \"Segundo\"))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/jptxaya.py",
    "content": "#Funciones\n\ndef funcion_basica():\n    print(\"funcion basica\")\nfuncion_basica()\n\ndef funcion_con_parametros(param1):\n    print(f\"funcion con parametros {param1}\")\n    \nfuncion_con_parametros(\"Parametro 1\")\n\ndef funcion_return(param1, param2):\n    return(param1 + param2)\n\nprint(f\"funcion return {funcion_return(4, 5)}\")\n\n#Funcion anidada\ndef funcion1(param1):\n    def funcion1_1(param2):\n        print(f\"funcion1_1 {param2 * 2}\")\n    def funcion1_2():\n        print(\"funcion1_2\")\n    funcion1_1(param1 - 2) #LLamada a la funcion anidada\n        \nfuncion1(5)\n\n#Utilizacion de funcion\nprint(f\"Utilizacion de funcion sum {sum([1,2,3])}\")\n\n\nvariable_global = 2\n\ndef funcion_var():\n    variable_local = 3\n    print(\"variable local:\" + str(variable_local))\n    print(\"variable global dentro de funcion:\" + str(variable_global))\n    \nfuncion_var()\n\n#Dificultad Extra\nprint(\"Dificultad extra\")\n\ndef funcion_extra(param_str1, param_str2):\n    count = 0\n    for elem in range(1,101):\n        if elem % 3 == 0 and elem % 5 == 0:\n            print(param_str1 + \" \" + param_str2)\n        elif elem % 3 == 0:\n            print(param_str1)\n        elif elem % 5 == 0:\n            print(param_str2)\n        else:\n            print(elem)\n            count += 1\n    return count\n\nnum_veces = funcion_extra(\"texto1\",\"texto2\")\nprint(f\"Numero de veces solo Numero Funcion Extra: {num_veces}\")\n    "
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/jtrujilloalcocer.py",
    "content": "# #02 FUNCIONES Y ALCANCE\n#### Dificultad: Fácil | Publicación: 08/01/24 | Corrección: 15/01/24\n\n\"\"\"\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n\"\"\"\n#FUNCIONES SIN PARAMETROS NI RETORNO\ndef suma_():\n    a=3\n    b=5\n    print(a + b)\n    \ndef resta():\n    a=5\n    b=3\n    print(a - b)               \n    \ndef multiplicacion():\n    a=4\n    b=6\n    print(a * b)   \n    \n    \n#FUNCIONES CON UNO O VARIOS PARAMETROS\ndef suma_parametros(a,b):\n    print(a + b) \n       \ndef resta_parametros(a,b):\n    print(a - b)\n \ndef multiplicacion_parametros(a,b):\n    print(a * b)\n\n#FUNCIONES CON RETORNO / FUNCIONES DENTRO DE FUNCIONES\ndef calculadora():\n    print(\"¿Que operacion quieres realzar?\")\n    print(\"1.- Suma\")\n    print(\"2.- Resta\")\n    print(\"3.- Multiplicacion\")\n    opcion = int(input(\"Opcion: \"))\n    \n    print(\"Introduce los numeros\")\n    a = int(input(\"Numero 1: \"))\n    b = int(input(\"Numero 2: \"))\n    \n    if opcion == 1:\n        return suma_parametros(a,b)\n    elif opcion == 2:\n        return resta_parametros(a,b)\n    elif opcion == 3:\n        return multiplicacion_parametros(a,b)\n    else:\n        return \"Opcion no valida\"\n#calculadora()\n\n#DIFICULTAD EXTRA\ndef multiplos(a,b):\n    for i in range(1,101): #bucle de 1 a 100 \n        if i % 3 == 0 and i % 5 == 0:   #si el numero es multiplo de 3 y 5\n            print(a + b)\n        elif i % 3 == 0: #si el numero es multiplo de 3\n            print(a)\n        elif i % 5 == 0: #si el numero es multiplo de 5\n            print(b)\n        else:\n            print(i)\n    return i    #retorna el numero de veces que se ha impreso el numero en lugar de los textos\n\ndef app():\n    a = input(\"Introduce el primer texto: \")\n    b = input(\"Introduce el segundo texto: \")\n    return multiplos(a,b)\napp()\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/juanRCoder.py",
    "content": "# FUNCIONES \n'''Sin parametros ni retorno'''\n# No se esta retornando ni pidiendo nada solo ejecuta el bloque de codigo dentro la funcion.\ndef greet():\n    print('Hola, como estas?')\n    \ngreet() #-> Hola, como estas?\n\n\n'''Con un parametro'''\n# No se esta retornando solo pide un parametro.\ndef greet(name):\n    print(f'Hola, como estas {name}?')\n    \ngreet('juanRCoder') #-> Hola, como estas juanRCoder?\n\n\n'''Con varios parametros'''\n#Tiene un parametro name y luego un parametro variable que suma cantidad indefinida de numeros\ndef sumar(name, *args):\n    print(f'Buenos dias {name}')\n    print(sum(*args))\n\nsumar('Mario', [1,2,3,4,5]) # Buenos dias Mario | 15\n\n\n'''Con retorno'''\n# funcion con retorno si se cumple la condicion retorna y sale de la funcion, caso contrario retorna el ultimo return\n# el return, solamente retorna mas no imprime por eso se le coloca un print para ver el resultado retornado.\ndef isPar(n):\n    if n % 2 == 0: return 'Es par'\n    return 'No es par'\n\nprint(isPar(13)) # No es par\nprint(isPar(16)) # Es par\n\n\n'''Funciones dentro de otras funciones'''\n# Esta funcion retorna una lista de numeros primos menores a n.\ndef numPrimos(n):\n    # Funcion para saber si el numero es primo\n    def isPrimo(primo):\n        if primo <= 1: return True\n        for i in range(2, (primo//2)+1):\n            if primo % i == 0: return False\n        return True\n    \n    # Logica para almacenar numeros primos menores a n\n    primos = []\n    for j in range(2, n + 1):\n        if (isPrimo(j)): primos.append(j)\n    \n    return primos\n\nprint(numPrimos(10)) # [2, 3, 5, 7]\n    \n\n'''Algunas funciones integradas mas utilizadas'''\nprint(len(['a', 'b', 'c', 'd', 'e']))   # 5, cantidad de elementos.\nprint(max([20, 40]))                    # 40, numeros maximo de una lista.\nprint(type('string'))                   # <class 'str'>, tipo de dato.\nprint(dir(list))                        # muestra todos los metodos de una lista.\nprint(range(10))                        # rango de numeros entre 0, 10 inmutable.\n\n\n# VARIABLE GLOBAL Y LOCAL\n\"\"\"\nvariable local, es una variable que solo esta disponible dentro de un rango como una funcion o una condicional.\nvariable global, es una variable que esta en el codigo y puede ser utilizada en cualquier bloque de codigo mediante\nla palabra reservada 'global'.\n\"\"\"\n# EJEMPLO \n# Aqui podemos distingui una variable local y global\nx = 10      #-> variable global\ndef show():\n    x = 6   #-> variable local\n    return(x)\n\nprint(show()) # 6\nprint(x)      # 10\n\n# Usar la variable global dentro de la funcion\nx = 10       #-> variable global\ndef show():\n    global x # palabra reservada para usar la variable global dentro de la funcion\n    x = 6    #-> variable local\n    return(x)\n\nprint(show()) # 6\nprint(x)      # 6\n\n\n#  * DIFICULTAD EXTRA (opcional):\n\ndef cadena(str, str2):\n    lista = []\n    \n    # Agregar a la lista los numeros y los textos segun las condiciones\n    for i in range(0, 100 + 1):\n        if i % 3 == 0 and i % 5 == 0:\n            lista.append(f\"{str}{str2}\")\n        elif i % 3 == 0:\n            lista.append(str)\n        elif i % 5 == 0:\n            lista.append(str2)\n        else:\n            lista.append(i)  \n            \n    # Quitar los textos de la lista\n    lista = [letter for letter in lista if letter != str and letter != str2 and letter != f\"{str}{str2}\"]\n    return len(lista)\n\nprint(cadena('hola', 'mundo')) # 53\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/juanchernandezdev.py",
    "content": "### Python Functions And Scope ###\n\n#! Function Without Parameters\n\ndef my_func():\n  print('Hello I\\'m a function')\n  \nmy_func()\n\n#! Function Without Parameters or Return\ndef empty_func():\n  pass\n\n#! Function With Parameters\n\nnum_one = 1\nnum_two = 5\n\ndef add(num1, num2):\n  print(num1 + num2)\n  \nadd(num_one, num_two)\n\n#! Function With Return\n\nnum_one = 1\nnum_two = 5\n\ndef add(num1, num2):\n  return num1 + num2\n\nmy_sum = add(num_one, num_two)\n\nprint(my_sum)\n\n#! Function Inside Another Function\n\ndef top_function():\n  my_num = 20\n  num_one = 5\n  num_two = 10\n  \n  def inside_function(first_num, second_num):\n    sum = first_num + second_num\n    return sum\n  \n  inside_func_val = inside_function(num_one, num_two)\n  \n  print(inside_func_val + my_num)\n  \ntop_function()\n\n#! Python Built In Functions\n\n# Range\nmy_range = range(1, 10)\nprint(*my_range)\n\n# List\nmy_list = list(my_range)\nprint(my_list)\n\n# Sorted\nprint(sorted(my_list))\n\n# Len\nprint(len(my_list))\n\n# Sum\nprint(sum(my_list))\n\n# Max\nprint(max(my_list))\n\n# Min\nprint(min(my_list))\n\n# Round\nprint(round(20.85))\n\n# Slice\nprint(my_list[1:4])\n\n# Int\nprint(int('8'))\n\n# Str\nprint(str(10))\n\n# Type\nprint(type(int('8')))\nprint(type(str(10)))\n\n#! Functions Global Scope\n\nnum_one = 50 # Global variable\nnum_two = 25 # Global variable\n\ndef function_global_vars():\n  return num_one + num_two\n\nprint(function_global_vars())\n\nnum_one = 50 # Global variable\nnum_two = 25 # Global variable\n\ndef function_global_vars():\n  num_one = 25 # Local variable\n  num_two = 10 # Local variable\n  \n  return num_one + num_two\n\nprint(function_global_vars())\n\n#! Functions Local Scope\n\ndef function_local_vars():\n  num_one_local = 15\n  num_two_local = 8\n  \n  return num_one_local - num_two_local\n\nprint(function_local_vars())\n\n#* print(num_one_local) will throw an error since the variable is declared inside a function local scope\n\n#! Lambda Functions\n\nsum = lambda first_num, second_num: first_num + second_num\nprint(sum(10, 50))\n\nsum_two = lambda first_num, second_num: first_num + second_num + 60\nprint(sum_two(10, 50))\n\ndef function_with_lambda(first_arg, second_arg):\n  lam_sum = lambda first_lam_arg, second_lam_arg: first_lam_arg + second_lam_arg * 30\n  return lam_sum(first_arg, second_arg) + 500\n\nprint(function_with_lambda(125, 500))\n\n#! Optional Challenge\nprint('---Optional Challenge----')\n\ndef fizz_buzz_twist(txt1: str, txt2: str):\n  times_when_num = 0\n  \n  for num in range(1, 101):\n    if num % 3 == 0 and num % 5 == 0:\n      print(f'{txt1} and {txt2}.')\n    elif num % 3 == 0:\n      print(f'{txt1}.') \n    elif num % 5 == 0:\n      print(f'{txt2}.')\n    else:\n      times_when_num += 1\n    \n  return times_when_num\n\nprint(fizz_buzz_twist('It\\'s multiple of 3', 'It\\'s multiple of 5'))\n      \n  \n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/juandaherrera.py",
    "content": "\"\"\"\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n *\n\"\"\"\n\n\ndef my_function(text_1: str, text_2: str) -> int:\n    counter = 0\n    for number in range(1, 101):\n        if number % 3 == 0 and number % 5 == 0:\n            print(text_1 + text_2)\n        elif number % 3 == 0:\n            print(text_1)\n        elif number % 5 == 0:\n            print(text_2)\n        else:\n            print(number)\n            counter += 1\n    return counter\n\n\nif __name__ == \"__main__\":\n    my_var = my_function(\"Hola\", \"Mundo\")\n    print(\"----------------------------\")\n    print(my_var)\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/juanmax2.py",
    "content": "\"\"\"\nFunciones básicas\n\"\"\"\n\n# Simples\n\ndef saludar():\n    print(\"Saludos, Python\")\n    \nsaludar()\n\n# Con retorno\n\ndef sumar():\n    return 2 + 2\n\nresultado = sumar() # Guardar el retorno en variable\nprint(resultado)\n\n# Con argumento\ndef saludo_argumento(nombre):\n    print(f\"Hola, {nombre}\")\n\nsaludo_argumento(\"Juanma\")\n\n# Con argumento con valor por defecto\ndef resta_argumento(num = 10, num2 = 5):\n    print(f\"Resultado de {num} - {num2} = {num - num2}\")\n\nresta_argumento()\n\n# Con argumentos y retorno\ndef suma_argumentos(num = 10, num2 = 5):\n    return f\"La suma de {num} + {num2} = {num + num2}\"\n\nsuma = suma_argumentos()\nprint(suma)\n\n# Funciones con número variable de argumentos\n\ndef saludo_argumentos_variables(*args):\n    for nombre in args:\n        print(f\"Hola, {nombre}\")\n\nsaludo_argumentos_variables(\"Juanma\", \"Maria\", \"David\")\n\n# Con número variable de argumentos y palabra clave\ndef saludo_argumentos_variables_key(**args):\n    for parametro, nombre in args.items():\n        print(f\"{nombre} ({parametro})\")\n\nsaludo_argumentos_variables_key(lenguage = \"Python\", \n                            nombre = \"juanma\", \n                            alias = \"juanmax2\"\n                            )\n\n\n\"\"\"\nFunciones dentro de funciones\n\"\"\"\n\ndef funcion_externa():\n    def funcion_interna(): # Crear función interna\n        print(\"Hola, Python\")\n    funcion_interna() # Llamar función interna \n\nfuncion_externa()\n\n\"\"\"\nFunciones del lenguaje (built - in)\n\"\"\"\n# Funcion encargada de imprimir\nprint(\"Juanma\")\n# Retorna un entero con la longitud\nprint(len(\"Juanma\"))\n# Retorna el tipo de la variable\nprint(type(5))\n\n\"\"\"\nVariables: Locales y Globales\n\"\"\"\n\nvariable_global = \"Python\"\n\ndef hello_python():\n    variable_local = \"Hola\" # Esta variable solo funciona dentro de la funcón\n    print(f\"{variable_local}, {variable_global}\")\n\nhello_python()\n\n\"\"\"\nDificultad extra\n\"\"\"\n'''\nCrea una función que reciba dos parámetros \nde tipo cadena de texto y retorne un número.\n- La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n- Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n- Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n- Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n- La función retorna el número de veces que se ha impreso el número en lugar de los textos.\nPresta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\nCada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n'''\n\ndef print_numeros(texto1, texto2):\n    count = 0\n    for numero in range(1, 101):\n        if numero % 3 == 0 and numero % 5 == 0:\n            print(texto1 + \" \" + texto2)\n        elif numero % 3 == 0:\n            print(texto1)\n        elif numero % 5 == 0:\n            print(texto2)\n        else:\n            print(numero)\n            count += 1\n    return count\ncontador = print_numeros(\"Hola, Juanma\", \"Adiós, Juanma\")\nprint(f\"El número de veces que ha impreso un número es: {contador}\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/juanppdev.py",
    "content": "# 1 Función sin parámetros ni retorno:\ndef hola_mundo():\n    print(\"¡Hola, mundo!\")\n\nhola_mundo()\n\n# 2  Función con un parámetro:\ndef suma(a):\n    return a + 5\n\nprint(suma(3)) # 8\n\n# 3 Función con varios parámetros:\ndef multiplicacion(a, b):\n    return a * b\n\nprint(multiplicacion(2, 3)) # 6\n\n# 4 Función con retorno pero sin parámetros:\ndef pi():\n    return 3.141592653589793\n\nprint(pi()) # 3.141592653589793\n\n# 5 Crear funciones dentro de funciones:\ndef contador(inicio, fin):\n    def incremento(a):\n        return a + 1\n\n    contador = inicio\n    while contador < fin:\n        print(contador)\n        contador = incremento(contador)\n\ncontador(1, 6)\n\n# 6 Utilizar funciones ya creadas en el lenguaje python:\ndef cubo(x):\n    return x**3\n\nprint(cubo(2)) # 8\n\n# 7 Poner a prueba el concepto de variable LOCAL y GLOBAL:\nnumero = 42\n\ndef variable_global():\n    global numero\n    numero = 23\n    print(f\"Dentro de la función: {numero}\")\n\nvariable_global()\nprint(f\"Fuera de la función: {numero}\")\n\n# Ejercicio Extra:\n\"\"\"\n    DIFICULTAD EXTRA (opcional):\nCrea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\nLa función imprime todos los números del 1 al 100. Teniendo en cuenta que:\nSi el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\nSi el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\nSi el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\nLa función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\"\"\"\n\ndef cuenta_multiplos(texto1, texto2):\n   contador = 0\n\n   for i in range(1, 101):\n       if i % 3 == 0 and i % 5 == 0:\n           print(f\"{texto1}{texto2}\")\n           contador += 1\n       elif i % 3 == 0:\n           print(texto1)\n           contador += 1\n       elif i % 5 == 0:\n           print(texto2)\n           contador += 1\n       else:\n           print(i)\n\n   return contador\n\nprint(f\"La función ha impreso el número {cuenta_multiplos('Fizz', 'Buzz')} veces.\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/jucedinv.py",
    "content": "#02 - FUNCIONES Y ALCANCE\nprint('#02 - FUNCIONES Y ALCANCE')\n\n#FUNCTION without parameters\ndef greeting():\n    print('Welcome')\nprint('FUNCTION without parameters: greeting() --> Print text on console.')\ngreeting()\n\n#FUNCTION with parameter\ndef isprime(number):\n    sqrtn = int(number ** 0.5)\n    for i in range(2,sqrtn + 1):\n        if number % i == 0:\n            print('The number not is prime.')\n            break\n    else:\n        print('The nuber is prime.')\nprint('FUNCTION with parameter: isprime(21) --> Print if number 21 is prime or not.')\nisprime(21)\n\n#FUNCTION with output\ndef factorial(n):\n    if n == 0:\n        return 1\n    else:\n        return n * factorial(n-1)\nprint('FUNCTION with output: factorial(5) --> Return the factorial of 5.')\nprint('factorial(5) = ', factorial(5))\n\n#FUNCTION with parameters\ndef combinationf(n, r):\n    return factorial(n) / (factorial(r) * factorial(n-r))\nprint('FUNCTION with parameters: combinationf(4,2) --> Return the 4 combination 2.')\nprint('combinationf(4,2) = ', combinationf(4,2))\n\n#FUNCTION inside other function\ndef combinationfb(n, r):\n    def factorialb(n):\n        if n == 0:\n            return 1\n        else:\n            return n * factorialb(n-1)\n    return factorialb(n) / (factorialb(r) * factorialb(n-r))\nprint('FUNCTION inside other function: combinationfb(5,2) --> Return the 5 combination 2.')\nprint('Implements function factorialb(n) inside the combinationfb function.')\nprint('combinationfb(5,2) = ', combinationfb(5,2))\n\n#FUNCTIONS Built-in\nprint('FUNCTIONS Built-in')\nprint('Function divmod() --> Return a tuple containing two values, the quotient and remainder of the division.')\nprint('divmod(11,2) = ', divmod(11,2))\nprint('Function enumerate() --> Returns an enumerate object, this is an iterator that yelds pairs of (index,value).')\nprint('enumerate ([\\'apple\\', \\'orange\\', \\'banana\\']) = ', list(enumerate (['apple', 'orange', 'banana'])))\n\n#Use Variable Local and Global\nglobal_variable = 0\ndef iteration1():\n    for local_variable1 in range(1,11):\n        global global_variable\n        global_variable = global_variable + 1\n    print('local_variable1 = ', local_variable1)\ndef iteration2():\n    for local_variable2 in range(1,21):\n        global global_variable\n        global_variable = global_variable + 1\n    print('local_variable2 = ', local_variable2)\nprint('Use Variable Local and Global in two iterations and count individuals and total iterations.')\niteration1()\niteration2()\nprint('global_variable = ', global_variable)\n\n#DIFICULTAD EXTRA\ndef print100conditional(text1, text2):\n    count = 0\n    for i in range(1,101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(text1 + text2)\n        elif i % 3 == 0:\n            print(text1)\n        elif i % 5 == 0:\n            print(text2)\n        else:\n            print(i)\n            count += 1\n    return count\nprint('DIFICULTAD EXTRA')\nprint(print100conditional('texta', 'textb'))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/julianbuitragocharry-dev.py",
    "content": "def my_function():\n  print('Hello from a function')\n\n# call function\nmy_function()\n\n\n# function with argument\n# A parameter is the variable listed inside the parentheses in the function definition.\n# An argument is the value that is sent to the function when it is called.\ndef my_function(fname):\n  print('Hi', fname)\n\nmy_function('Emil')\nmy_function('Linus')\nmy_function('Mark')\n\n# function with two arguments\ndef my_function(fname, lname):\n  print(fname + '' + lname)\n\nmy_function('Mark', 'Zuckerberg')\n\n# arbitrary arguments\ndef my_function(*kids):\n  print(\"The youngest child is \" + kids[2])\n\nmy_function(\"Mark\", \"Elon\", \"Torvals\")\n\n# Keyboards arguments\ndef my_function(programmer1, programmer2, programmer3):\n  print('This is the first programmer:', programmer1, 'second programmer:', programmer2, 'third programmer:', programmer3)\n\nmy_function(programmer2 = \"Zavitar\", programmer1 = \"Moure\", programmer3 = \"Midu\")\n\n\n# arbitrary keyboards arguments\ndef my_function(**person):\n  print(\"His last name is \" + person[\"lname\"])\n\nmy_function(fname = \"Linus\", lname = \"Torvals\")\n\n\"\"\" You use functions to give recursion to your program, some common functions in Python.\n# print(): Used to display information in the console or another output device.\n# input(): Allows the user to enter data from the keyboard.\n# len(): Returns the length of an object, such as a string, list, tuple, etc.\n# range(): Generates a sequence of numbers.\n# open(): Used to open a file and perform read or write operations on it.\n# str(), int(), float(): Used to convert between different data types.\n\"\"\"\n\nglobal_var = \"I'm global variable\"\n\ndef global_example():\n    local_var = \"I'm local variable\"\n    print(f\"{local_var}, {global_var}!\")\n\nprint(global_var)\n# print(local_var) No se puede acceder desde fuera de la función\n\nvariable_global = 10\n\ndef funcion():\n    globals() ['variable_global'] = 20\n\nprint(variable_global)  # Output: 10\nfuncion()\nprint(variable_global)  # Output: 20\n\ndef fizz_buzz(txt_1, txt_2):\n   print('FIZZ BUZZ with STEROIDS')\n   for numb in range(1, 101):\n        if numb % 3 == 0 and numb % 5 == 0:\n            print(txt_1 + ',' , txt_2)\n        elif numb % 3 == 0:\n           print(txt_1)\n        elif numb % 5 == 0:\n           print(txt_2)\n        else:\n           print(numb)\n\nfizz_buzz('Hello', 'Python!')"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/juliand89.py",
    "content": "#funciones \n\n\n# sin parametro\n\ndef saludo():\n    print(\"Esta es una funcion sin parametros\")\nsaludo()    \n\n# con 1 parametro\n\ndef nombre(name):\n    print(f\"Hola {name} esta es una funcion con 1 parametro\")\nnombre(\"Julian\")\n\n\n# con 2 parametros\n\ndef mostrar_mayores(lista,n):\n    for i in lista:\n        if i > n:\n            print(i)\nmostrar_mayores([1, 2, 3, 4, 5], 2)   \n\n# con retorno\n\ndef suma(a,b):\n    return a + b\nprint(suma(89,2))\n\n# con valores por defecto\n\ndef resta(a=0,b=0,c=0):\n    print(a+b+c)\nresta(10, 5, 2)\nresta(3)  \n\n# anotacion en funcion \ndef multiplica_por_3(numero: int):\n    return numero*3\nprint(multiplica_por_3(6)) # 18\n  \n\n# Con un número variable de argumentos\ndef sume(*numeros): \n    total = 0\n    for n in numeros:\n        total += n\n    return total\nsume(1, 3, 5, 4) # 13\n\n# Con un número variable de argumentos con palabra clave\n\ndef variable_key_arg_greet(**names):\n    for key, value in names.items():\n        print(f\"{value} ({key})!\")\n\nvariable_key_arg_greet(\n    language=\"Python\",\n    name=\"Brais\",\n    alias=\"MoureDev\",\n    age=36\n)   \n\n\n#funcion dentro de funcion \ndef nombres(nom):\n    def apellidos(ape):\n        print(f\"su nombre es {nom} {ape}\" )\n    apellidos(\"salamanca\")\nnombres(\"Julian\")  \n\n\n# Funciones del lenguaje (built-in)\n\nprint(len(\"MoureDev\"))\nprint(type(36))\nprint(\"MoureDev\".upper())\n\n# Variables locales y global\n\nglobal_1 = \"Python\"\nprint(global_1)\n\ndef hello_python():\n    local_1 = \"Hola\"\n    print(f\"{local_1} {global_1}\")\nprint(global_1)\n#print(local_1) da error porque esta definida de forma local en la funcion    \nhello_python()\n\n#Ejercicio\n\ndef extra(cadena1,cadena2):\n    count = 0\n    for i in range(1,101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(cadena1 + cadena2)\n        elif i % 3 == 0:\n            print(cadena1)\n        elif i % 5 == 0:\n            print(cadena2)\n        else:\n            print(i)\n            count += 1\n    return count            \n\nprint(extra(\"Fizz\", \"Buzz\"))        "
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/juserdev.py",
    "content": "'''\n * EJERCICIO:\n * -> Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n'''\n\ndef funcion_sin_paremetros ():\n  print(\"Hola Python --> esta es la la funcion funcion_sin_parametro\")\n\nfuncion_sin_paremetros()\n\ndef funcion_con_un_parametro(num):\n  print(f\"El parametro es el numner {num} y sin retono --> esta es la funcion def funcion_con_un_parametro\")\n\nfuncion_con_un_parametro(10)\n\ndef funcion_con_dos_parametro(num1, num2):\n  print(f\"Esta es la suma de dos parametros: {num1 + num2} sin retorno --> esta es la funcion funcion_con_dos_parametro\")\n\nfuncion_con_dos_parametro(10,5)\n\ndef funcion_parametros_retorno(lenguaje):\n  return f\"El lenguaje que estas estudiando es: {lenguaje} --> Funcion con parametro y retorno\"\n\nprint(funcion_parametros_retorno(\"Python\"))\n\n# Funcion infinita\n\ndef funcion_infinita(*param):\n  return param\n\nprint(funcion_infinita(\"hola\", \"juan\")) # esto es una tupla\nprint(type(funcion_infinita(\"hola\", \"juan\")))\n\nsaludar, juan = funcion_infinita(\"hola\", \"juan\") # aqui le agregue variabels a cada parametro\n\nprint(f\"{saludar} {juan}\")\n\ndef funcion_infinita_2(*params):\n  for param in params:\n    print(f\"{param}\")\n\nfuncion_infinita_2(\"hola\", \"python\", \"soy Juan\")\n\ndef funcion_key_value(**names):\n  for key, value in names.items():\n    print(f\"{value}, {key}\")\n\nfuncion_key_value(leugaje=\"python\", edad=35, nombre=\"Juan\", alias=\"juserdev\")\n\n# Funciones globales y locales\n\nvar_global = \"variable global\"\n\ndef funcion_var_local():\n  var_local = \"variable local\" # No se puede acceder a esta variable fuera de esta funcion\n  print(f\"{var_global}, {var_local}\")\n\nprint(var_global)\nfuncion_var_local(\n\n)\n\n# FUNCIONES ENTRE FUNCIONES\n\ndef area(lado1, lado2):\n  area = lado1 * lado2\n  return area\n\ndef volumen(lado1, lado2, altura):\n  base = area(lado1, lado2)\n  return f\"Este es el voluemn de {lado1} * {lado2} + {altura} = {base * altura} --> Funcion anidada\"\n\nprint(volumen(10, 20, 10))\n\n# Funciones creadas en el lenguage\n\n\ntexto = \"este es un str de pruba para este ejemplo\"\nnumber = \"1\"\n\nprint(f\"Esta es el resultado de la funcion len() --> {len(texto)}\") # cuenta la cantidad de caracteres\nprint(f\"Esta es el resultado de la funcion ucapitalize() --> {texto.capitalize()}\") # pone la primera letra en Mayuscula\nprint(f\"Esta es el resultado de la funcion upper() --> {texto.upper()}\") # pone todo el texto en mayuscula\nprint(f\"Esta es el resultado de la funcion count() --> {texto.count(\"e\")} \") # Cuenta la cantidad de letras que tiene dentro del parentesis\nprint(f\"Esta es el resultado de la funcion isnumeric() --> {texto.isnumeric()} \") # verifica si es int o str\nprint(f\"Esta es el resultado de la funcion isnumeric() --> {texto.isnumeric()} \") # verifica si es int o str\nprint(f\"Esta es el resultado de la funcion isnumeric() --> {number.isnumeric()} \") # verifica si es int o str\n\n\n# DIFICULADAD EXTRA\n\ndef dificultad_extra(name, surname):\n  i = 0\n  while i < 100:\n    if i % 3 == 0 and i % 5 == 0:\n      print(name)\n    elif i % 3 == 0 :\n      print(surname)\n    elif i % 5 == 0:\n      print(f\"{name} {surname}\")\n    else:\n      print(i)\n    i += 1\n\n# dificultad_extra(\"juan\", \"rodriguez\")\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/k-90.py",
    "content": "### Función Simple\ndef my_function():\n    print(\"Hola Mundo!\")\n\nmy_function()\n\n### Función con Retorno\n\ndef function_return():\n    return \"Hola Mundo!\"\n\nprint(function_return())\n\n### Función con un argumento\n\ndef arg_function(code):\n    print(f\"Mi codigo es {code}\")\n\narg_function(\"Python\")\n\n### Función con dos argumentos\n\ndef arg_function_2(name, surname):\n    print(f\"Mi nombre es {name} y mi apellido es {surname}.\")\n\narg_function_2(\"Enrique\", \"Castro\")\narg_function_2(name=\"Kike\",surname=\"90\")\n\n### Función con argumento predeterminado\n\ndef fun_prede (name=\"Kike\"):\n    print(f\"Hola, {name}\")\n\nfun_prede(\"Avelino\")\nfun_prede()\n\n### Función con argumentos y return\n\ndef other_function(number1:int, number2:int):\n    number3 = number1 + number2\n    return number3\nprint(other_function(4,5))\n\n### Función con retorno de varios valores\n\ndef fun_var_val():\n    return \"Hola\", \"Mundo\"\n\nmy_function, name= fun_var_val()\nprint(my_function)\nprint(name)\n\n### Función con numero variable de argumentos\n\ndef variable_arg(*languages):\n    for language in languages:\n        print(f\"Mi codigo es {language}\")\n\nvariable_arg(\"Python\", \"Java\", \"JavaScript\",\"Kotlin\")\n\n### Función con numero variable de argumentos con palabra clave\n\ndef variable_arg_keys(**languages):\n    for key, language in languages.items():\n        print(f\"Mi codigo es {language} ({key}).\")\n\nvariable_arg_keys(\n    dificil = \"Cobol\",\n    medio = \"Python\",\n    facil = \"JavaScript\"\n)\n\n### Funciones dentro de funciones\n\ndef outside():\n    def inside():\n        print(\"Hola Mundo\")\n    inside()\n    \noutside()\n\n### Funciones del Lenguaje\n\nprint(len(\"Enrique\"))\nprint(type(33))\nprint(\"kike\".upper())\n\n### Variables Locales y globales\n\nvar_global = \"Enrique\"\n\ndef saludo():\n    var_local = \"Hola\"\n    print(f\"{var_local} {var_global}!\")\n          \nsaludo()\n\n### Extra\n\ndef ejercicio_extra(text1:str, text2:str) ->int:\n    contador = 0\n    for number in range(1,101):\n        if number % 3 == 0 and number % 5 == 0:\n            print(text1 + text2)\n        elif number % 3 == 0:\n            print(text1)\n        elif number % 5 == 0:\n            print(text2)\n        else:\n            print(number)\n            contador += 1\n    return contador\n\nejercicio_extra(\"Fizz\",\"Buzz\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/keltoi-dev.py",
    "content": "\"\"\"\n* EJERCICIO:\n* - Crea ejemplos de funciones básicas que representen las diferentes\n*   posibilidades del lenguaje:\n*   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n* - Comprueba si puedes crear funciones dentro de funciones.\n* - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n* - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n* - Debes hacer print por consola del resultado de todos los ejemplos.\n*   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n*\n* DIFICULTAD EXTRA (opcional):\n* Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n* - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n*   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n*   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n*   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n*   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n*\n* Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n* Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n\"\"\"\nvar_1 = \"Chau\"\nvar_2 = \"2023\"\n\n\n# Funcion sin parametros ni retorno\ndef sin_parametros():\n    print(\"Hola Python\")\n    print(2 * 5)\n\n\nprint(\"\\nFuncion sin parametros\")\nsin_parametros()\n\n\n# Funcion con parametros, pero sin retorno\ndef sin_retorno(num1, num2):\n    print(num1 + num2)\n\n\nprint(\"\\nFuncion con parametros, pero sin retorno\")\nsin_retorno(3, 4)\n\n\n# Funcion con parametros y con retorno\ndef con_retorno(num1, num2):\n    resultado = num1 * num2\n    return resultado\n\n\nprint(\"\\nFuncion con parametros y retorno\")\nprint(con_retorno(5, 6))\n\n\n# Funcion con variable local\ndef var_local():\n    local_1 = 4\n    local_2 = 6\n    print(\"La suma de las variables locales es: \", local_1 + local_2)\n\n\nprint(\"\\nEjemplo de variable local\")\nvar_local()\n\n\n# Funcion Lambda o anonima\nresta = lambda x, y: x - y\nprint(\"\\nEl resultado de la funcion Lambda es:\", resta(5, 3))\n\n\n# Funcion con variable global\ndef var_global():\n    global var_1\n    global var_2\n    var_1 = \"Hola\"\n    var_2 = \"2024\"\n\n\nprint(f\"\\nEl valor de las variables globales antes de una funcion: {var_1} {var_2}\")\nvar_global()\nprint(f\"El valor de las variables globales despues de una funcion: {var_1} {var_2}\")\n\n\n# Una funcion dentro de otra funcion\ndef funcion_1(dato_1, dato_2):\n    def funcion_2(dato):\n        print(f\"Esta es {dato}\")\n        return f\"Salio de {dato}\"\n\n    print(f\"Esta es {dato_1}\")\n    print(funcion_2(\"la funcion 2\"))\n    print(f\"Esta de nuevo en {dato_1}\")\n    return f\"Salio de {dato_1}\"\n\n\nprint(\"\\nFuncion dentro de otra funcion\")\nprint(funcion_1(\"la funcion 1\", \"la funcion 2\"))\n\n\n# Funcion recursiva\ndef factor(factores, factoreo):\n    numero = factores[-1]\n    if numero == 1:\n        return factores, factoreo\n    elif numero == 0:\n        return [], 1\n    else:\n        numero -= 1\n        factoreo *= numero\n        factores.append(numero)\n        return factor(factores, factoreo)\n\n\nprint(\"\\nEjemplo de funcion recursiva\")\nnum = 3\nfactores, factoreo = factor([num], num)\nprint(\"El factoreo es:\", factores)\nprint(\"El resultodo del factoreo es:\", factoreo)\n\n\n# Dificultad extra\ndef dificultad_extra(texto_1, texto_2):\n    contador = 0\n    for i in range(1, 101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(texto_1, texto_2)\n        elif i % 3 == 0:\n            print(texto_1)\n        elif i % 5 == 0:\n            print(texto_2)\n        else:\n            print(i)\n            contador += 1\n    return contador\n\n\nprint(\"\\nDificultad extra\")\ncantidad = dificultad_extra(\"Fizz\", \"Buzz\")\nprint(f\"Se han impreso {cantidad} numeros\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/kenysdev.py",
    "content": "# ╔══════════════════════════════════════╗\n# ║ Autor: Kenys Alvarado                ║\n# ║ GitHub: https://github.com/Kenysdev  ║\n# ║ 2024 - Python                        ║\n# ╚══════════════════════════════════════╝\n\n# 1. Funciones:\n# *************\n# Definir función:\ndef function_name():\n    print(\"1. Funciones:\")\n\nfunction_name()\n#_________________________\n# Con Parámetro:\ndef imprimir(parametro):\n    print(parametro)\n    \n# Con retorno:\ndef saludo(nombre):\n    return (f\"¡Hola, nombre!\")\n\nimprimir(saludo(\"Ken\"))\n#_________________________\n# Con parametros:\ndef resta(a, b):\n    return (a-b)\n\nimprimir(resta(4, 2))\n#_________________________\n# Con parámetro predeterminado.\ndef suma(a, b=5):\n    return (a + b)\n\nimprimir(suma(5))\n#_________________________\n# Número Variable de Argumentos:\ndef sumar_numeros(*numeros):\n    return sum(numeros)\n\nimprimir(sumar_numeros(1, 2, 3))\n#_________________________\n# Argumentos de palabra clave.\ndef usuario(**kwargs):\n    for key, value in kwargs.items():\n        print(f\"{key}: {value}\")\n\nusuario(nombre=\"Ben\", edad=\"21\")\n#_________________________\n# Con recursividad:\ndef recursivo(n):\n    if n == 0:\n        print(\"Completado\")\n    else:\n        print(n)\n        n -=1\n        recursivo(n)\n\nrecursivo(3)\n#_________________________\n# 2. Función anidada:\n# *******************\ndef principal(a):\n    def interna(b):\n        return (b + a)\n    b = a * 2\n    return interna(b)\n\nimprimir(principal(10))\n#_________________________\n# 3. Ejemplo de funciones incorporadas:\n# *************************************\n# Solicitar una entrada.\n#entrada = input(\"Escribe:\")\n#print(f\"Loro: {entrada}\")\n\nprint(len(\"123\"))   # total char\nprint(\"ABC\".lower()) # minusculas\nprint(\"abc\".upper()) # mayusculas\na, b = \"a b\".split() # divide una cadena\nprint(b)\n\n# conversión de tipo(int, float, str, list, bool)\nun_bool = True\nprint(type(un_bool))\na_str = str(un_bool)\nprint(type(a_str))\n\n#_________________________\n# 4. Variable LOCAL y GLOBAL.\n# *************************************\nVariable_global = \"Variable_global\"\ndef var():\n    variable_local = 21 \n    return Variable_global\n\nimprimir(var)\n# Variable local no accesible fuera de la función.\n#print(variable_local)\n#print(Variable_global)\n\n#_________________________\n# 5. Ejercicio:\n# *************\n'''\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n * - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n * - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n * - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n * - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\"\"\")\n'''\ndef ejercicio(str_1, str_2):\n    n_veces = 0\n    for num in range(1, 101):\n        if num % 3 == 0 and num % 5  == 0: print(str_1 + str_2)\n        elif num % 3 == 0: print(str_1)\n        elif num % 5 == 0: print(str_2)\n        else: n_veces +=1; print(num)\n    return(n_veces)\n\nimprimir(ejercicio(\"  múltiplo de 3\", \"  múltiplo de 5\"))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/knowledgesoftdev.py",
    "content": "import random\n\ndef funcionSinRetornoSinParametros():\n    print(\"Hola mundo\")\nfuncionSinRetornoSinParametros()\n\n\ndef funcionConRetornoConParametros(a,b):\n    return a+b\nresultadoFuncion=funcionConRetornoConParametros(12,2)\nprint(resultadoFuncion)\n\n\ndef funcionPrueba():\n    def funcionPruebaDos():\n        print(\"Esta la funcion que esta dentro de una funcion\")\n    funcionPruebaDos()\n    print(\"Esta funcion es padre\")\n\nfuncionPrueba()\n\n#funcion creada por el lenguaje\n#devolver numeros aleatorios entre un rango colocado por parametros\nnumRandom=random.randint(1,10)\nprint(\"Numero escondido es\",numRandom)\n\n#varible LOCAL y GLOBAL\nVARIABLE_GLOBAL=\"ES UNA VARIABLE GLOBAL\"\ndef ejemploVariable():\n    variable_local=\"soy una variable local\"\n    return VARIABLE_GLOBAL\n\n#como con conclusion se sabe que la variable local dentro de una funcion no puede ser accesible\nprint(ejemploVariable())\n#print(variable_local)\n\n\n'''\nCrea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n *   - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n'''\ndef funcion(param1=\"textoUNO\",param2=\"textoDOS\"):\n    cont=0\n    for i in range(1,101):\n        if(i%3==0):\n            print(param1)\n        elif(i%5==0):\n            print(param2)\n        elif(i%3==0 and i%5==0):\n           print(param1+param2)\n        else:\n            cont+=1\n    \n    return cont\n        \nprint(funcion())"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/kodenook.py",
    "content": "\ndef name() -> None:\n    print('kodenook')\n\nname()\n\ndef full_name(fname: str = 'my', lname: str = 'name') -> None:\n    print(f'{fname} {lname}')\n\nfull_name(lname = 'lname')\n\ndef addition(*nums: int|float) -> int|float:\n    result: int = 0\n\n    for num in nums:\n        result += num\n\n    return result\n\nprint(addition(2, 3, 1, 10, 1.5))\n\ndef person(**persons: str|int) -> None:\n    for attribute in persons:\n        print(persons[attribute])\n\nperson(name = 'kodenook', age = 27, country = 'chile')\n\ndef first() -> None:\n    print('first')\n\n    def second() -> None:\n        print('second')\n\n    second()\n\nfirst()\n\nx = \"awesome\"\n\ndef global_variable():\n  print(\"Python is \" + x)\n\nglobal_variable()\n\nx = \"awesome\"\n\ndef local_variable():\n  x = \"fantastic\"\n  print(\"Python is \" + x)\n\nlocal_variable()\n\nprint(\"Python is \" + x)\n\nx = lambda a, b : a + b\n\nprint(x(1, 5))\n\n\"\"\" Exercise \"\"\"\n\ndef exercise(word1: str ,word2: str) -> int:\n    count_numbers = 0\n\n    for x in range(1, 101):\n        if x % 3 == 0 and x % 5 == 0:\n            print(word1)\n        elif x % 3 == 0:\n            print(word1)\n        elif x % 5 == 0:\n            print(word2)\n        else:\n            count_numbers += 1\n\n    return count_numbers\n\n\nprint(f'number of times it was a number and not words: {exercise('hello', 'python')}')"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/kuroz00.py",
    "content": "''' * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:'''\n#variables\na = 10\nb = 20\nc = 0\nsaludo = 'saludos estimado usuario!\\n'\n\ndef funcionConTodo(): #Una funcion con varias funciones dentro\n    #Funcion con parametros\n    def saludoSuma(a, b):\n        c = a + b\n        print(saludo, a, '+', b, '=', c, '\\n')\n\n    saludoSuma(a, b)\n\n    dialogo = 'me cuesta mucho trabajo hacer una carita feliz ->'\n    #Funcion sin parametros\n    def presentacion():\n        print(dialogo)\n        amsiedad = ':d', ':d', ':d', ':d', ':d', ':d', ':d', ':D' #variable local, no se puede utilizar fuera de la funcion\n        print(amsiedad, '\\n') \n    presentacion()\n\n    #funciones con retorno\n    def si_o_no():\n        if any (caracter == '>' for caracter in dialogo):\n            variable_extremadamente_larga_y_totalmente_inutil_en_el_programa_que_no_deberia_existir_pero_aun_asi_la_incluyo_porque_soy_tonto = True\n        else:\n            variable_extremadamente_larga_y_totalmente_inutil_en_el_programa_que_no_deberia_existir_pero_aun_asi_la_incluyo_porque_soy_tonto = False\n\n        return variable_extremadamente_larga_y_totalmente_inutil_en_el_programa_que_no_deberia_existir_pero_aun_asi_la_incluyo_porque_soy_tonto\n    print(si_o_no(), '\\n') #Return = True en caso de existir \">\", sin el Return, el valor seria NONE.\n\nfuncionConTodo()\n\n\na = 'hola'\nb = 'mundo'\nimport random\ndef dificultadExtra(a , b):\n    i2 = 0\n    for i in range(1, 101):\n        if i % 3 == 0 and i % 5 == 0 :\n            print(i, a, b)\n        elif i % 3 == 0:\n            print(i, a)\n        elif i % 5 == 0:\n            print(i, b)\n        else:\n            i2 = i2 + 1\n            print(i)\n    print('\\n', 'Numero de veces que no se imprimio ningun parametro:')\n    return i2\n\nprint(dificultadExtra(a, b))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/lPassword012.py",
    "content": "# Funciones:\n\ndef imprimir_mensaje():\n    print(\"Aprendiendo Python desde cero con el profe Mouredev\\n\")\n\n# Definimos una funcion que sera pasada como parametro\ndef saludar(nombre):\n    return f\"Hola, {nombre}!\"\n\n# Definimos otra funcion que recibe una función como parametro\ndef ejecutar_funcion(funcion, argumento):\n    return funcion(argumento)\n\n# Usamos la funcion\nresultado = ejecutar_funcion(saludar, \"lPassword012\")\nprint(resultado)  # Salida: Hola, lPassword012!\nimprimir_mensaje()\n\n# Variables locales y globales:\nnombre_usuario = \"lPassword012\"\n\ndef modificar_primer_mensaje():\n    usuario_incorrecto = \"lPassword123\" # Variable local.\n    return usuario_incorrecto\n\ndef modificar_segundo_mensaje():\n    global nombre_usuario  # Permite modificar la variable global dentro de la función\n    print(\"Comprobando nombre de usuario: \",nombre_usuario) # Comprobamos que valor tiene nombre_usuario.\n    print(\"Usuario registrado.\\n\")\n    nombre_usuario =  modificar_primer_mensaje()\n    print(\"Incorrecto, usuario no registrado.\",nombre_usuario)\n    print(\"Intente nuevamente!\\n\")\n\nprint(\"Incorrecto, usuario no registrado.\",modificar_segundo_mensaje()) # La funcion no retorna ningun valor.\nprint(\"\\nComprando si el usuario existe.\",nombre_usuario)\nprint(\"Intente nuevamente!\\n\")\n\n\n# Primero se llama a la funcion modificar_segundo_mensaje(), dentro de la funcion se llama a otra funcion.\n# modificar_primer_mensaje() que retorna un valor que se asigna a nombre_usuario (global).\n# pero modificar_segundo_mensaje() no retorna nada y devuelve None. Por ultimo.\n# imprimimos un el valor de la variable global.\n\n# Ejercicio extra:\ndef imprimir_numeros(cadena1: str, cadena2: str) -> list[int]:\n    contador = 0\n    numeros_sin_remplazos: list[int] = []\n    \n    for numero in range(1, 101):\n        if numero % 3 == 0 and numero % 5 == 0:\n            continue\n        elif numero % 3 == 0:\n            continue\n        elif numero % 5 == 0:\n            continue\n        else:\n            contador += 1\n            numeros_sin_remplazos.append(numero)  # Se almacena el numero, no el contador\n\n    return numeros_sin_remplazos\n\n# Imprimo el arreglo y muestro la longitud\ncantidad_impresa = imprimir_numeros(\"numero1\", \"numero2\")\nprint(f\"\\nColeccion de numeros sin reemplazo:\\n\\n{cantidad_impresa}\\n\\nCantidad total de numeros: {len(cantidad_impresa)}\")\n\n# Nota: Para resolver el ejercicio ademas de obtener la solucion, aprendi sobre el tipado estricto en Python. \n# Usando 'mypy strict mode'. Requiere anotaciones de tipo explicitas en funciones y variables.\n# Ademas, modifique la solucion para retonar una lista de los n numeros y manipularlos en el futuro.\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/linerlander.py",
    "content": "\"\"\"\nFunciones definidad por el usuario\n\"\"\"\n\n# Función simple\n\ndef greet():\n    print(\"Hola, Python!\")\n\ngreet()\n\n# Función con retorno\n\ndef return_greet():\n    return \"Hola, Python!\"\ngreet = return_greet()\nprint(greet)\nprint(return_greet())\n\n# Función con 1 argumento\n\ndef arg_greet(name):\n    print(f\"Hola, {name}!\")\n\narg_greet('Liner')\n\n\n# Función con argumentos\n\ndef arg_greet(greet,name):\n    print(f\"{greet}, {name}!\")\n\narg_greet('Hi','Liner')\narg_greet(name = 'HannyDev',greet = 'Hello')\n\n# Función con un argumento predeterminado\ndef arg_greet(name = 'Java'):\n    print(f\"Hola, {name}!\")\n\narg_greet('Hanny')\narg_greet()\n\n\n# Función con argumentos y return\n\ndef return_args_greet(greet, name):\n    return f'{greet}, {name}!'\n\nprint(return_args_greet('Hello', 'Camilo'))\n\n# Con retorno de varios valores\n\ndef multiple_return_greet():\n    return \"Holaaaa\", \"Python\"\n\ngreet, name = multiple_return_greet()\nprint(greet, name)\n\n# funcion con un número de variables de argumentos\n\ndef variable_arg_greet(*names):\n    for name in names:\n        print(f\"Holaaaa, {name}!\")\nvariable_arg_greet('Python','Brais','Comunidad')\n\n\n# Con un número variable de argumento con palabras claves\n\ndef variable_key_arg_greet(**names):\n    for key, value in names.items():\n        print(f\"{value} ({key})!\")\nvariable_key_arg_greet(language = \"Python\",name = \"Brais\",alias = \"MoureDev\",age = 36)\n\n\n# Funciones dentro de funciones\n\ndef outer_function():\n    def inner_function():\n        print('Función interna: Hola, Python!')\n    inner_function()\nouter_function()\n\n\n# Funciones del lenguaje(built-in)\n\nprint(len('MoureDev')) #Función len\nprint(type(36)) #Función type\nprint('MoureDev'.upper()) #Función upper\nprint(complex(5)) #Función complex\nlista = [4,5,6]\nprint(sum(lista)) #Función suma\nprint('MoureDev'.lower()) #Función lower\nprint('moureDev brais'.title()) #Función title\nprint('mouredev brais'.capitalize()) #Función capitalize\nx = input('Inserte su número: ') # Función input\nprint(x)\nprint(int(5.740)) #función int\n\n\n\"\"\" \nVariables locales y globales\n\"\"\"\n\nglobal_variable = 'python' #Variable global\n\nprint(global_variable)\n\ndef hello_python():\n    #local_var = 'hola' , es una variable local y no se puede llamar afuera de la función\n    #print(f'{local_var}, {global_variable}')\n    print(f'Hola, {global_variable}')\nhello_python()\n#print(local_var)\n\n\n#DIFICULTAD EXTRA\n\ndef extra(text_1,text_2)-> int:\n    count = 0\n    for i in range(101) :\n        if i % 3 == 0 and i % 5 == 0:\n            print(f'{text_1}, {text_2}') \n        elif i % 3 == 0:\n            print(f'{text_1}') \n        elif i % 5 == 0:\n            print(f'{text_2}')\n        else:\n            print(i)\n            count += 1\n    return count\n \ncantidad = extra(\"Fizz\",\"Buzz\")\nprint(cantidad) "
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/luisssSoto.py",
    "content": "\"\"\"Functions\"\"\"\n\n'''1. Common Functions'''\n'''with parameters and return'''\ndef simplestFunction():\n    print('Show something on the screen')\n\n'''with parameters but without return'''\ndef simpleFunction(parameter1):\n    print(parameter1)\n\n'''with parameters and return'''\ndef commonFunction(parameter1, parameter2):\n    return parameter1, parameter2\n\n# Note: one thing is create a function and another is call the function, take a look at the next:\n\n'''with parameters and return and variable inside it'''\ndef additionFunction(value1, value2):\n    resultOfAddition = value1 + value2\n    return resultOfAddition\n\nresult = additionFunction(10,5)\nprint(result)\n\n\n'''2. Recursive Functions'''\n\ndef addition(number):\n    if number <= 2:\n        return 4\n    else:\n        return number + addition(number-2)\nprint(addition(10))\n\n# Note: be carefull with the operations that are not commutatives:    \ndef substraction(number):\n    if number <= 0:\n        return 4\n    else:\n        return number - substraction(number-1)\n\nprint(substraction(5)) # 5-4, 4-3, 3-2, 2-1, 1-0 ---> return 4 ---> 1-4=-3, 2--3=5, 3-5=-2, 4--2=6, 5-6=-1\n\n'''3. Python's functions'''\n'''print() is an example of Integrated functions of Python'''\nprint('any', 'thing', sep=\"*\", end=\"\\n\")\n\n'''4. local and global variables'''\n'''locals'''\n# Note: all the variables are locals unless you add the \"global\" keyword before the variable\nisLocal = True\ndef anyFunction():\n    print('all the local variables are visible from anywhere', isLocal, \n          '''unless the variable is created in a delimited space''')\n    fromFunction = \"I'm hidden\"\n\nanyFunction()\ntry:\n    print(fromFunction)\nexcept NameError:\n    print(\"it won't work\")\n    \n\n'''globals'''\ndef anotherFunction():\n    global isGlobal\n    isGlobal = True\n    print(isGlobal)\n\nanotherFunction() # It's important first call the function otherwise the line of code below, is going to do an error \"NameError\"\nprint(isGlobal)\n\n'''There is a concept calls scope to defines the scope's variable'''\nvar1 = 1\ndef localScope():\n    var1 = 'one'\n    return var1\nprint(var1)\nprint(localScope())\nprint(var1)\n\nvar2 = 2\ndef globalScope():\n    global var2\n    var2 = 'two'\n    return var2\nprint(var2)\nprint(globalScope())\nprint(var2)\n\n'''5. Extra difficult'''\ndef extraFunction(stringA, stringB):\n    count = 0\n    for i in range (1, 101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(stringA, stringB)\n        elif i % 3 == 0:\n            print(stringA)\n        elif i % 5 == 0:\n            print(stringB)\n        else:\n            print(i)\n            count+=1\n    return count\n\nprint(extraFunction('divisor by 3', 'divisor by 5'))\n\n\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/luistecnocode.py",
    "content": "'''\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n '''\n\n#############################\n####       FUNCIONES     ####\n#############################\n\n# Funciones simples\ndef greet():\n    print(\"Funciones simples: \")\n    print(\"Hola, Python!\")\ngreet()\n\n\n# Funciones con retorno\ndef return_greet():\n    print(\"Funciones con retorno: \")\n    return(\"Hola, Python retornado!\")\ngreet = return_greet()\nprint(greet)\n\n# Funciones con argumento\ndef arg_greet(name):\n    print(\"Funciones con argumento: \")\n    print(f\"Hola, {name}!\")\narg_greet(\"Luis\")\n\ndef args_greet(greet, name):\n    print(\"Funciones con argumentos sin ordenar: \")\n    print(f\"{greet}, {name}!\")\nargs_greet(name=\"Luis\", greet=\"Hi!\")\n\n# Funciones con argumento predeterminado\ndef default_arg_greet(name=\"Brais default\"):\n    print(\"Funciones con argumento predeterminado: \")\n    print(f\"Hola, {name}!\")\ndefault_arg_greet()\ndefault_arg_greet(\"Luis\")\n\n# Funciones con argumento y retorno\ndef return_args_greet(greet, name):\n    print(\"Funciones con argumentos y retorno: \")\n    return(f\"{greet}, {name}!\")\nprint(return_args_greet(\"Hi\", \"Luis!\"))\n\n# Funciones con retorno de varios valores\ndef multiple_return_greet():\n    print(\"Funciones con retorno de varios valores: \")\n    return \"Hola\", \"Python\"\ngreet, name = multiple_return_greet()\nprint(greet)\nprint(name)\n\n# Funciones con un número variable de argumentos\ndef variable_arg_greet(*names):\n    print(\"Funciones con un número variable de argumentos: \")\n    for name in names:\n        print(f\"Hola, {name}!\")\nvariable_arg_greet(\"Python\", \"Luis\", \"comunidad\" )\n\n# Funciones con un número variable de argumentos con palabra clave\ndef variable_key_arg_greet(**names): # En realidad crea un DICCIONARIO\n    print(\"Funciones con un número variable de argumentos con palabra clave: \")\n    for key, value in names.items():\n        print(f\"Hola, {value} ({key})!\")\nvariable_key_arg_greet(\n    language=\"Python\", \n    name=\"Luis\", \n    age=53 \n)\n\n\n\n\n#################################################\n####       FUNCIONES DENTRO DE FUNCIONES     ####\n#################################################\n\ndef outer_function():\n    def inner_function():\n        print(\"Funcion interna: Hola, Python!\")\n    inner_function() # Hay que llamarla desde dentro\nouter_function()\n\n\n#################################################\n####    FUNCIONES DEL LENGUAJE (BUILT-IN)    ####\n#################################################\nprint(\"Funciones del lenguaje o built-in\")\nprint(len(\"mi nombre es Luis\"))\nprint(type(26))\nprint(\"mi nombre es Luis\".upper())\n\n\n#################################################\n####       VARIABLES LOCALES Y GLOBALES      ####\n#################################################\n\nglobal_variable = \"Variable global\"\nprint(global_variable)\ndef local_variable():\n    print(f\"Hello, {global_variable}\")\n    mi_local_variable = \"variable local de la funcion\"\n    print(f\"Imprimo desde dentro, {mi_local_variable}\")\nlocal_variable()\n# print(mi_local_variable)  No se puede acceder desde fuera\nprint(\"No me deja imprimir mi_local_variable porque no la encuentra desde fuera\")\n\n\n#################################################\n####       EJERCICIO DE DIFICULTAD EXTRA     ####\n#################################################\n\ndef print_numbers(text1, text2)-> int:\n    count= 0\n    for number in range(1, 101):\n        if number % 3 == 0 and number % 5 == 0:\n            print(text1, text2)\n        elif number % 3 == 0:\n            print(text1)\n        elif number % 5 == 0:\n            print(text2)\n        else:\n            print(number)\n            count += 1 # Incrementa cuando imprimos número\n    return count\n        \nprint(print_numbers(\"Fizz\", \"Buzz\")) # Imprime el return"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/luterfloyd.py",
    "content": "'''\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n '''\nimport math # modulo de funciones incorporadas de matematicas segun standard de C\n\n# variables de alcance global. Pueden ser invocadas en cualquier parte del codigo\nnumero_global_1 = 2\nnumero_global_2 = 3\nlista_global = [1,5,3,8,34,9,32,-1]\ndict_global = {\"color\":\"amarillo\",\n               \"numero\":10,\n               \"listado\": (1,3,5,7)}\n\n\ndef saludando ():\n    '''\n    funcion sin parametros ni retorno. Los comentarios pueden colocarse dentro de la funcion\n    al inicio de modoe que puedieran ser consultados invocando funcion help() de la funcion\n    '''\n    print (\"Hola!\")\n\ndef divisible (numero):\n    '''\n    uso de una funcion lambda para manejar un argumento y luego se empleada\n    como otra funcion. Aqui retorna un valor distinto a cero (equivalente a true) si\n    la division es exacta, en caso contrario retorna 0 (equivalente a false) cunado la division\n    sea inexacta \n    '''\n    return lambda valor: not valor%numero\n\ndef funcion_con_parametros (numero1: int, numero2: int, numero3_opcional=0):\n    '''\n    funcion con argumentos fijos. Retorna el resultado de la sumatoria de los argumentos\n    mas una variable local. Implementacion de una funcion lambda\n    '''\n    variable_local = 10 # esta variable solo tendra el ambito de esta funcion\n    sumatoria =numero1+numero2+numero3_opcional+variable_local\n    es_par = divisible(2) \n    return (sumatoria,es_par(sumatoria))\n\n\ndef funcion_multiples_argumentos(*args):\n    '''\n    funcion con numero de argumentos indefinido\n    los argumentos son empaquetados en una tupla y se define con un *\n    '''\n    print (type(args))\n    sumatoria = 0\n    for numero in args:\n        sumatoria += numero\n    return sumatoria\n\ndef funcion_multiples_argumentos_dict (**args):\n    '''\n    funcion que recibe numero variable de argumentos pero en formato clave:valor\n    los argumentos son empaquetados en un diccionario y se define como **\n    '''\n    for clave, valor in args.items():\n        print (f'{clave} = {valor}')\n\n# funciones propias de python\ndef funciones_reservadas_python (lista):\n    '''\n    funcion definida en el modulo math de op. de python sum()\n    y la funcion de conversion a valor numerico entero int() asi como la \n    funcion max() que devuelve el mayor valor de un iterable\n    '''\n\n    sumatoria_lista=int(math.fsum(lista)) \n    print(f'la sumatoria de elementos de la lista es: {sumatoria_lista}')\n    print(f'el mayor numero de la lista es: {max(lista)}')\n    lista.sort() # metodo sort se aplica para cualquier iterable\n    return (lista)\n\ndef funcion_opcional (cadena1: str, cadena2: str):\n    '''\n    evalua un rango de enteros entre 1 y 100, determina si es multiplo de 3, de 5 o de ambos,\n    en cuyo caso imprime un texto correspondiente. En caso de no coincidir, contabiliza todos\n    esos caso y retorna ese valor\n    '''\n    impresion_numeros = 0\n    multiplo_de_3 = divisible(3) \n    multiplo_de_5 = divisible(5)\n\n    for numero in range(1,101):\n        if multiplo_de_3(numero) and multiplo_de_5(numero):\n            print (f'{numero} - multiplo de {cadena1} y {cadena2}')\n        elif multiplo_de_3(numero): \n            print(f'{numero} - multiplo de {cadena1}')\n        elif multiplo_de_5(numero):\n            print(f'{numero} - multiplo de {cadena2}')\n        else:\n            impresion_numeros+=1\n            print (numero)\n    return impresion_numeros\n        \n# funcion sin argumentos y sin valor de retorno:\nsaludando()\n\n# funcion con argumentos fijos. Se pueden definir valores por defecto (ver 3er. arg.)\n# recibe dos valores, los suma y retorna la sumatoria y un booleano\nprint (funcion_con_parametros(numero_global_1,numero_global_2))\nprint (funcion_con_parametros(numero_global_1,numero_global_2, 4)) # 3er argumento opcional\n\n# print (variable_local) esto generaria un error porque variable_local solo existe dentro\n# de la funcion que lo definio \n\n# una funcion tambien es un objeto asi que se puede asignar a una variable\n# en vez de recibir una tupla, se puede desempaquetar en variables separadas\nsumatoria = funcion_con_parametros\nvalor1, valor2 = sumatoria(numero_global_1,numero_global_2,100)\nprint (f'sumatoria: {valor1} es par?: {valor2}')\n\n# una funcion puede recibir un numero indeterminado de argumentos\n# internamente se convertira en una lista\nprint (funcion_multiples_argumentos(1,5,67))\n\n# tambien puede recibir un dicicionario como argumento variable\nfuncion_multiples_argumentos_dict (a=5, b=20, c=23,nombre=\"Juan\", apellido=\"Perez\",edad=25, estatura=1.78)\nfuncion_multiples_argumentos_dict(**dict_global)\n\n# existen funciones incorporadas en python. Algunas precisan ser importadas desde un modulo\n# como el caso de math{} para operaciones matematicas. Los objetos contienen a su vez funciones\n# (ej.: lista.sort() para ordenar internamente una lista) \nprint (funciones_reservadas_python(lista_global))\n\n# las funciones pueden ser pasadas como argumentos a otra funcion. tambien se les \n# conoce como funciones de orden superior. Tambien pueden ser retornadas\n\ndef suma(a:int, b:int):\n    return a+b\ndef resta(a:int, b:int):\n    return a-b\ndef operacion(funcion,valor1,valor2):\n    '''\n    la funcion recibe otra funcion como argumento y retorna el resultado de esa\n    funcion recibida\n    '''\n    return funcion(valor1,valor2)\n\n\nprint (f'resultado de la suma: {operacion(suma,2,3)}')\nprint (f'resultado de la resta: {operacion(resta,2,3)}')\n\nprint ('total numeros que no son multiplos de 3 o 5: ',funcion_opcional('tres','cinco'))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/m-doce.py",
    "content": "#Ejemplo de función sin retorno y sin parámetros\r\ndef Saludo():\r\n    print(\"Hola gente!\")\r\n\r\nSaludo()\r\n\r\n#Ejemplo de función sin retorno con un parámetro\r\ndef Saludo(name):\r\n    print(\"Hola {}!\".format(name))\r\n\r\nSaludo(\"m-doce\")\r\n\r\n#Ejemplo de función con retorno sin parámetros\r\ndef Usuario():\r\n    return \"m-doce\"\r\n\r\nprint(Usuario())\r\n\r\n#Ejemplo de función con retorno y un parámetro\r\ndef CambiarSigno(number):\r\n    return (number * -1)\r\n\r\nprint(CambiarSigno(9))\r\n\r\n#Ejemplo de función con retorno y parámetros\r\ndef Suma(numA, numB):\r\n    return (numA + numB)\r\n\r\nprint(Suma(5, 3))\r\n\r\n#Variable global: puede ser accedida desde cualquier parte del código\r\nporcentajeIVA = 1.21\r\n\r\n#Variable local: sólo podemos acceder a ella dentro del bloque de código que se haya declarado\r\ndef CalcularIVA(value):\r\n    resultado = value * porcentajeIVA\r\n    print(resultado)\r\n\r\nCalcularIVA(100)\r\n#print(resultado) | Al pertenecer a un bloque de código en particular, no puede ser utilizada fuera del mismo\r\n\r\n#EJERCICIO EXTRA\r\n\r\ndef Extra(stringA, stringB):\r\n    counter = 0\r\n    for i in range(1,101):\r\n        if(((i % 3) == 0) and ((i % 5) == 0)):\r\n            print(\"[+] \" + stringA + \" y \" + stringB)\r\n        elif((i % 3) == 0):\r\n            print(\"[+] \" + stringA)\r\n        elif((i % 5) == 0):\r\n            print(\"[+] \" + stringB)\r\n        else:\r\n            print(i)\r\n            counter+=1\r\n    return counter\r\n\r\ntotal = Extra(\"Azul\", \"Amarillo\")\r\nprint(\"En total se imprimieron {} numeros\".format(total))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/m1l0j05.py",
    "content": "\"\"\"\nExplicacion teorica:\n\nEn programación, una función es una secuencia de declaraciones que realizan una tarea específica, agrupada bajo un nombre. \nLas funciones son fundamentales para la organización y reutilización del código. \nEn Python, una función se define con la palabra clave def, seguida de un nombre de función, paréntesis (que pueden incluir argumentos) y dos puntos. \nEl cuerpo de la función sigue en líneas indentadas.\n\nEl alcance de una función se refiere a la visibilidad de las variables y otros objetos dentro de esa función. \nEn Python, el alcance se maneja con las reglas LEGB, que describen la secuencia en la que se buscan los nombres:\n    Local (L): Nombres asignados dentro de una función. No son visibles fuera de la función.\n    Enclosing (E): Nombres en el ámbito local de todas las funciones envolventes (de \"afuera hacia adentro\"), si existen.\n    Global (G): Nombres asignados en el nivel superior de un módulo o declarados globalmente en una función.\n    Built-in (B): Nombres preasignados en Python (como print, len).\n\"\"\"\n# Ejemplo de la teoria:\nx = \"global x\"  # Global scope\n\ndef test():\n    y = \"local y\"  # Local scope\n    print(y)\n    print(x)  # Accede a la variable global x\n\ntest()\n# print(y)  # Esto generaría un error, ya que y es local a la función test\n\n# Ejercicios:\n\ndef my_fuction():\n    print('Hello World!')\n\ndef my_fuction_inside():\n    x_local = 'Hello World!'\n    def inside():\n        print(x_local)\n    inside()\n\nmy_fuction()\nmy_fuction_inside()\n\nprint(f'The length of the variable is: {len(x)}' )\n\nprint(x)\n#print(x_local) # Descomentar para ver el error que genera al no estar dispnible la variable de forma global.\nprint('The variable x is global and the x_local is local')\n\n\n# Ejercicio Extra:\nprint('\\n[+] Ejercicio extra:\\n')\n\ndef fizzBuzz(word_1, word_2):\n    for i in range(1, 101):\n        output = ''\n        if i % 3 == 0:\n            output += word_1\n        if i % 5 == 0:\n            output += word_2\n        if not output:\n            output = str(i)\n        print(output)\n\nword_1 = 'Fizz'\nword_2 = 'Buzz'\n\nfizzBuzz(word_1, word_2)\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/macova96.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\nESTRUCTURA DE UNA FUNCION\ndef nombre_de_la_funcion (parametros): \n    codigo de la funcion\n    return valor_de_retorno\n\n\"\"\"\n#Este menú (funcion) sirve para imprimir por consola las funciones que he usado como ejemplo y retornar la eleccion del usuario\ndef menu_inicio ():\n    print(\"CALCULADORA PROPINAS\\t---> 1\")\n    print(\"BANNER\\t\\t\\t---> 2\")\n    print(\"DIFICULTAD EXTRA\\t---> 3\")\n    \n\n    return(input(\"elije una opcion: \"))\n\n#funcione dentro de funciones \ndef calculadora_propinas ():\n    #Declaro las variables que se tendrán en cuenta para el calculo de la propina y en el total a pagar por persona \n    total_cuenta= float(input(\"Ingresa el total de la cuenta: \\n $\"))\n    porcentaje_propina= float(input(\"Ingrese el porcentaje de la propina: \\n \")) \n    numero_personas = float(input(\"Ingrese el numero de personas a dividir las cuenta: \\n\"))\n\n    def calculo(total_cuenta, porcentaje_propina, numero_personas = 1 ):\n        #Esta funcion solo se encarga de calcular la propina y en total a pagar por persona \n        return (total_cuenta + (total_cuenta * ( porcentaje_propina / 100 ))) / numero_personas\n    \n    #uso es return de la funcion interna asignadolo a la variable de total a pagar \n    total_pagar = calculo(total_cuenta , porcentaje_propina , numero_personas)\n    return total_pagar\n\n\n\ndef impresora_banner ():\n    #esta funcion solo imprime un banner, sin parametros ni retornos usando la funcion interna PRINT\n    print(\"\"\"\n     _______     _  _          _______             _     _           _       \n(_______)   | |(_)        (_______)           (_)   | |         | |      \n _____ _____| | _ _____    _     _ _____ _   _ _  __| |_____  __| |      \n|  ___) ___ | || (___  )  | |   | (____ | | | | |/ _  (____ |/ _  |      \n| |   | ____| || |/ __/   | |   | / ___ |\\ V /| ( (_| / ___ ( (_| |      \n|_|   |_____)\\_)_(_____)  |_|   |_\\_____| \\_/ |_|\\____\\_____|\\____|      \n                                                                         \n _                             _          _______       _             _  \n| |                           | |        (_______)     (_)           | | \n| |____  ____  _   _ ____   __| | ___     _______ ____  _ ____  _____| | \n| |  _ \\|    \\| | | |  _ \\ / _  |/ _ \\   |  ___  |  _ \\| |    \\(____ | | \n| | | | | | | | |_| | | | ( (_| | |_| |  | |   | | | | | | | | / ___ | | \n|_|_| |_|_|_|_|____/|_| |_|\\____|\\___/   |_|   |_|_| |_|_|_|_|_\\_____|\\_)\n                                                                         \n    \"\"\")\n\ndef dificultad_extra ():\n    texto_1 = str (input(\"ingrese el primer texto \\t---> \"))\n    texto_2 = str (input(\"ingrese el segundo texto \\t---> \"))\n    contador = 1\n    \n    for numero in range(1, 101):\n        if (numero % 3) == 0:\n            print(texto_1)\n        elif (numero % 5) == 0:\n            print(texto_2)\n        elif (numero % 3) == 0 and (numero % 5) == 0:\n            print(texto_1 + texto_2)\n        else:\n            print(numero)\n            contador += 1\n\n    print(f\"El numero se ha impreso {contador} veces.\")\n\n\n\n\ndef main ():\n    #esta funcion utiliza el retorno de la funcion menu_inicio y dependiendo de la respuesta llama alguna de las funciones creada\n    opcion =menu_inicio()\n    if opcion == \"1\":\n        total = calculadora_propinas()\n        print(f\"El total a pagar es ${total} por persona\")\n    elif opcion == \"2\":\n        impresora_banner()\n    elif opcion == \"3\":\n        dificultad_extra()\n\n\n\nif __name__ == \"__main__\":\n    main()"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/majinka10.py",
    "content": "# Función sin parámetros ni retorno\ndef hola():\n    print('¿Esto es un retorno?')\n\nhola()\n\n# Función con parámetro sin retorno\ndef hola_y_medio(message: str):\n    print(f'No soy un retorno, pero puedo mostrar un mensaje: {message}')\n\nhola_y_medio('Wakanda!')\n\n# Función con parámetro y retorno\ndef chao(message: str):\n    return f'Soy un retorno y puedo llevar un mensaje: {message}'\n\nprint(chao('Viva Falcao!'))\n\n# Función con retorno de varios valores\n\ndef multiple_return():\n    return \"Hola\", \"Python\"\n\n\ngreet, name = multiple_return()\nprint(greet)\nprint(name)\n\n# Con un número variable de argumentos\n\n\ndef variable_arg(*names):\n    for name in names:\n        print(f\"Hola, {name}!\")\n\n\nvariable_arg(\"Python\", \"Guillermo\", \"Colombia\", \"Voleibol\")\n\nprint()\n\n# Funciones dentro de funciones\n\ndef super_funcion():\n    def sub_funcion():\n        return 'Puedo crear funciones dentro de funciones!'\n    return sub_funcion()\n    \nprint(super_funcion())\n\nprint()\n\n# Funciones ya creadas.\n\nprint(type(range(2)))\nprint(type(len(range(2))))\nprint(len(range(2))) # Longitud del rango de 0 a 1\n\nprint()\n\n# Variable LOCAL y GLOBAL\n\nvariable_global = 'Soy una variable global'\n\ndef prueba_variables():\n    variable_local = 'Soy una variable local'\n    print(f\"Desde una función: {variable_local}\")\n    print(f\"Desde una función: {variable_global}\")\n\nprueba_variables()\n\ntry:\n    print(\"Fuera de la función\", variable_local)\nexcept NameError as e:\n    print(\"Nao nao, no existe. Error:\", e)\n\nprint(\"Fuera de la función:\", variable_global)\n\nprint()\n\n# Ejercicio EXTRA\n\ndef extra(string_one: str, string_two: str) -> int:\n    cuenta = 0\n    for number in range(1, 101):\n        if number % 3 == 0 and number % 5 == 0:\n            print(f\"Primera cadena: {string_one} más la segunda cadena: {string_two}\")\n        elif number % 3 == 0:\n            print(f\"Cadena de texto del primer parámetro: {string_one}\")\n        elif number % 5 == 0:\n            print(f\"Cadena de texto del segundo parametro: {string_two}\")\n        else:\n            print(number)\n            cuenta += 1\n    return cuenta\n    \nprint(extra('Hola!', 'Perú!'))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/mallcca.py",
    "content": "'''\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n '''\n\n# Ejemplo de función\nprint('------------------------------')\nprint('Ejemplo de función sencilla')\nprint('------------------------------')\ndef suma(a, b):\n    return a + b\n\nprint(suma(10, 20))\n\nprint('------------------------------')\nprint('Ejemplo de función lambda')\nprint('------------------------------')\nfun = lambda x, y: x + y\nprint(fun(10, 20))\n\nprint('------------------------------')\nprint('Ejemplo de funciones que retornan muchos valores')\nprint('------------------------------')\ndef generate_123():\n    return 1, 2, 3\n\nprint(generate_123())\n\nprint('------------------------------')\nprint('Ejemplo de funciones que retornan muchos valores')\nprint('------------------------------')\ndef generate_123():\n    return 1, 2, 3\n\nprint(generate_123())\n\nprint('------------------------------')\nprint('Ejemplo de función dentro de otra función')\nprint('------------------------------')\ndef suma_y_resta(a, b):\n    def resta(a, b):\n        return a - b\n    return a + b, resta(a, b)\n\nprint(suma_y_resta(10, 300))\n\n\nprint('------------------------------')\nprint('Ejemplo usando variables globales')\nprint('------------------------------')\nglobal PI \nPI = 3.1415\n\ndef get_pi():\n    return PI\n\nprint(get_pi())\n\n'''\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n'''\nprint('------------------------------')\nprint('Dificultad extra ...')\nprint('------------------------------')\n\ndef funcion(a, b):\n    c_str = 0\n    c_int = 0\n    for num in range(101):                 \n        if num%3 == 0 and num%5 == 0:\n            print(a + b)\n        elif num%3 == 0:\n            print(a)\n        elif num%5 == 0:\n            print(b)\n        else:\n            c_int += 1\n            print(num)\n\n    return '# veces que se ha impreso un número: ' + str(c_int)\n\nprint(funcion('Texto 1', 'Texto 2'))\n\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/manjaitan.py",
    "content": "# variable GLOBAL.\n\nA = 6\nB = 6\n\n\n\n# Funciones sin retorno de variables ni valores.\n\ndef saludo():\n    print ('Hola Mundo')\n    \n    \nsaludo()\n\n# Funciones con varios parametros.\n\ndef saludo_parametros(nombre,apellidos):\n    print ('Hola gracias por pasarme los valores de nombre y apellidos: ' + nombre + apellidos)\n    def antisaludo():\n        print ('Ha solicitado el antisaludo')\n        \n    \n    \n    \nsaludo_parametros('Pedro ', 'Martinez Pérez')\n\n\n# Funcion con retorno de valores, con ejemplo de variables GLOBALES.\n\ndef suma(A,B):\n    return (A+B)\n    \nresultadoSuma =  suma(A,B)\nprint (resultadoSuma)\n\n# Funcion con retorno de valores, con ejemplo de variables locales.\n\ndef resta (a,b):\n    return (a-b)\n    \nresultadoResta = resta (8,7)\nprint (resultadoResta)"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/marcelosanchez166.py",
    "content": "\"\"\" EJERCICIO:\n- Crea ejemplos de funciones básicas que representen las diferentes\n  posibilidades del lenguaje:\n  Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n- Comprueba si puedes crear funciones dentro de funciones.\n- Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n- Pon a prueba el concepto de variable LOCAL y GLOBAL.\n- Debes hacer print por consola del resultado de todos los ejemplos.\n  (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n\nDIFICULTAD EXTRA (opcional):\nCrea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n  - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n  - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n  - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n  - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n  - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\nPresta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\nCada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\"\"\"\n\n\ndef funcion_sin_parametros():\n    print(\"Esta es una función sin parámetros ni retorno.\")\n\ndef funcion_con_parametros(param1, param2):\n    print(f\"Esta es una función con parámetros: {param1} y {param2}.\")\n\ndef funcion_con_retorno(param1, param2):\n    resultado = param1 + param2\n    print(f\"Esta es una función con retorno: {resultado}.\")\n    return resultado\n\ndef funcion_anidada():\n    def funcion_interna():\n        print(\"Esta es una función interna dentro de otra función.\")\n    funcion_interna()\n\nfuncion_sin_parametros()\n\nfuncion_con_parametros(\"Hola\", \"Mundo\")\n\nresultado = funcion_con_retorno(5, 10)\n\nprint(f\"Resultado de la función con retorno: {resultado}.\")\n\nfuncion_anidada()\n\n# Ejemplo de variable global y local\nvariable_global = \"Soy una variable global\"\ndef funcion_con_variable_local():\n    variable_local = \"Soy una variable local\"\n    print(variable_local)\n    print(variable_global)  # Acceso a la variable global\n\nfuncion_con_variable_local()\nprint(variable_global)  # Acceso a la variable global desde fuera de la función\n\n# Ejemplo de función ya creada en el lenguaje\nlista = [1, 2, 3, 4, 5]\ndef funcion_existente(lista):\n    suma = sum(lista)\n    print(f\"La suma de los elementos de la lista es: {suma}.\")\nfuncion_existente(lista)\n\n\n\ndef imprimir(caracter1, caracter2):\n    count = 0\n    for i in range(1, 101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(caracter1+caracter2)\n        elif i % 3 == 0:\n            print(caracter1)\n        elif i % 5 == 0:\n            print(caracter2)\n        else:\n            print(i)\n            count += 1\n    return f\"{count} Cantidad de números impresos.\"\n\n\nprint(imprimir(\"fizz\", \"buzz\"))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/marcoh2325.py",
    "content": "\"\"\"En python se puede escoger que retorna una función. En caso de no indicar que se retorna\n('return <objeto a retornar>') al final del flujo de ejecución de una función se retorna None\"\"\"\n\n# Ejemplo función sin parametros ni retorno\nprint(\"Ejemplo función sin parametros ni retorno\")\ndef print_hola():\n    print(\"Hola!\")\n\nprint_hola()\nprint()\n\n# Ejemplo función sin parametros con retorno\nprint(\"Ejemplo función sin parametros con retorno\")\ndef get_adios():\n    return \"Adios!\" #En este caso se retorna el string \"Adios!\"\n\nprint(get_adios())\nprint()\n\n# Si un parametro tiene un valor por defecto nos referiremos en este fichero a dicho\n# parametro como parametro opcional. Pues es opcional es pasarse el argumento\n# correspondiente a dicho parametro al llamar a la función\n# Si un parametro no tiene valor por defecto nos referiremos en este fichero a dicho\n# parametro como parametro obligatorio. Pues es necesario pasar el argumento correspondiente\n# a dicho parametro siempre que se llame a la función\n\n# Ejemplo función con un número finito de parametros (en este caso 2) y sin retorno\nprint(\"Ejemplo función con un número finito de parametros (en este caso 2) y sin retorno\")\ndef add_two_numbers(n_1, n_2):\n    print(n_1 + n_2)\n\n# A la hora de llamar a la función, pasar los argumentos es obligatorio, pues los parametros\n# no tienen un valor por defecto y el resultado de las operaciones que lleva a cabo la función\n# no se podría determinar (TypeError)\nadd_two_numbers(14, 15)\nprint()\n\n# Ejemplo función con un número finito de parametros (en este caso 3) y con retorno\ndef add_three_numbers(n_1, n_2, n_3):\n    return(n_1 + n_2 + n_3)\n\nprint(add_three_numbers(14, 15, 16))\nprint(add_three_numbers(14, n_3 = 16, n_2 = 15))\nprint()\n\n# Notar que hasta este punto en todas las funciones se tiene que indicar el valor de los \n# los argumentos en el momento en el que se llamen. Además los valores que toman los argumentos\n# depende del orden en el que se llamen estos\n# por ejemplo en la función add_two_numbers(14, 15) -> n_1 = 14 y n_2 = 15 en cambio\n# add_two_numbers(15, 14) -> n_1 = 15 y n_2 = 14\n# Este orden sin embargo se puede modificar indicando el nombre del parametro al cúal queremos que se\n# asigne el valor. Por ejemplo: calculate_sum(14, n_3 = 16, n_2 = 15)\n\"\"\"Regla sintactica de Python : A la hora de llamar a una función los argumentos con unicamente valor (<valor>) no pueden ir a la\nderecha de argumentos con nombre y valor (<nombre>=<valor>). Por ejemplo: calculate_sum(n_3 = 15, 14, n_1 = 15) es incorrecto \"\"\"\n\n# Ejemplo de función con un número finito de parametros en el cúal algunos o todos los parametros\n# tiene un valor por defecto\n\n\"\"\"Regla sintactica de Python: Un parametro sin valor por defecto (obligatorio) no puede ir a la derecha\nde un parametro con valor por defecto (opcional) al definir una función\nPor ejemplo: def print_fav_animal(animal = \"Gato\", sonido) es incorrecto \"\"\"\nprint(\"\"\"Ejemplo de función con un número finito de parametros en el cúal algunos o todos los parametros\ntiene un valor por defecto\"\"\")\ndef print_fav_animal(sonido, animal = \"Perro\"):\n    print(f\"Tu animal favorito '{animal}' dice {sonido}\")\n\n# En este caso, Proporcionar el argumento correspondiente al/los parametro/s\n# con valor por defecto al llamar a la función es opcional\nprint_fav_animal(\"Guau\")\nprint_fav_animal(\"Guau\", \"Ardilla\")\nprint_fav_animal(animal= \"Vaca\", sonido = \"Muuuuh\")\nprint()\n\n# Para evitar alargar demasiado este fichero, se sobreentenderá que para \n# el resto de combinaciones se puede o no indicar un objeto a retornar \n# en cada una de las siguientes funciones de ejemplo\n\n# Ejemplo de función utilizando el parametro especial *<nombre parametro>\n\n# Este parametro que normalmente se nombra *args, permite pasar tantos argumentos\n# (con únicamente valor ) como se desee a la hora de llamar a la función.\nprint(\"Ejemplo de función utilizando el parametro especial *<nombre parametro>\")\ndef add_numbers(*args):\n    total = 0\n    #args es una tupla que contiene todos los argumentos que se han pasado\n    for n in args:\n        total += n\n    print(total)\n\nadd_numbers(2, 5, 5, 6, 10, 17)\n\n# Ejemplo de función utilizando un número finito de parametros además del \n# parametro especial *<nombre parametro>\nprint(\"\"\"Ejemplos de función utilizando un número finito de parametros además del \nparametro especial *<nombre parametro>\"\"\")\ndef concat_2_or_more(n_1, n_2, *args):\n    full_concat = str(n_1) + str(n_2)\n    for n in args:\n        full_concat += str(n)\n    print(full_concat)\n    \nconcat_2_or_more(5, 0, 0, 0, 5)\n\n# En la definición el parametro *<nombre parametro> puede ir en cualquier posición, sin embargo\n# si no va el final (a la derecha del todo), a la hora de llamar a la función\n# será necesario indicar por su nombre de los argumentos obligatorios\n# Ejemplo:\ndef concat_2_or_more(n_1, *args, n_2):\n    full_concat = str(n_1) + str(n_2)\n    for n in args:\n        full_concat += str(n)\n    print(full_concat)\n    \nconcat_2_or_more(5, 0, 0, 0, n_2 = 5)\n# Ejemplo con retorno\ndef concat_2_or_more(*args, n_1, n_2):\n    full_concat = str(n_1) + str(n_2)\n    for n in args:\n        full_concat += str(n)\n    return full_concat\nprint(concat_2_or_more(3, 2, 1, n_1 = 5, n_2 = 4))\nprint()\n\n# Ejemplo función con algunos parametros con valor por defecto y usando el parametro\n# especial *<nombre parametro>\nprint(\"\"\"Ejemplo función con algunos parametros con valor por defecto y usando el parametro\nespecial *<nombre parametro>\"\"\")\nfrom random import choice\n# El parametro especial *<nombre parametro> puede estar en cualquier posición\ndef who_washes_the_dishes(*args, host=\"Marco\"):\n    people = list(args)\n    people.append(host)\n    print(\"El que lava los platos es: \", choice(people))\n\nwho_washes_the_dishes(\"Juan\", \"Mateo\", \"Pedro\", host=\"Horacio\")\n\n# Ejemplo con retorno:\ndef make_team(first_member=\"Steve Rodgers\", *args):\n    team = list(args)\n    team.append(first_member)\n    print(\"El primer integrante es: \", first_member)\n    return team\nprint(make_team(\"Clark Kent\", \"Bruce Wayne\"))\n\n# Ejemplos de funciones con parametros finitos, teniendo alguno de estos\n# valor por defecto y utilizando el parametro especial *<nombre parametro>\nprint(\"\"\"Ejemplos de funciones con parametros finitos, teniendo alguno de estos\nvalor por defecto y utilizando el parametro especial *<nombre parametro>\"\"\")\ndef show_car(price, n_wheels = 4, *extra_features):\n    print(\"Precio:\", price)\n    print(\"Número de ruedas: \", n_wheels)\n    print(\"Otras características: \", extra_features)\n\n# Utilizando lo visto anteriormente acerca del orden: los parametros con valores\n# por defecto deben ir después de todos los parametros obligatorios, el parametro especial\n# *<nombre parametro> puede ir en cualquier posición en este caso.\n# Puede ser mejor declarar los parametros con valor por defecto después de *<nombre parametro>\n# para así poder aprovechar el valor por defecto, en caso contrario\n# el primer argumento pasado en la llamada a la función después de los obligatorios\n# corresponderá al parametro con valor por defecto y no a *<nombre parametro>\n# Ejemplo en este caso no podríamos aprovechar el valor por defecto de n_wheels\n# porque si no indicamos un valor para este argumento (en este caso 6), el valor \"electrico\" corresponderá a\n# n_wheels\nshow_car(10000, 6, \"electrico\", \"color rojo\", \"año 2022\")\n\n#Ejemplo con retorno y con orden conveniente para aprovechar las características de los parametros\ndef show_car_2(price, *extra_features, n_wheels = 4):\n    print(\"Precio:\", price)\n    print(\"Número de ruedas: \", n_wheels)\n    print(\"Otras características: \", extra_features)\nshow_car_2(9000, \"diesel\", \"color blanco\", \"año 2019\")\nshow_car_2(12000, \"diesel\", \"color amarillo\", \"año 2021\", n_wheels = 8)\nprint()\n\n# Ejemplo: Uso del parametro especial **<nombre parametro>\n# Este parametro permite pasar como argumentos tantos objetos como se desee\n# y además especificar los nombres con los que se hará referencia a dichos objetos\nprint(\"Ejemplo: Uso del parametro especial **<nombre parametro>\")\ndef print_grocery_list(**kargs):\n    #kargs es diccionario, cuyas claves son los nombres de los argumentos y los valores, los valores de estos \n    for k, v in kargs.items():\n        print(f\"{v} {k}\")\n\nprint_grocery_list(Melon=1, Patatas=6, Lentejas_1kg=1)\n# El uso del parametro **<nombre parametro> es opcional a la hora de llamar la función\n\n# Ejemplo: Uso del parametro especial **<nombre parametro> y parametros obligatorios\nprint(\"\"\"Ejemplo: Uso del parametro especial **<nombre parametro> y parametros obligatorios\"\"\")\n# En este caso el único orden posible para los parametros en la definición es con **<nombre parametro> al final\ndef get_supermarket_codes(supermarket_name, **kargs):\n    print(\"Nombre supermercado: \", supermarket_name)\n    for k, v in kargs.items():\n        print(f\"{k}: {v}\")\nget_supermarket_codes(\"El badulaque\", S990 = \"Guindillas\", S130= \"Patatas fritas\", S220= \"Boleto loteria\")\nprint()\n\n# Ejemplo: Uso del parametro especial **<nombre parametro> y parametros opcionales\nprint(\"\"\"Ejemplo: Uso del parametro especial **<nombre parametro> y parametros opcionales\"\"\")\n# En este caso el único orden posible para los parametros en la definición es con **<nombre parametro> al final\ndef get_supermarket_codes_2(supermarket_name = \"Agora\", **kargs):\n    \"\"\"Muestra el nombre de un supermercado y la clave y nombre de algunos productos de este\"\"\"\n    print(\"Nombre supermercado: \", supermarket_name)\n    for k, v in kargs.items():\n        print(f\"{k}: {v}\")\nget_supermarket_codes_2(Y54 = \"Pizza 4 quesos\", AP7= \"Helado\", N64= \"Cebollas\")\n\"\"\"Regla de sintaxis de Python: Cuando se usa **<nombre parametro> en una función. A la hora\nde llamarla se podrá etiquetar los valores con cualquier nombre (los argumentos que hacen referencia\na **<nombre parametro>). Excepto los de los parametros obligatorios o opcionales, ya que estos\nnombres siempre harán referencia los parametros con el mismo nombre\"\"\"\n\"\"\"Regla: **<nombre parametro> tiene que ir siempre al final en la definición de la función en caso de usarse\"\"\"\n# En este caso esto significaría que supermarket_name = \"El badulaque\" hace referencia al parametro supermarket_name\n# y no **kargs\nget_supermarket_codes_2(Y54 = \"Pizza 4 quesos\", AP7= \"Helado\", N64= \"Cebollas\", supermarket_name = \"El badulaque\")\nprint()\n\n# Ejemplo de función utiliando el parametro especial **<nombre parametro>, parametros obligatorios\n# y opcionales\n# En este caso **<nombre parametro> no puede ser el primer parametro en la definición\n# porque como se menciono anteriormente tanto los parametros obligatorios o opcionales\n# tienen que ir antes que **<nombre parametro>\n# Unico orden posible para este caso:\n# (<parametros obligatorios>, <parametros opcionales>, **<nombre parametro>)\n# Ejemplo de caso sin retorno\nprint(\"\"\"Ejemplo de función utiliando el parametro especial **<nombre parametro>, parametros obligatorios\ny opcionales\"\"\")\ndef show_dictionary(dictionary_name, language = \"Español\", **dictionary):\n    print(dictionary_name)\n    print(\"Lenguaje: \", language)\n    for k, v in dictionary.items():\n        print(f\"{k}: {v} \")\n\n# A la hora de llamar a la función el argumento que corresponde al parametro obligatorio como\n# ya se ha mencionado puede ocupar cualquier posición siempre y cuando se mencione junto al valor el\n# parametro al cúal hace referencia (ejemplo: dictionary_name=\"Diccionario de la RAE\"). \nshow_dictionary(\"Diccionario de la lengua Española\", manzana=\"fruta roja\", coche= \"vehiculo de 4 ruedas\")\nshow_dictionary(banana=\"fruit of color yellow\", language = \"English\", dictionary_name = \"English dictionary\",\n                 mathematician= \"machine that transforms coffee into mathematics\")\nprint()\n\n# Ejemplo de función utilizando los parametros especiales **<nombre parametro> y *<nombre parametro>\n# Unico orden posible\n# (*<nombre parametro>, **<nombre parametro>)\nprint(\"Ejemplo de función utilizando los parametros especiales **<nombre parametro> y *<nombre parametro>\")\ndef get_translation(*words, **translator):\n    \"\"\"Traduce una lista de palabras a partir de un diccionario cuyas\n    claves son las palabras en el idioma de origen y los valores su traducción\n    en el idioma objetivo\"\"\"\n    print(\"El resultado de la traducción es: \")\n    for word in words:\n        if(word in translator.keys()):\n            print(word, \":\", translator[word])\n        else:\n            print(f\"La traducción de {word} se desconoce\")\n\n# Al llamar a la función no hay forma de hacer referencia al parametro *<nombre parametro> indicando\n# el nombre. Unicamente se puede entonces pasar los valores de los argumentos que se asignaran a *<nombre parametro>\n# A la hora de llamar a la función el único orden posible es:\n# (<argumentos *<nombre parametros>, <argumentos **nombre parametro>)\nget_translation( \"hola\", \"manzana\", \"car\", \"words\", hola=\"hello\", cebolla=\"onion\", manzana=\"apple\", words=\"palabras\")\nprint()\n# Notar que se puede utilizar el nombre del parametro especial *words, \n# como una de las etiquetas de los pares <nombre>=<valor> que se asignarán a **translator\n\n# Ejemplo de función utilizando los parametros especiales *<nombre parametro>, **<nombre parametro>\n# además de parametros obligatorios\n\ndef get_letter_encrypted(alphabet, key, c):\n    \"\"\"Dado un carácter retorna el caracter encriptado\n    utilizando cifrado cesar\"\"\"\n    base_i = 0\n    found = False\n    if (c not in alphabet): #Si el carácter no esta en el alfabeto no se modifica\n        return c\n    while ((base_i < len(alphabet)) and (not found)): #Si se llega a este punto\n        # realmente la condición base_i < len(alphabet) no es necesaria porque\n        # ya se sabe que el carácter esta en el alfabeto\n        if(c == alphabet[base_i]):\n            found = True\n        else: \n            base_i += 1\n    final_i = (base_i + key) % len(alphabet) # Se obtiene el nuevo índice\n\n    return alphabet[final_i]\n\nprint(\"\"\"Ejemplo de función utilizando los parametros especiales *<nombre parametro>, **<nombre parametro>\n# además de parametros obligatorios\"\"\")\n# En este caso el parametro **<nombre parametro> siempre tiene que ir al final\n# El orden de los parametros obligatorios y *<nombre parametro> pueden estar en cualquier posición\n# siempre **<nombre parametro> este al final.\n\n# El sustituir números por letras puede dar problemas a la hora de desencriptar el mensaje si el\n# mensaje original contiene números también. Se ignoro esta posibilidad\n# al únicamente haberse creado esta función como ejemplo\ndef get_encrypted_messages(key: int, *input_messages, **extra_cypher):\n    \"\"\"Cifra mensajes utilizando el cifrado Cesar y retorna el resultado\n    key: clave del cifrado\n    input_messages: mensajes que se quieren codificar\n    extra_cypher: sustituye ciertas letras por números\n    retorna los mensajes cifrados\"\"\"\n    from string import ascii_lowercase\n    encrypted_messages = []\n    for message in input_messages:\n        encrypted_message = \"\"       \n        # Process\n        for c in message:\n            c_encrypted = get_letter_encrypted(ascii_lowercase, key, c.lower())\n            # notar que porque como el alfabeto y el caracter estan en mayúscula\n            # c_encrypted siempre estará en minúscula\n            if ((c_encrypted in extra_cypher.keys())):\n                c_encrypted = str(extra_cypher[c_encrypted])\n            elif (c_encrypted.upper() in extra_cypher.keys()):\n                c_encrypted = str(extra_cypher[c_encrypted.upper()])\n\n            encrypted_message += c_encrypted\n\n        encrypted_messages.append(encrypted_message)\n    return encrypted_messages\n\nencrypted_messages = get_encrypted_messages(0, \"Hola mundo!\", \"Come verduras!\", i=1, o=0)\nprint(encrypted_messages)\nencrypted_messages = get_encrypted_messages(29, \"Hipopotamo\", \"Rinoceronte\", a=4,e=3, i=2, o=1, u=0)\nprint(encrypted_messages)\nencrypted_messages = get_encrypted_messages(a=4,e=3, i=2, o=1, u=0, key=29)\nprint(encrypted_messages)\nprint()\n\n# Ejemplo de función utilizando los parametros especiales *<nombre parametro>, **<nombre parametro>\n# además de parametros opcionales\nprint (\"\"\"Ejemplo de función utilizando los parametros especiales *<nombre parametro>, **<nombre parametro>\nademás de parametros opcionales\"\"\")\n# el parametro **<nombre parametro> tiene que ir siempre al final\n# los parametros opcionales o *<nombre parametro> pueden ocupar cualquier otra posición\ndef get_encrypted_messages_2(*input_messages, key: int = 29, **extra_cypher): #en este caso key tiene valor por defecto\n    \"\"\"Cifra mensajes utilizando el cifrado Cesar y retorna el resultado\n    key: clave del cifrado\n    input_messages: mensajes que se quieren codificar\n    cypher: sustituye ciertas letras por números\n    retorna los mensajes cifrados\"\"\"\n    from string import ascii_lowercase\n    encrypted_messages = []\n    for message in input_messages:\n        encrypted_message = \"\"       \n        # Process\n        for c in message:\n            c_encrypted = get_letter_encrypted(ascii_lowercase, key, c.lower())\n            if (c_encrypted.lower() in extra_cypher.keys()):\n                c_encrypted = str(extra_cypher[c_encrypted])\n            encrypted_message += c_encrypted\n        encrypted_messages.append(encrypted_message)\n    return encrypted_messages\n\nencrypted_messages = get_encrypted_messages_2(\"Hola mundo!\", \"Come verduras!\", i=1, key=0, o=0)\nprint(encrypted_messages)\nencrypted_messages = get_encrypted_messages_2(\"Hipopotamo\", \"Rinoceronte\", a=4,e=3, i=2, o=1, u=0)\nprint(encrypted_messages)\nencrypted_messages = get_encrypted_messages_2(a=4,e=3, i=2, o=1, u=0, key=29)\nprint(encrypted_messages)\nprint()\n\n# Ejemplo de función utilizando los parametros especiales *<nombre parametro>, **<nombre parametro>\n# además de parametros obligatorios y opcionales\nprint(\"\"\"Ejemplo de función utilizando los parametros especiales *<nombre parametro>, **<nombre parametro> \nademás de parametros obligatorios y opcionales\"\"\")\ndef print_info_developer(name, *fav_languages, age = 30, **lang_time):\n    \"\"\"Función que imprime por pantalla el nombre, edad, lenguages de programación\n    favoritos, y el tiempo que se le ha dedicado a cada lenguage.\n    argumentos:\n    name: nombre del desarrollador\n    age: edad del desarrollador\n    fav_languages: lenguajes favoritos del desarrollador\n    lang_time: nombres del lenguaje de programación y el tiempo (en años) que se le ha dedicado\"\"\"\n    print(\"Nombre:\", name)\n    print(\"Edad: \", age)\n    print(\"Lenguages favoritos: \", fav_languages)\n    for lang, time in lang_time.items():\n        print(f\"{time} año/s trabajando con {lang}\")\n\nprint_info_developer(\"Grigori\", \"C\", \"Ruby\", age = 50, C= 10, Ruby=3, R=4, Python= 1)\nprint()\n\nprint(\"Prueba funciones dentro de funciones\")\n# Prueba funciones dentro de funciones:\ndef say_goodbye():\n    def put_exclamation_mark(str_1):\n        return str_1 + \"!\"\n    print(put_exclamation_mark(\"Goodbye\"))\n\nsay_goodbye()\n# Si se puede definir una función dentro de otra\nprint()\n\n# Ejemplo de función ya creada en el lenguaje:\n# La función sum que suma todos los elementos de un iterable\n# siempre y cuando estos sean int, boolean, float o complex\nprint(\"Ejemplo de función ya presente en el lenguaje\")\ntotal = sum(range(1,101))\ntotal = sum([3 + 4j, True])\nprint(total)\nprint()\n\n# Variables locales y globales en python\n# La diferencia entre una variable local y una global radica en el alcance (scope)\n# Una variable local solo esta definida dentro de una función, método o clase\n# mientras que el alcance de una variable global abarca desde la línea en la que se\n# definió hasta el final del programa\n\n\nprint(\"Primer ejemplo uso variables locales y globales\")\nfactor = 30\nprint(f\"Valor: {factor}, id: {id(factor)}\") # Con el identificador del objeto podemos ver\n#si el objeto es el mismo\n\ndef get_double(n):\n    \"\"\"Observación: Dada una variable global de llamada <v>.\n    Si dentro de una función se realiza una asignación a una variable\n    con el mismo nombre y antes no se ha declarado que se hará referencia\n    a la variable global <v> (global <v>). La variable global <v> deja de estar\n    definida en la función y desde ese momento se crea una variable local\n    con el mismo nombre.\"\"\"\n    # Luego si se trata de imprimir factor en este caso incluso antes de la asignación\n    # se producirá un error\n    # print(f\"Valor: {factor}, id: {id(factor)}\") # produce un error por lo mencionado antes\n    \"\"\"Observación: Si dentro de la función no se realiza ninguna asignación a una variable\n    llamada <v>, <v> hará referencia a la variable global <v>\"\"\"    \n    factor = 2 #variable local a la que se le asigna el 2\n    \"\"\"Observación: Si dada una variable global <nombre variable global> se realiza una asignación dentro de una función\n    a una variable con el mismo nombre (<nombre variable global>) antes de declarar 'global <nombre variable global>'\n    ya no se podrá utilizar 'global <nombre variable global>' en el resto de la función a partir de esa asignación.\n    En la función, <nombre variable global> hará referencia a una variable local y no a la variable global del mismo nombre.\"\"\"\n    # global factor # Esta declaración es incorrecta a partir de la asignación de factor\n    print(f\"Valor: {factor}, id: {id(factor)}\") # id distinto al de la variable global\n    print(factor)\n    return factor * n\n\nprint(get_double(10))\nprint(f\"Valor: {factor}, id: {id(factor)}\") # id distinto al del objeto asignado a la variable local en la función\n\n\"\"\"Si se quiere modificar el valor de una variable global dentro de una función\nse debe utilizar la palabra clave 'global'\nsi se hace una asignación a una variable con el mismo nombre de la variable global\nsin utilizar la palabra 'global' python creara una variable local con el mismo nombre que la\nvariable global y no modificará la variable global\"\"\"\n#Ejemplo\nprint(\"Segundo ejemplo uso variables locales y globales\")\nfactor = 30\nprint(f\"Valor: {factor}, id: {id(factor)}\")\n\ndef get_double_2(n):\n    global factor #primero se tiene que hacer la declaración 'global'\n    print(f\"Valor: {factor}, id: {id(factor)}\") #mismo id que variable global\n    factor= 2\n    print(f\"Valor: {factor}, id: {id(factor)}\") #nuevo id por la asignación de nuevo objeto\n    return factor * n\n\n\nget_double_2(10)\nprint(f\"Valor: {factor}, id: {id(factor)}\") #mismo id que en la última asignación (factor = 2)\n\n# DIFICULTAD EXTRA\nprint(\"Ejercicio de dificultad extra\")\ndef special_n_list(str_1, str_2):\n    count = 0\n    for n in range(1, 101):\n        if((n % 3 == 0) and (n % 5 == 0)):\n            print (str_1 + str_2)\n        elif(n % 3 == 0):\n            print (str_1)\n        elif(n % 5 == 0):\n            print (str_2)\n        else:\n            print(n)\n            count += 1\n    return count\n\ncount = special_n_list(\"fizz\", \"buzz\")\nprint(\"El número de veces que no se han imprimido numeros es: \", count)\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/mariovelascodev.py",
    "content": "#Función sin parámetros y sin retorno\ndef funcion_sin_parametros():\n    print(\"Función sin parámetros\")\n\nfuncion_sin_parametros()\n\n#Función con parámetros y sin retorno\ndef funcion_con_parametros_sin_retorno(param1, param2):\n    print(f\"El primer parámetro es: {param1}, el segundo parámetro es: {param2}\")\n\nfuncion_con_parametros_sin_retorno(\"Hola\", 4)\n\n#Función con parámetros y retorno\ndef funcion_con_parametros_y_retorno(a, b):\n    return a - b\n\nprint(funcion_con_parametros_y_retorno(5, 3))\n\n#Función con parámetros por defecto y retorno de varios parámetros\ndef funcion_con_parametro_por_defecto(nombre, apellido, alias = \"Anonimo\"):\n    return nombre, apellido, alias\n\nprint(funcion_con_parametro_por_defecto(\"Mario\", \"Velasco\"))\nprint(funcion_con_parametro_por_defecto(\"Mario\", \"Velasco\", \"mariovelascodev\"))\n\n#Función dentro de función\ndef funcion_1():\n    def funcion_2(arg):\n        return arg\n    print(f\"Hola\", funcion_2(\"mundo\"))\n\nfuncion_1()\n\n#Funciones creadas en el lenguaje\nprint(f\"len() que nos calcula la longitud del string: Hola mundo tiene una longitud de -> {len('Hola mundo')}\")\nprint(f\"pow() nos eleva el primer número a la potencia del segundo: 4**2 = {pow(4,2)}\")\n\n#Variable LOCAL y GLOBAL\nvariable_global = \"Contenido de la variable global\"\n\ndef funcion_variable_local():\n    variable_local = \"Contenido de la variable local\"\n    print(variable_local)\n\nprint(variable_global)\nfuncion_variable_local()\nvariable_local = 5 # el contenido de la variable no cambia dentro de la función ya que tiene ambito local\n\nprint(variable_local)\nfuncion_variable_local()\n\n#EXTRA\ndef print_number(arg1, arg2):\n    parametro_1 = str(arg1)\n    parametro_2 = str(arg2)\n    contador = 0\n    for i in range(1,101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(f\"{parametro_1} {parametro_2}\")\n        elif i % 3 == 0:\n            print(parametro_1)\n        elif i % 5 == 0:\n            print(parametro_2)\n        else:\n            print(i)\n            contador+=1\n        \n    return f\"Número de veces que se ha impreso el número en lugar de textos: {contador} veces\"\n\nprint(print_number(\"Hola\", \"Mundo\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/maxiRica.py",
    "content": "\"\"\"\nFUNCIONES BÁSICAS. Se declaran con el termino \"def\"\n\nSon las funciones creadas por el usuario. Hay del tipo:\n1. Sin parámetros ni retorno\n2. Con parámetros sin retorno\n3. Sin parámetros con retorno\n4. Con parámetros y con retorno\n5. Recursiva\n6. \n\"\"\"\n\n# 1. Funciones sin parámetros ni retorno\ndef Hola():\n    print(\"hola, estoy programando con Python\")\n\nprint(\" \")\n\n# 2. Funciones con parámetros sin retorno\ndef saludo(name):\n    print(name)\n\n# 3. Funciones sin parámetros con retorno\ndef retorno():\n    return print(\"devolvemos un valor\")\n\n# 4. Funciones con parámetros y retorno\ndef ret_param(valor,porcentaje):\n    calculo=valor*porcentaje/100\n    return calculo\n\n# 5. Función recursiva\ndef recursiva(valor):\n    if valor == 1:\n        return 1\n    else:\n        return valor * recursiva(valor - 1)\n\n\n        \n\n# ejercicios aplicando el código escrito\n\nprint(\"# 1. Funciones sin parámetros ni retorno\") #1\nprint(\"def Hola():\\nprint(\\\"hola, estoy programando con Python\\\")\\n\")\nHola()\nprint(\"\")\n\nmaxi =\"maxi\" #2\nprint(\"# 2. Funciones con parámetros sin retorno\")\nprint(\"def saludo(name):\\nprint(name)\\n\")\n\nsaludo(maxi)\nprint(\" \")\n\nprint(\"# 3. Funciones sin parámetros con retorno\") #3\nprint(\"def retorno():\\nreturn print(\\\"devolvemos un valor\\\")\\n\")\nretorno() \nprint(\" \")\n\nprint(\"# 4. Funciones con parámetros y retorno\") #4\nprint(\"def ret_param(valor,porcentaje):\\ncalculo=valor*porcentaje/100\\nreturn calculo\\n\")\nprint(ret_param(1000,25)) \nprint(\" \")\n\nprint(\"# 5. Función recursiva\\n\")\nprint(\"def recursiva(valor):\\n  if valor == 1:\\n      return 1\\n  else:\\n      return valor * recursiva(valor - 1)\\n\")\nprint(recursiva(5))\nprint(\" \")\n\n\"\"\"\nVamos a trabajar con variables LOCALES y GLOBALES\n\nLas variables GLOBALES se ejecutaran en todo el código, mientras que las LOCALES\nsolo se ejecutan dentro de las funciones.\n\nEn la gestión de recursos, las variables locales es mucho más efectivo, dado que solo\nocupan con caráter temporal recursos del sistema. Las variables globales al perdurar\nmantienen el uso de los recursos.\n\nEn un programa bien realizado, se ha de usar el mínimo de variables globales posible.\n\"\"\"\n\nsaludo=\"Hola a tod@s!!\" #variable global\n\ndef saludin(valor): #función donde generamos una variable local tipo string\n    cortes=valor\n    hola=\"holita a tod@s! \" + cortes\n    return hola\n\n\nprint(saludin(saludo))\n\n\n\"\"\"\nDificultad extra:\n\n* Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n* La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n* Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n* Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n* Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n* La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\"\"\"\n\ndef funcion(string1,string2):\n    for i in range(1,101):\n        if i%3==0 and i%5==0:\n            print(f\"i({i}): {string1} {string2}\")\n        elif i%3==0:\n            print(f\"i({i}): {string1}\")\n        elif i%5==0:\n            print(f\"i({i}): {string2}\")\n    return\n        \n    \nfuncion(\"uno\", \"dos\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/mensius87.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue unas convenciones que debes de respetar para que el código se entienda.\n */\n\"\"\"\n\nkm = 5\n\n\n# Función sin parámetros ni retorno\ndef km_actual():\n    print(f\"Llevas {km}km.\\n\")\n\n\n# Función con un parámetro sin retorno\ndef contador_letras(palabra):\n    print(f\"La palabra {palabra} tiene {len(palabra)} letras.\\n\")\n\n\n# Función con dos parámetros sin retorno\ndef suma(num1, num2):\n    print(f\"{num1} + {num2} = {num1+num2}\\n\")\n\n\n# Función con dos parámetros con retorno\ndef suma_retorno(num1, num2):\n    return num1 + num2\n\n\n# Esta es la función externa con retorno\ndef externa():\n\n    def interna():\n        # Esta es la función interna con retorno\n        return \"Hola desde la función anidada!\"\n\n    # Llamada a la función interna dentro de la función externa\n    resultado = interna()\n    return resultado\n\n\n# Dificultad extra\ndef dificultad_extra(tex_1, tex_2):\n\n    contador = 0\n\n    for num in range(1, 101):\n\n        if num % 3 == 0 and num %5 == 0:\n            print(tex_1+tex_2)\n\n        elif num % 3 == 0:\n            print(tex_1)\n\n        elif num % 5 == 0:\n            print(tex_2)\n\n        else:\n            contador += 1\n            print(num)\n\n    resultado = contador\n\n    print(f\"\\nSe ha impreso el número {resultado} veces en lugar de los textos\\n\")\n\n    return resultado\n\n\n\ndificultad_extra(\"Hola\", \"Mundo\")\n\nkm_actual()\n\ncontador_letras(\"hola\")\n\nsuma(1, 3)\n\nvar_suma_retorno = suma_retorno(1, 4)\n\nprint(var_suma_retorno)\nprint()\n\nprint(externa())\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/mhayhem.py",
    "content": "# @author: Mhayhem\n\n# - Crea ejemplos de funciones básicas que representen las diferentes\n#   posibilidades del lenguaje:\n#   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n\ndef withoiut_params():\n    print(\"Esta función no tiene parámetros ni retorno.\")\n\ndef whith_one_param(param):\n    print(f\"Esta es una función con {param}.\")\n\ndef whith_two_params(param1, param2):\n    print(f\"Esta función tiene {param2} {param1}.\")\n\ndef with_return(param):\n    return f\"Esta función tiene {param}.\"\n\"\"\"\nusando como parametro *args y **kwargs podremor flexibilizar el numwero de parámetros\nque recibe nuestra función\"\"\"\n\ndef with_multiple_params_without_name(*args): # nos permite pasarle a la funcion un numero de parámetros sin nombre, *args es una tupla\n    print(f\"Esta funcion puede recibir {len(args)} argumrntos posicionales.\")\n    print(f\"Los parámetros son: {args}.\")\n\ndef with_multiple_params_with_name(**kwargs): # también nos permite pasarle un número variable de parámetros pero en este caso con nombre, **kwargs es un diccionario\n    print(f\"Esta funcion puede recibir {len(kwargs)} argumentos con nombre.\")\n    print(f\"Los parámetros son: {kwargs}.\")\n\ndef with_multiple_returns():\n    return \"Este es el primer retorno.\", \"Y este es el segundo retorno.\"\n\n# - Comprueba si puedes crear funciones dentro de funciones.\n\ndef function_inside_function():\n    print(\"Esta función contiene otra dentro de su bloque de código.\")\n    \n    def inner_function():\n        print(\"Esta es la función que esta dentro de la función principal.\")\n    inner_function()\ndef function_with_lambda(param): # también puede contener una función lambda\n    func_lambda = lambda param: param ** 2\n    return f\"Función lambda que eleva al cuadrado un número: {func_lambda(param)}\"\n\n# - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n\n# de hecho ya hemos usado una función propia de python como es print() pero pondre otro ejemplo\npython_func = f\"Imprimimos el mayor número de una lista usando la funcion propia de python 'max': {max([10,20,30,40])}.\"\n\n# - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n\nglobal_var = \"Esta es una variable global\"\ndef local_and_global_var():\n    local_var = \"Esta es una variable local\"\n    print(f\"Variable local: {local_var} solo es accesible dentor de la función.\")\n    print(f\"Variable global: {global_var} es accesible desde cualquier parte del código.\")\n\n\n# - Debes hacer print por consola del resultado de todos los ejemplos.\n#   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\nwithoiut_params()\nwhith_one_param(\"un parámetro\")\nwhith_two_params(\"parámetros\", 2)\nprint(with_return(\"Un retorno\"))\nwith_multiple_params_without_name(\"coche\", \"avión\", \"barco\")\nwith_multiple_params_with_name(name=\"Dany\", age=42, city=\"Valladolid\")\nprint(with_multiple_returns())\nfunction_inside_function()\nprint(function_with_lambda(9))\nprint(python_func)\nlocal_and_global_var()\n#\n# DIFICULTAD EXTRA (opcional):\n# Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n# - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n#   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n#   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n#   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n#   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\ndef fizzbuzz(text_1, text_2):\n    count = 0\n    for n in range(1, 101):\n        if n % 3 == 0 and n % 5 == 0:\n            print(f\"{text_1}{text_2}\")\n        elif n % 3 == 0:\n            print(text_1)            \n        elif n % 5 == 0:\n            print(text_2)\n        else:\n            print(n)\n    return count\n\nprint(fizzbuzz(\"Fizz\", \"Buzz\"))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/miguel2rar.py",
    "content": "\"\"\" * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\"\"\"\n\ndef funcion_sin_retorno_ni_parametros():\n    print(\"esta es la funcion\")\n\nfuncion_sin_retorno_ni_parametros()\n\ndef con_uno_o_varios_parametros_y_retorno(altura, anchura):\n    area = altura * anchura\n    return area\n\nprint(con_uno_o_varios_parametros_y_retorno(23, 56))\n\ndef con_numero_random_de_parametros(*numeros):\n    if len(numeros) >= 1:\n        return \"Esta funcion no esta vacia\"\n    if len(numeros) < 1:\n        return \"Esta funcion está vacia\"\n\nprint(con_numero_random_de_parametros(0, 4, 5, 7, 8))\n\n# Ejemplo de funciones dentro de funciones\n\ndef funcion_en_funcion (altura):\n    def hacer_cuadrado():\n        trend = altura**2\n        return trend\n    treta = hacer_cuadrado()\n    return treta\n\nprint (\"Esto es una funcion dentro de otra funcion: \", funcion_en_funcion(45))\n\n# Esta es una funcion del sistema\n\nfrom math import sqrt\n\nprint(sqrt(25))\n\n# Variable local y global\n\nvariable_global = \"esto es una varible global\"\n\nprint (variable_global)\n\ndef ejemplo():\n    variable_local = \"esto es una variable local\"\n    print (variable_local)\n\nejemplo()\n\n# DIFICULTAD EXTRA\n\n\"\"\"Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\"\"\"\n\ndef polanco(wave, thunder):\n    uno = len(wave)\n    dos = len(thunder)\n\n    for i in range (0, 101):\n        print(i)\n        if i == 100:\n            numero = uno * dos\n            if numero % 3 == 0 and numero % 5 == 0:\n                return wave, thunder\n            elif numero % 3 == 0:\n                return wave\n            elif numero % 5 == 0:\n                return thunder\n\nprint(polanco(\"estadio\", \"dia\"))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/miguelex.py",
    "content": "# Funcion simple\n\ndef saludar():\n    print(\"Hola, soy una función simple\")\n    \nsaludar()\n\n# Funcion con return\ndef suma(a,b):\n    return a+b\n\nprint(suma(5,6))\n\n# Funcion con parametro\ndef saludar(nombre):\n    print(f\"Hala, un {nombre} ha entrado en la sala\")\n    \nsaludar(\"Miguelex\")\n\n# Funcion con parametros por defecto\ndef saludar(nombre=\"Miguelex\"):\n    print(f\"Hala, un {nombre} ha entrado en la sala\")\n    \nsaludar()\nsaludar(\"Juan\")\n\n# Funcion que devuelve varios valores\ndef varios():\n    return \"Pepi\", \"Lucy\", \"Boom\"\nx, y, z = varios()\nprint(x)\nprint(y)\nprint(z)\n\n# Funcion con numero variable de parametros\ndef varios(*args):\n    for arg in args:\n        print(arg)\nvarios(2,4,6,8,10)\n\n# Funcion lambda\nsuma = lambda a,b: a+b\nprint(suma(5,6))\n\n# Funcion con funcion interior\ndef funcion_exterior():\n    def funcion_interior():\n        print(\"Soy una funcion interior\")\n    print(\"Soy una funcion exterior\")\n    funcion_interior()\n    \nfuncion_exterior()\n\n# Ejemplos de funciones del sistema\nprint(len(\"Miguelex\"))\nprint(str(5))\n\n# Ejercicio Extra\n\ndef extra(param1, param2) -> int:\n    count = 0\n    for number in range(1, 101):\n        if number % 15 == 0:\n            print(param1 + param2)\n        elif number % 3 == 0:\n            print(param1)\n        elif number % 5 == 0:\n            print(param2)\n        else:\n            print(number)\n        count += 1\n    return count\n\nextra(\"Fizz\", \"Buzz\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/mikelm2020.py",
    "content": "# Función sin parámetros ni retorno\ndef name():\n    print(\"Mi nombre es: Miguel Angel López Monroy\")\n\n\n# Función con un parámetro\ndef square_area(side):\n    return side * side\n\n\n# Función con varios parametros\ndef polygon_area(side, n, aphotem):\n    return ((side * n) * aphotem) / 2\n\n\n# Función con Función\ndef polygon_area_2(aphotem, side, n):\n\n    def polygon_perimeter(side, n):\n        return side * n\n\n    return polygon_perimeter(side, n) * aphotem\n\n\n# Funciones ya credaas en el lenguaje\ndef python_functions():\n    import math\n\n    print(f\"El residuo de la divisón 10 / 2 es: {math.remainder(10,2)}\")\n    print(f\"La raiz cuadrada de 25 es: {math.sqrt(25)}\")\n\n\n# Variables globales y locales\nglobal_variable = 9\n\n\ndef variables():\n    local_variable = 2\n    print(\"La variable global tiene un valor de: {global_variable}\")\n    print(f\"La variable local tiene un valor de: {local_variable}\")\n    print(f\"La suma de las variables es: {global_variable + local_variable}\")\n\n\n# Extra\ndef extra_numbers(first_string: str, second_string: str) -> int:\n    count_of_numbers = 0\n    for number in range(1, 101):\n\n        if number % 3 == 0 and number % 5 == 0:\n            print(f\"{first_string} {second_string}\")\n        elif number % 3 == 0:\n            print(first_string)\n        elif number % 5 == 0:\n            print(second_string)\n        else:\n            print(number)\n            count_of_numbers += 1\n\n    return count_of_numbers\n\n\nif __name__ == \"__main__\":\n    name()\n    print(f\"El área de un cuadrado de 5 unidades por lado es: {square_area(5)}\")\n    print(\n        f\"El área de un poligono con 7 lados, de 5 unidades por lado y un apotema de 1.5 unidades es: {polygon_area(5, 7, 1.5)}\"\n    )\n    print(\n        f\"El área de un poligono con 9 lados, de 3 unidades por lado y un apotema de 3.5 unidades es: {polygon_area_2(3, 9, 3.5)}\"\n    )\n    python_functions()\n    variables()\n    numbers = extra_numbers(\"múltiplo de 3\", \"múltiplo de 5\")\n    print(f\"El número de veces que se ha impreso un número es: {numbers} veces\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/minn09.py",
    "content": "# Funciones sin parametros, con parametros y varios parametros\ndef funcion_con_retorno():\n    return 1\n\n\ndef funcion_sin_retorno():\n    print(\"No tengo retorno\")\n\n\ndef funcion_varios_retornos():\n    return \"nombre\", \"apellido\", \"edad\"\n\n\ndef funcion_con_parametro(numero):\n    return numero\n\n\ndef funcion_sin_parametro():\n    return 1\n\n\ndef funcion_varios_parametros(numero, letra, vocal):\n    return f\"{numero} {letra} {vocal}\"\n\n\n# Funciones anonimas\ncuadrado = lambda x: x**2\n\n\n# Variable global\nglobal variable_global\n\n\ndef imprimir_multiplos(palabra_multiplo_3: str, palabra_multiplo_5: str) -> int:\n    cantidad_multiplo_3 = 0\n    cantidad_multiplo_5 = 0\n\n    for i in range(1, 101):\n        if i % 3 == 0 and i % 5 == 0:\n            palabra = f\"{palabra_multiplo_3}, {palabra_multiplo_5}\"\n            cantidad_multiplo_3 += 1\n            cantidad_multiplo_5 += 1\n        elif i % 3 == 0:\n            palabra = palabra_multiplo_3\n            cantidad_multiplo_3 += 1\n        elif i % 5 == 0:\n            palabra = palabra_multiplo_5\n            cantidad_multiplo_5 += 1\n        else:\n            palabra = i\n    resultado = f\"La cantidad de veces que se ha impreso: (multiplo de tres, multiplo de 5): {cantidad_multiplo_3, cantidad_multiplo_5}\"\n    return resultado\n\n\nprint(\"====================================================\")\nprint(f\"Funcion con retorno: {funcion_con_retorno}\")\nprint(f\"Funcion sin retorno: {funcion_sin_retorno}\")\nprint(f\"Funcion con parametro: {funcion_con_parametro(7)}\")\nprint(f\"Funcion sin paramtro: {funcion_sin_parametro}\")\nprint(f\"Funcion con varios parametros: {funcion_varios_parametros(2, 'F', 'A')}\")\nprint(f\"Funcion que retorna varios elementos: {funcion_varios_retornos()}\")\nprint(f\"Funcion anonima: {cuadrado(3)}\")\n\nprint(\"------------------------------------------\")\nprint(imprimir_multiplos(\"tres\", \"cinco\"))\nprint(\"------------------------------------------\")\n\nprint(\"====================================================\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/mmacalli.py",
    "content": "\"\"\"\nfunciones definidas por el usuario\n\"\"\"\n#simple\n\ndef greet():\n    print(\"hola, Python!\")\n    \ngreet()\n\n#con retorno\n\ndef return_greet():\n    return \"Hola, Python\"\nprint(return_greet())\n\n#con argumento\n\ndef arg_greet(name):\n    print(f\"Hola, {name}!\")\n    \narg_greet(\"maca\")\n\n#con argumento predeterminado\n\ndef default_arg_greet(name=\"rucucu\"):\n    print(f\"Hola, {name}!\")\n    \ndefault_arg_greet(\"love\")\ndefault_arg_greet()\n\n#con argumento y retorno\n\ndef return_arg_greet(greet, name):\n    return f\"{greet}, {name}!\"\n    \nprint(return_arg_greet(\"bonacera\",\"pitufo\"))\n    \n# con retorno de varios valores\n\ndef multiple_return_greet():\n    return \"hola\", \"Python\"\ngreet, name = multiple_return_greet()\nprint(greet)\nprint(name)\n\ndef variable_arg_greet (*names):\n    for name in names:\n        print(f\"Hola,{name}:\")\nvariable_arg_greet(\"python\",\"maca\",\"loquito\",\"barrio\")\n\n#con un numero variable de argumentos con palabra clave\n\ndef variable_key_arg_greet(**names):\n    for key, value in names.items():\n        print(f\"{value} ({key})!\")\n        \nvariable_key_arg_greet (\n    lenguaje =\"python\",\n    name=\"maca\",\n    alias =\"loquito\",\n    de_donde =\"barrio\",\n    age= 49 \n)\n\"\"\"\nfunciones dentro de Funciones\n\"\"\"\ndef outer_funcion():\n    def inner_funcion():\n        print(\"funcion interna: Hola, Python !\")\n    inner_funcion()\n\nouter_funcion()\n\"\"\" \nfunciones del lenguaje (built-in)\n\"\"\"\n\nprint (len(\"martincho\"))\nprint(type(\"hola\"))\nprint (\"martincho\".upper())\n\n\"\"\"\nVariables locales y globales\n\"\"\"\nglobal_var = \"Python\"\nprint(global_var)\n\ndef hello_python():\n    local_var = \"hola\"\n    print(f\"{local_var}, {global_var}!\")\n\nprint(global_var)\n\nhello_python()\n\n\n\"\"\"\nextra\n\"\"\"\ndef print_numbers(text_1, text_2) -> int:\n    count = 0\n    for number in range (1, 101):\n        if number % 3 == 0 and number % 5 == 0:\n            print(text_1 + text_2)\n        elif number % 3 == 0:\n            print(text_1)\n        elif number % 5 == 0:\n            print(text_2)\n        else:\n            print(number)\n            count += 1\n    return count\n\nprint(print_numbers(\"Texto 1 \", \"Texto 2\"))\n        \n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/monicavaquerano.py",
    "content": "# 02 FUNCIONES Y ALCANCE\n# Mónica Vaquerano\n# https://monicavaquerano.dev\n\n\"\"\"\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes posibilidades del lenguaje:\n\"\"\"\n\n\n# Sin parámetros ni retorno\ndef cuentaRegresiva():\n    for i in range(10, -1, -1):\n        if i == 0:\n            print(\"Boom!\")\n        else:\n            print(i, end=\", \")\n\n\n# Con parámetro, no retorno\ndef greeting(name: str):\n    print(f\"¡Hola, {name}!\")\n\n\n# Con uno o más parámetros y con retorno\ndef suma(a: int, b: int) -> int:\n    return a + b\n\n\n# Una lista como argumento\ndef printSortedList(list: list) -> list:\n    list.sort()\n    print(list)\n\n\n# Parámetros arbitrarios, *args\ndef ultimaPersona(*persona):\n    print(\"La última persona que vino fue \" + persona[-1])\n\n\n# Parámetros con keywords\ndef vocales(vocal1, vocal2, vocal3, vocal4, vocal5):\n    print(\n        f\"Las vocales cerradas son {vocal4} y {vocal5}, las abiertas son {vocal3}, {vocal2} & {vocal1}.\"\n    )\n\n\n# Parámetros arbitrarios con keyword\ndef suApellido(**persona):\n    print(\"Su apellido es \" + persona[\"apellido\"])\n\n\n# Recursion\ndef recurrente(num: int) -> int:\n    if num > 0:\n        resultado = num + recurrente(num - 1)\n        print(resultado, end=\", \")\n    else:\n        resultado = 0\n    return resultado\n\n\n\"\"\"\n* - Comprueba si puedes crear funciones dentro de funciones.\n\"\"\"\n\n\ndef funcionPrincipal(string: str):\n    def funcionSecundaria(string: string):\n        for i in range(len(string)):\n            if i % 2 == 0:\n                print(f\"\\033[0;33m{string[i]}\\033[0m\", end=\"\")\n            else:\n                print(f\"\\033[0;31m{string[i]}\\033[0m\", end=\"\")\n        print()\n\n    return funcionSecundaria(string)\n\n\n\"\"\"\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n\"\"\"\n\nprint(\"\\nAlgunas funciones ya creadas en Python (Built-in Functions):\")\n\nlista = [5, 7, 4, 6, 1]\n\n# Abs\nprint(f\"abs(): el absoluto de -20 es: {abs(-20)}\")\n# Len\nprint(f\"len(): la longitud de {lista} es de: {len(lista)}\")\n# Max\nprint(f\"max(): el máximo en {lista} es: {max(lista)}\")\n# Min\nprint(f\"min(): el mínimo en {lista} es: {min(lista)}\")\n# Pow\nprint(f\"pow(): dos elevado al cuadrado es {pow(2,2)}\")\n# Print\nprint(f\"print(): imprime los resultados en la consola. {True}, {None}, {lista}, etc.\")\n# Sorted\nprint(f\"sorted(): la lista ({lista}) ordenada se ve así {sorted(lista)} \")\n# Sum\nprint(f\"sum(): la suma de todos los números en {lista} es igual a {sum(lista)}\")\n\n\n\"\"\"\n* - Pon a prueba el concepto de variable LOCAL y GLOBAL. \n\"\"\"\n\nprint(\"\\nVariable local y global:\")\n\n# Variable Global\nnombre = \"Juan\"\n\n\ndef devolverNombre():\n    # Variable Local\n    nombre = \"Carlos\"\n    return nombre\n\n\nprint(\n    f\"Yo regreso la variable global (nombre = {nombre})\\nYo regreso la variable local dentro de la funcion (nombre = {devolverNombre()}).\"\n)\n\n\"\"\"\n* - Debes hacer print por consola del resultado de todos los ejemplos.\n*   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n\"\"\"\n\nprint(\"\\nResultados de todos los ejemplos de funciones:\")\ncuentaRegresiva()\ngreeting(\"Monica\")\nprint(f\"1 + 2 = {suma(1, 2)}\")\nprintSortedList([9, 0, 8, 1, 7, 2, 6, 3, 5, 4])\nultimaPersona(\"Emil\", \"Tobias\", \"Linus\")\nvocales(vocal2=\"e\", vocal1=\"a\", vocal3=\"i\", vocal5=\"u\", vocal4=\"o\")\nsuApellido(nombre=\"Jane\", apellido=\"Doe\")\nprint(\"Función con recusión: \")\nrecurrente(3)\nfuncionPrincipal(\"Soy una string de prueba\")\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n\"\"\"\n\n\ndef miFuncion(string1: str, string2: str) -> int:\n    counter = 0\n    for i in range(1, 100):\n        if i % 3 == 0 and i % 5 == 0:\n            print(string1 + \" \" + string2, end=\", \")\n        elif i % 5 == 0:\n            print(string2, end=\", \")\n        elif i % 3 == 0:\n            print(string1, end=\", \")\n        else:\n            print(f\"\\033[0;31m{i}\\033[0m\", end=\", \")\n            counter += 1\n    print()\n    return counter\n\n\nprint(\"\\nDIFICULTAD EXTRA (opcional):\")\nx = miFuncion(\"hakuna\", \"matata\")\nprint(f\"\\nNúmero de veces que se ha impreso el número en lugar de los textos:\\n> {x}\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/mordevspt.py",
    "content": "\"\"\"\nCrea ejemplos de funciones básicas que representen las diferentes posibilidades del lenguaje:\n- Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n\"\"\"\n# Función sin parámetros ni retorno\nprint(\"Función sin parámetros ni retorno \\n\")\ndef basicFuntion ():\n    print(\"Esto es una función básica \\n\")\n    \nbasicFuntion()\n\n# Función con uno o más parámetros\nprint(\"Función con uno parámetro \\n\")\ndef saludar(nombre):\n    print(f\"Hola {nombre} \\n\")\n\nsaludar(\"Pepe\")\n\nprint(\"Función con dos parámetros \\n\")\ndef saludarEdad(nombre,edad):\n    print(f\"Hola {nombre}, tienes {edad} \\n\")\n\nsaludarEdad(\"Pepe\",34)\n\n# Función con retorno\nprint(\"Función con retorno \\n\")\ndef comporbarEdad(edad):\n    if edad in range(0,18):\n        return f\"Eres menor de edad con {edad} años \\n\"\n    else:\n        return f\"Eres mayor de edad con {edad} años \\n\"\n\nprint(comporbarEdad(13))\nprint(comporbarEdad(21))\n\n\n# Función con un parámetro por defecto\nprint(\"Función con un parámetro por defecto \\n\")\ndef saludarDefault(nombre=\"pepito\"):\n    print(f\"Hola {nombre} \\n\")\n\nsaludarDefault()\n\n# Función con un parámetro por defecto y otro no\nprint(\"Función con un parámetro por defecto y otro no \\n\")\ndef saludarDefaultTwo(nombre=\"pepito\",edad=int):\n    print(f\"Hola {nombre}, tienes {edad} \\n\")\n\nsaludarDefaultTwo(edad=34)\n\n\n# Función con retorno de más de un parámetro\nprint(\"Función con retorno de más de un parámetro \\n\")\ndef saludoYEdaCompuesto():\n    return \"Hola\",\"Pepito\"\n\nsaludo, nombre = saludoYEdaCompuesto()\nprint(f\"{saludo}, {nombre}!\\n\")\n\n\n\"\"\" \n- Comprueba si puedes crear funciones dentro de funciones.\n- Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n- Pon a prueba el concepto de variable LOCAL y GLOBAL.\n- Debes hacer print por consola del resultado de todos los ejemplos.\n(y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n\"\"\" \n# Función dentro de otra función\nprint(\"Función dentro de otra función \\n\")\nPI = 3.14 # Constante del valor Pi\nshapetype = \"circle\" # Tipo de figura\narea=1 # variable fuera de la función\n\ndef AreaCalc(shape,medida):\n    # variable dentro de la función que iniciamos a 0\n    area = 0\n    print(f\"Valor de área dentro de la función: {area} \\n\")\n    # Función dentro de otra función\n    def calcularAreaCircunferencia(medida):\n            area = PI * medida ** 2\n            print(f\"El varlor del área de la circunferencia es: {area}\")\n    # Comprobamos el tipo en y enviamos a la función interna que corresponda\n    if shape == \"circle\":\n        calcularAreaCircunferencia(medida)\n\nAreaCalc(shapetype,25)\nprint(f\"Valor de área fuera de la función: {area} \\n\")\n\n# Funciones que ya vienen con el sistema\nprint(f\"Función max(1,2,3,4,5): {max(1,2,3,4,5)}\")\nprint(f\"Función min(1,2,3,4,5): {min(1,2,3,4,5)}\")\nprint(f\"Función len('Hola Mundo!'): {len(\"Hola Mundo!\")}\")\n\n# Función con una variable de argumentos\nprint(\"Función con una variable de argumentos \\n\")\ndef mesesAno(*meses):\n    # Imprimimos tantas veces como meses nos han pasado\n    for mes in meses:\n        print(f\"Mes: {mes}\")\n    \nmesesAno(\"Enero\",\"Febrero\",\"Marzo\",\"Abril\",\"Mayo\",\"Junio\",\"Julio\",\"Agosto\",\"Septiembre\",\"Octubre\",\"Noviembre\",\"Diciembre\")\n    \n# Función con una variable de argumentos con palabra clave\nprint(\"Función con una variable de argumentos con palabra clave \\n\")\n\ndef mesesAnoClave(**valores):\n    # Imprimimos tantas veces como valores se nos han pasado\n    for clave, valor in valores.items():\n        print(f\"- El mes {clave} tiene {valor} días\")\n\nmesesAnoClave(Enero=31,\n         Febrero=28,\n         Marzo=31,\n         Abril=30,\n         Mayo=31,\n         Junio=30,\n         Julio=31,\n         Agosto=31,\n         Septiembre=30,\n         Octubre=31,\n         Noviembre=30,\n         Diciembre=31)\n\n\"\"\" \n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n \"\"\"\n\nprint(\"\\nEJERCICIO EXTRA\\n\")\n \ndef contrarCadenas(primerTexto,segundoTexto):\n    # Contador que usaremos para el return\n    contador = 0\n    # Usaremos un bucle for\n    for i in range(1,101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(f\"{i} - {primerTexto+segundoTexto}\")\n        elif i % 3 == 0:\n            print(f\"{i} - {primerTexto}\")\n        elif i % 5 == 0:\n            print(f\"{i} - {segundoTexto}\")\n        else:\n            print(i)\n            contador += 1\n    # Retornamos el resultado del contador\n    return f\"Números que no son múltiplos de 3 ni de 5: {contador}\"\n \nprint(contrarCadenas(\"Este es un ejemplo de primer texto\",\"Este es el segundo texto para calcular \\n\"))\n\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/mouredev.py",
    "content": "\"\"\"\nFunciones definidas por el usuario\n\"\"\"\n\n# Simple\n\n\ndef greet():\n    print(\"Hola, Python!\")\n\n\ngreet()\n\n# Con retorno\n\n\ndef return_greet():\n    return \"Hola, Python!\"\n\n\nprint(return_greet())\n\n# Con un argumento\n\n\ndef arg_greet(name):\n    print(f\"Hola, {name}!\")\n\n\narg_greet(\"Brais\")\n\n# Con argumentos\n\n\ndef args_greet(greet, name):\n    print(f\"{greet}, {name}!\")\n\n\nargs_greet(\"Hi\", \"Brais\")\nargs_greet(name=\"Brais\", greet=\"Hi\")\n\n# Con un argumento predeterminado\n\n\ndef default_arg_greet(name=\"Python\"):\n    print(f\"Hola, {name}!\")\n\n\ndefault_arg_greet(\"Brais\")\ndefault_arg_greet()\n\n# Con argumentos y return\n\n\ndef return_args_greet(greet, name):\n    return f\"{greet}, {name}!\"\n\n\nprint(return_args_greet(\"Hi\", \"Brais\"))\n\n# Con retorno de varios valores\n\n\ndef multiple_return_greet():\n    return \"Hola\", \"Python\"\n\n\ngreet, name = multiple_return_greet()\nprint(greet)\nprint(name)\n\n# Con un número variable de argumentos\n\n\ndef variable_arg_greet(*names):\n    for name in names:\n        print(f\"Hola, {name}!\")\n\n\nvariable_arg_greet(\"Python\", \"Brais\", \"MoureDev\", \"comunidad\")\n\n# Con un número variable de argumentos con palabra clave\n\n\ndef variable_key_arg_greet(**names):\n    for key, value in names.items():\n        print(f\"{value} ({key})!\")\n\n\nvariable_key_arg_greet(\n    language=\"Python\",\n    name=\"Brais\",\n    alias=\"MoureDev\",\n    age=36\n)\n\n\"\"\"\nFunciones dentro de funciones\n\"\"\"\n\n\ndef outer_function():\n    def inner_function():\n        print(\"Función interna: Hola, Python !\")\n    inner_function()\n\n\nouter_function()\n\n\"\"\"\nFunciones del lenguaje (built-in)\n\"\"\"\n\nprint(len(\"MoureDev\"))\nprint(type(36))\nprint(\"MoureDev\".upper())\n\n\"\"\"\nVariables locales y globales\n\"\"\"\n\nglobal_var = \"Python\"\n\n\ndef hello_python():\n    local_var = \"Hola\"\n    print(f\"{local_var}, {global_var}!\")\n\n\nprint(global_var)\n# print(local_var) No se puede acceder desde fuera de la función\n\nhello_python()\n\n\"\"\"\nExtra\n\"\"\"\n\n\ndef print_numbers(text_1, text_2) -> int:\n    count = 0\n    for number in range(1, 101):\n        if number % 3 == 0 and number % 5 == 0:\n            print(text_1 + text_2)\n        elif number % 3 == 0:\n            print(text_1)\n        elif number % 5 == 0:\n            print(text_2)\n        else:\n            print(number)\n            count += 1\n    return count\n\n\nprint(print_numbers(\"Fizz\", \"Buzz\"))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/mplatab.py",
    "content": "\"\"\"\nfuncion es un bloque de codigo que sirve para reutilizar el codigo\n\"\"\"\n\n# Simple\ndef greeting():\n    print(\"Hola, Python!\")\n\ngreeting()\n\n# Simple con parametro\ndef greeting(name):\n    print(f\"Hola, {name}!\")\n\ngreeting(\"Marcos\")\n\n\n# Con retorno sin parametro\ndef greeting():\n    return \"Hello, World\" \n\ngreet = greeting()\nprint(greet)\n\n# Con parametro, valor por defecto\ndef default_arg_greet(name = \"Python\"):\n    print(f\"Hola, {name}!\")\n\ndefault_arg_greet(\"Marcos\")\ndefault_arg_greet()\n\n# Con parametros y return\ndef arg_suma(a, b):\n    return a + b \n\nresult = arg_suma(5, 5)\nprint(result)\n\n# Con retorno de varios valores\ndef multiple_return():\n    return \"Hola\", \"Marcos\"\n\ngreet, name = multiple_return()\nprint(greet)\nprint(name)\n\n# Con un numero variables de argumentos\ndef variable_arg_greet(*name):\n    for name in name:\n        print(f\"Hello, {name}\")\n\nvariable_arg_greet(\"Python\", \"Marcos\", \"Andres\")\n\n# Con un número variable de argumentos con palabra clave\ndef variable_key_arg_greet(**names):\n    for key, value in names.items():\n        print(f\"{key}: {value}\")\n\nvariable_key_arg_greet(\n    lenguage=\"Python\", \n    name=\"Marcos\", \n    last_name=\"Andres\",\n    age=25\n)\n\n\"\"\"\nFunciones dentro de otras funciones\n\"\"\"\n\ndef outer_function():\n    def inner_function():\n        print(\"Funcion interna: Hola python\")\n    inner_function()\n\nouter_function()\n\n\"\"\"\nFunciones del lenguaje\n\"\"\"\n\nprint(len(\"Marcos\"))\nprint(type(\"Hello Python\"))\nprint(\"Marcos\".upper())\nprint(\"Python\".lower())\n\n\n\"\"\"\nVariables locales y globales\n\"\"\"\n\nglobal_var = \"Marcos\"\nprint(global_var)\n\ndef hello_python():\n    local_var = \"Hello\" \n    print(f\"{local_var}, {global_var}\")\n\nhello_python()\n\n# print(local_var) no se puede acceder desde fuera de la función\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n\"\"\"\ndef print_numbers(text_1, text_2):\n    count = 0\n    for number in range(1, 101):\n        if(number % 3 == 0 and number % 5 == 0):\n            print(f\"{text_1}{text_2}\")\n        elif(number % 3 == 0):\n            print(text_1)\n        elif(number % 5 == 0):\n            print(text_2)\n        else:\n            print(number)\n            count += 1\n    return f\"Veces que se imprimio un número: {count}\"\n\nprint(print_numbers('Fizz', 'Buzz'))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/mrodara.py",
    "content": "#/*\n# * EJERCICIO:\n# * - Crea ejemplos de funciones básicas que representen las diferentes\n# *   posibilidades del lenguaje:\n# *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n# * - Comprueba si puedes crear funciones dentro de funciones.\n# * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n# * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n# * - Debes hacer print por consola del resultado de todos los ejemplos.\n# *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n# *\n# * DIFICULTAD EXTRA (opcional):\n# * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n# * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n# *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n# *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n# *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n# *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n# *\n# * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n# * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n# */\n\n# Funciones básicas\n\ndef saludo_basico():\n    print(\"Hola\")\n\ndef saludo_personalizado(nombre: str):\n    print(f'Hola {nombre}')\n    \ndef suma(a: int, b: int):\n    return a + b\n\n# No podemos crear funciones dentro de funciones en Python, lo que si podemos hacer es llamar a una función dentro de otra.\ndef suma_rango(a: int, b: int):\n    suma = 0\n    for i in range(a, b+1):\n        suma += i\n    \n    return suma\n\nprint(f'La suma del rango de 1 a 200 es: {suma_rango(1, 200)}')\n\n# De este modo también acabamos de usar funciones ya creadas en python, como range().\n\n# Variable LOCAL y GLOBAL\n# En Python, una variable declarada dentro de una función es local a esa función, a menos que se declare global.\n\nage = 25\n\ndef get_age():\n    global age # Hay que asignar antes de la variable local.\n    age = 30\n    print(f'La edad dentro de la función es: {age}')# Imprime 30\n    print(f'La edad fuera de la función es: {age}')# Imprime 25\n    \nget_age()\n\n# Dificultad extra\ndef string_to_number(string1: str, string2: str) -> int:\n    \n    number = 0\n    \n    for i in range(1, 101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(f'{string1} {string2}')\n        elif i % 3 == 0:\n            print(f'{string1}')\n        elif i % 5 == 0:\n            print(f'{string2}')\n        else:\n            number += 1\n            print(i)\n    \n    return number\n\n\ntimes = string_to_number('Hola caracola', 'Hola caraculo')\n\nprint(f'Se ha impreso el número {times} veces')"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/mvidalb.py",
    "content": "\"\"\"\nFunciones definidas por el usuario\n\"\"\"\n\n# Simple\ndef greet():\n    print(\"Hola, Python!\")\n\ngreet()\n\n\n# Con retorno\ndef return_greet():\n    return \"Hola, Python!\"\n\nprint(return_greet())\n\n\n# Con argumento\ndef arg_greet(name):\n    print(f\"Hola, {name}!\")\n\narg_greet(\"Mario\")\n\n\n# Con argumentos\ndef args_greet(greet, name):\n    print(f\"{greet}, {name}!\")\n\nargs_greet(\"Hi\",\"Mario\")\n\n\n#Con un argumento predeterminado\ndef default_arg_greet(name = \"Pedro\", greet = \"Hi\"):\n    print(f\"{greet}, {name}!\")\n\ndefault_arg_greet(greet = \"Hola\")\ndefault_arg_greet(\"Mario\")\n\n\n# Con argumentos y return\ndef return_args_greet(greet, name):\n    return f\"{greet}, {name}!\"\n\nprint(return_args_greet(\"Hi\", \"Mario\"))\n\n\n# Con retorno de varios valores\ndef multiple_return_greet():\n    return \"Hola\",\"Python\"\n\ngreet, name = multiple_return_greet()\nprint(greet)\nprint(name)\n\n\n# Con un número variable de argumentos\ndef variable_arg_greet(*names):\n    for name in names:\n        print(f\"Hola, {name}!\")\n\nvariable_arg_greet(\"Python\", \"Mario\", \"Pedro\", \"Comunidad\")\n\n\n# Con un número variable de argumentos con palabra clave\ndef variable_key_arg_greet(**names):\n    for param, name in names.items():\n        print(f\"{name} ({param})!\")\n\nvariable_key_arg_greet(language=\"Python\", name=\"Mario\", alias=\"Pedro\", group=\"Comunidad\")\n\n\n\"\"\"\nFunciones dentro de funciones\n\"\"\"\n\ndef outer_function():\n    def inner_function():\n        print(\"Hola, Python!\")\n    inner_function()\n\nouter_function()\n\n\n\"\"\"\nFunciones de lenguaje (built-in)\n\"\"\"\n\nprint(len(\"Eyyyy\"))\nprint(type(\"Mario\"))\nprint(\"Mouredev\".upper())\n\n\"\"\"\nVariables locales y globales\n\"\"\"\n\nglobal_variable = \"Python\"\nlocal_variable = \"Hola\"\n\nprint(global_variable)\n\ndef hello_python():\n    print(f\"Hello, {global_variable}\")\n\nhello_python()\n\n\n\"\"\"\nEjercicio extra\n\"\"\"\ndef ejerc_extra(string1, string2):\n    print(\"Comienza el ejercicio extra:\")\n    cont_num = 0\n    for num in range(1,101):\n        if num%3 == 0 and num%5 == 0:\n            print(string1+string2)\n        elif num%5 == 0:\n            print(string2)\n        elif num %3 == 0:\n            print(string1)\n        else:\n            print(num)\n            cont_num += 1\n    \n    print(f\"Números printeados: {cont_num}\")\n\nejerc_extra(\"Hola\", \"Adiós\")\n    \n\n\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/neslarra.py",
    "content": "\"\"\"\n EJERCICIO:\n - Crea ejemplos de funciones básicas que representen las diferentes\n   posibilidades del lenguaje:\n   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n - Comprueba si puedes crear funciones dentro de funciones.\n - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n - Debes hacer print por consola del resultado de todos los ejemplos.\n   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n\n DIFICULTAD EXTRA (opcional):\n Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\n Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n\"\"\"\nnumero_de_llamadas_por_funcion = dict()\n\n\ndef contador_de_ejecuciones(funcion: str) -> None:\n    \"\"\"\n    Contabiliza la llamada\n    :return: None\n    \"\"\"\n    global numero_de_llamadas_por_funcion\n\n    if funcion in numero_de_llamadas_por_funcion.keys():\n        numero_de_llamadas_por_funcion[funcion] += 1\n    else:\n        numero_de_llamadas_por_funcion[funcion] = 1\n\n\ndef imprimir_llamadas_a_funcion() -> None:\n    \"\"\"\n    Imprime la cantidad de veces que se ejecutó una función\n    mostrando la variable global numero_de_llamadas_por_funcion.\n    :return: None\n    \"\"\"\n    global numero_de_llamadas_por_funcion\n\n    contador_de_ejecuciones(\"imprimir_llamadas_a_funcion\")\n\n    for k, v in numero_de_llamadas_por_funcion.items():\n        print(f\"La función {k} fue llamada {v} veces.\")\n\n\ndef sumar(*args) -> int:\n    \"\"\"\n    Suma los números recibidos\n    :param args: numeros a sumar\n    :return: suma\n    \"\"\"\n    def validar() -> bool:\n        for n in args:\n            if n.__class__.__name__ not in (\"int\", \"float\", \"str\"):\n                return False\n            if n.__class__.__name__ == \"str\" and not n.isnumeric():\n                return False\n\n        return True\n\n    contador_de_ejecuciones(\"sumar\")\n\n    suma = 0\n\n    if validar():\n        for sumando in args:\n            suma += int(sumando) if sumando.__class__.__name__ == \"str\" else sumando\n    else:\n        print(\"ERROR en sumar: argumentos NO validados.\")\n\n    return suma\n\n\ndef multiplicar(*args) -> int:\n    \"\"\"\n    Multplica los números recibidos\n    :param args: números a multiplicar\n    :return: producto\n    \"\"\"\n    def validar() -> bool:\n        for n in args:\n            if n.__class__.__name__ not in (\"int\", \"float\", \"str\"):\n                return False\n            if n.__class__.__name__ == \"str\" and not n.isnumeric():\n                return False\n\n        return True\n\n    contador_de_ejecuciones(\"multiplicar\")\n\n    producto = 1\n\n    if validar:\n        for factor in args:\n            producto *= int(factor) if factor.__class__.__name__ == \"str\" else factor\n    else:\n        print(\"ERROR en multiplicar: argumentos NO validados.\")\n\n    return producto\n\n\ndef mail(*args) -> str:\n    \"\"\"\n    Arma el mail con los datos recibidos\n    :param args: Para, Copiar, Asunto y Texto\n    :return: representación del mail\n    \"\"\"\n    contador_de_ejecuciones(\"mail\")\n\n    return f\"To: {args[0]}\\nCc: {args[1]}\\nAsunto: {args[2]}\\n{args[3]}\\n\"\n\n\ndef ejecutar(funcion, args):\n    \"\"\"\n    Una manera de armar \"reflexión\" => recibe cadenas y evalúa para ejecutar una función.\n    :param funcion: función a llamar\n    :param args: argumentos a enviar\n    :return: devuelve que lo que retorne cada función llamada\n    \"\"\"\n    ejecutar = funcion + str(args)\n    return eval(ejecutar)\n\n\ndef complejidad_extra(cadena1: str, cadena2: str) -> int:\n    \"\"\"\n    Sigue los lineamientos indicados al ppio del reto.\n    :param cadena1: a imprimir si es múltiplo de 3 o de 3 y 5\n    :param cadena2: a imprimir si es múltiplo de 5 o de 3 y 5\n    :return: número de veces que NO se imprimió la cadena\n    \"\"\"\n    contador_de_ejecuciones(\"complejidad_extra\")\n\n    numero_de_veces = 0\n\n    for i in range(1, 101):\n        if i % 3 == 0:\n            if i % 5 == 0:\n                print(f\"{cadena1} {cadena2}\")\n            else:\n                print(cadena1)\n        elif i % 5 == 0:\n            print(cadena2)\n        else:\n            print(f\"{i}\")\n            numero_de_veces += 1\n\n    return numero_de_veces\n\n\ntareas = {\n    \"suma 1\": [\"sumar\", (1, 4, 7, 9)],\n    \"producto 1\": [\"multiplicar\", (3, 3, 4)],\n    \"suma 2\": [\"sumar\", (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)],\n    \"suma 3\": [\"sumar\", (1, 2, 3, 5, 8, '1E', 21, 34)],\n    \"producto 2\": [\"multiplicar\", (1, 2, 3, 4, 5,  6)],\n    \"correo\": [\"mail\", (\"neslarra@fibertel.com.ar\",\n                        \"Brais.Moure@mouredev.com.es\",\n                        \"Reto# 2 - funciones\",\n                        \"Subiendo una versión python del reto.\"\n                        )],\n    \"complejidad extra\": [\"complejidad_extra\", (\"Lorem Ipsum\", \"dolor sit amet\")]\n    }\n\nfor k, v in tareas.items():\n    print(f\"{k} =>  {ejecutar(v[0], v[1])}\")\n\nprint(f\"Otra suma: {sumar(1, '29', 30, 40, 50)}\")\nprint(f\"Otro producto: {multiplicar(1, 2, 4, '8', 16, 32, 64)}\", end=\"\\n\\n\")\nprint(f\"Otro correo: {mail('neslarra@fibertel.com.ar', 'Brais.Moure@mouredev.com.es', 'Reto# 2 - funciones (2)', 'Agregué complejidad extra.')}\")\n\nimprimir_llamadas_a_funcion()\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/nightblockchain30.py",
    "content": "\"\"\"\n- Crea ejemplos de funciones básicas que representen las diferentes\n    posibilidades del lenguaje:\n    Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n\"\"\"\nprint(\"\\n**** PART 1 - FUNCTIONS ****\\n\")\n\ndef no_params_no_return_void_function():\n    pass\n\ndef no_params_no_return():\n    print(\"function no_params_no_return()\")\n\ndef no_params_return():\n    print(\"function no_params_return(): returns 'result'\")\n    return \"result\"\n\ndef params_return(x,y):\n    result=x+y\n    print(f\"function params_return(x,y): returns {result}\")\n    return result\n\n\ndef arbitrary_params(*elements):\n    result=sum(element for element in elements)\n    print(f\"arbitrary_params(*elements): returns {result}\")\n    return result\n\ndef keywords_params(dividend, divisor):\n    result=dividend/divisor\n    print(f\"keywords_params(dividend, divisor): returns {result}\")\n    return result\n\ndef keyword_arbitrary_params(**elements):\n    result = 0\n    if (\"dividend\" in elements and \"divisor\" in elements):\n        result = elements[\"dividend\"]/elements[\"divisor\"]\n    print(f\"keyword_arbitrary_params(**elements): returns {result}\")\n    return result\n\ndef default_value(name=\"Mickey\"):\n    print(f\"function default_value(name='Mickey'): param = {name}\")\n\ndef list_value(brands):\n    print(\"function list_value(brands)\")\n    for brand in brands:\n        print(f\" - {brand}\")\n\ndef positional_only_arguments(x, y, /):\n    result = x * y\n    print(f\"function positional_only_arguments(x, y, /): returns {result}\")\n    return x * y\n\ndef keyword_only_arguments(*, x, y):\n    result = x * y\n    print(f\"function keyword_only_arguments(*, x, y): returns {result}\")\n    return result\n    \ndef keyword_only_positional_only_and_arguments(x, y, /, *, a, b):\n    result = f\"positional : {str(x*y)} ... keyword: {str(a*b)}\"\n    print(f\"function positional_only_arguments(x, y, /): returns {result}\")\n    return result\n\n\ndef use_lambda_power_of_2(element):\n    lambda_func = lambda base: pow(2,base)\n    print(f\"lambda function: {lambda_func}\")\n    result = lambda_func(element)\n    print(f\"function use_lambda_power_of_2: result = {result}\" )\n    return result\n\ndef recursion_power(base,exponent):\n    print(f\"function recursion_power(base,exponent): params= ({base},{exponent})\")\n    if exponent == 0:\n      return 1\n    elif (exponent == 1):\n      return base\n    elif (exponent == -1):\n       return 1/base\n    else:\n        exponent -= 1 if exponent > 0 else -1\n        return recursion_power(base * base, exponent)\n\n# calling functions\n\nprint(\"\\ncalling no_params_no_return_void_function()\")\nno_params_no_return_void_function()\n\nprint(\"\\ncalling no_params_no_return()\")\nno_params_no_return()\n\nprint(\"\\ncalling params_return(5,9)\")\nprint(params_return(5,9))\n\nprint(\"\\ncalling arbitrary_params(1,2,3,4,5,6)\")\nprint(arbitrary_params(1,2,3,4,5,6))\n\nprint(\"\\ncalling keywords_params(divisor=1,dividend=0)\")\nprint(keywords_params(divisor=1,dividend=0))\n\nprint(\"\\ncalling keywords_params(divisor=1,dividend=0)\")\nprint(keywords_params(divisor=1,dividend=0))\n\nprint(\"\\ncalling keyword_arbitrary_params(divisor=1)\")\nprint(keyword_arbitrary_params(divisor=1))\n\nprint(\"\\ncalling default_value()\")\ndefault_value()\nprint(\"\\ncalling default_value('Pluto')\")\ndefault_value(\"Pluto\")\n\nprint(\"\\ncalling list_value('Apple','Samsung','Xiaomi')\")\nlist_value([\"Apple\",\"Samsung\",\"Xiaomi\"])\n\nprint(\"\\ncalling positional_only_arguments(5,9)\")\nprint(positional_only_arguments(5,9))\n\nprint(\"\\ncalling keyword_only_arguments(x=3,y=4)\")\nprint(keyword_only_arguments(x=3,y=4))\n\nprint(\"\\ncalling keyword_only_positional_only_and_arguments(5,9,a=3,b=4)\")\nprint(keyword_only_positional_only_and_arguments(5,9,a=3,b=4))\n\nprint(\"\\ncalling use_lambda_power_of_2(5))\")\nprint(use_lambda_power_of_2(5))\n\n\nprint(\"\\ncalling recursion_power(1,0)\")\nprint(recursion_power(1,0))\nprint(\"\\ncalling recursion_power(2,4)\")\nprint(recursion_power(2,4))\nprint(\"\\ncalling recursion_power(2,-2)\")\nprint(recursion_power(2,-2))\n\n\n\"\"\" - Comprueba si puedes crear funciones dentro de funciones.\"\"\"\nprint(\"\\n**** PART 2 - INNER FUNCTIONS ****\\n\")\n\ndef with_inner(a,b,c,d):\n    result=a+b\n    \n    def inner_function(c,d):\n        result=c+d\n        print(f\"function inner_function(c,d): returns {result}\")\n        return result\n    \n    result +=  inner_function(c,d)\n    print(f\"function with_inner(a,b,c,d): returns {result}\")\n    return result\n\nprint(\"\\ncalling with_inner(1,4,10,100) that contains an inner function\")\nprint(with_inner(1,4,10,100))\n\nprint(\"\\ninner function cannot be called directly: inner_function(10,100)\")\n\n# Inner function cannot be called: inner_function(1))\n\n\n\"\"\" - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\"\"\"\nprint(\"\\n**** PART 3 - BUILT-IN FUNCTIONS ****\\n\")\n\ndef slice_tuple_pairs_without_first(list):\n    slice_function=slice(1,len(list),2)\n    return list[slice_function]\nprint(slice_tuple_pairs_without_first(['banana','apple','orange','strawberry','pear','avocado','pineapple']))\nprint(f\"\\ncalling slice_tuple_pairs_without_first(['banana','apple','orange','strawberry','pear','avocado','pineapple'])\")\n\n\ndef sort_reverse_and_add(list,element):\n    list.append(element)\n    return sorted(list,reverse=1)\nprint(f\"\\ncalling sort_reverse_and_add(['banana','apple','orange','strawberry','pear','avocado','pineapple'],'peach')\")\nprint(sort_reverse_and_add(['banana','apple','orange','strawberry','pear','avocado','pineapple'],'peach'))\n\n\n\"\"\" - Pon a prueba el concepto de variable LOCAL y GLOBAL\"\"\"\nprint(\"\\n**** PART 4 - GLOBAL AND LOCAL SCOPES FOR VARIABLES ****\\n\")\n\nprint(\"setting global variable var1=1\")\nvar1=1\n\ndef sum_local_variables(element):\n    var1=3\n    result = var1+element\n    print(f\"function sum_local_variables: result = {result}\")\n    return result\n\ndef sum_global_variable(element):\n    result = var1+element\n    print(f\"function sum_global_variable: result = {result}\")\n\n    return result\n\ndef printing_local_variable():\n    var2=\"a\"\n    print(f\"function printing_local_variable: var2 = {var2}\")\n\nprint(\"\\ncalling sum_local_variables(10)\")\nsum_local_variables(10)\nprint(\"\\ncalling sum_global_variable(10)\")\nsum_global_variable(10)\n\nprint(\"\\ncalling printing_local_variable()\")\nprinting_local_variable()\nprint(\"\\nprinting local variable from printing_local_variable() doesn't compiles: print(var2)\")\n\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\nCrea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n- La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n- Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n- Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n- Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n- La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\"\"\"\nprint(\"\\n**** PART 5 - EXTRA FUNCTION ****\\n\")\n\ndef print_and_count(text1,text2):\n    counter = 0\n    for eachNumber in range(1,101):\n        result = ''\n        if(eachNumber % 3 == 0):\n            result += text1\n        if(eachNumber%5 == 0):\n            result += text2\n        if(len(result) == 0):\n            counter+=1\n            result=str(eachNumber)\n        print(result)\n    return counter\n\nprint(f\"Calling print_and_count('mul3','mul5'):\\n\")\nprint(f\"\\nresult = {print_and_count('mul3','mul5')}\")\n\nprint(\"\\n\") "
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/njaimev.py",
    "content": "# Los parametros son las variables que se definen entre () en la declaracion de una funcion.\r\n# Return es una instruccion que se usa dentro de una funcion para devolver un valor\r\n# o resultado al lugar donde fue llamada.\r\n\r\n# Como no comprendo muy bien lo de return, pondre un ejemplo:\r\ndef sumar(a, b):\r\n    resultado = a + b\r\n    return resultado\r\n\r\n# Llamada a la función y uso del valor de retorno\r\nsuma = sumar(5, 3)\r\nprint(suma)  # Salida: 8\r\n# return resultado FINALIZA la funcion sumar.\r\n# resulado es el valor devuelto al codigo que llamó a la funcion.\r\n# la variable suma almacena el valor devuelto (8).\r\n\r\n# 1. Funcion sin parámetros ni retorno\r\n# esta no recibe ningún parámetro y no devuelve nada, solo ejecuta su tarea y termina\r\ndef saludar():\r\n    print(\"Hola, bienvenido!\")\r\n\r\nsaludar()\r\n\r\n# 2. Función con parámetro pero sin retorno\r\n# recibe parámetros para realizar una operación, pero no devuelve ningun valor\r\ndef saludar(nombre):\r\n    print(f\"Hola, {nombre}!\")\r\n\r\nsaludar(\"Ana\")\r\n\r\n# 3. Función sin parámetros pero con retorno\r\n# no recibe parámetros, pero devuelve un valor\r\ndef obtener_mensaje():\r\n    return \"Este es un mensaje de prueba.\"\r\n\r\nmensaje = obtener_mensaje()\r\nprint(mensaje)\r\n\r\n# 4. Funcion con parámetros y retorno \r\n# recibe parametros y devuelve un valor, se usa para calculos o transformaciones\r\ndef sumar(a, b, c):\r\n    return a + b + c\r\n\r\nresultado = sumar(3, 5, 4)\r\nprint(resultado)\r\n\r\n# 5. Funcion con parametros predeterminados\r\n# si no se pasa un valor, usa el predeterminado \r\ndef saludar(nombre=\"invitado\"):\r\n    print(f\"Hola, {nombre}!\")\r\n\r\n# Llamada a la función sin y con un argumento\r\nsaludar()         # Salida: Hola, invitado!\r\nsaludar(\"Carlos\") # Salida: Hola, Carlos!\r\n\r\n# 6. Funcion con un numero variable de parámetros\r\n# usa *args o **kwargs, aceptando un numero arbitrario de argumentos\r\ndef sumar_varios(*numeros):\r\n    return sum(numeros)\r\n\r\n# Llamada a la función con múltiples argumentos\r\nresultado = sumar_varios(1, 2, 3, 4, 5)\r\nprint(resultado) # Salida: 15\r\n\r\n# *args recibe un numero indeterminado de argumentos en forma de tupla (que no puede cambiarse \r\n# el orden)\r\ndef sumar(*numeros):\r\n    total = sum(numeros)\r\n    return total\r\n\r\nprint(sumar(1, 2, 3, 4))  # Salida: 10\r\n\r\n# **kwargs recibe un numero indeterminado de argumentos nombrados tipo clave-valor en forma \r\n# de diccionario\r\ndef mostrar_informacion(**info):\r\n    for clave, valor in info.items():\r\n        print(f\"{clave}: {valor}\")\r\n\r\nmostrar_informacion(nombre=\"Ana\", edad=25, ciudad=\"Madrid\")\r\n# Salida:\r\n# nombre: Ana\r\n# edad: 25\r\n# ciudad: Madrid\r\n\r\n\r\n# Una función dentro de otra función se llama función anidada\r\n# esta función interna solo puede usarse dentro de la función externa, no se puede acceder \r\n# a ella fuera de esta.\r\ndef calcular_total_pedido(pedido):\r\n    # Función interna para verificar condiciones\r\n    def verificar_pedido():\r\n        if not pedido:  # Verifica si el pedido está vacío\r\n            print(\"El pedido está vacío.\")\r\n            return False\r\n        if sum(pedido.values()) <= 0:  # Verifica que el total sea positivo\r\n            print(\"El total del pedido no puede ser cero o negativo.\")\r\n            return False\r\n        return True\r\n    \r\n    # Si las condiciones se cumplen, calcula el total\r\n    if verificar_pedido():\r\n        total = sum(pedido.values())\r\n        print(f\"El total del pedido es: {total}\")\r\n    else:\r\n        print(\"No se pudo calcular el total.\")\r\n\r\n# Ejemplos de uso\r\npedido_valido = {\"item1\": 15, \"item2\": 30}\r\npedido_vacio = {}\r\npedido_invalido = {\"item1\": -10, \"item2\": -20}\r\n\r\ncalcular_total_pedido(pedido_valido)    # Salida: El total del pedido es: 45\r\ncalcular_total_pedido(pedido_vacio)     # Salida: El pedido está vacío.\r\ncalcular_total_pedido(pedido_invalido)  # Salida: El total del pedido no puede ser cero o negativo.\r\n\r\n\r\n# variables globales: se definen fuera de cualquier función y son accesibles de cualquier parte\r\n# del programa (incluidas funciones)\r\n\r\nx = 10  # Variable global\r\n\r\ndef imprimir_valor():\r\n    print(x)  # Puede acceder a la variable global\r\n\r\nimprimir_valor()  # Salida: 10\r\n\r\n# Variable local: se definen dentrode una función y solo es accesible dentro de esta.\r\n\r\ndef calcular_suma():\r\n    y = 5  # Variable local\r\n    return y + 10\r\n\r\nprint(calcular_suma())  # Salida: 15\r\n\r\n\r\n\r\n# Si se quiere modificar una variable global dentro de una función se debe usar la \r\n# palabra global \r\n\r\nz = 20  # Variable global\r\n\r\ndef modificar_variable():\r\n    global z\r\n    z = 30  # Modifica la variable global\r\n\r\nmodificar_variable()\r\nprint(z)  # Salida: 30\r\n\r\n# DIFICULTAD EXTRA (opcional):\r\n # Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\r\n # - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\r\n #   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\r\n #   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\r\n #   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\r\n #   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\r\n\r\ndef print_num(str_1, str_2) -> int:\r\n    count = 0\r\n    for num in range (1, 101):\r\n        if num % 3 == 0 and num % 5 == 0:\r\n            print(str_1 + str_2)\r\n        elif num % 3 == 0:\r\n            print(str_1)\r\n        elif num % 5 == 0:\r\n            print(str_2)\r\n        else:\r\n            print(num)\r\n            count += 1\r\n    return count\r\n\r\nprint(print_num(\"Mult3\", \"Mult5\"))\r\n\r\n# Se imprime al final el resultado del return que sería cuantas veces se imprimieron numeros."
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/nlarrea.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n\"\"\"\n\n# FUNCIONES SIN PARÁMETROS\n\ndef greet() -> None:\n    print('Hello there!')\n\n# FUNCIONES CON PARÁMETROS\n\ndef greet_user(name: str, surname: str) -> None:\n    print(f\"Hello {name} {surname}!\")\n\n# FUNCIONES CON RETORNO\n\ndef add_two(num_one: int | float, num_two: int | float) -> int | float:\n    return num_one + num_two\n\n# FUNCIONES CON FUNCIONES DENTRO\n\ndef greet_user_with_inner (name: str, surname: str):\n    def get_full_name(): return f\"{name} {surname}\"\n\n    print(f\"Hello {get_full_name()}!\")\n\n# BUILT IN FUNCTIONS\n\nSTRING_NUMBER = '11'\nNUMBER = int(STRING_NUMBER)\nprint(f\"STRING_NUMBER is {type(STRING_NUMBER)}, but NUMBER is {type(NUMBER)}\")\n# STRING_NUMBER is <class 'str'>, but NUMBER is <class 'int'>\n\n# LLAMADA A LAS FUNCIONES\n\ngreet()\n\ngreet_user('Naia', 'Larrea')\n\nprint(add_two(2, 3))      # 5\n\ngreet_user_with_inner('Naia', 'Larrea')\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n\"\"\"\n\ndef print_numbers(text_one, text_two):\n    counter = 0\n\n    for num in range(1, 101):\n        if num % 3 == 0 and num % 5 == 0:\n            print(f\"{text_one}{text_two}\")\n        elif num % 3 == 0:\n            print(text_one)\n        elif num % 5 == 0:\n            print(text_two)\n        else:\n            print(num)\n            counter += 1\n\n    return counter\n\nprint(print_numbers('fizz', 'buzz'))  # 53"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/nox456.py",
    "content": "# Función sin parámetros ni retorno\ndef saludar():\n    print(\"Holaaa!!\")\n\nsaludar()\n\n# Función con parámetros contados y retorno\ndef suma(num1,num2):\n    return num1 + num2\n\nprint(suma(5, 2))\n\n# Función con parámetros variables y retorno\ndef multiplicar(*nums):\n    resultado = 1\n    for i in nums:\n        resultado = resultado * i\n    return resultado\n\nprint(multiplicar(2,5,10,5))\n\n# Funciones anidadas\ndef accion(nombre):\n    def comer(comida):\n        print(f\"{nombre} está comiendo {comida}\")\n    def jugar(juego):\n        print(f\"{nombre} está jugando {juego}\")\n\n    comer(\"pizza\")\n    jugar(\"Fallout (juegazo)\")\n\naccion(\"Gabriel\")\n\n# Función predefinida por el lenguaje\nnombre = \"Gabriel\"\nprint(f\"La longitud el nombre es {len(nombre)}\")\n\n# Variable local\nnum = 5\ndef mostrarNum(num):\n    print(f\"Número es: {num}\")\n    num = 10\n    print(f\"(Dentro de la función) el número es: {num}\")\n\nmostrarNum(num)\nprint(f\"(Fuera de la función) el número sigue siendo: {num}\")\n\n# Variable global\nedad = 19\ndef mostrarEdad():\n    global edad\n    print(f\"La edad inicialmente es {edad}\")\n    edad = 20\n    print(f\"(Dentro de la función) Ahora la edad es {edad}\")\n\nmostrarEdad()\nprint(f\"(Fuera de la función) la edad también es {edad}\")\n\n# DIFICULTAD EXTRA\n\ndef contar(texto1,texto2):\n    count = 0\n    for i in range(1,101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(texto1 + texto2)\n        elif i % 3 == 0:\n            print(texto1)\n        elif i % 5 == 0:\n            print(texto2)\n        else:\n            print(i)\n            count += 1\n    return count\n\nprint(f\"La veces que se imprimió el número fueron: {contar(\"hola\", \"adios\")}\")\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/oniricoh.py",
    "content": "\n# Funciones básicas que representen las diferentes posibilidades\n# Función sin argumentos\ndef saludo_simple():\n    print(\"Hola!\")\n\nprint(\"\\nSaludo Simple:\")\nsaludo_simple()\n\n\n# Función con argumentos\ndef saludar_persona(nombre):\n    print(f\"Hola {nombre}!\")\n\nprint(\"\\nSaludo con argumentos:\")\nsaludar_persona(\"Dani\")\n\n\n# Función con retorno\ndef saludar_a_persona(nombre):\n    return f\"Hola {nombre}\"\n\nprint(\"\\nSaludo con retorno:\")\nmensaje = saludar_a_persona(\"Dani\")\nprint(mensaje)\n\n\n# Función con argumentos definidos por defecto\ndef saludo_definido(nombre=\"Invitado\", saludo=\"Saludos\"):\n    return f\"{saludo}, {nombre}\"\n\nprint(\"\\nSaludo con valores por defecto:\")\nmensaje = saludo_definido()\nprint(mensaje)\nprint(saludo_definido(nombre=\"Dani\", saludo=\"Buenos días\"))\n\n\n# *Args\ndef saludos_varios(*args, saludo=\"Hola\"):\n    for arg in args:\n        print(f\"{saludo}, {arg}\")\n\nprint(\"\\nSaludo con *args:\")\nsaludos_varios(\"Pepe\", \"Maria\", \"Dani\", \"Jesus\", \"Cristobal\")\n\n\n# **kwargs\ndef saludos_diccionario(**kwargs):\n    for clave, valor in kwargs.items():\n        print(f\"{clave}:{valor}\")\n\nprint(\"\\nFunción con *kwargs:\")\nsaludos_diccionario(nombre=\"dani\", edad=34, sexo=\"Hombre\")\n\n\n# Función dentro de otra función\ndef funcion_exterior(x):\n    def funcion_interior(y):\n        return y * 2\n    resultado = x + funcion_interior(x)\n    return resultado\n\nprint(\"\\nFunción dentro de otra función:\")\nprint(funcion_exterior(4))   \n\n\n# Variables LOCAL y variable GLOBAL\nvariable_global = 5\n\ndef variables():\n    global variable_global\n    variable_local = 10\n    print(variable_local + variable_global)\n\nprint(\"\\nVariable local + Variable global:\")\nvariables()\n\n\n# Dificultad Extra:\n\ndef prueba_extra(string1, string2) -> int:\n    count = 0\n    for number in range(1, 101):\n        if number % 3 == 0 and number % 5 == 0:\n            print(f\"{number} {string1} y {string2}\")\n        elif number % 3 == 0:\n            print(string1)\n        elif number % 5 == 0:\n            print(string2)\n        else:\n            print(number)\n            count += 1\n    return count\n\nprint(\"\\nEjercicio (dificultad extra):\")\nprueba = prueba_extra(\"Es multiplo de 3\", \"Es multiplo de 5\")\nprint(f\"Se imprimió {prueba} veces el número en vez de el texto\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/oriaj3.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\"\"\"\n\n# Ejemplo de función sin parámetros ni retorno\ndef funcion1():\n    print(\"Hola\")\nfuncion1()\n\n# Ejemplo de función con parámetros y sin retorno\ndef funcion2(param1, param2):\n    print (param1, param2)\nfuncion2(\"Hola\", \"Mundo\")\n\n# Ejemplo de función con parámetros y un retorno\ndef funcion3(param1, param2):\n    return param1 + param2\nprint(funcion3(\"Hola\", \"Mundo\"))\n\n# Ejemplo de función con parámetros y varios retornos\ndef funcion3a(param1, param2):\n    return param1, param2, param1 + param2\nprint(funcion3a(2, 5))\n\n# Función con otra función dentro\ndef funcion4():\n    def funcion4_1():\n        print(\"Adios Mundo\")\n    print(\"Hola Mundo\")\n    funcion4_1()\nfuncion4()\n\n#Ejemplo función creada en el lenguaje\nprint(f\"Ejemplo función creada en el lenguaje, el tamaño es: {len('Hola Mundo')}\")\n\n# Ejemplo de función con variable LOCAL\nvarLocal = \"Hola Mundo LOCAL externo a la función\"\ndef funcion5():\n    varLocal = \"Hola Mundo LOCAL dentro de la función\"\n    print(varLocal)\nprint(varLocal)\nfuncion5() # Llamada a la función y se comprueba que el print anterior y esta llamada el resultado es diferente\n    \n# Ejemplo de función con variable GLOBAL que no cambia su valor dentro de la función\nvarGlobal = \"Hola Mundo GLOBAL externa a la función\"\ndef funcion6():\n    varGlobal = \"Hola Mundo GLOBAL dentro de la función\"\n    print(varGlobal)\n\nprint(varGlobal)\nfuncion6() # Llamada a la función y se comprueba que el print anterior y esta llamada el resultado es diferente\nprint(varGlobal) # Se comprueba que la variable global no ha cambiado su valor fuera de la función\n\n# Ejemplo de función con variable GLOBAL que cambia su valor dentro de la función\nvarGlobal = \"Hola Mundo GLOBAL2 externa a la función\"\ndef funcion7():\n    global varGlobal\n    varGlobal = \"Hola Mundo GLOBAL2 dentro de la función\"\n    print(varGlobal)\nprint (varGlobal)\nfuncion7() # Llamada a la función y se comprueba que el print anterior y esta llamada el resultado es diferente\nprint(varGlobal) # Se comprueba que la variable global ha cambiado su valor fuera de la función\n\n\n\"\"\"\n    DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n\"\"\"\n\n# Función que recibe dos parámetros de tipo cadena de texto y retorna un número\ndef funcionExtra(param1, param2):\n    contador = 0 \n    for i in range (1, 101):\n        salida = \"\"\n        #Compruebo si es múltiplo de 3 y de 5\n        if i % 3 == 0 and i % 5 == 0: \n            salida = param1 + param2\n        elif i % 3 == 0:\n            salida = param1\n        elif i % 5 == 0:\n            salida = param2\n        else:\n            salida = i\n            contador += 1\n        print(salida)\n    return contador    \nnumero_veces = funcionExtra(\"Fizz\", \"Buzz\")\nprint(f\"El número de veces que se ha impreso el número en lugar de los textos es: {numero_veces}\")\n\ndef variable_key(**keywords):\n    for kw in keywords:\n        print(kw, \":\", keywords[kw])\n\nvariable_key(nombre=\"Oriaj\", apellido=\"Oriaj\", edad=30)"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/oscargeovannyrincon.py",
    "content": "'''/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */'''\n\ndef area_cuadrado():\n     lado=8\n     print(f'\\nEl area de un cuadrado de lado {lado} metros es {lado*lado} metros cuadrados')\n\narea_cuadrado()\n\ndef area_circulo(radio):\n     area_circulo=3.1416*(radio**2)\n     return(print(f'\\nEl area de un circulo de radio {radio}m es {area_circulo} metros cuadrados '))\narea_circulo(0.01)\n\ndef area_poligono(apotema,perimetro):\n     poligono=(apotema*perimetro)\n     return(print(f'\\nEl area de cualquier poligono solo necesita el apotema y el perimetro\\nEl area del poligono de apotema={apotema}cm y perimetro={perimetro}cm es {poligono}cm cuadrados'))\n\narea_poligono(perimetro=90,apotema=50)\n\ndef mi_peso(masa,acc_gravedad):\n     mi_peso=masa*acc_gravedad\n     return(mi_peso)\nprint(f'\\nMi masa es de 75kg y la acceleracion de la gravedad es 9.81m/s, mi peso sera de {mi_peso(75,9.81)}N')\n\ndef multiplo_3(numero):\n     if numero%3==0:\n          #print('multilplo de tres')\n          return(True)\n     else:\n          return(False)\nnum=399\nprint(f'\\nEl numero {num} es multiplo de 3?')\nprint(multiplo_3(num))\n\n\ndef area_poligono(apotema,perimetro=90):\n     poligono=(apotema*perimetro)\n     return(print(f'\\nEl area de cualquier poligono solo necesita el apotema y el perimetro\\nEl area del poligono de apotema={apotema}cm y perimetro={perimetro}cm es {poligono}cm cuadrados'))\n\narea_poligono(50)\narea_poligono(apotema=50,perimetro=100)\narea_poligono(60)\n\n\n#FUNCION DENTRO DE UNA FUNCION\n#La verdad no le encuentro sentido a una funcion dentro de otra funcion\n\ndef outer_function():\n     def inner_function(name):\n          print(f'Funcion interna: Hola, {name}')\n     inner_function('Oscar')\n     \nouter_function()\n\ndef variable_key_arg_greet(**names):\n     for key, value in names.items():\n          print(f'Hola, {value} ({key})!')\n\nvariable_key_arg_greet(Nombre='Oscar', Apellido='Rincon',Edad=35, Lenguaje='Python')\n\n\n#Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n\nx=(5<3)\nprint(bool(x))\n\nprint(ord('^'))\n\nnumeros=[24,37,-54,36,89]\nprint(sum(numeros))\n\nprint(hex(1333))\n\nnombre='Oscar Geovanny Rincon Fuentes'\nprint(nombre.replace('a','e'))\n\n#Variables globales y locales\n\npi=3.1416\nrad=20\n\ndef area_circulo(radio):\n     area=pi*(radio**2)\n     return area\n\nprint(f'El area de la circunferecia de radio {rad}cm es {area_circulo(rad)}cm cuadrados')\n\nang_grados=270\ndef longitud_arco(radio,angulo_grados):\n     angulo_radianes=angulo_grados*(pi/360)\n     long=radio*angulo_radianes\n     return long\n\nprint(f'La longitud de arco de radio {rad}cm y un angulo de {ang_grados}° es {longitud_arco(rad,ang_grados)}cm')\n\n'''* DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.'''\n \ndef tic_tac(texto_1,texto_2):\n     rep=0\n     for num in range(1,101):\n          if num%3==0 and num%5==0:\n               print(texto_1+texto_2)\n          elif num%3==0:\n               print(texto_1)\n          elif num%5==0:\n               print(texto_2)\n          else:\n               print(num)\n               rep += 1\n     return f'\\n El numero de veces que se imprimio el numero fue  {rep}'\n\nprint(tic_tac('tic','tac'))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/oscarhub90.py",
    "content": ""
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/pabloche73.py",
    "content": "# fUNCIONES\r\n\r\n#### Suma\r\n\r\ndef suma(num1, num2):\r\n    print(\"Suma: \", num1, \"+\", num2, \"=\", num1 + num2)\r\n\r\nsuma(3, 2)\r\n\r\nprint()\r\n#### Suma de strings\r\n\r\ndef full_name(name, surname):\r\n    print(\"Nombre completo:\", name, surname)\r\n\r\nfull_name(\"Juan\", \"Pérez\")\r\n\r\nprint()\r\n#### Funcion llama a otro funcion\r\n\r\ndef if_less (number):\r\n    if int(number) > 4:\r\n        print (f\"{number} es mayor que 4\")\r\n    elif int(number) == 4:\r\n        print (f\"El numero es igual a 4\")\r\n    else:\r\n        print (f\"El numero es menor a 4\")\r\n\r\n\r\ndef sum_if(num1, num2):\r\n    mi_suma = num1 + num2\r\n    print(f\"Suma: {mi_suma}\")\r\n    if_less(mi_suma)\r\n\r\nn1 = input(\"Ingrese un numero entero: \")\r\nn2 = input(\"ingrese otro numero entero: \")\r\n\r\nsum_if(int(n1), int(n2))\r\n\r\nprint()\r\n\r\n#### Funcion sencilla con return\r\n\r\ndef suma_str (str1, str2):\r\n    resultado = str1 + str2\r\n    return resultado\r\n\r\nprint (suma_str(\"Saludos a \", \"todos ustedes\"))\r\n\r\n#### Funciones incorporadas en Python\r\n\r\nprint()\r\n\r\na = 1234\r\nb = str(a)\r\nprint(len(b), \"es el largo de la variable a = 1234, que previamente debe pasarse a string con otra funcion de Python como str()\")\r\n\r\nprint()\r\n\r\n\r\n#### FUNCION SIMPLE Y EJEMPLO DE VARIABLE GLOBAL Y LOCAL\r\n\r\nmy_global_variable =\"Soy una variable global, llamame desde cualquier funcion\"\r\n\r\ndef saludo():\r\n    my_local_variable = \"Soy una variable local, no me llames desde fuera de esta funcion\"\r\n    print(\"Hola, soy una funcion!\")\r\n    print(my_global_variable)\r\n    print(my_local_variable)\r\n\r\n\r\nsaludo()\r\n\r\n#### Extra\r\n\r\ndef extra_02 (text1, text2):\r\n\r\n    for index in range(1,101):\r\n        if index % 3 == 0 and index % 5 == 0:\r\n           print(f\"{index}: {text1} {text2} Es múltiplo de 3 y 5\")\r\n        elif index % 3 == 0:\r\n           print(f\"{index}: {text1} Es múltiplo de 3\")\r\n        elif index % 5 == 0:\r\n            print(f\"{index}: {text2} Es múltiplo de 5\")\r\n        else:\r\n            print (index)\r\n\r\n    return index\r\n\r\n\r\nprint(f\"El numero se imprimió {extra_02(\"Texto 1\", \"Texto 2\")} veces\")\r\n\r\n# THE END. TO BE CONTINUED...\r\n\r\n\r\n\r\n\r\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/pakiuh.py",
    "content": "'''\r\n/*\r\n * EJERCICIO:\r\n * - Crea ejemplos de funciones básicas que representen las diferentes\r\n *   posibilidades del lenguaje:\r\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\r\n * - Comprueba si puedes crear funciones dentro de funciones.\r\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\r\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\r\n * - Debes hacer print por consola del resultado de todos los ejemplos.\r\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\r\n *\r\n * DIFICULTAD EXTRA (opcional):\r\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\r\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\r\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\r\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\r\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\r\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\r\n *\r\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\r\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\r\n */\r\n'''\r\n#funcion báisco sin parámetros ni retorno\r\n\r\ndef imprimir_hola():\r\n    print(\"Hola\")\r\nimprimir_hola()\r\n\r\ndef saludo_personal(nombre, apellido):\r\n    print(f\"¿Cómo esta Vd Sr {nombre} {apellido}?\")\r\n\r\nsaludo_personal(\"Francisco\", \"Camps\")\r\n\r\ndef sumar(num1, num2):\r\n    return num1+num2\r\n\r\nprint(f\"La suma de 3 y 5 es {sumar(3,5)}\")\r\n\r\ndef acciones_jarra(accion):\r\n    return f\"voy a {accion} la jarra\"\r\n\r\ndef que_hacer_jarra(accion, funcion_parametro):\r\n    print(f\"Voy a {accion} después de {funcion_parametro(\"abrirla\")}\")\r\n\r\nque_hacer_jarra(\"tirarla\", acciones_jarra)\r\n\r\n#funciones ya creadas por el lenguaje\r\n\r\nnombre = \"Paco\"\r\nprint(type(nombre))\r\nprint(hash(nombre))\r\n\r\ndef escribir_nombre(nom):\r\n    apellido = \"Camps\"\r\n    print(f\"el nombre es {nom} y el apellido es {apellido}\")\r\n\r\nescribir_nombre(nombre)\r\n\"\"\"\r\n * DIFICULTAD EXTRA (opcional):\r\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\r\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\r\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\r\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\r\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\r\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los texto\r\n\"\"\"\r\n\r\n\r\ndef fizz_buzz(palabra1, palabra2):\r\n    for i in range(101):\r\n        if i % 3 == 0 and i % 5 == 0:\r\n            print(f\"{palabra1}{palabra2}\")\r\n        elif i % 3 == 0:\r\n            print(palabra1)\r\n        elif i % 5 == 0:\r\n            print(palabra2)\r\n\r\nfizz_buzz(\"Gandalf\", \"Saruman\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/pcosin.py",
    "content": "# Funciones\n\n# Sin parámetros ni retorno\n\ndef saludar():\n    print(\"Hola, soy un saludo\")\n\nsaludar()\n\n# Con parámetros sin retorno\n\ndef suma(num1, num2):\n    \n    resultado = num1 + num2\n    print(resultado)\n\nsuma(4, 5)\n\n\n# Con parámetros y retorno\n\n\ndef suma_retorno(num1, num2):\n    \n    return num1 + num2\n\nprint(suma_retorno(4, 5))\n\n# Con parámetros opcionales\n\ndef area_circulo(radio, pi=3.14):\n    return pi * (radio ** 2)\n\nprint(area_circulo(5))\n\n# Con número variable de argumentos\n\ndef promedio(*args):\n    return sum(args) / len(args)\n\nprint(promedio(10,44,5,6,7))\n\n# Con retorno de varios valores\n\ndef varios_retornos():\n    return \"Paco\", \"Copa\"\n\nname, name2 = varios_retornos()\nprint(name)\nprint(name2)\n\n# Funciones anidadas\n\ndef operacion(cantidad, balance, tipo=\"deposito\"):\n    def deposito(cantidad, balance):\n        return cantidad + balance\n\n\n    def retiro(cantida, balance):\n        if cantidad < balance:\n            return balance - cantidad\n        else:\n            return None\n    \n    if tipo == \"deposito\":\n        return deposito(cantidad, balance)\n    elif tipo == \"retiro\":\n        return retiro(cantidad, balance)    \n\nprint(operacion(20, 40))\n\n# Funciones del lenguaje\n\nprint(len(\"La vida es una moneda\"))\nprint(type(True))\nprint(\"pcOSin\".lower())\n\n# Scope\n\nanimal = \"gato\" # variable global\n\npersona = \"Paco\" # variable global\n\ndef print_animal():\n    global persona # variable global\n    persona = \"Fernando\" \n    animal = \"perro\" # variable local\n    print(animal)\n    print(persona)\n    \nprint_animal()\n\nprint(animal)    \n\n#EXTRA\n\ndef FixBux(str1, str2):\n    count = 0\n    for num in range(1,100):\n        if num % 15 == 0:\n            print(f\"{str1}{str2}\")\n        elif num % 5 == 0:\n            print(str2)\n        elif num % 3 == 0:\n            print(str1)\n        else:\n            print(num)\n            count += 1\n    return count                 \n    \nFixBux(\"Fix\", \"Bux\")    "
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/pedro-blasco.py",
    "content": "# Funciones en python\n\n# Funcion sin retorno\ndef test():\n    print(\"Hola mundo\")\ntest()  # Llamada a la función\n\n# Funcion con retorno\ndef return_test():\n    return \"Hola mundo\"\nprint(return_test())  # Llamada a la función con retorno\n\n#Funcion con parametros\ndef parameters(name, age):\n    print(f\"Hola {name}, tienes {age} años\")\nparameters(\"Pedro\", 19)  # Llamada a la función con parámetros\n\n#Funcion con parametros por defecto\ndef parameters_default(name=\"Pedro\", age=19):\n    print(f\"Hola {name}, tienes {age} años\")\nparameters_default()  # Llamada a la función con parámetros por defecto\nparameters_default(\"Juan\", 25)  # Llamada a la función con parámetros personalizados    \n\n#Funcion dentro de otra función\ndef funcion_externa():\n    def funcion_interna():\n        print(\"Hola desde la función interna\")\n    funcion_interna()  # Llamada a la función interna\nfuncion_externa()  # Llamada a la función externa\n# funcion_interna()  # Error, la función interna no es accesible desde fuera de la función externa\n\n#Funcion con varios retornos\ndef varios_retornos(num):\n    if num > 0:\n        return \"Número positivo\"\n    elif num < 0:\n        return \"Número negativo\"\n    else:\n        return \"Número cero\"\nprint(varios_retornos(5))  # Llamada a la función con número positivo\nprint(varios_retornos(-3))  # Llamada a la función con número negativo\nprint(varios_retornos(0))  # Llamada a la función con número cero\n\n#Funcion con bucle for para distintos nombres\ndef nombres(nombres_list):\n    for nombre in nombres_list:\n        print(f\"Hola {nombre}\")\nnombres([\"Pedro\", \"Juan\", \"Maria\"])  # Llamada a la función con una lista de nombres\n\n#Funcion con claves y valores\ndef claves_valores(**names): # El ** indica que se pueden pasar un número indefinido de argumentos con clave-valor\n    for clave, valor in names.items(): # El método items() devuelve una lista de tuplas con las claves y valores del diccionario\n        print(f\"{clave}: {valor}\") # f sirve para formatear la cadena de texto, reemplazando las variables por su valor\n\nclaves_valores(\n    Nombre = \"Pedro\",\n    Edad = 19,\n    Nacionalidad = \"Argentino\"\n) # Llamada a la función con claves y valores\n\n#Funciones built-in (definidas por el lenguaje)\n\nprint(len(\"Hola mundo\"))  # Función len() para obtener la longitud de una cadena de texto en este caso devuelve 10\nprint(type(123))  # Función type() para obtener el tipo de dato de una variable en este caso devuelve <class 'int'>, si fuera 1.5 devolveria <class 'float'>, si fuera \"Hola\" devolvería <class 'str'>, etc\nprint(\"pedro-blasco\".upper())  # Función upper() para convertir una cadena de texto a mayúsculas, en este caso devuelve \"PEDRO-BLASCO\"\nprint(\"PEDRO-BLASCO\".lower())  # Función lower() para convertir una cadena de texto a minúsculas, en este caso devuelve \"pedro-blasco\"\nprint(\"Hola mundo\".split())  # Función split() para dividir una cadena de texto en una lista de palabras, en este caso devuelve [\"Hola\", \"mundo\"] \n\n# Variables Locales y Globales\n\nglobal_variable = \"Hola\"  # Variable global, se puede acceder desde cualquier parte del código\n\ndef local_variable():\n    local_variable = \"Python\"  # Variable local, solo se puede acceder dentro de la función\n    print(f\"{global_variable}, {local_variable}\")  # Imprime la variable local\n\nprint(global_variable)  # Imprime la variable global\nlocal_variable()  # Llamada a la función que imprime la variable local\n# print(local_variable) Da error, la variable local no es accesible desde fuera de la función\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n \"\"\"\n \ndef multiples(text1, text2):\n    count = 0\n    for num in range(1,101):\n        if num % 3 == 0 and num % 5 == 0:\n            print(f\"{text1} {text2}\") # Formatear el texto es una buena practica por si text1 y text2 no son cadenas de texto, de esta manera se convierten a string y no da error\n        elif num % 3 == 0:\n            print(f\"{text1}\")\n        elif num % 5 == 0:\n            print(f\"{text2}\")\n        else:\n            print(num)\n            count += 1\n    return count # Retorna el número de veces que se ha impreso el número en lugar de los textos\n\nprint(multiples(\"Texto1\", \"Texto2\"))  # Llamada a la función con los textos \"Fizz\" y \"Buzz\"\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/pguillo02.py",
    "content": "#Python tolera funciones de tipo void (sin return) y con return, no hace falta especificar a diferencia de otros lenguajes\n#Además las funciones admiten un número ilimitado de parámetros o ninguno\ndef sin_retorno(a, b):\n    print(a+b)\n\ndef con_retorno(c, d):\n    return c + d\n\ndef sin_parametros():\n    print(\"Esta es una función sin parametros\")\n\ndef con_parametros(e):\n    print(\"Este es el parametro a imprimir: \", e)\n\n#Se pueden crear funciones dentro de funciones\ndef funcion_interna():\n    def funcion_segunda():\n        print(\"hola\")\n\n    funcion_segunda()\n\n#También se pueden crear funciones que se llaman a si mismas, dentro de funciones\ndef recursiva(g):\n    if g != 10:\n        g += 1\n        print(g)\n        recursiva(g)\n    else:\n        print(\"final\")\n\n#Definición de variable local\ndef local(w):\n    local = 10\n    print(w+local)\n\n#Extra\ndef extra(texto1, texto2):\n    for item in range(1, 101):\n        if item%3 == 0 and item%5 == 0:\n            print(item, texto1, texto2)\n        elif item%5 == 0:\n            print(item, texto2)\n        elif item%3 == 0:\n            print(item, texto1)\n        else:\n            print(item)\n\n\n\n\nif __name__ == \"__main__\":\n    sin_retorno(2,2)\n    print(con_retorno(2,2))\n\n    sin_parametros()\n    con_parametros(\"hola\")\n\n    funcion_interna()\n    recursiva(1)\n\n    #Función propia del lenguaje\n    print(len([1,2,3]))\n\n    print(local)\n    local(2)\n\n    #Función lambda, sin cabecera\n    suma = lambda x, y: x + y\n\n    resultado = suma(3, 5)\n    print(resultado)\n\n    extra(\"uno\", \"dos\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/pipngpop.py",
    "content": "\"\"\"\nFunciones definidas por el usuario\n\"\"\"\n\n# Simple\ndef greet():\n    print(\"Hola, Python!\")\ngreet()\n\n\n# Con retorno\ndef return_greet():\n    return \"Hola, Pyhton!\"\ngreet = return_greet()\nprint(greet)\n\n\n# Con un argumento\ndef arg_greet(name):\n    print(f\"Hola, {name}!\")\narg_greet(\"Hosi\")\n\n\n# Con argumentos\ndef args_greet(greet, name):\n    print(f\"{greet}, {name}!\")\nargs_greet(\"Hola\",\"Hosi\")\nargs_greet(name=\"Hosi\",greet=\"Hola\") #si le digo qué es cada elemento, lo imprime en orden\n\n\n# Con un argumento predeterminado\ndef default_arg_greet(name=\"Hosi\"):\n     print(f\"Hola, {name}!\")\n\ndefault_arg_greet (\"Hosi\")\ndefault_arg_greet () #como no le hemos introducido un parámetro, imprime el por defecto\n\n\n# Con argumentos y retorno\ndef return_args_greet(greet, name):\n    return f\"{greet}, {name}!\"\n\nprint(return_args_greet(\"Hola\", \"Hosi\"))\n\n\n# Con retorno de varios valores\ndef multiple_return_greet():\n    return \"Hola\", \"Python\"\n\ngreet, name = multiple_return_greet()\nprint(greet)\nprint(name)\n\n\n# Con un número variable de argumentos\ndef variable_arg_greet(*names):\n    for name in names:\n        print(f\"Hola, {name}!\")\n\nvariable_arg_greet(\"Python\", \"Brais\", \"Comunidad\") #puedo pasar la cantidad de argumentos que me de la gana\n\n# Con un número variable de argumentos con palabra clave\ndef variable_key_arg_greet(**names): #cada argumento estará formado por una clave y un valor\n    for key,name in names.items():\n        print(f\"{name}({key})!\")\n\nvariable_key_arg_greet(\n    language=\"Python\",\n    name=\"Brais\",\n    alias= \"Moueredev\",\n    edad=36\n)\n\n\n'''\nFunciones dentro de funciones\n'''\n\ndef outer_function():\n    def inner_function():\n        print(\"función interna: Hola, Python !\")\n    inner_function()\n    \nouter_function()\n\n\n'''\nFunciones del lenguaje (built-in)\n'''\n\nprint(len(\"Mouredev\")) #nos cuenta la cantidad de datos\nprint(type(\"Mouredev\")) #nos dice el tipo de variable que es\nprint(\"Mouredev\".upper()) #modifica el dato y lo escribe en mayúscula\n\n\n'''\nVariables locales y globales\n'''\n\nglobal_var=\"Python\"\n\nprint(global_var)\n\ndef hello_python():\n    local_var = \"Hola\" #esta variable, como es local, solo funciona dentro de la función\n    print(f\"{local_var}, {global_var}!\")\n\n# print(local_var) No se puede acceder desde fuera de la función\n\nhello_python()\n\n\n'''\nExtra\n'''\n'''\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n'''\n\ndef print_numbers(text_1,text_2)->int: #la función devolverá un número entero al final\n    count = 0\n    for num in range (1, 101):\n        if num % 3 == 0 and num % 5 == 0:\n            print(text_1 + text_2)        \n        elif num % 3 == 0:\n            print(text_1)  \n        elif num % 5 == 0:\n            print(text_2) \n        else:\n            print(num)\n            count += 1\n    return (count)\n\nprint(print_numbers(\"Fizz\",\"Buzz\"))\n\n\n\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/pirrin22.py",
    "content": "# Funcion sin parametros y sin retorno.\ndef area_cuadrado():\n    lado = 6\n    print(f'El area de un cuadrado de un lado {lado} metros es {lado*lado}')\n\narea_cuadrado()\n\n# Funcion con un parametro y retorno.\ndef myname(name):\n    name = input('Ingresa tu nombre: ')\n    return f'Tu nombre es: {name}'\n\nprint(myname(input))\n\n# Funcion con 2 parametros\ndef area_triangulo(base, altura):\n    area = (base * altura) / 2\n    print(f'El area del triangulo es: {area}')\n\narea_triangulo(4, 3)\n\n# Funcion con 2 parametros y retorno.\ndef area_poligono(apotema, perimetro):\n    ar_pol = (apotema * perimetro) / 2\n    return f'El area del poligono es: {int(ar_pol)}'\n\nprint(area_poligono(4, 35))\n\n# Funcion dentro de Funcion.\n\ndef user():\n    def username(alias):\n        alias = input('Ingresa tu alias: ')\n        print(f'Este es tu alias {alias}')\n    username(input)\n\nuser()\n\n# Funciones ya creadas en el lenguaje.-\n\nprint(max(5, 7, 18))\n\nprint(len('Esto es una cadena de texto'))\n\nx = (5, 7, 9, 16)\nprint(sum(x))\n\n\n# Variuable Global dentro de una funcion.\n\ndef loc():\n    global y\n    y = ('Esto es una variable Global!')\n    print(y)\n\nloc()\nprint(y)\n\n# Variable local.\n\nage = 32\n\ndef myage(age):\n    age = input('Ingresa tu edad: ')\n    print(f'Tu edad segun la variable local {age}')\n\nmyage(input)\n\nprint(f'Tu edad segun la variable global {age}')\n\n\n# Ejercicio de dificultad extra.\n\ndef numeros(texto1, texto2):\n    num = 0\n    for numero in range(1, 101):\n       if numero % 3 == 0 and numero % 5 == 0:\n           print(texto1 + texto2)\n       elif numero % 3 == 0:\n           print(texto1) \n       elif numero % 5 == 0:\n           print(texto2) \n       else:\n           print(numero) \n           num += 1\n    return f'El numero se ha impreso {num} veces.'\n\nprint(numeros('fizz', 'buzz'))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/pyramsd.py",
    "content": "'''\nCrea ejemplos de funciones básicas que representen las diferentes posibilidades del lenguaje\n'''\ndef func_sinParametros_niRetorno():\n    result = 3 + 5\n    print(result)\nfunc_sinParametros_niRetorno()\n\n\ndef func_sinParametros_conRetorno():\n    result = 5 + 5\n    return result\nprint(func_sinParametros_conRetorno())\n\n\ndef func_conParametro_sinRetorno(a):\n    result = a + 5\n    print(result)\nfunc_conParametro_sinRetorno(6)\n\n\ndef func_conParametro_conRetorno(a):\n    result = a - 5\n    return result\nprint(func_conParametro_conRetorno(7))\n\n\ndef func_conParametros_sinRetorno(a, b):\n    result = a * b\n    print(result)\nfunc_conParametros_sinRetorno(2, 5)\n\n\ndef func_conParametros_conRetorno(a, b):\n    result = a * b\n    return result\nprint(func_conParametros_conRetorno(4, 5))\n\n\nprint()\n\n'''\nComprueba si puedes crear funciones dentro de funciones\n'''\ndef cuadrado_y_cubo(n1, n2):\n    \n    def cuadrado(n):\n        return n ** 2\n    \n    def cubo(n):\n        return n ** 3\n    \n    nAlCuadrado = cuadrado(n1)\n    nAlcubo = cubo(n2)\n\n    return nAlCuadrado, nAlcubo\nprint(cuadrado_y_cubo(4, 5))\n\nprint()\n\n'''\nUtiliza algún ejemplo de funciones ya creadas en el lenguaje.\nNOTA: \"print\" ya es una funcion creada del lenguaje, pero por las dudas usararé otras dos\n'''\n# funcion round\nprint(round(3.7))\n\n# funcion max\nlista = [12,35,453,46,8,45]\nprint(max(lista))\n\nprint()\n\n'''\nPon a prueba el concepto de variable LOCAL y GLOBAL.\n'''\n# NOTA: una variable local puede siempre estar fuera de funciones, pero no podrá ser modificada dentro de una.\n# * Para eso usamos 'global [nombre de la variable global]' dentro de una funcion para poder modificarlo.\n# * Y las varables locales no podrán ser llamadas fuera de su respectiva funcio funcion \nglob_var = 10\ndef func_globalLocal():\n    global glob_var\n    glob_var += 1\n    local_var = 12\n    print(f'{glob_var}, {local_var}')\nfunc_globalLocal()\n\nprint()\n\n'''\nExtra:\nCrea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n'''\ndef extra(s1: str, s2: str):\n    n_veces = 0\n    for i in range(1, 101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(f'{s1}{s2}')\n        elif i % 3 == 0:\n            print(s1)\n        elif i % 5 == 0:\n            print(s2)\n        else:\n            print(i)\n            n_veces += 1\n\n    return f'Se ha impreso el numero {n_veces} veces'\nprint(extra('arco', 'iris'))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/qv1ko.py",
    "content": "a = 5\n\ndef main():\n    func1()\n    print(func2())\n    func3(a, \"\\nParameterized and non-return function:\\nGlobal variable A: \")\n    print(func4(-4, \"\\nFunction with return and with parameters:\\nGlobal variable A: \"))\n\ndef func1():\n    b = 4\n    print(f\"\\nFunction without return and without parameters:\\nGlobal variable A: {a}\\nLocal variable B: {b}\")\n\ndef func2():\n    txt = \"\\nFunction with return and without parameters:\\nGlobal variable A: \" + str(a)\n    return txt\n\ndef func3(num, txt):\n    print(f\"{txt}{num}\")\n\ndef func4(num, txt):\n    text = txt + str(a) + \"\\nAbsolute number: \" + str(abs(num))\n    return text\n\nmain()\n\nprint(\"\\nProgram:\")\n\ndef program(zip, zap):\n\n    count = 0\n\n    for i in range(1, 100):\n        if i % 3 == 0 and i % 5 == 0:\n            print(zip + zap)\n        elif i % 3 == 0:\n            print(zip)\n        elif i % 5 == 0:\n            print(zap)\n        else:\n            count += 1\n    \n    return count\n\nprint(\"\\nNumber of times a text was not printed: \" + str(program(\"zip\", \"zap\")))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/qwik-zgheib.py",
    "content": "def fn_no_params_no_return() -> None:\n    print(\"fn_no_params_no_return\")\n\n\nprint(f\"example1: {fn_no_params_no_return()}\")\n\n\ndef fn_one_param_no_return(param1) -> None:\n    print(\"fn_one_param_no_return: \" + param1)\n\n\nprint(f\"example2: {fn_one_param_no_return('param1')}\")\n\n\ndef fn_params_return(param1: int, param2: int) -> int:\n    return param1 + param2\n\n\nprint(f\"example3: {fn_params_return(1, 2)}\")\n\n\ndef fn_params_return(*params: int) -> int:\n    return sum(params)\n\n\nprint(f\"example4: {fn_params_return(1, 2, 3, 4, 5)}\")\n\n\ndef fn_outside():\n    def fn_inside():\n        print(\"fn_inside\")\n\n    fn_inside()\n\n\nprint(f\"example5: {fn_outside()}\")\n\n\ndef all(iterable):\n    for element in iterable:\n        if not element:\n            return False\n    return True\n\n\nprint(f\"example6: {all([True, True, True])}\")\n\n\ndef fn_local_global():\n    global global_var\n    global_var = 1\n    local_var = 2\n    print(f\"global_var: {global_var}\")\n    print(f\"local_var: {local_var}\")\n\n\nprint(f\"example7: {fn_local_global()}\")\nprint(f\"global_var: {global_var}\")\n\n\n# -- extra challenge\ndef fn_challenge(param1: str, param2: str) -> int:\n    for i in range(1, 101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(param1 + param2)\n        elif i % 3 == 0:\n            print(param1)\n        elif i % 5 == 0:\n            print(param2)\n        else:\n            print(i)\n    return 100\n\n\nprint(f\"extra chanllenge: {fn_challenge('param1', 'param2')}\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/ramon-almeida.py",
    "content": "\n\ndef extra(p1: list, p2: list):\n    count = 0\n    for i in range(1, 101):\n        if i % 3 == 0:\n            print(p1)\n        elif i % 5 == 0:\n            print(p2)\n        elif i % 3 == 0 and i % 5 == 0:\n            print(p1, p2)\n        else:\n            print(i)\n            count += i\n    return count\n\n\nextra(('animo', 'vamos'), ('tu puedes', 'estamos contigo'))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/ramxv.py",
    "content": "# Variables Globales\r\n\r\nglobal1 = \"Soy Global\"\r\n\r\n# Variables Locales\r\ndef var_local():\r\n    variable_local = \"Soy una Variable Local\"\r\n    print(f\"Variable Local: {variable_local}\")\r\n    print(f\"Variable Globla: {global1}\")\r\nvar_local()\r\n\r\n# Funciones sin parámetros ni retorno\r\n\r\ndef fun():\r\n    print(\"Hola, no tengo parámetros ni retorno nada\")\r\nfun()\r\n\r\n# Funcion con retorno\r\ndef return_func():\r\n    return \"Hola Mundo!\"\r\n\r\nprint(return_func())\r\n\r\n# Funcion con argumento\r\ndef arg_saludo(nombre):\r\n    print(f\"Hola, {nombre}\")\r\n\r\narg_saludo(\"Ram\")\r\n\r\n# Argumentos predeterminados\r\ndef args_pred(nombre=\"Python\"):\r\n    print(f\"Hola, {nombre}\")\r\nargs_pred(\"Ram\")\r\nargs_pred()\r\n\r\n# Retorno de varios valores\r\ndef multiple_return_func():\r\n    return \"Hola\", \"Retorno\", \"Multiples Variables\"\r\n\r\nhola, retorno, variables = multiple_return_func()\r\nprint(hola) \r\nprint(retorno)\r\nprint(variables)\r\n\r\n# Argumentos de longitud variable\r\ndef suma(*nums):\r\n    print(type(nums))\r\n    total = 0\r\n    for num in nums:\r\n        total += num\r\n    return total\r\n\r\nprint(suma(1,2,3,4,5))\r\n\r\n# Argumentos clave valor\r\ndef key_val_func(**kwargs):\r\n    for k, val in kwargs.items():\r\n        print(f\"{k} = {val}\")\r\n\r\nkey_val_func(\r\n    nombre = \"Ram\",\r\n    lenguaje = \"Python\",\r\n    edad = 22,\r\n    alias = \"ramxv\"\r\n)\r\n\r\n# Funcion dentro de funcion\r\ndef outer_func():\r\n    print(\"Funcion padre\")\r\n    def inner_func():\r\n        print(\"Funcion hija\")\r\n    inner_func()\r\nouter_func()\r\n\r\n# Funciones del lenguaje\r\nprint(type(\"Hola soy Python\"))\r\nprint(len(\"Hola soy Python\"))\r\nprint(\"Hola soy Python\".lower())\r\n\r\n# Extra\r\n\r\nprint(\"#\"*40)\r\n\r\ndef multiplos(cadena1, cadena2) -> int:\r\n    count = 0\r\n    for i in range(1, 101):\r\n        if i % 3 == 0 and i % 5 == 0:\r\n            print(cadena1 + cadena2)\r\n        elif i % 3 == 0:\r\n            print(cadena1)\r\n        elif i % 5 == 0:\r\n            print(cadena2)\r\n        else:\r\n            print(i)\r\n            count += 1\r\n    print(\"Cantidad =\", end=\" \")\r\n    return count\r\n\r\nprint(multiplos(\"Hola\",\"Python\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/rantamhack.py",
    "content": "#!/usr/bin/python3 \n\n==================== FUNCION SIN ARGUMENTOS Y SIN RETORNO ====================\n\ndef hola_mundo():\n    print(\"Hola mundo!!\")\n\nhola_mundo() \n\n==================== FUNCION CON 1 ARGUMENT0 SIN RETORNO ====================\n\ndef hola_lenguaje(lenguaje):\n    print(f\"Hola mundo!! mi lenguaje de programación favorito es {lenguaje}\")\n\nhola_lenguaje(\"Python\") \n\n==================== FUNCION CON 2 ARGUMENTOS SIN RETORNO ====================\n\ndef presentacion(nick, lenguaje):\n    print(f\"Hola mundo!! soy {nick} y mi lenguaje de programación favorito es {lenguaje}\")\n\npresentacion(\"rantamplan\", \"Python\") \n\n==================== FUNCION CON 2 ARGUMENTOS Y CON RETORNO ====================\n\ndef publicacion(año, lenguaje):\n    edad = 2024 - año\n    print(f\"El lenguaje {lenguaje} se publicó en {año}\")\n    if edad >= 18:\n        return print(f\"El lenguaje {lenguaje} es adulto, tiene {edad} años\")\n    else:\n        return print(f\"El lenguaje {lenguaje} es aún muy reciente, tiene {edad} años\")\n\npublicacion(1991, \"Python\") \n\n==================== FUNCION DENTRO DE FUNCION ====================\n\nmy_list = [1, 2, 3, 4]\nn=5\n\ndef base(my_list):\n    def exponente(n):\n        for i in my_list:\n            print(i**n)\n    exponente(n)\nbase(my_list)        \n\n==================== FUNCION PROPIA DE PYTHON ====================\n\nmy_text = \"La primera función contará los caracteres de esta frase y la segunda los pondrá en mayúsculas\"\n\ndef contar_caracter():\n    print(len(my_text))\n    print(my_text.upper())\n\ncontar_caracter()\n\n==================== VARIABLES GLOBALES Y LOCALES ====================\n\n# Variable global, está fuera de las funciones y puede ser llamada por cualquier\n# parte del código\n# La variable local está dentro de la función y solo puede usarse dentro de ella\n\nn = 5  # Variable global\n\ndef multiplicar(numero):\n    b = 3  # Variable local\n    return numero * b\n\nprint(multiplicar(4))\nprint(n)\n# print(b) Esto nos daría error como variable no definida\n\n==================== EJERCICIO EXTRA ====================\n\ntext1 = \"multiplo de 3\"\ntext2 = \"multiplo de 5\"\n\ndef num_impress(text1, text2):\n    contador = 0\n    for i in range(1, 101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(f\"Es {text1} y {text2}\") \n        elif i % 3 == 0:\n            print(f\"Es {text1}\")\n        elif i % 5 == 0:\n            print(f\"Es {text2}\")\n        else:\n            contador +=1\n            print(i)\n\n    print(f\"Hay {contador} números que no son {text1} ni {text2}\")\n\nnum_impress(text1, text2)\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/raulG91.py",
    "content": "#Function without parameters and without return\ndef say_hello():\n    print(\"Function without parameters and return!\")\n    \nsay_hello()    \n\n#Function with parameters and return \ndef sum_numbers(a,b):\n    return a + b\n\nprint(\"Result function with parameters and return: \" + str(sum_numbers(3,5)))\n\n#Function with parameters but no return\n\ndef print_sum_numbers(a,b):\n    print(\"Result is: \" + str(a+b))\n    \nprint(\"Function with parameters but no return :\")\nprint_sum_numbers(2,3)    \n\n#Function with default parameter\n\ndef default_parameter(phrase = \"Default parameter\"):\n    return phrase\n    \nprint(\"Function with default parameter: \",default_parameter())\nprint(\"Function with default parameter: \",default_parameter(\"Modify default parameter\"))\n\n\n#Lambda function\n\nf = lambda: \"Message from a lambda function\"\n\nprint(\"Lambda function : \" + str(f()) )   \n\n#Function with multiple arguments\n\ndef multiple_arguments(*args):\n    for pos,argument in enumerate(args):\n        print(\"Argument in pos: \" + str(pos) +\" \"+ str(argument))\nprint(\"Function with multiple arguments: \")\nmultiple_arguments(\"Hello\")\nmultiple_arguments(\"Open\",\"Close\")        \n        \ndef multiple_arguments_keyword(**kargs):\n    for key in kargs:\n        print(\"Parameter key: \" + str(key) + \" parameter: \" + str(kargs[key]))\n        \nmultiple_arguments_keyword(string_parameter=\"Hi\", number_parameter=5)       \n\n\ndef wrap_function():\n    \n    a = 5 \n\n    def nested_function():\n        return a**2\n    \n    result = nested_function()\n    return result\n\nprint(\"Result of wrap/nested function: \" + str(wrap_function()))\n\nGLOBAL_VARIABLE = 3\n\nnumber_variable = 3\n\ndef modify_variable():\n    number_variable = 6\n    print(\"Value is: \",number_variable)\n\nmodify_variable()\nprint(\"Value is: \", number_variable)    \n\n#Language functions\n\ntext = \"This is a text\"\nprint(\"Funcrion Len:\" + str(len(text)))\n\nprint(\"Uppercase function: \",  text.upper())\n\n\n\nnumber_list = [5,2,6,16,7,3]\nfiltered_list = filter(lambda x: x%2 == 0,number_list)\nprint(\"Filter and list function\", list(filtered_list))\n\ndef extra_exercise(arg1,arg2):\n    \n    counter = 0\n    \n    for number in range(1,101):\n        \n        if number % 3 == 0 and number % 5 == 0:\n            print(arg1+arg2)\n        elif number % 3 == 0:\n            print(arg1) \n        elif number % 5 == 0:\n            print(arg2)\n        else:\n            print(number)\n            counter+=1\n    return counter\n\nnumbers = extra_exercise(\"fizz\",\"buzz\")\nprint(numbers)        \n            \n    "
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/raulallue.py",
    "content": "'''\nEJERCICIO:\n- Crea ejemplos de funciones básicas que representen las diferentes\nposibilidades del lenguaje:\nSin parámetros ni retorno, con uno o varios parámetros, con retorno...\n- Comprueba si puedes crear funciones dentro de funciones.\n- Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n- Pon a prueba el concepto de variable LOCAL y GLOBAL.\n- Debes hacer print por consola del resultado de todos los ejemplos.\n(y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n\nDIFICULTAD EXTRA (opcional):\nCrea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n- La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n- Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n- Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n- Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n- La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\nPresta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\nCada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n'''\n\n#------------------FUNCIOINES SIN PARAMETROS, NI RETORNO-----------------\n\ndef func():\n    print(\"Función básica\")\n\nfunc()\n\n#Función con parámetros\ndef suma(a,b):\n    print(a+b)\n\nsuma(2,3)\n\n#------------------FUNCIONES CON RETORNO---------------------------------\n\ndef suma(a,b):\n    return(a+b)\nresultado = suma(4,3)\nprint(resultado)\n\n#------------------FUNCIONES DENTRO DE FUNCIONES GLOBAL------------------\n\ndef resta_suma(a,b):\n    def resta(a):\n        return(a-1)\n    resultado = resta(a)+b\n    return resultado\n\nprint(resta_suma(5,7))\n\n#------------------FUNCIONES DEL SISTEMA---------------------------------\n\ntexto = \"esto es una cadena de texto\"\n\nprint(texto.title())\nprint(texto.upper())\nprint(texto.capitalize())\nprint(len(texto))\n\n#------------------VARIABLE LOCAL----------------------------------------\n\ndef resta():\n    num1 = 6\n    num2 = 2\n    resultado = num1 - num2\n    print(resultado)\n    \nresta()\n\n#Esto daria error puesto que la variable num1 solo tiene validez dentro del #ambito de la función.\n#print(num1)\n\n#------------------VARIABLE GLOBAL----------------------------------------\n\nnum4 = 2\ndef multipl():\n    global num3\n    num3 = 7\n    resultado = num3 * num4\n    print(resultado)\n    \nmultipl()\n\n#En este caso la variable declarada como global es accesible desde el exterior de la funcion\nprint(num3)\n\n#Las variables declaradas fuera de funciones también se consideran globales puesto que son accesibles fuera y dentro de las funciones.\nprint(num4)\n\n#------------------DIFICULTAD EXTRA----------------------------------------\n\ndef imprime_num(text1,text2):\n    num_veces = 0\n    for x in range(1,102):\n        if x % 3 == 0 and x % 5 == 0:\n            print(f\"número:{x} - {text1} {text2}\")\n        elif x % 5 == 0:\n            print(f\"número:{x} - {text2}\")\n        elif x % 3 == 0:\n            print(f\"número:{x} - {text1}\")\n        else:\n            print(f\"número:{x}\")\n            num_veces += 1\n    print(f\"número de veces que se imprime solo el número: {num_veces}\")\n    \nimprime_num(\"hola\",\"adios\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/rayn1er.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * - Crea ejemplos de funciones básicas que representen las diferentes\n#  *   posibilidades del lenguaje:\n#  *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n#  * - Comprueba si puedes crear funciones dentro de funciones.\n#  * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n#  * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n#  * - Debes hacer print por consola del resultado de todos los ejemplos.\n#  *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n#  * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n#  *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n#  *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n#  *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n#  *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n#  *\n#  * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n#  * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n#  */\n\n\n# en python declaramos una funcion con la palabra reservada def, seguida de sus argumentos(en caso de que los reciba) y dos puntos (:)\n\ndef first_function(): #esta es una funcion sencilla que no recibe parametros\n    print(\"I am a function!\")\n\nfirst_function() #para ejecutar una funcion tenemos que llamarla, esto lo hacemos simplemente escribiendo su nombre acompanado de parentesis, al ejecutar el codigo nos muestra en pantalla (\"soy una funcion!\")\n\ndef say_hi(name): #las funciones pueden recibir parametros, en este caso un nombre para devolver un saludo junto a dicho nombre\n    print(f'Hi {name}')\n\nsay_hi(\"Raul\") # llamamos y le entregamos el parametro que en este caso es mi nombre, muestra por pantalla el saludo\n\ndef sum_two_numbers(n1,n2): # en este caso esta funcion recibe dos parametros\n\n    return n1+n2 #usamos la palabra reservada return para devolver la suma de los dos numeros recibidos\n\nprint(sum_two_numbers(2,2)) #como queremos mostrar por consola el resultado de la funcion, utilizamos print, puesto que la funcion en si devuelve un dato, no un print con el resultado\n\ndef future_function():\n    pass #podemos tambien utilizar la palabra reservada pass para indicar que implementaremos codigo\n\ndef args_two_numbers(n1 = 2, n2= 2): #tambien podemos agregar valores por defectos a los argumentos en caso de requerirlo\n    return  n1 + n2\n\nprint(args_two_numbers()) #si ejecutamos esto tendremos 4, puesto que ambos valores valen 2\nprint(args_two_numbers(7,7)) # en este caso nos devuelve 14, ya que le hemos asignado parametros\nprint(args_two_numbers(7)) #aca nos ejecuta nueve, ya que al faltarnos un parametro, la funcion ejecuta el que tiene por defecto\n\ndef infinite_args_numbers(*args): #podemos utilizar ** para indicarle a la funcion que espere multiples valores los cuales se alamacenan en una tupla, esto para realizar operaciones en las que no sabemos cuantos argumentos necesitamos, como por ejemplo sumar multiples numeros\n    return sum(args)\n\nprint(infinite_args_numbers(10,10,10)) #devuelve la suma de todos los argumentos que le hemos pasado\n\n\ndef infinite_items(**kwargs): #para los kwargs tenemos lo mismo, con la diferencia de que estos se almacenan en un diccionario\n    return kwargs\n\nprint(infinite_items(car = 'toyota', shoes = 'nike', sports = 'soccer')) #devuelve el diccionario junto con sus valores\n\ndef event_cronogram(event, *args, **kwargs): #tambien podemos combinar todos los elementos en una funcion, como por ejemplo el nombre de un evento junto con su agenda y sus jueces\n    return event, args,kwargs \n\nprint(event_cronogram('anime festa', 'dance tournament', 'sing tournament', 'draw tournament', dance_judge = 'yoel', sing_judge = 'mariana', draw_judge = 'runny'))\n\n#funciones dentro de funciones\n\ndef main_function(): #en python podemos anidar funciones dentro de otras, en este caso esta sera nuestra funcion principal\n    def sub_function(): #dentro encontramos nuestra funcion secundaria\n        print(\"I am a sub function\")\n\n    sub_function() #llamamos a la funcion\n\nmain_function() #ejecutamos nuestra funcion nos ejecutara el codigo de la funcion anidada que hemos llamado dentro de la funcion principal\n\n#funciones integradas de python\n\nprint(\"hola\") #la funcion hola que venimos utilizando desde el principio es una funcion integrada de python\nprint(sum([10,20,20])) #sum tambien es otra funcion integrada de python y nos sirve para sumar elementos iterables\nprint(type(\"python\")) #la funcion type tambien es una integrada de python, y nos devuelve el tipo del objeto que le hemos entregado\n\n#variables locales\n\nglobal_variable = \"Global variable\" #en python una variable global es aquella que se declara fuera de una funcion y podemos utilizarla en cualquier funcion\n\ndef print_variable():\n    print(global_variable)\n\nprint_variable() #ejecutamos para imprimir la variable global\n\ndef print_local_variable():\n    local_variable = 'Local variable' #dentro de las funciones nos encontramos las variables locales, las cuales solo existen dentro de la funcion y no puede utilizarle fuera\n    print(local_variable)\n\nprint_local_variable() #en este caso nos imprime la variable local de la funcion, que es \"local variable\".\n\ndef extra_function(string1, string2):\n    total_numbers = 0\n    for i in range(1,101):\n\n        if i % 3 == 0 and i % 5 == 0:\n            print(string1+string2)\n        elif i %  3 == 0:\n            print(string1)\n        elif i % 5 == 0:\n            print(string2)\n        \n        \n        else:\n            print(i)\n            total_numbers += 1\n    \n    return f\"La cantidad de veces que se ha impreso un numero es de {total_numbers}\"\n   \n\nprint(extra_function('python','3'))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/raynerpv2022.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n\"\"\"\n\ndef func_sin_p():\n  print(\"hoy es   6 de agosto\")\n\ndef func_1_p(mes):\n  print(f\"hoy es  6 de {mes}\")\n\ndef func_2_p(dia, mes):\n  print(f\"hoy es  {dia} de {mes}\")\n\ndef func_value_default(dia = 26,mes=\"enero\"):\n  print(f\"hoy es  {dia} de {mes}\")\n\ndef func_value_dmult(dia = 26,mes=\"enero\"):\n  return dia, mes\n\ndef func_par_var(*var):\n  \n  if len(var) >0:\n    print(f\" existen {len(var)} parametros\")\n    for i in var:\n        print(i)\n  else :\n    print(\"No existen Parametros\")\n\ndef func_k_v(** data):\n  for k,v in data.items():\n    print(f\"key : {k}, value : {v}\")\n\n\n\n\n#  Dificultad Extra\ndef print_number(cad1, cad2):\n number = 0\n for i in range(1, 101):\n   \n   if i % 3 ==0 and i % 5 ==0:\n     print(cad1+\" \"+cad2)\n   elif i % 3 == 0 :\n      print(cad1)\n   elif i % 5 == 0:\n     print(cad2)\n   else:\n     number+=1\n     print(i)\n return number\n\nprint(print_number(\"TRES\",\"CINCO\"))\nfunc_sin_p()\nfunc_1_p(\"enero\")\nfunc_2_p(6,\"diciembre\")\nfunc_value_default(22,\"diciembre\")\nfunc_value_default()\ndia = func_value_dmult()[0]\nmes = func_value_dmult()[1]\nprint(dia, mes)\nfunc_par_var(1,2,3,4,5)\nfunc_par_var()\nfunc_k_v(a=1,b=2,c=3)\n\n# local y global variables\nglobal_var = \"ray\"\nprint(\"Global \", global_var)\n\ndef local_Function():\n  global_var = \"21\"\n  print(\"LOcal variable\", global_var)\nlocal_Function()\nprint(\"Global \", global_var)\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/restevean.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n * - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n * - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n * - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n * - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue unas convenciones que debes de respetar para que el código se entienda.\n\"\"\"\n\n\n# Function without parameters or return\ndef greet():\n    print(\"Hello, world!\")\n\n\n# Function with one parameter without return\ndef greet_person(name):\n    print(f\"Hello, {name}!\")\n\n\n# Function with multiple parameters without return\ndef greet_person_in_language(name, language):\n    greetings = {\"English\": \"Hello\", \"Spanish\": \"Hola\", \"French\": \"Salut\"}\n    print(f\"{greetings[language]}, {name}!\")\n\n\n# Function with return\ndef add_numbers(a, b):\n    return a + b\n\n\n# Function within a function\ndef outer_function():\n    def inner_function():\n        print(\"Hello from the inner function!\")\n\n    inner_function()\n\n\n# Test of local and global variables\nglobal_var = \"I'm a global variable\"\n\n\ndef test_variables():\n    local_var = \"I'm a local variable\"\n    print(f\"\\n{local_var}, {global_var}.\")\n\n\n# Call to the functions\ngreet()\ngreet_person(\"Alice\")\ngreet_person_in_language(\"Alice\", \"Spanish\")\ngreet_person_in_language(\"John\", \"French\")\ngreet_person_in_language(\"Helen\", \"English\")\nprint(add_numbers(2, 3))\nouter_function()\ntest_variables()\n\n# Use of a built-in function\ntext = \"Using a built-in function, print()\"\nprint(text)\n\n# Extra difficulty\nprint(\"\\nExtra difficulty:\")\n\n\ndef print_numbers_and_strings(str1, str2):\n    my_count = 0\n    for number in range(1, 101):\n        if number % 3 == 0 and number % 5 == 0:\n            print(str1 + str2)\n        elif number % 3 == 0:\n            print(str1)\n        elif number % 5 == 0:\n            print(str2)\n        else:\n            print(number)\n            my_count += 1\n    return f\"Total elements printed {my_count}\"\n\n\n# Call the function\nprint(print_numbers_and_strings(\"Fizz\", \"Buzz\"))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/rianojnicolas.py",
    "content": "import random\n\n# Variable global y funcion ya creada por el lenguaje\nvariableGlobal = \"Paso por aca, a desearte muchos exitos!!!\\n\"\nvariableGlobal = variableGlobal.upper()\n\n# (Funcion sin parametros ni retorno)\n# Funcion de bienvenida\ndef welcomePlayer():\n    print(\"\"\"\n        Hola People !!, este es un juego improvisado de\n        piedra, papel o tijera.\n        \n        las reglas son las siguientes:\n        \"\"\")\n    # Funcion dentro de otra funcion\n    def reglas():\n        print(\"\"\"\n            1. Debes ingresar el objeto con el que jugaras\n            2. El pc elegira aleatoriamente un objeto\n            3. Recuerda que: papel le gana a piedra,\n                            piedra le gana a tijera,\n                            tijera le gana a papel.\n            \n            Muchos Exitooooss !!!\n            \"\"\")\n    reglas()\n\n\n# Funcion sin parametros con retorno\n# Funcion para pedir el objeto a jugar\ndef functionInput():\n    option = input(\"Ingresa tu objeto con el que vas a jugar: \")\n    while(option != \"piedra\" and option != \"tijera\" and option != \"papel\"):\n        option = input(\"Ingresa tu objeto con el que vas a jugar: \")\n    return option\n\n\n# (Funcion con un parametro y sin retorno)\n# Funcion competencia\ndef playCompetition(optionPlayer):\n    # Concepto de Variable Local\n    optionList = [\"piedra\", \"papel\", \"tijera\"]\n    optionPC = random.choice(optionList)\n    print(f'la opcion del pc fue: {optionPC}\\n')\n    if (optionPC == optionPlayer):\n        print(\"Emptados\")\n    elif (optionPC == \"papel\"):\n        if (optionPlayer == \"piedra\"):\n            print(\"perdiste\")\n        elif(optionPlayer == \"tijera\"):\n            print(\"ganaste\")\n    elif(optionPC == \"tijera\"):\n        if (optionPlayer == \"papel\"):\n            print(\"perdiste\")\n        elif (optionPlayer == \"piedra\"):\n            print(\"ganaste\")\n    elif(optionPC == \"piedra\"):\n        if (optionPlayer == \"papel\"):\n            print(\"ganaste\")\n        elif (optionPlayer == \"tijera\"):\n            print(\"perdiste\")\n\n\ndef run():\n    welcomePlayer()\n    print(variableGlobal)\n    option_player = functionInput()\n    playCompetition(option_player)\n\n\ndef extraDifficult(param1, param2):\n    contador = 0\n    for i in range(0,101):\n        if (i%3 == 0 and i%5 == 0):\n            print(f'para el numero {i}: {param1} {param2}')\n        elif(i%3 == 0):\n            print(f'para el numero {i}: {param1}')\n        elif(i%5 == 0):\n            print(f'para el numero {i}: {param2}')\n        else:\n            contador += 1\n            print(f'para el numero {i} no hay texto')\n    return contador\n\n\nif __name__ == '__main__':\n    run()\n    print(\"\\nAhora vamos con el ejercicio extra\\n\")\n    print(extraDifficult(\"hola\",\"mundo\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/rigo93acosta.py",
    "content": "#02 FUNCIONES Y ALCANCE\n\n'''\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n'''\n##\ndef func_1():\n    print(\"Hola, funcion simple\")\nfunc_1()\n\n## \ndef func_2(val):\n    print(f'Parametro de entrada: {val}')\nfunc_2(\"Hola\")\n\n##\ndef func_3(val):\n    return val\nprint(f'Un argumento, un retorno {func_3('Parameter')}')\n\n##\ndef func_4(val = \"Hola\"):\n    print(f\"{val} mundo!!\")\nfunc_4()\n\n##  \ndef func_5(val_1, val_2):\n    return val_1, val_2\nprint(f'Dos arguments, un retorno {func_5('Hola', 'Mundo')}')\nprint(f'Dos arguments, un retorno {func_5(val_2='Mundo', val_1='Hola')}')\nval_1, val_2 = func_5('Hola', 'Mundo')\nprint(f'Dos arguments, un retorno {val_1} y {val_2}')\n\n## Numero variables de argumentos\ndef func_6(*names):\n    for name in names:\n        print(name)\n\nfunc_6(\"H\", \"o\", \"l\",\"a\")\n\n##\ndef func_7(**args):\n    for key in args:\n        print(f\"Hola, {args[key]} ({key})!\")\n\nfunc_7(language=\"Python\", name=\"Rigo\", alias=\"rigo93acosta\", age=30)\n\n##\ndef outer_func():\n    def inner_function():\n        print(\"Funcion interna: Hola, Python\")\n    inner_function()\n\nouter_func()\n\n##\nprint(len(\"Rigo\"))\nprint(type(36))\nprint(\"Rigo\".upper())\n\n##\nglobal_varible = \"Python\"\nprint(global_varible)\n\ndef func_8():\n    local_var = \"Hola\"\n    print(f\"{local_var}, {global_varible}\")\nfunc_8()\n# print(local_var)\n\n## Extra\ndef func_extra(var_1, var_2)-> int:\n    counter = 0\n    for number in range(1, 101):\n        if number % 3 == 0 and number % 5 == 0:\n            print(var_1)\n        elif number % 5 == 0:\n            print(var_2)\n        elif number % 3 == 0:\n            print(f'{var_1} {var_2}')\n        else:\n            counter += 1\n            print(number)\n        \n    return counter\n\nprint(func_extra(\"Fizz\", \"Buzz\"))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/rikmij.py",
    "content": "import colorama\n\ncolor_green = colorama.Fore.GREEN\ncolor_blue = colorama.Fore.BLUE\ncolor_grey = colorama.Fore.BLACK\ncolor_red = colorama.Fore.RED\nend_color = colorama.Fore.RESET\n\nprint(color_grey,'\\n--> Función sin parámetros ni retorno:', end_color)\ndef funcion_1():\n    print(\"Hola, soy una función sin parametros ni retorno\")\n\nfuncion_1()\n\n\nprint(color_grey, '\\n--> Función con 1 parámetro:', end_color)\ndef funcion_2(text):\n    print(text)\n\nfuncion_2(\"Hola, soy una función con 1 parámetro\")\n\n\nprint(color_grey, '\\n--> Función con varios parámetros:', end_color)\ndef funcion_3(*args):\n    print(f\"Hola, soy {args[0]} y tengo {args[1]} años. Quiero decir:\\n{args[2]}\")\n\nfuncion_3(\"Rick\", 26, \"Graaande MoureDev!!\")\n\n\nprint(color_grey, '\\n--> Función con retorno:', end_color)\ndef funcion_4(a, b):\n    return a+b\n\nfuncion_4(3,3)  #no imprime\nprint(funcion_4(2,3))   #sí imprime\n\n\nprint(color_grey, '\\n--> Función anónima / Función lambda:', end_color)\nsaludo = (lambda a: f\"Soy una función lambda, {a}\")\nprint(saludo(\"el argumento\"))\n\n\nprint(color_grey, '\\n--> Función recursiva:', end_color)\ndef funcion_5(num):\n    if num == 0:\n        return 1\n    else:\n        return num * funcion_5(num-1)\n\nprint(funcion_5(5))\n\n\nprint(color_grey, '\\n--> Función generadora:', end_color)\ndef funcion_6(num):\n    while num < 9:\n        num = num+1\n        yield num\n\n'''n = funcion_6(3)\nprint(next(n))\nprint(next(n))'''   #con esto elijo imprimir 2 valores\n\nfor n in funcion_6(3):\n    print(n)\n\n\nprint(color_grey, '\\n--> Función decoradora:', end_color)\ndef decor(funcion):\n    def decora_funct(a,b):\n        print(\"El resultado es:\")\n        funcion(a,b)\n        print(\"Ya está\")\n    return decora_funct\n\n@decor\ndef suma(a,b):\n    print(a+b)\n\nsuma(2,3)\n\n\nprint(color_blue, '\\n--> Sí se puedes crear funciones dentro de funciones, se llaman \"funciones anidadas\":', end_color)\ndef numeros(num):\n    \n    def suma():\n        return num + 3\n    \n    def resta():\n        return num - 2\n    \n    def multip():\n        return num * 3\n    \n    #podríamos hacer un return de cualquiera y funcionaría, pero encadenemos 2\n\n    def div():\n        return multip()/2\n    \n    return div()\n\nprint(numeros(4))\n\n\nprint(color_green, '\\n--> Uso de Variables Globales y Locales:', end_color)\nname = \"Brais\"\n\ndef presentation():\n    name = \"Rick\"\n    age = 26\n\n    return(f\"Hola, soy {name} y tengo {age} años\")\n\nprint(name) #funciona, es una variable GLOBAL (está fuera de la función y se puede usar donde se quiera)\n#print(age) da error, es una variable LOCAL (dentro de la función)\n\nprint(presentation())\n\n\nprint(color_blue, '\\n--> Función del sistema:', end_color)\nnums = [21, 33, 9]\n\nprint(max(nums))    #tanto print() como max() son funciones del sistema\n\n\nprint(color_red,'\\n','*'*13, \"EXTRA\", '*'*13, end_color)\ndef extra():\n    t1 = \"Py\"\n    t2 = \"Thon\"\n    contador_nums = 0\n    contador_t1 = 0\n    contador_t2 = 0\n    contador_t12 = 0\n\n    for n in range(1,101):\n        if n%3 == 0 and n%5 == 0:\n            print(t1,\"+\",t2)\n            contador_t12 +=1\n    \n        elif n%3 == 0:\n            print(t1)\n            contador_t1 +=1\n    \n        elif n%5 == 0:\n            print(t2)\n            contador_t2 +=1\n        \n        else:\n            print(n)\n            contador_nums +=1\n    \n    return(f\"--> Hay en total '{contador_nums} números', '{contador_t1} Py', '{contador_t2} Thon' y '{contador_t12} PyThon'\")\n\nprint(extra())\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/saezMD.py",
    "content": "#02 FUNCIONES Y ALCANCE\n\n# Simple Python function \ndef printLog():\n    \"\"\"Create a print. \"\"\" #Docstring\n    return print(\"This is a console print\")\n\nprintLog()\n\n# Function with Parameters\ndef sumNumbers(number1: int, number2: int) -> int:\n    \"\"\"sum 2 numbers\"\"\"\n    numberResult = number1 + number2  \n    return print(f\"The sum of {number1} and {number2} results {numberResult}.\")\n\nsumNumbers(5,12)\n\n# Function Default Arguments\ndef func1(x, y=100):\n    print(\"X = \", x)\n    print(\"Y = \", y)\n\nfunc1(50)\nfunc1(50,20)\n \n# Function Keyword arguments (The idea is to allow the caller to specify the argument name with values so that the caller does not need to remember the order of parameters.)\ndef student(firstname, lastname):\n    print(firstname, lastname)\n\nstudent(firstname='Saez', lastname='MD')\nstudent(lastname='MD', firstname='Saez')\n\n\n# Function Arbitrary Keyword Arguments [*args in Python (Non-Keyword Arguments)] & [**kwargs in Python (Keyword Arguments)]\n# *args for variable number of arguments\ndef func2(*argv):\n    for arg in argv:\n        print(arg)\n \nfunc2('Hello', 'Welcome', 'to', 'myPage') \n\n# *kwargs for variable number of keyword arguments\ndef func3(**kwargs):\n    for key, value in kwargs.items():\n        print(\"%s == %s\" % (key, value))\n  \nfunc3(first='Saez', mid='MD', last='Webpage', final='.com')\n\n#Function within Functions\ndef funcOut():\n    s = 'This is a combo functions'\n    def funcIn():\n        print(s)        \n    funcIn()\n \nfuncOut()\n\n#Anonymous Functions in Python (the def keyword is used to define the normal functions and the lambda keyword is used to create anonymous functions)\ncube_v2 = lambda x : x*x*x\nprint(cube_v2(7))\n\n#Recursive Functions in Python\ndef factorial(n):\n    if n == 0:  \n        return 1\n    else:\n        return n * factorial(n - 1) \n       \nprint(factorial(6))\n      \n      \n#Built-in Functions:\ndef all(iterable):\n    for element in iterable:\n        if not element:\n            print(\"False\")\n            return False\n    print(\"True\")\n    return True\nall([12,2,3,4,5,6,7])\nall(\"home\")\n# all(0) ; FALSE\n\nprint(len(\"SaezMD\"))\nprint(type(36))\nprint(\"SaezMD\".upper())\n\n\n# Variables Globales y locales\ncounter = 10\n\ndef restartCounter():\n\tglobal counter\n\tcounter = 0\n\n\nprint(f'counter before is {counter}')\nrestartCounter()\nprint(f'counter after is {counter}')\n\n\nvalue = 10\n\ndef func10():\n\tvalue = 20\n\tprint(f'Inside value: {value}')\n\nfunc10()\nprint(f'Outside value: {value}')\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\nCrea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n- La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n  - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n  - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n  - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n  - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\nPresta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\nCada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n\"\"\"\ndef textFizzBuzz(text1: str, text2: str) -> int:\n    \"\"\"function to print all numbers from 1 to 100 (included). When number is divisible by 3/5 or both, there is a text. The return is the number of printed numbers.\"\"\"\n    numbersPrinted=0\n    for i in range(1,101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(\"-> %s%s\" % (text1, text2))\n            continue\n        if i % 3 == 0:\n            print(\"-> %s\" % (text1))\n            continue\n        if i % 5 == 0:\n            print(\"-> %s\" % (text2))\n            continue\n        else:\n            print(i)\n            numbersPrinted += 1\n    return print(numbersPrinted)\ntextFizzBuzz(\"bat\",\"woman\")\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/saicobys.py",
    "content": "\"\"\" 1. Funciones sin parámetros ni retorno: \"\"\"\ndef saludar():  \n    print(\"¡Hola desde una función!\")\n\nsaludar()  # Llamada a la función\n\n\"\"\" 2. Funciones con parámetros: \"\"\"\ndef saludar_con_nombre(nombre):\n    print(f\"¡Hola, {nombre}!\")\n\nsaludar_con_nombre(\"Ana\")  # Llamada con un argumento\n\n\"\"\" 3. Funciones con múltiples parámetros: \"\"\"\ndef sumar(a, b):\n    resultado = a + b\n    print(f\"La suma de {a} y {b} es: {resultado}\")\n\nsumar(5, 3)  # Llamada con dos argumentos\n\n\"\"\" 4. Funciones con retorno: \"\"\"\ndef calcular_area_rectangulo(base, altura):\n    area = base * altura\n    return area\n\narea = calcular_area_rectangulo(4, 6)\nprint(f\"El área del rectángulo es: {area}\")\n\n\"\"\" 5. Funciones dentro de funciones (anidadas): \"\"\"\ndef operacion_matematica(x, y):\n    def sumar(a, b):\n        return a + b\n\n    def restar(a, b):\n        return a - b\n\n    suma_resultado = sumar(x, y)\n    resta_resultado = restar(x, y)\n\n    print(f\"Suma: {suma_resultado}, Resta: {resta_resultado}\")\n\noperacion_matematica(8, 3)\n\n\"\"\" 6. Uso de funciones integradas: \"\"\"\nmensaje = \"Hola, mundo!\"\nlongitud = len(mensaje)  # Función len() para obtener la longitud de la cadena\nprint(f\"La longitud del mensaje es: {longitud}\")\n\n\"\"\" . Variables locales y globales: \"\"\"\nvariable_global = \"Soy global\"\n\ndef funcion_ejemplo():\n    variable_local = \"Soy local\"\n    print(\"Dentro de la función:\", variable_global, variable_local)\n\nfuncion_ejemplo()\nprint(\"Fuera de la función:\", variable_global)\n# print(\"Fuera de la función:\", variable_local)  # Error: variable_local no está definida fuera de la función\n\n\ndef fizzbuzz(texto_multiplo_3, texto_multiplo_5):\n    \"\"\"Imprime los números del 1 al 100 con reglas especiales y retorna el número de veces que se imprime un número en lugar de texto.\"\"\"\n    contador_numeros = 0\n\n    for numero in range(1, 101):\n        if numero % 15 == 0:  # Múltiplo de 3 y 5\n            print(texto_multiplo_3 + texto_multiplo_5)\n        elif numero % 3 == 0:  # Múltiplo de 3\n            print(texto_multiplo_3)\n        elif numero % 5 == 0:  # Múltiplo de 5\n            print(texto_multiplo_5)\n        else:  # No es múltiplo de 3 ni de 5\n            print(numero)\n            contador_numeros += 1  # Incrementa el contador si se imprime un número\n\n    return contador_numeros\n\nresultado = fizzbuzz(\"Fizz\", \"Buzz\")\nprint(f\"Número de veces que se imprimió un número: {resultado}\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/santiago434c.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n\"\"\"\n# Funcion Sin parametros ni retorno retorno\ndef funcion_simple():\n    a = 5\n    a += a\n    print(a)\n\n# Funcion con un parametro\ndef funcion_parametro(num):\n    num += 1\n    print(num)\n\n# Funcion con varios parametros\ndef funcion_varios_parametros(palabra, num):\n    str(palabra)\n    int(num)\n    print(\"Esta es tu palabra: \",palabra, \"y este es tu numero: \",num)\n\n#Funcion con arguemntos predeterminados\ndef predetermindos(name=\"Python\"):\n     print(f\"Hola, {name}\")\n\n# Funcion con retorno\ndef funcion_retorno(num1, num2):\n    num1 *=2\n    num2 %=5\n    result = num2 + num1\n    return result\n\n#Funcion con retorno de varios argumentos\ndef retorno_multiple():\n    return \"Hola\", \"python\"\n\n#Asignacion del return para imprimir\ngreet, name = retorno_multiple()\n\n#Funcion con numero variable de argumentos\ndef funcion_arg_multiples(*names):\n    for name in names:\n        print(f\"Hola, {name}\")\n\n#Funcion con un numero variable de arguemtos con palabra clave - Similar al diccionario\ndef funcion_multi_palabra_clave(**names):\n    for key, value in names.items():\n        print(f\"{value} ({key})!\")\n\n#Funciones dentro de funciones?\ndef externa():\n    def interna():\n        print(\"Funcion interna: Sapo perro\")\n    interna()\n\n#Funciones del leguaje (built-in)\n#Logitud\nprint(len(\"Hola\"))\nprint(type(36))   \nprint(\"Hola\".upper())\n\n#Variable Local y Global\n\"\"\"\n-Una funcion puede acceder varibles globales.\n-Pero no se pueden acceder a variables locales desde fuera de la funcion.\n-Si existe una variable local y global en la funcion se tomará la local\n y afuera la global.\n\n\"\"\"\na = 5\ntext = \"perro\"\ndef funcion_local_global():\n    a = 8\n    print(f\"Este es el numero local: , {a}, y el texto global es: {text}\")\n\n#EXTRA\ndef funcion_reto(texto1, texto2):\n    count = 0\n    for number in range(1, 101):\n        if number % 3 == 0 | number % 5 == 0:\n            concat = texto1+texto2\n            print(f\"{number}, - {concat}\")\n        elif number % 3 == 0:\n            print(f\"{number}, - {texto1}\")\n        elif number % 5 == 0:\n            print(f\"{number}, - {texto2}\")\n        else:\n             count += 1\n             print(f\"{number}\")\n    return count\n    \nfuncion_simple()\nfuncion_parametro(2)\nfuncion_varios_parametros(\"Nuevo\", 2024)\nres = funcion_retorno(12, 25)\nprint(\"Este es el resultado del return: \", res)\nprint(greet)\nprint(name)\nexterna()\nfuncion_arg_multiples(\"Gato\", \"Toby\", \"Ahmed\")\nfuncion_multi_palabra_clave(laguage=\"Python\",\n                            name=\"Santiago\",\n                            age=\"16\")\nprint(\"Este es el numero global:\", a)\nfuncion_local_global()\n    \nres = funcion_reto(\"fizz\", \"buzz\")\nprint(res)\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/santiagobailleres.py",
    "content": "#02 FUNCIONES Y ALCANCE\n\n'''\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n'''\n\n# 1- Crea ejemplos de funciones básicas que representen las diferentes posibilidades del lenguaje:\n#    Sin parámetros ni retorno, con uno o varios parámetros, con retorno.\n\n# Función sin parámetros ni retorno\ndef funcion1():\n    print(\"Función sin parámetros ni retorno\")\n\nfuncion1()\n\n# Función sin parámetros y con retorno\ndef funcion2():\n    return \"Función sin parámetros y con retorno\"\n\nprint(funcion2())\n\n# Función con un parámetro predeterminado y sin retorno\ndef funcion3(parametro = \"Hola\"):\n    print(\"Función con un parámetro predeterminado y sin retorno:\", parametro)\n\nfuncion3()\n\n# Función con un parámetro y sin retorno\ndef funcion4(parametro):\n    print(\"Función con un parámetro y sin retorno:\", parametro)\n    \nfuncion4(\"Hola\")\n\n# Funcion con varios parámetros y con retorno\ndef funcion5(parametro1, parametro2):\n    return parametro1 + parametro2\n\na = funcion5(2, 3)\nprint(a)\n\n# Función con retorno de varios valores\ndef funcion6(parametro1, parametro2):\n    return parametro1, parametro2\n\na, b = funcion6(2, 3)\nprint(a)\nprint(b)\n\n# Función con numero variable de argumentos\ndef funcion7(*args):\n    for arg in args:\n        print(arg)\n\nfuncion7(1, 2, 3, 4, 5)\n\n# Función con numero variable de argumentos y argumentos con nombre\ndef funcion11(**kwargs): # kwargs = keyword arguments\n    for key, value in kwargs.items():\n        print(key, value)\n\nfuncion11(a = 1, b = 2, c = 3)\n\n# 2- Comprueba si puedes crear funciones dentro de funciones.\ndef funcion8():\n    def funcion9():\n        print(\"Función dentro de función\")\n    funcion9()\n\nfuncion8()\n\n# 3- Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\ndef funcion10():\n    print(\"Función que utiliza una función ya creada en el lenguaje\")\n    print(\"Ejemplo de función que ya existe en Python: len([1, 2, 3]) =\", len([1, 2, 3]))\n\nfuncion10()\n\n# 4- Pon a prueba el concepto de variable LOCAL y GLOBAL.\nvariable_global = 5\n\ndef funcion12():\n    variable_local = 3\n    print(\"Variable local:\", variable_local)\n    print(\"Variable global:\", variable_global)\n\nprint(\"Variable global:\", variable_global)\n# print(\"Variable local:\", variable_local) # Error: variable_local no está definida\n\nfuncion12()\n\n# EXTRA - Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n#         La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n#         - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n#         - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n#         - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n#         - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\ndef funcionExtra(text1, text2):\n    cont = 0\n    for i in range(1,101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(text1 + text2)\n        elif i % 3 == 0:\n            print(text1)\n        elif i % 5 == 0:\n            print(text2)\n        else:\n            print(i)\n            cont += 1\n    return cont\n\nprint(\"Número de veces que se ha impreso el número:\", funcionExtra(\"multi3\", \"multi5\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/santiagobima.py",
    "content": "\n'''\nFunciones definidas por el usuario\n'''\n\n#simple\ndef hola():\n    print(\"Hola, soy Santiago Bima\")\n    \nhola()\n\n\n#retorno\n\ndef otrafuncion2(numero1,numero2):\n    return numero1+numero2\n\nretorno = otrafuncion2(1,2)\n\nprint(retorno)\n\n\n#con un argumento\n\ndef argumento(nombre):\n    print(f'hola,{nombre}')\n    \nargumento('santiago')\n\n\n#con dos argumentos\ndef otrafuncion(numero, nombre):\n    print('Hola soy '+nombre+' y mi numero favorito es'+ str(numero))\n    \notrafuncion(7, 'Santiago Bima')\n\n\n#con argumento predeterminado\n\ndef pordefecto(name='santiago'):\n    print('hola,',{name})\n    \n\n\n\n\n#con retorno de varios valores , tupla de valores:\n\ndef multiplosderetornos():\n    return 'Que tal', 'Santiago'\n\nsaludo,nombre = multiplosderetornos()\n\nprint(saludo)\nprint(nombre)\n    \n\n\n\n#con un numero variable de argumentos\n\ndef variable_greet(*nombres):\n    for name in nombres:\n        print(f'Hola,{name}')\n        \n        \nvariable_greet('botella','marcos','Clara')\n\n\n\n#con un numero variable de argumentos con palabra clave\n\n\ndef variable_kwargs(**nombres):\n    for param,name in nombres.items():\n        print(f'Hola,{name}({param})')\n        \nvariable_kwargs(lugar='rastro',\n                ciudad='berlin',\n                capita='ny')\n        \n\n\n\n\n#funcion dentro de funcion\n\ndef funcion_porfuera():\n    print('esta es una funcion por fuera') \n    \n    def funcion_por_dentro():\n        print('esta es una función por dentro')\n    \n    funcion_por_dentro()\n    \nfuncion_porfuera()\n\n\n\n\n\n\n#funciones propias de python\n\ndef convertir_a_mayusculas(lista_cadenas):\n    return list(map(str.upper,lista_cadenas))\n    \ncadenas = ['me','llamo','santiago','bima']\n\ncadenas_mayusculas = convertir_a_mayusculas(cadenas)\nprint(cadenas_mayusculas)\n\n\nprint(len('santiago'))\nprint(type(10))\n\n\n\n\n\n#variables globales y locales (SCOPE//AMBITO)\n\ncontador_global = 0\n\ndef incrementar_contador_local():\n    contador_local = 0\n    contador_local += 1\n    print('Contador local:', contador_local)\n    \ndef incrementar_contador_global():\n    global contador_global\n    contador_global += 1\n    print('contador global:', contador_global)\n\nprint(f'Contador global antes de llamar : {contador_global}')\n\nincrementar_contador_local()\nincrementar_contador_global()\nincrementar_contador_global()\nincrementar_contador_local()\nprint(f'contador global final: {contador_global}')\n\n\n\n\n#EXTRA \n\nfrom word2number_es import w2n\n\ndef dificultad_extra(parametro1:str,parametro2:str) -> int:\n    contador = 0\n    \n    for numero in range(1,101):\n        if numero % 3 == 0 and numero % 5 == 0:\n            print(parametro1 + parametro2)\n            \n        elif numero % 3 == 0:\n            print(parametro1)\n            \n        elif numero % 5 == 0:\n            print(parametro2)\n            \n        else:\n            print(numero)\n            contador +=1\n            \n    return contador\n    \n\n\nresultado = dificultad_extra('aloha','mora')\n\nprint('cantidad de numeros reemplazados', resultado)\n\n\nprint('LISTO!')"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/santyjL.py",
    "content": "#02 FUNCIONES Y ALCANCE\n\n\"\"\"\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\"\"\"\n\n#las funciones se definen con def\ndef presentacion():\n    print(\"hola esto es una funcion \")\n\n\n#se pueden agregar parametros , tiene que estar dentro de los ()\ndef separador(nombre):\n    print(f\"-------------{nombre}---------------\")\n\n\n#los parametros se pueden definir por tipo\ndef mayor_que(num1 : int , num2 : int):\n#se puede dar una descripcion a las funciones con \"\"\n    \"\"\"\n    esta funcion resive 2 numeros y verifica cual de ellos es mayor\n    \"\"\"\n    try:\n        if num1 > num2:\n            return f\"el numero {num1} es mayor que {num2}\"\n\n        elif num2 < num1:\n            return f\"el numero {num2} es mayor que {num1}\"\n\n        else :\n            return f\"son iguales\"\n\n    except Exception as error:\n        print(f\"hubo un error : {error}\")\n\n\n#se pueden hacer funciones dentro de otra funcion\ndef funcion_interna(nombre):\n    saludo = f\"hola {nombre} ,\"\n\n    def saludo_raro():\n        saludo = \" hello pejarillito chaqueteado\"\n        return saludo\n\n    saludo2 = saludo_raro()\n    saludo += saludo2\n\n    return saludo\n\n\n#funciones del lenguaje y e iterables\n#funciones del lenguaje\n\nseparador(\"funciones del lenguaje\")\nprint(sum([1 , 2 , 5, -3 , 4, -1]) , \"sum\") #suma todos los valores de un iterables\nprint(max([1 , 2, 4 , 5, 5.5 , -2]), \"max\") #retorna el numero mayor\nprint(min([1 , 2, 4 , 5, 5.5 , -2]), \"min\") #retorna el numero menor\nprint(len(\"soy el mas perron de aqui . \\n'naruto uzumaki'\"), \"len en string\") #cuenta los caracteres del texto y lo retorna\nprint(len([1 , 2 , 34 , 6 , 76 , 3 , 4]), \"len en lista\") #tambien sirve para contar los elementos de la lista\nprint(sorted([1 , 4, 2 , 5, 5.5 , -2]) , \"sorted menor a mayot\") #ordena la lista de fomara ordenada  de menor a mayor\nprint(sorted([1 , 4, 2 , 5, 5.5 , -2] , reverse=True) , \"sorted de mayor a menor\") # ordena la lista de mayor a menor\n\n#funciones lambdas\nlista = [1,2,3,4,5,6,7,8,9]\n\n#son recomendadas paras funciones con solo un objetivo\nnum_X2 = lambda x : x * 2\nprint(num_X2(20 ,30 , 50) , \" funcion lambda\")\n\n\n#filter filtra los datos verdaderos y crea nueva lista esta se conoce como funcion de orden duperior\nes_par = lambda x : x %2 == 0\nlista_pares = filter(es_par, lista)\n\n\n#funcione recursiva\ndef cuenta_regresiva(iteraciones : int):\n\n    num = 0\n    if num == iteraciones:\n        return\n\n    else :\n        print(iteraciones)\n        cuenta_regresiva(iteraciones - 1)\n\n#funciones con parametros idefinidos\ndef sumador (*args):\n    suma_total = sum(*args)\n    return suma_total\n\n\ndef iterar_diccionarios (**kwargs):\n    for clave, valor in kwargs.items():\n        print(f\"{clave}: {valor}\")\n\n#EXTRA\ndef repeticion_de_texto (texto1 : str , texto2 : str) -> int:\n    text1_repeticiones = 0\n    text2_repeticiones = 0\n    text3_repeticiones = 0\n\n    for i in range(1 , 101):\n        if i % 3 == 0 and i % 5 == 0  :\n            print(texto1 + \"_\" + texto2)\n            text3_repeticiones += 1\n\n        elif i % 3 == 0 :\n            print(texto1)\n            text1_repeticiones += 1\n\n        elif i % 5 == 0 :\n            print(texto2)\n            text2_repeticiones += 1\n\n        else :\n            print(i)\n\n    return text1_repeticiones , text2_repeticiones , text3_repeticiones , texto1 , texto2\n\n\n#variable GLOBAL\nnum_max = 10\n\ndef funcion_global():\n    #variable LOCAL\n    num_min = 1\n\n    for i in range(num_min , num_max):\n        print(i)\n\ntry:\n    print(num_min)\n\nexcept Exception:\n    separador(\"variable local\")\n    print(\"no se puede llamar a la variable LOCAL num_min\")\n\n\nsaludo = funcion_interna(\"persona\")\nseparador(\"funcion_interna\")\nprint(saludo)\nseparador(\"sin parametro ni retorno\")\npresentacion()\nseparador(\"con retorno y tipado\")\nprint(mayor_que(1 , 3))\nseparador(\"fucnion de otrden superior\")\nprint(lista_pares)\nseparador(\"cuenta_regresiva\")\ncuenta_regresiva(20)\nseparador(\"*args\")\nprint(sumador([1,2,3,4,5,6,7,8,9,0,1]))\nseparador(\"*kwargs\")\nprint(iterar_diccionarios( **{'a': 1, 'b': 2, 'c': 3}))\nseparador(\"extra\")\ntexto1 , texto2  , texto3  , text1 , text2 = repeticion_de_texto(\"hola\" , \"mundo\")\nprint(f\"\"\"\n    texto {text1} aparecio {texto1}\n    texto {text2} aparecio {texto2}\n    texto {text1}_{text2} aparecio {texto3}\n      \"\"\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/sarismejiasanchez.py",
    "content": "# #02 FUNCIONES Y ALCANCE\n\n# Función sin argumentos ni retorno\nprint(\"Función sin argumentos ni retorno\")\n\ndef saludo():\n    print(\"Hola mundo!\")\n\n# Ejecutar la funcion\nsaludo()\n\n# Función con un argumentos y retorno\nprint(f\"\\nFunción con un argumentos y retorno\")\nnumero = 5\n\ndef cuadrado(numero):\n    return numero ** 2\n\nresultado = cuadrado(numero)\nprint(f\"Cuadrado de {numero}: {resultado}\")\n\n# Funcion con argumentos predeterminados\nprint(f\"\\nFuncion con argumentos predeterminados\")\n\ndef default_arg_greet(name=\"Python\"):\n    print(f\"Hola, {name}\")\n\ndefault_arg_greet(\"Sara\")\ndefault_arg_greet()\n\n# Llamar la funcion indicando los argumentos\ndef greet(greet, name):\n    print(f\"{greet}, {name}\")\n\ngreet(\"Hola\", \"Python\")\ngreet(name=\"Python\", greet=\"Hi\")\n\n# Función con argumentos y retorno de multiples valores\nprint(f\"\\nFunción con argumentos y retorno de multiples valores\")\n\ndef suma_producto(num1, num2):\n    print(f\"Parámetros de la función: num1 = {num1}, num2 = {num2}\")\n    suma = num1 + num2\n    producto = num1 * num2\n    return suma, producto\n\nsuma, producto = suma_producto(5, 4)\nprint(f\"Suma: {suma}\")\nprint(f\"Producto: {producto}\")\n\n# Función con un numero variable de argumentos\nprint(f\"\\nFunción con un numero variable de argumentos\")\n\ndef variable_arg_greet(*names): # Argumentos separados por coma\n    for name in names:\n        print(f\"Hola, {name}\")\n\nvariable_arg_greet(\"Python\", \"Sara\", \"MoureDev\", \"Comunidad\")\n\n# Función con un numero variable de argumentos con palabra clave\nprint(f\"\\nFunción con un numero variable de argumentos con palabra clave\")\n\ndef variable_key_arg_greet(**names): # Cada argumento estará formado por una clave y un valor\n    for key, value in names.items():\n        print(f\"{value} ({key})!\")\n\nvariable_key_arg_greet(\n    language = \"Python\",\n    name=\"Sara\",\n    alias = \"sarismejiasanchez\",\n    age = 31\n    )\n\n\n\"\"\"\nFunción dentro de función\n\"\"\"\nprint(f\"\\nFunción dentro de función\")\n\ndef outer_function():\n    def inner_function():\n        print(\"Funcion interna: Hola, Python!\")\n    inner_function()\n\nouter_function()\n\n\"\"\"\nEn esta función, se define una función interna llamada cuadruplicar. \nLa función principal toma un parámetro x, multiplica este parámetro por 4 utilizando \nla función interna cuadruplicar, y luego devuelve el resultado.\n\"\"\"\n\ndef funcion_principal(x):\n    def cuadruplicar(num):\n        return num * 4\n    resultado = cuadruplicar(x)\n    return resultado\n\nresultado_final = funcion_principal(5)\nprint(\"Resultado de función dentro de función:\", resultado_final)\n\n\n\"\"\"\nFunciones del lenguaje (built-in)\nhttps://docs.python.org/3/library/functions.html\n\"\"\"\n\nprint(f\"\\nFunciones del lenguaje (built-in)\")\n\n\"\"\"\nlen()\nRetorna el tamaño (el número de elementos) de un objeto. \nEl argumento puede ser una secuencia (como una cadena, un objeto byte, una tupla, lista o rango) \no una colección (como un diccionario, un set o un frozen set).\n\"\"\"\nprint(f\"\\nlen():\")\nlongitud_lista = len([1, 2, 3, 4, 5])\nprint(f\"La longitud de la lista es: {longitud_lista}\")\n\n\"\"\"\nenumerate(iterable, start=0)\nRetorna un objeto enumerador. iterable tiene que ser una secuencia, un iterator, \no algún otro objeto que soporte la iteración. El método __next__() del iterador \nretornado por la función enumerate() retorna una tupla que contiene un contador \n(desde start, cuyo valor por defecto es 0) y los valores obtenidos al iterar sobre iterable.\n\"\"\"\nprint(f\"\\nenumerate(iterable, start=0)\")\nseasons = ['Spring', 'Summer', 'Fall', 'Winter']\nprint(f\"Lista: {seasons}\")\nprint(f\"Lista con enumerate: {list(enumerate(seasons))}\")\n\n\"\"\"\nfilter(function, iterable)\nfunction\tA Function to be run for each item in the iterable\niterable\tThe iterable to be filtered\n\nFilter the array, and return a new array with only the values equal to or above 18:\n\"\"\"\nprint(f\"\\nfilter(function, iterable):\")\nages = [5, 12, 17, 18, 24, 32]\nprint(f\"Lista ages: {ages}\")\n\ndef is_adult(age):\n    if age < 18:\n        return False\n    else:\n        return True\n\nadults = filter(is_adult, ages)\n\nfor age in adults:\n    print(age)\n\n\n\"\"\"\nVariables Globales y Locales\nGlobal: Se definen por fuera del ámbito de la función\nLocal: Funcioan dentro del ambito de la función\n\"\"\"\n\nprint(f\"\\nVariables Globales y Locales\")\nglobal_var = \"Python\"\nprint(f\"global_var: {global_var}\")\n\ndef hello_python():\n    local_var = \"Hello\"\n    print(f\"local_var: {local_var}\")\n    print(f\"{local_var}, {global_var}!\")\n\nhello_python()\n\n# Variable global\nvariable_global = 10\n\n# Función que utiliza variable global\ndef incrementar_variable():\n    global variable_global\n    variable_global += 1\n\n# Uso de variable global\nprint(f\"\\nVariable global antes de incrementar:\", variable_global)\nincrementar_variable()\nprint(\"Variable global después de incrementar:\", variable_global)\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\"\"\"\nprint(f\"\\nDIFICULTAD EXTRA\")\ndef return_numbers(text1, text2):\n    count = 0\n    for number in range(1, 101):\n        if (number % 3 == 0 and number % 5 == 0):\n            print(text1 + text2)\n        elif number % 3 == 0:\n            print(text1)\n        elif number % 5 == 0:\n            print(text2)\n        else:\n            print(number)\n            count += 1\n    return count\n    \n# Ejecucion\ntext1 = \"Fizz\"\ntext2 = \"Buzz\" \nresultado = return_numbers(text1, text2)\nprint(f\"Se realizaron {resultado} impresiones de números\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/saulmrto.py",
    "content": "\"\"\"\nFunciones definidas por el usuario\n\"\"\"\n\n# Simple\n\ndef greet():\n    print(\"Hola, Python!\")\n\ngreet()\n\n# Con retorno\n\ndef return_greet():\n    return \"Hola, Python!\"\n\nprint(return_greet())\n\n# Con un argumento\n\ndef arg_greet(name):\n    print(f\"Hola, {name}!\")\n\narg_greet(\"Saul\")\n\n# Con argumentos\n\ndef args_greet(greet,name):\n    print(f\"{greet}, {name}!\")\n\nargs_greet(\"Hi\", \"Saul\")\nargs_greet(name=\"Saul\", greet=\"Hi\")\n\n# Con un argumento predeterminado\n\ndef default_arg_greet(name=\"Python\"):\n    print(f\"Hola, {name}!\")\n\ndefault_arg_greet(\"Saul\")\ndefault_arg_greet()\n\ndef return_args_greet(greet, name):\n    return f\"{greet}, {name}!\"\n\nprint(return_args_greet(\"Hi\", \"Saul\"))\n\n# Con retorno de varios valores\n\ndef multiple_return_greet():\n    return \"Hola\", \"Python\"\n\ngreet, name = multiple_return_greet()\nprint(greet)\nprint(name)\n\n# Con un numero variable de argumentos\n\ndef variable_arg_greet(*names):\n    for name in names:\n        print(f\"Hola, {name}!\")\n\nvariable_arg_greet(\"Python\", \"Saul\", \"Toon\")\n\n# Con un numero variable de argumentos con palabra clave\n\n\ndef variable_key_arg_greet(**names):\n    for key, value in names.items():\n        print(f\"{value} ({key})!\")\n\nvariable_key_arg_greet(\n    language=\"Python\", \n    name=\"Saul\", \n    alias=\"Toon\", \n    age=23\n)\n\n\n\"\"\"\nFunciones dentro de funciones\n\"\"\"\n\ndef outer_function():\n    def inner_function():\n        print(\"Funcion interna: Hola, Python!\")\n    inner_function()\n\nouter_function()\n\n\"\"\"\nFunciones de lenguaje (built-in)\n\"\"\"\n\nprint(len(\"Saul\"))\nprint(type(23))\nprint(\"toonsaul\".upper())\n\n\"\"\"\nVariables locales y globales\n\"\"\"\n\nglobal_var = \"Python\"\n\ndef hello_python():\n    local_var = \"Hola\"\n    print(f\"{local_var}, {global_var}!\")\n\nprint(global_var)\n# print(local_var) No se puede acceder desde fuera de la funcion\n\nhello_python()\n\n\"\"\"\nExtra\n\"\"\"\n\ndef print_numbers(text_1, text_2) -> int:\n    count = 0\n    for number in range(1, 101):\n        if number % 3 == 0 and number % 5 == 0:\n            print(text_1 + text_2)\n        elif number % 5 == 0:\n            print(text_2)\n        elif number % 3 == 0:\n            print(text_1)\n        else:\n            print(number)\n            count += 1\n    return count\n\nprint(print_numbers(\"Fizz\", \"Buzz\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/sniker1223.py",
    "content": "# Functions\ndef noParameterNoReturn():\n    print(\"Function no parameter and no Return!\")\nnoParameterNoReturn()\n\n# Function one parameter\ndef sayHello(name):\n    print(\"Hello \" + name + \"!\")\nsayHello(\"Sniker\")\n\n# Function with return\ndef add(number1, number2):\n    return number1+number2\nprint(f\"Function with return: {add(1, 2)}\")\n\n# This function contains a function\ndef sayHelloAndAdd(name, number1, number2):\n    sayHello(name)\n    print(f\"The add is: {add(number1, number2)}\")\nsayHelloAndAdd(\"Sniker\", 5, 10)\n\ndef returnTheLargest(list):\n    return max(list)\n\n# global variable\nmyList = [3, 10, 1]\nprint(f\"max() function: {returnTheLargest(myList)}\")\n\n# Lambda function to calculate the square of a number\ndef square(x): return x ** 2\nprint(f\"Lambda function: {square(3)}\")\n\n# Challenge\ndef printTheChallenge(text1, text2):\n    # local variable\n    count = 0\n    for i in range(1, 101):\n        if (i % 3 == 0 and i % 5 == 0):\n            print(text1+text2)\n        elif (i % 3 == 0):\n            print(text1)\n        elif (i % 5 == 0):\n            print(text2)\n        else:\n            print(i)\n            count += 1\n    return count\n\nprint(f\"Number of times the number has been printed: {\n      printTheChallenge(\"Star\", \"Wars\")}\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/sorubadguy.py",
    "content": "import random\nvar1 = \"Hola soy una variable\"\nvar2 = \"Hola soy otra variable\"\nvar3 = \"Somos 3 variables\"\nvar4 = \"Somos 4 variables\"\nlista = [\"manzana\", \"mandarina\", \"durazno\", \"sandia\"]\n#Funciones\n\n#No recibe parametros\ndef funcion_sin_parametros():\n    print(\"no uso parametros\")\n\nfuncion_sin_parametros()\n\n#Recibe un parametro\ndef funcion_con_un_parametro(var1):\n    print(var1)\n\nfuncion_con_un_parametro(var1)\n\n#recibe 2 o mas parametros, se conoce la cantidad exacta de parametros que recibe\ndef funcion_con_dos_parametros(var1, var2):\n    print(var1)\n    print(var2)\n\nfuncion_con_dos_parametros(var1, var2)\n\n#se envian varios parametros, no se conoce la cantidad exacta de estos\ndef funcion_con_muchos_parametros(*nombres):\n    for i in range(0, len(nombres)):\n        print(f\"Hola: {nombres[i]}\")\n\nfuncion_con_muchos_parametros(\"Lucas\", \"Pedro\", \"Alejandro\", \"Mauro\")\n\n#se envian varios parametros, no se conoce la cantidad exacta de estos, se puede agregar ademas otros argumentos\ndef funcion_con_muchos_parametros(variable1, variable2, *nombres):\n    for i in range(0, len(nombres)):\n        print(f\"Adios: {nombres[i]}\")\n    print(variable1)\n    print(variable2)\n\nfuncion_con_muchos_parametros( var1, var2, \"Lucas\", \"Pedro\", \"Alejandro\", \"Mauro\")\n\n#Variables creadas en los argumentos de las funciones\n\ndef funcion_con_var_propia(apellido1):\n    print(f\"El apellido es: {apellido1}\")\n\nfuncion_con_var_propia(apellido1 = \"Blanco\")\n\n#no se conocen los argumentos, del tipo variable, que se reciviran como parametros\ndef funcion_con_muchas_variables(**vars):\n    print(vars[\"var9\"])\n\nfuncion_con_muchas_variables(var7 = \"hola\", var8 = \"Como\", var9 = \"Estas\", var0 = \"Adios\")\n\n#Parametro por defecto\n\ndef arg_por_defecto(pais = \"Argentina\"):\n    print(f\"Soy de: {pais}\")\n\narg_por_defecto(\"España\")\narg_por_defecto(\"Chile\")\narg_por_defecto()\narg_por_defecto(\"Mexico\")\n\n#Pasar una lista como parametro\n\ndef comer_frutas(frutas):\n    for i in range(len(frutas)):\n        print(f\"Comiste un/a: {frutas[i]}\")\n\ncomer_frutas(lista)\n\n#funcion que devuelve un resultado\n\ndef retorno():\n    return 3+4\n\nvar4 = retorno()\nprint(var4)\n\n#Si nesesitas dejar una funcion vacia\n\ndef vacia():\n    pass\n\n#crear funcion dentro de funcion \n\ndef funcion_afuera():\n    def funcion_adentro():\n        return \"hola\"    \n    print(funcion_adentro())\n\nfuncion_afuera()\n\n#Funciones de Python\n\nprint(f\"len(var3): {len(var3)}\")\nprint(f\"numero random= {random.randint(0,100)}\")\n\n#Variables Locales y Globales\n\nvar_global = \"Soy una variable global\"\n\ndef variables():\n    var_local = \"Solo me puedo imprimir en esta funcion\"\n    print(f\"var_global= {var_global},||| var local= {var_local}\")\n\nvariables()\n\n#Extra\n\ndef extra(texto1, texto2):\n    contador = 0\n\n    for i in range(1, 101):\n        if(i % 3 == 0 and i % 5 == 0):\n            print(f\"{texto1} {texto2}\")\n        elif(i % 3 == 0):\n            print(texto1)\n        elif(i % 5 == 0):\n            print(texto2)\n        else:\n            print(i)\n            contador += 1\n    \n    print(contador)\n\nextra(\"hola\", \"chau\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/strooplab.py",
    "content": "\"\"\"\nEJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\"\"\" \nfrom datetime import datetime\nimport calendar\n\n#funcion sin retorno\ndef impresion():\n    print(\"Hola mundo\")\n\n#funcion con retorno\ndef suma():\n    suma = 5 + 5\n    return suma\n\n#funcion con un parametro\ndef nombre(palabra):\n    message = 'Hola, ' + palabra.capitalize() \n    return message\n\n#funcion con varios parametros\ndef cumple(date, now):\n    if date < now:\n        date = date.replace(year=date.year + 1) #funcion dentro de otra funcion ejecutada\n    diff = date - now\n    hours, seconds = divmod(diff.seconds, 60*60)\n    minutes, seconds = divmod(seconds, 60)\n\n    return (diff.days, hours, minutes, seconds)\n\nprint(impresion())\nprint(suma())\nprint(nombre(input(\"escriba una su nombre: \")))\nnow = datetime.now()\ntry:\n    mes = int(input(\"Digite el mes: \"))\n    dia = int(input(\"Digite el dia: \"))\n    nextcumple = cumple(datetime(now.year, mes, dia), now)\n    print(f\"Tu siguiente cumpleaños sera en: {nextcumple[0]} dias, {nextcumple[1]} horas, {nextcumple[2]} minutos, {nextcumple[3]} segundos\")\nexcept Exception as e:\n    print(f'error: {e}')\n\n#numero variable de argumentos\ndef meses(*args):\n    for i in args:\n        mes = calendar.month_name[i]\n        print(f\"En el año tenemos a: {mes}\")\n\n\nmeses(1,2,3,4,5,6,7,8,9,10,11,12)\n\n#argumentos variables con palabras clave\ndef info(**args):\n    for param, i in args.items():\n        print(f\"info relevante: ({param}): {i}\")\n\ninfo(\n    nombre = \"juan\",\n    edad = 25,\n    ciudad = \"cartagena\",\n    pais = \"colombia\"\n)\n\ndef funcionOut():\n    def funcionIn():\n        print(\"Holaaaaaaaaaaaaa\")\n    funcionIn()\n\nfuncionOut()\n\n#Funcion built-in\nnumero = 1\nprint(numero.to_bytes())\n\n#Variable global\nnumero1 = 1\nprint(numero1)\n\nnombre = 'Diego'\n\ndef imp_nombre():\n    global frase\n    frase = 'El nombre es: '\n    print(f\"{frase} {nombre}\")\n\nimp_nombre()\n\n#EXTRA\ndef cadenas(param1, param2):\n    cuenta = 0\n    for i in range (1,101):\n        if i % 3 == 0 and i % 5 == 0 :\n            print(param1 + param2)\n        elif i % 3 == 0:\n            print(param1)\n        elif i % 5 == 0:\n            print(param2)\n        else:\n            print(i)\n            cuenta += 1\n    return cuenta\n\ncadena1 = str(input(\"Digite una cadena de texto que se digite cuando el valor sea múltiplo de 3: \"))\ncadena2 = str(input(\"Digite una cadena de texto que se digite cuando el valor sea múltiplo de 5: \"))\n\nprint(f\"La cantidad de veces que apareció un numero en vez de texto fueron: {cadenas(cadena1,cadena2)}\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/suescun845.py",
    "content": "### Ejercicio ###\r\n\r\ndef hola(): #Sin parámetros ni retornos#\r\n    print(\"Hola\")\r\n\r\ndef suma(a,b): # Con parámetros sin retorno\r\n    print(a+b) \r\n\r\ndef resta(a,b): # Con parámetros y con retorno\r\n    return a-b\r\n\r\ndef perro(): # Sin parámetros y con retorno\r\n    return \"guau\"\r\n\r\ndef superfuncion(): #Función dentro de otra función\r\n    def division(a,b):\r\n        return a/b\r\n\r\n    def multiplicacion(a,b):\r\n        return a*b\r\n    \r\n    return division(5,6),multiplicacion(3,5)\r\n\r\nhola()\r\nsuma(12,45)\r\nprint(resta(12,789))\r\nprint(perro())\r\nprint(superfuncion())\r\n\r\nlist =[2, 6, 4, 23, 67, 0]\r\nstring = \"programación con python\"\r\nprint(len(\"Hola Moure\")) #Cuenta los caracteres\r\nprint(sorted(list)) #Ordena los caracteres\r\nprint(string.upper())# Coloca todos los caracteres en Mayúsculas\r\nprint(string.title())# Coloca todos los primeros caracteres de cada palabra en Mayusculas\r\n\r\n### Variable Local y Global ###\r\n\r\nglobal_Variable = \"Soy Global\" # Se puede usar en cualquier parte del código\r\n\r\ndef variables():\r\n    local_Variable = \"Soy Local\"\r\n    print(local_Variable)\r\n    print(local_Variable, global_Variable)\r\n\r\nvariables()\r\ntry:\r\n    print(global_Variable) \r\n    print(local_variable)\r\nexcept:\r\n    print(\"No se puede imprimir una variable local de una función\")\r\n\r\n### Extra ###\r\ncadena1 = str(input(\"Digite una cadena de texto que se digite cuando el valor sea múltiplo de 3: \"))\r\ncadena2 = str(input(\"Digite una cadena de texto que se digite cuando el valor sea múltiplo de 5: \"))\r\n\r\ndef extra(parametro1, parametro2):\r\n    cuenta = 0\r\n    for i in range (1,101):\r\n        if i % 3 == 0 and i % 5 == 0 :\r\n            print(parametro1 + parametro2)\r\n        elif i % 3 == 0:\r\n            print(parametro1)\r\n        elif i % 5 == 0:\r\n            print(parametro2)\r\n        else:\r\n            print(i)\r\n            cuenta += 1\r\n    return cuenta\r\n\r\nprint(f\"La cantidad de veces que apareció un numero en vez de texto fueron: {extra(cadena1,cadena2)}\")\r\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/sunjamer.py",
    "content": "# funciones\n\n# funcion sin parametros\n\ndef pinta_texto():\n    print (\"esta función pinta este texto\")\n\npinta_texto()\n\n# funcion que retorna un valor\n\ndef sumador():\n    a = 9\n    b = 5\n    return (a + b)\n\nprint (sumador())\n\n# función con parametros\n\ndef multiplicador_por2 (numero):\n    return (numero * 2)\n\nprint(multiplicador_por2(25))\n\n# función con dos parámetros\n\ndef multiplicar_por_valor(numero, multiplicador):\n    return (numero * multiplicador)\n\nprint(multiplicar_por_valor(796,344))\n\n# funcion con key y valor\n\ndef multiplicar_por_valor2 (numero, multiplicador):\n    return (numero * multiplicador) \n\nprint (multiplicar_por_valor2 (multiplicador=2, numero=500))\n\n# función que retorna un string\n\ndef junta_palabras(palabra1, palabra2):\n    espacio = ' '\n    palabra_total = palabra1 + espacio + palabra2\n    return (palabra_total)\n\nprint (junta_palabras(\"tonto\", \"quienlolea\"))\n\n# funcion con parámetro por defecto\n\ndef calcular_edad (año_nacimiento=2000, año_actual=2024):\n    return (año_actual - año_nacimiento)\n\nprint(calcular_edad(1977, 2014))\n\n# funcion con numero indeterminado de argumentos\n\ndef multiplicar_numeros(*numeros):\n    total = 1\n    for nums in numeros:\n        total *= nums \n    return total\n\nprint(multiplicar_numeros(3, 5, 10, 2, 24))\n\n\n\n\n\n\n\n\"\"\"\nextra\n\"\"\"\n\n\ndef funcion_extra (cadena1, cadena2) -> int:\n    contador = 0\n    for num in range(1,101):\n        if num % 3 == 0 and num % 5 == 0:\n            print (cadena1 + ' y ' + cadena2)\n        elif num % 3 == 0:\n            print(cadena1)\n        elif num % 5 == 0:\n            print (cadena2)\n        else:\n            print (num)\n            contador += 1\n    return contador\n\nveces = funcion_extra(\"multiplo de 3\",\"multiplo de 5\")\nprint(veces)\n    \n\n# funcion dentro de función\n\ndef suma_numeros (num1, num2, num3):\n    def suma_num1_num2 (num1, num2):\n        return num1 + num2\n    suma_parcial = suma_num1_num2(num1, num2)\n    return num3 + suma_parcial\n\nprint(suma_numeros (20, 400, 80))\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/super490.py",
    "content": "#  Funciones\n\n#  Sin parámetros ni retorno\n\ndef saludo():\n    print('Hola mundo')\n    \nsaludo()\n\n# Con un parámetros\n\ndef dato(nombre):\n    print(f'Mi nombre es {nombre}')\n    \ndato('Manuel')\n\n# Con varios parámetros\n\ndef datos(nombre,apellido,edad):\n    print(f'Mi nombre y apellido es {nombre} {apellido} y tengo {edad} de edad')\n    \ndatos('Manuel','Morales','28')\n\n# Con retorno\n\ndef suma(num1,num2):\n    return num1 + num2\n\nresultado = suma(30,20)\n\nprint(f'El resultado de la suma es: {resultado}')\n\n\ndef dividir(num1,num2):\n    if num2 == 0:\n        return 'Error: División por cero'\n    return num1 / num2\n\nresultado = dividir(30,2)\n\nprint(f'El resultado de la division es: {resultado}')\n\n# funciones dentro de funciones\n\ndef resultado_resta(num5,num6):\n    \n    def resta(num3,num4):\n        return num3 - num4\n\n    return resta(num5,num6)\n\nresultado = resultado_resta(30,10)\n    \nprint(resultado)\n\n# funciones ya creadas en el lenguaje\n\n# 1. print()\nprint(\"Hola, Python!\")\n\n# 2. len()\ncadena = \"Python\"\nlongitud = len(cadena) \nprint(longitud)\n\n# 3. type() \nnumero = 10\nprint(type(numero))\n\n# 4. input()\n\nnombre = input(\"Ingrese su nombre: \")  \nprint(\"Hola,\", nombre)\n\n# 5. int()\n\nnumero = \"10\"\nnumero_entero = int(numero) \nprint(numero_entero)\n\n# 6. float()\n\nprecio = \"99.99\"\nprecio_float = float(precio)\nprint(precio_float)\n\n# 7. float()\n\nedad = 25\nedad_str = str(edad)\nprint(edad_str)\n\n# 8. abs()\n\nnumero = -10\nvalor_absoluto = abs(numero)\nprint(valor_absoluto)\n\n# 9. round()\n\nnumero = 3.14159\nnumero_redondeado = round(numero, 2) \n\n# 10. max(), min()\n\nnumeros = [1, 5, 2, 8, 3]\nmaximo = max(numeros)  \nminimo = min(numeros)\nprint(maximo)\nprint(minimo)\n\n# 11. sum()\n\nnumeros = [1, 2, 3, 4, 5]\nsuma = sum(numeros)\nprint(suma)\n\n# Funcion con una variable local\n\ndef mi_funcion():\n    x = 12\n    print(x)\n\nmi_funcion()\n\n# Funcion con una variable global\n\nvariable = 'Hola mundo'\n\ndef mi_codigo():\n    print(variable)\n\nmi_codigo()\n\nprint(variable)\n\n# DIFICULTAD EXTRA\n\ndef numbers(number_1,number_2):\n    count = 0\n    for numero in range(1,101):\n        if numero % 3 == 0 and numero % 5 == 0:\n            print (number_1 + ' '+ number_2)\n        elif numero % 3 == 0:\n            print(number_1 )\n        elif numero % 5 == 0:\n            print(number_2)\n        else:\n            print(numero)\n            count += 1\n    return count\n\nprint(numbers('Number_1', 'Number_2'))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/switchdays.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n \"\"\"\n\n# Función sin parámetros y sin retorno:\ndef get_name1():\n    print(\"Mariano\")\n\nget_name1()\n\n# Función sin parámetros y con retorno:\ndef get_name2():\n    name = \"Pablo\"\n    return print(name)\n\nget_name2()\n\n# Función con parámetros y sin retorno:\ndef get_name3(name):\n    print(name)\n\nget_name3(\"Adrián\")\n\n# Función con parámetros y con retorno:\ndef get_name4(name, surname):\n    return print(name + \" \" + surname)\n\nget_name4(\"Manolo\", \"García\")\n\n# Función dentro de otra función:\ndef rest_tax(profit): # profit es una variable local que solo es accesible dentro de la función rest_tax\n    def irpf_calculate(quantity):\n        if quantity < 1500:\n            tax = 10\n        elif quantity > 1500:\n            tax = 15\n        return float(tax)\n    total = profit  - ((irpf_calculate(profit)/100) * profit)\n    return total\n\nentrada = int (input(\"Introduzca su sueldo bruto mensual: \"))\nsalary = rest_tax(entrada) # salary es una variable global y puede ser utilizada en cualquier parte del código\nprint(salary)\n\n# Función ya creada en el lenguaje:\n\nlist1 = [5,10,7,15,45,3]\n\nprint(list(filter(lambda number: number >= 7, list1)))\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\"\"\"\n\ndef return_num(word1, word2):\n    counter = 0\n    for i in range(1, 100):\n        if i % 3 == 0 and i % 5 == 0:\n            counter += 1\n            print(word1 + \" \" + word2)\n        elif i % 3 == 0:\n            counter += 1\n            print(word1)\n        elif i % 5 == 0:\n            counter += 1\n            print(word2)\n        else:\n            print(i)\n    return counter\n\nprint(return_num(\"Hola\", \"Que tal\")) "
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/tekatoki.py",
    "content": "'''\n╔═══════════════════════════════════════╗\n║ Autor:  tekatoki                      ║\n║ GitHub: https://github.com/tekatoki   ║\n║ 2024 -  Python                        ║\n╚═══════════════════════════════════════╝\n\nExercise:\n- Create examples of basic functions that represent the difereents\npossibilities of the language:\n    Without parametres nor return, with one or other parametres, with return values...\n- Checks if you can create functions inside functions\n- LOCAL and GLOBAL variables\n- You must print in the CLI the results of all the examples made\n\nExtra dificulty (optional):\n- Create a function that has two string parametres and returns an int\nThe function prints all numbers from 1 to 100. Considering:\n    - If the number is multiple of 3, show the text of the first parametre\n    - If the number is multiple of 5, show the text of the second parametre\n    - If the number is multiple of 3 and 5, show the two parametres concadenated\n'''\ndef extra_difficulty (text_1:str, text_2:str):\n    for num in range(1, 100 + 1):\n        if 0 == num % 3 and 0 == num % 5:\n            print(text_1 + text_2)\n        elif 0 == num % 3:\n            print(text_1)\n        elif 0 == num % 5:\n            print(text_2)\n\ndef checks_multiple_2(num:int):\n    if num % 2 == 0:\n        return True\n    else:\n        return False\n\ndef personal_greet(name:str, surname:str, formality:bool = False):\n    if formality:\n        print(f'Hello, dear {surname}')\n    else:\n        print(f'Hello, {name} {surname}')\n\n\ndef greet():\n    print('Hello, python!')\n\nif __name__ == '__main__':\n    greet() # Without parametres and returns\n\n    user_name:str = input('Introduce your name>')    \n    user_surname:str = input('Introduce your surname>')\n\n    personal_greet(user_name, user_surname, formality=False) # With three parametres\n    print(checks_multiple_2(4)) # Function that returns something\n\n    extra_difficulty('Python', 'Mathematics')\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/thezhizn.py",
    "content": "'''\nfunciones basicas en python\nEjemplos:\n'''\n# funciones sin parametros\ndef decir_hola_mundo():\n     print(\"hola mundo\")\ndecir_hola_mundo() #esta funcion solo imprime lo indicado en el 'print'\n\n#funciones con parametros\ndef saludar(nombre):\n    print(\"como va tu dia \" + nombre + \"?\" )\nsaludar(\"michael\") #estamos indicando un parametro extra que pondremos en los parentesis \n\n#funcions con retorno\ndef multiplica():\n    return 3 * 2\n#aquí lo que hicimos fue indicar que cuando vamos a imprimir la funcion el valor del return sea usado \n\nvalor = multiplica()\nprint(valor)\n# aquí vemos que cuando la imprimimos el resultado es 6 porque la multuplicacion de el return es 2 * 3\n# la variable es por estetica, se puede solo poner 'print(multiplica())' y funciona igual\n\n'''\nfunciones dentro de funciones\n'''\ndef funcion_externa():\n    def funcion_interna():\n        print(\"soy la funcion interna\")\n    funcion_interna()\nfuncion_externa()\n\n'''\nfunciones del lenguaje\n'''\n\n'''función max()'''\nprint(max(1,2,3,4,16))\n#la funcion max nos da el valor mas grande de lo que estemos usando\nlist = ['a','b','c','d','h']\nprint(max(list))\n\n'''función min()'''\nprint(min(1,2,3,4,16))\nlist = ['a','b','c','d','h']\nprint(min(list))\n\n'''función divmod()'''\nprint(divmod(10,2))\n# divide los numeros y nos da el cociente (10 // 2) y el resto (10 % 2) que en este caso seria '5 , 0'\n\n'''función len()'''\nprint(len(\"hola amigos\"))\n# esta funcion nos cuenta la cantidad de caracteres del texto incluyendo los espacios \nlist1 = [123, 'abc', 'limon'] \nprint(len(list1))\n# tambien funciona para contar cuantos objetos hay en una lista y demas usos similares para contar\n\n'''función hex()'''\nprint(hex(24)) \n# funcion que los da un numero hexadecimal con el prefijo 'ox' en este caso seria 'ox18'\n\n'''función ord()'''\nprint(ord(\"j\"))\n#es una funcion que tranforma un caracter en el numero unicode de ese caracter\n#en este caso el numero Unicode de la letra 'J' es 106\n\n'''función chr()'''\nprint(chr(106))\n#transforma un numero Unicode en el caracter que representa (lo contrario a la funcion 'ord()')\n#en este caso el numero Unicode 106 representa el la letra 'J' y el numero Unicode 6 representa el caracter '♠'\n#si es numero que se escriba en la funcion no tiene un caracter Unicode, dara error. Ejemplo: print(chr(-10))\n\n'''función input()'''\n'''age = int(input(\"por favor ingresa tu edad: \"))\nprint(age)'''\n# input es una funcion que nos permite interactuar con el codigo ingresando informacion \n# en el ejemplo quiero solicitar la edad y ya que imput lee todo como un Str es bueno especificar el tipo de dato\n# en este caso como es la edad es un numero entero = int \n#si quieres probar el ejemplo porfavor quita las comillas ya que a lo largo del codigo tendras que ingresar el dato cuando lo ejecutes\n\n'''función type()'''\nprint(type(4))\n#la funcion type() me permite saber el tipo de dato que pongo en la funcion, en este caso un INT\n\n'''variables locales y globales'''\n#list es una varible definida es la linea 28\nprint(list)\nlist\n#es una variable global ya que puedo acceder a ella en cualquier momento porque esta en el cuerpo del codigo\n\ndef variable_local():\n    my_new_list = ['l', 'm', 'n', 'ñ']\n    print(my_new_list)\nvariable_local()\n\n'''print(my_new_list)\n'my_new_list' es una variable local, solo la puedo usar llamando la funcion.\nY si tratara de hacer un print normal daria error\n'''\n\n'''ejercicio extra'''\ndef juego(parametro1, parametro2):\n    numeros = 0 \n    for i in range(1 , 101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(parametro1 , parametro2)\n        elif i % 3 == 0:\n            print(parametro1)\n        elif i % 5 == 0:\n            print(parametro2)\n        else:\n            numeros += 1\n            print(i)\n    return (\"numero de veces que se imprimio un numero \", numeros)  \nprint(juego(\"multiplo de 3\", \"multiplo de 5\")) \n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/tito-delpino.py",
    "content": "\"\"\" EJERCICIO:\nCrea ejemplos de funciones básicas que representen las diferentes\nposibilidades del lenguaje:\nSin parámetros ni retorno, con uno o varios parámetros, con retorno...\n\"\"\"\n# Sin parametros ni retorno\ndef bienvenida():\n    print('Bienvenido!!')\n\nbienvenida() # llamamos a la funcion\n\n# Con uno o varios parametros\ndef area_cuadrado(lado):\n    print(lado * lado)\n\ndef area_rectangulo(lado1, lado2):\n    print(lado1 * lado2)\narea_cuadrado(4)\narea_rectangulo(3,4)\n\ndef saludar(nombre):\n    return f'Hola {nombre}'\n\nprint(saludar(\"Pepe\"))\n\ndef default_saludar(nombre=\"Usuario\", password =1234):\n    return f'Hola {nombre} tu contrasenia es {password}'\n\nprint(default_saludar('tito', 4567))\n\ndef multiples_args():\n    return \"Usuario\", 1234\n\nnombre, password = multiples_args()\nprint(nombre)\nprint(password)\n\n\n# Comprueba si puedes crear funciones dentro de funciones.\ndef funcion_externa():\n    def funcion_interna():\n        print('A esta funcion interna la llamamos desde la funcion externa')\n    funcion_interna()\n\nfuncion_externa() # llamamos a la funcion externa que llama a la interna\n\n\n# Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\nprint(len('len va a printear el largo de este string'))\nprint(max(4,6,7,4,3)) # max printea el maximo de los valores\nprint(min(4,6,7,4,3)) # min printea el minimo de los valores\nprint(sum([4,5,6,7,8,6,4]))\nprint(type('string')) # devuelve el tipo de variable\nprint(sorted([9,6,8,4,7,5,7,3,6,2,5,1])) # devuelve una lista ordenada\nprint('tito'.upper())\n\n\n# Pon a prueba el concepto de variable LOCAL y GLOBAL.\nvar_global ='Esta variable es accesible desde cualquier parte del codigo'\n\ndef funcion_con_variable_local():\n    var_local = 'esta variable solo es accesible desde la funcion'\n    print(f'print desde funcion de variable global - {var_global}')\n    print(f'print desde funcion de variable local - {var_local}')\n\n\nfuncion_con_variable_local()\nprint(f'print desde fuera de la funcion de variable global - {var_global}')\n\n\n\"\"\" DIFICULTAD EXTRA (opcional):\nCrea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n* La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n    Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n    Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n    Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n    La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\"\"\"\n\ndef funcion_prueba(string1, string2):\n    contador = 0\n    for num in range(1,101):\n        if num % 3 == 0 and num % 5 == 0:\n            print(string1 + string2)\n        elif num % 3 == 0:\n            print(string1)\n        elif num % 5 == 0:\n            print(string2)\n        else:\n            print(num)\n            contador += 1\n        \n    return contador\n\n\nresultado = funcion_prueba('Fizz', 'Buzz')\nprint(resultado)"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/tobiBordino.py",
    "content": "# 02 FUNCIONES Y ALCANCE\n\n'''\n- Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n'''\n\n# Funciones simples sin parámetros ni retorno\ndef funcionSinParametrosNiRetorno():\n    print(\"Función sin parámetros ni retorno\")\n\n# Funciones con parámetros\ndef funcionConParametros(parametro1, parametro2):\n    print(f\"Función con parámetros: {parametro1} {parametro2}\")\n\n# Funciones con retorno\ndef funcionConRetorno():\n    return \"Función con retorno\"\n\n# Funciones con parámetros y retorno\ndef print_numbers(parametro1, parametro2=\"Mundo\"):\n    return f\"Función con parámetros y retorno: {parametro1} {parametro2}\"\n\n# Llamada a funciones\nfuncionSinParametrosNiRetorno()\nfuncionConParametros(\"Hola\", \"mundo\")\n# La función con retorno se puede imprimir directamente\nprint(funcionConRetorno())\nprint(print_numbers(\"Hola\", \"mundo\"))\nprint(print_numbers(\"Hola\"))\n\n# Comprobación de crear funciones dentro de funciones\ndef funcionExterna():\n    def funcionInterna():\n        print(\"Función interna\")\n    funcionInterna()\n\nfuncionExterna()\n\n# Funciones propias de Python\nprint(\"--- Funciones propias del lenguaje PYTHON ---\")\nprint(len(\"Hola mundo\"))\nprint(type(\"Hola mundo\"))\nprint(\"Hola mundo\".upper())\n\n# - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n\n# Variable global\nvariableGlobal = \"Variable global\"\n\ndef funcionConVariableGlobal():\n    print(variableGlobal)\n\nfuncionConVariableGlobal()\n\n# Variable local\ndef funcionConVariableLocal():\n    variableLocal = \"Variable local\"\n    print(variableLocal)\n\nfuncionConVariableLocal()\n\n# Función con número variable de argumentos\ndef funcionConNumeroVariableDeArgumentos(*name):\n    for i in name:\n        print(f\"Hola {i}\")\n\nfuncionConNumeroVariableDeArgumentos(\"Python\", \"C#\")\n\n# Número variable de argumentos con palabra clave\ndef funcionConNumeroVariableDeArgumentosYPalabraClave(**name):\n    for key, value in name.items():\n        print(f\"Hola, {value} ({key})!\")\n\nfuncionConNumeroVariableDeArgumentosYPalabraClave(name=\"Python\" , language=\"C#\")\n\n# DIFICULTAD EXTRA\n'''\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n'''\n\ndef print_numbers(parametro1, parametro2):\n    contador = 0\n    for i in range(1, 101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(parametro1 + parametro2)\n        elif i % 3 == 0:\n            print(parametro1)\n        elif i % 5 == 0:\n            print(parametro2)\n        else:\n            print(i)\n            contador += 1\n    return contador\n\nprint(print_numbers(\"Texto1\", \"Texto2\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/tonywarcode.py",
    "content": "#función sin parámetros de entrada ni parámetros de salida\n\ndef say_hello():\n    print(\"Hola Python\")\n\nsay_hello()\n\n#funció con retorno\n\ndef retorno_hello():\n    return \"Hola Python2\"\n\n\nretrorno_h = retorno_hello()  #guardar en variable\nprint(retorno_hello())  #o imprimir\n\n\n#pasando un argumento de entrada\n\ndef say_hello2(nombre):\n    print(\"Hola\", nombre)\n    print(f\"holas,{nombre}!\")\n\nsay_hello2(\"Python3\")\n\n\n#varios argumentos con retorno\n\ndef suma(a, b):\n    return a+b\n\nprint(suma(10, 15))\n\n#con longitud variable\n\ndef suma1(*numeros):\n    print(type(numeros))\n    total = 0\n    for i in numeros:\n        total += i\n    return total\n\nprint(suma1(1, 2, 3, 4, 5))\n\n#con longitud variable y clave valor\n\ndef suma(**numeros):\n    suma = 0\n    for key, value in numeros.items():\n        print(key, value)\n        suma += value\n    return suma\n\nprint(suma(a=9, b=20, c=21, d=0))\n\n#funciones dentro de funciones\n\ndef funcion1():\n    def funcion2():\n        print(\"dentro de la funcion 2\")\n    funcion2()\n\nfuncion1()\n\n#documentacion que hace una funcion o como usarla\n\ndef mi_funcion_suma(a, b):\n    \"\"\"\n    Descripción de la función. Como debe ser usada,\n    que parámetros acepta y que devuelve\n    \"\"\"\n    return a+b\n\nhelp(mi_funcion_suma)\n\n#funciones del lenguaje\nprint(\"¡Hola, Python!\") #imprime \n\nprint(len(\"Hola python\"))  #longitud del objeto\n\nprint(type([1, 2, 3, \"green\"]))  #tipo de dato\n\nprint(\"hola, python\".upper()) #pone en mayusculas\n\nprint(range(20))  #rango de numeros\n\n#variable LOCAL y GLOBAL\n\nv_global = \"Python\"\nprint(v_global)\n\ndef hi_var_global():\n    v_local= \"Me encanta\"\n    print(v_local ,v_global)\n\nhi_var_global()\n#print(v_local) no se puede acceder a la variable de dentro de la función\n\n'''\n* DIFICULTAD EXTRA (opcional):\n'''\ndef print_numeros_con_texto(texto1, texto2):\n    # Inicializa un contador para los números impresos directamente\n    contador_numeros = 0\n    \n    # Itera sobre los números del 1 al 100\n    for i in range(1, 101):\n        # Si el número es múltiplo de 3 y de 5, imprime la concatenación de texto1 y texto2\n        if i % 3 == 0 and i % 5 == 0:\n            print(texto1 + texto2)\n        # Si el número es múltiplo de 3, imprime texto1\n        elif i % 3 == 0:\n            print(texto1)\n        # Si el número es múltiplo de 5, imprime texto2\n        elif i % 5 == 0:\n            print(texto2)\n        # Si el número no es múltiplo de 3 ni de 5, imprime el número\n        else:\n            print(i)\n            # Incrementa el contador de números impresos directamente\n            contador_numeros += 1\n\n    # Retorna el número de veces que se imprimieron los números directamente\n    return contador_numeros\n\n# Ejemplo de uso de la función con los textos \"Max\" y \"Mix\"\nnum_cont = print_numeros_con_texto(\"Max\", \"Mix\")\n\n# Imprime el número de veces que se imprimieron números en lugar de textos\nprint(f\"El número de veces que se imprimieron los números en lugar de los textos es: {num_cont}\")\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/toral24.py",
    "content": "# EJERCICIO:\n# - Crea ejemplos de funciones básicas que representen las diferentes posibilidades del lenguaje:\n# Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n# - Comprueba si puedes crear funciones dentro de funciones.\n# - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n# - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n# - Debes hacer print por consola del resultado de todos los ejemplos.\n# (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n\n\n# Función sin parametros:\n\ndef fun_no_parametros():\n    for i in range(5):\n        print(i)\n\nfun_no_parametros()\n\n# Función con un parametro\n\ndef fun_con_parametro(nombre):\n    print(\"¡Hola, \"+nombre+\"!\")\n\nfun_con_parametro(\"sergio\")\n\n# Función con dos parametros\n\ndef fun_con_return(num1, num2):\n    numeros_pares = []\n    i = num1\n    print(\"Estos son los numeros pares entre \"+str(num1)+\" y \"+str(num2))\n    while i < num2:\n        if i%2 == 0:\n            numeros_pares.append(i)\n        i +=1\n    print(numeros_pares)\n    \n    \nfun_con_return(1, 100)\n\n# Función con return y tres parametros\n\ndef fun_return(a=5, b=8, c = 3):\n    return (a*b)/c\n\nprint(fun_return())\n\n#Diferencia variable local y variable global\nvar = \"Esto es una variable global\"\ndef fun_var():\n    var = \"Esto es una variable local\"\n    return var\nprint(var)\nprint(fun_var())\ndef fun_var_glob():\n    global var\n    var = var + \" bis\"\n    return var\nprint(fun_var_glob())\n\n# Una función ya creada de python es print que se ha utilizado más arriba varias veces pero existen muchas más, a continuación se muestran algunos ejemplos:\nlen(var) #imprime la longitud de un string\nletra = \"a\"\nletra = ord(letra) #devuelve el codigo ascii de una letra\nprint(letra)\nletra = chr(letra) #convierte codigo ascii en su correspondiente simbolo\nprint(letra)\n\n# DIFICULTAD EXTRA (opcional):\n# Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n# - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n# - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n# - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n# - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n# - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\ndef fun_dif_extra(var1 :str, var2 :str):\n    contador = 0\n    for i in range(100):\n        if i%3 == 0:\n            if i%5 == 0:\n                print(var1+var2)\n            print(var1)\n        elif i%5 == 0:\n            print(var2)\n        else:\n            print(i)\n            contador += 1\n    return \"El número se ha impreso \"+str(contador)+\" veces.\"\nprint(fun_dif_extra(\"¡Hola, \",\"mundo!\"))\n\n\n# Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n# Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/txuky.py",
    "content": "### Funciones ###\n\n#funcion sin parametros\ndef my_function_basic():\n    print('Funcion basica')\n\nmy_function_basic()\n\n#funcion con parametros\ndef my_new_function_basic(first, second):\n    print(f'la suma de {first} y {second} es : ', first + second)\n\nmy_new_function_basic(9, 6)\n\n#funcion con retorno\ndef my_functtion_return(first, second):\n    return (first * second)\n\nmy_return = my_functtion_return(2, 6)\nprint( my_return)\n\ndef impr_name(name, surname ):\n    print(f'{name} {surname}')\n\n# le puedo cambiar el orden de los parametros pero no puedo omitir ninguno\nimpr_name('More' , 'Francesc')\nimpr_name(surname = 'More', name = 'Francesc') \n# impr_name(name = 'Francesc') da error\n\n#funciones con bucle\ndef my_funcion_pares(primero, ultimo):\n    while primero <= ultimo:\n        multip = (int(primero))\n        if (multip % 2) == 0:\n            print(primero)\n        primero +=1\n\nmy_funcion_pares(1,14)\n\n#funciones anidadas\n\ndef long_word(word):\n    ''' Cuenta los caracteres del argument entrado'''\n    print(len(str(word)))\n\nlong_word('pedrito')\n\n\ndef suma_valor(*nums):\n    '''suma los valores de un rango entre el mas peuqeño y el mayor de una lista de numeros'''\n    print(list(range(min(nums), max(nums))))\n    print(sum(range(min(nums), max(nums))))\n\nsuma_valor(1, 4, 5)\n\n\nmy_tipo = type(18)\nprint(my_tipo)\nprint(type('Hola'))\n\nfor i in range(3):\n    print(i)\n\nprint(len('Hola mundo'))\n\nprint(locals())\nprint(globals())\n\n\n''' funciones_integradas\nA\nabs()\naiter()\nall()\nanext()\nany()\nascii()\nB\nbin()\nbool()\nbreakpoint()\nbytearray()\nbytes()\nC\ncallable()\nchr()\nclassmethod()\ncompile()\ncomplex()\nD\ndelattr()\ndict()\ndir()\ndivmod()\nE\nenumerate()\neval()\nexec()\nF\nfilter()\nfloat()\nformat()\nfrozenset()\nG\ngetattr()\nglobals()\nH\nhasattr()\nhash()\nhelp()\nhex()\nI\nid()\ninput()\nint()\nisinstance()\nissubclass()\niter()\nL\nlen()\nlist()\nlocals()\nM\nmap()\nmax()\nmemoryview()\nmin()\nN\nnext()\nO\nobject()\noct()\nopen()\nord()\nP\npow()\nprint()\nproperty()\nR\nrange()\nrepr()\nreversed()\nround()\nS\nset()\nsetattr()\nslice()\nsorted()\nstaticmethod()\nstr()\nsum()\nsuper()\nT\ntuple()\ntype()\nV\nvars()\nZ\nzip()\n\n__import__()\n'''\n# DIFICULTAD EXTRA ejercicio\n\nprint ('-' * 20)\n\ndef dif_extr (param_a, param_b):\n    n = 1\n    a = 0\n    b = 0\n    while n <= 100:\n        \n        if (n % 3) == 0 and (n % 5) != 0:\n            print (param_a, end='/')\n            n += 1\n            a = a + 1\n\n        if (n % 5) == 0 and (n % 3) != 0:\n            print (param_b, end='/')\n            n += 1  \n            b = b + 1 \n        if (n % 3) == 0 and (n % 5) == 0:\n            print (f'{param_a} / {param_b}')\n            n += 1\n            a = a + 1\n            b = b + 1\n        if (n % 3) != 0 and (n % 5) != 0 and (n <= 100):\n            print(n, end='/')\n            n += 1\n    \n    print(f'\\n{param_a} se escribio {a} veces y {param_b} se escribio {b} veces')\n\ndif_extr ('casa', 'perro')"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/vdroiid.py",
    "content": "\"\"\"\r\nEjemplos de funciones básicas:\r\n    Sin parámetros ni retorno\r\n    Con uno o varios parámetros\r\n    Con retorno...\r\n\"\"\"\r\n# Suma sin parámetro ni retorno\r\ndef suma():\r\n    print(1+2)\r\n\r\n# Resta sin parámetro, pero con retorno\r\ndef resta():\r\n    return 2 - 1\r\n# Multiplicación con parámetro y retorno\r\ndef multi(a,b):\r\n    return a * b\r\n\r\n\"\"\"\r\nFunciones dentro de funciones\r\n\"\"\"\r\n# Función que contiene otra función\r\ndef saludo(nombre):\r\n    def complemento(nombre):\r\n        complemento = \"Hola, estimando\"\r\n        saludo = \"{} {}\".format(complemento,nombre)\r\n        return saludo\r\n    saludo = complemento(nombre)\r\n    return saludo\r\n\r\n\"\"\"\r\nVariable LOCAL y GLOBAL.\r\n\"\"\"\r\n\r\ndef ver():\r\n    # Esto es una variable locañ de la función ver()\r\n    palabra1 = \"Nuevo\"\r\n    # Esto ya es una variable global\r\n    global palabra2\r\n    palabra2 = \"Auntiguo\"\r\n    return palabra1, palabra2\r\n\r\n# <palabra1> no puede ser llamado aquí para usarlo, en cambio <palabra2> sí\r\n\r\n\"\"\"\r\nA continuación, imprimimos todas las funciones, utilizando la función print() de python\r\n\"\"\"\r\n\r\nprint(\"Esto es la función sin parámetro: {}\".format(suma()), \"Función con retorno, pero sin parámetro: {}\".format(resta()), \"Función con parámetro y retorno: {}\".format(multi(1,3)), \"Función dentro de otra función: {}\".format(saludo(\"Santos\")), sep=\"\\n\")\r\nprint(\"Esto es variable local de la función ver(): {}\".format(ver()[0]), \"Y esto es la variable global de ver(): {}\".format(ver()[1]), sep=\"\\n\")\r\n\r\n\"\"\"\r\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\r\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\r\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\r\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\r\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\r\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\r\n\"\"\"\r\n\r\ndef funcion(texto1, texto2):\r\n    for i in range(1,101):\r\n        numero = 0\r\n        if i % 3 == 0 and i % 5 == 0:\r\n            print(texto1+texto2)\r\n        elif i % 3 == 0:\r\n            print(texto1)\r\n        elif i % 5 == 0:\r\n            print(texto2)\r\n        else: numero+=1\r\n    return numero\r\n\r\nprint(funcion(\"texto1\",\"texto2\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/vicman-182.py",
    "content": "# #02 FUNCIONES Y ALCANCE\n#### Dificultad: Fácil | Publicación: 08/01/24 | Corrección: 15/01/24\n\n## Ejercicio\n\n'''\n* EJERCICIO:\n'''\n\n''' *** Funciones Basicas sin parametros ni retorno *** '''\n\ndef saludo():\n    print(\"Hola, python\")\n    \nsaludo()\n\n''' *** Funciones basicas con parametros *** '''\n\ndef suma(a,b):\n    print(f\"La suma de {a} + {b} = {a + b}\")\n\nsuma(3,4)\n\n''' *** Funciones basicas con retorno *** '''\ndef multiplicacion(a,b):\n    return a * b\n\nprint(f\"La multiplicacion de 3 * 2 = {multiplicacion(3,2)}\")\n\n'''\n * - Comprueba si puedes crear funciones dentro de funciones.\n'''\ndef funcion_():\n    def otra_funcion():\n        print(\"Esto es una funcion dentro de otra funcion\")\n    otra_funcion()\n\nfuncion_()\nprint()\nprint(12)\n\n'''\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n'''\nx = \"Variable Global\"\n\ndef variable():\n    x = \"Variable Local\"\n    print(x)\n\nvariable()\nprint(x)\n\n\n'''\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n'''\n\ndef funcion_extra(cadena_1,cadena_2):\n    contador = 0\n    for i in range(1,101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(cadena_1,cadena_2)\n        elif i % 3 == 0:\n            print(cadena_1)\n        elif i % 5 == 0:\n            print(cadena_2)\n        else:\n            contador +=1\n            print(i)\n    return contador\ncontador = funcion_extra(\"Fizz\",\"Buzz\")\nprint()\nprint(f\"La cantidad de veces que se imprimio un numero es {contador} veces\")\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/victorfer69.py",
    "content": "#FUNCIONES\n\n#FUNCIONES DEFINIDAS POR EL USUARIO\n\n#Simple\ndef greet():\n    print(\"Hola, Python!\")\n\ngreet()\n\n#Con retorno\ndef return_greet():\n    return \"Hola, Python!\"\n\nprint(return_greet())\n\n#Con un argumento\ndef arg_greet(name):\n    print(f\"Hola, {name}!\")\n\narg_greet(\"Python\")\n\n#Con argumentos\ndef args_greet(name, greet):\n    print(f\"{greet}, {name}!\")\n\nargs_greet(\"Python\",\"Hola\")\nargs_greet(greet=\"Hola\",name=\"Python\")\n\n#Con un argumento predeterminado\ndef default_arg_greet(name=\"Python\"):\n    print(f\"Hola, {name}!\")\n\ndefault_arg_greet(\"Python\")\ndefault_arg_greet()\n\n#Con argumentos y retorno\ndef return_args_greet(name, greet):\n    return(f\"{greet}, {name}!\")\n\nprint(return_args_greet(\"Python\",\"Hola\"))\n\n#Con retorno de varios valores\ndef multiple_retur_greet():\n    return \"Hola\", \"Python\"\n\ngreet, name = multiple_retur_greet()\nprint(f\"{greet}, {name}!\")\n\n#Con un número variable de argumentos\ndef variable_arg_greet(*names):\n    for name in names:\n        print(f\"Hola, {name}!\")\n\nvariable_arg_greet(\"Python\", \"Victor\", \"Todos\")\n\n\n#FUNCIONES DENTRO DE FUNCIONES\n\ndef outer_function():\n    def inner_function():\n        print(\"Hola, Python!\")\n    inner_function()\n\nouter_function()\n\n\n#FUNCIONES DEL LENGUAJE\n\nprint(len(\"Hola\"))\nprint(type(\"Hola\"))\nprint(\"Hola\".upper())\n\n\n#VARIABLES LOCALES Y GLOBALES\n\nglobal_variable = \"Python\"\n\ndef hello_python():\n    local_variable = \"Hola\"\n    print(f\"{local_variable}, {global_variable}!\")\n\n\nprint(global_variable)\n#print(local_variable)  No funciona al ser variable local de la funcion\nhello_python()\n\n\n#EJERCICIO EXTRA\n\ndef extra_function(cad1, cad2) -> int:\n    cont = 0\n    for i in range(1,101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(f\"{cad1} , {cad2}\")\n        elif i % 3 == 0:\n            print(cad1)\n        elif i % 5 == 0:\n            print(cad2)\n        else:\n            print(i)\n            cont += 1\n    return cont\n\nprint(extra_function(\"M3\",\"M5\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/warclimb.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Crea ejemplos de funciones básicas que representen las diferentes\n * posibilidades del lenguaje:\n * Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * Comprueba si puedes crear funciones dentro de funciones.\n * Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * Debes hacer print por consola del resultado de todos los ejemplos.\n\"\"\"\n\n# FUNCIONES BÁSICAS DE PYTHON\n\n# Ejemplo de función sin parámetros\ndef pi():\n    return 3.141592653589\n\n\n# Ejemplo de función con parámetros y sin retorno\ndef cifrar(texto, clave):\n    diccionario = \"abcdefghijklmnopqrstuvwxyz\"\n    # Convierte el texto a lista y sustituye cada letra por otra situada en el diccionario en la posición de las veces que indique la clave\n    texto = list(texto.lower()) # list y lower son funciones que vienen incluida en el lenguaje\n    for i in range(len(texto)): # range y len también vienen con Python\n        if texto[i] in diccionario:\n            # recorre el diccionario de izquierda a derecha\n            texto[i] = diccionario[(diccionario.index(texto[i]) + clave) % len(diccionario)]\n    # Convierte la lista en texto y lo devuelve\n    return \"\".join(texto)\n\n\n# Bueno, ya que estamos hago también la de descifrar, que es otra función sin parámetros y sin retorno\ndef descifrar(texto, clave):\n    diccionario = \"abcdefghijklmnopqrstuvwxyz\"\n    # Convierte el texto a lista y sustituye cada letra por otra situada en el diccionario en la posición de las veces que indique la clave\n    texto = list(texto.lower())\n    for i in range(len(texto)):\n        if texto[i] in diccionario:\n            # recorremos el diccionario de derecha a izquierda\n            texto[i] = diccionario[(diccionario.index(texto[i]) - clave) % len(diccionario)]\n    # Convierte la lista en texto y lo devuelve\n    return \"\".join(texto)\n\n# Ejemplo de función con parámetros y un retorno\ndef fuerza_gravitacional(masa1, masa2, distancia):\n    # constante de gravitación universal\n    G = 6.674 * (10 ** -11)\n    # \n    F = G * (masa1 * masa2) / (distancia ** 2)\n    return F\n\n# crear funciones dentro de una función\ndef procesar_datos(datos):\n    def limpiar_datos(datos):\n        datos = datos.replace(\",\", \".\")\n        return datos\n    def convertir_datos(datos):\n        datos = datos.split()\n        return datos\n    return convertir_datos(limpiar_datos(datos))\n\n\"\"\" * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n * Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n * Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n * Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n * La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\"\"\"\n\ndef retornaNumero(text1: str, text2: str) -> int:\n    # contar numero de veces que se imprime text1 y numero de veces text2\n    text1_contador = 0\n    text2_contador = 0\n    for x in range(1, 101):\n        if x % 3 == 0 and x % 5 == 0:\n            print(text1 + text2)\n            text1_contador += 1\n            text2_contador += 1\n        elif x % 3 == 0:\n            print(text1)\n            text1_contador += 1\n        elif x % 5 == 0:\n            print(text2)\n            text2_contador += 1\n        else:\n            print(x)\n\n    return f\"Se ha impreso: \\n {text1}: {text1_contador} veces \\n {text2}: {text2_contador} veces\"\n        \n##################################\n# Vamos con el codigo principal:\n##################################\n\nif __name__ == \"__main__\":\n    # Función sin parámetros que devuelve el número PI\n    print(\"__Ejemplo función sin parámetros que devuelve el número PI__\")\n    print(f\"Número PI: {pi()}\")\n\n    # Función con parámetros y sin retorno que cifra un texto\n    print(\"__Ejemplo función con parámetros y sin retorno que modifica una variable global__\")\n    cifrado = cifrar(\"Hola Mundo\", 5878)\n    print(f\"Texto cifrado: {cifrado}\")\n\n    # Función sin parámetros y sin retorno que descifra un texto\n    descifrado = descifrar(cifrado, 5878)\n    print(f\"Texto descifrado: {descifrado}\")\n    print(\"-\"*48)\n\n    # Función con parámetros que calcula la gravitacional entre dos cuerpos\n    ## Vamos a calcularla entre la Luna y la Starship con la info de masa y distancia\n    print(\"__Ejemplo función con parámetros___\")\n    masa_luna = 7.342 * 10**22\n    masa_starship = 5000000\n    distancia_luna_starship = 384402 # aqui iria alguna info de posicion dinamica, pero bueno... es un ejemplo\n    \n    ## Calculamos y mostramos resultado\n    print(f\"Fuerza gravitacional entre la Luna y la Starship en órbita: {fuerza_gravitacional(masa_luna, masa_starship, distancia_luna_starship)}\")\n    print(\"-\"*48)\n\n    # Funciones lambda, esto es un tipo de función simple y sin nombre que se puede usar en cualquier parte del código\n    ## vamos a usarla para calcular la energía cinematica de un cuerpo\n    print(\"__Ejemplo función Lambda__\")\n    energia_cinetica = lambda masa, velocidad: (masa * velocidad ** 2) / 2\n    print(f\"Energía cinética del cuerpo es de: {energia_cinetica(10, 5)} j\")  \n\n    print(\"-\"*48)\n\n    # Funciones dentro de funciones\n    print(\"__Ejemplo función dentro de función__\")\n    print(procesar_datos(\"40, 55, 87, 65, 8, 6, 00, 78, 9, 68\"))\n    print(\"-\"*48)\n\n    # Mostramos el ejercicio extra\n    print(\"__Ejercicio extra__\")\n    print(retornaNumero(\"Fizz\",\"Buzz\"))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/willr30.py",
    "content": "'''\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n */\n\n'''\n\n#definimos una variable global\nesto_es_una_variable_global=\"Variable_local\"\n\n#funcion sin parametros\ndef funcion_sin_parametros():\n    print(\"Esto es una funcion sin parámetros\")\n\n#Funcion que recibe un parámetro\ndef funcion_con_parametros(nombre):\n    print(f\"Esto es un saludo para => {nombre}\")\n\n#funcion con un parámetro y el tipo de dato definido\ndef funcion_con_tipo_de_datos_definido(ciudad : str):\n    print(f\"Quiero viajar a {ciudad}\")\n\n#funcion con parametros definidos y tipos de datos\ndef funcion_con_parametros_definidos_suma(a:int = 2, b: int = 0):\n    print(f\"El resultaod es {a+b}\")\n\n#funcion con retorno y parámetro definido\ndef funcion_con_retorno(comida:str):\n    return f\"Quisier probar {comida} algún día\"\n\ndef funcion_mostrando_variable_global():\n    print(f\"{esto_es_una_variable_global}\")\n\n#funcion que mustra las tablas de multiplcar segun una variable local (que solo existe dentro de la funcion)\ndef funcion_con_variable_local():\n    tabla_de_multiplicar=input(\"Escribe una tabla de multiplicar => \")\n\n    for i in range (0,12):\n        print(f\"{tabla_de_multiplicar} * {i} = {tabla_de_multiplicar*i}\")\n\n\n# Llamada a las funciones\nfuncion_sin_parametros()\nfuncion_con_parametros(\"Juan\")\nfuncion_con_tipo_de_datos_definido(\"Managua\")\nfuncion_con_parametros_definidos_suma(3, 5)\n\nresultado_retorno = funcion_con_retorno(\"Gallo pinto\")\nprint(resultado_retorno)\n\nfuncion_mostrando_variable_global()\nfuncion_con_variable_local()\n#Extra\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\"\"\"\n\ndef extra(texto_1:str, text_2:str):\n    contador=0\n    #mostramos los numeros del 1 al 100\n    for i in range (0,100):\n        if i % 3 :\n            print(texto_1)\n        elif i % 5:\n            print(text_2)\n        elif i%3 and i%5:\n            print(f\"{texto_1} {text_2}\")\n        else:\n            #si las condiciones anteriores no se cumplen se mostrarpa en pantalla el numero\n            print(i)\n            contador+=1\n\n    return contador\n\n\n\nprint(extra(\"primer texto\", \"segundo texto\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/worlion.py",
    "content": "\"\"\"\nTipos de funciones\n\"\"\"\n\nprint(\"\\n ---- Tipos de funciones ----\\n\")\n\n# Sin parámetros ni retorno\ndef no_param_no_return():\n    # Function body\n    print(\"Hola! soy una función sin parámetros ni retorno.\")\n\nno_param_no_return()\n\n# Con retorno  \ndef retorno():\n    # Function body\n    print(\"Hola! soy una función con retorno, y te devuelvo un 5\")\n    return 5\n\nprint(retorno())\n\n# Con un parámetro SIN retorno\ndef saludo(nombre):\n    # Function body\n    print(f\"Hola! soy una función con un parámetro, y te saludo a ti, {nombre}\")\n\nsaludo(\"Worlion\")\n\n# Con un parámetro predeterminado\ndef saludoDef(nombre=\"Worlion\"):\n    # Function body\n    print(f\"Hola! soy una función con un parámetro POR DEFECTO ('Worlion'), y te saludo a ti, {nombre}\")\n    \nsaludoDef()\nsaludoDef(\"Juan\")\n\n# Con parámetros y retorno\ndef suma(a, b):\n    # Function body\n    print(\"Hola! soy una función con parámetros y retorno, y te devuelvo la suma de los dos parámetros\")\n    return a + b\n\nprint(suma(2, 3))\n\n#retorno multiple\ndef return_args_greet():\n    return \"Hola\", \"Worlion\"\n\nprint(return_args_greet())\n\nsaludo, nombre = return_args_greet()\nprint(saludo)\nprint(nombre)\n\n#Con nume3ro variable de argumentos\ndef variable_arg_saludo(*nombres):\n    for nombre in nombres:\n        print (f\"Hola, {nombre}!\")\n        \nvariable_arg_saludo(\"Worlion\", \"Mou\", \"Pepito\", \"Peña\")\n\n# Con un número variable de argumentos con palabra clave\n\n\ndef variable_key_arg_greet(**names):\n    for key, value in names.items():\n        print(f\" - {key} = {value}!\")\n\n\nvariable_key_arg_greet(\n    language=\"Python\",\n    name=\"Imanol\",\n    alias=\"Worlion\",\n    age=40\n)\n\n\"\"\"\nFunciones dentro de funciones\n\"\"\"\n\nprint(\"\\n ---- Funciones dentro de funciones ----\\n\")\n\ndef funcionExterna():\n    def funcionInterna():\n        print(\" - Soy una función interna\")\n    print(\"Soy una función externay voy a llamar a la interna:\")\n\n    funcionInterna()\n    \nfuncionExterna()\n\n\"\"\"\nFunciones predefinidas del lenguaje\n\"\"\"\nprint(\"\\n ---- Funciones definidas en el lenguaje ----\\n\")\n\nname = \"Worlion\"\nprint(f\"len: {len(name)}\")\narray = [10, 52, 32, 14, 25]\nprint(f\"max: {max(array)}\")\n\n\"\"\"\nvariable LOCAL y GLOBAL\n\"\"\"\n\nprint(\"\\n ---- Variable local y global ----\\n\")\nvar_global = \"Worlion\"\n\ndef funcion():\n    var_local = \"Python\"\n    print(f\"Variable local: {var_local}\")\n    print(f\"Variable global: {var_global}\")\n    \nprint(\"aqui puedo usar la variable global: \", var_global)\nprint(\"aqui NO puedo usar la variable local:  :(\")\n\n\"\"\"\nDIFICULTAD EXTRA (opcional)\nCrea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n- La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n  - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n  - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n  - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n  - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\nPresta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\nCada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n\"\"\"\n\nprint(\"\\n ---- 🌩 DIFICULTAD EXTRA 🌩 ----\\n\")\n\ndef funcionExtra(text1, text2):\n    count = 0;\n    def multiplo(a, b):\n        return a % b == 0\n        \n    for i in range(1,100):\n        if(multiplo(i, 3) and multiplo(i,5)):\n            print(text1 + text2)\n        elif(multiplo(i,3)):\n            print(text1)\n        elif(multiplo(i,5)):\n            print(text2)\n        else:\n            print(i)\n            count += 1\n    \n    return count;\n        \nprint(\"total: \" + str(funcionExtra(\"chori\", \"pan\"))  )\n            \n    "
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/xemita007.py",
    "content": "# #02 FUNCIONES Y ALCANCE\n#### Dificultad: Fácil | Publicación: 08/01/24 | Corrección: 15/01/24\n\n## Ejercicio\n\n'''\n\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n'''\n\n\n#Funciones sin parametros\n\ndef my_function():\n    print(\"mi primera función\")\n\nmy_function()\n#Funciones sin parametros con retorno\ndef my_function():\n    return print(\"función con retorno\")\n\nmy_function()\n\n#Funciones con parametros\ndef my_function(numero1,numero2):\n    print(numero1+numero2)\n\n\nmy_function(5,5)\n\ndef my_strings(text1,text2):\n    print(f\"{text2}{text1}\")\n\nmy_strings(\"hola\",\"adios\")\n\n#Función dentro de otra función con lambda y sin lambda\ndef my_function(numero1, numero2):\n    resultado = lambda numeroL1, numeroL2: numero1 + numero2 + numeroL1 * numeroL2\n    return resultado\nprint(\"ejecutamos función con lambda dentro \",my_function(5,5)(2,2))\n\ndef my_function(numero1, numero2):\n    def resultado(numeroL1, numeroL2): \n        return numero1 + numero2 + numeroL1 * numeroL2\n    return resultado\n\nprint(\"Resultado de una función dentro de otra: \",my_function(5,5)(2,2))\n\n# Uso de la función principal\nresultado_adicional = my_function(5, 5)(2, 2)\nprint(\"metemos la función en una variable \",resultado_adicional)\n\n\n#Funciones creadas por el sistema \n\nmiMombre=input()\nprint(\"Mi nombre es... \",miMombre)\n\ndef imprimirMayusculas(*texts):\n    for text in texts:\n        print(text.upper())\n\nimprimirMayusculas(\"hola\",\"adios\",\"hasta luego\")\n\n\n#Dificulta Extra :\nnumeros=range(1,101)\n\ndef dificultaExtra (parametro1,parametro2):\n    contador=0\n    for numero in numeros:\n      \n        if numero%3==0 and numero%5==0:\n            print(parametro1,parametro2)\n        elif numero%3==0:\n            print(parametro1)\n        elif numero%5==0:\n            print(parametro2)\n        else:\n            print(numero)\n            contador+=1\n\n\n    return contador\n\nprint(dificultaExtra(\"multiplo de 3 \",\"multiplo de 5\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/yah1r404.py",
    "content": "\"\"\"\nFUNCIONES DEFINIDAS X EL USUARIO\n\"\"\"\n# SIMPLE\n\ndef salu2():\n    print(\"hola, python!\")\n    \nsalu2()\n\n# CON RETORNO\n\ndef return_salu2():\n    return \"Hola, python!\"\n\nprint(return_salu2())\n\n# CON ARGUMENTO\n\ndef saludo_name(name):\n    print(f\"hola, {name}!\")\n\nsaludo_name(\"yahir\")\n\n# CON ARGUMENTOS\n\ndef saludo_name(saludo, nombre):\n    print(f\"{saludo}, {nombre}\")\n\nsaludo_name(\"hola\", \"yahir!\")\n\n# CON ARGUMENTO PREDETERMINADO\n\ndef default_arg_saludo(name=\"python\"):\n    print(f\"Hola, {name}!\")\n\ndefault_arg_saludo(\"benja\")\ndefault_arg_saludo()\n\n# CON ARGUMENTOS Y RETORNO\n\ndef jujutsu_kaisen(okkotsu, toji, sukuna):\n    return f\"{okkotsu}, {toji}, {sukuna}\"\n\nprint(jujutsu_kaisen(\"hechicero\", \"antagonista\", \"villano\"))\n\n# CON RETORNO DE VARIOS VALORES\n\ndef multiple_greet_return():\n    return \"hola\", \"python\"\n\ngreet, name = multiple_greet_return()\nprint(greet)\nprint(name)\n\n# CON UN NÚMERO VARIABLE DE ARGUMENTOS\n\ndef variable_arg_arcane(*names):\n    for name in names:\n        print(f\"Hola, {name}!\")\n\nvariable_arg_arcane(\"Vi\", \"Viktor\", \"Jinx\", \"Ecko\", \"Silco\")\n\n# CON UN NÚMERO VARIABLE DE ARGUMENTOS CON PALABRA CLAVE\n\ndef variable_key_arg_arcane(**names):\n    for key, value in names.items():\n        print(f\"{value} ({key})!\")\n\nvariable_key_arg_arcane(\n    Rojo=\"Vi\",\n    Castaño=\"Viktor\",\n    Azul=\"Jinx\",\n    Blanco=\"Ecko\",\n    Negro=\"Silco\"\n)\n\n\"\"\"\nFUNCIONES DENTRO DE FUNCIONES\n\"\"\"\n\ndef funcion_externa():\n    def funcion_interna():\n        print(\"Función interna: Hola, Pythoooon!\")\n    funcion_interna()\nfuncion_externa()\n\n\"\"\"\nFUNCIONES DEL LENGUAJE PYTHON! (built-in)\n\"\"\"\n\n# Funciones de tipo y longitud\nprint(len(\"quesadilla sin queso\"))        # Mide cuántos caracteres tiene el string\nprint(type(99999))                        # Devuelve el tipo de dato del valor\n\n# Métodos de strings (no son built-in globales, pero sí muy usados)\nprint(\"quesadilla sin queso\".upper())    # Convierte el string a mayúsculas\nprint(\"QUESADILLA CON QUESO\".lower())    # Convierte el string a minúsculas\nprint(\"   hola mundo   \".strip())        # Elimina espacios al principio y final\nprint(\"quesadilla con queso\".replace(\"con\", \"sin\")) # Reemplaza parte del string\nprint(\"queso,pan,tomate\".split(\",\"))     # Separa un string por comas\n\n# Funciones numéricas\nprint(abs(-25))                          # Valor absoluto\nprint(round(3.14159, 2))                 # Redondea con 2 decimales\nprint(pow(2, 3))                         # Potencia: 2^3\n\n# Conversión de tipos\nprint(int(\"5\"))                          # Convierte string a entero\nprint(str(100))                          # Convierte número a string\nprint(float(\"3.14\"))                     # Convierte string a float\nprint(bool(0))                           # Devuelve False porque 0 es considerado \"falsy\"\n\n# Funciones sobre colecciones\nprint(max([3, 7, 1]))                    # Mayor valor\nprint(min([3, 7, 1]))                    # Menor valor\nprint(sum([1, 2, 3, 4]))                 # Suma de todos los elementos\nprint(sorted([3999, 119, 40, 221]))              # Ordena los elementos\n\n# Funciones útiles varias\nprint(chr(65))                           # Convierte número a letra según ASCII (65 = 'A')\nprint(ord('A'))                          # Convierte letra a su número ASCII\n\n\"\"\"\nVARIABLES LOCALES Y GLOBALES\n\"\"\"\nglobal_var = \"I am global\"\n\ndef scope_example():\n    local_var = \"I am local\"\n    print(global_var)   # Accessing global inside function\n    print(local_var)\nscope_example()\nprint(global_var)\n\n\"\"\"\nEJERCICIO EXTRA\n\"\"\"\n\ndef extra_func(extra_1, extra_2)->int:\n    count = 0\n    for i in range(1, 101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(extra_1 + extra_2)       \n        elif i % 3 == 0:\n            print(extra_1)\n        elif i % 5 == 0:\n            print(extra_2)\n        else:\n            print(i)\n            count += 1\n    return count\n\nprint(extra_func(\"Fizz\", \"Buzz\"))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/ycanas.py",
    "content": "# --------- Funciones\n\n# --- I. Tipos\n\n# 1. Sin parametros y sin retorno\n\ndef sin_parametros_sin_retornos():\n    print(\"No recivo valores ni retorno valores.\")\n\n\n# 2. Con parametros y sin retorno\n    \ndef con_parametros_sin_retornos(parametro):\n    print(f\"Este es mi parametro: {parametro}, pero no retorno nada\")\n\n\n# 3. Sin parametros y con retorno\n    \ndef sin_parametros_con_retorno():\n    return \"No recivo parametros pero si retorno valores.\"\n\n\n# 4. Con parametros y con retorno\n\ndef con_parametros_con_retorno(parametro):\n    return f\"Estoy retornando mi parametro: {parametro}\"\n\n\n# 5. Con varios parametros y retornos\n\ndef varios_parametros_varios_retornos(parametro1, parametro2):\n    return f\"Parametro 1: {parametro1}\", f\"Parametro 1: {parametro2}\"\n\n\nsin_parametros_sin_retornos()\ncon_parametros_sin_retornos(\"Soy un parametro\")\nsin_parametros_con_retorno()\ncon_parametros_con_retorno(\"Soy un parametro\")\nvarios_parametros_varios_retornos(\"Soy un parametro\", \"Y yo otro\")\n\n\n# --- II. Función dentro de función\n\ndef funcion():\n    def funcion2():\n        print(\"Y yo estoy dentro de ti 😈\")\n\n\n    print(\"Soy una función...\")\n    funcion2()\n\n\n# --- III. Funciones creadas dentro del lenguaje\n    \na = [x for x in range(100)]\nb = len(a)\nprint(f\"Soy la funcion len() y retorno la longitud de un objeto: {b}\")\n\n\n# --------- Variables\n\n# --- I. Globales\n\nvariable_global = 5\n\n\ndef vg():\n    global variable_global\n    variable_global = 0\n\n\nvg()\nprint(f\"Global: {variable_global}\")\n\n# --- II. Locales\n\nvariable_local = 5\n\n\ndef vl():\n    variable_local = 0\n    print(f\"Varible local: {variable_local}\", end=\", \")\n\n\nvl()\nprint(f\"Variable local: {variable_local}\")\n\n\n# --------- Extra\n\ndef extra(str1: str, str2: str) -> int:\n    cont = 0\n\n    for i in range(1, 101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(str1 + str2)\n        \n        elif i % 3 == 0:\n            print(str1)\n\n        elif i % 5 == 0:\n            print(str2)\n\n        else:\n            cont = cont + 1\n            print(i)\n\n    return cont\n\n\nextra(\"uno\", \"dos\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/yeam-10.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n .\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n \"\"\"\n\n\"\"\"\n\nRESPUESTA\nLa funcion es un bloque de codigo fuente que contiene un conjunto \nde instrucciones y que puede ser utilizada \ndesde el codigo fuente que escribes tantas veces como necesites.\n\"\"\"\n\n#Sin parametro ni retorno\ndef saludar():\n    print(\"Hola buenos dias\")\nsaludar()\n\n\n#Con parametro sin retorno\n\ndef EsMayorQueCero(param):\n    if param > 0:\n        print(param, \"es mayor que cero\")\n    else:\n        print(param,\"no es mayor que cero\")\nnumero = int(input(\"Introduce un numero:\"))\nEsMayorQueCero(numero)\n\n#Con varios parametros y retorno\n\ndef Sumar(param1, param2):\n    return param1 + param2\nsumando1 = int(input(\"Introduce el primer numero:\"))\nsumando2 = int(input(\"Introduce el segundo numero:\"))\nresultado = Sumar(sumando1,sumando2)\nprint(\"EL resultado de la suma es:\", resultado)\n\n#Funciones dentro de otra funcion\n\ndef funcion1():\n    def funcion2():\n        print(\"Imprime funcion 2\")\n    print(\"Imprime funcion 1\")\n    funcion2()\nfuncion1()\n\nprint(\"Ejemplo de funcion creada en python\", {round(65.987)})\n\n#Ejemplo de una variable global\n\nx = 20\n\ndef mostrarX():\n    print(\"El valor de X es\", x)\nmostrarX()\n\n#Ejemplo de variable local\n\ndef mostraLocal(num):\n    n = 20\n    return num * n\nprint(mostraLocal(6))\n\n\n\n#DIFICULTAD EXTRA (opcional):\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos\n\"\"\"\n\ndef EjercicioExtra(cadena1, cadena2):\n    count = 0\n    for i in range(1,101):\n        if i % 5 == 0 and i % 3 == 0:\n            print(cadena1+cadena2)\n        elif i % 3 == 0:\n            print(cadena1)\n        elif i % 5 == 0:\n            print(cadena2)\n        else:\n            print(i)\n            count += 1\n    return count\nprint(\"Numero de veces\", {EjercicioExtra(\"Mickey\",\"Mouse\")} )"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/yenneralayon142.py",
    "content": "\"\"\"\nFunciiones definidas por el usuario\n\"\"\"\n\n# Simple\n\ndef simple():\n    print(\"Hola mundo\")\n\n\n# Con retorno\n    \ndef retorno():\n    return \"Hola,Python\"\n\n\n# Con parametro\n\ndef parametro(futbol):\n    print(f\"Hola,{futbol}\")\n\nparametro(\"Cristiano\")\n\n\n# Con parametros\ndef parametros(champions,messi):\n    print(f\"{champions} tiene {messi}\")\n\nparametros(0,\"messi\")\nparametros(champions=\"messi\",messi=0)\n\n\n# Con parametros predeterminados\n\ndef predeterminados(adverbio=\"no\"):\n    print(f\"{adverbio}, usar python\")\n\n\n# Con argumentos y return \n    \ndef argumento(casa,cosa):\n    return f\"{casa},{cosa}\"\nprint(argumento(\"Hola\" , \"Yenner\"))\n\n\n# Con un número varible de argumentos\n\ndef variable(*names):\n    for name in names:\n        print(f\"hola, {name}\")\n\nvariable(\"Gonzalo\", \"David\", \"Antonio\")\n\n\n# Con un número variable de argumentos con palabra clave\n\ndef palabrasclave(**names):\n        for key, value in names.items():\n            print(f\"{value} ({key})!\")\n\n\npalabrasclave(\n    language=\"Español\",\n    name=\"Millos\",\n    alias=\"El más grande\",\n    age=20\n)\n\n\n\"\"\"\nFunciones dentro de Funciones\n\n\"\"\"\n\ndef funcionExterna():\n    def funcionInterna():\n        print(\"Hola a todos soy una función interna\")\n    funcionInterna\nfuncionExterna()\n\n\n\"\"\"\n\nVariables locales y globales\n\n\"\"\"\n\nglobal_var = \"Xolo\"\n\ndef outside():\n    local_var = \"Milloz\"\n    print(f\"{global_var},{local_var}\")\n\n# No se puede acceder a local var desde fuera de la función\n    \ndef fizzbuzz(text1,text2) -> int:\n\n    count = 0\n\n    for i in range(1,101):\n        if i % 3 == 0 and  i % 5 == 0:\n            print(text1 + text2)\n        elif i % 3 == 0:\n            print(text1)\n        elif i % 5 == 0:\n            print(text2)\n        else:\n            print(i)\n            count += 1\n    return count\n\nprint(fizzbuzz(\"fizz\",\"Buzz\"))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/yharyarias.py",
    "content": "# Funciones básicas que representen las diferentes posibilidades del lenguajee\ndef hello_world():\n    print(\"¡Hello world!\")\nhello_world()\n\ndef greeting(name):\n    print(f\"Hello {name}\")\ngreeting('Yhary')\n\ndef addition(num1, num2):\n    result = num1 + num2\n    print(f\"El resultado de la suma de los números {num1} y {num2} es {result}\")\naddition(4, 6)\n\ndef get_number():\n    return 42\nreult = get_number()\nprint(f\"The number obtained is: {reult}\")\n\ndef square(num):\n    return num ** 2\nresult = square(5)\nprint(f\"The square of 5 is: {result}\")\n\ndef multiply(a, b):\n    return a * b\nresult = multiply(4, 6)\nprint(f\"El resultado de la multiplicación es: {result}\")\n\n# -------------------------------------------------------------\n# Funciones dentro de funciones\ndef operators(a, b):\n    def addition():\n        return a + b\n\n    def subtraction():\n        return a - b\n\n    def multiplication():\n        return a * b\n\n    def division():\n        if b != 0:\n            return a / b\n        else:\n            return \"Error: Cannot divide by zero.\"\n\n    result_addition = addition()\n    result_subtraction = subtraction()\n    result_multiplication = multiplication()\n    result_division = division()\n\n    print(f\"Addition: {result_addition}\")\n    print(f\"Subtraction: {result_subtraction}\")\n    print(f\"Multiplication: {result_multiplication}\")\n    print(f\"Division: {result_division}\")\noperators(10, 5)\n\n# -------------------------------------------------------------\n# Funciones del lenguaje\n# sorted()\nprint(\"Ordered list:\", sorted([4, 1, 8, 3, 7]))\n# len()\nprint(\"List size:\", len([4, 1, 8, 3, 7]))\n#sum()\nprint(\"Sum of the elements of the list:\", sum([4, 1, 8, 3, 7]))\n# type()\nnum = 3\nprint(\"Data type:\", type(num))\n# max()\nprint(\"Largest item in the list:\", max([4, 1, 8, 3, 7]))\n# min()\nprint(\"Smallest item in the list:\", min([4, 1, 8, 3, 7]))\n# str()\nprint(\"Number as string:\", str(num))\n# list()\nmy_tuple = (1, 2, 3, 4, 5)\nprint(\"Tuple as list:\", list(my_tuple))\n\n# -------------------------------------------------------------\n# DIFICULTAD EXTRA (opcional):\ndef function(a: str, b: str) -> int:\n    counter = 0\n    for i in range(1, 101):\n        if i % 3 == 0:\n            print(a)\n        elif i % 5 == 0:\n            print(b)\n        elif i % 3 == 0 and i % 5 == 0:\n            print(a, b)\n        else:\n            counter += 1\n\n    return print(f\"{counter} numbers are not multiplies of 3 and 5\")\n\nfunction(\"Multiplo of 3\", \"Multiplo of 5\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/yoezequiel.py",
    "content": "def saludar():\n    print(\"¡Hola, mundo!\")\n\n\nsaludar()\n\n\ndef saludar_persona(nombre):\n    print(\"¡Hola,\", nombre, \"!\")\n\n\nsaludar_persona(\"Juan\")\n\n\ndef suma(a, b):\n    return a + b\n\n\nresultado = suma(3, 5)\nprint(\"La suma es:\", resultado)\n\n\ndef exterior():\n    def interior():\n        print(\"¡Función interior!\")\n\n    print(\"¡Función exterior!\")\n    interior()\n\n\nexterior()\nnombre = \"Juan\"\nlongitud = len(nombre)\nprint(\"La longitud del nombre es:\", longitud)\n\nx = 10  # Variable global\n\n\ndef funcion():\n    x = 5  # Variable local\n    print(\"Dentro de la función, x es:\", x)\n\n\nfuncion()\nprint(\"Fuera de la función, x es:\", x)\n\n\ndef imprimir_numeros(texto1, texto2):\n    contador = 0\n    for i in range(1, 101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(texto1 + texto2)\n        elif i % 3 == 0:\n            print(texto1)\n        elif i % 5 == 0:\n            print(texto2)\n        else:\n            print(i)\n        contador += 1\n    return contador\n\n\nnum_impresiones = imprimir_numeros(\"Fizz\", \"Buzz\")\nprint(\"Número de impresiones:\", num_impresiones)\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/zakkdrte.py",
    "content": "'''\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n \n'''\n\n# funcion simple sin parametro ni return \ndef simple():\n    print(\"Esta es una funcion simple\")\n\nsimple() \n\n# funcion con parametros y un formateo\ndef funcion_con_parametros(name,surname):\n    print(f\"Mi nombre es {name} y mi apellido es {surname}\")\n    \nfuncion_con_parametros(\"Juan\", \"Chavez\")\n\n# funcion sin parametros pero con return\ndef retorno_sin_parametros():\n    resultado = 2 + 5\n    return resultado\nprint(retorno_sin_parametros())\n\n# funcion con parametros y un return\ndef retorno_con_parametros(num1,num2):\n    resultado = num1 + num2\n    return resultado\nprint(retorno_con_parametros(10,5))\n\n# funcion en funcion\ndef funcion_en_funcion(a):\n    def funcion(b):\n        suma_de_valores = a + b\n        return suma_de_valores\n    return funcion(5)\n\nprint(funcion_en_funcion(2))\n\n# funcion en funcion pero introduciendo los valores en el print donde llamamos la funcion\ndef funcion_en_funcion(a):\n    def funcion(b):\n        suma_de_valores = a + b\n        return suma_de_valores\n    return funcion\n\nprint((funcion_en_funcion(6))(8))\n\n# funcion con valor por defecto \ndef funcion_valor_por_defecto(name = \"JUAN\"):\n    return name\nprint(funcion_valor_por_defecto())\n\n# funcion con variable local\ndef local_value():\n    local_value_1 = \"Juanito\"\n    local_value_2 = \"Sanchez\"\n    return (f\"Hola mi nombre es {local_value_1} y mi apellido es {local_value_2}\")\n\nprint(local_value())\n\n# funcion con variable global\ndef global_value():\n    global global_value_1\n    global global_value_2\n    \n    global_value_1 = 24\n    global_value_2 = 58\n    result = global_value_1 + global_value_2\n    return (f\"la suma entre 24 y 58 es: {result}\")\n\nprint(global_value())\n\n# print de una lambda que se igualo a una variabl, y que el print tiene formateo\nmultiplicacion_entre_valores = lambda x,y,z: x*y*z\n\nprint(f\"Esta es el resultado de multiplicar 10*10*10: {multiplicacion_entre_valores(10,10,10)}\")\n'''\n* DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n'''\n# se uitliza ciclo for en una funcion para imprimir los numeros y luego se le pone condicionales para poder hacer uso de los parametros que se necesitan para el reto\n# para averiguar si un numero es multiplo del otro se utiliza el % que devuelve el residuo de un numero divido por el otro, ya que si un numero es multiplo de otro su residuo siempre sera 0. \ndef function(value1, value2):\n    numeros_no_cumplidos = 0\n    for i in range(1,101):\n        if i % 3 == 0 and i % 5 == 0:\n            print(f\"{value1} : {value2}\")\n        elif i % 5 == 0:\n            print(f\"{value2}\")\n        elif i % 3 == 0:\n            print(f\"{value1}\")\n        else:\n            print(i)\n            numeros_no_cumplidos += 1\n    return (f\"Estos son el total de los numeros que no cumplieron ninguna de las condicionales: {numeros_no_cumplidos}\")\n\nprint(function(\"fizz\",\"buzz\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/python/zetared92.py",
    "content": "# FUNCIONES Y ALCANCE\n\n# Función simple sin retorno\ndef simpleFunc():\n    print(\"Esto es una función simple\")\n\nsimpleFunc()\n\n# Función simple con retorno\ndef simpleReturn():\n    return \"Esto es una función simple con retorno\"\nprint(simpleReturn())\n\n# Función con un argumento\ndef funcArg(name):\n    print(f\"I'm {name}...!\")\n\nfuncArg(\"Batman\")\n\n# Función con varios argumentos\ndef funcArguments(name, surname):\n    print(f\"{name}, {surname}\")\n\nfuncArguments(\"Bruce\", \"Wayne\")\nfuncArguments(name=\"Bruce\", surname=\"Wayne\")\n\n# Función con argumento predeterminado\ndef defaultArgs(name=\"Bruce\"):\n    print(f\"Hi, {name}!\")\n\ndefaultArgs(\"Batman\")\ndefaultArgs()\n\n# Función con argumentos y return\ndef returnArgs(greet, name):\n    return f\"{greet}, {name}!\"\nprint(returnArgs(\"Hi\", \"Bruce\"))\n\n# Función con retorno de varios valores\ndef multipleReturn():\n    return \"Hi\", \"Batman\"\ngreet, name = multipleReturn()\nprint(greet)\nprint(name)\n\n# Función con un número variable de argumentos\ndef varArgs(*names):\n    for name in names:\n        print(f\"Hi, {name}!\")\nvarArgs(\"Diana\", \"Barry\", \"Clark\", \"Arthur\", \"Victor\")\n\n# Función con un número de variable de argumentos con keyword\ndef varKeyArg(**names):\n    for key, value in names.items():\n        print(f\"{value}({key})!\")\n\nvarKeyArg(\n    group=\"Justice League\",\n    name = \"Barry\",\n    aka = \"Flash\",\n    status = \"Active\"\n)\n\n# Funciones dentro de funciones\ndef firstFunc():\n    def innerFunc():\n        print(\"Inner function: I'm Batman!\")\n    innerFunc()\nfirstFunc()\n\n# Funciones Built-in\nprint(len(\"Bruce Wayne\"))\nprint(type(1972))\nprint(\"Bruce Wayne\".upper())\n\n# Variables locales y globales\nglobalVar = \"Batman\"\n\ndef im_Batman():\n    localVar = \"I'm\"\n    print(f\"{localVar}, {globalVar}!\")\n\nprint(globalVar)\n\nim_Batman()\n\n# EXTRA\ndef printNumbers(text1, text2) -> int:\n    counter = 0\n    for num in range(1, 101):\n        if num % 3 == 0 and num % 5 == 0:\n            print(text1 + text2)\n        elif num % 3 == 0:\n            print(text1)\n        elif num % 5 == 0:\n            print(text2)\n        else:\n            print(num)\n            counter += 1\n    return counter\n\nprint(printNumbers(\"Fizz\", \"Buzz\"))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/r/Micromantic.R",
    "content": "#\n  # EJERCICIO:\n# - Crea ejemplos de funciones básicas que representen las diferentes\n#   posibilidades del lenguaje:\n#   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n# - Comprueba si puedes crear funciones dentro de funciones.\n# - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n# - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n# - Debes hacer print por consola del resultado de todos los ejemplos.\n#   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n\n\n#### Funciones definidas por el usuario\n\n# Simple\n\nsaludar <- function() {\n  print(\"¡Hola, R!\")\n}\n\nsaludar()\n\n# Con retorno\n\nsaludar_con_retorno <- function() {\n  return(\"¡Hola, R!\")\n}\n\nprint(saludar_con_retorno())\n\nsaludo <- saludar_con_retorno()\n\nsaludo\n\n# Con un argumento\n\nsaludar_con_argumento <- function(x) {\n  cat(\"¡Hola, \", x,\"!\", sep = \"\")\n}\n\nsaludar_con_argumento(\"Micromantic\")\n\n# Con dos argumentos\n\nsaludar_con_argumentos <- function(x, y) {\n  cat(\"¡\", x, \", \", y, \"!\", sep = \"\")\n}\n\nsaludar_con_argumentos(\"Buenas\", \"Micromantic\")\n\n# Con un argumento por defecto\n\nsaludar_con_argumento_por_defecto <- function(x = \"R\") {\n  cat(\"¡Hola, \", x,\"!\", sep = \"\")\n}\n\nsaludar_con_argumento(\"Micromantic\")\n\n# Con dos argumentos por defecto\n\nsaludar_con_argumentos_por_defecto <- function(x = \"Hola\" , y = \"R\") {\n  cat(\"¡\", x, \", \", y, \"!\", sep = \"\")\n}\n\nsaludar_con_argumentos(\"Buenas\", \"Micromantic\")\n\n# Con retorno de varios valores\n\nsaludar_con_multiple_retorno <- function() {\n  \n  return(c(\"Hola\", \"R\"))\n}\n\nsaludar_con_multiple_retorno()\n\nsaludo <- saludar_con_multiple_retorno()[1]\nlenguaje <- saludar_con_multiple_retorno()[2]\n\nsaludo\nlenguaje\n\n# Con un número variable de argumentos\n\nsaludo_con_argumentos_variables <- function(...) {\n  for (i in list(...)) {\n    print(paste0(\"Hola, \", i))\n    \n  }\n}\n\nsaludo_con_argumentos_variables(\"Carlos\", \"Daniel\")\n\n# Con un número variable de argumentos con palabras clave\n\nsaludo_con_argumentos_variables_clave <- function(...) {\n  \n  claves <- list(...)\n  for (clave in names(claves)) {\n    cat(\"Hola,\", \"mi\", clave, \"es\", claves[[clave]], \"\\n\")\n  }\n}\n\nsaludo_con_argumentos_variables_clave(\n  nombre = \"Daniel\",\n  lenguaje = \"R\",\n  apodo = \"Micromantic\",\n  edad = \"30\"\n  )\n\n# Función dentro de otra función\n\npor_100 <- function(x) {\n  \n  y <- x * 100\n  \n  por_5 <- function(y) {\n  resultado <- (y * 5)\n  return(resultado)\n  }\n  print(por_5(y))\n}\n\npor_100(x = 1)\n\n# esta funcion recibe un argumento, lo multiplica por 100 y luego usa una\n# función interna para multiplicar el resultado por 5\n\n#### Funciones del lenguaje R\n\n### Funciones sin retorno\n\n## Con parametros\n\nrm(list = ls())\n\n# Al ser aplicada de esta manera, la función rm borra todos los objetos del environment\n\n## Sin parametros\n\ngraphics.off()\n\n# graphics.off cierra todos los dispositivos gráficos abiertos (por ejemplo, las visualizaciones en el panel Plots)\n\n### Funciones con retorno\n\n## Con parametros\n\nsum(2, 2)\n\n## Sin parametros\n\nSys.Date()\n\n# la función Sys.Date arroja la fecha actual en el formato \"YYYY-MM-DD\"\n\n\n### Concepto de alcance LOCAL y GLOBAL\n\n# Al definir la función por_5 dentro de la función por_100, ya estamos explorando el concepto de alcance LOCAL y GLOBAL.\n# La función por_5 está definida dentro del alcance local de la función por_100.\n# Eso quiere decir que no se puede llamar la función por_5() en ninguna otra parte del script\n# En cambio, cuando se definen objetos fuera de funciones, estos se guardan en el ambiente global,\n# esos objetos sí pueden llamarse en cualquier parte del script.\n\npor_100 <- function(x) {\n  \n  y <- x * 100\n  \n  por_5 <- function(y) {\n    resultado <- (y * 5)\n    return(resultado)\n  }\n  print(resultado)\n  print(por_5(y))\n}\n\n# por_100 está en el ambiente global\n# las variables \"y\", y la función \"por_5\" están en el ambiente local de la función \"por_100\"\n# la variable \"resultado\" está en el ambiente local de la función \"por_5\"\n\n\n\n\n# DIFICULTAD EXTRA (opcional):\n# Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n# - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n#   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n#   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n#   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n#   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n#\n# Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n# Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n\n\nimprimir_numeros <- function(x, y) {\n  vector <- 1:100\n  multiplos_3_5 <- c()\n  \n  for (i in vector) {\n    if(i %% 3 == 0 & i %% 5 == 0) {\n      print(paste0(x, y, sep = \" \"))\n      } else if(i %% 3 == 0) {\n        print(x)\n        } else if(i %% 5 == 0) {\n          print(y)\n          } else { \n            print(i)\n            multiplos_3_5 <- c(multiplos_3_5, i)\n            }\n  }\n  multiplos_3_5\n  paste0(\"Hubo un total de \", length(multiplos_3_5), \" números impresos en vez de textos.\")\n}\n\nimprimir_numeros(\"Fizz\", \"Buzz\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/ruby/domo2pdev.rb",
    "content": "# frozen_string_literal: true\n\n# EJERCICIO:\n# - Crea ejemplos de funciones básicas que representen las diferentes\n#   posibilidades del lenguaje:\n#   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n# - Comprueba si puedes crear funciones dentro de funciones.\n# - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n# - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n# - Debes hacer print por consola del resultado de todos los ejemplos.\n#   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n\n# DIFICULTAD EXTRA (opcional):\n# Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n\n# - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n#   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n#   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n#   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n#   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\n# Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n# Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n\n# Funciones Definidas por el usuario\n\n# Simple funcions:\ndef greet\n  puts 'Hello, Ruby'\nend\n\ngreet\n\n# Return functions: Ruby methods return the value of the last evaluated expression by default,\n#  so explicitly using return at the end of a method is not recomended for convention.\n\ndef return_greet\n  puts 'Hello, ReturnedRuby'\nend\n\ngreet = return_greet\nputs greet\nputs return_greet\n\n# Functions with parameters or aguments:\ndef square(number)\n  number**2\nend\n\nmy_square = square(2)\nputs my_square\nputs square(3)\n\ndef add(number_a, number_b)\n  number_a + number_b\nend\n\nputs add(1, 2)\n\n# Functions with default parameters:\ndef circle_area(radius, my_pi = 3.1416)\n  return 'Radius shuld be a positive number' if radius.negative? # Here you can use a return expression\n\n  my_pi * (radius**2)\nend\n\nresult_circle_area = circle_area(-5)\nputs result_circle_area\nputs circle_area(5)\n\n# keyword arguments:\ndef division(dividend:, divisor:)\n  dividend / divisor\nend\n\nresul_division = division(divisor: 5, dividend: 10)\nputs resul_division\nputs division(dividend: 24, divisor: 4)\n\n# multiple return functions:\ndef return_functions(place_a, place_b)\n  puts place_a, place_b\nend\n\nputs return_functions(1, 2)\n\n# Variable number of arguments:\n\ndef variable_arg_greet(*names)\n  names.each { |name| puts \"Hola, #{name}\" }\nend\n\nvariable_arg_greet('Juan', 'Pablo', 'Jorge', 'Ringo')\n\ndef variable_arg_greet2(*names)\n  names.each do |name|\n    puts \"Hi, #{name}\"\n  end\nend\n\nvariable_arg_greet2('John', 'Paul', 'George', 'Ringo')\n\ndef sum(*args)\n  args.sum\nend\n\nputs sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)\n\ndef variable_keyword_arg_greet(**names)\n  names.each { |name| puts \"Mission, #{name}\" }\nend\n\nvariable_keyword_arg_greet(Name: 'John', Last_name: 'Connor', Target: 'Yes', Location: 'Unknown')\n\n# Nested functions:\n# It is a function that is defined inside another function.\n\n# This is a nested function to see an example but not recommended practice\ndef outer_function\n  puts 'Outer function'\n\n  def inner_function\n    puts 'Inner function'\n  end\nend\n\nouter_function\ninner_function\n\n# In Ruby Method definitions must not be nested. Use lambda instead.\n\n# Bilt-in functions:\n# See https://ruby-doc.org/core-2.7.0/ for more information\n\ndef square_root(number)\n  Math.sqrt(number)\nend\n\nputs square_root(16)\n\ndef who_am_i\n  puts 'Enter your name'\n  firts_name = gets.chomp\n\n  puts 'Enter your last name'\n  last_name = gets.chomp\n\n  puts \"Your name is #{firts_name} #{last_name}\"\nend\n\nwho_am_i\n\n# Variable scoop in ruby:\n\n# Global variables are accessible from anywhere in the program.\n# their use is generally discouraged due to potential side effects\n# and reduced code maintainability.\n\n$global_var = 'I am accessible everywhere!'\n\ndef some_method\n  puts $global_var # Accessible here\nend\n\nsome_method # Outputs: I am accessible everywhere!\nputs $global_var\n\n# Local variables are accessible only within the scope of the method\n# where they are declared.\n\ndef my_method\n  local_variable = 'I am only accessible inside this method'\n  puts local_variable\nend\n\nmy_method\n\n# puts local_variable # This would raise an error as local_variable is not accessible here.\n\n# Instance variables:\n# Instance variables are specific to each instance of a class.\n\nclass MyClass\n  def setting_value(value)\n    @instance_var = value\n  end\n\n  def getting_value\n    @instance_var\n  end\nend\n\nobj = MyClass.new\nobj.setting_value(10)\nputs obj.getting_value # Outputs: 10\n\n# Class variables:\n# Class variables are shared among all instances of a class.\n# They are defined using the @@ prefix.\n\nclass MyClass\n  @@class_var = 'I am a class variable'\n\n  def self.show_class_var\n    puts @@class_var\n  end\nend\n\nMyClass.show_class_var # Outputs: I am a class variable\n\n# Constants:\n# Constants are variables that should not change once assigned.\n# They start with an uppercase letter.\n\nPI = 3.1416\n\nputs PI # Outputs: 3.1416\n\n# DIFICULTAD EXTRA (opcional):\n# Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n\n# - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n#   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n#   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n#   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n#   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\n# Prints numbers from 1 to 100 with specific substitutions:\n# - If the number is a multiple of 3, prints the first text parameter.\n# - If the number is a multiple of 5, prints the second text parameter.\n# - If the number is a multiple of both 3 and 5, prints the concatenation of both text parameters.\n# - Otherwise, prints the number itself and increments the count of such numbers.\n# Parameters:\n# - text1: String to print for multiples of 3.\n# - text2: String to print for multiples of 5.\ndef print_numbers(text1, text2)\n  count = 0\n  101.times do |number|\n    if (number % 3).zero? && (number % 5).zero?\n      puts text1 + text2\n    elsif (number % 3).zero?\n      puts text1\n    elsif (number % 5).zero?\n      puts text2\n    else\n      puts number\n      count += 1\n    end\n  end\n  count\nend\n\nprint(print_numbers('Es multiplo de 3', 'Es multiplo de 5'))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/ruby/kodenook.rb",
    "content": "\ndef name() :nil\n    puts 'kodenook'\nend\n\nname()\n\ndef full_name(fname: string = 'my', lname: string = 'name') :nil\n    puts \"#{fname} #{lname}\"\nend\n\nfull_name(lname: 'lname')\n\ndef addition(*nums) :int\n    result = 0\n\n    nums.each do |num|\n        result += num\n    end\n\n    return result\nend\n\nputs addition(1, 1.2, 5.5, -4)\n\ndef first() :nil\n    puts 'first'\n\n    def second() :nill\n        puts 'second'\n    end\n\n    second()\nend\n\nfirst()\n\n$global = 'global'\n\ndef scope(local: string = 'local', local2: string = 'local2') :nil\n    puts $global\n    puts local\nend\n\nscope()\n\n=begin\n    Exercise\n=end\n\ndef exercise(word1, word2) :int\n    number_count = 0\n\n    (0..100).each do |number|\n        if number % 3 == 0 && number % 5 == 0\n            puts \"#{word1} #{word2}\"\n        elsif number % 3 == 0\n            puts word1\n        elsif number % 5 == 0\n            puts word2\n        else\n            number_count += 1\n        end\n    end\n\n    return number_count\nend\n\nputs \"number of times it was a number and not words: #{exercise('hello', 'ruby')}\""
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/rust/Coshiloco.rs",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\nuse std::cmp;\n\n\nfn saludar() {\n    println!(\"Hola, Rust!\");\n}\n\n\nfn sumar(a: i32, b: i32) {\n    let suma = a + b;\n    println!(\"Suma: {}\", suma);\n}\n\n\nfn multiplicar(a: i32, b: i32) -> i32 {\n    a * b\n}\n\n\nfn externa() {\n    fn interna() {\n        println!(\"Estoy dentro de una función externa\");\n    }\n    interna();\n}\n\n\nfn demo_max() {\n    let maximo = cmp::max(3, 5);\n    println!(\"El máximo entre 3 y 5 es: {}\", maximo);\n}\n\n\nstatic GLOBAL: i32 = 10;\n\nfn usar_variable_global() {\n    println!(\"Variable global: {}\", GLOBAL);\n}\n\nfn usar_variable_local() {\n    let local = 5;\n    println!(\"Variable local: {}\", local);\n}\n\n//EJERCICIO EXTRA\n/* \n* DIFICULTAD EXTRA (opcional):\n* Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n* - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n*   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n*   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n*   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n*   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n*\n* Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n* Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n*/\n\nfn ejercicio_extra(cadena_uno: String, cadena_dos: String) -> i32 {\n    let mut contador = 0;\n    for i in 1..100 {\n        if i % 3 == 0 {\n            println!(\"{}\", cadena_uno);\n        } else if i % 5 == 0 {\n            println!(\"{}\", cadena_dos);\n        } else if i % 3 == 0 && i % 5 == 0 {\n            println!(\"{}{}\", cadena_uno, cadena_dos);\n        } else if i % 3 != 0 && i % 5 != 0 {\n            contador += 1;\n            println!(\"{}\", i);\n        }\n    }\n    println!(\"El contador vale: {}\", contador);\n    return contador;\n}\n\n\n\n\nfn main() {\n    saludar();\n    sumar(3, 7);\n    println!(\"Multiplicación: {}\", multiplicar(4, 5));\n    externa();\n    demo_max();\n    usar_variable_global();\n    usar_variable_local();\n    ejercicio_extra(\"Hola\".to_string(), \"Mundo\".to_string());\n}\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/rust/angelsanchezt.rs",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n // Función sin parámetros ni retorno\nfn funcion_simple() {\n    println!(\"¡Hola desde la función simple!\");\n}\n\n// Con retorno y sin parametros\nfn funcion_con_retorno_y_sin_parametros() -> i32 {\n    // Realiza alguna operación\n    let resultado = 42;\n\n    // Retorna un valor\n    resultado\n}\n\n// Función con un parámetro y retorno\nfn cuadrado(numero: i32) -> i32 {\n    numero * numero\n}\n\n// Función con varios parámetros y retorno\nfn suma_y_producto(a: i32, b: i32) -> (i32, i32) {\n    (a + b, a * b)\n}\n\n\n// Función que retorna múltiples valores usando una tupla\nfn funcion_con_retorno_multiple(input: i32) -> (i32, i32, i32) {\n    let cuadrado = input * input;\n    let cubo = input * input * input;\n    let cuadruple = input * 4;\n\n    // Retorna una tupla con los valores calculados\n    (cuadrado, cubo, cuadruple)\n}\n\n// Función con un número variable de argumentos usando slices\nfn funcion_con_varios_argumentos(args: &[i32]) -> i32 {\n    let mut suma = 0;\n\n    for &numero in args {\n        suma += numero;\n    }\n\n    suma\n}\n\nfn funcion_exterior() {\n    println!(\"Comienzo de la función exterior.\");\n\n    // Definición de una función interna\n    fn funcion_interior() {\n        println!(\"¡Hola desde la función interior!\");\n    }\n\n    // Llamada a la función interna\n    funcion_interior();\n\n    println!(\"Fin de la función exterior.\");\n}\n\n\n// Función que imprime todos los números del 1 al 100 con condiciones especiales\nfn procesar_numeros(texto1: &str, texto2: &str) -> u32 {\n    let mut contador = 0;\n\n    for num in 1..=100 {\n        if num % 3 == 0 && num % 5 == 0 {\n            println!(\"{}{}\", texto1, texto2);\n        } else if num % 3 == 0 {\n            println!(\"{}\", texto1);\n        } else if num % 5 == 0 {\n            println!(\"{}\", texto2);\n        } else {\n            println!(\"{}\", num);\n            contador += 1;\n        }\n\n        \n    }\n\n    contador\n}\n\nconst CONSTANTE_GLOBAL: i32 = 100;\n\n// Función principal\nfn main() {\n    // Uso de funciones simples\n    funcion_simple();\n\n    // Uso de función con un parámetro y retorno\n    let resultado_cuadrado = cuadrado(5);\n    println!(\"Cuadrado: {}\", resultado_cuadrado);\n\n     // Llama a la función y almacena el resultado\n     let resultado_funcion = funcion_con_retorno_y_sin_parametros();\n     println!(\"Resultado de la función: {}\", resultado_funcion);\n\n    // Uso de función con varios parámetros y retorno\n    let (suma, producto) = suma_y_producto(3, 4);\n    println!(\"Suma: {}, Producto: {}\", suma, producto);\n\n    // Llama a la función y almacena los resultados en una tupla\n    let (resultado_cuadrado, resultado_cubo, resultado_cuadruple) = funcion_con_retorno_multiple(3);\n\n    // Imprime los resultados\n    println!(\"Cuadrado: {}\", resultado_cuadrado);\n    println!(\"Cubo: {}\", resultado_cubo);\n    println!(\"Cuádruple: {}\", resultado_cuadruple);\n\n    // Llama a la función con diferentes números de argumentos\n    let resultado1 = funcion_con_varios_argumentos(&[1, 2, 3]);\n    let resultado2 = funcion_con_varios_argumentos(&[10, 20, 30, 40]);\n\n    // Imprime los resultados\n    println!(\"Resultado 1: {}\", resultado1);\n    println!(\"Resultado 2: {}\", resultado2);\n\n    // Llamada a la función exterior\n    funcion_exterior();\n\n    // Funciones estándar\n    // print! y println!\n    print!(\"Hola, \");\n    println!(\"Mundo!\");\n    // format!:\n    let mensaje = format!(\"{} {}\", \"Hola\", \"Mundo\");\n    println!(\"{}\", mensaje);\n\n    // Variable local en la función main\n    let variable_local = 42;\n    println!(\"Variable local en main: {}\", variable_local);\n\n    // Constante global\n    println!(\"Constante global: {}\", CONSTANTE_GLOBAL);\n\n    // Uso de función que imprime números con condiciones especiales\n    let veces_impreso = procesar_numeros(\"Fizz\", \"Buzz\");\n    println!(\"Número de veces impreso: {}\", veces_impreso);\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/rust/atienzar.rs",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n\n\n fn funcion_sin_params(){\n    let x:i32 = 5;\n    println!(\"aqui x es una variable local de la funcion y vale {x}\" );\n }\n\n fn funcion_con_parametros(x:i32, y:i32){\n    println!(\"La suma de {x} + {y} es {}\", x+y);\n }\n\n // ojo! no termina con ;  => esto lo cambia de una expresion a una declaracion \n // hace que devuelva ese valor.\n fn mas_uno(x:i32)->i32{\n    x + 1\n }\n\n fn cedemos_cadena(cad:String){\n    println!(\"Cadena vale: {}\", cad);\n }\n\n fn imprimir_cad(cad:String)->String{\n    println!(\"Cadena vale: {}\", cad);\n    cad\n }\n\n fn modificar_cadena(cad: &mut String) {\n    cad.push_str(\" mundo!\");\n}\n\n// Funcion extra.\nfn extra(cad1: String, cad2:String) -> i32{\n\n     let mut cont = 0;\n\n      for i in 1..100{\n\n         if i % 3 == 0 && i % 5 == 0 {\n            println!(\"{}{}\",cad1,cad2);\n         }else if i % 3 == 0{\n            println!(\"{}\",cad1);\n         }else if  i % 5 == 0 {\n            println!(\"{}\",cad2);\n         }else{\n               println!(\"{}\",i);\n               cont = cont + 1;\n         }\n      }\n      \n   return cont\n\n}\n\n\nconst HORAS: u32 = 24;\n\n\n fn main(){\n    println!(\"Esta es la funcion ppal por defecto\");\n\n    //uso constante\n    println!(\"constante {HORAS}\");\n\n    //definimos variables\n    let x:i32 = 5;\n    let y:i32 = 7;\n    println!(\"x es {x}, y es {y}\");\n\n    // x = 8;\n    println!(\"Sopresa! x es {x}\");\n\n    // para que las vbles varén tienen que ser mut\n    let mut x:i32 = 5;\n    x = 8;\n    println!(\"Ahora! x es {x}\");\n\n\n    funcion_sin_params();\n    funcion_con_parametros(x,y);\n    \n    {\n        // esto es un nuevo ambito, como una funcion dentro de la funcion\n        let x = x +2;\n        println!(\"x es {x}\");\n    }\n    // aqui fuera sigue valiendo 8 el ultimo valor asignado\n    println!(\"x es {x}\");\n\n    //Puedes asignar funciones a vbles \n    let incrementar = mas_uno;\n    println!(\"{x} + 1 es: {}\", incrementar(x));\n\n\n\n    let z:i32 = 7;\n    x = mas_uno(z);\n    println!(\"sumamos 1 a z: {z} y el valor es: {x} \");\n\n    x = { \n        z + 1\n    };\n    println!(\"Imprimismos x:  {x} y z: {z}\");\n\n    // Rust tiene como objetivo ser eficiente en memoria, para ello no te deja\n    // tener variables que apunten a la misma referencia, automaticamente se carga la primera.\n\n    \n\n    let cad1 = String::from(\"Hello World!\");\n    let cad2 = cad1;\n    \n    // cad1 ya no existe por lo que no podemos imprimirla.\n    //println!(\"Rust {}\", cad1);\n    println!(\"Rust {}\", cad2);\n\n    // mas magia => si pasamos la cadena a una funcion, entonces la estmaos prestando y ya no\n    // está diponible en el resto del scope\n\n    cedemos_cadena(cad2);\n    // Aqui ya no podemos imprimir cad2 pq la hemos perdido\n    //println!(\" {}\", cad2);\n\n    // para que no la perdamos la funcion nos la tiene que devolver de nuevo:\n    let mut cad3 = String::from(\"Hola!\");\n    cad3 = imprimir_cad(cad3);\n    println!(\"Seguimos teniendo cad1 {}\", cad3);\n\n    // Operador &mut para cuando queremos cambiar el contenido del puntero\n\n    let mut cad4 = String::from(\"Hola\");\n    modificar_cadena(&mut cad4);\n    println!(\"Modificando cadenas : {}\", cad4);\n\n\n    //LLamamos a la funcion extra\n    let cad1 = String::from(\"Cadena1\");\n    let cad2 = String::from(\"Cadena2\");\n\n   // Punto extra\n    let total:i32 = extra(cad1,cad2);\n    println!(\"Numero de numeros impresos en total: {total}\");\n\n }"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/rust/brockar.rs",
    "content": "const HORA_DE_LOS_DIRECTOS: u8 = 16;\nfn main() {\n    funcion_basica();\n\n    funcion_con_parametros(1, 2);\n\n    println!(\"Retorno: {}\", funcion_con_retorno());\n\n    println!(\"Retorno: {}\", funcion_con_parametros_y_retorno(1, 2));\n\n    funcion_con_parametros_y_varios_retornos(2, 4);\n\n    let (suma, resta) = funcion_con_parametros_y_varios_retornos_con_nombres(2, 4);\n    println!(\"Esta es la suma retornada: {}\", suma);\n    println!(\"Esta es la resta retornada: {}\", resta);\n\n    // Funcion dentro de otra\n    let x: u8 = 5;\n    let lamda_incrementar = |y: u8| y + 1;\n    println!(\n        \"\\nRetorno de funcion lamda(dentro de otra): {}\",\n        lamda_incrementar(x)\n    );\n\n    // Uso de constantes\n    println!(\"\\nEsta es una constante: {}\", HORA_DE_LOS_DIRECTOS);\n\n    // Scope de las variables definidas en una función solo podrán ser utilizadas dentro de esta,\n    // excepto que se pase por parámetro a otra función.\n\n    // función ya creada por el lenguaje\n    let mut s = String::from(\"Hola\");\n    s.push_str(\", moure!\");\n\n    println!(\"\\nResultado de la función creada por el lenguaje: \\n{}\", s);\n\n    // EXTRA EXTRA\n    println!(\"\\n\\n EXTRA EXTRA\\n\\n\");\n    let result = extra(\"Hola\", \" Mundo!\");\n    println!(\n        \"\\nLa cantidad de veces que se ha impreso el numero es: {}\",\n        result\n    );\n}\n\nfn funcion_basica() {\n    let x: u8 = 5;\n    println!(\"Esto es una función básica: {}\", x);\n}\n\nfn funcion_con_parametros(x: u8, y: u8) {\n    println!(\"Esto es una función con parámetros: {} y {}\", x, y);\n}\n\nfn funcion_con_retorno() -> u8 {\n    let x: u8 = 5;\n    println!(\"Esto es una función con retorno: {}\", x);\n    x\n}\n\nfn funcion_con_parametros_y_retorno(x: u8, y: u8) -> u8 {\n    let z = x + y;\n    println!(\n        \"Esto es una función con parámetros y retorno: {} + {} = {}\",\n        x, y, z\n    );\n    z\n}\n\nfn funcion_con_parametros_y_varios_retornos(x: i8, y: i8) -> (i8, i8) {\n    let z = x + y;\n    let w = x - y;\n    println!(\n        \"Esto es una función con parámetros y varios retornos: {} + {} = {} y {} - {} = {}\",\n        x, y, z, x, y, w\n    );\n    (z, w)\n}\n\nfn funcion_con_parametros_y_varios_retornos_con_nombres(x: i8, y: i8) -> (i8, i8) {\n    let suma = x + y;\n    let resta = x - y;\n    println!(\"Esto es una función con parámetros y varios retornos con nombres: {} + {} = {} y {} - {} = {}\", x, y, suma, x, y, resta);\n    (suma, resta)\n}\n\nfn extra(a: &str, b: &str) -> i32 {\n    let mut r = 0;\n    for num in 1..=100 {\n        if (num % 3) == 0 && (num % 5) == 0 {\n            println!(\"{} {}\", a, b);\n        } else if (num % 3) == 0 {\n            println!(\"{}\", a);\n        } else if (num % 5) == 0 {\n            println!(\"{}\", b);\n        } else {\n            println!(\"{}\", num);\n            r += 1;\n        }\n    }\n\n    r\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/rust/didacdev.rs",
    "content": "// https://doc.rust-lang.org/book/ch03-03-how-functions-work.html\n\n// Funciones con parámetro\nfn print_hello(name: &str) {\n    println!(\"Hello {name}\")\n}\n\nfn suma_dos(number1:i32, number2:i32) {\n    let result = number1 + number2;\n    println!(\"{result}\")\n}\n\n// Funciones con return\nfn five() -> i32 {\n    return 5\n}\n\nfn print_numbers(word1: &str, word2: &str) -> i32 {\n    let mut n = 0;\n\n    for number in 1..=100 {\n        if number % 3 == 0 && number % 5 == 0 {\n            println!(\"{}\", word1.to_owned() + word2)\n        } else if number % 5 == 0 {\n            println!(\"{word2}\")\n        } else if number % 3 == 0 {\n            println!(\"{word1}\")\n        } else {\n            n += 1;\n            println!(\"{number}\")\n        }\n    }\n\n    return n;\n}\n\nfn main() {\n    // print_hello(\"Diego\");\n    // suma_dos(1, 2);\n    // println!(\"{}\", five())\n    println!(\"Se ha impreso un número {} veces\", print_numbers(\"Hola\", \"Mundo\"));\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/rust/gabrielmoris.rs",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\nstatic _GLOBAL: i32 = 1;\nfn main() {\n    print!(\"\\n No parameters no return \\n\");\n    do_it_simple();\n\n    print!(\"\\n Recursive and not value \\n\");\n    let mut i = 1;\n\n    recursive(&mut i);\n\n    print!(\"\\n Return and method \\n\");\n    let value = dramatize(\"Hello, String\");\n    print!(\"{}\\n\", value);\n\n    print!(\"\\n 2 Params + return \\n\");\n\n    let result = sum(3, 5);\n    print!(\"{}\\n\", result);\n\n    print!(\"\\n Create function here \\n\");\n\n    fn call_me_here() -> String {\n        return \"I'm here, yes\".to_owned();\n    }\n    print!(\"{}\", call_me_here());\n\n    print!(\"\\n Local, Global variable \\n\");\n\n    fn _local_fn() {\n        let _local = 1;\n    }\n    // print!(\"{}\", _local) // Cannot find _local in this scope\n    print!(\"Can be logged: {} \", _GLOBAL);\n\n    print!(\"\\n Challenge \\n\");\n    let num = fizz_what(\"fizz\", \"buzz\");\n    print!(\"Solution: {}\\n\", num)\n}\n\nfn do_it_simple() {\n    return;\n}\n\nfn recursive(i: &mut i32) {\n    print!(\"{},\", i);\n    *i += 1;\n    if *i < 4 {\n        recursive(i)\n    }\n}\n\nfn dramatize(a: &str) -> String {\n    // I need to convert ir in a owned string\n    return a.to_uppercase() + \"!\";\n}\n\nfn sum(first: i32, second: i32) -> i32 {\n    // Instead of return I just can put the value here without semicolon.\n    first + second\n}\n\nfn fizz_what(str1: &str, str2: &str) -> i32 {\n    let mut number_of_numnbers_printed = 0;\n\n    for n in 0..=100 {\n        if n % 3 == 0 && n % 5 == 0 {\n            print!(\"{}{},\", str1, str2);\n        } else if n % 5 == 0 {\n            print!(\"{},\", str2);\n        } else if n % 3 == 0 {\n            print!(\"{},\", str1);\n        } else {\n            print!(\"{},\", n);\n            number_of_numnbers_printed += 1;\n        }\n    }\n    return number_of_numnbers_printed;\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/rust/javiearth.rs",
    "content": "//=========================\n// 02 - FUNCIONES Y ALCANCE\n//=========================\nuse rand::Rng; // A partir de ahora mejor usar el gestor de paquetes cargo ;)\n\n// Crea funciones basicas que que representen las diferentes posibilidades del lenguaje\n\nfn main(){\n\nsin_param();\n\nprintln!(\"La siguiente es una funcion a la que se le da un radio como paramentro:\");\n\ncon_param(5.0);\n\nprintln!(\"La siguiente expresion llama a una funcion que retorna un valor\");\n\nlet suma: u32 = con_return();\n\nprintln!(\"La suma de todos los pares en los primeros cien numeros naturales es {}\", suma);\n\n\n// Comprueba si puedes crear una funcion dentro de otra funcion:\n\nfunciones_anidadas();\n\n// Utiliza algunejemplo de funciones ya creadas en el lenguaje\n// Voy a utilizar una funcion para generar un numero aleatorio (para eso se importa la libreria rand al principio del archivo\n\nlet num = rand::thread_rng().gen_range(1..=100);\nprintln!(\"Numero aleatorio usando una funcion ya creada en Rust: {}\", num);\n\n// DIFICULTAD EXTRA\n\n// Funcion que recibe dos strings y devuelve un numero\n\nlet mi_num = cadena_numero (\"primero\", \"segundo\");\n\nprintln!(\"Dos strings a un numero: {}\", mi_num);\n\n\n}\n// FIN DE FUNCION MAIN\n\n// FUNCION SIN PARAMETROS\nfn sin_param(){\n    println!(\"Esta es una funcion sin parametros ni retorno\");\n}\n\n//FUNCION CON PARAMETROS\nfn con_param(radio: f32){\n    let area = 3.1415926 * radio * radio;\n    println!(\"El area del circulo es {}\", area);\n}\n\n//FUNCION CON RETURN\nfn con_return() -> u32 {\n    //let la_guia: u8 = 42; ESTO SERIA UNA VARIABLE LOCAL QUE NO PUEDO LLAMAR DESDE LA FUNCION MAIN\n    let mut suma: u32 = 0;\n    let mut counter: u32 = 1;\n    while counter <= 100 {\n        if counter % 2 == 0 {\n            suma = suma + counter;\n        }\n        counter += 1;\n    }\n    return suma;\n}\n\n//FUNCION DENTRO DE UNA FUNCION\nfn funciones_anidadas(){\n    println!(\"Esta es la funcion de primer nivel\");\n    funcion_interna();\n    fn funcion_interna(){\n         println!(\"Y esta es una funcion dentro de una funcion\");\n    }\n}\n\n//DIFICULTAD EXTRA\nfn cadena_numero(uno: &str, dos: &str) -> i32 {\n/*    let longitud: usize = uno.len() + dos.len();\n    longitud\n*/\n    let mut num_count: i32 = 0;\n    for mi_numero in 1..100 {\n        if mi_numero %3 == 0 && mi_numero %5 == 0 { println!(\"{}{}\", uno, dos);\n        } else if mi_numero %3 == 0 {println!(\"{}\", uno);\n        } else if mi_numero %5 == 0 {println!(\"{}\", dos);\n        } else {\n            println!(\"{}\", mi_numero);\n            num_count +=1;\n        }\n    }\n    num_count\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/rust/kenysdev.rs",
    "content": "/*\n╔═══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado                ║\n║ GitHub: https://github.com/Kenysdev   ║\n║ 2024 -  Rust                          ║\n╚═══════════════════════════════════════╝\n\n-----------------------------------------\n* FUNCIONES\n-----------------------------------------\n*/ \n// - Basica\nfn hello() {\n    println!(\"hello, world!\");\n}\n\n// _________________________\n// - Con Parámetro:\n//   \"&\" indica paso por referencia inmutable.\nfn print(msg: &str) {\n    println!(\"{}\", msg);\n}\n\n// _________________________\n// - Con retorno:\n//   Funciona mediante expresiones las cuales\n//   evalúan a un valor resultante.\nfn sum(a: i32, b: i32) -> i32 {\n    a + b\n    // Las expresiones no finalizan con \";\".\n    // usar \"return\" es opcional.\n}\n\n// _________________________\n// Función dentro de otra función\nfn external(a: i32) -> String {\n    fn internal(b: i32) -> i32 {\n        b * 2\n    }\n    format!(\"Externa: {}\", internal(a))\n}\n\n// _________________________\n// * Ejemplo de funciones y métodos incorporados.\nfn native_functions() {\n    println!(\"len: {}\", (\"123\").len());\n    println!(\"lower: {}\", (\"ABC\").to_lowercase());\n    println!(\"upper: {}\", (\"abc\").to_uppercase());\n    println!(\"convert: {}\", (12).to_string());\n}\n\n/* _________________________\n* Ejercicio:\n* Crea una función que reciba dos parámetros de tipo \n  cadena de texto y retorne un número.\n* La función imprime todos los números del 1 al 100,\n  teniendo en cuenta que:\n- Si el número es múltiplo de 3, muestra la cadena de\n  texto del primer parámetro.\n- Si el número es múltiplo de 5, muestra la cadena de \n  texto del segundo parámetro.\n- Si el número es múltiplo de 3 y de 5, muestra las  \n  dos cadenas de texto concatenadas.\n- La función retorna el número de veces que se ha \n  impreso el número en lugar de los textos.\"\"\")\n*/\n\nfn exs(str1: &str, str2: &str) -> i8 {\n    let mut total: i8 = 0;\n    for n in 1..=100 {\n        match (n % 3 == 0, n % 5 == 0) {\n            (true, false) => println!(\"- {str1}\"),\n            (false, true) => println!(\"- {str2}\"),\n            (true, true) => println!(\"- {str1} - {str2}\"),\n            _ => {println!(\"- {n}\"); total += 1;}\n        }\n    }\n    return total;\n}\n\n// _________________________\nfn main() {\n    hello();\n    print(\"hello, Rust!\");\n    println!(\"Suma: {}\", sum(2, 2));\n    println!(\"{}\", external(5));\n    native_functions();\n    println!(\"\\nnúmero de veces: {}\", exs(\"str1\", \"str2\"))\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/rust/kodenook.rs",
    "content": "\nstatic MYGLOBAL: &str = \"global\";\n\nfn main() {\n    name();\n    full_name(\"my\", \"lname\");\n    let mut age: u8 = 20;\n    age_addition(&mut age);\n    println!(\"{age}\");\n\n    first();\n    scope();\n\n    println!(\"number of times it was a number and not words: {}\", exercise(\"hello\", \"rust\"));\n}\n\n/// The function `name` in Rust prints \"kodenook\" when called.\nfn name() {\n    println!(\"kodenook\");\n}\n\nfn full_name(fname: &str, lname: &str) -> () {\n    println!(\"{fname} {lname}\");\n}\n\nfn age_addition(age: &mut u8) {\n    *age += 5;\n}\n\nfn first() -> () {\n    println!(\"First\");\n\n    fn second() -> () {\n        println!(\"Second\");\n    }\n\n    second();\n}\n\nfn scope() -> () {\n    let local: &str = \"local\";\n\n    println!(\"{}\", MYGLOBAL);\n    println!(\"{}\", local);\n}\n\n/*\n    Exercise\n*/\n\nfn exercise(word1: &str, word2: &str) -> u8 {\n    let mut count_numbers: u8 = 0;\n\n    for x in 1..=100 {\n        if x % 3 == 0 && x % 5 == 0 {\n            println!(\"{} {}\", word1, word2);\n        } else if x % 3 == 0 {\n            println!(\"{word1}\");\n        } else if x % 5 == 0 {\n            println!(\"{word2}\")\n        } else {\n            count_numbers += 1;\n        }\n    }\n\n    return count_numbers;\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/rust/owen-ian.rs",
    "content": "//==========================\n// 02 - FUNCIONES Y ALCANCE\n//==========================\n\nfn main() {\n    // Función sin parámetros y sin retorno\n    fn saludar() {\n        println!(\"¡Hola, mundo!\");\n    }\n    saludar();\n\n    // Función con un parámetro y sin retorno\n    fn saludar_persona(nombre: &str) {\n        println!(\"¡Hola, {}!\", nombre);\n    }\n    saludar_persona(\"Owen\");\n\n    // Función con múltiples parámetros y retorno\n    fn suma(a: i32, b: i32) -> i32 {\n        a + b\n    }\n    println!(\"Suma: {}\", suma(10, 3));\n\n    // Función con retorno implícito\n    fn resta(a: i32, b: i32) -> i32 {\n        a - b\n    }\n    println!(\"Resta: {}\", resta(10, 3));\n\n    // Función con retorno múltiple\n    fn division(a: i32, b: i32) -> (i32, i32) {\n        (a / b, a % b)\n    }\n    let (cociente, resto) = division(10, 3);\n    println!(\"División: {} (cociente) y {} (resto)\", cociente, resto);\n\n    // Función con argumentos variables\n    fn promedio(args: &[i32]) -> f64 {\n        let sum: i32 = args.iter().sum();\n        sum as f64 / args.len() as f64\n    }\n    let numeros = vec![1, 2, 3, 4, 5];\n    println!(\"Promedio: {}\", promedio(&numeros));\n\n    // Variables LOCAL y GLOBAL\n    let x: i32 = 5; // variable LOCAL\n    fn usa_variable() {\n        static Y: i32 = 10; // variable GLOBAL\n        println!(\"Y: {}\", Y);\n    }\n    usa_variable();\n    println!(\"X: {}\", x);\n\n    // Función anidada\n    fn funcion_externa() {\n        println!(\"Función externa\");\n\n        fn funcion_interna() {\n            println!(\"Función interna\");\n        }\n        funcion_interna();\n    }\n    funcion_externa();\n\n    // DIFICULTAD EXTRA\n    fn imprimir_multiplos(param1: &str, param2: &str) -> i32 {\n        let mut contador = 0;\n        for i in 1..=100 {\n            if i % 3 == 0 && i % 5 == 0 {\n                println!(\"{}{}\", param1, param2);\n            } else if i % 3 == 0 {\n                println!(\"{}\", param1);\n            } else if i % 5 == 0 {\n                println!(\"{}\", param2);\n            } else {\n                println!(\"{}\", i);\n                contador += 1;\n            }\n        }\n        contador\n    }\n    let veces_impreso = imprimir_multiplos(\"Fizz\", \"Buzz\");\n    println!(\"Veces que se ha impreso el número en lugar de los textos: {}\", veces_impreso);\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/rust/raulfauli.rs",
    "content": "/// #02 FUNCIONES Y ALCANCE\n///\n/// Para compilar y ejecutar este código, ejecute el siguiente comando desde el directorio principal:\n///\n/// ```bash\n///   rustc ./Roadmap/02\\ -\\ FUNCIONES\\ Y\\ ALCANCE/rust/raulfauli.rs && ./raulfauli\n/// ```\n///\nfn main() {\n    hello();\n    say_hello(\"Raúl\");\n\n    say_hello_engineer(\"Raül\", Some(10));\n    say_hello_engineer(\"Raül\", None);\n\n    let sum = sum(5, 5);\n    println!(\"Sum: {sum}\");\n\n    let (hello, world) = return_multiple_values();\n    println!(\"{hello} {world}\");\n\n    let tuple = return_multiple_values();\n    println!(\"{} {}\", tuple.0, tuple.1);\n\n    let media = average(&[1, 2, 3, 4, 5]);\n    println!(\"Media: {media}\");\n\n    exterior_function();\n    // interior_function(); // Error\n\n    builtin_functions();\n\n    local_global_variable();\n\n    let count = extra_difficulty(\"Fizz\", \"Buzz\");\n    println!(\"Count: {count}\");\n}\n\n// Función sin parámetro\nfn hello() {\n    println!(\"¡Hola mundo!\");\n}\n\n// Función con parámetro\nfn say_hello(name: &str) {\n    println!(\"Hola, {name}!\");\n}\n\n// Función con parámetro opcional Todo: revisar este punto\nfn say_hello_engineer(name: &str, years: Option<i32>) {\n    match years {\n        Some(years) => {\n            println!(\"Mi nombre es {name}, soy ingeniero de software hace más de {years} años\")\n        }\n        None => println!(\"Mi nombre es {name}\"),\n    }\n}\n\n// Función con 2 parámetros y retorno\nfn sum(a: i32, b: i32) -> i32 {\n    // return a + b;\n    a + b\n}\n\n// También podría haber devuelto -> (&'static str, &'static str)\nfn return_multiple_values() -> (String, String) {\n    (String::from(\"Hello\"), String::from(\"World\"))\n}\n\nfn average(numbers: &[i32]) -> f64 {\n    let sum: i32 = numbers.iter().sum();\n    sum as f64 / numbers.len() as f64\n}\n\nfn exterior_function() {\n    fn interior_function() {\n        println!(\"¡Hola desde la función interior!\");\n    }\n\n    interior_function();\n}\n\nfn local_global_variable() {\n    let global_variable = 10;\n    let v = {\n        // Este bloque de código nos permite obtener un resultado\n        // sin tener que definir una función\n        let a = 1;\n        let b = 2;\n        let global_variable = 20; // Shadowing\n        a + b + global_variable\n    };\n\n    // println!(\"Local: {a}\"); // Error\n\n    fn interior_function(local_variable: i32) {\n        // println!(\"Global: {global_variable}\"); // Error\n        println!(\"Local: {}\", local_variable);\n    }\n\n    interior_function(v);\n\n    println!(\"Global: {global_variable}\");\n}\n\nfn builtin_functions() {\n    let variable: &str = \"github\";\n    println!(\"Longitud de \\\"{variable}\\\" {}\", variable.len());\n\n    let variable: String = \"gitlab\".to_string();\n\n    println!(\"Longitud de \\\"{variable}\\\" {}\", variable.len());\n}\n\nfn extra_difficulty(first: &str, second: &str) -> u8 {\n    let mut count: u8 = 0;\n    for x in 1..100 {\n        if x % 3 == 0 && x % 5 == 0 {\n            println!(\"{first} {second}\");\n        } else if x % 3 == 0 {\n            println!(\"{first}\");\n        } else if x % 5 == 0 {\n            println!(\"{second}\");\n        } else {\n            println!(\"{x}\");\n            count += 1;\n        }\n    }\n\n    count\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/rust/troleomotor10.rs",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n// Main function\nfn main(){\n    hello_world();\n\n    let resultado: i32 = suma(10, 5);\n    println!(\"{resultado}\");\n\n    let (string1, string2) = multiple_return();\n    println!(\"{} {}\", string1, string2);\n\n    let names: [&str; 3] = [\"Juan\", \"Manolo\", \"Luis\"];\n    more_than_1_parameter(&names);\n\n    function_out();\n\n    builtin_functions();\n    \n    hello_rust1();\n\n    exercice_extra(\"Zipi\", \"Zape\");\n}\n\n/*\n    FUNCIONES BÁSICAS DEL LENGUAJE\n*/\n\n// Function without return and parameters\nfn hello_world() {\n    println!(\"Hello World!\")\n}\n\n//  Function with parameters and return\nfn suma(a: i32, b: i32) -> i32{\n    a + b\n}\n\n// Function with parameters and return of many values\nfn multiple_return() -> (&'static str, &'static str){\n    (\"Hola\", \"Troleomotor10\")\n}\n\n\n// Function with more than 1 parameter\nfn more_than_1_parameter(names: &[&str]) {\n    for name in names {\n        println!(\"{name}\");\n    }\n}\n\n/*\n    FUNCIONES DENTRO DE FUNCIONES\n*/\n\nfn function_out() {\n    fn function_in_function(){\n        println!(\"Hello, Rust 2!\")\n    }\n    function_in_function();\n}\n\n/*\n    FUNCIONES DEL LENGUAJE (built-in)\n*/\n\nfn builtin_functions(){\n    let variable: &str = \"github\";\n    println!(\"{}\", variable.len());\n    \n}\n\n/*\n    VARIABLES LOCALES Y GLOBALES\n*/\n\nfn hello_rust1() {\n    let global_var: i32 = 33;\n    fn hello_rust2(){\n        let local_var: i32 = 55;\n        //println!(\"{}\", global_var); -> No va a funcionar\n        println!(\"{}\", local_var);\n    }\n    hello_rust2();\n    println!(\"{}\",  global_var);\n    //println!(\"{}\", local_var); -> No va a funcionar\n}\n\n/*\n    EJERCICIO EXTRA\n*/\n\nfn exercice_extra(text1: &str, text2: &str) {\n    let mut contador: i32 = 0;\n    for x in 1..101 {\n        if x % 3 == 0 && x % 5 == 0{\n            println!(\"{} {}\", text1, text2);\n        } else if x % 3 == 0 {\n            println!(\"{text1}\");\n        } else if x % 5 == 0 {\n            println!(\"{text2}\");\n        } else {\n            println!(\"{x}\");\n            contador += 1;\n        }\n    }\n    println!(\"Los numeros en lugar de los textos han salido: {contador} veces\");\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/rust/zetared92.rs",
    "content": "// RETO 302 FUNCIONES Y ALCANCE\n\n\n// Función sin parámetros/retorno\nfn main() {\n    println!(\"Hello, World!\")\n}\n\n// Func con retorno y parámetros\nfn addition(x: i32, y: i32) -> i32{\n    x + y\n}\n\n// Func con varios parámetros y retorno\nfn multiple_value() -> (&'static str, &'static str){\n    (\"Hello\", \"Rust\")\n}\n\n// Func varios parámetros\nfn mult_values(games: &[&str]) {\n    for game in games {\n        println!(\"{game}\");\n    }\n}\n\n// FUNCIONES DENTRO DE FUNCIONES\nfn func_out() {\n    fn func_in_func(){\n        println!(\"Hello, Rust!\")\n    }\n    func_in_func();\n}\n\n// VARIABLES LOCALES Y GLOBALES\nfn hello_world() {\n    let global_var: i32 = 15;\n    fn hello_world() {\n        let local_var: i32 = 55;\n        println!(\"{}\", local_var);\n    }\n    hello_rust();\n    println!(\"{}\", global_var);\n}\n\n// EXTRA\nfn print_numbers(text_1: &str, text_2: &str) -> u8 {\n    let mut count: u8 = 0;\n    for x in 1..101 {\n        if x % 3 == 0 && x % 5 == 0 {\n            println!(\"{text_1}\", \"{text_2}\");\n        } else if x % 3 == 0 {\n            println!(\"{text_1}\");\n        } else if x % 5 == 0 {\n            println!(\"{text_2}\")\n        } else {\n            println!(\"{x}\");\n            count += 1;\n        }\n    }\n    count\n}\nprintln!(print_numbers(\"Fizz\", \"Buzz\"));\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/scala/angelsanchezt.scala",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n // Funciones definidas por el usuario\n object Main {\n  // Variable GLOBAL\n  val variableGlobal: String = \"Soy global\"\n\n  def main(args: Array[String]): Unit = {\n    // Llamada a una función ya creada en el lenguaje\n    println(s\"Longitud de 'Hola, Scala!': ${longitud(\"Hola, Scala!\")}\")\n\n    // Funciones básicas\n    funcionSinParametrosNiRetorno()\n    funcionConParametro(42)\n    val resultado = funcionConRetorno(5)\n    println(s\"Resultado de la función con retorno: $resultado\")\n\n    // Variable LOCAL\n    val variableLocal: Int = 100\n\n    // Función dentro de función\n    def funcionAnidada(): Unit = {\n      println(\"Función anidada\")\n    }\n\n    funcionAnidada()\n\n    // Dificultad EXTRA\n    val texto1 = \"Fizz\"\n    val texto2 = \"Buzz\"\n    val vecesImpreso = imprimirNumerosConTexto(texto1, texto2)\n    println(s\"La función se ejecutó $vecesImpreso veces\")\n  }\n\n  // Función sin parámetros ni retorno\n  def funcionSinParametrosNiRetorno(): Unit = {\n    println(\"Función sin parámetros ni retorno\")\n  }\n\n  // Función con parámetro\n  def funcionConParametro(numero: Int): Unit = {\n    println(s\"Función con parámetro: $numero\")\n  }\n\n  // Función con retorno\n  def funcionConRetorno(numero: Int): Int = {\n    println(s\"Función con retorno: $numero\")\n    numero * 2\n  }\n\n  // Función ya creada en el lenguaje\n  def longitud(texto: String): Int = {\n    texto.length\n  }\n\n  // Función con dificultad EXTRA\n  def imprimirNumerosConTexto(texto1: String, texto2: String): Int = {\n    var contador = 0\n    for (i <- 1 to 100) {\n      if (i % 3 == 0 && i % 5 == 0) {\n        println(texto1 + texto2)\n      } else if (i % 3 == 0) {\n        println(texto1)\n      } else if (i % 5 == 0) {\n        println(texto2)\n      } else {\n        println(i)\n        contador += 1\n      }\n      \n    }\n    contador\n  }\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/scala/rianojnicolas.scala",
    "content": "import scala.util.Random\n\nobject Main {\n    def main(args: Array[String]): Unit = {\n        // Variable Global\n        var varGlobal = \"Muchos Exitos, y que tenas un buen día\"\n\n        // Funciones:\n        // Funcion sin parametros ni retorno\n        def welcomePlayer(): Unit = {\n            println(\"\"\"\n        Hola People !!, este es un juego improvisado de\n        piedra, papel o tijera.\n        \n        las reglas son las siguientes:\n        \"\"\")\n        // Funcion dentro de otra funcion\n            def reglas(): Unit = {\n                print(\"\"\"\n            1. Debes ingresar el objeto con el que jugaras\n            2. El pc elegira aleatoriamente un objeto\n            3. Recuerda que: papel le gana a piedra,\n                            piedra le gana a tijera,\n                            tijera le gana a papel.\n            \n            Muchos Exitooooss !!!\n            \"\"\")\n            }\n            reglas()\n        }\n\n\n        // Funcion sin parametros con retorno   \n        // Funcion para pedir el objeto a jugar\n        def functionInput(): String = {\n            println(\"Ingresa tu objeto con el que vas a jugar: \")\n            var option = scala.io.StdIn.readLine()\n            while(option != \"piedra\" && option != \"tijera\" && option != \"papel\"){\n                println(\"Ingresa tu objeto con el que vas a jugar: \")\n                option = scala.io.StdIn.readLine()\n            }\n            return option\n        }\n\n\n        // (Funcion con un parametro y sin retorno)\n        // Funcion competencia\n        def playCompetition(optionPlayer:String): Unit = {\n            // Concepto de Variable Local\n            val optionList = List(\"piedra\", \"papel\", \"tijera\")\n            var optionPC = Random.shuffle(optionList).head\n            println(s\"la opcion del pc fue: $optionPC \\n\")\n            if (optionPC == optionPlayer) {\n                println(\"Emptados\")\n            }\n            else if (optionPC == \"papel\") {\n                if (optionPlayer == \"piedra\") {\n                    println(\"perdiste\")\n                }\n                else if(optionPlayer == \"tijera\") {\n                    println(\"ganaste\")\n                }\n            }\n            else if (optionPC == \"tijera\") {\n                if (optionPlayer == \"papel\") {\n                    println(\"perdiste\")\n                }\n                else if (optionPlayer == \"piedra\") {\n                    println(\"ganaste\")\n                }\n            }\n            else if (optionPC == \"piedra\") {\n                if (optionPlayer == \"papel\") {\n                    println(\"ganaste\")\n                }\n                else if (optionPlayer == \"tijera\") {\n                    println(\"perdiste\")\n                }\n            }\n        }\n\n        def run(): Unit = {\n            welcomePlayer()\n            println(varGlobal)\n            var option_player = functionInput()\n            playCompetition(option_player)\n        }\n        \n        run()\n\n        /*\n        DIFICULTAD EXTRA\n        */\n        println(\"*---------------------------------*\")\n        println(\"*       DIFICULTAD EXTRA          *\")\n        println(\"*---------------------------------*\")\n\n        def extraDifficult(param1: String, param2: String): Float = {\n            var contador = 0\n            for (i <- 0 to 101) {\n                if (i%3 == 0 && i%5 == 0) {\n                    println(s\"para el numero $i: $param1 $param2\")\n                }\n                else if(i%3 == 0) {\n                    println(s\"para el numero $i: $param1\")\n                }\n                else if(i%5 == 0) {\n                    println(s\"para el numero $i: $param2\")\n                }\n                else {\n                    contador += 1\n                    println(s\"para el numero $i no hay texto\")\n                }\n            }\n            return contador\n        }\n\n        println(\"\\nAhora vamos con el ejercicio extra\\n\")\n        println(extraDifficult(\"hola\", \"mundo\"))\n    }\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/sql/Nicojsuarez2.sql",
    "content": "# #02 FUNCIONES Y ALCANCE\n> #### Dificultad: Fácil | Publicación: 08/01/24 | Corrección: 15/01/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/sql/eulogioep.sql",
    "content": "-- Asumimos que estamos usando MySQL para este ejemplo\n\n-- Creamos una base de datos para nuestros ejemplos\nCREATE DATABASE IF NOT EXISTS ejemplos_funciones;\nUSE ejemplos_funciones;\n\n-- Creamos una tabla para almacenar un contador global\nCREATE TABLE IF NOT EXISTS contador_global (\n    valor INT DEFAULT 0\n);\nINSERT INTO contador_global (valor) VALUES (0);\n\n-- 1. Procedimiento almacenado sin parámetros ni retorno\nDELIMITER //\nCREATE PROCEDURE saludar()\nBEGIN\n    SELECT 'Hola, mundo!' AS mensaje;\nEND //\nDELIMITER ;\n\n-- 2. Procedimiento almacenado con un parámetro y sin retorno\nDELIMITER //\nCREATE PROCEDURE saludarPersona(IN nombre VARCHAR(50))\nBEGIN\n    SELECT CONCAT('¡Hola, ', nombre, '!') AS mensaje;\nEND //\nDELIMITER ;\n\n-- 3. Función con múltiples parámetros y retorno\nDELIMITER //\nCREATE FUNCTION sumar(a INT, b INT) RETURNS INT\nDETERMINISTIC\nBEGIN\n    RETURN a + b;\nEND //\nDELIMITER ;\n\n-- 4. Función que simula una \"función dentro de otra\"\n-- (En SQL no podemos definir funciones dentro de otras, pero podemos simular el comportamiento)\nDELIMITER //\nCREATE FUNCTION operacionMatematica(a INT, b INT) RETURNS INT\nDETERMINISTIC\nBEGIN\n    DECLARE resultado INT;\n    SET resultado = a * b + 10;\n    RETURN resultado;\nEND //\nDELIMITER ;\n\n-- 5. Uso de una función incorporada en SQL\nSELECT CURRENT_DATE() AS fecha_actual;\n\n-- 6. Demostración de variable local vs global\nDELIMITER //\nCREATE PROCEDURE incrementarContador()\nBEGIN\n    DECLARE contador_local INT DEFAULT 0;\n    SET contador_local = contador_local + 1;\n    \n    UPDATE contador_global SET valor = valor + 1;\n    \n    SELECT contador_local AS contador_local, valor AS contador_global \n    FROM contador_global;\nEND //\nDELIMITER ;\n\n-- DIFICULTAD EXTRA\nDELIMITER //\nCREATE PROCEDURE imprimirYContar(IN texto1 VARCHAR(50), IN texto2 VARCHAR(50), OUT numeros_puros INT)\nBEGIN\n    DECLARE i INT DEFAULT 1;\n    DECLARE resultado VARCHAR(100);\n    SET numeros_puros = 0;\n    \n    WHILE i <= 100 DO\n        IF i % 3 = 0 AND i % 5 = 0 THEN\n            SET resultado = CONCAT(texto1, texto2);\n        ELSEIF i % 3 = 0 THEN\n            SET resultado = texto1;\n        ELSEIF i % 5 = 0 THEN\n            SET resultado = texto2;\n        ELSE\n            SET resultado = CAST(i AS CHAR);\n            SET numeros_puros = numeros_puros + 1;\n        END IF;\n        \n        SELECT resultado;\n        \n        SET i = i + 1;\n    END WHILE;\nEND //\nDELIMITER ;\n\n-- Llamadas a los procedimientos y funciones\nCALL saludar();\n\nCALL saludarPersona('Alice');\n\nSELECT sumar(5, 3) AS suma;\n\nSELECT operacionMatematica(4, 5) AS resultado_operacion;\n\nCALL incrementarContador();\nCALL incrementarContador();\n\nCALL imprimirYContar('Fizz', 'Buzz', @numeros_puros);\nSELECT @numeros_puros AS numeros_sin_reemplazar;"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/swift/18miguelgalarza.swift",
    "content": "//: [Previous](@previous)\n\n/*\n * 18miguelgalarza.swift #02 - swift\n * EJERCICIO: #02 FUNCIONES Y ALCANCE\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno... [OK]\n * - Comprueba si puedes crear funciones dentro de funciones. [OK-factible]\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje. [OK]\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.  [OK]\n * - Debes hacer print por consola del resultado de todos los ejemplos. [OK]\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\nimport Foundation\n\n//Funciones básicas\n\nfunc simple(){print(\"Hola Mundo!\")}\n\nfunc conParametros(_ nombre:String, _ apellido:String){\n\nprint(\"Hola \\(nombre) \\(apellido)!\")\n\n}\n\nfunc operadorAritmetico(_ valor1:Int, _ valor2:Int, _ operacion:String) -> Double{\n//Funcion con parametros de entrada y retorno\n    \n    switch operacion {\n    case \"suma\":\n        return Double(valor1 + valor2)\n    case \"resta\":\n        return Double(valor1 - valor2)\n    case \"multiplicacion\":\n        return Double(valor1 * valor2)\n    case \"division\":\n        return Double(valor1 / valor2)\n    default:\n        return Double(-500)\n    }\n\n}\n\nfunc getSkateboard(){\n //Funcion que indica las partes del skate y el fabricante\n    func tabla(){print(\"Tabla: Zero\")}\n    func ruedas(){print(\"Ruedas: Pig Wheels\")}\n    func truck(){print(\"Truck: Independent\")}\n    func lija(){print(\"Lija: MOB Grip\")}\n    func estoboles(){print(\"Estoboles: Spitfire\")}\n    func rodajes(){print(\"Rodajes: Bones ABEC 03\")}\n    \n    tabla()\n    ruedas()\n    truck()\n    lija()\n    estoboles()\n    rodajes()\n    \n}\n\n\nvar variableGlobal = \"Variable global\" // Variable global en Swift\n\nfunc funcionVaribleLocal() { // Variable local en Swift\n\n    let variableLocal = \"Variable local\"\n    print(variableLocal) // variable local puedo ser usado dentro de esta función\n    print(variableGlobal) // variable global puedo ser usado afuera y dentro de esta función\n}\n\n\n\n//Testing\nprint(\"********** Funciones Básicas : Testing **********\")\nsimple()\nconParametros(\"Miguel\",\"Galarza\")\nprint(\"Funcion con parametros de entrada y retorno \\(Int(operadorAritmetico(2,2,\"suma\")))\")\n\nfuncionVaribleLocal()\n//print(variableLocal) // Esto genera error, variableLocal solo es visible dentro de funcionVaribleLocal()\nprint(variableGlobal) // Imprime: Soy una variable global\n\ngetSkateboard()//funciones dentro de otra funcion\n\n\nprint(\"********** Dificultad Extra **********\")\n/**\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n */\n\nfunc dificultadExtra ( _ param01 : String, _ param02 : String ) -> Int {\n    \n    var contador:Int = 0\n    \n    for numero in 1...100 {\n      \n            if (numero % 3) == 0 && (numero % 5) == 0 {\n            print(\"El número \\(numero) es multiplo de 3 y 5 -> \\(param01) \\(param02)\")\n            contador += 1\n            }else if (numero % 3) == 0{\n            print(\"El número \\(numero) es multiplo de 3 -> \\(param01)\")\n            contador += 1\n            }else if (numero % 5) == 0{\n            print(\"El número \\(numero) es multiplo de 5-> \\(param02)\")\n            contador += 1\n            }else{\n            print(\"El número \\(numero) no tiene coincidencias\")\n            }\n    }\n    \n    return contador\n}\n\nfunc dificultadExtraVersion02 ( _ param01 : String, _ param02 : String ) -> Int {\n    \n    var contador:Int = 0\n\n        for i in 1...100{\n            switch (i.isMultiple(of: 3), i.isMultiple(of: 5)){\n            case(true, true): print(\"El número \\(i) es múltiplo de 3 y 5 -> \\(param01) \\(param02)\"); contador += 1\n            case(false, true): print(\"El número \\(i) es múltiplo de 3 -> \\(param01)\"); contador += 1\n            case(true, false): print(\"El número \\(i) es múltiplo de 5-> \\(param02)\"); contador += 1\n            default: print(\"El número \\(i) no es múltiplo con 3 y 5\")\n            }\n        }\n    \n    return contador\n}\n\n\n\nprint(\"\\nLas veces que se han impreso los textos son :  \\( Int(dificultadExtra(\"Miguel\",\"Galarza\"))) veces\")\nprint(\"\\nLas veces que se han impreso los textos son :  \\( Int(dificultadExtraVersion02(\"Miguel\",\"Galarza\"))) veces\")\n\n\nlet banner = \"\"\"\n             \n                                                   hhhhhhh\n                                                   h:::::h\n                                                   h:::::h\n                                                   h:::::h\nppppp   ppppppppp  uuuuuu    uuuuuu     ssssssssss  h::::h hhhhh\np::::ppp:::::::::p u::::u    u::::u   ss::::::::::s h::::hh:::::hhh\np:::::::::::::::::pu::::u    u::::u ss:::::::::::::sh::::::::::::::hh\npp::::::ppppp::::::u::::u    u::::u s::::::ssss:::::h:::::::hhh::::::h\n p:::::p     p:::::u::::u    u::::u  s:::::s  ssssssh::::::h   h::::::h\n p:::::p     p:::::u::::u    u::::u    s::::::s     h:::::h     h:::::h\n p:::::p     p:::::u::::u    u::::u       s::::::s  h:::::h     h:::::h\n p:::::p    p::::::u:::::uuuu:::::u ssssss   s:::::sh:::::h     h:::::h\n p:::::ppppp:::::::u:::::::::::::::us:::::ssss::::::h:::::h     h:::::h\n p::::::::::::::::p u:::::::::::::::s::::::::::::::sh:::::h     h:::::h\n p::::::::::::::pp   uu::::::::uu:::us:::::::::::ss h:::::h     h:::::h\n p::::::pppppppp       uuuuuuuu  uuuu sssssssssss   hhhhhhh     hhhhhhh\n p:::::p\n p:::::p\np:::::::p\np:::::::p\np:::::::p\nppppppppp\n                                                                       \n                                                                         \n\"\"\"\n\nprint(banner)\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/swift/PineroDev.swift",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\nimport Foundation\n\nfunc funSimple() {\n    print(\"Función sin parámetros ni retorno.\")\n}\n\nfunc conParamentro(valor1: Int, valor2: Int) {\n    print(valor1 + valor2)\n}\n\nfunc conRetorno(valorD1: Double, valorD2: Double) -> Double {\n    return valorD1 + valorD2\n}\n\n// Llamada a funcion funSimple\nfunSimple()\n\n// Llamada a funcion ConParametro\nvar valor1 = 9\nvar valor2 = 7\nconParamentro(valor1: valor1, valor2: valor2)\n\n// Llamada a conRetorno\nvar total = 0.0\nvar valorD1 = 3.5\nvar valorD2 = 6.2\ntotal = conRetorno(valorD1: valorD1, valorD2: valorD2)\nprint(total)\n\n\n// Funcion con funciones dentro y datos locales\nlet isUserName: Bool = true\nlet isPremium: Bool = false\n\nfunc comprobarUser (isUserName: Bool, isPremium: Bool){\n    var correcto: String  = \"\"\n    var incorrecto: String  = \"\"\n    \n    func bienvenido() -> String{\n        return \"Bienvenido usuario Premium\"\n    }\n    func noPremium() -> String{\n        return \"No eres Premium\"\n    }\n    \n    if isUserName && isPremium {\n        correcto = bienvenido()\n        print(correcto)\n    }else {\n        incorrecto = noPremium()\n        print(incorrecto)\n    }\n}\ncomprobarUser(isUserName: isUserName, isPremium: isPremium)\n\n//------------------------------------------\n\n//DIFICULTAD EXTRA\n\nfunc imprimirNum(parametro1: String, parametro2: String) -> Int{\n    var cont: Int = 0\n    for i in 1...100{\n        if i % 3 == 0 && i % 5 == 0{\n            print(parametro1+parametro2+\" \\(i)\")\n        }else if i % 3 == 0{\n            print(parametro1+\" \\(i)\")\n        }else if i % 5 == 0{\n            print(parametro2+\" \\(i)\")\n        }else{\n            cont += 1\n        }\n    }\n    return cont\n}\n\nlet resultado = imprimirNum(parametro1: \"Papaya\", parametro2: \"Higos\")\nprint(\"Cantidad de numero que no son multiplos de 3, 5 y 3 y 5 conjuntamente: \\(resultado)\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/swift/allbertoMD.swift",
    "content": "import Foundation\n\n\n\n// Función sin parametros\nprint(\"\\nFucnción Sin Parametros\")\nfunc helloWorld() {\n    print(\"Hola mundo\")\n}\nhelloWorld()\n\n\n\n// Fución con un parametro\nprint(\"\\nFunción Con Un Parametro\")\nfunc greet(to name: String) {\n    print(\"Hola \\(name)\")\n}\ngreet(to: \"Alberto\")\n\n\n\n// Fución con multiples parametros\nprint(\"\\nFunción Con Multiples Parametros\")\nfunc personInfo(of firstName: String, secondName: String, age: Int, jobPosition: String) {\n    print(\"La persona seleccionada es: \\(firstName) \\(secondName) tiene \\(age) años y trabaja de \\(jobPosition)\")\n}\npersonInfo(of: \"Ricardo\", secondName: \"Fernandez\", age: 30, jobPosition: \"Jardinero\")\n\n\n\n// Función con retorno\nprint(\"\\nFunción Con Retorno\")\nfunc greet(person: String) -> String {\n    let name: String = person\n    return \"Hola \\(name) que tal estas\"\n}\nprint(greet(person: \"Yaiza\"))\n\n\n\n// Función con parametros varialbes\nprint(\"\\nFunción Con Parametros Variables\")\nfunc swapTwoInts(a: inout Int, b: inout Int) -> (a: Int, b: Int) {\n    let temporaryA: Int = a\n    a = b\n    b = temporaryA\n    return (a, b)\n}\nvar integer: Int = 33\nvar anotherInteger: Int = 10\nprint(\"La variable a vale: \\(swapTwoInts(a: &integer, b: &anotherInteger).a), la variable b vale: \\(swapTwoInts(a: &anotherInteger, b: &integer).b)\")\n\n\n\n// Fución dentro de una función\nprint(\"\\nFunción Dentro De Una Función\")\nfunc firstFunction() {\n    print(\"Soy la primera función\")\n\n    func secondFunction() {\n        print(\"Soy la segunda función\")\n    }\n    secondFunction()\n}\nfirstFunction()\n\n\n\n// Función con función en parametro\nprint(\"\\nFunción Con Función En Parametro\")\nfunc addFunction(a: Int, b: Int) -> Int {\n    return a + b\n}\nfunc arithmeticFunction(numA: Int, numB: Int, function: (Int, Int) -> Int) {\n    print(\"El resultado de la operacion es: \\(function(numA, numB))\")\n}\narithmeticFunction(numA: 2, numB: 2, function: addFunction)\n\n\n\n// Variable local\nprint(\"\\nVariable Local\")\nfunc useLocalVariable() {\n    var localVariable = \"\"\n    localVariable = \"Soy una variable local\"\n    print(localVariable)\n}\nuseLocalVariable()\n\n\n\n// Variable global\nprint(\"\\nVariable Global\")\nvar globalVariable: String = \"\"\nglobalVariable = \"Soy una variable global\"\nfunc useGlobalVariable(str: String) {\n    print(str)\n}\nuseGlobalVariable(str: globalVariable)\n\n\n\n// Funciones del lenguaje\nprint(\"\\nFunción Del Lenguaje\")\nprint(\"Potenciacion 2^3 = \\(pow(2.0, 3.0))\")\n\n\n\n// Dificultad extra\nfunc printNumbersOrStrings(str1: String, str2: String) -> Int {\n    var counter: Int = 0\n\n    for n in 1...100 {\n        if n % 5 == 0 && n % 3 == 0 {\n            print(str1 + \" \" + str2)\n            continue\n        } else if n % 5 == 0 {\n            print(str1)\n            continue\n        } else if n % 3 == 0 {\n            print(str2)\n        }\n        print(n)\n        counter += 1\n    }\n    return counter\n}\nprint(\"\\nDificultas Extra\")\nlet howManyNumbers: Int = printNumbersOrStrings(str1: \"Hola\", str2: \"Mundo\")\nprint(\"Se han impreso: \\(howManyNumbers) numeros\")\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/swift/blackriper.swift",
    "content": "/*\n  Convenciones del lenguaje Swift\n1. Nombres:\n\nLos nombres de variables, constantes, funciones, tipos y métodos deben ser descriptivos y en minúscula.\nSe pueden usar guiones bajos para separar palabras en nombres compuestos.\nLos nombres de tipo deben comenzar con una letra mayúscula.\nLas constantes deben tener un nombre en mayúscula con guiones bajos.\n2. Sangrías:\n\nSe debe usar una sangría de 4 espacios para las indentaciones.\nLas llaves de apertura y cierre deben estar en la misma línea que la instrucción que controlan.\n3. Espacios en blanco:\n\nSe debe usar un espacio después de las comas, puntos y comas.\nSe debe usar un espacio antes y después de los operadores.\n4. Comentarios:\n\nLos comentarios se pueden agregar usando // para comentarios de una sola línea o /* ... */ para comentarios de varias líneas.\n5. Enumeraciones:\n\nLos casos de enumeración deben estar en minúscula y separados por comas.\nEl último caso de enumeración no debe tener una coma al final.\n6. Funciones:\n\nLos argumentos de las funciones deben estar en minúscula y separados por comas.\nEl tipo de retorno de la función debe estar antes del nombre de la función.\n7. Clases:\n\nLos nombres de las clases deben comenzar con una letra mayúscula.\nLas propiedades y métodos de las clases deben ser públicos o privados.\n8. Protocolos:\n\nLos nombres de los protocolos deben comenzar con una letra mayúscula.\nLos métodos de los protocolos deben ser públicos.\n9. Extensiones:\n\nLas extensiones se pueden usar para agregar métodos a tipos existentes.\nEl nombre de la extensión debe comenzar con un guión bajo.\n10. Importaciones:\n\nSe deben usar importaciones para acceder a los tipos y funciones de otros módulos.\nSe debe usar la importación import para importar módulos completos.\nSe debe usar la importación import . para importar miembros específicos de un módulo.\n*/\n\n// ejemplos de funciones \n\n//sin parametros y sin retorno\nfunc helloWorld() {\n    print(\"Hello, World!\")\n}\n\n// con parametros y con retorno\nfunc sum(a: Int, b: Int) -> Int {\n    return a + b\n}\n\nprint(\"La suma de 5 + 3 es \\(sum(a: 5, b: 3))\")\n\n\n// retorno multiple como una tupla \nfunc rest(a: Int, b: Int) -> (resta: Int, multiplicacion: Int) {\n    let resta = a - b\n    let multiplicacion = a * b\n    return (resta, multiplicacion)\n}\n\nlet results=rest(a: 4, b: 5)\nprint(\"La resta de 4 - 5 es \\(results.resta) y la multiplicación es \\(results.multiplicacion)\")\n\n// cuando solo se va retornar un valor se puede hacer sin la palabra return \nfunc suma2(a: Int, b: Int) -> Int {\n    a + b\n}\nprint(\"La suma de 5 + 3 es \\(suma2(a: 5, b: 3))\")\n\n// funcion con argumental label \nfunc greeting(person: String , from hometown: String) {\n    print(\"Hello \\(person)! Glad you could visit from \\(hometown).\")\n}\ngreeting(person: \"Diego\", from: \"Madrid\")\n\n// funcion con argumental label y sin argumental label\nfunc greet(_ person: String, from hometown: String) {\n    print(\"Hello \\(person)! Glad you could visit from \\(hometown).\")\n}\ngreet(\"Diego\", from: \"Madrid\")\n\n// funcion con parametros con valor por defecto\nfunc greet2(_ person: String, from hometown: String = \"Madrid\") {\n    print(\"Hello \\(person)! Glad you could visit from \\(hometown).\")\n}\ngreet2(\"Diego\")\n\n// funcion con parametros sin especificar el numero del mismo\nfunc showNumbers(_ numbers: Int...) {\n    for number in numbers {\n        print(number)\n    }\n}\nshowNumbers(1, 2, 3, 4, 5)\n\n// funcion dentro de otra funcion\nfunc chooseStepFunction(backward: Bool) -> (Int) -> Int {\n    func stepForward(input: Int) -> Int { return input + 1 }\n    func stepBackward(input: Int) -> Int { return input - 1 }\n    return backward ? stepBackward : stepForward\n}\nvar currentValue = -4\nlet moveNearerToZero = chooseStepFunction(backward: currentValue > 0)\n// moveNearerToZero now refers to the nested stepForward() function\nwhile currentValue != 0 {\n    print(\"\\(currentValue)... \")\n    currentValue = moveNearerToZero(currentValue)\n}\nprint(\"zero!\")\n\n\n// ejercicio extra \nfunc printerNumbers(text1:String,text2:String)->Int{\n    var numRep=0\n    for num in 1...100{\n        if num % 5 == 0 && num % 3 == 0{\n            print(\"\\(text1) \\(text2)\")\n        }else if num % 5 == 0{\n            print(\"\\(text2)\")\n        }else if num % 3 == 0{\n            print(\"\\(text1)\")\n            \n        }else{\n            numRep+=1\n        }\n        \n    }\n    return numRep\n}\n\nlet num=printerNumbers(text1: \"Hulk\", text2: \"aplasta!!\")\nprint(\"\\(num) es el total de numeros que se imprimen\")"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/swift/didacdev.swift",
    "content": "import Foundation\n\n// Funciones sin parámetros y valor de retorno\nfunc hello() -> String {\n    return \"hello\"\n}\n\nprint(hello())\n\n// Funciones con múltiples parámetros\nfunc say(person: String, sentence: String) -> String {\n    return \"\\(sentence) \\(person)\" \n}\n\nprint(say(person: \"Diego\", sentence: \"hello\"))\n\n// Funciones sin valores de retorno\nfunc greet(person: String) {\n    print(\"hello \\(person)\")\n}\n\n// Funciones con varios valores de retorno\nfunc sayHelloToTwo(personOne: String, personTwo: String) -> (helloOne: String, helloTwo: String) {\n\n    return(\"hello \\(personOne)\", \"hello \\(personTwo)\")\n}\n\nlet greetings: (String, String) = sayHelloToTwo(personOne: \"Diego\", personTwo: \"Pepe\")\nprint(greetings.0)\nprint(greetings.1)\n\n// Retorno implícito\nfunc greet(for person: String) -> String {\n    \"hello \\(person)\"\n}\n\nprint(greet(for: \"Diego\"))\n\n// Especificar etiquetas en los argumentos\nfunc greet(person: String, from hometown: String) -> String {\n    return \"hello \\(person) for comming from \\(hometown)\"\n}\n\nprint(greet(person: \"Diego\", from: \"Madrid\"))\n\n// Omitir las etiquetas\nfunc sumaDos(_ number: Int) -> Int {\n    let result = number + 2\n    return result\n}\n\nprint(sumaDos(2))\n\n// Parámetros con valor por defecto\nfunc sayHello(person: String, greet: Bool = true) -> String{\n    if greet {\n        return \"hello \\(person)\"\n    } else {\n        return \"bye\"\n    }\n}\n\nprint(sayHello(person: \"Diego\"))\n\n// Parámetros variados\nfunc greetToPeople(_ people: String...) -> [String] {\n    var greet: [String] = []\n\n    for person in people {\n        greet.append(\"hello \\(person)\") \n    }\n\n    return greet\n}\n\nprint(greetToPeople(\"Diego\", \"Pepe\"))\n\n// Parámetros de entrada y salida\nfunc sumaDos(_ number: inout Int) {\n    number += 2\n}\n\nvar number = 2\nsumaDos(&number)\nprint(number)\n\n// Funciones anidadas\nfunc sumaDos(add: Bool) -> (Int) -> Int {\n\n    func addTwo(number: Int) -> Int {\n        let result = number + 2\n        return result\n    }\n\n    func addOne(number: Int) -> Int {\n        let result = number + 1\n        return result\n    }\n\n    return add ? addTwo : addOne \n}\n\nlet suma = sumaDos(add: false)\nprint(suma(2))\n\n\n// --------------------- Ejercicio ---------------------------\nfunc times(textOne: String, textTwo: String) -> Int {\n    \n    var times = 0\n\n    for number in 1...100 {\n\n\n        if number % 3 == 0 {\n            print(textOne)\n            times += 1\n        } else if number % 5 == 0 {\n            print(textTwo)\n            times += 1\n        } else if number % 3 == 0 && number % 5 == 0 {\n            print(\"\\(textOne) \\(textTwo)\")\n            times += 1\n        } else {\n            print(number)\n        }\n    }\n\n    return times\n}\n\nprint(times(textOne: \"hola\", textTwo: \"adios\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/swift/gliadev.swift",
    "content": "import Foundation\n\n// Ejemplo de una función sin parámetros ni retorno\nfunc imprimirMensaje() {\n    print(\"Esta es una función sin parámetros ni retorno\")\n}\nimprimirMensaje() // Llamada a la función\n\n// Ejemplo de una función con un parámetro\nfunc saluda(nombre: String) {\n    print(\"Hola, \\(nombre)!\")\n}\nsaluda(nombre: \"Adolfo\") // Llamada a la función con un parámetro\n\n// Ejemplo de función con varios parámetros\nfunc suma(a: Int, b: Int) {\n    print(\"La suma de \\(a) y \\(b) es \\(a + b)\")\n}\nsuma(a: 5, b: 3) // Llamada a la función con múltiples parámetros\n\n// Ejemplo de función con retorno\nfunc multiplica(a: Int, b: Int) -> Int {\n    return a * b\n}\nprint(\"El resultado de multiplicar 4 y 5 es \\(multiplica(a: 4, b: 5))\")\n\n// Función dentro de función\nfunc operacionesCompuestas() {\n    func resta(a: Int, b: Int) -> Int {\n        return a - b\n    }\n    print(\"El resultado de restar 5 de 10 es \\(resta(a: 10, b: 5))\")\n}\noperacionesCompuestas() // Llamada a la función contenedora\n\n// Variable global y local\nvar variableGlobal = 10 // Variable global\n\nfunc probarVariables() {\n    let variableLocal = 5 // Variable local\n    print(\"Variable global: \\(variableGlobal), Variable local: \\(variableLocal)\")\n}\nprobarVariables()\n\n// Función con dificultad extra\nfunc imprimirNumeros(cadena1: String, cadena2: String) -> Int {\n    var contador = 0\n    for numero in 1...100 {\n        if numero % 3 == 0 && numero % 5 == 0 {\n            print(\"\\(cadena1)\\(cadena2)\")\n        } else if numero % 3 == 0 {\n            print(cadena1)\n        } else if numero % 5 == 0 {\n            print(cadena2)\n        } else {\n            print(numero)\n            contador += 1\n        }\n    }\n    return contador\n}\n\nlet contador = imprimirNumeros(cadena1: \"Fizz\", cadena2: \"Buzz\")\nprint(\"Se imprimieron \\(contador) números en lugar de textos.\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/swift/karys4.swift",
    "content": "// Función sin parámetros ni retornos.\nfunc saludar() {\n    print(\"Hola, soy una función sin parámetros ni retornos!\")\n}\n\nsaludar()\n\n// Función con varios parámetros.\nfunc variosParametros(nombre: String, happy: Bool) {\n\n    if happy {\n        var pais = \"México\" // Variable Local\n        print(\"Hola \\(nombre) feliz que vive en \\(pais).\")\n    } else {\n        print(\"Adios \\(nombre).\")\n    }\n}\n\nvariosParametros(nombre: \"karys\", happy: true)\n\n// Función con parámetro y retorno.\nfunc diaFavorito(dia: String) -> String {\n\n    switch dia {\n    case \"Viernes\":\n    return \"Casi se acerca el fin de semana\"\n    case \"Sábado\":\n    return \"El mejor día del fin de semana\"\n    case \"Domingo\":\n    return \"Día completo para descansar\"    \n    default:\n    return \"No es un día válido\"\n     }  \n}\n\ndiaFavorito(dia: \"Sábado\")\n\n\n/*DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n func imprimirNumeros(cadena1: String, cadena2: String) -> Int {\n   \n    var contador = 0 // Variable Global\n    for numero in 1...100 {\n        if (numero % 3 == 0) && (numero % 5 == 0) {\n            print(\"El número \\(numero) es \\(cadena1) y es \\(cadena2)\")  \n            contador += 1\n            \n        } else if numero % 3 == 0 {\n            print(\"El número \\(numero) es \\(cadena1)\")\n            contador += 1\n            \n        } else if numero % 5 == 0 {\n             print(\"El número \\(numero) es \\(cadena2)\")\n             contador += 1 \n        }\n    } \n    print(\"Se imprimieron \\(contador) números.\") \n    return contador\n }\n\nimprimirNumeros(cadena1: \"múltiplo de 3\",cadena2: \"múltiplo de 5\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/swift/kontroldev.swift",
    "content": "import Foundation\n\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n\nfunc saludar() {\n    print(\"¡Hola, mundo!\")\n}\nsaludar()\n\nfunc saludar(nombre: String) {\n    print(\"¡Hola, \\(nombre)!\")\n}\nsaludar(nombre: \"Juan\")\n\nfunc sumar(a: Int, b: Int) -> Int {\n    return a + b\n}\nlet resultado = sumar(a: 3, b: 4)\nprint(\"El resultado de la suma es \\(resultado)\")\n\nfunc funcionExterna() {\n    func funcionInterna() {\n        print(\"Esta es una función interna\")\n    }\n    funcionInterna()\n}\nfuncionExterna()\n\nlet numeros = [1, 2, 3, 4, 5]\nlet numerosPares = numeros.filter { $0 % 2 == 0 }\nprint(numerosPares)\n\nvar variableGlobal = 10\n\nfunc funcionConVariableLocal() {\n    let variableLocal = 5\n    print(\"La variable local es \\(variableLocal)\")\n}\n\nfuncionConVariableLocal()\nprint(\"La variable global es \\(variableGlobal)\")\n\nfunc imprimirNumeros(texto1: String, texto2: String) -> Int {\n    var contador = 0\n    for i in 1...100 {\n        if i % 3 == 0 && i % 5 == 0 {\n            print(\"\\(texto1)\\(texto2)\")\n            contador += 1\n        } else if i % 3 == 0 {\n            print(\"\\(texto1)\")\n            contador += 1\n        } else if i % 5 == 0 {\n            print(\"\\(texto2)\")\n            contador += 1\n        } else {\n            print(i)\n        }\n    }\n    return contador\n}\n\nlet vecesImpreso = imprimirNumeros(texto1: \"Hola\", texto2: \"Mundo\")\nprint(\"La función ha impreso \\(vecesImpreso) veces\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/swift/miguelex.swift",
    "content": "import Foundation\n\nfunc holaMundo(){\n    print(\"¡Hola, mundo!\")\n}\n\nholaMundo()\n\nfunc mostrarEdad(edad: Int){\n    print(\"Tienes \\(edad) años\")\n}\n\nmostrarEdad(edad: 48)\n\nfunc sumar(a: Int, b: Int) -> Int {\n    return a + b\n}\n\nprint(\"La suma de 5 + 3 es  \\(sumar(a:5, b:3))\")\n\nfunc mainFunction(){\n    print(\"Este mensaje se muestra desde al funcion más externa\")\n    func innerFunction(){\n        print(\"Este mensaje se muestra desde la función interna\")\n    }\n    innerFunction()\n}\n\nmainFunction()\n\nlet numeros = [1, 2, 3, 4, 5]\n\nlet pares = numeros.filter { $0 % 2 == 0 }\nprint(\"\\nNumeros pares: \\n\\(pares)\")\n\n// Extra\n\nfunc extra(param1: String, param2: String) -> Int {\n    var numVeces = 0\n    for i in 1...100 {\n        if i % 15 == 0  {\n            print(\"\\(param1)\\(param2)\")\n        } else if i % 3 == 0 {\n            print(\"\\(param1)\")\n        } else if i % 5 == 0 {\n            print(\"\\(param2)\")\n        } else {\n            print(i)\n            numVeces += 1\n        }\n    }\n    return numVeces\n}\n\nprint(\"La función ha impreso un total de \\(extra(param1:\"Fizz\", param2:\"Buzz\")) numeros\")\n\n\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/swift/paola-itzel-martinez.swift",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n/*\n Variable / constante global\n */\nlet firstString = \"Hello\"\n\n\n\n/*\n Función sin parámetros ni retorno\n */\nfunc printFirstString() {\n    print(firstString)\n}\n\nprintFirstString()\n\n\n\n/*\n Función con un parámetro y sin retorno\n */\nfunc printSecondString(secondString: String) {\n    print(secondString)\n}\n\nprintSecondString(secondString: \"World\")\n\n\n\n/*\n Función con varios parámetros y con retorno\n*/\nfunc concatStrings(firstString: String, secondString: String) -> String {\n    let localVariable = \"\\(firstString) \\(secondString)\"\n    \n    return localVariable\n}\n\nprint(concatStrings(firstString: \"Hello\", secondString: \"world\"))\n\n\n\n/*\n Función con varios parámetros y varios retornos\n*/\nfunc concatSpecialPhrase(firstString: String, secondString: String) -> (cutePhrase: String, normalPhrase: String) {\n    let cutePhrase = \"\\(firstString), have a nice day!\"\n    let normalPhrase = \"\\(secondString), bye\"\n    \n    return (\n        cutePhrase,\n        normalPhrase\n    )\n}\n\nlet (cutePhrase, normalPhrase) = concatSpecialPhrase(firstString: \"Hello\", secondString: \"Hello\")\n\nprint(cutePhrase)\nprint(normalPhrase)\n\n\n\n/*\n Función dentro de otra función\n*/\nfunc printGreetings() {\n    let firstString = \"Hello\"\n    let secondString = \"Today is a good day\"\n    \n    let (cutePhrase, normalPhrase) = concatSpecialPhrase(\n        firstString: firstString,\n        secondString: secondString\n    )\n    \n    print(cutePhrase, \".\", normalPhrase)\n}\n\nprintGreetings()\n\n\n\n/*\n Funciones ya creadas en el lenguaje\n*/\nlet exists = [1, 2, 3].contains(2)\n\nprint(\"[1, 2, 3].contains(2) = \\(exists)\")\n\n\n\n/*\n Extra\n*/\n\nprint(\"\\n ------EXTRA------\")\n\n\nfunc extraExercise(firstString: String, secondString: String) -> Int {\n    var totalNumberPrinted: Int = 0\n    \n    for value in 1...100 {\n        let isMultipleOfThree = value % 3 == 0\n        let isMultipleOfFive = value % 5 == 0\n        \n        if (isMultipleOfThree && isMultipleOfFive) {\n            print(firstString, secondString)\n        } else if (isMultipleOfThree) {\n            print(firstString)\n        } else if (isMultipleOfFive) {\n            print(secondString)\n        } else {\n            totalNumberPrinted += 1\n        }\n    }\n    \n    return totalNumberPrinted\n}\n\nlet totalNumberPrinted = extraExercise(firstString: \"% 3\", secondString: \"% 5\")\n\nprint(\"Original numbers was printed: \\(totalNumberPrinted) times\")\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/swift/pedroomar23.swift",
    "content": "import Foundation \n\n/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n// Funciones sin parametros ni retorno\nfunc Greeting() {\n    print(\"!Welcome to Hola Mundo Day!\")\n}\n\nGreeting()\n\n// Funiones con uno o varios para metros \nlet nombres = [\"Pedro\", \"Juan\", \"Oscar\"] // Cadena de texto (String) \n\n// Ejemplo 1\nfunc Perfil(nombres: String) {\n    print(\"El perfil de las personas es \\(nombres)\")\n}\n\nlet age = [20, 25, 30] // Cadena de enteros (Int)\n\n// Ejemplo 2\nfunc age(age: Int) {\n    print(\"El array tiene una cadena de valores \\(age)\")\n}\n\n// Funciones con retorno\nfunc suma(a: Int, b: Int) -> Int { // Ejemplo 1 Suma\n    return a + b\n}\nprint(\"El resultado de la suma 5 + 5 es \\(suma(a: 5, b: 5))\")\n\nfunc resta(a: Int, b: Int) -> Int { // Ejemplo 2 Resta\n    return a - b \n}\nprint(\"El resultado de las resta 10 - 5 es \\(resta(a: 10, b: 5))\")\n\nfunc combinada(a: Int, b: Int, c: Int, d: Int) -> Int { // Ejemplo 3 Combinada \n    return a + b / c * d\n}\nprint(\"El resultado de la combinada 15 - 5 / 2 * 4 es \\(combinada(a: 1, b: 5, c: 2, d: 4))\")\n\n// Funciones dentro de funciones \nfunc MainActor() {\n    print(\"Esta funcion va dirigida a la parte externa\")\n\n    func OtherAction() {\n        print(\"Esta funcion va dirigida a la parte interna\")\n\n        OtherAction()\n    }\n}\nMainActor()\n\n// Variable Local\nvar numeros = 10\nfunc LocalVar() {\n    print(numeros)\n}\n\n// Variable Global\nvar numeros = 10\n\nfunc GlobalVar(numeros: Int) {\n   print(numeros)\n}\nGlobalVar(numeros: numeros)\n\n\n// Extra \nfunc extra(a: String, b: String) -> Int {\n    var count = 0\n\n    for number in 1...100 {\n        if number % 3 == 0 {\n            count += 1\n            print(a)\n        } else if number % 5 == 0 {\n            count += 1\n            print(b)\n        } else if number % 3 == 0 && number % 5 == 0 {\n            count += 1\n            print(a, b)\n        } \n    }\n    return count \n}\n\nlet new = extra(a: \"Juan\", b: \"Carlos\")\nprint(\"Los nombres se han imprimido en la consola \\(new) veces\")\n\n\n\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/swift/zetared92.swift",
    "content": "import Foundation\n\n// RETO #02 FUNCIONES Y ALCANCE\n\n// Función sin parámetros\nprint(\"\\nEsto es una función sin parámetros: \")\n\nfunc helloWorld() {\n    print(\"Hello, World!\")\n}\n\nhelloWorld()\n\n// Función con un parámetro\nprint(\"\\nEsto es una función con un parámetro: \")\n\nfunc squared(num:Int){\n    let squareNum = num * num\n\n    print(squareNum)\n}\n\nsquared(num: 5)\n\n// Función con múltiples parámetros y valor de retorno\nprint(\"\\nEsto es una función con múltiples parámetros y valor de retorno: \")\n\nfunc cube(num: Int) -> Int {\n    return num * num * num\n}\n\nlet resultCube = cube(num:5)\nprint(\"El resultado de cube³ es: \\(resultCube)\")\n\n// Función dentro de función\nprint(\"\\nEsto es una función dentro de una función: \")\n\nfunc myFirstFunc(){\n    print(\"Un gran poder, conlleva\")\n\n    func mySecondFunc(){\n        print(\"una gran responsabilidad\")\n    }\n    mySecondFunc()\n}\nmyFirstFunc()\n\n// Variable local\nprint(\"\\nVariables locales\")\n\nfunc localVarFunc() {\n    var localVar = 15\n\n    print(\"El valor de la variable local es: \\(localVar)\") \n}\nlocalVarFunc()\n\n// Variable global\nprint(\"\\nVariables globales\")\n\nvar globalVar: Int = 150\nfunc globalVarFunc(integer: Int) {\n    print(integer)\n\n}\nglobalVarFunc(integer: globalVar)\n\n\n/* DIFICULTAD EXTRA:\nCrea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n    - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n    - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n    - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n    - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n    - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n*/\n\nfunc printNum(str1: String, str2: String) -> Int {\n    var counter = 0\n    for i in 1...100 {\n        if i % 3 == 0 && i % 5 == 0 {\n            print(\"\\(str1)\\(str2)\")\n            counter += 1\n        } else if i % 3 == 0 {\n            print(\"\\(str1)\")\n            counter += 1\n        } else if i % 5 == 0 {\n            print(\"\\(str2)\")\n            counter += 1\n        } else {\n            print(i)\n        }\n    }\n    return counter\n}\n\nlet printedNum = printNum(str1: \"Hello\", str2: \"World!\")\nprint(\"\\(printedNum) times has been printed\")\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/typescript/AChapeton.ts",
    "content": "// *** TIPOS DE FUNCIONES ***\n\n//Funcion Autoejecutable\n(function () {\n  console.log(\"Autoejecutable\");\n})();\n\n//Funcion por Declaracion\nfunction saludar(): void{\n    return console.log('Hello World!')\n}\n\nsaludar()\n\n//Funcion por Expresion\nconst saludo: () => void = function saludar2(){\n    return console.log('Hola!')\n}\n\nsaludo()\n\n//Funcion Anonima\nconst anonima: () => void = function(){\n    return console.log('Sin nombre')\n}\n\nanonima()\n\n//Arrow Function\nconst arrow: () => void = () => {\n    return console.log('Arrow function')\n}\n\narrow()\n\n//Callbacks\nconst funB = function(){\n    return console.log('Funcion B ejecutada')\n}\n\nconst funA = function(callback){\n    callback()\n}\n\nfunA(funB)\n\n\n// *** FORMAS DE USO DE FUNCIONES ***\n//Sin parametros\nconst sinParametros: () => void = () => {\n    return console.log('Sin parametros')\n}\n\n//Con uno o varios parametros\n\nconst suma: (a: number, b: number) => void = (a: number, b: number){\n    return console.log(a+b)\n}\n\nsuma(4, 3)\n\n//Sin retorno\nconst sinReturn: () => void = () => {\n    console.log('Sin return')\n}\n\nsinReturn()\n\n//Con retorno\nconst conReturn: () => number = () => {\n    const sum = 4 + 5\n    return sum\n}\n\nconReturn()\n\n\n//Variable Local y Global\n\nlet globalVar = 10\n\nconst funcLocal: () => void = () => {\n    const localVar = 4\n    globalVar = 2\n    return console.log(localVar + globalVar)\n}\n\n//localVar no es accesible fuera de la funcion\n//globalVar esta disponible en cualquier lugar de la funcion\n\nfuncLocal()\n\n\n//EJERCICIO EXTRA\nconst funbun: (firstText: string, secondText: string) => number = (firstText: string, secondText: string) => {\n    let count: number = 0\n    for(let i: number = 1; i <= 100; i++){\n        if(i % 3 === 0 && i % 5 === 0){\n            console.log(firstText + secondText)\n        }else if(i % 3 === 0){\n            console.log(firstText)\n        }else if(i % 5 === 0){\n            console.log(secondText )\n        }else{\n            count++\n            console.log(i)\n        }\n    }\n\n    console.log('Numeros impresos: ', count)\n    return count\n}\n\nfunbun('FUN', 'BUN')\n\n\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/typescript/Andeveling.ts",
    "content": "// Ejemplo de función sin parámetros ni retorno\nfunction saludarAlMundo(): void {\n  console.log(\"¡Hola mundo!\")\n}\n\n// Ejemplo de función con un parámetro y retorno\nfunction duplicar(numero: number): number {\n  return numero * 2\n}\n\n// Ejemplo de función con varios parámetros y retorno\nfunction sumar(a: number, b: number): number {\n  return a + b\n}\n\n// Ejemplo de función dentro de función\nfunction operacionesMatematicas(): void {\n  function resta(a: number, b: number): number {\n    return a - b\n  }\n\n  const resultadoResta = resta(10, 5)\n  console.log(\"Resultado de la resta:\", resultadoResta)\n}\n\n// Ejemplo de uso de funciones ya creadas en el lenguaje\nconst arrayEjemplo: number[] = [1, 2, 3, 4, 5]\nconst sumaArray = arrayEjemplo.reduce((a, b) => a + b, 0)\nconsole.log(\"Suma del array:\", sumaArray)\n\n// Ejemplo de variable local y global\nlet variableGlobal: number = 100\n\nfunction mostrarVariableGlobal(): void {\n  console.log(\"Variable global dentro de la función:\", variableGlobal)\n}\n\nfunction cambiarVariableGlobal(): void {\n  let variableLocal: number = 50\n  variableGlobal = variableLocal\n  console.log(\"Variable global cambiada dentro de la función:\", variableGlobal)\n}\n\n// Llamadas a las funciones\nsaludarAlMundo()\nconsole.log(\"Resultado de duplicar(4):\", duplicar(4))\nconsole.log(\"Resultado de sumar(3, 7):\", sumar(3, 7))\noperacionesMatematicas()\nconsole.log(\"Variable global fuera de la función:\", variableGlobal)\nmostrarVariableGlobal()\ncambiarVariableGlobal()\nconsole.log(\"Variable global después de cambiarVariableGlobal:\", variableGlobal)\n\n// Funcion que recibe dos paremetros\nfunction cadenasRetornoNumero(fizz: string = \"fizz\", buzz: string = \"buzz\"): number {\n  if (typeof fizz !== \"string\" || typeof buzz !== \"string\") {\n    throw new Error(\"Los argumentos deben ser cadenas de texto\")\n  }\n  let contador = 0\n  for (let i = 1; i <= 100; i++) {\n    if (i % 3 === 0 && i % 5 === 0) {\n      console.log(fizz + buzz)\n      contador++\n    } else if (i % 3 === 0) {\n      console.log(fizz)\n      contador++\n    } else if (i % 5 === 0) {\n      console.log(buzz)\n      contador++\n    } else {\n      console.log(i)\n    }\n  }\n  return contador\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/typescript/CarlosAVargas7.ts",
    "content": "/*\n * EJERCICIO:\n * -//! Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n*/\nfunction sinParametrosNiRetorno(): void {\n\n}\n\n\nfunction ConUnParametro(a: number): number {\n    console.log(`Hola parametro ${a}`) // Hola parametro 7\n    return a\n}\nconst mostrarFun1 = ConUnParametro(7);\nconsole.log(mostrarFun1) //7\n\n\nfunction conVariosParametros(b: string, c: string): void {\n    console.log(`Hola parametros ${b} ${c}`) //Hola parametros Hola Mundo\n}\nconst mostrarFun2 = conVariosParametros(\"Hola\", \"Mundo\");\nconsole.log(mostrarFun2) // undefined \n\n\n/* \n*-//! Comprueba si puedes crear funciones dentro de funciones.\n*/\nfunction funcionExterna(nombre: string): string {\n    function funcionInterna(saludo: string): string {\n        return `${saludo}, ${nombre}!`;\n    }\n    return funcionInterna(\"Hola\");\n}\n\nconsole.log(funcionExterna(\"Juan\")); // Imprime: Hola, Juan!\n\n/* \n*-//! Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n*/\n\n\n//*Función básica con tipado explícito:\nfunction sumar(a: number, b: number): number {\n    return a + b;\n}\nconsole.log(sumar(5, 3)); // Salida: 8\n\n\n//*Función con parámetros opcionales:\nfunction saludar(nombre: string, saludo?: string): string {\n    return saludo ? `${saludo}, ${nombre}!` : `Hola, ${nombre}!`;\n}\nconsole.log(saludar(\"Juan\")); // Salida: Hola, Juan!\nconsole.log(saludar(\"Ana\", \"Bienvenida\")); // Salida: Bienvenida, Ana!\n\n\n//*Función con parámetros por defecto:\nfunction crearMensaje(mensaje: string, autor: string = \"Anónimo\"): string {\n    return `${mensaje} - ${autor}`;\n}\nconsole.log(crearMensaje(\"Hola mundo\")); // Salida: Hola mundo - Anónimo\nconsole.log(crearMensaje(\"Saludos\", \"Carlos\")); // Salida: Saludos - Carlos\n\n\n//*Función con tipo de retorno void:\nfunction logMensaje(mensaje: string): void {\n    console.log(mensaje);\n}\nlogMensaje(\"Este es un mensaje de prueba\"); // Salida: Este es un mensaje de prueba\n\n\n//*Función con unión de tipos:\nfunction procesarValor(valor: string | number): string {\n    return typeof valor === \"string\" ? valor.toUpperCase() : `Número: ${valor}`;\n}\nconsole.log(procesarValor(\"texto\")); // Salida: TEXTO\nconsole.log(procesarValor(42)); // Salida: Número: 42\n\n\n//*Función con interfaz como parámetro:\ninterface Usuario {\n    nombre: string;\n    edad: number;\n}\n\nfunction mostrarUsuario(usuario: Usuario): string {\n    return `${usuario.nombre} tiene ${usuario.edad} años`;\n}\nconsole.log(mostrarUsuario({ nombre: \"María\", edad: 25 })); // Salida: María tiene 25 años\n\n\n//*Función flecha (Arrow Function):\nconst multiplicar = (a: number, b: number): number => a * b;\nconsole.log(multiplicar(4, 5)); // Salida: 20\n\n\n//*Función con promesas (asíncrona):\nasync function obtenerDatos(): Promise<string> {\n    return new Promise((resolve) => {\n        setTimeout(() => resolve(\"Datos obtenidos\"), 1000);\n    });\n}\nobtenerDatos().then((resultado) => console.log(resultado)); // Salida: Datos obtenidos (tras 1 segundo)\n\n\n//*Función con genéricos:\nfunction obtenerPrimerElemento<T>(arreglo: T[]): T {\n    return arreglo[0];\n}\nconsole.log(obtenerPrimerElemento([1, 2, 3])); // Salida: 1\nconsole.log(obtenerPrimerElemento([\"a\", \"b\", \"c\"])); // Salida: a\n\n\n//*Función con sobrecarga (Function Overloading):\nfunction combinar(a: string, b: string): string;\nfunction combinar(a: number, b: number): number;\nfunction combinar(a: any, b: any): any {\n    return a + b;\n}\nconsole.log(combinar(10, 20)); // Salida: 30\nconsole.log(combinar(\"Hola \", \"mundo\")); // Salida: Hola mundo\n\n\n/*\n*-//! Pon a prueba el concepto de variable LOCAL y GLOBAL.\n*/\n\n//variable global\nlet variableGlobal: string = 'Hola, soy una variable global'\n\nfunction mostrarGlobal(): void {\n    console.log(variableGlobal);\n}\nmostrarGlobal();\nconsole.log(variableGlobal);\n\n\n//variable local\nfunction mostrarLocal(): void {\n    let variableLocal: string = 'Hola, soy una variable local'\n    console.log(variableLocal);\n}\n\nmostrarLocal(); // imprime 'Hola, soy una variable local'\nconsole.log(variableLocal); //presenta error\n\n\n/*\n *- Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n*/\n\nfunction dificultadExtra(param1: string, param2: string): number {\n    let i: number = 1\n    let x: number = 0\n    while (i <= 100) {\n        if (i % 3 === 0 && i % 5 === 0) {\n            console.log(param1, 'y ' + param2)\n            x++;\n        }\n        if (i % 3 === 0) {\n            console.log(param1)\n            x++;\n        }\n        else if (i % 5 === 0) {\n            console.log(param2)\n            x++;\n        }\n        i++;\n    }\n    return x //53\n}\n\nconst mostrarDE = dificultadExtra('es multiplo de 3', 'es multiplo de 5')\nconsole.log(mostrarDE)"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/typescript/Danilo0203.ts",
    "content": "// FUNCIONES BASICAS DE TYPESCRIPT\n\n/* function name(parameter: typeof, parameter: type, ...): returnType{\n  do something\n} */\n\n// 📌 Funcion Basica sin parametros y sin retorno\nfunction saludar(): void {\n  console.log(\"Hola mundo\");\n}\nsaludar();\n\n// 📌 Funcion Basica con parametros y retorno\nfunction suma(a: number, b: number): number {\n  return a + b;\n}\nconsole.log(suma(3, 2));\n\n// 📌 Funciones dentro de funciones 'CallBacks'\n\nfunction telefono(llamadas: Function): string {\n  llamadas();\n  return `Telefono ocupado`;\n}\n\nfunction llamada1() {\n  console.log(\"Estoy en una llamada\");\n  console.log(\"Llamada 1 finalizada\");\n  telefono(llamada2);\n}\n\nfunction llamada2() {\n  console.log(\"Realizando llamada 2\");\n}\ntelefono(llamada1);\n\n// 📌 Funciones ya creadas por el Lenguaje\n\n// setTimeOut\nsetTimeout(() => {\n  console.log(\"Esto es una funcion ya creada por el lengguaje\");\n  console.log(\"Se ejecuto despues de 3 segundos...\");\n}, 3000);\n\n// setInterval\nlet i = 0;\nlet interval = setInterval(() => {\n  console.log(++i);\n}, 1000);\n\nsetTimeout(() => {\n  clearInterval(interval);\n}, 5000);\n\n// Variable Local y globlal\nlet variableGloblal: string = \"Variable Globlal\"; // Esta disponible en todo el codigo\nfunction scopeLocal() {\n  let variableLocal = \"Variable Local\"; // Solamente esta disponible en este bloque de codigo {}\n  variableGloblal = \"Actualizacion de la Variable Global\";\n  console.log(variableGloblal);\n  console.log(variableLocal);\n}\n// variaableLocal = \"Actualizacion de la varibale Local\"; //Error: No encuentra la variable\nconsole.log(variableGloblal);\nscopeLocal();\n\n/* DIFICULTAD EXTRA (opcional):\n Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n   - La función retorna el número de veces que se ha impreso el número en lugar de los textos */\nlet count: number = 1;\nlet multiploNum = (cadena1: string, cadena2: string): number => {\n  let contadorNumeros: number[] = [];\n  while (count <= 100) {\n    if (count % 3 === 0 && count % 5 === 0) {\n      console.log(cadena1 + cadena2, count);\n    } else if (count % 3 === 0) {\n      console.log(cadena1, count);\n    } else if (count % 5 === 0) {\n      console.log(cadena2, count);\n    } else {\n      contadorNumeros.push(count);\n    }\n    count++;\n  }\n  return contadorNumeros.length;\n};\nconsole.log(multiploNum(\"Hola\", \"mundo\"));\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/typescript/Guillemduno.ts",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n// Función sin parámetros ni retorno.\nfunction imprimeMensaje(): void {\n    console.log(\"Mensaje\");\n  }\n  \n  imprimeMensaje();\n  \n  // Función con um parámetro que no retorna nada.\n  function imprimeEsteMensaje(mensaje: string): void {\n    console.log(mensaje);\n  }\n  \n  imprimeEsteMensaje(\"Hola mundo!\");\n  \n  //Función con más de un parámetro de entrada. Devuelve un número como resultatdo.\n  function sumaDosNumeros(num1: number, num2: number): number {\n    return num1 + num2;\n  }\n  let resultado = sumaDosNumeros(2, 4);\n  console.log(resultado);\n  \n  // Función dentro de otra función\n  function imprimeMensajeConFuncion(): void {\n    imprimeEsteMensaje(\"Función dentro de otra función.\");\n  }\n  imprimeMensajeConFuncion();\n  \n  /**\n   * FUNCIONES CREADAS POR EL LENGUAJE:\n   */\n  \n  // Números\n  const numeroRedondeado = Math.round(2.3);\n  console.log(\"Número redondeado: \" + numeroRedondeado);\n  \n  let numeroCadena = 3; // Tipo number\n  console.log(\"Número cadena: \" + numeroCadena.toString() + \" tipo: \" + typeof numeroCadena.toString());\n  \n  const miNumero = 2.0;\n  console.log(miNumero.toExponential());\n  \n  // Cadenas\n  let miNombre = \"guillem\";\n  console.log(miNombre.toUpperCase()); // GUILLEM\n  \n  const numeroLetras = miNombre.length;\n  console.log(`El número de letras de la palabar ${miNombre} es de ${numeroLetras}`);\n  \n  // Fechas\n  const fecha = Date();\n  console.log(\"Fecha: \" + fecha);\n  \n  // Arrays\n  \n  const misCoches = [\"Opel\", \"Ford\"];\n  const susCoches = [\"Renault\", \"Seat\"];\n  console.log(misCoches.concat(susCoches)); // Concatena los dos array en uno.\n  \n  const misNotas = [2, 4, 6];\n  const misNotasMas1 = misNotas.map((x) => x + 1); // Suma uno a cada numero del array.\n  console.log(misNotasMas1);\n  \n  /**\n   * Variable LOCAL i GLOBAL\n   *  */\n  \n  // Si se declara la variable num fuera de la funcion esta será global y la\n  // función tendrá accesso a ella.\n  let num = 10; //variable global\n  \n  function muestraNumero() {\n    console.log(\"dentro muestra número: \" + num);\n  }\n  muestraNumero();\n  \n  // Si se declar la variable dentro de la función, solo sera accesible dentro de\n  // la función.\n  function muestraOtroNumero() {\n    let otroNum = 10;\n    console.log(\"desde muestra otro número: \" + otroNum);\n  }\n  \n  muestraOtroNumero();\n  \n  //console.log(otroNum); // Muestra error porque detecta que esta variable no esta definida.\n  \n  console.log(num);\n  \n  /**\n   * EJERCICIO EXTRA\n   */\n  \n  function imprimeMultiplos(str1: string, str2: string) {\n    let count: number = 0;\n    for (let index = 1; index <= 100; index++) {\n      let esMultiplo3 = index % 3 === 0;\n      let esMultiplo5 = index % 5 === 0;\n  \n      if (esMultiplo3 && esMultiplo5) {\n        console.log(index + \" \" + str1 + \" y \" + str2);\n      } else if (esMultiplo3) {\n        console.log(index + \" \" + str1);\n      } else if (esMultiplo5) {\n        console.log(index + \" \" + str2);\n      } else {\n        console.log(index);\n        count++;\n      }\n    }\n    console.log(\"veces que se ha impreso el número: \" + count);\n  }\n  \n  imprimeMultiplos(\"multiplo de 3\", \"multiplo de 5\");\n  "
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/typescript/IgleDev.ts",
    "content": "// 1º Tipo de Funciones\n    // Funciones con retorno\n    function minumero() : number{\n        return 5;\n    }\n    let num = minumero();\n    console.log(num);\n\n    function olamundo() : string{\n        return 'Ola Mundo';\n    }\n    let ola = olamundo();\n    console.log(ola);\n\n    // Tambien podemos hacerlas como una función flecha\n    const minombre : () => string = () => {\n        return 'IgleDev';\n    }\n    let nombre = minombre();\n    console.log(nombre);\n\n    //Funciones sin retorno\n    function sinretorno() : void{\n        console.log('No retorno nada');\n    }\n    console.log(sinretorno());\n\n    //Funciones con un parámetro\n    function getNumero(num : number) : number{\n        return num;\n    }\n    let num2 = getNumero(5);\n    console.log(num2);\n\n    //Funciones con varios parametros\n    function sumar(a : number, b : number) : number{\n        return a + b;\n    }\n    let suma = sumar(3,2);\n    console.log(suma);\n\n    //Funciones con parámetros pero que no sabemos cuantos\n    function concatenar(...args : string[]) : string{\n        return args.join(' ');\n    }\n    let frase = concatenar('Ola','Mundo','con', 'TypeScript');\n    console.log(frase);\n\n    // Funciones donde la pasamos un dato y devolvemos otro distinto\n    function dametuNumero(num : number) : string{\n        return 'Mi número es el: ' + num;\n    }\n    let tunumero = dametuNumero(5);\n    console.log(tunumero);\n\n    //Funciones que se utilizan para lanzar expeciones o errores\n    function error() : never{\n        throw new Error('Error');\n    }\n\n// 2º Función dentro de función\n    function factorialFunction(): (num: number) => number {\n        function calculateFactorial(num: number): number {\n            if (num <= 1) {\n                return 1; \n            } else {\n                return num * calculateFactorial(num - 1); \n            }\n        }\n\n        return calculateFactorial;\n    }\n\n    let factorial = factorialFunction();\n    console.log(factorial(5));\n\n// 3º Funciones del propio lenguaje\n    //Funciones de Identidad: Permite la creación genérica que puedan aceptar y devolver tipos específicos\n    function identidad<T>(dni: T): T {\n        return dni;\n    }\n\n    //Funciones de alta orden: Toman una o más funciones como argumentos o devuelven una función.\n    function altaOrden(callback: (x: number) => number): number {\n        return callback(10);\n    }\n\n// 4º LOCAL vs GLOBAL.\n    let global: string = \"Global\";\n\n    function variableLocal() : void{\n        let local: string = \"Local\";\n        console.log(\"Desde la función: \" + global);\n        console.log(\"Desde la función: \" + local);\n    }\n\n    variableLocal();\n\n    console.log(\"Fuera de la función:\", global);\n\n// 5º Ejercicio Extra\nfunction ejercicio(cadena1 : string, cadena2 : string) : number{\n    let cadenaxnumero = 0;\n    for(let i = 1; i <= 100; i++){\n        console.log(i);\n        if(i % 3 == 0 && i % 5 == 0){\n            cadenaxnumero++;\n            console.log(cadena1 + cadena2);\n            continue;\n        }else if(i % 5 == 0){\n            cadenaxnumero++;\n            console.log(cadena2);\n            continue;\n        }else if(i % 3 == 0){\n            cadenaxnumero++;\n            console.log(cadena1)\n            continue;\n        }\n    }\n    return cadenaxnumero;\n}\n\nlet numvecesrepetidas = ejercicio('ola','mundo');\nconsole.log('Nº Veces:' + numvecesrepetidas);"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/typescript/Jaimerocel96.ts",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n// Función sin parámetros ni retorno\nfunction holaMundo() : void {\n    console.log(`Hola mundo`);\n}\n\nholaMundo();\n\n// Función con varios parámetros y retorno\nfunction sumar(a: number, b: number): number {\n    return a + b;\n}\n\nconsole.log(`El resultado de sumar 2 y 4 es ${sumar(2, 4)}`);\n\n// Variable global\nlet global : string = 'Global';\n\n// Función flecha dentro de otra función y variable local\nfunction localGlobal(): void {\n    let local : string = \"Local\";\n    console.log(global);\n    console.log(local);\n    let funcion = () => {\n        console.log('Función dentro de otra');\n    }\n    funcion();\n};\n\nlocalGlobal();\n\n// Ejemplo función ya creada en el lenguaje\nlet notas : number[] = [10, 4, 5, 2, 6];\nconsole.log(notas.sort((a, b) => a - b));\n\n// Ejercicio extra\nfunction imprimeCadena(str1: string, str2: string){\n    let k: number = 0;\n    for(let i = 0; i < 100; i++){\n        if(i % 3 === 0 && i % 5 === 0){\n            console.log(`${str1+str2}`)\n        }else if(i % 3 === 0){\n            console.log(`${str1}`)\n        }else if(i % 3 === 0){\n            console.log(`${str2}`)\n        }else{\n            console.log(i)\n            k++;\n        }\n    }\n    console.log(`El número se ha impreso ${k} veces.`);\n}\n\nimprimeCadena(\"fizz\", \"buzz\");"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/typescript/RicJDev.ts",
    "content": "//EJERCICIO\nfunction doSomething() {\n\tconsole.log('Hola, soy una función sin retorno ni parámetros');\n}\n\ndoSomething();\n\nfunction greeting(name: string) {\n\tconsole.log(\n\t\t`Hola, ${name}. Soy una función que admite un parámetro pero no retorno ningún valor`\n\t);\n}\n\ngreeting('George');\n\nfunction addTwoNumbers(a: number, b: number) {\n\tconsole.log(a + b);\n}\n\naddTwoNumbers(10, 20);\n\nfunction returnAMessage(message: string) {\n\treturn message;\n}\n\nlet message = returnAMessage('Soy una función que retorna un valor');\nconsole.log(message);\n\nfunction getTotal(...arg: number[]) {\n\tlet result: number = 0;\n\n\tfor (let i = 0; i < arg.length; i++) {\n\t\tresult = result + arg[i];\n\t}\n\n\treturn result;\n}\n\nlet total = getTotal(12, 23, 4, 10);\nconsole.log(total);\n\nfunction returnSomeValues() {\n\treturn [12, 20, 40];\n}\n\nlet [a, b, c] = returnSomeValues();\nconsole.log(a);\nconsole.log(b);\nconsole.log(c);\n\nfunction operate(a: number) {\n\tfunction divide() {\n\t\treturn a / 2;\n\t}\n\n\tfunction multiply() {\n\t\treturn a * 2;\n\t}\n\n\tconst double = multiply();\n\tconst half = divide();\n\n\tconsole.log(`El doble de ${a} es ${double}, mientras que la mitad es ${half}`);\n}\n\noperate(10);\n\nconst anonymus = function () {\n\tconsole.log('Soy una función anónima');\n};\n\nanonymus();\n\nconst arrowFun = () => {\n\tconsole.log('Soy una función flecha');\n};\n\narrowFun();\n\nlet scopeVariable =\n\t'Soy una variable con alcance global. Cualquier parte de este código puede acceder a mí';\nconsole.log(scopeVariable);\n\n{\n\tlet blockScopeVariable =\n\t\t'Soy una variable con alcance local. Solo soy accesible dentro de este bloque de código';\n\n\tconsole.log(blockScopeVariable);\n}\n\n//console.log(blockScopeVariable) daría error fuera del bloque de código\n\n{\n\tvar globalScope =\n\t\t'Soy una variable con alcance global. Cualquier parte de este código puede acceder a mí';\n}\n\nconsole.log(globalScope);\n\n//EXTRA\nfunction fizzBuzz(a: string = 'Fizz', b: string = 'Buzz') {\n\tfor (let i = 1; i <= 100; i++) {\n\t\tif (i % 3 === 0 && i % 5 === 0) {\n\t\t\tconsole.log(a + ' ' + b);\n\t\t} else if (i % 3 === 0) {\n\t\t\tconsole.log(a);\n\t\t} else if (i % 5 == 0) {\n\t\t\tconsole.log(b);\n\t\t} else {\n\t\t\tconsole.log(i);\n\t\t}\n\t}\n}\n\nfizzBuzz('papa', 'frita');\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/typescript/RobertoAmaroHub.ts",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...*/\nfunction sinParametros(){\n    console.log(\"prueba de función sin parametros\");\n}\n\nfunction conParametro(texto: string){\n    console.log(`prueba de función con parametro: ${texto}`)\n}\n\nfunction conParametros(texto1: string, texto2: string){\n    console.log(`prueba de función con parametros: ${texto1} y ${texto2}`)\n}\n\nfunction conRetorno(): string{\n    return \"prueba de función con retorno\";\n}\n\nfunction conRetornoParametrosOpcionales(valor1:number, valor2?:number): string{\n    let res: string;\n    if(valor2){\n        let suma= valor1+valor2;\n        res=`la suma de ambos valores es: ${suma}`;\n    } else {\n        res=`el único parámetro ingresado es: ${valor1}`;\n    }\n    return res;\n}\n\nfunction conParametrosPorDefecto(valor1: number, valor2: number=4){\n    let suma:number=valor1+valor2;\n    console.log(`la suma de ${valor1} mas ${valor2} es: ${suma}`)\n}\n\n//Otra característica de TypeScript es la posibilidad de pasar una lista indefinida de valores y que los reciba un vector.\n//El concepto de parámetro Rest se logra antecediendo tres puntos al nombre del parámetro:\nfunction conParametroRest(...valores:number[]){\n    let suma:number=0;\n    for(let i of valores){\n        suma+=i;\n    }\n    console.log(`la suma de todos los parametros es: ${suma}`)\n}\n\nsinParametros();\nconParametro(\"parámetro\");\nconParametros(\"var1\", \"var2\");\nconsole.log(conRetorno());\nconsole.log(conRetornoParametrosOpcionales(3));\nconsole.log(conRetornoParametrosOpcionales(3,5));\nconParametrosPorDefecto(7);\nconParametroRest(3,4,5);\n/**El operador Spread permite descomponer una estructura de datos en elementos individuales. \nEs la operación inversa de los parámetros Rest. La sintaxis se aplica anteponiendo al nombre de la variable tres puntos:*/\nfunction sumar(valor1:number, valor2:number, valor3:number):number {\n    return valor1+valor2+valor3;\n  }\n  \n  const vec=[10,20,30] as const;\n  console.log(`la suma de los datos es: ${sumar(...vec)}`);\n\n/*\n * - Comprueba si puedes crear funciones dentro de funciones.*/\nfunction funcionPrincipal(){\n    console.log(\"llamado de la primera función\")\n    function funcionAnidada(){\n        console.log(\"llamado a la función anidada\")\n    }\n    funcionAnidada();\n}\nfuncionPrincipal();\n\n\n/*\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.*/\nfunction contarLetrasEnFrase(frase: string){\n    console.log(`la frase \"${frase}\" contiene ${frase.length} caracteres incluyendo espacios`);\n}\ncontarLetrasEnFrase(\"Probando funciones ya creadas en typescript\");\n\n/*\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.*/\nlet varGlobal:boolean=true;\nfunction testVarGlobal(){\n    let varLocal:boolean=false;\n    if(varGlobal && varLocal){\n        console.log(\"puedo usar la variable global y la local dentro del método\")\n    }\n}\nconsole.log(`puedo acceder a la variable global con el valor ${varGlobal} pero es imposible acceder al la variable local (dentro del método)`)\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\nfunction returnNumber(texto1: string, texto2: string):number{\n    let count:number=0;\n    for(let i=0; i<100; i++){\n        if(i%3==0 && i%5==0){\n            console.log(`los dos parámetros son ${texto1} y ${texto2}`);\n        } else if(i%3==0){\n            console.log(`primer parámetro: ${texto1}`);\n        } else if (i%5==0){\n            console.log(`segundo parámetro: ${texto2}`);\n        } else {\n            console.log(i);\n            count++;\n        }\n    }\n   return count;\n}\n\nconsole.log(\"El número total de números mostrados es: \"+returnNumber(\"valor1\",\"valor2\"));"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/typescript/Sac-Corts.ts",
    "content": "// Function with no parameters and no return\nfunction greet(): void {\n    console.log(\"Hello, welcome to TypeScript!\");\n}\n\n// Function with one parameter and no return\nfunction greetUser(name: string): void {\n    console.log(`Hello, ${name}!`);\n}\n\n// Function with multiple parameters and no return\nfunction addNumbers(a: number, b: number): void {\n    console.log(`The sum of ${a} and ${b} is ${a + b}`);\n}\n\n// Function with one parameter and a return value\nfunction square(num: number): number {\n    return num * num;\n}\n\n// Function with multiple parameters and a return value\nfunction multiplyNumbers(a: number, b: number): number {\n    return a * b;\n}\n\n// Nested Functions \nfunction outerFunction(): void {\n    console.log(\"This is the outer function\");\n\n    // Inner function\n    function innerFunction(): void {\n        console.log(\"This is the inner function\");\n    }\n\n    innerFunction();\n}\n\n// Built-in Functions\nfunction calculateCircleArea(radius: number): number {\n    return Math.PI * Math.pow(radius, 2);\n} \n\n// Testing local and global variables\n// Global variable\nlet globalVar = \"I'm a global variable\";\n\nfunction testVariableScope(): void {\n    // Local variable\n    let localVar = \"I'm a local variable\";\n\n    console.log(globalVar);\n    console.log(localVar);\n\n    globalVar = \"Global variable modified inside the function\";\n}\n\ngreet(); // Function without parameters and no return\ngreetUser(\"Isaac\"); // Function with one parameter and no return\naddNumbers(5, 7); // Function with multiple parameters and no return\nconsole.log(`Square of 4 is: ${square(4)}`); // Function with one parameter and return value\nconsole.log(`Multiplication of 3 and 6 is: ${multiplyNumbers(3, 6)}`); // Function with multiple parameters and return value\n\nouterFunction(); // Calls outer and inner function\n\nconsole.log(`Area of circle with radius 5 is: ${calculateCircleArea(5)}`); // Uses Math functions\n\ntestVariableScope();\nconsole.log(globalVar);\n// console.log(localVar); Error: localVar is not defined outside the function\n\n\n// *** Extra Exercise *** //\nfunction printNumbersWithText(string1: string, string2: string): number  {\n    let counter = 0;\n\n    for (let i = 1; i <= 100; i++) {\n        if (i % 3 === 0 && i % 5 === 0) {\n            console.log(string1 + string2);\n        } else if (i % 3 === 0) {\n            console.log(string1);\n        } else if (i % 5 === 0) {\n            console.log(string2);\n        } else {\n            console.log(i);\n            counter++;\n        }\n    }\n    return counter;\n}\n\nconst times = printNumbersWithText(\"Fizz\", \"Buzz\");\nconsole.log(`The number was printed ${times} times`);\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/typescript/Sharah07.ts",
    "content": "// *** TIPOS DE FUNCIONES Y SUS VARIACIONES/POSIBILIDADES:\n\n// *** FUNCIÓN NORMAL (DECLARACIÓN ESTÁNDAR)\n/**\n * Función sin parámetros ni retorno: no reciben argumentos ni veduelven un valor. \n * Realizan solo el çodigo dentro de su bloque.\n */\nfunction mensaje(): void{\n    console.log('Función sin parámetros ni retorno'); \n}\n\nmensaje(); //Función sin parámetros ni retorno\n/**\n * Sin parámetros, pero con retorno: no usan parámetros, \n * pero sí retornan un resultado al llamarlas.\n */\nfunction mostrarFecha() {\n    return console.log(new Date()); //2025-03-13T15:45:43.284Z\n}\n\nmostrarFecha();\n/**\n * Con un parámetro y sin retorno: toman solo un parámetro y no devuelven un resultado.\n */\nfunction mostrarNombre(nombre:string){\n    console.log('Hola ', nombre);\n}\n\nmostrarNombre('Seira'); //Hola  Seira\n\n/**\n * Con uno o varios parámetros y con retorno: recibe uno o varios parámetros \n * y devuelve un resultado.\n */\nfunction areaCuadrado(a:number):number{\n    return a*a;\n}\n\nfunction areaRectangulo(a:number, b:number):number{\n    return a*b;\n}\n\nareaCuadrado(4); //Salida: 16\nareaRectangulo(3,6); //Salida: 18\n\n/**\n * Parámetros opcionales.\n */\nfunction saludoConOpcional(nombre?: string) {\n    if (nombre) {\n        return console.log('Hola, ', nombre, '!');\n    }\n    else {\n        return console.log('Hola!');\n    }\n}\n\nsaludoConOpcional('Sharah'); //Hola,  Sharah !\nsaludoConOpcional(); //Hola!\n\n/**\n * Con valores predeterminados: los parámetros tienen valores predeterminados que la\n * función usa si no se le pasan argumentos.\n */\n\nfunction bienvenido(nombre:string = 'Usuario/a'){\n    return console.log('Bienvenido/a, ', nombre, '!');\n}\n\nbienvenido(); //Bienvenido/a,  Usuario/a !\nbienvenido('Sharah'); //Bienvenido/a,  Sharah !\n\n// *** FUNCIONES ANÓNIMAS.\n/** Es una función sin nombre que se asigna a una variable o constante, suele crearse al momento en situaciones\n * donde no requiere ser reutilizada.\n * También sirve como callback (argumento en otra función).\n */\nvar operacion = function (a, b) {   //función anónima\n    return a * b;\n};\nfunction areaTriangulo(a=2) {\n    var area = operacion(8, 6) / a;\n    return console.log(area);\n}\n\nareaTriangulo(); //24\n\n// *** FUNCIONES FLECHA (ARROW FUNCTION).\n/**Hacen el código más compacto y fácil de leer,\n * especialmente en funciones pequeñas.\n */\nconst division = (a:number, b:number):number =>{\n    return a/b;\n}\nconsole.log(division(8,2)); // 4\n\nconst suma = (a:number, b:number):number => a + b;\nconsole.log(suma(4,2)); // 6\n\n// *** FUNCIONES GENÉRICAS.\n/**Permiten trabajar con distintos tipos de datos manteniendo la seguridad de tipos,\n * son útiles cuando no sabemos con que tipos de datos trabajará la función \n * y ahorran espacio al no tener que definir diferentes funciones para diferentes tipos de datos. \n */\nfunction valor<T>(a:T):T{\n    return a;\n}\n \nconsole.log(valor('Sharah')); //Sharah \nconsole.log(valor(27)); //27\n\nfunction combinar<T,U>(a: T, b: U): [T,U]{\n    return [a, b];\n}\nconsole.log(combinar('Seira', 21)); //[ 'Seira', 21 ]\n\n// ***FUNCIONES COMO TIPOS PERSONALIZADOS.\n/**Permiten definir la estructura de una función (parámetros y valor de retorno) como un tipo independiente.\n * Sirve cuando tenemos varias funciones con la misma estructura, lo que evita tener que definirla cada vez.\n*/\n\n// Type Alias\ntype operacion = (a:number, b:number) => number;\n\nconst multiplicaion: operacion = (a, b) => a*b;\nconst dividir:operacion = (a, b) => a/b;\n\nconsole.log(multiplicaion(6,2)); // 12\nconsole.log(dividir(6,2)); // 3\n\n// Interface\ninterface operacion2 {\n    (a:number, b:number): number;\n}\n\nconst suma2: operacion2 = (a, b) => a+b;\nconst resta: operacion2 = (a, b) => a-b;\n\nconsole.log(suma2(4,8)); //12\nconsole.log(resta(4,8)); //-4\n\n// *** FUNCIÓN DENTRO DE FUNCIÓN (FUNCIONES ANIDADAS).\n/**\n * Son funciones que se definen dentro del cuerpo de otra función.\n * Sirven para encapsular código, reducir su uso donde realmente es necesario \n * y reducir repetición de código. \n * */  \n\nfunction areaDeCuadrado(a) {\n    function multiplicar() {\n        return a * a;\n    }\n    return multiplicar();\n}\nconsole.log(areaDeCuadrado(3)); //9\n\n// *** EJEMPLO DE FUNCIÓN DEL LENGUAJE.\n\nconst persona2 = {nomber: 'Seira', edad: 20};      \n\nconsole.log(Object.keys(persona2)); //[ 'nomber', 'edad' ]\nconsole.log(Object.values(persona2)); //[ 'Seira', 20 ]\nconsole.log(Object.entries(persona2)); //[ [ 'nomber', 'Seira' ], [ 'edad', 20 ] ]             \n\n// *** VARIABLE LOCAL Y GLOBAL.\n/**\n * Variable Global: Esta variable se declara fuera de cualquier función, bloque o clase, \n * por lo que se puede acceder a ella desde cualquier parte del código, mientras no haya ninguna restrincción. \n * \n * Variable Local: Se defini dentro de una función, bloque o clase \n * y su uso se limita al ámbito en el que fue definida.\n */\nlet variableGlobal = 'Esta es una variable global.';\nfunction mostrar(){\n    let variableLocal='Esta es una variable local.';\n    console.log(variableGlobal); //'Esta es una variable global.'\n    console.log(variableLocal); //'Esta es una variable local.'\n}\nconsole.log(variableGlobal); //'Esta es una variable global.'\n\n\n// *** DIFICULTAD EXTRA.\n\nfunction numeros(m3:string, m5:string){\n    m3 = 'múltiplo de 3';\n    m5 = 'múltiplo de 5';\n    let contadorExterno=0;\n    for(let i=1; i <= 100; i++){\n        if(i%3 == 0 && i%5 == 0){\n            console.log(m3, 'y ', m5);\n        }else if(i%3 == 0){\n            console.log(m3);\n        }else if(i%5 == 0){\n            console.log(m5);\n        }else{\n            console.log(i);\n        }\n        contadorExterno++;\n    }\n    return console.log('retorno: ',contadorExterno);\n}\n\nnumeros();"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/typescript/XhuaSpy.ts",
    "content": "function mostrarHola() : void {\n    console.log(\"Hola como estas\");\n}\n\nfunction greet ( name : string) : void {\n    console.log(`Hello ${name}!`);\n} \n\nfunction operacion_logica (P : boolean, Q : boolean) : boolean {\n    function operacion_logica_2(P : boolean, Q : boolean) : boolean{\n        return P && Q && (!P || Q);\n    }\n\n    return ! operacion_logica_2(P, Q);\n}\n\nlet uno_1 = 1;\nvar dos_2 = 2;\n\nfunction numerica_global() {\n    console.log(uno_1 ?? \"Perro hp\");\n    console.log(dos_2);\n    let perro = \"hp\";\n}\n\nmostrarHola();\ngreet(\"Jesús\");\nconsole.log(operacion_logica(true, false));\ngreet(\"Putas karens\".toUpperCase());\nnumerica_global();\n// console.log(perro); da un error porquela variable no fue definida dentro del espacio.\n\nfunction ejercicio_funciones_extra_dificultad(cadena_1 : string, cadena_2: string) : number {\n    let acumulador : number = 0;\n    for (let i = 1; i <= 100; i++) {\n        console.log(acumulador++);\n        if ((i % 5 == 0) && (i % 3 == 0)) {\n            console.log(cadena_1, cadena_2);\n        } else if ((i % 3 == 0)) {\n            console.log(cadena_1);\n        } else if ((i % 5 == 0)) {\n            console.log(cadena_2);\n        }\n    }\n\n    return acumulador;\n}\n\nconsole.log(ejercicio_funciones_extra_dificultad(\"Jesus\", \"Peraza\"))\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/typescript/arnodchirivi08.ts",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n// Función sin parámetros ni retorno\nfunction saludar(): void {\n    console.log(\"¡Hola, mundo!\");\n}\n\nsaludar(); \n\n// Función con un parámetro y sin retorno\nfunction saludarPersona(nombre:string):void {\n    console.log(`¡Hola, ${nombre}!`);\n}\n\nsaludarPersona(\"Luis\");\n\n// Función con varios parámetros y con retorno\nfunction sumar(a:number, b:number):number {\n    return a + b;\n}\n\nconsole.log(`El valor de la suma es ${sumar(5, 3)}`);\n\n// Función de orden superior (función dentro de función)\nfunction greeter(fn: (name:string) => void){\n  fn(\"hello, world\");\n}\n\nfunction printConsole(s:string){\n  console.log(s);\n}\n\ngreeter(printConsole)\n\n\ntype operarNumeros = (n:number) => number;\n\nconst numerosDePrueba = [25,30,45,20]\n\nfunction operandoNumeros(numeros: number[], operacion: operarNumeros){\n  let valorFinal: number[] = [];\n  for(let numero of numeros){\n    const nuevoValor = operacion(numero)\n    valorFinal.push(nuevoValor)\n  }\n\n  return valorFinal;\n}\n\nfunction duplicar(numero: number){\n  return numero * 2\n}\n\n\nconsole.log(operandoNumeros(numerosDePrueba, duplicar));\nconsole.log(operandoNumeros(numerosDePrueba, (n) => n /2));\n\n// Call signatures \ntype DescribableFunction = {\n  description: string;\n  (someArg: number): boolean;\n}\n\nfunction doSomething(fn:DescribableFunction){\n  console.log(`${fn.description} returned ${fn(22)}`);\n}\n\nfunction myFunc(someArg: number) {\n  return someArg > 10;\n}\n\nmyFunc.description = \"Default description\"\n\ndoSomething(myFunc);\n\n// Construct Signatures\n\ninterface CallOrConstruct {\n  (n?: number): string;\n  new (s: string): Date;\n}\n\nfunction fn(ctor: CallOrConstruct) {\n  console.log(ctor(10));\n  console.log(new ctor(\"10\"));\n\n}\n\nfn(Date);\n\n// Generic Functions\n/*Las funciones genéricas son una de las características más potentes de TypeScript. En pocas palabras, son funciones que pueden trabajar con diferentes tipos de datos \nsin perder la seguridad de tipos. Actúan como plantillas o moldes que se adaptan al tipo de dato que les pases. */\n// A continuación se muestra un ejemplo de función genérica que devuelve el primer elemento de un array y aplica inferencia de tipos que \n// es la capacidad de TypeScript para deducir automáticamente el tipo de una variable o expresión en función del contexto en el que se utiliza.\nfunction firstElement<T>(arr: T[]): T | undefined {\n  return arr[0];\n}\n\nconsole.log(firstElement([\"a\",\"b\",\"c\"]));\nconsole.log(firstElement([1,2,3]));\nconsole.log(firstElement([]))\n\n\n/* Funcion generica con restricciones (Constraints)\nPermiten limitar los tipos que se pueden usar en una variable generia. A veces se necesita que se tengan ciertas propiedades o metodos. \nPara esto se usa extends. */\ninterface ConLongitud {\n  length: number,\n}\n\nfunction imprimirLongitud<T extends ConLongitud>(arg:T): void {\n  console.log(`La longitud es: `, arg.length)\n}\n\nimprimirLongitud(\"Hola\")\nimprimirLongitud([1,2,3,4,5]);\n//imprimirLongitud(122) //Genera error por trabajar con Valores Restringidos (Working with Constrained Values), debido a que number no tiene la propiedad length \n\n\n//Especificar Argumentos de Tipo (Specifying Type Arguments)\n//Es cuando le das a TypeScript \"instrucciones directas\" sobre el tipo a usar.\n\nfunction crearArray<T>(): T[]{\n  return [];\n}\n\nconst arrayNumeros = crearArray<number>();\nconst arrayDeStrings = crearArray<string>();\n\narrayNumeros.push(123);\n//arrayNumeros.push(true); genera error por que se especifico que es un array de numeros\nconsole.log(arrayNumeros);\n\n// Parametros opcionales en funciones\nfunction saludarConOpcional(nombre: string, apellido?: string): void {\n    console.log(`Hola, ${nombre} ${apellido ? apellido : ''}`.trim());\n}\n\nsaludarConOpcional(\"Carlos\");\nsaludarConOpcional(\"Carlos\", \"Gomez\");  \nsaludarConOpcional(\"Carlos\", undefined);\n\n\n// Sobrecarga de funciones (function overloads)\n\nfunction procesar(texto:string): string;\nfunction procesar(textos: string[]):string;\nfunction procesar(parametro: string | string[]): string {\n  if(typeof parametro === 'string'){\n    return parametro.toUpperCase();\n  }\n  else {\n    return parametro.join(' ');\n  }\n}\n\nconsole.log(procesar('buenas tardes!'));\nconsole.log(procesar(['Hola,', 'Buenas', 'Noches']));\n\n//Otros tipos en TypedPropertyDescriptor\n\n//void\n//Se usa principalmente para indicar que una función no devuelve nada.\nfunction mostrarMensaje(mensaje: string): void {\n  console.log(mensaje);\n}\n\nmostrarMensaje('Maurodev')\n\n//object\n//Es útil cuando sabes que vas a recibir un objeto, pero no te importan sus propiedades específicas.\n\nfunction trabajarConObjeto(obj: object): void {\n  console.log('Se recibio un objeto' + JSON.stringify(obj));\n}\n\ntrabajarConObjeto({ id: 1, nombre: \"producto\" });\n\n\n//unknown \n//Representa un valor cuyo tipo desconocemos. \n//TypeScript no  permite hacer casi nada con un valor de tipo unknown hasta que primero verifiques su tipo\n\nfunction procesarValor(valor: unknown) {\n  if (typeof valor === 'string') {\n    console.log(valor.toUpperCase());\n  }\n}\n\nprocesarValor(\"hola\"); // Funciona\nprocesarValor(123) // No hace nada\n\n//never\n//representa un valor que nunca debería ocurrir. Se usa para funciones que nunca terminan su ejecución o que siempre lanzan una excepción.\n/*function lanzarError(mensaje: string): never {\n  throw new Error(mensaje);\n}\n\nlanzarError('Sucedio un error')*/\n\n//Function  es un tipo global que representa cualquier valor de tipo función. Generalmente, debes evitar usarlo\n// NO RECOMENDADO\nfunction llamarCallback(cb: Function) {\n  cb(1, \"hola\"); \n}\n\n// Recomendado\nfunction llamarCallbackSeguro(cb: (num: number, str: string) => void) {\n  cb(1, \"hola\");\n}\n\n\n//Parámetros Rest \nfunction sumarTodo(...numeros: number[]): number {\n  return numeros.reduce((total, num) => total + num, 0);\n}\n\nconsole.log(sumarTodo(5, 10, 15));\n\n/*DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.*/\n\nfunction imprimir(cadenaUno:string, cadenaDos:string): number {\n   var numeroDeVecesImpreso = 0;\n   for(let i = 1; i <=100; i++){\n    let stringFinal = '';\n    const esMultiploDeTres = i % 3 === 0;\n    const esMultiploDeCinco = i % 5 === 0;\n\n    if(esMultiploDeTres){\n      stringFinal += cadenaUno;\n    }\n    if(esMultiploDeCinco) {\n      stringFinal += stringFinal && ' ';\n      stringFinal += cadenaDos;\n    }     \n\n  \n    stringFinal || numeroDeVecesImpreso++;\n    console.log(stringFinal === '' ? i : stringFinal);\n   }\n   return numeroDeVecesImpreso;\n }\n\n console.log(imprimir('Buenas', 'Noches'))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/typescript/axelsparta.ts",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\nfunction firstFunction () {\n  console.log('first function')\n}\n\nconst firstFunctionResult = firstFunction() // ejecutamos la función con esta sintaxis, el resultado se guardará en la constante 'firstFunctionResult'\nconsole.log(firstFunctionResult) // 'undefined', si no se indica un return por defecto las funciones devuelven 'undefined'\n\nfunction functionWithParameters(firstParameter: number, secondParameter: number){\n  return firstParameter ** secondParameter\n}\n\nconst functionResult = functionWithParameters(10, 2)\nconsole.log(functionResult)\n\nconst arrowFunction = (num1: number, num2: number) => {\n  return num1 + num2\n}\n\nconst arrowFunctionResult = arrowFunction(10, 30)\nconsole.log(arrowFunctionResult)\n\nlet globalVariable = 'My global variable'\n\nconst myFunction = () => {\n  // función creada dentro del bloque de la función 'myFunction', solo se puede llamar dentro de la misma\n  const myLocalFunction = () => {\n    return 'My local function result'\n  }\n\n  const myLocalFunctionResult = myLocalFunction()\n  let localVariable = 'My local variable'\n  console.log(localVariable, globalVariable, myLocalFunctionResult) // si se puede acceder a la variable global y a las variables declaradas dentro del bloque de la función\n}\n\n// console.log(localVariable) -> error no se puede acceder a la variable creada dentro de la función 'myFunction'  \n\n// Ejercicio extra...\nconst exerciseFunction = (param1: string, param2: string): number => {\n  let countResult = 0\n  for(let i = 1; i <= 100; i++) {\n    if (i % 3 == 0 && i % 5 == 0) {\n      console.log(param1, param2)\n    } else if(i % 3 == 0) {\n      console.log(param1)\n    } else if(i % 5 == 0) {\n      console.log(param2)\n    } else {\n      console.log(i)\n      countResult++\n    }\n  }\n  return countResult\n}\n\nconst exerciseFunctionResult = exerciseFunction('fizz', 'buzz')\nconsole.log(exerciseFunctionResult)"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/typescript/cubandeveloper89.ts",
    "content": "//   ***   FUNCIONES    ***\n\n// funciones sin parámetros ni retorno\n\nfunction myFunct() {\n  console.log(\"myFunt es una función que no requiere parámetros\");\n}\n\nmyFunct(); //invoco la funcion\n\n// funciones con parámetros pero sin retorno\n\nfunction my2Funct(name: string) {\n  console.log(\n    \"Hola, \" + name + \", my2Funct si que requiere un parámetro, tu nombre\"\n  );\n}\n\nmy2Funct(\"John\");\n\n// Funciones flecha\n\nconst my3Funct = () => {\n  console.log(\n    \"my3Funct es una funcion flecha, simplemente otrra manera de denominar una funcion\"\n  );\n};\n\nmy3Funct();\n\n// Dos o mas parámetros en una funcion, el tercero es opcinal\n\nconst my4Funct = (a: number, b: number, c?: number) => {\n  let result = 0;\n  if (c) {\n    result = a + b + c;\n  } else {\n    result = a + b;\n  }\n\n  console.log(\"my4Funct toma 2 parametros y los suma: \" + result);\n};\n\nmy4Funct(10, 5, 7);\n\n// Función con return\n\nconst my5Funct = () => {\n  return \"my5Funct es una función con RETURN\";\n};\n\nconsole.log(my5Funct());\n\n// Función dentro de funciones\n\nconst my6Funct = () => {\n  function innerFunct() {\n    console.log(\"Esta función se ejecuta dentro de my6Funct\");\n  }\n  innerFunct();\n};\n\nmy6Funct();\n\n// Funciones propias del lenguaje\n\nconsole.log(\"1- El mismo console.log() es una funcion del lenguaje\");\n\nlet words: string =\n  \"2- We all can work together and make this world a better place\";\nconsole.log(words.toUpperCase());\n\n// Variable global y local\nconst global: string = \"global\";\nconst my7Funct = () => {\n  let local: string = \"local\";\n  return `la variable ${global} esta fuera del scope de la funcion mientras que ${local} solo existe aqui dentro`;\n};\n\nconsole.log(my7Funct());\n\n//  *** Ejercicio EXTRA ***\n\nconsole.log(\"     *** Ejercicio Extra ***\");\n\nconst extraFunct = (param1: string, param2: string) => {\n  let count: number = 0;\n  for (let index = 1; index <= 100; index++) {\n    if (index % 3 == 0 && index % 5 == 0) {\n      console.log(param1 + \" y \" + param2);\n      count++;\n      continue;\n    } else if (index % 3 == 0) {\n      console.log(param1);\n      count++;\n      continue;\n    } else if (index % 5 == 0) {\n      console.log(param2);\n      count++;\n      continue;\n    }\n    console.log(index);\n  }\n  console.log(\"Se cambio por letras \" + count + \" veces\");\n  return count;\n};\n\nextraFunct(\"hola\", \"adios\");\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/typescript/dannyvera1234.ts",
    "content": ""
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/typescript/david-git-dev.ts",
    "content": "/*\n DIFICULTAD EXTRA (opcional):\n Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n\n Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n*/\n //EJERCICIO:\n /* - Crea ejemplos de funciones básicas que representen las diferentes\n   posibilidades del lenguaje:\n   Sin parámetros ni retorno, con uno o varios parámetros, con retorno... */\n\n//funcion sin parametros\n function functionWithoutParamsAndReturns(){\n\n }\n//funcion con parametros\n function functionWithParams(name:string ='soy un parametro'){\n }\n//funcion con retorno\n function functionWithReturn(x:number){\n  x = 1;\nreturn x;\n }\n//funciones dentro de funciones\n function getIntegerRandom(min:number=1, max:number=5):number {\n//funciones ya definidas por el lenguaje -> random()\n  return Math.floor(Math.random() * (max - min + 1)) + min;\n}\n//funciones flecha\nconst functionWordUpperCase = (word:string='pronto sere grande') => word.toUpperCase();\n// - Pon a prueba el concepto de variable LOCAL y GLOBAL.\nconst enum GlobalVars {Global='estoy en todo!'};\nfunction testGlobalScope(){\nGlobalVars.Global // access to global\nfunction testToLocalScoope(){\n  let local = 'this is a local var!'\n}\nreturn{local:this.local,global:GlobalVars.Global}; //test fail dont exist local in this scoope\n}\nasync function getData(){//funciones asincronas\n const data = await fetch('https://dragonball-api.com/api/characters/1')\nreturn await data.json()\n}\nconst consoles:{[key:string]:any} = {\n'funciones vacias': functionWithoutParamsAndReturns,\n'funciones con parametros': functionWithParams,\n'funciones con retorno': functionWithReturn,\n'funciones dentro de funciones y ya definidas por el lenguaje': getIntegerRandom,\n'funciones flecha': functionWordUpperCase,\n'funcion de scoope global y local':testGlobalScope,\n'funcion asincrona':getData\n}\nfor (const result in consoles){\nconsole.log(consoles[result](),'->',result,'\\n')\n}\n// DIFICULTAD EXTRA (opcional):\n//  Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n(function twoParamStringToNumber(one:string='fizz',two:string='buzz'){\n\n  let start:number = 1;\n  let stop:number = 100;\n  let total:number = 0;\n//  - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n  while(start<=stop){\n    let response:string = '';\n//    - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n    if(start%3==0 && start%5==0)\n      response =one+two\n//    - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n    if(start%3==0 && !response)\n      response = one\n//    - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n    if(start%5==0 && !response)\n      response= two\n//    - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n    !response ? total++ : ''\n    console.log(!response? start:response,'\\n')\n    start++;\n  }\n  return total\n})()\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/typescript/duendeintemporal.ts",
    "content": "/* { retosparaprogramadores }  #2 FUNCIONES Y ALCANCE */\n// I use the book \"Eloquent JavaScript: A Modern Introduction to Programming\" by Marijn Haverbeke for concept reference.\n// I also use the book \"Secrets of the JavaScript Ninja\" by John Resig, Bear Bibeault, and Josip Maras.\n// I refer to \"JavaScript Notes for Professionals\" from the people of Stack Overflow. https://goalkicker.com/JavaScriptBook\n// Additionally, I use GPT as a reference and sometimes to correct or generate proper comments.\n//https://www.typescriptlang.org/docs/\n\n// Short for log\nconst log = console.log;\n\n\n/* FUNCTIONS */\n/* Functions are fundamental in TypeScript and JavaScript programming. They allow us to structure larger programs, reduce repetition, \n   associate names with subprograms, and isolate these subprograms from each other. \n   Functions can be used to calculate values, perform side effects, achieve code reuse, and enhance code readability. */\n\n// Functions as first-class objects\n/* Functions in TypeScript are treated as first-class objects, meaning they can be assigned to variables, \n   passed as arguments, and returned from other functions. */\n\n// Created via literals.\nfunction addPad(number: number, width: number, pad: number | string = 0): string {\n    let result = String(number);\n    while (result.length < width) {\n        result = `${pad}` + result;\n    }\n    return result;\n}\n\nlog(addPad(4, 3, '#')); // ##4\nlog(addPad(56, 3, '$')); // $56\nlog(addPad(7, 3)); // 007\n\n// Note: Default arguments can be passed as shown in the last example.\n\n// Assigned to variables, array entries, and properties of other objects\nconst square = (n: number): number => n * n;\n\nconst funcArray: number[] = [];\nfuncArray.push(square(8)); // Adds a new function to an array\nlog(funcArray); // [64]\n\nconst data: { book_name: string; some_method?: () => void } = { book_name: 'Hackbook' };\ndata.some_method = function () {\n    console.log(`${data.book_name} is now available in z-lib.org, so hack the world.`);\n}; // Assigns a new function as a property of another object\ndata.some_method(); // Hackbook is now available in z-lib.org, so hack the world.\n\n// A newly created object passed as an argument to a function\n\n// Passed as arguments to other functions (callbacks)\nfunction call(doSomething: () => void): void {\n    doSomething();\n}\n\ncall(() => log('Hi roadmap coders!')); // Hi roadmap coders!\n\n// Returned as values from functions\nfunction returnFunc(): (str: string) => void {\n    return function (str: string) { console.log(str); };\n}\n\nconst greeting = returnFunc();\ngreeting('Hi there!'); // Hi there!\n\n// Functions can possess properties that can be dynamically created and assigned like objects:\nconst callMom = function () { log('Mommmmm!'); };\n\ncallMom(); // Mommmmm!\ncallMom.name = \"Mom\";\nlog(callMom.name); // Logs: callMom because \"name\" is an inherited property of the function constructor and is not writable\n\ncallMom.something = 'something';\nlog(callMom.something); // something\n\nlog(callMom); /* Logs: \n[Function: callMom] { something: 'something' } */\n\n/* Functions are objects with the special capability of being invokable. */\n\n// Constructor functions are functions designed to construct a new object.\nfunction Cat(this: any, name: string, color: string, sound: string) {\n    this.name = name;\n    this.color = color;\n    this.sound = sound;\n}\n\n// Constructor functions are invoked using the new keyword:\nconst psicoCat = new Cat(\"Psicotrogato\", \"Black & White\", \"Meaw\");\nlog(psicoCat.color); // Black & White\npsicoCat.sound = \"Hey girl what's your name, what's your name?... I forgot\";\n\n// Constructor functions also have a prototype property which points to an object whose properties are automatically inherited by all objects created with that constructor:\nCat.prototype.speak = function () {\n    log(this.sound);\n};\n\npsicoCat.speak(); // \"Hey girl what's your name, what's your name?.. I forgot\"\n\n// Closure\n/* The ability to treat functions as values, combined with the fact that local bindings are recreated every time a function is called, \n   leads to interesting possibilities. */\n\nconst incrementer = (function (n: number) {\n    let local = n;\n    return () => local++;\n})(0); // Immediately invoked with an initial value of 0\n\nconsole.log('incrementer value is:', incrementer()); // incrementer value is: 0\nconsole.log('incrementer value is:', incrementer()); // incrementer value is: 1\nconsole.log('incrementer value is:', incrementer()); // incrementer value is: 2\n\n// In the previous example, we used an IIFE (Immediately Invoked Function Expression) to create a closure, \n// but we can achieve the same with regular functions.\nfunction square_v2(n: number): () => number {\n    return () => n * n;\n}\n\nconst pow64 = square_v2(64);\nconst pow78 = square_v2(78);\n\nlog(pow64()); // 4096\nlog(pow78()); // 6084\n\n// Arrow Functions\nconst factor = (n: number): number => {\n    if (n === 1) return 1;\n    return n * factor(n - 1);\n};\n\nlog(factor(8)); // 40320\n\n// Note: The factor function is recursive, meaning it calls itself.\n\n// Arrow functions allow us to abbreviate expressions when they have only one parameter or a single expression.\nconst square_v3 = (n: number): number => n * n;\nlog(square_v3(4)); // 16\n// Note: We omit the curly braces, the return statement, and also the parentheses.\n\n// Note 2: It's important to remember that arrow functions do not have their \n// The following code is commented to avoid conflicts in Node.js environments. \n// If you transpile it to JavaScript, it will run fine in a browser.\n//own 'this' context.\n// const obj = {\n//     value: 'Rutadeprogramacion Exercice #2.',\n//     advertisement: function () {\n//         log(this.value); // Rutadeprogramacion Exercice #2\n//         setTimeout(() => {\n//             alert(`${this.value} Please open the Browser Developer Tools.`);\n//         }, 1000);\n//     }\n// };\n\n//obj.advertisement(); // Alert: Rutadeprogramacion Exercice #2. Please open the Browser Developer Tools. and Logs in console: Rutadeprogramacion Exercice #2.\n\n/* Note: Because arrow functions don't have `this`, the 'this' points to obj. \n   If we had used a regular function instead of the arrow function inside the setTimeout, \n   it would have alerted undefined or thrown a reference error. */\n\n// Function Declarations: A function declaration defines a named function. It is hoisted, meaning it can be called before it is defined in the code.\nfunction subtract(n: number, m: number): number {\n    return n - m;\n}\n\nlog(subtract(8, 4)); // 4\n\n// Function Expressions: A function expression defines a function as part of a larger expression. \n// It can be anonymous or named and is not hoisted.\nconst multiply = function (n: number, m: number): number {\n    return n * m;\n};\n\nlog(multiply(8, 9)); // 72\n\nconst add = function add(a: number, b: number): number {\n    return a + b;\n}; // Can share the name for the binding word & the named function\n\nlog(add(3, 3)); // 6\n\n// Arrow Functions: Introduced in ES6, arrow functions provide a more concise syntax for writing functions. \nconst divide = (n: number, m: number): number => n / m;\n\nlog(divide(543, 56)); // 9.696428571428571\n\n// Anonymous Functions: These are functions that do not have a name. \n// They are often used in callbacks or as arguments to other functions.\n// The following code is commented to avoid conflicts in Node.js environments. \n// If you transpile it to JavaScript, it will run fine in a browser.\n// window.addEventListener('load', function () {\n//     const body = document.querySelector('body') as HTMLBodyElement;\n//     const title = document.createElement('h1');\n\n//     body.style.setProperty('background', '#000');\n//     body.style.setProperty('text-align', 'center');\n\n//     title.textContent = 'Retosparaprogramadores #2.';\n//     title.style.setProperty('font-size', '3.5vmax');\n//     title.style.setProperty('color', '#fff');\n//     title.style.setProperty('line-height', '100vh');\n\n//     body.appendChild(title);\n\n//     log('This is an anonymous function'); // This will be logged at the end due to the nature of the window event\n// });\n\nlet sayHi = function () {\n    console.log('Hi');\n};\n\nsayHi(); // Hi\n\n/* Named functions differ from anonymous functions in multiple scenarios:\n   - When debugging, the name of the function will appear in the error/stack trace.\n   - Named functions are hoisted while anonymous functions are not.\n   - Named functions and anonymous functions behave differently when handling recursion.\n   - Depending on the ECMAScript version, named and anonymous functions may treat the function name property differently. */\n\n// Immediately Invoked Function Expressions (IIFE): An IIFE is a function that is executed immediately after it is defined. \n// It is often used to create a new scope and avoid scope pollution.\nlet iife = (function () {\n    console.log(\"This is another example of IIFE functions\"); // This will be logged\n})();\n\n/* Higher-Order Functions: These are functions that take other functions as arguments or return functions as their result. \n   They are commonly used in functional programming. */\n\n// Example of a sum function\nfunction sum(numbers: number[]): number {\n    let total = 0;\n    for (let i = 0; i < numbers.length; i++) {\n        total += numbers[i];\n    }\n    return total;\n}\n\n// Example of a range function\nfunction range(n: number, m: number): number[] {\n    let result: number[] = [];\n    for (let i = n; i <= m; i++) {\n        result.push(i);\n    }\n    return result;\n}\n\n// Using the sum and range functions together\nlog(sum(range(1, 100))); // 5050\n\n/* Generator Functions: Introduced in ES6, generator functions can pause and resume execution. \n   They are defined using the function * syntax and use the yield keyword. */\nfunction* IdGenerator() {\n    let id = 0;\n    while (true) {\n        yield addPad(++id, 5);\n    }\n}\n\nconst idIterator = IdGenerator();\n\nlog(idIterator.next().value); // 00001\nlog(idIterator.next().value); // 00002\n\n/* Async Functions: Async functions are a way to work with asynchronous code. \n   They return a promise and can use the await keyword to pause execution until a promise is resolved. */\n\n// Note: You may need an extension to allow CORS (Cross-Origin Resource Sharing) to avoid console warnings.\nconst getLoremIpsum = (numberOfParagraphs: number): Promise<string[]> => {\n    return fetch(`https://baconipsum.com/api/?type=meat-and-filler&paras=${numberOfParagraphs}`)\n        .then(response => response.json())\n        .then(loremIpsumTextArray => {\n            return loremIpsumTextArray;\n        })\n        .catch(error => {\n            showError(error);\n        });\n};\n\nconst showError = (error: any): void => console.log(error);\n\nasync function logParagraphs(): Promise<void> {\n    const result = await getLoremIpsum(2);\n    console.log(result);\n}\n\nlogParagraphs(); // Logs: Array of paragraphs or similar content\n\n// Functions that take multiple arguments / the Rest parameter ...\n// Sometimes we don't know how many arguments we will receive, we can use the rest parameter in those cases.\nconst total = (...numbers: number[]): number => {\n    return numbers.reduce((total, num) => total + num, 0);\n};\n\nlog('Total: ', total(10, 256, 345, 465, 87, 432)); // Total: 1595\n\n/* CLOSURES AND SCOPES */\n\n// Scope: A scope refers to the visibility of identifiers in certain parts of a program. \n/* Closure: A closure allows a function to access and manipulate variables that are external to that function. \n   Closures allow a function to access all the variables, as well as other functions, that are in scope when the function itself is defined. \n   Hoisting is a mechanism that moves all variable and function declarations to the top of their scope. \n   However, variable assignments still happen where they originally were. */\n\n// This will work because doSomething is a Named Function and JavaScript hoists function declarations to the top of their containing scope.\nlog(doSomething()); // I'm here coding, and I'm amazed at all we can learn by following this roadmap.\n\nfunction doSomething(): void {\n    console.log(\"I'm here coding, and I'm amazed at all we can learn by following this roadmap.\");\n}\n\n// This will throw an error because an anonymous function cannot be called before its declaration.\n// log(doAnotherthing());\n\nlet anotherthing = function () {\n    console.log('never log this...');\n};\n\nlet friend = 'Asterix';\n\nfunction showClosure(): void {\n    log(friend); // Asterix in scope\n    let anotherFriend = 'Obelix';\n    function innerClosure(): void {\n        let anotherOne = 'Idefix';\n        log(anotherFriend); // Obelix in scope\n        log(friend); // Asterix in scope\n        log(anotherOne); // Idefix in scope\n    }\n    // log(anotherOne); // Throws an Error: anotherOne is not defined, is not in scope\n    innerClosure();\n}\n\nshowClosure();\n// log(anotherFriend); // Throws an Error: anotherFriend is not defined, is not in scope\n\n/* Closures let us do some interesting things, such as defining \"private\" variables that are visible only to a specific function or set of functions. \n   A contrived (but popular) example: */\nconst makeCounter = () => {\n    let counter = 0;\n    return {\n        value: () => counter,\n        increment: () => {\n            counter++;\n        },\n        restart: () => {\n            counter = 0;\n        }\n    };\n};\n\nlet counter1 = makeCounter();\nlet counter2 = makeCounter();\ncounter2.increment();\ncounter2.increment();\nlog(counter1.value()); // 0\nlog(counter2.value()); // 2\ncounter2.restart();\nlog(counter2.value()); // 0\n\n// Note: When makeCounter() is called, a snapshot of the context of that function is saved.\n// Note 2: Closures are also used to prevent global namespace pollution, often through the use of immediately-invoked function expressions.\n// Apply and Call\nfunction speak(this: { name: string }, ...sentences: string[]): void {\n    let tell = '';\n    sentences.forEach(word => tell += word + ' ');\n    console.log(this.name + \": \" + tell);\n}\n\nlet person = { name: \"Niko\" };\nspeak.apply(person, [\"I\", \"will\", \"go\", \"through\", \"this\", \"roadmap\", \"until\", \"the\", \"end\"]); // Niko: I will go through this roadmap until the end\nspeak.call(person, \"But\", \"first\", \"I\", \"need\", \"some\", \"exercise\"); // Niko:  But first I need some exercise\n\n/* Notice that apply allows you to pass an Array or the arguments object (array-like) as the list of arguments, \n   whereas call requires you to pass each argument separately. */\n\n/* As we see in the previous obj.advertisement() example: \n   When using arrow functions, 'this' takes the value from the enclosing execution context's 'this' (that is, \n   'this' in arrow functions has lexical scope rather than the usual dynamic scope). \n   In global code (code that doesn't belong to any function), it would be the global object. \n   And it keeps that way, even if you invoke the function declared with the arrow notation from any of the other methods here described. */\n\n/* The bind method of every function allows you to create a new version of that function with the context strictly bound to a specific object. \n   It is especially useful to force a function to be called as a method of an object. */\n\nlet person2 = { name: 'Anna' };\n\nfunction sayHiLady(this: { name: string }): void {\n    log(`Hi ${this.name}`);\n}\n\nconst hiAnna = sayHiLady.bind(person2);\nhiAnna(); // Hi Anna\n\n/*  This a possible output example for the previus  logParagraphs() async function:\n[\n  'Shank aliquip fugiat, cupim irure pig capicola kielbasa in mollit bresaola venison bacon aliqua.  Alcatra aliqua jowl fatback pork chop in exercitation corned beef leberkas aliquip qui chicken consequat laboris.  Swine shank porchetta tail quis in.  Chuck dolore venison, picanha id swine cupim strip steak porchetta magna ball tip excepteur hamburger mollit ex.  Picanha chislic irure strip steak sausage, in kevin ullamco.  Magna pork belly tongue meatloaf elit tempor.  Veniam meatball corned beef pork chop in.',\n  'Sint ut deserunt pork loin enim doner sunt chuck qui occaecat aliqua meatloaf spare ribs exercitation.  Shank esse cupidatat, boudin cupim eiusmod tenderloin occaecat do drumstick cow ut meatball.  Aute non pig esse ea capicola landjaeger beef ad qui minim in boudin.  Shank non dolore adipisicing.  Ham hock drumstick sint landjaeger minim.  Dolor in nisi chicken sunt.'    \n]  */"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/typescript/eulogioep.ts",
    "content": "// Variable global\nlet contadorGlobal: number = 0;\n\n// 1. Función sin parámetros ni retorno\nfunction saludar(): void {\n    console.log(\"¡Hola, mundo!\");\n}\n\n// 2. Función con un parámetro y sin retorno\nfunction saludarPersona(nombre: string): void {\n    console.log(`¡Hola, ${nombre}!`);\n}\n\n// 3. Función con múltiples parámetros y retorno\nfunction sumar(a: number, b: number): number {\n    return a + b;\n}\n\n// 4. Función que demuestra una \"función\" dentro de otra\nfunction operacionMatematica(a: number, b: number): number {\n    const multiplicar = (x: number, y: number): number => x * y;\n    return multiplicar(a, b) + 10;\n}\n\n// 5. Uso de una función incorporada en TypeScript/JavaScript\nfunction obtenerFechaActual(): string {\n    return new Date().toISOString().split('T')[0];\n}\n\n// 6. Demostración de variable local vs global\nfunction incrementarContador(): void {\n    let contadorLocal: number = 0;\n    contadorLocal++;\n    contadorGlobal++;\n    console.log(`Contador local: ${contadorLocal}, Contador global: ${contadorGlobal}`);\n}\n\n// DIFICULTAD EXTRA\nfunction imprimirYContar(texto1: string, texto2: string): number {\n    let contadorNumeros: number = 0;\n\n    for (let i: number = 1; i <= 100; i++) {\n        if (i % 3 === 0 && i % 5 === 0) {\n            console.log(texto1 + texto2);\n        } else if (i % 3 === 0) {\n            console.log(texto1);\n        } else if (i % 5 === 0) {\n            console.log(texto2);\n        } else {\n            console.log(i);\n            contadorNumeros++;\n        }\n    }\n\n    return contadorNumeros;\n}\n\n// Llamadas a las funciones y impresión de resultados\nconsole.log(\"1. Función sin parámetros ni retorno:\");\nsaludar();\n\nconsole.log(\"\\n2. Función con un parámetro y sin retorno:\");\nsaludarPersona(\"Alice\");\n\nconsole.log(\"\\n3. Función con múltiples parámetros y retorno:\");\nconsole.log(`Suma de 5 y 3: ${sumar(5, 3)}`);\n\nconsole.log(\"\\n4. Función que demuestra una \\\"función\\\" dentro de otra:\");\nconsole.log(`Resultado de operación matemática: ${operacionMatematica(4, 5)}`);\n\nconsole.log(\"\\n5. Uso de una función incorporada en TypeScript/JavaScript:\");\nconsole.log(`Fecha actual: ${obtenerFechaActual()}`);\n\nconsole.log(\"\\n6. Demostración de variable local vs global:\");\nincrementarContador();\nincrementarContador();\n\nconsole.log(\"\\nDIFICULTAD EXTRA:\");\nconst numerosPuros: number = imprimirYContar(\"Fizz\", \"Buzz\");\nconsole.log(`Números impresos sin ser reemplazados por texto: ${numerosPuros}`);"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/typescript/fravelz.ts",
    "content": "// Funciones en JavaScript ************************************************** //\n\n//Función sin parámetros ni retorno\nfunction texto(): void {\n    console.log(\"Hola mundo\");\n}\ntexto();\n\n//Función con parámetros\nfunction suma(num1: number, num2: number): void {\n    console.log(num1 + num2);\n}\nsuma(2, 3);\n\n//Función con parámetro y retorno\nfunction cuadrado(x: number): number {\n    return x * x;\n}\n\nconsole.log(cuadrado(4));\n\n// crear scope para función dentro de otra función\n{\n    function cubo(f: (num: number) => number, m: number[]): number[] {\n        const resultado: number[] = [];\n\n        for (let i = 0; i < m.length; i++)\n            resultado[i] = f(m[i]);\n        return resultado;\n    }\n\n    const f = function (num: number): number {\n        return num * num * num;\n    }\n\n    let matriz: number[] = [1, 2, 3, 4]\n    console.log(cubo(f, matriz));\n}\n\n//Ejemplo de función creada por el lenguaje\n\nlet aleatorio: number = Math.random(); // Math.random es una función que genera un número aleatorio entre 0 y 1\nconsole.log(aleatorio);\n\n// Variable global y local ************************************************** //\nvar x: number = 8;\n\nfunction numero(): void {\n    var x: number = 6;\n\n    console.log(x); //Muestra el valor de la variable local\n}\n\nconsole.log(x); //Muestra el valor de la variable global\nnumero();\n\n/*DIFICULTAD EXTRA (opcional):\nCrea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n- La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n- Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n- Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n- Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n- La función retorna el número de veces que se ha impreso el número en lugar de los textos. */\n\nfunction lista(multiplo3: string, multiplo5: string): number | void {\n    let count: number = 0;\n    for (let i = 1; i < 101; i++) {\n        if (i % 3 == 0 && i % 5 == 0) console.log(multiplo3 + \" y \" + multiplo5);\n        else if (i % 3 == 0) console.log(multiplo3);\n        else if (i % 5 == 0) console.log(multiplo5);\n        else {\n            console.log(i);\n            count++;\n        }\n    }\n    return count;\n}\n\nlista(\"múltiplo de 3\", \"múltiplo de 5\");\n\nexport { };\n\n// > Autor: Fravelz\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/typescript/giovanyosorio.ts",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n\nfunction saludar(): void {\n    console.log(\"Hola mundo\");\n}\n\n\nfunction sumar(valor1:number, valor2:number): number {\n    return valor1+valor2;\n  }\n  \n  console.log(sumar(10, 5));\n\n  // Función dentro de otra función\nfunction operacionesMatematicas(): void {\n    const restar = (x: number, y: number): number => {\n        return x - y;\n    }\n\n    console.log(\"Suma: \", sumar(5, 3));\n}\n\n// Uso de una función incorporada: Math.max()\nfunction maximoDeDosNumeros(a: number, b: number): number {\n    return Math.max(a, b);\n}\n\n\n// Demostración de variable LOCAL y GLOBAL\nlet variableGlobal = \"Soy global\";\n\nfunction probarScope(): void {\n    let variableLocal = \"Soy local\";\n    console.log(variableGlobal); // Accede a la variable global\n    console.log(variableLocal);  // Accede a la variable local\n}\n\n// Función con dificultad extra\nfunction extra(texto1: string, texto2: string): number {\n    let contadorNumeros :number=0\n\n    for (let index = 0; index < 100; index++) {\n        if(index%3===0) {\n            console.log(texto1)\n        }\n       else if(index%5===0) {\n            console.log(texto2)\n        }\n        else if(index%5===0 && index%3===0 ) {\n            console.log(texto1+texto2)\n        }   \n        else{\n            console.log(index)\n            contadorNumeros++\n        } \n    }\n    return contadorNumeros\n}\nconsole.log(\"Número de veces que se imprimió un número:\", extra(\"Fizz\", \"Buzz\"));\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/typescript/gitperalta.ts",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n//* EJEMPLOS DE FUNCIONES\n\n// Sin Parametros ni retorno\nconst sinParametros = () => {\n  // Esta función no recibe parametros\n  console.log(\"Esta funcion no retorna nada.\");\n};\nsinParametros();\n\n// Con Parametros y retorno\nconst conParametros = (a: string, b: string) =>\n  // Esta función recibe 2 parametros\n  console.log(`Esta función retorna ${a} y ${b}`);\nconParametros(\"Hola\", \"Mundo\");\n\n// Con varios parametro\nconst conVariosParametros = (...params: number[]) => {\n  // Esta función recibe varios parametros\n  console.log(params.reduce((acc, ele) => ((acc += ele), 0)));\n};\nconVariosParametros(...Array.from({ length: 10 }, (_, index) => index + 1));\n\n// CREANDO UNA FUNCIÓN DENTRO DE OTRA\nconst crearDentroDeOtra = (a: number) => {\n  const interna = () =>\n    `${a.toString()} al cuadrado e igual ${(a ^ 2).toString()}`;\n  console.log(interna());\n};\ncrearDentroDeOtra(4);\n\n//FUNCIONES CREADAS POR EL LENGUAGE\nconsole.log(Date()); // Devuelve la hora y fecha de este momento;\nconsole.log(Math.random()); // Devuelve un numero random entre 0 y 1;\nconsole.log(\"Hola Mundo\".length); // Devuelve el numero de caracteres del string\n\n// VARIABLE LOCAL Y GLOBAL\nlet a = \"Hola Mundo\";\nconst global = () => console.log(`La variable ${a} se puede usar globalmente`);\nglobal();\n\nconst local = () => {\n  let a = \"Chau Mundo\";\n  return console.log(\n    `La variable ${a} solo puede usarse en el scope en el que se encuentra.`\n  );\n};\nlocal();\n\n// DIFICULTAD EXTRA\nconst extra = (a: string, b: string): number => {\n  let sum = 0;\n  for (let i = 1; i <= 100; i++) {\n    if (!(i % 5) && !(i % 3)) console.log(a + b);\n    if (!(i % 5)) console.log(b);\n    if (!(i % 3)) console.log(a);\n    if (i % 3 && i % 5) sum++;\n  }\n  return 0;\n};\n\nconsole.log(extra(\"Fizz\", \"Buzz\"));\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/typescript/hozlucas28.ts",
    "content": "/*\n    Types of functions...\n*/\n\n// IIFE\n;((): void => {\n\tconsole.log('IFE (Immediately-Invoked Function Expression): (() => {<INTRUCTIONS...>})()')\n})()\n\n// Arrow function\nconst arrowFunction = (): void => {\n\tconsole.log('Arrow function: const <FUNCTION NAME> = (<PARAMETERS...>) => {<INTRUCTIONS...>}')\n}\n\n// Common function\nfunction commonFunction(): void {\n\tconsole.log('Common function: function <FUNCTION NAME>(<PARAMETERS...>) {<INTRUCTIONS...>}')\n}\n\n// With parameters\nfunction fnWithParameters(name: string): void {\n\tconsole.log(`Common function (with parameters): function <FUNCTION NAME>(name) {<INTRUCTIONS...>} --> Hello ${name}!`)\n}\n\n// Without parameters\nfunction fnWithoutParameters(): void {\n\tconsole.log(`Common function (without parameters): function <FUNCTION NAME>() {<INTRUCTIONS...>} --> Hello!`)\n}\n\n// With default parameters\nfunction fnWithDefaultParameters(lastName: string = 'Hoz'): void {\n\tconsole.log(\n\t\t`Common function (with default parameters): function <FUNCTION NAME>(lastName = \"Hoz\") {<INTRUCTIONS...>} --> By ${lastName}!`\n\t)\n}\n\n// With rest parameter\nfunction fnWithRestParameter(...rest: string[]): void {\n\tconsole.log(`Common function (with rest parameter): function <FUNCTION NAME>(...rest) {<INTRUCTIONS...>} --> ${rest}`)\n}\n\n// With return\nfunction fnWithReturn(): string {\n\treturn 'Lucas Hoz'\n}\n\n// Without return\nfunction fnWithoutReturn(): void {\n\tconsole.log(\n\t\t`Common function (without return): function <FUNCTION NAME>() {<INTRUCTIONS (return not included)...>} --> return void`\n\t)\n}\n\narrowFunction()\ncommonFunction()\nfnWithParameters('Lucas')\nfnWithoutParameters()\nfnWithDefaultParameters()\nfnWithRestParameter('JavaScript', 'TypeScript', 'ReactJS', 'NextJS')\nconsole.log(\n\t`Common function (with return): function <FUNCTION NAME>() {<INTRUCTIONS (with return definition included)...>} --> return '${fnWithReturn()}'`\n)\nfnWithoutReturn()\n\n/*\n    Function definition inside another function...\n*/\n\n// Arrow function inside a common function definition\nfunction wrapperFn(): void {\n\tconst innerFn = (): void => {\n\t\tconsole.log('Inner function called')\n\t}\n\n\tconsole.log('\\nWrapper function called')\n\tinnerFn()\n}\n\nwrapperFn()\n\n/*\n    Native functions...\n*/\n\nconst result: number = eval('1 + 7')\nconsole.log(`\\nNative functions: eval('1 + 7') --> ${result}`)\n\nconst casting: number = parseInt('12')\nconsole.log(`Native functions: parseInt('12') --> ${casting} (${typeof casting})`)\n\n/*\n    Global and local variables...\n*/\n\nconst country: string = 'Argentina'\n\nfunction showCountry(): string {\n\tconst state = 'Buenos Aires'\n\treturn `function call with a global variable --> country = '${country}'`\n}\n\nconsole.log(`\\nGlobal variable: ${showCountry()}`)\n// console.log(`Local variable: variable defined inside a function but called outside it --> state = ${state}`) // Throw a reference error.\nconsole.log(`Local variable: variable defined inside a function but called outside it --> state = ReferenceError`)\n\n/*\n    Additional challenge...\n*/\n\nfunction additionalChallenge(str01: string, str02: string): number {\n\tconsole.log('')\n\n\tlet counter: number = 0\n\tfor (let i = 1; i < 101; i++) {\n\t\tconst multipleOfFive = i % 5 === 0\n\t\tconst multipleOfThree = i % 3 === 0\n\n\t\tif (multipleOfFive && multipleOfThree) {\n\t\t\tconsole.log(str01 + str02)\n\t\t\tcontinue\n\t\t}\n\n\t\tif (multipleOfFive) {\n\t\t\tconsole.log(str02)\n\t\t\tcontinue\n\t\t}\n\n\t\tif (multipleOfThree) {\n\t\t\tconsole.log(str01)\n\t\t\tcontinue\n\t\t}\n\n\t\tconsole.log(i)\n\t\tcounter++\n\t}\n\n\treturn counter\n}\n\nconsole.log(`\\n${additionalChallenge('fizz', 'buzz')} numbers was printed instead of 'fizz' or 'buzz' (function arguments)!`)\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/typescript/ialmontedr0.ts",
    "content": "/**\r\n * Funciones basicas Typescript\r\n */\r\n\r\n// Funcion sin parametros ni retorno\r\nfunction primerFucion(): void {\r\n    console.log(\"Funcion sin parametros ni retorno\");\r\n  }\r\n  \r\n  // Funcion con un parametro sin retorno\r\n  function funcionConParametro(param1: string): void {\r\n    console.log(`Funcion con un parametro: ${param1}`);\r\n  }\r\n  \r\n  // Funcion con varios parametros sin retorno\r\n  function funcionConParametros(param1: string, param2: number): void {\r\n    console.log(`Funcion con varios parametros: ${param1}, ${param2}`);\r\n  }\r\n  \r\n  // Funcion con un parametro y retorno\r\n  \r\n  function funcionConParametroYRetorno(param: string): string {\r\n    return `Funcion con un parametro y retorno: ${param}`;\r\n  }\r\n  \r\n  // Funcion dentro de otra funcion\r\n  function funcionConFuncionInterna(): void {\r\n    function funcionInterna(): void {\r\n      console.log(\"Funcion dentro de otra funcion\");\r\n    }\r\n  }\r\n  \r\n  /**\r\n   * Ejemplo de funciones ya creadas en Typescript\r\n   */\r\n  \r\n  // Funcion Math.random()\r\n  \r\n  function ejemploFuncionMathRandom(): void {\r\n    const numeroRandom = Math.random();\r\n    console.log(`Ejemplo Math.random(): ${numeroRandom}`);\r\n  }\r\n  \r\n  /**\r\n   * Variables locales y globales\r\n   */\r\n  \r\n  // Variable global\r\n  let variableGlobal: string = \"Variable global\";\r\n  \r\n  // Funcion con variable global\r\n  \r\n  function ejemploFuncionConVariableGlobal(): void {\r\n    console.log(`Ejemplo con variable global: ${variableGlobal}`);\r\n  }\r\n  \r\n  // Funcion con variable local\r\n  function ejemploFuncionConVariableLocal(variableLocal: string): void {\r\n    console.log(`Ejemplo con variable local: ${variableLocal}`);\r\n  }\r\n  \r\n  /**\r\n   * Ejercicio extra Funcion que imprime numeros y concatena cadenas\r\n   */\r\n  function ejercicioExtra(primerTexto: string, segundoTexto: string): void {\r\n    let numeroImpresiones: number = 0;\r\n    for (let i = 1; i <= 100; i++) {\r\n      if (i % 3 === 0 && i % 5 === 0) {\r\n        console.log(`${primerTexto} ${segundoTexto}`);\r\n        numeroImpresiones++;\r\n      } else if (i % 3 === 0) {\r\n        console.log(primerTexto);\r\n        numeroImpresiones++;\r\n      } else if (i % 5 === 0) {\r\n        console.log(segundoTexto);\r\n        numeroImpresiones++;\r\n      } else {\r\n        console.log(i);\r\n        numeroImpresiones++;\r\n      }\r\n    }\r\n  }\r\n  \r\n  /**\r\n   * Llamadas a las funciones\r\n   */\r\n  \r\n  primerFucion();\r\n  funcionConParametro(\"Parametro 1\");\r\n  funcionConParametros(\"Parametro 1\", 2);\r\n  console.log(funcionConParametroYRetorno(\"Parametro 1\"));\r\n  funcionConFuncionInterna();\r\n  ejemploFuncionMathRandom();\r\n  ejemploFuncionConVariableGlobal();\r\n  ejemploFuncionConVariableLocal(\"Variable local\");\r\n  ejercicioExtra(\"Texto 1\", \"Texto 2\");"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/typescript/isaias-alt.ts",
    "content": "// Definimos una función sin parámetros ni retorno\nfunction greeting(): void {\n  console.log(\"¡Hola, mundo!\");\n}\n\n// Definimos una función con parámetros y retorno\nfunction adition(a: number, b: number): number {\n  return a + b;\n}\n\n// Definimos una función que crea funciones dentro de funciones\nfunction createFunctionWithinFunction(): void {\n  function internalFunction(): void {\n    console.log(\"¡Función interna ejecutada!\");\n  }\n\n  internalFunction(); // Llamamos a la función interna\n}\n\n// Utilizamos una función ya creada en el lenguaje\nconst currentDate = new Date();\nconsole.log(\"Fecha actual:\", currentDate);\n\n// Probamos el concepto de variable LOCAL y GLOBAL\nlet globalVariable = \"Soy global\";\n\nfunction showLocalVariable(): void {\n  let localVariable = \"Soy local\";\n  console.log(localVariable); // Mostramos la variable local\n  console.log(globalVariable); // Mostramos la variable global\n}\n\nshowLocalVariable();\n\n// Dificultad extra: función con dos parámetros de tipo cadena y retorno numérico\nfunction printNumbers(text1: string, text2: string): number {\n  let counter: number = 0;\n  for (let i: number = 1; i <= 100; i++) {\n    if (i % 3 === 0 && i % 5 === 0) {\n      console.log(text1 + text2);\n    } else if (i % 3 === 0) {\n      console.log(text1);\n    } else if (i % 5 === 0) {\n      console.log(text2);\n    } else {\n      console.log(i);\n    }\n    counter++;\n  }\n  return counter;\n}\n\n// Probamos la función con dos cadenas y mostramos el resultado\nconst result = printNumbers(\"Fizz\", \"Buzz\");\nconsole.log(\"La función ha impreso números \" + result + \" veces.\");\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/typescript/jesusEs1312.ts",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n// Variable Global\nlet resultado: number = 0;\n\n//Función con retorno\nfunction functionWithReturn(): string {\n    return 'Hola mundo desde Typescript';\n}\n\n// Función con parametros (number) utilizando variable global\nfunction fuctionWithParameters(valor1: number, valor2: number): void {\n    // Variable global\n    this.resultado = valor1 + valor2;\n    console.log(`Función con parametros: ${valor1} + ${valor2} = ${this.resultado}`);\n}\n\n// Función con parametros con valor por default\nfunction functionWithDefaultParameters(nombre: string = 'Peter', apellido: string = 'Parker'): string {\n    return `${nombre} ${apellido}`;\n}\n\n/*\n * Utilización de una función dentro de otrar sin retorno \n * y utilizando la función toUpperCase()\n */\nfunction functionWithOtherFunction(): void {\n    // Variable Local\n    let resultado: string = functionWithReturn().toUpperCase();\n    console.log(`Función que utiliza la función toUpperCase(): ${resultado}`);\n}\n\n// Consoles\nconsole.log(functionWithReturn());\nfuctionWithParameters(4,1);\nconsole.log(functionWithDefaultParameters());\nfunctionWithOtherFunction();\n\n// Ejercicio Extra\nfunction extraExercise(param1: string, param2: string): number {\n    const array: number[] = Array.from(Array(100).keys()).map(x => x + 1);\n    let numReturn = 0;\n    array.forEach(num => {\n        if(num % 3 == 0 && num % 5 == 0){\n            console.log(param1);\n        } else if(num % 5 == 0){\n            console.log(param2);\n        } else if(num % 3 == 0){\n            console.log(`${param1} ${param2}`);\n        } else {\n            console.log(num);\n            numReturn++;\n        }\n    });\n    return numReturn;\n}\n\nconsole.log(extraExercise('Spider Man', 'Batman'));\n\n\n "
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/typescript/juserdev.ts",
    "content": "/*\n * EJERCICIO:\n ! - Crea ejemplos de funciones básicas que representen las diferentes posibilidades del lenguaje: Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n ! - Comprueba si puedes crear funciones dentro de funciones.\n ! - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n ! - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n ! - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n\n// FUNCION BASICA\nconst myFunction = ()=>{\n    console.log(\"hola funcion 1\")\n}\nmyFunction()\n\n// FUNCION CON RETORNO\nconst myFunction2: ()=> string = ()=>{\n    return \"hola como estas funcion 2?\"\n}\n\nconsole.log(myFunction2())\n\n//FUNCION CON PARAMETROS\n\nconst myFunction3: (saludo: string, lenguaje:string) => string = (saludo, lenguaje) =>{\n    return `${saludo} ${lenguaje}`\n}\n\nconsole.log(myFunction3(\"Hola\", \"TypeScript\"))\n\n//FUNCION DENTRO DE UNA FUNCION\n\nconst myFunction4: (saludar: string) => string = (saludar)=>{\n    const myFunction5: (lenguaje: string) => string = (lenguaje)=>{\n        return `${saludar} ${lenguaje}`\n    }\n    return myFunction5(\"TypeScript, funcion dentro de una funcion\")\n}\n\nconsole.log(myFunction4(\"hola\"))\n\n// console.log(Math.random()) // FUNCION DEL LENGUAJE\n\n//VARIABLE LOCAL Y GLOBAR\n\nconst saludar: string = \"hola\"\n\nconst myFunction6: (lenguaje: string) => string = (lenguaje)=>{\n    return `${saludar}, ${lenguaje}`\n}\nconsole.log(myFunction6(\"TypeScript\")) // variable global\n\nconst myFunction7: (lenguaje: string) => string = (lenguaje)=>{\n    const saludo: string = \"hola\"\n    return `${saludo} ${lenguaje}`\n}\n\nconsole.log(myFunction7(\"TypeScript con variable local\"))\n\n\n//EXTRA\n\nconst functionExtra: (param1:string, param2:string)=> number = (param1, param2)=>{\n    let num: number = 0\n    for (let i = 1; i < 100 ; i++) {\n        if (i % 3 === 0) {\n            console.log(param1)\n            num++\n        }else if (i % 5 === 0){\n            console.log(param2)\n            num++\n        } else if (i % 3 === 0 && i % 5 === 0){\n            console.log(`${param1}${param2}`)\n            num++\n        }else {\n            console.log(i)\n        }\n    }\n    return num\n}\n\nconsole.log(functionExtra(\"Type\", \"Script\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/typescript/kodenook.ts",
    "content": "\nfunction name(): void {\n    console.log('kodenook')\n}\n\nname()\n\nfunction fullName({ fname = 'my', lname = 'name' }: { fname?: string, lname?: string }): void {\n    console.log(`${fname} ${lname}`)\n}\n\nfullName({ lname: 'lname' })\n\nfunction addition(...nums: number[]): number {\n    let result: number = 0\n\n    for (let x of nums) {\n        result += x\n    }\n\n    return result\n}\n\nconsole.log(addition(1, 2, 2.4, 1.1, -2.2))\n\nfunction first() {\n    console.log('first')\n\n    function second() {\n        console.log('second')\n    }\n\n    second()\n}\n\nfirst()\n\nlet global = 'global'\n\nfunction scope() {\n    console.log(global)\n    let local = 'local'\n}\n\nscope()\n\n/*\n    Exercise\n*/\n\nfunction exercise(word1: string, word2: string): number {\n    let numberCount: number = 0\n\n    for (let x of Array(101).keys()) {\n        if (x % 3 == 0 && x % 5 == 0) {\n            console.log(`${word1} ${word2}`)\n        } else if (x % 3 == 0) {\n            console.log(word1)\n        } else if (x % 5 == 0) {\n            console.log(word2)\n        } else {\n            numberCount++\n        }\n    }\n\n    return numberCount\n}\n\nconsole.log(`number of times it was a number and not words: ${exercise('hello', 'typescript')}`)"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/typescript/marcode24.ts",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n// Ejemplos de funciones básicas\nfunction funcionSinParametrosNiRetorno(): void {\n  console.log(\"¡Hola desde la función sin parámetros ni retorno!\");\n}\n\nfunction funcionConParametros(parametro1: any, parametro2: any): void {\n  console.log(\"Parámetro 1:\", parametro1);\n  console.log(\"Parámetro 2:\", parametro2);\n}\n\nfunction funcionConRetorno(num1: number, num2: number): number {\n  return num1 + num2;\n}\n\n// Funciones dentro de funciones\nfunction funcionExterna(): void {\n  console.log(\"Función externa\");\n\n  function funcionInterna(): void {\n    console.log(\"Función interna\");\n  }\n\n  funcionInterna();\n}\n\n// Variable GLOBAL y LOCAL\nlet variableGlobal: string = \"Soy global\";\n\nfunction funcionConVariables(): void {\n  let variableLocal: string = \"Soy local\";\n  console.log(variableGlobal);\n  console.log(variableLocal);\n}\n\n// Utilizar función ya creada en el lenguaje\nlet numeros: number[] = [1, 2, 3, 4, 5];\nlet cuadrados: number[] = numeros.map((numero) => numero * numero);\n\nconsole.log(\"Cuadrados:\", cuadrados);\n\n// Función Extra (DIFICULTAD EXTRA)\nfunction funcionExtra(texto1: string, texto2: string): number {\n  let contador: number = 0;\n\n  for (let i: number = 1; i <= 100; i++) {\n    if (i % 3 === 0 && i % 5 === 0) {\n      console.log(texto1 + texto2);\n    } else if (i % 3 === 0) {\n      console.log(texto1);\n    } else if (i % 5 === 0) {\n      console.log(texto2);\n    } else {\n      console.log(i);\n    }\n\n    contador++;\n  }\n\n  return contador;\n}\n\nconsole.log(\"Número de impresiones:\", funcionExtra(\"Fizz\", \"Buzz\"));\n\n// Visita mi repo en GitHub para ver y correr los tests de este código --> https://github.com/marcode24/weekly-challenges\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/typescript/markc1234.ts",
    "content": "// EJERCICIO:\n\n(() => {\n    // Crea ejemplos de funciones básicas que representen las diferentes posibilidades del lenguaje:\n    function funcion1():void {\n        console.log(\"Funcion que no recibe parametros\")\n    }\n    funcion1()\n\n    // Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n    const funcion2 = (a:number,b:number):number => {\n        console.log(\"Funcion que recibe dos parametros y retorna un numero\")\n        return a + b\n    }\n    \n    // Comprueba si puedes crear funciones dentro de funciones.\n    const funcion3 = () => {\n        const funcion4Anidada = () => {\n            console.log(\"Esta es una funcion interna\")\n        }\n        funcion4Anidada()\n    }\n    funcion3()\n\n    // Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n    function funcion5() {\n        return funcion2(25, 25)\n    }\n    const suma = funcion5()\n    console.log(suma)\n\n    // Pon a prueba el concepto de variable LOCAL y GLOBAL.\n    let varGlobal:string = \"GLOBAL\"\n    const funcion6 = () => {\n        let varLocal: string = \"LOCAL\"\n        // Debes hacer print por consola del resultado de todos los ejemplos.\n        console.log(varLocal)\n        console.log(varGlobal)\n    }\n    // (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n    funcion6()\n    \n    // DIFICULTAD EXTRA (opcional):\n    // Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n    function funcionExtra(p1:string, p2:string):number {\n        let contador:number = 0\n\n        // La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n        for (let i = 1; i <= 100; i++) {\n            // Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n            if(i % 3 === 0 && i % 5 === 0) {\n                console.log(p1 + \" \" + p2)\n            }\n            // Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n            else if(i % 3 === 0) {\n                console.log(p1)\n            } else if(i % 5 === 0) {\n                // Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n                console.log(p2)\n            }\n            \n            contador += 1\n        }\n        // La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n        \n        return contador\n    }\n})()"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/typescript/martinbohorquez.ts",
    "content": "/**\n * 02 FUNCIONES Y ALCANCE\n *\n * @author martinbohorquez\n */\nclass martinbohorquez {\n\n    /**\n     * Ejemplo de Método estático, sin retorno y sin parámetros.\n     */\n    static saludar(): void {\n        console.log(\"Hola, TypeScript!\");\n    }\n\n    /**\n     * Ejemplo de Método estático, sin retorno, con parámetros.\n     *\n     * @param name tipo string.\n     */\n    static saludarWithName(name: string): void {\n        console.log(`Hola, ${name}!`);\n    }\n\n    /**\n     * Ejemplo de Método estático, con retorno y sin parámetros.\n     *\n     * @return tipo string.\n     */\n    static saludarKotlin(): string {\n        return \"Hola, Kotlin!\";\n    }\n\n    /**\n     * Ejemplo de Método estático, con retorno y parámetros.\n     *\n     * @param salario tipo number.\n     * @param percentAhorro tipo number.\n     * @return ahorro mensual, tipo number.\n     */\n    static calcularAhorroMensual(salario: number, percentAhorro: number): number {\n        return salario * percentAhorro;\n    }\n\n    /**\n     * Método con retorno y parámetros.\n     *\n     * @param ahorroMensual tipo number.\n     * @param tasaAnual tipo number.\n     * @param periodos tipo number.\n     * @return ahorro total, tipo number.\n     */\n\n    /**\n     * Método con retorno y parámetros.\n     *\n     * @param salario tipo number.\n     * @param percentAhorro tipo number.\n     * @param tasaAnual tipo number.\n     * @param periodos tipo number.\n     * @return ahorro total, tipo number.\n     */\n\n    calcularAhorro(param1: number, param2: number, param3: number, param4?: number): number {\n        if (param4 !== undefined) {\n            // Lógica para el cálculo basado en salario, percentAhorro, tasaAnual, periodos\n            const pago = martinbohorquez.calcularAhorroMensual(param1, param2);\n            return this.calcularAhorro(pago, param3, param4);\n        } else {\n            // Lógica para el cálculo basado en ahorroMensual, tasaAnual, periodos\n            const periodosPorAnio = 12; // Capitalización mensual\n            const tasaMensual = Math.pow(1 + param2, 1 / periodosPorAnio) - 1; // Tasa mensual\n            return param1 * ((Math.pow(1 + tasaMensual, param3) - 1) / tasaMensual);\n        }\n    }\n\n    /**\n     * DIFICULTAD EXTRA (Ejercicio fizz buzz)\n     *\n     * @param texto1 el texto para los divisores de 3.\n     * @param texto2 el texto para los divisores de 5.\n     * @return el número de veces que mostró números y no texto.\n     */\n    fizzBuzz(texto1: string, texto2: string): number {\n        let counter = 0;\n        let result: string;\n\n        for (let i = 1; i <= 100; i++) {\n            result = \"\";\n\n            if (i % 3 === 0) {\n                result += texto1;\n            }\n\n            if (i % 5 === 0) {\n                result += texto2;\n            }\n\n            if (result === \"\") {\n                result = i.toString();\n                counter++;\n            }\n\n            console.log(result);\n        }\n        return counter;\n    }\n}\n\n\n/**\n * Método principal\n */\nfunction main(): void {\n    console.log(\"---- SALUDAR ----\");\n    martinbohorquez.saludar();\n    martinbohorquez.saludarWithName(\"Python\");\n    martinbohorquez.saludarWithName(\"Typescript\");\n    console.log(martinbohorquez.saludarKotlin());\n\n    console.log(\"---- CALCULAR AHORRO ----\");\n    let salario = 4000;\n    let percentAhorro = 62.5 / 100;\n    let tasaAnual = 8.00 / 100;\n    let periodos = 3 * 12;\n\n    const df = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' });\n    const dfp = new Intl.NumberFormat('en-US', { style: 'percent', minimumFractionDigits: 2 });\n\n    console.log(\"Salario: \" + df.format(salario));\n    console.log(\"Porcentaje de ahorro (%): \" + dfp.format(percentAhorro));\n    console.log(\"Periodos de ahorro (meses): \" + periodos);\n    console.log(\"Tasa de interés anual (%): \" + dfp.format(tasaAnual));\n\n    const ahorroMensual = martinbohorquez.calcularAhorroMensual(salario, percentAhorro);\n    console.log(\"El ahorro mensual: \" + df.format(ahorroMensual));\n\n    // Crear instancia\n    const mbohorquez = new martinbohorquez();\n    const ahorroTotal = mbohorquez.calcularAhorro(ahorroMensual, tasaAnual, periodos);\n    console.log(\"El ahorro total generado es: \" + df.format(ahorroTotal));\n    console.log();\n\n    salario = 1500;\n    percentAhorro = 67.5 / 100;\n    tasaAnual = 7.50 / 100;\n    periodos = 2 * 12;\n\n    console.log(\"Salario: \" + df.format(salario));\n    console.log(\"Porcentaje de ahorro (%): \" + dfp.format(percentAhorro));\n    console.log(\"Periodos de ahorro (meses): \" + periodos);\n    console.log(\"Tasa de interés anual (%): \" + dfp.format(tasaAnual));\n\n    const ahorroTotal2 = mbohorquez.calcularAhorro(salario, percentAhorro, tasaAnual, periodos);\n    console.log(\"El ahorro total generado es: \" + df.format(ahorroTotal2));\n    console.log();\n\n    console.log(\"DIFICULTAD EXTRA\");\n    const numeros = mbohorquez.fizzBuzz(\"fizz\", \"buzz\");\n    console.log(\"números de: \" + numeros);\n}\n    \n// Llamada al método principal\nmain();\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/typescript/miguelangelmz21.ts",
    "content": "\n \n\n// - Crea ejemplos de funciones básicas que representen las diferentes posibilidades del lenguaje:\n//   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n\nfunction sinParametrosNiRetorno() {\n    console.log(\"Esta función no tiene parámetros ni retorno.\");\n}\n// Llamada a la función sin parámetros ni retorno\nsinParametrosNiRetorno();\n\nfunction conUnParametro(parametro: string) {\n    console.log(\"Este es un parámetro: \" + parametro);\n}\n// Llamada a la función con un parámetro\nconUnParametro(\"Hola, soy un parámetro\");\n\nfunction conVariosParametros(param1: string, param2: number) {\n    console.log(\"Primer parámetro: \" + param1);\n    console.log(\"Segundo parámetro: \" + param2);\n}\n// Llamada a la función con varios parámetros\nconVariosParametros(\"Hola\", 42);\n\nfunction conRetorno(): string {\n    return \"Este es el valor de retorno.\";\n}\n// Llamada a la función con retorno\nconst retorno = conRetorno();\nconsole.log(\"Valor de retorno: \" + retorno);\n\n// - Comprueba si puedes crear funciones dentro de funciones.\nfunction funcionConFuncion() {\n    function funcionInterna() {\n        console.log(\"Soy una función interna.\");\n    }\n    funcionInterna();\n}\n// Llamada a la función que contiene una función interna\nfuncionConFuncion();\n\n// - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\nfunction ejemploFuncionesYaCreadas() {\n    const array = [1, 2, 3, 4, 5];\n    const suma = array.reduce((acc, val) => acc + val, 0);\n    console.log(\"Suma de los elementos del array: \" + suma);\n    const maximo = Math.max(...array);\n    console.log(\"Máximo del array: \" + maximo);\n    const minimo = Math.min(...array);\n    console.log(\"Mínimo del array: \" + minimo);\n}\n// Llamada a la función que utiliza funciones ya creadas\nejemploFuncionesYaCreadas();\n\n// - Pon a prueba el concepto de variable LOCAL y GLOBAL.\nlet variableGlobal = \"Soy una variable global\";\n\nfunction pruebaVariables() {\n    let variableLocal = \"Soy una variable local\";\n    console.log(variableLocal);\n    console.log(variableGlobal);\n}\n// Llamada a la función que prueba variables locales y globales\npruebaVariables();\n\n// Dificultad extra\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n*/\n\n\n//  Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\nfunction ejercicioReto(texto1: string, texto2: string): number {\n    let contadorNumerosImpresos: number = 0;\n\n    for (let i = 1; i <= 100; i++) {\n        if (i % 3 === 0 && i % 5 === 0) {\n            console.log(`${texto1} ${texto2}`);\n        } else if (i % 3 === 0) {\n            console.log(texto1);\n        } else if (i % 5 === 0) {\n            console.log(texto2);\n        } else {\n            console.log(i);\n            contadorNumerosImpresos++;\n        }\n    }\n\n    return contadorNumerosImpresos;\n}\n// Llamada a la función de dificultad extra\nconst resultado = ejercicioReto(\"Oro\", \"Plata\");\nconsole.log(\"Número de veces que se imprimió un número:\", resultado);"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/typescript/miguelex.ts",
    "content": "// Ejemplo de funcion sin variables ni retorno\n\nfunction saludo(): void {\n    console.log(\"Hola\");\n}\n\n// Ejemplo de funcion con paso de variable y sin retorno\n\nfunction saludo2(nombre): void {\n    console.log(\"Hola \" + nombre);\n}\n\nsaludo2(\"Migue\");\n\n// Ejemplo de funcion con paso de variable y retorno\n\nfunction saludo3(nombre): string {\n    return \"Hola \" + nombre;\n}\n\nlet msj: string = saludo3(\"Migue\");\nconsole.log(msj);\n\n// Ejemplo de funcion flecha de funcion sumar\n\nconst sumar = (a, b): number => {\n    return a + b;\n}\n\nlet suma: number = sumar(2, 3);\n\n// Ejemplo de funcion creada dentro de otra funcion\n\nfunction saludoYSuma(a, b): void {\n    console.log(\"Hola, vamos a hacer una suma\");\n    function sumar(a, b) {\n        return a + b;\n    }\n    console.log(sumar(a, b));\n}\n\nsaludoYSuma(2, 3);\n\n// Ambito global y local de las variables\n\nlet variableGlobal: string = \"Soy global\";\n\nfunction mostrarVariableGlobal() : void{\n    console.log(variableGlobal);\n}\n\nmostrarVariableGlobal();\n\nfunction mostrarVariableLocal(): void {\n    let variableLocal = \"Soy local\";\n    console.log(variableLocal);\n}\n\n// Ejemplo de funciones del sistema\n\nconsole.log(parseInt(\"20\"));\n\n// Ejemplo de funcion anonima\n\nlet anonima = function() {\n    console.log(\"Soy anonima\");\n}\nanonima();\n\n// Extra\n\nfunction ejercicioExtra(param1, param2): number {\n    let numVeces = 0;\n    for (let i = 1; i <= 100; i++) {\n      if (i % 15 === 0) {\n        console.log(param1 + param2);\n      } else if (i % 3 === 0) {\n        console.log(param1);\n      } else if (i % 5 === 0) {\n        console.log(param2);\n      } else {\n        console.log(i);\n        numVeces++;\n      }\n    }\n    return numVeces;\n  }\n  \n  const extra = ejercicioExtra(\"Fizz \", \"Buzz\");\n  console.log(\"Cantidad de numeros imprimidos =  \" + extra)\n\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/typescript/mikelroset.ts",
    "content": "/* - Sin parámetros ni retorno, con uno o varios parámetros, con retorno... - */\n// Función anónima autoejecutable\n(function () {\n  console.log(\"Hola Mundo\");\n})(); // Hola Mundo\n\n// Función anónima\nconst funcionAnonima = function() {\n  console.log(\"Hola Mundo\");\n};\nfuncionAnonima(); // Hola Mundo\n\n// Función declarativa sin retorno\nfunction funcionSinRetorno(): void {\n  console.log(\"Hola Mundo\");\n}\nfuncionSinRetorno(); // Hola Mundo\n\n// Función declarativa con retorno\nfunction funcionConParametro(name: string): void {\n  console.log(`Hola ${name}`);\n}\nfuncionConParametro(\"Miquel\"); // Hola Miquel\n\n// Función declarativa con varios parámetros\nfunction funcionConVariosParametros(\n  firstName: string, \n  lastName: string\n): void {\n  console.log(`Hola ${firstName} ${lastName}`);\n}\nfuncionConVariosParametros(\"Miquel\", \"Roset\"); // Hola Miquel Roset\n\n// Función expresada con retorno\nfunction funcionConRetorno(a: number, b: number): number {\n  return a + b;\n}\nfuncionConRetorno(5, 5); // 10\n\n// Función con parámetros opcionales\nfunction funcionConParametrosOpcionales(a: number, b?: number): number {\n  return b ? a + b : a;\n}\nfuncionConParametrosOpcionales(5); // 5\nfuncionConParametrosOpcionales(5, 5); // 10\n\n// Función con parámetros de tipo rest\nfunction funcionConParametrosRest(a: number, ...b: number[]): number {\n  return a + b.reduce((total, current) => total + current, 0);\n}\nfuncionConParametrosRest(5, 1, 2, 3, 4, 5); // 15\n\n// Función con parámetros de tipo rest y parámetros opcionales\nfunction funcionConParametrosRestOpcionales(\n    a: number, c?: number, ...b: number[]\n): number {\n  return a + b.reduce((total, current) => total + current, 0) + (c || 0);\n}\nfuncionConParametrosRestOpcionales(5, undefined, 1, 2, 3, 4, 5); // 20\nfuncionConParametrosRestOpcionales(5, 10, 1, 2, 3, 4, 5); // 25\n\n// Función flecha\nconst funcionFlecha = (a: number, b: number): number => a + b;\nfuncionFlecha(5, 5); // 10\n\n// Función con callbacks\nfunction funcionConCallbacks(\n  a: number, \n  b: number, \n  callback: (a: number, b: number) => number\n): number {\n  return callback(a, b);\n}\nfuncionConCallbacks(5, 5, (a, b) => a + b); // 10\n\n\n/* ----------- Funciones dentro de funciones (o de orden superior) ---------- */\nfunction ordenSuperior(): void {\n  function funcionDentro(): void {\n    console.log(\"Hola Mundo\");\n  }\n  funcionDentro();\n}\nordenSuperior(); // Hola Mundo\n\n\n/* ---------------- Funciones ya creadas por el lenguaje -------------------- */\nfunction creadasPorLenguaje(): void {\n  console.log(\"Hola Mundo\");\n  alert(\"Hola Mundo\");\n  prompt(\"Hola Mundo\");\n  confirm(\"Hola Mundo\");\n}\ncreadasPorLenguaje(); // Hola Mundo, Hola Mundo, Hola Mundo, Hola Mundo\n\n\n/* -------------------- Variable local y variable global -------------------- */\nlet variableGlobal: string = \"Hola Mundo Global\";\n\nfunction funcionConVariableLocal(): void {\n  let variableLocal: string = \"Hola Mundo Local\";\n  console.log(variableLocal); // Hola Mundo Local\n  console.log(variableGlobal); // Hola Mundo Global\n}\nfuncionConVariableLocal(); // Hola Mundo Local, Hola Mundo Global\n\nconsole.log(variableLocal); // ReferenceError: variableLocal is not defined\n\n\n// -------------------------- BONUS EJERCICIO ------------------------------- //\n\n/*\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne \n * un número.\n * \n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer \n *     parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo \n *     parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto \n *     concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en \n *     lugar de los textos.\n * \n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los \n * casos. Cada lenguaje sigue una convenciones que debes de respetar para que el \n * código se entienda.\n */\n\nfunction bonus(a: string, b: string): number {\n  let count: number = 0;\n  for (let i: number = 1; i <= 100; i++) {\n    if (i % 3 === 0) {\n      console.log(a);\n    } else if (i % 5 === 0) {\n      console.log(b);\n    } else if (i % 3 === 0 && i % 5 === 0) {\n      console.log(a + b);\n    } else {\n      console.log(i);\n      count++;\n    }\n  }\n  return count;\n}\nbonus(\"Miquel\", \"Roset\"); // 100\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/typescript/mxtrar23.ts",
    "content": "\n// Funciones\n\n// básica\nfunction saludar() {\n  console.log('Hola');\n}\nsaludar()\n\n// de flecha\nconst bienvenida = () => {\n  console.log('Bienvenidos!')\n}\n\nbienvenida()\n\n// retorna\nfunction obtenerSaludo() {\n  return \"Hola, Bienvenido!\"\n}\n\nconsole.log(obtenerSaludo())\n\n//con parametros\nfunction saludarPersona(nombre) {\n  console.log(`Hola, ${nombre} bienvenido!`)\n}\n\nsaludarPersona('Typescript')\n\n// parametros opcionales\nfunction saludarOpcional(nombre=''){\n  console.log(`Hola, ${nombre} bienvenido!`)\n}\n\nsaludarOpcional('mxtrar23')\nsaludarOpcional('')\n\n// parametros y retorno\nfunction obtenerSaludarPersona(nombre) {\n  return `Hola, ${nombre} bienvenidos!`\n}\n\nconsole.log(obtenerSaludarPersona('Devs'))\n\n// retorno con dispercion \nfunction obtenerSaludoMultipleArray() {\n  return ['Hola','Bienvenidos']\n}\n\nconst [saludoText,bienvenidaText] = obtenerSaludoMultipleArray()\n\nconsole.log(saludoText,bienvenidaText);\n\nfunction obtenerSaludoMultipleObject() {\n  return {\n    saludoObj:'Hola',\n    bienvenidaObj:'Bienvenidos'\n  }\n}\n\nconst {saludoObj,bienvenidaObj} = obtenerSaludoMultipleObject()\n\nconsole.log(saludoObj,bienvenidaObj);\n\n// multiples parametros\nfunction SaludoMultiple (...rest){\n  rest.forEach(el => {\n    console.log(`Hola, ${el}`);\n  });\n}\n\nSaludoMultiple('Mundo','Typescript','Devs','Mxtrar23')\n\n\n// parametros con palabra clave de Objeto\nfunction saludoClave (data){\n  Object.keys(data).forEach(e=>{\n    console.log(`{${e}} =  {${data[e]}}`);\n  })\n}\n\nsaludoClave({\n  language:'TypeScript',\n  name:'Arb',\n  alias:'Mxtrar23',\n  edad:29\n});\n\n\n// funcion anónima\n(()=>{\n  console.log('Ejecución de Funcion anónima')\n})();\n\n//function intera\nfunction funcionExterna(){\n  function functionInterna(){\n    console.log('Saludos desde dentro');\n  }\n  functionInterna()\n}\n\nfuncionExterna()\n\n//calback\nfunction funcionretornoEnParametro(n1,n2,callback){\n  callback(n1+n2)\n}\n\nfuncionretornoEnParametro(5,2,(n)=>console.log('La suma es ',n))\n\nconst variabelGlobal = 'Typescript'\n\nfunction misVariables() {\n  const varibaleLocal = 'Bienvenido'\n  console.log(varibaleLocal,variabelGlobal);\n}\n\nconsole.log(variabelGlobal);\nmisVariables()\n\n//Dificultad Extra\n\nfunction remplaza(str1,str2){\n  let count =0\n  for (let num = 1; num <=100; num++) {\n    if(num%3==0 && num%5==0){\n      console.log(`${str1}${str2}`);\n    } else if (num%3==0){\n      console.log(`${str1}`);\n    } else if (num%5==0){\n      console.log(`${str2}`);\n    } else{\n      count++\n      console.log(`${num}`);\n    }\n  }\n  return count\n}\n\nconsole.log(remplaza('Mde3','Mde5'))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/typescript/nlarrea.ts",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n\n// BASIC FUNCTIONS\n\nfunction noParamsNoReturn() {\n    console.log('Hello there!')\n}\n\nnoParamsNoReturn() // Hello there\n\n\nfunction paramsNoReturn(name: string) {\n    console.log(`Hello, ${name}`)\n}\n\nparamsNoReturn('Naia')  // Hello, Naia\n\n\nfunction paramsReturn(name: string, surname: string): string {\n    return `${name} ${surname}`\n}\n\nconsole.log(paramsReturn('John', 'Smith'))  // John Smith\n\n\n// FUNCTIONS INSIDE FUNCTIONS\n\nfunction printFullName(name: string, surname: string): void {\n    function getFullName() {\n        return `${name} ${surname}`\n    }\n\n    console.log(getFullName())\n}\n\nprintFullName('John', 'Smith')  // John Smith\n\n\n// BUILTIN FUNCTIONS\n\nconsole.log(typeof parseInt('101'))  // number\n\n\n// LOCAL AND GLOBAL VARIABLES\n\n// Global variables\nvar counter: number = 0\n\nfunction globalVariables() {\n    counter++\n    console.log(counter)  // 1\n    counter++\n}\n\nglobalVariables()\nconsole.log(counter)  // 2\n\n// Local variables\n\nfunction localCounter() {\n    let counterTwo: number = 0\n    counterTwo++\n    console.log(counterTwo)\n}\n\nlocalCounter()  // 1\n// console.log(counterTwo)  // Error: Cannot find name 'counterTwo'\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n */\n\nfunction printNumbers(textOne: string, textTwo: string): number {\n    let counter: number = 0;\n\n    for (let num: number = 1; num <= 100; num++) {\n        if (num % 3 === 0 && num % 5 === 0) {\n            console.log(`${textOne}${textTwo}`);\n        } else if (num % 3 === 0) {\n            console.log(textOne);\n        } else if (num % 5 === 0) {\n            console.log(textTwo);\n        } else {\n            console.log(num);\n            counter++;\n        }\n    }\n\n    return counter;\n}\n\nconsole.log(printNumbers('fizz', 'buzz'));  // 53"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/typescript/pcosin.ts",
    "content": "// función simple sin parámetros\n\nfunction printString(): void {\n    console.log(\"Hola\");\n  }\n  \n  printString();\n  \n  // función simple con parámetros\n  \n  function printStringPara(name: string): void {\n    console.log(`Hola ${name}`);\n  }\n  \n  printStringPara(\"Brais\");\n  \n  // Retorno y dos parámetros\n  \n  function add(num1: number, num2: number) {\n    return num1 + num2;\n  }\n  \n  console.log(add(2, 5));\n  \n  // función anónima\n  \n  const sub = function (num1: number, num2: number) {\n    return num1 - num2;\n  };\n  \n  console.log(sub(4, 2));\n  \n  // funciones flecha en una sola línea con retorno implícito.\n  \n  const multiply = (num1: number, num2: number) => num1 * num2;\n  \n  console.log(multiply(34, 55));\n  \n  // callbacks\n  \n  const addChar = (arr: string[]) =>\n    arr.map((element) => {\n      return element + \"!\";\n    });\n  \n  console.log(addChar([\"hola\", \"chau\", \"quizás\"]));\n  \n  // Ejemplo de variable global y local\n  \n  let variableGlobal: string = \"Juan\";\n  \n  function variables() {\n    let variableLocal: string = \"Hola\";\n    let lasDosVariables: string = `${variableLocal} ${variableGlobal}`;\n    return lasDosVariables;\n  }\n  console.log(variables());\n  \n  // console.log(variableLocal); No se puede mostrar porque está fuera del scope de la función\n  \n  // Dificultad Extra\n  \n  const fizzBuzz = (firstWord: string, secondWord: string) => {\n    let totalNum: number = 0;\n    for (let i: number = 1; i <= 100; i++) {\n      if (i % 15 === 0) console.log(firstWord + secondWord);\n      else if (i % 5 === 0) console.log(secondWord);\n      else if (i % 3 === 0) console.log(firstWord);\n      else {\n        totalNum++;\n        console.log(i);\n      }\n    }\n    return totalNum;\n  };\n  \n  console.log(fizzBuzz(\"Fizz\", \"Buzz\"));\n  "
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/typescript/qv1ko.ts",
    "content": "let a: number = 3;\n\nmain();\nconsole.log(\"\\nNumber of times a text was not printed: \" + program(\"zip\", \"zap\"));\n\nfunction main() {\n\n    func1();\n    console.log(func2());\n    func3(a, \"\\nParameterized and non-return function:\\nGlobal variable A: \");\n    console.log(func4(-4, \"\\nFunction with return and with parameters:\\nGlobal variable A: \"));\n    \n}\n\nfunction func1() {\n    var b = 3;\n    console.log(\"\\nFunction without return and without parameters:\\nGlobal variable A: \" + a + \"\\nLocal variable B:\" + b);\n}\n\nfunction func2(): string {\n    return \"\\nFunction with return and without parameters:\\nGlobal variable A: \" + a;\n}\n\nfunction func3(num: number, str: string) {\n    console.log(str + num);\n}\n\nfunction func4(num: number, str: string): string {\n    return str + a + \"\\nAbsolute number: \" + Math.abs(num);\n}\n\nfunction program(zip: string, zap: string): number {\n\n    console.log(\"\\nProgram:\")\n\n    let count: number = 0;\n\n    for (let i = 1; i <= 100; i++) {\n        if (i % 3 == 0 && i % 5 == 0) {\n            console.log(zip + zap);\n        } else if (i % 3 == 0) {\n            console.log(zip);\n        } else if (i % 5 == 0) {\n            console.log(zap);\n        } else {\n            count++;\n        }\n    }\n\n    return count;\n\n}\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/typescript/qwik-zgheib.ts",
    "content": "/* -- exercise */\nconst greet = (): void => console.log(\"Hello, world!\");\n\ngreet();\n\nconst square = (number: number): number => number * number;\n\nlet result: number = square(5);\nconsole.log(\"Square of 5:\", result);\n\nconst outerFunction = (): void => {\n  console.log(\"Outer function is executing.\");\n  const innerFunction = (): void => console.log(\"Inner function is executing.\");\n  innerFunction();\n};\n\nouterFunction();\n\nlet globalVariable: string = \"I'm global\";\n\nfunction localGlobalExample(): void {\n  let localVariable: string = \"I'm local\";\n  console.log(\"Inside function:\");\n  console.log(\" - Local variable:\", localVariable);\n  console.log(\" - Global variable:\", globalVariable);\n}\n\nlocalGlobalExample();\n\nconsole.log(\"Outside function - Global variable:\", globalVariable);\n\nlet randomNumber: number = Math.random();\nconsole.log(\"Random number:\", randomNumber);\n\n/* -- extra challenge */\nfunction printNumbersAndCount(text1: string, text2: string): number {\n  let count: number = 0;\n\n  for (let i: number = 1; i <= 100; i++) {\n    if (i % 3 === 0 && i % 5 === 0) {\n      console.log(text1 + text2);\n      count++;\n    } else if (i % 3 === 0) {\n      console.log(text1);\n      count++;\n    } else if (i % 5 === 0) {\n      console.log(text2);\n      count++;\n    } else console.log(i);\n  }\n\n  return count;\n}\n\nlet count: number = printNumbersAndCount(\"Fizz\", \"Buzz\");\nconsole.log(\"Number of times text has been printed:\", count);\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/typescript/rendonnm.ts",
    "content": "// Función declarada\n// Se hoistea\nfunction greet() {\n  console.log('Hello world')\n}\n\n// Función expresada\n// No se hoistea\nconst greet2 = function () {\n  console.log('Hello world')\n}\n\n// Arrow function\n// No tiene this, común en callbacks\nconst greetArrow = () => {\n  console.log('Hello world')\n}\n\n// Con argumentos/parámetros y return\nconst greetName = (name: string = 'Friend') => {\n  return `Hello ${name}`\n}\n\nconsole.log(greetName('Santiago'))\n\n// Múltiples parámetros, se recomienda utilizar objetos\nconst personalizedGreet = ({ greet, name }: { greet: string, name: string }) => {\n  return `${greet} ${name}!`\n}\n\npersonalizedGreet({ name: 'Santi', greet: 'Oe' })\n\n// Funciones de orden súperior\n// Funciones que reciben una una función cómo callback o retornan una función\nconst runOnce = (fn: () => void) => {\n  return () => {\n    // Hacer algo...\n    fn()\n  }\n}\n\n// Variables locales y globales\nlet usuario = \"Santi\" // variable global\n\nfunction saludar() {\n  let saludo = `Hola, ${usuario}` // variable local\n  console.log(saludo)\n}\n\nsaludar()\nconsole.log(usuario) // ✅ Santi\n\n// console.log(saludo) ❌ Error: 'saludo' is not defined\n\n// Closures \nconst createCounter = () => {\n  let counter = 0\n  return () => {\n    console.log(`Aumentamos contador: ${++counter}`)\n  }\n}\n\nconst counter = createCounter()\ncounter()\ncounter()\ncounter()\n\n/* DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\nconst newF = (a: string, b: string): number => {\n  let counter = 0\n  for (let i = 1; i <= 100; i++) {\n    if (i % 3 === 0 && i % 5 === 0) {\n      console.log(`${a}${b}`)\n    } else if (i % 3 === 0) {\n      console.log(a)\n    } else if (i % 5 === 0) {\n      console.log(b)\n    } else {\n      console.log(i)\n      counter++\n    }\n  }\n  return counter\n}"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/typescript/rubenplazavi.ts",
    "content": "/*\n * EJERCICIO:\n * - Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:\n *   Sin parámetros ni retorno, con uno o varios parámetros, con retorno...\n * - Comprueba si puedes crear funciones dentro de funciones.\n * - Utiliza algún ejemplo de funciones ya creadas en el lenguaje.\n * - Pon a prueba el concepto de variable LOCAL y GLOBAL.\n * - Debes hacer print por consola del resultado de todos los ejemplos.\n *   (y tener en cuenta que cada lenguaje puede poseer más o menos posibilidades)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n\n// Sin parámetros ni retorno\nfunction noParametersNoReturnFunction(): void {\n    console.log('No Parameters No Return');\n}\n\n// con uno o varios parámetros, con retorno\nfunction oneOrMoreParametersFunction(a: number, b: number): void {\n    console.log(a+b);\n}\n\n// con retorno\nfunction returnFunction(parameter: string): string {\n    return `this is the parameter you have introduced ${parameter}`;\n}\n\n// crear funciones dentro de funciones\nfunction exteriorFunction(): void {\n    function insideFunction(): void {\n        console.log('this is a function inside a function');\n    }\n    insideFunction();\n}\n\nexteriorFunction();\n\n// Funciones ya creadas en el lenguaje\nconsole.log(Math.max(1, 2, 3, 4, 5));\nconsole.log(Math.min(1, 2, 3, 4, 5));\n\n// Variable LOCAL y GLOBAL\nconst globalVariable: string = 'this is a global variable';\n\nfunction localVariableFunction(): void {\n    let localVariable: string = 'this is a local variable';\n    console.log(globalVariable);\n    console.log(localVariable);\n}\nlocalVariableFunction();\nconsole.log(globalVariable);\n//console.log(localVariable);  // al ser local scope no la reconoce\n/*\n\nCrea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n * */\n\nfunction numberOfNonMultiplesOfThreeOrFive(parameter1: string, parameter2: string): number{\n    let count: number = 0;\n\n    for(let i=1; i<=100; i++){\n        if( i%3 === 0 && i%5 === 0){\n            console.log(parameter1 + parameter2);\n            continue;\n        }\n        if(i%3 === 0){\n            console.log(parameter1);\n            continue;\n        }\n        if(i%5 === 0){\n            console.log(parameter2);\n            continue;\n        }\n        count++;\n    }\n\n    return count;\n}\n\nconst counterOfTimes: number = numberOfNonMultiplesOfThreeOrFive('multiplo de 3', 'multiplo de 5');\n\nconsole.log('\\ncounterOfTimes ---->\\n',counterOfTimes);"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/typescript/samuelarandia.ts",
    "content": "/*--- Tipo de funciones ---*/\n\n// Funcion autoejectuable\n(function(){\n    console.log('Funcion autoejectuable')\n})()\n\n//Sin parametros ni retorno\n\nfunction sinParametros(): void{ \n    console.log('Sin parametros')\n}\nsinParametros()\n\n//Con un parametro y retorno\n\nfunction unParametro(numero: number): number{\n    return numero\n}\n\nconsole.log(unParametro(5))\n\n//Con varios parametros y retorno\n\nfunction variosParametros(a: number, b: number): number{\n    return a + b\n}\n\nconsole.log(variosParametros(2, 3))\n\n\n//Funcion dentro de funcion\n\nfunction funcionExterna(){\n    function funcionInterna(){\n        console.log('Funcion interna')\n    }\n    funcionInterna()\n}\n\nfuncionExterna()\n\n//Funciones ya creadas en el lenguaje\n\nconst arrayEjemplo: number[] = [1, 2, 3, 4, 5]\nconst restaArray = arrayEjemplo.reduce((a, b) => a - b, 0)\nconsole.log(\"Resta del array:\", restaArray)\n\n\n//Variable local y global\n\nlet variableGlobal: number = 100\n\nfunction mostrarVariableGlobal(): void {\n  console.log(\"Variable global dentro de la función:\", variableGlobal)\n}\n\nfunction cambiarVariableGlobal(): void {\n  let variableLocal: number = 50\n  variableGlobal = variableLocal\n  console.log(\"Variable global cambiada dentro de la función:\", variableGlobal)\n}\n\n// Llamadas a toda la funciones creadas\n\nsinParametros()\nconsole.log(\"Resultado de unParametro(4):\", unParametro(4))\nconsole.log(\"Resultado de variosParametros(3, 7):\", variosParametros(3, 7))\nfuncionExterna()\nconsole.log(\"Variable global fuera de la función:\", variableGlobal)\nmostrarVariableGlobal()\ncambiarVariableGlobal()\n\n\n/*\n * EJERCICIO:\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n *\n * Presta especial atención a la sintaxis que debes utilizar en cada uno de los casos.\n * Cada lenguaje sigue una convenciones que debes de respetar para que el código se entienda.\n */\n// Funcion que recibe dos paremetros\n\nfunction cadenasRetornoNumero( cadena1: string, cadena2: string): number{\n    if (typeof cadena1 !== \"string\" || typeof cadena2 !== \"string\") {\n        throw new Error(\"Los argumentos deben ser cadenas de texto\")\n    }\n    let contadorNumeros: number[] = [];\n    for (let i = 1; i <= 100; i++) {\n        if (i % 3 === 0 && i % 5 === 0) {\n            console.log(cadena1 + cadena2, i);\n        } else if (i % 3 === 0) {\n            console.log(cadena1, i);\n        } else if (i % 5 === 0) {\n            console.log(cadena2, i);\n        } else {\n            contadorNumeros.push(i);\n        }\n    }\n    return contadorNumeros.length;\n}\n\nconsole.log(\"Número de veces que se imprimió un número:\", cadenasRetornoNumero( \"fizz\", \"buzz\"))\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/typescript/sniker1223.ts",
    "content": "// no arguments, no return\nfunction sayHello() {\n  console.log(\"Hello. This function doesn't has parameter and return\")\n}\n\n// argument and return\nfunction square(number: number) {\n  return number * number;\n}\n\n// Nested functions\nfunction getScore(name: String, num1: number, num2: number) {\n  function add(name: String, num1: number, num2: number) {\n    return name + \" scored  \" + (num1 + num2);\n  }\n  console.log(add(name, num1, num2))\n}\n\n// Function printing\nsayHello()\nconsole.log(\"This function has a parameter and return: \" + square(2))\ngetScore(\"Sniker\", 20, 20)\nconsole.log(\"Console.log() is an example of a function\")\n\nlet varGlobal = 0\n// Challenge\nfunction printTheChallenge(text1: String, text2: String) {\n  for (let i = 1; i <= 100; i++) {\n    if (i % 3 == 0 && i % 5 == 0) {\n      console.log(text1.concat(text2.toString()))\n    } else if (i % 3 == 0) {\n      console.log(text1)\n    } else if (i % 5 == 0) {\n      console.log(text2)\n    } else {\n      console.log(i)\n      varGlobal += 1\n    }\n  }\n  return varGlobal\n}\n\nconsole.log(\"Number of times the number has been printed:\", printTheChallenge(\"Star\", \"Wars\"))"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/typescript/tolomero.ts",
    "content": "/*Crea ejemplos de funciones básicas que representen las diferentes\n *   posibilidades del lenguaje:*/\n\n//función sinple\n\nfunction saludar1(): void {\n    console.log(\"Hola, mundo!\");\n}\nsaludar1()//funcion con retorno\n\nfunction saludarRetorno(): string{\n    return \"Hola, mundo!\";\n}\n\nconst saludar2 = saludarRetorno;\nconsole.log(saludar2());\n\n// funcion con parametros\t\nfunction saludarConParametros(nombre: string, edad: number): void {\n    console.log(`Hola, ${nombre}! Tienes ${edad} años.`);\n}\nsaludarConParametros(\"Elena\", 28);\n\n\n//funcion con parametros por defecto\n\nfunction saludarConApellido(saludar:string = \"!Hola\", apellido: string = \"Perez\"): void {\n    console.log(`${saludar} parce ${apellido}`)\n}\n\nsaludarConApellido();\n\n//funcion con parametros rest\n\nfunction saludarConRestParametros(saludo: string, ...nombres: string[]): void {\n    nombres.forEach(nombre => {\n        console.log(`${saludo} ${nombre}`);\n    });\n}\nsaludarConRestParametros(\"Hola\", \"Juan\", \"Pedro\", \"Luis\");\n\n//funcion con parametros y retorno\n\nfunction elevarAlCuadrado(base: number): number {\n    return base * base;\n}\n\nconsole.log(elevarAlCuadrado(3));\n\n//funciones dentro de funciones\n\nfunction saludarConFunciones(nombre: string): void {\n    function saludar(): void {\n        console.log(`Hola ${nombre}`);\n    }\n\n    saludar();\n}\n\nsaludarConFunciones(\"Elena\");\n\n// variables globales\n\nlet variableGlobal = \"Hola, soy global\";\n\nfunction variableGlobal2(): void {\n    console.log(variableGlobal);\n\n}\n\n\n\n//variable local\n\nfunction variableLocal(): void {\n    let variableLocal = \"Hola, soy local\";\n    console.log(variableLocal);\n    console.log(variableGlobal);\n\n}\nvariableLocal();\n\n// ejercicio extra\nlet count: number = 0;\nfunction dosTextos(texto1:string, texto2:string): number {\n    \n    for(let i = 1; i <= 100; i++){\n        if ( i % 3 === 0) console.log(texto1 + texto2);\n        else if (i % 3 === 0) console.log(texto1);\n        else if (i % 5 === 0) console.log(texto2 );\n        else console.log(i);\n         count += 1 \n    }\n    return count\n}\n\nconsole.log(dosTextos(\"fizz\", \"buzz\"));\n\n\n\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/typescript/victor-Casta.ts",
    "content": "//Funciones sin parametros y sin retorno\nlet myFunction = function() {\n  console.log(\"Soy una función\");\n}\n\n//Funciones con unos o varios parametros\nlet addNumbers = function(a:number, b:number) {\n  console.log(a + b);\n}\naddNumbers(1, 2);\n\n//Funciones con retorno\nlet multiply = function(a:number, b:number):number{\n  return a * b;\n}\nconsole.log(multiply(3,4));\n\n/*\n  * -Utiliza algún ejemplo de funciones ya creadas en el lenguaje\n*/\n\nsetTimeout(() => console.log('Hola despues de 2000 ms'), 2000)\n\n\n/*\n  * -Pon a prueba el concepto de variable LOCAL y GLOBAL.\n*/\n\nlet myGlobalVariable = 'Hola' //Esta varible  se puede acceder en cualquier lugar del documento\nlet variables = function(){\n  let myLocalVariable = 'TypeScript'//solo se puede acceder a myLocalVariable dentro de esta funcion\n  return myGlobalVariable + myLocalVariable\n}\nconsole.log(variables())\n\n/*\n  * - Comprueba si puedes crear funciones dentro de funciones.\n*/\n\nlet saludar = function(a:string) {\n  let hablar = (b:string) => console.log(`${a} ${b}`);\n  return hablar;\n}\nsaludar(\"Hola\")(\"TypeScript\");\n\n/*\n * - Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n *   - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n *   - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n *   - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n *   - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\n*/\n\nlet myPrincipalFuncion = function(a:string, b:string) {\n  let contador = 0\n  for (let i=1; i<=100;i++){\n    if (i % 3 === 0 && i % 5 === 0) {\n      console.log(`${a} ${b}`);\n    } else if(i % 3 === 0) {\n      console.log(a);\n    } else if(i % 5 === 0) {\n      console.log(b);\n    }\n    else {\n      contador++;\n    }\n  }\n  return contador;\n}\n\nconsole.log(myPrincipalFuncion('Hola', 'TypeScript'));\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/typescript/victoriaparraf.ts",
    "content": "//Funciones Sin Parámetros ni Retorno\nfunction saludar(): void {\n    console.log(\"¡Hola Mundo!\");\n}\nsaludar(); // ¡Hola Mundo!\n\n//Funciones Con Parámetros\n//Un Parámetro\nfunction saludarPersona(nombre: string): void {\n    console.log(`¡Hola, ${nombre}!`);\n}\nsaludarPersona(\"Juan\"); // ¡Hola, Juan!\n\n//Varios Parámetros\nfunction sumar(a: number, b: number): void {\n    console.log(a + b);\n}\nsumar(5, 3); // 8\n\n//Funciones Con Retorno\n//Retorno de un Valor\nfunction obtenerEdad(): number {\n    return 25;\n}\n\nlet edad: number = obtenerEdad();\nconsole.log(edad); // 25\n\n//Retorno de Varios Valores (tupla)\nfunction obtenerCoordenadas(): [number, number] {\n    return [10, 20];\n}\n\nlet coordenadas: [number, number] = obtenerCoordenadas();\nconsole.log(coordenadas); // [10, 20]\n\n//Funciones con Parámetros Opcionales y Valores Predeterminados\n//Parámetros Opcionales\nfunction saludarOpcional(nombre?: string): void {\n    if (nombre) {\n        console.log(`¡Hola, ${nombre}!`);\n    } else {\n        console.log(\"¡Hola!\");\n    }\n}\n\nsaludarOpcional(\"Ana\"); // ¡Hola, Ana!\nsaludarOpcional();      // ¡Hola!\n\n//Parámetros con Valores Predeterminados\nfunction saludarConPredeterminado(nombre: string = \"Amigo\"): void {\n    console.log(`¡Hola, ${nombre}!`);\n}\n\nsaludarConPredeterminado(\"Pedro\"); // ¡Hola, Pedro!\nsaludarConPredeterminado();        // ¡Hola, Amigo!\n\n//Funciones Anónimas\nlet saludarAnonimo = function(nombre: string): void {\n    console.log(`¡Hola, ${nombre}!`);\n};\n\nsaludarAnonimo(\"Carlos\"); // ¡Hola, Carlos!\n\n//Funciones Flecha\nlet saludarFlecha = (nombre: string): void => {\n    console.log(`¡Hola, ${nombre}!`);\n};\n\nsaludarFlecha(\"Laura\"); // ¡Hola, Laura!\n\n//Funciones que Aceptan Otras Funciones como Parámetros\n//Funciones como Parámetros\nfunction procesar(callback: (a: number, b: number) => number, a: number, b: number): void {\n    console.log(callback(a, b));\n}\n\nfunction sumando(a: number, b: number): number {\n    return a + b;\n}\n\nprocesar(sumando, 5, 3); // 8\n\n//Funciones que Devuelven Funciones\nfunction crearMultiplicador(multiplicador: number): (valor: number) => number {\n    return (valor: number) => valor * multiplicador;\n}\n\nlet duplicar = crearMultiplicador(2);\nconsole.log(duplicar(5)); // 10\n\n//Funcion dentro de una funcion\nfunction externa() {\n    let mensaje: string = \"Hola desde la función externa\";\n\n    function interna() {\n        console.log(mensaje);\n    }\n\n    interna();\n}\n\nexterna(); // \"Hola desde la función externa\"\n\n//Funcion ya creada en TypeScript\nlet mensaje: string = \"Hola Mundo\";\nconsole.log(mensaje.toUpperCase()); // \"HOLA MUNDO\"\nconsole.log(mensaje.includes(\"Mundo\")); // true\n\n\n//Variables locales versus variables globales\nlet globalVariable: string = \"Variable global\";\n\nfunction ejemplo() {\n    let localVariable: string = \"Variable local\";\n\n    console.log(globalVariable); // \"Variable global\"\n    console.log(localVariable); // \"Variable local\"\n\n    globalVariable = \"Variable global modificada\";\n\n    if (true) {\n        let localEnBloque: string = \"Variable local en bloque\";\n        console.log(localEnBloque); // \"Variable local en bloque\"\n    }\n\n    // La siguiente línea daría un error porque `localEnBloque` no está definida en este alcance.\n    // console.log(localEnBloque);\n}\n\nejemplo();\n\nconsole.log(globalVariable); // \"Variable global modificada\"\n// La siguiente línea daría un error porque `localVariable` no está definida en este alcance.\n// console.log(localVariable);\n\nfunction ejercicio(a: string, b: string): number{\n    let impresiones:number=0;\n    for(let contador: number = 1; contador <=100;contador++){\n        if ((contador % 3 == 0)&&(contador % 5 == 0)){\n            console.log(a+b);\n        }else if (contador % 3 == 0){\n            console.log(a);\n        }else if (contador % 5 == 0){\n            console.log(b);\n        }else {console.log(contador)\n            impresiones++;\n        }\n    }\n    return impresiones;\n}\n\nconsole.log(\"Cantidad de veces que se imprimio un numero = \"+ ejercicio(\"Wenas \",\"Taldes\"));\n"
  },
  {
    "path": "Roadmap/02 - FUNCIONES Y ALCANCE/vb.net/kenysdev.vb",
    "content": "' ╔══════════════════════════════════════╗\n' ║ Autor:  Kenys Alvarado               ║\n' ║ GitHub: https://github.com/Kenysdev  ║\n' ║ 2024 -  VB.NET                       ║\n' ╚══════════════════════════════════════╝\nModule Program\n    ' ----------\n    ' Funciones:\n    ' ----------\n    ' Función estática sin retorno\n    Sub print(ByVal msg As Object)\n        Console.WriteLine(msg)\n    End Sub\n\n    ' Funcion estática con retorno:\n    Function Suma(ByVal a As Integer, ByVal b As Integer) As Integer\n        Return a + b\n    End Function\n\n    ' Con Parámetro Opcional\n    Sub Divide(ByVal a As Integer, Optional ByVal b As Integer = 2)\n        print(a / b)\n    End Sub\n\n    ' Con Parámetros de Salida\n    Sub Dividir(ByVal dividendo As Integer, ByVal divisor As Integer, ByRef cociente As Integer, ByRef residuo As Integer)\n        cociente = dividendo / divisor\n        residuo = dividendo Mod divisor\n    End Sub\n\n    ' Funciones Recursivas\n    Function Factorial(ByVal n As Integer) As Integer\n        Return If(n = 0, 1, n * Factorial(n - 1))\n    End Function\n\n    'NOTE: las funciones anidadas (funciones dentro de funciones) no son permitidas.\n    \n    ' ----------\n    ' Ejercicio:\n    ' ----------\n    ' * Crea una función que reciba dos parámetros de tipo cadena de texto y retorne un número.\n    ' * - La función imprime todos los números del 1 al 100. Teniendo en cuenta que:\n    ' * - Si el número es múltiplo de 3, muestra la cadena de texto del primer parámetro.\n    ' * - Si el número es múltiplo de 5, muestra la cadena de texto del segundo parámetro.\n    ' * - Si el número es múltiplo de 3 y de 5, muestra las dos cadenas de texto concatenadas.\n    ' * - La función retorna el número de veces que se ha impreso el número en lugar de los textos.\"\"\")\n\n    Function Ejercicio(ByVal str1 As String, ByVal str2 As String) As Integer\n        Dim nVeces As Integer = 0\n        For num As Integer = 1 To 100\n            If num Mod 3 = 0 AndAlso num Mod 5 = 0 Then\n                print(str1 & str2)\n            ElseIf num Mod 3 = 0 Then\n                print(str1)\n            ElseIf num Mod 5 = 0 Then\n                print(str2)\n            Else\n                nVeces += 1\n                print(num)\n            End If\n        Next\n        Return nVeces\n    End Function\n\n    Sub Main(args As String())\n        ' Función estática sin retorno\n        print(\"Estática\")\n\n        ' Función estática con retorno\n        print(Suma(2, 2))\n\n        ' Con Parámetro Opcional\n        Divide(10)\n\n        ' Con Parámetros de Salida\n        Dim rCociente As Integer\n        Dim rResiduo As Integer\n        Dividir(10, 5, rCociente, rResiduo)\n        print($\"Cociente: {rCociente}, Residuo: {rResiduo}\")\n\n        ' Funciones Recursivas\n        print(Factorial(4))\n\n        ' Ejemplo de funciones incorporadas\n        Dim un_bool As Boolean = True\n        Dim a_str As String = Convert.ToString(un_bool)\n        print(a_str)\n\n        print(DateTime.Now)\n\n        print(\"abc\".Length)\n\n        ' Ejercicio\n        print(Ejercicio(\"múltiplo de 3\", \"múltiplo de 5\"))\n    End Sub\nEnd Module"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/arduino/santyjL.ino",
    "content": "// 03 ESTRUCTURAS DE DATOS //\n\n/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n *   y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n *   y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más\n *   de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.\n*/\n\n\nvoid setup() {\n  Serial.begin(9600);\n  array();\n  delay(1000);\n  Struct();\n  delay(1000);\n  presentacion();\n}\n\nvoid loop() {\n}\n\nvoid array() {\n  // Arrays - Listas\n  int miLista[5] = {10, 20, 30, 40, 50};\n  Serial.println(\"\\n=== Arrays - Listas ===\");\n  Serial.print(\"Lista original: \");\n  imprimirLista(miLista, 5);\n\n  // Añadir nuevos valores al final de la lista\n  miLista[5] = 60;\n  Serial.println(\"Lista modificada 1: \");\n  imprimirLista(miLista, 6);\n  miLista[6] = 70;\n  Serial.println(\"Lista modificada 2: \");\n  imprimirLista(miLista, 7);\n  miLista[7] = 80;\n  Serial.println(\"Lista modificada 3: \");\n  imprimirLista(miLista, 8);\n\n  // Asignar un nuevo valor a una posición existente\n  miLista[2] = 35;\n  Serial.println(\"Lista modificada 4: \");\n  imprimirLista(miLista, 7);\n\n  // Eliminar el valor en la posición 3\n  miLista[3] = 0; // Asignar un valor nulo o fuera de rango (en realidad no elimina nada, pero indica que no es relevante)\n  Serial.println(\"Lista modificada 5: \");\n  imprimirLista(miLista, 7);\n}\n\nvoid Struct(){ //Una struct te permite crear un tipo de dato personalizado que puede contener varios campos con diferentes tipos de datos.\n\n  // Struct\n  struct Persona {\n    char nombre[30];\n    int edad;\n    float altura;\n  };\n\n  Persona santiago;\n\n  // Asignar valores\n  strcpy(santiago.nombre, \"Santiago\");\n  santiago.edad = 14;\n  santiago.altura = 1.71;\n\n  // Acceder a los valores\n  Serial.println(\"\\n=== Struct ===\");\n  Serial.print(\"Nombre: \");\n  Serial.println(santiago.nombre); //el nombre de la struct con el valor a leer se parece a POO por lo menos de python\n  Serial.print(\"Edad: \");\n  Serial.println(santiago.edad); //prueba variando el orde del llamado\n  Serial.print(\"Altura: \");\n  Serial.println(santiago.altura);\n}\n\nvoid imprimirLista(int lista[], int longitud) {\n  Serial.print(\"Lista: [\");\n\n  for (int i = 0; i < longitud; i++) {\n    Serial.print(lista[i]);\n\n    // Imprimir coma y espacio si no es el último elemento\n    if (i < longitud - 1) {\n      Serial.print(\", \");\n    }\n  }\n  Serial.println(\"]\");\n}\n\n\n// Extra - contactos //\n\n// Funciones utilizadas en el reto - conceptos//\n\n/*\n*sizeof : devuelve el tamaño en bytes de un tipo de dato o de una variable. Se utiliza para determinar cuánta memoria ocupa un\n  tipo de dato o una instancia de un tipo de dato. Ejemplo : 43 utiliza 2 bytes , 777 utiliza 3 bytes o 555 55 utiliza 6 bytes\n  o en cadenas de texto \"111 11\" regresaria 8 bytes porque las \"\" tambien cuenta , en este caso la funcion se usa para leer\n  la cantidad de caracteres del carecteres del nombre y el numero\n\n*readBytesUntil : es una función de Arduino que lee datos desde un objeto de tipo Stream (como Serial) hasta que encuentra un\n  delimitador especificado. Los datos leídos se almacenan en un búfer. en otras parabras crea una variable temporal la cual\n  almacenara los datos semejantes a los que se busca en este caso se usa para verificar si un nombre existe y si exciste mostrarlo\n\n*strcmp : compara dos cadenas de caracteres. Devuelve un valor entero menor que, igual a, o mayor que cero si la primera cadena\n es menor que, igual a, o mayor que la segunda cadena, respectivamente. en respectiva si la respues es 0 es que son iguales si no\n las cadenas son diferentes y regresara un -1 o un 1\n\n*strcpy :(string copy) se utiliza para copiar el contenido de una cadena de caracteres (string) en otra\n\n*/\n\n\n// Definición de la estructura para los contactos\nstruct Contacto {\n  char nombre[20];\n  char numero[12];\n};\n\n// Arreglo de contactos\nContacto contactos[] = {\n  {\"fernandez\", \"1111 1111\"},\n  {\"julieta\", \"2222 2222\"},\n  {\"jose\", \"3333 3333\"},\n  {\"juancho\", \"4444 4444\"}\n};\n\n// Función de búsqueda\nvoid busqueda() {\n  char nombreBuscar[20];\n  Serial.print(\"Introduzca el nombre del contacto: \");\n  Serial.readBytesUntil('\\n', nombreBuscar, sizeof(nombreBuscar));\n\n  for (int i = 0; i < sizeof(contactos) / sizeof(contactos[0]); i++) {\n    if (strcmp(nombreBuscar, contactos[i].nombre) == 0) {\n      Serial.print(contactos[i].nombre);\n      Serial.print(\" - \");\n      Serial.println(contactos[i].numero);\n      return;\n    }\n  }\n\n  Serial.println(\"Contacto no existente\");\n}\n\n// Función de inserción\nvoid insercion() {\n  char nuevoNombre[20];\n  char nuevoNumero[12];\n\n  Serial.print(\"Ingrese el nombre del nuevo contacto: \");\n  Serial.readBytesUntil('\\n', nuevoNombre, sizeof(nuevoNombre));\n  Serial.print(\"Ingrese el número de teléfono: \");\n  Serial.readBytesUntil('\\n', nuevoNumero, sizeof(nuevoNumero));\n\n  // Verificar número de teléfono\n  if (strlen(nuevoNumero) <= 11) {\n    // Crear nuevo contacto\n    Contacto nuevoContacto;\n    strcpy(nuevoContacto.nombre, nuevoNombre);\n    strcpy(nuevoContacto.numero, nuevoNumero);\n\n    // Añadir a la lista\n    int indice = sizeof(contactos) / sizeof(contactos[0]);\n    contactos[indice] = nuevoContacto;\n\n    Serial.print(\"Contacto \");\n    Serial.print(nuevoContacto.nombre);\n    Serial.println(\" añadido correctamente.\");\n  } else {\n    Serial.println(\"Número de teléfono no válido. Asegúrate de ingresar un número numérico máximo de 11 dígitos.\");\n  }\n}\n\n// Función de actualización\nvoid actualizacion() {\n  char antiguoNombre[20];\n  char nuevoNombre[20];\n\n  Serial.print(\"Introduzca el nombre a cambiar: \");\n  Serial.readBytesUntil('\\n', antiguoNombre, sizeof(antiguoNombre));\n  Serial.print(\"Introduzca el nuevo nombre: \");\n  Serial.readBytesUntil('\\n', nuevoNombre, sizeof(nuevoNombre));\n\n  // Buscar el contacto\n  for (int i = 0; i < sizeof(contactos) / sizeof(contactos[0]); i++) {\n    if (strcmp(antiguoNombre, contactos[i].nombre) == 0) {\n      // Cambiar el nombre\n      strcpy(contactos[i].nombre, nuevoNombre);\n      Serial.println(\"Se cambió correctamente.\");\n      return;\n    }\n  }\n\n  Serial.println(\"El contacto a cambiar no existe.\");\n}\n\n// Función de eliminación\nvoid eliminacion() {\n  char nombreEliminar[20];\n  Serial.print(\"Introduzca el nombre a eliminar: \");\n  Serial.readBytesUntil('\\n', nombreEliminar, sizeof(nombreEliminar));\n\n  // Buscar el contacto\n  for (int i = 0; i < sizeof(contactos) / sizeof(contactos[0]); i++) {\n    if (strcmp(nombreEliminar, contactos[i].nombre) == 0) {\n      // Eliminar el contacto\n      contactos[i] = contactos[sizeof(contactos) / sizeof(contactos[0]) - 1];\n      Serial.println(\"Se eliminó correctamente.\");\n      return;\n    }\n  }\n\n  Serial.println(\"Contacto no existente, inténtelo de nuevo.\");\n}\n\nvoid presentacion() {\n\n  Serial.println(\"\\nLista de contactos\\n\"\n                 \"Acciones:\\n\"\n                 \"1. Mirar contactos\\n\"\n                 \"2. Buscar contactos\\n\"\n                 \"3. Añadir contactos\\n\"\n                 \"4. Eliminar contactos\\n\"\n                 \"5. Cerrar lista de contactos\");\n\n  while (!Serial.available()) {}\n\n  Serial.print(\"Elija según el índice: \");\n  delay(100);\n\n  int opcion = Serial.parseInt();\n\n  switch (opcion) {\n    case 1:\n      for (const Contacto &contacto : contactos) {\n        Serial.print(contacto.nombre);\n        Serial.print(\" -- \");\n        Serial.println(contacto.numero);\n      }\n      break;\n\n    case 2:\n      busqueda();\n      break;\n\n    case 3:\n      insercion();\n      break;\n\n    case 4:\n      eliminacion();\n      break;\n\n    case 5:\n      Serial.println(\"Programa finalizado\");\n      while (true) {}  // Detener aquí\n      break;\n\n    default:\n      Serial.println(\"No está en el índice.\");\n      break;\n  }\n}"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/bash/arturonavas.sh",
    "content": "#!/usr/bin/env bash\n: '\nejercicio:\n- muestra ejemplos de todas las estructuras soportadas por defecto en bash\n- utiliza operaciones de insercion, borrado, actualizacion y ordenacion\n\ndificultad extra (opcional):\n- agenda de contactos por terminal con busqueda, insercion, actualizacion, eliminacion\n- valido telefono solo numerico y maximo 11 digitos\n- menu con opcion de finalizacion\n'\n\n# estructuras de control basicas\n\n# if-elif-else\nejemplo_if() {\n  local n=\"$1\"\n  if (( n < 0 )); then\n    echo \"negativo\"\n  elif (( n == 0 )); then\n    echo \"cero\"\n  else\n    echo \"positivo\"\n  fi\n}\n\n# case\nejemplo_case() {\n  local letra=\"$1\"\n  case \"$letra\" in\n    [aeiou]) echo \"vocal\" ;;\n    *)        echo \"consonante\" ;;\n  esac\n}\n\n# for\nejemplo_for() {\n  for i in {1..3}; do\n    echo \"for i: $i\"\n  done\n}\n\n# while\nejemplo_while() {\n  local i=0\n  while (( i < 3 )); do\n    echo \"while i: $i\"\n    (( i++ ))\n  done\n}\n\n# until\nejemplo_until() {\n  local i=0\n  until (( i >= 3 )); do\n    echo \"until i: $i\"\n    (( i++ ))\n  done\n}\n\n# funciones y retorno\ncuadrado() {\n  echo \"$(( $1 * $1 ))\"\n}\n\n# operaciones sobre lista (array)\n\nlista=(3 1 4 1 5 9)\n\n# insercion\ninsertar_en_lista() {\n  lista+=(\"$1\")\n}\n\n# borrado (elimina todas las ocurrencias)\nborrar_de_lista() {\n  local val=\"$1\"\n  local nueva=()\n  for x in \"${lista[@]}\"; do\n    [[ $x -eq $val ]] || nueva+=(\"$x\")\n  done\n  lista=(\"${nueva[@]}\")\n}\n\n# actualizacion (sustituye primer coincidencia)\nactualizar_lista() {\n  local old=\"$1\" new=\"$2\"\n  for i in \"${!lista[@]}\"; do\n    if (( lista[i] == old )); then\n      lista[i]=\"$new\"\n      break\n    fi\n  done\n}\n\n# ordenacion\nordenar_lista() {\n  IFS=$'\\n' lista=($(sort -n <<<\"${lista[*]}\"))\n  unset IFS\n}\n\n# mostrar lista\nmostrar_lista() {\n  echo \"lista: ${lista[*]}\"\n}\n\n# agenda de contactos \n\ndeclare -A contactos\n\nvalidar_telefono() {\n  [[ $1 =~ ^[0-9]{1,11}$ ]]\n}\n\nagregar_contacto() {\n  read -r -p \"nombre: \" nombre\n  read -r -p \"telefono: \" tel\n  if validar_telefono \"$tel\"; then\n    contactos[\"$nombre\"]=\"$tel\"\n    echo \"contacto agregado\"\n  else\n    echo \"telefono invalido\"\n  fi\n}\n\nbuscar_contacto() {\n  read -r -p \"nombre a buscar: \" nombre\n  if [[ -v contactos[\"$nombre\"] ]]; then\n    echo \"$nombre: ${contactos[$nombre]}\"\n  else\n    echo \"contacto no encontrado\"\n  fi\n}\n\nactualizar_contacto() {\n  read -r -p \"nombre a actualizar: \" nombre\n  if [[ -v contactos[\"$nombre\"] ]]; then\n    read -r -p \"nuevo telefono: \" tel\n    if validar_telefono \"$tel\"; then\n      contactos[\"$nombre\"]=\"$tel\"\n      echo \"contacto actualizado\"\n    else\n      echo \"telefono invalido\"\n    fi\n  else\n    echo \"contacto no existe\"\n  fi\n}\n\neliminar_contacto() {\n  read -r -p \"nombre a eliminar: \" nombre\n  if [[ -v contactos[\"$nombre\"] ]]; then\n    unset contactos[\"$nombre\"]\n    echo \"contacto eliminado\"\n  else\n    echo \"contacto no existe\"\n  fi\n}\n\nlistar_contactos() {\n  echo \"contactos ordenados:\"\n  for nombre in \"${!contactos[@]}\"; do\n    echo \"$nombre ${contactos[$nombre]}\"\n  done | sort\n}\n\n# menu principal\n\nwhile true; do\n  echo \"::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\"\n  echo \"menu: agregar, buscar, actualizar, eliminar, listar, salir\"\n  read -r -p \"opcion: \" opcion\n  case \"$opcion\" in\n    agregar)    agregar_contacto  ;;\n    buscar)     buscar_contacto   ;;\n    actualizar) actualizar_contacto ;;\n    eliminar)   eliminar_contacto ;;\n    listar)     listar_contactos  ;;\n    salir)      echo \"salir\"; break ;;\n    *)          echo \"opcion invalida\" ;;\n  esac\ndone\n\necho \"fin del programa\"\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/bash/drvito1977.sh",
    "content": "#!/bin/bash\n\n# Ejemplos de estructuras en Bash\n\n# Arrays\n# Definición de un array con elementos iniciales\narray=(1 2 3 4 5)\n# Imprimir todos los elementos del array\necho \"Array original: ${array[@]}\"\n# Añadir un nuevo elemento al final del array\narray+=(6) # Inserción\n# Imprimir el array después de la inserción\necho \"Array después de inserción: ${array[@]}\"\n# Eliminar el tercer elemento del array (índice 2)\nunset array[2] # Borrado\n# Imprimir el array después del borrado\necho \"Array después de borrado: ${array[@]}\"\n# Actualizar el segundo elemento del array (índice 1) a 10\narray[1]=10 # Actualización\n# Imprimir el array después de la actualización\necho \"Array después de actualización: ${array[@]}\"\n# Ordenar el array y guardarlo en una nueva variable\nsorted_array=($(for i in \"${array[@]}\"; do echo $i; done | sort)) # Ordenación\n# Imprimir el array ordenado\necho \"Array ordenado: ${sorted_array[@]}\"\n\n# Arrays asociativos\n# Declarar un array asociativo\ndeclare -A assoc_array\n# Inicializar el array asociativo con pares clave-valor\nassoc_array=([key1]=value1 [key2]=value2)\n# Imprimir todos los valores del array asociativo\necho \"Array asociativo original: ${assoc_array[@]}\"\n# Añadir un nuevo par clave-valor al array asociativo\nassoc_array[key3]=value3 # Inserción\n# Imprimir el array asociativo después de la inserción\necho \"Array asociativo después de inserción: ${assoc_array[@]}\"\n# Eliminar un par clave-valor del array asociativo usando la clave\nunset assoc_array[key1] # Borrado\n# Imprimir el array asociativo después del borrado\necho \"Array asociativo después de borrado: ${assoc_array[@]}\"\n# Actualizar el valor asociado a una clave existente\nassoc_array[key2]=new_value # Actualización\n# Imprimir el array asociativo después de la actualización\necho \"Array asociativo después de actualización: ${assoc_array[@]}\"\n\n# Strings (cadenas de texto)\n# Definir una cadena de texto\nstring=\"Hola Mundo\"\n# Imprimir la cadena original\necho \"String original: $string\"\n# Añadir un carácter al final de la cadena\nstring+=\"!\" # Inserción\n# Imprimir la cadena después de la inserción\necho \"String después de inserción: $string\"\n# Eliminar parte de la cadena (mantener solo los primeros 4 caracteres)\nstring=${string:0:4} # Borrado\n# Imprimir la cadena después del borrado\necho \"String después de borrado: $string\"\n# Actualizar la cadena completa\nstring=\"Hola Bash\" # Actualización\n# Imprimir la cadena después de la actualización\necho \"String después de actualización: $string\"\n\n# Numbers (números)\n# Definir un número\nnum=5\n# Imprimir el número original\necho \"Número original: $num\"\n# Incrementar el número en 5\n((num+=5)) # Inserción (suma)\n# Imprimir el número después de la inserción\necho \"Número después de inserción: $num\"\n# Decrementar el número en 3\n((num-=3)) # Borrado (resta)\n# Imprimir el número después del borrado\necho \"Número después de borrado: $num\"\n# Actualizar el número a 10\nnum=10 # Actualización\n# Imprimir el número después de la actualización\necho \"Número después de actualización: $num\"\n\n# Agenda de contactos\ndeclare -A agenda\n\n# Declarar un array asociativo para la agenda de contactos\ndeclare -A agenda\n\n# Función para insertar un contacto\nfunction insertar_contacto {\n    # Pedir al usuario que ingrese el nombre del contacto\n    read -p \"Nombre: \" nombre\n    # Pedir al usuario que ingrese el número de teléfono del contacto\n    read -p \"Número de teléfono: \" telefono\n    # Validar que el número de teléfono sea numérico y tenga hasta 11 dígitos\n    if ! echo \"$telefono\" | grep -qE \"^[0-9]{1,11}$\"; then\n        # Si el número no es válido, mostrar un mensaje y salir de la función\n        echo \"Número de teléfono inválido.\"\n        return\n    fi\n    # Añadir el contacto a la agenda\n    agenda[$nombre]=$telefono\n    # Confirmar que el contacto ha sido añadido\n    echo \"Contacto añadido.\"\n}\n\n# Función para buscar un contacto\nfunction buscar_contacto {\n    # Pedir al usuario que ingrese el nombre del contacto a buscar\n    read -p \"Nombre: \" nombre\n    # Verificar si el contacto existe en la agenda\n    if [[ -z ${agenda[$nombre]} ]]; then\n        # Si no existe, mostrar un mensaje\n        echo \"Contacto no encontrado.\"\n    else\n        # Si existe, mostrar el número de teléfono del contacto\n        echo \"Teléfono de $nombre: ${agenda[$nombre]}\"\n    fi\n}\n\n# Función para actualizar un contacto\nfunction actualizar_contacto {\n    # Pedir al usuario que ingrese el nombre del contacto a actualizar\n    read -p \"Nombre: \" nombre\n    # Verificar si el contacto existe en la agenda\n    if [[ -z ${agenda[$nombre]} ]]; then\n        # Si no existe, mostrar un mensaje y salir de la función\n        echo \"Contacto no encontrado.\"\n        return\n    fi\n    # Pedir al usuario que ingrese el nuevo número de teléfono\n    read -p \"Nuevo número de teléfono: \" telefono\n    # Validar que el nuevo número de teléfono sea numérico y tenga hasta 11 dígitos\n    if ! echo \"$telefono\" | grep -qE \"^[0-9]{1,11}$\"; then\n        # Si el número no es válido, mostrar un mensaje y salir de la función\n        echo \"Número de teléfono inválido.\"\n        return\n    fi\n    # Actualizar el contacto en la agenda\n    agenda[$nombre]=$telefono\n    # Confirmar que el contacto ha sido actualizado\n    echo \"Contacto actualizado.\"\n}\n\n# Función para eliminar un contacto\nfunction eliminar_contacto {\n    # Pedir al usuario que ingrese el nombre del contacto a eliminar\n    read -p \"Nombre: \" nombre\n    # Verificar si el contacto existe en la agenda\n    if [[ -z ${agenda[$nombre]} ]]; then\n        # Si no existe, mostrar un mensaje y salir de la función\n        echo \"Contacto no encontrado.\"\n        return\n    fi\n    # Eliminar el contacto de la agenda\n    unset agenda[$nombre]\n    # Confirmar que el contacto ha sido eliminado\n    echo \"Contacto eliminado.\"\n}\n\n# Función para mostrar el menú de opciones\nfunction mostrar_menu {\n    # Mostrar las opciones disponibles al usuario\n    echo \"1. Insertar contacto\"\n    echo \"2. Buscar contacto\"\n    echo \"3. Actualizar contacto\"\n    echo \"4. Eliminar contacto\"\n    echo \"5. Salir\"\n}\n\n# Bucle principal para mostrar el menú y ejecutar las opciones seleccionadas\nwhile true; do\n    # Mostrar el menú de opciones\n    mostrar_menu\n    # Pedir al usuario que seleccione una opción\n    read -p \"Seleccione una opción: \" opcion\n    # Ejecutar la acción correspondiente a la opción seleccionada\n    case $opcion in\n        1) insertar_contacto ;;  # Llamar a la función para insertar un contacto\n        2) buscar_contacto ;;    # Llamar a la función para buscar un contacto\n        3) actualizar_contacto ;; # Llamar a la función para actualizar un contacto\n        4) eliminar_contacto ;;  # Llamar a la función para eliminar un contacto\n        5) break ;;              # Salir del bucle y terminar el programa\n        *) echo \"Opción inválida.\" ;; # Mostrar un mensaje si la opción no es válida\n    esac\ndone"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/bash/rantamhack.sh",
    "content": "\n#!/bin/bash\n\n\necho -e \"\\n\\n======================LISTAS - ARRAYS======================\\n\\n\"\n\n\n# ARRAYS- Se pueden declarar de varias formas. Asignado valores, mediante la palabra reservada \"declare\" con \"-a\"\n# Pueden hacerse de de cualquier tipo de datos incluso mezclandolos\n# Cuando un elemento tiene varios palabras para considerarlo como un solo elemento se pone entre comillas, dobles o simples\n\ndeclare -a array_strings\n\narray_strings=(Luis Mari­a Helena Pedro Ignacio 'Jose Maria' Zoe Candela)\necho ${array_strings[@]}\n# Para acceder a un elemento de la lista\necho ${array_strings[2]}\n# Para acceder al primer elemento se puede hacer de dos maneras\necho ${array_strings[0]}\necho ${array_strings}\n# Para ver cuantos elementos tiene un array\necho ${#array_strings[@]}\n# Para saber la longitud uno de los elemento\n# En este caso es el tercer elemento (Helena) nos devolvera un[6]\necho ${#array_strings[2]}\n# Los arrays pueden ser tanto de cadenas de texto, como de numeros como mixtos\narray_numbers=(3 7 52 4.5 9 8 8 8 7 5)\necho ${array_numbers[@]}\n\narray_mix=(3 7 'Jose Luis' Juan 92)\necho ${array_mix[@]}\n\n# Insercion \n# Podemos añadir elementos al array por el principio\narray_strings=(Isabel \"${array_strings[@]}\")\n# Tambien por el final\narray_strings=(\"${array_strings[@]}\" Isabel)\n# Incluso en la posicion que tu quieras\narray_strings=(\"${array_strings[@]:0:2}\" Isabel \"${array_strings[@]:3}\")\n\n# Borrado\n# Borrar un elemento\nunset array_strings[1]\narray_strings=(${array_strings[@]/Luis/})\n\n\necho -e \"\\n\\n======================DICCIONARIOS======================\\n\\n\"\n\n\n# Diccionarios - Tambien llamados Arrays asociativos. Es un elemento definido por pares\n# clave-valor. Para iniciarlos se usa la palabra clave \"declare\" con el parametro -A\n\ndeclare -A evaluation\nevaluation[Luis]='5'\nevaluation[Maria]='7.5' \nevaluation[Helena]='9' \nevaluation[Pedro]='3.8'\nevaluation[Ignacio]='2'\n\n# Para imprimir todos los valores de un diccionario tenemos dos opciones\necho ${evaluation[@]}\necho ${evaluation[*]}\n\n# Para imprimir todas las claves de un diccionario tambien tenemos dos opciones\necho ${!evaluation[@]}\necho ${!evaluation[*]}\n# Para imprimir un elemento\necho ${evaluation[Luis]}\n# Para imprimir varios elementos a la vez\necho ${evaluation[@]:1:2}\n# Para ver cuantos elementos tiene un diccionario\necho ${#evaluation[@]}\n\n# Insercion Se puede hacer en una linea o en varias como antes\nevaluation+=([Lola]=7 [Manuel]=8)\necho ${!evaluation[@]}\necho ${evaluation[*]}\n\n# Borrado  --para borrar todo el diccionario\nunset evaluation\n# Para borrar un elemento\nunset evaluation['Luis']  \necho ${!evaluation[@]}\n\n\necho -e \"\\n\\n======================DIFICULTAD EXTRA======================\\n\\n\"\n\n#!/bin/bash\n\ndeclare -A agenda\n\nagenda[Juan]='1111'\nagenda[Luis]='2222'\nagenda[Maria]='3333'\nagenda[Helena]='4444'\nagenda[Candela]='5555'\nagenda[Miguel]='6666'\nagenda[Jose]='7777'\nagenda[Isabel]='8888'\nagenda[Alberto]='99995'\n\necho ${agenda[@]}]    #Imprime los valores\necho ${#agenda[@]}    #Imprime el numero de componentes del diccionario\necho ${!agenda[@]}    #Imprime las keys\n\nfunction insert_contact(){\n    echo \"Escribe el nombre del nuevo contacto: \" && read -r name\n    echo \"Escribe el numero del contacto $name : \" && read -r number\n\n    if [ -v agenda[$name] ]; then\n        echo -e \"El contacto $name ya existe\"\n    else\n        echo -e \"El contacto $name no existe y se incorpora a la agenda\"\n        agenda[$name]=\"$number\"\n    fi\n  echo ${!agenda[@]}\n  echo ${agenda[@]}\n}\n\nfunction delete_contac(){\n    echo \"Escribe el nombre del contacto que quieres borrar: \" && read -r name\n\n    if [ -v agenda[$name] ]; then\n        unset agenda[$name]\n    else\n        echo -e \"El contacto $name no existe en la agenda\"\n    fi\n\n    echo ${!agenda[@]}\n    echo ${agenda[@]}\n}\n\nfunction find_contact(){\n    echo \"Escribe el nombre del contacto que quieres buscar: \" && read -r name\n    if [ -v agenda[$name] ]; then\n        echo \"El numero de $name es: \" ${agenda[$name]}\n    else\n\techo \"El contacto no estÃ¡ en la agenda\"\n    fi\n\n    echo ${!agenda[@]}\n    echo ${agenda[@]}\n}\n\nfunction update_contact(){\n    echo \"Escribe el nombre del contacto que deseas actualizar: \" && read -r name\n    echo \"Escribe el nuevo numero del contacto $name: \" && read -r new_number\n\n    if [ -v agenda[$name] ]; then\n        agenda[$name]=\"$new_number\"\n        echo  \"El contacto $name se ha actualizado\"\n    else\n        echo \"El contacto $name no existe y no se puede actualizar\n        si quieres añadirlo escoge la opcion adecuada\"\n    fi\n    echo ${!agenda[@]}\n    echo ${agenda[@]}\n}\n\n\noption=0\n\nwhile [ $option -ne 5 ];do\n    echo \" \"\n    echo \"Opciones de la agenda: \"\n    echo \"1) Añadir contacto a la agenda\"\n    echo \"2) Borrar un contacto de la agenda\"\n    echo \"3) Buscar un contacto en la agenda\"\n    echo \"4) Actualizar la agenda\"\n    echo \"5) Salir de la agenda\"\n    echo \n\n    read -p \"Elige la opcion de lo que deseas hacer: \" option\n\n    case $option in\n\n        1) insert_contact;;\n        2) delete_contac;;\n        3) find_contact;;\n        4) update_contact;;\n        5) break\n           echo \"[+] Saliendo de la agenda ....\";;\n        *) echo \"$option es una opcion no valida, por favor elige una valida\";;\n    esac \ndone\n\n\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/bash/santyjL.sh",
    "content": "#!/bin/bash\n\n# 03 ESTRUCTURAS DE DATOS\n#### Dificultad: Media | Publicación: 15/01/24 | Corrección: 22/01/24\n\n## Ejercicio\n\n: \"\n/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\"\n\n# Arrays\nfunction print_array() {\n    # Declarar un array\n    declare -a array_strings=(\"hola\" \"bash\" \"python\" \"javascript\" \"c++\")\n    echo -e \"\\nArray inicial: ${array_strings[@]}\"\n\n    # Añadir elementos al array\n    array_strings+=(\"java\" \"c#\")\n    echo -e \"\\nArray tras añadir elementos: ${array_strings[@]}\"\n\n    # Añadir un elemento al principio del array\n    array_strings=(\"Go\" \"${array_strings[@]}\")\n    echo -e \"\\nArray tras añadir un elemento al principio: ${array_strings[@]}\"\n\n    # Insertar un elemento en una posición específica\n    array_strings=(${array_strings[@]:0:4} \"Rust\" ${array_strings[@]:5})\n    echo -e \"\\nArray tras insertar 'Rust': ${array_strings[@]}\"\n\n    # Mostrar un elemento específico del array\n    echo -e \"\\nPrimer elemento-segundo valor: ${array_strings[1]}\"\n\n    # Mostrar el número de elementos en el array\n    echo -e \"\\nNúmero de elementos en el array: ${#array_strings[@]}\"\n\n    # Actualizar un elemento del array\n    array_strings[2]=\"bash2\"\n    echo -e \"\\nArray tras actualizar un elemento: ${array_strings[@]}\"\n\n    # Eliminar un valor del array\n    unset array_strings[2]\n    echo -e \"\\nArray tras eliminar un elemento: ${array_strings[@]}\"\n\n    # Reindexar el array tras eliminar un elemento\n    array_strings=(\"${array_strings[@]}\")\n    echo -e \"\\nArray tras reindexar: ${array_strings[@]}\"\n}\n\n# Diccionarios\nfunction print_dictionary() {\n    # Declarar un diccionario\n    declare -A evaluation\n    evaluation[Luis]='5'\n    evaluation[Maria]='7.5'\n    evaluation[Helena]='9'\n    evaluation[Pedro]='3.8'\n    evaluation[Ignacio]='2'\n\n    # Mostrar todos los valores del diccionario\n    echo -e \"\\nDiccionario: ${evaluation[@]}\"\n\n    # Mostrar todas las claves del diccionario\n    echo -e \"\\nClaves del diccionario: ${!evaluation[@]}\"\n\n    # Mostrar un valor específico\n    echo -e \"\\nNota de Maria: ${evaluation[Maria]}\"\n\n    # Actualizar un valor\n    evaluation[Pedro]='6.5'\n    echo -e \"\\nDiccionario tras actualizar la nota de Pedro: ${evaluation[@]}\"\n\n    # Eliminar un elemento del diccionario\n    unset evaluation[Ignacio]\n    echo -e \"\\nDiccionario tras eliminar a Ignacio: ${evaluation[@]}\"\n}\n\n# Llamar a las funciones\nprint_array\nprint_dictionary\n\necho -e \"\\n======================Extra======================\\n\"\n\n# Agenda de contactos (pendiente de implementación)\n\ndeclare -A contacto\n\nfunction inserción() {\n    nombre=$1\n    numero=$2\n\n    contacto[\"$nombre\"]=\"$numero\"\n    echo \"se ha agregado a ${nombre}  a la lista de contactos\"\n}\n\nfunction busqueda() {\n    nombre=$1\n\n    for usuario in \"${!contacto[@]}\"; do\n        if [ \"$usuario\" == \"$nombre\" ]; then\n            echo \"Contacto encontrado: $nombre - ${contacto[$nombre]}\"\n            return 1\n        fi\n    done\n\n    echo \"Contacto no encontrado: $nombre\"\n    return 0\n}\n\nfunction actualización() {\n    nombre=$1\n    nuevo_numero=$2\n\n    busqueda $nombre\n    if [ $? -eq 1 ]; then\n        contacto[\"$nombre\"]=\"$nuevo_numero\"\n        echo \"Número de teléfono de $nombre actualizado a $nuevo_numero\"\n        return\n    fi\n\n    echo \"el contacto que desea cambiar no existe\"\n\n}\n\nfunction eliminación() {\n    nombre=$1\n\n    busqueda $nombre\n    if [ $? -eq 1 ]; then\n        unset contacto[\"$nombre\"]\n        echo \"Contacto $nombre eliminado.\"\n    else\n        echo \"Contacto no encontrado: $nombre\"\n    fi\n}\n\nwhile [[ 1 -eq 1 ]]; do\n    echo \" \"\n    echo \"Opciones de la agenda: \"\n    echo \"0) revisar contactos\"\n    echo \"1) Añadir contacto a la agenda\"\n    echo \"2) Borrar un contacto de la agenda\"\n    echo \"3) Buscar un contacto en la agenda\"\n    echo \"4) Actualizar la agenda\"\n    echo \"5) Salir de la agenda\"\n    echo\n\n    read -p \"Elige la opción de lo que deseas hacer: \" opcion\n\n    if [ \"$opcion\" == \"0\" ]; then\n        echo \"Contactos en la agenda:\"\n        if [[ ${#contacto[@]} > 0 ]]; then\n            for usuario in \"${!contacto[@]}\"; do\n                echo \"$usuario - ${contacto[$usuario]}\"\n            done\n        fi\n\n    elif [ \"$opcion\" == \"1\" ]; then\n        read -p \"Introduce el nombre del contacto: \" nombre\n        read -p \"Introduce el número del contacto: \" numero\n        if [[ \"$numero\" =~ ^[0-9]{1,11}$ ]]; then\n            inserción \"$nombre\" \"$numero\"\n        else\n            echo \"El número debe ser numérico y tener como máximo 11 dígitos.\"\n        fi\n\n    elif [ \"$opcion\" == \"2\" ]; then\n        read -p \"Introduce el nombre del contacto a eliminar: \" nombre\n        eliminación \"$nombre\"\n\n    elif [ \"$opcion\" == \"3\" ]; then\n        read -p \"Introduce el nombre del contacto a buscar: \" nombre\n        busqueda \"$nombre\"\n\n    elif [ \"$opcion\" == \"4\" ]; then\n        read -p \"Introduce el nombre del contacto a actualizar: \" nombre\n        read -p \"Introduce el nuevo número del contacto: \" nuevo_numero\n        if [[ \"$nuevo_numero\" =~ ^[0-9]{1,11}$ ]]; then\n            actualización \"$nombre\" \"$nuevo_numero\"\n        else\n            echo \"El número debe ser numérico y tener como máximo 11 dígitos.\"\n        fi\n\n    elif [ \"$opcion\" == \"5\" ]; then\n        echo \"Saliendo de la agenda...\"\n        break\n\n    else\n        echo \"Opción no válida. Por favor, elige una opción entre 1 y 5.\"\n    fi\ndone"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/c/04khaos.c",
    "content": "#include <ctype.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n// Prototipos de funciones para las estructuras de datos\nvoid arrays();\nvoid structs();\nvoid linkedlists();\nvoid queue();\nvoid stacks();\n\n// Definición global de la estructura node\ntypedef struct node {\n    int number;\n    struct node* next;\n} node;\n\n// Variables globales para las colas (First In, First Out)\nnode *front = NULL; // Apunta al primer elemento de la cola (First to dequeue)\nnode *rear = NULL;  // Apunta al último elemento de la cola (Recently enqueue add)\n\n// Variables globales para las pilas (Last In, First Out)\nnode* top = NULL;   // Apunta al tope de la pila (Last element added)\n\n// Prototipos de funciones para las colas \nvoid enqueue(int value);\nvoid dequeue();\nvoid displayqueue();\n\n// Prototipos de funciones para las pilas \nvoid push(int value);\nvoid pop();\nvoid displaystack();\n\n\n// DIFICULTAD EXTRA\n\n#define MAX_CONTACTS 100\n#define MAX_NAME 50\n#define MAX_PHONE 12\n\ntypedef struct {\n    char name[MAX_NAME];\n    char phone[MAX_PHONE];\n} contacts;\n\ncontacts *contact = NULL;\nint contactCount = 0;\n\nvoid displaymenu();\nint validatePhone(const char *phone);\nvoid addContact();\nvoid searchContact();\nvoid updateContact();\nvoid deleteContact();\nvoid displayContact();\n\n\nint main() {\n\n    printf(\"\\n== Basic Structures ==\");\n\n    printf(\"\\n1. Arrays\\n\");\n    arrays();\n\n    printf(\"\\n\\n2. Structs\\n\");\n    structs();\n\n    printf(\"\\n3. Linked Lists\\n\");\n    linkedlists();\n\n    printf(\"\\n4. Queue\\n\");\n    queue();\n\n    printf(\"\\n5. Stacks\\n\");\n    stacks();\n\n    printf(\"\\n== Extra Difficulty ==\\n\");\n\n    int option;\n    do {\n        displaymenu();\n\n        (scanf(\"%d\", &option));\n        getchar();\n        switch (option) {\n            case 1:\n                searchContact();\n                break;\n            case 2:\n                addContact();\n                while (getchar() != '\\n'); // Limpiar buffer\n                break;\n            case 3:\n                updateContact();\n                while (getchar() != '\\n');\n                break;\n            case 4:\n                deleteContact();\n                break;\n            case 5:\n                displayContact();\n                break;\n            case 6:\n                printf(\"Exiting the program...\\n\\n\");\n                break;\n            default:\n                printf(\"Invalid option. Please try again\\n\\n\");\n        }\n    } while (option != 6);\n\n    free(contact);\n    return 0;\n}\n\n\nvoid arrays() {\n\n    // Creación de un array simple de enteros\n    int arr[10] = {10, 4, 3, 6, 1, 8};\n    int size = 6;\n\n    printf(\"Initial array: \");\n    for (int i = 0; i < size; i++) {\n        printf(\"%d \", arr[i]);\n    }\n\n    // Inserción de un elemento\n    if (size < 10) {\n        arr[size] = 5;\n        size++;\n    }\n\n    // Actualización de un elemento\n    printf(\"\\nUpdated array: \");\n    arr[2] = 0;\n    for (int i = 0; i < size; i++) {\n        printf(\"%d \", arr[i]);\n    }\n\n    // Eliminación de un elemento\n    for (int i = 0; i < size; i++) {\n        arr[i] = arr[i + 1];\n    }\n    size--;\n\n    // Bubble sort\n    for (int i = 0; i < size - 1; i++) {\n        for (int j = 0; j < size - i - 1; j++) {\n            if (arr[j] > arr[j + 1]) {\n                int temp = arr[j];\n                arr[j] = arr[j + 1];\n                arr[j + 1] = temp;\n            }\n        }\n    }\n\n    printf(\"\\nFinal array: \");\n    for (int i = 0; i < size; i++) {\n        printf(\"%d \", arr[i]);\n    }\n\n}\n\n\nvoid structs() {\n\n    typedef struct {\n        char name[20];\n        int age;\n    } persons;\n\n    persons person[3] = {\n        {\"Gregory\", 45},\n        {\"Wilson\", 38},\n        {\"Alice\", 20},\n    };\n\n    for (int i = 0; i < 3; i++) {\n        printf(\"1. Name: %s, %d years old\\n\", person[i].name, person[i].age);\n    }\n}\n\n\nvoid linkedlists() {\n\n    node *list = NULL;\n\n    // Crear y agregar nodos a la lista\n    for (int i = 0; i < 3; i++) {\n        node *n = malloc(sizeof(node));\n        if (n == NULL) {\n            return;\n        }\n\n        n->number = i+1;\n        n->next = list;\n        list = n;\n    }\n\n    // Imprimir la lista\n    node *ptr = list;\n    while (ptr != NULL) {\n        printf(\"%d -> \", ptr->number);\n        ptr = ptr->next;\n    }\n    printf(\"NULL\\n\");\n\n\n    // Liberar memoria\n    node *temp;\n    while(list != NULL) {\n        temp = list;\n        list = list->next;\n        free(temp);\n    }\n}\n\n\nvoid queue() {\n\n    // Estado inicial de la cola\n    printf(\"Initial state: \");\n    displayqueue();\n\n    // Añadir elementos a la cola\n    printf(\"Enqueue all: \");\n    enqueue(10);\n    enqueue(20);\n    enqueue(30);\n    displayqueue();\n\n    // Eliminar un elemento de la cola\n    printf(\"Dequeue one: \");\n    dequeue();\n    displayqueue();\n\n    // Añadir un elemento a la cola\n    printf(\"Enqueue one: \");\n    enqueue(40);\n    displayqueue();\n\n    // Eliminar todos los elementos de la cola\n    printf(\"Dequeue all: \");\n    while (front != NULL) {\n        dequeue();\n    }\n    displayqueue();\n}\n\nvoid enqueue(int value) {\n    node* newNode = malloc(sizeof(node));\n    if (newNode == NULL) {\n        printf(\"Memory allocation failed\\n\");\n        return;\n    }\n\n    newNode->number = value;      // Asignar el valor al nuevo nodo\n    newNode->next = NULL;         // El nuevo nodo no tiene siguiente\n\n    if (rear == NULL) {\n        front = rear = newNode;   // Si la cola esta vacia, el nuevo nodo es el primero y el último\n    } else {\n        rear->next = newNode;     // El último nodo apunta al nuevo\n        rear = newNode;           // El nuevo nodo ahora es el último \n    }\n}\n\nvoid dequeue() {\n    if (front == NULL) {\n        printf(\"Error: The queue is empty\\n\");\n    }\n\n    node *temp = front;           // Guardar el nodo que se eliminará (el primero, o sea 10)\n\n    front = front->next;          // Mover al frente el siguiente nodo (el siguiente, o sea 20)\n    if (front == NULL) {\n        rear = NULL;              // Si la cola quedó vacía, también actualizamos rear\n    }\n\n    free(temp);                   // Liberar la memoria del nodo eliminado\n}\n\nvoid displayqueue() {\n    if (front == NULL) {\n        printf(\"The queue is empty\\n\");\n        return;\n    }\n\n    node *ptr = front;            // Puntero temporal para recorrer la cola\n    while (ptr != NULL) {         // Recorrer la cola y mostrar el valor actual \n        printf(\"%d -> \", ptr->number);\n        ptr = ptr->next;          // Mover al siguiente nodo\n    }\n    printf(\"NULL\\n\");\n}\n\n\nvoid stacks() {\n\n    printf(\"Initial state: \");\n    displaystack();\n\n    printf(\"Push elements: \");\n    push(100);\n    push(200);\n    push(300);\n    displaystack();\n\n    printf(\"Pop one element: \");\n    pop();\n    displaystack();\n\n    printf(\"Pop all elements: \");\n    while (top != NULL) {\n        pop();\n    }\n    displaystack();\n}\n\nvoid push(int value) {\n    node *newNode = malloc(sizeof(node));\n    if (newNode == NULL) {\n        printf(\"Memory allocation failed\\n\");\n        return;\n    }\n\n    newNode->number = value;            // Asignar el valor al nuevo nodo\n    newNode->next = top;                // El nuevo nodo apunta al tope actual\n    top = newNode;                      // El nuevo nodo es ahora el tope\n}\n\nvoid pop() {\n    if (top == NULL) {\n        printf(\"Error: The stacks is empty\\n\");\n        return;\n    }\n\n    node *temp = top;                   // Guardar el nodo que se eliminará\n    top = top->next;                    // Mover el tope al siguiente nodo\n\n    free(temp);                         // Liberar la memoria del nodo eliminado\n}\n\nvoid displaystack() {\n    if (top == NULL) {\n        printf(\"The stacks is empty\\n\");\n        return;\n    }\n\n    node *ptr = top;\n    while(ptr != NULL) {\n        printf(\"%d -> \", ptr->number);\n        ptr = ptr->next;\n    }   \n    printf(\"NULL\\n\");\n}\n\n\n// FUNCIONES DE LA DIFICULTAD EXTRA \n\nvoid displaymenu() {\n\n    printf(\"\\n1. Search contact\\n\");\n    printf(\"2. Add contact\\n\");\n    printf(\"3. Update contact\\n\");\n    printf(\"4. Delete contact\\n\");\n    printf(\"5. Display contacts\\n\");\n    printf(\"6. Exit\\n\");\n    printf(\"Option: \");\n}\n\nint validatePhone(const char *phone) {\n\n    if (strlen(phone) != 11) {\n        return 0;\n    }\n\n    for (int i = 0; i < 11; i++) {\n        if(!isdigit(phone[i])) {\n            return 0;\n        }\n    }\n\n    return 1;\n}\n\n\nvoid addContact() {\n\n    if (contactCount >= MAX_CONTACTS) {\n        printf(\"The contact list is full\");\n        return;\n    }\n\n    contacts newContact;\n\n    printf(\"Enter contact name: \");\n    fgets(newContact.name, sizeof(newContact.name), stdin);\n    newContact.name[strcspn(newContact.name, \"\\n\")] = '\\0';\n\n    if (strlen(newContact.name) == 0) {\n        printf(\"Error: The contact name cannot be empty\\n\");\n        return;\n    }\n\n    printf(\"Enter phone number (11 digits): \");\n    fgets(newContact.phone, sizeof(newContact.phone), stdin);\n    newContact.phone[strcspn(newContact.phone, \"\\n\")] = '\\0';\n\n    if (!validatePhone(newContact.phone)) {\n        printf(\"Error: Invalid phone number\\n\");\n        return;\n    }\n\n    contact = realloc(contact, (contactCount + 1) * sizeof(contacts));\n    if (contact == NULL) {\n        printf(\"Memory allocation failed\\n\");\n        return;\n    }\n\n    contact[contactCount] = newContact;\n    contactCount++;\n\n    printf(\"Contact added successfully\\n\");\n}\n\nvoid searchContact() {\n    char query[MAX_NAME];\n    printf(\"Contact name or phone to search: \");\n    fgets(query, sizeof(query), stdin);\n    query[strcspn(query, \"\\n\")] = '\\0';\n\n    for (int i = 0; i < contactCount; i++) {\n        if (strcmp(query, contact[i].name) == 0 || strcmp(query, contact[i].phone) == 0) {\n            printf(\"Contact found: (%d) %s, +%s\\n\", i+1, contact[i].name, contact[i].phone);\n            return;\n        }\n    }\n\n    printf(\"Contact not found\\n\\n\");\n}\n\nvoid updateContact() {\n    char query[MAX_NAME];\n    printf(\"Enter a name or phone to update contact: \");\n    fgets(query, sizeof(query), stdin);\n    query[strcspn(query, \"\\n\")] = '\\0';\n\n    for (int i = 0; i < contactCount; i++) {\n        if (strcmp(contact[i].name, query) == 0 || strcmp(contact[i].phone, query) == 0) {\n            printf(\"-> Leave blank to make no changes <-\\n\");\n\n            // Actualizar nombre o dejar en blanco\n            printf(\"New name: \");\n            char newName[MAX_NAME];\n            fgets(newName, sizeof(newName), stdin);\n            newName[strcspn(newName, \"\\n\")] = '\\0';\n\n            if (strlen(newName) > 0) {\n                strcpy(contact[i].name, newName);\n            }\n\n            // Actualizar número o dejar en blanco\n            printf(\"New phone: \");\n            char newPhone[MAX_PHONE];\n            fgets(newPhone, sizeof(newPhone), stdin);\n            newPhone[strcspn(newPhone, \"\\n\")] = '\\0';\n\n            if (strlen(newPhone) > 0) {\n                if (!validatePhone(newPhone)) {\n                    printf(\"Error: Invalid phone number.\\n\");\n                    return;\n                }\n                strcpy(contact[i].phone, newPhone);\n            }\n\n            printf(\"Contact update successfully\\n\");\n            return;\n        }\n    }\n\n    printf(\"Contact not found\\n\");\n}\n\nvoid deleteContact() {\n    if (contactCount == 0) {\n        printf(\"No contacts to delete\\n\");\n        return;\n    }\n\n    char query[MAX_NAME];\n    printf(\"Contact name or phone to delete: \");\n    fgets(query, sizeof(query), stdin);\n    query[strcspn(query, \"\\n\")] = '\\0';\n\n    int found = 0;\n\n    for (int i = 0; i < contactCount; i++) {\n        if (strcmp(contact[i].name, query) == 0 || strcmp(contact[i].phone, query) == 0) {\n            for (int j = i; j < contactCount - 1; j++) {\n                contact[j] = contact[j+1];\n            }\n            found = 1;\n            contactCount--;\n            break;\n        } \n    }\n\n    if (!found) {\n        printf(\"Contact not found\\n\");\n        return;\n    }\n\n    // Si ya no hay contactos, liberar la memoria\n    if (contactCount == 0) {\n        free(contact);\n        contact = NULL;\n    } else {\n        contacts *temp = realloc(contact, contactCount * sizeof(contacts)); // Redimensionar la memoria reservada para contact de acuerdo con el nuevo contactCount\n        if (temp == NULL) {\n            printf(\"Memory allocation failed\\n\");\n            return;\n        }\n        contact = temp;\n    } \n\n    printf(\"Contact delete successful\\n\");\n}\n\nvoid displayContact() {\n    if (contactCount == 0) {\n        printf(\"No contacts found (Press enter)\\n\");\n        return;\n    }\n\n    printf(\"\\n------ Contact list ------\\n\");\n    for(int i = 0; i < contactCount; i++) {\n        printf(\"(%d) %s, +%s\\n\", i+1, contact[i].name, contact[i].phone);\n    }\n    printf(\"-------- (%d/%d) --------\\n\", contactCount, MAX_CONTACTS);\n}"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/c/N0HagoNada.c",
    "content": "#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n// RETO\n#define MAX_CONTACTOS 100\n#define MAX_NOMBRE 50\n#define MAX_TELEFONO 12\n\ntypedef struct\n{\n    char nombre[MAX_NOMBRE];\n    char telefono[MAX_TELEFONO];\n} Contacto;\n\nContacto agenda[MAX_CONTACTOS];\nint totalContactos = 0;\n\nvoid insertarContacto()\n{\n    if (totalContactos >= MAX_CONTACTOS)\n    {\n        printf(\"Agenda llena.\\n\");\n        return;\n    }\n\n    printf(\"Introduce el nombre del contacto: \");\n    scanf(\"%s\", agenda[totalContactos].nombre);\n\n    char telefono[MAX_TELEFONO];\n    printf(\"Introduce el número de telefono (hasta 11 dígitos): \");\n    scanf(\"%s\", telefono);\n\n    // Validar longitud y que sean solo dígitos\n    if (strlen(telefono) > 11)\n    {\n        printf(\"Numero invalido. Demasiados dígitos.\\n\");\n        return;\n    }\n\n    strcpy(agenda[totalContactos].telefono, telefono);\n    totalContactos++;\n    printf(\"Contacto añadido.\\n\");\n}\n\nvoid buscarContacto()\n{\n    char nombre[MAX_NOMBRE];\n    printf(\"Introduce el nombre del contacto a buscar: \");\n    scanf(\"%s\", nombre);\n\n    for (int i = 0; i < totalContactos; i++)\n    {\n        if (strcmp(agenda[i].nombre, nombre) == 0)\n        {\n            printf(\"Contacto encontrado: %s, Telefono: %s\\n\", agenda[i].nombre, agenda[i].telefono);\n            return;\n        }\n    }\n    printf(\"Contacto no encontrado.\\n\");\n}\n\nvoid actualizarContacto()\n{\n    char nombre[MAX_NOMBRE];\n    printf(\"Introduce el nombre del contacto a actualizar: \");\n    scanf(\"%s\", nombre);\n\n    for (int i = 0; i < totalContactos; i++)\n    {\n        if (strcmp(agenda[i].nombre, nombre) == 0)\n        {\n            printf(\"Introduce el nuevo número de telefono: \");\n            scanf(\"%s\", agenda[i].telefono);\n            printf(\"Contacto actualizado.\\n\");\n            return;\n        }\n    }\n    printf(\"Contacto no encontrado.\\n\");\n}\n\nvoid eliminarContacto()\n{\n    char nombre[MAX_NOMBRE];\n    printf(\"Introduce el nombre del contacto a eliminar: \");\n    scanf(\"%s\", nombre);\n\n    for (int i = 0; i < totalContactos; i++)\n    {\n        if (strcmp(agenda[i].nombre, nombre) == 0)\n        {\n            for (int j = i; j < totalContactos - 1; j++)\n            {\n                agenda[j] = agenda[j + 1];\n            }\n            totalContactos--;\n            printf(\"Contacto eliminado.\\n\");\n            return;\n        }\n    }\n    printf(\"Contacto no encontrado.\\n\");\n}\n// Definición de la estructura Persona\ntypedef struct\n{\n    int id;\n    char nombre[50];\n} Persona;\n\n// Definición de la estructura Nodo para la lista enlazada\ntypedef struct Nodo\n{\n    int dato;\n    struct Nodo *siguiente;\n} Nodo;\n\n// Funciones para la lista enlazada\nvoid insertarInicio(Nodo **cabeza, int nuevoDato)\n{\n    Nodo *nuevoNodo = (Nodo *)malloc(sizeof(Nodo));\n    nuevoNodo->dato = nuevoDato;\n    nuevoNodo->siguiente = *cabeza;\n    *cabeza = nuevoNodo;\n}\n\nvoid borrarInicio(Nodo **cabeza)\n{\n    if (*cabeza != NULL)\n    {\n        Nodo *temp = *cabeza;\n        *cabeza = (*cabeza)->siguiente;\n        free(temp);\n    }\n}\n\nvoid imprimirLista(Nodo *n)\n{\n    while (n != NULL)\n    {\n        printf(\"%d \", n->dato);\n        n = n->siguiente;\n    }\n    printf(\"\\n\");\n}\n\nint main()\n{\n    // Arrays\n    int numeros[5] = {1, 2, 3, 4, 5};\n    numeros[2] = 30; // Actualización\n    // Ordenación simplificada\n    for (int i = 0; i < 4; i++)\n    {\n        for (int j = i + 1; j < 5; j++)\n        {\n            if (numeros[i] > numeros[j])\n            {\n                int temp = numeros[i];\n                numeros[i] = numeros[j];\n                numeros[j] = temp;\n            }\n        }\n    }\n    for (int i = 0; i < 5; i++)\n    {\n        printf(\"%d \", numeros[i]);\n    }\n    printf(\"\\n\");\n\n    // Struct\n    Persona persona1;\n    persona1.id = 1;\n    strcpy(persona1.nombre, \"Juan\");\n    persona1.id = 2; // Actualización\n    printf(\"ID: %d, Nombre: %s\\n\", persona1.id, persona1.nombre);\n\n    // Lista enlazada\n    Nodo *cabeza = NULL;\n    insertarInicio(&cabeza, 10);\n    insertarInicio(&cabeza, 20);\n    imprimirLista(cabeza);\n    borrarInicio(&cabeza);\n    imprimirLista(cabeza);\n    /********************************************RETO*****************************************************/\n    int opcion;\n\n    do\n    {\n        printf(\"\\nAgenda de contactos\\n\");\n        printf(\"1. Insertar contacto\\n\");\n        printf(\"2. Buscar contacto\\n\");\n        printf(\"3. Actualizar contacto\\n\");\n        printf(\"4. Eliminar contacto\\n\");\n        printf(\"5. Salir\\n\");\n        printf(\"Selecciona una opción: \");\n        scanf(\"%d\", &opcion);\n\n        switch (opcion)\n        {\n        case 1:\n            insertarContacto();\n            break;\n        case 2:\n            buscarContacto();\n            break;\n        case 3:\n            actualizarContacto();\n            break;\n        case 4:\n            eliminarContacto();\n            break;\n        case 5:\n            printf(\"Saliendo...\\n\");\n            break;\n        default:\n            printf(\"Opción invalida.\\n\");\n        }\n    } while (opcion != 5);\n\n    return 0;\n}"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/c/SoMaxB.c",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/c/d1d4cum.c",
    "content": "#include <stddef.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdbool.h>\n#include <stdlib.h>\n#include <string.h>\n\n/*\n//---------------- Array\nint numbers[] = {0, 1, 2, 3, 4, 5};\n\n// Acceder a un elemento\nprintf(\"%d\\n\", numbers[2]);\n\n// Cambiar un elemento\nnumbers[2] = 7;\nprintf(\"%d\\n\", numbers[2]);\n\n// Iterar\nprintf(\"{\");\nfor (int i = 0; i < 6; i++) {\n    printf(\"%d, \", numbers[i]);\n}\nprintf(\"}\\n\");\n\n// Iniciar con tamaño fijo\nint fourNumbers[4];\nfourNumbers[0] = 0;\nfourNumbers[1] = 1;\nfourNumbers[2] = 2;\nfourNumbers[3] = 3;\n\n// Tamaño del array\nint length = sizeof(fourNumbers) / sizeof(fourNumbers[0]);\nprintf(\"%d\\n\", length);\n\n//Multidimensional\nint matrix[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};\n\nfor (int i = 0; i < 3; i++) {\n\n    for (int j = 0; j < 3; j++) {\n        printf(\"%d, \", matrix[i][j]);\n    }\n    printf(\"\\n\");\n}\n\n//------------------ Structs\nstruct myStructure {\n    int number;\n    char character;\n};\n\nstruct myStructure s1;\ns1.character = 'A';\ns1.number = 10;\nprintf(\"%c\\n\", s1.character);\nprintf(\"%d\\n\", s1.number);\n\n//------------- Enumeration\nenum Level {\n    LOW,\n    MEDIUM,\n    HIGH\n};\n\n\nenum Level {\n    LOW = 25,\n    MEDIUM = 50,\n    HIGH = 75\n};\n\nenum Level myLevel1 = LOW;\nenum Level myLevel2 = MEDIUM;\nenum Level myLevel3 = HIGH;\nprintf(\"%d\\n\", myLevel1);\nprintf(\"%d\\n\", myLevel2);\nprintf(\"%d\\n\", myLevel3);\n*/\n\n#define MAX_CONTACTS 100\n#define MAX_NAME_LENGTH 100\n\nstruct Contact {\n    int number;\n    char name[MAX_NAME_LENGTH];\n};\n\nstruct Contact contacts[MAX_CONTACTS];\nint contactCount = 0;\n\nvoid clearInputBuffer() {\n    int c;\n    while ((c = getchar()) != '\\n' && c != EOF);\n}\n\nvoid removeElement(struct Contact arr[], int index) {\n       if (index < 0 || index >= MAX_CONTACTS) {\n           printf(\"Índice fuera de rango\\n\");\n           return;\n       }\n\n       // Desplazar los elementos posteriores hacia adelante\n       for (int i = index; i < MAX_CONTACTS - 1; i++) {\n           arr[i] = arr[i + 1];\n       }\n\n       // Inicializar el último elemento a valores predeterminados\n       arr[contactCount - 1].number = 0;\n       arr[contactCount - 1].name[0] = '\\0';\n\n       contactCount--;\n   }\n\nstruct Contact search() {\n    char contactName[MAX_NAME_LENGTH];\n    struct Contact contact = {0, \"\"};\n\n    clearInputBuffer();\n\n    printf(\"\\nIntroduce el nombre del contacto: \");\n    if (fgets(contactName, sizeof(contactName), stdin) == NULL) {\n        fprintf(stderr, \"\\nError al leer el nombre\\n\");\n    }\n\n    // Eliminar el carácter de nueva línea al final de la cadena\n    size_t len = strlen(contactName);\n    if (len > 0 && contactName[len - 1] == '\\n') {\n        contactName[len - 1] = '\\0';\n    }\n\n    for (int i = 0; i < MAX_CONTACTS; i++) {\n        if (strcmp(contacts[i].name, contactName) == 0) {\n            contact = contacts[i];\n            break;\n        }\n    }\n\n    return contact;\n}\n\nint addContact() {\n    if (contactCount >= MAX_CONTACTS) {\n        fprintf(stderr, \"\\nNo se pueden añadir más contactos\\n\");\n        return 1;\n    }\n\n    struct Contact contact;\n    char contactName[MAX_NAME_LENGTH];\n    int contactNumber;\n\n    clearInputBuffer();\n\n    printf(\"\\nIntroduce el nombre del contacto: \");\n    if (fgets(contactName, sizeof(contactName), stdin) == NULL) {\n        fprintf(stderr, \"\\nError al leer el nombre\\n\");\n        return 1;\n    }\n\n    // Eliminar el carácter de nueva línea al final de la cadena\n    size_t len = strlen(contactName);\n    if (len > 0 && contactName[len - 1] == '\\n') {\n        contactName[len - 1] = '\\0';\n    }\n\n    // Solicitar el número del contacto\n    printf(\"Introduce el número del contacto: \");\n    if (scanf(\"%d\", &contactNumber) != 1) {\n        fprintf(stderr, \"\\nError al leer el número\\n\");\n        clearInputBuffer();\n        return 1;\n    }\n\n    strcpy(contact.name, contactName);\n    contact.number = contactNumber;\n\n    contacts[contactCount++] = contact;\n    printf(\"Contacto añadido correctamente\\n\");\n\n    return 0;\n}\n\nint update() {\n    int contactNumber;\n    struct Contact contact = search();\n\n    // Solicitar el nuevo número del contacto\n    printf(\"Introduce el nuevo número del contacto: \");\n    if (scanf(\"%d\", &contactNumber) != 1) {\n        fprintf(stderr, \"\\nError al leer el número\\n\");\n        clearInputBuffer();\n        return 1;\n    }\n\n    if (contact.number) {\n        for (int i = 0; i < MAX_CONTACTS; i++) {\n            if (strcmp(contacts[i].name, contact.name) == 0) {\n                contacts[i].number = contactNumber;\n                printf(\"Contacto actualizado\\n\");\n                break;\n            }\n        }\n    } else {\n        printf(\"El contacto no existe\\n\");\n    }\n\n    return 0;\n}\n\nint removeContact() {\n    struct Contact contact = search();\n\n    if (contact.number) {\n        for (int i = 0; i < MAX_CONTACTS; i++) {\n            if (strcmp(contacts[i].name, contact.name) == 0) {\n                removeElement(contacts, i);\n                printf(\"Contacto eliminado\\n\");\n                break;\n            }\n        }\n    } else {\n        printf(\"El contacto no existe\\n\");\n    }\n\n    return 0;\n}\n\nint main() {\n\n    int choice;\n    bool finish = false;\n    struct Contact contact;\n\n    while (!finish) {\n        printf(\"\\nQué dese hacer?:\\n\");\n        printf(\"1- Buscar\\n\");\n        printf(\"2- Añadir\\n\");\n        printf(\"3- Actualizar\\n\");\n        printf(\"4- Eliminar\\n\");\n        printf(\"5- Salir\\n\");\n\n        if (scanf(\"%d\", &choice) != 1) {\n            fprintf(stderr, \"\\n⚠️ Opción incorrecta\\n\");\n        }\n\n        switch (choice) {\n            case 1:\n                contact = search();\n                if (contact.number) {\n                    printf(\"%s - %d\\n\", contact.name, contact.number);\n                } else {\n                    printf(\"No existe el contacto\\n\");\n                }\n                break;\n            case 2:\n                addContact();\n                break;\n            case 3:\n                update();\n                break;\n            case 4:\n                removeContact();\n                break;\n            case 5:\n                finish = true;\n                printf(\"👋 Hasta pronto\");\n                break;\n            default:\n                printf(\"\\n⚠️ Opción incorrecta\\n\");\n        }\n    }\n\n\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/c/jchavescaceres.c",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n/*\nExample of structure\n*/\ntypedef struct {\n\tint firstField;\n\tlong secondField; \n} t_structSample;\n\n\n/*\nAnother example of structure is union, only one field can be used \n*/\ntypedef union {\n\tunsigned int firstField;\n\tlong secondField;\n} t_union;\n\n#define MAX_SIZE_OF_TELEPHONE_NUMBER 11\n\n#define MAX_BUFFER 250\n\n/*\nDefine a phone directory record\n*/\ntypedef struct {\n\tchar* name;\n\tchar* telephone;\n} t_phone_directory_record;\n\n/*\nReturn 1 if inLeft == inRecord\n*/\nint isLeftEqualToRight (\n\tt_phone_directory_record inLeft,\n\tt_phone_directory_record inRight);\n\n/*\nReturn 1 if inLeft > inRecord\n*/\nint isLeftGreaterThanRight (\n\tt_phone_directory_record inLeft,\n\tt_phone_directory_record inRight);\n\n/*\nReturn 1 if inLeft >= inRecord\n*/\nint isLeftGreaterOrEqualThanRight (\n\tt_phone_directory_record inLeft,\n\tt_phone_directory_record inRight);\n\n/*\nReturn 1 if inLeft >= inRecord\n*/\nvoid freeResources (t_phone_directory_record inPhoneDirectoryRecord);\n\n/*\nDefine a phone directory list\nUser MUSTN'T malloc or free memory related with the list (next)\n*/\ntypedef struct t_struct_phone_directory {\n\tt_phone_directory_record phoneDirectoryRecord;\n\tstruct t_struct_phone_directory* next;\n} t_phone_directory;\n\n/*\nInsert a new record, inOutPhoneDirectory will be updated with pointer to first element\nDo not malloc or free memory related with t_phone_directory* or \"next field\", use delete functions\n*/\nvoid insertPhoneDirectoryRecord (\n\tt_phone_directory** inOutPhoneDirectory, \n\tt_phone_directory_record inPhoneDirectoryRecord);\n\ntypedef void (t_callback_record)(t_phone_directory_record inRecord);\n\n/*\nIterate the list, invoke callbackRecord for each record \nDO NOT insert, update or delete while iterating\nDo not malloc or free memory related with t_phone_directory* or \"next field\", use delete functions\n*/\nvoid iteratePhoneDirectory(\n\tt_phone_directory* inPhoneDirectory,\n\tt_callback_record callbackRecord);\n\n/*\nUpdate record (if found), inOutPhoneDirectory will be updated with pointer to first element\ncallbackOldRecord is a function that will be invoked before updating the record, \nuser for example can use it to free resources from that record, \nDo not malloc or free memory related with t_phone_directory* or \"next field\", use delete functions\n*/\nvoid updatePhoneDirectoryRecord (\n\tt_phone_directory** inOutPhoneDirectory,\n\tt_phone_directory_record OldPhoneDirectoryRecord,\n\tt_phone_directory_record NewPhoneDirectoryRecord,\n\tt_callback_record callbackOldRecord);\n\n/*\nDelete record (if found), inOutPhoneDirectory will be updated with pointer to first element\ncallbackRecord is a function that will be invoked before removing the record, \ncan use it to for example to free resources from that record, \nDo not malloc or free memory related with t_phone_directory* or \"next field\", use delete functions\n*/\nvoid deletePhoneDirectoryRecord (\n\tt_phone_directory** inOutPhoneDirectory,\n\tt_phone_directory_record inPhoneDirectoryRecord,\n\tt_callback_record callbackRecord);\n\n/*\nDelete all records, inOutPhoneDirectory will be set to NULL\ncallbackRecord is a function that will be invoked before removing the record, \ncan use it to for example to free resources from that record, \nDo not malloc or free memory related with t_phone_directory* or \"next field\", use delete functions\n*/\nvoid deleteAllPhoneDirectory (\n\tt_phone_directory** inOutPhoneDirectory,\n\tt_callback_record callbackRecord);\n\n/*\nSort all record, inOutPhoneDirectory will be updated with pointer to first element\nThis function is never needed as all insert, update or delete mantains the phone directory sorted\nDo not malloc or free memory related with t_phone_directory* or \"next field\", use delete functions\n*/\nvoid sortPhoneDirectory (t_phone_directory** inPhoneDirectory);\n\n/*\nMenu options\n*/\ntypedef enum {E_SEARCH=1, E_SEARCH_ALL=2, E_INSERT=3, E_UPDATE=4, E_DELETE=5, E_EXIT=6, E_WRONG_ACTION} t_action;\n\n/*\nGet name from stdin, user MUST free memory\n*/\nchar* getInputName();\n\n/*\nGet telephone from stdin, user MUST free memory, return NULL if wrong telephone is input\n*/\nchar* getInputTelephone();\n\n/*\nPrint telephone record\n*/\nvoid displayPhoneRecord(t_phone_directory_record inPhoneDirectoryRecord);\n\n/*\nDisplay wrong action \n*/\nvoid displayWrongAction();\n\n/*\nDisplay main menu\n*/\nt_action displayMainMenu();\n\n/*\nDisplay search by Name,\noptionally results can be stored in a new phoneDirectory (phoneDirectoryResults != NULL)\n*/\nvoid displaySearchByName(\n\tt_phone_directory *phoneDirectory,\n\tt_phone_directory **phoneDirectoryResults);\n\n/*\nDisplay search by Telephone, \noptionally results can be stored in a new phoneDirectory (phoneDirectoryResults != NULL)\n*/\nvoid displaySearchByTelephone(\n\tt_phone_directory *phoneDirectory,\n\tt_phone_directory **phoneDirectoryResults);\n\n/*\nDisplay search menu,\noptionally results can be stored in a new phoneDirectory (phoneDirectoryResults != NULL)\n*/\nvoid displaySearchMenu(\n\tt_phone_directory *phoneDirectory,\n\tt_phone_directory **phoneDirectoryResults);\n\n/*\nDisplay search all menu\n*/\nvoid displaySearchAllMenu(t_phone_directory *phoneDirectory);\n\n/*\nDisplay insert menu, if newInserted is not NULL \nit will be set to 1 or 0 if a new record is inserted\n*/\nvoid displayInsertMenu(t_phone_directory **phoneDirectory, int* newInserted);\n\n/*\nDisplay update menu\n*/\nvoid displayUpdateMenu(t_phone_directory **phoneDirectory);\n\n/*\nDisplay delete menu\n*/\nvoid displayDeleteMenu(t_phone_directory **phoneDirectory);\n\n\nvoid main() {\n\n\t/* Ejemplos de estructuras */\n\n\t/* Create a struct */\n\tt_structSample myStruct;\n\n\t/* Create a union  */\n\tt_union myUnion;\n\n\tt_phone_directory *phone_directory = NULL;\n\n\t/* Initialize struct */\n\tmyStruct.firstField = 1;\n\tmyStruct.secondField = 2;\n\n\t/* Initialize union */\n\tmyUnion.firstField = 1;\n\tmyUnion.secondField = -2;\n\n\tprintf (\"Struct: First field %d, second field %ld\\n\", myStruct.firstField, myStruct.secondField);\n\n\tprintf (\"Union: First field %u, second field %ld, remains only second field\\n\", myUnion.firstField, myUnion.secondField);\n\n\t/*\n\tEl ejercicio de dificultad extra cubre el resto ejercicio básico (inserción, borrado, actualización y ordenación),\n\tasí que no lo repetimos */\n\n\tdo {\n\t} while (displayMainMenu (&phone_directory) != E_EXIT);\n\n\tdeleteAllPhoneDirectory (&phone_directory, freeResources);\n\n\n\t/*Tests*/\n//\tt_phone_directory_record a, b, c, d, new;\n//\n//\ta.name = \"aaaa\";\n//\ta.telephone = \"34669587172\";\n//\n//\tb.name = \"bbbb\";\n//\tb.telephone = \"33669587172\";\n//\n//\tc.name = \"cccc\";\n//\tc.telephone = \"34669587173\";\n//\n//\td.name = \"dddd\";\n//\td.telephone = \"34669587173\";\n//\n//\tnew.name = \"cccc\";\n//\tnew.telephone = \"94669587173\";\n//\n//\tprintf (\"isLeftGreaterThanRight %d, isLeftEqualToRight: %d\\n\", isLeftGreaterThanRight (a, b), isLeftEqualToRight (a,b));\n//\tprintf (\"isLeftGreaterOrEqualThanRight %d\\n\", isLeftGreaterOrEqualThanRight (a,b));\n//\n//\n//\tinsertPhoneDirectoryRecord ( &phone_directory, d);\n//\tinsertPhoneDirectoryRecord ( &phone_directory, c);\n//\tinsertPhoneDirectoryRecord ( &phone_directory, b);\n//\tinsertPhoneDirectoryRecord ( &phone_directory, a);\n//\n//\titeratePhoneDirectory (phone_directory, displayPhoneRecord);\n//\n//\tprintf (\"Update :\\n\");\n//\tupdatePhoneDirectoryRecord (&phone_directory, c, new, NULL);\n//\titeratePhoneDirectory (phone_directory, displayPhoneRecord);\n//\n//\tprintf (\"Ordenar todos :\\n\");\n//\t/* unsort manually \n//\tbbbb -> aaaa -> cccc\n//\t*/\n//\tt_phone_directory *aaaa = phone_directory;\n//\tt_phone_directory *bbbb = aaaa->next;\n//\tt_phone_directory *cccc = bbbb->next;\n//\tphone_directory = bbbb;\n//\tbbbb->next = aaaa;\n//\taaaa->next = cccc;\n//\tprintf (\"Antes de ordenar todos :\\n\");\n//\titeratePhoneDirectory (phone_directory, displayPhoneRecord);\n//\n//\tsortPhoneDirectory (&phone_directory);\n//\tprintf (\"Despues de ordenar todos :\\n\");\n//\titeratePhoneDirectory (phone_directory, displayPhoneRecord);\n//\n//\tprintf (\"Borrar uno :\\n\");\n//\tdeletePhoneDirectoryRecord (&phone_directory, a, NULL);\n//\tprintf (\"Nueva :\\n\");\n//\titeratePhoneDirectory (phone_directory, displayPhoneRecord);\n//\n//\tprintf (\"Borrar todos :\\n\");\n//\tdeleteAllPhoneDirectory (&phone_directory, NULL);\n//\titeratePhoneDirectory (phone_directory, displayPhoneRecord);\n\n\n};\n\nint isLeftEqualToRight (\n\tt_phone_directory_record inLeft,\n\tt_phone_directory_record inRight) {\n\t\n\tint res = 0;\n\n\tif (strcasecmp (inLeft.name, inRight.name) == 0) {\n\n\t\tres = (strcmp (inLeft.telephone, inRight.telephone) == 0 ? 1 : 0);\n\t}\n\n\treturn res;\n};\n\nint isLeftGreaterThanRight (\n\tt_phone_directory_record inLeft,\n\tt_phone_directory_record inRight) {\n\t\n\tconst int compareName = strcasecmp (inLeft.name, inRight.name);\n\tint res = 0;\n\n\n\tif (compareName < 0) {\n\t\tres = 1;\n\t}\n\telse if (compareName == 0) {\n\t\tres = strcmp (inLeft.telephone, inRight.telephone) < 0 ? 1 : 0;\n\t}\n\n\treturn res;\n};\n\nint isLeftGreaterOrEqualThanRight (\n\tt_phone_directory_record inLeft,\n\tt_phone_directory_record inRight) {\n\n\treturn isLeftGreaterThanRight (inLeft, inRight) || isLeftEqualToRight (inLeft, inRight);\n};\n\nvoid freeResources (t_phone_directory_record inPhoneDirectoryRecord) {\n\tfree (inPhoneDirectoryRecord.name);\n\tfree (inPhoneDirectoryRecord.telephone);\n};\n\nvoid insertPhoneDirectoryRecord (\n\tt_phone_directory** inOutPhoneDirectory, \n\tt_phone_directory_record inPhoneDirectoryRecord) {\n\t\n\tt_phone_directory *first = *inOutPhoneDirectory;\n\tt_phone_directory *current, *new = NULL;\n\n\tcurrent = first;\n\n\tnew = malloc (sizeof (t_phone_directory));\n\tnew-> phoneDirectoryRecord = inPhoneDirectoryRecord;\n\tnew-> next = NULL;\n\n\n\tif (first == NULL) {\n\t\t/* First element in the list*/\n\t\tfirst = new;\n\t}\n\telse if (isLeftGreaterOrEqualThanRight (\n\t\t\tnew->phoneDirectoryRecord,\n\t\t\tfirst->phoneDirectoryRecord)) {\n\t\t/*new item is the first in an existing list, we add it */\n\t\tnew->next = first;\n\t\tfirst = new;\n\t}\n\telse {\n\t\t/*\n\t\tIterate to find the proper position in the list\n\t\tfirst -> A -> B -> NEW -> NULL\n\t\t*/\n\t\tcurrent = first;\n\n\t\twhile (current  != NULL) {\n\n\t\t\tif (current-> next == NULL) {\n\t\t\t\t/* Last one, add new at the end */\n\t\t\t\tcurrent-> next = new;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif (isLeftGreaterOrEqualThanRight (\n\t\t\t\t\tcurrent->phoneDirectoryRecord,\n\t\t\t\t\tnew->phoneDirectoryRecord) &&\n\t\t\t\t    isLeftGreaterOrEqualThanRight (\n\t\t\t\t\tnew->phoneDirectoryRecord,\n\t\t\t\t\tcurrent->next->phoneDirectoryRecord)) {\n\t\t\t\t\t\t/*\n\t\t\t\t\t\tFound position, add it and exit loop\n\t\t\t\t\t\t*/\n\t\t\t\t\t\tnew->next = current->next;\n\t\t\t\t\t\tcurrent->next = new;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t};\n\t\t\tcurrent = current->next;\n\t\t};\n\t};\n\n\t*inOutPhoneDirectory = first;\n};\n\nvoid iteratePhoneDirectory(\n\tt_phone_directory* inPhoneDirectory,\n\tt_callback_record callbackRecord) {\n\n\tt_phone_directory *current = inPhoneDirectory;\n\n\tif (callbackRecord != NULL) {\n\t\twhile (current != NULL) {\n\n\t\t\tcallbackRecord (current->phoneDirectoryRecord);\n\t\t\tcurrent = current->next;\n\n\t\t};\n\t};\n};\n\n\nvoid updatePhoneDirectoryRecord (\n\tt_phone_directory** inOutPhoneDirectory,\n\tt_phone_directory_record OldPhoneDirectoryRecord,\n\tt_phone_directory_record NewPhoneDirectoryRecord,\n\tt_callback_record callbackOldRecord) {\n\t\n\n\tint found = 0;\n\tvoid callback_record (t_phone_directory_record inRecord) {\n\n\t\tfound = 1;\n\n\t\tif (callbackOldRecord != NULL) {\n\t\t\tcallbackOldRecord (inRecord);\n\t\t};\n\t};\n\n\tdeletePhoneDirectoryRecord (inOutPhoneDirectory, OldPhoneDirectoryRecord, callback_record);\n\n\tif (found) {\n\n\t\tinsertPhoneDirectoryRecord (inOutPhoneDirectory, NewPhoneDirectoryRecord);\n\n\t};\n\n};\n\nvoid deletePhoneDirectoryRecord (\n\tt_phone_directory** inOutPhoneDirectory,\n\tt_phone_directory_record inPhoneDirectoryRecord,\n\tt_callback_record callbackRecord) {\n\n\tt_phone_directory *first = *inOutPhoneDirectory;\n\tt_phone_directory *current = NULL;\n\tt_phone_directory *previous = NULL;\n\n\tif (first != NULL) {\n\t\tif (isLeftEqualToRight (first->phoneDirectoryRecord, inPhoneDirectoryRecord)) {\n\t\t\t/* First one is to be removed */\n\t\t\t\n\t\t\tif (callbackRecord != NULL) {\n\t\t\t\tcallbackRecord (first->phoneDirectoryRecord);\n\t\t\t};\n\t\n\t\t\tcurrent = first;\n\t\t\tfirst = first->next;\n\t\t\tfree (current);\n\t\t}\n\t\telse {\n\t\t\tcurrent = first->next;\n\t\t\tprevious = first;\n\t\n\t\t\twhile (current != NULL) {\n\t\t\t\t/* first -> A -> OLD -> C -> NULL*/\n\t\t\t\tif (isLeftEqualToRight (current->phoneDirectoryRecord, inPhoneDirectoryRecord)) {\n\t\t\n\t\t\t\t\t/* Found */\n\t\t\t\t\tif (callbackRecord != NULL) {\n\t\t\t\t\t\tcallbackRecord (current->phoneDirectoryRecord);\n\t\t\t\t\t};\n\t\n\t\t\t\t\tprevious->next = current->next;\n\t\t\t\t\tfree (current);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tprevious = current;\n\t\t\t\tcurrent = current->next;\n\t\t\t};\n\t\t};\n\n\t};\n\t*inOutPhoneDirectory = first;\n};\n\nvoid deleteAllPhoneDirectory (\n\tt_phone_directory** inOutPhoneDirectory,\n\tt_callback_record callbackRecord) {\n\n\tt_phone_directory *current, *previous = NULL;\n\n\tcurrent = *inOutPhoneDirectory;\n\n\twhile (current != NULL) {\n\n\t\tif (callbackRecord != NULL) {\n\t\t\tcallbackRecord (current->phoneDirectoryRecord);\n\t\t};\n\t\tprevious = current;\n\t\tcurrent = current->next;\n\t\tfree (previous);\n\t};\n\n\t*inOutPhoneDirectory = current;\n};\n\nvoid sortPhoneDirectory (t_phone_directory** inPhoneDirectory) {\n\n\t/* Instead of sorting it will create a new phone diretory as all elements will be sorted */\n\n\tt_phone_directory *old = *inPhoneDirectory;\n\tt_phone_directory *new = NULL;\n\n\tvoid iterateCallback (t_phone_directory_record inPhoneDirectoryRecord) {\n\n\t\tinsertPhoneDirectoryRecord (&new, inPhoneDirectoryRecord);\n\n\t};\n\n\tdeleteAllPhoneDirectory (&old, iterateCallback);\n\n\t*inPhoneDirectory = new;\n};\n\nchar* getInputName() {\n\tchar buffer [MAX_BUFFER];\n\tchar *res = NULL;\n\n\tprintf(\"\\nNombre : \");\n\tfgets (buffer, MAX_BUFFER, stdin);\n\tbuffer [strlen (buffer)-1] = '\\0'; /* remove \\n */\n\tres = malloc (strlen (buffer)+1);\n\t\n\tstrcpy (res, buffer);\n\n\treturn res;\n};\n\nchar* getInputTelephone() {\n\tchar buffer [MAX_BUFFER];\n\tchar *res = NULL;\n\n\tprintf(\"Telefono (máximo 11 dígitos) : \");\n\tfgets (buffer, MAX_BUFFER, stdin);\n\tbuffer [strlen (buffer)-1] = '\\0'; /* remove \\n */\n\tif ( (strlen(buffer) > MAX_SIZE_OF_TELEPHONE_NUMBER) || (strspn(buffer, \"0123456789\") != strlen(buffer))) {\n\t\tprintf (\"Wrong number\\n\");\n\t}\n\telse\n\t{\n\t\tres = malloc (strlen (buffer));\n\t\tstrcpy (res, buffer);\n\t}\n\n\treturn res;\n};\n\nvoid displayPhoneRecord(t_phone_directory_record inPhoneDirectoryRecord) {\n\n\tprintf(\"\\nNombre: %s, teléfono : %s\", inPhoneDirectoryRecord.name, inPhoneDirectoryRecord.telephone);\n\n};\n\nvoid displayWrongAction() {\n\n\tconst char* WRONG_ACTION = \"Opción incorrecta\";\n\tprintf (\"%s\\n\\n\", WRONG_ACTION);\n};\n\nt_action displayMainMenu(t_phone_directory **phoneDirectory) {\n\n\tchar buffer [MAX_BUFFER];\n\tt_action action = E_EXIT;\n\n\tprintf (\"\\n\\n********* MENU PRINCIPAL **********\\n\");\n\tprintf (\"1. Buscar:\\n\");\n\tprintf (\"2. Listar todos:\\n\");\n\tprintf (\"3. Insertar nuevo registro:\\n\");\n\tprintf (\"4. Actualizar registro:\\n\");\n\tprintf (\"5. Borrar registro:\\n\");\n\tprintf (\"6. Salir:\\n\");\n\tprintf (\"\\nEscoja opcion: \");\n\n\tfgets (buffer, MAX_BUFFER, stdin);\n\tif (sscanf (buffer, \"%d\\n\", (int*)&action) != 1) {\n\t\tdisplayWrongAction();\n\t\taction = E_WRONG_ACTION;\n\t}\n\telse {\n\t\tswitch (action) {\n\n\t\t\tcase E_SEARCH :\n\t\t\t\tdisplaySearchMenu(*phoneDirectory, NULL);\n\t\t\t\tbreak;\n\t\t\tcase E_SEARCH_ALL:\n\t\t\t\tdisplaySearchAllMenu(*phoneDirectory);\n\t\t\t\tbreak;\n\t\t\tcase E_INSERT:\n\t\t\t\tdisplayInsertMenu(phoneDirectory, NULL);\n\t\t\t\tbreak;\n\t\t\tcase E_UPDATE:\n\t\t\t\tdisplayUpdateMenu(phoneDirectory);\n\t\t\t\tbreak;\n\t\t\tcase E_DELETE: \n\t\t\t\tdisplayDeleteMenu(phoneDirectory);\n\t\t\t\tbreak;\n\t\t\tcase E_EXIT: \n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tdisplayWrongAction();\n\t\t\t\taction = E_WRONG_ACTION;\n\t\t\t\tbreak;\n\t\t};\n\t};\n\n\treturn action;\n};\n\nvoid displaySearchByName(\n\tt_phone_directory *phoneDirectory,\n\tt_phone_directory **phoneDirectoryResults) {\n\n\tchar* name = getInputName();\n\n\tvoid iterateCallback (t_phone_directory_record inPhoneDirectoryRecord) {\n\n\t\tif (strcmp (inPhoneDirectoryRecord.name, name) == 0) {\n\n\t\t\tdisplayPhoneRecord(inPhoneDirectoryRecord);\n\t\t\tinsertPhoneDirectoryRecord (phoneDirectoryResults, inPhoneDirectoryRecord);\n\n\t\t};\n\t};\n\n\titeratePhoneDirectory(phoneDirectory, iterateCallback); \n\tfree (name);\n};\n\nvoid displaySearchByTelephone(\n\tt_phone_directory *phoneDirectory,\n\tt_phone_directory **phoneDirectoryResults) {\n\n\tchar* telephone = getInputTelephone();\n\n\tvoid iterateCallback (t_phone_directory_record inPhoneDirectoryRecord) {\n\n\t\tif (strcmp (inPhoneDirectoryRecord.telephone, telephone) == 0) {\n\n\t\t\tdisplayPhoneRecord(inPhoneDirectoryRecord);\n\t\t\tinsertPhoneDirectoryRecord (phoneDirectoryResults, inPhoneDirectoryRecord);\n\n\t\t};\n\t};\n\n\tif (telephone != NULL) {\n\n\t\titeratePhoneDirectory(phoneDirectory, iterateCallback); \n\n\t\tfree (telephone);\n\t};\n};\n\nvoid displaySearchMenu(\n\tt_phone_directory *phoneDirectory,\n\tt_phone_directory **phoneDirectoryResults) {\n\n\tchar buffer [MAX_BUFFER];\n\tchar selectedOption = ' ';\n\n\tprintf(\"Búsqueda por (N)ombre o (T)eléfono? :\");\n\tfgets (buffer, MAX_BUFFER, stdin);\n\n\tif (sscanf (buffer, \"%c\\n\", &selectedOption) != 1) {\n\t\tdisplayWrongAction();\n\t}\n\telse {\n\n\t\tswitch (selectedOption) {\n\t\n\t\t\tcase 'n':\n\t\t\tcase 'N':\n\t\n\t\t\t\tdisplaySearchByName (phoneDirectory, phoneDirectoryResults);\n\t\t\t\tbreak;\n\t\n\t\t\tcase 't':\n\t\t\tcase 'T':\n\t\n\t\t\t\tdisplaySearchByTelephone (phoneDirectory, phoneDirectoryResults);\n\t\t\t\tbreak;\n\t\n\t\t\tdefault:\n\t\n\t\t\t\tdisplayWrongAction();\n\t\t\t\tbreak;\n\t\n\t\t};\n\t};\n\n};\n\nvoid displaySearchAllMenu(t_phone_directory *phoneDirectory) {\n\n\tvoid iterateCallback (t_phone_directory_record inPhoneDirectoryRecord) {\n\n\t\tdisplayPhoneRecord(inPhoneDirectoryRecord);\n\t};\n\n\titeratePhoneDirectory(phoneDirectory, iterateCallback);\n\tprintf(\"\\n\");\n\n};\n\nvoid displayInsertMenu(t_phone_directory **phoneDirectory, int* newInserted) {\n\n\tt_phone_directory_record phoneRecord;\n\tphoneRecord.name = getInputName();\n\tphoneRecord.telephone = getInputTelephone();\n\tint ok = 0;\n\n\tif (phoneRecord.telephone == NULL ) {\n\t\tfree (phoneRecord.name);\n\t\tfree (phoneRecord.telephone);\n\t\tok=0;\n\t}\n\telse {\n\t\tok=1;\n\t\tinsertPhoneDirectoryRecord (phoneDirectory, phoneRecord);\n\t}\n\tif (newInserted != NULL) {\n\t\t*newInserted = ok;\n\t};\n};\n\nvoid displayUpdateMenu(t_phone_directory **phoneDirectory) {\n\tt_phone_directory *recordsFound=NULL;\n\tint newInserted = 0;\n\n\tvoid iterateCallback (t_phone_directory_record inPhoneDirectoryRecord) {\n\n\t\tdeletePhoneDirectoryRecord (\n\t\t\tphoneDirectory,\n\t\t\tinPhoneDirectoryRecord,\n\t\t\tfreeResources);\n\t};\n\n\tdisplaySearchMenu(*phoneDirectory, &recordsFound);\n\n\tif (recordsFound != NULL) {\n\t\t/* Old records to update, \n\t\tthem insert new one and remove old one if properlly inserted \n\t\t(there could be several old records, but they will be replaced \n\t\tby only one new record*/\n\n\t\tprintf (\"\\nUpdate with: \\n\");\n\t\tdisplayInsertMenu(phoneDirectory, &newInserted);\n\t};\n\n\tif (newInserted) {\n\t\t/* Remove from phoneDirectory the old record(s) */\n\t\titeratePhoneDirectory(recordsFound, iterateCallback);\n\n\t\tdeleteAllPhoneDirectory (&recordsFound, NULL);\n\t};\n};\n\nvoid displayDeleteMenu(t_phone_directory **phoneDirectory) {\n\tt_phone_directory *recordsFound=NULL;\n\n\tvoid iterateCallback (t_phone_directory_record inPhoneDirectoryRecord) {\n\n\t\tdeletePhoneDirectoryRecord (\n\t\t\tphoneDirectory,\n\t\t\tinPhoneDirectoryRecord,\n\t\t\tfreeResources);\n\t};\n\n\tdisplaySearchMenu(*phoneDirectory, &recordsFound);\n\n\tif (recordsFound != NULL) {\n\t\t/* Remove from phoneDirectory the old record(s) */\n\t\titeratePhoneDirectory(recordsFound, iterateCallback);\n\n\t\tdeleteAllPhoneDirectory (&recordsFound, NULL);\n\t};\n};\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/c/srvariable.c",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\n#include <stdio.h>\n#include <stdbool.h>\n#include <stdlib.h>\n#include <string.h>\n\n/*! Declaración de estructuras y funciones !*/\n \n/* Lista enlazada simple */\n\n// Estructura\n\ntypedef struct s_linked_list\n{\n    int                     data;\n    struct s_linked_list    *next;\n}                           t_linked_list;\n\n// Operaciones\n\nt_linked_list   *ll_create_node(int data);\nint             ll_insert_node_beginning(t_linked_list **ll, int data);\nint             ll_insert_node_end(t_linked_list **ll, int data);\nint             ll_insert_node_nth_position(t_linked_list **ll, int data, int position);\nvoid            ll_delete(t_linked_list **ll);\nint             ll_delete_first_node(t_linked_list **ll);\nint             ll_delete_last_node(t_linked_list **ll);\nint             ll_delete_nth_node(t_linked_list **ll, int position);\nint             ll_update_node(t_linked_list **ll, int new_data, int position);\nt_linked_list   *ll_find_data(t_linked_list *ll, int data);\nvoid            ll_sort(t_linked_list **ll);\nvoid            ll_print(t_linked_list *ll);\nint             ll_length(t_linked_list *ll);\n\n/* Lista doblemente enlazada */\n\n// Estructura\n\ntypedef struct s_doubly_linked_list\n{\n    int                         data;\n    struct s_doubly_linked_list *previous;\n    struct s_doubly_linked_list *next;\n}                               t_doubly_linked_list;\n\n// Operaciones\n\nt_doubly_linked_list    *dll_create_node(int data);\nint                     dll_insert_node_beginning(t_doubly_linked_list **dll, int data);\nint                     dll_insert_node_end(t_doubly_linked_list **ll, int data);\nint                     dll_insert_node_nth_position(t_doubly_linked_list **dll, int data, int position);\nint                     dll_delete(t_doubly_linked_list **dll);\nint                     dll_delete_first_node(t_doubly_linked_list **dll);\nint                     dll_delete_last_node(t_doubly_linked_list **dll);\nint                     dll_delete_nth_node(t_doubly_linked_list **dll, int position);\nint                     dll_update_node(t_doubly_linked_list **dll, int new_data, int position);\nt_doubly_linked_list    *dll_find_data(t_doubly_linked_list *dll, int data);\nvoid                    dll_sort(t_doubly_linked_list **dll);\nvoid                    dll_print(t_doubly_linked_list *dll);\nint                     dll_length(t_doubly_linked_list *dll);\n\n/* DIFICULTAD EXTRA */\n\n// Estructura\n\ntypedef struct s_contact\n{\n    char                name[50];\n    unsigned long long  phone_number;\n    struct s_contact    *previous;\n    struct s_contact    *next;\n}                       t_contact;\n\n// Funciones\n\nint                     contact_list(void);\nt_contact               *create_contact_list(void);\nvoid                    display_menu(void);\nvoid                    handle_option(int option, t_contact **contact);\nvoid                    add_contact(t_contact **contact);\nvoid                    update_contact(t_contact **contact);\nt_contact               *search_contact(t_contact *contact, unsigned long long phone_number);\nvoid                    delete_contact(t_contact **contact);\nvoid                    display_contacts(t_contact *contact);\nvoid                    delete_contact_list(t_contact **contact);\n\n// Programa principal\n\nint main(void)\n{\n\n    /* === 1 === */\n    /* Array */\n    int array[10] = {8, 5, 2, 1, 9, 125, 3892, -1, 12893, -9592};\n\n    /* Lista enlazada simple */\n    t_linked_list *ll = ll_create_node(array[0]);\n    if (!ll)\n        return (1);\n\n    /* Lista doblemente enlazada */\n    t_doubly_linked_list *dll = dll_create_node(array[0]);\n    if (!dll)\n        return (2);\n\n    /* === 2 === */\n    /* Array */\n    // Obtener el tamaño\n    int size = sizeof(array) / sizeof(array[0]);\n\n    // Modificar el valor\n    array[5] = 82319;\n\n    /* Lista enlazada simple*/\n    int i = 1;\n    for (i; i < 4; i++)\n        // Inserta un nodo al principio\n        ll_insert_node_beginning(&ll, array[i]);\n\n    for (i; i < size; i++)\n        // Inserta un nodo al final\n        ll_insert_node_end(&ll, array[i]);\n\n    // Insertar nodo en una posición en concreto\n    ll_insert_node_nth_position(&ll, array[3], 3);\n\n    // Elimina el primer nodo\n    ll_delete_first_node(&ll);\n\n    // Elimina el último nodo\n    ll_delete_last_node(&ll);\n\n    // Elimina un nodo\n    ll_delete_nth_node(&ll, 4);\n\n    // Actualiza un elemento\n    ll_update_node(&ll, 2024, 7);\n\n    // Busca un elemento\n    if (ll_find_data(ll, 2024))\n        printf(\"Lo he encontrado\\n\");\n    else\n        printf(\"No lo he encontrado\\n\");\n\n    // Imprime el número de nodos\n    printf(\"Hay %d nodos en la lista enlazada simple\\n\", ll_length(ll));\n\n    // Imprime la lista enlazada\n    printf(\"*****************\\n\");\n    printf(\"Sin ordenar\\n\");\n    ll_print(ll);\n    printf(\"*****************\\n\");\n\n    // Ordena la lista enlazada\n    ll_sort(&ll);\n    printf(\"*****************\\n\");\n    printf(\"Ordenado\\n\");\n    ll_print(ll);\n    printf(\"*****************\\n\");\n\n    // Elimina completamente la lista enlazada simple\n    ll_delete(&ll);\n\n    /* Lista doblemente enlazada */\n    i = 1;\n    for (i; i < 4; i++)\n        // Insertar un nodo al principio\n        dll_insert_node_beginning(&dll, array[i]);\n\n    for (i; i < size; i++)\n        // Inserta un nodo al final\n        dll_insert_node_end(&dll, array[i]);\n\n    // Inserta un nodo en una posición en concreto\n    dll_insert_node_nth_position(&dll, array[9], 9);\n\n    // Elimina el primer nodo\n    dll_delete_first_node(&dll);\n\n    // Elimina el último nodo\n    dll_delete_last_node(&dll);\n\n    // Elimina un nodo\n    dll_delete_nth_node(&dll, 1);\n\n    // Actualiza un elemento\n    dll_update_node(&dll, 213498, 0);\n\n    // Busca un elemento\n    if (dll_find_data(dll, 21474836))\n        printf(\"Lo he encontrado\\n\");\n    else\n        printf(\"No lo he encontrado\\n\");\n    printf(\"Hay %d nodos en la lista doblemente enlazada\\n\", dll_length(dll));\n\n    // Imprime la lista doblemente enlazada\n    printf(\"*****************\\n\");\n    printf(\"Sin ordenar\\n\");\n    dll_print(dll);\n    printf(\"*****************\\n\");\n\n    // Ordena la lista doblemente enlazada\n    dll_sort(&dll);\n    printf(\"*****************\\n\");\n    printf(\"Ordenado\\n\");\n    dll_print(dll);\n    printf(\"*****************\\n\");\n\n    // Elimina completamente la lista doblemente enlazada\n    dll_delete(&dll);\n    /* DIFICULTAD EXTRA */\n    if (contact_list() < 0)\n        return (-1);\n    return (0);\n}\n\n/*! Definición de funciones !*/\n\n/* Lista enlazada simple */\n\nt_linked_list   *ll_create_node(int data)\n{\n    t_linked_list   *ll;\n\n    ll = (t_linked_list *)malloc(sizeof(t_linked_list));\n    if (!ll)\n    {\n        fprintf(stderr, \"Error: creando lista enlazada\\n\");\n        return (NULL);\n    }\n    ll->data = data;\n    ll->next = NULL;\n    return (ll);\n}\n\nint ll_insert_node_beginning(t_linked_list **ll, int data)\n{\n    t_linked_list   *node;\n\n    if (!(*ll))\n    {\n        fprintf(stderr, \"Error: lista enlazada nula\\n\");\n        return (-1);\n    }\n    node = (t_linked_list *)malloc(sizeof(t_linked_list));\n    if (!node)\n    {\n        fprintf(stderr, \"Error: añadiendo nodo al principio de la lista enlazada\\n\");\n        return (-1);\n    }\n    node->data = data;\n    node->next = *ll;\n    *ll = node;\n    return (0);\n}\n\nint ll_insert_node_end(t_linked_list **ll, int data)\n{\n    t_linked_list   *node;\n    t_linked_list   *temp;\n\n    if (!(*ll))\n    {\n        fprintf(stderr, \"Error: lista enlazada nula\\n\");\n        return (-1);\n    }\n    node = (t_linked_list *)malloc(sizeof(t_linked_list));\n    if (!node)\n    {\n        fprintf(stderr, \"Error: añadiendo nodo al final de la lista enlazada\\n\");\n        return (-1);\n    }\n    node->data = data;\n    node->next = NULL;\n    temp = *ll;\n    while (temp->next)\n        temp = temp->next;\n    temp->next = node;\n    return (0);\n}\n\nint ll_insert_node_nth_position(t_linked_list **ll, int data, int position)\n{\n    t_linked_list   *node;\n    t_linked_list   *temp;\n\n    if (!(*ll))\n    {\n        fprintf(stderr, \"Error: lista enlazada nula\\n\");\n        return (-1);\n    }\n    if (position < 0 || position > ll_length(*ll))\n    {\n        fprintf(stderr, \"Error: posición inválida\\n\");\n        return (-1);\n    }\n    if (position == 0)\n        ll_insert_node_beginning(ll, data);\n    else if (position == ll_length(*ll))\n        ll_insert_node_end(ll, data);\n    else\n    {\n        node = (t_linked_list *)malloc(sizeof(t_linked_list));\n        if (!node)\n        {\n            fprintf(stderr, \"Error: añadiendo nodo en la posición %d de la lista enlazada\\n\", position);\n            return (-1);\n        }\n        temp = *ll;\n        while (position-- > 1)\n            temp = temp->next;\n        node->data = data;\n        node->next = temp->next;\n        temp->next = node;\n    }\n    return (0);\n}\n\nvoid    ll_delete(t_linked_list **ll)\n{\n    t_linked_list   *temp;\n\n    while (*ll)\n    {\n        temp = (*ll)->next;\n        free(*ll);\n        *ll = temp;\n    }\n    *ll = NULL;\n}\n\nint ll_delete_first_node(t_linked_list **ll)\n{\n    t_linked_list   *temp;\n\n    if (!(*ll))\n    {\n        fprintf(stderr, \"Error: lista enlazada nula\\n\");\n        return (-1);\n    }\n    temp = (*ll)->next;\n    free(*ll);\n    *ll = temp;\n    return (0);\n}\n\nint ll_delete_last_node(t_linked_list **ll)\n{\n    t_linked_list   *temp;\n    t_linked_list   *penultimate;\n\n    if (!(*ll))\n    {\n        fprintf(stderr, \"Error: lista enlazada nula\\n\");\n        return (-1);\n    }\n    temp = *ll;\n    penultimate = NULL;\n    while (temp->next)\n    {\n        penultimate = temp;\n        temp = temp->next;\n    }\n    if (!penultimate)\n    {\n        free(*ll);\n        *ll = NULL;\n    }\n    else\n    {\n        free(temp);\n        penultimate->next = NULL;\n    }\n    return (0);\n}\n\nint ll_delete_nth_node(t_linked_list **ll, int position)\n{\n    t_linked_list   *temp;\n    t_linked_list   *previous;\n\n    if (!(*ll))\n    {\n        fprintf(stderr, \"Error: lista enlazada nula\\n\");\n        return (-1);\n    }\n    if (position < 0 || position >= ll_length(*ll))\n    {\n        fprintf(stderr, \"Error: posición inválida\\n\");\n        return (-1);\n    }\n    if (position == 0)\n        ll_delete_first_node(ll);\n    else if (position == ll_length(*ll))\n        ll_delete_last_node(ll);\n    else\n    {\n        temp = *ll;\n        while (position-- > 0)\n        {\n            previous = temp;\n            temp = temp->next;\n        }\n        previous->next = temp->next;\n        free(temp);\n    }\n    return (0);\n}\n\nint ll_update_node(t_linked_list **ll, int new_data, int position)\n{\n    t_linked_list   *temp;\n\n    if (!(*ll))\n    {\n        fprintf(stderr, \"Error: lista enlazada nula\\n\");\n        return (-1);\n    }\n    if (position < 0 || position >= ll_length(*ll))\n    {\n        fprintf(stderr, \"Error: posición inválida\\n\");\n        return (-1);\n    }\n    temp = *ll;\n    while (position-- > 0)\n        temp = temp->next;\n    temp->data = new_data;\n    return (0);\n}\n\nvoid    ll_print(t_linked_list *ll)\n{\n    if (!ll)\n    {\n        fprintf(stderr, \"Error: lista enlazada nula\\n\");\n        return ;\n    }\n    while (ll)\n    {\n        printf(\"%d\\n\", ll->data);\n        ll = ll->next;\n    }\n}\n\nt_linked_list   *ll_find_data(t_linked_list *ll, int data)\n{\n    t_linked_list   *temp;\n\n    if (!ll)\n    {\n        fprintf(stderr, \"Error: lista enlazada nula\\n\");\n        return (NULL);\n    }\n    temp = ll;\n    while (temp)\n    {\n        if (temp->data == data)\n            return (temp);\n        temp = temp->next;\n    }\n    return (NULL);\n}\n\nvoid    ll_sort(t_linked_list **ll)\n{\n    int             temp_data;\n    bool            is_swapped;\n    t_linked_list   *temp;\n\n    if (!(*ll))\n    {\n        fprintf(stderr, \"Error: lista enlazada nula\\n\");\n        return ;\n    }\n    is_swapped = false;\n    while (!is_swapped)\n    {\n        is_swapped = true;\n        temp = *ll;\n        while (temp->next != NULL)\n        {\n            if (temp->data > temp->next->data)\n            {\n                temp_data = temp->data;\n                temp->data = temp->next->data;\n                temp->next->data = temp_data;\n                is_swapped = false;\n            }\n            temp = temp->next;\n        }\n    }\n}\n\nint ll_length(t_linked_list *ll)\n{\n    t_linked_list   *temp;\n    int             counter;\n\n    if (!ll)\n    {\n        fprintf(stderr, \"Error: lista enlazada nula\\n\");\n        return (0);\n    }\n    temp = ll;\n    counter = 0;\n    while (temp)\n    {\n        counter++;\n        temp = temp->next;\n    }\n    return (counter);\n}\n\n/* Lista doblemente enlazada */\n\nt_doubly_linked_list    *dll_create_node(int data)\n{\n    t_doubly_linked_list    *dll;\n\n    dll = (t_doubly_linked_list *)malloc(sizeof(t_doubly_linked_list));\n    if (!dll)\n    {\n        fprintf(stderr, \"Error: creando lista doblemente enlazada\\n\");\n        return (NULL);\n    }\n    dll->data = data;\n    dll->previous = NULL;\n    dll->next = NULL;\n    return (dll);\n}\n\nint dll_insert_node_beginning(t_doubly_linked_list **dll, int data)\n{\n    t_doubly_linked_list    *node;\n    t_doubly_linked_list    *temp;\n\n    if (!(*dll))\n    {\n        fprintf(stderr, \"Error: lista doblemente enlazada nula\\n\");\n        return (-1);\n    }\n    node = (t_doubly_linked_list *)malloc(sizeof(t_doubly_linked_list));\n    if (!node)\n    {\n        fprintf(stderr, \"Error: añadiendo nodo al principio de la lista doblemente enlazada\\n\");\n        return (-1);\n    }\n    temp = *dll;\n    while (temp->previous)\n        temp = temp->previous;\n    node->data = data;\n    node->previous = NULL;\n    node->next = temp;\n    temp->previous = node;\n    *dll = node;\n    return (0);\n}\n\nint dll_insert_node_end(t_doubly_linked_list **dll, int data)\n{\n    t_doubly_linked_list    *node;\n    t_doubly_linked_list    *temp;\n\n    if (!(*dll))\n    {\n        fprintf(stderr, \"Error: lista doblemente enlazada nula\\n\");\n        return (-1);\n    }\n    node = (t_doubly_linked_list *)malloc(sizeof(t_doubly_linked_list));\n    if (!node)\n    {\n        fprintf(stderr, \"Error: añadiendo nodo al final de la lista doblemente enlazada\\n\");\n        return (-1);\n    }\n    node->data = data;\n    node->next = NULL;\n    temp = *dll;\n    while (temp->next)\n        temp = temp->next;\n    node->previous = temp;\n    temp->next = node;\n    return (0);\n}\n\nint dll_insert_node_nth_position(t_doubly_linked_list **dll, int data, int position)\n{\n    t_doubly_linked_list    *node;\n    t_doubly_linked_list    *temp;\n\n    if (!(*dll))\n    {\n        fprintf(stderr, \"Error: lista doblemente enlazada nula\\n\");\n        return (-1);\n    }\n    if (position < 0 || position > dll_length(*dll))\n    {\n        fprintf(stderr, \"Error: posición inválida\\n\");\n        return (-1);\n    }\n    if (position == 0)\n        dll_insert_node_beginning(dll, data);\n    else if (position == dll_length(*dll))\n        dll_insert_node_end(dll, data);\n    else\n    {\n        node = (t_doubly_linked_list *)malloc(sizeof(t_doubly_linked_list));\n        if (!node)\n        {\n            fprintf(stderr, \"Error: añadiendo nodo en la posición %d de la lista doblemente enlazada\\n\", position);\n            return (-1);\n        }\n        temp = *dll;\n        while (position-- > 1)\n            temp = temp->next;\n        node->data = data;\n        node->previous = temp;\n        node->next = temp->next;\n        temp->next->previous = node;\n        temp->next = node;\n    }\n    return (0);\n}\n\nint dll_delete(t_doubly_linked_list **dll)\n{\n    t_doubly_linked_list    *temp;\n    t_doubly_linked_list    *temp2;\n\n    if (!(*dll))\n    {\n        fprintf(stderr, \"Error: lista doblemente enlazada nula\\n\");\n        return (-1);\n    }\n    temp2 = (*dll)->next;\n    while (*dll)\n    {\n        temp = (*dll)->previous;\n        free(*dll);\n        *dll = temp;\n    }\n    while (temp2)\n    {\n        *dll = temp2;\n        temp2 = temp2->next;\n        free(*dll);\n    }\n    *dll = NULL;\n    return (0);\n}\n\nint dll_delete_first_node(t_doubly_linked_list **dll)\n{\n    t_doubly_linked_list    *temp;\n\n    if (!(*dll))\n    {\n        fprintf(stderr, \"Error: lista doblemente enlazada nula\\n\");\n        return (-1);\n    }\n    temp = (*dll)->next;\n    free(*dll);\n    if (temp)\n        temp->previous = NULL;\n    *dll = temp;\n}\n\nint dll_delete_last_node(t_doubly_linked_list **dll)\n{\n    t_doubly_linked_list    *temp;\n    t_doubly_linked_list    *penultimate;\n\n    if (!(*dll))\n    {\n        fprintf(stderr, \"Error: lista doblemente enlazada nula\\n\");\n        return (-1);\n    }\n    temp = *dll;\n    penultimate = NULL;\n    while (temp->next)\n    {\n        penultimate = temp;\n        temp = temp->next;\n    }\n    if (!penultimate)\n    {\n        free(*dll);\n        *dll = NULL;\n    }\n    else\n    {\n        free(temp);\n        penultimate->next = NULL;\n    }\n    return (0);\n}\n\nint dll_delete_nth_node(t_doubly_linked_list **dll, int position)\n{\n    t_doubly_linked_list    *temp;\n    t_doubly_linked_list    *previous;\n\n    if (!(*dll))\n    {\n        fprintf(stderr, \"Error: lista doblemente enlazada nula\\n\");\n        return (-1);\n    }\n    if (position < 0 || position >= dll_length(*dll))\n    {\n        fprintf(stderr, \"Error: posición inválida\\n\");\n        return (-1);\n    }\n    if (position == 0)\n        dll_delete_first_node(dll);\n    else if (position == dll_length(*dll))\n        dll_delete_last_node(dll);\n    else\n    {\n        temp = *dll;\n        while (position-- > 0)\n        {\n            previous = temp;\n            temp = temp->next;\n        }\n        previous->next = temp->next;\n        temp->next = previous;\n        free(temp);\n    }\n    return (0);\n}\n\nint dll_update_node(t_doubly_linked_list **dll, int new_data, int position)\n{\n    t_doubly_linked_list    *temp;\n\n    if (!(*dll))\n    {\n        fprintf(stderr, \"Error: lista doblemente enlazada nula\\n\");\n        return (-1);\n    }\n    if (position < 0 || position >= dll_length(*dll))\n    {\n        fprintf(stderr, \"Error: posición invalida\\n\");\n        return (-1);\n    }\n    temp = *dll;\n    while (position-- > 0)\n        temp = temp->next;\n    temp->data = new_data;\n    return (0);\n}\n\nint dll_length(t_doubly_linked_list *dll)\n{\n    t_doubly_linked_list    *temp;\n    int                     counter;\n\n    if (!dll)\n    {\n        fprintf(stderr, \"Error: lista doblemente enlazada nula\\n\");\n        return (0);\n    }\n    temp = dll;\n    counter = 0;\n    while (temp)\n    {\n        counter++;\n        temp = temp->next;\n    }\n    temp = dll->previous;\n    while (temp)\n    {\n        counter++;\n        temp = temp->next;\n    }\n    return (counter);\n}\n\nt_doubly_linked_list    *dll_find_data(t_doubly_linked_list *dll, int data)\n{\n    t_doubly_linked_list    *temp;\n\n    if (!dll)\n    {\n        fprintf(stderr, \"Error: lista doblemente enlazada nula\\n\");\n        return (NULL);\n    }\n    temp = dll;\n    while (temp)\n    {\n        if (temp->data == data)\n            return (temp);\n        temp = temp->next;\n    }\n    temp = dll->previous;\n    while (temp)\n    {\n        if (temp->data == data)\n            return (temp);\n        temp = temp->previous;\n    }\n    return (NULL);\n}\n\nvoid    dll_sort(t_doubly_linked_list **dll)\n{\n    int                     temp_data;\n    bool                    is_swapped;\n    t_doubly_linked_list    *temp;\n\n    if (!(*dll))\n    {\n        fprintf(stderr, \"Error: lista doblemente enlazada nula\\n\");\n        return ;\n    }\n    is_swapped = false;\n    while (!is_swapped)\n    {\n        is_swapped = true;\n        temp = *dll;\n        while (temp->next != NULL)\n        {\n            if (temp->data > temp->next->data)\n            {\n                temp_data = temp->data;\n                temp->data = temp->next->data;\n                temp->next->data = temp_data;\n                is_swapped = false;\n            }\n            temp = temp->next;\n        }\n    }\n}\n\nvoid    dll_print(t_doubly_linked_list *dll)\n{\n    t_doubly_linked_list    *temp;\n\n    if (!dll)\n    {\n        fprintf(stderr, \"Error: lista doblemente enlazada nula\\n\");\n        return ;\n    }\n    temp = dll;\n    while (temp->previous)\n        temp = temp->previous;\n    while (temp)\n    {\n        printf(\"%d\\n\", temp->data);\n        temp = temp->next;\n    }\n}\n\n/* DIFICULTAD EXTRA */\n\nint contact_list(void)\n{\n    int         option;\n    t_contact   *contact;\n\n    option = 0;\n    contact = create_contact_list();\n    if (!contact)\n    {\n        fprintf(stderr, \"Error: creando lista de contactos\\n\");\n        return (-1);\n    }\n    while (option != 6)\n    {\n        if (!contact)\n        {\n            contact = create_contact_list();\n            if (!contact)\n            {\n                fprintf(stderr, \"Error: creando lista de contactos\\n\");\n                return (-1);\n            }\n        }\n        display_menu();\n        printf(\"Elige una opción: \");\n        if (scanf(\"%d\", &option) != 1)\n        {\n            fprintf(stderr, \"Error: leyendo la opción\\n\");\n            break ;\n        }\n        handle_option(option, &contact);\n    }\n    delete_contact_list(&contact);\n    return (0);\n}\n\nvoid    display_menu(void)\n{\n    printf(\"========================================\\n\");\n    printf(\"\\t   Lista de contactos\\n\");\n    printf(\"========================================\\n\");\n    printf(\"\\t1. Añadir contacto\\n\");\n    printf(\"\\t2. Actualizar contacto\\n\");\n    printf(\"\\t3. Buscar contacto\\n\");\n    printf(\"\\t4. Eliminar contacto\\n\");\n    printf(\"\\t5. Mostrar contactos\\n\");\n    printf(\"\\t6. Salir\\n\");\n    printf(\"=========================================\\n\");\n}\n\nvoid    handle_option(int option, t_contact **contact)\n{\n    t_contact   *temp;\n    printf(\"\\n\");\n    switch (option)\n    {\n        case 1:\n            add_contact(contact);\n            break;\n        case 2:\n            update_contact(contact);\n            break;\n        case 3:\n            temp = search_contact(*contact, 0);\n            if (temp)\n            {\n                printf(\"Nombre: %s\\n\", temp->name);\n                printf(\"Número de teléfono: %llu\\n\", temp->phone_number);\n            }\n            else\n                fprintf(stderr, \"Error: el contacto no existe\\n\");\n            break;\n        case 4:\n            delete_contact(contact);\n            break;\n        case 5:\n            display_contacts(*contact);\n            break;\n        case 6:\n            printf(\"Saliendo...\\n\");\n            break;\n        default:\n            fprintf(stderr, \"Error: Opción inválida\\n\");\n            break;\n    }\n}\n\nvoid    add_contact(t_contact **contact)\n{\n    t_contact   *new_contact;\n    t_contact   *temp;\n\n    if (!(*contact))\n    {\n        fprintf(stderr, \"Error: lista de contactos vacía\\n\");\n        return ;\n    }\n    if (!(*contact)->name[0])\n    {\n        printf(\"Introduce el nombre del contacto: \");\n        if (scanf(\"%49s\", (*contact)->name) != 1)\n        {\n            fprintf(stderr, \"Error: añadiendo nuevo contacto\\n\");\n            return ;\n        }\n        printf(\"Introduce el número de %s: \", (*contact)->name);\n        if (scanf(\"%llu\", &((*contact)->phone_number)) != 1)\n        {\n            fprintf(stderr, \"Error: añadiendo nuevo contacto\\n\");\n            return ;\n        }\n    }\n    else\n    {\n        new_contact = (t_contact *)malloc(sizeof(t_contact));\n        if (!new_contact)\n        {\n            fprintf(stderr, \"Error: añadiendo nuevo contacto\\n\");\n            return ;\n        }\n        printf(\"Introduce el nombre del contacto: \");\n        if (scanf(\"%49s\", new_contact->name) != 1)\n        {\n            fprintf(stderr, \"Error: añadiendo nuevo contacto\\n\");\n            free(new_contact);\n            return ;\n        }\n        printf(\"Introduce el número de %s: \", new_contact->name);\n        if (scanf(\"%llu\", &(new_contact->phone_number)) != 1)\n        {\n            fprintf(stderr, \"Error: añadiendo nuevo contacto\\n\");\n            free(new_contact);\n            return ;\n        }\n        if (search_contact(*contact, new_contact->phone_number))\n        {\n            fprintf(stderr, \"Error: el número ya existe\\n\");\n            free(new_contact);\n            return ;\n        }\n        temp = *contact;\n        while (temp->next)\n            temp = temp->next;\n        temp->next = new_contact;\n        new_contact->previous = temp;\n        new_contact->next = NULL;\n    }\n}\n\nvoid    update_contact(t_contact **contact)\n{\n    int                 option;\n    t_contact           *temp;\n    unsigned long long  temp_phone_number;\n\n    if (!(*contact))\n    {\n        fprintf(stderr, \"Error: lista de contactos vacía\\n\");\n        return ;\n    }\n    printf(\"Introduce el número de teléfono: \");\n    if (scanf(\"%lld\", &temp_phone_number) != 1)\n    {\n        fprintf(stderr, \"Error: leyendo el número de teléfono\\n\");\n        return ;\n    }\n    temp = search_contact(*contact, temp_phone_number);\n    if (!temp)\n    {\n        fprintf(stderr, \"Error: el contacto no existe\\n\");\n        return ;\n    }\n    printf(\"Introduce 1 si quieres actualizar el nombre o 2 si quieres actualizar el número: \");\n    if (scanf(\"%d\", &option) != 1)\n    {\n        fprintf(stderr, \"Error: leyendo la opción\\n\");\n        return ;\n    }\n    if (option == 1)\n    {\n        printf(\"El nombre actual es %s\\n\", temp->name);\n        memset(temp->name, 0, 50);\n        printf(\"Introduce el nuevo nombre: \");\n        if (scanf(\"%49s\", temp->name) != 1)\n        {\n            fprintf(stderr, \"Error: leyendo el nombre\\n\");\n            return ;\n        }\n    }\n    else if (option == 2)\n    {\n        printf(\"El número actual es %llu\\n\", temp->phone_number);\n        printf(\"Introduce el nuevo número de teléfono: \");\n        if (scanf(\"%llu\", &temp->phone_number) != 1)\n        {\n            fprintf(stderr, \"Error: leyendo el número de teléfono\\n\");\n            return ;\n        }\n    }\n    else\n        fprintf(stderr, \"Error: opción inválida\\n\");\n}\n\nt_contact   *search_contact(t_contact *contact, unsigned long long phone_number)\n{\n    t_contact           *temp;\n    unsigned long long  temp_phone_number;\n\n    if (!contact)\n    {\n        fprintf(stderr, \"Error: lista de contactos vacía\\n\");\n        return (NULL);\n    }\n    temp_phone_number = phone_number;\n    if (temp_phone_number == 0)\n    {\n        printf(\"Introduce el número de teléfono que quieres buscar: \");\n        if (scanf(\"%llu\", &temp_phone_number) != 1)\n        {\n            fprintf(stderr, \"Error: leyendo el número de teléfono\\n\");\n            return (NULL);\n        }\n    }\n    temp = contact;\n    while (temp)\n    {\n        if (temp->phone_number == temp_phone_number)\n            return (temp);\n        temp = temp->previous;\n    }\n    temp = contact->next;\n    while (temp)\n    {\n        if (temp->phone_number == temp_phone_number)\n            return (temp);\n        temp = temp->next;\n    }\n    return (NULL);\n}\n\nvoid    delete_contact(t_contact **contact)\n{\n    t_contact           *temp;\n    unsigned long long  temp_phone_number;\n\n    if (!(*contact))\n    {\n        fprintf(stderr, \"Error: lista de contactos vacía\\n\");\n        return ;\n    }\n    printf(\"Introduce el número de teléfono del contacto que quieres eliminar: \");\n    if (scanf(\"%llu\", &temp_phone_number) != 1)\n    {\n        fprintf(stderr, \"Error: leyendo el número de teléfono\\n\");\n        return ;\n    }\n    temp = search_contact(*contact, temp_phone_number);\n    if (!temp)\n    {\n        fprintf(stderr, \"Error: el contacto no existe\\n\");\n        return ;\n    }\n    if (temp->previous)\n        temp->previous->next = temp->next;\n    else\n    {\n        *contact = temp->next;\n        if (*contact)\n            (*contact)->previous = NULL;\n    }\n    if (temp->next)\n        temp->next->previous = temp->previous;\n    free(temp);\n}\n\nvoid    display_contacts(t_contact *contact)\n{\n    t_contact   *temp;\n\n    if (!contact || !contact->name[0])\n    {\n        fprintf(stderr, \"Error: lista de contactos vacía\\n\");\n        return ;\n    }\n    temp = contact;\n    while (temp->previous)\n        temp = temp->previous;\n    while (temp)\n    {\n        printf(\"Nombre: %s\\n\", temp->name);\n        printf(\"Teléfono: %llu\\n\", temp->phone_number);\n        temp = temp->next;\n    }\n}\n\nt_contact   *create_contact_list(void)\n{\n    t_contact   *contact;\n\n    contact = (t_contact *)malloc(sizeof(t_contact));\n    if (!contact)\n    {\n        fprintf(stderr, \"Error: creando la lista de contactos\\n\");\n        return (NULL);\n    }\n    memset(contact->name, 0, 50);\n    contact->phone_number = 0;\n    contact->previous = NULL;\n    contact->next = NULL;\n    return (contact);\n}\n\nvoid    delete_contact_list(t_contact **contact)\n{\n    t_contact   *temp;\n\n    if (!(*contact)) \n    {\n        fprintf(stderr, \"Error: lista de contactos vacía\\n\");\n        return ;\n    }\n    temp = *contact;\n    while (temp->previous)\n        temp = temp->previous;\n    while (temp)\n    {\n        *contact = temp;\n        temp = temp->next;\n        free(*contact);\n    }\n    *contact = NULL;\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/c#/Andreavzqz.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\n\nclass Program\n{\n    static void Main (string[] args)\n    {\n        //LISTA\n        List<int> myList = new List<int> { 3, 1, 4, 1, 5, 9 };\n        myList.Add(2);  // Insercion\n        myList.Remove(1); // Borrado (elimina la primera aparicion del 1)\n        myList[2] = 8; // Actualizacion\n        myList.Sort(); // Orientacion\n        console.WriteLine(\"Lista \" + string.Join(\", \" , myList));\n\n        //CONJUNTO(hashSet)\n        HashSet<int> mySet = new HashSet<int> { 3, 1, 4, 1, 5, 9};\n        mySet.Add(2); // Insercion\n        mySet.Remove(1); //Borrado \n        // Los conjuntos no tienen una actualización directa, se puede eliminar y volver a agregar\n        mySet.Remove(9);\n        mySet.Add(9);\n        // Ordenación no aplicable directamente a conjuntos, pero podemos convertir a lista para ordenación\n        List<int> sortedSet = new List<int>(mySet);\n        sortedSet.Sort();\n        console.WriteLine(\"Conjunto \" + string.Join(\", \", sortedSet));\n\n        //PILA\n        Stack<int> myStack = new Stack<int>();\n        myStack.Push(3); // Insercion\n        myStack.Push(1); \n        myStack.Push(4);\n        int top = myStack.Pop(); // Borrado\n        console.WriteLine(\"Pila: \" + string.Join(\", \", myStack));\n\n        //COLA\n        Queue<int> myQueue = new Queue<int>();\n        myQueue.Enqueue(3); // Insercion\n        myQueue.Enqueue(1);\n        myQueue.Enqueue(4);\n        int front = myQueue.Dequeue(); // Borrado\n        console.WriteLine(\"Cola: \" + string.Join(\", \", myQueue));\n\n        //DICCIONARIO\n        Dictionary<string, int> myDict = new Dictionary<string, int>();\n        myDict[\"a\"] = 3; // Insercion\n        myDict[\"b\"] = 1;\n        myDict[\"c\"] = 4;\n        myDict[\"d\"] = 8; // Actualizacion\n        myDict.Remove(\"b\"); // Borrado\n        foreach (var kvp in myDict)\n        {\n            console.WriteLine(\"Diccionario: {0} = {1}\", kvp.Key, kvp.Value);\n        }\n\n        //ARRAY\n        int[] myArray = {3, 1, 4, 1, 5, 9};\n        Array.Sort(myArray); // Ordenacion\n        myArray[2] = 8; // Actualizacion\n        console.WriteLine(\"Array: \" + string.Join(\", \", myArray));\n\n        //LINKEDLIST\n        LinkedList<int> myLinkedList = new LinkedList<int>(new int[] { 3, 1, 4, 1, 5, 9});\n        myLinkedList.AddLast(2); // Insercion\n        myLinkedList.Remove(1); // Borrado\n        var node = myLinkedList.Find(4);\n        if (node != null)\n        {\n            myLinkedList.AddAfter(node, 8); // Actualizacion simulada\n        }\n        // LinkedList no tiene un metodo de ordenacion nativo\n        myList<int> sortedLinkedList = new myList<int>(myLinkedList);\n        sortedLinkedList.Sort();\n        console.WriteLine(\"LinkedList: \" + string.Join(\", \", sortedLinkedList));\n\n    }\n\n/*\nExplicación:\n\nList:\nInserción: Add\nBorrado: Remove\nActualización: Acceder por índice y asignar\nOrdenación: Sort\n\nHashSet:\nInserción: Add\nBorrado: Remove\nActualización: No aplicable directamente, se simula con Remove y Add\nOrdenación: Convertir a List y usar Sort\n\nStack:\nInserción: Push\nBorrado: Pop\n\nQueue:\nInserción: Enqueue\nBorrado: Dequeue\n\nDictionary:\nInserción: Asignación a una clave\nBorrado: Remove\nActualización: Asignación a una clave\n\nArray:\nActualización: Acceder por índice y asignar\nOrdenación: Array.Sort\n\nLinkedList:\nInserción: AddLast\nBorrado: Remove\nActualización: No aplicable directamente, se simula con AddAfter\nOrdenación: Convertir a List y usar Sort\n*/\n\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/c#/Arkmiguel379.cs",
    "content": "﻿//==================== ESTRUCTURAS DE DATOS ====================\n\n// ARREGLO/ARRAY (Almacenan elementos de manera contigua en memoria y permiten un acceso rápido mediante índices)\n\nConsole.WriteLine(\"===== ARRAY / ARREGLO ===== \\n\");\n\nint[] array = { 1, 5, 3, 2, 4 };\n\nforeach (int elemento in array)\n{\n    Console.WriteLine(elemento);\n}\n\nConsole.WriteLine(\"\\n\");\n\n// INSERSION <-- Insersion como tal no se puede\n\nConsole.WriteLine(\"ARRAY con 'insercion' \\n\");\n\nint[] nuevoArray = new int[array.Length + 1]; // <-- Lo que hay que hacer es crear otro array que contenga la misma cantidad de indices del array original + 1\n\nfor (int i = 0; i < array.Length; i++)\n{\n    nuevoArray[i] = array[i];\n}\n\nnuevoArray[array.Length] = 6;\n\nforeach (int elemento in nuevoArray)\n{\n    Console.WriteLine(elemento);\n}\n\nConsole.WriteLine(\"\\n\");\n\n// ORDENACION \n\nConsole.WriteLine(\"ARRAY ordenada \\n\");\n\nArray.Sort(array);\n\nforeach (int elemento in array)\n{\n    Console.WriteLine(elemento);\n}\n\nConsole.WriteLine(\"\\n\");\n\n// ACTUALIZACION\n\nConsole.WriteLine(\"ARRAY actualizada \\n\");\n\narray[4] = 379;\n\nforeach (int elemento in array)\n{\n    Console.WriteLine(elemento);\n}\n\nConsole.WriteLine(\"\\n\");\n\n\n// LISTA/LIST (Dinámicamente redimensionables y proporcionan métodos para insertar, eliminar y buscar elementos)\n\nConsole.WriteLine(\"===== LIST / LISTA ===== \\n\");\n\nList<int> lista = new List<int> { 1, 5, 3, 2, 4 };\n\nforeach (int elemento in lista)\n{\n    Console.WriteLine(elemento);\n}\n\nConsole.WriteLine(\"\\n\");\n\n// INSERCION\n\nConsole.WriteLine(\"LISTA con insercion \\n\");\n\nlista.Add(6);\n\nforeach (int elemento in lista)\n{\n    Console.WriteLine(elemento);\n}\n\nConsole.WriteLine(\"\\n\");\n\n// ELIMINACION\n\nConsole.WriteLine(\"LISTA con eliminacion \\n\");\n\nlista.Remove(6);\n\nforeach (int elemento in lista)\n{\n    Console.WriteLine(elemento);\n}\n\nConsole.WriteLine(\"\\n\");\n\n// ORDENACION\n\nConsole.WriteLine(\"LISTA con ordenacion \\n\");\n\nlista.Sort();\n\nforeach (int elemento in lista)\n{\n    Console.WriteLine(elemento);\n}\n\nConsole.WriteLine(\"\\n\");\n\n// ACTUALIZACION \n\nConsole.WriteLine(\"LISTA con actualizacion \\n\");\n\nlista[0] = 89;\n\nforeach (int elemento in lista)\n{\n    Console.WriteLine(elemento);\n}\n\nConsole.WriteLine(\"\\n\");\n\n\n\n// PILA/STACK (Implementan el principio LIFO (último en entrar, primero en salir))\n\nConsole.WriteLine(\"===== PILA / STACK ===== \\n\");\n\nStack<int> stack = new Stack<int>(new[] {1, 2, 3, 4, 5});\n\n\nforeach (int elemento in stack)\n{\n    Console.WriteLine(elemento);\n}\n\nConsole.WriteLine(\"\\n\");\n\n// INSERCION \n\nConsole.WriteLine(\"PILA con Insercion \\n\");\n\nstack.Push(6);\n\nforeach (int elemento in stack)\n{\n    Console.WriteLine(elemento);\n}\n\nConsole.WriteLine(\"\\n\");\n\n//ELIMINACION\n\nConsole.WriteLine(\"PILA con Eliminacion \\n\");\n\nstack.Pop();\n\nforeach (int elemento in stack)\n{\n    Console.WriteLine(elemento);\n}\n\nConsole.WriteLine(\"\\n\");\n\n// COLAS/QUEUE Implementan el principio FIFO (primero en entrar, primero en salir))\n\nConsole.WriteLine(\"===== COLA / QUEUE ===== \\n\");\n\nQueue<int> cola = new Queue<int>(new[] { 1, 2, 3, 4, 5 });\n\nforeach (int elemento in cola)\n{\n    Console.WriteLine(elemento);\n}\n\nConsole.WriteLine(\"\\n\");\n\n// INSERCION \n\nConsole.WriteLine(\"COLA con Insercion \\n\");\n\ncola.Enqueue(6);\n\nforeach (int elemento in cola)\n{\n    Console.WriteLine(elemento);\n}\n\nConsole.WriteLine(\"\\n\");\n\n// INSERCION \n\nConsole.WriteLine(\"COLA con Eliminacion \\n\");\n\ncola.Dequeue();\n\nforeach (int elemento in cola)\n{\n    Console.WriteLine(elemento);\n}\n\nConsole.WriteLine(\"\\n\");\n\n// CONJUNTOS/HASHSET (Almacenan elementos únicos sin duplicados)\n\nConsole.WriteLine(\"===== CONJUNTOS / HASHSET ===== \\n\");\n\nHashSet<int> conjunto = new HashSet<int> { 1, 2, 3, 4, 5};\n\n// INSERCION \n\nConsole.WriteLine(\"CONJUNTO con Insercion \\n\");\n\nconjunto.Add(6);\n\nforeach (int elemento in conjunto)\n{\n    Console.WriteLine(elemento);\n}\n\nConsole.WriteLine(\"\\n\");\n\n// ELIMINACION \n\nConsole.WriteLine(\"CONJUNTO con Eliminacion \\n\");\n\nconjunto.Remove(6);\n\nforeach (int elemento in conjunto)\n{\n    Console.WriteLine(elemento);\n}\n\nConsole.WriteLine(\"\\n\");\n\nHashSet<int> conjunto2 = new HashSet<int> { 6, 7, 8, 4, 10 };\n\nconjunto.UnionWith(conjunto2);\n\nforeach (int elemento in conjunto)\n{\n    Console.WriteLine(elemento);\n}\n\nConsole.WriteLine(\"\\n\");\n\n\n// DICCIONARIO/DICCIONARY (Almacenan pares clave-valor y proporcionan acceso rápido a los valores mediante las claves)\n\nConsole.WriteLine(\"===== DICCIONARIO / DICCIONARY ===== \\n\");\n\nDictionary<string, string> diccionario = new Dictionary<string, string>()\n{\n    {\"Nombre\", \"Miguel\"},\n    {\"Apellido\", \"Moreno\"},\n    {\"Edad\", \"28\"},\n    {\"Alias\", \"Logan\"}\n};\n\nforeach (var dict in diccionario)\n{\n    string clave = dict.Key;\n    string valor = dict.Value;\n\n    Console.WriteLine($\"{clave} {valor}\");\n}\n\nConsole.WriteLine(\"\\n\");\n\n// INSERCION \n\nConsole.WriteLine(\"DICCIONARIO con Insercion \\n\");\n\ndiccionario.Add(\"Correo\", \"arkangel-159@hotmail.com\"); // <-- El metodo Add se encarga de agregar un nuevo registro en el diccionario\n\nforeach (var dict in diccionario)\n{\n    string clave = dict.Key;\n    string valor = dict.Value;\n\n    Console.WriteLine($\"{clave} {valor}\");\n}\n\nConsole.WriteLine(\"\\n\");\n\n// ACTUALIZACION \n\nConsole.WriteLine(\"DICCIONARIO con Actualizacion \\n\");\n\ndiccionario[\"Correo\"] = \"blaziken.257@gmail.com\"; /* <-- Se escribe la clave y posteriormente se le modifica el nuevo valor que se desea \n                                                    asignar */\n\nforeach (var dict in diccionario)\n{\n    string clave = dict.Key;\n    string valor = dict.Value;\n\n    Console.WriteLine($\"{clave} {valor}\");\n}\n\nConsole.WriteLine(\"\\n\");\n\n// ELIMINACION \n\nConsole.WriteLine(\"DICCIONARIO con Eliminacion \\n\");\n\ndiccionario.Remove(\"Correo\"); // <-- El metodo Remove se encarga de eliminar un registro en el diccionario segun la clave que le sea escrita\n\nforeach (var dict in diccionario)\n{\n    string clave = dict.Key;\n    string valor = dict.Value;\n\n    Console.WriteLine($\"{clave} {valor}\");\n}\n\nConsole.WriteLine(\"\\n\");\n\n// ORDENACION\n\nSortedDictionary<string, string> diccionarioO = new SortedDictionary<string, string>() /* <-- La clase SortedDictionary hace un diccionario \n                                                                                         que se ordena solo */\n{\n    {\"Nombre\", \"Miguel\"},\n    {\"Apellido\", \"Moreno\"},\n    {\"Edad\", \"28\"},\n    {\"Alias\", \"Logan\"},\n    {\"Correo\", \"blaziken.257@gmail.com\"}\n};\n\nforeach (var dic in diccionarioO)\n{\n    string clave = dic.Key;\n    string valor = dic.Value;\n\n    Console.WriteLine($\"{clave} {valor}\");\n}\n\nConsole.WriteLine(\"\\n\");\n\n// ==================== EXTRA =========================\n\nDictionary<string, int> agenda = new Dictionary<string, int>()\n{\n    {\"Miguel\", 379},\n    {\"Daniel\", 257},\n    {\"Juan\", 654},\n    {\"Claudia\", 258}\n};\n\nbool operacion = false;\n\nwhile (!operacion)\n{\n    Console.WriteLine(\"=== AGENDA === \\n\");\n    Console.WriteLine(\"Oprime el numero correspondiente para cada accion \\n \\n 1. Buscar Contacto \\n 2. Insertar Contacto \\n 3. Actualizar Contacto \\n 4. Eliminar Contacto \\n\");\n    string accion = Console.ReadLine();\n    Console.WriteLine();\n\n    if (accion == \"1\")\n    {\n        Console.WriteLine(\"Escribe el nombre o el numero del contacto que deseas buscar \\n\");\n        string dato = Console.ReadLine();\n        Console.WriteLine();\n\n        int value;\n        int.TryParse(dato, out value);\n\n        while (!agenda.ContainsKey(dato) && !agenda.ContainsValue(value))\n        {\n            Console.WriteLine(\"No se ha encontrado el nombre o numero ingresado \\n Intentalo nuevamente \\n\");\n            dato = Console.ReadLine();\n            int.TryParse(dato, out value);\n            Console.WriteLine();\n        }\n\n        foreach (var contacto in agenda)\n        {\n            string clave = contacto.Key;\n            int valor = contacto.Value;\n\n            if (clave == dato || valor.ToString() == dato)\n            {\n                Console.WriteLine($\"Contacto encontrado: {clave} {valor} \\n\");\n                break;\n            }\n        } \n    }\n    else if (accion == \"2\")\n    {\n        Console.WriteLine(\"Escribe el nombre y el numero del contacto que deseas crear \\n El numero no debe de exceder los 11 digitos \\n\");\n        Console.Write(\"Nombre: \");\n        string nombre = Console.ReadLine();\n        \n\n        Console.Write(\"Numero: \");\n\n        int maxLen = 11;\n        string numero;\n        int numV = 0;\n        bool numeroValido = false;\n\n        while (!numeroValido)\n        {\n            numero = Console.ReadLine();\n            Console.WriteLine();\n\n            if (numero.Length > maxLen)\n            {\n                Console.WriteLine(\"El numero excede los 11 digitos. Ingrese un numero que no exceda esa cantidad \\n\");\n            }\n            else\n            {\n                if (int.TryParse(numero, out numV))\n                {\n                    numeroValido = true;\n                }\n                else\n                {\n                    Console.WriteLine(\"Valor ingresado no valido \\n Ingrese un valor que sea numerico \\n\");\n                }\n            }\n        }\n\n        agenda.Add(nombre, numV);\n\n    }\n    else if (accion == \"3\")\n    {\n        Console.WriteLine(\"¿Que deseas actualizar? \\n 1.Nombre \\n 2.Numero \\n\");\n\n        string update = Console.ReadLine();\n        Console.WriteLine();\n\n        if (update == \"1\")\n        {\n            Console.Write(\"Ingresa el nombre del contacto que deseas cambiar: \");\n            string nombreA = Console.ReadLine();\n            Console.WriteLine();\n\n            while (!agenda.ContainsKey(nombreA))\n            {\n                Console.WriteLine(\"El nombre ingresado no existe \\n Intentalo nuevamente \\n\");\n                nombreA = Console.ReadLine();\n                Console.WriteLine();\n            }\n\n            if (agenda.ContainsKey(nombreA))\n            {\n                Console.Write(\"Ingresa el nuevo nombre: \");\n                string nombreN = Console.ReadLine();\n                Console.WriteLine();\n\n                Console.WriteLine(\"\");\n\n                ActualizarClave(agenda, nombreA, nombreN);\n\n                Console.WriteLine($\"El nombre del contacto {nombreA} ha sido actualizado a {nombreN} \\n\");\n            }\n        }\n        else if (update == \"2\")\n        {\n            Console.Write(\"Ingresa el nombre del contacto que deseas cambiar: \");\n            string nombreA = Console.ReadLine();\n            Console.WriteLine();\n\n            while (!agenda.ContainsKey(nombreA))\n            {\n                Console.WriteLine(\"El nombre ingresado no existe \\n Intentalo nuevamente \\n\");\n                nombreA = Console.ReadLine();\n                Console.WriteLine();\n            }\n\n            Console.Write(\"Ingresa el nuevo numero: \");\n\n            string numero;\n            int numV = 0;\n            bool numeroValido = false;\n\n            while (!numeroValido)\n            {\n                numero = Console.ReadLine();\n                Console.WriteLine();\n\n                if (int.TryParse(numero, out numV))\n                {\n                    numeroValido = true;\n                }\n                else\n                {\n                    Console.WriteLine(\"Valor ingresado no valido \\n Ingrese un valor que sea numerico \\n\");\n                }\n            }\n\n            agenda[nombreA] = numV;\n\n            Console.WriteLine($\"Numero actualizado a {numV} \\n\");\n        }\n    }\n    else if (accion == \"4\")\n    {\n        Console.WriteLine(\"Escribe el nombre del contacto que deseas eliminar \\n\");\n        string del = Console.ReadLine();\n        Console.WriteLine();\n\n        while (!agenda.ContainsKey(del))\n        {\n            Console.WriteLine(\"El nombre ingresado no existe \\n Intentalo nuevamente \\n\");\n            del = Console.ReadLine();\n            Console.WriteLine();\n        }\n\n        agenda.Remove(del);\n    }\n\n    Console.WriteLine(\"¿Deseas seguir trabajando en la agenda? \\n 1. Si \\n 2. No \\n\");\n\n    bool close = false;\n\n    while (!close) {\n\n        string rep = Console.ReadLine();\n        Console.WriteLine();\n\n        if (rep == \"1\")\n        {\n            close = true;\n        }\n        else if (rep == \"2\")\n        {\n            Console.WriteLine(\"Agenda cerrada\");\n            close = true;\n            operacion = true;\n        }\n        else\n        {\n            Console.WriteLine(\"Comando no valido. Ingrese alguno de los comandos que se muestran en pantalla \\n\");\n        }\n    }\n\n    Console.WriteLine(\"\\n\");\n\n    foreach (var contacto in agenda)\n    {\n        string clave = contacto.Key;\n        int valor = contacto.Value;\n\n        Console.WriteLine(clave + \" \" + valor);\n    }\n\n    Console.WriteLine();\n}\n\n// =================================================================================\n\nstatic void ActualizarClave(Dictionary<string,int> diccionario, string claveAntigua, string claveNueva)\n{\n    if (diccionario.ContainsKey(claveAntigua))\n    {\n        int valor = diccionario[claveAntigua];\n\n        diccionario.Remove(claveAntigua);\n\n        diccionario.Add(claveNueva, valor);\n    }\n    else\n    {\n        Console.WriteLine(\"La clave proporcionada no existe\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/c#/Esaens12.cs",
    "content": "﻿using System;\r\nusing System.Collections.Generic;\r\nusing System.IO;\r\nusing System.Security.Cryptography.X509Certificates;\r\nusing System.Text.Json;\r\n\r\nnamespace _03_ESTRUCTURA_DE_DATOS\r\n{\r\n    internal class Program\r\n    {\r\n        static void Main(string[] args)\r\n        {\r\n\r\n            /*\r\n * EJERCICIO:\r\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto\r\n *   en tu lenguaje.\r\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\r\n *\r\n * DIFICULTAD EXTRA (opcional):\r\n * Crea una agenda de contactos por terminal.\r\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\r\n *   y eliminación de contactos.\r\n * - Cada contacto debe tener un nombre y un número de teléfono.\r\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\r\n *   y a continuación los datos necesarios para llevarla a cabo.\r\n * - El programa no puede dejar introducir números de teléfono no númericos y con más\r\n *   de 11 dígitos (o el número de dígitos que quieras).\r\n * - También se debe proponer una operación de finalización del programa.\r\n */\r\n\r\n            // --------------------\r\n            // Listas\r\n            // --------------------\r\n\r\n            // Crear una lista de enteros y agregar algunos elementos iniciales\r\n            List<int> numeros = new List<int> { 1, 2, 3 };\r\n\r\n            // Eliminar el elemento con valor 2 de la lista\r\n            numeros.Remove(2);\r\n\r\n            // Actualizar el primer elemento de la lista a 10\r\n            numeros[0] = 10;\r\n\r\n            // Ordenar la lista en orden ascendente\r\n            numeros.Sort();\r\n\r\n            // --------------------\r\n            // Colas\r\n            // --------------------\r\n\r\n            // Crear una cola de cadenas\r\n            Queue<string> cola = new Queue<string>();\r\n\r\n            // Insertar elementos en la cola\r\n            cola.Enqueue(\"A\");\r\n            cola.Enqueue(\"B\");\r\n            cola.Enqueue(\"C\");\r\n\r\n            // Eliminar y retornar el primer elemento de la cola \r\n            cola.Dequeue();\r\n\r\n            // Obtener el primer elemento de la cola sin eliminarlo\r\n            string primeroCola = cola.Peek();\r\n\r\n            // --------------------\r\n            // Pilas\r\n            // --------------------\r\n\r\n            // Crear una pila de enteros\r\n            Stack<int> pila = new Stack<int>();\r\n\r\n            // Insertar elementos en la pila\r\n            pila.Push(1);\r\n            pila.Push(2);\r\n            pila.Push(3);\r\n\r\n            // Eliminar y retornar el último elemento insertado en la pila (LIFO - Last In, First Out)\r\n            pila.Pop();\r\n\r\n            // Obtener el último elemento insertado en la pila sin eliminarlo\r\n            int topePila = pila.Peek();\r\n\r\n            // --------------------\r\n            // Conjuntos\r\n            // --------------------\r\n\r\n            // Crear un conjunto de enteros y agregar algunos elementos iniciales\r\n            HashSet<int> conjunto = new HashSet<int> { 1, 2, 3 };\r\n\r\n            // Eliminar el elemento con valor 2 del conjunto\r\n            conjunto.Remove(2);\r\n\r\n            // Verificar si el elemento con valor 1 está en el conjunto\r\n            bool existeEnConjunto = conjunto.Contains(1);\r\n\r\n            // --------------------\r\n            // Diccionarios\r\n            // --------------------\r\n\r\n            // Crear un diccionario con claves enteras y valores de cadena, y agregar algunos elementos iniciales\r\n            Dictionary<int, string> diccionario = new Dictionary<int, string>\r\n            {\r\n               {1, \"Uno\"},\r\n               {2, \"Dos\"},\r\n               {3, \"Tres\"}\r\n            };\r\n\r\n            // Eliminar el par clave-valor con clave 2 del diccionario\r\n            diccionario.Remove(2);\r\n\r\n            // Actualizar el valor asociado a la clave 1\r\n            diccionario[1] = \"Uno Modificado\";\r\n\r\n            // Obtener el valor asociado a la clave 1\r\n            string valorDiccionario = diccionario[1];\r\n\r\n            // --------------------\r\n            // Mostrar resultados\r\n            // --------------------\r\n\r\n            // Mostrar el contenido de la lista\r\n            Console.WriteLine(\"Lista: \" + string.Join(\", \", numeros));\r\n\r\n            // Mostrar el primer elemento de la cola\r\n            Console.WriteLine(\"Primero en la cola: \" + primeroCola);\r\n\r\n            // Mostrar el último elemento insertado en la pila\r\n            Console.WriteLine(\"Tope de la pila: \" + topePila);\r\n\r\n            // Mostrar si el elemento con valor 1 existe en el conjunto\r\n            Console.WriteLine(\"Existe en conjunto: \" + existeEnConjunto);\r\n\r\n            // Mostrar el valor asociado a la clave 1 en el diccionario\r\n            Console.WriteLine(\"Valor en diccionario: \" + valorDiccionario);\r\n\r\n            Console.WriteLine();\r\n\r\n            string nombre = \"\";\r\n            long telefono = 0;\r\n            string operacion = \"\";\r\n            string entrada = \"\";\r\n            long telefonoMod = 0;\r\n\r\n            string filePath = \"contactos.json\";\r\n            Dictionary<string, long> contactos = CargarContactos(filePath);\r\n           \r\n            bool continuarSwitch = true;\r\n\r\n            while (continuarSwitch)\r\n            {\r\n                Console.WriteLine(\"bienvenido al menu de la agenda\\n\");\r\n\r\n                Console.WriteLine(\"elija una opcion\");\r\n                Console.Write(\"1: busqueda\\n\");\r\n                Console.Write(\"2: insercion\\n\");\r\n                Console.Write(\"3: actualizacion\\n\");\r\n                Console.Write(\"4: eliminacion\\n\");\r\n                Console.Write(\"5: mostrar todos los contactos registrados\\n\");\r\n                Console.Write(\"6: salir y guardar contactos\\n\");\r\n                Console.Write(\"7: limpiar pantalla\\n\\n\");\r\n                int opcion = Convert.ToInt32(Console.ReadLine());\r\n\r\n                switch (opcion)\r\n                {\r\n                    case 1:\r\n                        operacion = \"busqueda\";\r\n                        Console.WriteLine(\"haz escogido: \" + operacion);\r\n\r\n                        Console.Write(\"escriba el nombre del contacto a buscar: \");\r\n                        string busqueda = Console.ReadLine().ToUpper();\r\n\r\n                        if (contactos.TryGetValue(busqueda.ToUpper(), out telefono) || contactos.TryGetValue(busqueda.ToLower(), out telefono))\r\n                        {\r\n                            Console.WriteLine(\"\\nse encontro el siguiente contacto\");\r\n                            Console.WriteLine(\"[\" + busqueda + \" - \" + telefono + \"]\" + \"\\n\");\r\n                            continuarSwitch = false;\r\n\r\n                            Console.WriteLine(@\"presiona \"\"s\"\" para volver al menu\");\r\n                            string volver2 = Console.ReadLine().ToLower();\r\n\r\n                            if (volver2 == \"s\")\r\n                            {\r\n                                continuarSwitch = true;\r\n                            }\r\n                            else\r\n                            {\r\n                                Console.WriteLine(@\"presiona \"\"s\"\" para volver al menu\");\r\n                            }\r\n\r\n                        }\r\n                        else\r\n                        {\r\n                            Console.WriteLine(\"ERROR ERROR (no se encontro el nombre ingresado) ERROR ERROR\\n\");\r\n                        }\r\n\r\n                        break;\r\n\r\n                    case 2:\r\n                        operacion = \"insercion\";\r\n                        Console.WriteLine(\"haz escogido: \" + operacion);\r\n                        bool continuar = true;\r\n\r\n                        while (continuar)\r\n                        {\r\n                            for(int i = 0; i <= 1000; i++) { }\r\n                            Console.Write(\"ingrese un nombre para el contacto: \");\r\n                            nombre = Console.ReadLine();\r\n\r\n                            try\r\n                            {\r\n                                Console.Write(\"ingrese numero telefonico: \");\r\n                                entrada = Console.ReadLine();\r\n\r\n                                telefono = Convert.ToInt64(entrada);\r\n                            }\r\n                            catch (FormatException)\r\n                            {\r\n                                Console.WriteLine(\"favor de introducir numeros solamente\\n\");\r\n                            }\r\n\r\n                            if (contactos.ContainsKey(nombre) || contactos.ContainsKey(nombre.ToLower()))\r\n                            {\r\n                                Console.WriteLine(\"ERROR ERROR (El contacto ya existe) ERROR ERROR\\n\");\r\n                                break;\r\n                            }\r\n\r\n                            if (entrada.Length > 10 || entrada.Length < 10)\r\n                            {\r\n                                Console.WriteLine(\"ERROR ERROR (por favor ingrese un numero de 10 digitos) ERROR ERROR\");\r\n                            }\r\n                            else\r\n                            {\r\n                                contactos[nombre] = telefono;\r\n                  \r\n                                Console.WriteLine(\"el contacto se guardo con exito !!!\\n\");\r\n                                Console.WriteLine(nombre + \" - \" + telefono + \"\\n\");\r\n\r\n                                Console.Write(\"desea agregar otro contacto? (s/n): \");\r\n                                string respuesta = Console.ReadLine();\r\n\r\n                                if (respuesta.ToLower() != \"s\")\r\n                                {\r\n                                    continuar = false;\r\n                                    Console.WriteLine(\"saliendo de \" + operacion + \"..........\\n\");\r\n                                    continuarSwitch = true;\r\n                                }\r\n                                else\r\n                                {\r\n                                    continuar = true;\r\n                                }\r\n                            }\r\n                        }\r\n\r\n                        break;\r\n\r\n                    case 3:\r\n                        operacion = \"actualizacion\";\r\n                        Console.WriteLine(\"haz escogido: \" + operacion);\r\n\r\n                        Console.Write(\"ingrese el nombre del contacto a cambiar su telefono: \\n\");\r\n                        string cosa = Console.ReadLine().ToLower();\r\n\r\n                        if(contactos.TryGetValue(nombre, out telefono))\r\n                        {\r\n                            Console.WriteLine(nombre + \" - \" + telefono + \"\\n\");\r\n\r\n                            Console.Write(\"ingrese el nuevo telefono: \");\r\n                            string entradaMod = Console.ReadLine();\r\n\r\n                            telefonoMod = Convert.ToInt64(entradaMod);\r\n\r\n                            if (telefonoMod != telefono)\r\n                            {\r\n                                telefono = telefonoMod;\r\n                            }\r\n\r\n                            contactos[nombre] = telefono;\r\n\r\n                            Console.WriteLine(\"el contacto se actualizo con exito !!! \\n\");\r\n\r\n                            Console.WriteLine(nombre + \" - \" + telefono + \"\\n\");\r\n\r\n                            continuarSwitch = true;\r\n                        }\r\n                        else\r\n                        {\r\n                            Console.WriteLine(\"no se encontraron resultados\\n\");\r\n                            continuarSwitch = true;\r\n                        }\r\n\r\n                        break;\r\n\r\n                    case 4:\r\n                        operacion = \"eliminacion\";\r\n                        Console.WriteLine(\"haz escogido: \" + operacion);\r\n                        bool borrar = true;\r\n\r\n                        Console.Write(\"ingrese el nombre del contacto a eliminar: \");\r\n                        string busqueda2 = Console.ReadLine().ToUpper();\r\n\r\n                        if(contactos.TryGetValue(busqueda2.ToUpper(), out telefono) || contactos.TryGetValue(busqueda2.ToLower(), out telefono))\r\n                        {\r\n                            Console.WriteLine(busqueda2 + \" - \" + telefono);\r\n                            Console.Write(\"estas seguro de que quieres eliminar este contacto? (s/n): \");\r\n                            string eliminar = Console.ReadLine().ToLower();\r\n\r\n                            if(eliminar != \"s\")\r\n                            {\r\n                                Console.WriteLine(\"eliminacion cancelada\");\r\n                            }\r\n                            else\r\n                            {\r\n                                contactos.Remove(busqueda2);\r\n                                Console.WriteLine(\"!!! el contacto ha sido borrado con exito !!!\\n\");\r\n                            }\r\n\r\n                            continuarSwitch = true;\r\n                        }\r\n\r\n                        break;\r\n\r\n                    case 5:\r\n                        operacion = \"mostrar contactos registrados\\n\\n\";\r\n                        Console.Write(\"haz escogido: \" + operacion);\r\n\r\n                        if(contactos.Count == 0)\r\n                        {\r\n                            Console.WriteLine(\"!!! aun no hay contactos registrados !!!\\n\");\r\n                        }\r\n                        else\r\n                        {\r\n                            continuarSwitch = false;\r\n                            foreach(object contacto in contactos)\r\n                            {\r\n                                Console.WriteLine(contacto);\r\n                            }\r\n                            Console.WriteLine();\r\n\r\n                            Console.WriteLine(@\"presiona \"\"s\"\" para volver al menu\");\r\n                            string volver2 = Console.ReadLine().ToLower();\r\n\r\n                            if(volver2 == \"s\")\r\n                            {\r\n                                continuarSwitch = true;\r\n                            }\r\n                            else\r\n                            {\r\n                                Console.WriteLine(@\"presiona \"\"s\"\" para volver al menu\");\r\n                            }\r\n                        }\r\n\r\n                        break;\r\n\r\n                    case 6:\r\n\r\n                        GuardarContactos(filePath, contactos);\r\n                        continuarSwitch = false;\r\n                        Console.WriteLine(\"saliendo del programa..........\");\r\n\r\n                        break;\r\n\r\n                    case 7:\r\n\r\n                        Console.Clear();\r\n                        break;\r\n\r\n                    default:\r\n                        Console.WriteLine(\"ERROR ERROR (opcion no disponible) ERROR ERROR\");\r\n                        break;\r\n\r\n                }\r\n            }\r\n        }\r\n\r\n        static Dictionary<string, long> CargarContactos(string filePath)\r\n        {\r\n            if (File.Exists(filePath))\r\n            {\r\n                string json = File.ReadAllText(filePath);\r\n                return JsonSerializer.Deserialize<Dictionary<string, long>>(json, new JsonSerializerOptions { PropertyNameCaseInsensitive = true })\r\n                       ?? new Dictionary<string, long>(StringComparer.OrdinalIgnoreCase);\r\n            }\r\n            else\r\n            {\r\n                return new Dictionary<string, long>(StringComparer.OrdinalIgnoreCase);\r\n            }\r\n        }\r\n\r\n        static void GuardarContactos(string filePath, Dictionary<string, long> contactos)\r\n        {\r\n            string json = JsonSerializer.Serialize(contactos, new JsonSerializerOptions { WriteIndented = true });\r\n            File.WriteAllText(filePath, json);\r\n        }\r\n\r\n    }\r\n}\r\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/c#/Isj-code.cs",
    "content": "﻿\n// ## Ejercicio, se hace con las colecciones mas usadas, Hash está en desuso dicho por la documentacion oficial.\n// Basadas en IList\n// Array\n\nint[] array = { 1, 2, 3, 4, 5 };\nConsole.WriteLine(\"----- Array -----\");\nConsole.WriteLine(\"Array base a trabajar\");\nforeach (var item in array)\n{\n    Console.Write($\"{item} \");\n}\n\n// Operaciones con array\nConsole.WriteLine($\"la longitud del array es {array.Length}\");\n// Cambio de dato explicito\narray[0] = 0;\nConsole.WriteLine(\"Cambio del primer valor\");\nforeach (var item in array)\n{\n    Console.Write($\"{item} \");\n}\n\nConsole.WriteLine(\"\");\n// Primer valor\nConsole.WriteLine($\"El primer valor es {array.First()}\");\n// Añadimos al final\nConsole.WriteLine(\"Métodos sin modificar el array original\");\nvar arrayMas = array.Append(5);\nConsole.WriteLine(\"Añadimos otro 5 al final\");\nforeach (var item in arrayMas)\n{\n    Console.Write($\"{item} \");\n}\n\nConsole.WriteLine(\" \");\n// Hacer el reverso\nConsole.WriteLine(\"Reverse\");\nvar arrayRev = array.Reverse();\nforeach (var item in arrayRev)\n{\n    Console.Write($\"{item} \");\n}\n\nConsole.WriteLine(\" \");\n// Pasamos el array a uno nuevo que sea un lista para hacer otro tipo de operaciones\nConsole.WriteLine(\"Pasamos el array a lista\");\nList<int> listaNumeros = array.ToList();\nConsole.WriteLine(\"----- Lista -----\");\nforeach (var item in listaNumeros)\n{\n    Console.Write($\"{item} \");\n}\n// Borrado de una posicion en concreto\nConsole.WriteLine(\"Borramos el indice 0\");\nlistaNumeros.RemoveAt(0);\nforeach (var item in listaNumeros)\n{\n    Console.Write($\"{item} \");\n}\n\nConsole.WriteLine(\"\");\nConsole.WriteLine(\"Recorte de 2 posiciones, desde cero 2 posiciones\");\nvar listaRecorte = listaNumeros.Slice(0, 2);\nforeach (var item in listaRecorte)\n{\n    Console.Write($\"{item} \");\n    \n}\n\nConsole.WriteLine(\"\");\n// Añadimos un rango de varios números de una lista\nConsole.WriteLine(\"Añadimos un rango de nuemeros\");\nlistaNumeros.AddRange([4,2,1,2,3]);\nforeach (var item in listaNumeros)\n{\n    Console.Write($\"{item} \");\n}\n\nConsole.WriteLine(\"\");\n// Sort() para ordenar\nConsole.WriteLine(\"Ordenamos son Sort\");\nlistaNumeros.Sort();\nforeach (var item in listaNumeros)\n{\n    Console.Write($\"{item} \");\n}\nConsole.WriteLine(\"\");\n// Busqueda dentro de la lista\nConsole.WriteLine(\"Busqueda del primer numero 1, en una lista de valores primitivos no es muy útil pero en lista de objetos es muy útil\");\nvar resp = listaNumeros.FirstOrDefault((i) => i == 1);\nConsole.WriteLine(resp);\n\n// Limpieza de la lista\nConsole.WriteLine(\"Vaciamos la lista\");\nlistaNumeros.Clear();\n\n// Dictionary con key int y valor string\n\n// Declaracion\nConsole.WriteLine(\"----- Diccionario -----\");\nDictionary<int, string> dictionary = new Dictionary<int, string>();\n\n// Añadir al dicionario\ndictionary.Add(1,\"Jose\");\ndictionary.Add(3,\"Pepito\");\ndictionary.Add(4,\"Luisita\");\ndictionary.Add(5,\"Maribel\");\n\nforeach (var item in dictionary)\n{\n    Console.WriteLine($\"Key: {item.Key} tiene de valor: {item.Value}\");\n}\n\nvar respDic = dictionary.FirstOrDefault((t) => t.Key == 1);\nConsole.WriteLine($\"La busqueda con clave 1 es: {respDic.Value}\");\n\n// Borrado\ndictionary.Remove(3);\nConsole.WriteLine(\"Borrado del key 3\");\nforeach (var item in dictionary)\n{\n    Console.WriteLine($\"Key: {item.Key} tiene de valor: {item.Value}\");\n}\n\nConsole.WriteLine(\"AHora vamos a buscar todos los valores que tengan una i\");\nvar respWhere = dictionary.Where(t => t.Value.Contains(\"i\"));\nforeach (var item in respWhere)\n{\n    Console.WriteLine($\"Key: {item.Key} tiene de valor: {item.Value}\");\n}\n\nConsole.WriteLine(\"Se ve que Jose no está en la lista\");\n\n// ## Dificultad Extra (opcional)\nConsole.WriteLine(\"-----------------------\");\nConsole.WriteLine(\"--- Ejercicio opcional ---\");\nConsole.WriteLine(\"-----------------------\");\n\nDictionary<string, int> agenda = new Dictionary<string, int>();\nvar entrada = \"\";\n\ndo\n{\n    Console.WriteLine(\"Elige una opción\");\n    Console.WriteLine(\"c-Crear\");\n    Console.WriteLine(\"a-Actualizar\");\n    Console.WriteLine(\"d-Borrar\");\n    Console.WriteLine(\"f-Buscar\");\n    Console.WriteLine(\"x-Salir\");\n    entrada = Console.ReadLine().ToUpper();\n    if (entrada != \"C\" && entrada != \"A\" && entrada != \"D\" & entrada != \"F\" && entrada != \"X\")\n    {\n        Console.WriteLine(\"Eleccion Incorrecta, vuelva a elegir\");\n    }\n    else\n    {\n        var name = \"\";\n        int tlf;\n        switch (entrada)\n        {\n            case \"C\":\n                Console.WriteLine(\"Añada el nombre:\");\n                name = Console.ReadLine().ToUpper().TrimEnd().TrimStart();\n                Console.WriteLine(\"Añada el número, solo 9 digitos \");\n                string? numeroTlf = Console.ReadLine();\n                if (numeroTlf != null && name.Length > 0)\n                {\n                    var sol = int.TryParse(numeroTlf, out tlf);\n                    if (sol == true && numeroTlf.Length < 9)\n                    {\n                        agenda.Add(name, tlf);\n                    }\n                    else\n                    {\n                        Console.WriteLine(\"Ingresa los datos correctos, vuelva a empezar.\");\n                    }\n                }\n                break;\n            case \"F\":\n                Console.WriteLine(\"Ingrese el contacto a buscar: \");\n                string nombreBusqueda = Console.ReadLine().TrimStart().ToUpper().TrimEnd();\n                if (nombreBusqueda != null)\n                {\n                    var respBusqueda = agenda.FirstOrDefault(t => t.Key == nombreBusqueda);\n                    if (respBusqueda.Key != null)\n                    {\n                        Console.WriteLine($\"El nombre {respBusqueda.Key} tiene el telefono {respBusqueda.Value}\");\n                    }\n                    else\n                    {\n                        Console.WriteLine(\"Nombre erroneo o inexistente, intentelo de nuevo\");\n                    }\n                }\n                else\n                {\n                    Console.WriteLine(\"Nombre erroneo o inexistente, intentelo de nuevo\");\n                }\n\n                break;\n            case \"D\":\n                Console.WriteLine(\"Ingrese el contacto a Borrar\");\n                var contactoBorrar = Console.ReadLine().ToUpper().TrimStart().TrimEnd();\n                if (contactoBorrar != null)\n                {\n                    var respDelete = agenda.Remove(contactoBorrar);\n                    if (!respDelete)\n                    {\n                        Console.WriteLine(\"Contacto no econtrado\");\n                    }\n                    else\n                    {\n                        Console.WriteLine(\"Contacto Borrado\");\n                    }\n                }\n                break;\n            case \"A\":\n                Console.WriteLine(\"Ingrese el contacto a Modificar\");\n                var respMod = Console.ReadLine().ToUpper().TrimEnd().TrimStart();\n                if (respMod != null)\n                {\n                    var findMod = agenda.FirstOrDefault((t) => t.Key == respMod);\n                    if (findMod.Key != null)\n                    {\n                        Console.WriteLine(\"Indique su nuevo numero\");\n                        string stringTlf = Console.ReadLine().Trim();\n                        int nuevoTlf;\n                        bool respConvert = int.TryParse(stringTlf, out nuevoTlf);\n                        if (respConvert)\n                        {\n                            agenda[findMod.Key] = nuevoTlf; \n                        }\n\n                        Console.WriteLine(\"Numero erroneo, pruebe otra vez\");\n                    }\n                    else\n                    {\n                        Console.WriteLine(\"Nombre no encontrado\");\n                    }\n                }\n                break;\n        }\n    }\n} while (!entrada.Equals(\"X\"));\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/c#/IvanCalero04.cs",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto\n *   en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n *   y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n *   y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no numéricos y con más\n *   de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.\n*/\n\nusing System;\nusing System.Dynamic;\nusing System.Timers;\n\n// Diferentes estructuras de datos en el Lenguaje de C#\n\n// Listas:\n\nList<string> usuarios = new();\n\nusuarios.Add(\"Iván\");\nusuarios.Add(\"Juan\");\nusuarios.Add(\"Natalia\");\nusuarios.Add(\"Pablo\");\nusuarios.Add(\"Alfonso\");\n\nforeach (var usuariosLista in usuarios)\n{\n    Console.WriteLine($\"Usuario: {usuariosLista}\");\n}\n\n// Diccionarios:\n\nDictionary<int, string> productos = new();\n\nproductos.Add(1, \"lapiz\");\nproductos.Add(2, \"goma\");\nproductos.Add(3, \"boli\");\n\nConsole.WriteLine(productos[2]);\n\n\n// Stacks:\n\nStack<string> sitiosWeb = new();\n\nsitiosWeb.Push(\"www.google.com\");\nsitiosWeb.Push(\"www.amazon.es\");\nsitiosWeb.Push(\"www.github.com\");\n\nstring ultima = sitiosWeb.Pop(); // Esto elimina el primer dato que introducimos anterior mente en el Stack en este caso -> www.google.com\n\n// Queue: \n\nQueue<string> filaImpresion = new();\n\nfilaImpresion.Enqueue(\"Documento_1.pdf\");\nfilaImpresion.Enqueue(\"Foto.jpg\");\n\n// Atendemos al primero que llegó\nstring procesando = filaImpresion.Dequeue();\nConsole.WriteLine($\"Imprimiendo: {procesando}\");\n\n\n// Tuplas: Son listas que no se pueden modificar\n\nvar tuplaInt = (1, 2, 3, 4, 5);\nConsole.WriteLine(tuplaInt);\n\n// Arrays:\nvar myArray = new string[] { \"Iván\", \"Calero Moreno\", \"Juan Carlos\" };\nConsole.WriteLine(myArray[1]);\nmyArray[1] = \"21\";\nConsole.WriteLine(myArray[1]);\n\n// Sets (Conjuntos)\nvar mySet = new HashSet<string> { \"Pepe\", \"Córdoba\", \"Sevilla\" };\nforeach (string elemento in mySet)\n{\n    Console.WriteLine(elemento);\n}\n\n\n\n// Agenda de contacto Ejercicio Extra.\n\n\nvar agendaContactos = new Dictionary<string, string>\n{\n    {\"Iván\", \"111222333\"},\n    {\"Pepe\", \"123456789\"},\n    {\"Alberto\", \"987654321\"},\n    {\"Miguel\", \"1234512345\"},\n};\n\nConsole.WriteLine(\"--------- Agenda de contactos -----------\");\n\nConsole.WriteLine(\"Selecciona una acción a realizar en tu Agenda de contactos: \");\nConsole.WriteLine(\"1. Buscar contacto\");\nConsole.WriteLine(\"2. Añadir contacto\");\nConsole.WriteLine(\"3. Actualizar contacto\");\nConsole.WriteLine(\"4. Eliminar contacto\");\nConsole.WriteLine(\"5. Salir\");\nConsole.Write(\"Elige una opción: \");\n\nstring entradaUsuario = Console.ReadLine() ?? \"\";\n\n//bool continuar = true;\n\n\n\nswitch (entradaUsuario)\n{\n    case \"1\":\n        Console.WriteLine(\"Introduce el nombre que quieras buscar en tu agenda.\");\n        string nombreBuscar = Console.ReadLine() ?? \"\";\n\n        if (agendaContactos.ContainsKey(nombreBuscar))\n        {\n                Console.WriteLine($\"El usuario {nombreBuscar} se encuentra en tu agenda de contactos.\");\n                Console.WriteLine($\"Su numero de telefono es: {agendaContactos[nombreBuscar]}\");\n        } \n        else\n        {\n            Console.WriteLine(\"El nombre que has introducido no se encuentra en tu lista de contactos.\");\n        }\n    break;\n\n    case \"2\":\n        Console.WriteLine(\"Introduce el nombre y del contacto que deseas añadir en tu agenda.\");\n        string nombreAñadir = Console.ReadLine() ?? \"\";\n        string telefonoAñadir = TelefonoValido();\n        if (agendaContactos.ContainsKey(nombreAñadir))\n        {\n            Console.WriteLine(\"Este contacto ya existe en tu agenda.\");\n        }\n        else\n        {\n            agendaContactos.Add(nombreAñadir, telefonoAñadir);\n            Console.WriteLine(\"Contacto guardado correctamente en tu agenda.\");\n        }\n    break;\n\n    case \"3\":\n        Console.WriteLine(\"Introduce el nombre del contacto que quieras editar: \");\n        string nombreEditar = Console.ReadLine() ?? \"\";\n\n        if (agendaContactos.ContainsKey(nombreEditar))\n        {   \n            Console.WriteLine($\"Ahora mismo se encuentra enditando {nombreEditar}.\");\n            Console.WriteLine(\"Selecciona el campo que quieres modificar al contacto.\");\n            Console.WriteLine(\"1.Nombre\");\n            Console.WriteLine(\"2.Telefono\");\n            string opcionEditar = Console.ReadLine() ?? \"\";\n            switch (opcionEditar)\n            {\n                case \"1\":\n                    Console.WriteLine(\"Introduce el nombre nuevo para este contacto: \");\n                    string nombreEditado = Console.ReadLine() ?? \"\";\n                    agendaContactos[nombreEditar] = nombreEditado;\n                    Console.WriteLine(\"Nombre del contacto editado correctamente.\");\n                break;\n                case \"2\":\n                    string telefonoEditar = TelefonoValido();\n                    agendaContactos[nombreEditar] = telefonoEditar;\n                    Console.WriteLine(\"Telefono del contacto actualizado correctamente.\");\n                break;\n            }\n        } \n        else\n        {\n            Console.WriteLine(\"No puedes editar un contacto que no existe.\");\n        }\n    break;\n\n    case \"4\":\n        Console.WriteLine(\"Introduce el nombre del contacto que quieres borrar: \");\n        string nombreBorrar = Console.ReadLine() ?? \"\";\n        if (agendaContactos.ContainsKey(nombreBorrar))\n        {\n            agendaContactos.Remove(nombreBorrar);\n            Console.Write($\"Eliminando {nombreBorrar}...\");\n            Console.Write($\"Contacto elimidado con exito.\");\n        }\n        else\n        {\n            Console.WriteLine(\"No puedes borrar un contacto que no existe.\");\n        }\n    break;\n    \n    case \"5\":\n        Console.WriteLine(\"Saliendo del programa....\");\n    break;\n\n    default:\n        Console.WriteLine(\"Opción no valida intentalo de nuevo.\");\n    break;\n}\n\n\nstring TelefonoValido()\n{\n    string telefonoContacto = \"\";\n    bool esValido = false;\n\n    while (!esValido)\n    {\n        Console.WriteLine(\"Introduce un número de telefono para añadirlo al contacto.\");\n        telefonoContacto = Console.ReadLine() ?? \"\";\n        \n        bool esNumerico = telefonoContacto.All(char.IsDigit);\n\n        if (!string.IsNullOrEmpty(telefonoContacto) && esNumerico && telefonoContacto.Length <= 11)\n        {\n            esValido = true;\n        }\n        else\n        {\n            Console.Write(\"Formato del número de telefono incorrecto. Intentalo de nuevo.\");\n        }\n    }\n    return telefonoContacto;\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/c#/JoseEsmil04.cs",
    "content": "\nclass Program\n{\n    static void Main()\n    {\n        // ARRAYS\n        int[] numbers = { 1, 2, 3, 4, 5, 6 }; // Insercion\n\n        numbers[0] = 7; // Actualizacion\n                        // Borrado no soportado por los Arrays.\n        Array.Sort(numbers); // Ordenacion\n\n        foreach (int number in numbers)\n        {\n            Console.WriteLine(number + \" \");\n        }\n\n        // LISTAS\n        List<string> countries = new();\n\n        countries.Add(\"Spain\"); // Insercion\n        countries.Add(\"Canada\");\n        countries.Add(\"Dominican Republic\");\n        countries.Remove(\"Canada\"); // Borrado\n        countries[0] = \"Italy\"; // Actualizacion\n        countries.Sort(); // Ordenacion\n\n        foreach (var country in countries)\n        {\n            Console.WriteLine(country + \" \");\n        }\n\n        // DICTIONARY\n        Dictionary<string, int> employees = new Dictionary<string, int>\n        {\n            { \"Esmil\", 4 },\n            { \"Ana\", 2 },\n            { \"Maria\", 5 }\n        };\n\n        employees.Add(\"Alex\", 11); // Insercion\n        employees.Remove(\"Esmil\"); // Borrado\n        employees[\"Ana\"] = 43; // Actualizacion\n                               // No hay Ordenacion directa, se debe hacer por clave o valor\n\n        foreach (var employee in employees)\n        {\n            Console.WriteLine(employee + \"\");\n        }\n\n        // HASHSET\n        HashSet<int> set = new HashSet<int> { 1, 2, 3 };\n\n        set.Add(5); // Insercion\n        set.Remove(1); // Borrado\n\n        set.Remove(2); // Actualizacion (Borrar y Agregar)\n        set.Add(4);\n\n        List<int> sortedSet = set.ToList();\n        sortedSet.Sort(); // Ordenacion (Hay que pasarlo a List)\n\n        foreach (var s in sortedSet)\n        {\n            Console.WriteLine(s + \"\");\n        }\n\n        // QUEUE\n        Queue<int> queue = new Queue<int>();\n\n        queue.Enqueue(5); // Insercion\n        queue.Enqueue(2);\n        queue.Enqueue(8);\n        queue.Enqueue(1);\n        queue.Enqueue(3);\n\n        queue.Dequeue(); // Borrado\n\n        // Actualizacion (no se puede directamente, se debe reconstruir la cola)\n        Queue<int> updatedQueue = new Queue<int>(queue.Select(x => x == 2 ? 4 : x));\n\n        List<int> sortedQueue = updatedQueue.ToList(); // Ordenacion (Hay que pasarlo a list)\n        sortedQueue.Sort();\n\n        foreach (var item in sortedQueue)\n        {\n            Console.Write(item + \" \");\n        }\n\n        // STACK\n        Stack<int> stack = new Stack<int>();\n\n        stack.Push(5); // Insercion\n        stack.Push(2);\n        stack.Push(8);\n        stack.Push(1);\n        stack.Push(3);\n\n        stack.Pop(); // Borrado\n\n        // Actualizacion (no se puede directamente, se debe reconstruir la Pila)\n        Stack<int> updatedStack = new Stack<int>(stack.Select(x => x == 8 ? 9 : x));\n\n        List<int> sortedStack = updatedStack.ToList();\n        sortedStack.Sort(); // Ordenacion (Hay que pasarlo a list)\n\n        foreach (var item in sortedStack)\n        {\n            Console.Write(item + \" \");\n        }\n\n        // LINKEDLIST\n        LinkedList<int> linkedList = new LinkedList<int>();\n\n        linkedList.AddLast(5); // Insercion\n        linkedList.AddLast(2);\n        linkedList.AddLast(8);\n        linkedList.AddLast(1);\n        linkedList.AddLast(3);\n        linkedList.AddLast(7);\n\n        linkedList.Remove(8); // Borrado\n\n        // Actualización (no es directa, se debe manejar con nodos)\n        LinkedListNode<int> node = linkedList.Find(2);\n        node.Value = 4;\n\n        List<int> sortedLinkedList = linkedList.ToList();\n        sortedLinkedList.Sort(); // Ordenacion (Hay que pasarlo a list)\n\n        foreach (var item in sortedLinkedList)\n        {\n            Console.Write(item + \" \");\n        }\n\n        // EJERCICIO EXTRA AGENDA\n        AgendaContactos.Iniciar();\n\n    }\n}\n\npublic class AgendaContactos\n{\n    static Dictionary<string, string> agenda = new Dictionary<string, string>();\n\n\n    public static void Iniciar()\n    {\n        while (true)\n        {\n            Console.WriteLine(\"------ Agenda ------\");\n            Console.WriteLine(\"\");\n            Console.WriteLine(\"Seleccione una operación:\");\n            Console.WriteLine(\"1. Insertar contacto\");\n            Console.WriteLine(\"2. Buscar contacto\");\n            Console.WriteLine(\"3. Actualizar contacto\");\n            Console.WriteLine(\"4. Eliminar contacto\");\n            Console.WriteLine(\"5. Finalizar programa\");\n\n            var option = Console.ReadLine();\n\n            switch (option)\n            {\n                case \"1\":\n                    InsertarContacto();\n                    break;\n                case \"2\":\n                    BuscarContacto();\n                    break;\n                case \"3\":\n                    ActualizarContacto();\n                    break;\n                case \"4\":\n                    EliminarContacto();\n                    break;\n                case \"5\":\n                    Console.WriteLine(\"Finalizando Programa...\");\n                    return;\n                default:\n                    Console.WriteLine(\"Opcion no valida, intente de nuevo por favor!\");\n                    break;\n            }\n\n\n        }\n    }\n\n    public static void InsertarContacto()\n    {\n        Console.WriteLine(\"Inserte el nombre del Contacto: \");\n        var nombre = Console.ReadLine();\n\n        Console.WriteLine(\"Inserte el numero del contacto: \");\n        var telefono = Console.ReadLine();\n\n        if (nombre == null)\n        {\n            Console.WriteLine(\"Nombre Invalido, Intente nuevamente\");\n            return;\n        }\n\n        if (telefono.Length > 11 || !long.TryParse(telefono, out _) || telefono == null)\n        {\n            Console.WriteLine(\"Telefono Invalido, intente nuevamente\");\n            return;\n        }\n\n        if (agenda.ContainsKey(nombre))\n        {\n            Console.WriteLine(\"EL nombre ya existe en la agenda!\");\n            return;\n        }\n\n        agenda[nombre] = telefono;\n    }\n\n    public static void BuscarContacto()\n    {\n        Console.Write(\"Ingrese el nombre del contacto:\");\n        var nombre = Console.ReadLine();\n\n        if (nombre == null)\n        {\n            Console.WriteLine(\"Nombre Invalido!\");\n            return;\n        }\n\n        if (agenda.ContainsKey(nombre))\n        {\n            Console.WriteLine($\"Nombre: {nombre}, Telefono: {agenda[nombre]}\");\n        }\n        else\n        {\n            Console.WriteLine(\"Contacto! no encontrado!\");\n        }\n    }\n\n    public static void ActualizarContacto()\n    {\n        Console.Write(\"Ingrese el nombre del contacto: \");\n        var nombre = Console.ReadLine();\n\n        if (nombre == null)\n        {\n            Console.WriteLine(\"Nombre Invalido!\");\n            return;\n        }\n\n        if (agenda.ContainsKey(nombre))\n        {\n            Console.Write(\"Ingrese el nuevo numero (max 11 dígitos): \");\n            string telefono = Console.ReadLine();\n\n            if (telefono.Length > 11 || !long.TryParse(telefono, out _) || telefono == null)\n            {\n                Console.WriteLine(\"Número de teléfono no válido.\");\n                return;\n            }\n\n            agenda[nombre] = telefono;\n            Console.WriteLine(\"Contacto actualizado correctamente.\");\n        }\n        else\n        {\n            Console.WriteLine(\"Contacto no encontrado.\");\n        }\n    }\n\n    public static void EliminarContacto()\n    {\n        Console.Write(\"Ingrese el nombre del contacto: \");\n        var nombre = Console.ReadLine();\n\n        if (nombre == null)\n        {\n            Console.WriteLine(\"Nombre Invalido!\");\n            return;\n        }\n\n        if (agenda.ContainsKey(nombre))\n        {\n            agenda.Remove(nombre);\n            Console.WriteLine(\"Contacto Eliminado correctamente.\");\n        }\n        else\n        {\n            Console.WriteLine(\"Contacto no encontrado.\");\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/c#/RXVLC.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\n\nnamespace R03___2024\n{\n    //Clase para dificultad adicional\n    public class Contacto\n    {\n        private string nombre;\n        private int numero;\n\n        public string Nombre { get { return this.nombre; } set { this.nombre = value; } }\n        public int Numero { get { return this.numero; } set { this.numero = value; } }\n    }\n\n    internal class Program\n    {\n        /*\n         * EJERCICIO:\n         * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n         * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n         *\n         * DIFICULTAD EXTRA (opcional):\n         * Crea una agenda de contactos por terminal.\n         * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n         * - Cada contacto debe tener un nombre y un número de teléfono.\n         * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n         *   los datos necesarios para llevarla a cabo.\n         * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n         *   (o el número de dígitos que quieras)\n         * - También se debe proponer una operación de finalización del programa.\n         */\n\n        static int MenuPrincipal()\n        {\n            int opcion;\n\n            do\n            {\n                Console.WriteLine(\"\\nBienvenido a tu agenda, escoge una opción:\");\n                Console.WriteLine(\"1 - Buscar contacto\");\n                Console.WriteLine(\"2 - Insertar contacto\");\n                Console.WriteLine(\"3 - Actualizar contacto\");\n                Console.WriteLine(\"4 - Eliminar contacto\");\n                Console.WriteLine(\"5 - Salir\");\n\n                if (!int.TryParse(Console.ReadLine(), out opcion))\n                {\n                    Console.WriteLine(\"Opción no válida. Por favor, ingrese un número entero.\");\n                }\n                else if (opcion < 1 || opcion > 5)\n                {\n                    Console.WriteLine(\"Opción fuera de rango. Por favor, elija una opción del 1 al 5.\");\n                }\n\n            } while (opcion < 1 || opcion > 5);\n\n            return opcion;\n        }\n\n        static void BuscarContacto(List<Contacto> contactos)\n        {\n            Console.Write(\"Ingrese el nombre del contacto que desea buscar: \");\n            string nombreBuscado = Console.ReadLine();\n\n            bool encontrado = false;\n\n            for (int i = 0; i < contactos.Count; i++)\n            {\n                if (contactos[i].Nombre.Equals(nombreBuscado, StringComparison.OrdinalIgnoreCase))\n                {\n                    Console.WriteLine(\"Contacto encontrado:\");\n                    Console.WriteLine($\"Nombre: {contactos[i].Nombre}\");\n                    Console.WriteLine($\"Número: {contactos[i].Numero}\");\n                    encontrado = true;\n                    break; // Si encontramos el contacto, salimos del bucle\n                }\n            }\n\n            if (!encontrado)\n            {\n                Console.WriteLine(\"Contacto no encontrado.\");\n            }\n        }\n\n        static Contacto AgregarContacto(List<Contacto> contactos)\n        {\n            Contacto contacto = new Contacto();\n            string nombre; string numero;\n            // Pedir y validar el nombre\n            do\n            {\n                Console.Write(\"Nombre del contacto: \");\n                nombre = Console.ReadLine();\n                if (string.IsNullOrWhiteSpace(nombre))\n                {\n                    Console.WriteLine(\"El nombre está vacío. Por favor, ingréselo nuevamente.\");\n                }\n            } while (string.IsNullOrWhiteSpace(nombre));\n\n            do\n            {\n                Console.Write(\"Número de teléfono (hasta 11 dígitos): \");\n                numero = Console.ReadLine();\n                if (string.IsNullOrWhiteSpace(numero) || !EsNumero(numero) || numero.Length > 11)\n                {\n                    Console.WriteLine(\"Número de teléfono inválido. Debe contener hasta 11 dígitos numéricos.\");\n                }\n            } while (string.IsNullOrWhiteSpace(numero) || !EsNumero(numero) || numero.Length > 11);\n\n            if (ExisteContacto(nombre, numero, contactos))\n            {\n                Console.WriteLine(\"El contacto ya existe en la agenda.\");\n            }\n            else\n            {\n                contacto.Nombre = nombre;\n                contacto.Numero = int.Parse(numero);\n                contactos.Add(contacto);\n                Console.WriteLine(\"Contacto agregado correctamente.\");\n            }\n\n            return contacto;\n        }\n\n        private static bool EsNumero(string str)\n        {\n            return int.TryParse(str, out _);\n        }\n\n        static bool ExisteContacto(string nombre, string numero, List<Contacto> contactos)\n        {\n            foreach (Contacto contacto in contactos)\n            {\n                if (contacto.Nombre == nombre || contacto.Numero == int.Parse(numero))\n                {\n                    return true;\n                }\n            }\n            return false;\n        }\n\n        static void MostrarContactos(List<Contacto> contactos)\n        {\n            Console.WriteLine(\"Lista de contactos:\");\n\n            if (contactos.Count == 0)\n            {\n                Console.WriteLine(\"No hay contactos en la lista.\");\n            }\n            else\n            {\n                foreach (var contacto in contactos)\n                {\n                    Console.WriteLine($\"Nombre: {contacto.Nombre}, Número: {contacto.Numero}\");\n                }\n            }\n        }\n\n        static void ActualizarContacto(List<Contacto> contactos)\n        {\n            Console.Write(\"Ingrese el nombre del contacto que desea actualizar: \");\n            string nombreBuscado = Console.ReadLine();\n\n            int indiceEncontrado = -1;\n\n            for (int i = 0; i < contactos.Count; i++)\n            {\n                if (contactos[i].Nombre.Equals(nombreBuscado, StringComparison.OrdinalIgnoreCase))\n                {\n                    indiceEncontrado = i;\n                    break;\n                }\n            }\n\n            if (indiceEncontrado != -1)\n            {\n                Console.WriteLine(\"Contacto encontrado. Proporcione la nueva información:\");\n\n                // Solicitar y actualizar el nombre\n                Console.Write(\"Nuevo nombre: \");\n                string nuevoNombre = Console.ReadLine();\n                contactos[indiceEncontrado].Nombre = string.IsNullOrWhiteSpace(nuevoNombre) ? contactos[indiceEncontrado].Nombre : nuevoNombre;\n\n                // Solicitar y actualizar el número de teléfono\n                Console.Write(\"Nuevo número de teléfono (hasta 11 dígitos): \");\n                string nuevoNumero = Console.ReadLine();\n                if (!string.IsNullOrWhiteSpace(nuevoNumero) && EsNumero(nuevoNumero) && nuevoNumero.Length <= 11)\n                {\n                    contactos[indiceEncontrado].Numero = int.Parse(nuevoNumero);\n                }\n                else\n                {\n                    Console.WriteLine(\"Número de teléfono inválido. No se actualizó el número.\");\n                }\n\n                Console.WriteLine(\"Contacto actualizado correctamente.\");\n            }\n            else\n            {\n                Console.WriteLine(\"Contacto no encontrado. No se puede actualizar.\");\n            }\n        }\n\n        static void EliminarContacto(List<Contacto> contactos)\n        {\n            Console.Write(\"Ingrese el nombre del contacto que desea eliminar: \");\n            string nombreBuscado = Console.ReadLine();\n\n            int indiceEncontrado = -1;\n\n            for (int i = 0; i < contactos.Count; i++)\n            {\n                if (contactos[i].Nombre.Equals(nombreBuscado, StringComparison.OrdinalIgnoreCase))\n                {\n                    indiceEncontrado = i;\n                    break;\n                }\n            }\n\n            if (indiceEncontrado != -1)\n            {\n                Console.WriteLine(\"Contacto encontrado. ¿Está seguro de que desea eliminarlo? (S/N)\");\n\n                if (Console.ReadKey().Key == ConsoleKey.S)\n                {\n                    contactos.RemoveAt(indiceEncontrado);\n                    Console.WriteLine(\"\\nContacto eliminado correctamente.\");\n                }\n                else\n                {\n                    Console.WriteLine(\"\\nContacto no eliminado.\");\n                }\n            }\n            else\n            {\n                Console.WriteLine(\"Contacto no encontrado. No se puede eliminar.\");\n            }\n        }\n\n        static void Main(string[] args)\n        {\n            //Ejemplo array 3 elementos:\n            int[] arrayInt = new int[3];\n\n            //Rellena elementos:\n            arrayInt[0] = 3; arrayInt[1] = 2; arrayInt[2] = 1;\n\n            //Ordena elementos, en este caso para los arrays en c# se puede hacer con el método sort, pero en muchos otros no hay métodos, os muestro como crear una función manual,\n            //se puede hacer de varias formas , en mi caso haré el algoritmo bubble (uno de los más fáciles).:\n            int aux = arrayInt[0];\n            for (int i = 0; i < arrayInt.Length; i++)\n            {\n                for (int j = i + 1; j < arrayInt.Length; j++)\n                {\n                    if (arrayInt[j] < arrayInt[i])\n                    {\n                        aux = arrayInt[i];\n                        arrayInt[i] = arrayInt[j];\n                        arrayInt[j] = aux;\n                    }\n                }\n            }\n            //Ordenacion con método:\n            Array.Sort(arrayInt);\n\n            //Actualización:\n            arrayInt[2] = 4;\n\n            // Borrado (desplazamiento hacia la izquierda):\n            int posicionABorrar = 3;\n            for (int i = posicionABorrar; i < arrayInt.Length - 1; i++)\n            {\n                arrayInt[i] = arrayInt[i + 1];\n            }\n            // Se establece el último elemento como 0 (o cualquier valor por defecto)\n            arrayInt[arrayInt.Length - 1] = 0;\n\n            //Muestra elementos por consola\n            foreach (int i in arrayInt)\n            {\n                Console.WriteLine(i);\n            }\n\n\n            //Ejemplo lista altamente tipada, a diferencia del array no tiene límite.\n            List<int> list = new List<int>();\n            //Rellena elementos:\n            list.Add(24); list.Add(25); list.Add(26);\n\n            //Ordenar lista:\n            list.Sort();\n\n            //Borrado, en este caso no es necesario borrar el último elemento.\n            list.RemoveAt(list.Count - 1);\n\n            //Mostrar elementos lista:\n            foreach (int i in list)\n            {\n                Console.WriteLine(i);\n            }\n\n            //Cola o queue:\n            Queue<string> cola = new Queue<string>();\n\n            //Rellenar elementos:\n            cola.Enqueue(\"Elemento1\");\n            cola.Enqueue(\"Elemento2\");\n            cola.Enqueue(\"Elemento3\");\n\n            //La cola no es la mejor estructura para actualizar debido a su falta de índice\n\n            //Borrado de elementos:\n            cola.Dequeue(); //Borra el primer elemento\n\n            //Mostrar elementos:\n            Console.WriteLine(\"\\nElementos de la cola:\");\n            foreach (string elemento in cola)\n            {\n                Console.WriteLine(elemento);\n            }\n            Console.WriteLine();\n\n            // Pila o stack:\n            Stack<string> pila = new Stack<string>();\n\n            // Rellenar elementos:\n            pila.Push(\"Elemento1\");\n            pila.Push(\"Elemento2\");\n            pila.Push(\"Elemento3\");\n\n            // Borrado de elementos (elimina el elemento en la cima de la pila):\n            pila.Pop();\n\n            // Mostrar elementos:\n            Console.WriteLine(\"Elementos de la pila:\");\n            foreach (string elemento in pila)\n            {\n                Console.WriteLine(elemento);\n            }\n            Console.WriteLine();\n            Console.WriteLine(\"Pulsa una tecla para ir a la dificultad extra:\");\n            Console.ReadKey();\n            Console.Clear();\n\n            //DIFICULTAD EXTRA:\n            int opcion;\n            List<Contacto> contactos = new List<Contacto>();\n            do\n            {\n                opcion = MenuPrincipal();\n                switch (opcion)\n                {\n                    case 1:\n                        BuscarContacto(contactos);\n                        break;\n                    case 2:\n                        AgregarContacto(contactos);\n                        break;\n                    case 3:\n                        ActualizarContacto(contactos);\n                        break;\n                    case 4:\n                        EliminarContacto(contactos);\n                        break;\n                    case 5: break;\n                }\n                Console.WriteLine(\"Pulsa una tecla para continuar\");\n                Console.ReadKey();\n                Console.Clear();\n            } while (opcion != 5);\n\n\n        }\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/c#/XPERIARGLUNA.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Runtime.CompilerServices;\n\nclass Program\n{\n    //Diccionario para la agenda\n    static Dictionary<string, string> agenda = new Dictionary<string, string>();\n    static void Main()\n    {\n\n        // ---Estructuras de datos---\n        Console.WriteLine(\"EJEMPLOS DE ESTRUCTURAS\");\n\n        //Arrays - Arreglos\n        string[] abc = new string[5] { \"a\", \"b\", \"c\", \"d\", \"e\" };  //Datos de tamaño fijo\n\n        //List - Listas \n        List<int> myList = new List<int> { 2, 4, 6, 8, };  //Datos dinámicos\n        myList.Add(3); // Inserción\n        myList.Remove(6); //Eliminar\n        myList[1] = 7;  //Actualizar\n        myList.Sort();  //Ordenación\n        Console.WriteLine(\"Lista \" + string.Join(\", \", myList));\n\n        //Tuplas\n        var usuario = (\"XPERIARGLUNA\", 19, \"C#\"); //Agrupa valores en una sola variable\n\n        Console.WriteLine($\"Nombre de usuario: {usuario.Item1}\");\n        Console.WriteLine($\"Edad del usuario: {usuario.Item2}\");\n        Console.WriteLine($\"Lenguaje del usuario: {usuario.Item3}\");\n\n        //HashSet - Conjuntos\n        HashSet<string> pokedex = new HashSet<string>(); //Evita datos duplicados, pero no se pueden ordenar\n        string[] pokemones = { \"Pikachu\", \"Charmander\", \"Bulbasur\", \"Pikachu\" };\n\n        foreach (string pokemon in pokemones)\n        {\n            if (pokedex.Add(pokemon)) //Intento de captura del pokemón\n                Console.WriteLine($\"¡Has capturado a {pokemon}!\");\n            else\n                Console.WriteLine($\"Ya tienes capturado a {pokemon}, sigue buscando... \");\n        }\n        Console.WriteLine(\"\\n Pokedex actual: \" + string.Join(\" , \", pokedex));\n\n        // Diccionario - Dictionary \n        Dictionary<int, string> menu = new Dictionary<int, string>()\n        {\n            { 1, \"Hamburguesa\" },\n            { 2, \"Papas Fritas\" },\n            { 3, \"Pizza\" },\n            { 4, \"Postre\" }\n        };\n\n        Console.WriteLine(\"\\n Menú original:\");\n        foreach (var item in menu)\n        {\n            Console.WriteLine($\"{item.Key}, {item.Value}\");\n        }\n\n        menu[4] = \"Alitas\";\n        menu.Remove(3);\n        menu[2] = \"Boneless\";\n        //No hay ordenación ya que se usan claves para búsqueda rápida \n\n        Console.WriteLine(\"\\n Menú actualizado:\");\n        foreach (var item in menu)\n        {\n            Console.WriteLine($\"{item.Key}, {item.Value}\");\n        }\n\n        // Pilas - Stack\n        Stack<int> pila = new Stack<int>();\n        pila.Push(9); //Inserción\n        pila.Push(18);\n        pila.Push(27);\n\n        Console.WriteLine(\"Sacando de la pila(Pop): \" + pila.Pop()); //Quita el último elemento añadido de la pila\n\n        Console.WriteLine(\"Cima de la pila (Peek): \" + pila.Peek()); //Ver que hay en la cima de la pila\n                                                                     //no se puede ordenar, sigue el principio LIFO\n\n        // Cola - Queue\n        Queue<int> cola = new Queue<int>();\n        cola.Enqueue(9);\n        cola.Enqueue(18); //Inserción\n        cola.Enqueue(27);\n        int primero = cola.Dequeue(); // Quita el primer elemento añadido de la cola\n                                      // No se puede ordenar, sigue el principio FIFO        \n        Console.WriteLine($\"Primer elemento: {primero}\");\n\n        foreach (var item in cola)\n        {\n            Console.WriteLine(item);\n        }\n\n        //LinkedList\n        LinkedList<int> myLinkedList = new LinkedList<int>(new int[] { 3, 1, 3, 1, 6, 9});\n        myLinkedList.AddLast(2); //Inserción al final\n        myLinkedList.AddFirst(4); //Inserción al inicio\n        myLinkedList.Remove(3); // Borrado \n\n        foreach (var item in myLinkedList)\n        {\n            Console.WriteLine(item);\n        }\n\n        //Agenda Interactiva\n        Console.WriteLine(\"\\n AGENDA DE CONTACTOS\");\n\n        while (true)\n        {\n            Console.WriteLine(\"\\nOpciones:\");\n            Console.WriteLine(\"1. Agregar contacto\");\n            Console.WriteLine(\"2. Buscar contacto\");\n            Console.WriteLine(\"3. Actualizar contacto\");\n            Console.WriteLine(\"4. Eliminar contacto\");\n            Console.WriteLine(\"5. Mostrar todos los contactos\");\n            Console.WriteLine(\"6. Salir\");\n            Console.Write(\"Elige una opción: \");\n            string opcion = Console.ReadLine();\n\n            switch (opcion)\n            {\n                case \"1\": AgregarContacto(); break;\n                case \"2\": BuscarContacto(); break;\n                case \"3\": ActualizarContacto(); break;\n                case \"4\": EliminarContacto(); break;\n                case \"5\": MostrarTodos(); break;\n                case \"6\": Console.WriteLine(\"¡Hasta la próxima!\"); return;\n                default: Console.WriteLine(\"❌ Opción inválida.\"); break;\n            }\n        }\n    }\n\n    // Funciones para la agenda\n    static void AgregarContacto()\n    {\n        Console.Write(\"Nombre: \");\n        string nombre = Console.ReadLine();\n\n        Console.Write(\"Teléfono (máx 11 dígitos): \");\n        string telefono = Console.ReadLine();\n\n        if (EsTelefonoValido(telefono))\n        {\n            agenda[nombre] = telefono;\n            Console.WriteLine(\"✅ Contacto agregado.\");\n        }\n        else\n        {\n            Console.WriteLine(\"❌ Teléfono no válido.\");\n        }\n    }\n\n    static void BuscarContacto()\n    {\n        Console.Write(\"Nombre a buscar: \");\n        string nombre = Console.ReadLine();\n\n        if (agenda.ContainsKey(nombre))\n            Console.WriteLine($\"➡️ {nombre}: {agenda[nombre]}\");\n        else\n            Console.WriteLine(\"❌ Contacto no encontrado.\");\n    }\n\n    static void ActualizarContacto()\n    {\n        Console.Write(\"Nombre del contacto: \");\n        string nombre = Console.ReadLine();\n\n        if (agenda.ContainsKey(nombre))\n        {\n            Console.Write(\"Nuevo teléfono: \");\n            string telefono = Console.ReadLine();\n            if (EsTelefonoValido(telefono))\n            {\n                agenda[nombre] = telefono;\n                Console.WriteLine(\"✅ Contacto actualizado.\");\n            }\n            else\n            {\n                Console.WriteLine(\"❌ Teléfono no válido.\");\n            }\n        }\n        else\n        {\n            Console.WriteLine(\"❌ Contacto no encontrado.\");\n        }\n    }\n\n    static void EliminarContacto()\n    {\n        Console.Write(\"Nombre a eliminar: \");\n        string nombre = Console.ReadLine();\n\n        if (agenda.Remove(nombre))\n            Console.WriteLine(\"🗑️ Contacto eliminado.\");\n        else\n            Console.WriteLine(\"❌ Contacto no encontrado.\");\n    }\n\n    static void MostrarTodos()\n    {\n        Console.WriteLine(\"\\n📒 Contactos guardados:\");\n        foreach (var contacto in agenda)\n            Console.WriteLine($\"- {contacto.Key}: {contacto.Value}\");\n    }\n\n    static bool EsTelefonoValido(string telefono)\n    {\n        return telefono.Length <= 11 && long.TryParse(telefono, out _);\n    }\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/c#/abrahamraies.cs",
    "content": "// Author: Abraham Raies https://github.com/abrahamraies\n\n/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\nusing System;\nusing System.Collections.Generic;\n\n class Program {\n    static void Main (string[] args){\n        #region Estructuras soportadas\n        Console.WriteLine(\"Estructuras soportadas: \");\n\n        #region Arrays\n\n        // Arreglos: Una colección de elementos del mismo tipo almacenados en una ubicación de memoria continua.\n        Console.WriteLine(\"Array: \");\n\n        int[] numbersInArray = new int[5];\n        string[] names = {\"Jorge\",\"Emilio\"};\n        int[] numbersInArray2 = new int[] {5,4,3,2,6,1};\n\n        // ADD: No es posible redimencionar un arreglo directamente, es necesario crear un nuevo arreglo.\n\n        // Delete: No es posible eliminar un elemento de un arreglo, es necesario crear un nuevo arreglo sin ese elemento.\n\n        // Update: \n        numbersInArray[0] = 2; // Modifica el primer elemento del arreglo.\n\n        // Order:\n        Array.Sort(numbersInArray2); // Ordena los elementos de menor a mayor\n        Console.WriteLine(\"Array \" + string.Join(\", \" , numbersInArray2));\n        #endregion\n\n        #region Lists\n        // Listas: Una colección genérica que puede crecer dinámicamente.\n        Console.WriteLine(\"Lists: \");\n\n        List<int> numberList = new List<int>();\n        List<int> numberList2 = new List<int> {2,3,4,7,1};\n\n        // ADD:\n        numberList.Add(3); // Inserta un elemento al final de la lista.\n        numberList.Insert(1,4); // Inserta el elemento de valor 4 en el indice 1.\n\n        // Delete:\n        numberList2.Remove(4); // Elimina la primera aparicion del elemento de valor 4.\n        numberList2.RemoveAt(2); // Elmina el elemento en el indice 2.\n\n        // Update: \n        numberList[0] = 2; // Modifica el primer elemento de la lista.\n\n        // Order:\n        numberList.Sort(); // Ordena los elementos de menor a mayor.\n        Console.WriteLine(\"List \" + string.Join(\", \" , numberList2));\n        #endregion\n\n        #region Dictionary\n        // Diccionarios: Una colección de pares clave-valor.\n        Console.WriteLine(\"Dictionary: \");\n\n        Dictionary<int,string> numberNames = new Dictionary<int, string>();\n\n        // ADD:\n        numberNames.Add(1,\"One\"); // Inserta un par.\n\n        // Delete:\n        numberNames.Remove(2); // Quita el par clave-valor con la clave 2.\n\n        // Update: \n        numberNames[0] = \"Uno\"; // Modifica el valor para el elemento 1.\n\n        // Order: No se pueden ordenar los elementos en un diccionario.\n        foreach (var kvp in numberNames)\n        {\n            Console.WriteLine(\"Diccionario: {0} = {1}\", kvp.Key, kvp.Value);\n        }\n        #endregion\n\n        #region HashSet\n        // HashSet: Una colección de elementos únicos.\n        Console.WriteLine(\"HashSet: \");\n\n        HashSet<int> uniqueNumbers = new HashSet<int>();\n\n        // ADD:\n        uniqueNumbers.Add(1); // Inserta un elemento.\n        uniqueNumbers.Add(2);\n        // Delete:\n        uniqueNumbers.Remove(2); // Quita un elemento.\n\n        // Update: No se puede modificar un elemento, pero si se puede eliminar y agregar uno.\n\n        // Order: No se pueden ordenar los elementos.\n        Console.WriteLine(\"HashSet \" + string.Join(\", \", uniqueNumbers));\n        #endregion\n\n        #region Queue\n        // Colas: Una colección FIFO (First-In-First-Out).\n        Console.WriteLine(\"Queue: \");\n\n        Queue<string> queue = new Queue<string>();\n\n        // ADD:\n        queue.Enqueue(\"first\"); // Agrega el elemento first a la cola.\n        queue.Enqueue(\"second\");\n        // Delete:\n        string first = queue.Dequeue(); // Quita y retorna el primer elemento.\n\n        // Update: No se pueden actualizar los elementos con un metodo propio. Para hacerlo es necesario realizar una busqueda del elemento, crear una queue temporal, sacar todos los elementos anteriores, remover el valor deseado y agregarlo con el nuevo valor.\n\n        // Order: No se pueden ordenar los elementos en una cola, el primero que entra es el primero que sale.\n        Console.WriteLine(\"Queue \" + string.Join(\", \", queue));\n        #endregion\n\n        #region Stack\n        // Pilas: Una colección LIFO (Last-In-First-Out).\n        Console.WriteLine(\"Stack: \");\n\n        Stack<string> stack = new Stack<string>();\n\n        // ADD:\n        stack.Push(\"First\"); // Agrega el elemento first a la pila.\n        stack.Push(\"Second\");\n        // Delete:\n        string firstElement = stack.Pop(); // Quita y retorna el primer elemento.\n\n        // Update: No se pueden actualizar los elementos con un metodo propio. Para hacerlo es necesario realizar una busqueda del elemento, crear una pila temporal, sacar todos los elementos anteriores, remover el valor deseado y agregarlo con el nuevo valor.\n\n        // Order: No se pueden ordenar los elementos en una pla, el ultimo que entra es el primero que sale.\n        Console.WriteLine(\"Stack \" + string.Join(\", \", stack));\n        #endregion\n\n        #region Matrix\n        // Matriz multidimensional: Array que tiene más de una dimensión, como una tabla de dos dimensiones (matriz) o más.\n        Console.WriteLine(\"Multidimensional matrix: \");\n\n        int[,] matrix = new int[3, 3];\n\n        // ADD: No se pueden redimensionar directamente. Debes crear una nueva matriz si necesitas una matriz de diferente tamaño.\n\n        // Delete: No se puede eliminar directamente elementos. Necesitas crear una nueva matriz y copiar los elementos deseados.\n\n        // Update:\n        matrix[0, 1] = 7; // Actualiza el valor en la posición [0, 1]\n\n        // Order: Para ordenarla es necesario convertirla a una lista, ordenarla y luego volver a convertirla a matriz.\n        for (int i = 0; i < matrix.GetLength(0); i++)\n        {\n            for (int j = 0; j < matrix.GetLength(1); j++)\n            {\n                Console.Write(matrix[i, j] + \" \");\n            }\n            Console.WriteLine();\n        }\n        #endregion\n\n        #region Jagged Matrix\n        // Matriz Jagged: Es un array de arrays. Cada \"fila\" puede tener una longitud diferente.\n        Console.WriteLine(\"Jagged Matrix: \");\n\n        int[][] jaggedArray = new int[3][];\n            jaggedArray[0] = new int[] { 1, 2 };\n            jaggedArray[1] = new int[] { 3, 4, 5 };\n            jaggedArray[2] = new int[] { 6, 7, 8, 9 };\n\n        // ADD: Es necesario re-ajustar el tamaño del array.\n        Array.Resize(ref jaggedArray[1], 4);\n        jaggedArray[1][3] = 10;\n\n        // Delete: Es necesario implementar LINQ\n\n        // Update:\n        jaggedArray[1][2] = 20; // Actualiza el tercer elemento de la segunda fila\n\n        // Order: \n        Array.Sort(jaggedArray[1]); //Ordena una fila especifica.\n        for (int i = 0; i < jaggedArray.Length; i++)\n        {\n            for (int j = 0; j < jaggedArray[i].Length; j++)\n            {\n                Console.Write(jaggedArray[i][j] + \" \");\n            }\n            Console.WriteLine();\n        }\n        #endregion\n\n        #region Enum\n        // Enum: Es un tipo de valor que define un conjunto de constantes con nombre.\n        Console.WriteLine(\"Enum: \");\n\n        // public enum DaysOfWeek\n        //{\n        //    Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday\n        //}\n\t\t\n\n        // ADD / Update / Delete: No se puede añadir, actualizar o eliminar valores en un enum después de su definición.\n\n        // Order: Los valores de un enum tienen un orden predefinido basado en su declaración.\n        #endregion\n\n        #region Tupla\n        // Tuple: Es una estructura de datos que puede contener un número fijo de elementos de tipos diferentes.\n        Console.WriteLine(\"Tuple: \");\n\n        var person = (Name: \"Alice\", Age: 30);\n\n        // ADD / Delete: No se pueden añadir ni eliminar elementos en una tupla. Se necesita crear una nueva tupla.\n\n        // Update: Es necesario crear una nueva tupla con los valores actualizados.\n        var updatedPerson = (Name: person.Name, Age: 31);\n\n        // Order: No es posible ordenar una tupla.\n        Console.WriteLine($\"Name: {person.Name}, Age: {person.Age}\");\n        #endregion\n\n        #region Record\n        // Record: Es un tipo de referencia que proporciona un mecanismo conciso para definir un tipo inmutable con igualdad de valores.\n        Console.WriteLine(\"Record: \");\n\n        //public record Person(string Name, int Age);\n\n        // ADD / Delete: No se pueden añadir ni eliminar propiedades en un record después de su definición.\n        //Person person = new Person(\"Sonia\", 30);\n        // Update: Usar la sintaxis with para crear una nueva instancia con valores actualizados.\n        var olderPerson = person with { Age = 31 };\n\n        // Order: Hay que crear una lista, y utilizar LINQ para ordenarla.\n        Console.WriteLine($\"Name: {person.Name}, Age: {person.Age}\");\n        #endregion\n\n        #region LinkedList\n        // LinkedList: Es una colección de nodos que permite una inserción y eliminación eficientes.\n        Console.WriteLine(\"LinkedList: \");\n\n        LinkedList<int> linkedList = new LinkedList<int>();\n\n        // ADD: Existen distintos metodos para agregar un elemento a una lista linkeada:\n        linkedList.AddLast(1); // Agregar el valor 1 al ultimo nodo\n        linkedList.AddFirst(0); //Agrega el valor 0 al primer nodo.\n        linkedList.AddAfter(linkedList.First, 2); //Luego del primer nodo agrega el elemento 2.\n        linkedList.AddLast(3);\n        linkedList.AddLast(4);\n\n        // Delete:\n        linkedList.Remove(2); // Elimina el primer nodo que contiene el valor 2\n        linkedList.RemoveFirst(); // Elimina el primer nodo\n        linkedList.RemoveLast(); // Elimina el último nodo\n\n        // Update: Linq para buscarlo y luego se puede modificar el valor con la propiedad value.\n        var node = linkedList.Find(1);\n        node.Value = 10;\n\n        // Order: Hay que crear una lista, utilizar LINQ para ordenarla y luego volver a convertirla a una linkedList.\n        \n        #endregion\n        \n        #endregion\n        \n        #region Ejercicio Extra:\n\n        ContactList agenda = new ContactList();\n\n\t\twhile(true)\n        {\n            ShowMenu();\n            Console.Write(\"Selecciona una opción: \");\n            string opcion = Console.ReadLine();\n            switch (int.Parse(opcion))\n            {\n                case 1:\n                    Console.WriteLine(\"Ingresar el nombre del contacto a buscar\");\n                    string nameToSearch = Console.ReadLine();\n\t\t\t\t\tagenda.SearchContact(nameToSearch);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 2:\n\t\t\t\t\tConsole.WriteLine(\"Ingresar el nombre del contacto a agregar\");\n                    string nameToAdd = Console.ReadLine();\n                    Console.WriteLine(\"Ingresar el numero del contacto a agregar\");\n                    string numberToAdd = Console.ReadLine();\n                    agenda.AddContact(nameToAdd,numberToAdd);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 3:\n                    Console.WriteLine(\"Ingresar el nombre del contacto a actualizar\");\n                    string nameToUpdate = Console.ReadLine();\n                    Console.WriteLine(\"Ingresar el nuevo numero del contacto a actualizar\");\n                    string numberToUpdate = Console.ReadLine();\n                    agenda.UpdateContact(nameToUpdate,numberToUpdate);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 4:\n\t\t\t\t\tConsole.WriteLine(\"Ingresar el nombre del contacto a eliminar\");\n                    string nameToDelete = Console.ReadLine();\n                    agenda.DeleteContact(nameToDelete);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 5:\n\t\t\t\t\tConsole.WriteLine(\"\\n Adios\");\n\t\t\t\t\treturn;\n                default:\n\t\t\t\t\tConsole.WriteLine(\"Opcion no valida\");\n\t\t\t\t\tbreak;\n            }\n        }\n        #endregion\n\t}\n\n\tstatic void ShowMenu(){\n\t\tConsole.WriteLine(\"\\n--- Agenda de Contactos ---\");\n        Console.WriteLine(\"1# Buscar contacto\");\n        Console.WriteLine(\"2# Crear contacto\");\n        Console.WriteLine(\"3# Actualizar contacto\");\n        Console.WriteLine(\"4# Eliminar contacto\");\n        Console.WriteLine(\"5# Salir\");\n\t}\n\n    \n}\n\npublic class ContactList{\n\tprivate Dictionary<string,string> contacts;\n\n    public ContactList(){\n        contacts = new Dictionary<string, string>();\n    }\n\n    public void AddContact(string name, string number){\n        if(contacts.ContainsValue(number)){\n            Console.WriteLine(\"El contacto ya existe.\");\n        }else{\n            contacts.Add(name,number);\n            Console.WriteLine(\"Usuario agregado correctamente.\");\n        }\n    }\n\n    public void SearchContact(string name){\n        if(contacts.TryGetValue(name, out string number)){\n            Console.WriteLine($\"Nombre: {name}, Número: {number}\");\n        }\n        else\n        {\n            Console.WriteLine(\"Contacto no encontrado.\");\n        }\n    }\n\n    public void UpdateContact(string name, string newNumber){\n        if(contacts.ContainsKey(name)){\n            contacts[name] = newNumber;\n            Console.WriteLine(\"Contacto actualizado exitosamente.\");\n        }\n        else\n        {\n            Console.WriteLine(\"Contacto no encontrado.\");\n        }\n    }\n\n    public void DeleteContact(string name){\n        if(contacts.Remove(name)){\n            Console.WriteLine(\"Contacto eliminado exitosamente.\");\n        }\n        else\n        {\n            Console.WriteLine(\"Contacto no encontrado.\");\n        }\n    }\n\n    public void AllContacts(){\n        Console.WriteLine(\"Lista de contactos:\");\n        foreach (var contact in contacts)\n        {\n            Console.WriteLine($\"Nombre: {contact.Key}, Número: {contact.Value}\");\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/c#/charlerodriguez3.cs",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto\n *   en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n */\n\n\n// List\nConsole.WriteLine(\"Lista:\");\nList<int> lista = new List<int>();\nlista.Add(3); // Inserción\nlista.Add(1);\nlista.Add(2);\nlista.Insert(1, 4); // Inserción en índice específico\nlista.RemoveAt(2); // Borrado por índice\nlista[0] = 5; // Actualización por índice\nlista.Sort(); // Ordenación\nforeach (var item in lista)\n{\n    Console.Write(item + \" \");\n}\nConsole.WriteLine();\n\n// Dictionary\nConsole.WriteLine(\"\\nDiccionario:\");\nDictionary<string, int> diccionario = new Dictionary<string, int>();\ndiccionario.Add(\"uno\", 1); // Inserción\ndiccionario.Add(\"dos\", 2);\ndiccionario[\"tres\"] = 3; // Actualización\ndiccionario.Remove(\"dos\"); // Borrado por clave\nforeach (var kvp in diccionario)\n{\n    Console.WriteLine($\"{kvp.Key}: {kvp.Value}\");\n}\n\n// Queue\nConsole.WriteLine(\"\\nCola:\");\nQueue<int> cola = new Queue<int>();\ncola.Enqueue(1); // Inserción\ncola.Enqueue(2);\ncola.Enqueue(3);\nint primerElemento = cola.Dequeue(); // Borrado (toma y elimina el primer elemento)\nConsole.WriteLine($\"Primer elemento: {primerElemento}\");\nforeach (var item in cola)\n{\n    Console.Write(item + \" \");\n}\nConsole.WriteLine();\n\n// Stack\nConsole.WriteLine(\"\\nPila:\");\nStack<int> pila = new Stack<int>();\npila.Push(1); // Inserción\npila.Push(2);\npila.Push(3);\nint ultimoElemento = pila.Pop(); // Borrado (toma y elimina el último elemento)\nConsole.WriteLine($\"Último elemento: {ultimoElemento}\");\nforeach (var item in pila)\n{\n    Console.Write(item + \" \");\n}\nConsole.WriteLine();\n\n// HashSet\nConsole.WriteLine(\"\\nConjunto:\");\nHashSet<int> conjunto = new HashSet<int>();\nconjunto.Add(1); // Inserción\nconjunto.Add(2);\nconjunto.Add(3);\nconjunto.Remove(2); // Borrado\nconjunto.Add(3); // No permite duplicados, entonces no se añadirá nuevamente\nforeach (var item in conjunto.OrderBy(x => x))\n{\n    Console.Write(item + \" \");\n}\nConsole.WriteLine();\n\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n *   y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n *   y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más\n *   de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.\n */\n\n class Contacto\n{\n    public string Nombre { get; set; }\n    public string Telefono { get; set; }\n}\n\nclass Program\n{\n    static List<Contacto> agenda = new List<Contacto>();\n\n    static void Main()\n    {\n        bool salir = false;\n\n        while (!salir)\n        {\n            Console.WriteLine(\"\\nSeleccione una operación:\");\n            Console.WriteLine(\"1. Mostrar todos los contactos\");\n            Console.WriteLine(\"2. Buscar contacto\");\n            Console.WriteLine(\"3. Añadir contacto\");\n            Console.WriteLine(\"4. Actualizar contacto\");\n            Console.WriteLine(\"5. Eliminar contacto\");\n            Console.WriteLine(\"6. Salir\");\n\n            Console.Write(\"\\nOpción: \");\n            string opcion = Console.ReadLine();\n\n            switch (opcion)\n            {\n                case \"1\":\n                    MostrarContactos();\n                    break;\n                case \"2\":\n                    BuscarContacto();\n                    break;\n                case \"3\":\n                    AgregarContacto();\n                    break;\n                case \"4\":\n                    ActualizarContacto();\n                    break;\n                case \"5\":\n                    EliminarContacto();\n                    break;\n                case \"6\":\n                    salir = true;\n                    Console.WriteLine(\"¡Hasta luego!\");\n                    break;\n                default:\n                    Console.WriteLine(\"Opción no válida. Por favor, elija una opción válida.\");\n                    break;\n            }\n        }\n    }\n\n    static void MostrarContactos()\n    {\n        Console.WriteLine(\"\\nLista de contactos:\");\n        foreach (var contacto in agenda)\n        {\n            Console.WriteLine($\"Nombre: {contacto.Nombre}, Teléfono: {contacto.Telefono}\");\n        }\n    }\n\n    static void BuscarContacto()\n    {\n        Console.Write(\"Introduce el nombre del contacto a buscar: \");\n        string nombre = Console.ReadLine();\n        Contacto contactoEncontrado = agenda.Find(c => c.Nombre.Equals(nombre, StringComparison.OrdinalIgnoreCase));\n        if (contactoEncontrado != null)\n        {\n            Console.WriteLine($\"Nombre: {contactoEncontrado.Nombre}, Teléfono: {contactoEncontrado.Telefono}\");\n        }\n        else\n        {\n            Console.WriteLine(\"Contacto no encontrado.\");\n        }\n    }\n\n    static void AgregarContacto()\n    {\n        Console.Write(\"Nombre del contacto: \");\n        string nombre = Console.ReadLine();\n        Console.Write(\"Teléfono del contacto: \");\n        string telefono = Console.ReadLine();\n\n        if (!EsNumeroTelefonoValido(telefono))\n        {\n            Console.WriteLine(\"Número de teléfono no válido.\");\n            return;\n        }\n\n        agenda.Add(new Contacto { Nombre = nombre, Telefono = telefono });\n        Console.WriteLine(\"Contacto añadido correctamente.\");\n    }\n\n    static void ActualizarContacto()\n    {\n        Console.Write(\"Introduce el nombre del contacto a actualizar: \");\n        string nombre = Console.ReadLine();\n        Contacto contacto = agenda.Find(c => c.Nombre.Equals(nombre, StringComparison.OrdinalIgnoreCase));\n        if (contacto != null)\n        {\n            Console.Write(\"Nuevo nombre del contacto: \");\n            string nuevoNombre = Console.ReadLine();\n            Console.Write(\"Nuevo teléfono del contacto: \");\n            string nuevoTelefono = Console.ReadLine();\n\n            if (!EsNumeroTelefonoValido(nuevoTelefono))\n            {\n                Console.WriteLine(\"Número de teléfono no válido.\");\n                return;\n            }\n\n            contacto.Nombre = nuevoNombre;\n            contacto.Telefono = nuevoTelefono;\n            Console.WriteLine(\"Contacto actualizado correctamente.\");\n        }\n        else\n        {\n            Console.WriteLine(\"Contacto no encontrado.\");\n        }\n    }\n\n    static void EliminarContacto()\n    {\n        Console.Write(\"Introduce el nombre del contacto a eliminar: \");\n        string nombre = Console.ReadLine();\n        Contacto contacto = agenda.Find(c => c.Nombre.Equals(nombre, StringComparison.OrdinalIgnoreCase));\n        if (contacto != null)\n        {\n            agenda.Remove(contacto);\n            Console.WriteLine(\"Contacto eliminado correctamente.\");\n        }\n        else\n        {\n            Console.WriteLine(\"Contacto no encontrado.\");\n        }\n    }\n\n    static bool EsNumeroTelefonoValido(string telefono)\n    {\n        long numero;\n        return long.TryParse(telefono, out numero) && telefono.Length <= 11; // Validar que el teléfono sea numérico y tenga hasta 11 dígitos\n    }\n\n "
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/c#/devcherry1.cs",
    "content": "/*    #03 ESTRUCTURAS DE DATOS\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto\n *   en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n */\n\nusing System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Text.RegularExpressions;\n\nclass Program\n{\n    static void Main()\n    {\n        //***  Arrays  ***\n        //son colecciones de elementos del mismo tipo con un tamaño fijo.\n        int[] numeros = new int[5] { 1, 2, 3, 4, 5 };\n\n        //*** Listas ***\n        //son colecciones dinámicas que pueden crecer o reducirse según sea necesario.\n        List<string> nombres = new List<string>() { \"Ana\", \"Carlos\", \"Elena\" };\n        nombres.Add(\"David\");\n        nombres.Remove(\"Ana\"); //se puede por valor \"Ana\"\n                               //nombres.RemoveAt(0) o por indice \"0\", tambien por condiciones\n                               //numeros.RemoveAll(n => n % 2 == 0); Elimina todos los números pares\n        nombres[1] = \"JP\"; //actualiza el indice 1\n        nombres.Sort(); // Ordena alfabeticamente\n        List<int> azar = new List<int>() { 5, 1, 4, 2, 3 };\n        azar.Sort(); // Ordena de menor a mayor\n\n\n        //*** Dictionary<TKey, TValue> ***\n        //almacenan pares clave-valor para un acceso rápido a los datos.\n\n        Dictionary<string, int> edades = new Dictionary<string, int>()\n        {\n            {\"Chata\", 30},\n            {\"JP\", 31}\n        };\n\n        //agregar una entrada\n        edades[\"Elena\"] = 22;\n\n        //*** Queue ***\n        //Las colas siguen el principio FIFO(First In, First Out).\n\n        Queue<string> cola = new Queue<string>();\n        cola.Enqueue(\"Primero\");\n        cola.Enqueue(\"Segundo\");\n\n        //*** Stack  ***\n        //Las pilas siguen el principio LIFO(Last In, First Out).\n\n        Stack<int> pila = new Stack<int>();\n        pila.Push(1);\n        pila.Push(2);\n\n        /* DIFICULTAD EXTRA (opcional):\n        * Crea una agenda de contactos por terminal.\n        * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n        *   y eliminación de contactos.\n        * - Cada contacto debe tener un nombre y un número de teléfono.\n        * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n        *   y a continuación los datos necesarios para llevarla a cabo.\n        * - El programa no puede dejar introducir números de teléfono no númericos y con más\n        *   de 11 dígitos (o el número de dígitos que quieras).\n        * - También se debe proponer una operación de finalización del programa.\n        */\n\n        Dictionary<string, string> telefonos = new Dictionary<string, string>() { };\n        string opciones = $\"\\nIndique la operacion a realizar digitando el numero de entre estas opciones:\" +\n                          $\"\\n1.Crear contacto\" +\n                          $\"\\n2.Buscar contacto\" +\n                          $\"\\n3.Actualizar contacto\" +\n                          $\"\\n4.Eliminar contacto\" +\n                          $\"\\n5.Mostrar directorio completo\" +\n                          $\"\\n6.Salir de la aplication.\";\n        int opcion;\n\n        Console.WriteLine(\"*** Bienvenido al directorio ***\" + opciones);\n\n        do\n        {\n            opcion = validarOpcion();\n            switch (opcion)\n            {\n                case 1:\n                    Console.WriteLine(\"Por favor, ingresa el nombre: \");\n                    string nombre = validarNombre();\n                    Console.WriteLine(\"Por favor, ingresa el telefono: \");\n                    string telefono = validarTelefono();\n                    telefonos[nombre] = telefono;\n                    break;\n\n                case 2:\n                    Console.WriteLine(\"Por favor ingrese el nombre a buscar: \");\n                    string buscarNombre = validarNombre();\n\n                    if (telefonos.ContainsKey(buscarNombre))\n                    {\n                        Console.WriteLine($\"El telefono de {buscarNombre} existe y es {telefonos[buscarNombre]}\");\n                    }\n                    else\n                    {\n                        Console.WriteLine($\"{buscarNombre} no se encuentra en el directorio.\");\n                    }\n                    break;\n\n                case 3:\n                    Console.WriteLine(\"Por favor ingrese el nombre de quien desea actualizar el telefono: \");\n                    string actualizarNombre = validarNombre();\n\n                    if (telefonos.ContainsKey(actualizarNombre))\n                    {\n                        Console.WriteLine($\"Ingrese el nuevo telefono de {actualizarNombre}:\");\n                        telefonos[actualizarNombre] = validarTelefono();\n                    }\n                    else\n                    {\n                        Console.WriteLine($\"{actualizarNombre} no se encuentra en el directorio.\");\n                    }\n                    break;\n\n                case 4:\n                    Console.WriteLine(\"Por favor ingrese el nombre de quien desea remover del directorio: \");\n                    string borrarNombre = validarNombre();\n\n                    if (telefonos.ContainsKey(borrarNombre))\n                    {\n                        telefonos.Remove(borrarNombre);\n                        Console.WriteLine($\"{borrarNombre} ha sido removido del directorio.\");\n                    }\n                    else\n                    {\n                        Console.WriteLine($\"{borrarNombre} no se encuentra en el directorio.\");\n                    }\n                    break;\n\n                case 5:\n                    Console.WriteLine(\"\\nDirectorio completo:\");\n                    foreach (var i in telefonos)\n                    {\n                        Console.WriteLine($\"\\nNombre: { i.Key} - Teléfono: { i.Value} \");\n                    }\n                    break;\n\n                case 6:\n                    break;\n \n            }\n            if (opcion != 6) // Mostrar las opciones solo si no se ha salido\n            {\n                Console.WriteLine(opciones);\n            }\n        } while (opcion != 6);\n    }\n    static int validarOpcion()\n    {\n        int cantidad;\n\n        while (!int.TryParse(Console.ReadLine(), out cantidad) || cantidad <= 0 || cantidad >= 7)\n        {\n            Console.Write(\"Por favor, ingresa un número entre 1 y 6: \");\n        }\n        return cantidad;\n    }\n    static string validarNombre()\n    {\n        string input = Console.ReadLine();\n        while (string.IsNullOrEmpty(input))\n        {\n            Console.WriteLine(\"El nombre no puede estar vacío. Ingresa nuevamente el nombre:\");\n            input = Console.ReadLine();\n        }\n        return input;\n    }\n    static string validarTelefono()\n    {\n        string telefono;\n        while (true)\n        {\n            telefono = Console.ReadLine(); // Primero leemos el teléfono\n\n            // Validamos si el teléfono tiene exactamente 10 dígitos y solo números\n            if (Regex.IsMatch(telefono, @\"^\\d{10}$\"))\n            {\n                break; // Si es válido, salimos del ciclo\n            }\n            else\n            {\n                Console.Write(\"Por favor, ingresa un telefono valido de 10 digitos: \");\n            }\n        }\n        return telefono;\n    }\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/c#/elmarqueli.cs",
    "content": "using System.Collections.Immutable;\n\nnamespace elmarqueli\n{\n    /*\n     * EJERCICIO:\n     * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n     * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n     *\n     * DIFICULTAD EXTRA (opcional):\n     * Crea una agenda de contactos por terminal.\n     * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n     * - Cada contacto debe tener un nombre y un número de teléfono.\n     * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n     *   los datos necesarios para llevarla a cabo.\n     * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n     *   (o el número de dígitos que quieras)\n     * - También se debe proponer una operación de finalización del programa.\n     */\n    public class EjercicioArray\n    {\n        static int[] m_array = Array.Empty<int>();\n\n        public EjercicioArray(int[] nums)\n        {\n            m_array = nums;\n        }\n        /// <summary>\n        /// Imprime los elementos del array.\n        /// </summary>\n        public void Print(string Prompt)\n        {\n            Console.Write(Prompt);\n            foreach (int elemento in m_array)\n            {\n                Console.Write($\" {elemento}\");\n            }\n            Console.WriteLine(\"\\n\");\n        }\n\n        /// <summary>\n        /// Inserta 2 numeros mas al array\n        /// </summary>\n        public void Insert(int Value)\n        {\n            Array.Resize(ref m_array, m_array.Length + 1);\n            m_array[m_array.Length - 1] = Value;\n        }\n\n        /// <summary>\n        /// Ordena el array.\n        /// </summary>\n        public void Sort()\n        {\n            Array.Sort(m_array);\n        }\n\n        /// <summary>\n        /// Eliminacion de un elemento en el array\n        /// </summary>\n        /// <param name=\"Value\"></param>\n        public void Delete(int Value)\n        {\n            // Creamos una nueva lista excluyendo al elemento a eliminar.\n            var new_array = m_array.Where(x => x != Value).ToArray();\n\n            // Redimiencionamos el array con una posision menos.\n            Array.Resize(ref m_array, m_array.Length - 1);\n\n            // Finalmente asignamos el valor del array nuevo al redimensionado.\n            m_array = new_array;\n        }\n\n        /// <summary>\n        /// Actualiza el array modificando la posision 5 y 6\n        /// </summary>\n        public void UpDate(int Index, int Value)\n        {\n            m_array[Index] = Value;\n        }\n\n        /// <summary>\n        /// Permite la modificacion de un elemento en la coleccion.\n        /// Utilice la funcion predicate para buscar el elemento a modificar\n        /// </summary>\n        /// <param name=\"Element\">Elemento en la coleccion</param>\n        /// <param name=\"Value\">Valor para la actualizacion</param>\n        /// <returns>Verdadero si la actualizacion fue correcta</returns>\n        public bool UpDate(Predicate<int> Element, int Value)\n        {\n            Sort();\n            var index = -1;\n\n            for (int i = 0; i < m_array.Length; i++)\n            {\n                if (Element.Invoke(m_array[i]))\n                {\n                    index = i; break;\n                };\n            }\n\n            if (index == -1)\n                return false;\n\n            m_array[index] = Value;\n            this.Sort();\n\n            return true;\n        }\n    }\n\n    public class EjercicioList\n    {\n        private List<int> m_Ints;\n        public EjercicioList(List<int> Ints)\n        {\n            m_Ints = Ints;\n        }\n        public void Print(string Prompt)\n        {\n            Console.Write(Prompt);\n            m_Ints.ToList().ForEach((x) => {\n                Console.Write($\" {x}\");\n            });\n            Console.WriteLine(\"\\n\");\n        }\n\n        public void Insert(int Value)\n        {\n            m_Ints.Add(Value);\n        }\n\n        public void Sort()\n        {\n            m_Ints.Sort();\n        }\n\n        public void Delete(int Value)\n        {\n            m_Ints.Remove(Value);\n        }\n\n        /// <summary>\n        /// Permite modificar un elemento de la coleccion\n        /// </summary>\n        public void UpDate(int Index, int Value)\n        {\n            m_Ints[Index] = Value;\n        }\n\n        /// <summary>\n        /// Permite modificar un elemento de la coleccion\n        /// Utilice la funcion predicate para buscar el elemento a modificar.\n        /// </summary>\n        /// <param name=\"Match\">Elemento en la coleccion</param>\n        /// <param name=\"Value\">Valor para la actualizacion</param>\n        /// <returns>Verdadero si la actualizacion fue correcta</returns>\n        public bool UpDate(Predicate<int> Match, int Value)\n        {\n            Sort();\n            var index = -1;\n\n            index = m_Ints.FindIndex((x) => Match.Invoke(x));\n\n            if (index == -1) return false;\n\n            m_Ints[index] = Value;\n\n            this.Sort();\n\n            return true;\n        }\n    }\n\n    public class EjercicioStack\n    {\n        // último en entrar, primero en salir\n        private Stack<int> m_Ints;\n        public EjercicioStack(Stack<int> ints)\n        {\n            m_Ints = ints;\n        }\n\n        public void Print(string Prompt)\n        {\n            Console.Write(Prompt);\n            m_Ints.ToList().ForEach((x) => {\n                Console.Write($\" {x}\");\n            });\n            Console.WriteLine(\"\\n\");\n        }\n\n        public void Insert(int Value)\n        {\n            m_Ints.Push(Value);\n        }\n\n        /// <summary>\n        /// Elimina el ultimo en entrar.\n        /// </summary>\n        /// <returns>Número eliminado</returns>\n        public int Delete()\n        {\n            return m_Ints.Pop();\n        }\n    }\n\n    public class EjercicioQueue\n    {\n        // Primero en entrar, primero en salir\n        private Queue<int> m_Queue;\n        public EjercicioQueue(Queue<int> ints)\n        {\n            m_Queue = ints;\n        }\n        /// <summary>\n        /// Imprime el contenido de la colección\n        /// </summary>\n        /// <param name=\"Prompt\"></param>\n        public void Print(string Prompt)\n        {\n            Console.Write(Prompt);\n            m_Queue.ToList().ForEach((x) => {\n                Console.Write($\" {x}\");\n            });\n            Console.WriteLine(\"\\n\");\n        }\n\n        /// <summary>\n        /// Agrega un número a la colección\n        /// </summary>\n        /// <param name=\"Value\"></param>\n        public void Insert(int Value)\n        {\n            m_Queue.Enqueue(Value);\n        }\n\n        /// <summary>\n        /// Quita el primer número agregado recientemente.\n        /// </summary>\n        public int Delete()\n        {\n            return m_Queue.Dequeue();\n        }\n    }\n\n    public class EjercicioHashSet\n    {\n        // Establecemos la variable para la colección\n        private HashSet<int> m_Set;\n        public EjercicioHashSet(HashSet<int> ints)\n        {\n            // Inicializamos la colección\n            m_Set = ints;\n        }\n\n        public void Print(string Prompt)\n        {\n            Console.Write(Prompt);\n            m_Set.ToList().ForEach((x) => {\n                Console.Write($\" {x}\");\n            });\n            Console.WriteLine(\"\\n\");\n        }\n\n        /// <summary>\n        /// Agrega un nuevo número.\n        /// </summary>\n        /// <param name=\"Value\"></param>\n        public void Insert(int Value)\n        {\n            m_Set.Add(Value);\n        }\n\n        /// <summary>\n        /// Quita el número indicado.\n        /// </summary>\n        /// <param name=\"Value\"></param>\n        public void Delete(int Value)\n        {\n            m_Set.Remove(Value);\n        }\n\n        /// <summary>\n        /// Ordena la colección\n        /// </summary>\n        public void Sort()\n        {\n            var newHashSet = new HashSet<int>();\n            m_Set.ToImmutableSortedSet().ToList().ForEach(x =>\n            {\n                newHashSet.Add(x);\n            });\n\n            m_Set = newHashSet;\n        }\n    }\n\n    public class EjercicioDictionary\n    {\n        private Dictionary<int, string> m_Dictionary;\n        public EjercicioDictionary(Dictionary<int, string> dictionary)\n        {\n            m_Dictionary = dictionary;\n        }\n\n        /// <summary>\n        /// Imprime la coleccion.\n        /// </summary>\n        /// <param name=\"Prompt\"></param>\n        public void Print(string Prompt)\n        {\n            Console.Write(Prompt);\n            m_Dictionary.ToList().ForEach((x) => {\n                Console.Write($\" {x}\");\n            });\n            Console.WriteLine(\"\\n\");\n        }\n\n        /// <summary>\n        /// Inserta un nuevo registro.\n        /// </summary>\n        /// <param name=\"Id\"></param>\n        /// <param name=\"Nombre\"></param>\n        /// <returns></returns>\n        public bool Insert(int Id, string Nombre)\n        {\n            if (!m_Dictionary.ContainsKey(Id))\n            {\n                m_Dictionary.Add(Id, Nombre);\n                return true;\n            }\n            else\n                return false;\n        }\n\n        /// <summary>\n        /// Elimina un registro excistente.\n        /// </summary>\n        /// <param name=\"Id\"></param>\n        public void Delete(int Id)\n        {\n            m_Dictionary.Remove(Id);\n        }\n\n        /// <summary>\n        /// Actualiza un registro.\n        /// </summary>\n        /// <param name=\"id\"></param>\n        /// <param name=\"Nombre\"></param>\n        public void UpDate(int id, string Nombre)\n        {\n            m_Dictionary[id] = Nombre;\n        }\n\n        /// <summary>\n        /// Ordena la coleccion.\n        /// </summary>\n        public void Sort()\n        {\n            var ff = new Dictionary<int, string>();\n            var sorted = new SortedDictionary<int, string>(m_Dictionary);\n            sorted.ToList().ForEach(x => ff.Add(x.Key, x.Value));\n            m_Dictionary = ff;\n        }\n    }\n\n    // ***** Extra: Programa, Agenda de Contactos (AddressBook)\n    public static class AddressBook\n    {\n        private static string m_Nombre = string.Empty;\n        private static int m_TelefonNumber;\n        private static Dictionary<int, Action>? m_ActionMenu;\n        private static Dictionary<string, int>? m_Agenda;\n        static AddressBook()\n        {\n            m_Agenda = new Dictionary<string, int>();\n\n            // Podemos crear un diccionario con el numero de la opcion, y la funcion correspondiente,\n            // de esta manera en el futuro podremos extender la funsionalidad de la agenda agegando funciones\n            // y agregando estas al diccionario => m_ActionMenu\n            m_ActionMenu = new Dictionary<int, Action>();\n            m_ActionMenu.Add(1, MenuFind);\n            m_ActionMenu.Add(2, MenuInsert);\n            m_ActionMenu.Add(3, MenuUpDate);\n            m_ActionMenu.Add(4, MenuDelete);\n            m_ActionMenu.Add(5, MenuExit);\n        }\n\n        static public void InitProgram() => MainMenu();\n\n        static Action PrintOptions = () =>\n        {\n            Console.Clear();\n            Console.WriteLine(\"*** Menú Principal Agenda ***\\n\");\n\n            Console.WriteLine(\"---- Seleccione una de las siguientes opciones:\\n\");\n\n            Console.WriteLine(\"1 - Buscar contacto...\\n\");\n            Console.WriteLine(\"2 - Agregar contacto...\\n\");\n            Console.WriteLine(\"3 - Modificar contacto...\\n\");\n            Console.WriteLine(\"4 - Eliminar contacto...\\n\");\n            Console.WriteLine(\"5 - Exit\\n\");\n\n            Console.Write(\"Seleccione una opcion: \");\n            var option = Console.ReadLine();\n\n            // Verificamos que sea de tipo número.\n            if (int.TryParse(option, out int op))\n            {\n                var actionMenu = m_ActionMenu[op];\n                actionMenu.Invoke();\n            }\n            else\n            {\n                Console.WriteLine(\"La opcion ingresada debe ser un número entero, intente nuevamente.\\nPresione Enter para continuar....\");\n                Console.ReadLine();\n                PrintOptions();\n            }\n        };\n\n        static void MainMenu()\n        {\n            PrintOptions();\n        }\n\n        static void MenuInsert()\n        {\n            Console.Clear();\n            Console.WriteLine(\"*** Menú Agregar Contacto ***\\n\");\n\n            Console.Write(\"Escriba el Nombre: \");\n            var name = Console.ReadLine();\n            Console.Write(\"Escriba un numero de telefono de asta 11 digitos: \");\n            var telefon = Console.ReadLine();\n\n            if (int.TryParse(telefon, out int op) && telefon.Count() <= 11)\n            {\n                if (!m_Agenda.ContainsKey(name))\n                {\n                    m_Agenda.Add(name, op);\n                    Console.WriteLine(\"\\nContacto ingresado con exito!!.\\nEnter para Menu Principal.\");\n                    Console.ReadLine();\n                    MainMenu();\n                }\n                else\n                {\n                    Console.WriteLine(\"El contacto ya existe!!.\\nPresione Enter para continuar....\");\n                    Console.ReadLine();\n                    MenuInsert();\n                }\n            }\n            else\n            {\n                Console.WriteLine(\"Error!!, número telefonico no valido!.\\nPresione Enter para continuar....\");\n                Console.ReadLine();\n                MenuInsert();\n            }\n        }\n\n        static void MenuDelete()\n        {\n            Console.Clear();\n            Console.WriteLine(\"*** Menú Eliminar Contacto ***\\n\");\n\n            Console.Write(\"Escriba Nombre del contacto: \");\n            var name = Console.ReadLine();\n\n            if (!m_Agenda.ContainsKey(name))\n            {\n                m_Agenda.Remove(name);\n                Console.WriteLine(\"\\nContacto eliminado con exito!!.\\nEnter para Menu Principal.\");\n                Console.ReadLine();\n                MainMenu();\n            }\n            else\n            {\n                Console.WriteLine(\"El contacto no existe!!.\\nPresione Enter para continuar....\");\n                Console.ReadLine();\n                MenuInsert();\n            }\n        }\n\n        static void MenuUpDate()\n        {\n            Console.Clear();\n            Console.WriteLine(\"*** Menú Modificar Contacto ***\\n\");\n\n            Console.WriteLine(\"1 - Modificar el nombre\");\n\n            Console.WriteLine(\"2 - Modificar el Telefono\");\n\n            Console.WriteLine(\"3 - Menu Principal\");\n\n            var opt = Console.ReadLine();\n\n            if (int.TryParse(opt, out int op))\n            {\n                Console.Write(\"Nombre del contacto a modificar: \");\n                var name = Console.ReadLine();\n\n                if (m_Agenda.ContainsKey(name))\n                {\n                    var reName = \"\";\n                    switch (op)\n                    {\n                        case 1:\n                            Console.Write(\"Nuevo nombre: \");\n                            reName = Console.ReadLine();\n\n                            var newValues = new KeyValuePair<string, int>(reName, m_Agenda[name]);\n\n                            m_Agenda.Remove(name);\n                            m_Agenda.Append(newValues);\n\n                            Console.WriteLine(\"\\nContacto Modificado con exito!!.\\nEnter para continuar.\");\n                            Console.ReadLine();\n                            MenuUpDate();\n                            break;\n                        case 2:\n                            bool exit = false;\n                            while (!exit)\n                            {\n                                Console.Write(\"Número de telefono nuevo, no mas de 11 digitos: \");\n                                reName = Console.ReadLine();\n                                if (int.TryParse(reName, out int o) && reName.Count() <= 11)\n                                {\n                                    m_Agenda[name] = (o);\n                                    Console.WriteLine(\"\\nContacto Modificado con exito!!.\\nEnter para continuar.\");\n                                    Console.ReadLine();\n                                    MenuUpDate();\n                                    exit = true;\n                                }\n                            }\n                            break;\n                        case 3:\n                            MainMenu();\n                            break;\n                    }\n                }\n                else\n                {\n                    Console.WriteLine(\"El contacto no existe!!.\\nPresione Enter para continuar....\");\n                    Console.ReadLine();\n                    MenuUpDate();\n                }\n            }\n            else\n            {\n                Console.WriteLine(\"Error!!, opcion no valida!.\\nPresione Enter para continuar....\");\n                Console.ReadLine();\n                MenuUpDate();\n            }\n        }\n\n        static void MenuFind()\n        {\n            Console.Clear();\n            Console.WriteLine(\"*** Menú Buscar Contacto ***\\n\");\n\n            Console.Write(\"Escriba el Nombre ó exit para Menu principal: \");\n            var name = Console.ReadLine();\n\n            if (m_Agenda.ContainsKey(name))\n            {\n                m_Agenda.ToList().ForEach(x =>\n                {\n                    Console.WriteLine($\"\\n Nombre: {x.Key} - Telefono {x.Value}\");\n                });\n                Console.ReadLine();\n                MainMenu();\n            }\n            else if (name.ToLower() == \"exit\")\n                MainMenu();\n            else\n            {\n                Console.WriteLine(\"El contacto no existe!!.\\nPresione Enter para continuar....\");\n                Console.ReadLine();\n                MenuFind();\n            }\n        }\n\n        static void MenuExit()\n        {\n            Console.Clear();\n            Console.WriteLine(\"Gracias por usar AddressBook, Saliendo de la aplicacion....\");\n            Console.ReadLine();\n            Environment.Exit(0);\n        }\n    }\n\n\n  class Program\n\t{\n\t\tstatic void Main(string[] args)\n\t\t{\n            var numRetire = 0;\n\n            Console.WriteLine(\"***** Array ******\\n\");\n\n            var EjrArray = new EjercicioArray(new int[] { 1, 2, 5, 7, 3, 4 ,11});\n\n            EjrArray.Print(\"Array actual:\");\n\n            EjrArray.Delete(4);\n\n            EjrArray.Print(\"Eliminando el número { 4 }:\");\n\n            EjrArray.Insert(4);\n\n            EjrArray.Print(\"Insertando el núemro { 4 }:\");\n\n            EjrArray.Sort();\n\n            EjrArray.Print(\"Array ordenado:\");\n\n            if (EjrArray.UpDate((x) => x == 11, 6))\n                EjrArray.Print(\"Actualización correcta!!! se cambio el { 11 } por el { 6 }:\");\n            else\n                Console.WriteLine(\"El elemento a modificar no se encuentra!!!\");\n\n\n            // **************************************************************\n\n            Console.WriteLine(\"***** List ******\\n\");\n\n            var EjrList = new EjercicioList(new List<int> { 1, 3, 2, 5, 4, 11, 12 });\n\n            EjrList.Print(\"Lista actual:\");\n\n            EjrList.Sort();\n\n            EjrList.Print(\"Lista ordenada:\");\n\n            EjrList.Insert(6);\n\n            EjrList.Print(\"Elemento { 6 } insertado:\");\n\n            EjrList.Delete(12);\n\n            EjrList.Print(\"Elemento { 12 } eliminado crrectamente:\");\n\n            if (EjrList.UpDate((x) => x == 11, 7))\n                EjrList.Print(\"Actualizacion Correcta!! se cambio el { 11 } por el { 7 }:\");\n            else\n                Console.WriteLine(\"Actualizacion Incirrecta, no existe el elemento a acutalizar!!\");\n\n            // **************************************************************\n\n            Console.WriteLine(\"***** Stack ******\\n\");\n\n            var EjrStack = new EjercicioStack(new Stack<int>(new int[] { 1, 2, 3, 5 }));\n\n            EjrStack.Print(\"Pila actual:\");\n\n            EjrStack.Insert(6);\n\n            EjrStack.Print(\"Número { 6 } agregado a la pila:\");\n\n            numRetire = EjrStack.Delete();\n\n            EjrStack.Print($\"Quitando de la pila el ultimo número agregado: [{numRetire}] ->\");\n\n            // **************************************************************\n\n            Console.WriteLine(\"***** Queue ******\\n\");\n\n            var EjrQueue = new EjercicioQueue(new Queue<int>(new int[] {2, 1, 4, 8, 6}));\n\n            EjrQueue.Insert(3);\n\n            EjrQueue.Print(\"Agregando a la cola el numero { 3 }:\");\n\n            numRetire =  EjrQueue.Delete();\n\n            EjrQueue.Print($\"Quitando de la cola el primer número agregado:[{numRetire}] ->\");\n\n            // **************************************************************\n\n            Console.WriteLine(\"***** HashSet ******\\n\");\n\n            var EjrHashSet = new EjercicioHashSet(new HashSet<int>() { 1,2,3,4,6,5});\n\n            EjrHashSet.Print(\"Lista HashSet acutal:\");\n\n            EjrHashSet.Insert(7);\n\n            EjrHashSet.Print(\"Agregando el número { 7 }:\");\n\n            // Como el número 7 ya esta agergado anteriormente este no se agregara otra ves\n            EjrHashSet.Insert(7);\n\n            EjrHashSet.Print(\"Queriendo Agregando el número { 7 } nuevamente:\");\n\n            EjrHashSet.Sort();\n            \n            EjrHashSet.Print(\"Ordenando el HashSet:\");\n\n            EjrHashSet.Delete(7);\n\n            EjrHashSet.Print(\"Quitando el número { 7 }:\");\n\n            // **************************************************************\n\n            Console.WriteLine(\"***** Dictionary ******\\n\");\n\n            var EjrDictionary = new EjercicioDictionary(new Dictionary<int, string>() { { 0, \"Pablo\" },{3,\"Carol\"}, { 1, \"Roberto\" }, { 2,\"Romina\"} });\n\n            EjrDictionary.Print(\"Diccionario actual:\");\n\n            // No se insertara ya que el id 3 ya exciste.\n            if(!EjrDictionary.Insert(3, \"Guillermo\"))\n                Console.WriteLine(\"Se quiere agregar a Guillermo con el { id 3 } pero este id ya existe!!\\n\");\n            else\n                EjrDictionary.Print(\"El registro { 3, Guillermo } a sido ingresado con exito!!:\");\n\n            if (!EjrDictionary.Insert(4, \"Romina Piriz\"))\n                Console.WriteLine(\"Se quiere agregar a Romina con el { id 4 } pero este ya existe!!\\n\");\n            else\n                EjrDictionary.Print(\"El registro { 4, Romina Piriz } a sido ingresado con exito!!:\");\n\n            EjrDictionary.Sort();\n            EjrDictionary.Print(\"Diccionario ordenado:\");\n\n            EjrDictionary.Delete(0);\n            EjrDictionary.Print(\"Se a eliminado el registro { 0 }:\");\n\n            EjrDictionary.UpDate(3, \"Carol Sofia\");\n            EjrDictionary.Print(\"Se a actualizado el registro { 3 }:\");\n\n\n            // **************************************************************\n\n            Console.WriteLine(\"\\n\\n========== Extra: Programa Agenda ==========\\n\");\n\n            AddressBook.InitProgram();\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/c#/estuardodev.cs",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\nusing System.Collections;\nusing static System.Runtime.InteropServices.JavaScript.JSType;\n\nclass Program\n{\n\n    private class Artista\n    {\n        public int ArtistId { get; set; }\n        public string Name { get; set; }\n    }\n\n    private class Contacto\n    {\n        public string Name { get; set; }\n        public string Number_Phone { get; set; }\n    }\n\n    public static void Main(string[] args)\n    {\n        _Queue();\n        _Array();\n        _List();\n        _Dictionary();\n        _Stack();\n        Agenda();\n    }\n\n    private static void _Queue()\n    {\n        /*\n         La estrucutra de datos de Queue sigue la regla de First In First Out (Primero en entrar, primero en salir)\n         A esta estructura de datos podemos designarle un tamaño al momento de crea una nueva instancia, o también\n         podemos indicarle que tipo de dato se le estará asignando.\n         */\n        Console.WriteLine(\"------------- Queue ----------------\");\n\n        // Formas en la cual podemos utilizarlo\n        Queue queue = new Queue();\n        Queue queue2 = new Queue(5);\n        Queue<Artista> queue3 = new Queue<Artista>();\n\n        // Para agregar un nuevo elemento a la lista podemos utilizar el metodo Enqueue y como argumento el dato\n        queue3.Enqueue(new Artista\n        {\n            ArtistId = 1,\n            Name = \"Estuardo\"\n        });\n\n        queue3.Enqueue(new Artista\n        {\n            ArtistId = 2,\n            Name = \"Lilian\"\n        });\n\n        queue3.Enqueue(new Artista\n        {\n            ArtistId = 3,\n            Name = \"Bob Esponja\"\n        });\n\n        // Al momento de iterar sobre la estructura, este nos devolvera el orden en el cual se fueron agregando a la estructura\n        foreach(var item in queue3)\n        {\n            Console.WriteLine($\"Hola soy el artista {item.ArtistId}, me llamo {item.Name}.\");\n        }\n\n        // Para eliminar elementos de esta estructura tenemos dos funciones\n        /*\n         * Dequeue(), Este elimina el primer elemento pero lo devuelve\n         */\n        var eliminadoDequeue = queue3.Dequeue();\n        Console.WriteLine(\"Elimnado:\" + eliminadoDequeue.Name);\n\n        foreach (var item in queue3)\n        {\n            Console.WriteLine($\"Hola soy el artista {item.ArtistId}, me llamo {item.Name}.\");\n        }\n\n        // Para acceder elementos de esta estructura tenemos dos funciones\n        /*\n         * Peek(), Accede al primer elemento pero no lo elimina\n         * FirstOrDefault(lamda)\n         */\n        var accederPeek = queue3.Peek();\n        Console.WriteLine($\"Accedido a {accederPeek.Name}\");\n\n        var accederId = queue3.FirstOrDefault(x => x.ArtistId == 3);\n\n        // Para actualizar datos de algún elemento en esta estructura hacemos lo siguiente:\n        var actualizarQueue3 = queue3.FirstOrDefault(x => x.ArtistId == 2);\n        actualizarQueue3.Name = \"Adalberta\";\n        Console.WriteLine(actualizarQueue3.Name);\n    }\n\n    private static void _Array()\n    {\n        /*\n         * Los Array son una colección ordenada de elementos los cuales tienen un índice identificador.\n         * Muchas de las estructuras de datos que utilizamos son en realidad Arrays con funcionalidades añadidas.\n         * En C# al utilizar Arrays debemos especificar el tamaño al momento de crear la instancia y tambien el tipo.\n         * Además los arrays como la mayoria de estructuras de datos empiezan con el índice 0\n         */\n        Console.WriteLine(\"------------- Array ----------------\");\n\n        string[] array = new string[10];\n\n        // Para agregar un nuevo elemento debemos seguir lo siguiente\n        // nombre[indice_ordenado] = valor;\n        array[0] = \"Lilian\";\n        array[1] = \"Estuardo\";\n        Console.WriteLine(array[0], array[1]);\n\n        // Para acceder a un índice en específico deberás de hacer lo siguiente:\n        // nombre[indice_a_acceder]\n        Console.WriteLine(array[1]);\n\n        // Para actualizar un array deberás de seguir lo siguiente:\n        // nombre[indice_a_actualizar] = nuevo_valor;\n        array[0] = \"Lili\";\n        Console.WriteLine(array[0]);\n\n        // Para \"eliminar\" elementos de los arrays se puede lograr de la siguiente manera\n        array[1] = null;\n        Console.WriteLine(array[1]);        \n    }\n\n    private static void _List() \n    {\n        /*\n         * Las listas en C# utilizan Arrays \"under the hood (Bajo el capó)\" pero fueron optimizadas para el uso en caso de\n         * que no se sepa el tamaño de la lista.\n         */\n        Console.WriteLine(\"------------- List ----------------\");\n\n        // Inicializar una lista\n        List<string> list = new List<string>();\n\n        // Agregar elementos a la lista\n        list.Add(\"Lilian\");\n        list.Add(\"Estuardo\");\n        list.Add(\"Pentium\");\n\n        // Ver la cantidad de elementos que tiene nuestra lista\n        Console.WriteLine(list.Count);\n\n        // Podemos ver si existe algún valor en específico\n        Console.WriteLine(list.Contains(\"Carro\"));\n\n        // Obtener objetos específicos\n        Console.WriteLine(list.Find(x => x == \"Estuardo\"));\n\n        // Actualizar un valor específico\n        list[1] = \"ESTUARDO\";\n        Console.WriteLine(list[1]);\n\n        // Eliminar elementos\n        list.Remove(\"Pentium\");\n\n        // Recorrer la lista\n        list.ForEach(x => Console.WriteLine(x));\n    }\n\n    private static void _Dictionary() {\n        /*\n         * Para crear un diccionario en C# únicamente debemos intanciarlo, los diccionarios es una colección para almacenar datos de forma \"clave-valor\"\n         * los cuales pueden ser de diferente tipos de datos.\n         */\n        Console.WriteLine(\"------------- Dictionary ----------------\");\n\n        // Instanciar un diccionario\n        Dictionary<string, string> dict = new Dictionary<string, string>();\n\n        // Agregar elementos\n        dict.Add(\"Mujer\", \"Lilian\");\n        dict.Add(\"Hombre\", \"Estuardo\");\n\n        // Acceder a un elemento, para ello debemos usar su clave\n        Console.WriteLine(dict[\"Mujer\"]);\n        Console.WriteLine(dict[\"Hombre\"]);\n\n        // Paraa ctualizar un elemento lo hacemos por medio de su clave\n        dict[\"Hombre\"] = \"ESTUARDO\";\n        Console.WriteLine(dict[\"Hombre\"]);\n\n        // Para eliminar tenemos dos opciones\n        // Remove: Elininaras por medio de su clave\n        // Clear: Limpia todo el diccionario\n        dict.Remove(\"Mujer\");\n        Console.WriteLine(dict);\n    }\n\n    private static void _Stack() {\n        /*\n         *  Esta estrucutra de datos sigue el consejo de pila \"Último en entrar, primero en salir\"\n         *  Al igual que las demás estructuras de datos debemos inicializarla\n         */\n        Console.WriteLine(\"------------- Stack ----------------\");\n\n        // Inicializar Stack o crear el objeto Stack\n        Stack<string> stack = new Stack<string>();\n\n        // Agregar valores a la estructura\n        stack.Push(\"C#\");\n        stack.Push(\"Python\");\n        stack.Push(\"Java\");\n\n        // Para ver el último elemento que añadimos\n        Console.WriteLine(stack.Peek());\n\n        // Para remover el último elemento que fue añadido\n        stack.Pop();\n        Console.WriteLine(stack.Peek());\n\n        // Buscar un valor específico\n        Console.WriteLine(stack.FirstOrDefault(x => x.Equals(\"C#\")));\n    }\n\n    private static void Agenda()\n    {\n        Console.WriteLine();\n        Console.WriteLine();\n        List<Contacto> contactos = new List<Contacto>();\n        int opcion = -1;\n\n        Console.WriteLine(\"---- Bienvenido a tu agenda de contactos ----\");\n\n        while (opcion != 0)\n        {\n            Console.WriteLine();\n            Console.WriteLine();\n            Console.WriteLine();\n            Console.WriteLine(\"¿Qué deseas hacer?\");\n            Console.WriteLine(\"[1] - Buscar contacto\");\n            Console.WriteLine(\"[2] - Agregar contacto\");\n            Console.WriteLine(\"[3] - Actualizar contacto\");\n            Console.WriteLine(\"[4] - Eliminar Contacto\");\n            Console.WriteLine(\"[0] - Salir \");\n\n            Console.Write(\"Escoje una opción: \");\n            try { \n                opcion = Convert.ToInt32(Console.ReadLine());\n\n                switch (opcion){\n                    case 0:\n                        Console.WriteLine(\"Adios\");\n                        break;\n                    case 1:\n                        Search();\n                        break;\n                    case 2:\n                        Create();\n                        break;\n                    case 3:\n                        Update();\n                        break;\n                    case 4:\n                        Delete();\n                        break;\n                }\n            }catch(Exception)\n            {\n                Console.WriteLine(\"Por favor escoge una opción correcta\");\n            }\n        }\n\n        void Search()\n        {\n            string dato;\n            Console.WriteLine(\"Escribe el número de teléfono o nombre del contacto: \");\n            dato = Console.ReadLine();\n\n            var busqueda = contactos.FirstOrDefault(x => x.Name == dato || x.Number_Phone == dato);\n            if (busqueda != null)\n            {\n                Console.WriteLine(\"Tu contacto: \");\n                Console.WriteLine($\"Nombre: {busqueda.Name}\");\n                Console.WriteLine($\"Número: {busqueda.Number_Phone}\");\n                Thread.Sleep(1000);\n                Console.WriteLine(\"Regresando...\");\n                Thread.Sleep(1000);\n            }\n            \n        }\n\n        void Create()\n        {\n            string dato1;\n            Int64 dato2;\n            string dato3;\n\n            Console.WriteLine(\"-- Creando Nuevo Contacto --\");\n            Console.WriteLine(\"Nombre de tu contacto:\");\n            dato1 = Console.ReadLine();\n            Console.WriteLine(\"Número de telefono de tu contacto:\");\n            try\n            {\n                dato2 = Convert.ToInt64(Console.ReadLine());\n                if (dato2 < 0 || dato2 > 99999999999)\n                {\n                    Console.WriteLine(\"Error, no se permite esa longitud del número\");\n                }\n\n                dato3 = Convert.ToString(dato2);\n                contactos.Add(new Contacto\n                {\n                    Name = dato1,\n                    Number_Phone = dato3,\n                });\n\n                Console.WriteLine(\"Contacto Guardado.\");\n                Thread.Sleep(1000);\n                Console.WriteLine(\"Regresando...\");\n                Thread.Sleep(1000);\n            }\n            catch\n            {\n                Console.WriteLine(\"Error, solo se permiten números\");\n            }\n\n        }\n\n        void Update()\n        {\n            int option;\n\n            Console.WriteLine(\"¿Qué deseas editar?\");\n            Console.WriteLine(\"[1] - Editar Nombre\");\n            Console.WriteLine(\"[2] - Editar número\");\n\n            try\n            {\n\n                option = Convert.ToInt32(Console.ReadLine());\n                switch (option)\n                {\n                    case 1:\n                        string dato;\n                        Console.WriteLine(\"Escribe el número de teléfono o nombre del contacto: \");\n                        dato = Console.ReadLine();\n\n                        var busqueda = contactos.FirstOrDefault(x => x.Name == dato || x.Number_Phone == dato);\n                        if (busqueda != null)\n                        {\n                            string nuevo;\n                            Console.WriteLine(\"Escribe el nuevo nombre: \");\n                            nuevo = Console.ReadLine();\n                            busqueda.Name = nuevo;\n                        }\n                        else\n                        {\n                            Console.WriteLine(\"Contacto no encontrado.\");\n                        }\n                        break;\n                    case 2:\n                        string dato2;\n                        Int64 dato3;\n\n                        Console.WriteLine(\"Escribe el número de teléfono o nombre del contacto: \");\n                        dato = Console.ReadLine();\n\n                        var busqueda2 = contactos.FirstOrDefault(x => x.Name == dato || x.Number_Phone == dato);\n                        if (busqueda2 != null)\n                        {\n                            string nuevo;\n                            Console.WriteLine(\"Escribe el nuevo número: \");\n                            nuevo = Console.ReadLine();\n\n                            dato3 = Convert.ToInt64(nuevo);\n                            if (dato3 < 0 || dato3 > 99999999999)\n                            {\n                                Console.WriteLine(\"Error, no se permite esa longitud del número\");\n                            }\n                            else\n                            {\n                                busqueda2.Number_Phone = nuevo;\n                                Console.WriteLine(\"Contacto Guardado.\");\n                                Thread.Sleep(1000);\n                                Console.WriteLine(\"Regresando...\");\n                                Thread.Sleep(1000);\n                            }\n                        }\n                        else\n                        {\n                            Console.WriteLine(\"Contacto no encontrado.\");\n                        }\n\n\n                        break;\n                    default:\n                        Console.WriteLine(\"No existe esa opcion\");\n                        break;\n                }\n            }\n            catch\n            {\n                Console.WriteLine(\"Error\");\n            }\n        }\n\n        void Delete()\n        {\n            string datos;\n\n            Console.WriteLine(\"Escribe el número de teléfono o nombre del contacto: \");\n            datos = Console.ReadLine();\n            var contact = contactos.FirstOrDefault(x => x.Name == datos || x.Number_Phone == datos);\n            contactos.RemoveAll(x => x.Name == datos || x.Number_Phone == datos);\n\n            if (contact != null)\n            {\n                Console.WriteLine(\"Eliminando\");\n                Thread.Sleep(1000);\n                Console.WriteLine(\"Saliendo...\");\n                Thread.Sleep(1000);\n            }\n            else\n            {\n                Console.WriteLine(\"Contacto no encontrado.\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/c#/hequebo.cs",
    "content": "class Program\n{\n    static List<Contacto> agenda = new List<Contacto>\n    {\n        new Contacto(1, \"Emilio\", \"612123456\"),\n        new Contacto(2, \"Samantha\", \"62134567\"),\n        new Contacto(3, \"Aldo\", \"6124573154\")\n    };\n    static int id = 4;\n    static void Main(string[] args)\n    {\n        // Estructuras de Datos\n\n        #region Arrays\n        // Arreglos o Arrays\n        /* \n            -Almacenan elementos del mismo tipo.\n            -Su tamaño es definido al momento de\n            su creación.\n            -Pueden tener multiples dimensiones\n        */\n        string[] personas = { \"Hugo\", \"Paco\", \"Luis\" }; // Se puede inicializar definiendo los elementos que lo conforman \n        int[] edades = new int[5]; // Tambien se puede indicar el tamaño al inicializarlo para su llenado posterior\n        for (int i = 1; i < 5; i++) // => {1, 2, 3, 4, 5}\n            edades[i] = i;\n\n        string[,] coordenadads = new string[5, 5]; // Un array de dos dimensiones se conoce como matríz\n        /*\n         * Para recorrer una matriz podemos utilizar dos ciclos for para \n         * recorrer tanto sus renglones como sus columnas\n         */\n        for (int i = 0; i < 5; i++)\n        {\n            for (int j = 0; j < 5; j++)\n            {\n                coordenadads[i, j] = $\"{i},{j}\";\n            }\n        }\n        \n        // Agregar\n        /* \n         * Al tener su tamaño definido al momento de creación\n         * no es posible agregar nuevos elementos, pero si \n         * reemplazar los ya existentes al conocer su posición\n         * o índice. Los índices se incializan en 0, por lo que\n         * el último elemento de un array con 5 elementos se\n         * encuentra en el índice 4\n         */\n        edades[4] = 6; // => {1, 2, 3, 4, 6}\n        /* \n         * edades[5] = 6 <- esto daría un error ya que el tamaño\n         *                  del array es de 5 por lo que el índice\n         *                  5 estaría fuera de ese límite\n         */\n\n        // Eliminar\n        /* \n         * Para elminar elementos de un array se puede usar el metodo\n         * Array.Clear() en el cual se indica a partir de cual indice\n         * quieres eliminar y la cantidad de elmentos a eliminar.\n         * Sin embargo el tamaño del array no cambia y en los índices\n         * donde se elimino se coloca un valor por default como el 0\n         */\n        Array.Clear(edades, 2, 2); // => {1, 2, 0, 0, 6}\n\n        // Modificar\n        /* \n         * Para modificar solo se debe indicar el indice del elemento\n         * a modificar y asignarle el nuevo valor\n         */\n        edades[0] = 5; // => {5, 2, 0, 0, 6}\n        edades[2] = 7; // => {5, 2, 7, 0, 6}\n        edades[3] = 2; // => {5, 2, 7, 2, 6}\n\n        // Ordenar\n        /* \n         * El metodo Array.Sort() ordena los elemento de\n         * mayor a menor por default en caso de tipos enteros\n         * o alfabéticamente en casa de chars o strings, teniendo la opción\n         * de enviar varias conbinacione de parámetros \n         * para configurar el ordenamiento\n         */\n\n        char[] letras = { 'f', 'b', 'a', 'h', 'c' };\n        Array.Sort(letras); // => {a, b, c, f, h}\n        #endregion\n        #region Listas\n        // Listas\n        /*\n         * También llamadas colecciones las listas\n         * permiten almacenar varios datos de un mismo\n         * tipo. A diferencia del array el tamaño de\n         * un lista es dinamico y no se tiene que indicar\n         * al momento de inicializarla. Además cuenta \n         * con metodos para el manejo de sus datos de una\n         * manera más fácil\n         */\n\n        List<string> paises = new List<string>();\n        // Agregar de datos\n        paises.Add(\"México\");\n        paises.Add(\"España\");\n        paises.Add(\"Perú\");\n        paises.Add(\"Colombia\");// => {\"México\", \"España\", \"Perú\", \"Colombia\"}\n        // Eliminar\n        paises.Remove(\"Perú\"); // => {\"México\", \"España\", \"Colombia\"}\n\n        // Modificar\n        /*\n         * Para modificar una lista se puede hacer \n         * de manera similar a un array e indicar\n         * el índice a modificar. Sin embargo al ser\n         * posible eliminar y agregar elementos el\n         * indice del elemento puede cambiar por lo\n         * que primero se tendría que buscar dicho \n         * índice\n         */\n        paises[1] = \"Españita\"; // => {\"México\", \"Españita\", \"Colombia\"}\n        paises[0] = \"Estados Unidos Mexicanos\"; // => {\"Estados Unidos Mexicanos\", \"España\", \"Colombia\"}\n\n        // Ordenar\n        /*\n         * Se ordenan los elementos de manera similar\n         * a  como se hace con arrays\n         */\n        paises.Sort(); // => {\"Colombia\", \"Españita\", \"Estados Unidos Mexicanos\"}\n        #endregion\n        #region Diccionario\n        // Diccionario\n        /*\n         * Representa una colección de claves y valores\n         * o key-value pairs\n         */\n        Dictionary<string, string> languages = new Dictionary<string, string>();\n        // Agregar\n        /*\n         * Se agreagan tanto la clave como el valor.\n         * Las claves no pueden ser duplicadas pero los\n         * valores sí\n         */\n        languages.Add(\"C#\", \"https://learn.microsoft.com/en-us/dotnet/csharp/\");\n        languages.Add(\"Python\", \"https://www.python.org/\");\n        languages.Add(\"Java\", \"https://www.java.com/es/\");\n        languages.Add(\"Javascript\", \"https://developer.mozilla.org/es/docs/Web/JavaScript\");\n        languages.Add(\"Php\", \"https://www.php.net/manual/es/intro-whatis.php\");\n        languages.Add(\"Kotlin\", \"https://kotlinlang.org/\");\n\n        // Eliminar\n        /*\n         * Para eliminar se utiliza el método Remove()\n         * indicando la clave de elemento, de manera\n         * utilizando la clave como un índice\n         */\n        languages.Remove(\"Java\");\n        // Modificar\n        /*\n         * Para modificar solo se índica la \n         * clave del elemento a modificar\n         */\n        languages[\"Python\"] = \"python.org\";\n\n        // Ordenar\n        /*\n         * Los diccionarios no tienen un metodo propio\n         * para ser ordenados. Sin embargo puede utilizarse \n         * Linq para ordenarlos\n         */\n        languages = (from language in languages\n                     orderby language.Key ascending\n                     select language).ToDictionary();\n        #endregion\n        #region Queue\n        // Queue\n        /*\n         * Queue o fila es una colección de datos\n         * donde se aplica el método FIFO (First In First Out).\n         * Como su nombre lo indica el primer elemento en entrar a\n         * la colección es el primero en salir\n         */\n\n        Queue<string> turnos = new Queue<string>();\n        // Agregar \n        /*\n         * Se utiliza el método Enqueue()\n         */\n        turnos.Enqueue(\"Uno\"); // => {\"Uno\"}\n        turnos.Enqueue(\"Dos\"); // => {\"Uno\", \"Dos\"}\n        turnos.Enqueue(\"Tres\"); // => {\"Uno\", \"Dos\", \"Tres\"}\n        turnos.Enqueue(\"Cuatro\"); // => {\"Uno\", \"Dos\", \"Tres\", \"Cuatro\"}\n        turnos.Enqueue(\"Cinco\"); // => {\"Uno\", \"Dos\", \"Tres\", \"Cuatro\", \"Cinco\"}\n\n        // Eliminar\n        turnos.Dequeue(); // => {\"Dos\", \"Tres\", \"Cuatro\", \"Cinco\"}\n        /*\n         * Para elminar se utiliza el metodo Dequeue()\n         * se elimina el primer elemento en se añadido\n         * no se puede indicar el elemento a remover\n         */\n\n        // No es posible modificar u ordenar una fila\n        #endregion\n        #region Stack\n        // Stack\n        /*\n         * Stack o pila es una colección de datos\n         * donde se aplica el método FILO (First In Last Out).\n         * Como su nombre lo indica el primer elemento en entrar a\n         * la colección es el ultimo en salir\n         */\n\n        Stack<int> stack = new Stack<int>();\n        // Agregar\n        /*\n         * Para agregar se utiliza el método Push\n         */\n        stack.Push(1); // => {1}\n        stack.Push(2); // => {1, 2}\n        stack.Push(3); // => {1, 2, 3}\n        stack.Push(4); // => { 1, 2, 3, 4}\n        stack.Push(5); // => { 1, 2, 3, 4, 5}\n\n        // Eliminar\n        /*\n         * Se utiliza el método Pop() para remover\n         * el último elemento agregado a la pila\n         */\n        stack.Pop(); // => { 1, 2, 3, 4}\n\n        // No es posible modificar u ordenar una pila\n        #endregion\n        #region Linked List\n        // Listas enlazadas\n        /*\n         * Una lista enlazada o linked list\n         * es una colección de datos en la\n         * cual todos sus elementos estan relacionados\n         */\n\n        LinkedList<string> list = new LinkedList<string>();\n        // Agregrar elementos\n        /*\n         * Existen cuatro metodos diferente para agregar\n         * elmentos o nodos a una lista enlazada\n         */\n        list.AddFirst(\"Primer elemento\"); //Se agrega un nodo al inicio de la lista\n        list.AddLast(\"Cuarto elemento\"); // Se agrega un nodo al final de la lista\n        LinkedListNode<string> current = list.Last; // Tomamos el último nodo para agregar otro en una posición anterior\n        list.AddBefore(current, \"Segundo elemento\"); // Agregamos el nuevo nodo antes del nodo indicado\n        current = list.Find(\"Segundo elemento\"); // Seleccionamos el nodo que acabamos de agregar\n        list.AddAfter(current, \"Tercer elemento\"); // Agregamos el nodo después del nodo indicado\n        list.AddLast(\"Quinto elemento\");\n        list.AddLast(\"Sexto elemento\");\n        list.AddLast(\"Séptimo elemento\");\n\n        // Eliminar\n        /*\n         * Existen tres formas diferentes para \n         * elminiar elementos o nodos\n         */\n        list.RemoveFirst(); // Se elimina el primer nodo de la lista\n        list.RemoveLast(); // Se elimina el último nodo de la lista\n        current = list.Find(\"Tercer elemento\"); // Se busca el nodo a eliminar\n        list.Remove(current); // Se elimina indicando el nodo\n\n        // Modificar\n        current = list.Find(\"Segundo elemento\"); // Se busca elemento a modificar\n        current.Value = \"Primer elemento\"; // Se asigna a la propiedad value el nuevo valor \n\n        // Ordenar\n        /*\n         * Para ordenar es necesario crear una\n         * segunda lista para almecenar el resultado\n         * de la función Sort() ya que esta no \n         * modifica la lista a ordenar\n         */\n        var orderedList = list.Order();\n\n        #endregion\n        #region HashSet\n        // Hash Set\n\n        /*\n         * Conjunto de datos que no\n         * admite elementos repetidos\n         * y no tiene un orden\n         */\n\n        HashSet<int> numeros = new HashSet<int>();\n        // Agregar\n        numeros.Add(1);\n        numeros.Add(2);\n        numeros.Add(3);\n        numeros.Add(3);\n        numeros.Add(4);\n        numeros.Add(5);\n        /*\n         * Aunque se indique la instruccón de agregar el número 3\n         * el hashset solo contiene 5 elemento ya que no acepta\n         * valores repetidos\n         */\n        Console.WriteLine($\"El hash tiene {numeros.Count} elementos\");\n\n        // Eliminar\n\n        numeros.Remove(1); // Se indica el valor a eliminar\n\n        // No es posible modificar un elemento o ordenar el hashset\n        #endregion\n        // Agenda telefónica\n        \n        bool salir = false;\n\n        Console.WriteLine();\n        Console.WriteLine();\n        while (!salir)\n        {\n            Console.WriteLine(\"----SISTEMA DE AGENDA TELEFONICA----\");\n            MostrarMenu();\n\n            int opcion;\n            int.TryParse(Console.ReadLine(), out opcion);\n            if (opcion == 0)\n            {\n                Console.Clear();\n                Console.WriteLine(\"Opción no valida, intente de nuevo\");\n            }\n            switch (opcion)\n            {\n                case 1:\n                    Console.Clear();\n                    if (agenda.Count == 0)\n                    {\n                        Console.WriteLine(\"Su agenda está vacía...\");\n                        break;\n                    }\n                    MostrarAgenda(agenda);\n                    break;\n                case 2:\n                    BuscarContacto();\n                    break;\n                case 3:\n                    AgregarContacto();\n                    break;\n                case 4:\n                    ModificarContacto();\n                    break;\n                case 5:\n                    EliminarContacto();\n                    break;\n                case 6:\n                    Console.Clear();\n                    Console.WriteLine(\"Hasta la próxima...\");\n                    Thread.Sleep(1000);\n                    salir = true;\n                    break;\n                default:\n                    Console.Clear();\n                    Console.WriteLine(\"Opción no valida, intente de nuevo\");\n                    break;\n            }\n\n        }\n        \n    }\n    static void MostrarMenu()\n    {\n        Console.WriteLine(\"1.- Consultar contactos\");\n        Console.WriteLine(\"2.- Buscar contacto\");\n        Console.WriteLine(\"3.- Agregar un nuevo contacto\");\n        Console.WriteLine(\"4.- Modificar contacto existente\");\n        Console.WriteLine(\"5.- Eliminar contacto\");\n        Console.WriteLine(\"6.- Salir\");\n        Console.WriteLine(\"Por favor elija una opción...\");\n    }\n    static void MostrarAgenda(List<Contacto> agenda)\n    {\n        foreach (var contacto in agenda)\n            Console.WriteLine($\"ID: {contacto.Id}, Nombre: {contacto.Nombre}, Teléfono: {contacto.Telefono}\");\n    }\n    static void BuscarContacto()\n    {\n        Console.Clear();\n        Console.WriteLine(\"Ingrese el nombre del contacto que desea buscar:\");\n        string contacto = Console.ReadLine();\n        var resultado = agenda.Where(c => c.Nombre.ToUpper().Contains(contacto.ToUpper())).ToList();\n        Console.Clear();\n        if (resultado.Count() == 0)\n        {\n            Console.WriteLine(\"No se encontró ningún contacto...\");\n            return;\n        }\n        Console.WriteLine(\"Se encontraron los siguientes contactos:\");\n        MostrarAgenda(resultado);\n    }\n    static string IngresarNombre()\n    {\n        string nombre = \"\";\n        do\n        {\n            Console.WriteLine(\"Ingrese el nombre del contacto\");\n            nombre = Console.ReadLine();\n            if (nombre == \"\")\n            {\n                Console.Clear();\n                Console.WriteLine(\"El nombre ingresado no es valido, intente de nuevo\");\n            }\n        } while (nombre == \"\");\n        return nombre;\n    }\n    static string IngresarTelefono()\n    {\n        Int64 num;\n        string telefono;\n        bool esValido = true;\n        do\n        {\n            esValido = true;\n            Console.WriteLine(\"Ingrese el número del contacto\");\n            telefono = Console.ReadLine();\n            if (!Int64.TryParse(telefono, out num) | telefono.Length > 11)\n            {\n                Console.Clear();\n                Console.WriteLine(\"El número ingresado no es valido, intente de nuevo\");\n                esValido = false;\n            }\n        } while (!esValido);\n        return telefono;\n    }\n    static void AgregarContacto()\n    {\n        Console.Clear();\n        string nombre = IngresarNombre();\n        string telefono = IngresarTelefono();\n        agenda.Add(new Contacto(id, nombre, telefono));\n        Console.Clear();\n        Console.WriteLine(\"El contacto se agregó correctamente:\");\n        Console.WriteLine($\"ID: {id}, Nombre: {nombre}, Telefono: {telefono}\");\n        id++;\n    }\n    static int BuscarPorId()\n    {\n        bool esValido = true;\n        int idContacto;\n        do\n        {\n            esValido = true;\n            Console.WriteLine(\"Especifique el id del contacto\");\n\n            int.TryParse(Console.ReadLine(), out idContacto);\n            if (idContacto == 0)\n            {\n                Console.WriteLine(\"Por favor ingrese un id válido...\");\n                esValido = false;\n            }\n            else if (agenda.Where(c => c.Id == idContacto).Count() == 0)\n            {\n                Console.WriteLine($\"No existe ningún contacto con el id {idContacto}...\");\n                esValido = false;\n            }\n\n        } while (!esValido);\n        return idContacto;\n    }\n    static void ModificarContacto()\n    { \n        Console.Clear();\n        MostrarAgenda(agenda);\n        int idContacto = BuscarPorId();\n\n        string nombre = IngresarNombre();\n        string telefono = IngresarTelefono();\n        var contacto = agenda.FirstOrDefault(c => c.Id == idContacto);\n        contacto.Nombre = nombre;\n        contacto.Telefono = telefono;\n        Console.Clear();\n        Console.WriteLine(\"Contacto modificado existosamente\");\n        MostrarAgenda(agenda);\n\n    }\n    static void EliminarContacto()\n    {\n        Console.Clear();\n        MostrarAgenda(agenda);\n        int idContacto = BuscarPorId();\n        var contacto = agenda.FirstOrDefault(c => c.Id == idContacto);\n        Console.WriteLine(\"Se eliminará el siguiente contacto:\");\n        Console.WriteLine($\"ID: {contacto.Id}, Nombre: {contacto.Nombre}, Teléfono: {contacto.Telefono}\");\n        Console.WriteLine(\"Para confirmar ingrese la tecla s, para cancelar ingrese otra tecla\");\n        string respuesta = Console.ReadLine();\n        if( respuesta.ToUpper() == \"S\")\n        {\n            agenda.Remove(contacto);\n            Console.WriteLine(\"El contacto se eliminó correctamente...\");\n        }\n        else\n        {\n            Console.WriteLine(\"La operación ha sido cancelada...\");\n        }\n        Thread.Sleep(2000);\n        Console.Clear();\n    }\n\n    class Contacto\n    {\n        public int Id { get; set; }\n        public string Nombre { get; set; }\n        public string Telefono { get; set; }\n\n        public Contacto(int id, string nombre, string telefono) \n        {\n            this.Id = id;\n            this.Nombre = nombre;\n            this.Telefono = telefono;\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/c#/jamerrq.cs",
    "content": "/*\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n*/\n\nusing System;\n\nclass DataStructures\n{\n    // Queue <T>\n    // https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.queue-1?view=net-8.0\n    static void Queue()\n    {\n        Console.WriteLine(\"=========\");\n        Console.WriteLine(\"Queue <T>\");\n        Console.WriteLine(\"=========\");\n        Console.WriteLine();\n\n        var queue = new Queue<string>();\n\n        queue.Enqueue(\"Hola\");\n        queue.Enqueue(\"C#\");\n        queue.Enqueue(\"!\");\n\n        Console.WriteLine(\"Método Enqueue\");\n        Console.WriteLine(\"Se utiliza para añadir un elemento al final de la cola\");\n        Console.WriteLine(\"============\");\n\n        Console.WriteLine(\"queue.Enqueue(\\\"Hola\\\")\");\n        Console.WriteLine(\"queue.Enqueue(\\\"C#\\\")\");\n        Console.WriteLine(\"queue.Enqueue(\\\"!\\\")\");\n        Console.WriteLine();\n\n        Console.WriteLine(\"Método Count\");\n        Console.WriteLine(\"Se utiliza para obtener el número de elementos de la cola\");\n        Console.WriteLine(\"============\");\n\n        Console.WriteLine(\"queue.Count: {0}\", queue.Count);\n        Console.WriteLine();\n\n        Console.WriteLine(\"Método Peek\");\n        Console.WriteLine(\"Se utiliza para obtener el primer elemento de la cola sin eliminarlo\");\n        Console.WriteLine(\"============\");\n\n        Console.WriteLine(\"queue.Peek(): {0}\", queue.Peek());\n        Console.WriteLine();\n\n        Console.WriteLine(\"Método Dequeue\");\n        Console.WriteLine(\"Se utiliza para obtener el primer elemento de la cola y eliminarlo\");\n        Console.WriteLine(\"============\");\n\n        Console.WriteLine(\"queue.Dequeue(): {0}\", queue.Dequeue());\n        Console.WriteLine();\n    }\n\n    // Stack <T>\n    // https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.stack-1?view=net-8.0\n    static void Stack()\n    {\n        Console.WriteLine(\"=========\");\n        Console.WriteLine(\"Stack <T>\");\n        Console.WriteLine(\"=========\");\n        Console.WriteLine();\n\n        var stack = new Stack<string>();\n\n        stack.Push(\"Hola\");\n        stack.Push(\"C#\");\n        stack.Push(\"!\");\n\n        Console.WriteLine(\"Método Push\");\n        Console.WriteLine(\"Se utiliza para añadir un elemento al final de la pila\");\n        Console.WriteLine(\"============\");\n\n        Console.WriteLine(\"stack.Push(\\\"Hola\\\")\");\n        Console.WriteLine(\"stack.Push(\\\"C#\\\")\");\n        Console.WriteLine(\"stack.Push(\\\"!\\\")\");\n        Console.WriteLine();\n\n        Console.WriteLine(\"Método Count\");\n        Console.WriteLine(\"Se utiliza para obtener el número de elementos de la pila\");\n        Console.WriteLine(\"============\");\n\n        Console.WriteLine(\"stack.Count: {0}\", stack.Count);\n        Console.WriteLine();\n\n        Console.WriteLine(\"Método Peek\");\n        Console.WriteLine(\"Se utiliza para obtener el primer elemento de la pila sin eliminarlo\");\n        Console.WriteLine(\"============\");\n\n        Console.WriteLine(\"stack.Peek(): {0}\", stack.Peek());\n        Console.WriteLine();\n\n        Console.WriteLine(\"Método Pop\");\n        Console.WriteLine(\"Se utiliza para obtener el primer elemento de la pila y eliminarlo\");\n        Console.WriteLine(\"============\");\n\n        Console.WriteLine(\"stack.Pop(): {0}\", stack.Pop());\n        Console.WriteLine();\n    }\n\n    // Dictionary <TKey, TValue>\n    // https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2?view=net-8.0\n    static void Dictionary()\n    {\n        Console.WriteLine(\"==============\");\n        Console.WriteLine(\"Dictionary <TKey, TValue>\");\n        Console.WriteLine(\"==============\");\n        Console.WriteLine();\n\n        var dictionary = new Dictionary<string, string>\n        {\n            { \"Hola\", \"Hello\" },\n            { \"C#\", \"C#\" },\n            { \"!\", \"!\" }\n        };\n\n        Console.WriteLine(\"Método Add\");\n        Console.WriteLine(\"Se utiliza para añadir un elemento al diccionario\");\n        Console.WriteLine(\"============\");\n\n        Console.WriteLine(\"dictionary.Add(\\\"Hola\\\", \\\"Hello\\\")\");\n        Console.WriteLine(\"dictionary.Add(\\\"C#\\\", \\\"C#\\\")\");\n        Console.WriteLine(\"dictionary.Add(\\\"!\\\", \\\"!\\\")\");\n        Console.WriteLine();\n\n        Console.WriteLine(\"Método Count\");\n        Console.WriteLine(\"Se utiliza para obtener el número de elementos del diccionario\");\n        Console.WriteLine(\"============\");\n\n        Console.WriteLine(\"dictionary.Count: {0}\", dictionary.Count);\n        Console.WriteLine();\n\n        Console.WriteLine(\"Método ContainsKey\");\n        Console.WriteLine(\"Se utiliza para comprobar si existe una clave en el diccionario\");\n        Console.WriteLine(\"============\");\n\n        Console.WriteLine(\"dictionary.ContainsKey(\\\"Hola\\\"): {0}\", dictionary.ContainsKey(\"Hola\"));\n        Console.WriteLine();\n\n        Console.WriteLine(\"Método ContainsValue\");\n        Console.WriteLine(\"Se utiliza para comprobar si existe un valor en el diccionario\");\n        Console.WriteLine(\"============\");\n\n        Console.WriteLine(\"dictionary.ContainsValue(\\\"Hello\\\"): {0}\", dictionary.ContainsValue(\"Hello\"));\n        Console.WriteLine();\n\n        Console.WriteLine(\"Método TryGetValue\");\n        Console.WriteLine(\"Se utiliza para obtener el valor de una clave en el diccionario\");\n        Console.WriteLine(\"============\");\n\n        dictionary.TryGetValue(\"Hola\", out string? value);\n        Console.WriteLine(\"dictionary.TryGetValue(\\\"Hola\\\", out value): {0}\", value);\n        Console.WriteLine();\n\n        Console.WriteLine(\"Método Remove\");\n        Console.WriteLine(\"Se utiliza para eliminar un elemento del diccionario\");\n        Console.WriteLine(\"============\");\n\n        dictionary.Remove(\"Hola\");\n        Console.WriteLine(\"dictionary.Remove(\\\"Hola\\\")\");\n        Console.WriteLine();\n    }\n\n    // List <T>\n    // https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.list-1?view=net-8.0\n    static void List()\n    {\n        Console.WriteLine(\"=========\");\n        Console.WriteLine(\"List <T>\");\n        Console.WriteLine(\"=========\");\n        Console.WriteLine();\n\n        var list = new List<string>();\n\n        list.Add(\"Hola\");\n        list.Add(\"C#\");\n        list.Add(\"!\");\n\n        Console.WriteLine(\"Método Add\");\n        Console.WriteLine(\"Se utiliza para añadir un elemento a la lista\");\n        Console.WriteLine(\"============\");\n\n        Console.WriteLine(\"list.Add(\\\"Hola\\\")\");\n        Console.WriteLine(\"list.Add(\\\"C#\\\")\");\n        Console.WriteLine(\"list.Add(\\\"!\\\")\");\n        Console.WriteLine();\n\n        Console.WriteLine(\"Método Count\");\n        Console.WriteLine(\"Se utiliza para obtener el número de elementos de la lista\");\n        Console.WriteLine(\"============\");\n\n        Console.WriteLine(\"list.Count: {0}\", list.Count);\n        Console.WriteLine();\n\n        Console.WriteLine(\"Método Contains\");\n        Console.WriteLine(\"Se utiliza para comprobar si existe un elemento en la lista\");\n        Console.WriteLine(\"============\");\n\n        Console.WriteLine(\"list.Contains(\\\"Hola\\\"): {0}\", list.Contains(\"Hola\"));\n        Console.WriteLine();\n\n        Console.WriteLine(\"Método IndexOf\");\n        Console.WriteLine(\"Se utiliza para obtener el índice de un elemento en la lista\");\n        Console.WriteLine(\"============\");\n\n        Console.WriteLine(\"list.IndexOf(\\\"Hola\\\"): {0}\", list.IndexOf(\"Hola\"));\n        Console.WriteLine();\n\n        Console.WriteLine(\"Método Remove\");\n        Console.WriteLine(\"Se utiliza para eliminar un elemento de la lista\");\n        Console.WriteLine(\"============\");\n\n        list.Remove(\"Hola\");\n        Console.WriteLine(\"list.Remove(\\\"Hola\\\")\");\n        Console.WriteLine();\n    }\n\n    // Array\n    // https://docs.microsoft.com/en-us/dotnet/api/system.array?view=net-8.0\n    static void ArrayMethod()\n    {\n        Console.WriteLine(\"=====\");\n        Console.WriteLine(\"Array\");\n        Console.WriteLine(\"=====\");\n        Console.WriteLine();\n\n        var array = new string[3];\n\n        array[0] = \"Hola\";\n        array[1] = \"C#\";\n        array[2] = \"!\";\n\n        Console.WriteLine(\"Método Length\");\n        Console.WriteLine(\"Se utiliza para obtener el número de elementos del array\");\n        Console.WriteLine(\"============\");\n\n        Console.WriteLine(\"array.Length: {0}\", array.Length);\n        Console.WriteLine();\n\n        Console.WriteLine(\"Método IndexOf\");\n        Console.WriteLine(\"Se utiliza para obtener el índice de un elemento en el array\");\n        Console.WriteLine(\"============\");\n\n        Console.WriteLine(\"Array.IndexOf(array, \\\"Hola\\\"): {0}\", Array.IndexOf(array, \"Hola\"));\n        Console.WriteLine();\n\n        Console.WriteLine(\"Método Clear\");\n        Console.WriteLine(\"Se utiliza para eliminar todos los elementos del array\");\n        Console.WriteLine(\"============\");\n\n        Array.Clear(array, 0, array.Length);\n        Console.WriteLine(\"Array.Clear(array, 0, array.Length)\");\n        Console.WriteLine();\n    }\n\n    /*\n     * DIFICULTAD EXTRA (opcional):\n     * Crea una agenda de contactos por terminal.\n     * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n     * - Cada contacto debe tener un nombre y un número de teléfono.\n     * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n     *   los datos necesarios para llevarla a cabo.\n     * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n     *   (o el número de dígitos que quieras)\n     * - También se debe proponer una operación de finalización del programa.\n    */\n    class Contact\n    {\n        public string Name { get; set; }\n        public string Phone { get; set; }\n\n        public Contact(string name, string phone)\n        {\n            Name = name;\n            Phone = phone;\n        }\n    }\n\n    static void Agenda()\n    {\n        Console.WriteLine(\"=======\");\n        Console.WriteLine(\"Agenda\");\n        Console.WriteLine(\"=======\");\n        Console.WriteLine();\n\n        var contacts = new List<Contact>();\n\n        while (true)\n        {\n            Console.WriteLine(\"¿Qué operación quieres realizar?\");\n            Console.WriteLine(\"1. Buscar contacto\");\n            Console.WriteLine(\"2. Añadir contacto\");\n            Console.WriteLine(\"3. Actualizar contacto\");\n            Console.WriteLine(\"4. Eliminar contacto\");\n            Console.WriteLine(\"5. Salir\");\n            Console.WriteLine();\n\n            Console.Write(\"Opción: \");\n            var option = Console.ReadLine();\n\n            Console.WriteLine();\n\n            switch (option)\n            {\n                case \"1\":\n                    Console.Write(\"Nombre: \");\n                    var name = Console.ReadLine();\n\n                    var contact = contacts.Find(c => c.Name == name);\n\n                    if (contact != null)\n                    {\n                        Console.WriteLine(\"Contacto encontrado\");\n                        Console.WriteLine(\"Nombre: {0}\", contact.Name);\n                        Console.WriteLine(\"Teléfono: {0}\", contact.Phone);\n                    }\n                    else\n                    {\n                        Console.WriteLine(\"No se ha encontrado el contacto\");\n                    }\n\n                    break;\n                case \"2\":\n                    Console.WriteLine(\"¿Qué contacto quieres añadir?\");\n                    Console.Write(\"Nombre: \");\n                    var name2 = Console.ReadLine();\n\n                    Console.Write(\"Teléfono: \");\n                    var phone = Console.ReadLine();\n\n                    if (name2 != null && phone != null)\n                        contacts.Add(new Contact(name2, phone));\n\n                    break;\n                case \"3\":\n                    Console.WriteLine(\"¿Qué contacto quieres actualizar?\");\n                    Console.Write(\"Nombre: \");\n                    var name3 = Console.ReadLine();\n\n                    var contact3 = contacts.Find(c => c.Name == name3);\n\n                    if (contact3 != null)\n                    {\n                        Console.Write(\"Teléfono: \");\n                        string? phone3 = Console.ReadLine();\n\n                        if (phone3 != null)\n                            contact3.Phone = phone3;\n                    }\n                    else\n                    {\n                        Console.WriteLine(\"No se ha encontrado el contacto\");\n                    }\n\n                    break;\n                case \"4\":\n                    Console.WriteLine(\"¿Qué contacto quieres eliminar?\");\n                    Console.Write(\"Nombre: \");\n                    var name4 = Console.ReadLine();\n\n                    var contact4 = contacts.Find(c => c.Name == name4);\n\n                    if (contact4 != null)\n                    {\n                        contacts.Remove(contact4);\n                    }\n                    else\n                    {\n                        Console.WriteLine(\"No se ha encontrado el contacto\");\n                    }\n\n                    break;\n                case \"5\":\n                    return;\n                default:\n                    Console.WriteLine(\"Opción no válida\");\n                    break;\n            }\n\n            Console.WriteLine();\n        }\n    }\n\n\n    static void Main()\n    {\n        bool runExtra = true;\n        Queue();\n        Console.WriteLine();\n        Stack();\n        Console.WriteLine();\n        Dictionary();\n        Console.WriteLine();\n        List();\n        Console.WriteLine();\n        ArrayMethod();\n        if (runExtra)\n        {\n            Console.WriteLine();\n            Agenda();\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/c#/jcubero12.cs",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\n// ESTRUCTURAS DE DATOS\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.ObjectModel;\nusing System.Collections.Concurrent;\nclass Program\n{\n    static void Main(string[] args)\n    {\n        //Arreglos\n        int[] nums = { 1, 2, 3, };\n        Console.WriteLine(nums[0]); // 1\n\n        // Listas\n        List<int> numbers = new List<int> { 1, 2, 3 };\n        numbers.Add(4);\n        numbers.Remove(2);\n\n        foreach (int num in numbers)\n        {\n            Console.WriteLine(num); // 1 3 4\n        }\n\n        // Diccionarios \n        Dictionary<string, int> phoneBook = new Dictionary<string, int>\n        {\n            {\"Juan\", 1234567890},\n            {\"Pedro\", 9876543210}\n        };\n        phoneBook.Add(\"Ana\", 5555555555);\n        foreach (var contact in phoneBook)\n        {\n            Console.Write($\"Nombre: {contact.Key}, Número: {contact.Value}\\n\");\n        }\n\n        //Queues basada en fifo\n        Queue<int> queue = new Queue<int>();\n        queue.Enqueue(1);\n        queue.Enqueue(2);\n        queue.Enqueue(3);\n        Console.WriteLine(queue.Dequeue()); // 1\n\n        //Stacks basada en lifo\n        Stack<int> stack = new Stack<int>();\n        stack.Push(1);\n        stack.Push(2);\n        stack.Push(3);\n        Console.WriteLine(stack.Pop()); // 3\n\n        //Hashset no permite duplicados y no ordena los elementos\n        HashSet<int> set = new HashSet<int> { 1, 2, 3 };\n        set.Add(3); //No se agrega porque ya está en el set\n        set.Remove(4);\n        foreach (int num in set)\n        {\n            Console.WriteLine(num);\n        }\n\n        //Linkedlist permite insertar y eliminar elementos en cualquier lugar\n        LinkedList<string> linkedList = new LinkedList<string>();\n        linkedList.AddLast(\"Node1\");\n        linkedList.AddLast(\"Node2\");\n        linkedList.AddFirst(\"Node0\");\n        foreach (string node in linkedList)\n        {\n            Console.WriteLine(node);\n        }\n\n        //SortList permite ordenar los elementos por clave\n        SortedList<int, string> sortedList = new SortedList<int, string>\n        {\n            { 2, \"B\" },\n            { 1, \"A\" },\n            { 3, \"C\" }\n        };\n        foreach (var item in sortedList)\n        {\n            Console.WriteLine($\"Key: {item.Key}, Value: {item.Value}\");\n        }\n\n        //Observable collections permite notificar a sus observadores cuando cambia su contenido\n        ObservableCollection<string> observable = new ObservableCollection<string>();\n        observable.CollectionChanged += (sender, e) =>\n        {\n            Console.WriteLine($\"Action: {e.Action}\");\n        };\n        observable.Add(\"Item1\"); // Notifica el cambio\n\n        //Tuples son estructuras de datos que contienen varios valores\n        var tuple = (1, \"Alice\", true);\n        Console.WriteLine($\"ID: {tuple.Item1}, Name: {tuple.Item2}, Active: {tuple.Item3}\");\n\n        //KeyValyePair permite crear pares de valores\n        KeyValuePair<int, string> kvp = new KeyValuePair<int, string>(1, \"Alice\");\n        Console.WriteLine($\"Key: {kvp.Key}, Value: {kvp.Value}\");\n\n        //BitArray permite manipular bits\n        BitArray bits = new BitArray(4);\n        bits[0] = true;\n        bits[1] = false;\n        bits[2] = true;\n        bits[3] = false;\n        foreach (bool bit in bits)\n        {\n            Console.WriteLine(bit);\n        }\n\n        //CurrentQueue Colecciones seguras para entornos multihilo del espacio de nombres\n        ConcurrentQueue<int> concurrentQueue = new ConcurrentQueue<int>();\n        concurrentQueue.Enqueue(1);\n        concurrentQueue.Enqueue(2);\n        if (concurrentQueue.TryDequeue(out int result))\n        {\n            Console.WriteLine(result); // Imprime \"1\"\n        }\n\n        //Span Permite manipular segmentos de memoria sin crear copias\n        Span<int> numbers = stackalloc int[] { 1, 2, 3, 4, 5 };\n        numbers[0] = 10;\n        foreach (var number in numbers)\n        {\n            Console.WriteLine(number);\n        }\n\n        Agenda ListaContactos = new Agenda();\n\n        while (true)\n        {\n            ShowMenu();\n            Console.Write(\"Elige una opción: \");\n            int option = int.Parse(Console.ReadLine());\n\n            switch (option)\n            {\n                case 1:\n                    Console.Write(\"Nombre del contacto a buscar: \");\n                    string name = Console.ReadLine();\n                    ListaContactos.SearchContact(name);\n                    break;\n                case 2:\n                    Console.Write(\"Nombre del contacto: \");\n                    string name2 = Console.ReadLine();\n                    Console.Write(\"Número de teléfono: \");\n                    string phone = Console.ReadLine();\n                    ListaContactos.AddContact(name2, phone);\n                    break;\n                case 3:\n                    Console.WriteLine(\"Nombre Contacto a actualizar: \")\n                    string UpdateName = Console.ReadLine();\n                    Console.WriteLine(\"Nuevo número de teléfono: \")\n                    string UpdatePhone = Console.ReadLine();\n                    ListaContactos.UpdateContact(UpdateName, UpdatePhone);\n                    break;\n                case 4:\n                    Console.WriteLine(\"Nombre Contacto a eliminar: \")\n                    string DeleteName = Console.ReadLine();\n                    ListaContactos.DeleteContact(DeleteName);\n                case 5:\n                    ListaContactos.AllContacts();\n                    break;\n                case 6:\n                    return;\n                default:\n                    Console.WriteLine(\"Opción no válida\");\n                    break;\n            }\n        }\n\n        static void ShowMenu()\n        {\n            Console.WriteLine(\"\\n--- Agenda de Contactos ---\");\n            Console.WriteLine(\"1# Buscar contacto\");\n            Console.WriteLine(\"2# Crear contacto\");\n            Console.WriteLine(\"3# Actualizar contacto\");\n            Console.WriteLine(\"4# Eliminar contacto\");\n            Console.WriteLine(\"5# Todos los contactos\");\n            Console.WriteLine(\"6# Salir\");\n        }\n\n        public class Agenda()\n    {\n        private Dictionary<string, string> contacts = new Dictionary<string, string>();\n\n        public void AddContact(string name, string phone)\n        {\n            if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(phone) || !phone.All(char.IsDigit) || phone.Length != 11)\n            {\n                Console.WriteLine(\"Error: Invalid data\");\n                return;\n            }\n            else\n            {\n                contacts.Add(name, phone);\n                Console.WriteLine($\"Contact {name} added with phone number {phone}\");\n            }\n        }\n\n        public void SearchContact(string name)\n        {\n            if (TryGetValue(name, out string phone))\n            {\n                Console.WriteLine($\"Contact {name} found with phone number {phone}\");\n                return;\n            }\n            else\n            {\n                Console.WriteLine($\"Contact {name} not found\");\n                return;\n            }\n        }\n\n        public void UpdateContact(string name, string newPhone)\n        {\n            if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(newPhone) || !newPhone.All(char.IsDigit) || newPhone.Length != 11)\n            {\n                Console.WriteLine(\"Error: Invalid data\");\n            }\n            else\n            {\n                if (contacts.ContainsKey(name))\n                {\n                    contacts[name] = newPhone;\n                }\n                else\n                {\n                    Console.WriteLine($\"Contact {name} not found\");\n                }\n            }\n            return;\n        }\n\n        public void DeleteContact(string name)\n        {\n            if (contacts.ContainsKey(name))\n            {\n                contacts.Remove(name);\n                Console.WriteLine($\"Contact {name} deleted\");\n            }\n            else\n            {\n                Console.WriteLine($\"Contact {name} not found\");\n            }\n        }\n\n        public void AllContacts()\n        {\n            Console.WriteLine(\"All contacts:\");\n            foreach (var contact in contacts)\n            {\n                Console.WriteLine($\"Name: {contact.Key}, Phone: {contact.Value}\");\n            }\n        }\n    }\n}\n}\n\n\n    \n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/c#/kenysdev.cs",
    "content": "// ╔══════════════════════════════════════╗\n// ║ Autor:  Kenys Alvarado               ║\n// ║ GitHub: https://github.com/Kenysdev  ║\n// ║ 2024 -  C#                           ║\n// ╚══════════════════════════════════════╝\nclass Program\n{\n    static void Main()\n    {\n        // -----------------\n        // Arrays(Arreglos):\n        // -----------------\n        // - Colección de elementos del mismo tipo almacenados en posiciones contiguas de memoria.\n        // - Acceso rápido a elementos por índice.\n        // Declarar e inicializar\n        var numeros = new int[2];\n        var palabras = new string[] { \"Hola\", \"Mundo\" };\n\n        // Inserción:\n        numeros[0] = 1;\n        numeros[1] = 2;\n\n        // Acceder:\n        Console.WriteLine(numeros[0]);\n\n        // Modificar:\n        palabras[1] = \"Ben\";\n\n        // Ordenación:\n        Array.Sort(numeros);\n\n        // Iteración:\n        for (int i = 0; i < numeros.Length; i++)\n        {\n            Console.WriteLine(\"Índice \" + i + \": \" + numeros[i]);\n        }\n        // Nota: Los arreglos en C# son de tamaño fijo después de la inicialización.\n\n        // -------------\n        // List(Listas):\n        // -------------\n        // - Dinámicas y redimensionables, permiten almacenar elementos del mismo tipo.\n        // - Flexibilidad en la manipulación de datos.\n        // Declarar e inicializar\n        var nombres = new List<string>();\n        var abc = new List<string> { \"a\", \"c\", \"d\" };\n\n        // Inserción:\n        nombres.Add(\"Ben\"); // Agrega elemento al final de la lista.\n        abc.Insert(1, \"b\"); // Agrega un elemento en una posición específica.\n\n        // Acceder:\n        Console.WriteLine(abc[1]);\n\n        // Modificar:\n        nombres[0] = \"Zoe\";\n\n        // Eliminacion:\n        abc.Remove(\"a\");\n        abc.RemoveAt(1); // por indice\n        abc.RemoveAll(x => x == \"c\"); // todas las ocurrencias\n\n        // Ordenación:\n        abc.Sort();\n\n        // Iteración:\n        foreach (string i in abc)\n        {\n            Console.WriteLine(i);\n        }\n\n        // --------------------------\n        // Dictionary(Diccionarios ):\n        // --------------------------\n        // - Asocian claves únicas con valores, permitiendo búsquedas eficientes.\n        // - Almacenar y recuperar datos con base en claves.\n        // Declarar\n        var nombre_edad = new Dictionary<string, int>();\n        var dic = new Dictionary<string, int>\n        {\n            {\"a\", 1},\n            {\"b\", 2}\n        };\n        // Inserción:\n        nombre_edad[\"Zoe\"] = 21;\n        dic.Add(\"c\", 3);\n\n        // Acceder:\n        Console.WriteLine(dic[\"b\"]);\n        // No mostrar excepción en caso de no existir.\n        if (dic.TryGetValue(\"b\", out var valor_))\n        {\n            Console.WriteLine(valor_);\n        }\n        // Modificar:\n        nombre_edad[\"Zoe\"] = 27;\n\n        // Eliminacion:\n        dic.Remove(\"c\");\n\n        // Iteración:\n        foreach (int valor in dic.Values) // o dic.Keys\n        {\n            Console.WriteLine(valor);\n        }\n\n        // -------------\n        // Queue(Colas):\n        // -------------\n        // - Estructura FIFO (Primero en entrar, primero en salir).\n        // - Modelar procesos secuenciales.\n        // Declarar\n        var cola = new Queue<string>();\n\n        // Inserción:\n        cola.Enqueue(\"Joe\");\n\n        // Acceder:\n        Console.WriteLine(cola.Peek()); // Mostrar el primero sin eliminarlo.\n        Console.WriteLine(cola.Dequeue()); // Mostrar el primero y eliminarlo\n        Console.WriteLine(cola.Count); // Obtener la cantidad de elementos.\n\n        // Eliminacion:\n        cola.Clear(); //  Elimina todos los elementos.\n\n        // Iteración:\n        foreach (var elemento in cola)\n        {\n            Console.WriteLine(elemento);\n        }\n\n        // -------------\n        // Stack(Pilas):\n        // -------------\n        // - Estructura LIFO (Último en entrar, primero en salir).\n        // - Gestión de llamadas a funciones, historial de navegación(Undo/Redo).\n        // Declarar\n        var miPila = new Stack<int>();\n\n        // Apilar elementos:\n        miPila.Push(1);\n        miPila.Push(2);\n\n        // Ver el elemento en la cima de la pila sin quitarlo\n        Console.WriteLine(miPila.Peek());\n\n        // Desapilar un elemento:\n        Console.WriteLine(miPila.Pop());\n\n        // Imprimir todos los elementos de la pila:\n        foreach (var elemento in miPila)\n        {\n            Console.WriteLine(elemento);\n        }\n\n        // ------------------\n        // HashSet(Conjuntos):\n        // ------------------\n        // - Colección sin duplicados, sin orden definido.\n        // - Verificación de pertenencia y eliminación de duplicados.\n        // Declarar e inicializar\n        var miConjunto = new HashSet<int>();\n        var otroConjunto = new HashSet<int> { 2, 3, 4 };\n\n        // Inserción:\n        miConjunto.Add(1);\n        miConjunto.Add(2);\n\n        // Buscar:\n        if (otroConjunto.Contains(3))\n        {\n            Console.WriteLine($\"El conjunto contiene el elemento {3}\");\n        }\n\n        // Eliminacion:\n        miConjunto.Remove(2);\n\n        // Verificación:\n        Console.WriteLine(miConjunto.Contains(1));\n\n        // Operaciones:\n        miConjunto.UnionWith(otroConjunto);     // Unión de conjuntos\n        miConjunto.IntersectWith(otroConjunto); // Intersección de conjuntos\n        miConjunto.ExceptWith(otroConjunto);    // Diferencia de conjuntos\n\n        // Iteración:\n        foreach (var elemento in otroConjunto)\n        {\n            Console.WriteLine(elemento);\n        }\n\n        // ---------\n        // Matrices:\n        // ---------\n        // - Estructura bidimensional organizada en filas y columnas.\n        // - Representar datos tabulares.\n        // Declarar e inicializar\n        var mtx1 = new int[3, 3];\n        var mtx2 = new int[,] { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };\n\n        // asignación:\n        mtx1[0, 0] = 1;\n        mtx1[0, 1] = 2;\n        mtx1[0, 2] = 3;\n\n        // Acceder:\n        Console.WriteLine(mtx1[0, 1]);\n\n        // Iteración:\n        int filas = mtx2.GetLength(0);\n        int columnas = mtx2.GetLength(1);\n        for (int i = 0; i < filas; i++)\n        {\n            for (int j = 0; j < columnas; j++)\n            {\n                Console.Write(mtx2[i, j] + \" \");\n            }\n            Console.WriteLine();\n        }\n\n        // --------------\n        // Tuple(tuplas):\n        // --------------\n        // - Agrupación de elementos heterogéneos como una entidad única.\n        // - Son inmutables.\n        // - Devolver múltiples valores desde un método.\n        // Declarar e inicializar\n        var miTupla = (1, \"hola\", 3.14, true);\n        var tuplaConNombres = (numero: 1, saludo: \"hola\", pi: 3.14, esCierto: true);\n        object item1 = 1;\n        object item2 = \"hola\";\n        var miTupla2 = new ValueTuple<object, object>(item1, item2);\n\n        // Acceder:\n        Console.WriteLine(miTupla.Item1);\n        Console.WriteLine(tuplaConNombres.saludo);\n\n        // ---------\n        // Ejercicio:\n        // ---------\n        /*\n        * Crea una agenda de contactos por terminal.\n        * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n        * - Cada contacto debe tener un nombre y un número de teléfono.\n        * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n        *   los datos necesarios para llevarla a cabo.\n        * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n        *   (o el número de dígitos que quieras)\n        * - También se debe proponer una operación de finalización del programa.\n        */\n        while (true)\n        {\n            Agenda();\n        }\n    }\n\n    static Dictionary<string, string> miAgenda = new Dictionary<string, string>();\n    static void Agenda()\n    {\n        Console.WriteLine(@\"\n    Agenda de contactos\n╔═══════════════════════════╗\n║ 1. Nuevo      4. Editar   ║\n║ 2. Buscar     5. Eliminar ║\n║ 3. Lista      6. Salir    ║\n╚═══════════════════════════╝\n        \");\n\n        Console.Write(\"Número de opción: \");\n        string option = Console.ReadLine()!;\n\n        switch (option)\n        {\n            case \"1\": Crear();  break;\n            case \"2\": Buscar(); break;\n            case \"3\": Lista();  break;\n            case \"4\": Editar(); break; \n            case \"5\": Eliminar(); break;\n            case \"6\":\n                Console.WriteLine(\"Adios\");\n                Environment.Exit(0);\n                break;\n            default:\n                Console.WriteLine(\"Número 1 -> 6\");\n                break;\n        }\n    }\n    static void Crear()\n    {\n        Console.WriteLine(\"Crear contacto o 6 para Salir\");\n        Console.Write(\"Escriba el nombre: \");\n        string nombre = Console.ReadLine()!;\n\n        if (nombre.Length < 1)\n        {\n            Crear();\n        }\n        else if (nombre == \"6\")\n        {\n            Console.WriteLine(\"Cancelado\");\n        }\n        else if (miAgenda.ContainsKey(nombre))\n        {\n            Console.WriteLine(\"El nombre ya existe.\");\n        }\n        else\n        {\n            Console.Write(\"Escriba el número: \");\n            string numero = Console.ReadLine()!;\n\n            if (int.TryParse(numero, out _) && numero.Length > 0 && numero.Length <= 11)\n            {\n                miAgenda[nombre] = numero;\n                Console.WriteLine(\"Guardado\");\n            }\n            else\n            {\n                Console.WriteLine(\"Número no válido.\");\n            }\n        }\n    }\n\n    static void Buscar()\n    {\n        Console.WriteLine(\"Buscar contacto o 6 para Salir\");\n        Console.Write(\"Escriba el nombre:\\n\");\n        string nombre = Console.ReadLine()!;\n\n        if (nombre == \"6\")\n        {\n            Console.WriteLine(\"Cancelado\");\n        }\n        else if (miAgenda.ContainsKey(nombre))\n        {\n            Console.WriteLine(miAgenda[nombre]);\n        }\n        else\n        {\n            Console.WriteLine(\"Contacto no encontrado.\");\n        }\n    }\n\n    static void Lista()\n    {\n        var ordenarAgenda = new SortedDictionary<string, string>(miAgenda);\n\n        foreach (var entry in ordenarAgenda)\n        {\n            Console.WriteLine($\"{entry.Key}: {entry.Value}\");\n        }\n    }\n\n    static void Editar()\n    {\n        Console.WriteLine(\"Editar contacto o 6 para Salir\");\n        Console.Write(\"Escriba el nombre: \");\n        string nombre = Console.ReadLine()!;\n\n        if (nombre == \"6\")\n        {\n            Console.WriteLine(\"Cancelado\");\n        }\n        else if (miAgenda.ContainsKey(nombre))\n        {\n            Console.Write(\"Escriba el nuevo número: \");\n            string nuevoNumero = Console.ReadLine()!;\n\n            if (int.TryParse(nuevoNumero, out _) && nuevoNumero.Length > 0 && nuevoNumero.Length <= 11)\n            {\n                miAgenda[nombre] = nuevoNumero;\n                Console.WriteLine(\"Contacto editado\");\n            }\n            else\n            {\n                Console.WriteLine(\"Número no válido.\");\n            }\n        }\n        else\n        {\n            Console.WriteLine(\"Contacto no encontrado.\");\n        }\n    }\n\n    static void Eliminar()\n    {\n        Console.WriteLine(\"Eliminar contacto o 6 para Salir\");\n        Console.Write(\"Escriba el nombre: \");\n        string nombre = Console.ReadLine()!;\n\n        if (nombre == \"6\")\n        {\n            Console.WriteLine(\"Cancelado\");\n        }\n        else if (miAgenda.ContainsKey(nombre))\n        {\n            miAgenda.Remove(nombre);\n            Console.WriteLine(\"Contacto eliminado\");\n        }\n        else\n        {\n            Console.WriteLine(\"Contacto no encontrado.\");\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/c#/mor39a.cs",
    "content": "/*\n--------------------------------------------------------------------------------------------------------\nInstrucciones:\n\n    1. Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n    2. Utiliza operaciones de inserción, borrado, actualización y ordenación.\n\nDificultad extra:\n    Crea una agenda de contactos por terminal.\n        - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n        - Cada contacto debe tener un nombre y un número de teléfono.\n        - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n          los datos necesarios para llevarla a cabo.\n        - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n          (o el número de dígitos que quieras)\n        - También se debe proponer una operación de finalización del programa.\n--------------------------------------------------------------------------------------------------------\n*/\n\n#region Arreglos\n\n//Los array tienen un tamaño fijo y almacenan elementos de un tipo especifico.\n\n// Definiciones:\nusing System.Runtime.InteropServices;\n\nstring[] myArray = {\n    \"Un dato\",\n    \"Otro dato\",\n    \"Y otro dato\"\n};\nstring[] otroArray = new string[10];\n\n// Insercion:\n// Dado que son de tamaño fijo no se pueden hacer inserciones.\n\n// Borrado:\nmyArray[0] = null!; //Esta seria lo mas parecido a hacer un borrado de un dato.\nmyArray = new string[3]; // De esta forma se pueden borrar todos los datos (y de paso volver a asignar el tamaño)\n\n// Actualizacion:\nmyArray[0] = \"Nuevo dato\";\n\n// Reorganizacion:\n// No se puede reorganizar directamente, se necesitaria la ayuda de otro array\notroArray = myArray;\nmyArray[0] = otroArray[2];\nmyArray[1] = otroArray[0];\nmyArray[2] = otroArray[1];\n\n#region Arreglos Multidimencionales\n\n// Son arreglos de mas de una dimancion\n\n// Definiciones:\nstring[,] myMatriz = {\n    {\"Primera dimencion\", \"Segunda dimencion\", }\n};\nstring[,] myMatriz2 = new string[1, 2];\n\n#endregion\n\n#region Arreglos de arreglos\n\n// Son arreglos de arreglos\n\n//Definiciones:\nstring[][] myJaggedArray = {\n    [\"Un\", \"Array\"],\n    [\"Otro\", \"Array\"]\n};\nstring[][] myJaggedArray2 = new string[5][];\n\n#endregion\n\n#endregion\n\n#region Listas\n\n// Las listas a diferencia de los array no tienen un tamaño fijo.\n// Lo que permite insertar, eliminar y acceder facilmente a los datos.\n// Tambien almacenan datos de un tipo especifico.\n\n// Definicion:\nList<string> myList = new();\n\n// Insercion:\nmyList.Add(\"Nuevo elemento\");\n\n// Borrado:\nfor (int i = 0; i < 10; i++) myList.Add(null!); // Temporal para tener elemento que eliminar\nmyList.Remove(\"Nuevo elemento\"); // Elimina un dato en especifico por su contenido\nmyList.RemoveAt(0); // Elimina un dato en especifico por su index\nmyList.RemoveRange(0, 3); // Elimina un rango\nmyList.Clear(); // Elimina todo\n\n// Actualizacion:\nfor (int i = 0; i < 10; i++) myList.Add(i.ToString()); // Temporal para tener elemento que actualizar\nmyList[0] = \"Dato actualizado\"; // Actualiza por indice\n\n// Reorganizacion:\nmyList.Sort(); // Ordena de manera acendente\nmyList.Sort((x, y) => y.CompareTo(x)); // Ordena de manera desendente\n\n#endregion\n\n#region Diccionarios\n\n// Los diccionarios permiten guardar una lista de elementos (de tipo especifico)\n// bajo una llave (de otro o el mismo tipo especifico).\n// Tambien tienen un tamaño flexible, por lo que tambien pueden insertar, eliminar\n// y acceder a datos aun mas facil que con las listas.\n// No permite llaves repetidas.\n\n// Definicion:\nDictionary<string, int> /*<llave, valor>*/ myDictionary = new();\n\n// Insercion:\nmyDictionary.Add(\"Uno\", 1);\n\n// Borrado:\nfor (int i = 0; i < 10; i++) myDictionary.Add(i.ToString(), i); // Temporal para tener elemento que eliminar\nmyDictionary.Remove(\"Uno\"); // Eliminacion por llave\nint datoEliminadoDic;\nmyDictionary.Remove(\"1\", out datoEliminadoDic); // Elimina por llave y guarda el valor en el segundo parametro\nmyDictionary.Clear(); // Elimina todos los valores\n\n// Actualizacion:\nfor (int i = 10; i > 0; i--) myDictionary.Add(i.ToString(), i); // Temporal para tener elemento que actualizar\nmyDictionary[\"2\"] = 3; // Actualiza por llave\n\n// Reorganizacion:\nmyDictionary = myDictionary.OrderBy(x => x.Key).ToDictionary(); // Ordena por la llave, pero toca volverlo a asignar.\nmyDictionary = myDictionary.OrderBy(x => x.Value).ToDictionary(); // Ordena por la valor, pero toca volverlo a asignar.\n\n#endregion\n\n#region Colas\n\n// Sigen el principio FIFO (First In, First Out)\n// Solo permite interactuar, o mas bien, eliminar el primer elemento\n// No tiene metodo de actualizacion ni reorganizacion.\n\n// Definicion:\nQueue<string> myQueue = new();\n\n// Insercion:\nmyQueue.Enqueue(\"Yo ire primero\");\nmyQueue.Enqueue(\"Luego ire yo\");\nmyQueue.Enqueue(\"Y luego yo\");\n\n// Borrado:\nstring valorQueue = myQueue.Dequeue(); // Elimina el primer valor y lo retorna\nmyQueue.Clear(); // Elimina todos los valores\n\n// Reorganizacion:\n// Se que dije que no se puede reorganizar, pero si lo conviertes en una lista\n// y luego nuevamente a una cola, se puede lograr\nfor (int i = 0; i < 0; i++) myQueue.Enqueue(i.ToString()); // Temporal para tener elemento que reorganizar\nList<string> tempQList = myQueue.ToList();\ntempQList.Sort();\nmyQueue = new(tempQList);\n// PD: Este mismo enfoque se puede usar para la actualizacion\n\n#region Colas Prioritarias\n\n// Es una estructura de datos que permite guardar elementos con una prioridad asociada\n\n// Definicion:\nPriorityQueue<string, int> /*<valor, prioridad>*/ myPriorityQueue = new();\n\n// Insercion:\nmyPriorityQueue.Enqueue(\"Valor\", 1);\nmyPriorityQueue.Enqueue(\"Otro valor\", 2);\n\n#endregion\n\n#endregion\n\n#region Pilas\n\n// Sigue el principio LIFO (Last In, First Out)\n// Solo permite interactuar, o mas bien, eliminar el ultimo elemento\n// No tiene metodo de actualizacion ni reorganizacion.\n\n// Definicion:\nStack<string> myStack = new();\n\n// Insercion:\nmyStack.Push(\"Yo ire primero\");\nmyStack.Push(\"No, ire yo\");\nmyStack.Push(\"Se equivocan, ire yo\");\n\n// Borrado:\nstring valorStack = myStack.Pop(); // Elimina el ultimo elemento y lo retorna.\n\n// Reorganizacion:\n// Se que dije que no se puede reorganizar, pero si lo conviertes en una lista\n// y luego nuevamente a una pila, se puede lograr\nfor (int i = 0; i < 0; i++) myStack.Push(i.ToString()); // Temporal para tener elemento que reorganizar\nList<string> tempSList = myStack.ToList();\ntempSList.Sort();\nmyStack = new(tempSList);\n// PD: Este mismo enfoque se puede usar para la actualizacion\n\n#endregion\n\n#region Conjuntos\n\n// Es una coleccion no ordenada\n// Dada su naturaleza no permite reorganizar datos, pero tampoco actualizar\n// No permite datos duplicados por lo que es muy util para verificar si hay datos duplicados en una estructura de datos\n\n// Definicion:\nHashSet<string> myHashSet = new();\n\n// Insercion:\nmyHashSet.Add(\"Hola mundo\");\n\n// Borrado:\nmyHashSet.Remove(\"Hola mundo\");\nmyHashSet.Clear(); // Elimina todo\n\n// Actualizacion:\n// La unica manera de actualizar datos es eliminandolos y volviendolos a añadir\n\n#region Conjunto Ordenado\n\n// Parecido al HashSet, pero mantiene los elementos ordenados siempre y automaticamente\n\n// Definicion\nSortedSet<string> mySortedSet = new();\n\n#endregion\n\n#endregion\n\n#region Tuplas\n\n// Agrupan un numero fijo de elementos de diferentes tipos\n\n// Definicion:\nvar myTuple = Tuple.Create(\"Hola\", 2);\nvar myTuple2 = (\"Chao\", \"1\", 5);\n\n// Actualizacion:\nmyTuple = Tuple.Create(\"Nuevo valor\", myTuple.Item2);\nmyTuple2.Item1 = \"Nuevo valor\";\n\n#endregion\n\n#region Lista enlazada\n\n// Es una lista que permite la adiccion y eliminacion desde cualquier parte de la misma.\n// Aunque consume mas memoria debido a sus apuntadores\n\n// Definicion:\nLinkedList<string> myLinkedList = new();\n\n// Insercion:\nmyLinkedList.AddFirst(\"Se añade al principio\");\nmyLinkedList.AddLast(\"Se añade al final\");\nmyLinkedList.AddBefore(myLinkedList.First!, \"Se añade antes de\");\nmyLinkedList.AddAfter(myLinkedList.Last!, \"Se añade despues de\");\n\n// Borrado:\nmyLinkedList.Remove(\"Se añade despues de\"); // Elimina un objeto especifico\nmyLinkedList.RemoveFirst(); // Elimina el primer objeto\nmyLinkedList.RemoveLast(); // Elimina el ultimo objeto\n\n//La actualizacion y reorganizacion es igual que una lista normal\n\n#endregion\n\n#region Span y Memory\n\n// Imagina que tienes un array muy grande\nstring[] arrayImaginario = new string[1000];\n// Y solo vas a trabajar en algunos datos, como lo harias?\n// Copiando?\nstring[] arrayCopia = new string[100];\nArray.Copy(arrayImaginario, 100, arrayCopia, 0, 100);\n// Esto consume memoria y es muy poco eficiente\n// Ademas de que luego tendras que volver a pasar los datos al array original\nArray.Copy(arrayCopia, 0, arrayImaginario, 100, 100);\n\n// Para eso estan Span y Memory\n// Estos te permiten acceder a estos datos sin necesidad de hacer una copia\nSpan<string> mySpan = arrayImaginario.AsSpan(100, 100);\n\n// Lo unico es que Span vive en la memoria rapida (stack),\n// por lo que, anque lo hace mas rapido, solo se guardara mientras lo estas usando\n// ademas de que no permite usar async\n// Para eso usas Memory\nMemory<string> myMemory = arrayImaginario.AsMemory(100, 100);\n// Este vive en la memoria mas duradera (heap),\n// por lo que puedes guardarlo y usarlo despues, aunque esto lo hace mas lento\n\n#endregion\n\n#region Extra\n\n/*Dificultad extra:\n    Crea una agenda de contactos por terminal.\n        - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n        - Cada contacto debe tener un nombre y un número de teléfono.\n        - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n          los datos necesarios para llevarla a cabo.\n        - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n          (o el número de dígitos que quieras)\n        - También se debe proponer una operación de finalización del programa.*/\n\nbool inProgram = true;\n\nwhile (inProgram)\n{\n    Console.WriteLine(\"\\nMenu Principal:\\n\");\n\n    Console.WriteLine(\"Seleccione una opcion:\");\n    Console.WriteLine(\"     1. Agregar un nuevo contacto\");\n    Console.WriteLine(\"     2. Editar un contacto\");\n    Console.WriteLine(\"     3. Buscar un contacto\");\n    Console.WriteLine(\"     4. Eliminar un contacto\");\n    Console.WriteLine(\"     5. Salir\");\n\n    ConsoleKeyInfo input = Console.ReadKey();\n    Console.WriteLine();\n\n    string? name;\n    string? number;\n    string? countryCode;\n\n    switch (input.KeyChar)\n    {\n        case '1': // Nuevo contacto\n            InputNumber();\n            Console.WriteLine(ContactBook.AddContact(name, number, countryCode) ? $\"Contacto {name} agregado exitosamente.\" : $\"No se pudo agregar a {name}.\");\n            break;\n        case '2': // Editar contacto\n            InputNumber();\n            Console.WriteLine(ContactBook.UpdateContact(name, number, countryCode) ? $\"El contacto {name} fue editado exitosamente\" : $\"No fue posible editar el contacto {name}.\");\n            break;\n        case '3': // Buscar contacto\n            InputName();\n            Console.WriteLine(ContactBook.GetContact(name));\n            break;\n        case '4': // Eliminar contacto\n            InputName();\n            Console.WriteLine(ContactBook.DeleteContact(name) ? $\"Contacto {name} eliminado exitosamente.\" : $\"No se pudo eliminar a {name}.\");\n            break;\n        case '5': // Salir\n            inProgram = false;\n            Console.WriteLine(\"Hasta luego\");\n            return;\n        default: // Opcion no valida\n            Console.WriteLine(\"No a ingresado una opcion valida\");\n            break;\n    }\n    Console.WriteLine(\"Oprima cualquier tecla para continuar.\");\n    Console.ReadKey();\n\n    void InputNumber()\n    {\n        bool validNumber = false;\n\n        InputName();        \n\n        Console.WriteLine(\"Ingrese el codigo de pais (opcional - enter para omitir):\");\n        countryCode = Console.ReadLine();\n        do\n        {\n            Console.WriteLine(\"Ingrese el numero telefonico:\");\n            number = Console.ReadLine();\n            switch (ContactBook.VerifyNumber(number))\n            {\n                case 0:\n                    validNumber = true;\n                    break;\n                case 1:\n                    Console.WriteLine(\"El numero no puede ser nullo.\");\n                    break;\n                case 2:\n                    Console.WriteLine(\"Solo se admiten numeros.\");\n                    break;\n                case 3:\n                    Console.WriteLine(\"El numero es muy largo, por favor ingrese hasta 10 digitos.\");\n                    break;\n                default:\n                    Console.WriteLine(\"Numero no valido.\");\n                    break;\n            }\n        } while (!validNumber);\n\n    }\n\n    void InputName()\n    {\n        bool validName = false;\n        do\n        {\n            Console.WriteLine(\"Escriba el nombre:\");\n            name = Console.ReadLine();\n            if (!string.IsNullOrWhiteSpace(name)) validName = true;\n            else Console.WriteLine(\"Nombre no valido.\");\n        } while (!validName);\n    }\n}\n\npublic static class ContactBook\n{\n    #region Private Declarations\n\n    private static Dictionary<string, string> contactBook = new();\n\n    #endregion\n\n    #region Public Procedures\n\n    public static int VerifyNumber(string? number)\n    {\n        if (string.IsNullOrWhiteSpace(number)) return 1;\n        number = number.Replace(\" \", \"\");\n        if (!number.All(char.IsDigit)) return 2;\n        else if (number.Length > 10) return 3;\n        else return 0;\n    }\n\n    public static bool AddContact(string? name, string? number, string? countryCode = null)\n    {\n        if (VerifyNumber(number) != 0 || string.IsNullOrWhiteSpace(name)) return false;\n        contactBook.Add(name, FormatNumber(number, countryCode));\n        return true;\n    }\n\n    public static string GetContact(string? name)\n        => !string.IsNullOrWhiteSpace(name) && contactBook.ContainsKey(name) ? contactBook[name] : $\"El contacto {name} no existe\";\n\n    public static bool DeleteContact(string? name)\n    {\n        if (!string.IsNullOrWhiteSpace(name) && contactBook.ContainsKey(name))\n        {\n            contactBook.Remove(name);\n            return true;\n        } else return false;\n    }\n\n    public static bool UpdateContact(string? name, string? newNumber, string? newCountryCode = null)\n    {\n        if (VerifyNumber(newNumber) != 0 || string.IsNullOrWhiteSpace(name)) return false;\n        contactBook[name] = FormatNumber(newNumber, newCountryCode);\n        return true;\n    }\n\n    #endregion\n\n    #region Private Procedures\n\n    private static string FormatNumber(string? number, string? countryCode = null)\n    {\n        if (string.IsNullOrWhiteSpace(number)) return null!;\n        number = number.Replace(\" \", \"\");\n        if (!string.IsNullOrWhiteSpace(countryCode) && countryCode.Replace(\" \", \"\").All(char.IsDigit))\n        {\n            countryCode = countryCode.Replace(\" \", \"\");\n            if (number.Length != 10) return $\"+{countryCode.Replace(\" \", \"\")} {number}\";\n            else return $\"+{countryCode.Replace(\" \", \"\")} {number[..3]} {number.Substring(3, 3)} {number[6..]}\";\n        }\n        if (number.Length != 10) return number;\n        else return $\"{number[..3]} {number.Substring(3, 3)} {number[6..]}\";\n    }\n\n    #endregion\n}\n\n#endregion\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/c#/vasilealexandru02.cs",
    "content": "public class vasilealexandru02\n{\n    static string regexTelefono = @\"^\\d{9}$\";\n\n    static List<Contacto> listaDeContactos = new List<Contacto>();\n\n    static string rutaArchivoTxt = \"\";\n    static void Main(string[] args)\n    {\n        rutaArchivoTxt = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), \"contactos.txt\");\n        // Colas \n        // Es una coleccin de tipo FIFO (First In First Out)\n\n        Queue queue = new Queue();\n        // Operacin insercin\n        queue.Enqueue(1);\n        queue.Enqueue(2);\n        queue.Enqueue(3);\n\n        Console.WriteLine(\"Imprimiendo elementos de la cola: \");\n        foreach (var i in queue)\n        {\n            Console.WriteLine(\"Elemento \" + i + \" en la cola\");\n        }\n        Console.WriteLine(\"\");\n\n        // Operacin de eliminacin o sacar de la cola\n        queue.Dequeue();\n        queue.Dequeue();\n\n        Console.WriteLine(\"Cola despus de quitar elementos de la cola: \");\n        foreach (var i in queue)\n        {\n            Console.WriteLine(\"Elemento \" + i + \" en la cola\");\n        }\n        Console.WriteLine(\"\");\n        Console.WriteLine(\"Mtodo para ver el siguiente elemento a sacar de la cola \" + \"Elemento \" + queue.Peek());\n\n        queue.Enqueue(1);\n        queue.Enqueue(2);\n        queue.Enqueue(3);\n        Console.WriteLine(\"Valores de la cola antes de vaciarla: \");\n        foreach (var i in queue)\n        {\n            Console.WriteLine(\"Elemento \" + i + \" en la cola\");\n        }\n\n        Console.WriteLine(\"\");\n        queue.Clear();\n        Console.WriteLine(\"Valores de la cola despus de vaciarla: \");\n        foreach (var i in queue)\n        {\n            Console.WriteLine(\"Elemento \" + i + \" en la cola\");\n        }\n        Console.WriteLine(\"\");\n\n        // Stack\n        // Representa una coleccin de tipo LIFO (Last In First Out)\n\n        Stack stack = new Stack();\n\n        // Operacin de insercin\n        stack.Push(\"Primer elemento\");\n        stack.Push(\"Segundo elemento\");\n        stack.Push(\"Tercer elemento\");\n        stack.Push(\"Cuarto elemento\");\n\n        Console.WriteLine(\"Valores del stack: \");\n        foreach (var i in stack)\n        {\n            Console.WriteLine(\"Elemento \" + i + \" en la cola\");\n        }\n        Console.WriteLine(\"\");\n\n        // Operacin de eliminacin\n        stack.Pop();\n        stack.Pop();\n\n        Console.WriteLine(\"Valores del stack despus sacar elementos: \");\n        foreach (var i in stack)\n        {\n            Console.WriteLine(\"Elemento \" + i + \" en la cola\");\n        }\n        Console.WriteLine(\"\");\n\n\n        // Arrays \n\n        var arrayAlimentos = new Alimento[10];\n\n        // Operacin de insercin\n        arrayAlimentos[0] = new Alimento { nombre = \"Espinaca\", precio = .8, calorias = 23 };\n        arrayAlimentos[1] = new Alimento { nombre = \"Salmn\", precio = 10, calorias = 208 };\n        arrayAlimentos[2] = new Alimento { nombre = \"Tofu\", precio = 2, calorias = 144 };\n        arrayAlimentos[3] = new Alimento { nombre = \"Arndanos\", precio = 3, calorias = 57 };\n        arrayAlimentos[4] = new Alimento { nombre = \"Avena\", precio = .5, calorias = 389 };\n        arrayAlimentos[5] = new Alimento { nombre = \"Almendras\", precio = 5, calorias = 576 };\n        arrayAlimentos[6] = new Alimento { nombre = \"Quinoa\", precio = 1.5, calorias = 120 };\n        arrayAlimentos[7] = new Alimento { nombre = \"Lentejas\", precio = .9, calorias = 116 };\n        arrayAlimentos[8] = new Alimento { nombre = \"Aguacate\", precio = 1, calorias = 160 };\n        arrayAlimentos[9] = new Alimento { nombre = \"Batata\", precio = .75, calorias = 86 };\n\n        Console.WriteLine(\"Imprimiendo elementos de la array: \");\n        foreach (var alimento in arrayAlimentos)\n        {\n            Console.WriteLine($\"Nombre: {alimento.nombre} | Caloras: {alimento.calorias} | Precio: {alimento.precio}\");\n        }\n        Console.WriteLine(\"\");\n\n        // Operacin de borrado \n\n        arrayAlimentos = arrayAlimentos.Where(a => a.nombre.StartsWith(\"A\")).ToArray();\n\n        Console.WriteLine(\"Imprimiendo elementos de la array despus del borrado: \");\n        foreach (var alimento in arrayAlimentos)\n        {\n            Console.WriteLine($\"Nombre: {alimento.nombre} | Caloras: {alimento.calorias} | Precio: {alimento.precio}\");\n        }\n        Console.WriteLine(\"\");\n\n        // Operacin de actualizacin \n\n        var alimentos = arrayAlimentos.ToList();\n\n        foreach (var alimento in alimentos)\n        {\n            if (alimento.calorias > 150)\n            {\n                alimento.precio += 2;\n            }\n\n        }\n\n        arrayAlimentos = alimentos.ToArray();\n\n        Console.WriteLine(\"Imprimiendo elementos de la array despus de la actualizacin del precio: \");\n        foreach (var alimento in arrayAlimentos)\n        {\n            Console.WriteLine($\"Nombre: {alimento.nombre} | Caloras: {alimento.calorias} | Precio: {alimento.precio}\");\n        }\n        Console.WriteLine(\"\");\n\n        // Operacin de ordenacin\n\n        arrayAlimentos = arrayAlimentos.OrderBy(a => a.calorias).ToArray();\n\n        Console.WriteLine(\"Imprimiendo elementos de la array despus de la ordenacin por kcal: \");\n\n        foreach (var alimento in arrayAlimentos)\n        {\n            Console.WriteLine($\"Nombre: {alimento.nombre} | Caloras: {alimento.calorias} | Precio: {alimento.precio}\");\n        }\n        Console.WriteLine(\"\");\n\n\n        // Listas \n\n        var listaAlimentos = new List<Alimento>()\n{\n     new Alimento { nombre = \"Manzana\", precio = 0.5, calorias = 95 },\n            new Alimento { nombre = \"Pan\", precio = 1, calorias = 265 },\n            new Alimento { nombre = \"Leche\", precio = 0.9, calorias = 42 },\n            new Alimento { nombre = \"Queso\", precio = 2.5, calorias = 405 },\n            new Alimento { nombre = \"Yogur\", precio = 0.8, calorias = 59 },\n            new Alimento { nombre = \"Pollo\", precio = 5, calorias = 215 },\n            new Alimento { nombre = \"Arroz\", precio = .7, calorias = 130 },\n            new Alimento { nombre = \"Pasta\", precio = 1.2, calorias = 131 }\n\n};\n\n        //Operacin de insercin \n\n        listaAlimentos.Add(\n                    new Alimento { nombre = \"Pepino\", precio = 0.25, calorias = 16 });\n        listaAlimentos.Add(new Alimento { nombre = \"Tomate\", precio = 0.30, calorias = 18 });\n\n\n        Console.WriteLine(\"Imprimiendo elementos de la lista: \");\n        listaAlimentos.ForEach(a => Console.WriteLine($\"Nombre: {a.nombre} | Caloras: {a.calorias}\"));\n        Console.WriteLine(\"\");\n\n        // Operacin de borrado\n\n        listaAlimentos.RemoveAt(7);\n        listaAlimentos.RemoveAt(8);\n\n        Console.WriteLine(\"Imprimiendo elementos de la lista despus del borrado: \");\n        listaAlimentos.ForEach(a => Console.WriteLine($\"Nombre: {a.nombre} | Caloras: {a.calorias}\"));\n        Console.WriteLine(\"\");\n\n        // Operacin de actualizacin\n\n        foreach (var alimento in listaAlimentos)\n        {\n            if (alimento.precio < 1)\n            {\n                alimento.nombre = \"Alimento asequible\";\n            }\n        }\n\n\n        Console.WriteLine(\"Imprimiendo elementos de la lista despus de la actualizacin del nombre: \");\n        listaAlimentos.ForEach(a => Console.WriteLine($\"Nombre: {a.nombre} | Caloras: {a.calorias}\"));\n        Console.WriteLine(\"\");\n\n\n        // Operacin de ordenacin \n        listaAlimentos = listaAlimentos.OrderByDescending(a => a.calorias).ToList();\n\n        Console.WriteLine(\"Imprimiendo elementos de la lista despus de ordenarlos por sus caloras: \");\n        listaAlimentos.ForEach(a => Console.WriteLine($\"Nombre: {a.nombre} | Caloras: {a.calorias}\"));\n        Console.WriteLine(\"\");\n\n        var alimentosQueComienzanPorP = listaAlimentos.Where(x => x.nombre.StartsWith(\"P\"));\n\n\n        // Hashshets \n\n\n        // Operacin de insercin\n\n        HashSet<Alimento> hashSetAlimentos = new HashSet<Alimento>()\n{\n    new Alimento { nombre = \"Aguacate\", precio = 1.00, calorias = 160},\n            new Alimento { nombre = \"Tofu\", precio = 0.50, calorias = 76},\n            new Alimento { nombre = \"Lentejas\", precio = 0.35, calorias = 116},\n            new Alimento { nombre = \"Quinoa\", precio = 1.10, calorias = 120},\n            new Alimento { nombre = \"Espinacas\", precio = 0.40, calorias = 23},\n            new Alimento { nombre = \"Nueces\", precio = 2.00, calorias = 654},\n            new Alimento { nombre = \"Arndanos\", precio = 1.50, calorias = 57}\n};\n\n        hashSetAlimentos.Add(new Alimento { nombre = \"Garbanzos\", precio = 0.33, calorias = 164 });\n        hashSetAlimentos.Add(new Alimento { nombre = \"Tempeh\", precio = 1.75, calorias = 193 });\n        hashSetAlimentos.Add(new Alimento { nombre = \"Kale\", precio = 0.90, calorias = 49 });\n\n        Console.WriteLine(\"Imprimiendo elementos del hashset: \");\n\n        foreach (var alimento in hashSetAlimentos)\n        {\n            Console.WriteLine($\"Nombre: {alimento.nombre} | Caloras: {alimento.calorias}\");\n        }\n        Console.WriteLine(\"\");\n\n        // Operacin de eliminacin\n        hashSetAlimentos.RemoveWhere(alimento => alimento.nombre.Equals(\"Tofu\") || alimento.nombre.Equals(\"Nueces\"));\n\n        Console.WriteLine(\"Imprimiendo elementos del hashset despus de la eliminacin: \");\n\n        foreach (var alimento in hashSetAlimentos)\n        {\n            Console.WriteLine($\"Nombre: {alimento.nombre} | Caloras: {alimento.calorias}\");\n        }\n        Console.WriteLine(\"\");\n\n\n        // Operacin de actualizacin\n        foreach (var alimento in hashSetAlimentos)\n        {\n            alimento.nombre += \" modificado.\";\n        }\n\n\n        Console.WriteLine(\"Imprimiendo elementos del hashset despus de la actualizacin del nombre: \");\n\n        foreach (var alimento in hashSetAlimentos)\n        {\n            Console.WriteLine($\"Nombre: {alimento.nombre} | Caloras: {alimento.calorias}\");\n        }\n        Console.WriteLine(\"\");\n\n        // Operacin de ordenacin\n\n\n        hashSetAlimentos = hashSetAlimentos.OrderBy(alimento => alimento.calorias).ToHashSet();\n\n\n        Console.WriteLine(\"Imprimiendo elementos del hashset despus de ordenarlos por sus caloras: \");\n\n        foreach (var alimento in hashSetAlimentos)\n        {\n            Console.WriteLine($\"Nombre: {alimento.nombre} | Caloras: {alimento.calorias}\");\n        }\n        Console.WriteLine(\"\");\n\n        // Diccionarios\n\n\n        // Operacin de insercin\n\n        Dictionary<string, Alimento> diccionarioAlimentos = new Dictionary<string, Alimento>();\n        diccionarioAlimentos.Add(\"0001\", new Alimento { nombre = \"Papaya\", precio = 1.20, calorias = 59 });\n        diccionarioAlimentos.Add(\"0002\", new Alimento { nombre = \"Mango\", precio = 0.80, calorias = 60 });\n        diccionarioAlimentos.Add(\"0003\", new Alimento { nombre = \"Espinaca\", precio = 0.50, calorias = 23 });\n        diccionarioAlimentos.Add(\"0004\", new Alimento { nombre = \"Almendra\", precio = 2.50, calorias = 575 });\n        diccionarioAlimentos.Add(\"0005\", new Alimento { nombre = \"Sardinas\", precio = 1.00, calorias = 208 });\n        diccionarioAlimentos.Add(\"0006\", new Alimento { nombre = \"Batata\", precio = 0.45, calorias = 86 });\n        diccionarioAlimentos.Add(\"0007\", new Alimento { nombre = \"Kfir\", precio = 1.30, calorias = 99 });\n        diccionarioAlimentos.Add(\"0009\", new Alimento { nombre = \"Cacao\", precio = 2.00, calorias = 228 });\n        diccionarioAlimentos.Add(\"0010\", new Alimento { nombre = \"Cha\", precio = 1.50, calorias = 486 });\n        diccionarioAlimentos.Add(\"0011\", new Alimento { nombre = \"Lino\", precio = 0.75, calorias = 534 });\n\n\n        Console.WriteLine(\"Imprimiendo elementos del diccionario: \");\n        foreach (var elemento in diccionarioAlimentos)\n        {\n            Console.WriteLine($\"Key/Clave: {elemento.Key} | Nombre alimento:  {elemento.Value.nombre} | Precio: {elemento.Value.precio}\");\n        }\n\n        Console.WriteLine(\"\");\n\n        // Operacin de eliminacin\n\n        diccionarioAlimentos.Remove(\"0001\");\n        diccionarioAlimentos.Remove(\"0007\");\n\n        Console.WriteLine(\"Imprimiendo elementos del diccionario despus de la eliminacin: \");\n        foreach (var elemento in diccionarioAlimentos)\n        {\n            Console.WriteLine($\"Key/Clave: {elemento.Key} | Nombre alimento:  {elemento.Value.nombre} | Precio: {elemento.Value.precio}\");\n        }\n\n        Console.WriteLine(\"\");\n\n\n        // Operacin de actualizacin\n\n\n        foreach (var alimento in diccionarioAlimentos)\n        {\n            alimento.Value.nombre += \" modificado diccionario.\";\n        }\n\n\n        Console.WriteLine(\"Imprimiendo elementos del diccionario despus de la actualizacin: \");\n        foreach (var elemento in diccionarioAlimentos)\n        {\n            Console.WriteLine($\"Key/Clave: {elemento.Key} | Nombre alimento:  {elemento.Value.nombre} | Precio: {elemento.Value.precio}\");\n        }\n\n        Console.WriteLine(\"\");\n\n        // Operacin de ordenacin\n        diccionarioAlimentos = diccionarioAlimentos.OrderByDescending(alimento => alimento.Value.precio).ToDictionary(pair => pair.Key, pair => pair.Value);\n\n        Console.WriteLine(\"Imprimiendo elementos del diccionario despus de la ordenacin: \");\n        foreach (var elemento in diccionarioAlimentos)\n        {\n            Console.WriteLine($\"Key/Clave: {elemento.Key} | Nombre alimento:  {elemento.Value.nombre} | Precio: {elemento.Value.precio}\");\n        }\n\n        Console.WriteLine(\"\");\n\n        leerContactos();\n        agendaDeContactos();\n        /* DIFICULTAD EXTRA (opcional):\n         * Crea una agenda de contactos por terminal.\n         * - Debes implementar funcionalidades de bsqueda, insercin, actualizacin y eliminacin de contactos.\n         * - Cada contacto debe tener un nombre y un nmero de telfono.\n         * - El programa solicita en primer lugar cul es la operacin que se quiere realizar, y a continuacin\n         *   los datos necesarios para llevarla a cabo.\n         * - El programa no puede dejar introducir nmeros de telfono no nmericos y con ms de 11 dgitos.\n         *   (o el nmero de dgitos que quieras)\n         * - Tambin se debe proponer una operacin de finalizacin del programa.\n         */\n\n\n        static void agendaDeContactos()\n        {\n\n            Console.WriteLine(\"---- AGENDA DE CONTACTOS ----\");\n            Console.WriteLine(\"Qu operacion quieres realizar?\");\n            Console.WriteLine(\"1. Buscar contactos\\n\" +\n                \"2. Introducir contacto\\n\" +\n                \"3. Actualizar contacto\\n\" +\n                \"4. Eliminar contacto\\n\" +\n                \"0. Salir del programa\");\n\n            bool opcionConvertida;\n            int opcion;\n\n\n            do\n            {\n                opcionConvertida = int.TryParse(Console.ReadLine(), out opcion);\n                // Segn la opcin elegida, con un switch elige cada uno de los mtodos\n\n                switch (opcion)\n                {\n                    case 0:\n                        if (!opcionConvertida)\n                        {\n                            Console.WriteLine(\"Opcion no vlida!\");\n                        }\n                        else\n                        {\n                            Console.WriteLine(\"Has salido del programa!\");\n                            Environment.Exit(0);\n                        }\n                        break;\n                    case 1:\n                        buscarContactos();\n                        break;\n                    case 2:\n                        introducirContactos();\n                        break;\n                    case 3:\n                        actualizarContacto();\n                        break;\n                    case 4:\n                        eliminarContacto();\n                        break;\n                    default:\n                        Console.WriteLine(\"Opcin no vlida\");\n                        break;\n                }\n\n            } while (!opcionConvertida || opcion != 0);\n        }\n\n\n        // Este mtodo elimina un contacto\n        static void eliminarContacto()\n        {\n\n            if (!(listaDeContactos.Count == 0))\n            {\n                int idUsuario;\n                bool idCorrecto;\n                bool campoAModificarCorrecto;\n                int campoAModificar;\n                string mensajeActualizar = \"Introduce el id del usuario que quieres eliminar: \";\n\n\n                do\n                {\n                    Console.WriteLine(mensajeActualizar);\n                    idCorrecto = int.TryParse(Console.ReadLine(), out idUsuario);\n                    mensajeActualizar = \"Por favor introduce un valor numrico vlido: \";\n\n                } while (!idCorrecto);\n\n\n                var contactoSeleccionado = listaDeContactos.Where(c => c.idContacto == idUsuario).FirstOrDefault();\n                if (contactoSeleccionado != null)\n                {\n                    listaDeContactos.Remove(contactoSeleccionado);\n                    Console.WriteLine(\"Contacto eliminado correctamente\");\n\n                }\n                else\n                {\n                    Console.WriteLine(\"Id introducida no encontrada!\");\n                }\n\n            }\n            else\n            {\n                Console.WriteLine(\"La lista est vaca :(!\");\n            }\n            vaciarArchivo();\n            guardarContacto();\n            agendaDeContactos();\n        }\n\n        // Este mtodo va a actualizar un contacto en concreto\n        static void actualizarContacto()\n        {\n            if (!(listaDeContactos.Count == 0))\n            {\n                int idUsuario;\n                bool idCorrecto;\n                bool campoAModificarCorrecto;\n                bool telefonoValido;\n                int campoAModificar;\n                string telefonoContacto;\n                string mensajeTelefonoIncorrecto = \"\";\n\n                string mensajeActualizar = \"Introduce el id del usuario que quieres actualizar: \";\n\n\n                do\n                {\n                    Console.WriteLine(mensajeActualizar);\n                    idCorrecto = int.TryParse(Console.ReadLine(), out idUsuario);\n                    mensajeActualizar = \"Por favor introduce un valor numrico vlido: \";\n\n                } while (!idCorrecto);\n\n\n                var contactoSeleccionado = listaDeContactos.Where(c => c.idContacto == idUsuario).FirstOrDefault();\n                if (contactoSeleccionado != null)\n                {\n                    Console.WriteLine(\"Por favor elige el campo a modificar: \\n 1. Nombre\\n\" +\n                  \" 2. Nmero telefnico\");\n                    campoAModificarCorrecto = int.TryParse(Console.ReadLine(), out campoAModificar);\n                    if (campoAModificar == 1)\n                    {\n                        Console.WriteLine($\"Valor actual: {contactoSeleccionado.nombre} | Nuevo valor: \\n\");\n                        listaDeContactos.Where(c => c.idContacto == idUsuario).FirstOrDefault().nombre = Console.ReadLine();\n\n                        Console.WriteLine(\"Nombre modificado correctamente.\");\n                    }\n                    else if (campoAModificar == 2)\n                    {\n\n                        do\n                        {\n                            Console.WriteLine($\"Valor actual: {contactoSeleccionado.numeroTelefono} | Nuevo valor: \\n\");\n                            Console.WriteLine(mensajeTelefonoIncorrecto);\n                            telefonoContacto = Console.ReadLine();\n                            telefonoValido = Regex.IsMatch(telefonoContacto, regexTelefono);\n                            mensajeTelefonoIncorrecto = \"Introduce un nmero de telfono vlido!: \";\n\n                        } while (!telefonoValido);\n\n                        listaDeContactos.Where(c => c.idContacto == idUsuario).FirstOrDefault().numeroTelefono = telefonoContacto;\n\n                        Console.WriteLine(\"Numero de telfono modificado correctamente.\");\n                    }\n                    else\n                    {\n                        Console.WriteLine(\"Introduce un campo correcto\");\n                    }\n\n                }\n                else\n                {\n                    Console.WriteLine(\"Id introducida no encontrada!\");\n                }\n\n            }\n            else\n            {\n                Console.WriteLine(\"La lista est vaca :(!\");\n            }\n            vaciarArchivo();\n            guardarContacto();\n            agendaDeContactos();\n\n        }\n\n\n        // Este mtodo aade contactos a nuestra lista\n        static void introducirContactos()\n        {\n            Console.WriteLine(\"Introduce el nombre de tu contacto: \");\n            string nombreContacto = Console.ReadLine();\n            string telefonoContacto;\n            bool numeroValido;\n\n            Console.WriteLine(\"Introduce el nmero de telfono de tu contacto\");\n\n            string mensaje = \"\";\n            do\n            {\n                Console.WriteLine(mensaje);\n                telefonoContacto = Console.ReadLine();\n                numeroValido = Regex.IsMatch(telefonoContacto, regexTelefono);\n                mensaje = \"Por favor, introduce un nmero de telfono vlido: \";\n\n            } while (!numeroValido);\n\n            listaDeContactos.Add(new Contacto(nombreContacto, telefonoContacto));\n            Console.WriteLine($\"El contacto con el nombre {nombreContacto} y el nmero de telfono {telefonoContacto}  se ha introducido correctamente!\");\n            guardarContacto();\n            agendaDeContactos();\n\n        }\n\n        // Este mtodo todos los contactos que hemos aadidos\n        static void buscarContactos()\n        {\n            if (listaDeContactos.Count == 0)\n            {\n                Console.WriteLine(\"Lista de contactos vaca :(\");\n\n            }\n            else\n            {\n                Console.WriteLine(\"\\nLista de contactos: \\n\");\n                foreach (Contacto contacto in listaDeContactos)\n                {\n                    Console.WriteLine($\"Id: {contacto.idContacto} || Nombre: {contacto.nombre} | Nmero tlf: {contacto.numeroTelefono}\");\n                }\n            }\n            Console.WriteLine(\"\");\n            agendaDeContactos();\n        }\n\n\n        // Este mtodo guarda los contactos en un fichero de texto\n        static void guardarContacto()\n        {\n            using (StreamWriter file = new StreamWriter(rutaArchivoTxt))\n            {\n                foreach (Contacto contacto in listaDeContactos)\n                {\n                    file.WriteLine(contacto.ToString());\n                }\n            }\n\n        }\n        // Este mtodo borra el contenido del fichero de texto \n        static void vaciarArchivo()\n        {\n            using (StreamWriter file = new StreamWriter(rutaArchivoTxt))\n            {\n                // No escribir nada en el archivo\n            }\n        }\n\n        // Este mtodo los contactos del fichero de texto\n        static void leerContactos()\n        {\n            try\n            {\n                using (StreamReader reader = new StreamReader(rutaArchivoTxt))\n                {\n                    string linea;\n                    while ((linea = reader.ReadLine()) != null)\n                    {\n                        string[] partes = linea.Split(',');\n                        if (partes.Length == 2)\n                        {\n                            Contacto contacto = new Contacto(partes[0], partes[1]);\n                            listaDeContactos.Add(contacto);\n                        }\n                    }\n                }\n            }\n            catch (Exception)\n            {\n                Console.WriteLine(\"Error leyendo contactos del fichero\");\n            }\n        }\n    }\n\n}\nclass Alimento\n{\n    public string nombre;\n    public double precio;\n    public int calorias;\n}\n\nclass Contacto\n{\n    public static int idAutoIncrementable;\n    public string nombre;\n    public string numeroTelefono;\n    public int idContacto;\n\n    public Contacto(string nombre, string numeroTelefono)\n    {\n        idContacto = idAutoIncrementable;\n        this.nombre = nombre;\n        this.numeroTelefono = numeroTelefono;\n        idAutoIncrementable++;\n    }\n    public override string ToString()\n    {\n        return $\"{nombre},{numeroTelefono}\";\n    }\n}\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/c#/victormugo.cs",
    "content": "﻿using System.Numerics;\n\nnamespace _03_estructuras\n{\n    internal class Program\n    {\n        public static Dictionary<string, int> myContacts = new Dictionary<string, int>();\n        \n        static void Main(string[] args)\n        {\n            /*\n              * EJERCICIO:\n              * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto\n              *   en tu lenguaje.\n              * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n              *\n              * DIFICULTAD EXTRA (opcional):\n              * Crea una agenda de contactos por terminal.\n              * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n              *   y eliminación de contactos.\n              * - Cada contacto debe tener un nombre y un número de teléfono.\n              * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n              *   y a continuación los datos necesarios para llevarla a cabo.\n              * - El programa no puede dejar introducir números de teléfono no númericos y con más\n              *   de 11 dígitos (o el número de dígitos que quieras).\n              * - También se debe proponer una operación de finalización del programa.\n              */\n\n\n            // ------------------ ESTRUCTURAS DE DATOS\n            // ------------------ Queue\n            Console.WriteLine(\" ------------------ QUEUE ------------- \");\n            var queue = new Queue<Contact>();\n\n            Console.WriteLine(\" --- Insertar en la cola\");\n            // Insertar en la cola\n            queue.Enqueue(new Contact(\"Juan\", 65959494));\n            queue.Enqueue(new Contact(\"Maria\", 4949594));\n            queue.Enqueue(new Contact(\"Xavi\", 9394399));\n            queue.Enqueue(new Contact(\"Susan\", 34935959));\n            queue.Enqueue(new Contact(\"Ricardo\", 34934599));\n            foreach (var contact in queue)\n            {\n                Console.WriteLine($\"Nombre: {contact.name}, Telefono: {contact.phoneNumber}\");\n            }\n\n            Console.WriteLine(\" --- Eliminar primer elemento de la cola\");\n            // Eliminar el primer elemento de la cola\n            queue.Dequeue();\n            foreach (var contact in queue)\n            {\n                Console.WriteLine($\"Nombre: {contact.name}, Telefono: {contact.phoneNumber}\");\n            }\n\n            Console.WriteLine(\" --- Ordenación\");\n            // Ordenación\n            queue.Order();\n\n            // Actualizar un elemento\n            Console.WriteLine(\" --- Actualizar un elemento de la cola\");\n            queue.Peek().name = \"Manuel\";\n            foreach (var contact in queue)\n            {\n                Console.WriteLine($\"Nombre: {contact.name}, Telefono: {contact.phoneNumber}\");\n            }\n\n            Console.WriteLine(\" --- Eliminar todos los elementos de la cola\");\n            // Borra todos los elementos\n            queue.Clear();\n            foreach (var contact in queue)\n            {\n                Console.WriteLine($\"Nombre: {contact.name}, Telefono: {contact.phoneNumber}\");\n            }\n\n\n\n\n\n            // ------------------ Array\n            Console.WriteLine(\"\\r\\n\\r\\n ------------------ ARRAY ------------- \");\n            Console.WriteLine(\" --- Insertar en array\");\n            // Insertar en el array\n            var contactsArray = new Contact[3];\n            contactsArray[0] = new Contact(\"Pedro\", 4969696);\n            contactsArray[1] = new Contact(\"Rodrigo\", 8695949);\n            contactsArray[2] = new Contact(\"Miriam\", 9359595);\n            foreach (var contact in contactsArray)\n            {\n                if (contact == default) continue;\n                Console.WriteLine($\"{contact.name} - {contact.phoneNumber}\");\n            }\n\n            Console.WriteLine(\" --- Ordenación del array\");\n            // Ordenación\n            contactsArray.Order();\n\n            // Actualizar un elemento\n            Console.WriteLine(\" --- Actualizar un elemento del array\");\n            contactsArray[1].name = \"Actualizado\";\n            foreach (var contact in contactsArray)\n            {\n                Console.WriteLine($\"Nombre: {contact.name}, Telefono: {contact.phoneNumber}\");\n            }\n\n\n\n\n            // ------------------ List\n            Console.WriteLine(\"\\r\\n\\r\\n ------------------ LIST ------------- \");\n            Console.WriteLine(\" --- Insertar en una list\");\n            // Insertar en el list\n            var contactList = new List<Contact>();\n            contactList.Add(new Contact(\"Pedro\", 4969696));\n            contactList.Add(new Contact(\"Marlo\", 5848438));\n            contactList.Add(new Contact(\"Susana\", 34838348));\n            foreach (var contact in contactList)\n            {\n                if (contact == default) continue;\n                Console.WriteLine($\"{contact.name} - {contact.phoneNumber}\");\n            }\n\n            // Cantidad total de elementos en la lista\n            Console.WriteLine($\"Contactos en la lista: {contactList.Count}\");\n\n            // Encontrar objetos por propiedades especificas\n            Console.WriteLine($\"Encuentra el teléfono del contacto Pedro: {contactList.Find(x => x?.name == \"Pedro\").phoneNumber}\");\n            foreach (var contact in contactList)\n            {\n                if (contact == default) continue;\n                Console.WriteLine($\"{contact.name} - {contact.phoneNumber}\");\n            }\n\n            // Actualizar un elemento\n            Console.WriteLine(\" --- Actualizar un elemento de la lista\");\n            contactList[0].phoneNumber = 2;\n            foreach (var contact in contactList)\n            {\n                Console.WriteLine($\"Nombre: {contact.name}, Telefono: {contact.phoneNumber}\");\n            }\n\n            Console.WriteLine(\" --- Ordenación de la lista\");\n            // Ordenación\n            contactList.Order();\n\n            Console.WriteLine(\" --- Eliminar todos los elementos de la lista\");\n            // Borra todos los elementos\n            contactList.Clear();\n            foreach (var contact in contactList)\n            {\n                Console.WriteLine($\"Nombre: {contact.name}, Telefono: {contact.phoneNumber}\");\n            }\n\n\n\n\n            // ------------------ Stack\n            Console.WriteLine(\"\\r\\n\\r\\n ------------------ STACK ------------- \");\n            Console.WriteLine(\" --- Insertar en una stack\");\n            // Insertar en el stack\n            var stackContact = new Stack<Contact>();\n            stackContact.Push(new Contact(\"Pedro\", 4969696));\n            stackContact.Push(new Contact(\"Maria\", 943943));\n            stackContact.Push(new Contact(\"Sandra\", 34835843));\n            stackContact.Push(new Contact(\"Georgina\", 2384848));\n            foreach (var contact in stackContact)\n            {\n                if (contact == default) continue;\n                Console.WriteLine($\"{contact.name} - {contact.phoneNumber}\");\n            }\n\n            // Pop para remover el último elemento que fue añadido a nuestro stack.\n            stackContact.Pop();\n\n            foreach (var contact in stackContact)\n            {\n                if (contact == default) continue;\n                Console.WriteLine($\"{contact.name} - {contact.phoneNumber}\");\n            }\n\n            // Peek para ver el ultimo elemento que añadimos.\n            Console.WriteLine(stackContact.Peek().name);\n\n\n            Console.WriteLine(\" --- Ordenación del stack\");\n            // Ordenación\n            stackContact.Order();\n\n            Console.WriteLine(\" --- Eliminar todos los elementos del stack\");\n            // Borra todos los elementos\n            stackContact.Clear();\n            foreach (var contact in stackContact)\n            {\n                Console.WriteLine($\"Nombre: {contact.name}, Telefono: {contact.phoneNumber}\");\n            }\n\n\n\n\n            // ------------------ Dictionary\n            Console.WriteLine(\"\\r\\n\\r\\n ------------------ DICTIONARY ------------- \");\n            Console.WriteLine(\"--- Detallado en el ejercicio\");\n\n\n            // ------------------ Crea una agenda de contactos por terminal\n            Console.WriteLine(\"\\r\\n\\r\\n ------------------ EXAMPLE ------------- \");\n            int option = 0;\n\n            do\n            {\n                Console.WriteLine($\"Seleccione una opción:\\r\\n\" +\n                    $\"1 - Buscar contacto\\r\\n\" +\n                    $\"2 - Insertar contacto\\r\\n\" +\n                    $\"3 - Actualizar contacto\\r\\n\" +\n                    $\"4 - Eliminar contacto\\r\\n\" +\n                    $\"5 - Salir\");\n\n                int.TryParse(Console.ReadLine(), out option);\n\n                switch (option)\n                {\n                    case 1:\n                        // Buscar contacto\n                        BuscarContacto();\n                        break;\n\n                    case 2:\n                        // Insertar contacto\n                        InsertarContacto();\n                        break;\n\n                    case 3:\n                        // Actualizar contacto\n                        ActualizarContacto();\n                        break;\n\n                    case 4:\n                        // Eliminar contacto\n                        EliminarContacto();\n                        break;\n\n                    case 5:\n                        // Salir\n                        option = 5;\n                        break;\n\n                    case 0:\n                    default:\n                        Console.WriteLine(\"Opción no disponible.\");\n                        Console.ReadKey();\n                        break;\n                }\n\n                Console.Clear();\n\n            } while (option != 5);\n        }\n\n\n        public static void ShowContacts()\n        {\n            try\n            {\n                Console.WriteLine(\"Lista de contactos:\");\n                foreach (KeyValuePair<string, int> kvp in myContacts)\n                {\n                    Console.WriteLine($\"{kvp.Key} - {kvp.Value}\");\n                }\n\n            }\n            catch (Exception ex)\n            {\n                Console.WriteLine(ex.ToString());\n            }\n        }\n\n        /// <summary>\n        /// Función para buscar contacto en la agenda\n        /// </summary>\n        public static void BuscarContacto()\n        {\n            try\n            {\n                if (myContacts.Count > 0)\n                {\n                    // Mostrar todos los contactos de la agenda\n                    ShowContacts();\n\n                    // Buscar el contacto en concreto\n                    Console.WriteLine(\"Introduzca el nombre del contacto:\");\n                    string name = Console.ReadLine();\n\n                    if (myContacts.TryGetValue(name, out var value))\n                    {\n                        Console.WriteLine($\"{name} - {value}\");\n                    }\n                    else\n                    {\n                        Console.WriteLine(\"Contacto no encontrado\");\n                        Console.ReadKey();\n                    }\n                } \n                else\n                {\n                    Console.WriteLine(\"No existen contactos en la agenda\");\n                    Console.ReadKey();\n                }\n\n            } catch(Exception e) { \n                Console.WriteLine(e.ToString());\n            }\n\n        }\n\n        /// <summary>\n        /// Función para insertar contacto en la agenda\n        /// </summary>\n        public static void InsertarContacto()\n        {\n            try\n            {\n                Console.WriteLine(\"Introduzca nombre del contacto:\");\n                string name = Console.ReadLine();\n\n                // Verificar si nombre (clave ya existe en el diccionario);\n                if (myContacts.TryGetValue(name, out var value))\n                {\n                    Console.WriteLine(\"Contacto ya existente\");\n                    Console.ReadKey();\n                }\n                else\n                {\n                    Console.WriteLine(\"Introduzca número de teléfono:\");\n                    int.TryParse(Console.ReadLine(), out int phoneNumber);\n\n                    double data = Math.Floor(Math.Log10(phoneNumber) + 1);\n\n                    if (data > 0 && data < 11)\n                    {\n                        myContacts.Add(name, phoneNumber);\n                    }\n                    else\n                    {\n                        Console.WriteLine(\"Número de teléfono incorrecto.\\r\\nDebe comprender entre 1 y 11 números\");\n                        Console.ReadKey();\n                    }\n                }  \n            }\n\n            catch (Exception e)\n            {\n                Console.WriteLine(e.ToString());\n            }\n        }\n\n        /// <summary>\n        /// Método para actualizar un contacto de la agenda\n        /// </summary>\n        public static void ActualizarContacto()\n        {\n            try\n            {\n                if (myContacts.Count > 0)\n                {\n                    // Mostrar listado de contactos\n                    ShowContacts();\n\n                    // Buscar el contacto en concreto\n                    Console.WriteLine(\"Introduzca el nombre del contacto:\");\n                    string name = Console.ReadLine();\n\n                    if (myContacts.TryGetValue(name, out var value))\n                    {\n                        Console.WriteLine(\"Introduzca el nuevo número de teléfono:\");\n                        int.TryParse(Console.ReadLine(), out int phoneNumber);\n\n                        double data = Math.Floor(Math.Log10(phoneNumber) + 1);\n\n                        if (data > 0 && data < 11)\n                        {\n                            myContacts[name] = phoneNumber;\n                        }\n                        else\n                        {\n                            Console.WriteLine(\"Número de teléfono incorrecto.\\r\\nDebe comprender entre 1 y 11 números\");\n                            Console.ReadKey();\n                        }\n                    }\n                    else\n                    {\n                        Console.WriteLine(\"Contacto no encontrado\");\n                        Console.ReadKey();\n                    }\n                }\n                else\n                {\n                    Console.WriteLine(\"No existen contactos en la agenda\");\n                    Console.ReadKey();\n                }\n            }\n            catch (Exception e)\n            {\n                Console.WriteLine(e.ToString());\n            }\n        }\n\n        /// <summary>\n        /// Método para eliminar un contacto de la agenda\n        /// </summary>\n        public static void EliminarContacto()\n        {\n            try\n            {\n                if (myContacts.Count > 0)\n                {\n                    // Mostrar listado de contactos\n                    ShowContacts();\n\n\n                    // Buscar el contacto en concreto\n                    Console.WriteLine(\"Introduzca el nombre del contacto:\");\n                    string name = Console.ReadLine();\n\n                    if (myContacts.TryGetValue(name, out var value))\n                    {\n                        Console.WriteLine($\"{name} - {value}\");\n                        myContacts.Remove(name);\n                    }\n                    else\n                    {\n                        Console.WriteLine(\"Contacto no encontrado\");\n                        Console.ReadKey();\n                    }\n                }\n                else\n                {\n                    Console.WriteLine(\"No existen contactos en la agenda\");\n                    Console.ReadKey();\n                }\n            }\n            catch (Exception e)\n            {\n                Console.WriteLine(e.ToString());\n            }\n        }\n    }\n\n    public class Contact\n    {\n        public string name;\n        public int phoneNumber;\n\n        public Contact(string name, int phoneNumber)\n        {\n            this.name = name;\n            this.phoneNumber = phoneNumber;\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/c++/CesarCarmona30.cpp",
    "content": "#include <iostream>\n#include <vector>\n#include <set>\n#include <map>\n#include <tuple>\n#include <algorithm>\n\nusing namespace std;\n/*\n  ESTRUCTURAS DE DATOS\n*/\n\n// Arrays\n\n/*\n  Arreglo de enteros inicializado con valores específicos.\n  Los arreglos son estructuras estáticas que no pueden modificarse en tiempo de ejecución.\n  No tienen métodos o funciones nativas que permitan insertar, borrar o ordenar elementos.\n  Sin embargo, podemos actualizar elementos individualmente.\n*/\n\nint my_array[] = {0, 5, 6, 2, 7, 2, 6 ,8, 9};\n\ntemplate <typename Structure>\nvoid printStruct(const Structure& struc) {\n  for (const auto& element : struc) {\n    cout << element << \" \";\n  }\n  cout << endl;\n}\n\ntemplate <typename... Ts>\nvoid printStruct(const tuple<Ts...>& tuple) {\n  apply([](const auto&... args) {\n    ((cout << args << \" \"), ... );\n  }, tuple);\n  cout << endl;\n}\n\ntemplate<typename K, typename V>\nvoid printStruct(const map<K, V>& map) {\n  for (const auto& pair : map) {\n    cout << pair.first << \": \" << pair.second << endl;\n  }\n  cout << endl;\n}\n\n\n/*\n  Arreglos inicializados en su declarción\n  Si no se pasan la cantidad completa\n  de elementos, los demas se inicializan por defecto\n\n   int my_array2[5] = {1, 2, 3}; => {1, 2, 3, 0, 0};\n   char my_arr[5] = {'a', 'b', 'c'}; => {'a', 'b', 'c', '', ''};\n*/ \n\nmap<string, string> agenda;\n\n\nvoid searchContact(string contact_name) {\n  if (agenda.find(contact_name) != agenda.end()) {\n    cout << \"Contacto: \" << agenda.find(contact_name)->first << \" - \" << agenda.find(contact_name)->second << endl;\n  } else {\n    cout << \"Contacto no encontrado.\" << endl;\n  }\n}\n\nvoid newContact(string contact_name, string phone_number) {\n  if (phone_number.size() != 10) {\n    cout << \"Numero de telefono invalido, debe tener 10 digitos.\" << endl;\n    return;\n  }\n  agenda[contact_name] = phone_number;\n  cout << \"Contacto agregado correctamente\" << endl;\n}\n\nvoid updateContact(string contact_name, string new_number) {\n  if (agenda.find(contact_name) != agenda.end()) {\n    agenda.erase(contact_name);\n    newContact(contact_name, new_number);\n    cout << \"Contacto actualizado correctamente.\" << endl;\n  } else {\n    cout << \"Contacto no encontrado.\" << endl;\n  }\n\n}\n\nvoid deleteContact(string contact_name) {\n  if (agenda.find(contact_name) != agenda.end()) {\n    agenda.erase(contact_name);\n    cout << \"Contacto eliminado correctamente.\" << endl;\n  } else {\n    cout << \"Contacto no encontrado.\" << endl;\n  }\n}\n\nvoid showContacts() {\n  printStruct(agenda);\n}\n\nvoid menu() {\n  cout << \"--AGENDA--\" << endl;\n  bool cont = true;\n  do {\n    string name, phone;\n    int opcion = 0;\n    cout << \"1.- BUSCAR CONTACTO\" << endl;\n    cout << \"2.- NUEVO CONTACTO\" << endl;\n    cout << \"3.- ACTUALIZAR CONTACTO\" << endl;\n    cout << \"4.- ELIMINAR CONTACTO \" << endl;\n    cout << \"5.- LISTAR CONTACTOS \" << endl;\n    cout << \"6.- SALIR \" << endl;\n    cout << \"Seleccione una opcion: \";\n    cin >> opcion;\n    switch (opcion){\n      case 1:\n        cout << \"Nombre del contacto a buscar: \";\n        cin >> name;\n        searchContact(name);\n        break;\n      case 2:\n        cout << \"Nombre del nuevo contacto: \";\n        cin >> name;\n        cout << \"\\nNumero de telefono: \";\n        cin >> phone;\n        newContact(name, phone);\n        break;\n      case 3:\n        cout << \"Nombre del contacto a actualizar: \";\n        cin >> name;\n        cout << \"\\nNuevo numero de telefono: \";\n        cin >> phone;\n        updateContact(name, phone);\n        break;\n      case 4:\n        cout << \"Nombre del contacto a eliminar: \";\n        cin >> name;\n        deleteContact(name);\n        break;\n      case 5:\n        cout << \"Lista de contactos: \" << endl;\n        showContacts();\n        break;\n      case 6:\n        cont = false;\n        cout << \"Hasta luego\" << endl;\n        break;      \n      default:\n        cout << \"Opcion no valida, intentelo de nuevo\" << endl;\n        break;\n    }\n  } while (cont);\n}\n\n\nint main() {\n  /*\n    Vectores: Estructuras de un solo tipo de dato\n    que pueden cambiar dinámicamente en tiempo de \n    ejecución\n  */\n  cout << \"VECTOR: \" << endl;\n  vector<int> my_vector = {1, 3, 5, 74, 21, 12};\n  printStruct(my_vector);\n  // Inserción al final\n  my_vector.push_back(43); // {1, 3, 5, 74, 21, 12, 43}\n  printStruct(my_vector);\n  // Inserción 5 posiciones despues del primer elemento (indice 5)\n  my_vector.insert(my_vector.begin() + 5, 10);  // {1, 3, 5, 74, 21, 10, 12, 43}\n  printStruct(my_vector);\n  // Eliminación del último elemento\n  my_vector.pop_back();  // {1, 3, 5, 74, 21, 10, 12}\n  printStruct(my_vector);\n  // Eliminación del elemento con índice 5 (vector original)\n  my_vector.erase(my_vector.begin() + 5);   // {1, 3, 5, 74, 21, 12}\n  printStruct(my_vector);\n  // Eliminación del índice 2 al 4 \n  my_vector.erase(my_vector.begin() + 2, my_vector.begin() + 4);   // {1, 3, 10, 12}\n  printStruct(my_vector);\n  // Ordenamiento, menor a mayor\n  sort(my_vector.begin(), my_vector.end());\n  printStruct(my_vector);\n  // Ordenamiento mayor a menor\n  sort(my_vector.begin(), my_vector.end(), greater<int>());\n  printStruct(my_vector);\n  // Actualización \n  my_vector[3] = 5;\n  printStruct(my_vector);\n  sort(my_vector.begin(), my_vector.end());\n  printStruct(my_vector);\n  /*\n    Sets: Estructuras de un solo tipo\n    de dato, únicos, que no permiten duplicados y pueden \n    cambiar de tamaño dinámicamente en tiempo de ejecución.\n    -No se pueden ordenar de otro modo que el establecido\n    -No se pueden actualizar los datos\n  */ \n  cout << \"\\nSET: \" << endl; \n  set<int> my_set = {1, 23, 8, 3, 6};\n  printStruct(my_set);\n  // Insercion al final\n  my_set.insert(7);\n  printStruct(my_set);\n  my_set.insert(5);\n  my_set.insert(6); // No se inserta\n  printStruct(my_set);\n  // Eliminación del elemento con valor 5\n  my_set.erase(5);\n  printStruct(my_set);\n  // Eliminación de todo el set\n  my_set.clear();\n  printStruct(my_set);\n  /*\n    Tuples: Estructuras de múltiples tipos de datos inmutables,\n    por lo tanto no hay manera de insertar, borrar, actualizar\n    y ordenar elementos.\n  */ \n  cout << \"\\nTUPLE: \" << endl; \n  tuple<int, int, int> my_tuple = {2, 4, 6};\n  printStruct(my_tuple);\n  tuple<int, string, char> my_tuple2 = {19, \"Cesar\", 'H'};\n  printStruct(my_tuple2);\n\n  /*\n    Maps: Estructuras de pares clave-valor con claves o identificadores\n    únicos, ordenados por defecto\n  */\n  cout << \"\\nMAP: \" << endl; \n  map<int, string> my_map = {{1, \"One\"}, {2, \"Two\"}, {5, \"Five\"}, {8, \"Eigth\"}};\n  //Inserción\n  my_map.insert({7, \"Seven\"});\n  my_map[6] = \"Seis\";\n  my_map.insert({5, \"Cinco\"}); // No se inserta\n  printStruct(my_map);\n  // Eliminación, se hace por el identificador o clave\n  my_map.erase(6);\n  printStruct(my_map);\n  // Actualización\n  my_map[8] = \"Eight\";\n  printStruct(my_map);\n\n  cout << endl;\n\n  menu();\n  return 0;\n}"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/c++/Fravelz.cpp",
    "content": "//******************************************************************************\n//* Nota: Para el Proyecto de Dificultad Extra se utilizara librerias\n//* para mejor facilidad y no tener que crear cada funcionalidad desde\n//* cero, y seran las siguientes.\n\n#include <iostream> // Entrada y Salida de datos.\n#include <string>   // Tipo de dato string. (de la Libreria estandar C++)\n#include <vector>   // Tipo de dato Vector. (de la Libreria estandar C++)\n\n\n//******************************************************************************\n\nusing namespace std;\n\n//* Declaracion de funciones para el ejercicio Extra\n\nstruct Contactos {\n    string nombre;\n    string celular;\n    string correo;\n};\n\nvoid formatear (  \n    char caracter, string palabras, int orientacion=0, \n    bool vacio=true, int espacio = 44\n);\n\nint buscar_contacto(string buscar, vector<Contactos> vect);\n\n\n// ********************** #03 - Estructuras de datos ********************** //\n\n/*\n * Las estructuras de datos basicas Primitivas de C++ son:\n *  > int, float, double, char, bool (Tipos básicos) (Estructura de 1 solo dato)\n *  > Arrays (Arreglos estáticos)\n *  > struct (Agrupa distintos tipos de datos)\n *  > pointers (Punteros, es para trabajar con direcciones de memoria) (1 dato)\n *  > enum (Enumeraciones)\n * \n * \n * Las anteriores son las estructuras Basicas Primitivas, de los anteriores\n * surgen estructuras de datos, de la biblioteca estandar de C++,\n * es decir surgen mas estructuras de datos pero tienes que importarlas,\n * segun la que nesesites. (son aproximadamente mas de 14 bibliotecas\n * estandar con estructuras de datos diferentes).\n * \n * Los siguientes son estructuras de datos Primitivas del lenguaje que no se\n * importan de ninguna biblioteca en las que se pueden almacenar varios datos\n * pero ninguna de ellas tienen funciones propias para utilizar operaciones de \n * inserción, borrado, actualización y ordenación. (Eso toca crearlas uno mismo\n * o implementando algun tipo de datos de una libreria estandar)\n * \n * Nota: Todo esto es asi para usar solo lo que requiere el programa y poder \n * tener una buena obtimizacion del codigo.\n*/\n\n\n\nint main() {\n    // ****************************** Arreglos ****************************** //\n    // Se define el tamaño entre [] y la lista de datos entre {}\n    int array[3] = {1, 2, 3};\n\n    // Tambien se puedde definir y luego colocar valores 1 por 1\n    int array2[3];\n    \n    array2[0] = 1; // Los valores para llamar cada parte de la lista empiezan \n    array2[1] = 2; // con cero.\n    array2[2] = 3;\n\n    // Los arreglos son lista de la forma {1, 2, 3, ...}\n\n    // *********************** Arreglos 2 Dimensiones *********************** //\n    \n    /* \n     * Similares al arreglo pero son de la forma:\n     * {\n     *      {1, 2, 3},\n     *      {4, 5, 6},\n     *      {7, 8, 9},\n     * }\n     * \n     * Practicamente un arreglo con arreglos adentro.\n    */\n\n    int array3[3][2] = {{1,2}, {3,4}, {5, 6}};\n    // Se debe indicar tambien el tamaño de los arrglos del interior.\n\n\n    // ******************************* String ******************************* //\n    // El string es un arreglo que utiliza el tipo de dato char.\n    \n    char texto[11] = \"Hola Mundo\";\n    \n    // Normalmente se importa <string> y se utiliza std::string porque ofrece\n    // automaticamente muchas facilidades que para un arreglo tipo char, \n    // no ofrece, pero tocaria importar de la biblioteca estandar.\n    // Normalmente se utiliza mucho las bibliotecas estandar para cualquier cosa\n    // en el codigo (Y muchas veces es lo recomendado).\n    \n    // ******************************* Struct ******************************* //\n    // Se utiliza para agrupar varias variables de diferentes datos \n    // Relacionadas entre si.\n\n    struct Persona {\n        char nombre[50];\n        int edad;\n        float estatura;\n    };\n\n    int i = 0;\n    struct Persona yo;\n\n    // Como el string es array entonces toca asi, o importando la libreria\n    // <cstring> y utilizando la siguiente linea  strcpy(yo.nombre, \"Fravelz\");\n\n    for (char letter : \"Fravelz\") { \n        yo.nombre[i] = letter;\n        i++;\n    }\n\n    yo.edad = 99;\n    yo.estatura = 1.72;\n\n    // ************************** Enum (Enumeraciones) ********************** //\n    // Enumera las variables que posee, con numeros enteros, se puede utilizar\n    // para retornar estados de una app o programa, etc.\n\n    enum sistema {\n        activo,   // El valor es: 0\n        inactivo, // 1\n        hackeado  // 2\n    };\n\n    cout << activo << '\\n'; \n\n    // Se cambia los valores numericos poe defecto\n    enum CodigoError {\n        OK = 0,\n        NotFound = 404,\n        ServerError = 500\n    };\n\n    cout << NotFound << '\\n';\n\n    // Se Fuerza a utilizar un identificador para evitar confucciones en codigo.\n\n    enum class ajedrez { // :v\n        arfil = 3,\n        caballo = 3,\n        torre = 11092001, \n        dama = 9,\n        peon = 1\n    };\n\n    // Para imprimir el numero toca asi porque son tipos fuertemente tipados.\n    // static_cast<int> con esta linea. \n\n    cout << static_cast<int>(ajedrez::torre) << '\\n';\n\n    // ********************* Ejercicio Dificultad Extra ********************* //\n    \n    // cout <<  búsqueda, inserción, actualización y eliminación de contactos.\n\n    // cout ;\n\n    //* Bueno, con la funcion anterior aqui digito la informacion \n    //* para formatear la salida del texto.\n    bool salir = false;\n    char c = '*', opc;\n\n    vector<Contactos> agenda;\n\n    while (!salir){\n        formatear(c, \"\", 0, false);\n        formatear(c, \"Agenda de contactos\", 0, false);\n        formatear(c, \"\", 0, false);\n        \n        formatear(c, \"1. Buscar Contacto.\", 1);\n        formatear(c, \"2. Agregar Contacto.\", 1);\n        formatear(c, \"3. Actualizar Contacto.\", 1);\n        formatear(c, \"4. Eliminar Contactos.\", 1);\n        formatear(c, \"5. Salir.\", 1);\n        formatear(c, \"\", 0, false);\n        \n        cout << c << \" # \"; \n        cin >> opc;\n        cin.ignore();\n\n        string buscar, dato_opc, data_actualizar;\n        bool correct = false;\n        int buscado;\n\n        switch(opc) {\n            case '1': {\n                string buscar;\n                formatear(c, \"Digite el nombre del contacto a buscar:\", 1);\n                cout << c << \" > \";\n                getline(cin, buscar);\n\n                formatear(c, \"\", 0);\n                int buscado = buscar_contacto(buscar, agenda);\n\n                if (buscado != -1) {\n                    formatear(c, \"Nombre: \" + agenda[buscado].nombre, 1);\n                    formatear(c, \"Celular: \" + agenda[buscado].celular, 1);\n                    formatear(c, \"Correo: \" + agenda[buscado].correo, 1);\n\n                } else {\n                    formatear(c, \"El contacto que buscas NO Existe.\", 0);\n                };\n\n                formatear(c, \"\", 0, false);\n                break;\n            }\n\n            case '2': {\n                Contactos contacto;\n                cout << c << \" > Digite el nombre: \";\n                getline(cin, contacto.nombre);\n                \n                cout << c << \" > Digite el celular: \";\n                getline(cin, contacto.celular);\n                \n                cout << c << \" > Digite el correo: \";\n                getline(cin, contacto.correo);\n\n                agenda.push_back(contacto);\n                            \n                formatear(c, \"\", 0);\n                formatear(c, \"Nuevo Contacto Creado :)\", 0);\n                formatear(c, \"\", 0, false);\n                break;\n            }\n\n            case '3': \n                formatear(c, \"D. el nombre del contacto a Actualizar:\", 1);\n                cout << c << \" > \";\n                getline(cin, buscar);\n\n                formatear(c, \"\", 0);                \n                buscado = buscar_contacto(buscar, agenda);\n\n                if (buscado != -1) {\n                    do {\n                        formatear(c, \"Cual dato quieres actualizar:\", 1);\n                        cout << c << \" (nombre=0, celular=1, correo=2) > \";\n                        getline(cin, dato_opc);\n                        \n                        if (dato_opc == \"0\") {\n                            cout << c << \" Que nuevo Nombre deseas: \";\n                            getline(cin, data_actualizar);\n                            agenda[buscado].nombre = data_actualizar;\n                            correct = true;\n                            \n                        } else if (dato_opc == \"1\") {\n                            cout << c << \" Que nuevo # Celular deseas: \";\n                            getline(cin, data_actualizar);\n                            agenda[buscado].celular = data_actualizar;\n                            correct = true;\n                            \n                        } else if (dato_opc == \"2\") {\n                            cout << c << \" Que nuevo Correo deseas: \";\n                            getline(cin, data_actualizar);\n                            agenda[buscado].correo = data_actualizar;\n                            correct = true;\n                            \n                        } else {\n                            formatear(c, \"Error: Intentelo de nuevo.\", 1);\n                        }\n                    } while (!correct);\n    \n                    formatear(c, \"\", 0);                \n                    \n                    formatear(c, \"Nombre: \" + agenda[buscado].nombre, 1);\n                    formatear(c, \"Celular: \" + agenda[buscado].celular, 1);\n                    formatear(c, \"Correo: \" + agenda[buscado].correo, 1);\n\n                } else {\n                    formatear(c, \"El contacto que buscas NO Existe.\", 0);\n                };\n\n                formatear(c, \"\", 0, false);\n                break;\n\n            case '4': {\n                formatear(c, \"D. el nombre del contacto a Eliminar:\", 1);\n                cout << c << \" > \";\n                getline(cin, buscar);\n\n                formatear(c, \"\", 0);                \n                buscado = buscar_contacto(buscar, agenda);\n\n                if (buscado != -1) {    \n                    formatear(c, \"\", 0);                \n                    \n                    formatear(c, \"Nombre: \" + agenda[buscado].nombre, 1);\n                    formatear(c, \"Celular: \" + agenda[buscado].celular, 1);\n                    formatear(c, \"Correo: \" + agenda[buscado].correo, 1);\n                    \n                    formatear(c, \"\", 0);                \n                    formatear(c, \"Contacto eliminado :(\", 0);\n\n                    agenda.erase(agenda.begin() + buscado);\n                    formatear(c, \"\", 0, false);\n\n\n                } else {\n                    formatear(c, \"El contacto NO Existe.\", 0);\n                };\n\n                break;\n            }\n            \n            case '5': \n                salir = true; break;\n\n            default: {\n                \n                formatear(c, \"\", 0);\n                formatear(c, \"Nuevo Contacto Creado :)\", 0);\n                formatear(c, \"\", 0, false);\n            }\n        }\n        cout << '\\n';\n    }\n\n    formatear(c, \"\", 0, false);\n    formatear(c, \"Cordial Saludo!\", 2);\n    formatear(c, \"\", 0, false);\n        \n    \n    return 0;\n}\n\n// **************** Funciones de Ejercicio Dificultad Extra  **************** //\n\n// Funcion encargada del formateo del texto :)\n// Hiba a utilizar la Libreria <iomanip> pero no me funciono.\nvoid formatear ( \n    char caracter, string palabras, int orientacion, \n    bool vacio, int espacio\n) {\n    int longitud = palabras.length(); // abc = 3\n    int izquierda = 0, derecha = 0;   // |*Izquierda + *Derecha|\n\n    int relleno = espacio - longitud; // |***| - a(1) = |**| \n    if (palabras != \"\") relleno -= 2;            // |***a***| -2 = |** a **|\n\n    if (orientacion == 0) { // * Orientacion Centrada\n        izquierda = relleno / 2; \n        derecha = relleno - izquierda;\n        \n        for (int i = 0; i < izquierda; ++i) {\n            if (vacio) {\n                cout << ((i == 0) ? caracter : ' ');\n\n            } else { cout << caracter; }\n        }\n\n        string espacio_1 = (palabras != \"\") ? \" \" : \"\";\n        cout << espacio_1 << palabras << espacio_1;\n\n        for (int i = 0; i < derecha; ++i) {\n            if (vacio) {\n                cout << ((i != derecha-1) ? ' ' : caracter);\n\n            } else { cout << caracter; }\n        };\n\n\n    } else if (orientacion == 1) { // * Orientacion Izquierda\n        izquierda = 0;\n        derecha = relleno-1;\n\n        for (int i = 0; i < izquierda; ++i) {\n            if (vacio) {\n                cout << ((i == 0) ? caracter : ' ');\n\n            } else { cout << caracter; }\n        }\n\n        string espacio_1 = (palabras != \"\") ? \" \" : \"\";\n        cout << caracter << espacio_1 << palabras << espacio_1;\n\n        for (int i = 0; i < derecha; ++i) {\n            if (vacio) {\n                cout << ((i == derecha-1) ? caracter : ' ');\n\n            } else { cout << caracter; }\n        };\n\n\n    } else if (orientacion == 2) { // * Orientacion Derecha\n        izquierda = relleno-1;\n        derecha = 0;\n\n        for (int i = 0; i < izquierda; ++i) {\n            if (vacio) {\n                cout << ((i == 0) ? caracter : ' ');\n\n            } else { cout << caracter; }\n        };\n        string espacio_1 = (palabras != \"\") ? \" \" : \"\";\n\n        cout << espacio_1 << palabras << espacio_1 << caracter;\n        for (int i = 0; i < derecha; ++i) {\n            if (vacio) {\n                cout << ((i == 0) ? caracter : ' ');\n\n            } else { cout << caracter; }\n        };\n    }\n    cout << '\\n';\n};\n\nint buscar_contacto(string buscar, vector<Contactos> vect){\n    for (int x = 0; x < vect.size(); x++) {\n        if (buscar == vect[x].nombre) {\n            return x;\n        }\n    }\n    return -1;\n}\n\n// ****** Demostraccion de la Consola del Ejercicio Dificultad Extra  ****** //\n\n/*\n TODO: Se puede obtimizar el codigo pero uf, es mucho, mejor voy a continuar \n Todo: mejor....\n\n TODO: Muestra por Consola del programa:\n\n********************************************\n*********** Agenda de contactos ************\n********************************************\n* 1. Buscar Contacto.                      *\n* 2. Agregar Contacto.                     *\n* 3. Actualizar Contacto.                  *\n* 4. Eliminar Contactos.                   *\n* 5. Salir.                                *\n********************************************\n* # 2\n* > Digite el nombre: Xi\n* > Digite el celular: 123 456 78 90\n* > Digite el correo: correo@hotmail.com\n*                                          *\n*         Nuevo Contacto Creado :)         *\n********************************************\n\n********************************************\n*********** Agenda de contactos ************\n********************************************\n* 1. Buscar Contacto.                      *\n* 2. Agregar Contacto.                     *\n* 3. Actualizar Contacto.                  *\n* 4. Eliminar Contactos.                   *\n* 5. Salir.                                *\n********************************************\n* # 1\n* > Xi\n*                                          *\n* Nombre: Xi                               *\n* Celular: 123 456 78 90                   *\n* Correo: correo@hotmail.com               *\n********************************************\n\n********************************************\n*********** Agenda de contactos ************\n********************************************\n* 1. Buscar Contacto.                      *\n* 2. Agregar Contacto.                     *\n* 3. Actualizar Contacto.                  *\n* 4. Eliminar Contactos.                   *\n* 5. Salir.                                *\n********************************************\n* # 3\n* D. el nombre del contacto a Actualizar:  *\n* > Xi\n*                                          *\n* Cual dato quieres actualizar:            *\n* (nombre=0, celular=1, correo=2) > 0\n* Que nuevo Nombre deseas: FV\n*                                          *\n* Nombre: FV                               *\n* Celular: 123 456 78 90                   *\n* Correo: correo@hotmail.com               *\n********************************************\n\n********************************************\n*********** Agenda de contactos ************\n********************************************\n* 1. Buscar Contacto.                      *\n* 2. Agregar Contacto.                     *\n* 3. Actualizar Contacto.                  *\n* 4. Eliminar Contactos.                   *\n* 5. Salir.                                *\n********************************************\n* # 4\n* D. el nombre del contacto a Eliminar:    *\n* > FV\n*                                          *\n*                                          *\n* Nombre: FV                               *\n* Celular: 123 456 78 90                   *\n* Correo: correo@hotmail.com               *\n*                                          *\n*          Contacto eliminado :(           *\n********************************************\n\n********************************************\n*********** Agenda de contactos ************\n********************************************\n* 1. Buscar Contacto.                      *\n* 2. Agregar Contacto.                     *\n* 3. Actualizar Contacto.                  *\n* 4. Eliminar Contactos.                   *\n* 5. Salir.                                *\n********************************************\n\n********************************************\n*********** Agenda de contactos ************\n********************************************\n* 1. Buscar Contacto.                      *\n* 2. Agregar Contacto.                     *\n* 3. Actualizar Contacto.                  *\n* 4. Eliminar Contactos.                   *\n* 5. Salir.                                *\n********************************************\n* # 1\n* Digite el nombre del contacto a buscar:  *\n* > FV\n*                                          *\n*    El contacto que buscas NO Existe.     *\n********************************************\n\n********************************************\n*********** Agenda de contactos ************\n********************************************\n* 1. Buscar Contacto.                      *\n* 2. Agregar Contacto.                     *\n* 3. Actualizar Contacto.                  *\n* 4. Eliminar Contactos.                   *\n* 5. Salir.                                *\n********************************************\n* # 5\n\n********************************************\n*                          Cordial Saludo! *\n********************************************\n\n\n? NOTA: Los datos recibidos no son verificados por el programa, es\n? decir si escribes un numero de celular de solo letras lo aceptara,\n? y el programa se puede obtimizar, algun dia lo hare :)\n*/\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/c++/RoniPG.cpp",
    "content": "// @RoniPG\n\n#include <iostream>\n#include <array>\n#include<stack>\n#include<queue>\n#include<map>\n\nusing namespace std;\n\nint main() {\n\n\t//Arrays\n\n\t//Arrays estaticos\n\n\tint numeros[] = { 1, 2, 3, 4, 5 }; // Instanciamos con variables asignadas\n\tint numeros2[5]; // Instaciamos con cantidad de variables\n\n\t// Acceder y modificar datos del array\n\n\tnumeros2[0] = 1;\n\n\tcout << (numeros2[0] = 1) << endl; // Asignamos el valor 1 en la posicion 0\n\tcout << (numeros2[1] = 2) << endl; // Asignamos el valor 2 en la posicion 1\n\tcout << \"Valor de la primera posicion en el array numeros: \" << numeros[0]\n\t\t\t<< endl; // Asignamos el valor 1 en la posicion 0\n\tcout << \"Valor de la primera posicion en el array numeros: \";\n\tcout << (numeros[0] = 6) << endl; // Asignamos el valor 6 en la posicion 0\n\tfor (int i : numeros) { // ---> Foreach\n\t\tcout << i << \",\";\n\t}\n\tcout << \"\" << endl;\n\tfor (int i = 0; i < 5; ++i) { // No hay una funcion que devuelva el tama├▒o del arrray\n\t\tcout << numeros[i] << \",\";\n\t}\n\tcout << \"\" << endl;\n\n\t//Ordenar\n\n\t/* No existe un metodo que ordene automaticamente el array como en java.\n\t * Pero podemos implementar funciones que realizen esta funcion.\n\t * Disponemos de varias funciones com podrian ser: Burbuja, Quicksort, entre otros.\n\t */\n\n\tnumeros[0] = 3;\n\tnumeros[1] = 1;\n\tnumeros[2] = 5;\n\tnumeros[3] = 2;\n\tnumeros[4] = 4;\n\n\tfor (int i : numeros) {\n\t\tcout << i << \",\";\n\t}\n\tcout << \"\" << endl;\n\n\t//Funcion burbuja\n\n\tfor (int i = 0; i < 5; ++i) { // --> Hay que indicar el tama├▒o del array\n\t\tfor (int j = i + 1; j < 5; ++j) {\n\t\t\tif (numeros[i] > numeros[j]) { // --> Con el signo elegimos el orden, si de mayor a menor (<) o de menor a mayour (>).\n\t\t\t\tint aux = numeros[i];\n\t\t\t\tnumeros[i] = numeros[j];\n\t\t\t\tnumeros[j] = aux;\n\t\t\t}\n\t\t}\n\t}\n\tfor (int i : numeros) {\n\t\tcout << i << \",\";\n\t}\n\tcout << endl;\n\n\t//Estructura (struct)\n\n\t/* En una estructura podemos guardar varios tipos de datos.\n\t * Cada variable que creemos tendra los mismos tipos de datos que la estrucutura\n\t */\n\n\tstruct Persona {\n\t\tstring nombre;\n\t\tint edad;\n\t};\n\n\t//Insercion datos\n\n\tPersona persona1 = { \"Pedro\", 47 };\n\tPersona persona2 = { \"Alberto\", 34 };\n\n\tcout << persona1.nombre << \"\\t\" << persona1.edad << endl;\n\tcout << persona2.nombre << \"\\t\" << persona2.edad << endl;\n\n\t//Borrar\n\n\t/* Para borrar podemos dejar sus datos vacios\n\t * La variable creada no se podra borrar\n\t *\n\t * Ejemplo\n\t *\n\t */persona2 = { }; // --> Valor acutal 0\n\tcout << persona2.nombre << endl;\n\tcout << persona2.edad << endl;\n\n\t//Actualizacion\n\n\t/*Para actualizar podemos indicar la variable y cambiarle los datos\n\t * La variable sera sustituida por los nuevos datos o creada si no existe\n\t *\n\t * Ejemplo\n\t *\n\t */persona2 = { \"Alberto\", 34 };\n\tcout << persona2.nombre << endl;\n\tcout << persona2.edad << endl;\n\n\t/* Ordenacion\n\t * Al ser una esctrucura que se declara en variables la manera de ordenarlo seria\n\t * declarar las variables dentro de un array y luego aplicarle algun metodo de ordenacion\n\t */\n\n\t//Pilas(stack)\n\t/*\n\t * Los datos se almancenan en pila con ordenacion LIFO (LAST IN, FIRST OUT)\n\t * El ultimo dato introducido sera el primero en salir\n\t */\n\tstack<int> pila; // ---> #include<stack>\n\n\t//Insertar Datos\n\n\tpila.push(7);\n\tpila.push(8);\n\tpila.push(9);\n\n\tcout << \"El tama├▒o de la pila es de: \" << pila.size() << \" elementos\"\n\t\t\t<< endl;\n\n\t//Extraer Datos\n\n\tcout << \"El valor actual de la cima de la pila es: \" << pila.top() << endl;\n\tpila.pop(); // ---> Elimina el dato de arriba\n\tcout << \"El valor actual de la cima de la pila es: \" << pila.top() << endl;\n\n\t//Colas(Queue)\n\t/*\n\t * Los datos se almacenan en fila con ordenacion FIFO (FIRST IN, FIRST OUT)\n\t * El ultimo dato introducido sera el ultimo en salir\n\t */\n\tqueue<int> cola; // ---> #include<queue>\n\n\t//Insertar Datos\n\n\tcola.push(7);\n\tcola.push(8);\n\tcola.push(9);\n\n\tcout << \"El tama├▒o de la cola es de: \" << cola.size() << \" elementos\"\n\t\t\t<< endl;\n\n\t//Extraer Datos\n\n\tcout << \"El valor actual del primero de la cola es: \" << cola.front()\n\t\t\t<< endl;\n\tcola.pop(); // ---> Elimina el dato del primero de la cola\n\tcout << \"El valor actual del primero de la cola es: \" << cola.front()\n\t\t\t<< endl;\n\n\t//Map\n\t/*\n\t * Podemos ordenar los datos con clave-valor, en donde la clave nos permitira acceder/locacalizar el valor\n\t */\n\tmap<int, int> mapa; // ---> #include<map>\n\n\t//Insertar Datos\n\n\tmapa[1] = 15;\n\tmapa[2] = 25;\n\tmapa[3] = 35;\n\tmapa[4] = 45;\n\tmapa[5] = 55;\n\n\tfor (auto &x : mapa) {\n\t\tcout << \"Key: \" << x.first << \" Value: \" << x.second << endl;\n\t}\n\n\t//Borrar Datos\n\n\t//mapa.clear(); ---> Eliminar(limpiar) todos los datos de la lista\n\tmapa.erase(3);\n\tcout << \"Se ha borrado la tercera llave\" << endl;\n\tfor (auto &x : mapa) {\n\t\tcout << \"Key: \" << x.first << \" Value: \" << x.second << endl;\n\t}\n\n\t//Para actualizar los datos podemos indicar la llave y asignarle el nuevo valor,\n\t//Para actualizar la llave, tenemos que eliminar la que desemos cambiar y crear una nueva\n\t//Las estructuras map no se pueden ordenar por naturaleza.\n\n\t/* DIFICULTAD EXTRA (opcional):\n\t * Crea una agenda de contactos por terminal.\n\t * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n   * - Cada contacto debe tener un nombre y un número de teléfono.\n   * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n   *   los datos necesarios para llevarla a cabo.\n   * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n   *   (o el número de dígitos que quieras)\n   * - También se debe proponer una operación de finalización del programa.\n   */\n\tmap<string, string> agenda;\n\tint opcion;\n\tint contador = 0;\n\tdo {\n\t\tcout << \"\\n*************Agenda de Contactos*************\" << endl;\n\t\tcout << endl;\n\t\tcout << \"Decida la opcion que quiera realizar: \" << endl;\n\t\tcout << endl;\n\t\tcout << \"Opcion 1: Buscar contacto\" << endl;\n\t\tcout << \"Opcion 2: Nuevo contacto\" << endl;\n\t\tcout << \"Opcion 3: Actualizar contacto\" << endl;\n\t\tcout << \"Opcion 4: Eliminar contacto\" << endl;\n\t\tcout << \"Opcion 5: Salir\" << endl;\n\t\tcout << endl;\n\t\tcout << \"Intruzca el numero de la opcion que desee: \" << endl;\n\t\tcin >> opcion;\n\t\tcin.ignore();\n\t\tif (opcion == 1) {\n\t\t\tcout << \"Nombre\\t\\t\\tTelefono\" << endl;\n\t\t\tcout << endl;\n\t\t\tfor (auto &x : agenda) {\n\t\t\t\tcout << x.first << \"\\t\\t\\t\" << x.second << endl;\n\t\t\t}\n\t\t} else if (opcion == 2) {\n\t\t\tcout << \"Introduzca el nombre del contacto: \" << endl;\n\t\t\tstring nombre;\n\t\t\tgetline(cin, nombre);\n\t\t\tcout << \"\\nIntroduzca el numero del contacto (max 11 digitos): \"\n\t\t\t\t\t<< endl;\n\t\t\tstring numero;\n\t\t\tgetline(cin, numero);\n\t\t\tif (numero.length() > 11) {\n\t\t\t\tcout << \"Ha excedido el limite de digitos, intente de nuevo: \"\n\t\t\t\t\t\t<< endl;\n\t\t\t} else {\n\t\t\t\tfor (int i = 0; i < numero.length(); ++i) {\n\t\t\t\t\tif ((numero.at(i) != '0') && (numero.at(i) != '1')\n\t\t\t\t\t\t\t&& (numero.at(i) != '2') && (numero.at(i) != '3')\n\t\t\t\t\t\t\t&& (numero.at(i) != '4') && (numero.at(i) != '5')\n\t\t\t\t\t\t\t&& (numero.at(i) != '6') && (numero.at(i) != '7')\n\t\t\t\t\t\t\t&& (numero.at(i) != '8') && (numero.at(i) != '9')) {\n\t\t\t\t\t\tcout << \"Ha introducido un dato no numerico, \" << endl;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tagenda[nombre] = numero;\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (opcion == 3) {\n\t\t\tcout << \"Nombre\\t\\t\\tTelefono\" << endl;\n\t\t\tcout << endl;\n\t\t\tfor (auto &x : agenda) {\n\t\t\t\tcout << x.first << \"\\t\\t\\t\" << x.second << endl;\n\t\t\t}\n\t\t\tcout << \"Decida la opcion que quiera realizar: \\n\" << endl;\n\t\t\tcout << \"Opcion 1: Actulizar nombre\" << endl;\n\t\t\tcout << \"Opcion 2: Actulizar numero\" << endl;\n\t\t\tint subOpcion;\n\t\t\tcin >> subOpcion;\n\t\t\tcin.ignore();\n\t\t\tif (subOpcion == 1) {\n\t\t\t\tcout << \"Introduzca el numero del contacto: \" << endl;\n\t\t\t\tstring numero;\n\t\t\t\tgetline(cin,numero);\n\t\t\t\tif (numero.length() > 11) {\n\t\t\t\t\tcout\n\t\t\t\t\t\t\t<< \"Ha excedido el limite de digitos, intentelo de nuevo: \"\n\t\t\t\t\t\t\t<< endl;\n\t\t\t\t} else {\n\t\t\t\t\tfor (int i = 0; i < numero.length(); ++i) {\n\t\t\t\t\t\tif ((numero.at(i) != '0') && (numero.at(i) != '1')\n\t\t\t\t\t\t\t\t&& (numero.at(i) != '2')\n\t\t\t\t\t\t\t\t&& (numero.at(i) != '3')\n\t\t\t\t\t\t\t\t&& (numero.at(i) != '4')\n\t\t\t\t\t\t\t\t&& (numero.at(i) != '5')\n\t\t\t\t\t\t\t\t&& (numero.at(i) != '6')\n\t\t\t\t\t\t\t\t&& (numero.at(i) != '7')\n\t\t\t\t\t\t\t\t&& (numero.at(i) != '8')\n\t\t\t\t\t\t\t\t&& (numero.at(i) != '9')) {\n\t\t\t\t\t\t\tcout << \"Ha introducido un dato no numerico, intentelo de nuevo: \"\n\t\t\t\t\t\t\t\t\t<< endl;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfor (auto &x : agenda) {\n\t\t\t\t\tif (x.second.compare(numero)==0) {\n\t\t\t\t\t\tcout << \"El numero coincide con el nombre: \"<< x.first << endl;\n\t\t\t\t\t\tcout << \"Introduzca el nuevo nombre: \" <<endl;\n\t\t\t\t\t\tstring nombre;\n\t\t\t\t\t\tgetline(cin, nombre);\n\t\t\t\t\t\tagenda.erase(x.first);\n\t\t\t\t\t\tagenda[nombre]=numero;\n\t\t\t\t\t\tcontador=0;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcontador++;\n\t\t\t\t}\n\t\t\t\tif (agenda.size() == contador) {\n\t\t\t\t\tcout << \"El numero no ha encontrado coincidencias, intentelo de nuevo\" << endl;\n\t\t\t\t\tcontador=0;\n\t\t\t\t}\n\t\t\t}else if(subOpcion == 2){\n\t\t\t\tcout << \"Introduzca el nombre del contacto: \" << endl;\n\t\t\t\tstring nombre;\n\t\t\t\tgetline(cin,nombre);\n\t\t\t\tfor (auto &x : agenda) {\n\t\t\t\t\tif (x.first.compare(nombre)==0) {\n\t\t\t\t\t\tcout << \"El nombre coincide con el numero: \"<< x.second << endl;\n\t\t\t\t\t\tcout << \"Introduzca el nuevo numero: \" <<endl;\n\t\t\t\t\t\tstring numero;\n\t\t\t\t\t\tgetline(cin, numero);\n\t\t\t\t\t\tif (numero.length() > 11) {\n\t\t\t\t\t\t\tcout\n\t\t\t\t\t\t\t\t\t<< \"Ha excedido el limite de digitos, intente de nuevo: \"\n\t\t\t\t\t\t\t\t\t<< endl;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}else{\n\t\t\t\t\t\t\tfor (int i = 0; i < numero.length(); ++i) {\n\t\t\t\t\t\t\t\tif ((numero.at(i) != '0') && (numero.at(i) != '1')\n\t\t\t\t\t\t\t\t\t\t&& (numero.at(i) != '2')\n\t\t\t\t\t\t\t\t\t\t&& (numero.at(i) != '3')\n\t\t\t\t\t\t\t\t\t\t&& (numero.at(i) != '4')\n\t\t\t\t\t\t\t\t\t\t&& (numero.at(i) != '5')\n\t\t\t\t\t\t\t\t\t\t&& (numero.at(i) != '6')\n\t\t\t\t\t\t\t\t\t\t&& (numero.at(i) != '7')\n\t\t\t\t\t\t\t\t\t\t&& (numero.at(i) != '8')\n\t\t\t\t\t\t\t\t\t\t&& (numero.at(i) != '9')) {\n\t\t\t\t\t\t\t\t\tcout << \"Ha introducido un dato no numerico, intentelo de nuevo: \"\n\t\t\t\t\t\t\t\t\t\t\t<< endl;\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tagenda.erase(x.first);\n\t\t\t\t\t\t\t\tagenda[nombre]=numero;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcout << \"El numero no ha encontrado coincidencias, intentelo de nuevo\" << endl;\n\t\t\t}\n\n\t\t}else if (opcion == 4) {\n\t\t\tcout << \"Nombre\\t\\t\\tTelefono\" << endl;\n\t\t\tcout << endl;\n\t\t\tfor (auto &x : agenda) {\n\t\t\t\tcout << x.first << \"\\t\\t\\t\" << x.second << endl;\n\t\t\t}\n\t\t\tcout << \"Introduce el nombre del contacto que quieras eliminar\" << endl;\n\t\t\tstring nombre;\n\t\t\tgetline(cin,nombre);\n\t\t\tfor(auto &x: agenda){\n\t\t\t\tif (x.first.compare(nombre) == 0) {\n\t\t\t\t\tagenda.erase(nombre);\n\t\t\t\t\tcout << \"Contacto eliminado\" << endl;\n\t\t\t\t\tcontador =0;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcontador++;\n\t\t\t}\n\t\t\tif (agenda.size()==contador){\n\t\t\tcout << \"El nombre no coincide con ningun contacto\" << endl;\n\t\t\tcontador=0;\n\t\t\t}\n\t\t} else {\n\n\t\t}\n\n\t} while (opcion != 5);\n\n\treturn 0;\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/c++/Vid92.cpp",
    "content": "#include <iostream>\n#include <string>\n#include <sstream>\n//#include <cmath>\n\nusing namespace std;\n\n\n//Ejercicio extra - agenda contactos\nstruct agenda{\n    string nombre;\n    int telefono;\n};\n\n\nagenda *contacto = new agenda[50];\n\nbool flag = false;\nbool flagOut = false;\nint n = 1;\n\n\nvoid inserte(){\n    string num;\n    do{\n        cout<<\"Ingrese nombre:\"<<endl;\n        cin>>contacto[n].nombre;\n        \n        num = \"\";\n        flag = false;\n        cout<<endl<<\"Ingrese telefono:\"<<endl;\n        cin>>num;\n        \n        for(int i=0;i<num.length();i++){\n            if(!isdigit(num[i])){\n                flag = true; \n                goto next;\n            }\n        }\n        \n        next:\n        if(num.length()>11 | flag){\n            cout<<\"Error, longitud o digitos no numericos\"<<endl;\n            contacto[n].nombre = \"\";\n            n--;\n        }\n        else{\n            contacto[n].telefono = stoi(num);\n        }\n            \n        n++;\n    }while(num.length()>11 | flag);\n    cout<<endl;\n}\n\nvoid buscar(){\n    string nombre;\n    bool flag=false;\n    cout<<\"Nombre de contacto a buscar...\"<<endl;\n    cin>>nombre;\n    for(int x=1;x<n;x++){\n       if(contacto[x].nombre==nombre){\n           cout<<\" Contacto encontrado! : \"<<contacto[x].nombre<<\" -- \"<<contacto[x].telefono<<endl; \n           flag = true;\n           break;\n       }\n    }\n    \n    if(!flag)\n        cout<<endl<<\"Contacto no encontrado\"<<endl<<endl;\n}\n\nvoid actualizar(){\n    cout<<endl<<\"-------Nombre--------|-----------Telefono----------\"<<endl;\n    for(int x=1;x<n;x++){\n       cout<<\"       \"<<contacto[x].nombre<<\"                    \"<<contacto[x].telefono<<endl; \n    }\n}\n\nvoid eliminar(){\n    string nombre;\n    actualizar();\n    cout<<\"Eliminar contacto con nombre...\"<<endl;\n    cin>>nombre;\n    \n    for(int x=1;x<n;x++){\n       if(contacto[x].nombre==nombre){\n           for(int i=x;i<n;i++){\n                contacto[i].nombre = contacto[i+1].nombre;\n                contacto[i].telefono = contacto[i+1].telefono;\n           }\n       }\n    }\n    n--;\n    actualizar();\n}\n\nvoid menu(){\n    int a;\n    cout<<endl<<\"------------------------------ Agenda de Contactos -----------------------------------------\"<<endl;\n    cout<<endl<<\"Inserte numero para elegir opcion:\"<<endl;\n    cout<<endl<<\"| 1. Busqueda | 2. Insertar | 3. Actualizar | 4. Eliminar | 5. Salir |\"<<endl<<endl;\n    cin>>a;\n    \n    switch(a){\n        case 1:\n        buscar();\n        break;\n        \n        case 2:\n        inserte();\n        break;\n        \n        case 3:\n        actualizar();\n        break;\n        \n        case 4:\n        eliminar();\n        break;\n        \n        case 5:\n        cout<<\"Fin\"<<endl;\n        flagOut = true;\n        break;\n        \n        \n        default:\n        cout<<\"Opcion no encontrada\"<<endl;\n        break;\n    }\n}\n\n\nint main(){\n    do{\n        menu();\n    }while(!flagOut);\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/c++/carZep09.cpp",
    "content": "#include <iostream> \n#include <array> \n#include <iomanip>\n#include <vector> \n#include <list>\n#include <queue>\n#include <deque> \n#include <tuple> \n#include <map>\n#include <utility>\n#include <set>\n#include <iterator>\n#include <algorithm> // se usa solamente en la operacion all_of \n\nusing namespace std; \n\n// *******************************************************************************************\n/*Esta funcion es necesaria para que queue pueda imprimirse, refierase al ejemplo de la cola */\nvoid imprCola(queue <int>& q){\n    while (!q.empty()){\n        cout << q.front() << ' '; \n        q.pop(); \n    }\n    cout << '\\n'; \n}\n// *******************************************************************************************\n// *********************** Funciones para el uso de la agenda *****************************\nvoid insert_num(string& nombre, string& numero, map <string, string>& mapa){\n\n    cout << \"Escribe el nombre: \"; \n    cin >> nombre; \n    cout << \" y el numero del contacto: \"; \n    cin >> numero;\n\n    if ((numero.length() > 0 && numero.length() <= 11) && (all_of(numero.begin(), numero.end(), ::isdigit))) {\n        mapa[nombre] = numero; \n    }\n\n    else{\n        cout << \"Solo pon 11 digitos y que sea digitos!\" << '\\n'; \n    } \n}\n\nvoid search_num(string& nombre, map <string, string>& mapa){\n    if (mapa.find(nombre) != mapa.end()){\n        cout << \"Aqui tienes al contacto \" << mapa.find(nombre) -> first  << \" - \" <<  mapa.find(nombre) -> second << '\\n'; \n    }\n    else{\n        cout << \"No se encontro el contacto\" << '\\n'; \n    }\n}\n\nvoid delete_num(string& nombre, map<string, string>& mapa){\n    if (mapa.find(nombre) != mapa.end()){\n        mapa.erase(nombre); \n    }\n    else{\n        cout << \"No se encontro el contacto\" << '\\n'; \n    }\n}\n\nvoid update_num(string& nombre, string& numero,  map<string,string>& mapa){\n    if (mapa.find(nombre) != mapa.end()){\n        mapa.erase(nombre); \n\n        insert_num(nombre,numero,mapa); \n        cout << \"Este es el nuevo contacto\" << '\\n'; \n    }\n    else{\n        cout << \"No se encontro el contacto\" << '\\n'; \n    }\n}\n\nvoid print_num(map<string,string>& mapa){\n    for (auto &pair : mapa){\n        cout << pair.first << \" ---- \" <<  pair.second << '\\n'; \n    }\n}\n// ********************* fin de el uso de las funciones para la agenda ******************\n// ********************************************************************************************\nint main()\n{\n    // *******************************************************************\n    // Matriz de una dimension\n    string nombres[8] = {\"Eduardo\", \"Roberto\", \"Camilo\", \"Mario\", \"Edgardo\" ,\"Emiliano\", \"Marty\", \"Alejandro\"};\n    cout << \"Ejemplos de Matrices de una y dos dimensiones: \" <<  '\\n';\n    \n    nombres[2] = \"Mariano\"; // cambia el nombre de el 3er individuo. Indice 2\n\n    for (string i : nombres){\n        cout << i << \" \"; \n    }\n    cout << '\\n';\n     \n    // Matriz de 2 dimensiones\n    int cuadricula [3][5] = {1,2,3,4,5,\n                            6,7,8,9,10,\n                            11,12,13,14,15}; \n\n    for (int i = 0 ; i < 3; i++){\n        cout << setw(6) << '\\n'; \n        cuadricula[2][1] = 98; // cambia el 2do elemento de la 3er fila de 12 a 98\n        for(int j = 0; j < 5; j++){\n            cout << cuadricula[i][j] << \" \";\n        }\n    }\n    cout << '\\n'; \n    cout << \"El size de la cuadricula es de: \" << sizeof(cuadricula) << \" bytes\" <<  '\\n'; // imprime el tamano de la matriz  \n        // *******************************************************************\n\n    cout << '\\n';\n    cout << '\\n'; \n    // Estructura (struct)\n        // ********************************************************************\n    cout << \"Ejemplo de estructura: \" << '\\n'; \n    struct Persona {\n        string nombre; \n        int edad; \n        string pasatiempo; \n        \n    }; \n    Persona persona1, persona2; \n    persona1.nombre = \"Miguel\"; \n    persona1.edad = 23; \n    persona1.pasatiempo = \"jugar videojuegos\"; \n\n    cout << \"Te presento a: \" << persona1.nombre << \" el tiene \" << persona1.edad << \" años, y le gusta \" \n         << persona1.pasatiempo << '\\n'; \n\n    persona2.nombre = \"Juan\"; \n    persona2.edad = 19; \n    persona2.pasatiempo = \"nadar\";\n\n    cout << \"Te presento a: \" << persona2.nombre << \" el tiene \" << persona2.edad << \" años, y le gusta \" \n         << persona2.pasatiempo << '\\n'; \n\n        // *************************************************************** \n    cout << '\\n'; \n    cout << '\\n';  \n    // *******************************************************************\n    // Vector\n    cout << \"Ejemplo Vector en una secuencia de numeros: \"; \n    vector <int> secuencia;\n    vector <int> secuencia2; \n    \n\n    secuencia.push_back(5);      //   0.   [5]\n    secuencia.push_back(3);     //    1.   [3]\n    secuencia.push_back(1);    //     2.   [1]\n   \n    vector<int> :: iterator it = secuencia.begin() + 1; // se posisiona en el indice 2 \n\n    secuencia.emplace(it, -2);  //   1. [-2]\n    secuencia.emplace_back(-7); //   3. [-7] agrega un elemento adicional en el fondo de la secuencia\n    secuencia.emplace_back(-9); //   4. [-9] \"\"     \"\"    \"\"        \"\"    \"\" \"\"  \"\"  despues del indice 3\n\n    secuencia.push_back(-25);  //    5. [-25] va en orden, asi que se agrega despues de la operacion anterior\n    secuencia.front() += secuencia.back(); //     1. indice de el frente [5]\n                                        //        = [5] + indice de el fondo [-25] -> [20]\n    secuencia.pop_back();     //      remueve el elemento -25\n    for(int i = 0; i < secuencia.size(); i++){ \n        cout << secuencia[i] << \" \";  // imprime cada elemento del vector\n    }\n    cout << '\\n'; \n    cout << \"2da forma para llamar a la secuencia: \";  \n    for (vector<int> :: iterator it1 = secuencia.begin(); it1 != secuencia.end(); it1++){\n        cout << *it1 << ' ';  \n    }\n    \n    cout << '\\n'; \n\n    for(int i = 0; i < 4; i++){\n        secuencia2.push_back(i); \n    }\n    \n    cout << '\\n'; \n    cout << \"Este es el numero en el espacio 5 es igual a [4] del vector: \" << secuencia.at(4) << '\\n'; \n    cout <<\"Este es el tamaño de la secuencia: \" <<  secuencia.size() << '\\n';  \n    \n    secuencia2.assign(4, -20);  //  0 - 4 [-20,-20,-20,-20] assigna a los 4 espacios el valor -20\n    secuencia.swap(secuencia2); // remplaza el contenido de secuencia 2 desde secuencia\n    secuencia2.swap(secuencia); // deshace la operacion anterior \n    it = secuencia2.begin(); // reinicia el valor del iterador y lo pone en el segundo elemento de \n                                //  la secuencia 2 \n    secuencia2.insert((it + 3), 2, 39); // en el indice 4 se posisiona el fichero e imprime en los siguientes \n    // 2 (3 - 4) indices el numero 39 \n    it = secuencia2.begin(); \n    secuencia2.emplace((it + 2) , 50);  // 3. [50] es substituido  \n    secuencia2.erase((secuencia2.begin() + 2), secuencia2.end() - 2); // borra el elemento del indice 1 y \n    // del indice 4 [5] de la secuencia\n    // clear() borrar la secuencia \n    \n    cout << \"Este es el contenido de secuencia 2: \"; \n    for(vector<int> :: iterator it2 = secuencia2.begin(); it2 != secuencia2.end(); ++it2){\n        cout << *it2 << ' '; \n    }\n\n    cout << '\\n'; \n    cout << '\\n';\n    // *******************************************************************\n    // Lista\n    // Tiene los miembros de funciones al igual que los vectores \n    // Solo que este incluye emplace_front()\n    cout << \"Ejemplo de una lista \" << '\\n'; \n    list <string> lista_compras {\"tomates, cebollas, chiles\", \"papaya\"}; \n\n    list <string> :: iterator itr; \n    lista_compras.push_back(\"zanahorias\"); \n    lista_compras.push_back(\"brocolis\"); \n    lista_compras.push_back(\"rabanos\"); \n    lista_compras.push_back(\"frijoles\"); \n    lista_compras.pop_front(); // remueve el elemento tomates de la lista\n    lista_compras.emplace_front(\"camotes\"); // substituye a cebollas de la lista \n    lista_compras.emplace_back(\"berenjena\"); // se posisiona al final \n\n    cout <<\"Este es el frente de la lista: \" <<  lista_compras.front() << '\\n'; \n    cout << \"Este es el fondo de la lista: \" << lista_compras.back() << '\\n'; \n    \n    cout << \"Lista completa aqui: \"; \n    for (auto itr = lista_compras.begin(); itr != lista_compras.end(); ++itr){\n        cout << *itr << ' '; \n    }\n    // **********************************************************************\n    cout << '\\n'; \n    cout << '\\n'; \n    // **********************************************************************\n    // cola \n    cout << \"Ejemplo de cola: \"<< '\\n'; \n\n    queue <int> lugar; \n    lugar.push(20); \n    lugar.push(25); \n    lugar.push(45); \n    lugar.push(19); \n    lugar.emplace(42); \n    lugar.pop(); \n    lugar.pop(); \n\n    imprCola(lugar); \n    // ************************************************************************\n    cout << '\\n';  \n    // ************************************************************************\n\n    // Tuplas\n    cout << \"Ejemplo de tupla: \" << '\\n'; \n    tuple <int, double, string> num_y_nom (10.4, 27.5, \"Julio\") ; \n    tuple <int, double, string> num_y_nom2; (9, 5.2, \"Mario\"); \n\n   \n    cout << get<0>(num_y_nom) << ' ' << get<1>(num_y_nom) << ' ' << get<2>(num_y_nom) << '\\n'; \n\n    num_y_nom.swap(num_y_nom2); // intercambia las tuplas num_y_nom2 por las de num_y_nom\n\n    cout << get<0>(num_y_nom2) << ' ' << get<1>(num_y_nom2) << ' ' << get<2>(num_y_nom2) << '\\n'; \n    cout << '\\n'; \n    // ***************************************************************************\n    // Sets \n    cout << \"Ejemplo de set: \" << '\\n'; \n    set <int> set_num; \n    set_num.insert(10); \n    set_num.insert(23); \n    set_num.insert(107); \n    set_num.erase(23); \n    set_num.emplace_hint(set_num.begin(), 29); \n    set_num.emplace_hint(set_num.end(), 72); \n    set_num.emplace(11); \n\n    for (auto it = set_num.begin(); it != set_num.end(); ++it){\n        cout << *it << ' '; \n    }\n    cout << '\\n'; \n    // ****************************************************************************\n    // Colas de doble fin\n    cout << \"Ejemplo de un deque: \"; \n    deque <string> bebidas = {\"soda\", \"jugos\", \"agua\"}; \n\n    bebidas.push_front(\"cerveza\"); // luego este\n    bebidas.push_back(\"vino\"); \n    bebidas.emplace_front(\"té\"); // este elemento se pone primero \n    bebidas.emplace_back(\"agua carbonatada\"); \n\n\n    for (deque <string> :: iterator it = bebidas.begin(); it != bebidas.end(); ++it){\n        cout << *it << ' '; \n    }\n    cout << '\\n'; \n    cout << '\\n'; \n    // ******************************************************************************\n    // Mapa \n    cout << \"Ejemplo de un mapa #1: \" << '\\n';  \n    map <string, string> traductor; \n    traductor.insert (pair <string, string> (\"bote\", \"boat\"));\n    traductor.insert (pair <string, string> (\"manzana\", \"apple\")); \n    traductor[\"paleta\"] = \"lolleypop\"; \n    traductor[\"carne\"] = \"steak\"; \n\n    for (auto pair : traductor){\n        cout << pair.first << \" ---- la traduccion: ----- \" << pair.second << '\\n'; \n    }\n\n    cout << '\\n'; \n\n    cout << \"Ejemplo de otro mapa #2: \" << '\\n'; // este ejemplo usa una lista como \n    cout << '\\n'; \n    map <string, list<string> > DBZ; \n\n    list <string> ataque_Goku {\"kamehameha\", \"kienzan\", \"kaio ken\"}; \n    list <string> ataque_Piccolo {\"makankosappo\", \"masenko\", \"mafuba\", \"kaikosen\"}; \n    list <string> ataque_Gohan {\"kamehameha\", \"makankosappo\", \"gekizturanma\", \"super masenko\"}; \n\n    DBZ.insert(pair<string, list<string>> (\"Goku\", ataque_Goku));\n    DBZ.insert(pair<string, list<string>> (\"Gohan\", ataque_Gohan));\n    DBZ.insert(pair<string, list<string>> (\"Piccolo\", ataque_Piccolo)); \n\n    for (auto pair : DBZ){\n        cout << pair.first << \" posee: \"; \n        for (auto ataque : pair.second){\n            cout << ataque << \" \";  \n        }\n        cout << '\\n'; \n    }\n\n    /* DIFICULTAD EXTRA (opcional):\n     * Crea una agenda de contactos por terminal.\n     * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n    * - Cada contacto debe tener un nombre y un número de teléfono.\n    * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n    *   los datos necesarios para llevarla a cabo.\n    * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n     *   (o el número de dígitos que quieras)\n    * - También se debe proponer una operación de finalización del programa. */\n   \n\n   int opcion = 0; \n   bool cont = true; // esta condicion se mantiene true, se usa en el bucle while\n   map <string, string> numero_cel; \n   string nombre, numero; \n    while(cont){\n        cout << '\\n' << '\\n'; \n        cout << \"-----AGENDA DE CONTACTOS ------\" << '\\n'; \n        cout << \"¿Que quisieras hacer?  \" << '\\n';\n        cout << \"1. Insercion \" << '\\n'; \n        cout << \"2. Busqueda \" << '\\n'; \n        cout << \"3. Actualizacion \" << '\\n'; \n        cout << \"4. Eliminacion \" << '\\n'; \n        cout << \"5. Terminar el programa\" << '\\n'; \n        cout << \"Selecciona la opcion: \"; \n        cin >> opcion; \n        cout << '\\n'; \n\n        if(cin.fail()){\n            cin.clear(); // limpia el flag de error para futuras operaciones  \n            cin.ignore(numeric_limits<streamsize>::max(),'\\n'); // previene que los viejos input de operaciones \n            // pasadas no interfieran con nuevos inputs \n            cout << \"No es valido! Elige algo entre 1 y 5\" << '\\n'; \n            continue;\n        }\n\n        switch(opcion){\n            case 1:\n                insert_num(nombre,numero,numero_cel); \n                cout << '\\n'; \n                print_num(numero_cel); \n \n                break; \n            case 2: \n                cout << \"Escribe el nombre del contacto que quieres buscar: \";\n                cin >> nombre; \n\n                search_num(nombre,numero_cel);\n                cout << '\\n'; \n                print_num(numero_cel); \n\n                break; \n            case 3: \n                cout << \"Escribe el nombre que quieres actualizar: \"; \n                cin >> nombre; \n\n                update_num(nombre,numero,numero_cel); \n                cout << '\\n'; \n                print_num(numero_cel);\n\n                break; \n\n            case 4: \n                cout << \"Escribe el nombre que quieres eleminar: \";\n                cin >> nombre; \n\n                delete_num(nombre,numero_cel);\n                cout << '\\n';  \n                print_num(numero_cel); \n\n                break;\n\n            case 5: \n                cout << \"El fin de la agenda.\" << '\\n'; \n                cont = false;  \n                break; \n            default: \n                cout << \"No es valido! Elige algo entre el 1 al 5.\" << '\\n'; \n                break; \n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/c++/hectorio23.cpp",
    "content": "#include <algorithm>\n#include <iostream>\n#include <string>\n#include <list>\n\n/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\nvoid menu();\nvoid buscarContacto();\nvoid agregarContacto();\nvoid eliminarContacto();\nvoid imprimirContacto();\nvoid actualizarContacto();\n\nstd::list<std::pair<std::string, std::string>> data;\n\nint main() {\n\n    // Funcion que se encarga de todo\n    menu();\n\n    return 0;\n}\n\nvoid menu() {\n    char choose;\n    while (true) {\n        std::cout << \"************ Sistema de Gestion de contactos *************\\n\";\n        std::cout << \"[1] - Busqueda de Contactos \\n\";\n        std::cout << \"[2] - Insercion de Contactos \\n\";\n        std::cout << \"[3] - Actualizacion de Contactos \\n\";\n        std::cout << \"[4] - Eliminacion de Contactos \\n\";\n        std::cout << \"[5] - Imprimir todos los contactos \\n\";\n        std::cout << \"[6] - Terminar el programa \\n\";\n\n        std::cout << \"Escoge una opcion: \";\n        std::cin >> choose;\n\n        switch (choose) {\n            case '1':\n                buscarContacto();\n                break;\n            case '2':\n                agregarContacto();\n                break;\n            case '3':\n                actualizarContacto();\n                break;\n            case '4':\n                eliminarContacto();\n                break;\n            case '5':\n               imprimirContacto();\n               break;\n            case '6':\n                std::cout << \"Programa terminado. Adios.\\n\";\n                exit(0);\n            default:\n                std::cout << \"Opcion invalida. Intentalo de nuevo.\\n\";\n        }\n\n        std::cout << \"\\n\\n\";\n    }\n}\n\nvoid buscarContacto() {\n    std::cout << \"Ingresa el registro que quieras buscar (nombre/telefono): \";\n    std::string patron;\n    std::cin >> patron;\n\n    std::cout << \"\\n\";\n\n    bool encontrado = false;\n    for (auto element : data) {\n        if (element.first == patron || element.second == patron) {\n            std::cout << \"Registro encontrado: \" << element.first << \" <- \" << element.second << \"\\n\";\n            encontrado = true;\n            break;\n        }\n    }\n\n    if (!encontrado) {\n        std::cout << \"Dato no encontrado\\n\";\n    }\n}\n\nvoid agregarContacto() {\n    std::string nombre, telefono;\n\n    std::cout << \"Ingresa el nombre del nuevo contacto: \";\n    std::cin.ignore(); // Limpiar el buffer del teclado antes de getline\n    std::getline(std::cin, nombre);\n\n    std::cout << \"Ingresa el numero de telefono del nuevo contacto: \";\n    std::cin >> telefono;\n\n    // Validar número de teléfono (opcional)\n    if (telefono.size() > 11 || !std::all_of(telefono.begin(), telefono.end(), ::isdigit)) {\n        std::cout << \"Numero de telefono invalido. Debe tener hasta 11 digitos y ser numerico.\\n\";\n        return;\n    }\n\n    data.push_back(std::make_pair(nombre, telefono));\n    std::cout << \"Contacto agregado exitosamente.\\n\";\n}\n\nvoid actualizarContacto() {\n    std::string nombre, nuevoTelefono;\n\n    std::cout << \"Ingresa el nombre del contacto que quieres actualizar: \";\n    std::cin.ignore(); // Limpiar el buffer del teclado antes de getline\n    std::getline(std::cin, nombre);\n\n    bool encontrado = false;\n    for (auto &element : data) {\n        if (element.first == nombre) {\n            std::cout << \"Ingresa el nuevo numero de telefono para \" << nombre << \": \";\n            std::cin >> nuevoTelefono;\n\n            // Validar número de teléfono (opcional)\n            bool telefonoValido = true;\n            if (nuevoTelefono.size() > 11) {\n                telefonoValido = false;\n            } else {\n                for (char c : nuevoTelefono) {\n                    if (!std::isdigit(c)) {\n                        telefonoValido = false;\n                        break;\n                    }\n                }\n            }\n\n            if (!telefonoValido) {\n                std::cout << \"Numero de telefono invalido. Debe tener hasta 11 digitos y ser numerico.\\n\";\n                return;\n            }\n\n            element.second = nuevoTelefono;\n            std::cout << \"Contacto actualizado exitosamente.\\n\";\n            encontrado = true;\n            break;\n        }\n    }\n\n    if (!encontrado) {\n        std::cout << \"Contacto no encontrado.\\n\";\n    }\n}\n\nvoid eliminarContacto() {\n    std::string nombre;\n\n    std::cout << \"Ingresa el nombre del contacto que quieres eliminar: \";\n    std::cin.ignore(); // Limpiar el buffer del teclado antes de getline\n    std::getline(std::cin, nombre);\n\n    auto it = data.begin();\n    while (it != data.end()) {\n        if (it->first == nombre) {\n            it = data.erase(it);\n            std::cout << \"Contacto eliminado exitosamente.\\n\";\n            return;\n        } else {\n            ++it;\n        }\n    }\n\n    std::cout << \"Contacto no encontrado.\\n\";\n}\n\nvoid imprimirContacto() {\n   std::cout << \"\\n\\n\";\n   for (auto item : data) { std::cout << item.first << \" <- \" << item.second << \"\\n\\n\";\n   }\n}"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/c++/jhoshmc.cpp",
    "content": "#include <iostream>\n#include <vector>\n#include <algorithm> // necesario para remove\n#include <map>\n#include <regex>\nusing namespace std;\n\n//* estructura \n/*\n una estructura es  es un tipo compuesto definido por el usuario. Se compone de campos o \n de miembros que pueden tener diferentes tipos.\n*/\nstruct PERSONA{  // nombre de la estructura(declarando la estructura)\n// declarando los tipos de campos \n  int edad;\n  string name;\n  string last_name;\n}miembros_de_la_familia; // definir el objeto de la estructura\n\nstruct AGENDA{\n  string nombre;\n  long long int numero;\n};\n//* estructura para poder retornar mas de un valor\nstruct RETORNAR\n{\n  bool encontrado=false;\n  int posicion=NULL;\n};\n\n\n\n\n//* Prototipos de funciones\nvoid insert_Sort(vector<int>); // funcion de ordenmiento por inserción\nvoid imprimir_vector(vector<int>);\nvoid burbuja_simple(vector<int>); // fucion de ordeanmeinto por burbuja simple\nvoid eliminar_por_posicion(vector<int> &, int);\nvoid eliminar_por_valor(vector<int> &, int);\n\n//? funciones para el ejercicio extra\nbool validarNombre(const string &nombre);\nbool validarNumero(const string &input);\nvoid menu(vector<AGENDA>&);\nvoid ingresar_contacto(vector<AGENDA>&);\nRETORNAR buscar_contacto(vector<AGENDA>&,string);\nvoid actualizar_contacto(vector<AGENDA>&,string);\nvoid ordenar_contactos(vector<AGENDA>);\nvoid eliminar_contacto(vector<AGENDA>&,string nombre);\n// funcion para ordenar los contactos\nbool compararPorNombre(const AGENDA&, const AGENDA&);\n\nint main(){\n  \n  //? struct PERSONA hermana; // declarando una estructura al estilo C\n  // // ingresando los valores\n  // hermana.edad = 23;\n  // hermana.name = \"berenice\";\n  // hermana.last_name = \" Morales Zapata\";\n\n  // cout << \"hemana: \" << hermana.name <<hermana.last_name<<\" \"<<hermana.edad<< endl;\n  //? Declarando estructuras al estilo c++\n  //? PERSONA hermano = {14, \"Matias\", \"Morales Zapata\"};\n  //? PERSONA papa = {40, \"Pedro\", \"Morales\"};\n  //? PERSONA mama = {41, \"Ana\", \"Zapata\"};\n\n  // cout << \"hermano: \" << hermano.name << \" \" << hermano.last_name << \" edad: \" << hermano.edad << endl;\n  // cout << \"papá: \" << papa.name << \" \" << papa.last_name << \" edad: \" << papa.last_name << endl;\n  // cout << \"mama: \" << mama.name << \" \" << mama.last_name << \" edad: \" << mama.edad << endl;\n\n  // vector<int> numeros = {2,5,3,7,1};\n  // insert_Sort(numeros);\n  // cout<<\"vector original \"<<endl;\n  // imprimir_vector(numeros);\n  // cout << \"ordenaminto por burbuja simple: \" << endl;\n  // burbuja_simple(numeros);\n  // vector<int> numeros_2 = {4, 2, 9, 8, 5, 3};\n  // imprimir_vector(numeros_2);\n  // numeros_2.push_back(10); // se inserta un nuevo numeroal final del vector\n  // imprimir_vector(numeros_2);\n  // eliminar_por_posicion(numeros_2,3);\n  // eliminar_por_valor(numeros_2,5);\n\n  //* begin() da el inicio del iterador, 0, el prinicipio, end() da el final , tamaño n\n  // numeros_2.insert((numeros_2.begin() + 3), 7);\n  // imprimir_vector(numeros_2);\n  //* map\n  // map<string, int> people = { {\"John\", 32}, {\"Adele\", 45}, {\"Bo\", 29} };\n  // map<string, int> estudiante = {{\"jose\", 923424323}, {\"pedro,98768730\"}};\n  // for( auto es : people){\n  //   cout << es.first << \" is \" << es.second << endl;\n  // };\n  // map<int, AGENDA> contactos;\n  // AGENDA new_contacto;\n  // contactos.insert({1, {new_contacto.nombre = \"jose\", new_contacto.numero = 98767887634}});\n  // contactos.insert({2, {new_contacto.nombre = \"maria\", new_contacto.numero = 93456758965}});\n  // for(auto persona : contactos){\n  //   cout << persona.first << \" : \" << persona.second.nombre<<\" \"<<persona.second.numero<< endl;\n  // }\n\n  //? ejercicio extra\n  vector<AGENDA> contactos = {{\"jose\", 987654623451},{\"maria\",98788765437}};\n  \n  \n   menu(contactos);\n\n  return 0;\n}\nvoid imprimir_vector(vector<int> numeros){\n  for (int i = 0; i < numeros.size(); i++)\n {\n   cout << numeros[i]<<\", \";\n }\n cout << endl;\n}\n\nvoid insert_Sort(vector<int> numeros){\n  /*\n  * Pseudocodigo:\n  * for j=1 hasta (tamaño) hacer\n  *   key = vec[j]\n  *   i= j-1\n  *   while i>= 0 && vec[i]> key\n  *     vec[i+1]= vec[i]\n  *     i= i-1\n  *   vec[i+1] = key \n  */\n  int key;\n  int i;\n  for (int j = 1; j < numeros.size(); j++)\n  {\n     key = numeros[j];\n     i = j - 1;\n     while (i>= 0 && numeros[i]>key)\n     {\n       numeros[i + 1] = numeros[i];\n       i = i - 1;\n     }\n     numeros[i + 1]= key;\n }\n\n imprimir_vector(numeros);\n}\n\nvoid burbuja_simple(vector<int> vec){\n\n  /*\n  *Pseudocodigo\n  para i desde 0 hasta n-1 hacer\n    para j desde 0 hasta n-i-1\n     si vec[j] > vec[j+1] entonces\n      intercambiar vec[j] y vec[j+1]\n      fin_si\n    fin_para\n  fin_para\n  */\n  int aux=0;\n\n  for (int i = 0; i < (vec.size()-1); i++)\n  {\n    for (int j = 0; j < (vec.size()-i-1); j++)\n    {\n      if (vec[j] > vec[j+1])\n      {\n        aux = vec[j];\n        vec[j] = vec[j+1];\n        vec[j+1] = aux;\n      }\n      \n    }\n }\n\n imprimir_vector(vec);\n}\n\nvoid eliminar_por_posicion(vector<int>& vec, int pos){\n   //* eliminar por un número por posición.\n   //* estoy pasando el vector por referencia, asi que afecta al que fue creado en main\n  vector<int>::iterator it = vec.begin() + pos;\n  vec.erase(it);\n  // *eliminando el valor de la posiicon ingresada\n  imprimir_vector(vec);\n}\n\nvoid eliminar_por_valor(vector<int>& vec, int valor){\n  //* eliminar por valor\n  vec.erase(remove(vec.begin(), vec.end(), valor), vec.end());\n  //* eliminando el valor ingresado\n  imprimir_vector(vec);\n}\n\n//? funciones para el ejercicio extra\nbool validarNombre(const string& nombre) {\n    regex patron(\"^[A-Za-zÁÉÍÓÚáéíóúÑñ ]{1,}$\"); \n    return regex_match(nombre, patron);\n}\nbool validarNumero(const string& input) {\n    regex patron(\"^\\\\d{1,11}$\"); // Expresión regular para validar números de 1 a 11 dígitos\n    return regex_match(input, patron);\n}\nvoid menu(vector<AGENDA>& contactos)\n{\n  int option;\n  while (option != 6)\n  {\n    system(\"cls\");\n    cout << \"\\t AGENDA DE CONTACTOS \" << endl;\n    cout << \"1. ingresar contacto \" << endl;\n    cout << \"2. buscar contacto \" << endl;\n    cout << \"3. actualizar contacto \" << endl;\n    cout << \"4. ordenar contactos \" << endl;\n    cout <<\"5. eliminar contacto \"<<endl;\n    cout << \"6. salir \" << endl;\n    cout << \" opcion: \";\n    cin >> option;\n    string nombre;\n    switch (option)\n    {\n    case 1:\n      ingresar_contacto(contactos);\n      system(\"pause\");\n      break;\n    case 2:\n      \n      cout << \"ingrese el nombre del contacto a buscar: \";\n      cin >> nombre;\n      buscar_contacto(contactos,nombre);\n      system(\"pause\");\n      break;\n    case 3:\n     \n      cout << \"ingrese el nombre del contacto a buscar: \";\n      cin >> nombre;\n      actualizar_contacto(contactos,nombre);\n      system(\"pause\");\n      break;\n    case 4:\n      ordenar_contactos(contactos);\n      system(\"pause\");\n      break;\n    case 5:\n      cout << \"ingrese el nombre del contacto a buscar: \";\n      cin >> nombre;\n      eliminar_contacto(contactos,nombre);\n      system(\"pause\");\n      break;\n      case 6:\n        cout << \" adios \" << endl;\n      system(\"pause\");\n        break;\n    default:\n      cout << \" opcion no valida, intente denuevo \" << endl;\n      system(\"pause\");\n      break;\n    }\n  }\n};\nvoid ingresar_contacto(vector<AGENDA>& contactos){\n  AGENDA new_contacto;\n  string nombre;\n  long long int numero;\n  bool correcto = false;\n  bool val_1 = false;\n  bool val_2 = false;\n  while (!correcto)\n  {\n    cout << \"ingrese el nombre: \";\n    cin >> nombre;\n    if(!validarNombre(nombre)){\n      cout << \"almenos deve ingresar un caracter \" << endl;\n    }else{\n      val_1 = true;\n    }\n    cout << \"ingrese el numero, no mayor a 11 dijitos: \";\n    cin>> numero;\n    if (!validarNumero(to_string(numero)))\n    {\n      cout << \"numero no valido\" << endl;\n    }else{\n      val_2 = true;\n    }\n    if (val_1 && val_2)\n    {\n      correcto = true;\n    }\n    \n    \n  }\n  \n  \n  contactos.push_back({new_contacto.nombre = nombre, new_contacto.numero = numero});\n  cout << \" se agrego el contacto \" << endl;\n};\n\nRETORNAR buscar_contacto(vector<AGENDA>& contactos,string nombre){\n  \n  bool encontrado=false;\n  int posicion;\n  int i = 0;\n  RETORNAR retornar_variables; // estructura para retornar 2 valores\n  while ( i<=contactos.size())\n  {\n    if (contactos[i].nombre == nombre)\n    {\n      posicion = i;\n      encontrado = true;\n      break;\n    }\n    \n    i++;\n  }\n  if (encontrado)\n  {\n    \n    cout << \"contacto encontrado \"<<endl;\n    cout << contactos[posicion].nombre << endl;\n    cout <<\"Movil \"<< contactos[posicion].numero << endl;\n    retornar_variables.encontrado = true;\n    retornar_variables.posicion = posicion;\n  }else{\n    cout << \"contacto no encontrado \" << endl;\n    retornar_variables.encontrado = false;\n  }\n\n  return retornar_variables; // retornar 2 valores\n};\n\nvoid actualizar_contacto(vector<AGENDA>& contactos,string nombre){\n  RETORNAR respuesta; // estructura para tomar los 2 valores retornados\n  respuesta=buscar_contacto(contactos, nombre);\n  int posicion=respuesta.posicion;\n  bool encontrado=respuesta.encontrado;\n  int op;\n\n  if (encontrado)\n  {\n    // cout << \"contacto: \" << endl;\n    // cout << contactos[posicion].nombre << \" \" << contactos[posicion].numero << endl;\n    cout << \"actualizar contacto: \" << endl;\n    cout << \"cambiar el nombre? , si=1, no=0\" << endl;\n    cout << \"op: \";\n    long long numero;\n    cin >> op;\n    bool val = false;\n    if (op ==1)\n    {\n      cout << \"nombre: \";\n      cin>>contactos[posicion].nombre;\n     \n    }\n    cout << \" cambiar el numero?, si=1, no=0\" << endl;\n     cout << \"op: \";\n    cin >> op;\n    if (op==1)\n    {\n      while (!val)\n      {\n        cout << \"numero: \";\n        cin >> numero;\n      \n       if (!validarNumero(to_string(numero)))\n       {\n         cout << \"numero no valido\" << endl;\n       }else{\n        val = true;\n        contactos[posicion].numero= numero;\n      \n       }\n      \n      }\n      \n      \n    }\n    cout << \"contacto actualizado: \" << endl;\n    cout << contactos[posicion].nombre << \" \" << contactos[posicion].numero << endl;\n  }else{\n    cout << \"paso algo :c\" << endl;\n  }\n  \n};\n\nvoid ordenar_contactos(vector<AGENDA> contactos){\n  \n  // funcion para ordenar los nombres segun el alfabeto \n  sort(contactos.begin(), contactos.end(), compararPorNombre);\n\n  for (int i = 0; i < contactos.size(); i++)\n  {\n    cout << \"-----------------------\" << endl;\n    cout << contactos[i].nombre << endl;\n    cout <<\"Movil \"<< contactos[i].numero << endl;\n    \n  }\n\n};\nvoid eliminar_contacto(vector<AGENDA>& contactos,string nombre){\n  RETORNAR respuesta;\n  respuesta = buscar_contacto(contactos, nombre);\n  int posicion = respuesta.posicion;\n  bool encontrado = respuesta.encontrado;\n  if (encontrado)\n  {\n    vector<AGENDA>::iterator it = contactos.begin() + posicion;\n    contactos.erase(it);\n    cout << \"contacto eliminado \" << endl;\n  }\n  \n\n};\n\nbool compararPorNombre(const AGENDA &a, const AGENDA &b) {\n    return a.nombre < b.nombre;\n}"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/c++/m-doce.cpp",
    "content": "#include <iostream>\r\n#include <algorithm>\r\n#include <vector>\r\n#include <list>\r\n#include <map>\r\n#include <tuple>\r\n#include <string.h>\r\nusing namespace std;\r\n\r\n#define MAX_SIZE 50\r\n\r\n// - - - Funciones y estructuras para el ejercicio extra - - -\r\n\r\nstruct Contacto\r\n{\r\n    char nombre[MAX_SIZE];\r\n    int numero;\r\n};\r\n\r\nvoid Continuar()\r\n{\r\n    printf(\"Presione 'Enter' para continuar...\\n\");\r\n    cin.get();\r\n    cin.ignore();\r\n\r\n    return;\r\n}\r\n\r\nvoid ListarContactos(vector <Contacto> agenda, int &option)\r\n{\r\n    for(int i=0; i<agenda.size(); i++)\r\n    {\r\n        printf(\"[%d] %s\\n\", (i+1), agenda[i].nombre);\r\n    }\r\n\r\n    scanf(\"%d\", &option);\r\n\r\n    return;\r\n}\r\n\r\nvoid BuscarContacto(vector <Contacto> agenda)\r\n{\r\n    int option = 0;\r\n    printf(\"\\nSeleccione el contacto para ver su numero:\\n\");\r\n    ListarContactos(agenda, option);\r\n\r\n    int i = 0;\r\n    while(i < option)\r\n    {\r\n        if(i == (option - 1))\r\n        {\r\n            printf(\"%s: %d\\n\", agenda[i].nombre, agenda[i].numero);\r\n        }\r\n\r\n        i++;\r\n    }\r\n\r\n    Continuar();\r\n\r\n    return;\r\n}\r\n\r\nvoid AgregarContacto(vector <Contacto> &agenda)\r\n{\r\n    Contacto newContact;\r\n    \r\n    printf(\"Ingrese el nombre del contacto: \");\r\n    scanf(\"%s\", &newContact.nombre);\r\n    printf(\"Ingrese el numero del contacto: \");\r\n    scanf(\"%d\", &newContact.numero);\r\n\r\n    agenda.push_back(newContact);\r\n    printf(\"\\nSe agrego a %s de forma exitosa!\\n\", newContact.nombre);\r\n    Continuar();\r\n\r\n    return;\r\n}\r\n\r\nvoid ActualizarContacto(vector <Contacto> &agenda)\r\n{\r\n    int option = 0;\r\n    printf(\"\\nSeleccione el contacto que desea actualizar:\\n\");\r\n    ListarContactos(agenda, option);\r\n\r\n    int i = 0;\r\n    while(i < option)\r\n    {\r\n        if(i == (option - 1))\r\n        {\r\n            printf(\"Actualice el nombre del contacto: \");\r\n            scanf(\"%s\", &agenda[i].nombre);\r\n            printf(\"Actualice el numero del contacto: \");\r\n            scanf(\"%d\", &agenda[i].numero);\r\n        }\r\n\r\n        i++;\r\n    }\r\n\r\n    printf(\"\\nContacto actualizado de forma exitosa!\\n\");\r\n    Continuar();\r\n\r\n    return;\r\n}\r\n\r\nvoid EliminarContacto(vector <Contacto> &agenda)\r\n{\r\n    int option = 0;\r\n    char user[MAX_SIZE];\r\n    printf(\"\\nSeleccione el contacto que desea eliminar:\\n\");\r\n    ListarContactos(agenda, option);\r\n\r\n    int i = 0;\r\n    while(i < option)\r\n    {\r\n        if(i == (option - 1))\r\n        {\r\n            strcpy(user, agenda[i].nombre);\r\n            agenda.erase(agenda.begin()+i);\r\n        }\r\n\r\n        i++;\r\n    }\r\n\r\n    printf(\"\\nSe elimino a %s de forma exitosa!\\n\", user);\r\n    Continuar();\r\n\r\n    return;\r\n}\r\n\r\nvoid Salir()\r\n{\r\n    printf(\"\\nGracias por utilizar nuestra agenda! Que tenga un buen dia :)\\n\");\r\n    exit(0);\r\n\r\n    return;\r\n}\r\n\r\nvoid MenuPrincipal(vector <Contacto> agenda)\r\n{\r\n    int firstOption = 0;\r\n    printf(\"\\nSeleccione la accion a realizar:\\n [1] Buscar\\n [2] Agregar\\n [3] Actualizar\\n [4] Eliminar\\n [5] Salir\\n\\n\");\r\n    scanf(\"%d\", &firstOption);\r\n\r\n    switch(firstOption)\r\n    {\r\n        case 1:\r\n        BuscarContacto(agenda);\r\n        MenuPrincipal(agenda);\r\n        break;\r\n\r\n        case 2:\r\n        AgregarContacto(agenda);\r\n        MenuPrincipal(agenda);\r\n        break;\r\n\r\n        case 3:\r\n        ActualizarContacto(agenda);\r\n        MenuPrincipal(agenda);\r\n        break;\r\n\r\n        case 4:\r\n        EliminarContacto(agenda);\r\n        MenuPrincipal(agenda);\r\n        break;\r\n\r\n        case 5:\r\n        Salir();\r\n        break;\r\n\r\n        default:\r\n        printf(\"\\nError de ingreso. Por favor ingrese una opcion valida\\n\");\r\n        MenuPrincipal(agenda);\r\n        break;\r\n    }\r\n}\r\n\r\n\r\n\r\nint main()\r\n{\r\n    // - - - Ejercicio extra - - -\r\n    printf(\"Bienvenido/a a su agenda!\\n\");\r\n    vector <Contacto> agenda = {{\"m-doce\", 1212}, {\"mouredev\", 1000}, {\"gitHubUser\", 9999}};\r\n    MenuPrincipal(agenda);\r\n\r\n    return 0;\r\n}\r\n\r\n/* USO Y DEFINICIÓN DE DISTINTOS TIPOS DE ESTRUCTURAS DE DATOS\r\n\r\n//Arrays\r\n    //Su tamaño y tipo de dato deben definirse al momento de crearlos, y no pueden modificarse luego. Es decir, no se pueden agregar o quitar elementos\r\n    int arrayEnteros[5] = {1, 3, 5, 7, 11}; //Creación\r\n    printf(\"%d\\n\",arrayEnteros[3]); //Acceso\r\n    arrayEnteros[4] = 13; //Modificación\r\n    //Para listar todos sus elementos es necesario utilizar un bucle de repetición\r\n    for(int i=0; i<5; i++)\r\n    {\r\n        printf(\"%d, \", arrayEnteros[i]);\r\n    }\r\n    printf(\"\\n\");\r\n\r\n\r\n    //Vectores\r\n    //Debemos definir el tipo de datos que contendrá nuestro vector, pero no es necesario definir su tamaño. El mismo es flexible y puede variar durante la ejecución del código\r\n    vector <int> vectorEnteros; //Creación\r\n    vectorEnteros.push_back(12); //Agregar un elemento al final\r\n    vectorEnteros.push_back(9);\r\n    vectorEnteros.push_back(2);\r\n    vectorEnteros.push_back(92);\r\n    vectorEnteros.push_back(19);\r\n    vectorEnteros[3] = 29; //Modificar un elemento\r\n    printf(\"%d\\n\\n\\n\", vectorEnteros[0]); //Acceso a elementos\r\n    vectorEnteros.pop_back(); //Eliminar el último elemento\r\n    sort(vectorEnteros.begin(), vectorEnteros.end()); //Ordenar de menor a mayor\r\n\r\n\r\n    //Listas\r\n    list <int> listaEnteros;\r\n    listaEnteros.push_back(10); //Agregar un elemento al final\r\n    listaEnteros.push_back(20);\r\n    listaEnteros.push_front(15); //Agregar un elemento al principio\r\n    listaEnteros.push_front(5);\r\n    listaEnteros.pop_back(); //Quitar el último elemento\r\n    listaEnteros.pop_front(); //Quitar el primer elemento\r\n\r\n    //Diccionarios\r\n    map <string, string> diccionario;\r\n    diccionario[\"User\"] = \"m-doce\";\r\n    diccionario[\"Language\"] = \"C++\";\r\n\r\n\r\n*/"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/c++/xooseph.cpp",
    "content": "// Estructuras de datos\n\n#include <iostream>\n#include <vector>\n#include <list>\n#include <stack>\n#include <queue>\n#include <deque>\n#include <set>\n#include <map>\n#include <algorithm>\n\nusing namespace std;\n\nvoid arrays() {\n    string names[3] = {\"Joseph\", \"Miley\", \"Rick\"};\n    \n    cout << \"El segundo elemento del arreglo: \" << names[1] << endl;\n    cout << \"El primer elemento del arreglo: \" << names[0] << \",\" << endl;\n    \n    names[0] = \"Roberto\";\n    \n    cout << \"ahora es \" << names[0] << endl;\n}\n\nvoid vectors() {\n    vector<string> names = {\"Joseph\", \"Miley\", \"Rick\"};\n    \n    cout << \"El primer elemento del vector: \" << names.front() << endl;\n    cout << \"El segundo elemento del vector: \" << names[1] << endl; \n    // Preferencia usar para vectores porque hace saber si ocurrió un error\n    cout << \"El segundo elemento del vector: \" << names.at(1) << endl;\n    cout << \"El último elemento del vector: \" << names.back() << endl;\n    \n    names.back() = \"Ricardo\";\n    \n    cout << \"Ahora el último elemento es \" << names.at(2) << endl;\n\n    names.push_back(\"Alan\");\n    \n    cout << \"Se agregó un nuevo nombre: \" << names.back() << endl;\n\n    names.pop_back();\n\n    cout << \"El último elemento del vector: \" << names.back() << endl;\n}\n\nvoid lists() {\n    list<string> names = {\"Joseph\", \"Miley\", \"Rick\"};\n\n    cout << \"El primer elemento de la lista: \" << names.front() << endl;\n    cout << \"El último elemento de la lista: \" << names.back() << endl;\n\n    names.front() = \"Alan\";\n\n    cout << \"Ahora el primer elemento es \" << names.front() << endl;\n\n    names.push_front(\"Fil\");\n    names.push_back(\"Flor\");\n\n    cout << \"La lista completa:\" << endl;\n\n    for (string name : names) {\n        cout << name << endl;\n    }\n\n    names.pop_back();\n    names.pop_front();\n\n    cout << \"La lista completa:\" << endl;\n\n    for (string name : names) {\n        cout << name << endl;\n    }\n}\n\nvoid stacks() {\n    stack<string> names;\n\n    names.push(\"Rick\");\n    names.push(\"Joseph\");\n    names.push(\"Alan\");\n\n    cout << \"El primer elemento tomado de la pila: \" << names.top() << endl;\n\n    names.top() = \"Flor\";\n\n    cout << \"Ahora el primer elemento tomado de la pila es \" << names.top() << endl;\n\n    names.pop();\n\n    cout << \"Ahora el primer elemento tomado de la pila es \" << names.top() << endl;\n}\n\nvoid queues() {\n    queue<string> names;\n\n    names.push(\"Rick\");\n    names.push(\"Joseph\");\n    names.push(\"Alan\");\n\n    cout << \"El primer elemento de la queue: \" << names.front() << endl;\n    cout << \"El último elemento de la queue: \" << names.back() << endl;\n\n    names.front() = \"Gil\";\n\n    cout << \"Ahora el primer elemento de la queue es \" << names.front() << endl;\n\n    names.pop();\n\n    cout << \"Ahora el primer elemento de la queue es \" << names.front() << endl;\n}\n\nvoid dequeues() {\n    deque<string> names = {\"Rick\", \"Sam\", \"Joseph\"};\n    \n    cout << \"El primer elemento de la deque: \" << names.front() << endl;\n    cout << \"El último elemento de la deque: \" << names.back() << endl;\n\n    names.at(1) = \"Flor\";\n    names.push_back(\"Gil\");\n    names.push_front(\"Vale\");\n\n    for (string name : names) {\n        cout << name << endl;\n    }\n\n    names.pop_back();\n    names.pop_front();\n\n    for (string name : names) {\n        cout << name << endl;\n    }\n}\n\nvoid sets() {\n    set<string> namesAsc = {\"Rick\", \"Sam\", \"Joseph\", \"Rick\"};\n\n    for (string name : namesAsc) {\n        cout << name << endl;\n    }\n\n    set<float> numbers = {2.5, 10.3, 5.1, 1.3, -0.5};\n\n    for (float number : numbers) {\n        cout << number << endl;\n    }\n\n    set<string, greater<string>> namesDesc= {\"Rick\", \"Sam\", \"Joseph\"};\n\n    namesDesc.insert(\"Vale\");\n\n    for (string name : namesDesc) {\n        cout << name << endl;\n    }\n\n    cout << \"---------\" << endl;\n\n    namesDesc.erase(\"Rick\");\n\n    for (string name : namesDesc) {\n        cout << name << endl;\n    }\n\n    cout << \"---------\" << endl;\n\n    // Elimina todos los elementos\n    namesDesc.clear();\n\n    for (string name : namesDesc) {\n        cout << name << endl;\n    }\n\n    cout << \"---------\" << endl;\n}\n\nvoid maps() {\n    map<string, string> translations = {{\"hello\", \"hola\"}, {\"world\", \"mundo\"}, \n        {\"code\", \"código\"}};\n\n    cout << \"La traducción para 'hello' es \" << translations[\"hello\"] << endl;\n    cout << \"La traducción para 'world' es \" << translations[\"world\"] << endl;\n    // Se prefiere utilizar .at() porque lanzaría un error si no existe la key\n    cout << \"La traducción para 'code' es \" << translations.at(\"code\") << endl;\n\n    translations.at(\"hello\") = \"bonjour\";\n    cout << \"La traducción para 'hello' es \" << translations.at(\"hello\") << endl;\n\n    // Es correcto usar cualquiera de éstas para insertar nuevos key-value\n    translations[\"language\"] = \"lenguaje\";\n    translations.insert({\"syntax\", \"sintaxis\"});\n\n    cout << \"La traducción para 'language' es \" << translations.at(\"language\") << endl;\n    cout << \"La traducción para 'syntax' es \" << translations.at(\"syntax\") << endl;\n\n    translations.erase(\"language\");\n\n    for (auto translation : translations) {\n        cout << translation.first << \" - \" << translation.second << endl;\n    }\n\n    cout << \"---------\" << endl;\n\n    translations.clear();\n\n    for (auto translation : translations) {\n        cout << translation.first << \" - \" << translation.second << endl;\n    }\n\n    cout << \"---------\" << endl;\n}\n\nvoid algorithms() {\n    vector<string> names = {\"Miley\", \"Joseph\", \"Rick\"};\n\n    vector<string>::iterator it;            \n    \n    sort(names.begin(), names.end());\n\n    for (it = names.begin(); it != names.end(); it++) {\n        cout << *it << endl;\n    }\n\n    auto name = find(names.begin(), names.end(), \"Joseph\");\n\n    if (name != names.end()) {\n        cout << \"Joseph ha sido encontrado\" << endl;\n    } else {\n        cout << \"No se ha encontrado Joseph\" << endl;\n    }\n}\n\n/*\nEJERCICIO EXTRA\nCrea una agenda de contactos por terminal.\n- Debes implementar funcionalidades de búsqueda, inserción, actualización\n  y eliminación de contactos.\n- Cada contacto debe tener un nombre y un número de teléfono.\n- El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n  y a continuación los datos necesarios para llevarla a cabo.\n- El programa no puede dejar introducir números de teléfono no numéricos y con más\n  de 11 dígitos (o el número de dígitos que quieras).\n- También se debe proponer una operación de finalización del programa.\n*/\n\nmap<string, string> people;\n\nvoid showMenu() {\n    cout << \"1. Agregar nuevo contacto\" << endl;\n    cout << \"2. Buscar contacto\" << endl;\n    cout << \"3. Actualizar contacto\" << endl;\n    cout << \"4. Eliminar contacto\" << endl;\n    cout << \"5. Salir\" << endl;\n}\n\nbool isEmpty() {\n    return people.empty();\n}\n\nvoid addPerson() {\n    string name, telephone;\n    cout << \"Escribe el nombre: \";\n    cin >> name;\n    cout << \"Escribe el número de teléfono (debe ser de 10 dígitos): \";\n    cin >> telephone;\n\n    while (true) {\n        if (telephone.size() > 10 || telephone.size() < 10 ||\n        !all_of(telephone.begin(), telephone.end(), ::isdigit)) {\n            cout << \"El número de teléfono no es válido. Inserte uno nuevo: \";\n            cin >> telephone;\n        } else {\n            people.insert({name, telephone});\n            cout << \"Nuevo contacto agregado.\\n\";\n            break;\n        }\n    }\n}\n\nvoid findPerson() {\n    string name, telephone;\n\n    if (isEmpty()) {\n        cout << \"La agenda está vacía.\" << endl;\n    } else {\n        cout << \"Escribe el nombre: \";\n        cin >> name;\n\n        try {\n            telephone = people.at(name);\n\n            cout << \"Nombre: \" << name << \"\\nTeléfono: \" << telephone << endl;\n        } catch (out_of_range) {\n            cout << \"No existe el nombre en tu agenda de contactos.\" << endl;\n        }\n    }\n}\n\nvoid updatePerson() {\n    string name, telephone;\n\n    if (isEmpty()) {\n        cout << \"La agenda está vacía.\" << endl;\n    } else {\n        cout << \"Escribe el nombre: \";\n        cin >> name;\n\n        try {\n            people.at(name);\n\n            cout << \"Escribe el nuevo número de teléfono: \";\n            cin >> telephone;\n\n            while (true) {\n                if (telephone.size() > 10 || telephone.size() < 10 || \n                !all_of(telephone.begin(), telephone.end(), ::isdigit)) {\n                    cout << \"El número de teléfono no es válido. Inserte uno nuevo: \";\n                    cin >> telephone;\n                } else {\n                    people.at(name) = telephone;\n                    cout << \"Contacto actualizado.\" << endl;\n                    break;\n                }\n            }\n        } catch (out_of_range) {\n            cout << \"No existe el nombre en tu agenda de contactos.\" << endl;\n        }\n    }\n}\n\nvoid deletePerson() {\n    string name;\n\n    if (isEmpty()) {\n        cout << \"La agenda está vacía.\" << endl;\n    } else {\n        cout << \"Escribe el nombre: \";\n        cin >> name;\n\n        try {\n            people.at(name);\n            people.erase(name);\n\n            cout << \"Contacto eliminado.\" << endl;\n        } catch (out_of_range) {\n            cout << \"No existe el nombre en tu agenda de contactos.\" << endl;\n        }\n    }\n}\n\nvoid telcel() {\n    int inputMenu;\n    cout << \"Bienvenido a Telcel, qué deseas hacer hoy?\" << endl;\n\n    do {\n        cout << endl;\n        showMenu();\n        cin >> inputMenu;\n        cout << endl;\n\n        switch (inputMenu) {\n            case 1:\n                addPerson();\n                break;\n            case 2:\n                findPerson();\n                break;\n            case 3:\n                updatePerson();\n                break;\n            case 4:\n                deletePerson();\n                break;\n            case 5:\n                break;\n            default:\n                cout << \"Elige un valor válido, por favor.\" << endl;\n                break;\n        }\n    } while (inputMenu != 5);\n    \n}\n\nint main() {\n    cout << \"ARREGLOS\" << endl;\n    arrays();\n\n    cout << \"\\nVECTORES\" << endl;\n    vectors();\n\n    cout << \"\\nLISTAS\" << endl;\n    lists();\n\n    cout << \"\\nSTACKS\" << endl;\n    stacks();\n\n    cout << \"\\nQUEUES\" << endl;\n    queues();\n\n    cout << \"\\nDEQUEUES\" << endl;\n    dequeues();\n\n    cout << \"\\nSETS\" << endl;\n    sets();\n\n    cout << \"\\nMAPS\" << endl;\n    maps();\n\n    cout << \"\\nALGORITHMS\" << endl;\n    algorithms();\n    \n    cout << \"-------------------------------------\" << endl;\n\n    telcel();\n\n    return 0;\n}"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/cobol/any7dev.cbl",
    "content": "     /*\n      * EJERCICIO:\n      * - Muestra ejemplos de creacin de todas las estructuras soportadas por defecto en tu lenguaje.\n      * - Utiliza operaciones de insercin, borrado, actualizacin y ordenacin.\n      *\n      * DIFICULTAD EXTRA (opcional):\n      * Crea una agenda de contactos por terminal.\n      * - Debes implementar funcionalidades de bsqueda, insercin, actualizacin y eliminacin de contactos.\n      * - Cada contacto debe tener un nombre y un nmero de telfono.\n      * - El programa solicita en primer lugar cul es la operacin que se quiere realizar, y a continuacin\n      *   los datos necesarios para llevarla a cabo.\n      * - El programa no puede dejar introducir nmeros de telfono no nmericos y con ms de 11 dgitos.\n      *   (o el nmero de dgitos que quieras)\n      * - Tambin se debe proponer una operacin de finalizacin del programa.\n      */\n       IDENTIFICATION DIVISION.\n       PROGRAM-ID. RETO-03.\n       DATA DIVISION.\n       FILE SECTION.\n       WORKING-STORAGE SECTION.\n\n           01 TABLA.\n      * Es indexada para poder buscar\n               05 AGENDA OCCURS 25 TIMES INDEXED BY INDICE.\n                   10 NOMBRE PIC X(10).\n                   10 NUMERO PIC 9(9).\n\n           01 OPCIONES-MENU PIC X.\n               88 ALTA VALUE 1.\n               88 ACTUALIZAR VALUE 2.\n               88 QUITAR VALUE 3.\n               88 MUESTRA VALUE 4.\n               88 BUSCA VALUE 5.\n               88 SALE VALUE 0.\n\n           77 CONTADOR PIC 9 VALUE 0.\n           77 CONTADOR-AUX PIC 9 VALUE 1.\n           77 NOMBRE-AUX PIC X(10).\n           77 NOMBRE-NUEVO PIC X(10).\n           77 NUMERO-NUEVO PIC 9(9).\n           77 OPCION PIC 9.\n\n       PROCEDURE DIVISION.\n\n       EJERCICIO.\n            DISPLAY \"En cobol existen las tablas y tablas internas. \"-\n            \"Estas ultimas no se pueden modificar. Las tablas se \"-\n            \"pueden anidar.\"\n            DISPLAY \"Voy a utilizar el ejercicio de dificultad extra \"-\n            \"como ejemplo de las operaciones\".\n\n      *DIFICULTAD EXTRA\n       MENU.\n            DISPLAY SPACES\n            DISPLAY \"-----MENU-----\"\n            DISPLAY \"1 - Aadir\"\n            DISPLAY \"2 - Modificar\"\n            DISPLAY \"3 - Eliminar\"\n            DISPLAY \"4 - Mostrar agenda\"\n            DISPLAY \"5 - Buscar contacto\"\n            DISPLAY SPACES.\n            DISPLAY \"0 - SALIR\"\n            DISPLAY SPACES.\n\n            DISPLAY \"Selecciona una opcion:\"\n            ACCEPT OPCIONES-MENU.\n\n            EVALUATE TRUE\n\n                 WHEN ALTA\n                   IF CONTADOR = 0\n      *La tabla empieza por 1 y no por 0 como en otros lenguajes\n                       ADD 1 TO CONTADOR\n                   ELSE\n                       MOVE CONTADOR-AUX TO CONTADOR\n                   END-IF\n                   PERFORM AADIR\n\n                 WHEN ACTUALIZAR\n                  IF CONTADOR = 0\n                       DISPLAY \"No hay contactos en la agenda\"\n                  ELSE\n                       PERFORM MODIFICAR\n                  END-IF\n\n                 WHEN QUITAR\n                   IF CONTADOR = 0\n                       DISPLAY \"No hay contactos en la agenda\"\n                       PERFORM VOLVER-MENU\n                   ELSE\n                       PERFORM ELIMINAR\n\n                 WHEN MUESTRA\n                   IF CONTADOR = 0\n                       DISPLAY \"No hay contactos en la agenda\"\n                       PERFORM VOLVER-MENU\n                   ELSE\n                       PERFORM MOSTRAR\n                   END-IF\n\n                 WHEN BUSCA\n                   IF CONTADOR = 0\n                       DISPLAY \"No hay contactos en la agenda\"\n                       PERFORM VOLVER-MENU\n                   ELSE\n                       PERFORM BUSCAR\n                   END-IF\n\n                 WHEN SALE\n                   DISPLAY \"Saliendo...\"\n                   PERFORM SALIR\n\n                 WHEN OTHER\n                   DISPLAY \"Opcion invalida\"\n                   PERFORM VOLVER-MENU\n\n             END-EVALUATE.\n\n      *INSERCCION\n       AADIR.\n           IF CONTADOR < 25\n               DISPLAY \"Introduce el nombre:\"\n               ACCEPT NOMBRE(CONTADOR)\n               DISPLAY \"Introduce su numero:\"\n               ACCEPT NUMERO(CONTADOR)\n               DISPLAY SPACES\n               DISPLAY \"Contacto aadido\"\n               ADD 1 TO CONTADOR-AUX\n           ELSE\n               DISPLAY \"No se puede aadir contacto, agenda llena\"\n           END-IF\n           PERFORM VOLVER-MENU.\n\n       MOSTRAR.\n           MOVE 1 TO CONTADOR\n           DISPLAY SPACES\n           DISPLAY \"LOS CONTACTOS DE TU AGENDA SON:\"\n           PERFORM UNTIL CONTADOR = CONTADOR-AUX\n               DISPLAY AGENDA(CONTADOR)\n               ADD 1 TO CONTADOR\n           END-PERFORM.\n           DISPLAY SPACES\n           PERFORM VOLVER-MENU.\n\n\n      *BUSQUEDA\n       BUSCAR.\n           DISPLAY \"Dime el nombre del contacto a buscar:\"\n           ACCEPT NOMBRE-AUX.\n           SET INDICE TO 1\n           SEARCH AGENDA\n               AT END DISPLAY \"Contacto no encontrado\"\n                      PERFORM VOLVER-MENU\n               WHEN NOMBRE(INDICE) = NOMBRE-AUX\n                    DISPLAY \"El numero de \"NOMBRE-AUX\"es \"NUMERO(INDICE)\n                    PERFORM VOLVER-MENU\n           END-SEARCH.\n\n\n      *ACTUALIZACION\n       MODIFICAR.\n           DISPLAY \"Dime el nombre del contacto a modificar:\"\n           ACCEPT NOMBRE-AUX.\n           SET INDICE TO 1\n           SEARCH AGENDA\n               AT END DISPLAY \"Contacto no encontrado\"\n                      PERFORM VOLVER-MENU\n               WHEN NOMBRE(INDICE) = NOMBRE-AUX\n                    DISPLAY \"Que quieres cambiar?\"\n                    DISPLAY \"1-Nombre\"\n                    DISPLAY \"2-Numero\"\n                    ACCEPT OPCION\n                    IF OPCION = 1\n                        DISPLAY \"Dime el nuevo nombre:\"\n                        ACCEPT NOMBRE-NUEVO\n                        MOVE NOMBRE-NUEVO TO NOMBRE(INDICE)\n                        DISPLAY \"Nombre del contacto modificado\"\n                    ELSE\n                        IF OPCION = 2\n                           DISPLAY \"Dime el nuevo numero:\"\n                           ACCEPT NUMERO-NUEVO\n                           MOVE NUMERO-NUEVO TO NUMERO(INDICE)\n                           DISPLAY \"Numero del contacto modificado\"\n                        ELSE\n                           DISPLAY \"Opcion invalida\"\n                        END-IF\n                    END-IF\n                    DISPLAY SPACES\n                    PERFORM VOLVER-MENU\n           END-SEARCH.\n\n      *ELIMINACION\n       ELIMINAR.\n           DISPLAY \"Dime el nombre del contacto a borrar:\"\n           ACCEPT NOMBRE-AUX.\n           SET INDICE TO 1\n           SEARCH AGENDA\n               AT END DISPLAY \"Contacto no encontrado\"\n                      PERFORM VOLVER-MENU\n               WHEN NOMBRE(INDICE) = NOMBRE-AUX\n      *En COBOL no se eliminan los datos, se mueven los datos ms bajos de la tabla de ASCII\n                    MOVE LOW-VALUES TO AGENDA(INDICE)\n                    DISPLAY \"Contacto borrado\"\n                    PERFORM VOLVER-MENU\n           END-SEARCH.\n\n       VOLVER-MENU.\n           DISPLAY \"Volviendo al menu\"\n           PERFORM MENU.\n\n       SALIR.\n           STOP RUN.\n\n       END PROGRAM RETO-03.\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/cobol/keltoi-dev.cbl",
    "content": "       IDENTIFICATION DIVISION.\n       PROGRAM-ID. RETO-03.\n       ENVIRONMENT DIVISION.\n       CONFIGURATION SECTION.\n       SPECIAL-NAMES.\n           CLASS Decimal IS \"0\" THRU \"9\".\n       DATA DIVISION.\n       FILE SECTION.\n       WORKING-STORAGE SECTION.\n      * Declaracion de variables para ejemplos\n      * Las tablas se pueden anidar\n       01  TABLA-SIMPLE OCCURS 10 TIMES.\n           02 DATO PIC X(10).\n\n       77  I PIC 99 VALUE ZERO.\n\n      * Declaracion de variables para ejercicio extra\n      * Variables para opciones de menu\n       01  opcion-menu PIC X VALUE SPACE.\n           88 opc-alta VALUE \"A\" \"a\".\n           88 opc-baja VALUE \"B\" \"b\".\n           88 opc-consulta VALUE \"C\" \"c\".\n           88 opc-modificar VALUE \"M\" \"m\".\n           88 opc-salir VALUE \"S\" \"s\".\n\n      * Declaracion de Tabla\n       01  agenda OCCURS 100 TIMES DEPENDING ON indice\n           INDEXED BY puntero.\n           02 ag-indice PIC 99.\n           02 nombre PIC X(30).\n           02 telefono PIC X(13).\n\n      * Variables simples\n       77  contador PIC 99.\n       77  indice PIC 99 VALUE ZERO.\n       77  id-editar PIC 99.\n       77  auxiliar PIC X(13).\n\n      * Variables para selecciones\n       01  continuar PIC X VALUE SPACE.\n           88 cont-si VALUE \"S\" \"s\".\n           88 cont-no VALUE \"N\" \"n\".\n\n       01  seleccion PIC X VALUE SPACE.\n           88 sel-nombre VALUE \"N\" \"n\".\n           88 sel-telefono VALUE \"T\" \"t\".\n           88 sel-cancela VALUE \"C\" \"c\".\n\n       PROCEDURE DIVISION.\n      * La estructura mas parecida a los arrays, listas, diccionarios, etc.\n      * son las tablas y se declaran en WORKING-STORAGE\n\n       TABLAS.\n      * Carga de tabla\n           MOVE \"Juan\" TO DATO(1).\n           MOVE \"Paco\" TO DATO(2).\n           MOVE \"Maria\" TO DATO(3).\n           MOVE \"Ana\" TO DATO(4).\n           MOVE \"Jose\" TO DATO(5).\n\n      * Iterar la tabla y mostrar los datos en la pantalla\n           SET I TO 1\n           PERFORM 5 TIMES\n               DISPLAY TABLA-SIMPLE(I)\n               ADD 1 TO I\n           END-PERFORM.\n\n      * Modificar datos\n           MOVE \"Rocio\" TO DATO(2).\n           DISPLAY \"-- Modificamos el dato de la posicion 2\".\n           MOVE 1 TO I.\n           PERFORM Iterar-tabla 5 TIMES.\n\n      * Eliminar datos\n           MOVE LOW-VALUE TO DATO(5).\n           DISPLAY \"-- Eliminamos el dato de la posicion 5\".\n           MOVE 1 TO I.\n           PERFORM Iterar-tabla 5 TIMES.\n\n           PERFORM EJERCICIO-EXTRA.\n\n\n       Iterar-tabla.\n           DISPLAY DATO(I).\n           ADD 1 TO I.\n\n       EJERCICIO-EXTRA.\n      * Mostrar el menu de opciones\n           DISPLAY \"----- MENU AGENDA -----\".\n           DISPLAY \"A - Alta de contacto\".\n           DISPLAY \"B - Baja de contacto\".\n           DISPLAY \"M - Modificacion de contacto\".\n           DISPLAY \"C - Listado de contactos\".\n           DISPLAY \" \".\n           DISPLAY \"S - Salir de la agenda\".\n           ACCEPT opcion-menu.\n      * Controlador de opciones\n           IF opc-alta\n               PERFORM Alta-contacto\n           ELSE\n           IF opc-baja\n               PERFORM Baja-contacto\n           ELSE\n           IF opc-modificar\n               PERFORM Modifica-contacto\n           ELSE\n           IF opc-consulta\n               SET I TO 1\n               PERFORM Consulta-contacto UNTIL I > indice\n               DISPLAY \"Presione una tecla para continuar\"\n               ACCEPT continuar\n           ELSE\n           IF opc-salir\n               DISPLAY \"Ha salido de la agenda\"\n               STOP RUN\n           ELSE\n               DISPLAY \"La opcion seleccionada no es valida\".\n           PERFORM EJERCICIO-EXTRA.\n\n      * Altas de contacos\n       Alta-contacto.\n           DISPLAY \"--- ALTA DE CONTACTO ---\"\n           ADD 1 TO indice.\n           DISPLAY \"Ingrese un nombre:\"\n           ACCEPT nombre(indice).\n           PERFORM Alta-telefono.\n\n       Alta-telefono.\n           DISPLAY \"Ingrese el telefono (deben ser 13 digitos):\"\n           ACCEPT telefono(indice).\n           IF telefono(indice) IS NOT Decimal\n               DISPLAY \"El valor ingresado es incorrecto\"\n               PERFORM Alta-telefono\n           ELSE\n               MOVE indice TO ag-indice(indice)\n               DISPLAY \"Se ha guardado el contacto con el ID \" indice\n               DISPLAY \" \"\n               MOVE SPACE to continuar\n               DISPLAY \"Desea cargar otro contacto S=SI / N=NO\"\n               ACCEPT continuar\n               IF cont-si\n                   PERFORM Alta-contacto.\n\n      * Baja de contactos\n       Baja-contacto.\n           SET I TO 1.\n           PERFORM Consulta-contacto UNTIL I > indice.\n           DISPLAY \"Seleccione un ID de contaco para eliminar 0=Salir\"\n           ACCEPT id-editar.\n           IF id-editar <> 0\n               IF ag-indice(id-editar) <> 0\n                   PERFORM Baja-seleccion\n               ELSE\n                   DISPLAY \"El id seleccionado es incorrecto\"\n                   PERFORM Baja-contacto.\n\n       Baja-seleccion.\n           MOVE ZERO TO ag-indice(id-editar).\n           MOVE LOW-VALUE TO nombre(id-editar).\n           MOVE LOW-VALUE TO telefono(id-editar).\n           DISPLAY \"Se ha dado de baja al ID: \" id-editar.\n\n      * Modificacion de contactos\n       Modifica-contacto.\n           SET I TO 1.\n           PERFORM Consulta-contacto UNTIL I > indice.\n           DISPLAY \"Seleccione el ID de un contaco para editar 0=Salir\"\n           ACCEPT id-editar.\n           IF id-editar <> 0\n               IF ag-indice(id-editar) <> 0\n                   PERFORM Modifica-seleccion\n               ELSE\n                   DISPLAY \"El id seleccionado es incorrecto\"\n                   PERFORM Modifica-contacto.\n\n\n       Modifica-seleccion.\n           IF id-editar <= indice\n               DISPLAY \"Que va a editar N=Nombre T=Telefono C=Cancelar?\"\n               ACCEPT seleccion\n               IF sel-nombre\n                   DISPLAY \"Ingrese el nuevo Nombre:\"\n                   ACCEPT nombre(id-editar)\n                   DISPLAY \"Se ha modificado el Nombre\"\n               ELSE\n                   IF sel-telefono\n                       DISPLAY \"Ingrese el nuevo Telefono:\"\n                       ACCEPT auxiliar\n                       IF auxiliar IS Decimal\n                           MOVE auxiliar TO telefono(id-editar)\n                           DISPLAY \"Se ha modificado el telefono\"\n                       ELSE\n                           DISPLAY \"El valor ingresado es incorrecto\"\n                           PERFORM Modifica-seleccion\n                   ELSE\n                       IF sel-cancela\n                           DISPLAY \"Accion cancelada\"\n                       ELSE\n                           DISPLAY \"Seleccion incorrecta\"\n                           PERFORM Modifica-seleccion.\n\n      * Listado de contactos\n       Consulta-contacto.\n           IF ag-indice(I) <> ZERO\n               DISPLAY \"ID: \" ag-indice(I) \"-Nombre: \" nombre(I)\n                       \"  -Telefono: \" telefono(I).\n           ADD 1 TO I.\n\n       END PROGRAM RETO-03.\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/dart/D3rk1us.dart",
    "content": "import 'dart:collection';\nimport 'dart:io';\n\nvoid main() {\n\n/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n*/\n\n    // Lista\n\n    print('\\nList: ');\n    List<int> numeros = [2, 5, 6, 87, 12, 532];\n    print(numeros);\n\n    numeros.insert(0, 1); // Inserción\n    print(numeros);\n\n    numeros.remove(87); // Borrado\n    print(numeros);\n\n    numeros[3] = 601; // Actualización\n    print(numeros);\n\n    numeros.sort(); // Ordenar\n    print(numeros);\n\n    // Mapa\n\n    print('\\nMap:');\n    Map<String, String> puesto = {'Mateo': 'Gerente', 'Marta': 'Desarrolladora de Software', 'Dani': 'Ventas'};\n    print(puesto);\n\n    puesto['Juan'] = 'Becario'; // Inserción\n    print(puesto);\n\n    puesto.remove('Dani'); // Borrado\n    print(puesto);\n\n    puesto['Juan'] = 'Ventas'; // Actualización\n    print(puesto);\n\n    Map<String, String> puestoOrdenado = SplayTreeMap<String, String>.from(puesto, (a, b) => a.compareTo(b)); // Ordenar\n    print(puestoOrdenado);\n\n    // Conjunto\n\n    print('\\nSet: ');\n    Set<String> menu = {'Hamburgesa con queso', 'Patatas fritas', 'Resfresco a escoger'};\n    print(menu);\n\n    menu.add('Nuggets de pollo'); // Inserción\n    print(menu);\n\n    menu.remove('Patatas fritas'); // Borrado\n    print(menu);\n\n    /// Debido a que Set almacena datos únicos y no tiene un índice, la actualización directa no tiene una función.\n    /// Lo mismo sucede con ordenarlo, para poder hacerlo, se ha de convertir en List y luego utilizar sort().\n    \n    List<String> menuActualizado = menu.toList(); // Actualización\n    menuActualizado[1] = 'Pepsi';\n    print(menuActualizado);\n\n\n    List<String> menuOrdenado = menu.toList(); // Ordenar\n    menuOrdenado.sort();\n    print(menuOrdenado);\n \n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\n    Map<String, int> agenda = {};\n    bool exit = false;\n\n   while (!exit) {\n      print('Bienvenido a la agenda de contactos. \\n');\n      print('Opciones: \\n 1. Agregar \\n 2. Buscar \\n 3. Actualizar \\n 4. Eliminar \\n 5. Mostrar \\n 6. Salir\\n');\n      print('Indica el número de la opción a realizar: ');\n   \n      String? opcion = stdin.readLineSync();\n\n      switch (opcion) {\n         case '1':\n\n            print('Introduce el nombre: ');\n            String? name = stdin.readLineSync();\n\n            print('Introduce el número: ');\n            String? number = stdin.readLineSync();\n\n            if (name != null && number != null) {\n\n               try {\n\n                  int phone = int.parse(number);\n\n                  if('$phone'.length <= 11) {\n                     agregar(agenda, name, phone);\n                  } else {\n                     print('El número debe ser menor de 11 dígitos.');\n                  }\n\n               } catch (e) {\n                  print('Introduce un número válido.');\n               }\n            } else {\n               print('No se introdujo ningún número.');\n            }\n            break;\n         \n         case '2':\n            \n            print('Introduce el nombre del usuario que busca: ');\n            String? name = stdin.readLineSync();\n\n            if (name != null) {\n               buscar(agenda, name);\n            }\n            break;\n\n         case '3':\n            \n            print('Introduce el nombre: ');\n            String? name = stdin.readLineSync();\n            \n            print('Introduce el número a actualizar: ');\n            String? number = stdin.readLineSync();\n\n            if (number != null && name != null) {\n               try {\n                  int phone = int.parse(number);\n                  actualizar(agenda, name, phone);\n               } catch (e) {\n                  print('Introduce un número válido.');\n               }\n            }\n            break;\n         \n         case '4':\n            \n            print('Introduce el nombre del contacto a eliminar: ');\n            String? name = stdin.readLineSync();\n\n            if (name != null) {\n               eliminar(agenda, name);\n            }\n            break;\n         \n         case '5':\n            \n            mostrar(agenda);\n            break;\n\n         case '6':\n            \n            exit = true;\n            break;\n         \n         default:\n            print('Opción no válida.');\n      }\n   }\n}\n\n// Agregar\n\nvoid agregar(Map<String, int> agenda, String name, int phone) {\n    agenda[name] = phone;\n    print('Contacto agregado.');\n}\n\n// Buscar\n\nvoid buscar(Map<String, int> agenda, String name) {\n\n   if(agenda.containsKey(name)) {\n      'El número de $name es: ${agenda[name]}';\n   } else {\n      print('El contacto no existe');\n   }\n}\n\n// Actualizar\n\nvoid actualizar(Map<String, int> agenda, String name, int phone) {\n\n   if(agenda.containsKey(name)) {   \n      agenda[name] = phone;\n      print('Contacto atualizado.');\n   } else {\n      print('El contacto no existe.');\n   }\n}\n// Eliminar\n\nvoid eliminar(Map<String, int> agenda, String name) {\n   \n   if (agenda.containsKey(name)) {\n      agenda.remove(name);   \n   } else {\n      print('El contacto no existe.');\n   }\n}\n// Mostrar\n\nvoid mostrar(Map<String, int> agenda) {\n\n   if (agenda.isEmpty) {\n      print('La agenda está vacía.');\n   } else {\n      print(agenda);\n   }\n}"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/dart/Lia-M3dusa.dart",
    "content": "import 'dart:io';\n\nvoid main(List<String> args) {\n  // Listas\n  List<int> numeros = [1, 2, 3, 4, 5];\n  // Sets\n  Set<String> frutas = {'manzana', 'banana', 'naranja'};\n  // Mapas\n  Map<String, int> contactos = {};\n  int condition = 0;\n\n  try{do {\n    print('''\n    1. Agregar contacto\n    2. Eliminar contacto\n    3. Ver contactos\n    4. Buscar contacto\n    5. Salir\n  ''');\n\n    String? input = stdin.readLineSync();\n    if (input != null) {\n      condition = int.parse(input);\n    }\n\n    switch (condition) {\n      case 1:\n        print('Ingrese el nombre del contacto:');\n        String? nombre = stdin.readLineSync();\n        print('Ingrese el número del contacto:');\n        String? numero = stdin.readLineSync();\n        if (nombre != null && numero != null) {\n          contactos[nombre] = int.parse(numero);\n        }\n        break;\n      case 2:\n        print('Ingrese el nombre del contacto a eliminar:');\n        String? nombreEliminar = stdin.readLineSync();\n        if (nombreEliminar != null) {\n          contactos.remove(nombreEliminar);\n        }\n        break;\n      case 3:\n        print('Contactos:');\n        contactos.forEach((nombre, numero) {\n          print('$nombre: $numero');\n        });\n        break;\n      case 4:\n        print('Ingrese el nombre del contacto a buscar:');\n        String? nombreBuscar = stdin.readLineSync();\n        if (nombreBuscar != null && contactos.containsKey(nombreBuscar)) {\n          print('$nombreBuscar: ${contactos[nombreBuscar]}');\n        } else {\n          print('Contacto no encontrado');\n        }\n        break;\n      case 5:\n        print('Saliendo...');\n        break;\n      default:\n        print('Opción no válida');\n    }\n  } while (condition != 5);}\n  catch(e){\n    print('Error: $e');\n  }\n}"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/dart/bluefeatherdev.dart",
    "content": "/*\n* EJERCICIO:\n* - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n* - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n*\n* DIFICULTAD EXTRA (opcional):\n* Crea una agenda de contactos por terminal.\n* - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n* - Cada contacto debe tener un nombre y un número de teléfono.\n* - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n*   los datos necesarios para llevarla a cabo.\n* - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n*   (o el número de dígitos que quieras)\n* - También se debe proponer una operación de finalización del programa.\n*/\nimport 'dart:io';\n\nvoid listOperations(List myList) {\n  // default:\n  print(myList);  // [1, 2, 3]\n\n  // inserción:\n  myList.add(0);\n  print(myList);  // [1, 2, 3, 0]\n\n  // borrado:\n  myList.remove(2); \n  print(myList);  // [1, 3, 0] \n\n  // acceso:\n  print(myList[1]); // 3\n\n  // actualización:\n  myList[1] = 2; \n  print(myList); // [1, 2, 0]\n\n  // ordenación:\n  myList.sort();\n  print(myList);  // [0, 1, 2]\n}\n\nvoid setOperations(Set mySet) {\n  // default:\n  print(mySet);  // {'apple', 23, null}\n\n  // inserción:\n  mySet.add(true);\n  print(mySet);  // {apple, 23, null, true}\n\n  // borrado:\n  mySet.remove(null);\n  print(mySet);  // {apple, 23, true}\n\n  // acceso:\n  // no directamente\n\n  // actualización:\n  // no directamente\n  \n  // ordenación:\n  // no directamente\n}\n\nvoid mapOperations(Map myMap) {\n  // default:\n  print(myMap);  // {name: Jesús, birthYear: 2004, isCool: true}\n\n  // inserción:\n  myMap['eyeColor'] = 'brown';\n  print(myMap); // {name: Jesús, birthYear: 2004, isCool: true, eyeColor: brown}\n\n  // borrado:\n  myMap.remove('birthYear');\n  print(myMap); // {name: Jesús, isCool: true, eyeColor: brown}\n\n  // acceso:\n  print(myMap.keys);  // (name, isCool, eyeColor)\n  print(myMap.values);  // (Jesús, true, brown)\n  print(myMap.entries);  // (MapEntry(name: Jesús), MapEntry(isCool: true), MapEntry(eyeColor: brown))\n  print(myMap['name']); // Jesús\n\n  // actualización:\n  myMap['isCool'] = 'always';\n  print(myMap); // {name: Jesús, isCool: always, eyeColor: brown}\n\n  // ordenación:\n  // no directamente\n}\n\nvoid recordOperations((int, bool, String) myRecord) {\n  // default:\n  print(myRecord);  // (46, true, hello)\n\n  // inserción:\n  // no aplica\n\n  // borrado:\n  // no aplica\n\n  // acceso:\n  print(myRecord.$1);  // 46\n  print(myRecord.$2);  // true\n  print(myRecord.$3);  // hello\n\n  // actualización:\n  // no aplica\n  \n  // ordenación:\n  // no aplica\n}\n\n/// [DIFICULTAD EXTRA]:\nvoid agenda() {\n\n  Map agenda = {};\n  \n  void insertarContacto(String name) {\n    // Leer teléfono contacto nuevo\n    print('Ingrese el número de teléfono:');\n    String? phone = stdin.readLineSync();\n\n    // Validar que sean máximo 11 dígitos\n    var isDigit = RegExp(r'^\\d+$');\n    if (isDigit.hasMatch(phone!) && phone.length <= 11) {\n      // Insertar en agenda\n      agenda['${name}'] = int.parse(phone);\n      print('¡Datos guardados!');\n    } else {\n      print('Solo teléfonos numéricos de máximo de 11 dígitos...');\n    }\n  }\n\n  void verContactos() {\n    for (var name in agenda.keys) {\n      print('- $name: ${agenda['$name']}');\n    }\n  }\n\n  while (true) {\n    // Mostrar opciones en terminal\n    print('Agenda de Contactos:');\n    print('1. Buscar');\n    print('2. Insertar');\n    print('3. Actualizar');\n    print('4. Eliminar');\n    print('5. Ver todos');\n    print('6. Salir');\n\n    // Leer action del usuario\n    String? action = stdin.readLineSync();\n\n    // 1. Buscar contacto\n    if (action == '1') {\n      // Leer nombre a buscar en agenda\n      print('Ingrese nombre a buscar:');\n      String? name = stdin.readLineSync();\n      // Validar que exista\n      if (agenda['$name'] != null) {\n        print('Teléfono de $name: ${agenda['$name']}');\n      } else {\n        print('$name no es un contacto...');\n      } \n    }\n\n    // 2. Insertar contacto\n    else if (action == '2') {\n      // Leer nombre contacto nuevo\n      print('Ingrese nombre contacto nuevo:');\n      String? name = stdin.readLineSync();\n      insertarContacto(name!);\n    }\n\n    // 3. Actualizar contacto\n    else if (action == '3') {\n      // Leer nombre a buscar en agenda\n      print('Ingrese nombre contacto para actualizar:');\n      String? name = stdin.readLineSync();\n      // Validar que exista\n      if (agenda['$name'] != null) {\n        insertarContacto(name!);\n      } else {\n        print('$name no es un contacto...');\n      } \n    }\n\n    // 4. Eliminar contacto\n    else if (action == '4') {\n      // Leer nombre a buscar en agenda\n      print('Ingrese nombre a eliminar:');\n      String? name = stdin.readLineSync();\n      // Validar que exista\n      if (agenda['$name'] != null) {\n        agenda.remove('$name');\n        print('¡Contacto eliminado!');\n      } else {\n        print('$name no es un contacto...');\n      } \n    }\n\n    // 5. Ver contactos\n    else if (action == '5') verContactos();\n\n    // 6. Salir de agenda\n    else if (action == '6') {print('¡Hasta luego!'); break;}\n\n    // Validar input menú\n    else print('Opción inválida...'); \n  }\n}\n\nvoid main() {\n  /// 1. List\n  List myList = [1, 2, 3];\n  listOperations(myList);\n\n  /// 2. Sets\n  Set mySet = {'apple', 23, null};\n  setOperations(mySet);\n\n  /// 3. Maps\n  Map myMap = {\n    'name': 'Jesús',\n    'birthYear': 2004,\n    'isCool': true,\n  };\n  mapOperations(myMap);\n\n  /// 4. Records\n  (int, bool, String) myRecord = (46, true, 'hello');\n  recordOperations(myRecord);\n\n  /// [DIFICULTAD EXTRA]:\n  agenda();\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/dart/marinaortells.dart",
    "content": "/// URL del sitio web oficial: https://dart.dev/\n\nimport 'dart:io';\n\n\nvoid main() {\n\n\n/** \n * En dart, las estructuras de datos soportadas por defecto son:\n * Listas, Mapas, Sets, Strings, Números y Booleanos\n */\n\nfinal letters = <String>['a', 'b', 'c', 'd'];\nfinal numbers = <int>[3, 8, 4, 2023, 5];\nfinal empty = [];\n\n/// Operaciones sobre listas\nfinal fixedLists = List<String>.empty(growable: false); // Lista vacía y fija\nfinal listaFija2 = List<String>.filled(6, 'hola', growable:false); // Lista no vacía y fija\n\nletters.add('e'); // Añadir un elemento\nletters.addAll(['f', 'g', 'h', 'i']); // Añadir varios elementos al final de la lista\nnumbers.insert(1, 7); // Inserta un valor en la posición indicada\nnumbers.insertAll(0, [-9,-6,-2,-5]); // Inserta un array en la posición indicada\n\nnumbers[2] = 3; // Acceder al elemento y asignándole un nuevo valor\n\nnumbers.remove(0); // Quitar la primera ocurrencia del valor\nnumbers.removeAt(9); // Quitar el elemento en la posición indicada\nnumbers.removeRange(0, 7); // Eliminar los elementos desde la posición start hasta la posición end\nnumbers.removeLast(); // Elimina el último elemento\nnumbers.removeWhere((element) => element < 0); // Elimina todos los elementos que satisfacen el test\n\n\nfinal list1 = [1, 2, 3, 4];\nfinal list2 = [4, 2, 4];\nfinal suma = list1 + list2; // Concatenar listas\n\nvar index2 = letters.elementAt(2); // Devuelve el elemento en la posición 2\nvar firstElement = letters.first; // Devuelve el primer elemento\nvar lastElement = letters.last; // Devuelve el último elemento\nvar numbersLength = numbers.length; // Devuelve la longitud\nprint(numbers.isEmpty); // Devuelve True si está vacía\nprint(empty.isNotEmpty); // Devuelve True si no está vacía\n\n/// Operaciones sobre Mapas\n\nMap<String,dynamic> persona = {\n  'nombre': 'Marina',\n  'apellido': 'O',\n  'edad': 19,\n  'vive': true\n}; // <A,B>: A es el tipo de los puntos a la izquierda, que son tipo string\n/// B: es el tipo de lo de la derecha, que es dinámico\n\n\nprint(persona.keys); // Devuelve las llaves\nprint(persona.values); // Devuelve los valores\nprint(persona.length); // La longitud del mapa\nprint(persona.isEmpty); // Devuelve booleano si está vacío\nprint(persona.isNotEmpty); // Devuelve booleano si no está vacío\n\npersona.addAll({'carrera': 'INFADE', 'país':'España'}); // Añade más elementos al mapa\n// persona.clear(); // Borra todos los elementos\npersona.remove(0); // Borra una posición específica\npersona.forEach((k, v) => print('${k}:${v}')); // Aplica una función a todos los valores del mapa\n\n/// Operaciones sobre Sets\n/// La diferencia entre Sets y Listas es que los sets no tienen elementos repetidos\n\nvar countries1 = <String>{'España'}; // Forma 1 de declarar un set\nSet<String> countries2 = {'España'}; // Forma 2 de declarar un set\n\ncountries1.add('Francia'); //Añadir un elemento\ncountries1.addAll({'Alemania', 'Dinamarca'}); // Añadir varios elementos\nprint(countries1.elementAt(3)); // Elemento en índice indicado\nprint(countries1.length); // Longitud del set\nprint(countries1.contains('España')); // Devuelve booleano si el elemento está\nprint(countries1.remove('Alemania'));\ncountries1.forEach((name) {\n  print(name); // Imprimir todos los elementos del set\n});\ncountries2.clear(); // Borrar todos los elementos del set\n\n/// Dificultad extra\n\nMap<String,dynamic> agenda = {\n  'Roberto': '573829572',\n  'Susana': '829102948',\n  'María': '729402857'\n};\n\nprint(\"Binvenid@ a tu agenda virtual\");\n\n\nvar solicitud; \n\ndo {\n  print('''¿Qué quieres hacer?: \n  1. Añadir | 2. Buscar | 3. Eliminar | 4. Mostrar | 5. Exit''');\n\n  solicitud = stdin.readLineSync();\n\n  if ((solicitud == '1') || (solicitud == 'Añadir')) {\n    print(\"Introduzca el nombre de la persona a la que quiera añadir: \");\n    String? nombre = stdin.readLineSync();\n    print(\"Introduzca su número de teléfono: \");\n    String? numero;\n    while (true) {\n      numero = stdin.readLineSync();\n      if (numero!.length == 9) {\n        break;\n      } else {\n        print(\"El número no tiene 9 dígitos\");\n      }\n    }\n    agenda.addAll({ '${nombre}': '${numero}'});\n\n  } else if ((solicitud == '2') || (solicitud == 'Buscar')) {\n    \n    print(\"Introduzca el nombre de la persona que está buscando: \");\n    String? buscarNombre = stdin.readLineSync();\n    if (agenda.containsKey(buscarNombre)) {\n      print(agenda[buscarNombre]);\n    } else {\n      print(\"Ese nombre no está en la agenda\");\n    }\n\n  } else if ((solicitud == '3') || (solicitud == 'Eliminar')) {\n    print(\"Introduzca el nombre de la persona que quiere eliminar de la agenda: \");\n    String? eliminarNombre = stdin.readLineSync();\n    if (agenda.containsKey(eliminarNombre)) {\n      agenda.remove(eliminarNombre);\n    } else {\n      print(\"Ese contacto no existía en tu agenda\");\n    }\n  } else if ((solicitud == '4') || (solicitud == 'Mostrar')) {\n    agenda.forEach((k, v) => print('Persona: ${k}, Contacto: ${v}'));\n  } else if ((solicitud == '5') || (solicitud == 'Exit')) {\n    print(\"¡Nos vemos a la próxima!\");\n    false;\n  } else {\n    print(\"Indique de nuevo la solicitud\");\n  }\n} while (true);\n\n\n\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/dart/raulfauli.dart",
    "content": "import 'dart:io';\n\n/// 03 ESTRUCTURAS DE DATOS\n\nvoid main() {\n  /*\n    Estrucutras de datos nativas de Dart\n    Operaciones: inserción, borrado, actualización y ordenación\n  */\n  final languages = ['Dart', 'Java', 'Kotlin', 'Swift'];\n  print('List $languages');\n  print('Length: ${languages.length}');\n  print('Type of languages: ${languages.runtimeType}'); // List<String>\n\n  languages.add('Dart'); // Añadir un elemento\n  languages.addAll(['C#', 'Python']); // Añadir varios elementos\n  languages.insert(0, 'Rust'); // Añadir un elemento en un índice\n  languages.insertAll(1, ['C++', 'C']); // Añadir varios elementos en un índice\n\n  languages.remove('Java'); // Eliminar un elemento\n  languages.removeAt(1); // Eliminar un elemento por índice\n  languages.removeLast(); // Eliminar el último elemento\n  languages.removeRange(0, 2); // Eliminar un rango de elementos\n  languages.removeWhere((element) => element.length <= 2); // Eliminar por condición\n\n  languages[0] = 'C#'; // Reemplazar un elemento\n  languages.replaceRange(1, 3, ['C++', 'C']); // Reemplazar un rango de elementos\n\n  languages.sort(); // Ordenar alfabéticamente\n  languages.shuffle(); // Mezclar la lista\n  languages.reversed; // Invertir la lista\n  languages.sort((a, b) => a.length.compareTo(b.length)); // ordenar por longitud de cadena\n  print('Ordenado por longitud: $languages');\n\n  final uniqueLang = {'Dart', 'Java', 'Kotlin', 'Swift'};\n  print('Set $uniqueLang');\n  print('Length: ${uniqueLang.length}');\n  print('Type of uniqueLang: ${uniqueLang.runtimeType}'); // Set<String>\n\n  uniqueLang.add('Dart'); // Añadir un elemento sin repetir\n  print(uniqueLang);\n  // ...Misma sintaxis que las listas\n\n  final locales = {'es': 'Español', 'en': 'Inglés', 'fr': 'Francés'};\n  print('Map $locales');\n  print('Length: ${locales.length}');\n  print('Type of locales: ${locales.runtimeType}'); // Map<String, String>\n\n  locales['de'] = 'Alemán'; // Añadir un elemento\n  locales.addAll({'it': 'Italiano', 'pt': 'Portugués'}); // Añadir varios elementos\n  locales.putIfAbsent('ca', () => 'Catalán'); // Añadir un elemento si no existe\n\n  locales.update('es', (value) => 'Castellano'); // Actualizar un elemento\n  locales.updateAll((key, value) => value.toUpperCase()); // Actualizar todos los elementos\n\n  locales.remove('fr'); // Eliminar un elemento\n  locales.removeWhere((key, value) => value.length <= 7); // Eliminar por condición\n  print(locales);\n\n  final person = {\n    'name': 'Raul',\n    'phone': 666666666,\n    'weight': 75.5,\n    'subscribed': true,\n  };\n  print('Object $person');\n  print('Length: ${person.length}');\n  print('Type of person: ${person.runtimeType}'); // Map<String, dynamic>\n\n  person['age'] = 35;\n  person.addAll({'height': 1.75, 'married': true});\n  person.remove('married');\n  person.removeWhere((key, value) => value is double);\n  print(person);\n\n  final position = ('GPS', x: 10, y: 20);\n  print('Record $position');\n  print('Type of tupla: ${position.runtimeType}'); // (String, {int x, int y})\n\n  print(position.$1); // Prints 'GPS'\n  print(position.x); // Prints 10\n  print(position.y); // Prints 20\n\n  // Se trata como una variable y por tanto inmutable\n  // position.$1 = 'GPRS'; // Error\n  final position2 = ('GPS', x: 10, y: 20);\n  print(position == position2); // true\n\n  /*\n   EXTRA: Crea una agenda de contactos por terminal.\n  */\n  final contacts = <String, BigInt>{};\n  int? option = 0;\n  do {\n    print('''\n    1. Añadir contacto\n    2. Eliminar contacto\n    3. Buscar contacto\n    4. Listar contactos\n    5. Salir\n    ''');\n    option = int.tryParse(stdin.readLineSync()!);\n\n    switch (option) {\n      case 1:\n        String name = writeName();\n        BigInt? phone = writePhone();\n        if (phone == null) {\n          print('Teléfono incorrecto');\n          break;\n        }\n        contacts[name] = phone;\n        break;\n      case 2:\n        String name = writeName();\n        if (!contacts.containsKey(name)) {\n          print('Contacto no encontrado');\n        } else {\n          contacts.remove(name);\n          print('Contacto eliminado');\n        }\n        break;\n      case 3:\n        String name = writeName();\n        BigInt? phone = contacts[name];\n        if (phone == null) {\n          print('Contacto no encontrado');\n          break;\n        } else {\n          print('Teléfono: $phone');\n        }\n        break;\n      case 4:\n        for (final entry in contacts.entries) {\n          print('${entry.key}: ${entry.value}');\n        }\n        break;\n      case 5:\n        print('Programa finalizado');\n        break;\n      default:\n        print('Opción incorrecta');\n    }\n  } while (option != 5);\n}\n\nbool isNumeric(String s) {\n  // Todo: Bigint falla si introduces un caracter no numérico\n  return BigInt.tryParse(s) != null;\n}\n\nString writeName() {\n  print('Nombre: ');\n  // si es nulo, vuelvo a pedirlo\n  String? name;\n  do {\n    name = stdin.readLineSync();\n  } while (name == null || name.trim().isEmpty);\n\n  return name.trim();\n}\n\nBigInt? writePhone() {\n  print('Teléfono: ');\n  final phoneStr = stdin.readLineSync()!;\n  if (isNumeric(phoneStr) && phoneStr.length < 9) {\n    return null;\n  }\n  return BigInt.parse(phoneStr);\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/dart/teren91.dart",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n *   y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n *   y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más\n *   de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.\n */\n\n// Estructuras de datos soportadas por defecto en Dart:\n// - List\n// - Set\n// - Map\n\nimport 'dart:io';\n\nvoid main() {\n  listExample();\n  setExample();\n  mapExample();\n\n  // Agenda de contactos\n  agendaContactos();\n}\n\n// List - example insert, delete, update, sort\nvoid listExample() {\n  List<int> list = [2, 5, 3, 2, 1];\n  print('\\n----- LIST -----:');\n  print('Initial list:' + list.toString());\n\n  // Insert\n  list.add(6);\n  print('Insert result:' + list.toString());\n\n  // Delete\n  list.remove(6);\n  print('Delete result:' + list.toString());\n\n  // Update\n  list[0] = 0;\n  print('Update result:' + list.toString());\n\n  // Sort\n  list.sort();\n  print('Sort list result:' + list.toString());\n}\n\n//Set - example insert, delete, update, sort\nvoid setExample() {\n  Set<int> set = {2, 5, 3, 4, 1};\n  print('\\n----- SET -----:');\n  print('Initial set:' + set.toString());\n\n  // Insert\n  set.add(6);\n  print('Insert result:' + set.toString());\n\n  // Delete\n  set.remove(6);\n  print('Delete result:' + set.toString());\n\n  // Update\n  // set[0] = 0; // Error: Unhandled exception:\n  // Unsupported operation: Cannot modify an unmodifiable set\n  print('Update result: Cannot modify an unmodifiable set');\n\n  // Sort\n  // set.sort(); // Error: Unhandled exception:\n  // Unsupported operation: Cannot sort an unmodifiable set\n  print('Sort set result: Cannot sort an unmodifiable set');\n}\n\n//Map - example insert, delete, update, sort\nvoid mapExample() {\n  Map<int, String> map = {1: 'one', 2: 'two', 3: 'three'};\n   print('\\n----- MAP -----:');\n  print('Initial map:' + map.toString());\n\n  // Insert\n  map[4] = 'four';\n  print('Insert result:' + map.toString());\n\n  // Delete\n  map.remove(2);\n  print('Delete result:' + map.toString());\n\n  // Update\n  map.update(1, (value) => 'uno');\n  print('Update result:' + map.toString());\n\n  // Sort\n  // map.sort(); // Error: Unhandled exception:\n  // Unsupported operation: Cannot sort an unmodifiable map\n  print('Sort map result: Cannot sort an unmodifiable map');\n}\n\n\n//Agenda de contactos\nvoid agendaContactos() {\n  Map<String, BigInt> contacts = {};\n  int? option = 0;\n\n  do {\n    print('''\n    \n    --------------------\n      1. Add contact\n      2. Remove contact\n      3. Search contact\n      4. List contacts\n      5. Exit\n    --------------------\n    ''');\n    option = int.tryParse(stdin.readLineSync()!);\n\n    switch (option) {\n      case 1:\n        contacts.addAll(addContact());\n      case 2:\n        contacts = removeContact(contacts);\n      case 3:\n        searchContact(contacts);\n      case 4:\n        listContacts(contacts);\n      case 5:\n        print('Program finished');\n    }\n  } while (option != 5);\n\n  listContacts(contacts);\n}\n\nMap<String, BigInt> addContact() {\n  try {\n    print('Insert name:');\n    String name = stdin.readLineSync()!;\n\n    print('Insert phone:');\n    BigInt? phone = BigInt.tryParse(stdin.readLineSync()!);\n\n    if (phone == null) {\n      print('Incorrect phone');\n      return {};\n    }\n\n    return {name: phone};\n  } on Exception catch (e) {\n    e.toString();\n    return {};\n  }\n}\n\nMap<String, BigInt> removeContact(Map<String, BigInt> contacts) {\n  listContacts(contacts);\n  print('Insert name to remove:');\n  \n  try {\n    String name = stdin.readLineSync()!;\n\n    if (!contacts.containsKey(name)) {\n      print('Contact not found');\n      return contacts;\n    }\n\n    contacts.remove(name);\n\n    print('Contact removed');\n    return contacts;\n\n  } on Exception catch (e) {\n      e.toString();\n      return contacts; \n  }\n}\n\nvoid searchContact(Map<String, BigInt> contacts) {\n  print('Insert name to search:');\n  \n  try {\n  String name = stdin.readLineSync()!;\n  \n  if (!contacts.containsKey(name)) {\n    print('Contact not found');\n    return;\n  }\n  \n  print('phone: ' + contacts[name].toString());\n\n  return;\n\n} on Exception catch (e) {\n    e.toString();\n    return;\n}\n}\n\nvoid listContacts(Map<String, BigInt> contacts) {\n  print('Contacts:' + contacts.toString());\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/delphi/fduron.dpr",
    "content": "(*\n * EJERCICIO:\n * - Muestra ejemplos de creacin de todas las estructuras soportadas por defecto\n *   en tu lenguaje.\n * - Utiliza operaciones de insercin, borrado, actualizacin y ordenacin.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de bsqueda, insercin, actualizacin\n *   y eliminacin de contactos.\n * - Cada contacto debe tener un nombre y un nmero de telfono.\n * - El programa solicita en primer lugar cul es la operacin que se quiere realizar,\n *   y a continuacin los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir nmeros de telfono no nmericos y con ms\n *   de 11 dgitos (o el nmero de dgitos que quieras).\n * - Tambin se debe proponer una operacin de finalizacin del programa.\n *)\n\nprogram fduron;\n\n{$APPTYPE CONSOLE}\n\n{$R *.res}\n\nuses\n  System.SysUtils,\n  System.Generics.Collections;\n\ntype\n  TContacto = Record\n     Nombre,\n     Telefono: String;\n     RegistroActivo: Boolean;\n  end;\n\n  TRegistro = Record\n    Campo1: Integer;\n    Campo2: String;\n    Campo3: 1..20;\n    Campo4: String[40];\n  end;\n\n  TRegistroDefinido = record\n    Nombre, Apellido: string[40];\n    Nacimiento: TDate;\n    case SueldoAnual: boolean of\n      True: (MontoAnual: Currency);\n      False: (MontoMensual: Currency);\n  end;\n\n  TRegistroAvanzado = record\n    type\n      TNumeroDeColor = Integer;\n    var\n      FRojo: Integer;\n    class var\n      FAzul: Integer;\n    procedure imprimeRojo();\n    constructor Create(Val: Integer);\n    property Rojo: TNumeroDeColor read FRojo write FRojo;\n    class property Azul: TNumeroDeColor read FAzul write FAzul;\n  end;\n\n  TElementos = (Elemento1, Elemento2, Elemento3, Elemento4, Elemento5);\nvar\n  Conjunto: set of TElementos;\n  UnElemento: TElementos;\n  Arreglo: array [64..120] of Char;\n  Matriz: array[1..100,1..100] of Real;\n  ArregloDinamico: array of Real; //El tamao se define en tiempo de ejecusin\n  ArregloClase: TArray<integer>;\n  Registro: TRegistro;\n  RegistroAvanzado: TRegistroAvanzado;\n  UnDiccionario: TDictionary<string, TRegistro>;\n  PilaFIFO: TQueue<String>;\n  Lista: TList<Integer>;\n  PilaLIFO: TStack<String>;\n  //Dificultad Extra\n  Agenda: TList<TContacto>;\n\n/// <summary>\n///  Para el reto de dificultad extra se utiliza un TList por ser uno de los tipos\n///  de estructura mas basicos en Delphi (despus del Array simple), para cumplir\n///  con este reto se pueden utilizar clases, objetos, diccionarios o arreglos\n///  dinamicos con metodos que evaluen los campos del contacto. Sin embargo\n///  por ser de los primeros retos prefer omitit el uso de estructuras\n///  ms avanzadas ya que supongo que se vern mas adelante. F\n/// </summary>\nprocedure DificultadExtra;\n  procedure VerMenuPrincipal;\n  begin\n    WriteLn;\n    WriteLn('******************************************');\n    WriteLn('****       AGENDA DE CONTACTOS        ****');\n    WriteLn('******************************************');\n    WriteLn;\n    WriteLn('<?> Men de opciones');\n    WriteLn('------------------');\n    WriteLn('<A> Insertar');\n    WriteLn('<B> Buscar');\n    WriteLn('<C> Actualizar');\n    WriteLn('<D> Eliminar');\n    WriteLn('<L> Lista de contactos');\n    WriteLn('------------------');\n    WriteLn('<X> Salir');\n  end;\n\n  function ContactoCorrecto(const Contacto: TContacto): boolean;\n  begin\n    Result := True;\n    if Contacto.Nombre.IsEmpty then\n    begin\n      WriteLn('El nombre no puede estar vacio');\n      Result := False;\n    end;\n    if (Contacto.telefono.Length < 11) then\n    begin\n      for var I := 1 to Contacto.Telefono.Length do\n        if not (Contacto.Telefono[I] in ['0'..'9']) then\n        begin\n          WriteLn('#Solo se aceptan numeros en el campo telfono.');\n          Exit(False);\n        end;\n      end\n    else\n    begin\n      WriteLn('#El telefono no puede tener mas de 11 numeros');\n      Result := False;\n    end;\n  end;\n\n  /// <summary>\n  ///  se utiliza el metodo mas simple de busqueda, ya que la busqueda se realiza\n  ///  nicamente por el nombre no se utiliza BinarySearch, as que no es\n  ///  necesario que el arreglo este ordenado.\n  ///  En caso de que el NombreBuscado no exista se recorre\n  ///  el arreglo por completo, si NombreBuscado es localizado se detiene la\n  ///  busqueda y se regresa el Indice de la posicin donde se encontr\n  /// </summary>\n  /// <param name=\"NombreBuscado\">\n  ///   Nombre del contacto que se esta buscando\n  /// </param>\n  /// <param name=\"Indice\">\n  ///   Regresa la posicin donde se encontro el nombre o -1 en caso contrario\n  /// </param>\n  /// <returns>\n  ///   Verdadero si el nombre se encuentra en la agenda, Falso en caso contrario\n  /// </returns>\n  function NombreEncontrado(const NombreBuscado: String; var Indice: Integer): Boolean;\n  begin\n    Result := False;\n    Indice := -1;\n    for var Contacto in Agenda do //Extraer cada contacto de la agenda\n    begin\n      if Contacto.Nombre = NombreBuscado then\n      begin\n        Indice := Agenda.IndexOf(Contacto);\n        //se utiliza Exit(True); en lugar de Result := True; para romper el cilo for\n        Exit(True);\n      end\n    end;\n  end;\n\n  function InsertarContacto: Boolean;\n  var\n    Contacto: TContacto;\n    C: Char;\n    idx: Integer;\n  begin\n    Result := False;\n    Contacto.RegistroActivo := True;\n\n    WriteLn('-- Insertar contacto');\n    Write('Nombre: ');\n    ReadLn(Contacto.Nombre);\n    Write('Telfono: ');\n    ReadLn(Contacto.Telefono);\n    Write('Datos correctos? (S/N) ');\n    ReadLn(C);\n    if (UpperCase(C) = 'S') and ContactoCorrecto(Contacto) then\n    begin\n      if not NombreEncontrado(Contacto.Nombre, idx) then\n      begin\n        Agenda.Add(Contacto);\n        WriteLn('# Contacto \"', Contacto.Nombre, '\" agregado');\n        Result := True;\n      end\n      else\n      begin\n        WriteLn('# El contacto \"', Contacto.Nombre, '\" ya existe en la agenda');\n        Result := True;\n      end;\n    end;\n  end;\n\n  function BuscarContacto: boolean;\n  var\n    Contacto: TContacto;\n    Nombre: String;\n    Idx: Integer;\n  begin\n    WriteLn('-- Buscar un contacto');\n    Write('Nombre: ');\n    ReadLn(Nombre);\n    Result := NombreEncontrado(Nombre, Idx);\n    if Result then\n    begin\n      WriteLn('# Contacto encontrado:');\n      Contacto := Agenda[Idx];\n      WriteLn('Nombre: ', Contacto.Nombre, ', Telfono: ', Contacto.Telefono);\n    end\n    else\n      WriteLn('# El contacto \"', Nombre, '\" no se enuentra en la agenda')\n  end;\n\n  function ActualizarContacto: Boolean;\n  var\n    Contacto: TContacto;\n    Nombre: String;\n    Idx: Integer;\n    C: Char;\n  begin\n    WriteLn('-- Actualizar un contacto');\n    Write('Escriba el nombre del contacto: ');\n    ReadLn(Nombre);\n    if NombreEncontrado(Nombre, Idx) then\n    begin\n      Contacto := Agenda[Idx];\n      WriteLn('Nombre: ', Contacto.Nombre, ', Telfono: ', Contacto.Telefono);\n      Write('Nuevo nombre: ');\n      ReadLn(Contacto.Nombre);\n      Write('Nuevo Telfono: ');\n      ReadLn(Contacto.Telefono);\n      Write('Datos correctos? (S/N) ');\n      ReadLn(C);\n      if (UpperCase(C) = 'S') and ContactoCorrecto(Contacto) then\n      begin\n        Agenda[Idx] := Contacto;\n        Result := True;\n      end;\n    end\n    else\n      Write('# El contacto \"', Nombre, '\" no se encuentra en la agenda');\n  end;\n\n  function EliminarContacto: Boolean;\n  var\n    Nombre: String;\n    Idx: Integer;\n    C: Char;\n  begin\n    Result := False;\n    WriteLn('-- Eliminar un contacto');\n    Write('Escriba el nombre del contacto: ');\n    ReadLn(Nombre);\n    if NombreEncontrado(Nombre, Idx) then\n    begin\n      Write('Esta seguro de eliminar al contacto? (S/N) ');\n      ReadLn(C);\n      if UpperCase(C) = 'S' then\n      begin\n        Agenda.Delete(Idx);\n        WriteLn('# El contacto \"', Nombre, '\" Ha sido eliminado de la agenda');\n        Result := True;\n      end;\n    end\n    else\n      Write('# El contacto \"', Nombre, '\" no se encuentra en la agenda');\n  end;\n\n  procedure ListarContactos;\n  begin\n    WriteLn;\n    if Agenda.Count = 0 then\n      WriteLn('# No hay contactos en la agenda')\n    else\n    for var Contacto in Agenda do\n      WriteLn('Nombre: ', Contacto.Nombre, ', Telfono: ', Contacto.Telefono);\n\n    WriteLn;\n  end;\n\nvar\n  C: Char;\n  S: String;\nbegin\n  WriteLn;\n  Write('Deseas iniciar la agenda de contactos? (S/N) ');\n  ReadLn(C);\n  if UpperCase(C) = 'S' then\n  try\n    Agenda := TList<Tcontacto>.Create;\n    VerMenuPrincipal;\n    Repeat\n      WriteLn;\n      Write('Elija una opcin: ');\n      ReadLn(C);\n      {Convertir el contenido de la variable \"C\" a mayusculas, y obtener\n       solamente el primer caracter [1] para usarlo en la instruccin CASE}\n      C := UpperCase(C)[1];\n      case C of\n        'A': InsertarContacto;\n        'B': BuscarContacto;\n        'C': ActualizarContacto;\n        'D': EliminarContacto;\n        'L': ListarContactos;\n        '?': VerMenuPrincipal;\n      else\n        WriteLn('# Opcin incorrecta use ? para ver el men');\n      end;\n    Until C = 'X';\n  finally\n    Agenda.Free;\n  end;\nend;\n\n{ TRegistroAvanzado }\nconstructor TRegistroAvanzado.Create(Val: Integer);\nbegin\n  Rojo := Val;\nend;\n\nprocedure TRegistroAvanzado.imprimeRojo;\nbegin\n  WriteLn('Rojo: ', Rojo);\nend;\n\nvar\n  R, R2: TRegistro;\n  IndiceEncontrado: integer;\nbegin\n  Conjunto := [Elemento1, Elemento3, Elemento4];\n  UnElemento := Elemento1;\n  if UnElemento in Conjunto then\n    WriteLn('el contenido de la variable UnElemento se encuentra en la variable Conjunto')\n  else\n    WriteLn('el contenido de la variable UnElemento no se encuentra en la variable Conjunto');\n\n  //Agregar elementos al Arreglo\n  for var I := 64 to 120 do //Declaracin en linea de una variable \"I\"\n    Arreglo[I] := Chr(I);\n\n  WriteLn('Arreglo en la posicion 65 es ', Arreglo[65]);\n  WriteLn('Arreglo en la posicion 70 es ', Arreglo[70]);\n  WriteLn('Arreglo en la posicion 110 es ', Arreglo[110]);\n\n  SetLength(ArregloDinamico, 10);\n  for var I := Low(ArregloDinamico) to High(ArregloDinamico) do\n    ArregloDinamico[I] := I * 3.33;\n\n  WriteLn('ArregloDinamico en la posicin 5 es ', ArregloDinamico[5]);\n  WriteLn('ArregloDinamico en la posicin 9 es ', ArregloDinamico[9]);\n  WriteLn('ArregloDinamico en la posicin 8 es ', ArregloDinamico[8]);\n\n  R.Campo1 := 1;\n  R.Campo2 := 'Un nombre';\n  R.Campo3 := 10;\n  R.Campo4 := 'Texto adicional';\n\n  R2.Campo1 := 2;\n  R2.Campo2 := 'Nombre 2';\n  R2.Campo3 := 20;\n  R2.Campo4 := 'Texto adicional dos';\n\n  UnDiccionario := TDictionary<string, TRegistro>.Create;\n  ArregloClase := TArray<integer>.Create(100,250,28,57,110,2,44,68,25,215);\n  PilaFIFO := TQueue<String>.Create;\n  PilaLIFO := TStack<String>.Create;\n  Lista := TList<Integer>.Create;\n\n  try\n    //Agregar nuevos valores a UnDiccionario\n    UnDiccionario.Add('Uno', R);\n    UnDiccionario.Add('Dos', R2);\n    //Modificar valores a unDiccionario\n    R2.Campo2 := 'Nombre numero dos';\n    UnDiccionario.AddOrSetValue('Dos', R2);\n    //Eliminar valores de UnDiccionario\n    UnDiccionario.ExtractPair('Dos');\n    //TDictionary no se puede ordenar directamente\n    for var ElemDiccionario in UnDiccionario do\n      WriteLn('Diccionario: \"', ElemDiccionario.Key, '\"',\n        ' Campo1:', ElemDiccionario.Value.Campo1,\n        ' Campo2:', ElemDiccionario.Value.Campo2,\n        ' Campo3:', ElemDiccionario.Value.Campo3);\n\n    //Insertar elementos a la pilaFIFO\n    PilaFIFO.Enqueue('Texto 1');\n    PilaFIFO.Enqueue('Texto 2');\n    PilaFIFO.Enqueue('Texto 3');\n    PilaFIFO.Enqueue('Texto 4');\n    PilaFIFO.Enqueue('Texto 5');\n    WriteLn('El primer elementos de la PilaFIFO es: ', PilaFIFO.Peek);\n\n    //Extraer el primero de la pila \"Texto 1\"\n    PilaFIFO.Extract;\n    PilaFIFO.TrimExcess; //Ajustar la capacidad de la pila\n    WriteLn('PilaFIFO contiene ', PilaFIFO.Count, ' elementos');\n    //Limpiar la pila\n    PilaFIFO.Clear;\n\n    //Insertar elementos a la PilaLIFO\n    PilaLIFO.Push('Texto 1');\n    PilaLIFO.Push('Texto 2');\n    PilaLIFO.Push('Texto 3');\n    PilaLIFO.Push('Texto 4');\n    PilaLIFO.Push('Texto 5');\n    WriteLn('El ltimo elemento agregado a PilaLIFO es: ', PilaLIFO.Peek);\n\n    //Extraer el ultimo elemento de la pila \"Texto 5\"\n    PilaLIFO.Extract;\n    PilaLIFO.Pop;\n    PilaLIFO.TrimExcess; //Ajustar la capacidad de la pila\n    WriteLn('PilaLIFO contiene ', PilaLIFO.Count, ' elementos');\n    //Limpiar la pila\n    PilaLIFO.Clear;\n\n    //Ordenar ArregloClase\n    TArray.Sort<integer>(ArregloClase);\n    //buscar en ArregloClase\n    if TArray.BinarySearch<integer>(ArregloClase, 57, IndiceEncontrado) then\n      WriteLn('Elemento encontrado en ', IndiceEncontrado);\n\n    //Agregar elementos a Lista\n    Lista.AddRange([10,5,7,83,9,62,4,1,81,9,32,12,5,45,1]);\n    WriteLn('Indice del primer 1 en \"Lista\": ', Lista.IndexOf(1));\n    WriteLn('Indice del ultimo 1 en \"Lista\": ', Lista.LastIndexOf(1));\n    WriteLn('\"Lista\" contiene el numero 144 : ', Lista.Contains(144));\n\n    Write('Elementos en \"Lista\": ');\n    for var ItemLista in Lista do\n      Write(ItemLista, ', ');\n    WriteLn;\n\n    //Agregar elementos a Lista\n    Lista.Add(100);\n    Lista.Insert(0, 5);\n    Lista.InsertRange(0, [5,8,7,6,3]); //Insertar un rango a partir de la posicin 0\n    //Eliminar elementos\n    Lista.Delete(0); //Eliminar el elemento 0 de Lista\n    Lista.DeleteRange(0, 2); //Eleminar 2 elementos a partir del indice 0\n    Lista.Extract(1); //Remover los elementos 1 de Lista\n\n    Write('Elementos en \"Lista\": ');\n    for var ItemLista in Lista do\n      Write(ItemLista, ', ');\n    WriteLn;\n\n    //Ordenar Lista\n    Lista.Sort;\n    Write('Elementos ordenados en \"Lista\": ');\n    for var ItemLista in Lista do\n      Write(ItemLista, ', ');\n    WriteLn;\n\n    //Buscar\n    if Lista.BinarySearch(62, IndiceEncontrado) then\n      WriteLn('elemento 62 encontrado en la posicin ', IndiceEncontrado);\n\n    Lista.Reverse; //Invertir el orden\n\n  finally\n    UnDiccionario.Free;\n    PilaFIFO.Free;\n    Lista.Free;\n    PilaLIFO.Free;\n  end;\n\n  DificultadExtra;\nend.\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/ejercicio.md",
    "content": "# #03 ESTRUCTURAS DE DATOS\n> #### Dificultad: Media | Publicación: 15/01/24 | Corrección: 22/01/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/erlang/edalmava.erl",
    "content": "-module(edalmava).\n-export([listas/0, tuplas/0, listasProps/0, registros/0, mapas/0, extra/0]).\n-record(agenda, {nombre, telefono}).   % Estructura registro.  Se emplea esta directiva de preprocesamiento\n\n% Listas: vectores de información heterogénea.  Erlang maneja las listas como \n%         lenguaje de alto nivel\nlistas() ->\n    % Definición de una lista\n    Lista = [1, 2, 3, 4, 5],\n\n    % Agregar elementos a la lista\n    ListaA = Lista ++ [6, 7, 8, 9, 0], % [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]\n    % Sustraer elementos a la lista\n    ListaS = ListaA -- [0],            % [1, 2, 3, 4, 5, 6, 7, 8, 9]\n\n    % Extrayendo elementos de la cabecera dejando el resto en sublistas\n    [H | T] = ListaS,\n\n    io:format(\"Primer elemento: ~w~n\", [H]), % Primer elemento de la lista  % 1\n    io:format(\"Resto de la lista: ~w~n\", [T]). % Resto de la lista            % [2, 3, 4, 5, 6, 7, 8, 9]\n\n% TODO: Listas binarias\n% TODO: Listas E/S\n\n% Tuplas: tipos de datos organizativos.  A diferencia de las listas no pueden incrementar ni decrementar\n%         su tamaño salvo por la redefinición completa de su estructura o el uso de funciones específicas.  \n%         Se emplean para agrupar datos con un propósito específico.\ntuplas() ->\n    Tamano = 100,\n    Tupla = {\"Ruta\", \"Nombre\", Tamano},  % Tupla que guarda la información de un fichero\n\n    % Modificación dinámica de tuplas\n    % Cambiar un elemento de una tupla\n    TuplaM = erlang:setelement(1, Tupla, \"/home/edalmava/archivo.erl\"), % Cambiar el primer elemento\n    % Agregar un elemento al final de la tupla\n    TuplaA = erlang:append_element(TuplaM, {date(), time()}),           % Agregar la fecha de modificación\n    TuplaA2 = erlang:append_element(TuplaA, {date(), time()}),          % Agregar la fecha de modificación\n    % Eliminar un elemento de la tupla\n    TuplaE = erlang:delete_element(5, TuplaA2),                         % Eliminar el último elemento\n\n    io:format(\"~p~n\", [TuplaE]).\n\n% Listas de Propiedades: lista de tuplas de dos elementos: clave, valor.  Se gestiona mediante la librería\n%     proplists.  Son usadas para almacenar configuraciones\ndata() ->\n    [{path, \"/\"}, debug, {days, 7}].\nlistasProps() ->\n    io:format(proplists:get_value(debug, data())).   % Obtener el valor de debug \n\n% Registros: son un tipo específico de tupla  que facilita el acceso a los datos individuales dentro \n% de la misma mediante un nombre y una sintaxis de acceso mucho más cómoda para el programador. \nregistros() ->    \n    A = #agenda{nombre=\"Edalmava\", telefono=\"573100000000\"},\n    io:format(\"Nombre: \"),\n    io:format(A#agenda.nombre),\n    io:format(\"~nTeléfono: \"),\n    io:format(A#agenda.telefono),\n    A2 = {agenda, \"Pedro\", \"573101010100\"},\n    io:format(\"~nNombre: \"),\n    io:format(A2#agenda.nombre),\n    io:format(\"~nTeléfono: \"),\n    io:format(A2#agenda.telefono).\n\n% Mapas: son estructuras de datos.  Cada elemento se almacena bajo un índice o clave y contiene un valor.\n% El índice puede ser de cualquier tipo al igual que su contenido\nmapas() ->\n    % Definición de un mapa\n    M = #{nombre => \"Edalmava\"},\n    % Agregar datos a un mapa\n    M2 = M#{telefono => \"573100000000\"},\n    % Cambio sobre un índice existente\n    M3 = M2#{telefono := \"573150000000\"},\n    io:format(\"Nombre: \"),\n    io:format(maps:get(nombre, M3)),\n    io:format(\"~nTeléfono: \"),\n    io:format(maps:get(telefono, M3)).\n\n% RETO EXTRA\nbuscar() ->\n    \"\",\n    extra().\ninsertar() ->\n    \"\",\n    extra().\nactualizar() ->\n    \"\",\n    extra().\neliminar() -> \n    \"\",\n    extra().\nextra() ->\n    io:format(\"~n\"),\n    io:format(\"1. Buscar Contacto~n\"),\n    io:format(\"2. Insertar Contacto~n\"),\n    io:format(\"3. Actualizar Contacto~n\"),\n    io:format(\"4. Eliminar Contacto~n\"),\n    io:format(\"5. Salir~n\"),\n    Opcion = string:trim(io:get_line(\"Escoja una opción: \"), both, \"\\n\"),\n    case Opcion of\n        \"1\" -> buscar();\n        \"2\" -> insertar();\n        \"3\" -> actualizar();\n        \"4\" -> eliminar();\n        \"5\" -> ok;\n        _   -> extra()\n    end.  \n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/fortran/LeandroCFD.f90",
    "content": "program ARRAYS\n    implicit none\n\n    !Fortran permite la creación y manipulación de arreglos unidimensionales (vectores), bidimensionales (matrices) y\n    !tridimensionales (grillas). Es importante entender que Fortran al momento de compilar convierte todos los tipos de arreglos a\n    !arreglos unidimensionales. En Fortran es posible declarar los arreglos de forma estatica y de forma dinámica.\n    !Declaración de arreglos unidimensionales de forma estatica.\n    integer, dimension(5) :: vector1  !Declaración de un arreglo unidimensional de tipo integer que tiene dimensión 5.\n    integer :: vector5(5) !También es posible declarar un arreglo añadiendo las dimensiones al nombre del arreglo.\n    real, dimension(1:3) :: vector2 !Declaración de un arreglo unidimensional de tipo real que tiene dimensión 3 con indices 1 a 3\n    character(len=20), dimension(5) :: nombres !Declaración de un arreglo unidimensional de tipo character que tiene dimensión 5 y \n    !cada posición del arreglo tiene una longitud máxima de 20 caracteres.\n    complex, dimension(10:15) :: vector3 !Declaración de un arreglo unidimensional de tipo complex, dimensión 5 indices 10 a 15\n    logical, dimension(5:8) :: pruebas !!Declaración de un arreglo unidimensional de tipo logical que tiene dimensión 4 con \n    !indices 5 a 8\n\n    !Declaración de arreglos bidimensionales de forma estatica.\n    integer, dimension(5,3) :: matriz1  !Declaración de arreglo tipo integer que tiene dimensión 5 (filas) y 3 (columnas).\n    real, dimension(1:5,1:3) :: matriz2 !Declaración de arreglo tipo real que tiene dimensión 5 (filas) y 3 (columnas) \n    !con indices 1 a 5 y 1 a 3 respectivamente.\n    character(len=20), dimension(2:4,5:7) :: nombres1 !Declaración de arreglo tipo character que tiene dimensión 3 (filas) y \n    !3 (columnas) con indices 2 a 4 y 5 a 7 respectivamente, cada posición del arreglo tiene una longitud máxima de 20 caracteres.\n    complex, dimension(1:5,6) :: matriz3 !Declaración de arreglo tipo complex que tiene dimensión 5 (filas) y 6 (columnas) \n    !con indices 1 a 5 y sin asginación de indices para las columnas.\n    logical, dimension(2,2:6) :: pruebas1 !!Declaración de arreglo de tipo logical que tiene dimensión 2 (filas) y 5 (columnas) \n    !sin indices para las filas y con indices 2 a 6 para las columnas.\n\n    !Declaración de arreglos tridimensionales de forma estatica.\n    integer, dimension(4,3,5) :: tensor1  !Declaración de arreglo tipo integer que tiene dimensión 4 (filas) , 3 (columnas) y \n    !5 (matrices).\n    real, dimension(1:10,1:7,1:4) :: tensor2,tensor4,tensor5 !Declaración de arreglo tipo real que tiene dimensión 10 (filas) y\n    !7 (columnas) y 4 (matrices) con indices 1 a 10, 1 a 7 y 1 a 4 respectivamente.\n    character(len=20), dimension(2:5,5:7,5) :: nombres3 !Declaración de arreglo tipo character que tiene dimensión 4 (filas), \n    !3 (columnas) y 5 (matrices) con indices 2 a 4, 5 a 8 para filas y columnas y sin indices para las matrices, cada posición\n    !del arreglo tiene una longitud máxima de 20 caracteres.\n    complex, dimension(1:5,6,2:4) :: tensor3 !Declaración de arreglo tipo complex que tiene dimensión 5 (filas), 6 (columnas) y\n    !3 (matrices) con indices 1 a 5 y 2 a 4 para filas y matrices y sin asginación de indices para las columnas.\n    logical, dimension(2,2:6,4) :: pruebas2 !!Declaración de arreglo de tipo logical que tiene dimensión 2 (filas), 5 (columnas) y\n    !4 (matrices) sin indices para las filas y matrices y con indices 2 a 6 para las columnas.\n\n    !En algunas ocasiones no es posible saber apriori el tamaño de un arreglo, por lo tanto, Fortran permite la declaración\n    !de arreglos de forma dinámica con la opción allocatable.\n    integer,dimension(:),allocatable :: vector4 !Arreglo unidimensional\n    real,dimension(:,:),allocatable :: matriz4 !Arreglo bidimensional\n    \n    !Declaraciones de variables ejercicio extra\n    integer :: n,i,j,m\n    character (len=100) :: comparacion\n    type contacto\n        character (len=100) :: nombre\n        integer (kind=8):: telefono\n        integer :: ID\n    end type contacto\n\n    type (contacto), dimension(100) :: agenda \n\n    !La asignación de valores para los arreglos se puede realizar componente a componente.\n    vector1(2)=100 !Se le asigna un valor de 100 a la posición 2 del vector1.\n    vector2(3)=15.3 !Se le asigna un valor de 15.3 a la posición 3 del vector2.\n    nombres(1)=\"Lizeth\" !Se le asigna la cadena de texto \"Lizeth\" a la posición 1 del arreglo nombres.\n    vector3(13)=(2,5) !Se le asigna un valor de (2,5) a la posición 13 del vector3.\n    pruebas(7)=.true. !Se le asigna un valor true a la posición 7 del arreglo pruebas.\n\n    !También es posible asignar un arreglo de manera global de la siguiente manera.\n    vector5=(/6,7,8,9,10/) !la asignación se realiza con los delimitadores / / y los valores deben ir separados por coma.\n    print*,vector1\n    matriz1=reshape([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],[5,3]) !Para arreglos multidimensionales se debe utilizar la función \n    !reshape que convierte un arreglo unidimensional en uno multidimnesional, Los valores dentro de los parentesis [] son los\n    !valores del arreglo y el segundo parentesis las dimensiones.\n    print*,matriz1 !Aunque es una matriz fortran lo imprime como un vector, esto debido a que Fortran solo utiliza arreglos \n    !unidimensionales.\n    matriz2=reshape([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],[5,3])\n    print*,matriz2(1,:) !Es posible imprimir una sola fila.\n    print*,matriz2(:,1) !Es posible imprimir una sola columna.\n    nombres1=\"Juan\" !Es posible asignar un valor a todos los componentes de un arreglo.\n    matriz3(2,:)=(5,3) !Es posible asignar un valor a todos los componentes de una fila en un arreglo.\n    pruebas1(:,3)=.false. !Es posible asignar un valor a todos los componentes de una columna en un arreglo.\n    tensor1(:,:,3)=100 !Es posible asignar un valor a todos los componentes de la matriz de un arreglo tridimensional.\n\n    !Operaciones aritmeticas\n    tensor4=2\n    tensor5=5\n    tensor2=tensor4*tensor5 !multiplicación elemento a elemento de dos tensores\n    tensor2=sqrt(tensor4)\n\n    !Intrucciones de control con arreglos\n    where (tensor1==100) nombres3=\"Valor\" !La instrución where permite asignar el valor a el arreglo nombres3 en las posiciones\n    !donde tensor1==100.\n    pruebas2=.true.\n    pruebas=all(pruebas2) !La instrucción all devuelve un .true. si todos los elementos de pruebas2 son .true.\n    print*,pruebas\n    pruebas2=.false.\n    pruebas=any(pruebas2) !La instrucción any devuelve un .true. si almenos un elemento de pruebas2 son .true.\n    print*,pruebas\n    tensor3=(5,3)\n\n    !Se le asigna el tamaño a los arreglos declarados dinámicamente con la sentencia allocate\n    allocate(vector4(vector1(1):10),matriz4(tensor1(1,2,2),3))\n\n    !Se destruye un arreglo con la sentencia deallocate\n    deallocate(matriz4)\n\n    !DIFICULTAD EXTRA\n    agenda%ID=0\n    menu : do i = 1, 100\n        print*,\"********************************************************\"\n        print*,\"                    MENU PRINCIPAL\"\n        print*,\"********************************************************\"\n        print*,\"********************************************************\"\n        print*,\"BIENVENIDO A TU PROGRAMA DE AGENDA DE CONTACTOS PERSONAL\"\n        print*,\"********************************************************\"\n        print*,\"\"\n        print*,\"Digite un numero entre las siguientes opciones: \"\n        print*,\"\"\n        print*,\"1. Agregar contacto\"\n        print*,\"2. Eliminar contacto\"\n        print*,\"3. Buscar contacto\"\n        print*,\"4. Actualizar contacto\"\n        print*,\"5. Ver todos los contactos\"\n        read*,n\n        select case (n)\n            case(1)\n                print*,\"Cada contacto tiene un número de identificación entre el 1 y el 100.\"\n                print*,\"Para agregar un contacto digite el número de identificación (ID) que usted desee:\"\n                read*,m\n                do  j= 1, 100\n                    if (m==agenda(j)%ID) then\n                        print*,\"Este ID ya se encuentra reservado, si desea actualizarlo digite 4 en el menu principal\"\n                        print*,\"\"\n                        cycle menu\n                    end if                    \n                end do\n                agenda(m)%ID=m      \n                print*,\"Ahora, escriba el nombre del contacto en minusculas:\"\n                read*,agenda(m)%nombre\n                print*,\"Ahora, escriba el número del contacto (no máximo de 11 digitos):\"\n                read*,agenda(m)%telefono\n                print*,\"\"\n                print*,\"**********************************\"\n                print*,\"Contacto guardado correctamente!!!\"\n                print*,\"**********************************\"\n                print*,\"\"\n                print*,\"ID             NOMBRE            TELEFONO\"\n                print'(X,I0,14X,A,13X,I0)',agenda(m)%ID,trim(agenda(m)%nombre),agenda(m)%telefono\n                print*,\"\"\n                print*,\"¿Si deseas volver al menu principal digita 1 si deseas salir digita 2:\"\n                read*,m\n                if ( m==1 ) then\n                    cycle menu\n                else if ( m==2 ) then\n                    print*,\"Gracias por utilizar nuestros servicios. Que tengas un bonito día!!!\"\n                    exit menu         \n                end if                 \n            case(2)\n                print*,\"Escriba el nombre del contacto que desea eliminar:\"\n                read*,comparacion\n                do j = 1, 100\n                    if (comparacion==agenda(j)%nombre) then\n                        agenda(j)%ID=0\n                        agenda(j)%nombre=\"\"\n                        agenda(j)%telefono=0\n                        print*,\"\"\n                        print*,\"***********************************\"\n                        print*,\"Contacto eliminado correctamente!!!\"\n                        print*,\"***********************************\"\n                        print*,\"\"\n                        print*,\"¿Si deseas volver al menu principal digita 1 si deseas salir digita 2:\"\n                        read*,m\n                        if ( m==1 ) then\n                            cycle menu\n                        else if ( m==2 ) then\n                            print*,\"Gracias por utilizar nuestros servicios. Que tengas un bonito día!!!\"\n                            exit menu         \n                        end if\n                    end if                \n                end do\n                print*,\"\"\n                print*,\"*************************\"\n                print*,\"Contacto NO encontrado!!!\"\n                print*,\"*************************\"\n                print*,\"\"\n                print*,\"Si deseas guardarlo como contacto nuevo digita 1 en el menu principal\"\n                print*,\"\"\n                cycle menu  \n            case(3)\n                print*,\"Escriba el nombre del contacto que deseas buscar:\"\n                read*,comparacion\n                do j = 1, 100\n                    if (comparacion==agenda(j)%nombre) then\n                        print*,\"\"\n                        print*,\"************************************\"\n                        print*,\"Contacto encontrado correctamente!!!\"\n                        print*,\"************************************\"\n                        print*,\"\"\n                        print*,\"ID             NOMBRE            TELEFONO\"\n                        print'(X,I0,14X,A,13X,I0)',agenda(j)%ID,trim(agenda(j)%nombre),agenda(j)%telefono\n                        print*,\"\"\n                        print*,\"¿Si deseas volver al menu principal digita 1 si deseas salir digita 2:\"\n                        read*,m\n                        if ( m==1 ) then\n                            cycle menu\n                        else if ( m==2 ) then\n                            print*,\"Gracias por utilizar nuestros servicios. Que tengas un bonito día!!!\"\n                            exit menu         \n                        end if\n                    end if                \n                end do\n                print*,\"\"\n                print*,\"*************************\"\n                print*,\"Contacto NO encontrado!!!\"\n                print*,\"*************************\"\n                print*,\"\"\n                print*,\"Si deseas guardarlo como contacto nuevo digita 1 en el menu principal\"\n                print*,\"\"\n                cycle menu                      \n            case(4)\n                print*,\"Escriba el nombre del contacto que desea actualizar:\"\n                read*,comparacion\n                do j = 1, 100\n                    if (comparacion==agenda(j)%nombre) then\n                        print*,\"Digite el nuevo ID:\"\n                        read*,agenda(j)%ID\n                        print*,\"Digite el nuevo nombre en minusculas:\"\n                        read*,agenda(j)%nombre\n                        print*,\"Digite el nuevo número de telefono (no máximo de 11 digitos)\"\n                        read*,agenda(j)%telefono\n                        print*,\"\"\n                        print*,\"***********************************\"\n                        print*,\"Contacto actualizado correctamente!!!\"\n                        print*,\"***********************************\"\n                        print*,\"\"\n                        print*,\"ID             NOMBRE            TELEFONO\"\n                        print'(X,I0,14X,A,13X,I0)',agenda(j)%ID,trim(agenda(j)%nombre),agenda(j)%telefono\n                        print*,\"\"\n                        print*,\"¿Si deseas volver al menu principal digita 1 si deseas salir digita 2:\"\n                        read*,m\n                        if ( m==1 ) then\n                            cycle menu\n                        else if ( m==2 ) then\n                            print*,\"Gracias por utilizar nuestros servicios. Que tengas un bonito día!!!\"\n                            exit menu         \n                        end if\n                    end if                \n                end do\n                print*,\"\"\n                print*,\"*************************\"\n                print*,\"Contacto NO encontrado!!!\"\n                print*,\"*************************\"\n                print*,\"\"\n                print*,\"Si deseas guardarlo como contacto nuevo digita 1 en el menu principal\"\n                print*,\"\"\n                cycle menu \n            case(5)\n                print*,\"Tus contactos son:\"\n                print*,\"\"\n                print*,\"ID             NOMBRE            TELEFONO\"\n                do j = 1,100\n                    if ( agenda(j)%ID/=0 ) then\n                        print*,\"\"\n                        print'(X,I0,14X,A,13X,I0)',agenda(j)%ID,trim(agenda(j)%nombre),agenda(j)%telefono             \n                    end if\n                end do\n                print*,\"\"\n                print*,\"¿Si deseas volver al menu principal digita 1 si deseas salir digita 2:\"\n                read*,m\n                    if ( m==1 ) then\n                        cycle menu\n                    else if ( m==2 ) then\n                        print*,\"Gracias por utilizar nuestros servicios. Que tengas un bonito día!!!\"\n                        exit menu         \n                    end if\n       end select     \n    end do menu\nend program ARRAYS"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/fortran/edalmava.f90",
    "content": "program estructuras\n    implicit none\n    ! Manejo de Arrays en Fortran\n    ! Los arrays en Fortran son variables multidimensionales que contienen más de un valor donde se \n    ! accede a cada valor utilizando uno o más índices.  En Fortran los arrays por defecto se inician en 1\n\n    ! Declaración de Arrays\n    ! Se pueden declarar arrays de cualquier tipo.  Hay dos notaciones para declarar variables array:\n    ! Usando el atributo dimension o añadiendo las dimensiones del array al nombre de la variable\n    ! TIPO, DIMENSION(dimensiones) :: nombre\n    ! TIPO, DIMENSION :: nombre(dimensiones)\n    ! TIPO :: nombre(dimensiones)\n\n    integer :: i, n\n\n    ! Declaración estática de Arrays o Tablas\n    \n    ! Array de una dimension\n    integer, dimension(10) :: array1\n    ! Una declaración de array equivalente\n    integer :: array2(10)\n\n    ! Array de dos dimensiones\n    integer, dimension(10, 10) :: array3\n\n    ! Limites inferior y superior de una dimensión\n    real :: array4(0:4)\n    real :: array5(-5:5)\n\n    integer, dimension (2,3) :: mat1 = reshape( (/ 1, 2, 3, 4, 5, 6/) , (/2,3/) )\n\n    ! Declaración dinámica de Arrays o Tablas\n\n    ! La creación de este tipo de tablas se hace en dos etapas:\n    ! 1. Declaración de la tabla mediante el atributo ALLOCATABLE, sin información sobre el\n    !    tamaño de la misma.\n    !        TIPO, ALLOCATABLE :: nombre_tabla(ind-dim)\n    !    donde ind-dim es la indicación sobre el número de dimensiones de la tabla.\n    ! 2. Cuando se desee crear la tabla, se usará la instrucción\n    !        ALLOCATE(nombre_tabla(dim))\n    \n    real*4, allocatable :: tabla(:, :)\n\n    ! Manejo de Tipos Derivados \n    type :: t_pair\n        integer :: i\n        real :: x\n    end type\n\n    type(t_pair) :: pair\n\n    ! Rebanado o corte de arrays - notación rebanado\n\n    array1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]  ! Constructor Array\n    array2 = [(i, i = 1, 10)]                 ! Bucle Do implícito \n\n    array4 = [1.0, 2.0, 3.0, 4.0, 5.0]\n    print *, array4(0)\n    print *, array4(4)\n    print *, mat1\n\n    print *, 'Array inicial: ', array1\n    array1(:) = 0                             ! Establece todos los elementos a cero\n    print *, 'Todos los elementos a cero: ', array1\n    array1(1:5) = 1                           ! Establece los primeros cinco elementos a 1\n    print *, 'Cinco primeros elementos a 1: ', array1\n    array1(6:) = 2                            ! Establece todos los elementos después de 5 a 2\n    print *, 'Cinco últimos elementos a 2: ', array1\n\n    print *, array2(1:10:2)   ! Imprime los elementos con índice impar\n    print *, array3(:,1)      ! Imprime la primera columna en un array 2D\n    print *, array2(10:1:-1)  ! Imprime un array en reverso\n\n    ! Declaración de una varibale type e inicialización de sus miembros\n   \n    pair%i = 1\n    pair%x = 0.5\n    print *, 't_pair i: ', pair%i, ' t_pair x : ', pair%x \n\n    print *, 'Dimensión de la matriz dinámica: '\n    read *, n\n    if (allocated(tabla) .eqv. .true.) then\n        allocate(tabla(n, n))\n    end if\n\nend program estructuras"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/gdscript/ElHacedorDeCosas.gd",
    "content": "#Estructuras de datos\n\n#En GDscript todo script tiene que estar asociado a una escena o nodo para poder ejecutarlo\n\nextends Node\n#La función _ready es una especial de GDScript que hace que la función se ejecute al momento de iniciar la ecena de forma automatica\n#y solo puede ser usada una vez por script\nfunc _ready(): #voy a utilizar esta función para llamar a todas las que haga a partir de ahora en este ejercicioç\n    ##Ejemplos de estructuras\n    #Arrays\n    print_un_array()\n    print_dos_array()\n    #Diccionario\n    print_diccionario()\n    print_var_array_en_diccionario()\n    ##Operaciones\n    #Incerción\n    incerción_en_array()\n    #Borrado\n    borrado_en_array()\n    #Actualización\n    actualizar_array()\n    #Ordenamiento\n    ordenar_array()\n\n\n\n##Ejemplos de estructuras\n#Array o arreglo\nvar mi_primer_array = [7, 0, \"hola\", true]\nvar array_estatico: Array[int] = [1, 2, 3 , 4, 1_800_70]\n\nfunc print_un_array() -> void:\n    print(mi_primer_array)\nfunc print_dos_array() -> void:\n    print(mi_primer_array + array_estatico)\n\n#Diccionario\nvar mi_primer_diccionario = {\n    \"hola\": 5,\n    7:\"hola\",\n    \"nose\": 1914,\n    1985: mi_primer_array, #puedes agregar una variable ya echa en el diccionario\n    \"array_en_diccionario\":[7, 57, \"lobo\"], #además de poder crear un nuevo array ya dentro del diccionario\n    }\n\nfunc print_diccionario() -> void:\n    print(mi_primer_diccionario)\nfunc print_var_array_en_diccionario() -> void:\n    print(mi_primer_diccionario[1985])\n\n\n##Operaciones\n#en este caso voy a hacerlo unicamente con los arrays, pero con los diccionarios es practicamente lo mismo\nvar array_de_operaciones: Array[String] = []\nvar array_adicional = [\"pollo\", \"manteca\", \"filistea\"]\n#Incerción\nfunc incerción_en_array() -> void:\n    array_de_operaciones.append(\"hola\")\n    print(array_de_operaciones)\n    array_de_operaciones.append(\"pato\")\n    print(array_de_operaciones)\n    array_de_operaciones.append(\"ganso\")\n    print(array_de_operaciones)\n    array_de_operaciones.append_array(array_adicional) #puedes insertar el contenido de un array en otro\n    print(array_de_operaciones)\n    print(array_adicional)\n    array_de_operaciones.insert(4, \"ganso\") #tambien puedes reemplazar un dato en la pocición deseada\n    print(array_de_operaciones)\n\n#Borrado\nfunc borrado_en_array() -> void:\n    array_de_operaciones.erase(\"hola\")\n    print(array_de_operaciones)\n    array_de_operaciones.erase(array_de_operaciones[0])\n    print(array_de_operaciones)\n\n#Actualización\nfunc actualizar_array() -> void:\n    array_de_operaciones[1] = \"merengue\"\n    print(array_de_operaciones)\n\n#Ordenamiento\nfunc ordenar_array() -> void:\n    array_de_operaciones.reverse() #sentido inverso\n    print(array_de_operaciones)\n    array_de_operaciones.sort() #de mayor a menor u orden alfabetico\n    print(array_de_operaciones)\n    array_de_operaciones.shuffle() #orden aleatorio\n    print(array_de_operaciones)\n\n\n##Extra\n#Por limitaciones del lenguaje y de la modalidad de la Road map no puedo hacer el extra\n#ya que requeriría crear un archivo de Escena para vincularlo con el script y poder ejecutarlo\n#además de que GDScript está pensado para usarse con el editor Godot para videojuegos y aplicaciones con entorno gráfico\n#desconozco de momento si hay alguna otra manera de hacerlo\n#todo esto sin contar mi desconocimiento sobre el uso de terminal con GDScript\n#si en algún momento a futuro encuentro la forma lo haré ya que es muy similar a lo que tendrías que hacer\n#en un lenguaje como Phyton cosa que es sencilla "
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/go/AmadorQuispe.go",
    "content": "package main\n\nimport (\n\t\"bufio\"\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n)\n\nfunc main() {\n\t//inserción, borrado, actualización y ordenación\n\t//==>Arrays, son estáticos y son del mismo tipo\n\tarr := [5]int{4, 2, 1, 3}\n\tfmt.Println(\"Array de tamaño 5 => \", arr)\n\t//borrado, actualización\n\tarr[4] = 5\n\t// Ordenación\n\tsort.Ints(arr[:])\n\tfmt.Println(\"Array de tamaño 5 ordenada => \", arr)\n\n\t//==>Matrices\n\tmatrix := [2][3]int{{1, 2, 3}, {4, 5, 6}}\n\tfmt.Println(\"matriz de 2 x 3 => \", matrix)\n\n\t//==>Slices, son dinámicos\n\tslice := []int{1, 2, 3, 4, 5}\n\tfmt.Println(\"Slice => \", slice)\n\t//insertar\n\tslice = append(slice, 6)\n\tfmt.Println(\"Con agregado al final => \", slice)\n\t//Modificación\n\tindexToUpdate := 2\n\tslice[indexToUpdate] = 89\n\tfmt.Println(\"Con el indice 2 actualizado =>\", slice)\n\t//Eliminación\n\tindexToRemove := 2\n\tslice = append(slice[:indexToRemove], slice[indexToRemove+1:]...)\n\tfmt.Println(\"Con el indice 2 eliminado =>\", slice)\n\n\t//Maps, clave : valor\n\tweekdays := map[int]string{1: \"Lunes\", 2: \"Martes\", 3: \"Miércoles\", 4: \"Jueves\", 5: \"Viernes\", 6: \"Sábado\", 7: \"Domingo\"}\n\tfmt.Println(\"Mapa => \", weekdays)\n\n\t//Structs, estructura de datos que nos permite agrupar datos de diferentes tipos\n\ttype person struct {\n\t\tname string\n\t\tage  int\n\t}\n\tp1 := person{\"Amador\", 32}\n\tfmt.Println(\"Struct => \", p1)\n\n\t//EXTRA\n\treader := bufio.NewReader(os.Stdin)\n\tagenda := NewAgenda()\n\n\tfor {\n\t\tfmt.Println(\"==============================\")\n\t\tfmt.Println(\"Agenda de Contactos\")\n\t\tfmt.Println(\"0. Listar Contactos\")\n\t\tfmt.Println(\"1. Agregar Contacto\")\n\t\tfmt.Println(\"2. Buscar Contacto\")\n\t\tfmt.Println(\"3. Actualizar Contacto\")\n\t\tfmt.Println(\"4. Eliminar Contacto\")\n\t\tfmt.Println(\"Escribe 'exit' para salir\")\n\t\tfmt.Println(\"==============================\")\n\t\tfmt.Print(\"Ingresa una opción: \")\n\t\toption, _ := reader.ReadString('\\n')\n\t\toption = strings.TrimSpace(option)\n\t\tif option == \"exit\" {\n\t\t\tbreak\n\t\t}\n\t\tswitch option {\n\t\tcase \"0\":\n\t\t\tfmt.Println(\"LISTA CONTACTOS :\")\n\t\t\tfor key, contact := range agenda.contacts {\n\t\t\t\tfmt.Println(key, \"->\", contact)\n\t\t\t}\n\t\tcase \"1\":\n\t\t\tfmt.Println(\"AGREGAR CONTACTO :\")\n\t\t\tvar name, phone string\n\t\t\tfmt.Print(\"Ingresa el nombre: \")\n\t\t\tname, _ = reader.ReadString('\\n')\n\t\t\tname = strings.TrimSpace(name)\n\t\t\tfmt.Print(\"Ingresa el # celular: \")\n\t\t\tphone, _ = reader.ReadString('\\n')\n\t\t\tphone = strings.TrimSpace(phone)\n\t\t\terr := agenda.addContact(name, phone)\n\t\t\tif err != nil {\n\t\t\t\tfmt.Println(err)\n\t\t\t} else {\n\t\t\t\tfmt.Println(\"Contacto agregado !\")\n\t\t\t}\n\n\t\tcase \"2\":\n\t\t\tfmt.Println(\"BUSCAR CONTACTO :\")\n\t\t\tfmt.Print(\"Ingresa el nombre de contacto a buscar: \")\n\t\t\tinputSearch, _ := reader.ReadString('\\n')\n\t\t\tinputSearch = strings.TrimSpace(inputSearch)\n\t\t\tphone, err := agenda.searchByName(inputSearch)\n\t\t\tif err != nil {\n\t\t\t\tfmt.Println(\"El contacto\", inputSearch, \"no se encuentra registrada\")\n\t\t\t} else {\n\t\t\t\tfmt.Println(\"Contacto encontrado : Nombre =\", inputSearch, \" Celular  =\", phone)\n\t\t\t}\n\t\tcase \"3\":\n\t\t\tfmt.Println(\"ACTUALIZAR CONTACTO :\")\n\t\t\tfmt.Print(\"Ingresa el nombre del contacto a actualizar: \")\n\t\t\tcontactToUpdate, _ := reader.ReadString('\\n')\n\t\t\tcontactToUpdate = strings.TrimSpace(contactToUpdate)\n\t\t\t_, err := agenda.searchByName(contactToUpdate)\n\t\t\tif err != nil {\n\t\t\t\tfmt.Println(\"El contacto\", contactToUpdate, \"no se encuentra registrada\")\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tfmt.Print(\"Ingresa el # celular del contacto a actualizar: \")\n\t\t\tphoneToUpdate, _ := reader.ReadString('\\n')\n\t\t\tphoneToUpdate = strings.TrimSpace(phoneToUpdate)\n\t\t\terr = agenda.addContact(contactToUpdate, phoneToUpdate)\n\t\t\tif err != nil {\n\t\t\t\tfmt.Println(err)\n\t\t\t} else {\n\t\t\t\tfmt.Println(\"Contacto agregado !\")\n\t\t\t}\n\t\tcase \"4\":\n\t\t\tfmt.Println(\"ELIMINAR CONTACTO :\")\n\t\t\tfmt.Print(\"Ingresa el nombre del contacto a eliminar: \")\n\t\t\tcontactToDelete, _ := reader.ReadString('\\n')\n\t\t\tcontactToDelete = strings.TrimSpace(contactToDelete)\n\t\t\t_, err := agenda.searchByName(contactToDelete)\n\t\t\tif err != nil {\n\t\t\t\tfmt.Println(\"El contacto\", contactToDelete, \"no se encuentra registrada\")\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tagenda.removeContact(contactToDelete)\n\t\t\tfmt.Println(\"Contacto eliminado !\")\n\t\t}\n\t}\n}\n\n// IMPLEMENTACIÓN DE AGENDA\n\ntype agenda struct {\n\tcontacts map[string]string\n}\n\nfunc NewAgenda() *agenda {\n\treturn &agenda{\n\t\tcontacts: map[string]string{},\n\t}\n}\n\nfunc (a *agenda) addContact(name, phone string) error {\n\tif _, err := a.searchByName(name); err == nil {\n\t\treturn errors.New(\"el contacto ya se encuentra registrada\")\n\t}\n\n\tif _, err := strconv.Atoi(phone); err != nil || len(phone) > 9 {\n\t\treturn errors.New(\"número de teléfono no válido, debe ser numérico y tener máximo 9 dígitos\")\n\t}\n\ta.contacts[name] = phone\n\treturn nil\n}\n\nfunc (a *agenda) searchByName(name string) (string, error) {\n\tphone, ok := a.contacts[name]\n\tif ok {\n\t\treturn phone, nil\n\t} else {\n\t\treturn \"\", errors.New(\"contacto no encontrado\")\n\t}\n}\n\nfunc (a *agenda) removeContact(name string) {\n\tdelete(a.contacts, name)\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/go/FreyFonseca117.go",
    "content": "// # #03 ESTRUCTURAS DE DATOS\n// > #### Dificultad: Media | Publicación: 15/01/24 | Corrección: 22/01/24\n\n// ## Ejercicio\n\n// ```\n// /*\n//  * EJERCICIO:\n//  * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n//  * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n//  *\n//  * DIFICULTAD EXTRA (opcional):\n//  * Crea una agenda de contactos por terminal.\n//  * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n//  * - Cada contacto debe tener un nombre y un número de teléfono.\n//  * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n//  *   los datos necesarios para llevarla a cabo.\n//  * - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n//  *   (o el número de dígitos que quieras)\n//  * - También se debe proponer una operación de finalización del programa.\n//  */\n// ```\n// #### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\n// Sigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n// > Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n\npackage main\n\nimport (\n\t\"fmt\"\n\t\"sort\"\n)\n\nfunc array() {\n\t// array inicial\n\tciudades := [3]string{\"carora\", \"barquisimeto\", \"valencia\"}\n\tfmt.Println(\"esto es el array inicial ===> \", ciudades)\n\n\t//aray despues de modificar\n\tciudades[2] = \"caracas\"\n\tfmt.Println(\"esto es el array modificado ===> \", ciudades)\n}\n\nfunc slice() {\n\t// slice inicial\n\tpaises := []string{\"rusia\", \"china\", \"venezuela\"}\n\tfmt.Println(\"esto es el slice inicial ===> \", paises)\n\n\t// modificacion del slice\n\tpaises[2] = \"venezuela modificada\"\n\tfmt.Println(\"esto es el slice inicial ===> \", paises)\n\n\t//agregando en el slice\n\tpaises = append(paises, \"chile\", \"peru\", \"argentina\")\n\tfmt.Println(\"esto es el slice con paises agregados ===> \", paises)\n\n\t//quitar elementos en el slice\n\t// buscando el index de peru\n\tvar index int\n\tfor i, pais := range paises {\n\t\tif pais == \"peru\" {\n\t\t\tindex = i\n\t\t\tbreak\n\t\t}\n\t}\n\tpaises = append(paises[:index], paises[index+1:]...)\n\tfmt.Println(\"esto es el slice con paises borrados ===> \", paises)\n\n\t//ordenando el slice\n\tsort.Strings(paises)\n\tfmt.Println(\"esto es el slice con paises ordenados ===> \", paises)\n\n\t// ordenando el slice de manera descendente\n\tsort.Sort(sort.Reverse(sort.StringSlice(paises)))\n\tfmt.Println(\"esto es el slice con paises ordenados de manera descendente ===> \", paises)\n\n}\n\nfunc agendaAdicional() {\n\n\t// variables y mapas\n\tagenda := make(map[string]int)\n\tagenda[\"frey\"] = 957985975\n\tagenda[\"zeoly\"] = 937639373\n\n\t//Ingresar el valor por consola\n\tvar nombre string\n\tvar numero int\n\tvar opcion int\n\n\t//verificacion de numero\n\tvalidarNumero := func(numero int) bool {\n\t\tif numero >= 100000000 && numero <= 999999999 {\n\t\t\treturn true\n\t\t} else {\n\t\t\treturn false\n\t\t}\n\t}\n\n\t// opciones que aparecen en la consola\n\tfor {\n\t\t// Validación para la opción ingresada\n\t\tfmt.Println(\"Marque una de las siguientes opciones\")\n\t\tfmt.Println(\"1. Para buscar un contacto\")\n\t\tfmt.Println(\"2. Para modificar un contacto\")\n\t\tfmt.Println(\"3. Para agregar un contacto\")\n\t\tfmt.Println(\"4. Para eliminar un contacto\")\n\t\tfmt.Println(\"5. Para mostrar todos los contactos\")\n\t\tfmt.Println(\"6. Para salir\")\n\n\t\t// Validar que la opción sea un número entero\n\t\t_, err := fmt.Scanln(&opcion)\n\t\tif err != nil || opcion < 1 || opcion > 6 {\n\t\t\tfmt.Println(\"Opción inválida. Por favor ingrese un número entre 1 y 6.\")\n\t\t\tcontinue\n\t\t}\n\n\t\t//Buscar contactos registrados\n\t\tswitch opcion {\n\t\tcase 1:\n\t\t\tfmt.Println(\"Por favor ingrese el nombre del contacto que desea buscar\")\n\t\t\tfmt.Scanln(&nombre)\n\t\t\tnumero, ok := agenda[nombre]\n\t\t\tif ok {\n\t\t\t\tfmt.Printf(\"El nombre del contacto es %s y su número es %d \\n\\n\", nombre, numero)\n\t\t\t} else {\n\t\t\t\tfmt.Printf(\"El contacto con nombre %s no está registrado\\n\", nombre)\n\t\t\t}\n\n\t\t//Modificar un contacto\n\t\tcase 2:\n\t\t\tfmt.Println(\"Ingrese por favor el nombre del contacto que desea modificar\")\n\t\t\tfmt.Scanln(&nombre)\n\t\t\tnumero, ok := agenda[nombre]\n\t\t\tif ok {\n\t\t\t\tfmt.Println(\"Por favor ingrese el nuevo número\")\n\t\t\t\t// Validación para el nuevo número\n\t\t\t\t_, err := fmt.Scanln(&numero)\n\t\t\t\tif err != nil || !validarNumero(numero) {\n\t\t\t\t\tfmt.Println(\"Número incorrecto. Debe ser un número válido de 9 dígitos.\")\n\t\t\t\t} else {\n\t\t\t\t\tagenda[nombre] = numero\n\t\t\t\t\tfmt.Printf(\"Se ha actualizado el número de %s \\n\", nombre)\n\t\t\t\t\tfmt.Printf(\"El nuevo número es: %d \\n\", numero)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfmt.Printf(\"El contacto con nombre %s no está registrado \\n\", nombre)\n\t\t\t}\n\n\t\t// Agregar un contacto\n\t\tcase 3:\n\t\t\tfmt.Println(\"Ingrese por favor el nombre del contacto que desea agregar\")\n\t\t\tfmt.Scanln(&nombre)\n\t\t\tfmt.Println(\"Ingrese por favor el número del contacto que desea agregar\")\n\t\t\t// Validación para el número\n\t\t\t_, err := fmt.Scanln(&numero)\n\t\t\tif err != nil || !validarNumero(numero) {\n\t\t\t\tfmt.Println(\"Número incorrecto. Debe ser un número válido de 9 dígitos.\")\n\t\t\t} else {\n\t\t\t\tagenda[nombre] = numero\n\t\t\t\tfmt.Printf(\"Se ha agregado el contacto %s con el número %d \\n\", nombre, numero)\n\t\t\t}\n\n\t\t// Eliminar un contacto\n\t\tcase 4:\n\t\t\tfmt.Println(\"Ingrese por favor el nombre del contacto que desea eliminar\")\n\t\t\tfmt.Scanln(&nombre)\n\t\t\t_, ok := agenda[nombre]\n\t\t\tif ok {\n\t\t\t\tdelete(agenda, nombre)\n\t\t\t\tfmt.Printf(\"Se ha eliminado el contacto %s \\n\", nombre)\n\t\t\t} else {\n\t\t\t\tfmt.Printf(\"El usuario %s no se encuentra registrado \\n\", nombre)\n\t\t\t}\n\n\t\t// Mostrar todos los contactos\n\t\tcase 5:\n\t\t\tif len(agenda) == 0 {\n\t\t\t\tfmt.Println(\"La agenda está vacía\")\n\t\t\t} else {\n\t\t\t\tfmt.Println(\"Estos son los contactos registrados:\")\n\t\t\t\tfor nombre, numero := range agenda {\n\t\t\t\t\tfmt.Printf(\"El contacto %s tiene el número %d \\n\", nombre, numero)\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Terminar programa\n\t\tcase 6:\n\t\t\tfmt.Println(\"Programa finalizado.\")\n\t\t\treturn\n\n\t\t// Valor por defecto\n\t\tdefault:\n\t\t\tfmt.Println(\"Por favor ingrese una opción válida.\")\n\t\t}\n\t}\n}\n\nfunc main() {\n\tarray()\n\tslice()\n\tagendaAdicional()\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/go/MiguelP-Dev.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"unicode\"\n)\n\n// ordenamiento de un sync.Map\n// Pair representa pares claves-valor\ntype Pair struct {\n\tkey   string\n\tvalue int\n}\n\n// PairList es un slice de pares\ntype PairList []Pair\n\n// Implementando la interface de ordenamiento para la pairList\nfunc (p PairList) Len() int {\n\treturn len(p)\n}\n\nfunc (p PairList) Swap(i, j int) {\n\tp[i], p[j] = p[j], p[i]\n}\n\nfunc (p PairList) Less(i, j int) bool {\n\treturn p[i].value < p[j].value\n}\n\nfunc main() {\n\t// Array(Arreglos): Los array son un tipo de estructura fundamental en golang, aunque tienen sus limitaciones,\n\t// debido a su tamaño fijo, se pueden realizar algunas operaciones utiles con arrays.\n\t// Nota: Esta estractura manejas índice y valor, pero siempre del mismo tipo de valor.\n\n\t// Declaración\n\tvar myArray [5]string\n\tfmt.Println(\"Declaración: \", myArray)\n\n\t// Inicialización\n\tvar myArray2 = [5]int{10, 20, 30, 40, 50}\n\tfmt.Println(\"Inicialización: \", myArray2)\n\n\t// Acceso\n\tmyArray[0] = \"Miguel\"\n\tmyArray[2] = \"Portillo\"\n\tfmt.Println(\"Acceso a myArray: \", myArray[0])\n\n\t// Modificación\n\tmyArray2[0] = 100\n\tfmt.Println(\"Modificación myArray2: \", myArray2[:])\n\n\t// Iteración con bucle for\n\tfmt.Println(\"Iteración con bucle for\")\n\tfor i := 0; i < len(myArray2); i++ {\n\t\tfmt.Println(myArray2[i])\n\t}\n\n\t// Iteración con range\n\tfmt.Println(\"Iteración con range\")\n\tfor id, value := range myArray {\n\t\tfmt.Println(\"Índice: \", id, \"Valor: \", value)\n\t}\n\n\t// Copia manual\n\tvar copyArray [5]string\n\tfor i := range myArray {\n\t\tcopyArray[i] = myArray[i]\n\t}\n\tfmt.Println(\"Copia Manual :\", copyArray)\n\n\t// Copia usando slices\n\tcopyArray2 := make([]int, len(myArray2))\n\tcopy(copyArray2, myArray2[:])\n\tfmt.Println(\"Copia usando slices: \", copyArray2)\n\n\t// Subarrays(slices)\n\tmySlice := myArray2[2:5]\n\tfmt.Println(\"SubArrays(Slices): \", mySlice)\n\n\t// comparacion\n\tfmt.Println(\"Comparación\")\n\tif copyArray == myArray {\n\t\tfmt.Println(\"copyArray es igual a myArray\")\n\t}\n\n\t// suma de elementos\n\ttotal := 0\n\tfor _, value := range myArray2 {\n\t\ttotal += value\n\t}\n\tfmt.Println(\"Suma de elementos: \", total)\n\n\t// Reversión\n\tarrayReverse := [5]int{1, 2, 3, 4, 5}\n\tfor i, j := 0, len(arrayReverse)-1; i < j; i, j = i+1, j-1 {\n\t\tarrayReverse[i], arrayReverse[j] = arrayReverse[j], arrayReverse[i]\n\t}\n\tfmt.Println(\"Reversión: \", arrayReverse)\n\n\t// Slices(SubArrays): A diferencia de los arrays, los slices son flexibles en tamaño, lo que les permite crecer y decrecer según las necesidades.\n\t// Es importante saber que un slice no contiene datos, solo hace referencia a los datos en un array. Por lo que aunque estos copian el índice del array,\n\t// si se modifica el slice, el array de origen también cambiará.\n\t// si un array tiene 5 indices y se quiere agregar un 6to índice, el slice, creará otro array por debajo aunque se refiera al mismo desde el inicio.\n\n\t// inicialización\n\tvar slice []int\n\tslice2 := []int{1, 2, 3} // inicialización corta con 3 elementos\n\tslice3 := make([]int, 5) // inicialización usando make con una longitud de 5\n\tfmt.Println(\"Slice iniciado: \", slice)\n\tfmt.Println(\"Slice con inicialización corta: \", slice2)\n\tfmt.Println(\"Slice con capacidad: \", cap(slice3), \" y \", \"longitud: \", len(slice3))\n\n\t// Índexación\n\tsliceNumber := []int{10, 20, 30, 40}\n\tfmt.Println(\"Indexación: \", sliceNumber[3], sliceNumber[1])\n\n\t// Inserción de elementos\n\tslice2 = append(slice2, 25)\n\tfmt.Println(\"Inserción: :\", slice2)\n\n\t// Copiar un slice\n\tnewSlice := make([]int, len(sliceNumber))\n\tcopy(newSlice, sliceNumber)\n\tfmt.Println(\"Copiar un slice: \", newSlice)\n\n\t// Slice bidimensional\n\ttowDimension := make([][]int, 3)\n\tfor i := 0; i < 3; i++ {\n\t\ttowDimension[i] = make([]int, 3)\n\t\tfor j := 0; j < 3; j++ {\n\t\t\ttowDimension[i][j] = i + j\n\t\t}\n\n\t}\n\tfmt.Println(\"Slice bidimensional: \", towDimension)\n\n\t// Mapas: En golang son un tipo de dato especial, que puede almacenar una colección de pares clave-valor, esto es similar a un\n\t// diccionario en python o un hashmap en java. En go, un mapa es un tipo de dato incorporado que se implementa\n\t// utilizando una tabla hash, lo que le da, caracteristicas de busqueda, adición, ctualización y eliminación de datos.\n\t// Al ser un tipo de referencia estos al ser creados, obtienen un puntero a los datos subyacentes.\n\t// son de crecimiento dinámico, tienen unicidad de clave(son únicas) y son colecciones desordenadas.\n\n\t// Declaración e Inicialización: La forma más común es usar la función make, aunque también se crean con sintaxis literal\n\t// al trabajar con mapas hay que tener en cuenta que el valor nulo de un mapa no inicializado es nil.\n\t// un mapa debe inicializarse para poder usarlo, esto se logra usando make.\n\n\temptyMap := make(map[string]int) // cración con make\n\n\tfruitsMap := map[string]int{ // creación con sisntaxis literal\n\t\t\"manzana\": 2,\n\t\t\"pera\":    5,\n\t\t\"banana\":  4,\n\t\t\"cereza\":  2,\n\t\t\"durazno\": 5,\n\t\t\"kiwi\":    4,\n\t}\n\n\tvar m = map[string]int{}\n\tif m == nil {\n\t\tm = make(map[string]int)\n\t\tfmt.Println(\"Mapa Inicializado.\")\n\t} else {\n\t\tfmt.Println(\"Mapa ya inicializado y listo para usarse.\")\n\t}\n\n\t// Inserción:\n\temptyMap[\"miguel\"] = 31\n\tfmt.Println(emptyMap)\n\n\t// Borrado:\n\tdelete(emptyMap, \"miguel\")\n\tfmt.Println(emptyMap)\n\n\t// Actualización:\n\tfruitsMap[\"manzana\"] = 12\n\tfmt.Println(fruitsMap[\"manzana\"])\n\n\t// Ordenamiento: Por defecto, los mapas no permiten el ordenamiento porque estan hechos para acceder a sus valores por medio de claves.\n\t// pero hay manera de hcarlo:\n\n\tvar keys []string          // Slice\n\tfor k := range fruitsMap { // Extraer las claves del mapa\n\t\tkeys = append(keys, k)\n\t}\n\n\t// Ordenamos las claves:\n\tsort.Strings(keys)\n\n\t// Recorremos las claves ordenadas y accedemos a los valores:\n\tfor _, k := range keys {\n\t\tfmt.Printf(\"%s: %d:\\n\", k, fruitsMap[k])\n\t}\n\n\t// Seguridad y sync.map: AL utilizar un entorno multihilo, se debe prestar especial atención a los problemas de seguridad, en concurrencia.\n\t// En un escenario concurrente, el tipo mapa en golang puede llevar a condiciones de carrera si no se implementa una sincronización adecuada.\n\t// La biblioteca estándar de Go proporciona el tipo sync.Map, que es un mapa seguro diseñado para entornos concurrentes.\n\t// Este tipo ofrece métodos básicos como Load, Store, LoadOrStore, Delete y Range para operar en el mapa.\n\n\t// Declarando el  mapa\n\tvar mySyncMap sync.Map\n\n\t// Inserción de datos en el mapa\n\tmySyncMap.Store(\"miguel\", 26)\n\tmySyncMap.Store(\"alejandro\", 33)\n\n\t// Leendo e imprimiendo datos\n\tif valor, ok := mySyncMap.Load(\"miguel\"); ok {\n\t\tfmt.Printf(\"Clave: Miguel Valor:%d\\n\", valor)\n\t}\n\n\t// Iterando sobre eun sync.Map con range\n\tmySyncMap.Range(func(clave, valor interface{}) bool {\n\t\tfmt.Printf(\"Clave: %v, Valor: %v\\n\", clave, valor)\n\t\treturn true // continuar la iteración\n\t})\n\n\t// Eliminando datos en el map\n\tmySyncMap.Delete(\"alejandro\")\n\tfmt.Println(mySyncMap.Load(\"miguel\"))    // Resultado: valor + un true\n\tfmt.Println(mySyncMap.Load(\"alejandro\")) // Resultado: valor nil y false\n\n\t// Ordenamiento\n\tvar animals sync.Map\n\n\t// Guardar algunos valores\n\tanimals.Store(\"Mono\", 5)\n\tanimals.Store(\"Foca\", 13)\n\tanimals.Store(\"Águila\", 3)\n\tanimals.Store(\"Mandríl\", 2)\n\tanimals.Store(\"Burro\", 1)\n\n\tvar pairs PairList\n\n\t// Usa range sobre el mapa para obtener los pares\n\tanimals.Range(func(key, value interface{}) bool {\n\t\tpairs = append(pairs, Pair{key: key.(string), value: value.(int)})\n\t\treturn true\n\t})\n\n\t// Ordenar los pares por valor\n\tsort.Sort(pairs)\n\n\t// Imprime los pares ordenados\n\tfor _, pair := range pairs {\n\t\tfmt.Printf(\"%s: %d\\n\", pair.key, pair.value)\n\t}\n\n\t// Actualización Valores:\n\tvar myUpdateMap sync.Map\n\tmyUpdateMap.Store(\"llave\", \"Valor Inicial\")\n\tvalor, _ := myUpdateMap.Load(\"llave\")\n\tfmt.Printf(\"Clave: llave Valor: %s\\n\", valor)\n\n\tmyUpdateMap.Store(\"llave\", \"Nuevo Valor\")\n\tvalor2, _ := myUpdateMap.Load(\"llave\")\n\tfmt.Printf(\"Clave: llave Valor: %s\\n\", valor2)\n\n\t// Structs: En golang, son un tipo de dato compuesto muy utilizado para agrupar diferentes tipos de datos en una sola entidad, ya sean diferentes o identicos\n\t// en go los Structs son un aspecto fundamental para la programación orientada a objetos, con ligeras diferencias a los lenguajes tradicionales de poo.\n\t// la necesidad de strucs surge de los siguientes aspectos:\n\t// \t- Organizar variables con fuerte relevancia juntas para mejorar la mantenibilidad del código.\n\t//  - Proporcionar un medio para simular \"clases\", facilitando las características de encapsulación y agregación.\n\t//  - Al interactuar con estructuras de datos como JSON, registros de bases de datos, etc., los structs ofrecen una herramienta de mapeo conveniente.\n\n\t// Declaración:\n\ttype person struct {\n\t\tname     string\n\t\tnickname string\n\t\tage      uint8\n\t\tmails    []string // Pueden obtener tipos comolejos como slices\n\t}\n\n\t// Instanciacion de una struct.\n\tvar p person\n\n\t// Esto crea un puntero a la struct.\n\tp2 := new(person)\n\tfmt.Println(p2)\n\n\t// Inicializar con nombres de campo.\n\tp3 := person{\n\t\tname:     \"Miguel\",\n\t\tnickname: \"Migue\",\n\t}\n\tfmt.Println(p3)\n\n\t// inicializar sin nombre de campos:  es posible pero es obligatorio mantener el orden para que no se presenten errores.\n\t// Además no se pueden omitir campos, es decir que es obligatorio usarlos todo, más importante aún, esta manera es insostenible\n\t// en estructuras grandes.\n\tp4 := person{\"miguel\", \"miguel\", 31, []string{\"miguelportillo2475@gmail.com\"}}\n\n\t// Acceso e inserción de datos\n\tp.name = \"Miguel\"\n\tfmt.Println(\"Inserción: \", p)\n\n\t// Actualización\n\tp4.name = \"Alejandro\"\n\tfmt.Println(\"Actualización: \", p4)\n\n\t// Una estructura anónima; no declara explícitamente un nuevo tipo,\n\t// sino que utiliza directamente la definición de la estructura.\n\t// Esto es útil cuando necesitas crear una estructura una vez y\n\t// usarla de manera simple, evitando la creación de tipos innecesarios.\n\n\tpet := struct {\n\t\tname  string\n\t\tage   uint8\n\t\towner string\n\t}{\n\t\tname:  \"Winky\",\n\t\tage:   6,\n\t\towner: \"Miguel\",\n\t}\n\n\tfmt.Printf(\"Nombre: %s Edad; %d Propietario: %s\\n\", pet.name, pet.age, pet.owner)\n\n\t// El anidamieto de estructuras nos permite anidar una estructura como parte de otra, para crear estructuras más complejas.\n\ttype address struct {\n\t\toriginCity   string\n\t\tlocationCity string\n\t\twork         bool\n\t}\n\n\ttype person2 struct {\n\t\tname      string\n\t\tage       uint8\n\t\tdirection address\n\t}\n\n\tp5 := person2{\n\t\tname: \"miguel\",\n\t\tage:  31,\n\t\tdirection: address{\n\t\t\toriginCity:   \"Santa Bárbara de Zulia\",\n\t\t\tlocationCity: \"Medellín\",\n\t\t\twork:         true,\n\t\t},\n\t}\n\tfmt.Println(\"Nombre: \", p5.name, \"\\nEdad: \", p5.age, \"\\nCiudad de Origen: \", p5.direction.originCity, \"\\nCiudad Actual: \", p5.direction.locationCity, \"\\nTrabaja: \", p5.direction.work)\n\n\t// Las Strucs son muy extensas y versátiles, podría seguir con más ejemplos pero pienso que se pueden aclarar en otros ejercicios más adelante.\n\n\t// Llamada a la aplicación de agenda.\n\tContacts()\n}\n\nvar directoryOfContacts = make(map[string]int)\nvar options uint8\nvar contactName string\nvar contactNumber string\n\nfunc Contacts() {\n\tfor {\n\t\tfmt.Println(\"\")\n\t\tfmt.Println(\"Bienvenido a mi lista de contactos\")\n\t\tfmt.Println(\"1. Búscar un contacto.\")\n\t\tfmt.Println(\"2. Crear un Contacto.\")\n\t\tfmt.Println(\"3. Actualizar un contacto.\")\n\t\tfmt.Println(\"4. Eliminar un contacto.\")\n\t\tfmt.Println(\"5. Lista de contactos.\")\n\t\tfmt.Println(\"6. Salir de la lista.\")\n\t\tfmt.Println(\"Por favor selecciona una de las opciones:\")\n\t\tfmt.Scan(&options)\n\n\t\tswitch options {\n\t\tcase 1: // Busqueda\n\t\t\tfmt.Println(\"Ingresa el nombre del contacto a buscar:\")\n\t\t\tfmt.Scan(&contactName)\n\n\t\t\tif verifyIfUserExist(contactName) {\n\t\t\t\tfmt.Printf(\"Número de contacto: %v\\n\", directoryOfContacts[contactName])\n\t\t\t} else {\n\t\t\t\tfmt.Println(\"El contacto no existe.\")\n\t\t\t}\n\n\t\tcase 2: // Creación\n\t\t\tfmt.Println(\"Introduce un nombre: \")\n\t\t\tfmt.Scan(&contactName)\n\t\t\tfmt.Println(\"Introduce un número: \")\n\t\t\tfmt.Scan(&contactNumber)\n\n\t\t\tif verifyIfUserExist(contactName) {\n\t\t\t\tfmt.Println(\"Este contacto ya existe, si desea actualizarlo seleccione la opción 3.\")\n\t\t\t} else {\n\t\t\t\tif validatePhoneNumber(contactNumber) {\n\t\t\t\t\tconvertedNumber, _ := strconv.Atoi(contactNumber)\n\t\t\t\t\tdirectoryOfContacts[contactName] = convertedNumber\n\t\t\t\t\tfmt.Printf(\"Contacto Registrado: %s\\n\", contactName)\n\t\t\t\t} else {\n\t\t\t\t\tfmt.Println(\"Número no válido\")\n\t\t\t\t}\n\t\t\t}\n\t\tcase 3: // Actualización\n\t\t\tfmt.Println(\"Ingresa el nombre del contacto a actualizar:\")\n\t\t\tfmt.Scan(&contactName)\n\n\t\t\tif verifyIfUserExist(contactName) {\n\t\t\t\tfmt.Println(\"Ingresa el nuevo número de contacto: \")\n\t\t\t\tfmt.Scan(&contactNumber)\n\t\t\t\tdirectoryOfContacts[contactName] = convertNumber(contactNumber)\n\t\t\t} else {\n\t\t\t\tfmt.Println(\"El contacto no existe.\")\n\t\t\t}\n\t\tcase 4: // Eliminación\n\t\t\tfmt.Println(\"Ingresa el nombre del contacto a eliminar:\")\n\t\t\tfmt.Scan(&contactName)\n\n\t\t\tif verifyIfUserExist(contactName) {\n\t\t\t\tdelete(directoryOfContacts, contactName)\n\t\t\t} else {\n\t\t\t\tfmt.Println(\"Contacto no encontrado\")\n\t\t\t}\n\n\t\tcase 5: // Listar todos los contactos\n\t\t\tvar keys []string\n\t\t\tfor k := range directoryOfContacts {\n\t\t\t\tkeys = append(keys, k)\n\t\t\t}\n\n\t\t\tsort.Strings(keys)\n\n\t\t\tfor _, k := range keys {\n\t\t\t\tfmt.Printf(\"%s: %d\\n\", k, directoryOfContacts[k])\n\t\t\t}\n\t\tcase 6:\n\t\t\tfmt.Println(\"Saliendo... ¡Bye!\")\n\t\t\treturn\n\t\tdefault:\n\t\t\tfmt.Print(\"\")\n\t\t}\n\t}\n}\n\nfunc validatePhoneNumber(s string) bool {\n\n\tif len(s) > 11 {\n\t\treturn false\n\t}\n\n\tfor _, r := range s {\n\t\tif !unicode.IsDigit(r) {\n\t\t\t{\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t}\n\treturn true\n}\n\nfunc verifyIfUserExist(name string) bool {\n\tvar keys []string\n\tfor k, _ := range directoryOfContacts {\n\t\tkeys = append(keys, k)\n\t}\n\n\tfor _, k := range keys {\n\t\tvar result = strings.Contains(k, name)\n\t\tif result {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc convertNumber(value string) int {\n\tcn, _ := strconv.Atoi(value)\n\treturn cn\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/go/N0HagoNada.go",
    "content": "package main\n\nimport (\n\t\"bufio\"\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"regexp\"\n\t\"sort\"\n\t\"unicode\"\n)\n\n// Estructrua de Contacto\ntype Contacto struct {\n\tNombre string\n\tTel    string\n\tCorreo string\n}\n\nfunc (c *Contacto) ActualizarEmail(nuevoEmail string) {\n\tc.Correo = nuevoEmail\n}\nfunc (c *Contacto) ActualizarTel(nuevoTel string) {\n\tc.Tel = nuevoTel\n}\n\nfunc (c *Contacto) ActualizarNombre(nuevoNombre string) {\n\tc.Nombre = nuevoNombre\n}\n\nvar agenda []Contacto\n\nfunc main() {\n\testructurasEnGo()\n\t// Alamcenamiento, incializado\n\tscanner := bufio.NewScanner(os.Stdin)\n\tfor {\n\t\tfmt.Println(\"Agenda de Contactos\")\n\t\tfmt.Println(\"1. Agregar Contacto\")\n\t\tfmt.Println(\"2. Buscar Contacto\")\n\t\tfmt.Println(\"3. Actualizar Contacto\")\n\t\tfmt.Println(\"4. Eliminar Contacto\")\n\t\tfmt.Println(\"Escribe 'exit' para salir\")\n\t\tfmt.Print(\"Elige una opción: \")\n\n\t\tscanner.Scan()\n\t\tentrada := scanner.Text()\n\n\t\tif entrada == \"exit\" {\n\t\t\tbreak\n\t\t}\n\n\t\tswitch entrada {\n\t\tcase \"1\":\n\t\t\t// Lógica para agregar contacto\n\t\t\tvar nombre, telefono, correo string\n\t\t\tfmt.Print(\"Ingresa el nombre del contacto: \")\n\t\t\tscanner.Scan()\n\t\t\tnombre = scanner.Text()\n\n\t\t\tfmt.Print(\"Ingresa el teléfono del contacto: \")\n\t\t\tscanner.Scan()\n\t\t\ttelefono = scanner.Text()\n\n\t\t\tfmt.Print(\"Ingresa el correo electrónico del contacto: \")\n\t\t\tscanner.Scan()\n\t\t\tcorreo = scanner.Text()\n\n\t\t\t// Aquí llamamos a la función para agregar el contacto.\n\t\t\t// Suponiendo que tu función se llama agregarContacto y devuelve un error si falla.\n\t\t\terr := agregarContacto(&agenda, nombre, telefono, correo)\n\t\t\tif err != nil {\n\t\t\t\tfmt.Println(\"Error al agregar contacto:\", err)\n\t\t\t} else {\n\t\t\t\tfmt.Println(\"Contacto agregado exitosamente: \", agenda)\n\t\t\t}\n\t\tcase \"2\":\n\t\t\t// Lógica para buscar contacto\n\t\t\tvar correo string\n\t\t\tfmt.Print(\"Ingresa el correo electrónico del contacto: \")\n\t\t\tscanner.Scan()\n\t\t\tcorreo = scanner.Text()\n\t\t\t_, contactoNuevo, err := busquedaContacto(agenda, correo)\n\t\t\tif err != nil {\n\t\t\t\tfmt.Println(\"Error al buscar contacto:\", err)\n\t\t\t} else {\n\t\t\t\tfmt.Println(\"Nombre: \"+contactoNuevo.Nombre, \"Telefono: \"+contactoNuevo.Tel)\n\t\t\t}\n\t\tcase \"3\":\n\t\t\tvar nombre, telefono, correo string\n\t\t\tfmt.Print(\"Ingresa el nombre del contacto: \")\n\t\t\tscanner.Scan()\n\t\t\tnombre = scanner.Text()\n\n\t\t\tfmt.Print(\"Ingresa el teléfono del contacto: \")\n\t\t\tscanner.Scan()\n\t\t\ttelefono = scanner.Text()\n\n\t\t\tfmt.Print(\"Ingresa el correo electrónico del contacto: \")\n\t\t\tscanner.Scan()\n\t\t\tcorreo = scanner.Text()\n\t\t\terr := ActualizarContacto(&agenda, nombre, telefono, correo)\n\t\t\tif err != nil {\n\t\t\t\tfmt.Println(\"Error al Actualizar contacto:\", err)\n\t\t\t} else {\n\t\t\t\tfmt.Println(\"Contacto actualizado\")\n\t\t\t}\n\t\tcase \"4\":\n\t\t\tvar correo string\n\t\t\tfmt.Print(\"Ingresa el correo electrónico del contacto: \")\n\t\t\tscanner.Scan()\n\t\t\tcorreo = scanner.Text()\n\t\t\terr := eliminarContacto(&agenda, correo)\n\t\t\tif err != nil {\n\t\t\t\tfmt.Println(\"Error al eliminar contacto:\", err)\n\t\t\t} else {\n\t\t\t\tfmt.Println(\"Contacto eliminado\")\n\t\t\t}\n\t\tdefault:\n\t\t\tfmt.Println(\"Opción no válida, por favor intenta de nuevo.\")\n\t\t}\n\t}\n}\n\nfunc agregarContacto(agenda *[]Contacto, nombre, telefono, correo string) error {\n\t// Validación del nombre\n\tif nombre == \"\" {\n\t\treturn errors.New(\"el nombre no puede estar vacío\")\n\t}\n\n\t// Validación del teléfono\n\tif len(telefono) >= 9 {\n\t\treturn errors.New(\"el teléfono debe tener menos de 9 dígitos\")\n\t}\n\tfor _, c := range telefono {\n\t\tif !unicode.IsDigit(c) {\n\t\t\treturn errors.New(\"el teléfono solo debe contener dígitos\")\n\t\t}\n\t}\n\n\t// Validación del correo electrónico\n\tre := regexp.MustCompile(`^[a-z0-9._%+\\-]+@[a-z0-9.\\-]+\\.[a-z]{2,4}$`)\n\tif !re.MatchString(correo) {\n\t\treturn errors.New(\"formato de correo electrónico inválido\")\n\t}\n\n\t// Agregar el contacto\n\tnuevoContacto := Contacto{Nombre: nombre, Tel: telefono, Correo: correo}\n\t*agenda = append(*agenda, nuevoContacto)\n\n\treturn nil\n}\n\nfunc busquedaContacto(agenda []Contacto, correo string) (int, *Contacto, error) {\n\tfor i, contacto := range agenda {\n\t\tif contacto.Correo == correo {\n\t\t\treturn i, &contacto, nil\n\t\t}\n\t}\n\treturn -1, nil, errors.New(\"Correo no se encuentra en la lista de contacto\")\n}\nfunc eliminarContacto(agenda *[]Contacto, correo string) error {\n\tindice, _, err := busquedaContacto(*agenda, correo)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*agenda = append((*agenda)[:indice], (*agenda)[indice+1:]...)\n\treturn nil\n}\nfunc ActualizarContacto(agenda *[]Contacto, nombre, telefono, correo string) error {\n\tindice, _, err := busquedaContacto(*agenda, correo)\n\tif err != nil {\n\t\treturn err\n\t}\n\t(*agenda)[indice].Nombre = nombre\n\t(*agenda)[indice].Tel = telefono\n\treturn errors.New(\"No es posible actualizar contacto\")\n}\n\nfunc estructurasEnGo() {\n\tvar miArray [5]int // Array de 5 enteros\n\tmiArray[0] = 100\n\tmiArray[1] = 200\n\t// Acceder a los elementos: miArray[0], miArray[1], etc.\n\tmiSlice := []int{10, 20, 30, 40, 50}\n\tmiSlice = append(miSlice, 60) // Añadir un elemento al final\n\t// Acceder a los elementos: miSlice[0], miSlice[1], etc.\n\tslice := []int{3, 1, 4, 1}\n\tsort.Ints(slice)\n\t// Ahora slice está ordenado\n\tsliceStrings := []string{\"z\", \"a\", \"b\"}\n\tsort.Strings(sliceStrings)\n\t// Ahora slice está ordenado\n\tsort.Slice(slice, func(i, j int) bool {\n\t\treturn slice[i] < slice[j] // Criterio de comparación\n\t})\n\t// Ahora slice está ordenado según tu criterio\n\tfmt.Println(slice)\n\tmiMap := make(map[string]int)\n\tmiMap[\"clave1\"] = 100\n\tmiMap[\"clave2\"] = 200\n\t// Acceder a los valores: miMap[\"clave1\"], miMap[\"clave2\"]\n\tuser := Contacto{\"Juan\", \"02123112111\", \"user@user.com\"}\n\tfmt.Println(user)\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/go/gabrielmoris.go",
    "content": "/*\n * EXERCISE:\n * - Create examples of basic functions that represent the different\n *   possibilities of the language:\n *   Without parameters or return, with one or more parameters, with return...\n * - Check if you can create functions within functions.\n * - Use some examples of functions already created in the language.\n * - Test the concept of LOCAL and GLOBAL variables.\n * - You must print the result of all examples to the console.\n *   (and keep in mind that each language may have more or fewer possibilities)\n *\n * EXTRA DIFFICULTY (optional):\n * Create a function that receives two parameters of string type and returns a number.\n * - The function prints all numbers from 1 to 100. Taking into account that:\n *   - If the number is a multiple of 3, it shows the text string of the first parameter.\n *   - If the number is a multiple of 5, it shows the text string of the second parameter.\n *   - If the number is a multiple of 3 and 5, it shows both text strings concatenated.\n *   - The function returns the number of times the number has been printed instead of the texts.\n *\n * Pay special attention to the syntax you should use in each of the cases.\n * Each language follows conventions that you must respect for the code to be understood.\n */\n\npackage main\n\nimport \"fmt\"\n var globalvar = \"I am global because I am outside any function or block.\"\n func main() {\n\tvar localVar =\"I am local because I am inside a function\";\n\tfmt.Println(localVar);\n\tfmt.Println(noParams()); // No params\n\tfmt.Println(withParams(1,2)) // 3\n\tvar number = 1;\n\tnotReturn(&number);\n\tfmt.Println(number);  // 2\n\tb(a); // string\n\trecursive(&number,10);\n\n\t// Anonymous Functions\n\tanonFunc := func() {\n        fmt.Println(\"I am an anonymous function\")\n    }\n\tanonFunc();\n\n\t// Clousures\n\tcounter := 0\n    increment := func() int {\n        counter++\n        return counter\n    }\n    fmt.Println(increment()) // 1\n    fmt.Println(increment()) // 2\n\tfmt.Println(sum(1,2,3,4,5)) //15\n\tchallenge(\"fizz\",\"buzz\");\n }\n\n // Without Params\n func noParams() string {\n\treturn \"No Params\";\n }\n\n // With Params\n func withParams(num1 int, num2 int) int{\n\treturn num1 + num2;\n }\n\n // Function modifying external variable\n func notReturn(num *int){\n\t*num += 1;\n }\n\n // High order Functions\n func a () string {\n\treturn \"I am func A\"\n }\n\n func b (function func() string) {\n\tfmt.Println(\"I am in func B and I an calling this fn: \" + function());\n }\n\n // Recursive Function\n func recursive (num *int , max int){\n\tif *num <= max {\n\t\tfmt.Println(\"This is recutsive: \")\n\t\tfmt.Println(*num)\n\t\t*num++\n\t\trecursive(num, max)\n\t}\n }\n\n // Variable number of arguments\n func sum(nums ...int) int {\n    total := 0\n    for _, num := range nums {\n        total += num\n    }\n    return total\n}\n\nfunc challenge(str1 string, str2 string){\n\tfor i:=0; i<100; i++{\n\t\tif(i %3 ==0 && i%5==0){\n\t\t\tfmt.Println(str1 +  \" \"+ str2)\n\t\t} else if(i % 3==0){\n\t\t\tfmt.Println(str1)\n\t\t} else if(i % 5==0){\n\t\t\tfmt.Println(str2)\n\t\t}\n\n\t}\n\n}"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/go/hozlucas28.go",
    "content": "package main\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"regexp\"\n\t\"strings\"\n)\n\ntype Product struct {\n\tname  string\n\tprice float32\n}\n\ntype Form interface {\n\tArea() float64\n\tPerimeter() float64\n}\n\ntype Contact struct {\n\tname        string\n\tphoneNumber string\n}\n\nfunc getContactName(msg string, msgOnInvalid string, shouldExist bool, contacts *[]Contact) (string, error) {\n\tvar name string\n\n\tfmt.Printf(msg)\n\tfmt.Scan(&name)\n\tif name == \"\" {\n\t\treturn \"\", errors.New(\"Input omitted\")\n\t}\n\n\tcondition := func(name *string) bool {\n\t\tif shouldExist {\n\t\t\treturn !contactExist(name, contacts)\n\t\t}\n\n\t\treturn contactExist(name, contacts)\n\t}\n\n\tfor condition(&name) {\n\t\tfmt.Printf(msgOnInvalid)\n\t\tfmt.Scan(&name)\n\t\tif name == \"\" {\n\t\t\treturn \"\", errors.New(\"Input omitted\")\n\t\t}\n\t}\n\n\treturn name, nil\n}\n\nfunc getPhoneNumber(msg string, msgOnInvalid string) (string, error) {\n\tvar phoneNumber string\n\n\tfmt.Printf(msg)\n\tfmt.Scan(&phoneNumber)\n\tif phoneNumber == \"\" {\n\t\treturn \"\", errors.New(\"Input omitted\")\n\t}\n\n\tfor !isValidPhoneNumber(&phoneNumber) {\n\t\tfmt.Printf(msgOnInvalid)\n\t\tfmt.Scan(&phoneNumber)\n\t\tif phoneNumber == \"\" {\n\t\t\treturn \"\", errors.New(\"Input omitted\")\n\t\t}\n\t}\n\n\treturn phoneNumber, nil\n}\n\nfunc isValidPhoneNumber(phoneNumber *string) bool {\n\tmatch, _ := regexp.MatchString(`[^0-9]`, *phoneNumber)\n\treturn len(*phoneNumber) <= 11 && !match\n\n}\n\nfunc contactExist(name *string, contacts *[]Contact) bool {\n\tvar exist bool = false\n\tfor i := 0; i < len(*contacts); i++ {\n\t\tif strings.ToUpper((*contacts)[i].name) == strings.ToUpper(*name) {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn exist\n}\n\nfunc showContacts(contacts *[]Contact) {\n\tfmt.Print(\"[ \")\n\tfor i := 0; i < len(*contacts); i++ {\n\t\tif i == len(*contacts)-1 {\n\t\t\tfmt.Printf(\"%s / %s\", (*contacts)[i].name, (*contacts)[i].phoneNumber)\n\t\t} else {\n\t\t\tfmt.Printf(\"%s / %s, \", (*contacts)[i].name, (*contacts)[i].phoneNumber)\n\t\t}\n\t}\n\tfmt.Print(\" ]\")\n}\n\nfunc findContactIndex(name *string, contacts *[]Contact) (int, error) {\n\tfor i := 0; i < len(*contacts); i++ {\n\t\tif strings.ToUpper((*contacts)[i].name) == strings.ToUpper(*name) {\n\t\t\treturn i, nil\n\t\t}\n\t}\n\n\treturn -1, errors.New(\"The contact doesn't exists\")\n}\n\nfunc main() {\n\t/*\n\t   Structures...\n\t*/\n\n\t// Array\n\tarray := [3]int{1, 2, 3}\n\tfmt.Printf(\"Array structure: <ARRAY NAME> := [<LENGTH>]<DATA TYPE>{<ELEMENTS...>}\")\n\tfmt.Printf(\"\\narray := [3]int{1, 2, 3} --> array = %d\", array)\n\n\t// Matrix\n\tmatrix := [3][2]int{{1, 2}, {3, 4}, {5, 6}}\n\tfmt.Printf(\"\\n\\nMatrix structure: <MATRIX NAME> := [<LENGTH OF ROWS>][<LENGTH OF COLUMNS>]<DATA TYPE>{<ROWS WITH ELEMENTS (COLUMNS)...>}\")\n\tfmt.Printf(\"\\nmatrix := [3][2]int{{1, 2}, {3, 4}, {5, 6}} --> matrix = \")\n\tfmt.Print(matrix)\n\n\t// Slice - Array with a length defined by the elements\n\tslice := []string{\"Lucas\", \"Hoz\"}\n\tfmt.Printf(\"\\n\\nSlice structure: <SLICE NAME> := []<DATA TYPE>{<ELEMENTS...>}\")\n\tfmt.Printf(\"\\nslice := []string{'Lucas', 'Hoz'} --> slice = \")\n\tfmt.Print(slice)\n\n\t// Map\n\tmyMap := map[string]string{\"firstName\": \"Lucas\", \"lastName\": \"Hoz\"}\n\tfmt.Printf(\"\\n\\nMap structure: <MAP NAME> := map[<DATA TYPE OF KEYS>]<DATA TYPE OF VALUES>{PROPERTIES...}\")\n\tfmt.Printf(\"\\nmyMap := map[string]string{'firstName': 'Lucas', 'lastName': 'Hoz'} --> myMap = \")\n\tfmt.Print(myMap)\n\n\t// Struct\n\tfmt.Printf(\"\\n\\nStruct structure: type <STRUCT NAME> struct {<PARAMETERS...>}\")\n\tfmt.Print(\"\\ntype Product struct { name string; price float32 }\")\n\n\t// Interface\n\tfmt.Printf(\"\\n\\nInterface structure: type <INTERFACE NAME> interface {<METHODS...>}\")\n\tfmt.Print(\"\\ntype Form interface { Area() float64; Perimeter() float64 }\")\n\n\tfmt.Printf(\"\\n\\n# ---------------------------------------------------------------------------------- #\")\n\n\t/*\n\t   Insert, delete, update, and sort operations\n\t*/\n\n\tmySlice := []int{1, 2, 3}\n\tmyMap02 := map[string]string{\"firstName\": \"Lucas\", \"lastName\": \"Hoz\"}\n\n\t// Insert element/s at the end of a slice structure\n\tmySlice = append(mySlice, 4, 5)\n\tfmt.Printf(\"\\n\\nInsert element/s at the end of a slice structure: <SLICE NAME> = append(<SLICE NAME>, <ELEMENTS...>)\")\n\tfmt.Printf(\"\\n[1, 2, 3] = append([1, 2, 3], 4, 5) --> mySlice = \")\n\tfmt.Print(mySlice)\n\n\t// Delete an element of a slice structure\n\tmySlice = append(mySlice[:2], mySlice[2+1:]...)\n\tfmt.Printf(\"\\n\\nDelete an element of a slice structure: <SLICE NAME> = append(<SLICE NAME>[:<INDEX OF THE ELEMENT TO DELETE>], <SLICE NAME>[<INDEX OF THE ELEMENT TO DELETE> + 1:]...)\")\n\tfmt.Printf(\"\\n[1, 2, 3, 4, 5] = append([1, 2, 3, 4, 5][:2], [1, 2, 3, 4, 5][2 + 1:]...) --> mySlice = \")\n\tfmt.Print(mySlice)\n\n\t// Update an element of a slice structure\n\tmySlice[0] = 1 * 10\n\tfmt.Printf(\"\\n\\nUpdate an element of a slice structure: <SLICE NAME>[<INDEX OF THE ELEMENT TO UPDATE>] = <NEW VALUE>\")\n\tfmt.Printf(\"\\n[1, 2, 4, 5][0] = 1 * 10 --> mySlice = \")\n\tfmt.Print(mySlice)\n\n\t// Insert element in a map structure\n\tmyMap02[\"country\"] = \"Argentina\"\n\tfmt.Printf(\"\\n\\nInsert element in a map structure: <MAP NAME>[<KEY OF THE NEW ELEMENT>] = <VALUE>\")\n\tfmt.Printf(\"\\n{ 'firstName': 'Lucas', 'lastName': 'Hoz' }['country'] = 'Argentina' --> myMap02 = \")\n\tfmt.Print(myMap02)\n\n\t// Delete an element of a map structure\n\tdelete(myMap02, \"lastName\")\n\tfmt.Printf(\"\\n\\nDelete an element of a map structure: delete(<MAP NAME>, <KEY OF THE PROPERTY TO DELETE>)\")\n\tfmt.Printf(\"\\ndelete({ 'country': 'Argentina', 'firstName': 'Lucas', 'lastName': 'Hoz' }, 'lastName') --> myMap02 = \")\n\tfmt.Print(myMap02)\n\n\t// Update an element of a map structure\n\tmyMap02[\"firstName\"] = \"Nahuel\"\n\tfmt.Printf(\"\\n\\nUpdate an element of a map structure: <MAP NAME>[<KEY OF THE ELEMENT TO UPDATE>] = <NEW VALUE>\")\n\tfmt.Printf(\"\\n{ 'country': 'Argentina', 'firstName': 'Lucas' }['firstName'] = 'Nahuel' --> myMap02 = \")\n\tfmt.Print(myMap02)\n\n\tfmt.Printf(\"\\n\\n# ---------------------------------------------------------------------------------- #\")\n\n\t/*\n\t   Additional challenge...\n\t*/\n\n\tcontacts := []Contact{\n\t\t{\n\t\t\tname:        \"Juan\",\n\t\t\tphoneNumber: \"1115616\",\n\t\t},\n\t}\n\n\tvar operation string\n\tvar exit bool = false\n\tfor !exit {\n\t\tfmt.Printf(\"\\n\\n> Select an operation ('Show', 'Find', 'Insert', 'Update', 'Delete' or 'Exit'): \")\n\t\tfmt.Scan(&operation)\n\n\t\tswitch strings.ToUpper(operation) {\n\t\tcase \"SHOW\":\n\t\t\tif len(contacts) > 0 {\n\t\t\t\tfmt.Printf(\"Contacts: \")\n\t\t\t\tshowContacts(&contacts)\n\t\t\t} else {\n\t\t\t\tfmt.Printf(\"There are no contacts listed!\")\n\t\t\t}\n\t\t\tbreak\n\n\t\tcase \"FIND\":\n\t\t\tname, nameError := getContactName(\"> Enter the name of the contact: \", \"> The contact doesn't exists! Enter another name: \", true, &contacts)\n\t\t\tif nameError != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tindex, _ := findContactIndex(&name, &contacts)\n\t\t\tfmt.Printf(\"Contact info: %s / %s\", contacts[index].name, contacts[index].phoneNumber)\n\t\t\tbreak\n\n\t\tcase \"INSERT\":\n\t\t\tname, nameError := getContactName(\"Enter the name of the new contact: \", \"The contact already exists! Try with another name: \", false, &contacts)\n\t\t\tif nameError != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tphoneNumber, phoneNumberError := getPhoneNumber(\"Enter the phone number of new contact: \", \"Invalid phone number! Enter a valid one: \")\n\t\t\tif phoneNumberError != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tcontacts = append(contacts, Contact{name: name, phoneNumber: phoneNumber})\n\n\t\t\tfmt.Printf(\"Contact inserted!\")\n\t\t\tbreak\n\n\t\tcase \"UPDATE\":\n\t\t\tcontactNameToUpdate, contactNameToUpdateError := getContactName(\"Enter the name of the contact to update: \", \"The contact doesn't exists! Enter another name: \", true, &contacts)\n\t\t\tif contactNameToUpdateError != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tname, nameError := getContactName(\"Enter the new name:\", \"There is a contact with this name! Try another one: \", false, &contacts)\n\t\t\tif nameError != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tphoneNumber, phoneNumberError := getPhoneNumber(\"Enter the new phone number: \", \"Invalid phone number! Enter a valid one: \")\n\t\t\tif phoneNumberError != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tcontactIndex, _ := findContactIndex(&contactNameToUpdate, &contacts)\n\t\t\tcontacts[contactIndex].name = name\n\t\t\tcontacts[contactIndex].phoneNumber = phoneNumber\n\n\t\t\tfmt.Printf(\"Contact updated!\")\n\t\t\tbreak\n\n\t\tcase \"DELETE\":\n\t\t\tcontactNameToDelete, contactNameToDeleteError := getContactName(\"Enter the name of the contact to delete: \", \"The contact doesn't exists! Enter another name: \", true, &contacts)\n\t\t\tif contactNameToDeleteError != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tcontactIndex, _ := findContactIndex(&contactNameToDelete, &contacts)\n\t\t\tcontacts = append(contacts[:contactIndex], contacts[contactIndex+1:]...)\n\n\t\t\tfmt.Printf(\"Contact deleted!\")\n\t\t\tbreak\n\n\t\tcase \"EXIT\":\n\t\t\tfmt.Printf(\"Program finished!\")\n\t\t\texit = true\n\t\t\tbreak\n\n\t\tdefault:\n\t\t\tbreak\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/go/kodenook.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"sort\"\n)\n\nfunc main() {\n\t/* Array */\n\n\tvar arr1 = [5]int{1, 2, 3, 4, 5}\n\n\t// edit\n\n\tarr1[0] = 6\n\tfmt.Println(arr1)\n\n\t/* Slice */\n\n\tvar slice []int = arr1[1:4]\n\n\t// add\n\n\tslice = append(slice, 5)\n\tfmt.Println(slice)\n\n\t// edit\n\n\tslice[0] = 7\n\tfmt.Println(slice)\n\n\t// delete\n\n\tslice = append(slice[:1], slice[2:]...)\n\tfmt.Println(slice)\n\n\t// sort\n\n\tsort.Ints(slice)\n\tfmt.Println(slice)\n\n\t/* Map */\n\n\tvar cars = map[int]string{1: \"ford\", 2: \"toyota\", 3: \"chevrolet\"}\n\n\t// add/edit\n\n\tcars[4] = \"renault\"\n\tfmt.Println(cars)\n\n\t// delete\n\n\tdelete(cars, 1)\n\tfmt.Println(cars)\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/go/miguelex.go",
    "content": "package main\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n)\n\ntype Contact struct {\n\tName  string\n\tPhone string\n}\n\ntype Agenda map[string]Contact\n\nfunc inc(i *int) {\n\t*i++\n}\n\nfunc searchContact(reader *bufio.Reader, agenda Agenda) {\n\tfmt.Print(\"Ingrese el nombre del contacto que desea buscar: \")\n\tname, _ := reader.ReadString('\\n')\n\tname = strings.TrimSpace(name)\n\n\tcontact, found := agenda[name]\n\tif found {\n\t\tfmt.Println(\"Nombre:\", contact.Name)\n\t\tfmt.Println(\"Teléfono:\", contact.Phone)\n\t} else {\n\t\tfmt.Println(\"El contacto no existe en la agenda.\")\n\t}\n}\n\nfunc insertContact(reader *bufio.Reader, agenda Agenda) {\n\tfmt.Print(\"Ingrese el nombre del nuevo contacto: \")\n\tname, _ := reader.ReadString('\\n')\n\tname = strings.TrimSpace(name)\n\n\tfmt.Print(\"Ingrese el número de teléfono del nuevo contacto: \")\n\tphone, _ := reader.ReadString('\\n')\n\tphone = strings.TrimSpace(phone)\n\n\t// Verificar si el número de teléfono es válido\n\tif _, err := strconv.Atoi(phone); err != nil || len(phone) > 11 {\n\t\tfmt.Println(\"Número de teléfono no válido. Debe ser numérico y tener 11 dígitos como máximo.\")\n\t\treturn\n\t}\n\n\tagenda[name] = Contact{Name: name, Phone: phone}\n\tfmt.Println(\"Contacto agregado correctamente.\")\n}\n\nfunc updateContact(reader *bufio.Reader, agenda Agenda) {\n\tfmt.Print(\"Ingrese el nombre del contacto que desea actualizar: \")\n\tname, _ := reader.ReadString('\\n')\n\tname = strings.TrimSpace(name)\n\n\t_, found := agenda[name]\n\tif !found {\n\t\tfmt.Println(\"El contacto no existe en la agenda.\")\n\t\treturn\n\t}\n\n\tfmt.Print(\"Ingrese el nuevo número de teléfono: \")\n\tphone, _ := reader.ReadString('\\n')\n\tphone = strings.TrimSpace(phone)\n\n\t// Verificar si el número de teléfono es válido\n\tif _, err := strconv.Atoi(phone); err != nil || len(phone) > 11 {\n\t\tfmt.Println(\"Número de teléfono no válido. Debe ser numérico y tener 11 dígitos como máximo.\")\n\t\treturn\n\t}\n\n\tagenda[name] = Contact{Name: name, Phone: phone}\n\tfmt.Println(\"Contacto actualizado correctamente.\")\n}\n\nfunc deleteContact(reader *bufio.Reader, agenda Agenda) {\n\tfmt.Print(\"Ingrese el nombre del contacto que desea eliminar: \")\n\tname, _ := reader.ReadString('\\n')\n\tname = strings.TrimSpace(name)\n\n\t_, found := agenda[name]\n\tif !found {\n\t\tfmt.Println(\"El contacto no existe en la agenda.\")\n\t\treturn\n\t}\n\n\tdelete(agenda, name)\n\tfmt.Println(\"Contacto eliminado correctamente.\")\n}\n\nfunc main() {\n\n\t// Arrays\n\tvar arr [5]int\n\tarr[0] = 1\n\tarr[1] = 2\n\tarr[2] = 3\n\tarr[3] = 4\n\tarr[4] = 5\n\tfmt.Println(arr)\n\n\t// Slices\n\tslice := []int{1, 2, 3, 4, 5}\n\tfmt.Println(slice)\n\tfmt.Println(slice[2:4])\n\n\t// Maps\n\tm := make(map[string]int)\n\tm[\"key1\"] = 1\n\tm[\"key2\"] = 2\n\tfmt.Println(m)\n\n\t// Structs\n\ttype person struct {\n\t\tname string\n\t\tage  int\n\t}\n\tp := person{name: \"Miguel\", age: 25}\n\tfmt.Println(p)\n\n\t// Pointers\n\ti := 7\n\tinc(&i)\n\tfmt.Println(i)\n\n\t// Extra\n\n\tagenda := make(Agenda)\n\treader := bufio.NewReader(os.Stdin)\n\n\tfor {\n\t\tfmt.Println(\"\\nOperaciones disponibles:\")\n\t\tfmt.Println(\"1. Búsqueda de contacto\")\n\t\tfmt.Println(\"2. Inserción de contacto\")\n\t\tfmt.Println(\"3. Actualización de contacto\")\n\t\tfmt.Println(\"4. Eliminación de contacto\")\n\t\tfmt.Println(\"5. Salir del programa\")\n\n\t\tfmt.Print(\"\\nSeleccione la operación que desea realizar (1-5): \")\n\t\tchoiceStr, _ := reader.ReadString('\\n')\n\t\tchoiceStr = strings.TrimSpace(choiceStr)\n\t\tchoice, err := strconv.Atoi(choiceStr)\n\t\tif err != nil || choice < 1 || choice > 5 {\n\t\t\tfmt.Println(\"Por favor, ingrese un número válido entre 1 y 5.\")\n\t\t\tcontinue\n\t\t}\n\n\t\tswitch choice {\n\t\tcase 1:\n\t\t\tsearchContact(reader, agenda)\n\t\tcase 2:\n\t\t\tinsertContact(reader, agenda)\n\t\tcase 3:\n\t\t\tupdateContact(reader, agenda)\n\t\tcase 4:\n\t\t\tdeleteContact(reader, agenda)\n\t\tcase 5:\n\t\t\tfmt.Println(\"Saliendo del programa...\")\n\t\t\treturn\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/go/qwik-zgheib.go",
    "content": "package main\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"os\"\n\t\"sort\"\n\t\"strings\"\n\t\"unicode\"\n)\n\ntype Person struct {\n\tName string\n\tAge  int\n}\n\n// Contact struct represents a contact in the agenda\ntype Contact struct {\n\tName  string\n\tPhone string\n}\n\n// Agenda struct represents the agenda of contacts\ntype Agenda struct {\n\tContacts []Contact\n}\n\n// NewAgenda creates a new empty agenda\nfunc NewAgenda() *Agenda {\n\treturn &Agenda{Contacts: []Contact{}}\n}\n\n// AddContact adds a new contact to the agenda\nfunc (a *Agenda) AddContact(name, phone string) {\n\ta.Contacts = append(a.Contacts, Contact{Name: name, Phone: phone})\n}\n\n// UpdateContact updates an existing contact's phone number\nfunc (a *Agenda) UpdateContact(name, phone string) bool {\n\tfor i, c := range a.Contacts {\n\t\tif c.Name == name {\n\t\t\ta.Contacts[i].Phone = phone\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// DeleteContact deletes a contact by name\nfunc (a *Agenda) DeleteContact(name string) bool {\n\tfor i, c := range a.Contacts {\n\t\tif c.Name == name {\n\t\t\ta.Contacts = append(a.Contacts[:i], a.Contacts[i+1:]...)\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// SearchContact searches for a contact by name\nfunc (a *Agenda) SearchContact(name string) *Contact {\n\tfor _, c := range a.Contacts {\n\t\tif c.Name == name {\n\t\t\treturn &c\n\t\t}\n\t}\n\treturn nil\n}\n\n// ListContacts lists all contacts sorted by name\nfunc (a *Agenda) ListContacts() {\n\tsort.Slice(a.Contacts, func(i, j int) bool {\n\t\treturn a.Contacts[i].Name < a.Contacts[j].Name\n\t})\n\tfor _, c := range a.Contacts {\n\t\tfmt.Printf(\"Name: %s, Phone: %s\\n\", c.Name, c.Phone)\n\t}\n}\n\n// ValidPhoneNumber checks if the phone number is valid\nfunc ValidPhoneNumber(phone string) bool {\n\tif len(phone) > 11 {\n\t\treturn false\n\t}\n\tfor _, c := range phone {\n\t\tif !unicode.IsDigit(c) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// ReadInput reads input from the user\nfunc ReadInput(prompt string) string {\n\treader := bufio.NewReader(os.Stdin)\n\tfmt.Print(prompt)\n\tinput, _ := reader.ReadString('\\n')\n\treturn strings.TrimSpace(input)\n}\n\nfunc main() {\n\t// Arrays\n\tarr := [5]int{1, 2, 3, 4, 5}\n\tfmt.Println(\"Array:\", arr)\n\tarr[2] = 10\n\tfmt.Println(\"Updated Array:\", arr)\n\tfmt.Println(\"----------------------------------------\")\n\n\t// Slices\n\tslice := []int{5, 3, 4, 1, 2}\n\tfmt.Println(\"Slice:\", slice)\n\tslice = append(slice, 6)\n\tfmt.Println(\"Appended Slice:\", slice)\n\tsort.Ints(slice)\n\tfmt.Println(\"Sorted Slice:\", slice)\n\tslice = slice[:len(slice)-1]\n\tfmt.Println(\"Slice after deletion:\", slice)\n\tfmt.Println(\"----------------------------------------\")\n\n\t// Maps\n\tm := make(map[string]int)\n\tm[\"one\"] = 1\n\tm[\"two\"] = 2\n\tm[\"three\"] = 3\n\tfmt.Println(\"Map:\", m)\n\tm[\"two\"] = 22\n\tfmt.Println(\"Updated Map:\", m)\n\tdelete(m, \"three\")\n\tfmt.Println(\"Map after deletion:\", m)\n\n\t// Sorting map keys\n\tkeys := make([]string, 0, len(m))\n\tfor k := range m {\n\t\tkeys = append(keys, k)\n\t}\n\tsort.Strings(keys)\n\tfmt.Println(\"Sorted Map Keys:\", keys)\n\tfmt.Println(\"----------------------------------------\")\n\n\t// Structs\n\tperson := Person{\"Alice\", 30}\n\tfmt.Println(\"Struct:\", person)\n\tperson.Age = 31\n\tfmt.Println(\"Updated Struct:\", person)\n\n\t// extra exercise\n\tagenda := NewAgenda()\n\tfor {\n\t\tfmt.Println(\"\\nChoose an option:\")\n\t\tfmt.Println(\"1. Add contact\")\n\t\tfmt.Println(\"2. Update contact\")\n\t\tfmt.Println(\"3. Delete contact\")\n\t\tfmt.Println(\"4. Search contact\")\n\t\tfmt.Println(\"5. List contacts\")\n\t\tfmt.Println(\"6. Exit\")\n\n\t\tchoice := ReadInput(\"Enter choice: \")\n\t\tswitch choice {\n\t\tcase \"1\":\n\t\t\tname := ReadInput(\"Enter name: \")\n\t\t\tphone := ReadInput(\"Enter phone number: \")\n\t\t\tif ValidPhoneNumber(phone) {\n\t\t\t\tagenda.AddContact(name, phone)\n\t\t\t\tfmt.Println(\"Contact added.\")\n\t\t\t} else {\n\t\t\t\tfmt.Println(\"Invalid phone number.\")\n\t\t\t}\n\t\tcase \"2\":\n\t\t\tname := ReadInput(\"Enter name: \")\n\t\t\tphone := ReadInput(\"Enter new phone number: \")\n\t\t\tif ValidPhoneNumber(phone) {\n\t\t\t\tif agenda.UpdateContact(name, phone) {\n\t\t\t\t\tfmt.Println(\"Contact updated.\")\n\t\t\t\t} else {\n\t\t\t\t\tfmt.Println(\"Contact not found.\")\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfmt.Println(\"Invalid phone number.\")\n\t\t\t}\n\t\tcase \"3\":\n\t\t\tname := ReadInput(\"Enter name: \")\n\t\t\tif agenda.DeleteContact(name) {\n\t\t\t\tfmt.Println(\"Contact deleted.\")\n\t\t\t} else {\n\t\t\t\tfmt.Println(\"Contact not found.\")\n\t\t\t}\n\t\tcase \"4\":\n\t\t\tname := ReadInput(\"Enter name: \")\n\t\t\tcontact := agenda.SearchContact(name)\n\t\t\tif contact != nil {\n\t\t\t\tfmt.Printf(\"Contact found - Name: %s, Phone: %s\\n\", contact.Name, contact.Phone)\n\t\t\t} else {\n\t\t\t\tfmt.Println(\"Contact not found.\")\n\t\t\t}\n\t\tcase \"5\":\n\t\t\tagenda.ListContacts()\n\t\tcase \"6\":\n\t\t\tfmt.Println(\"Exiting.\")\n\t\t\treturn\n\t\tdefault:\n\t\t\tfmt.Println(\"Invalid choice. Please try again.\")\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/go/thegera4.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"sort\"\n)\n\nfunc main() {\n\n\t// Slice (Array / Lista)\n\tvar slice []int\n\n\t//Agregar\n\tslice = append(slice, 1) \n\tslice = append(slice, 2) // Cada que se inserta un dato se inserta al final\n\tfmt.Println(\"Slice inicial con datos: \",slice)\n\n\tslice = append([]int{0}, slice...) //si queremos agregar al principio\n\tfmt.Println(\"Slice con dato agregado en el primer indice: \",slice)\n\n\tslice = append(slice[:1], append([]int{3}, slice[1:]...)...) //para agregar en un indice especifico: agregar el 3 en el indice 1\n\tfmt.Println(\"Slice con dato agregado en el indice 1: \",slice)\n\n\t//Eliminar\n\tslice = append(slice[:1], slice[2:]...) //para eliminar un elemento desde posicion 1 hasta 2 no inclusive, osea solo el \"1\"\n\tfmt.Println(\"Slice con dato eliminado: \",slice)\n\n\t//Actualizar\n\tslice[0] = 10\n\tfmt.Println(\"Slice con dato actualizado: \",slice)\n\n\t//Buscar\n\tfor i := 0; i < len(slice); i++ {\n\t\tif slice[i] == 10 {\n\t\t\tfmt.Println(\"El dato se encuentra en el indice: \", i)\n\t\t}\n\t}\n\n\t//Ordenar\n\tslice = append(slice, 5)\n\tsort.Ints(slice)\n\tfmt.Println(\"Slice ordenado ascendente: \",slice)\n\tsort.Sort(sort.Reverse(sort.IntSlice(slice)))\n\tfmt.Println(\"Slice ordenado descendente: \",slice)\n\n\t//Mapa\n\tvar mapa = make(map[string]int) //mapa con llave string y valor int\n\tmapa[\"Juan\"] = 12345678900\n\tmapa[\"Pedro\"] = 12345678911\n\tmapa[\"Maria\"] = 12345678922\n\tfmt.Println(\"Mapa inicial: \", mapa)\n\n\t//Agregar\n\tmapa[\"Jose\"] = 12345678933\n\tfmt.Println(\"Mapa con dato agregado: \", mapa)\n\n\t//Eliminar\n\tdelete(mapa, \"Jose\")\n\tfmt.Println(\"Mapa con dato eliminado: \", mapa)\n\n\t//Actualizar\n\tmapa[\"Juan\"] = 12345678999\n\tfmt.Println(\"Mapa con dato actualizado: \", mapa)\n\n\t//Buscar\n\ttelefono, ok := mapa[\"Juan\"]\n\tif ok {\n\t\tfmt.Println(\"El teléfono del contacto es: \", telefono)\n\t} else {\n\t\tfmt.Println(\"El contacto no existe\")\n\t}\n\n\t//Ordenar\n\tvar keys []string\n\tfor k := range mapa {\n\t\tkeys = append(keys, k)\n\t}\n\tsort.Strings(keys)\n\tfmt.Println(\"Mapa ordenado: \", mapa)\n\n\t//Dificultad extra\n\tAgendaExtra()\n\n}\n\nfunc AgendaExtra() {\n\tvar agenda = make(map[string]int) //mapa con llave string y valor int\n\tagenda[\"Juan\"] = 12345678900\n\tagenda[\"Pedro\"] = 12345678911\n\tagenda[\"Maria\"] = 12345678922\n\tvar opcion int\n\tvar nombre string\n\tvar telefono int\n\tvar invalidTel bool\n\n\tfor {\n\t\tfmt.Println(\"******Bienvenido a la agenda de contactos******\")\n\t\tfmt.Println(\"Por favor, selecciona una opción:\")\n\t\tfmt.Println(\"1  Agregar contacto\")\n\t\tfmt.Println(\"2  Buscar contacto\")\n\t\tfmt.Println(\"3  Actualizar contacto\")\n\t\tfmt.Println(\"4  Eliminar contacto\")\n\t\tfmt.Println(\"5  Mostrar todos los contactos\")\n\t\tfmt.Println(\"6  Salir\")\n\t\tfmt.Scanln(&opcion)\n\n\t\tswitch opcion {\n\t\tcase 1:\n\t\t\tfmt.Println(\"Ingresa el nombre del contacto a agregar:\")\n\t\t\tfmt.Scanln(&nombre)\n\t\t\tfmt.Println(\"Ingrese el teléfono del contacto:\")\n\t\t\tfmt.Scanln(&telefono)\n\t\t\tinvalidTel = CheckTelInvalid(telefono)\n\t\t\tif invalidTel {\n\t\t\t\tfmt.Println(\"El teléfono ingresado no es válido\")\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tagenda[nombre] = telefono\n\t\t\tfmt.Println(\"Contacto agregado exitosamente\")\n\t\tcase 2:\n\t\t\tfmt.Println(\"Ingrese el nombre del contacto a buscar\")\n\t\t\tfmt.Scanln(&nombre)\n\t\t\ttelefono, ok := agenda[nombre]\n\t\t\tif ok {\n\t\t\t\tfmt.Println(\"El teléfono del contacto es: \", telefono)\n\t\t\t} else {\n\t\t\t\tfmt.Println(\"El contacto no existe\")\n\t\t\t}\n\t\tcase 3:\n\t\t\tfmt.Println(\"Ingrese el nombre del contacto a actualizar: \")\n\t\t\tfmt.Scanln(&nombre)\n\t\t\tfmt.Println(\"Ingrese el nuevo teléfono del contacto:\")\n\t\t\tfmt.Scanln(&telefono)\n\t\t\tinvalidTel = CheckTelInvalid(telefono)\n\t\t\tif invalidTel {\n\t\t\t\tfmt.Println(\"El teléfono ingresado no es válido\")\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tagenda[nombre] = telefono\n\t\t\tfmt.Println(\"Contacto actualizado exitosamente\")\n\t\tcase 4:\n\t\t\tfmt.Println(\"Ingrese el nombre del contacto a eliminar:\")\n\t\t\tfmt.Scanln(&nombre)\n\t\t\tdelete(agenda, nombre)\n\t\t\tfmt.Println(\"Contacto eliminado exitosamente\")\n\t\tcase 5:\n\t\t\tfmt.Println(\"Contactos guardados:\")\n\t\t\tfor k, v := range agenda {\n\t\t\t\tfmt.Println(k, v)\n\t\t\t}\n\t\tcase 6:\n\t\t\tfmt.Println(\"Gracias por usar la agenda\")\n\t\t\treturn\n\t\tdefault:\n\t\t\tfmt.Println(\"Opción no válida\")\n\t\t}\n\t}\n\n}\n\nfunc CheckTelInvalid (telefono int) bool {\n\tif telefono < 10000000000 {\n\t\treturn false\n\t} else {\n\t\treturn true\n\t}\n}"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/haskell/SalazarProgrammer.hs",
    "content": "{-\n * EJERCICIO:\n * - Estructuras de datos soportadas por defecto\n * - Operaciones: inserción, borrado, actualización, ordenación\n-}\n\nmodule Main where\n\nimport Data.List (sort, delete, insert, nub)\nimport Data.Map (Map)\nimport qualified Data.Map as Map\nimport qualified Data.Set as Set\nimport Control.Monad (forever)\nimport System.Exit (exitSuccess)\n\n-- 1. LISTAS (la estructura más común en Haskell)\nejemploListas :: IO ()\nejemploListas = do\n    putStrLn \"\\n=== LISTAS ===\"\n    let lista = [1, 2, 3, 4, 5]\n    putStrLn $ \"Lista original: \" ++ show lista\n\n    -- Inserción\n    let listaInsertada = 0 : lista  -- Al inicio\n    putStrLn $ \"Inserción al inicio: \" ++ show listaInsertada\n\n    let listaInsertada2 = lista ++ [6]  -- Al final\n    putStrLn $ \"Inserción al final: \" ++ show listaInsertada2\n\n    let listaInsertada3 = insert 3 lista  -- En posición ordenada\n    putStrLn $ \"Inserción ordenada: \" ++ show listaInsertada3\n\n    -- Borrado\n    let listaBorrada = delete 3 lista  -- Elimina primera ocurrencia\n    putStrLn $ \"Borrado del 3: \" ++ show listaBorrada\n\n    -- Actualización (las listas son inmutables, creamos una nueva)\n    let listaActualizada = take 2 lista ++ [99] ++ drop 3 lista\n    putStrLn $ \"Actualización (posición 2 a 99): \" ++ show listaActualizada\n\n    -- Ordenación\n    let listaDesordenada = [5, 2, 8, 1, 9]\n    putStrLn $ \"Ordenación: \" ++ show (sort listaDesordenada)\n\n-- 2. TUPLAS\nejemploTuplas :: IO ()\nejemploTuplas = do\n    putStrLn \"\\n=== TUPLAS ===\"\n    let tupla = (1, \"Hola\", True)\n    putStrLn $ \"Tupla: \" ++ show tupla\n\n    -- Las tuplas son inmutables, no se pueden modificar directamente\n    -- Se crean nuevas tuplas para \"actualizar\"\n    let tuplaActualizada = (fst tupla + 1, snd tupla, not (thrd tupla))\n        where thrd (_, _, x) = x\n    putStrLn $ \"Tupla 'actualizada': \" ++ show tuplaActualizada\n\n-- 3. CONJUNTOS (Set)\nejemploConjuntos :: IO ()\nejemploConjuntos = do\n    putStrLn \"\\n=== CONJUNTOS ===\"\n    let conjunto = Set.fromList [1, 2, 3, 3, 2, 1]  -- Elimina duplicados\n    putStrLn $ \"Conjunto: \" ++ show (Set.toList conjunto)\n\n    -- Inserción\n    let conjuntoInsertado = Set.insert 4 conjunto\n    putStrLn $ \"Inserción del 4: \" ++ show (Set.toList conjuntoInsertado)\n\n    -- Borrado\n    let conjuntoBorrado = Set.delete 2 conjunto\n    putStrLn $ \"Borrado del 2: \" ++ show (Set.toList conjuntoBorrado)\n\n-- 4. MAPAS/DICCIONARIOS (Map)\nejemploMapas :: IO ()\nejemploMapas = do\n    putStrLn \"\\n=== MAPAS ===\"\n    let mapa = Map.fromList [(\"Juan\", 25), (\"Maria\", 30), (\"Pedro\", 35)]\n    putStrLn $ \"Mapa: \" ++ show (Map.toList mapa)\n\n    -- Inserción\n    let mapaInsertado = Map.insert \"Ana\" 28 mapa\n    putStrLn $ \"Inserción de Ana: \" ++ show (Map.toList mapaInsertado)\n\n    -- Borrado\n    let mapaBorrado = Map.delete \"Juan\" mapa\n    putStrLn $ \"Borrado de Juan: \" ++ show (Map.toList mapaBorrado)\n\n    -- Actualización\n    let mapaActualizado = Map.adjust (+1) \"Maria\" mapa\n    putStrLn $ \"Actualización de Maria (+1): \" ++ show (Map.toList mapaActualizado)\n\n    -- Búsqueda\n    case Map.lookup \"Pedro\" mapa of\n        Just edad -> putStrLn $ \"Edad de Pedro: \" ++ show edad\n        Nothing -> putStrLn \"Pedro no encontrado\"\n\n-- 5. ARRAYS (menos comunes, pero disponibles)\nejemploArrays :: IO ()\nejemploArrays = do\n    putStrLn \"\\n=== ARRAYS ===\"\n    -- Los arrays son inmutables y de tamaño fijo\n    let array = listArray (0, 4) [10, 20, 30, 40, 50] :: Array Int Int\n    putStrLn $ \"Array: \" ++ show (elems array)\n\n    -- \"Actualización\" creando nuevo array\n    let arrayActualizado = array // [(2, 99)]\n    putStrLn $ \"Array actualizado (posición 2): \" ++ show (elems arrayActualizado)\n\n-- DIFICULTAD EXTRA: Agenda de contactos\ntype Agenda = Map.Map String String\n\nagendaContactos :: IO ()\nagendaContactos = do\n    putStrLn \"\\n=== AGENDA DE CONTACTOS ===\"\n    putStrLn \"Operaciones disponibles:\"\n    putStrLn \"1. Buscar contacto\"\n    putStrLn \"2. Insertar contacto\"\n    putStrLn \"3. Actualizar contacto\"\n    putStrLn \"4. Eliminar contacto\"\n    putStrLn \"5. Mostrar todos los contactos\"\n    putStrLn \"6. Salir\"\n\n    let loop agenda = do\n            putStr \"\\nSelecciona una operación (1-6): \"\n            opcion <- getLine\n\n            case opcion of\n                \"1\" -> buscarContacto agenda >>= loop\n                \"2\" -> insertarContacto agenda >>= loop\n                \"3\" -> actualizarContacto agenda >>= loop\n                \"4\" -> eliminarContacto agenda >>= loop\n                \"5\" -> mostrarContactos agenda >>= loop\n                \"6\" -> putStrLn \"¡Hasta luego!\" >> exitSuccess\n                _   -> putStrLn \"Opción no válida\" >> loop agenda\n\n    loop Map.empty\n\nbuscarContacto :: Agenda -> IO Agenda\nbuscarContacto agenda = do\n    putStr \"Nombre a buscar: \"\n    nombre <- getLine\n    case Map.lookup nombre agenda of\n        Just telefono -> putStrLn $ nombre ++ \": \" ++ telefono\n        Nothing -> putStrLn \"Contacto no encontrado\"\n    return agenda\n\ninsertarContacto :: Agenda -> IO Agenda\ninsertarContacto agenda = do\n    putStr \"Nombre: \"\n    nombre <- getLine\n    putStr \"Teléfono: \"\n    telefono <- getLine\n\n    if validarTelefono telefono then do\n        if Map.member nombre agenda\n            then putStrLn \"¡El contacto ya existe! Usa actualizar.\"\n            else putStrLn \"Contacto agregado.\"\n        return $ Map.insert nombre telefono agenda\n    else do\n        putStrLn \"Teléfono no válido. Debe ser numérico y tener 10 dígitos.\"\n        return agenda\n\nactualizarContacto :: Agenda -> IO Agenda\nactualizarContacto agenda = do\n    putStr \"Nombre a actualizar: \"\n    nombre <- getLine\n    if Map.member nombre agenda then do\n        putStr \"Nuevo teléfono: \"\n        telefono <- getLine\n        if validarTelefono telefono then do\n            putStrLn \"Contacto actualizado.\"\n            return $ Map.insert nombre telefono agenda\n        else do\n            putStrLn \"Teléfono no válido.\"\n            return agenda\n    else do\n        putStrLn \"Contacto no encontrado.\"\n        return agenda\n\neliminarContacto :: Agenda -> IO Agenda\neliminarContacto agenda = do\n    putStr \"Nombre a eliminar: \"\n    nombre <- getLine\n    if Map.member nombre agenda then do\n        putStrLn \"Contacto eliminado.\"\n        return $ Map.delete nombre agenda\n    else do\n        putStrLn \"Contacto no encontrado.\"\n        return agenda\n\nmostrarContactos :: Agenda -> IO Agenda\nmostrarContactos agenda = do\n    if Map.null agenda then\n        putStrLn \"La agenda está vacía.\"\n    else do\n        putStrLn \"\\n--- CONTACTOS ---\"\n        mapM_ (\\(nombre, telefono) -> putStrLn $ nombre ++ \": \" ++ telefono)\n              (Map.toList agenda)\n    return agenda\n\nvalidarTelefono :: String -> Bool\nvalidarTelefono telefono =\n    length telefono == 10 && all (`elem` \"0123456789\") telefono\n\n-- Función principal\nmain :: IO ()\nmain = do\n    -- Ejemplos de estructuras de datos\n    ejemploListas\n    ejemploTuplas\n    ejemploConjuntos\n    ejemploMapas\n    ejemploArrays\n\n    -- Ejecutar agenda de contactos\n    agendaContactos\n\n-- Fin del programa\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/AFOXJONES.java",
    "content": "\nimport java.util.*;\npublic class AFOXJONES{\n        // Mapa para almacenar los contactos (nombre -> número de teléfono)\n    private static Map<String, String> contacts = new HashMap<>();\n    private static final int MAX_PHONE_DIGITS = 11; // Límite de dígitos del número de teléfono\n\n\n    static Scanner scanner = new Scanner(System.in);\n    public static void main(String[] args){\n\n          // 1. Array\n        System.out.println(\"Array:\");\n        int[] array = {5, 3, 8, 1};\n        System.out.println(\"Original: \" + Arrays.toString(array));\n        array[1] = 10; // Actualización\n        System.out.println(\"Actualizado: \" + Arrays.toString(array));\n        Arrays.sort(array); // Ordenación\n        System.out.println(\"Ordenado: \" + Arrays.toString(array));\n\n        // 2. ArrayList (Lista)\n        System.out.println(\"\\nArrayList:\");\n        List<Integer> arrayList = new ArrayList<>(Arrays.asList(5, 3, 8, 1));\n        System.out.println(\"Original: \" + arrayList);\n        arrayList.add(7); // Inserción\n        System.out.println(\"Añadido 7: \" + arrayList);\n        arrayList.remove(Integer.valueOf(3)); // Borrado\n        System.out.println(\"Borrado 3: \" + arrayList);\n        arrayList.set(1, 10); // Actualización\n        System.out.println(\"Actualizado: \" + arrayList);\n        arrayList.sort(Comparator.naturalOrder()); // Ordenación\n        System.out.println(\"Ordenado: \" + arrayList);\n\n        // 3. HashSet (Conjunto)\n        System.out.println(\"\\nHashSet:\");\n        Set<Integer> hashSet = new HashSet<>(Arrays.asList(5, 3, 8, 1));\n        System.out.println(\"Original: \" + hashSet);\n        hashSet.add(7); // Inserción\n        System.out.println(\"Añadido 7: \" + hashSet);\n        hashSet.remove(3); // Borrado\n        System.out.println(\"Borrado 3: \" + hashSet);\n        // No admite ordenación directamente; convertir a lista\n        List<Integer> sortedSet = new ArrayList<>(hashSet);\n        Collections.sort(sortedSet);\n        System.out.println(\"Ordenado: \" + sortedSet);\n\n        // 4. HashMap (Mapa)\n        System.out.println(\"\\nHashMap:\");\n        Map<String, Integer> hashMap = new HashMap<>();\n        hashMap.put(\"A\", 5); // Inserción\n        hashMap.put(\"B\", 3);\n        hashMap.put(\"C\", 8);\n        System.out.println(\"Original: \" + hashMap);\n        hashMap.put(\"B\", 10); // Actualización\n        System.out.println(\"Actualizado B: \" + hashMap);\n        hashMap.remove(\"A\"); // Borrado\n        System.out.println(\"Borrado A: \" + hashMap);\n        // No admite ordenación directamente; usar TreeMap\n        Map<String, Integer> sortedMap = new TreeMap<>(hashMap);\n        System.out.println(\"Ordenado: \" + sortedMap);\n\n        // 5. Queue (Cola)\n        System.out.println(\"\\nQueue:\");\n        Queue<Integer> queue = new LinkedList<>(Arrays.asList(5, 3, 8, 1));\n        System.out.println(\"Original: \" + queue);\n        queue.add(7); // Inserción\n        System.out.println(\"Añadido 7: \" + queue);\n        queue.poll(); // Borrado (primer elemento)\n        System.out.println(\"Borrado primer elemento: \" + queue);\n\n        // 6. Stack (Pila)\n        System.out.println(\"\\nStack:\");\n        Stack<Integer> stack = new Stack<>();\n        stack.push(5); // Inserción\n        stack.push(3);\n        stack.push(8);\n        stack.push(1);\n        System.out.println(\"Original: \" + stack);\n        stack.pop(); // Borrado (último elemento)\n        System.out.println(\"Borrado último elemento: \" + stack);\n        stack.push(7); // Inserción\n        System.out.println(\"Añadido 7: \" + stack);\n\n        extra();\n\n    \n    }\n\n    public static void extra(){\n          Scanner scanner = new Scanner(System.in);\n        boolean running = true;\n\n        System.out.println(\"Bienvenido a la Agenda de Contactos\");\n\n        while (running) {\n            System.out.println(\"\\n¿Qué deseas hacer?\");\n            System.out.println(\"1. Insertar contacto\");\n            System.out.println(\"2. Buscar contacto\");\n            System.out.println(\"3. Actualizar contacto\");\n            System.out.println(\"4. Eliminar contacto\");\n            System.out.println(\"5. Mostrar todos los contactos\");\n            System.out.println(\"6. Salir\");\n            System.out.print(\"Selecciona una opción: \");\n            \n            String option = scanner.nextLine();\n\n            switch (option) {\n                case \"1\":\n                    insertContact(scanner);\n                    break;\n                case \"2\":\n                    searchContact(scanner);\n                    break;\n                case \"3\":\n                    updateContact(scanner);\n                    break;\n                case \"4\":\n                    deleteContact(scanner);\n                    break;\n                case \"5\":\n                    showAllContacts();\n                    break;\n                case \"6\":\n                    running = false;\n                    System.out.println(\"¡Hasta luego!\");\n                    break;\n                default:\n                    System.out.println(\"Opción no válida. Inténtalo de nuevo.\");\n            }\n        }\n\n        scanner.close();\n    }\n\n    // Método para insertar un contacto\n    private static void insertContact(Scanner scanner) {\n        System.out.print(\"Introduce el nombre del contacto: \");\n        String name = scanner.nextLine().trim();\n\n        if (contacts.containsKey(name)) {\n            System.out.println(\"El contacto ya existe.\");\n            return;\n        }\n\n        System.out.print(\"Introduce el número de teléfono: \");\n        String phone = scanner.nextLine().trim();\n\n        if (isValidPhone(phone)) {\n            contacts.put(name, phone);\n            System.out.println(\"Contacto agregado correctamente.\");\n        } else {\n            System.out.println(\"Número de teléfono no válido. Debe ser numérico y tener hasta \" + MAX_PHONE_DIGITS + \" dígitos.\");\n        }\n    }\n\n    // Método para buscar un contacto\n    private static void searchContact(Scanner scanner) {\n        System.out.print(\"Introduce el nombre del contacto a buscar: \");\n        String name = scanner.nextLine().trim();\n\n        if (contacts.containsKey(name)) {\n            System.out.println(\"Contacto encontrado: \" + name + \" -> \" + contacts.get(name));\n        } else {\n            System.out.println(\"No se encontró ningún contacto con ese nombre.\");\n        }\n    }\n\n    // Método para actualizar un contacto\n    private static void updateContact(Scanner scanner) {\n        System.out.print(\"Introduce el nombre del contacto a actualizar: \");\n        String name = scanner.nextLine().trim();\n\n        if (contacts.containsKey(name)) {\n            System.out.print(\"Introduce el nuevo número de teléfono: \");\n            String newPhone = scanner.nextLine().trim();\n\n            if (isValidPhone(newPhone)) {\n                contacts.put(name, newPhone);\n                System.out.println(\"Contacto actualizado correctamente.\");\n            } else {\n                System.out.println(\"Número de teléfono no válido.\");\n            }\n        } else {\n            System.out.println(\"No se encontró ningún contacto con ese nombre.\");\n        }\n    }\n\n    // Método para eliminar un contacto\n    private static void deleteContact(Scanner scanner) {\n        System.out.print(\"Introduce el nombre del contacto a eliminar: \");\n        String name = scanner.nextLine().trim();\n\n        if (contacts.containsKey(name)) {\n            contacts.remove(name);\n            System.out.println(\"Contacto eliminado correctamente.\");\n        } else {\n            System.out.println(\"No se encontró ningún contacto con ese nombre.\");\n        }\n    }\n\n    // Método para mostrar todos los contactos\n    private static void showAllContacts() {\n        if (contacts.isEmpty()) {\n            System.out.println(\"No hay contactos en la agenda.\");\n        } else {\n            System.out.println(\"Lista de contactos:\");\n            contacts.forEach((name, phone) -> System.out.println(name + \" -> \" + phone));\n        }\n    }\n\n    // Método para validar un número de teléfono\n    private static boolean isValidPhone(String phone) {\n        return phone.matches(\"\\\\d{1,\" + MAX_PHONE_DIGITS + \"}\");\n    }\n}"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/AbelADE.java",
    "content": "/**\n * Solución al ejercicio #03 ESTRUCTURAS DE DATOS.\n * \n * @author AbelADE\n */\npublic class AbelADE {\n    \n    /**\n     * Estructuras de datos por defecto en Java:\n     *      -- Arrays: son un conjunto de datos del mismo tipo\n     *          almacenados en posiciones con consecutivas de memoria, \n     *          cuya extensión es inmutable.\n     *      -- Listas: secuencia de datos del mismo tipo, donde cada\n     *          elemento está enlazado al siguiente. La extensión es mutable.\n     *      -- Pilas: Los elementos se apilan uno encima del otro, \n     *          y solo se puede acceder al último elemento agregado (LIFO).\n     *      -- Colas: Los elementos se encolan uno detrás del otro, \n     *          y solo se puede acceder al primer elemento agregado (FIFO).\n     *      -- Conjuntos: son colecciones de elementos únicos sin orden.\n     *      -- Diccionarios: son colecciones guardadas en pares de clave-valor,\n     *          donde cada clave se asocia con un valor. El concepto de clave\n     *          es similar al de primary key en bases de datos.\n     */\n    \n    /**\n     * Arrays.\n     */\n    \n    // Inicializar un array con datos.\n    private int [] array = new int[]{0,1,2,3,4,5,6,7,8,9};\n\n    // Inicializar un array con su longitud.\n    private int [] array2 = new int[10];\n    \n    /**\n     * Listas.\n     */\n    ArrayList<Integer> lista = new ArrayList<>();\n    \n    /**\n     * Conjuntos.\n     */\n    HashSet<Integer> conjunto = new HashSet<>();\n    \n    /**\n     * Diccionarios.\n     */\n    HashMap<Integer, Integer> diccionario = new HashMap<>();\n    \n    /**\n     * Pilas\n     */\n    Stack<Integer> pila = new Stack<>();\n    \n    /**\n     * Colas\n     */\n    Queue<Integer> cola = new LinkedList<>();\n    \n    //Métodos a usar en el Ejercicio extra\n    \n    public static String getName(){\n        Scanner scan = new Scanner(System.in);\n        System.out.print(\"Dame el nombre: \");\n        return scan.nextLine();\n    }\n    \n    public static Long getPhone(){\n        Scanner scan;\n        boolean validTel = false;          \n        long tel = Long.MIN_VALUE;\n\n        do {       \n            scan = new Scanner(System.in);\n            try {\n                System.out.print(\"Dame el número de teléfono: \");\n\n                String telText = scan.nextLine();\n\n                tel = Long.parseLong(telText);\n\n                if (telText.length() > 11) {\n                   System.out.println(\"El teléfono debe tener menos de 11 dígitos\");\n                   System.out.println();\n                }else{\n                   validTel = true;\n                }\n            } catch (NumberFormatException e) {\n                System.out.println(\"Número de teléfono no válido\");\n            }\n\n        } while (!validTel);\n        \n        return tel;\n    }\n    \n    public static void getResult(Long result, String success){\n        if (result!= null) {\n            System.out.println(success);\n        }else{\n            System.out.println(\"Operación fallida\");\n        }\n    }\n    \n\n    /**\n     * @param args the command line arguments\n     */\n    public static void main(String[] args) {\n        AbelADE estructuras = new AbelADE();\n        \n        //Operaciones con Arrays.\n        \n            //Inserción en Array\n            estructuras.array2[0] = 5;\n            estructuras.array2[1] = 15;\n            estructuras.array2[2] = 25;\n\n            //No se puede borrar en un Array, \n            //pero se podría realizar un borrado lógico,\n            //en este caso un dato a cero sería equivalente a no tener dato\n            estructuras.array2[1] = 0;\n\n            //Actualización de un dato en un Array.\n            estructuras.array2[2] = 20;\n\n            //Ordenar un array\n            Arrays.sort(estructuras.array2);\n        \n        //Operaciones con Listas.\n            \n            // Inserción\n            estructuras.lista.add(20);\n            estructuras.lista.add(10);\n            estructuras.lista.add(30);\n\n            // Borrar el primer elemento\n            estructuras.lista.remove(0);\n\n            // Actualizar el primer dato\n            estructuras.lista.set(0, 15);\n\n            // Ordenar\n            Collections.sort(estructuras.lista);\n            \n        // Operaciones con Conjuntos.\n        \n            // Inserción\n            estructuras.conjunto.add(20);\n            estructuras.conjunto.add(10);\n            estructuras.conjunto.add(30);\n            \n            //Borrar el dato que sea igual a 20\n            estructuras.conjunto.remove(20);\n        \n            // No se puede Actualizar, pero podemos eliminar el elemento antigüo\n            // y añadir un nuevo elemento\n            estructuras.conjunto.remove(10);\n            estructuras.conjunto.add(15);\n            \n            // No se puede Ordenar\n            \n        // Operaciones con Diccionarios.\n        \n            // Inserción\n            estructuras.diccionario.put(0, 0);\n            estructuras.diccionario.put(5, 5);\n            estructuras.diccionario.put(10, 10);\n            estructuras.diccionario.put(6, 6);\n            \n            //Borrar por clave\n            estructuras.diccionario.remove(0);\n            \n            // Actualizar\n            estructuras.diccionario.replace(10, 20);\n            \n            // Ordenar - No existe un método nativo\n            \n         // Operaciones con Pilas\n            \n            // Inserción\n            estructuras.pila.add(50);\n            estructuras.pila.add(10);\n            estructuras.pila.add(90);\n            \n            //Borrar el primer elemento\n            estructuras.pila.remove(0);\n            \n            // Actualizar \n            estructuras.pila.set(1, 9);\n            \n            // Ordenar \n            Collections.sort(estructuras.pila);\n            \n         // Operaciones con Colas\n         \n            // Inserción\n            estructuras.cola.add(50);\n            estructuras.cola.add(10);\n            estructuras.cola.add(90);\n            \n            //Borrar\n             estructuras.cola.remove(0);\n             \n            // No se puede Actualizar, pero podemos borrar\n            // e insertar el nuevo valor.\n            \n            // No existe un método nativo para Ordenar     \n            \n            \n            \n         /**\n          * DIFICULTAD EXTRA: Crea una agenda de contactos por terminal\n          */   \n         Scanner scan = new Scanner(System.in);\n         boolean exit = false;\n         HashMap<String,Long> contacts = new HashMap<>();\n         \n         do {           \n             System.out.println(\"Bienvenido a la agenda de contactos\");\n             System.out.println(\"¿Qué deseas hacer?\");\n             System.out.println(\"1 - Crear un contacto\");\n             System.out.println(\"2 - Buscar un contacto\");\n             System.out.println(\"3 - Actualizar un contacto\");\n             System.out.println(\"4 - Eliminar un contacto\");\n             System.out.println(\"5 - Salir\");\n             System.out.println();\n             \n             System.out.print(\"Elige una opción: \");\n             int option = scan.nextInt();\n             scan.nextLine();\n             \n             String name = \"\";\n             if (option != 5) {\n                name = getName();\n                 System.out.println();\n             }\n             \n             switch (option) {\n                 case 1:     \n                     getResult(contacts.put(name, getPhone()), \"Contacto añadido\");\n                     break;\n                 case 2:\n                     Long telUser = contacts.get(name);\n           \n                     getResult(telUser, \"El teléfono de \" + name + \" es: \" + telUser);                     \n                     break;\n                 case 3:\n                     getResult(contacts.replace(name, getPhone()), \"Contacto actualizado\");\n                     \n                     System.out.println(\"El nuevo teléfono de \" + name + \" es: \" + contacts.get(name));\n                     break;\n                 case 4:\n                      getResult(contacts.remove(name), name + \" se ha eliminado\");\n                     break;\n                 case 5:\n                     exit = true;\n                     break;\n                 default:\n                     System.out.println(\"Opción no válida!\");\n             }\n             \n             System.out.println();\n             \n        } while (!exit);\n            \n    }\n    \n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/Alextc35.java",
    "content": "/*                                                                                                                \n * EJERCICIO:                                                                                                     \n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.                 \n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.                                       \n *                                                                                                                \n * DIFICULTAD EXTRA (opcional):                                                                                   \n * Crea una agenda de contactos por terminal.                                                                     \n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.          \n * - Cada contacto debe tener un nombre y un número de teléfono.                                                  \n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación           \n *   los datos necesarios para llevarla a cabo.                                                                   \n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.              \n *   (o el número de dígitos que quieras)                                                                         \n * - También se debe proponer una operación de finalización del programa.                                         \n */\n\nimport java.util.Collections; // Colecciones de Java\nimport java.util.Arrays;\nimport java.util.ArrayList;\nimport java.util.LinkedList;\nimport java.util.HashSet;\nimport java.util.TreeSet;\nimport java.util.HashMap;\nimport java.util.TreeMap;\nimport java.util.InputMismatchException; // Para excepciones\nimport java.util.Scanner;\n\npublic class Alextc35 {\n    private static Scanner sc = new Scanner(System.in); // Inicializamos Scanner para recoger inputs\n\n    public static void main(String[] args) {\n        // ---- ARRAY UNIDIMENSIONAL ----\n        System.out.println(\"----- ARRAY UNIDIMENSIONAL -----\");\n\n        // Creación de un arreglo unidimensional de enteros con 5 elementos\n        int[] numbers = new int[5];\n\n        // Inserción de valores en el arreglo\n        int value = 1;\n        for (int i = 0; i < numbers.length; i++) {\n            numbers[i] = value++;\n        }\n\n        // Alternativa de inserción\n        numbers[0] = 10;\n        numbers[1] = 20;\n        numbers[2] = 30;\n        numbers[3] = 40;\n        numbers[4] = 50;\n\n        // Actualización de un elemento\n        numbers[2] = 35; // Cambia el valor del índice 2 a 35\n\n        // Borrar un elemento (sobreescribir con 0)\n        numbers[4] = 0;\n\n        // Ordenar el arreglo\n        Arrays.sort(numbers);\n\n        // Imprimir el arreglo\n        System.out.println(\"Array Unidimensional:\");\n        for (int indice : numbers) {\n            System.out.println(indice);\n        }\n\n        // ---- ARRAY BIDIMENSIONAL ----\n        System.out.println(\"\\n----- ARRAY BIDIMENSIONAL -----\");\n\n        // Creación de un arreglo bidimensional de enteros con 3 filas y 4 columnas\n        int[][] matriz = new int[3][4];\n\n        // Inserción de valores en la matriz\n        value = 1;\n        for (int i = 0; i < matriz.length; i++) {\n            for (int j = 0; j < matriz[i].length; j++) {\n                matriz[i][j] = value++;\n            }\n        }\n\n        // Actualización de un elemento\n        matriz[1][2] = 70; // Cambia el valor en la fila 1, columna 2 a 70\n\n        // Borrar un elemento (sobreescribir con 0)\n        matriz[2][3] = 0;\n\n        // Imprimir la matriz\n        System.out.println(\"Array Bidimensional:\");\n        for (int i = 0; i < matriz.length; i++) {\n            for (int j = 0; j < matriz[i].length; j++) {\n                System.out.print(matriz[i][j] + \" \");\n            }\n            System.out.println();\n        }\n\n        // ---- ARRAY MULTIDIMENSIONAL ----\n        System.out.println(\"\\n----- ARRAY MULTIDIMENSIONAL -----\");\n\n        // Creación de un arreglo tridimensional de enteros con dimensiones 2x3x4\n        int[][][] cube = new int[2][3][4];\n\n        // Inserción de valores en el arreglo tridimensional\n        value = 1;\n        for (int i = 0; i < cube.length; i++) {\n            for (int j = 0; j < cube[i].length; j++) {\n                for (int k = 0; k < cube[i][j].length; k++) {\n                    cube[i][j][k] = value++;\n                }\n            }\n        }\n\n        // Actualización de un elemento\n        cube[1][2][3] = 99; // Cambia el valor en la capa 1, fila 2, columna 3 a 99\n\n        // Borrar un elemento (sobreescribir con 0)\n        cube[0][0][0] = 0;\n\n        // Imprimir el arreglo tridimensional\n        System.out.println(\"Array Multidimensional:\");\n        for (int i = 0; i < cube.length; i++) {\n            for (int j = 0; j < cube[i].length; j++) {\n                for (int k = 0; k < cube[i][j].length; k++) {\n                    System.out.print(cube[i][j][k] + \" \");\n                }\n                System.out.println();\n            }\n            System.out.println();\n        }\n\n        // ---- ARRAYLIST ----\n        System.out.println(\"----- ARRAYLIST -----\");\n        /*\n         * Admite duplicados y es ordered.\n         * \n         * Los elementos tienen un índice asociado que indica\n         * la posición dentro de la lista, comienza en 0.\n         * \n         * Acceso en modo aleatorio rápido pero lento secuencialmente.\n         * \n         * No es sincronizada.\n         */\n\n        // Creación de un ArrayList de cadenas\n        ArrayList<String> list = new ArrayList<>();\n\n        // Inserción de elementos\n        list.add(\"Banana\");\n        list.add(\"Apple\");\n        list.add(\"Cherry\");\n\n        // Actualización de un elemento\n        list.set(1, \"Blueberry\"); // Cambia \"Apple\" por \"Blueberry\"\n\n        // Ordenar la lista\n        Collections.sort(list);\n\n        // Borrar un elemento\n        list.remove(\"Cherry\");\n\n        // Imprimir la lista\n        System.out.println(\"ArrayList:\");\n        System.out.println(list);\n\n        /*\n         * ----- Métodos -----\n         * ----- list.add(elemento)\n         * Añade un elemento primitivo(autoboxing) o referenciado.\n         * Lo coloca al final.\n         * Devuelve un boolean si se modificó la colección.\n         * \n         * ----- list.add(posicion, elemento)\n         * Añade el elemento en una posición dada.\n         * Las anteriores han de estar ocupadas.\n         * Desplaza hacia arriba al resto.\n         * Devuelve void.\n         * \n         * ----- list.addAll(Collection)\n         * Añadir todo el contenido de un Collection a la colección actual.\n         * \n         * ----- list.set(posicion, elemento)\n         * Introduce un elemento en la posición indicada.\n         * Si ya estaba ocupada, despalza hacia arriba a los otros.\n         * \n         * ----- list.add(null)\n         * Podemos añadir null.\n         * \n         * ----- list.get(posicion)\n         * Obtener el elemento de la posición indicada.\n         * Recuperamos Object, luego hacer Casting (salvo que usemos genéricos).\n         * \n         * ----- list.contains(elemento)\n         * Comprueba si el elemento existe.\n         * Devuelve un true / false (podemos tener más de 1, luego utilizar bucle\n         * WHILE).\n         * \n         * ----- list.indexOf(elemento)\n         * Primera posición que cupa un determinado elemento (puede haber varios),\n         * -1 si no lo encuentra.\n         * \n         * ----- list.lastIndexOf(elemento)\n         * Última posición que ocupa un determinado elemento (puede haber varios),\n         * -1 si no lo encuentra.\n         * \n         * ----- list.isEmpty()\n         * Booleano que nos dice si hay elementos (también se toman en cuenta los null).\n         * \n         * ----- list.size()\n         * Tamaño del ArrayList.\n         * También cuenta los null.\n         * \n         * ----- list.iterator()\n         * Obtener iterador para recorrer elementos (hasNext() - next()).\n         * \n         * ----- list.toArray()\n         * Obtener un Array de Object con los elementos contenidos en la colección.\n         * \n         * ----- list.remove(posicion)\n         * Devuelve el elemento contenido en una determinada posición\n         * y a continuaciñon lo elimina de la colección.\n         * \n         * ----- list.remove(Objeto)\n         * Elimina el objeto de la posición (podemos tener más de 1).\n         * Devuelve true si la lista ha sido modificada.\n         * \n         * ----- list.clear()\n         * Borra todo, incluidos los null.\n         */\n\n        // ---- LINKEDLIST ----\n        System.out.println(\"\\n----- LINKEDLIST -----\");\n        /*\n         * Lista simplemente enlazada.\n         * Cada elemento dispone de la dirección del elemento que le sigue en la lista.\n         * \n         * Acceso secuencial rápido tanto para lectura como para escritura,\n         * pero lento en acceso aleatorio.\n         * \n         * Permite duplicados y no está sincronziada.\n         * Es ordered.\n         */\n\n        // Creación de un LinkedList de cadenas\n        LinkedList<String> linkedList = new LinkedList<>();\n\n        // Inserción de elementos\n        linkedList.add(\"Banana\");\n        linkedList.add(\"Apple\");\n        linkedList.add(\"Cherry\");\n\n        // Actualización de un elemento\n        linkedList.set(1, \"Blueberry\"); // Cambia \"Apple\" por \"Blueberry\"\n\n        // Ordenar la lista\n        linkedList.sort(null); // Ordena usando el orden natural de los elementos\n\n        // Borrar un elemento\n        linkedList.remove(\"Cherry\");\n\n        // Imprimir la lista\n        System.out.println(\"LinkedList:\");\n        System.out.println(linkedList);\n\n        /*\n         * Métodos similares al de ArrayList, incorpora métodos propios.\n         * ----- Métodos -----\n         * ----- linkedList.addFirst(elemento)\n         * Añade el elemento al principio de la colección.\n         * \n         * ----- linkedList.offerFirst(elemento)\n         * Lo mismo (java 6).\n         * \n         * ----- linkedList.addLast(elemento)\n         * Añade el elemento al final de la colección\n         * \n         * ----- linkedList.offerLast(elemento)\n         * Lo mismo (java 6).\n         * \n         * ----- linkedList.peekFirst()\n         * Obtiene el primer elemento sin borrarlo de la colección\n         * \n         * ----- linkedList.peekLast()\n         * Obtiene el último elemento sin borrarlo de la colección\n         * \n         * ----- linkedList.pollFirst()\n         * Extrae el primer elemento de la colección.\n         * (extraer == obtener y luego quitarlo de la colección).\n         * Desplaza al resto de elementos.\n         * \n         * ----- linkedList.pollLast()\n         * Extrae el último elemento de la colección.\n         * (Desplaza al resto de elementos).\n         * \n         * ----- linkedList.push(elemento)\n         * Introduce el elemento al principio de la colección.\n         * Desplaza al resto.\n         * Pila tipo LIFO.\n         * \n         * ----- linkedList.pop()\n         * Extrae el último elemento de la colección.\n         * Pila tipo LIFO.\n         */\n\n        // ---- VECTOR ----\n        // System.out.println(\"\\n----- VECTOR -----\");\n        /*\n         * De las tres implementaciones de la interfaz List,\n         * es la única que está sincronizada.\n         * También permite duplicados y es ordered.\n         * \n         * Si no es necesario controla la concurrencia en multiacceso,\n         * sería mejor utilizar un ArrayList.\n         * Dicho control sacrifica buena parte del rendimiento de la clase.\n         */\n\n        /*\n         * ----- Métodos -----\n         * ----- v.capacity()\n         * Obtiene la capacidad inicial con la que se ha creado la instancia de la clase\n         * Vector.\n         * \n         * ----- v.size()\n         * Obtiene el número total de elementos contenido en el vector\n         * (posiciones realmente oocupadas, no la capacidad inicial)\n         * \n         * ----- v.elementAt(posicion)\n         * Obtiene el elemento contenido en la posición indicada.\n         * Se recupera como Object, salvo que se haya usado genéricos.\n         * \n         * ----- v.get(posicion)\n         * Igual que el anterior.\n         * \n         * ----- v.firstElement()\n         * Obtiene el primer elemento de la colección\n         * \n         * ----- v.lastElement()\n         * Obtiene el último elemento de la colección\n         * \n         * ----- v.add(posicion, elemento)\n         * Añade el elemento en la posición indicada.\n         * Operación NO SINCRONIZADA.\n         * \n         * ----- v.insertElementAt(elemento, posicion)\n         * Igual que el anterior, pero esta vez la operación\n         * ES SINCRONIZADA.\n         * \n         * ----- v.elements()\n         * Devuelve un Enumeration que contiene los elementos de la colección.\n         * \n         * ----- v.iterator()\n         * Devuelve un Iterator con el que poder recorrer los elementos de la colección\n         * (secuencial, hacia abajo, necesita recarga).\n         * \n         * ----- v.removeElementAt(posicion)\n         * Elimina el elemento de la posición indicada.\n         * Devuelve void.\n         * Operación sincronizada.\n         * \n         * ----- v.indexOf(elemento)\n         * Devuelve la posición que ocupa un determinado elemento\n         * (podemos tener más de 1).\n         * \n         * ----- v.removeAllElements()\n         * Elimina todos los elementos de la colección\n         */\n\n        // ---- HASHSET ----\n        System.out.println(\"\\n----- HASHSET -----\");\n        // No es ordered.\n\n        // Creación de un HashSet de cadenas\n        HashSet<String> set = new HashSet<>();\n\n        // Inserción de elementos\n        set.add(\"Banana\");\n        set.add(\"Apple\");\n        set.add(\"Cherry\");\n\n        // Intentar insertar un elemento duplicado\n        set.add(\"Apple\"); // No se agregará porque \"Apple\" ya está en el set\n\n        // Borrar un elemento\n        set.remove(\"Cherry\");\n\n        // Imprimir el conjunto\n        System.out.println(\"HashSet:\");\n        System.out.println(set);\n\n        // Los métodos más importantes son los ya vistos en la interface List.\n\n        // ---- TREESET ----\n        System.out.println(\"\\n----- TREESET -----\");\n        /*\n         * Los SortedSet (y en los Map, los denominados SortedMap)\n         * organizan sus elementos como una ordenación natural.\n         * Dicha ordenación es automática.\n         * \n         * No permite mezclar tipos de datos incompatibles.\n         * Es sorted.\n         */\n\n        // Creación de un TreeSet de cadenas (se mantiene ordenado)\n        TreeSet<String> treeSet = new TreeSet<>();\n\n        // Inserción de elementos\n        treeSet.add(\"Banana\");\n        treeSet.add(\"Apple\");\n        treeSet.add(\"Cherry\");\n\n        // Borrar un elemento\n        treeSet.remove(\"Cherry\");\n\n        // Imprimir el conjunto\n        System.out.println(\"TreeSet:\");\n        System.out.println(treeSet);\n\n        /*\n         * ----- Métodos -----\n         * ----- treeSet.descendingIterator()\n         * Obtiene un iterator de recorrido descendente (el normal tiene recorrido\n         * ascendete).\n         * \n         * ----- treeSet.ceiling(elemento)\n         * Devuelve el mismo o el siguiente mayor que se encuentre en la colección\n         * respecto al elemento indicado.\n         * \n         * ----- treeSet.first()\n         * Obtiene el primer elemento.\n         * \n         * ----- treeSet.floor(elemento)\n         * Obtiene el elemento de la colección que sea igual o el más próximo por\n         * defecto, con respecto al indicado.\n         * \n         * ----- treeSet.higher(elemento)\n         * Obtiene el elemento de la colección que sea igual o el más próximo por\n         * exceso, con respecto al indicado.\n         * \n         * ----- treeSet.headSet(elemento)\n         * Obtiene un subconjunto inferior en ordenación al elemento indicado.\n         * \n         * ----- treeSet.tailSet(elemento)\n         * Obtiene un subconjunto superior en ordenación al elemento indicado.\n         */\n\n        // ---- HASHTABLE ----\n        // System.out.println(\"\\n----- HASHTABLE -----\");\n        /*\n         * Esta colección es de tipo sincronizada, al igual que ocurría con Vector en\n         * las listas.\n         * \n         * No se admite null, ni para el campo key ni para el campo value (HashMap si lo\n         * permite).\n         */\n\n        /*\n         * ----- Métodos -----\n         * ----- ht.put(clave, valor)\n         * Introduce el elemento de la colección.\n         * Si la clave ya existe, se devuelve el valor antiguo\n         * y luego se reemplaza con el nuevo.\n         * \n         * ----- ht.containsKey(clave)\n         * Devuelve un booleano que indica si la clave existe.\n         * \n         * ----- ht.containsValue(valor)\n         * Devuelve un booleano que indica si el valor existe.\n         * \n         * ----- ht.get(clave)\n         * Devuelve el valor asociado a la clave indicada.\n         * \n         * ----- ht.keys()\n         * Devuelve un Enumeration con las claves de la colección.\n         * \n         * ----- ht.values()\n         * Devuelve un Collection con los valores de la colección.\n         * (Obtener de aquí el Iterator ***).\n         * \n         * ----- ht.elements()\n         * Devuelve un Enumeration con los valores de la colección.\n         * \n         * ----- ht.values().iterator()\n         * *** devuelve un Iterador para recorrer la colección.\n         * Se ha de obtener primero el Collection correspondiente y de él, el Iterator.\n         * \n         * ----- ht.remove(clave)\n         * Devuelve el valor y a continuación elimina el registro que coincida con la\n         * clave indicada.\n         * Si la clave no existe no ocurre nada.\n         */\n\n        // ---- HASHMAP ----\n        System.out.println(\"\\n----- HASHMAP -----\");\n        /*\n         * A diferencia de Hashtable, sí se permite null en el campo clave\n         * y en el campo valor.\n         */\n\n        // Creación de un HashMap de cadenas a enteros\n        HashMap<String, Integer> map = new HashMap<>();\n\n        // Inserción de pares clave-valor\n        map.put(\"Banana\", 1);\n        map.put(\"Apple\", 2);\n        map.put(\"Cherry\", 3);\n\n        // Actualización de un valor\n        map.put(\"Apple\", 4); // Cambia el valor de \"Apple\" a 4\n\n        // Borrar un elemento\n        map.remove(\"Cherry\");\n\n        // Imprimir el mapa\n        System.out.println(\"HashMap:\");\n        System.out.println(map);\n\n        /*\n         * Mismos métodos que Hashtable.\n         * \n         * NO TIENE elements()\n         * que devolvía un Enumeration\n         * con los valores de la colección !!!!!\n         */\n\n        // ---- LINKEDHASHMAP ----\n        // System.out.println(\"\\n----- LINKEDHASHMAP -----\");\n        // Un mapa que se basa en una lista enlazada\n\n        // Los métodos son los ya vistos hasta ahora.\n\n        // ---- TREEMAP ----\n        System.out.println(\"\\n----- TREEMAP -----\");\n        // Mapa ordenado. Elementos de menor a mayor.\n\n        // Creación de un TreeMap de cadenas a enteros (mantiene el orden de las claves)\n        TreeMap<String, Integer> treeMap = new TreeMap<>();\n\n        // Inserción de pares clave-valor\n        treeMap.put(\"Banana\", 1);\n        treeMap.put(\"Apple\", 2);\n        treeMap.put(\"Cherry\", 3);\n\n        // Actualización de un valor\n        treeMap.put(\"Apple\", 4);\n\n        // Borrar un elemento\n        treeMap.remove(\"Cherry\");\n\n        // Imprimir el mapa\n        System.out.println(\"TreeMap:\");\n        System.out.println(treeMap);\n\n        /*\n         * ----- Métodos -----\n         * ----- treeMap.descendingMap()\n         * Obtiene un NavigableMap para recorrer la colección\n         * en orden inverso al natural. (mayor a menor).\n         * \n         * ----- treeMap.firstKey()\n         * Obtiene la primera clave de la colección\n         * \n         * ----- treeMap.lastKey()\n         * Obtiene la última clave de la colección\n         * \n         * ----- treeMap.floorKey(clave)\n         * Obtiene la clave indicada o la más próxima a ésta por defecto.\n         * \n         * ----- treeMap.lowerKey(clave)\n         * Igual que la anterior.\n         * \n         * ----- treeMap.higherKey(clave)\n         * Obtiene la clave indicada o la más próxima a ésta por exceso.\n         */\n\n        // ----- OPCIONAL -----\n        HashMap<String, Integer> miAgenda = new HashMap<>();\n        menu(miAgenda);\n        sc.close();\n    }\n    // AGENDA\n    // menú\n    public static void menu(HashMap<String, Integer> map) {\n        int opcion;\n        System.out.println(\"\\n----- AGENDA DE CONTACTOS -----\");\n        System.out.println(\"\\t1. BÚSQUEDA\");\n        System.out.println(\"\\t2. INSERCIÓN\");\n        System.out.println(\"\\t3. ACTUALIZACIÓN\");\n        System.out.println(\"\\t4. ELIMINACIÓN\");\n        System.out.println(\"\\t5. SALIR\");\n        System.out.print(\"Elige su opción [1-5]: \");\n\n        opcion = getValidIntInput(1, 5);\n\n        agenda(map, opcion);\n    }\n\n    public static void agenda(HashMap<String, Integer> map, int opcion) {\n        switch (opcion) {\n            case 1:\n                busquedaAgenda(map);\n                break;\n            case 2:\n                insercionAgenda(map);\n                break;\n            case 3:\n                actualizacionAgenda(map);\n                break;\n            case 4:\n                eliminacionAgenda(map);\n                break;\n            case 5:\n                System.out.println(\"\\n----- Fin del programa -----\\n\");\n                break;\n        }\n    }\n\n    // 1\n    public static void busquedaAgenda(HashMap<String, Integer> map) {\n        int opcion = 0;\n        String nombre;\n\n        while (opcion != 3) {\n            System.out.println(\"\\n----- MIS CONTACTOS -----\");\n            System.out.println(\"\\t1. VER (TODOS)\");\n            System.out.println(\"\\t2. BUSCAR POR NOMBRE\");\n            System.out.println(\"\\t3. SALIR\");\n            System.out.print(\"Elige su opción [1-3]: \");\n\n            opcion = getValidIntInput(1, 3);\n\n            switch (opcion) {\n                case 1:\n                    System.out.println(map);\n                    break;\n                case 2:\n                    System.out.print(\"\\nEscribe el nombre del contacto\\n> \");\n                    nombre = sc.next();\n                    if (map.containsKey(nombre)) {\n                        System.out.println(\"Número de contacto: \" + map.get(nombre)); // da el teléfono\n                    } else {\n                        System.out.println(\"Contacto no encontrado.\");\n                    }\n                    break;\n                case 3:\n                    menu(map);\n            }\n        }\n    }\n\n    // 2\n    public static void insercionAgenda(HashMap<String, Integer> map) {\n        String nombre;\n        int telefono;\n\n        System.out.print(\"\\nInserta el nombre del contacto\\n> \");\n        nombre = sc.next();\n\n        System.out.print(\"Inserta el número de teléfono del contacto\");\n        telefono = getValidNumber();\n\n        map.put(nombre, telefono); // Clave-Valor\n\n        menu(map);\n    }\n\n    // 3\n    public static void actualizacionAgenda(HashMap<String, Integer> map) {\n        String nombre;\n        int telefono;\n\n        System.out.print(\"\\nIntroduzca el nombre del contacto a editar\\n> \");\n        nombre = sc.next();\n\n        if (map.containsKey(nombre)) {\n            System.out.print(\"Introduzca el nuevo número del contacto\");\n            telefono = getValidNumber();\n            map.put(nombre, telefono); // Se actualiza el número del contacto\n        } else {\n            System.out.println(\"Contacto no encontrado.\");\n        }\n        menu(map);\n    }\n\n    // 4\n    public static void eliminacionAgenda(HashMap<String, Integer> map) {\n        String nombre;\n\n        System.out.print(\"\\nEscribe el nombre del contacto a borrar\\n> \");\n        nombre = sc.next();\n        if (map.containsKey(nombre)) {\n            System.out.println(nombre + \" ha sido borrado...\");\n            map.remove(nombre);\n        } else {\n            System.out.println(\"Contacto no encontrado.\");\n        }\n        menu(map);\n    }\n\n    private static int getValidNumber() {\n        while (true) {\n            try {\n                System.out.print(\"\\n> \");\n                int input = sc.nextInt();\n                if (Integer.toString(input).length() >= 9) {\n                    return input;\n                } else {\n                    System.out.println(\"El mínimo son 9 dígitos.\");\n                }\n            } catch (InputMismatchException e) {\n                System.out.println(\"Número inválido. Por favor, introduce un número válido.\");\n                sc.next();\n            }\n        }\n    }\n\n    // Validador de Inputs (int) con Scanner\n    private static int getValidIntInput(int min, int max) {\n        while (true) {\n            try {\n                System.out.print(\"\\n> \");\n                int input = sc.nextInt();\n                if (input >= min && input <= max) {\n                    return input;\n                } else {\n                    System.out.println(\n                            \"\\nOption out of bounds. Please enter a number between \" + min + \" and \" + max + \".\\n\");\n                }\n            } catch (InputMismatchException e) {\n                System.out.println(\"\\nInvalid input. Please enter a valid integer.\\n\");\n                sc.next(); // Clear invalid input\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/AmadorQuispe.java",
    "content": "import java.util.Arrays;\nimport java.util.Stack;\nimport java.util.TreeMap;\nimport java.util.ArrayList;\nimport java.util.LinkedList;\nimport java.util.Map;\nimport java.util.Optional;\nimport java.util.Properties;\nimport java.util.Comparator;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Queue;\nimport java.util.Scanner;\nimport java.util.ArrayDeque;\nimport java.util.TreeSet;\nimport java.util.stream.Stream;\n\npublic class AmadorQuispe {\n    // Arrays, son del mismo tipo y de tamaño fijo\n    // Se acceden por un indice\n    public static void arrays() {\n        // Crear\n        int[] integers = new int[5]; // crea un array con valores por defecto 0\n        // String[] names = { \"Amador\", \"AMsoft\", \"AMcodex\" }; otro forma de inicializar\n        // Agregar\n        integers[0] = 3;\n        integers[1] = 5;\n        integers[2] = 6;\n        integers[3] = 7;\n        integers[4] = 8;\n        for (int n : integers) {\n            System.out.println(n);\n        }\n        // modificar\n        integers[2] = 12;\n        System.out.println(\"Array modificado\");\n        for (int n : integers) {\n            System.out.println(n);\n        }\n        // Eliminar\n        // No es posible eliminar, podemos asignar su valor por defecto.\n\n        // ordenar\n        // se puede usar la clase Arrays del lenguaje.\n        Arrays.sort(integers);\n        System.out.println(\"Array ordenado\");\n        for (int n : integers) {\n            System.out.println(n);\n        }\n    }\n\n    // Array de Arrays\n    public static void matriz() {\n        // creación y inserción\n        int[][] numbers = { { 1, 2 }, { 2, 2 }, { 2, 3 } };\n        // modificación\n        numbers[0][1] = 8;\n        // Eliminación\n        // No es posible eliminar\n        // ordenar\n        Arrays.sort(numbers);\n    }\n\n    // ArrayList, pueden cambiar de tamaño durante la ejecución del programa\n    public static void arrayList() {\n        // Initialization.\n        ArrayList<String> studentNames = new ArrayList<>();\n        // Insertar\n        studentNames.add(\"Pedro\");\n        studentNames.add(\"Juan\");\n        studentNames.add(\"Pepe\");\n        studentNames.add(\"Amador\");\n        // Modificar, se puede modificar por el indice\n        studentNames.set(0, \"Pedro F\"); // modificar el valor del indice 0\n        // Eliminar, se puede eliminar por el indice\n        studentNames.remove(0);// Elimina por el indice 0\n\n        // Ordenar\n        studentNames.sort(Comparator.naturalOrder()); // ordena en orden alfabético\n        for (String name : studentNames) {\n            System.out.println(name);\n        }\n    }\n\n    // LinkedList, Una clase que añade métodos adicionales y permite disponer de una\n    // lista doblemente enlazada en la que las inserciones y modificaciones de la\n    // lista sean muy rápidas\n    public static void linkedList() {\n        // Initialization.\n        LinkedList<String> studentNames = new LinkedList<>();\n        // Insertar\n        studentNames.add(\"Pedro\");\n        studentNames.add(\"Juan\");\n        studentNames.add(\"Pepe\");\n        studentNames.add(\"Amador\");\n        studentNames.addFirst(\"Mia\");// inserta al inicio\n\n        // Modificar, se puede modificar por el indice\n        studentNames.set(0, \"Pedro F\"); // modificar el valor del indice 0\n\n        // Eliminar, se puede eliminar por el indice\n        studentNames.remove(\"Pedro\");// Elimina por el indice 0\n        studentNames.removeLast();// Elimina el ultimo\n        // Ordenar\n        studentNames.sort(Comparator.naturalOrder()); // ordena en orden alfabético\n        for (String name : studentNames) {\n            System.out.println(name);\n        }\n    }\n\n    // Stack, representa una pila en la que el último elemento agregado es el\n    // primero en ser eliminado\n    public static void stack() {\n        Stack<String> studentNames = new Stack<>();\n        // Agregar\n        studentNames.push(\"Pedro\");\n        studentNames.push(\"Juan\");\n        studentNames.push(\"Pepe\");\n        studentNames.add(\"Amador\");\n        System.out.println(\"Contenido inicial de la pila: \" + studentNames);\n        // Modificar.\n        studentNames.set(0, \"Pedro F\");\n        System.out.println(\"Contenido modificado de la pila: \" + studentNames);\n        // Eliminar\n        studentNames.pop();\n        System.out.println(\"Contenido post eliminación de la pila: \" + studentNames);\n        // ordenar, es posible ordenar pero no es necesaria\n        studentNames.sort(Comparator.naturalOrder());\n        System.out.println(\"Ordenado: \" + studentNames);\n    }\n\n    // HashSet, permite añadir elementos no repetidos al grupo\n    public static void hashSet() {\n        // initialization\n        HashSet<String> setStudents = new HashSet<>();\n        // inserción\n        setStudents.add(\"Mia\");\n        setStudents.add(\"Pepe\");\n        setStudents.add(\"Amador\");\n        setStudents.add(\"Carlos\");\n        setStudents.add(\"Mia\"); // Se intenta agregar duplicado.\n        System.out.println(\"Lista inicial \" + setStudents);\n        // modificación\n        // No es posible modificar, lo que se puede hacer es eliminar y insertar\n        // Eliminación\n        setStudents.remove(\"Pepe\");\n        System.out.println(\"Lista post eliminación \" + setStudents);\n        // ordenar\n        // Siempre se guardan en desorden, java usa hash para fácil acceso\n    }\n\n    // TreeSet, permite añadir elementos no repetidos al grupo pero ordenados (orden\n    // natural)\n    public static void treeSet() {\n        // initialization\n        TreeSet<String> setStudents = new TreeSet<>((s1, s2) -> Integer.compare(s1.length(), s2.length()));\n        // inserción\n        setStudents.add(\"Mia\");\n        setStudents.add(\"Pepe\");\n        setStudents.add(\"Amador\");\n        setStudents.add(\"Carlos\");\n        setStudents.add(\"Mia\"); // Se intenta agregar duplicado.\n        System.out.println(\"Lista inicial \" + setStudents);\n        // modificación\n        // No es posible modificar, lo que se puede hacer es eliminar y insertar\n\n        // Eliminación\n        setStudents.remove(\"Pepe\");\n        System.out.println(\"Lista post eliminación \" + setStudents);\n        // ordenar\n        // Siempre se guardan en desorden, java usa hash para fácil acceso\n\n    }\n\n    // Queue, para manejar colas, primero en entrar, primero en salir\n    public static void deQueue() {\n        Queue<String> cola = new ArrayDeque<>();\n        // Agregar elementos a la cola\n        cola.offer(\"Mia\");\n        cola.offer(\"Amador\");\n        cola.offer(\"Carlos\");\n        // Mostrar la cola\n        System.out.println(\"Cola: \" + cola);\n\n        // Obtener y eliminar el primer elemento de la cola\n        String primerElemento = cola.poll();\n        System.out.println(\"Primer elemento obtenido y eliminado: \" + primerElemento);\n\n        // Mostrar la cola después de la operación de poll\n        System.out.println(\"Cola después de poll: \" + cola);\n\n        // Obtener el primer elemento sin eliminarlo\n        String primerElementoPeek = cola.peek();\n        System.out.println(\"Primer elemento obtenido sin eliminar: \" + primerElementoPeek);\n\n        // Mostrar la cola después de peek\n        System.out.println(\"Cola después de peek: \" + cola);\n        cola.remove();\n\n    }\n\n    // HashMap, Un diccionario es una colección de pares clave-valor\n    public static void hashMap() {\n        // Initialization un HashMap\n        HashMap<String, Integer> hashMap = new HashMap<>();\n\n        // Agregar elementos al HashMap\n        hashMap.put(\"Uno\", 1);\n        hashMap.put(\"Dos\", 2);\n        hashMap.put(\"Tres\", 3);\n        // Modificar un elemento del HashMap\n        hashMap.put(\"Uno\", 4);\n        // Imprimir todos los elementos del HashMap\n        System.out.println(\"Elementos del HashMap \" + hashMap);\n        // Eliminar un elemento del HashMap\n        hashMap.remove(\"Uno\");\n        System.out.println(\"Elementos del HashMap post Eliminación \" + hashMap);\n        // Obtener un valor usando una clave\n        int valorDos = hashMap.get(\"Dos\");\n        System.out.println(\"Valor asociado a 'Dos': \" + valorDos);\n        // Ordenar\n        // !No se garantiza orden\n    }\n\n    // HashMap, Un diccionario es una colección de pares clave-valor, con orden\n    // natural o personalizado\n    public static void treeMap() {\n        // Crear un TreeMap\n        TreeMap<String, Integer> treeMap = new TreeMap<>();\n        treeMap.put(\"Uno\", 1);\n        treeMap.put(\"Dos\", 2);\n        treeMap.put(\"Tres\", 3);\n        treeMap.put(\"Cero\", 0);\n        // Mostrar todo los elementos\n        System.out.println(\"Mostrar todo los elementos \" + treeMap);\n        // Modificar\n        treeMap.put(\"Cero\", 9);\n        System.out.println(\"Mostrar todo los elementos, con mod \" + treeMap);\n        // Eliminar elemento del TreeMap\n        treeMap.remove(\"Cero\");\n        System.out.println(\"Mostrar elementos post eliminación \" + treeMap);\n    }\n\n    // Properties, gestiona pares clave-valor, diseñada para cadenas de texto. Usada\n    // para\n    // configuraciones y archivos de propiedades en aplicaciones Java.\n    public static void properties() {\n        Properties properties = new Properties();\n        // Agregar elementos a properties\n        properties.setProperty(\"app-name\", \"App\");\n        properties.setProperty(\"app-language\", \"ES\");\n        System.out.println(\"Mostrar elementos \" + properties);\n        // Modificar\n        properties.setProperty(\"app-name\", \"App Gestion\");\n        System.out.println(\"Mostrar modificado \" + properties);\n        // Eliminar\n        properties.remove(\"app-name\");\n        System.out.println(\"Mostrar post eliminación \" + properties);\n        // Ordenación\n        // No se garantiza orden.\n    }\n\n    public static void agenda() {\n\n    }\n\n    public static void main(String[] args) {\n        // Arrays\n        arrays();\n        matriz();\n        // Listas\n        arrayList();\n        linkedList();\n        stack();\n        // Sets\n        hashSet();\n        treeSet();\n        // --Queue (Colas)\n        deQueue();\n        // --Map (mapas)\n        hashMap();\n        treeMap();\n        properties();\n        // Opcional - Agenda\n        Agenda agenda = new Agenda();\n        while (true) {\n            String optSelect = agenda.showMenu();\n            if (!Character.isDigit(optSelect.charAt(0))) {\n                System.out.println(\"Introduzca un número\");\n            } else {\n                int numSelect = optSelect.charAt(0) - '0';\n                switch (agenda.getOperation(numSelect)) {\n                    case INSERT:\n                        agenda.insert();\n                        break;\n                    case SEARCH:\n                        agenda.search();\n                        break;\n                    case DELETE:\n                        agenda.delete();\n                        break;\n                    case UPDATE:\n                        agenda.update();\n                        break;\n                    case SHOW:\n                        agenda.show();\n                        break;\n                    case EXIT:\n                        System.out.println(\"!!! Hasta luego, vuelva pronto!\");\n                        System.exit(0);\n                        break;\n                    default:\n                        System.out.println(\"Ingresa una opción valida\");\n                        break;\n                }\n            }\n        }\n\n    }\n}\n\nclass Agenda {\n    public enum operations {\n        SEARCH(1),\n        INSERT(2),\n        UPDATE(3),\n        DELETE(4),\n        SHOW(5),\n        EXIT(6);\n\n        private final int value;\n\n        operations(int value) {\n            this.value = value;\n        }\n    }\n\n    private Map<String, Long> agenda = new HashMap<>();\n    String optSelect;\n    private Scanner sc = new Scanner(System.in);\n\n    public String showMenu() {\n        System.out.println(\"-----------------------\");\n        System.out.println(\"<<< MENU DE AGENDA  >>>\");\n        System.out.println(\"-----------------------\");\n        System.out.println(\"Introduce el número de la opción que quieres realizar\");\n        for (operations ope : operations.values()) {\n            System.out.println(ope.value + \"> \" + ope);\n        }\n        System.out.print(\"Ingrese la opción :\");\n        optSelect = sc.next();\n        sc.nextLine();\n        return optSelect;\n    }\n\n    public operations getOperation(int value) {\n        Optional<operations> op = Stream.of(operations.values()).filter(o -> o.value == value).findFirst();\n        return op.isPresent() ? op.get() : null;\n    }\n\n    public void insert() {\n        String name;\n        Long number;\n        do {\n            System.out.print(\"Ingresa el nombre del contacto :\");\n            name = sc.next();\n            if (name.trim().length() < 3) {\n                System.out.println(\"! El nombre no puede ser vació\");\n            }\n        } while (name.trim().length() < 3);\n\n        do {\n            System.out.print(\"Ingresa el número del contacto :\");\n            number = sc.nextLong();\n            if (Long.toString(number).length() > 11) {\n                System.out.println(\"! El número debe ser máximo de 11\");\n            }\n        } while (Long.toString(number).length() > 11);\n\n        agenda.put(name, number);\n        System.out.println(\"(- Contacto agregado correctamente\");\n    }\n\n    public void search() {\n        System.out.print(\"Ingresa el contacto a buscar :\");\n        String name = sc.next();\n        if (agenda.containsKey(name)) {\n            System.out.println(\"El numero de \" + name + \" es: \" + agenda.get(name));\n        } else {\n            System.out.println(\"El usuario no se encuentra en el sistema! \");\n        }\n    }\n\n    public void delete() {\n        System.out.print(\"Ingresa el contacto a eliminar :\");\n        String name = sc.next();\n        if (agenda.containsKey(name)) {\n            agenda.remove(name);\n            System.out.println(\"Contacto Eliminado!\");\n        } else {\n            System.out.println(String.format(\"El usuario %s no se encuentra en el sistema!\", name));\n        }\n    }\n\n    public void update() {\n        System.out.print(\"Que contacto desea actualizar? :\");\n        String name = sc.next();\n        if (agenda.containsKey(name)) {\n            Long number;\n            do {\n                System.out.print(\"Ingresa el nuevo número del contacto :\");\n                number = sc.nextLong();\n                if (Long.toString(number).length() > 11) {\n                    System.out.println(\"! El número debe ser máximo de 11\");\n                }\n            } while (Long.toString(number).length() > 11);\n            agenda.replace(name, number);\n            System.out.println(\"(- Contacto actualizado!\");\n        } else {\n            System.out.println(\"! El usuario no se encuentra en el sistema!\");\n        }\n    }\n\n    public void show() {\n        System.out.println(\"Tus contactos\");\n        System.out.println(\"----------------\");\n        agenda.forEach((c, n) -> {\n            System.out.println(String.format(\"%s : %d\", c, n));\n        });\n        System.out.println(\"----------------\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/AnaLauDB.java",
    "content": "import java.util.Stack;\nimport java.util.Queue;\nimport java.util.LinkedList;\nimport java.util.HashMap;\nimport java.util.Scanner;\n\npublic class AnaLauraDB {\n    public static void main(String[] args) {\n        // creación de todas las estructuras soportadas por defecto\n\n        // Arreglos\n        int[] num = new int[10];\n        for (int i = 0; i < num.length; i++) {\n            num[i] = i + 1; // inicializar el arreglo con ceros\n            System.out.println(\"Elemento del arreglo num: \" + num[i]);\n        }\n\n        // Pilas y colas\n        Stack<Integer> pilas = new Stack<>();\n        pilas.push(99); // ejemplo de uso: agregar un elemento\n        int elementoPila = pilas.pop(); // obtener y eliminar el elemento\n        System.out.println(\"Elemento de la pila: \" + elementoPila);\n\n        Queue<Integer> colas = new LinkedList<>();\n        colas.add(42); // ejemplo de uso: agregar un elemento\n        int elementoCola = colas.poll(); // obtener y eliminar el elemento\n        System.out.println(\"Elemento de la cola: \" + elementoCola);\n\n        // Matrices y diccionarios\n        int[][] matriz = new int[2][2];\n        // Llenar la matriz con valores de ejemplo\n        int valor = 1;\n        for (int i = 0; i < matriz.length; i++) {\n            for (int j = 0; j < matriz[i].length; j++) {\n                matriz[i][j] = valor++;\n            }\n        }\n        System.out.println(\"Elemento de la matriz: \" + matriz[0][0]);\n        Scanner scanner = new Scanner(System.in);\n        boolean running = true;\n        final int MAX_DIGITS = 11;\n\n        while (running) {\n\n            HashMap<String, String> Contactos = new HashMap<>();\n            // Ejemplo de uso: agregar un contacto y obtenerlo\n            Contactos.put(\"Ana\", \"555451234\");\n            Contactos.put(\"Richard\", \"555569878\");\n            Contactos.put(\"Juan\", \"555098765\");\n            Contactos.put(\"Gabi\", \"5522153042\");\n            Contactos.put(\"Toño\", \"555123456\");\n            Contactos.put(\"Ale\", \"555987654\");\n            String telefono = Contactos.get(\"Ana\");\n            System.out.println(\"Teléfono de Ana: \" + telefono);\n\n            System.out.println(\"\\nOperaciones disponibles:\");\n            System.out.println(\"1. Buscar contacto\");\n            System.out.println(\"2. Insertar contacto\");\n            System.out.println(\"3. Actualizar contacto\");\n            System.out.println(\"4. Eliminar contacto\");\n            System.out.println(\"5. Salir\");\n            System.out.print(\"Selecciona una opción: \");\n            String opcion = scanner.nextLine();\n\n            switch (opcion) {\n                case \"1\": // Buscar\n                    System.out.print(\"Nombre del contacto a buscar: \");\n                    String nombreBuscar = scanner.nextLine();\n                    if (Contactos.containsKey(nombreBuscar)) {\n                        System.out.println(\"Teléfono de \" + nombreBuscar + \": \" + Contactos.get(nombreBuscar));\n                    } else {\n                        System.out.println(\"Contacto no encontrado.\");\n                    }\n                    break;\n                case \"2\": // Insertar\n                    System.out.print(\"Nombre del nuevo contacto: \");\n                    String nombreInsertar = scanner.nextLine();\n                    System.out.print(\"Número de teléfono: \");\n                    String telefonoInsertar = scanner.nextLine();\n                    if (!telefonoInsertar.matches(\"\\\\d{1,\" + MAX_DIGITS + \"}\")) {\n                        System.out.println(\"Número inválido. Debe ser numérico y máximo \" + MAX_DIGITS + \" dígitos.\");\n                    } else {\n                        Contactos.put(nombreInsertar, telefonoInsertar);\n                        System.out.println(\"Contacto agregado.\");\n                    }\n                    break;\n                case \"3\": // Actualizar\n                    System.out.print(\"Nombre del contacto a actualizar: \");\n                    String nombreActualizar = scanner.nextLine();\n                    if (Contactos.containsKey(nombreActualizar)) {\n                        System.out.print(\"Nuevo número de teléfono: \");\n                        String telefonoActualizar = scanner.nextLine();\n                        if (!telefonoActualizar.matches(\"\\\\d{1,\" + MAX_DIGITS + \"}\")) {\n                            System.out\n                                    .println(\"Número inválido. Debe ser numérico y máximo \" + MAX_DIGITS + \" dígitos.\");\n                        } else {\n                            Contactos.put(nombreActualizar, telefonoActualizar);\n                            System.out.println(\"Contacto actualizado.\");\n                        }\n                    } else {\n                        System.out.println(\"Contacto no encontrado.\");\n                    }\n                    break;\n                case \"4\": // Eliminar\n                    System.out.print(\"Nombre del contacto a eliminar: \");\n                    String nombreEliminar = scanner.nextLine();\n                    if (Contactos.containsKey(nombreEliminar)) {\n                        Contactos.remove(nombreEliminar);\n                        System.out.println(\"Contacto eliminado.\");\n                    } else {\n                        System.out.println(\"Contacto no encontrado.\");\n                    }\n                    break;\n                case \"5\": // Salir\n                    running = false;\n                    System.out.println(\"Programa finalizado.\");\n                    break;\n                default:\n                    System.out.println(\"Opción no válida.\");\n            }\n        }\n        scanner.close();\n\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/AndrewCodev.java",
    "content": "import java.util.*;\n\npublic class AndrewCodev {\n\n\tpublic static void main(String[] args) {\n\t\t// Arrays\n\t\tint[] arNumeros = { 1, 2, 3, 4, 5 };\n\t\tString[] arCadenaTexto = { \"Hola\", \"Hola Mundo\", \"Mundo\" };\n\n\t\tAndrewCodev andrewCodev = new AndrewCodev();\n\t\t// Imprimiendo Array\n\t\tSystem.out.println(\"IMPRESIÓN DE Arrays\");\n\t\tfor (int i = 0; i < arNumeros.length; i++) {\n\t\t\tSystem.out.println(\"numero: \" + arNumeros[i]);\n\t\t}\n\t\tSystem.out.println(\"\\n\");\n\t\tfor (int i = 0; i < arCadenaTexto.length; i++) {\n\t\t\tSystem.out.println(\"Cadena de texto: \" + arCadenaTexto[i]);\n\t\t}\n\n\t\t// Impresión de listas\n\t\tSystem.out.println(\"\\nLISTAS DE DEPORTES - ArrayList\\n\");\n\n\t\t// Agregando datos a la lista\n\t\t// Listas ArrayList\n\t\tArrayList<String> deportes = new ArrayList<>();\n\t\tdeportes.add(\"NATACIÓN\");\n\t\tdeportes.add(\"FUTBOL\");\n\t\tdeportes.add(\"BALONCESTO\");\n\t\tdeportes.add(\"BESEBALL\");\n\n\t\t// Imprimir la lista con los datos agregados\n\t\tfor (int i = 0; i < deportes.size(); i++) {\n\t\t\tSystem.out.println(i + \": \" + deportes.get(i));\n\t\t}\n\n\t\t// Editamos un dato de la lista\n\t\tSystem.out.println(\"\\nMODIFICAMOS UN REGISTRO DE LA LISTA\\n\");\n\t\tdeportes.set(0, \"FUTBOL SALA\");\n\n\t\t// Imprimir la lista con los datos editados\n\t\tfor (int i = 0; i < deportes.size(); i++) {\n\t\t\tSystem.out.println(i + \": \" + deportes.get(i));\n\t\t}\n\n\t\t// ORDENAR LISTA POR NOMBRE\n\t\tSystem.out.println(\"\\nORDENANDO LA LISTA POR NOMBRE\\n\");\n\t\tCollections.sort(deportes);\n\t\t// Imprimir la lista con los datos agregados\n\t\tfor (int i = 0; i < deportes.size(); i++) {\n\t\t\tSystem.out.println(i + \": \" + deportes.get(i));\n\t\t}\n\n\t\t// Removemos un dato de la lista\n\t\tSystem.out.println(\"\\nREMOVEMOS UN REGISTRO DE LA LISTA\\n\");\n\t\tdeportes.remove(2);\n\t\t// Imprimir la lista con los datos agregados\n\t\tfor (int i = 0; i < deportes.size(); i++) {\n\t\t\tSystem.out.println(i + \": \" + deportes.get(i));\n\t\t}\n\n\t\t// Conjunto que no permite elementos duplicados\n\t\tHashSet<String> animales = new HashSet<>();\n\t\tSystem.out.println(\"\\nCONJUNNTO DE DATOS - HashSet (No permite valores repetidos)\");\n\t\tanimales.add(\"Leon\");\n\t\tanimales.add(\"Tigre\");\n\t\tanimales.add(\"Elefante\");\n\t\tanimales.add(\"Leon\");\n\n\t\t// Imprimir la lista con los datos agregados\n\t\tfor (String animal : animales) {\n\t\t\tSystem.out.println(animal);\n\t\t}\n\n\t\t// Eliminar un elemento\n\t\tSystem.out.println(\"\\nREMOVEMOS AL Elefante DE LA LISTA\\n\");\n\n\t\tanimales.remove(\"Elefante\");\n\t\t// Imprimir la lista con los datos agregados\n\t\tfor (String animal : animales) {\n\t\t\tSystem.out.println(animal);\n\t\t}\n\n\t\t// HashMap\n\t\tSystem.out.println(\"\\nLISTAS DE PERSONAS Y EDAD - HashMap\\n\");\n\t\t// HashMap\n\t\tHashMap<String, Integer> edades = new HashMap<>();\n\t\tedades.put(\"Ana\", 30);\n\t\tedades.put(\"Luis\", 25);\n\t\tedades.put(\"Carlos\", 35);\n\n\t\tfor (HashMap.Entry<String, Integer> edad : edades.entrySet()) {\n\t\t\tSystem.out.println(edad.getKey() + \": \" + edad.getValue());\n\t\t}\n\n\t\tSystem.out.println(\"\\nREMOVEMOS EL REGISTRO Ana - HashMap\\n\");\n\t\tedades.remove(\"Ana\");\n\t\tfor (HashMap.Entry<String, Integer> edad : edades.entrySet()) {\n\t\t\tSystem.out.println(edad.getKey() + \": \" + edad.getValue());\n\t\t}\n\n\t\t// COLAS\n\t\tSystem.out.println(\"\\nCOLAS - Queue - LinkedList \\n\");\n\t\tQueue<String> cola = new LinkedList<>();\n\t\tcola.add(\"Primer\");\n\t\tcola.add(\"Segundo\");\n\t\tcola.add(\"Tercero\");\n\n\t\tSystem.out.println(cola.add(\"Cuarto\")); // Elimina y retorna \"Primer\"\n\n\t\tSystem.out.println(\"\\nPILAS - Queue - LinkedList \\n\");\n\t\t// PILA\n\t\tStack<String> pila = new Stack<>();\n\t\tpila.push(\"Primero\");\n\t\tpila.push(\"Segundo\");\n\t\tpila.push(\"Tercero\");\n\n\t\tSystem.out.println(pila.pop()); // Elimina y retorna \"Tercero\"\n\n\t\tArrayList<AndrewCodev> agenda = new ArrayList<>();\n\n\t\tandrewCodev.inicioPrograma(agenda);\n\t}\n\n\t// INICIO DESARROLLO DE AGENDA\n\tString nombre;\n\tLong telefono;\n\tint codigo;\n\n\tpublic AndrewCodev() {\n\t}\n\n\tpublic AndrewCodev(String nombre, Long telefono) {\n\t\tthis.nombre = nombre;\n\t\tthis.telefono = telefono;\n\t}\n\n\tScanner scanner = new Scanner(System.in);\n\n\t// ABRIMOS EL MENÚ\n\tpublic void menuAgenda(ArrayList<AndrewCodev> agenda) {\n\t\tString key = scanner.nextLine();\n\t\ttry {\n\n\t\t\tint opcion = Integer.parseInt(key);\n\n\t\t\tswitch (opcion) {\n\t\t\tcase 1: {\n\t\t\t\tSystem.out.println(\"LISTA DE CONTACTO\\n\");\n\n\t\t\t\tlistarContactos(agenda);\n\t\t\t\tinicioPrograma(agenda);\n\t\t\t\tbreak;\n\n\t\t\t}\n\t\t\tcase 2: {\n\n\t\t\t\tSystem.out.println(\"CREANDO NUEVO CONTACTO\\n\");\n\t\t\t\tSystem.out.println(\"Ingrese el nombre\");\n\t\t\t\tthis.nombre = scanner.nextLine();\n\n\t\t\t\tSystem.out.println(\"Ingrese el numero de telefono\");\n\n\t\t\t\tString telefono = scanner.nextLine();\n\t\t\t\tthis.telefono = Long.parseLong(telefono);\n\t\t\t\tif (validarTelefono(telefono)) {\n\n\t\t\t\t\tnuevoContacto(agenda, this.nombre, this.telefono);\n\n\t\t\t\t\tSystem.out.println(\"El Contacto ha sido agregado correctamente: \" + this.nombre + \" Telefono: \"\n\t\t\t\t\t\t\t+ this.telefono);\n\t\t\t\t} else {\n\t\t\t\t\tSystem.out.println(\"El número de telefono debe tener 11 digitos\");\n\t\t\t\t\tinicioPrograma(agenda);\n\t\t\t\t}\n\t\t\t\tinicioPrograma(agenda);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 3: {\n\t\t\t\tif (listarContactos(agenda)) {\n\t\t\t\t\tSystem.out.println(\"\\nMODIFICAR CONTACTO\\n\");\n\t\t\t\t\tSystem.out.println(\"Escriba el Código del contacto que desea modificar\");\n\t\t\t\t\tthis.codigo = Integer.parseInt(scanner.nextLine());\n\n\t\t\t\t\tSystem.out.println(\"Modifique el nombre\");\n\t\t\t\t\tthis.nombre = scanner.nextLine();\n\n\t\t\t\t\tSystem.out.println(\"Modifique el telefono\");\n\t\t\t\t\tString telefono = scanner.nextLine();\n\t\t\t\t\tthis.telefono = Long.parseLong(telefono);\n\n\t\t\t\t\tif (validarTelefono(telefono)) {\n\n\t\t\t\t\t\tmodificarContacto(agenda, this.codigo, this.nombre, this.telefono);\n\n\t\t\t\t\t\tSystem.out.println(\"El Contacto ha sido modificado correctamente: \" + this.nombre\n\t\t\t\t\t\t\t\t+ \" Telefono: \" + this.telefono);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tSystem.out.println(\"El número de telefono no debe tener mas de 11 digitos\");\n\t\t\t\t\t\tinicioPrograma(agenda);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tinicioPrograma(agenda);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 4: {\n\n\t\t\t\tif (listarContactos(agenda)) {\n\t\t\t\t\tSystem.out.println(\"\\nELIMINAR CONTACTO\\n\");\n\t\t\t\t\tSystem.out.println(\"Escriba el Código del contacto que desea ELIMINAR\");\n\t\t\t\t\tthis.codigo = Integer.parseInt(scanner.nextLine());\n\n\t\t\t\t\teliminarContacto(agenda, this.codigo);\n\n\t\t\t\t}\n\t\t\t\tinicioPrograma(agenda);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 5: {\n\t\t\t\tscanner.close();\n\t\t\t\tSystem.err.println(\"EL PROGRAMA ESTÁ CERRADO\");\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tSystem.out.println(\"La opción no se encuentra en el menú, intente nuevamente\");\n\t\t\t\tinicioPrograma(agenda);\n\t\t\t}\n\n\t\t} catch (NumberFormatException e) {\n\t\t\tSystem.out.println(\"Los datos de entrada son invalidos inicie el proceso nuevamente\");\n\t\t\tSystem.out.println(\"-----------------------------------------------------------------------\");\n\t\t\tpintarMenu();\n\t\t\tmenuAgenda(agenda);\n\t\t}\n\t}\n\n\tpublic void pintarMenu() {\n\t\t// DIFICULTAD EXTRA\n\t\tSystem.out.println(\"\\nAGENDA DE CONTACTOS\\n\" + \"\\nPresiona 1 para LISTAR todos tus contactos\"\n\t\t\t\t+ \"\\nPresiona 2 para AGREGAR un nuevo contacto\" + \"\\nPresiona 3 para MODIFICAR un contacto\"\n\t\t\t\t+ \"\\nPresiona 4 para ELIMINAR un contacto\" + \"\\nPresiona 5 para CERRAR EL PROGRAMA\");\n\t}\n\n\t// Función que crea y retorna la lista de contactos\n\tpublic static ArrayList<AndrewCodev> nuevoContacto(ArrayList<AndrewCodev> agenda, String nombre, Long telefono) {\n\t\tagenda.add(new AndrewCodev(nombre, telefono));\n\t\treturn agenda;\n\t}\n\n\tpublic static ArrayList<AndrewCodev> modificarContacto(ArrayList<AndrewCodev> agenda, int codigo, String nombre,\n\t\t\tLong telefono) {\n\t\tfor (int i = 0; i < agenda.size(); i++) {\n\t\t\tif (i == codigo) {\n\t\t\t\tSystem.out.println(\n\t\t\t\t\t\t\"Vas a modificar el contacto: \" + agenda.get(i).nombre + \" - \" + agenda.get(i).telefono);\n\t\t\t\tagenda.set(i, new AndrewCodev(nombre, telefono));\n\t\t\t}\n\t\t}\n\t\treturn agenda;\n\t}\n\n\tpublic boolean listarContactos(ArrayList<AndrewCodev> agenda) {\n\n\t\tSystem.out.println(\"\\nLISTA DE CONTACTOS ACTUALIZADA\");\n\t\tif (agenda.size() != 0) {\n\t\t\tfor (int i = 0; i < agenda.size(); i++) {\n\t\t\t\tSystem.out.println(\"\\nCódigo: \" + i + \"\\nNombre: \" + agenda.get(i).nombre + \"\\nTelefono: \"\n\t\t\t\t\t\t+ agenda.get(i).telefono);\n\t\t\t}\n\t\t\treturn true;\n\t\t} else {\n\t\t\tSystem.out.println(\"Aun no has registrado contactos en tu agenda\");\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic static ArrayList<AndrewCodev> eliminarContacto(ArrayList<AndrewCodev> agenda, int codigo) {\n\t\tfor (int i = 0; i < agenda.size(); i++) {\n\t\t\tif (i == codigo) {\n\t\t\t\tSystem.out.println(\n\t\t\t\t\t\t\"EL contacto: \" + agenda.get(i).nombre + \" - \" + agenda.get(i).telefono + \": Está eliminado\");\n\t\t\t\tagenda.remove(i);\n\t\t\t}\n\t\t}\n\t\treturn agenda;\n\t}\n\n\tpublic boolean validarTelefono(String telefono) {\n\t\tif (telefono.length() != 11) {\n\t\t\treturn false;\n\t\t} else {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tpublic void inicioPrograma(ArrayList<AndrewCodev> agenda) {\n\t\tSystem.out.println(\"-----------------------------------------------------------------------\");\n\t\tpintarMenu();\n\t\tmenuAgenda(agenda);\n\t}\n}\n/*\n * EJERCICIO: - Muestra ejemplos de creación de todas las estructuras soportadas\n * por defecto en tu lenguaje. - Utiliza operaciones de inserción, borrado,\n * actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional): Crea una agenda de contactos por terminal. -\n * Debes implementar funcionalidades de búsqueda, inserción, actualización y\n * eliminación de contactos. - Cada contacto debe tener un nombre y un número de\n * teléfono. - El programa solicita en primer lugar cuál es la operación que se\n * quiere realizar, y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y\n * con más de 11 dígitos. (o el número de dígitos que quieras) - También se debe\n * proponer una operación de finalización del programa.\n */"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/BlasBarragan.java",
    "content": "/**\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * @version v1\n * \n * @since 27/01/2024\n * \n * @author Blas Barragán\n * \n */\n\n import java.util.ArrayList;\n import java.util.LinkedList;\n import java.util.Scanner;\n import java.util.HashMap;\n import java.util.HashSet;\n \n public class BlasBarragan {\n \n // VARIABLES GLOBALES PARA DIFICULTAD EXTRA\n static Scanner sc = new Scanner(System.in);\n     // HashMap para almacenar contactos\n private static HashMap<String, Integer> AgendaContactos = new HashMap<String, Integer>();\n \n /**\n  * Arrays (vectores).\n  * Almacenan de manera estructurada un conjunto de valores del mismo tipo de dato (entero, caracter, objeto, etc..)\n  */ \n \n     /**\n      * Array estatico (tiene un tamaño fijo)\n      * Lo declaramos de la siguiente forma:\n      * tipoDeDato[] nombreArray = new tipoDeDato[tamañoArray];\n      */ \n     public static void ArrayEstatico() {\n         // Declaramos Array\n         int[] notas = new int[4];\n \n         // Inserción\n             // Insertamos datos de la siguiente forma:\n             // nombreArray[indiceDelDatoInsertado] = valorDato;\n             // Los indices del array siempre empiezan en 0, por lo que seguiran el patron:\n             // indice: 0 posicion:1, indice:1 posicion:2, indice:2 posicion:3, etc...\n             // y asi como posiciones (tamaño total) tenga el array.\n             notas[0] = 6;\n             notas[1] = 3;\n             notas[2] = 10;\n             notas[3] = 8;\n \n             // Si conocemos los datos del array con antelacion, tambien podriamos insertar diectamente esos datos en su declaracion.\n             String[] alumnos = {\"Blas\", \"Marcos\"}; \n         \n         // Actualización \n             // Para actualizar datos, simplemente llamaos al array con el indice deseado e igualamos al nuevo valor.\n             System.out.println(\"Valor posición 1 del array: \" + notas[0]);\n             notas[0] = 5; \n             System.out.println(\"Valor posición 1 del array actualizada: \" + notas[0]);\n \n         // Borrado \n             // Como los arrays tienen un tamaño estatico, el borrado de datos no se puede realizar como tal.\n             // Podriamos declarar el tamaño del array con una variable y con esto cambiar el tamaño del array pero no eliminar un dato en una posicion concreta.\n             int tamanoArray = 5;\n             int[] array = new int[tamanoArray];\n             System.out.println(\"Tamaño array: \" + array.length);\n             tamanoArray = 10;\n             System.out.println(\"Nuevo tamaño array: \" + array.length);\n \n         // Ordenación\n             // La ordenacion de los Array viene dada por sus indices de 0 a N-1.\n             // Siendo N el tamaño del array. \n         \n         // ## Si importamos en nuestro programa la clase Array (import java.util.Arrays;) \n         // podremos utilizar diferentes metodos extra de manipulacion de arrays que nos ofrece dicha biblioteca. \n         // https://docs.oracle.com/javase/8/docs/api/java/util/Arrays.html\n     }\n     \n     /**\n      * Array multidimensional (matrices/tablas)\n      * Un array dentro de un array.\n      * Nos permite almacenar y manejar elementos como si tuvieramos una tabla.\n      * Lo declaramos de la siguiente forma:\n      * tipoDeDato[][] nombreArray = new tipoDeDato[tamañoArray/filas][tamañoArray2/columnas];\n      */\n \n      public static void ArrayMultidimensional() {\n         // Inserción\n \n         int notasCurso[][] = new int [2][3];\n         notasCurso[0][0] = 7;\n         notasCurso[0][1] = 5;\n         notasCurso[0][2] = 9;\n         notasCurso[1][0] = 4;\n         notasCurso[1][1] = 6;\n         notasCurso[1][2] = 10;\n \n         // Tambien podemos inicializarlo de la siguiente forma, añadiendo a su vez los datos.\n         int[][] notasCurso2 = {\n             {9,5,6},\n             {8,8,10},\n             {5,4,5},\n             {3,4,2},\n         };\n \n         // Por lo demas, los arrays multidimensionales (matrices) se tratan igual que los array estaticos.\n      }\n \n /**\n  * ArrayList (Arrays con vitaminas).\n  * import java.util.ArrayList;\n  * Con esto, podremos crear y usar arrays con distintos metodos incluidos en Java que nos facilitaran trabajar con ellos.\n  */ \n \n      public static void ArrayConVitaminas() {\n         // Inicializacion\n         ArrayList<String> coches = new ArrayList<String>();\n \n         // Insercion\n         coches.add(\"Hyundai\");\n         coches.add(\"Ford\");\n         coches.add(\"Fiat\");\n         System.out.println(coches);\n \n         // Actualizacion\n         coches.set(0, \"Opel\");\n         coches.set(2, \"Mazda\");\n         coches.set(1, \"Audi\");\n \n         // Borrado\n         coches.remove(2);\n         coches.remove(1);\n             // Para vaciar el array\n         coches.clear();\n      }\n \n      // Existe una \"Variante\" de los ArrayList que se comporta igual pero trabaja en segundo plano de forma diferente.\n      // Hablamos de las LinkedList que estan mas optimizadas para manipular datos al contrario que los Array que funcionan mejor para almacenarlos.\n      // import java.util.LinkedList\n      public static void ListaParaManipularDatos(){\n         LinkedList<String> motos = new LinkedList<String>();\n         motos.add(\"Honda\");\n         motos.add(\"Aprilia\");\n \n         // Tiene una serie de metodos utiles\n         motos.addFirst(\"Kawasaki\"); // Añade los datos en la primera posicion.\n         motos.addLast(\"Triumph\"); // Añade los datos en la ultima posicion.\n         motos.removeFirst(); // Elimina el dato en primera posicion.\n         motos.removeLast(); // Elimina el dato en ultima posicion.\n         motos.getFirst(); // Devuelve el dato en primera posicion.\n         motos.getLast(); // Devuelve el dato en ultima posicion.\n      }\n \n /**\n  * HashMap\n  * import java.util.HashMap;\n  * A difierencia de los arrays o las listas no se almacenan los datos ordenados. \n  * En su lugar, almacena parejas de datos en forma clave/valor para acceder a ellos.\n  */\n      public static void AlmacenClaveValor() {\n         // Inicializacion\n         // Podemos emparejar datos de distinto tipo\n         HashMap<String, String> PueblosDeEspaña = new HashMap<String, String>();\n \n         // Insercion\n         // Para insertar datos lo haremos con nombreDelHashMap.put(\"clave\",'valor');\n         PueblosDeEspaña.put(\"Valencia\",\"Alaquas\");\n         PueblosDeEspaña.put(\"Valencia\", \"L'eliana\");\n         PueblosDeEspaña.put(\"Alicante\", \"Elche\");\n         PueblosDeEspaña.put(\"Castellon\", \"Onda\");\n \n         // Borrado\n         PueblosDeEspaña.remove(\"Valencia\");\n         PueblosDeEspaña.remove(\"Castellon\");\n             // Para vaciar \n         PueblosDeEspaña.clear();\n      }\n \n /**\n  * HashSet\n  * import java.util.HashSet;\n  * Coleccion de datos UNICOS. \n  */\n      public static void DatosUnicos() {\n         // Inicializacion\n         HashSet<String> Marcas = new HashSet<String>();\n \n         // Insercion\n         Marcas.add(\"Logitech\");\n         Marcas.add(\"Asus\");\n         Marcas.add(\"Razer\");\n \n         // Borrado\n         Marcas.remove(\"Asus\");\n             // Para vaciar \n         Marcas.clear();\n      }\n \n     public static void main(String[] args) {\n         dificultadExtra();\n     }\n \n     /** DIFICULTAD EXTRA (opcional):\n     * Crea una agenda de contactos por terminal.\n     * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n     * - Cada contacto debe tener un nombre y un número de teléfono.\n     * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n     *   los datos necesarios para llevarla a cabo.\n     * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n     *   (o el número de dígitos que quieras)\n     * - También se debe proponer una operación de finalización del programa.\n     */\n \n     public static void dificultadExtra() {\n \n         int opcion = 0;\n         do {\n             System.out.println(\"##### Agenda #####\");\n             System.out.println(\"<---Menu agenda--->\");\n             System.out.println(\"1. Añadir contacto\");\n             System.out.println(\"2. Buscar contacto\");\n             System.out.println(\"3. Actualizar contacto\");\n             System.out.println(\"4. Eliminar contacto\");\n             System.out.println(\"5. Salir\");\n             System.out.println(\"Selecciona una opcion: \");\n             opcion = sc.nextInt();\n \n             switch (opcion) {\n                 case 1:\n                     // Añadir contacto\n                     anadir();\n                     break;\n                 case 2:\n                     // Buscar contacto\n                     buscar();\n                     break;\n                 case 3:\n                     // Actualizar contacto\n                     actualizar();\n                     break;\n                 case 4:\n                     // Eliminar contacto\n                     eliminar();\n                     break;\n                 case 5:\n                     // Salir\n                     break;\n                 default:\n                     System.out.println(\"Opcion no valida\");\n             }\n         } while (opcion !=5);\n         System.out.println(\"< ==== Salir ==== >\");\n \n     }\n \n     public static void anadir(){\n         System.out.println(\"< ==== Añadir nuevo contacto ==== > \\n\");\n         System.out.println(\"Nombre: \");\n         String nuevoNombre = sc.next();\n         System.out.println(\"Telefono: \");\n         Integer nuevoTelefono = sc.nextInt();\n         while (nuevoTelefono < 0 || nuevoTelefono > 999999999) {\n             System.out.println(\"Error: El telefono debe ser numerico max. 9 digitos\");\n             System.out.println(\"\\nTelefono: \");\n             nuevoTelefono = sc.nextInt();\n         }\n         AgendaContactos.put(nuevoNombre,nuevoTelefono);\n         System.out.println(\"Nuevo contacto añadido.\");\n     }\n \n     public static void buscar(){\n         System.out.println(\"< ==== Buscar contacto ==== > \\n\");\n         System.out.println(\"Nombre: \");\n         String nombre = sc.next();\n         \n         if (AgendaContactos.get(nombre) != null){\n             System.out.println(\"Contacto: \" + nombre);\n             System.out.println(\"Telefono: \" + AgendaContactos.get(nombre));\n         } else {\n             System.out.println(\"El contacto no existe\");\n         }\n     }\n \n     public static void actualizar(){\n         System.out.println(\"< ==== Actualizar contacto ==== > \\n\");\n         System.out.println(\"Nombre: \");\n         String nombre = sc.next();\n         \n         if (AgendaContactos.get(nombre) != null){\n             System.out.println(\"Nuevo numero de telefono: \");\n             Integer actualizarTelefono = sc.nextInt();\n         while (actualizarTelefono < 0 || actualizarTelefono > 999999999) {\n             System.out.println(\"Error: El telefono debe ser numerico max. 9 digitos\");\n             System.out.println(\"\\nNuevo numero de telefono:  \");\n             actualizarTelefono = sc.nextInt();\n         }\n         AgendaContactos.put(nombre,actualizarTelefono);\n         System.out.println(\"El contacto: \" + nombre);\n         System.out.println(\"Ha sido actualizado con el telefono: \" + actualizarTelefono);\n         } else {\n             System.out.println(\"El contacto no existe\");\n         }\n     }\n     public static void eliminar(){\n         System.out.println(\"< ==== Eliminar contacto ==== > \\n\");\n         System.out.println(\"Nombre: \");\n         String nombre = sc.next();\n         \n         if (AgendaContactos.get(nombre) != null){\n             System.out.println(\"El contacto: \" + nombre);\n             System.out.println(\"Con telefono: \" + AgendaContactos.get(nombre));\n             AgendaContactos.remove(nombre);\n             System.out.println(\"Ha sido eliminado\");\n             \n         } else {\n             System.out.println(\"El contacto no existe\");\n         }\n     }\n \n }\n "
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/Clarancedev.java",
    "content": "/**\n * @author clarancedev\n * @version 1.0 - 2025/04/15\n */\n\nimport java.util.Arrays;\nimport java.util.ArrayList;\nimport java.util.LinkedList;\nimport java.util.Collections;\nimport java.util.Stack;\nimport java.util.Deque;\nimport java.util.ArrayDeque;\nimport java.util.Queue;\nimport java.util.HashMap;\nimport java.util.Scanner;\n\npublic class Clarancedev {\n\n    // TIPOS DE ESTRUCTURAS DE DATOS\n\n    public static void exampleArray() {\n\n        /*\n        ARRAYS\n        - Almacena valores de un mismo tipo\n        - Se accede a los valores mediante un índice\n        - Tamaño fijo determinado al crearse, sin poder modificarse después\n        */\n\n        // Creación\n        int[] array1 = new int[5];\n        int[] array2 = {1, 2, 3, 4, 5};\n\n        // Inserción de valores indicando la posición\n        array1[0] = 10;\n        array1[1] = 20;\n        array1[2] = 30;\n        array1[3] = 40;\n        array1[4] = 50;\n\n        // Cambio de valor de una posición\n        array2[0] = 0;\n\n        // Recorrer un array\n        for (int i = 0; i < array1.length; i++) {\n            System.out.println(array1[i]);\n        }\n        System.out.println(\"Cómo recorre un bucle for-each un array:\");\n        for (int i : array2) {\n            System.out.println(i); // 0, 20, 30, 40, 50\n        }\n\n        // Imprimir array\n        System.out.println(Arrays.toString(array1)); // 0, 20, 30, 40, 50\n\n        // Imprimir posición\n        System.out.println(\"Impresión de una posición de un array: \" + array1[0]);\n    }\n\n    public static void exampleArrayList() {\n\n        /*\n        ARRAYLIST\n        - Almacena datos de un mismo tipo, pero también objetos\n        - Tamaño dinámico\n        - Puntos fuertes: rápido para consultas y actualizaciones\n        - Puntos débiles: lento para inserciones y borrados en posiciones concretas\n        */\n\n        // Creación\n        java.util.ArrayList<Integer> arrayList = new java.util.ArrayList<>();\n\n        // Inserción de valores (se añaden al final de la lista)\n        arrayList.add(10);\n        arrayList.add(20);\n        arrayList.add(30);\n\n        // Otros tipos de inserción\n        arrayList.add(2, 100); // Valores en posiciones posteriores se moverán de posición (n + 1)\n        arrayList.addFirst(0); // También aplicable con .remove y .set\n        arrayList.addLast(40); // También aplicable con .remove y .set\n\n        // Borrado de un valor\n        arrayList.remove(1);\n\n        // Actualización ([índice], [valor])\n        arrayList.set(4, 25);\n\n        // Ordenación\n        java.util.Collections.sort(arrayList);\n\n        // Se recorren de la misma forma que un array\n        for (int i = 0; i < arrayList.size(); i++) {\n            System.out.println(arrayList.get(i));\n        }\n\n        // Imprimir lista + posición concreta\n        System.out.println(arrayList + \"\\n\" + arrayList.get(1));\n    }\n\n    public static void exampleLinkedList() {\n        /*\n        LINKEDLIST\n        - Almacena datos de un mismo tipo, pero también objetos\n        - Tamaño dinámico\n        - Puntos fuertes: rápido para inserciones y borrados en posiciones concretas\n        - Puntos débiles: lento para consultas y actualizaciones\n        */\n\n        // Creación\n        java.util.LinkedList<Integer> linkedList = new java.util.LinkedList<>();\n\n        // Inserción de valores (se añaden al final de la lista)\n        linkedList.add(10);\n        linkedList.add(20);\n        linkedList.add(30);\n\n        // Otros tipos de inserción\n        linkedList.add(2, 100); // Valores en posiciones posteriores se moverán de posición (n + 1)\n        linkedList.addFirst(0); // También aplicable con .remove y .set\n        linkedList.addLast(40); // También aplicable con .remove y .set\n\n        // Borrado de un valor\n        linkedList.remove(1);\n\n        // Actualización ([indice], [valor])\n        linkedList.set(4, 25);\n\n        // Ordenación de la lista\n        java.util.Collections.sort(linkedList);\n\n        // Se recorren de la misma forma que un array\n        for (int i = 0; i < linkedList.size(); i++) {\n            System.out.println(i);\n        }\n\n        // Imprimir lista + posición concreta\n        System.out.println(linkedList + \"\\n\" + linkedList.get(1));\n    }\n\n    public static void exampleStack() {\n\n        /*\n        STACK (también conocido como PILA)\n        - Lógica de manipulación de datos según el principio LIFO (Last-In-First-Out)\n        - Solo permite inserción/borrado/consulta sobre último valor almacenado\n        - Ideal para almacenar datos temporales y acceder a ellos según LIFO\n        */\n\n        // Creación\n        Stack<Integer> aStack = new Stack<>();\n\n        // Inserción\n        aStack.push(10);\n        aStack.push(20);\n        aStack.push(30);\n        aStack.push(40);\n        aStack.push(50);\n\n        // Borrado\n        aStack.pop(); // En este caso el valor [50]\n\n        // Consulta (imprimiendo directamente el valor)\n        aStack.peek(); // 40\n\n        // Imprimir todos los valores\n        System.out.println(aStack); // [10, 20, 30, 40]\n\n        /* OJO:\n        * Con la clase predeterminada Stack la impresión de todos\n        * los elementos no se hace según la lógica LIFO. Si queremos\n        * una impresión LIFO, tenemos las clases Deque + ArrayDeque.\n        */\n\n        // Ejemplo Deque implementando ArrayDeque\n        Deque<Integer> aDeque = new ArrayDeque<>();\n\n        aDeque.push(10);\n        aDeque.push(20);\n        aDeque.push(30);\n        aDeque.push(40);\n        aDeque.push(50);\n\n        aDeque.pop();\n\n        aDeque.peek();\n\n        System.out.println(aDeque); // [40, 30, 20, 10]\n    }\n\n    public static void exampleQueue() {\n\n        /*\n        QUEUE (también conocido como COLA)\n        - Lógica de manipulación de datos según el principio FIFO (First-In-First-Out)\n        - Inserción se aplica sobre la siguiente posición\n        - Borrado y consulta se aplican sobre la primera posición\n        - Ideal para almacenar datos temporales y acceder a ellos según FIFO\n        */\n\n        // Creación\n        Queue<Integer> aQueue = new ArrayDeque<>();\n\n        // Inserción (Enqueue)\n        aQueue.offer(10);\n        aQueue.offer(20);\n        aQueue.offer(30);\n        aQueue.offer(40);\n        aQueue.offer(50);\n\n        // Borrado (Dequeue)\n        aQueue.poll(); // En este caso el valor [10]\n\n        // Consulta (imprimiendo directamente el valor)\n        aQueue.peek(); // 20\n\n        // Imprimir todos los valores\n        System.out.println(aQueue); // [20, 30, 40, 50]\n    }\n\n    public static void exampleHash() {\n\n        /*\n        HASH\n        - Las tablas hash almacenan datos en pares clave-valor, sin duplicados\n        - Permite acceso rápido a los valores mediante la clave\n        - No garantiza el orden de los elementos\n        - El HashMap es la implementación más común\n        - Ideal para búsquedas rápidas de valores mediante su referencia\n        */\n\n        // Creación\n        HashMap<String, Integer> hashMap = new HashMap<>();\n\n        // Inserción ([clave], [valor])\n        hashMap.put(\"One\", 1);\n        hashMap.put(\"Two\", 2);\n        hashMap.put(\"Three\", 3);\n\n        // Borrado\n        hashMap.remove(\"Dos\");\n\n        // Actualización ([clave], [nuevo valor])\n        hashMap.put(\"Tres\", 4);\n\n        // Consulta ([clave])\n        System.out.println(hashMap.get(\"Uno\")); // 1\n\n        // Imprimir todos los valores\n        System.out.println(hashMap); // {Uno=1, Tres=4}\n    }\n\n    /*\n    DIFICULTAD EXTRA\n    Agenda de contactos utilizando HashMap y desengranando en métodos\n    */\n\n    private static final HashMap<String, String> CONTACTS_AGENDA = new HashMap<>(); // Para almacenaje de datos\n    private static final Scanner SCN = new Scanner(System.in); // Scanner\n\n    public static void runContactsAgenda() {\n        boolean running = false;\n        System.out.println(\"\\n-* AGENDA DE CONTACTOS *-\");\n        while (!running) {\n            printMenu();\n            int userOption = getOption();\n            running = executeOption(userOption);\n        }\n    }\n\n    // Menú\n    private static void printMenu() {\n        System.out.println(\"-----------Opciones:----------\");\n        System.out.println(\"------------------------------\");\n        System.out.println(\"1. Buscar contacto\");\n        System.out.println(\"2. Añadir contacto\");\n        System.out.println(\"3. Actualizar contacto\");\n        System.out.println(\"4. Eliminar contacto\");\n        System.out.println(\"5. Mostrar todos los contactos\");\n        System.out.println(\"6. Salir\");\n        System.out.println(\"------------------------------\");\n        System.out.println(\"Seleccione una opción:\");\n     }\n\n    // Recoger opción seleccionada\n    private static int getOption() {\n\n        int userOption = 0;\n        if (SCN.hasNextInt()) {\n            userOption = SCN.nextInt();\n            SCN.nextLine();\n            checkUserOption(userOption);\n        } else {\n            System.out.println(\"Formato incorrecto. Debe introducir un número entre 1 y 6:\");\n            SCN.nextLine();\n            getOption();\n        }\n        return userOption;\n    }\n\n    // Controlar input usuario (valor de tipo int entre 1 y 6)\n    private static void checkUserOption(int userOption) {\n\n        if (userOption < 1 || userOption > 6) {\n            System.out.println(\"Valor incorrecto. Debe introducir un número entre 1 y 6:\");\n            getOption();\n        }\n    }\n\n    // Ejecución de opción del menú seleccionada por usuario\n    private static boolean executeOption(int userOption) {\n        boolean running = false;\n\n        switch (userOption) {\n            case 1 -> searchContact();\n            case 2 -> addContact();\n            case 3 -> updateContact();\n            case 4 -> deleteContact();\n            case 5 -> printAllContacts();\n            case 6 -> {\n                System.out.println(\"Cerrando agenda de contactos.\");\n                running = true;\n            }\n        }\n        return running;\n    }\n\n    // Buscar contacto\n    private static void searchContact() {\n        if (CONTACTS_AGENDA.isEmpty()) {\n            System.out.println(\"La agenda de contactos está vacía.\");\n        } else {\n            System.out.println(\"Indique el nombre del contacto que desea buscar:\");\n            String contactName = checkNameInput(SCN.nextLine().trim());\n\n            if (CONTACTS_AGENDA.containsKey(contactName)) {\n                System.out.println(\"El número de teléfono de \" + contactName + \" es: \" + CONTACTS_AGENDA.get(contactName));\n            } else {\n                System.out.println(\"El contacto \\\"\" + contactName + \"\\\" no existe.\");\n            }\n        }\n    }\n\n    // Añadir contacto\n    private static void addContact() {\n        System.out.println(\"Indique el nombre del nuevo contacto: \");\n        String name = checkNameInput(SCN.nextLine().trim());\n        System.out.println(\"Indique el número de teléfono de \" + name + \":\");\n        String phoneNumber = checkPhoneNumberInput(SCN.nextLine().trim());\n        CONTACTS_AGENDA.put(name, phoneNumber);\n        System.out.println(\"Contacto registrado con los siguientes datos:\\n\" + name + \" - \" + phoneNumber);\n    }\n\n    // Controlar input usuario para nombre de contacto (valor de tipo String no vacío)\n    private static String checkNameInput(String contactName) {\n\n        while (contactName.isEmpty()) {\n            System.out.println(\"El campo no puede estar vacío. Introduzca un nombre válido:\");\n            contactName = SCN.nextLine().trim();\n        }\n        return contactName;\n    }\n\n    // Controlar input usuario de número de teléfono (valor de tipo String de entre 1 y 11 dígitos)\n    private static String checkPhoneNumberInput(String contactPhoneNumber) {\n\n        while (!contactPhoneNumber.matches(\"\\\\d{1,11}\")) {\n            System.out.println(\"El campo no puede estar vacío, ni tener más de 11 dígitos. Introduzca un número de teléfono válido\");\n            contactPhoneNumber = SCN.nextLine().trim();\n        }\n        return contactPhoneNumber;\n    }\n\n    // Actualizar contacto\n    private static void updateContact() {\n        if (CONTACTS_AGENDA.isEmpty()) {\n            System.out.println(\"La agenda de contactos está vacía.\");\n        } else {\n            System.out.println(\"Indique el nombre del contacto que desea actualizar:\");\n            String contactName = checkNameInput(SCN.nextLine().trim());\n\n            if (!CONTACTS_AGENDA.containsKey(contactName)) {\n                System.out.println(\"El contacto \\\"\" + contactName + \"\\\" no existe.\");\n            } else {\n                System.out.println(\"Indique el nuevo número de teléfono para el contacto \\\"\" + contactName + \"\\\":\");\n                String newContactPhoneNumber = checkPhoneNumberInput(SCN.nextLine().trim());\n                CONTACTS_AGENDA.put(contactName, newContactPhoneNumber);\n                System.out.println(\"El nuevo número de teléfono de \" + contactName + \" es: \" + newContactPhoneNumber);\n            }\n        }\n    }\n\n    // Eliminar contacto\n    private static void deleteContact() {\n        if (CONTACTS_AGENDA.isEmpty()) {\n            System.out.println(\"La agenda de contactos está vacía.\");\n        } else {\n            System.out.println(\"Indique el nombre del contacto que desea eliminar:\");\n            String contactName = checkNameInput(SCN.nextLine().trim());\n\n            if (!CONTACTS_AGENDA.containsKey(contactName)) {\n                System.out.println(\"El contacto \\\"\" + contactName + \"\\\" no existe.\");\n            } else {\n                CONTACTS_AGENDA.remove(contactName);\n                System.out.println(\"El contacto \\\"\" + contactName + \"\\\" ha sido eliminado.\");\n            }\n        }\n    }\n\n    // Imprimir todos los contactos existentes\n    private static void printAllContacts() {\n        if (CONTACTS_AGENDA.isEmpty()) {\n            System.out.println(\"La agenda de contactos está vacía.\");\n        } else {\n            System.out.println(\"Contactos existentes:\");\n            CONTACTS_AGENDA.forEach((contactName, contactPhoneNumber) -> {\n                System.out.println(contactName + \" - \" + contactPhoneNumber);\n            });\n        }\n    }\n\n\n    public static void main (String[]args){\n        runContactsAgenda();\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/CurtoBrull.java",
    "content": "import java.util.ArrayList;\nimport java.util.BitSet;\nimport java.util.Deque;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Hashtable;\nimport java.util.InputMismatchException;\nimport java.util.LinkedHashMap;\nimport java.util.LinkedList;\nimport java.util.PriorityQueue;\nimport java.util.Scanner;\nimport java.util.Stack;\nimport java.util.TreeMap;\nimport java.util.TreeSet;\nimport java.util.concurrent.ConcurrentHashMap;\n\npublic class CurtoBrull {\n    public static void main(String[] args) {\n\n        // Creación de todas las estructuras soportadas por defecto en tu lenguaje.\n        // Array\n        int[] array = {1, 2, 3, 4, 5};\n        // ArrayList\n        ArrayList<Integer> arrayList = new ArrayList<>();\n        arrayList.add(1);\n        // Map\n        HashMap<String, Integer> map = new HashMap<>();\n        map.put(\"key1\", 1);\n        // HashSet\n        HashSet<Integer> hashSet = new HashSet<>();\n        hashSet.add(1);\n        // LinkedList\n        LinkedList<Integer> linkedList = new LinkedList<>();\n        linkedList.add(1);\n        //TreeMap\n        TreeMap<String, Integer> treeMap = new TreeMap<>();\n        treeMap.put(\"key1\", 1);\n        // TreeSet\n        TreeSet<Integer> treeSet = new TreeSet<>();\n        treeSet.add(1);\n        // LinkedHashMap\n        LinkedHashMap<String, Integer> linkedHashMap = new LinkedHashMap<>();\n        linkedHashMap.put(\"key1\", 1);\n        // Stack\n        Stack<Integer> stack = new Stack<>();\n        stack.push(1);\n        // PriorityQueue\n        PriorityQueue<Integer> priorityQueue = new PriorityQueue<>();\n        priorityQueue.add(1);\n        // BitSet\n        BitSet bitSet = new BitSet();\n        bitSet.set(1);\n        // Vector\n        Deque<Integer> vector = new LinkedList<>();\n        vector.add(1);\n        // HashTable\n        Hashtable<String, Integer> hashTable = new Hashtable<>();\n        hashTable.put(\"key1\", 1);\n        // ConcurrentHashMap\n        ConcurrentHashMap<String, Integer> concurrentHashMap = new ConcurrentHashMap<>();\n        concurrentHashMap.put(\"key1\", 1);\n        // Etc...\n\n        // Utiliza operaciones de inserción, borrado, actualización y ordenación.\n        // Actualizar en ArrayList\n        arrayList.set(0, 2);\n        // Insertar en ArrayList\n        arrayList.add(2);\n        // Borrar en ArrayList\n        arrayList.remove(1);\n        // Ordenar en ArrayList\n        arrayList.sort(null);\n\n        // Agenda\n        agenda();\n    }\n\n    /**\n     * Función para simular una agenda telefónica\n     * Permite buscar, insertar, actualizar y eliminar contactos\n     */\n    public static void agenda() {\n        HashMap<String, Integer> agenda = new HashMap<>();\n        boolean exitProgram = false;\n        while (!exitProgram) {\n            System.out.println(\"1. Buscar contacto\");\n            System.out.println(\"2. Insertar contacto\");\n            System.out.println(\"3. Actualizar contacto existente\");\n            System.out.println(\"4. Eliminar contacto\");\n            System.out.println(\"5. Salir\");\n\n            // Leer la opción del usuario por teclado\n            Scanner scanner = new Scanner(System.in);\n            int option = scanner.nextInt();\n\n            switch (option) {\n                case 1 -> searchContact(agenda, scanner);\n                case 2 -> insertContact(agenda, scanner);\n                case 3 -> updateContact(agenda, scanner);\n                case 4 -> deleteContact(agenda, scanner);\n                case 5 -> {\n                    System.out.println(\"Saliendo...\");\n                    exitProgram = true;\n                }\n            }\n\n        }\n\n    }\n\n    /**\n     * Función para buscar un contacto en la agenda\n     *\n     * @param agenda  contacto de la agenda a buscar\n     * @param scanner scanner para leer la entrada del usuario\n     */\n    public static void searchContact(HashMap<String, Integer> agenda, Scanner scanner) {\n        System.out.println(\"Ingrese el nombre del contacto a buscar\");\n        String searchName = scanner.next();\n        if (agenda.containsKey(searchName)) {\n            System.out.println(\"El número de \" + searchName + \" es \" + agenda.get(searchName) + \"\\n\");\n        } else {\n            System.out.println(\"No se ha encontrado el contacto\\n\");\n        }\n    }\n\n    /**\n     * Función para insertar un contacto en la agenda\n     *\n     * @param agenda contacto de la agenda a insertar\n     * @param scanner scanner para leer la entrada del usuario\n     */\n    public static void insertContact(HashMap<String, Integer> agenda, Scanner scanner) {\n        System.out.println(\"Ingrese el nombre del contacto a insertar\");\n        String insertName = scanner.next();\n        int insertNumber = validateNumber(scanner);\n        if (insertNumber != -1) {\n            if (agenda.containsKey(insertName)) {\n                System.err.println(\"El contacto ya existe\\n\");\n            } else {\n                agenda.put(insertName, insertNumber);\n                System.out.println(\"El contacto \" + insertName + \" ha sido añadido con el número \" + insertNumber + \"\\n\");\n            }\n        }\n    }\n\n    /**\n     * Función para actualizar un contacto en la agenda\n     *\n     * @param agenda contacto de la agenda a actualizar\n     * @param scanner scanner para leer la entrada del usuario\n     */\n    public static void updateContact(HashMap<String, Integer> agenda, Scanner scanner) {\n        System.out.println(\"Ingrese el nombre del contacto a actualizar\");\n        String oldName = scanner.next();\n        if (!agenda.containsKey(oldName)) {\n            System.err.println(\"El contacto no existe\\n\");\n            return;\n        }\n        System.out.println(\"Ingrese el nuevo nombre del contacto\");\n        String newName = scanner.next();\n        int updateNumber = validateNumber(scanner);\n        if (updateNumber != -1) {\n            agenda.remove(oldName);\n            agenda.put(newName, updateNumber);\n            System.out.println(\"El contacto \" + oldName + \" ha sido actualizado a \" + newName + \" con el número \" + updateNumber + \"\\n\");\n        }\n    }\n\n    /**\n     * Función para eliminar un contacto en la agenda\n     *\n     * @param agenda contacto de la agenda a eliminar\n     * @param scanner scanner para leer la entrada del usuario\n     */\n    public static void deleteContact(HashMap<String, Integer> agenda, Scanner scanner) {\n        System.out.println(\"Ingrese el nombre del contacto a eliminar\");\n        String deleteName = scanner.next();\n        if (!agenda.containsKey(deleteName)) {\n            System.err.println(\"El contacto no existe\\n\");\n            return;\n        }\n        agenda.remove(deleteName);\n        System.out.println(\"El contacto \" + deleteName + \" ha sido eliminado\\n\");\n    }\n\n    /**\n     * Función para validar un número de teléfono\n     *\n     * @param scanner scanner para leer la entrada del usuario\n     * @return número de teléfono validado\n     */\n    public static int validateNumber(Scanner scanner) {\n        int number = -1;\n        boolean validNumber = false;\n        while (!validNumber) {\n            System.out.println(\"Ingrese el número del contacto\");\n            try {\n                number = scanner.nextInt();\n                // Comprobar si el número es válido utilizando regex\n                if (!String.valueOf(number).matches(\"[0-9]{1,11}\")) {\n                    System.err.println(\"El número de teléfono no es válido\\n\");\n                } else {\n                    validNumber = true;\n                }\n            } catch (InputMismatchException e) {\n                System.err.println(\"Error: Debes ingresar un número válido\\n\");\n                scanner.next();\n            }\n        }\n        return number;\n    }\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/DanielBelenguer.java",
    "content": "import java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.LinkedHashMap;\nimport java.util.LinkedList;\nimport java.util.Scanner;\nimport java.util.TreeMap;\nimport java.util.TreeSet;\n\npublic class DanielBelenguer {\n/*\n* EJERCICIO:\n* - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n* - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n*\n* DIFICULTAD EXTRA (opcional):\n* Crea una agenda de contactos por terminal.\n* - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n* - Cada contacto debe tener un nombre y un número de teléfono.\n* - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n*   los datos necesarios para llevarla a cabo.\n* - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n*   (o el número de dígitos que quieras)\n* - También se debe proponer una operación de finalización del programa.\n*/\npublic static void main(String[] args) {\n    // Creación de estructuras de datos en Java\n\n    // Array\n    int[] arrayNúmeros = {1,4,6,7,8};\n    // Vamos a mostrar el contenido del array de números\n    for (int i : arrayNúmeros) {\n        System.out.println(i);\n    }\n\n    String[] arrayStrings = new String[3];\n    arrayStrings[0] = \"Hola\";\n    arrayStrings[1] = \"Mundo\";\n    arrayStrings[2] = \"Java!!\";\n    // Vamos a mostrar el contenido del array de String\n    for (String string : arrayStrings) {\n        System.out.println(string);\n    }\n\n    // Arrays bidimensionales\n    int[][] matriz = new int[3][3];\n    matriz[0][0] = 1;\n    matriz[0][1] = 2;\n    matriz[0][2] = 3;\n    matriz[1][0] = 4;\n    matriz[1][1] = 5;\n    matriz[1][2] = 6;\n    matriz[2][0] = 7;\n    matriz[2][1] = 8;\n    matriz[2][2] = 9;\n    // Vamos a mostrar el contenido de la matriz\n    for (int i = 0; i < matriz.length; i++) {\n        for (int j = 0; j < matriz[i].length; j++) {\n            System.out.print(matriz[i][j] + \" \");\n        }\n        System.out.println();\n    }\n\n    // Listas\n\n    // ArrayList es la lista que se basa en un array, por lo que es más rápido acceder a los elementos pero más lento añadir o eliminar\n    ArrayList<Integer> listaNúmeros = new ArrayList<>();\n    listaNúmeros.add(3);\n    listaNúmeros.add(1);\n    listaNúmeros.add(2);\n    // Vamos a mostrar el contenido de la lista de números\n    for (Integer integer : listaNúmeros) {\n        System.out.println(integer);\n    }\n\n    // LinkedList es la lista formada por lincks, es decir, cada elemento tiene una referencia al siguiente y al anterior\n    LinkedList<String> listaStrings = new LinkedList<>();\n    listaStrings.add(\"Hola\");\n    listaStrings.add(\"Mundo\");\n    listaStrings.add(\"Java!!\");\n    // Vamos a mostrar el contenido de la lista de strings\n    for (String string : listaStrings) {\n        System.out.println(string);\n    }\n\n\n   // Conjuntos\n\n   // HashSet es un conjunto que no permite elementos duplicados. No garantiza el orden de los elementos.\n    HashSet<String> conjuntoStrings = new HashSet<>();\n    conjuntoStrings.add(\"Hola\");\n    conjuntoStrings.add(\"Mundo\");\n    conjuntoStrings.add(\"Java!!\");\n    // Vamos a mostrar el contenido del conjunto de strings\n    for (String string : conjuntoStrings) {\n        System.out.println(string);\n    }\n\n    //TreeSet es un conjunto que mantiene los elementos ordenados según como tenga el metodo compareTo implementado.\n    TreeSet<Integer> conjuntoNúmeros = new TreeSet<>();\n    conjuntoNúmeros.add(1);\n    conjuntoNúmeros.add(2);\n    conjuntoNúmeros.add(3);\n    // Vamos a mostrar el contenido del conjunto de números\n    for (Integer integer : conjuntoNúmeros) {\n        System.out.println(integer);\n    }\n\n\n    // Mapas\n\n    // HashMap es un mapa que no garantiza el orden de los elementos\n    HashMap<String, Integer> mapaStringsANúmeros = new HashMap<>();\n    mapaStringsANúmeros.put(\"Uno\", 1);\n    mapaStringsANúmeros.put(\"Dos\", 2);\n    mapaStringsANúmeros.put(\"Tres\", 3);\n    // Vamos a mostrar el contenido del mapa de strings a números\n    for (String key : mapaStringsANúmeros.keySet()) {\n        System.out.println(key + \" -> \" + mapaStringsANúmeros.get(key));\n    }\n\n    // TreeMap es un mapa que mantiene los elementos ordenados según como tenga el metodo compareTo implementado.\n    TreeMap<Integer, String> mapaNúmerosAStrings = new TreeMap<>();\n    mapaNúmerosAStrings.put(1, \"Uno\");\n    mapaNúmerosAStrings.put(2, \"Dos\");\n    mapaNúmerosAStrings.put(3, \"Tres\");\n    // Vamos a mostrar el contenido del mapa de números a strings\n    for (Integer key : mapaNúmerosAStrings.keySet()) {\n        System.out.println(key + \" -> \" + mapaNúmerosAStrings.get(key));\n    }\n\n\n    // LinkedHashMap es un mapa que mantiene el orden de inserción de los elementos\n    LinkedHashMap<String, Integer> mapaStringsANúmerosOrdenado = new LinkedHashMap<>();\n    mapaStringsANúmerosOrdenado.put(\"Uno\", 1);\n    mapaStringsANúmerosOrdenado.put(\"Dos\", 2);\n    mapaStringsANúmerosOrdenado.put(\"Tres\", 3);\n    // Vamos a mostrar el contenido del mapa de strings a números ordenado\n    for (String key : mapaStringsANúmerosOrdenado.keySet()) {\n        System.out.println(key + \" -> \" + mapaStringsANúmerosOrdenado.get(key));\n    }\n\n\n    // Operaciones de inserción, borrado, actualización y ordenación\n\n    // Inserción en un ArrayList\n    listaNúmeros.add(4);\n    listaNúmeros.add(5);\n    // Mostramos el contenido de la lista de números\n    for (Integer integer : listaNúmeros) {\n        System.out.println(integer);\n    }\n\n    // Borrado en una LinkedList\n    listaStrings.remove(\"Mundo\");\n    // Mostramos el contenido de la lista de strings\n    for (String string : listaStrings) {\n        System.out.println(string);\n    }\n\n    // Actualización en un HashMap\n    mapaStringsANúmeros.put(\"Uno\", 10);\n    // Mostramos el contenido del mapa de strings a números\n    for (String key : mapaStringsANúmeros.keySet()) {\n        System.out.println(key + \" -> \" + mapaStringsANúmeros.get(key));\n    }\n\n\n    // Ordenación en un ArrayList\n    listaNúmeros.sort((a, b) -> a - b);\n    // Mostramos el contenido de la lista de números\n    for (Integer integer : listaNúmeros) {\n        System.out.println(integer);\n    }\n\n\n    // Dificultad extra\n\n    // Creacion de menu\n    Scanner lector = new Scanner(System.in);\n    int opt = 0; // Variable para elegir la opción del menú.\n    HashMap<String, Integer> agenda = new HashMap<>(); // Mapa para guardar los contactos\n    do{\n        System.out.println(\"\"\"\n                Bienvenido a la agenda de contactos\n                1. Buscar contacto\n                2. Añadir contacto\n                3. Actualizar contacto\n                4. Eliminar contacto\n                5. Salir\n                Elija una opción: \n                \"\"\");\n        opt = lector.nextInt();\n        switch(opt){\n            case 1:\n                System.out.println(\"Buscar contacto\");\n                String nombreBuscar = lector.nextLine();\n                if(agenda.containsKey(nombreBuscar)){\n                    System.out.println(\"El contacto \" + nombreBuscar + \" tiene el número \" + agenda.get(nombreBuscar));\n                }\n                break;\n            case 2:\n                System.out.println(\"Añadir contacto\");\n                String nombre = lector.nextLine();\n                int telefono = lector.nextInt();\n                agenda.put(nombre, telefono);\n                System.out.println(\"Contacto añadido\");\n                break;\n            case 3:\n                System.out.println(\"Actualizar contacto\");\n                String nombreActualizar = lector.nextLine();\n                if(agenda.containsKey(nombreActualizar)){\n                    int telefonoActualizar = lector.nextInt();\n                    agenda.put(nombreActualizar, telefonoActualizar);\n                    System.out.println(\"Contacto actualizado\");\n                }\n                break;\n            case 4:\n                System.out.println(\"Eliminar contacto\");\n                String nombreEliminar = lector.nextLine();\n                if(agenda.containsKey(nombreEliminar)){\n                    agenda.remove(nombreEliminar);\n                    System.out.println(\"Contacto eliminado\");\n                }\n                break;\n            case 5:\n                System.out.println(\"Saliendo del programa\");\n                break;\n            default:\n                System.out.println(\"Opción no válida\");\n                break;\n        }\n        \n    }while(opt != 5);\n    lector.close();\n}\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/Davidr1594.java",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\nimport java.util.ArrayDeque;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Queue;\nimport java.util.Scanner;\nimport java.util.Stack;\n\npublic class Davidr1594 {\n\n    public static void main(String[] args) {\n\n        /*\n         * Tipos de estructuras en Java\n         * \n         * Arrays - Los arrays o arreglos, son colecciones de elementos del mismmo tipo,\n         * accesibles a traves\n         * son estaticos en tamaño, lo que significa que su tama no puede cambiar\n         * después de la creación.\n         */\n        // Ejemplo\n        int[] arreglo = { 1, 2, 3, 4, 5 };\n        for (int num : arreglo) {\n            System.out.println(num);\n        }\n        /*\n         * ArrayList - Coleccion que contiene un tamaño dinamico, el nombre de una serie\n         * de nombres, mostrando\n         * la operacion de añadir y obtener la salida de elementos.\n         */\n        // Ejemplo\n        ArrayList<String> nombres = new ArrayList<>();\n        nombres.add(\"David\");\n        nombres.add(\"Carlos\");\n        nombres.add(\"Daniela\");\n        nombres.add(\"Sofia\");\n        System.out.println(nombres);\n        // borrar\n        nombres.remove(3);\n        // Actualizar\n        nombres.set(2, \"Daniela\");\n        // Ordenamiento\n        Collections.sort(nombres);\n        System.out.println(nombres);\n\n        /*\n         * Mapas - Estas estructuras de datos almacenan datos en forma de\n         * pares(clave-valor), lo que facilita la\n         * busqueda y recuperación eficiente de vaores mediante clave única.\n         */\n        // Ejemplo\n        HashMap<String, Integer> edades = new HashMap<>();\n        edades.put(\"David\", 29);\n        edades.put(\"Sofia\", 22);\n        edades.put(\"Daniel\", 34);\n        edades.put(\"Elvin\", 28);\n        System.out.println(edades);// muestra todos los datos\n        System.out.println(edades.get(\"David\"));// obtener un elemento del diccionario mediante la key.\n        for (Map.Entry<String, Integer> entry : edades.entrySet()) {// Recorre todos las key y values\n            System.out.println(\"Nombre: \".concat(entry.getKey()) + \" Edad: \" + entry.getValue());\n        }\n        // Para borrar un elemento\n        edades.remove(\"Elvin\");\n        // Para ver si el hash contiene un elemento\n        edades.containsKey(\"Elvin\");\n        // Para actualizar valor\n        edades.put(\"David\", 30);\n\n        /*\n         * Colas - Las colas siguen el princiiop \"FIFO\"(primero en entrar, primeor en\n         * salir). Pueden ser implementadas\n         * como PriorityQuere o LinkedList. Son útiles en situaciones donde el orden de\n         * llegada es relevante, el ejemplo\n         * típico, es la cola de tareas de la bandeja de impresión.\n         */\n        // Ejemplo\n        Queue<String> colas = new ArrayDeque<>();\n        colas.add(\"David\");\n        colas.add(\"Daniel\");\n        colas.add(\"Daniela\");\n        System.out.println(colas);\n        // Poll elimina y devuelve el primer elemento de la cola\n        colas.poll();\n        // Peel devuelve el primer elemento de la lista sin eliminarlo\n        colas.peek();\n\n        /*\n         * Pilas - Ultimo en entrar, primero en salir (FIFO).\n         */\n        // Ejemplo\n        Stack<String> books = new Stack<>();\n        books.push(\"El retrato de Dorian Grey\");\n        books.push(\"El Principito\");\n        books.push(\"Habitos Atomicos\");\n        System.out.println(books);\n        // Peek Ver el ultimo elemento\n        System.out.println(books.peek());\n        // Eliminar el ultimo elemento\n        books.pop();\n        // Buscar elemento\n        books.search(\"El Principito\");\n\n        // Ejercicio Extra de Agenda Telefonica\n        ejercicioExtra();\n\n    }\n\n\n    // Funcion principal que llama a las demas funciones del ejercicio Extra\n    public static void ejercicioExtra() {\n        HashMap<String, Long> agendaTelefonicaMap = new HashMap<>();\n\n        Scanner res = new Scanner(System.in);\n        Scanner datos = new Scanner(System.in);\n\n        Long numero;\n        String nombre;\n        int respuesta = 0;\n\n        System.out.println(\"\\n\\n\\n\");\n        System.out.println(\"-----------Bienvenido a la Agenda Telefonica-----------\");\n\n        while (respuesta != 5) {\n            System.out.println(\"\\n\");\n            System.out.println(\"1. Ver contactos\");\n            System.out.println(\"2. Agregar contactos\");\n            System.out.println(\"3. Actualizar contacto\");\n            System.out.println(\"4. Eliminar contacto\");\n            System.out.println(\"5. Salir\");\n            respuesta = res.nextInt();\n\n            if (respuesta == 1) {\n                System.out.println(\"\\n\\n----------Lista de Contactos-----------\\n\\n\");\n                verContactos(agendaTelefonicaMap);\n\n            } else if (respuesta == 2) {\n                System.out.println(\"\\n¿Con que nombre quieres agregar el nuevo contaco?\");\n                nombre = datos.next();\n                System.out.println(\"¿Cual es el numero de este nuevo contacto?\");\n                numero = datos.nextLong();\n                agregarContacto(nombre, numero, agendaTelefonicaMap);\n\n            } else if (respuesta == 3) {\n                System.out.println(\"\\nElige el contacto que quieres actualizar por su nombre\\n\");\n                verContactos(agendaTelefonicaMap);\n                nombre = datos.next();\n                System.out.println(\"\\nIngresa un nuevo nombre: \");\n                String nuevoNombre = datos.next();\n                System.out.println(\"\\nIngresa nuevo numero: \");\n                Long nuevoNumero = datos.nextLong();\n                actualizarContacto(nombre,nuevoNombre, nuevoNumero, agendaTelefonicaMap);\n\n            } else if (respuesta == 4) {\n                System.out.println(\"\\nElige el contacto que quieres eliminar por su nombre\\n\");\n                verContactos(agendaTelefonicaMap);\n                nombre = datos.next();\n                eliminarContacto(nombre, agendaTelefonicaMap);\n            }\n        }\n    }\n\n    //Funcion para actualizar contactos\n    private static void actualizarContacto(String nombre, String nuevoNombre, Long nuevoNumero, HashMap<String, Long> agendaTelefonicaMap) {\n        if (agendaTelefonicaMap.containsKey(nombre)){\n            agendaTelefonicaMap.remove(nombre);\n            agendaTelefonicaMap.put(nuevoNombre, nuevoNumero);\n        }\n    }\n\n    //Funcion para eliminar contactos\n    private static void eliminarContacto(String nombre, HashMap<String, Long> agendaTelefonicaMap) {\n        agendaTelefonicaMap.remove(nombre);\n        System.out.println(\"\\n*****Contacto Eliminado****\\n\");\n    }\n\n    // Funcion para ver los contactos\n    private static void verContactos(HashMap<String, Long> agendaTelefonicMap) {\n        if (agendaTelefonicMap.isEmpty()) {\n            System.out.println(\"Aun no hay ningun contacto guardado\\n\\n\");\n        } else {\n            for (Map.Entry<String, Long> entry : agendaTelefonicMap.entrySet()) {\n                System.out.println(\"Nombre: \".concat(entry.getKey()) + \" Numero: \" + entry.getValue());\n            }\n        }\n    }\n\n    // Funcion para guardar un contacto\n    private static void agregarContacto(String nombre, Long numero, HashMap<String, Long> agendaTelefonicMap) {\n        String numeroCoversion = String.valueOf(numero);\n        if (numeroCoversion.length() > 8) {\n            System.out.println(\n                    \"\\n***El numero excede la capacidad de cifras aceptadas, ingrese un numero telefonico no mayor a 8 digitos*****\");\n            return;\n        } else {\n            agendaTelefonicMap.put(nombre, numero);\n            System.out.println(\"\\n**Contacto Guardado**\");\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/DiegoIBB.java",
    "content": "package Estructura_Datos_03;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Dictionary;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Hashtable;\nimport java.util.Iterator;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.Scanner;\nimport java.util.Set;\n\npublic class Estructura_Datos {\n\tpublic static void main(String[]args) {\n\t\t\n\t\t//---------------------------------------------------------------\n\t\t//---------------------------- ARRAY ----------------------------\n\t\t//---------------------------------------------------------------\n\t\t\n\t\tSystem.out.println(\"-------- ARRAY -------- \\n\");\n\t\t\n\t\t/*Un Array es una estructura de almacenamiento que guarda\n\t\t *datos del mismo tipo en una sola variable.*/\n\t\t\n\t\tString [] cars = {\"BMW\", \"Volvo\", \"Ford\", \"Mazda\"};\n\t\t\n\t\t//----- 1) Acceder a elementos\n\t\t\n\t\tSystem.out.println(\"Acces to the fisrt item: \" + cars[0]);\n\t\t\n\t\t//Recorrer un array usando ciclos for\n\n\t\tSystem.out.println(\"Array Number_1\");\n\t\tfor(int c=0; c<cars.length; c++) {\n\t\t\tSystem.out.println(\"Position: \" + c + \", Item: \" + cars[c]);\n\t\t}\n\n\t\t//Recorrer un Array usando For-each\n\t\t\n\t\tfor (String c : cars) { // Con esta forma no necesitamos especificar la longitud del array\n\t\t\tSystem.out.println(c);\n\t\t}\n\t\t\t\t\n\t\t//----- 2) Métodos sobre los elementos\n\t\t\n\t\t//Cambiar elementos de un array\n\t\tcars[2] = \"Mercedes Benz\";\n\t\tSystem.out.println(\"Item 2 change it: \" + cars[2]);\n\t\t\n\t\t//Conocer la cantidad de elementos\n\t\tSystem.out.println(\"Lenght Array Cars: \" + cars.length);\n\t\t\n\t\t\n\t\t//--------------------------------------------------------------------\n\t\t//---------------------------- ARRAY LIST ----------------------------\n\t\t//--------------------------------------------------------------------\n\t\t\n\t\t/*Un ArrayList es una estructura que nos permite utilizar métodos para insertar\n\t\t *datos, remover o cambiar dentro de un ArrayList.*/\n\t\t\n\t\tSystem.out.println(\"-------- ARRAY LIST -------- \\n\");\n\t\t\n\t\tArrayList<Integer> numbers = new ArrayList<Integer>();\n\n\t\tnumbers.add(1);\n\t\tnumbers.add(2);\n\t\tnumbers.add(3);\n\t\tnumbers.add(4);\n\t\tnumbers.add(5);\n\t\tnumbers.add(6);\n\t\tnumbers.add(7);\n\t\t\n\t\t//Diferentes tipos de datos en arrays\n\t\t\n\t\tArrayList<Double> numbers_2 = new ArrayList<Double>();\n\t\tArrayList<Float> numbers_3 = new ArrayList<Float>();\n\t\tArrayList<Character> numbers_4 = new ArrayList<Character>();\n\n\t\t\n\t\t//----- 1) Acceder a elementos\n\t\t\n\t\tSystem.out.println(numbers); //Acceder a la lista de elementos\n\t\tSystem.out.println(\"Pos0: \" + numbers.get(0) + \" Pos5: \" + numbers.get(4)); // Acceder a diferentes elementos por su indice\n\t\t\n\t\tSystem.out.println(\"Usando bucle For\");\n\t\tfor(int i =0; i< numbers.size(); i++) { // Acceder a diferentes elementos por medio de un bucle FOR\n\t\t\tSystem.out.println(numbers.get(i));\n\t\t}\n\t\tSystem.out.println(\"Usando bucle For-each\");\n\t\tfor (Integer i : numbers) {\n\t\t\tSystem.out.println(i);\n\t\t}\n\n\t\t\n\t\t//----- 2) Métodos sobre los elementos\n\t\t\n\t\t//Método de adición\n\t\tnumbers.add(8);\n\t\tSystem.out.println(\"Usando add: \" + numbers);\n\t\t\n\t\t// Método para cambiar un elemento\n\t\tnumbers.set(0, 10); //Especificamos indice y el nuevo valor\n\t\tSystem.out.println(\"Usando set: \" + numbers);\n\t\t\n\t\t//Método remove\n\t\tnumbers.remove(0);\n\t\tSystem.out.println(\"Usando remove: \" + numbers);\n\t\t\n\t\t//Método clear para remover todos los elementos de un array\n\t\tnumbers.clear();\n\t\tSystem.out.println(\"Usando clear: \" + numbers);\n\t\t\n\t\t//Método para conocer el largo de un array\n\t\tnumbers.add(8);\n\t\tnumbers.add(5);\n\t\tnumbers.add(1);\n\t\tnumbers.add(14);\n\t\tSystem.out.println(\"Usando size: \" + numbers.size());\n\n\t\t//Método para ordenar datos de un array (libreria Collections)\n\t\tSystem.out.println(\"Datos ordenados usando Collections.sort\");\n\t\tCollections.sort(numbers);\n\t\tfor(Integer i: numbers) {\n\t\t\tSystem.out.println(i);\n\t\t}\n\t\t\n\t\t//--------------------------------------------------------------------------------\n\t\t//---------------------------- ARRAY MULTIDIMENSIONAL ----------------------------\n\t\t//--------------------------------------------------------------------------------\n\t\t\n\t\t/* Los arrays multidimensionales son usados cuando se quiere\n\t\t * guardar datos en forma de tablas(filas y columnas), la \n\t\t * sintaxis es añadiendo cada array dentro de uno general*/\n\t\t\n\t\t//----- Acceder a los elementos de los arrays -----\n\n\t\tint[][] multiArray = {{1,2,3,4,5}, {6,7,8,9}};\n\n\t\tSystem.out.println(multiArray[1][3]);\n\t\t\n\t\t/* En el array anterior seleccionamos el segundo elemento del array (1)\n\t\t * y luego accedemos al tercer elemento del array antes seleccionado (2)\n\t\t * NOTA: En los arrays los valores se organizan desde la posición 0 como\n\t\t * valor inicial*/\n\n\t\t//----- Podemos cambiar elementos del array -----\n\t\t// En este caso cambiamos el 4 elemento del primer array de valor 4 a 7\n\t\t\n\t\tSystem.out.println(\"Cambio en el valor de un elemento\");\n\t\tSystem.out.println(multiArray[0][3]);\n\t\tmultiArray [0][3] = 7;\n\t\tSystem.out.println(multiArray[0][3]);\n\t\t\n\t\t\n\t\t//--------------------------------------------------------------------\n\t\t//----------------------------- HASH SET -----------------------------\n\t\t//--------------------------------------------------------------------\n\t\t\n\t\tSystem.out.println(\"-------- HASH SET -------- \\n\");\n\n\t\t// Un Hash Set es una estructura de datos que no admite elementos duplicados\n\t\t\n\t\tSet<String> hash_set = new HashSet<String>(); // Creamos el objeto \"hash_set\" a partir da la clase Set\n\t\t\n\t\t//Método para añadir elementos a un set\n\t\t\n\t\thash_set.add(\"Australia\");\n\t\thash_set.add(\"Alemania\");\t\t\n\t\thash_set.add(\"Estados Unidos\");\n\t\thash_set.add(\"Chile\");\n\t\thash_set.add(\"Holanda\");\n\t\tSystem.out.println(hash_set);\n\n\t\t//----- 1) Acceder a elementos\n\t\t\n\t\tSystem.out.println(hash_set.contains(\"Alemania\"));\n\t\t\n\t\t//----- 2) Métodos sobre los elementos\n\t\t\n\t\tSet<String> lenguage_set = new HashSet<String>();\n\t\t\n\t\t//Método ADD, con el podemos agregar elementos a un set\n\t\tlenguage_set.add(\"Java\");\n\t\tlenguage_set.add(\"Python\");\n\t\tlenguage_set.add(\"SQL\");\n\t\tlenguage_set.add(\"Rust\");\n\t\tlenguage_set.add(\"C++\");\n\t\tlenguage_set.add(\"C\");\n\t\tlenguage_set.add(\"Kotlin\");\n\t\t\n\t\tSystem.out.println(lenguage_set);\n\t\t\n\t\t// Método REMOVE, con el podemos quitar elementos de un set\n\t\tlenguage_set.remove(\"Kotlin\");\t\t\n\t\tSystem.out.println(lenguage_set);\n\t\t\n\t\t// Método SIZE, con el podemos obtener la cantidad de elementos de un set\n\t\tSystem.out.println(lenguage_set.size());\t\t\n\t\t\n\t\tSet<String> lenguage_set_2 = new HashSet<String>();\n\n\t\tlenguage_set_2.add(\"PHP\");\n\t\tlenguage_set_2.add(\"React\");\n\t\tlenguage_set_2.add(\"R\");\n\t\tlenguage_set_2.add(\"JavaScript\");\n\t\tlenguage_set_2.add(\"HTML\");\n\t\tlenguage_set_2.add(\"CSS\");\n\t\t\n\t\t// Método ITERATOR, con el podemos iterar sobre los elementos de un set\n\t\tIterator<String> it = lenguage_set_2.iterator();\n\t\twhile(it.hasNext()) { //Usamos un bucle While y el método hasNext\n\t\t\tSystem.out.println(it.next()); //Retorna un set vacio\n\t\t}\n\t\t\n\t\t// Método CLEAR, con el podemos borrar todos los elementos de un set\n\t\tlenguage_set_2.clear();\n\t\tSystem.out.println(lenguage_set_2); //Retorna un set vacio\n\t\t\n\t\t\n\t\t//--------------------------------------------------------------------\n\t\t//----------------------------- HASH MAP -----------------------------\n\t\t//--------------------------------------------------------------------\n\t\t\n\t\tSystem.out.println(\"-------- HASH MAP -------- \\n\");\n\t\t\n\t\t// Un Hash Map es una estructura de datos que toma valores en la forma Key:Values\n\t\t// los valores de las values pueden ser de diferentes tipos, no necesariamente string\n\n\t\tHashMap<String, String> capitalCities = new HashMap<String, String>();\n\t\t\n\t\t//Añadimos elementos usando el método put\n\t\t\n\t\tcapitalCities.put(\"England\", \" London\");\n\t\tcapitalCities.put(\"Germany\", \" Berlin\");\t\t\n\t\tcapitalCities.put(\"Norway\", \" Oslo\");\t\t\n\t\tcapitalCities.put(\"USA\", \" Washington DC\");\n\t\tSystem.out.println(capitalCities);\n\t\t\n\t\t//----- 1) Acceder a elementos\n\t\tSystem.out.println(capitalCities.get(\"England\"));\n\t\t\n\t\t//----- 2) Métodos sobre los elementos\n\t\t\n\t\t//Método PUT, con el podemos agregar elementos a un HashMap\n\t    capitalCities.put(\"USA\", \"Washington DC\");\n\t\t\n\t\t//Método REMOVE es utilizado para sacar elementos de un HashMap\n\t\tcapitalCities.remove(\"England\");\n\t\tSystem.out.println(capitalCities);\n\t\t\n\t\t//Método SIZE, utilizado para conocer la cantidad de parejas que hay en un HashMap\n\t\tSystem.out.println(capitalCities.size());\n\t\t\n\t\t//Método CLEAR, se utiliza para limpiar un HashMap de todos los elementos que contiene\n\t\tcapitalCities.clear();\n\t\tSystem.out.println(capitalCities);\n\t\t\n\t\t\n\t\tcapitalCities.put(\"England\", \"London\");\n\t\tcapitalCities.put(\"Germany\", \"Berlin\");\t\t\n\t\tcapitalCities.put(\"Norway\", \"Oslo\");\t\t\n\t\tcapitalCities.put(\"USA\", \"Washington DC\");\n\t\tcapitalCities.put(\"Chile\", \"Santiago\");\n\t\tcapitalCities.put(\"Australia\", \"Camberra\");\n\t\t\n\t\t//----- 1) Acceder a elementos usando un loop\n\t\t//Este loop lo usamos para obtener la clave (KEY)\n\t\tfor(String i: capitalCities.keySet()) {\n\t\t\tSystem.out.println(\"Key: \" + i);\n\t\t}\n\t\t//Este loop lo usamos para obtener el valor (VALUE)\n\t\tfor(String i: capitalCities.values()) {\n\t\t\tSystem.out.println(\"Value: \" + i);\n\t\t}\n\t\t\n\t\t//--------------------------------------------------------------------\n\t\t//---------------------------- DICTIONARY ----------------------------\n\t\t//--------------------------------------------------------------------\n\t\t\n\t\tSystem.out.println(\"-------- DICTIONARY -------- \\n\");\n\n\t\t//La clase dictionay nos permite crear diccionarios con una Key y un Value, es similar al Hashmap\n\t\t\n\t\tDictionary<String, Integer> dict = new Hashtable<>();\n\t\t\n\t\t//Método PUT, con el podemos agregar elementos a un dictionary\n\t\tdict.put(\"Porsche\", 1931);\n\t\tdict.put(\"Mercedez Benz\", 1926);\n\t\tdict.put(\"Ferrari\", 1939);\n\t\tdict.put(\"BMW\", 1916);\n\t\t\n\t\tSystem.out.println(dict);\n\t\t\n\t\t//----- 1) Acceder a elementos\n\t\tSystem.out.println(dict.get(\"BMW\"));\n\t\t\n\t\t//----- 2) Métodos sobre los elementos\n\t\t\n\t\t//Método REMOVE, para remover elementos\n\t\tdict.remove(\"Ferrari\");\n\t\tSystem.out.println(dict);\n\n\t\t//Método SIZE, para conocer el largo de una lista\n\t\tSystem.out.println(dict.size());\n\t\t\n\n\t\t//--------------------------------------------------------\n\t\t//--------------------- LINKEDLIST -----------------------\n\t\t//--------------------------------------------------------\n\t\t\n\t\tSystem.out.println(\"-------- LINKEDLIST -------- \\n\");\n\t\t\n\t\t//La estructura linked list nos permite crear conjuntos de datos en formato lista\n\t\t//puede contener varios objetos del mismo tipo\n\t\t\n\t\tLinkedList<String> nombres = new LinkedList<String>();\n\t\t\n\t\t//Método ADD, con el podemos agregar elementos a un LinkedList\n\t\tnombres.add(\"Serena\");\n\t\tnombres.add(\"Diego\");\n\t\tnombres.add(\"Alan\");\n\t\tnombres.add(\"Pablo\");\n\t\tnombres.add(\"Andres\");\n\t\tnombres.add(\"Ignacio\");\n\t\t\n\t\tSystem.out.println(nombres);\n\t\t\n\t\t//----- 1) Acceder a los elementos\n\t\tSystem.out.println(nombres.get(0));\n\t\tSystem.out.println(nombres.get(1));\n\n\t\t\n\t\t//----- 2) Métodos sobre los elementos\n\n\t\t//Método addFirst, añade un item al inicio de la lista\n\t\tnombres.addFirst(\"Maria\");\n\t\t//Método addLast, añade un item al final de la lista\n\t\tnombres.addLast(\"Jose\");\n\t\t\n\t\tSystem.out.println(nombres);\n\t\t\n\t\t// Método POP, para remover el primer elemento de una LinkedList\n\t\tnombres.pop();\n\t\tSystem.out.println(nombres);\n\t\t\n\t\t// Método CONTAINS, para saber si un objeto está en la LinkedList\n\t\tSystem.out.println(nombres.contains(\"Serena\"));\n\t\t\n\t\t//--------------------------------------------------------------------\n\t\t//------------------------------- LIST -------------------------------\n\t\t//--------------------------------------------------------------------\n\t\tSystem.out.println(\"-------- LIST -------- \\n\");\n\t\t\n\t\tList<String> letters = new ArrayList<String>();\n\t\t\n\t\t//Método ADD, con el podemos agregar elementos a una List\n\t\tletters.add(\"A\");\n\t\tletters.add(\"B\");\n\t\tletters.add(\"C\");\n\t\tletters.add(\"D\");\n\t\tletters.add(\"E\");\n\t\t\n\t\tSystem.out.println(letters);\n\t\t\n\t\t//----- 1) Acceder a los elementos\n\t\tSystem.out.println(letters.get(0));\n\t\tSystem.out.println(letters.get(3));\n\t\t\n\t\t//----- 2) Métodos sobre los elementos\n\t\t\n\t\t//Método SET, para cambiar elementos a partir del indice\n\t\tletters.set(3, \"F\");\n\t\tletters.add(0, \"Z\");\n\t\t\n\t\t//Método REMOVE, para remover elementos\n\t\tletters.remove(\"C\");\n\t\tletters.remove(\"B\");\n\t\t\n\t\tSystem.out.println(letters);\n\t\t\n\t\t//Método SIZE, para conocer sobre la cantidad de elementos que hay en una lista\n\t\tSystem.out.println(letters.size());\n\t\t\n\t\t// SORT\n\t\tCollections.sort(letters); //Usamos la clase collections con el método sort para ordenar los elementos\n\t\tSystem.out.println(letters);\n\t\t\n\t\t\n\t\t\n\t\t//--------------------------------------\n\t\t//---------- DIFICULTAD EXTRA ----------\n\t\t//--------------------------------------\n\t\t/*\n\t\tDIFICULTAD EXTRA (opcional):\n\t\t* Crea una agenda de contactos por terminal.\n\t\t* - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n\t\t* - Cada contacto debe tener un nombre y un número de teléfono.\n\t\t* - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n\t\t*   los datos necesarios para llevarla a cabo.\n\t\t* - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n\t\t*   (o el número de dígitos que quieras)\n\t\t* - También se debe proponer una operación de finalización del programa.\n\t\t*/\n\t\tHashMap<String, Integer> contact_list = new HashMap<String, Integer>();\n\t\tint number_contact;\n\t\t\n\t\twhile (true) {\n\t\t\t// Show Options\n\t\t\tSystem.out.println(\"----- Options Available -----\");\n\t\t\tSystem.out.println(\"1_ Add Contact\");\n\t\t\tSystem.out.println(\"2_ Search Contact\");\n\t\t\tSystem.out.println(\"3_ Remove Contact\");\n\t\t\tSystem.out.println(\"4_ Update Contact\");\n\t\t\t\n\t\t\t// Create variables of contact and number\n\t\t\tScanner contact = new Scanner(System.in);\n\t\t\tScanner number = new Scanner(System.in);\n\t\t\t\n\t\t\t//Create a global variable HashMap contact_list \n\n\t\t\t// Select an option\n\t\t\tScanner options = new Scanner(System.in);\n\t\t\tSystem.out.print(\"Select an option: \");\n\t\t\tint option = options.nextInt();\n\t\t\t\n\t\t\tif(option == 1) {\n\t\t\t\tSystem.out.println(\"Option Selected Add Contact\");\n\t\t\t\tSystem.out.print(\"Contact Name: \");\n\t\t\t\tString name_contact = contact.nextLine();\n\t\t\t\tSystem.out.println(\"New Contact Name: \" + name_contact);\n\t\t\t\t\n\t\t\t\tSystem.out.print(\"Phone Number: \");\n\t\t\t    Integer phone_number = number.nextInt();\n\t\t\t\tSystem.out.println(\"New Contact Number: \" + phone_number);\n\t\t\t\t\n\t\t\t\t// Add the contact to a Hash Map\n\t\t\t\tcontact_list.put(name_contact, phone_number);\n\t\t\t\tSystem.out.println(contact_list);\n\t\t\t\t\n\t\t\t}else if(option == 2) {\n\t\t\t\tSystem.out.println(\"Option Selected Search Contact\");\n\t\t\t\tSystem.out.print(\"Contact Name: \");\n\t\t\t\tString name_contact = contact.nextLine();\n\t\t\t\tSystem.out.println(\"Phone Number: \" + contact_list.get(name_contact));\n\n\t\t\t}else if(option == 3) {\n\t\t\t\tSystem.out.println(\"Option Selected Remove Contact\");\n\t\t\t\tSystem.out.println(\"Contact Name: \");\n\t\t\t\tString name_contact = contact.nextLine();\n\t\t\t\tSystem.out.println(contact_list.remove(name_contact) + \"Had been Removed\");\n\t\t\t\t\n\t\t\t}else if(option == 4) { // Resolver la actualizacion del contacto y nombre\n\t\t\t\tSystem.out.println(\"Option Selected Update Contact\");\n\t\t\t\tSystem.out.println(\"---- Item to Update ----\");\n\t\t\t\tSystem.out.println(\"(1) Contact - (2) Number\");\n\t\t\t\tScanner itemUpdate = new Scanner(System.in);\n\t\t\t\tint item = itemUpdate.nextInt();\n\t\t\t\t\n\t\t\t\tif(item == 1) {\n\t\t\t\t\t//Consultar por contacto a modificar\n\t\t\t\t\tScanner contactOld = new Scanner(System.in);\n\t\t\t\t\tSystem.out.print(\"Contact to change: \");\n\t\t\t\t\tString old_contact = contactOld.nextLine();\n\t\t\t\t\t//Definir nuevo nombre del contacto\n\t\t\t\t\tScanner contactNew = new Scanner(System.in);\n\t\t\t\t\tSystem.out.print(\"New Name Contact: \");\n\t\t\t\t\tString new_contact = contactNew.nextLine();\n\t\t\t\t\tnumber_contact = contact_list.get(old_contact);\n\t\t\t\t\t//Eliminar conacto antiguo y agregar nuevo contacto\n\t\t\t\t\tcontact_list.remove(old_contact);\n\t\t\t\t\tcontact_list.put(new_contact, number_contact);\n\t\t\t\t\tSystem.out.println(contact_list);\n\t\t\t\t}else if(item == 2) {\n\t\t\t\t\t//Seleccionar contacto a cambiar el nombre\n\t\t\t\t\tScanner contactNum = new Scanner(System.in);\n\t\t\t\t\tSystem.out.print(\"Contact to change number: \");\n\t\t\t\t\tString contact_num = contactNum.nextLine();\n\t\t\t\t\t//Solicitar nuevo número\n\t\t\t\t\tSystem.out.println(\"Old Number: \" + contact_list.get(contact_num));\n\t\t\t\t\tScanner newNumber = new Scanner(System.in);\n\t\t\t\t\tSystem.out.print(\"New Number: \");\n\t\t\t\t\tint number_new = newNumber.nextInt();\n\t\t\t\t\t//Quitar contacto con numero antiguo\n\t\t\t\t\tcontact_list.remove(contact_num);\n\t\t\t\t\t// Añadir contacto con nuevo numero\n\t\t\t\t\tcontact_list.put(contact_num, number_new);\n\t\t\t\t\t\n\t\t\t\t}\n\t\t\t}else {\n\t\t\t\tSystem.out.println(\"Option Not Available\");\n\t\t\t}\n\t\t\t\n\t\t\t// Ask for more operations or end the program\n\t\t\tScanner moreOperations = new Scanner(System.in);\n\t\t\tSystem.out.print(\"Another Operation yes(1)/no(2)?: \");\n\t\t\tint mOperation = moreOperations.nextInt();\n\t\t\t\n\t\t\tif (mOperation == 1) {\n\t\t\t\tcontinue;\n\t\t\t}else if (mOperation == 2){\n\t\t\t\tSystem.out.println(\"Program Ended\");\n\t\t\t\tSystem.out.println(contact_list);\n\t\t\t\tbreak;\n\t\t\t}else {\n\t\t\t\tSystem.out.println(\"Option not available\");\n\t\t\t}\n\t}\n\t}\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/DomingoAndres.java",
    "content": "import java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.Scanner;\n\npublic class DomingoAndres {\n    public static void main(String[]args){\n\n        //EJERCICIO 03: ESTRUCTURAS DE DATOS\n\n        //ARRAY\n        String[] nombres = new String[3]; //Creamos el array\n        \n        //Le insertamos datos\n        nombres[0] = \"Pedro\";\n        nombres[1] = \"Juan\";\n        nombres[2] = \"Diego\";\n\n        //en los arrays no existe eliminacion directa\n        //podriamos hacer un tipo de limpieza asignando un valor nulo\n        //al indice que queremos \"eliminar\"\n        nombres[1] = null;\n\n        //actualizamos datos\n        nombres[0] = \"Domingo\";\n        nombres[2] = \"Andres\";\n        nombres[1] = \"Juanito\";\n\n        //Ordenamos el array por orden alfabetico\n        Arrays.sort(nombres);\n\n\n        //LIST\n        List<Integer> calificaciones = new ArrayList<>(); //Creamos una lista de tipo ArrayList\n\n        //Insertamos datos\n        calificaciones.add(4);\n        calificaciones.add(3);\n        calificaciones.add(8);\n        calificaciones.add(1);\n        calificaciones.add(10);\n\n        //Eliminamos datos\n        calificaciones.remove(1); //aca estamos eliminando el elemento del indice 1 que seria el valor 3\n\n        //Actualizamos datos\n        calificaciones.set(0, 9); //aca actualizamos el valor del indice 0, paso de 4 a 9\n\n        //Ordenamiento\n        calificaciones.sort(null); //el null los ordena de menor a mayor\n\n\n        //SETS\n        Set<Integer> numeroTelefonico = new HashSet<>(); //creamos un set que alamacenara numeros telefonicos\n\n        //Insertamos datos\n        numeroTelefonico.add(12345678);\n        numeroTelefonico.add(78945612);\n        numeroTelefonico.add(65123488);\n\n\n        //Eliminamos datos\n        numeroTelefonico.remove(12345678);\n\n        //Los datos de los sets no pueden ser actualizados directamente\n\n        //Los sets no pueden ser ordenados directamente ya que esta estructura no prioriza el orden si no la unicidad.\n        \n\n\n        //MAPS\n        Map <String, Integer> productos = new HashMap<>(); //Creamos un mapa de productos con sus respectivos precios\n\n        //Insertamos datos\n        productos.put(\"Hamburguesa\", 5000);\n        productos.put(\"Completo\", 2500);\n        productos.put(\"Bebida\", 1500);\n\n        //Eliminamos datos por su clave\n        productos.remove(\"Completo\");\n\n        //actualizamos\n        productos.replace(\"Hamburguesa\", 5000, 4500);//aca actualizamos el precio de la hamburguesa, paasó de 5000 a 4500\n\n        //Los maps no pueden ser ordenados directamente\n\n\n        //----------------DIFICULTAD EXTRA--------------------------//\n\n        Map <String, String> contactos = new HashMap<>();//creamos la agenda de contactos\n\n        //Agregamos algunos contactos para que la agenda no este vacia\n        contactos.put(\"Maria\", \"12345678916\");\n        contactos.put(\"Juan\", \"7894561234\");\n        contactos.put(\"Pedro\", \"4561237893\");\n\n        //Agregamos el scanner para las selecciones del usuario\n        Scanner scanner = new Scanner(System.in);\n\n        //agregamos un booleano para salir del bucle\n        boolean salir = false;\n        \n        while (!salir) {\n\n            System.out.println(\"|----------------------------------|\");\n            System.out.println(\"       AGENDA DE CONTACTOS\");\n            System.out.println(\"|----------------------------------|\");\n            System.out.println(\"\\n¿Que accion desea realiar?\");\n            System.out.println(\"1. Buscar Contacto\");\n            System.out.println(\"2. Agregar Contacto\");\n            System.out.println(\"3. Actualizar Contacto\");\n            System.out.println(\"4. Eliminar Contacto\");\n            System.out.println(\"5. Salir\");\n            System.out.println(\"Ingrese su eleccion a continuacion:\");\n            \n\n            if (scanner.hasNextInt()) {\n                int opcion = scanner.nextInt();\n                scanner.nextLine();\n\n                switch (opcion) {\n                case 1:\n                    System.out.println(\"Ingrese el nombre del contacto que desea buscar:\");\n                    String nombreBuscar = scanner.nextLine();\n                    \n                    if(contactos.containsKey(nombreBuscar)){\n                        System.out.println(\"el numero de contacto para \" + nombreBuscar + \" es: \" + contactos.get(nombreBuscar));\n                    }else{\n                        System.out.println(\"El numero de contacto para \" + nombreBuscar + \" no existe.\");\n                    }\n                    break;\n                case 2:\n                    System.out.println(\"Ingrese el nombre del nuevo contacto:\");\n                    String nombreNuevo = scanner.nextLine();\n                    System.out.println(\"Ingrese el numero de nuevo contacto:\");\n                    String numeroNuevo = scanner.nextLine();\n                    if(numeroNuevo.length() > 11){\n                        System.out.println(\"Numero de contacto demasiado largo. No pude tener mas de 11 numeros.\");\n                    }else {\n                        System.out.println(\"Nuevo contacto agregado exitosamente.\");\n                        contactos.put(nombreNuevo, numeroNuevo);\n                    }\n                    break;\n                case 3:\n                    System.out.println(\"Ingrese el nombre del contacto que desea actualiar:\");\n                    String nombreActualizar = scanner.nextLine();\n                    \n                    if(contactos.containsKey(nombreActualizar)){\n                        System.out.println(\"Ingrese el nuevo nombre para ese contacto:\");\n                        String nuevoNombre = scanner.nextLine();\n                        \n                        System.out.println(\"Ingrese el nuevo numero para ese contacto:\");\n                        String nuevoNumero = scanner.nextLine();\n                        \n                        if(nuevoNumero.length() > 11){\n                            System.out.println(\"Numero de contacto demasiado largo. No pude tener mas de 11 numeros.\");\n                        }else {\n                            contactos.remove(nombreActualizar);\n\n                            contactos.put(nuevoNombre, nuevoNumero);\n\n                            System.out.println(\"Contacto actualizado correctamente.\");\n                        }\n                    }else {\n                        System.out.println(\"El numero de contacto para \" + nombreActualizar + \" no existe.\");\n                    }\n                    break;\n                case 4:\n                    System.out.println(\"Ingrese el nombre del contacto que desea eliminar:\");\n                    String nombreEliminar = scanner.nextLine();\n                    if (contactos.containsKey(nombreEliminar)) {\n                        contactos.remove(nombreEliminar);\n                        System.out.println(\"El contacto de \" + nombreEliminar + \" se ha eliminado exitosamente de la agenda.\");\n                    }else {\n                        System.out.println(\"El contacto de \" + nombreEliminar + \" no existe.\");\n                    }\n                    break;\n                case 5:\n                    System.out.println(\"Saliendo de la agenda...\");\n                    salir = true;\n                    break;\n            \n                default:\n                    System.out.println(\"Opcion incorrecta. Elija una opcion numerica del 1 al 5\");\n                }\n            }else {\n                System.out.println(\"Opcion incorrecta. Elija una opcion numerica del 1 al 5\");\n                scanner.nextLine();\n            }\n            \n        }\n        scanner.close();\n\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/Dredux2.java",
    "content": "import java.util.*;\npublic class Dredux2 {\n    public static void main(String[] args) {\n        Scanner sc = new Scanner(System.in);\n        /*\n         * EJERCICIO:\n         * - Muestra ejemplos de creación de todas las estructuras de datos soportadas por defecto.\n         * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n         */\n\n        // Array\n        int[] array = {1, 2, 3, 4, 5};\n        array[2] = 10; // Actualización\n        Arrays.sort(array); // Ordenación\n\n        // List\n        List<Integer> lista = new ArrayList<>();\n        lista.add(1); // Inserción\n        lista.add(2); // Inserción\n        lista.remove(0); // Borrado\n        lista.set(0, 10); // Actualización\n        Collections.sort(lista); // Ordenación\n\n        // Set\n        Set<Integer> set = new HashSet<>();\n        set.add(1); // Inserción\n        set.remove(1); // Borrado\n\n        // Map\n        Map<String, Integer> map = new HashMap<>();\n        map.put(\"uno\", 1); // Inserción\n        map.remove(\"uno\"); // Borrado\n        map.put(\"uno\", 10); // Actualización\n\n        EjercicioExtra(sc);\n    }\n\n    /* DIFICULTAD EXTRA (opcional):\n     * Crea una agenda de contactos por terminal.\n     * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n     *   y eliminación de contactos.\n     * - Cada contacto debe tener un nombre y un número de teléfono.\n     * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n     *   y a continuación los datos necesarios para llevarla a cabo.\n     * - El programa no puede dejar introducir números de teléfono no númericos y con más\n     *   de 11 dígitos (o el número de dígitos que quieras).\n     * - También se debe proponer una operación de finalización del programa.\n     */\n\n    public static void EjercicioExtra(Scanner sc) {\n        Map<String, Integer> agenda = new HashMap<>();\n        String nombre;\n        int telefono;\n        int opcion = 0;\n        while (opcion != 5) {\n            System.out.println(\"\\n*** Agenda ***\");\n            System.out.println(\"1. Buscar Contacto\");\n            System.out.println(\"2. Nuevo Contacto\");\n            System.out.println(\"3. Actualizar Contacto\");\n            System.out.println(\"4. Eliminar Contacto\");\n            System.out.println(\"5. Salir\");\n            System.out.print(\"Introduce una opción: \");\n            try {\n                opcion = sc.nextInt();\n                if (opcion < 1 || opcion > 5) {\n                    System.out.println(\"ERROR: Opción no válida.\");\n                    continue;\n                }\n\n                switch (opcion) {\n                    case 1:\n                        System.out.print(\"Introduce el nombre del contacto: \");\n                        nombre = sc.next();\n                        if (agenda.containsKey(nombre)) {\n                            System.out.println(\"El número de teléfono de \" + nombre + \" es \" + agenda.get(nombre));\n                        } else {\n                            System.out.println(\"El contacto no existe.\");\n                        }\n                        continue;\n                    case 2:\n                        System.out.print(\"Introduce el nombre del contacto: \");\n                        nombre = sc.next();\n                        System.out.print(\"Introduce el número de teléfono: \");\n                        telefono = sc.nextInt();\n\n                        while (String.valueOf(telefono).length() != 9) {\n                            System.out.println(\"Número de teléfono no válido.\");\n                            System.out.print(\"Introduce el número de teléfono: \");\n                            telefono = sc.nextInt();\n                        }\n\n                        agenda.put(nombre, telefono);\n                        continue;\n                    case 3:\n                        System.out.print(\"Introduce el nombre del contacto: \");\n                        nombre = sc.next();\n                        if (agenda.containsKey(nombre)) {\n                            System.out.print(\"Introduce el nuevo número de teléfono: \");\n                            telefono = sc.nextInt();\n\n                            while (String.valueOf(telefono).length() != 9) {\n                                System.out.println(\"Número de teléfono no válido.\");\n                                System.out.print(\"Introduce el número de teléfono: \");\n                                telefono = sc.nextInt();\n                            }\n\n                            agenda.put(nombre, telefono);\n                        } else {\n                            System.out.println(\"El contacto no existe.\");\n                        }\n                        continue;\n                    case 4:\n                        System.out.print(\"Introduce el nombre del contacto: \");\n                        nombre = sc.next();\n                        if (agenda.containsKey(nombre)) {\n                            agenda.remove(nombre);\n                            System.out.println(\"Contacto eliminado.\");\n                        } else {\n                            System.out.println(\"El contacto no existe.\");\n                        }\n                }\n                if (opcion == 5) {\n                    System.out.println(\"Saliendo...\");\n                }\n            } catch (InputMismatchException e) {\n                System.out.println(\"ERROR: Opción no válida.\");\n                sc.next();\n            }\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/FranDev200.java",
    "content": "import java.util.*;\nimport java.util.stream.Stream;\n\npublic class FranDev200 {\n\n    static HashMap<Integer, String> contactList = new HashMap<>();\n    static Scanner scan = new Scanner(System.in);\n\n    static void main() {\n\n        /*\n\n        - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n        - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n\n         */\n\n        // ARRAYLIST\n        ArrayList<String> months = new ArrayList<>();\n        months.add(\"Enero\");\n        months.add(\"Febrero\");\n        months.add(\"Marzo\");\n        months.add(\"Abril\");\n        months.add(\"Mayo\");\n        months.add(\"Junio\");\n        months.add(\"Julio\");\n        months.add(\"Agosto\");\n        months.add(\"Septiembre\");\n        months.add(\"Octubre\");\n        months.add(\"Noviembre\");\n        months.add(\"Diciembre\");\n\n        System.out.println(\"Meses del año\");\n        System.out.println(\"=============\");\n        for(String month : months){\n            System.out.println(month);\n        }\n\n        months.remove(1);\n        months.remove(2);\n\n        System.out.println(\"\\nMeses del año (despues de borrar 2)\");\n        System.out.println(\"===================================\");\n        for(String month : months){\n            System.out.println(month);\n        }\n\n        months.set(1, \"Febrero\");\n\n        System.out.println(\"\\nMeses del año (despues de modificar 1)\");\n        System.out.println(\"======================================\");\n        months.forEach(System.out::println);\n\n        System.out.println(\"\\nMeses del año (Ordenados por nombre)\");\n        System.out.println(\"=======================================\");\n\n        sortMonthsByName(months).toList().forEach(System.out::println);\n\n        /*\n        Este bloque de codigo es lo mismo que lo de arriba\n        for (String month: sortMonthsByName(months).toList()){\n            System.out.println(month);\n        }\n        */\n        months.clear();\n        System.out.println(\"\\nMeses del año (despues de borrar todos)\");\n        System.out.println(\"=======================================\");\n        for(String month : months){\n            System.out.println(month);\n        }\n        months.forEach(System.out::println);\n\n        // HASHSET\n        HashSet<Integer> phoneNumber = new HashSet<>();\n        phoneNumber.add(123456789);\n        phoneNumber.add(987654321);\n        phoneNumber.add(111222333);\n        phoneNumber.add(444555666);\n        phoneNumber.add(777888999);\n        phoneNumber.add(676767676);\n\n        System.out.println(\"\\nTelefonos\");\n        System.out.println(\"=========\");\n        for(int number : phoneNumber){\n            System.out.println(number);\n        }\n\n        phoneNumber.remove(phoneNumber.stream().toList().getFirst()); // Podria haber puesto el numero de telefono también\n        System.out.println(\"\\nTelefonos (Después de borrar 1)\");\n        System.out.println(\"===============================\");\n        for(int number : phoneNumber){\n            System.out.println(number);\n        }\n\n        phoneNumber.add(444555666);\n        phoneNumber.add(676767676);\n        System.out.println(\"\\nTelefonos (Intento de duplicados)\");\n        System.out.println(\"=================================\");\n        for(int number : phoneNumber){\n            System.out.println(number);\n        }\n\n        System.out.println(\"\\nTelefonos (Ordenados)\");\n        System.out.println(\"=================================\");\n        List<Integer> phoneOrdered = phoneNumber.stream().sorted(new Comparator<Integer>() {\n            @Override\n            public int compare(Integer o1, Integer o2) {\n\n                return o1.compareTo(o2);\n\n            }\n        }).toList();\n        for(int number : phoneOrdered){\n            System.out.println(number);\n        }\n\n        phoneNumber.clear();\n        System.out.println(\"\\nTelefonos (Despúes de borrarlos)\");\n        System.out.println(\"=================================\");\n        for(int number : phoneNumber){\n            System.out.println(number);\n        }\n\n        System.out.println(\"\\nTelefonos (Comprobar si existe un telefono)\");\n        System.out.println(\"=================================\");\n        System.out.println(phoneNumber.contains(111222333));\n\n        /*\n            En los HashSet no se puede editar un valor en concreto, debido a su estructura interna.\n         */\n\n        // HASHMAP\n        HashMap<String, String[]> identity = new HashMap<>();\n        identity.put(\"09834674Q\", new String[]{\"Francisco\", \"Baviano\", \"Ocampo\"});\n        identity.put(\"09225664R\", new String[]{\"Pedro\", \"López\", \"Dúrez\"});\n        identity.put(\"09236656L\", new String[]{\"Inmaculada\", \"Calvo\", \"Chicharro\"});\n        identity.put(\"09979571X\", new String[]{\"Zaira\", \"Herrán\", \"Gonzalez\"});\n        identity.put(\"09675674N\", new String[]{\"Jesus\", \"García\", \"Ocampos\"});\n\n        System.out.println(\"\\nDNI y su nombre y apellidos\");\n        System.out.println(\"=================================\");\n        for(Map.Entry<String, String[]> person: identity.entrySet()){\n            String[] name = person.getValue();\n            System.out.println(person.getKey() + \" --> \" + name[0] + \" \" + name[1] + \" \" + name[2]);\n        }\n\n        System.out.println(\"\\nDNI y su nombre y apellidos (Otra forma de mostrarlo)\");\n        System.out.println(\"=================================\");\n        for(Map.Entry<String, String[]> person: identity.entrySet()){\n            System.out.println(person.getKey() + \" --> \" + Arrays.stream(person.getValue()).toList());\n        }\n\n        System.out.println(\"\\nDNI y su nombre y apellidos (Ordenador por DNI)\");\n        System.out.println(\"=================================\");\n        for(Map.Entry<String, String[]> person: sortByDNI(identity).toList()){\n            String[] name = person.getValue();\n            System.out.println(person.getKey() + \" --> \" + name[0] + \" \" + name[1] + \" \" + name[2]);\n        }\n\n        identity.remove(\"09225664R\");\n        System.out.println(\"\\nDNI y su nombre y apellidos(Después de eliminar a una persona)\");\n        System.out.println(\"=================================\");\n        for(Map.Entry<String, String[]> person: identity.entrySet()){\n            String[] name = person.getValue();\n            System.out.println(person.getKey() + \" --> \" + name[0] + \" \" + name[1] + \" \" + name[2]);\n        }\n\n        identity.put(\"09675674N\", new String[]{\"David\", \"Baviano\", \"Ocampo\"});\n        System.out.println(\"\\nDNI y su nombre y apellidos(Después de editar a una persona)\");\n        System.out.println(\"=================================\");\n\n        sortByDNI(identity).toList().forEach(person -> {\n            String[] name = person.getValue();\n            System.out.println(person.getKey() + \" --> \" + name[0] + \" \" + name[1] + \" \" + name[2]);\n        });\n\n\n        /*\n\n          DIFICULTAD EXTRA (opcional):\n          Crea una agenda de contactos por terminal.\n          - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n          - Cada contacto debe tener un nombre y un número de teléfono.\n          - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n            los datos necesarios para llevarla a cabo.\n          - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n            (o el número de dígitos que quieras)\n          - También se debe proponer una operación de finalización del programa.\n\n         */\n\n        int choice;\n\n        do{\n\n            System.out.println(\"\\nAGENDA PERSONAL, que desea hacer:\");\n            System.out.println(\"---------------------------------\");\n            System.out.println(\"1 - Agregar un contacto.\");\n            System.out.println(\"2 - Buscar contactos.\");\n            System.out.println(\"3 - Actualizar un contacto.\");\n            System.out.println(\"4 - Eliminar un contacto.\");\n            System.out.println(\"5 - Salir.\");\n            System.out.println(\"---------------------------------\");\n            System.out.print(\"Eleccion: \");\n\n\n            try {\n                choice = Integer.parseInt(scan.nextLine());\n\n                if(choice > 0 && choice < 6){\n                    options(choice);\n                }else{\n                    System.out.println(\"Selecciona un numero correcto.\");\n                }\n\n            } catch (NumberFormatException e) {\n                System.out.println(\"Introduzca un número.\");\n                choice = 0;\n            }\n\n        }while (choice != 5);\n\n    }\n\n    // Metodo para ordenar los meses del ArrayList\n    private static Stream<String> sortMonthsByName(ArrayList<String> months) {\n        return months.stream().sorted((o1, o2) -> o1.compareTo(o2));\n    }\n\n    // Metodo para ordenar el HashMap\n    public static Stream<Map.Entry<String, String[]>> sortByDNI(HashMap<String, String[]> persons) {\n        return persons.entrySet().stream().sorted((o1, o2) ->\n                o1.getKey().compareTo(o2.getKey()));\n\n    }\n\n    // EJERCICIO EXTRA\n    public static void options(int choice) {\n\n        switch (choice){\n            case 1:\n\n                addContact();\n                break;\n\n            case 2:\n\n                if(!contactList.isEmpty()){\n                    search();\n                }else{\n                    System.out.println(\"Añade un contacto primero.\");\n                }\n\n                break;\n\n            case 3:\n\n                if(!contactList.isEmpty()){\n                    editContact();\n                }else{\n                    System.out.println(\"Añade un contacto primero.\");\n                }\n\n                break;\n\n            case 4:\n\n                if(!contactList.isEmpty()){\n                    deleteContact();\n                }else{\n                    System.out.println(\"Añade un contacto primero.\");\n                }\n\n                break;\n\n            case 5:\n\n                System.out.println(\"SALIENDO...\");\n                break;\n        }\n\n\n    }\n\n    private static void addContact() {\n\n        int number = 0;\n        String name = \"\";\n        String checkNum = \"\";\n\n        do{\n            System.out.print(\"Introduce el número (9 digitos): \");\n\n            try {\n                number = Integer.parseInt(scan.nextLine());\n                checkNum = String.valueOf(number);\n                if(checkNum.length() != 9){\n                    System.out.println(\"Longitud incorrecta.\");\n\n                }else{\n                    if(contactList.containsKey(number)){\n                        System.out.println(\"Ese número ya existe.\");\n                    }else{\n                        System.out.print(\"Introduce el nombre del contacto: \");\n                        name = scan.nextLine();\n                    }\n\n                }\n            } catch (NumberFormatException e) {\n                System.out.println(\"Formato incorrecto.\");\n            }\n        }while(checkNum.length() != 9 || contactList.containsKey(number));\n\n        contactList.put(number, name);\n        System.out.println(\"Contacto guardado.\");\n    }\n\n    private static void search() {\n        int choice = 0;\n\n        do{\n            System.out.println(\"\\nBuscar por:\");\n            System.out.println(\"-----------\");\n            System.out.println(\"1 - Número.\");\n            System.out.println(\"2 - Nombre.\");\n            System.out.println(\"-----------\");\n            System.out.print(\"Respuesta: \");\n\n            try {\n                choice = Integer.parseInt(scan.nextLine());\n\n                if(choice == 1 || choice == 2){\n                    searchContact(choice);\n                }else{\n                    System.out.println(\"Elección incorrecta.\");\n                }\n\n            } catch (NumberFormatException e) {\n                System.out.println(\"Introduzca un número.\");\n            }\n        }while (choice != 1 && choice != 2);\n    }\n\n    private static void searchContact(int choice) {\n\n        int num;\n        String name;\n        if(choice == 1){\n            try {\n                System.out.print(\"Introduce el número o parte de él: \");\n                num = Integer.parseInt(scan.nextLine());\n                for (Map.Entry<Integer, String> contact: searchByNum(contactList, num).toList()){\n                    System.out.println(contact.getValue() + \" --> \" + contact.getKey());\n                }\n\n            } catch (NumberFormatException e) {\n                System.out.println(\"Formato incorrecto.\");\n            }\n        }else if (choice == 2) {\n            System.out.print(\"Introduce el nombre o parte de él: \");\n            name = scan.nextLine();\n            for (Map.Entry<Integer, String> contact: searchByName(contactList, name).toList()){\n                System.out.println(contact.getValue() + \" --> \" + contact.getKey());\n            }\n        }\n\n    }\n\n    private static Stream<Map.Entry<Integer, String>> searchByNum(HashMap<Integer, String> contacts, int numToSearch){\n\n        String num = String.valueOf(numToSearch);\n        return contacts.entrySet().stream().filter(\n                entry -> entry.getKey().toString().contains(num)\n        );\n\n    }\n\n    private static Stream<Map.Entry<Integer, String>> searchByName(HashMap<Integer, String> contacts, String nameToSearch){\n\n        return contacts.entrySet().stream().filter(\n                entry -> entry.getValue().toLowerCase().contains(nameToSearch.toLowerCase())\n        );\n\n    }\n\n    private static void deleteContact(){\n        int number = 0;\n        String checkNum = \"\";\n        do{\n            System.out.print(\"Introduce el número a eliminar: \");\n\n            try {\n                number = Integer.parseInt(scan.nextLine());\n                checkNum = String.valueOf(number);\n                if(checkNum.length() != 9){\n                    System.out.println(\"Longitud incorrecta.\");\n\n                }else{\n                    if(!contactList.containsKey(number)){\n                        System.out.println(\"Ese número no existe.\");\n                    }\n                }\n            } catch (NumberFormatException e) {\n                System.out.println(\"Formato incorrecto.\");\n            }\n        }while(checkNum.length() != 9 || !contactList.containsKey(number));\n\n        contactList.remove(number);\n        System.out.println(\"Contacto eliminado.\");\n    }\n\n    private static void editContact(){\n\n        System.out.println(\"LISTA DE CONTACTOS (\" + contactList.entrySet().stream().toList().size() + \" contactos)\");\n        System.out.println(\"=================================\");\n        for (Map.Entry<Integer, String> contact: contactList.entrySet().stream().toList()){\n            System.out.println(\" - \" + contact.getKey() + \" --> \" + contact.getValue());\n        }\n\n        int number = 0;\n        String checkNum = \"\";\n        do{\n            System.out.print(\"Introduce el número del contacto a editar: \");\n\n            try {\n                number = Integer.parseInt(scan.nextLine());\n                checkNum = String.valueOf(number);\n                if(checkNum.length() != 9){\n                    System.out.println(\"Longitud incorrecta.\");\n\n                }else{\n                    if(!contactList.containsKey(number)){\n                        System.out.println(\"Ese número no existe.\");\n                    }\n                }\n            } catch (NumberFormatException e) {\n                System.out.println(\"Formato incorrecto.\");\n            }\n        }while(checkNum.length() != 9 || !contactList.containsKey(number));\n\n        int choice = 0;\n\n        do{\n            System.out.println(\"\\n¿Qué quiere editar?\");\n            System.out.println(\"-------------------\");\n            System.out.println(\"1 - Número.\");\n            System.out.println(\"2 - Nombre.\");\n            System.out.println(\"-----------\");\n            System.out.print(\"Respuesta: \");\n\n            try {\n                choice = Integer.parseInt(scan.nextLine());\n\n                if(choice == 1){\n                    editNumber(number);\n                } else if (choice == 2) {\n                    editName(number);\n                } else{\n                    System.out.println(\"Elección incorrecta.\");\n                }\n\n            } catch (NumberFormatException e) {\n                System.out.println(\"Introduzca un número.\");\n            }\n        }while (choice != 1 && choice != 2);\n\n    }\n\n    private static void editName(int number) {\n\n        System.out.print(\"Introduzca un nombre nuevo: \");\n        String name = scan.nextLine();\n        contactList.put(number, name);\n        System.out.println(\"Contacto modificado.\");\n    }\n\n    private static void editNumber(int number) {\n\n        int newNumber = 0;\n        String name = \"\";\n        String checkNum = \"\";\n\n        do{\n            System.out.print(\"Introduce el nuevo número (9 digitos): \");\n\n            try {\n                newNumber = Integer.parseInt(scan.nextLine());\n                checkNum = String.valueOf(newNumber);\n                if(checkNum.length() != 9){\n                    System.out.println(\"Longitud incorrecta.\");\n\n                }else{\n                    if(contactList.containsKey(newNumber)){\n                        System.out.println(\"Ese numero ya existe.\");\n                    }\n\n                }\n            } catch (NumberFormatException e) {\n                System.out.println(\"Formato incorrecto.\");\n            }\n        }while(checkNum.length() != 9 || contactList.containsKey(newNumber));\n\n        name = contactList.get(number);\n        contactList.put(newNumber, name);\n        contactList.remove(number);\n\n        System.out.println(\"Contacto modificado.\");\n    }\n\n\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/Gerthai08.java",
    "content": "import java.util.*;\npublic class Gerthai08 {\n\n    //Map para almacenar los contactos (nombre -> número de teléfono)\n    private static Map<String, String> contacts = new HashMap<>();\n    private static final int maxPhoneNumbers = 11; //límite de dígitos\n\n    public static void main(String[] args) {\n\n        //ARRAYS\n        //Array de String\n        String[] arrayString = {\"Juan\", \"Pedro\", \"Esteban\"};\n        //Array de Números\n        int[] arrayNumber = {1, 2, 24, 37, 50};\n        //Modificando elemento de array\n        arrayNumber[0] = 3;\n        //Array de varios subindices\n        int[][] arraySubindices = {{1, 2, 3, 4, 5}, {6, 7, 8, 9, 0}};\n        //Acceder a una Array\n        System.out.println(\"=====Accediendo a Array=====\");\n        System.out.println(arrayNumber[4]);\n        System.out.println(arrayString[0]);\n        //Recorrer array\n        System.out.println(\"=====Recorriendo Array=====\");\n        for (int i : arrayNumber) {\n            System.out.println(i);\n        }\n        //Recorrer array subindices\n        System.out.println(\"=====Recorriendo Array Subindices=====\");\n        for (int i = 0; i < arraySubindices.length; i++) {\n            for (int j = 0; j < arraySubindices[i].length; j++) {\n                System.out.print(arraySubindices[i][j] + \" \");\n            }\n            System.out.println();\n        }\n\n        //LIST\n        //ArrayList\n        List<String> listaObjetos = new ArrayList<String>();\n        //Agregar elementos\n        listaObjetos.add(\"Guante\");\n        listaObjetos.add(\"Cartera\");\n        listaObjetos.add(\"Libro\");\n        //Acceder al elemento\n        System.out.println(\"=====Acceder a elementos de una ArrayList=====\");\n        System.out.println(listaObjetos.get(0)); //Accede al elemento \"Guante\"\n        //cambiar elemento\n        System.out.println(\"=====Se cambió el elemento de la ArrayList=====\");\n        listaObjetos.set(1,\"Celular\"); //El elemento \"Cartera\" ahora es \"Celular\"\n        System.out.println(listaObjetos.get(1));\n        //Tamaño de ArrayList\n        System.out.println(\"=====Tamaño de ArrayList=====\");\n        System.out.println(listaObjetos.size());\n        //Recorrer ArrayList\n        System.out.println(\"=====Recorriendo ArrayList =====\");\n        Collections.sort(listaObjetos); //Método para ordenar alfabéticamente\n        for(String i : listaObjetos){\n            System.out.println(i);\n        }\n        //Elimina un elemento de la lista\n        listaObjetos.remove(1); //se elimina el objeto celular\n        //Elimina todos los objetos de la lista\n        listaObjetos.clear();\n\n        //LinkedList\n        //Se comporta de la misma manera que ArrayList pero esta son \"Listas enlazadas\"\n        //Disponen de métodos que hacen mas eficientes la manipulación de las mismas\n        List<String> listaEnlazada = new LinkedList<String>();\n        //Agregar elementos\n        listaEnlazada.add(\"Juan\");\n        listaEnlazada.add(\"marcos\");\n        listaEnlazada.add(\"Pedro\");\n        //Agregar elemento al comienzo de la lista\n        listaEnlazada.addFirst(\"Nombre Primero\");\n        //Agregar elemento al final de la lista\n        listaEnlazada.addLast(\"Nombre Ultimo\");\n        //Traer elemento que está al Principio de la lista\n        System.out.println(\"=====Traer elemento que está al Principio de la LinkedList=====\");\n        System.out.println(listaEnlazada.getFirst());\n        //Traer elemento que está al Final de la lista\n        System.out.println(\"=====Traer elemento que está al Final de la LinkedList=====\");\n        System.out.println(listaEnlazada.getLast());\n        //Eliminar elemento que está al Principio de la lista\n        System.out.println(\"=====Eliminar elemento que está al Principio de la LinkedList=====\");\n        System.out.println(listaEnlazada.removeFirst());\n        //Eliminar elemento que está al Final de la lista\n        System.out.println(\"=====Eliminar elemento que está al Final de la LinkedList=====\");\n        System.out.println(listaEnlazada.removeLast());\n\n        //SET\n        //HashSet\n        //Instanciando el objeto HashSet (desordenado)\n        HashSet<String> listaHashSet = new HashSet<String>();\n        listaHashSet.add(\"Volvo\");\n        listaHashSet.add(\"BMW\");\n        listaHashSet.add(\"Ford\");\n        listaHashSet.add(\"BMW\");  // Duplicate\n        listaHashSet.add(\"Mazda\");\n        //Llamando a la lista\n        System.out.println(\"=====Llamando a la lista HashSet=====\");\n        System.out.println(listaHashSet);\n        //Comprobar si existe el elemento\n        System.out.println(\"=====Comprobando si existe el elemento HashSet=====\");\n        System.out.println(listaHashSet.contains(\"Ford\"));\n        //Eliminando un elemento\n        listaHashSet.remove(\"Ford\");\n        //Tamaño de HashSet\n        System.out.println(\"=====Tamaño de HashSet=====\");\n        System.out.println(listaHashSet.size());\n        //Eliminar todos los elementos\n        listaHashSet.clear();\n        //TreeSet (Conjunto ordenado)\n        //es lo mismo que hash pero con la condición entre parentecis\n        //LinkedHashSet (Ordenado por inserción)\n\n        //MAP\n        //HashMap\n        //Agregar elementos\n        HashMap<String,String> listHashMap = new HashMap<>();\n        listHashMap.put(\"England\", \"London\");\n        listHashMap.put(\"India\", \"New Dehli\");\n        listHashMap.put(\"Austria\", \"Wien\");\n        listHashMap.put(\"Norway\", \"Oslo\");\n        listHashMap.put(\"USA\", \"Washington DC\");\n        //Acceder a un elemento\n        System.out.println(\"=====Accediendo al elemento HashMap=====\");\n        System.out.println(listHashMap.get(\"England\"));\n        //Eliminar elemento\n        listHashMap.remove(\"England\");\n        //Tamaño de HashMap\n        System.out.println(\"=====Tamaño de HashMap=====\");\n        System.out.println(listHashMap.size());\n        //Recorrer HashMap\n        System.out.println(\"=====Recorrer HashMap por claves=====\");\n        for(String i : listHashMap.keySet()){\n            System.out.println(i);\n        }\n        System.out.println(\"=====Recorrer HashMap por valores=====\");\n        for(String i : listHashMap.values()){\n            System.out.println(i);\n        }\n        System.out.println(\"=====Recorrer HashMap por clave-valor=====\");\n        for(String i : listHashMap.keySet()){\n            System.out.println(\"key: \" + i + \"| value: \" + listHashMap.get(i));\n        }\n        //Treemap (ordenado por clave)\n        //LinkedHashMap (odenado por inserción)\n\n        extra();\n    }\n\n    public static void extra() {\n        Scanner scanner = new Scanner(System.in);\n        boolean running = true;\n\n        System.out.println(\"!bienvenido a la agenda de contactos¡\");\n\n        while (running) {\n            System.out.println(\"\\n¿Qué deseas hacer?\");\n            System.out.println(\"1. Insertar contacto\");\n            System.out.println(\"2. Buscar contacto\");\n            System.out.println(\"3. Actualizar contacto\");\n            System.out.println(\"4. Eliminar contacto\");\n            System.out.println(\"5. Mostrar todos los contactos\");\n            System.out.println(\"6. Salir\");\n            System.out.print(\"Selecciona una opción: \");\n\n            String option = scanner.nextLine();\n\n            switch (option){\n                case \"1\":\n                    insertContact(scanner);\n                    break;\n                case \"2\":\n                    seachContact(scanner);\n                    break;\n                case \"3\":\n                    updateContact(scanner);\n                    break;\n                case \"4\":\n                    deleteContact(scanner);\n                    break;\n                case \"5\":\n                    showAllContacts();\n                    break;\n                case \"6\":\n                    running = false;\n                    System.out.println(\"¡Hasta luego!\");\n                    break;\n                default:\n                    System.out.println(\"Opción no válida. Inténtalo de nuevo.\");\n            }\n        }\n        scanner.close();\n    }\n\n    //Metodo para insertar contacto\n    private static void insertContact(Scanner scanner){\n        String name = pedirDato(scanner,\"Introduzca el nombre del contacto: \");\n\n        if (contacts.containsKey(name)){\n            System.out.println(\"Este contacto ya existe.\");\n            return;\n        }\n\n            System.out.println(\"Introduzca el numero del contacto.\");\n            String phone = scanner.nextLine().trim();\n\n        if (isValidPhone(phone)){\n            contacts.put(name,phone);\n            System.out.println(\"Contacto agregado correctamente.\");\n        }else{\n            System.out.println(\"Número de teléfono no válido. Debe ser numérico y tener hasta \" + maxPhoneNumbers + \" dígitos.\");\n        }\n    }\n\n    //Metodo para buscar cotacto\n    private static void seachContact(Scanner scanner){\n        String name = pedirDato(scanner,\"Introduce el nombre del contacto a buscar: \");\n\n        if(contacts.containsKey(name)){\n            System.out.println(\"Contacto encontrado: \" + name + \" -> \" + contacts.get(name));\n        }else{\n            System.out.println(\"No se encontro ningun contacto con este nombre.\");\n        }\n    }\n\n    //Metodo para actualizar los contactos\n    private static void updateContact(Scanner scanner){\n        String name = pedirDato(scanner,\"Introduce el nombre del contacto a actualizar: \");\n\n        if (contacts.containsKey(name)){\n            System.out.println(\"Introduce el numero numero de teléfono: \");\n            String newPhone = scanner.nextLine().trim();\n\n            if (isValidPhone(newPhone)){\n                contacts.put(name,newPhone);\n                System.out.println(\"El contacto se actualizó correctamente.\");\n            }else{\n                System.out.println(\"El teléfono no es valido.\");\n            }\n        }else{\n            System.out.println(\"No se encontró ningún contacto con ese nombre.\");\n        }\n    }\n\n    //Metodo para eliminar un contacto\n    private static void deleteContact(Scanner scanner){\n        String name = pedirDato(scanner,\"Introduce el nombre del contacto a eliminar.\");\n\n        if (contacts.containsKey(name)){\n            contacts.remove(name);\n            System.out.println(\"Contacto eliminado correctamente.\");\n        }else{\n            System.out.println(\"No se encontró ningún contacto con ese .\");\n        }\n    }\n\n    //Metodo para mostrar todos los contactos\n    private static void showAllContacts(){\n        if(contacts.isEmpty()){\n            System.out.println(\"No hay contactos en la agenda.\");\n        }else{\n            System.out.println(\"Lista de contactos:\");\n            contacts.forEach((name,phone) -> System.out.println(name + \" -> \" + phone));\n        }\n    }\n\n    // Método para validar un número de teléfono\n    private static boolean isValidPhone(String phone){\n        return phone.matches(\"\\\\d{1,\" + maxPhoneNumbers + \"}\");\n    }\n\n    //Metodo para introducir texto informativo y asignar nombre a la variable scanner\n    private static String pedirDato(Scanner scanner, String mensaje){\n        System.out.println(mensaje);\n        return scanner.nextLine().trim();\n    }\n}"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/GlossyPath.java",
    "content": "/**\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * @version v1.0\n * \n * @since 20/06/2024\n * \n * @author GlossyPath\n * \n */\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.InputMismatchException;\nimport java.util.LinkedList;\nimport java.util.Queue;\nimport java.util.Scanner;\nimport java.util.Stack;\n \npublic class GlossyPath {\n\n    /*\n     * Arrays (también conocidos como vectores).\n     * Tenemos dos tipos de Arrays: los estáticos y los dinámicos.\n     * Los estáticos son aquellos Arrays en los que en su definición se especifica el número de elementos máximo que podrá almacenar la estructura de datos.\n     * A diferencia de los anteriores los dinámicos son aquellos Arrays en los que no se especifica un número máximo de elementos y es la máquina virtual de Java,\n     * quien se encarga por nosotros de gestionar la memoria de forma transparente.\n     * En ambos podemos utilizar tipos de datos primitivos como objetos.\n     */\n\n     /*\n      * Descripción: método para implementar las diferentes operaciones con Arrays estáticos.\n      */\n     public static void vectorStatic(){\n\n        char[] hola = {'h', 'o', 'l', 'a'}; //definimos los caracteres de los que esta compuesto el Array.\n        String[] isbn = new String[5]; // definimos el tamaño del Array (mediante la instanciación se reserva la memoria para poder almacenar los elementos deseados).\n\n        //Inserción\n            //Para insertar datos se hace de la siguiente manera.\n            //Los elementos en los Arrays tienen asociado un índice. Estos comienzan desde 0.\n            //Por lo tanto para insertar un elemento solamente tendremos que indicar su indice y el valor a introducir.\n            //Siempre se hace de la misma forma: nombreDelArray[indice] = valor;\n\n        isbn[0] = \"933-3-16-121410-0\";\n        isbn[1] = \"238-8-16-248110-2\";\n        isbn[2] = \"178-9-16-123410-0\";\n        isbn[3] = \"978-3-16-148410-3\";\n        isbn[4] = \"111-1-16-956789-0\";\n\n        //Actualización\n            //Para actualizar los datos se hace de la siguiente manera.\n            //De la misma manera que se hace con la inserción, debemos acceder al indice del elemento que queremos actualizar o modificar.\n            //Siempre se hace de la misma forma: nombreDelArray[indice] = nuevoValor;\n\n        System.out.println(\"Valor actual del Array con indice 0 es: \" + isbn[0]);\n\n        isbn[0] = \"999-3-99-999999-0\";\n        \n        System.out.println(\"Nuevo valor del Array con indice 0 es: \" + isbn[0]);\n\n        //Borrado\n            //En los Arrays estáticos no podemos variar su tamaño como tal una vez ha sido creado.\n            //Lo que si podemos hacer es reemplazar el valor del elemento con un valor predeterminado (como null para referencias de objetos, 0 para enteros, false para booleanos, etc.).\n            //De esta manera eliminamos el valor original.\n\n        hola[0] = '\\u0000'; //En los tipo char, de esta manera, el valor del elemento se establece en el carácter nulo.\n\n        //Ordenación.\n            //Para odenar los Arrays podemos utilizar la clase \"Arrays\" y uno de sus metodos, en concreto el método sort().\n            //Devemos importar la clase Arrays (import java.util.Arrays;).\n        \n        System.out.println(\"Array isbn sin ordenar sería como sigue:\");\n\n        for(int i= 0; i<isbn.length; i++){\n            System.out.println(isbn[i]);\n        }\n        System.out.println();\n\n        System.out.println(\"Ahora el Array isbn ordenado:\");\n\n        Arrays.sort(isbn); //Ordenamos el Array con el método sort\n\n        for(int i= 0; i<isbn.length; i++){\n            System.out.println(isbn[i]);\n        }\n     }\n\n\n\n     /*\n      * En JAVA como en otros lenguajes de programación también tenemos los Arrays multidimensionales (tablas o matrices), que son\n      * estructuras de datos que permiten almacenar elementos en un formato de filas y columnas, similar a una tabla. \n      * Cada elemento en un array multidimensional se accede usando dos índices: el índice de la fila y el índice de la columna.\n      * Su declaración sería como sigue: tipoDeDato[][] nombreDelArray = new tipoDeDato[tamañoArray/filas][tamañoArray/columnas];\n      */\n\n     /*\n      * Descripcion: método para implementar las diferentes operaciones con Arrays multidimensionales.\n      */\n      public static void arrayMultidimensional(){\n\n        //A la hora de declarar el Array se hace de la misma manera que con los estáticos.\n        int[][] matriz = {\n            {4, 2, 93},\n            {41, 25, 6},\n            {72, 8, 19}\n        };\n\n        char[][] sopaLetras = new char[5][5];\n\n        //Inserción, actualizacíon, borrado.\n            //Sigue la misma pauta que los Arrays estáticos, lo único que tenemos que tener en cuenta es la posición del segundo índice.\n\n\n        //Ordenación\n            //El método sort() de la clase Arrays no tiene soporte para los multidimensionales.\n            //En el caso de que sepamos como queremos ordenar cada filo o columna si que podriamos ordenarlas individualemnte.\n\n        System.out.println(\"\\nMostramos la matriz actual:\");\n\n        for(int i=0; i<matriz.length; i++){\n            for(int j=0; j<matriz[i].length; j++){\n                System.out.print(matriz[i][j] + \" \");\n            }\n            System.out.println();\n        }\n\n        System.out.println(\"\\nAhora la matriz ordenada:\");\n\n        for(int i=0; i<matriz.length; i++){\n            Arrays.sort(matriz[i]); //en este caso ordenamos solo las filas.\n        }\n\n        for(int i=0; i<matriz.length; i++){\n            for(int j=0; j<matriz[i].length; j++){\n                System.out.print(matriz[i][j] + \" \");\n            }\n            System.out.println();\n        }\n      }\n\n\n      /*\n       * Ahora pasemos a los Arrays dinámicos.\n       * Su principal ventaja es que se basan en memoria dinámica, podemos almacenar tantos elementos como queramos de los mismos.\n       * Los arrays dinámicos se implementan principalmente mediante la interfaz List y sus diversas implementaciones.\n       * Podemos almacenar cualquier tipo de Objeto pero es importante destacar que no se pueden almacenar tipos de datos primitivos.\n       */\n     \n\n     /*\n      * Descripción: método para implementar las diferentes operaciones con ArrayList.\n      */\n     public static void arrayList(){\n\n        //Los ArrayList tienen la siguiente estructura: ArrayList<String> miArrayList = new ArrayList<String>();\n\n        ArrayList <String> nombres = new ArrayList<>();\n\n        //Inserción\n            //Para insertar elementos utilizamos el método 'add'.\n        \n        nombres.add(\"Juan\");\n        nombres.add(\"Laura\");\n\n        //Borrado\n            //Para eliminar objetos del ArrayList tenemos que escribir la posición del elemento que queremos borrar.\n            //Utilizaremos el método 'remove'.\n        \n        nombres.remove(0);\n\n        nombres.clear();//vaciamos el ArrayList\n        \n        //Actualización\n            //Para actualizar objetos, insertaremos dos argumentos al metodo 'set' que serán el indice y el nuevo valor.\n\n        nombres.add(\"Juan\");\n        nombres.set(0, \"Pedro\");\n\n        //Ordenación\n            //Para ordenar objetos podriamos implementar la interfaz Comparable<T> en la clase que queramos comparar y en la misma implementar el método\n            //compareTo y ya en el main realizar la comparación con la clase Collections y su método sort().\n     }\n\n     /*\n      * Descripción: método para implemetar las diferentes operaciones con la clase Stack (pila).\n      */\n     public static void listaStack(){\n\n        //La clase Stact (conocido como pila) tiene la siguiente estructura: Stack(TipoDato) miStack = new Stack<tipoDato>();\n        //El comportamiento de la pila se conoce como LIFO (Last In, First Out), es decir, \n        //el último elemento que se añade será el primero en eliminarse/consultarse. \n\n        Stack <String> nombres = new Stack<String>();\n\n        //Inserción\n            //Para insertar elementos utilizamos el método 'push()'.\n\n        nombres.push(\"Paco\"); \n        nombres.push(\"Alexia\"); //vamos apilando uno encima de otro\n\n        //Borrado\n            //Para eliminar objetos utilizamos el método pop(), el cual elimina el elemento que esta en la cima de la pila\n        \n        nombres.pop(); // Alexia sería eliminado.\n\n        //Actualización\n            //En la clase Stack no disponemos de ningún método para actulizar un objeto mediante su indice.\n        \n     }\n\n     /*\n      * Descripción: método para implementar las diferentes operaciones con la interfaz Queue y la clase LinkdList.\n      */\n      public static void listaQueue(){\n\n        //La clase LinkedList la utilzamos en conjunto con la interfaz Queue para implementar las colas.\n        //Su estructura es la siguiente: Queue<tipoDato> miQueue = new LinkedList<tipoDato>();\n        //El comportamiento de la cola se conoce como FIFO (First in, First Out), es decir, \n        //el primer elemento que se añade será el primero en eliminarse/consultarse. \n\n        Queue<String> personas = new LinkedList<String>();\n\n        //Inserción\n            //Para insertar elementos utilizamos el método 'add'.\n\n        personas.add(\"Clara\");\n        personas.add(\"Lucas\");\n        personas.add(\"Jose\");\n\n\n        //Borrado\n            //Para eliminar objetos utilizamos el método remove(), el cual elimina el primer elemento que llegó a la cola.\n\n        personas.remove();\n\n        System.out.println();\n\n        while(!personas.isEmpty()){\n            System.out.println(\"Nombre: \" + personas.poll()); //también podemos utilizar el método poll() para eliminar la cabeza de la cola.\n        }\n\n        //Actualización\n            //En las colas en concreto con la interfaz Queue no disponemos de ningún método para actulizar un objeto mediante su indice.\n      }\n\n      /*\n       * En JAVA también disponemos de los conjuntos. Matemáticamente un conjunto es una colección no ordenada de elementos no repetidos. \n       * Por una parte, es no ordenada porque no podemos acceder a los elementos a través de un índice. \n       * Y por otra, no repetidos porque cada elemento del conjunto es único.\n       */\n\n       /*\n        * Descripción: método para implementar las diferentes operaciones con la clase HashSet.\n        */\n        public static void conjuntoHashSet(){\n\n            //La clase HashSet la utilzamos para implementar los conjuntos.\n            //Su estructura es la siguiente: HashSet<tipoDato> miHashSet = new HashSet<tipoDato>();\n\n            HashSet<String> direcciones = new HashSet<String>();\n\n            //Inserción\n                //Para insertar elementos utilizamos el método 'add'.\n\n                direcciones.add(\"calle macarron\");\n                direcciones.add(\"calle santón\");\n            \n            //Borrado\n                //Para eliminar objetos utilizamos el método remove(), el cual elimina el objeto que le digamos (si existe).\n            \n            direcciones.remove(\"calle macarron\");\n            direcciones.clear();//elimina todos los elementos del conjunto.\n\n        }\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * - Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n*/\n\n/* \n * Para la dificultad extra vamos a utilizar los diccionarios.\n * Los Diccionarios, al igual que las listas, los datos están indexados. \n * Sin embargo, sus índices (claves) pueden ser cualquier tipo de valor. \n * Por tanto, a los Diccionarios se les conoce como dato dinámico de tipo CLAVE-VALOR.\n */\n\n\n /*\n  * Descripción: enum para escoger opción del menu de selección.\n  */\n    public enum AccionesMenu{\n\n        B(\"Buscar contacto\"),\n        I(\"Insertar contacto\"),\n        A(\"Actualizar contacto\"),\n        E(\"Elimina contacto\"),\n        L(\"Listar contactos\"),\n        C(\"Contar\"),\n        S(\"Salir del menú\");\n\n        private final String valor;\n\n        private AccionesMenu(String valor){\n\n            this.valor = valor;\n        }\n\n        public String getValor(){\n\n            return this.valor;\n        }\n    }\n\n    /*\n     * Descripción: método para imprimir el menu\n     */\n    private static void imprimirMenu(){\n\n        Arrays.stream(AccionesMenu.values()).forEach(item ->System.out.println(String.format(\"(%s)%s\", item.name(), item.getValor().substring(1))));\n        System.out.print(\"Seleccione la inicial de la operación que quieres realizar: \");\n    }\n\n    /*\n     * Descripción: metodo para insertar contactos\n     */\n    public static void insertarContacto(HashMap<String, Integer> contactos){\n\n        Scanner sc = new Scanner(System.in);\n\n        String nombre;\n        boolean nombreNulo;\n        \n        Integer numTelefono = 0;\n\n        try{\n\n        do{\n\n            System.out.println(\"\\nIntroduce en nombre del contacto que quieres añadir: \");\n            nombre = sc.nextLine().toUpperCase();\n            nombreNulo = (nombre.isEmpty() || nombre.isBlank());\n            \n        } while(nombreNulo);\n        \n\n        do{\n\n            try{\n\n                System.out.println(\"\\nIntroduce el telefono del conctato que quieres añadir (tiene que tener 9 dígitos): \");\n                numTelefono = Integer.parseInt(sc.nextLine());\n\n            } catch(NumberFormatException e){\n                System.out.println(\"Error: Ingresa solo números para el teléfono y asegúrate de que tenga 9 dígitos.\");\n            }\n    \n        } while(numTelefono.toString().length() != 9);\n        \n\n        contactos.put(nombre, numTelefono); // utilizamos el método put() para añadir los elementos.\n        System.out.println(\"Contacto añadido correctamente.\");\n\n        } catch (InputMismatchException e){\n            System.out.println(\"Datos introducidos incorrectos\");\n            e.printStackTrace();\n        } \n    }\n\n    /*\n     * Descripción: método para buscar contactos.\n     */\n    public static void buscarContacto(HashMap<String, Integer> contactos){\n\n        Scanner sc = new Scanner(System.in);\n\n        String nombre;\n\n        if(contactos != null && !(contactos.isEmpty())){\n\n            System.out.println(\"\\nIntroduce el nombre del contacto que quieres buscar\");\n            nombre = sc.nextLine();\n\n            for(String s: contactos.keySet()){ // devuelve la clave de nuestro HashMap.\n                Integer telefono = contactos.get(s); // devuelve el valor de nuestro HashMap.\n                if(s.equals(nombre.toUpperCase())){\n                    System.out.println(\"Nombre: \" + s + \" \" + \"Telefono: \" + telefono);\n                } else {\n                    System.out.println(\"El contacto no esta en la lista\");\n                }\n            }\n\n        } else {\n            System.out.println(\"Lista no existe o esta vacia\");\n        } \n\n    }\n    /*\n     * Descripciópn: método para actulizar contactos.\n     */\n    public static void actualizarContacto(HashMap<String, Integer> contactos){\n\n        Scanner sc = new Scanner(System.in);\n\n        String nombre;\n\n        Integer nuevoTelefono;\n\n        if(contactos != null && !(contactos.isEmpty())){\n\n            System.out.println(\"\\nIntroduce el nombre del contacto que quieres actualizar: \");\n            nombre = sc.nextLine().toUpperCase();\n\n            if(contactos.containsKey(nombre)){\n\n                Integer telefono = contactos.get(nombre);\n                System.out.println(\"Nombre: \" + nombre + \" Teléfono: \" + telefono);\n                System.out.println(\"\\nIntroduce el nuevo teléfono:\");\n\n                try {\n                    nuevoTelefono = Integer.parseInt(sc.nextLine());\n\n                    if (nuevoTelefono.toString().length() != 9) {\n                        System.out.println(\"El número de teléfono debe tener 9 dígitos.\");\n                    } else {\n                        contactos.put(nombre, nuevoTelefono);\n                        System.out.println(\"El contacto ha sido actualizado.\");\n                    }\n                    \n                } catch (NumberFormatException e) {\n                    System.out.println(\"Entrada no válida. Por favor, introduce un número de teléfono válido.\");\n                }\n\n            } else {\n                System.out.println(\"El contacto no está en la lista.\");\n            }\n\n        } else {\n            System.out.println(\"La lista no existe o está vacía.\");\n        }\n    }\n    \n    /*\n     * Descripción: método para eliminar un contacto\n     */\n    public static void eliminarContacto(HashMap<String, Integer> contactos){\n\n        Scanner sc = new Scanner(System.in);\n\n        String nombre;\n\n        if(!contactos.isEmpty()){\n\n            try{\n\n                System.out.println(\"\\nIntroduce el nombre del contacto que quieres eliminar: \");\n                nombre = sc.nextLine().toUpperCase();\n\n                if(contactos.containsKey(nombre)) {\n                    contactos.remove(nombre);\n                    System.out.println(\"Contacto eliminado.\");\n\n                } else {\n                    System.out.println(\"El contacto no está en la lista.\");\n                }\n\n            } catch(InputMismatchException e){\n                System.out.println(\"Datos introducidos incorrectos, debes introducir un nombre valido.\");\n            }\n            \n\n        } else {\n            System.out.println(\"La lista no existe o está vacía.\");\n        }\n    }\n\n    /*\n     * Descripción: método para mostrar todos los contactos por terminal\n     */\n    public static void listarContactos(HashMap<String, Integer> contactos){\n\n        if(!contactos.isEmpty()){\n            for(String s: contactos.keySet()){\n                Integer numTelefono = contactos.get(s);\n                System.out.println(\"\\nNOMBRE: \" + s + \" TELÉFONO: \" + numTelefono);\n            }\n        } else {\n            System.out.println(\"La lista no existe o está vacía.\");\n        }\n    }\n\n    public static void contarContactos(HashMap<String, Integer> contactos){\n\n        int cantidadContactos = 0;\n\n        cantidadContactos = contactos.size();\n\n        System.out.println(\"La agenda tiene \" + cantidadContactos + \" contactos.\");\n    }\n    /*\n     * Descripción: meétodo main\n     */\n    public static void main(String[] args) {\n        \n        Scanner sc = new Scanner(System.in);\n\n        HashMap<String, Integer> contactos = new HashMap<>();\n        AccionesMenu accionesMenu = null;\n        String opcion;\n\n        do{\n            System.out.println(\"\\n---------MENU--------\");\n            imprimirMenu();\n            opcion = sc.nextLine(); //capturamos la entrada del usuario y lo guardamos en una variable.\n\n            try{\n\n                accionesMenu = AccionesMenu.valueOf(opcion.toUpperCase());\n\n                switch(accionesMenu){\n\n                    case B:\n                        buscarContacto(contactos);\n                        break;\n\n                    case I:\n                        insertarContacto(contactos);\n                        break;\n                    \n                    case A:\n                        actualizarContacto(contactos);\n                        break;\n                    \n                    case E:\n                        eliminarContacto(contactos);\n                        break;\n                    \n                    case L:\n                        listarContactos(contactos);\n                        break;\n                \n                    case C:\n                        contarContactos(contactos);\n                        break;\n                    \n                    case S:\n                        System.out.println(\"Salir del menú\");\n                        break;\n                }\n            } catch (IllegalArgumentException e){\n                System.out.println(\"Error al introducir la inicial de la operación a realizar\"); //aseguramos que el argumento pasado sea alguna constante del Enum.\n                e.printStackTrace();\n            }\n\n        }\n        while(accionesMenu != null && accionesMenu != AccionesMenu.S);\n\n        sc.close();\n\n     }\n}\n "
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/Guillermo-Munoz.java",
    "content": "import java.util.Arrays;\nimport java.util.ArrayList;\nimport java.util.HashSet;\nimport java.util.Set;\nimport java.util.TreeSet;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.TreeMap;\nimport java.util.PriorityQueue;\nimport java.util.Scanner;\nimport java.util.ArrayDeque;\n\npublic class GuillermoMunoz {\n    /*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\n\n    public static void main(String[] args) {\n\n        //========================================================================\n        // *************** Array ****************\n        // Un array es una estructura de datos que almacena elementos del mismo tipo en una posición contigua de memoria.\n        //========================================================================\n\n        System.out.println(\"------- ARRAY ------- \\n\");\n\n        int[] numeros = {4, 5, 1, 2, 3};\n        String[] colores = {\"Rojo\", \"Verde\", \"Azul\"};\n\n        // No se pueden insertar o eliminar elementos en un array, pero si se pueden actualizar\n        \n        // Actualización de un elemento\n        colores[1] = \"Amarillo\";\n        System.out.println(\"Actualización de un elemento: \" + colores[1]);\n\n        // Ordenación de un array\n        System.out.println(\"Ordenación de un array:\" + \" Antes: \" + Arrays.toString(numeros));\n        Arrays.sort(numeros);\n        System.out.println(\"Ordenación de un array:\" + \" Después: \" + Arrays.toString(numeros));\n\n        //========================================================================\n        // ************* ArrayList **************** \n        // ArrayList es una clase que implementa la interfaz List, y permite almacenar elementos de forma dinámica.\n        //=========================================================================\n\n        System.out.println(\"\\n------- ARRAYLIST ------- \\n\");\n\n        ArrayList<Integer> numerosList = new ArrayList<Integer>();\n\n        // Inserción de elementos\n        numerosList.add(10);\n        numerosList.add(20);\n        numerosList.add(30);\n        numerosList.add(55);\n        numerosList.add(88);\n\n        // Borrado de un elemento\n        numerosList.remove(3); // Elimina el elemento en la posición 3 (55)\n\n        // Actualización de un elemento\n        numerosList.set(2, 15);\n\n        // Ordenación de un ArrayList\n        System.out.println(\"Ordenación de un ArrayList:\" + \" Antes: \" + numerosList);\n        numerosList.sort(null); \n        System.out.println(\"Ordenación de un ArrayList:\" + \" Después: \" + numerosList);\n\n        //========================================================================\n        // ************* Array Multidimensionales **************** \n        // Un array multidimensional es un array que contiene otros arrays como elementos, permitiendo almacenar datos en múltiples dimensiones.\n        //=========================================================================\n\n\n        System.out.println(\"\\n------- ARRAY MULTIDIMENSIONAL ------- \\n\");\n\n        int[][] matriz = {\n            {1,2,3},\n            {4,5,6},\n            {7,8,9}\n        };\n\n        // Inserción de un elemento\n        matriz[0][0] = 10; // Inserta el valor 10 en la posición (0,0)\n\n        // Borrado de un elemento (no se puede eliminar un elemento de un array, pero se puede establecer a un valor específico)\n        matriz[1][1] = 0; // Establece el valor en la posición (1,1) a 0\n\n        // Actualización de un elemento\n        matriz[2][2] = 20; // Actualiza el valor en la posición (2,2) a 20\n\n        // Ordenación de un array multidimensional (no se puede ordenar directamente, pero se puede ordenar cada fila o columna por separado)\n       for ( int i = 0; i < matriz.length; i++){\n        System.out.println(Arrays.toString(matriz[i]));\n       }\n\n        for (int i = 0; i < matriz.length; i++) {\n            Arrays.sort(matriz[i]);\n        }{\n            System.out.println(\"Ordenación de un array multidimensional:\" + \" Después: \");\n            for (int i = 0; i < matriz.length; i++) {\n                System.out.println(Arrays.toString(matriz[i]));\n            }\n        }\n\n        //========================================================================\n        // ************* HashSet **************** \n        // HashSet es una clase que implementa la interfaz Set, y permite almacenar elementos únicos de forma no ordenada.\n        //=========================================================================\n\n        System.out.println(\"\\n------- HASHSET ------- \\n\");\n\n        HashSet<String> coloresSet = new HashSet<String>();\n\n        //Inserción de elementos\n        coloresSet.add(\"rojo\");\n        coloresSet.add(\"verde\");\n        coloresSet.add(\"amarillo\");\n        coloresSet.add(\"negro\");\n        coloresSet.add(\"blanco\");\n        coloresSet.add(\"rojo\"); // No se añadirá porque ya existe\n        coloresSet.add(\"morado\"); \n\n        //Borrado de un elemento\n        coloresSet.remove(\"negro\");\n\n        //Actualización de un elemento (no se puede actualizar directamente, pero se puede eliminar el elemento antiguo y agregar el nuevo)\n        \n        // Ordenación de un HashSet (no se puede ordenar directamente, pero se puede convertir a un TreeSet y ordenar esa lista)\n\n        Set<String> coloresOrdenados = new TreeSet<>(coloresSet);\n        System.out.println(\"Ordenación de un HashSet:\" + \" Antes: \" + coloresSet);\n        System.out.println(\"Ordenación de un HashSet:\" + \" Después: \" + coloresOrdenados);\n\n\n        //========================================================================\n        // ************* HashMap **************** \n        // HashMap es una clase que implementa la interfaz Map, y permite almacenar pares clave-valor.\n        //=========================================================================\n\n        System.out.println(\"\\n------- HASHMAP ------- \\n\");\n\n        HashMap<String, String> contactos = new HashMap<String, String>();\n\n        //Inserción de elementos\n        contactos.put(\"Juan\", \"123456789\");\n        contactos.put(\"María\", \"987654321\");\n        contactos.put(\"Pedro\", \"555555555\");\n        contactos.put(\"Ana\", \"111111111\");\n\n        //Borrado de un elemento\n        contactos.remove(\"Pedro\");\n\n        //Actualización de un elemento\n        contactos.put(\"Juan\", \"999999999\");\n\n        // Ordenación de un HashMap (no se puede ordenar directamente, pero se puede convertir a un TreeMap y ordenar esa lista)\n        Map<String, String> contactosOrdenados = new TreeMap<>(contactos);\n        System.out.println(\"Ordenación de un HashMap:\" + \" Antes: \" + contactos);\n        System.out.println(\"Ordenación de un HashMap:\" + \" Después: \" + contactosOrdenados);\n\n        //========================================================================\n        // ************* PriorityQueue **************** \n        // PriorityQueue es una clase que implementa la interfaz Queue, y permite almacenar elementos de forma ordenada según su prioridad.\n        //=========================================================================\n\n        System.out.println(\"\\n------- PRIORITYQUEUE ------- \\n\");\n\n        PriorityQueue<Integer> colaPrioridad = new PriorityQueue<Integer>();\n\n        //Inserción de elementos\n        colaPrioridad.add(5);\n        colaPrioridad.add(2);\n        colaPrioridad.add(8);\n        colaPrioridad.add(1);\n        colaPrioridad.add(3) ;\n\n        //Borrado de un elemento (elimina el elemento con mayor prioridad, que en este caso es el número más pequeño)  \n        colaPrioridad.poll(); // Elimina el elemento con menor valor (prioridad más alta)\n        System.out.println(\"Cola de prioridad: \" + colaPrioridad);\n\n        //Actualización de un elemento (no se puede actualizar directamente, pero se puede eliminar el elemento antiguo y agregar el nuevo)\n        colaPrioridad.remove(3); // Elimina el elemento 3\n        colaPrioridad.add(4); // Agrega el nuevo elemento 4\n        System.out.println(\"Cola de prioridad después de la actualización: \" + colaPrioridad);\n\n        // Ordenación de una PriorityQueue (la cola de prioridad ya mantiene los elementos ordenados según su prioridad, por lo que no es necesario ordenarla manualmente)\n        System.out.println(\"Cola de prioridad ordenada: \" + colaPrioridad);\n\n        //========================================================================\n        // ************* ArrayDeque **************** \n        // ArrayDeque es una clase que implementa la interfaz Deque, y permite almacenar elementos de forma dinámica en ambos extremos de la cola.\n        //=========================================================================\n\n        System.out.println(\"\\n------- ARRAYDEQUE ------- \\n\");\n\n        ArrayDeque<Integer> colaArray = new ArrayDeque<Integer>();\n\n        //Inserción de elementos\n        colaArray.add(5);\n        colaArray.add(2);\n        colaArray.add(8);\n        colaArray.add(1);\n        colaArray.add(3) ;\n\n        //Borrado de un elemento (elimina el primer elemento de la cola)\n        colaArray.pollFirst(); // Elimina el primer elemento\n        System.out.println(\"Cola ArrayDeque: \" + colaArray);\n\n        //Actualización de un elemento (no se puede actualizar directamente, pero se puede eliminar el elemento antiguo y agregar el nuevo)\n        colaArray.remove(3); // Elimina el elemento 3\n        colaArray.addLast(4); // Agrega el nuevo elemento 4 al final de la cola\n        System.out.println(\"Cola ArrayDeque después de la actualización: \" + colaArray);\n\n    \n\n         /*\n * EJERCICIO:\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\nejecutarAgenda();\n             \n}\n\n //========================================================================\n        // ************* EJERCICIO **************** \n        // Crea una agenda de contactos por terminal.\n        //=========================================================================\n          // Constantes de color\n        public static final String RESET = \"\\u001B[0m\";\n        public static final String VERDE = \"\\u001B[32m\";\n        public static final String VERDE_CLARO = \"\\u001B[92m\";\n        public static final String AMARILLO = \"\\u001B[33m\";\n        public static final String CYAN = \"\\u001B[36m\";\n\n        public static void ejecutarAgenda() {\n            \n                // Aquí iría la lógica para manejar las opciones del menú y realizar las operaciones correspondientes\n                HashMap<String, String> agenda = new HashMap<String, String>(); // Esta estructura de datos se utilizaría para almacenar los contactos de la agenda\n                int opcion = 0; // Esta variable se actualizaría con la opción seleccionada por el usuario\n                // Ejemplo de manejo de opciones (esto es solo un esquema, no es funcional)\n                Scanner scanner = new Scanner(System.in);\n                do{ // Mientras la opción no sea la de salir\n                     mostrarMenu();\n                     opcion = scanner.nextInt(); // Leer la opción seleccionada por el usuario\n                     scanner.nextLine(); // Limpiar el buffer después de leer un número\n                switch (opcion) {\n                 \n\n                    case 1:\n                        System.out.println(VERDE + \"Inserta un nombre de contacto.\" + RESET);\n                        String nombre = scanner.nextLine(); // Leer el nombre del contacto\n                        System.out.println(VERDE + \"Inserta un número de teléfono.\" + RESET);\n                        String telefono = scanner.nextLine(); // Leer el número de teléfono del contacto\n                        // Validar el número de teléfono (debe ser numérico y tener un máximo de 11 dígitos)\n                        if(telefono.matches(\"\\\\d{1,11}\")) {\n                            // Lógica para insertar el contacto en la agenda\n                            System.out.println(VERDE + \"Contacto insertado: \" + nombre + \" - \" + telefono + RESET);\n                            agenda.put(nombre,  telefono); // Insertar el contacto en la agenda\n\n                        } else {\n                            System.out.println(AMARILLO + \"Número de teléfono no válido. Debe ser numérico y tener un máximo de 11 dígitos.\" + RESET);\n                        }\n                        break;\n                    case 2:\n                        System.out.println(VERDE + \"Inserta el nombre del contacto que deseas buscar.\" + RESET);\n                        String nombreBusqueda = scanner.nextLine(); // Leer el nombre del contacto a buscar\n                        // Lógica para buscar el contacto en la agenda\n                        if(agenda.containsKey(nombreBusqueda)){\n                            System.out.println(VERDE + \"Contacto encontrado: \" + nombreBusqueda + \" - \" + agenda.get(nombreBusqueda) + RESET);\n                        } else {\n                            System.out.println(AMARILLO + \"Contacto no encontrado.\" + RESET);\n                        }\n                        break;\n                    case 3:\n                        System.out.println(VERDE + \"Inserta el nombre del contacto que deseas actualizar.\" + RESET);\n                        String nombreActualizacion = scanner.nextLine(); // Leer el nombre del contacto a actualizar\n                        if(agenda.containsKey(nombreActualizacion)){\n                            System.out.println(VERDE + \"Inserta el nuevo número de teléfono.\" + RESET);\n                            String nuevoTelefono = scanner.nextLine(); // Leer el nuevo número de teléfono\n                            agenda.put(nombreActualizacion, nuevoTelefono); // Actualizar el contacto en la agenda\n                            System.out.println(VERDE + \"Contacto actualizado: \" + nombreActualizacion + \" - \" + nuevoTelefono + RESET);\n                        } else {\n                            System.out.println(AMARILLO + \"Contacto no encontrado.\" + RESET);\n                        }\n                        break;\n                    case 4:\n                        System.out.println(VERDE + \"Inserta el nombre del contacto que deseas eliminar.\" + RESET);\n                        String nombreEliminar = scanner.nextLine(); // Leer el nombre del contacto a eliminar\n                        if(agenda.containsKey(nombreEliminar)){\n                            agenda.remove(nombreEliminar); // Eliminar el contacto de la agenda\n                            System.out.println(VERDE + \"Contacto eliminado: \" + nombreEliminar + RESET);   \n                        } else {\n                            System.out.println(AMARILLO + \"Contacto no encontrado.\" + RESET);\n                        }\n                        break;\n                    case 5:\n                        System.out.println(VERDE + \"Mostrando todos los contactos:\" + RESET);\n                        agenda.entrySet().stream()\n                        .forEach(contacto -> System.out.println(\">\" + contacto.getKey() + \": \"+\n                            CYAN + contacto.getValue() + RESET\n                        ));\n                        break;\n                    case 6:\n                        // Lógica para salir del programa\n                        System.out.println(VERDE + \"¡Gracias por usar la agenda de contactos!\" + RESET);\n                        break;\n                    default:\n                        System.out.println(AMARILLO + \"Opción no válida. Por favor, selecciona una opción del menú.\" + RESET);\n                }\n\n                //Cerrar el scanner al finalizar el programa\n                \n            }while(opcion != 6);\n            scanner.close();\n      \n        \n      \n        }\n          public static void mostrarMenu() {\n            // Borde superior en verde claro\n            System.out.println(VERDE_CLARO + \"╔════════════════════════════╗\" + RESET);\n            \n            // Título en amarillo\n            System.out.println(AMARILLO + \"║    AGENDA DE CONTACTOS     ║\" + RESET);\n            \n            // Línea divisoria en verde claro\n            System.out.println(VERDE_CLARO + \"╠════════════════════════════╣\" + RESET);\n            \n            // Opciones en verde normal\n            System.out.println(VERDE + \"║ 1. Insertar contacto       ║\" + RESET);\n            System.out.println(VERDE + \"║ 2. Buscar contacto         ║\" + RESET);\n            System.out.println(VERDE + \"║ 3. Actualizar contacto     ║\" + RESET);\n            System.out.println(VERDE + \"║ 4. Eliminar contacto       ║\" + RESET);\n            System.out.println(VERDE + \"║ 5. Mostrar todos           ║\" + RESET);\n            \n            // Opción salir en color diferente\n            System.out.println(CYAN + \"║ 6. Salir                   ║\" + RESET);\n            \n            // Borde inferior en verde claro\n            System.out.println(VERDE_CLARO + \"╚════════════════════════════╝\" + RESET);\n            \n            // Prompt en verde\n            System.out.print(VERDE + \"Selecciona una opción: \" + RESET);\n        }\n      \n\n}\n\n         \n \n\n        \n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/GustavoGomez19.java",
    "content": "import java.util.ArrayDeque;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.Deque;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.PriorityQueue;\nimport java.util.Queue;\nimport java.util.Scanner;\nimport java.util.Set;\nimport java.util.TreeMap;\nimport java.util.TreeSet;\n\nclass GustavoGomez192 {\n    public static void main(String[] args) {\n        // Punto 1: Ejemplos de las estructuras de datos en Java\n        // Arrays: Conjuntos ordenados del mismo tipo de datos\n        Integer[] numeros = new Integer[5];\n        // Punto 2: operaciones de inserción, borrado, actualización y ordenación.\n        // INSERCIÓN\n        numeros[0] = 1;\n        numeros[1] = 2;\n        numeros[2] = 3;\n        numeros[3] = 4;\n        numeros[4] = 5;\n        for (int i = 0; i < numeros.length; i++) {\n            System.out.println(numeros[i]);\n        }\n        System.out.println();\n        // BORRADO\n        int indiceEliminar = 1;\n        // Se marca la posición como null para \"eliminar\"\n        numeros[indiceEliminar] = null;\n        for (int i = 0; i < numeros.length; i++) {\n            System.out.println(numeros[i]);\n        }\n        System.out.println();\n        // ACTUALIZACIÓN\n        numeros[4] = 10;\n        for (int i = 0; i < numeros.length; i++) {\n            System.out.println(numeros[i]);\n        }\n        // ORDENACIÓN\n        int[] ordenarArrays = { 20, 10, 50, 60, 40 };\n        // se imprime el arreglo desordenado\n        for (int i = 0; i < ordenarArrays.length; i++) {\n            System.out.println(\"Números\" + ordenarArrays[i]);\n        }\n        System.out.println();\n        // se imprime el arreglo ordenado\n        Arrays.sort(ordenarArrays);\n        for (int i = 0; i < ordenarArrays.length; i++) {\n            System.out.println(\"Números\" + ordenarArrays[i]);\n        }\n        System.out.println();\n\n        // Punto 1: Ejemplos de las estructuras de datos en Java\n        /*\n         * Listas (lists): Las listas pueden crecer o decrecer dinámicamente\n         * Se implementan por la clases en el paquete 'java.util' como 'arrayLists'\n         * y 'linkedList'\n         */\n        List<String> nombres = new ArrayList<String>();\n        // Punto 2: operaciones de inserción, borrado, actualización y ordenación.\n        // INSERCIÓN\n        nombres.add(\"Gustavo\");\n        nombres.add(\"Katerine\");\n        System.out.println(nombres);\n        System.out.println(\"Tamaño de la lista antes de borrar un elemento: \" + nombres.size());\n        // BORRADO\n        nombres.remove(0);\n        System.out.println(nombres);\n        System.out.println(\"Tamaño de la lista despues de borrar un elemento : \" + nombres.size());\n        // ACTUALIZACIÓN\n        System.out.println(\"Lista antes de actualizar un elemento : \" + nombres);\n        nombres.set(0, \"María José\");\n        System.out.println(\"Lista después de actualizar un elemento : \" + nombres);\n        // ORDENACIÓN\n        List<Integer> ordenarLista = new ArrayList<Integer>();\n        ordenarLista.add(50);\n        ordenarLista.add(21);\n        ordenarLista.add(105);\n        ordenarLista.add(10);\n        System.out.println(\"Lista desordenada: \" + ordenarLista);\n        Collections.sort(ordenarLista);\n        System.out.println(\"Lista ordenada: \" + ordenarLista);\n\n        // Punto 1: Ejemplos de las estructuras de datos en Java\n        /*\n         * Queue (colas): Son interfaces que se extienden de la interfaz 'Collection'\n         * Proporcionan métodos especificos para manipular los elementos.\n         * 'linkedList' puede utilizarse como una Queue\n         */\n        Queue<String> apellidos = new LinkedList<>();\n        // Punto 2: operaciones de inserción, borrado, actualización y ordenación.\n        // INSERCIÓN\n        apellidos.add(\"Gómez\");\n        apellidos.add(\"Gil\");\n        apellidos.add(\"Quiñones\");\n        apellidos.add(\"Marin\");\n        apellidos.offer(\"Ardila\");\n        System.out.println(apellidos);\n        // BORRADO\n        apellidos.remove(\"Marin\");\n        System.out.println(apellidos);\n        System.out.println();\n        /*\n         * ACTUALIZACIÓN. Para actualizar un cola no se hace directamente en la cola\n         * por motivo de que está diseñadas para trabajar con la lógia FIFO, una forma\n         * de actualizar un valor es creando una lista enlazada 'LinkedList'\n         */\n        System.out.println(\"Cola antes de actualizar: \" + apellidos);\n        LinkedList<String> listaTemporal = new LinkedList<>(apellidos);\n        // Actualizar el valor\n        listaTemporal.set(1, \"Villa\");\n        apellidos.clear();\n        apellidos.addAll(listaTemporal);\n        System.out.println(\"Cola después de actualizar: \" + apellidos);\n        /*\n         * ORDENACIÓN. Para ordenar los datos de una cola no se hace directamente en la\n         * cola\n         * por motivo de que está diseñadas para trabajar con la lógia FIFO, una forma\n         * de ordenar los valores es creando una lista enlazada 'LinkedList'\n         */\n        System.out.println();\n        Queue<Integer> ordenarCola = new LinkedList<>();\n        ordenarCola.add(50);\n        ordenarCola.add(10);\n        ordenarCola.add(30);\n        ordenarCola.add(5);\n        System.out.println(\"Cola antes de ordenar: \" + ordenarCola);\n        // Ordenar cola\n        List<Integer> ordenar = new LinkedList<>(ordenarCola);\n        ordenarCola.clear();\n        Collections.sort(ordenar);\n        ordenarCola.addAll(ordenar);\n        System.out.println(\"Cola después de ordenar: \" + ordenarCola);\n\n        // Punto 1: Ejemplos de las estructuras de datos en Java\n        /*\n         * Conjuntos (set): Son interfaces que se extienden de 'Collection'\n         * Representan conjuntos de elementos unicos, pueden ser 'HashSet' y 'TreeSet'\n         */\n        Set<String> animales = new HashSet<String>();\n        System.out.println();\n        // Punto 2: operaciones de inserción, borrado, actualización y ordenación.\n        // INSERCIÓN\n        animales.add(\"Perro\");\n        animales.add(\"Gato\");\n        animales.add(\"Tigre\");\n        animales.add(\"Lobo\");\n        System.out.println(\"Inserción: \" + animales);\n        // BORRADO\n        animales.remove(\"Gato\");\n        System.out.println(\"Borrado\" + animales);\n        // ACTUALIZACIÓN --> para actualizar un dato se realizan los pasos de 'remove' y\n        // 'add'\n        System.out.println(\"Antes de actualizar: \" + animales);\n        animales.remove(\"Lobo\");\n        animales.add(\"Zorro\");\n        System.out.println(\"Despué de actualizar: \" + animales);\n        // ORDENACIÓN --> para ordenar un HasHSet se debe convertir a una lista\n        Set<Integer> oredenarHashSet = new HashSet<>();\n        oredenarHashSet.add(50);\n        oredenarHashSet.add(10);\n        oredenarHashSet.add(30);\n        oredenarHashSet.add(5);\n        System.out.println(\"Antes de ordenar: \" + oredenarHashSet);\n        // Se convierte el 'HashSet' en lista\n        List<Integer> hashSetOrdenado = new ArrayList<>(oredenarHashSet);\n        Collections.sort(hashSetOrdenado);\n        System.out.println(\"Después de ordenar: \" + hashSetOrdenado);\n        System.out.println();\n\n        // Punto 1: Ejemplos de las estructuras de datos en Java\n        Set<String> mascotas = new TreeSet<String>();\n        // Punto 2: operaciones de inserción, borrado, actualización y ordenación.\n        // INSERCIÓN\n        mascotas.add(\"Roko\");\n        mascotas.add(\"Gael\");\n        mascotas.add(\"Raymond\");\n        mascotas.add(\"Benji\");\n        System.out.println(\"Inserción: \" + mascotas);\n        // BORRADO\n        mascotas.remove(\"Raymond\");\n        System.out.println(\"Borrado: \" + mascotas);\n        // ACTUALIZACIÓN\n        System.out.println(\"Antes de actualizar: \" + mascotas);\n        mascotas.remove(\"Gael\");\n        mascotas.add(\"Larry\");\n        System.out.println(\"Después de actualizar: \" + mascotas);\n        // ORDENACIÓN\n        Set<String> treeSetOrdenado = new TreeSet<>(Comparator.comparing(String::length));\n        treeSetOrdenado.add(\"Gustavo\");\n        treeSetOrdenado.add(\"María\");\n        treeSetOrdenado.add(\"Katerine\");\n        treeSetOrdenado.add(\"José\");\n        System.out.println(\"Ordenado con base a la longitud de cada String: \" + treeSetOrdenado);\n\n        /*\n         * Mapas (Maps): Interfaces que representan asociaciones clave - valor\n         * Pueden ser 'HashMap' y 'TreeMap'\n         */\n        Map<String, Integer> razas = new HashMap<>();\n        Map<String, Integer> carros = new TreeMap<>();\n\n        /*\n         * Pilas (Stacks): La clase 'Stack' es una subclase de 'vector' que implementa\n         * una pila\n         * Se pueden implementar con el uso de 'Deque'\n         */\n        Deque<String> pila = new ArrayDeque<>();\n\n        /*\n         * Colas de prioridad (Priority Queues): Son implementadas por la interfaz\n         * 'PriorityQueue'\n         * Representan colas donde elementos tiene una proridad asociada.\n         */\n        PriorityQueue<Integer> priority = new PriorityQueue<>();\n\n        /*\n         * Deques (Double-Ended Queues): Son onterfaces que extiendne de la interfaz\n         * 'Queue'\n         * Permiten la manipulación de elementos desde ambos extremos 'ArrayDeque' es\n         * una\n         * implementación muy común\n         */\n        Deque<String> deque = new ArrayDeque<>();\n\n        // Dificultad extra\n        System.out.println(\"----------------------------------------------\");\n        System.out.println(\"** AGENDA ELECTRÓNICA **\");\n        Scanner name = new Scanner(System.in);\n        Scanner number = new Scanner(System.in);\n        Scanner option = new Scanner(System.in);\n        Scanner buscar = new Scanner(System.in);\n        Scanner actualizar = new Scanner(System.in);\n        Scanner actualizarNum = new Scanner(System.in);\n\n        Map<String, Long> agenda = new HashMap<>();\n        // List<Long> numContacto = new ArrayList<>();\n        System.out.println(\"Seleccione una opción: \" + \"\\n\" +\n                \"-----+-----+-----+-----+\" + \"\\n\" +\n                \"1. Agregar contacto\" + \"\\n\" +\n                \"2. Buscar contacto\" + \"\\n\" +\n                \"3. Actualizar contacto\" + \"\\n\" +\n                \"4. Borrar contacto\" + \"\\n\" +\n                \"5. Salir\" + \"\\n\" +\n                \"-----+-----+-----+-----+\");\n\n        int opcion = option.nextInt();\n\n        while (opcion != 5) {\n            if (opcion == 1) {\n                System.out.print(\"Ingrese el nombre del contacto: \");\n                String nombre = name.nextLine();\n                System.out.print(\"Ingrese el número del contacto: \");\n                Long numero = number.nextLong();\n                agenda.put(nombre, numero);\n                System.out.println(\"Agenda\" + agenda);\n                System.out.println(\"-----*-----*-----*-----*-----\");\n            } else if (opcion == 2) {\n                System.out.print(\"Ingrese el nombre del contacto a buscar: \");\n                String buscarNombre = buscar.nextLine();\n                Long numberFind = agenda.get(buscarNombre);\n                if (numberFind != null) {\n                    System.out.println(\"Resultado de la búsqueda: \");\n                    System.out.println(\"Nombre: \" + buscarNombre + \"\\n\" + \"Número: \" + numberFind);\n                } else {\n                    System.out.println(\"Resultado de la búsqueda: \");\n                    System.out.println(\"El nombre ingresado no está en la agenda de contactos.\");\n                }\n                System.out.println();\n            } else if (opcion == 3) {\n                System.out.print(\"Ingrese el nombre del contacto a actualizar: \");\n                String actualizarContacto = actualizar.nextLine();\n                System.out.print(\"Ingrese el nuevo núnero: \");\n                Long nuevoNumero = actualizarNum.nextLong();\n                agenda.put(actualizarContacto, nuevoNumero);\n                System.out.println(\"Contacto actualizado.\" + actualizarContacto);\n                System.out.println(\"Agenda\" + agenda);\n                System.out.println(\"-----*-----*-----*-----*-----\");\n            } else if (opcion == 4) {\n                System.out.print(\"Ingrese el nombre del contacto a elimina: \");\n                String eliminarContaco = actualizar.nextLine();\n                agenda.remove(eliminarContaco);\n                System.out.println(\"Contacto elimina: \" + eliminarContaco);\n                System.out.println(\"Agenda\" + agenda);\n                System.out.println(\"-----*-----*-----*-----*-----\");\n            } else if (opcion > 5) {\n                System.out.println(\"Opción no valida. Intente de nuevo\");\n                System.out.println(\"-----*-----*-----*-----*-----\");\n            }\n            System.out.println(\"Seleccione una opción: \" + \"\\n\" +\n                    \"-----+-----+-----+-----+\" + \"\\n\" +\n                    \"1. Agregar contacto\" + \"\\n\" +\n                    \"2. Buscar contacto\" + \"\\n\" +\n                    \"3. Actualizar contacto\" + \"\\n\" +\n                    \"4. Borrar contacto\" + \"\\n\" +\n                    \"5. Salir\" + \"\\n\" +\n                    \"-----+-----+-----+-----+\");\n\n            opcion = option.nextInt();\n\n        }\n        System.out.println(\"-----*-----*-----*-----*-----\");\n        System.out.println(\"Contactos registrados en la agenda\" + \"\\n\" +\n                agenda);\n\n    }\n}"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/Jeigar2.java",
    "content": "import java.util.*;\n\npublic class Jeigar2 {\n    /*\n     * EJERCICIO:\n     * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n     * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n     *\n     * DIFICULTAD EXTRA (opcional):\n     * Crea una agenda de contactos por terminal.\n     * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n     * - Cada contacto debe tener un nombre y un número de teléfono.\n     * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n     *   los datos necesarios para llevarla a cabo.\n     * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n     *   (o el número de dígitos que quieras)\n     * - También se debe proponer una operación de finalización del programa.\n     */\n\n    public enum Acciones {\n        B(\"Buscar\"),\n        I(\"Insertar\"),\n        A(\"Actualizar\"),\n        E(\"Eliminar\"),\n        L(\"Listar\"),\n        C(\"Contar\"),\n        S(\"Salir\");\n\n        private final String valor;\n\n        Acciones(String valor) {\n            this.valor = valor;\n        }\n\n        public String getValor() {\n            return valor;\n        }\n    }\n\n    public enum Datos {\n        N(\"Nombre\"),\n        T(\"Teléfono\"),\n        A(\"Ambos\"),\n        S(\"Salir\");\n\n        private final String valor;\n\n        Datos(String valor) {\n            this.valor = valor;\n        }\n\n        public String getValor() {\n            return valor;\n        }\n    }\n\n    // Se decide que la colección sea un HashMap\n    // Se guarda como key el nombre y luego el teléfono, existiendo el contacto duplicado\n    // Ventaja, es muy rápido buscar por ambos atributos: nombre, teléfono\n    // Desventaja, al actualizar hay que borrar ambos elementos y volver a insertar.\n    //   si hay un error no hay transaccionalidad, por lo que puede que esto de errores al contar o buscar o listar\n    //   TODO: Al borrar si da error, hay que revisar donde ha dado el error y ver como recuperar la coherencia\n    private HashMap<String, Jeigar2Contacto> contactos;\n\n    public static void main(String[] args) {\n        Jeigar2 app = new Jeigar2();\n        app.iniciar();\n    }\n\n    public void iniciar(){\n        contactos =  new HashMap();\n        String opcion;\n        Acciones accion = null;\n        // Nota: Solo se puede cerrar el Scanner una vez, aunque se use en muchos sitios\n        Scanner scanner = new Scanner(System.in);\n        do {\n            imprimirMenu();\n            opcion = scanner.next();\n            try {\n                accion = Acciones.valueOf(opcion.toUpperCase()); // Paso a Mayúsculas\n                switch (accion) {\n                    case B:\n                         buscarContacto();\n                        break;\n                    case I:\n                        insertarContacto();\n                        break;\n                    case A:\n                        actualizarContacto();\n                        break;\n                    case E:\n                        eliminarContacto();\n                        break;\n                    case C:\n                        contarContactos();\n                        break;\n                    case L:\n                        listarContactos();\n                        break;\n                }\n            } catch (IllegalArgumentException e){\n                System.out.println(\"Error. Operación no reconocida.\");\n            }\n        } while (accion != null && accion != Acciones.S);\n        scanner.close();\n    }\n\n    private void imprimirMenu(){\n        Arrays.stream(Acciones.values()).forEach(item -> System.out.println(String.format(\"(%s)%s\", item.name(), item.getValor().substring(1))));\n        System.out.print(\"Seleccione la inicial de la operación a realizar: \");\n    }\n\n    public Jeigar2Contacto buscarContacto() {\n        Jeigar2Contacto contacto = null;\n        if(contactos.isEmpty()) {\n            System.out.println(\"La lista de contactos está vacía.\");\n        } else {\n            contacto = getJeigar2Contacto(\"buscar\");\n            if(contacto == null){\n                System.out.println(\"Este contacto no existe\");\n            } else {\n                System.out.println(\"encontrado: \" + contacto.toString());\n            }\n        }\n        return contacto;\n    }\n\n    private Jeigar2Contacto getJeigar2Contacto(String accion) {\n        Scanner scannerGet = new Scanner(System.in);\n        Jeigar2Contacto contacto = null;\n        System.out.println(String.format(\"Procedemos a %s un contacto\", accion));\n        if(contactos.isEmpty()) {\n            System.out.println(\"La lista de contactos está vacía.\");\n        } else {\n            System.out.println(\"Introduce un nombre o numero de teléfono\");\n            String valor = scannerGet.nextLine();\n            contacto = contactos.get(valor);\n        }\n        return contacto;\n    }\n\n    public void insertarContacto() {\n        System.out.println(\"Procedemos a insertar un contacto\");\n        insertarContacto(\"\");\n    }\n    public void insertarContacto(String nombre) {\n        boolean nombreInvalido = true;\n        Scanner scannerInsertar = new Scanner(System.in);\n        String nombreInterno = null;\n        Jeigar2Contacto contacto = null;\n        if(nombre == null || nombre.isBlank() || nombre.isEmpty()) {\n            do {\n                System.out.println(\"Introduce un nombre (obligatorio, no puede ser un valor vacío o espacios en blanco)\");\n                nombreInterno = scannerInsertar.nextLine();\n                nombreInvalido = (nombreInterno == null || nombreInterno.isEmpty() || nombreInterno.isBlank());\n            } while (nombreInvalido);\n\n        } else {\n            nombreInterno = nombre;\n        }\n        System.out.println(\"Introduce un numero de teléfono (solo números, menor o igual a \" + Jeigar2Contacto.MAX_DIGITOS_TELEFONO + \" dígitos)\");\n        String telefono = scannerInsertar.nextLine();\n        try {\n            contacto = new Jeigar2Contacto(nombreInterno.trim(), telefono);\n        } catch (TelefonoException ex) {\n            System.err.println(\"Error de validación. \" + ex.getMessage());\n            insertarContacto(nombreInterno);\n        }\n        try {\n            insertarContacto(contacto);\n        } catch (ContactoDuplicadoException exception) {\n            System.err.println(exception.getMessage());\n            insertarContacto();\n        }\n    }\n\n    public void insertarContacto(Jeigar2Contacto contacto) throws ContactoDuplicadoException{\n        if (contacto != null) {\n            System.out.println(\"insertando: \" + contacto);\n            if(contactos.containsKey(contacto.getNombre()) || contactos.containsKey(contacto.getTelefono())) {\n                throw new ContactoDuplicadoException();\n            } else {\n                contactos.put(contacto.getNombre(), contacto);\n                contactos.put(contacto.getTelefono(), contacto);\n            }\n        }\n    }\n\n    public void actualizarContacto() {\n        actualizarContacto(null);\n    }\n\n    public void actualizarContacto(Jeigar2Contacto contacto) {\n        String opcion = \"\";\n        Datos datos = null;\n        Jeigar2Contacto contactoInterno = null;\n        Jeigar2Contacto contactoNuevoNombre = null;\n        Jeigar2Contacto contactoNuevoTelefono = null;\n        Jeigar2Contacto contactoNuevo = null;\n        if (contactos.isEmpty()){\n            System.out.println(\"La lista de contactos está vacía.\");\n        } else {\n            if (contacto == null) {\n                contactoInterno = getJeigar2Contacto(\"actualizar\");\n            } else {\n                contactoInterno = contacto;\n            }\n            System.out.println(\"Datos Antes: \" + contactoInterno.toString());\n            Arrays.stream(Datos.values()).forEach(item -> System.out.println(String.format(\"(%s)%s\", item.name(), item.getValor().substring(1))));\n            System.out.print(\"Seleccione la inicial de la operación a realizar: \");\n            Scanner scannerActualizar = new Scanner(System.in);\n            opcion = scannerActualizar.nextLine();\n            try {\n                datos = Datos.valueOf(opcion.toUpperCase()); // Paso a mayúsculas\n                switch (datos) {\n                    case N:\n                        contactoNuevoNombre = actualizaNombreContacto(contactoInterno);\n                        System.out.println(\"Datos Actualizados: \" + contactoNuevoNombre.toString());\n                        break;\n                    case T:\n                        contactoNuevoTelefono = actualizaTelefonoContacto(contactoInterno);\n                        System.out.println(\"Datos Actualizados: \" + contactoNuevoTelefono.toString());\n                        break;\n                    case A:\n                        contactoNuevoNombre = actualizaNombreContacto(contactoInterno);\n                        contactoNuevoTelefono = actualizaTelefonoContacto(contactoInterno);\n                        try {\n                            contactoNuevo = new Jeigar2Contacto(contactoNuevoNombre.getNombre(), contactoNuevoTelefono.getTelefono());\n                        } catch (TelefonoException e) {\n                        } // No hacer nada porque ya está validado el telefono antes\n                        System.out.println(\"Datos Actualizados: \" + contactoNuevo.toString());\n                        break;\n                }\n            } catch (IllegalArgumentException e) {\n                System.err.println(\"Error. Operación no reconocida. \" + e.getMessage());\n            } catch (ContactoDuplicadoException | ContactoNoEncontradoException exception) {\n                System.err.println(\"Error. No se realiza la actualización. \" + exception.getMessage());\n            }\n        }\n    }\n\n    private Jeigar2Contacto actualizaTelefonoContacto(Jeigar2Contacto contacto) throws ContactoNoEncontradoException, ContactoDuplicadoException {\n        Scanner scannerActualizar = new Scanner(System.in);\n        Jeigar2Contacto contactoNuevo = null;\n        Jeigar2Contacto contactoRecuperado = contactos.get(contacto.getTelefono());\n        if (contactoRecuperado != null) {\n            boolean telefonoValido = false;\n            String nombre = contactoRecuperado.getNombre();\n            String telefono = null;\n            do {\n                System.out.println(\"Introduce un numero de teléfono (solo números, menor o igual a \" + Jeigar2Contacto.MAX_DIGITOS_TELEFONO + \" dígitos\");\n                telefono = scannerActualizar.nextLine();\n                try {\n                    contactoNuevo = new Jeigar2Contacto(nombre, telefono);\n                    telefonoValido = true;\n                } catch (TelefonoException ex) {\n                    System.out.println(\"Error de validación. \" + ex.getMessage());\n                }\n            } while (!telefonoValido);\n            eliminarContacto(contactoRecuperado);\n            insertarContacto(contactoNuevo);\n        } else {\n            throw new ContactoNoEncontradoException(\"Actualizando Telefono\");\n        }\n        return contactoNuevo;\n    }\n\n    private Jeigar2Contacto actualizaNombreContacto(Jeigar2Contacto contacto) throws ContactoNoEncontradoException, ContactoDuplicadoException {\n        Scanner scannerActualizar = new Scanner(System.in);\n        Jeigar2Contacto contactoNuevo = null;\n        Jeigar2Contacto contactoRecuperado = contactos.get(contacto.getNombre());\n        if(contactoRecuperado != null) {\n            System.out.println(\"Introduce un nombre\");\n            String nombre = scannerActualizar.nextLine();\n            String telefono = contactoRecuperado.getTelefono();\n            try {\n                contactoNuevo = new Jeigar2Contacto(nombre, telefono);\n            }catch (TelefonoException ex){\n                // No hacer nada porque el teléfono es el mismo\n            }\n            eliminarContacto(contactoRecuperado);\n            insertarContacto(contactoNuevo);\n        } else {\n            throw new ContactoNoEncontradoException(\"Actualizando nombre\");\n        }\n        return contactoNuevo;\n    }\n\n    public void eliminarContacto() {\n        System.out.println(\"Procedemos a eliminar un contacto\");\n        Jeigar2Contacto contacto = getJeigar2Contacto(\"eliminar\");;\n        if (contacto == null) {\n            System.out.println(\"El contacto no existe\");\n        } else {\n            eliminarContacto(contacto);\n        }\n    }\n\n    public void eliminarContacto(Jeigar2Contacto contacto) {\n        System.out.println(\"Borraremos: \" + contacto.toString());\n        contacto = contactos.remove(contacto.getNombre());\n        if(contacto != null) {\n            System.out.println(\"Borrado por nombre: \" + contacto.toString());\n        } else {\n            System.out.println(\"No se pudo borrar por nombre\");\n        }\n        contacto = contactos.remove(contacto.getTelefono());\n        if(contacto != null) {\n            System.out.println(\"Borrado por teléfono: \" + contacto.toString());\n        } else {\n            System.out.println(\"No se pudo borrar por teléfono\");\n        }\n    }\n\n    public void contarContactos() {\n        System.out.println(\"Total contacto: \" + contactos.size()/2); // Muestra la mitad porque está duplicado por teléfono y nombre\n    }\n\n    public void listarContactos(){\n        HashMap<String, Jeigar2Contacto> contactosUnicos =  new HashMap<>();\n        if (contactos.isEmpty()){\n            System.out.println(\"La lista de contactos está vacía.\");\n        } else {\n            //recorre todos\n            contactos.forEach((cadena, contacto) -> {\n                // solo introduce los nombres por lo que los teléfonos no los mete\n                if(!contactosUnicos.containsKey(contacto.nombre)){\n                    contactosUnicos.put(contacto.nombre, contacto);\n                }\n            });\n            // recorre todos, pero solo hay la mitad los que tienen nombre\n            contactosUnicos.forEach((cadena, contacto) -> {\n                System.out.println(contacto.toString());\n            });\n        }\n    }\n\n\n    class Jeigar2Contacto {\n        public static final int MAX_DIGITOS_TELEFONO = 11;\n\n        private String nombre;\n        private String telefono;\n\n        public Jeigar2Contacto(String nombre, String telefono) throws TelefonoException{\n            this.nombre = nombre;\n            this.setTelefono(telefono);\n        }\n\n        public String getNombre() {\n            return nombre;\n        }\n\n        public void setNombre(String nombre) {\n            this.nombre = nombre;\n        }\n\n        public String getTelefono() {\n            return telefono;\n        }\n\n        public void setTelefono(String telefono) throws TelefonoException {\n            try {\n                if (telefono == null || telefono.length() == 0) {\n                    throw new TelefonoException(\"debe tener un valor\");\n                }\n                if (telefono.length() > MAX_DIGITOS_TELEFONO) {\n                    throw new TelefonoException(String.format(\"no puede superar los %d dígitos\", MAX_DIGITOS_TELEFONO));\n                }\n                Long.parseLong(telefono); // Solo para forzar la validacion de que sea numérico\n                this.telefono = telefono;\n            } catch (NumberFormatException e){\n                throw new TelefonoException(\"No permite valores que no sean dígitos\");\n            }\n        }\n\n        @Override\n        public String toString() {\n            return \"Contacto{\" +\n                    \"nombre='\" + nombre + '\\'' +\n                    \", telefono='\" + telefono + '\\'' +\n                    '}';\n        }\n    }\n\n    class TelefonoException extends Exception{\n        TelefonoException(){\n            super();\n        }\n\n        TelefonoException(String mensaje){\n            super(\"Error: El teléfono \" + mensaje);\n        }\n    }\n\n    class ContactoDuplicadoException extends Exception {\n        ContactoDuplicadoException() {\n            super(\"Contacto duplicado, los nombres deben ser únicos y los teléfonos también \");\n        }\n\n        ContactoDuplicadoException(String mensaje){\n            super(\"Error: contacto duplicado. \" + mensaje);\n        }\n    }\n\n    class ContactoNoEncontradoException extends Exception {\n        ContactoNoEncontradoException() {\n            super(\"Contacto no encontrado.\");\n        }\n\n        ContactoNoEncontradoException(String mensaje){\n            super(\"Error: contacto no encontrado. \" + mensaje);\n        }\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/JerrySantana.java",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\nimport java.util.ArrayList;\nimport java.util.LinkedList;\nimport java.util.PriorityQueue;\nimport java.util.Queue;\nimport java.util.Stack;\n\nclass JerrySantana {\n    public static void main(String[] args) {\n        System.out.println(\"Estructuras de datos.\");\n        arrays();\n        pilas();\n        colas();\n    }\n    // Arreglos\n    private static void arrays() {\n        System.out.println(\"- Arreglos.\");\n        System.out.println(\"\\tUtilizando la declaracion de arrays: tipoDato nombreVariable[] = {elementos};.\");\n        System.out.println(\"\\t\\tAl inicializar un arreglo automaticamente se define el tamano que tendra, por lo que no se puede agregar ni eliminar valores.\");\n        System.out.println(\"\\t\\tCada elemento dentro del arreglo cuenta con un indice que define la posicion que ocupa dentro del arreglo, este indice comienza en '0'.\");\n        int arreglo[] = {1, 2, 3, 4, 5};\n        System.out.print(\"\\t\\tarreglo original: {\");\n        for (int i : arreglo) {\n            System.out.printf(i + \" \");\n        }\n        System.out.println('}');\n        System.out.println(\"\\t\\tLas operaciones que podemos realizar sobre arreglos son: obtener longitud, acceder a sus valores y modificar los valores de sus elementos.\");\n        System.out.println(\"\\t\\t\\tTamano de arreglo: \" + arreglo.length);\n        System.out.println(\"\\t\\tModificando el valor '5', en la posición [4]; por el valor '6'\");\n        arreglo[4] = 6;\n        System.out.print(\"\\t\\tarreglo modificado: {\");\n        for (int i : arreglo) {\n            System.out.printf(i + \" \");\n        }\n        System.out.println('}');\n        System.out.println(\"\\tUtilizando la clase ArrayList de la biblioteca java.util.\");\n        System.out.println(\"\\t\\tEsta clase nos permite realizar más cosas que con la definición anterior de arreglos. Mediante ArrayList podemos realizar diferentes acciones:\");\n        ArrayList<Integer> arrayList = new ArrayList<>();\n        for (Integer integer : arreglo) {\n            arrayList.add(integer);\n        }\n        System.out.println(\"\\t\\tarrayList: \" + arrayList.toString());\n        arrayList.add(2, 9);\n        System.out.println(\"\\t\\tAñadir elementos.\");\n        System.out.println(\"\\t\\t\\tAñadiendo un valor en la posición '2' del arreglo: \" + arrayList.toString());\n        arrayList.remove(0);\n        System.out.println(\"\\t\\tEliminar elementos.\");\n        System.out.println(\"\\t\\t\\tEliminando el valor en la posición '0' del arreglo: \" + arrayList.toString());\n        arrayList.set(2, 25);\n        System.out.println(\"\\t\\tModificar elementos.\");\n        System.out.println(\"\\t\\t\\tModificado el valor '3', en la posición '2'; por el valor '25': \" + arrayList.toString());\n        arrayList.sort(null);\n        System.out.println(\"\\t\\tOrdenar elementos.\");\n        System.out.println(\"\\t\\t\\tOrdenando el arreglo mediante la función sort de la clase: \" + arrayList.toString());\n        System.out.println(\"\\tTambién podemos utilizar la definición inicial de arrays para crear arreglos bidimensionales o también llamados matrices.\");\n    }\n    // Pilas\n    private static void pilas() {\n        System.out.println(\"- Arreglos.\");\n        System.out.println(\"\\tUtilizamos la clase Stack de la biblioteca java.utils, para implementar pilas.\");\n        System.out.println(\"\\tLas pilas utilizan el principio LIFO 'Last In First Out' (Ultimo en entrar, primero en salir).\");\n        System.out.println(\"\\tUtilizamos la clase Stack de la biblioteca java.utils, para implementar pilas.\");\n        System.out.println(\"\\tMediante esta clase podemos realizar las siguientes acciones:\");\n        Stack<Integer> pila = new Stack<>();\n        System.out.println(\"\\t\\tAñadir elementos al final de la pila mediante el comando push.\");\n        for(int i = 0; i < 5; i++) {\n            System.out.println(\"\\t\\t\\tAñadiendo valor: \" + i + \", a la pila: \" + pila.toString());\n            pila.push(i);\n        }\n        System.out.println(\"\\t\\t\\tpila resultante: \" + pila.toString());\n        System.out.println(\"\\t\\tAñadir elementos en un lugar específico mediante el comando add.\");\n        pila.add(2, 8);\n        System.out.println(\"\\t\\t\\tAñadido el valor '8', en la posición 2.\");\n        System.out.println(\"\\t\\t\\tpila resultante: \" + pila.toString());\n        System.out.println(\"\\t\\tBorrar elementos mediante el comando pop.\");\n        pila.pop();\n        System.out.println(\"\\t\\t\\tEliminado el último elemento de la pila.\");\n        System.out.println(\"\\t\\t\\tpila resultante: \" + pila.toString());\n        System.out.println(\"\\t\\tModificar elementos mediante el comando set.\");\n        pila.set(3, 6);\n        System.out.println(\"\\t\\t\\tModificado el valor '3', en la posición 3; con el valor '6'.\");\n        System.out.println(\"\\t\\t\\tpila resultante: \" + pila.toString());\n        System.out.println(\"\\t\\tOrdenar elementos mediante el comando sort.\");\n        pila.sort(null);\n        System.out.println(\"\\t\\t\\tpila resultante: \" + pila.toString());\n    }\n    // Colas\n    private static void colas() {\n        System.out.println(\"- Colas.\");\n        System.out.println(\"\\tSon estructuras que siguen el principio FIFO 'First In First Out' (Primero en entrar primero en salir).\");\n        System.out.println(\"\\tPueden ser implementadas mediante la clase PriorityQueue o Linkedlist de la biblioteca java.util.\");\n        System.out.println(\"\\tUtilizando la clase PriorityQueue, podemos realizar las siguientes operaciones:\");\n        PriorityQueue<Integer> colaPrioridad = new PriorityQueue<>();\n        System.out.println(\"\\t\\tAñadir elementos a la cola de prioridad mediante el comando add.\");\n        for(int i = 11; i < 21; i++) {\n            System.out.println(\"\\t\\t\\tAñadiendo valor: \" + i + \", a la cola de prioridad: \" + colaPrioridad.toString());\n            colaPrioridad.add(i);\n        }\n        System.out.println(\"\\t\\t\\tCola de prioridad resultante: \" + colaPrioridad.toString());\n        System.out.println(\"\\t\\tEliminar el elemento en la cabeza de la cola de prioridad mediante el comando poll.\");\n        System.out.println(\"\\t\\t\\tEliminando el elemento al frente de la cola de prioridad...: \" + colaPrioridad.poll());\n        System.out.println(\"\\t\\t\\tCola de prioridad resultante: \" + colaPrioridad.toString());\n        System.out.println(\"\\tUtilizando la clase Queue y LinkedList, podemos realizar las siguientes operaciones:\");\n        Queue<Integer> queue = new LinkedList<Integer>();\n        for(int i = 21; i < 31; i++) {\n            System.out.println(\"\\t\\t\\tAñadiendo valor: \" + i + \", a la cola: \" + queue.toString());\n            queue.offer(i);\n        }\n        System.out.println(\"\\t\\t\\tCola resultante: \" + queue.toString());\n        System.out.println(\"\\t\\tEliminar el elemento en la cabeza de la cola mediante el comando poll.\");\n        System.out.println(\"\\t\\t\\tEliminando el elemento al frente de la cola...: \" + queue.poll());\n        System.out.println(\"\\t\\t\\tCola resultante: \" + queue.toString());\n        System.out.println(\"\\t\\t\");\n        System.out.println(\"\\t\\t\\t\");\n    }\n}"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/JesusAntonioEEscamilla.java",
    "content": "/** #03 - Java -> Jesus Antonio Escamilla */\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Scanner;\n\npublic class JesusAntonioEEscamilla {\n    private static final int MAX_DIGITS = 11;\n    public static void main(String[] args) {\n    //---EJERCIÓ---\n        array();\n        list();\n        map();\n        set();\n    //---EXTRA---\n        EXTRA();\n    }\n\n    public static void array(){\n        //.....ARRAYS.....\n        // Creando Arreglo\n        System.out.println(\"---ARRAY---\");\n        int[] arreglo = new int[5];\n        \n        // INSERCIÓN\n        System.out.println(\"INSERCIÓN\");\n        arreglo[0] = 20;\n        arreglo[1] = 10;\n        arreglo[2] = 40;\n        arreglo[3] = 30;\n        arreglo[4] = 60;\n        System.out.println(Arrays.toString(arreglo));\n\n        // BORRANDO\n        System.out.println(\"BORRADO\");\n        System.out.println(\"No hay forma directa para borrar un elemento\");\n        System.out.println(\"Pero mostrare otra forma de borrar un elemento\");\n        int indexToRemove = 4;\n        for (int i = indexToRemove; i < arreglo.length -1; i++) {\n            arreglo[i] = arreglo[i + 1];\n        }\n        // Reducir el tamaño del array eliminando el último elemento\n        arreglo = Arrays.copyOf(arreglo, arreglo.length - 1);\n        System.out.println(Arrays.toString(arreglo));\n\n        // ACTUALIZACIÓN\n        System.out.println(\"ACTUALIZACIÓN\");\n        arreglo[2] = 35;\n        System.out.println(Arrays.toString(arreglo));\n\n        // ORDENAMIENTO\n        System.out.println(\"ORDENAMIENTO\");\n        Arrays.sort(arreglo);\n        System.out.println(Arrays.toString(arreglo));\n    }\n\n    public static void list(){\n        //.....LISTAS.....\n        // Creando Lista\n        System.out.println(\"---LISTA---\");\n        List<String> lista = new ArrayList<>();\n        Collections.addAll(lista, \"Manzana\", \"Pera\", \"Banana\", \"Cereza\", \"Melon\");\n        System.out.println(lista);\n        \n        // INSERCIÓN\n        System.out.println(\"INSERCIÓN\");\n        lista.add(\"Uva\");\n        System.out.println(lista);\n        lista.add(0, \"Kiwi\");\n        System.out.println(lista);\n\n        // BORRANDO\n        System.out.println(\"BORRADO\");\n        lista.remove(\"Banana\");\n        System.out.println(lista);\n        String elementoBorrado = lista.remove(2);\n        System.out.println(elementoBorrado);\n        System.out.println(lista);\n\n        // ACTUALIZACIÓN\n        System.out.println(\"ACTUALIZACIÓN\");\n        lista.set(2, \"Papaya\");\n        System.out.println(lista);\n\n        // ORDENAMIENTO\n        System.out.println(\"ORDENAMIENTO\");\n        Collections.sort(lista);\n        List<String> listaOrdenada = new ArrayList<>(lista);\n        System.out.println(\"Lista Ordenada: \" + listaOrdenada);\n    }\n\n    public static void map(){\n        //.....HASHMAP.....\n        // Creando Arreglo\n        System.out.println(\"---HASHMAP---\");\n        HashMap<String, Integer> mapa = new HashMap<>();\n        \n        // INSERCIÓN\n        System.out.println(\"INSERCIÓN\");\n        mapa.put(\"Rancheros\", 1);\n        mapa.put(\"Palomitas\", 10);\n        mapa.put(\"Galletas\", 4);\n        mapa.put(\"Pan\", 2);\n        mapa.put(\"Coca Cola\", 8);\n        System.out.println(mapa);\n\n        // BORRANDO\n        System.out.println(\"BORRADO\");\n        mapa.remove(\"Pan\");\n        System.out.println(mapa);\n\n        // ACTUALIZACIÓN\n        System.out.println(\"ACTUALIZACIÓN\");\n        mapa.put(\"Galletas\", 3);\n        System.out.println(mapa);\n\n        // ORDENAMIENTO\n        System.out.println(\"ORDENAMIENTO\");\n        System.out.println(\"No hay forma directa para ordenar los elementos\");\n    }\n\n    public static void set(){\n        //.....HASHSET.....\n        // Creando Arreglo\n        System.out.println(\"---HASHSET---\");\n        HashSet<String> conjunto = new HashSet<>();\n        \n        // INSERCIÓN\n        System.out.println(\"INSERCIÓN\");\n        conjunto.add(\"A\");\n        conjunto.add(\"B\");\n        conjunto.add(\"C\");\n        conjunto.add(\"D\");\n        System.out.println(conjunto);\n\n        // BORRANDO\n        System.out.println(\"BORRADO\");\n        conjunto.remove(\"B\");\n        System.out.println(conjunto);\n\n        // ACTUALIZACIÓN\n        System.out.println(\"ACTUALIZACIÓN\");\n        conjunto.remove(\"D\");\n        System.out.println(conjunto);\n        conjunto.add(\"E\");\n        System.out.println(conjunto);\n\n        // ORDENAMIENTO\n        System.out.println(\"ORDENAMIENTO\");\n        System.out.println(\"No hay forma directa para ordenar los elementos\");\n    }\n\n    /**-----DIFICULTAD EXTRA-----*/\n\n    public static void EXTRA(){\n        Map<String, String> agenda = new HashMap<>();\n        Scanner scanner = new Scanner(System.in);\n\n        while (true) {\n            mostrarMenu();\n            String option = scanner.nextLine();\n\n            switch (option) {\n                case \"1\":\n                    insertarContacto(agenda, scanner);\n                    break;\n                case \"2\":\n                    buscarContacto(agenda, scanner);\n                    break;\n                case \"3\":\n                    actualizarContacto(agenda, scanner);\n                    break;\n                case \"4\":\n                    eliminarContacto(agenda, scanner);\n                    break;\n                case \"5\":\n                    mostrarTodosContactos(agenda);\n                    break;\n                case \"6\":\n                    System.out.println(\"Saliendo del programa.....\");\n                    scanner.close();\n                    return;\n                default:\n                    System.out.println(\"Opción ni valida. Intente de nuevo\");\n                    break;\n            }\n        }\n    }\n\n    private static void mostrarMenu() {\n        System.out.println(\"\\nAgenda de Contactos\");\n        System.out.println(\"1. Insertar Contacto\");\n        System.out.println(\"2. Buscar Contacto\");\n        System.out.println(\"3. Actualizar Contacto\");\n        System.out.println(\"4. Eliminar Contacto\");\n        System.out.println(\"5. Mostrar todos los Contacto\");\n        System.out.println(\"6. Salir\");\n        System.out.print(\"Seleccione una option: \");\n    }\n\n    private static boolean validarTelefono(String telefono){\n        return telefono.matches(\"\\\\d+\") && telefono.length() <= MAX_DIGITS;\n    }\n\n    private static void insertarContacto(Map<String, String> agenda, Scanner scanner) {\n        System.out.print(\"Ingrese el Nombre del contacto: \");\n        String nombre = scanner.nextLine();\n        System.out.print(\"Ingrese el Teléfono del contacto: \");\n        String telefono = scanner.nextLine();\n\n        if (validarTelefono(telefono)) {\n            agenda.put(nombre, telefono);\n            System.out.println(\"Contacto \" + nombre + \" añadido con éxito\");\n        } else {\n            System.out.println(\"Numero de Teléfono no valido. Debe ser numérico y tener un máximo de \" + (MAX_DIGITS - 1) + \" dígitos\");\n        }\n    }\n\n    private static void buscarContacto(Map<String, String> agenda, Scanner scanner) {\n        System.out.print(\"Ingrese el Nombre del contacto al buscar: \");\n        String nombre = scanner.nextLine();\n        if (agenda.containsKey(nombre)) {\n            System.out.println(\"Nombre: \" + nombre + \", Teléfono: \" + agenda.get(nombre));\n        } else {\n            System.out.println(\"Contacto no encontrado\");\n        }\n    }\n\n    private static void actualizarContacto(Map<String, String> agenda, Scanner scanner) {\n        System.out.print(\"Ingrese el Nombre del contacto al actualizar: \");\n        String nombre = scanner.nextLine();\n        if (agenda.containsKey(nombre)) {\n            System.out.print(\"Ingrese el nuevo numero de telefono: \");\n            String nuevoTelefono = scanner.nextLine();\n            if (validarTelefono(nuevoTelefono)) {\n                agenda.put(nombre, nuevoTelefono);\n                System.out.println(\"Contacto \" + nombre + \" actualizado con éxito\");\n            } else {\n                System.out.println(\"Numero de Teléfono no valido. Debe ser numérico y tener un máximo de \" + (MAX_DIGITS - 1) + \" dígitos\");\n            }\n        } else {\n            System.out.println(\"Contacto no encontrado\");\n        }\n    }\n\n    private static void eliminarContacto(Map<String, String> agenda, Scanner scanner) {\n        System.out.print(\"Ingrese el Nombre del contacto a eliminar: \");\n        String nombre = scanner.nextLine();\n        if (agenda.containsKey(nombre)) {\n            agenda.remove(nombre);\n            System.out.println(\"Contacto \" + nombre + \" eliminado con éxito\");\n        } else {\n            System.out.println(\"Contacto no encontrado\");\n        }\n    }\n\n    private static void mostrarTodosContactos(Map<String, String> agenda) {\n        if (agenda.isEmpty()) {\n            System.out.println(\"No hay contactos en la agenda\");\n        } else {\n            for (Map.Entry<String, String> entry : agenda.entrySet()) {\n                System.out.println(\"Nombre: \" + entry.getKey() + \", Telefono: \" + entry.getValue());\n            }\n        }\n    }\n\n    /**-----DIFICULTAD EXTRA-----*/\n}"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/JesusEs1312.java",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\nclass JesusEs1312 {\n    // Ejemplos de creación de estructuras de datos\n    public static void main(String[] args) {\n        // Creación de un array\n        int[] array = new int[10];\n        // Creación de una lista\n        java.util.List<Integer> lista = new java.util.ArrayList<>();\n        // Creación de un conjunto\n        java.util.Set<Integer> conjunto = new java.util.HashSet<>();\n        // Creación de un mapa\n        java.util.Map<String, Integer> mapa = new java.util.HashMap<>();\n        // Creación de una cola\n        java.util.Queue<Integer> cola = new java.util.LinkedList<>();\n        // Creación de una pila\n        java.util.Stack<Integer> pila = new java.util.Stack<>();\n\n        // Operaciones de inserción\n        for (int i = 0; i < 10; i++) {\n            array[i] = i;\n            lista.add(i);\n            conjunto.add(i);\n            mapa.put(\"Clave \" + i, i);\n            cola.add(i);\n            pila.push(i);\n        }\n\n        // Operaciones de borrado\n        for (int i = 0; i < 10; i++) {\n            lista.remove(0);\n            conjunto.remove(i);\n            mapa.remove(\"Clave \" + i);\n            cola.poll();\n            pila.pop();\n        }\n\n        // Operaciones de actualización\n        for (int i = 0; i < 10; i++) {\n            array[i] = i * 2;\n            lista.set(i, i * 2);\n            conjunto.remove(i);\n            conjunto.add(i * 2);\n            mapa.put(\"Clave \" + i, i * 2);\n            cola.poll();\n            cola.add(i * 2);\n            pila.pop();\n            pila.push(i * 2);\n        }\n\n        // Operaciones de ordenación\n        java.util.Arrays.sort(array);\n        java.util.Collections.sort(lista);\n        java.util.List<Integer> listaOrdenada = new java.util.ArrayList<>(conjunto);\n        java.util.Collections.sort(listaOrdenada);\n        java.util.List<java.util.Map.Entry<String, Integer>> listaOrdenadaMapa = new java.util.ArrayList<>(mapa.entrySet());\n        java.util.Collections.sort(listaOrdenadaMapa, new java.util.Comparator<java.util.Map.Entry<String, Integer>>() {\n            @Override\n            public int compare(java.util.Map.Entry<String, Integer> o1, java.util.Map.Entry<String, Integer> o2) {\n                return o1.getValue().compareTo(o2.getValue());\n            }\n        });\n        java.util.Collections.sort((java.util.List<Integer>) cola);\n        java.util.Collections.sort(pila);\n\n        // Ejemplo de agenda de contactos\n        java.util.Scanner scanner = new java.util.Scanner(System.in);\n        java.util.Map<String, String> agenda = new java.util.HashMap<>();\n        while (true) {\n            System.out.println(\"1. Buscar contacto\");\n            System.out.println(\"2. Añadir contacto\");\n            System.out.println(\"3. Actualizar contacto\");\n            System.out.println(\"4. Eliminar contacto\");\n            System.out.println(\"5. Salir\");\n            System.out.print(\"Elige una opción: \");\n            int opcion = scanner.nextInt();\n            scanner.nextLine();\n            switch (opcion) {\n                case 1:\n                    System.out.print(\"Introduce el nombre del contacto: \");\n                    String nombre = scanner.nextLine();\n                    String telefono = agenda.get(nombre);\n                    if (telefono != null) {\n                        System.out.println(\"El teléfono de \" + nombre + \" es \" + telefono);\n                    } else {\n                        System.out.println(\"No se ha encontrado el contacto\");\n                    }\n                    break;\n                case 2:\n                    System.out.print(\"Introduce el nombre del contacto: \");\n                    nombre = scanner.nextLine();\n                    System.out.print(\"Introduce el teléfono del contacto: \");\n                    telefono = scanner.nextLine();\n                    agenda.put(nombre, telefono);\n                    System.out.println(\"Contacto añadido\");\n                    break;\n                case 3:\n                    System.out.print(\"Introduce el nombre del contacto: \");\n                    nombre = scanner.nextLine();\n                    telefono = agenda.get(nombre);\n                    if (telefono != null) {\n                        System.out.print(\"Introduce el nuevo teléfono del contacto: \");\n                        telefono = scanner.nextLine();\n                        agenda.put(nombre, telefono);\n                        System.out.println(\"Contacto actualizado\");\n                    } else {\n                        System.out.println(\"No se ha encontrado el contacto\");\n                    }\n                    break;\n                case 4:\n                    System.out.print(\"Introduce el nombre del contacto: \");\n                    nombre = scanner.nextLine();\n                    telefono = agenda.get(nombre);\n                    if (telefono != null) {\n                        agenda.remove(nombre);\n                        System.out.println(\"Contacto eliminado\");\n                    } else {\n                        System.out.println(\"No se ha encontrado el contacto\");\n                    }\n                    break;\n                case 5:\n                    return;\n                default:\n                    System.out.println(\"Opción no válida\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/JimsimroDev.java",
    "content": "import java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Scanner;\nimport java.util.Set;\nimport java.util.Stack;\nimport java.util.TreeMap;\n\npublic class JimsimroDev {\n  private Scanner in = new Scanner(System.in);\n  private Map<String, Long> agenda = new HashMap<>();\n  private String nombre;\n  private Long telefono;\n\n  private void crearContacto() {\n    System.out.println(\"Ingresa el nombre del contacto\");\n    nombre = in.nextLine();\n    System.out.println(\"Ingresa el numero de telefono\");\n    telefono = in.nextLong();\n    in.nextLine();\n    validacion(nombre, telefono);\n  }\n\n  private void buscarContacto() {\n    System.out.println(\"Escribe el nombre del contacto a buscar\");\n    nombre = in.nextLine();\n    if (agenda.containsKey(nombre)) {\n      System.err.println(\"El telefono de \" + nombre + \" es \" + agenda.get(nombre));\n    } else {\n      System.out.println(\"Contacto no encontrado\");\n    }\n  }\n\n  private void actualizarContacto() {\n    System.out.println(\"Escribe el nombre del contacto que desea Actualizar\");\n    String contactoActualizar = in.nextLine();\n    if (agenda.containsKey(contactoActualizar)) {\n      System.out.println(\"Escribe el nuevo número para el contacto \");\n      Long nuevoNumero = in.nextLong();\n      validacion(contactoActualizar, nuevoNumero);\n    }\n  }\n\n  private void eliminarContacto() {\n    System.out.println(\"Escribe el nombre del contacto a eliminar\");\n    String contactoAEliminar = in.nextLine();\n    if (agenda.containsKey(contactoAEliminar)) {\n      agenda.remove(contactoAEliminar);\n      System.out.println(\"Contacto eliminado \");\n    } else {\n      System.out.println(\"Ese contacto no existe\");\n    }\n  }\n\n  public void run() {\n    String menu = \"\"\"\n        Menu\n        + 1. Crear contacto nuevo\n        + 2. Buscar contacto\n        + 3. Actualizar contacto\n        + 4. Elimnar contacto\n        + 5. Salir\n        \"\"\";\n    int opcion = 0;\n    while (opcion != 5) {\n      System.out.println(menu);\n      System.out.print(\"Seleciona una opcion -> \");\n      opcion = in.nextInt();\n      in.nextLine();\n\n      switch (opcion) {\n        case 1:\n          crearContacto();\n          break;\n        case 2:\n          buscarContacto();\n          break;\n        case 3:\n          actualizarContacto();\n          break;\n        case 4:\n          eliminarContacto();\n          break;\n        case 5:\n          System.out.println(\"Saliendo de la agenda\");\n          break;\n        default:\n          break;\n      }\n    }\n  }\n\n  private static boolean isDigit(Long telefono) {\n    Integer longitud = String.valueOf(telefono).length();\n    if (telefono >= 0 && longitud >= 10) {\n      return true;\n    }\n    return false;\n  }\n\n  private void validacion(String nombre, Long telefono) {\n    if (isDigit(telefono)) {\n      agenda.put(nombre, telefono);\n      System.out.println(\"Contacto Guardado \" + agenda);\n    } else {\n      System.out.println(\"Debes introducir un número de telefono valido de 10 digitos\");\n    }\n  }\n\n  public static void main(String[] args) {\n    JimsimroDev ejecutar = new JimsimroDev();\n    String divLine = \"::::::::::::::::::::::::::::::::::::::\";\n    // Estructuras de datos\n    // Listas enlasadas\n    //\n    System.out.println(divLine);\n    List<String> miListaInmutable = List.of(\"JimsimroDev\", \"Thor\", \"Comedian\");// Inmutable no se puede modificar\n    System.out.println(miListaInmutable);\n    System.out.println(divLine);\n\n    List<String> miLista = new ArrayList<>(Arrays.asList(\"JimsimroDev\", \"Thor\", \"Comedian\"));\n    System.out.println(miLista);\n    miLista.add(\"Wanda\");// Insercción\n    System.out.println(miLista);\n\n    miLista.remove(\"Wanda\");// Eliminación\n    System.out.println(miLista);\n\n    System.out.println(miLista.get(1)); // Acceso\n    miLista.set(1, \"Wanda\"); // Actualizaacion\n    System.out.println(miLista);\n\n    // Ordena la Listas\n    Collections.sort(miLista);\n    System.out.println(miLista);\n\n    System.out.println(divLine);\n    LinkedList<String> lista = new LinkedList<>() {\n      {\n        add(\"Phyton\");\n        add(\"Java\");\n        add(\"PHP\");\n        add(\"Rust\");\n      }\n    };\n    System.out.println(lista);\n\n    lista.add(\"Cobol\");// Insercción\n    System.out.println(lista);\n\n    lista.remove(\"PHP\");// eliminacion\n    System.out.println(lista);\n\n    System.out.println(lista.get(3));// Acceso\n\n    lista.set(3, \"Perl\");\n    System.out.println(lista);\n\n    System.out.println(divLine);\n    Set<String> conjunto = new HashSet<>() {\n      {\n        add(\"Spring\");\n        add(\"Laravel\");\n        add(\"Angular\");\n        add(\"Angular\");// No se agrega por que Set no permite elemento duplicados\n      }\n    };\n    System.out.println(conjunto);\n\n    conjunto.add(\"React\");// Insercción\n    System.out.println(conjunto);\n\n    conjunto.remove(\"Laravel\");// Eliminación\n    System.out.println(conjunto);\n\n    // no permite acceder a los elementos en un indice especifico ya que este los\n    // guardan sin un ordenación y no permite tampoco duplicados\n    // lo que podemos hacer es validar si existe un elemento con contains\n    System.out.println(\"El framework Spring existe en el cojunto? \" + conjunto.contains(\"Spring\"));// Devuelve tru si\n                                                                                                   // esta en el\n                                                                                                   // conjunto\n    System.out.println(divLine);\n    Stack<String> pila = new Stack<>() {\n      {\n        push(\"Elemento 1\");\n        push(\"Elemento 2\");\n        push(\"Elemento 3\");\n      }\n    };\n    System.out.println(pila);\n\n    pila.push(\"Elemento 4\");// Insercción\n    System.out.println(pila);\n\n    pila.pop();// Elimina el ultimo elemento de la lista ya que no permite eliminar elementos\n               // intermedios\n    System.out.println(pila);\n    System.out.println(pila.get(2));// Acceso al elementos por indice\n\n    System.out.println(divLine);\n    // Diccionario o mapas\n    Map<String, String> map = new HashMap<>();\n    map.put(\"nombre\", \"JimsimroDev\");\n    map.put(\"apellidos\", \"Simanca\");\n    map.put(\"edad\", \"28\");\n    System.out.println(map);\n\n    map.put(\"telefono\", \"321343534\");// Insercción\n    System.out.println(map);\n\n    map.remove(\"apellidos\");// Eliminación\n    System.out.println(map);\n\n    System.out.println(map.get(\"nombre\")); // Acceso\n\n    map.put(\"edad\", \"29\"); // Actualización\n    System.out.println(map);\n\n    Map<String, String> ordenacionPorClave = new TreeMap<>(map);\n    System.out.println(ordenacionPorClave);// ordenación por la clave\n\n    System.out.println(divLine);\n    // Extra\n    ejecutar.run();\n  }\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/Josegs95.java",
    "content": "import java.util.*;\n\npublic class Josegs95 {\n    public static void main(String[] args) {\n        // Estructuras de datos\n\n        //Arrays o arreglos\n        //Son estructuras de datos bastante rígidas que no permiten la adicción o eliminación de elementos.\n        //Su tamaño es especificado al crear el array, ya sea rellenándolo de elementos o especificando el tamaño\n        String[] arrayVacio = new String [4]; //Creación de un array vacío con espacio de hasta 4 elementos\n        String[] diasSemana = {\"Lunes\", \"Martes\", \"Miércoles\", \"Jueves\", \"Viernes\", \"Sábado\", \"Domingo\"};\n        System.out.println(Arrays.toString(diasSemana));\n\n        diasSemana[0] = \"LUNES\"; //Modificación\n        System.out.println(Arrays.toString(diasSemana));\n\n        Arrays.sort(diasSemana); //Ordenación gracias a la clase Arrays.\n        System.out.println(Arrays.toString(diasSemana));\n\n        //Listas\n        //Hay muchos tipos de listas, cada una con sus peculiaridades, pero yo voy a mostrar la clase ArrayList\n        ArrayList<Integer> tiradasDado = new ArrayList<>(); //Creación del objeto\n\n        tiradasDado.add(5); //Inserción de un elemento\n        tiradasDado.add(2);\n        tiradasDado.add(6);\n        System.out.println(tiradasDado);\n\n        tiradasDado.set(0, 4); //Modificación de un elemento, en este caso, el primero (índice 0)\n        System.out.println(tiradasDado);\n\n        tiradasDado.remove(2); //Eliminación del tercer elemento de la lista\n        System.out.println(tiradasDado);\n\n        Collections.sort(tiradasDado); //Ordenación a través de la clase Collections\n        System.out.println(tiradasDado);\n\n        //Sets\n        //Estructura de datos parecido a las listas pero que no permite la inserción de duplicados\n        //Como no se puede acceder a un elemento en concreto, no se puede modificar a los mismos\n        HashSet<String> colores = new HashSet<>(); //Creación del objeto\n\n        colores.add(\"Azul\"); //Inserción de elementos\n        colores.add(\"Verde\");\n        colores.add(\"Blanco\");\n        System.out.println(colores);\n\n        colores.remove(\"Blanco\"); //Eliminación de un elemento\n        System.out.println(colores);\n\n            //Existe una clase que permite ordenar los set (SortedSet, o su subclase, TreeSet).\n\n        //Mapas\n        //Estructuras de datos que asocian un valor a una clave única. Los mapas no permiten la ordenación de\n        //elementos por defecto (el usuario puede crear un método para esto)\n        HashMap<String, Double> notasExamen = new HashMap<>(); //Creación del mapa\n\n        notasExamen.put(\"Jose\", 9.0); //Inserción de elementos\n        notasExamen.put(\"Guillermo\", 6.0);\n        notasExamen.put(\"Rocío\", 9.25);\n        notasExamen.put(\"Antonio\", 3.75);\n        System.out.println(notasExamen);\n\n        notasExamen.replace(\"Guillermo\", 6.25); //Modificación de un elemento\n        System.out.println(notasExamen);\n\n        notasExamen.remove(\"Antonio\"); //Eliminación de un elemento\n        System.out.println(notasExamen);\n\n        //\n        System.out.println(\"\\n\\n\");\n        //\n\n        retoFinal();\n    }\n\n    static Scanner sc;\n    static String[] options = {\"Ver Contactos\", \"Buscar Contacto\", \"Agregar Contacto\", \"Modificar Contacto\",\n            \"Eliminar Contacto\", \"Salir del programa\"};\n\n    static Map<String, String> agenda;\n\n    public static void retoFinal(){\n        sc = new Scanner(System.in);\n        agenda = new HashMap<>();\n        boolean end = false;\n        do{\n            showMenu();\n\n            System.out.print(\"Introduzca la operación que quiere realizar: \");\n            String option = sc.nextLine();\n\n            switch (option){\n                case \"1\": //Ver contactos\n                    showAgenda();\n                    break;\n                case \"2\": //Buscar contactos\n                    searchContact();\n                    break;\n                case \"3\": //Añadir contactos\n                    addContact(null);\n                    break;\n                case \"4\": //Modificar contactos\n                    modifyContact();\n                    break;\n                case \"5\": //Borrar contactos\n                    removeContact();\n                    break;\n                case \"6\": //Salir\n                    end = true;\n                    break;\n                default:\n                    System.out.println(\"Opción no válida. Introduzca un número de opción válido.\");\n            }\n        }while(end == false);\n\n        System.out.println(\"Cerrando la aplicación. Hasta otra!\");\n    }\n\n    private static void showMenu(){\n        System.out.println(\"----------------------------\");\n        for (int i = 0; i < options.length; i++){\n            System.out.println((i+1) + \". \" + options[i]);\n        }\n        System.out.println(\"----------------------------\");\n    }\n\n    private static void showAgenda(){\n        if (agenda.size() == 0)\n            System.out.println(\"La agenda está vacía.\");\n        else {\n            for (Map.Entry<String, String> entry : agenda.entrySet()){\n                System.out.println(\"Contacto: \" + entry.getKey() + \", Teléfono: \" + entry.getValue());\n            }\n        }\n    }\n\n    private static void searchContact(){\n        System.out.print(\"Introduzca el nombre del contacto que quiera buscar: \");\n        String contact = sc.nextLine();\n        String phone;\n        if ((phone = agenda.get(contact)) == null)\n            System.out.println(\"El contacto \" + contact + \" no existe.\");\n        else\n            System.out.println(\"El telefono de \" + contact + \" es \" + phone);\n    }\n\n    private static void addContact(String antiguoContacto){\n        System.out.print(\"Introduzca el nombre del contacto: \");\n        String contact = sc.nextLine();\n        boolean correctOption = false;\n        do {\n            System.out.print(\"Introduzca el número de teléfono: \");\n            String phone = sc.nextLine();\n            if (phone.length() > 11){\n                System.out.println(\"El número de teléfono no puede tener mas de 11 dígitos\");\n            } else {\n                try {\n                    Long.parseLong(phone);\n                    correctOption = true;\n                    if (antiguoContacto != null)\n                        agenda.remove(antiguoContacto);\n                    agenda.put(contact, phone);\n                } catch (NumberFormatException e){\n                    System.out.println(\"Error. Carácteres no númericos detectados.\");\n                }\n            }\n        } while (correctOption == false);\n    }\n\n    private static void modifyContact(){\n        System.out.print(\"Introduzca el nombre del contacto que quiera modificar: \");\n        String contacto = sc.nextLine();\n        if (agenda.get(contacto) == null){\n            System.out.println(\"Error. Ese contacto no existe en su agenda\");\n        } else {\n            addContact(contacto);\n        }\n\n    }\n\n    private static void removeContact(){\n        System.out.print(\"Introduzca el nombre del contacto que quiera eliminar: \");\n        String contact = sc.nextLine();\n        if (agenda.remove(contact) == null)\n            System.out.println(\"El contacto \" + contact + \" no existe.\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/JuanCamiloFVX.java",
    "content": "\n/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por\n * defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y\n * eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere\n * realizar, y a continuación\n * los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no numéricos y\n * con más de 11 dígitos.\n * (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n/**\n * JuanCamiloFVX\n */\nimport java.util.*;\n\npublic class JuanCamiloFVX {\n\n    // INICIALIZACIÓN:\n    // Array\n    static int[] array = new int[4]; // Inicializa un array de tamaño 4 con valores por defecto (0, 0, 0, 0).\n\n    // ArrayList\n    static ArrayList<String> arrayList = new ArrayList<>(); // Inicializa un ArrayList vacío. []\n\n    // Map\n    static Map<Integer, String> map = new HashMap<>(); // Inicializa un HashMap vacío. {}\n\n    // Stack\n    static Stack<Integer> stack = new Stack<>(); // Inicializa una pila vacía. []<=>\n\n    // Queue\n    static Queue<Integer> queue = new LinkedList<>(); // Inicializa una cola vacía. <-[]<-\n\n    public static void main(String[] args) {\n        imprimirContenidos();\n        insertar();\n        imprimirContenidos();\n        borrar();\n        imprimirContenidos();\n        actualizar();\n        imprimirContenidos();\n        ordenar();\n        imprimirContenidos();\n        agendaContactos();\n    }\n\n    static void insertar() {\n        // Array\n        array[0] = 2;\n        array[1] = 3;\n        array[2] = 5;\n        array[3] = 6;\n\n        // ArrayList\n        arrayList.add(\"uno\");\n        arrayList.add(\"dos\");\n        arrayList.add(\"tres\");\n        arrayList.add(\"cuatro\");\n\n        // Map\n        map.put(0, \"uno\");\n        map.put(1, \"dos\");\n\n        // Stack\n        stack.push(1);\n        stack.push(2);\n        stack.push(3);\n\n        // Queue\n        queue.offer(1);\n        queue.offer(2);\n        queue.offer(3);\n    }\n\n    static void ordenar() {\n        // Array\n        Arrays.sort(array); // Ordena el array.\n\n        // ArrayList\n        Collections.sort(arrayList); // Ordena el ArrayList.\n\n        // Map - No tiene un método para ordenarlo.\n\n        // Stack - No es necesario ordenar un Stack ya que representa una pila.\n\n        // Queue - No es necesario ordenar una Queue ya que representa una cola.\n    }\n\n    static void borrar() {\n        // Array\n        array[0] = 0;\n\n        // ArrayList\n        arrayList.remove(\"dos\");\n\n        // Map\n        map.remove(1);\n\n        // Stack\n        stack.pop(); // Elimina el elemento superior de la pila.\n\n        // Queue\n        if (!queue.isEmpty()) {\n            queue.poll(); // Elimina el elemento frontal de la cola si no está vacía.\n        }\n    }\n\n    static void actualizar() {\n        // Array\n        array[0] = 7;\n\n        // ArrayList\n        arrayList.set(0, \"UNO\"); // Actualiza el primer elemento del ArrayList.\n\n        // Map\n        map.put(0, \"UNO\"); // Actualiza el valor asociado a la clave 0 en el mapa.\n\n        // Stack\n        if (!stack.isEmpty()) {\n            stack.pop(); // Elimina el elemento superior de la pila.\n            stack.push(99); // Inserta el valor 99 en la pila.\n        }\n\n        // Queue\n        if (!queue.isEmpty()) {\n            queue.poll(); // Elimina el elemento frontal de la cola.\n            queue.offer(999); // Inserta el valor 999 en la cola.\n        }\n    }\n\n    static void imprimirContenidos() {\n        System.out.println(\"Array: \" + Arrays.toString(array));\n        System.out.println(\"ArrayList: \" + arrayList);\n        System.out.println(\"Map: \" + map);\n        System.out.println(\"Stack: \" + stack);\n        System.out.println(\"Queue: \" + queue);\n        System.out.println(\"--------------------------------\");\n    }\n\n    // DIFICULTAD EXTRA\n\n    static void agendaContactos() {\n        Scanner scanner = new Scanner(System.in);\n        Map<String, String> agenda = new HashMap<>();\n\n        while (true) {\n            System.out.println(\" \");\n            System.out.println(\"Agenda de Contactos\");\n            System.out.println(\" \");\n            System.out.println(\"---------------------------\");\n            System.out.println(\"| 1: Buscar Contacto      |\");\n            System.out.println(\"| 2: Agregar Contacto     |\");\n            System.out.println(\"| 3: Actualizar Contacto  |\");\n            System.out.println(\"| 4: Eliminar Contacto    |\");\n            System.out.println(\"| 5: Salir                |\");\n            System.out.println(\"---------------------------\");\n            System.out.println(\" \");\n            System.out.print(\"+ Seleccione una opción: \");\n            int opcion = scanner.nextInt();\n            scanner.nextLine(); // Consumir el salto de línea después de la opción\n\n            switch (opcion) {\n                case 1:\n                    buscarContacto(agenda, scanner);\n                    break;\n                case 2:\n                    insertarContacto(agenda, scanner);\n                    break;\n                case 3:\n                    actualizarContacto(agenda, scanner);\n                    break;\n                case 4:\n                    eliminarContacto(agenda, scanner);\n                    break;\n                case 5:\n                    System.out.println(\"¡Hasta la proxima!\");\n                    System.exit(0);\n                default:\n                    System.out.println(\"Opción no válida. Inténtalo de nuevo.\");\n            }\n        }\n    }\n\n    private static void buscarContacto(Map<String, String> agenda, Scanner scanner) {\n        System.out.print(\"Ingrese el nombre del contacto a buscar: \");\n        String nombre = scanner.nextLine();\n\n        if (agenda.containsKey(nombre)) {\n            String telefono = agenda.get(nombre);\n            System.out.println(\"Número de teléfono de \" + nombre + \": \" + telefono);\n        } else {\n            System.out.println(\"El contacto no se encuentra en la agenda.\");\n        }\n    }\n\n    private static void insertarContacto(Map<String, String> agenda, Scanner scanner) {\n        System.out.print(\"Ingrese el nombre del contacto: \");\n        String nombre = scanner.nextLine();\n\n        // Verificar que el nombre no esté en la agenda\n        if (agenda.containsKey(nombre)) {\n            System.out.println(\"El contacto ya existe en la agenda.\");\n            return;\n        }\n\n        System.out.print(\"Ingrese el número de teléfono: \");\n        String telefono = scanner.nextLine();\n\n        // Verificar que el número de teléfono sea numérico y tenga 11 dígitos\n        try {\n            validarNumeroTelefono(telefono);\n        } catch (IllegalArgumentException e) {\n            return;\n        }\n\n        agenda.put(nombre, telefono);\n        System.out.println(\"Contacto insertado con éxito.\");\n    }\n\n    private static void actualizarContacto(Map<String, String> agenda, Scanner scanner) {\n        System.out.print(\"Ingrese el nombre del contacto a actualizar: \");\n        String nombre = scanner.nextLine();\n\n        if (agenda.containsKey(nombre)) {\n            System.out.print(\"Ingrese el nuevo número de teléfono: \");\n            String nuevoTelefono = scanner.nextLine();\n\n            // Verificar que el nuevo número de teléfono sea numérico y tenga 11 dígitos\n            try {\n                validarNumeroTelefono(nuevoTelefono);\n            } catch (IllegalArgumentException e) {\n                return;\n            }\n\n            agenda.put(nombre, nuevoTelefono);\n            System.out.println(\"Contacto actualizado con éxito.\");\n        } else {\n            System.out.println(\"El contacto no se encuentra en la agenda.\");\n        }\n    }\n\n    private static void eliminarContacto(Map<String, String> agenda, Scanner scanner) {\n        System.out.print(\"Ingrese el nombre del contacto a eliminar: \");\n        String nombre = scanner.nextLine();\n\n        if (agenda.containsKey(nombre)) {\n            agenda.remove(nombre);\n            System.out.println(\"Contacto eliminado con éxito.\");\n        } else {\n            System.out.println(\"El contacto no se encuentra en la agenda.\");\n        }\n    }\n\n    private static void validarNumeroTelefono(String telefono) {\n        if (!telefono.matches(\"\\\\d{11}\")) {\n            System.out.println(\"Número de teléfono no válido. Debe tener 11 dígitos.\");\n            throw new IllegalArgumentException(\"Número de teléfono no válido\");\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/JuanGuzmanG.java",
    "content": "\nimport java.util.*;\n\npublic class JuanGuzmanG {\n    private static final int maxDigitos = 11;\n    public static void main(String args[]) {\n        Scanner sc = new Scanner(System.in);\n        System.out.println(\"=== ARRAYLIST ===\");\n        //ideal para muchas lecturas\n        ArrayList<String> numeros = new ArrayList<>();\n        //add\n        numeros.add(\"b2\");\n        numeros.add(\"c3\");\n        System.out.println(\"lista original\");\n        listar(numeros);\n        //observar\n        System.out.println(\"get: posicion 1:\" + numeros.get(1));\n        //remover\n        numeros.remove(\"b2\");\n        System.out.println(\"remover posicion 1\");\n        listar(numeros);\n        //actualizar\n        numeros.set(0, \"v2\");\n        System.out.println(\"actualizado posicion 0 con 4\");\n        listar(numeros);\n\n        System.out.println(\"se agrega valores:\");\n        numeros.add(\"v1\");\n        numeros.add(\"a3\");\n        numeros.add(\"b3\");\n        listar(numeros);\n\n        System.out.println(\"lista:\");\n        System.out.println(numeros);\n\n        System.out.println(\"invertir\");\n        System.out.println(numeros.reversed());\n\n        System.out.println(\"ordenar\");\n        Collections.sort(numeros);\n        listar(numeros);\n\n        System.out.println(\"=== LINKEDLIST ===\");\n        //ideal para muchas inserciones y eliminaciones\n        LinkedList<String> linkedlist = new LinkedList<>();\n        linkedlist.add(\"linkedin\");\n        linkedlist.add(\"prueba\");\n        linkedlist.remove(\"prueba\");\n        System.out.println(linkedlist);\n\n        System.out.println(\"=== HASHSET ===\");\n        //ideal solo si importa evitar duplicados\n        //muy rapido\n        HashSet<String> cars = new HashSet<>();\n        cars.add(\"carro1\");\n        cars.add(\"carro2\");\n        cars.remove(\"carro2\");\n        System.out.println(cars);\n        System.out.println(\"modificar carro1 por carro11\");\n        if (cars.contains(\"carro1\")) {\n            cars.remove(\"carro1\");\n            cars.add(\"carro11\");\n            System.out.println(cars);\n        }\n        cars.add(\"carro2\");\n        System.out.println(cars);\n\n        System.out.println(\"=== LINKEDHASHSET===\");\n        //ideal para orden se mantiene tal como se agrega\n        //levemente mas lento que hashset\n        //estructura hashTable + LinkedList\n        //comun en orden de inserción\n        LinkedHashSet<Integer> ordenLinkedHashSet = new LinkedHashSet<>();\n        ordenLinkedHashSet.add(5);\n        ordenLinkedHashSet.add(2);\n        ordenLinkedHashSet.add(1);\n        System.out.println(ordenLinkedHashSet);\n\n        System.out.println(\"===TREESET===\");\n        //ideal siempre ordenado automaticamente\n        //lento, usa estructura Arbol rojo-negro\n        //permite null con restricciones\n        //comun en ordenamiento\n        TreeSet<Integer> arbol = new TreeSet<>();\n        arbol.add(2);\n        arbol.add(3);\n        arbol.add(4);\n        arbol.add(1);\n        System.out.println(arbol);\n\n        //forma de usar null\n        Comparator<Integer> comparator = Comparator.nullsFirst(Integer::compareTo);\n        TreeSet<Integer> set = new TreeSet<>(comparator);\n        set.add(1);\n        set.add(2);\n        set.add(null);\n        System.out.println(set);\n\n        System.out.println(\"===HASHMAP===\");\n        //velocidad y sin importar el orden.\n        HashMap<String, Integer> edades = new HashMap<>();\n        edades.put(\"ana\", 20);\n        edades.put(\"juan\", 10);\n        System.out.println(edades);\n        System.out.println(\"edad de ana: \" + edades.get(\"ana\"));\n\n        System.out.println(\"===LinkedHashMap===\");\n        //velocidad y mantiene el orden de inserción\n        LinkedHashMap<Integer, String> paciente = new LinkedHashMap<>();\n        paciente.put(1, \"paciente1\");\n        paciente.put(2, \"paciente2\");\n        paciente.put(0, \"paciente0\");\n        paciente.put(3, \"paciente3\");\n        System.out.println(paciente);\n\n        System.out.println(\"===TREEMAP===\");\n        //llaves ordenadas y operaciones de rango (llaves entre)\n        TreeMap<Integer, String> estudiantes = new TreeMap<>();\n        estudiantes.put(1, \"juan\");\n        estudiantes.put(3, \"maria\");\n        estudiantes.put(2, \"pepe\");\n        System.out.println(estudiantes);\n\n        System.out.println(\"===QUEUE===\");\n        //sistema de turnos, proceso de orden de llegada\n        //FIFO First in, First Out\n        //offer si no tiene espacio regresa un false - recomendado en colas sin limites\n        //add si no tiene espacio regresa una IllegalStateException - colas con capacidad limitada\n        Queue<String> cola = new LinkedList<>();\n        cola.offer(\"ana\");\n        cola.add(\"pepe\");\n        System.out.println(cola);\n        System.out.println(cola.poll());\n        System.out.println(cola.poll());\n\n        System.out.println(\"=== STACK ===\");\n        //obsoleta\n        //sistema LIFO last in, first out\n        Stack<String> pila = new Stack<>();\n        pila.push(\"A\");\n        pila.push(\"B\");\n        System.out.println(\"completa\");\n        System.out.println(pila);\n        pila.pop();\n        System.out.println(\"pop\");\n        System.out.println(pila);\n\n        System.out.println(\"=== DEQUE ===\");\n        Deque<String> pilaDeque = new ArrayDeque<>();\n        pilaDeque.push(\"A\");\n        pilaDeque.push(\"B\");\n        System.out.println(\"completa\");\n        System.out.println(pilaDeque);\n        pilaDeque.pop();\n        System.out.println(\"pop\");\n        System.out.println(pilaDeque);\n\n        /*        \n        * DIFICULTAD EXTRA (opcional):\n        * Crea una agenda de contactos por terminal.\n        * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n        * - Cada contacto debe tener un nombre y un número de teléfono.\n        * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n        *   los datos necesarios para llevarla a cabo.\n        * - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n        *   (o el número de dígitos que quieras)\n        * - También se debe proponer una operación de finalización del programa.\n         */\n        Map<String, String> contactos = new HashMap<>();\n        contactos.put(\"ana\", \"32919382\");\n\n        boolean on = true;\n        while (on) {\n            String telefono =\"\";\n            String nombre = \"\";\n            System.out.println(\"Agenda de contactos, seleccione la operación\");\n            System.out.println(\" 1. búsqueda\");\n            System.out.println(\" 2. inserción\");\n            System.out.println(\" 3. actualización\");\n            System.out.println(\" 4. eliminación\");\n            System.out.println(\" 5. lista completa\");\n            System.out.print(\"Opción: \");\n            \n            int opcion;\n            try {\n                opcion = Integer.parseInt(sc.nextLine().trim());\n            } catch (NumberFormatException e) {\n                System.out.println(\"opcion invalida, intente de nuevo\");\n                continue;\n            }\n            \n            if(opcion<1 || opcion>6){\n                System.out.println(\"opcion fuera de menu, intente den uevo \\n\");\n                continue;\n            }\n            \n            switch(opcion){\n                case 1 -> {\n                    System.out.println(\"Ingrese el nombre: \");\n                    nombre = sc.nextLine().trim().toLowerCase();\n                    if(contactos.containsKey(nombre)){\n                        System.out.println(nombre+\" Numero: \"+contactos.get(nombre));\n                    } else {\n                        System.out.println(\"No se encontro este contacto\");\n                    }\n                }\n                case 2 -> {\n                    System.out.println(\"Ingrese el nombre del nuevo contacto\");\n                    nombre = sc.nextLine().trim().toLowerCase();\n                    if(nombre.isEmpty()){\n                        System.out.println(\"Nombre invalido\");\n                        break;\n                    } else if(contactos.containsKey(nombre)){\n                        System.out.println(\"ya existe un usuario con este nombre\");\n                        break;\n                    }\n                    System.out.println(\"Ingrese el numero del nuevo contacto, maximo 11 numeros\");\n                    telefono = sc.nextLine().trim();\n                    if(validarTelefono(telefono)==null){\n                        System.out.println(\"Telefono no valido\");\n                        break;\n                    }\n                    contactos.put(nombre,telefono);\n                    System.out.println(\"Se guardo: \"+ nombre +\" con el telefono: \"+telefono);\n                }\n                case 3 -> {\n                    System.out.println(\"Ingrese el nombre del contacto a modificar:\");\n                    nombre = sc.nextLine().trim().toLowerCase();\n                    if(nombre.isEmpty()){\n                        System.out.println(\"Nombre invalido\");\n                        break;\n                    }\n                    if(contactos.containsKey(nombre)){\n                        System.out.println(\"Ingrese el nuevo telefono\");\n                        telefono = sc.nextLine().trim();\n                        if(validarTelefono(telefono)==null){\n                            System.out.println(\"telefono no valido\");\n                            break;\n                        }\n                    }else{\n                        System.out.println(\"No se encontro contacto con este nombre\");\n                        break;\n                    }\n                    System.out.println(\"el contacto: \"+ \n                            nombre +\" con telefono: \"+ contactos.containsKey(nombre));\n                    contactos.put(nombre, telefono);\n                    System.out.println(\"ahora contiene el numero: \"+ contactos.containsKey(nombre));\n                }\n                case 4 -> {\n                    System.out.println(\"ingrese el nombre del contacto a eliminar:\");\n                    nombre = sc.nextLine().trim().toLowerCase();\n                    if(contactos.containsKey(nombre)){\n                        contactos.remove(nombre);\n                        System.out.println(\"contacto eliminado\");\n                    } else {\n                        System.out.println(\"No se encontro contacto con este nombre\");\n                        break;\n                    }\n                }\n                case 5 -> {\n                    System.out.println(contactos);\n                }\n            }\n            \n            System.out.println(\"¿Dese finalizar? si[y] o no[n]\");\n            String finalizar = sc.nextLine().trim();\n            if(finalizar.equalsIgnoreCase(\"y\")){\n                on = false;\n            }\n        }\n        System.out.println(\"finalizo el programa\");\n        sc.close();\n    }\n\n    static String validarTelefono(String t){\n        if(t.matches(\"\\\\d+\") && t.length() <= maxDigitos){\n            return t;\n        } else {\n            return null;\n        }\n    }\n    \n    static void listar(ArrayList<String> numeros) {\n        for (String num : numeros) {\n            System.out.println(num);\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/Karolle.java",
    "content": "import java.util.*;\n\npublic class Karolle {\n  public static void main(String[] args) {\n\n    // Ejemplo de Lista\n    List<String> lista = new ArrayList<>();\n    lista.add(\"Uno\"); // Inserción\n    lista.add(\"Dos\");\n    lista.remove(0); // Borrado\n    lista.set(0, \"Tres\"); // Actualización\n    Collections.sort(lista); // Ordenación\n    System.out.println(\"Lista: \" + lista);\n\n    // Ejemplo de Set\n    Set<String> conjunto = new HashSet<>();\n    conjunto.add(\"Uno\"); // Inserción\n    conjunto.add(\"Dos\");\n    conjunto.remove(\"Uno\"); // Borrado\n    // En un Set no se puede actualizar un elemento específico, necesitas removerlo y luego agregar el nuevo\n    conjunto.add(\"Tres\"); // Actualización simulada\n    List<String> listaParaOrdenar = new ArrayList<>(conjunto);\n    Collections.sort(listaParaOrdenar); // Ordenación\n    System.out.println(\"Conjunto: \" + listaParaOrdenar);\n\n    // Ejemplo de Mapa\n    Map<String, String> mapa = new HashMap<>();\n    mapa.put(\"clave1\", \"valor1\"); // Inserción\n    mapa.put(\"clave2\", \"valor2\");\n    mapa.remove(\"clave1\"); // Borrado\n    mapa.put(\"clave2\", \"valor3\"); // Actualización\n    List<Map.Entry<String, String>> listaDeEntradas = new ArrayList<>(mapa.entrySet());\n    listaDeEntradas.sort(Map.Entry.comparingByKey()); // Ordenación\n    System.out.println(\"Mapa: \" + listaDeEntradas);\n\n    // Ejemplo de Contacto, Agenda\n    Agenda agenda = new Agenda();\n    agenda.agregarContacto(\"Juan\", \"1234567890\");\n    agenda.agregarContacto(\"Maria\", \"0987654321\");\n    agenda.mostrarContactos();\n    agenda.eliminarContacto(\"Juan\");\n    agenda.actualizarContacto(\"Maria\", \"1111111111\");\n    agenda.mostrarContactos();\n}\n}\n\nclass Contacto {\nString nombre;\nString numeroDeTelefono;\n\nContacto(String nombre, String numeroDeTelefono) {\n    this.nombre = nombre;\n    this.numeroDeTelefono = numeroDeTelefono;\n}\n\n\npublic String toString() {\n    return \"Nombre: \" + nombre + \", Número de Teléfono: \" + numeroDeTelefono;\n}\n}\n\nclass Agenda {\nList<Contacto> contactos = new ArrayList<>();\n\nvoid agregarContacto(String nombre, String numeroDeTelefono) {\n    contactos.add(new Contacto(nombre, numeroDeTelefono));\n}\n\nvoid eliminarContacto(String nombre) {\n    contactos.removeIf(contacto -> contacto.nombre.equals(nombre));\n}\n\nvoid actualizarContacto(String nombre, String nuevoNumero) {\n    for (Contacto contacto : contactos) {\n        if (contacto.nombre.equals(nombre)) {\n            contacto.numeroDeTelefono = nuevoNumero;\n            break;\n        }\n    }\n}\n\nvoid mostrarContactos() {\n    for (Contacto contacto : contactos) {\n        System.out.println(contacto);\n    }\n}\n}"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/LdPC999.java",
    "content": "package fundamentos;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Map;\nimport java.util.Scanner;\nimport java.util.TreeMap;\nimport java.util.TreeSet;\n\npublic class Clase03 {\n\t/*\n\t * CLASE 03 - ESTRUCTURAS DE DATOS\n\t * \n\t * EJERCICIO\n\t * \n\t * - Muestra ejemplos de creación de todas las estructuras soportadas por\n\t * defecto en tu lenguaje. - Utiliza operaciones de inserción, borrado,\n\t * actualización y ordenación.\n\t *\n\t * EXTRA\n\t * \n\t * Crea una agenda de contactos por terminal. - Debes implementar\n\t * funcionalidades de búsqueda, inserción, actualización y eliminación de\n\t * contactos. - Cada contacto debe tener un nombre y un número de teléfono. - El\n\t * programa solicita en primer lugar cuál es la operación que se quiere\n\t * realizar, y a continuación los datos necesarios para llevarla a cabo. - El\n\t * programa no puede dejar introducir números de teléfono no numéricos y con más\n\t * de 11 dígitos. - También se debe proponer una operación de finalización del\n\t * programa.\n\t */\n\n\t// EXTRA\n\tpublic static final int MAX_DIGITS = 11;\n\tpublic static Map<String, String> contactos = new HashMap<>();\n\n\tpublic static void extra() {\n\t\tScanner sc = new Scanner(System.in);\n\t\tboolean on = true;\n\n\t\tSystem.out.println(\"------ Bienvenido a la Agenda ------\");\n\n\t\twhile (on) {\n\t\t\tSystem.out.println(\"Menu: \\n\");\n\t\t\tSystem.out.println(\"Insertar contacto - Pulse 1\");\n\t\t\tSystem.out.println(\"Buscar contacto - Pulse 2\");\n\t\t\tSystem.out.println(\"Actualizar contacto - Pulse 3\");\n\t\t\tSystem.out.println(\"Eliminar contacto - Pulse 4\");\n\t\t\tSystem.out.println(\"Mostrar todos los contactos - Pulse 5\");\n\t\t\tSystem.out.println(\"Salir - Pulse 6\\n\");\n\t\t\tSystem.out.println(\"Seleccione una opción\");\n\n\t\t\tString option = sc.nextLine();\n\n\t\t\tswitch (option) {\n\t\t\tcase \"1\":\n\t\t\t\tinsertarContacto(sc);\n\t\t\t\tbreak;\n\t\t\tcase \"2\":\n\t\t\t\tbuscarContacto(sc);\n\t\t\t\tbreak;\n\t\t\tcase \"3\":\n\t\t\t\tactualizarContacto(sc);\n\t\t\t\tbreak;\n\t\t\tcase \"4\":\n\t\t\t\teliminarContacto(sc);\n\t\t\t\tbreak;\n\t\t\tcase \"5\":\n\t\t\t\tmostrarTodos();\n\t\t\t\tbreak;\n\t\t\tcase \"6\":\n\t\t\t\ton = false;\n\t\t\t\tSystem.out.println(\"Hasta pronto\");\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tSystem.out.println(\"Opción no válida\");\n\n\t\t\t}\n\t\t}\n\n\t\tsc.close();\n\t}\n\n\tpublic static void insertarContacto(Scanner sc) {\n\t\tSystem.out.println(\"Introduzca el nombre del contacto: \");\n\t\tString nombre = sc.nextLine().trim();\n\n\t\tif (contactos.containsKey(nombre)) {\n\t\t\tSystem.out.println(\"El contacto introducido ya existe\");\n\t\t\treturn;\n\t\t} else {\n\n\t\t\tString telefono = \"\";\n\t\t\twhile (true) {\n\t\t\t\tSystem.out.println(\"Introduzca el número de teléfono. (Escriba salir para volver al menú\");\n\t\t\t\ttelefono = sc.nextLine().trim();\n\n\t\t\t\tif (telefono.equalsIgnoreCase(\"salir\")) {\n\t\t\t\t\tSystem.out.println(\"Volviendo al menú\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (isValid(telefono)) {\n\t\t\t\t\tcontactos.put(nombre, telefono);\n\t\t\t\t\tSystem.out.println(\"Contacto guardado correctamente\");\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\tSystem.out.println(\"Número no válido. Máximo 11 dígitos\");\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\t}\n\n\tpublic static void buscarContacto(Scanner sc) {\n\t\tSystem.out.println(\"Introduzca el nombre del contacto\");\n\t\tString nombre = sc.nextLine().trim();\n\n\t\tif (contactos.containsKey(nombre)) {\n\t\t\tSystem.out.println(\"Contacto encontrado: \" + nombre + \" -> \" + contactos.get(nombre));\n\n\t\t} else {\n\t\t\tSystem.out.println(\"Contacto no encontrado\");\n\t\t}\n\t}\n\n\tpublic static void actualizarContacto(Scanner sc) {\n\t\tSystem.out.println(\"Introduzca el nombre del contacto a actualizar\");\n\t\tString nombre = sc.nextLine().trim();\n\n\t\tif (contactos.containsKey(nombre)) {\n\t\t\tString telNuevo = \"\";\n\t\t\twhile (true) {\n\t\t\t\tSystem.out.println(\n\t\t\t\t\t\t\"Introduzca el nuevo número. Máximo 11 dígitos (Escribe salir para cancelar y volver al menú)\");\n\t\t\t\ttelNuevo = sc.nextLine().trim();\n\n\t\t\t\tif (telNuevo.equalsIgnoreCase(\"salir\")) {\n\t\t\t\t\tSystem.out.println(\"Volviendo al menu\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (isValid(telNuevo)) {\n\t\t\t\t\tcontactos.put(nombre, telNuevo);\n\t\t\t\t\tSystem.out.println(\"Contacto actualizado\");\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\tSystem.out.println(\"Número de teléfono no válido. Máximo 11 dígitos\");\n\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tSystem.out.println(\"Contacto no encontrado\");\n\t\t}\n\t}\n\n\tpublic static void eliminarContacto(Scanner sc) {\n\t\tSystem.out.println(\"Introduzca el nombre del contacto\");\n\t\tString nombre = sc.nextLine().trim();\n\n\t\tif (contactos.containsKey(nombre)) {\n\t\t\tcontactos.remove(nombre);\n\t\t\tSystem.out.println(\"Contacto eliminado correctamente\");\n\t\t} else {\n\t\t\tSystem.out.println(\"Contacto no encontrado\");\n\t\t}\n\t}\n\n\tpublic static void mostrarTodos() {\n\t\tif (contactos.isEmpty()) {\n\t\t\tSystem.out.println(\"La agenda está vacía\");\n\t\t} else {\n\t\t\tSystem.out.println(\"Lista de contactos\");\n\t\t\tcontactos.forEach((nombre, telefono) -> System.out.println(nombre + \" -> \" + telefono));\n\t\t}\n\t}\n\n\tpublic static boolean isValid(String telefono) {\n\t\treturn telefono.matches(\"\\\\d{1,\" + MAX_DIGITS + \"}\");\n\t}\n\n\tpublic static void main(String[] args) {\n\n\t\t// ESTRUCTURAS DE DATOS - Formas de almacenar y organizar datos\n\n\t\t// 1.- ArrayList - Es un array redimensionable al que añadimos elementos y\n\t\t// accedemos a ellos por índices.\n\t\t// Creación new ArrayList<String>();\n\t\tArrayList<String> nombres = new ArrayList<>();\n\n\t\t// Inserción - .add(\"\");\n\t\t// Si lo queremos en alguna posición concreta .add(0,\"\");\n\t\tnombres.add(\"Luis\");\n\t\tnombres.add(\"Pepe\");\n\t\tnombres.add(\"Juan\");\n\t\tnombres.add(\"Javier\");\n\t\tnombres.add(0, \"Álvaro\");\n\t\tnombres.add(\"Alvaro\");\n\n\t\t// Eliminación - .remove(index o elemento);\n\t\tnombres.remove(3);\n\t\tnombres.remove(\"Javier\");\n\n\t\t// Actualizar - .set(0, elemento); Machacamos uno por otro\n\t\tnombres.set(0, \"LoL\");\n\t\tSystem.out.println(\"ArrayList: \" + nombres);\n\n\t\t// Ordenar - Collections.sort(ArrayList)\n\t\t// Para orden inverso Collections.reverseOrder()\n\t\tCollections.sort(nombres);\n\n\t\tSystem.out.println(\"ArrayList: \" + nombres);\n\n\t\t// 2.- HashSet\n\t\t/*\n\t\t * Set no admita duplicados HashSet no es ordenado (Para eso TreeSet o\n\t\t * LinkedHashSet)\n\t\t */\n\n\t\t// Creación - HashSet<String> xxxx = new HashSet<String>();\n\t\tHashSet<String> mySet = new HashSet<>();\n\n\t\t// Insertar - .add()\n\t\tmySet.add(\"Luis\");\n\t\tmySet.add(\"Wuizi\");\n\t\tmySet.add(\"36\");\n\t\tmySet.add(\"LoL\");\n\t\tmySet.add(\"Wuizi\"); // Aunque lo añada dos veces no lo duplica\n\n\t\t// Eliminar - .remove();\n\t\tmySet.remove(\"LoL\");\n\n\t\t// Ordenación - No se puede, tendríamos que usar TreeSet\n\t\tTreeSet<String> myTreeSet = new TreeSet<>();\n\t\tmyTreeSet.add(\"Wuizi\");\n\t\tmyTreeSet.add(\"Luis\");\n\t\tmyTreeSet.add(\"36\");\n\t\tmyTreeSet.add(\"LoL\");\n\t\tSystem.out.println(\"TreeSet: \" + myTreeSet);\n\n\t\tSystem.out.println(\"HashSet: \" + mySet);\n\n\t\t// 3.- HashMap - Diccionario clave - valor (key/value)\n\n\t\t// Creación\n\t\tHashMap<String, String> capitalesPaises = new HashMap<>();\n\n\t\t// Inserción - .put(key, value)\n\t\tcapitalesPaises.put(\"Inglaterra\", \"Londres\");\n\t\tcapitalesPaises.put(\"España\", \"Madrid\");\n\t\tcapitalesPaises.put(\"Francia\", \"Paris\");\n\t\tcapitalesPaises.put(\"Italia\", \"Turín\");\n\t\tSystem.out.println(\"HashMap antes de actualizar: \" + capitalesPaises);\n\n\t\t// Eliminar - .remove(Key);\n\t\tcapitalesPaises.remove(\"Inglaterra\");\n\n\t\t// Actualizar - .put(Key, value) Machacamos el valor de una clave\n\t\tcapitalesPaises.put(\"Italia\", \"Roma\");\n\n\t\tSystem.out.println(\"HashMap después de actualizar: \" + capitalesPaises);\n\n\t\t// Ordenar - Hash no se puede ordenar, hay que usar Tree\n\t\tTreeMap<String, String> capitalesPaisesTree = new TreeMap<>();\n\n\t\tcapitalesPaisesTree.put(\"Inglaterra\", \"Londres\");\n\t\tcapitalesPaisesTree.put(\"España\", \"Madrid\");\n\t\tcapitalesPaisesTree.put(\"Francia\", \"Paris\");\n\n\t\tSystem.out.println(\"TreeMap: \" + capitalesPaisesTree);\n\n\t\t// EXTRA\n\t\textra();\n\n\t}\n\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/Ldre3.java",
    "content": "import java.util.*;\n\npublic class Ldre3 {\n    private static HashMap<String, Integer> agenda = new HashMap<>();\n\n    public static void main(String[] args) {\n        int [] array = new int[5];\n        for(int i = 0; i < array.length; i++) {\n          array[i] = i;\n        }\n\n        ArrayList<String> lista = new ArrayList<>();\n        lista.add(\"Elemento 1\");\n        lista.add(\"Elemento 2\");\n        Collections.sort(lista);\n        lista.remove(1);\n\n\n        HashSet<Integer> set = new HashSet<>();\n        set.add(1);\n        set.add(2);\n        set.add(3);\n        set.removeIf(n -> n%2 == 0);\n\n        HashMap<String, Integer> mapa = new HashMap<>();\n        mapa.put(\"A\",1);\n        mapa.put(\"B\",2);\n        Integer clave = mapa.get(\"A\");\n\n\n        /*\n         * DIFICULTAD EXTRA (opcional):\n         * Crea una agenda de contactos por terminal.\n         * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n         * - Cada contacto debe tener un nombre y un número de teléfono.\n         * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n         *   los datos necesarios para llevarla a cabo.\n         * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n         *   (o el número de dígitos que quieras)\n         * - También se debe proponer una operación de finalización del programa.\n         */\n        boolean salir = false;\n        int opcion;\n        Scanner ent = new Scanner(System.in);\n        while (!salir){\n            System.out.println(\"Introduce una opcion 1. Busqueda 2. Insertar 3. Actualizacion 4. Eliminacion 5.Salir\");\n            opcion = ent.nextInt();\n            ent.nextLine();\n            switch (opcion){\n                case 1 -> {\n                    System.out.println(\"Introduce el nombre a buscar\");\n                    String busqueda = ent.nextLine();\n                    Optional <Integer> telefono = busquedaContacto(busqueda);\n                    String mostrar = telefono.map(integer -> \"El numero de \"+ busqueda+\" es \" + integer).orElse(\"No existe el contacto\");\n                    System.out.println(mostrar);\n                }\n                case 2 -> {\n                    System.out.println(\"Introduce el nombre a introducir\");\n                    String nombre = ent.nextLine();\n                    System.out.println(\"Introduce el telefono a introducir\");\n                    int telefono = ent.nextInt();\n                    ent.nextLine();\n                    if (insertarContacto(nombre, telefono)) System.out.println(\"Contacto insertado\");\n                    else System.out.println(\"El contacto ya existe\");\n\n                }\n                case 3 -> {\n                    System.out.println(\"Introduce el nombre a actualizar\");\n                    String nombre = ent.nextLine();\n                    System.out.println(\"Introduce el telefono a actualizar\");\n                    int telefono = ent.nextInt();\n                    ent.nextLine();\n                    if (actualizar(nombre, telefono)) System.out.println(\"Contacto actualizado\");\n                    else System.out.println(\"El contacto no existe\");\n                }\n\n                case 4 -> {\n                    System.out.println(\"Introduce el nombre a eliminar\");\n                    String nombre = ent.nextLine();\n\n                    if (eliminar(nombre)) System.out.println(\"Contacto eliminado\");\n                    else System.out.println(\"El contacto no existe\");\n                }\n\n                case 5 -> {\n                    salir=true;\n                }\n            }\n        }\n\n    }\n    private static Optional<Integer> busquedaContacto(String nombre){\n        return Optional.ofNullable(agenda.get(nombre));\n    }\n\n    private static boolean insertarContacto (String nombre, int telefono){\n        if (String.valueOf(telefono).length()>9) throw new IllegalArgumentException(\"El numero no puede tener mas de 9 digitos\");\n        return agenda.putIfAbsent(nombre, telefono) == null;\n    }\n\n    private static boolean actualizar (String nombre, int telefono){\n        if (String.valueOf(telefono).length()>9) throw new IllegalArgumentException(\"El numero no puede tener mas de 9 digitos\");\n        return agenda.replace(nombre, telefono) != null;\n    }\n\n    private static boolean eliminar (String nombre){\n        return agenda.remove(nombre) != null;\n    }\n}"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/LucasAG01.java",
    "content": "import java.util.*;\n\npublic class LucasAG01 {\n\n    /*\n    Estructuras de datos son elemntos fundamentales en la programacion que permiten organizar y almacenar datos de una forma eficiente.\n\n    Actuan como cimiento para construir aplicaciones y algoritmos\n\n    Hay que elegir la estructura adecuada de datos, ya que entran aquí puntos esenciales como La optimización del rendimeinto, La organización en si, La reutilización del código,\n    y facilitar ka resolucion de problemas\n\n     */\n\n    public static void main(String[] args) {\n\n    /*\n    ARRAYS :\n    Son colecciones de elemntos del mismo tipo, accesibles a traves de un inidice, Son estáticos, lo que significa que no podemos cambiar su tamaño después de crearlos\n     */\n        int[] arreglo = new int[5]; //creamos un array de 10 valores de tipo int\n        int[][] arreglo2 = new int[5][5]; //bidimensional\n\n\n        arreglo[0] = 1; //Selecciono la posicion, y lo que le añado\n        arreglo[1] = 2;\n        arreglo[2] = 3;\n        arreglo[3] = 4;\n        arreglo[4] = 5;\n\n        //Otra forma tambín puede ser int[] arreglo = {1,2,3,4,5};\n        //Recorramos el array para printarlo\n        for (int num : arreglo) {\n            System.out.println(num);\n        }\n\n    /*\n    ARRAYLIST\n        Esta coleccion es de tipo dinámica, es decir, despues de creada la podemos ir modificando en funcion de nuestras necesidades, aparte tienen metodos incorporados para\n        modificarlas\n     */\n\n        ArrayList<String> nombres = new ArrayList<>();\n\n        nombres.add(\"Lucas\");\n        nombres.add(\"Ana\");\n        nombres.add(\"Pedro\");\n        System.out.println(nombres); //se imprime la lista\n        //para acceder a los metodos se pone nombre. y aparecera muchas cosas\n\n\n    /*\n    LINKEDLIST\n        Es una lista enlazada que permite inserciones y eliminaciones efeicientes Ideal cuando se necesita acceder y manipular elementos en ambas direcciones\n    */\n\n        LinkedList<String> nombres2 = new LinkedList<>();\n        nombres2.add(\"Ana\");\n        nombres2.add(\"Pedro\");\n        nombres2.add(\"Lucas\");\n        System.out.println(nombres2);\n\n    /*\n    HASHMAP\n        Esta estructura, alamcena pares clave-valor\n         veremos ejemplo complejos para lañdir mas cosas y los ordena por orden alfabetico en este caso\n     */\n        HashMap<String, Integer> edades = new HashMap<>();\n        edades.put(\"Pedro\", 23);\n        edades.put(\"Ana\", 33);\n        edades.put(\"Lucas\", 22);\n        System.out.println(edades); //todo\n        System.out.println(edades.get(\"Pedro\")); //solo pedro\n        for (String key : edades.keySet()) {\n            System.out.println(key + \" -> \" + edades.get(key));\n        }\n\n\n    /*\n    HASHSET\n        Es una colección que almacena elemtos únicos sin mantener ningún order específico. Ideal para evitar duplicados\n    */\n        HashSet<String> nombresSet = new HashSet<>();\n        nombresSet.add(\"Pedro\");\n        nombresSet.add(\"Ana\");\n        nombresSet.add(\"Lucas\");\n        nombresSet.add(\"Lucas\");\n        System.out.println(nombresSet); //Cuando lo imprima, solo habrá 1 Lucas, el IDE ya me avisa de ello\n\n    /*\n    TREESET\n        Implementacion del Set que alamcena elementos de forma ordenada (por defecto en orden natural)\n     */\n\n        TreeSet<String> nombresTreeSet = new TreeSet<>(); //El parectesis que hay al lado del new, podemos poner el nombre de otra lista creada y así no escribir mas\n        nombresTreeSet.add(\"Pedro\");\n        nombresTreeSet.add(\"Ana\");\n        nombresTreeSet.add(\"Lucas\");\n        System.out.println(nombresTreeSet); //[Ana, Lucas, Pedro]\n\n    /*\n    QUEUE (LinkedList)\n         Queue es una estructura FIFO (First In, First Out). LinkedList se puede usar para implementar una cola.\n     */\n        Queue<String> cola = new LinkedList<>();\n        cola.add(\"Lucas\");\n        cola.add(\"Pedro\");\n        cola.add(\"Ana\");\n        System.out.println(cola.poll());// Imprimimos y removemos el primer elemento en la cola, en este caso, saldrá por pantalla Lucas, pero al volver a ejecutar el cola.poll() , aparecera Pedro\n\n\n    /*\n    PRIORITYQUEUE\n            Ordena los elementos de forma natural o por un comparador proporcionado\n     */\n\n        PriorityQueue<Integer> colaPrioridad = new PriorityQueue<>();\n\n        colaPrioridad.add(23);\n        colaPrioridad.add(33);\n        colaPrioridad.add(22);\n        System.out.println(colaPrioridad.poll()); //Imprimimos y removemos el elemento con la mayor prioridad Si son sumeros del pequeño al grande\n\n    /*\n    STACK\n        Estructura LIFO (last in m First out)\n     */\n        Stack<String> pila = new Stack<>();\n\n        pila.push(\"Lucas\");\n        pila.push(\"Pedro\");\n        pila.push(\"Ana\");\n\n        System.out.println(pila.pop()); //Imprimimos y removemos el último elemento agregado (LIFO)\n\n\n    /*\n    DEQUE (ArrayDeque)\n        Cola de doble extremo que permite agregar y eliminar elemntos de ambos extremos\n     */\n        ArrayDeque<String> deque = new ArrayDeque<>();\n\n        deque.addFirst(\"Pimero\");\n        deque.addLast(\"Ultimo\");\n        deque.push(\"Lucas\"); //equivalente a addLast\n\n        System.out.println(deque.pollFirst());\n        System.out.println(deque.pollLast());\n        System.out.println(deque);\n\n\n    /*\n     HASHTABLE\n        Similar a HashMap, pero es sincronizado y no permite claves ni valores nulos\n     */\n        Hashtable<String, Integer> hash = new Hashtable<>();\n\n        hash.put(\"Pedro\", 23);\n        hash.put(\"Ana\", 33);\n        hash.put(\"Lucas\", 22);\n        System.out.println(hash);\n\n\n    /*\n    LINKEDHASHMAP\n        Mantiene el orden de insercion de elmentos no los ordena como el HashMap\n     */\n        LinkedHashMap<String, Integer> linkedHashMap = new LinkedHashMap<>();\n        linkedHashMap.put(\"Pedro\", 23);\n        linkedHashMap.put(\"Ana\", 33);\n        linkedHashMap.put(\"Lucas\", 22);\n        System.out.println(linkedHashMap);\n\n\n    /*\n    TREEMAP\n        Mapa ordenado que ordena las claves de forma natural o con comparador no claves nulas.\n        En el HashMap, los elementos no están en ningún orden específico, mientras que en el TreeMap,\n        los elementos están ordenados alfabéticamente por las claves.\n\n    */\n        TreeMap<String, Integer> mapaOrdenadoPorClave = new TreeMap<>(); // Creamos un TreeMap\n\n        mapaOrdenadoPorClave.put(\"Pedro\", 25);\n        mapaOrdenadoPorClave.put(\"Ana\", 30);\n        mapaOrdenadoPorClave.put(\"Lucas\", 22);\n        System.out.println(mapaOrdenadoPorClave); // Imprimimos todo el TreeMap\n        for (String key : mapaOrdenadoPorClave.keySet()) {\n            System.out.println(key + \" -> \" + mapaOrdenadoPorClave.get(key));\n        }\n\n\n\n\n        //Agengfa del ejercicio\n\n        HashMap<String,Integer> agenda = new HashMap<>();\n\n        // Primero sacamos el scanner Peticion\n        Scanner scanner = new Scanner(System.in);\n\n        int opiconElexida=0;\n\n\n        //Hay que hacer un bucle con los case y dentro de cada case la opcion\n\n        while (opiconElexida!=6) {\n\n            System.out.println(\"\"\"\n                     /*/*/*/*/ AGENDA TELEFÓNICA /*/*/*/\n                     \n                     1.Buscar contacto\n                     2.Añadir contacto\n                     3.Modificar contacto\n                     4.Borrar contacto\n                     5.Ver todos\n                     6.Salir\n                         \n                    \"\"\");\n\n            opiconElexida = scanner.nextInt();\n            switch (opiconElexida) {\n                case 1:\n                    BuscarContaco(agenda);\n                    break;\n                case 2:\n                    AgregarContacto(agenda,scanner);\n                    break;\n                case 3:\n                    ModificarContacto(agenda,scanner);\n                    break;\n                case 4:\n                    BorrarContacto(agenda,scanner);\n                    break;\n                case 5:\n                    verContactos(agenda);\n                    break;\n                case 6:\n                    System.out.println(\"No tengo ni puta idea de como voy a aprender esto xddd\");\n                    break;\n\n\n\n\n            }\n\n\n        }\n\n    }\n\n    //LA FORMA MAS SENCIALLA DE HACER EL MENU ES CREANO FUERA LOS MÉTODOS\n\n    //En los métodos que te he mostrado, se usan agenda y scanner como parámetros porque estos son necesarios para que los métodos funcionen correctamente.\n    //Scanner scanner sale del scanner del menu. sirve para utilizar ese scanner y que vaya mejor el programa.\n\n    /*\n    Cosas Importanmtes aprendidas:\n    -En el sout, poniendo \"\"\" puedo hacer lo que quiera de forma más cómoda a la hora de crear menús.\n    -Dependiendo de lo que pidan hay que revisar que tipo de estructura te viene mejor.\n    - Es importante respetar el orden de KEY, VALUE\n    -metodos de containskey, contains value\n    -metodo de String.valueOf(telefonoContacto) sirve para converttir un int en un String\n    -cuando una opcion requiere que le usuario ponga algo de nuevo si se equivoca, es importante hacer un while en vez de un IF\n    -el bucle de imprimir maps for (Map.Entry<String, Integer> entry : agenda.entrySet())\n\n    -Para crear una función, hay que ir desglosandolo poco a poco, un analisis de un problema, para tatra de encontrar la solución adecuada\n    por ejemplo, tenemos qué queremos que sea le resultado basico ej: porner nombre y poner numero\n    ahora podemos crear los criterios como por ejemplo si el numero es x digitois de largo, ahí sabemos que la forma mas facil de contar los caracteres es en un String y existe\n    el método de convertir el int a String\n\n    -Es importante saber que la reutilizacion es usando los pasos de atrás vamos hacia delante. PERO hay que crear una función apropiada para reutilizar, en el caso de la linea 336.\n    -Se puede complicar de una manera LOCA\n\n\n\n\n\n     */\n\n    public static void BuscarContaco(Map<String, Integer> agenda) {\n        Scanner scanner = new Scanner(System.in);\n        System.out.println(\"Introduce el nombre del contacto: \");\n        String nombre = scanner.nextLine();\n\n        if (agenda.containsKey(nombre)) {\n            System.out.println(nombre +\":\"+ agenda.get(nombre)+ \"\\n\");\n        }else {\n            System.out.println(\"El contacto no existe\"+ nombre +\"\\n\");\n        }\n\n    }\n\n    public static void AgregarContacto(Map<String, Integer> agenda, Scanner scanner) {\n        System.out.println(\"Introduce el nombre del contacto: \");\n        String nombreContacto = scanner.nextLine();\n\n        System.out.println(\"Introduce el telefono RECUERDA QUER SON 9 CIFRAS\");\n        int telefonoContacto = scanner.nextInt();\n\n\n        while (String.valueOf(telefonoContacto).length()==9 || agenda.containsValue(telefonoContacto)){\n\n            if(String.valueOf(telefonoContacto).length()!=9){\n                System.out.println(\"9 CIFRAS\");\n                telefonoContacto = scanner.nextInt();\n            } else if (agenda.containsValue(telefonoContacto)) {\n                System.out.println(\"Error el número\"+telefonoContacto+\" ya existe en la agenda\");\n                telefonoContacto= scanner.nextInt();\n            }\n\n            agenda.put (nombreContacto,telefonoContacto);\n\n            System.out.println(\"El nombre \"+nombreContacto+ \" de numero \"+telefonoContacto+ \" se ha gregado.\\n\");\n\n\n        }\n\n\n    }\n\n    public static void ModificarContacto (Map<String,Integer>agenda, Scanner scanner){\n        System.out.println(\"Introduce el nombre del contacto a MODIFICAR\");\n        String nombreMod = scanner.nextLine();\n\n\n        if(!agenda.containsKey(nombreMod)){\n            System.out.println(\"Contacto no encontrado... dale otro try\");\n            ModificarContacto(agenda,scanner);\n\n        }else {\n            //No hay forma de usar el metodo replace.\n            agenda.remove(nombreMod);\n\n            //AgregarContacto(agenda,scanner); si reutilizase de buena manera el codigo si no lo modifico, haria esto y lo de abajo me lo ahorro.\n            //copiamos EL bloque de añadir contacto.\n            System.out.println(\"Introduce el nombre del contacto: \");\n            String nombreContacto = scanner.nextLine();\n\n            System.out.println(\"Introduce el telefono RECUERDA QUER SON 9 CIFRAS\");\n            int telefonoContacto = scanner.nextInt();\n\n\n            while (String.valueOf(telefonoContacto).length()==9 || agenda.containsValue(telefonoContacto)){\n\n                if(String.valueOf(telefonoContacto).length()!=9){\n                    System.out.println(\"9 CIFRAS\");\n                    telefonoContacto = scanner.nextInt();\n                } else if (agenda.containsValue(telefonoContacto)) {\n                    System.out.println(\"Error el número\"+telefonoContacto+\" ya existe en la agenda\");\n                    telefonoContacto= scanner.nextInt();\n                }\n\n                agenda.put (nombreContacto,telefonoContacto);\n\n                System.out.println(\"El nombre \"+nombreContacto+ \" de numero \"+telefonoContacto+ \" se ha MODIFICADO.\\n\");\n\n            }\n        }\n    }\n\n    public static void BorrarContacto (Map<String,Integer>agenda, Scanner scanner){\n        System.out.println(\"Introduzca el numero del contacto a eliminar\");\n        String numeroContacto = scanner.nextLine();\n\n        if (agenda.containsKey(numeroContacto)) {\n        String nombre= null;\n\n        for(Map.Entry<String ,Integer> entry : agenda.entrySet()){\n            if(entry.getKey().equals(numeroContacto)){\n                nombre= entry.getValue().toString();\n            }\n            break;\n        }\n        agenda.remove(numeroContacto);\n\n            System.out.println(\"Contacto \"+nombre+ \" con número \"+numeroContacto+ \" se ha eliminado.\\n\");\n\n        }else{\n            System.out.println(\"Numenro ingresado no existe.\\n \");\n        }\n    }\n\n    public static void verContactos (Map<String,Integer>agenda){\n        for (Map.Entry<String, Integer> entry : agenda.entrySet()) {\n            System.out.println(\"Nombre: \" + entry.getValue() + \", Número: \" + entry.getKey());\n        }\n\n    }\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/Marianoemir.java",
    "content": "\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.LinkedList;\nimport java.util.Map;\nimport java.util.Scanner;\nimport java.util.TreeMap;\n\n/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto\n *   en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n */\nclass Marianoemir {\n\n    public static void main(String[] args) {\n\n        //Array \n        //Creación\n        int[] numeros = {9, 4, 2, 8, 10};\n\n        //Actualización\n        numeros[1] = 5;\n\n        //Ordenación\n        Arrays.sort(numeros);\n\n        //Mostrar Array\n        for (int num : numeros) {\n            System.out.println(num);\n        }\n\n        //ArrayList\n        //Creación\n        ArrayList<String> lista = new ArrayList<>();\n\n        //Inserciòn\n        lista.add(\"Ford\");\n        lista.add(\"Toyota\");\n        lista.add(\"Fiat\");\n        lista.add(\"Alfa Romeo\");\n\n        //Borrado\n        lista.remove(\"Fiat\");\n\n        //Actualización\n        lista.set(0, \"Ferrari\");\n\n        //Ordenación\n        Collections.sort(lista);\n\n        //Mostrar ArrayList\n        for (String autos : lista) {\n            System.out.println(autos);\n        }\n\n        //HashMap\n        //Creación\n        HashMap<Integer, String> mapa = new HashMap<>();\n\n        //Inserciòn\n        mapa.put(1, \"Uno\");\n        mapa.put(2, \"Dos\");\n        mapa.put(3, \"Tres\");\n\n        //Borrado\n        mapa.remove(2);\n\n        //Actualización\n        mapa.put(1, \"Actualización de uno\");\n\n        //Mostrar HashMap\n        for (Map.Entry<Integer, String> entry : mapa.entrySet()) {\n            System.out.println(\"Clave: \" + entry.getKey() + \", Valor: \" + entry.getValue());\n        }\n\n        //HashSet\n        //Creación\n        HashSet<String> conjunto = new HashSet<>();\n\n        //Inserción\n        conjunto.add(\"A\");\n        conjunto.add(\"B\");\n        conjunto.add(\"C\");\n\n        //Borrado\n        conjunto.remove(\"B\");\n\n        //Mostrar HashSet\n        for (String elemento : conjunto) {\n            System.out.println(elemento);\n        }\n\n        //LinkedList\n        //Creación\n        LinkedList<String> listaEnlazada = new LinkedList<>();\n\n        //Inserción \n        listaEnlazada.add(\"Rojo\");\n        listaEnlazada.add(\"Azul\");\n        listaEnlazada.add(\"Verde\");\n\n        //Inserción en una posición especifica\n        listaEnlazada.add(1, \"Amarilla\");\n\n        //Borrado\n        listaEnlazada.remove(\"Azul\");\n\n        //Actualizaciòn\n        listaEnlazada.set(2, \"Morado\");\n\n        //Ordenación\n        Collections.sort(listaEnlazada);\n\n        for (String color : listaEnlazada) {\n            System.out.println(color);\n        }\n\n        /*\n        * DIFICULTAD EXTRA (opcional):\n        * Crea una agenda de contactos por terminal.\n        * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n        *   y eliminación de contactos.\n        * - Cada contacto debe tener un nombre y un número de teléfono.\n        * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n        *   y a continuación los datos necesarios para llevarla a cabo.\n        * - El programa no puede dejar introducir números de teléfono no númericos y con más\n        *   de 11 dígitos (o el número de dígitos que quieras).\n        * - También se debe proponer una operación de finalización del programa.\n         */\n        HashMap<String, String> agenda = new HashMap<>();\n        ;\n\n        Scanner sc = new Scanner(System.in);\n        String entrada1, entrada2;\n        int menu = 0;\n        boolean condi = true;\n        boolean telefonoValido = false;\n        boolean condifinal = true;\n\n        do {\n\n            System.out.println(\"¿Qué operación desea realizar?\");\n            System.out.println(\"1. Agregar un número a la agenda\");\n            System.out.println(\"2. Actualizar un número de la agenda\");\n            System.out.println(\"3. Eliminar contactos de la agenda\");\n            System.out.println(\"4. Salir del Programa.\");\n            menu = sc.nextInt();\n            sc.nextLine();\n\n            switch (menu) {\n                case 1:\n                    do {\n                        do {\n                            System.out.println(\"Ingrese el Nombre:\");\n                            entrada1 = sc.nextLine();\n\n                            System.out.println(\"Ingrese el Telefono:\");\n                            entrada2 = sc.nextLine();\n\n                            if (entrada2.matches(\"\\\\d{11}\")) {\n                                telefonoValido = true;\n                                agenda.put(entrada1, entrada2);\n                            } else {\n                                System.out.println(\"El teléfono debe contener exactamente 11 dígitos numéricos.\");\n                            }\n                        } while (!telefonoValido); // Repite hasta que el teléfono sea válido\n\n                        String respuesta;\n                        boolean respuestaValida = false;\n\n                        do {\n                            System.out.println(\"¿Desea continuar ingresando números? S=Sí/N=No\");\n                            respuesta = sc.nextLine().trim().toUpperCase();\n\n                            if (respuesta.equals(\"S\")) {\n                                condi = true;\n                                respuestaValida = true;\n                            } else if (respuesta.equals(\"N\")) {\n                                condi = false;\n                                respuestaValida = true;\n                            } else {\n                                System.out.println(\"Por favor, ingrese solo 'S' o 'N'.\");\n                            }\n                        } while (!respuestaValida);\n\n                    } while (condi);\n                    break;\n                    \n                case 2:\n                    if (agenda.isEmpty()) {\n                        System.out.println(\"La agenda está vacía.\");\n                    } else {\n                        int contador = 1;  // Contador para numerar los contactos\n                        HashMap<Integer, String> indiceAgenda = new HashMap<>();  // Para mapear el número a la clave\n\n                        // Mostrar la agenda con un índice numérico\n                        for (Map.Entry<String, String> entry : agenda.entrySet()) {\n                            System.out.println(contador + \". Nombre: \" + entry.getKey() + \", Número: \" + entry.getValue());\n                            indiceAgenda.put(contador, entry.getKey());  // Mapeo del índice al nombre\n                            contador++;\n                        }\n\n                        // Pedir al usuario que seleccione un número\n                        System.out.println(\"Ingrese el número del contacto que desea actualizar:\");\n                        int seleccion = sc.nextInt();\n                        sc.nextLine();  // Consumir el salto de línea\n\n                        // Validar que la selección sea válida\n                        if (indiceAgenda.containsKey(seleccion)) {\n                            String nombreSeleccionado = indiceAgenda.get(seleccion);\n                            System.out.println(\"Ha seleccionado: \" + nombreSeleccionado);\n\n                            // Preguntar qué desea modificar\n                            System.out.println(\"¿Qué desea modificar?\");\n                            System.out.println(\"1. Solo el número de teléfono\");\n                            System.out.println(\"2. Solo el nombre\");\n                            System.out.println(\"3. Ambos\");\n\n                            int opcion = sc.nextInt();\n                            sc.nextLine();  // Consumir el salto de línea\n\n                            switch (opcion) {\n                                case 1:\n                                    // Modificar solo el número de teléfono\n                                    System.out.println(\"Ingrese el nuevo número de teléfono:\");\n                                    String nuevoNumero = sc.nextLine();\n                                    if (nuevoNumero.matches(\"\\\\d{11}\")) {\n                                        agenda.put(nombreSeleccionado, nuevoNumero);\n                                        System.out.println(\"Número actualizado correctamente.\");\n                                    } else {\n                                        System.out.println(\"El teléfono debe contener exactamente 11 dígitos numéricos.\");\n                                    }\n                                    break;\n\n                                case 2:\n                                    // Modificar solo el nombre\n                                    System.out.println(\"Ingrese el nuevo nombre:\");\n                                    String nuevoNombre = sc.nextLine();\n                                    if (!agenda.containsKey(nuevoNombre)) {\n                                        String numeroExistente = agenda.remove(nombreSeleccionado);  // Remover el contacto con el nombre anterior\n                                        agenda.put(nuevoNombre, numeroExistente);  // Añadir el contacto con el nuevo nombre y el mismo número\n                                        System.out.println(\"Nombre actualizado correctamente.\");\n                                    } else {\n                                        System.out.println(\"Ese nombre ya existe en la agenda.\");\n                                    }\n                                    break;\n\n                                case 3:\n                                    // Modificar tanto el nombre como el número de teléfono\n                                    System.out.println(\"Ingrese el nuevo nombre:\");\n                                    nuevoNombre = sc.nextLine();\n                                    System.out.println(\"Ingrese el nuevo número de teléfono:\");\n                                    nuevoNumero = sc.nextLine();\n\n                                    if (!agenda.containsKey(nuevoNombre) && nuevoNumero.matches(\"\\\\d{11}\")) {\n                                        agenda.remove(nombreSeleccionado);  // Eliminar el contacto con el nombre anterior\n                                        agenda.put(nuevoNombre, nuevoNumero);  // Añadir el nuevo nombre y el nuevo número\n                                        System.out.println(\"Nombre y número actualizados correctamente.\");\n                                    } else {\n                                        System.out.println(\"El nuevo nombre ya existe o el número no es válido.\");\n                                    }\n                                    break;\n\n                                default:\n                                    System.out.println(\"Opción no válida.\");\n                                    break;\n                            }\n                        } else {\n                            System.out.println(\"Selección no válida.\");\n                        }\n                    }\n                    break;\n\n                case 3:\n                    if (agenda.isEmpty()) {\n                        System.out.println(\"La agenda está vacía.\");\n                    } else {\n                        int contador = 1;\n                        HashMap<Integer, String> indiceAgenda = new HashMap<>();  // Mapeo del índice al nombre\n\n                        // Mostrar la agenda con índices numéricos\n                        for (Map.Entry<String, String> entry : agenda.entrySet()) {\n                            System.out.println(contador + \". Nombre: \" + entry.getKey() + \", Número: \" + entry.getValue());\n                            indiceAgenda.put(contador, entry.getKey());\n                            contador++;\n                        }\n\n                        // Pedir al usuario que seleccione un número para eliminar\n                        System.out.println(\"Ingrese el número del contacto que desea eliminar:\");\n                        int seleccion = sc.nextInt();\n                        sc.nextLine();  // Consumir el salto de línea\n\n                        // Validar la selección y eliminar el contacto\n                        if (indiceAgenda.containsKey(seleccion)) {\n                            String nombreSeleccionado = indiceAgenda.get(seleccion);\n                            agenda.remove(nombreSeleccionado);\n                            System.out.println(\"Contacto eliminado correctamente.\");\n                        } else {\n                            System.out.println(\"Selección no válida.\");\n                        }\n                    }\n                    break;\n\n                case 4:\n                    condifinal = false;\n                    System.out.println(\"Numeros cargados en la agenda (ordenados alfabéticamente): \");\n\n                    // Convertir el HashMap a TreeMap para ordenar alfabéticamente\n                    TreeMap<String, String> agendaOrdenada = new TreeMap<>(agenda);\n\n                    for (Map.Entry<String, String> entry : agendaOrdenada.entrySet()) {\n                        System.out.println(\"Nombre: \" + entry.getKey() + \", Número: \" + entry.getValue());\n                    }\n                    break;\n\n                default:\n                    System.out.println(\"Opción no válida.\");\n                    break;\n            }\n\n        } while (condifinal);\n\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/Password1989.java",
    "content": "package org.roadmap.java.ejercicio.tres;\r\n\r\nimport java.util.ArrayList;\r\nimport java.util.Collections;\r\nimport java.util.HashMap;\r\nimport java.util.HashSet;\r\nimport java.util.LinkedList;\r\nimport java.util.Scanner;\r\nimport java.util.Stack;\r\n\r\npublic class Password1989 {\r\n\r\n\t// Mapa para almacenar los contactos (nombre como clave y teléfono como valor)\r\n    private static final HashMap<String, String> contacts = new HashMap<>();\r\n    private static final Scanner scanner = new Scanner(System.in);\r\n\r\n    // Constante para la opción de salir\r\n    private static final int OPTION_EXIT = 6;\r\n\r\n    // Bucle principal de la agenda\r\n    public static void runAgenda() {\r\n        boolean exit = false;\r\n        while (!exit) {\r\n            showMenu();\r\n            int option = readOption();\r\n            exit = processOption(option);\r\n        }\r\n    }\r\n\r\n    // Mostrar menú\r\n    private static void showMenu() {\r\n        System.out.println(\"\\n--- Agenda de Contactos ---\");\r\n        System.out.println(\"1. Insertar contacto\");\r\n        System.out.println(\"2. Buscar contacto\");\r\n        System.out.println(\"3. Actualizar contacto\");\r\n        System.out.println(\"4. Eliminar contacto\");\r\n        System.out.println(\"5. Mostrar todos los contactos\");\r\n        System.out.println(\"6. Salir\");\r\n        System.out.print(\"Elige una opción: \");\r\n    }\r\n\r\n    // Leer opción del usuario\r\n    private static int readOption() {\r\n        int option = scanner.nextInt();\r\n        scanner.nextLine(); // Limpieza del buffer\r\n        return option;\r\n    }\r\n\r\n    // Procesar la opción elegida\r\n    private static boolean processOption(int option) {\r\n        switch (option) {\r\n            case 1:\r\n                insertContact();\r\n                break;\r\n            case 2:\r\n                searchContact();\r\n                break;\r\n            case 3:\r\n                updateContact();\r\n                break;\r\n            case 4:\r\n                deleteContact();\r\n                break;\r\n            case 5:\r\n                showAllContacts();\r\n                break;\r\n            case OPTION_EXIT:\r\n                System.out.println(\"Adiós!\");\r\n                return true;\r\n            default:\r\n                System.out.println(\"Opción no válida.\");\r\n        }\r\n        return false;\r\n    }\r\n\r\n    // Insertar un contacto\r\n    private static void insertContact() {\r\n        String name = inputNonEmptyString(\"Introduce nombre: \");\r\n        String phone = inputValidPhoneNumber();\r\n\r\n        if (contacts.containsKey(name)) {\r\n            System.out.println(\"El contacto ya existe.\");\r\n        } else {\r\n            contacts.put(name, phone);\r\n            System.out.println(\"Contacto añadido.\");\r\n        }\r\n    }\r\n\r\n    // Buscar un contacto (verificar si el mapa está vacío)\r\n    private static void searchContact() {\r\n        if (contacts.isEmpty()) {\r\n            System.out.println(\"La agenda está vacía. No hay contactos para buscar.\");\r\n            return;\r\n        }\r\n\r\n        String name = inputNonEmptyString(\"Introduce nombre a buscar: \");\r\n\r\n        if (contacts.containsKey(name)) {\r\n            System.out.println(\"Nombre: \" + name + \", Teléfono: \" + contacts.get(name));\r\n        } else {\r\n            System.out.println(\"Contacto no encontrado.\");\r\n        }\r\n    }\r\n\r\n    // Actualizar un contacto (verificar si el mapa está vacío)\r\n    private static void updateContact() {\r\n        if (contacts.isEmpty()) {\r\n            System.out.println(\"La agenda está vacía. No hay contactos para actualizar.\");\r\n            return;\r\n        }\r\n\r\n        String name = inputNonEmptyString(\"Introduce nombre del contacto a actualizar: \");\r\n\r\n        if (contacts.containsKey(name)) {\r\n            String newPhone = inputValidPhoneNumber();\r\n            contacts.put(name, newPhone);\r\n            System.out.println(\"Contacto actualizado.\");\r\n        } else {\r\n            System.out.println(\"Contacto no encontrado.\");\r\n        }\r\n    }\r\n\r\n    // Eliminar un contacto (verificar si el mapa está vacío)\r\n    private static void deleteContact() {\r\n        if (contacts.isEmpty()) {\r\n            System.out.println(\"La agenda está vacía. No hay contactos para eliminar.\");\r\n            return;\r\n        }\r\n\r\n        String name = inputNonEmptyString(\"Introduce nombre del contacto a eliminar: \");\r\n\r\n        if (contacts.remove(name) != null) {\r\n            System.out.println(\"Contacto eliminado.\");\r\n        } else {\r\n            System.out.println(\"Contacto no encontrado.\");\r\n        }\r\n    }\r\n\r\n    // Mostrar todos los contactos\r\n    private static void showAllContacts() {\r\n        if (contacts.isEmpty()) {\r\n            System.out.println(\"No hay contactos en la agenda.\");\r\n        } else {\r\n            System.out.println(\"--- Lista de Contactos ---\");\r\n            contacts.forEach((name, phone) -> \r\n                System.out.println(\"Nombre: \" + name + \", Teléfono: \" + phone));\r\n        }\r\n    }\r\n\r\n    // Leer una cadena no vacía del usuario\r\n    private static String inputNonEmptyString(String prompt) {\r\n        String input;\r\n        do {\r\n            System.out.print(prompt);\r\n            input = scanner.nextLine().trim();\r\n            if (input.isEmpty()) {\r\n                System.out.println(\"El valor no puede estar vacío. Inténtalo de nuevo.\");\r\n            }\r\n        } while (input.isEmpty());\r\n        return input;\r\n    }\r\n\r\n    // Validar y leer un número de teléfono válido (solo dígitos, hasta 11 caracteres)\r\n    private static String inputValidPhoneNumber() {\r\n        String phone;\r\n        do {\r\n            System.out.print(\"Introduce un número de teléfono (solo dígitos, máximo 11): \");\r\n            phone = scanner.nextLine().trim();\r\n            if (!phone.matches(\"\\\\d{1,11}\")) {\r\n                System.out.println(\"Número de teléfono no válido. Debe contener solo dígitos y hasta 11 caracteres.\");\r\n            }\r\n        } while (!phone.matches(\"\\\\d{1,11}\"));\r\n        return phone;\r\n    }\r\n\t\r\n\tpublic static void main(String[] args) {\r\n\t\t\r\n\t\t/*\r\n\t\t * EJERCICIO:\r\n\t\t * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\r\n\t\t * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\r\n\t\t *\r\n\t\t * DIFICULTAD EXTRA (opcional):\r\n\t\t * Crea una agenda de contactos por terminal.\r\n\t\t * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\r\n\t\t * - Cada contacto debe tener un nombre y un número de teléfono.\r\n\t\t * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\r\n\t\t *   los datos necesarios para llevarla a cabo.\r\n\t\t * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\r\n\t\t *   (o el número de dígitos que quieras)\r\n\t\t * - También se debe proponer una operación de finalización del programa.\r\n\t\t \r\n\t\t\r\n\t\t// Creación de una lista\r\n        ArrayList<Integer> list = new ArrayList<>();\r\n\r\n        // Inserción\r\n        list.add(5);\r\n        list.add(2);\r\n        list.add(8);\r\n        System.out.println(\"Lista después de inserción: \" + list);\r\n\r\n        // Borrado\r\n        list.remove(Integer.valueOf(2)); // Eliminar el valor 2\r\n        System.out.println(\"Lista después de borrado: \" + list);\r\n\r\n        // Actualización\r\n        list.set(1, 2); // Cambiar el elemento en el índice 1 por 10\r\n        System.out.println(\"Lista después de actualización: \" + list);\r\n\r\n        // Ordenación\r\n        Collections.sort(list);\r\n        System.out.println(\"Lista ordenada: \" + list);\r\n        \r\n        // Creación de un conjunto\r\n        HashSet<String> set = new HashSet<>();\r\n\r\n        // Inserción\r\n        set.add(\"Rojo\");\r\n        set.add(\"Azul\");\r\n        set.add(\"Verde\");\r\n        System.out.println(\"Conjunto después de inserción: \" + set);\r\n\r\n        // Borrado\r\n        set.remove(\"Azul\");\r\n        System.out.println(\"Conjunto después de borrado: \" + set);\r\n\r\n        // Actualización (no hay actualización directa, se debe eliminar y volver a insertar)\r\n        set.remove(\"Rojo\");\r\n        set.add(\"Amarillo\");\r\n        System.out.println(\"Conjunto después de actualización: \" + set);\r\n\r\n        // Ordenación (no aplicable a HashSet, pero se puede convertir en una lista)\r\n        System.out.println(\"Conjunto (no ordenado por defecto): \" + set);\r\n        \r\n        // Creación de una lista enlazada\r\n        LinkedList<Integer> queue = new LinkedList<>();\r\n\r\n        // Inserción (en cola)\r\n        queue.add(3);\r\n        queue.add(1);\r\n        queue.add(4);\r\n        System.out.println(\"Cola después de inserción: \" + queue);\r\n\r\n        // Borrado (de la cabeza)\r\n        queue.remove();\r\n        System.out.println(\"Cola después de borrado: \" + queue);\r\n\r\n        // Actualización\r\n        queue.set(0, 7); // Cambia el primer elemento a 7\r\n        System.out.println(\"Cola después de actualización: \" + queue);\r\n\r\n        // Ordenación\r\n        Collections.sort(queue);\r\n        System.out.println(\"Cola ordenada: \" + queue);\r\n        \r\n        // Creación de una pila\r\n        Stack<String> stack = new Stack<>();\r\n\r\n        // Inserción (empujar en la pila)\r\n        stack.push(\"Uno\");\r\n        stack.push(\"Dos\");\r\n        stack.push(\"Tres\");\r\n        System.out.println(\"Pila después de inserción: \" + stack);\r\n\r\n        // Borrado (pop, sacar de la pila)\r\n        stack.pop();\r\n        System.out.println(\"Pila después de borrado: \" + stack);\r\n\r\n        // Actualización (no hay actualización directa)\r\n        stack.set(0, \"Cuatro\");\r\n        System.out.println(\"Pila después de actualización: \" + stack);\r\n        \r\n        // Creación de un mapa\r\n        HashMap<Integer, String> map = new HashMap<>();\r\n\r\n        // Inserción\r\n        map.put(1, \"Manzana\");\r\n        map.put(2, \"Banana\");\r\n        map.put(3, \"Cereza\");\r\n        System.out.println(\"Mapa después de inserción: \" + map);\r\n\r\n        // Borrado\r\n        map.remove(2); // Eliminar la entrada con clave 2\r\n        System.out.println(\"Mapa después de borrado: \" + map);\r\n\r\n        // Actualización\r\n        map.put(1, \"Durazno\"); // Cambiar el valor de la clave 1\r\n        System.out.println(\"Mapa después de actualización: \" + map);\r\n\r\n        // No hay ordenación para HashMap, ya que no mantiene orden.\r\n        \r\n         */\r\n\t\trunAgenda();\r\n\t}\r\n}\r\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/Qv1ko.java",
    "content": "import java.io.BufferedReader;\nimport java.io.InputStreamReader;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.Set;\nimport java.util.TreeSet;\n\npublic class Qv1ko {\n\n    public static void main(String[] args) {\n\n        arrayStructure();\n\n        listStructure();\n\n        setStructure();\n\n        mapStructure();\n\n        schedule();\n        \n    }\n\n    private static void arrayStructure() {\n        \n        String[] array = new String[6];\n\n        array[0] = \"A\";\n\n        array[0] = null;\n\n        array[0] = \"A\";\n\n        array[0] += \" - Updated\";\n\n        array[1] = \"B\";\n\n        String aux = \"\";\n\n        aux = array[0];\n        array[0] = array[1];\n        array[1] = aux;\n        \n    }\n    \n    private static void listStructure() {\n        \n        ArrayList<Integer> list = new ArrayList<Integer>();\n\n        list.add(0);\n\n        list.set(0, 3);\n\n        list.remove(0);\n\n        list.add(5);\n\n        list.add(4);\n        \n        list.add(3);\n\n        Collections.sort(list);\n\n    }\n    \n    private static void setStructure() {\n        \n        Set<String> set = new TreeSet<>();\n\n        set.add(\"B\");\n\n        set.add(\"C\");\n\n        set.add(\"A\");\n\n        set.remove(\"B\");\n\n    }\n    \n    private static void mapStructure() {\n        \n        HashMap<Integer, String> map = new HashMap<Integer, String>();\n\n        map.put(0, \"A\");\n        map.put(1, \"B\");\n        map.put(2, \"C\");\n\n        map.remove(1);\n\n        map.replace(2, \"B\");\n\n    }\n\n    private static void schedule() {\n\n        System.out.println(\"\\nS C H E D U L E\");\n\n        HashMap<String, String> contacts = new HashMap<String, String>();\n        boolean exit = false;\n        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));\n        String option = \"\", option2 = \"\";\n\n        while (!exit) {\n\n            options();\n            try {\n                System.out.print(\">> \");\n                option = br.readLine();\n                switch (option) {\n                    case \"1\":\n                        if (contacts.size() != 0) {\n                            System.out.println(\"\\nType the name of the contact to search for\");\n                            System.out.print(\">> \");\n                            option = br.readLine();\n                            if (contacts.containsKey(option)) {\n                                System.out.println(\"Contact \" + option + \" - \" + contacts.get(option));\n                            } else {\n                                System.out.println(\"\\n>> contact not found\");\n                            }\n                        } else {\n                            System.out.println(\"\\n>> you have no contacts\");\n                        }\n                        break;\n\n                    case \"2\":\n                        System.out.println(\"\\nEnter the name of the new contact\");\n                        System.out.print(\">> \");\n                        option = br.readLine();\n                        if (contacts.containsKey(option)) {\n                            System.out.println(\"\\n>> the contact already exists\");\n                        } else {\n                            do {\n                                System.out.println(\"\\nEnter the phone number of the new contact\");\n                                System.out.print(\">> \");\n                                option2 = br.readLine();\n                            } while (!option2.matches(\"\\\\d{9,11}\"));\n                            contacts.put(option, option2);\n                            System.out.println(\"\\nUser \" + option + \" with phone (\" + option2 + \") successfully added\");\n                        }\n                        break;\n\n                    case \"3\":\n                        System.out.println(\"\\nEnter the name of the contact\");\n                        System.out.print(\">> \");\n                        option = br.readLine();\n                        if (contacts.containsKey(option)) {\n                            do {\n                                System.out.println(\"\\nEnter the phone number\");\n                                System.out.print(\">> \");\n                                option2 = br.readLine();\n                            } while (!option2.matches(\"\\\\d{9,11}\"));\n                            contacts.replace(option, option2);\n                            System.out.println(\"\\nUser \" + option + \" with phone (\" + option2 + \") successfully added\");\n                        } else {\n                            System.out.println(\"\\n>> contact not found\");\n                        }\n                        break;\n\n                    case \"4\":\n                        if (contacts.size() != 0) {\n                            System.out.println(\"\\nEnter the name of the contact you wish to delete\");\n                            System.out.print(\">> \");\n                            option = br.readLine();\n                            if (contacts.containsKey(option)) {\n                                contacts.remove(option);\n                                System.out.println(\"\\nUser \" + option + \" was successfully deleted\");\n                            } else {\n                                System.out.println(\"\\n>> contact not found\");\n                            }\n                        } else {\n                            System.out.println(\"\\n>> you have no contacts\");\n                        }\n                        break;\n\n                    case \"0\":\n                        exit = true;\n                        System.out.println(\"\\n>> leaving...\\n\");\n                        break;\n\n                    default:\n                        throw new Exception();\n\n                }\n            } catch (Exception exc) {\n                System.out.println(\"\\n>> error when selecting the option\\n\");\n            }\n            \n        }\n\n    }\n\n    private static void options() {\n        System.out.println(\"\\nOptions:\");\n        System.out.println(\"-----\");\n        System.out.println(\"1) Search contact\");\n        System.out.println(\"2) Create contact\");\n        System.out.println(\"3) Update contact\");\n        System.out.println(\"4) Delete contact\");\n        System.out.println(\"0) Exit\");\n        System.out.println(\"-----\");\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/RodrigoGit87.java",
    "content": "import java.util.*;\n\npublic class RodrigoGit87 {\n    //EXTRA\n    // Objeto contacto\n    public static class Contacto {\n        private String nombre;\n        private String telefono;\n        public static int contador = 1; //contador estatico(afecta a todas las instancias) para usar en la variable id.\n        private int id;\n\n        //Constructor\n        public Contacto(String nombre, String telefono) {\n            this.nombre = nombre;\n            setTelefono(telefono);\n            this.id = contador++;\n        }\n\n        //getters\n        public int getId() {\n            return id;\n        }\n\n        public String getTelefono() {\n            return telefono;\n        }\n\n        public String getNombre() {\n            return nombre;\n        }\n\n        //setter para que telefono cumpla las condiciones de digitos y longitud máxima\n        public void setTelefono(String telefono) {\n            if (telefono.length() > 11) {\n                throw new IllegalArgumentException(\"El telefono no debe tener más de 11 caracteres\");\n            }\n            if (!telefono.matches(\"\\\\d+\")) { //  \\\\d+ es una expresión q signifca q solo admite dígitos\n                throw new IllegalArgumentException(\" Solo se admite dígitos\");\n            }\n            this.telefono = telefono;\n        }\n        //setter nombre\n        public void setNombre(String nombre) {\n            this.nombre = nombre;\n        }\n\n        @Override\n        public String toString() {\n            return \"Contacto{\" +\n                    \"nombre='\" + nombre + '\\'' +\n                    \", telefono='\" + telefono + '\\'' +\n                    \", id=\" + id +\n                    '}';\n        }\n    }\n\n\n        // Objeto Agenda\n        public static class Agenda {\n            private HashMap<Integer, Contacto> contactos;\n\n            //Constructor\n            public Agenda() {\n                this.contactos = new HashMap<>();\n            }\n                //metodo inserción\n                public void añadirContacto (Contacto contacto){\n                    this.contactos.put(contacto.getId(), contacto);\n                }\n                //metodo buscar\n                public Contacto buscarId (int id){\n                if(!contactos.containsKey(id)){\n                    throw new IllegalArgumentException(\"No existe el contacto con el id: \" + id);\n                }\n                return this.contactos.get(id);\n                }\n                //metodo eliminar\n                public Contacto eliminarContacto (int id){\n                    if(!contactos.containsKey(id)){\n                        throw new IllegalArgumentException(\"No existe el contacto con el id: \" + id);\n                    }\n                    return this.contactos.remove(id);\n                }\n                //metodo modificar\n                public void modificarContacto (int id, String nuevoNombre, String nuevoTelefono){\n                if(!contactos.containsKey(id)){\n                    throw new IllegalArgumentException(\"No existe el contacto con el id: \" + id);\n                }\n                Contacto c = contactos.get(id);\n                if ( nuevoNombre != null && !nuevoNombre.isEmpty()) {\n                    c.setNombre(nuevoNombre);\n                }\n                if ( nuevoTelefono != null && !nuevoTelefono.isEmpty()) {\n                    c.setTelefono(nuevoTelefono);\n                }\n            }\n        }\n\n\n    public static void main (String[] args){\n     //EXTRA\n    Scanner sc = new Scanner(System.in);\n    var agenda = new Agenda();\n    boolean finalizar = false;\n    int opcion;\n\n\n    do{\n        System.out.println(\"Introduce la opcion a realizar \");\n        System.out.println(\"1.Añadir contacto \\n2. Buscar contacto \\n3. Modificar contacto \\n4. Eliminar contacto \\n5 Finalizar\");\n        try{\n            opcion = sc.nextInt();\n        } catch (Exception e) {\n            opcion = 0;\n            sc.nextLine();\n        }\n        sc.nextLine();\n        switch (opcion){\n            case 1: // insertar\n                try {\n                    System.out.println(\"Introduce el nombre del contacto : \");\n                    String nombre = sc.nextLine().trim().toUpperCase();\n                    System.out.println(\"Introduce la telefono del contacto : \");\n                    String tfn = sc.nextLine().trim();\n\n                    Contacto nuevo = new Contacto (nombre, tfn);\n                    agenda.añadirContacto(nuevo);\n                    System.out.println( \" Nuevo contacto creado con id: \" + nuevo.getId());\n                } catch (IllegalArgumentException e){\n                    System.err.println(e.getMessage());\n                }\n                break;\n            case 2: //buscar\n                System.out.println(\" Introduce la ID del contacto a buscar: \");\n                int idScanner = sc.nextInt();\n                sc.nextLine();\n                try{\n                   Contacto encontrado = agenda.buscarId(idScanner);\n                    System.out.println(\"Encontrado: \" + encontrado.toString());\n                } catch (IllegalArgumentException e){\n                    System.err.println(e.getMessage());\n                }\n                break;\n            case 3: // modificar\n                System.out.println(\" Introduce la ID del contacto a modificar: \");\n                int idMod = sc.nextInt();\n                sc.nextLine();\n\n                try {\n                    Contacto actual = agenda.buscarId(idMod); // Solo para mostrar el nombre actual\n                    System.out.println(\"Editando a: \" + actual.getNombre());\n\n                    System.out.print(\"Nuevo nombre (pulsa ENTER para mantener el actual): \");\n                    String nuevoNombre = sc.nextLine();\n\n                    System.out.print(\"Nuevo teléfono (pulsa ENTER para mantener el actual): \");\n                    String nuevoTlf = sc.nextLine();\n\n                    agenda.modificarContacto(idMod, nuevoNombre, nuevoTlf);\n                    System.out.println(\">> ¡Contacto actualizado!\");\n\n                } catch (IllegalArgumentException e) {\n                    System.out.println(\"ERROR: \" + e.getMessage());\n                }\n                break;\n            case 4: // Eliminar\n                System.out.print(\"ID a eliminar: \");\n                int idBorrar = sc.nextInt();\n                sc.nextLine();\n\n                try {\n                    Contacto eliminado = agenda.eliminarContacto(idBorrar);\n                    System.out.println(\">> Se ha eliminado a: \" + eliminado.getNombre());\n                } catch (IllegalArgumentException e) {\n                    System.out.println(\"ERROR: \" + e.getMessage());\n                }\n                break;\n            case 5:\n                finalizar = true;\n                System.out.println(\"¡Hasta la vista, baby !\");\n                break;\n            default:\n                System.out.println(\" opcion incorrecta \");\n        }\n    } while (!finalizar);\n    sc.close();\n\n\n/* -------- Ejercicios Principales ----------*/\n        System.out.println(\" -------------- \\n\");\n    //ARRAYS\n        //declarar\n    int[] arrayDeNumeros = new int[10]; /* se indica q hay 10 posiciones en índice, se cuentan del 0 al 9, en este caso\n    las posiciones están vacías. Para rellenarlas, se puede manualmente indice a indice o con un ciclo for.*/\n\n        //declarar array y asignar a la vez\n        String[] frutas =  {\"piña\",\"manzana\",\"kiwi\",\"melon\",\"fruta del dragón\",\"coco\",\"pepinaco\"};\n        System.out.println(\" \");\n        //Acceso al array -> con metodo .toString\n        System.out.println(\"Frutas: \" + Arrays.toString(frutas));\n            // o, con un for-each\n        for(String itemFruta: frutas){\n            System.out.println(\"Fruta: \" + itemFruta);\n        }\n\n    // asignar valor a un indice del array\n    arrayDeNumeros [0]= 69;\n\n    //asignar mediante ciclo for\n        for (int i= 0; i < arrayDeNumeros.length; i++){\n            arrayDeNumeros[i] = (i + 1) * 5 ; //Esto hace q la primera posicion del array, [0], empieze valiendo 1, luego multiplica por\n            //5 y tenemos 5 como valor guardado en [0]. Siguiente iteracion, y ahora tenemos q en [1] = 5x5 = 10, [1] guarda el valor 10 y así...\n        }\n    //recorrer el array - con un for each\n        for (int numero: arrayDeNumeros ){\n            System.out.println(\" \");\n            System.out.println(numero);\n        } // tenemos una maravillosa tabla del 5 guardada como un Array\n\n   // LIST\n        //declarar\n    ArrayList<Integer> listaDeNumeros = new ArrayList<>();\n    ArrayList<String> listaDeAlumnos = new ArrayList<>();\n        //asignar\n        listaDeAlumnos.add(\"RodrigoGit87\");\n        listaDeAlumnos.add(\"AbelADE\");\n        listaDeAlumnos.add(\"BlasBarragan\");\n        listaDeAlumnos.add(\"Cesar-ch\");\n        listaDeAlumnos.add(\"danhingar\");\n        IO.print(\"- listaDeAlumnos -\");\n        IO.println(\"\\n\"+ listaDeAlumnos + \"\\nTotal de alumnos: \" + listaDeAlumnos.size());\n\n        //Acceder a elementos\n        //listaDeAlumnos.get(posicion));\n        IO.println(\"---\");\n        IO.println(\".get(1) = \" + listaDeAlumnos.get(1));\n        // otras formas -> .getFirst(); y .getLast();\n        IO.println(\".getFirst() = \" + listaDeAlumnos.getFirst() + \"\\n\");\n        IO.println(\".getLast() = \" + listaDeAlumnos.getLast() + \"\\n\");\n\n        //modificar elementos\n        listaDeAlumnos.set(3, \"AnaLauDB\");\n        //ahora  la posicion 3 es AnaLauDB, antes era cesar-ch, lo comprobamos:\n        IO.println(\".get(3), despues de haber 'setteado' = \" + listaDeAlumnos.get(3) + \"\\n\");\n\n    //HashSet,HashMap -> Aqui no existen indices, el valor se guarda en hashes, y de forma aleatoria, sin orden\n    //HASHSET\n        System.out.println(\"-- HashSet ---\");\n        //Declaracion y creacion\n        HashSet<String> names = new HashSet<>();//una manera\n        var id = new HashSet<String>();//otra manera\n\n        // añadir\n        names.add(\"Doom The Slayer\");\n        names.add(\"Rosa Melano\");\n        names.add(\"Gandalf el coder gris\");\n        names.add(\"Elver\");\n\n        // quitar\n        names.remove(\"Elver\");\n        System.out.println(\" hashSet: \" + names.size());\n\n        //acceso; no se puede, no hay indices como en array o arraylist\n        //Se puede 'buscar' con .contains()\n        IO.println(\"names.contains('Gandalf') \" + names.contains(\"Gandalf\")); //<- false, tiene q estar escrito exactamente igual\n        IO.println(\"names.contains('Gandalf el coder gris') \" + names.contains(\"Gandalf el coder gris\")); // <- true\n\n        System.out.println(\" \");\n        //conjuntos (añadir un hashset a otro, tienen q ser del mismo tipo)\n        id.add(\"001\");\n        id.add(\"002\");\n        id.add(\"003\");\n        id.add(\"004\");\n        names.addAll(id);// ahora names contiene los elementos de id\n        IO.println(names);\n        names.removeAll(id);//ahora no\n        IO.println(names);\n\n    //HASHMAP Funciona con pares 'clave:valor' (Una Clave = Un Valor, no se puede asignar a la misma clave más de un valor )\n        System.out.println(\" ---- Hashmap ---\");\n        var mapa1 = new HashMap<String, String>(); // Indicar el tipo para <clave, valor>\n\n        //.put para añadir\n        mapa1.put(\"Humano\",\"Aragorn\");\n        mapa1.put(\"Elfo\",\"Legolas\");\n        mapa1.put(\"Mago\",\"Gandalf\");\n        IO.println(mapa1.size());\n        IO.println(mapa1);\n\n        //.get para acceder (sabiendo la key y tipeando exactamente igual)\n        IO.println(mapa1.get(\"Humano\")); // <- Aragorn\n\n        // comprobamos el principio de 1 key = 1 value\n        mapa1.put(\"Humano\", \"Frodo\"); //<- Ahora el valor del key \"humano\" es Frodo. Técnicamente: el puntero 'Humano' apunta a un hash, y ese hash solo\n        //guarda un valor, el último asignado (al igual q una variable primitiva normal)\n        IO.println(mapa1.get(\"Humano\"));\n\n        //.containsValue() o .containsKey(); para verificar (true o false).\n        // De paso comprobamos q Aragorn ya no existe al usar la misma clave \"Humano\" para Frodo\n        IO.println(mapa1.containsValue(\"Aragorn\")); // <- false, osea, mapa1 no contiene/no existe el valor \"Aragorn\".\n    }\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/RoniPG.java",
    "content": "import java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.InputMismatchException;\nimport java.util.LinkedHashSet;\nimport java.util.Scanner;\nimport java.util.Stack;\nimport java.util.TreeSet;\n\n// @Roni\n\npublic class ESTRUCTURAS_DE_DATOS_03 {\n\n\tpublic static void main(String[] args) {\n\n\t\t// Arrays\n\n\t\t// Array estatico\n\n\t\tint numeros[] = { 1, 2, 3, 4, 5 }; // Instanciamos con variables asignadas\n\t\tint numeros2[] = new int[5]; // Instaciamos con cantidad de variables\n\n\t\t// Acceder y modificar datos del array\n\n\t\tSystem.out.println(numeros2[0] = 1); // Asignamos el valor 1 en la posicion 0\n\t\tSystem.out.println(numeros2[1] = 2); // Asignamos el valor 2 en la posicion 1\n\t\tSystem.out.println(\"Valor de la primera posicion en el array numeros: \" + numeros[0]); // Asignamos el valor 1\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// en la posicion 0\n\t\tSystem.out.print(\"Valor de la primera posicion en el array numeros: \");\n\t\tSystem.out.println(numeros[0] = 6); // Asignamos el valor 6 en la posicion 0\n\t\tfor (int i : numeros) { // --->Foreach\n\t\t\tSystem.out.print(i + \",\");\n\t\t}\n\t\tSystem.out.println();\n\t\tfor (int i = 0; i < numeros.length; i++) {\n\t\t\tSystem.out.print(numeros[i] + \",\");\n\t\t}\n\t\tSystem.out.println();\n\n\t\t// Ordenar\n\n\t\tnumeros[0] = 3;\n\t\tnumeros[1] = 1;\n\t\tnumeros[2] = 5;\n\t\tnumeros[3] = 2;\n\t\tnumeros[4] = 4;\n\t\tfor (int i : numeros) {\n\t\t\tSystem.out.print(i + \",\");\n\t\t}\n\t\tSystem.out.println();\n\t\tArrays.sort(numeros); // --> Ordena el array que le pases como parametro\n\t\tfor (int i : numeros) {\n\t\t\tSystem.out.print(i + \",\");\n\t\t}\n\t\tSystem.out.println();\n\n\t\t// Array dinamico (ArrayList)\n\n\t\tArrayList<String> nombres = new ArrayList<>();// Creamos el array dinamico\n\n\t\t// Insertar datos\n\n\t\tnombres.add(\"Hola\"); // Se a├▒ade a la primera posicion disponible\n\t\tnombres.add(\"Mundo\"); // Se a├▒ade al final de la lista\n\t\tnombres.add(\"Nuevo\");\n\n\t\t// Borrar datos\n\n\t\tSystem.out.println(\"La lista contiene \" + nombres.size() + \" posiciones\");\n\t\tSystem.out.println(\"Este el el dato en la posicion 3 : \" + nombres.get(2));\n\t\tnombres.remove(2); // Eliminamos le dato que esta en la posici├│n 2\n\t\t// System.out.println(\"Este el el dato en la posici├│n 2 : \"+nombres.get(2)); -->\n\t\t// Una vez eliminado el dato, la posicion deja de existir\n\t\tSystem.out.println(\"La lista contiene \" + nombres.size() + \" posiciones\");\n\n\t\t// Actualizar datos\n\n\t\tSystem.out.println(nombres);\n\t\tnombres.add(2, \"Nuevo\");\n\t\tSystem.out.println(\"Dato en la posicion 3: \" + nombres.get(2));\n\t\tnombres.set(2, \"Viejo\");\n\t\tSystem.out.println(\"Dato en la posicion 3: \" + nombres.get(2));\n\t\tSystem.out.println(nombres);\n\n\t\t// HashSet , TreeSet y LinkedHashSet\n\n\t\t/*\n\t\t * Estas tres estructuras de datos evitan que se introuduzcan datos repetidos y\n\t\t * cada uno contiene su forma de ordenar los datos. En el HashSet los datos no\n\t\t * garantizan un orden especifico En TreeSet se ordena de menor a mayor, y el\n\t\t * LinkedHashSet mantiene el orden de inserccion\n\t\t */\n\n\t\tHashSet<Integer> noRepsHS = new HashSet<>();\n\t\tTreeSet<Integer> noRepsTS = new TreeSet<>();\n\t\tLinkedHashSet<Integer> noRepsLHS = new LinkedHashSet<>();\n\n\t\t// Insertar datos\n\n\t\tnoRepsHS.add(4);\n\t\tnoRepsTS.add(4);\n\t\tnoRepsLHS.add(4);\n\t\tnoRepsHS.add(2);\n\t\tnoRepsTS.add(2);\n\t\tnoRepsLHS.add(2);\n\t\tnoRepsHS.add(1);\n\t\tnoRepsTS.add(1);\n\t\tnoRepsLHS.add(1);\n\t\tnoRepsHS.add(3);\n\t\tnoRepsTS.add(3);\n\t\tnoRepsLHS.add(3);\n\t\tnoRepsHS.add(1);\n\t\tnoRepsTS.add(1);\n\t\tnoRepsLHS.add(1); // ---> A├▒adimos datos repetidos\n\n\t\tSystem.out.println(noRepsHS);\n\t\tSystem.out.println(noRepsTS);\n\t\tSystem.out.println(noRepsLHS);\n\n\t\tfor (Integer numero : Arrays.asList(9, 6, 8, 7, 5)) { // --Otro metodo de inserccion de datos\n\t\t\tnoRepsHS.add(numero);\n\t\t\tnoRepsTS.add(numero);\n\t\t\tnoRepsLHS.add(numero);\n\t\t}\n\t\tSystem.out.println(noRepsHS);\n\t\tSystem.out.println(noRepsTS);\n\t\tSystem.out.println(noRepsLHS);\n\n\t\t// Borrar datos\n\n\t\t/*\n\t\t * Con estos metodos podemos eliminar(limpiar) todos los datos de la lista\n\t\t * \n\t\t * noRepsHS.clear(); noRepsTS.clear(); noRepsLHS.clear();\n\t\t */\n\n\t\tint begin = 1;\n\t\tint desirable = 2;\n\n\t\tSystem.out.println(noRepsHS);\n\t\tfor (Integer numero : noRepsLHS) {\n\t\t\tif (begin == desirable) {\n\t\t\t\tSystem.out.println(numero); // --->Podemos acceder la posicion que deseemos (desirable)\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tbegin++;\n\t\t}\n\t\tnoRepsHS.remove(2); // ---> Borrar dato en la posicion deseada\n\t\tSystem.out.println(noRepsHS);\n\n\t\tSystem.out.println(noRepsTS);\n\t\tSystem.out.println(noRepsLHS);\n\n\t\tint beginB = 1;\n\t\tfor (Integer numero : noRepsTS) {\n\t\t\tif (begin == desirable) {\n\t\t\t\tnoRepsHS.remove(numero); // ---> Borrar dato en la posicion deseada\n\t\t\t\tfor (Integer num : noRepsLHS) {\n\t\t\t\t\tif (beginB == desirable) {\n\t\t\t\t\t\tnoRepsLHS.remove(num); // ---> Borrar dato en la posicion deseada\n\t\t\t\t\t\tSystem.out.println(num);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tbeginB++;\n\t\t\t\t}\n\t\t\t\tSystem.out.println(numero); // --->Podemos acceder la posicion que deseemos (desirable)\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tbegin++;\n\t\t}\n\t\tSystem.out.println(noRepsTS);\n\t\tSystem.out.println(noRepsLHS);\n\n\t\t// Las estructuras set no se pueden ordenar por naturaleza.\n\n\t\t// Pilas (Stacks)\n\n\t\tStack<String> pila = new Stack<>();\n\n\t\t// Insertar datos\n\n\t\tpila.push(\"A\");\n\t\tpila.push(\"B\");\n\t\tpila.push(\"C\");\n\n\t\tSystem.out.println(\"Contenido de la pila: \" + pila);\n\n\t\t// Borrar datos\n\n\t\tpila.remove(1); // ---> Borrar dato en la posicion deseada\n\t\t// pila.clear(); ---> Eliminar(limpiar) todos los datos de la lista\n\t\tSystem.out.println(\"Contenido de la pila: \" + pila);\n\t\tString elementoCima = pila.pop(); // ---> Borrar dato en la cima de la pila con un return del dato\n\t\tSystem.out.println(\"Contenido de la pila: \" + pila);\n\t\tSystem.out.println(\"Elemento en la cima de la pila: \" + elementoCima);\n\n\t\t// Actualizar datos\n\n\t\tSystem.out.println(\"Contenido de la pila: \" + pila);\n\t\tpila.set(0, \"B\");\n\t\tSystem.out.println(\"Contenido de la pila: \" + pila);\n\n\t\t// Ordenar datos\n\n\t\tpila.push(\"C\");\n\t\tpila.push(\"D\");\n\t\tpila.push(\"A\");\n\t\tSystem.out.println(pila);\n\t\tCollections.sort(pila);\n\t\tSystem.out.println(pila);\n\n\t\t// HashMap , TreeMap y LinkedHashMap\n\n\t\t/*\n\t\t * Podemos ordenar los datos con clave-valor, en donde la clave nos permitira\n\t\t * acceder/locacalizar el valor Estas tres estructuras de datos evitan que se\n\t\t * introuduzcan datos repetidos y cada uno contiene su forma de ordenar los\n\t\t * datos. En el HashSet los datos no garantizan un orden especifico En TreeSet\n\t\t * se ordena de menor a mayor, y el LinkedHashSet mantiene el orden de insercion\n\t\t */\n\n\t\tHashMap<String, String> persona = new HashMap<>();\n\n\t\t// Insertar datos\n\n\t\tpersona.put(\"023909R\", \"Pedro\");\n\t\tpersona.put(\"903828A\", \"Juan\");\n\t\tpersona.put(\"270842B\", \"Alberto\");\n\t\tSystem.out.println(persona);\n\n\t\t// Borrar datos\n\n\t\tSystem.out.println(persona);\n\t\tpersona.remove(\"903828A\");\n\t\tSystem.out.println(persona);\n\t\t// persona.clear(); ---> Eliminar(limpiar) todos los datos de la lista\n\n\t\t// Actualizar datos\n\n\t\tSystem.out.println(\"Contenido de persona: \" + persona);\n\t\tpersona.replace(\"023909R\", \"Ronaldo\");\n\t\tSystem.out.println(\"Contenido de persona: \" + persona);\n\n\t\t// Las estructuras map no se pueden ordenar por naturaleza.\n\n\t\t/*\n\t\t * DIFICULTAD EXTRA (opcional): Crea una agenda de contactos por terminal. -\n\t\t * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n     * - Cada contacto debe tener un nombre y un número de teléfono.\n     * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n     *   los datos necesarios para llevarla a cabo.\n     * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n     *   (o el número de dígitos que quieras)\n     * - También se debe proponer una operación de finalización del programa.\n     */\n\n\t\tScanner entradaDatos = new Scanner(System.in);\n\t\tint opcion = 0;\n\t\tlong numero;\n\t\tString nombre;\n\t\tHashMap<String, Long> agenda = new HashMap<>();\n\n\t\tdo {\n\t\t\topcion = Menu(opcion, entradaDatos);\n\n\t\t\tif (opcion == 1) {\n\t\t\t\t\n\t\t\t\tVerAgenda(agenda);\n\t\t\t\t\n\t\t\t} else if (opcion == 2) {\n\t\t\t\tSystem.out.println(\"Introduzca el nombre del contacto: \");\n\t\t\t\tnombre = entradaDatos.nextLine();\n\t\t\t\tNuevoContacto(nombre, entradaDatos, agenda);\n\n\t\t\t} else if (opcion == 3) {\n\t\t\t\t\n\t\t\t\tVerAgenda(agenda);\n\t\t\t\t\n\t\t\t\tSystem.out.println(\"Decida la opcion que quiera realizar: \");\n\t\t\t\tSystem.out.println();\n\t\t\t\tSystem.out.println(\"Opcion 1: Actulizar nombre\");\n\t\t\t\tSystem.out.println(\"Opcion 2: Actualizar numero\");\n\t\t\t\tint subOpcion = entradaDatos.nextInt();\n\t\t\t\tentradaDatos.nextLine();\n\t\t\t\tif (subOpcion ==1 ) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tSystem.out.println(\"Introduzca el numero del contacto: \");\n\t\t\t\t\t\tnumero = entradaDatos.nextLong();// ---> No tiene en cuenta los 0 a la izquierda\n\t\t\t\t\t\tentradaDatos.nextLine();\n\t\t\t\t\t\tString countNum = String.valueOf(numero);\n\t\t\t\t\t\tif (countNum.length() > 11) {\n\t\t\t\t\t\t\tSystem.out.println(\"Ha excedido el limite de digitos, intente de nuevo: \");\n\t\t\t\t\t\t}else {\n\t\t\t\t\t\t\tSystem.out.println(\"Indrozca el nuevo nombre del contacto: \");\n\t\t\t\t\t\t\tnombre = entradaDatos.nextLine();\n\t\t\t\t\t\t\tagenda.put(nombre, numero);\n\t\t\t\t\t\t\tVerAgenda(agenda);\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch (InputMismatchException e) {\n\t\t\t\t\t\tSystem.out.println(\"No ha introduciodo un numero, intente de nuevo: \");\n\t\t\t\t\t\tentradaDatos.nextLine();\n\t\t\t\t\t}\n\t\t\t\t}else if (subOpcion == 2) {\n\t\t\t\t\tSystem.out.println(\"Introduzca el nombre del contacto: \");\n\t\t\t\t\tnombre = entradaDatos.nextLine();\n\t\t\t\t\tif (agenda.containsKey(nombre)) {\n\t\t\t\t\t\tActualizarContacto(nombre, entradaDatos, agenda);\n\t\t\t\t\t\tVerAgenda(agenda);\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tSystem.out.println(\"El nombre del contacto no existe\");\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t}else {\n\t\t\t\t\tSystem.out.println(\"Opcion erronea\");\n\t\t\t\t}\n\t\t\t} else if (opcion == 4) {\n\t\t\t\tVerAgenda(agenda);\n\t\t\t\tSystem.out.println(\"Introduzca el nombre de contacto que quiera eliminar: \");\n\t\t\t\tnombre = entradaDatos.nextLine();\n\t\t\t\tagenda.remove(nombre);\n\t\t\t\tSystem.out.println(\"Contacto eliminado\");\n\t\t\t\tVerAgenda(agenda);\n\t\t\t} else if (opcion == 5) {\n\t\t\t\tSystem.out.println(\"Programa finalizado\");\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t} while (opcion != 5);\n\n\t}\n\n\tpublic static int Menu(int opcion, Scanner entradaDatos) {\n\n\t\tSystem.out.println(\"\\n*************Agenda de Contactos*************\");\n\t\tSystem.out.println();\n\t\tSystem.out.println(\"Decida la opcion que quiera realizar: \");\n\t\tSystem.out.println();\n\t\tSystem.out.println(\"Opcion 1: Buscar contacto\");\n\t\tSystem.out.println(\"Opcion 2: Nuevo contacto\");\n\t\tSystem.out.println(\"Opcion 3: Actualizar contacto\");\n\t\tSystem.out.println(\"Opcion 4: Eliminar contacto\");\n\t\tSystem.out.println(\"Opcion 5: Salir\");\n\t\tSystem.out.println();\n\t\tSystem.out.println(\"Intruzca el numero de la opcion que desee: \");\n\t\ttry {\n\t\t\topcion = entradaDatos.nextInt();\n\t\t\tentradaDatos.nextLine();\n\t\t} catch (InputMismatchException e) {\n\t\t\tSystem.out.println(\"No ha introduciodo un numero, intente de nuevo: \");\n\t\t\tentradaDatos.nextLine();\n\t\t\topcion =0;\n\t\t}\n\t\treturn opcion;\n\t}\n\n\tpublic static void NuevoContacto(String nombre, Scanner entradaDatos, HashMap<String, Long> agenda) {\n\t\ttry {\n\t\t\tSystem.out.println(\"\\nIntroduzca el numero del contacto (max 11 digitos): \");\n\t\t\tLong numero = entradaDatos.nextLong();// ---> No tiene en cuenta los 0 a la izquierda\n\t\t\tentradaDatos.nextLine();\n\t\t\tString countNum = String.valueOf(numero);\n\t\t\tif (countNum.length() > 11) {\n\t\t\t\tSystem.out.println(\"Ha excedido el limite de digitos, intente de nuevo: \");\n\t\t\t\tNuevoContacto(nombre, entradaDatos, agenda);\n\t\t\t} else {\n\t\t\t\tagenda.put(nombre, numero);\n\t\t\t\tSystem.out.println(\"Nuevo contacto creado: Nombre \" + nombre + \" | Numero \" + numero);\n\t\t\t}\n\t\t} catch (InputMismatchException e) {\n\t\t\tSystem.out.println(\"No ha introduciodo un numero, intente de nuevo: \");\n\t\t\tentradaDatos.nextLine();\n\t\t\tNuevoContacto(nombre, entradaDatos, agenda);\n\t\t}\n\n\n\t}\n\t\n\tpublic static void VerAgenda(HashMap<String, Long> agenda) {\n\n\t\tSystem.out.println(\"NOMBRE\\t\\t\\tTelefono\");\n\t\tagenda.forEach((key, value) -> System.out.println(key + \"\\t\\t\\t\" + value));\n\t}\n\tpublic static void ActualizarContacto(String nombre, Scanner entradaDatos, HashMap<String, Long> agenda) {\n\t\ttry {\n\t\t\tSystem.out.println(\"\\nIntroduzca el nuevo numero del contacto (max 11 digitos): \");\n\t\t\tLong numero = entradaDatos.nextLong();// ---> No tiene en cuenta los 0 a la izquierda\n\t\t\tentradaDatos.nextLine();\n\t\t\tString countNum = String.valueOf(numero);\n\t\t\tif (countNum.length() > 11) {\n\t\t\t\tSystem.out.println(\"Ha excedido el limite de digitos, intente de nuevo: \");\n\t\t\t\tActualizarContacto(nombre, entradaDatos, agenda);\n\t\t\t} else {\n\t\t\t\tagenda.replace(nombre, numero);\n\t\t\t\tSystem.out.println(\"Contacto acutalizado: Nombre \" + nombre + \" | Numero \" + numero);\n\t\t\t}\n\t\t} catch (InputMismatchException e) {\n\t\t\tSystem.out.println(\"No ha introduciodo un numero, intente de nuevo: \");\n\t\t\tentradaDatos.nextLine();\n\t\t\tActualizarContacto(nombre, entradaDatos, agenda);\n\t\t}\n\n\t}\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/Sniker1223.java",
    "content": "import java.util.*;\n\npublic class Sniker1223 {\n\n  private Map<String, String> contacts;\n\n  public Sniker1223() {\n    contacts = new HashMap<>();\n  }\n\n  public void addContact(String name, String phone) {\n    contacts.put(name, phone);\n    System.out.println(\"Contact added: \" + name);\n  }\n\n  public void listContacts() {\n    if (contacts.isEmpty()) {\n      System.out.println(\"Agent is empty.\");\n      return;\n    }\n    System.out.println(\"Contacts:\");\n    for (Map.Entry<String, String> entry : contacts.entrySet()) {\n      System.out.println(\"Name: \" + entry.getKey() + \", Phone: \" + entry.getValue());\n    }\n  }\n\n  public void searchContacts(String name) {\n    String phone = contacts.get(name);\n    if (phone != null) {\n      System.out.println(\"Contact found: \" + name + \", Phone: \" + phone);\n    } else {\n      System.out.println(\"Contact not found: \" + name);\n    }\n  }\n\n  public static void main(String[] args) {\n    getExampleArray(new int[] { 10, 2, 67, 4, 5 });\n    getExampleArrayList();\n    getExampleHashMap();\n\n    // Run with: javac Sniker1223.java then java Sniker1223\n    Scanner scanner = new Scanner(System.in);\n    Sniker1223 sniker = new Sniker1223();\n\n    while (true) {\n      System.out.println(\"\\nOptions:\");\n      System.out.println(\"1. Add contact\");\n      System.out.println(\"2. List contacts\");\n      System.out.println(\"3. Search contact\");\n      System.out.println(\"4. Exit\");\n      System.out.println(\"Select an option\");\n\n      int choice = scanner.nextInt();\n      scanner.nextLine();\n\n      switch (choice) {\n        case 1:\n          System.out.println(\"Name: \");\n          String name = scanner.nextLine();\n          System.out.println(\"Phone: \");\n          String phone = scanner.nextLine();\n          sniker.addContact(name, phone);\n          break;\n        case 2:\n          sniker.listContacts();\n          break;\n        case 3:\n          System.out.println(\"Name to search for: \");\n          String searchName = scanner.nextLine();\n          sniker.searchContacts(searchName);\n          break;\n        case 4:\n          System.out.println(\"Quit... \");\n          scanner.close();\n          return;\n        default:\n          System.out.println(\"Invalid choice. Try again. \");\n      }\n    }\n  }\n\n  static void getExampleArray(int[] array) {\n    // sort elements\n    Arrays.sort(array);\n\n    // Print Array\n    for (int numOfarray : array) {\n      System.out.println(numOfarray);\n    }\n\n    // Get element\n    System.out.println(array[3]);\n\n    // Update an element\n    for (int i = 0, j = 0; i < array.length; i++, j++) {\n      array[i] = j;\n    }\n\n    for (int numOfarray : array) {\n      System.out.println(numOfarray);\n    }\n  }\n\n  static void getExampleArrayList() {\n    ArrayList<String> names = new ArrayList<>();\n    // Add elements\n    names.add(\"Juan\");\n    names.add(\"Ana\");\n    // Print elements\n    System.out.println(names);\n\n    // Sort elements\n    Collections.sort(names);\n    System.out.println(names);\n    // Update elements\n    names.set(1, \"Cesar\");\n    // Get element\n    System.out.println(names.get(1));\n    // Delete element\n    names.remove(1);\n    System.out.println(names);\n  }\n\n  static void getExampleHashMap() {\n    HashMap<String, Integer> studentsAge = new HashMap<>();\n    // Add elements\n    studentsAge.put(\"Lili\", 12);\n    studentsAge.put(\"Lore\", 8);\n    studentsAge.put(\"Lucy\", 2);\n    System.out.println(studentsAge);\n\n    // get elements\n    System.out.println(studentsAge.get(\"Lili\"));\n\n    // sort by Key\n    TreeMap<String, Integer> sortedByKey = new TreeMap<>();\n    sortedByKey.putAll(studentsAge);\n    System.out.println(sortedByKey + \" ordered by key\");\n\n    // sort by value\n    // Hashmap to List\n    List<Map.Entry<String, Integer>> entryList = new ArrayList<>(studentsAge.entrySet());\n    // sort by value\n    entryList.sort(Map.Entry.comparingByValue());\n    // Create LinkedHashMap\n    LinkedHashMap<String, Integer> sortedMap = new LinkedHashMap<>();\n    for (Map.Entry<String, Integer> entry : entryList) {\n      sortedMap.put(entry.getKey(), entry.getValue());\n    }\n    System.out.println(sortedMap + \" ordered by value\");\n\n    // update element\n    studentsAge.put(\"Lucy\", 20);\n    System.out.println(studentsAge);\n\n    // Delete element\n    studentsAge.remove(\"Lore\");\n    studentsAge.remove(\"Lili\");\n    System.out.println(studentsAge);\n  }\n\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/TofeDev.java",
    "content": "import java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.HashSet;\nimport java.util.LinkedHashMap;\nimport java.util.LinkedHashSet;\nimport java.util.HashMap;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Scanner;\nimport java.util.TreeMap;\nimport java.util.TreeSet;\n\npublic class TofeDev {\n    public static void main(String[] args) {\n\n        //ARRAY------\n\n        //Array declaración manual\n        int numeros [] = new int [8]; //(con Strings se haría igual, pero en vez de int, String)\n        numeros[0] = 10;\n        numeros[1] = 51;\n        numeros[2] = 98;\n        numeros[3] = 41;\n        numeros[4] = 50;\n        numeros[5] = 39;\n        numeros[6] = 87;\n        numeros[7] = 17;\n        for (int i = 0; i<8;i++) {\n            System.out.println(\"Índice: \" + i + \" Valor: \" + numeros[i]);\n        }\n\n        //Otra forma de incersión:\n        int [] listaNum = {2, 5, 7, 10};\n\n        for (int i = 0; i<listaNum.length;i++) {\n            System.out.println(\"Índice: \" + i + \" Valor: \" + listaNum[i]);\n        }\n\n        //Array bidimencional\n        int cajas [][] = new int[3][4]; \n        cajas[0][0] = 10;\n        cajas[0][1] = 50;\n        cajas[0][2] = 75;\n        cajas[0][3] = 15;\n        cajas[1][0] = 64;\n        cajas[1][1] = 93;\n        cajas[1][2] = 34;\n        cajas[1][3] = 37;\n        cajas[2][0] = 41;\n        cajas[2][1] = 19;\n        cajas[2][2] = 24;\n        cajas[2][3] = 87;\n        for (int i = 0; i < cajas.length; i++) {\n            for (int j = 0; j < cajas[i].length; j++) {\n                System.out.print(\"Fila: \" + i + \" Columna: \" + j + \" Valor: \" + cajas[i][j] + \" \");\n            }\n            System.out.println();\n        }\n\n        //LISTAS------\n\n        //ArrayList, integer, declaración manual\n        ArrayList<Integer> listaNumeros = new ArrayList<>();\n        listaNumeros.add(5);\n        listaNumeros.add(7);\n        listaNumeros.add(3);\n        for (Integer num : listaNumeros) {\n            System.out.println(num);\n        }\n\n        //Ordenacion\n        listaNumeros.sort((a, b) -> a - b);\n        for (Integer num : listaNumeros) {\n            System.out.println(num);\n        }\n\n        //ArrayList, Strings, declaraciones con una array\n        String [] nombres = {\"Marco\",\"Maria\",\"Roberto\"};\n        List<String> listaNombres = Arrays.asList(nombres);\n        for (String nombre : listaNombres) {\n            System.out.println(nombre);\n        }\n\n        //LinkedList, Strings, datos relacionados del siguiente y el anterior\n        LinkedList<String> listaStrings = new LinkedList<>();\n        listaStrings.add(\"Hoy\");\n        listaStrings.add(\"hace\");\n        listaStrings.add(\"frio.\");\n        for (String palabras : listaStrings) {\n            System.out.println(palabras);\n        }\n\n        //Conjuntos-------\n\n        //Hashset, cada dato tiene que ser único, no asegura que los datos estén ordenados\n        HashSet<String> idiomas = new HashSet<String>();\n        idiomas.add(\"Español\");\n        idiomas.add(\"Inglés\");\n        idiomas.add(\"Portugués\");\n        idiomas.add(\"Francés\");\n        for (String idioma : idiomas) {\n            System.out.println(idioma);\n        }\n\n        //Borrado de datos\n        idiomas.remove(\"Francés\");\n        for (String idioma : idiomas) {\n            System.out.println(idioma);\n        }\n\n        /*TreeSet, los datos si están ordenados\n        (si es String se ordena en orden alfabético)*/\n        TreeSet<Integer> numOrdenados = new TreeSet<Integer>();\n        numOrdenados.add(1);\n        numOrdenados.add(100);\n        numOrdenados.add(20);\n        numOrdenados.add(50);\n        for (Integer ordenados : numOrdenados) {\n            System.out.println(ordenados);\n        }\n\n        //LinkedHashSet, mantiene el orden de incersión\n        LinkedHashSet<String> notasMusicales = new LinkedHashSet<String>();\n        notasMusicales.add(\"Do\");\n        notasMusicales.add(\"Re\");\n        notasMusicales.add(\"Mi\");\n        for (String notas : notasMusicales) {\n            System.out.println(notas);\n        }\n\n        //Mapas---------\n\n        //HashMap, un mapa con una key y un valor relacionado, no asegura que los datos estén ordenados\n        HashMap<String, Integer> mapaInventario = new HashMap<>();\n        mapaInventario.put(\"Cubo\", 2);\n        mapaInventario.put(\"Hacha\", 1);\n        mapaInventario.put(\"Carbón\", 50);\n        mapaInventario.put(\"Pan\", 20);\n        for (String key : mapaInventario.keySet()) {\n            System.out.println(key + \" - \" + mapaInventario.get(key));\n        }\n\n        //Actualización\n        mapaInventario.put(\"Pan\", 15);\n        for (String key : mapaInventario.keySet()) {\n            System.out.println(key + \" - \" + mapaInventario.get(key));\n        }\n\n        //TreeMap, los datos están ordenados según la key\n        TreeMap<Integer, String> mapaRanking = new TreeMap<>();\n        mapaRanking.put(1, \"Python\");\n        mapaRanking.put(3, \"Java\");\n        mapaRanking.put(2, \"JavaScript\");\n        for (Integer key : mapaRanking.keySet()) {\n            System.out.println(key + \" - \" + mapaRanking.get(key));\n        }\n\n        //LinkedTreeMap, mantiene el orden de incersión\n        LinkedHashMap<String, Integer> mapaRandom = new LinkedHashMap<>();\n        mapaRandom.put(\"cinco\", 5);\n        mapaRandom.put(\"uno\", 1);\n        mapaRandom.put(\"siete\", 7);\n        for (String key : mapaRandom.keySet()) {\n            System.out.println(key + \" - \" + mapaRandom.get(key));\n        }\n\n        /* DIFICULTAD EXTRA (opcional):\n        * Crea una agenda de contactos por terminal.\n        * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n        *   y eliminación de contactos.\n        * - Cada contacto debe tener un nombre y un número de teléfono.\n        * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n        *   y a continuación los datos necesarios para llevarla a cabo.\n        * - El programa no puede dejar introducir números de teléfono no númericos y con más\n        *   de 11 dígitos (o el número de dígitos que quieras).\n        * - También se debe proponer una operación de finalización del programa.\n        */\n\n        System.out.println(\"---------AGENDA---------\");\n        Scanner name = new Scanner(System.in);\n        Scanner number = new Scanner(System.in);\n        Scanner eleccion = new Scanner(System.in);\n        Scanner buscar = new Scanner(System.in);\n        Scanner actualizar = new Scanner(System.in);\n        Scanner actualizarNum = new Scanner(System.in);\n\n        Map<String, Long> agenda = new HashMap<>();\n\n        System.out.println(\"\"\"\n                    Seleccione una opción:\n                    1. Agregar contacto\n                    2. Buscar contacto\n                    3. Actualizar contacto\n                    4. Borrar contacto\n                    5. Salir \"\"\");\n\n        int opcion = eleccion.nextInt();\n\n        while (opcion != 5) {\n            // Agregar contacto\n            if (opcion == 1) {\n                System.out.print(\"Ingrese el nombre del contacto: \");\n                String nombre = name.nextLine();\n                System.out.print(\"Ingrese el número del contacto: \");\n                Long numero = number.nextLong();\n                agenda.put(nombre, numero);\n            } else if (opcion == 2) {\n            // Buscar contacto\n                System.out.print(\"Ingrese el nombre del contacto a buscar: \");\n                String buscarNombre = buscar.nextLine();\n                Long numberFind = agenda.get(buscarNombre);\n                if (numberFind != null) {\n                    System.out.println(\"Resultado de la búsqueda: \");\n                    System.out.println(\"Nombre: \" + buscarNombre + \" Número: \" + numberFind);\n                } else {\n                    System.out.println(\"Resultado de la búsqueda: \");\n                    System.out.println(\"El nombre ingresado no está en la agenda de contactos.\");\n                }\n                System.out.println();\n            } else if (opcion == 3) {\n            // Actualizar número de contacto\n                System.out.print(\"Ingrese el nombre del contacto a actualizar: \");\n                String actualizarContacto = actualizar.nextLine();\n                System.out.print(\"Ingrese el nuevo núnero: \");\n                Long nuevoNumero = actualizarNum.nextLong();\n                agenda.put(actualizarContacto, nuevoNumero);\n                System.out.println(\"Contacto actualizado.\" + actualizarContacto);\n            } else if (opcion == 4) {\n            // Eliminar contacto\n                System.out.print(\"Ingrese el nombre del contacto a eliminar: \");\n                String eliminarContaco = actualizar.nextLine();\n                agenda.remove(eliminarContaco);\n                System.out.println(\"Contacto eliminado: \" + eliminarContaco);\n            } else if (opcion > 5 || opcion == 0) {\n                System.out.println(\"Opción no valida. Intente de nuevo\");\n            }\n            System.out.println(\"Agenda\" + agenda);\n            System.out.println(\"\"\"\n                    Seleccione una opción:\n                    1. Agregar contacto\n                    2. Buscar contacto\n                    3. Actualizar contacto\n                    4. Borrar contacto\n                    5. Salir \"\"\");\n            opcion = eleccion.nextInt();\n        }\n        name.close();\n        number.close();\n        buscar.close();\n        actualizar.close();\n        actualizarNum.close();\n        eleccion.close();\n    }\n\n}"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/Verschlingendenacht.java",
    "content": "package source;\n\nimport java.util.*;\n\npublic class Verschlingendenacht {\n    \n    public static void main(String[] args){\n        //arreglos();\n        //arreglosBidimensionales();\n        //arrayLists();\n        //stacks();\n        //queues();\n        //linkedLists();\n        //sets();\n        //maps();\n        extra();\n    }\n\n    public static void arreglos(){\n        String[] colors = new String[5];\n\n        colors[0] = \"Green\";\n        colors[1] = \"Yellow\";\n        colors[2] = \"Purple\";\n        colors[3] = \"Red\";\n        colors[4] = \"Blue\";\n\n        System.out.println(Arrays.toString(colors));\n\n        int[] numbers = {100, 200, 300};\n\n        for(int i = 0; i < numbers.length; i++){\n            System.out.println(numbers[i]);\n        }\n\n        for(int i = numbers.length-1; i >= 0; i--){\n            System.out.println(numbers[i]);\n        }\n\n        for(int number : numbers){\n            System.out.println(number);\n        }\n\n        Arrays.stream(numbers).forEach(System.out::println);\n        //el doble :: nos permite referenciar una funcion o metodo sin llamarla dentro de otra funcion como foreach\n\n        //La clase arrays contiene muchos metodos para lidiar con arreglos\n        //Pero debemos recordar que los arreglos en Java no pueden cambiar su tamaño, por tanto no podemos realizar operaciones como eliminar realmente\n        //Si queremos actualizar algun elemento de nuestro arreglo basta con usar el operador de asignacion a modo de actualizacion:\n        colors[0] = \"Pink\";\n        System.out.println(colors[0]);\n\n        //Mientras que, si queremos eliminar un elemento, lo mejor sera asignarle un valor null\n\n    }\n\n    public static void arreglosBidimensionales(){\n\n        char[][] board = new char[3][3];\n\n        for(int i = 0; i < 3; i++){\n            for(int j = 0; j < 3; j++){\n                board[i][j] = '-';\n            }\n        }\n\n        System.out.println(Arrays.deepToString(board)); //usamos deepToString ya que es un arreglo bidimensional\n\n        char[][] board2 = {\n                new char[] {'-','-','-'},\n                new char[] {'-','-','-'},\n                new char[] {'-','-','-'}\n        };\n\n        System.out.println(Arrays.deepToString(board2));\n\n    }\n\n    public static void arrayLists(){\n        /*\n        las listas son implentaciones de las colecciones (las listas son interfaces que al mismo tiempo implementan a las colecciones)\n        la diferencia entre una coleccion y una lista es que la lista contiene mas informacion y metodos\n         */\n\n        //A pesar de que podemos hacer algo como esto como hariamos en Python:\n        List colors = new ArrayList();\n        colors.add(\"Blue\");\n        colors.add(\"Purple\");\n        colors.add(1);\n        colors.add(true);\n        colors.add(new Object());\n\n        //O esto:\n\n        ArrayList names = new ArrayList();\n        names.add(\"Alejandro\");\n        names.add(\"Carlos\");\n        names.add(\"Oscar\");\n\n        //Debemos tomar preferencia por determinar el tipo a almacenar usando <> (formalizacion) y usar el contrato en la declaracion de la lista\n        //NOTA: El operador <> no admite tipos primitivos\n        List<String> colors2 = new ArrayList<>();\n        colors2.add(\"Red\");\n        colors2.add(\"Yellow\");\n        //colors2.add(1); Esta linea resulta en un error de restriccion\n\n        //ELIMINAR\n        names.remove(\"Alejandro\");\n        names.remove(1);\n\n        //ACTUALIZAR\n        colors2.set(0, \"Blue\");\n\n        //Al usar List en la declaracion no nos preocupamos por la implementacion que usemos en la asignacion, en la asignacion solo referenciaremos el constructor de alguna implementacion de List como ArrayList\n\n        System.out.println(colors2); //Imprime los contenidos de la lista por defecto\n        System.out.println(colors2.contains(\"Yellow\")); //Imprime la existencia o no del elemento especificado\n\n        //Tambien podemos iterar listas de la forma clasica\n        for(String color : colors2){\n            System.out.println(color);\n        }\n\n        colors2.forEach(System.out::println);\n\n        //List tambien nos permite simular tuplas por medio del metodo of el cual retorna una lista inmutable\n        List<String> colorsUnmodifiable = List.of(\"blue\",\"red\",\"black\");\n        //colorsUnmodifiable.add(\"white\"); Esta linea resulta en un error de modificacion\n\n        System.out.println(colorsUnmodifiable);\n\n    }\n\n    public static void stacks(){\n        /*\n        Podemos pensar en un stack como una lata de pringles.\n        Esto quiere decir que la primera papa en entrar es la ultima en salir\n         */\n\n        //Se declaran de la misma forma que declarariamos una lista\n        //Al igual que con las listas, el parametro de tipo para un stack no puede ser primitivo\n        //Por ello usamos clases envolventes o wrapper classes en su lugar\n        Stack<Integer> numbers = new Stack<>();\n\n        //push() añade items al stack en orden desde el indice 0\n        numbers.push(1);\n        numbers.push(20);\n        numbers.push(43);\n\n        System.out.println(numbers.peek()); //con peek() podemos ver el item almacenado en el ultimo indice (o en este caso, encima del stack)\n        System.out.println(numbers.size()); //retorna el tamaño del stack\n        System.out.println(numbers.pop()); //elimina el elemento en el ultimo indice y lo retorna\n        System.out.println(numbers.size());\n        System.out.println(numbers.empty()); //Retorna si el stack se encuentra vacio o no\n        System.out.println(numbers.search(20)); //Retorna el indice del objeto a buscar\n        numbers.set(0, 10); //Actualiza el indice 0\n\n        /*\n        Stack hereda de Vector y Vector es una implementacion de List, por lo tanto, Stack es una implementacion de List.\n        La diferencia entre un Stack y una lista es que los stack son sincronos,\n        mientras que las listas se emplean en entornos multithreading, por ello se debe\n        saber cuando emplear un stack dado que puede ralentizar algunas operaciones\n         */\n\n        //Entonces, esto nos permite tener objetos como este\n        List<Integer> numbers2 = new Stack<>();\n        numbers2.add(2); //Ahora podemos usar metodos de List mientras conserva algo del comportamiento de un Stack\n\n        //Por ejemplo, ya que Stack no sobreescribe add() podemos emplearlo como si fuese push()\n        //En resumen, podremos usar metodos de List mientras no esten sobreescritos por Stack para este caso\n        //Aun asi, lo recomendable es declarar la variable como Stack\n\n    }\n\n    public static void queues(){\n\n        /*\n        Podemos pensar en las queues como \"primero que llega primero que sale\"\n        de la misma forma que se haria en una fila, por definicion, una queue se refiere a\n        una coleccion diseñada para almacenar elementos antes de procesarlos\n         */\n\n        //Ya que Queue es una interface, declaremos la siguiente queue usando una de sus implementaciones\n        Queue<Persona> filaMercado = new LinkedList<>();\n\n        //AÑADIR\n        filaMercado.add(new Persona(\"Alejandro\", 22));\n        filaMercado.add(new Persona(\"Maria\",31));\n        filaMercado.add(new Persona(\"Carlos\", 18));\n\n\n        System.out.println(filaMercado.peek());\n        //Podemos ver entonces que, a diferencia de un stack, en una queue, quien va primero o encima es quien primero ingresa\n\n        System.out.println(filaMercado.size());\n        System.out.println(filaMercado.poll()); //Equivalente a pop() en stacks, poll elimina el objeto a la cabeza\n        System.out.println(filaMercado.size());\n        System.out.println(filaMercado.peek()); //Podemos ver que ahora la cabeza de la queue se ha movido al siguiente objeto\n\n        //Tambien contamos con otros metodos adicionales:\n        System.out.println(filaMercado.remove()); //Misma utilidad que poll, difiere en que arroja una excepcion si la queue se encuentra vacia\n        System.out.println(filaMercado.offer(new Persona(\"Oscar\", 25))); //Misma utilidad que add, difiere en que no arroja una excepcion en caso de restricciones de tamaño como si lo haria add(), simplemente arroja un booleano confirmando el resultado de la operacion\n        System.out.println(filaMercado.isEmpty()); //Retorna si la queue se encuentre vacia o no\n    }\n\n    public static void linkedLists(){\n        /*\n        Como sabemos, linkedList es una implementacion de Queues\n        Conceptualmente, las linkedLists son cadenas de nodos (siendo los nodos de los extremos cabeza y cola respectivamente), donde cada nodo contiene 2 cosas:\n        1- Un valor u objeto almacenado\n        2- Una o dos referencias\n\n        La referencia representara ya sea el nodo anterior o posterior\n        Aqui es donde tenemos dos casos, si una linkedList contiene dos referencias se considera una linkedList bidireccional donde cada referencia apunta al nodo anterior y posterior\n        De lo contrario, la referencia de cada nodo apuntara unicamente a uno de los nodos en una direccion determinada\n\n        Cabe entender que: si queremos añadir un nodo a nuestra linkedList, debemos crear este nodo antes de insertarlo teniendo en cuenta las dos caracteristicas mencionadas anteriormente\n        esto quiere decir que, para cada agregado debemos actualizar las referencias\n         */\n\n        LinkedList<Persona> linkedList = new LinkedList<>();\n\n        //AÑADIR\n        linkedList.add(new Persona(\"Roberto\", 43));\n        linkedList.add(new Persona(\"Alex\", 18));\n        linkedList.addFirst(new Persona(\"Elizabeth\", 25));\n        linkedList.addLast(new Persona(\"Julian\", 39));\n        linkedList.add(2, new Persona(\"Carolle\", 30));\n\n        //ELIMINAR\n        linkedList.remove(2);\n        linkedList.remove(new Persona(\"Alex\", 18));\n\n        //ACTUALIZAR\n        linkedList.set(0, new Persona(\"Arthur\", 27));\n\n        //Podemos iterar esta linkedList por medio de listIterator()\n        ListIterator<Persona> personaListIterator = linkedList.listIterator(); //listIterator() nos permite acceder a metodos que nos permiten tener visualizacion de los nodos en una linkedList\n\n        //listIterator cuenta con un cursor o un marcador de posicion entre los nodos, este nodo se inicializa antes del primer elemento\n        while(personaListIterator.hasNext()){ //Solo itera mientras haya un nodo a la derecha del cursor\n            System.out.println(personaListIterator.next()); //En caso de haber un nodo a la derecha del cursor, imprime este mismo y el cursor es ubicado antes del nuevo nodo\n        }\n\n        //para poder usar previous debemos haber movido el cursor al final de la linkedList\n        while(personaListIterator.hasPrevious()){\n            System.out.println(personaListIterator.previous()); //de esta forma se imprime el anterior y el cursor es movido a la derecha del nuevo nodo\n        }\n\n        //Aun asi, podemos seguir empleando las mismas visualizaciones a cuando se emplean listas:\n        System.out.println(linkedList);\n\n        for(Persona persona : linkedList){\n            System.out.println(persona);\n        }\n\n        for (int i = 0; i < linkedList.size(); i++){\n            System.out.println(linkedList.get(i));\n        }\n\n    }\n\n    public static void sets(){\n        /*\n        Podemos pensar en los sets como colecciones desordenadas donde ningun elemento se repite\n        por ello podemos imaginar a los sets como bolsas\n         */\n\n        //Los sets son interfaces con varias implementaciones\n        Set<Pelota> pelotas = new HashSet<>();\n        pelotas.add(new Pelota(\"Blue\"));\n        pelotas.add(new Pelota(\"Yellow\"));\n        pelotas.add(new Pelota(\"Red\"));\n\n        pelotas.forEach(System.out::println);\n\n        //Si llegas a añadir un duplicado al set este sera ignorado y no habran cambios\n        //El set define un duplicado como objetos de igual constructor, campos, metodos, etc\n        //Podriamos tener una clase dedicada a pelotas al mismo tiempo que el record, esto permitira duplicados (mientras no se sobreescriba equals, hashcode y toString)\n\n        //Cabe tambien mencionar que una de las implementaciones de set son los TreeSet los cuales otorgan un orden natural a sus elementos (alfabetico o numerico)\n\n        //ELIMINAR\n        //Ya que los hashset no cuentan con indices, solo podemos eliminar referenciando el objeto como tal a eliminar\n        pelotas.remove(new Pelota(\"Yellow\"));\n\n    }\n\n    public static void maps(){\n        /*\n        Podemos pensar en los maps como colecciones de clave valor\n        Para el caso de la clase Map, esta se refiere a una interfaz con multiples implementaciones como:\n\n        -> HashTable = no permite valores null, sincronizado (si trabajas con multithreading, esta opcion puede ser mas lenta)\n        -> HashMap = permite valores null\n            -> LinkedHashMap = permite valores null, implementacion basada en linkedList, lento\n       -> SortedMap\n       -> NavigableMap\n       -> TreeMap = Ordenado, no permite valores null\n         */\n\n        Map<Integer, Persona> map = new HashMap<>();\n\n        //AÑADIR\n        map.put(1, new Persona(\"Alexander\", 24));\n        map.put(2, new Persona(\"Carolina\", 23));\n        map.put(3, new Persona(\"Martin\", 26));\n\n        //ACTUALIZAR\n        //Podemos actualizar un item reasignando por medio del mismo indice\n        map.put(3, new Persona(\"Garcia\", 31));\n        System.out.println(map);\n\n        //ELIMINAR\n        map.remove(2);\n        System.out.println(map);\n\n        //Otros metodos:\n        System.out.println(map.size()); //retorna el tamaño\n        System.out.println(map.get(1)); //retorna el item por medio de su llave\n        System.out.println(map.containsKey(4)); //retorna si existe la llave o no\n        System.out.println(map.keySet()); //retorna un set con las llaves del hashmap\n        System.out.println(map.values()); //Retorna un set con los valores del hashmap\n        System.out.println(map.entrySet()); //retorna un set con los items del hashmap\n        System.out.println(map.getOrDefault(2, new Persona(\"Gomez\", 34))); //Retora el elemento que tiene como llave el primer parametro, de lo contrario, usa esta llave y asigna el segundo parametro como su nuevo valor\n\n        //Tambien podemos usar getKey y getValue en los elementos de un map\n        map.entrySet().forEach(persona -> System.out.println(persona.getKey() + \" \" + persona.getValue()));\n        map.forEach((llave, persona) -> System.out.println(llave + \" \" + persona));\n\n        ////////////////////////////////////////////////\n        //funciones Hash y HashCode\n        /*\n        Cuando ejecutamos por ejemplo map.put(1, \"Hello\"), map ingresa la llave a una funcion hash la cual retornada un hashcode el cual sera usado para referenciar la llave internamente\n        en el caso de numeros enteros, el hashcode resultante termina siendo el mismo numero.\n        Pero hay casos en donde puede que tengamos algo como:\n\n        map.put(new Person(\"Camila\"), new Diamante());\n\n        Aqui estamos usando un objeto como llave, entonces, lo que resulta de la funcion hash al pasar esto como parametro sera un hashcode que sera un numero entero dificil de leer como -2083476985, a diferencia de con un entero, este sera generado por un algoritmo especifco.\n        numero que map usara para referenciar a la llave de este elemento del map, cabe recalcar que no importa cuantas veces ingresemos esta llave, siempre se retornara la misma llave.\n\n        Esto no es eficiente y es por ello recomendable que sobreescribamos los metodos equals y hashcode en nuestras clases\n         */\n\n        Map<Persona, Auto> map2 = new HashMap<>();\n\n        map2.put(new Persona(\"Isabela\", 29), new Auto(\"Mercedes\"));\n\n        System.out.println(map2.get(new Persona(\"Isabela\", 29))); //si no hemos sobreescrito la clase de la llave, esto retornara null, la busqueda se hace comparando los hashcodes de ambas partes, nunca entre los objetos por si mismos\n    }\n\n    public static void extra(){\n\n        int opcion;\n        Scanner scanner = new Scanner(System.in);\n        boolean ejecutar = true;\n        String menu = \"-AGENDA DE CONTACTOS- \\n\\n\"+\"1-Buscar Contactos\\n\"+\"2-Insertar Contactos\\n\"+\"3-Actualizar Contactos\\n\"+\"4-Eliminar Contactos\\n\"+\"5-Finalizar Programa\\n\";\n\n        String restriccionNumero = \"^\\\\d{10}$\";\n\n        List<List<Object>> contactos = new ArrayList<>();\n\n        while(ejecutar){\n            System.out.println();\n            System.out.println(menu);\n            System.out.println();\n            System.out.print(\"Ingresa una opcion: \");\n            try{\n                opcion = Integer.parseInt(scanner.nextLine());\n                if(opcion < 1 || opcion > 5){\n                    throw new Exception();\n                }\n            }catch(Exception e){\n                System.out.println(\"ERROR: Ingresa un numero u opcion valida\");\n                continue;\n            }\n\n            switch(opcion){\n                case 5:\n                    System.out.println(\"Fin del Programa\");\n                    ejecutar = false;\n                    break;\n                case 1:\n\n                    int opcionMenuBuscar;\n\n                    while(true){\n                        try{\n                            System.out.println(\"1- Mostrar todos los contactos\");\n                            System.out.println(\"2- Buscar contacto en especifico\");\n                            opcionMenuBuscar = Integer.parseInt(scanner.nextLine());\n                            if(opcionMenuBuscar < 1 || opcionMenuBuscar > 2){\n                                throw new Exception();\n                            }\n                            break;\n                        }catch (Exception e){\n                            System.out.println(\"Ingresa una opcion valida\");\n                        }\n                    }\n\n                    if(opcionMenuBuscar == 1){\n                        for(List<Object> c : contactos){\n                            System.out.println(c);\n                        }\n                    }else{\n                        System.out.println(\"Ingresa el Nombre o Numero del contacto a buscar\");\n                        String busqueda = scanner.nextLine();\n                        String resultado = \"\";\n                        for(List<Object> contacto : contactos){\n                            if(contacto.get(0).toString().equalsIgnoreCase(busqueda) || contacto.get(1).toString().equals(busqueda)){\n                                resultado = contacto.toString();\n                            }\n                        }\n\n                        if(resultado.isEmpty()){\n                            System.out.println(\"No se encontro algun contacto relacionado\");\n                        }else{\n                            System.out.println(resultado);\n                        }\n                    }\n\n                    break;\n                case 2:\n\n                    String nombreIngresar;\n                    String numeroIngresar;\n\n                    while(true){\n                        try{\n                            System.out.print(\"Nombre: \");\n                            nombreIngresar = scanner.nextLine();\n                            if(nombreIngresar.isBlank() || nombreIngresar.length() > 25){\n                                throw new Exception();\n                            }\n                            break;\n                        }catch(Exception e){\n                            System.out.println(\"ERROR: Ingresa un nombre valido\");\n                        }\n                    }\n\n                    while(true){\n                        try{\n                            System.out.print(\"Numero: \");\n                            numeroIngresar = scanner.nextLine();\n                            if(numeroIngresar.isBlank() || !numeroIngresar.matches(restriccionNumero)){\n                                throw new Exception();\n                            }\n                            break;\n                        }catch(Exception e){\n                            System.out.println(\"ERROR: Ingresa un numero valido\");\n                        }\n                    }\n\n                    contactos.add(Arrays.asList(nombreIngresar, numeroIngresar));\n                    break;\n\n                case 3:\n                    int opcionContacto = -1;\n                    int opcionMenuActualizar;\n                    for(int i = 0; i < contactos.size(); i++){\n                        System.out.println((i+1)+\"-\"+contactos.get(i));\n                    }\n                    while(true){\n                        if(contactos.isEmpty()){\n                            break;\n                        }\n                        try{\n                            System.out.print(\"Escribe el identificador del contacto a actualizar: \");\n                            opcionContacto = Integer.parseInt(scanner.nextLine());\n                            if(opcionContacto < 1 || opcionContacto > contactos.size()){\n                                throw new Exception();\n                            }\n                            break;\n                        }catch (Exception e){\n                            System.out.println(\"Ingresa un identificador valido\");\n                        }\n                    }\n\n                    while(true){\n                        try{\n                            System.out.println(\"¿Que deseas actualizar?\");\n                            System.out.println(\"1- Nombre\");\n                            System.out.println(\"2- Numero\");\n                            opcionMenuActualizar = Integer.parseInt(scanner.nextLine());\n                            if(opcionMenuActualizar < 1 || opcionMenuActualizar > 2){\n                                throw new Exception();\n                            }\n                            break;\n                        }catch (Exception e){\n                            System.out.println(\"Ingresa una opcion valida\");\n                        }\n                    }\n\n                    if(opcionMenuActualizar == 1){\n                        String nombreNuevo;\n                        while(true){\n                            try{\n                                System.out.print(\"Nombre: \");\n                                nombreNuevo = scanner.nextLine();\n                                if(nombreNuevo.isBlank() || nombreNuevo.length() > 25){\n                                    throw new Exception();\n                                }\n                                break;\n                            }catch(Exception e){\n                                System.out.println(\"ERROR: Ingresa un nombre valido\");\n                            }\n                        }\n                        contactos.get(opcionContacto-1).set(0, nombreNuevo);\n\n                    }else{\n                        String numeroNuevo;\n                        while(true){\n                            try{\n                                System.out.print(\"Numero: \");\n                                numeroNuevo = scanner.nextLine();\n                                if(numeroNuevo.isBlank() || !numeroNuevo.matches(restriccionNumero)){\n                                    throw new Exception();\n                                }\n                                break;\n                            }catch(Exception e){\n                                System.out.println(\"ERROR: Ingresa un numero valido\");\n                            }\n                        }\n                        contactos.get(opcionContacto-1).set(1, numeroNuevo);\n                    }\n\n                    break;\n\n                case 4:\n                    int opcionEliminar = -1;\n                    for(int i = 0; i < contactos.size(); i++){\n                        System.out.println((i+1)+\"-\"+contactos.get(i));\n                    }\n\n                    while(true){\n                        if(contactos.isEmpty()){\n                            break;\n                        }\n                        try{\n                            System.out.print(\"Escribe el identificador del contacto a eliminar: \");\n                            opcionEliminar = Integer.parseInt(scanner.nextLine());\n                            if(opcionEliminar < 1 || opcionEliminar > contactos.size()){\n                                throw new Exception();\n                            }\n                            break;\n                        }catch (Exception e){\n                            System.out.println(\"Ingresa un identificador valido\");\n                        }\n                    }\n\n                    contactos.remove(contactos.get(opcionEliminar-1));\n                    break;\n\n            }\n        }\n    }\n\n    //DTOS para ejemplos [queues, sets]\n    static class Persona{\n\n        String nombre;\n        int edad;\n\n        public Persona(String nombre, int edad) {\n            this.nombre = nombre;\n            this.edad = edad;\n        }\n\n        @Override\n        public String toString() {\n            return \"Persona{\" +\n                    \"nombre='\" + nombre + '\\'' +\n                    \", edad=\" + edad +\n                    '}';\n        }\n\n        @Override //sobreescribir equals es necesario para la comparacion al momento de buscar un elemento\n        public boolean equals(Object o) {\n            if (o == null || getClass() != o.getClass()) return false;\n            Persona persona = (Persona) o;\n            return edad == persona.edad && Objects.equals(nombre, persona.nombre);\n        }\n\n        @Override //Esta es la funcion hash, sin esta sobreescritura, no se puede encontrar elementos en un map donde su llave sea un objeto, hace que objetos identicos retornen exactamente el mismo hashcode\n        public int hashCode() {\n            return Objects.hash(nombre, edad); //retorna un hashcode\n        }\n    }\n    //record Persona(String nombre, int edad){}\n    record Pelota(String color){}\n    record Auto(String marca){}\n\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/Worlion.java",
    "content": "import java.util.TreeMap;\nimport java.util.LinkedList;\nimport java.util.HashSet;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.Queue;\nimport java.util.Scanner;\n\npublic class Worlion {\n\n            \n    Scanner scanner = new Scanner(System.in);\n    HashMap<String, String> agenda = new HashMap<>();\n\n    public static void main(String[] args) {\n        System.out.println(\"Estructuras de datos en Java\");\n\n        new Worlion().run();\n    }\n\n    public void run() {\n        estructurasDeDatos();\n        extra();\n    }\n\n    /*\n    * EJERCICIO: Estructuras de datos en Java\n    */\n\n    private void estructurasDeDatos() {\n        // Ejemplos de creación de estructuras de datos en Java\n        // Arrays\n        int [] numbers = new int[5];\n\n        // ArrayList\n        ArrayList<String> listaCadenas = new ArrayList<>();\n        System.out.println(\"Lista: \" +listaCadenas);\n\n        //HashMap\n        HashMap<Integer, String> mapaEnteroCadena = new HashMap<>();\n        System.out.println(\"Mapa: \" +mapaEnteroCadena);\n\n        //HashSet \n        HashSet<String> conjuntoCadenas = new HashSet<>();\n        System.out.println(\"Conjunto: \" +conjuntoCadenas);\n\n        // LinkedList\n        LinkedList<Integer> listaEnteros = new LinkedList<>();\n        System.out.println(\"Lista: \" +listaEnteros);\n\n        // TreeMap\n        TreeMap<String, Integer> mapaCadenaEntero = new TreeMap<>();\n        System.out.println(\"Mapa: \" +mapaCadenaEntero);\n\n        // Cola\n        Queue<Integer> cola = new LinkedList<>();\n        System.out.println(\"Cola: \" +cola);\n\n        // inserción \n        listaCadenas.add(\"Hola\");\n        listaCadenas.add(\"Mundo\");\n        listaCadenas.add(\"Java\");\n        listaCadenas.add(\"Estructuras de datos\");\n\n        System.out.println(\"Lista tras la inserción: \" +listaCadenas);\n        \n        //borrado, \n        listaCadenas.remove(\"Java\");\n        System.out.println(\"Lista tras borrado: \" +listaCadenas);\n        \n        //actualización \n        listaCadenas.set(2, \"Java\");\n        System.out.println(\"Lista tras actualización: \" +listaCadenas);\n        \n        //ordenación.\n        listaCadenas.sort(null);\n        System.out.println(\"Lista ordenada: \" +listaCadenas);\n    }\n\n\n    private void extra() {\n\n        /*\n        * DIFICULTAD EXTRA (opcional): Agenda de contactos\n        */\n\n        \n\n        System.out.println(\" \\n ---- 🌩 DIFICULTAD EXTRA 🌩 ----\\n\");\n\n        var option = \"\";\n        while(!option.equals(\"0\")){\n\n            option = showMenu();\n            manageOption(option);\n        }\n    \n    }\n\n    private String showMenu() {\n        \n        System.out.println(\"\\n AGENDA DE CONTACTOS\\n\");\n        System.out.println(\"\\t 1.- Búsqueda de un contacto\");\n        System.out.println(\"\\t 2.- Añadir un contacto\");\n        System.out.println(\"\\t 3.- Actualización de un contacto\");\n        System.out.println(\"\\t 4.- Borrar un contacto\");\n        System.out.println(\"\\t 5.- Mostrar agenda (extra)\");\n        System.out.println(\"\\t 0.- Salir\");\n        System.out.println(\"\\n Selecciona una opción:\");\n        return scanner.nextLine();\n    }\n\n    private void manageOption(String option) {\n        switch (option) {\n            case \"1\":\n                System.out.println(findContact());\n                break;\n            case \"2\":\n                addContact();\n                break;\n            case \"3\":\n                updateContact();\n                break;\n            case \"4\":\n                deleteContact();\n                break;\n            case \"5\":\n                showDirectory();\n                break;\n            case \"0\":\n                System.out.println(\"Saliendo...\");\n                break;\n            default:\n                System.out.println(\"WARNING: Opción no válida\");\n                break;\n        }\n    }\n\n    private String findContact() {\n        System.out.println(\"Introduce el nombre del contacto que quieres buscar:\");\n        var name = scanner.nextLine();\n        var phone = agenda.get(name);\n\n        if(phone != null){\n            return phone;\n        } else {\n            return \"No se ha encontrado el contacto\";\n        }\n    }\n\n    private void addContact() {\n        System.out.println(\"Introduce el nombre del contacto que quieres añadir:\");\n        var name = scanner.nextLine();\n        System.out.println(\"Introduce el teléfono del contacto que quieres añadir:\");\n        var phone = readValidPhone();\n        if(phone != null){\n            agenda.put(name, phone);\n            System.out.println(\"Contacto añadido\");\n        } else {\n            System.out.println(\"ERROR: No se ha podido añadir el contacto\");\n        }\n    }\n\n    private void updateContact(){\n        System.out.println(\"Introduce el nombre del contacto que quieres actualizar:\");\n        var name = scanner.nextLine();\n        var phone = readValidPhone();\n        if(phone != null){\n            agenda.put(name, phone);\n            System.out.println(\"Contacto actualizado\");\n        } else {\n            System.out.println(\"ERROR: No se ha podido actualizar el contacto\");\n        }\n    }\n\n    private void deleteContact(){\n        System.out.println(\"Introduce el nombre del contacto que quieres eliminar:\");\n        var name = scanner.nextLine();\n        var phone = agenda.get(name);\n        if(phone != null){\n            agenda.remove(name);\n            System.out.println(\"Contacto eliminado\");\n        } else {\n            System.out.println(\"ERROR: No se ha encontrado el contacto\");\n        }\n    }\n\n    private void showDirectory(){\n        System.out.println(\"\\nAgenda de contactos:\");\n        for (String name : agenda.keySet()) {\n            System.out.println(\" - Nombre: \" + name + \" - Teléfono: \" + agenda.get(name));\n        }\n        System.out.println(\"\\nTotal de contactos: \" + agenda.size() + \"\\n\");\n    }\n\n    private String readValidPhone() {\n        System.out.println(\"Introduce el teléfono:\");\n        var phone = scanner.nextLine();\n        while(!validPhone(phone)){\n            System.out.println(\" # Teléfono no valido # ¿Desea volver a intentarlo? (s/n): \");\n            var retry = scanner.nextLine();\n            if(retry.equals(\"n\")){\n                return null;\n            }\n            System.out.println(\"Introduce el teléfono:\");\n            phone = scanner.nextLine();\n        }\n        return phone;\n    \n    }\n\n    private boolean validPhone(String phone) {\n        return phone.matches(\"[0-9]+\") && phone.length() <= 11;\n    }\n\n\n\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/agusrosero.java",
    "content": "import java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Scanner;\nimport java.util.Set;\n\npublic class agusrosero {\n    public static void main(String[] args) {\n        // Arrays\n        String[] array = new String[3];\n\n        array[0] = \"Hola\";\n        array[1] = \"Mundo\";\n        array[2] = \"Java\";\n\n        // Lista\n        List<String> list = new ArrayList<>();\n        list.add(\"Hola\");\n        list.add(\"Mundo\");\n        list.add(\"Java\");\n\n        list.clear();\n\n        // Set\n        Set<String> set = new HashSet<>();\n\n        set.add(\"Hola\");\n        set.add(\"Mundo\");\n        set.add(\"Java\");\n\n        set.clear();\n\n        // Map\n        Map<String, String> hashMap = new HashMap<>();\n\n        hashMap.put(\"Hola\", \"Mundo\");\n        hashMap.put(\"Java\", \"Kotlin\");\n\n        hashMap.clear();\n\n        /*\n         * * DIFICULTAD EXTRA (opcional):\n         * Crea una agenda de contactos por terminal.\n         * - Debes implementar funcionalidades de búsqueda, inserción, actualización y\n         * eliminación de contactos.\n         * - Cada contacto debe tener un nombre y un número de teléfono.\n         * - El programa solicita en primer lugar cuál es la operación que se quiere\n         * realizar, y a continuación\n         * los datos necesarios para llevarla a cabo.\n         * - El programa no puede dejar introducir números de teléfono no númericos y\n         * con más de 11 dígitos.\n         * (o el número de dígitos que quieras)\n         * - También se debe proponer una operación de finalización del programa.\n         */\n        System.out.println(\"*** Agenda de contactos ***\");\n        System.out.println(\"1. Buscar contacto\");\n        System.out.println(\"2. Insertar contacto\");\n        System.out.println(\"3. Actualizar contacto\");\n        System.out.println(\"4. Eliminar contacto\");\n        System.out.println(\"5. Salir\");\n\n        Scanner scanner = new Scanner(System.in);\n        int option = 0;\n        List<String> contacts = new ArrayList<>();\n\n        while (true) {\n            System.out.print(\"Seleccione una opcion: \");\n            option = scanner.nextInt();\n            switch (option) {\n                case 1:\n                    System.out.print(\"Ingrese un nombre: \");\n                    String search = scanner.next();\n                    for (String contact : contacts) {\n                        if (contact.contains(search)) {\n                            System.out.println(contact);\n                        } else {\n                            System.out.println(\"Contacto no encontrado\");\n                        }\n                    }\n                    break;\n                case 2:\n                    System.out.print(\"Ingrese un nombre: \");\n                    String name = scanner.next();\n                    System.out.print(\"Ingrese un número de teléfono: \");\n                    String phoneNumber = scanner.next();\n                    contacts.add(name + \" - \" + phoneNumber);\n                    break;\n                case 3:\n                    System.out.print(\"Ingrese el nombre del contacto a actualizar: \");\n                    String oldName = scanner.next();\n                    System.out.print(\"Ingrese el nuevo nombre: \");\n                    String newName = scanner.next();\n                    System.out.print(\"Ingrese el nuevo número de teléfono: \");\n                    String newPhoneNumber = scanner.next();\n                    for (String contact : contacts) {\n                        if (contact.contains(oldName)) {\n                            contacts.remove(contact);\n                            contacts.add(newName + \" - \" + newPhoneNumber);\n                        }\n                    }\n                    break;\n                case 4:\n                    System.out.print(\"Ingrese el contacto a eliminar: \");\n                    String contact = scanner.next();\n                    contacts.remove(contact);\n                    break;\n                case 5:\n                    System.out.println(\"Saliendo...\");\n                    scanner.close();\n                    System.exit(0);\n                    break;\n                default:\n                    System.out.println(\"Opción no válida\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/alvarofernandezavalos.java",
    "content": "import java.util.ArrayList;\nimport java.util.Scanner;\n\npublic class alvarofernandezavalos {\n\n  public static class Contacto {\n    public String nombre;\n    public long telefono;\n\n    public Contacto (String nombre, long telefono) {\n      this.nombre = nombre;\n      this.telefono = telefono;\n    }\n\n    public String getNombre() {\n      return nombre;\n    }\n\n    public long getTelefono() {\n      return telefono;\n    }\n\n    public void setNombre(String nombre) {\n      this.nombre = nombre;\n    }\n\n    public void setTelefono(long telefono) {\n      this.telefono = telefono;\n    }\n\n  }\n\n\n  private static Scanner keyboard = new Scanner(System.in);\n  private static ArrayList<Contacto> agenda;\n\n  private static final int BUSCAR = 1;\n  private static final int INSERTAR = 2;\n  private static final int ACTUALIZAR = 3;\n  private static final int ELIMNAR = 4;\n  private static final int SALIR = 5;\n\n  public static void main(String[] args) {\n    agenda =  new ArrayList<Contacto>();\n    while (true) {\n      int num = menu();\n      switch (num) {\n        case BUSCAR:\n          System.out.println(\"Buscar\");\n          mostrar(search());\n          break;\n        case INSERTAR:\n          System.out.println(\"Insertar\");\n          insert();\n          break;\n        case ACTUALIZAR:\n          System.out.println(\"Actualizar\");\n          update();\n          break;\n        case ELIMNAR:\n          System.out.println(\"Eliminar\");\n          delete();\n          break;\n        case SALIR:\n          System.out.println(\"BYE!\");\n          keyboard.close();\n          System.exit(0);\n          break;\n      }\n    }\n  }\n\n  private static void mostrar(Contacto search) {\n    if (search != null) System.out.println(\"Nombre: \"+search.getNombre() +\" Telefono: \"+search.getTelefono());\n    else System.out.println(\"Contacto no encontrado en la agenda!\");\n  }\n\n  private static int menu() {\n    int opcion=0;\n    do {\n      System.out.println(\"*************************\");\n      System.out.println(\"1 - Buscar\");\n      System.out.println(\"2 - Insertar\");\n      System.out.println(\"3 - Actualizar\");\n      System.out.println(\"4 - Eliminar\");\n      System.out.println(\"5 - Salir\");\n      System.out.println(\"*************************\");\n      System.out.println(\"Opcion:\");\n      try {\n        opcion = keyboard.nextInt();\n      } catch (Exception e) {\n        System.out.println(\"Inserta un Numero !\");\n      }\n    } while (opcion>5 || 1>opcion);\n    return opcion;\n  }\n\n  private static void delete() {\n    Contacto delete = search();\n    if (delete != null) {\n      agenda.remove(delete);\n      System.out.println(\"Contacto Borrado !\");\n    }\n    else System.out.println(\"El contacto no esta en la agenda\");\n  }\n\n  private static void update() {\n    Contacto contactoViejo = search();\n    if (contactoViejo != null) {\n      if (insert()) {\n        agenda.remove(contactoViejo);\n        System.out.println(\"Contacto Modificado !\");\n      }\n    }\n    else System.out.println(\"El contacto no esta en la agenda\");\n  }\n\n  private static Contacto search () {\n    keyboard = new Scanner(System.in);\n    System.out.println(\"Nombre:\");\n    String nombre = keyboard.nextLine();\n    for (Contacto contacto : agenda) {\n      if (contacto.getNombre().equals(nombre)) return contacto;\n    }\n    return null;\n  }\n\n  private static boolean insert () {\n    try {\n      keyboard = new Scanner(System.in);\n      System.out.println(\"Nombre:\");\n      String nombre = keyboard.nextLine();\n      int size = 0;\n      long telefono = 0;\n      do {\n        keyboard = new Scanner(System.in);\n        System.out.println(\"Teléfono (11 Dígitos y sin Letras)):\");\n        try {\n          telefono = keyboard.nextLong();\n        } catch (Exception e ) {\n          System.out.println(\"Inserta un Teléfono valido !\");\n        }\n        size = String.valueOf(telefono).length();\n      } while (size!=11);\n      agenda.add(new Contacto(nombre,telefono));\n      return true;\n    } catch (Exception e) {\n      return false;\n    }\n  }\n\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/asjordi.java",
    "content": "import java.util.*;\n\npublic class Main {\n\n    public static void main(String[] args) {\n\n//        Arrays\n        int[] numeros = new int[3];\n        numeros[0] = 10; // Insertar\n        numeros[1] = 2; // Actualizar\n        Arrays.sort(numeros); // Ordenar forma ascendente\n\n//        ArrayList\n        List<String> list = new ArrayList<>();\n        list.add(\"Java\"); // Insertar\n        list.add(\"Python\"); // Insertar\n        list.set(1, \"C#\"); // Actualizar\n        list.remove(1); // Borrar\n        list.get(0); // Obtener elemento\n        Collections.sort(list); // Ordenar forma ascendente\n        list.sort(Collections.reverseOrder()); // Ordenar forma descendente\n\n//        LinkedList\n        List<Integer> linkedList = new LinkedList<>();\n        linkedList.add(1); // Insertar\n        linkedList.add(2); // Insertar\n        linkedList.set(1, 3); // Actualizar\n        linkedList.remove(1); // Borrar\n        linkedList.get(0); // Obtener elemento\n        Collections.sort(linkedList); // Ordenar forma ascendente\n        linkedList.sort(Collections.reverseOrder()); // Ordenar forma descendente\n\n//        Stack\n        Stack<Integer> stack = new Stack<>();\n        stack.push(1); // Insertar\n        stack.push(2); // Insertar\n        stack.pop(); // Borrar\n        stack.peek(); // Obtener elemento\n\n//        Queue\n        Queue<Integer> queue = new LinkedList<>();\n        queue.add(1); // Insertar\n        queue.offer(3); // Insertar\n        queue.remove(); // Borrar\n        queue.peek(); // Obtener elemento\n\n//        HashMap\n        Map<Integer, String> map = new HashMap<>();\n        map.put(1, \"Java\"); // Insertar\n        map.put(2, \"Python\"); // Insertar\n        map.replace(2, \"C#\"); // Actualizar\n        map.remove(2); // Borrar\n\n//        HashSet\n        Set<String> hashSet = new HashSet<>();\n        hashSet.add(\"Java\"); // Insertar\n        hashSet.add(\"Python\"); // Insertar\n        hashSet.remove(\"Python\"); // Borrar\n        hashSet.stream().sorted(); // Ordenar forma ascendente\n\n//        TreeSet\n        TreeSet<Integer> treeSet = new TreeSet<>();\n        treeSet.add(1); // Insertar\n        treeSet.add(2); // Insertar\n        treeSet.remove(2); // Borrar\n        treeSet.first(); // Obtener primer elemento\n        treeSet.last(); // Obtener ultimo elemento\n        treeSet.stream().sorted(Collections.reverseOrder()); // Ordenar forma descendente\n\n//        TreeMap\n        TreeMap<String,Integer> scores=new TreeMap<>();\n        scores.put(\"Juan\", 100); // Insertar\n        scores.put(\"Maria\", 90); // Insertar\n        scores.put(\"Pedro\", 80); // Insertar\n        scores.replace(\"Maria\", 95); // Actualizar\n        scores.remove(\"Pedro\"); // Borrar\n        scores.get(\"Juan\"); // Obtener elemento\n        scores.firstEntry(); // Obtener primer elemento\n        scores.lastEntry(); // Obtener ultimo elemento\n        scores.entrySet().stream().sorted(Map.Entry.comparingByValue()); // Ordenar forma ascendente\n        scores.entrySet().stream().sorted(Map.Entry.comparingByValue(Collections.reverseOrder())); // Ordenar forma descendente\n\n        agenda();\n\n    }\n\n    /**\n     * Crea una agenda de contactos por terminal.\n     * Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n     * Cada contacto debe tener un nombre y un número de teléfono.\n     * El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n     * los datos necesarios para llevarla a cabo.\n     * El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n     * (o el número de dígitos que quieras)\n     * También se debe proponer una operación de finalización del programa.\n     */\n    public static void agenda() {\n        Scanner sc = new Scanner(System.in);\n        ContactoRepositorio repo = new ContactoRepositorio();\n        System.out.println(\"Bienvenido a la agenda de contactos\");\n\n        Contacto contacto;\n        int opcion, id;\n\n        while (true) {\n            mostrarMenu();\n            opcion = sc.nextInt();\n            sc.nextLine();\n\n            switch (opcion) {\n                case 1:\n                    contacto = new Contacto();\n                    System.out.print(\"Introduce el nombre del contacto: \");\n                    contacto.setNombre(sc.nextLine());\n                    System.out.print(\"Introduce el teléfono del contacto: \");\n                    contacto.setTelefono(sc.nextLong());\n                    if (repo.insertar(contacto)) System.out.println(\"Contacto insertado correctamente -> \" + contacto);\n                    sc.nextLine();\n                    break;\n                case 2:\n                    System.out.print(\"Introduce el id del contacto a actualizar: \");\n                    id = sc.nextInt();\n                    sc.nextLine();\n                    System.out.print(\"Introduce el nombre actualizado: \");\n                    String n = sc.nextLine();\n                    System.out.print(\"Introduce el teléfono actualizado: \");\n                    long tel = sc.nextLong();\n                    if (repo.actualizar(id, n, tel)) System.out.println(\"Contacto actualizado correctamente -> \" + repo.buscarPorId(id));\n                    sc.nextLine();\n                    break;\n                case 3:\n                    System.out.print(\"Introduce el id del contacto a actualizar: \");\n                    id = sc.nextInt();\n                    sc.nextLine();\n                    if (repo.eliminar(id)) System.out.println(\"Contacto eliminado correctamente\");\n                    break;\n                case 4:\n                    System.out.print(\"Introduce el nombre del contacto\");\n                    String nombre = sc.nextLine();\n                    Contacto c = repo.buscar(nombre);\n                    if (c == null) System.out.println(\"No se ha encontrado el contacto\");\n                    else System.out.print(c);\n                    break;\n                case 5:\n                    System.out.println(\"--- Contactos ---\");\n                    System.out.println(\"Total contactos: \" + repo.getTotalContactos());\n                    repo.getContactos().forEach(System.out::println);\n                    break;\n                case 6:\n                    System.out.println(\"Adiós\");\n                    System.exit(0);\n                    break;\n                default:\n                    System.out.println(\"Opción no válida\");\n                    break;\n            }\n        }\n\n    }\n\n    public static void mostrarMenu() {\n        System.out.println(\"¿Qué quieres hacer?\");\n        System.out.println(\"1. Insertar contacto\");\n        System.out.println(\"2. Actualizar contacto\");\n        System.out.println(\"3. Eliminar contacto\");\n        System.out.println(\"4. Buscar contacto\");\n        System.out.println(\"5. Ver contactos\");\n        System.out.println(\"6. Salir\");\n    }\n\n}\n\nclass Contacto {\n\n    private String nombre;\n    private long telefono;\n    private final int id;\n    private static int lastId = 0;\n\n    public Contacto() {\n        this.id = ++lastId;\n    }\n\n    public Contacto(String nombre, long telefono) {\n        this();\n        this.nombre = nombre;\n        this.telefono = telefono;\n    }\n\n    public int getId() {\n        return id;\n    }\n\n    public String getNombre() {\n        return nombre;\n    }\n\n    public void setNombre(String nombre) {\n        this.nombre = nombre;\n    }\n\n    public void setTelefono(long telefono) {\n        this.telefono = telefono;\n    }\n\n    @Override\n    public String toString() {\n        return \"Contacto{\" +\n                \"nombre='\" + nombre + '\\'' +\n                \", telefono=\" + telefono +\n                \", id=\" + id +\n                '}';\n    }\n}\n\nclass ContactoRepositorio {\n\n        private List<Contacto> contactos;\n\n        public ContactoRepositorio() {\n            this.contactos = new ArrayList<>();\n        }\n\n        public boolean insertar(Contacto contacto) {\n            this.contactos.add(contacto);\n            return true;\n        }\n\n        public boolean actualizar(int id, String nombre, long telefono) {\n            Contacto c = buscarPorId(id);\n            c.setNombre(nombre);\n            c.setTelefono(telefono);\n            return true;\n        }\n\n        public boolean eliminar(int id) {\n            this.contactos.remove(buscarPorId(id));\n            return true;\n        }\n\n        public Contacto buscar(String nombre) {\n            return this.contactos.stream().filter(contacto -> contacto.getNombre().equals(nombre)).findFirst().orElse(null);\n        }\n\n        public Contacto buscarPorId(int id) {\n            return this.contactos.stream().filter(contacto -> contacto.getId() == id).findFirst().orElse(null);\n        }\n\n        public List<Contacto> getContactos() {\n            return contactos;\n        }\n\n        public int getTotalContactos() {\n            return this.contactos.size();\n        }\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/bladi23.java",
    "content": "import java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Map;\nimport java.util.Scanner;\n\npublic class bladi23 {\n    static Scanner sc = new Scanner(System.in);\n    static ArrayList<bladi23> arrayList = new ArrayList<bladi23>();\n    String nombre;\n    int numero;\n\n    public bladi23(String nombre, int numero) {\n        this.nombre = nombre;\n        this.numero = 0;\n    }\n\n    public String getNombre() {\n        return nombre;\n    }\n\n    public int getNumero() {\n        return 0;\n    }\n\n    public void setNombre(String nombre) {\n        this.nombre = nombre;\n    }\n\n    public void setNumero(int numero) {\n        this.numero = 0;\n    }\n\n    public static void main(String[] args) {\n        // Ejemplo de lista\n        int[] array = new int[5];\n        array[0] = 1; // Insercion\n        array[1] = 2; // Insercion\n        array[0] = 0; // Actualizacion\n        Arrays.sort(array); // Ordenacion\n\n        // Ejemplo de arraylist\n        ArrayList<Integer> lista = new ArrayList<>();\n        lista.add(1); // Insercion\n        lista.add(2); // Insercion\n        lista.remove(0); // Borrado\n        Collections.sort(lista); // Ordenacion\n\n        // Ejemplo de set\n        HashSet<Integer> conjunto = new HashSet<>();\n        conjunto.add(1); // Insercion\n        conjunto.remove(1); // Borrado\n        conjunto.add(2); // Para actualizar, se debe eliminar y luego agregar el nuevo\n\n        // Ejemplo de mapa\n        Map<String, String> mapa = new HashMap<>();\n        mapa.put(\"clave1\", \"valor1\"); // Inserción\n        mapa.put(\"clave2\", \"valor2\");\n        mapa.remove(\"clave1\"); // Borrado\n        mapa.put(\"clave2\", \"valor3\"); // Actualización\n\n        // Agenda\n        boolean salir = false;\n        while (!salir) {\n            System.out.println(\"1. Agregar contacto\");\n            System.out.println(\"2. Busqueda de contacto\");\n            System.out.println(\"3. Insertar contacto\");\n            System.out.println(\"4. Actualizar contacto\");\n            System.out.println(\"5. Eliminar contacto\");\n            System.out.println(\"6. Salir\");\n            String op = sc.nextLine();\n            switch (op) {\n                case \"1\":\n                    agregarContacto();\n                    break;\n                case \"2\":\n                    buscarContacto();\n                    break;\n                case \"3\":\n                    insertarContacto();\n                    break;\n                case \"4\":\n                    actualizarContacto();\n                    break;\n                case \"5\":\n                    eliminarContacto();\n                    break;\n                case \"6\":\n                    salir = true;\n                    break;\n            }\n        }\n\n    }\n\n    static void agregarContacto() {\n        System.out.println(\"Ingrese el nombre del contacto\");\n        String nombre = sc.nextLine();\n        System.out.println(\"Ingrese el numero del contacto\");\n        int numero = sc.nextInt();\n        bladi23 contacto = new bladi23(nombre, numero);\n        arrayList.add(contacto);\n    }\n\n    static void buscarContacto() {\n        System.out.println(\"Ingrese el nombre del contacto\");\n        String nombre = sc.nextLine();\n        for (int i = 0; i < arrayList.size(); i++) {\n            if (arrayList.get(i).getNombre().equals(nombre)) {\n                System.out.println(\"El numero de \" + nombre + \" es \" + arrayList.get(i).getNumero());\n            }\n        }\n    }\n\n    static void insertarContacto() {\n        System.out.println(\"Ingrese el nombre del contacto\");\n        String nombre = sc.nextLine();\n        System.out.println(\"Ingrese el numero del contacto\");\n        int numero = sc.nextInt();\n        bladi23 contacto = new bladi23(nombre, numero);\n        arrayList.add(contacto);\n    }\n\n    static void actualizarContacto() {\n        System.out.println(\"Ingrese el nombre del contacto\");\n        String nombre = sc.nextLine();\n        System.out.println(\"Ingrese el numero del contacto\");\n        int numero = sc.nextInt();\n        bladi23 contacto = new bladi23(nombre, numero);\n        arrayList.add(contacto);\n    }\n\n    static void eliminarContacto() {\n        System.out.println(\"Ingrese el nombre del contacto\");\n        String nombre = sc.nextLine();\n        for (int i = 0; i < arrayList.size(); i++) {\n            if (arrayList.get(i).getNombre().equals(nombre)) {\n                arrayList.remove(i);\n            }\n        }\n    }\n\n}"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/cesar-ch.java",
    "content": "import java.util.*;\n\npublic class Main {\n    public static void main(String[] args) {\n\n        // Listas\n        List<String> lista = new ArrayList<>();\n\n        // Insertamos elementos en la lista\n        lista.add(\"Hola\");\n        lista.add(\"Mundo\");\n        lista.add(\"Java\");\n\n        // Eliminamos elementos de la lista\n        lista.remove(\"Hola\");\n\n        // Actualizamos elementos de la lista\n        lista.set(0, \"Adiós\");\n\n        // Ordenamos la lista\n        lista.sort(Comparator.naturalOrder());\n\n        // Imprimimos la lista\n        System.out.println(lista);\n\n        // Sets\n        Set<String> conjunto = new HashSet<>();\n\n        // Insertamos elementos en el conjunto\n        conjunto.add(\"Hola\");\n        conjunto.add(\"Mundo\");\n        conjunto.add(\"Java\");\n\n        // Eliminamos elementos del conjunto\n        conjunto.remove(\"Hola\");\n\n        // Imprimimos el conjunto\n        System.out.println(conjunto);\n\n        // Maps\n        Map<String, Integer> mapa = new HashMap<>();\n\n        // Insertamos elementos en el mapa\n        mapa.put(\"Hola\", 1);\n        mapa.put(\"Mundo\", 2);\n        mapa.put(\"Java\", 3);\n\n        // Eliminamos elementos del mapa\n        mapa.remove(\"Hola\");\n\n        crearAgenda();\n\n    }\n\n    public static void crearAgenda() {\n        ArrayList<String> nombres = new ArrayList<>();\n        ArrayList<String> telefonos = new ArrayList<>();\n        boolean run = true;\n        Scanner scanner = new Scanner(System.in);\n\n        while (run) {\n            System.out.println(\"Ingrese la operación a realizar:\");\n            System.out.println(\"1. Buscar contacto\");\n            System.out.println(\"2. Insertar contacto\");\n            System.out.println(\"3. Actualizar contacto\");\n            System.out.println(\"4. Eliminar contacto\");\n            System.out.println(\"5. Salir\");\n\n            String operacion = scanner.nextLine();\n\n            if (\"1\".equals(operacion)) {\n                if (nombres.isEmpty()) {\n                    System.out.println(\"Agenda vacía\");\n                    continue;\n                }\n                System.out.println(\"Ingrese el nombre del contacto a buscar:\");\n                String nombreBuscar = scanner.nextLine();\n                boolean contactoEncontrado = false;\n\n                for (int i = 0; i < nombres.size(); i++) {\n                    if (nombres.get(i).equals(nombreBuscar)) {\n                        System.out.println(\"Contacto encontrado: \" + \"Nombre: \" + nombres.get(i) + \", Teléfono: \"\n                                + telefonos.get(i));\n                        contactoEncontrado = true;\n                        break;\n                    }\n                }\n\n                if (!contactoEncontrado) {\n                    System.out.println(\"Contacto no encontrado\");\n                }\n            } else if (\"2\".equals(operacion)) {\n                System.out.println(\"Ingrese el nombre del contacto a insertar:\");\n                String nombreInsertar = scanner.nextLine();\n                System.out.println(\"Ingrese el teléfono del contacto a insertar:\");\n                String telefonoInsertar = scanner.nextLine();\n\n                if (!telefonoInsertar.matches(\"^\\\\d{6,11}$\")) {\n                    System.out.println(\"El número de teléfono no es válido.\");\n                    run = false;\n                    break;\n                }\n\n                nombres.add(nombreInsertar);\n                telefonos.add(telefonoInsertar);\n                System.out.println(\n                        \"Contacto insertado: \" + \"Nombre: \" + nombreInsertar + \", Teléfono: \" + telefonoInsertar);\n            } else if (\"3\".equals(operacion)) {\n                System.out.println(\"Ingrese el nombre del contacto a actualizar:\");\n                String nombreActualizar = scanner.nextLine();\n                boolean contactoActualizado = false;\n\n                for (int i = 0; i < nombres.size(); i++) {\n                    if (nombres.get(i).equals(nombreActualizar)) {\n                        System.out.println(\"Ingrese el nuevo teléfono del contacto:\");\n                        String nuevoTelefono = scanner.nextLine();\n                        telefonos.set(i, nuevoTelefono);\n                        System.out.println(\"Contacto actualizado: \" + \"Nombre: \" + nombres.get(i) + \", Teléfono: \"\n                                + telefonos.get(i));\n                        contactoActualizado = true;\n                        break;\n                    }\n                }\n\n                if (!contactoActualizado) {\n                    System.out.println(\"Contacto no encontrado\");\n                }\n            } else if (\"4\".equals(operacion)) {\n                System.out.println(\"Ingrese el nombre del contacto a eliminar:\");\n                String nombreEliminar = scanner.nextLine();\n                boolean contactoEliminado = false;\n\n                for (int i = 0; i < nombres.size(); i++) {\n                    if (nombres.get(i).equals(nombreEliminar)) {\n                        nombres.remove(i);\n                        telefonos.remove(i);\n                        System.out.println(\"Contacto eliminado: \" + \"Nombre: \" + nombreEliminar);\n                        contactoEliminado = true;\n                        break;\n                    }\n                }\n\n                if (!contactoEliminado) {\n                    System.out.println(\"Contacto no encontrado\");\n                }\n            } else if (\"5\".equals(operacion)) {\n                run = false;\n                System.out.println(\"Agenda creada: \" + nombres);\n            } else {\n                System.out.println(\"Operación no válida\");\n            }\n        }\n\n        scanner.close();\n        System.out.println(\"Agenda creada: \" + nombres);\n    }\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/chartypes.java",
    "content": "import java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.InputMismatchException;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Scanner;\nimport java.util.Set;\n\npublic class chartypes {\n    public static void main(String[] args) {\n        dataStructures();\n        exercise();\n\n    }\n\n    static void dataStructures() {\n        // Arrays\n        System.out.println(\"-------------\\nArray:\");\n        int[] arrayNumbers = new int[3];\n        arrayNumbers[0] = 1;\n        arrayNumbers[1] = 2;\n        arrayNumbers[2] = 3;\n        System.out.println(Arrays.toString(arrayNumbers));\n\n        // ArrayList\n        System.out.println(\"-------------\\nArrayList:\");\n        ArrayList<Integer> listNumbers = new ArrayList<>();\n        listNumbers.add(4);\n        listNumbers.add(5);\n        listNumbers.add(1);\n        System.out.println(listNumbers.get(0));\n        listNumbers.set(1, 20);\n        listNumbers.remove(2);\n        listNumbers.forEach(System.out::println);\n\n        // Sets\n        System.out.println(\"-------------\\nSets:\");\n        Set<Integer> setNumbers = new HashSet<>();\n        setNumbers.add(5);\n        setNumbers.add(12);\n        setNumbers.add(8);\n        setNumbers.add(12);\n        setNumbers.forEach(System.out::println);\n\n        // LinkedList\n        System.out.println(\"-------------\\nLinkedList:\");\n        List<String> listColors = new LinkedList<>();\n        listColors.add(\"Red\");\n        listColors.add(\"Blue\");\n        listColors.add(\"Yellow\");\n        listColors.forEach(System.out::println);\n\n        // HashMap\n        System.out.println(\"-------------\\nHasMap:\");\n        Map<Integer, String> mapNumbers = new HashMap<>();\n        mapNumbers.put(1, \"one\");\n        mapNumbers.put(2, \"two\");\n        mapNumbers.put(3, \"three\");\n        System.out.println(mapNumbers);\n        mapNumbers.put(2, \"five\");\n        System.out.println(\"Keys:\" + mapNumbers.keySet() + \"---- Values:\" + mapNumbers.values());\n    }\n\n    boolean checkPhoneNumber(String phoneNumber) {\n        return phoneNumber.length() >= 11;\n    }\n\n    static void exercise() {\n        final String WRONG_VALUE = \"You inserted a wrong value\";\n\n        Map<String, Long> contact = new HashMap<>();\n        while (true) {\n\n            System.out.println(\"\\n-----------------------------------------------------\");\n            System.out.println(\"Select an option :\\n\");\n            System.out.println(\"1. Insert a new contact\");\n            System.out.println(\"2. Show contact\");\n            System.out.println(\"3. Update a contact\");\n            System.out.println(\"4. Delete a contact\");\n            System.out.println(\"5. Exit\");\n\n            Scanner choice = new Scanner(System.in);\n            switch (choice.nextInt()) {\n                case 1:\n                    System.out.println(\"Insert a name for the contact: \");\n                    System.out.println(\"Insert a phone number for the contact: \");\n                    Scanner data = new Scanner(System.in);\n                    try {\n                        String name = data.nextLine();\n                        long phoneNumber = data.nextLong();\n                        if (phoneNumber >= 10000000000L) {\n                            System.out.println(WRONG_VALUE);\n                            break;\n                        }\n                        contact.put(name, phoneNumber);\n                        break;\n                    } catch (InputMismatchException e) {\n                        System.out.println(WRONG_VALUE);\n                        break;\n\n                    }\n                case 2:\n                    System.out.println(\"Whats the name of the contact you want to see? : \");\n                    Scanner nameToShow = new Scanner(System.in);\n                    Long contactValue = contact.get(nameToShow.nextLine());\n                    if (contactValue instanceof Long) {\n                        System.out.println(contactValue);\n                    } else\n                        System.out.println(WRONG_VALUE);\n\n                    break;\n                case 3:\n                    System.out.println(\"Whats the name of the contact you want to update? : \");\n                    System.out.println(\"Insert the new phone number to update? : \");\n                    try {\n                        Scanner dataToUpdate = new Scanner(System.in);\n                        String nameToUpdate = dataToUpdate.nextLine();\n                        long phoneNumberToUpdate = dataToUpdate.nextLong();\n                        contact.put(nameToUpdate, phoneNumberToUpdate);\n                        System.out.println(\"Contact updated correctly\");\n\n                    } catch (InputMismatchException e) {\n                        System.out.println(\"You inserted a wrong value\");\n                    }\n                    break;\n                case 4:\n                    System.out.println(\"Whats the name of the contact you want to delete? : \");\n                    Scanner nameToDelete = new Scanner(System.in);\n                    contact.remove(nameToDelete.nextLine());\n                    System.out.println(\"Contact deleted correctly\");\n                    break;\n                case 5:\n                    return;\n                default:\n                    System.out.println(\"You inserted a wrong option \");\n                    break;\n            }\n\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/danhingar.java",
    "content": "import java.util.*;\nimport java.util.Map.Entry;\n\npublic class danhingar {\n\n    // Lista vacía\n    public static List<String> nameList = new ArrayList<>();\n    // Lista con valores iniciales\n    public static List<String> friendList = new ArrayList<>(Arrays.asList(\"MATEO\", \"CRISTINA\", \"ALBA\"));\n    // Array vacía\n    public static String[] movies = new String[2];\n    // Array con valores iniciales\n    public static int[] numbers = { 1, 2, 3, 4 };\n    // Set vacío\n    public static Set<Long> numbers3 = new LinkedHashSet<>();\n    // Set con valores iniciales\n    public static Set<Long> numbers4 = Set.of(1L, 2L, 3L, 4L);\n    // Map vacío\n    public static Map<String, Integer> animalsMap = new HashMap<>();\n    // Map con valores iniciales\n    public static Map<String, Integer> carsMap = Map.of(\"Ferrari\", 2, \"Lamborghini\", 5, \"MCLAREN\", 10);\n\n    public static void main(String[] args) {\n        System.out.println(nameList);\n        System.out.println(friendList);\n        System.out.println(movies);\n        System.out.println(numbers);\n        System.out.println(numbers3);\n        System.out.println(numbers4);\n        System.out.println(animalsMap);\n        System.out.println(carsMap);\n\n        //Agregar elementos\n        addElement();\n        System.out.println(nameList);\n        System.out.println(movies);\n        System.out.println(numbers3);\n        System.out.println(animalsMap);\n\n        //Actualizar elementos\n        updateElement();\n        System.out.println(friendList);\n        System.out.println(numbers);\n        System.out.println(animalsMap);\n\n        //Eliminar elementos\n        removeElement();\n        System.out.println(friendList);\n        System.out.println(numbers3);\n        System.out.println(animalsMap);\n\n        //Ordenar elementos\n        sortElement();\n        System.out.println(friendList);\n        System.out.println(numbers);\n\n        // EJERCICIO EXTRA\n        agenda();\n    }\n\n    private static void addElement() {\n        nameList.add(\"MATILDA\");\n        movies[0] = \"CARS\";\n        numbers3.add(100L);\n        animalsMap.put(\"LION\", 5);\n    }\n\n    private static void updateElement() {\n        friendList.set(0, \"LORENZO\");\n        numbers[0] = 0;\n        animalsMap.replace(\"LION\", 100);\n    }\n\n    private static void removeElement() {\n        friendList.remove(0);\n        numbers3.remove(100L);\n        animalsMap.remove(\"LION\");\n    }\n\n    private static void sortElement() {\n        Collections.sort(friendList);\n        Arrays.sort(numbers);\n    }\n\n    public static Map<String, String> agenda = new HashMap<>();\n\n    public static Boolean on = Boolean.TRUE;\n\n    private static void agenda() {\n\n        while (on) {\n            System.out.println(\"1. Buscar contacto\");\n            System.out.println(\"2. Insertar contacto\");\n            System.out.println(\"3. Actualizar contacto\");\n            System.out.println(\"4. Eliminar contacto\");\n            System.out.println(\"5. Mostrar agenda\");\n            System.out.println(\"6. Salir\");\n            System.out.println(\"-----------------------------\");\n\n            System.out.println(\"Seleccione una opción\");\n\n            Scanner scanner = new Scanner(System.in);\n            String option = scanner.nextLine();\n            if (!option.isBlank()) {\n\n                switch (Integer.parseInt(option)) {\n                    case 1:\n                        searchContact(scanner);\n                        break;\n                    case 2:\n                        addContact(scanner);\n                        break;\n                    case 3:\n                        updateContact(scanner);\n                        break;\n                    case 4:\n                        removeContact(scanner);\n                        break;\n                    case 5:\n                        showContacts();\n                        break;\n                    case 6:\n                        scanner.close();\n                        System.exit(0);\n                        on = Boolean.FALSE;\n                        break;\n                    default:\n                        System.out.println(\"---------------Opción no valida---------------\");\n\n                }\n            }\n        }\n\n    }\n\n    private static void showContacts() {\n        System.out.println(\"Mostrando agenda completa\");\n        for (Entry<String, String> person : agenda.entrySet()) {\n            System.out.println(person.getKey().toUpperCase()+\" : \"+person.getValue());\n        }\n        System.out.println(\"---------Acción completada-------------\\n\");\n    }\n\n    private static void removeContact(Scanner scanner) {\n        System.out.println(\"Introduzca el nombre de contacto que quiere eliminar\");\n        String name = scanner.nextLine();\n        if (!name.isBlank() && !agenda.keySet().contains(name.toUpperCase())) {\n            System.out.println(\"No existe el contacto que quiere eliminar\");\n        } else {\n            agenda.remove(name.toUpperCase());\n            System.out.println(\"Eliminado el contacto \" + name.toUpperCase());\n        }\n        System.out.println(\"---------Acción completada-------------\\n\");\n    }\n\n    private static void addContact(Scanner scanner) {\n        System.out.println(\"Introduzca el nombre de contacto\");\n        String name = scanner.nextLine();\n        System.out.println(\"Introduzca el número de teléfono\");\n        String number = scanner.nextLine();\n        if (!name.isBlank() && agenda.containsKey(name.toUpperCase())) {\n            System.out.println(\"Ya existe el contacto \" + name+\" en la agenda\");\n        } else if(!number.matches(\"^\\\\d{0,11}$\")) {\n            System.out.println(\"Número de teléfono no válido \" + number);\n        }else{\n            agenda.put(name.toUpperCase(), number);\n            System.out.println(String.format(\"Añadido el contacto %s , %s\", name.toUpperCase(), number));\n        }\n        System.out.println(\"---------Acción completada-------------\\n\");\n    }\n\n    private static void searchContact(Scanner scanner) {\n        System.out.println(\"Introduzca un nombre\");\n        String name = scanner.nextLine();\n        if (agenda.get(name.toUpperCase()) != null) {\n            System.out.println(String.format(\"El teléfono de %s es %s\", name.toUpperCase(), agenda.get(name.toUpperCase())));\n        } else {\n            System.out.println(\"No existe el contacto \" + name.toUpperCase());\n        }\n        System.out.println(\"---------Acción completada-------------\\n\");\n    }\n\n    private static void updateContact(Scanner scanner) {\n        System.out.println(\"Introduzca el nombre de contacto que quiere actualizar\");\n        String name = scanner.nextLine();\n        System.out.println(\"Introduzca el nuevo número de teléfono\");\n        String number = scanner.nextLine();\n        if (!name.isBlank() && !agenda.keySet().contains(name.toUpperCase())) {\n            System.out.println(\"No existe el contacto que quiere actualizar\");\n        } else if (!number.matches(\"^\\\\d{0,11}$\")) {\n            System.out.println(\"Número de teléfono no válido \" + number);\n        } else {\n            agenda.replace(name.toUpperCase(), number);\n            System.out.println(String.format(\"Actualizado el contacto %s , %s\", name.toUpperCase(), number));\n        }\n        System.out.println(\"---------Acción completada-------------\\n\");\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/deathwing696.java",
    "content": "\nimport java.util.HashMap;\nimport java.util.Scanner;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\n/*\n * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license\n * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template\n */\n\n/*\n * EJERCICIO:\n * - Muestra ejemplos de creacin de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de insercin, borrado, actualizacin y ordenacin.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de bsqueda, insercin, actualizacin y eliminacin de contactos.\n * - Cada contacto debe tener un nombre y un nmero de telfono.\n * - El programa solicita en primer lugar cul es la operacin que se quiere realizar, y a continuacin\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir nmeros de telfono no nmericos y con ms de 11 dgitos.\n *   (o el nmero de dgitos que quieras)\n * - Tambin se debe proponer una operacin de finalizacin del programa.\n */\n\n/**\n *\n * @author death\n */\npublic class deathwing696 {\n    public static void main(String[] args)\n    {\n        int opcion;\n        var listin = new HashMap<String, Long>();\n        \n        do\n        {\n            opcion = Menu();\n            \n            switch (opcion) \n            {\n                case 0 ->\n                {\n                    //Salir\n                }\n                case 1 -> Insertar_nuevo_contacto(listin);\n                case 2 -> \n                {\n                    Object[] contacto;\n                    \n                    contacto = Buscar_contacto(listin, null);\n                    \n                    if (contacto != null)\n                        System.out.println(\"Nombre: \" + contacto[0] + \" Telfono: \" + contacto[1]);\n                    else\n                        System.out.println(\"El contacto buscado no se encuentra en el listn\");\n                }\n                case 3 -> \n                {\n                    if (Actualizar_contacto(listin))\n                        System.out.println(\"Contacto actualizado correctamente\");\n                }\n                case 4 -> \n                {\n                    if (Eliminar_contacto(listin))\n                        System.out.println(\"Contacto eliminado correctamente\");\n                    else\n                        System.out.println(\"El contacto buscado no se encuentra en el listn\");\n                }\n                    \n                case 5 -> Mostrar_listin(listin);\n                default -> throw new AssertionError();\n            }\n        }while(opcion != 0);\n    } \n    \n    static private int Menu()\n    {\n        int opcion;\n        Scanner lectura = new Scanner(System.in);\n        \n        do\n        {\n        \n        System.out.println(\"**************************************\");\n        System.out.println(\"** 1. Insertar nuevo contacto       **\");\n        System.out.println(\"** 2. Buscar contacto               **\");\n        System.out.println(\"** 3. Actualizar contacto           **\");\n        System.out.println(\"** 4. Eliminar contacto             **\");\n        System.out.println(\"** 5. Mostrar listn                **\");\n        System.out.println(\"** 0. Salir                         **\");\n        System.out.println(\"**************************************\");\n        \n        System.out.print(\"Introduce una opcin:\");\n        \n        try\n        {\n            opcion = lectura.nextInt();\n        }\n        catch(Exception e)\n        {\n            System.out.println(\"Opcin incorrecta, por favor introduzca una opcin del 0 al 5\"); \n            lectura.nextLine();\n            opcion = 9;\n        }\n        \n        }while(opcion < 0 || opcion > 5);\n        \n        return opcion;\n    }\n    \n    static private Long Comprobar_telefono_valido()\n    {\n        String cadena;\n        Scanner lectura = new Scanner(System.in);\n        Pattern pattern = Pattern.compile(\"[0-9]{11}\");\n        Matcher matcher;\n        boolean ok;\n        \n        do\n        {            \n            System.out.print(\"Introduce el nmero de telfono:\");                        \n            cadena = lectura.nextLine();                        \n            matcher = pattern.matcher(String.valueOf(cadena));\n            ok = matcher.find();\n            if (!ok)            \n                System.out.println(\"Formato del telfono incorrecto, introduzca una secuencia de nmeros de 11 dgitos\");\n            \n        }while(!ok);\n        \n        return Long.valueOf(cadena);\n    }\n    \n    static private void Insertar_nuevo_contacto(HashMap<String,Long> listin)\n    {\n        String nombre;\n        long telefono;\n        Scanner lectura = new Scanner(System.in);\n        \n        \n        System.out.print(\"Introduce el nombre del contacto:\");\n        nombre = lectura.nextLine();\n        telefono = Comprobar_telefono_valido();\n        \n        listin.put(nombre, Long.valueOf(String.valueOf(telefono)));\n    }\n    \n    static private Object[] Buscar_contacto(HashMap<String, Long> listin, String key)\n    {\n        Long value;\n        Scanner lectura = new Scanner(System.in);\n        \n        if (key == null)\n        {\n            System.out.print(\"Cul es el nombre del usuario que desea buscar?\");\n            key = lectura.nextLine();            \n        }\n        \n        value = listin.get(key);\n        \n        if (value != null)\n            return new Object[]{key, value};\n        else\n            return null;\n    }\n    \n    static private Boolean Actualizar_contacto(HashMap<String, Long> listin)\n    {\n        Boolean ok;\n        String key;\n        Long value;\n        Scanner lectura = new Scanner(System.in);\n        \n        System.out.print(\"Introduce el nombre del contacto que deseas modificar:\");\n        key = lectura.nextLine();\n        value = listin.get(key);\n        \n        if (value != null)\n        {\n            int opcion;\n            \n            do\n            {\n                System.out.print(\"Qu deseas modificar? (0 para nombre, 1 para telfono)\");                \n                try\n                {\n                    opcion = lectura.nextInt();\n                    lectura.nextLine();\n                }\n                catch(Exception e)\n                {\n                    System.out.println(\"Opcin invlida, por favor introduzca una opcin entre 0 y 1\");\n                    lectura.nextLine();\n                    opcion = 9;\n                }\n            }while (opcion != 0 && opcion != 1);\n            \n            if (opcion == 0)\n            {\n                String nombre;\n                \n                System.out.print(\"Introduce el nuevo nombre:\");\n                nombre = lectura.nextLine();\n                listin.remove(key);\n                listin.put(nombre, value);\n            }\n            else\n            {\n                Long telefono;\n                                \n                telefono = Comprobar_telefono_valido();\n                listin.put(key, telefono);\n            }\n            \n            ok = true;\n        }\n        else\n        {\n            System.out.println(\"El contacto buscado no se encuentra en el listn\");\n            ok = false;\n        }\n        \n        return ok;\n    }\n    \n    static private Boolean Eliminar_contacto(HashMap<String, Long> listin)\n    {\n        Boolean ok = false;\n        String key;\n        Long value;\n        Scanner lectura = new Scanner(System.in);\n\n        System.out.print(\"Introduce el nombre del contacto que deseas modificar:\");\n        key = lectura.nextLine();\n        value = listin.get(key);\n        \n        if (value != null)\n        {\n            listin.remove(key);\n            ok = true;\n        }\n        \n        return ok;\n    }\n    \n    static private void Mostrar_listin(HashMap<String,Long> listin)\n    {\n        if (!listin.isEmpty())\n            listin.forEach((k,v) -> System.out.println(\"Nombre: \" + k + \" Telfono: \" + v));\n        else\n            System.out.println(\"No hay contactos actualmente en el listn, por favor, introduzca alguno con la opcin 1 del men\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/dmauricio4.java",
    "content": "package com.dm4.roadmap;\n\nimport java.util.*;\n\n/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n *   y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n *   y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más\n *   de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.\n */\n\npublic class Roadmap03_EstructuraDatos {\n\n    public static Scanner teclado = new Scanner(System.in);\n    public static ArrayList<Contacto> listAgenda;\n\n\n    public static void main(String[] args) {\n\n        System.out.println(\" *** HashMap *** \");\n        //Creamos un HashMap para almacebar notas\n        Map<String, Double>notasAlumnos = new HashMap<>();\n        //Agregamos datos al HashMap\n        notasAlumnos.put(\"Daniela\", 8.5);\n        notasAlumnos.put(\"Diego\", 8.0);\n        notasAlumnos.put(\"Franchezca\", 10.0);\n        //Acceder a las notas\n        double notaDaniela = notasAlumnos.get(\"Daniela\");\n        double notaDiego = notasAlumnos.get(\"Diego\");\n        double notaFranchezca = notasAlumnos.get(\"Franchezca\");\n        System.out.println(\"Nota de Daniela es: \" + notaDaniela);\n        System.out.println(\"Nota de Diego es: \" + notaDiego);\n        System.out.println(\"Nota de Franchezca es: \" + notaFranchezca);\n        //Modificar la nota de un alumno\n        notasAlumnos.put(\"Daniela\", 9.0);\n        //Imprimir las notas de los alumnos\n        System.out.println(\"Nota de los alumnos\");\n        for (Map.Entry<String,Double> entry: notasAlumnos.entrySet()) {\n            String nombre = entry.getKey();\n            double nota = entry.getValue();\n            System.out.println(nombre + \" : \" + nota);\n        }\n\n        System.out.println(\" *** Array *** \");\n        //Creamos un arreglo inicial\n        int [] arregloOriginal = {1,2,3,4,5};\n        //Nuevo tamaño deseado para el arreglo\n        int nuevoTamanio = 8;\n        //Creamos un nuevo arreglo con el nuevo tamanio\n        int [] nuevoArreglo = new int[nuevoTamanio];\n        //Copiar los elementos de arreglo original al nuevo arreglo\n        for (int i = 0; i < arregloOriginal.length; i++) {\n            nuevoArreglo[i] = arregloOriginal[i];\n        }\n        //Tenemos un nuevo arreglo con un tamaño mayor\n        arregloOriginal = nuevoArreglo;\n        //Imprimimos el nuevo arreglo\n        for (int elemento:arregloOriginal) {\n            System.out.println(elemento + \" \");\n        }\n\n        System.out.println();\n        System.out.println(\" *** ArrayList *** \");\n        ArrayList<String> ciudades = new ArrayList<>();\n        //Agregamos las ciudades\n        ciudades.add(\"Cuenca\");\n        ciudades.add(\"Guayaquil\");\n        ciudades.add(\"Quito\");\n        //Recorrer un ArrayList\n        for (int i = 0; i < ciudades.size(); i++) {\n            System.out.println(i + \" : \"  + ciudades.get(i));\n        }\n        //Eliminar una ciudad\n        ciudades.remove(\"Cuenca\");\n\n\n        /**\n         * Dificultad Extra\n         */\n\n        listAgenda = new ArrayList<Contacto>();\n\n        int opcion = 0;\n\n        //Bucle para pedir las opciones hasta que elijamos salir\n        while (opcion != 6) {\n            System.out.println();\n            System.out.println(\"------------------------\");\n            System.out.println(\" **** AGENDA **** \");\n            System.out.println(\"------------------------\");\n            System.out.println();\n\n            //opciones\n            System.out.println(\"1. Crear Contacto\");\n            System.out.println(\"2. Listar Contactos\");\n            System.out.println(\"3. Buscar Contacto\");\n            System.out.println(\"4. Actualizar Contacto\");\n            System.out.println(\"5. Borrar Contacto\");\n            System.out.println(\"6. Salir\");\n\n            try {\n                System.out.println();\n                System.out.print(\"Seleccione una opcion: \");\n                opcion = teclado.nextInt();\n                switch (opcion) {\n                    case 1:\n                        add();\n                        break;\n                    case 2:\n                        getLista();\n                        break;\n                    case 3:\n                        mostrar(search());\n                        break;\n                    case 4:\n                        update();\n                        break;\n                    case 5:\n                        delete();\n                        break;\n                    case 6:\n                        System.out.println(\"Fin del programa\");\n                        teclado.close();\n                        System.exit(0);\n                        break;\n                    default:\n                        System.out.println(\"Las opciones son entre 1 y 6\");\n                }\n\n                //controla la excepcionn en caso de que se introduzca un valor no correcto\n            } catch (InputMismatchException e) {\n                System.out.println(\"Debes escribir un numero\");\n                teclado.next();\n            }\n        }\n    }\n\n\n    /**\n     * Clase Contacto\n     */\n    public static class Contacto {\n\n        public String nombre;\n        public String correo;\n        public Long telefono;\n\n        public Contacto(String nombre, String correo, Long telefono) {\n            this.nombre = nombre;\n            this.correo = correo;\n            this.telefono = telefono;\n        }\n\n        public Contacto() {\n        }\n\n        public String getNombre() {\n            return nombre;\n        }\n\n        public void setNombre(String nombre) {\n            this.nombre = nombre;\n        }\n\n        public String getCorreo() {\n            return correo;\n        }\n\n        public void setCorreo(String correo) {\n            this.correo = correo;\n        }\n\n        public Long getTelefono() {\n            return telefono;\n        }\n\n        public void setTelefono(Long telefono) {\n            this.telefono = telefono;\n        }\n\n    }\n\n    /**\n     * Metodo para agregar un contacto\n     */\n    private static boolean add() {\n        try {\n            teclado = new Scanner(System.in);\n            System.out.println(\"-----------------------------------\");\n            System.out.println(\"---Crear Contacto---\");\n            System.out.println(\"Ingrese los datos\");\n            System.out.println();\n            System.out.println(\"* Ingrese el Nombre:\");\n            String nombre = teclado.nextLine();\n            System.out.println(\"* Ingrese el correo: \");\n            String correo = teclado.nextLine();\n            int size = 0;\n            long telefono = 0;\n            do {\n                teclado = new Scanner(System.in);\n                System.out.println(\"* Ingrese el telefono (11 digitos)):\");\n                try {\n                    telefono = teclado.nextLong();\n                } catch (Exception e) {\n                    System.out.println(\"# telefono invalido\");\n                }\n                size = String.valueOf(telefono).length();\n            } while (size != 11);\n            listAgenda.add(new Contacto(nombre, correo, telefono));\n            System.out.println();\n            System.out.println(\"*** Datos ingresados correctamente ***\");\n            System.out.println();\n            System.out.println(\"-----------------------------------\");\n            return true;\n        } catch (Exception e) {\n            return false;\n        }\n    }\n\n    /**\n     * Metodo para listar los contactos existentes\n     *\n     * @return\n     */\n    public static boolean getLista() {\n        System.out.println(\"-----------------------------------\");\n        System.out.println(\"--- Lista de Contactos ---\");\n        System.out.println();\n        for (int i = 0; i < listAgenda.size(); i++) {\n            System.out.println(i + \" Nombre: \" + listAgenda.get(i).getNombre() + \"| Correo: \" + listAgenda.get(i).getCorreo() + \"| Telefono: \" + listAgenda.get(i).getTelefono());\n        }\n        return true;\n    }\n\n    /**\n     * Metodo para buscar un contacto por el nombre\n     *\n     * @return\n     */\n    public static Contacto search() {\n        System.out.println(\"-----------------------------------\");\n        System.out.println(\"--- Buscar Contacto ---\");\n        System.out.println(\"* Ingrese el nombre: \");\n        teclado = new Scanner(System.in);\n        String nombre = teclado.nextLine();\n        for (Contacto c : listAgenda) {\n            if (c.getNombre().equals(nombre)) {\n                return c;\n            }\n        }\n        return null;\n    }\n\n    /**\n     * Metodo para mostrar el contacto por el nombre\n     *\n     * @param search\n     */\n    public static void mostrar(Contacto search) {\n        //System.out.println(\"-----------------------------------\");\n        //System.out.println(\"Buscar Contacto\");\n        //System.out.println(\"Ingrese el nombre: \");\n        if (search != null) {\n            System.out.println();\n            System.out.println(\" --- Contacto encontrado --- \");\n            System.out.println();\n            System.out.println(\"Nombre: \" + search.getNombre() + \"| Correo: \" + search.getCorreo() + \"| Telefono: \" + search.getTelefono());\n        } else {\n            System.out.println(\"--- El contacto no existe ---\");\n        }\n    }\n\n    /**\n     * Metodo para actualizar un contacto\n     */\n    public static void update() {\n        System.out.println(\"-----------------------------------\");\n        System.out.println(\"--- Actualizar Contacto ---\");\n        Contacto ca = search();\n        if (ca != null) {\n            if (add()) {\n                listAgenda.remove(ca);\n                System.out.println(\"--- Contacto actualizado ---\");\n                System.out.println(\"Liste los contactos para ver los cambios\");\n            }\n        } else {\n            System.out.println(\" --- No existe el contacto --- \");\n        }\n    }\n\n    /**\n     * Metodo para borrar un contacto buscado por el nombre\n     */\n    public static void delete() {\n        Contacto borrar = search();\n        if (borrar != null) {\n            listAgenda.remove(borrar);\n            System.out.println(\"--- Contacto eliminado ---\");\n        } else {\n            System.out.println(\"--- El contacto no existe ---\");\n        }\n    }\n}\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/eulogioep.java",
    "content": "import java.util.*;\n\npublic class eulogioep {\n\n    public static void main(String[] args) {\n        // Ejemplos de estructuras de datos en Java\n        ejemplosEstructurasDatos();\n\n        // Agenda de contactos\n        agendaContactos();\n    }\n\n    public static void ejemplosEstructurasDatos() {\n        // ArrayList: Lista dinámica\n        List<String> arrayList = new ArrayList<>();\n        arrayList.add(\"Java\");\n        arrayList.add(\"Python\");\n        arrayList.add(\"C++\");\n        System.out.println(\"ArrayList: \" + arrayList);\n\n        // LinkedList: Lista enlazada\n        List<String> linkedList = new LinkedList<>();\n        linkedList.add(\"Rojo\");\n        linkedList.add(\"Verde\");\n        linkedList.add(\"Azul\");\n        System.out.println(\"LinkedList: \" + linkedList);\n\n        // HashSet: Conjunto sin duplicados y sin orden\n        Set<Integer> hashSet = new HashSet<>();\n        hashSet.add(1);\n        hashSet.add(2);\n        hashSet.add(2); // No se añade por ser duplicado\n        System.out.println(\"HashSet: \" + hashSet);\n\n        // TreeSet: Conjunto ordenado\n        Set<Integer> treeSet = new TreeSet<>();\n        treeSet.add(3);\n        treeSet.add(1);\n        treeSet.add(2);\n        System.out.println(\"TreeSet: \" + treeSet); // Imprime en orden\n\n        // HashMap: Mapa clave-valor\n        Map<String, Integer> hashMap = new HashMap<>();\n        hashMap.put(\"Uno\", 1);\n        hashMap.put(\"Dos\", 2);\n        hashMap.put(\"Tres\", 3);\n        System.out.println(\"HashMap: \" + hashMap);\n\n        // Operaciones\n        arrayList.remove(\"Python\"); // Borrado\n        linkedList.set(1, \"Amarillo\"); // Actualización\n        Collections.sort(arrayList); // Ordenación\n\n        System.out.println(\"ArrayList después de operaciones: \" + arrayList);\n        System.out.println(\"LinkedList después de operaciones: \" + linkedList);\n    }\n\n    public static void agendaContactos() {\n        Scanner scanner = new Scanner(System.in);\n        Map<String, String> agenda = new HashMap<>();\n\n        while (true) {\n            System.out.println(\"\\n--- Agenda de Contactos ---\");\n            System.out.println(\"1. Buscar contacto\");\n            System.out.println(\"2. Añadir contacto\");\n            System.out.println(\"3. Actualizar contacto\");\n            System.out.println(\"4. Eliminar contacto\");\n            System.out.println(\"5. Mostrar todos los contactos\");\n            System.out.println(\"6. Salir\");\n            System.out.print(\"Seleccione una opción: \");\n\n            int opcion = scanner.nextInt();\n            scanner.nextLine(); // Consumir el salto de línea\n\n            switch (opcion) {\n                case 1:\n                    buscarContacto(agenda, scanner);\n                    break;\n                case 2:\n                    anadirContacto(agenda, scanner);\n                    break;\n                case 3:\n                    actualizarContacto(agenda, scanner);\n                    break;\n                case 4:\n                    eliminarContacto(agenda, scanner);\n                    break;\n                case 5:\n                    mostrarContactos(agenda);\n                    break;\n                case 6:\n                    System.out.println(\"¡Hasta luego!\");\n                    return;\n                default:\n                    System.out.println(\"Opción no válida.\");\n            }\n        }\n    }\n\n    private static void buscarContacto(Map<String, String> agenda, Scanner scanner) {\n        System.out.print(\"Ingrese el nombre del contacto: \");\n        String nombre = scanner.nextLine();\n        String telefono = agenda.get(nombre);\n        if (telefono != null) {\n            System.out.println(\"Teléfono de \" + nombre + \": \" + telefono);\n        } else {\n            System.out.println(\"Contacto no encontrado.\");\n        }\n    }\n\n    private static void anadirContacto(Map<String, String> agenda, Scanner scanner) {\n        System.out.print(\"Ingrese el nombre del contacto: \");\n        String nombre = scanner.nextLine();\n        String telefono = solicitarTelefono(scanner);\n        agenda.put(nombre, telefono);\n        System.out.println(\"Contacto añadido con éxito.\");\n    }\n\n    private static void actualizarContacto(Map<String, String> agenda, Scanner scanner) {\n        System.out.print(\"Ingrese el nombre del contacto a actualizar: \");\n        String nombre = scanner.nextLine();\n        if (agenda.containsKey(nombre)) {\n            String telefono = solicitarTelefono(scanner);\n            agenda.put(nombre, telefono);\n            System.out.println(\"Contacto actualizado con éxito.\");\n        } else {\n            System.out.println(\"Contacto no encontrado.\");\n        }\n    }\n\n    private static void eliminarContacto(Map<String, String> agenda, Scanner scanner) {\n        System.out.print(\"Ingrese el nombre del contacto a eliminar: \");\n        String nombre = scanner.nextLine();\n        if (agenda.remove(nombre) != null) {\n            System.out.println(\"Contacto eliminado con éxito.\");\n        } else {\n            System.out.println(\"Contacto no encontrado.\");\n        }\n    }\n\n    private static void mostrarContactos(Map<String, String> agenda) {\n        if (agenda.isEmpty()) {\n            System.out.println(\"La agenda está vacía.\");\n        } else {\n            for (Map.Entry<String, String> entry : agenda.entrySet()) {\n                System.out.println(entry.getKey() + \": \" + entry.getValue());\n            }\n        }\n    }\n\n    private static String solicitarTelefono(Scanner scanner) {\n        while (true) {\n            System.out.print(\"Ingrese el número de teléfono (máximo 11 dígitos): \");\n            String telefono = scanner.nextLine();\n            if (telefono.matches(\"\\\\d{1,11}\")) {\n                return telefono;\n            }\n            System.out.println(\"Número no válido. Debe ser numérico y tener máximo 11 dígitos.\");\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/frannmv.java",
    "content": "import java.util.Scanner;\nimport java.util.HashMap;\n\npublic class frannmv {\n\n    public enum Operaciones {\n        BUSCAR(1),\n        INSERTAR(2),\n        ACTUALIZAR(3),\n        ELIMINAR(4),\n        MOSTRAR(5),\n        EXIT(6);\n\n        private final int valor;\n\n        Operaciones(int valor) {\n            this.valor = valor;\n        }\n    }\n\n    public static Scanner keyboard = new Scanner(System.in);\n    public static HashMap<String, Long> agenda = new HashMap<>();\n    public static long numTelefono;\n    public static String nombre;\n\n    public static void main(String[] args) {\n\n        while (true) {\n\n            mostrarMenu();\n\n            switch (operacionElegida()) {\n\n                case BUSCAR:\n                    System.out.println(\"Ingrese el nombre del contacto a buscar:\");\n                    nombre = keyboard.nextLine();\n                    buscar(nombre);\n                    break;\n\n                case ELIMINAR:\n                    System.out.println(\"Ingrese el nombre del contacto a eliminar: \");\n                    nombre = keyboard.nextLine();\n                    eliminar(nombre);\n                    break;\n\n                case INSERTAR:\n                    insertar();\n                    break;\n\n                case ACTUALIZAR:\n                    actualizar();\n                    break;\n\n                case MOSTRAR:\n                    mostrar();\n                    break;\n\n                case EXIT:\n                    System.out.println(\"Hasta luego, vuelva prontos!\");\n                    System.exit(0);\n                    break;\n\n                case null:\n                    System.out.println(\"Ingrese un numero valido!\");\n\n            }\n        }\n    }\n\n    private static void mostrarMenu() {\n        for (Operaciones operacion : Operaciones.values()) {\n            System.out.println(operacion.valor + \". \" + operacion);\n        }\n    }\n\n    private static Operaciones obtenerOperacion(int valor) {\n        for (Operaciones operacion : Operaciones.values()) {\n            if (valor == operacion.valor) {\n                return operacion;\n            }\n        }\n        return null;\n    }\n\n    private static Operaciones operacionElegida() {\n\n        int valor = keyboard.nextInt();\n        keyboard.nextLine(); // Consumir el caracter \\n que deja keyboard.nextInt() en el bufer\n        return obtenerOperacion(valor);\n    }\n\n    private static boolean existeContacto(String nombre) {\n        return agenda.containsKey(nombre);\n    }\n\n    private static void buscar(String nombre) {\n\n        if (existeContacto(nombre)) {\n            System.out.println(\"El numero de \" + nombre + \" es: \" + agenda.get(nombre));\n        } else {\n            System.out.println(\"El usuario no se encuentra en el sistema! \");\n        }\n    }\n\n    private static void eliminar(String nombre) {\n\n        if (existeContacto(nombre)) {\n            agenda.remove(nombre);\n            System.out.println(\"Contacto Eliminado!\");\n        } else {\n            System.out.println(\"Ingrese un nombre de usuario valido!\");\n        }\n    }\n\n    private static boolean cumpleCondiciones(long telefono) {\n        String telStr = Long.toString(telefono);\n        return telStr.length() <= 11;\n    }\n\n    private static void insertar() {\n        System.out.println(\"Agregue el nombre del contacto: \");\n        nombre = keyboard.nextLine();\n\n        System.out.println(\"Agregue el telefono del contacto: \");\n\n        numTelefono = keyboard.nextLong();\n        keyboard.nextLine(); // Consumir el caracter \\n que deja keyboard.nextInt() en el bufer\n\n        if (cumpleCondiciones(numTelefono)) {\n            agenda.put(nombre, numTelefono);\n        } else {\n            System.out.println(\"El numero de telefono tiene que tener al menos un digito y menos que 11 digitos\");\n        }\n\n    }\n\n    private static void actualizar() {\n        System.out.println(\"Que persona desea actualizar?\");\n        nombre = keyboard.nextLine();\n        if (existeContacto(nombre)) {\n            System.out.println(\"Ingrese el nuevo numero: \");\n            numTelefono = keyboard.nextLong();\n            keyboard.nextLine(); // Consumir el caracter \\n que deja keyboard.nextInt() en el bufer\n\n            agenda.replace(nombre, numTelefono);\n            System.out.println(\"Contacto actualizado!\");\n        } else {\n            System.out.println(\"El usuario no se encuentra en el sistema!\");\n        }\n    }\n\n    private static void mostrar() {\n        System.out.println(agenda);\n    }\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/inmortalnight.java",
    "content": "// 03 - Java \n// Estructuras de datos\n\nimport java.util.*;\n\npublic class inmortalnight {\n\tpublic static void main(String[] args) {\n\t\t//Creación de estructuras de datos\n\t\t//NOTA: en Java, al declarar ya se establece un tipo de dato para toda la estructura.\n        //Array, estructura de tamaño fijo \n\t\tint[] array = {1, 2, 3, 4, 5}; //Operación de insercción\n\t\tarray[0] = 1; //Operación de actualización\n\t\tArrays.sort(array); //Operación de ordenación\n\n\t\t//Lista (ArrayList), estructura de tamaño variable de cualquier tipo\n\t\tArrayList<Integer> lista = new ArrayList<Integer>();\n\t\tlista.add(1); //Operación de insercción\n        lista.add(2);\n        lista.remove(1); //Operación de borrado\n        lista.set(0, 10); //Operación de actualización\n        lista.sort(null); //Operación de ordenación\n\t\t\n\t\t//Set, estructura de valores únicos\n\t\tSet<Integer> set = new HashSet<Integer>();\n\t\tset.add(1); //Operación de insercción\n\t\tset.remove(1); //Operación de borrado\n\n\t\t//Map, estructura de clave-valor, donde la clave es única\n\t\tMap<String, Integer> map = new HashMap<String, Integer>();\n\t\tmap.put(\"uno\", 1); //Operación de insercción\n\t\tmap.remove(\"uno\"); //Operación de borrado\n\t\tmap.put(\"uno\", 10); //Operación de actualización\n\n\t\t//Queue, estructura de datos que sigue el orden FIFO\n\t\tQueue<Integer> queue = new LinkedList<Integer>(); \n\t\tqueue.add(1); //Operación de insercción\n\t\tqueue.remove(); //Operación de borrado\n\n\t\t//Stack, estructura de datos que sigue el orden LIFO\n\t\tStack<Integer> stack = new Stack<Integer>();\n\t\tstack.push(1); //Operación de insercción\n\t\tstack.pop(); //Operación de borrado\n\n\t\t//EXTRA: Crear una agenda de contactos\n\t\tEjercicioExtra();\n\t}\n\n\tpublic static void EjercicioExtra() {\n\t\tScanner sc = new Scanner(System.in);\n\t\tMap<String, Integer> agenda = new HashMap<>();\n\t\tint opcion = 0;\n\t\tdo {\n\t\t\tSystem.out.println(\"\\n*** Agenda ***\");\n\t\t\tSystem.out.println(\"Seleccione una opción:\");\n\t\t\tSystem.out.println(\"1. Buscar Contacto\");\n\t\t\tSystem.out.println(\"2. Nuevo Contacto\");\n\t\t\tSystem.out.println(\"3. Actualizar Contacto\");\n\t\t\tSystem.out.println(\"4. Eliminar Contacto\");\n\t\t\tSystem.out.println(\"5. Salir\");\n\t\t\topcion = sc.nextInt();\n\t\t\tswitch(opcion) {\n\t\t\t\tcase 1:\n\t\t\t\t\tBuscarContacto(sc, agenda);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 2:\n\t\t\t\t\tNuevoContacto(sc, agenda);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 3:\n\t\t\t\t\tActualizarContacto(sc, agenda);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 4:\n\t\t\t\t\tEliminarContacto(sc, agenda);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 5:\n\t\t\t\t\tSystem.out.println(\"Saliendo...\");\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tSystem.out.println(\"Opción no válida\");\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t} while (opcion != 5);\n\t\tsc.close();\n\t}\n\n\tpublic static void BuscarContacto(Scanner sc, Map<String, Integer> agenda) {\n        System.out.print(\"Ingrese el nombre del contacto: \");\n        String nombre = sc.next();\n        if (agenda.containsKey(nombre)) {\n            System.out.println(\"Teléfono de \" + nombre + \": \" + agenda.get(nombre));\n        } else {\n            System.out.println(\"Contacto no encontrado.\");\n        }\n    }\n\n    public static void NuevoContacto(Scanner sc, Map<String, Integer> agenda) {\n        System.out.print(\"Ingrese el nombre del nuevo contacto: \");\n        String nombre = sc.next();\n        System.out.print(\"Ingrese el número de teléfono: \");\n        String telefono = sc.next();\n        if (telefono.length() <= 11 && telefono.matches(\"\\\\d+\")) {\n            agenda.put(nombre, Integer.parseInt(telefono));\n            System.out.println(\"Contacto agregado.\");\n        } else {\n            System.out.println(\"Número de teléfono inválido. Debe ser numérico y no más de 11 dígitos.\");\n        }\n    }\n\n    public static void ActualizarContacto(Scanner sc, Map<String, Integer> agenda) {\n        System.out.print(\"Ingrese el nombre del contacto a actualizar: \");\n        String nombre = sc.next();\n        if (agenda.containsKey(nombre)) {\n            System.out.print(\"Ingrese el nuevo número de teléfono: \");\n            String telefono = sc.next();\n            if (telefono.length() <= 11 && telefono.matches(\"\\\\d+\")) {\n                agenda.put(nombre, Integer.parseInt(telefono));\n                System.out.println(\"Contacto actualizado.\");\n            } else {\n                System.out.println(\"Número de teléfono inválido. Debe ser numérico y no más de 11 dígitos.\");\n            }\n        } else {\n            System.out.println(\"Contacto no encontrado.\");\n        }\n    }\n\n    public static void EliminarContacto(Scanner sc, Map<String, Integer> agenda) {\n        System.out.print(\"Ingrese el nombre del contacto a eliminar: \");\n        String nombre = sc.next();\n        if (agenda.containsKey(nombre)) {\n            agenda.remove(nombre);\n            System.out.println(\"Contacto eliminado.\");\n        } else {\n            System.out.println(\"Contacto no encontrado.\");\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/jcrodmir.java",
    "content": "import java.util.*;\n\npublic class EstructuraDatos {\n\n\n    public static void main(String[] args) {\n        /*Array*/\n        int[] array= new int[4];\n        array[0]=3;\n        array[1]=2;\n        array[2]=1;\n        array[3]=4;\n        System.out.println(\"Array\\n\");\n        for (int i = 0; i <  array.length  ; i++) {\n            System.out.println(\"value: \" + i);\n        }\n        System.out.println(\"Update Array 4 to 5\");\n        array[3]=5;\n        for (int i = 0; i <  array.length  ; i++) {\n            System.out.println(\"value: \" + i);\n        }\n        System.out.println(\"Sort Array\");\n        Arrays.sort(array);\n        for (int i = 0; i <  array.length  ; i++) {\n            System.out.println(\"value: \" + i);\n        }\n\n        /*LISTAS*/\n        //Order, Access by index , Can repeat elements.\n        System.out.println(\"\\nARRAYLIST\\n\");\n        List<Integer> list= new ArrayList<>();\n        System.out.println(\"Add 4 elements\");\n        list.add(8);\n        list.add(10);\n        list.add(6);\n        list.add(5);\n        list.forEach(value -> System.out.println(\"value: \" + value));\n        list.remove(3);\n        System.out.println(\"Remove last element 5: \");\n        list.forEach(value -> System.out.println(\"value: \" + value));\n        list.set(0,7);\n        System.out.println(\"Update first element 8 to 7: \");\n        list.forEach(value -> System.out.println(\"value: \" + value));\n        System.out.println(\"Sort the elements: \");\n        list.sort(Comparator.naturalOrder());\n        list.forEach(value -> System.out.println(\"value: \" + value));\n\n        /*ArrayList\n        //When: When you need quick access to elements by index.\n        //Advantage:The same when\n        //Disadvantage:Insertions and deletions in the middle of the list are expensive  because they\n        //require scrolling elements.*/\n        System.out.println(\"\\nARRAYLIST\\n\");\n        ArrayList<Integer> arrayList= new ArrayList<>();\n        System.out.println(\"Add 4 elements\");\n        arrayList.add(8);\n        arrayList.add(10);\n        arrayList.add(6);\n        arrayList.add(5);\n        arrayList.forEach(value -> System.out.println(\"value: \" + value));\n        arrayList.remove(3);\n        System.out.println(\"Remove last element 5: \");\n        arrayList.forEach(value -> System.out.println(\"value: \" + value));\n        arrayList.set(0,7);\n        System.out.println(\"Update first element 8 to 7: \");\n        arrayList.forEach(value -> System.out.println(\"value: \" + value));\n        System.out.println(\"Sort the elements: \");\n        arrayList.sort(Comparator.naturalOrder());\n        arrayList.forEach(value -> System.out.println(\"value: \" + value));\n\n        /*LinkedList\n        //When: When you need a lot of inserts and deletes at the beginning or in the middle of the list.\n        //Advantage:The same when\n        //Disadvantage:Slow access to items by index due to having to traverse the list from the beginning.*/\n        System.out.println(\"\\nLINKEDLIST\\n\");\n        LinkedList<Integer> linkedList= new LinkedList<>();\n        System.out.println(\"Add 4 elements\");\n        linkedList.add(8);\n        linkedList.add(10);\n        linkedList.add(6);\n        linkedList.add(5);\n        linkedList.forEach(value -> System.out.println(\"value: \" + value));\n        linkedList.remove(3);\n        System.out.println(\"Remove last element 5: \");\n        linkedList.forEach(value -> System.out.println(\"value: \" + value));\n        linkedList.set(0,7);\n        System.out.println(\"Update first element 8 to 7: \");\n        linkedList.forEach(value -> System.out.println(\"value: \" + value));\n        System.out.println(\"Sort the elements: \");\n        linkedList.sort(Comparator.naturalOrder());\n        linkedList.forEach(value -> System.out.println(\"value: \" + value));\n        //Vector\n        //When to use: similar to ArrayList but when you need a synchronized version for access from multiple threads.\n        //Advantages: Synchronized, so it is safe for concurrent access.\n        System.out.println(\"\\nVECTOR\\n\");\n        Vector<Integer> vector= new Vector<>();\n        System.out.println(\"Add 4 elements\");\n        vector.add(8);\n        vector.add(10);\n        vector.add(6);\n        vector.add(5);\n        vector.forEach(value -> System.out.println(\"value: \" + value));\n        vector.remove(3);\n        System.out.println(\"Remove last element 5: \");\n        vector.forEach(value -> System.out.println(\"value: \" + value));\n        vector.set(0,7);\n        System.out.println(\"Update first element 8 to 7: \");\n        vector.forEach(value -> System.out.println(\"value: \" + value));\n        System.out.println(\"Sort the elements: \");\n        vector.sort(Comparator.naturalOrder());\n        vector.forEach(value -> System.out.println(\"value: \" + value));\n        //Stack\n        //When to use: When you need a LIFO stack.\n        //Advantages: Provides stack-specific methods such as push and pop.\n        //Disadvantages: It is deprecated and ArrayDeque is recommended as a replacement\n        System.out.println(\"\\nSTACK\\n\");\n        Stack<Integer> stack= new Stack<>();\n        System.out.println(\"Add 4 elements\");\n        stack.add(8);\n        stack.add(10);\n        stack.add(6);\n        stack.add(5);\n        stack.forEach(value -> System.out.println(\"value: \" + value));\n        stack.remove(3);\n        System.out.println(\"Remove last element 5: \");\n        stack.forEach(value -> System.out.println(\"value: \" + value));\n        stack.set(0,7);\n        System.out.println(\"Update first element 8 to 7: \");\n        stack.forEach(value -> System.out.println(\"value: \" + value));\n        System.out.println(\"Sort the elements: \");\n        stack.sort(Comparator.naturalOrder());\n        stack.forEach(value -> System.out.println(\"value: \" + value));\n\n        /*CONJUNTOS*/\n        //Unique values, without Order, belongs a group.\n        //HashSet\n        //When to use: When you need an unordered set and have no duplicates.\n        //Advantages: Fast insert, delete and search operations.\n        //Disadvantages: Does not guarantee any order of the elements.\n        System.out.println(\"\\nHashSet\\n\");\n        HashSet<Integer> hashSet = new HashSet<>();\n        hashSet.add(5);\n        hashSet.add(3);\n        hashSet.add(4);//Ignoring\n        hashSet.add(4);\n        hashSet.add(1);\n        hashSet.forEach(value -> System.out.println(\"Value: \" + value));\n        System.out.println(\"Remove the value 5\");\n        hashSet.remove(5);\n        System.out.println(\"Update  is not available\");\n        hashSet.forEach(value -> System.out.println(\"Value: \" + value));\n        //LinkedHashSet\n        //When to use: when you need a set that maintains insertion order.\n        //Advantages: Maintains insertion order.\n        //Disadvantages: Slightly slower than HashSet due to order maintenance.\n        System.out.println(\"\\nLinkedHashSet\\n\");\n        LinkedHashSet<Integer> linkedHashSet = new LinkedHashSet<>();\n        linkedHashSet.add(5);\n        linkedHashSet.add(3);\n        linkedHashSet.add(4);//Ignoring\n        linkedHashSet.add(4);\n        linkedHashSet.add(1);\n        linkedHashSet.forEach(value -> System.out.println(\"Value: \" + value));\n        System.out.println(\"Remove the value 5\");\n        linkedHashSet.remove(5);\n        System.out.println(\"Update  is not available\");\n        linkedHashSet.forEach(value -> System.out.println(\"Value: \" + value));\n        //TreeSet\n        //When to use: When you need a sorted set.\n        //Advantages: Keeps the elements in ascending order.\n        //Disadvantages: Slower operations compared to HashSet due to the need to maintain order.\n        System.out.println(\"\\nTreeSet\\n\");\n        TreeSet<Integer> treeSet = new TreeSet<>();\n        treeSet.add(5);\n        treeSet.add(3);\n        treeSet.add(4);//Ignoring\n        treeSet.add(4);\n        treeSet.add(1);\n        treeSet.forEach(value -> System.out.println(\"Value: \" + value));\n        System.out.println(\"Remove the value 5\");\n        treeSet.remove(5);\n        System.out.println(\"Update  is not available\");\n        treeSet.forEach(value -> System.out.println(\"Value: \" + value));\n\n        /*MAP*/\n        //HashMap\n        //When to use: when you need an unordered map with unique keys.\n        //Advantages: Fast insert, delete and search operations.\n        //Disadvantages: Does not guarantee any order of the keys.\n        System.out.println(\"\\nHashMap\\n\");\n        HashMap<Integer,Integer> hashMap = new HashMap<>();\n        hashMap.put(2,4);\n        hashMap.put(3,6);\n        hashMap.put(4,8);\n        hashMap.put(5,10);\n        System.out.println(hashMap);\n        System.out.println(\"remove last  key-value\");\n        hashMap.remove(5);//clear lo borra entero\n        System.out.println(hashMap);\n        hashMap.put(2,8);\n        System.out.println(\"update   key 2 to value 8\");\n        System.out.println(hashMap);\n        //LinkedHashMap\n        //When to use: When you need a map that maintains insertion or access order.\n        //Advantages: Maintains insertion or access order.\n        //Disadvantages: Slightly slower than HashMap due to order maintenance.\n        System.out.println(\"\\nLinkedHashMap\\n\");\n        LinkedHashMap<Integer,Integer> linkedHashMap = new LinkedHashMap<>();\n        linkedHashMap.put(2,4);\n        linkedHashMap.put(3,6);\n        linkedHashMap.put(4,8);\n        linkedHashMap.put(5,10);\n        System.out.println(linkedHashMap);\n        System.out.println(\"remove last  key-value\");\n        linkedHashMap.remove(5);//clear lo borra entero\n        System.out.println(linkedHashMap);\n        linkedHashMap.put(2,8);\n        System.out.println(\"update   key 2 to value 8\");\n        System.out.println(linkedHashMap);\n        //TreeMap\n        //When to use: When you need a map ordered by keys.\n        //Advantages: Keeps keys in ascending order.\n        //Disadvantages: Slower operations compared to HashMap due to the need to maintain order.\n        System.out.println(\"\\nTreeMap\\n\");\n        TreeMap<Integer,Integer> treeMap = new TreeMap<>();\n        treeMap.put(2,4);\n        treeMap.put(3,6);\n        treeMap.put(4,8);\n        treeMap.put(5,10);\n        System.out.println(treeMap);\n        System.out.println(\"remove last  key-value\");\n        treeMap.remove(5);//clear lo borra entero\n        System.out.println(treeMap);\n        treeMap.put(2,8);\n        System.out.println(\"update   key 2 to value 8\");\n        System.out.println(treeMap);\n        //Hashtable\n        //When to use: Similar to HashMap but when you need a synchronized version for multi-threaded access.\n        //Advantages: Synchronized, so it is safe for concurrent access.\n        //Disadvantages: Synchronization operations can add overhead.\n        System.out.println(\"\\nHashtable\\n\");\n        Hashtable<Integer,Integer> hashtable = new Hashtable<>();\n        hashtable.put(2,4);\n        hashtable.put(3,6);\n        hashtable.put(4,8);\n        hashtable.put(5,10);\n        System.out.println(hashtable);\n        System.out.println(\"remove last  key-value\");\n        hashtable.remove(5);//clear lo borra entero\n        System.out.println(hashtable);\n        hashtable.put(2,8);\n        System.out.println(\"update   key 2 to value 8\");\n        System.out.println(hashtable);\n\n        /*QUEUES DEQUES*/\n        //PriorityQueue\n        //When to use: when you need a queue with priority.\n        //Advantages: Items are automatically ordered according to their priority.\n        //Disadvantages: Does not allow null elements and is not synchronized.\n        System.out.println(\"PriorityQueue\");\n        PriorityQueue<Integer> priorityQueue= new PriorityQueue<>();\n        priorityQueue.add(2);\n        priorityQueue.add(3);\n        priorityQueue.add(1);\n        System.out.println(priorityQueue);\n        System.out.println(\"Queue with order, all poll\");\n        System.out.println(priorityQueue.poll()+\"-\"+priorityQueue.poll()+\"-\"+priorityQueue.poll());\n        //ArrayDeque\n        //When to use: When you need a deque or a stack.\n        //Advantages: Provides efficient operations to add and remove elements from both ends.\n        //Disadvantages: Does not allow null elements.\n        System.out.println(\"ArrayDeque\");\n        ArrayDeque<Integer> arrayDeque= new ArrayDeque<>();\n        arrayDeque.add(2);\n        arrayDeque.add(3);\n        arrayDeque.add(1);\n        System.out.println(\"peekFirst show the first of the Queue\");\n        System.out.println(arrayDeque.peekFirst());\n        System.out.println(arrayDeque);\n        System.out.println(\"Queue with order, all poll\");\n        System.out.println(arrayDeque.poll()+\"-\"+arrayDeque.poll()+\"-\"+arrayDeque.poll());\n        //LinkedList(like Deque)\n        //When to use: When you need a deque and also want the features of a linked list.\n        //Advantages: Versatility to use as a list, queue or deque.\n        //Disadvantages: Slower operations compared to ArrayDeque for some operations.\n        System.out.println(\"LinkedList\");\n        LinkedList<Integer> linkedListQueue= new LinkedList<>();\n        linkedListQueue.add(2);\n        linkedListQueue.add(3);\n        linkedListQueue.add(1);\n        System.out.println(linkedListQueue);\n        System.out.println(\"Update 1 to a 5\");\n        linkedListQueue.set(2,5);\n        System.out.println(\"delete number 2  add a null\");\n        linkedListQueue.remove(0);\n        System.out.println(linkedListQueue);\n        System.out.println(\"Queue like a list, all poll\");\n        System.out.println(linkedListQueue.poll()+\"-\"+linkedListQueue.poll()+\"-\"+linkedListQueue.poll());\n\n        //EXTRA Contacts\n        System.out.println(\"----------------------------CONTACTS-----------------------------------------------\");\n        int exit=1;\n        ArrayList<String[]> contacts = new ArrayList<>();\n        while(exit !=0){\n            Scanner chooseNumber= new Scanner(System.in);\n            System.out.println(\"Add contact: 1\");\n            System.out.println(\"Update contact: 2\");\n            System.out.println(\"Delete contact: 3\");\n            System.out.println(\"Sort contact: 4\");\n            System.out.println(\"Exit: 5\");\n            System.out.print(\"Your Choice: \");\n            int number= chooseNumber.nextInt();\n            switch (number){\n                case 1:\n                    System.out.println(\"Add contact\");\n                    Scanner chooseName= new Scanner(System.in);\n                    System.out.print(\"Add name: \");\n                    String name= chooseName.next();\n                    Scanner choosePhone= new Scanner(System.in);\n                    System.out.print(\"Add number: \");\n                    String phone= choosePhone.next();\n                    if(checkContact(name,phone) ){\n                        contacts.add(new String[]{name, phone});\n                        System.out.println(\"New Contact \" + name + \" added\");\n                    }\n                    break;\n                case 2:\n                    System.out.println(\"Update contact\");\n                    showContacts(contacts);\n                    System.out.println(\"Number to update\");\n                    int updateNumber= pickNumber();\n                    System.out.println(\"1 update name \");\n                    System.out.println(\"2 update phone \");\n                    if(updateNumber >= 0) {\n                        updateControl(contacts, updateNumber);\n                    }\n                    else{\n                        System.out.println(\"Invalid Option\");\n                    }\n\n                    break;\n                case 3:\n                    System.out.println(\"Delete contact\");\n                    showContacts(contacts);\n                    System.out.println(\"Number to delete\");\n                    deleteControl(contacts);\n\n                    break;\n                case 4:\n                    System.out.println(\"Sort contact\");\n                    contacts.sort(Comparator.comparing(value -> value[0]));\n                    contacts.forEach(value -> System.out.println(\"Contact: \" +value[0] + \" Phone: \" +value[1]));\n                    break;\n                case 5:\n                    System.out.println(\"See you\");\n                    exit =0;\n                    break;\n                default:\n                    System.out.println(\"Wrong Option\");\n                    break;\n            }\n\n        }\n    }\n    public static void showContacts(ArrayList<String[]> contacts){\n        contacts.forEach(value ->\n                System.out.println(contacts.indexOf(value) +\".Contact: \" +value[0] + \" Phone: \" +value[1]));\n\n    }\n    public static void updateControl(ArrayList<String[]> contacts, int updateNumber){\n\n        int updateOption= pickNumber();\n        Scanner newUpdate= new Scanner(System.in);\n        String[] oldContact=contacts.get(updateNumber);\n        switch (updateOption){\n            case 1:\n\n                System.out.print(\"Add name: \");\n                String newName= newUpdate.next();\n                if(checkName(newName)){\n                    contacts.set(updateNumber,new String[]{newName, oldContact[1]});\n                }\n                System.out.println(\"Update name successfully\");\n                break;\n            case 2:\n                System.out.print(\"Add phone: \");\n                String newPhone= newUpdate.next();\n                if(checkName(newPhone)){\n                    contacts.set(updateNumber,new String[]{oldContact[0], newPhone});\n                }\n                System.out.println(\"Update phone successfully\");\n                break;\n            case -1:\n                break;\n            default:\n                System.out.println(\"Invalid option\");\n\n        }\n    }\n\n    public static void deleteControl(ArrayList<String[]> contacts){\n        try {\n            contacts.remove(pickNumber());\n            System.out.println(\"Contact deleted\");\n        }catch (IndexOutOfBoundsException e){\n\n        }\n\n    }\n\n    public static int pickNumber(){\n        try {\n            Scanner chooseNumber= new Scanner(System.in);\n            return chooseNumber.nextInt();\n        }catch (InputMismatchException e){\n            System.out.println(\"Invalid Option\");\n            return -1;\n        }\n    }\n    public static boolean checkName(String name){\n        boolean answer= name != null;\n        return answer;\n    }\n    public static boolean checkPhone(String phone){\n        boolean answer= phone != null && phone.length()<=11 && !phone.isEmpty();\n\n        try {\n            Long.parseLong(phone);\n        }catch (NumberFormatException e){\n            answer = false;\n            System.out.println(\"It´s not numeric\" );\n        }\n        return answer;\n    }\n    public static  boolean checkContact(String name,String phone){\n        return checkPhone(phone) && checkName(name);\n    }\n\n}"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/juanca2805.java",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por\n * defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y\n * eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere\n * realizar, y a continuación\n * los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no numéricos y\n * con más de 11 dígitos.\n * (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.LinkedList;\nimport java.util.Map;\nimport java.util.Queue;\nimport java.util.Stack;\n\npublic class juanca2805 {\n       // INICIALIZACIÓN:\n    // Array\n    static int[] array = new int[4]; // Inicializa un array de tamaño 4 con valores por defecto (0, 0, 0, 0).\n\n    // ArrayList\n    static ArrayList<String> arrayList = new ArrayList<>(); // Inicializa un ArrayList vacío. []\n\n    // Map\n    static Map<Integer, String> map = new HashMap<>(); // Inicializa un HashMap vacío. {}\n\n    // Stack\n    static Stack<Integer> stack = new Stack<>(); // Inicializa una pila vacía. []<=>\n\n    // Queue\n    static Queue<Integer> queue = new LinkedList<>(); // Inicializa una cola vacía. <-[]<-\n\n    public static void main(String[] args) {\n        imprimirContenidos();\n        insertar();\n        imprimirContenidos();\n        borrar();\n        imprimirContenidos();\n        actualizar();\n        imprimirContenidos();\n        ordenar();\n        imprimirContenidos();\n   \n    }\n\n    static void insertar() {\n        // Array\n        array[0] = 2;\n        array[1] = 3;\n        array[2] = 5;\n        array[3] = 6;\n\n        // ArrayList\n        arrayList.add(\"uno\");\n        arrayList.add(\"dos\");\n        arrayList.add(\"tres\");\n        arrayList.add(\"cuatro\");\n\n        // Map\n        map.put(0, \"uno\");\n        map.put(1, \"dos\");\n\n        // Stack\n        stack.push(1);\n        stack.push(2);\n        stack.push(3);\n\n        // Queue\n        queue.offer(1);\n        queue.offer(2);\n        queue.offer(3);\n    }\n\n    static void ordenar() {\n        // Array\n        Arrays.sort(array); // Ordena el array.\n\n        // ArrayList\n        Collections.sort(arrayList); // Ordena el ArrayList.\n\n        // Map - No tiene un método para ordenarlo.\n\n        // Stack - No es necesario ordenar un Stack ya que representa una pila.\n\n        // Queue - No es necesario ordenar una Queue ya que representa una cola.\n    }\n\n    static void borrar() {\n        // Array\n        array[0] = 0;\n\n        // ArrayList\n        arrayList.remove(\"dos\");\n\n        // Map\n        map.remove(1);\n\n        // Stack\n        stack.pop(); // Elimina el elemento superior de la pila.\n\n        // Queue\n        if (!queue.isEmpty()) {\n            queue.poll(); // Elimina el elemento frontal de la cola si no está vacía.\n        }\n    }\n\n    static void actualizar() {\n        // Array\n        array[0] = 7;\n\n        // ArrayList\n        arrayList.set(0, \"UNO\"); // Actualiza el primer elemento del ArrayList.\n\n        // Map\n        map.put(0, \"UNO\"); // Actualiza el valor asociado a la clave 0 en el mapa.\n\n        // Stack\n        if (!stack.isEmpty()) {\n            stack.pop(); // Elimina el elemento superior de la pila.\n            stack.push(99); // Inserta el valor 99 en la pila.\n        }\n\n        // Queue\n        if (!queue.isEmpty()) {\n            queue.poll(); // Elimina el elemento frontal de la cola.\n            queue.offer(999); // Inserta el valor 999 en la cola.\n        }\n    }\n\n    static void imprimirContenidos() {\n        System.out.println(\"Array: \" + Arrays.toString(array));\n        System.out.println(\"ArrayList: \" + arrayList);\n        System.out.println(\"Map: \" + map);\n        System.out.println(\"Stack: \" + stack);\n        System.out.println(\"Queue: \" + queue);\n        System.out.println(\"--------------------------------\");\n    }}"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/julian98789.java",
    "content": "\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.InputMismatchException;\nimport java.util.LinkedList;\nimport java.util.NoSuchElementException;\nimport java.util.PriorityQueue;\nimport java.util.Scanner;\nimport java.util.TreeMap;\nimport java.util.TreeSet;\nimport java.util.Vector;\n\npublic class reto_3 {\n\n    private static HashMap<String, String> contacto = new HashMap();\n\n    public static void main(String[] args) {\n        Scanner input = new Scanner(System.in);\n        // Array\n        int[] array = new int[5];\n        array[0] = 1;\n        array[1] = 2;\n        array[2] = 3;\n        array[1] = 20; // Actualización\n        array[2] = 0; // \"Borrado\"\n        Arrays.sort(array); // Ordenación\n        System.out.println(\"Array: \" + Arrays.toString(array));\n\n        // Matriz\n        int[][] matrix = new int[3][3];\n        matrix[0][0] = 1;\n        matrix[0][1] = 2;\n        matrix[0][2] = 3;\n        matrix[1][0] = 4;\n        matrix[1][1] = 5;\n        matrix[1][2] = 6;\n        matrix[2][0] = 7;\n        matrix[2][1] = 8;\n        matrix[2][2] = 9;\n        matrix[1][1] = 50; // Actualización\n        matrix[2][0] = 0; // \"Borrado\"\n\n        // Ordenación por filas\n        for (int i = 0; i < matrix.length; i++) {\n            Arrays.sort(matrix[i]);\n        }\n\n        System.out.println(\"Matriz ordenada por filas:\");\n        for (int i = 0; i < matrix.length; i++) {\n            System.out.println(Arrays.toString(matrix[i]));\n        }\n\n        // ArrayList\n        ArrayList<Integer> arrayList = new ArrayList<>();\n        arrayList.add(1);\n        arrayList.add(2);\n        arrayList.add(3);\n        arrayList.set(1, 20); // Actualización\n        arrayList.remove(Integer.valueOf(3)); // Borrado\n        Collections.sort(arrayList); // Ordenación\n        System.out.println(\"ArrayList: \" + arrayList);\n\n        // LinkedList\n        LinkedList<String> linkedList = new LinkedList<>();\n        linkedList.add(\"A\");\n        linkedList.add(\"B\");\n        linkedList.add(\"C\");\n        linkedList.set(1, \"Z\"); // Actualización\n        linkedList.remove(\"C\"); // Borrado\n        Collections.sort(linkedList); // Ordenación\n        System.out.println(\"LinkedList: \" + linkedList);\n\n        // HashMap\n        HashMap<Integer, String> hashMap = new HashMap<>();\n        hashMap.put(1, \"Uno\");\n        hashMap.put(2, \"Dos\");\n        hashMap.put(3, \"Tres\");\n        hashMap.put(2, \"Veinte\"); // Actualización\n        hashMap.remove(3); // Borrado\n        System.out.println(\"HashMap: \" + hashMap);\n\n        // HashSet\n        HashSet<String> hashSet = new HashSet<>();\n        hashSet.add(\"A\");\n        hashSet.add(\"B\");\n        hashSet.add(\"C\");\n        hashSet.add(\"B\"); // No se añadirá porque ya existe\n        hashSet.remove(\"C\"); // Borrado\n        // Ordenación (conversión a lista y ordenación)\n        ArrayList<String> sortedList = new ArrayList<>(hashSet);\n        Collections.sort(sortedList);\n        System.out.println(\"HashSet: \" + sortedList);\n\n        // TreeMap\n        TreeMap<Integer, String> treeMap = new TreeMap<>();\n        treeMap.put(1, \"Uno\");\n        treeMap.put(2, \"Dos\");\n        treeMap.put(3, \"Tres\");\n        treeMap.put(2, \"Veinte\"); // Actualización\n        treeMap.remove(3); // Borrado\n        System.out.println(\"TreeMap: \" + treeMap);\n\n        // TreeSet\n        TreeSet<String> treeSet = new TreeSet<>();\n        treeSet.add(\"A\");\n        treeSet.add(\"B\");\n        treeSet.add(\"C\");\n        treeSet.add(\"B\"); // No se añadirá porque ya existe\n        treeSet.remove(\"C\"); // Borrado\n        System.out.println(\"TreeSet: \" + treeSet);\n\n        // Vector\n        Vector<Integer> vector = new Vector<>();\n        vector.add(1);\n        vector.add(2);\n        vector.add(3);\n        vector.set(1, 20); // Actualización\n        vector.remove(Integer.valueOf(3)); // Borrado\n        Collections.sort(vector); // Ordenación\n        System.out.println(\"Vector: \" + vector);\n\n        // PriorityQueue\n        PriorityQueue<Integer> priorityQueue = new PriorityQueue<>();\n        priorityQueue.add(3);\n        priorityQueue.add(1);\n        priorityQueue.add(2);\n        priorityQueue.add(20); // Inserción\n        priorityQueue.remove(2); // Borrado\n        System.out.println(\"PriorityQueue (ordenada automáticamente): \");\n        while (!priorityQueue.isEmpty()) {\n            System.out.print(priorityQueue.poll() + \" \\n\\n\");\n\n        }\n        boolean exit = false;\n        while (!exit) {\n            try {\n                System.out.println(\"*******Libreta de contactos******* \\n\" + //\n                        \"\");\n                System.out.println(\"***Ingresa el numero de la accion que deseas realizar*** \\n\" + //\n                        \"\");\n\n                System.out.println(\"1: Registrar contacto\");\n                System.out.println(\"2: buscar contacto \");\n                System.out.println(\"3: Actualizar contacto\");\n                System.out.println(\"4: Eliminar contacto\");\n                System.out.println(\"5: salir\");\n\n                int option = input.nextInt();\n\n                switch (option) {\n                    case 1:\n                        register();\n                        break;\n                    case 2:\n                        find();\n                        break;\n                    case 3:\n                        update();\n                        break;\n                    case 4:\n                        delete();\n                        break;\n                    case 5:\n                        exit = true;\n                        break;\n                    default:\n                        break;\n                }\n            } catch (InputMismatchException e) {\n                System.out.println(\"Ingrese una opcion valida\");\n                input.nextLine();\n            }\n        }\n\n    }\n\n    public static void register() {\n        Scanner input = new Scanner(System.in);\n\n        System.out.println(\"Nombre\");\n        String name = input.nextLine();\n\n        System.out.println(\"Numero de telefono\");\n        String numberOfPhone = input.nextLine();\n\n        while (numberOfPhone.length() > 11 || !esNumerico(numberOfPhone)) {\n\n            System.out.print(\"Número de teléfono inválido. Ingresa un número maximo de 11 dígitos: \");\n            numberOfPhone = input.nextLine();\n\n            break;\n\n        }\n        contacto.put(numberOfPhone, name);\n    }\n\n    private static String find() {\n        Scanner input = new Scanner(System.in);\n\n        try {\n            System.out.println(\"Número de teléfono:\");\n            String numberOfPhone = input.nextLine();\n\n            if (contacto.containsKey(numberOfPhone) && esNumerico(numberOfPhone)) {\n                String name = contacto.get(numberOfPhone);\n                System.out.println(\"Contacto encontrado:\");\n                System.out.println(\"Nombre: \" + name);\n                System.out.println(\"Número de teléfono: \" + numberOfPhone);\n                return numberOfPhone;\n            } else if (!esNumerico(numberOfPhone)) {\n                System.out.println(\"Ingresa un número entero válido.\");\n            } else {\n                System.out.println(\"No se encontró ningún contacto para el número \" + numberOfPhone);\n            }\n        } catch (NoSuchElementException e) {\n            System.out.println(\"Error: No se encontró ningún contacto.\");\n        }\n        return null;\n    }\n\n    private static void update() {\n        Scanner input = new Scanner(System.in);\n\n        String currentNumberOfPhone = find();\n        String newNumberOfPhone = \"\";\n\n        if (currentNumberOfPhone != null) {\n            System.out.println(\"Ingresa el nuevo numero de telefono\");\n            newNumberOfPhone = input.nextLine();\n\n            while (newNumberOfPhone.length() > 11 || !esNumerico(newNumberOfPhone)) {\n\n                System.out.print(\"Número de teléfono inválido. Ingresa un número maximo de 11 dígitos: \");\n                newNumberOfPhone = input.nextLine();\n\n                break;\n\n            }\n\n        }\n\n        System.out.println(\"Ingresa el nuevo nombre\");\n        String newName = input.nextLine();\n\n        contacto.remove(currentNumberOfPhone);\n        contacto.put(newNumberOfPhone, newName);\n        System.out.println(\"Contacto actualizado con éxito.\");\n\n    }\n\n    private static void delete() {\n        String deleteNumberOfPhone = find();\n\n        contacto.remove(deleteNumberOfPhone);\n\n        System.out.println(\"contacto eliminado con exito\");\n    }\n\n    private static boolean esNumerico(String cadena) {\n        try {\n            Long.parseLong(cadena);\n            return true;\n        } catch (NumberFormatException e) {\n            return false;\n        }\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/kilianhc.java",
    "content": "package retosProgramacion;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.PriorityQueue;\nimport java.util.Queue;\nimport java.util.Scanner;\nimport java.util.Stack;\nimport java.util.TreeMap;\nimport java.util.TreeSet;\n\npublic class RetoCuatro {\n\n    public static void main(String[] args) {\n/*\n        //Array (No hay borrado)\n        int[] numeros = {1, 2, 3, 4, 5};\n        numeros[0] = 0; //Inserción\n        numeros[0] = 10; //Actualización\n        Arrays.sort(numeros); //Ordenación\n        System.out.println(numeros[0]); //Acceso\n\n        //ArrayList\n        ArrayList<String> lista = new ArrayList<>();\n        lista.add(\"Kilian\"); //Inserción\n        lista.add(\"Hernández\");\n        lista.add(\"Chirino\");\n        lista.add(1, \"Daniel\"); //Inserción en una posición determinada\n        lista.set(0, \"Kili\"); //Actualización\n        lista.remove(1); //Borrado\n        Collections.sort(lista); //Ordenación (alfabética)\n        System.out.println(lista);\n\n        //LinkedList\n        LinkedList<String> lista2 = new LinkedList<>();\n        lista2.add(\"Elena\"); //Inserción\n        lista2.addFirst(\"Ele\");\n        lista2.addLast(\"Espino\");\n        lista2.add(2, \"González\");\n        lista2.set(0, \"Elenita\"); //Actualización\n        lista2.remove(0); //Borrado\n        Collections.sort(lista2); //Ordenación\n        System.out.println(lista2);\n\n        //HashSet (No hay actualización...sería borrar y añadir de nuevo)\n        HashSet<String> lista3 = new HashSet<>();\n        lista3.add(\"Kilian\"); //Inserción\n        lista3.add(\"Elena\");\n        lista3.add(\"Daniel\");\n        lista3.remove(\"Daniel\"); //Borrado\n        System.out.println(lista3);\n        List<String> sortedList = new ArrayList(lista3); //Ordenación(hay que convertirla en una ArrayList)\n        Collections.sort(sortedList);\n        System.out.println(sortedList);\n\n        //TreeSet (No hay actualización...sería borrar y añadir de nuevo. | Se ordena automáticamente.)\n        TreeSet<String> lista4 = new TreeSet<>();\n        lista4.add(\"Real Madrid\"); //Inserción\n        lista4.add(\"Barcelona\");\n        lista4.add(\"Las Palmas\");\n        lista4.remove(\"Barcelona\"); //Borrado\n        System.out.println(lista4);\n\n        //TreeMap (Se ordena automáticamente)\n        TreeMap<Integer, String> lista7 = new TreeMap<>();\n        lista7.put(1, \"Real Madrid\"); //Inserción\n        lista7.put(0, \"Barcelona\");\n        lista7.replace(0, \"Las Palmas\"); //Actualización\n        lista7.remove(0); //Borrado\n        System.out.println(lista7);\n\n        //HashMap\n        HashMap<String, String> lista5 = new HashMap<>();\n        lista5.put(\"Subcampeón \", \" Real Madrid\"); //Inserción\n        lista5.put(\"Campeón \", \" Las Palmas\");\n        lista5.put(\"Último \", \" Barcelona\");\n        lista5.replace(\"Último \", \" Tenerife\"); //Actualización\n        lista5.remove(\"Último \"); //Borrado\n        System.out.println(lista5);\n        TreeMap<String, String> sortedMap = new TreeMap<>(lista5); //Ordenación (Convirtiéndolo a un TreeMap)\n        System.out.println(sortedMap);\n\n        //Stack\n        Stack<String> pila = new Stack<>();\n        pila.push(\"Pedri\"); //Inserción\n        pila.push(\"Yeremi\");\n        pila.remove(\"Pedri\");\n        pila.push(\"Ayoze\"); //Actualización (Borrar y añadir)\n        pila.sort(String::compareTo); //Ordenación\n        pila.pop(); //Borrado del último elemento\n        System.out.println(pila);\n\n        //Queue\n        Queue<String> cola = new LinkedList<>();\n        cola.add(\"Valerón\"); //Inserción\n        cola.add(\"Silva\");\n        cola.remove(\"Silva\");\n        cola.add(\"Viera\"); //Actualización (Borrar y añadir)\n        LinkedList<String> sortedCola = new LinkedList<>(cola); //Ordenación\n        sortedCola.sort(String::compareTo);\n        cola.poll(); //Borrado del primer elemento\n        System.out.println(cola);\n        System.out.println(sortedCola);\n\n        //PriorityQueue (no permite actualización, ni ordenación)\n        PriorityQueue<String> lista6 = new PriorityQueue<>();\n        lista6.add(\"España\"); //Inserción\n        lista6.add(\"Alemania\");\n        lista6.remove(\"Alemania\"); //Borrado\n        lista6.add(\"Inglaterra\");\n        lista6.add(\"Francia\");\n        System.out.println(lista6);\n*/\n        agenda();\n\n    }\n\n    //Dificultad Extra\n    public static void agenda() {\n        \n        Scanner leer = new Scanner(System.in);\n        \n        HashMap<String, Long> memoria = new HashMap<>();\n        \n        boolean flujo = true;\n        \n        \n        \n        while (flujo) {\n        System.out.println(\n                \"\\n\"\n                + \"--------AGENDA--------\\n\"\n                + \"1.Buscar Contacto\\n\"\n                + \"2.Insertar Contacto\\n\"\n                + \"3.Actualizar Contacto\\n\"\n                + \"4.Eliminar Contacto\\n\"\n                + \"5.Salir de la Agenda\\n\"\n                + \"Elige una de las opciones:\\n\");\n\n        int opcion = leer.nextInt();       \n\n        switch (opcion) {\n            case 1:\n                System.out.println(\"Introduce el nombre: \\n\");\n                String name = leer.next();\n                if (memoria.containsKey(name)) {\n                    System.out.printf(\"Su numero es: \\n\" + memoria.get(name));\n                } else {\n                    System.out.println(\"El contacto no existe\");\n                }\n                break;\n            case 2:\n                System.out.print(\"Ingrese el nombre: \\n\");\n                name = leer.next();\n                System.out.print(\"Ingrese el número: \\n\");\n                Long numero = leer.nextLong();\n                if(numero.toString(numero).length() == 9) {\n                    memoria.put(name, numero);\n                    System.out.println(\"Contacto insertado\");\n                }else {\n                    System.out.println(\"Error: El número debe tener 9 dígitos\");\n                }\n                break;\n            case 3:\n                System.out.println(\"Ingrese el nombre del contacto que quiere actualizar: \\n\");\n                name = leer.next();\n                System.out.println(\"Ingrese su nuevo número: \\n\");\n                numero = leer.nextLong();\n                if(numero.toString(numero).length() == 9 && memoria.containsKey(name)){\n                    memoria.replace(name, numero);\n                    System.out.println(\"Contacto actualizado\");\n                }else {\n                    System.out.println(\"Error: El nombre debe existir en la agenda y el nuevo número debe tener 9 dígitos\");\n                }\n                break;\n            case 4:\n                System.out.println(\"Ingrese el nombre: \\n\");\n                name = leer.next();\n                if(memoria.containsKey(name)) {\n                    memoria.remove(name);\n                    System.out.println(\"Contacto borrado\");\n                }else {\n                    System.out.println(\"Error: El contacto no existe en la agenda\");\n                }\n                break;\n            case 5:\n                System.out.println(\"Salió de la Agenda\");\n                flujo = false;\n                break;\n            default:\n                System.out.println(\"Error: Elige una opción del 1 al 5\");\n        }\n          \n    }\n        leer.close();\n\n }\n\n}\n\n\n/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto\n *   en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n *   y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n *   y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más\n *   de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.\n */\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/kleyner098.java",
    "content": "\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.LinkedHashMap;\nimport java.util.LinkedHashSet;\nimport java.util.LinkedList;\nimport java.util.Map;\nimport java.util.PriorityQueue;\nimport java.util.Queue;\nimport java.util.Scanner;\nimport java.util.Set;\nimport java.util.Stack;\nimport java.util.TreeMap;\nimport java.util.TreeSet;\n\n\n/**\n * kleyner098\n */\npublic class kleyner098 {\n    /*\n     * EJERCICIO:\n     * - Muestra ejemplos de creación de todas las estructuras soportadas por\n     * defecto en tu lenguaje.\n     * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n     */\n\n    // Método main ------\n    public static void main(String[] args) {\n        // Las estructuras de datos en java se pueden clasificar en estáticas y\n        // dinámicas.\n        // Estáticas: Arrays, Arrays bidimensionales, Arrays multidimensionales\n        // Dinámicas, se pueden dividir en:\n        // -List: ArraysList, LinkedList\n        // -Queue\n        // -Stacks\n        // -Set: HashSet, TreeSet, LinkedListSet\n        // -Map: HashMap, TreeMap\n        // Generalmente la forma de construir un estructura de dato es :\n        // tipoDato nombreEstructura = new tipoEstructura\n\n        // Arrays: Estructura de datos de elementos del mismo tipo y tamaño estático\n\n        // Creación de array\n        System.out.println(\"Array ----------------------\");\n        int[] arrayNumbers = new int[3];\n        // Inserción\n        for (int i = 0; i < arrayNumbers.length; i++) {\n            arrayNumbers[i] = arrayNumbers.length - i - 1;\n        }\n        System.out.println(Arrays.toString(arrayNumbers));\n        // Ordenar\n        Arrays.sort(arrayNumbers);\n        System.out.println(Arrays.toString(arrayNumbers));\n        // Para borrar debemos aplicar métodos que nos permita indentificar el elemnto\n        // que deseamos borrar y métodos que nos permitar copiar la tabla sin el\n        // elemento\n        // Buscamos el indice del elemento que queremos borrar, binarySearch solo\n        // funciona con arrays ordenadas\n        int indexElement = Arrays.binarySearch(arrayNumbers, 2);\n        // Desplazamos todos los elementos despues del elemento que quermos borrar una\n        // posición menos\n        System.arraycopy(arrayNumbers, indexElement + 1, arrayNumbers, indexElement,\n                arrayNumbers.length - indexElement - 1);\n        // Copiamos la tabla sin el elemento que hemos borrado y le asignamos una\n        // longitud menos\n        arrayNumbers = Arrays.copyOf(arrayNumbers, arrayNumbers.length - 1);\n        System.out.println(Arrays.toString(arrayNumbers));\n        // Actualización\n        arrayNumbers[1] = 4;\n        System.out.println(Arrays.toString(arrayNumbers));\n\n        // List: Estructura de datos dinámica con datos repetidos y orden relevante en\n        // ocasiones.\n        // Las dos clase ArrayList y LinkedList ofrecen los mismos métodos y\n        // funcionalidades\n        // La diferencia entre ArrayList y LinkedList es que la primera ofrece un mayor\n        // rendimiento en lectura y modificación de elementos y la sengunda ofrece mayor\n        // rendimiento en en inserción y eliminación. Utilizare ArrayList pero le puede\n        // sustituir por la clase LinkedList\n        System.out.println(\"List ----------------------\");\n        ArrayList<Integer> arrayList = new ArrayList<>();\n        // Inserción\n        arrayList.add(1);\n        arrayList.add(7);\n        arrayList.add(3);\n        System.out.println(arrayList);\n        // Borrado\n        arrayList.remove(0);\n        System.out.println(arrayList);\n        // Actualización\n        arrayList.set(0, 10);\n        System.out.println(arrayList);\n        // Ordenación\n        Collections.sort(arrayList);\n        System.out.println(arrayList);\n\n        // Las colas son estructuras de datos que siguen el principio FIFO (First In,\n        // First Out). Se puede utilizar la clase PriorityQueue una cola que ordena los\n        // elementos o una Linkedlist que no ordena la cola\n        System.out.println(\"Queue ----------------------\");\n        PriorityQueue<Integer> priorityQueue = new PriorityQueue<>();\n        Queue<Integer> queue = new LinkedList<>();\n        // Inserción\n        priorityQueue.offer(3);\n        priorityQueue.offer(1);\n        priorityQueue.offer(2);\n        queue.offer(3);\n        queue.offer(1);\n        queue.offer(2);\n        System.out.println(\"PriorityQueue:\" + priorityQueue);\n        System.out.println(\"Queue:\" + queue);\n        // Borrado\n        priorityQueue.poll();\n        queue.poll();\n        System.out.println(\"PriorityQueue:\" + priorityQueue);\n        System.out.println(\"Queue:\" + queue);\n        // Actualización\n        // Debido a que las colas siguen el principio de FIFO, no tiene sentido\n        // actualizar un valor\n        // Ordenación\n        // En el caso de PriorityQueue ordena los elementos según el orden de prioridad.\n        // En general, tampoco tiene sentido ordenar las cola ya que los elemntos se\n        // procesan según se insertaron\n\n        // La pilas son estructuras de datos que siguen el principio LIFO (Last In,\n        // First Out).\n        System.out.println(\"Stack ----------------------\");\n        Stack<Integer> stack = new Stack<>();\n        // Inserción\n        stack.push(3);\n        stack.push(1);\n        stack.push(2);\n        System.out.println(stack);\n        // Borrado\n        stack.pop();\n        System.out.println(stack);\n        // Actualización\n        // Debido a que las pila siguen el principio de LIFO, no tiene sentido\n        // actualizar un valor\n        // Ordenación\n        // En general, tampoco tiene sentido ordenar las cola ya que los elemntos se\n        // procesan sengún el ultimo valor introducido\n\n        // Los conjuntos son estructuras de datos que no admiten elementos repetidos y\n        // su orden no es relevante\n        // Existen tres clase HashSet, TreeSet, LinkedHashSet. La diferencia principal\n        // diferencia entre ellos es que HashSet no garantiza el orden de la inserción,\n        // TreeSet mantiene los elemento ordenados segun el orden natural y\n        // LinkedHashSet mantiene el orden de insersión;\n        System.out.println(\"Set ----------------------\");\n        Set<String> hashSet = new HashSet<>();\n        Set<String> linkedHashSet = new LinkedHashSet<>();\n        Set<String> treeSet = new TreeSet<>();\n        // Inserción\n        hashSet.add(\"c\");\n        hashSet.add(\"a\");\n        hashSet.add(\"b\");\n        hashSet.add(\"c\");\n        System.out.println(\"HashSet: \" + hashSet);\n        treeSet.add(\"c\");\n        treeSet.add(\"a\");\n        treeSet.add(\"b\");\n        treeSet.add(\"c\");\n        System.out.println(\"TreeSet: \" + treeSet);\n        linkedHashSet.add(\"c\");\n        linkedHashSet.add(\"a\");\n        linkedHashSet.add(\"b\");\n        linkedHashSet.add(\"c\");\n        System.out.println(\"LinkedHashSet: \" + linkedHashSet);\n        // Borrado\n        hashSet.remove(\"b\");\n        System.out.println(\"HashSet: \" + hashSet);\n        treeSet.remove(\"b\");\n        System.out.println(\"TreeSet: \" + treeSet);\n        linkedHashSet.remove(\"b\");\n        System.out.println(\"LinkedHashSet: \" + linkedHashSet);\n        // Actualizar\n        // No se puede actualizar como tal, si queremos actualizar un valor debemos\n        // borrar y agragar otro\n        // Ordenación\n        // No tiene mucho sentido ordenar ningúna de la tres, sobre todo TreeSet y\n        // LinkedHasSet porque una ya esta ordenada y la una de las funciones de la otra\n        // es mantener el orden de inserción. En el caso de HashSet, podemos hacer una\n        // conversión a una lista y ordenarla\n\n        // Los mapas son estructuras de datos donde sus elementos se relacionan en pares\n        // de clave/valor. Las claves son únicas, pero pueden tener el mismo valor\n        // Existen tres clase HashMap, TreeMap, LinkedHashMap. La diferencia entre ellos\n        // es similar a\n        // las diferencia entre las clase de Set. En el caso de TreeMap el orden será el\n        // ordena narutal creciente de las claves\n        System.out.println(\"Map ----------------------\");\n        Map<String, Integer> hashMap = new HashMap<>();\n        Map<String, Integer> treeMap = new TreeMap<>();\n        Map<String, Integer> linkedHashMap = new LinkedHashMap<>();\n        // Inserción\n        hashMap.put(\"b\", 3);\n        hashMap.put(\"a\", 2);\n        hashMap.put(\"c\", 3);\n        System.out.println(\"HashMap: \" + hashMap);\n        treeMap.put(\"b\", 3);\n        treeMap.put(\"a\", 2);\n        treeMap.put(\"c\", 1);\n        System.out.println(\"HashMap: \" + treeMap);\n        linkedHashMap.put(\"b\", 2);\n        linkedHashMap.put(\"c\", 1);\n        linkedHashMap.put(\"a\", 3);\n        System.out.println(\"LinkedHashMap: \" + linkedHashMap);\n        // Borrado\n        hashMap.remove(\"b\");\n        System.out.println(\"HashMap: \" + hashMap);\n        treeMap.remove(\"b\");\n        System.out.println(\"HashMap: \" + treeMap);\n        linkedHashMap.remove(\"b\");\n        System.out.println(\"LinkedHashMap: \" + linkedHashMap);\n        // Actualización\n        hashMap.put(\"c\", 1);\n        System.out.println(\"HashMap: \" + hashMap);\n        treeMap.put(\"c\", 7);\n        System.out.println(\"HashMap: \" + treeMap);\n        linkedHashMap.put(\"c\", 5);\n        System.out.println(\"HashMap: \" + linkedHashMap);\n        // Ordenación\n        // No tiene sentido ordenarlos y dependiendo del programa usaremos uno u otro\n\n        // Ejercicio extra\n        System.out.println();\n        agenda();\n    }\n\n    /*\n     * DIFICULTAD EXTRA (opcional):\n     * Crea una agenda de contactos por terminal.\n     * - Debes implementar funcionalidades de búsqueda, inserción, actualización y\n     * eliminación de contactos.\n     * - Cada contacto debe tener un nombre y un número de teléfono.\n     * - El programa solicita en primer lugar cuál es la operación que se quiere\n     * realizar, y a continuación\n     * los datos necesarios para llevarla a cabo.\n     * - El programa no puede dejar introducir números de teléfono no númericos y\n     * con más de 11 dígitos.\n     * (o el número de dígitos que quieras)\n     * - También se debe proponer una operación de finalización del programa.\n     */\n    static void agenda() {\n        Map<String, Integer> agenda = new HashMap<>();\n        Scanner sc = new Scanner(System.in);\n        String eleccion;\n        int numEleccion = 0;\n        // String multilinea\n        String option = \"\"\"\n                Introduce el número de la opción que quieres realizar.\n                1. Añadir un nuevo contacto\n                2. Actualizar un contacto\n                3. Buscar contacto\n                4. Eliminar contacto\n                5. Mostra agenda\n                6. Cerrar agenda\n                \"\"\";\n        // Bucle que no terminará hasta que la opción se 5\n        while (true) {\n            // Mostramos las opciones\n            System.out.println(option);\n            eleccion = sc.next();\n            sc.nextLine();\n            // Comprobamos si se a introducido un digito\n            if (!(Character.isDigit(eleccion.charAt(0)))) {\n                System.out.println(\"Introduce un número\");\n            } else {\n                // Convertimos el carácter en un int restando el valor del caracter 0, 48 en\n                // ASCII\n                numEleccion = eleccion.charAt(0) - '0';\n                // Comprobamos el digito con las opciones disponibles\n                switch (numEleccion) {\n                    case 1 -> {\n                        addContacto(agenda);\n                    }\n                    case 2 -> {\n                        actualizar(agenda);\n                    }\n                    case 3 -> {\n                        buscar(agenda);\n                    }\n                    case 4 -> {\n                        eliminar(agenda);\n                    }\n                    case 5 ->{\n                        System.out.println(agenda + \"\\n\");\n                    }\n                    case 6 -> {\n                        System.out.println(\"Agenda cerrada\");\n                        System.exit(0);\n                    }\n                    default -> {\n                        System.out.println(\"Introduce un número válido\");\n                    }\n                }\n            }\n        }\n\n    }\n\n    public static void addContacto(Map<String, Integer> agenda) {\n        String nombre;\n        String telf;\n        int telfNum;\n        Scanner sc = new Scanner(System.in);\n        do {\n            System.out.println(\"Introduce el nombre del contacto\");\n            nombre = sc.nextLine();\n            if (agenda.containsKey(nombre)) {\n                System.out.println(\"El contacto está en la agenda\");\n            }\n        } while (agenda.containsKey(nombre));\n\n        do {\n            System.out.println(\"Introduce el télefono de contacto del contacto\");\n            do {\n                if(!(sc.hasNextInt())){\n                    System.out.println(\"Error. Introduce un número :\");\n                    sc.next();\n                }\n            } while (!(sc.hasNextInt()));\n            telfNum = sc.nextInt();\n            telf = String.valueOf(telfNum);\n            if (telf.length() > 9) {\n                System.out.println(\"El número de teléfono no puede tener mas de 9 digitos\");\n            }\n        } while (telf.length() > 9);\n\n        System.out.println(\"Contacto añadido\\n\");\n        agenda.put(nombre, telfNum);\n    }\n\n    public static void actualizar(Map<String, Integer> agenda){\n        String nombre;\n        String telf;\n        int telfNum;\n        Scanner sc = new Scanner(System.in);\n        System.out.println(\"Introduce el nombre del contacto\");\n        nombre = sc.nextLine();\n        if(!(agenda.containsKey(nombre))){\n            System.out.println(\"Contacto no encontrado\\n\");\n        }else{\n            do {\n                System.out.println(\"Introduce el nuevo télefono de contacto del contacto\");\n                do {\n                    if(!(sc.hasNextInt())){\n                        System.out.println(\"Error. Introduce un número :\");\n                        sc.next();\n                    }\n                } while (!(sc.hasNextInt()));\n                telfNum = sc.nextInt();\n                telf = String.valueOf(telfNum);\n                if (telf.length() > 9) {\n                    System.out.println(\"El número de teléfono no puede tener mas de 9 digitos\");\n                }\n            } while (telf.length() > 9);\n            System.out.println(\"Contacto actualizado \\n\");\n            agenda.put(nombre, telfNum);\n        }\n    }\n\n    public static void buscar(Map<String, Integer> agenda){\n        String nombre;\n        Scanner sc = new Scanner(System.in);\n        System.out.println(\"Introduce el nombre del contacto\");\n        nombre = sc.nextLine();\n        if(!(agenda.containsKey(nombre))){\n            System.out.println(\"Contacto no encontrado\");\n        }else{\n            System.out.println(nombre + \"|\" + agenda.get(nombre)+\"\\n\");;\n        }\n    }\n\n    public static void eliminar(Map<String, Integer> agenda){\n        String nombre;\n        Scanner sc = new Scanner(System.in);\n        System.out.println(\"Introduce el nombre del contacto\");\n        nombre = sc.nextLine();\n        if(!(agenda.containsKey(nombre))){\n            System.out.println(\"Contacto no encontrado\");\n        }else{\n            agenda.remove(nombre);\n            System.out.println(\"Contacto eliminado \\n\");\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/lautarorisso.java",
    "content": "import java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.HashSet;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.Queue;\nimport java.util.Set;\nimport java.util.Stack;\nimport java.util.TreeMap;\nimport java.util.TreeSet;\nimport java.util.Scanner;\nimport java.util.Map;\nimport java.util.HashMap;\n\npublic class LogicaJava03 {\n    \n    private static final Map<String, String> agenda = new HashMap<>();\n    private static final Scanner teclado =new Scanner(System.in);\n    \n    public static void main(String[] args) {\n    \n        // 1.\n        // Array\n        int[] numeros = new int[3];\n\n        // Inserción / actualización\n        numeros[0] = 10;\n        numeros[1] = 5;\n\n        // Borrado (no existe, se reasigna)\n        numeros[1] = 0;\n\n        // Ordenación\n        Arrays.sort(numeros);\n\n        // Mostrar\n        System.out.println(Arrays.toString(numeros));\n        \n        // ArrayList\n        \n        List<String> nombres = new ArrayList<>();\n\n        // Inserción\n        nombres.add(\"Ana\");\n        nombres.add(\"Pedro\");\n\n        // Actualización\n        nombres.set(1, \"Lucía\");\n\n        // Borrado\n        nombres.remove(\"Pedro\");\n\n        // Ordenación\n        Collections.sort(nombres);\n\n        // Mostrar\n        System.out.println(nombres);\n\n        // LinkedList\n        List<Integer> edades = new LinkedList<>();\n\n        edades.add(30);\n        edades.add(20);\n\n        edades.set(0, 35);\n        edades.remove(1);\n\n        Collections.sort(edades);\n\n        System.out.println(edades);\n\n        // HashSet\n        Set<String> paises = new HashSet<>();\n\n        paises.add(\"Argentina\");\n        paises.add(\"Brasil\");\n        paises.add(\"Argentina\"); // duplicado, no entra\n\n        paises.remove(\"Brasil\");\n\n        // ❌ No hay actualización directa (se borra y se agrega)\n        paises.remove(\"Argentina\");\n        paises.add(\"Uruguay\");\n\n        // Ordenación → convertir a lista\n        List<String> ordenados = new ArrayList<>(paises);\n        Collections.sort(ordenados);\n\n        System.out.println(ordenados);\n        \n        // TreeSet\n        Set<Integer> numeros2 = new TreeSet<>();\n\n        numeros2.add(50);\n        numeros2.add(10);\n\n        numeros2.remove(10);\n\n        // Ya está ordenado\n        System.out.println(numeros);\n        \n        // HashMap\n        \n        Map<String, Integer> personas = new HashMap<>();\n\n        // Inserción\n        personas.put(\"Roberto\", 25);\n        personas.put(\"Ana\", 30);\n\n        // Actualización\n        personas.put(\"Roberto\", 40);\n\n        // Borrado\n        personas.remove(\"Ana\");\n\n        // Ordenación por clave\n        Map<String, Integer> ordenado = new TreeMap<>(personas);\n\n        System.out.println(ordenado);\n\n        // TreeMap\n        Map<Integer, String> ranking = new TreeMap<>();\n\n        ranking.put(3, \"Bronce\");\n        ranking.put(1, \"Oro\");\n        ranking.put(2, \"Plata\");\n\n        ranking.remove(3);\n\n        System.out.println(ranking);\n\n        // Queue\n        Queue<String> cola = new LinkedList<>();\n\n        cola.add(\"Cliente 1\");\n        cola.add(\"Cliente 2\");\n\n        cola.poll(); // elimina el primero\n\n        System.out.println(cola);\n\n        // Stack\n        Stack<Integer> pila = new Stack<>();\n\n        pila.push(10);\n        pila.push(20);\n\n        pila.pop(); // elimina el último\n\n        System.out.println(pila);\n        \n        \n        // EXTRA : Agenda de contactos\n        int opcion;\n        \n        do {\n            mostrarMenu();\n            opcion = leerOpcion();\n\n            switch (opcion) {\n                case 1 -> insertarContacto();\n                case 2 -> buscarContacto();\n                case 3 -> actualizarContacto();\n                case 4 -> eliminarContacto();\n                case 5 -> System.out.println(\"Programa finalizado.\");\n                default -> System.out.println(\"Opción inválida\");\n            }\n\n        } while (opcion != 5);\n\n        teclado.close();\n    }\n    \n    private static void mostrarMenu() {\n        System.out.println(\"\\n--- AGENDA DE CONTACTOS ---\");\n        System.out.println(\"1. Insertar contacto\");\n        System.out.println(\"2. Buscar contacto\");\n        System.out.println(\"3. Actualizar contacto\");\n        System.out.println(\"4. Eliminar contacto\");\n        System.out.println(\"5. Salir\");\n        System.out.print(\"Elegí una opción: \");\n    }\n\n    private static int leerOpcion() {\n        while (!teclado.hasNextInt()) {\n            System.out.print(\"Ingresá un número válido: \");\n            teclado.next();\n        }\n        int opcion = teclado.nextInt();\n        teclado.nextLine(); // limpiar buffer\n        return opcion;\n    }\n    \n    private static String leerTelefono() {\n        String telefono;\n        \n        while (true) {\n            System.out.print(\"Teléfono (solo números, máx 11 dígitos): \");\n            telefono = teclado.nextLine();\n            \n            if (telefono.length() == 0) {\n            System.out.println(\"Error: no puede estar vacío.\");\n            continue;\n            }\n\n            if (telefono.length() > 11) {\n                System.out.println(\"Error: máximo 11 dígitos.\");\n                continue;\n            }\n\n            boolean esNumerico = true;\n\n            for (int i = 0; i < telefono.length(); i++) {\n                char c = telefono.charAt(i);\n\n                if (c < '0' || c > '9') {\n                    esNumerico = false;\n                    break;\n                }\n            }\n\n            if (!esNumerico) {\n                System.out.println(\"Error: solo números.\");\n                continue;\n            }\n\n            break;\n        }\n\n        return telefono;\n    }\n    \n    private static void insertarContacto() {\n        System.out.print(\"Nombre: \");\n        String nombre = teclado.nextLine();\n\n        if (agenda.containsKey(nombre)) {\n            System.out.println(\"Ese contacto ya existe.\");\n            return;\n        }\n\n        String telefono = leerTelefono();\n        agenda.put(nombre, telefono);\n        System.out.println(\"Contacto agregado.\");\n    }\n    \n    private static void buscarContacto() {\n        System.out.print(\"Nombre a buscar: \");\n        String nombre = teclado.nextLine();\n\n        if (agenda.containsKey(nombre)) {\n            System.out.println(\"Teléfono: \" + agenda.get(nombre));\n        } else {\n            System.out.println(\"Contacto no encontrado.\");\n        }\n    }\n    \n    private static void actualizarContacto() {\n        System.out.print(\"Nombre a actualizar: \");\n        String nombre = teclado.nextLine();\n\n        if (!agenda.containsKey(nombre)) {\n            System.out.println(\"El contacto no existe.\");\n            return;\n        }\n\n        System.out.print(\"Escribe telefono nuevo: \");\n        String nuevoTelefono = leerTelefono();\n        agenda.put(nombre, nuevoTelefono);\n        System.out.println(\"Contacto actualizado.\");\n    }\n\n    private static void eliminarContacto() {\n        System.out.print(\"Nombre a eliminar: \");\n        String nombre = teclado.nextLine();\n\n        if (agenda.remove(nombre) != null) {\n            System.out.println(\"Contacto eliminado.\");\n        } else {\n            System.out.println(\"Contacto no encontrado.\");\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/mariovelascodev.java",
    "content": "import java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Scanner;\n\npublic class mariovelascodev {\n    public static void main(String[] args) {\n        //Estructuras de datos\n\n        //Arrays\n        System.out.println(\"Arrays\");\n        int [] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};\n\n        //Acceso elemento indicado\n        System.out.println(numbers[3]);\n\n        // Cambiar elemento\n        numbers[3] = 12;\n        System.out.println(numbers[3]);\n\n        //Ver longitud\n        System.out.println(numbers.length);\n\n        System.out.println(\"-----------------------\\n\");\n\n        //ArrayList\n        System.out.println(\"ArrayList\");\n        //Creación del ArrayList\n        ArrayList<String> cars = new ArrayList<>();\n\n        //Inserción de datos\n        cars.add(\"Volvo\");\n        cars.add(\"Toyota\");\n        cars.add(\"Ford\");\n        cars.add(\"BMW\");\n        cars.add(\"Mazda\");\n\n        System.out.println(cars);\n\n        //Ver tamaño del ArrayList\n        System.out.println(cars.size());\n\n        //Acceso al elemento\n        System.out.println(cars.get(1)); //Accede al elemento del indice 1\n        System.out.println(cars.getFirst()); //Acede al primer elemento\n        System.out.println(cars.getLast()); //Accede al último elemento\n\n        //Cambiar valor de algún elemento\n        cars.set(0, \"Opel\");\n        System.out.println(cars);\n\n        //Eliminar elemento\n        cars.remove(3);\n        System.out.println(cars);\n\n        cars.clear(); //Vaciaria el ArrayList\n        System.out.println(cars);\n\n        System.out.println(\"-----------------------\\n\");\n\n        //HashSet\n        System.out.println(\"HashSet\");\n\n        //Creación del HashSet\n        HashSet<Integer> setNumbers = new HashSet<Integer>();\n\n        //Añadir elemento\n        setNumbers.add(1);\n        setNumbers.add(2);\n        setNumbers.add(3);\n        setNumbers.add(4);\n        setNumbers.add(5);\n\n        System.out.println(setNumbers);\n\n        //Comprobar si un elemento existe\n        System.out.println(setNumbers.contains(3));\n\n        //Ver tamaño del HashSet\n        System.out.println(setNumbers.size());\n\n        //Eliminar elemento\n        setNumbers.remove(3); //Elimina el elemento indicado\n        System.out.println(setNumbers);\n\n        setNumbers.clear(); //Vacía el HashSet\n        System.out.println(setNumbers);\n\n        System.out.println(\"-----------------------\\n\");\n\n        //HashMap\n        System.out.println(\"HashMap\");\n\n        //Creación de HashMap\n        HashMap <String, Integer> contact = new HashMap<>();\n\n        //Añadir elemento\n        contact.put(\"Marta\", 123456789);\n        contact.put(\"Victor\", 234567891);\n        contact.put(\"Rodrigo\", 987654321);\n        contact.put(\"Carla\", 987654321);\n        contact.put(\"Carlos\", 987654321);\n\n        System.out.println(contact);\n\n        //Ver tamaño del HashMap\n        System.out.println(contact.size());\n\n        //Acceder al elemento\n        System.out.println(contact.get(\"Marta\"));\n\n        //Eliminar elemento\n        contact.remove(\"Rodrigo\"); //Elimina el elemento indicado por la clave\n        System.out.println(contact);\n\n        contact.clear(); //Vacía el HashMap\n        System.out.println(contact);\n\n        System.out.println(\"-----------------------\\n\");\n\n        //EXTRA\n        System.out.println(\"Extra\");\n        addressBook();\n    }\n\n    public static void addressBook() {\n        System.out.println(\"Agenda de Contactos\");\n\n        HashMap<String, Integer> contacts = new HashMap<>();\n        Scanner input = new Scanner(System.in);\n        Scanner inputName = new Scanner(System.in);\n        Scanner inputPhone = new Scanner(System.in);\n        boolean open = true;\n        String name;\n        String phone;\n\n        //Menú de opciones de la agenda de contactos\n        while (open) {\n            System.out.print(\"\"\"\n                    1 - Ver Contactos\n                    2 - Búsqueda de Contactos\n                    3 - Añadir Contactos\n                    4 - Actualización de Contactos\n                    5 - Eliminar Contactos\n                    6 - Salir\n                    Introduce el número de la acción a realizar:\n                    \"\"\");\n\n            int inputOption = input.nextInt();\n\n\n            switch (inputOption) {\n                case 1:\n                    System.out.println(\"Contactos\");\n                    contacts.forEach((contactName, phoneNumber) ->\n                            System.out.println(contactName + \": \" + phoneNumber));\n                    break;\n                case 2:\n                    System.out.println(\"Introduce el contacto a buscar:\");\n                    name = inputName.nextLine();\n\n                    if (contacts.containsKey(name)) {\n                        System.out.println(contacts.get(name));\n                    }else {\n                        System.out.println(\"Contacto no encontrado\");\n                    }\n\n                    break;\n                case 3:\n                    System.out.println(\"Introduce el nombre del contacto:\");\n                    name = inputName.nextLine();\n\n                    System.out.println(\"Introduce el número de teléfono:\");\n                    phone = inputPhone.nextLine();\n\n                    if(phone.length() == 9) {\n                        try {\n                            int phoneNumber = Integer.parseInt(phone);\n                            contacts.put(name, phoneNumber);\n                            System.out.println(\"Contacto creado correctamente\");\n                        }catch (NumberFormatException e) {\n                            System.out.println(\"Error, no has introducido un número.\");\n                        }\n                    }else {\n                        System.out.println(\"Error, el número de teléfono debe tener una longitud de 9 números.\");\n                    }\n\n                    break;\n                case 4:\n                    System.out.println(\"Introduce el nombre del contacto:\");\n                    name = inputName.nextLine();\n\n                    if(contacts.containsKey(name)) {\n                        System.out.println(\"Introduce el número de teléfono a actualizar:\");\n                        phone = inputPhone.nextLine();\n\n                        if(phone.length() == 9) {\n                            try {\n                                int phoneNumber = Integer.parseInt(phone);\n                                contacts.replace(name, phoneNumber);\n                                System.out.println(\"Contacto actualizado correctamente\");\n                            }catch (NumberFormatException e) {\n                                System.out.println(\"Error,\"+e.getMessage()+\". Introduce el número de teléfono\");\n                            }\n                        }else {\n                            System.out.println(\"Error, el número de teléfono debe tener una longitud de 9 números.\");\n                        }\n\n                    }\n                    break;\n                case 5:\n                    System.out.println(\"Introduce el nombre del contacto a eliminar:\");\n                    name = inputName.nextLine();\n\n                    if(contacts.containsKey(name)) {\n                        contacts.remove(name);\n                        System.out.println(\"Contacto eliminado correctamente\");\n                    }else{\n                        System.out.println(\"Contacto no encontrado\");\n                    }\n                    break;\n                case 6:\n                    open = false;\n                    break;\n                default:\n                    System.out.println(\"Debes introducir una opción valida.\\nMarcando números del 1 al 6\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/martinbohorquez.java",
    "content": "import java.util.*;\nimport java.util.stream.Collectors;\n\n/**\n * 03 ESTRUCTURAS DE DATOS\n *\n * @author martinbohorquez\n */\npublic class martinbohorquez {\n    /**\n     * Arrays\n     */\n    private static final int[] array = new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; //array con datos inicializados\n    private static final int[] array2 = new int[10]; //array con longitud\n    /**\n     * List: {@code ArrayList}, {@code LinkedList}, {@code Vector}, {@code Stack}<p>\n     * Unlike sets, lists typically allow duplicate elements, null elements.<p>\n     * An ordered collection, where the user has precise control over where in the list\n     * each element is inserted. The user can access elements by their integer index\n     * (position in the list), and search for elements in the list.<p>\n     * {@code iterator}, {@code add}, {@code remove}, {@code equals}, and\n     * {@code hashCode} methods.\n     */\n    private static final List<String> lista = new ArrayList<>();//Mutable\n    private static final List<String> listaInmutable = List.of(\"Martin\", \"Zuckerberg\");//Inmutable\n    private static final List<String> listaMutable = new ArrayList<>(Arrays.asList(\"Martin\", \"Zuckerberg\"));//Mutable\n    /**\n     * Set: {@code HashSet}, {@code LinkedHashSet}, {@code TreeSet}<p>\n     * A collection that contains no duplicate elements.  More formally, sets\n     * contain no pair of elements {@code e1} and {@code e2} such that\n     * {@code e1.equals(e2)}, and at most one null element.<p>\n     * {@code TreeSet} sorted based on natural ordering or custom comparator\n     */\n    private static final Set<String> conjunto = new HashSet<>();\n    private static final Set<String> conjuntoInmutable = Set.of(\"Martin\", \"Zuckerberg\");//Inmutable\n    private static final Set<String> conjuntoMutable = new HashSet<>(Arrays.asList(\"Martin\", \"Zuckerberg\"));\n\n    /**\n     * Map: {@code HashMap}, {@code LinkedHashMap}, {@code HashTable}, {@code TreeMap}<p>\n     * An object that maps keys to values. A map cannot contain duplicate keys;\n     * each key can map to at most one value.\n     * <p>This interface takes the place of the {@code Dictionary} class, which\n     * was a totally abstract class rather than an interface.\n     * <p>{@code TreeMap} sorted based on natural ordering or custom comparator\n     */\n    private static final Map<String, String> diccionario = new HashMap<>();\n    private static final Map<String, Integer> diccionarioSingleton = Collections.singletonMap(\"uno\", 1);\n    private static final Map<String, Integer> diccionarioInmutable = Map.of(\n            \"uno\", 1,\n            \"dos\", 2,\n            \"tres\", 3\n    );//Inmutable\n    private static final Map<String, Integer> linkedHashMap = new LinkedHashMap<>();\n    private static final Map<String, Integer> treeMap = new TreeMap<>();//Ordered\n    private static Scanner scan;\n\n    public static void main(String[] args) {\n        System.out.println(\"LIST\");\n        /*\n         * List\n         */\n        Collections.addAll(lista, \"Martin\", \"Karl\");\n        ListIterator<String> listIterator = lista.listIterator();\n\n        listIterator.next(); //ListIterator\n        listIterator.add(\"Mike\"); //add()\n\n        Iterator<String> iterator = lista.iterator(); //Iterator\n        while (iterator.hasNext()) {\n            String elemento = iterator.next();\n            if (elemento.equals(\"Karl\")) {\n                iterator.remove(); //remove()\n            }\n        }\n//        lista.add(\"Martin\"); //inserción\n        lista.add(\"Castle\"); //inserción\n        lista.set(2, \"Pepe\"); //actualización\n        System.out.println(lista);\n        System.out.println(lista.getClass().getSimpleName()); //ArrayList\n\n        System.out.println(listaInmutable.getClass().getSimpleName()); //List12\n\n        listaMutable.add(\"Moy\"); //inserción\n        listaMutable.set(2, \"Xavi\"); //actualización\n        listaMutable.add(\"Kathe\"); //inserción\n        listaMutable.add(\"Martin\");\n        listaMutable.remove(\"Zuckerberg\"); //borrado\n        listaMutable.sort(String::compareTo);\n        System.out.println(listaMutable);\n        listaMutable.removeIf(s -> s.equals(\"Martin\"));\n        listaMutable.add(\"Franklin\");\n        Collections.sort(listaMutable);// Collections.sort()\n        listaMutable.add(null);\n\n        listaMutable.forEach(System.out::println);\n        System.out.println(listaMutable.reversed());\n        System.out.println(listaMutable.getClass().getSimpleName()); //ArrayList\n\n        /*\n         * Set\n         * No se puede Actualizar\n         * No se puede Ordenar\n         */\n        System.out.println(\"\\nSET\");\n        Collections.addAll(conjunto, \"Patrick\", \"Sam\", \"Jim\");\n        conjunto.add(\"Sam\"); //inserción\n        System.out.println(conjunto.getClass().getSimpleName());\n        System.out.println(conjunto);\n        conjunto.remove(\"Patrick\"); //borrado\n        System.out.println(conjunto.contains(\"Peter\"));\n        System.out.println(conjunto);\n        System.out.println(conjuntoInmutable.getClass().getSimpleName());\n        System.out.println(conjuntoInmutable.size());\n        conjuntoInmutable.forEach(System.out::println);\n        conjuntoMutable.add(\"Sam\");\n        System.out.println(conjuntoMutable.getClass().getSimpleName());\n        System.out.println(conjuntoMutable);\n\n        /*\n         * Map: clave-valor (key, value)\n         * Las llaves (keys) son únicas dentro del diccionario.\n         */\n        diccionario.put(\"clave1\", \"valor1\"); //inserción\n        diccionario.put(\"clave2\", \"valor2\");\n        diccionario.put(\"clave3\", \"valor3\");\n        diccionario.put(\"clave2\", \"nuevoValor2\"); // Sobrescribe \"valor2\"\n        Map<String, String> diccionarioOrdenado = diccionario.entrySet().stream()\n                .sorted(Map.Entry.comparingByValue())//ordenación byValue\n                .collect(Collectors.toMap(\n                        Map.Entry::getKey,\n                        Map.Entry::getValue,\n                        (e1, e2) -> e1,\n                        LinkedHashMap::new\n                ));\n        System.out.println(diccionarioOrdenado);\n        diccionario.remove(\"clave1\"); //borrado\n        diccionario.replace(\"clave3\", \"nuevoValor3\"); //actualización\n        System.out.println(diccionario.getClass().getSimpleName());\n        System.out.println(diccionario);\n        System.out.println(diccionario.keySet());\n        System.out.println(diccionario.get(\"clave2\"));  // Imprime \"nuevoValor2\"\n        System.out.println(diccionario.get(\"clave3\"));  // Imprime \"nuevoValor3\"\n\n        System.out.println(diccionarioSingleton.getClass().getSimpleName());\n        System.out.println(diccionarioSingleton);\n\n        System.out.println(diccionarioInmutable.getClass().getSimpleName());\n        diccionarioInmutable.forEach((m, n) -> System.out.println(\"Key es: \" + m.toUpperCase() + \", value es : \" + n));\n\n        //LinkedHashMap\n        linkedHashMap.put(\"uno\", 1);\n        linkedHashMap.put(\"tres\", 3);\n        linkedHashMap.put(\"dos\", 2);\n        System.out.println(linkedHashMap);\n\n        // Ordenar por claves\n        Map<String, Integer> mapaOrdenado = new TreeMap<>(linkedHashMap);\n\n        System.out.println(mapaOrdenado);\n\n        //TreeMap\n        treeMap.put(\"uno\", 1);\n        treeMap.put(\"tres\", 3);\n        treeMap.put(\"dos\", 2);\n\n        System.out.println(treeMap);\n\n        /*\n         * DIFICULTAD EXTRA\n         */\n        HashMap<String, Long> contactos = new HashMap<>();\n\n        //etiqueta de bucle\n        outerloop:\n        while (true) {\n            System.out.println(\"\"\"\n                    Bienvenido a la agente de contactos, tiene las siguientes opciones:\n                    1. Buscar un contacto\n                    2. Crear un contacto\n                    3. Actualizar un contacto\n                    4. Eliminar un contacto\n                    5. Salir\n                    \"\"\");\n\n            System.out.print(\"Elige una opción: \");\n            int option = 0;\n            try {\n                scan = new Scanner(System.in);\n                option = scan.nextInt();\n            } catch (InputMismatchException ignored) {\n            }\n            String name = \"\";\n\n            if (option > 0 && option < 5) {\n                name = getName();\n            }\n\n            switch (option) {\n                case 1 -> {\n                    Long number = contactos.get(name);\n                    getResult(number,\n                            \"El número de teléfono de \" + name + \" es \" + number + \"\\n\",\n                            \"El contacto \" + name + \" no existe en la agenda!\\n\");\n                }\n                case 2 -> {\n                    boolean flag = contactos.containsKey(name);\n                    contactos.put(name, getPhone());\n                    Long number = flag ? null : contactos.get(name);\n                    getResult(number,\n                            \"El contacto \" + name + \" ha sido registrado!\\n\",\n                            \"El contacto \" + name + \" ya se encuentra registrado. Si desea actualizar usa la opción 3!\\n\");\n\n                }\n                case 3 -> getResult(contactos.replace(name, getPhone()),\n                        \"El contacto \" + name + \" ha sido actualizado!\\n\",\n                        \"El contacto \" + name + \" no existe en la agenda!\\n\");\n                case 4 -> getResult(contactos.remove(name),\n                        \"El contacto \" + name + \" ha sido eliminado!\\n\",\n                        \"El contacto \" + name + \" no existe en la agenda!\\n\");\n                case 5 -> {\n                    System.out.println(\"Saliendo de la agenda!\");\n                    break outerloop;\n                }\n                default -> System.out.println(\"Opción no válida! Debe elegir una opción del 1 al 5.\\n\");\n            }\n        }\n    }\n\n    public static String getName() {\n        scan = new Scanner(System.in);\n        System.out.print(\"Indique su nombre: \");\n        return scan.next();\n    }\n\n    public static Long getPhone() {\n        Long numero = Long.MIN_VALUE;\n        while (true) {\n            try {\n                System.out.print(\"Indique su numero de teléfono: \");\n                scan = new Scanner(System.in);\n                numero = scan.nextLong();\n                if (numero.toString().length() > 11 && numero > 0L) {\n                    System.out.println(\"Debe introducir un número de teléfono con un máximo de 11 dígitos!\\n\");\n                } else {\n                    break;\n                }\n            } catch (InputMismatchException e) {\n                System.out.println(\"Número de teléfono no válido!\\n\");\n            }\n        }\n        return numero;\n    }\n\n    public static void getResult(Long result, String success) {\n        if (result != null) {\n            System.out.println(success);\n        } else {\n            System.out.println(\"Operación fallida\");\n        }\n    }\n\n    public static void getResult(Long result, String success, String failed) {\n        if (result != null) {\n            System.out.println(success);\n        } else {\n            System.out.println(failed);\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/mensius87.java",
    "content": "import java.util.*;\n\npublic class mensius87 {\n\n    public static void main(String[] args) {\n\n        // Listas: colección ordenada y mutable de elementos\n        System.out.println(\"::::::::::::::::::::::::::::::::::::: LISTAS :::::::::::::::::::::::::::::::::::::\");\n\n        List<String> listaColores = new ArrayList<>(Arrays.asList(\"rojo\", \"verde\", \"azul\", \"amarillo\", \"marrón\", \"naranja\", \"blanco\", \"negro\"));\n\n        System.out.println(\"Lista inicial:\");\n        System.out.println(listaColores);\n\n        // Inserción en listas\n        listaColores.add(\"violeta\");\n\n        System.out.println(\"Añadido color violeta:\");\n        System.out.println(listaColores);\n\n        // Actualización del nuevo color (cambio de violeta por fucsia)\n        listaColores.set(listaColores.size() - 1, \"fucsia\");\n\n        System.out.println(\"Cambiado color violeta por fucsia:\");\n        System.out.println(listaColores);\n\n        // Borrado del color\n        listaColores.remove(\"fucsia\");\n\n        System.out.println(\"Eliminado color fucsia:\");\n        System.out.println(listaColores);\n\n        // Ordenado alfabético\n        Collections.sort(listaColores);\n\n        System.out.println(\"Lista ordenada:\");\n        System.out.println(listaColores + \"\\n\");\n\n        // Tuplas: colección ordenada e inmutable\n        System.out.println(\"::::::::::::::::::::::::::::::::::::: TUPLAS :::::::::::::::::::::::::::::::::::::\");\n\n        List<String> tuplaPaises = Arrays.asList(\"España\", \"Portugal\", \"USA\", \"Alemania\", \"Suecia\");\n\n        System.out.println(\"Tupla inicial:\");\n        System.out.println(tuplaPaises);\n\n        // Ordenar tupla (indirectamente)\n        Collections.sort(tuplaPaises);\n\n        System.out.println(\"Tupla ordenada:\");\n        System.out.println(tuplaPaises + \"\\n\");\n\n        // Conjuntos: colección desordenada y mutable de elementos únicos\n        System.out.println(\"::::::::::::::::::::::::::::::::::::: CONJUNTOS :::::::::::::::::::::::::::::::::::::\");\n\n        Set<Integer> conjuntoNumeros = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5));\n\n        System.out.println(\"Conjunto inicial:\");\n        System.out.println(conjuntoNumeros);\n\n        // Añadir un elemento\n        conjuntoNumeros.add(10);\n        System.out.println(\"Conjunto con añadido:\");\n        System.out.println(conjuntoNumeros);\n\n        // Eliminar un elemento\n        conjuntoNumeros.remove(2);\n        System.out.println(\"Conjunto eliminando el nº2:\");\n        System.out.println(conjuntoNumeros + \"\\n\");\n\n        // Diccionarios: colección desordenada y mutable de pares clave-valor\n        System.out.println(\"::::::::::::::::::::::::::::::::::::: DICCIONARIOS :::::::::::::::::::::::::::::::::::::\");\n\n        Map<String, String> diccionarioSpaEng = new HashMap<>();\n        diccionarioSpaEng.put(\"manzana\", \"apple\");\n        diccionarioSpaEng.put(\"hola\", \"Hello\");\n        diccionarioSpaEng.put(\"silla\", \"chair\");\n\n        System.out.println(\"Diccionario original:\");\n        System.out.println(diccionarioSpaEng);\n\n        // Añadir un elemento\n        diccionarioSpaEng.put(\"mundo\", \"world\");\n        System.out.println(\"Diccionario con añadido:\");\n        System.out.println(diccionarioSpaEng);\n\n        // Modificar un elemento\n        diccionarioSpaEng.put(\"mundo\", \"world\");\n        System.out.println(\"Diccionario con corrección:\");\n        System.out.println(diccionarioSpaEng);\n\n        // Eliminar un elemento\n        diccionarioSpaEng.remove(\"silla\");\n        System.out.println(\"Diccionario con elemento eliminado:\");\n        System.out.println(diccionarioSpaEng);\n\n        // Ordenar diccionario\n        Map<String, String> diccionarioOrdenado = new TreeMap<>(diccionarioSpaEng);\n        System.out.println(\"Diccionario ordenado:\");\n        System.out.println(diccionarioOrdenado + \"\\n\");\n\n        System.out.println(\"::::::::::::::::::::::::::::::::::::: EXTRA :::::::::::::::::::::::::::::::::::::\");\n\n        // Agenda de contactos\n        Map<String, Integer> agenda = new HashMap<>();\n\n        Scanner scanner = new Scanner(System.in);\n        int opcionElegida = 0;\n\n        while (opcionElegida != 6) {\n\n            // Creación del menú y bucle\n            System.out.println(\"\"\"\n\n            ### Agenda Telefónica ###\n\n            ¿Qué deseas hacer?:\n\n            [1] - Buscar\n            [2] - Añadir\n            [3] - Modificar\n            [4] - Eliminar\n            [5] - Ver todos los contactos\n            [6] - Salir\n            \"\"\");\n\n            opcionElegida = scanner.nextInt();\n\n            switch (opcionElegida) {\n                case 1:\n                    buscarContacto(agenda);\n                    break;\n                case 2:\n                    anadirContacto(agenda, scanner);\n                    break;\n                case 3:\n                    modificarContacto(agenda, scanner);\n                    break;\n                case 4:\n                    eliminarContacto(agenda, scanner);\n                    break;\n                case 5:\n                    verContactos(agenda);\n                    break;\n                case 6:\n                    System.out.println(\"\\nGracias por utilizar la agenda. Hasta pronto!!!\");\n                    break;\n            }\n        }\n    }\n\n    private static void buscarContacto(Map<String, Integer> agenda) {\n        Scanner scanner = new Scanner(System.in);\n        System.out.print(\"Introduce el nombre del contacto a buscar: \");\n        String contactoABuscar = scanner.nextLine();\n\n        if (agenda.containsKey(contactoABuscar)) {\n            System.out.println(contactoABuscar + \": \" + agenda.get(contactoABuscar) + \"\\n\");\n        } else {\n            System.out.println(\"El contacto no existe, inténtalo de nuevo.\\n\");\n        }\n    }\n\n    private static void anadirContacto(Map<String, Integer> agenda, Scanner scanner) {\n        System.out.print(\"Introduce el nombre del contacto: \");\n        String nombre = scanner.next();\n\n        System.out.print(\"Introduce el número de 9 cifras: \");\n        int numero = scanner.nextInt();\n\n        while (String.valueOf(numero).length() != 9 || agenda.containsValue(numero)) {\n\n            if (String.valueOf(numero).length() != 9) {\n                System.out.print(\"Error. Tiene que tener 9 cifras: \");\n                numero = scanner.nextInt();\n            } else if (agenda.containsValue(numero)) {\n                System.out.print(\"Error. El número \" + numero + \" ya existe en la agenda: \");\n                numero = scanner.nextInt();\n            }\n        }\n\n        agenda.put(nombre, numero);\n        System.out.println(nombre + \" se ha agregado a la agenda correctamente.\\n\");\n    }\n\n    private static void modificarContacto(Map<String, Integer> agenda, Scanner scanner) {\n        System.out.print(\"Introduce el nombre del contacto a modificar: \");\n        String contactoAModificar = scanner.next();\n\n        if (!agenda.containsKey(contactoAModificar)) {\n            System.out.println(\"El nombre no existe en la agenda, inténtalo de nuevo.\\n\");\n            modificarContacto(agenda, scanner);\n        } else {\n            agenda.remove(contactoAModificar);\n\n            System.out.print(\"Introduce el nuevo nombre del contacto: \");\n            String nombre = scanner.next();\n\n            System.out.print(\"Introduce el nuevo número de 9 cifras: \");\n            int numero = scanner.nextInt();\n\n            while (String.valueOf(numero).length() != 9 || agenda.containsValue(numero)) {\n\n                if (String.valueOf(numero).length() != 9) {\n                    System.out.print(\"Error. Tiene que tener 9 cifras: \");\n                    numero = scanner.nextInt();\n                } else if (agenda.containsValue(numero)) {\n                    System.out.print(\"Error. El número \" + numero + \" ya existe en la agenda: \");\n                    numero = scanner.nextInt();\n                }\n            }\n\n            agenda.put(nombre, numero);\n            System.out.println(contactoAModificar + \" se ha modificado correctamente.\\n\");\n        }\n    }\n\n    private static void eliminarContacto(Map<String, Integer> agenda, Scanner scanner) {\n        System.out.print(\"Introduce el nombre del contacto a eliminar: \");\n        String contactoAEliminar = scanner.next();\n\n        if (agenda.containsKey(contactoAEliminar)) {\n            agenda.remove(contactoAEliminar);\n            System.out.println(\"El contacto \" + contactoAEliminar + \" se ha eliminado correctamente.\\n\");\n        } else {\n            System.out.println(\"El contacto no existe, inténtalo de nuevo.\\n\");\n        }\n    }\n\n    private static void verContactos(Map<String, Integer> agenda) {\n        Map<String, Integer> agendaOrdenada = new TreeMap<>(agenda);\n\n        for (Map.Entry<String, Integer> entry : agendaOrdenada.entrySet()) {\n            System.out.println(entry.getKey() + \": \" + entry.getValue());\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/miguelex.java",
    "content": "import java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\n\npublic class miguelex {\n\n    public static void main(String[] args) {\n        // Arrays\n\n        // Declaración e inicialización\n        int[] numbers = new int[5];\n\n        // Asignación\n        numbers[0] = 1;\n        numbers[1] = 2;\n        numbers[2] = 3;\n        numbers[3] = 4;\n\n        // Mostramos el array\n        for (int i = 0; i < numbers.length; i++) {\n            System.out.println(numbers[i]);\n        }\n\n        // Añadimos un nuevo elemento\n        numbers[4] = 0;\n        // Mostramos el array con el nuevo elemento\n        for (int i = 0; i < numbers.length; i++) {\n            System.out.println(numbers[i]);\n        }\n\n        // Editamos un elemento\n        numbers[4] = 5;\n\n        // Mostramos el array con el nuevo elemento\n        for (int i = 0; i < numbers.length; i++) {\n            System.out.println(numbers[i]);\n        }\n\n        // Mostramos el array con el nuevo elemento\n\n        for (int i = 0; i < numbers.length; i++) {\n            System.out.println(numbers[i]);\n        }\n\n        // ordenamos el array\n\n        Arrays.sort(numbers);\n\n        // Mostramos el array con el nuevo elemento\n\n        for (int i = 0; i < numbers.length; i++) {\n            System.out.println(numbers[i]);\n        }\n\n        // Listas\n\n        // Declaración e inicialización\n\n        List<Integer> numbers3 = new ArrayList<Integer>();\n\n        // Añadimos elementos\n\n        numbers3.add(1);\n        numbers3.add(2);\n        numbers3.add(3);\n        numbers3.add(4);\n\n        // Mostramos la lista\n\n        for (int i = 0; i < numbers3.size(); i++) {\n            System.out.println(numbers3.get(i));\n        }\n\n        // Añadimos un nuevo elemento\n\n        numbers3.add(0);\n\n        // Mostramos la lista con el nuevo elemento\n\n        for (int i = 0; i < numbers3.size(); i++) {\n            System.out.println(numbers3.get(i));\n        }\n\n        // Editamos un elemento\n\n        numbers3.set(4, 5);\n\n        // Mostramos la lista con el nuevo elemento\n\n        for (int i = 0; i < numbers3.size(); i++) {\n            System.out.println(numbers3.get(i));\n        }\n\n        // Borramos un elemento\n\n        numbers3.remove(3);\n\n        // Mapas\n\n        // Declaración e inicialización\n        HashMap<String, Integer> mapNumbers = new HashMap<>();\n        // Agregando valores al mapa\n        mapNumbers.put(\"one\", 1);\n        mapNumbers.put(\"two\", 2);\n        mapNumbers.put(\"three\", 3);\n        mapNumbers.put(\"four\", 4);\n\n        // Mostramos el mapa\n        for (Map.Entry<String, Integer> entry : mapNumbers.entrySet()) {\n            System.out.println(entry.getKey() + \" = \" + entry.getValue());\n        }\n\n        // Añadimos un nuevo elemento\n        mapNumbers.put(\"zero\", 0);\n        \n        // Recorremos el mapa para mostrarlo\n\n        for (Map.Entry<String, Integer> entry : mapNumbers.entrySet()) {\n            System.out.println(entry.getKey() + \" = \" + entry.getValue());\n        }\n\n        // Editamos un elemento\n\n        mapNumbers.put(\"four\", 5);\n\n         // Recorremos el mapa para mostrarlo\n\n         for (Map.Entry<String, Integer> entry : mapNumbers.entrySet()) {\n            System.out.println(entry.getKey() + \" = \" + entry.getValue());\n        }\n\n        // Borramos un elemento\n\n        Set<Integer> numbers2 = new HashSet<Integer>();\n        numbers2.add(5);\n\n        // Mostramos el set\n        for (Integer number : numbers2) {\n            System.out.println(number);\n        }\n\n\n\n\n\n\n\n\n\n\n\n\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/mtirador.java",
    "content": "import java.util.ArrayList;\nimport java.util.Comparator;\nimport java.util.Scanner;\n\npublic class mtirador {\n    public static void main(String[] args) {\n\n\n        /*Arrays _Arreglos */\n\n        int[]num={10,3,4,5,6};\n\n            //Para recorrer un array. Los arrays tiene un tamaño fijo\n            for(int i=0;i<num.length;i++){\n                System.out.println(num[i]);\n            }\n\n        /*ArrayList */\n\n        ArrayList<String>name =new ArrayList<String>();\n\n        /*Inserción */\n        name.add(\"Pablo\");\n        name.add(\"Pedro\");\n        name.add(\"María\");\n        name.add(\"Sonia\");\n        System.out.println(name);\n\n        /*Borrado */\n        name.remove(\"Pablo\");\n\n        /*Recorrer un ArrayList */\n        for(int i=0;i<name.size();i++){\n            System.out.println(name.get(i));\n        }\n\n        /* Actualización */\n        name.set(2, \"Marta\");\n        System.out.println(name);\n\n        /*Ordenación */\n        name.sort(Comparator.naturalOrder());\n    \n        /*Borrar todos los elementos del ArrayList */\n        name.clear();\n        System.out.println(name);\n\n\n\n    \n       \n        \n       /*Agenda */\n\n        ArrayList<Contacto>agenda=new ArrayList<>();\n        Scanner ent =new Scanner(System.in);\n        boolean flag=true;\n\n\n\n        System.out.println(\"Agenda(elija una opción)\\n1.Buscar\\n2.Insertar\\n3.Actualizar\\n4.Eliminar\\n5.Salir\");\n        String opcion=ent.nextLine();\n\n        while (flag) {\n          \n\n            switch (opcion) {\n                case \"1\":\n                    opcion = Buscar(agenda, ent);\n                    break;\n                case \"2\":\n                    opcion = Insertar(agenda, ent);\n                    break;\n                case \"3\":\n                    opcion = Actualizar(agenda, ent);\n                    break;\n                \n                case \"4\":\n    \n                    opcion = Eliminar(agenda, ent);\n                    break;\n                \n                case \"5\":\n                    flag = false;\n                    System.out.println(\"Hasta pronto.\");\n                    break;\n                default:\n                    System.out.println(\"Ingrese una opción válida.\");\n                    break;\n            }\n        }\n\n    }//fin main\n\n\n\n    private static String Eliminar(ArrayList<Contacto> agenda, Scanner ent) {\n        String opcion;\n        System.out.println(\"Ingrese el nombre del contacto a eliminar:\");\n        String nombreEliminar = ent.nextLine();\n        boolean eliminado = false;\n            \n        for (int i = 0; i < agenda.size(); i++) {\n            Contacto contacto = agenda.get(i);\n            if (contacto.getNombre().equalsIgnoreCase(nombreEliminar)) {\n                agenda.remove(i);\n                eliminado = true;\n                System.out.println(\"Contacto eliminado exitosamente.\");\n                break; \n            }\n        }\n            \n        if (!eliminado) {\n            System.out.println(\"No se encontró ningún contacto con ese nombre.\");\n        }\n\n        System.out.println(\"Agenda(elija una opción)\\n1.Buscar\\n2.Insertar\\n3.Actualizar\\n4.Eliminar\\n5.Salir\");\n        opcion=ent.nextLine();\n        return opcion;\n    }\n\n\n\n    private static String Actualizar(ArrayList<Contacto> agenda, Scanner ent) {\n        String opcion;\n        System.out.println(\"Ingrese el nombre del contacto a actualizar:\");\n        String nombreActualizar = ent.nextLine();\n        boolean actualizado = false;\n            \n        for (Contacto contacto : agenda) {\n            if (contacto.getNombre().equalsIgnoreCase(nombreActualizar)) {\n                System.out.println(\"Ingrese el nuevo número de teléfono para \" + nombreActualizar + \":\");\n                String nuevoTelefono = ent.nextLine();\n                contacto.settfno(nuevoTelefono);\n                actualizado = true;\n                System.out.println(\"Contacto actualizado exitosamente.\");\n                break; // Terminamos el bucle ya que encontramos y actualizamos el contacto.\n            }\n        }\n            \n        if (!actualizado) {\n            System.out.println(\"No se encontró ningún contacto con ese nombre.\");\n        }\n\n        System.out.println(\"Agenda(elija una opción)\\n1.Buscar\\n2.Insertar\\n3.Actualizar\\n4.Eliminar\\n5.Salir\");\n        opcion=ent.nextLine();\n        return opcion;\n    }\n\n\n\n    private static String Insertar(ArrayList<Contacto> agenda, Scanner ent) {\n        String nombre;\n        String tfno;\n        String opcion;\n        System.out.println(\"Ingrese el Nombre:\");\n        nombre = ent.nextLine();\n    \n        // Validación del número de teléfono\n        do {\n            System.out.println(\"Ingrese el teléfono (11 dígitos):\");\n            tfno = ent.nextLine();\n            if (tfno.length() != 11 || !tfno.matches(\"\\\\d+\")) {\n                System.out.println(\"El número de teléfono debe tener exactamente 11 dígitos.\");\n            }\n        } while (tfno.length() != 11 || !tfno.matches(\"\\\\d+\")); \n    \n        agenda.add(new Contacto(nombre, tfno));\n        System.out.println(\"Contacto añadido exitosamente.\");\n        System.out.println(\"Agenda(elija una opción)\\n1.Buscar\\n2.Insertar\\n3.Actualizar\\n4.Eliminar\\n5.Salir\");\n        opcion=ent.nextLine();\n        return opcion;\n    }\n    \n\n\n\n    private static String Buscar(ArrayList<Contacto> agenda, Scanner ent) {\n        String opcion;\n        System.out.println(\"Buscar por nombre:\");\n        String nombreBuscar = ent.nextLine();\n        boolean encontrado = false;\n        for (Contacto contacto : agenda) {\n            if (contacto.getNombre().equalsIgnoreCase(nombreBuscar)) {\n                System.out.println(\"Contacto encontrado:\");\n                System.out.println(contacto.toString());\n                encontrado = true;\n                \n                break;\n            }\n        }\n        if (!encontrado) {\n            System.out.println(\"No se encontró ningún contacto con ese nombre.\");\n            \n        }\n\n        System.out.println(\"Agenda(elija una opción)\\n1.Buscar\\n2.Insertar\\n3.Actualizar\\n4.Eliminar\\n5.Salir\");\n        opcion=ent.nextLine();\n        return opcion;\n    }\n\n    \n\n    public static class Contacto{\n        protected String nombre;\n        protected String tfno;\n\n        public Contacto(){\n            this.nombre=\"Anónimo\";\n            this.tfno=\"null\";\n        }\n\n        public Contacto(String nombre,String tfno){\n            this.nombre=nombre;\n            this.tfno=tfno;\n\n        }\n\n        public String getNombre(){\n            return nombre;\n        }\n        public void setnombre(String nombre){\n            this.nombre=nombre;\n        }\n\n        public String getTfno(){\n            return tfno;\n\n        }\n\n        public void settfno(String tfno){\n            this.tfno=tfno;\n        }\n\n        public String toString(){\n            return \"Nombre: \"+getNombre() +\"|| Telefono: \"+getTfno();\n            \n        }\n    }//fin contacto\n\n\n}//fin class\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/java/simonguzman.java",
    "content": "import java.lang.reflect.Array;\nimport java.util.*;\n\npublic class simonguzman {\n    public enum Dias{\n        Lunes, Martes, Miercoles, Jueves, Viernes, Sabado, Domingo\n    }\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n        //*********************Arrays*********************\n        int [] numbers = {1,2,3,4,5}; \n        int newLength = 8;\n        //update\n        numbers[0] = 13;\n        //sort\n        Arrays.sort(numbers);\n        //Insertion\n        int [] newArray = new int[newLength];\n        for (int i = 0; i < numbers.length; i++) {\n            newArray[i] = numbers[i];\n        }\n        numbers = newArray;\n        //Delete\n        for (int i = 0; i < numbers.length; i++) {\n            numbers[i] = 0;\n        }\n        //Show the array\n        System.out.println(Arrays.toString(numbers));\n        //Alternative to show the array\n        for (int i = 0; i < numbers.length; i++){\n            System.out.println(numbers[i]);\n        }\n\n        ////*********************Bidimensional Array****************\n        int [][] numId = new int[2][2];\n\n        //Insertion\n        numId[0][0] = 0;\n        numId[0][1] = 1;\n        numId[1][0] = 2;\n        numId[1][1] = 3;\n        //update\n        numId[0][1] = 4;\n        //Delete\n        numId[1][1] = 0;\n        //Alternative delele\n        for (int i = 0; i < numId.length; i++){\n            for (int j = 0; j < numId[i].length; j++){\n                numId[i][j] = 0;\n            }\n        }\n\n        //Show the bidimensional array\n        for (int i = 0; i < numId.length; i++){\n            for (int j = 0; j < numId[i].length; j++){\n                System.out.println(numId[i][j]);\n            }\n        }\n\n\n        //*********************Lists*********************\n        ArrayList<String> names = new ArrayList<>();\n        //Insertion\n        names.add(\"Simon\");\n        names.add(\"Julian\");\n        names.add(\"Camilo\");\n        names.add(\"Santiago\");\n        names.add(\"Carlos\");\n        //Delete    \n        names.clear();\n        //Update\n        names.set(2, \"Juliana\");\n        //Sort\n        Collections.sort(names);\n        //Show the list\n        System.out.println(names);\n\n        //LinkedList\n        LinkedList<String> lista = new LinkedList<>();\n\n        //Insertion\n        lista.add(\"Primer elemento\");\n        lista.add(\"Segundo elemento\");\n        lista.add(\"Tercer elemento\");\n        lista.add(\"Cuarto elemento\");\n        lista.add(\"Ultimo elemento\");\n        //Update\n        lista.set(4, \"Nuevo elemento\");\n        //Delete\n        lista.remove(3);\n        lista.remove(\"Tercer elemento\");\n        //Alternative of delete\n        //lista.removeFirst();\n        //lista.removeLast();\n        //lista.removeAll(lista);\n        //Sort\n        Collections.sort(lista);\n        //Show linked list\n        for(String item: lista){\n            System.out.println(item);\n        }\n\n        //*********************Maps*********************\n        HashMap<String, Integer> infoPersonal = new HashMap<>();\n        //Insertion\n        infoPersonal.put(\"Simon\", 20);\n        infoPersonal.put(\"Julian\", 22);\n        infoPersonal.put(\"Camilo\", 24);\n        infoPersonal.put(\"Santiago\", 21);\n        infoPersonal.put(\"Carlos\", 28);\n        //Uodate\n        infoPersonal.put(\"Juliana\", 22);\n        //Delete\n        infoPersonal.remove(\"Camilo\");\n        //Show the map\n        System.out.println(infoPersonal.keySet() + \" \" + infoPersonal.values());\n        //Alternative option\n        for(Map.Entry<String, Integer> entry : infoPersonal.entrySet()){\n            System.out.println(entry.getKey() + \" \" + entry.getValue());\n        }\n\n        //*********************Colections*********************\n        ArrayList<Integer> edades = new ArrayList<>();\n        //Insertion\n        edades.add(22);\n        edades.add(30);\n        edades.add(21);\n        edades.add(24);\n        //update\n        edades.set(1, 29);\n        //Delete\n        edades.remove(2);\n        //Sort\n        Collections.sort(edades);\n        //Show the colections\n        int age = edades.get(0);\n        System.out.println(age);\n        for (int i = 0; i < edades.size(); i++){\n            System.out.println(edades.get(i));\n        }\n\n        //*********************TreeSet*********************\n        TreeSet<Integer> set = new TreeSet<>();\n\n        //Insertion\n        set.add(10);\n        set.add(11);\n        set.add(12);\n        set.add(13);\n        set.add(14);\n        set.add(15);\n        //Delete\n        set.remove(13);\n        //Show the TreeSet\n        for(Integer i: set){\n            System.out.println(i);\n        }\n\n        //*********************HashSet*********************\n        HashSet<String> namesPersonal = new HashSet<>();\n        //Insertion\n        namesPersonal.add(\"Juan\");\n        namesPersonal.add(\"Maria\");\n        namesPersonal.add(\"Adriano\");\n        //Update\n        names.remove(\"Maria\");\n        //Show HashSet\n        for(String name : names){\n            System.out.println(name);\n        }\n\n        //*********************Enum*********************\n        Dias dia = Dias.Lunes;\n\n        switch (dia) {\n            case Lunes:\n                System.out.println(\"Es el dia lunes\");\n                break;\n            case Martes:\n                System.out.println(\"Es el dia martes\");\n                break;\n            case Miercoles:\n                System.out.println(\"Es el dia miercoles\");\n                break;\n            case Jueves:\n                System.out.println(\"Es el dia jueves\");\n                break;\n            case Viernes:\n                System.out.println(\"Es el dia viernes\");\n                break;\n            case Sabado:\n                System.out.println(\"Es el dia sabado\");\n                break;\n            case Domingo:\n                System.out.println(\"Es el dia domingo\");\n                break;\n            default:\n                System.out.println(\"El dia no existe\");\n                break;\n        }\n        //*Ejecucion del ejercicio adicional */\n        agendaContactos();\n    }\n    //******************************Ejercicio adicional******************************/\n    public static void agendaContactos(){\n        HashMap<String, Long> contactos = new HashMap();\n        Scanner scanner = new Scanner(System.in);\n        int opcion;\n        do{\n            menuPresentacion();\n            opcion = scanner.nextInt();\n            opcionMenu(opcion, contactos, scanner);\n        }while( opcion !=5 );\n        scanner.close();\n    }\n\n    public static void presentacion(){\n        System.out.println(\"*******************************\");\n        System.out.println(\"Bienvenido al sistema\");\n        System.out.println(\"*******************************\");\n    }\n\n    public static void menuPresentacion(){\n        presentacion();\n        System.out.println(\"1. Busqueda\");\n        System.out.println(\"2. Insercion\");\n        System.out.println(\"3. Actualizacion\");\n        System.out.println(\"4. Eliminar\");\n        System.out.println(\"5. Salir\");\n        System.out.println(\"Ingrese una opcion: \");\n    }\n\n    public static void opcionMenu(int opcion, HashMap<String,Long> contactos ,Scanner scanner){\n        switch (opcion) {\n            case 1:\n                    buscarContacto(contactos, scanner);\n                break;\n            case 2:\n                    insertarContacto(contactos, scanner);\n                break;\n            case 3:\n                    actualizarContacto(contactos, scanner);\n                break;\n            case 4:\n                    eliminarContacto(contactos, scanner);\n                break;\n            case 5:\n                    System.out.println(\"Saliendo del programa....\");\n                break;\n        \n            default:\n                System.out.println(\"ERROR: Ingrese una opcion validad\");\n                break;\n        }\n    }\n\n    public static void insertarContacto(HashMap<String, Long> contactos ,Scanner scanner){\n        System.out.println(\"Ingrese el nombre del contacto: \");\n        String name = scanner.next();\n        Long numPhone = validInput(scanner, \"Ingrese el numero de telefono:\");\n        if(validacionCompleta(numPhone)){\n            contactos.put(name, numPhone);\n            System.out.println(\"Contacto ingresado con exito\");\n        }else{\n            System.out.println(\"ERROR: El número de teléfono debe ser numérico y tener un máximo de 11 dígitos.\");\n        }\n    }\n\n    public static void buscarContacto(HashMap<String, Long> contactos, Scanner scanner){\n        if(validarVacios(contactos)){\n            System.out.println(\"Ingrese el nombre del contacto: \");\n            String nombre = scanner.next();\n            Long telefono = contactos.get(nombre);\n            if(telefono != null){\n                System.out.println(\"Nombre del contacto: \"+ nombre + \" Telefono : \"+ telefono); \n            }else{\n                System.out.println(\"El contacto no existe\");\n            }\n        }\n    }\n\n    public static void actualizarContacto(HashMap<String,Long> contactos, Scanner scanner){\n        if(validarVacios(contactos)){\n            System.out.println(\"Ingrese el nombre del contacto: \");\n            String nombre = scanner.next();\n            if(contactos.containsKey(nombre)){\n                Long telefono = validInput(scanner, \"Ingrese el numero de telefono nuevo: \");\n                if(validacionCompleta(telefono)){\n                    contactos.put(nombre, telefono);\n                    System.out.println(\"Contacto actualizado con exito\");\n                }else{\n                    System.out.println(\"ERROR: El número de teléfono debe ser numérico y tener un máximo de 11 dígitos.\");\n                }\n            }else{\n                System.out.println(\"El contacto no fue encontrado o no existe\");\n            }\n        }\n    }\n\n    public static void eliminarContacto(HashMap<String,Long> contactos, Scanner scanner){\n        if(validarVacios(contactos)){\n            System.out.println(\"Ingrese el nombre del contacto: \");\n            String nombre = scanner.next();\n            if(contactos.remove(nombre)!=null) {\n                System.out.println(\"Contacto eliminado con exito\");\n            }else{\n                System.out.println(\"El contacto no ha sido encontrado\");\n            }\n        }\n    }\n\n    public static boolean validarTelefono(Long numPhone){\n        String numPhoneString = String.valueOf(numPhone);\n        if(numPhoneString.length() > 11){\n            return false;\n        }\n        return true;\n    }\n\n\n    public static boolean validarNoNumericos(Long numPhone){\n        String numPhoneString = String.valueOf(numPhone);\n        for (int i = 0; i < numPhoneString.length(); i++){\n            char c = numPhoneString.charAt(i);\n            if(!Character.isDigit(c)){\n                return false;\n            }\n        }\n        return true;        \n    }\n\n    public static boolean validacionCompleta(Long numPhone){\n        boolean valPhone = validarTelefono(numPhone);\n        boolean valNotNumeric = validarNoNumericos(numPhone);\n\n        return valPhone && valNotNumeric;\n    }\n\n    public static boolean validarVacios(HashMap<String, Long> contactos){\n        if(contactos.isEmpty()){\n            System.out.println(\"No hay contactos\");\n            return false;\n        }else{\n            return true;\n        }\n    }\n\n\n    public static Long validInput(Scanner scanner, String input){\n        boolean isValidInput = false;\n        Long inputNumber = null;\n        while (!isValidInput) {\n            try {\n                System.out.println(input);\n                inputNumber = scanner.nextLong();\n                isValidInput = true;\n            } catch (InputMismatchException e) {\n                System.out.println(\"Error: el numero de telefono solo puede tener digitos\");\n                scanner.next();\n            }\n        }\n        return inputNumber;\n    }\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/1Nonamed.js",
    "content": "// DATA STRUCTURES\n\nconsole.log(\"----- ARRAYS -----\");\nconst fruitsArr = [\"Banana\", \"Pear\", \"Apple\", \"Apricot\", \"Banana\"];\nconsole.log(\"Fruits:\", fruitsArr, \"\\n\");\n\nconsole.log(\"Array length:\", fruitsArr.length);\n\n// Acceder a las posiciones de un Array\nconsole.log(\"fruitsArr[2] =>\", fruitsArr[2]);\nconsole.log(\"fruitsArr[3] =>\", fruitsArr[3]);\n\nconsole.log(\"\\nMétodos de los Arrays:\");\n\n// Push -- Añadir (Modifica el array original)\nfruitsArr.push([\"Pear\", \"Apple\"]);\nconsole.log(\"- Push =>\", fruitsArr);\n\n// Unshift\nfruitsArr.unshift(\"Watermelon\");\nconsole.log(\"- Unshift =>\", fruitsArr);\n\n// Filter\nconst bananasArr = fruitsArr.filter((fruit) => fruit === \"Banana\");\nconsole.log(\"- Filter =>\", bananasArr);\n\n// Find\nconst foundFruit = fruitsArr.find((fruit) => fruit.startsWith(\"Apr\"));\nconsole.log(\"- Find =>\", foundFruit);\n\n// Sort\nconst numbers = [2, 3, 10, 2, 4];\nconsole.log(\n  \"- Sort =>\",\n  numbers.sort((a, b) => a - b)\n);\n\n// Splice\nconsole.log(\"- Splice =>\", fruitsArr.splice(1, fruitsArr.length));\n\n// Reverse\nconsole.log(\"- Reverse =>\", fruitsArr.reverse());\n\n// Flat\nconsole.log(\"- Flat =>\", fruitsArr.flat());\n\nconsole.log(\"----- OBJECTS -----\");\nconst person = {\n  id: 15,\n  name: \"Marcos\",\n  age: 20,\n  knowledge: {\n    javascript: false,\n    go: false,\n  },\n};\nconsole.log(\"Person: \", person);\n\nperson.name = \"Lucas\";\nperson.knowledge = { ...person.knowledge, python: true };\n\nconsole.log(\"\\nModified Person Obj: \", person);\n\nconsole.log(\"----- MAPS -----\");\n// The Map object holds key-value pairs and remembers the original insertion order of the keys. Any value (both objects and primitive values) may be used as either a key or a value.\n\nconst people = new Map();\npeople.set(\"Poncho\", { phone: \"2347651029\" });\npeople.set(\"Vicky\", { phone: \"2347654449\", address: \"9 Fow Ave\" });\n\nconsole.log(people);\n\n// Extra Challenge\n// Agenda de Contactos\nimport * as readline from \"node:readline/promises\";\nimport { stdin as input, stdout as output } from \"node:process\";\nconst rl = readline.createInterface({ input, output });\n\nconst contacts = [\n  { id: 1, name: \"Juan\", phone: 1234560987 },\n  { id: 2, name: \"Juan\", phone: 1222543388 },\n  { id: 3, name: \"Pedro\", phone: 1255566427 },\n];\n\nconst ops = [\n  { id: 1, name: \"Search\" },\n  { id: 2, name: \"Add\" },\n  { id: 3, name: \"Update\" },\n  { id: 4, name: \"Delete\" },\n];\n\nconst showAgenda = (arr) => {\n  console.log(`\n    *****************************************************\n    *                    CONTACT LIST                   *\n    *****************************************************`);\n  arr.map((contact) =>\n    console.log(`    * Name: ${contact.name}\n    *   Phone: ${contact.phone}\n    -----------------------------------------------------`)\n  );\n  isExit();\n};\n\nconst isExit = async (op) => {\n  const answer = await rl.question(`\n    *****************************************************\n    *                                                   *\n    * Please select one of the following options:       *\n    *                                                   *\n    * 1: Go back and try again                          *\n    * 2: Go to the Main Menu                            *\n    * 3: Show contact list                              *\n    * 0: Exit                                           *\n    *                                                   *\n    *****************************************************\n    * `);\n\n  if (+answer === 1) return op();\n  if (+answer === 2) return agenda();\n  if (+answer === 3) return showAgenda(contacts);\n\n  rl.close();\n};\n\nconst searchContact = async () => {\n  console.log(`\n    *****************************************************\n    *                  SEARCH CONTACT                   *\n    *****************************************************`);\n  const contactInput =\n    await rl.question(`    * Contact name?                                     *\n    * `);\n\n  const contactsFound = contacts.filter((contact) => {\n    return contact.name.toLowerCase() === contactInput.toLowerCase();\n  });\n\n  if (contactsFound.length === 0) {\n    console.log(`    *                                                   *\n    * Contact not found.                                *`);\n    return isExit(searchContact);\n  }\n\n  showAgenda(contactsFound);\n  isExit(searchContact);\n};\n\nconst addContact = async () => {\n  console.log(`\n    *****************************************************\n    *                     ADD CONTACT                   *\n    *****************************************************`);\n  const contactInputName =\n    await rl.question(`    * Contact name?                                     *\n    * `);\n  const contactInputPhone =\n    await rl.question(`    *                                                   *\n    * Phone number?                                     *\n    * `);\n\n  const nameHasNumbers = /\\d/.test(contactInputName);\n  const phoneHasLetters = /[a-zA-Z]/g.test(contactInputPhone);\n\n  if (contactInputName === \"\" || nameHasNumbers) {\n    console.log(`\n    * Contact name is not valid.                        *\n    * Only letters allowed.                             *`);\n    return isExit(addContact);\n  }\n\n  if (\n    contactInputPhone === \"\" ||\n    phoneHasLetters ||\n    contactInputPhone.length > 10\n  ) {\n    console.log(`\n    * Contact phone number is not valid.                *\n    * Only numbers allowed, has to be 10 digits         *`);\n    return isExit(addContact);\n  }\n\n  const newContact = {\n    id: contacts.length + 1,\n    name: contactInputName,\n    phone: +contactInputPhone,\n  };\n\n  contacts.push(newContact);\n  console.log(`    *\n    * The contact ${newContact.name} has been added sucessfully     *`);\n  isExit(addContact);\n};\n\nconst updateContact = async () => {\n  console.log(`\n    *****************************************************\n    *                   UPDATE CONTACT                  *\n    *****************************************************`);\n  const contactInputData =\n    await rl.question(`    * Contact to update? Type name or phone number      *\n    * `);\n\n  const foundContactIndex = contacts.findIndex(\n    (contact) =>\n      contact.name.toLowerCase() === contactInputData.toLowerCase() ||\n      contact.phone === +contactInputData\n  );\n\n  if (foundContactIndex === -1) {\n    console.log(`    * Contact ${contactInputData} not found`);\n    return isExit(updateContact);\n  }\n\n  const contact = contacts[foundContactIndex];\n  console.log(`    *                                                   *   \n    * Updating contact ${contact.name}\n    *                                                   *\n    * Name: ${contact.name}\n    *   Phone: ${contact.phone}\n    -----------------------------------------------------`);\n\n  const option =\n    await rl.question(`    *                                                   *\n    * What would you like to update?                    *\n    * 1: Name                                           *\n    * 2: Phone                                          *\n    * `);\n\n  if (+option !== 1 && +option !== 2) {\n    console.log(`    *                                                   *\n    * Please select a valid option                      *`);\n  }\n\n  if (+option === 1) {\n    const newContactName =\n      await rl.question(`    *                                                   *\n    * Type the new name for ${contact.name} \n    * `);\n    console.log(`    *                                                   *\n    * Contact name was successfully updated to ${newContactName}`);\n    contact.name = newContactName;\n  }\n\n  if (+option === 2) {\n    const newContactPhone =\n      await rl.question(`    *                                                   *\n    * Type the new phone number for ${contact.name} \n    * `);\n\n    const phoneHasLetters = /[a-zA-Z]/g.test(newContactPhone);\n    if (phoneHasLetters) {\n      console.log(`    *                                                   * \n    * Phone number must be a number, please try again   *`);\n      return isExit(updateContact);\n    }\n\n    console.log(`    *                                                   *\n    * Contact phone number was successfully updated to ${newContactPhone}`);\n    contact.phone = newContactPhone;\n  }\n\n  isExit(updateContact);\n};\n\nconst deleteContact = async () => {\n  console.log(`\n    *****************************************************\n    *                   UPDATE CONTACT                  *\n    *****************************************************`);\n  const contactInputData =\n    await rl.question(`    * Contact to delete? Type name or phone number      *\n    * `);\n\n  const foundContactIndex = contacts.findIndex(\n    (contact) =>\n      contact.name.toLowerCase() === contactInputData.toLowerCase() ||\n      contact.phone === +contactInputData\n  );\n\n  if (foundContactIndex === -1) {\n    console.log(`    * Contact ${contactInputData} not found`);\n    return isExit(updateContact);\n  }\n\n  const contact = contacts[foundContactIndex];\n  console.log(`    *                                                   *   \n    * Deleting contact ${contact.name}\n    *                                                   *\n    * Name: ${contact.name}\n    *   Phone: ${contact.phone}\n    -----------------------------------------------------`);\n  console.log(`\n    * Contact ${contact.name} was successfully deleted`);\n  contacts.splice(foundContactIndex, 1);\n\n  isExit(deleteContact);\n};\n\nasync function agenda() {\n  const op = await rl.question(\n    `\n    *****************************************************\n    *                        AGENDA                     *\n    *****************************************************\n    *                                                   * \n    * What do you want to do today?                     *\n    *                                                   *\n    * 1: Search Contact                                 *\n    * 2: Add Contact                                    *\n    * 3: Update Contact                                 *\n    * 4: Delete Contact                                 *\n    * 5: Show contact list                              *\n    *                                                   *\n    * 0: Exit program                                   *\n    *                                                   *\n    *****************************************************\n    \n    * Insert the operation number or 0 to exit: `\n  );\n  switch (+op) {\n    case 1:\n      searchContact();\n      break;\n    case 2:\n      addContact();\n      break;\n    case 3:\n      updateContact();\n      break;\n    case 4:\n      deleteContact();\n      break;\n    case 5:\n      showAgenda(contacts);\n      break;\n    case 0:\n      rl.close();\n      break;\n    default:\n      console.log(\"Operation not valid\");\n      break;\n  }\n}\n\nagenda();\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/7R0N1X.js",
    "content": "// Array\nlet numbers = [5, 0, 1]\n\nnumbers.push(2) // Añadir un elemento al final\n\nnumbers.unshift(-1) // Añadir un elemento al principio\n\nnumbers.pop() // Eliminar el último elemento\n\nnumbers.shift() // Eliminar el primer elemento\n\nnumbers[1] = 2 // Actualizar un elemento\n\nnumbers.sort() // Ordenación\n\n// console.log(numbers)\n\n\n\n// Set\nlet mySet = new Set(numbers)\n\nmySet.add(4) // Añadir un elemento\n\nmySet.delete(5) // Elimina un elemento en específico\n\n// console.log(mySet.has(5)) // Verifica si un elemento existe en el set\n\n// console.log(mySet.size) // Devuelve el tamaño del set\n\nmySet.clear() // Elimina todos los elementos del set\n\n// Los sets no soportan ordenamiento\n\n// console.log(mySet)\n\n\n\n// Objetos\nlet myCar = new Object()\n\nmyCar.make = \"Ford\"; // Añadir un elemento\nmyCar.model = \"Mustang\";\nmyCar.year = 2024;\n\ndelete myCar[\"year\"] // Elimina un elemeneto en específico\n\nmyCar[\"model\"] = \"Ranger\" // Actualización\n\n// Los objetos no soportan ordenamiento\n\n// console.log(myCar)\n\n\n\n// Map\nlet myMap = new Map()\n\nmyMap.set(\"Name\", \"7R0N1X\") // Añadir un elemento\nmyMap.set(\"Age\", 24)\nmyMap.set(\"Country\", \"Colombia\")\n\nmyMap.delete(\"Age\") // Eliminar\n\nmyMap.set(\"Country\", \"Ecuador\") // Actualizar\n\n// Los maps no soportan ordenamiento\n\n// console.log(myMap)\n\n\n\n// Dificultad extra\nlet readline = require('readline')\nlet rl = readline.createInterface({ input: process.stdin, output: process.stdout })\nlet opc = 0\nlet contacts = []\n\nconst App = () => {\n  console.log(`\n    **************************************************\n    *                                                *\n    *              GESTIÓN DE CONTACTOS              *\n    *                                                *\n    **************************************************\n    *                                                *\n    *    1. Buscar contacto                          *\n    *    2. Ingresar nuevo contacto                  *\n    *    3. Actualizar contacto                      *\n    *    4. Eliminar contacto                        *\n    *    5. Salir                                    *\n    *                                                *\n    **************************************************\n    `);\n\n  rl.question('Opción: ', (answer) => {\n    opc = parseInt(answer)\n\n    switch (opc) {\n      case 1:\n        if (contacts.length === 0) {\n          alerta('No hay contactos')\n          App()\n        } else {\n          rl.question('Nombre: ', (nombre) => {\n            filtrar(nombre)\n            App()\n          })\n        }\n        break\n      case 2:\n        rl.question('Nombre: ', (nombre) => {\n          if (existe(nombre)) {\n            alerta('Error: Nombre ya existe')\n            App()\n          } else {\n            rl.question('Numero: ', (numero) => {\n              if (/^\\d{1,11}$/.test(numero) && Number(numero)) {\n                let contact = { nombre, numero }\n                ingresar(contact)\n                alerta('Contacto ingresado correctamente')\n                App()\n              } else {\n                alerta('Error: Número no válido')\n                App()\n              }\n            })\n          }\n        })\n        break\n      case 3:\n        rl.question('Nombre: ', (nombre) => {\n          if (existe(nombre)) {\n            rl.question('Numero: ', (numero) => {\n              let contact = { nombre, numero }\n              actualizar(contact)\n              alerta('Contacto actualizado correctamente')\n              App()\n            })\n          } else {\n            alerta('Error: Nombre no existe')\n            App()\n          }\n        })\n        break\n      case 4:\n        rl.question('Nombre: ', (nombre) => {\n          if (existe(nombre)) {\n            eliminar(nombre)\n            alerta('Contacto eliminado correctamente')\n            App()\n          } else {\n            alerta('Error: El contacto no existe')\n            App()\n          }\n\n        })\n        break\n      case 5:\n        rl.close()\n        break\n      default:\n        alerta('Error: Opción desconocida')\n        App()\n    }\n  })\n\n  function filtrar(nombre) {\n    existe(nombre) ? mostrar(contacts.filter((contact) => contact.nombre === nombre)) : alerta('Error: El contacto no existe')\n  }\n\n  function existe(nombre) {\n    return contacts.find((contact) => contact.nombre === nombre)\n  }\n\n  function ingresar(contact) {\n    contacts = [...contacts, contact]\n  }\n\n  function actualizar(contact) {\n    let { nombre, numero } = contact\n    contacts.map((contact) => {\n      if (contact.nombre === nombre) {\n        contact.numero = numero\n      }\n    })\n  }\n\n  function eliminar(nombre) {\n    contacts = contacts.filter((contact) => contact.nombre !== nombre)\n  }\n\n  function mostrar(contacts) {\n    console.log(`\n    **************************************************\n    *                                                *\n    *                LISTA DE CONTACTOS              *\n    *                                                *\n    **************************************************\n    `);\n    contacts.map((contact) => {\n      let { nombre, numero } = contact\n      console.log(`\n    **************************************************                     \n        Nombre: ${nombre}                           \n        Teléfono: ${numero}                         \n    **************************************************\n    `)\n    })\n  }\n\n  function alerta(mensaje) {\n    console.log(`\n    **************************************************\n        ${mensaje}\n    **************************************************\n    `)\n  }\n\n}\n\nApp()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/AChapeton.js",
    "content": "// **** TIPOS DE ESTRUCTURAS ****\n// ** ARRAYS **\n// Tiene dos formas distintas de tiparlo pero ambas dan el mismo resultado\n// Se pueden combinar los tipos de datos que se permiten almacenar o incluso personalizarlos, a estos elementos se les llama Tuplas\nvar numbers = [2, 4, 6, 8];\nvar letters = ['p', 'b', 'd', 'q'];\nvar combined = ['abc', true, 'def', false]; //No se permite otro tipo de dato que no sea String o Boolean\nvar users = [\n    {\n        id: 1,\n        name: 'Andres',\n        subscribed: true\n    },\n    {\n        id: 2,\n        name: 'Brais',\n        subscribed: false\n    },\n    {\n        id: 3,\n        name: 'Chape',\n        subscribed: false\n    },\n    {\n        id: 4,\n        name: 'Jesus',\n        subscribed: true\n    },\n    {\n        id: 5,\n        name: 'Midudev',\n        subscribed: true\n    },\n    {\n        id: 6,\n        name: 'Teffcode',\n        subscribed: false\n    }\n];\nconsole.log('users', users);\n\n\n// Operaciones en Arrays\n\n//Push - Agregar elementos al final\nvar pushUser = {\n    id: 11,\n    name: 'Moure',\n    subscribed: true\n};\nusers.push(pushUser);\nconsole.log('push', users);\n\n//Unshift - Agregar elementos al inicio\nvar unshiftUser = {\n    id: 0,\n    name: 'Mouredev',\n    subscribed: false\n};\nusers.unshift(unshiftUser);\nconsole.log('unshift', users);\n\n//Splice - Agregar elementos en cualquier posicion\n//El primer parametro es para indicar en que posicion agregarlo\n//El segundo parametro es para indicar cuantos elementos se reemplazarian (0 es ningun elemento)\n//El tercer parametro es el elemento a agregar\nvar spliceUser = {\n    id: 12,\n    name: 'Chape',\n    subscribed: false\n};\nusers.splice(2, 0, spliceUser);\nconsole.log('splice', users);\n\n//Pop - Eliminar el ultimo elemento\nusers.pop();\nconsole.log('pop', users);\n\n//Shift - Eliminar el primer elemento\nusers.shift();\nconsole.log('shift', users);\n\n//Splice - Eliminar un elemento en cualquier posicion\n//El primer parametro es la posicion del elemento\n//El segundo parametro es la cantidad de elementos a eliminar desde la posiocion indicada\nusers.splice(2, 1);\nconsole.log('splice', users);\n\n//Filter - Crea un nuevo array con los elementos que cumplan el criterio\nvar fiteredUsers = users.filter(function (user) { return user.id < 10; });\nconsole.log('filter', fiteredUsers);\n\n//Sort - Metodo para ordenar datos\nvar unorderedArray = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5];\n// Ordenar el array\nunorderedArray.sort(function (a, b) { return a - b; });\nconsole.log('sort', unorderedArray);\n\n\n// ** SETS **\nvar mySet = new Set();\n//Add - Agregar un valor\nmySet.add(1);\nmySet.add(2);\nmySet.add(3);\n// mySet.add('string') - No se permite porque el Set fue tipado de solo numeros\nconsole.log('add', mySet);\n\n//Has - Verificar si un valor existe dentro del Set\nmySet.has(1); //true\nmySet.has(3); //false\n//Delete - Elimina un valor\nmySet.delete(1);\nconsole.log('delete', mySet);\n\n//Size - Devuelve el tama;o del set\nconsole.log('size', mySet.size);\n\n//Clear - Eliminar todos los elementos\nmySet.clear();\nconsole.log('clear', mySet);\n\nvar contacts = [];\nvar agregarContacto = function () {\n    var newName = null;\n    var newPhone = null;\n    do {\n        newName = prompt('Nombre: ');\n        if (!newName) {\n            console.log('Por favor, ingresa un nombre válido.');\n        }\n    } while (!newName);\n    do {\n        newPhone = prompt('Telefono: ');\n        if (!newPhone) {\n            console.log('Por favor, ingresa un número de teléfono válido.');\n        }\n    } while (!newPhone);\n    var newContact = {\n        nombre: newName,\n        telefono: parseInt(newPhone)\n    };\n    contacts.push(newContact);\n};\nvar buscarContacto = function () {\n    var searchedName = null;\n    do {\n        searchedName = prompt('Buscar por nombre: ');\n    } while (!searchedName);\n    var searchedResult = contacts.find(function (contact) { return contact.nombre.toLowerCase() === searchedName.toLowerCase(); });\n    if (searchedResult === undefined) {\n        alert(searchedName + ' no existe');\n    }\n    else {\n        alert(JSON.stringify(searchedResult, null, 2));\n    }\n};\nvar actualizarContacto = function () {\n    var _a, _b;\n    var searchedName = null;\n    do {\n        searchedName = prompt('Buscar por nombre: ');\n    } while (!searchedName);\n    var searchedResult = contacts.findIndex(function (contact) { return contact.nombre.toLowerCase() === searchedName.toLowerCase(); });\n    if (searchedResult === undefined) {\n        alert(searchedName + ' no existe');\n    }\n    else {\n        var newName = null;\n        var newPhone = null;\n        do {\n            newName = prompt('Nuevo nombre', ((_a = contacts[searchedResult]) === null || _a === void 0 ? void 0 : _a.nombre) || '');\n            contacts[searchedResult].nombre = newName;\n        } while (newName === null);\n        do {\n            newPhone = prompt('Nuevo telefono', ((_b = contacts[searchedResult]) === null || _b === void 0 ? void 0 : _b.telefono.toString()) || '');\n            contacts[searchedResult].telefono = parseInt(newPhone);\n        } while (newPhone === null);\n        alert(searchedName + ' fue actualizado a ' + newName);\n    }\n};\nvar eliminarContacto = function () {\n    var searchedName = null;\n    do {\n        searchedName = prompt('Nombre de contacto a eliminar: ');\n    } while (!searchedName);\n    var searchedResult = contacts.findIndex(function (contact) { return contact.nombre.toLowerCase() === searchedName.toLowerCase(); });\n    if (searchedResult === undefined) {\n        alert(searchedName + ' no existe');\n    }\n    else {\n        if (searchedResult >= 0 && searchedResult < contacts.length) {\n            contacts.splice(searchedResult, 1);\n            alert(searchedName + ' fue eliminado');\n        }\n        else {\n            console.log('Índice inválido');\n        }\n    }\n};\nvar listarContactos = function () {\n    var contactsString = JSON.stringify(contacts, null, 2);\n    alert(contactsString);\n};\nvar agendaApp = function () {\n    var option = '';\n    var menu = 'MENU: \\n 1. Agregar nuevo contacto \\n 2. Buscar contacto \\n 3. Actualizar contact \\n 4. Eliminar un contacto \\n 5. Listar todos los contactos \\n 6. Salir';\n    while (option !== '6') {\n        option = prompt(menu);\n        switch (option) {\n            case '1':\n                agregarContacto();\n                break;\n            case '2':\n                buscarContacto();\n                break;\n            case '3':\n                actualizarContacto();\n                break;\n            case '4':\n                eliminarContacto();\n                break;\n            case '5':\n                listarContactos();\n                break;\n            case '6':\n                break;\n            default:\n                console.log('Opcion no valida. Intentar de nuevo.');\n                break;\n        }\n    }\n};\nagendaApp();\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/Airesesteban.js",
    "content": "// Arrays\nlet numbers = [1,2,3,4,5]\nconsole.log(\"Array\", numbers)\n\n// Operaciones con arrays\n\n// Inserción\nnumbers.push(6)\nconsole.log(\"Array despues de agregar al final un valor\",numbers)\n\n// Borrado\nnumbers.splice(2,1)\nconsole.log(\"Array despues de eliminar un valor\",numbers)\n\n// Actualización\nnumbers[1]= 10\nconsole.log(\"Array despues de actualizar un valor\",numbers)\n\n// Orden\nnumbers.sort()\nconsole.log(\"Array despues de ordenar\",numbers)\n\n\n// Objetos\n\nlet objeto = {nombre: \"Esteban\", edad: 38}\nconsole.log(\"Objeto\",objeto)\n\n// Operaciones con objetos\n\n// Inserción\nobjeto.direccion = \" Calle 123\"\nconsole.log(\"Objeto despues de inserción:\",objeto)\n\n// Borrado\ndelete objeto.edad\nconsole.log(\"Objeto despues de borrado:\",objeto)\n\n// Actualización\nobjeto.nombre = \"Pedro\"\nconsole.log(\"Objeto despues de actualizacion:\",objeto)\n\n// Mapas\n\nlet mapa = new Map()\nmapa.set(\"clave1\", \"valor1\")\nmapa.set(\"clave2\", \"valor2\")\nconsole.log('Mapa:', mapa)\n\n// Operaciones con mapas\n\n// Inserción\nmapa.set(\"clave3\",\"valor3\")\nconsole.log('Mapa después de inserción:', mapa)\n\n// Borrado\nmapa.delete(\"clave2\")\nconsole.log('Mapa después de borrado:', mapa)\n\n// Actualización\nmapa.set(\"clave1\",\"NewValor1\")\nconsole.log('Mapa después de actualizacion:', mapa)\n\n// Conjuntos\nlet conjunto = new Set([1, 2, 3, 4, 5])\nconsole.log('Conjunto:', conjunto)\n\n// Operaciones con conjuntos\n\n// Inserción\nconjunto.add(6)\nconsole.log('Conjunto después de inserción:', conjunto)\n\n\n// Borrado\nconjunto.delete(6) \nconsole.log('Conjunto después de borrado:', conjunto);\n\n// Actualización\nconjunto = new Set([...conjunto].map(x => x * 2))\nconsole.log('Conjunto después de actualización:', conjunto)\n\n\n// Ejercicio extra: Agenda de contactos por terminal\n\nconst readline = require(\"readline\");\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\nconst agenda = []\n\nconst my_agenda = () => {\n\n    console.log(\"Agenda de contactos\")\n    console.log(\"Digite el numero de la opcion que quiere utilizar\")\n    console.log(\"1 - Buscar contacto\")\n    console.log(\"2 - Agregar contacto\")\n    console.log(\"3 - Actualizar contacto\")\n    console.log(\"4 - Borrar contacto\")\n    console.log(\"5 - Salir\")\n\n    rl.question(\"Opción: \", (answer) => {\n        opcion = parseInt(answer)\n\n    switch (opcion){\n        case 1:\n            buscarContacto()\n            break;\n        case 2:\n            ingresarContacto()\n            break;\n        case 3:\n            actualizarContacto()\n            break;\n        case 4:\n            borrarContacto()\n            break;\n        case 5:\n            console.log(\"Saliendo de la agenda\")\n            rl.close()\n            break;   \n        default:\n            console.log(\"Opcion no valida. Solo se admiten numeros del 1 al 5\") \n            my_agenda()                \n    }})\n}\n\n\nfunction ingresarContacto(){\n    rl.question(\"Ingrese el nombre del nuevo contacto:\", (nuevoNombre) => {\n        rl.question(\"Ingrese el numero de teléfono (maximo 10 digitos):\", (nuevoNumero) => {\n            if (nuevoNumero.length > 10){\n                console.log(\"El teléfono no puede superar los 10 digitos\")\n        }    \n        else if (agenda.some(i => i.nombre.toLowerCase()=== nuevoNombre.toLowerCase())){\n            console.log(\"El contacto ya existe, intente con otro nombre\")\n        }else{  \n            agenda.push({nombre: nuevoNombre, telefono: nuevoNumero})\n            console.log(\"Contacto agendado exitosamente\")\n        }\n        my_agenda()\n    })\n    })\n}\n\nfunction buscarContacto(){\n    rl.question(\"Ingresa el nombre del contacto a buscar\", (nombreConsulta) => {\n        const contacto = agenda.find(i => i.nombre.toLowerCase() === nombreConsulta.toLowerCase())\n    if (contacto) {\n        console.log(`Nombre: ${contacto.nombre}, Teléfono:${contacto.telefono}`)\n    }else{\n        console.log(\"No se encontro un contacto con ese nombre\")\n    }\n    my_agenda()\n    }) \n}\n\nfunction borrarContacto(){\n    rl.question('Nombre del contacto a eliminar: ', (nombre) => {\n        const index = agenda.findIndex(c => c.nombre === nombre);\n        if (index !== -1) {\n            agenda.splice(index, 1);\n            console.log('Contacto eliminado.');\n        } else {\n            console.log('Contacto no encontrado.');\n        }\n        my_agenda()\n    })\n}\nfunction actualizarContacto(){\n    rl.question('Nombre del contacto a actualizar: ', (nombre) => {\n        const contacto = agenda.find(c => c.nombre === nombre);\n        if (contacto) {\n            rl.question(\"Ingrese el numero de teléfono (maximo 10 digitos):\", (nuevoNumero) => {\n                if (nuevoNumero.length > 10){\n                    console.log(\"El teléfono no puede superar los 10 digitos\")\n                }    \n                else {\n                    contacto.telefono = nuevoNumero;\n                    console.log('Contacto actualizado.');\n                }\n                my_agenda()\n            });\n        } else {\n            console.log('Contacto no encontrado.');\n           my_agenda()\n        }\n    }); \n}\n\n\nmy_agenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/AndresMCardenas.js",
    "content": "/* \n  * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n\n  \"\"\"\n\n# Creación de estructuras de datos\n\n# Listas\n*/\n\nlet lista = [1, 2, 3, 4, 5, 6, 7, 8, 9];\n\n// Inserción\nlista.push(10);\nconsole.log(lista);\n\n// Borrado\n\nlista.pop();\nconsole.log(lista);\n\n// Actualización\n\nlista[0] = 0;\nconsole.log(lista);\n\n// Ordenación\n\nlista.sort();\nconsole.log(lista);\n\n// Diccionarios\n\nlet diccionario = {\n  nombre: \"Andres\",\n  apellido: \"Cardenas\",\n  edad: 30,\n};\n\n// Inserción\n\ndiccionario[\"sexo\"] = \"Masculino\";\nconsole.log(diccionario);\n\n// Borrado\n\ndelete diccionario[\"sexo\"];\nconsole.log(diccionario);\n\n// Actualización\n\ndiccionario[\"edad\"] = 31;\nconsole.log(diccionario);\n\n// Ordenación\n \n// No aplica\n\n// Tuplas\n\nlet tupla = [1, \"Andres\", 30];\nconsole.log(tupla);\n\n// Inserción\n\ntupla.push(\"Cardenas\");\nconsole.log(tupla);\n\n// Borrado\n\ntupla.pop();\nconsole.log(tupla);\n\n// Actualización\n\ntupla[0] = 0;\nconsole.log(tupla);\n\n// Ordenación\n\ntupla.sort();\nconsole.log(tupla);\n\n// Conjuntos son estructuras de datos que no permiten elementos repetidos\n\nlet conjunto = new Set([1, 2, 3, 4, 5, 6, 7, 8, 9]);\nconsole.log(conjunto);\n\n// Inserción\n\nconjunto.add(10);\nconsole.log(conjunto);\n\n// Borrado\n\nconjunto.delete(10);\nconsole.log(conjunto);\n\n// Actualización no aplica dado que no permite dadp que no se tiene accesos a los elementos por indice\n\n// Ordenación no aplica dado que no permite se tiene accesos a los elementos por indice\n\n// Diccionarios ordenados\n\nlet diccionarioOrdenado = new Map([\n  [\"nombre\", \"Andres\"],\n  [\"apellido\", \"Cardenas\"],\n  [\"edad\", 30],\n]);\n\nconsole.log(diccionarioOrdenado);\n\n// busqueda\n\nconsole.log(diccionarioOrdenado.get(\"nombre\"));\n\n\n// Inserción\n\ndiccionarioOrdenado.set(\"sexo\", \"Masculino\");\nconsole.log(diccionarioOrdenado);\n\n// Borrado\n\ndiccionarioOrdenado.delete(\"sexo\");\nconsole.log(diccionarioOrdenado);\n\n// Actualización\n\ndiccionarioOrdenado.set(\"edad\", 31);\nconsole.log(diccionarioOrdenado);\n\n// Ordenación no se aplica dado que no tiene indice\n\n// Pilas\n\nlet pila = [1, 2, 3, 4, 5, 6, 7, 8, 9];\nconsole.log(pila);\n\n// Inserción\n\npila.push(10);\nconsole.log(pila);\n\n// Borrado\n\npila.pop();\nconsole.log(pila);\n\n// Actualización\n\npila[0] = 0;\nconsole.log(pila);\n\n// Ordenación\n\npila.sort();\nconsole.log(pila);\n\n// Colas\n\nlet cola = [1, 2, 3, 4, 5, 6, 7, 8, 9];\nconsole.log(cola);\n\n// Inserción\n\ncola.push(10);\nconsole.log(cola);\n\n// Borrado\n\ncola.shift();\nconsole.log(cola);\n\n// Actualización\n\ncola[0] = 0;\nconsole.log(cola);\n\n// Ordenación\n\ncola.sort();\nconsole.log(cola);\n\n// Árboles son estructuras de datos no lineales que se componen de nodos o vértices y ramas u hojas\n\nclass Nodo {\n  constructor(valor) {\n    this.valor = valor;\n    this.hijos = [];\n  }\n}\n\nclass Arbol {\n  constructor(valor) {\n    this.raiz = new Nodo(valor);\n  }\n}\n\nlet arbol = new Arbol(1);\nconsole.log(arbol);\n\n// Inserción\n\narbol.raiz.hijos.push(new Nodo(2));\nconsole.log(arbol);\n\n// Borrado\n\narbol.raiz.hijos.pop();\nconsole.log(arbol);\n\n// Actualización\n\narbol.raiz.valor = 0;\nconsole.log(arbol);\n\n// Ordenación no aplica dado que no tiene indice\n\n// Grafos son estructuras de datos no lineales que se componen de nodos o vértices y aristas\n\n// class Nodo {\n//   constructor(valor) {\n//     this.valor = valor;\n//     this.hijos = [];\n//   }\n// }\n\n// class Grafo {\n//   constructor(valor) {\n//     this.raiz = new Nodo(valor);\n//   }\n// }\n\n// let grafo = new Grafo(1);\n// console.log(grafo);\n\n// Inserción\n\n// grafo.raiz.hijos.push(new Nodo(2));\n// console.log(grafo);\n\n// // Borrado\n\n// grafo.raiz.hijos.pop();\n// console.log(grafo);\n\n// // Actualización\n\n// grafo.raiz.valor = 0;\n// console.log(grafo);\n\n// Ordenación no aplica dado que no tiene indice\n\n// Matrices son estructuras de datos que se componen de filas y columnas\n\nlet matriz = [\n  [1, 2, 3],\n  [4, 5, 6],\n];\nconsole.log(matriz);\n\n// Inserción\n\nmatriz.push([7, 8, 9]);\nconsole.log(matriz);\n\n// Borrado\n\nmatriz.pop();\nconsole.log(matriz);\n\n// Actualización\n\nmatriz[0][0] = 0;\nconsole.log(matriz);\n\n// Ordenación\n\nmatriz.sort();\nconsole.log(matriz);\n\n/*\n\"\"\"\n  * DIFICULTAD EXTRA(opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n  * y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n * y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más\n  * de 11 dígitos(o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.\n\n\"\"\"\n*/\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/AndrewCodev.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\n//Array: Lista ordenada de elementos accesibles por índice.\nconst frutas = [\"manzana\", \"banana\", \"pera\"];\nfrutas.push(\"Naranja\"); //Agregamos elemento al final\nfrutas.unshift(\"Mango\"); //Agregamos elemento al inicio\nfrutas.splice(2, 0, \"kiwi\"); // Inserta \"kiwi\" en la posición 2\nconsole.log(frutas);\n\n//Modificamos frutas en la posición 1 Manzana por mandarina\nfrutas[1] = \"mandarina\";\nconsole.log(frutas);\n\n//Recorriendo el array de frutas y modificando el valor de banana\nfrutas.forEach((fruta, index) => {\n  if (fruta === \"banana\") {\n    frutas[index] = \"plátano\";\n  }\n});\nconsole.log(frutas);\n\n//Eliminar elementos\nfrutas.pop(); // ➜ elimina el último (\"Naranja\")\nconsole.log(frutas);\n\nfrutas.shift(); // ➜ elimina el primero (\"mango\")\nconsole.log(frutas);\n\nfrutas.splice(1, 1); // Elimina 1 elemento en la posición 1 (kiwi)\nconsole.log(frutas);\n\nconst nuevasFrutas = [...frutas, \"sandía\"]; // Agrega \"sandía\" sin tocar el original\nconsole.log(nuevasFrutas);\n\n//Objeto: Conjunto de pares clave-valor, útil para representar entidades.\nconst persona = {\n  nombre: \"Andrew\",\n  apellido: \"code\",\n  edad: 31,\n};\nconsole.log(persona);\n\n//Agregamos elementos al objeto persona con .\npersona.pais = \"colombia\";\nconsole.log(persona);\n\n//Agregamos elementos al objeto persona con []\nconst nuevaClave = \"ciudad\";\npersona[nuevaClave] = \"Medellín\";\nconsole.log(persona);\n\n//Modificamos elementos al objeto persona edad = 31\npersona.edad = 33;\nconsole.log(persona);\n\n//Eliminamos elementos al objeto persona edad = 31\ndelete persona.edad;\nconsole.log(persona);\n\n//Agregar multiples elementos\nObject.assign(persona, {\n  hobbies: [\"leer\", \"música\"],\n  activo: true,\n});\n\nconsole.log(persona);\n\n//Set: Conjunto de valores únicos, sin duplicados.\nconst numerosUnicos = new Set([1, 2, 3, 3]);\nnumerosUnicos.add(4);\nnumerosUnicos.add(5);\nnumerosUnicos.add(5); // ❌ No se agrega porque ya existe\n\nconsole.log(numerosUnicos);\n\nnumerosUnicos.delete(5); // Elimina \"pera\"\nconsole.log(numerosUnicos);\n\n//Map Estructura clave-valor como un objeto, pero con orden y flexibilidad.\nconst mapa = new Map();\nmapa.set(\"nombre\", \"Andrew\");\nmapa.set(\"apellido\", \"Codev\");\nmapa.set(\"edad\", \"31\");\n\nconsole.log(mapa);\n\nmapa.delete(\"edad\"); // Elimina \"pera\"\nconsole.log(mapa);\n\n//DIFICULTAD EXTRA\n\nconst agenda = [\n  { nombre: \"Juan\", telefono: 36598855441 },\n  { nombre: \"Camila\", telefono: 36598877441 },\n  { nombre: \"Andres\", telefono: 32569874111 },\n];\nconst MAX_CARACTERES = 11;\nlet programaActivo = true; // Bandera para controlar si el programa sigue activo\n\nconst iniciarAgenda = (MAX_CARACTERES) => {\n  if (!programaActivo) return; // Si el programa no está activo, no sigue ejecutándose.\n\n  const opcion = parseInt(\n    prompt(\n      \"Bienvenid@ a tu Agenda. ¿Qué deseas hacer? presiona\\n1 para Agregar\\n2 para Buscar\\n3 para Modificar\\n4 para Eliminar\\n5 para Listar\\n6 para Cerrar\"\n    )\n  );\n\n  switch (opcion) {\n    case 1:\n      agregarContanto();\n      break;\n    case 2:\n      buscarContacto(\n        prompt(\"Escribe el nombre o el número de teléfono:\").trim()\n      );\n      break;\n    case 3:\n      let contactoModificado = buscarContacto(\n        prompt(\n          \"Escribe el nombre o teléfono del contacto que deseas modificar:\"\n        ).trim()\n      );\n      if (contactoModificado) modificarContanto(contactoModificado);\n      break;\n    case 4:\n      eliminarContacto();\n      break;\n    case 5:\n      listarContactos();\n      break;\n    case 6:\n      cerrarPrograma();\n      break;\n    default:\n      alert(\"Opción no válida. Inténtalo de nuevo.\");\n  }\n\n  if (programaActivo) iniciarAgenda(MAX_CARACTERES); // Solo vuelve a llamar a la función si el programa sigue activo\n};\n\n// Función para validar el teléfono\nconst validarTelefono = (telefono) => {\n  if (!/^\\d+$/.test(telefono)) {\n    alert(\"El teléfono debe contener solo números.\");\n    return false;\n  }\n  if (telefono.length > MAX_CARACTERES) {\n    alert(`El teléfono no puede tener más de ${MAX_CARACTERES} dígitos.`);\n    return false;\n  }\n  return true;\n};\n\n// Función para verificar si un contacto ya existe\nconst contactoExistente = (telefono) =>\n  agenda.some((contacto) => contacto.telefono === telefono);\n\n// Función común para mostrar un mensaje de error\nconst mostrarError = (mensaje) => {\n  alert(mensaje);\n};\n\n// Buscar un contacto por nombre o teléfono\nconst buscarContacto = (contactoBuscado) => {\n  console.log(\"🔍 BUSCANDO...\");\n  const contactoEncontrado = agenda.find(\n    (contacto) =>\n      contacto.nombre.toLowerCase() === contactoBuscado.toLowerCase() ||\n      contacto.telefono === parseInt(contactoBuscado)\n  );\n\n  if (contactoEncontrado) {\n    console.log(\"✅ Contacto encontrado:\", contactoEncontrado);\n    return contactoEncontrado;\n  } else {\n    console.log(\"❌ Contacto no encontrado.\");\n    return null;\n  }\n};\n\n// Agregar un nuevo contacto\nconst agregarContanto = () => {\n  let nombre = prompt(\"Escribe el nombre del contacto:\").trim();\n  if (!nombre) return alert(\"El nombre no puede estar vacío.\");\n\n  let telefono = prompt(\n    `Escribe el teléfono (solo números, máx. ${MAX_CARACTERES} dígitos):`\n  ).trim();\n\n  if (!validarTelefono(telefono)) return;\n\n  if (contactoExistente(telefono)) {\n    mostrarError(\"El contacto con este teléfono ya existe.\");\n  } else {\n    agenda.push({ nombre, telefono });\n    alert(\"Contacto agregado correctamente ✅\");\n    listarContactos();\n  }\n};\n\n// Listar todos los contactos\nconst listarContactos = () => {\n  if (agenda.length > 0) {\n    console.log(\"MIS CONTACTOS\");\n    agenda.forEach((contacto) => {\n      console.log(`Nombre: ${contacto.nombre}, Teléfono: ${contacto.telefono}`);\n    });\n  } else {\n    console.log(\"La agenda no tiene contactos.\");\n  }\n};\n\n// Modificar un contacto\nconst modificarContanto = (contacto) => {\n  console.log(\"El contacto a modificar es:\", contacto);\n  contacto.nombre = prompt(\"Ingresa el nuevo nombre:\").trim();\n  let telefono = prompt(\"Ingresa el nuevo teléfono:\").trim();\n\n  if (!validarTelefono(telefono)) return;\n\n  contacto.telefono = telefono;\n  console.log(\"Contacto modificado:\", contacto);\n};\n\n// Eliminar un contacto\nconst eliminarContacto = () => {\n  let telefono = prompt(\n    \"Escribe el teléfono del contacto que deseas eliminar:\"\n  ).trim();\n\n  if (!validarTelefono(telefono)) return;\n\n  const contactoAEliminar = agenda.find(\n    (contacto) => contacto.telefono === telefono\n  );\n\n  if (contactoAEliminar) {\n    const confirmacion = confirm(\n      `¿Estás seguro de que deseas eliminar el contacto de ${contactoAEliminar.nombre} con el teléfono ${contactoAEliminar.telefono}?`\n    );\n    if (confirmacion) {\n      const index = agenda.indexOf(contactoAEliminar);\n      agenda.splice(index, 1);\n      console.log(\"Contacto eliminado:\", contactoAEliminar);\n      alert(\"El contacto ha sido eliminado.\");\n    } else {\n      console.log(\"Eliminación cancelada.\");\n    }\n  } else {\n    mostrarError(\"No se encontró un contacto con ese teléfono.\");\n  }\n};\n\n// Cerrar el programa\nconst cerrarPrograma = () => {\n  console.log(\"Programa cerrado.\");\n  programaActivo = false; // Cambiar la bandera a false para cerrar el programa\n  alert(\"Programa cerrado.\");\n};\n\niniciarAgenda(MAX_CARACTERES);\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/AngelArgumedo.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto\n *   en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n *   y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n *   y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más\n *   de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.\n */\n\nconst { Console } = require('console');\nconst { get } = require('http');\n\n// estructura de datos\n//Areglos\nconsole.log(\"Areglos\");\nlet array = [1, 2, 3, 4];\nconsole.log(array[0]);\narray.push(5);\nconsole.log(array.length);\n\n//Objetos\\\nconsole.log(\"Objetos\");\nlet objeto = {\n    nombre: \"Carl\",\n    edad: 25,\n    esEstudiante: true,\n};\nconsole.log(objeto.nombre);\nobjeto.edad = 31; // modificar propiedad\n\n// Sets (conjuntos)\nconsole.log(\"Sets\");\nlet set = new Set([1, 2, 3, 4]);\nset.add(5);\nset.delete(3);\nconsole.log(set.size);\nconsole.log(set.has(3));//false\n\n// maps\nconsole.log(\"Mapas\");\nlet map = new Map();\nmap.set(\"nombre\", \"Carl\");\nmap.set(\"edad\", 25);\nconsole.log(map);\nconsole.log(map.get(\"nombre\"));\nmap.delete(\"edad\");\nconsole.log(map.size);\n\n// WeakSets (conjuntos debiles)\n/* son como los set, pero solo almacenan objetos*/\nconsole.log(\"WeakSets\");\nlet weakSet = new WeakSet();\nlet obj = {};\nweakSet.add(obj);\nconsole.log(weakSet.has(obj));\n\n// WeakMaps (mapas debiles)\nlet weakMap = new WeakMap();\nlet obj2 = {};\nweakMap.set(obj, \"valor\");\nconsole.log(weakMap.get(obj));\n\n// Typed Arrays (arreglos tipados)\n// son como los arreglos normales, pero manejan datos binarios y datos especificos\nconsole.log(\"Typed Arrays\");\nlet buffer = new ArrayBuffer(8);//crea buffer de 8 bytes\nlet int32view = new Int32Array(buffer);//crea arreglo de 32 bits\nint32view[0] = 42;\nconsole.log(int32view[0]);\n\n// Stacks (pilas)\nconsole.log(\"Stacks\");\nclass Stack {\n    constructor() {\n        this.items = [];\n    };\n    push(element) {\n        this.items.push(element);\n    };\n    pop() {\n        if (this.items.length === 0) return \"Underflow\";\n        return this.items.pop();\n    };\n    peek() {\n        return this.items[this.items.length - 1];\n    };\n};\nlet stack = new Stack();\nstack.push(1);\nstack.push(2);\nconsole.log(stack.peek());\n\n// Queues (colas)\nconsole.log(\"Queues\");\nclass Queue{\n    constructor() { \n        this.items = [];\n    }\n    enqueue(element) {\n        this.items.push(element);\n    }\n    dequeue() {\n        if (this.items.length === 0) return \"Underflow\";\n        return this.items.shift();\n    }\n    front() {\n        return this.items[0];\n    } \n}\nlet queue = new Queue();\nqueue.enqueue(1);\nqueue.enqueue(2);\nconsole.log(queue.front());\nqueue.dequeue();\nconsole.log(queue.front());\n\n\n// Ejercicio\nconst readline = require('readline');\nconst contactos = new Map();\n\nclass PedirDatos {\n        constructor(input) {\n            this.input = input;\n        }\n        getRespuesta() {\n            const rl = readline.createInterface({\n                input: process.stdin,\n                output: process.stdout\n            });\n\n            return new Promise((resolve) => {\n                rl.question(this.input, (output) => {\n                    rl.close();\n                    resolve(output);\n                })\n            });\n            \n        }\n};\n\nclass GetData extends PedirDatos {\n        constructor(prompt) {\n            super(prompt);\n        }\n        obtenerDatos() {\n            return this.getRespuesta();\n        }\n};\n    \nconst verContactos = async () => {\n    if (contactos.size === 0) {\n        console.log(\"No hay contactos\");\n    } else {\n        const verConcatos = console.log(contactos);\n        return verConcatos;\n    }\n};\n    \nconst AgregarContacto = async () => {\n    let persona = {\n            id: contactos.size + 1,\n            nombre: '',\n            edad: 0,\n            sexo: '',\n            telefono: '',\n            direccion: '',\n            email: '',\n            pronombre: ''\n    };\n\n    const datos = [\n        { prompt: \"Escribe el nombre: \", key: \"nombre\" },\n        { prompt: \"Escribe su edad: \", key: \"edad\" },\n        { prompt: \"Escribe su sexo: \", key: \"sexo\" },\n        { prompt: \"Escribe el numero de celular: \", key: \"telefono\" },\n        { prompt: \"Escribe su direccion: \", key: \"direccion\" },\n        { prompt: \"Escribe su email: \", key: \"email\" },\n        { prompt: \"con que nombre te gustaria guardar tu contacto?: \", key: \"pronombre\" },\n    ];\n    const getLength = (number) => number.toString().length;\n\n    for (let dato of datos) {\n        let getData = new GetData(dato.prompt);\n        let inputData = await getData.obtenerDatos();\n\n        // Validaciones\n        if (dato.key === 'telefono') {\n            if (!inputData) {\n                console.log(\"Teléfono no válido\");\n                return;\n            } else if (isNaN(inputData)) {\n                console.log(\"El número de teléfono debe ser numérico\");\n                return;\n            }else if ( getLength(inputData) !== 11) {\n                console.log(\"Teléfono debe tener 11 dígitos\");\n                return;\n            } \n        }\n\n        if (dato.key === 'nombre' && !inputData) {\n            console.log(\"No puedes dejar el nombre en blanco\");\n            return;\n        }\n\n        persona[dato.key] = inputData;\n    }\n\n    contactos.set(persona.pronombre, persona);\n    console.log(\"concato agregado\");\n\n};\n\nconst EliminarContacto = async () => {\n    let getData = new GetData(\"Escriba el nombre del contacto que desea eliminar: \");\n    let nombre = await getData.obtenerDatos();\n    if (contactos.has(nombre)) {\n        contactos.delete(nombre);\n        console.log(\"Contacto eliminado\");\n    } else {\n        console.log(\"No existe el contacto que desea eliminar\");\n    }\n};\n\nconst BuscarContacto = async () => {\n    let getData = new GetData(\"Escriba el nombre del contacto que desea buscar: \");\n    let nombre = await getData.obtenerDatos();\n    if (contactos.has(nombre)) {\n        console.log(contactos.get(nombre));\n    } else {\n        console.log(\"No existe el contacto que desea buscar\");\n    }\n};\n\nconst ModificarContacto = async () => {\n    let getData = new GetData(\"Escriba el nombre del contacto que desea modificar: \");\n    let nombre = await getData.obtenerDatos();\n    if (contactos.has(nombre)) {\n        let contacto = contactos.get(nombre);\n        let nuevoNombre = await new GetData(\"Escriba el nuevo nombre: \").obtenerDatos();\n        let nuevaEdad = await new GetData(\"Escriba la nueva edad: \").obtenerDatos();\n        let nuevoSexo = await new GetData(\"Escriba el nuevo sexo: \").obtenerDatos();\n        let nuevoTelefono = await new GetData(\"Escriba el nuevo numero de celular: \").obtenerDatos();\n        let nuevaDireccion = await new GetData(\"Escriba la nueva direccion: \").obtenerDatos();\n        let nuevoEmail = await new GetData(\"Escriba el nuevo email: \").obtenerDatos();\n        let nuevoPronombre = await new GetData(\"Con qué nombre te gustaría guardar tu contacto?: \").obtenerDatos();\n\n        contacto.nombre = nuevoNombre || contacto.nombre;\n        contacto.edad = nuevaEdad || contacto.edad;\n        contacto.sexo = nuevoSexo || contacto.sexo;\n        contacto.telefono = nuevoTelefono || contacto.telefono;\n        contacto.direccion = nuevaDireccion || contacto.direccion;\n        contacto.email = nuevoEmail || contacto.email;\n        contacto.pronombre = nuevoPronombre || contacto.pronombre;\n\n        contactos.set(nuevoPronombre, contacto);\n        if (nombre !== nuevoPronombre) {\n            contactos.delete(nombre);\n        }\n\n        console.log(\"Contacto modificado\");\n    } else {\n        console.log(\"No existe el contacto que desea modificar\");\n    }\n};\n\nconst interfaces = async () => {\n    \n    const recibirOpcion = async(text) => {\n        return await new Promise((resolve) => {\n            const rl = readline.createInterface({\n                input: process.stdin,\n                output: process.stdout\n            });\n            rl.question(text, (opcion) => {\n                rl.close();\n                resolve(opcion);\n            })\n        });\n    };\n\n    const printHome = async() => {\n        let home = (`\n *******AGENDA DE CONTACTOS*******\n        1.  ver contactos\n        2.  Agregar contacto \n        3.  Eliminar contacto \n        4.  Buscar contacto\n        5.  Modificar contacto\n        6.  Finalizar programa\n\n        escriba su opcion: `);\n        const opcionHome = await recibirOpcion(home);\n        return opcionHome;\n    }\n\n\n\n    let opcion = '';\n    while (opcion !== '6') {\n        opcion = await printHome();\n        switch (opcion) {\n            case '1':\n                await verContactos();\n                break;\n            case '2':\n                await AgregarContacto();\n                break;\n            case '3':\n                await EliminarContacto();\n                break;\n            case '4':\n                await BuscarContacto();\n                break;\n            case '5':\n                await ModificarContacto();\n                break;\n            case '6':\n                console.log('Finalizando programa.');\n                break;\n            default:\n                console.log('Opción no válida, intente de nuevo.');\n        }\n    }\n    \n};\n\n\n\nasync function main() {\n    await interfaces();\n}\n\nmain();\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/ArticKun.js",
    "content": "\n//ESTRUCTURAS DE DATOS EN JS\n\n/*\nALgunas de las estructuras soportadas en javascript son:\n\n1. Arrays\n2. Objects\n3. Strings\n4. Sets\n5. Maps\n6. Colas (Queues) y Pilas (Stacks):\n\n*/\n\n//*  1 ARRAYS ----- \n\n/*\nun array (también conocido como arreglo o matriz) \nes una estructura de datos que almacena elementos del \nmismo tipo en una secuencia ordenada. Cada elemento en \nun array ocupa una posición específica, y se puede acceder \na ellos mediante un índice o posición.\nEn el contexto de JavaScript, un array puede contener \nelementos de cualquier tipo, ya sean números, cadenas de texto, \nobjetos u otros arrays.\n\nLos arrays son muy utilizados en programación debido a su \ncapacidad para almacenar y organizar datos de manera eficiente. \nPueden ser utilizados en una variedad de situaciones, como la \nimplementación de listas, colas, pilas y muchas otras estructuras \nde datos. Además, los arrays proporcionan métodos y propiedades \nútiles que facilitan la manipulación y gestión de los datos \nalmacenados en ellos.\n\nSINTAXIS:\n\nindice        0 1 2 3     el indice siempre empieza en 0\nLet array = [ a,b,c,d ];  cuerpo de array\n\n*/\n\n// INSERCIÓN EN UN ARRAY\n// Al final del array\nlet miArray = [1, 2, 3];\nmiArray.push(4);\n// Resultado: miArray = [1, 2, 3, 4]\n\n// Al principio del array\nlet miArray2 = [2, 3, 4];\nmiArray.unshift(1);\n// Resultado: miArray = [1, 2, 3, 4]\n\n//En una posicion Específica\nlet miArray3 = [1, 2, 4];\nmiArray.splice(2, 0, 3);\n// Resultado: miArray = [1, 2, 3, 4]\n\n/*\n\nExplicacion de Splice -----\n\nEl primer argumento (2) es el índice en el cual comenzará la modificación. \nEn este caso, se empieza en el índice 2, que es la posición después de 2 en el array.\n\nEl segundo argumento (0) indica cuántos elementos se deben eliminar desde \nel índice especificado. En este caso, 0 significa que no se eliminará ningún elemento.\n\nLos argumentos restantes (3) son los elementos que se agregarán al array a partir \ndel índice especificado. En este caso, se agrega el elemento 3 en el índice 2.\n\n*/\n\n// BORRADO EN UN ARRAY\n//Al final de array\nlet miArray4 = [1, 2, 3, 4];\nmiArray.pop();\n// Resultado: miArray = [1, 2, 3]\n\n//Al inicio del array\nlet miArray5 = [1, 2, 3];\nmiArray.shift();\n// Resultado: miArray = [2, 3]\n\n//En una posición específica\nlet miArray6 = [1, 2, 3, 4];\nmiArray.splice(1, 1);\n// Resultado: miArray = [1, 3, 4]\n\n\n// ACTUALIZACION  EN UN ARRAY\n//Reasignando valores\nlet miArray7 = [1, 2, 3];\nmiArray[1] = 4;\n// Resultado: miArray = [1, 4, 3]\n\n//En una posicion específica\nlet miArray8 = [1, 2, 4];\nmiArray.splice(1, 1, 10);\n// Resultado: miArray = [1, 10, 4]\n\n//En una posicion especifica\nlet miArray9 = [1, 2, 4];\nmiArray.fill(10, 1, 2);\n// Resultado: miArray = [1, 10, 4]\n\n//Creando un nuevo array\nlet miArray10 = [1, 2, 4];\nlet nuevoArray1 = miArray.map((elemento, indice) => (indice === 1 ? 10 : elemento));\n// Resultado: miArray = [1, 10, 4]\n\n/*\nmap crea un nuevo array aplicando una función a cada elemento del array original. \nEn este caso, se verifica si el índice es 1 y se actualiza ese elemento a 10.\n*/\n\n// Operador de propagacion\nlet miArray11 = [1, 2, 4];\nlet nuevoArray2 = [...miArray.slice(0, 1), 10, ...miArray.slice(2)];\n// Resultado: miArray = [1, 10, 4]\n\n/*\n\nExplicacion operador de propagacion\n\nmiArray es el array original que contiene los elementos [1, 2, 4].\n\nmiArray.slice(0, 1) devuelve una porción del array desde el índice 0 (inclusive) \nhasta el índice 1 (exclusive). En este caso, devuelve [1].\n\n...miArray.slice(0, 1) utiliza el operador de propagación para descomponer los \nelementos de la porción obtenida. Esto es necesario para incluir los elementos \nindividualmente en el nuevo array.\n\n10 es el valor que queremos insertar o actualizar en el array.\n\n...miArray.slice(2) realiza una operación similar a la primera parte, obteniendo \nlos elementos desde el índice 2 hasta el final del array. En este caso, devuelve [4].\n\nFinalmente, todos estos fragmentos se combinan en un nuevo array llamado nuevoArray \nutilizando el operador de propagación. El resultado es [1, 10, 4].\n\n*/\n\n/*\nExplicacion metodo fill\n\n10 es el valor con el que se llenarán los elementos.\n1 es el índice de inicio (inclusive) desde el cual comenzará a llenarse.\n2 es el índice de fin (exclusive) hasta el cual se llenarán los elementos.\nEn este caso, fill llenará los elementos desde el índice 1 (inclusive) hasta el \níndice 2 (exclusive) con el valor 10.\n\nComo resultado, el array miArray se modifica, y ahora contiene los elementos [1, 10, 4].\n\n*/\n\n\n// ORDENACIÓN DE UN ARRAY \n//Ascendente\nlet miArray = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5];\nmiArray.sort((a, b) => a - b);\n// Resultado: miArray = [1, 1, 2, 3, 3, 4, 5, 5, 5, 6, 9]\n\n//Descendente\nlet miArray = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5];\nmiArray.sort((a, b) => b - a);\n// Resultado: miArray = [9, 6, 5, 5, 5, 4, 3, 3, 2, 1, 1]\n\n\n\n//* 2 OBJECTS -----\n\n/*\n\nEn JavaScript, un objeto es una estructura de datos que permite almacenar \ny organizar datos mediante pares clave : valor. Cada valor almacenado en un \nobjeto está asociado a una clave única, lo que facilita el acceso y la \nmanipulación de los datos. Los objetos en JavaScript son una de las características \nfundamentales del lenguaje y se utilizan extensamente.\n\nSINTAXIS\n\nlet miObjeto = {\n  clave1: \"valor1\",\n  clave2: 42,\n  clave3: true\n};\n\nAcceso a valores mediante claves\n\nconsole.log( miObjeto.clave1 ); // Imprime \"valor1\"\nconsole.log( miObjeto.clave2 ); // Imprime 42\nconsole.log( miObjeto.clave3 ); // Imprime true\n\n*/\n\n// INSERCIÓN EN UN OBJETO\n//Para insertar una nueva propiedad en un objeto, simplemente \n// se asigna un valor a una nueva clave:\nlet miObjeto = {\n  clave1: \"valor1\",\n  clave2: 42\n};\n\n// Inserción de una nueva propiedad\nmiObjeto.nuevaClave = \"nuevoValor\";\nconsole.log(miObjeto);\n\n// Resultado: { clave1: \"valor1\", clave2: 42, nuevaClave: \"nuevoValor\" }\n\n\n// BORRADO EN UN OBJETO\n//Para eliminar una propiedad de un objeto, puedes utilizar el operador delete:\nlet miObjeto2 = {\n  clave1: \"valor1\",\n  clave2: 42,\n  nuevaClave: \"nuevoValor\"\n};\n\n// Borrado de una propiedad\ndelete miObjeto.nuevaClave;\nconsole.log(miObjeto2);\n// Resultado: { clave1: \"valor1\", clave2: 42 }\n\n\n//ACTUALIZACION DE UN OBJETO\n//La actualización de un valor en un objeto se realiza simplemente asignando \n//un nuevo valor a la clave correspondiente:\nlet miObjeto3 = {\n  clave1: \"valor1\",\n  clave2: 42\n};\n\n// Actualización de un valor\nmiObjeto.clave2 = 100;\nconsole.log(miObjeto3);\n// Resultado: { clave1: \"valor1\", clave2: 100 }\n\n\n//ORDENACION DE UN OBJETO\n//A diferencia de los arrays, los objetos en JavaScript no tienen un orden \n//específico para sus propiedades. Sin embargo, se puede simular un cierto orden \n//utilizando arrays o mapas si el orden es importante para la aplicación.\nlet miObjeto4 = {\n  clave2: 42,\n  clave1: \"valor1\",\n  clave3: true\n};\n\n// Crear un array de las claves y ordenarlas\nlet clavesOrdenadas = Object.keys(miObjeto4).sort();\n\n// Crear un nuevo objeto con las claves ordenadas\nlet objetoOrdenado = {};\nfor (let clave of clavesOrdenadas) {\n  objetoOrdenado[clave] = miObjeto4[clave];\n};\n\nconsole.log(objetoOrdenado);\n// Resultado: { clave1: \"valor1\", clave2: 42, clave3: true }\n\n/*\nExplicacion de método objext.keys() y el método .short()\n\nObject.keys(miObjeto4): El método Object.keys() es una función \nincorporada en JavaScript que toma un objeto como argumento y devuelve \nun array con las claves (o propiedades) de ese objeto. En este caso, \nmiObjeto4 es el objeto del cual queremos obtener las claves.\n\n.sort(): Después de obtener las claves del objeto usando Object.keys(), \nse aplica el método sort() al array resultante. El método sort() ordena \nlos elementos de un array alfabéticamente (por defecto, en orden lexicográfico).\n\n*/\n\n\n\n//*  3 SETS ----- \n\n/*\n\nEn JavaScript, un Set es un objeto que te permite almacenar valores \núnicos de cualquier tipo, ya sea valores primitivos o referencias a objetos. \nLa principal característica de un Set es que no permite duplicados, por lo \nque cada elemento debe ser único en el conjunto.\n\nSINTAXIS:\n\nCreacion del set\nlet miSet = new Set();\n\nInsercion de datos en el set\n\nmiSet.add(1);\nmiSet.add(\"Hola\");\nmiSet.add(true);\nmiSet.add(1); \n\nEste ultimo valor 1 no se añadirá, ya que los Sets no permiten duplicados\n\nconsole.log(miSet);\nResultado: Set { 1, 'Hola', true }\n\n\n*/\n\n/*\n\nCaracterísticas\n\nValores Únicos: Los Sets no pueden contener elementos duplicados. \nSi intentas añadir un elemento que ya está presente en el conjunto, no \nse realizará ninguna acción.\n\nNo Ordenados: A diferencia de los arrays, los Sets no mantienen un orden \nespecífico de los elementos. No puedes acceder a los elementos de un Set \npor índice.\n\nOperaciones Básicas: Los Sets proporcionan métodos como add para añadir \nelementos, delete para eliminar elementos, y has para verificar si un elemento \nestá presente en el conjunto.\n\n*/\n\n\n// INSERCION EN UN SET\n//Para insertar elementos en un Set, puedes utilizar el método add:\nlet miSet = new Set();\n\nmiSet.add(1);\nmiSet.add(\"Hola\");\nmiSet.add(true);\n\nconsole.log(miSet);\n// Resultado: Set { 1, 'Hola', true }\n\n\n//BORRADO EN UN SET\n//Para eliminar elementos de un Set, puedes utilizar el método delete:\nlet miSet2 = new Set([1, 2, 3, 4, 5]);\n\nmiSet.delete(3);\n\nconsole.log(miSet2);\n// Resultado: Set { 1, 2, 4, 5 }\n\n\n//ACTUALIZACION DE UN SET\n//No hay un método específico para actualizar un elemento en un Set porque, \n//por diseño, los elementos en un Set son únicos y no se permiten duplicados. \n//Si se necesitara actualizar un valor, se puede eliminar el antiguo y añadir \n//el nuevo.\nlet miSet3 = new Set([1, 2, 3]);\n\nmiSet.delete(2);\nmiSet.add(4);\n\nconsole.log(miSet3);\n// Resultado: Set { 1, 3, 4 }\n\n\n//ORDENACION DE UN SET\n//Los Sets en JavaScript no tienen un método sort porque, a diferencia de los \n//arrays, los Sets no mantienen un orden específico. Sin embargo, si SE necesita\n//obtener un array ordenado a partir de un Set, Se puede convertir en un array y \n//luego usar el método sort de los arrays.\nlet miSet4 = new Set([3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]);\n\nlet arrayOrdenado = Array.from(miSet4).sort((a, b) => a - b);\n\nconsole.log(arrayOrdenado);\n// Resultado: [1, 2, 3, 4, 5, 6, 9]\n\n//En este ejemplo, Array.from(miSet) convierte el Set en un array, y luego sort \n//ordena ese array numéricamente.\n\n\n//*  4 MAPS ----- \n\n/*\n\nEn JavaScript, un Map es una estructura de datos que te permite almacenar pares clave-valor, \ndonde cada clave y cada valor pueden ser de cualquier tipo. A diferencia de los Sets, que solo \nalmacenan valores únicos, los Mapas permiten asociar valores específicos a claves y proporcionan\nmétodos para la inserción, borrado, actualización y recuperación de estos pares clave-valor.\n\n*/\n\n// SINTAXIS:\n\n// Creacion del map\nlet miMapa = new Map();\n\n// Inserción de pares clave-valor\n\nmiMapa.set(\"clave1\", \"valor1\");\nmiMapa.set(42, \"Hola\");\nmiMapa.set(true, [1, 2, 3]);\n\nconsole.log(miMapa);\n\n// Resultado: Map { 'clave1' => 'valor1', 42 => 'Hola', true => [ 1, 2, 3 ] }\n\n/*\n\nCaracteristicas\n\nClaves Únicas: Cada clave en un Map es única, lo que significa que no puede haber duplicados.\nIteración: Puedes iterar sobre los pares clave-valor de un Map utilizando bucles o métodos como forEach.\n\n*/\n\nmiMapa.forEach((valor, clave) => {\n  console.log(`${clave} : ${valor}`);\n});\n\n// Resultado:\n// clave1 : valor1\n// 42 : Hola\n// true : 1,2,3\n\n/*\n\nOperaciones Básicas: Los Mapas proporcionan métodos como set para añadir pares clave-valor, \ndelete para eliminar pares, get para obtener el valor asociado a una clave, y más.\n\n*/\n\nconsole.log(miMapa.get(\"clave1\")); // Imprime 'valor1'\nmiMapa.delete(42);\nconsole.log(miMapa.has(true));     // Imprime true\n\n\n//Tamaño Dinámico: Los Mapas pueden cambiar de tamaño dinámicamente a medida que se añaden \n//o eliminan pares clave-valor.\n\nconsole.log(miMapa.size); // Imprime 2 (después de la eliminación del par con clave 42)\n\n/*\n\nLos Mapas son especialmente útiles cuando necesitas almacenar y recuperar datos asociados \na claves específicas y proporcionan una alternativa a los objetos cuando las claves no \nnecesariamente son cadenas de texto y se requiere un comportamiento más predecible en términos \nde orden y manipulación de datos.\n\n*/\n\n//INSERCION EN MAPS\n//Para insertar pares clave-valor en un Map, puedes utilizar el método set:\nlet miMapa2 = new Map();\n\n// Inserción de pares clave-valor\nmiMapa2.set(\"clave1\", \"valor1\");\nmiMapa2.set(42, \"Hola\");\nmiMapa2.set(true, [1, 2, 3]);\n\nconsole.log(miMapa2);\n// Resultado: Map { 'clave1' => 'valor1', 42 => 'Hola', true => [ 1, 2, 3 ] }\n\n\n//BORRADO EN MAPAS\n//Para eliminar pares clave-valor de un Map, puedes utilizar el método delete:\nmiMapa2.delete(42);\n\nconsole.log(miMapa2);\n// Resultado: Map { 'clave1' => 'valor1', true => [ 1, 2, 3 ] }\n\n\n\n//ACTUALIZACION EN MAPS\n//Para actualizar el valor asociado a una clave específica, simplemente vuelves a utilizar \n//el método set con la misma clave:\nmiMapa2.set(\"clave1\", \"nuevoValor\");\n\nconsole.log(miMapa2);\n// Resultado: Map { 'clave1' => 'nuevoValor', true => [ 1, 2, 3 ] }\n\n\n// ORDENACION O RECORRIDO ORDENADO\n//Aunque los Mapas en JavaScript mantienen el orden de inserción, si queremos recorrer \n//los pares clave-valor en un orden específico, se puede hacer utilizando el método \n//entries() y, por ejemplo, ordenar el array resultante.\nlet miMapa3 = new Map([\n  ['z', 1],\n  ['a', 2],\n  ['c', 3]\n]);\n\n// Recorrer los pares clave-valor en orden alfabético\nlet paresOrdenados = Array.from(miMapa3.entries()).sort((a, b) => a[0].localeCompare(b[0]));\n\nconsole.log(paresOrdenados);\n// Resultado: [ [ 'a', 2 ], [ 'c', 3 ], [ 'z', 1 ] ]\n\n/*\nEn este ejemplo, Array.from(miMapa.entries()) convierte los pares clave-valor en un array, y \nluego el método sort se utiliza para ordenar el array alfabéticamente según las claves.\neste enfoque proporcionará un array ordenado, pero los Mapas en sí \nmismos mantendrán el orden de inserción original.\n*/\n\n\n//*  5 COLAS(QUEQUES) Y PILAS(STACKS) ----- \n\n/*\n\nEn JavaScript, las colas (queues) y pilas (stacks) son estructuras \nde datos comúnmente implementadas utilizando arrays o linked lists. Estas estructuras se \nutilizan para organizar y gestionar datos de manera específica.\n\n*/\n\n//PILAS(STACKS)\n\n/*\nUna pila es una estructura de datos en la que los elementos se añaden y eliminan siguiendo \nel principio de Last In, First Out (LIFO), es decir, el último elemento que se añade es el \nprimero en ser eliminado.\nEn JavaScript, se puede implementar una pila utilizando un array y utilizando los métodos push \npara añadir elementos al final y pop para eliminar el último elemento añadido.\n\n*/\nlet pila = [];\n\n// Añadir elementos a la pila\npila.push(1);\npila.push(2);\npila.push(3);\n\nconsole.log(pila);  // Resultado: [1, 2, 3]\n\n// Eliminar el último elemento añadido (LIFO)\nlet elementoEliminado = pila.pop();\nconsole.log(elementoEliminado);  // Resultado: 3\nconsole.log(pila);  // Resultado: [1, 2]\n\n//COLAS (QUEQUE)\n\n/*\n\nUna cola es una estructura de datos en la que los elementos se añaden al final y se eliminan \ndesde el principio, siguiendo el principio de First In, First Out (FIFO), es decir, el \nprimer elemento que se añade es el primero en ser eliminado.\nEn JavaScript, se puede implementar una cola utilizando un array y utilizando los métodos push \npara añadir elementos al final y shift para eliminar el primer elemento añadido.\n\n*/\n\nlet cola = [];\n\n// Añadir elementos a la cola\ncola.push(1);\ncola.push(2);\ncola.push(3);\n\nconsole.log(cola);  // Resultado: [1, 2, 3]\n\n// Eliminar el primer elemento añadido (FIFO)\nlet elementoFuera = cola.shift();\nconsole.log(elementoFuera);  // Resultado: 1\nconsole.log(cola);  // Resultado: [2, 3]\n\n\n\n//*  6 STRINGS ----- \n\n/*\n\nEn JavaScript, un String es una estructura de datos que representa una secuencia de caracteres. \nLos strings son utilizados para almacenar y manipular texto en el lenguaje. Cada carácter en un \nstring tiene un índice numérico, comenzando desde 0 para el primer carácter.\n\n*/\n\nlet miString = \"Hola, mundo!\";\n\n// Acceder a caracteres por índice\nconsole.log(miString[0]); // Resultado: \"H\"\n\n// Longitud de un string\nconsole.log(miString.length); // Resultado: 13\n\n// Algunos Métodos de string\nconsole.log(miString.toUpperCase());    // Resultado: \"HOLA, MUNDO!\"\nconsole.log(miString.indexOf(\"mundo\")); // Resultado: 6\nconsole.log(miString.split(\", \"));      // Resultado: [\"Hola\", \"mundo!\"]\n\n/*\n\nCaracteristicas\n\nInmutabilidad: Los strings en JavaScript son inmutables, lo que significa que no \npueden ser modificados directamente una vez creados. Cualquier operación que parezca \nmodificar un string, en realidad crea uno nuevo.\n\nConcatenación: Puedes concatenar strings utilizando el operador + o el método concat().\n\nInterpolación de cadenas (Template literals): Puedes utilizar template literals para \ncrear strings de manera más legible e incluir expresiones dentro del string.\n\nMétodos de manipulación: JavaScript proporciona diversos métodos para manipular y trabajar con strings\n\n*/\n\n//INSERCION EN STRINGS\n//Para \"insertar\" caracteres en un string, puedes utilizar la concatenación de strings o \n//la interpolación de cadenas (template literals):\nlet original = \"Hola\";\nlet insertado = original + \", mundo!\";\nconsole.log(insertado); // Resultado: \"Hola, mundo!\"\n\n// O usando template literals\nlet insertadoTemplate = `${original}, mundo!`;\nconsole.log(insertadoTemplate); // Resultado: \"Hola, mundo!\"\n\n\n//BORRADO DE STRINGS\n//Para \"borrar\" caracteres de un string, puedes utilizar el método slice para crear un nuevo \n//string excluyendo ciertos caracteres:\nlet original2 = \"Hola, mundo!\";\nlet borrado = original2.slice(0, 5); // Elimina los caracteres desde el índice 5 en adelante\nconsole.log(borrado); // Resultado: \"Hola\"\n\n//ACTUALIZACION DE STRINGS\n//Para \"actualizar\" caracteres en un string, también puedes utilizar el método slice para \n//dividir el string en partes, modificar la parte deseada y luego concatenarlas de nuevo:\nlet original3 = \"Hola, mundo!\";\nlet actualizado = original3.slice(0, 5) + \" JavaScript!\";\nconsole.log(actualizado); // Resultado: \"Hola JavaScript!\"\n\n//ORDENACION DE STRINGS\n//Para \"ordenar\" caracteres en un string, puedes convertir el string en un array, ordenar \n//el array y luego convertirlo de nuevo a un string:\nlet original4 = \"javascript\";\nlet ordenado = original4.split('').sort().join('');\nconsole.log(ordenado); // Resultado: \"aaccijprstv\"\n\n\n\n//* 7. DIFICULTAD EXTRA -----\n\n/*\n\nCrea una agenda de contactos por terminal.\n  - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n  - Cada contacto debe tener un nombre y un número de teléfono.\n  - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n    los datos necesarios para llevarla a cabo.\n  - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n    (o el número de dígitos que quieras)\n  - También se debe proponer una operación de finalización del programa.\n\n*/\n\n// NOTA: \n\n//Se puede hacer con prompt, para capturar una entrada dinámica\n//del usuario, pero tocaria vincular html a este documento, y solo estamos usando\n//archivos Js, asi que se resolverá con código duro y sin ciclo while, pues no \n//existirá entrada de datos dinámica, y aun no se como hacerlo por terminal con Js\n\nconst miAgenda = () => {\n\n  let agenda = new Map();\n\n  //Datos en código duro \n  let option  = 3;  // Menú de opciones del 1 al 5\n  let name    = 'Fabian';\n  let number  = 3188473006;\n  let name2   = 'Luisa';\n  let number2 = 3188294406;\n \n  console.log('1. Buscar');\n  console.log('2. Insertar');\n  console.log('3. Actualizar');\n  console.log('4. Eliminar');\n  console.log('5. Salir');\n\n  if( option >= 1 && option <= 5 ){\n\n      switch (option) {\n        case 1:\n          console.log('Insertando datos...');\n          if (name !== '' && !isNaN(number) && number.toString().length <= 11) {\n            agenda.set(name, number);\n            console.log( agenda );\n          } else {\n            console.log('Inserte datos válidos');\n          }\n          break;\n        case 2:\n          console.log('Realizando la búsqueda...');\n          if (name !== '' && !isNaN(number) && number.toString().length <= 11){\n            agenda.set(name, number);\n          }\n          if( agenda.has(name) ){\n            console.log( `El numero de ${name} es : ${agenda.get(name)}` );\n          }else{\n            console.log('El contacto no esta registrado');\n          }\n          break;\n        case 3:\n          console.log('Actualizando información...');\n          agenda.set(name2,number2);\n          console.log( `El numero de ${name2} es : ${agenda.get(name2)}` );\n          break;\n        case 4:\n          console.log('Eliminando datos...');\n          agenda.delete(name);\n          console.log( agenda );\n          break;\n        case 5:\n          console.log('Saliendo de la agenda ...');\n          break;\n        default:\n          break;\n    }\n\n  } else {\n    console.log('Opción no válida');\n    console.log('Digite opciones del 1 al 5');\n  }\n\n};\n\n// Llamada a la función\nmiAgenda();\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/C-BLSKV.js",
    "content": "//#03 Ejercicio: Estructura de Datos.\n// Retos de Programación con MoureDev.\n// Creador: César Biliškov.\n/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n// Desarrollo:\n\n// Ejemplos de estructuras de datos:\n\nlet arrayEjemplo = [10, 20, 30, 40, 50]; \nlet objetoEjemplo = { nombre: \"César Biliškov\", edad: 33, ciudad: \"ConCon, Valparaiso\" };\nlet setEjemplo = new Set([60, 70, 80, 90, 100]); \n\nconsole.log(\"Array:\", arrayEjemplo);\nconsole.log(\"Objeto:\", objetoEjemplo);\nconsole.log(\"Set:\", Array.from(setEjemplo));\n\narrayEjemplo.push(60); \nconsole.log(\"Array después de la inserción:\", arrayEjemplo);\n\nobjetoEjemplo.edad = 33; \nconsole.log(\"Objeto después de la actualización:\", objetoEjemplo);\n\nsetEjemplo.add(70); \nconsole.log(\"Set después de la inserción:\", Array.from(setEjemplo));\n\narrayEjemplo.pop();\nconsole.log(\"Array después del borrado:\", arrayEjemplo);\n\ndelete objetoEjemplo.ciudad;\nconsole.log(\"Objeto después del borrado:\", objetoEjemplo);\n\n\nsetEjemplo.delete(60);\nconsole.log(\"Set después del borrado:\", Array.from(setEjemplo));\n\narrayEjemplo.sort((a, b) => b - a);\nconsole.log(\"Array después de la ordenación:\", arrayEjemplo);\n\n// Dificultad extra de ejercicio:\n\nconst readline = require('readline');\n\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout\n});\n\nlet agenda = [\n  { nombre: \"Aquiles Dpic\", telefono: \"1212121212\" },\n  { nombre: \"María Jose Radic\", telefono: \"17771117771\" },\n  { nombre: \"Vicente Novak\", telefono: \"5555544441\" }\n];\n\nfunction mostrarContactos() {\n  console.log(\"Lista de contactos:\");\n  agenda.forEach((contacto, index) => {\n    console.log(`${index + 1}. Nombre: ${contacto.nombre}, Teléfono: ${contacto.telefono}`);\n  });\n}\n\nfunction agregarContacto() {\n  rl.question(\"Ingrese el nombre del contacto: \", (nombre) => {\n    rl.question(\"Ingrese el número de teléfono: \", (telefono) => {\n      if (/^\\d+$/.test(telefono) && telefono.length <= 11) {\n        agenda.push({ nombre, telefono });\n        console.log(\"Contacto agregado con éxito.\");\n        mostrarContactos();\n      } else {\n        console.log(\"Número de teléfono no válido.\");\n      }\n      mostrarMenu();\n    });\n  });\n}\n\nfunction buscarContacto() {\n  rl.question(\"Ingrese el nombre del contacto a buscar: \", (nombre) => {\n    const contactoEncontrado = agenda.find(contacto => contacto.nombre.toLowerCase() === nombre.toLowerCase());\n    if (contactoEncontrado) {\n      console.log(`Contacto encontrado - Nombre: ${contactoEncontrado.nombre}, Teléfono: ${contactoEncontrado.telefono}`);\n    } else {\n      console.log(\"Contacto no encontrado.\");\n    }\n    mostrarMenu();\n  });\n}\n\nfunction actualizarContacto() {\n  rl.question(\"Ingrese el nombre del contacto a actualizar: \", (nombre) => {\n    const indiceContacto = agenda.findIndex(contacto => contacto.nombre.toLowerCase() === nombre.toLowerCase());\n    if (indiceContacto !== -1) {\n      rl.question(\"Ingrese el nuevo número de teléfono: \", (nuevoTelefono) => {\n        if (/^\\d+$/.test(nuevoTelefono) && nuevoTelefono.length <= 11) {\n          agenda[indiceContacto].telefono = nuevoTelefono;\n          console.log(\"Contacto actualizado con éxito.\");\n          mostrarContactos();\n        } else {\n          console.log(\"Número de teléfono no válido.\");\n        }\n        mostrarMenu();\n      });\n    } else {\n      console.log(\"Contacto no encontrado.\");\n      mostrarMenu();\n    }\n  });\n}\n\nfunction eliminarContacto() {\n  rl.question(\"Ingrese el nombre del contacto a eliminar: \", (nombre) => {\n    const indiceContacto = agenda.findIndex(contacto => contacto.nombre.toLowerCase() === nombre.toLowerCase());\n    if (indiceContacto !== -1) {\n      agenda.splice(indiceContacto, 1);\n      console.log(\"Contacto eliminado con éxito.\");\n    } else {\n      console.log(\"Contacto no encontrado.\");\n    }\n    mostrarMenu();\n  });\n}\n\nfunction mostrarMenu() {\n  console.log(\"\\nSeleccione una operación:\");\n  console.log(\"1. Mostrar contactos\");\n  console.log(\"2. Agregar contacto\");\n  console.log(\"3. Buscar contacto\");\n  console.log(\"4. Actualizar contacto\");\n  console.log(\"5. Eliminar contacto\");\n  console.log(\"6. Salir\");\n\n  rl.question(\"Ingrese el número de la operación deseada: \", (opcion) => {\n    switch (opcion) {\n      case '1':\n        mostrarContactos();\n        mostrarMenu();\n        break;\n      case '2':\n        agregarContacto();\n        break;\n      case '3':\n        buscarContacto();\n        break;\n      case '4':\n        actualizarContacto();\n        break;\n      case '5':\n        eliminarContacto();\n        break;\n      case '6':\n        rl.close();\n        break;\n      default:\n        console.log(\"Opción no válida. Intente nuevamente.\");\n        mostrarMenu();\n    }\n  });\n}\n\nmostrarMenu();\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/Carolhs92.js",
    "content": "import logo from './logo.png';\nimport './App.css';\n\n\nfunction App() {\n// Crear la lista\nconst mi_lista = [1, 2, 3];\n\n// Agregar un nuevo elemento a la lista\nmi_lista.push(4); \n\n// Borrar un elemento de la lista\nconst lista_menos = mi_lista.splice(2, 1);\n\n// Actualizar un elemento de la lista\nconst lista_mas = mi_lista[5] = 7;\n\n// Ordenar la lista\nmi_lista.sort();\n\n\n//Agenda de teléfono\n // Lista de contactos inicial\n  const contacts = [];\n\n // Función para validar el número de teléfono\nfunction isValidPhoneNumber(number) {\n  return /^[0-9]{1,11}$/.test(number);\n}\n\n // Función para agregar un contacto\nfunction addContact() {\n  const name = document.getElementById('name').value.trim();\n  const phoneNumber = document.getElementById('number').value.trim();\n\n  if (isValidPhoneNumber(phoneNumber)) {\n    contacts.push({ name, phoneNumber });\n    alert('Contacto agregado.');\n    clearForm();\n    showContacts();\n  } else {\n    alert('Número de teléfono inválido. Debe ser numérico y de hasta 11 dígitos.');\n  }\n}\n\n // Función para actualizar un contacto\nfunction updateContact() {\n  const name = prompt('Introduce el nombre del contacto a actualizar:');\n  const phoneNumber = prompt('Introduce el nuevo número de teléfono:');\n\n  if (isValidPhoneNumber(phoneNumber)) {\n    const index = contacts.findIndex(contact => contact.name.toLowerCase() === name.toLowerCase());\n    if (index !== -1) {\n      contacts[index].phoneNumber = phoneNumber;\n      alert('Contacto actualizado.');\n    } else {\n      alert('No se encontró el contacto.');\n    }\n      showContacts();\n  } else {\n    alert('Número de teléfono inválido. Debe ser numérico y de hasta 11 dígitos.');\n  }\n}\n\n // Función para eliminar un contacto\nfunction deleteContact() {\n  const name = prompt('Introduce el nombre del contacto a eliminar:');\n  const index = contacts.findIndex(contact => contact.name.toLowerCase() === name.toLowerCase());\n\n  if (index !== -1) {\n    contacts.splice(index, 1);\n      alert('Contacto eliminado.');\n      showContacts();\n  } else {\n    alert('No se encontró el contacto.');\n  }\n}\n\n // Función para mostrar todos los contactos\nfunction showContacts() {\n  const contactListDiv = document.getElementById('contact-list');\n  contactListDiv.innerHTML = ''; // Limpiar lista actual\n\n  if (contacts.length > 0) {\n    const ul = document.createElement('ul');\n    contacts.forEach(contact => {\n      const li = document.createElement('li');\n      li.textContent = `Nombre: ${contact.name}, Teléfono: ${contact.phoneNumber}`;\n      ul.appendChild(li);\n    });\n    contactListDiv.appendChild(ul);\n  } else {\n    contactListDiv.textContent = 'No hay contactos.';\n  }\n}\n\n // Función para limpiar el formulario\nfunction clearForm() {\n  document.getElementById('name').value = '';\n  document.getElementById('number').value = '';\n}\n\n  return (\n    \n    <div class=\"App\">\n      <header class=\"App-header\">\n        <img src={logo} class=\"App-logo\" alt=\"logo\" />\n      </header>\n      <main>\n        <section>\n          <p>Oscar es el  <small class='resultado'>[{mi_lista[0]}]</small>  de su clase.</p>\n          <p>Pero ha venido una persona nueva a la clase <small class='resultado'>[{mi_lista[2]}]</small> que se llama Lucas.</p>\n          <p>Este mes Andrés tuvo que abandonar. Ahora somos <small class='resultado'>[{lista_menos}]</small></p>\n          <p>Han venido varias personas más a la clase y ahora somos <small class='resultado'>[{lista_mas}]</small></p>\n          <p>Despues de abandonos y llegadas a la clase ahora la lista queda así: <small class='resultado'>[{mi_lista}]</small></p>\n        </section>\n        <section>\n          <h1>Contactos</h1>\n          <div>\n            <div class='group-input'>\n              <div class=\"form-group\">\n                  <label htmlFor=\"name\">Nombre: </label>\n                  <input type=\"text\" id=\"name\"/>\n              </div>\n              <div class=\"form-group\">\n                  <label htmlFor=\"number\">Número de Teléfono: </label>\n                  <input type=\"text\" id=\"number\"/>\n              </div>\n              <button onClick={addContact}>Agregar Contacto</button>\n            </div>\n              \n              \n              <button onClick={updateContact}>Actualizar Contacto</button>\n              <button onClick={deleteContact}>Eliminar Contacto</button>\n              <button onClick={showContacts}>Mostrar Contactos</button>\n          </div>\n\n          <div id=\"contact-list\" class=\"contact-list\"></div>\n        </section>\n        \n      </main>\n    </div>\n  );\n}\n\nexport default App;\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/CaveroBrandon.js",
    "content": "// const { get } = require('http');\nconst readline = require('readline');\n\n/*\nEJERCICIO:\n- Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n- Utiliza operaciones de inserción, borrado, actualización y ordenación.\n*/\n// --- List ---\n// Population, update operations\nlet fruitsList = ['Banana', 'Apple'];   // Creating an array\nfruitsList[0] = 'Orange';               // Modifying an element based on its position\nfruitsList.push('Banana');              // Adding an element to the end\nfruitsList.unshift('Banana');           // Adding an element to the beginning\nfruitsList.splice(1, 0, 'Strawberry')   // Adding an element on an specific position\nfruitsList.splice(4, 1, 'Pear')         // Replacing an element on an specific position\nfruitsList.splice(0, 0, 'Grapes', 'Watermelon') // Adding more than one element starting on an specific position\nlet groceryList = new Array();          // Creating an array\ngroceryList = fruitsList.concat(['Tomato', 'Pepper'])   // Adding another array to the first array\n\n// Removing operations\ngroceryList = groceryList.slice(0,3);   // Slicing the array\ngroceryList.pop();                      // Removing the last element\ngroceryList.shift();                    // Removing the first element\ngroceryList.splice(1, 1);               // Removing an element of an specific position\ngroceryList.reverse();                  // Reversing the array\n\n// Sorting operation\nlet numberList = [10, 2, 3, 5, 73];\nnumberList.sort((a, b) => a - b);       // Sorting the array ascending order\nnumberList.sort((a, b) => b - a);       // Sorting the array descending order\n\n// --- Maps ---\nconst phoneCharacteristics = new Map();         // Creating a map\nphoneCharacteristics.set('Battery', '100');     // Adding an element to the map\nphoneCharacteristics.set('Portability', true);  // Adding an element to the map\nphoneCharacteristics.set('Wireless', false);    // Adding an element to the map\nphoneCharacteristics.set('PhoneNumber', 12321)  // Adding an element to the map\nphoneCharacteristics.delete('Battery');         // Remove an element using it's key\nlet phonePortability = phoneCharacteristics.get('Portability'); // Get an element vßalue using it's key\n\n// --- Set ---\nconst user = new Set(); // Creating a set\nuser.add('name');       // Adding an element to the set\nuser.add('age');        // Adding an element to the set\nuser.add('weight');     // Adding an element to the set\nuser.delete('weight');  // Removing an element of the set\nuser.clear();           // Clear all the set\n\n\n// --- Objects ---\nlet newCar = {color: 'red', hasWindows: true, year: 2025};  // Creating an object\nnewCar.electric = false;    // Adding a new element to the object\nnewCar.color = 'Blue';      // Updating a value based on a key\ndelete newCar.hasWindows;   // Removing an element\nisColorKeyAvailable = 'color' in newCar // Verifying that an object has a value\n\n/*\nDIFICULTAD EXTRA (opcional):\nCrea una agenda de contactos por terminal.\n- Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n- Cada contacto debe tener un nombre y un número de teléfono.\n- El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\nlos datos necesarios para llevarla a cabo.\n- El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n(o el número de dígitos que quieras)\n- También se debe proponer una operación de finalización del programa.\n*/\nlet agenda = [];\n\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout,\n});\n\nfunction getUserInput(questionText) {\n    return new Promise((resolve) => {\n        rl.question(questionText, (ans) => {\n            resolve(ans);\n        });\n    });\n}\n\nasync function registerContact() {\n    let contact = {};\n    const contactName = await getUserInput('Enter the contact name: ');\n    const contactPhoneNumber = await getUserInput('Enter contact phone number: ');\n    if (isNaN(contact.phoneNumber) || contact.phoneNumber.toString().split('').length > 11) {\n        console.log('The entered value must be a number with less than 11 digits');\n        showMenu();\n    }\n    else {\n        contact = {name: contactName, phoneNumber: contactPhoneNumber};\n        agenda.push(contact);\n        console.log('---------------------------------');\n        console.log('New entry registered successfully');\n        console.log('Contact name: ' + contact.name);\n        console.log('Contact phone number: ' + contact.phoneNumber);\n        console.log('---------------------------------');\n        showMenu();\n    }\n}\n\nasync function updateContact(nameToSearch) {\n    const contact = agenda.find(contact => contact.name === nameToSearch);\n    if (contact) {\n        contact.phoneNumber = await getUserInput('Enter new phone number: ');\n        if (isNaN(contact.phoneNumber) || contact.phoneNumber.toString().split('').length > 11) {\n            console.log('The entered value must be a number with less than 11 digits');\n            showMenu();\n        }\n        else {\n            console.log('---------------------------------');\n            console.log('New phone number registered successfully');\n            console.log('Contact name: ' + contact.name);\n            console.log('Contact phone number: ' + contact.phoneNumber);\n            console.log('---------------------------------');\n            showMenu();\n        }\n    }\n    else {\n        contactNotFoundMessage();\n    }\n}\n\nasync function removeContact(nameToSearch) {\n    const contact = agenda.find(contact => contact.name === nameToSearch);\n    if (contact) {\n        console.log('---------------------------------');\n        console.log('The contact was succesfully removed from the agenda');\n        console.log('Contact name: ' + contact.name);\n        console.log('Contact phone number: ' + contact.phoneNumber);\n        const index = agenda.indexOf(contact);\n        agenda.splice(index, 1);\n        console.log('---------------------------------');\n        showMenu();\n    }\n    else {\n        contactNotFoundMessage();\n    }\n}\n\nasync function getPhoneNumberByName(nameToSearch) {\n    // Find the contact with the matching name in the global 'agenda' list\n    const contact = agenda.find(contact => contact.name === nameToSearch);\n    if (contact) {\n        console.log('---------------------------------');\n        console.log('Contact \"' + nameToSearch + '\" found in the agenda');\n        console.log(nameToSearch + ': ' + contact.phoneNumber);\n        console.log('---------------------------------');\n        showMenu()\n    }\n    else {\n        contactNotFoundMessage();\n    }\n}\n\nfunction isAgendaEmpty() {\n    if (agenda.length === 0) {\n        console.log('---------------------------------');\n        console.log('Agenda is empty, try adding some contacts first');\n        console.log('---------------------------------');\n        showMenu();\n    }\n}\n\nfunction contactNotFoundMessage() {\n    console.log('---------------------------------');\n    console.log('The contact was not found in the agenda');\n    console.log('---------------------------------');\n    showMenu();\n}\n\nasync function showMenu() {\n    console.log('Select an option');\n    console.log('1. Register a new contact (Insert)');\n    console.log('2. Update an existing contact');\n    console.log('3. Remove an existing contact');\n    console.log('4. Search a contact')\n    console.log('5. Exit');\n    const option = await getUserInput('Select your option (1-5): ');\n    switch (option) {\n        case '1':\n            registerContact();\n            break;\n        case '2':\n            isAgendaEmpty();\n            const nameToUpdate = await getUserInput('Enter the contact name to update: ');\n            updateContact(nameToUpdate);    \n            break;\n        case '3':\n            isAgendaEmpty();\n            const nameToRemove = await getUserInput('Enter the contact name to remove: ');\n            removeContact(nameToRemove);\n            break;\n        case '4':\n            isAgendaEmpty();\n            const nameToSearch = await getUserInput('Enter the contact name to search: ');\n            getPhoneNumberByName(nameToSearch);\n            break;\n        case '5':\n            process.exit(0);\n        default:\n            console.log('---------------------------------');\n            console.log('Invalid option. Please select a valid option (1-5)');\n            console.log('---------------------------------');\n            showMenu();\n    }\n}\n\nshowMenu();\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/CesarCarmona30.js",
    "content": "/**\n * EJERCICIO\n */\n\n// Arreglos\nlet my_array = [0, 5, 6, 2, 7, 2, 6, 8, 9, 4, 3, 3];\n\n// Objetos\nlet my_object = {\n    name: \"César\",\n    surname: \"Carmona\",\n    age: 20,\n};\n\n// Mapas\nlet my_map = new Map();\nmapa.set(\"name\", \"Leroy\");\nmapa.set(\"surname\", \"González\");\nmapa.set(\"age\", 21);\n\n// Colecciones\nlet my_set = new Set([\"Mexico, España, Argentina, Colombia, Chile, Peru\"]);\n\n// Operaciones\n// Inserción\nmy_array.push(6);\nmy_object.city = \"Mexico City\";\nmy_map.set(\"country\", \"Mexico\");\nmy_set.add(\"Ecuador\");\n\n// Actualización{\nmy_array[0] = 10;\nmy_object.surname = \"González\";\nmy_map.set(\"age\", 20);\n\n// Ordenamiento\nmy_array.sort();\n\n// Eliminación\nmy_array.pop();\ndelete my_object.city;\nmy_map.delete(\"country\");\nmy_set.delete(\"España\");\n\n// DIFICULTAD EXTRA\nfunction myContacts() {\n    let agenda = []\n    let run = true\n    while (run) {\n\n        const operation = prompt(`Ingrese la operación a realizar:\n            1. Buscar contacto\n            2. Insertar contacto\n            3. Actializar contacto\n            4. Eliminar contacto\n            5. Salir\n        `)\n\n        if (operation === \"1\") {\n\n            if (agenda.length === 0) {\n                console.log(\"Agenda vacía\")\n                continue\n            }\n            const name = prompt(\"Ingrese el nombre del contacto a buscar:\")\n\n            for (let i = 0; i < agenda.length; i++) {\n                if (agenda[i].name === name) {\n                    console.log(\"Contacto encontrado:\", agenda[i])\n                } else {\n                    console.log(\"Contacto no encontrado\")\n                }\n            }\n        } else if (operation === \"2\") {\n\n            const name = prompt(\"Ingrese el nombre del contacto a insertar:\")\n            const phone = prompt(\"Ingrese el teléfono del contacto a insertar:\")\n\n            if (!/^\\d{6,11}$/.test(phone)) {\n                console.log(\"El número de teléfono no es válido.\");\n                break;\n            }\n\n            const contact = {\n                name: name,\n                phone: phone\n            }\n\n            agenda.push(contact)\n            console.log(\"Contacto insertado:\", contact)\n\n\n        } else if (operation === \"3\") {\n            const name = prompt(\"Ingrese el nombre del contacto a actualizar:\")\n            for (let i = 0; i < agenda.length; i++) {\n                if (agenda[i].name === name) {\n                    agenda[i].phone = prompt(\"Ingrese el nuevo teléfono del contacto:\")\n                    console.log(\"Contacto actualizado:\", agenda[i])\n                } else {\n                    console.log(\"Contacto no encontrado\")\n                }\n            }\n        } else if (operation === \"4\") {\n            const name = prompt(\"Ingrese el nombre del contacto a eliminar:\")\n            for (let i = 0; i < agenda.length; i++) {\n                if (agenda[i].name === name) {\n                    agenda.splice(i, 1)\n                    console.log(\"Contacto eliminado:\")\n                } else {\n                    console.log(\"Contacto no encontrado\")\n                }\n            }\n        } else if (operation === \"5\") {\n            run = false;\n            console.log(\"Agenda creada:\", agenda)\n            break;\n        } else {\n            console.log(\"Operación no válida\")\n        }\n    }\n    console.log(\"Agenda creada:\", agenda)\n}"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/DAVstudy.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\n// Arrays\n\n// Crear un array\nlet elements = [\"aire\", \"fuego\", \"tierra\", \"agua\"];\nconsole.log(elements);\n\n// longitud\nconsole.log(elements.length);\n\n// pop sacar ultimo elemento\nlet water = elements.pop();\nconsole.log(water);\nconsole.log(elements);\n\n// push agregar un elemento al final\nelements.push(water);\nconsole.log(elements);\n\n// pop sacar primer elemento\nlet air = elements.shift();\nconsole.log(air);\nconsole.log(elements);\n\n// push agregar un elemento al inicio\nelements.unshift(air);\nconsole.log(elements);\n\n// Recorrer arreglo\nelements.forEach((element) => {\n  console.log(element);\n});\n\nfor (const element of elements) {\n  console.log(element);\n}\n\n// clear\nelements = [];\nelements.length = 0; // Alt\nconsole.log(elements);\n\n// slice\nelements.push(\"aire\", \"fuego\", \"tierra\", \"agua\");\nconsole.log(elements);\n\nlet myNewArray = elements.slice(1, 3); // Permite extraer elemento indicando el indice incial y el final pero el ultimo indice no cuenta si no el anterior\nconsole.log(myNewArray);\n\n// splice\n\nelements.splice(1, 2, \"tierra\"); // Elimina elementos en el rango y agrega un nuevo elemento en la posicion intermedia\nconsole.log(elements);\n\n// Copiar array\n\nlet otherArray = [...elements];\nconsole.log(otherArray);\n\n// Set\n\n// Declaracion\nlet mySet = new Set();\nconsole.log(mySet);\n\n// Inicialización\nmySet = new Set([\n  \"Elemento 1\",\n  \"Elemento 2\",\n  \"Elemento 3\",\n  \"Elemento 4\",\n  \"Elemento 5\",\n]);\nconsole.log(mySet);\n\n// Métodos comunes\n\n// add & delete\n\nmySet.add(\"Elemento 6\"); // En Js el add añade el elemento al final, manteniendo el orden\nconsole.log(mySet);\n\nconsole.log(mySet.delete(\"Elemento 6\")); // Elimina el elemento pero no utiliza el indice, debe ser con el valor del elemento que se quiere borrar\n// Ademas retornara un true si existe el elemento y lo elimino, si no devuelve false.\nconsole.log(mySet);\n\n// NOTA: No hay acceso al indice a diferencia de los Array\n\n// has\nconsole.log(mySet.has(\"Elemento 6\")); // Verifica si existe el elemento\nconsole.log(mySet.has(\"Elemento 1\"));\n\n// Size\nconsole.log(mySet.size); // Tamaño del set\n\n// Convertir Set en Array\nlet myArray = Array.from(mySet);\nconsole.log(myArray);\n\n// Convertir Array en Set\nmySet = new Set(myArray);\nconsole.log(mySet);\n\n// Map\n\n// Map\n\n// Declaración\nlet myMap = new Map();\nconsole.log(myMap);\n\n// Inicialización\nmyMap = new Map([\n  [\"key 1\", \"value 1\"],\n  [\"key 2\", \"value 2\"],\n  [\"key 3\", \"value 3\"],\n]);\nconsole.log(myMap);\n\n// Métodos y propiedades\n\n// set\nmyMap.set(\"key 4\", \"value 4\");\nconsole.log(myMap);\n\nmyMap.set(\"key 2\", \"new value 2\");\nconsole.log(myMap);\n\n// get\nconsole.log(myMap.get(\"key 1\"));\nconsole.log(myMap.get(\"key 5\"));\n\n// has\nconsole.log(myMap.has(\"key 1\"));\nconsole.log(myMap.has(\"key 5\"));\n\n// delete\nmyMap.delete(\"key 4\");\nconsole.log(myMap);\n\n// keys\nconsole.log(myMap.keys());\n\n// values\nconsole.log(myMap.values());\n\n// entries\nconsole.log(myMap.entries());\n\n// size\nconsole.log(myMap.size);\n\n// clear\nmyMap.clear();\nconsole.log(myMap);\n\n// Objects\n\n// Sintaxis\nlet person = {\n  // Propiedades clave : valor\n  name: \"Diego\",\n  age: 27,\n  alias: \"DevsDav\",\n};\n\n// Acceso a Propiedades\n\n// Notacion por punto\nconsole.log(person.name);\n\n// Notación por corchetes\nconsole.log(person[\"name\"]);\n\n// Modificar propiedades\nperson.name = \"Diego Arenas\";\nconsole.log(person.name);\n\n// Eliminación de propiedades\ndelete person.age;\nconsole.log(person);\n\n// Nueva propiedad\nperson[\"age\"] = 27;\nperson.email = \"devsdav@devsdav.dev\";\nconsole.log(person);\n\n// Métodos (funciones) y Anidación\n\nlet person2 = {\n  // Propiedades clave : valor\n  name: \"Diego\",\n  age: 27,\n  alias: \"DevsDav\",\n  // Métodos\n  walk: function () {\n    console.log(\"La persona camina.\");\n  },\n  // Anidación de objeto\n  job: {\n    name: \"Programador\",\n    exp: 4,\n    work: function () {\n      console.log(\"La persona trabaja.\");\n    },\n  },\n};\n\nperson2.walk();\nperson2.job.work();\n\n// Igualdad de objetcs\n\nlet person4 = {\n  // Propiedades clave : valor\n  name: \"Diego Arenas\",\n  age: 27,\n  alias: \"DevsDav\",\n};\n\n// No se puede igualar asi\nconsole.log(person == person4);\nconsole.log(person === person4);\n\n// Pero si por propiedades\nconsole.log(person.name == person4.name);\n\n// Iteración\nfor (let key in person4) {\n  console.log(key + \": \" + person4[key]);\n}\n\n// Interpolación de variables\n\nlet person3 = {\n  // Propiedades clave : valor\n  name: \"Diego\",\n  age: 27,\n  alias: \"DevsDav\",\n  // Métodos\n  walk: function () {\n    console.log(\"La persona camina.\");\n  },\n  // Anidación de objeto\n  job: {\n    name: \"Programador\",\n    exp: 4,\n    work: function () {\n      // interpolacion con this\n      console.log(`La persona tiene ${this.exp} años de experiencia`);\n    },\n  },\n};\n\nperson3.job.work();\n\n// Funciones como objects\n// NOTA: Esto deberia ser una clase\nfunction Person(name, age) {\n  this.name = name;\n  this.age = age;\n}\n\nlet person5 = new Person(\"Diego\", 27);\nconsole.log(person5);\n\n// console.clear();\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\nconst Agenda = {\n  contacts: {},\n  find: function (name) {\n    return Object.hasOwn(this.contacts, name)\n      ? `${name}: ${this.contacts[name]}`\n      : \"Contacto no encontrado\";\n  },\n  insert: function (name, phone) {\n    let result = false;\n    let phoneValidate = this.checkNumber(phone);\n    let propsValidate = !Object.hasOwn(this.contacts, name);\n\n    if (propsValidate && phoneValidate) {\n      this.contacts[name] = Number(phone);\n      result = true;\n    }\n\n    return result\n      ? \"Registro exitoso\"\n      : \"Contacto no encontrado o numero invalido\";\n  },\n  update: function (name, phone) {\n    let phoneValidate = this.checkNumber(phone);\n    let propsValidate = Object.hasOwn(this.contacts, name);\n\n    if (propsValidate && phoneValidate) {\n      (this.contacts[name] = Number(phone))\n      return \"Contacto Actualizado\";\n    }\n    return \"Contacto no encontrado o numero invalido\";\n  },\n  delete: function (name) {\n    if (Object.hasOwn(this.contacts, name)) {\n      delete this.contacts[name];\n      return \"Contacto eliminado\";\n    }\n    return \"Contacto no encontrado\";\n  },\n  show: function () {\n    console.log(this.contacts);\n  },\n\n  checkNumber: function (number) {\n    return number.length < 12 && !Number.isNaN(Number(number));\n  },\n};\n\nconst readline = require(\"readline\");\nconst read = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout,\n});\n\nconst menu = () => {\n  read.question(\n    `Menu:\n        1.Agregar\n        2.Buscar\n        3.Actualizar\n        4.Eliminar\n        5.Contactos\n        6.Finalizar\n        Ingrese la opcion:`,\n    (option = (option) => {\n      switch (option) {\n        case \"1\":\n          read.question(`Ingrese el nombre: `, (name) => {\n            read.question(`Ingrese el numero de telfono: `, (phone) => {\n              console.log(Agenda.insert(name, phone));\n              menu();\n            });\n          });\n          break;\n        case \"2\":\n          read.question(`Ingrese el nombre: `, (name) => {\n            console.log(Agenda.find(name));\n            menu();\n          });\n          break;\n        case \"3\":\n          read.question(`Ingrese el nombre: `, (name) => {\n            read.question(`Ingrese el numero de telfono: `, (phone) => {\n              console.log(Agenda.update(name, phone));\n              menu();\n            });\n          });\n          break;\n        case \"4\":\n          read.question(`Ingrese el nombre: `, (name) => {\n            console.log(Agenda.delete(name));\n            menu();\n          });\n          break;\n        case \"5\":\n          Agenda.show();\n          menu();\n          break;\n        case \"6\":\n          read.close();\n          break;\n        default:\n          console.log(\"Operación no válida\");\n          menu();\n          break;\n      }\n    })\n  );\n};\n\nmenu();\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/Dan-Corbo.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\n\n\n/* Soluciones */\n\n// Arrays\n\n// Creación\nlet miArray = [1, 2, 3, 4, 5];\n\n// Inserción\nmiArray.push(6); // Añade un elemento al final\nmiArray.unshift(0); // Añade un elemento al principio\n\n// Borrado\nmiArray.pop(); // Elimina el último elemento\nmiArray.shift(); // Elimina el primer elemento\nmiArray.splice(2, 1); // Elimina un elemento en la posición 2\n\n// Actualización\nmiArray[1] = 10; // Actualiza el valor en la posición 1\n\n// Ordenación\nmiArray.sort(); // Ordena el array\n\n// Objetos \n\n// Creación\nlet miObjeto = { nombre: 'Juan', edad: 25, ciudad: 'Montevideo' };\n\n// Actualización\nmiObjeto.edad = 26;\n\n// Inserción\nmiObjeto.trabajo = 'Desarrollador';\n\n// Borrado\ndelete miObjeto.ciudad;\n\n// No hay operación de ordenación para objetos\n\n// Mapas\n\n// Creación\nlet miMapa = new Map();\n\n// Inserción\nmiMapa.set('clave1', 'valor1');\nmiMapa.set('clave2', 'valor2');\n\n// Borrado\nmiMapa.delete('clave1');\n\n// Actualización\nmiMapa.set('clave2', 'nuevoValor');\n\n// No hay operación de ordenación específica para Mapas\n\n// Sets\n\n// Creación\nlet miSet = new Set([1, 2, 3]);\n\n// Inserción\nmiSet.add(4);\n\n// Borrado\nmiSet.delete(2);\n\n// No hay operación de actualización específica para Sets\n// No hay operación de ordenación específica para Sets\n\n// Extra/Opcional\n\nlet lista = [];\n\nfunction validarTelefono(numero) {\n    return /^\\d{10,11}$/.test(numero);\n}\n\nfunction buscarContacto(nombre) {\n    return lista.find(contacto => contacto.Nombre === nombre);\n}\n\nfunction contactos() {\n    console.log(\"Para agregar un contacto presiona 1, para borrarlo presiona 2, para volver presiona 3.\");\n    let numeros = prompt(\"Por favor, presiona un número: \"); \n\n    switch (numeros) {\n        case '1':\n            let nombre = prompt(\"Ingresa el nombre de tu contacto: \");\n            let numero = prompt(\"Ingresa el número de tu contacto: \");\n\n            if (validarTelefono(numero)) {\n                lista.push({ Nombre: nombre, Numero: numero });\n                console.log(\"Contacto guardado.\");\n            } else {\n                console.error(\"Número de teléfono inválido. Debe tener 10 o 11 dígitos como máximo y no tener caracteres incorrectos.\");\n            }\n            break;\n\n        case '2':\n            let nombreBorrar = prompt(\"Ingresa el nombre del contacto que quieres borrar: \");\n            let contactoBorrar = buscarContacto(nombreBorrar);\n\n            if (contactoBorrar) {\n                lista = lista.filter(contacto => contacto !== contactoBorrar);\n                console.log(\"Contacto borrado.\");\n            } else {\n                console.error(\"Contacto no encontrado.\");\n            }\n            break;\n\n        case '3':\n            return panel();\n\n        default:\n            console.error(\"Operación cancelada. Número no reconocido.\");\n    }\n    return panel();\n}\n\nfunction agenda() {\n    console.log(\"Bienvenido a la lista de contactos.\");\n    if (lista.length === 0) {\n        console.log(\"No hay contactos registrados.\");\n    } else {\n        console.log(lista);\n    }\n    return panel();\n}\n\nfunction buscarYMostrarContacto() {\n    let nombre = prompt(\"Ingresa el nombre del contacto que quieres buscar: \");\n    let contacto = buscarContacto(nombre);\n\n    if (contacto) {\n        console.log(\"Contacto encontrado: \", contacto);\n    } else {\n        console.error(\"Contacto no encontrado.\");\n    }\n    return panel();\n}\n\nfunction panel() {\n    console.log(\"Bienvenido al panel de contactos: Presiona 1 para agregar o borrar un contacto, presiona 2 para ver todos los contactos, presiona 3 para buscar un contacto, presiona 4 para salir.\");\n    let numero = prompt(\"Por favor, presiona un número: \");\n\n    switch (numero) {\n        case '1':\n            return contactos();\n\n        case '2':\n            return agenda();\n\n        case '3':\n            buscarYMostrarContacto();\n            break;\n\n        case '4':\n            console.log(\"Ha salido del programa.\");\n            break;\n\n        default:\n            console.error(\"Número incorrecto.\");\n            return panel();\n    }\n}\n\npanel();\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/DanielBustos342.js",
    "content": "//! Arreglos\n//* Creacion\nlet array = [1, 2, 3, 4, 5];\nconsole.log(array); // [1, 2, 3, 4, 5]\n\n//* Insersion\narray.push(6); // Inserta al final\nconsole.log(array); // [1, 2, 3, 4, 5, 6]\n\narray.unshift(0); // Inserta al inicio\nconsole.log(array); // [0, 1, 2, 3, 4, 5, 6]\n\n//* Borrado\narray.pop(); // Elimina el último elemento\nconsole.log(array); // [0, 1, 2, 3, 4, 5]\n\narray.shift(); // Elimina el primer elemento\nconsole.log(array); // [1, 2, 3, 4, 5]\n\n//* Actualizacion\narray[2] = 10; // Actualiza el tercer elemento\nconsole.log(array); // [1, 2, 10, 4, 5]\n\n//* Ordenacion\narray.sort((a, b) => a - b); // Ordena de menor a mayor\nconsole.log(array); // [1, 2, 4, 5, 10]\n\n//! Objetos\n//* Creacion\nlet obj = { a: 1, b: 2, c: 3 };\nconsole.log(obj); // {a: 1, b: 2, c: 3}\n\n//* Insersion\nobj.d = 4;\nconsole.log(obj); // {a: 1, b: 2, c: 3, d: 4}\n\n//* Borrado\ndelete obj.b;\nconsole.log(obj); // {a: 1, c: 3, d: 4}\n\n//* Actualizacion\nobj.a = 10;\nconsole.log(obj); // {a: 10, c: 3, d: 4}\n\n//* Ordenacion\nlet sortedKeys = Object.keys(obj).sort();\nlet sortedObj = {};\nsortedKeys.forEach((key) => {\n  sortedObj[key] = obj[key];\n});\nconsole.log(sortedObj); // {a: 10, c: 3, d: 4}\n\n//! Conjuntos (sets)\n//* Creacion\nlet set = new Set([1, 2, 3, 4, 5]);\nconsole.log(set); // Set {1, 2, 3, 4, 5}\n\n//* Insersion\nset.add(6);\nconsole.log(set); // Set {1, 2, 3, 4, 5, 6}\n\n//* Borrado\nset.delete(4);\nconsole.log(set); // Set {1, 2, 3, 5, 6}\n\n//* Actualizacion (no hay una operacion directa, se puede hacer borrando e insertando)\nif (set.has(3)) {\n  set.delete(3);\n  set.add(10);\n}\nconsole.log(set); // Set {1, 2, 5, 6, 10}\n\n//* Ordenacion (no aplica a Stes ya que son desordenados, pero se puede convertir a array y ordenar)\nlet sortedSetArray = Array.from(set).sort((a, b) => a - b);\nconsole.log(sortedSetArray); // [1, 2, 5, 6, 10]\n\n//! Mapas (maps)\n//* Creacion\nlet map = new Map([\n  [\"a\", 1],\n  [\"b\", 2],\n  [\"c\", 3],\n]);\nconsole.log(map); // Map {'a' => 1, 'b' => 2, 'c' => 3}\n\n//* Insercion\nmap.set(\"d\", 4);\nconsole.log(map); // Map {'a' => 1, 'b' => 2, 'c' => 3, 'd' => 4}\n\n//* Borrado\nmap.delete(\"b\");\nconsole.log(map); // Map {'a' => 1, 'c' => 3, 'd' => 4}\n\n//* Actualizacion\nmap.set(\"a\", 10);\nconsole.log(map); // Map {'a' => 10, 'c' => 3, 'd' => 4}\n\n//* Ordenacion (por clave)\nlet sortedMapKeys = new Map([...map.entries()].sort());\nconsole.log(sortedMapKeys); // Map {'a' => 10, 'c' => 3, 'd' => 4}\n\n//! Extra Ejercicio\n// * Crea una agenda de contactos por terminal.\n//  * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n//  * - Cada contacto debe tener un nombre y un número de teléfono.\n//  * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n//  *   los datos necesarios para llevarla a cabo.\n//  * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n//  *   (o el número de dígitos que quieras)\n//  * - También se debe proponer una operación de finalización del programa.\n\nconst readline = require(\"readline\");\n\nlet schedule = [\n  {\n    name: \"Daniel\",\n    phone: 123456789,\n  },\n  {\n    name: \"Juan\",\n    phone: 987654321,\n  },\n  {\n    name: \"Pedro\",\n    phone: 123456789,\n  },\n  {\n    name: \"Maria\",\n    phone: 987654321,\n  },\n  {\n    name: \"Luis\",\n    phone: 123456789,\n  },\n];\nfunction addContact(name, phone) {\n  if (phone.length > 11) {\n    console.log(\"El numero de telefono no puede ser mayor a 11 digitos\");\n    return;\n  } else if (isNaN(phone)) {\n    console.log(\"El numero de telefono debe ser numerico\");\n    return;\n  }\n  let contact = {\n    name: name,\n    phone: phone,\n  };\n  console.log(\"Contacto anadido\");\n  schedule.push(contact);\n  return contact;\n}\n\nfunction findContact(name) {\n  const lowerCaseName = name.toLowerCase();\n  const contact = schedule.find(\n    (contact) => contact.name.toLowerCase() === lowerCaseName\n  );\n  if (contact) {\n    return contact;\n  } else {\n    return \"El contacto no fue encontrado\";\n  }\n}\n\nfunction deleteContact(name) {\n  const lowerCaseName = name.toLowerCase();\n  const index = schedule.findIndex(\n    (contact) => contact.name.toLocaleLowerCase() === lowerCaseName\n  );\n  if (index !== -1) {\n    schedule.splice(index, 1);\n    return \"El contacto fue eliminado con exito\";\n  } else {\n    return \"El contacto no fue encontrado\";\n  }\n}\n\nfunction updateContact(currentName, newName = null, newPhone = null) {\n  const lowerCaseCurrentName = currentName.toLowerCase();\n  const contact = schedule.find(\n    (contact) => contact.name.toLocaleLowerCase() === lowerCaseCurrentName\n  );\n  if (contact) {\n    if (newName) {\n      contact.name = newName;\n    }\n    if (newPhone) {\n      contact.phone = newPhone;\n    }\n    return \"El contacto fue actualizado con exito\";\n  } else {\n    return \"El contacto no fue encontrado\";\n  }\n}\n\nfunction sortContactByName() {\n  schedule.sort((a, b) => {\n    if (a.name < b.name) {\n      return -1;\n    }\n    if (a.name > b.name) {\n      return 1;\n    }\n    return 0;\n  });\n}\n\nfunction sortContactByPhone() {\n  schedule.sort((a, b) => a.phone - b.phone);\n}\n\nfunction promptUser() {\n  const rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout,\n  });\n\n  function askOperarion() {\n    rl.question(\n      \"\\n ¿Que operacion deseas realizar? \\n 1 - Agregar Contacto, \\n 2 - Buscar Contacto, \\n 3 - Actualizar Contacto, \\n 4 - Eliminar Contacto, \\n 5 - Ordenar Contactos, \\n 6 - Ver Agenda \\n 7 - Salir \\n\",\n      function (operation) {\n        switch (operation) {\n          case \"1\":\n            rl.question(\"Ingresa el nombre del contacto: \", function (name) {\n              rl.question(\n                \"Ingresa el telefono del contacto: \",\n                function (phone) {\n                  addContact(name, phone);\n                  askOperarion();\n                }\n              );\n            });\n            break;\n\n          case \"2\":\n            rl.question(\"Ingresa el nombre del contacto: \", function (name) {\n              console.log(findContact(name));\n              askOperarion();\n            });\n            break;\n\n          case \"3\":\n            rl.question(\n              \"Ingresa el nombre actual del contacto: \",\n              function (currentName) {\n                rl.question(\n                  \"Ingresa el nuevo nombre del contacto o presiona enter para no modificarlo: \",\n                  function (newName) {\n                    rl.question(\n                      \"Ingresa el nuevo telefono del contacto o presiona enter para no modificarlo: \",\n                      function (newPhone) {\n                        console.log(\n                          updateContact(\n                            currentName,\n                            newName || null,\n                            newPhone || null\n                          )\n                        );\n                        askOperarion();\n                      }\n                    );\n                  }\n                );\n              }\n            );\n            break;\n\n          case \"4\":\n            rl.question(\n              \"Ingresa el nombre del contacto a eliminar: \",\n              function (name) {\n                console.log(deleteContact(name));\n                askOperarion();\n              }\n            );\n            break;\n\n          case \"5\":\n            rl.question(\n              \"Como desea ordenar los contactos? \\n 1 - Por nombre \\n 2 - Por telefono \\n\",\n              function (sortOption) {\n                if (sortOption === \"1\") {\n                  sortContactByName();\n                } else if (sortOption === \"2\") {\n                  sortContactByPhone();\n                } else {\n                  console.log(\"Operacion no valida\");\n                }\n                askOperarion();\n              }\n            );\n            break;\n\n          case \"6\":\n            console.log(schedule);\n            askOperarion();\n            break;\n\n          case \"7\":\n            rl.close();\n            break;\n          default:\n            console.log(\"Operacion no valida\");\n            askOperarion();\n            break;\n        }\n      }\n    );\n  }\n  askOperarion();\n}\n\npromptUser();\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/DannyMarperOne.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\n\n/* \nNOTA: En array y en objetos, Si una propiedad comienza con numero, guion bajo, guion, \nsolo se puede acceder a el por medio de corchetes, con punto no\n */\n\n//  Estructuras\n\n// ************** Arreglos (Arrays) ***************\n\nconst autos = [\"Mercedes\", \"RedBull\", \"Mclaren\"]; //Creación de arreglo\nconsole.log(Object.keys(autos)); // [ '0', '1', '2' ]\n\nconsole.log(autos.length); //3\nconsole.log(autos[1]); //RedBull\n\nlet first = autos[0];\nlet end = autos[autos.length - 1]; // Numero de elementos menos 1, y el resultado lo toma como la posición del indice\nconsole.log(end); //Mclaren\n\nlet agregar = autos.push(\"Williams\", \"Aston Martin\"); //Inserción de elemento al array\nconsole.log(autos);\n\nlet eliminar = autos.pop(); //Borrar el último elemento del array\nconsole.log(autos);\n\nlet deleteFirt = autos.shift(); //Borrar el primer elemento del array\nconsole.log(autos);\n\nlet search = autos.indexOf(\"Williams\"); //Encuentra el índice del elemento\nconsole.log(search);\n\nlet deleteElement = autos.splice(search, 1); //splice(desde que indice, numero de elementos a eliminar)\nconsole.log(deleteElement);\nconsole.log(autos);\n\nautos[1] = (\"HAAS\"); //Actualizar Elemento\nconsole.log(autos);\n\nlet order = autos.sort(); //Ordenamiento de elementos\nconsole.log(autos)\n\n\n// ******************** Objetos (Object) **********************\n\nconst computadora = {\n    procesador: \"Intel-I7\",\n    teclado: \"Dell\",\n    monitor: \"HP\",\n    mouse: \"Logitech\",\n    internet: true\n}; //Creación de Objeto\n\nconsole.log(computadora);\nconsole.log(computadora.monitor); //Imprime propiedad\n\ncomputadora.pulgadaMonitor = 18; //Inserción de nueva propiedad\nconsole.log(computadora);\n\ncomputadora.teclado = \"Generico\"; //Actualización de propiedad\ncomputadora[\"mouse\"] = \"ElGato\"; //De esta forma también es posible acceder a una propiedad\nconsole.log(computadora);\n\ndelete computadora.teclado; //Eliminar propiedad\nconsole.log(computadora);\n\n\n//Función constructora de un Objeto e instancias de objetos\nfunction Car(make, model, year) {\n    this.make = make;\n    this.model = model;\n    this.year = year;\n}\nvar mycar = new Car(\"Eagle\", \"Talon TSi\", 1993);\nconsole.log(mycar); //Car { make: 'Eagle', model: 'Talon TSi', year: 1993 }\n\nfunction Person(name, age, sex) {\n    this.name = name;\n    this.age = age;\n    this.sex = sex;\n}\n\nvar rand = new Person(\"Rand McKinnon\", 33, \"M\");\nvar ken = new Person(\"Ken Jones\", 39, \"M\");\n\nfunction Car(make, model, year, owner) {\n    this.make = make;\n    this.model = model;\n    this.year = year;\n    this.owner = owner;\n}\n\nvar car1 = new Car(\"Eagle\", \"Talon TSi\", 1993, rand);\nvar car2 = new Car(\"Nissan\", \"300ZX\", 1992, ken);\n\ncar2.owner.name;\nconsole.log(car2);\n\n\n\n//****************** Set ******************\n\nconst setCreator = new Set([1, 2, 3, 4, 5]); //Cración de constructor Set\n\n// Has devuelve si un elemento pertenece o no al set\nconsole.log(setCreator.has(1)); //true\nconsole.log(setCreator.has(5)); //true\nconsole.log(setCreator.has(8)); //false\n\nsetCreator.add(\"Texto Libre\"); //Agregar elemento a un set\nconst objectSet = {\n    nombre: \"JavaScript\",\n    version: \"ECMAScript 6\"\n}\nsetCreator.add(10).add(\"Otro texto\");\nsetCreator.add(objectSet); //Agregar elemento a un set\nconsole.log(setCreator);\n\nconsole.log(setCreator.size); //Retorno del tamaño del set\n\n\n//Elimina un elemento existente del objeto set (Devuelve True refiriendose a que \"El elemento fue eliminado exitosamente\")\nconsole.log(setCreator.delete(1));\n\nsetCreator.clear(); //Eliminar todos los elementos dentro del objeto set\nconsole.log(setCreator.size);\nconsole.log(setCreator);\n\n\n\n// ***************** WeakSet ******************\n\n//A un WeakSet solo es posible pasarle objetos.\nconst wk = new WeakSet; //Creación de constructor WeakSet\nconst wkOne = {};\nconst wkTwo = {};\n\nwk.add(wkOne); //Agregar objeto al WeakSet\nwk.add(wkTwo);\n\nwk.has(wkOne); //Valida si existe dentro del WeakSet o no\nwk.has(wkTwo);\n\nwk.delete(wkOne); //Eliminación del objeto (Devuelve True \"Fue eliminado exitosamente\")\nconsole.log(wk.has(wkOne));\n\n\n\n\n// ****************** Map ****************\n\n//Creación del constructor Map\nconst myMap = new Map([\n    [\"Trampa\", \"Sombreros Mágicos\"],\n    [\"Monstruo\", \"Mago Oscuro\"],\n    [\"Especial\", \"Exodia\"],\n    [\"Magica\", \"Espadas de luz reveladora\"],\n    [1000, \"Vida Actual\"]\n]);\n\nmyMap.set(\"Dios Egipcio\", \"Obelisco el atormetador\"); //Agregar un elemento Key-Value\nconsole.log(myMap.delete(\"Trampa\")); //Eliminar un elemento Key-Value\nconsole.log(myMap.get(\"Magica\")); //Obtienes el Value asociado al Key\nconsole.log(myMap.size); //Verificar tamaño de Map\nconsole.log(myMap.get(\"Especial\"));\n\n\n/* \nDIFICULTAD EXTRA\n*/\n\n\nfunction panelPrincipal() {\n    const listContact = new Map([[\"Daniel\", \"29293018309\"]]);\n\n    var is_on = true;\n    while (is_on) {\n\n        alert(\"Agenda de contactos\");\n\n        let numberOption = prompt(\n            `Selecciona la opción de tu preferencia: \n        0: Ver lista de contactos.\n        1: Buscar un contacto.\n        2: Agregar un nuevo contacto. \n        3: Actualizar un contacto.\n        4: Eliminar un contacto.\n        5: Salir.`\n        );\n\n        let name = null;\n        let phone = null;\n\n        switch (numberOption) {\n            case \"0\":\n                for (let [key, value] of listContact) {\n                    alert(`Nombre: ${key}, Teléfono: ${value}`);\n                }\n                break;\n            case \"1\":\n                name = prompt(`Introduce el nombre del contacto que buscas`);\n                if (listContact.has(name)) {\n                    let phoneNumber = listContact.get(name);\n                    alert(`El contacto ${name} tiene asignado el número ${phoneNumber}`)\n                } else {\n                    alert(`El contacto ${name} no existe.`);\n                }\n                break;\n            case \"2\":\n                name = prompt(`Escribe el nombre del nuevo contacto`);\n                phone = parseInt(prompt(`Escribe el número del nuevo contacto`));\n                if (/^\\d{10,11}$/.test(phone)) {\n                    listContact.set(name, phone);\n                    alert(`El contacto ${name} fue agregado con éxito`);\n                } else {\n                    alert(\"Debes introducir un número de télefono de 10 u 11 dígitos\")\n                }\n                break;\n            case \"3\":\n                name = prompt(`Introduce el nombre del contacto que deseas actualizar.`);\n                if (listContact.has(name)) {\n                    phone = parseInt(prompt(`Escriba el nuevo número del contacto ${name}`));\n                    if (/^\\d{10,11}$/.test(phone)) {\n                        listContact.set(name, phone);\n                        alert(`El contacto ${name} fue actualizado`);\n                    } else {\n                        alert(`No se pudo actualizar al contacto ${name}, favor de verificar el número de teléfono, este debe contener de 10 a 11 dígitos.`)\n                    }\n                }\n                break;\n            case \"4\":\n                name = prompt(`Introduce el nombre del contacto que deseas eliminar`);\n                if (listContact.has(name)) {\n                    listContact.delete(name);\n                    alert(`Contacto eliminado exitosamente`)\n                } else {\n                    alert(`El contacto ${name} no existe.`);\n                }\n                break;\n            case \"5\":\n                alert(\"Saliendo de la agenda.\")\n                is_on = false;\n                break;\n            default:\n                alert(\"Selección incorrecta, selecciona una opción del 0 al 5.\")\n                break;\n        }\n    }\n}\npanelPrincipal();"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/DavidMoralesDeveloper.js",
    "content": "//1 - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n// en object lo valores se pasan por referencia y en primitivos por valor****\n\nconsole.log(typeof null) //object,  (e la teoria deberia ser null primitivo)***\n// objects\nconsole.log(typeof {}) //object : objeto\nconsole.log(typeof []) //object :array\nconst set = new Set()\nconsole.log(typeof set) //object : añadir datos a la array\n\n// cada constructor de las funciones se deriaba del contructor object pero es un objeto especial\n// function \nconsole.log(typeof function(){}) //function pero por detras es un objeto especial\n    \n//tipdos en un array\nlet numbers = [1, 2, 3, 4];\nlet letters = ['a', 'b', 'c', 'd'];\nlet combined = ['abc', true, 'def', false]; \nlet users = [  //array de objetos\n    {\n        id: 1,\n        name: 'Andres',\n        subscribed: true\n    },\n    {\n        id: 2,\n        name: 'Brais',\n        subscribed: false\n    }\n];\nconsole.log('users', users);\n\n//2- Utiliza operaciones de inserción, borrado, actualización y ordenación.\n\nlet frutas = [\"Manzana\", \"Banana\"];\nconsole.log(frutas.length); //2\n\nfrutas.push('uva') //inserción\nconsole.log(frutas + ' metodo push'); //[ 'Manzana', 'Banana', 'uva' ]\nfrutas.pop() //borrado\nconsole.log(frutas + ' metodo pop'); //[ 'Manzana', 'Banana',  ]\n\nlet mejoresCarros2023 = [\"audi\", \"ferrari\", \"renol\", \"nisan\", \"honda\"]\nconsole.log(mejoresCarros2023)\nmejoresCarros2023[2] = 'suzuki' //actualización\nconsole.log(mejoresCarros2023)\n\nconst numeros = [10, 21, 13, 45, 5, 26] //ordenación\n\nconst descNumeros = numeros.sort((a,b) => a > b ? -1 : 1) //[ 45, 26, 21, 13, 10, 5 ]\nconsole.log(descNumeros)\n\nconst asenNumeros = numeros.sort((a,b) => a > b ? 1 : -1) //[ 5, 10, 13, 21, 26, 45 ]\nconsole.log(asenNumeros)\n\n//set\n// es una estructura de datos qe nos permite almacenar colecciones de datos especificamente que no se van a repetir\nconsole.log('-----------------set')\nconst set1 = new Set()\n\nset1.add(1)\nset1.add(2)\nset1.add(false)\nset1.add([1,5,6]) // guardado por valor - console.log(set1.has([1,5,6])) : false\nconst arr = [1,5,6] //guardado por referencia\nset1.add(arr) // console.log(set1.has(arr)) : true\nset1.delete(false)\n\nconsole.log(set1.has(arr))\nfor( item of set1){\n    console.log(item)\n}\n\n//map\nconsole.log('-----------------map')\nconst map = new Map()\n\nmap.set(1, 'lunes')\nmap.set('2', 3)\nmap.set(false, 10)\nconsole.log(map.has(1))\nconsole.log(map.size)\nmap.delete(false)\nconsole.log(map.size)\n\nfor(item of map){\n    console.log(item)\n}\nfor(const [key, value] of map){\n    console.log(key, value)\n}\n\nconsole.log(map.get('2'))\n\n\n//3 EXTRA\n// Crea una agenda de contactos por terminal.\n//  * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n//  * - Cada contacto debe tener un nombre y un número de teléfono.\n//  * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n//  *   los datos necesarios para llevarla a cabo.\n//  * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n//  *   (o el número de dígitos que quieras)\n//  * - También se debe proponer una operación de finalización del programa.\n\n\nconst readline = require(\"readline\");\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout,\n  });\n\n  let agenda = {}\n\nfunction miAgenda  () {\n\n   \n\n    rl.question(\"¿Qué operación quieres realizar? (buscar, insertar, actualizar, agenda, eliminar, salir): \", (operacion) => {\n    switch (operacion) {\n        case 'buscar':\n            rl.question('¿nombre de contacto?', (nombre)=> {\n                if(agenda[nombre]){\n                    console.log(`Nombre: ${nombre} Telefono: ${agenda[nombre]}`)\n                    miAgenda  ()\n                }else {\n                    console.log(\"Contacto no encontrado.\");\n                    miAgenda  ()\n                  }\n            })\n            miAgenda  ()\n            break;\n        case 'insertar':\n           rl.question('¿cuales el nombre?:', (nombre) =>{\n             rl.question('¿cual es el telfono?:', (telefono) =>{\n                if( !isNaN(telefono) && telefono.toString().length <= 11){\n\n                    agenda[nombre] = telefono\n                    console.log(\"Contacto agrego correctamente.\");\n                    miAgenda  ()\n                }else{\n                    console.log('Error, el telefono solo acepta numeros, hasta 11 digitos')\n                    miAgenda  ()\n                }\n             })\n            } )\n            \n            \n            break;\n        case 'actualizar':\n            rl.question('nombre de contacto ', (nombre) => {\n                if(agenda[nombre]){\n                    rl.question('introducel el nuevo numero de telefono',(telefono) => {\n                        agenda[nombre] = telefono\n                        console.log('se actualice exitosamente')\n                        miAgenda()\n                    })\n                }else{\n                    console.log(\"Contacto no encontrado.\");\n                    miAgenda  ()\n                }\n            })\n            console.log('actualizar')\n            break;\n        case 'eliminar':\n            rl.question('Escriba el nombre de el contacto que se quiera eliminar',(nombre) => {\n                if(agenda[nombre] ){\n                    delete agenda[nombre]\n                    console.log( 'fue eliminado eliminado' )\n                    miAgenda()\n                }\n            })\n            break;\n        case 'agenda':\n            console.log(agenda)\n            miAgenda()\n            break;\n        case 'salir':\n            rl.close();\n            console.log('saliendo de la agenda')\n            break;\n    \n        default:\n            console.log('Error al leer su respuesta , eliga una opcion valida')\n            miAgenda  ()\n            break;\n    }\n\n})\n \n}\n\nmiAgenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/Deyvid-10.js",
    "content": "// Estructuras \n\n// arreglo\nlet array = [2, 3, 4]\narray.push(5) // insertar un elemento al final\narray.unshift(1) // insertar un elemento al inicio\narray.pop() // borra el ultimo elemento del array\narray.shift() // borra el primer elemento del array\narray.splice(2, 1) // borra 1 elemento del indice seleccionado\narray[1] = 6 // actualiza el valor del indice seleccionado\narray.splice(0, 1, 10) // actualiza solo 1 elemento en el indice seleccionado\narray.sort((a, b) => a - b) // ordena un array con numeros\n\nlet array2 = [\"d\", \"a\", \"z\", \"q\", \"p\"]\narray2.sort() // ordena un array con strings\n\n// objeto\nlet objeto = {nombre: \"Deyvid\", profesion: \"Informatica\"}\nobjeto.pasatiempo = \"Anime y videojuegos\" // insertar un elemento \nobjeto[\"segundoNombre\"] = \"Gabriel\" // insertar un elemento \ndelete objeto.pasatiempo // borrar un elemento\nobjeto.profesion = \"Desarrollador de software\" // actualizar un elemento\n\n// mapas\nlet mapa = new Map()\nmapa.set(\"nombre\", \"Deyvid\") // insertar un elemento \nmapa.set(\"profesion\", \"Informatica\") // insertar un elemento \nmapa.set(\"pasatiempo\", \"Anime y videojuegos\") // insertar un elemento \nmapa.delete(\"pasatiempo\") // borrar un elemento\nmapa.set(\"profesion\", \"Desarrollador de software\") // actualizar un elemento\n\n// Conjuntos\nlet set = new Set()\nset.add(1) // insertar un elemento \nset.add(2) // insertar un elemento \nset.add(3) // insertar un elemento \nset.delete(1) // borrar un elemento\nset.delete(2); set.add(4); // actualizar un elemento"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/DjSurgeon.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto\n *   en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n *   y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n *   y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más\n *   de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.\n */\n\n/* === ESTRUCTURAS DE DATOS EN JAVASCRIPT === */\n/*\n * Las estructuras de datos en JavaScript son un aspecto crucial de la programación eficiente.\n * Proporcionan una forma de organizar, gestionar y almacenar datos que facilita su acceso y trabajo.\n * Comprender los diferentes tipos de estructuras de datos y sus aplicaciones puede mejorar\n * significativamente tus habilidades de programación.\n *\n * JavaScript admite una serie de estructuras de datos, incluyendo Arreglos (Arrays),\n * Objetos (Objects), Datasets (Sets), Mapas (Maps),\n * Pilas (Stacks), Colas (Queues), Listas Enlazadas (Linked Lists),\n * Árboles (Trees), Grafos (Graphs), Tablas Hash (Hash Tables), y otras.\n * Cada una de estas estructuras de datos tiene sus propias fortalezas y debilidades,\n * y se utilizan en diferentes situaciones dependiendo de los requisitos de la tarea en cuestión.\n */\n// ARRAYS\n/* El arreglo es la estructura de datos más simple en JavaScript.\n * Se utiliza para almacenar múltiples valores en una sola variable.\n */\n\nlet ids = [1, 2, 3, 4, 5];\nconsole.log(ids);\n\nlet nombres = [\"Marc\", \"Noa\", \"Sergio\", \"Verónica\"];\n\n// Accedes a un elemento del array mediante su indice\nconsole.log(nombres[2]);\n\n// Adición de elementos al final de un array\n\nnombres.push(\"Leonidas\");\nconsole.log(nombres);\n\n// Eliminar el último elemento de un array\n\nnombres.pop();\nconsole.log(nombres);\n\n// Añadir un elemento al principio de un array\n\nnombres.unshift(\"Nala\");\nconsole.log(nombres);\n\n// Eliminar el primer elemento de un array\n\nnombres.shift();\nconsole.log(nombres);\n\n// Encontrar el índice de un elemento del array\n\nlet position = nombres.indexOf(\"Sergio\");\nconsole.log(position);\n\n// Eliminar elemento de un array y crear un array nuevo (Modifica el array original)\n\nlet hijos = nombres.splice(0, 2);\nconsole.log(hijos);\nconsole.log(nombres);\n\n// Copiar un array (No modifica el array original)\n\nlet padres = nombres.slice();\nconsole.log(padres);\nconsole.log(nombres);\n\n// OBJETOS\n/*\n * Un objeto es una colección de propiedades, y una propiedad es una asociación\n * entre un nombre (o clave) y un valor. El valor de una propiedad puede ser una función,\n * en cuyo caso la propiedad es conocida como un método.\n */\n\nlet miCoche = {\n  color: \"rojo\",\n  ruedas: 4,\n  descapotable: false,\n};\n\nconsole.log(miCoche);\nconsole.log(miCoche.color);\n\n// Añadir una propiedad al objeto.\n\nmiCoche.volante = false;\n\nconsole.log(miCoche);\n\n// Iterar sobre las propiedades de los objetos.\n// For...in\nfor (let piezas in miCoche) {\n  console.log(\n    `Estas son mis claves: ${piezas} y estos sus valores: ${miCoche[piezas]}`\n  );\n}\n//Devuelve un array con las claves Object.keys()\nconsole.log(Object.keys(miCoche));\n// Object.getOwnPropertyNames()\nconsole.log(Object.getOwnPropertyNames(miCoche));\n\n// SET\n/*\n * Set es una colección de valores en la que cada valor debe ser único.\n * Los valores duplicados son automáticamente eliminados.\n * Set es ideal para situaciones donde los valores deben ser únicos,\n * y se manejan datos que no requieren un orden específico o indexación.\n */\n// Creamos un nuevo set\nlet consolas = new Set();\n// Agregar elementos\nconsolas.add(\"NES\");\nconsolas.add(\"Mega Drive\");\nconsole.log(consolas);\n// Eliminar elementos\nconsolas.delete(\"NES\");\nconsole.log(consolas);\n// Verificar Existencia\nconsole.log(consolas.has(\"Mega Drive\"));\n// Tamaño\nconsole.log(consolas.size);\n// Eleminar todos los datos\nconsolas.clear();\n// Algunos usos de los set\n// Eliminar duplicados\nconst nuevas = [\"360\", \"PS3\", \"PS4\", \"XboxOne\", \"PS3\"];\nconsole.log(nuevas);\nconst newGen = new Set(nuevas);\nconsole.log(newGen);\n// Unir conjuntos\nconst oldGen = new Set([\"NES\", \"MegaDrive\"]);\nconsolas = new Set([...newGen, ...oldGen]);\nconsole.log(consolas);\n\n// MAP\n/*\n * Map es una colección de pares clave-valor donde cada clave es única.\n * A diferencia de los objetos, las claves en Map pueden ser de cualquier tipo,\n * y mantiene el orden de inserción de los elementos\n */\n// Creamos un nuevo Map\nlet juegos = new Map();\n// Agregar elementos\njuegos.set(1, \"Gears of War\");\njuegos.set(2, \"Jak & Daxter\");\nconsole.log(juegos);\n// Tamaño del mapa\nconsole.log(juegos.size);\n// Valor de la clave\nconsole.log(juegos.get(1));\nconsole.log(juegos.get(4));\n// Saber si existe la clave o no\nconsole.log(juegos.has(1));\nconsole.log(juegos.has(4));\n// Eliminar una clave\njuegos.delete(2);\nconsole.log(juegos);\n// Eliminar el mapa completo\njuegos.clear();\nconsole.log(juegos);\n// Diferentes maneras de reccorrer un map\njuegos.set(1, \"Gears of War\");\njuegos.set(2, \"Jak & Daxter\");\njuegos.set(3, \"Halo\");\n//.keys() devuelve un iterable con las claves.\nconsole.log(juegos.keys());\n// .values() devuelve un iterable con los valores.\nconsole.log(juegos.values());\n// .entries() devuelve un iteracle con la entradas clave y valor.\nconsole.log(juegos.entries());\n\n// AGENDA DE CONTACTOS\n\nconst agenda = new Map();\nagenda.set(1, { name: \"Juan\", phone: \"123456789\" });\nagenda.set(2, { name: \"María\", phone: \"987654321\" });\n\n// Añadir un contacto\n/* Creamos una función con los parametros nombre y telefono\n * comprobamos si tanto nombre y telefono son strings\n * y si es asi, añadimos el contacto a la agenda en la siguiente posición disponible.\n */\nfunction addContact(nombre, telefono) {\n  if (\n    typeof nombre === \"string\" &&\n    typeof telefono === \"string\" &&\n    telefono.length === 9\n  ) {\n    agenda.set(agenda.size + 1, { name: nombre, phone: telefono });\n    console.log(\n      `El contacto: ${nombre} y el telefono: ${telefono} han sido correctamente introducidos.`\n    );\n  } else {\n    console.log(\"Introduce los datos correctos\");\n  }\n}\n// Eliminar un contacto\n/*\n * Creamos una función con el numero de clave como argumento\n * comprobamos si esa clave esta en el set de la agenda\n * si está se procede al borrado de esa clave\n */\nfunction deleteContact(clave) {\n  if (agenda.has(clave) === true) {\n    console.log(`El contacto ${agenda.get(clave).name} ha sido eliminado.`);\n    agenda.delete(clave);\n  } else {\n    console.log(\"El contacto seleccionado no existe.\");\n  }\n}\n// Busqueda de un contacto\n/*\n * Creamos una función con el numero de clave como argumento\n * comprobamos que esa clave este dentro del set y si esta\n * devuelve por consola los datos de la clave.\n */\nfunction getContact(clave) {\n  if (agenda.has(clave) === true) {\n    console.log(\n      `El contacto seleccionado es: ${\n        agenda.get(clave).name\n      } y su telefono es: ${agenda.get(clave).phone}`\n    );\n  } else {\n    console.log(\"Ese contacto no se encuentra en la agenda.\");\n  }\n}\n// Actualización de un contacto\n/*\n * Creamos una función que toma como argumentos un clave\n * un nombre y un telefono, comprueba si esa clave es valida\n * y luego toma los argumentos para actualizar el contacto\n */\nfunction actContact(clave, nombre, telefono) {\n  if (agenda.has(clave) === true && typeof clave === \"number\") {\n    if (\n      typeof nombre === \"string\" &&\n      typeof telefono === \"string\" &&\n      telefono.length === 9\n    ) {\n      agenda.set(clave, { name: nombre, phone: telefono });\n      console.log(`El contacto: ${agenda.get(clave).name} ha sido actualizado`);\n    } else {\n      console.log(\"Los datos introducidos son incorrectos.\");\n    }\n  } else {\n    console.log(\"Ese contacto no esta en la agenda.\");\n  }\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/DobleDJ.js",
    "content": "/**\n * Reto de programación #03 - javaScript\n * Autor: Yoandy Doble Herrera\n * Fecha: 08/12/2024\n */\n\n/*\n * EJERCICIO:\n * [x] Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * [x] Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * [-] Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * [-] Cada contacto debe tener un nombre y un número de teléfono.\n * [-] El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * [-] El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * [-] También se debe proponer una operación de finalización del programa.\n */\n\n/* 1- Estructura de dato: Array */\nlet equipoBaseball = [\n  \"Pinar del Río\",\n  \"Mayabeque\",\n  \"Artemisa\",\n  \"Industriales\",\n  \"Matanzas\",\n  \"Cienfuegos\",\n  \"Villaclara\",\n  \"Ciego de Ávila\",\n  \"Holguín\",\n  \"Granma\",\n  \"Sancti Spiritus\",\n  \"Santiago de Cuba\",\n  \"Guantánamo\",\n  \"Camagüey\",\n]\nconsole.log(\"Array\", equipoBaseball)\n//inserción, borrado, actualización y ordenación\n\n//Insertar elemento en array al final\nequipoBaseball.push(\"Isla de la Juventud\")\nconsole.log(\"Array con nuevo elemento al final\", equipoBaseball)\n\n//Insertar elemento al principio en array\nlet newArrayLength = equipoBaseball.unshift(\"Chicago White Sox\")\nconsole.log(\"Array con nuevo elemento al incio\", equipoBaseball, \"\\nNueva longitud: \", newArrayLength)\n\n//Eliminar elemento en array al final\nlet elementoRemoved = equipoBaseball.pop()\nconsole.log(\"Array con nuevo elemento al final\", equipoBaseball, \"\\nElemento borrado al final: \", elementoRemoved)\n\n//Eliminar elemento al principio en array\nlet elementShifted = equipoBaseball.shift()\nconsole.log(\"Array con nuevo elemento al incio\", equipoBaseball, \"\\nElemento borrado al inicio: \", elementShifted)\n\n//Actualizar elemento en el array\nequipoBaseball[0] = \"Team Challenger\"\nconsole.log(\"Array con nuevo elemento al incio actualizado\", equipoBaseball)\n\n//Ordenación Sort in place\nconsole.log(\"Elementos ordenados:\", equipoBaseball.sort())\n\n/* 2- Estructura de dato: Set */\nconst palabrasUnicas = new Set([\"laptop\", \"boy\", \"boy\", \"keyboard\", \"javaScript\", \"flute\"])\nconsole.log(palabrasUnicas) //no se muestran elementos repetidos\n\n//Insertar elemento en Set\npalabrasUnicas.add(\"car\")\nconsole.log(\"Nuevo elemento en Set insertado al final\", palabrasUnicas)\n\n//Eliminar elemento en Set\nlet apearElem = palabrasUnicas.delete(\"boy\")\nconsole.log(\"Elimina elemento: (boy) true si aparece en el Set \", palabrasUnicas, \"\\nrespuesta:\", apearElem)\n\n//Actualizar elemento en el array\n/* No es posible porque son elementos únicos */\n\n//Ordenación Sort in place\nlet palabrasArray = Array.from(palabrasUnicas)\npalabrasArray.sort()\nconsole.log(\"Set convertido en array para ordanar\\n\", palabrasArray)\nlet newSetPalabras = new Set(palabrasArray)\nconsole.log(\"Nuevo SET ordenado:\\n\", newSetPalabras)\n\n/* 3- Estructura de dato: Map */\nconst misContactos = new Map([\n  [\"Yoandy\", 5312365478],\n  [\"Mabel\", 5365897452],\n  [\"Ariana\", 548793112125],\n])\nconsole.log(misContactos)\n\n//inserción, borrado, actualización y ordenación\n// Insertar tupla\nmisContactos.set(\"Barbarita\", 5369874123625)\nconsole.log(\"ELemento insertado al MAP\", misContactos)\n\n// Eliminar por key\nmisContactos.delete(\"Mabel\")\nconsole.log(\"Eliminada key: Mabel\", misContactos)\n\n//Actualizar value en Set\nmisContactos.set(\"Yoandy\", 5989325789)\nconsole.log(\"Actulizado valor número de teléfono key: Yoandy\", misContactos.get(\"Yoandy\"))\n\n// Ordenacion\nlet arrayEnOrden = [...misContactos].sort((a, b) => a[0].localeCompare(b[0]))\nconsole.log(arrayEnOrden)\nlet newContactos = new Map(arrayEnOrden)\nconsole.log(newContactos)\n\n/* 4- Estructura de dato: Object */\nlet auto = {\n  brand: \"Dodge Challenger\",\n  price: 25000,\n  color: \"Black\",\n  date: \"08/12/2024\",\n  isnew: true,\n  owner: \"Yoandy Doble Herrera\",\n}\n\n// Insertar propiedad a Objeto\nauto[\"seller\"] = \"Rick Ortiz\"\nconsole.log(\"Nuevo elemento al Objeto\", auto)\n\n//borrado propiedad a Objeto\ndelete auto.color\nconsole.log(\"Propiedad color eliminada de Objeto\", auto)\n\n// Actualización de propiedades\nauto[\"seller\"] = \"Rick Ortiz Martínez\"\nconsole.log(auto)\n\n// Ordenación\n/* Utilizando sort de Array impacto en eficiencia */\nconsole.time()\nconst autoArray = Object.keys(auto).sort()\n//console.log(autoArray)\n\nconst objCar = {}\nautoArray.forEach((value) => {\n  objCar[value] = auto[value]\n})\nconsole.log(objCar)\nconsole.timeEnd()\n\n/* Utilizar un mapa más rápido*/\nconsole.time()\nconst mapOrdenado = new Map()\nfor (clave in auto) {\n  mapOrdenado.set(clave, auto[clave])\n}\n\nfor (const [clave, valor] of mapOrdenado) {\n  console.log(clave, valor) //aplicar ordenación\n}\nconsole.timeEnd()\n\n/**\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * [-] Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * [x] Cada contacto debe tener un nombre y un número de teléfono.\n * [x] El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * [x] El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * [x] También se debe proponer una operación de finalización del programa.\n */\n\nconst readline = require(\"node:readline\")\nconst { stdin: input, stdout: output } = require(\"node:process\")\nconst rl = readline.createInterface({ input, output })\n\nconst libretaContactos = new Map()\n\n/**\n * Función para validar nombre insertado\n * @param {string} nombre Cualquier valor de tipo cadena\n * @returns Retorna un boolean\n */\nfunction validarNombre(nombre) {\n  if (!(nombre.trim().length > 0)) {\n    return \"Error: Debes insertar un nombre válido.\"\n  }\n  if (/\\d/.test(nombre)) {\n    return \"Error: El nombre no debe poseer números.\"\n  }\n  return null\n}\n\nconst validarNumero = (numero) => /^\\d{11}$/.test(numero)\n\n/**\n * Menú interactivo con readline para Proyecto ¡Agenda de Contactos!\n */\nconst menu = () => {\n  console.info(\n    `\\nApp: ¡Agenda de contactos!\n  1. Insertar contacto\n  2. Eliminar contacto\n  3. Buscar contacto\n  4. Actualizar contacto\n  5. Salir\n  `\n  )\n  rl.question(\"Seleccione una opción: \", (answer) => {\n    switch (answer) {\n      case \"1\":\n        insertarContacto()\n        break\n      case \"2\":\n        eliminarContacto()\n        break\n      case \"3\":\n        buscarContacto()\n        break\n      case \"4\":\n        actualizarContacto()\n        break\n      case \"5\":\n        rl.close()\n        console.log(`\n          Ha finalizado la Agenda de Contactos. ¡Hasta luego!`)\n        break\n      default:\n        console.log(\"Opción inválida\")\n        menu()\n    }\n  })\n}\n\n/**\n * Insertar un contacto en la libreta de direcciones (void function)\n * Readline: nombre de contacto, un número de 11 dígitos\n */\nconst insertarContacto = () => {\n  rl.question(\"Nombre del contacto: \", (nombre) => {\n    const error = validarNombre(nombre)\n    if (error) {\n      console.log(`Error: ${error}`)\n      return insertarContacto()\n    }\n    rl.question(\"Número del contacto: \", (numero) => {\n      if (!validarNumero(numero)) {\n        console.log(\"Error: El número debe ser un número de teléfono válido de 11 dígitos.\")\n        return insertarContacto()\n      }\n      const contactUser = { id: libretaContactos.size + 1, nombre, numero }\n      libretaContactos.set(contactUser.id, contactUser)\n      console.log(`\n        Contacto creado: ${contactUser.nombre} - ${contactUser.numero}`)\n      menu()\n    })\n  })\n}\n\n/**\n * Eliminar un contacto de la libreta de contactos por el nombre\n */\nconst eliminarContacto = () => {\n  if (libretaContactos.size === 0) {\n    console.log(\"Error: Libreta de contactos vacía.\")\n    return menu()\n  } else {\n    rl.question(\"Nombre del contacto: \", (nombre) => {\n      const error = validarNombre(nombre)\n      if (error) {\n        console.log(`Error: ${error}`)\n        return eliminarContacto()\n      }\n      if (borrarContacto(nombre)) {\n        console.log(`\n            Contacto eliminado: ${nombre}`)\n      } else {\n        console.log(\"Contacto no encontrado.\")\n      }\n      menu()\n    })\n  }\n}\n\nconst borrarContacto = (contacto) => {\n  for (const [key, value] of libretaContactos) {\n    if (value.nombre === contacto) {\n      libretaContactos.delete(key)\n      return true\n    }\n  }\n  return false\n}\n\n/**\n * Buscar un contacto en la libreta telefónica\n */\nconst buscarContacto = () => {\n  let isContact = false\n  if (libretaContactos.size === 0) {\n    console.log(\"Error: Libreta de contactos vacía.\")\n    return menu()\n  } else {\n    rl.question(\"Nombre del contacto: \", (nombre) => {\n      const error = validarNombre(nombre)\n      if (error) {\n        console.log(`Error: ${error}`)\n        return buscarContacto()\n      }\n\n      const singleContact = findContacto(nombre)\n      if (Object.keys(singleContact).length !== 0) {\n        console.log(`\n            Contacto encontrado: ${singleContact.nombre} - ${singleContact.numero}`)\n      } else {\n        console.log(`\n            Contacto no encontrado`)\n      }\n      menu()\n    })\n  }\n}\n\n/**\n * Función que dado una cadena de texto comprueba si aparece en la libreta de contactos\n * @param {string} nombre Cualquier cadena de texto\n * @returns Retorna el objeto encontrado, si no aparece devuelve un objeto vacío\n */\nconst findContacto = (nombre) => {\n  const contacto = {}\n  for (const value of libretaContactos.values()) {\n    if (value.nombre === nombre) {\n      contacto.nombre = value.nombre\n      contacto.numero = value.numero\n    }\n  }\n  return contacto\n}\n\n/**\n * Actualizar un contacto en la libreta telefónica\n */\nconst actualizarContacto = () => {\n  if (libretaContactos.size === 0) {\n    console.log(\"Error: libreta de contactos vacía.\")\n    return menu()\n  } else {\n    rl.question(\"Nombre del contacto: \", (nombre) => {\n      const error = validarNombre(nombre)\n      if (error) {\n        console.log(`Error: ${error}`)\n        return actualizarContacto()\n      }\n      const singleContact = findContacto(nombre)\n      if (Object.keys(singleContact).length === 0) {\n        console.log(`\n            Contacto no encontrado`)\n        return actualizarContacto()\n      } else {\n        rl.question(\"Número del contacto: \", (numero) => {\n          if (!validarNumero(numero)) {\n            console.log(\"Error: El número debe ser un número de teléfono válido de 11 dígitos.\")\n            return actualizarContacto()\n          }\n          updateContact(nombre, numero)\n          console.log(`\n              Contacto actualizado: ${nombre} - ${numero}`)\n          menu()\n        })\n      }\n    })\n  }\n}\n\n/**\n * Función actualizar contacto\n * @param {string} nombre Una cadena de texto sin números\n * @param {string} numero Un número de 11 dígitos\n * @returns Retorna un boolean\n */\nconst updateContact = (nombre, numero) => {\n  for (const value of libretaContactos.values()) {\n    if (value.nombre === nombre) {\n      value.numero = numero\n      return true\n    }\n  }\n  return false\n}\n\nmenu()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/DouglasDiazR.js",
    "content": "/* ESTRUCTURAS DE DATOS EN JAVASCRIPT */\n\n// VARIABLES\nlet variableLet = \"variable let\";\nconst variableConst = \"variable const\";\n\n// TIPOS DATOS PRIMARIOS\nconst string = \"cadena de texto\";\nconst number = \"número\";\nconst boolean = true;\nlet undefined;\nconst nullVariable = null;\n\n//ARRAYS\nlet array = [1, 2, 3, \"cuatro\", true];\nconsole.log(array);\n\nlet elementoArray = array[3]; //Acceder a un elemento dentro del array\nconsole.log(elementoArray);\n\narray = array[3] = \"cinco\"; //Cambiar un elemento dentro del array\nconsole.log(array);\n\nlet frutas = [\"banana\", \"manzana\", \"pera\", \"uva\"];\nconsole.log(frutas);\nfrutas = frutas.toString(); //Convierte el array en un string\nconsole.log(frutas);\n\nconsole.log(array.length); // length = Devuelve la longitud del array\n\nlet numeros = [1, 2, 3, 4, 5, 6];\nnumeros.forEach((numero) => console.log((numero += 1)));\n\nlet colores = [\"amarillo\", \"azul\", \"rojo\"];\nconsole.log(colores);\ncolores.push(\"negro\"); //Agrega un elemento al final de array\nconsole.log(colores);\n\ncolores[colores.length] = \"marrón\";\nconsole.log(colores);\n\ncolores.shift(colores); //.shift = Elimina el primer elemento dentro de un array\nconsole.log(colores);\n\nlet edades = [20, 15, 33, 46, 18, 25];\nedades.sort(); // .sort() = Ordena los elemento dentrode un array\nconsole.log(edades);\n\n/*OBJETOS*/\nconst objeto = {\n  nombre: \"Javier\",\n  edad: 34,\n  saludar: function saludo() {\n    console.log(`hola`);\n  },\n};\n\nobjeto.saludar(); // Acceder a una propiead del objeto\n\nobjeto.apellido = \"Rojas\"; // Agregar propiedades a un objeto\nconsole.log(objeto);\n\nconst persona = {\n  nombre: \"Pedro\",\n  apellido: \"Perez\",\n  edad: 30,\n  nombreCompleto: function () {\n    //Un método es una función almacenada como una propiedad\n    console.log(`${this.nombre} ${this.apellido}`);\n  },\n};\npersona.nombreCompleto();\nconsole.log(persona);\n\n/* DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\nlet agenda = [];\nlet contacto = {};\n\nconst readline = require(\"readline\");\n\nconst read = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout,\n});\n\nconst menu = () => {\n  read.question(\n    \"¡BIENVENIDO! \\n Ingrese el número de la operación a realizar \\n  1.Agregar | 2.Buscar | 3.Actualizar | 4.Eliminar | 5.Contactos | 6.Finalizar  \\n \",\n    (operar = (operacion) => {\n      switch (operacion) {\n        case \"1\":\n          agregarContacto();\n          break;\n        case \"2\":\n          buscarContacto();\n          break;\n        case \"3\":\n          actualizarContacto();\n          break;\n        case \"4\":\n          eliminarContacto();\n          break;\n        case \"5\":\n          mostrarTodosLosContactos();\n          break;\n        case \"6\":\n          finalizar();\n          break;\n        default:\n          console.log(\"Operación no válida\");\n          read.close();\n      }\n    })\n  );\n};\nmenu();\n\nconst repetirOperacion = () => {\n  read.question(\"¿Desea realizar otra operación? 1.Si | 2.No \\n\", (ope) => {\n    if (ope === \"1\") menu();\n    else {\n      console.log(\"Hasta luego\");\n      read.close();\n    }\n  });\n};\n\nconst agregarContacto = () => {\n  console.log(\"Agregar Contacto:\");\n  read.question(\"Nombre del Contacto: \", (nombre) => {\n    read.question(\"Número de Teléfono: \", (telefono) => {\n      if (isNaN(telefono) | (telefono.length > 11)) {\n        console.log(\"El número de teléfono no es correcto, Intente de nuevo\");\n        agregarContacto();\n      } else contacto = { nombre, telefono };\n      agenda.push(contacto);\n      console.log(`Contacto ${nombre} agregado con éxtio`);\n      repetirOperacion();\n    });\n  });\n};\n\nconst buscarContacto = (callback) => {\n  console.log(\"Buscar Contacto:\");\n  read.question(\"Nombre del Contacto: \", (nombre) => {\n    const encontrado = agenda.filter((contacto) => contacto.nombre === nombre);\n    if (encontrado.length > 0) {\n      console.log(\n        `CONTACTO: \\n Nombre: ${contacto.nombre} \\n Teléfono: ${contacto.telefono}`\n      );\n      if (callback) callback(encontrado);\n    } else console.log(\"Contacto no encontrado\");\n    repetirOperacion();\n  });\n};\n\nconst mostrarTodosLosContactos = () => {\n  if (agenda.length < 1) console.log(\"No hay contactos agregados\");\n  else console.log(agenda);\n  repetirOperacion();\n};\n\nconst actualizarContacto = () => {\n  buscarContacto((encontrado) => {\n    if (encontrado) {\n      read.question(\"Nuevo Nombre: \", (nombre) => {\n        read.question(\"Nuevo Teléfono: \", (telefono) => {\n          encontrado[0].nombre = nombre;\n          encontrado[0].telefono = telefono;\n          console.log(`Contacto Actualizado ${nombre} con éxito`);\n          repetirOperacion();\n        });\n      });\n    } else {\n      console.log(\"Contacto no encontrado\");\n    }\n  });\n};\n\nconst eliminarContacto = () => {\n  read.question(\"Nombre: \", (nombre) => {\n    agenda = agenda.filter((contacto) => contacto.nombre !== nombre);\n    console.log(`Contacto ${nombre} eliminado con éxito`);\n    repetirOperacion();\n  });\n};\n\nconst finalizar = () => {\n  console.log(\"Operación Finalizada, !Hasta Luego!\");\n  read.close();\n};\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/EloyParga.js",
    "content": "// 1. Arrays\nlet arrayDatosSub = [\"Spira\", \"Drazz\", \"Espaby\", \"Kainyan77\"];\nconsole.log(\"Array Inicial: \",arrayDatosSub);\n\n//Insercción\narrayDatosSub.push(\"EloyParga\"); //Añade un elemento al final\nconsole.log(\"Despues de la insercción\" , arrayDatosSub);\n\n//Boorar\narrayDatosSub.slice(0,1);\nconsole.log(\"Despues de Borrar\", arrayDatosSub );\n\n//Actualización\narrayDatosSub[2] = \"ESPABY\";\nconsole.log(\"Despues de Actualizar \", arrayDatosSub)\n\n//Ordenación\n/**\n * @method sort()\n * por defecto ordena lexicograficamente\n * por @param podemos pasarle de forma OPCIONAL\n * una regla que defina el orden de los elementos\n */\narrayDatosSub.sort((a, b) => a.length - b.length); // Odena de menor a mayor longitud de palabra\nconsole.log(\"Despues de ordenar \" , arrayDatosSub)\n\n\n//2. Objetos\nlet listaTrabajadores = {\n    trabajador1: \"Manolo\",\n    trabajador2: \"Jony\"\n}\n    console.log(\"Objeto Inicial \", listaTrabajadores);\n\n//Insercción\nlistaTrabajadores.trabajador3 = \"Pepe\";\nconsole.log (\"Despues de insertar \", listaTrabajadores)\n\n//Borrar\ndelete listaTrabajadores.trabajador1\nconsole.log(\"Despues de borrar \", listaTrabajadores);\n\n//Actualizar\nlistaTrabajadores.trabajador2 = \"Jonathan\";\nconsole.log(\"Despues de actualizar \", listaTrabajadores);\n\n\n// 3.Mapas\nlet mapa = new Map();\nmapa.set(\"a\", 1);\nmapa.set(\"b\", 2);\nconsole.log(\"Mapa Inicial: \", mapa);\n\n// Inserción\nmapa.set(\"c\", 3);\nconsole.log(\"Despues de la Inserción: \", mapa);\n\n// Borrar\nmapa.delete(\"b\");\nconsole.log(\"Despues de Borrar: \", mapa);\n\n// Actualizar\nmapa.set(\"c\", 10);\nconsole.log(\"Despues de Actualizar: \", mapa);\n\n\n\n//DIFICULTAD EXTRA: AGENDA DE CONTACTOS \nconst readline = require(\"readline\");\n\nconst agenda = new Map();\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout,\n});\n\n//validar que el numero sea válido\nfunction validacionNum(numero){\n    return /^[0-9]{1,11}$/.test(numero)\n}\n\n//Funciones para las operaciones de la agenda\nfunction insertarContacto(nombre, numero) {\n    if(!validacionNum(numero)){\n        console.log(\"Numero de telefono no valido, debe contener solo numeros y maximo 11 digitos\");\n        return;\n    }\n    agenda.set(nombre, numero);\n    console.log(\"Contacto añadido\");\n}\n\nfunction buscarContacto(nombre) {\n    if(agenda.has(nombre)) {\n        console.log(`Contacto encontrado: ${nombre} - ${agenda.get(nombre)}`);\n    }else{\n        console.log(\"Contacto no encontrado\");\n    }\n}\n\nfunction actualizarContacto(nombre, Newnumero){\n    if(!agenda.has(nombre)){\n        console.log(\"El contacto no existe\");\n    }\n\n    if(!validacionNum(Newnumero)){\n        console.log(\"Numero de telefono no valido, debe contener solo numeros y maximo 11 digitos\");\n        return;\n    }\n\n    agenda.set({nombre, Newnumero});\n    console.log(\"Contacto actualizado\");\n}\n\nfunction eliminarContacto(nombre,){\n    if(agenda.delete(nombre)){\n        console.log(\"Contacto Eliminado\");\n    }else{\n        console.log(\"El contacto no existe\");\n    }\n}\n\nfunction mostrarAgenda(){\n    if(agenda.size === 0){\n        console.log(\"La agenda esta vacia\");\n    }else{\n        console.log(\"==CONTACTO DE LA AGENDA==\");\n        agenda.forEach((nombre, numero) => {\n            console.log(`- ${nombre}: ${numero}`);\n        })\n    }\n}\n\n\n//MENU AGENDA\n\nfunction menu(){\n    console.log(\"\\n=== AGENDA CONTACTOS ===\");\n    console.log(\"1. Insertar Contacto\");\n    console.log(\"2. Buscar Contacto\");\n    console.log(\"3. Actualizar Contacto\");\n    console.log(\"4. Eliminar Contacto\");\n    console.log(\"5. Mostrar todos los contacto\");\n    console.log(\"6. SALIR\");\n\n    rl.question(\"Selecciona una opción: \", (opcion) => {\n        switch(opcion){\n            case \"1\":\n                rl.question(\"Introduce el nombre\", (nombre)=> {\n                    rl.question(\"Introduce el numero de telefono\", (numero)=> {\n                        insertarContacto(nombre, numero);\n                        menu();\n                    });\n                });\n                break;\n\n            case \"2\":\n                rl.question(\"Introduce el nombre del contacto\", (nombre) => {\n                    buscarContacto(nombre);\n                    menu();\n                });\n                break;\n\n            case \"3\":\n                rl.question(\"Introduce el nombre\", (nombre)=> {\n                    rl.question(\"Introduce el nuevo numero de telefono\", (numero)=> {\n                        actualizarContacto(nombre, numero);\n                        menu();\n                    });\n                });\n                break;\n\n            case \"4\":\n                rl.question(\"Introduce el nombre del contacto que desea eliminar\", (nombre) => {\n                    eliminarContacto(nombre);\n                    menu();\n                });\n                break;\n\n            case \"5\":\n                mostrarAgenda();\n                menu();\n                break;\n\n            case \"6\":\n                console.log(\"Ha salido de la agenda.  ¡ADIOS!\");\n                rl.close();\n                break;\n\n            default:\n                console.log(\"Opcion no valida\");\n                menu();\n        }\n    });\n}\n\n//Inicializar el menu\nmenu();"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/FabianRpv.js",
    "content": "// Estructura de Datos\n\n// Arrays\n\nlet autos = [\"BMW\", \"Audi\", \"Mercedes\", \"Nissan\"];\nconsole.log(autos);\n\n// Inserción en Arrays\n\nconst agregarAdelante = () => {\n  let array = autos.slice();\n  array.unshift(\"Ford\"); // Agrega un elemento al inicio del array\n  console.log(array);\n};\n\nagregarAdelante();\n\nconst agregarAlFinal = () => {\n  let array = autos.slice();\n  array.push(\"Ford\"); // Agrega un elemento al final del array\n  console.log(array);\n};\n\nagregarAlFinal();\n\n// Borrado en Arrays\n\nconst eliminarAdelante = () => {\n  let array = autos.slice();\n  array.shift(); // Elimina el primer elemento del array\n  console.log(array);\n};\n\neliminarAdelante();\n\nconst eliminarAlFinal = () => {\n  let array = autos.slice();\n  array.pop(); // Elimina el último elemento del array\n  console.log(array);\n};\n\neliminarAlFinal();\n\nconst eliminarYAgregar = () => {\n  let array = autos.slice();\n  array.splice(2, 1, \"Ford\"); // Elimina un elemento y agrega otro\n  console.log(array);\n};\n\neliminarYAgregar();\n\n// Actualizacion en Arrays\n\nconst actualizarElemento = () => {\n  let array = autos.slice();\n  array[1] = \"McLaren\"; // Actualiza un elemento del array\n  console.log(array);\n};\n\nactualizarElemento();\n\n// Ordenacion en Arrays\n\nconst ordenarAlfabeticamente = () => {\n  let array = autos.slice();\n  array.sort(); // Ordena alfabéticamente\n  console.log(array);\n};\n\nordenarAlfabeticamente();\n\nconst invertirOrden = () => {\n  let array = autos.slice();\n  array.reverse(); // Invierte el orden\n  console.log(array);\n};\n\ninvertirOrden();\n\n// Sets\n\nlet frutas = new Set([\"Manzana\", \"Pera\", \"Naranja\", \"Fresa\"]);\nconsole.log(frutas);\n\n// Inserción en Sets\n\nconst agregarElemento = () => {\n  let set = new Set(frutas);\n  set.add(\"Mora\");\n  console.log(set);\n};\n\nagregarElemento();\n\n// Borrado en Sets\n\nconst eliminarElemento = () => {\n  let set = new Set(frutas);\n  set.delete(\"Pera\");\n  console.log(set);\n};\n\neliminarElemento();\n\n// Saber si existe un valor en Sets\n\nconst existeValor = () => {\n  let set = new Set(frutas);\n  console.log(set.has(\"Piña\"));\n};\n\nexisteValor();\n\n// Maps\n\nlet personas = new Map([\n  [\"nombre\", \"Fabian\"],\n  [\"apellido\", \"Petit\"],\n  [\"edad\", 20],\n]);\n\nconsole.log(personas);\n\n// Inserción en Maps\n\nconst agregarElementoMap = () => {\n  let map = new Map(personas);\n  map.set(\"sexo\", \"Masculino\");\n  console.log(map);\n};\n\nagregarElementoMap();\n\n// Borrado en Maps\n\nconst eliminarElementoMap = () => {\n  let map = new Map(personas);\n  map.delete(\"apellido\");\n  console.log(map);\n};\n\neliminarElementoMap();\n\n// Actualizacion en Maps\n\nconst actualizarElementoMap = () => {\n  let map = new Map(personas);\n  map.set(\"edad\", 25);\n  console.log(map);\n};\n\nactualizarElementoMap();\n\n// Obtener un valor en Maps\n\nconst obtenerValorMap = () => {\n  let map = new Map(personas);\n  console.log(map.get(\"nombre\"));\n};\n\nobtenerValorMap();\n\n// Saber si existe una clave en Maps\n\nconst existeClaveMap = () => {\n  let map = new Map(personas);\n  console.log(map.has(\"Ciudad\"));\n};\n\nexisteClaveMap();\n\n// Objetos\n\nlet persona = {\n  nombre: \"Fabian\",\n  apellido: \"Petit\",\n  edad: 20,\n};\n\nconsole.log(persona);\n\n// Inserción en Objetos\n\npersona.sexo = \"Masculino\";\nconsole.log(persona);\n\n// Borrado en Objetos\n\ndelete persona.sexo;\nconsole.log(persona);\n\n// Actualizacion en Objetos\n\npersona.edad = 25;\nconsole.log(persona);\n\n/*\nCrea una agenda de contactos por terminal.\n- Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n- Cada contacto debe tener un nombre y un número de teléfono.\n- El programa solicita en primer lugar cuál es la operación que se quiere realizar,\ny a continuación los datos necesarios para llevarla a cabo.\n- El programa no puede dejar introducir números de teléfono no numéricos\ny con más de 11 dígitos (o el número de dígitos que quieras).\n- También se debe proponer una operación de finalización del programa.\n*/\n\n\nconst readline = require(\"readline\");\n\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout,\n});\n\nconst mostrarMenu = () => {\n  console.log(\"1. Buscar contacto\");\n  console.log(\"2. Insertar contacto\");\n  console.log(\"3. Actualizar contacto\");\n  console.log(\"4. Eliminar contacto\");\n  console.log(\"5. Salir\");\n};\n\nconst buscarContacto = (nombre) => {\n  return agenda.find((contacto) => contacto.nombre === nombre);\n};\n\nconst insertarContacto = (nombre, telefono) => {\n  if (/^\\d{1,11}$/.test(telefono)) {\n    agenda.push({ nombre, telefono });\n    console.log(`Contacto \"${nombre}\" insertado correctamente.`);\n  } else {\n    console.log(\n      \"Numero de telefono no valido. Debe ser numerico y tener maximo 11 digitos.\"\n    );\n  }\n};\n\nconst actualizarContacto = (nombre, nuevoTelefono) => {\n  if (/^\\d{1,11}$/.test(nuevoTelefono)) {\n    const contacto = buscarContacto(nombre);\n    if (contacto) {\n      contacto.telefono = nuevoTelefono;\n      console.log(`Contacto \"${nombre}\" actualizado correctamente.`);\n    } else {\n      console.log(`Contacto \"${nombre}\" no encontrado.`);\n    }\n  } else {\n    console.log(\n      \"Numero de telefono no valido. Debe ser numerico y tener maximo 11 digitos.\"\n    );\n  }\n};\n\nconst eliminarContacto = (nombre) => {\n  const indice = agenda.findIndex((contacto) => contacto.nombre === nombre);\n  if (indice !== -1) {\n    agenda.splice(indice, 1);\n    console.log(`Contacto \"${nombre}\" eliminado correctamente.`);\n  } else {\n    console.log(`Contacto \"${nombre}\" no encontrado.`);\n  }\n};\n\nlet agenda = [];\n\nconst iniciarAgenda = () => {\n\n  mostrarMenu();\n  rl.question(\"Seleccione una Opcion: \", (menu) => {\n\n    switch (menu) {\n\n      case \"1\":\n        rl.question(\"Ingrese el nombre del contacto a buscar: \", (nombre) => {\n          const contacto = buscarContacto(nombre);\n          if (contacto) {\n            console.log(\n              `Contacto encontrado: Nombre: ${contacto.nombre}, Telefono: ${contacto.telefono}`\n            );\n          } else {\n            console.log(`Contacto \"${nombre}\" no encontrado.`);\n          }\n          iniciarAgenda();\n        });\n\n        break;\n\n      case \"2\":\n        rl.question(\"Ingrese el nombre del contacto: \", (nombre) => {\n          rl.question(\"Ingrese el numero de telefono: \", (telefono) => {\n            insertarContacto(nombre, telefono);\n            iniciarAgenda();\n          });\n        });\n\n        break;\n\n      case \"3\":\n        rl.question(\"Ingrese el nombre del contacto a actualizar: \", (nombre) => {\n            rl.question(\"Ingrese el nuevo numero de telefono: \", (nuevoTelefono) => {\n                actualizarContacto(nombre, nuevoTelefono);\n                iniciarAgenda();\n              });\n          });\n\n        break;\n\n      case \"4\":\n        rl.question(\"Ingrese el nombre del contacto a eliminar: \", (nombre) => {\n          eliminarContacto(nombre);\n          iniciarAgenda();\n        });\n\n        break;\n\n      case \"5\":\n        console.log(\"Saliendo del programa...\");\n        rl.close();\n        break;\n\n      default:\n        console.log(\"Opcion no valida\");\n    }\n  });\n};\n\niniciarAgenda();\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/Facundo-Muoio.js",
    "content": "const obj = {\n\tnombre: \"Facundo\",\n\tapellido: \"Muoio\",\n\tphoneNumber: 4546521,\n\taddress: \"Avenida Siempre Viva 200\",\n\tage: 27,\n\tmarried: false,\n\tfavoriteMovies: [\n\t\t\"The wolf of wall street\",\n\t\t\"The prestige\",\n\t\t\"The hateful eight\",\n\t\t\"Goodfellas\",\n\t],\n};\n\n//actualizacion de propiedad\nobj.nombre = \"Daniel\";\n//eliminacion de propieda\ndelete obj.married;\n//insercion de propiedad\nobj.favoriteSport = \"Futbol\";\n\n// Arreglos\nconst numbers = [2, 3, 6, 8, 9, 10, 1, 4, 7, 5];\n\n//insertar un elemento en un arreglo\nnumbers.push(11);\nnumbers.unshift(0);\n\n//acutualizar un elemento en un arreglo\nnumbers[numbers.length - 1] = 12;\n\n//eliminar elementos de un arreglo\nnumbers.pop();\nnumbers.shift();\n\n//eliminar e insertar elementos de un arreglo\nnumbers.splice(3, 1, 4);\n\n//ordernar los elmentos del arreglo de menor a mayor\nnumbers.sort((a, b) => a - b);\n//ordenar de mayor a menor\nnumbers.sort((a, b) => b - a);\n\n////cambiar todos los elementos de un array\nnumbers.fill(3);\n\n//Sets\nconst set = new Set();\n\n//Añadir elementos\nset.add(1);\nset.add(2);\nset.add(3);\n\n//Eliminar un elemnto\nset.delete(2);\n//Eliminar todos los elementos\nset.clear();\n\nconsole.log(set[0]);\n\n//Maps\nconst map = new Map();\n\n//Añadir elementos\nmap.set(\"A\", \"10\");\nmap.set(\"B\", \"8\");\nmap.set(\"C\", \"6\");\nmap.set(\"F\", \"4\");\n\n//Actualizar elemento\nmap.set(\"A\", \"9\");\n\n//Eliminar elementos\nmap.delete(\"F\");\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/Glitzypanic.js",
    "content": "// ESTRUCTURA DE DATOS\nlet numero_orden = [1, 3, 5, 2, 4]; // Array\n\nconsole.log(numero_orden);\nnumero_orden.push(6); // Agregar un elemento al final\nconsole.log(numero_orden);\nnumero_orden.pop(); // Eliminar el último elemento\nconsole.log(numero_orden);\nnumero_orden.unshift(0); // Agregar un elemento al principio\nconsole.log(numero_orden);\nnumero_orden.shift(); // Eliminar el primer elemento\nconsole.log(numero_orden[1]);\nnumero_orden[4] = \"Hola\"; // Modificar un elemento y actualizar el array\nconsole.log(numero_orden);\nnumero_orden.sort(); // Ordenar el array\nconsole.log(numero_orden);\nnumero_orden.reverse(); // Invertir el orden del array\nconsole.log(numero_orden);\nnumero_orden.splice(2, 1); // Eliminar un elemento en la posición 2\nconsole.log(numero_orden);\nnumero_orden.splice(2, 0, 5); // Agregar un elemento en la posición 2\nconsole.log(numero_orden);\nnumero_orden.lastIndexOf(5); // Buscar la última posición de un elemento\nconsole.log(numero_orden);\n\n// Objeto\nlet persona = {\n  nombre: \"Juan\",\n  edad: 25,\n  direccion: {\n    calle: \"Av. Siempre Viva\",\n    numero: 123,\n    ciudad: \"Springfield\",\n  },\n};\n\n// Map\nlet map = new Map().set(\"nombre\", \"Juan\").set(\"edad\", 25).set(\"direccion\", {\n  calle: \"Av. Siempre Viva\",\n  numero: 123,\n  ciudad: \"Springfield\",\n});\n\n// Set\nlet set = new Set().add(\"Juan\").add(25);\n\nset.add(\"Jose\");\nset.add(89);\nconsole.log(set);\n\n// Clase\nclass Persona {\n  constructor(nombre, edad) {\n    this.nombre = nombre;\n    this.edad = edad;\n  }\n}\n\n// Promesa\nlet output = new Promise((resolve, reject) => {\n  setTimeout(() => {\n    resolve(\"Hola mundo\");\n  }, 2000);\n});\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/Jalivur.js",
    "content": "/*\r\n * EJERCICIO:\r\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\r\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\r\n *\r\n * DIFICULTAD EXTRA (opcional):\r\n * Crea una agenda de contactos por terminal.\r\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\r\n * - Cada contacto debe tener un nombre y un número de teléfono.\r\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\r\n *   los datos necesarios para llevarla a cabo.\r\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\r\n *   (o el número de dígitos que quieras)\r\n * - También se debe proponer una operación de finalización del programa.\r\n */\r\n\r\n//ESTRUCTURAS DE DATOS:\r\n//ARRAY\r\nconsole.log(`===============`);\r\nconsole.log(`ARRAYS: se pueden definir \r\nde 3 formas:`);\r\nlet arr1 = new Array(1, 1.1, \"hola\", true);\r\nconsole.log(`let arr1 = new Array (1, 1.1, \"hola\", true)  \r\n${arr1}`);\r\nconsole.log(`===============`);\r\nlet arr2 = Array(1, 1.1, \"hola\", true);\r\nconsole.log(`let arr2 = Array (1, 1.1, \"hola\", true)\r\n${arr2}`);\r\nconsole.log(`===============`);\r\nlet arr3 = [1, 1.1, \"hola\", true];\r\nconsole.log(`let arr3 = [1, 1.1, \"hola\", true]\r\n${arr3}`);\r\nconsole.log(`===============`);\r\nconsole.log(`Tambien se pueden asignar \r\ncomo propiedade de un objeto:\r\nlet obj1 = {}\r\nobj1.prop = arr3`);\r\nlet obj1 = {};\r\nobj1.prop = arr3;\r\nconsole.log(obj1);\r\nconsole.log(`===============`);\r\nlet arrayEmpty = Array(42);\r\nconsole.log(`Tambien se pueden crear\r\nsin elementos:\r\nlet arryEmpty = Array(${arrayEmpty.length})\r\n${arrayEmpty}\r\nen este caso con longitud ${arrayEmpty.length}.\r\nSiempre y cuando el valor sea un numero entero.`);\r\nconsole.log(`===============`);\r\nlet arrayEmpty2 = new Array(15);\r\nconsole.log(`Tambien se puede:\r\nlet arryEmpty = new Array(${arrayEmpty2.length})\r\n${arrayEmpty2}\r\nen este caso con longitud ${arrayEmpty2.length}.\r\nSi el valor no es numero enter, dara error de rango.`);\r\nconsole.log(`===============`);\r\nlet arrayOneElement = [58];\r\nconsole.log(`Sin ebargo con la declaracion literal:\r\nlet arryOneElement = [${arrayOneElement}]\r\nen este caso es un array de un elemento: ${arrayOneElement}\r\nculla longitud es ${arrayOneElement.length}.`);\r\nconsole.log(`===============`);\r\nlet arrayOneElement2 = Array.of(10.5);\r\nconsole.log(`Desde ES2015 se puede utilizar el metodo estatico Array.of:\r\nlet arryOneElement2 = Array.of(${arrayOneElement2})\r\nen este caso es un array de un elemento: ${arrayOneElement2}\r\nculla longitud es ${arrayOneElement2.length}.`);\r\nconsole.log(`===============`);\r\n\r\n//Manejo de arrays:\r\nconsole.log(`===============`);\r\nconsole.log(`Operaciones Con Arrays`);\r\nconsole.log(`===============`);\r\nlet arrayEmpty3 =[];\r\nconsole.log(`Un array se puede declarar vacio, let arrayEmpty3 = [${arrayEmpty3}];`);\r\nconsole.log(`===============`);\r\narrayEmpty3.push(\"Alberto\",\"Estella\");\r\nconsole.log(`Con el metodo arraEmpy3.push(\"${arrayEmpty3[0]}\",\"${arrayEmpty3[1]}\"), añadimos contenido [${arrayEmpty3}]`);\r\nconsole.log(`===============`);\r\nconsole.log(`===============`);\r\nlet array1=arrayEmpty3;\r\nlet array2=new Array(\"Jalivur\",\"Pamplona\");\r\nconsole.log(`Teniendo dos array, array1=[${array1}] y array2=[${array2}],\r\nCon el metodo array1.concat(array2), concatenamos el contenido [${array1=array1.concat(array2)}]`);\r\nconsole.log(`===============`);\r\nconsole.log(`===============`);\r\narray1[4]=true;\r\nconsole.log(`Tambien podemos añadir, o modificar los valores de un array haciendo referencia al index a añadir o modificar,\r\narray1[4]=${array1[4]}, de esta manera ahora array1=[${array1}].`);\r\narray1[3]=\"Falces\"\r\nconsole.log(`Si hacemos referencia a un index vacio, lo ocupamos, mientras que si hacemos referencia a un index ocupado, actualizamos su valor.\r\narray1[3]=\"${array1[3]}\", ahora el array queda array1=[${array1}]`);\r\narray1[20]=\"hola\"\r\nconsole.log(`Si hacemos referencia a un index vacio lejano de los ocupados,\r\narray1[20]=\"${array1[20]}\", ahora el array queda array1=[${array1}]`);\r\nconsole.log(`===============`);\r\nconsole.log(`===============`);\r\nlet allValues=array1.join('-');\r\nconsole.log(`Con el metodo join(delimiter=('-')) podemos unir todos los elementos en un string separados por el caracter del delimitador,\r\nlet allValues=array1.join('-')= ${allValues}.`);\r\nconsole.log(`===============`);\r\nconsole.log(`===============`);\r\nlet popValue = array1.pop();\r\nconsole.log(`Con el metodo pop() extrae el ultimo valor del array,\r\nlet popValue = array1.pop()= ${array1}.\r\npodemos usar par ir eliminando los valores desde el ultimo, o podemos almacenar esos valores en variables.\r\npopValue = ${popValue}`);\r\nconsole.log(`===============`);\r\nconsole.log(`===============`);\r\nlet shiftValue = array1.shift();\r\nconsole.log(`Con el metodo shift() extrae el primer valor del array,\r\nlet shiftValue = array1.shift()= ${array1}.\r\npodemos usar par ir eliminando los valores desde el primero, o podemos almacenar esos valores en variables.\r\nshiftValue = ${shiftValue}`);\r\nconsole.log(`===============`);\r\nconsole.log(`===============`);\r\nlet unshiftValue1 = (\"Alberto\");\r\nlet unshiftValue2 = (2);\r\narray1.unshift(unshiftValue1,unshiftValue2)\r\nconsole.log(`Con el metodo unshift() añadir valores al principio del array,\r\narray1.unshift(${unshiftValue1},${unshiftValue2})= ${array1}.`);\r\nconsole.log(`===============`);\r\nconsole.log(`===============`);\r\nlet startIndex=0;\r\nlet upToIndex=4;\r\nlet sliceArray = array1.slice(startIndex,upToIndex)\r\nconsole.log(`Con el metodo slice() añadir valores al principio del array,\r\narray1.slice(${startIndex},${upToIndex})= [${sliceArray}}].`);\r\nconsole.log(`===============`);\r\nconsole.log(`===============`);\r\nlet index=5;\r\nlet countToRemove=20;\r\nlet addElement1=\"Tecnico De Mantenimento\";\r\nlet addElement2=\"Volkswagen Navarra\";\r\narray1.splice(index, countToRemove, addElement1, addElement2)\r\nconsole.log(`Con el metodo splice() eliminar valores, indicando el primer index a eliminar, y el numero de valores a eliminar,\r\ny opcionalmente se pueden añadir valores.\r\narray1.splice(${index},${countToRemove},${addElement1},${addElement2})= [${array1}].`);\r\nconsole.log(`===============`);\r\nconsole.log(`===============`);\r\nconsole.log(`array1=[${array1}]`)\r\narray1.reverse()\r\nconsole.log(`Con el metodo revese() invertimos el orden del array.\r\narray1.reverse()= [${array1}].`);\r\nconsole.log(`===============`);\r\nconsole.log(`===============`);\r\nconsole.log(`array1=[${array1}]`)\r\narray1.sort()\r\nconsole.log(`Con el metodosort() ordenamos el array.\r\narray1.sort()= [${array1}].`);\r\nconsole.log(`===============`);\r\n\r\n//Map:\r\nconsole.log(`===============`);\r\nconsole.log(`Objeto Mapa, Map(), son objetos clave,valor:\r\nSe puede definir,\r\nlet matrimonios = new Map()`);\r\nlet matrimonios = new Map();\r\nlet setKey1 = \"Alberto\";\r\nlet setValue1 = \"Sandra\";\r\nlet setKey2 = \"Cesar\";\r\nlet setValue2 = \"Nadie\";\r\nmatrimonios.set(setKey1, setValue1);\r\nmatrimonios.set(setKey2, setValue2);\r\nconsole.log(`===============`);\r\nconsole.log(`Con el metodo set(), añadimos las parejas de clave valor al mapa.\r\nlet setKey1 = \"Alberto\";\r\nlet setValue1 = \"Sandra\";\r\nlet setKey2 = \"Cesar\";\r\nlet setValue2 = \"Nadie\";\r\nmatrimonios.set(setKey1, setValue1)\r\nmatrimonios.set(setKey2, setValue2)`);\r\nfor (let [key, value] of matrimonios) {\r\n    console.log(key + \" esta casado con \" + value);\r\n};\r\nconsole.log(`===============`);\r\nconsole.log(`===============`);\r\nmatrimonios.delete(setKey2)\r\nconsole.log(`Con el metodo delete(), eliminamos mediante la clave, el objeto del mapa correspodiente.\r\nmatrimonios.delete(\"${setKey2}\")`);\r\n\r\nfor (let [key, value] of matrimonios) {\r\n    console.log(key + \" esta casado con \" + value);\r\n};\r\nconsole.log(`===============`);\r\nconsole.log(`===============`);\r\nconsole.log(`Con el metodo has(), podemos comprobar si algo se encuentra en el mapa.`);\r\nconsole.log(`matrimonios.has(${setKey1})=${matrimonios.has(setKey1)}`);\r\nconsole.log(`matrimonios.has(${setKey2})=${matrimonios.has(setKey2)}`);\r\nconsole.log(`===============`);\r\nmatrimonios.set(setKey2,setValue2)\r\nconsole.log(`Al volver a utilizar el metodo set(), ahora matrimonios.has(${setKey2})=${matrimonios.has(setKey2)}`);\r\nconsole.log(`===============`);\r\nconsole.log(`===============`);\r\nconsole.log(`Con el metodo get() obtenemos el valor para una clave, matrimonios.get(${setKey2})=${matrimonios.get(setKey2)}.`);\r\nconsole.log(`===============`);\r\nconsole.log(`===============`);\r\nconsole.log(`Con el metodo size() obtenemos el valor del tamaño del mapa, matrimonios.size=${matrimonios.size}.`);\r\nconsole.log(`===============`);\r\nconsole.log(`===============`);\r\nmatrimonios.clear();\r\nconsole.log(`Con el metodo clear() limpiamos el mapa, matrimonios.clear() = matrimonios.size = ${matrimonios.size}.`);\r\nconsole.log(`===============`);\r\n\r\n//Set:\r\nconsole.log(`===============`);\r\nlet mySet = new Set();\r\nlet setValue3 = 1;\r\nlet setValue4 = \"algún texto\";\r\nlet setValue5 = \"foo\";\r\nmySet.add(setValue3);\r\nmySet.add(setValue4);\r\nmySet.add(setValue5);\r\nconsole.log(`Un objeto Set, se declara:\r\nlet mySet = new Set();.\r\nEstos son colecciones de valores, con el metodo add() añadimos valores.\r\nlet setValue3 = 1;\r\nlet setValue4 = \"algún texto\";\r\nlet setValue5 = \"foo\";\r\nmySet.add(${setValue3});\r\nmySet.add(${setValue4});\r\nmySet.add(${setValue5});`)\r\nfor (let item of mySet) console.log(item);\r\nconsole.log(`===============`);\r\nconsole.log(`mySet.has(${setValue3}) = ${mySet.has(setValue3)}`); // true\r\nconsole.log(`===============`);\r\nmySet.delete(\"foo\");\r\nmySet.size; // 2\r\nfor (let item of mySet) console.log(item);\r\nconsole.log(`===============`);\r\nconst { copyFileSync } = require('fs');\r\n/*\r\n* DIFICULTAD EXTRA (opcional):\r\n* Crea una agenda de contactos por terminal.\r\n* - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\r\n* - Cada contacto debe tener un nombre y un número de teléfono.\r\n* - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\r\n*   los datos necesarios para llevarla a cabo.\r\n* - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\r\n*   (o el número de dígitos que quieras)\r\n* - También se debe proponer una operación de finalización del programa.\r\n*/\r\n\r\n//Creacion de interactividad con consola.\r\nconst readline = require('readline');\r\nconst rl = readline.createInterface({\r\n    input: process.stdin,\r\n    output: process.stdout,\r\n\r\n});\r\n//Variables\r\nlet agenda = [\r\n    {\"nombre\":\"alberto\", \"tel\":\"638432255\", \"email\":\"esteya92@gmail.com\"},\r\n]\r\n\r\nlet nombre;\r\nlet tel;\r\nlet email;\r\nlet busqueda;\r\nlet contacto;\r\nlet select;\r\n\r\n//Funciones\r\nfunction insertAgenda(nombre,tel,email){\r\n        const esTelefonoValido = (telefono) => {\r\n            // Verifica que el teléfono solo contenga dígitos\r\n            const contieneSoloDigitos = Array.from(telefono).every(caracter => '0123456789'.includes(caracter));\r\n            return contieneSoloDigitos && telefono.length <= 11;\r\n        };\r\n        if (esTelefonoValido(tel)){\r\n            contacto={\r\n                \"nombre\":nombre,\r\n                \"tel\":tel,\r\n                \"email\":email,\r\n            };\r\n            agenda.push(contacto);\r\n            console.log(`===============`);\r\n            console.log(\"Contacto añadido con exito.\");\r\n            console.log(`===============`);\r\n            main();\r\n        }else{\r\n            console.log(`===============`);\r\n            console.log(\"Telefono no valido, deve contener solo numeros y maximo 11.\");\r\n            console.log(`===============`);\r\n            main();\r\n        };\r\n};\r\n\r\nfunction buscar(busqueda){\r\n        let contacto= agenda.find(contacto=>contacto.nombre===busqueda);\r\n        if (contacto){\r\n            console.log(`===============`);\r\n            console.log(\"Buscando····\");\r\n            console.log(`===============`);\r\n            console.log(\"Contacto Encotrado: \");\r\n            console.log(`===============`);\r\n            console.log(contacto);\r\n            console.log(`===============`);\r\n        }else{\r\n            console.log(`===============`);\r\n            console.log(\"Contacto no encotrado, Pruebe de nuevo.\");\r\n            console.log(`===============`);\r\n        };\r\n};\r\n\r\nfunction actualizar(nombre, tel, email){\r\n    contacto= agenda.findIndex(contacto=>contacto.nombre === nombre, tel, email);\r\n    if (contacto !== -1){\r\n        if (tel){\r\n            agenda[contacto].tel = tel;\r\n        }\r\n        if(email){\r\n            agenda[contacto].email = email;\r\n        }\r\n        console.log(`===============`);\r\n        console.log(`Informacion actualizada: ${JSON.stringify(agenda[contacto])}`);\r\n        console.log(`===============`);\r\n    }else{\r\n        console.log(`===============`);\r\n        console.log(\"Contacto no encotrado, Pruebe de nuevo.\");\r\n        console.log(`===============`);\r\n    }\r\n\r\n}\r\n\r\nfunction eliminar(nombre){\r\n    \r\n    const agendaActualizada = agenda.filter(contacto => contacto.nombre !== nombre);\r\n    \r\n    if (agenda.length !== agendaActualizada.length){\r\n        console.log(`===============`);\r\n        console.log('Contacto eliminado con exito');\r\n        console.log(`===============`);\r\n        agenda = agendaActualizada;\r\n        console.log(`===============`);\r\n        console.log(agenda);\r\n        console.log(`===============`);\r\n    }else{\r\n        console.log(`===============`);\r\n        console.log('Persona no encontrada');\r\n        console.log(`===============`);\r\n    };\r\n};\r\n\r\nfunction listaContactos(){\r\n    console.log(`===============`);\r\n    console.log(\"Esta es tu agenda completa:\");\r\n    console.log(agenda);\r\n    console.log(`===============`);\r\n};\r\n\r\n//Menu de seleccion.\r\nfunction main(){\r\n    console.log(`===============`);\r\n        rl.question(\"Eliga una opcion: \\nopcion 1, insertar contacto, \\nopcion 2, buscar contacto, \\nopcion 3, mostrar agenda completa, \\nopcion 4, actualizar, \\nopcion 5, eliminar, \\nopcion 6, salir, \\n¿Cual elige?:\", (respuesta) =>{\r\n            select = respuesta;\r\n            switch(select){\r\n                case \"1\":\r\n                    console.log(`===============`);\r\n                    rl.question(\"Nombre del contacto: \", (respuesta) =>{\r\n                        nombre = respuesta\r\n                        let contacto=agenda.find(contacto=>contacto.nombre===nombre);\r\n                        if (contacto){\r\n                            console.log(`===============`);\r\n                            console.log(contacto);\r\n                            console.log(`===============`);\r\n                            console.log(`Existe un contacto con nombre ${nombre}, instroduzca nombre diferente.`);\r\n                            console.log(`===============`);\r\n                            main();\r\n                        }else{\r\n                            console.log(`===============`);\r\n                            console.log(`Tu contacto se llama ${respuesta}`)\r\n                            console.log(`===============`);\r\n                            rl.question(\"Telefono del contacto: \", (respuesta) =>{\r\n                                tel = respuesta\r\n                                console.log(`===============`);\r\n                                console.log(`Tu contacto tiene el telefono ${respuesta}`);\r\n                                console.log(`===============`);\r\n                                rl.question(\"Email del contacto: \", (respuesta) =>{\r\n                                    email = respuesta\r\n                                    console.log(`===============`);\r\n                                    console.log(`Tu contacto tiene el email ${respuesta}`);\r\n                                    console.log(`===============`);\r\n                                    insertAgenda(nombre,tel,email);\r\n                                    main();\r\n                                });\r\n                            });\r\n                        };\r\n                    });\r\n                    break;\r\n                case \"2\":\r\n                    console.log(`===============`);\r\n                    rl.question(\"Nombre del contacto a buscar: \",(respuesta)=>{\r\n                        busqueda=respuesta;\r\n                        buscar(busqueda);\r\n                        main();\r\n                    });\r\n                    break;\r\n                case \"3\":\r\n                    listaContactos();\r\n                    main();\r\n                    break;\r\n                case \"4\":\r\n                    console.log(`===============`);\r\n                    rl.question(\"Nombre del contacto a actualizar: \", (respuesta) =>{\r\n                        nombre = respuesta\r\n                        let contacto= agenda.find(contacto=>contacto.nombre===nombre);\r\n                        if (contacto){\r\n                            console.log(`===============`);\r\n                            console.log(`Tu contacto se llama ${respuesta}`);\r\n                            console.log(`===============`);\r\n                            rl.question(\"Nuevo Telefono del contacto: \", (respuesta) =>{\r\n                                tel = respuesta\r\n                                if (tel){\r\n                                    console.log(`===============`);\r\n                                    console.log(`Tu contacto tiene ahora el telefono ${respuesta}`);\r\n                                }else{\r\n                                    console.log(`===============`);\r\n                                    console.log(`Tu contacto tiene ahora el mismo telefono que antes ${contacto[\"tel\"]}`);\r\n                                    console.log(`===============`);\r\n                                }\r\n                                console.log(`===============`);\r\n                                rl.question(\"Email del contacto: \", (respuesta) =>{\r\n                                    email = respuesta\r\n                                    if (email){\r\n                                        console.log(`===============`);\r\n                                        console.log(`Tu contacto tiene ahora el email ${respuesta}`);\r\n                                        actualizar(nombre,tel,email);\r\n                                        main();\r\n                                    }else{\r\n                                        console.log(`===============`);\r\n                                        console.log(`Tu contacto tiene ahora el mismo email que antes ${contacto[\"email\"]}`);\r\n                                        console.log(`===============`);\r\n                                        actualizar(nombre,tel,email);\r\n                                        main();\r\n                                    }\r\n                                });\r\n                            });\r\n                        }else{\r\n                            console.log(`===============`);\r\n                            console.log(\"Contacto no Encontrado.\");\r\n                            console.log(`===============`);\r\n                            main();\r\n                        };\r\n                    });\r\n                    break;\r\n                case \"5\":\r\n                    console.log(`===============`);\r\n                    rl.question(\"Nombre del contacto a eliminar: \",(respuesta)=>{\r\n                        busqueda=respuesta;\r\n                        eliminar(busqueda);\r\n                        main();\r\n                    });\r\n                    break;\r\n                case \"6\":\r\n                    console.log(`===============`);\r\n                    console.log(\"Te veo pronto, Adios.\");\r\n                    console.log(`===============`);\r\n                    rl.close();\r\n                    break;\r\n                default:\r\n                    console.log(`===============`);\r\n                    console.log(\"Inserte opcion valida\");\r\n                    console.log(`===============`);\r\n                    main();\r\n                    \r\n            };\r\n\r\n        });\r\n};\r\nmain();\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #03 - JavaScript ->Jesus Antonio Escamilla */\n/**\n * Dentro de los ejemplos de estructura de soporte tenemos:\n * Arrays\n * Objetos\n * Maps\n * Sets\n */\n\n\n\n//-----ARRAYS-----\n//  Esto es ejemplo de un Array\nvar frutas = [\"Manzana\", \"Pera\", \"Plátano\", \"Durazno\", \"Kiwi\", \"Fresa\"];\n\n//  INSERCIÓN\nfrutas.push(\"Uva\"); // Agrega al final\nconsole.log(frutas); //[ 'Manzana', 'Pera', 'Plátano', 'Durazno', 'Kiwi', 'Fresa', 'Uva' ]\n\nfrutas.unshift(\"Pasas\"); // Agrega al principio\nconsole.log(frutas); //[ 'Pasas', 'Manzana', 'Pera', 'Plátano', 'Durazno', 'Kiwi', 'Fresa', 'Uva' ]\n\nfrutas.splice(3, 0, \"Naranja\"); // Agrega en alguna parte del array, siempre y cuando se explique que se va agregar\nconsole.log(frutas); //[ 'Pasas', 'Manzana', 'Pera', 'Naranja', 'Plátano', 'Durazno', 'Kiwi', 'Fresa', 'Uva' ]\n\n\n//  BORRADO\nfrutas.pop(); // Elimina al final\nconsole.log(frutas); //[ 'Manzana', 'Pera', 'Naranja', 'Plátano', 'Durazno', 'Kiwi', 'Fresa' ]\n\nfrutas.shift(); // Elimina al principio\nconsole.log(frutas);\n\nfrutas.splice(2, 1); // Elimina una parte especifica en la cual le demos los parámetros\nconsole.log(frutas);\n\n\n//  ACTUALIZACIÓN\nfrutas[3] = \"Cereza\"; // Se actualiza el elemento en una posición especifica\nconsole.log(frutas);\n\n\n//  ORDENAMIENTO\nfrutas.sort(); // Esta es la forma simple de ordenamiento en menor a mayor ó bien de a - z\nconsole.log(frutas);\n\n\n\n//-----OBJETO-----\nvar persona = {\n    nombre: \"Jesus Antonio\",\n    edad: 23,\n    país: \"Mexico\",\n};\n\n//  INSERCIÓN\npersona.altura = 1.70; // Agrega una nueva propiedad\nconsole.log(persona);\n\n\n//  BORRADO\ndelete persona.altura; // Elimina una propiedad especifica\nconsole.log(persona);\n\n\n//  ACTUALIZACIÓN\npersona.edad = 24; // Se actualiza el valor de la piedad\nconsole.log(persona);\n\n\n//  ORDENAMIENTO\n// No existe una forma de ordenamiento para las propiedades\n// sin embargo se puede utilizar los valores de las propiedades\n// para hacer el ordenamiento\n\n\n\n//-----MAPS-----\nvar agendaTelefonica = new Map([\n    [\"Fatima\", { teléfono: \"953-123-4567\", email:\"fatima@example.com\"}],\n    [\"Rosa\", { teléfono: \"953-123-4567\", email:\"rosa@example.com\"}],\n]);\n\n//  INSERCIÓN\nagendaTelefonica.set(\"JesusAntonio\", { teléfono: \"953-000-0000\", email:\"jesus@example.com\"}); // Agrega un nuevo valor al map\nconsole.log(agendaTelefonica);\n\n\n//  BORRADO\nagendaTelefonica.delete(\"Rosa\"); // Elimina un valor especifico del map\nconsole.log(agendaTelefonica);\n\n\n//  ACTUALIZACIÓN\nagendaTelefonica.set(\"JesusAntonio\",  { teléfono: \"953-123-4567\", email:\"jesusantonio@example.com\"}); // Se actualiza el valor especifica del map\nconsole.log(agendaTelefonica);\n\n\n//  ORDENAMIENTO\n// No existe una forma de ordenamiento para los maps\n\n\n\n//-----SETS-----\nvar etiquetaArticulo = new Set([\n    \"Hogar\",\n    \"Ropa\",\n    \"Electrodomésticos\"\n]);\n\n//  INSERCIÓN\netiquetaArticulo.add(\"Juguetes\"); // Agrega un nuevo valor al set\nconsole.log(etiquetaArticulo);\n\n\n//  BORRADO\netiquetaArticulo.delete(\"Ropa\"); // Elimina un valor especifico del set\nconsole.log(etiquetaArticulo);\n\n\n//  ACTUALIZACIÓN\netiquetaArticulo.delete(\"Juguetes\"); // Se elimina el ultimo valor del set\netiquetaArticulo.add(\"Jardín\"); // Se agrega el nuevo valor al final del set\nconsole.log(etiquetaArticulo);\n\n\n//  ORDENAMIENTO\nvar sortArray = [...etiquetaArticulo].sort(); // Se hace el ordenamiento manera alfabética\nconsole.log(sortArray);\n\n\n\n/**-----DIFICULTAD EXTRA-----*/\n\nconst readline = require('readline');\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\nlet contacts = [];\n\nconst mainMenu = () => {\nrl.question(\"Choose an operation: search (s), insert (i), update (u), delete (d), list (l), exit (e): \",\n(choice) => {\n    switch (choice) {\n        case \"s\":\n            searchContact();\n            break;\n        case \"i\":\n            insertContact();\n            break;\n        case \"u\":\n            updateContact();\n            break;\n        case \"d\":\n            deleteContact();\n            break;\n        case \"l\":\n            listContacts();\n            break;\n        case \"e\":\n            rl.close();\n            break;\n        default:\n            console.log(\"Invalid choice.\");\n            mainMenu();\n            }\n        }\n    );\n};\n\nconst validatePhoneNumber = (number) => {\n    const regex = /^\\d{1,11}$/;\n    return regex.test(number);\n};\n\nconst findContactIndex = (name) =>\n    contacts.findIndex((c) => c.name.toLowerCase() === name.toLowerCase());\n\nconst searchContact = () => {\n    rl.question(\"Enter the name of the contact to search: \", (name) => {\n    const index = findContactIndex(name);\n    if (index !== -1) {\n        console.log(\n        `Contact found: ${contacts[index].name}, ${contacts[index].phone}`\n    );\n    } else {\n        console.log(\"Contact not found.\");\n    }\n    mainMenu();\n    });\n};\n\nconst insertContact = () => {\n    rl.question(\"Enter the name of the new contact: \", (name) => {\n        rl.question(\"Enter the phone number of the new contact: \", (phone) => {\n        if (!validatePhoneNumber(phone)) {\n            console.log(\"Invalid phone number.\");\n            insertContact();\n        } else {\n            contacts.push({ name, phone });\n            console.log(\"Contact inserted.\");\n            mainMenu();\n            }\n        });\n    });\n};\n\nconst updateContact = () => {\nrl.question(\"Enter the name of the contact to update: \", (name) => {\n    const index = findContactIndex(name);\n    if (index !== -1) {\n        rl.question(\"Enter the new phone number: \", (phone) => {\n            if (!validatePhoneNumber(phone)) {\n            console.log(\"Invalid phone number.\");\n            updateContact();\n        } else {\n            contacts[index].phone = phone;\n            console.log(\"Contact updated.\");\n            mainMenu();\n            }\n        });\n    } else {\n        console.log(\"Contact not found.\");\n        mainMenu();\n        }\n    });\n};\n\nconst deleteContact = () => {\nrl.question(\"Enter the name of the contact to delete: \", (name) => {\n    const index = findContactIndex(name);\n    if (index !== - 1) {\n        contacts.splice(index, 1);\n        console.log(\"Contact deleted.\");\n    } else {\n        console.log(\"Contact not found.\");\n        }\n        mainMenu();\n    });\n};\n\nconst listContacts = () => {\nif (contacts.length === 0) {\n    console.log(\"No contacts to display.\");\n    } else {\n    console.log(\"Contact List:\");\n    contacts.forEach((contact, index) => {\n        console.log(\n        `${index + 1}. Name: ${contact.name}, Phone: ${contact.phone}`\n        );\n    });\n}\nmainMenu();\n};\n\nmainMenu();\n\nrl.on(\"close\", () => {\n    console.log(\"Exiting contact list application.\");\n    process.exit(0);\n});\n\n/**-----DIFICULTAD EXTRA-----*/\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/Joanfv-git.js",
    "content": "//Ejemplo de creación de estructuras de datos en JavaScript\n//Array, Object, Map y Set son las estructuras de datos más comunes en JavaScript.\n\n//Array es una colección de elementos, donde cada elemento tiene un índice numérico.\nlet array = [1, 2, 3, 4, 5];\nconsole.log(array);\n//Operaciones de inserción\narray.push(6);\nconsole.log(array);\n//Operaciones de borrado\narray.pop();\nconsole.log(array);\n//Operaciones de actualización\narray[0] = 0;\nconsole.log(array);\n//Operaciones de ordenación\narray.sort();\nconsole.log(array);\n\n//Object es una colección de pares clave-valor, donde la clave es una cadena y el valor puede ser de cualquier tipo.\nlet object = { name: \"Joan\", age: 25, city: \"Barcelona\" };\nconsole.log(object);\n//Operaciones de inserción\nobject.job = \"Developer\";\nconsole.log(object);\n//Operaciones de borrado\ndelete object.city;\nconsole.log(object);\n//Operaciones de actualización\nobject.age = 26;\nconsole.log(object);\n//Operaciones de ordenación\n//No se pueden ordenar objetos\n\n//Map es una colección de pares clave-valor, donde tanto la clave como el valor pueden ser de cualquier tipo.\nlet map = new Map();\nmap.set(\"name\", \"Joan\");\nmap.set(\"age\", 25);\nmap.set(\"city\", \"Barcelona\");\nconsole.log(map);\n//Operaciones de inserción\nmap.set(\"job\", \"Developer\");\nconsole.log(map);\n//Operaciones de borrado\nmap.delete(\"city\");\nconsole.log(map);\n//Operaciones de actualización\nmap.set(\"age\", 26);\nconsole.log(map);\n//Operaciones de ordenación\n//No se pueden ordenar mapas\n\n//Set es una colección de valores únicos, lo que significa que un valor solo puede estar una vez en un set.\nlet set = new Set([1, 2, 3, 4, 5]);\nconsole.log(set);\n//Operaciones de inserción\nset.add(6);\nconsole.log(set);\n//Operaciones de borrado\nset.delete(1);\n\nconsole.log(set);\n//Operaciones de actualización\n//No se pueden actualizar elementos de un set\n//Operaciones de ordenación\n//No se pueden ordenar sets\n\n//Ejercicio extra\n//Crear una agenda:\n//Declaración de variables\nlet opcion;\nlet nombre = \"\";\nlet numTelf = \"\";\nlet agenda = new Map();\nlet is_on = true;\n//Bucle principal\nwhile (is_on == true) {\n  //Menú de opciones\n  console.log(\"Buscar contacto --> 1\");\n  console.log(\"Insertar contacto --> 2\");\n  console.log(\"Actualizar contacto --> 3\");\n  console.log(\"Eliminar contacto --> 4\");\n  console.log(\"Salir --> 5\");\n  //Selección de opción\n  opcion = parseInt(prompt(\"Elige una opcion: \"));\n  //Switch para cada opción\n  switch (opcion) {\n    case 1:\n      //Buscar contacto\n      //objecto.has(key) es un método que devuelve un booleano indicando si el objeto tiene la clave dada.\n      //objecto.get(key) es un método que devuelve el valor asociado con la clave dada.\n      nombre = prompt(\"Introduce el nombre del contacto: \");\n      if (agenda.has(nombre)) {\n        console.log(\n          `El contacto ${nombre} tiene el número ${agenda.get(nombre)}`\n        );\n      } else {\n        console.log(\"El contacto no existe\");\n      }\n      break;\n    case 2:\n      //Insertar contacto\n      //objecto.set(key, value) es un método que añade un nuevo par clave-valor al objeto.\n      nombre = prompt(\"Introduce el nombre del contacto: \");\n      numTelf = prompt(\"Introduce el número de teléfono: \");\n      if (numTelf.length === 11) {\n        agenda.set(nombre, numTelf);\n        console.log(\"Contacto añadido correctamente\");\n      } else {\n        console.log(\"Número de teléfono incorrecto\");\n      }\n      break;\n    case 3:\n      //Actualizar contacto\n      nombre = prompt(\"Introduce el nombre del contacto: \");\n      if (agenda.has(nombre)) {\n        nombre = prompt(\"Introduce el nuevo nombre del contacto: \");\n        numTelf = prompt(\"Introduce el nuevo número de teléfono: \");\n        if (numTelf.length === 11) {\n          agenda.set(nombre, numTelf);\n          console.log(\"Contacto actualizado correctamente\");\n        } else {\n          console.log(\"Número de teléfono incorrecto\");\n        }\n      } else {\n        console.log(\"El contacto no existe\");\n      }\n      break;\n    case 4:\n      //Eliminar contacto\n      //objecto.delete(key) es un método que elimina la clave y su valor asociado del objeto.\n      nombre = prompt(\"Introduce el nombre del contacto: \");\n      if (agenda.has(nombre)) {\n        agenda.delete(nombre);\n        agenda.delete(numTelf);\n        console.log(\"Contacto eliminado correctamente\");\n      } else {\n        console.log(\"El contacto no existe\");\n      }\n      break;\n    case 5:\n      console.log(\"Saliendo del programa. ¡Hasta luego!\");\n      is_on = false;\n      break;\n    default:\n      console.log(\"Opción incorrecta. Introduce un número del 1 al 5\");\n      break;\n  }\n}\nagenda();\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/JoaquinLopez14.js",
    "content": "/*\n * EJERCICIO:\n 1 - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n 1.1 DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\n//------------------------------------------------------------------------------------------------------\n\n/* 1\n    Arrays */\n\n    let array = [1, 6, 54, \"Joaquin\"]\n\nconsole.log(array) // [1, 6, 56, \"Joaquin\"]\n\n // operacion de insercion de datos al final de array\n\n    array.push(\"Lopez\");\n\nconsole.log(array) // [1, 6, 54, \"Joaquin\", \"Lopez\"]\n\n // operacion de insercion de datos al principio de un array\n\n    array.unshift(1000);\n\nconsole.log(array) // [1000, 1, 6, 54, \"Joaquin\", \"Lopez\"]\n\n// operacion de eliminacion al final de un array\n\n    array.pop();\n\nconsole.log(array) //[1000, 1, 6, 54, \"Joaquin\"]\n\n// operacion de eliminacion al principio de un array\n\n    array.shift();\n\nconsole.log(array) //[1, 6, 54, \"Joaquin\"]\n\n// actualizar el valor de un elemento del array \n\n  array[2] = \"Lopez\" // donde [2] es el lugar donde se encuentra \"54\"\n\nconsole.log(array) //[1, 6, \"Lopez\", \"Joaquin\"]\n\n// ordenar un array\n\n  array.sort()\n\nconsole.log(array); // [1, 6, \"Joaquin\", \"Lopez\"]\n\n\n\n// Objetos\n\nlet Aprendiz = {\n    nombre: \"Joaquin\",\n    apellido: \"Lopez\",\n    lenguaje: \"Javascript\",\n    edad: 25\n  };\n  \n  // Insertar una propiedad nueva al objeto\n  Aprendiz.pais = \"Argentina\";\n\n  console.log(Aprendiz); // {nombre: \"Joaquin\", apellido: \"Lopez\", lenguaje: \"Javascript\", edad: 25, pais: \"Argentina\"}\n  \n  // Eliminar una propiedad\n  delete Aprendiz.pais;\n\n  console.log(Aprendiz); // {nombre: \"Joaquin\", apellido: \"Lopez\", lenguaje: \"Javascript\", edad: 25}\n  \n  // Actualizar una propiedad\n  Aprendiz.apellido = \"Lopez Sanchez\";\n\n  console.log(Aprendiz); // {nombre: \"Joaquin\", apellido: \"Lopez Sanchez\", lenguaje: \"Javascript\", edad: 25}\n  \n\n\n// Sets \n\n  // Creación\n    const Numeros = new Set([1, 2, 3, 6, 8, 20]);\n\n// Añadir un nuevo elemento\n    Numeros.add(50);\n\n    console.log(Numeros); // Set(7) { 1, 2, 3, 6, 8, 20, 50 }\n\n// Eliminar un elemento\n    Numeros.delete(2);\n\n    console.log(Numeros); // Set(6) { 1, 3, 6, 8, 20, 50 }\n\n\n// Maps \n\n  // Creación\nconst Mascota = new Map([\n    [\"nombre\", \"Vuelto\"],\n    [\"tipo\", \"Gato\"],\n    [\"edad\", \"1 Año\"]\n  ]);\n  \n  // Añadir un nuevo dato\n  Mascota.set(\"color\", \"Naranja\");\n\n  console.log(Mascota); // Map(4) { 'nombre' => 'Vuelto', 'tipo' => 'Gato', 'edad' => '1 Año', 'color' => 'Naranja' }\n  \n  // Eliminar un dato\n  Mascota.delete(\"tipo\");\n\n  console.log(Mascota); // Map(3) { 'nombre' => 'Vuelto', 'edad' => '1 Año', 'color' => 'Naranja' }\n  \n  // Actualizar un dato\n  Mascota.set(\"edad\", \"1 Año y 6 Meses\");\n\n  console.log(Mascota); // Map(3) { 'nombre' => 'Vuelto', 'edad' => '1 Año y 6 Meses', 'color' => 'Naranja' }\n  \n\n\n// 1.1\n    // Dificultad Extra\n\n    const readline = require(\"readline\");\n    const rl = readline.createInterface({\n        input:process.stdin,\n        output: process.stdout\n    });\n\n    const agenda = new Map();\n\n    function showMenu () {\n        console.log(\"\\n1. Mostrar contactos\");  //n1 salto de linea.\n        console.log(\"2. Añadir contacto\");\n        console.log(\"3. Actualizar contacto\");\n        console.log(\"4. Eliminar contacto\");\n        console.log(\"Salir\");\n    }\n\n    function showContact () {\n        console.log(\"\\n-Contactos-\");\n            if (agenda.size === 0) {\n                console.log(\"No hay conctactos\")\n            } else {\n                agenda.forEach((telefono, nombre) => {\n                    console.log(`${nombre}: ${telefono}`)\n                })\n            }\n    }\n\n    function addContact () {\n        rl.question(\"Nombre del contacto\", (nombre) => {\n            rl.question(\"Numero de telefono:\", (telefono) => {\n                if (/^\\d{1,11}$/.test(telefono)) {   ///^\\d{1,11}$/ => la cadena debe consistir en entre 1 y 11 dígitos, tampoco debe contener ningún otro caracter.\n                agenda.set(nombre, telefono);\n                console.log(\"Contacto añadido\");\n            } else {\n                console.log(\"Numero no valido\");\n            }\n            showMenu();\n            })\n        })\n    }\n\n    function updateContact() {\n        rl.question(\"Nombre del contacto a actualizar: \", (nombre) => {\n            if (agenda.has(nombre)) {\n                rl.question(\"Nuevo numero de teléfono \", (telefono) => {\n                    if(/^\\d{1,11}$/.test(telefono)) {\n                        agenda.set(nombre, telefono);\n                        console.log(\"Contacto actualizado\");\n                    } else {\n                        console.log(\"Numero no válido\");\n                    }\n                    showMenu();\n                });\n            } else {\n                console.log(\"Contacto no encontrado\");\n                showMenu();\n            }\n        });\n    }\n    \n    function deleteContact () {\n        rl.question(\"Nombre del contacto que quieres eliminar \", (nombre) => {\n            if (agenda.has(nombre)) {\n                agenda.delete(nombre);\n                console.log(\"Contacto eliminado\");\n            } else {\n                console.log(\"Contacto no encontrado\");\n            }\n            showMenu();\n        })\n    }\n    \n    function optionUser (opcion) {\n        switch (opcion) {\n            case \"1\":\n                showContact ();\n                break;\n            case \"2\":\n                addContact ();\n                break;\n            case \"3\":\n                updateContact ();\n                break;\n            case \"4\":\n                deleteContact ();\n                break;\n            case \"5\":\n                console.log(\"Saliendo\");\n                rl.close();\n                break;\n            default:\n                console.log(\"Accion invalida. Introduce un número del 1 al 5\");\n        }\n    }\n    "
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/JoseAndresGC.js",
    "content": "// Array\n\nlet cars = ['corolla', 'corsa', 'explorer', 'yaris']\n\nconsole.log(cars.shift()); // 'corolla' remueve y retorna el primer elemento\nconsole.log(cars); //['corsa', 'explorer', 'yaris']\n\nconsole.log(cars.pop()); // remueve y retorna el último elemento del array\nconsole.log(cars); // ['corsa', 'explorer']\n\nconsole.log(cars.unshift('corolla cross', 'mazda')); // 4 Agrega uno o más elementos al principio y retorna la longitud que en ese momento tome el array\nconsole.log(cars); // ['corolla cross', 'mazda', 'corsa', 'explorer']\n\nconsole.log(cars.push('aveo')); // 5 Agrega uno o más elementos al final y retorna la longitud que en ese momento tome el array\nconsole.log(cars); // ['corolla cross', 'mazda', 'corsa', 'explorer', 'aveo']\n\nconsole.log(cars.join(', ')); // concatena todos los elementos de un array en una sola línea de texto. Hay que aclarar el separador\n\nconsole.log(cars.splice()); // se puede agregar, eliminar o reemplazar elementos de un array / sintaxis: .splice(inicio, del, elem1, elem2, ...)\nconsole.log(cars.splice(1, 2)); // eliminar: retorna los elementos eliminados del array ['mazda', 'corsa'] cars retorna ['corolla cross', 'explorer', 'aveo']\n\nconsole.log(cars.splice(1, 0, 'mustang', 'camaro')); // agregar: retorna un array vacío, pero agrega 'mustrang' y 'camaro' al array original cars. por ende retorna cars ['corolla cross', 'mustang', 'camaro', 'explorer', 'aveo']\n\nconsole.log(cars.splice(3, 1, 'explorer limited' )); // reemplazar: retorna el elemento eliminado y se reemplaza a su vez por otro elemento 'explorer limited' cars retorna ['corolla cross', 'mustang', 'camaro', 'explorer limited', 'aveo']\n\nconsole.log(cars.slice()); // retorna una porción de un array. No confundir con splice // .slice(inicio, final)\nconsole.log(cars.slice(0, 3)); // ['corolla cross', 'mustang', 'camaro'] \n\nconsole.log(cars.reverse()); // retorna el array, pero al reves\n\nconsole.log(cars.fill('relleno/reemplazo', 1, 3));  // Rellena un array con un valor estático, devuelve el array original y modificado, sintaxis: .fill(valor, inicio, fin);\nconsole.log(cars); // ['aveo,' 'relleno/reemplazo', 'relleno/reemplazo', 'mustang', 'corolla cross']\n\n// Object\n\nlet persona = {\n    nombre: \"Andrés\",\n    edad: 22,\n    altura: 1.70,\n}; // creación de un objeto\n\nconsole.log(persona); // obtengo todas las propiedades del objeto {nombre: 'Andrés, edad: 22, altura: 1.7}\nconsole.log(persona.nombre); // obtengo una propiedad específica\nconsole.log(persona.nombre = 'José'); // cambio el valor de la propiedad accedida\nconsole.log(persona.vivo = true);// añado nueva/s propiedades al objeto\n\n// Map\n\nlet persona2 = new Map();\n\npersona2.set('elemento', 'valor'); // agrego un elemento elemento\nconsole.log(persona2.set('nombre', 'José')); // { 'nombre' : 'José' }\n\npersona2.get('elemento') // obtengo el valor del elemento\nconsole.log(persona2.get('nombre')) // 'José'\n\nconsole.log(persona2);\n\nconsole.log(persona2.size); // devuelve el número de elementos en el Map\nconsole.log(persona2.clear()); // Elimina todos los elementos del Map\n\n// Set\n\nlet mySet = new Set();\n\nmySet.add('añadirElemento'); // añadiendo elemento/s al Set\nmySet.add(5);\nmySet.add(1);\nmySet.add(1); // este elemento no se añade al set porque ya forma parte\n\nmySet.delete('añadirElemento'); // eliminar elemento del set\nmySet.clear(); // Elimina todos los elementos del Set\n\nmySet // {}\n\n// DIFICULTAD EXTRA:\n\nconst readline = require('readline').createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nlet agenda = {};\n\nfunction app(){\n    console.log(`\n        '********************'\n        'LISTA DE CONTACTOS'\n        '********************'`\n    );\n\n    while (true) {\n        console.log('---Qué desea hacer?---');\n    console.log('1. Añadir contacto');\n    console.log('2. Buscar contacto');\n    console.log('3. Actualizar contacto');\n    console.log('4. Eliminar contacto');\n    console.log('5. Salir');\n    console.log('-----------------------');\n    \n    readline.question('Ingrese una opción: ', (opcion) => {\n        console.log('Opción', opcion);\n        switch(opcion) {\n            case '1': // añadir contacto\n                nombre = readline.question('Ingrese el nombre: ');\n                telefono = readline.question('Ingre el teléfono: ');\n                if (telefono.length > 0 && telefono.length <= 11) {\n                    agenda[nombre] = telefono;\n                } else {\n                    console.log('Número de teléfono inválido. Ingresa un número de 11 dígitos');\n                }\n                app();\n                break\n            case '2': // buscar contacto\n                nombre = readline.question('Ingrese el nombre a buscar: ');\n                // si nombre está en agenda obtengo el numero de teléfono y lo muestro\n                // si no está, muestro un mensaje de que no se encontró el contacto \n                if (agenda.hasOwnProperty(nombre)) {\n                    console.log('Número de teléfono: ', agenda[nombre]);\n                } else {\n                    console.log('Contacto no encontrado');\n                }\n                break\n            case '3': // actualizar contacto\n                nombre = readline.question('Ingrese el nombre a actualizar: ');\n                telefono = readline.question('Ingrese el nuevo número de teléfono: ');\n                if (telefono.length > 0 && telefono.length <= 11) {\n                    agenda[nombre] = telefono;\n                } else {\n                    console.log('Número de teléfono inválido. Ingresa un número de 11 dígitos');\n                }\n                break\n            case '4': // borrar contacto\n                nombre = readline.question('Ingrese el nombre a eliminar:');\n                if (agenda.hasOwnProperty(nombre)) {\n                    delete agenda[nombre];\n                } else {\n                    console.log('Contacto no encontrado');\n                }\n                break\n            case '5': // salir\n                console.log('Saliendo... ');\n                break;\n            default: \n                console.log('Opción no válida, Elige una opción válida');\n                agenda();\n                break;\n        }\n    });\n}\n    }\n\napp();\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/JosueVH07.js",
    "content": "//CREACION \n\n//ARRAYS\nlet numeros = [1, 2, 3, 4, 5];\n\n//ACCESO\nconsole.log(numeros[0]);\nconsole.log(numeros[1]);\n\n//MODIFICACION\nnumeros[0] = 6;\nconsole.log(numeros[0]);\n\n//AGREGAR ELEMENTOS\nnumeros.push(6);\nnumeros.unshift(0);\n\n//ELIMINAR ELEMENTOS\nnumeros.pop();\nnumeros.shift();\n\n//ELIMINAR ELEMENTO DE UNA ZONA ESPECIFICA\nnumeros.splice(2, 1);\nconsole.log(numeros)\n\n//OTROS METODOS\nconsole.log(numeros.includes(3));\nconsole.log(numeros.indexOf(3));\nconsole.log(numeros.reverse());\nconsole.log(numeros.sort());\nconsole.log(numeros.sort().reverse());\n\n\n//OBJETOS\n\n//CREACION\nlet persona = {\n    nombre: \"Josue\",\n    edad: 20,\n    ciudad: \"Guatemala\"\n};\n\n//ACCESO\nconsole.log(persona.nombre);\nconsole.log(persona.edad);\n\n//MODIFICACION\npersona.edad = 21;\nconsole.log(persona.edad);\n\n//AGREGAR PROPIEDAD\npersona.profesion = \"Estudiante\";\nconsole.log(persona.profesion);\n\n//ELIMINAR PROPIEDAD\n\ndelete persona.ciudad;\nconsole.log(persona);\n\n//OTROS METODOS\n\nconsole.log(Object.keys(persona));\n\nconsole.log(Object.values(persona));\n\nconsole.log(Object.entries(persona));\n\n//MAPAS (MAPS)\n\n//CREACION\nlet mapa = new Map();\n\n//AGREGAR ELEMENTOS\nmapa.set(\"nombre\", \"Josue\");\nmapa.set(\"edad\", 20);\n\n//ACCESO\nconsole.log(mapa.get(\"nombre\"));\n\n\n//ACTUALIZACION\nmapa.set(\"edad\", 21);\n\n//ELIMINAR ELEMENTO\nmapa.delete(\"edad\");\n\n//VERIFICAR EXISTENCIA\n\nconsole.log(mapa.has(\"nombre\"));\n\n//OTROS METODOS\n\nconsole.log(mapa.size);\nmapa.clear();\nconsole.log(mapa.size);\n\n//SETS\n\n//CREACION\nlet set = new Set();\n\n//AGREGAR ELEMENTOS\nset.add(1);\nset.add(2);\n\n//ELIMINAR ELEMENTOS\nset.delete(1);\n\n//VERIFICAR EXISTENCIA\nconsole.log(set.has(2));\n\n//OTROS METODOS\nconsole.log(set.size);\nset.clear();\nconsole.log(set.size);\n\n\n//EXTRA\n\nconst readline = require(\"readline\");\nconst input = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nconst agenda = new Map();\n\n\nfunction showMenu() {\n    console.log(\"\\n1. Mostrar contactos\");\n    console.log(\"2. Añadir contacto\");\n    console.log(\"3. Actualizar contacto\");\n    console.log(\"4. Eliminar contacto\");\n    console.log(\"Salir\");\n    input.question(\"Selecciona una opcion: \", (opcion) => {\n        optionUser(opcion);\n    })\n}\n\nfunction validarTelefono(telefono) {\n    const number = Number(telefono);\n    if (isNaN(number)) {\n        console.log(\"Telefono no valido\");\n        showMenu();\n        return false;\n    } else {\n        return true;\n    }\n}\n\nfunction addContact() {\n    input.question(\"Ingresa el Nombre: \", (nombre) => {\n        input.question(\"Ingresa el Telefono: \", (telefono) => {\n            if (validarTelefono(telefono)) {\n                agenda.set(nombre.toUpperCase(), telefono);\n                console.log(\"Contacto agregado correctamente!!\");\n                showMenu();\n            }\n        })\n    })\n}\n\nfunction updateContact() {\n    input.question(\"Ingresa el nombre del contacto que quieres actualizar: \", (nombre) => {\n        const filter = nombre.toUpperCase()\n        const contact = agenda.get(filter);\n\n        if (contact) {\n            input.question(\"Ingresa el nuevo numero de telefono: \", (telefono) => {\n                if (validarTelefono(telefono)) {\n                    agenda.set(filter, telefono);\n                    console.log(\"Contacto actualizado\");\n                    showMenu();\n                }\n            })\n        } else {\n            console.log(\"Contacto no encontrado\");\n            showMenu();\n        }\n    })\n}\n\nfunction deleteContact() {\n    input.question(\"Ingresa el nombre del contacto que quieres eliminar: \", (nombre) => {\n        const filter = nombre.toUpperCase();\n\n        if (agenda.has(filter)) {\n            agenda.delete(filter);\n            console.log(\"Contacto eliminado\");\n            showMenu();\n        } else {\n            console.log(\"Contacto no encontrado\");\n            showMenu();\n        }\n    })\n}\n\n\nfunction optionUser(opcion) {\n    switch (opcion) {\n        case \"1\":\n            console.log(agenda);\n            showMenu();\n            break;\n        case \"2\":\n            addContact();\n            break;\n        case \"3\":\n            updateContact();\n            break;\n        case \"4\":\n            deleteContact();\n            break;\n        case \"5\":\n            input.close();\n            break;\n        default:\n            console.log(\"Opcion no valida\");\n            showMenu();\n            break;\n    }\n}\n\nshowMenu();"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/JuSeRDev.js",
    "content": "\n//  * EJERCICIO:\n//  * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n//  * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n\n\n//! ARRAY\n\nconst number = [1, 2, 3]\n\nconsole.log(number)\nnumber.push(4) // añade al final\nconsole.log(number)\nnumber.unshift(0) // añade al inicio\nconsole.log(number)\nnumber.pop() // elimina al final\nconsole.log(number)\nnumber.shift() // elimina al inicio\nconsole.log(number)\nnumber[2] = 4 // modifica\nconsole.log(number)\nnumber.sort((a,b)=> b- a) // ordena de menor a mayor\nconsole.log(number)\nnumber.sort((a,b)=> a-b) // ordena de menor a mayor\nconsole.log(number)\n\n//! OBJETOS\n\nlet persona = {\n    nombre: \"Sebastian\",\n    apellido: \"rodriguez\"\n}\nconsole.log(persona)\npersona.edad = 33 // Añade una nueva propiedad\nconsole.log(persona)\ndelete persona.apellido // elimina una propiedad\nconsole.log(persona)\npersona.nombre = \"Juan Sebastian\" // actualiza una propiedad\nconsole.log(persona)\nlet keys = Object.keys(persona).sort();  // Ordena las claves alfabéticamente\nconsole.log(keys)\n\n//! SET\n\nlet personas = new Set([\"juan\", \"sebatian\", \"Laura\"]) // aqui me muestra la posicion y su valor\nconsole.log(personas); \npersonas.add(\"Daniel\") // aqui me muestra la posicion y su valor\nconsole.log(personas); \npersonas.add(\"persona5\") // aqui me muestra la posicion y su valor\nconsole.log(personas); \npersonas.delete(\"persona5\")// aqui me muestra la posicion y su valor\nconsole.log(personas); \n\n\n//! MAP\n\nlet personas2 = new Map([[\"persona1\", \"Sebastian\"],[\"persona2\", \"Laura\"]])\n\n// para crear un mapa debe ser un array dentro de un array [[llave, valor]] \nconsole.log(personas2);\npersonas2.set(\"persona3\", \"Maxi\") //añade la clave\nconsole.log(personas2);\npersonas2.delete(\"persona3\") // Elimina la clave\nconsole.log(personas2);\npersonas2.set(\"persona1\", \"Juan\") //modifica la clave\nconsole.log(personas2);\n\n//  * DIFICULTAD EXTRA (opcional):\n//  * Crea una agenda de contactos por terminal.\n//  * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n//  * - Cada contacto debe tener un nombre y un número de teléfono.\n//  * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n//  *   los datos necesarios para llevarla a cabo.\n//  * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n//  *   (o el número de dígitos que quieras)\n//  * - También se debe proponer una operación de finalización del programa.\n\nconst readline = require(\"readline\")\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nconst contactos = new Map()\n\nconst agregarContacto = ()=>{\n    console.log(\"\")\n    rl.question(\"Escriba el nombre: \",(nombre)=>{\n        rl.question(\"Escriba el celular: \", (telefono)=>{\n            const telefonoValido = /^\\d{10}$/.test(telefono)\n            if (telefonoValido) {\n                console.log(\"\")\n                contactos.set(nombre, telefono)\n                console.log(\"CONTACTO AGREGADO\")\n                console.log(\"\")\n                console.log(`Nombre: ${nombre}`)\n                console.log(`Telefono: ${telefono}`)\n                console.log(\"\")\n                console.log(\"Volveras al menu principial\")\n                console.log(\"\")\n                agenda()\n            }else {\n                console.log(\"El numero de telefono debe tener 10 digitos\")\n                console.log(\"\")\n                agregarContacto()\n            }\n        })\n    })\n   \n}\n\nconst BuscarContacto = ()=>{\n    console.log(\"\")\n    rl.question(\"Escribe el nombre del contacto que desdeas buscar: \", (nombre)=>{\n        if (contactos.has(nombre)) {\n            const telefono = contactos.get(nombre)\n            console.log(\"\")\n            console.log(\"CONTACTO EXISTENTE\")\n            console.log(\"\")\n            console.log(`Nombre: ${nombre}`)\n            console.log(`Telefono: ${telefono}`)\n            console.log(\"\")\n            agenda()\n        } else{\n            console.log(`El contacto ${nombre} no existe`);\n            console.log(\"\")\n            console.log(\"Volveras al menu principial\")\n            console.log(\"\")\n            agenda()\n        }\n    })\n}\n\nconst actualizarContacto = ()=>{\n    console.log(\"\")\n    rl.question(\"Escribe el nombre del contacto que quieres actualizar: \",(nombre)=>{\n        if (contactos.has(nombre)) {\n            rl.question(\"Escrible en telefono actulizado: \",(telefono)=>{\n                console.log(\"\")\n                contactos.set(nombre,telefono)\n                console.log(\"Contacto actualizado exitosamente\")\n                console.log(`Contacto: ${nombre}`)\n                console.log(`Telefono: ${telefono}`)\n                console.log(\"\");\n                console.log(\"Volveras al menu principial\")\n                console.log(\"\")\n                agenda()\n            })\n        }else{\n            console.log(\"El contacto no se puede actualizar por que no existe existe\")\n            console.log(\"\")\n            agenda()\n        }\n    })\n}\n\nconst eliminarContacto = ()=>{\n    console.log(\"\")\n    rl.question(\"escribe el nombre del contacto que deseas eliminar: \", (nombre)=>{\n        if (contactos.has(nombre)) {\n            const telefono = contactos.get(nombre)\n            console.log(`Nombre: ${nombre} - ${telefono}`)\n            contactos.delete(nombre)\n            console.log(\"contacto eliminado\");\n            console.log(\"Volveras al menu principial\")\n            console.log(\"\")\n            agenda()\n        } else {\n            console.log(\"El contacto no esta en la base de datos\");\n            console.log(\"\")\n        }\n    })\n}\n\nconst mostrarContactos = ()=>{\n    console.log(\"\")\n    console.table(contactos)\n    agenda()\n}\n\nconst salir = ()=>{\n    console.log(\"\")\n    console.log(\"saliste de la aplicacion\");\n    rl.close()\n    process.exit(0)\n}\n\n\nconst agenda = ()=>{\n    console.log(\"\")\n    console.log(\"/--------AGENDA--------/\")\n    console.log(\"\")\n    console.log(\"Escribe la opcion que deseas:\")\n    console.log(\"1. Agregar contacto\")\n    console.log(\"2. Buscar contacto\")\n    console.log(\"3. Actualizar contacto\")\n    console.log(\"4. Eliminar contacto\")\n    console.log(\"5. Mostrar contactos existentes\")\n    console.log(\"6. Salir\")\n\n    rl.question(\"que vas a hacer?\",(respuesta)=>{\n        switch (respuesta) {\n            case \"1\":\n                agregarContacto()\n                break;\n            case \"2\":\n                BuscarContacto()\n                break;\n            case \"3\":\n                actualizarContacto()\n                break;\n            case \"4\":\n                eliminarContacto()\n                break;\n            case \"5\":\n                mostrarContactos()\n                break;\n            case \"6\":\n                salir()\n                break;\n            default:\n                console.log(\"No seleccionaste una opcion valida\")\n                agenda()\n                break;\n        }\n    })\n\n\n    // rl.question(\"Que vas a hacer?\", (respuesta)=>{\n    //     if (respuesta === \"1\") {\n    //         agregarContacto()\n    //     } else if (respuesta === \"2\") {\n    //         BuscarContacto()\n    //     }else if (respuesta === \"3\") {\n    //         actualizarContacto()\n    //     }else if(respuesta === \"4\"){\n    //         eliminarContacto()\n    //     }else if(respuesta === \"5\"){\n    //         mostrarContactos()\n    //     }else if(respuesta === \"6\"){\n    //         salir()\n    //     }else{\n    //         console.log(\"No seleccionaste una opcion valida\")\n    //         agenda()\n    //     }\n    // })\n}\n\nagenda()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/JuanCaicedo1024.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto\n *   en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n *   y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n *   y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más\n *   de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.\n */\n\n\nlet numeros = [0,1,2,3,4,5,6,7,8,9];\n\n// 📌 Insertar\nnumeros.push(7); // Agrega al final\nnumeros.unshift(3); // Agrega al inicio\n\n// 📌 Borrar\nnumeros.pop(); // Elimina el último\nnumeros.shift(); // Elimina el primero\n\n// 📌 Actualizar\nnumeros[1] = 10; // Cambia el segundo elemento\n\n// 📌 Ordenar\nnumeros.sort((a, b) => a - b); // Orden ascendente\n\nconsole.log(numeros);\n\n\nlet persona = {\n    nombre : \"Juan\" ,\n    edad: 10,\n    profesion: \"programador\",\n    equipo: \"\",\n}\n// 🔹 Inserción\n//persona[equipo] = \"pikachu\";\npersona.edad = 11\n// borrar\ndelete persona[edad];\n\n//actualizacion\n\n\nconsole.log (persona);\n\n\nlet user = {\n    name: \"John\",\n    age: 30\n};\n\n  Object.keys(user) = [\"name\", \"age\"]\n  Object.values(user) = [\"John\", 30]\n  Object.entries(user) = [ [\"name\",\"John\"], [\"age\",30] ]\n\n\n  //  * DIFICULTAD EXTRA (opcional):\n//  * Crea una agenda de contactos por terminal.\n//  * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n//  * - Cada contacto debe tener un nombre y un número de teléfono.\n//  * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n//  *   los datos necesarios para llevarla a cabo.\n//  * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n//  *   (o el número de dígitos que quieras)\n//  * - También se debe proponer una operación de finalización del programa.\n\n\nconst readline = require(\"readline\");\n\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout,\n});\n\nlet contactos = {}; // Diccionario para almacenar contactos\n\n// Validar número de teléfono\nconst validarTelefono = (telefono) => {\n  return /^\\d{1,11}$/.test(telefono); // Solo números y máximo 11 dígitos\n};\n\n// Menú de opciones\nconst mostrarMenu = () => {\n  console.log(\"\\n📞 AGENDA DE CONTACTOS\");\n  console.log(\"1️⃣ Agregar contacto\");\n  console.log(\"2️⃣ Buscar contacto\");\n  console.log(\"3️⃣ Actualizar contacto\");\n  console.log(\"4️⃣ Eliminar contacto\");\n  console.log(\"5️⃣ Listar contactos\");\n  console.log(\"6️⃣ Salir\\n\");\n  rl.question(\"Elige una opción: \", manejarOpcion);\n};\n\n// Manejar opción del usuario\nconst manejarOpcion = (opcion) => {\n  switch (opcion) {\n    case \"1\":\n      agregarContacto();\n      break;\n    case \"2\":\n      buscarContacto();\n      break;\n    case \"3\":\n      actualizarContacto();\n      break;\n    case \"4\":\n      eliminarContacto();\n      break;\n    case \"5\":\n      listarContactos();\n      break;\n    case \"6\":\n      console.log(\"📴 Saliendo del programa...\");\n      rl.close();\n      break;\n    default:\n      console.log(\"❌ Opción inválida, intenta de nuevo.\");\n      mostrarMenu();\n  }\n};\n\n// Función para agregar un contacto\nconst agregarContacto = () => {\n  rl.question(\"Nombre: \", (nombre) => {\n    if (!nombre) {\n      console.log(\"❌ El nombre no puede estar vacío.\");\n      return mostrarMenu();\n    }\n\n    rl.question(\"Teléfono: \", (telefono) => {\n      if (!validarTelefono(telefono)) {\n        console.log(\"❌ Teléfono inválido (máximo 11 dígitos, solo números).\");\n        return mostrarMenu();\n      }\n\n      contactos[nombre] = telefono;\n      console.log(`✅ Contacto ${nombre} agregado.`);\n      mostrarMenu();\n    });\n  });\n};\n\n// Función para buscar un contacto\nconst buscarContacto = () => {\n  rl.question(\"Nombre del contacto a buscar: \", (nombre) => {\n    if (contactos[nombre]) {\n      console.log(`📞 ${nombre}: ${contactos[nombre]}`);\n    } else {\n      console.log(\"❌ Contacto no encontrado.\");\n    }\n    mostrarMenu();\n  });\n};\n\n// Función para actualizar un contacto\nconst actualizarContacto = () => {\n  rl.question(\"Nombre del contacto a actualizar: \", (nombre) => {\n    if (!contactos[nombre]) {\n      console.log(\"❌ Contacto no encontrado.\");\n      return mostrarMenu();\n    }\n\n    rl.question(\"Nuevo teléfono: \", (telefono) => {\n      if (!validarTelefono(telefono)) {\n        console.log(\"❌ Teléfono inválido.\");\n        return mostrarMenu();\n      }\n\n      contactos[nombre] = telefono;\n      console.log(`✅ Contacto ${nombre} actualizado.`);\n      mostrarMenu();\n    });\n  });\n};\n\n// Función para eliminar un contacto\nconst eliminarContacto = () => {\n  rl.question(\"Nombre del contacto a eliminar: \", (nombre) => {\n    if (contactos[nombre]) {\n      delete contactos[nombre];\n      console.log(`🗑️ Contacto ${nombre} eliminado.`);\n    } else {\n      console.log(\"❌ Contacto no encontrado.\");\n    }\n    mostrarMenu();\n  });\n};\n\n// Función para listar todos los contactos\nconst listarContactos = () => {\n  console.log(\"\\n📋 Lista de contactos:\");\n  if (Object.keys(contactos).length === 0) {\n    console.log(\"⚠️ No hay contactos guardados.\");\n  } else {\n    for (let nombre in contactos) {\n      console.log(`📞 ${nombre}: ${contactos[nombre]}`);\n    }\n  }\n  mostrarMenu();\n};\n\n// Iniciar el programa\nmostrarMenu();\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/LauraCastrillonMp.js",
    "content": "// array\n// Creation\nlet array = [1, 2, 3, 4];\n\n// Insertion\narray.push(5); // Appends to the end\n\n// Deletion\narray.splice(2, 1); // Removes the item at index 2\n\n// Update\narray[2] = 10; // Updates the item at index 2\n\n// Sorting\narray.sort((a, b) => a - b); // Sorts the array in ascending order\n\n// object\n// Creation\nlet object = { name: \"Alice\", age: 25 };\n\n// Insertion\nobject.email = \"alice@example.com\"; // Adds a new property\n\n// Deletion\ndelete object.age; // Deletes the age property\n\n// Update\nobject.name = \"Bob\"; // Updates the name property\n\n// set\n// Creation\nlet set = new Set([1, 2, 3, 4]);\n\n// Insertion\nset.add(5); // Adds a new element\n\n// Deletion\nset.delete(2); // Removes the element 2\n\n// map\n// Creation\nlet map = new Map([\n  [\"a\", 1],\n  [\"b\", 2],\n]);\n\n// Insertion\nmap.set(\"c\", 3); // Adds a new key-value pair\n\n// Deletion\nmap.delete(\"b\"); // Deletes the key-value pair with key 'b'\n\n// Update\nmap.set(\"a\", 100); // Updates the value for key 'a'\n\n// Sorting - Maps are not directly sortable, but you can sort the entries\nlet mapSorted = new Map([...map.entries()].sort());\n\n//EJERCICIO\nconst readline = require(\"readline\");\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout,\n});\n\nlet contacts = [];\n\nconst mainMenu = () => {\n  rl.question(\n    \"Choose an operation: search (s), insert (i), update (u), delete (d), list (l), exit (e): \",\n    (choice) => {\n      switch (choice) {\n        case \"s\":\n          searchContact();\n          break;\n        case \"i\":\n          insertContact();\n          break;\n        case \"u\":\n          updateContact();\n          break;\n        case \"d\":\n          deleteContact();\n          break;\n        case \"l\":\n          listContacts();\n          break;\n        case \"e\":\n          rl.close();\n          break;\n        default:\n          console.log(\"Invalid choice.\");\n          mainMenu();\n      }\n    }\n  );\n};\n\nconst validatePhoneNumber = (number) => {\n  const regex = /^\\d{1,11}$/;\n  return regex.test(number);\n};\n\nconst findContactIndex = (name) =>\n  contacts.findIndex((c) => c.name.toLowerCase() === name.toLowerCase());\n\nconst searchContact = () => {\n  rl.question(\"Enter the name of the contact to search: \", (name) => {\n    const index = findContactIndex(name);\n    if (index !== -1) {\n      console.log(\n        `Contact found: ${contacts[index].name}, ${contacts[index].phone}`\n      );\n    } else {\n      console.log(\"Contact not found.\");\n    }\n    mainMenu();\n  });\n};\n\nconst insertContact = () => {\n  rl.question(\"Enter the name of the new contact: \", (name) => {\n    rl.question(\"Enter the phone number of the new contact: \", (phone) => {\n      if (!validatePhoneNumber(phone)) {\n        console.log(\"Invalid phone number.\");\n        insertContact();\n      } else {\n        contacts.push({ name, phone });\n        console.log(\"Contact inserted.\");\n        mainMenu();\n      }\n    });\n  });\n};\n\nconst updateContact = () => {\n  rl.question(\"Enter the name of the contact to update: \", (name) => {\n    const index = findContactIndex(name);\n    if (index !== -1) {\n      rl.question(\"Enter the new phone number: \", (phone) => {\n        if (!validatePhoneNumber(phone)) {\n          console.log(\"Invalid phone number.\");\n          updateContact();\n        } else {\n          contacts[index].phone = phone;\n          console.log(\"Contact updated.\");\n          mainMenu();\n        }\n      });\n    } else {\n      console.log(\"Contact not found.\");\n      mainMenu();\n    }\n  });\n};\n\nconst deleteContact = () => {\n  rl.question(\"Enter the name of the contact to delete: \", (name) => {\n    const index = findContactIndex(name);\n    if (index !== - 1) {\n      contacts.splice(index, 1);\n      console.log(\"Contact deleted.\");\n    } else {\n      console.log(\"Contact not found.\");\n    }\n    mainMenu();\n  });\n};\n\nconst listContacts = () => {\n  if (contacts.length === 0) {\n    console.log(\"No contacts to display.\");\n  } else {\n    console.log(\"Contact List:\");\n    contacts.forEach((contact, index) => {\n      console.log(\n        `${index + 1}. Name: ${contact.name}, Phone: ${contact.phone}`\n      );\n    });\n  }\n  mainMenu();\n};\n\nmainMenu();\n\nrl.on(\"close\", () => {\n  console.log(\"Exiting contact list application.\");\n  process.exit(0);\n});\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/MarcosLombardo.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto\n *   en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n *   y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n *   y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más\n *   de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.\n */\n\n// Estructuras soportadas\n\n// Array: Colección de datos que pueden ser números, strings, objetos, otros arrays, entre otros.\nconsole.log(\"Array:\");\n\n// Creación de Array\nlet myArray = [3, 6, 5, 1, 4, 2]; // [3, 6, 5, 1, 4, 2]\n\n// Métodos\nmyArray.push(0); // [3, 6, 5, 1, 4, 2, 0] => Agrega uno o más elementos al final del array\nmyArray.unshift(7); // [7, 3, 6, 5, 1, 4, 2, 0] => Agrega uno o más elementos al principio del array\nmyArray.pop(); // [7, 3, 6, 5, 1, 4, 2] => Elimina el último elemento del array\nmyArray.shift(); // [3, 6, 5, 1, 4, 2] => Elimina el primer elemento del array\nmyArray.splice(4, 0, 0); // [3, 6, 5, 1, 8, 4, 2] => Cambia uno o más elementos según la especificación\nmyArray[4] = 8; // [3, 6, 5, 1, 0, 4, 2] => Cambia el elemento del índice indicado por el nuevo asignado\nmyArray.sort(); // [0, 1, 2, 3, 4, 5, 6] => Ordena el Array de menor a mayor\n\nconsole.log(myArray);\n\n// Object: Colección de variables y funciones agrupadas de manera estructural. Las variables definidas dentro de un objeto se las denomina propiedades y las funciones métodos. Las propiedades son pares clave-valor.\nconsole.log(\"Object:\");\n\n// Creación de Objeto\nlet myObject = { name: \"Marcos\", age: 32, country: \"Argentina\" };\n\n// Métodos\nmyObject.mail = \"marcos@mail.com\"; // { name: \"Marcos\", age: 32, country: \"Argentina\", mail: \"marcos@mail.com\" } => Agrega una nueva colección clave valor\nmyObject.age = 33; // { name: \"Marcos\", age: 33, country: \"Argentina\", mail: \"marcos@mail.com\" } => Modifica un valor de una clave existente\ndelete myObject.country; // { name: \"Marcos\", age: 33, mail: \"marcos@mail.com\" } => Elimina una colección específica\n\nconsole.log(myObject);\n\n// Map: Colección de pares clave-valor donde tanto las claves como los valores, pueden ser de cualquier tipo.\nconsole.log(\"Map:\");\n\n// Creación de Map\nlet myMap = new Map([\n  [\"name\", \"Marcos\"],\n  [\"age\", 32],\n  [\"country\", \"Argentina\"],\n]);\n\n// Métodos\nmyMap.set(\"mail\", \"marcos@mail.com\"); // { \"name\" => \"Marcos\", \"age\" => 32, \"country\" => \"Argentina\", \"mail\" => \"marcos@mail.com\" } => Agrega una nueva colección al map\nmyMap.set(\"age\", 33); // { \"name\" => \"Marcos\", \"age\" => 33, \"country\" => \"Argentina\", \"mail\" => \"marcos@mail.com\" } => Actualiza el valor cuya clave se especifica\nmyMap.get(\"name\"); // Marcos => Accede al valor cuya clave se especifique\nmyMap.delete(\"country\"); // { \"name\" => \"Marcos\", \"age\" => 33, \"mail\" => \"marcos@mail.com\" } => Elimina la colección con la clave especificada\n\nconsole.log(myMap);\n\n// Set: Colección de valores únicos.\nconsole.log(\"Set:\");\n\n// Creación de Set\nlet mySet = new Set([\"Marcos\", \"Lombardo\", 33, true]);\n\n// Métodos\nmySet.add(\"Hola\"); // { \"Marcos\", \"Lombardo\", 33, true, \"Hola\" } => Agrega uno o más elementos al final del set\nmySet.delete(true); // { \"Marcos\", \"Lombardo\", 33, \"Hola\" } => Elimina el elemento asignado\nmySet.has(\"Lombardo\"); // true => Corrobora si un elemento puntual se encuentra dentro del set y devuelve un booleano\nmySet.has(true); // false => Corrobora si un elemento puntual se encuentra dentro del set y devuelve un booleano\nmySet.size; // 4 => Devuelve la longitud del set\n\nconsole.log(mySet);\n\nconst { constants } = require(\"buffer\");\n\n// Dificultad extra\n\nconst readline = require(\"readline\");\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout,\n});\n\nlet contacts = [];\n\nconst mainMenu = () => {\n  rl.question(\n    \"Choose an option: (s)Search, (i)Insert, (u)Update, (d)Delete, (l)List, (e)Exit\",\n    (choice) => {\n      switch (choice) {\n        case \"s\":\n          searchContact();\n          break;\n        case \"i\":\n          insertContact();\n          break;\n        case \"u\":\n          updateContact();\n          break;\n        case \"d\":\n          deleteContact();\n          break;\n        case \"l\":\n          listContacts();\n          break;\n        case \"e\":\n          rl.close();\n          break;\n        default:\n          console.log(\"Invalid option.\");\n          mainMenu();\n      }\n    }\n  );\n};\n\nconst findContactIndex = (name) =>\n  contacts.findIndex((c) => c.name.toLowerCase() === name.toLowerCase());\n\nconst searchContact = () => {\n  rl.question(\"Enter the name of the contact to search: \", (name) => {\n    const index = findContactIndex(name);\n    if (index !== -1) {\n      console.log(\n        `Name: ${contacts[index].name} - Phone: ${contacts[index].phone}`\n      );\n    } else {\n      console.log(\"Contact not found\");\n    }\n    mainMenu();\n  });\n};\n\nconst insertContact = () => {\n  rl.question(\"Enter the name of the new contact: \", (name) => {\n    rl.question(\"Enter the phone number of the new contact: \", (phone) => {\n      if (!/^\\d{8,11}$/.test(phone)) {\n        console.log(\"The phone number is not valid\");\n        insertContact();\n      } else {\n        contacts.push({ name, phone });\n        console.log(\"Contact inserted\");\n        mainMenu();\n      }\n    });\n  });\n};\n\nconst updateContact = () => {\n  rl.question(\"Enter the name of the contact to update: \", (name) => {\n    const index = findContactIndex(name);\n    if (index !== -1) {\n      rl.question(\"Enter the phone number to update: \", (phone) => {\n        if (!/^\\d{8,11}$/.test(phone)) {\n          console.log(\"The phone number is not valid\");\n          mainMenu();\n        } else {\n          contacts[index].phone = phone;\n          console.log(\"Contact updated\");\n          mainMenu();\n        }\n      });\n    } else {\n      console.log(\"Contact not found\");\n      mainMenu();\n    }\n  });\n};\n\nconst deleteContact = () => {\n  rl.question(\"Enter the name of the contact to delete: \", (name) => {\n    const index = findContactIndex(name);\n    if (index !== -1) {\n      contacts.splice(index, 1);\n      console.log(\"Contact deleted\");\n    } else {\n      console.log(\"Contact not found\");\n    }\n    mainMenu();\n  });\n};\n\nconst listContacts = () => {\n  if (contacts.length === 0) {\n    console.log(\"No contacts yet\");\n  } else {\n    console.log(\"Contacts: \");\n    contacts.forEach((contact, index) => {\n      console.log(\n        `${index + 1}. Name: ${contact.name} - Phone: ${contact.phone}`\n      );\n    });\n  }\n  mainMenu();\n};\n\nmainMenu();\n\nrl.on(\"close\", () => {\n  process.exit(0);\n});\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/MatiTC.js",
    "content": "//Tipo de estructura de datos JS\n\n//1. Arrays(Arreglos)\nlet numérico = [1, 3, 5, 2, 100, 0];\nlet personas = ['Mario', 'Marco', 'Marcelo', 'Martin'];\nconsole.log('El arreglo numérico contiene los siguientes números:', numérico); // El arreglo numérico contiene los siguientes números: [ 1, 2, 2, 3 ]\nconsole.log('El arreglo personas contiene las siguientes personas:', personas); // El arreglo personas contiene las siguientes personas: [ 'Mario', 'Marco', 'Marcelo', 'Martin' ]\nconsole.log(`.........................................`);\n//1.1 inserción\npersonas.push('Matias');\nconsole.log('Se agrego al final a  Matias', personas); // Se agrego al final a  Matias [ 'Mario', 'Marco', 'Marcelo', 'Martin', 'Matias' ]\npersonas.unshift('Primero');\nconsole.log('Se agrego al inicio a \"Primero\"', personas); //[ 'Primero' , 'Mario', 'Marco', 'Marcelo', 'Martin', 'Matias' ]\n//1.2 borrado\npersonas.shift();\nconsole.log('Eliminación del inicio \"Primero\" ', personas); //Eliminación del inicio \"Primero\"  [ 'Mario', 'Marco', 'Marcelo', 'Martin', 'Matias' ]\npersonas.splice(2, 2); //\nconsole.log('Eliminación especifica Martin', personas); //Eliminación especifica Martin [ 'Mario', 'Marco', 'Matias' ]\npersonas.pop();\nconsole.log('Eliminación de la ultima posición: ', personas); // Eliminación de la ultima posición:  [ 'Mario', 'Marco' ]\n//1.3 actualización\npersonas[0] = 'Máximo';\nconsole.log('Mario se cambio por Máximo:', personas); // Mario se cambio por Máximo: [ 'Máximo', 'Marco' ]\n//1.4 ordenación\npersonas.sort;\nconsole.log('Se ordeno alfabéticamente ', personas); // Se ordeno alfabéticamente  [ 'Máximo', 'Marco' ]\nnumérico.sort((a, b) => a - b);\nconsole.log('Se ordeno el array numérico de menor a mayor:', numérico); // Se ordeno el array numérico de menor a mayor: [ 0, 1, 2, 3, 5, 100 ]\nconsole.log(`.........................................`);\n\n//2.Object(Objetos){Almacena datos pares clave-valor}\nlet marioObject = {\n  nombre: 'Mario',\n  apellido: 'Bros',\n  edad: '24',\n  ciudad: 'Champiñon',\n};\nconsole.log('Los datos de la Mario son:', marioObject); // Los datos de la Mario son: { nombre: 'Mario', apellido: 'Bros', edad: '24', ciudad: 'Champiñon' }\nconsole.log('Nombre de la persona. Su nombre es: ', marioObject.nombre); //Nombre de la persona. Su nombre es: Mario\n//2.1 inserción\n//2.2 borrado\ndelete marioObject.ciudad;\nconsole.log('Se elimino la ciudad', marioObject); // Se elimino la ciudad { nombre: 'Mario', apellido: 'Bros', edad: '24' }\nconsole.log(`.........................................`);\n//3 Map(Map){Almacena pares clave-valor//Diferencia cualquier clave}\nlet miMapa = new Map();\nmiMapa.set('a', 1);\nmiMapa.set('b', 2);\nconsole.log('Mi map es:', miMapa); // Mi map es: Map(2) { 'a' => 1, 'b' => 2 }\n//3.1 inserción\nmiMapa.set('c', 3);\nconsole.log('Se agrego C con 3', miMapa); //Se agrego C con 3 Map(3) { 'a' => 1, 'b' => 2, 'c' => 3 }\n//3.2 borrado\nmiMapa.delete('a');\nconsole.log('Se elimino a ', miMapa); //Se elimino a  Map(2) { 'b' => 2, 'c' => 3 }\n//3.3 actualización\nmiMapa.set('b', 1);\nconsole.log('Se actualizo el valor de \"b\" ', miMapa); // Se actualizo el valor de \"b\"  Map(2) { 'b' => 1, 'c' => 3 }\nconsole.log(`.........................................`);\n\n//4 Set(Set) {valores únicos }\nlet conjuntoUnico = new Set([1, 2, 3, 3, 4]);\nconsole.log(conjuntoUnico); // Set(4) { 1, 2, 3, 4 }\n//4.1 inserción\nconjuntoUnico.add(6);\nconsole.log(conjuntoUnico); // Set(5) { 1, 2, 3, 4, 6 }\n//4.2 borrado\nconjuntoUnico.delete(2);\nconsole.log(conjuntoUnico); //Set(4) { 1, 3, 4, 6 }\nconsole.log(`.........................................`);\n\n//Otras estructura de datos\n\n//5. string\nlet mensaje = 'Hola, mundo!';\n//6. number\nlet edad = 24;\n//7. booleano\nlet esMayorDeEdad = true; // o false\n//8. Undefined\nlet variableNoDefinida;\n//9. Null\nlet valorNulo = null;\n\n/*\n EJERCICIO:\n DIFICULTAD EXTRA (opcional):\n */\n\n// realizar operaciones de entrada y salida de manera más sencilla\nconst readline = require('readline');\n\n// Creamos una interfaz de lectura para interactuar con la terminal\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout,\n});\n\n// Objeto para almacenar los contactos\nconst agenda = {}; // Cada contacto debe tener un nombre y un número de teléfono. // Global\n\n// Función para mostrar el menú de operaciones\nfunction mostrarMenu() {\n  console.log('\\n** Agenda de Contactos **');\n  console.log('1. Buscar contacto');\n  console.log('2. Insertar contacto');\n  console.log('3. Actualizar contacto');\n  console.log('4. Eliminar contacto');\n  console.log('5. Mostrar contacto');\n  console.log('6. Salir');\n}\n\n//1. Función para buscar un contacton\nfunction buscarContacto() {\n  rl.question(\n    'Ingrese el nombre o número de teléfono del contacto a buscar: ',\n    (entrada) => {\n      // Verificar si la entrada coincide con un nombre\n      const contactoPorNombre = agenda[entrada];\n\n      // Verificar si la entrada coincide con un número de teléfono\n      const contactoPorTelefono = Object.entries(agenda).find(\n        ([nombre, telefono]) => telefono === entrada\n      );\n\n      if (contactoPorNombre) {\n        console.log(`Teléfono de ${entrada}: ${contactoPorNombre}`);\n      } else if (contactoPorTelefono) {\n        console.log(\n          `Nombre de la persona con el teléfono ${entrada}: ${contactoPorTelefono[0]}`\n        );\n      } else {\n        console.log(`Contacto ${entrada} no encontrado.`);\n      }\n\n      mostrarMenu();\n      seleccionarOperacion();\n      console.log('\\n Viendo si entran los datos:', agenda);\n    }\n  );\n}\n//2. Insertar un conctato\nfunction insertarContacto() {\n  rl.question('Ingrese el nombre del contacto: ', (nombre) => {\n    rl.question('Ingrese el número de teléfono: ', (telefono) => {\n      if (!isNaN(telefono) && telefono.length <= 11) {\n        agenda[nombre] = telefono;\n        console.log(`Contacto ${nombre} insertado con éxito.`);\n      } else {\n        console.log(\n          'Número de teléfono no válido. Debe ser numérico y tener hasta 11 dígitos.'\n        );\n      }\n      mostrarMenu();\n      seleccionarOperacion();\n      console.log('\\n Viendo si entran los datos:', agenda);\n    });\n  });\n}\n//3. actualziar contacto./ isNaN:Is Not a Number(No es un número)\nfunction actualizarContacto() {\n  rl.question('Ingrese el nombre del contacto a actualizar: ', (nombre) => {\n    if (agenda[nombre]) {\n      rl.question('Ingrese el nuevo número de teléfono: ', (telefono) => {\n        if (!isNaN(telefono) && telefono.length <= 11) {\n          agenda[nombre] = telefono;\n          console.log(`Contacto ${nombre} actualizado con éxito.`);\n        } else {\n          console.log(\n            'Número de teléfono no válido. Debe ser numérico y tener hasta 11 dígitos.'\n          );\n        }\n        mostrarMenu();\n        seleccionarOperacion();\n      });\n    } else {\n      mostrarMenu();\n      seleccionarOperacion();\n      console.log('\\n Viendo si entran los datos:', agenda);\n    }\n  });\n}\n//4. Eliminar conctto\nfunction eliminarContacto() {\n  rl.question('Ingrese el nombre del contacto a eliminar: ', (nombre) => {\n    if (agenda[nombre]) {\n      delete agenda[nombre];\n      console.log(`Contacto ${nombre} eliminado con éxito.`);\n    } else {\n      console.log(`Contacto ${nombre} no encontrado.`);\n    }\n    mostrarMenu();\n    seleccionarOperacion();\n    console.log('\\n Viendo si entran los datos:', agenda);\n  });\n}\n//5.Mostrar a los contactos\nfunction mostrarTodosLosContactos() {\n  console.log('\\n** Todos los contactos **');\n  for (const [nombre, telefono] of Object.entries(agenda)) {\n    console.log(`${nombre}: ${telefono}`);\n  }\n  mostrarMenu();\n  seleccionarOperacion();\n  console.log('Viendo si entran los datos:', agenda);\n}\n//6. Función para seleccionar la operación\nfunction seleccionarOperacion() {\n  rl.question('Seleccione una operación (1-6): ', (opcion) => {\n    switch (opcion) {\n      case '1':\n        buscarContacto();\n        break;\n      case '2':\n        insertarContacto();\n        break;\n      case '3':\n        actualizarContacto();\n        break;\n      case '4':\n        eliminarContacto();\n        break;\n      case '5':\n        mostrarTodosLosContactos();\n        break;\n      case '6':\n        console.log('Saliendo del programa.');\n        rl.close();\n        break;\n      default:\n        console.log('Opción no válida. Inténtelo de nuevo.');\n        mostrarMenu();\n        seleccionarOperacion();\n        break;\n    }\n  });\n}\n\n// Inicio del programa\nmostrarMenu();\nseleccionarOperacion();\n\n//Esto no es eficiente pero funciona. Puede haber datos repetidos, no hay una id\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/MeLlamoOmar.js",
    "content": "let seleccion;\nconst contactos = [\n  {\n    nombre: 'Omar Tio',\n    numero: 8292854059,\n  },\n];\n\nconst mostrarContactos = () => {\n  let lista = '';\n\n  contactos.forEach((contacto, i) => {\n    lista += `${i + 1}. ${contacto.nombre} -> ${contacto.numero}\\n`;\n  });\n\n  alert(lista);\n};\n\nconst mostrarContacto = (contacto) => {\n  alert(`\n    Nombre: ${contacto.nombre}\n    Numero: ${contacto.numero}\n    `);\n};\n\nconst agregarContacto = () => {\n  const nombreContacto = prompt('Cual es el nombre de su contacto?');\n  let numeroContacto;\n  do {\n    numeroContacto = prompt('Cual es el numero de telefono de su contacto? ');\n    numeroContacto = Number(numeroContacto);\n  } while (\n    isNaN(numeroContacto) ||\n    toString(numeroContacto).length > 10 ||\n    toString(numeroContacto).length < 10\n  );\n  const contactoNuevo = { nombre: nombreContacto, numero: numeroContacto };\n  console.log('Agregando contacto nuevo ...');\n  console.table(contactoNuevo);\n  contactos.push(contactoNuevo);\n  console.log('Contacto agregado!');\n};\n\nconst buscarContacto = (text) => {\n  if (contactos.length === 0) {\n    alert('No hay contactos en la agenda');\n    return NaN;\n  }\n\n  mostrarContactos();\n\n  const busqueda = Number(prompt(text));\n\n  return [contactos[busqueda - 1], busqueda - 1];\n};\n\nconst actualizarContactos = (contacto) => {\n  let confirmarCambio = false;\n  if (!contacto) return;\n  const [{ nombre, numero }, idContacto] = contacto;\n\n  const nombreNuevo = prompt(`Cual nombre nuevo quiere asignarle al contacto: \n  ${nombre}\n  ${numero}`);\n  const numeroNuevo = prompt(`Cual numero nuevo quiere asignarle al contacto: \n  ${nombre} -> ${nombreNuevo}\n  ${numero}`);\n\n  while (!confirmarCambio) {\n    const conf = Number(\n      prompt(` Desea confirmar el siguiente cambio?\n      ${nombre} -> ${nombreNuevo}\n      ${numero} -> ${numeroNuevo}\n    1.Si\n    2.No\n      `)\n    );\n    if (conf === 1) {\n      confirmarCambio = true;\n    } else {\n      break;\n    }\n  }\n\n  if (confirmarCambio) {\n    contactos[idContacto] = { nombre: nombreNuevo, numero: numeroNuevo };\n  }\n};\n\nconst borrarContacto = (contacto) => {\n  let confirmarCambio = false;\n  if (!contacto) return;\n  const [{ nombre, numero }, idContacto] = contacto;\n\n  while (!confirmarCambio) {\n    const conf = Number(\n      prompt(` Desea borrar el siguiente contacto?\n      ${nombre}\n      ${numero}\n    1.Si\n    2.No\n      `)\n    );\n    if (conf === 1) {\n      confirmarCambio = true;\n    } else {\n      break;\n    }\n  }\n\n  if (confirmarCambio) {\n    contactos.splice(idContacto, 1);\n  }\n};\n\nwhile (seleccion != 6) {\n  seleccion = Number(\n    prompt(`\n  1. Agregar Contactos\n  2. Buscar Contactos\n  3. Actualizar Contactos\n  4. Borrar Contactos\n  5. Mostrar Contactos\n  6. Salir\n  `)\n  );\n  switch (seleccion) {\n    case 1:\n      agregarContacto();\n      break;\n    case 2:\n      mostrarContacto(\n        buscarContacto(\n          'Ingrese el numero de lista del contacto que desea buscar'\n        )\n      );\n      break;\n    case 3:\n      actualizarContactos(\n        buscarContacto(\n          'Ingrese el numero de lista del contacto que desea actualizar'\n        )\n      );\n      break;\n    case 4:\n      borrarContacto(\n        buscarContacto(\n          'Ingrese el numero de lista del contacto que desea borrar'\n        )\n      );\n      break;\n    case 5:\n      mostrarContactos();\n      break;\n    case 6:\n      seleccion = 6;\n      break;\n    default:\n      break;\n  }\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/MiguelAngelMTZ000414.js",
    "content": "console.log(`----------(◉◉∖____/◉◉)---------- Estructura de datos ----------(OO∖____/OO)----------\n    Utilizando operaciones de inserción, borrado, actualización y ordenación.\n    - Array[]           - Set()                    - Map()\n    let Array = [,,]    let set = new Set([,,])    let map = new Map([[clave,valor],])\n\n    - Object{}\n    let object = {clave: valor,}\n    `\n)\nconsole.log(\"-------------------------------- Array[] --------------------------------\")\nlet arrayED = [1, 2 ,3 , 4, 5, 6, 7, 8, 9, 10]\nconsole.log(arrayED)\nconsole.log(\"El tipo de dato del Arreglo es: \" + typeof(arrayED)) // typeOf arrayED\nconsole.log(\"Longitud del Arreglo: \" + arrayED.length)\nconsole.log(`Extraer datos del Array[0]: ${arrayED[0]}`)\nconsole.log(`Extraer datos del Array[1]: ${arrayED[1]}`)\nconsole.log(`Extraer datos del Array[2]: ${arrayED[2]}`)\nconsole.log(`Extraer datos del Array[3]: ${arrayED[3]}`)\nconsole.log(`Extraer datos del Array[4]: ${arrayED[4]}`)\nconsole.log(`Extraer datos del Array[5]: ${arrayED[5]}`)\nconsole.log(`Extraer datos del Array[6]: ${arrayED[6]}`)\nconsole.log(`Extraer datos del Array[7]: ${arrayED[7]}`)\nconsole.log(`Extraer datos del Array[8]: ${arrayED[8]}`)\nconsole.log(`Extraer datos del Array[9]: ${arrayED[9]}`)\nconsole.log(`Extraer datos del Array[10]: ${arrayED[10]}`) // No contiene datos\n\narrayED[10] = 11 // Insetando valores en la posición del Array[10]\narrayED[11] = 12 // Insetando valores en la posición del Array[11]\narrayED[12] = 13 // Insetando valores en la posición del Array[12]\narrayED[13] = 14 // Insetando valores en la posición del Array[13]\narrayED[14] = 15 // Insetando valores en la posición del Array[14]\nconsole.log(arrayED)\n\n// Insertando un valor al principio del arreglo con un unshift()\nconsole.log(\"con unshift() insertamos un valor al principio del Array\")\narrayED.unshift(0)\nconsole.log(arrayED)\n\n// Insetamos un valor al final del arreglo con push()\nconsole.log(\"Con push() insertamos un valor al final del Array\")\narrayED.push(16, 17)\nconsole.log(arrayED)\n\n// Borrar elemento en Array\nconsole.log(\"Con splice() indicamos cuales son los valores del Array que deseamos eliminar\");\n// splice(\"indiceInsertar, \"cantidadELiminar\", \"elemento1\")\n// splice(\"indiceEliminar, \"cantidadELiminar\")\nconsole.log(`El valor que eliminaremos del Array es: ${arrayED.splice(10, 1)}`)\nconsole.log(arrayED)\n\n// Actualización de valores del Array\nconsole.log(arrayED)\nconsole.log(\"Actualizar valores del Array mediante la posición del Array[posición]\")\narrayED[5] = \"Ivett\"\narrayED[11] = \"Samantha\"\narrayED[2] = \"Miguel\"\narrayED[16] = \"Aixa\"\narrayED[6] = \"Rox\"\narrayED[17] = \"Jenifer\"\narrayED[3] = \"Marce\"\narrayED[0] = \"Leonel\"\narrayED[13] = \"Xochitl\"\narrayED[14] = \"Nikol\"\nconsole.log(arrayED)\n\n// Ordenar\n// arrayED.sort((a, b) => a - b)  Ordena siempre y cuando sea del mismo dato string o number.\n// console.log(arrayED)\n\nconsole.log(\"-------------------------------- Set() --------------------------------\")\nlet setED = new Set()\n// Set no permite repetir los valores\nsetED = new Set([\n    \"McLaren\", \"Acura\", \"Peugeot\",\n    \"Apollo\", \"Ferrari\", \"Bugatti\",\n    \"Chevrolet\", \"Porsche\", \"Alfa Romeo\",\n    \"Mercedez-Benz\", \"Lamborghini\", \"BMW\",\n    \"Cadillac\" ,\"Nissan\", \"Mitsubishi\",\n    \"Lexus\", \"Apex\", \"Mazda\",\n    \"Pagani\", \"Jaguar\", \"Koenigsegg\",\n    \"Rezvani\", \"Pannfarina\", \"Rimac\",\n    \"Volkswagen\", \"Zenvo\", \"Lotus\",\n    \"Volkswagen\", \"Zenvo\", \"Lotus\",\n])\nconsole.log(setED)\n\nconsole.log(`El tipo de dato del Set es: ${typeof(setED)}`) // typeOf setED\nconsole.log(\"Tamaño del Set: \" + setED.size)\n\n// Con set.add() insertamos elementos (si no esta repetido)\nconsole.log(\"Con .add() insertaremos elementos al Set\")\nsetED.add(\"Trion\")\nsetED.add(\"Jeep\")\nsetED.add(\"Ford\")\nconsole.log(setED)\nconsole.log(\"Longitud del Set: \" + setED.size)\n\n// Con set.has() comprobamos si elemento ya existe en el conjunto true o false\nconsole.log(setED.has(\"Ford\")) // true si existe.\nconsole.log(setED.has(\"Mini\")) // false no existe.\n\nconsole.log(\"Con .delete() eliminaremos el elementos deseado del Set\")\nsetED.delete(\"Trion\")\nsetED.delete(\"Lotus\")\nconsole.log(setED)\nconsole.log(\"Longitud del Set: \" + setED.size)\n\nconsole.info(\"No es posible actualizar elementos en un set en JavaScript. Esto se debe a que los sets no tienen índices para obtener un elemento específico, a diferencia de los arrays.\")\n\n/* \nNo es posible reordenar los elementos de un set ni obtener un elemento directamente por su número. Pero sí, es posible ordenar elementos en un set en JavaScript, pero no de forma directa.\n\n    * Un set en JavaScript es una colección ordenada de elementos únicos, que se recuperan en el mismo orden en el que se insertaron.\n    * Para ordenar un set en JavaScript, se debe convertir primero en un Array, ordenar el Array y luego volver a convertirla en un set.\n*/\nconsole.log(\"Convertiremos el Set en Array\")\nlet arraySet = [...setED]\nconsole.log(arraySet)\nconsole.log(\"Ordenaremos los valores del Array con .sort()\")\narraySet.sort() // Con .sort() ordenamos los valores del Array\nconsole.log(arraySet)\nconsole.log(\"Convertiremos el Array en Set nuevamente\")\nlet setEDNew = new Set(arraySet)\nconsole.log(setEDNew)\n\nconsole.log(\"-------------------------------- Map() --------------------------------\")\nlet mapED = new Map() // Declaración\nmapED = new Map([ // Inicialización\n    [\"Lamborghini\", \"Asterión\"],\n    [\"Pagani\", \"Zonda R\"],\n    [\"Porsche\", \"Panamera Turbo S\"],\n    [\"Mercedes Benz\", \"AMG GT-S\"],\n])\nconsole.log(mapED)\nconsole.log(`El tipo de dato del Map es: ${typeof(mapED)}`) // typeOf setED\nconsole.log(\"Tamaño del Map: \" + mapED.size)\n\nconsole.log(\"Accediendo a los elementos del Map() mediante la clabe Key\")\nconsole.log(mapED.get(\"Lamborghini\")) // Accediendo a los valores del Map mediante la key\nconsole.log(mapED.get(\"Pagani\"))\n\nconsole.log(\"Insertando elementos con set()\")\nmapED.set(\"McLaren\", \"SENNA GTR\")\nmapED.set(\"Puritalia\", \"Berlinetta\")\nmapED.set(\"Ford Mustang\", \"GT-500\")\nmapED.set(\"Ultima\", \"RS\")\nmapED.set(\"Chevrolet Corvette\", \"Stingray\")\nconsole.log(mapED)\n\nconsole.log(\"Eliminando elementos con delete()\")\nmapED.delete(\"Ultima\") // Eliminando elementos del Map con la clave Key\nconsole.log(mapED)\n\nconsole.log(\"Actualizando elementos con set()\")\n// El metodo .set() modifica tanto como agrega nuevos elementos al Map\nmapED.set(\"Lamborghini\", \"Terzo Millennio\")\nmapED.set(\"Pagani\", \"Huayra BC\")\nmapED.set(\"Porsche\", \"911 GT1 Evolution\")\nmapED.set(\"porsche\", \"918 Spyder\")\nconsole.log(mapED)\n\nconsole.log(\"-------------------------------- Object[] --------------------------------\")\nlet objectED = {\n    \"Lamborghini\": \"Termario\",\n    \"Porsche\": \"Taycan Turbo S\",\n    \"Pagani\": \"Zonda R\",\n    \"McLaren\": \"SENNA GTS\",\n}\nconsole.log(objectED)\nconsole.log(`El tipo de dato del Object es: ${typeof(objectED)}`) // typeOf objectED\n\nconsole.log(\"Accediendo a las propiedades del Object\")\n// Hay dos formas de acceder a las propiedades\nconsole.log(objectED.Lamborghini) // Notación por punto \".\"\nconsole.log(objectED[\"Porsche\"]) // Notación por corchetes \"[]\"\nconsole.log(objectED.Pagani) // Notación por punto \".\"\nconsole.log(objectED[\"McLaren\"]) // Notación por corchetes \"[]\"\n\nconsole.log(\"Insertando propiedades al Object\")\nobjectED.Maserati = \"MC20 GT2\" // Insetando propiedades con Notación por punto \".\"\nobjectED[\"Jaguar\"] = \"C-X75\" // Insetando propiedades con Notación por corchetes \"[]\"\nobjectED.Honda = \"Civic Type-R\" // Insetando propiedades con Notación por punto \".\"\nobjectED[\"Arrinera\"] = \"Hussarya 33\" // Insetando propiedades con Notación por corchetes \"[]\"\nobjectED.Apollo = \"N\" // Insetando propiedades con Notación por punto \".\"\nobjectED[\"Edad\"] = 24 // Insetando propiedades con Notación por corchetes \"[]\"\nconsole.log(objectED)\n\nconsole.log(\"Eliminando propiedades del Object\")\ndelete objectED.Apollo\nconsole.log(objectED)\n\nconsole.info(\"Modificando propiedades del Object\")\nobjectED.Porsche = \"911 GT1 Evolution\" // Modificando propiedades del objecto usando la Notación por punto \".\"\nobjectED[\"McLaren\"] = \"P1\" // Modificando propiedades del objecto usando la Notación por corchetes \"[]\"\nconsole.log(objectED)\n\n// Mostrando el tipo de dato mediante la clave \nconsole.log(typeof objectED.Lamborghini)\nconsole.log(typeof objectED.Edad)\n\n// Ejercició Extra\nconsole.info(`----------(◉◉∖____/◉◉)---------- Ejercicio Extra ----------(OO∖____/OO)----------\n    Creando una agenda de contactos`)\n// Primero debemos requerir el módulo \"readline\". Este módulo está integrado en Node.js, por lo que no nesitamos instalarlo.\nconst readline = require('readline')\n// Crear una interfaz para leer y escribir\n// Usamos el metodo \"createInterface()\" de \"readline\" para crear una interfaz que nos permita leer y escribir en la consola\nconst rl = readline.createInterface({\n    input: process.stdin, // Entrada desde la consola\n    output: process.stdout // Salida hacia la consola\n})\n\n// Creamos nuestro Array vació\nlet agendaContactos = []\n\n// Declaramos nuestra función\nfunction agenda_contactos() {\n    console.log(\"\")\n    // Hacemos uso de la varialbe \"rl\" llamando al metodo \"question\", al usuario le haremos una consulta, donde nos tendra que decir que desar hacer, su respuesta se almacenara en el parametro (operacion). \n    rl.question(\"¿Que operación desea realizar? \\n1.- Agregar: \\n2.- Buscar: \\n3.- Actualizar: \\n4.- Eliminar: \\n5.- Salir: \\n= \", (operacion) => {\n        // Haremos uso de una condicion, donde le pasaremos el parametro \"operacion\", donde evaluara si coincide con con los casos \"case\"\n        switch (operacion) {\n            // Caso 1.- Agregar\n            case \"agregar\":\n                // Con el metodo question, haremos una pregunta al usuario. \n                // La respuesta que nos de se pasara como parametro a (nombre)\n                rl.question(\"Nombre de la persona: \", (nombre) => {\n                    rl.question(\"Contacto de la persona: \", (contacto) => {\n                        let contactoNum = parseInt(contacto) // convertimos la variable contacto a tipo Number\n                        // Comparamos si lo que nos como parametro el Usuario es de tipo Numbrer, si es podra agregar el nombre y el contacto\n                        if (!isNaN(contactoNum)) {\n                            // con push agregamos el nombre y el contacto al array, pero como object dentro del array\n                            agendaContactos.push({nombre: nombre, contacto: contactoNum})\n                            //console.log(`Se agrego a la persona ${agendaContactos[\"nombre\"] = nombre} y su contacto ${agendaContactos[\"contacto\"] = contactoNum}`)\n                            console.log(`Se agrego a la persona ${nombre} y su contacto ${contactoNum}`)\n                            console.log(agendaContactos) // Mostrar los elementos del object para verificar\n                        } else {\n                            console.log(\"El número de contacto, no debe de contener palabras.\")\n                        }\n                        // Si la condicion se cumple velvemos a las operaciones de nuevo\n                        agenda_contactos()\n                    })\n                })\n                break\n            // Caso 2.- Buscar\n            case \"buscar\":\n                // Con el metodo question, haremos una pregunta al usuario. \n                // La respuesta que nos de se pasara como parametro a (nombre)\n                rl.question(\"Nombre de la persona: \", (nombre) => {\n                    // agendaContactos.find: El metodo find() devuelve el primer objecto que cumpla con la condiciòn, busca un nombre cuyo nombre conincida con el nombre que el usuario ingreso. La funcion callback\n                    // buscar_callback (Callback: compara .nombre de todos los objectos del arreglo si es igual al parametro nombre. Ussamos una funcion flecha (Arrow function)\n                    let buscar = agendaContactos.find(buscar_callback => buscar_callback.nombre === nombre)\n                    // Si \"buscar\" es verdadero\n                    if (buscar) {\n                        // Se imprime por consola el nombre y el contacto\n                        console.log(`Datos de ${nombre}: Contacto ${buscar.contacto}`)\n                    } else {\n                        console.log(\"No se ha podido encontrar a la Persona\")\n                    }\n                    // rl.close()\n                    agenda_contactos()\n                })\n                break\n            // Caso 3.- Actualizar\n            case \"actualizar\":\n                // Con el metodo question, haremos una pregunta al usuario. \n                // La respuesta que nos de se pasara como parametro a (nombre)\n                rl.question(\"Persona: \", (nombre) => {\n                    // agendaContacto.findIndex(): buscar el índice del primer nombre en la agendaContactos cuyo nombre coincida con el nombre que ingreso el usuario. Si se encuentra el nombre, findIndex() devuelve el índice del elemento; si no, devuelve -1.\n                    let actualizar_nombre = agendaContactos.findIndex((actualizar_callback) => actualizar_callback.nombre === nombre)\n                    // Si actualizar_nombre !== -1 es estrictamente no igual\n                    if (actualizar_nombre !== -1) {\n                        // Imprimimos por consola el nombre y el contacto\n                        console.log(`Datos de la persona: \\n  Nombre: ${nombre} \\n  Contacto: ${agendaContactos[actualizar_nombre].contacto}`) // Mostramos el nombre y el contacto de la persona buscada\n                        // Le hacemos una preguntamos al usuario, la respuesta que nos de se pasara como parametro a (nuevoElemento)\n                        rl.question(\"Ahora que desea hacer, cambiar el Nombre o cambiar el Contacto: \", (nuevoElemento) => {\n                            // Si el parametro \"nuevoElemento\" es igual a \"nombre\"\n                            if (nuevoElemento == \"nombre\") {\n                                // Le decimos al usuario que escriba el nuevo nombre, la respuesta que nos de se pasara como parametro a (nuevoNombre)\n                                rl.question(\"Ingrese el nuevo nombre: \", (nuevoNombre) => {\n                                    // Accedemos al array agendaContacto[actualizar_nombre] en la posicion indice especificada por \"actualizar_nombre\"\n                                    // Para acceder al valor del nombre: agendaContactos[actualizar_nombre].nombre\n                                    agendaContactos[actualizar_nombre].nombre = nuevoNombre // Asignamos el nuevo valor del usuario que ingreso\n                                    console.log(\"Se ha actualizado el nombre.\") // mostramos un mensaje\n                                    console.log(agendaContactos) // Mostramos los cambios\n                                    agenda_contactos() // Nos regresamos al Inicio\n                                })\n                            }\n                            // Si el parametro \"nuevoElemento\" es igual a \"contacto\"\n                            else if (nuevoElemento == \"contacto\") {\n                                // Le decimos al usuario que ingrese el nuevo contacto, la respuesta que nos de se pasara como parametro a (nuevoContacto)\n                                rl.question(\"Ingrese el nuevo número del contacto: \", (nuevoContacto) => {\n                                    // Convertimos el parametro a Number inicializandolo con una nueva variable contactoNum_actualizar\n                                    let contactoNum_actuailzar = parseInt(nuevoContacto)\n                                    // Comparamos si \"contactoNum_actuailzar\" no es de tipo Number, pero si es tipo Number pasa.\n                                    if (!isNaN(contactoNum_actuailzar)) {\n                                        // Accedemos al array agendaContacto[actualizar_nombre] en la posicion indice especificada por \"actualizar_nombre\"\n                                        // Para acceder al valor del nombre: agendaContactos[actualizar_nombre].contacto\n                                        agendaContactos[actualizar_nombre].contacto = contactoNum_actuailzar // Asignamos el nuevo valor del usuario que ingreso\n                                        console.log(\"Se ha actualizado el contacto\") // Mostramos el mensaje\n                                        console.log(agendaContactos) // Mostramos el array\n                                        agenda_contactos() // Nos regresamos al Inicio           \n                                    } else {\n                                        console.log(\"El número de contacto, no debe de contener palabras.\")\n                                        agenda_contactos() // Nos regresamos al Inicio            \n                                    }\n                                })                                \n                            } else {\n                                // Si el usuario no elige ni \"nombre\" ni \"contacto\": Si el usuario ingresa algo diferente a \"nombre\" o \"contacto\", se muestra un mensaje de error solicitando que elija una opción válida\n                                console.log(\"Indique que desea hacer. ¡Por Favor!\")\n                                agenda_contactos() // Nos regresamos al Inicio\n                            }\n                        })\n                    } else {\n                        console.error(\"No se ha podido encontrar a la Persona. \\nVerifique si se encuentra. ¡Por Favor!\")\n                        agenda_contactos() // Nos regresamos al Inicio\n                    }\n                })\n                break\n            // Caso 4.- Eliminar\n            case \"eliminar\":\n                // Mostramos los elementos del array\n                console.log(agendaContactos)\n                // Con el metodo question, haremos una pregunta al usuario. \n                // La respuesta que nos de se pasara como parametro a (nombre)\n                rl.question(\"Nombre de la Persona: \", (nombre) => {\n                    // agendaContacto.findIndex(): buscar el índice del primer nombre en la agendaContactos cuyo nombre coincida con el nombre que ingreso el usuario. Si se encuentra el nombre, findIndex() devuelve el índice del elemento; si no, devuelve -1.\n                    let eliminar = agendaContactos.findIndex(eliminar_Persona => eliminar_Persona.nombre === nombre)\n                    // Comparamos si eliminar es indiferente de -1\n                    if (eliminar !== -1) {\n                        // Accedemos al array, usando el metodo splice()\n                        // eliminar: especificamos el indice en el que se desea modificar el array\n                        // 1: le indicamos cuantos elemento queremos eliminar desde ese indice, en este caso es 1\n                        agendaContactos.splice(eliminar, 1) // eliminamos el elemento en la posición encontrada por findIndex().\n                        console.log(\"Se ha eliminado correctamente\") // Mostramos el mensaje\n                        console.log(agendaContactos)// Mostramos el array modificado\n                    } else {\n                        console.log(\"La persona que usted desea eliminar, no exite.\")\n                    }\n                    agenda_contactos() // Volvemos al inicio\n                })\n                break\n            // Caso 5.- Salir\n            case \"salir\":\n                // Aquí se está utilizando el método close() del objeto readline.Interface (almacenado en rl), que cierra la interfaz de lectura.\n                // Esto termina la sesión interactiva con el usuario, es decir, deja de escuchar las entradas del usuario y finaliza el programa o el ciclo de preguntas.\n                // Cuando se ejecuta rl.close(), el programa termina, y el proceso de Node.js se detiene si no hay más código que ejecutar.\n                rl.close()\n                break\n            default:\n                // Si en dado caso se escribe mal uno de los casos se muestra el mensaje\n                console.warn(\"De las opciones indique que desea hacer. ¡Por favor!\")\n                agenda_contactos() // Nuevamente nos vamos al inicio si no se repeta los \"case\"\n        }            \n    })\n}\nagenda_contactos() // Imprimimos por consola la función"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/N1sek.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n */\n\n// Arrays, sets, objects, map\n\nlet array = [\"JavaScript\", \"Python\", \"Bash\"]\n\nconsole.log(\"++++++ ARRAYS ++++++\")\nconsole.log(\"Array original: \"+array)\narray.push(\"PHP\") // Insertar\nconsole.log(\"Array con inserción al final: \"+array)\narray.unshift(\"Ruby\")\nconsole.log(\"Array con insercion al inicio: \"+array)\narray[2] = \"Lua\" // Modificar en X posicion\nconsole.log(\"Array con modificacion: \"+array)\narray.shift() //Elimina el primer elemento del array\nconsole.log(\"Array con primer elemento eliminado: \"+array)\narray.pop(); //Elimina el ultimo elemento del array\nconsole.log(\"Array con ultimo elemento eliminado: \"+array)\n\n/* SPLICE y SLICE */\nlet arraySplice = [\"JavaScript\", \"Python\", \"Bash\", \"Lua\", \"PHP\"]\nconsole.log(\"--- SPLICE: modifica el array original ---\")\nconsole.log(\"Array original: \"+arraySplice)\nconsole.log(\"Elementos eliminados del array con 'splice(2)': \"+arraySplice.splice(2)) // splice con un parametro\nconsole.log(\"Resultado array: \"+arraySplice)\narraySplice.push(\"Bash\", \"Lua\", \"PHP\")\nconsole.log(\"Elementos eliminados del array con 'splice(2,1)': \"+arraySplice.splice(2,1)) // splice con dos parametros\nconsole.log(\"Resultado array: \"+arraySplice)\narraySplice.push(\"Bash\")\nconsole.log(\"Elemento eliminado y reemplazado del array con 'splice(2,1,'Ruby')': \"+arraySplice.splice(2,1,\"Ruby\")) //splice con tres parametros\nconsole.log(\"Resultado array: \"+arraySplice)\n\nlet arraySlice = [\"JavaScript\", \"Python\", \"Bash\", \"Lua\", \"PHP\"]\nconsole.log(\"--- SLICE: no modifica el array original ---\")\nconsole.log(\"Array original: \"+arraySlice)\nlet arraySlice2 = arraySlice.slice(2) //Aray original no es modificado, por eso hay que guardar el resultado\nconsole.log(\"Resultado array con 'slice(2)': \"+arraySlice2) // slice con un parametro\nlet arraySlice3 = arraySlice.slice(1,3)\nconsole.log(\"Resultado array con 'slice(1,3)': \"+arraySlice3)\n\nconsole.log(\"++++++ SETS ++++++\")\nlet miSet = new Set([1, 2, 3, 4])\nmiSet.add(3) //Esto no hace nada porque los valores son unicos, no puede haber dos iguales\nmiSet.add(5) //Inserta\nmiSet.add(\"Hola\") //Inserta\nmiSet.delete(1) //Elimina\nconsole.log(miSet)\n\nconsole.log(\"++++++ OBJETOS ++++++\")\nlet yo = {\n    nombre: \"Dennis\",\n    apellido: \"Cizma\",\n    edad: 20,\n    nombreCompleto: function(){ return this.nombre + \" \" + this.apellido;}\n}\n\nyo[\"colorOjos\"] = 'Azules' // Insercion\nyo[\"nombre\"] = 'Denis' // Modificacion\ndelete yo.edad // Elimina propiedad\nconsole.log(yo)\nconsole.log(yo.nombreCompleto())\n\nconsole.log(\"++++++ MAP ++++++\")\nlet miMapa = new Map([\n    [1, \"uno\"],\n    [2, \"dos\"],\n    [3, \"tres\"]\n])\n\nmiMapa.set(4, \"cuatro\") // Insercion\nmiMapa.set(2, \"dos sobreescrito\") // Modificacion\nmiMapa.delete(1) // Borrado\n\n//Borra TODOS los elementos\n//miMapa.clear()\n\nconsole.log(miMapa)\nconsole.log(miMapa.has(2)) // Busca elemento y devuelve true si existe"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/Nightblockchain30.js",
    "content": "/* \n  * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n*/\n\n// >>> listas\nlet lista = [1, 2, 3, 4, 5, 6, 7, 8, 9]; // TYPE OF \"Object\"\n// Inserción\nlista.push(\"ten\");\n// Borrado\nlista.pop();\nconsole.log(lista);\n// Actualización\nlista[0] = \"One\";\nconsole.log(lista);\n// Ordenación\nlista.sort();\nconsole.log(lista);\n\n \n// >>> Diccionarios Objeto \n\n/*\nIMPORTANTE \n-> las claves SIEMPRE DEBEB ser strings\n-> los objetos en JS están pernsado para tener informacion estática\n-> Métodos propios del tipo de structura\n*/\n\nlet diccionario = { // constructor: ƒ Object()\n    nombre: \"Night\",\n    apellido: \"BlockChain\",\n    edad: 26\n};\n// Inserción\ndiccionario[\"nacionalidad\"]=\"Español\";\nconsole.log(diccionario);\n// Borrado\ndelete diccionario[\"nacionalidad\"];\nconsole.log(diccionario);\n// Actualización\ndiccionario[\"nombre\"]=\"ALP\";\nconsole.log(diccionario);\n// Ordenación\n// > No aplica\n\n\n// >>> Conjuntos\nmyset = new Set([1, 2, 3, 4, 5, 6, 7, 8, 9,9,9,9]); // No permite elementos repetidos\nconsole.log(myset);\n// Inserción\nmyset.add(10);\nconsole.log(myset);\n// Borrado\nmyset.delete(9);\nconsole.log(myset);\n// Actualización && Ordenación \n// >No aplica porque no permite acceso por índice\n\n\n// >>> Diccionario con Constructor MAP. \n/*\nIMPORTANTE \n-> las claves PUEDEN de ser cualquier tipo\n-> Permite agregar datos de forma dinámica\n-> Métodos propios del tipo de dato\n*/\n\nlet diccionarioMap = new Map([ // constructor: Map()\n    [1, \"Night\"], // clave INT\n    [\"apellido\", \"Blockchain\"], // clave STRING\n    [true, 26], // clave BOOL\n]);\n// Busqueda \ndiccionarioMap.get(\"apellido\");\nconsole.log(diccionarioMap);\n//  Inserción\ndiccionarioMap.set(\"nacionalidad\",\"español\");\nconsole.log(diccionarioMap);\n// Borrado\ndiccionarioMap.delete(true);\nconsole.log(diccionarioMap);\n// Actualización\ndiccionarioMap.set(1,\"Alonso\");\nconsole.log(diccionarioMap);\n// Ordenación\n// >No aplica porque no tiene índice\n\n\n// >>> Pilas // LIFO - last In First Out\nlet pila = [1,2,3,4,5]\n// Inserción\npila.push(\"6\");\nconsole.log(pila);\n// Borrado\npila.pop();\nconsole.log(pila);\n// Actualización\npila[0] = \"1\";\nconsole.log(pila);\n// Ordenación\npila.sort();\nconsole.log(pila);\n\n\n// >>> Colas // FIFO - FIRST In FIRST Out\nlet cola = [1,2,3];\n// Inserción\ncola.push(\"ultimo\");\nconsole.log(cola);\n// Borrado\ncola.shift(); \nconsole.log(cola);\n// Actualización\ncola[0]=\"dos\";\nconsole.log(cola);\n// Ordenación\ncola.sort();\nconsole.log(cola);\n\n/* DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\n\n// EJERCICIO HECHO CON ARRAYS DE OBJETOS\n\nlet contacts = [];\ncontacts.push({name:\"Pablo\", phone:\"6000774503\"});\ncontacts.push({name:\"Doly\", phone:\"6521412514\"});\n\n\n// SEARCH CONTACT\nfunction searchContact(name){\n    let contacto = contacts.find(contacto => contacto.name.toLowerCase() === name.toLowerCase());\n    if(contacto == undefined){\n        return \"Contacto no encontrado\"\n    }\n    return contacto.phone;\n    \n}\n\n// ADD CONTACT\nfunction addContact(name, phone){\n    if (phone.length > 11){\n        console.log(\"\\n --> El número es demasiado largo, debe tener 11 dígitos como máximo\\n\");\n    } else {\n        let contacto = contacts.find(contacto => contacto.name.toLowerCase() === name.toLowerCase());\n        if(contacto == undefined){\n            console.log(\"\\n --> Inserción realizada con éxito\\n\");\n            contacts.push({name,phone});\n        } else {\n            console.log(\"\\n --> Ese contacto ya existe, guárdalo con un nombre diferente\\n\");\n        }\n    }\n}\n\n// DELETE CONTACT\nfunction deleteContact(name){\n    let contacto = contacts.find(contacto => contacto.name.toLowerCase() === name.toLowerCase());\n    if (contacto == undefined){\n        console.log(\"\\n --> El nombre que has introducido no se encuentra en la agenda \\n\");\n    } else {\n        contacts = contacts.filter(contacto => contacto.name.toLowerCase() !== name.toLowerCase());\n        console.log(\"\\n Has eliminado el contacto: \" + name + \"\\n\");\n    }\n}\n\n// UPDATE CONTACT\nfunction updateContact(name, phone){\n    let contactIndex = contacts.findIndex(contacto => contacto.name.toLowerCase() === name.toLowerCase());\n    if (phone.length > 11){\n        console.log(\"\\n -->El número es demasiado largo, debe tener 11 dígitos como máximo \\n\");\n    } else {\n        if (contactIndex == -1){\n            console.log(\"\\n -->El nombre que has introducido no se encuentra en la agenda \\n\");\n        } else {\n            contacts[contactIndex].phone = phone;\n            console.log(\"\\n -->Has actualizado el número de teléfono de : \" + name +\" (\"+phone+\")\");\n        }\n    }\n}\n\n// VER AGENDA\nfunction verAgenda(){\n    if(contacts.length > 0){\n        console.log(\"TU AGENDA\");\n        console.log(\"------------------------------------\");\n        for(let i = 0; i< contacts.length; i++){\n            console.log(\"* Nombre: \" + contacts[i].name + \" | Teléfono: \" + contacts[i].phone);\n        }\n        console.log(\"------------------------------------\");\n        console.log(\"\\n\");\n    } else {\n        console.log(\"\\n--> Tu agenda de contactos está vacía prueba a añadir algún contacto primero\");\n    }\n}\n\n\nconst readline = require(\"readline\");\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout,\n});\n\nfunction showMenu() {\nconsole.log(\"¿Qué deseas hacer?\");\nconsole.log(\"1. Añadir Contacto\");\nconsole.log(\"2. Buscar Contacto\");\nconsole.log(\"3. Actualizar Contacto\");\nconsole.log(\"4. Eliminar Contacto\");\nconsole.log(\"5. Ver Agenda\");\nconsole.log(\"6. Salir\\n\");\n}\n\nfunction runAction(opcion) {\n\n    switch (opcion){\n        case \"1\":\n            rl.question(\"\\n --> Introduzca el nombre de contacto que quieres añadir \\n\", (newName) => {\n                rl.question(\"\\n --> y ahora su número de teléfono \\n\", (newPhone) => {\n                    addContact(newName, newPhone);\n                    run();\n                });\n            });  \n            break;\n        case \"2\":\n            rl.question(\"\\n --> Introduzca el nombre de contacto que quiere buscar \\n\", (opcion) => {\n                console.log(\"\\n --> El número de \" + opcion + \" es: \" +searchContact(opcion) +\"\\n\");\n                run();\n            });            \n            break;\n        case \"3\":\n            rl.question(\"\\n --> Introduzca el nombre de contacto que quieres actualizar \\n\", (newName) => {\n                rl.question(\"\\n --> y ahora su nuevo número de teléfono \\n\", (newPhone) => {\n                    updateContact(newName, newPhone);\n                    run();\n                });\n            });\n            break;\n        case \"4\":\n            rl.question(\"\\n --> Introduzca el nombre de contacto que deseas eliminar \\n\", (opcion) => {\n                deleteContact(opcion);\n                run();\n            });\n            break;\n        case \"5\":\n            verAgenda();\n            run();\n            break;\n        case \"6\":\n            console.log(\"\\n --> Cerrando agenda \\n\");\n            rl.close();\n            break;\n        default: \n            console.log(\"\\n --> No le entiendo \\n\");\n            run();\n    }\n}\n\nfunction run() {\n    showMenu();\n    rl.question(\"Seleccione una opción (1-6): \", (opcion) => {\n        runAction(opcion);\n    });\n}\n\nrun();\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/OmarLand.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto\n *   en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n*/\n\nconst { opendirSync } = require(\"fs\");\n\n// #########################\n// ### GESTIÓN DE ARRAYS ###\n// #########################\n\n// Arrays\nlet carBrands = [\"Mercedez\",\"Ferrari\",\"Peugeot\", \"Citroën\",\"Wolsvagen\", \"McLaren\",\"Toyota\",\"Daewoo\",\"Porshe\",\"Rolls-Royce\" ]\nconsole.log( \"Brand Cards >>> \", carBrands );\n\n//Insertando elementos en el array en la ultima posición del array:\ncarBrands.push(\"Malibu\");\nconsole.log(\"Elemento añadido en la ultima posición >>>\", carBrands );\n\n// Insertando elemento el en la primera posición del array:\ncarBrands.unshift(\"Seat\");\nconsole.log(\"Añadido en primera posición >>> \", carBrands );\n\n// Eliminando elemento del array en la ultima posición:\ncarBrands.pop();\nconsole.log(\"Ultimo elemento eliminado >>>\", carBrands );\n\n// Eliminando el primer elemento del array:\ncarBrands.shift();\nconsole.log(\"Primer elemento eliminado >>>\", carBrands );\n\n// Actualizando un elemento especifico del array:\ncarBrands[1] = \"Hummer\";\nconsole.log(\">>> Elemento [1] actualizado: \", carBrands);\n \n// Copiando el array integro\nlet newCarBrands = carBrands.slice();\nconsole.log( \"Copiado: \", newCarBrands );\n\n// Ver longitud de un array:\nconsole.log( \"Longitud del array es: \", carBrands.length );\n\n// Ordenamiento de los elementos de un array de forma ascendente:\ncarBrands.sort();\nconsole.log( \"ordenados de la A a la Z: \", carBrands );\n\n\n// ##########################\n// ### GESTIÓN DE OBJETOS ###\n// ##########################\n\n// Objeto\nlet heroe = {\n    nombre    : \"Iron man\",\n    poder     : \"volar\",\n    profesion : \"Filantropo heroe\",\n    fuerza    : 5,\n}\nconsole.log(\"Objeto: \", heroe );\n\n// Añadiendo un elemento nuevo al objeto Heroe:\nheroe.debilidad = \"Martinis\";\nconsole.log( \" Elemento añadido al objeto >>>\", heroe );\n\n// Eliminando un elemento de un objeto:\ndelete heroe.profesion;\nconsole.log(\"Eliminando elemento del objeto: >>>\", heroe);\n\n// Actualizando elemento de un objeto:\nheroe.poder = \"Super Fuerza\";\nconsole.log( \"Poder actualizado: \", heroe );\n\nconsole.log(\" \");\nconsole.log(\" \");\n\nconsole.log(\"#####################################\");\nconsole.log(\"#####################################\");\nconsole.log(\"#####################################\");\nconsole.log(\" \");\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n *   y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n *   y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más\n *   de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.\n*/\n\nlet contacts = [];\nconst readline = require(\"readline\");\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout,\n});\n\n//Validando el numero de telefono ingresado\nconst validatePhonenumer = (number) => {\n  const format = /^\\d{1,11}$/;\n  return format.test(number);\n};\n\n// Inserción de datos\nconst insertContact = () => {\n  rl.question(\"Ingresa nombre de contacto: \", (userInput) => {\n    let userName = userInput;\n\n    rl.question(\"Ingresa numero de telefono: \", (userInput) => {\n      let numberValidation = validatePhonenumer(userInput);\n      if (numberValidation == true) {\n        let phoneNumber = userInput;\n        contacts.push({ userName, phoneNumber });\n        console.log(\"\\n Contacto agregado\");\n        comenzarPrograma();\n      } else {\n        console.log(\"Formato de numero invalido\");\n        insertContact();\n      }\n    });\n  });\n};\n\n// Eliminando contacto\nconst deleteContact = () => {\n  rl.question(\"DIme que usuario deseas borrar del registro\", (userName) => {\n    index = findContact(userName);\n    if (index != -1) {\n      contacts.splice([index], 1);\n      console.log(\"\\n Contacto borrado\");\n    } else {\n      console.log(\n        \"\\n No hemos encontrados coincidencias con el dato ingresado\",\n      );\n    }\n  });\n};\n\n// Actualizando un contacto\nconst updateContact = () => {\n  rl.question(\"Indique el usuario a actualizar:\", (userName) => {\n    index = findContact(userName);\n    if (index != -1) {\n      rl.question(\"Ingrese el nuevo nombre de contacto:\", (userName) => {\n        contacts[index].userName = userName;\n        rl.question(\"Ingrese el nuevo numero de telefono:\", (phoneNumber) => {\n          contacts[index].phoneNumber = phoneNumber;\n          console.log(\"\\n Contacto actualizado\");\n          comenzarPrograma();\n        });\n      });\n    } else {\n      console.log(\"\\n No logro encontrar el contacto indicado o no existe.\");\n    }\n    comenzarPrograma();\n  });\n};\n\n//Encontrar coincidencias\nconst findContact = (name) => {\n  let contact = contacts.findIndex((contact) => contact.userName == name);\n  return contact;\n};\n\n// Buscando un contacto\nconst searchContact = () => {\n  rl.question(\"Ingresa nombre de contacto: \", (userName) => {\n    index = findContact(userName);\n    if (index != -1) {\n      console.log(\n        `\n          Nombre: ${contacts[index].userName}\n          Numero: ${contacts[index].phoneNumber}\n        `,\n      );\n    } else {\n      console.log(\"\\n No se encontraron coincidencias\");\n    }\n    comenzarPrograma();\n  });\n};\n\n// Muestra todos los contactos\nconst showAllContacts = () => {\n  for (i = 0; i <= contacts.length - 1; i++) {\n    console.log(`\n   Nombre: ${contacts[i].userName} - Numero: ${contacts[i].phoneNumber}`);\n  }\n  comenzarPrograma();\n};\n\n// Menu principal\nconst comenzarPrograma = () => {\n  // Pregunta al usuario y espera la respuesta\n  rl.question(\n    `\n      #### - Agenda de Contactos 1.0 - ####\n      Pulse 1 -> Para Insertar nuevo contacto\n      Pulse 2 -> Para Eliminar un contacto\n      Pulse 3 -> Para Actualizar un contacto\n      Pulse 4 -> Para Buscar contacto\n      Pulse 5 -> Mostrar todos los contactos\n      Pulse 6 -> Para Salir\n    `,\n    (userInput) => {\n      const selectedOption = parseInt(userInput);\n      switch (selectedOption) {\n        case 1:\n          insertContact();\n          break;\n\n        case 2:\n          deleteContact();\n          break;\n\n        case 3:\n          updateContact();\n          break;\n\n        case 4:\n          searchContact();\n          break;\n\n        case 5:\n          showAllContacts();\n          break;\n\n        case 6:\n          console.log(\"Gracias por usar la agenda 1.0. ¡Hasta luego!\");\n          rl.close();\n          break;\n\n        default:\n          console.log(\"No ha ingresado una opción válida.\");\n          comenzarPrograma();\n      }\n    },\n  );\n};\n\ncomenzarPrograma();\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/Pancratzia.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\n/***ESTRUCTURAS DE DATOS EN JS - PT1***/\n\n//Arrays\n\nlet arrayStructure = [1, 2, 3, 4, 5, 6, 7, 8, 9];\narrayStructure.push(10); //Inserción\narrayStructure.splice(7, 1); //Borrado\narrayStructure.pop(); //Borrado - Elimina el útlimo elemento del array\narrayStructure.shift(); //Borrado - Elimina el primer elemento del array\narrayStructure[6] = 8; //Actualización\nlet index = arrayStructure.findIndex((element) => element === 6); //Busqueda\narrayStructure = arrayStructure.sort((a, b) => b - a); //Ordenación\n\n//Sets\n\nlet setStructure = new Set([1, 2, 3, 4, 5, 6, 7, 8, 9]); //Representan un conjunto de elementos\nsetStructure.add(10); //Inserción\nsetStructure.delete(1); //Borrado\nsetStructure.has(3); //Busqueda - En este caso particular retorna un boolean de valor true\nsetStructure.clear(); //Borrado - Elimina todos los elementos\n\n//Los sets no tienen update o sort\n\n//Maps - Es una colección de pares clave-valor\n\nlet mapStructure = new Map([\n  [\"uno\", 1],\n  [\"dos\", 2],\n  [\"tres\", 3],\n  [\"cuatro\", 4],\n  [\"cinco\", 8],\n]);\n\nmapStructure.set(\"seis\", 6); //Inserción\nmapStructure.delete(\"seis\"); //Borrado\nmapStructure.get(\"cinco\"); //Busqueda\nmapStructure.set(\"cinco\", 5); //Actualización\nmapStructure.clear(); //Borrado - Elimina todos los elementos\n\n//Objects\n\nlet objectStructure = {\n  nombre: \"Carmen\",\n  apellido: \"Pérez\",\n  edad: 25,\n  dni: 12345678,\n  fechaNacimiento: \"01/01/2000\",\n};\n\nobjectStructure[\"Ciudad\"] = \"Madrid\"; //Inserción\ndelete objectStructure[\"Ciudad\"]; //Borrado\nobjectStructure[\"edad\"] = 26; //Actualización\nlet edad = objectStructure[\"edad\"]; //Busqueda\n\n/***ESTRUCTURAS DE DATOS EN JS - PT2***/\n/**ACTIVIDAD EXTRA**/\n\nconst readline = require(\"readline\");\n\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout,\n});\n\nlet contactos = [];\n\nfunction mostrarMenu() {\n  console.log(\"\\nAgenda de Contactos\\n\");\n  console.log(\"1. Mostrar Contactos\");\n  console.log(\"2. Buscar Contacto\");\n  console.log(\"3. Agregar Contacto\");\n  console.log(\"4. Actualizar Contacto\");\n  console.log(\"5. Eliminar Contacto\");\n  console.log(\"6. Salir\\n\");\n}\n\nfunction mostrarContactos() {\n  console.log(\"\\nLista de Contactos:\");\n  contactos.forEach((contacto) =>\n    console.log(`${contacto.nombre}: ${contacto.telefono}`)\n  );\n  volverAlMenu();\n}\n\nfunction buscarContacto(nombre) {\n  const contactoEncontrado = contactos.find(\n    (contacto) => contacto.nombre === nombre\n  );\n  if (contactoEncontrado) {\n    console.log(\n      `\\n${contactoEncontrado.nombre}: ${contactoEncontrado.telefono}`\n    );\n  } else {\n    console.log(`\\nContacto \"${nombre}\" no encontrado.`);\n  }\n  volverAlMenu();\n}\n\nfunction agregarContacto(nombre, telefono) {\n  contactos.push({ nombre, telefono });\n  console.log(`\\nContacto ${nombre} agregado.`);\n  volverAlMenu();\n}\n\nfunction actualizarContacto(nombre, nuevoTelefono) {\n  const contactoIndex = contactos.findIndex(\n    (contacto) => contacto.nombre === nombre\n  );\n  if (contactoIndex !== -1) {\n    contactos[contactoIndex].telefono = nuevoTelefono;\n    console.log(`\\nContacto ${nombre} actualizado.`);\n  } else {\n    console.log(`\\nContacto \"${nombre}\" no encontrado.`);\n  }\n  volverAlMenu();\n}\n\nfunction eliminarContacto(nombre) {\n  contactos = contactos.filter((contacto) => contacto.nombre !== nombre);\n  console.log(`\\nContacto ${nombre} eliminado.`);\n  volverAlMenu();\n}\n\nfunction validarTelefono(telefono) {\n  return /^\\d{1,11}$/.test(telefono);\n}\n\nfunction volverAlMenu() {\n  setTimeout(() => {\n    mostrarMenu();\n    rl.question(\"Seleccione una opción (1-6): \", (opcion) => {\n      ejecutarOperacion(opcion);\n    });\n  }, 1000);\n}\n\nfunction ejecutarOperacion(opcion) {\n  switch (opcion) {\n    case \"1\":\n      mostrarContactos();\n      break;\n    case \"2\":\n      rl.question(\"Nombre del contacto a buscar: \", (nombre) =>\n        buscarContacto(nombre)\n      );\n      break;\n    case \"3\":\n      rl.question(\"Nombre del contacto: \", (nombre) => {\n        rl.question(\"Número de teléfono: \", (telefono) => {\n          if (validarTelefono(telefono)) {\n            agregarContacto(nombre, telefono);\n          } else {\n            console.log(\"Número de teléfono no válido.\");\n            volverAlMenu();\n          }\n        });\n      });\n      break;\n    case \"4\":\n      rl.question(\"Nombre del contacto a actualizar: \", (nombre) => {\n        rl.question(\"Nuevo número de teléfono: \", (nuevoTelefono) => {\n          if (validarTelefono(nuevoTelefono)) {\n            actualizarContacto(nombre, nuevoTelefono);\n          } else {\n            console.log(\"Número de teléfono no válido.\");\n          }\n        });\n      });\n      break;\n    case \"5\":\n      rl.question(\"Nombre del contacto a eliminar: \", (nombre) =>\n        eliminarContacto(nombre)\n      );\n      break;\n    case \"6\":\n      console.log(\"Saliendo del programa.\");\n      rl.close();\n      break;\n    default:\n      console.log(\"Opción no válida.\");\n      volverAlMenu();\n  }\n}\n\nfunction iniciarPrograma() {\n  mostrarMenu();\n  rl.question(\"Seleccione una opción (1-6): \", (opcion) => {\n    ejecutarOperacion(opcion);\n  });\n}\n\niniciarPrograma();\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/RaulDoezon.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n*/\n\n// +++++++++ ARRAY +++++++++\nvar colores = [\"Blanco\", \"Azul\", \"Naranja\"];\n\ncolores.push(\"Verde\"); // Añade un elemento al final.\ncolores.splice(2, 1); // Elimina el elemento en el índice 2.\ncolores[2] = \"Rojo\"; // Actualiza el elemento en el índice 2.\ncolores.sort(); // Ordena los elementos alfabéticamente.\nconsole.log(colores);\n\n// +++++++++ OBJECT +++++++++\nvar bountyHunter = {\n  name: \"-\",\n  height: \"1.9m\",\n  specie: \"Human\",\n}\n\nbountyHunter.lastName = \"Aran\"; // Añade un nuevo elemento.\ndelete bountyHunter.specie; // Elimina una propiedad.\nbountyHunter.name = \"Samus\"; // Modifica el valor de una propiedad existente.\nObject.keys(bountyHunter).sort(); // Ordena las propiedad alfabéticamente, pero convierte el objeto en un arreglo.\nconsole.log(bountyHunter);\n\n// +++++++++ DIFICULTAD EXTRA +++++++++\nvar menu = \"Por favor, ingrese el número de la opción que desea ejecutar:\\n1) Agregar.\\n2) Actualizar.\\n3) Eliminar.\\n4) Buscar.\\n5) Salir.\"\nvar selectedOption = 0;\nvar directory = [];\n\nfunction addContact() {\n  var name = prompt(\"Por favor, ingrese el nombre del contacto:\");\n  var newContact = {Nombre: name};\n  var stringPhone = prompt(\"Por favor, ingrese el teléfono del contacto con 10 dígitos:\");\n  var phoneNumber = parseInt(stringPhone, 10);\n\n  if (/^[0-9.,]+$/.test(phoneNumber) && stringPhone.length === 10) {\n    newContact.Telefono = phoneNumber;\n    directory.push(newContact);\n  } else {\n    alert(\"Debe ingresar un número de teléfono conformado por 10 dígitos.\");\n  }\n}\n\nfunction updateContact() {\n  var name = prompt(\"Por favor, ingrese el nombre del contacto a actualizar:\");\n\n  function searchContact(contact) {\n    return contact.Nombre === name;\n  }\n\n  var results = directory.find(searchContact);\n  var newName = prompt(\"Por favor, ingrese el nombre nuevo:\");\n  \n  var stringnewPhone = prompt(\"Por favor, ingrese el teléfono nuevo con 10 dígitos:\");\n  var newPhoneNumber = parseInt(stringnewPhone, 10);\n\n  if (/^[0-9.,]+$/.test(newPhoneNumber) && stringnewPhone.length === 10) {\n    results.Nombre = newName;\n    results.Telefono = newPhoneNumber;\n  } else {\n    alert(\"Debe ingresar un número de teléfono conformado por 10 dígitos.\");\n  }\n}\n\nfunction deleteContact() {\n  var name = prompt(\"Por favor, ingrese el nombre del contacto que desea eliminar:\");\n\n  function searchContact(contact) {\n    return contact.Nombre === name;\n  }\n\n  var results = directory.findIndex(searchContact);\n\n  if (results >= 0) {\n    directory.splice(results, 1);\n  } else {\n    alert(\"El contacto no pudo ser eliminado porque no existe.\");\n  }\n}\n\nfunction searchContact() {\n  var name = prompt(\"Por favor, ingrese el nombre del contacto que desea buscar:\");\n\n  function searchContact(contact) {\n    return contact.Nombre === name;\n  }\n\n  var results = directory.find(searchContact);\n\n  if (results === undefined) {\n    alert(\"El contacto no existe.\");\n  } else {\n    alert(\"Nombre: \" + results.Nombre + \"\\n\" + \"Teléfono: \" + results.Telefono);\n  }\n}\n\ndo {\n  selectedOption = parseInt(prompt(menu), 10);\n\n  switch (selectedOption) {\n    case 1:\n      addContact();\n      break;\n\n    case 2:\n      updateContact();\n      break;\n\n    case 3:\n      deleteContact();\n      break;\n\n    case 4:\n      searchContact();\n      break;\n\n    case 5:\n      alert(\"Cerrando la agenda.\");\n      break;\n\n    default:\n      alert(\"Por favor, introduzca una opción del 1 al 5.\");\n      break;\n  }\n} while (selectedOption !== 5);\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/Reaien.js",
    "content": "//Tipo de estructura de datos JS\n\n//ARRAYS\n\n//Array con elementos\nconst myArray = [\"Hola\", \"Mundo\", \"JavaScript\", \"Retos de programación\", 11];\nconsole.log(myArray);\n\n//Inserción, push inserta un nuevo elemento al final de un array\nconst myArrayInsercion = [\n  \"Hola\",\n  \"Mundo\",\n  \"JavaScript\",\n  \"Retos de programación\",\n  11,\n];\nmyArrayInsercion.push(12);\nconsole.log(myArrayInsercion);\n\n//Borrado, shift elimina el primer elemento de un array\nconst myArrayBorrar = [\n  \"Hola\",\n  \"Mundo\",\n  \"JavaScript\",\n  \"Retos de programación\",\n  11,\n];\nmyArrayBorrar.shift();\nconsole.log(myArrayBorrar);\n\n//Actualizacion, al seleccionar una posicion del array podemos actualizar su valor\nconst myArrayActualizado = [\n  \"Hola\",\n  \"Mundo\",\n  \"JavaScript\",\n  \"Retos de programación\",\n  11,\n];\nmyArrayActualizado[1] = \"World\";\nconsole.log(myArrayActualizado);\n\n//Ordenación, con sort ordenamos los elementos, primero numeral y luego alfabeticamente en string\nconst myArrayOrdenado = [\n  \"Hola\",\n  \"Mundo\",\n  \"JavaScript\",\n  \"Retos de programación\",\n  11,\n];\nmyArrayOrdenado.sort();\nconsole.log(myArrayOrdenado);\n\n//OBJETOS\n//Los objetos están compuestos por 2 clasificaciones clave y valor\n\n//Objeto\nconst miObjeto = {\n  pais: \"Chile\",\n};\n\n//Insersión de clave : valor a un objeto\nmiObjeto[\"nombre\"] = \"Andy\";\nconsole.log(miObjeto);\n\n//Actualización de valor de una clave dentro de un objeto\nmiObjeto.nombre = \"Lucy\";\nconsole.log(miObjeto);\n\n//Borrado de clave - valor\ndelete miObjeto.pais;\nconsole.log(miObjeto);\n\n//PILAS\n//Se caracteriza por seguir la secuencia LIFO\n//Inicializacion de pila o stack\nclass Pila {\n  constructor() {\n    this.items = [];\n  }\n  //Metodo para validar pila vacía\n  isEmpty() {\n    return this.items.length === 0;\n  }\n  //Metodo para retornar el valor que está por sobre el último elemento\n  last() {\n    if (this.isEmpty() === 0) {\n      return \"La pila está vacía\";\n    }\n    return this.items[this.items.length - 1];\n  }\n  //Metodo de inserción de valor a la pila\n  push(item) {\n    this.items[this.items.length] = item;\n  }\n\n  //Metodo para borrar el último valor de la pila\n  pop() {\n    if (this.isEmpty()) {\n      return \"la pila está vacia\";\n    }\n    const lastElement = this.items[this.items.length - 1];\n    this.items.length -= 1;\n    return lastElement;\n  }\n}\n\nconst miPila = new Pila();\n//Inserción a la pila de valor\nmiPila.push(\"hola\");\nmiPila.push(\"mundo\");\nmiPila.push(\"Javascript\");\nconsole.log(miPila);\n\n//Comprobación de último elemento en la pila\nconsole.log(miPila.last());\n\n//Borrado de último elemento de la pila\nconsole.log(miPila.pop());\n//Pila con nuevos valores al borrar el ultimo que se ingresó\nconsole.log(miPila);\n\n//Actualizar pila\nmiPila.items[0] = \"bye\";\nconsole.log(miPila);\n\n//COLAS\n//Se caracteriza por seguir la secuencia FIFO\n//Inicializacion de cola\nclass Cola {\n  constructor() {\n    this.items = [];\n    this.initialIndex = 0;\n  }\n  //validacion de cola vacía\n  isEmpty() {\n    return this.initialIndex >= this.items.length;\n  }\n\n  top() {\n    if (this.isEmpty()) {\n      return \"La cola está vacía\";\n    }\n    return this.items[this.initialIndex];\n  }\n\n  //Metodo para agregar elemento a la cola\n  enqueue(element) {\n    this.items[this.items.length] = element;\n  }\n\n  //Metodo para borrar elemento de la cola\n  dequeue() {\n    if (this.isEmpty()) {\n      return \"La cola está vacía\";\n    }\n    const firstElement = this.items[this.initialIndex];\n    delete this.items[this.initialIndex];\n    this.initialIndex++;\n    return firstElement;\n  }\n}\n\nconst miCola = new Cola();\n\n//Insercion de elementos a la cola\nmiCola.enqueue(\"Hola\");\nmiCola.enqueue(\"Mundo\");\nmiCola.enqueue(\"Javascript\");\n//cola con elementos\nconsole.log(miCola);\n\n//Ver el primer elemento ingresado y primer elemento en salir\nconsole.log(miCola.top());\n\n//Actualizar cola\nmiCola.items[0] = \"bye\";\nconsole.log(miCola);\n\n//Borrado de primer elemento ingresado\nconsole.log(miCola.dequeue());\n\n//Ejercicio extra pendiente...\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/RicJDev.js",
    "content": "//EJERCICIO\n//ARRAYS\nlet frutasQueMeGustan = ['mango', 'fresa', 'pera', 'manzana', 'uva', 'durazno'];\n\n//-Iteración de elementos-\nfor (let i = 0; i < frutasQueMeGustan.length; i++) {\n\tconsole.log(frutasQueMeGustan[i]);\n}\n\nfrutasQueMeGustan.forEach((elemento) => {\n\tconsole.log(elemento);\n});\n\nfrutasQueMeGustan.map((elemento) => {\n\tconsole.log(elemento);\n});\n\n//-Insercion-\nfrutasQueMeGustan.push('guanabana');\n\nfrutasQueMeGustan.unshift('aguacate');\n\nfrutasQueMeGustan.splice(2, 1, 'papaya');\n\n//-Borrado-\nfrutasQueMeGustan.pop();\n\nfrutasQueMeGustan.shift();\n\nfrutasQueMeGustan.splice(1, 1);\n\n//-Actualizacion-\nfrutasQueMeGustan[2] = 'piña';\n\nfrutasQueMeGustan.splice(1, 1, 'parchita');\n\nfrutasQueMeGustan.fill('tamarindo', 2, 3);\n\n//-Búsqueda-\nconsole.log(frutasQueMeGustan.indexOf('parchita'));\n\nfrutasQueMeGustan.push('parchita');\nconsole.log(frutasQueMeGustan.lastIndexOf('parchita'));\n\nconsole.log(frutasQueMeGustan.includes('parchita'));\nconsole.log(frutasQueMeGustan.includes('naranja'));\n\nconsole.log(\n\tfrutasQueMeGustan.find((valor) => {\n\t\treturn valor === 'tamarindo';\n\t})\n);\n\nconsole.log(\n\tfrutasQueMeGustan.findIndex((valor) => {\n\t\treturn valor === 'parchita';\n\t})\n);\n\nconsole.log(\n\tfrutasQueMeGustan.findLast((valor) => {\n\t\treturn valor === 'parchita';\n\t})\n);\n\nconsole.log(\n\tfrutasQueMeGustan.findLastIndex((valor) => {\n\t\treturn valor === 'parchita';\n\t})\n);\n\n//-Ordenado-\nlet nuevoArray = [12, 10, 34, 25, 82];\nconsole.log(nuevoArray);\nnuevoArray.sort((a, b) => a - b);\nconsole.log(nuevoArray);\n\nlet nuevoArray2 = [12, 10, 34, 25, 82];\nconsole.log(nuevoArray2);\nnuevoArray2.sort((a, b) => b - a);\nconsole.log(nuevoArray2);\n\n//-Concatenación-\nconsole.log(nuevoArray.concat(nuevoArray2));\n\n//-Otros-\nconsole.log(frutasQueMeGustan.join(' '));\n\nlet nuevoArray3 = [\n\t[1, 3],\n\t[23, 43],\n\t[21, 67],\n\t[12, 23],\n];\n\nconsole.log(nuevoArray3.flat());\n\n//SETS\nconst animales = new Set(['gallina', 'foca', 'lagarto']);\nconsole.log(animales);\n\n//-Insercion-\nanimales.add('gato');\nanimales.add('perro');\nanimales.add('araña');\nanimales.add('gato'); //no se ejecuta debido a que los sets no admiten duplicados\nconsole.log(animales);\n\n//-Borrado-\nanimales.delete('lagarto');\nanimales.delete('perro');\nconsole.log(animales);\n\n//-Ordenado-\n// los sets no tienen indice, por lo que no es posible ordenarlos sin antes convertirlos en un array\nconst miNuevoSet = new Set([12, 23, 45, 87, 43, 67, 12, 87]);\nconsole.log(miNuevoSet);\n\nlet arrayDelSet = Array.from(miNuevoSet).sort((a, b) => a - b);\nconsole.log(arrayDelSet);\n\n//-Otros-\nconsole.log(animales.has('foca'));\n\nanimales.clear();\nconsole.log(animales);\n\n//MAPS\nconst miMap = new Map([\n\t['clave1', 'valor1'],\n\t['uno', 1],\n\t['dos', 2],\n]);\nconsole.log(miMap);\n\n//-Iteración de elementos-\nmiMap.forEach((element) => {\n\tconsole.log(element);\n});\n\n//-Insercion-\nmiMap.set('nombre', 'Ric');\nconsole.log(miMap);\n\n//-Actualizacion-\nmiMap.set('nombre', 'Josue'); //se utiliza el mismo metodo\nconsole.log(miMap);\n\n//-Borrado-\nmiMap.delete('dos'); //elimina una clave-valor existente\nconsole.log(miMap);\n\n//-Otras operaciones-\nconsole.log(miMap.get('nombre')); //obtiene el valor de una clave\nconsole.log(miMap.get('uno'));\n\nconsole.log(`Mi map contiene la clave 'dos': ${miMap.has('dos')}`); //verfica si el map contiene una clave\n\nconsole.log(miMap.size); //nos indica la cantidad de claves-valor\n\n//OBJETOS\nconst persona = {\n\tnombre: 'Ricardo',\n\tedad: 21,\n\tsexo: 'masculino',\n\tcasado: false,\n\testatura: 159,\n};\nconsole.log(persona);\n\n//-Insercion-\npersona.pasatiempos = ['escribir', 'dibujar', 'leer'];\nconsole.log(persona);\n\n//-Borrado-\ndelete persona.estatura;\n\n//-Actualizacion-\npersona.pasatiempos[1] = 'escuchar musica';\n\npersona.edad = 22;\n\nconsole.log(persona);\n\nconsole.log(Object.keys(persona)); //devuelve un array con las claves del objeto\n\nconsole.log(Object.values(persona)); //devuelve un array con los valores del objeto\n\nconst copiaDePersona = Object.assign({}, persona);\ncopiaDePersona.nombre = 'Luis';\n\nconsole.log(copiaDePersona);\n\n//EXTRA\n//Se ejecuta en Node js\nconsole.log('\\nAGENDA DE CONTACTOS');\n\nconst { resolve } = require('path');\nconst readline = require('readline');\nconst rl = readline.createInterface({\n\tinput: process.stdin,\n\toutput: process.stdout,\n});\n\nconst contactos = [\n\t/*\n\t{\n\t\tnombre: 'Pedro',\n\t\ttelefono: '0412-5248215',\n\t},\n\t{\n\t\tnombre: 'Julia',\n\t\ttelefono: '0424-3333333',\n\t},\n\t{\n\t\tnombre: 'Juan',\n\t\ttelefono: '0212-3434345',\n\t},\n\t*/\n];\n\nfunction funcionDeBusqueda(nombre) {\n\tlet result = undefined;\n\n\tcontactos.find((contacto) => {\n\t\tif (contacto.nombre === nombre) {\n\t\t\tresult = contacto;\n\t\t}\n\t});\n\n\treturn result;\n}\n\nlet telefonoRegEx = /(\\d{4})\\-(\\d{7})/;\n\nfunction insertaContacto() {\n\tlet nuevoContacto = {\n\t\tnombre: '',\n\t\ttelefono: '',\n\t};\n\n\trl.question('\\nIngrese el nombre del contacto: ', (nombre) => {\n\t\tnuevoContacto.nombre = nombre;\n\n\t\trl.question('\\nIngrese el número de telefono del contacto: ', (telefono) => {\n\t\t\tif (telefonoRegEx.test(telefono)) {\n\t\t\t\tnuevoContacto.telefono = telefono;\n\t\t\t\tcontactos.push(nuevoContacto);\n\n\t\t\t\tconsole.log('\\nContacto agregado con exito!');\n\t\t\t} else {\n\t\t\t\tconsole.log('\\nFormato inválido. Por favor seguir el formato 0000-0000000');\n\t\t\t}\n\n\t\t\tagendaDeContactos();\n\t\t});\n\t});\n}\n\nfunction buscaContacto() {\n\tif (contactos.length > 0) {\n\t\trl.question('\\nIngrese el nombre del contacto: ', (nombre) => {\n\t\t\tlet contacto = funcionDeBusqueda(nombre);\n\n\t\t\tif (contacto === undefined) {\n\t\t\t\tconsole.log('\\nNo existe');\n\t\t\t} else {\n\t\t\t\tconsole.log(`\\n${contacto.nombre}: ${contacto.telefono}`);\n\t\t\t}\n\n\t\t\tagendaDeContactos();\n\t\t});\n\t} else {\n\t\tconsole.log('\\nNo hay registros');\n\t\tagendaDeContactos();\n\t}\n}\n\nfunction actualizaContacto() {\n\tif (contactos.length > 0) {\n\t\trl.question('\\nIngrese el nombre del contacto: ', (nombre) => {\n\t\t\tlet contacto = funcionDeBusqueda(nombre);\n\n\t\t\tif (contacto === undefined) {\n\t\t\t\tconsole.log('\\nNo existe');\n\n\t\t\t\tagendaDeContactos();\n\t\t\t}\n\n\t\t\trl.question('\\nIngrese el nuevo número de teléfono del contacto: ', (nuevoTelefono) => {\n\t\t\t\tif (telefonoRegEx.test(nuevoTelefono)) {\n\t\t\t\t\tcontacto.telefono = nuevoTelefono;\n\n\t\t\t\t\tconsole.log('\\nEl contacto ha sido actualizado!');\n\t\t\t\t} else {\n\t\t\t\t\tconsole.log('\\nFormato inválido. Por favor seguir el formato 0000-0000000');\n\t\t\t\t}\n\n\t\t\t\tagendaDeContactos();\n\t\t\t});\n\t\t});\n\t} else {\n\t\tconsole.log('\\nNo hay registros');\n\t\tagendaDeContactos();\n\t}\n}\n\nfunction eliminaContacto() {\n\tif (contactos.length > 0) {\n\t\trl.question('\\nIngrese el nombre del contacto: ', (nombre) => {\n\t\t\tlet contacto = funcionDeBusqueda(nombre);\n\n\t\t\tif (contacto === undefined) {\n\t\t\t\tconsole.log('\\nNo existe');\n\t\t\t} else {\n\t\t\t\tcontactos.splice(contactos.indexOf(contacto), 1);\n\n\t\t\t\tconsole.log('\\nContacto eliminado exitosamente!');\n\t\t\t}\n\n\t\t\tagendaDeContactos();\n\t\t});\n\t} else {\n\t\tconsole.log('\\nNo hay registros');\n\t\tagendaDeContactos();\n\t}\n}\n\nfunction mostrarLista() {\n\tif (contactos.length > 0) {\n\t\tconsole.log('\\nLISTA DE CONTACTOS\\n');\n\n\t\tcontactos.forEach((elemento) => {\n\t\t\tconsole.log(`- ${elemento.nombre}: ${elemento.telefono}`);\n\t\t});\n\t} else {\n\t\tconsole.log('\\nNo hay registros');\n\t}\n\n\tagendaDeContactos();\n}\n\nfunction agendaDeContactos() {\n\tconsole.log(\n\t\t'\\n1. Insertar contacto\\n2. Buscar contacto\\n3. Actualizar contacto\\n4. Eliminar contacto\\n5. Mostrar lista de contactos\\n6. Salir'\n\t);\n\n\trl.question('\\nSeleccione una opción: ', (opcion) => {\n\t\tif (opcion === '1') {\n\t\t\tinsertaContacto();\n\t\t} else if (opcion === '2') {\n\t\t\tbuscaContacto();\n\t\t} else if (opcion === '3') {\n\t\t\tactualizaContacto();\n\t\t} else if (opcion === '4') {\n\t\t\teliminaContacto();\n\t\t} else if (opcion === '5') {\n\t\t\tmostrarLista();\n\t\t} else if (opcion === '6') {\n\t\t\tconsole.log('\\nSaliendo de la aplicación...');\n\t\t\trl.close();\n\t\t} else {\n\t\t\tconsole.log('\\nOpción inválida. Introduzca un número del 1 al 6 para ejecutar una acción');\n\t\t\tagendaDeContactos();\n\t\t}\n\t});\n}\n\nagendaDeContactos();\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/Rikar20.js",
    "content": "// ESTRUCTURAS DE DATOS\n\n//ARRAYS(Un array es una colección ordenada de elementos)\n\nconst myArray =[\"Musica\", 1, \"Dos\", 3, \"temperaturas\"];\nconsole.log('\\n Arrays');\nconsole.log(myArray);\n\n//OBJETOS(Los objetos permiten almacenar datos en pares clave-valor)\nconst person ={\n    name: \"Ricardo\",\n    apellido: \"Oyola\",\n    nacionalidad: \"Colombiano\"\n}\nconsole.log('\\n Objetos');\nconsole.log(person);\n\n//SET(Un set es una colección de valores únicos, lo que significa que no puede haber duplicados en un set)\nconst mySet = new Set([1, 2, 3, 1, 2]);\nconsole.log('\\n Set');\nconsole.log(mySet);\n\n//MAP(Un map es similar a un objeto, pero las claves pueden ser de cualquier tipo de dato, no solo cadenas.)\nlet myMap = new Map();\nmyMap.set(\"key1\", \"value1\");\nmyMap.set(\"key2\", \"value2\");\nconsole.log('\\n Map');\nconsole.log(myMap);\n\nlet queue = [];\nqueue.push(1);\nqueue.push(2);\nlet firstItem = queue.shift(); // Elimina el primer elemento (1)\n\nlet stack = [];\nstack.push(1);\nstack.push(2);\nlet lastItem = stack.pop(); // Elimina el último elemento (2)\n\nconst readline = require('readline');\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout\n});\n\n// Definición de la clase Contacto\nclass Contacto {\n  constructor({ nombre, numeroDeTelefono, email }) {\n    this.nombre = nombre;\n    this.numeroDeTelefono = numeroDeTelefono;\n    this.email = email;\n  }\n}\n\n// Array que almacenará los contactos en la agenda\nconst agenda = [];\n\n// Función para agregar un nuevo contacto\nfunction agregarContacto() {\n    rl.question('Ingrese el nombre: ', (nombre) => {\n      rl.question('Ingrese el número de teléfono (debe ser numérico y tener 10 dígitos): ', (numeroDeTelefono) => {\n        // Validar que el número de teléfono sea numérico y tenga 10 dígitos\n        const esNumeroValido = /^\\d{10}$/.test(numeroDeTelefono);\n  \n        if (esNumeroValido) {\n          rl.question('Ingrese el correo electrónico: ', (email) => {\n            const nuevoContacto = new Contacto({ nombre, numeroDeTelefono, email });\n            agenda.push(nuevoContacto);\n            console.log(`Contacto ${nombre} agregado.`);\n            queHacer();\n          });\n        } else {\n          console.log('Número de teléfono inválido. Debe ser numérico y tener 10 dígitos.');\n          agregarContacto();\n        }\n      });\n    });\n  }\n\n  function actualizarContacto() {\n    rl.question('Ingrese el nombre del contacto que desea actualizar: ', (nombre) => {\n      const contactoAActualizar = agenda.find(contacto => contacto.nombre === nombre);\n  \n      if (!contactoAActualizar) {\n        console.log(`No se encontró el contacto ${nombre} en la agenda.`);\n        queHacer();\n      } else {\n        rl.question(`Ingrese el nuevo número de teléfono para ${nombre}: `, (nuevoNumeroDeTelefono) => {\n          contactoAActualizar.numeroDeTelefono = nuevoNumeroDeTelefono;\n          console.log(`Contacto ${nombre} actualizado con el nuevo número de teléfono.`);\n          queHacer();\n        });\n      }\n    });\n  }\n  \n// Función para remover un contacto por nombre\nfunction removerContacto(nombre) {\n  const indiceContacto = agenda.findIndex(contacto => contacto.nombre === nombre);\n\n  if (indiceContacto !== -1) {\n    agenda.splice(indiceContacto, 1);\n    console.log(`Contacto ${nombre} eliminado.`);\n    queHacer();\n  } else {\n    console.log(`No se encontró el contacto ${nombre} en la agenda.`);\n    queHacer();\n  }\n}\n\n// Función para buscar un contacto por nombre\nfunction buscarContacto(nombre) {\n  const buscar = agenda.find(contacto => contacto.nombre === nombre);\n\n  if (!buscar) {\n    console.log(`No se encontró el contacto ${nombre} en la agenda.`);\n  } else {\n    console.log(`Contacto encontrado:\\nNombre: ${buscar.nombre}\\nNúmero de teléfono: ${buscar.numeroDeTelefono}\\nCorreo electrónico: ${buscar.email}`);\n  }\n\n  queHacer();\n}\n\n// Función para mostrar el menú y manejar las opciones del usuario\nconst queHacer = () => {\n  rl.question('Escoge una opción a realizar:\\n1. Buscar contacto\\n2. Insertar contacto\\n3. Actualizar contacto\\n4. Eliminar contacto\\n5. Salir\\n', (answer) => {\n    switch (answer) {\n      case '1':\n        console.log('Realizando búsqueda de contacto...');\n        rl.question('Ingrese el nombre del contacto a buscar: ', (nombre) => {\n          buscarContacto(nombre);\n        });\n        break;\n      case '2':\n        console.log('Realizando inserción de contacto...');\n        agregarContacto();\n        break;\n      case '3':\n        console.log('Realizando actualización de contacto...');\n        actualizarContacto();\n        break;\n      case '4':\n        console.log('Realizando eliminación de contacto...');\n        rl.question('Ingrese el nombre del contacto a eliminar: ', (nombre) => {\n          removerContacto(nombre);\n        });\n        break;\n      case '5':\n        console.log('Saliendo...');\n        rl.close();\n        break;\n      default:\n        console.log('Opción no válida. Por favor, elige una opción del 1 al 5.');\n        queHacer();\n        break;\n    }\n  });\n};\n\n// Llamamos a la función para empezar\nqueHacer();\n\n  \n  \n\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/Sac-Corts.js",
    "content": "// Exercise //\n\n// Arrays\nlet array = [1, 2, 3, 4, 5];\n\narray.push(6);\narray.unshift(0);\narray.splice(3, 0, 2.5);\nconsole.log(array);\n\narray.pop();\narray.shift();\narray.splice(3, 1);\nconsole.log(array);\n\narray[2] = 9;\nconsole.log(array);\n\narray.sort((a, b) => a - b);\nconsole.log(array);\n\n// Objects\nlet obj = {\n    name: 'Isaac',\n    age: 22,\n    city: 'Reynosa'\n};\n\nobj.country = \"México\";\nconsole.log(obj);\n\ndelete obj.city;\nconsole.log(obj);\n\nobj.age = 23;\nconsole.log(obj);\n\nlet sortedKeys = Object.keys(obj).sort();\nlet sortedObj = {};\nfor (let key of sortedKeys) {\n    sortedObj[key] = obj[key];\n}\nconsole.log(sortedObj);\n\n// Sets\nlet set = new Set([2, 3, 5, 1, 4]); \n\nset.add(6);\nconsole.log(set);\n\nset.delete(3);\nconsole.log(set);\n\nlet sortedSet = new Set([...set].sort((a, b) => a - b));\nconsole.log(sortedSet);\n\n// Maps\nlet map = new Map([\n    [\"name\", \"Isaac\"],\n    [\"age\", 22],\n    [\"city\", \"Reynosa\"]\n]);\n\nmap.set(\"country\", \"México\");\nconsole.log(map);\n\nmap.delete(\"city\");\nconsole.log(map);\n\nmap.set(\"age\", 23);\nconsole.log(map);\n\nlet sortedMapArray = [...map.entries()].sort();\nlet sortedMap = new Map(sortedMapArray);\nconsole.log(sortedMap);\n\n// WeakSets\nlet weakSet = new WeakSet();\nlet obj1 = { a: 1 };\nlet obj2 = { b: 2 };\n\nweakSet.add(obj1);\nweakSet.add(obj2);\n\nweakSet.delete(obj1);\nconsole.log(weakSet);\n\n// WeakMaps\nlet weakMap = new WeakMap();\nlet key1 = {};\nlet key2 = {};\n\nweakMap.set(key1, \"value1\");\nweakMap.set(key2, \"value2\")\n\nweakMap.delete(key1);\n\nweakMap.set(key2, \"newValue2\");\nconsole.log(weakMap);\n\n// Extra Exercise //\n\nconst readline = require('readline');\n\nconst rl = readline.createInterface(\n    process.stdin, process.stdout);\n\n\nlet contactBook = [];\n\nfunction menu() {\n    console.log(`\n        1. Search contact\n        2. Add contact\n        3. Update contact\n        4. Delete contact\n        5. Exit\n        `);\n        rl.question('Select an option: ', handleUserInput);\n}\n\nfunction handleUserInput(option) {\n    switch(option) {\n        case '1':\n            searchContact();\n            break;\n        case '2':\n            addContact();\n            break;\n        case '3':\n            updateContact();\n            break;\n        case '4':\n            deleteContact();\n            break;\n        case '5':\n            rl.close();\n            break;\n        default:\n            console.log('Invalid option');\n            menu();\n    }\n}\n\nfunction searchContact() {\n    rl.question(\"Enter the contact's username: \", (name) => {\n        const contact = contactBook.find(c => c.name.toLowerCase() === name.toLowerCase());\n        if (contact) {\n            console.log(`Contact found: ${contact.name} - ${contact.phone}`);\n        } else {\n            console.log('Contact not found');\n        }\n        menu();\n    });\n}\n\nfunction addContact() {\n    rl.question(\"Enter the contact's username: \", (name) => {\n        rl.question(\"Enter the contact's phone number: \", (phone) => {\n            if (/^\\d{1,11}$/.test(phone)) {\n                contactBook.push({name, phone});\n                console.log('Contact added');\n            } else {\n                console.log('Invalid phone number');\n            }\n            menu();\n        });\n    });\n}\n\nfunction updateContact() {\n    rl.question(\"Enter the name of the contact to update: \", (name) => {\n        const contact = contactBook.find(c => c.name.toLowerCase() === name.toLowerCase());\n        if (contact) {\n            rl.question(\"Enter the new phone number: \", (phone) => {\n                if (/^\\d{1,11}$/.test(phone)) {\n                    contact.phone = phone;\n                    console.log('Contact updated');\n                } else {\n                    console.log('Invalid phone number');\n                }\n                menu();\n            });\n        } else {\n            console.log('Contact not found');\n            menu();\n        }\n    });\n}\n\nfunction deleteContact() {\n    rl.question(\"Enter the name of the contact to delete: \", (name) => {\n        const index = contactBook.findIndex(c => c.name.toLowerCase() === name.toLowerCase());\n        if (index !== -1) {\n            contactBook.splice(index, 1);\n            console.log('Contact deleted');\n        } else {\n            console.log('Contact not found');\n        }\n        menu();\n    });\n}\n\nrl.on('close', () => {\n    console.log('Finished program')\n    process.exit(0);\n});\n\nmenu();"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/SalazarProgrammer.js",
    "content": "// #03 ESTRUCTURAS DE DATOS\n// Dificultad: Media | Publicación: 15/01/24 | Corrección: 22/01/24\n\n/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\n/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n */\n\nconsole.log('=== ESTRUCTURAS DE DATOS EN JAVASCRIPT ===');\n\n// 1. ARRAY (Arreglo)\nconsole.log('\\n1. ARRAY:');\n\n// Creación\nlet frutas = ['manzana', 'banana', 'naranja'];\nconsole.log('Array creado:', frutas);\n\n// Inserción\nfrutas.push('uva'); // Al final\nfrutas.unshift('pera'); // Al inicio\nfrutas.splice(2, 0, 'mango'); // En posición específica\nconsole.log('Después de inserciones:', frutas);\n\n// Actualización\nfrutas[1] = 'kiwi';\nconsole.log('Después de actualizar:', frutas);\n\n// Borrado\nfrutas.pop(); // Elimina el último\nfrutas.shift(); // Elimina el primero\nfrutas.splice(1, 1); // Elimina en posición específica\nconsole.log('Después de borrados:', frutas);\n\n// Ordenación\nfrutas.sort();\nconsole.log('Ordenado alfabéticamente:', frutas);\nfrutas.reverse();\nconsole.log('Ordenado inverso:', frutas);\n\n// 2. OBJECT (Objeto)\nconsole.log('\\n2. OBJECT:');\n\n// Creación\nlet persona = {\n\tnombre: 'Juan',\n\tedad: 30,\n\tciudad: 'Madrid',\n};\nconsole.log('Objeto creado:', persona);\n\n// Inserción\npersona.profesion = 'Desarrollador';\npersona['email'] = 'juan@email.com';\nconsole.log('Después de inserciones:', persona);\n\n// Actualización\npersona.edad = 31;\npersona['ciudad'] = 'Barcelona';\nconsole.log('Después de actualizaciones:', persona);\n\n// Borrado\ndelete persona.email;\nconsole.log('Después de borrados:', persona);\n\n// 3. SET (Conjunto)\nconsole.log('\\n3. SET:');\n\n// Creación\nlet numeros = new Set([1, 2, 3, 3, 4]); // Los duplicados se eliminan\nconsole.log('Set creado:', numeros);\n\n// Inserción\nnumeros.add(5);\nnumeros.add(6);\nconsole.log('Después de inserciones:', numeros);\n\n// Borrado\nnumeros.delete(3);\nconsole.log('Después de borrados:', numeros);\n\n// Verificación\nconsole.log('¿Contiene el 4?', numeros.has(4));\n\n// 4. MAP (Mapa)\nconsole.log('\\n4. MAP:');\n\n// Creación\nlet usuarios = new Map();\nusuarios.set('user1', { nombre: 'Ana', edad: 25 });\nusuarios.set('user2', { nombre: 'Carlos', edad: 30 });\nconsole.log('Map creado:', Array.from(usuarios));\n\n// Inserción\nusuarios.set('user3', { nombre: 'Maria', edad: 28 });\nconsole.log('Después de inserciones:', Array.from(usuarios));\n\n// Actualización\nusuarios.set('user2', { nombre: 'Carlos', edad: 31 });\nconsole.log('Después de actualizaciones:', Array.from(usuarios));\n\n// Borrado\nusuarios.delete('user1');\nconsole.log('Después de borrados:', Array.from(usuarios));\n\n// 5. WEAKMAP y WEAKSET\nconsole.log('\\n5. WEAKMAP y WEAKSET:');\n\n// WeakMap (solo acepta objetos como keys)\nlet weakMap = new WeakMap();\nlet obj1 = {};\nweakMap.set(obj1, 'valor1');\nconsole.log('WeakMap:', weakMap.get(obj1));\n\n// WeakSet (solo almacena objetos)\nlet weakSet = new WeakSet();\nweakSet.add(obj1);\nconsole.log('WeakSet contiene obj1:', weakSet.has(obj1));\n\n// 6. TYPED ARRAYS\nconsole.log('\\n6. TYPED ARRAYS:');\n\n// Int32Array\nlet intArray = new Int32Array([10, 20, 30, 40]);\nconsole.log('Int32Array:', intArray);\n\n// Float64Array\nlet floatArray = new Float64Array([1.1, 2.2, 3.3]);\nconsole.log('Float64Array:', floatArray);\n\n// 7. ARRAYBUFFER\nconsole.log('\\n7. ARRAYBUFFER:');\nlet buffer = new ArrayBuffer(16);\nlet view = new Int32Array(buffer);\nview[0] = 42;\nconsole.log('ArrayBuffer:', view[0]);\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Agenda de contactos por terminal\n */\n\nconsole.log('\\n=== AGENDA DE CONTACTOS ===');\n\n// Simulamos entrada de terminal con prompts (en navegador)\n// Para Node.js necesitaríamos el módulo 'readline'\n\nclass AgendaContactos {\n\tconstructor() {\n\t\tthis.contactos = new Map();\n\t}\n\n\tvalidarTelefono(telefono) {\n\t\tconst regex = /^\\d{1,11}$/; // Máximo 11 dígitos numéricos\n\t\treturn regex.test(telefono);\n\t}\n\n\tagregarContacto(nombre, telefono) {\n\t\tif (!this.validarTelefono(telefono)) {\n\t\t\treturn '❌ Teléfono inválido. Debe contener solo números y máximo 11 dígitos.';\n\t\t}\n\n\t\tif (this.contactos.has(nombre)) {\n\t\t\treturn '❌ El contacto ya existe.';\n\t\t}\n\n\t\tthis.contactos.set(nombre, telefono);\n\t\treturn '✅ Contacto agregado correctamente.';\n\t}\n\n\tbuscarContacto(nombre) {\n\t\tif (this.contactos.has(nombre)) {\n\t\t\treturn `📞 ${nombre}: ${this.contactos.get(nombre)}`;\n\t\t}\n\t\treturn '❌ Contacto no encontrado.';\n\t}\n\n\tactualizarContacto(nombre, nuevoTelefono) {\n\t\tif (!this.validarTelefono(nuevoTelefono)) {\n\t\t\treturn '❌ Teléfono inválido.';\n\t\t}\n\n\t\tif (this.contactos.has(nombre)) {\n\t\t\tthis.contactos.set(nombre, nuevoTelefono);\n\t\t\treturn '✅ Contacto actualizado correctamente.';\n\t\t}\n\t\treturn '❌ Contacto no encontrado.';\n\t}\n\n\teliminarContacto(nombre) {\n\t\tif (this.contactos.has(nombre)) {\n\t\t\tthis.contactos.delete(nombre);\n\t\t\treturn '✅ Contacto eliminado correctamente.';\n\t\t}\n\t\treturn '❌ Contacto no encontrado.';\n\t}\n\n\tlistarContactos() {\n\t\tif (this.contactos.size === 0) {\n\t\t\treturn '📋 La agenda está vacía.';\n\t\t}\n\n\t\tlet lista = '📋 Lista de contactos:\\n';\n\t\tfor (let [nombre, telefono] of this.contactos) {\n\t\t\tlista += `  ${nombre}: ${telefono}\\n`;\n\t\t}\n\t\treturn lista;\n\t}\n}\n\n// Simulación de la interfaz de terminal\nfunction simularAgenda() {\n\tconst agenda = new AgendaContactos();\n\n\tconsole.log('\\n--- SIMULACIÓN DE AGENDA ---');\n\n\t// Operaciones de ejemplo\n\tconsole.log(agenda.agregarContacto('Ana', '1234567890'));\n\tconsole.log(agenda.agregarContacto('Carlos', '0987654321'));\n\tconsole.log(agenda.agregarContacto('Maria', '5551234567'));\n\n\tconsole.log(agenda.buscarContacto('Ana'));\n\tconsole.log(agenda.buscarContacto('Pedro')); // No existe\n\n\tconsole.log(agenda.actualizarContacto('Carlos', '999888777'));\n\tconsole.log(agenda.actualizarContacto('Pedro', '111222333')); // No existe\n\n\tconsole.log(agenda.eliminarContacto('Maria'));\n\tconsole.log(agenda.eliminarContacto('Luis')); // No existe\n\n\tconsole.log(agenda.listarContactos());\n\n\t// Prueba de validación\n\tconsole.log(agenda.agregarContacto('Test', 'abc123')); // Inválido\n\tconsole.log(agenda.agregarContacto('Test', '123456789012')); // Demasiados dígitos\n}\n\n// Ejecutar la simulación\nsimularAgenda();\n\n// Fin de la simulación\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/TofeDev.js",
    "content": "//Array normal\nvar numeros = [10, 15, 54, 70, 64, 13]\nnumeros.pop() //Elimina el último elemento de un array\nnumeros.push(40) //Agrega un elemento al final de un array\nnumeros[2] = 52 //Actualizar un número\nnumeros.sort() //Ordena los elementos\nfor (i = 0; i < numeros.length; i++) {\n    console.log(numeros[i])\n}\n\nvar colores = [\"rojo\", \"amarillo\", \"azul\", \"morado\"]\ncolores.pop() //Elimina el último elemento de un array\ncolores.push(\"verde\") //Agrega un elemento al final de un array\ncolores[2] = \"naranja\" //Actualizar un string\ncolores.sort() //Ordena los elementos por orden alfabético\nfor (i = 0; i < colores.length; i++) {\n    console.log(colores[i])\n}\n\n//Array bidimencional\nvar matriz = [[1, 2, 3], [4, 5, 6]]\nfor(i = 0; i < matriz[i].length; i++) {\n    for(j = 0; j < matriz.length; j++) {\n      console.log(matriz[j][i]);\n    }\n}\n\n//Objetos\nvar persona = {\n    nombre: \"Marcos\",\n    edad: 24,\n    estudiante: false,\n}\npersona.edad = 25 //Actualizar una propiedad\npersona[\"profesión\"] = \"Analista de Datos\" //Agregar una propiedad\ndelete persona.estudiante //Eliminar una propiedad\nconsole.log(persona)\n\n\n//Sets\nvar miSet = new Set([51, 84, 34]) //Los sets no pueden tener elementos repetidos\nmiSet.add(17) //agregar un int\nmiSet.add(\"texto\") //agregar un string\nlet unObjeto = {a: 14, b:74} \nmiSet.add(unObjeto) //agregar un objeto\nmiSet.delete(51) //eliminar un elemento\nfor (let item of miSet.keys()) console.log(item)\n\n//Mapas\nconst mapa = new Map();\n//Agregar elementos\nmapa.set('a', \"primero\"); \nmapa.set('b', \"segundo\");\nmapa.set('c', \"tercero\");\nmapa.set('d', \"cuarto\");\nmapa.set('c', \"medio\") //Actualizar según la key\nmapa.delete('d'); //eliminar un elemento\nconsole.log(mapa)\n\n/* DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\nconst agenda = function () {\n  let agenda = [\n    { nombre: \"Marcos\", numero: \"1234567894\" },\n    { nombre: \"Andrea\", numero: \"1478523690\" },\n    { nombre: \"Carlos\", numero: \"4893175451\" }\n  ];\n\n  let leave = false;\n\n  while (!leave) {\n    let opcion = prompt(`Elija una opción:\n        1 - Buscar contacto\n        2 - Añadir contacto \n        3 - Actualizar contacto\n        4 - Eliminar contacto\n        5 - Salir`);\n\n    switch (opcion) {\n      case '1':\n        let search_contacto = prompt(\"Ingrese el nombre del contacto: \");\n        let contactoEncontrado = agenda.find(contacto => contacto.nombre === search_contacto);\n        if (contactoEncontrado) {\n          console.log(`Nombre: ${contactoEncontrado.nombre}, Número: ${contactoEncontrado.numero}`);\n        } else {\n          console.log(\"Contacto no encontrado\");\n        }\n        break;\n\n      case '2':\n        let nombre = prompt(\"Nombre del contacto: \");\n        let numero = prompt(\"Número del contacto: \");\n        if (numero.length <= 12) {\n          agenda.push({ nombre: nombre, numero: numero });\n          console.log(\"Contacto agregado\");\n        } else {\n          console.log(\"El número de teléfono debe tener 12 dígitos o menos\");\n        }\n        break;\n\n      case '3':\n        let nombreAntiguo = prompt(\"Ingrese el nombre del contacto que deseas actualizar: \");\n        let nombreNuevo = prompt(\"Ingrese el nuevo nombre del contacto: \");\n        let nuevoNumero = prompt(\"Ingrese el nuevo número de teléfono para este contacto: \");\n        let contactoParaActualizar = agenda.find(contacto => contacto.nombre === nombreAntiguo);\n        if (contactoParaActualizar) {\n          contactoParaActualizar.nombre = nombreNuevo;\n          contactoParaActualizar.numero = nuevoNumero;\n          console.log(\"Contacto actualizado\");\n        } else {\n          console.log(\"Contacto no encontrado\");\n        }\n        break;\n\n      case '4':\n        let eliminar_contacto = prompt(\"Nombre del contacto que desea eliminar: \");\n        let index = agenda.findIndex(contacto => contacto.nombre === eliminar_contacto);\n        if (index !== -1) {\n          agenda.splice(index, 1);\n          console.log(\"Contacto eliminado\");\n        } else {\n          console.log(\"Contacto no encontrado\");\n        }\n        break;\n\n      case '5':\n        leave = true;\n        console.log(\"Haz salido de la agenda\")\n        break;\n\n      default:\n        console.log('Opción no existente, por favor ingrese una opción válida');\n    }\n  }\n}\nagenda();"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/UserMatthew.js",
    "content": "/*# #03 ESTRUCTURAS DE DATOS \n  ## Ejercicio\n*/\n\n// 1. Arrays\nlet array = [3, 1, 4, 1, 5, 9, 7, 15, 11, 8, 35];\n// ---- Inserción ----\narray.push(2); // Inserción al final\nconsole.log(\"Mi array:\", array);\narray.unshift(6); // Inserción al inicio\nconsole.log(\"Mi array:\", array);\n// ---- Eliminación -----\narray.pop(); // Eliminación del último\nconsole.log(\"Mi array:\", array);\narray.shift(); // Eliminación del primero\nconsole.log(\"Mi array:\", array);\narray.splice(0, 3); // Elimina elementos especificos, 3 elementeos desde el indice 0\nconsole.log(\"Mi array:\", array);\narray.length = 5; // Elimina los elementos de una array hasta dejar solo indice especificado\nconsole.log(\"Mi array:\", array);\n// ---- Actualización -----\narray[1] = 10; // Actualización segun el indice\nconsole.log(\"Mi array:\", array);\n// ---- Ordenación ----\narray.sort((a, b) => a - b); // Ordenación de forma ascendente \nconsole.log(\"Mi array:\", array);\n// ---- Array Vacio -----\narray = []\nconsole.log(\"Mi array:\", array);\n\n// 2. Objetos \nlet objeto = { Nombre: 'Juan', edad: 25, profesión: 'Abogado ' };\nconsole.log(objeto)\n// ---- Inserción ----\nobjeto.apellidos = 'Diaz'\nobjeto.email = 'Juan@gmail.com';\nconsole.log(objeto)\n// ---- Actualización -----\nobjeto.Nombre = 'Bruno'\nconsole.log(objeto)\n// ---- Eliminación -----\ndelete objeto.edad\nconsole.log(objeto)\n// ---- LLamar solo una clave valor\nconsole.log(objeto.Nombre) //\n\n// 3. Maps\nlet map = new Map([['Nombre', 'Luffy'], ['edad', 17]]);\n// ---- Inserción ----\nmap.set('rango', 'capitan'); // Añade un nuevo dato debido a que no existe la clave\nconsole.log(map)\n// ---- Actualización -----\nmap.set('edad', 19); // Actualiza el valor debido a que existe la clave\nconsole.log(map)\n// ---- Eliminación -----\nmap.delete('rango'); //\nconsole.log(map)\n\n// 4. Sets \nlet set = new Set([1, 2, 3, 4, 5]);\n// ---- Inserción ----\nset.add(6); // Al no existir se añade\nset.add(1); // Al existir no se añade\nconsole.log(set)\n// ---- Eliminación -----\nset.delete(2); // Al existir se elimina\nconsole.log(set)\n\n\n// Dificultad Extra\n\nlet agenda = function () {\n  let agendaDB = [\n    { Nombre: 'Juan', Telefono: 123456789 },\n    { Nombre: 'Tony', Telefono: 987456312 },\n    { Nombre: 'Alberto', Telefono: 521364789 },\n    { Nombre: 'Viego', Telefono: 456123987 }\n  ];\n  let bucle = true;\n\n  while (bucle) {\n    let decision = prompt(`Elije una opción del menú:\n        1 - Buscar contacto\n        2 - Añadir contacto\n        3 - Actualizar contacto\n        4 - Eliminar contacto\n        5 - Salir`);\n\n    switch (decision) {\n      case '1':\n        let nombreBuscado = prompt(\"Ingrese el nombre del contacto a buscar: \");\n        let contactoEncontrado = agendaDB.find(contacto => contacto.Nombre === nombreBuscado);\n        if (contactoEncontrado) {\n          console.log(`Contacto encontrado: ${contactoEncontrado.Nombre} - ${contactoEncontrado.Telefono}`);\n        } else {\n          console.log(`No se encontró el contacto.`);\n        }\n        break;\n      case '2':\n        let nombre = prompt(\"Ingrese el nombre del nuevo contacto: \");\n        let telefono = prompt(\"Ingrese el número del nuevo teléfono: \");\n        if (telefono.length <= 11) {\n          agendaDB.push({ Nombre: nombre, Telefono: telefono });\n          console.log(`Contacto añadido: ${nombre} ${telefono}`);\n        } else {\n          console.log(\"El número de teléfono es demasiado largo.\");\n        }\n        break;\n      case '3':\n        let nombreActualizar = prompt(\"Ingrese el nombre del contacto a actualizar: \");\n        let contactoActualizado = agendaDB.find(contacto => contacto.Nombre === nombreActualizar);\n        if (contactoActualizado) {\n          let nuevoTelefono = prompt(\"Ingrese el nuevo número de teléfono: \");\n          if (nuevoTelefono.length <= 11) {\n            contactoActualizado.Telefono = nuevoTelefono;\n            console.log(`Contacto actualizado: ${nombreActualizar} ${nuevoTelefono}`);\n          } else {\n            console.log(\"El número de teléfono es demasiado largo.\");\n          }\n        } else {\n          console.log(`No se encontró el contacto.`);\n        }\n        break;\n      case '4':\n        let nombreEliminar = prompt(\"Ingrese el nombre del contacto a eliminar: \");\n        contactoEncontrado = agendaDB.find(contacto => contacto.Nombre === nombreEliminar);\n        if (contactoEncontrado) {\n          agendaDB = agendaDB.filter(contacto => contacto.Nombre !== nombreEliminar);\n          console.log(`Contacto eliminado: ${nombreEliminar}`);\n        } else {\n          console.log(`No se encontró el contacto.`);\n        }\n        break;\n      case '5':\n        bucle = false;\n        break;\n      default:\n        console.log('Opción no existente, por favor ingrese una opción válida');\n    }\n  }\n}\n\nagenda();\n\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un Nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/Vixito.js",
    "content": "// CREACIÓN DE LAS ESTRUCTURAS SOPORTADAS\n\n// Datos primitivos (no pueden ser manipuladas por las distintas operaciones)\n\nlet numero = 4;\nlet float = 4.0;\nlet cadena = \"jeje\";\nlet booleano = true;\n\n// Array\nconst array = [\"Hola\", \"moure\", \"soy\", \"Vixis\"];    // Creación\nconst array_2 = new Array;\nconsole.log(array);\nconsole.log(array.push(\"zzz\"));                     // Operación de inserción\nconsole.log(array.unshift(1));\nconsole.log(array.pop());                           // Operación de borrado\nconsole.log(array.shift());\nconsole.log(array[1]=\"Moure\");                      // Operación de actualización\nconsole.log(array.sort());                          // Operación de ordenación ascendente\nconsole.log(array.sort((a, b) => {                  // Operación de ordenación descendente\n    if (a > b) return -1;\n}));\n\n// Map\n\nlet mapa = new Map();   // Creación\nmapa.set({ z: 1, x: 2, y: 3 }, \"zzz\");\nmapa.set(\"a\", 1);\nmapa.set(\"b\", 2);\nmapa.set(\"c\", 3);       // Operación de inserción\nmapa.delete(\"a\");       // Operación de borrado\nmapa.set(\"b\", 20)       // Operación de actualización\nconsole.log(mapa + \"\\n\");\n\n// Object\n\nconst objeto = {                // Creación\n    nombre: \"Vixito\",\n    edad: \"22\",\n    país: \"Colombia\"\n}; console.log(objeto);\nobjeto.profesion = \"Ingeniero\"; // Operación de inserción\ndelete objeto.país;             // Operación de borrado\nobjeto.nombre = \"Carlos\";       // Operación de actualización\nconsole.log(objeto);\n\n// Set\n\nlet conjunto = new Set([1, 2, 3, 4, 5]);    // Creación\nconjunto.add(6);                            // Operación de inserción\nconjunto.delete(3);                         // Operación de borrado\n// No hay operación de actualización porque no exite un comando como tal, se tiene que hacer manualmente.\n\n\n\n// DIFICULTAD EXTRA\n\nconst readline = require('readline');\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\nlet contacto = [];\n\nfunction Menu(){\n    console.log(\"AGENDA DE DATOS \\n Pulsa los números para explorar las opciones: \\n 1. Buscar contacto \\n 2. Insertar contacto \\n 3. Actualizar contacto \\n 4. Eliminar contacto \\n 5. Cerrar\");\n    rl.question(\"Selecciona: \", (opcion) => {\n        switch (opcion.trim()) {\n            case '1':\n                rl.question(\"Nombre del contacto a buscar: \", (nombre) => {\n                    const busqueda = contacto.find(c => c.nombre.toLowerCase() === nombre.trim().toLowerCase());\n                    if(busqueda){\n                        console.log(`✅ Contacto encontrado: ${busqueda.nombre} - ${busqueda.telefono}\\n`);\n                    }else{\n                        console.log(\"❌ Contacto no encontrado.\\n\");\n                    }\n                    Menu();\n                })\n                break;\n            case '2':\n                rl.question(\"Inserte el nombre: \", (nombre) => {\n                    rl.question(\"Inserte el teléfono: \", (telefono) => {\n                        if(/^\\d{1,11}$/.test(telefono)){\n                            contacto.push({nombre: nombre.trim(), telefono: telefono.trim()});\n                            console.log(\"✅ Contacto añadido.\\n\");\n                        }else{\n                            console.log(\"❌ Número de teléfono no válido.\\nDebe ser numérico y no más de 11 dígitos.\\n\");\n                        }\n                        Menu();\n                    });\n                });\n                break;\n            case '3':\n                rl.question(\"Nombre del contacto a actualizar: \", (nombre) => {\n                    const indice = contacto.findIndex(c => c.nombre.toLowerCase() === nombre.trim().toLowerCase());\n                    if (indice !== -1) {\n                        rl.question(\"Inserte el nuevo nombre: \", (nuevoNombre) => {\n                            rl.question(\"Inserte el nuevo número de teléfono: \", (nuevoTelefono) => {\n                                if (/^\\d{1,11}$/.test(nuevoTelefono)) {\n                                    contacto[indice] = { nombre: nuevoNombre.trim(), telefono: nuevoTelefono.trim() };\n                                    console.log(\"✅ Contacto actualizado.\\n\");\n                                } else {\n                                    console.log(\"❌ Número de teléfono no válido.\\nDebe ser numérico y no más de 11 dígitos.\\n\");\n                                }\n                                Menu();\n                            });\n                        });\n                    } else {\n                        console.log(\"❌ Contacto no encontrado.\\n\");\n                        Menu();\n                    }\n                });\n                break;\n            case '4':\n                rl.question(\"Nombre del contacto a eliminar: \", (nombre) => {\n                    const indice = contacto.findIndex(c => c.nombre.toLowerCase() === nombre.trim().toLowerCase());\n                    if(indice !== -1){\n                        contacto.splice(indice, 1)\n                        console.log(\"✅ Contacto eliminado.\\n\");\n                    }else{\n                        console.log(\"❌ Contacto no encontrado.\\n\")\n                    }\n                    Menu();\n                });\n                break;\n            case '5':\n                rl.close();\n                break;\n            default:\n                console.log(\"\\nOpción no válida...\");\n                Menu();\n                break;\n        }\n    });\n}\n\nMenu();"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/VolumiDev.js",
    "content": "/**\n * Tipos de estructuras de datos:\n *  ➡️ Objetos \n *  ➡️ Arreglos (array)\n *  ➡️ Mapas (map)\n *  ➡️ Conjuntos (set) \n */\n\n// Objetos, podemos almacenar en los atributos distinto tipos de datos primitivos\n  var persona1 = {\n    nombre: 'Diego',\n    edad: 34,\n    grado: 'DAM'\n  }\n\n  // Podemos acceder a cada uno de los atributos del objeto de la siguiente manera\n  console.log('Atributo nombre de persona1', persona1.nombre)\n  console.log('Atributo edad de persona1', persona1.edad)\n  console.log('Atributo grado de persona 1', persona1.grado)\n  console.log('Aqui vemos el objeto completo', persona1)\n\n// Arrays, coleccion de datos, pueden ser de destintos tipos\nvar array1 = ['hola', 23, true, 'datos variables']\nconsole.log('Mostramos el array completo', array1)\nconsole.log('Accedemos a la segunda posicion del array desde el indice.', array1[1])\n\n// Mapas \nvar mapa = new Map()\n  // ➕ agregacion de elementos al mapa\nmapa.set('edad', 35)\nmapa.set('nombre', 'Diego')\nmapa.set(25, 'piso')\nmapa.set(true, 'estudios')\nconsole.log(mapa)\n  \n  // ➡️ accedemos al valor por su key.\nconsole.log(mapa.get('edad'))\nconsole.log(mapa.get('nombre'))\nconsole.log(mapa.get(25))\nconsole.log(mapa.get(true))\n  // ➡️ comprobar si una clave existe\n  console.log('Comprobamos que existe la clave \"edad\"', mapa.has('edad'))\n  // ➖ Elimiar un elemento por su key\n  console.log(mapa)\n  mapa.delete('nombre')\n  console.log(mapa)\n\n// Conjuntos set\n  var conjunto = new Set(['Diego', 'Laura', 'Eren', 'Laia', 'Diego'])\n  console.log('Vemos los elementos del conjunto, Diego lo metimos dos veces pero como no es posible que haya elementos repetido no lo incluye', conjunto)\n  // Añadimos un elemento al conjunto\n  conjunto.add(35)\n  console.log(conjunto)\n  console.log('Comprobamos si exite el valor \"Diego\" en el conjunto', conjunto.has('Diego'))\n  console.log(conjunto)\n  //Eliminamos un elemento al conjunto\n  conjunto.delete('Laura')\n  console.log(conjunto)\n\n  // Dificultad extra AGENDA\n  \n  \n  //  **  EJECUCION  **\n  //IMPLEMENTAMOS EL ELEMENTO CON EL QUE VAMOS A HACER  LA LECTURA DEL TECLADO\n  const readline = require('readline')\n  const rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n  })\n\n  // DEFINIMOS EL MAP QUE ALMACENARA LA INFO\n  const agenda = new Map();\n  let telregEx = /\\d{9}/\n  \n  function inicio() {\n    rl.question('¿Que operacion desea realizar? insertar, buscar, actualizar, eliminar, salir:\\n', (resp) => {\n      resp.toLowerCase()\n      if (resp === 'insertar'){\n        rl.question('Introduce el nombre que deseas almacenar:\\n', (nom) => {\n          rl.question('Introduce el numero de telefono:\\n', (tel) => {\n            if(telregEx.test(tel)){\n              agenda.set(nom, tel)\n              console.log('Contacto insertado')\n              inicio()\n            }else {\n              console.log('El formato del telefono no es correcto')\n              inicio()\n            }\n          })\n        })\n      } else if (resp === 'buscar'){\n        rl.question('Introduce el nombre que deseas buscar:\\n', (nom) => {\n          if(agenda.has(nom)){\n            console.log(`Nombre: ${nom} Telefono: ${agenda.get(nom)}`)\n            inicio()\n          }else {\n            console.log('El nombre que has introducido no esta almacenado')\n            inicio()\n          }\n        })\n      } else if(resp === 'salir'){\n        console.log('Saliendo....')\n        process.exit(0)\n      }else if(resp === 'actualizar'){\n        rl.question('Introduce el nombre que deseas actualizar\\n', (nom) => {\n          if(agenda.has(nom)){\n            rl.question('Actualiza el numero de telefono\\n', (tel) => {\n              if(telregEx.test(tel)){\n                agenda.set(nom, tel)\n                console.log('Contacto actualizado')\n                inicio()\n              }else {\n                console.log('El formato del telefono no es correcto')\n                inicio()\n              }\n            })\n          }\n        })\n      }else if(resp === 'eliminar'){\n        rl.question('Introduce el nombre que deseas borrar:\\n', (nom) => {\n          if(agenda.has(nom)){\n            agenda.delete(nom)\n            console.log('Contacto borrado')\n            inicio()\n          }else{\n            console.log('El nombre introducido no existe en el registro')\n            inicio()\n          }\n        })\n      }\n    })\n  }\n  \n  console.log('**** AGENDA ****')\n  inicio()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/YgriegaSB.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\n// Create contactos\nlet contactos = []\n\n// INSERT\nconst insertContacto = (nombre, numero) => {\n    contactos.push([nombre, numero]);\n}\n\ninsertContacto(\"Pedro Lama\", \"+555-555-5555\");\ninsertContacto(\"Lola Campbell\", \"+555-555-5556\");\ninsertContacto(\"May Yates\", \"+555-555-4444\");\ninsertContacto(\"Nicholas Sanders\", \"+555-555-3333\");\ninsertContacto(\"Edgar Morgan\", \"+555-555-7777\");\ninsertContacto(\"Gene Johnson\", \"+555-555-1111\");\n\n// DELETE\nconst deleteContact = (nombre) => {\n    contactos = contactos.filter((contacto) => contacto[0] != nombre);\n}\n\ndeleteContact(\"Cristian\");\n\n// UPDATE\nconst updateContact = (nombre, nuevoNumero) => {\n    const index = contactos.findIndex(contacto => contacto[0] === nombre);\n    return (index !== -1) ? contactos[index][1] = nuevoNumero : console.log(`Contacto \"${nombre}\" no encontrado.`);\n}\n\nupdateContact(\"Pedro Lama\", \"+555-555-2222\");\n\n\n// SORT\n/*\ncontactos.sort((a, b) => {\n    const nombreA = a[0].toLowerCase();\n    const nombreB = b[0].toLowerCase();\n\n    if (nombreA < nombreB) return -1;\n    if (nombreA > nombreB) return 1;\n    return 0;\n});\n\nconsole.log(contactos);\n\n*/\nfor (let i = 0; i < contactos.length - 1; i++) {\n    for (let j = 0; j < contactos.length - 1 - i; j++) {\n        const nombreA = contactos[j][0].toLowerCase();\n        const nombreB = contactos[j + 1][0].toLowerCase();\n        if (nombreA > nombreB) {\n            const temp = contactos[j];\n            contactos[j] = contactos[j + 1];\n            contactos[j + 1] = temp;\n        }\n    }\n}\n\nconsole.log(contactos);"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/Zunigaj1101.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto\n *   en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n*/\n\n// Arrays\n\nlet myArray = [1,2,3,4,5]\nlet myArray2 = new Array (6,7,8,9)\n\n// Insercion\nmyArray.push(6,7) // se añade al final del array\nmyArray.unshift (1,10) // se añade al inicio del array\n\n// Actualización\nmyArray[1] = 100 // actualiza el valor segun su indice\nmyArray.splice(1,1,500,2) // indico el indice, cuantos valores elimino, y cuantos añado \n\n// Ordenacion\nmyArray.sort ()  // convierte los elementos a cadenas y los ordena en orden lexicográfico\nmyArray.sort ((a, b)=> b - a) // orden descendente\n\n// Borrar\nmyArray.splice (2,3) // eliminar elementos especificos\nmyArray.shift() // elimina el primer elemento de una array\nmyArray.length = 4 // elimina los elementos de una array hasta dejar solo indice especificado\nmyArray = [] // vacia el array\n\nconsole.log (myArray)\nconsole.log (myArray2)\n\n// Objects \n\nlet myObjects = {name: \"Jose\", age: 30, alias: \"Chee\"}\nlet myObjetcs2 = new Object ({name:'Juan', age:29})\n\n// Inserción\nmyObjects.email = 'Che@gmail.com' // añado un elemento ya que no exite la clave\n\n// Actualización\nmyObjects.name = 'Juanito' // acutalizo la clave existente\n\n// Eliminacion\ndelete myObjects.age // elimina el par clave:valor\n\nconsole.log (myObjects)\nconsole.log (myObjects.name)\nconsole.log (typeof myObjetcs2)\n\n// Maps \n\nlet myMap = new Map ([['alias', 'Che'], ['name', 'Juan'] ])\n\n// Insercion\nmyMap.set (\"age\", 30) // añade ya que no exite la clave\n\n// Actualizacion \nmyMap.set ('age', 20) // actualiza ya que existe la clave\n\n// Borrar\nmyMap.delete ('age') // elimina mediate la clave\n\nconsole.log (myMap)\nconsole.log (typeof myMap)\n\n// Sets\n\n// Isercion\nlet mySet = new Set([1,3,4,6,7,2])\nmySet.add (10)\nmySet.add (2) // no se añade porque el valor ya existe\nmySet.add (1)\nmySet.add (myMap)\n\n// Acutalizacion y Delete\n// no se acualiza diretamente, se borra y se añade el elemento\n\nif (mySet.has(3)) {\n    mySet.delete(3); // elimina el elemento de un Set\n    mySet.add(30);\n}\n\nconsole.log (mySet)\n\n// WeakMap\n\nlet myWeakMap = new WeakMap ()\nmyWeakMap.set(myObjects, 'Nuevo valor')\n\nconsole.log (myWeakMap.get(myObjects))\n\n// WeakSet\n\nlet myWeakSet = new WeakSet ()\nmyWeakSet.add (myMap)\n\nconsole.log (myWeakSet.has(myMap))\n\n\n// * DIFICULTAD EXTRA (opcional):\n// * Crea una agenda de contactos por terminal.\n// * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n// *   y eliminación de contactos.\n// * - Cada contacto debe tener un nombre y un número de teléfono.\n// * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n// *   y a continuación los datos necesarios para llevarla a cabo.\n// * - El programa no puede dejar introducir números de teléfono no númericos y con más\n// *   de 11 dígitos (o el número de dígitos que quieras).\n// * - También se debe proponer una operación de finalización del programa.\n\nlet agenda = new Array ()\nagenda.push({name:'Jose', phone:123456789})\n\nconst readline = require('readline');\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nconst agregarContacto = () => {\n    rl.question ('Nombre del contacto: ', (nameCon) => {\n        if (/^.{1,50}$/.test(nameCon)) {\n            console.log ('\\nNombre guardado')\n            rl.question ('Numero del contacto: ', (phoneCon) => {\n                if (/^[0-9]{1,11}$/.test(phoneCon)) {\n                    agenda.push ({name:nameCon, phone:parseInt(phoneCon)})\n                    console.log ('\\n==================')\n                    console.log ('Contacto guardado')\n                    console.log ('==================\\n')\n                } else {\n                    console.log ('\\nNumero de contacto invalido\\n')\n                }\n                mostrarMenu ();\n            })\n        } else {\n            console.log ('\\nNombre invalido\\n')\n            mostrarMenu ();\n        }\n    })\n}\n\nconst buscarContacto = () => {\n    rl.question ('Nombre del contacto: ', (nameCon) => {\n        if (agenda.some(c => c.name === nameCon)) {\n            let contacto = agenda.find (c => c.name === nameCon)\n            console.log ('')\n            console.log (contacto)\n        } else {\n            console.log (`\\n${nameCon} no esta registrado.\\n`)\n        }\n        mostrarMenu();\n    });\n}\n\nconst actualizarContacto = () => {\n    rl.question ('Buscar contacto a actualizar: ', (nameCon) => {\n        if (agenda.some (c => c.name === nameCon)) {\n                console.log ('Contacto encontrado')\n            rl.question ('Nuevo nombre de contacto: ', (nameConNuevo) => {\n                if (/^.{1,50}$/.test(nameConNuevo)) {\n                    rl.question ('Nuevo numero de telefono: ', (phoneCon) => {\n                        if (/^[0-9]{1,11}$/.test(phoneCon)) {\n                            let contactoIdx = agenda.findIndex (c => c.name === nameCon)\n                            agenda.splice (contactoIdx, 1, {name: nameConNuevo, phone: parseInt(phoneCon)})\n                            console.log ('\\nContacto actualizado:')\n                            console.log (agenda[contactoIdx])\n                            mostrarMenu();\n                        } else {\n                            console.log ('\\nNumero de contacto invalido\\n')\n                            mostrarMenu();\n                        }\n                    })\n                }\n            })              \n        } else {\n            console.log ('\\nContacto invalido\\n')\n            mostrarMenu();\n        }\n    });\n}\n\nconst eliminarContacto = () => {\n    rl.question ('Bucar el contacto a eliminar: ', (nameCon) => {\n        if (agenda.some(c => c.name === nameCon)) {\n            let contactoIdx = agenda.findIndex (c => c.name === nameCon)\n            rl.question(`Escriba \"S\" para elminar el contacto: `, (value) =>{\n                if (value === 'S' || value === 's') {\n                    agenda.splice(contactoIdx, 1)\n                    console.log ('\\nContacto ' + nameCon + ' eliminado.')\n                    mostrarMenu();\n                } else {\n                    console.log ('\\nNo se elimino el contacto')\n                    mostrarMenu();\n                }\n            })\n        } else {\n            console.log (`\\nEl Contacto ${nameCon} no existe`)\n            mostrarMenu ();\n        }\n    })\n}\n\nconst mostrarMenu = () => {\n    console.log (\"\\n1. Mostrar Catalogo\")\n    console.log (\"2. Buscar contacto\")\n    console.log (\"3. Agregar Contacto\")\n    console.log (\"4. Actualizar Contacto\")\n    console.log (\"5. Eliminar Contacto\")\n    console.log (\"0. Salir\")\n    rl.question (\"Selecione una opcion: \", opciones)\n}\n\nfunction opciones(option) {\n    switch (parseInt(option)){\n        case 1:\n            console.table (agenda)\n            break;\n        case 2:\n            buscarContacto();\n            return\n        case 3:\n            agregarContacto ();\n            return;\n        case 4:\n            actualizarContacto ();\n            return;\n        case 5:\n            eliminarContacto();\n            return;\n        case 0:\n            console.log ('\\n==================')\n            console.log (' Agenda Cerrada')\n            console.log ('==================\\n')\n            rl.close();\n            return;\n        default:\n            console.log ('Opcion incorrecta, seleccione una opcion del 1 al 6.')\n            break;\n    }\n    mostrarMenu();\n}\n\nmostrarMenu();"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/aarxnmendez.js",
    "content": "// Ejemplos de creación de estructuras soportadas por defecto en JavaScript\r\n\r\n// 1. Arrays\r\nlet array = [1, 2, 3, 4, 5];\r\nconsole.log('Array:', array);\r\n\r\n// Operaciones con arrays\r\narray.push(6); // Inserción\r\nconsole.log('Array después de inserción:', array);\r\n\r\narray.splice(2, 1); // Borrado\r\nconsole.log('Array después de borrado:', array);\r\n\r\narray[1] = 10; // Actualización\r\nconsole.log('Array después de actualización:', array);\r\n\r\narray.sort((a, b) => a - b); // Ordenación\r\nconsole.log('Array después de ordenación:', array);\r\n\r\n// 2. Objetos\r\nlet objeto = { nombre: 'Juan', edad: 30 };\r\nconsole.log('Objeto:', objeto);\r\n\r\n// Operaciones con objetos\r\nobjeto.direccion = 'Calle Falsa 123'; // Inserción\r\nconsole.log('Objeto después de inserción:', objeto);\r\n\r\ndelete objeto.edad; // Borrado\r\nconsole.log('Objeto después de borrado:', objeto);\r\n\r\nobjeto.nombre = 'Pedro'; // Actualización\r\nconsole.log('Objeto después de actualización:', objeto);\r\n\r\n// 3. Mapas\r\nlet mapa = new Map();\r\nmapa.set('clave1', 'valor1');\r\nmapa.set('clave2', 'valor2');\r\nconsole.log('Mapa:', mapa);\r\n\r\n// Operaciones con mapas\r\nmapa.set('clave3', 'valor3'); // Inserción\r\nconsole.log('Mapa después de inserción:', mapa);\r\n\r\nmapa.delete('clave2'); // Borrado\r\nconsole.log('Mapa después de borrado:', mapa);\r\n\r\nmapa.set('clave1', 'nuevoValor1'); // Actualización\r\nconsole.log('Mapa después de actualización:', mapa);\r\n\r\n// 4. Conjuntos\r\nlet conjunto = new Set([1, 2, 3, 4, 5]);\r\nconsole.log('Conjunto:', conjunto);\r\n\r\n// Operaciones con conjuntos\r\nconjunto.add(6); // Inserción\r\nconsole.log('Conjunto después de inserción:', conjunto);\r\n\r\nconjunto.delete(3); // Borrado\r\nconsole.log('Conjunto después de borrado:', conjunto);\r\n\r\nconjunto = new Set([...conjunto].map(x => x * 2)); // Actualización\r\nconsole.log('Conjunto después de actualización:', conjunto);\r\n\r\n// Ejercicio extra: Agenda de contactos por terminal\r\n\r\nconst readline = require('readline');\r\n\r\nconst rl = readline.createInterface({\r\n    input: process.stdin,\r\n    output: process.stdout\r\n});\r\n\r\nlet contactos = [];\r\n\r\nfunction mostrarMenu() {\r\n    console.log('\\nAgenda de Contactos');\r\n    console.log('1. Insertar contacto');\r\n    console.log('2. Buscar contacto');\r\n    console.log('3. Actualizar contacto');\r\n    console.log('4. Eliminar contacto');\r\n    console.log('5. Salir');\r\n    rl.question('Selecciona una opción: ', (opcion) => {\r\n        switch (opcion) {\r\n            case '1':\r\n                insertarContacto();\r\n                break;\r\n            case '2':\r\n                buscarContacto();\r\n                break;\r\n            case '3':\r\n                actualizarContacto();\r\n                break;\r\n            case '4':\r\n                eliminarContacto();\r\n                break;\r\n            case '5':\r\n                rl.close();\r\n                break;\r\n            default:\r\n                console.log('Opción no válida');\r\n                mostrarMenu();\r\n                break;\r\n        }\r\n    });\r\n}\r\n\r\nfunction insertarContacto() {\r\n    rl.question('Nombre: ', (nombre) => {\r\n        rl.question('Número de teléfono: ', (telefono) => {\r\n            if (!/^\\d{1,11}$/.test(telefono)) {\r\n                console.log('Número de teléfono no válido. Debe ser numérico y tener hasta 11 dígitos.');\r\n                mostrarMenu();\r\n            } else {\r\n                contactos.push({ nombre, telefono });\r\n                console.log('Contacto insertado.');\r\n                mostrarMenu();\r\n            }\r\n        });\r\n    });\r\n}\r\n\r\nfunction buscarContacto() {\r\n    rl.question('Nombre del contacto a buscar: ', (nombre) => {\r\n        const contacto = contactos.find(c => c.nombre === nombre);\r\n        if (contacto) {\r\n            console.log(`Contacto encontrado: ${contacto.nombre} - ${contacto.telefono}`);\r\n        } else {\r\n            console.log('Contacto no encontrado.');\r\n        }\r\n        mostrarMenu();\r\n    });\r\n}\r\n\r\nfunction actualizarContacto() {\r\n    rl.question('Nombre del contacto a actualizar: ', (nombre) => {\r\n        const contacto = contactos.find(c => c.nombre === nombre);\r\n        if (contacto) {\r\n            rl.question('Nuevo número de teléfono: ', (telefono) => {\r\n                if (!/^\\d{1,11}$/.test(telefono)) {\r\n                    console.log('Número de teléfono no válido. Debe ser numérico y tener hasta 11 dígitos.');\r\n                } else {\r\n                    contacto.telefono = telefono;\r\n                    console.log('Contacto actualizado.');\r\n                }\r\n                mostrarMenu();\r\n            });\r\n        } else {\r\n            console.log('Contacto no encontrado.');\r\n            mostrarMenu();\r\n        }\r\n    });\r\n}\r\n\r\nfunction eliminarContacto() {\r\n    rl.question('Nombre del contacto a eliminar: ', (nombre) => {\r\n        const index = contactos.findIndex(c => c.nombre === nombre);\r\n        if (index !== -1) {\r\n            contactos.splice(index, 1);\r\n            console.log('Contacto eliminado.');\r\n        } else {\r\n            console.log('Contacto no encontrado.');\r\n        }\r\n        mostrarMenu();\r\n    });\r\n}\r\n\r\nmostrarMenu();"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/adrs1166ma.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n// 🔥 Arrays\nlet array = [3, 1, 4, 1, 5, 9];\narray.push(2); // Inserción\n//\t\t[3, 1, 4, 1, 5, 9, 2]\narray.splice(1, 1); // Borrado\n//\t\t[3, 4, 1, 5, 9, 2]\narray[0] = 8; // Actualización\n//\t\t[8, 4, 1, 5, 9, 2]\narray.sort(); // Ordenación\n//\t\t[1, 2, 4, 5, 8, 9]\nconsole.log(\"Array:\", array);\n\n// 🔥 Objetos\nlet objeto = { nombre: \"Anderson\", edad: 20 };\nobjeto.apellido = \"Mancilla\"; // Inserción\n//\t\t{nombre: 'Anderson', edad: 20, apellido: 'Mancilla'}\ndelete objeto.edad; // Borrado\n//\t\t{nombre: 'Anderson', apellido: 'Mancilla'}\nobjeto.nombre = \"Alfonso\"; // Actualización\n//\t\t{nombre: 'Alfonso', apellido: 'Mancilla'}\nconsole.log(\"Objeto:\", objeto);\n\n// 🔥 Conjuntos (Set)\nlet conjunto = new Set([1, 2, 3, 4]);\nconjunto.add(5); // Inserción\n//\t\t{1, 2, 3, 4, 5}\nconjunto.delete(2); // Borrado\n//\t\t{1, 3, 4, 5}\nconsole.log(\"Conjunto:\", conjunto);\n\n// 🔥 Mapas (Map)\nlet mapa = new Map();\nmapa.set(\"clave1\", \"valor1\"); // Inserción\n//\t\t{'clave1' => 'valor1'}\nmapa.delete(\"clave1\"); // Borrado\n//\t\t{size: 0}\nmapa.set(\"clave2\", \"valor2 actualizado\"); // Actualización\n//\t\t{'clave2' => 'valor2 actualizado'}\nconsole.log(\"Mapa:\", mapa);\n\n// 🔥 Extra: Agenda de Contactos\nconst readline = require('readline').createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nlet agenda = {};\n\nfunction mostrarMenu() {\n    console.log(\"\\n1. Buscar contacto\");\n    console.log(\"2. Insertar contacto\");\n    console.log(\"3. Actualizar contacto\");\n    console.log(\"4. Eliminar contacto\");\n    console.log(\"5. Mostrar todos los contactos\");\n    console.log(\"6. Salir\");\n}\n\nfunction buscarContacto(nombre) {\n    if (agenda[nombre]) {\n        console.log(`Contacto encontrado: ${nombre} - ${agenda[nombre]}`);\n    } else {\n        console.log(\"Contacto no encontrado.\");\n    }\n}\n\nfunction insertarContacto(nombre, telefono) {\n    if (/^\\d{1,11}$/.test(telefono)) {\n        agenda[nombre] = telefono;\n        console.log(\"Contacto insertado correctamente.\");\n    } else {\n        console.log(\"Número de teléfono no válido. Debe ser numérico y tener máximo 11 dígitos.\");\n    }\n}\n\nfunction actualizarContacto(nombre, telefono) {\n    if (agenda[nombre]) {\n        if (/^\\d{1,11}$/.test(telefono)) {\n            agenda[nombre] = telefono;\n            console.log(\"Contacto actualizado correctamente.\");\n        } else {\n            console.log(\"Número de teléfono no válido. Debe ser numérico y tener máximo 11 dígitos.\");\n        }\n    } else {\n        console.log(\"Contacto no encontrado.\");\n    }\n}\n\nfunction eliminarContacto(nombre) {\n    if (agenda[nombre]) {\n        delete agenda[nombre];\n        console.log(\"Contacto eliminado correctamente.\");\n    } else {\n        console.log(\"Contacto no encontrado.\");\n    }\n}\n\nfunction mostrarTodosLosContactos() {\n    console.log(\"\\nLista de contactos:\");\n    for (let nombre in agenda) {\n        console.log(`${nombre} - ${agenda[nombre]}`);\n    }\n}\n\nfunction iniciarAgenda() {\n    mostrarMenu();\n    readline.question(\"Seleccione una opción: \", opcion => {\n        switch (opcion) {\n            case '1':\n                readline.question(\"Nombre del contacto a buscar: \", nombre => {\n                    buscarContacto(nombre);\n                    iniciarAgenda();\n                });\n                break;\n            case '2':\n                readline.question(\"Nombre del contacto: \", nombre => {\n                    readline.question(\"Número de teléfono: \", telefono => {\n                        insertarContacto(nombre, telefono);\n                        iniciarAgenda();\n                    });\n                });\n                break;\n            case '3':\n                readline.question(\"Nombre del contacto a actualizar: \", nombre => {\n                    readline.question(\"Nuevo número de teléfono: \", telefono => {\n                        actualizarContacto(nombre, telefono);\n                        iniciarAgenda();\n                    });\n                });\n                break;\n            case '4':\n                readline.question(\"Nombre del contacto a eliminar: \", nombre => {\n                    eliminarContacto(nombre);\n                    iniciarAgenda();\n                });\n                break;\n            case '5':\n                mostrarTodosLosContactos();\n                iniciarAgenda();\n                break;\n            case '6':\n                console.log(\"Saliendo de la agenda...\");\n                readline.close();\n                break;\n            default:\n                console.log(\"Opción no válida.\");\n                iniciarAgenda();\n                break;\n        }\n    });\n}\n\niniciarAgenda();"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/agusrosero.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\n// EJERCICIO:\n// Arrays\nlet miArray = [1, 2, 3, 4, 5];\nmiArray.push(10);\nmiArray.pop();\nmiArray[0] = 23;\nmiArray.sort();\nconsole.log(miArray);\n\n// Sets\nconst miSet = new Set([1, 2, 3]);\nmiSet.add(4);\nmiSet.delete();\nconsole.log(miSet);\n\n// Objects\nconst miObjeto = {\n  x: 10,\n  y: 15,\n  z: 20,\n};\nmiObjeto.punto = 2;\ndelete miObjeto.z;\nmiObjeto[\"y\"] = 45;\nconsole.log(miObjeto);\n\n// Maps\nconst miMap = new Map([\n  [\"a\", 1],\n  [\"b\", 2],\n]);\nmiMap.set(\"c\", 3);\nmiMap.delete();\nmiMap.set(\"a\", \"a\");\nconsole.log(miMap);\n\n// DIFICULTAD EXTRA:\nconst agendaContactos = () => {\n  let agenda = new Map();\n\n  let opcion = 1;\n  let nombre = \"Hernan\";\n  let numero = 3413646464;\n  let nombre2 = \"Agustin\";\n  let numero2 = 3413646566;\n\n  console.log(`\n    1. Buscar\n    2. Insertar\n    3. Actualizar\n    4. Eliminar\n    5. Salir\n  `);\n\n  if (opcion >= 1 && opcion <= 5) {\n    switch (opcion) {\n      case 1:\n        if (nombre !== \"\" && !isNaN(numero) && numero.toString().length <= 11) {\n          agenda.set(nombre, numero);\n          console.log(agenda);\n        } else {\n          console.log(\"Error, vuelva a insertar datos validos\");\n        }\n        break;\n      case 2:\n        if (nombre !== \"\" && !isNaN(numero) && numero.toString().length <= 11) {\n          agenda.set(nombre, numero);\n        } else if (agenda.has(nombre)) {\n          console.log(`El numero de ${nombre} es: ${agenda.get(nombre)}`);\n        } else {\n          console.log(\"El contacto no esta registrado\");\n        }\n        break;\n      case 3:\n        agenda.set(nombre2, numero2);\n        console.log(`El numero de ${nombre2} es: ${agenda.get(nombre2)}`);\n        break;\n      case 4:\n        agenda.delete(nombre);\n        console.log(agenda);\n        break;\n      case 5:\n        console.log(\"Saliendo de la agenda..\");\n        break;\n      default:\n        break;\n    }\n  } else {\n    console.log(\"Error de opcion, ingrese un numero entre el 1 y el 5\");\n  }\n};\n\nagendaContactos();\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/alexdevrep.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\n// Arrays  conjunto de elementos del mismo tipo\n\nlet mi_array = [1,2,3,4,5]\n//Insertar un elemento en un array\nmi_array.push(6)\nconsole.log(mi_array)\n\n//Borrar un elemento del array \nmi_array.pop()\nconsole.log(mi_array)\n\n//Actualizar un valor de un array\nmi_array.splice(2,1,33) // Primer parámetro (2) indico la posición del número a modificar\nconsole.log(mi_array)   // Segundo parámetro (1) indico cuantos elementos quiero modificar\n                        // Tercer parámetro (33) indico el valor nuevo modificado\n//Ordenar arrays\nmi_array.sort((a,b)=> a-b) // con esa arrow function indico que me los ordene de menor a mayor\nconsole.log(mi_array)\n\n\n// Sets Colección de valores únicos donde no puede haber duplicados\nlet miSet = new Set ([1,2,3,4,5])\nconsole.log(miSet)\n//Insertar un elemento en un Set\nmiSet.add(6)\nconsole.log(miSet)\n\n//Borrar un elemento del set\nmiSet.delete(4)\nconsole.log(miSet)\n\n//Actualizar un elemento en el set\n/*No se puede cambiar el valor de un elemento pero\nsi podemos quitar y añadir como hemos visto antes*/\n\n//Ordenar sets \n/*\n *Para ordenar los elementos de un set primero lo convertimos a array \n *y luego ordenamos sus elementos como hemos hecho anteriormente \n */\n\n\n\n//Maps almacenan pares clave-valor pero con más flexibilidad que los objetos\nlet miMapa = new Map()\nmiMapa.set(\"lenguaje\",\"Javascript\")\nmiMapa.set(\"nombre\",\"alexdevrep\")\nconsole.log(miMapa)\n\n//Insertar un elemento en un Map\nmiMapa.set(\"edad\",\"24\")\nconsole.log(miMapa)\n\n//Borrar un elemento del mapa\nmiMapa.delete(\"nombre\")\nconsole.log(miMapa)\n\n//Actualizar el valor de un mapa\nmiMapa.set(\"edad\",\"30\")\nconsole.log(miMapa)\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/andresgcastillo.js",
    "content": "// Arrays\nlet miArray = [1, 2, 3, 4, 5];\nmiArray.push(6); // Inserción\nmiArray.splice(0, 1); // Borrado\nmiArray[0] = 7; // Actualización\nmiArray.sort(); // Ordenación\n\n// Sets\nlet miSet = new Set([1, 2, 3, 4, 5]);\nmiSet.add(6); // Inserción\nmiSet.delete(1); // Borrado\n// Los Sets no soportan la actualización de un elemento específico o la ordenación debido a su naturaleza\n\n// Objects\nlet miObjeto = {uno: 1, dos: 2, tres: 3};\nmiObjeto[\"cuatro\"] = 4; // Inserción\ndelete miObjeto[\"uno\"]; // Borrado\nmiObjeto[\"dos\"] = 22; // Actualización\n// Los Objects no soportan la ordenación debido a su naturaleza\n\n// Maps\nlet miMapa = new Map([\n  [\"uno\", 1],\n  [\"dos\", 2],\n  [\"tres\", 3],\n]);\nmiMapa.set(\"cuatro\", 4); // Inserción\nmiMapa.delete(\"uno\"); // Borrado\nmiMapa.set(\"dos\", 22); // Actualización\n// Los Maps no soportan la ordenación debido a su naturaleza\n\n//Dificultad Extra\n//se ejecuta con node.js\n\nconst readline = require(\"readline\");\n\nlet contactos = {};\n\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout,\n});\n\nfunction iniciarPrograma() {\n  rl.question(\"¿Qué operación quieres realizar? (buscar, insertar, actualizar, eliminar, salir): \", (operacion) => {\n    switch (operacion) {\n      case \"buscar\":\n        buscarContacto();\n        break;\n      case \"insertar\":\n        insertarContacto();\n        break;\n      case \"actualizar\":\n        actualizarContacto();\n        break;\n      case \"eliminar\":\n        eliminarContacto();\n        break;\n      case \"salir\":\n        rl.close();\n        break;\n      default:\n        console.log(\"Operación no reconocida.\");\n        iniciarPrograma();\n    }\n  });\n}\n\nfunction buscarContacto() {\n  rl.question(\"Introduce el nombre del contacto que quieres buscar: \", (nombre) => {\n    if (contactos[nombre]) {\n      console.log(`Nombre: ${nombre}, Teléfono: ${contactos[nombre]}`);\n    } else {\n      console.log(\"Contacto no encontrado.\");\n    }\n    iniciarPrograma();\n  });\n}\n\nfunction insertarContacto() {\n  rl.question(\"Introduce el nombre del nuevo contacto: \", (nombre) => {\n    rl.question(\"Introduce el número de teléfono del nuevo contacto: \", (telefono) => {\n      if (validarTelefono(telefono)) {\n        contactos[nombre] = telefono;\n        console.log(\"Contacto insertado correctamente.\");\n      } else {\n        console.log(\"Número de teléfono no válido.\");\n      }\n      iniciarPrograma();\n    });\n  });\n}\n\nfunction actualizarContacto() {\n  rl.question(\"Introduce el nombre del contacto que quieres actualizar: \", (nombre) => {\n    if (contactos[nombre]) {\n      rl.question(\"Introduce el nuevo número de teléfono: \", (telefono) => {\n        if (validarTelefono(telefono)) {\n          contactos[nombre] = telefono;\n          console.log(\"Contacto actualizado correctamente.\");\n        } else {\n          console.log(\"Número de teléfono no válido.\");\n        }\n      });\n    } else {\n      console.log(\"Contacto no encontrado.\");\n    }\n    iniciarPrograma();\n  });\n}\n\nfunction eliminarContacto() {\n  rl.question(\"Introduce el nombre del contacto que quieres eliminar: \", (nombre) => {\n    if (contactos[nombre]) {\n      delete contactos[nombre];\n      console.log(\"Contacto eliminado correctamente.\");\n    } else {\n      console.log(\"Contacto no encontrado.\");\n    }\n    iniciarPrograma();\n  });\n}\n\nfunction validarTelefono(telefono) {\n  const regex = /^\\d{1,11}$/;\n  return regex.test(telefono);\n}\n\niniciarPrograma();\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/andyfg0289.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\n//Ejercicio:\n\n//----Arreglos (Arrays) ----//\n\nlet arreglo = [\"rojo\", \"azul\", \"amarillo\"];\n\n//insersión\n\narreglo.push(\"verde\");\nconsole.log(arreglo); //Array(4) [ \"rojo\", \"verde\", \"amarillo\", \"verde\" ]\n\n//Borrado\narreglo.splice(3, 1);\nconsole.log(arreglo); //Array(3) [ \"rojo\", \"azul\", \"amarillo\" ]\n\n//Actualización\n\narreglo[0] = \"verde\";\nconsole.log(arreglo); //Array(3) [ \"verde\", \"azul\", \"amarillo\" ]\n\n//Ordenación\nlet numeros = [6, 3, 8, 21, 42, 11, 20];\n\nnumeros.sort((a, b) => a - b);\n\nconsole.log(numeros); //Array(7) [ 3, 6, 8, 11, 20, 21, 42 ]\n\n//---- Objetos ----//\n\nlet miObjeto = {\n  nombre: \"Andy\",\n  apellido: \"Fernandez\",\n  edad: 30,\n};\n\nconsole.log(miObjeto);\n\n//insersión\n\nmiObjeto.direccion = \"La direccion\";\n\nconsole.log(miObjeto);\n\n//Borrado\ndelete miObjeto.direccion;\nconsole.log(miObjeto);\n\n//Actualización\nmiObjeto.edad = 35;\n//Ordenación\n\nlet listaD = { d: 4, c: 3, a: 1, b: 2 };\n\nlet keysOrdenadas = Object.keys(listaD).sort();\nconsole.log(\"LLaves ordenadas\", keysOrdenadas); //Array(4) [ \"a\", \"b\", \"c\", \"d\" ]\n\nlet objetoOrdenado = {};\nkeysOrdenadas.forEach((key) => (objetoOrdenado[key] = listaD[key]));\nconsole.log(objetoOrdenado); //Object { a: 1, b: 2, c: 3, d: 4 }\n\n//---- Sets ----//\n\nlet MiSet = new Set([1, 2, 3]);\n\n//insersión\nMiSet.add(4);\nconsole.log(MiSet); //Set(4) [ 1, 2, 3, 4 ]\n\n//Borrado\nMiSet.delete(2);\nconsole.log(MiSet); //Set(3) [ 1, 3, 4 ]\n\n//Actualización\nif (MiSet.has(1)) {\n  MiSet.delete(1);\n  MiSet.add(10);\n}\nconsole.log(MiSet); //Set(3) [ 3, 4, 10 ]\n\n//Ordenación\n\nlet SetDes = new Set([7, 2, 4, 3, 1, 5, 6]);\n\nlet ordenado = Array.from(SetDes).sort((a, b) => a - b);\nconsole.log(ordenado); //Array(7) [ 1, 2, 3, 4, 5, 6, 7 ]\n\n//----  WeakSets ----//  WeakSet solo permite almacenar objetos y no admite ordenación directa.\n\nlet weakSet = new WeakSet();\nlet obj1 = { a: 1 };\nlet obj2 = { b: 2 };\nlet obj3 = { c: 3 };\n//insersión\nweakSet.add(obj1);\nweakSet.add(obj2);\nweakSet.add(obj3);\n\nconsole.log(weakSet);\n//Borrado\n\nweakSet.delete(obj1);\nconsole.log(weakSet);\n// Actualización (no aplica en WeakSet)\n\n// Ordenación (no aplica en WeakS\n\n//---- Mapas o (Map) ----//\n\nlet map = new Map();\nmap.set(\"a\", 1);\nmap.set(\"b\", 2);\n\n//insersión\nmap.set(\"c\", 3);\nconsole.log(map);\n//Borrado\nmap.delete(\"b\");\nconsole.log(map);\n//Actualización\n\nmap.set(\"a\", 10);\nconsole.log(map);\n//Ordenación\nlet mapOrdenado = new Map([...map].sort((a, b) => a[1] - b[1]));\nconsole.log(mapOrdenado);\n\n//usando array from\nlet mapOrdenado2 = new Map(\n  Array.from(map.entries()).sort((a, b) => a[1] - b[1])\n);\n\n//DIFICULTAD EXTRA (opcional):\n/* Ejecutar en un navegador dado que no use linebyline para usarlo en cualquiuer consola con node\n -Se puede usar con el prompt o simplemente mediante los \"COMANDOS\" por la consola\n - Usar init() para iniciar el programa.\n */\nconsole.log(`#     #            #                         \n  ##   ## #         # #    ####  ###### #    # #####    ## \n  # # # # #        #   #  #    # #      ##   # #    #  #  #  \n  #  #  # # ##### #     # #      #####  # #  # #    # #    # \n  #     # #       ####### #  ### #      #  # # #    # ###### \n  #     # #       #     # #    # #      #   ## #    # #    # \n  #     # #       #     #  ####  ###### #    # #####  #    #\\n\\ninit() --> PAra iniciar Agenda \\nhelp() --> Ayuda\"`);\n\nlet contactos = [\n  { id: 1, nombre: \"Juan Pérez\", telefono: 123456789032 },\n  { id: 2, nombre: \"María García\", telefono: 987654321074 },\n  { id: 3, nombre: \"Luis Rodríguez\", telefono: 555123456735 },\n  { id: 4, nombre: \"Ana López\", telefono: 777888999944 },\n  { id: 5, nombre: \"Carlos Fernández\", telefono: 444555666622 },\n];\n\nlet miagenda;\n\nconst help = () => {\n  const ayuda = [\n    {\n      comando: \"init()\",\n      accion: \"Inicializar Agenda\",\n    },\n    {\n      comando: \"miagenda.listar()\",\n      accion: \"Muestra el listado de contactos\",\n    },\n    {\n      comando: \"miagenda.actualizar()\",\n      accion: \"Actualiza un contacto mediante la ID \",\n    },\n    {\n      comando: \"miagenda.agregar()\",\n      accion: \"Agrega un contacto nuevo\",\n    },\n    {\n      comando: \"miagenda.eliminar()\",\n      accion: \"Elimina un contacto mediante la ID \",\n    },\n    {\n      comando: \"miagenda.buscar()\",\n      accion: \"Buscar contacto\",\n    },\n    {\n      comando: \"miagenda.salir()\",\n      accion: \"Finaliza la Agenda\",\n    },\n  ];\n\n  console.table(ayuda);\n};\n\nclass Agenda {\n  constructor(contactos) {\n    this.contactos = contactos;\n    help();\n  }\n}\n\nclass miAgenda extends Agenda {\n  mensage = (mensaje, color, fondo) => {\n    console.log(\n      `%c${mensaje}`,\n      `background-color:${fondo};color:${color};padding: 5px 10px;`\n    );\n  };\n  listar = () => {\n    this.contactos.length == 0\n      ? console.log(\"No hay contactos para mostrar\")\n      : console.table(this.contactos);\n\n    inicio();\n  };\n\n  actualizar = () => {\n    const secId = verfId(this.contactos);\n    let id = 0;\n\n    for (let i = 0; i < this.contactos.length; i++) {\n      if (this.contactos[i].id === secId) {\n        id = i;\n        break;\n      }\n    }\n\n    if (secId !== null) {\n      const name = prompt(\"Actualizar nombre\", this.contactos[id].nombre);\n\n      if (name === null || name.trim() === \"\") {\n        this.mensage(\"No se puede dejar el nombre vacío\", \"white\", \"red\");\n        inicio();\n        return;\n      }\n\n      let telefono = prompt(\"Actualizar Teléfono\", this.contactos[id].telefono);\n      telefono = Number(telefono);\n      if (!Number.isInteger(telefono) || telefono.toString().length > 11) {\n        this.mensage(\n          \"Debe introducir un numero de teléfono de 11 digítos\",\n          \"white\",\n          \"red\"\n        );\n        inicio();\n        return;\n      }\n\n      this.contactos[id].nombre = name.toString();\n      this.contactos[id].telefono = telefono;\n      this.listar();\n      inicio();\n    }\n  };\n  agregar = () => {\n    const secId =\n      this.contactos.length > 0\n        ? this.contactos[this.contactos.length - 1].id + 1\n        : 0;\n\n    const name = prompt(\"Nombre: \");\n\n    if (name === null || name.trim() === \"\") {\n      this.mensage(\"No se puede dejar el nombre vacío.\", \"white\", \"red\");\n      inicio();\n      return;\n    }\n\n    let telefono = prompt(\"Telefono: \");\n    telefono = Number(telefono);\n    if (!Number.isInteger(telefono) || telefono.toString().length > 11) {\n      this.mensage(\n        \"Debe introducir un numero de telefono de 11 digitos como monimo \",\n        \"white\",\n        \"red\"\n      );\n      inicio();\n      return;\n    }\n\n    const nuevoContacto = {\n      id: secId,\n      nombre: name,\n      telefono: telefono,\n    };\n\n    this.contactos.push(nuevoContacto);\n    this.mensage(\"Nuevo contacto agregado\", \"white\", \"green\");\n    this.listar();\n    inicio();\n  };\n\n  eliminar = () => {\n    const secId = verfId(this.contactos);\n    console.log(secId);\n    if (secId !== null) {\n      this.mensage(\"Contacto Eliminado \", \"white\", \"red\");\n      const del = this.contactos.filter((contacto) => contacto.id !== secId);\n\n      this.contactos = del;\n      this.listar();\n      inicio();\n    }\n  };\n\n  buscar = () => {\n    const input = prompt(\"Buscar en la agenda\");\n    const textRegex = new RegExp(/^[a-zA-Z\\s]+$/);\n    const numRegex = new RegExp(/^[0-9\\s]+$/);\n    const textNumRegex = new RegExp(/^(?=.*[a-zA-Z])(?=.*\\d).+$/);\n    let searchResult = [];\n\n    if (input === null || input.trim() === \"\") {\n      this.mensage(\"No se puede dejar el nombre vacío.\", \"white\", \"red\");\n      inicio();\n      return;\n    }\n\n    if (textRegex.test(input)) {\n      function eliminarAcentos(texto) {\n        return texto.normalize(\"NFD\").replace(/[\\u0300-\\u036f]/g, \"\");\n      }\n\n      function eliminarAcentosYEspacios(texto) {\n        return eliminarAcentos(texto).replace(/\\s+/g, \"\").toLowerCase();\n      }\n      const palabrasInput = eliminarAcentos(input).toLowerCase().split(/\\s+/);\n\n      for (let i = 0; i < this.contactos.length; i++) {\n        const nombreContacto = eliminarAcentosYEspacios(\n          this.contactos[i].nombre\n        );\n        for (let j = 0; j < palabrasInput.length; j++) {\n          const regex = new RegExp(palabrasInput[j], \"i\");\n\n          if (regex.test(nombreContacto)) {\n            searchResult.push(this.contactos[i]);\n            break;\n          }\n        }\n      }\n\n      if (searchResult.length == 0) {\n        miagenda.mensage(\"No se encontro el contacto\", \"white\", \"red\");\n        inicio();\n        return;\n      }\n\n      console.table(searchResult);\n    }\n\n    if (numRegex.test(input)) {\n      let telefono = input;\n      telefono = Number(telefono);\n\n      for (let i = 0; i < this.contactos.length; i++) {\n        if (\n          this.contactos[i].telefono.toString().includes(telefono.toString())\n        ) {\n          searchResult.push(this.contactos[i]);\n        }\n      }\n\n      if (searchResult.length == 0) {\n        miagenda.mensage(\"No se encontro el contacto\", \"white\", \"red\");\n        inicio();\n        return;\n      }\n      console.table(searchResult);\n    }\n\n    if (textNumRegex.test(input)) {\n      miagenda.mensage(\n        \"Introduzca una palabra clave o un numero telefononico correctos\",\n        \"white\",\n        \"red\"\n      );\n      return;\n    }\n    console.log(\"Resultado de buscar:\", input);\n    inicio();\n  };\n\n  salir = () => {\n    console.clear();\n    miagenda = null;\n    console.log(\"%cPrograma finalizado.\", \"color: red\");\n  };\n}\n\nconst verfId = (lista) => {\n  const id = prompt(\"Introduzca ID del contacto\", \"#id\");\n  let secId = Number(id);\n  if (id === \"\") {\n    miagenda.mensage(\n      \"Proporcione una id valida: No puede estar vacia\",\n      \"white\",\n      \"red\"\n    );\n    inicio();\n    return (secId = null);\n  }\n\n  if (!Number.isInteger(secId) || secId === \"\") {\n    miagenda.mensage(\n      \"Proporcione una id valida: debe ser un número entero\",\n      \"white\",\n      \"red\"\n    );\n    inicio();\n    return (secId = null);\n  }\n\n  if (secId < 0) {\n    console.log(lista[0]);\n    miagenda.mensage(\n      \"Proporcione una id valida: Use listar() --> Mostrar contactos\",\n      \"white\",\n      \"red\"\n    );\n    inicio();\n    return (secId = null);\n  }\n\n  for (let i = 0; i < lista.length; i++) {\n    if (lista[i].id === secId) {\n      return secId;\n    }\n  }\n\n  miagenda.mensage(\n    \"El id proporcionado no existe en los contactos\",\n    \"white\",\n    \"red\"\n  );\n  inicio();\n  return (secId = null);\n};\n\nconst init = () => {\n  console.log(\n    \"%cAgenda Iniciada\",\n    \"color: white ; background-color:green;padding: 5px 10px;\"\n  );\n  miagenda = new miAgenda(contactos);\n  inicio();\n};\n\nconst inicio = () => {\n  const opcion = prompt(\n    \"(1: LIST - 2: UPDATE - 3: ADD - 4: DEL - 5: FIND - 6: QUIT)\"\n  );\n\n  switch (opcion) {\n    case \"1\":\n      console.log(\"Hola mundo\");\n      miagenda.listar();\n      break;\n\n    case \"2\":\n      miagenda.actualizar();\n      break;\n\n    case \"3\":\n      miagenda.agregar();\n      break;\n\n    case \"4\":\n      miagenda.eliminar();\n      break;\n\n    case \"5\":\n      miagenda.buscar();\n      break;\n\n    case \"6\":\n      miagenda.salir();\n      break;\n\n    default:\n      // miagenda.salir();\n      break;\n  }\n};\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/angelurrutdev.js",
    "content": "//  Estructuras\n\n// ************** Arreglos (Arrays) ***************\nconst autos = [\"Toyota\", \"Fiat\", \"Mclaren\"]; //Creación de arreglo\nconsole.log(Object.keys(autos)); \n\nconsole.log(autos.length); // 3\nconsole.log(autos[0]); // Toyota\nconsole.log(autos[1]); //   Fiat\nconsole.log(autos[2]); //   Mclaren\n\nlet first = autos[0]; // Toyota\n\nlet end = autos[autos.length - 1]; // Numero de elementos menos 1, y el resultado lo toma como la posición del indice\nconsole.log(end)\n\n\n\nlet Agregar = autos.push(\"Honda\", \"Ford\"); //Inserción de elemento al array\nconsole.log(autos);\n\nlet Eliminar = autos.pop(); //Borrar el último elemento del array\nconsole.log(autos);\n\nautos.sort(); //Ordenamiento de elementos\nconsole.log(autos)\n\n// ******************** Objetos (Object) **********************\n\nconst celular = {\n    procesador: \"SnapDragon\",\n    RAM: \"4GB\",\n    pantalla: \"6.5 pulgadas\",\n    camara: \"12 MP\",\n    bateria: \"5000 mAh\"\n}; //Creación de Objeto\n\nconsole.log(celular);\nconsole.log(celular.pantalla); //Imprime la pantalla\nconsole.log(celular.RAM); //Imprime la RAM\n\ncelular.camara = \"Generico\"; // Actualización de propiedad\ncelular[\"bateria\"] = \"Yuca\"; // De esta forma también es posible acceder a una propiedad\nconsole.log(celular);\n\ndelete celular.Yuca; //Eliminar propiedad\nconsole.log(computadora);\n\n\n//Función constructora de un Objeto e instancias de objetos\nfunction Car(make, model, year) {\n    this.make = make;\n    this.model = model;\n    this.year = year;\n}\nvar mycar = new Car(\"Eagle\", \"Talon TSi\", 1993);\nconsole.log(mycar); //Car { make: 'Eagle', model: 'Talon TSi', year: 1993 }\n\nfunction Person(name, age, sex) {\n    this.name = name;\n    this.age = age;\n    this.sex = sex;\n}\n\nvar rand = new Person(\"Rand McKinnon\", 33, \"M\");\nvar ken = new Person(\"Ken Jones\", 39, \"M\");\n\nfunction Car(make, model, year, owner) {\n    this.make = make;\n    this.model = model;\n    this.year = year;\n    this.owner = owner;\n}\n\nvar car1 = new Car(\"Eagle\", \"Talon TSi\", 1993, rand);\nvar car2 = new Car(\"Nissan\", \"300ZX\", 1992, ken);\n\nconsole.log(car2);\n\n\n\n//****************** Set ******************\n\nconst setCreator = new Set([1, 2, 3, 4, 5]); //Cración de constructor Set\n\n// Has devuelve si un elemento pertenece o no al set\nconsole.log(setCreator.has(1)); //true\nconsole.log(setCreator.has(5)); //true\nconsole.log(setCreator.has(8)); //false\n\nsetCreator.add(\"Texto Libre\"); //Agregar elemento a un set\nconst objectSet = {\n    nombre: \"JavaScript\",\n    version: \"ECMAScript 6\"\n}\nsetCreator.add(10).add(\"Otro texto\");\nsetCreator.add(objectSet); //Agregar elemento a un set\nconsole.log(setCreator);\n\nconsole.log(setCreator.size); //Retorno del tamaño del set\n\n\n//Elimina un elemento existente del objeto set (Devuelve True refiriendose a que \"El elemento fue eliminado exitosamente\")\nconsole.log(setCreator.delete(1));\n\nsetCreator.clear(); //Eliminar todos los elementos dentro del objeto set\nconsole.log(setCreator.size);\nconsole.log(setCreator);\n\n\n\n// ***************** WeakSet ******************\n\n//A un WeakSet solo es posible pasarle objetos.\nconst wk = new WeakSet; //Creación de constructor WeakSet\nconst wkOne = {};\nconst wkTwo = {};\n\nwk.add(wkOne); //Agregar objeto al WeakSet\nwk.add(wkTwo);\n\nwk.has(wkOne); //Valida si existe dentro del WeakSet o no\nwk.has(wkTwo);\n\nwk.delete(wkOne); //Eliminación del objeto (Devuelve True \"Fue eliminado exitosamente\")\nconsole.log(wk.has(wkOne));\n\n\n// ****************** Map ****************\n\n//Creación del constructor Map\nconst myMap = new Map([\n    [\"Trampa\", \"Sombreros Mágicos\"],\n    [\"Monstruo\", \"Mago Oscuro\"],\n    [\"Especial\", \"Exodia\"],\n    [\"Magica\", \"Espadas de luz reveladora\"],\n    [1000, \"Vida Actual\"]\n]);\n\nmyMap.set(\"Dios Egipcio\", \"Obelisco el atormetador\"); //Agregar un elemento Key-Value\nconsole.log(myMap.delete(\"Trampa\")); //Eliminar un elemento Key-Value\nconsole.log(myMap.get(\"Magica\")); //Obtienes el Value asociado al Key\nconsole.log(myMap.size); //Verificar tamaño de Map\nconsole.log(myMap.get(\"Especial\"));\n\n\n/* \nDIFICULTAD EXTRA\n*/\n\n\nfunction panelPrincipal() {\n    const listContact = new Map([[\"Daniel\", \"29293018309\"]]);\n\n    var is_on = true;\n    while (is_on) {\n\n        alert(\"Agenda de contactos\");\n\n        let numberOption = prompt(\n            `Selecciona la opción de tu preferencia: \n        0: Ver lista de contactos.\n        1: Buscar un contacto.\n        2: Agregar un nuevo contacto. \n        3: Actualizar un contacto.\n        4: Eliminar un contacto.\n        5: Salir.`\n        );\n\n        let name = null;\n        let phone = null;\n\n        switch (numberOption) {\n            case \"0\":\n                for (let [key, value] of listContact) {\n                    alert(`Nombre: ${key}, Teléfono: ${value}`);\n                }\n                break;\n            case \"1\":\n                name = prompt(`Introduce el nombre del contacto que buscas`);\n                if (listContact.has(name)) {\n                    let phoneNumber = listContact.get(name);\n                    alert(`El contacto ${name} tiene asignado el número ${phoneNumber}`)\n                } else {\n                    alert(`El contacto ${name} no existe.`);\n                }\n                break;\n            case \"2\":\n                name = prompt(`Escribe el nombre del nuevo contacto`);\n                phone = parseInt(prompt(`Escribe el número del nuevo contacto`));\n                if (/^\\d{10,11}$/.test(phone)) {\n                    listContact.set(name, phone);\n                    alert(`El contacto ${name} fue agregado con éxito`);\n                } else {\n                    alert(\"Debes introducir un número de télefono de 10 u 11 dígitos\")\n                }\n                break;\n            case \"3\":\n                name = prompt(`Introduce el nombre del contacto que deseas actualizar.`);\n                if (listContact.has(name)) {\n                    phone = parseInt(prompt(`Escriba el nuevo número del contacto ${name}`));\n                    if (/^\\d{10,11}$/.test(phone)) {\n                        listContact.set(name, phone);\n                        alert(`El contacto ${name} fue actualizado`);\n                    } else {\n                        alert(`No se pudo actualizar al contacto ${name}, favor de verificar el número de teléfono, este debe contener de 10 a 11 dígitos.`)\n                    }\n                }\n                break;\n            case \"4\":\n                name = prompt(`Introduce el nombre del contacto que deseas eliminar`);\n                if (listContact.has(name)) {\n                    listContact.delete(name);\n                    alert(`Contacto eliminado exitosamente`)\n                } else {\n                    alert(`El contacto ${name} no existe.`);\n                }\n                break;\n            case \"5\":\n                alert(\"Saliendo de la agenda.\")\n                is_on = false;\n                break;\n            default:\n                alert(\"Selección incorrecta, selecciona una opción del 0 al 5.\")\n                break;\n        }\n    }\n}\npanelPrincipal();\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/ant000o.js",
    "content": "//  * EJERCICIO:\n//  * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n//  * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n\n// Arrays\nconst estudiantes = [\"ant000o\", \"7R0N1X\", \"dieswae\"];\nestudiantes.push(\"Reaien\"); // Inserción\nconsole.log(estudiantes); \nestudiantes.splice(2, 1, \"C-BLSKV\", \"d4-n1\"); // Borrado/Inserción (usando splice). En la posición 2, borra 1 item, agrega \"C-BLSKV\" y \"d4-n1\".\nconsole.log(estudiantes);\nestudiantes.pop(); // Borrado (usando pop, borra el último del array)\nconsole.log(estudiantes);\nestudiantes[2] = \"TofeDev\"; // Actualización\nconsole.log(estudiantes);\nestudiantes.sort(); // Ordenación\nconsole.log(estudiantes);\n\n\nconsole.log(\"---------------------------------------------------------------\")\n\n\n// Objects\nlet perro = {\n    raza: \"Shiba Inu\", \n    edad: \"2 años\", \n    nombre: \"Moonie\"\n}\nperro.sexo = \"Hembra\"; // Inserción\nperro.color = \"Blanco\"\nconsole.log(perro);\ndelete perro.color; // Borrado\nconsole.log(perro);\nObject.defineProperty(perro, \"edad\", {value: \"18 meses\"}); // Actualización\nconsole.log(perro);\n// No se puede ordenar un Object, para ordenarlo hay que convertir valores en array. --Se omitirá por ahora--\n\n\nconsole.log(\"---------------------------------------------------------------\")\n\n// Maps\nlet autos = new Map(); // map creado vacío\nautos.set(\"Kia\", 600); // Inserción\nautos.set(\"Toyota\", 200);\nautos.set(\"Lamborghini\", 350);\nconsole.log(autos);\nconsole.log(\"---------------------------------------------------------------\")\nautos.set(\"frutas\",[   // Inserción de un Array (map acepta cualquier tipo de dato).\n    [\"uva\", 20],\n    [\"piña\", 15],\n    [\"kiwi\", 10],\n]);\nconsole.log(autos.get(\"frutas\"));\nconsole.log(\"---------------------------------------------------------------\")\nautos.get(\"frutas\").push([\"mango\", 7]);  // Inserción al Array dentro del Map\nconsole.log(autos);\nconsole.log(\"---------------------------------------------------------------\")\nautos.delete(\"frutas\"); // Borrado\nconsole.log(autos);\nconsole.log(\"---------------------------------------------------------------\")\nautos.set(\"Kia\", 40); // Actualizado\nconsole.log(autos);\n// Para ordenarlo hay que convertir valores en array. --Se omitirá por ahora--\n\n\nconsole.log(\"---------------------------------------------------------------\")\n\n\n// Set\nlet letras = new Set([\"h\", \"o\", \"l\", \"a\"]);\nletras.add(\"d\"); // Inserción\nconsole.log(letras);\nletras.delete(\"d\"); // Borrado\nconsole.log(letras);\n// Actualizado como tal no existe, habría que borrar uno y crear uno nuevo.\nlet palabra = \"\";   // Listar  los elementos, se puede hacer con un for...of.\nfor (const x of letras){\n    palabra += x\n}\nconsole.log(palabra);\n\n\nconsole.log(\"---------------------------------------------------------------\");\nconsole.log(\"---------------------------------------------------------------\");\nconsole.log(\"---------------------------------------------------------------\");\nconsole.log(\"---------------------------------------------------------------\");\n//  * DIFICULTAD EXTRA (opcional):\n//  * Crea una agenda de contactos por terminal.\n//  * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n//  * - Cada contacto debe tener un nombre y un número de teléfono.\n//  * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n//  *   los datos necesarios para llevarla a cabo.\n//  * - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n//  *   (o el número de dígitos que quieras)\n//  * - También se debe proponer una operación de finalización del programa.\n\nconst readline = require('readline');\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nlet contactos = new Map();\ncontactos.set(\"Joaquin\", \"56923467680\");\ncontactos.set(\"Alonso\", \"56986749614\");\ncontactos.set(\"Ignacio\", \"56973960467\");\ncontactos.set(\"Josefa\", \"56934684569\");\n\n\nfunction menu(){\n    console.log(\n            \"--- MENÚ PRINCIPAL ---\\n\" +\n            \"1. Buscar contacto\\n\" +\n            \"2. Añadir nuevo contacto\\n\" +\n            \"3. Editar un contacto\\n\" +\n            \"4. Eliminar un contacto\\n\" +\n            \"0. Salir\"\n        );\n        rl.question(\"\\nSelecciona una opción: \", (opcion) => {\n        switch(opcion){\n            case \"1\":\n                console.log(\"\\nBuscar contacto\");\n                buscarContact();\n            break;\n            case \"2\": \n                console.log(\"\\nAñadir contacto\")\n                addContact();\n            break;\n            case \"3\":\n                console.log(\"\\nEditar contacto\")\n                editContact();\n            break;\n            case \"4\":\n                console.log(\"\\nEliminar contacto\")\n                deleteContact();\n            break;\n            case \"0\":\n                rl.close();\n            break;\n            default:\n                console.log(\"Error\");\n                menu();\n        }\n        });\n}\nmenu();\n\nfunction buscarContact(){\n    rl.question(\"\\nNombre del contacto: \", (nombre) => {\n        if (contactos.has(nombre)){\n            const value = contactos.get(nombre);\n            console.log(`${nombre} - ${value}`);\n        }else{\n            console.log(\"Contacto no existente\")\n            buscarContact();\n        }\n        rl.question('\\n1. Buscar otro contacto\\n0. Volver al menú\\n', (opcion) => {\n            if (opcion === \"1\"){\n                buscarContact();\n            }else{\n                menu();\n            }\n        });\n    });\n}\n\n\nfunction addContact(){\n    rl.question(\"\\nNúmero: \", (numero) => {\n        if (numero.length <= 11 && !isNaN(numero)){\n            rl.question('\\nNombre: ', (nombre) => {\n                contactos.set(nombre, numero);\n                console.log(`Se agregó a ${nombre}`)\n                rl.question('\\n1. Añadir otro contacto\\n0. Volver al menú\\n', (opcion) => {\n                    if (opcion === \"1\"){\n                        addContact();\n                    }else{\n                        menu();\n                    }\n                });\n            });\n        }else{\n            console.log(\"Número no válido, intente otra vez\");\n            addContact();\n        }\n    });\n}\n\nfunction editContact(){\n    for (const [key, value] of contactos){\n    console.log(key, value);\n};\n    rl.question(\"\\nNombre del contacto a editar: \", (nombre) => {\n        if (contactos.has(nombre)){\n            rl.question(\"\\n¿Qué quieres editar?\\n1. Nombre\\n2. Número\\n\", (opcion) => {\n                if (opcion === \"1\"){\n                    rl.question(\"\\nNuevo nombre: \", (newName) => {\n                        const newNombre = newName; \n                        const numActual = contactos.get(nombre);\n                        contactos.delete(nombre);\n                        contactos.set(newNombre, numActual);\n                        console.log(\"Contacto editado con exito.\")\n                        rl.question('\\n1. Editar otro contacto\\n0. Volver al menú\\n', (opcion) => {\n                            if (opcion === \"1\"){\n                                editContact();\n                            }else{\n                                menu();\n                            }\n                        });\n                    });\n                }else if (opcion === \"2\"){\n                    rl.question(\"Nuevo número: \", (newNum) => {\n                        if (newNum.length <= 11 && !isNaN(newNum)){\n                            const newNumero = newNum;\n                            contactos.set(nombre, newNumero);\n                        console.log(\"Contacto editado con exito.\")\n                        }else{\n                            console.log(\"Número no válido, intente otra vez\");\n                            editContact();\n                        }\n                        rl.question('\\n1. Editar otro contacto\\n0. Volver al menú\\n', (opcion) => {\n                            if (opcion === \"1\"){\n                                editContact();\n                            }else{\n                                menu();\n                            }\n                        });\n                    });\n                }else{\n                    console.log(\"Opción inválida\");\n                    editContact();\n                }\n            });\n        }else{\n            console.log(\"Contacto no existente\")\n            editContact();\n        }\n    });\n}\n\n\nfunction deleteContact(){\n    for (const [key, value] of contactos){\n    console.log(key, value);\n};\n    rl.question(\"\\nNombre del contacto a eliminar: \", (nombre) => {\n        if (contactos.has(nombre)){\n            contactos.delete(nombre);    \n            console.log(`Se eliminó a ${nombre}`)\n            rl.question('\\n1. Eliminar otro contacto\\n0. Volver al menú\\n', (opcion) => {\n                    if (opcion === \"1\"){\n                        deleteContact();\n                    }else{\n                        menu();\n                    }\n                });\n        }else{\n            console.log(\"Contacto no existente\")\n            deleteContact();\n        }\n    });\n}\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/bernatcs.js",
    "content": "// ** -1-\n\n// * Estructuras de Datos\n\nlet number = 8\nnumber = 8.8\nnumber = NaN\n\nlet string = 'ocho'\n\nlet boolean = true\nboolean = false\n\nlet nullNull = null\n\nlet undefined\n\nlet symbol = Symbol(\"foo\")\n\nlet object = {\n    Nombre: 'Bernat',\n    Apellido: 'Cucarella'\n}\n\nlet array = [1, 2, 3, 4, 5, 6, 7, 8]\n\nfunction funcion(){\n}\n\nlet fecha = new Date\n\n// * Estructuras de Control\n\nif (number === 8){\n\n} else if (number > 8){\n\n} else {\n\n}\n\nswitch (number) {\n    case 8:\n        \n        break;\n\n    default:\n        break;\n}\n\nfor (index = 0; index < 8; index++) {\n}\n\nfor (const key in object) {\n    if (Object.hasOwnProperty.call(object, key)) {\n        const element = object[key];\n        \n    }\n}\n\ndo {\n    \n} while (index < 8);\n\ntry { \n    \n} catch (error) {\n    \n}\n\n// ** EXTRA (simple) ** -----------------------------------------------------------------------------------------------------------------------------------------------\n\nconst agendaContactos = [\n    {\n        Nombre: 'Bernat',\n        Numero: '674863572'\n    }\n];\n\n// Inserción\n\nfunction compruebaNumero(nuevoNumero) {\n    if (String(nuevoNumero).length === 9) {\n        return parseInt(nuevoNumero, 10);\n    }\n    console.error(\"El formato del número no es correcto\");\n    return undefined;\n}\n\nfunction nuevoContacto(nuevoNombre, nuevoNumero) {\n    let numeroValidado = compruebaNumero(nuevoNumero);\n    if (numeroValidado) {\n        let nuevoContacto = {\n            Nombre: nuevoNombre,\n            Numero: numeroValidado\n        };\n        agendaContactos.push(nuevoContacto);\n        console.log(`El contacto ${nuevoNombre} ha sido añadido con éxito`);\n    } else {\n        console.error(`No se pudo añadir el contacto ${nuevoNombre} debido a un número inválido.`);\n    }\n}\n\n// Busqueda\n\nfunction buscarNúmero(buscarNombre) {\n    for (let index = 0; index < agendaContactos.length; index++) {\n        if (agendaContactos[index].Nombre === buscarNombre) {\n            console.log(`El número del contacto ${agendaContactos[index].Nombre} es: ${agendaContactos[index].Numero}`);\n            return; \n        } \n    }\n    console.error('Este contacto no existe');\n}\n\n// Actualización\n\nfunction actualizarNumero(buscarNombre, nuevoNumero) {\n    for (let index = 0; index < agendaContactos.length; index++) {\n        if (agendaContactos[index].Nombre == buscarNombre) {\n            agendaContactos[index].Numero = compruebaNumero(nuevoNumero)\n            console.log(`El contacto ${agendaContactos[index].Nombre} ha sido actualizado con éxito`)\n            return; \n        } \n    }\n    console.error('Este contacto no existe');\n}\n\n\nfunction actualizarNombre(buscarNombre, nuevoNombre) {\n    for (let index = 0; index < agendaContactos.length; index++) {\n        if (agendaContactos[index].Nombre == buscarNombre) {\n            agendaContactos[index].Nombre = nuevoNombre\n            console.log(`El contacto ${agendaContactos[index].Nombre} ha sido actualizado con éxito`)\n            return; \n        } \n    }\n    console.error('Este contacto no existe');\n}\n\n// Eliminación de contactos\n\nfunction eliminarContacto(buscarNombre) {\n    for (let index = 0; index < agendaContactos.length; index++) {\n        if (agendaContactos[index].Nombre == buscarNombre) {\n            console.log(`El contacto ${agendaContactos[index].Nombre} ha sido borrado con éxito`)\n            agendaContactos.splice(index, 1)\n            return; \n        } \n    }\n    console.error('Este contacto no existe');\n}\n\n// ** EXTRA ** -----------------------------------------------------------------------------------------------------------------------------------------------\n\nconst readline = require('readline').createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nfunction listinTelefonico(){\n    readline.question('¿Qué quiere hacer? Elija entre [búsqueda], [inserción], [actualización] y [eliminación] y escriba el comando a continuación: ', (respuesta) => {\n        switch (respuesta.toLowerCase()) {\n            case 'búsqueda':\n                readline.question('Ingrese el nombre del contacto que desea buscar: ', (nombre) => {\n                    buscarNúmero(nombre);\n                    listinTelefonico();\n                });\n                break;\n            case 'inserción':\n                readline.question('Ingrese el nombre del nuevo contacto: ', (nombre) => {\n                    readline.question('Ingrese el número del nuevo contacto: ', (numero) => {\n                        nuevoContacto(nombre, numero);\n                        listinTelefonico();\n                    });\n                });\n                break;\n            case 'actualización':\n                readline.question('¿Desea actualizar el [nombre] o el [número]?: ', (tipoActualizacion) => {\n                    if (tipoActualizacion.toLowerCase() === 'nombre') {\n                        readline.question('Ingrese el nombre del contacto a actualizar: ', (nombre) => {\n                            readline.question('Ingrese el nuevo nombre: ', (nuevoNombre) => {\n                                actualizarNombre(nombre, nuevoNombre);\n                                listinTelefonico();\n                            });\n                        });\n                    } else if (tipoActualizacion.toLowerCase() === 'número') {\n                        readline.question('Ingrese el nombre del contacto a actualizar: ', (nombre) => {\n                            readline.question('Ingrese el nuevo número: ', (nuevoNumero) => {\n                                actualizarNumero(nombre, nuevoNumero);\n                                listinTelefonico();\n                            });\n                        });\n                    } else {\n                        console.error('Opción no reconocida');\n                        listinTelefonico();\n                    }\n                });\n                break;\n            case 'eliminación':\n                readline.question('Ingrese el nombre del contacto que desea eliminar: ', (nombre) => {\n                    eliminarContacto(nombre);\n                    listinTelefonico();\n                });\n                break;\n            default:\n                console.error(`No reconocí \"${respuesta}\".`);\n                listinTelefonico();\n        }\n    });\n}\n\nlistinTelefonico()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/caterinarodriguezdev.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto\n *   en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n *   y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n *   y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más\n *   de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.\n */\n\nconsole.log(\"--------------ESTRUCTURAS DE DATOS----------------\");\nconsole.log(\"---------------------ARRAY------------------------\");\n\nconst arr = [1, 2, 3];\nconsole.log(\"array: \", arr);\narr.push(4);\nconsole.log(\"Inserción en el array de un 4. Resultado: \", arr);\narr.pop();\nconsole.log(\"Borrado en el array\", arr);\narr.shift();\nconsole.log(\"Borrado del primer elemento en el array\", arr);\n\nlet arrDesordenado = [2, 1, 0];\nconsole.log(\"array desordenando\", arrDesordenado);\narrDesordenado.sort();\nconsole.log(\"array ordenado\", arrDesordenado);\n\narrDesordenado[0] = 10;\nconsole.log(\"actualizamos array desordenado\", arrDesordenado);\n\nconsole.log(\"---------------------SET------------------------\");\n// Los sets solo permiten datos únicos, no puede haber dos elementos repetidos\nconst miSet = new Set([1, 2, 3]);\nconsole.log(\"mi set es\", miSet);\nmiSet.add(4);\nconsole.log(\".add() añade un elemento a mi\", miSet);\nmiSet.delete(3);\nconsole.log(\"borrando el elemento 3\", miSet);\nconsole.log(\"el set tiene el elemento 4?\", miSet.has(4));\nmiSet.clear();\nconsole.log(\"hacemos un clear del set\", miSet);\n\nconsole.log(\"---------------------WEAKSET------------------------\");\nconst obj1 = { nombre: \"obj1\" };\nconst obj2 = { nombre: \"obj2\" };\nconst obj3 = { nombre: \"obj3\" };\n\nconst miWeakSet = new WeakSet();\nmiWeakSet.add(obj1);\nmiWeakSet.add(obj2);\nconsole.log(\"my weak set\", miWeakSet);\nmiWeakSet.add(obj3);\nconsole.log(\"add obj3\", miWeakSet);\nmiWeakSet.delete(obj2);\nconsole.log(\"delete 3\", miWeakSet);\nconsole.log(\"my weak set has obj1?\", miWeakSet.has(obj1));\n\nconsole.log(\"---------------------WEAKMAP------------------------\");\nlet weakMap = new WeakMap();\nlet key1 = {};\nlet key2 = {};\n\nweakMap.set(key1, \"value1\");\nweakMap.set(key2, \"value2\");\n\nweakMap.delete(key1);\n\nweakMap.set(key2, \"newValue2\");\nconsole.log(weakMap);\n\nconsole.log(\"---------------------OBJETO------------------------\");\nconst persona = {\n  nombre: \"Caterina\",\n  edad: 24,\n  genero: \"f\",\n};\n\npersona.edad = 25;\nconsole.log(persona);\n\ndelete persona.genero;\nconsole.log(persona);\n\nconst sortedKeys = Object.keys(persona).sort();\n\nlet sortedObj = {};\nsortedKeys.map((key) => (sortedObj[key] = persona[key]));\nconsole.log(\"objeto ordenado\", sortedObj);\n\nconsole.log(\"---------------------MAP------------------------\");\n\nlet map = new Map([\n  [\"nombre\", \"Caterina\"],\n  [\"edad\", 22],\n  [\"genero\", \"f\"],\n]);\n\nmap.set(\"casa\", \"Mallorca\");\n\nmap.delete(\"genero\");\nconsole.log(map);\n\nlet sortedMapArray = [...map.entries()].sort();\nlet sortedMap = new Map(sortedMapArray);\nconsole.log(sortedMap);\n\nconsole.log(\"--------------------EJERCICIO EXTRA------------------\");\n\n/* DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n *   y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n *   y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más\n *   de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.\n */\nconst readline = require(\"readline\");\nconst rl = readline.createInterface(process.stdin, process.stdout);\n\nlet contacts = [];\n\nconst menu = () => {\n  console.log(`\n        ------------------\n        1. Añadir contacto\n        2. Borrar contacto\n        3. Opción sorpresa\n        4. Ver contactos\n        -----------------\n\n        `);\n  rl.question(\"Elije mortal :) -> \", chooseOption);\n};\n\nconst chooseOption = (option) => {\n  switch (option) {\n    case \"1\":\n      addContact();\n      break;\n    case \"2\":\n      deleteContact();\n      break;\n    case \"3\":\n      console.log(\"testim Grace, princeseta\");\n    case \"4\":\n      listContacts();\n      break;\n    default:\n      menu();\n  }\n};\n\nconst addContact = () => {\n  rl.question(\"Nombre pls -> \", (name) => addContactTelephone(name));\n};\n\nconst addContactTelephone = (name) => {\n  rl.question(\"Teléfono porfa pls -> \", (tlf) => {\n    if (tlf.length > 11) {\n      console.log(\"El teléfono no puede ser mayor a 11 dígitos\");\n      addContactTelephone();\n    } else if (!/^\\d{1,11}$/.test(tlf)) {\n      console.log(\"El teléfono solo puede incluir dígitos numéricos\");\n      addContact();\n    } else {\n      contacts.push({ nombre: name, telefono: tlf });\n      console.log(\"siuuuu, contacto añadido\");\n      listContacts();\n    }\n  });\n};\n\nconst listContacts = () => {\n  console.log(\"                  \");\n  console.log(\"------------------\");\n  console.log(\"                  \");\n  console.log(\"TUS CONTACTOS, REINA:\");\n  console.log(\"                  \");\n  contacts.map((contact) =>\n    console.log(`Nombre: ${contact.nombre} - Teléfono: ${contact.telefono}`)\n  );\n  menu();\n};\n\nconst deleteContact = () => {\n  rl.question(\"A quien hacemos la cruz? -> \", (contact) => {\n    contacts = contacts.filter((contact) => contact.nombre === contact);\n    console.log(\"eliminao >:)\");\n    menu();\n  });\n  menu();\n};\n\nmenu();\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/ceciliarava1.js",
    "content": "// 03-Javascript\n\n\n/*\n * EJERCICIO:\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\n\n// Array\nlet myArray = new Array()\nmyArray = [1, 2, 3]\n\nmyArray.push(4)\nmyArray.pop()\nmyArray[0] = 200\nmyArray = myArray.sort((a, b) => a - b); // Ascending sort\nmyArray = myArray.sort((a, b) => b - a); // Descending sort\n// console.log(myArray)\n\n\n/* Set\n    Can not update and sort because has no index, and are unique elements\n*/\nlet mySet = new Set()\nmySet = new Set([\"Cat\", \"Dog\", \"Fox\"])\nmySet.add('Elephant')\nmySet.delete(\"Cat\")\n// console.log(mySet)\n\n\n/* Map\n    Insertion order\n*/\nlet myMap = new Map()\nmyMap = new Map([\n  [\"Name\", \"Cat\"],\n  [\"Age\", 21],\n])\nmyMap.set(\"Location\", \"Chile\")\nmyMap.delete(\"Name\")\nmyMap.set(\"Location\", \"France\")\n// console.log(myMap)\n\n\n// Exercise\nclass Contact {\n    constructor(name, phoneNumber) {\n        this._name = name\n        this._phoneNumber = phoneNumber\n    }\n\n    set name(newName) {\n        if (typeof newName == 'string') {\n            this._name = newName \n        } else {\n            console.log('Name must be a string')\n        }\n    }\n\n    set phoneNumber(newPhoneNumber) {\n        let phoneLength = newPhoneNumber.toString().length\n\n        if (typeof newPhoneNumber == 'number' &&\n            phoneLength >= 9 &&\n            phoneLength <= 13) {\n\n            this._phoneNumber = newPhoneNumber\n\n        } else {\n            console.log('Phone must be a number [9-13 char]')\n        }\n    }\n\n    get name() {\n        return this._name \n    }\n\n    get phoneNumber() {\n        return this._phoneNumber\n    }\n}\n\n\nlet newContact = new Contact()\nnewContact.name = 'Lucia'\nnewContact.phoneNumber = 123456789\n\nconsole.log(newContact)"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/cesar-ch.js",
    "content": "// Arreglos\nconst arreglo = [1, 2, 3, 4, 5];\n\n// Objetos\nconst objeto = {\n    nombre: \"Juan\",\n    apellido: \"Pérez\",\n    edad: 30,\n};\n\n// Mapas\nconst mapa = new Map();\nmapa.set(\"nombre\", \"Juan\");\nmapa.set(\"apellido\", \"Pérez\");\nmapa.set(\"edad\", 30);\n\n// Colecciones\nconst coleccion = new Set([1, 2, 3, 4, 5]);\n\n// Operaciones\n// Inserción\narreglo.push(6);\nobjeto.pais = \"España\";\nmapa.set(\"pais\", \"España\");\ncoleccion.add(6);\n\n// Actualización{\narreglo[0] = 10;\nobjeto.apellido = \"López\";\nmapa.set(\"edad\", 31);\n\n// Ordenamiento\narreglo.sort();\n\n// Eliminación\narreglo.pop();\ndelete objeto.pais;\nmapa.delete(\"pais\");\ncoleccion.delete(6);\n\n// DIFICULTAD EXTRA\nfunction crearAgenda() {\n    let agenda = []\n    let run = true\n    while (run) {\n\n        const operacion = prompt(`Ingrese la operación a realizar:\n            1. Buscar contacto\n            2. Insertar contacto\n            3. Actializar contacto\n            4. Eliminar contacto\n            5. Salir\n        `)\n\n        if (operacion === \"1\") {\n\n            if (agenda.length === 0) {\n                console.log(\"Agenda vacía\")\n                continue\n            }\n            const nombre = prompt(\"Ingrese el nombre del contacto a buscar:\")\n\n            for (let i = 0; i < agenda.length; i++) {\n                if (agenda[i].nombre === nombre) {\n                    console.log(\"Contacto encontrado:\", agenda[i])\n                } else {\n                    console.log(\"Contacto no encontrado\")\n                }\n            }\n        } else if (operacion === \"2\") {\n\n            const nombre = prompt(\"Ingrese el nombre del contacto a insertar:\")\n            const phone = prompt(\"Ingrese el teléfono del contacto a insertar:\")\n\n            if (!/^\\d{6,11}$/.test(phone)) {\n                console.log(\"El número de teléfono no es válido.\");\n                break;\n            }\n\n            const contacto = {\n                nombre: nombre,\n                phone: phone\n            }\n\n            agenda.push(contacto)\n            console.log(\"Contacto insertado:\", contacto)\n\n\n        } else if (operacion === \"3\") {\n            const nombre = prompt(\"Ingrese el nombre del contacto a actualizar:\")\n            for (let i = 0; i < agenda.length; i++) {\n                if (agenda[i].nombre === nombre) {\n                    agenda[i].phone = prompt(\"Ingrese el nuevo teléfono del contacto:\")\n                    console.log(\"Contacto actualizado:\", agenda[i])\n                } else {\n                    console.log(\"Contacto no encontrado\")\n                }\n            }\n        } else if (operacion === \"4\") {\n            const nombre = prompt(\"Ingrese el nombre del contacto a eliminar:\")\n            for (let i = 0; i < agenda.length; i++) {\n                if (agenda[i].nombre === nombre) {\n                    agenda.splice(i, 1)\n                    console.log(\"Contacto eliminado:\")\n                } else {\n                    console.log(\"Contacto no encontrado\")\n                }\n            }\n        } else if (operacion === \"5\") {\n            run = false;\n            console.log(\"Agenda creada:\", agenda)\n            break;\n        } else {\n            console.log(\"Operación no válida\")\n        }\n    }\n    console.log(\"Agenda creada:\", agenda)\n}"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/christian-jfr.js",
    "content": "// #03 ESTRUCTURAS DE DATOS\n\n/**\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n */\n\n// 1. Arrays (Coleccion de datos)\nconst pLanguages = ['javascript', 'python', 'c#'];\n// inserción\npLanguages.unshift('java'); // insercion al principio del array\npLanguages.push('kotlin'); // insercion al final del array\npLanguages[5] = 'php'; // insercion en una posicion especificada del array\npLanguages.length; // -> 6\nconsole.log(pLanguages); // -> ['java', 'javascript', 'python', 'c#', 'kotlin', 'php']\n// borrado\npLanguages.shift(); // borra el primer elemento del array\npLanguages.pop(); // borra el ultimo elemento del array\npLanguages.length; // -> 4\ndelete pLanguages[2]; // borra el elemento en una posicion especificada pero mantiene el espacio vacío\npLanguages.length; // -> 4\nconsole.log(pLanguages); // -> ['javascript', 'python', 'empty', 'kotlin']\n// actualización\npLanguages[2] = 'c++'; // actualiza el elemento en una posicion especificada\nconsole.log(pLanguages); // -> ['javascript', 'python', 'c++', 'kotlin']\n// ordenación\npLanguages.sort(); // ordena el array de menor a mayor por defecto (alfabeticamente)\nconsole.log(pLanguages); // -> ['c++', 'javascript', 'kotlin', 'python']\npLanguages.reverse(); // invierte el orden del array\nconsole.log(pLanguages); // -> ['python', 'kotlin', 'javascript', 'c++']\n\n// 2. Objects (Colecciones de pares clave-valor)\nconst languages = {\n\tjavascript: '1995',\n\tpython: '1991',\n\tc: '1972',\n};\n// inserción y actualización\nlanguages.java = '995';\nlanguages['kotlin'] = '2011';\nObject.defineProperty(languages, 'php', {\n\tvalue: '1995',\n\twritable: true,\n\tenumerable: true,\n\tconfigurable: true,\n});\nconsole.log(languages); // -> {javascript: '995', python: '1991', c: '1972', java: '1995', kotlin: '2011', php: '1995'}\nlanguages.java = '1995'; // actualiza la propiedad java\nconsole.log(languages); // -> {javascript: '1995', python: '1991', c: '1972', java: '1995', kotlin: '2011', php: '1995'}\n// borrado\ndelete languages.c; // borra la propiedad c y su valor del objeto languages\n\n// 3. Set (Colecciones de valores unicos (no duplicados))\nconst numbers = new Set([0]);\n// inserción\nnumbers.add(1);\nnumbers.add(2);\nnumbers.add(3);\nnumbers.add(1); // este no ingresa al array por ser duplicado\nnumbers.size; // -> 4\nnumbers.has(0); // -> true\nnumbers.has(5); // -> false\nconsole.log(numbers); // -> {0, 1, 2, 3}\n// borrado\nnumbers.delete(0);\nnumbers.size; // -> 3\nconsole.log(numbers); // -> {1, 2, 3}\n\n// 4. Map (Coleccion asociativa de datos)\nconst numbersMap = new Map([['zero', 0]]);\n// inserción\nnumbersMap.set('one', 1);\nnumbersMap.set('two', 2);\nnumbersMap.set('three', 3);\nnumbersMap.size; // -> 4\nconsole.log(numbersMap); // -> {zero: 0, one: 1, two: 2, three: 3}\n// actualización\nnumbersMap.set('zero', 'cero');\nnumbersMap.set('one', 'uno');\nnumbersMap.set('two', 'dos');\nnumbersMap.set('three', 'tres');\nconsole.log(numbersMap); // -> {zero: 'cero', one: 'uno', two: 'dos', three: 'tres'}\n// borrado\nnumbersMap.delete('zero');\nnumbersMap.size; // -> 3\nconsole.log(numbersMap); // -> {one: 'uno', two: 'dos', three: 'tres'}\n\n/** DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\n/**\n * Use el entorno nodejs para poder programar la agenda del\n * ejercicio extra.\n * */\nimport { createInterface } from 'readline';\n\nconst rl = createInterface({\n\tinput: process.stdin,\n\toutput: process.stdout,\n});\n\nconst contacts = {\n\tTest: {\n\t\tname: 'Test Name',\n\t\tphone: '3012456789',\n\t},\n};\n\nconst regex = /^[0-9]{10}$/; // 10 digitos - solo numeros\n\nmain();\n\nfunction main() {\n\tconsole.log('\\nWelcome to Contacts.\\n');\n\n\tconsole.log('  0. All Contacts');\n\tconsole.log('  1. Search');\n\tconsole.log('  2. Add');\n\tconsole.log('  3. Update');\n\tconsole.log('  4. Delete');\n\tconsole.log('  5. Exit');\n\n\trl.question('\\nChoose an option: ', (action) => {\n\t\tfunctionSet(action);\n\t});\n}\n\nfunction backToMain() {\n\trl.question('\\nPress enter to back to menu', () => {\n\t\tconsole.clear();\n\t\tmain();\n\t});\n}\n\nfunction validatePhone(phone) {\n\treturn regex.test(phone);\n}\n\nfunction functionSet(action) {\n\tif (action === '0') {\n\t\tshowContacts(contacts);\n\t} else if (action === '1') {\n\t\tconsole.log('\\n==Search Contact==\\n');\n\t\trl.question('Enter the contact nick: ', (nick) => {\n\t\t\tsearchContact(contacts, nick);\n\t\t});\n\t} else if (action === '2') {\n\t\tconsole.log('\\n==Add a Contact==\\n');\n\t\trl.question('Enter the contact nick: ', (nick) => {\n\t\t\trl.question('Enter the contact name: ', (name) => {\n\t\t\t\trl.question('Enter the contact phone: ', (phone) => {\n\t\t\t\t\taddContact(contacts, nick, name, phone);\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\t} else if (action === '3') {\n\t\tconsole.log('\\n==Update Contact==\\n');\n\t\trl.question('Enter the contact nick: ', (nick) => {\n\t\t\trl.question('Enter the contact name: ', (name) => {\n\t\t\t\trl.question('Enter the contact phone: ', (phone) => {\n\t\t\t\t\tupdateContact(contacts, nick, name, phone);\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\t} else if (action === '4') {\n\t\tconsole.log('\\n==Delete Contact==\\n');\n\t\trl.question('Enter the contact nick: ', (nick) => {\n\t\t\tdeleteContact(contacts, nick);\n\t\t});\n\t} else if (action === '5') {\n\t\texitContacts();\n\t} else {\n\t\tconsole.log('Invalid option. Select an option from 0 to 5');\n\t\tsetTimeout(() => {\n\t\t\tconsole.clear();\n\t\t\tmain();\n\t\t}, 2000);\n\t}\n}\n\nfunction showContacts(obj) {\n\tconsole.log('\\nHere are your contacts:\\n');\n\tif (Object.keys(obj).length === 0) {\n\t\tconsole.log('No contacts... list is empty.');\n\t} else {\n\t\tfor (const contact in obj) {\n\t\t\tconsole.log(`${contact}: ${obj[contact].name} - ${obj[contact].phone}`);\n\t\t}\n\t}\n\tbackToMain();\n}\n\nfunction searchContact(obj, nick) {\n\tconst search = obj.hasOwnProperty(nick);\n\tif (search) {\n\t\tconsole.log(`${obj[nick].name} - ${obj[nick].phone}`);\n\t} else {\n\t\tconsole.log(`Contact ${nick} does not exist`);\n\t}\n\tbackToMain();\n}\n\nfunction addContact(obj, nick, name, phone) {\n\tif (obj.hasOwnProperty(nick)) {\n\t\tconsole.log(`Contact ${nick} already exist`);\n\t\tbackToMain();\n\t} else if (validatePhone(phone)) {\n\t\tobj[nick] = { name, phone };\n\t\tconsole.log(`Contact ${nick} successfully added`);\n\t} else {\n\t\tconsole.log('Invalid phone number. Phone must have 10 digits');\n\t}\n\tbackToMain();\n}\n\nfunction updateContact(obj, nick, name, phone) {\n\tif (obj.hasOwnProperty(nick) && validatePhone(phone)) {\n\t\tobj[nick].name = name;\n\t\tobj[nick].phone = phone;\n\t\tconsole.log(`Contact ${nick} successfully updated`);\n\t} else {\n\t\tconsole.log(\n\t\t\t`Contact ${nick} does not exist or you input an invalid phone number. Phone must have 10 digits`\n\t\t);\n\t}\n\tbackToMain();\n}\n\nfunction deleteContact(obj, nick) {\n\tif (obj.hasOwnProperty(nick)) {\n\t\tdelete obj[nick];\n\t\tconsole.log(`Contact ${nick} successfully deleted`);\n\t} else {\n\t\tconsole.log(`Contact ${nick} does not exist`);\n\t}\n\tbackToMain();\n}\n\nfunction exitContacts() {\n\tconsole.log('Exiting Contacts!');\n\tsetTimeout(() => {\n\t\tconsole.clear();\n\t\tprocess.exit();\n\t}, 1000);\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/cmejiajulian.js",
    "content": "/*\n* #03 ESTRUCTURAS DE DATOS\n*/\n\n/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n*/\n\n/*\n*Arrays o Arreglos\n\nLos arrays son una colección ordenada de elementos, donde cada elemento se accede mediante un índice numérico.\nCaracterísticas:\nPueden almacenar cualquier tipo de dato (números, cadenas, objetos, funciones, etc.).\nTienen un tamaño dinámico, es decir, pueden crecer o reducirse según se añadan o eliminen elementos.\n\n*/ \n\nconst arr = new Array(10);\nconsole.log(arr);\n\nconst arra = [];\nconsole.log(arra);\n\n//ahora crearemos un arreglo con video juegos\n\nlet videoJuegos = ['fifa','AsseAssassins Creed','Forza'];\nconsole.log({videoJuegos})\n\n//Insercion \n videoJuegos.push ('Call of Duty');\n console.log({videoJuegos})\n\n //Borrado\n\nlet ultimoJuegoBorrado = videoJuegos.pop(); //Pop elimina el ultimo elemento del arreglo.\nconsole.log({ultimoJuegoBorrado,videoJuegos});\n\nlet posicionJuegoBorrado = videoJuegos.splice(1,1); //Splice elimina el elemento de acuerdo a la posicion indicada.\nconsole.log({posicionJuegoBorrado,videoJuegos});\n\n//Acceso\nconsole.log(videoJuegos[1]);\n\n//Actualizacion \nlet actualizacionVideoJuego = 'Mario Bros'\nvideoJuegos[1] = actualizacionVideoJuego\nconsole.log({videoJuegos,actualizacionVideoJuego});\n\n//Ordenacion \nlet ordenVideoJuegos = videoJuegos.sort();\nconsole.log({ordenVideoJuegos});\n\n/*\n*Sets\nEn JavaScript, un Set es una colección de valores únicos, y se implementa como un objeto especial\n que proporciona una manera eficiente de almacenar y manejar conjuntos de datos sin duplicados. \n Aunque se considera un tipo de objeto, tiene su propia interfaz y métodos específicos que lo diferencian \n de los objetos regulares y de otros tipos de colecciones como los arrays.\n*/\n\n let marcaCars = ['Renault','Mazda','Toyota','Jeep','Porche','Tesla']\n\n let setsMarcasCars = new Set(marcaCars);\n console.log({setsMarcasCars});\n\n//Inserccion \n\nlet inserSet = setsMarcasCars.add('mercedes')\nconsole.log({inserSet});\n\n//Borrado\n\nlet borrarSet = setsMarcasCars.delete('Toyota');\nconsole.log(borrarSet);\nconsole.log(setsMarcasCars);\n\n//Acceso \n/*A diferencia de los arrays, los Set en JavaScript no tienen un índice para acceder \ndirectamente a sus elementos. Sin embargo, puedes iterar sobre los elementos de un Set para acceder a ellos*/\n\nlet elemento = Array.from (setsMarcasCars);\nconsole.log(elemento [2]);\n\n//Actualizacion \n\nif (setsMarcasCars.has('Renault')){\n    setsMarcasCars.delete('Renault');\n    setsMarcasCars.add('BMW');\n}\n\nconsole.log(setsMarcasCars);\n\n//Ordenacion\n\nlet ordenCars = Array.from(setsMarcasCars);\n//para ordenar el arreglo utilizo sort asi:\n\nordenCars.sort();\n\n//creo un nuevo set\n\nlet carsOrdenado = new Set(ordenCars);\nconsole.log(carsOrdenado);\n\n/* \n* Objetos \nLos objetos son colecciones de pares clave-valor, donde cada clave es una cadena (o un símbolo) \ny cada valor puede ser cualquier tipo de dato.\n*/\n\nlet serieHouseOfDragon = {\n\n    reina:'RaineRhaenyra Targaryen',\n    villano:'Aemond Targaryen',\n    temporadas:2,\n    numeroDeDragones:17,\n    NombreDeLasCasas: ['Casa Targaryen','Casa Hightower','Casa Velaryon']\n\n}\n\n//insercion \nserieHouseOfDragon.villano ='Aegon II Targaryen';\nconsole.log({serieHouseOfDragon})\n\nserieHouseOfDragon['NumeroDeSoldados'] = 1000\n\n//Borrado \ndelete serieHouseOfDragon.temporadas;\nconsole.log({serieHouseOfDragon});\n\n//acceso \nconsole.log(serieHouseOfDragon.NombreDeLasCasas[1]);\n\n//Actualizacion \n\nserieHouseOfDragon.NombreDeLasCasas[0] = 'Casa Stark ';\nconsole.log({serieHouseOfDragon});\n\n//Ordenar \n\nlet ordenHouse = Object.entries(serieHouseOfDragon);\nordenHouse.sort((a,b)=>a[0].localeCompare(b[0]));\nlet houseOrdenada = Object.fromEntries(ordenHouse);\n\nconsole.log({houseOrdenada});\n\n\n/*\n *   DIFICULTAD EXTRA (opcional):\n *   Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\n\nconst readline = require('readline');\n\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout\n});\n\nlet contactos = {}; // Objeto para almacenar los contactos\nlet ejecutar = true;\n\nconst mostrarMenu = () => {\n  console.log(\"\\nOpciones:\");\n  console.log(\"1: Búsqueda\");\n  console.log(\"2: Inserción\");\n  console.log(\"3: Actualización\");\n  console.log(\"4: Eliminación de Contactos\");\n  console.log(\"5: Salir\");\n};\n\nconst preguntarAccion = () => {\n  rl.question('Por favor ingrese el número de la acción que desea realizar: ', (dato) => {\n    let opcion = parseInt(dato, 10);\n\n    switch (opcion) {\n      case 1:\n        rl.question('Por favor ingrese el nombre del contacto a buscar: ', (nombre) => {\n          if (contactos[nombre]) {\n            console.log(`Contacto encontrado: Nombre - ${nombre}, Teléfono - ${contactos[nombre]}`);\n          } else {\n            console.log('Nombre no encontrado');\n          }\n          preguntarAccion(); // Volver a preguntar después de la operación\n        });\n        break;\n      case 2:\n        rl.question('Por favor ingrese su nombre: ', (nombre) => {\n          rl.question('Ingrese su número telefónico: ', (telefono) => {\n            let telefonoStr = telefono.toString();\n            if (telefonoStr.length > 11) {\n              console.log('El número no es válido, es mayor a 11 dígitos');\n            } else {\n              contactos[nombre] = telefono;\n              console.log(`Contacto agregado: Nombre - ${nombre}, Teléfono - ${telefono}`);\n            }\n            preguntarAccion(); // Volver a preguntar después de la operación\n          });\n        });\n        break;\n      case 3:\n        rl.question('Ingrese el nombre del contacto a actualizar: ', (nombre) => {\n          if (contactos[nombre]) {\n            rl.question('Ingrese el nuevo número telefónico: ', (nuevoTelefono) => {\n              let nuevoTelefonoStr = nuevoTelefono.toString();\n              if (nuevoTelefonoStr.length > 11) {\n                console.log('El número no es válido, es mayor a 11 dígitos');\n              } else {\n                contactos[nombre] = nuevoTelefono;\n                console.log(`Contacto actualizado: Nombre - ${nombre}, Nuevo Teléfono - ${nuevoTelefono}`);\n              }\n              preguntarAccion(); // Volver a preguntar después de la operación\n            });\n          } else {\n            console.log('Nombre no encontrado');\n            preguntarAccion(); // Volver a preguntar después de la operación\n          }\n        });\n        break;\n      case 4:\n        rl.question('Ingrese el nombre del contacto a eliminar: ', (nombre) => {\n          if (contactos[nombre]) {\n            delete contactos[nombre];\n            console.log(`Contacto eliminado: Nombre - ${nombre}`);\n          } else {\n            console.log('Nombre no encontrado');\n          }\n          preguntarAccion(); // Volver a preguntar después de la operación\n        });\n        break;\n      case 5:\n        console.log('Saliendo del programa.');\n        ejecutar = false; // Cambiar la variable de control para salir del bucle\n        rl.close(); // Cerrar la interfaz\n        break;\n      default:\n        console.log(\"Operación no reconocida\");\n        preguntarAccion(); // Volver a preguntar si la operación no es válida\n    }\n  });\n};\n\nconst iniciar = () => {\n  while (ejecutar) {\n    mostrarMenu();\n    preguntarAccion();\n    break; // Salir del bucle para permitir que preguntarAccion maneje la entrada del usuario\n  }\n};\n\niniciar();\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/cristophher087.js",
    "content": "/**\n * Estructuras soportadas por JavaScript\n * \n * Tipado dinámico\n * \n * JS es un Lenguaje de prigramacion debilmente tipado y dinámico.\n */\n\nlet foo = 42;   // foo ahora es un número\nfoo = \"bar\";    // foo ahora es un string\nfoo = true;     // foo ahora es un booleano\n\n/**\n * Estructuras y tipso de datos\n * El último estándar ECMAScript define nueve tipos:\n*/\n\n// Seis tipos de datos primitivos, controlados por el operador typeof\n\ntypeof isntance === \"undefined\"\ntypeof isntance === \"boolean\"\ntypeof instance === \"number\"\ntypeof instance === \"string\"\ntypeof instance === \"bigint\"\ntypeof instance === \"symbol\"\n\ntypeof instance === \"object\" //Tipo primitivo especial que tiene un uso adicional para su valor: si el objeto no se hereda, se muestra null\n\ntypeof instance === \"object\" //Tipo estructural especial que no es de datos pero para cualquier instancia de objeto construido que también se utiliza como estructuras de datos: new Object, new Array, new Map, new Set, new WeakMap, new WeakSet, new Date y casi todo lo hecho con la palabra clave new;\n\ntypeof instance === \"function\" //Esta simplemente es una forma abreviada para funciones, aunque cada constructor de funciones se deriva del constructor Object.\n\n/**\n * Estructuras de Datos\n */\n\n// Set: Conjunto de valores únicos\nlet conjunto = new Set([1, 2, 3, 3]);\nconsole.log(conjunto);  // {1, 2, 3}\n/**\n * Set define valores como se muestra en el ejemplo\n */\n\n// Map: Estructura clave-valor\nlet mapa = new Map();\nmapa.set(\"nombre\", \"Carlos\");\nmapa.set(\"edad\", 25);\nconsole.log(mapa.get(\"nombre\"));  // Carlos\n/**\n * Map Genera una estructura en donde s egenera una clave con su rsepectivo valor de este\n */\n\n// WeakSet y WeakMap: Estructuras que contienen referencias débiles\nlet weakSet = new WeakSet();\nlet objeto1 = { clave: 123 };\nweakSet.add(objeto1);\n\n// No se puede iterar directamente un WeakSet\nconsole.log(weakSet.has(objeto1));  // true\n\n\n/**\n * Vectores (Arrays) en JavaScript\n *      Un Array es una lista ordenada de elementos. En JavaScript, los arrays pueden contener cualquier tipo de dato (números, strings, objetos, etc.).\n */\n\nlet numeros = [1, 2, 3, 4, 5];  // Array de números\nlet mezclado = [42, \"texto\", true, { id: 1 }];  // Elementos de distintos tipos\n\n/**\n * Inserciones\n */\n\n// Inserción al final del array\nnumeros.push(6);  // [1, 2, 3, 4, 5, 6]\n\n// Inserción al inicio del array\nnumeros.unshift(0);  // [0, 1, 2, 3, 4, 5, 6]\n\n// Inserción en una posición específica (índice)\nnumeros.splice(3, 0, 99);  // [0, 1, 2, 99, 3, 4, 5, 6]\n\n/**\n * Eliminación de Elementos\n */\n\n// Eliminar el último elemento\nnumeros.pop();  // [0, 1, 2, 99, 3, 4, 5]\n\n// Eliminar el primer elemento\nnumeros.shift();  // [1, 2, 99, 3, 4, 5]\n\n// Eliminar en una posición específica\nnumeros.splice(2, 1);  // [1, 2, 3, 4, 5] (elimina el valor en el índice 2)\n\n/**\n * Búsquedas en Arrays\n */\n\n// Buscar el índice de un elemento\nlet indice = numeros.indexOf(3);  // 2\n\n// Verificar si un elemento existe\nlet existe = numeros.includes(4);  // true\n\n// Búsqueda con función de condición\nlet mayorQueTres = numeros.find(num => num > 3);  // 4\n\n/**\n * Recorrer un Array\n */\n\n// Usando for\nfor (let i = 0; i < numeros.length; i++) {\n  console.log(numeros[i]);\n}\n\n// Usando for...of\nfor (let num of numeros) {\n  console.log(num);\n}\n\n// Usando forEach\nnumeros.forEach((num, index) => {\n  console.log(`Elemento en ${index}: ${num}`);\n});\n\n/**\n * Matrices (Arrays Multidimensionales)\n *  Una matriz es un array de arrays. Esto se usa para representar estructuras como tablas o grillas.\n */\n\nlet matriz = [\n  [1, 2, 3],\n  [4, 5, 6],\n  [7, 8, 9]\n];\n\n/**\n * Acceso a Elementos\n */\n\nlet elemento = matriz[1][2];  // 6 (Fila 1, Columna 2)\n\n/**\n * Modificación de Elementos\n */\n\nmatriz[2][1] = 88;  // Modifica el valor en la fila 2, columna 1\nconsole.log(matriz);\n// Resultado: [ [1, 2, 3], [4, 5, 6], [7, 88, 9] ]\n\n/**\n * Recorrer una Matriz\n */\n\nfor (let fila of matriz) {\n  for (let valor of fila) {\n    console.log(valor);\n  }\n}\n\n// Usando forEach\nmatriz.forEach(fila => {\n  fila.forEach(valor => console.log(valor));\n});\n\n/**\n * Operaciones Funcionales en Arrays (map, filter, reduce)\n */\n\n/**\n * map: Crear un nuevo array transformando los elementos.\n */\n\nlet duplicados = numeros.map(num => num * 2);  // [2, 4, 6, 8, 10]\n\n/**\n * reduce: Reducir el array a un solo valor.\n */\n\nlet suma = numeros.reduce((acumulador, actual) => acumulador + actual, 0);  // 15\n\n/**\n * Ejemplo\n */\n\n// Crear una matriz 3x3\nlet matriz = [\n  [1, 2, 3],\n  [4, 5, 6],\n  [7, 8, 9]\n];\n\n// Insertar un valor en una posición específica (fila 1, columna 1)\nmatriz[1][1] = 99;\n\n// Sumar todos los elementos de la matriz\nlet sumaTotal = matriz.flat().reduce((acc, val) => acc + val, 0);\nconsole.log(`Suma total: ${sumaTotal}`);  // 144\n\n// Filtrar todos los valores mayores que 5\nlet mayores = matriz.flat().filter(num => num > 5);\nconsole.log(`Mayores que 5: ${mayores}`);  // [6, 7, 8, 9]\n\n\nlet contactos = [\n  { nombre: \"Carlos\", telefono: \"5558765123\" },\n  { nombre: \"María\", telefono: \"5512345678\" },\n  { nombre: \"Juan\", telefono: \"5578943210\" },\n  { nombre: \"Ana\", telefono: \"5587654321\" },\n  { nombre: \"Luis\", telefono: \"5612345678\" },\n  { nombre: \"Sofía\", telefono: \"5545678912\" },\n  { nombre: \"Pedro\", telefono: \"5556781234\" },\n  { nombre: \"Laura\", telefono: \"5598765432\" },\n  { nombre: \"Roberto\", telefono: \"5587123456\" },\n  { nombre: \"Daniela\", telefono: \"5567894321\" }\n];\n\n// Mostrar contactos iniciales\nmostrarContactos();\n\n// Ciclo principal del programa\nwhile (true) {\n  console.log(\"\\nAgenda de contactos\");\n  console.log(\"Digita la opción que quieres realizar:\");\n  console.log(\"[b] - Búsqueda\");\n  console.log(\"[i] - Inserción\");\n  console.log(\"[a] - Actualización\");\n  console.log(\"[e] - Eliminación\");\n  console.log(\"[q] - Salir\");\n\n  let opcion = prompt(\"¿Qué acción deseas realizar?\").toLowerCase().trim();\n\n  switch (opcion) {\n    case \"b\":\n      consultaContacto();\n      break;\n    case \"i\":\n      ingresaContacto();\n      break;\n    case \"a\":\n      actualizaContacto();\n      break;\n    case \"e\":\n      eliminaContacto();\n      break;\n    case \"q\":\n      console.log(\"Saliendo de la agenda...\");\n      process.exit();  // Solo en Node.js; en navegador, usar 'break' y finalizar el ciclo.\n    default:\n      console.log(\"Opción no válida. Inténtalo de nuevo.\");\n  }\n}\n\n// Función para mostrar todos los contactos\nfunction mostrarContactos() {\n  console.log(\"\\nContactos actuales:\");\n  contactos.forEach((contacto, index) =>\n    console.log(`${index + 1}. Nombre: ${contacto.nombre}, Teléfono: ${contacto.telefono}`)\n  );\n}\n\n// Función para buscar un contacto por nombre\nfunction consultaContacto() {\n  let nombreConsulta = prompt(\"Ingresa el nombre del contacto a buscar:\").trim().toLowerCase();\n  let contacto = contactos.find(c => c.nombre.toLowerCase() === nombreConsulta);\n\n  if (contacto) {\n    console.log(`\\nNombre: ${contacto.nombre}, Teléfono: ${contacto.telefono}`);\n  } else {\n    console.log(`No se encontró un contacto con el nombre \"${nombreConsulta}\".`);\n  }\n}\n\n// Función para ingresar un nuevo contacto\nfunction ingresaContacto() {\n  let nuevoNombre = prompt(\"Ingresa el nombre del nuevo contacto:\").trim();\n  let nuevoNumero = prompt(\"Ingresa el número de teléfono (10 dígitos):\").trim();\n\n  if (!/^\\d{10}$/.test(nuevoNumero)) {\n    console.log(\"Número inválido. Debe contener exactamente 10 dígitos.\");\n    return;\n  }\n  /**\n   * \"/^\\d{10}$/\" es una expresión regular (regex) que valida que la entrada nuevoNumero contenga exactamente 10 dígitos numéricos.\n   * \"^\" y \"$\" aseguran que la cadena completa debe cumplir con el patrón (no puede haber otros caracteres).\n   * \"\\d{10}\" indica que deben ser exactamente 10 dígitos consecutivos.\n   * El operador NOT (!) invierte el resultado de la expresión regular. Si el número no coincide con la regex (es decir, no tiene exactamente 10 dígitos), la condición se cumple.\n   * .test(nuevoNumero): Este método prueba si el contenido de nuevoNumero coincide con la expresión regular.\n   */\n\n  if (contactos.some(c => c.nombre.toLowerCase() === nuevoNombre.toLowerCase())) {\n    console.log(\"El contacto ya existe. No se puede duplicar.\");\n    return;\n  }\n  /**\n   * c => c.nombre.toLowerCase() === nuevoNombre.toLowerCase() es una función flecha (arrow function) que actúa como callback. Por cada elemento del array contactos, ejecuta el código dentro de esa función flecha.\n   * La c no está definida antes porque es solo un parámetro temporal de la función flecha.\n   * some() es un método de los arrays que retorna true si al menos un elemento del array cumple con la condición que se le pasa.\n   * Se compara el nombre del contacto existente (c.nombre) con el nuevo nombre ingresado (nuevoNombre).\n   * Ambos nombres se convierten a minúsculas con toLowerCase() para evitar errores por mayúsculas o minúsculas (por ejemplo, \"Carlos\" y \"carlos\" se tratarían como iguales).\n   */\n\n  contactos.push({ nombre: nuevoNombre, telefono: nuevoNumero });\n  console.log(\"Contacto agregado exitosamente.\");\n  mostrarContactos();\n}\n\n// Función para actualizar un contacto\nfunction actualizaContacto() {\n  let nombreConsulta = prompt(\"Ingresa el nombre del contacto a actualizar:\").trim().toLowerCase();\n  let contacto = contactos.find(c => c.nombre.toLowerCase() === nombreConsulta);\n\n  if (contacto) {\n    let nuevoNombre = prompt(`Ingresa el nuevo nombre (actual: ${contacto.nombre}):`).trim() || contacto.nombre;\n    let nuevoNumero = prompt(`Ingresa el nuevo número (actual: ${contacto.telefono}):`).trim() || contacto.telefono;\n\n    if (!/^\\d{10}$/.test(nuevoNumero)) {\n      console.log(\"Número inválido. Debe contener exactamente 10 dígitos.\");\n      return;\n    }\n\n    contacto.nombre = nuevoNombre;\n    contacto.telefono = nuevoNumero;\n    console.log(\"Contacto actualizado exitosamente.\");\n    mostrarContactos();\n  } else {\n    console.log(`No se encontró un contacto con el nombre \"${nombreConsulta}\".`);\n  }\n}\n\n// Función para eliminar un contacto\nfunction eliminaContacto() {\n  let nombreConsulta = prompt(\"Ingresa el nombre del contacto a eliminar:\").trim().toLowerCase();\n  let index = contactos.findIndex(c => c.nombre.toLowerCase() === nombreConsulta);\n\n  if (index !== -1) {\n    contactos.splice(index, 1);\n    console.log(\"Contacto eliminado exitosamente.\");\n    mostrarContactos();\n  } else {\n    console.log(`No se encontró un contacto con el nombre \"${nombreConsulta}\".`);\n  }\n}\n\n/**\n ¿Qué es una expresión regular?\n\nEs una secuencia de caracteres que define un patrón de búsqueda. Por ejemplo, /\\d{10}/ es una expresión regular que busca 10 dígitos consecutivos.\n\nLas expresiones regulares se delimitan entre barras /.../ (en JavaScript), y pueden incluir caracteres literales, metacaracteres (como . o \\d), y modificadores para ampliar su funcionalidad.\n\nComponentes básicos de una regex\nMetacaracteres (símbolos especiales):\n\n    . (punto): Representa cualquier carácter, excepto saltos de línea.\n        Ejemplo: /c.t/ coincide con cat, cot, o cut.\n\n    \\d: Representa cualquier dígito (equivale a [0-9]).\n        Ejemplo: /\\d/ encuentra cualquier número en la cadena \"Tel: 123\".\n\n    \\w: Representa cualquier carácter alfanumérico (letras, números o guion bajo).\n        Ejemplo: /\\w+/ encuentra palabras como \"hola123\".\n\n    \\s: Coincide con espacios en blanco (incluye tabulaciones y saltos de línea).\n\n    ^ y $: Marcan el inicio y fin de la cadena, respectivamente.\n        Ejemplo: /^Hola/ verifica que la cadena empiece con \"Hola\".\n        Ejemplo: /mundo$/ verifica que termine con \"mundo\".\n\n    \n */\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/cubandeveloper89.js",
    "content": "// ***  Estructura de Datos  ***\n// !    Array\nvar my_list = ['Brais', 'midudev', 'el_gato'];\nvar num_list = [2, 5, 7, 3, 7];\nconsole.log(my_list);\nmy_list.push('John'); // * añadir al final\nconsole.log(my_list);\nmy_list.unshift('Python'); // * añadir al inicio\nconsole.log(my_list);\nconsole.log(my_list[0]); // * accediendo a un elemento en mi lista segun su posición \nmy_list.pop(); // * elimina el ultimo elemento de la lista\nconsole.log(my_list);\nmy_list.shift(); // * elimina el primer elemento de la lista\nconsole.log(my_list);\nvar my_second_list = my_list.slice(1, 3); // * crea un nuevo array con elementos del primero\nconsole.log(my_second_list);\nmy_list.splice(2, 1); // * elimina elementos segun su posicion\nconsole.log(my_list);\nmy_list[1] = 'mouredev'; // * actualizar un elemento segun su posicion\nconsole.log(my_list);\nmy_list.push('John');\nmy_list.push('Doe');\nmy_list.sort(); //  * Ordenar los elementos del array\nconsole.log(my_list);\n// !     Set \nvar my_set = new Set();\nmy_set.add(3); // * añadiendo valores\nmy_set.add('ordenador');\nmy_set.add(true);\nmy_set.add('45');\nconsole.log(my_set);\nconsole.log(my_set.has('ordenador'));\nmy_set.delete('45'); // * eliminando por elemento\nconsole.log(my_set);\nconsole.log(my_set.size); // * muestra el tamaño del set\n// !     Map\nvar my_map = new Map();\nmy_map.set('a', 1); // * insertando elementos \nmy_map.set('b', 2);\nmy_map.set('c', 3);\nconsole.log(my_map);\nmy_map.set('a', 89); // * actualizando elemento\nconsole.log(my_map);\nmy_map.delete('b'); // * eliminando elemento\nconsole.log(my_map);\n// !    Objects\nvar my_obj = {}; //  * 2 maneras de declarar un objeto\nvar my_second_obj = new Object();\nmy_obj.name = 'Camilo'; //  *   insertando elementos clave/valor\nmy_obj.age = 35;\nmy_obj.profession = 'influencer';\nconsole.log(my_obj);\nmy_obj.name = 'Brais'; // * actualizando elementos\nconsole.log(my_obj);\ndelete my_obj.profession; // * eliminando elemento\nconsole.log(my_obj);\n// ? *** Ejercicio Extra ***\nvar prompt = require('prompt-sync')({ sigint: true });\nvar agenda = [];\nfunction mostrarMenu() {\n    console.log(\"Agenda de Contactos\");\n    console.log(\"1. Buscar contacto\");\n    console.log(\"2. Insertar contacto\");\n    console.log(\"3. Actualizar contacto\");\n    console.log(\"4. Eliminar contacto\");\n    console.log(\"5. Salir\");\n}\nfunction buscarContacto(nombre) {\n    var contacto = agenda.find(function (c) { return c.nombre === nombre; });\n    if (contacto) {\n        console.log(\"Contacto encontrado:\");\n        console.log(contacto);\n    }\n    else {\n        console.log(\"Contacto no encontrado.\");\n    }\n}\nfunction insertarContacto() {\n    var nombre = prompt(\"Ingrese el nombre del contacto:\");\n    var telefono = prompt(\"Ingrese el número de teléfono:\");\n    // Validación del número de teléfono\n    while (!/^\\d{11}$/.test(telefono)) {\n        console.log(\"El número de teléfono debe tener 11 dígitos.\");\n        telefono = prompt(\"Ingrese el número de teléfono:\");\n    }\n    var nuevoContacto = { nombre: nombre, telefono: telefono };\n    agenda.push(nuevoContacto);\n    console.log(\"Contacto agregado exitosamente.\");\n}\nfunction actualizarContacto(nombre) {\n    var indice = agenda.findIndex(function (c) { return c.nombre === nombre; });\n    if (indice !== -1) {\n        var nuevoTelefono = prompt(\"Ingrese el nuevo número de teléfono:\");\n        agenda[indice].telefono = nuevoTelefono;\n        console.log(\"Contacto actualizado exitosamente.\");\n    }\n    else {\n        console.log(\"Contacto no encontrado.\");\n    }\n}\nfunction eliminarContacto(nombre) {\n    var indice = agenda.findIndex(function (c) { return c.nombre === nombre; });\n    if (indice !== -1) {\n        agenda.splice(indice, 1);\n        console.log(\"Contacto eliminado exitosamente.\");\n    }\n    else {\n        console.log(\"Contacto no encontrado.\");\n    }\n}\nfunction main() {\n    var opcion;\n    do {\n        mostrarMenu();\n        opcion = prompt(\"Ingrese una opción:\");\n        switch (opcion) {\n            case \"1\":\n                var nombreBuscar = prompt(\"Ingrese el nombre a buscar:\");\n                buscarContacto(nombreBuscar);\n                break;\n            case \"2\":\n                insertarContacto();\n                break;\n            case \"3\":\n                var nombreActualizar = prompt(\"Ingrese el nombre a actualizar:\");\n                actualizarContacto(nombreActualizar);\n                break;\n            case \"4\":\n                var nombreEliminar = prompt(\"Ingrese el nombre a eliminar:\");\n                eliminarContacto(nombreEliminar);\n                break;\n            case \"5\":\n                console.log(\"Saliendo del programa...\");\n                break;\n            default:\n                console.log(\"Opción inválida.\");\n        }\n    } while (opcion !== \"5\");\n}\nmain();\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/d4-n1.js",
    "content": "////////////////////////////////\n// Arrays\n////////////////////////////////\n\nlet macedonia = [\"apple\", \"orange\", \"banana\", \"grapes\", \"lemon\"]\nconsole.log(macedonia)\n\n// Añadir al final\nmacedonia.push(\"strawberries\")\nconsole.log(macedonia)\n\n// Añadir al principio\nmacedonia.unshift(\"pear\")\nconsole.log(macedonia)\n\n// Eliminar del final\nmacedonia.pop()\nconsole.log(macedonia)\n\n// Eliminar del principio\nmacedonia.shift()\nconsole.log(macedonia)\n\n// Eliminar una cantidad concreta desde un punto\nmacedonia.splice(3, 1)\nconsole.log(macedonia)\n\n// Mostrar el último elemento\nconsole.log(macedonia[macedonia.length-1])\n\n// Ordenar alfabéticamente\nmacedonia.sort()\nconsole.log(macedonia)\n\n\n////////////////////////////////\n// Objects\n////////////////////////////////\n\nlet user = {\n  name: \"d4-n1\",\n  age: 28,\n  favouriteFood: \"pizza\"\n}\nconsole.log(user)\n\n// Añadir un elemento\nuser.gender = \"male\"\nconsole.log(user)\n\n// Actualizar un elemento\nuser.favouriteFood = \"pasta\"\nconsole.log(user)\n\n// Eliminar un elemento\ndelete user.gender\nconsole.log(user)\n\n// .sort() no se puede utilizar en objetos\n\n\n////////////////////////////////\n// Extra\n////////////////////////////////\nlet phoneBook = []\nconst readline = require('readline');\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout\n});\n\n////////////////////////////////\n// Functions\n////////////////////////////////\n\n// Validate phone number\nconst validatePhoneNumber = (number) => {\n  const format = /^\\d{1,11}$/;\n  return format.test(number);\n}\n\n// Add a contact\nconst addContact = () => {\n  rl.question(\"Enter a name \", (userInput) => {\n    let userName = userInput;\n\n    rl.question(\"Enter a phone number \", (userInput) => {\n      let numberValidation = validatePhoneNumber(userInput)\n      if (numberValidation == true) {\n        let phoneNumber = userInput;\n        phoneBook.push({ userName, phoneNumber });\n        console.log(\"\\n✅ Contact added\")\n        menu();\n      } else {\n        console.log(\"Invalid number format\")\n        addContact()\n      }\n    });\n  });\n};\n\n// Display all contacts\nconst displayContacts = () => {\n  for(i = 0; i <= phoneBook.length - 1; i++) {\n    console.log(`· ${phoneBook[i].userName} - ${phoneBook[i].phoneNumber}`)\n  }\n  menu()\n}\n\n// Edit a contact\nconst editContact = () => {\n  rl.question(\"Search a name \", (userName) => {\n    index = findContact(userName)\n    if (index != -1) {\n      rl.question(\"Enter a new name \", (userName) => {\n        phoneBook[index].userName = userName\n    \n        rl.question(\"Enter a new phone number \", (userNumber) => {\n          phoneBook[index].phoneNumber = userNumber\n          console.log(\"\\n✅ Contact updated\")\n          menu()\n        });\n      });\n    } else {\n      console.log(\"\\n😥 There are no results with that name\")\n    }\n    menu()\n  });\n}\n\n// Remove a contact\nconst removeContact = () => {\n  rl.question(\"Search a name \", (userName) => {\n    index = findContact(userName)\n    if (index != -1) {\n      phoneBook.splice([index], 1)\n      console.log(\"\\n✅ Contact removed\")\n    } else {\n      console.log(\"\\n😥 There are no results with that name\")\n    }\n    menu()\n  });\n}\n\n// Find matches in phoneBook\nconst findContact = (name) => {\n  let contact = phoneBook.findIndex((contact) => contact.userName == name)\n  return contact\n}\n\n// Search a contact\nconst searchContact = () => {\n  rl.question(\"Search a name \", (userName) => {\n    index = findContact(userName)\n    if (index != -1) {\n      console.log(\n`\nName: ${phoneBook[index].userName}\nPhone number: ${phoneBook[index].phoneNumber}\n`)\n    } else {\n      console.log(\"\\n😥 There are no results with that name\")\n    }\n    menu()\n  });\n};\n\n// Run Phone book\nconst menu = () => {\n  rl.question(\n`a   Add a new contact\nc   Close the phone book\nd   Display all the contacts\ne   Edit an existing contact\nr   Remove a contact\ns   Search for a contact\nWhat do you want to do?\n`,\n  (userInput) => {\n    userInput = userInput.toLowerCase()\n\n    switch(userInput) {\n      // Add\n      case \"a\":\n        addContact()\n        break;\n\n      // Close  \n      case \"c\":\n        rl.close();\n        break;\n\n       // Display\n      case \"d\":\n        displayContacts()\n        break;\n        \n      // Edit  \n      case \"e\":\n        editContact()\n        break;\n\n      // Remove\n      case \"r\":\n        removeContact()\n        break;\n\n      // Search  \n      case \"s\":\n        searchContact()\n        break;\n        \n      default:\n        console.log(\"Please, choose an valid option\")\n        menu()\n    }\n  })\n}\n\nconsole.log(\"Welcome to Console Book\")\nmenu()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/darkhouselab08.js",
    "content": "// NOTA; Este archivo es la version final del ejerccio Roadmap de JavaScript-darkHouseLab08.js  \n/*\n * #03 ESTRUCTURAS DE DATOS\n */\n\n// --- 1. ARRAYS (Listas) ---\nlet misFrutas = [\"Manzana\", \"Pera\"];\nmisFrutas.push(\"Uva\");             // Inserción\nmisFrutas[1] = \"Mango\";            // Actualización\nmisFrutas.splice(0, 1);            // Borrado (elimina el primer elemento)\nmisFrutas.sort();                  // Ordenación\nconsole.log(\"Array:\", misFrutas);\n\n// --- 2. OBJETOS (Diccionarios) ---\nlet programador = { nombre: \"Jorge\", lenguaje: \"JS\" };\nprogramador.experiencia = \"1 año\"; // Inserción\nprogramador.lenguaje = \"JavaScript\"; // Actualización\ndelete programador.experiencia;    // Borrado\nconsole.log(\"Objeto:\", programador);\n\n// --- 3. SETS (Conjuntos de valores únicos) ---\nlet miSet = new Set([\"a\", \"b\", \"c\"]);\nmiSet.add(\"d\");                    // Inserción\nmiSet.delete(\"a\");                 // Borrado\nconsole.log(\"Set (convertido a array):\", Array.from(miSet));\n\n// --- 4. MAPS (Diccionarios Clave-Valor dinámicos) ---\nlet miMapa = new Map();\nmiMapa.set(\"id\", 1);               // Inserción\nmiMapa.set(\"id\", 2);               // Actualización\nmiMapa.delete(\"id\");               // Borrado\n\n// ------------------------------------------------------------------\n// DIFICULTAD EXTRA: AGENDA DE CONTACTOS\n// ------------------------------------------------------------------\n\nconst readline = require('readline'); // Módulo para leer entrada desde la consola\nconst rl = readline.createInterface({ // Configuración de la interfaz\n    input: process.stdin, \n    output: process.stdout \n});\n\nlet agenda = {};\n\nfunction mostrarMenu() {\n    console.log(\"\\n--- AGENDA DE CONTACTOS ---\"); // Menú de opciones\n    console.log(\"1. Buscar\");\n    console.log(\"2. Insertar\");\n    console.log(\"3. Actualizar\");\n    console.log(\"4. Eliminar\");\n    console.log(\"5. Salir\");\n    \n    rl.question(\"\\nSelecciona una opción: \", (opcion) => {\n        switch (opcion) {\n            case \"1\": buscar(); break;  // Llama a la función correspondiente según la opción\n            case \"2\": insertar(); break;\n            case \"3\": actualizar(); break;\n            case \"4\": eliminar(); break;\n            case \"5\":\n                console.log(\"Saliendo de la agenda...\"); // Mensaje de salida\n                rl.close();\n                break;\n            default:\n                console.log(\"Opción no válida.\"); // Manejo de opción inválida\n                mostrarMenu();\n                break;\n        }\n    });\n}\n\nfunction validarTelefono(tel) {\n    // Verifica que sea un número y que tenga entre 1 y 11 dígitos\n    return !isNaN(tel) && tel.length > 0 && tel.length <= 11;\n}\n\nfunction insertar() {\n    rl.question(\"Nombre del nuevo contacto: \", (nombre) => {\n        rl.question(\"Número de teléfono (máx 11 dígitos): \", (tel) => {\n            if (validarTelefono(tel)) {\n                agenda[nombre] = tel;\n                console.log(\"✅ Contacto guardado con éxito.\"); // Mensaje de éxito\n            } else {\n                console.log(\"❌ Error: El teléfono debe ser numérico y tener máximo 11 dígitos.\");\n            }\n            mostrarMenu(); // Vuelve al menú principal\n        });\n    });\n}\n\nfunction buscar() {\n    rl.question(\"Nombre a buscar: \", (nombre) => {\n        if (agenda[nombre]) {\n            console.log(`🔍 Resultado: ${nombre} -> Tel: ${agenda[nombre]}`);\n        } else {\n            console.log(\"⚠️ Contacto no encontrado.\"); // Mensaje si no se encuentra\n        }\n        mostrarMenu();\n    });\n}\n\nfunction actualizar() {\n    rl.question(\"Nombre del contacto a actualizar: \", (nombre) => {\n        if (agenda[nombre]) {\n            rl.question(\"Nuevo teléfono: \", (nuevoTel) => {\n                if (validarTelefono(nuevoTel)) {\n                    agenda[nombre] = nuevoTel;\n                    console.log(\"✅ Contacto actualizado.\"); // Mensaje de éxito\n                } else {\n                    console.log(\"❌ Error en el formato del teléfono.\"); // Mensaje de error\n                }\n                mostrarMenu();\n            });\n        } else {\n            console.log(\"⚠️ El contacto no existe.\");\n            mostrarMenu();\n        }\n    });\n}\n\nfunction eliminar() {\n    rl.question(\"Nombre del contacto a eliminar: \", (nombre) => {\n        if (agenda[nombre]) {\n            delete agenda[nombre];\n            console.log(\"🗑️ Contacto eliminado.\"); // Mensaje de éxito\n        } else {\n            console.log(\"⚠️ No se encontró el contacto.\"); // Mensaje si no se encuentra\n        }\n        mostrarMenu();\n    });\n}\n\n\nmostrarMenu();\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/dieswae.js",
    "content": "/* Arrays */\n\n// creación\n\nlet myArray = [10, 45, 89, 100, 120];\n\n// inserción\nmyArray.push(70); // añade un elemento al final del array\nmyArray.unshift(0); // añade un elemento al inicio del array\nmyArray.splice(3, 0, 110); // añade un elemento en cierta pocision, en este caso despues del 100 agrega el 110\n\n// borrado\nmyArray.pop(); // elimina el ultimo elemento del array\nmyArray.shift(); // elimina el primer elemento del array\nmyArray.splice(2, 1); // elimina un elemento en la posición 2\n\n// actualización\nmyArray[2] = 58; // actualiza el valor en la posición 2\n\n// ordenación\nmyArray.sort(); // ordena el array\n\n/* Objects */\n\n// creación\nlet myObject = {\n  nombre: 'Diego',\n  edad: 22,\n  ciudad: 'Buenos Aires',\n  hobbies: {\n    inside: 'Practicar coding',\n    outside: 'Jugar Futbol',\n  }\n};\n\n// inserción\nmyObject.trabajo = 'Developer' // mostrara una propiedad nueva con el valor de 'Developer'\n\n// actualización\nmyObject.nombre = 'Diklaus' // actualizara la propiedad nombre a 'Diklaus'\n\n// Borrado\ndelete myObject.trabajo; // borrará a propiedad que acabamos de crear llamada trabajo\n\n/* Sets */\n\n// creación\nlet mySet = new Set([1, 2, 3]);\n\n// inserción\nmySet.add(4);\n\n// borrado\nmySet.delete(2);\n\n/* Maps */\n\n// creación \nlet myMap = new Map();\n\n// inserción\nmyMap.set(1, 'lunes');\nmyMap.set(true, 10);\n\n// borrado\nmyMap.delete('hola1');\n\n// actialización\nmyMap.set('hola2', 'newValue');\n\nconsole.log(map.has(1)); // verificar si existe un valor // sirve para set tambien\n\nconsole.log(map.size); // ver numero de elementos que hay // sirve para set tambien\n\n/* EXTRA */\n\n// realizar operaciones de entrada y salida de manera más sencilla\nconst readline = require('readline');\n\n// Creamos una interfaz de lectura para interactuar con la terminal\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout,\n});\n\n// Objeto para almacenar los contactos\nconst agenda = {}; // Cada contacto debe tener un nombre y un número de teléfono. // Global\n\n// Función para mostrar el menú de operaciones\nfunction mostrarMenu() {\n  console.log('\\n** Agenda de Contactos **');\n  console.log('1. Buscar contacto');\n  console.log('2. Insertar contacto');\n  console.log('3. Actualizar contacto');\n  console.log('4. Eliminar contacto');\n  console.log('5. Mostrar contacto');\n  console.log('6. Salir');\n}\n\n//1. Función para buscar un contacton\nfunction buscarContacto() {\n  rl.question(\n    'Ingrese el nombre o número de teléfono del contacto a buscar: ',\n    (entrada) => {\n      // Verificar si la entrada coincide con un nombre\n      const contactoPorNombre = agenda[entrada];\n\n      // Verificar si la entrada coincide con un número de teléfono\n      const contactoPorTelefono = Object.entries(agenda).find(\n        ([nombre, telefono]) => telefono === entrada\n      );\n\n      if (contactoPorNombre) {\n        console.log(`Teléfono de ${entrada}: ${contactoPorNombre}`);\n      } else if (contactoPorTelefono) {\n        console.log(\n          `Nombre de la persona con el teléfono ${entrada}: ${contactoPorTelefono[0]}`\n        );\n      } else {\n        console.log(`Contacto ${entrada} no encontrado.`);\n      }\n\n      mostrarMenu();\n      seleccionarOperacion();\n      console.log('\\n Viendo si entran los datos:', agenda);\n    }\n  );\n}\n//2. Insertar un conctato\nfunction insertarContacto() {\n  rl.question('Ingrese el nombre del contacto: ', (nombre) => {\n    rl.question('Ingrese el número de teléfono: ', (telefono) => {\n      if (!isNaN(telefono) && telefono.length <= 11) {\n        agenda[nombre] = telefono;\n        console.log(`Contacto ${nombre} insertado con éxito.`);\n      } else {\n        console.log(\n          'Número de teléfono no válido. Debe ser numérico y tener hasta 11 dígitos.'\n        );\n      }\n      mostrarMenu();\n      seleccionarOperacion();\n      console.log('\\n Viendo si entran los datos:', agenda);\n    });\n  });\n}\n//3. actualziar contacto./ isNaN:Is Not a Number(No es un número)\nfunction actualizarContacto() {\n  rl.question('Ingrese el nombre del contacto a actualizar: ', (nombre) => {\n    if (agenda[nombre]) {\n      rl.question('Ingrese el nuevo número de teléfono: ', (telefono) => {\n        if (!isNaN(telefono) && telefono.length <= 11) {\n          agenda[nombre] = telefono;\n          console.log(`Contacto ${nombre} actualizado con éxito.`);\n        } else {\n          console.log(\n            'Número de teléfono no válido. Debe ser numérico y tener hasta 11 dígitos.'\n          );\n        }\n        mostrarMenu();\n        seleccionarOperacion();\n      });\n    } else {\n      mostrarMenu();\n      seleccionarOperacion();\n      console.log('\\n Viendo si entran los datos:', agenda);\n    }\n  });\n}\n//4. Eliminar conctto\nfunction eliminarContacto() {\n  rl.question('Ingrese el nombre del contacto a eliminar: ', (nombre) => {\n    if (agenda[nombre]) {\n      delete agenda[nombre];\n      console.log(`Contacto ${nombre} eliminado con éxito.`);\n    } else {\n      console.log(`Contacto ${nombre} no encontrado.`);\n    }\n    mostrarMenu();\n    seleccionarOperacion();\n    console.log('\\n Viendo si entran los datos:', agenda);\n  });\n}\n//5.Mostrar a los contactos\nfunction mostrarTodosLosContactos() {\n  console.log('\\n** Todos los contactos **');\n  for (const [nombre, telefono] of Object.entries(agenda)) {\n    console.log(`${nombre}: ${telefono}`);\n  }\n  mostrarMenu();\n  seleccionarOperacion();\n  console.log('Viendo si entran los datos:', agenda);\n}\n//6. Función para seleccionar la operación\nfunction seleccionarOperacion() {\n  rl.question('Seleccione una operación (1-6): ', (opcion) => {\n    switch (opcion) {\n      case '1':\n        buscarContacto();\n        break;\n      case '2':\n        insertarContacto();\n        break;\n      case '3':\n        actualizarContacto();\n        break;\n      case '4':\n        eliminarContacto();\n        break;\n      case '5':\n        mostrarTodosLosContactos();\n        break;\n      case '6':\n        console.log('Saliendo del programa.');\n        rl.close();\n        break;\n      default:\n        console.log('Opción no válida. Inténtelo de nuevo.');\n        mostrarMenu();\n        seleccionarOperacion();\n        break;\n    }\n  });\n}\n\n// Inicio del programa\nmostrarMenu();\nseleccionarOperacion();\n\n\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/duendeintemporal.js",
    "content": "/* #3 ESTRUCTURAS DE DATOS  */\n//I use Professional JavaScript for web developers by Matt Frisbie (z-lib.org) for give acurate information in some coments.\n//Also use GPT\n\n/* In JavaScript, there are several built-in data structures that you can use to store and manipulate data. Here’s a list of the most common ones: */\n\nlet log = console.log.bind(console);\n\n/* Primitive Data Types */\n   //Number: Represents both integer and floating-point numbers. \n/* Perhaps the most interesting data type in ECMAScript is Number, which uses the IEEE–754 format\nto represent both integers and floating-point values (also called double–precision values in some languages). To support the various types of numbers, there are several different number literal formats. */\n   let age = 35; // Integer\n   let total = 118.87; // Floating-point      \n   log('age: ', age + ', total: ', total)// age: 35, total: 118.87\n   log(.3)// 0.3\n//To define a floating-point value, you must include a decimal point and at least one number after the decimal point. Although an integer is not necessary before a decimal point, it is recommended.\n\n   let octNum = 045;\n   log(octNum)// 37\n\n   let hexNum = 0x2f;\n   log(hexNum)// 47\n//Note: Numbers created using octal or hexadecimal format are treated as decimal numbers in all arithmetic operations.\n   \n/* There is a special numeric value called NaN, short for Not a Number, which is used to indicate when an operation intended to return a number has failed (as opposed to throwing an error). For exam-\nple, dividing any number by 0 typically causes an error in other programming languages, halting\ncode execution. In ECMAScript, dividing a number by 0 returns NaN, which allows other processing\nto continue. */\n\n/*  The value NaN has a couple of unique properties. First, any operation involving NaN always returns NaN (for instance, NaN /10), which can be problematic in the case of multistep computations. Second, NaN is not equal to any value, including NaN. For example, the following returns false: */\n  \n   log('Hi man how you doing?' * 4)// NaN\n   log(NaN == NaN); // false\n\n//For this reason, ECMAScript provides the isNaN() function. \n\n   log(isNaN(\"04\"))// false cause can be converted to NaN\n\n//Note: there is a particular difference between the Number() and parseInt() function when they are used to convert types(you can search for more information)   \n\n   //String: Represents a sequence of characters. The String data type represents a sequence of zero or more 16-bit Unicode characters. Strings can be delineated by either double quotes (\"), single quotes ('), or backticks (`)\n\n   let dreamyGirl = \"Lucy\";\n   let song = dreamyGirl + ' in the sky with dimonds';\n   let song_info = `\"${song}\" is a song from The Beatles that allude to the LSD`\n   log(song_info)// \"Lucy in the sky with dimonds\" is a song from The Beatles that allude to the LSD\n\n   /* Character Literals\nThe String data type includes several character literals to represent nonprintable or otherwise useful characters: */\n/* LITERAL MEANING\n\\n New line\n\\t Tab\n\\b Backspace\n\\r Carriage return\n\\f Form feed\n\\\\ Backslash (\\)\n\\' Single quote (')—used when the string is delineated by single quotes. Example: 'He\nsaid, \\'hey.\\''.\n\\\" Double quote (\")—used when the string is delineated by double quotes. Example:\n\"He said, \\\"hey.\\\"\".\n\\` Backtick (`)—used when the string is delineated by backticks. Example: `He said,\n\\`hey.\\``.\n\\xnn A character represented by hexadecimal code nn (where n is a hexadecimal digit\n0-F). Example: \\x41 is equivalent to \"A\".\n\\unnnn A Unicode character represented by the hexadecimal code nnnn (where n is a\nhexadecimal digit 0-F). Example: \\u03a3 is equivalent to the Greek character Σ. */\n\n//Template literals also support the ability to define tag functions\n  let num1 = 40;\n  let num2 = 80;\n\n  let sum = `${num1} + ${num2} = ${num1 + num2}`;\n  log(sum)// \"40 + 80 = 120\"\n\n/* Raw Strings\nIt is also possible to use template literals to give you access to the raw template literal contents without being converted into actual character representations, such as a new line or Unicode character. This can be done by using the String.raw tag function, which is available by default. */\n// Unicode demo\n// \\u57A8 is the 垨  character. \n\n/* Info: The character 𗞨 (yǐ) is often associated with the meaning of \"to be\" or \"to exist.\" However, it is important to note that this character is quite rare and may not be found in everyday usage or standard dictionaries. It may appear in historical texts or specific contexts.(gpt brings me this last info, I type an aleatory unicode secuence) */\n\n log(`\\u57A8`); // 垨   or  ?  if you run in Console with Node\n log(String.raw`\\u57A8`); // \\u57A8\n// Newline demo\n log(`first line\\nsecond line`);\n// first line\n// second line\n log(String.raw`first line\\nsecond line`); // \"first line\\nsecond line\" \n\n\n   /* Boolean: Represents a logical entity and can have two values: `true` and `false`. The Boolean type is one of the most frequently used types in ECMAScript and has only two literalvalues: true and false. These values are distinct from numeric values, so true is not equal to 1, and false is not equal to 0. */\n   let isChecked = true;\n   log(!isChecked)// false\n //Note that the Boolean literals true and false are case–sensitive, so True and False (and other mixings of uppercase and lowercase) are valid as identifiers but not as Boolean values.\n   \n   //Undefined: A variable that has been declared but has not yet been assigned a value.\n    let somebody;\n    log(somebody)// undefined\n    let explicitlyUndefined = void(0);\n    log(explicitlyUndefined)// undefined\n  //Note: the use of void(0) is deprecated cause allow some javascript injection that can cause vulnerabilities in the structure of the code.  \n\n   //Null: Represents the intentional absence of any object value. Is common to initialize objects with null value.  That way, you can explicitly check for the value null to determine if the variable has been filled with an object reference at a later time.\n    let animals = null;\n    log(animals)// null\n\n   //Symbol: A unique and immutable primitive value, often used as object property keys. The purpose is guaranteed unique identifier that does not risk property collision.\n   const Id = Symbol('xm');\n   const otherid = Symbol('xm');\n   log('equal symbols: ', Id == otherid)// false\n\n  /* You can also use symbols as object's properties .We'll use a common property name like email, but we'll use a symbol to ensure that this property is unique and not easily accessible or overridden. */\n\n\n// Create a unique symbol for the email property\nconst emailSymbol = Symbol('email');\n\nclass User {\n    constructor(name, email) {\n        this.name = name;\n        this[emailSymbol] = email; // Use the symbol as the key for the email property\n    }\n\n    // Method to get the email\n    getEmail() {\n        return this[emailSymbol];\n    }\n}\n\n// Create a new user\nconst user1 = new User('Barbarella', 'softbaby@something.com');\n\nconsole.log(user1.name); // Barbarella\nconsole.log(user1.getEmail()); // softbaby@something.com\n\n// Trying to access the email property directly\nconsole.log(user1[emailSymbol]); // softbaby@something.com\nconsole.log(user1.email); // undefined, as 'email' is not a property of the object\n\n\n   //BigInt: Represents integers with arbitrary precision.\n   let bigNumber = BigInt(765466743212345679874653358945321);\n   log(bigNumber)// 765466743212345679874653358945321\n\n  /*  Note: Many modern cryptographic libraries and implementations do use BigInt or similar constructs to handle large integers, especially for operations that involve large prime numbers, modular arithmetic, and other mathematical computations common in cryptography.  */\n\n\n/*  Reference Data Types */\n\n  // Object: A collection of key-value pairs. Objects can store multiple values as properties and methods who can interact with that properties.\n\n  let debian = {\n      name: 'Debian',\n      description: 'Ardilla parlante cuyo nucleo esta basado en un Sistema Operativo del mismo nombre, lucha contra el Sistema establecido y habita más alla del Borde(el Universo conocido)',\n      location: 'No Found',\n\n      speak: ()=> {\n        console.log(this.description)\n      }\n  }\n   \n    log(debian.description)// Ardilla parlante cuyo nucleo esta basado en un Sistema Operativo del mismo nombre, lucha contra el Sistema establecido y habita más alla del Borde(el Universo conocido)\n\n  // Array: A special type of object used to store ordered collections of values. Arrays can hold elements of any type and are indexed numerically.\n\n  let friends = ['Susan', 'Maryatta','Denise','Luna', 'Kena', 'Maria']\n  log(friends) \n  // Function: A special type of object that can be called to perform a specific task. Functions can also be stored in variables, passed as arguments, and returned from other functions.\n\n  let from = 4, to = 12; \n  const randomValue = (from, to)=> {\n    return Math.floor(Math.random() * (to - from + 1)) + from;\n  }\n\n  let count = from;\n  while(count < to){\n      log('random value: ', randomValue(from, to));\n      count++;\n  }\n//Logs: numbers between 4 and 12 inclusive\n/* Specialized Data Structures */\n   //Set: A collection of unique values. Sets can store any type of value, and duplicate values are automatically removed.\n\n   let uniqueNumbers = new Set([4, 4, 3, 5, 8, 1, 8, 1, 7]);\n   log(uniqueNumbers); //  Set {4, 3, 5, 8, 1, 7 }\n\n   //Map: A collection of key-value pairs where keys can be of any type. Maps maintain the insertion order of their elements.\n   \n   let map = new Map();\n   map.set('gopi_name', 'Khamala');\n   map.set('age', 35);\n   log(map.get('gopi_name')); //  Khamala\n\n   //WeakSet: Similar to a Set, but it holds \"weak\" references to its values, allowing for garbage collection if there are no other references to the object.\n   \n   let weakSet = new WeakSet();\n   let obj = {};\n   weakSet.add(obj);\n   log(weakSet.has(obj)); //  true\n\n   //WeakMap: Similar to a Map, but it holds \"weak\" references to its keys, allowing for garbage collection if there are no other references to the key object.\n\n   let weakMap = new WeakMap();\n   let keyObj = {};\n   weakMap.set(keyObj, \"crasylady\");\n   log(weakMap.get(keyObj)); //  crazylady\n\n   //Note: garbage collection allow memory management by automatically allocating what is needed and reclaiming memory that is no longer being used. \n\n     /* Typed Arrays */ \n  /* Typed arrays in JavaScript provide a way to work with binary data directly in memory. They are particularly useful for handling raw binary data, such as in scenarios involving graphics, audio, and network communications. \n  They provide a way to work with binary data in a more efficient manner. Examples include `Int8Array`, `Uint8Array`, `Float32Array`, etc. */\n\n   //int8Array: Represents an array of 8-bit integers.\n   let int8Array = new Int8Array([-3, 5, -8, 99, 76]);\n   log(int8Array)// [-3, 5, -8, 99, 76]\n\n   //Uint8Array: Represents an array of 8-bit unsigned integers.\n   let uint8Array = new Uint8Array([1, 2, 3]);\n   \n   //Uint8ClampedArray: Represents an array of 8-bit unsigned integers clamped to the range [0, 255].\n   let uint8ClampedArray = new Uint8ClampedArray([-1, 256, 100]);\n\n   \n   //Int16Array: Represents an array of 16-bit signed integers.\n   let int16Array = new Int16Array([1, -2, 3]);\n   \n  // Uint16Array: Represents an array of 16-bit unsigned integers.\n   let uint16Array = new Uint16Array([1, 2, 3]);\n   \n  // Int32Array: Represents an array of 32-bit signed integers.\n   let int32Array = new Int32Array([1, -2, 3]);\n   \n   //Uint32Array: Represents an array of 32-bit unsigned integers.\n   let uint32Array = new Uint32Array([1, 2, 3]);\n   \n  // Float32Array: Represents an array of 32-bit floating-point numbers.\n   let float32Array = new Float32Array([1.5, 2.5, 3.5]);\n   \n  // Float64Array: Represents an array of 64-bit floating-point numbers.\n   let float64Array = new Float64Array([1.5, 2.5, 3.5]);\n   \n  // BigInt64Array: Represents an array of 64-bit signed integers (BigInt).\n   let bigInt64Array = new BigInt64Array([1n, 2n, 3n]);\n   \n  // BigUint64Array: Represents an array of 64-bit unsigned integers (BigInt).\n   let bigUint64Array = new BigUint64Array([1n, 2n, 3n]);\n   log(bigUint64Array)/* Logs:\n  BigUint64Array(3) [ {}, {}, {} ]\n   0: 1n\n   1: 2n\n   2: 3n\n   buffer: ArrayBuffer { byteLength: 24 }\n   byteLength: 24\n   byteOffset: 0\n   length: 3\n   <prototype>: BigUint64Array.prototype { … } */\n\n   window.addEventListener('load', function(){\n    const body = document.querySelector('body');\n    const title = document.createElement('h1');\n    \n    body.style.setProperty('background', '#000');\n    body.style.setProperty('text-align', 'center');\n    \n    title.textContent = 'Retosparaprogramadores #3.';\n    title.style.setProperty('font-size', '3.5vmax')\n    title.style.setProperty('color', '#fff');\n    title.style.setProperty('line-height', '100vh');\n    \n    body.appendChild(title);\n    \n    alert('Retosparaprogramadores #3. Please open the Browser Developer Tools.');\n    log( 'Retosparaprogramadores #3')// this will be logged at the end cause the nature of window event\n});\n\n\n\n\n\n/*   EXTRA DIFFICULTY (optional):\n   Create a contact book via the terminal.\n       You must implement functionalities for searching, inserting, updating, and deleting contacts.\n       Each contact must have a name and a phone number.\n       The program first asks which operation you want to perform, and then the necessary data to carry it out.\n       The program cannot allow the input of non-numeric phone numbers and those with more than 11 digits (or the number of digits you choose).\n       An option to terminate the program should also be provided.\n*/\n\n//Node.js was used to achieve interaction with the console.\n//Then you should copy the exercise, save it with a .js extension, and run it in a terminal using the command node plus the name of the file.\n/*\n   const rl = require('readline').createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nlet contacts = [];\n\nfunction showMenu(){\n    console.log(\"--- List of Contacts ---\");\n    console.log(\"1. Insert Contact\");\n    console.log(\"2. Buscar Contact\");\n    console.log(\"3. Update Contact\");\n    console.log(\"4. Delate Contact\");\n    console.log(\"5. Exit\");\n    rl.question(\"Chose and Option: \", (option) => {\n        switch (option) {\n            case '1':\n                insertContact();\n                break;\n            case '2':\n                searchContact();\n                break;\n            case '3':\n                updateContact();\n                break;\n            case '4':\n                delateContact();\n                break;\n            case '5':\n                console.log(\"living the program...\");\n                rl.close();\n                break;\n            default:\n                console.log(\"No Valid Option. Try again.\");\n                showMenu();\n        }\n    });\n}\n\n\nfunction askQuestion(query){\n    return new Promise(resolve => {\n        rl.question(query, resolve);\n    });\n}\n\nasync function insertContact(){\n  try {\n        const name = await askQuestion(\"Type the contact name: \");\n        \n        const telefone = await askQuestion(\"Type the telephone number (11 digits): \");\n        if (!/^\\d{11}$/.test(telefone)) {\n            console.log(\"Invalid telephone number. Must be a numeric value and have 11 digits.\");\n            return showMenu(); \n        }\n    \n        const email = await askQuestion(\"Type the email of the contact: \");\n        const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$/;\n        if (!emailRegex.test(email)) {\n            console.log(\"Invalid email. Must be a valid email address.\");\n            return showMenu(); \n        }\n    \n        contacts.push({ name, telefone, email });\n        console.log(`Contact ${name} added.`);\n    \n  } catch (error) {\n      console.error(\"An error occurred:\", error.message);\n  } finally {\n      showMenu(); \n  }\n}\n\nfunction searchContact(){\n    rl.question(\"Ingrese el name del contact a search: \", (name) => {\n        const contact = contacts.find(c => c.name.toLowerCase() === name.toLowerCase());\n        if (contact) {\n            console.log(`Contact found: ${contact.name}, Telefone: ${contact.telefone}, Email: ${contact.email}`);\n        } else {\n            console.log(\"Contact not found.\");\n        }\n        showMenu();\n    });\n}\n\nasync function updateContact(){\n  try {\n        const name = await askQuestion(\"Type the name of the contact to update: \");\n        const contact = contacts.find(c => c.name.toLowerCase() === name.toLowerCase());\n    \n        if (contact) {\n            const telefone = await askQuestion(\"Type the new number of telephone (11 digits): \");\n            if (/^\\d{11}$/.test(telefone)) {\n                contact.telefone = telefone;\n                console.log(`Contact ${name} updated with new number.`);\n            } else {\n                console.log(\"Invalid telephone number. Must be a numeric value and have 11 digits.\");\n            }\n    \n            const email = await askQuestion(\"Type the email of the contact: \");\n            const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$/;\n            if (emailRegex.test(email)) {\n                contact.email = email; \n                console.log(`Contact ${name} updated with new email.`);\n            } else {\n                console.log(\"Invalid email. Must be a valid email address.\");\n            }\n        } else {\n            console.log(\"Contact not found.\");\n        }\n  } catch (error) {\n      console.error(\"An error occurred:\", error.message);\n  } finally {\n      showMenu(); \n  }\n}\n\n\nfunction delateContact(){\n    rl.question(\"Type the name of the contact to delate: \", (name) => {\n        const index = contacts.findIndex(c => c.name.toLowerCase() === name.toLowerCase());\n        if (index !== -1) {\n            contacts.splice(index, 1);\n            console.log(`Contact ${nombre} delated.`);\n        } else {\n            console.log(\"Contact not found.\");\n        }\n        showMenu();\n    });\n}\n\nshowMenu();\n\n*/\n /*  /^(?=.{1,254}$)(?=.{1,64}@)([a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+)(?<!\\.)(?<!\\.\\.)@[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+$/i  */\n\n//Regular Expression Breakdown\n\n  //  (?=.{1,254}$): Ensures that the total length of the email does not exceed 254 characters.\n\n  //  (?=.{1,64}@): Ensures that the local part (before the @) does not exceed 64 characters.\n\n  //  (?<!\\.) and (?<!\\.\\.): Ensures that the local part does not end with a period and does not contain consecutive periods.\n\n  //  [a-zA-Z0-9]: Allows uppercase letters in the local part and in the domain.\n\n  //  (?:\\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+: Ensures that the domain has at least one period and that each part of the domain follows the length rules.\n\n\n  "
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/elianisdev.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\n// Creación de estructuras de datos en JavaScript\n// Array\nconst array = [1, 2, 3, 4, 5];\nconsole.log(array);\n\n// Operaciones de inserción\narray.push(6);\nconsole.log(array);\n\n// Operaciones de borrado\narray.pop();\nconsole.log(array);\n\n// Operaciones de actualización\narray[0] = 0;\nconsole.log(array);\n\n// Operaciones de ordenación\narray.sort();\nconsole.log(array);\n\n// Object\nconst object = {\n  name: 'Elianis',\n  age: 25,\n  country: 'Colombia'\n};\nconsole.log(object);\n\n// Operaciones de inserción\nobject.email = '';\nconsole.log(object);\n\n\n\n// Creación de una agenda de contactos\nconst contacts = [];\n\nfunction addContact(name, phone) {\n  contacts.push({ name, phone });\n\n  console.log('Contact added successfully');\n\n}\n\nfunction searchContact(name) {\n  const contact = contacts.find(contact => contact.name === name);\n\n  if (contact) {\n    console.log(contact);\n  } else {\n    console.log('Contact not found');\n  }\n}\n\nfunction updateContact(name, phone) {\n  const contact = contacts.find(contact => contact.name === name);\n\n  if (contact) {\n    contact.phone = phone;\n    console.log('Contact updated successfully');\n  } else {\n    console.log('Contact not found');\n  }\n}\n\nfunction deleteContact(name) {\n  const index = contacts.findIndex(contact => contact.name === name);\n\n  if (index !== -1) {\n    contacts.splice(index, 1);\n    console.log('Contact deleted successfully');\n  } else {\n    console.log('Contact not found');\n  }\n}\n\nfunction isPhoneNumber(phone) {\n  return /^\\d{11}$/.test(phone);\n}\n\nfunction main() {\n  let option;\n\n  do {\n    console.log('1. Add contact');\n    console.log('2. Search contact');\n    console.log('3. Update contact');\n    console.log('4. Delete contact');\n    console.log('5. Exit');\n\n    option = prompt('Choose an option: ');\n\n    switch (option) {\n      case '1':\n        const name = prompt('Enter the name: ');\n        let phone;\n\n        do {\n          phone = prompt('Enter the phone number: ');\n        } while (!isPhoneNumber(phone));\n\n        addContact(name, phone);\n        break;\n      case '2':\n        const search = prompt('Enter the name to search: ');\n        searchContact(search);\n        break;\n      case '3':\n        const update = prompt('Enter the name to update: ');\n        let newPhone;\n\n        do {\n          newPhone = prompt('Enter the new phone number: ');\n        } while (!isPhoneNumber(newPhone));\n\n        updateContact(update, newPhone);\n        break;\n      case '4':\n        const del = prompt('Enter the name to delete: ');\n        deleteContact(del);\n        break;\n      case '5':\n        console.log('Goodbye!');\n        break;\n      default:\n        console.log('Invalid option');\n        break;\n    }\n  } while (option !== '5');\n}\n\nmain();\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/emaerniquez.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n*/\n\n// Array\nlet miArray = [1,2,3,4,5,6,7,8,9,10];\nmiArray.push(11); // inserción\nmiArray[2] = 4; // actualización\nmiArray.splice(0,1); // borrado\nmiArray.sort() // ordenación\n\n// Sets\nlet miSet = new Set([1,2,3,4,5,6,7,8,10])\nmiSet.add(11) // inserción\nmiSet.delete(2) // borrado\n\n// Objectos\nlet miObjeto = {\n    nombre: 'Emanuel',\n    edad: 20,\n    facultad: 'ITU',\n    carerra: 'Desarrollo de software'\n}\n\nmiObjeto['semestres'] = 6 // inserción\ndelete facultad // borrado\nmiObjeto['edad'] = 21 // actualización\n\n// Map\nlet miMapa = new Map([\n    [\"God of War\", 1],\n    [\"Mortal kotmbat\", 2],\n    [\"Batman\", 3],\n]);\nmiMapa.set(\"Mario\", 4); // Inserción\nmiMapa.delete(\"Mortal kotmbat\"); // Borrado\nmiMapa.set(\"God of War\", 5); // Actualización"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/emedevelopa.js",
    "content": "// ESTRUCUTRAS DE DATOS\n\n// Arrays\nlet myArray = [1, 2, 3 ,4];\nconsole.log(myArray);\n\n//Insercción\nmyArray.push(5); //Inserta 5 en el último lugar.\nconsole.log(myArray);\n\nmyArray.unshift(0); //Inserta 0 en primer lugar.\nconsole.log(myArray);\n\n//Borrado\nmyArray.shift(0); //Borra el primer dato.\nconsole.log(myArray);\n\nmyArray.pop(5); //Borra el último dato.\nconsole.log(myArray); \n\n//Actualización\nmyArray[1] = 13; // La posición 1 se actualiza.\nconsole.log(myArray);\n\n\n//Objetos\nlet user = {\n    name: \"María\",\n    age: 33,\n    town: \"Madrid\",\n    \"number of kids\": 2,\n};\nconsole.log(user);\n\n//Actualiza\nuser.name = \"Paca\";\nconsole.log(user);\n\n//Inserta nueva propiedad\nuser[\"favourite color\"] = \"green\";\nconsole.log(user);\n\n//Borrado\ndelete user.age;\nconsole.log(user);\n\n// Creación\nlet miMapa = new Map();\n\n// Inserción\nmiMapa.set('clave1', 'valor1');\nmiMapa.set('clave2', 'valor2');\n\n// Borrado\nmiMapa.delete('clave1');\n\n// Actualización\nmiMapa.set('clave2', 'nuevoValor');\n\n\n// Sets\n\n// Creación\nlet miSet = new Set([1, 2, 3]);\n\n// Inserción\nmiSet.add(4);\n\n// Borrado\nmiSet.delete(2);\n\n//EXTRA\nconst readline = require (\"readline\"); //Importa el módulo readline de node.js que proporciona una interfaz para leer ddatos desde un flujo de entrada (terminal)\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n}); // Se crea una interfaz de comandos q utiliza el módulo \"readline\". process.stdin representa la entrada estandar (teclado) y process.stdout la salida (pantalla).\n\nconst agenda = new Map(); //Aquí se almacenan los datos. Un map es una estructura de datos que asocia claves con valores.\n\nfunction mostrarMenu () {\n    console.log(\"\\n1. Mostrar contactos\");  //n1 salto de linea.\n    console.log(\"2. Añadir contacto\");\n    console.log(\"3. Actualizar contacto\");\n    console.log(\"Eliminar contacto\");\n    console.log(\"Salir\");\n}\n\nfunction mostrarContactos () {\n    console.log(\"\\n---Contactos---\");\n    if (agenda.size === 0) {\n        console.log(\"La agenda está vacía\");\n    } else {\n        agenda.forEach((telefono, nombre) => {\n            console.log(`${nombre}: ${telefono}`);\n        });\n    }\n}\n\nfunction agregarContacto () {\n    rl.question(\"Nombre del contacto\", (nombre) => {\n        rl.question(\"Número de teléfono: \", (telefono) => {\n            if (/^\\d{1,11}$/.test(telefono)) {   ///^\\d{1,11}$/ significa que la cadena debe consistir en entre 1 y 11 dígitos y no debe contener ningún otro carácter.\n                agenda.set(nombre, telefono);\n                console.log(\"Contacto añadido\");\n            } else {\n                console.log(\"Número no válido\");\n            }\n            mostrarMenu();\n        });\n    });\n}  \n\nfunction actualizarContacto () {\n    rl.question(\"Nombre del contacto a actualizar: \", (nombre) => {\n        if (agenda.has(nombre)) {\n            rl.question(\"Nuevo número de teléfono \", (telefono) => {\n                if(/^\\d{1,11}$/.test(telefono)) {\n                    agenda.set(nombre, telefono);\n                    console.log(\"Contacto actualizado\");\n                } else {\n                    console.log(\"Número no válido\");\n                }\n                mostrarMenu();\n            });\n        } else {\n            console.log(\"Contacto no encontrado\");\n            mostrarMenu();\n        }\n    });\n}\n\nfunction eliminarContacto () {\n    rl.question(\"Nombre del contacto a elimiar \", (nombre) => {\n        if (agenda.has(nombre)) {\n            agenda.delete(nombre);\n            console.log(\"Contacto eliminado\");\n        } else {\n            console.log(\"Contacto no encontrado\");\n        }\n        mostrarMenu();\n    })\n}\n\nfunction opcionUser (opcion) {\n    switch (opcion) {\n        case \"1\":\n            mostrarContactos();\n            break;\n        case \"2\":\n            agregarContacto ();\n            break;\n        case \"3\":\n            actualizarContacto ();\n            break;\n        case \"4\":\n            eliminarContacto ();\n            break;\n        case \"5\":\n            console.log(\"Saliendo del programa\");\n            rl.close();\n            break;\n        default:\n            console.log(\"Opción no válida. Introduce un número del 1 al 5\");\n    }\n}\n\n\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/eulogioep.js",
    "content": "// Importamos el módulo readline para manejar la entrada del usuario\nconst readline = require('readline');\n\n// Creamos una interfaz de readline\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\n// Función para ejemplificar las estructuras de datos en JavaScript\nfunction ejemplosEstructurasDatos() {\n    // Array: equivalente a ArrayList en Java\n    let array = ['Java', 'Python', 'JavaScript'];\n    console.log('Array:', array);\n\n    // Set: conjunto sin duplicados\n    let set = new Set([1, 2, 2, 3, 4]);\n    console.log('Set:', set);\n\n    // Map: equivalente a HashMap en Java\n    let map = new Map();\n    map.set('Uno', 1);\n    map.set('Dos', 2);\n    map.set('Tres', 3);\n    console.log('Map:', map);\n\n    // Operaciones\n    array.splice(1, 1); // Borrado (elimina 'Python')\n    array[1] = 'TypeScript'; // Actualización\n    array.sort(); // Ordenación\n\n    console.log('Array después de operaciones:', array);\n}\n\n// Función principal para la agenda de contactos\nfunction agendaContactos() {\n    let agenda = new Map();\n\n    function mostrarMenu() {\n        console.log(\"\\n--- Agenda de Contactos ---\");\n        console.log(\"1. Buscar contacto\");\n        console.log(\"2. Añadir contacto\");\n        console.log(\"3. Actualizar contacto\");\n        console.log(\"4. Eliminar contacto\");\n        console.log(\"5. Mostrar todos los contactos\");\n        console.log(\"6. Salir\");\n        rl.question(\"Seleccione una opción: \", manejarOpcion);\n    }\n\n    function manejarOpcion(opcion) {\n        switch (opcion) {\n            case '1':\n                buscarContacto();\n                break;\n            case '2':\n                anadirContacto();\n                break;\n            case '3':\n                actualizarContacto();\n                break;\n            case '4':\n                eliminarContacto();\n                break;\n            case '5':\n                mostrarContactos();\n                break;\n            case '6':\n                console.log(\"¡Hasta luego!\");\n                rl.close();\n                return;\n            default:\n                console.log(\"Opción no válida.\");\n                mostrarMenu();\n        }\n    }\n\n    function buscarContacto() {\n        rl.question(\"Ingrese el nombre del contacto: \", (nombre) => {\n            if (agenda.has(nombre)) {\n                console.log(`Teléfono de ${nombre}: ${agenda.get(nombre)}`);\n            } else {\n                console.log(\"Contacto no encontrado.\");\n            }\n            mostrarMenu();\n        });\n    }\n\n    function anadirContacto() {\n        rl.question(\"Ingrese el nombre del contacto: \", (nombre) => {\n            solicitarTelefono((telefono) => {\n                agenda.set(nombre, telefono);\n                console.log(\"Contacto añadido con éxito.\");\n                mostrarMenu();\n            });\n        });\n    }\n\n    function actualizarContacto() {\n        rl.question(\"Ingrese el nombre del contacto a actualizar: \", (nombre) => {\n            if (agenda.has(nombre)) {\n                solicitarTelefono((telefono) => {\n                    agenda.set(nombre, telefono);\n                    console.log(\"Contacto actualizado con éxito.\");\n                    mostrarMenu();\n                });\n            } else {\n                console.log(\"Contacto no encontrado.\");\n                mostrarMenu();\n            }\n        });\n    }\n\n    function eliminarContacto() {\n        rl.question(\"Ingrese el nombre del contacto a eliminar: \", (nombre) => {\n            if (agenda.delete(nombre)) {\n                console.log(\"Contacto eliminado con éxito.\");\n            } else {\n                console.log(\"Contacto no encontrado.\");\n            }\n            mostrarMenu();\n        });\n    }\n\n    function mostrarContactos() {\n        if (agenda.size === 0) {\n            console.log(\"La agenda está vacía.\");\n        } else {\n            agenda.forEach((telefono, nombre) => {\n                console.log(`${nombre}: ${telefono}`);\n            });\n        }\n        mostrarMenu();\n    }\n\n    function solicitarTelefono(callback) {\n        rl.question(\"Ingrese el número de teléfono (máximo 11 dígitos): \", (telefono) => {\n            if (/^\\d{1,11}$/.test(telefono)) {\n                callback(telefono);\n            } else {\n                console.log(\"Número no válido. Debe ser numérico y tener máximo 11 dígitos.\");\n                solicitarTelefono(callback);\n            }\n        });\n    }\n\n    mostrarMenu();\n}\n\n// Ejecutamos los ejemplos y la agenda\nconsole.log(\"Ejemplos de estructuras de datos en JavaScript:\");\nejemplosEstructurasDatos();\n\nconsole.log(\"\\nIniciando la agenda de contactos...\");\nagendaContactos();"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/fdcorreadev.js",
    "content": "/**\n * javascript tiene estructuras de datos como casi todos los lenguajes, arrays, y objetos \n */\n\n// objetos estan diseñados para tener clave valor\nlet object = { saludar: 'Hola', objeto: 'mundo' }\n\n//funciones que se pueden hacer con los objetos\nlet myCar = new Object()\n\n//opcion1\nmyCar.brand = \"ford\"\nmyCar.reference = \"mustang\"\nmyCar.modelo = 1968\n\n//opcion2\nmyCar[\"brand\"] = \"chevrolet\";\nmyCar[\"reference\"] = \"aveo\";\nmyCar[\"modelo\"] = 2010;\n\nconsole.log(myCar)\n\n// eliminar propiedades no de un object.\n\ndelete myCar.brand\n\nconsole.log(myCar)\n\n//objeto tipo map\nconst map1 = new Map()\n\nconsole.log('objeto tipo map')\nconsole.log(map1)\n\n//para insertar valores \nmap1.set('nombre', 'fabian')\nmap1.set('apellido', 'correa')\nmap1.set('edad', 26)\n\nconsole.log(map1)\n//objener valores\n\nconsole.log(map1.get(\"nombre\"))\n\n//borrar un valor\nconsole.log(\"borrar valores\")\nmap1.delete(\"edad\")\nconsole.log(map1)\n\n//arrays\nlet arrays = ['hola', 'mundo', 'cruel']\n\n// insertar valores, ya sea uno o varios\n\nconsole.log('agregar valores a un array push()')\narrays.push(\"parte\", \"uno\")\nconsole.log(arrays)\n\n//agregar valores al inicio un array\nconsole.log('agregar valores al inicio un array unshift()')\narrays.unshift(\"¡\")\nconsole.log(arrays)\n\n\n//eliminar el ultimo valor del array\nconsole.log('eliminar el ultimo valor del array pop()')\narrays.pop()\nconsole.log(arrays)\n\n//eliminar el valor por indice de un array\nconsole.log('eliminar por el valor del indice de un array splice()')\narrays.splice(4)\nconsole.log(arrays)\n\n//actualizar por indice el valor de un array\nconsole.log('actualizar por indice el valor de un array splice()')\narrays.splice(1, 1, \"hello\")\nconsole.log(arrays)\n\n//actualizar un array\nconsole.log('actualizar por indice array[indice]')\narrays[3] = \"bello\"\nconsole.log(arrays)\n\n//Ordenar un array \nconsole.log('ordenar un array con sort()')\narrays.sort()\nconsole.log(arrays)\n\nconsole.log('nuevo ejemplo para ordenar un array')\nlet newArray = [45, 12, 47, 28, 1, 0, 34, 56, 13, 10]\n\nconsole.log(newArray)\nconsole.log('ordenar un array con sort()')\nnewArray.sort()\nconsole.log(newArray)\n\n\n//ejercicio Extra\n\nconst readline = require('readline')\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n})\n\nlet data = []\n\nfunction validatePhone(valor) {\n    const splitNumber = valor.split('')\n    const validateLenght = true ? splitNumber.length === 10 : false\n    let validateNumbers;\n    if (Number(valor)) {\n        validateNumbers = true\n    } else {\n        validateNumbers = false\n    }\n    return true ? validateLenght === true && validateNumbers === true : false\n}\n\nfunction mostrarMenu() {\n    console.log(`---->> escriba el numero de la tarea que vas a realizar en la agenda <<----`)\n    console.log(`0. salir`)\n    console.log(`1. insercion`)\n    console.log(`2. busqueda`)\n    console.log(`3. actualizacion`)\n    console.log(`4. eliminacion`)\n    console.log(`9. mostrar base`)\n\n    rl.question('Numero: ', (numeroTask) => {\n        processTask(numeroTask)\n    })\n\n}\n\nfunction processTask(numeroTask) {\n    switch (numeroTask) {\n        case '1':\n            console.log()\n            console.log()\n            console.log(`vamos a realizar una insercion`)\n            let contacto = { name: '', telefono: '' }\n            rl.question('Nombre: ', (name) => {\n                contacto.name = name\n                rl.question('telefono: ', (telefono) => {\n                    let longNumber = validatePhone(telefono)\n                    if (longNumber) {\n                        contacto.telefono = telefono\n                        data.push(contacto)\n                        mostrarMenu()\n                    } else {\n                        console.log(`verifica los valores ingresados 10 digitos y deben ser numericos`)\n                        mostrarMenu()\n                    }\n                })\n            })\n            break;\n        case '2':\n            console.log()\n            console.log(`vamos a realizar una busqueda, puedes hacerlo por telefono o nombre`)\n            console.log()\n            rl.question('Ingrese valor de busqueda: ', (dataSearch) => {\n                const findName = data.filter(value => value.name.toLowerCase() === dataSearch.toLowerCase())\n                const findPhone = data.filter(value => value.telefono.toLowerCase() === dataSearch.toLowerCase())\n                if (findName.length > 0) {\n                    findName.forEach(name => {\n                        console.log(`el usuario es: ${name.name} con numero de telefono ${name.telefono}`)\n                    })\n                } else if (findPhone.length > 0) {\n                    findPhone.forEach(phone => {\n                        console.log(`el usuario es: ${phone.name} con numero de telefono ${phone.telefono}`)\n                    })\n                } else {\n                    console.log()\n                    console.log()\n                    console.log(`Este datos no se registro en la agenda registralo`)\n                    console.log()\n                    console.log()\n                }\n                console.log()\n                console.log()\n                mostrarMenu()\n            })\n            break;\n        case '3':\n            console.log(`vamos a realizar una actualizacion`)\n            rl.question('ingresa Valor a Actualizar: ', (dataSearch) => {\n                rl.question('Por cual quieres actualizar: ', (dataReplace) => {\n                    const index = data.findIndex(value => value.name.toLowerCase() === dataSearch.toLowerCase() || value.telefono.toLowerCase() === dataSearch.toLowerCase())\n                    if (index !== -1) {\n                        //Determinar si el valor es un nombre o un telefono\n                        if (isNaN(dataSearch)) {\n                            data[index].name = dataReplace;\n                            console.log()\n                            console.log(`El nombre ${dataSearch} fue actualizado por ${dataReplace} con exito`)\n                            console.log()\n                        } else {\n                            data[index].telefono = dataReplace;\n                            console.log()\n                            console.log(`El telefono ${dataSearch} fue actualizado por ${dataReplace} con exito`)\n                            console.log()\n\n                        }\n                    } else {\n                        console.log()\n                        console.log()\n                        console.log(`Verifique si es usuario se encuentra`)\n                        console.log()\n                        console.log()\n                    }\n                    mostrarMenu()\n                })\n            })\n            break;\n        case '4':\n            console.log()\n            console.log(`vamos a realizar una eliminacion`)\n            console.log()\n            rl.question('ingresa Valor a eliminar: ', (dataSearch) => {\n                const findName = data.filter(value => value.name.toLowerCase() === dataSearch.toLowerCase())\n                const findPhone = data.filter(value => value.telefono.toLowerCase() === dataSearch.toLowerCase())\n                if (data.includes(findName[0]) || data.includes(findPhone[0])) {\n                    const index = data.indexOf(findName[0])\n                    data.splice(index, 1)\n                    console.log(`el usuario fue eliminado con exito`)\n                } else {\n                    console.log()\n                    console.log()\n                    console.log(`Verifique si es usuario se encuentra`)\n                    console.log()\n                    console.log()\n                }\n                mostrarMenu()\n            })\n\n            break;\n        case '9':\n            console.log()\n            console.log()\n            console.table(data)\n            console.log()\n            console.log()\n            mostrarMenu()\n            break;\n        case '0':\n            console.log(`!nos vemos pronto fue un placer¡`)\n            rl.close()\n            break;\n        default:\n            console.log(\"el valor que escribiste no esta en el menu\")\n            mostrarMenu()\n            break;\n    }\n}\n\nmostrarMenu()\n// rl.question('Que desea hacer: ', (task) => {\n//     const tasks = [\"busqueda\", \"insercion\", \"actualizacion\", \"eliminacion\"]\n//     if(tasks.includes(task)){\n//         console.log(task)\n//     } else {\n//         console.log(`recuerda que tienes 4 opciones: \"busqueda\", \"insercion\", \"actualizacion\", \"eliminacion\"`)\n//     }\n// })\n\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/fernandog25.js",
    "content": "//Array\nvar lista = [4,6,1,7,5,8,2,3]\nconsole.log(\"Lista original: \" + lista)\n//Inserción\nlista.push(0) //Agrego un elemento al final de la lista \nconsole.log(\"Nuevo elemento: \" + lista)\nlista.unshift(9) //Agrego un elemento al principio de la lista\nconsole.log(\"Nuevo elemento: \" + lista)\nlista.splice(2,0,10) //Agrego el 10 en la posición 3\nconsole.log(\"Nuevo elemento: \" + lista)\n//Borrado\nlista.pop() //Elimino el ultimo elemento de la lista\nconsole.log(\"Elemento borrado: \" + lista)\nlista.shift() //Elimino el primer elemento de la lista\nconsole.log(\"Elemento borrado: \" + lista)\nlista.splice(3,1) //Elimino el elemento en la posición 4\nconsole.log(\"Elemento borrado: \" + lista)\n//Actualización\nlista[6] = 9 //Reemplazo el elemento de la posición 7\nconsole.log(\"Lista actualizada: \" + lista)\n//Ordenación\nlista.sort(function(a,b){return a-b}) //Ordeno la lista de menor a mayor\nconsole.log(\"Lista ordenada: \" + lista)\nlista.reverse(function(a,b){return a-b}) //Ordeno la lista de mayor a menor\nconsole.log(\"Lista ordenada: \" + lista)\n\n//Objet\nvar persona = \n{\n    nombre: \"Fernando\",\n    apellido: \"Gomez\",\n    edad: 29\n}\nconsole.log(persona)\n//Inserción\npersona[\"ciudad\"] = \"Rosario\"\nconsole.log(\"Objeto con nueva propiedad: \" + persona)\n//Borrado\ndelete persona.apellido\nconsole.log(\"Objeto con propiedad borrada: \" + persona)\n//Actualización\npersona.nombre = \"Fer\"\nconsole.log(\"Objeto con propiedad actualizada: \" + persona)\n\n//Map\nvar mapa = new Map()\n//Inserción\nmapa.set(\"rojo\", \"red\")\nmapa.set(\"verde\", \"green\")\nmapa.set(\"azul\", \"blue\")\nconsole.log(mapa)\n//Borrado\nmapa.delete(\"verde\")\nconsole.log(mapa)\n//Actualización\nmapa.set(\"rojo\", \"vermelho\")\nconsole.log(mapa)\n\n//Set\nvar numeros = new Set([4,6,1,7])\nconsole.log(numeros)\n//Inserción\nnumeros.add(0)\nconsole.log(numeros)\n//Borrado\nnumeros.delete(1) \nconsole.log(numeros)\n\n/*DIFICULTAD EXTRA (opcional):\nCrea una agenda de contactos por terminal.\n- Debes implementar funcionalidades de búsqueda, inserción, actualización\n  y eliminación de contactos.\n- Cada contacto debe tener un nombre y un número de teléfono.\n- El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n  y a continuación los datos necesarios para llevarla a cabo.\n- El programa no puede dejar introducir números de teléfono no númericos y con más\n de 11 dígitos (o el número de dígitos que quieras).\n- También se debe proponer una operación de finalización del programa.*/\n\n\nvar agenda = new Map()\nvar nombre\nvar telefono\nvar op\n\nimport readline from 'readline'\n\n\nfunction obtenerInput(pregunta) \n{ \n  const rl = readline.createInterface\n  (\n    { \n      input: process.stdin, output: process.stdout\n    })\n    return new Promise((resolve) => \n      { rl.question(pregunta, (respuesta) => \n        { resolve(respuesta); rl.close(); \n\n        }); \n      });\n}\n\n\nconsole.log(\"\\n1- Buscar contacto\")\nconsole.log(\"2- Insertar contacto\")\nconsole.log(\"3- Actualizar contacto\")\nconsole.log(\"4- Eliminar contacto\")\nconsole.log(\"5- Salir\")\n\n\ndo\n{\n  op = await obtenerInput('Por favor, ingresa un valor: ') \n\n  switch (op)\n  {\n    case \"1\":\n      nombre = await obtenerInput(\"Ingrese nombre a buscar: \")\n      if (agenda.get(nombre))\n        console.log(\"El telefono de \" + nombre + \" es: \" + agenda.get(nombre))\n      else console.log(\"El contacto \" + nombre + \" no exixte en la agenda\")\n      break\n    case \"2\":\n      nombre = await obtenerInput('Nombre: ')\n      telefono = await obtenerInput('Telefono: ')\n      if (!isNaN(telefono) && telefono.length > 0 && telefono.length < 12)\n      {\n        agenda.set(nombre, telefono)\n        console.log(\"El contacto fue credo con exito\")\n      }\n      else console.log(\"Tiene que ingresar un numero con menos de 12 digitos\")\n      break\n    case \"3\":\n      nombre = await obtenerInput('Ingrese el nombre del contacto a actualizar: ')\n      if (agenda.get(nombre))\n      {\n        telefono = await obtenerInput('Ingrese el nuevo numero de telefono: ')\n        if (!isNaN(telefono) && telefono.length > 0 && telefono.length < 12)\n        {\n          agenda.set(nombre, telefono)\n          console.log(\"El contacto fue actualizado con exito\")\n        }\n        else console.log(\"Tiene que ingresar un numero con menos de 12 digitos\")\n      }\n      else console.log(\"El contacto \" + nombre + \" no exixte en la agenda\")\n      break\n    case \"4\":\n      nombre = await obtenerInput('Ingrese el nombre del contacto a eliminar: ')\n      if (agenda.get(nombre))\n      {\n        agenda.delete(nombre)\n        console.log(\"El contacto \" + nombre + \" fue eliminado con éxito\")\n      }\n      else console.log(\"El contacto \" + nombre + \" no exixte en la agenda\")\n      break\n  }\n}while (op != 5)\n\n\n  \n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/fravelz.js",
    "content": "// Array ******************************************************************** //\n\nlet lista = [4, 6, 1, 7, 5, 8, 2, 3]\nconsole.log(\"Lista original: \" + lista)\n\n//Inserción\nlista.push(0) //Agrego un elemento al final de la lista \n// [4, 6, 1, 7, 5, 8, 2, 3, 0]\n\nlista.unshift(9) //Agrego un elemento al principio de la lista\n// [9, 4, 6, 1, 7, 5, 8, 2, 3, 0]\n\nlista.splice(2, 0, 10) //Agrego el 10 en la posición 3\n// [9, 4, 10, 6, 1, 7, 5, 8, 2, 3, 0]\n\n//Borrado\nlista.pop() //Elimino el ultimo elemento de la lista\n// [9, 4, 10, 6, 1, 7, 5, 8, 2, 3]\n\nlista.shift() //Elimino el primer elemento de la lista\n// [4, 10, 6, 1, 7, 5, 8, 2, 3]\n\nlista.splice(3, 1) //Elimino el elemento en la posición 4\n// [4, 10, 6, 7, 5, 8, 2, 3]\n\n//Actualización\nlista[6] = 9 //Reemplazo el elemento de la posición 7\n// [4, 10, 6, 7, 5, 8, 9, 3]\n\n//Ordenación\nlista.sort(function (a, b) { return a - b }) //Ordeno la lista de menor a mayor\n// [3, 4, 5, 6, 7, 8, 9, 10]\n\nlista.reverse(function (a, b) { return a - b }) //Ordeno la lista de mayor a menor\n// [10, 9, 8, 7, 6, 5, 4, 3]\n\n// Objet ******************************************************************** //\nvar person = {\n    name: \"Fra\",\n    lastname: \"velz\",\n    age: 9999999n\n}\n\n//Inserción\nperson[\"ciudad\"] = \"Rosario\"\n// { name: 'Fra', lastname: 'velz', age: 9999999n, ciudad: 'Rosario' }\n\n//Borrado\ndelete person.lastname\n// { name: 'Fra', age: 9999999n, ciudad: 'Rosario' }\n\n//Actualización\nperson.name = \"Javier\"\n// { name: 'Javier', age: 9999999n, ciudad: 'Rosario' }\n\n// Map ********************************************************************** //\n\nlet mapa = new Map()\n\n//Inserción\nmapa.set(\"rojo\", \"red\")\nmapa.set(\"verde\", \"green\")\nmapa.set(\"azul\", \"blue\")\n// { 'rojo' => 'red', 'verde' => 'green', 'azul' => 'blue' }\n\n//Borrado\nmapa.delete(\"verde\")\n// { 'rojo' => 'red', 'azul' => 'blue' }\n\n//Actualización\nmapa.set(\"rojo\", \"vermelho\")\n// { 'rojo' => 'vermelho', 'azul' => 'blue' }\n\nlet mapa2 = new WeakMap();\n\n/* { <object> => 'valor' } a diferencia del Map, el WeakMap no impide que el\nobjeto clave sea recolectado por el garbage collector si no hay otras referencias\na él. Esto significa que si el objeto clave es eliminado, la entrada\ncorrespondiente en el WeakMap también será eliminada automáticamente.\n*/\n\n// Set ********************************************************************** //\n\nlet numeros = new Set([4, 6, 1, 7])\n// { 4, 6, 1, 7 }\n\n//Inserción\nnumeros.add(0)\n// { 4, 6, 1, 7, 0 }\n\n//Borrado\nnumeros.delete(1)\n// { 4, 6, 7, 0 }\n\nlet sets = new WeakSet();\n\n/* { <object>, <object>, ... } a diferencia del Set, el WeakSet no impide que los\nobjetos sean recolectados por el garbage collector si no hay otras referencias\na ellos. Esto significa que si un objeto es eliminado, la entrada correspondiente\nen el WeakSet también será eliminada automáticamente.\n*/\n\n/* *****************************************************************************\nDIFICULTAD EXTRA (opcional):\nCrea una agenda de contactos por terminal.\n- Debes implementar funcionalidades de búsqueda, inserción, actualización\n    y eliminación de contactos.\n- Cada contacto debe tener un nombre y un número de teléfono.\n- El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n    y a continuación los datos necesarios para llevarla a cabo.\n- El programa no puede dejar introducir números de teléfono no númericos y con más\n    de 11 dígitos (o el número de dígitos que quieras).\n- También se debe proponer una operación de finalización del programa.\n***************************************************************************** */\n\n\nvar agenda = new Map()\nvar nombre\nvar telefono\nvar op\n\nimport readline from 'readline'\n\n\nfunction obtenerInput(pregunta) {\n    const rl = readline.createInterface({ input: process.stdin, output: process.stdout })\n\n    return new Promise((resolve) => {\n        rl.question(pregunta, (respuesta) => {\n            resolve(respuesta); rl.close();\n        });\n    });\n}\n\ndo {\n    console.log(`\\n****************************************`);\n    console.log(\"* 1. Search contact\");\n    console.log(\"* 2. Add contact\");\n    console.log(\"* 3. Update contact\");\n    console.log(\"* 4. Delete contact\");\n    console.log(\"* 5. Exit\");\n    console.log(`****************************************`);\n\n    op = await obtenerInput('* > Please enter an option: ');\n\n    switch (op) {\n        case \"1\":\n            nombre = await obtenerInput(\"* > Enter name to search: \");\n\n            if (agenda.get(nombre))\n                console.log(`The phone number for ${nombre} is: ${agenda.get(nombre)}`);\n            else\n                console.log(`The contact ${nombre} does not exist in the agenda`);\n            break;\n\n        case \"2\":\n            nombre = await obtenerInput('Name: ');\n            telefono = await obtenerInput('Phone number: ');\n\n            if (!isNaN(telefono) && telefono.length > 0 && telefono.length < 12) {\n                agenda.set(nombre, telefono);\n                console.log(\"The contact was successfully created\");\n            } else {\n                console.log(\"You must enter a number with less than 12 digits\");\n            }\n\n            break;\n\n        case \"3\":\n            nombre = await obtenerInput('* > Enter the name of the contact to update: ');\n\n            if (agenda.get(nombre)) {\n                telefono = await obtenerInput('* > Enter the new phone number: ');\n                if (!isNaN(telefono) && telefono.length > 0 && telefono.length < 12) {\n                    agenda.set(nombre, telefono);\n                    console.log(\"The contact was successfully updated\");\n                } else {\n                    console.log(\"You must enter a number with less than 12 digits\");\n                }\n            } else {\n                console.log(`The contact ${nombre} does not exist in the agenda`);\n            }\n            break;\n\n        case \"4\":\n            nombre = await obtenerInput('* > Enter the name of the contact to delete: ');\n            if (agenda.get(nombre)) {\n                agenda.delete(nombre);\n                console.log(`The contact ${nombre} was successfully deleted`);\n            } else {\n                console.log(`The contact ${nombre} does not exist in the agenda`);\n            }\n            break;\n\n        default: console.log(\"Invalid option. Please try again.\");\n    }\n} while (op != \"5\");\n\n// > Autor: Fravelz\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/garos01.js",
    "content": "// Creación de un arreglo\nlet miArreglo = [1, 2, 3, 4, 5];\n\n// Inserción\nmiArreglo.push(6);\n\n// Borrado\nmiArreglo.splice(2, 1); // Elimina el elemento en el índice 2\n\n// Actualización\nmiArreglo[0] = 10;\n\n// Ordenación\nmiArreglo.sort();\n\nconsole.log(miArreglo);\n\n// Creación de un objeto\nlet miObjeto = {\n  clave1: \"valor1\",\n  clave2: \"valor2\",\n  clave3: \"valor3\",\n};\n\n// Inserción\nmiObjeto.clave4 = \"valor4\";\n\n// Borrado\ndelete miObjeto.clave2;\n\n// Actualización\nmiObjeto.clave1 = \"nuevo_valor\";\n\n// No hay ordenación en los objetos, ya que son estructuras basadas en claves\n\nconsole.log(miObjeto);\n\n// Creación de un conjunto\nlet miConjunto = new Set([1, 2, 3, 4, 5]);\n\n// Inserción\nmiConjunto.add(6);\n\n// Borrado\nmiConjunto.delete(3);\n\n// No hay actualización en los conjuntos, ya que los elementos son únicos\n\n// No hay ordenación en los conjuntos, ya que son desordenados por naturaleza\n\nconsole.log(miConjunto);\n\n// Creación de un mapa\nlet miMapa = new Map([\n  [\"clave1\", \"valor1\"],\n  [\"clave2\", \"valor2\"],\n  [\"clave3\", \"valor3\"],\n]);\n\n// Inserción\nmiMapa.set(\"clave4\", \"valor4\");\n\n// Borrado\nmiMapa.delete(\"clave2\");\n\n// Actualización\nmiMapa.set(\"clave1\", \"nuevo_valor\");\n\n// No hay ordenación en los mapas, ya que son estructuras basadas en claves\n\nconsole.log(miMapa);\n\n// Ejercicio extra\nconst readline = require(\"readline\");\n\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout,\n});\n\nconst usuarios = {};\nconst identificadores = [];\n\nfunction new_user() {\n  rl.question(\"Ingrese el nombre: \", function (nombre) {\n    let numero_telefono;\n    do {\n      numero_telefono = readlineSync.question(\n        \"Ingrese el numero de telefono: \"\n      );\n      if (!/^\\d{10}$/.test(numero_telefono)) {\n        console.log(\"Error: El numero debe contener 10 digitos\");\n      }\n    } while (!/^\\d{10}$/.test(numero_telefono));\n\n    const identificador = identificadores.length + 1;\n    identificadores.push(identificador);\n\n    usuarios[identificador] = { nombre, numero_telefono };\n\n    console.log(\n      `Usuario guardado correctamente. Identificador: ${identificador}, nombre: ${nombre}`\n    );\n\n    startMenu();\n  });\n}\n\nfunction show_user(id_usuario) {\n  if (id_usuario in usuarios) {\n    const usuario = usuarios[id_usuario];\n    console.log(`Informacion del usuario con ID ${id_usuario}`);\n    console.log(`Nombre: ${usuario.nombre}`);\n    console.log(`Numero de telefono: ${usuario.numero_telefono}`);\n  } else {\n    console.log(`No se encontro el usuario con ID ${id_usuario}`);\n  }\n\n  startMenu();\n}\n\n// ... (resto de las funciones sin cambios)\n\n// Menú Principal\nfunction startMenu() {\n  console.log(\"\\nMenú:\");\n  console.log(\"A.- Registrar nuevos usuarios\");\n  console.log(\"B.- Listar usuarios\");\n  console.log(\"C.- Ver información de un usuario por ID\");\n  console.log(\"D.- Editar información de un usuario por ID\");\n  console.log(\"E.- Eliminar usuario por ID\");\n  console.log(\"F.- Finalizar el programa\");\n\n  rl.question(\"Seleccione una opción (A/B/C/D/E/F): \", function (opcion) {\n    opcion = opcion.toUpperCase();\n\n    if (opcion === \"A\") {\n      new_user();\n    } else if (opcion === \"B\") {\n      list_user();\n    } else if (opcion === \"C\") {\n      rl.question(\n        \"Ingrese el ID del usuario que desea ver: \",\n        function (id_usuario) {\n          show_user(parseInt(id_usuario, 10));\n        }\n      );\n    } else if (opcion === \"D\") {\n      rl.question(\n        \"Ingrese el ID del usuario que desea editar: \",\n        function (id_usuario) {\n          edit_user(parseInt(id_usuario, 10));\n        }\n      );\n    } else if (opcion === \"E\") {\n      rl.question(\n        \"Ingrese el ID del usuario que desea eliminar: \",\n        function (id_usuario) {\n          delete_user(parseInt(id_usuario, 10));\n        }\n      );\n    } else if (opcion === \"F\") {\n      console.log(\"Programa finalizado.\");\n      rl.close();\n    } else {\n      console.log(\n        \"Opción no válida. Por favor, seleccione una opción correcta.\"\n      );\n      startMenu();\n    }\n  });\n}\n\nstartMenu();\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/gianbordon.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\n// Arrays\n\nconsole.group(\"Arrays:\");\n\n//\n// Creación de un Array\n//\nlet numeros = [1, 2, 3, 4, 6, 7, 8, 9];\nconsole.log(\"Array inicial:\", numeros);\n\n//\n// Adición de elementos\n//\nnumeros.push(10); // Agrega al final\nconsole.log(\"Adición con push:\", numeros);\n\nnumeros.unshift(0); // Agrega al principio\nconsole.log(\"Adición con unshift:\", numeros);\n\n//\n// Eliminación de elementos\n//\nnumeros.pop(); // Elimina el último\nconsole.log(\"Eliminación con pop:\", numeros);\n\nnumeros.shift(); // Elimina el primero\nconsole.log(\"Eliminación con shift:\", numeros);\n\n//\n// Eliminación con splice\n//\nlet numerosII = numeros.splice(4, 1); // Elimina desde el índice 4, 1 elemento\nconsole.log(\n    \"Eliminación con splice:\",\n    \"Resultado:\",\n    numeros,\n    \"Eliminado:\",\n    numerosII\n);\n\n//\n// Modificación de un elemento\n//\nnumeros[3] = 10; // Cambia el valor en el índice 3\nconsole.log(\"Modificación de valor:\", numeros);\n\n//\n// Ordenación del array\n//\nnumeros.sort((a, b) => a - b); // Orden ascendente\nconsole.log(\"Array ordenado:\", numeros);\n\n//\n// Métodos adicionales\n//\nconsole.log(\"¿Incluye el 3?:\", numeros.includes(3));\nconsole.log(\"Índice del número 3:\", numeros.indexOf(3));\nconsole.log(\"Array invertido:\", numeros.reverse());\n\nconsole.groupEnd();\n\n/// Objetos\n\nconsole.group(\"Objetos:\");\n\n//\n// Creación de un objeto\n//\nlet persona = {\n    name: \"Gian\",\n    age: 26,\n    email: \"gianbordonpresti@hotmail.com\",\n    saludar() {\n        console.log(`Hola, soy ${this.name}`);\n    },    \n};\nconsole.log(\"Objeto inicial:\", persona);\n\n//\n// Acceso a propiedades del objeto\n//\nconsole.log(\"Acceso con punto:\", persona.name);\nconsole.log(\"Acceso con corchetes:\", persona[\"age\"]);\n\n//\n// Métodos útiles de objetos\n//\nconsole.log(\"Claves del objeto:\", Object.keys(persona));\nconsole.log(\"Valores del objeto:\", Object.values(persona));\nconsole.log(\"Entradas del objeto:\", Object.entries(persona));\n\n//\n// Uso de método dentro del objeto\n//\npersona.saludar();\n\n//\n// Agregar nuevas propiedades\n//\npersona.surname = \"Bordon\";\npersona[\"alias\"] = \"Giasin\";\nconsole.log(\"Después de agregar propiedades:\", persona);\n\n//\n// Eliminar propiedades\n//\ndelete persona.alias;\nconsole.log(\"Después de eliminar alias:\", persona);\n\n//\n// Modificar propiedades existentes\n//\npersona.surname = \"Prestifilippo\";\npersona.age = 34;\nconsole.log(\"Después de modificar propiedades:\", persona);\n\n//\n// Función constructora de objetos\n//\nfunction Person(name, surname, age, alias) {\n    this.name = name;\n    this.surname = surname;\n    this.age = age;\n    this.alias = alias;\n}\n\nconst personaCreada = new Person(\"Estevan\", \"Ruiz\", 23, \"Estevanquito\");\nconsole.log(\"Objeto creado con función constructora:\", personaCreada);\n\nconsole.groupEnd();\n\n// Sets\n\nconsole.group(\"Sets:\");\n\n//\n// Creación de un Set\n//\nlet animal = new Set([\"perro\", \"golden\", 4, \"Adoptado\"]);\nconsole.log(\"Set inicial:\", animal);\n\n//\n// Agregar elementos al Set\n//\nanimal.add(\"Familia Perez\");\nconsole.log(\"Después de agregar un elemento:\", animal);\n\n//\n// Eliminar elementos del Set\n//\nanimal.delete(\"perro\");\nanimal.delete(4);\nconsole.log(\"Después de eliminar elementos:\", animal);\n\n//\n// Verificar existencia de un valor\n//\nconsole.log(\"¿Contiene 'Adoptado'?:\", animal.has(\"Adoptado\"));\n\n//\n// Obtener tamaño del Set\n//\nconsole.log(\"Tamaño del Set:\", animal.size);\n\n//\n// Convertir Set en Array y viceversa\n//\nlet arr = Array.from(animal);\nconsole.log(\"Convertido a Array:\", arr);\n\nanimal = new Set(arr);\nconsole.log(\"Convertido nuevamente a Set:\", animal);\n\n//\n// Metodo Clear\n//\nanimal.clear();\nconsole.log(\"Set después de clear():\", animal);\n\nconsole.groupEnd();\n\n// Maps\n\nconsole.group(\"Maps:\");\n\n//\n// Declaración de un Map vacío\n//\nlet materia = new Map();\nconsole.log(\"Map vacío:\", materia);\n\n//\n// Inicialización con pares clave-valor\n//\nmateria = new Map([\n    [\"name\", \"Lengua\"],\n    [\"Horario\", \"11hs a 13hs\"],\n    [\"Profesor\", \"Dominguez\"],\n]);\nconsole.log(\"Map inicializado:\", materia);\n\n//\n// Inserción de un nuevo valor\n//\nmateria.set(\"curso\", \"3º B\");\nconsole.log(\"Después de insertar 'curso':\", materia);\n\n//\n// Modificación de un valor existente\n//\nmateria.set(\"Horario\", \"9 a.m. a 11 a.m.\");\nconsole.log(\"Después de modificar 'Horario':\", materia);\n\n//\n// Eliminación de un valor\n//\nmateria.delete(\"Profesor\");\nconsole.log(\"Después de eliminar 'Profesor':\", materia);\n\n//\n// Verificación de existencia (has)\n//\nconsole.log(\"¿Existe 'Horario'?:\", materia.has(\"Horario\"));\nconsole.log(\"¿Existe 'Profesor'?:\", materia.has(\"Profesor\"));\n\n//\n// Obtener claves, valores y entradas\n//\nconsole.log(\"Claves:\", materia.keys());\nconsole.log(\"Valores:\", materia.values());\nconsole.log(\"Entradas:\", materia.entries());\n\n//\n// Tamaño del Map\n//\nconsole.log(\"Tamaño del Map:\", materia.size);\n\n//\n// Transformar en Array y viceversa\n//\nlet arrDesdeMap = Array.from(materia);\nconsole.log(\"Map convertido a Array:\", arrDesdeMap);\n\nmateria = new Map(arrDesdeMap);\nconsole.log(\"Array reconvertido a Map:\", materia);\n\n//\n// Vaciar el Map\n//\nmateria.clear();\nconsole.log(\"Después de clear():\", materia);\n\nconsole.groupEnd();\n\n//\n// EXTRA\n//\n\nconst agenda = [];\nconst readline = require(\"readline\");\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout,\n});\n\nfunction menu() {\n    console.clear();\n\n    console.log(\"╔═══════════════════════════════════════╗\");\n    console.log(\"║         📒 AGENDA DE CONTACTOS        ║\");\n    console.log(\"╠═══════════════════════════════════════╣\");\n    console.log(\"║ 1. Agregar contacto                   ║\");\n    console.log(\"║ 2. Buscar contacto                    ║\");\n    console.log(\"║ 3. Actualizar contacto                ║\");\n    console.log(\"║ 4. Eliminar contacto                  ║\");\n    console.log(\"║ 5. Mostrar todos                      ║\");\n    console.log(\"║ 0. Salir                              ║\");\n    console.log(\"╚═══════════════════════════════════════╝\");\n\n    rl.question(\"Seleccioná una opción (1 al 6): \", (opc) => {\n        switch (opc) {\n        case \"1\":\n            console.log(\"→ Elegiste AGREGAR contacto.\");\n            addContact()\n            break;\n        case \"2\":\n            console.log(\"→ Elegiste BUSCAR contacto.\");\n            searchContact()\n            break;\n        case \"3\":\n            console.log(\"→ Elegiste ACTUALIZAR contacto.\");\n            modifyContact()\n            break;\n        case \"4\":\n            console.log(\"→ Elegiste ELIMINAR contacto.\");\n            deleteContact()\n            break;\n        case \"5\":\n            console.log(\"→ Elegiste MOSTRAR todos.\");\n            showContacts()\n            break;\n        case \"0\":\n            console.log(\"→ Programa finalizado.\");\n            rl.close();\n            break;\n        default:\n            console.log(\"❌ Opción inválida.\");\n            setTimeout(menu, 1500); \n        }\n    });\n}\n\nfunction Contact(name, num) {\n    this.name = name;\n    this.num = num;\n}\n\nfunction verifyNumber(num) {\n    const onlyNumbers = /^\\d+$/;\n    if (!onlyNumbers.test(num)) {\n        console.log('❌ El valor ingresado no contiene solo números');\n        return null;\n    }\n    if (num.length >= 11) {\n        return num;\n    } else {\n        console.log('❌ El número no es mayor o igual a 11');\n        return null;\n    }\n}\n\nfunction addContact() {\n    rl.question(\"Introduzca el nombre del contacto que desea agregar: \", (name) => {\n        const requestNumber = () => {\n            rl.question(\"Introduzca el número del contacto (exactamente 11 dígitos): \", (num) => {\n                const numeroVerificado = verifyNumber(num);\n                if (numeroVerificado) {\n                    const contact = new Contact(name, numeroVerificado);\n                    agenda.push(contact);\n                    console.log(`✅ Contacto agregado: ${contact.name} - ${contact.num}`);\n                    backToMenu();\n                } else {\n                    console.log(\"🔁 Número inválido. Intente nuevamente.\\n\");\n                    requestNumber(); \n                }\n            });\n        };\n        requestNumber(); \n    });\n}\n\nfunction contactFound(value){\n    let index = - 1\n    agenda.forEach((contact, i)=>{\n        if(contact.name.toLowerCase().includes(value.toLowerCase()) ||              \n            (contact.num.toLowerCase().includes(value.toLowerCase()))){\n                console.log(`🔎 Contacto encontrado: ${contact.name} - ${contact.num}`);\n                index = i;\n        }\n    })\n    if (index === -1) {\n        console.log(\"❌ No se encontró ningún contacto con ese criterio.\");\n    }\n    backToMenu()\n}\n\nfunction searchContact(name){\n    rl.question(\"🔍 Ingrese el nombre o número a buscar: \", (name) =>{\n        contactFound(name)\n    })\n    backToMenu()\n}\n\nfunction searchIndex(value){\n    let index = - 1\n    agenda.forEach((contact, i)=>{\n        if(contact.name.toLowerCase().includes(value.toLowerCase()) ||              \n            (contact.num.toLowerCase().includes(value.toLowerCase()))){\n                index = i;\n                return\n        }\n    })\n    return index\n}\n\nfunction modifyContact(){\n    rl.question(\"🔍 Ingrese el nombre o número a buscar: \", (name) =>{\n        const index = searchIndex(name)\n        if(index === -1){\n            console.log(\"❌ No se encontró ningún contacto con ese criterio.\");\n            return backToMenu()\n        }\n        console.log(`🔎 Contacto encontrado: ${agenda[index].name} - ${agenda[index].num}`);\n        console.log(\"╔═══════════════════════════════════════╗\");\n        console.log(\"║ 1. Nombre                             ║\");\n        console.log(\"║ 2. Número                             ║\");\n        console.log(\"╚═══════════════════════════════════════╝\");\n        rl.question(\"Seleccione la opcion que desea modificar? \", (res) =>{\n\n            switch (res) {\n                case \"1\":\n                    rl.question(\"Ingrese el nuevo nombre:\",(name)=>{\n                        agenda[index].name = name\n                        console.log(\"✅ Nombre actualizado.\")\n                        backToMenu()\n                    })\n                    break;\n                case \"2\":\n                    rl.question(\"Ingrese el nuevo numero\", (num)=>{\n                        const numVerf = verifyNumber(num)\n                        if(numVerf){\n                            agenda[index].num = num\n                            console.log(\"✅ Número actualizado.\")\n                        } else {\n                            console.log(\"❌ Número inválido. No se modificó.\");\n                        }\n                        backToMenu()\n                    })\n                    break\n                default: \n                    console.log(\"❌ Opción no válida.\");\n                    backToMenu()\n                    break;\n            }\n        })\n    })\n}\n\nfunction deleteContact(){\n    rl.question(\"🔍 Ingrese el nombre o número a buscar: \", (name) =>{\n        const index = searchIndex(name)\n        if(index === -1){\n            console.log(\"❌ No se encontró ningún contacto con ese criterio.\");\n            return backToMenu()\n        } else {\n            console.log(`⚠️ Eliminando contacto: ${agenda[index].name} - ${agenda[index].num}`);\n            agenda.splice(index, 1);\n            console.log(\"✅ Contacto eliminado correctamente.\");\n        }\n        backToMenu()\n    })\n}\n\nfunction showContacts() {\n    console.log(\"📋 Contactos en la agenda:\");\n    if (agenda.length === 0) {\n        console.log(\"→ No hay contactos aún.\");\n    } else {\n        agenda.forEach((c, i) => {\n            console.log(`${i + 1}. ${c.name} - ${c.num}`);\n        });\n    }\n    backToMenu();\n}\n\n\nfunction backToMenu() {\n    rl.question(\"Presioná ENTER para volver al menú...\", () => {\n        menu();\n    });  \n}\nmenu();"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/giovanyosorio.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\n// Ejemplo de creación de estructuras de datos en JavaScript\n// -------------------------------------------------------\n\n// Array\n// -----\nvar array = [1, 2, 3, 4, 5];\nconsole.log(array);\n\n// Inserción\narray.push(6);\narray.unshift(0);\nconsole.log(array);\n\n// Borrado\narray.pop();\narray.shift();\nconsole.log(array);\n\n\n\n// Actualización\narray[0] = 0;\nconsole.log(array);\n\n// Ordenación\narray.sort();\nconsole.log(array);\n\n// Diccionario\n// -----------\nvar diccionario = {\n    \"nombre\": \"Giovany\",\n    \"apellido\": \"Osorio\",\n    \"edad\": 28\n};\nconsole.log(diccionario);\n\n// Inserción\ndiccionario[\"sexo\"] = \"Hombre\";\nconsole.log(diccionario);\n\n// Borrado\ndelete diccionario.sexo;\nconsole.log(diccionario);\n\n// Actualización\ndiccionario.nombre = \"Giovany Andres\";\nconsole.log(diccionario);\n\n// Conjunto\n// --------\nvar conjunto = new Set();\nconjunto.add(1);\nconjunto.add(2);\nconjunto.add(3);\n\nconsole.log(conjunto);\n\n// Inserción\nconjunto.add(4);\nconsole.log(conjunto);\n\n// Borrado\nconjunto.delete(4);\nconsole.log(conjunto);\n\n\n// Cola\n// ----\nvar cola = [];\ncola.push(1);\ncola.push(2);\ncola.push(3);\nconsole.log(cola);\n\n// Inserción\ncola.push(4);\nconsole.log(cola);\n\n// Borrado\ncola.shift();\nconsole.log(cola);\n\n// Actualización\ncola[0] = 0;\nconsole.log(cola);\n\n// Dificultad Extra\n// ----------------\nvar contactos = {};\nvar readline = require('readline');\nvar rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nconst opciones=()=>{\n    rl.question('Que desea hacer?\\n1. Buscar contacto\\n2. Insertar contacto\\n3. Actualizar contacto\\n4. Eliminar contacto\\n5. Salir\\n', (answer) => {\n        switch (answer) {\n            case \"1\":\n                buscarContacto();\n                break;\n            case \"2\":\n                insertarContacto();\n                break;\n            case \"3\":\n                actualizarContacto();\n                break;\n            case \"4\":\n                eliminarContacto();\n                break;\n            case \"5\":\n                rl.close();\n                break;\n            default:\n                console.log(\"Opcion no valida\");\n                opcion();\n                break;\n        }\n    });\n\n}\n\n\nfunction buscarContacto() {\n    rl.question(\"ingrese el nombre del contacto que desea buscar: \",(nombre)=>{\n        if(contactos[nombre]){\n            console.log(`Contacto encontrado: ${nombre} Telefono ${contactos[nombre]}`)\n        }\n        else{\n            console.log(\"contacto no existe\")\n        }\n        opciones()\n    })\n}\n\nfunction insertarContacto(){\n    rl.question(\"Ingresa el nombre del contacto: \",(nombre)=>{\n        if(contactos[nombre]){\n            console.log('Este contacto ya existe.');\n            opciones()\n        }\n        else{\n            rl.question('Ingrese el número de teléfono: ', (telefono) => {\n                if(!isNaN(telefono)){\n                contactos[nombre] = telefono;\n                console.log('Contacto insertado con éxito.');\n                console.log(contactos)\n                }else{\n                    console.log('Número de teléfono inválido.');\n                }\n                opciones()\n            })\n        }\n    })\n}\n\nfunction actualizarContacto(){\n    rl.question(\"ingrese el nombre del contacto que quiere actualizar: \",(nombre)=>{\n        if(contactos[nombre]){\n            rl.question(\"ingrese el nuevo numero telefonico: \",(telefono)=>{\n                contactos[nombre] = telefono;\n                console.log('Contacto actualizado con éxito.');   \n                opciones(); \n            })\n           \n        }else{\n            console.log('Contacto no encontrado.') \n            opciones();\n        }\n\n    })\n}\n\nfunction eliminarContacto(){\n    rl.question(\"Ingrese el nombre del contacto a eliminar: \",(nombre)=>{\n        if(contactos[nombre]){\n            delete contactos[nombre]\n            console.log(\"Contacto eliminado con exito\")\n            opciones();\n        }else{\n            console.log(\"no se encontro el contacto a eliminar\")\n        }\n    })\n}\nopciones()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/gonzadev28.js",
    "content": "/*EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.*/\n\n//ARRAY \nlet myArray = [1, 2, 3, 4, 5, 5, 2, 4];\n\nmyArray.push(0);//Insercion en array (agrega numero 0)\ndelete(myArray[0]);//Eliminacion en array en la posicion [0]\nmyArray[5] = 6;//Actualizacion en array (actualiza en la posicion [5])\nmyArray.sort();//Ordenacion de array\n\nconsole.log(myArray);\n\n//OBJETO\nlet persona = {\n    nombre: 'Gonzalo',\n    apellido: 'Lizama',\n    edad: 30,\n};\npersona['ciudad'] = 'Ancud';//Insercion en objeto\ndelete persona.edad;//Eliminacion dentro de objeto\npersona['nombre'] = 'Enrique'; //Actualizacion de 'nombre'\n\nconsole.log(persona);\n\n//MAP\nlet map= new Map([\n    [1, 'Javascript'],\n    [2, 'Python'],\n    [3, 'C++'],\n]);\n\nmap.set(4, 'Java');//Insercion en map\nmap.delete(3); //Elimina elemento con la clave '3' --> 'C++'\nmap.set(2, 'C#');//Actualiza en map elemento con la clave '2'\n\nconsole.log(map);\n\n//SET\nlet mySet = new Set([1, 1, 1, 2, 3, 4, 5]); \n\nmySet.add(6);//Insercion dentro de set\nmySet.delete(1);//Eliminacion dentro de set\n\nconsole.log(mySet);\n\n/*DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.*/\n  \n//Funcion de node.js para enviar y recibir datos por consola \nconst readline = require('readline').createInterface({\n  input: process.stdin,\n  output: process.stdout\n});\n\nconst contactos = {};\n\n//Menu de opciones\nfunction opciones(){\n  console.log('==========================================');\n  console.log('Selecciona una de las siguientes opciones:');\n  console.log('==========================================');\n  console.log('1. Buscar contacto');\n  console.log('2. Ingresar contacto');\n  console.log('3. Actualizar contacto');\n  console.log('4. Eliminar contacto');\n  console.log('5. Salir\\n');\n}\n//switch para cada opcion seleccionada\nfunction selecionaOpcion(){\n  readline.question('Por favor seleccione una opcion: ', (opcion) => {\n    switch (opcion){\n      case '1':\n        buscarContacto();\n        break;\n      case '2':\n        ingresarContacto();\n        break;\n      case '3':\n        actualizarContacto();\n        break;\n      case '4':\n        eliminarContacto();\n        break;\n      case '5':\n        console.log('Saliendo...');\n        readline.close();\n        break;\n      default:('Por favor seleccione una opcion');\n      break;\n    }\n  });\n}\nopciones();\nselecionaOpcion();\n\n//Buscar contacto\nfunction buscarContacto(){\n  readline.question('Ingrese el nombre o telefono para comenzar a buscar: ', (ingresa) => {\n    const busquedaNombre = contactos[ingresa];\n    const busquedaNumero = Object.entries(contactos).find(\n      ([nombre, telefono]) => telefono === ingresa\n    );\n    if(busquedaNombre){\n      console.log(`El telefono de ${ingresa} es: ${busquedaNombre}`);\n    }else if(busquedaNumero){\n      console.log(`El telefono numero ${ingresa} pertenece a: ${busquedaNumero}`);\n    }else{\n      console.log(`Contacto ${contactos} no encontrado`);\n    }\n    opciones();\n    selecionaOpcion();\n  });\n}\n\n//Ingresar contacto\nfunction ingresarContacto(){\n  readline.question('Ingrese el nombre del contacto: ', (nombre) => {\n    readline.question('Ingrese el telefono del contacto: ', (telefono) => {\n      if(!isNaN(telefono) && telefono.length <= 11){\n        contactos[nombre] = telefono;\n        console.log(`${nombre} ha sido ingresado con exito`);\n      }else{\n        console.log('Telefono debe ser numerico y maximo de 11 digitos');\n      }\n      opciones();\n      selecionaOpcion();\n    });\n  });\n}\n\n//Actualizar contacto\nfunction actualizarContacto(){\n  readline.question('Ingrese el nombre del contacto que desea actualizar: ', (nombre) => {\n    if(contactos[nombre]){\n      readline.question('Ingrese el telefono: ', (telefono) => {\n        if (!isNaN(telefono) && telefono.length <= 11){\n          contactos[nombre] = telefono;\n          console.log(`${nombre} ha sido actualizado`);\n        }else{\n          console.log('Telefono debe ser numerico y de maximo 11 digitos');\n        }\n        opciones();\n        selecionaOpcion();\n      });\n    }\n  });\n}\n\n//Eliminar contacto\nfunction eliminarContacto(){\n  readline.question('Ingrese el nombre del contacto que desea eliminar: ', (nombre) => {\n    if(contactos[nombre]){\n      delete contactos[nombre];\n      console.log(`${nombre} ha sido eliminado`);\n    }else{\n      console.log(`${nombre} no se encuentra`);\n    }\n    opciones();\n    selecionaOpcion();\n  });\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/h4ckxel.js",
    "content": "// #03 ESTRUCTURAS DE DATOS\n\n/**\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n */\n\n// 1. Arrays (Coleccion de datos)\nconst pLanguages = ['javascript', 'python', 'c#'];\n// inserción\npLanguages.unshift('java'); // insercion al principio del array\npLanguages.push('kotlin'); // insercion al final del array\npLanguages[5] = 'php'; // insercion en una posicion especificada del array\npLanguages.length; // -> 6\nconsole.log(pLanguages); // -> ['java', 'javascript', 'python', 'c#', 'kotlin', 'php']\n// borrado\npLanguages.shift(); // borra el primer elemento del array\npLanguages.pop(); // borra el ultimo elemento del array\npLanguages.length; // -> 4\ndelete pLanguages[2]; // borra el elemento en una posicion especificada pero mantiene el espacio vacío\npLanguages.length; // -> 4\nconsole.log(pLanguages); // -> ['javascript', 'python', 'empty', 'kotlin']\n// actualización\npLanguages[2] = 'c++'; // actualiza el elemento en una posicion especificada\nconsole.log(pLanguages); // -> ['javascript', 'python', 'c++', 'kotlin']\n// ordenación\npLanguages.sort(); // ordena el array de menor a mayor por defecto (alfabeticamente)\nconsole.log(pLanguages); // -> ['c++', 'javascript', 'kotlin', 'python']\npLanguages.reverse(); // invierte el orden del array\nconsole.log(pLanguages); // -> ['python', 'kotlin', 'javascript', 'c++']\n\n// 2. Objects (Colecciones de pares clave-valor)\nconst languages = {\n\tjavascript: '1995',\n\tpython: '1991',\n\tc: '1972',\n};\n// inserción y actualización\nlanguages.java = '995';\nlanguages['kotlin'] = '2011';\nObject.defineProperty(languages, 'php', {\n\tvalue: '1995',\n\twritable: true,\n\tenumerable: true,\n\tconfigurable: true,\n});\nconsole.log(languages); // -> {javascript: '995', python: '1991', c: '1972', java: '1995', kotlin: '2011', php: '1995'}\nlanguages.java = '1995'; // actualiza la propiedad java\nconsole.log(languages); // -> {javascript: '1995', python: '1991', c: '1972', java: '1995', kotlin: '2011', php: '1995'}\n// borrado\ndelete languages.c; // borra la propiedad c y su valor del objeto languages\n\n// 3. Set (Colecciones de valores unicos (no duplicados))\nconst numbers = new Set([0]);\n// inserción\nnumbers.add(1);\nnumbers.add(2);\nnumbers.add(3);\nnumbers.add(1); // este no ingresa al array por ser duplicado\nnumbers.size; // -> 4\nnumbers.has(0); // -> true\nnumbers.has(5); // -> false\nconsole.log(numbers); // -> {0, 1, 2, 3}\n// borrado\nnumbers.delete(0);\nnumbers.size; // -> 3\nconsole.log(numbers); // -> {1, 2, 3}\n\n// 4. Map (Coleccion asociativa de datos)\nconst numbersMap = new Map([['zero', 0]]);\n// inserción\nnumbersMap.set('one', 1);\nnumbersMap.set('two', 2);\nnumbersMap.set('three', 3);\nnumbersMap.size; // -> 4\nconsole.log(numbersMap); // -> {zero: 0, one: 1, two: 2, three: 3}\n// actualización\nnumbersMap.set('zero', 'cero');\nnumbersMap.set('one', 'uno');\nnumbersMap.set('two', 'dos');\nnumbersMap.set('three', 'tres');\nconsole.log(numbersMap); // -> {zero: 'cero', one: 'uno', two: 'dos', three: 'tres'}\n// borrado\nnumbersMap.delete('zero');\nnumbersMap.size; // -> 3\nconsole.log(numbersMap); // -> {one: 'uno', two: 'dos', three: 'tres'}\n\n/** DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\n/**\n * Use el entorno nodejs para poder programar la agenda del\n * ejercicio extra.\n * */\nimport { createInterface } from 'readline';\n\nconst rl = createInterface({\n\tinput: process.stdin,\n\toutput: process.stdout,\n});\n\nconst contacts = {\n\tTest: {\n\t\tname: 'Test Name',\n\t\tphone: '3012456789',\n\t},\n};\n\nconst regex = /^[0-9]{10}$/; // 10 digitos - solo numeros\n\nmain();\n\nfunction main() {\n\tconsole.log('\\nWelcome to Contacts.\\n');\n\n\tconsole.log('  0. All Contacts');\n\tconsole.log('  1. Search');\n\tconsole.log('  2. Add');\n\tconsole.log('  3. Update');\n\tconsole.log('  4. Delete');\n\tconsole.log('  5. Exit');\n\n\trl.question('\\nChoose an option: ', (action) => {\n\t\tfunctionSet(action);\n\t});\n}\n\nfunction backToMain() {\n\trl.question('\\nPress enter to back to menu', () => {\n\t\tconsole.clear();\n\t\tmain();\n\t});\n}\n\nfunction validatePhone(phone) {\n\treturn regex.test(phone);\n}\n\nfunction functionSet(action) {\n\tif (action === '0') {\n\t\tshowContacts(contacts);\n\t} else if (action === '1') {\n\t\tconsole.log('\\n==Search Contact==\\n');\n\t\trl.question('Enter the contact nick: ', (nick) => {\n\t\t\tsearchContact(contacts, nick);\n\t\t});\n\t} else if (action === '2') {\n\t\tconsole.log('\\n==Add a Contact==\\n');\n\t\trl.question('Enter the contact nick: ', (nick) => {\n\t\t\trl.question('Enter the contact name: ', (name) => {\n\t\t\t\trl.question('Enter the contact phone: ', (phone) => {\n\t\t\t\t\taddContact(contacts, nick, name, phone);\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\t} else if (action === '3') {\n\t\tconsole.log('\\n==Update Contact==\\n');\n\t\trl.question('Enter the contact nick: ', (nick) => {\n\t\t\trl.question('Enter the contact name: ', (name) => {\n\t\t\t\trl.question('Enter the contact phone: ', (phone) => {\n\t\t\t\t\tupdateContact(contacts, nick, name, phone);\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\t} else if (action === '4') {\n\t\tconsole.log('\\n==Delete Contact==\\n');\n\t\trl.question('Enter the contact nick: ', (nick) => {\n\t\t\tdeleteContact(contacts, nick);\n\t\t});\n\t} else if (action === '5') {\n\t\texitContacts();\n\t} else {\n\t\tconsole.log('Invalid option. Select an option from 0 to 5');\n\t\tsetTimeout(() => {\n\t\t\tconsole.clear();\n\t\t\tmain();\n\t\t}, 2000);\n\t}\n}\n\nfunction showContacts(obj) {\n\tconsole.log('\\nHere are your contacts:\\n');\n\tif (Object.keys(obj).length === 0) {\n\t\tconsole.log('No contacts... list is empty.');\n\t} else {\n\t\tfor (const contact in obj) {\n\t\t\tconsole.log(`${contact}: ${obj[contact].name} - ${obj[contact].phone}`);\n\t\t}\n\t}\n\tbackToMain();\n}\n\nfunction searchContact(obj, nick) {\n\tconst search = obj.hasOwnProperty(nick);\n\tif (search) {\n\t\tconsole.log(`${obj[nick].name} - ${obj[nick].phone}`);\n\t} else {\n\t\tconsole.log(`Contact ${nick} does not exist`);\n\t}\n\tbackToMain();\n}\n\nfunction addContact(obj, nick, name, phone) {\n\tif (obj.hasOwnProperty(nick)) {\n\t\tconsole.log(`Contact ${nick} already exist`);\n\t\tbackToMain();\n\t} else if (validatePhone(phone)) {\n\t\tobj[nick] = { name, phone };\n\t\tconsole.log(`Contact ${nick} successfully added`);\n\t} else {\n\t\tconsole.log('Invalid phone number. Phone must have 10 digits');\n\t}\n\tbackToMain();\n}\n\nfunction updateContact(obj, nick, name, phone) {\n\tif (obj.hasOwnProperty(nick) && validatePhone(phone)) {\n\t\tobj[nick].name = name;\n\t\tobj[nick].phone = phone;\n\t\tconsole.log(`Contact ${nick} successfully updated`);\n\t} else {\n\t\tconsole.log(\n\t\t\t`Contact ${nick} does not exist or you input an invalid phone number. Phone must have 10 digits`\n\t\t);\n\t}\n\tbackToMain();\n}\n\nfunction deleteContact(obj, nick) {\n\tif (obj.hasOwnProperty(nick)) {\n\t\tdelete obj[nick];\n\t\tconsole.log(`Contact ${nick} successfully deleted`);\n\t} else {\n\t\tconsole.log(`Contact ${nick} does not exist`);\n\t}\n\tbackToMain();\n}\n\nfunction exitContacts() {\n\tconsole.log('Exiting Contacts!');\n\tsetTimeout(() => {\n\t\tconsole.clear();\n\t\tprocess.exit();\n\t}, 1000);\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/hectorio23.js",
    "content": "const readline = require('readline');\n\n// Creación de la interfaz de entrada/salida\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\n// Función para descubrir el tipo de relación entre dos palabras\nfunction discoverType(value1, value2) {\n    // Invertir la primera palabra\n    let valueReverse = value1.split('').reverse().join('');\n\n    if (valueReverse === value2) {\n        return \"\\nLas palabras anteriormente insertadas forman en realidad un palíndromo\\n\\n\";\n    } else if (isograma(value1) && isograma(value2)) {\n        return \"\\nAmbas palabras son isogramas\\n\\n\";\n    } else if (isograma(value1) || isograma(value2)) {\n        return \"\\nUna de las palabras es un isograma\\n\\n\";\n    } else if (anagrama(value1, value2)) {\n        return \"\\nEs un anagrama\\n\\n\";\n    }\n\n    return \"\\nLas palabras proporcionadas no cumplen con las condiciones para ser un palíndromo, isograma o anagrama\\n\";\n}\n\n// Función para verificar si una palabra es un isograma\nfunction isograma(palabra) {\n    let _tmp_ = \"\";\n\n    for (let item of palabra) {\n        if (_tmp_.includes(item)) {\n            return false;\n        }\n        _tmp_ += item;\n    }\n    return true;\n}\n\n// Función para verificar si dos palabras son anagramas\nfunction anagrama(palabra1, palabra2) {\n    let palabra1_sorted = palabra1.split('').sort().join('');\n    let palabra2_sorted = palabra2.split('').sort().join('');\n\n    if (palabra1.length !== palabra2.length || palabra1_sorted !== palabra2_sorted) {\n        return false;\n    }\n    return true;\n}\n\n// Función principal\nfunction main() {\n    rl.question(\"Inserta la primera palabra: \", function(value1) {\n        if (!value1) {\n            console.log(\"Entrada inválida. Por favor, inserta una palabra.\");\n            rl.close();\n            return;\n        \n        }\n        rl.question(\"Ahora inserta la segunda palabra: \", function(value2) {\n\n            let cadena1 = \"Hola\";\n            let cadena2 = \"Mundo\";\n\n            if (!value1 || !value2) {\n                return ;\n            }\n            // Convertir las palabras ingresadas a minúsculas\n            value1 = value1.toLowerCase();\n            value2 = value2.toLowerCase();\n\n            // Mostrar el tipo de relación entre las palabras ingresadas\n            console.log(discoverType(value1, value2));\n\n            // Ejemplos de operaciones con cadenas\n            let concatenacion = cadena1 + \" \" + cadena2;\n            console.log(\"Concatenación: \" + concatenacion);\n\n            let cadenaPrueba = concatenacion.replace(/\\s/g, \"\");\n            console.log(\"Cadena sin espacios en blanco: \" + cadenaPrueba);\n\n            console.log(\"Longitud de la cadena 1: \" + cadena1.length);\n            console.log(\"Longitud de la cadena 2: \" + cadena2.length);\n\n            console.log(\"Primer caracter de la cadena 1: \" + cadena1[0]);\n            console.log(\"Último caracter de la cadena 2: \" + cadena2[cadena2.length - 1]);\n\n            if (cadena1 === cadena2) {\n                console.log(\"Las cadenas son iguales\");\n            } else {\n                console.log(\"Las cadenas son diferentes\");\n            }\n\n            let subcadena = concatenacion.substring(5, 10); // Extrae \"Mundo\"\n            console.log(\"Subcadena: \" + subcadena);\n\n            let buscar = \"Mundo\";\n            let posicion = concatenacion.indexOf(buscar);\n            if (posicion !== -1) {\n                console.log(\"La cadena '\" + buscar + \"' fue encontrada en la posición \" + posicion);\n            } else {\n                console.log(\"La cadena '\" + buscar + \"' no fue encontrada\");\n            }\n\n            concatenacion = concatenacion.replace(\"Mundo\", \"Universo\");\n            console.log(\"Después de reemplazar 'Mundo' por 'Universo': \" + concatenacion);\n\n            // Cerrar la interfaz readline\n            rl.close();\n        });\n    });\n}\n\n// Ejecutar la función principal\nmain();\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/jaxi86.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\nconsole.log('OBJETOS');\n\nlet miObjeto = {\n    nombre : 'jaxi',\n    apellido :'jax',\n    edad : 23,\n}\n\nconsole.log(miObjeto);\n\nmiObjeto.email='jaxijax86@gmail.com';//insercion.\nconsole.log(miObjeto);\n\ndelete miObjeto.edad;//borrado.\nconsole.log(miObjeto)\n\nmiObjeto.nombre='josue';//actualizacion.\nconsole.log(miObjeto)\n\n//no hay operacion de ordenacion para objetos\n\nconsole.log('ARRAY');\n\nlet miArray = [2, 5, 4, 9];\nlet mi2Array = [55, 88, 11, 99];\nconsole.log(miArray);\n\nmiArray[4] =1;//insercion en un indice que le indique.\nmiArray.push(3);//insercion siempre de ultimo indice del array.\nmiArray.unshift(10);//insercion siempre en el indice 0 del array empujando a los demas a lo indices siguientes\nconsole.log(miArray);\n\ndelete miArray[1];//borrar el valor de un indice que le indiquemos.\nmiArray.pop();//borrar el valor del ultimo indice\nmiArray.shift();//borrar el valor del indice 0\nmiArray.splice(2,3)//borrar (el primer numero es el indice de donde se quiere empezar a borrar, el segundo es de CUANTOS indices a la derecha se quiere borrar contando el indice que se quiere borrar)\nconsole.log(miArray);\n\nmiArray[0]=15;//actualizacion.\nconsole.log(miArray);\n\nmi2Array.sort();//ordenacion\nconsole.log(mi2Array)\n\nconsole.log('MAPS')\n\n\nlet miMapa = new Map();\nconsole.log(miMapa)\n\n\nmiMapa.set('clave1', 1);// Inserción\nmiMapa.set('clave2', 'valor2');\nconsole.log(miMapa)\n\nmiMapa.delete('clave1');//borrar\nconsole.log(miMapa);\n\nmiMapa.set('clave2', 'nuevo valor')//actualizacion\nconsole.log(miMapa)\n\n//no hay operacion para ordenar un mapa\n\nconsole.log('SET')\n\nlet miSet = new Set([1, 5, 8, 2]);\nconsole.log(miSet);\n\nmiSet.add(4);//insercion.\nconsole.log(miSet);\n\nmiSet.delete(1);\nconsole.log(miSet);\n\n//no tiene un opperador para actualizar\n\n//no tiene un operador para ordenacion\n\nconsole.log('DIFICULTAD EXTRA');\n\nlet lista = [];\n\nfunction validarNumerotele (numero){\n    return /^\\d{11}$/.test(numero);\n}\n\n\nfunction buscarContactos (nombre){\n    return lista.find(contacto => contacto.Nombre === nombre);\n}\n\nfunction panelPrincipal (){\n    console.log('marca 1 para registrar un contacto, 2 para actualizar un  contacto, 3 para buscar contacto, 4 para eliminar contacto y 5 para salir de la funcion');\n    let eleccion = prompt('ingresa un numero para elegir una accion: ');\n\n    switch(eleccion){\n        case '1':\n            insertarContacto();\n            break;\n        case '2':\n            actualizarContacto();\n            break;\n        case '3':\n            buscarYMostrarContactos();\n            break;\n        case '4':\n            borrarContacto();\n            break;\n        case '5':\n            console.log('saliste del programa');\n            break;\n    }\n}\npanelPrincipal();\n\nfunction insertarContacto(){//1\n    console.log('maraca 1 para ingresar contacto, 2 para volver al panel principal');\n    let eleccion = prompt ('marca una opcion')\n    switch (eleccion){\n        case '1':\n            let nombre = prompt('escribe el nombre del contacto');\n            let numero = prompt('escribe el numero del contacto');\n        \n            if (validarNumerotele(numero)){\n                lista.push({Nombre: nombre, Numero: numero});\n                console.log('contacto guardado');\n            }else{ console.log('contacto no valido') }\n        case '2':\n            return panelPrincipal();\n        default:\n            console.log('accion no valida');\n            return insertarContacto();\n    }\n    \n}\n\nfunction actualizarContacto (){//2\n    console.log('buscar contacto para actualizar');\n    let buscando = prompt('introduce el nombre del contacto que desea actualizar: ');    \n    if(lista.find(contacto => contacto.Nombre === buscando)){\n        lista.Nombre = prompt ('nuevo nombre del contacto');\n        lista.Numero = prompt ('nuevo numero telefonico');\n        console.log('contacto actualizado');\n    }else{ console.log('contacto no encontrado')}\n    return panelPrincipal();\n}\n\nfunction buscarYMostrarContactos(){//3\n    console.log('marca 1 para ver un contacto indicado, 2 para ver todos los contactos, 3 para volver atras');\n    let eleccion = prompt ('seleciona una opcion');\n\n    switch(eleccion){\n        case '1':\n            let buscando = prompt('introduce el nombre del contacto que desea ver: ');\n            let verContacto = buscarContactos(buscando)\n            if(verContacto){\n                for (idx of lista){\n                    if (idx === verContacto){\n                        console.log(idx);\n                    }\n                }\n            }else{ console.log('contacto no encontrado')}\n            break;\n        case '2':\n            console.log(lista);\n            break;\n        case '3':\n            return panelPrincipal();\n            break;\n        default:\n            console.log('accion no reconocida');\n            \n    }\n    return panelPrincipal()\n}\n\nfunction borrarContacto(){//4\n    console.log ('ingresa el nombre del contacto que desea borrar');\n    let buscando = prompt('introduce el nombre del contacto que desea borrar: ');\n    let contactoBorrar = buscarContactos(buscando)\n    \n    if(contactoBorrar){\n        lista = lista.filter(contacto => contacto.Nombre !== contactoBorrar);\n        console.log('contacto borrado')\n    }else{ console.log('contacto no encontrado')}\n    return panelPrincipal()\n}\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/jeronimocardu.js",
    "content": "// ESTRUCTURAS SOPORTADAS DE JS\n\nconst { clear } = require('console');\nconst { read } = require('fs');\n\n//          Primitivos\nlet number = 12;\nlet string = 'Hola mundo!';\nlet boolean = true;\nlet indefinito = undefined;\nlet isNull = null;\n\n//          Objetos\nlet objeto1 = {\n    nombre: 'Jeronimo',\n    edad: 22,\n    lenguaje: 'javascript',\n};\nobjeto1[\"sexo\"] = 'hombre';     // insercion\ndelete objeto1.lenguaje;        // borrado\nobjeto1.edad = 20               // actualizacion\nconsole.log(objeto1)\n\nlet arreglo1 = [1, 2, 3, 4];\nlet arreglo2 = ['a', 'b', 'c', 'd'];\narreglo1.push(7);       // insercion\narreglo2.pop();         // borrado\narreglo1[0] = 0;        // actualizado\narreglo1.reverse();     // ordenado\n\nconsole.log(arreglo1);\nconsole.log(arreglo2);\n\nfunction unaFuncion(){\n    console.log('Soy una funcion');\n}\n\nlet fecha = new Date();\n\n//          Otros\nlet promesa = new Promise((res, rej) => {\n    // operacion\n})\n\nasync function funcionAsync(){\n    let variable = await promesa//....\n};\n\n\n\n// EXTRA\nlet contactos = [\n    {nombre: 'Jeronimo', numero: 123456788},\n]\n\nconst readline = require('readline').createInterface({\n    input: process.stdin,\n    output: process.stdout,\n})\n// Busqueda de contacto\nfunction busqueda(name){\n    let encontrado = false;\n    for(let i of contactos){\n        if(i.nombre === name){\n            console.log(`\\nEl número telefonico de ${name} es: ${i.numero}`);\n            encontrado = true;\n        }\n    }\n    if(!encontrado) console.log(`\\n${name} no esta en nuestra agenda`);\n    espera();\n}\n// Insercion de contacto\nfunction insercion(newName, newNumber){\n    let encontrado = false;\n    for(let i of contactos){\n        if(i.numero === newNumber){\n            console.log('\\nEste numero ya esta agendado, debe haber un error..');\n            encontrado = true;\n        }\n    }\n    if(newNumber.toString().length >= 11 || isNaN(newNumber)){\n        console.log('\\nDebe ser numerico y menor a 11 digitos de largo..')\n    }\n    if(!encontrado && !isNaN(newNumber) && newNumber.toString().length < 11) {\n        contactos.push({nombre: newName, numero: newNumber});\n        console.log(`\\nContacto agregado: ${newName} - ${newNumber}`);\n    }\n    espera();\n}\nfunction actualizacion(toUpdate, newName, newNumber){\n    let encontrado = false;\n    for(let i of contactos){\n        if(i.nombre === toUpdate){\n            i.nombre = newName;\n            i.numero = newNumber;\n            encontrado = true;\n            break;\n        }\n    }\n    if(!encontrado) console.log(`\\n${toUpdate} no está en nuestra agenda`);\n    if(newNumber.toString().length >= 11 || isNaN(newNumber)) console.log('\\nDebe ser numerico y menor a 11 digitos de largo..');\n    espera();\n}\nfunction eliminar(conctact){\n    let incialLength = contactos.length;\n    contactos = contactos.filter(persona => persona.nombre !== conctact);\n    if(incialLength > contactos.length){\n        console.log(`\\n${conctact} se ha eliminado con exito!`);\n    } else{\n        console.log(`No se encontro ${conctact} en nuestros contactos`)\n    }\n    espera();\n}\nfunction espera(){\n    readline.question('\\nPrecione ENTER para continuar..', (tecla) =>{\n        if(tecla === ''){\n            console.clear();\n            agenda()\n        } else{\n            espera();\n        }\n    })\n}\nfunction makeNumber(str){\n    let number = parseInt(str);\n    return number;\n}\nfunction makeName(name){\n    let nameMod = name[0].toUpperCase() + name.slice(1).toLowerCase();\n    return nameMod;\n}\n\nfunction agenda(){\n    console.log(`\n======= Agenda Telefonica ======= \\n\n    1. Buscar contacto\n    2. Agregar contacto\n    3. Actulizar contacto\n    4. Borrar contacto\n    0. Salir \\n`);\n\n    readline.question('Elija una opcion: ', (opcion) => {\n        opcionNumber = parseInt(opcion);\n        switch (opcionNumber){\n            case 1:\n                readline.question('Ingrese el nombre de la persona que quiere buscar: ', (nombreBuscado) =>{\n                    busqueda(makeName(nombreBuscado));\n                })\n                break;\n            case 2:\n                readline.question('Ingrese el nombre del contacto que quiere agregar: ', (newNameContact) => {\n                    readline.question('Ahora ingrese el número del nuevo contacto: ', (newNumContact) => {\n                        insercion(makeName(newNameContact), makeNumber(newNumContact));\n                    })\n                })\n                break;\n            case 3:\n                readline.question('Ingrese el nombre del contacto que quiere actualizar: ', (contactToUpdate) => {\n                    readline.question('Ingrese el nuevo nombre del contacto: ', (nameUpdate) =>{\n                        readline.question('Ingrese el nuevo número del contacto: ', (numberUpdate) => {\n                            actualizacion(makeName(contactToUpdate), makeName(nameUpdate), makeNumber(numberUpdate));\n                        })\n                    })\n                })\n                break;\n            case 4:\n                readline.question('Ingrese el nombre del contacto que desea eliminar: ', (contactToDelete) =>{\n                    eliminar(makeName(contactToDelete));\n                })\n                break;\n            case 0:\n                console.log('\\nSaliendo..')\n                readline.close();\n                break;\n            default:\n                console.log(`\"${opcionNumber}\" no es una opcion valida`);\n                espera();\n        }\n    })\n}\nagenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/jhoshmc.js",
    "content": "//* formas de crear un objeto\n\n// comun\n\nlet persona = {\n  nombre: \"juan\",\n  apellido: \"martines\",\n};\n\n// console.log(persona);\n// usando la funcion constructura Object()\n\nlet productos = new Object();\nproductos.nombre = \"pera\";\nproductos.precio = 1.3;\n\n// console.log(productos);\n// objetos con comportamiento, objetos orientados a objetos\n\nclass verduras {\n  constructor(nombre, precio) {\n    this.nombre = nombre;\n    this.precio = precio;\n  }\n}\n\nlet verdura = new verduras(\"brocoli\", 2);\n\n// console.log(verdura);\n\n//* arreglos\n\nlet arreglo_frutas = [\"manzana\", \"platano\", \"pera\", \"zandia\"];\nlet numeros = [1, 2, 3, 4, 5, 6];\n\n// metodo para saber el tamaño del arreglo, se usa .length\n//* console.log(\"el tamaño del arreglo es: \", arreglo_frutas.length);\n// un metodo para recorrerlo, seria un for\nconsole.log(\"--------------------for clasico--------------------------\");\nfor (let i = 0; i < arreglo_frutas.length; i++) {\n  console.log(arreglo_frutas[i]);\n}\n\n// otra forma seria usando forEach\nconsole.log(\"-------------------forEach---------------------------------\");\narreglo_frutas.forEach((elemento) => {\n  console.log(elemento);\n});\n\n// otra forma seia con un map, este crea un nuevo arreglo con los resultados de la llamada a\n// a la funcion , esto se aplica a cada uno de sus elementos\n\nconsole.log(\"------------------------map------------------------------------\");\ndobles = numeros.map((elemento) => {\n  return elemento * elemento;\n});\n\nconsole.log(\"numeros antes: \");\nconsole.log(numeros);\nconsole.log(\"numeros al cuadrado \");\nconsole.log(dobles);\n\n//* push(), añade un elemento al final del array y devuelve el tamaño\nnuevo_tamaño = arreglo_frutas.push(\"zanahoria\");\n// console.log(\"el nuevo tamañlo del arreglo es: \", nuevo_tamaño);\n\n//* pop(), elimina el último elemento del arreglo y lo devuelte\neliminado = arreglo_frutas.pop();\n// console.log(\"eliminado: \", eliminado);\n\n//* reduce(), ejecuta una funcion reductora sobre cada elemento del array\n//* devolviendo como resultado unico valor\n// en este caso vamos a sumar los elementos del arreglo numeros\n\nlet valor_inicial = 0;\nlet resultado = numeros.reduce(\n  (acumulador, currentValue) => acumulador + currentValue,\n  valor_inicial\n);\n// console.log(\" la suma es: \", resultado);\n\n//! Set, son colecciones de valores\n// crear un set con valores, los valores tienen que ser unicos\nlet set = new Set([\"nombre\", 1]);\nconsole.log(set);\n// agregar\nset.add(2);\nconsole.log(set);\n\nlet nombres = { nombre: \"juan\", apellido: \"parodi\" };\n\nset.add(nombres);\nconsole.log(set);\n//* has() devuelve un booleano afirmando si un valor está en objeto set o no\nconsole.log(set.has(2));\nconsole.log(set.has(nombres));\n\n//* tamaño del objeto\nconsole.log(set.size);\n\n//* eliminar un elemento del objeto delete(), devuelve un booleano confirmando si se elimino el elemento\n\nconsole.log(set.delete(nombres));\nconsole.log(set);\n\n//* probando ingresar datos desde el terminal con readline\n\nconst { exit } = require(\"process\");\nconst readline = require(\"readline\");\nconst rl = readline.createInterface({\n  //* rl, es la interface de readline\n  //* configurado para\n  input: process.stdin, //*  recibir entradas del usuario\n  output: process.stdout, //* y mostrar salida\n});\n\n// rl.question(\"ingrese un numero: \", (numero) => {\n//   console.log(`el numero es: ${numero}`);\n//   rl.close(); // supongo que es para cerrar\n// });\n\n//! ejercicio extra:\n\nconst patronNumeros = /^\\d{1,11}$/; // Expresión regular para validar números de 1 a 11 dígitos;\nlet ejecutando = true; //* funcion para ejecutar bucle en el menu\n//* array con las opciones del menu\nlet CONTACTOS = [{ nombre: \"pedro\", telefono: 98999878978 }];\nconst datos_menu = [\n  { num: \"1.\", option: \" ingresar contacto\" },\n  { num: \"2.\", option: \" buscar contacto \" },\n  { num: \"3.\", option: \" actualizar contacto\" },\n  { num: \"4.\", option: \"borrar contacto\" },\n  { num: \"5.\", option: \" ordenar contactos\" },\n  { num: \"6.\", option: \" salir\" },\n];\n\nclass InfoContacto {\n  constructor(nombre, telefono) {\n    this.nombre = nombre;\n    this.telefono = telefono;\n  }\n}\n\n//* funcion para hacer preguntas de forma asincrona\nconst ask = (text) => {\n  return new Promise((resolve) => rl.question(text, resolve));\n};\n\n//* 1. funcion para ingresar un nuevo contacto:\nasync function ingresarContacto() {\n  console.log(\"\\n\\t ingresar contactos \\n\");\n  let nombre = await ask(\"ingresa el nombre del contacto: \");\n  let telefono = await ask(\"ingresa el telefono: \");\n  if (patronNumeros.test(telefono)) {\n    let contacto = new InfoContacto(nombre, telefono);\n    CONTACTOS.push(contacto);\n    console.log(\n      `nuevo contacto: ${contacto.nombre} \\n Movil:${contacto.telefono}\\n`\n    );\n    console.log(\"contacto agregado\\n\");\n  } else {\n    console.warn(\" solo se permiten un maximo de 11 numeros \");\n  }\n}\n\n//* 2. funcion para buscar contacto:\nasync function buscarContacto(buscar) {\n  let i = 0;\n  let encontrado = false;\n  for (const elemento of CONTACTOS) {\n    if (Object.is(elemento.nombre, buscar)) {\n      console.log(\" se encontro el contacto \");\n      encontrado = true;\n      break;\n    }\n    i++;\n  }\n  if (!encontrado) {\n    console.log(\"no se encontro el contacto\");\n    return false;\n  } else {\n    console.log(\n      `contacto: ${CONTACTOS[i].nombre} \\n Movil: ${CONTACTOS[i].telefono}`\n    );\n    return i;\n  }\n}\n\n//* 3. actualizar contacto\nasync function actualizarContacto() {\n  console.log(\"\\n\\t actualizar contacto\\n\");\n  let buscar = await ask(\"ingrese el nombre a buscar: \");\n  let i = await buscarContacto(buscar);\n  if (i !== false) {\n    console.log(\"ingrese datos a actualizar: \");\n    let new_nombre = await ask(\"ingrese el nombre: \");\n    let new_telefono = await ask(\"ingrese el numero: \");\n    CONTACTOS[i].nombre = new_nombre;\n    CONTACTOS[i].telefono = new_telefono;\n    console.info(\n      `contacto actualizado: \\n ${CONTACTOS[i].nombre} \\n Movil: ${CONTACTOS[i].telefono}`\n    );\n  }\n}\n\n//* 4. borrar contacto\nasync function borrarContacto() {\n  console.log(\"\\n\\t eliminar contacto: \\n\");\n  let buscar = await ask(\"ingrese el nombre del contacto: \");\n  let i = await buscarContacto(buscar);\n  if (i !== false) {\n    CONTACTOS.splice(i, 1);\n    console.log(\"contacto eliminado\");\n  }\n}\n\n//* 5. funcion para mostrar los contactos ordenados:\nfunction ordenarContactos() {\n  console.log(\"\\n\\t contactos: \\n\");\n  CONTACTOS.forEach((element) => {\n    console.log(`${element.nombre} \\n Movil:${element.telefono}\\n`);\n  });\n}\n\n//* 6. funcion para salir\nconst salir = () => {\n  console.log(\"\\n adiosssssssssssss\");\n  ejecutando = false;\n  rl.close();\n  process.exit(0);\n};\n\n//* funcion principal, menu\nconst menu = async () => {\n  while (ejecutando) {\n    console.log(\"\\n\\t menu: \\n\");\n    console.table(datos_menu);\n    let answer = await ask(\"ingrese la opcion: \");\n    switch (answer) {\n      case \"1\":\n        await ingresarContacto();\n        break;\n      case \"2\":\n        console.log(\"\\n\\t bucar contacto: \\n\");\n        let buscar = await ask(\"nombre a buscar: \");\n        await buscarContacto(buscar);\n        break;\n      case \"3\":\n        await actualizarContacto();\n        break;\n      case \"4\":\n        await borrarContacto();\n        break;\n      case \"5\":\n        ordenarContactos();\n        break;\n      case \"6\":\n        salir();\n        break;\n      default:\n        console.info(\"\\nopcion no valida\\n\");\n        break;\n    }\n  }\n};\n\nmenu();\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/joapalobael.js",
    "content": "//--------------------------------> Estructuras de datos de JS\n//Array\nconsole.log('Estructura de dato: Array');\nlet lista = [\"Mani\", \"Nuez\", \"Castaña de Cajú\", \"Avellana\"]\nconsole.log(lista);\nconsole.log('---------------------------------');\n\n//Agregar elemento al final del array\nconsole.log('Agregar al final → push()');\nlista.push(\"Almendra\", \"Girasol\");\nconsole.log(lista);\nconsole.log('---------------------------------');\n\n//Eliminar del array\nconsole.log('Eliminar primer item → pop()');\nlista.pop();\nconsole.log(lista);\nconsole.log('---------------------------------');\n\n//Agregar elemento al comienzo del array\nconsole.log('Agregar al comienzo → unshift()');\nlista.unshift(\"Girasol\");\nconsole.log(lista);\nconsole.log('---------------------------------');\n//Eliminar primer elemento de la lista\nconsole.log('Eliminar al comienzo → shift()');\nlista.shift();\nconsole.log(lista);\nconsole.log('---------------------------------');\n\n//Encontrar el índice de un elemento del array\nconsole.log('Indice → idexOf(\"x\")');\nlet posicion = lista.indexOf(\"Nuez\");\nconsole.log(`La posición en la lista de la Nuez es: ${posicion}`);\nconsole.log('---------------------------------');\n\n//Eliminar un elemento con posición del array → Quitar, reemplazar o agregar nuevos elementos del medio del array\n//Splice (index, borrar, agregar)\nconsole.log('Eliminar/agregar un elemento en el medio → splice()');\nconsole.log(lista);\nlista.splice(4, 0, 'Girasol');\nconsole.log(lista);\nconsole.log('---------------------------------');\n\n// Array de objetos\nconsole.log('Estructura de dato: Array de objetos');\nconst verduleria = [\n    { nombre: \"papa\", costo: 1200, unidad: \"kg\" },\n    { nombre: \"cebolla\", costo: 800, unidad: \"kg\" },\n    { nombre: \"zanahoria\", costo: 400, unidad: \"kg\" },\n    { nombre: \"palta\", costo: 1500, unidad: \"unidad\" },]\n\nverduleria.push({ nombre: \"lechuga\", costo: 2800, unidad: \"kg\" }); // agregar un dato\nverduleria.splice(1, 1); //Elimina 1 dato\nverduleria[3].nombre = \"Lechuga Francesa\" //Actualiza dato\nverduleria.sort((a, b) => a.costo - b.costo); //Ordena datos\n//Busqueda\nlet buscaVerdura = \"Zanahoria\";\nlet verdura = verduleria.find(verdura => verdura.nombre.toLocaleLowerCase().includes(buscaVerdura.toLocaleLowerCase()));\nif (verdura) {\n    console.log(`La ${verdura.nombre} sale $${verdura.costo} por ${verdura.unidad}`);\n}\nelse { console.log(`No tenemos stock de ${buscaVerdura}. Vuelva prontos`) };\nconsole.log('---------------------------------');\n\n//--------------------------------> Ejercicio extra\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\n//También instale npm install prompt-sync\n// Y se debe colocar const prompt = require(\"prompt-sync\")({sigint:true}); al comienzo del código\nconst prompt = require(\"prompt-sync\")({ sigint: true });\n\nlet agendaContactos = [\n    { nombre: \"Sara Garrett\", tel: 4958572 },\n    { nombre: \"Gilbert Robinson\", tel: 8259704 },\n    { nombre: \"Pedro Byrd\", tel: 4714090 },\n    { nombre: \"Hannah Ryan\", tel: 9847358 },\n    { nombre: \"Lisa Spencer\", tel: 8577432 },\n    { nombre: \"Ivan Shaw\", tel: 3872149 },\n]\n\nfunction mi_agenda() {\n    let is_on = true;\n    while (is_on) {\n    console.log(\"1. Buscar contacto\");\n    console.log(\"2. Insertar contacto\");\n    console.log(\"3. Actualizar contacto\");\n    console.log(\"4. Eliminar contacto\");\n    console.log(\"5. salir\");\n    let usuarioResponde = prompt('Seleccione una opción: ');\n    \n    switch (usuarioResponde) {\n        // 1. Buscar\n        case \"1\":\n            let buscaNombre = prompt('Introduce el nombre del contacto a buscar: ');\n            let contactoEncontrado = agendaContactos.find(contacto => contacto.nombre.toLocaleLowerCase().includes(buscaNombre.toLocaleLowerCase()));\n\n            if (contactoEncontrado) {\n                console.log(`El teléfono de ${contactoEncontrado.nombre} es: ${contactoEncontrado.tel}`);\n            } else {\n                console.log(`El contacto ${buscaNombre} no existe`);\n            }\n            break;\n        // 2. Agregar\n        case \"2\":\n            let nombreNuevo = prompt('Inserte el nombre: ');\n            let telNuevo = prompt('Inserte el tel nuevo: ');\n            while (!(!isNaN(telNuevo) && telNuevo.length > 0 && telNuevo.length <= 11)) {\n                tel = prompt('Inserte un número válido de no más de 11 caracteres');\n            }\n            telNuevo = parseInt(telNuevo);\n            agendaContactos.push({ nombre: nombreNuevo, tel: telNuevo });\n            console.log(agendaContactos)\n            break;\n        // 3. Modificar\n        case \"3\":\n            let modificaNombre = prompt('Introduce el nombre del contacto a modificar: ');\n            let encuentraContacto = agendaContactos.find(contacto => contacto.nombre.toLocaleLowerCase().includes(modificaNombre.toLocaleLowerCase()));\n            if(encuentraContacto){\n                encuentraContacto.tel = prompt('Introduce el nuevo número: ');\n                console.log(`El nuevo número de ${encuentraContacto.nombre} es ${encuentraContacto.tel}`);\n            } else {console.log(`El contacto ${modificaNombre} no existe`);\n        }\n            break;\n        // 4. Eliminar\n        case \"4\":  \n            let eliminaNombre = prompt('Introduce el nombre del contacto a eliminar: ');\n            let contactoEliminado = agendaContactos.find(contacto => contacto.nombre.toLocaleLowerCase().includes(eliminaNombre.toLocaleLowerCase()));\n            let indexContacto = agendaContactos.indexOf(contactoEliminado)\n            agendaContactos.splice(indexContacto, 1);\n            console.log(`Se elimino a ${contactoEliminado.nombre} de la agenda.`)\n            break;\n        // 5. Salir\n            case \"5\":\n            console.log(\"Gracias, vuelva pronto.\");\n            is_on = false;\n            break;\n        default:\n            console.log(\"Opción inválida\\n Elija un numero del 1 al 5\");\n            break;\n    }\n}\n}\n\nmi_agenda();"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/joshbaez.js",
    "content": "// EJERCICIO\n\n/* - Muestra ejemplos de creación de todas las estructuras soportadas por defecto\n   en tu lenguaje.\n - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n\n DIFICULTAD EXTRA (opcional):\n Crea una agenda de contactos por terminal.\n - Debes implementar funcionalidades de búsqueda, inserción, actualización\n   y eliminación de contactos.\n - Cada contacto debe tener un nombre y un número de teléfono.\n - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n   y a continuación los datos necesarios para llevarla a cabo.\n - El programa no puede dejar introducir números de teléfono no númericos y con más\n   de 11 dígitos (o el número de dígitos que quieras).\n - También se debe proponer una operación de finalización del programa.\n*/\n\n\n//  ARRAYS \n\n\n// creacion \nlet numeros = [1, 2, 3, 4, 5];\n\n// acceso\nconsole.log(numeros[0]);\n\n// actualizacion \nnumeros[0] = 10;\nconsole.log(numeros[0]);\n\n// agregar elementos \nnumeros.push(6); // agregar al final\nnumeros.unshift(0); // agregar al inicio \n\n// eliminar elementos \nnumeros.pop(); // elimina el ultimo elemento\nnumeros.shift(); // eliminar el primer elemento \n\n// eliminar elemento de una sona espesifica \nnumeros.splice(2, 1);  // Elimina 1 elemento en la posición 2\n\n// otros metodos \nnumeros.includes(3); // true\nnumeros.indexOf(3); // 2\nnumeros.reverse(); // Invierte el array\nnumeros.sort(); // Ordena el array\n\n\n\n// OBJETOS \n\n\n// creacio \nlet persona = {\n    nombre: \"Joshua\",\n    edad: 25,\n    ciudad: \"Boston\"\n};\n\n// acceso\nconsole.log(persona.nombre); // joshua \n\n// actualizacion \npersona.edad = 26;\n\n// agregar propiedad \npersona.profesion = \"Ingeniero\";\n\n// eliminar propiedad \ndelete persona.ciudad;\n\n// otros metodos\n Object.keys(persona); // [\"nombre\", \"edad\", \"profesion\"]\n Object.values(persona); // [\"Joshua\", 26, \"Ingeniero\"]\n Object.entries(persona); // [[\"nombre\", \"Joshua\"], [\"edad\", 26], [\"profesion\", \"Ingeniero\"]]\n\n\n\n // MAPAS (MAPS)\n\n\n\n// creacion \nlet mapa = new Map();\nmapa.set(\"nombre\", \"Joshua\");\nmapa.set(\"edad\", 25);\n\n\n// acceso \nconsole.log(mapa.get(\"nombre\")); // \"Joshua\"\n\n// actualizacion \nmapa.set(\"edad\", 26);\n\n// eliminar elemento \nmapa.delete(\"edad\");\n\n// verificar existencia \nmapa.has(\"nombre\"); // true\n\n// otros metodos \nmapa.size; // 1\nmapa.clear(); // Elimina todos los elementos\n\n\n\n// CONJUNTOS \n\n\n\n// creacion\nlet conjunto = new Set();\nconjunto.add(1);\nconjunto.add(2);\nconjunto.add(2); // No se agrega porque ya existe\n\n// acceso \nconsole.log(conjunto.has(1)); // true\n\n// elminar elemento \nconjunto.delete(1);\n\n// verificar existencia\nconjunto.has(1); // false\n\n// otros metodos \nconjunto.size; // 1\nconjunto.clear(); // Elimina todos los elementos\n\n\n\n// CADENA DE TEXTO STRING \n\n\n\n// creacion \nlet cadena = \"Hola, mundo!\";\n\n// acceso \nconsole.log(cadena[0]); // \"H\"\n\n// actualizacion \ncadena = cadena.replace(\"mundo\", \"Joshua\");\n\n// otros metodos\ncadena.length; // 12\ncadena.toUpperCase(); // \"HOLA, JOSHUA!\"\ncadena.toLowerCase(); // \"hola, joshua!\"\ncadena.includes(\"Joshua\"); // true\ncadena.indexOf(\"Joshua\"); // 6\ncadena.split(\", \"); // [\"Hola\", \"Joshua!\"]\ncadena.substring(0, 4); // \"Hola\"\n\n\n\n// NUMEROS \n\n\n\n// creacion \nlet entero = 42;\nlet decimal = 3.14;\n\n// operaciones \nlet suma = entero + decimal;\nlet resta = entero - decimal;\nlet multiplicacion = entero * decimal;\nlet division = entero / decimal;\n\n\n// metodos \nMath.round(decimal); // 3\nMath.ceil(decimal); // 4\nMath.floor(decimal); // 3\nMath.max(1, 2, 3); // 3\nMath.min(1, 2, 3); // 1\nMath.random(); // Número aleatorio entre 0 y 1\n\n\n\n// BOLEANOS \n\n// creacion \nlet esVerdadero = true;\nlet esFalso = false;\n\n\n// operaciones logicas \nconsole.log(esVerdadero && esFalso); // false\nconsole.log(esVerdadero || esFalso); // true\nconsole.log(!esVerdadero); // false\n\n\n\n\n// FUNCIONES \n\n\n\n//creacion \nfunction saludar(nombre) {\n    return \"Hola, \" + nombre + \"!\";\n}\n\n// llamada a una funcion \nconsole.log(saludar(\"Joshua\")); // \"Hola, Joshua!\"\n\n\n// funcion anonima \nlet sumar = function(a, b) {\n    return a + b;\n};\n\n\n// funcion flecha\nlet restar = (a, b) => a - b;\n\n\n\n// CLASES \n\n\n\n// creacion \nclass Persona {\n    constructor(nombre, edad) {\n        this.nombre = nombre;\n        this.edad = edad;\n    }\n\n    saludar() {\n        return \"Hola, \" + this.nombre + \"!\";\n    }\n}\n\n\n// instanciacion \nlet joshua = new Persona(\"Joshua\", 25);\n\n\n// acceso a metodos \nconsole.log(joshua.saludar()); // \"Hola, Joshua!\"\n\n\n\n\n//  SIMBOLOS \n\n\n// creacion\nlet simbolo1 = Symbol(\"descripcion\");\nlet simbolo2 = Symbol(\"descripcion\");\n\n\n// comparacion \nconsole.log(simbolo1 === simbolo2); // false\n\n\n// uso como propiedad de un objeto \nlet objeto = {\n    [simbolo1]: \"valor\"\n};\nconsole.log(objeto[simbolo1]); // \"valor\"\n\n\n\n// BIGLNT\n\n\n\n// creacion \nlet numeroGrande = BigInt(123456789012345678901234567890);\nlet otroNumeroGrande = 123456789012345678901234567890n;\n\n// operaciones \nlet sumaGrande = numeroGrande + otroNumeroGrande;\nconsole.log(sumaGrande); // 246913578024691357802469135780n\n\nconst readline = require('readline');\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nlet contactos = {};\n\nfunction mostrarMenu() {\n    console.log(\"\\nAgenda de Contactos\");\n    console.log(\"1. Buscar contacto\");\n    console.log(\"2. Insertar contacto\");\n    console.log(\"3. Actualizar contacto\");\n    console.log(\"4. Eliminar contacto\");\n    console.log(\"5. Salir\");\n    rl.question(\"Seleccione una opción: \", (opcion) => {\n        switch (opcion) {\n            case '1':\n                buscarContacto();\n                break;\n            case '2':\n                insertarContacto();\n                break;\n            case '3':\n                actualizarContacto();\n                break;\n            case '4':\n                eliminarContacto();\n                break;\n            case '5':\n                finalizarPrograma();\n                break;\n            default:\n                console.log(\"Opción no válida. Intente de nuevo.\");\n                mostrarMenu();\n                break;\n        }\n    });\n}\n\nfunction buscarContacto() {\n    rl.question(\"Ingrese el nombre del contacto: \", (nombre) => {\n        if (contactos[nombre]) {\n            console.log(`Contacto encontrado: ${nombre} - ${contactos[nombre]}`);\n        } else {\n            console.log(\"Contacto no encontrado.\");\n        }\n        mostrarMenu();\n    });\n}\n\nfunction insertarContacto() {\n    rl.question(\"Ingrese el nombre del contacto: \", (nombre) => {\n        rl.question(\"Ingrese el número de teléfono: \", (telefono) => {\n            if (validarTelefono(telefono)) {\n                contactos[nombre] = telefono;\n                console.log(\"Contacto agregado.\");\n            } else {\n                console.log(\"Número de teléfono no válido.\");\n            }\n            mostrarMenu();\n        });\n    });\n}\n\nfunction actualizarContacto() {\n    rl.question(\"Ingrese el nombre del contacto a actualizar: \", (nombre) => {\n        if (contactos[nombre]) {\n            rl.question(\"Ingrese el nuevo número de teléfono: \", (telefono) => {\n                if (validarTelefono(telefono)) {\n                    contactos[nombre] = telefono;\n                    console.log(\"Contacto actualizado.\");\n                } else {\n                    console.log(\"Número de teléfono no válido.\");\n                }\n                mostrarMenu();\n            });\n        } else {\n            console.log(\"Contacto no encontrado.\");\n            mostrarMenu();\n        }\n    });\n}\n\nfunction eliminarContacto() {\n    rl.question(\"Ingrese el nombre del contacto a eliminar: \", (nombre) => {\n        if (contactos[nombre]) {\n            delete contactos[nombre];\n            console.log(\"Contacto eliminado.\");\n        } else {\n            console.log(\"Contacto no encontrado.\");\n        }\n        mostrarMenu();\n    });\n}\n\nfunction finalizarPrograma() {\n    console.log(\"Finalizando programa...\");\n    rl.close();\n}\n\nfunction validarTelefono(telefono) {\n    return /^\\d{1,11}$/.test(telefono);\n}\n\nmostrarMenu();"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/kaesar84.js",
    "content": "/*\n# #03 ESTRUCTURAS DE DATOS\n> #### Dificultad: Media | Publicación: 15/01/24 | Corrección: 22/01/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\n/*\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n*/\n\nconsole.log(\"--------------------------------------\")\nconsole.log(\"** ARRAY **\")\nconsole.log(\"--------------------------------------\")\nconsole.log(\"** Declaración **\")\nconsole.log(`let myArray = []`)\nlet myArray = []\nconsole.log(myArray, \"\\n\")\n\nconsole.log(\"** Inserción **\")\nconsole.log(\"push() -> Añade al final\")\nmyArray.push(\"Peter\")\nmyArray.push(\"Parker\")\nmyArray.push(\"Spiderman\")\nconsole.log(myArray, \"\\n\")\nconsole.log(\"unshift() -> Añade al principio\")\nmyArray.unshift(\"Marvel Hero\")\nconsole.log(myArray, \"\\n\")\n\nconsole.log(\"** Borrado **\")\nconsole.log(\"pop() -> Elimina el último\")\nmyArray.pop() //Elimina el último, puede almacenarse\nconsole.log(myArray, \"\\n\")\nconsole.log(\"shift() -> Elimina el primero\")\nmyArray.shift()\nconsole.log(myArray, \"\\n\")\nconsole.log(\"splice() -> Elimina un elemento en la posición indicada\")\nmyArray.splice(1, 2) // elimina desde la posición 1, 2 elementos\nconsole.log(myArray, \"\\n\")\n\nconsole.log(\"** Actualización **\")\nmyArray = [\"Peter\", \"Parker\", \"Spiderman\"]\nconsole.log(myArray)\n// console.log(\"indexOf() -> \")\nconsole.log((myArray[myArray.indexOf(\"Spiderman\")] = \"Spidey\"))\n// console.log(myArray,\"\\n\")\n\nconsole.log(\"** Ordenación **\")\nconsole.log(\"sort()\")\nmyArray.sort()\nconsole.log(myArray, \"\\n\")\n\nconsole.log(\"--------------------------------------\")\nconsole.log(\"** SET **\")\n// set - son datos ordenados sin indices, no se pueden repetir los elementos\nconsole.log(\"--------------------------------------\")\nconsole.log(\"** Declaración **\")\nconsole.log(`Opción 1 -let mySet = new Set()`)\nlet mySet = new Set()\nconsole.log(mySet, \"\\n\")\nconsole.log(`\nOpción 2 - mySet_two = new Set([\n    \"Bruce\",\n    \"Banner\",\n    \"Hulk\",\n    40,\n  ]) `)\nmySet_two = new Set([\"Bruce\", \"Banner\", \"Hulk\", 40])\nconsole.log(mySet_two, \"\\n\")\n\nconsole.log(\"** Inserción **\")\nconsole.log(`add()\nmySet.add(\"Tony\")\nmySet.add(\"Stark\")\nmySet.add(\"Iron Man\")\\n\n    `)\nmySet.add(\"Tony\")\nmySet.add(\"Stark\")\nmySet.add(\"Iron Man\")\nconsole.log(mySet, \"\\n\")\n\nconsole.log(\"** Borrado **\")\n// delete -> elimina un elemento especifico, devuelve true si lo ha eliminado\nconsole.log(` delete() -> elimina un elemento especifico, devuelve true si lo ha eliminado\nconsole.log(mySet.delete(\"Iron Man\"))\n    `)\nconsole.log(mySet.delete(\"Iron Man\"))\nconsole.log(mySet, \"\\n\")\n\nconsole.log(\"** Actualización **\")\nconsole.log(`\nNo permite modificación inmediata:\n1. Elimina el valor existente con delete()\n2. Añade con add()    \n    `)\n\nconsole.log(\"** Ordenación **\")\nconsole.log(`\nEn el set el orden es el de la incorporación, si fuera necesario\ndeberia convertirse en array y ordenarlo, y convertir de nuevo   \n\\n`)\n\nconsole.log(\"--------------------------------------\")\nconsole.log(\"** MAP **\")\nconsole.log(\"--------------------------------------\")\nconsole.log(\"** Declaración **\")\nconsole.log(`\nlet myMap = new Map();\n    `)\nlet myMap = new Map()\nconsole.log(myMap, \"\\n\")\n\nconsole.log(\"** Inserción **\")\nconsole.log(`\n- Permite cualquier tipo de dato como clave\nmyMap.set(\"name\", \"Peter\")\nmyMap.set(42, \"Edad\")\nmyMap.set(true, \"Es un héroe\")\n    `)\nmyMap.set(\"name\", \"Peter\")\nmyMap.set(42, \"Edad\")\nmyMap.set(true, \"Es un héroe\")\nconsole.log(myMap, \"\\n\")\n\nconsole.log(\"** Borrado **\")\nconsole.log(`\n delete() -> elimina un elemento según clave   \n console.log(myMap.delete(\"name\"))\n    `)\nconsole.log(myMap.delete(\"name\"))\nconsole.log(myMap, \"\\n\")\nconsole.log(`\nclear() -> elimina todos los elementos`)\nmyMap.clear()\nconsole.log(myMap)\n\nconsole.log(\"** Actualización **\")\nconsole.log(\"Igual que inserción\\n\")\n\nconsole.log(\"** Ordenación **\")\nconsole.log(`\nEn el map el orden es el de la incorporación  \n\\n`)\nconsole.log(`\nPodemos ordenarlos por claves o por valores  \n    \\n`)\n\n\nconsole.log(\"--------------------------------------\")\nconsole.log(\"** OBJETOS **\")\nconsole.log(\"--------------------------------------\")\nconsole.log(\"** Declaración **\")\nconsole.log(`\nlet persona = {\n    nombre: \"Peter\",\n    apellido: \"Parker\",\n    email: \"parker@parker.com\",\n    edad: 25,\n  } \n    `)\n\nlet persona = {\n    nombre: \"Peter\",\n    apellido: \"Parker\",\n    email: \"parker@parker.com\",\n    edad: 25,\n  }\nconsole.log(persona)\n\nconsole.log(\"** Inserción **\")\nconsole.log(`\npersona.year=2025\n    `)\npersona.year=2025\nconsole.log(persona)\n\nconsole.log(\"** Borrado **\")\nconsole.log(`\ndelete persona.year\n    `)\ndelete persona.year\nconsole.log(persona)\n\nconsole.log(\"** Actualización **\")\nconsole.log('Asignar sobre clave existente\\n')\n\nconsole.log(\"** Ordenación **\")\nconsole.log(\"Sin orden específico, para ordenar convertir en array y sort()\")\n\nconsole.log(\"--------------------------------------\")\nconsole.log(\"--------------------------------------\")\nconsole.log(\"**** EXTRA ****\")\nconsole.log(\"--------------------------------------\")\n\n// * DIFICULTAD EXTRA (opcional):\n// * Crea una agenda de contactos por terminal.\n// * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n// * - Cada contacto debe tener un nombre y un número de teléfono.\n// * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n// *   los datos necesarios para llevarla a cabo.\n// * - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n// *   (o el número de dígitos que quieras)\n// * - También se debe proponer una operación de finalización del programa.\n\nconst readline = require(\"readline\")\n\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout,\n})\n\nlet contacts = []\n\nfunction showMenu() {\n  console.log(\"\\n===========================\")\n  console.log(\"       *** AGENDA ***\")\n  console.log(\"===========================\")\n  console.log(\"1. Nuevo contacto\")\n  console.log(\"2. Buscar contacto\")\n  console.log(\"3. Actualizar contacto\")\n  console.log(\"4. Eliminar contacto\")\n  console.log(\"5. Listar contactos\")\n  console.log(\"6. Salir\\n\")\n  rl.question(\"Selecciona una opción: \", handleMenu)\n}\n\nfunction handleMenu(option) {\n  switch (option) {\n    case \"1\":\n      addContact()\n      break\n    case \"2\":\n      searchContact()\n      break\n    case \"3\":\n      updateContact()\n      break\n    case \"4\":\n      deleteContact()\n      break\n    case \"5\":\n      showContacts()\n      break\n    case \"6\":\n      console.log(\"Saliendo...\")\n      rl.close()\n      break\n    default:\n      console.log(\"Opción no válida\")\n      showMenu()\n  }\n}\n\nfunction addContact() {\n  rl.question(\"Nombre: \", (name) => {\n    rl.question(\"Número de teléfono: \", (phone) => {\n      if (!/^[0-9]{1,11}$/.test(phone)) {\n        console.log(\"Número de teléfono inválido (máx. 11 dígitos)\")\n        return showMenu()\n      }\n      contacts.push({ name, phone })\n      console.log(\"-- Contacto añadido --\")\n      showMenu()\n    })\n  })\n}\n\nfunction searchContact() {\n  rl.question(\"Nombre a buscar: \", (name) => {\n    const results = contacts.filter((c) =>\n      c.name.toLowerCase().includes(name.toLowerCase())\n    )\n    if (results.length) {\n      console.log(\"-- Resultados:\", results)\n    } else {\n      console.log(\"-- No se encontraron contactos --\")\n    }\n    showMenu()\n  })\n}\n\nfunction updateContact() {\n  rl.question(\"Nombre del contacto a actualizar: \", (name) => {\n    const index = contacts.findIndex(\n      (c) => c.name.toLowerCase() === name.toLowerCase()\n    )\n    if (index === -1) {\n      console.log(\"-- Contacto no encontrado --\")\n      return showMenu()\n    }\n    rl.question(\"Nuevo número de teléfono: \", (phone) => {\n      if (!/^[0-9]{1,11}$/.test(phone)) {\n        console.log(\"Número de teléfono inválido (máx. 11 dígitos)\")\n        return showMenu()\n      }\n      contacts[index].phone = phone\n      console.log(\"Contacto actualizado\")\n      showMenu()\n    })\n  })\n}\n\nfunction deleteContact() {\n  rl.question(\"Nombre del contacto a eliminar: \", (name) => {\n    const index = contacts.findIndex(\n      (c) => c.name.toLowerCase() === name.toLowerCase()\n    )\n    if (index === -1) {\n      console.log(\"Contacto no encontrado\")\n      return showMenu()\n    }\n    rl.question(\n      \"Seguro que quieres eliminar el contacto? (S/N): \\n\",\n      (respuesta) => {\n        if (respuesta == \"S\" || respuesta == \"s\") {\n          contacts.splice(index, 1)\n          console.log(\"-- Contacto eliminado --\")\n          showMenu()\n        } else {\n          showMenu()\n        }\n      }\n    )\n  })\n}\n\nfunction showContacts() {\n  if (contacts.length === 0) {\n    console.log(\"No hay contactos guardados\")\n  } else {\n    console.log(\"Lista de contactos:\\n\", contacts)\n  }\n  showMenu()\n}\n\nshowMenu()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n_______________________________________\n03 ESTRUCTURAS DE DATOS\n---------------------------------------\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n*/\n\n// ________________________________________________________\n// 1. Arrays(Listas Ordenadas y Flexibles)\nconsole.log(\"Arreglos\");\n\nlet numeros = [3, 2, 1];\nlet palabras = [\"Hola\", \"Mundo\"];\n\n// Acceder:\nconsole.log(numeros[0]); // 3\n\n// Modificar:\npalabras[1] = \"Ben\";\n\n// Ordenación:\nnumeros.sort((a, b) => a - b); // Ordenar de menor a mayor\n\n// Iteración:\nfor (let i = 0; i < numeros.length; i++) {\n    console.log(`Índice ${i}: ${numeros[i]}`);\n}\n\n// ________________________________________________________\n// 2. Sets(Colecciones de Valores Únicos)\nconsole.log(\"\\nConjuntos\");\n\nlet miConjunto = new Set();\nlet otroConjunto = new Set([2, 3, 4]);\n\n// Inserción:\nmiConjunto.add(1);\nmiConjunto.add(2);\n\n// Buscar:\nconsole.log(otroConjunto.has(3)); // true\n\n// Eliminación:\nmiConjunto.delete(2);\n\n// Verificación:\nconsole.log(miConjunto.has(1)); // true\n\n// Operaciones:\nmiConjunto = new Set([...miConjunto, ...otroConjunto]); // Unión\n\n// Iteración:\notroConjunto.forEach(elemento => {\n    console.log(elemento);\n});\n\n// ________________________________________________________\n// 3. Maps(Pares Clave-Valor con Claves de Cualquier Tipo)\nconsole.log(\"\\nMaps\");\n\nlet map = new Map();\n\n// Agregar pares clave-valor:\nmap.set(\"nombre\", \"Zoe\");\nmap.set(\"edad\", 27);\nmap.set(\"activo\", true);\n\n// Acceder\nconsole.log(map.get(\"nombre\")); // \"Zoe\"\nconsole.log(map.get(\"edad\"));   // 27\n\n// Verificar\nconsole.log(map.has(\"activo\")); // true\n\n// Obtener el tamaño del Map:\nconsole.log(map.size); // 3\n\n// Modificar\nmap.set(\"edad\", 28);\nconsole.log(map.get(\"edad\")); // 28\n\n// Comprobar\nconsole.log(map.has(\"activo\")); // false\n\n// Iteración\nmap.forEach((valor, clave) => {\n    console.log(`Clave: ${clave}, Valor: ${valor}`);\n});\n\nfor (let [clave, valor] of map) {\n    console.log(`Clave: ${clave}, Valor: ${valor}`);\n}\n\n// Eliminar un par clave-valor:\nmap.delete(\"activo\");\n\n// Eliminar todos los elementos del Map:\nmap.clear();\n\n// ________________________________________________________\n// 4. Objects(Pares Clave-Valor para Estructuras Complejas)\nconsole.log(\"Objetos\");\n\nlet persona = {\n    nombre: \"Zoe\",\n    edad: 27,\n    activo: true\n};\n\n// Acceder\nconsole.log(persona.nombre); // \"Zoe\"\nconsole.log(persona[\"edad\"]); // 27\n\n// Modificar\npersona.edad = 28;\nconsole.log(persona.edad); // 28\n\n// Agregar\npersona.pais = \"España\";\nconsole.log(persona.pais); // \"España\"\n\n// ________________________________________________________\n// DIFICULTAD EXTRA\n\nconst readline = require('readline');\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nlet myAgenda = new Map();\n\nconst msg_home = `\nAgenda de contactos\n╔═══════════════════════════╗\n║ 1. Nuevo      4. Editar   ║\n║ 2. Buscar     5. Eliminar ║\n║ 3. Lista      6. Salir    ║\n╚═══════════════════════════╝\n`;\n\nconst Create = () => {\n    rl.question(\"Escribe el nombre: \", (name) => {\n        if (name.length < 1) {\n            Create();\n        } else if (name === \"6\") {\n            console.log(\"Cancelado\");\n            Agenda();\n        } else if (myAgenda.has(name)) {\n            console.log(\"El nombre ya existe.\");\n            Create();\n        } else {\n            rl.question(\"Escribe el número: \", (number) => {\n                if (isNaN(number) || number.length === 0 || number.length > 11) {\n                    console.log(\"Número no válido.\");\n                    Create();\n                } else {\n                    myAgenda.set(name, number);\n                    console.log(\"Guardado\");\n                    Agenda();\n                }\n            });\n        }\n    });\n};\n\nconst Search = () => {\n    rl.question(\"Escribe el nombre: \", (name) => {\n        if (name === \"6\") {\n            console.log(\"Cancelado\");\n            Agenda();\n        } else if (myAgenda.has(name)) {\n            console.log(myAgenda.get(name));\n            Agenda();\n        } else {\n            console.log(\"Contacto no encontrado.\");\n            Agenda();\n        }\n    });\n};\n\nconst List = () => {\n    console.log(\"Lista de contactos:\");\n    const sortedAgenda = new Map([...myAgenda].sort());\n    for (const [key, value] of sortedAgenda) {\n        console.log(`${key}: ${value}`);\n    }\n    Agenda();\n};\n\nconst Edit = () => {\n    rl.question(\"Escribe el nombre: \", (name) => {\n        if (name === \"6\") {\n            console.log(\"Cancelado\");\n            Agenda();\n        } else if (myAgenda.has(name)) {\n            rl.question(\"Escribe el nuevo número: \", (newNumber) => {\n                if (isNaN(newNumber) || newNumber.length === 0 || newNumber.length > 11) {\n                    console.log(\"Número no válido.\");\n                    Edit();\n                } else {\n                    myAgenda.set(name, newNumber);\n                    console.log(\"Contacto editado\");\n                    Agenda();\n                }\n            });\n        } else {\n            console.log(\"Contacto no encontrado.\");\n            Agenda();\n        }\n    });\n};\n\nconst Delete = () => {\n    rl.question(\"Escribe el nombre: \", (name) => {\n        if (name === \"6\") {\n            console.log(\"Cancelado\");\n            Agenda();\n        } else if (myAgenda.has(name)) {\n            myAgenda.delete(name);\n            console.log(\"Contacto eliminado\");\n            Agenda();\n        } else {\n            console.log(\"Contacto no encontrado.\");\n            Agenda();\n        }\n    });\n};\n\nconst Agenda = () => {\n    rl.question(\"Número de opción: \", (option) => {\n        switch (option) {\n            case \"1\":\n                Create();\n                break;\n            case \"2\":\n                Search();\n                break;\n            case \"3\":\n                List();\n                break;\n            case \"4\":\n                Edit();\n                break;\n            case \"5\":\n                Delete();\n                break;\n            case \"6\":\n                console.log(\"Adiós\");\n                rl.close();\n                break;\n            default:\n                console.log(\"Elija una opción entre 1 y 6.\");\n                Agenda();\n                break;\n        }\n    });\n};\n\nAgenda();\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/kodenook.js",
    "content": "'uses strict'\n\n/*\n    Arrays\n*/\n\nlet fruits = ['apple', 'orange', 'banana']\n\n// insert\n\nfruits[3] = 'pineapple'\nfruits.push('lemon')\nfruits.unshift('mango')\n\nconsole.log(fruits)\n\n// edit\n\nfruits[1] = 'grapes'\n\nconsole.log(fruits)\n\n// delete\n\nfruits.pop()\nfruits.shift()\ndelete fruits[3]\n\nconsole.log(fruits)\n\n/*\n    Sets\n*/\n\nletters = new Set(['a', 'b', 'c'])\n\n// insert\n\nletters.add('f')\n\nconsole.log(letters)\n\n// delete\n\nletters.delete('b')\n\nconsole.log(letters)\n/*\n    Maps\n*/\n\nperson = new Map([\n    ['name', 'kodenook'],\n    ['country', 'chile']\n])\n\n// insert\n\nperson.set('continent', '')\n\nconsole.log(person)\n\n// insert\n\nperson.set('continent', 'america')\n\nconsole.log(person)\n\n// delete\n\nperson.delete('continent')\n\nconsole.log(person)\n\n/*\n    Exercise\n*/\n\nconst readline = require('readline');\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nlet option = 0\nlet data = new Map([])\n\nfunction ask() {\n    console.clear()\n\n    console.log('1. search')\n    console.log('2. add')\n    console.log('3. edit')\n    console.log('4. delete')\n    console.log('5. exit')\n    console.log('')\n\n    rl.question('choose an option: ', (input) => {\n        option = parseInt(input.trim());\n\n        switch (option) {\n            case 1:\n                rl.question('name: ', (input) => {\n                    let name = parseInt(input.trim());\n\n                    console.log(data.get(name))\n                    setTimeout(() => {\n                        ask();\n                    }, 2000);\n                })\n                break;\n            case 2:\n                rl.question('name: ', (input) => {\n                    let name = parseInt(input.trim());\n\n                    rl.question('number: ', (input) => {\n                        let number = parseInt(input.trim());\n\n                        data.set(name, number)\n                        ask()\n                    })\n                })\n                break;\n            case 3:\n                rl.question('name: ', (input) => {\n                    let name = parseInt(input.trim());\n\n                    rl.question('number: ', (input) => {\n                        let number = parseInt(input.trim());\n\n                        data.set(name, number)\n                        ask()\n                    })\n                })\n                break;\n            case 4:\n                rl.question('name: ', (input) => {\n                    let name = parseInt(input.trim());\n\n                    data.delete(name)\n\n                    ask()\n                })\n                break;\n            case 5:\n                rl.close()\n                break;\n            default:\n                break;\n        }\n    });\n\n}\n\nask()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/levsistemas.js",
    "content": "/*# #03 ESTRUCTURAS DE DATOS\n> #### Dificultad: Media | Publicación: 15/01/24 | Corrección: 22/01/24\n\n## Ejercicio\n\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n \n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n*/\n\n// ESTRUCTURAS SOPORTADAS\n\n// ARRAY O ARREGLOS\n\nlet myArray1 = [1, 2, 3, 4, 5, 6, 7, 8, 9]\n\nconsole.log(\"\\nArray númerico:\", myArray1)\n\nlet myArrayString = [\"Pedro\", \"Marcos\", \"Horacio\", \"Carlos\", \"Mauricio\"]\n\nconsole.log(\"\\nArray de nombres:\", myArrayString)\n\nconsole.log(\"\\nMi array organizado:\", myArrayString.sort())\n\n//Agregando un elemento al array\nmyArray1.push(10)\n\nconsole.log(\"\\nElemento al final:\", myArray1)\n\nmyArray1[5] = 16\n\nconsole.log(\"\\nElemento posicion 4 modificado:\", myArray1)\n\n//Eliminando el primer elemento e imprimiendo en pantalla\nmyArray1.shift()\n\nconsole.log(\"\\nEliminado el primer elemento:\", myArray1)\n\n//Elimina el último elemento indizado del arreglo\nmyArray1.pop()\n\nconsole.log(\"\\nEliminado el último elemento:\", myArray1)\n\n//Agregar elementos al principio del array\nmyArray1.unshift(\"Brais\", \"Moure\", \"Developer\")\n\nconsole.log(\"\\nAgregado un elemento al principio:\", myArray1)\n\n//Realizar un recorrido de los indices comenzando en el indice 2 hasta la posicion 4\nconst result = myArray1.slice(2, 5)\n\n//Realizar un recorrido de los indices comenzando en el indice 1 hasta la posicion 6\nconsole.log(\"\\nVisualizando algunos elementos del array:\", myArray1.slice(1, 7))\nconsole.log(\"\\nVisualizando otros elementos del array:\", result)\n\n//Eliminar a partir de la posicion o indice 2 del array en ADELANTE hasta la posicion o indice 4 incluido\nconsole.log(\"\\nModo splice:\", myArray1.splice(2, 4))\n\n//Objeto\nlet mySelf = { name: \"Leandro\", age: 38 }\n\nconsole.log(\"\\nEstilo:\", mySelf)\n\n//Objeto - Agregar\n\nmySelf.country = \"Argentina\"\n\nconsole.log(\"\\nAgregando pais:\", mySelf)\n\n//Objeto - Eliminar\n\ndelete mySelf.age\n\nconsole.log(\"\\nEliminando edad:\", mySelf)\n\n//Objeto - Actualizar\n\nmySelf.name = \"SlipKnot\"\n\nconsole.log(\"\\nModificando nombre:\", mySelf)\n\nlet myNewSet = new Set()\nmyNewSet = new Set([\"Brais\", \"Moure\", 38, \"Brais\"])\n\nconsole.log(\"\\nNuevo set:\", myNewSet)\n\nmyNewSet.add(\"Mouredev.pro\")\n\nconsole.log(\"\\nAgregando string al set:\", myNewSet)\n\nmyNewSet.delete(\"Brais\")\n\nconsole.log(\"\\nEliminando la palabra Brais del set:\", myNewSet)\n\nconsole.log(\"\\nEl set contiene la palabra: Moure...\", myNewSet.has(\"Moure\"))\n\nconsole.log(\"\\nVerificando tamaño:\", myNewSet.size)\n\n//Convertir el Set en Array\nlet myArrayOfSet = Array.from(myNewSet)\n\nconsole.log(\"\\nSet convertido a array:\", myArrayOfSet)\n\n//Convertir Array \"nuevamente\" en un Set\nmyNewSetAgain = new Set(myArrayOfSet)\n\nconsole.log(\"\\nConvertir array en set de nuevo:\", myNewSetAgain)\n\nmyNewMap = new Map([[\"name\", \"Brais\"], [\"email\", \"braismoure@gmail.com\"], [\"age\", 37]])\n\nconsole.log(\"\\nNuevo map:\", myNewMap)\n\n//Agregados 2 items (clave, valor) al set myNewMap\nmyNewMap.set(\"alias\", \"mouredev\")\nmyNewMap.set(\"name\", \"Brais Moure\")\n\nconsole.log(\"\\nDos nuevos items clave y valor:\", myNewMap)\n\nmyNewMap.get(\"alias\")\nmyNewMap.has(\"Hello World\")\n\nmyNewMap.delete(\"alias\")\n\nconsole.log(\"\\nBorrado alias:\", myNewMap)\n\nconsole.log(\"\\nTamaño del mapa:\", myNewMap.size)\n\n//Limpiar completamente el Map myNewMap\nmyNewMap.clear()\n\n//DIFICULTAD EXTRA\nlet nombre\nlet telefono\nlet contacto\n\nlet contactos = []\nconst readline = require('readline').createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nfunction menu() {\n    console.log(\"\\nMenú de opciones:\\n\")\n    readline.question(\"1) Agregar un nuevo contacto.\\n2) Editar un contacto.\\n3) Eliminar un contacto.\\n4) Buscar un contacto o registro.\\n5) Salir.\\n\\nSelecciona una opción del menú: \", respuesta => {\n        switch (respuesta) {\n            case \"1\": {\n                addContact()\n                break;\n            }\n            case \"2\": {\n                editPerson()\n                break;\n            }\n            case \"3\": {\n                deleteContact()\n                break;\n            }\n            case \"4\": {\n                findContact()\n                break;\n            }\n            case \"5\": {\n                exit()\n                process.exit()\n            }\n            default:\n                console.log(\"opción incorrecta, regresando al menú\")\n                menu()\n        }\n    })\n}\n\nfunction addContact() {\n    function person() {\n        readline.question(\"¿Cual es tu nombre? \", respuesta => {\n            nombre = respuesta\n            phone()\n        })\n    }\n\n    function phone() {\n        readline.question(\"¿Tu número de telefono? \", respuesta => {\n            if (respuesta.length <= 10) {\n                telefono = parseInt(respuesta)\n                if (isNaN(telefono)) {\n                    console.log(`¡La respuesta ${telefono} no fue un número de teléfono, digita solo números!`)\n                    phone()\n                } else if (typeof telefono === 'number') {\n                    telefono = telefono.toString()\n                    addContactResult()\n                }\n            } else {\n                console.log(`Solo se acepta una cantidad máxima de 10 dígitos (se ingresaron ${respuesta.length} dígitos)`)\n                phone()\n            }\n        })\n    }\n\n    person()\n}\n\nfunction addContactResult() {\n    contactos.push([nombre, telefono])\n    console.log(\"¡Contacto agendado exitosamente!\", contactos)\n    menu()\n}\n\nfunction editPerson() {\n    if (contactos.length === 0) {\n        console.log(\"No hay contactos agendados.\")\n        menu()\n    } else {\n        console.log(\"\\nElige el contacto a editar: \\n\")\n        contactos.map((contacto, index) => {\n            console.log(index, contacto)\n        })\n\n        readline.question(\"\\nNúmero de contacto: \", respuesta => {\n            contacto = parseInt(respuesta)\n            if (isNaN(contacto)) {\n                console.log(\"\\nDato inválido, por favor selecciona un número\")\n                editPerson()\n            } else if (typeof contacto === 'number') {\n                if (contacto >= 0 && contacto <= contactos.length - 1) {\n                    editName()\n                } else {\n                    console.log(\"\\nEl número ingresado para editar el contacto no es valido, verificá...\")\n                    editPerson()\n                }\n            }\n        })\n\n        function editName() {\n            readline.question(\"Edita Nombre: \", respuesta => {\n                nombre = respuesta\n                editPhone()\n            })\n        }\n\n        function editPhone() {\n            readline.question(\"Edita Telefono: \", respuesta => {\n                if (respuesta.length <= 10) {\n                    telefono = parseInt(respuesta)\n                    if (isNaN(telefono)) {\n                        console.log(`\\n¡La respuesta ${telefono} no fue un número de teléfono, digita solo números!`)\n                        editPhone()\n                    } else if (typeof telefono === 'number') {\n                        telefono = telefono.toString()\n                        contactos[contacto] = [nombre, telefono]\n                        console.log(contactos)\n                        console.log(\"\\nRegistro actualizado exitosamente número \" + contacto)\n                        menu()\n                    }\n                } else {\n                    console.log(`\\nSolo se acepta una cantidad máxima de 10 dígitos (se ingresaron ${respuesta.length} dígitos)`)\n                    editPhone()\n                }\n            })\n        }\n    }\n}\n\nfunction deleteContact() {\n    if (contactos.length === 0) {\n        console.log(\"No hay contactos agendados.\")\n        menu()\n    } else {\n        console.log(\"\\nElige el contacto: \\n\")\n        contactos.map((contacto, index) => {\n            console.log(index, contacto)\n        })\n\n        readline.question(\"\\nNúmero de contacto: \", respuesta => {\n            contacto = respuesta\n            removeContact()\n        })\n\n        function removeContact() {\n            console.log(\"\\nEl contacto seleccionado para eliminar es:\", contactos[contacto])\n            contactos.splice(contacto, 1)\n            console.log(\"\\nCantidad de contactos:\", contactos)\n            menu()\n        }\n    }\n}\n\nfunction findContact() {\n    console.log(contactos)\n    if (contactos.length === 0) {\n        console.log(\"\\nNo hay contactos agendados.\\n\")\n        menu()\n    } else {\n        readline.question(\"\\nEscribe lo que estas buscando (parte de un nombre y/o números): \", respuesta => {\n            contacto = respuesta\n            contact()\n        })\n\n        function contact() {\n            nuevoResultado = new Set()\n            contactos.find(elemento => {\n                if(typeof elemento === 'object') {\n                    elemento.find(indice => {\n                        if(indice.includes(contacto)) {\n                            nuevoResultado.add(elemento)\n                        }\n                    })\n                }\n            })\n\n            console.log(\"\\nResultados filtrados sin repetir:\\n\")\n            Array.from(nuevoResultado).map(item => console.log(item))\n\n            console.log('\\nCantidad:', nuevoResultado.size, '\\n')\n            \n            if (nuevoResultado.size === 0) {\n                console.log(`¡No se ha encontrado el resultado que buscas para: ${contacto}!`)\n            }\n            if (nuevoResultado.size === 1) {\n                console.log(`¡Con referencia a \"${contacto}\", se ha encontrado ${nuevoResultado.size} coincidencia!`)\n            } else if (nuevoResultado.size > 1) {\n                console.log(`¡En referencia a \"${contacto}\", se han encontrado ${nuevoResultado.size} coincidencias!`)\n            }\n\n            menu()\n        }\n    }\n}\n\nfunction exit() {\n    readline.close()\n}\n\nmenu()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/lrpeset.js",
    "content": "//  Data Structure\n//  Array\nlet arrayOfNumbers = [0, 1, 2, 3, 4];\n\narrayOfNumbers.push(5); //  Add an element to the end of the array\narrayOfNumbers.unshift(-1); // Add an element to the beginning of the array\n\narrayOfNumbers.pop(); // Removes the last element of the array\narrayOfNumbers.shift(); //  Removes the first element of the array\n\narrayOfNumbers[0] = -1; //  Updates an element of the array\n\narrayOfNumbers.sort((a, b) => a - b); //  Sort the elementos of the array\n\n//  Object\nlet me = {\n  name: \"Isaac\",\n  age: 20,\n};\n\nme.language = \"Spanish\"; //  Add a key to the object\n\ndelete me.language; //  Removes a key of the object\n\nme.age = 25; //  Update a key of the object\n\nlet sortedKeys = Object.keys(me).sort(); //  Sort the keys of the object\n\n//  Set\nlet set = new Set([6, 7, 8, 9, 1]);\n\nset.add(1); //  Add an element to the set\n\nset.delete(9); //   Delete an element of the set\n\nlet sortedArray = Array.from(set).sort((a, b) => a - b); //  Sort the elements of the set in an array\n\n//  Map\nlet map = new Map();\nmap.set(\"name\", \"Isaac\");\nmap.set(\"age\", 25);\n\nmap.set(\"language\", \"Spanish\"); //  Add an element to the map\n\nmap.set(\"age\", 30); //  Update the value of 'age'\n\nmap.delete(\"language\"); //Delete the key 'language'\n\nlet sortedMap = new Map([...map.entries()].sort()); //  Sort the map by keys\n\n//  Extra difficulty\nconst readline = require(\"readline\");\n\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout,\n});\n\nlet contactList = [];\n\nconst searchContact = (name) => {\n  const contact = contactList.find(\n    (c) => c.name.toLowerCase() === name.toLowerCase()\n  );\n  if (contact) {\n    console.log(`Contact found: ${contact.name} - ${contact.phone}`);\n  } else {\n    console.log(`No contact found with the name ${name}.`);\n  }\n};\n\nconst insertContact = (name, phone) => {\n  contactList.push({ name, phone });\n  console.log(`Contact ${name} added successfully.`);\n};\n\nconst updateContact = (name, newPhone) => {\n  const index = contactList.findIndex(\n    (c) => c.name.toLowerCase() === name.toLowerCase()\n  );\n  if (index !== -1) {\n    contactList[index].phone = newPhone;\n    console.log(`Contact ${name} updated successfully.`);\n  } else {\n    console.log(`No contact found with the name ${name}.`);\n  }\n};\n\nconst deleteContact = (name) => {\n  const initialLength = contactList.length;\n  contactList = contactList.filter(\n    (c) => c.name.toLowerCase() !== name.toLowerCase()\n  );\n  if (contactList.length < initialLength) {\n    console.log(`Contact ${name} deleted successfully.`);\n  } else {\n    console.log(`No contact found with the name ${name}.`);\n  }\n};\n\nconst validatePhone = (phone) => {\n  const phoneRegex = /^[0-9]{1,11}$/;\n  return phoneRegex.test(phone);\n};\n\nconst showMenu = () => {\n  rl.question(\n    \"Select the option to do in the contact list: search / add / update / delete / exit\\n\",\n    (option) => handleOption(option)\n  );\n};\n\nconst handleOption = (option) => {\n  switch (option) {\n    case \"search\":\n      rl.question(\"Write the name of the contact to find: \", (name) => {\n        searchContact(name);\n        showMenu();\n      });\n      break;\n\n    case \"add\":\n      rl.question(\"Write the name of the contact to add: \", (name) => {\n        rl.question(\"Write the phone number of the contact: \", (phone) => {\n          if (validatePhone(phone)) {\n            insertContact(name, phone);\n          } else {\n            console.log(\"Invalid phone number, failed to add the contact.\");\n          }\n          showMenu();\n        });\n      });\n      break;\n\n    case \"update\":\n      rl.question(\"Write the name of the contact to update: \", (name) => {\n        rl.question(\"Write the new phone number: \", (newPhone) => {\n          if (validatePhone(newPhone)) {\n            updateContact(name, newPhone);\n          } else {\n            console.log(\"Invalid phone number, failed to update the contact.\");\n          }\n          showMenu();\n        });\n      });\n      break;\n\n    case \"delete\":\n      rl.question(\"Write the name of the contact to delete: \", (name) => {\n        rl.question(\n          `Are you sure to delete ${name} contact? true / false: `,\n          (confirmation) => {\n            if (confirmation !== \"true\") {\n              console.log(`The contact ${name} has not been deleted.`);\n            } else {\n              deleteContact(name);\n              console.log(`The contact ${name} has been deleted.`);\n            }\n            showMenu();\n          }\n        );\n      });\n      break;\n\n    case \"exit\":\n      console.log(\"Thanks for using Contact List 3000!\");\n      rl.close();\n      break;\n\n    default:\n      console.log(\"Invalid option, please try again.\");\n      showMenu();\n      break;\n  }\n};\n\nshowMenu();\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/marcode24.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\n// Arrays\nconst arrayEjemplo = [1, 2, 3, 4, 5];\nconsole.log('Array original:', arrayEjemplo);\n\n// Inserción\narrayEjemplo.push(6);\nconsole.log('Array después de la inserción:', arrayEjemplo);\n\n// Borrado\narrayEjemplo.pop();\nconsole.log('Array después del borrado:', arrayEjemplo);\n\n// Actualización\narrayEjemplo[0] = 10;\nconsole.log('Array después de la actualización:', arrayEjemplo);\n\n// Ordenación\nconst arrayOrdenado = arrayEjemplo.slice().sort();\nconsole.log('Array ordenado:', arrayOrdenado);\n\n// Objetos\nconst objetoEjemplo = { nombre: 'Juan', edad: 25, ciudad: 'Barcelona' };\nconsole.log('Objeto original:', objetoEjemplo);\n\n// Inserción/Actualización\nobjetoEjemplo.profesion = 'Ingeniero';\nconsole.log('Objeto después de la inserción/actualización:', objetoEjemplo);\n\n// Borrado\ndelete objetoEjemplo.edad;\nconsole.log('Objeto después del borrado:', objetoEjemplo);\n\n// Visita mi repo en GitHub para ver y correr los tests de este código --> https://github.com/marcode24/weekly-challenges\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/mariovelascodev.js",
    "content": "//Listas\n\nconsole.log(\"----LISTAS----\");\n\nlista = [1, 2, \"hola\", 3, 4];\nconsole.log(lista);\n\n//Inserción\n//Añade el valor indicado al final de la lista\nlista.push(\"manzana\");\nconsole.log(lista);\n\n//Añade el valor indicado al principio de la lista\nlista.unshift(true);\nconsole.log(lista);\n\n//Borrado\n//Elimina el último valor de la lista\nlista.pop();\nconsole.log(lista);\n\n//Elimina el primer valor de la lista\nlista.shift();\nconsole.log(lista);\n\n//Actualización\n//Se actualiza el valor de la posición indicada\nlista[3] = \"Python\"\nconsole.log(lista);\n\n/*\nCon el método slice() se pueden actualizar los valores del array\n- Primer parámetro la posición a modificar\n- Segundo parámetro el número de valores a modificar\n- Tercer parámetro el nuevo valor\n*/\nlista.splice(4, 1, 54);\nconsole.log(lista);\n\n//Ordenación\nlista.sort();\nconsole.log(lista);\n\n//Objetos\n\nconsole.log(\"----OBJETOS----\");\n\nlet objeto = {\n    nombre: \"Mario\",\n    edad: 33,\n    altura: 1.80\n};\n\nconsole.log(objeto);\n\n//Inserción\nobjeto.developer = true;\n\nconsole.log(objeto);\n//Borrado\ndelete objeto.altura;\n\nconsole.log(objeto);\n\n//Actualizado\nobjeto.nombre = \"Laura\";\n\nconsole.log(objeto);\n\nobjeto[\"nombre\"] = \"Mario\";\nconsole.log(objeto);\n\n//Ordenación\n//Los objetos no pueden ser ordenados\n\n//Map\n\nconsole.log(\"----MAP----\");\n\nlet mapa = new Map();\n\nconsole.log(mapa);\n\n//Inserción\n//Método set(clave, valor) \nmapa.set(\"1\", \"str1\");\nmapa.set(1, 'num1');\nmapa.set(true, 'bool1');\n\nconsole.log(mapa);\n\n//Borrado\n//Método delete(clave)\nmapa.delete(1);\n\nconsole.log(mapa);\n\n//Actualizado\nmapa.set(true, \"bool2\");\n\nconsole.log(mapa);\n\n//Ordenación\n//Los mapas no pueden ser ordenados\n\n//Set\n\nconsole.log(\"----SET----\");\n\nlet miSet = new Set();\n\nconsole.log(miSet);\n\n//Inserción\n//Método add(valor)\nmiSet.add(true);\nmiSet.add(2);\nmiSet.add(\"str\");\n\nconsole.log(miSet)\n\n//Borrado\n//Método delete(valor)\nmiSet.delete(2);\n\nconsole.log(miSet);\n\n//Los Set no pueden ser actualizados ni ordenados\n\n//Extra\n\nconsole.log(\"----EXTRA----\");\n\nfunction contactList() {\n    //Creamos un objeto , que contendrá el nombre y el teléfono de los contactos\n    let agenda = {\n        Mario: 123456678,\n        Sara: 1423423435\n    };\n\n    //Creamos una variable booleana para poder controlar el bucle del menu de opciones\n    let leave = true;\n\n    //Creamos el bucle que contendra el menu de opciones\n    while (leave) {\n        //Mostramos las opciones del menu y preguntamos al usuario que desea hacer\n        let ask = prompt(`¿Qué desea hacer? \n        1 - Búsqueda de contacto \n        2 - Añadir contacto \n        3 - Actualizar contacto\n        4 - Eliminar contacto\n        5 - Salir` );\n\n        let answer = parseInt(ask);\n\n        //Dependiendo de la opción seleccionada el menu entrará en dicha opción\n        switch (answer) {\n            case 1:\n                //Se introduce por consola el nombre del usuario a buscar\n                let search = prompt(\"Introduce el nombre del contacto a buscar \");\n                if (agenda[search] == undefined) {\n                    console.log(\"Usuario no encontrado\");\n                } else {\n                    console.log(agenda[search]);\n                }\n                break;\n            case 2:\n                //Añadimos el nombre y el número de teléfono del nuevo contacto\n                let add = prompt(\"Añade el nombre del nuevo contacto \");\n                let condition = true;\n                //Si el número de teléfono no tiene 9 dígitos o no es un número, se le pedirá al usuario que vuelva a introducir el número\n                while (condition) {\n                    let number = prompt(\"Añade el número de teléfono \");\n                    if (number.length == 9) {\n                        number = parseInt(number);\n                        if (Number.isInteger(number)) {\n                            agenda[add] = number;\n                            console.log(\"Contacto añadido\");\n                            condition = false;\n                        } else {\n                            console.log(\"No has introducido un número\");\n                        }\n                    } else {\n                        console.log(\"La longitud del número es menor o superior a 9 dígitos\");\n                    };\n                };\n                break;\n            case 3:\n                //Se pide por consola el nombre del contacto y el número de teléfono que se actualizará\n                let update_name = prompt(\"Añade el nombre del contacto \");\n                let update_phone = prompt(\"Añade el número de teléfono a actualizar \");\n                agenda[update_name] = parseInt(update_phone);\n                console.log(\"Actualizado el número de teléfono del contacto\");\n                break;\n            case 4:\n                //Se pide por consola el nombre del contacto a eliminar\n                let remove = prompt(\"Añade el nombre del contacto a eliminar \")\n                delete agenda.remove;\n                console.log(`Eliminado el contacto de ${remove}`);\n                break;\n            case 5:\n                //Finalizar el programa\n                leave = false;\n                break;\n            default:\n                console.log(\"Introduce un número entre 1 y 5\");\n        }\n    }\n};\n\ncontactList();\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/mateo423.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto\n *   en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n *   y eliminación de contactos.\n * \n\n- Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n *   y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más\n *   de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.\n */\n\n// Arrays sin Elementos;\nlet arrays = [] //array \nconsole.log(arrays);\nconsole.log(\"..... \")\n\n// Arrays con Elementos\nconst superHeroes = ['Batman', 'Super Man', 'Deadpool', 'Hulk'];\n\n// Arrays Metodo pop() y push();\nconst pop_element = superHeroes.pop()\nconsole.log(superHeroes);\nconsole.log(\"..... \")\n\n// push();\nconst push_element = superHeroes.push('Spider Man');\nconsole.log(superHeroes);\nconsole.log(\".... \")\n\n// Arraus Metodo shift y unshift;\nconst unshift_elment = superHeroes.unshift('Profesor X', 'Aquaman');\nconsole.log(superHeroes);\nconsole.log(\".... \")\n\n// shift;\nconst shift_element = superHeroes.shift();\nconsole.log(superHeroes);\nconsole.log(\".... \")\n\n// Arrays Mapeo\nconst notas = [2, 3, 4, 5, 9];\n\nconst notaPor2 = notas.map((Notas) => {\n  return Notas * 2;\n})\nconsole.log(notaPor2);\nconsole.log(\".... \")\n\n// filter\nconst notas_1 = [4, 6, 8, 9, 10, 2, 3, 5]\nconst notasPar = notas_1.filter((unaNotaPar) => {\n  return unaNotaPar % 2 === 0;\n});\nif (notasPar.length === 0) {\n  console.log('Ninguna nota cumple con la condicion');\n} else {\n  console.log(notasPar);\n};\n\n// ordenación\nconst fruta = ['Manzana', 'Banana', 'Pera', 'Naranja'];\n\nfruta.sort();\nconsole.log(fruta);\nconsole.log(\"..... \")\n\n// Actualizacio\nconst juegos = ['Pacman', 'Call of Duty ', 'Fortnite'];\njuegos[0] = 'Pokemon';\nconsole.log(juegos);\nconsole.log(\"..... \")\n\n// Eliminacio\ndelete juegos[0];\nconsole.log(juegos);\nconsole.log(\"......\")\n\n// Busqueda del indexOf();\n\nconsole.log(\"....  indexOf()... \")\nconst index_elemento = juegos.indexOf('Fortnite');\nconsole.log(index_elemento);\nconsole.log(\".... \")\n\n// Objeto\nlet objeto = {\n  nombre: \"Mario\",\n  edad: 33,\n  altura: 1.80\n};\nconsole.log(objeto);\nconsole.log(\".... \")\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n *   y eliminación de contactos.\n * \n\n- Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n *   y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más\n *   de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.\n */\nconsole.log(\"Bienvenidos ala Agenda de Contactos\");\n\nconst agenda_contacto = function () {\n  let agenda = [\n    { nombre: \"Matteo\", numero: \"3123113498\" },\n    { nombre: \"Laura\", numero: \"3138434573\" }\n  ];\n\n  let leave = false;\n\n  while (!leave) {\n    let opcion = prompt(`¿Qué desea hacer? \n        1 - Búsqueda de contacto \n        2 - Añadir contacto \n        3 - Actualizar contacto\n        4 - Eliminar contacto\n        5 - Salir`);\n\n    switch (opcion) {\n      case '1':\n        let search_contacto = prompt(\"Ingrese el nombre del contacto que deseas buscar: \");\n        let contactoEncontrado = agenda.find(contacto => contacto.nombre === search_contacto);\n        if (contactoEncontrado) {\n          console.log(`Nombre: ${contactoEncontrado.nombre}, Número: ${contactoEncontrado.numero}`);\n        } else {\n          console.log(\"Contacto no encontrado\");\n        }\n        break;\n\n      case '2':\n        let nombre = prompt(\"Ingrese el Nombre del contacto que quieres agregar: \");\n        let telefono = prompt(\"Ingrese el Número del contacto que quieres agregar: \");\n        if (telefono.length <= 11) {\n          agenda.push({ nombre: nombre, numero: telefono });\n          console.log(\"Contacto agregado\");\n        } else {\n          console.log(\"Error: El número de teléfono debe tener 11 dígitos o menos\");\n        }\n        break;\n\n      case '3':\n        let nombreAntiguo = prompt(\"Ingrese el nombre del contacto que deseas actualizar: \");\n        let nombreNuevo = prompt(\"Ingrese el nuevo nombre del contacto: \");\n        let nuevoTelefono = prompt(\"Ingrese el nuevo número de teléfono para este contacto: \");\n        let contactoParaActualizar = agenda.find(contacto => contacto.nombre === nombreAntiguo);\n        if (contactoParaActualizar) {\n          contactoParaActualizar.nombre = nombreNuevo;\n          contactoParaActualizar.numero = nuevoTelefono;\n          console.log(\"Contacto actualizado\");\n        } else {\n          console.log(\"Contacto no encontrado\");\n        }\n        break;\n\n      case '4':\n        let eliminar_contacto = prompt(\"Ingrese el nombre del contacto que desea eliminar: \");\n        let index = agenda.findIndex(contacto => contacto.nombre === eliminar_contacto);\n        if (index !== -1) {\n          agenda.splice(index, 1);\n          console.log(\"Contacto eliminado\");\n        } else {\n          console.log(\"Contacto no encontrado\");\n        }\n        break;\n\n      case '5':\n        leave = true;\n        console.log('Saliendo de la agenda...');\n        break;\n\n      default:\n        console.log('Opción no válida, por favor intente de nuevo');\n    }\n  }\n}\n\nagenda_contacto();\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/maximiliano1997.js",
    "content": "/*\r\n* EJERCICIO:\r\n* - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\r\n* - Utiliza operaciones de inserción, borrado, actualización y ordenación.\r\n*\r\n* DIFICULTAD EXTRA (opcional):\r\n* Crea una agenda de contactos por terminal.\r\n* - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\r\n * - Cada contacto debe tener un nombre y un número de teléfono.\r\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\r\n *   los datos necesarios para llevarla a cabo.\r\n * - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\r\n *   (o el número de dígitos que quieras)\r\n * - También se debe proponer una operación de finalización del programa.\r\n */\r\n\r\n\r\n\r\n\r\n// SOLUCION:\r\n\r\n\r\n/* En Javascript tenemos las siguientes estructuras de datos nativas con sus respectivos metodos de creacion, insercion, borrrado, actualizacion y orden.\r\n1- Array        <-- Estructura ordenada de datos (string, numbers, arrays, objetos, etc)\r\n2- Objetos      <-- Coleccion Clave - Valor tipo diccionario\r\n3- MAP          <-- Coleccion clave - valor\r\n4- SET          <-- Conjunto de valores unicos\r\n*/\r\n\r\n\r\n/////////////////////////// ARRAY /////////////////////////\r\nconsole.log('Array: ')\r\n\r\n// Creacion\r\nlet familiares = ['Imanol', 'Sebastian', 'Carolina', 'Alexis']\r\nconsole.log(familiares)\r\n\r\n// Insercion\r\nfamiliares.push('Pablo')\r\nconsole.log(familiares)\r\n\r\n// Actualizacion\r\nfamiliares[0] = 'Santino'\r\nconsole.log(familiares)\r\n\r\n//Borrado\r\nfamiliares.pop()\r\nconsole.log(familiares)\r\n\r\n// Ordenar\r\nfamiliares.sort((a, b) => a - b)\r\nconsole.log(familiares)\r\n\r\n/////////////////////////// OBJETOS /////////////////////////\r\nconsole.log('OBJETO: ')\r\n\r\n// Creacion\r\nlet pais = { nombre: 'Argentina', poblacion: 50000000 }\r\nconsole.log(pais)\r\n\r\n// Insercion\r\npais.capital = 'Buenos Aires'\r\nconsole.log(pais)\r\n\r\n// Actualizacion\r\npais.poblacion = 47000000\r\nconsole.log(pais)\r\n\r\n// Borrado\r\ndelete pais.capital\r\nconsole.log(pais)\r\n\r\n/////////////////////////// MAP /////////////////////////\r\nconsole.log('MAP: ')\r\n\r\n// Creacion\r\nlet mapa = new Map([\r\n    ['uno', 1],\r\n    ['dos', 2],\r\n])\r\nconsole.log(mapa)\r\n\r\n// Insercion\r\nmapa.set('tres', 3)\r\nconsole.log(mapa)\r\n\r\n// Actualizacion\r\nmapa.set('uno', 0)\r\nconsole.log(mapa)\r\n\r\n// Borrado\r\nmapa.delete('uno')\r\n\r\n// Ordenado\r\n// let nuevoMapaOrdenado = new Map([...mapa.entries().sort()])\r\n\r\n/////////////////////////// SET /////////////////////////\r\nconsole.log('SET: ')\r\n\r\n// Creacion\r\nlet conjuntoSet = new Set([5, 2, 3, 4, 1])\r\nconsole.log(conjuntoSet)\r\n\r\n// Insercion\r\nconjuntoSet.add(0)\r\nconsole.log(conjuntoSet)\r\n\r\n// Borrado\r\nconjuntoSet.delete(5)\r\nconsole.log(conjuntoSet)\r\n\r\n// Actualizacion\r\nconjuntoSet.delete(1)\r\nconjuntoSet.add(10)\r\nconsole.log(conjuntoSet)\r\n\r\n\r\n/*\r\n    * DIFICULTAD EXTRA(opcional):\r\n* Crea una agenda de contactos por terminal.\r\n* - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\r\n * - Cada contacto debe tener un nombre y un número de teléfono.\r\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\r\n    * los datos necesarios para llevarla a cabo.\r\n * - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\r\n * (o el número de dígitos que quieras)\r\n * - También se debe proponer una operación de finalización del programa.\r\n */\r\n\r\nconsole.log(`\\n\\n\\n\\n\\n\\n\\n\\n Bienvenido a tu Agenda de Contactos`)\r\n\r\nconst readline = require('readline')\r\nconst { stdin: input, stdout: output } = require('node:process')\r\n\r\nconst rl = readline.createInterface({ input, output })\r\n\r\n\r\nfunction programa() {\r\n\r\n\r\n    const agenda = [\r\n        { id: 1, nombre: 'Imanol', numero: 3624701656 },\r\n        { id: 2, nombre: 'Lucas', numero: 3624156585 },\r\n        { id: 3, nombre: 'Sebastian', numero: 3624255554 },\r\n    ]\r\n    // console.log()\r\n\r\n    function menu() {\r\n        rl.question(`\r\n                Selecciona el tipo de operaciono a realizar:\r\n                1 <-- para Ver Agenta Completa\r\n                2 <-- para Agendar un nuevo contacto\r\n                3 <-- para Actualizar un Contacto\r\n                4 <-- para Eliminar un Contacto\r\n                5 <-- para Buscar un Contacto Especifico\r\n                0 <-- Cerrar menu/programa\r\n                `, (respuesta) => {\r\n\r\n            switch (respuesta) {\r\n                case '1':\r\n                    mostrarAgenda()\r\n                    break;\r\n                case '2':\r\n                    crearNuevoContacto()\r\n                    break;\r\n                case '3':\r\n                    actualizarContacto()\r\n                    break;\r\n                case '4':\r\n                    eliminarContacto()\r\n                    break;\r\n                case '5':\r\n                    buscarContacto()\r\n                    break;\r\n                case '0':\r\n                    console.clear()\r\n                    console.log('Menu/programa finalizado !!!!')\r\n                    rl.close()\r\n                default:\r\n                    'No has seleccionado ninguna de las opciones !'\r\n                    rl.question('')\r\n            }\r\n        })\r\n    }\r\n    menu()\r\n\r\n\r\n    const mostrarAgenda = () => {\r\n        console.clear()\r\n        console.log(`Agenda completa: `)\r\n        console.log(agenda)\r\n\r\n        rl.question('Presione (m) para volver al menu: ', (res) => { if (res === 'm') return menu() })\r\n    }\r\n\r\n    const crearNuevoContacto = () => {\r\n        console.clear()\r\n        console.log(agenda)\r\n        rl.question('Escribe Nombre del nuevo contaco: ', (nombre) => {\r\n            rl.question('Ahora escribe el Numero: ', (numero) => {\r\n                agenda.push({ id: agenda.length + 1, nombre: nombre, numero: Number(numero) })\r\n                console.log('Contacto Agendado:  \\n ', agenda)\r\n\r\n\r\n                // console.cls()\r\n                rl.question('Presione (m) para volver al menu: ', (res) => {\r\n                    if (res === 'm') {\r\n                        menu()\r\n                    }\r\n                })\r\n            })\r\n        })\r\n\r\n\r\n    }\r\n\r\n    const actualizarContacto = () => {\r\n        console.clear()\r\n        console.log('\\n Agenda de Contactos:  \\n', agenda.map(a => `id: ${a.id}, nombre: ${a.nombre}, numero: ${a.numero}`))\r\n        rl.question('Selecciona el ID del contacto que quieres Actualizar: ', (id) => {\r\n            let idContact = Number(id)\r\n            agenda.map(contact => {\r\n                if (contact.id === Number(idContact)) {\r\n                    console.clear(), console.log(`\\n Contacto a ser Actualizado: id: ----> id: ${contact.id}, nombre: ${contact.nombre}, numero: ${contact.numero}`)\r\n\r\n                    rl.question('Escribe Nuevo Nombre del Contacto: ', (nombreActualizado) => {\r\n                        rl.question('Escribe Nuevo Numero del Contacto: ', (numeroActualizado) => {\r\n                            contact.nombre = nombreActualizado\r\n                            contact.numero = numeroActualizado\r\n                            // agenda.push({ id: contact.id, nombre: contact.nombre, numero: contact.numero })\r\n                            mostrarAgenda()\r\n                        })\r\n                    })\r\n                }\r\n            })\r\n        })\r\n\r\n    }\r\n\r\n    const eliminarContacto = () => {\r\n        console.clear()\r\n        console.log('\\n Agenda de Contactos:  \\n', agenda.map(a => `id: ${a.id}, nombre: ${a.nombre}, numero: ${a.numero}`))\r\n\r\n        rl.question('Selecciona el (ID) del Contacto a Eliminar: ', (resId) => {\r\n\r\n            let contactToDelete = agenda.findIndex(i => agenda.id === Number(resId) - 1)\r\n            agenda.splice(contactToDelete, 1)\r\n\r\n\r\n            rl.question('Presione (m) para volver al menu: ', (res) => {\r\n                if (res === 'm') {\r\n                    menu()\r\n                }\r\n            })\r\n        })\r\n    }\r\n\r\n    const buscarContacto = () => {\r\n        console.clear()\r\n\r\n        rl.question('Escriba el Nombre o Numero del contacto Agendado a Buscar: ', (toSearch) => {\r\n\r\n            const buscarContacto = agenda.find(c =>\r\n                c.nombre.toLowerCase() == toSearch.toLowerCase() ||\r\n                c.numero == Number(toSearch)\r\n            )\r\n\r\n            if (buscarContacto) {\r\n                console.log('Contacto Encontrado: ', buscarContacto)\r\n            } else {\r\n                console.log('No se ha encontrado ningun Contacto.')\r\n            }\r\n\r\n\r\n\r\n            rl.question('Presione (m) para volver al menu: ', (res) => {\r\n                if (res === 'm') {\r\n                    menu()\r\n                }\r\n            })\r\n        })\r\n\r\n    }\r\n}\r\n\r\n\r\nprograma()\r\n\r\n\r\n\r\n\r\n\r\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/miguelex.js",
    "content": "// Ejemplo de array\n\nlet array = [1, 2, 3, 4, 5];\nconsole.log(array);\n\n// Añando un elemento al final del array\n\narray.push(6);\nconsole.log(array);\n\n// Añadiendo un elemento al principio del array\n\narray.unshift(0);\nconsole.log(array);\n\n// Añadir en un indice concreto\n\narray.splice(3, 0, 3.5);\nconsole.log(array);\n\n// Eliminar el ultimo elemento del array\n\narray.pop();\nconsole.log(array);\n\n// Eliminar el primer elemento del array\n\narray.shift();\nconsole.log(array);\n\n// Eliminar un elemento en un indice concreto\n\narray.splice(3, 1);\nconsole.log(array);\n\n//Ejemplo de objeto\n\nlet objeto = {\n    nombre: \"Miguel\",\n    apellidos: \"Delgado\",\n    edad: 20\n}\n\nconsole.log(objeto);\n\n// Añadir campo a un objeto\n\nobjeto.direccion = \"Calle falsa 123\";\nconsole.log(objeto);\n\n// Eliminar campo de un objeto\n\ndelete objeto.edad;\nconsole.log(objeto);\n\n// Ejemplo de map\n\nlet mapa = new Map();\n\nmapa.set(\"nombre\", \"Miguel\");\nmapa.set(\"apellidos\", \"Delgado\");\nmapa.set(\"edad\", 20);\n\nconsole.log(mapa);\n\n// Añadir al mapa\n\nmapa.set(\"direccion\", \"Calle falsa 123\");\nconsole.log(mapa);\n\n// Eliminar del mapa\n\nmapa.delete(\"edad\");\nconsole.log(mapa);\n\n// Ejemplo de set\n\nlet set = new Set();\n\nset.add(\"Miguel\");\nset.add(\"Delgado\");\nset.add(20);\n\nconsole.log(set);\n\n// Añadir al set\n\nset.add(\"Calle falsa 123\");\nconsole.log(set);\n\n// Eliminar del set\n\nset.delete(20);\nconsole.log(set);\n\n// Extra\n\nconst readline = require('readline');\n\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout\n});\n\nconst agenda = {};\n\nfunction validarNumeroTelefono(numero) {\n  return /^\\d{1,11}$/.test(numero);\n}\n\nfunction ejecutarPrograma() {\n  rl.question('¿Qué operación deseas realizar? (buscar, insertar, actualizar, eliminar, salir): ', (operacion) => {\n    operacion = operacion.toLowerCase();\n\n    if (operacion === 'salir') {\n      console.log('Saliendo del programa. ¡Hasta luego!');\n      rl.close();\n    } else if (operacion === 'buscar') {\n      rl.question('Ingrese el nombre del contacto a buscar: ', (nombre) => {\n        if (agenda[nombre]) {\n          console.log(`Nombre: ${nombre}, Teléfono: ${agenda[nombre]}`);\n        } else {\n          console.log(`El contacto \"${nombre}\" no se encuentra en la agenda.`);\n        }\n        ejecutarPrograma(); \n      });\n    } else if (operacion === 'insertar') {\n        rl.question('Ingrese el nombre del nuevo contacto: ', (nombre) => {\n        rl.question('Ingrese el número de teléfono del nuevo contacto: ', (telefono) => {\n          if (validarNumeroTelefono(telefono)) {\n            agenda[nombre] = telefono;\n            console.log(`Contacto \"${nombre}\" insertado correctamente.`);\n          } else {\n            console.log('Número de teléfono no válido. Debe ser numérico y tener entre 1 y 11 dígitos.');\n          }\n          ejecutarPrograma(); \n        });\n      });\n    } else if (operacion === 'actualizar') {\n        rl.question('Ingrese el nombre del contacto a actualizar: ', (nombre) => {\n        if (agenda[nombre]) {\n          rl.question('Ingrese el nuevo número de teléfono: ', (nuevoTelefono) => {\n            if (validarNumeroTelefono(nuevoTelefono)) {\n              agenda[nombre] = nuevoTelefono;\n              console.log(`Contacto \"${nombre}\" actualizado correctamente.`);\n            } else {\n              console.log('Número de teléfono no válido. Debe ser numérico y tener entre 1 y 11 dígitos.');\n            }\n            ejecutarPrograma(); \n          });\n        } else {\n          console.log(`El contacto \"${nombre}\" no se encuentra en la agenda.`);\n          ejecutarPrograma(); \n        }\n      });\n    } else if (operacion === 'eliminar') {\n        rl.question('Ingrese el nombre del contacto a eliminar: ', (nombre) => {\n        if (agenda[nombre]) {\n          delete agenda[nombre];\n          console.log(`Contacto \"${nombre}\" eliminado correctamente.`);\n        } else {\n          console.log(`El contacto \"${nombre}\" no se encuentra en la agenda.`);\n        }\n        ejecutarPrograma(); \n      });\n    } else {\n      console.log('Operación no válida. Por favor, ingrese una operación válida.');\n      ejecutarPrograma(); \n    }\n  });\n}\n\nconsole.log('Bienvenido a la Agenda de Contactos por Terminal.');\nejecutarPrograma();\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/misterdan100.js",
    "content": "const readline = require('readline')\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout,\n})\n\nclass ContactsAgenda {\n    constructor() {\n        this.contacts = [\n            { name: 'daniel', number: 3107802775, id: 1 },\n            { name: 'emma', number: 3123730300, id: 2 }\n        ]\n    }\n\n    showMenu() {\n        console.log('-------------')\n        console.log('\\x1b[33m%s\\x1b[0m', 'Menu options:')\n        console.log('1. Show agenda')\n        console.log('2. Add new contact')\n        console.log('3. Update a contact')\n        console.log('4. Search a contact')\n        console.log('5. Delete a contact')\n        console.log('6. Exit')\n\n        const options = {\n            1: () => this.showAgenda(),\n            2: () => this.addContact(),\n            3: () => this.updateContact(),\n            4: () => this.searchContact(),\n            5: () => this.deleteContact(),\n            6: () => this.exit(),\n        }\n\n        rl.question('Select an option: ', (opt) => {\n            options[opt]()\n            if(opt === '6') {\n                rl.close()\n            }\n\n        })\n    }\n\n    showAgenda() {\n        if(!this.contacts.length) {\n            console.log('\\x1b[31m%s\\x1b[0m', 'The agenda is empty')\n            this.showMenu()\n            return\n        }\n        console.log('\\x1b[32m%s\\x1b[0m', `You have ${this.contacts.length} contact in the agenda.`)\n        this.contacts.forEach(contact => console.log(contact))\n        this.showMenu()\n    }\n\n    addContact() {\n        const newContact = {}\n        \n        const askNumber = () => {\n            rl.question('Input the contact number: ', (number) => {\n                if(!isNaN(number) && number.trim() !== '' && number.length === 10) {\n                    newContact.number = +number\n                    newContact.id = this.contacts.length ? this.contacts.length + 1 : 1 \n                    this.contacts.push(newContact)\n                    console.log(this.contacts)\n                    this.showMenu()\n                } else {\n                    console.log('Invalid number')\n                    askNumber()\n                }\n            })\n        }\n\n        const askName = () => {\n\n            rl.question('Input the new contact name: ', (name) => {\n                if(name.trim().length > 0) {\n                    newContact.name = name\n                    askNumber()\n                } else {\n                    askName()\n                }\n            })\n        }\n        askName()\n    }\n\n    searchContact() {\n        rl.question('Input the name or number to search contact: ', (data) => {\n            let result \n            if(isNaN(data)) {\n                result = this.contacts.filter( contact => contact.name.includes(data))\n            } else {\n                result = this.contacts.filter( contact => contact.number.toString().includes(data))\n            }\n            if(result.length > 0) {\n                console.log('\\x1b[32m%s\\x1b[0m', 'Search result:')\n                result.forEach(item => console.log(item))\n                this.showMenu()\n                return\n            }\n            console.log('\\x1b[31m%s\\x1b[0m', 'Any contact found')\n            this.showMenu()\n        })\n\n\n    }\n\n    updateContact() {\n        console.log('\\x1b[32m%s\\x1b[0m', 'Contats in the agenda.')\n        this.contacts.forEach(contact => console.log(contact))\n        rl.question('Input contact ID to update: ', (contactId) => {\n            const contactIDs = this.contacts.reduce((total, item) => [...total, item.id],[])\n            if(!contactIDs.includes(+contactId)) {\n                console.log('\\x1b[32m%s\\x1b[0m', 'ID not valid')\n                this.updateContact()\n                return\n            }\n\n            const newContactData = {}\n            const askNumber = () => {\n                rl.question('Input the contact number: ', (number) => {\n                    if(!isNaN(number) && number.trim() !== '' && number.length === 10) {\n                        newContactData.number = +number\n                        this.contacts.map(currentContact => {\n                            if(currentContact.id === contactId) {\n                                currentContact.name = newContactData.name\n                                currentContact.number = newContactData.number\n                                return currentContact\n                            }\n                            return currentContact\n                        })\n                        console.log('\\x1b[32m%s\\x1b[0m', 'Contact updated successfully!')\n                        console.log({...newContactData, id: +contactId})\n                        this.showMenu()\n                    } else {\n                        console.log('Invalid number')\n                        askNumber()\n                    }\n                })\n            }\n    \n            const askName = () => {\n    \n                rl.question('Input the new contact name: ', (name) => {\n                    if(name.trim().length > 0) {\n                        newContactData.name = name\n                        askNumber()\n                    } else {\n                        askName()\n                    }\n                })\n            }\n            askName()\n        })\n    }\n\n    deleteContact() {\n        console.log('\\x1b[32m%s\\x1b[0m', 'Contats in the agenda.')\n        this.contacts.forEach(contact => console.log(contact))\n        rl.question('Input contact ID to update: ', (contactId) => {\n            const contactIDs = this.contacts.reduce((total, item) => [...total, item.id],[])\n            if(!contactIDs.includes(+contactId)) {\n                console.log('\\x1b[32m%s\\x1b[0m', 'ID not valid')\n                this.deleteContact()\n                return\n            }\n\n            const filteredContacts = this.contacts.filter( contact => contact.id !== +contactId)\n            this.contacts = filteredContacts\n            console.log('\\x1b[32m%s\\x1b[0m', 'Contact deleted successfully')\n            this.showMenu()\n        })\n\n    }\n\n    exit() {\n        console.log('\\n')\n        console.log('App closed!')\n    }\n}\n\nconst newAgenda = new ContactsAgenda()\nnewAgenda.showMenu()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/natalyjoanna.js",
    "content": "\nArreglos\nlet arrayString = [\"Morado\", \"Rosa\", \"Verde\", \"Azul\", \"Rojo\"]\nlet arrayNumeros = [ 2021, 2023, 2022, 2020, 2024]\nlet arrayMixto = [\"Chico\", 12, false, \"Mediano\", true, 16, \"Grande\", 23, true]\n\nconsole.log(\"Lista de strings\", arrayString)\nconsole.log(\"Lista de numeros\", arrayNumeros)\nconsole.log(\"Lista de mixtos\", arrayMixto)\n\n// Arreglos | Insertar dato al final de una lista\narrayString.push(\"Naranja\")\nconsole.log(\"Lista actualizada string: \", arrayString)\n\n// Arreglos | Insertar dato al principio de una lista\narrayMixto.unshift(\"WTF\")\nconsole.log(\"Lista actualizada mixto: \", arrayMixto)\n\n// Arreglos | Insertar dato en una posicion en concreto\narrayString.splice(2,1,\"Dorado\")\nconsole.log(\"Lista actualizada string con Dorado: \", arrayString)\n\n// Arreglos | Actualizar dato especifico de la lista\narrayString[3] = \"Azul Marino\"\nconsole.log(\"Dato actualizado string: \", arrayString)\n\n\n// Arreglos | Eliminar dato ultima de una lista\narrayNumeros.pop()\nconsole.log(\"Lista actualizada numeros: \", arrayNumeros)\n\n// Arreglos | Eliminar dato primero de una lista\narrayNumeros.shift()\nconsole.log(\"Lista actualizada numeros: \", arrayNumeros)\n\n// Arreglos | Concatenar dos listas\nlet concatenado = arrayString.concat(arrayNumeros)\nconsole.log(\"Concatenado: \", concatenado)\n\n// Arreglos | Ubicar dato especifico en una lista por su indice\nlet index = 4\nconsole.log(`En el indice ${index} se encuentra el elemento ${arrayMixto.at(index)} `)\n\n// Arreglos | Ordenar lista\nlet listaOrdenata = arrayNumeros.sort()\nconsole.log(\"Lista ordenada numeros: \", listaOrdenata)\n\n// Objetos\n\nlet objeto = {\n  titulo: \"Deadpool & Wolverine\",\n  genero: \"Accion\",\n  año: 2024\n}\nconsole.log(\"Objeto: \", objeto)\nconsole.log(\"Genero de la pelicula: \", objeto.genero)\nobjeto[\"director\"] = \"Shawn Levy\" // Agregar dato\nconsole.log(\"Objeto actualizado: \", objeto)\nobjeto[\"genero\"] = \"Comedia\" // Modificar valor\nconsole.log(\"Objeto genero actualizado: \", objeto)\n// Set\n\nlet set = new Set()\nset.add(1)\nset.add(2)\nset.add(3)\nset.add(1) // No añade datos repetidos\n\nconsole.log(\"Set: \", set)\nconsole.log(\"Set actualizado: \", set)\nset.delete(1)\nconsole.log(\"Set actualizado: \", set)\nset.clear() // Limpiar set\n\n// DIFICULTAD EXTRA\n\nlet contacto = {}\n\nconst readline = require('readline')\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n})\n\nfunction agendaMenu() {\n  console.log(\"1. Mostrar todos los contactos\")\n  console.log(\"2. Buscar contacto\")\n  console.log(\"3. Insertar contacto\")\n  console.log(\"4. Actualizar contacto\")\n  console.log(\"5. Eliminar contacto\")\n  console.log(\"6. Salir\\n\")\n  rl.question(\"Elige una opcion: \", (opcion) => {\n    switch (opcion) {\n      case '1':\n          mostrarContactos();\n          break;\n      case '2':\n          buscar();\n          break;\n      case '3':\n          insertar();\n          break;\n      case '4':\n          actualizar();\n          break;\n      case '5':\n          eliminar();\n          break;\n      case '6':\n          salir();\n          break;\n      default:\n          console.log(\"Debes introducir un valor.\");\n          agendaMenu();\n          break;\n  }\n  })\n}\n\nfunction mostrarContactos() { \n  for(con in contacto) {\n    console.log(`Contactos: Nombre: ${con} - Telefono: ${contacto[con]}\\n`)\n  }\n  agendaMenu();\n}\n\n\nfunction buscar() {\n  rl.question(\"Nombre del contacto: \", (nombre) => {\n    if (contacto[nombre]) {\n      console.log(`Contacto encontrado: ${nombre} - ${contacto[nombre]}\\n`)\n    } else {\n      console.log(\"No se encontro el contacto\\n\")\n    }\n    agendaMenu()\n  })\n}\n\nfunction insertar() {\n  rl.question(\"Nombre del nuevo contacto: \", (nombre) => {\n    rl.question(\"Telefono del nuevo contacto: \", (telefono) => {\n      if(validarTelefono(telefono)) {\n        contacto[nombre] = telefono\n        console.log(\"Se agrego el contacto\\n\")\n      } else {\n        console.log(\"Numero de telefono no valido\\n\")\n        agendaMenu()\n      }\n      agendaMenu()\n    })\n  })\n}\n\nfunction actualizar() {\n  rl.question(\"Nombre del contacto a actualizar: \", (nombre) => {\n    if(contacto[nombre]) {\n      rl.question(\"Actualizar telefono: \", (telefono) => {\n        if (validarTelefono(telefono)) {\n          contacto[nombre] = telefono\n          console.log(\"Se actualizo el contacto\\n\")\n        } else {\n          console.log(\"Numero de telefono no valido\\n\")\n          agendaMenu()\n        }\n      })\n    } else {\n      console.log(\"No se encontro el contacto\\n\")\n    }\n    agendaMenu()\n  })\n}\n\nfunction eliminar() {\n  rl.question(\"Nombre del contacto: \", (nombre) => {\n    if (contacto[nombre]) {\n      delete contacto[nombre]\n      console.log(\"Se elimino el contacto\\n\")\n    } else {\n      console.log(\"No se encontro el contacto\\n\")\n    }\n    agendaMenu()\n  })\n}\n\nfunction salir() {\nconsole.log(\"Saliendo...\");\n rl.close()\n}\n\nfunction validarTelefono(telefono) {\n  const regex = /^\\d{10}$/;\n  return regex.test(telefono);\n}\n\nagendaMenu()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/nlarrea.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\n// ARRAY\n\nconst fruits = ['apple', 'orange', 'pear', 'banana'];\n\n// Insert new items\n\nfruits.push('melon');               // append at the end\nfruits.unshift('strawberry');       // insert at the beginning\nfruits.splice(2, 0, 'pineapple');   // insert in position 2 (starts at 0)\n\nconsole.log(fruits);\n// [ 'strawberry', 'apple', 'pineapple', 'orange', 'pear', 'banana', 'melon' ]\n\n// Remove items from array\n\nfruits.pop();           // removes 'melon' and returns it from array\nfruits.shift();         // removes 'strawberry' and returns it\nfruits.splice(2, 1);    // removes the item in position 2 (starts at 0)\n\nconsole.log(fruits);    // [ 'apple', 'pineapple', 'pear', 'banana' ]\n\n// Update the array\n\nfruits[1] = 'peach';    // Modify the item at index 1 to 'peach'\nconsole.log(fruits);    // [ 'apple', 'peach', 'pear', 'banana' ]\nfruits.splice(2, 1, 'melon');   // Remove item at 2nd index and add there the 'melon' value\nconsole.log(fruits);            // [ 'apple', 'peach', 'melon', 'banana' ]\n\n// Order arrays\n\nconsole.log(fruits);    // [ 'apple', 'peach', 'melon', 'banana' ]\nconst orderedFruits = fruits.toSorted();    // Order without modifying the original\nconsole.log(fruits);    // [ 'apple', 'peach', 'melon', 'banana' ]\nconsole.log(orderedFruits); // [ 'apple', 'banana', 'melon', 'peach' ]\n\nconst numbers = [1, 4, 2, 8, 11];\nlet orderedNumbers = numbers.toSorted((a, b) => a - b);   // to order numbers in ascending\nconsole.log(orderedNumbers);    // [ 1, 2, 4, 8, 11 ]\norderedNumbers = numbers.toSorted((a, b) => b - a);   // to order numbers in descending\nconsole.log(orderedNumbers);    // [ 11, 8, 4, 2, 1 ]\n\n\n// SET -> removes duplicates\n\nconst fruitsSet = new Set(['apple', 'orange', 'pear', 'banana', 'banana']);\nconsole.log(fruitsSet);\n// Set { 0: 'apple', 1: 'orange', 2: 'pear', 3: 'banana' }\n\n// Insert new items\n\nfruitsSet.add('melon');\nconsole.log(fruitsSet);\n// Set { 0: 'apple', 1: 'orange', 2: 'pear', 3: 'banana', 4: 'melon' }\n\n// Remove one item\n\nfruitsSet.delete('pear');\nconsole.log(fruitsSet);\n// Set { 0: 'apple', 1: 'orange', 2: 'banana', 3: 'melon' }\n\n// Remove all\n\nfruitsSet.clear();\nconsole.log(fruitsSet);\n// Set {}\n\n\n// OBJECTS\n\nconst person = {\n    name: 'Naia',\n    age: 25\n};\n\n// Insert new data\n\nperson.country = 'Spain';\nconsole.log(person);\n// { name: 'Naia', age: 25, country: 'Spain' }\n\n// Update data\n\nperson.age = 26;\nconsole.log(person);\n// { name: 'Naia', age: 26, country: 'Spain' }\n\n// Remove data\n\ndelete person.country;\nconsole.log(person);\n// { name: 'Naia', age: 26 }\n\n\n/* DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\nconst readline = require('readline');\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nconst contactList = [];\n\nconst printMenu = () => {\n    console.log('\\nWhat do you want to do?');\n    console.log('1. Add');\n    console.log('2. Find');\n    console.log('3. Update');\n    console.log('4. Remove');\n    console.log('5. View list');\n    console.log('6. Exit');\n};\n\n\nconst printContactData = ({ name, number }, printMessage=true) => {\n    if (printMessage) {\n        console.log('\\nHere is the contact data:');\n    }\n\n    console.log(` - Name: ${name}`);\n    console.log(` - Phone: ${number}`);\n};\n\n\nconst checkCorrectPhone = (number) => {\n    if (number.length > 11) {\n        console.log('\\nThe phone number must be less than 11 characters length.');\n    } else if (isNaN(number)) {\n        console.log('\\nThe phone number must be a number');\n    } else {\n        return true;\n    }\n\n    return false;\n}\n\n\nconst addContact = ({ name, number }) => {\n    const isCorrectNumber = checkCorrectPhone(number);\n    \n    if (!isCorrectNumber) {\n        return false;\n    }\n\n    if (findContactByName(name)) {\n        console.log('\\nThe introduced contact already exists.');\n        return false;\n    } else {\n        contactList.push({ name, number });\n        console.log('\\nThe new contact has been created.');\n        printContactData({ name, number });\n        return true;\n    }\n};\n\nconst findContactByName = (nameToFind) => {\n    return contactList.find(({ name }) => nameToFind === name);\n}\n\nconst findContactIndex = ({ name: nameToFind, number: numberToFind }) => {\n    return contactList.findIndex(({ name, number }) => (\n        nameToFind === name && numberToFind === number\n    ));\n};\n\nconst updateContact = (oldData, newData) => {\n    const contactIndex = findContactIndex(oldData);\n\n    if (contactIndex === -1) {\n        console.log('\\nThe contact doesn\\'t exist.');\n        return false;\n    }\n\n    contactList[contactIndex] = {...newData};\n    printContactData(newData);\n    return true;\n};\n\nconst removeContact = ({ name, number }) => {\n    const contactIndex = findContactIndex({ name, number });\n\n    if (contactIndex === -1) {\n        console.log('\\nThe contact doesn\\'t exist.');\n        return false;\n    }\n\n    contactList.splice(contactIndex, 1);\n    return true;\n};\n\nconst printContactList = () => {\n    if (contactList.length === 0) {\n        console.log('\\nThere are not contacts yet.');\n        return;\n    }\n\n    console.log('\\nThese are the stored contacts:');\n    for (let contact of contactList) {\n        printContactData(contact, false);\n        console.log('\\n');\n    }\n};\n\n\nfunction run() {\n    printMenu();\n    rl.question('Select your option (1-6): ', (option) => {\n        if (option === '1') {\n            // ADD NEW CONTACT\n\n            rl.question('\\nEnter the new name:\\n> ', (newName) => {\n                const contact = findContactByName(newName);\n\n                if (contact) {\n                    console.log('\\nThe contact already exists. Use another name instead.');\n                    run();\n                }\n\n                rl.question('Enter the new phone number:\\n> ', (newNumber) => {\n                    const newContact = {\n                        name: newName,\n                        number: newNumber\n                    };\n                    \n                    addContact(newContact);\n                    run();\n                });\n            });\n\n        } else if (option === '2') {\n            // FIND CONTACT\n\n            rl.question('\\nEnter the name to find:\\n> ', (name) => {\n                const contact = findContactByName(name);\n\n                if (!contact) {\n                    console.log('\\nNo contact has been found.');\n                } else {\n                    printContactData(contact);\n                }\n\n                run();\n            });\n\n        } else if (option === '3') {\n            // UPDATE CONTACT\n\n            rl.question('\\nEnter the name of the contact to update:\\n> ', (oldName) => {\n                const contact = findContactByName(oldName);\n\n                if (!contact) {\n                    console.log('\\nThe contact doesn\\'t exist. You can not update it.');\n                    run();\n                }\n\n                console.log('\\nWhat do you want to update?');\n                console.log('1. Contact name');\n                console.log('2. Contact phone number');\n                rl.question('Select (1-2): ', (modifier) => {\n                    const newData = {...contact};\n\n                    if (modifier === '1') {\n                        rl.question('Enter the new name: ', (newName) => {\n                            newData.name = newName\n                            updateContact(contact, newData);\n                            run();\n                        });\n                    } else if (modifier === '2') {\n                        rl.question('Enter the new phone number: ', (newNumber) => {\n                            const isCorrectNumber = checkCorrectPhone(newNumber);\n\n                            if (!isCorrectNumber) {\n                                run();\n                            }\n\n                            newData.number = newNumber\n                            updateContact(contact, newData);\n                            run();\n                        });\n                    } else {\n                        console.log('\\nNot correct option.');\n                    }\n                });\n            });\n\n        } else if (option === '4') {\n            // REMOVE CONTACT\n\n            rl.question('\\nEnter the name of the contact to remove:\\n> ', cName => {\n                const contact = findContactByName(cName);\n\n                if (!contact) {\n                    console.log('\\nThe contact doesn\\'t exist.');\n                    run();\n                }\n\n                removeContact(contact);\n                run();\n            });\n\n        } else if (option === '5') {\n            printContactList();\n            run();\n        } else if (option === '6') {\n            rl.close();\n            return;\n        } else {\n            console.log('\\nOption not allowed.');\n            run();\n        }\n    })\n}\n\nrun();"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/ocram1304.js",
    "content": "//Arreeglos\n//Son estructuras de datos que almacenana valores de manera indexada\n//En JS los arreglos son dinámicos, su longitud se puede aumentar o disminur sin restricciones\n//Además en JS los arreglos pueden almacenar datos de distinto tipo no es necesario definir\n//que tipo de datos se van a almacenar \n\n//La longitud de un arreglo es un dato muy importante a la hora de reealizar operaciones. En los arreglos\n//se puede obtener por medio de la atributo length\nconst longitud = miarreglo.length;\n//Declaración de un arreglo\nconst miarreglo = [\"item\", \"item2\", \"item3\"];\n//insertar valores (al final del arreglo)\nmiarreglo.push(\"item4\");\n//insertar valor al principio del arreglo\nmiarreglo.unshift(\"item0\");\n//Eliminar el ultimo elemento del arreglo (además este método recupera el valor)\nconst itemRemovido = miarreglo.pop();\n//Eliminar el primer valor del arreglo\nconst firstItem = miarreglo.shift();\n//cambia el contenido de un array añadiendo o remplazando elementos\nmiarreglo.splice(2,1,\"nItem3\");\n//actualizar valor\nmiarreglo[0]= \"item1\";\n//ordenación \n//El método sort ordena los elementos del arreglo y regresa una referenica la mismo arreglo. \nconst miarreglo2= [0,5,6,7,8,12,15];\nmiarreglo2.sort((a,b)=>{\n  return a-b;\n});\nconsole.log(miarreglo2);\n\n//Objetos\n//son una colección de datos y funcionalidades\n//están constituidos por variables y funciones que reciben el nombre de atributos y métodos respectivamente.\n//Los objetos almacenan sus valores (atributos) de manera similar a los arreglos, utilizán el formato clave/valor\n//en el caso de los arreglos es el indice, mientras que en los objetos es el \"key\", por ello a los ojetos \n//tambiíen se les conoce como arreglos asociativos.\n//Declaración de un objeto\nconst miobjeto ={\n  nombre: \"ocram1304\",\n  edad: 24,\n  estatus: \"aprendiendo\",\n  saludos: function (){\n    console.log(\"hola soy: \", this.nombre);\n  }\n  \n}\n//acceso a las popoiedades de un objeto\nconsole.log(miobjeto.nombre)\n//acceso a los métodos de un objeto\nmiobjeto.saludos();\n//Notación de corchetes, es una alternativa para acceder a los atributos de un objeto\nconsole.log(miobjeto[\"edad\"]);\n//Agregar una nueva propiedead al objeto\nmiobjeto[\"lenguje\"] = \"JavaScript\";\n//Agregar un nuevo método\nmiobjeto.presentacion = function(){\n  console.log(\"Tengo\", this.edad,  \"años y estudio\", this.lenguje)\n}\n\n//Set permite almacenar valores únicos de cualquier tipo, ya sea primitivos o referencias de objetos\n//Son colecciones de valores, se puede iterar a traves de los valores en órden de insercion\n//un valor en un set solo puede ocurrir una vez\n\n//Declaración de un set\nconst myset = new Set();\n//añadir un vaor\nmyset.add(\"valor1\");\nmyset.add(\"valor2\");\nmyset.add(\"valor3\");\nmyset.add(\"valor4\");\n//has, este método verifica si existe un valor en el objeto set, y devuelve un valor booleano.\nconst exist = myset.has(\"valor1\");\n//size devuelbe el numero de valores del objeto set \nconst longitudset = myset.size;\n//Eliminar un valor especifico de un set. Para ello se utiliza el método delete() que además devuelve un \n//valor booleano que afirma si el valor se elimino correctamente o no.\nconst velorBorrado = myset.delete(\"valor3\");\n//Borrar todos los valores. Se puede eliminar todos los valores del objeto set por medio del método clear()\nmyset.clear();\n//Objetos iterables\n//Entries. Devuleve un objeto iterable que contiene una arreglo con todos los elementos del set\nconst arregloDeSet = myset.entries();\nconsole.log(arregloDeSet);\n\n//Maps\n//El objeto map permite almacenar pares clave-valor y recuerda el orden de inserción de las clave (keys). \n//Se direncia de set ya que este admite claves y no solo valores como en el caso del primero.\n//Las claves en los objetos son únicas y no se pueden repetir\n\n//Declaración de un Map\nlet myMapa = new Map();\n//Agregar valores de un map\nmyMapa.set(\"mykey1\", \"valor1\");\nmyMapa.set(\"mykey2\", \"valor2\");\nmyMapa.set(\"mykey3\", \"valor3\");\nconsole.log(myMapa);\n//Tamaño de un map. Se puede conocer el tamaño de un map por medio del método size\nconst longitudmap = myMapa.size();\n//Get regresa un elemento en especifico de un map, si el valor asociado es un objeto entonces\n// cualquier cambio en el objeto modificara al objeto en el map\nconsole.log(myMapa.get(\"mykey3\"));\n//Eliminar valores de un map\nmyMapa.delete(\"mykey2\");\n//Map también cuenta con el método has al igual que set\nconst existInMap = myMapa.has(\"mykey2\");\n//Eliminar todas las claves del map\nmyMapa.clear();\n//Objetos iterables, se puden obtener objetos iterables de un map, tanto para las claves como para los valores\n//como para la claves\n//Método entries. Rgresa un  objeto (map) iterador  que contiene los pares clave-valor para  cada elemento\n//en el orden de inserción\nconst mapaIterador = myMapa.entries();\nconsole.log(mapaIterador.next().value);\n//El medot keys. Regresa un objeto iterador que contien la claves de cada uno de los elementos en orden de inserción\nconst mapaclaves = myMapa.keys();\nconsole.log(mapaclaves.next().value);\n//El método values. Funciona igual que el método kes() pero regresa los valors en lugar de las claves\nconst mapavalores = myMapa.values();\nconsole.log(mapavalores.next().value);\n\n//Difucultad extra\n\nfunction miagenda(){\n  let  continuar = \"s\";\n  let agenda = new Map([\n    [\"Marco\",526711139082],\n    [\"Antonio\",526711139049]\n  ]);\n    let contacto = \"\";\n    let numTel = 0;\n  while(continuar===\"s\"){\n    console.log(\"Bienvenido, ¿qué deseas hacer?\");\n    console.log(\"1.buscar 2.agregar  3.actulalizar 4.eliminar \");\n\n    let option = prompt(\"Seleccione una opción\");\n    \n    if (option > 0 && option < 5){\n\n      switch(option){\n        case 1://Buscar\n        contacto = prompt(\"Ingresa el nombre de contacto\");\n        if(agenda.has(contacto)){\n            console.log(`Contacto ${contacto} # ${agenda.get(contacto)}`);\n        }\n        else{\n          console.log(\"contacto no existente\")\n        }\n        break;\n        case 2://agregar\n        contacto = prompt(\"Ingrese el nombre del contacto\");\n        numTel = Number(prompt(\"Ingrese el numero de telefono\"));\n        if(contacto !==\"\" && !isNaN(numTel) && numTel.toString().length>=11){\n          agenda.set(contacto,numTel);\n          console.log(\"Contacto guardado\")\n\n        }\n        else{\n          console.log(\"Ingrese los datos correctamente\");\n\n        }\n        break;\n        case 3://actualizar\n        contacto = prompt(\"Ingrese el nombre de contacto\");\n        numTel = Number(prompt(\"Ingrese el nuevo numero de telefono\"));\n        if(agenda.has(contacto) && contacto !==\"\" && !isNaN(numTel) && numTel.toString().length>=11){\n          agenda.set(contacto,numTel);\n          console.log(\"Contacto actualizado\");\n\n        }\n        else{\n          console.log(\"Ingrese los datos correctamente\");\n\n        }\n        break;\n        case 4://Eliminar\n        let contactoEliminar = prompt(\"Ingrese el nombre del contacto a eliminar\");\n        if (agenda.has(contactoEliminar) && contactoEliminar !== \"\") {\n        agenda.delete(contactoEliminar);\n        if (!agenda.has(contactoEliminar)) {\n          console.log(\"Contacto eliminado\");\n        } else {\n          console.log(\"No se pudo eliminar el contacto\");\n        }\n      } else {\n        console.log(\"El contacto no existe o el nombre está vacío\");\n      }\n      break;\n\n        \n\n      }\n\n    }\n    else{\n      console.log(\"Elija una opción correta\");\n    }\n\n    continuar = prompt(\"Desea continuar s/n\");\n\n  }\n \n\n}\nmiagenda();\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/oleojake.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n */\n\n// 1.- ARRAY\nlet frutas = [\"manzana\", \"pera\", \"plátano\", \"fresa\"];\n\n// 1.1 INSERCIÓN EN ARRAY\nfrutas.push(\"melocotón\"); // Inserción al final\nfrutas.unshift(\"albaricoque\"); // Inserción al principio\nfrutas.splice(0,0,\"palta\"); // Añadiendo con splice en la posición 0\n\n// 1.2 BORRADO EN ARRAY\nfrutas.pop(); // Borrado al final\nfrutas.shift(); // Borrado al principio\nfrutas.splice(0,1); // Eliminando con splice en la posición 0\n\n// 1.3 ACTUALIZACIÓN EN ARRAY\nfrutas[0] = 'mango'; // Actualización\nfrutas.splice(2,1, \"uva\"); // Actualizando con splice\n\n// Actualizando con MAP\n// El método map crea un nuevo array de la misma longitud que el original, pero con los elementos transformados\nlet numbers = [1, 2, 3]\nlet doubleNumbers = numbers.map((number) => {\n  return number * 2\n})\nconsole.log(doubleNumbers)\n\n// Filtrado\nnumbers = [1, 2, 3, 4, 5, 6, 7]\nlet evenNumbers = numbers.filter(function (number) {\n    return number % 2 === 0\n})\nconsole.log(evenNumbers)\n\n// 1.4 ORDENACIÓN EN ARRAY\nnumbers = [3, 5, 22, 7, 2];\nconsole.log(numbers.sort()); // Ordena los strings, no sirve para números\n\nlet numerosOrdenados = numbers.toSorted(function(a, b) { // Usamos toSorted y un nuevo array para no modificar el array original\n    return a - b\n    // Si quisieramos descendente return b - a\n})\nconsole.log(numerosOrdenados);\n\n// Maatriz o array de arrays.\nlet matriz = [\n    [1, 2, 3],\n    [4, 5, 6,]\n]\n\n// 2. SET\n// No acepta duplicados\nlet mySet = new Set([\"Oleojake\", 30]); \n\n// 2.1 INSERCCIÓN EN SET\nmySet.add(\"Jijona\");\n\n// 2.2 BORRADO EN SET\nmySet.delete(\"Oleojake\");\nmySet.clear(); // Borra todo el SET\n\n\n// 3. MAPA\n// No permite repetir claves\nlet myMap = new Map ([[\"Pablo\", 30], [\"Doly\", 25]]);\n\n// 3.1 INSERCCIÓN EN MAPA\nmyMap.set(\"Bonsito\", 16);\n\n// 3.2 BORRADO EN MAPA\nmyMap.delete(\"Bonsito\");\nmyMap.clear(); // Borra todo el Mapa\n\n\n// 4. OBJETOS\n// Creación\nlet myObject = { nombre: 'Pabo', edad: 30, ciudad: 'Alicante' };\nconsole.log(myObject);\n// Inserción\nmyObject.trabajo = 'Dev';\n\n// Actualización\nmyObject.edad = 26;\n\n// Borrado\ndelete myObject.ciudad;\nconsole.log(myObject.edad)\n\n\n/* DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\n\n// EJERCICIO HECHO CON ARRAYS DE OBJETOS\n\nlet contacts = [];\ncontacts.push({name:\"Pablo\", phone:\"6000774503\"});\ncontacts.push({name:\"Doly\", phone:\"6521412514\"});\n\n\n// SEARCH CONTACT\nfunction searchContact(name){\n    let contacto = contacts.find(contacto => contacto.name.toLowerCase() === name.toLowerCase());\n    if(contacto == undefined){\n        return \"Contacto no encontrado\"\n    }\n    return contacto.phone;\n    \n}\n\n// ADD CONTACT\nfunction addContact(name, phone){\n    if (phone.length > 11){\n        console.log(\"\\n --> El número es demasiado largo, debe tener 11 dígitos como máximo\\n\");\n    } else {\n        let contacto = contacts.find(contacto => contacto.name.toLowerCase() === name.toLowerCase());\n        if(contacto == undefined){\n            console.log(\"\\n --> Inserción realizada con éxito\\n\");\n            contacts.push({name,phone});\n        } else {\n            console.log(\"\\n --> Ese contacto ya existe, guárdalo con un nombre diferente\\n\");\n        }\n    }\n}\n\n// DELETE CONTACT\nfunction deleteContact(name){\n    let contacto = contacts.find(contacto => contacto.name.toLowerCase() === name.toLowerCase());\n    if (contacto == undefined){\n        console.log(\"\\n --> El nombre que has introducido no se encuentra en la agenda \\n\");\n    } else {\n        contacts = contacts.filter(contacto => contacto.name.toLowerCase() !== name.toLowerCase());\n        console.log(\"\\n Has eliminado el contacto: \" + name + \"\\n\");\n    }\n}\n\n// UPDATE CONTACT\nfunction updateContact(name, phone){\n    let contactIndex = contacts.findIndex(contacto => contacto.name.toLowerCase() === name.toLowerCase());\n    if (phone.length > 11){\n        console.log(\"\\n -->El número es demasiado largo, debe tener 11 dígitos como máximo \\n\");\n    } else {\n        if (contactIndex == -1){\n            console.log(\"\\n -->El nombre que has introducido no se encuentra en la agenda \\n\");\n        } else {\n            contacts[contactIndex].phone = phone;\n            console.log(\"\\n -->Has actualizado el número de teléfono de : \" + name +\" (\"+phone+\")\");\n        }\n    }\n}\n\n// VER AGENDA\nfunction verAgenda(){\n    if(contacts.length > 0){\n        console.log(\"TU AGENDA\");\n        console.log(\"------------------------------------\");\n        for(let i = 0; i< contacts.length; i++){\n            console.log(\"* Nombre: \" + contacts[i].name + \" | Teléfono: \" + contacts[i].phone);\n        }\n        console.log(\"------------------------------------\");\n        console.log(\"\\n\");\n    } else {\n        console.log(\"\\n--> Tu agenda de contactos está vacía prueba a añadir algún contacto primero\");\n    }\n}\n\n\nconst readline = require(\"readline\");\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout,\n});\n\nfunction showMenu() {\nconsole.log(\"¿Qué deseas hacer?\");\nconsole.log(\"1. Añadir Contacto\");\nconsole.log(\"2. Buscar Contacto\");\nconsole.log(\"3. Actualizar Contacto\");\nconsole.log(\"4. Eliminar Contacto\");\nconsole.log(\"5. Ver Agenda\");\nconsole.log(\"6. Salir\\n\");\n}\n\nfunction runAction(opcion) {\n\n    switch (opcion){\n        case \"1\":\n            rl.question(\"\\n --> Introduzca el nombre de contacto que quieres añadir \\n\", (newName) => {\n                rl.question(\"\\n --> y ahora su número de teléfono \\n\", (newPhone) => {\n                    addContact(newName, newPhone);\n                    run();\n                });\n            });  \n            break;\n        case \"2\":\n            rl.question(\"\\n --> Introduzca el nombre de contacto que quiere buscar \\n\", (opcion) => {\n                console.log(\"\\n --> El número de \" + opcion + \" es: \" +searchContact(opcion) +\"\\n\");\n                run();\n            });            \n            break;\n        case \"3\":\n            rl.question(\"\\n --> Introduzca el nombre de contacto que quieres actualizar \\n\", (newName) => {\n                rl.question(\"\\n --> y ahora su nuevo número de teléfono \\n\", (newPhone) => {\n                    updateContact(newName, newPhone);\n                    run();\n                });\n            });\n            break;\n        case \"4\":\n            rl.question(\"\\n --> Introduzca el nombre de contacto que deseas eliminar \\n\", (opcion) => {\n                deleteContact(opcion);\n                run();\n            });\n            break;\n        case \"5\":\n            verAgenda();\n            run();\n            break;\n        case \"6\":\n            console.log(\"\\n --> Cerrando agenda \\n\");\n            rl.close();\n            break;\n        default: \n            console.log(\"\\n --> No le entiendo \\n\");\n            run();\n    }\n}\n\nfunction run() {\n    showMenu();\n    rl.question(\"Seleccione una opción (1-6): \", (opcion) => {\n        runAction(opcion);\n    });\n}\n\nrun();"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/omegatroy.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n * DIFICULTAD EXTRA (opcional):\n * - Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\n// Arrays conjunto de elementos del mismo tipo o diferentes tipos\nlet myArray = [10,7,9,4,5];\nlet myArray2 = ['hola',2,true,[1,\"mundo\"]];\n\n// Insertar un nuevo elemento del array\nmyArray.push(10)\n\nconsole.log(myArray)\nconsole.log(myArray2)\n\n// Borrar un elemento del array \nmyArray.pop() // --> Elimino el ultimo elemento (10)\nconsole.log(myArray)\n\n  //Actualizar un valor de un array \n  //  0,1,2,3,4 --> posición de los elemantos\n  // [1,2,3,4,13]\nmyArray.splice(4,1,13) // --> Primer parámetro (4) indico la posición del número a modificar\nconsole.log(myArray)   // --> Segundo parámetro (1) indico cuantos elementos quiero modificar\n                        // --> Tercer parámetro (13) indico el valor nuevo modificado\n\n// ordenar arrays\nmyArray.sort((a,b)=> a-b) // con esa arrow function indico que me los ordene de menor a mayor\nconsole.log(myArray)\n\n\n//Maps almacenan pares clave-valor pero con más flexibilidad que los objetos\n// Forma 1\nlet mapStructura = new Map([\n  [\"uno\", 1],\n  [\"dos\", 2],\n  [\"tres\", 3],\n  [\"cuatro\", 4],\n  [\"cinco\", 11],\n]);\n\nmapStructura.set(\"seis\", 6); //Inserción\nmapStructura.delete(\"seis\"); //Borrado\nmapStructura.get(\"cinco\"); //Busqueda\nmapStructura.set(\"cinco\", 5); //Actualización\nmapStructura.clear(); //Borrado - Elimina todos los elementos\n\n\n// Forma 2\nlet newMap = new Map()\nnewMap.set(\"lenguaje\",\"Javascript\")\nnewMap.set(\"area\",\"front\")\nconsole.log(newMap)\n\n//Insertar un elemento en un Map\nnewMap.set(\"back\",\"Java\")\nconsole.log(newMap)\n\n//Borrar un elemento del mapa\nnewMap.delete(\"area\")\nconsole.log(newMap)\n\n//Actualizar el valor de un mapa\nnewMap.set(\"back\",\"Rust\")\nconsole.log(newMap)\n\n\n// Sets Colección de valores únicos donde no puede haber duplicados\nlet mySet = new Set ([1,2,3,4,5])\nconsole.log(mySet)\n//Insertar un elemento en un Set\nmySet.add(6)\nconsole.log(mySet)\n\n//Borrar un elemento del set\nmySet.delete(4)\nconsole.log(mySet)\n\n//Actualizar un elemento en el set\n/*No se puede cambiar el valor de un elemento pero\nsi podemos quitar y añadir como hemos visto antes*/\n\n//Ordenar sets \n/*\n  Para ordenar los elementos de un set primero lo convertimos a array \n  y luego ordenamos sus elementos como hemos hecho anteriormente \n*/\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/oscar503sv.js",
    "content": "/*\r\n * EJERCICIO:\r\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\r\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\r\n *\r\n * DIFICULTAD EXTRA (opcional):\r\n * Crea una agenda de contactos por terminal.\r\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\r\n * - Cada contacto debe tener un nombre y un número de teléfono.\r\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\r\n *   los datos necesarios para llevarla a cabo.\r\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\r\n *   (o el número de dígitos que quieras)\r\n * - También se debe proponer una operación de finalización del programa.\r\n */\r\n\r\n/* ************************************** ARRAYS ************************************** */\r\n/*Una colección ordenada de elementos que pueden ser de cualquier tipo, y están indexados numéricamente, comenzando desde 0.*/\r\nvar miArray = [1, \"dos\", { clave: \"valor\" }, true];\r\nconsole.log(miArray); //[1, \"dos\", { clave: \"valor\" }, true]\r\nconsole.log(miArray[1]); //\"dos\"\r\n\r\nmiArray.push(\"tres\"); // agrega un elemento al final de la colección\r\nconsole.log(miArray); \r\nmiArray.pop(); // elimina el último elemento de la colección\r\nconsole.log(miArray); \r\nmiArray.shift(); // elimina el primer elemento de la colección\r\nconsole.log(miArray);\r\nmiArray.unshift(\"uno\"); // agrega un elemento al principio de la colección\r\nconsole.log(miArray); \r\n\r\nmiArray.splice(1, 1); // elimina el elemento en la posición 1 de la colección\r\nconsole.log(miArray); \r\nmiArray.splice(1, 0, \"dos\"); // agrega un elemento en la posición 1 de la colección\r\nconsole.log(miArray); \r\n\r\n/* ************************************** OBJETOS ************************************** */\r\n/*Un objeto es una colección de propiedades, que se pueden acceder a mediante el operador de acceso de objetos.*/\r\nvar miObjeto = {\r\n    propiedad1: \"valor1\",\r\n    propiedad2: \"valor2\",\r\n    propiedad3: \"valor3\"\r\n};\r\nconsole.log(miObjeto.propiedad1); //\"valor1\"\r\nmiObjeto.propiedad2 = \"nuevo valor\"; //cambia el valor de la propiedad propiedad2\r\nconsole.log(miObjeto.propiedad2); //\"nuevo valor\"\r\nmiObjeto.nuevaPropiedad = \"Esta es una nueva propiedad\"; //agrega una nueva propiedad a miObjeto\r\nconsole.log(miObjeto.nuevaPropiedad); //\"Esta es una nueva propiedad\"\r\ndelete miObjeto.nuevaPropiedad; //elimina la propiedad nuevaPropiedad de miObjeto\r\nconsole.log(miObjeto); //{ propiedad1: \"valor1\", propiedad2: \"nuevo valor\" }\r\n\r\n/* ************************************** MATRICES ************************************** */\r\n/*Una matriz es una colección de elementos del mismo tipo, indexados por un entero numérico.*/\r\nvar miMatriz = [\r\n    [1, 2, 3],\r\n    [4, 5, 6],\r\n    [7, 8, 9]\r\n];\r\n\r\n// Obtener elementos de la matriz\r\nconsole.log(miMatriz[0][0]); // Output: 1\r\nconsole.log(miMatriz[1][2]); // Output: 6\r\nconsole.log(miMatriz[2][1]); // Output: 8\r\n\r\n// Iterar sobre la matriz\r\nfor (var i = 0; i < miMatriz.length; i++) {\r\n    for (var j = 0; j < miMatriz[i].length; j++) {\r\n        console.log(miMatriz[i][j]);\r\n    }\r\n}\r\n\r\n// Agregar un elemento a la matriz\r\nmiMatriz[0][0] = 10;\r\nconsole.log(miMatriz); // Output: [[10, 2, 3], [4, 5, 6], [7, 8, 9]]\r\n\r\n// Eliminar un elemento de la matriz\r\ndelete miMatriz[1][2];\r\nconsole.log(miMatriz); // Output: [[10, 2, 3], [4, 5], [7, 8, 9]]\r\n\r\n// Cambiar el valor de un elemento de la matriz\r\nmiMatriz[1][1] = 20;\r\nconsole.log(miMatriz); // Output: [[10, 2, 3], [4, 20], [7, 8, 9]]\r\n\r\n// Agregar una nueva fila a la matriz\r\nmiMatriz.push([10, 20, 30]);\r\nconsole.log(miMatriz); // Output: [[10, 2, 3], [4, 20], [7, 8, 9], [10, 20, 30]]\r\n\r\n// Eliminar una fila de la matriz    \r\nmiMatriz.pop();\r\nconsole.log(miMatriz); // Output: [[10, 2, 3], [4, 20], [7, 8, 9]]\r\n\r\n// Cambiar el valor de una fila de la matriz\r\nmiMatriz[1][1] = 30;\r\nconsole.log(miMatriz); // Output: [[10, 2, 3], [4, 30], [7, 8, 9]]\r\n\r\nmiMatriz[1][2] = 6;\r\nconsole.log(miMatriz); // Output: [[10, 2, 3], [4, 30, 6], [7, 8, 9]]\r\n\r\n// Sumar dos matrices\r\nvar otraMatriz = [\r\n    [9, 8, 7],\r\n    [6, 5, 4],\r\n    [3, 2, 1]\r\n];\r\n\r\nvar resultadoSuma = [];\r\nfor (var i = 0; i < miMatriz.length; i++) {\r\n    resultadoSuma[i] = [];\r\n    for (var j = 0; j < miMatriz[i].length; j++) {\r\n        resultadoSuma[i][j] = miMatriz[i][j] + otraMatriz[i][j];\r\n    }\r\n}\r\nconsole.log(resultadoSuma);\r\n\r\n// Multiplicar una matriz por un escalar\r\nvar escalar = 2;\r\nvar resultadoMultiplicacion = [];\r\nfor (var i = 0; i < miMatriz.length; i++) {\r\n    resultadoMultiplicacion[i] = [];\r\n    for (var j = 0; j < miMatriz[i].length; j++) {\r\n        resultadoMultiplicacion[i][j] = miMatriz[i][j] * escalar;\r\n    }\r\n}\r\nconsole.log(resultadoMultiplicacion);\r\n\r\n/* ************************************** SETS ************************************** */\r\n/*Un conjunto es una colección de elementos que no tiene repeticiones, y que se pueden acceder a mediante el operador de acceso de objetos.*/\r\nvar miSet = new Set([1, 2, 3, 4, 5, 6, 7, 8, 9]);\r\nconsole.log(miSet); //Set { 1, 2, 3, 4, 5, 6, 7, 8, 9 }\r\nconsole.log(miSet.has(1)); //true\r\nconsole.log(miSet.has(10)); //false\r\nconsole.log(miSet.add(10)); //Set { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }\r\nconsole.log(miSet.size); //10\r\nconsole.log(miSet.delete(1)); //true\r\nconsole.log(miSet); //Set { 2, 3, 4, 5, 6, 7, 8, 9, 10 }\r\n\r\n/* ************************************** MAPS ************************************** */\r\n/*Un map es una colección de elementos que se pueden acceder a mediante el operador de acceso de objetos.*/\r\nvar miMap = new Map();\r\nmiMap.set(\"nombre\", \"Juan\");\r\nmiMap.set(\"edad\", 25);\r\nmiMap.set(\"apellido\", \"Perez\"); //Agrega un elemento a miMap\r\nconsole.log(miMap); //Map { \"nombre\" => \"Juan\", \"edad\" => 25, \"apellido\" => \"Perez\" }\r\nconsole.log(miMap.get(\"nombre\")); //\"Juan\"\r\nconsole.log(miMap.get(\"apellido\")); //\"Perez\"\r\nconsole.log(miMap.has(\"nombre\")); //true\r\nconsole.log(miMap.has(\"apellido\")); //true  \r\nconsole.log(miMap.delete(\"apellido\")); //true\r\nconsole.log(miMap); //Map { \"nombre\" => \"Juan\", \"edad\" => 25 }\r\n\r\n/* ************************************** EJERCICIO EXTRA ************************************** */\r\n// Importar la librería readline-sync para leer la entrada del usuario desde la terminal\r\n// Crea una agenda de contactos por terminal\r\nconst readline = require(\"readline\");\r\n\r\nfunction agregarContacto(nombre, telefono) {\r\n    if (!/^\\d{1,11}$/.test(telefono)) {\r\n        console.log(\"El número de teléfono debe ser numérico y no tener más de 11 dígitos.\");\r\n        return;\r\n    }\r\n    miAgenda.set(nombre, telefono);\r\n    console.log(\"Contacto agregado.\");\r\n}\r\n\r\nfunction buscarContacto(nombre) {\r\n    if (miAgenda.has(nombre)) {\r\n        console.log(\"El contacto de \" + nombre + \" es \" + miAgenda.get(nombre));\r\n    } else {\r\n        console.log(\"No existe un contacto con el nombre \" + nombre);\r\n    }\r\n}\r\n\r\nfunction actualizarContacto(nombre, telefono) {\r\n    if (miAgenda.has(nombre)) {\r\n        miAgenda.set(nombre, telefono);\r\n        console.log(\"El contacto \" + nombre + \" ha sido actualizado\");\r\n    } else {\r\n        console.log(\"No existe un contacto con el nombre \" + nombre);\r\n    }\r\n}\r\n\r\nfunction eliminarContacto(nombre) {\r\n    if (miAgenda.has(nombre)) {\r\n        miAgenda.delete(nombre);\r\n        console.log(\"El contacto \" + nombre + \" ha sido eliminado\");\r\n    } else {\r\n        console.log(\"No existe un contacto con el nombre \" + nombre);\r\n    }\r\n}\r\n\r\nfunction mostrarAgenda() {\r\n    console.log(\"La agenda de contactos es:\");\r\n    miAgenda.forEach((nombre, telefono) => {\r\n        console.log(nombre + \" - \" + telefono);\r\n    });\r\n}\r\n\r\nfunction menuAgenda() {\r\n    console.log(\"\\nBienvenido al sistema de agenda de contactos\");\r\n    console.log(\"1. Agregar un contacto\");\r\n    console.log(\"2. Buscar un contacto\");\r\n    console.log(\"3. Actualizar un contacto\");\r\n    console.log(\"4. Eliminar un contacto\");\r\n    console.log(\"5. Mostrar la agenda\");\r\n    console.log(\"6. Salir\");\r\n}\r\n\r\nasync function preguntar(question) {\r\n    const rl = readline.createInterface({\r\n        input: process.stdin,\r\n        output: process.stdout\r\n    });\r\n    return new Promise(resolve => rl.question(question, ans => {\r\n        rl.close();\r\n        resolve(ans);\r\n    }));\r\n}\r\n\r\nasync function main() {\r\n    miAgenda = new Map();\r\n    let salir = false;\r\n\r\n    while (!salir) {\r\n        menuAgenda();\r\n        const opcion = await preguntar(\"Introduzca la opción: \");\r\n        \r\n        switch (opcion) {\r\n            case \"1\":\r\n                const nombreAgregar = await preguntar(\"Introduzca el nombre del contacto: \");\r\n                const telefonoAgregar = await preguntar(\"Introduzca el número de teléfono: \");\r\n                agregarContacto(nombreAgregar, telefonoAgregar);\r\n                break;\r\n            case \"2\":\r\n                const nombreBuscar = await preguntar(\"Introduzca el nombre del contacto: \");\r\n                buscarContacto(nombreBuscar);\r\n                break;\r\n            case \"3\":\r\n                const nombreActualizar = await preguntar(\"Introduzca el nombre del contacto: \");\r\n                const telefonoActualizar = await preguntar(\"Introduzca el número de teléfono: \");\r\n                actualizarContacto(nombreActualizar, telefonoActualizar);\r\n                break;\r\n            case \"4\":\r\n                const nombreEliminar = await preguntar(\"Introduzca el nombre del contacto: \");\r\n                eliminarContacto(nombreEliminar);\r\n                break;\r\n            case \"5\":\r\n                mostrarAgenda();\r\n                break;\r\n            case \"6\":\r\n                console.log(\"Saliendo del sistema\");\r\n                salir = true;\r\n                break;\r\n            default:\r\n                console.log(\"Opción inválida\");\r\n                break;\r\n        }\r\n    }\r\n}\r\n\r\nmain();\r\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/othamae.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\n// Array \nconsole.log('** ARRAY **')\nlet array = new Array([1,2,3,4,5,6,7,8,9]) // creation\nconsole.log(`This is the initial array: ${array}`)\narray.push(10) // insert at the end\nconsole.log(`Adding an element at the end: ${array}`)\narray.unshift(0) // insert at the beginning\nconsole.log(`Inserting an element at the beginning: ${array}`)\narray.splice(2,0,55) // insert the element 3 at index 2\nconsole.log(`Inserting an element at index 2: ${array}`)\narray.splice(2,1) // delete one element starting at index 2\nconsole.log(`Deleting an element at index 2: ${array}`)\narray.pop() // delete the last element\nconsole.log(`Deleting the last element: ${array}`)\narray.shift() // delete the first element\nconsole.log(`Deleting the first element: ${array}`)\narray[2]= 0 // update the element at index 2\nconsole.log(`Updating the element at index 2: ${array}`)\narray.reverse() // reverse the array\nconsole.log(`Reversing the array: ${array}`)\narray.sort() // sort the array\nconsole.log(`Sorting the array: ${array}`)\n\n// Object\nconsole.log('** OBJECT **')\nlet object = new Object({one: 1, two: 2, three: 3, four: 4}) // creation\nconsole.log(`This is the initial object:`)\nconsole.log(object)\nobject.five = 7 // insert at the end\nconsole.log(`Adding an element at the end:`)\nconsole.log(object)\nobject['six']= 6 // insert at the end\nconsole.log(`Different way to add an element at the end:`)\nconsole.log(object)\ndelete object.six // delete the element with key 'six' (Also working with: object['six'])\nconsole.log(`Deleting the element with key 'six':`)\nconsole.log(object)\nobject.five = 5 // update the element with key 'five' (Also working with: object['five'])\nconsole.log(`Updating the element with key 'five':`)\nconsole.log(object)\n\n\n// Map\nconsole.log('** MAP **')\nlet map = new Map([\n    ['one', 1],\n    ['two', 2],\n    ['three', 3],\n    ['four', 4],  \n]) // creation\nconsole.log(`This is the initial map: `)\nconsole.log(map)\nmap.set('five', 6) // insert at the end\nconsole.log(`Adding an element at the end:`)\nconsole.log(map)\nmap.delete('two') // delete the element with key 'two' \nconsole.log(`Deleting the element with key 'two':`)\nconsole.log(map)\nmap.set('five', 5) // update the element with key 'five'\nconsole.log(`Updating the element with key 'five':`)\nconsole.log(map)\nmap.clear() // delete all elements\nconsole.log(`Deleting all elements:`)\nconsole.log(map)\n\n// Set\nconsole.log('** SET **')\nlet set = new Set([1,2,3,4]) // creation\nconsole.log(`This is the initial set: `)\nconsole.log(set)\nset.add(5) // insert at the end\nconsole.log(`Adding an element at the end:`)\nconsole.log(set)\nset.delete(2) // delete the element with value 'two' \nconsole.log(`Deleting the element with value 'two':`)\nconsole.log(set)\nset.clear() // delete all elements\nconsole.log(`Deleting all elements:`)\nconsole.log(set)\n\n// EXTRA TASK:\n\nconst readline = require('readline')\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n})\n\nfunction addressBook(book){       \n    console.log('** Welcome to your address book **')\n    console.log('This is your address book:')\n    console.log(book)\n    showOptions()\n    rl.on('line', (input)=>{\n        if (input == 1) addContact(book)\n        if (input == 2) searchContact(book)\n        if (input == 3) updateContact(book)\n        if (input == 4) deleteContact(book)\n        if (input == 5) rl.close()\n        if (input > 5) console.log('Invalid option, please try again')\n    })\n  \n}\n\nfunction showOptions(){\n    console.log('Please select an option')\n    console.log('1. Add a new contact')\n    console.log('2. Search a contact')\n    console.log('3. Update a contact')\n    console.log('4. Delete a contact')\n    console.log('5. Exit')\n}\n\nfunction addContact(book){\n    rl.question('Enter the name of the contact: ', (name)=>{\n        rl.question('Enter the phone number of the contact: ', (phone)=>{\n            if (!validatePhone(phone)){\n                console.log('Invalid phone number, please try again')\n                addContact(book)\n                return\n            }\n            book.set(name, phone)\n            console.log('Contact added successfully')\n            console.log(book)\n            showOptions()\n        })\n    })\n}\n\nfunction searchContact(book){\n    rl.question('Enter the name of the contact to search: ', (name)=>{\n        if (book.has(name))console.log(`The phone number of ${name} is ${book.get(name)}`)\n        else console.log('Contact not found')\n        showOptions()\n    })\n}\n\nfunction updateContact(book){\n    rl.question('Enter the name of the contact to update: ', (name)=>{\n        if (book.has(name)){\n            rl.question('Enter the new phone number of the contact: ', (phone)=>{\n                if (!validatePhone(phone)){\n                    console.log('Invalid phone number, please try again')\n                    updateContact(book)\n                    return\n                }\n                book.set(name, phone)\n                console.log('Contact updated successfully')\n                console.log(book)\n                showOptions()\n            })\n        }\n        else {\n            console.log('Contact not found')\n            showOptions()\n        }\n    })\n}\n\nfunction deleteContact(book){\n    rl.question('Enter the name of the contact to delete: ', (name)=>{\n        if (book.has(name)){\n            book.delete(name)\n            console.log('Contact deleted successfully')\n            console.log(book)\n            showOptions()\n        }\n        else {\n            console.log('Contact not found')\n            showOptions()\n        }\n    })\n}\n\nfunction validatePhone(phone){\n    const regex = /^\\d{1,11}$/;\n    return regex.test(phone);\n}\n\n\nconst book = new Map([\n    ['Moure', '123456789'],\n    ['Mario', '987654312'] \n])\n\naddressBook(book)"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/parababire.js",
    "content": "/*Arrays, colección de datos ordenados por indices*/\n\nlet names = [\"maria\", \"angel\", \"pedro\", \"luisa\"];\nnames.push(\"rogelio\");//Insertar dato\nnames.pop();//Eliminar dato\nnames[0] = \"lupita\";//Actualizar dato\nnames.sort();//Reordenar datos\n\n/*Objectos literales, colección de datos ordenados por pares (clave:valor)*/\n\nconst joy = {\n  raza: \"poodle\",\n  color: \"blanco\",\n  patas: 4,\n  ladra: function () {\n    console.log(\"woof, woof, woof\");\n  }\n}\njoy.raza = \"mixed\";//Actualizar propiedad\njoy.cola = true;//Crear propiedad\njoy.vive = false;\ndelete joy.vive;//Eliminar propiedad\n//Objetos literales no poseen un método que reordene sus pares.\n\n/*Date*/\n\n/*Esta estructura de datos posee muchos métodos que permiten su manipulación. \nEsto permite la representación de los datos en diferentes formatos, acceder a \ndatos por separado (año, día, mes...).*/\n\nlet diaActual = new Date().toString();\n\n/*Map, colección de datos ordenados por pares*/\n\nconst map1 = new Map();\nmap1.set(\"a\", 1);//Crear dato\nmap1.set(\"b\", true);\nmap1.set(\"a\", 44);//Modificar dato\nmap1.delete(\"b\");//Borrar dato\n//El objeto Map() no posee un método que reordene sus pares.\n\n/*WeakMap, colección de datos por par donde las keys pueden ser objetos o\nsymbols no registrados*/\n\nconst wm1 = new WeakMap();//Crear objeto WeakMap\nconst wm2 = new WeakMap();\nconst wm3 = new WeakMap();\nconst o1 = {};//Crear keys\nconst o2 = function () {};\nconst o3 = window;\n\nwm1.set(o1, 37);//Añadir values a las keys\nwm1.set(o2, \"azerty\");\nwm2.set(o1, o2); //Cualquier valor, incluidos objetos y funciones\nwm2.set(o2, undefined);\nwm2.set(wm1, wm2); //Otro WeakMap puede ser key\n\nwm1.get(o2); // \"azerty\"\nwm2.get(o2); // undefined, ya que ese valor recibió\nwm2.get(o3); // undefined, ya que no existe key para o3 en wm2\n\nwm1.has(o2); // true\nwm2.has(o2); // true (aunque el valor mismo sea 'undefined')\nwm2.has(o3); // false\n\nwm3.set(o1, 37);\nwm3.get(o1); // 37\n\nwm1.has(o1); // true\nwm1.delete(o1);\nwm1.has(o1); // false\n//No se pueden reordenar o mutar los pares en WeakMaps\n\n/*Set, colección de datos únicos, primitivos u objetos*/\n\nconst mySet1 = new Set();\n\nmySet1.add(1); //Crear dato\nmySet1.add(5); // Set(2) { 1, 5 }\nmySet1.add(5); // Set(2) { 1, 5 }, los datos son únicos. No se repíten.\nmySet1.add(\"some text\");\nconst o = { a: 1, b: 2 };\nmySet1.add(o);\n/*Los datos en el objeto creado no pueden ser actualizados o reordenarse \nsu posición.*/\nmySet1.add({ a: 1, b: 2 }); // o hace referencia a un objeto diferente.\nmySet1.delete(5);//Borrar dato\n\n/*WeakSet, esta colección solo permite datos de tipo objeto y Symbol*/\n\nconst ws = new WeakSet();\nconst foo = {};\nconst bar = {};\n\nws.add(foo);//Añadir dato\nws.add(bar);\n\nws.has(foo); //true\nws.has(bar); //true\n\nws.delete(foo); //Eliminar dato\nws.has(foo); //false\nws.has(bar); //true\n/*Esta estructura solo permite guardar objetos y eliminarlos cuando se les deja \nde hacer referencia en el código*/\n\n/*JSON*/\n\n/*JSON es un objeto utilizado para tranferir data entre diferentes ambientes \nincluso lenguajes, sus métodos son estático lo que permite únicamente su parseo*/\n\n/*\n{\n  \"browsers\": {\n    \"firefox\": {\n      \"name\": \"Firefox\",\n      \"pref_url\": \"about:config\",\n      \"releases\": {\n        \"1\": {\n          \"release_date\": \"2004-11-09\",\n          \"status\": \"retired\",\n          \"engine\": \"Gecko\",\n          \"engine_version\": \"1.7\"\n        }\n      }\n    }\n  }\n}*/\n\n//Extra\n\nfunction my_agenda() {\n\n  let name, phone;\n  let on = true;\n  let phoneRegex = /^\\s{0}\\b\\d{11}\\b\\s{0}$/;\n  let agenda = {};\n  function phone_Regex() {\n    phone = prompt(\"Ingresa número telefónico del contacto: \", \"\");\n        if (phoneRegex.test(phone)) {\n          agenda[name] = phone;\n        } else {\n          console.log(\"El número debe tener 11 dígitos, sin espacios.\");\n        }\n  }\n  function msjError() {\n    console.log(`El contacto ${name} no existe.`);\n  }\n\n  while (on) {\n\n    console.log(\"\");\n    console.log(\"1.- Buscar contacto\");\n    console.log(\"2.- Insertar contacto\");\n    console.log(\"3.- Actualizar contacto\");\n    console.log(\"4.- Borrar contacto\");\n    console.log(\"5.- Salir\");\n\n    let operacion = prompt(\"\\nSelecciona una operación: \", \"\");\n\n    switch (operacion) {\n      case \"1\":\n        console.log(\"\");\n        name = prompt(\"Ingresa nombre del contacto a buscar: \", \"\");\n        if (agenda.hasOwnProperty(name)) {\n          console.log(`El número de ${name} es: ${agenda[name]}`);\n        } else {\n          msjError();\n        }\n        break;\n      case \"2\":\n        name = prompt(\"Ingresa nombre del contacto: \", \"\");\n        phone_Regex();\n        break;\n      case \"3\":\n        name = prompt(\"Ingresa nombre del contacto a actualizar: \", \"\");\n        if (agenda.hasOwnProperty(name)) {\n          phone_Regex();\n        } else {\n          msjError();\n        }\n        break;\n      case \"4\":\n        name = prompt(\"Ingresa nombre del contacto a eliminar: \", \"\");\n        if (agenda.hasOwnProperty(name)) {\n          delete agenda[name];\n        } else {\n          msjError();\n        }\n        break;\n      case \"5\":\n        console.log(\"Salir del programa.\");\n        on = false;\n        break;\n      default:\n        console.log(\"Tu elección no es válida. Elige un número del 1 al 5.\");\n        break;\n    }\n  }\n}\n\nmy_agenda();"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/pedamoci.js",
    "content": "// ----------------------------- ESTRUCTURAS DE DATOS -----------------------------\n  // ARRAYS\n\n  const frutas = new Array('Manzana', 'Pera', 'Banana')\n  // OBJECTS\n\n    const persona = new Object({nombre: 'Aang', edad: 112, profesion: 'Avatar'});\n  // SETS\n\n    const notasMusicales = new Set(['do', 're', 'mi', 'fa', 'sol', 'la']);\n  // MAPS\n\n  const capacidad = new Map([[0, \"zero\"], [1, 'one'], [2, 'two'], [3, 'tree'], [4, 'four']]);\n\n// ----------------------------- OPERACIONES BASICAS -----------------------------\n    // Inserción\n      frutas.push('Naranja')  // Array\n      persona.tribu = 'Nómadas del aire'  // Object\n      notasMusicales.add('si')  // Set\n      capacidad.set(5, 'five')  // Map\n\n    // Borrado\n      frutas.splice(1, 1) // Array \n      delete persona.edad  // Object\n      notasMusicales.delete('fa')  // Set\n      capacidad.delete(5) //Map\n\n    // Actualización\n      frutas[0] = 'Mango'  // Array\n      persona.profesion = 'Maestro del aire'  // Object\n      // Los Sets no permiten actualización directa\n      capacidad.set(3, 'three')  // Map\n\n    // Ordenación\n      frutas.sort()  // Array\n      // Los Objects no tienen funciones de ordenación directa\n      // Los Sets no tienen funciones de ordenación directa\n      // Los Maps no tienen funciones de ordenación directa\n\n// ----------------------------- DIFICULTAD EXTRA -----------------------------\nlet agenda = new Object({\n  3321904500: 'Erick',\n  6598204500: 'Jaime',\n  3321968740: 'Raul',\n  3654928824: 'Mateo',\n  1218322247: 'Laura',\n  9633455572: 'Miguel',\n  3321994421: 'Omar',\n  2076589124: 'Oscar',\n  4863465825: 'Jose',\n  5739514862: 'Fernando',\n  8134679852: 'Eloy',\n  7159852456: 'Daniel',\n  3322577770: 'Erick',\n  3999994500: 'Erick',\n})\n\nfunction verificarInfo() {\n  //Verifica si el nombre o número ingresado por el usuario esta en la agenda\n  while (true) {\n    let info = prompt(\"Ingrese el nombre o telefono\")\n    if (Object.hasOwn(agenda, parseInt(info))) {\n      return {'tel': info}\n    } else if (Object.values(agenda).includes(info)) {\n      return {'name': info}\n    }\n    alert(\"Persona/Telefono NO agendado/a\")\n  }\n}\n\nfunction verificarTel() {\n  //Verifica que el número de telefono ingresado tenga entre 8 y 11 digitos\n  while (true) {\n    let tel = parseInt(prompt(\"Ingrese el teléfono (debe tener entre 8 y 11 dígitos)\"))\n    if (!isNaN(tel) && tel.toString().length >= 8 && tel.toString().length <= 11) {\n      return tel;\n    }\n    alert(\"Número de teléfono inválido. Debe tener entre 8 y 11 dígitos.\")\n  }\n}\n\nfunction updateNombre() {\n  //Actualiza el nombre de un contacto\n  let infoUpdate = verificarInfo()\n  if (infoUpdate.name !== undefined) {\n    // busca a los contactos por nombre si hay varios devuelve los numeros y si hay uno permite cambiar el nombre\n    let tel = Object.keys(agenda).filter(key => agenda[key] === infoUpdate.name)\n    if (tel.length !== 1){\n      alert(`Tienes varios contactos con ese nombre, verifica y actualiza el contacto que quieres por alguno de estos números ${tel}`)\n    } else {\n      let newName = prompt('Ingrese el nuevo nombre')\n      agenda[parseInt(tel)] = newName\n      alert(`Se ha actualizado el nombre del número ${tel} por ${newName}`)\n    }\n  } else {\n    // busca el contacto por el telefono y le cambia el nombre\n    let newName = prompt('Ingrese el nuevo nombre')\n    agenda[parseInt(infoUpdate.tel)] = newName\n    alert(`Se ha actualizado el nombre del número ${infoUpdate.tel} por ${newName}`)\n  }\n}\n\nfunction updateTelefono(tel) {\n  // Actualiza el telefono de un contacto\n  let infoUpdate = verificarInfo()\n  if (infoUpdate.name !== undefined) {\n    // busca a los contactos por nombre si hay varios devuelve los numeros y si hay uno permite cambiar el telefono\n    let tel = Object.keys(agenda).filter(key => agenda[key] === infoUpdate.name)\n    if (tel.length !== 1){\n      alert(`Tienes varios contactos con ese nombre, verifica y actualiza el contacto que quieres por alguno de estos números ${tel}`)\n    } else {\n      let newTel = verificarTel()\n      delete agenda[tel]\n      agenda[newTel] = infoUpdate.name\n      alert(`Se ha actualizado el número de ${infoUpdate.name} a ${newTel}`)\n    }\n  } else {\n    // busca el contacto por el telefono y le cambia el telefono\n    let newTel = verificarTel()\n    let lastName = agenda[infoUpdate.tel]\n    delete agenda[infoUpdate.tel]\n    agenda[newTel] = lastName\n    alert(`Se ha actualizado el número de ${lastName} a ${newTel}`)\n  }\n}\n\nfunction search() { \n  // te permite buscar, insertar, actualizar y borrar un contacto\n  // ademas te pregunta si queres hacer otra operacion\n  let operation = prompt(\"Ingrese la operación a realizar: buscar, insercion, actualizar, borrar\")\n  switch (operation) {\n    case \"buscar\":\n      let infoSearch = verificarInfo()\n      if (infoSearch.name !== undefined) {\n        // busca los telefonos que coincidan con el nombre ingresado y devuelve todos\n        let tel = Object.keys(agenda).filter(key => agenda[key] === infoSearch.name)\n        if (tel.length !== 1){\n          alert(`Tienes ${tel.length} contactos llamados ${infoSearch.name} con los números ${tel}`)\n        } else{\n          alert(`El telefono de ${agenda[tel]} es ${tel}`)\n        }\n      } else {\n        // busca el nombre del número de telefono ingresado\n        let name = agenda[infoSearch.tel]\n        alert(`El dueño del telefono ${infoSearch.tel} es ${name}`)\n      }\n      break;\n\n    case \"insercion\":\n      let name = prompt(\"Ingrese el nombre\")\n      tel = verificarTel()\n      agenda[tel] = name\n      alert(`Se ha agendado a ${name} con el número ${tel}`)\n      break;\n\n    case \"actualizar\":\n      let updateOption = alert('¿Que queres actualizar nombre o telefono?')\n        while (updateOption !== 'nombre' && updateOption !== 'telefono') {\n          (updateOption === 'nombre') ? updateNombre()\n                                      : updateTelefono()\n        }\n      break;\n\n    case \"borrar\":\n      let infoRemove = verificarInfo()\n      if (infoRemove.name !== undefined) {\n        // busca todos los números que estan agendados con el mismo nombre\n        let tel = Object.keys(agenda).filter(key => agenda[key] === infoRemove.name)\n        if (tel.length !== 1){\n          let aviso = prompt('Tienes varios contactos con ese nombre, ¿Deseas borrar todos? Y/N')\n          while (aviso !== 'Y' && aviso !== 'N') {\n            if (aviso === 'Y'){\n              let telRemoved = [...tel]\n              while (tel.length !== 0) {\n                // va eliminando de un telefono a la vez desde el último hasta el primero\n                let i = tel.length - 1\n                delete agenda[parseInt(tel[i])]\n                tel.pop()\n              }\n              alert(`Los contacto con nombre ${infoRemove.name} y números ${telRemoved} han sido borrado`)\n              break;\n            } else {\n              alert(`Los números que tienes agendados como ${infoRemove.name} son ${tel}`)\n              break;\n            }\n          }\n        } else {\n          delete agenda[tel]\n          alert(`El contacto con nombre ${infoRemove.name} y número ${tel} ha sido borrado`)\n        }\n      } else {\n        let nameRemoved = agenda[infoRemove.tel]\n        delete agenda[infoRemove.tel]\n        alert(`El contacto con nombre ${nameRemoved} y número ${infoRemove.tel} ha sido borrado`)\n      }\n      break;\n    default:\n      break;\n  }\n  let stop = prompt('Quieres hacer otra operación? Y/N')\n  while (stop !== 'Y' && stop !== 'N') {\n    if (stop === 'Y') {\n      search()\n    } break;\n  }\n}\n\nsearch()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/popmaquin.js",
    "content": "/*__Estructura de datos__*/\n\n\n/*.............colecciones indexadas.............*/\n\n\n//--Array (matriz)-- => datos ordenados por indice numerico\n// Formas de crear una matriz\nmatriz1 = new Array(\" elemento1\",\" elemento2\",\" elemento3\");\nmatriz2 = Array(\"elemento1\",\"elemento2\",\"elementoN\");\nmatriz3 = [\"elemento1\",\"elemento2\",\"elementoN\"];\n\n\n//Métodos para manipular matriz.\nconsole.log(matriz1); //salida: ['elemento1', 'elemento2', 'elemento3']\n\n\n//-Insercion- Agrega elementos al final y devuelve la longitud.\nconsole.log(\"ahora tiene: \"+matriz1.push(\"elemento10\")+\" elemento\"); //4\nconsole.log(matriz1); // ['elemento1', 'elemento2', 'elemento3', 'elemento10']\n\n\n//-Elimina- 'elemento10' el último elemento y devuelve.\nconsole.log(\"Eliminado: \"+ matriz1.pop());\n\n\n//-Actualiza- el valor del indece 1 por 'elemento4'\nconsole.log(\"Actualizacion de valor indice 1 \")\nconsole.log(matriz1[1] = \" elemento4\");\nconsole.log(matriz1); // ['elemento1', 'elemento4', 'elemento3']\n\n\n//-Ordena- los elemento y devuelve la matriz ordenada.\nconsole.log(\"Ordenado \");\nconsole.log(matriz1.sort());// ['elemento1', 'elemento3', 'elemento4']\n\n\n\n\n/*.............colecciones con clave.............*/\n\n\n//map\nlet mimap = new Map();\nconsole.log(mimap.size);\n\n\n//Métodos para manipular Map.\n//Ingresar datos\nmimap.set('nombre', 'Julio');\nmimap.set('apellido', 'Maquin');\nmimap.set('edad', '25');\n\n\nconsole.log(mimap.size); //3\n\n//-Eliminar-\nmimap.delete('nombre')\nconsole.log(mimap.get('nombre')); // undefined\nconsole.log(mimap.get('apellido')); //Maquin\nconsole.log(mimap.has('apellido')); //true\n\n\n// Actualizacion\nconsole.log(mimap.set('edad','32')); //['edad', '32']\n\n\nconsole.log(\"Antes de ordenar\");\nconsole.log(mimap);// Ordenacion\n\n//Elementos Map Ordenado por valores.\nconsole.log(\"Map ordenado por valores\");\nlet mapOrdenado= [...mimap.values()].sort();\nconsole.log(mapOrdenado);\n/*----------------------------*/\n\n\n//WeakMap\nlet wekMap = new WeakMap();\n\n\n// Objeto1 clave y valor\nlet clave1 = {\n    id: 1\n}\nlet obj1 = {\n    marca: 'Toyota',\n    modelo: 'Civic'\n}\n// Objeto2 clave y valor\nlet clave2 = {\n    id: 2\n}\nlet obj2 = {\n    marca: 'Honda',\n    modelo: 'Civic'\n}\n// Objeto2 clave y valor\nlet clave3 = {\n    id: 3\n}\nlet obj3 = {\n    marca: 'Mazda',\n    modelo: 'Sedan'\n}\n// Objeto4\nlet obj4 = {\n    marca: 'Mazda',\n    modelo: 'CX-3'\n}\n\n\n//Ingresar datos\n//weakMap.set(clave, valor)\nwekMap.set(clave1, obj1 );\nwekMap.set(clave2, obj2 );\nwekMap.set(clave3, obj3 );\n\n\n//Mostrar los elementos.\nconsole.log(\"Mostrar datos ingresados. \");\nconsole.log(wekMap);\n\n\n//Eliminar\n//weakMap.delete(clave)\nconsole.log(\"se ha eliminado exitosamente.\");\nconsole.log(wekMap.delete(clave3)); //true\n\n\n//weakMap.has(clave)\nconsole.log(\"comprobamos si existe objeto clave3.\");\nconsole.log(wekMap.has(clave3)); // false\n\n\n//Actualizar\nconsole.log(\"Objeto clave1 se actualiza valor con obj4. \");\nconsole.log(wekMap.set(clave1, obj4 ));\n\n\n//weakMap.get(clave)\nconsole.log(\"Obtener dato objeto: clave2 \");\nconsole.log(wekMap.get(clave2)); //{marca: 'Honda', modelo: 'Civic'}\n\n\n//Ordenar\nconsole.log(\"No es posible ordenar los elementos de WeakMap.\");\n\n\n/*----------------------------*/\n\n\n//Set() con datos\nlet miset = new Set(['uno', 'dos'])\n\n\n//Ingresar datos\nmiset.add('tres');\nmiset.add('cinco');\n\n\n//Mostrar los elementos.\nconsole.log(\"Mostrar datos ingresados. \");\nconsole.log(miset);//{'uno', 'dos', 'tres', 'cinco'}\n\n\n//Eliminar\nconsole.log(\" 'true' eliminado exitosamente si no, 'false' no existe\");\nconsole.log(miset.delete('tres')); //true o false\n\n\n//miset.has('tres')\nconsole.log(\"comprobamos si existe 'tres'.\");\nconsole.log(miset.has('tres')); // false o true\n\n\n//miset.values()\nconsole.log(miset.values());\n\n\n//Actualizar\nconsole.log(\"Set no proporciona un metodo para actualizar.\");\n//Ordenar\nconsole.log(\"No proporciona un metodo para ordenar, Pero es posible convertirlo en array\");\n\n\n\n\n/*----------------------------*/\n\n\n//WeakSet() /Solo admite objetos\nlet miwkset = new WeakSet();\n\n\n// objetos\nlet objeto1 = {nombre: \"objeto1\"};\nlet objeto2 = {nombre: \"objeto2\"};\nlet objeto3 = {nombre: \"objeto3\"};\n\nconsole.log(miwkset);\n\n//Ingresar datos - add(value)\nmiwkset.add(objeto1);\nmiwkset.add(objeto2);\nmiwkset.add(objeto3);\n\n//Eliminar - delete(value)\nconsole.log(\"Se elimino objeto3:\");\nconsole.log(miwkset.delete(objeto3));\n\n//-- has(value)\n//Comprobar si un objeto está en el WeakSet\nconsole.log(\"Objeto3 existe en weakset: \");\nconsole.log(miwkset.has(objeto3));\n\n//Actualizar\nconsole.log(\"Set no proporciona un metodo para actualizar.\");\n//Ordenar\nconsole.log(\"Set no proporciona un metodo para ordenar.\");\n\n\n/*.............Dificultad Extra.............*/ \n\n//Funcionalidad\n/*\n* Inserccion\n* Busqueda\n* actualizacion\n* eliminación\n*/\n\nconsole.log(\"               Dificultad Extra  \")\n\nfunction crearAgenda(){\n\n    let agenda = new Map();\n    let opcion;\n    let condicion = true;\n    let nombre = \"\";\n    let numero = \"\";\n\n    while (condicion) {\n        console.log(\" \");\n        console.log(\" 1. Crear contacto\");\n        console.log(\" 2. Buscar contacto\");\n        console.log(\" 3. Actualizar contacto\");\n        console.log(\" 4. Eliminar contacto\");\n        console.log(\" 5. Salir \");\n    \n        opcion = parseInt(prompt(\"Elige una opcion: \"));\n\n        switch (opcion) {\n                case 1:\n                \n                nombre = prompt(\"Ingrese nombre: \");\n                numero = prompt(\"Ingrese numero celular: \");\n\n                if (numero.length>0 && numero.length<=8) {\n                    agenda.set(nombre, numero);\n                    console.log(\"Contacto guardado \");\n                }else {\n                    console.log(\" El numero celular solo admite 8 digitos \");\n                }\n                    break;\n                \n                case 2:  \n                    nombre = prompt(\"Ingrese nombre: \");\n                    if ((agenda.has(nombre)) == true) {\n                        console.log(nombre); \n                        console.log(agenda.get(nombre)); // muestra el numero de contacto\n                    } else {\n                        console.log(\"No existe el contacto.\")\n                    }\n                    \n                    break;\n\n                case 3:\n                    nombre = prompt(\"Ingrese nombre: \");\n                    if ((agenda.has(nombre)) == true) {\n                        numero = prompt(\"Ingrese el numero para actualizar: \"); \n                        console.log(agenda.set(nombre, numero));\n                        console.log(\"Se actualizo el contacto.\");\n                    } else {\n                        console.log(\"No existe el contacto.\");\n                    }\n                    break;\n\n                case 4:\n                    nombre = prompt(\"Ingrese nombre para eliminar: \");\n                    if ((agenda.has(nombre)) == true) {\n                        agenda.delete(nombre);\n                        console.log(\"Contacto eliminado \");\n                    } else {\n                        console.log(\"No existe el contacto.\");\n                    }\n                    break;\n\n                case 5:\n                    condicion =false;\n                    console.log(\"Gracias por utilizar el programa\")\n                    break;\n\n                default:\n                console.log(\"Digite una opcion desde 1 a 5 \")\n                    break;\n        }\n    }\n}\n\ncrearAgenda();"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/pype-Dev.js",
    "content": "/**\n * ESTRUCTURAS DE DATOS\n */\n\n// 1. Array\nconst myArray = [1, 2, 3, 4, 5];\nconsole.log(myArray);\n\n/* Acceder a los elementos de un Array */\nconsole.log(myArray.length); //Tamaño de elementos de array\n// -> 5\nmyArray[2]; //Acceder a una posición especifica del array\n// -> 3\nmyArray[4] = 0; //Modificar un elemto del array\n// -> [1, 2, 3, 4, 0]\nconst lastItem = myArray.length -1; //Código para acceder al último elemento cuando no se conoce el tamaño del array\nconsole.log(myArray[lastItem]);\n// -> 0\nconst myArrayNew = myArray.with(0, 0); //Crea una copia del array original garantizando la inmutabilidad de esta\n// -> myArray = [1, 2, 3, 4, 0]\n// -> myArrayNew = [0, 2, 3, 4, 0]\n\n/* Añadir o eliminar elementos de un Array */\nmyArray.push(6); //Inserta el valor indicado al FINAL del array\n// -> 6 == devuleve el tamaño del array ([1, 2, 3, 4, 0, 6])\nmyArray.unshift(0); //Inserta el valor indicado al INICIO del array\n// -> 7 == devuleve el tamaño del array ([0, 1, 2, 3, 4, 0, 6])\nmyArray.pop(); //Extrae el ÚLTIMO valor del array\n// -> 6 == devuleve el elemento extraido ([0, 1, 2, 3, 4, 0])\nmyArray.shift(); //Extrae el PRIMER valor del array\n// -> 0 == devuleve el elemento extraido ([1, 2, 3, 4, 0])\n\n/*  Buscar elementos en un Array */\nconst numbers = [5, 10, 15, 20, 25, 20, 15, 10, 5];\nnumbers.includes(15); //Comprueba si el elemento existe y devuleve un valor Boolean\n// -> true\nnumbers.includes(30);\n// -> false\nnumbers.includes(20,2); //El segundo parámetro indica la posición desde donde se empieza a buscar el elemento\n// -> true\nnumbers.indexOf(20); //Devuleve la posición de un elemento dentro del array\n// -> 4\nnumbers.indexOf(0);\n// -> -1\nnumbers.indexOf(15,4) //El segundo parámetro permite encontrar elementos repetidos despues del indice indicado\n// -> 6\nnumbers.lastIndexOf(10); //Devuelve la posición del elemento indicado, pero esta vez busca desde el último hasta el primer elementos del Array\n// -> 7\nnumbers.lastIndexOf(50);\n// -> -1\nnumbers.lastIndexOf(10,2);\n// -> 1\n\n/* Ordenación de un Array */\n//.reverse() y .toReversed()\nconst elements = ['A', 'B', 'C', 'D', 'E', 'F'];\nconst reversedElements = elements.reverse();\n// -> reversedElements = ['F', 'E', 'D', 'C', 'B', 'A']\n// -> elements = ['F', 'E', 'D', 'C', 'B', 'A'] -> Array mutado\n\nconst newReversedElements = elements.toReversed();\n// -> newReversedElements = ['F', 'E', 'D', 'C', 'B', 'A'];\n// -> elements = ['A', 'B', 'C', 'D', 'E', 'F'] -> Array no mutado\n\n//.sort() y .toSorted()\nconst names = ['Paula', 'Angela', 'Sofia', 'Karen', 'Valentina'];\nconst sortedName = names.sort();\n// -> sortedName = ['Angela', 'Karen', 'Paula', 'Sofia', 'Valentina']\n// -> names = ['Angela', 'Karen', 'Paula', 'Sofia', 'Valentina'] -> Array Mutado\n\nconst newSortedName = names.toSorted();\n// -> newSortedName = ['Angela', 'Karen', 'Paula', 'Sofia', 'Valentina']\n// -> names = ['Paula', 'Angela', 'Sofia', 'Karen', 'Valentina'] -> Array no mutado\n\n//Ordenar números\nconst number = [1, 8, 2, 32, 9, 7, 4];\n\nconst naturalOrden = (a, b) => a - b;\n\nconst naturalNumbs = number.toSorted(naturalOrden);\n// -> naturalNumbs = [1, 2, 4, 7, 8, 9, 32]\n\n\n// 2. Obejto\nconst player = {\n    name : 'Barbaros',\n    life : 100,\n    power : 82,\n};\n\n/* Acceder a las propiedades de un objeto */\nconsole.log(player.name);  //Notación con punto\n// -> Barbaros\nconsole.log(player['life']);  //Notación con llaves\n// -> 100\n\n/* Añadir propiedades a un objeto*/\nplayer.damage = 75;\nplayer['velocity'] = 30;\nconsole.log(player);\n// -> {name: 'Barbaros', life: 100, power: 82, damage: 75, velocity: 30}\n\n/* Ver las propiedades de un objeto */\n\n// Método Object.keys()\nconst keys = Object.keys(player);\nconsole.log(keys);\n// -> ['name', 'life', 'power', 'damage', 'velocity']\n\n// Método Object.values()\nconst values = Object.values(player);\nconsole.log(values);\n// -> ['Barbaros', 100, 82, 75, 30]\n\n//Método Object.entries()\nconst properties = Object.entries(player);\nconsole.log(properties);\n// -> [['name', 'Barbaros'], ['life', 100], ['power', 82], ['damage', 75], ['velocity', 30]]\n\n/* Eliminar propiedades de un objeto */\ndelete player.damage;\ndelete player['velocity'];\nconsole.log(player);\n// -> {name: 'Barbaros', life: 100, power: 82}\n\n/* Modificar las porpiedades de un objeto */\n\n// Modificar un valor\nplayer.power = 90;\nplayer['life'] = 100 + 5;\nconsole.log(player);\n// -> {name: 'Barbaros', life: 105, power: 90}\n\n// Modificar una llave\nplayer.avatar = player.name; // 1. asignamos el valor de la llave original a una nueva llave\ndelete player.name; // 2. borramos la llave original\nconsole.log(player);\n// -> {avatar: 'Barbaros', life: 105, power: 90}\n\n/* Combinar objetos o propiedades */\n\n// Método Object.assign\nconst habilidades = {vission : 50, audition : 75,};\nObject.assign(player, habilidades);\nconsole.log(player);\n// -> {avatar: 'Barbaros', life: 105, power: 90, vission: 50, audition: 75}\n\n// 3. Set\nconst mySet = new Set([1, 2, 2, 3, 4]);\n// -> Set(4) {1, 2, 3, 4}\n\nmySet.size; // Cantidad de elemntos de un Set\n// -> 4\nmySet.add(5).add('A').add('B').add(true); // Añadir elementos en un Set\n// -> Set(8) {1, 2, 3, 4, 5, \"A\", \"B\", \"C\", true}\nmySet.has(4); //Comprobar si existe un elemento en un Set\n// -> true\nmySet.has('a');\n// -> false 'case sensitive'\nmySet.delete('A'); // borrar un elemento de un Set\n// -> true Set(7) {1, 2, 3, 4, 5, \"B\", \"C\", true}\nmySet.clear(); //Borra todos lo elementos de un Set\n\nconsole.log(mySet);\n// -> Set(0) {size: 0}\n\n// 4. Map\nconst myMap = new Map ([\n    ['libro', 'Cien años de Soledad'],\n    ['autor', 'Gabriel Garcia Marquez'],\n    ['nacionalidad', 'Colombiano'],\n    ['disponible', true],\n]);\n// -> Map(4) {'libro' => 'Cien años de Soledad', 'autor' => 'Gabriel Garcia Marquez', 'nacionalidad' => 'Colombiano', 'disponible' => true}}\n\nmyMap.size; // Cantidad de elemntos en un Map\n// -> 4\nmyMap.set('cantidad', 0); // Se añade la clave si no existe en el Map\n// -> Map(5) {'libro' => 'Cien años de Soledad', 'autor' => 'Gabriel Garcia Marquez', 'nacionalidad' => 'Colombiano', 'disponible' => true, 'cantidad' => 0}\nmyMap.set('disponible', false); // Se sorbreescribe el valor de la clave indicada\n// -> Map(5) {'libro' => 'Cien años de Soledad', 'autor' => 'Gabriel Garcia Marquez', 'nacionalidad' => 'Colombiano', 'disponible' => false, 'cantidad' => 0}\nmyMap.has('autor'); // Comprueba si existe un elemento en un Map por medio de su clave\n// -> true\nmyMap.has('Cien años de Soledad');\n// -> false\nmyMap.delete('nacionalidad'); // borrar un elemento de un Map\n// -> true\nmyMap.clear(); // Borrar todos lo elementos de un Map\n\nconsole.log(myMap);\n// -> Map(0) {size: 0}\n\n\n/**\n * DIFICULTAD EXTRA\n */\n\n// Importar el modulo 'readline' de Node.js\nconst { parse } = require('path');\nconst readline = require('readline');\n\n// Declaración e inicialización de la interfaz\nconst rl = readline.createInterface({\n    input: process.stdin,       // Recibe y alamcena la entreda de datos del usuario\n    output: process.stdout,     // Imprime la información recibida\n});\n\nconst agendaContactos = [];\n\nconst menuAgenda = () => {\n    console.log(`\n        MENÚ AGENDA TELEFÓNICA.\n        1. Crear contacto\n        2. Buscar contactos\n        3. Editar contacto\n        4. Ver contactos\n        5. Eliminar contacto\n        6. Salir de la agrenda\n    `);\n\n    rl.question('Seleccione una opción del 1 al 6: ', (opcion) => {\n        switch(opcion){\n            case '1':\n                crearContacto();\n                break;\n            case '2':\n                buscarContacto();\n                break;\n            case '3':\n                editarContacto();\n                break;\n            case '4':\n                verContacto();\n                break;\n            case '5':\n                eliminarContacto();\n                break;\n            case '6':\n                console.log('\\nSaliendo de los contactos... ¡Adiós!');\n                rl.close();\n                break;\n            default:\n                console.log('Opción no disponible. Seleccione una opción del 1 al 6:');\n                menuAgenda();\n                break;\n        }\n    });\n}\n\n// Opcion 1: Crear contacto\nconst crearContacto = () => {\n    rl.question('\\nNombre y Apellido: ', (name) => {\n        rl.question('Celular: ', (phone) => {\n            if(validarLongitudCelular(phone)){\n                //Guarda el Object dentro del Array agendaContactos[]\n                agendaContactos.push({\n                    Nombre: name, //{llave: valor}\n                    Celular: phone,\n                });\n\n                console.log('\\nContacto registrado.');\n            } else{\n                console.log('\\nContacto no registrado: El celular debe tener máximo 10 números.');\n            }\n            menuAgenda();\n        })\n    })\n    \n}\n\n// Opcion 2: Buscar contactos\nconst buscarContacto = () => {\n    if(agendaContactos.length === 0){\n        console.log('\\nNo hay usuarios registrados.');\n        return menuAgenda();\n    }\n\n    rl.question('\\nIngrese el nombre del contacto: ', (name) => {\n        const encontrarContacto = agendaContactos.find(contacto => contacto.Nombre.toLocaleLowerCase().includes(name.toLocaleLowerCase()));\n        \n        if(encontrarContacto){\n            console.log(`\n                Contacto encontrado.\n                Nombre: ${encontrarContacto.Nombre}\n                Celular: ${encontrarContacto.Celular}\n            `);\n        } else{\n            console.log('El contacto no existe.');\n            \n        }\n\n        menuAgenda();\n    })\n}\n\n//Opcion 3: Editar contacto\nconst editarContacto = () => {\n    rl.question('\\nIngresa el nombre del contacto: ', (name) => {\n        const indiceContacto = agendaContactos.findIndex(contacto => contacto.Nombre.toLocaleLowerCase() === name.toLocaleLowerCase()) ?? -1;\n\n        if(indiceContacto === -1){\n            console.log(\"El contacto no existe.\");\n            return menuAgenda();\n        } else{\n            const menuEditarContacto = () => {\n                console.log(`\n                    ¿Qué dato quieres actualizar:\n                    1. Nombre y Apellido\n                    2. Celular\n                    3. Toda la información del contacto\n                    4. Volver al menú principal\n                `);\n                rl.question(`Seleccione una opción del 1 al 3: `, (opcion) => {\n                    switch(opcion){\n                        case '1':\n                            rl.question('\\nEscriba el nuevo Nombre y Apellido: ', (newName) =>{\n                                agendaContactos[indiceContacto].Nombre = newName;\n                                console.log('Nombre y Apellido de contacto actualizado.');\n\n                                menuAgenda();\n                            });\n                            break;\n\n                        case '2':\n                            rl.question('\\nEscriba el nuevo número: ', (phone) => {\n                                if(validarLongitudCelular(phone)){\n                                    agendaContactos[indiceContacto].Celular = phone;\n                                    console.log('Celular actualizado.');\n                                    menuAgenda();\n                                } else{\n                                    console.log('Error: El celular debe tener máximo 10 números.');\n                                    menuEditarContacto();\n                                }\n                            });\n                            break;\n\n                        case '3':\n                            rl.question('\\nEscriba el nuevo Nombre y Apellido: ', (newName) => {\n                                rl.question('Escriba el nuevo número: ', (phone) => {\n                                    if(validarLongitudCelular(phone)){\n                                        agendaContactos[indiceContacto] = {Nombre: newName, Celular: phone};\n                                        console.log('\\nContacto actualizado.')\n                                        menuAgenda();\n                                    } else{\n                                        console.log('\\nNo se actualizó la información del contacto : El celular debe tener máximo 10 números.');\n                                        menuEditarContacto();\n                                    }\n                                });\n                            });\n                            break;\n                        \n                        case '4':\n                            menuAgenda();\n                            break;\n\n                        default:\n                            console.log('Opción no disponible. Seleccione una opción del 1 al 3.');\n                            menuEditarContacto();\n                            break;\n                        }\n                });\n            }\n            menuEditarContacto();\n        } \n    });\n}\n\n// Opcion 4: Ver contactos\nconst verContacto = () => {\n    if(agendaContactos.length === 0){\n        console.log('Aún no hay contactos registrados.');\n    } else{\n        for(const registros of agendaContactos){\n            console.log(registros);\n        }\n    }\n\n    rl.question('\\n¿Quiere registrar un nuevo contacto? (Si/No) ', (registroNuevo) => {\n        if(registroNuevo.toLocaleLowerCase() === 'si'){\n            crearContacto()\n        } else{\n            menuAgenda();\n        }\n    });\n}\n\n// Opcion 5: Elimianr contacto\nconst eliminarContacto = () => {\n    rl.question('\\nIngrese el nombre del contacto: ', (name) => {\n        const indiceContacto = agendaContactos.findIndex(contacto => contacto.Nombre.toLocaleLowerCase() === name.toLocaleLowerCase()) ?? -1;\n\n        if(indiceContacto === -1){\n            console.log(\"El contacto no existe.\");\n            return menuAgenda();\n        } else{\n            rl.question(`\\n¿Esta seguro que quiere eliminar a ${name} de sus contactos? `, (confirmarBorrado) => {\n                if(confirmarBorrado.toLocaleLowerCase() === 'si'){\n                    agendaContactos.splice(indiceContacto, 1);\n                    console.log('\\nContacto eliminado');\n                    menuAgenda();\n                } else{\n                    return menuAgenda();\n                }\n            });\n        }\n    });\n}\n\n//Valida condición del telefono\nconst validarLongitudCelular = function (telefono){\n    if(!isNaN(telefono) && telefono.length === 10){ //Código para verificar que sea un dato Number y que tenga 10 digitos\n        return true;\n    } else{\n        return false;\n    }\n}\n\n\nmenuAgenda();"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/qwik-zgheib.js",
    "content": "import { createInterface } from \"readline\";\n\n/* -- exercise */\nlet fruits = [\"Apple\", \"Banana\", \"Cherry\"];\n\nfruits.push(\"Date\");\nconsole.log(\"Array after insertion:\", fruits);\nfruits.pop();\nconsole.log(\"Array after deletion:\", fruits);\nfruits[1] = \"Blueberry\";\nconsole.log(\"Array after update:\", fruits);\nfruits.sort();\nconsole.log(\"Sorted array:\", fruits);\n\nlet colors = new Set([\"red\", \"green\", \"blue\"]);\ncolors.add(\"yellow\");\nconsole.log(\"Set after insertion:\", colors);\ncolors.delete(\"green\");\nconsole.log(\"Set after deletion:\", colors);\n\nlet fruitsMap = new Map([\n  [\"apple\", 5],\n  [\"banana\", 10],\n  [\"cherry\", 15],\n]);\nfruitsMap.set(\"date\", 20);\nconsole.log(\"Map after insertion:\", fruitsMap);\nfruitsMap.delete(\"banana\");\nconsole.log(\"Map after deletion:\", fruitsMap);\nfruitsMap.set(\"cherry\", 18);\nconsole.log(\"Map after update:\", fruitsMap);\n\nlet sentence = \"Hello, world!\";\nlet newSentence = sentence.replace(\"world\", \"JavaScript\");\nconsole.log(\"String after replacement:\", newSentence);\nlet modifiedSentence = \"Hey \" + sentence + \" Have a nice day!\";\nconsole.log(\"String after insertion:\", modifiedSentence);\nlet removedText = sentence.replace(\", world\", \"\");\nconsole.log(\"String after deletion:\", removedText);\n\n/* -- extra challenge */\nconst rl = createInterface({\n  input: process.stdin,\n  output: process.stdout,\n});\n\nlet contacts = [];\nconst isNumeric = (str) => {\n  return /^\\d+$/.test(str);\n};\n\nconst addContact = (name, phoneNumber) => {\n  contacts.push({ name, phoneNumber });\n  console.log(`Contact ${name} added successfully.`);\n};\n\nconst searchContact = (name) => {\n  let foundContacts = contacts.filter((contact) => contact.name.toLowerCase() === name.toLowerCase());\n  if (foundContacts.length > 0) {\n    console.log(`Found ${foundContacts.length} contacts:`);\n    foundContacts.forEach((contact) => console.log(`Name: ${contact.name}, Phone Number: ${contact.phoneNumber}`));\n  } else console.log(`No contacts found with name '${name}'.`);\n};\n\nconst updateContact = (name, newPhoneNumber) => {\n  let foundContact = contacts.find((contact) => contact.name.toLowerCase() === name.toLowerCase());\n  if (foundContact) {\n    foundContact.phoneNumber = newPhoneNumber;\n    console.log(`Phone number updated for contact '${name}'.`);\n  } else console.log(`Contact '${name}' not found.`);\n};\n\nconst deleteContact = (name) => {\n  let initialLength = contacts.length;\n  contacts = contacts.filter((contact) => contact.name.toLowerCase() !== name.toLowerCase());\n  if (contacts.length < initialLength) console.log(`Contact '${name}' deleted successfully.`);\n  else console.log(`Contact '${name}' not found.`);\n};\n\nconst handleUserInput = () => {\n  rl.question(`\\nChoose an operation:\\n1. Add contact\\n2. Search contact\\n3. Update contact\\n4. Delete contact\\n5. Exit\\n`, function (option) {\n    switch (option.trim()) {\n      case \"1\":\n        rl.question(`Enter name: `, function (name) {\n          rl.question(`Enter phone number: `, function (phoneNumber) {\n            if (isNumeric(phoneNumber) && phoneNumber.length <= 11) addContact(name, phoneNumber);\n            else console.log(`Invalid phone number format.`);\n\n            handleUserInput();\n          });\n        });\n        break;\n      case \"2\":\n        rl.question(`Enter name to search: `, function (name) {\n          searchContact(name);\n          handleUserInput();\n        });\n        break;\n      case \"3\":\n        rl.question(`Enter name to update: `, function (name) {\n          rl.question(`Enter new phone number: `, function (phoneNumber) {\n            if (isNumeric(phoneNumber) && phoneNumber.length <= 11) updateContact(name, phoneNumber);\n            else console.log(`Invalid phone number format.`);\n\n            handleUserInput();\n          });\n        });\n        break;\n      case \"4\":\n        rl.question(`Enter name to delete: `, function (name) {\n          deleteContact(name);\n          handleUserInput();\n        });\n        break;\n      case \"5\":\n        rl.close();\n        break;\n      default:\n        console.log(`Invalid option. Please choose a valid operation.`);\n        handleUserInput();\n    }\n  });\n};\n\nconsole.log(\"Welcome to the Contact Agenda!\");\n\nhandleUserInput();\n\nrl.on(\"close\", () => {\n  console.log(\"Exiting the Contact Agenda. Goodbye!\");\n  process.exit(0);\n});\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/ralphmcralph.js",
    "content": "// Estructuras por defecto\r\n\r\n// ARRAYS\r\n\r\nvar myArray = [\"Manolo\", \"Benito\", \"Kamelas\"]\r\nconsole.log(myArray);\r\n\r\n// Operaciones de inserción\r\n\r\nmyArray.push(\"Alonso\");\r\n\r\nconsole.log(myArray);\r\n\r\n// Operaciones de borrado\r\n\r\nvar newArray = myArray.filter(e => e !== 'Kamelas');\r\n\r\nmyArray = newArray;\r\n\r\nconsole.log(myArray);\r\n\r\n// Operaciones de actualización\r\n\r\nmyArray[myArray.indexOf(\"Alonso\")] = \"Fernando Alonso\";\r\n\r\nconsole.log(myArray);\r\n\r\n// Operaciones de ordenación\r\n\r\nmyArray.sort()\r\n\r\nconsole.log(myArray);\r\n\r\n// Objetos\r\n\r\nvar myObject = {\r\n    name: \"Brais\",\r\n    surname: \"Moure\",\r\n    username: \"@mouredev\",\r\n    age: 36\r\n}\r\n\r\nconsole.log(typeof (myObject));\r\n\r\n// Sets\r\n\r\nconst a = new Set([1, 2, 3]);\r\n\r\na.add(\"Hola\");\r\n\r\nconsole.log(a);\r\nconsole.log(typeof (a));\r\n\r\n\r\n// Map\r\n\r\nconst b = new Map([\r\n    [1, \"one\"],\r\n    [2, \"two\"],\r\n    [3, \"three\"]\r\n])\r\n\r\nconsole.log(b);\r\nconsole.log(typeof (b));\r\n\r\n\r\nb.set(4, \"four\");\r\nb.delete(3);\r\nb.set(4, \"cuatro\");\r\n\r\nconsole.log(b);\r\n\r\n\r\n/* DIFICULTAD EXTRA(opcional):\r\n* Crea una agenda de contactos por terminal.\r\n* - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\r\n* - Cada contacto debe tener un nombre y un número de teléfono.\r\n* - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\r\n   * los datos necesarios para llevarla a cabo.\r\n* - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\r\n* (o el número de dígitos que quieras)\r\n* - También se debe proponer una operación de finalización del programa.\r\n*/\r\n\r\nconst readlineSync = require('readline-sync');\r\n\r\nconst contactos = new Map();\r\n\r\nasync function my_agenda() {\r\n\r\n    while (true) {\r\n        console.log(\"\");\r\n        console.log(\"1. Buscar contacto\");\r\n        console.log(\"2. Insertar contacto\");\r\n        console.log(\"3. Actualizar contacto\");\r\n        console.log(\"4. Eliminar contacto\");\r\n        console.log(\"5. Salir\");\r\n\r\n\r\n        let selected_option = parseInt(readlineSync.question(\"Selecciona una opción: \"));\r\n\r\n        switch (selected_option) {\r\n            case 1:\r\n                buscarContacto();\r\n                break;\r\n            case 2:\r\n                insertarContacto();\r\n                break;\r\n            case 3:\r\n                actualizarNumeroContacto();\r\n                break;\r\n            case 4:\r\n                borrarContacto();\r\n                break;\r\n            case 5:\r\n                console.log(\"Saliendo de la agenda\");\r\n                process.exit(0);\r\n            default:\r\n                console.log(\"Opción no válida. Elige una opción del 1 al 5\");\r\n                break;\r\n\r\n        }\r\n    }\r\n\r\n\r\n}\r\n\r\nfunction introducirNumero() {\r\n\r\n    let numero;\r\n\r\n    do {\r\n        numero = readlineSync.question(\"Introduce el número del contacto: \");\r\n\r\n        numero = parseInt(numero);\r\n    } while (isNaN(numero) || numero.toString().length >= 11 || numero.toString().length <= 0);\r\n\r\n    return numero;\r\n}\r\n\r\nfunction buscarContacto() {\r\n    let nombre;\r\n\r\n    do {\r\n        nombre = readlineSync.question(\"Introduce el nombre del contacto: \");\r\n    } while (!contactos.has(nombre))\r\n\r\n    console.log(`Contacto encontrado: ${nombre} - ${contactos.get(nombre)}`);\r\n\r\n    return nombre;\r\n}\r\n\r\nfunction insertarContacto() {\r\n    let nombre = readlineSync.question(\"Introduce el nombre del contacto: \");\r\n    let numero = introducirNumero();\r\n\r\n    if (contactos.has(numero)) {\r\n        console.log(\"El número ya está registrado\");\r\n\r\n    } else {\r\n        contactos.set(nombre, numero);\r\n        console.log(`Contacto guardado: ${nombre} - ${numero}`);\r\n    }\r\n}\r\n\r\nfunction actualizarNumeroContacto() {\r\n    let nombre = buscarContacto();\r\n\r\n    let nuevoNumero = introducirNumero();\r\n\r\n    contactos.set(nombre, nuevoNumero);\r\n\r\n    console.log(`Contacto guardado: ${nombre} - ${nuevoNumero}`);\r\n\r\n}\r\n\r\nfunction borrarContacto() {\r\n    let nombre = buscarContacto();\r\n\r\n    contactos.delete(nombre);\r\n    console.log(`Contacto eliminado: ${nombre}`);\r\n\r\n}\r\n\r\n\r\n\r\nmy_agenda();\r\n\r\n\r\n\r\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/raulG91.js",
    "content": "//Array\nconsole.log(\"***Array***\");\nlet array = [6,4,23,3,4];\n\n//Add element \narray.push(10);\nconsole.log(\"Add element: \",array);\n\n//Delete last element\narray.pop();\nconsole.log(\"Remove last element: \",array);\n\n//Delete specific element\narray.splice(1,1) //Removes element at position 1\nconsole.log(\"Remove specific element: \",array);\n\n//Update element at position 0 \narray[0] = 5;\nconsole.log(\"Update element at pos 0: \",array);\n\n//Order array\nfunction compareNumeric(a, b) {\n    if (a > b) return 1;\n    if (a == b) return 0;\n    if (a < b) return -1;\n  }\narray.sort(compareNumeric);\nconsole.log(\"Sort array: \",array);\n\n//MAP\nconsole.log(\"***Map***\");\nlet map = new Map();\n\n//Add values to the map\nmap.set(1,\"one\");\nmap.set(2,\"two\");\nconsole.log(\"Adding element: \",map);\n\n//Update value\nmap.set(2,\"dos\");\nconsole.log(\"Update value: \",map);\n\n//Borrado \nmap.delete(2) //Delete element with key\nconsole.log(\"Delete element: \",map);\n\n//Set \nconsole.log(\"***Set***\");\n\nlet set = new Set();\n//Add element\nset.add(1);\nset.add(2);\nset.add(10)\nconsole.log(\"Add elements: \", set);\n\n//Delete element\nset.delete(10)\nconsole.log(\"Delete elements: \",set);\n\n// Objects\nconsole.log(\"***Object***\");\nmy_object = {\n\n    name:\"Raul\",\n    last_name:\"last name\"\n}\n\n// Add element\nmy_object.age = 14;\nconsole.log(\"Adding element: \",my_object);\n\n//Update element\nmy_object.age = 32;\nconsole.log(\"Update object: \", my_object);\n\n//Delete element\ndelete my_object.last_name;\nconsole.log(\"Delete element: \", my_object);\n\n//Extra exercise\nconst  readline = require('node:readline').createInterface({\n    input: process.stdin,\n    output: process.stdout,\n  });\n\nlet contact_agenda = {};\n\nfunction agenda(){\n        show_menu();\n        readline.question(\"Insert operation: \",(operation)=>{\n            operation = parseInt(operation);\n            switch(operation){\n                case 1: //Insert\n                    readline.question(\"Insert user name: \",(name)=>{\n                        if(contact_agenda[name]){\n                            console.log(\"User already exist\");\n                            agenda()\n                        }\n                        else{\n                            readline.question('Insert number: ',(number)=>{\n                                phone = parseInt(number);\n                                if(validate_number(phone)){\n                                    contact_agenda[name] = phone;\n                                }\n                                else{\n                                    console.log(\"Invalid phone number\");\n                                }\n                                \n                                agenda()\n                            });\n                        }\n                       \n                    });\n                    break;\n                case 2: //Update\n                    readline.question('Insert user name: ',(name)=>{\n                        if(contact_agenda[name]){\n                            //User already exist\n                            readline.question('Insert new phone number: ',(number)=>{\n                                phone = parseInt(number);\n                                if(validate_number(phone)){\n                                    contact_agenda[name] = phone;\n                                }\n                                else{\n                                    console.log(\"Invalid phone number\");\n                                }\n                                agenda()\n                            })\n                        }   \n                        else{\n                            console.log(\"User doesn't exist\");\n                            agenda()\n\n                        }\n                    });\n                    break;   \n                case 3: //Delete user\n                    readline.question('Insert user name: ',(name)=>{\n                        if(contact_agenda[name]){\n                            delete contact_agenda[name];\n                        }\n                        else{\n\n                            console.log(\"User doesn't exist\");\n                        }\n                        agenda();\n                    });\n                    break;\n                case 4: //Show user phone\n                    readline.question('Insert user name: ',(name)=>{\n                        if(contact_agenda[name]){\n                          console.log(`Phone number for ${name} is ${contact_agenda[name]}`);\n                        }\n                        else{\n                            console.log(\"User doesn't exist\");\n                        }\n                        agenda();\n                    });\n                    break;  \n                case 5: //Exit program \n                    readline.close();\n                    break\n                }\n        })\n\n}\nfunction show_menu(){\n\n    console.log(\"Insert 1 to create user\");\n    console.log(\"Insert 2 to update user\");\n    console.log(\"Insert 3 to delete user\");\n    console.log(\"Insert 4 to look for a user\");\n    console.log(\"Insert 5 to exit\");\n}\nfunction validate_number(number){\n\n    return /^\\d{9}$/.test(number)\n}\nagenda();"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/reinaldosanchez.js",
    "content": "//Estructuras de datos\n//arreglos\nlet frutas = [\"manzana\", \"banana\", \"naranja\"];\n\n// Insertar\nfrutas.push(\"pera\"); // Añade al final\nfrutas.splice(1, 0, \"kiwi\"); // Inserta en el índice 1\n\n// Borrar\nfrutas.pop(); // Elimina el último\nfrutas.splice(2, 1); // Elimina 1 elemento desde índice 2\n\n// Actualizar\nfrutas[0] = \"mango\";\n\n// Ordenar\nfrutas.sort(); // Orden alfabético\nconsole.log(frutas);\n//objetos\nlet persona = {\n    nombre: \"Juan\",\n    edad: 30,\n    ciudad: \"Madrid\"\n};\n\n// Insertar\npersona.pais = \"España\"; // Añade una nueva propiedad\npersona.edad = 31; // Actualiza una propiedad existente\n\n// Borrar\ndelete persona.ciudad; // Elimina una propiedad\n\n// Acceder\nconsole.log(persona.nombre); // Accede a una propiedad\nconsole.log(persona[\"edad\"]); // Accede a una propiedad con nombre dinámico\n\n\n//reto\n\nlet agenda = [\n    {\n        nombre: \"Reinaldo\",\n        telefono: \"123456789\"\n    },\n    {\n        nombre: \"Juan\",\n        telefono: \"123456789\"\n    },\n    {\n        nombre: \"Pedro\",\n        telefono: \"123456789\"\n    }\n]; //agenda de contactos\n\n//funcion validar telefono\nfunction validarTelefono(telefono) {\n    let regex = /^\\d{1,11}$/;\n    return regex.test(telefono);\n};\n\n//funcion agregar contacto\nfunction agregarContacto() {\n    let nombre = prompt(\"Ingrese el nombre\");\n    let telefono = prompt(\"Ingrese el telefono\");\n    if (!validarTelefono(telefono)) {\n        alert(\"Numero invalido. Solo numeros y maximo 11 digitos\");\n        return;\n    }\n    agenda.push({ nombre, telefono });\n    alert(\"Contacto agregado\");\n};\n\n//funcion mostrar agenda\nfunction mostrarAgenda() {\n    if (agenda.length === 0) {\n        alert(\"Agenda vacia\");\n        return;\n    }\n    let lista = \"Contactos:\\n\";\n    agenda.forEach((c, i) => {\n        lista += `$(i + 1). ${c.nombre} - {c.telefono}\\n`;\n    });\n\n    alert(lista);\n};\n\n//funcion buscar contacto\nfunction buscarContacto() {\n    let nombre = prompt(\"Nombre a buscar:\");\n    let resultados = agenda.filter(c => c.nombre.toLowerCase() === nombre.toLowerCase());\n\n    if (resultados.length === 0) {\n        alert(\"No se encontró ningún contacto con ese nombre.\");\n    } else {\n        let lista = \"Resultados:\\n\";\n        resultados.forEach(c => lista += `${c.nombre} - ${c.telefono}\\n`);\n        alert(lista);\n    }\n};\n\n//funcion actualizar contacto\nfunction actualizarContacto() {\n    let nombre = prompt(\"Nombre del contacto a actualizar:\");\n    let contacto = agenda.find(c => c.nombre.toLowerCase() === nombre.toLowerCase());\n\n    if (!contacto) {\n        alert(\"Contacto no encontrado.\");\n        return;\n    }\n\n    let nuevoTelefono = prompt(\"Ingresa el nuevo teléfono:\");\n    if (!validarTelefono(nuevoTelefono)) {\n        alert(\"Número inválido.\");\n        return;\n    }\n\n    contacto.telefono = nuevoTelefono;\n    alert(`${nombre} actualizado/a correctamente.`);\n};\n\n//funcion eliminar contacto\nfunction eliminarContacto() {\n    let nombre = prompt(\"Nombre del contacto a eliminar:\");\n    let indice = agenda.findIndex(c => c.nombre.toLowerCase() === nombre.toLowerCase());\n\n    if (indice === -1) {\n        alert(\"Contacto no encontrado.\");\n        return;\n    }\n\n    agenda.splice(indice, 1);\n    alert(`${nombre} eliminado/a de la agenda.`);\n};\n\n//funcion principal\nfunction menu() {\n    let opcion = prompt(\"Seleccione una opción:\\n1. Agregar contacto\\n2. Mostrar agenda\\n3. Buscar contacto\\n4. Actualizar contacto\\n5. Eliminar contacto\\n6. Salir\");\n\n    switch (opcion) {\n        case \"1\":\n            agregarContacto();\n            break;\n        case \"2\":\n            mostrarAgenda();\n            break;\n        case \"3\":\n            buscarContacto();\n            break;\n        case \"4\":\n            actualizarContacto();\n            break;\n        case \"5\":\n            eliminarContacto();\n            break;\n        case \"6\":\n            alert(\"Hasta luego!\");\n            break;\n        default:\n            alert(\"Opción inválida. Intente de nuevo.\");\n    }\n};"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/rlores-edison.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n */\n\n\n/*KIND OF OBJECTS:\n\nARRAYS:\n\nAn array can hold many values under a single name.*/\nconst capitals = [\"Madrid\", \"Paris\", \"London\", \"Rome\"];\nconsole.log(capitals);\n\nconst cars = [\"Saab\", \"Volvo\", \"BMW\", \"Seat\", \"Ford\"];\n// Access the full array and print it in the Terminal:\nconsole.log(cars); \n\n\n//ARRAY PROPERTIES AND METHODS:\n\n// Access the values by referring ALWAYS to an index NUMBER (Arrays use numbered indexes):\nconsole.log(cars[0]); // Saab in position 0\n\n// Change the value of a specific index:\ncars[0]= \"Audi\";\nconsole.log(cars); // Changed element 0, now Audi\n\n// Access the last element in the array:\nconsole.log(cars[cars.length - 1]); // Ford in position 4\n\n// Print the length of an array:\nconst movies = [\"Alice in Wonderland\", \"The Lion King\", \"Aladdin\", \"Dumbo\"];\nlet length = movies.length;\nconsole.log(length); // 4\n\n// Add a new element to the end of an array:\ncars[cars.length] = \"Mercedes\"; // Using the .length property or the Array.push() method.\nconsole.log(cars); // Mercedes in position 5\ncars.push(\"BMW\"); // Add a new element to the end of an array\nconsole.log(cars); // BMW in position 6\n\n//Add a new element to the beginning of an array:\ncars.unshift(\"Volvo\"); // Add a new element to the beginning of an array\nconsole.log(cars); // Volvo in position 0\n\n// Remove an element from an array:\ncars.pop(); // Remove the last element from an array\nconsole.log(cars); // [\"Saab\", \"Volvo\", \"BMW\", \"Seat\"]\ncars.shift(); // Remove the first element from an array\nconsole.log(cars); // [\"Volvo\", \"BMW\", \"Seat\"]\n\n// Flat the array:\nconst myArr = [[1,2],[3,4],[5,6]];\nconst newArr = myArr.flat();\nconsole.log(newArr); // [1, 2, 3, 4, 5, 6]  \n\n// Array.at() method to find out which elements are in an array position:\nconsole.log(cars.at(0)); \nconsole.log(cars.at(2));\n\n// Sort an array:\nlet sort = movies.sort();\nconsole.log(sort) // [\"Aladdin\", \"Alice in Wonderland\", \"Dumbo\", \"The Lion King\"]\n\n// Looping through an array:\nfor (let i = 0; i < movies.length; i++) {\n  console.log(movies[i]);\n}\n\n// We can also create de array and provide the elements:\nconst fruits = [];\nfruits[0]= \"pear\";\nfruits[1]= \"apple\";\nfruits[2]= \"banana\";\n\nconsole.log(fruits);\n\n// Converting an Array to String or text, using .toString() method:\nconst pets = [\"dog\", \"cat\", \"bird\", \"mouse\", \"fish\"];\nconsole.log(pets.toString());\n\n\n/*OBJECTS: \n\nObjects use NAMES to Access its values (Objects use named indexes):*/ \nconst person = {firstName:\"Alf\",  lastName:\"Brown\", age:\"53\"};\nconsole.log(person);\n\n\n/*NESTED ARRAYS AND OBJECTS:\nValues in objects can be arrays, and values in arrays can be objects, variables of different types, functions and arrays:*/\n\nconst obj = {\n  fruits: [\"apple\", \"banana\", \"orange\"]\n};\n\nconst arr = [\n  { name: \"John\", age: 30 },\n  { name: \"Jane\", age: 25 }\n];\n\nlet mixedVar = \"Hello\"; // string\nmixedVar = 42; // number\nmixedVar = true; // boolean\n\nconst functionsArray = [\n  function() { console.log(\"Function 1\"); },\n  () => { console.log(\"Arrow Function\"); }\n];\n\nconst nestedArr = [\"outer\", [1, 2, [3, 4]]];\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\nconst contacts = [\n  { name: \"John Doe\", phoneNumber: \"+1234567890\" },\n  { name: \"Jane Smith\", phoneNumber: \"+9876543210\" },\n  { name: \"Mike Johnson\", phoneNumber: \"+1122334455\" },\n  { name: \"Emily Brown\", phoneNumber: \"+5667788999\" },\n  { name: \"David Lee\", phoneNumber: \"+4444555566\" },\n  { name: \"Sarah Taylor\", phoneNumber: \"+7777888899\" },\n  { name: \"Kevin White\", phoneNumber: \"+2223334444\" },\n  { name: \"Lisa Nguyen\", phoneNumber: \"+5556667777\" },\n  { name: \"Tom Harris\", phoneNumber: \"+8889990000\" },\n  { name: \"Amy Martin\", phoneNumber: \"+1112223333\" }\n];   \n\n//Funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n\nconst prompt = require(\"prompt-sync\")({sigint: true});\n\nconsole.log(\"Select the operation you want to perform:\");\nconsole.log(\"1. Search contact\");\nconsole.log(\"2. Insert contact\");\nconsole.log(\"3. Update contact\");\nconsole.log(\"4. Delete contact\");\nconsole.log(\"5. Exit\");\n\nlet operationSelected = false;\n\nwhile (!operationSelected) {\n  let input = prompt(\"Enter the number of the operation you want to perform (1-5): \");\n\n  if (input === null) {\n    console.log(\"Operation cancelled.\");\n    break;\n  }\n  let selectedNumber = parseInt(input, 10);\n\n  switch (selectedNumber) {\n    case 1:\n      console.log(\"Search contact selected\");\n      searchContacts();\n      operationSelected = true;\n      break;\n    case 2:\n      console.log(\"Insert contact selected\");\n      insertContact();\n      operationSelected = true;\n      break;\n    case 3:\n      console.log(\"Update contact selected\");\n      updateContact();\n      operationSelected = true;\n      break;\n    case 4:\n      console.log(\"Delete contact selected\");\n      deleteContact();\n      operationSelected = true;\n      break;\n    case 5:\n      console.log(\"Exiting...\");\n      operationSelected = true;\n      break;\n    default:\n      console.log(\"Invalid input. Please enter a number between 1 and 5.\");\n  }\n}\n\nfunction searchContacts() {\n  let searchTerm = prompt(\"Enter the name of the contact you want to search for: \");\n  const foundContacts = contacts.filter((contact) => \n    contact.name.toLowerCase().includes(searchTerm.toLowerCase())\n  );\n  \n  if (foundContacts.length > 0) {\n    console.log(`Found ${foundContacts.length} matching contact(s):`);\n    foundContacts.forEach((contact, index) => {\n      console.log(`${index + 1}. Name: ${contact.name}, Phone: ${contact.phoneNumber}`);\n    });\n  } else {\n    console.log(\"No contacts found.\");\n  }\n}\n\nfunction insertContact() {\n  let name = prompt(\"Enter the name of the contact: \");\n  let phoneNumber = prompt(\"Enter the phone number of the contact: \");\n  \n  if (!validatePhoneNumber(phoneNumber)) {\n    console.log(\"Invalid phone number format. Please use XXX-XXX-XXXX\");\n    return;\n  }\n  \n  contacts.push({ name, phoneNumber });\n  console.log(`Contact ${contacts.length} added.`);\n  console.log(contacts);\n}\n\nfunction validatePhoneNumber(phone) {\n  const regex = /^\\(?([0-9]{3})\\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$/;\n  return phone.match(regex);\n}\n\n\nfunction findContactIndex(name) {\n  return contacts.findIndex((contact) => contact.name.toLowerCase() === name.toLowerCase());\n}\n\nfunction updateContact() {\n  const name = prompt(\"Enter the name of the contact to update: \");\n  const index = findContactIndex(name);\n  if (index !== -1) {\n    const phone = prompt(\"Enter the new phone number: \");\n    if (!validatePhoneNumber(phone)) {\n      console.log(\"Invalid phone number.\");\n      updateContact();\n    } else {\n      contacts[index].phoneNumber = phone;\n      console.log(\"Contact updated.\");\n      console.log(contacts);\n    }\n  } else {\n    console.log(\"Contact not found.\");\n    mainMenu();\n  }\n}\n\nfunction deleteContact() {\n  let name = prompt(\"Enter the name of the contact you want to delete: \"); \n  const index = findContactIndex(name);\n  if (index !== -1) {\n    const deletedContact = contacts.splice(index, 1)[0];\n    console.log(`Contact deleted: Name - ${deletedContact.name}, Phone - ${deletedContact.phoneNumber}`);\n  } else {\n    console.log(\"Contact not found.\");\n  }\n  console.log(contacts);\n}"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/robmxz.js",
    "content": "/*#03 ESTRUCTURAS DE DATOS*/\n\n// 1. Arrays\n\nlet arrayNumerico = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; // Array de números\nlet arrayString = [\"Hola\", \"Mundo\", \"en\", \"Array\", \"!\"]; // Array de strings\nlet arrayMixto = [1, \"Hola\", 2, \"Mundo\", 3, \"en\", 4, \"Array\", 5, \"!\"]; // Array mixto\n\n// Insertando valores\n\narrayNumerico.push(11); // Inserta el valor 11 al final del array\n//console.log(arrayNumerico); -> // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]\narrayNumerico.unshift(0); // Inserta el valor 0 al inicio del array\n//console.log(arrayNumerico); -> // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]\n\n// Eliminando valores\n\narrayNumerico.pop(); // Elimina el último valor del array\n//console.log(arrayNumerico); -> // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n\narrayNumerico.shift(); // Elimina el primer valor del array\n//console.log(arrayNumerico); -> // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n\narrayNumerico.splice(0, 5); // Elimina los primeros 5 valores del array\n//console.log(arrayNumerico); -> // [6, 7, 8, 9, 10]\n\n// Actualizando valores\n\narrayAlCuadrado = arrayNumerico.map((num) => Math.pow(num, 2)); // Eleva al cuadrado cada valor del array\n// console.log(arrayAlCuadrado); // -> [36, 49, 64, 81, 100]\n\n// Ordenando valores\n\narrayNumerico.sort((a, b) => b - a); // Ordena los valores de forma descendente\n//console.log(arrayNumerico); // -> [10, 9, 8, 7, 6]\n\narrayNumerico.reverse(); // Invierte el orden de los valores del array\n//console.log(arrayNumerico); // -> [6, 7, 8, 9, 10]\n\n// 2. Objetos\n\nlet Programmer = {\n  dev: \"RobMxz\",\n  edad: 18,\n  nacionalidad: \"Peruana\",\n  lenguajes: [\"JavaScript\", \"Python\", \"Java\", \"C++\"],\n};\n\nlet Gato = {\n  nombre: \"Yoko\",\n  raza: \"Bengala\",\n  edad: 4,\n};\n\n// Array de Objetos\n\nlet arrayObjetos = [Programmer, Gato];\n\n// Añadir un valor\n\nProgrammer[\"sexo\"] = \"Masculino\";\n//console.log(Programmer); // -> {dev: \"RobMxz\", edad: 18, nacionalidad: \"Peruana\", [ 'JavaScript', 'Python', 'Java', 'C++' ], sexo: \"Masculino\"}\n\n// Actualizar un valor\n\nProgrammer[\"edad\"] = 19;\n//console.log(Programmer); // -> {dev: \"RobMxz\", edad: 19, nacionalidad: \"Peruana\", [ 'JavaScript', 'Python', 'Java', 'C++' ], sexo: \"Masculino\"}\n\n// Eliminar un valor\n\ndelete Programmer[\"nacionalidad\"];\n//console.log(Programmer); // -> {dev: \"RobMxz\", edad: 19, [ 'JavaScript', 'Python', 'Java', 'C++' ], sexo: \"Masculino\"}\n\n// Dificultad extra :)\n\n/*\n    DIFICULTAD EXTRA (opcional):\n    Crea una agenda de contactos por terminal.\n    Debes implementar funcionalidades de búsqueda, inserción, actualización\n    y eliminación de contactos.\n    Cada contacto debe tener un nombre y un número de teléfono.\n    El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n    y a continuación los datos necesarios para llevarla a cabo.\n    El programa no puede dejar introducir números de teléfono no númericos y con más\n    de 11 dígitos (o el número de dígitos que quieras).\n    También se debe proponer una operación de finalización del programa.\n*/\n\nconst readline = require(\"readline\");\n\nlet rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout,\n});\n\nlet usuario = \"RobMxz\";\n\nlet contactos = [];\n\nfunction agenda() {\n  rl.question(options(), (respuesta) => {\n    switch (respuesta) {\n      case \"1\":\n        añadirContacto();\n        break;\n      case \"2\":\n        buscarContacto();\n        break;\n      case \"3\":\n        actualizarContacto();\n        break;\n      case \"4\":\n        eliminarContacto();\n        break;\n      case \"5\":\n        console.log(\"\\nAdios muchas gracias por usar la agenda ٩(◕‿◕｡)۶\\n\");\n        rl.close();\n        break;\n      default:\n        agenda();\n        break;\n    }\n  });\n}\n\nfunction options() {\n  return (\n    `Hola ${usuario} !!!` +\n    \"\\nEliga una opción ◑﹏◐ ( 1 - 5 )\\n\" +\n    \"1.Agrega un contacto 📱\\n\" +\n    \"2.Buscar un contacto\\n\" +\n    \"3.Actualizar un contacto\\n\" +\n    \"4.Eliminar un contacto\\n\" +\n    \"5.Salir\\n\" +\n    \"Opción: \"\n  );\n}\n\nfunction añadirContacto() {\n  rl.question(\"Nombre: \", (nombre) => {\n    if (contactos.find((contacto) => contacto.nombre === nombre)) {\n      console.log(\"\\nEl contacto ya existe\\n\");\n      return agenda();\n    }\n    rl.question(\"Número: \", (numero) => {\n      if (!verificacion(numero)) {\n        console.log(\"\\nNúmero no válido\\n\");\n        return agenda();\n      }\n      if (contactos.find((contacto) => contacto.numero === numero)) {\n        console.log(\"\\nEl número ya existe\\n\");\n        return agenda();\n      }\n      contactos.push({ nombre, numero });\n      console.log(\"\\nContacto añadido\\n\");\n      agenda();\n    });\n  });\n}\n\nfunction buscarContacto() {\n  if (contactos.length === 0) {\n    console.log(\"\\nNo hay contactos\\n\");\n    return agenda();\n  }\n  rl.question(\"Indique el nombre del contacto ლ(╹◡╹ლ): \", (nombre) => {\n    let contacto = contactos.find((contacto) => contacto.nombre === nombre);\n    if (contacto) {\n      console.log(`\\nNombre: ${contacto.nombre}, Número: ${contacto.numero}\\n`);\n    } else {\n      console.log(\"\\nContacto no encontrado\\n\");\n    }\n    agenda();\n  });\n}\n\nfunction actualizarContacto() {\n  if (contactos.length === 0) {\n    console.log(\"\\nNo hay contactos\\n\");\n    return agenda();\n  }\n  rl.question(\"Indique el nombre del contacto: \", (nombre) => {\n    let contacto = contactos.find((contacto) => contacto.nombre === nombre);\n    if (contacto) {\n      rl.question(\"Nuevo número: \", (numero) => {\n        if (!verificacion(numero)) {\n          console.log(\"\\nNúmero no válido\\n\");\n          return agenda();\n        }\n        contacto.numero = numero;\n        console.log(\"\\nContacto actualizado\\n\");\n        return agenda();\n      });\n    } else {\n      console.log(\"\\nContacto no encontrado\\n\");\n      agenda();\n    }\n  });\n}\n\nfunction eliminarContacto() {\n  if (contactos.length === 0) {\n    console.log(\"\\nNo hay contactos\\n\");\n    return agenda();\n  }\n  rl.question(\"Indique el nombre del contacto: \", (nombre) => {\n    let contacto = contactos.find((contacto) => contacto.nombre === nombre);\n    if (contacto) {\n      contactos = contactos.filter((contacto) => contacto.nombre !== nombre);\n      console.log(\"\\nContacto eliminado\\n\");\n    } else {\n      console.log(\"\\nContacto no encontrado\\n\");\n    }\n    1;\n    agenda();\n  });\n}\n\nfunction verificacion(numero) {\n  let regex = /^\\d{9}$/;\n  return regex.test(numero);\n}\nagenda();\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/saicobys.js",
    "content": "/* Creación */\n/* Arrays */\n\n// Ejemplo de array de numeros\nconst numeros = [1, 2, 3, 4, 5];\n\n// Ejemplo de array de strings\nconst nombres = [\"Juan\", \"Maria\", \"Pedro\"];\n\n// Ejemplo de array mixto\nconst datos = [1, \"Hola\", true, { nombre: \"Pedro\" }];\n\n/* Operaciones basicas */\n/* Insercion */\n\n// Agregar un numero al final del array \"numeros\"\nnumeros.push(6);\nconsole.log(numeros);\n\n// Agregar un nombre al inicio del array \"nombres\"\nnombres.unshift(\"Ana\");\nconsole.log(nombres);\n\n// Insertar el string \"Hola\" en el indice 2 del array \"datos\"\ndatos.splice(2, 0, \"Hola\");\nconsole.log(datos);\n\n/* Borrar */\n\n// Eliminar el ultimo numero del array \"numeros\" y guardarlo en una variable\nconst numeroEliminado = numeros.pop();\nconsole.log(numeroEliminado);\nconsole.log(numeros);\n\n// Eliminar el primer nombre del array \"nombres\" y guardarlo en una variable\nconst nombreEliminado = nombres.shift();\nconsole.log(nombreEliminado);\nconsole.log(nombres);\n\n// Eliminar dos elementos a partir del indice 2 del array \"datos\"\ndatos.splice(2, 2);\nconsole.log(datos);\n\n/* Actualización */\n\n// Actualizar el nombre de la segunda fruta en el array \"frutas\"\nfrutas[1] = \"Uva\";\nconsole.log(frutas);\n\n/* Ordenación */\n\n// Ordenar alfabeticamente el array \"nombres\"\nnombres.sort();\nconsole.log(nombres);\n\n// Ordenar el array \"productos\" por precio de menor a mayor\nproductos.sort((a, b) => a.precio - b.precio);\nconsole.log(productos);\n\n/* Objects */\n\n// Ejemplo de objeto con propiedades de tipo string\nconst persona = {\n  nombre: \"Juan\",\n  edad: 30,\n  ciudad: \"Madrid\",\n};\n\n// Ejemplo de objeto con propiedades de diferentes tipos\nconst producto = {\n  id: 1,\n  nombre: \"Producto X\",\n  precio: 12.5,\n  disponible: true,\n};\n\n/* Acceso a propiedades */\n\n// Acceder al nombre del usuario en el objeto \"usuario\"\nconst nombreUsuario = usuario.nombre;\nconsole.log;\n\n/* DIFICULTAD EXTRA */\n\nconst contactos = []; // Array para almacenar los contactos\n\nfunction validarTelefono(telefono) {\n  // Validación del número de teléfono (puedes ajustar los criterios)\n  return /^\\d{10}$/.test(telefono); // Ejemplo: 10 dígitos numéricos\n}\n\nwhile (true) {\n  const opcion = prompt(\n    \"Elija una opción:\\n\" +\n      \"1. Agregar contacto\\n\" +\n      \"2. Buscar contacto\\n\" +\n      \"3. Actualizar contacto\\n\" +\n      \"4. Eliminar contacto\\n\" +\n      \"5. Mostrar todos los contactos\\n\" +\n      \"6. Salir\"\n  );\n\n  switch (opcion) {\n    case \"1\":\n      const nombre = prompt(\"Ingrese el nombre del contacto:\");\n      let telefono;\n      do {\n        telefono = prompt(\"Ingrese el número de teléfono (10 dígitos):\");\n      } while (!validarTelefono(telefono));\n      contactos.push({ nombre, telefono });\n      alert(\"Contacto agregado exitosamente!\");\n      break;\n\n    case \"2\":\n      const terminoBusqueda = prompt(\"Ingrese el nombre o teléfono a buscar:\");\n      const resultados = contactos.filter(\n        (c) =>\n          c.nombre.includes(terminoBusqueda) ||\n          c.telefono.includes(terminoBusqueda)\n      );\n      if (resultados.length > 0) {\n        alert(\n          resultados\n            .map((c) => `Nombre: ${c.nombre}, Teléfono: ${c.telefono}`)\n            .join(\"\\n\")\n        );\n      } else {\n        alert(\"No se encontraron contactos.\");\n      }\n      break;\n\n    // ... (Casos 3, 4, 5 para actualizar, eliminar y mostrar todos los contactos)\n\n    case \"6\":\n      alert(\"Saliendo del programa...\");\n      process.exit(0);\n      break;\n\n    default:\n      alert(\"Opción inválida.\");\n  }\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/seandsun.js",
    "content": "// Arrays: son colecciones de datos que tienen un identificador (numérico) y un valor (de cualquier tipo)\n\nlet array1 = new Array() // Forma 1 para declarar un array\nlet array2 = []          // Forma 2 para declarar un array\n\nlet frutas = [\"piña\", \"fresa\", \"mango\",] // Los elementos están numerados partiendo desde el 0\n\nconsole.log(frutas[1]) // Acceder al elemento en la posición 1: fresa\n\nfrutas[2] = \"uva\" // Reemplazar el elemento \"mango\" por \"uva\"\nconsole.log(frutas) // [ 'piña', 'fresa', 'uva' ]\n\nfrutas[3] = \"naranja\" // Agregar un nuevo elemento en la posición 3\nconsole.log(frutas) // [ 'piña', 'fresa', 'uva', 'naranja' ]\n\nconsole.log(frutas.at(-1)) // Obtener el último elemento del array: naranja\n\nfrutas.push(\"manzana\") // Agregar un nuevo elemento al final del array\nconsole.log(frutas) // [ 'piña', 'fresa', 'uva', 'naranja', 'manzana' ]\n\nfrutas.pop() // Eliminar el último elemento del array: manzana\nconsole.log(frutas) // [ 'piña', 'fresa', 'uva', 'naranja' ]\n\nfrutas.shift() // Extraer el primer elemento del array: piña\nconsole.log(frutas) // [ 'fresa', 'uva', 'naranja' ]\n\nfrutas.unshift(\"pera\") // Agregar el elemento al principio del array: pera\nconsole.log(frutas) // [ 'pera', 'fresa', 'uva', 'naranja' ]\n\nfrutas.sort() // Ordenar los elementos, en este caso en orden alfabético\nconsole.log(frutas) // [ 'fresa', 'naranja', 'pera', 'uva' ]\n\n//------------------------------------------------------------------------\n\n// Objeto: son colecciones de datos que tienen una clave y un valor (de cualquier tipo)\n\nlet objeto1 = new Object() // Forma 1 para declarar un objeto\nlet objeto2 = {}          // Forma 2 para declarar un objeto\n\nlet persona = {\n    nombre:\"Marisol\",\n    edad: 24,\n    \"comida favorita\": \"pastas\", // Para obtener este valor se deben utilizar: []\n}\n\nconsole.log(persona.nombre) // Obtener el nombre: Marisol\nconsole.log(persona[\"comida favorita\"]) // Obtener la comida favorita: pastas \n\npersona[\"comida favorita\"] = \"pizza\" // Actualizar su comida favorita de pastas a: pizza\npersona.sabeBailar = false // Insertar si sabe bailar con el valor: false\n\nconsole.log(persona) // { nombre: 'Marisol', edad: 24, 'comida favorita': 'pizza', sabeBailar: false }\n\ndelete persona.edad // Borrar la propiedad: edad: 24\ndelete persona[\"comida favorita\"] // Borrar la propiedad: \"comidad favorita\": \"pizza\"\n\nconsole.log(persona) // { nombre: 'Marisol', sabeBailar: false }"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/septarian.js",
    "content": "// array\nconst arr = [1,2]\nconst arr2 = new Array(0,2,4,5,6)    //OTRA FORMA DE CREAR UN OBJETO\nconst arr3 = [\"erick\", \"fernando\"]\n//actualizar\narr2[0] = \"hola\"\n//agrega elemento al inicio\narr2.unshift(\"manzana\") \n//borra el primer elemento del arr\narr2.shift()    \n//agrega elemento al final \narr2.push(\"adios\")\n//borra el ultimo elemento\narr2.pop()\n//encuentra el indice de un elemento\narr2.indexOf(5)\n//elimina elementos desde el index que le indiques y le dices cuantos elementos quieres eliminar\narr2.splice(2, 2)\nconst nuevoArr = arr2.splice(1,1)   //guardas lo que borraste en otro array\n//copiar array\nconst copiaArray = arr2.slice()\n//muestra los indices de los elementos del array\nconsole.log(Object.keys(arr2))\n//muestra el numero de elemntos que tiene el array\narr2.length\n//crea una nueva instancia de array a partir de un objeto iterable o parecido a un array\nconsole.log(Array.from(\"hola\"))\n//devuelve true si si es array o false si no es \nconsole.log(Array.isArray(arr2))\n//Crea una nueva instancia de Array con un número variable de parámetros, independientemente del número y del tipo de dichos parámetros.\nArray.of()\n//concatena un array con otro\nconst arr4 = arr2.concat(arr)\n//convierte en un string todos los elemntos de un array\narr2.join()\n//devuelve true o false si el array contiene lo que se busca\narr2.includes(6)    //true\n//invierte el orden del array\narr4.reverse()\n//ordena los elementos del array\narr4.sort()\n\n\nconsole.log(arr4)\n\n//objetos\nconst obj = {}\nconst obj2 = new Object()   //OTRA FORMA DE CREAR UN OBJETO\nconst obj3 = {name: \"erick\", age: 23}\n\n//diccionario / matriz\nconst dic = \n[\n    [1,2,3]\n    [4],\n    [5],\n    [6]\n]\nconst dic2 = \n[\n    {id: 1, name: \"erick\"},\n    {id: 2, name: \"johnny\"},\n    {id: 3, name: \"gyro\"}\n]\n\n//clases\nclass Articulo {\n    constructor(title, author){\n        this.title = title\n        this.author = author\n    }\n}\nlet terror = new Articulo(\"cuentos de terror\", \"alan wake\")\nconsole.log(terror.title)\nconsole.log(terror.author)\n\n//set\nconst mySet = new Set()\nmySet.add(1)\nmySet.add(2)\nconsole.log(mySet)\n\n//EXTRA\nfunction agenda(){\n\n    const contactos = [\n        {name: \"erick\", tel: 3321904500},\n        {name: \"johnny\", tel: 3321909000},\n        {name: \"gyro\", tel: 3321908080},\n    ]\n\n    const option = 1\n    const con = \"johnny\"\n\n    console.log(\"1. buscar contacto\")\n    console.log(\"2. agregar contacto\")\n    console.log(\"3. actualizar contacto\")\n    console.log(\"4. eliminar contacto\")\n    console.log(\"5. salir\")\n\n    switch(option){\n        case 1:\n            console.log(\"cual contacto quiere buscar\")\n            let res = contactos.find(contacto => contacto.name === con) //compara que el nombre del contacto y el de la variable con sea el mismo\n            if(res){    //si la variable es true (si encontro algo) ejecuta el codigo, si es false (no encontro coincidencias) hace lo del else\n                console.log(res)\n            } else{\n                console.log(\"el contacto no existe\")\n            }\n        break\n        case 2:\n            console.log(\"registre su contacto, primero el nombre\")\n            let newName = \"funny valentine\"\n            console.log(\"nombre del contacto es: \"+newName)\n            console.log(\"ahora el numero, no puede ser mayor ni menor que 10 numeros\")\n            let newNumber = \"3314111174\"\n            if(newNumber.length == 10){\n                contactos.push({newName, newNumber})\n                console.log(\"numero del contacto es: \"+newNumber)\n                console.log(contactos[3])\n            } else {\n                console.log(\"numero no valido\")\n                return\n            }\n        break\n        case 3:\n            console.log(\"escribe el nombre del contacto que  quieres actualizar\")\n            let act = \"erick\"\n            let newAct = contactos.find(contacto => contacto.name === act)\n            console.log(\"1. actualizar nombre\")\n            console.log(\"2. actualizar numero\")\n\n            let opt = 2\n\n            switch(opt){\n            case 1:\n                console.log(\"escribe el nuevo nombre\")\n                let newNameAct = \"diego\"\n                newAct.name = newNameAct\n                console.log(newAct)\n            break\n            case 2:\n                console.log(\"escribe nuevo numero\")\n                let newNumberAct = \"3311444790\"\n                 if(newNumberAct.length == 10){\n                    newAct.tel = newNumberAct\n                    console.log(newAct)\n            } else {\n                console.log(\"numero no valido\")\n                return\n            }\n            break\n            default:\n                return\n            }\n        break\n        case 4:\n            console.log(\"nombre del contacto quieres borrar\")\n            let del = \"gyro\"\n            let deleted = contactos.findIndex(contacto => contacto.name === del)\n            if (deleted === -1){\n                console.log(\"no existe el contacto\")\n            }else{\n                contactos.splice(deleted, 1)\n                console.log(contactos)\n            }\n        break\n        case 5:\n            console.log(\"hasta luego\")\n            return\n        default:\n            return\n    }\n}\n\nagenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/shevotool.js",
    "content": "//Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n// Arreglo\nconst array = [1, 2, 3, 4, 5];\nconsole.log(array);\n\n// Objeto\nlet persona = {\n  nombre: \"Juan\",\n  apellido: \"Perez\",\n};\n\nconst { nombre, apellido } = persona;\nconsole.log(nombre);\nconsole.log(apellido);\n\n// Set\nlet set = new Set([1, 2, 3, 4, 5]);\nconsole.log(set);\n\n// Map\nlet map = new Map();\nmap.set(\"nombre\", \"juan\");\nmap.set(\"apellido\", \"Perez\");\nconsole.log(map);\n\n// WeakSet\nlet mascota1 = { nombre: \"Max\" };\nlet mascota2 = { nombre: \"Bruno\" };\nlet weakSet = new WeakSet([mascota1, mascota2]);\nconsole.log(weakSet);\n\n// WeakMap\nlet weakMap = new WeakMap();\nlet obj = { id: 1 };\nweakMap.set(obj, \"Valor asociado\");\nconsole.log(weakMap);\n\n// String\nlet cadenaDeTexto = \"Hola JavaScript\";\n\n// Number\nlet vuelto = 2000;\n\n// Boolean\nlet tieneTelefono = true;\n\n// Funcion\nfunction caminar() {\n  console.log(\"caminando\");\n}\ncaminar();\n\n//  * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n\n// Arreglos\nconst tareas = [\"entrenar\", \"trabajar\", \"estudiar\", \"descansar\"];\nconsole.log(tareas);\n\n// Arreglos inserción\ntareas[4] = \"meditar\";\nconsole.log(tareas);\n\nconst leer = \"leer\";\ntareas.push(leer);\n\nconsole.log(tareas);\nconst socializar = \"socializar\";\n\ntareas.unshift(socializar);\nconsole.log(tareas);\n\n// Arreglos borrado\ntareas.shift();\nconsole.log(tareas);\n\ntareas.pop();\nconsole.log(tareas);\n\nlet pos = 1;\nlet elementoEliminado = tareas.splice(pos, 1);\nconsole.log(elementoEliminado);\nconsole.log(tareas);\n\n// Arreglos actualización\ntareas[1] = \"programar\";\nconsole.log(tareas);\n\n// Arreglos ordenación\ntareas.sort();\nconsole.log(tareas);\n\n//  * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n\n// Objetos\nconst automovil = {\n  marca: \"Toyota\",\n  modelo: \"rav4\",\n  tipo: \"SUV\",\n};\n\nconsole.log(automovil);\n\n// Objetos inserción\nautomovil.motor = 2000;\nconsole.log(automovil);\n\n// Objetos borrado\ndelete automovil.motor;\nconsole.log(automovil);\n\n// Objetos actualización\nautomovil.modelo = \"4Runner\";\nconsole.log(automovil);\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\nconst contactos = [\n  { nombre: \"Juan\", telefono: \"12345678\" },\n  { nombre: \"María\", telefono: \"87654321\" },\n  { nombre: \"Lupe\", telefono: \"87654321\" },\n];\n\n//console.log(typeof contactos);\n\nfunction mostrarMenu() {\n  process.stdout.write(\"1. Crear un usuario\\n\");\n  process.stdout.write(\"2. Buscar un usuario\\n\");\n  process.stdout.write(\"3. Actualizar un usuario\\n\");\n  process.stdout.write(\"4. Eliminar un usuario\\n\");\n  process.stdout.write(\"5. Salir\\n\");\n  process.stdout.write(\"Selecciona una opción:\\n\");\n}\n\nmostrarMenu();\n\nprocess.stdin.on(\"data\", function (data) {\n  const exp = data.toString().trim();\n  console.log(exp);\n\n  switch (exp) {\n    // Crear un contacto\n    case \"1\":\n      process.stdout.write(\"Ingresa el nombre del contacto: \\n\");\n      process.stdin.once(\"data\", function (nombreData) {\n        const nuevoNombre = nombreData.toString().trim();\n\n        process.stdout.write(\"Ingresa el número de teléfono: \\n\");\n        process.stdin.once(\"data\", function (telefonoData) {\n          const nuevoTelefono = telefonoData.toString().trim();\n\n          if (\n            !isNaN(nuevoTelefono) &&\n            nuevoTelefono !== \"\" &&\n            nuevoTelefono.length <= 11\n          ) {\n            const nuevoContacto = {\n              nombre: nuevoNombre,\n              telefono: nuevoTelefono,\n            };\n            contactos.push(nuevoContacto);\n            console.log(\n              `Nuevo contacto ${nuevoContacto.nombre} agregado exitósamente.\\n`\n            );\n            console.log(contactos);\n            mostrarMenu();\n          } else {\n            console.log(\n              \"El número de teléfono debe tener 11 dígitos o menos y solo contener números.\"\n            );\n          }\n        });\n      });\n      break;\n    // Buscar un contacto\n    case \"2\":\n      process.stdout.write(\"Ingresa el nombre del contacto a buscar: \");\n      process.stdin.once(\"data\", function (nombreContacto) {\n        const buscarContacto = nombreContacto.toString().trim();\n        const contactoEncontrado = contactos.find(\n          (contacto) => contacto.nombre == buscarContacto\n        );\n        if (contactoEncontrado) {\n          console.log(\"Contacto encontrado\", contactoEncontrado);\n        } else {\n          console.log(\"Contacto no encontrado\");\n        }\n      });\n      break;\n    // Actualizar un contacto\n    case \"3\":\n      process.stdout.write(\n        \"Ingresa el nombre del contacto que deseas actualizar: \"\n      );\n      process.stdin.once(\"data\", function (nombreContacto) {\n        const buscarContacto = nombreContacto.toString().trim();\n        const contactoEncontrado = contactos.find(\n          (contacto) => contacto.nombre == buscarContacto\n        );\n        if (contactoEncontrado) {\n          process.stdout.write(\"Ingresa el nuevo nombre: \");\n          process.stdin.once(\"data\", function (nombreContacto) {\n            const nuevoNombreContacto = nombreContacto.toString().trim();\n            contactoEncontrado.nombre = nuevoNombreContacto;\n            console.log(contactos);\n            process.stdout.write(\"Ingresa el nuevo número de teléfono: \");\n            process.stdin.once(\"data\", function (numeroContacto) {\n              const nuevoNumeroContacto = numeroContacto.toString().trim();\n\n              if (\n                !isNaN(nuevoNumeroContacto) &&\n                nuevoNumeroContacto !== \"\" &&\n                nuevoNumeroContacto.length <= 11\n              ) {\n                contactoEncontrado.telefono = nuevoNumeroContacto;\n                console.log(contactos);\n                mostrarMenu();\n              } else {\n                console.log(\n                  \"El número de teléfono debe tener 11 dígitos o menos y solo contener números.\"\n                );\n              }\n            });\n          });\n        } else {\n          console.log(\"Contacto no encontrado\");\n        }\n      });\n      break;\n    // Eliminar un contacto\n    case \"4\":\n      process.stdout.write(\n        \"Ingresa el nombre del contacto que deseas eliminar: \"\n      );\n      process.stdin.once(\"data\", function (nombreContacto) {\n        const nombreContactoAEliminar = nombreContacto.toString().trim();\n        const indice = contactos.findIndex(\n          (contacto) => contacto.nombre == nombreContactoAEliminar\n        );\n        if (indice !== -1) {\n          contactos.splice(indice, 1);\n          console.log(`Contacto ${nombreContactoAEliminar} eliminado`);\n          console.log(contactos);\n          mostrarMenu();\n        } else {\n          console.log(\"Contacto no encontrado\");\n        }\n      });\n      break;\n    // Salir\n    case \"5\":\n      process.stdout.write(\"Gracias por visitarnos.\\n\");\n      process.exit();\n      break;\n    default:\n      process.stdout.write(\n        \"Opción no válida. Selecciona una opción correcta.\\n\"\n      );\n      mostrarMenu();\n  }\n});\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/sniker1223.js",
    "content": "// Array\nlet fruits = [\"Apple\", \"Banana\"]\nconsole.log(fruits)\nfruits.push(\"Orange\") // Insert\nconsole.log(fruits)\nfruits.pop() // Remove\nconsole.log(fruits)\nconsole.log(fruits[0]) // Get\nfruits[0] = \"Blueberry\" // Update\nconsole.log(fruits)\nfruits.sort() // Sort\nconsole.log(fruits)\nconsole.log(typeof fruits)\n\n// Tuple\nlet my_Tuple = [5, false, 'Coding God was here']\nconsole.log(my_Tuple)\nmy_Tuple.push(\"39\") // Insert\nconsole.log(my_Tuple)\nmy_Tuple.pop() // Remove\nconsole.log(my_Tuple)\nconsole.log(my_Tuple[1]) // Get\nconsole.log(my_Tuple)\nmy_Tuple[1] = true // Update\nconsole.log(my_Tuple)\nmy_Tuple.sort() // Sort\nconsole.log(my_Tuple)\nconsole.log(typeof my_Tuple)\n\n// Sets\nconst my_Set = new Set([\"orange\", \"apple\", \"banana\"])\nconsole.log(my_Set)\nmy_Set.add(\"3\") // Insert\nconsole.log(my_Set)\nmy_Set.delete(\"3\") // Remove\nconsole.log(my_Set)\nconsole.log(my_Set.has(\"orange\")) // Get\nconsole.log(typeof my_Set)\n\n// Dictionary\nlet my_dict = {\n  \"name\": \"Sniker\",\n  \"surname\": \"Dev\",\n  \"age\": \"20\"\n}\nconsole.log(my_dict)\nmy_dict[\"email\"] = \"sniker@gmail.com\"  // Insert\nconsole.log(my_dict)\ndelete my_dict[\"surname\"] // Remove\nconsole.log(my_dict)\nconsole.log(my_dict[\"name\"]) // Get\nmy_dict[\"name\"] = \"Stick\";\nconsole.log(my_dict) // Update\nconsole.log(typeof my_dict)\n\n// Map\nconst my_Map = new Map();\nmy_Map.set('Apples', 500) // Insert\nmy_Map.set('Orange', 100)\nconsole.log(my_Map)\nconsole.log(my_Map.get(\"Apples\")) // Get\nmy_Map.set('Apples', 200) // Update\nconsole.log(my_Map)\nmy_Map.delete(\"Apples\") // Remove\nconsole.log(my_Map)"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/socramwd.js",
    "content": "console.log('/* ESTRUCTURA DE DATOS */')\nconsole.log('/* ----- ***** ----- ***** ----- ***** ----- */')\n\nconsole.log('/* ARRAYS */')\nconst myList = ['Marcos', 'Estefanía', 'Izan', 'Gael', 'Olivia']\nconsole.log(myList)\n\nconsole.log('Añadir elemento al final de la lista')\nmyList.push('Slash')\nconsole.log(myList)\n\nconsole.log('Añadir elemento al principio de la lista')\nmyList.unshift('Mushu')\nconsole.log(myList)\n\nconsole.log('Añadir elemento a ubicación específica de la lista')\nmyList.splice(3, 0, 'Neo') // splice => el primer argumento es la posición, el segundo argumento cuántos elementos quiero borrar (en este caso 0), el tercer argumento lo que inserto\nconsole.log(myList)\n\nconsole.log('Eliminar el último elemento de la lista')\nmyList.pop()\nconsole.log(myList)\n\nconsole.log('Eliminar el primer elemento de la lista')\nmyList.shift()\nconsole.log(myList)\n\nconsole.log('Eliminar elemento elegido en de la lista')\nmyList.splice(2, 1)\nconsole.log(myList)\n\n\nconsole.log('/* ----- ***** ----- ***** ----- ***** ----- */')\n\n\nconsole.log('/* Acceder a un elemento del array */')\nconsole.log(myList[3])\n\nconsole.log('/* Actualizar un elemento del array */')\nmyList[2] = 'Z'\nconsole.log(myList)\n\n\nconsole.log('/* ----- ***** ----- ***** ----- ***** ----- */')\n\n\nconsole.log('/* Ordenar un array */')\nconsole.log(myList.sort())\n\n\nconsole.log('/* ----- ***** ----- ***** ----- ***** ----- */')\n\n\nconsole.log('/* Tuple */') // Son elementos inmutables, en javascript existe esta opción\nconst myTuple = Object.freeze(['Marcos', 'Pérez', '@socramdev', 46])\nconsole.log(myTuple)\n\n\nconsole.log('/* ----- ***** ----- ***** ----- ***** ----- */')\n\n\nconsole.log('/* SETS */')\nconst mySet = new Set()\nconsole.log(typeof(mySet))\n\nconsole.log('/* Añadir al set */')\nmySet.add('Marcos')\nconsole.log(mySet)\nmySet.add('Pérez')\nconsole.log(mySet)\nmySet.add('@socramdev')\nconsole.log(mySet)\nmySet.add(46)\nconsole.log(mySet)\n\nconsole.log('/* Añadir al set un mismo valor */') // Si os datos son iguales, no se duplican\nmySet.add('Marcos')\nconsole.log(mySet)\n\nconsole.log('/* Eliminar del set */')\nmySet.delete('Pérez')\nconsole.log(mySet)\n\n\nconsole.log('/* ----- ***** ----- ***** ----- ***** ----- */')\n\n\nconsole.log('/* OBJETOS / DICCIONARIOS */')\nconst myDict = {\n    'name': 'Marcos',\n    'surname': 'Pérez',\n    'alias': '@socramdev',\n    'age': 46\n}\nconsole.log(myDict)\n\nconsole.log('/* Acceder al diccionario */')\nconsole.log(myDict['name'])\n\nconsole.log('/* Añadir al diccionario */')\nmyDict.email = 'socram@socram.com'\nconsole.log(myDict)\n\nconsole.log('/* Actualizar al diccionario */')\nmyDict.age = 47\nconsole.log(myDict)\n\nconsole.log('/* Eliminar del diccionario */')\ndelete myDict.age\nconsole.log(myDict)\n\n\nconsole.log('/* ----- ***** ----- ***** ----- ***** ----- */')\n\n\nconsole.log('/* DIFICULTAD EXTRA - AGENDA */')\n// Pendiente ya que no se usar aplicaciones en Terminal"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/ssanjua.js",
    "content": "// Operadores aritméticos\nlet suma = 5 + 3;\nlet resta = 5 - 3;\nlet multiplicacion = 5 * 3;\nlet division = 5 / 3;\nlet modulo = 5 % 3;\nlet potencia = 5 ** 3;\nconsole.log('Aritméticos:', suma, resta, multiplicacion, division, modulo, potencia);\n\n// Operadores lógicos\nlet and = true && false;\nlet or = true || false;\nlet not = !true;\nconsole.log('Lógicos:', and, or, not);\n\n// Operadores de comparación\nlet igual = 5 == '5';\nlet estrictamenteIgual = 5 === '5';\nlet diferente = 5 != '5';\nlet mayorQue = 5 > 3;\nlet menorQue = 5 < 3;\nconsole.log('Comparación:', igual, estrictamenteIgual, diferente, mayorQue, menorQue);\n\n// Operadores de asignación\nlet x = 5;\nx += 3; // 8\nx -= 2; // 6\nx *= 2; // 12\nx /= 2; // 6\nx %= 2; // 0\nconsole.log('Asignación:', x);\n\n// Operadores de identidad\nlet identidad = 5 === 5;\nconsole.log('Identidad:', identidad);\n\n// Operadores de pertenencia\nlet array = [1, 2, 3, 4, 5];\nlet pertenece = array.includes(3);\nconsole.log('Pertenencia:', pertenece); // true\nconsole.log('Pertenencia:', array.includes(6)); // false\n\n// Operadores de bits\nlet bitAnd = 5 & 3;\nlet bitOr = 5 | 3;\nlet bitXor = 5 ^ 3;\nlet bitNot = ~5;\nlet bitShiftLeft = 5 << 1;\nlet bitShiftRight = 5 >> 1;\nconsole.log('Bits:', bitAnd, bitOr, bitXor, bitNot, bitShiftLeft, bitShiftRight);\n\n// Estructuras de control condicionales\nif (suma > 5) {\n    console.log('Condicional if: La suma es mayor que 5');\n} else {\n    console.log('Condicional if: La suma no es mayor que 5');\n}\n\n// Estructuras de control iterativas\nfor (let i = 0; i < 5; i++) {\n    console.log('Iterativa for:', i);\n}\n\nlet j = 0;\nwhile (j < 5) {\n    console.log('Iterativa while:', j);\n    j++;\n}\n\n// Estructuras de control excepciones\ntry {\n    throw new Error('Esto es un error');\n} catch (error) {\n    console.log('Excepción:', error.message);\n}\n\n// Switch case\nlet mayor = 18;\nswitch (mayor) {    \n  case 18:\n      console.log('Eres mayor de edad');\n      break;\n  case 21:\n      console.log('Ya puedes beber');\n      break;\n  default:\n      console.log('No eres mayor de edad');\n      break;\n}\n\n// For in\nlet persona = {\n    nombre: 'Juan',\n    edad: 25\n};\n\nfor (let key in persona) {\n    console.log('For in:', key, persona[key]);\n}\n\n// For of\nlet colores = ['rojo', 'verde', 'azul'];\n\nfor (let color of colores) { \n    console.log('For of:', color);\n}\n\n// DIFICULTAD EXTRA\nfor (let i = 10; i <= 55; i++) {\n    if (i % 2 === 0 && i !== 16 && i % 3 !== 0) {\n        console.log('Número:', i);\n    }\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/victor-Casta.js",
    "content": "/*\n  * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n*/\n\n//Array: Coleccion ordenada de elemento\nconst arrayExample = [1, 2, 3, 4, 5];\n\n//Objects: Colecciones de pares clave-valor\nconst objectExample = {\n  name: \"John\",\n  age: 30,\n}\n\n//sets: Estructuras que no permiten valores repetidos\nlet miSet = new Set([1, 2, 3, 4, 5]);\n\n//maps: Estructuras clave-valor que pueden tener cualquier tipo de clave y valor\nlet myMap = new Map();\nmyMap.set(\"key1\", \"value1\");\nmyMap.set({ a: 1, b: 2 }, \"value2\");\n\n//Arrays Typed: permiten almacenar datos de un tipo específico, como enteros o flotantes.\nlet miArrayTyped = new Int32Array([1, 2, 3, 4]);\n\n/*\n   * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n*/\nconst numberList = [1, 2, 3, 4]\n\n//Insertar datos\nnumberList.push(5); //Insertar datos al final de un array\nnumberList.unshift(0); //Insertar datos al principio de un array\n\n\n//Borrar datos\nnumberList.pop(); //Eliminar el ultimo elemento del array\nnumberList.shift(); //Eliminar el primer elemento del array\n\n\n//Actualizacion\nnumberList[1] = 9; //Modificar un dato en una posición\nnumberList.splice(3, 0, 7); // Agrega 4 en la posición 3\n\n\n//Ordenación\nnumberList.sort((a, b) => a - b); // Ordenamiento ascendente\n\nnumberList.reverse(); // Cambia el sentido de los elementos (ascendente a descendente)\nconst { log } = require('console');\n// guardarDato.js\n\nconst readline = require('readline');\n\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout\n});\n\nconst contacts = [];\n\nfunction searchContact(callback) {\n  rl.question('Ingrese el Nombre del contacto: ', (dato) => {\n    let searchedData = contacts.find(objeto => objeto.name === dato);\n    if (searchedData) {\n      console.log(`Nombre: ${searchedData.name} Telefono: ${searchedData.phone}`);\n    } else {\n      console.log('Contacto no encontrado');\n    }\n    if (callback) {\n      callback(searchedData);\n    }\n  });\n}\n\nfunction realizarOperacion() {\n  rl.question('Seleccione un numero: 1.Buscar, 2.Insertar, 3.Actualizar, 4.Borrar, 5.Salir: ', (data) => {\n    const userData = data;\n    switch (userData) {\n      case '1':\n        searchContact(() => {\n          realizarOperacion();\n        });\n        break;\n      case '2':\n        let contactsItem = {};\n        rl.question('nombre: ', (name) => {\n          contactsItem['name'] = name;\n          rl.question('telefono: ', (phone) => {\n            contactsItem['phone'] = phone;\n            if (!isNaN(phone) && phone.length >= 10) {\n              contacts.push(contactsItem);\n              console.log(`Datos Ingresados: ${contactsItem.name} ${contactsItem.phone}`);\n            } else {\n              console.log('Por favor ingrese un telefono de 10 caracteres (Incluya código de verificación)');\n            }\n            realizarOperacion();\n          });\n        });\n        break;\n      case '3':\n        searchContact((searchedData) => {\n          if (searchedData) {\n            rl.question(`Ingrese el nuevo nombre para ${searchedData.name}: `, (newName) => {\n              rl.question(`Ingrese el nuevo teléfono para ${searchedData.name}: `, (newPhone) => {\n                searchedData.name = newName;\n                searchedData.phone = newPhone;\n                console.log(`Contacto actualizado: ${searchedData.name} ${searchedData.phone}`);\n                realizarOperacion();\n              });\n            });\n          } else {\n            realizarOperacion();\n          }\n        });\n        break;\n      case '4':\n        if (contacts.length > 0) {\n          rl.question('Ingrese el nombre del contacto que desea eliminar: ', (contactDelete) => {\n            let position = contacts.findIndex(objeto => objeto.name === contactDelete)\n            if (position !== -1) {\n              contacts.splice(position, 1);\n              console.log(`Se ha eliminado al contacto: ${contactDelete}`);\n            } else {\n              console.log(\"No se encontró a este usuario\");\n            }\n            realizarOperacion();  \n          });\n        } else {\n          console.log(\"No hay contactos registrados\");\n          realizarOperacion(); \n        }\n        break;\n      case '5':\n        console.log('Saliendo del programa');\n        rl.close();\n        break;\n      default:\n        console.log(`Ups! No se ha seleccionado correctamente`);\n        realizarOperacion();\n    }\n  });\n}\n\n// Iniciar el programa\nrealizarOperacion();\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/vsUnix0.js",
    "content": "//Estructuras de datos para JavaScript:\r\n\r\n// 1. Array\r\nconsole.log(\"-----------------------array------------------------\");\r\nlet myArray = [\"Manzana\", \"Pera\", \"Banano\", \"Sandía\"];\r\n\r\nfor (let a = 0; a < myArray.length; a++) {\r\n  console.log(myArray[a]);\r\n} // Esto es para recorrerlo pero se puede utilizar foreach:\r\n\r\nconsole.log(\"----------------------foreach-----------------------\");\r\n\r\nmyArray.forEach((e, i, a) => {\r\n  console.log(i, e);\r\n});\r\n\r\nconsole.log(\"---------------Operaciones habituales---------------\");\r\n//Añadir un elemento al final del array:\r\nlet addLastFruit = myArray.push(\"Zapote\");\r\nconsole.log(addLastFruit);\r\n\r\n//Eliminar el ultimo elemento de un array\r\nlet deleteLastFruit = myArray.pop();\r\nconsole.log(deleteLastFruit);\r\n\r\n//Añadir un elemento al principio de un array:\r\nlet addFirstFruid = myArray.unshift(\"Fresa\");\r\nconsole.log(addFirstFruid);\r\n\r\n//Eliminar el primer elemento de un array:\r\nlet deleteFirstFruit = myArray.shift();\r\nconsole.log(deleteFirstFruit);\r\n\r\n//Encontrar el índice de un array:\r\nlet pos = myArray.indexOf(2);\r\nconsole.log(pos);\r\n\r\n//eliminar cualquier elemento del array:\r\nlet deleteElement = myArray.splice(2);\r\nconsole.log(deleteElement);\r\n\r\n//2. Objeto\r\nconsole.log(\"---------------------objetos------------------------\");\r\n\r\nlet perro = {\r\n  nombre: \"dodis\",\r\n  edad: \"9\",\r\n  raza: \"pug\",\r\n};\r\n\r\nconsole.log(JSON.stringify(perro, null, 3));\r\n\r\nconsole.log(\r\n  \"---------------------función constructora para crear objetos------------------------\",\r\n);\r\n\r\nfunction Car(make, model, year) {\r\n  this.make = make;\r\n  this.model = model;\r\n  this.year = year;\r\n} //para crear un constructor de un objeto\r\n\r\nlet myCar = new Car(\"Ford\", \"Mustang\", \"2025\"); // crear nuevos vehículos\r\nconsole.log(JSON.stringify(myCar, null, 3)); // Mostrarlos de manera organizada\r\n\r\nconsole.log(\r\n  \"-----------------------clase en vez de función constructora----------------------\",\r\n);\r\n//lo mejor es crearlo con class\r\nclass Lamp {\r\n  constructor(color, forma, marca) {\r\n    this.color = color;\r\n    this.forma = forma;\r\n    this.marca = marca;\r\n  }\r\n}\r\n\r\nlet lamp1 = new Lamp(\"Amarillo\", \"Redonda\", \"Pajarito\");\r\nconsole.log(JSON.stringify(lamp1, null, 3));\r\n\r\nconsole.log(\r\n  \"------------------------enumeración de objetos------------------------\",\r\n);\r\nlet i = 1;\r\nfor (const prop in myCar) {\r\n  console.log(i, myCar[prop]);\r\n  i++;\r\n} // para enumerarlos\r\n\r\n//3. Set\r\nconsole.log(\"------------------conjuntos o sets------------------\");\r\n\r\nlet conjunto = new Set();\r\n\r\nconjunto.add(2);\r\nconjunto.add(\"mesa\");\r\nconjunto.add(\"libro\");\r\nconjunto.add(\"reloj\");\r\nconjunto.delete(2);\r\nconsole.log(conjunto.has(\"lampara\")); //Se usa para saber si contiene un valor\r\n\r\nconsole.log(conjunto);\r\n\r\n// Para recorrer un set se utiliza for of:\r\nlet o = 0;\r\n\r\nfor (const prop of conjunto) {\r\n  console.log(o, prop);\r\n  o++; /*a diferencia de un array con set no se puede hacer destructing, \r\n  así que el contador es manual pero por lo general no hay necesidad de \r\n  enumerarlo*/\r\n}\r\n\r\n//4. Map\r\nconsole.log(\"--------------------maps----------------------------\");\r\n\r\nlet mapa = new Map();\r\n\r\nmapa.set(\"nombre\", \"Martín\");\r\nmapa.set(\"apellido\", \"Melo\");\r\nmapa.set(\"edad\", 20);\r\nmapa.set(\"comida preferida\", \"Hamburguesa\");\r\nmapa.set(\"Dónde ha viajado\", [\r\n  \"Cali\",\r\n  \"Barranquilla\",\r\n  \"Buenaventura\",\r\n  \"Medellín\",\r\n]);\r\n\r\nconsole.log(mapa);\r\nconsole.log(mapa.get(\"Dónde ha viajado\"));\r\n\r\nconsole.log(\"---------------Desafío extra------------------------\");\r\n\r\nlet contacts = [\r\n  {name: \"Martín Melo\", cel: \"3045369321\"},\r\n  {name: \"Sofía Gonzalez\", cel: \"3224326901\"}\r\n];\r\n\r\n\r\nfunction cleanText(text) {\r\n  return text.toString().trim().toLowerCase();\r\n}\r\n\r\nfunction agenda() {\r\n  process.stdout.write(\r\n    `\r\n    1. Buscar contacto.\\n\r\n    2. Añadir contacto.\\n\r\n    3. Salir.\\n\\n\r\n    Selecciona una opción\\n> `\r\n  )\r\n  process.stdin.once(\"data\", (data) => {\r\n    let valor = cleanText(data);\r\n    switch (valor) {\r\n      case \"1\":\r\n        searchContact();\r\n        break;\r\n      case \"2\":\r\n        addContact();\r\n        break;\r\n      case \"3\":\r\n        process.stdout.write(\"Saliendo...\")\r\n        setTimeout(()=>{\r\n          process.exit();\r\n        }, 2000)\r\n        break;\r\n      default:\r\n        process.stdout.write(\"Por favor selecciona la opción correcta\\n> \");\r\n        agenda();\r\n        break;\r\n    }\r\n  })\r\n}\r\n\r\nfunction searchContact() {\r\n  process.stdout.write(\"Introduce el nombre de contacto: \")\r\n  process.stdin.once(\"data\", (data) => {\r\n    valor = cleanText(data);\r\n    let encontrado = false;\r\n    for (const prop of contacts) {\r\n      let name = prop.name;\r\n      let formatName = name\r\n        .toString()\r\n        .trim()\r\n        .toLowerCase()\r\n        .normalize(\"NFD\")\r\n        .replace(/[\\u0300-\\u036f]/g,\"\");\r\n      if (formatName.includes(valor)){\r\n        process.stdout.write(`El número de teléfono de ${prop.name} es ${prop.cel}\\n`);\r\n        encontrado = true;\r\n        process.stdout.write(\"1. Eliminar contacto.\\n2. Actualizar contacto.\\n3. Regresar al menú\\n>\")\r\n        process.stdin.once(\"data\", (inputData) => {\r\n          valor1 = cleanText(inputData)\r\n          switch (valor1) {\r\n            case \"1\":\r\n              const index = contacts.indexOf(prop)\r\n              if (index !== -1){\r\n                contacts.splice(index, 1)\r\n                process.stdout.write(\"Usuario eliminado\\n\")\r\n              }\r\n              agenda();\r\n              break;\r\n            case \"2\":\r\n              process.stdout.write(\"Escribe el número de teléfono para actualizar el contacto: \")\r\n              process.stdin.once(\"data\", (updateHandler)=> {\r\n                let valor2 = cleanText(updateHandler);\r\n                prop.cel = valor2;\r\n                agenda();\r\n              });\r\n              break;\r\n            case \"3\":\r\n              process.stdout.write(\"Regresando...\");\r\n              setTimeout(()=>{\r\n                agenda();\r\n              }, 2000)\r\n          }\r\n        })\r\n      }\r\n    }\r\n    if (!encontrado) {\r\n      process.stdout.write(\"No encontrado, deseas agregar uno nuevo? responde si o no: \");\r\n      process.stdin.once(\"data\", (data) => {\r\n        valor = cleanText(data)\r\n        switch (valor) {\r\n          case \"si\":\r\n            addContact();\r\n            break;\r\n          case \"no\":\r\n            searchContact();\r\n            break;\r\n        }\r\n      })\r\n    }\r\n  })\r\n}\r\n\r\nfunction addContact() {\r\n  let temp = {};\r\n  let counter = 0;\r\n\r\n  function handleInput(data) {\r\n  let valor = cleanText(data);\r\n    switch (counter) {\r\n      case 0:\r\n        if (/^[a-zA-ZáéíóúÁÉÍÓÚñÑ\\s'-]+$/.test(valor)) {\r\n          counter = 1;\r\n          temp.name = valor\r\n          process.stdout.write(\"Por favor ingresa el número de teléfono: \")\r\n        } else {\r\n          process.stdout.write(\"Ingresa solo el nombre sin números o caracteres especiales: \")\r\n        }\r\n        break;\r\n      case 1:\r\n        if (/^\\d{7,11}$/.test(valor)) {\r\n          temp.cel = valor;\r\n          contacts.push({...temp});\r\n          temp = {};\r\n          counter = 0;\r\n          process.stdout.write(\"Agregado satisfactoriamente.\\n\")\r\n          process.stdin.off(\"data\", handleInput);\r\n          agenda();\r\n        } else {\r\n          process.stdout.write(\"Debes agregar un número válido: \")\r\n        }\r\n        break;\r\n    }\r\n  }\r\n\r\n  process.stdout.write(\"Por favor ingresa el nombre: \");\r\n  process.stdin.on(\"data\", handleInput)\r\n}\r\n\r\n\r\nagenda()\r\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/wapastorv.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en Javascript.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n */\n \n/* Array:\n    Los arrays permiten almacenar listas ordenas de elementos y permite insertar, borrar, actualizar y ordenar los valores\n    conozca más en: https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array\n*/\n    // Sintaxis de creación de un array vacío\n        const arrayVacio = [];\n        console.log(arrayVacio);\n        // Sintaxis de creación de un array con elementos\n        const array = [1, 2, 3, 4, 5];\n        console.log(array);\n        // sintaxis de creación de un array con el constructor Array\n        let frutas = Array('Manzana', 'Banana', 'Naranja'); \n        console.log(frutas);\n        // Creacion de array mixto\n        let mixto = [1, 'Manzana', true, 3.14];\n        console.log(mixto);// [1, 'Manzana', true, 3.14]\n\n    // Operaciones de inserción\n        // Insertar al final\n        array.push(6);\n        console.log(array);\n        \n        // Insertar al principio\n        array.unshift(0);\n        console.log(array);\n        \n        // Insertar en una posición específica\n        array.splice(3, 0, 2.5);// Inserta 2.5 en la posición 3 del array, el 0 indica que no se eliminará ningún elemento \n        console.log(array);\n        \n        // Insertar varios elementos\n        array.splice(3, 0, 2.1, 2.2, 2.3, 2.4);// Inserta varios elementos en la posición 3 del array\n        console.log(array);// [0, 1, 2, 2.1, 2.2, 2.3, 2.4, 2.5, 3, 4, 5, 6]\n        \n        // Insertar un array en otro array\n        array.splice(3, 0, [2.1, 2.2, 2.3, 2.4]);// Inserta un array en la posición 3 del array\n        console.log(array);// [0, 1, 2, [2.1, 2.2, 2.3, 2.4], 2.1, 2.2, 2.3, 2.4, 2.5, 3, 4, 5, 6]  \n        \n        // Insertar un array en otro array con spread operator\n        let array2 = [2.1, 2.2, 2.3, 2.4];\n        array.splice(3, 0, ...array2);// Inserta un array en la posición 3 del array\n        console.log(array);// [0, 1, 2, 2.1, 2.2, 2.3, 2.4, 2.1, 2.2, 2.3, 2.4, 2.5, 3, 4, 5, 6]\n        \n        // Insertar un array en otro array con concat\n        //array = array.concat([7, 8, 9]);//Inserta un array al final del array\n        console.log(array);// [0, 1, 2, 2.1, 2.2, 2.3, 2.4, 2.1, 2.2, 2.3, 2.4, 2.5, 3, 4, 5, 6, 7, 8, 9]\n        \n    // Operaciones de borrado\n        \n        // Borrar al final\n        array.pop();// Elimina el último elemento del array\n        console.log(array);// [0, 1, 2, 2.1, 2.2, 2.3, 2.4, 2.1, 2.2, 2.3, 2.4, 2.5, 3, 4, 5, 6, 7, 8]\n\n        // Borrar al principio\n        array.shift();// Elimina el primer elemento del array\n        console.log(array);// [1, 2, 2.1, 2.2, 2.3, 2.4, 2.1, 2.2, 2.3, 2.4, 2.5, 3, 4, 5, 6, 7, 8] \n\n        // Borrar en una posición específica\n        array.splice(3, 1);// Elimina un elemento en la posición 3 del array\n        console.log(array);// [1, 2, 2.1, 2.3, 2.4, 2.1, 2.2, 2.3, 2.4, 2.5, 3, 4, 5, 6, 7, 8]\n\n        // Borrar varios elementos\n        array.splice(3, 4);// Elimina varios elementos en la posición 3 del array, el 4 indica que se eliminarán 4 elementos\n        console.log(array);// [1, 2, 2.1, 2.1, 2.2, 2.3, 2.4, 2.5, 3, 4, 5, 6, 7, 8]\n\n        // Borra un rango de elementos\n        array.splice(3, 3, 2.3, 2.4, 2.5);// Elimina 3 elementos en la posición 3 del array y añade 3 nuevos elementos en la misma posición\n        console.log(array);// [1, 2, 2.1, 2.3, 2.4, 2.5, 2.5, 3, 4, 5, 6, 7, 8]\n\n        // Borrar un rango de elementos con slice\n        array = array.slice(3, 6);// Elimina los elementos desde la posición 3 hasta la 6\n        console.log(array);// [2.3, 2.4, 2.5]\n\n    // Operaciones de actualización\n\n        // Actualizar un elemento\n        array[0] = 1;\n        console.log(array);// [1, 2.4, 2.5]\n\n        // Actualizar varios elementos\n        array.splice(1, 2, 2.1, 2.2, 2.3);// Actualiza varios elementos en la posición 1 del array, el 2 indica que se actualizarán 2 elementos y se añaden 3 nuevos elementos\n        console.log(array);// [1, 2.1, 2.2, 2.3]\n\n    // Operaciones de ordenación\n\n        // Ordenar un array\n        frutas.sort();// Ordena los elementos del array en orden alfabético\n        console.log(frutas);// ['Banana', 'Manzana', 'Naranja']\n\n        // Ordenar un array de números\n        let numeros = [1, 5, 3, 2, 4];\n        numeros.sort((a, b) => a - b);// Ordena los elementos del array en orden ascendente\n        console.log(numeros);// [1, 2, 3, 4, 5]\n        numeros.sort();// Ordena los elementos del array en orden descendente\n        console.log(numeros);// [5, 4, 3, 2, 1]\n\n        // Ordenar un array de objetos\n        let personas = [\n            {nombre: 'Juan', edad: 25},\n            {nombre: 'Ana', edad: 20},\n            {nombre: 'Pedro', edad: 30}\n        ];\n        personas.sort((a, b) => a.edad - b.edad);// Ordena los elementos del array en orden ascendente según la edad\n        console.log(personas);// [{nombre: 'Ana', edad: 20}, {nombre: 'Juan', edad: 25}, {nombre: 'Pedro', edad: 30}]\n        personas.sort((a, b) => a.nombre.localeCompare(b.nombre));// Ordena los elementos del array en orden alfabético según el nombre, localeCompare compara cadenas de texto teniendo en cuenta el orden alfabético\n        console.log(personas);// [{nombre: 'Ana', edad: 20}, {nombre: 'Juan', edad: 25}, {nombre: 'Pedro', edad: 30}]   \n\n/* Object:\n        Los objetos permiten almacenar colecciones de pares clave-valor y permite insertar, borrar y actualizar los valores\n        conozca más en: https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Object\n\n*/\n        //sintaxis de creación de un objeto vacío\n        const objetoVacio = {};\n        console.log(objetoVacio);// {}\n\n        //sintaxis de creación de un objeto con propiedades\n        const objetoPersona = {\n            nombre: 'Juan',\n            edad: 25,\n            casado: false\n        };\n        console.log(objetoPersona);// {nombre: 'Juan', edad: 25, casado: false}\n\n        // Operaciones con la clave\n            // Insertar una propiedad\n            objetoPersona.apellido = 'Pérez';\n            console.log(objetoPersona);// {nombre: 'Juan', edad: 25, casado: false, apellido: 'Pérez'}\n\n            // Borrar una propiedad\n            delete objetoPersona.casado;\n            console.log(objetoPersona);// {nombre: 'Juan', edad: 25, apellido: 'Pérez'}\n\n            // Actualizar una propiedad\n            objetoPersona.nombre = 'Pedro';\n            console.log(objetoPersona);// {nombre: 'Pedro', edad: 25, apellido: 'Pérez'}\n            // Ordenar un propiedades de un objeto\n            const ordered = {};\n            Object.keys(objetoPersona).sort().forEach(function(key) {\n                ordered[key] = objetoPersona[key];\n            });\n            console.log(ordered);// {apellido: 'Pérez', edad: 25, nombre: 'Pedro'}\n\n\n        // Operaciones con el valor\n            // Insertar un valor\n            objetoPersona.edad = 30;\n            console.log(objetoPersona);// {nombre: 'Pedro', edad: 30, apellido: 'Pérez'}\n\n            // Borrar un valor\n            objetoPersona.edad = undefined;\n            console.log(objetoPersona);// {nombre: 'Pedro', edad: undefined, apellido: 'Pérez'}\n\n            // Actualizar un valor\n            objetoPersona.edad = 35;\n            console.log(objetoPersona);// {nombre: 'Pedro', edad: 35, apellido: 'Pérez'}\n\n\n\n/* Set:\n        Los sets permiten almacenar colecciones de valores únicos y permite insertar, borrar y actualizar los valores\n        conozca más en: https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Set\n*/\n\n    // Sintaxis de creación de un set vacío\n        const setVacio = new Set();\n        console.log(setVacio);// Set {}\n\n    // Sintaxis de creación de un set con elementos\n        const set = new Set([1, 2, 3, 4, 5]);\n        console.log(set);// Set {1, 2, 3, 4, 5}\n    \n    // Operaciones de inserción\n        set.add(6);\n        console.log(set);// Set {1, 2, 3, 4, 5, 6}\n        set.add(6);// No se puede añadir un valor duplicado, el set solo permite valores únicos\n        console.log(set);// Set {1, 2, 3, 4, 5, 6}\n        set.add(7);\n        console.log(set);// Set {1, 2, 3, 4, 5, 6, 7}\n        set.add(8);\n        console.log(set);// Set {1, 2, 3, 4, 5, 6, 7, 8}\n    \n    // Operaciones de borrado\n        set.delete(8);\n        console.log(set);// Set {1, 2, 3, 4, 5, 6, 7}\n        set.clear();\n        console.log(set);// Set {}\n    \n    // Operaciones de actualización\n        set.add(1);\n        set.add(2);\n        set.add(3);\n        set.add(4);\n        set.add(5);\n        set.add(6);\n        set.add(7);\n        console.log(set);// Set {1, 2, 3, 4, 5, 6, 7}\n        set.add(8);\n        console.log(set);// Set {1, 2, 3, 4, 5, 6, 7, 8}\n        set.add(9);\n        console.log(set);// Set {1, 2, 3, 4, 5, 6, 7, 8, 9}\n        set.add(13);\n        set.add(11);\n        set.add(10);\n        set.add(12);\n        console.log(set);// Set {1, 2, 3, 4, 5, 6, 7, 8, 9, 13, 11, 10, 12}\n\n    // Operaciones de ordenación\n    let setOrdenado = new Set([...set].sort((a, b) => a - b));\n    console.log(setOrdenado);// Set {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}\n\n/* Map:\n    Los maps permiten almacenar colecciones de pares clave-valor, donde las claves pueden ser de cualquier tipo.\n    Mantienen el orden de inserción de los elementos.\n*/\n\n    // Sintaxis de creación de un map vacío\n        const mapVacio = new Map();\n        console.log(mapVacio);// Map {}\n\n    // Sintaxis de creación de un map con elementos\n        const map = new Map([\n            ['nombre', 'Juan'],\n            ['edad', 25],\n            ['casado', false]\n        ]);\n        console.log(map);// Map {'nombre' => 'Juan', 'edad' => 25, 'casado' => false}   \n\n    // Operaciones de inserción\n        map.set('apellido', 'Pérez');// Inserta un nuevo par clave-valor\n        console.log(map);// Map {'nombre' => 'Juan', 'edad' => 25, 'casado' => false, 'apellido' => 'Pérez'}\n    \n    // Operaciones de borrado\n        map.delete('casado');// Elimina un par clave-valor\n        console.log(map);// Map {'nombre' => 'Juan', 'edad' => 25, 'apellido' => 'Pérez'}\n        map.clear();// Elimina todos los pares clave-valor\n        console.log(map);// Map {}\n    \n    // Operaciones de actualización\n        map.set('nombre', 'Pedro');// Actualiza un valor\n        console.log(map);// Map {'nombre' => 'Pedro'}\n        map.set('edad', 30);// Actualiza un valor\n        map.set('apellido', 'Pérez');// Inserta un nuevo par clave-valor\n        console.log(map);// Map {'nombre' => 'Pedro', 'edad' => 30, 'apellido' => 'Pérez'}\n    \n    // Operaciones de ordenación\n        let mapOrdenado = new Map([...map].sort((a, b) => a[0] - b[0]));\n        console.log(mapOrdenado);// Map {'apellido' => 'Pérez', 'edad' => 30, 'nombre' => 'Pedro'}\n\n/* Pilas (stack):\n    las pilas permiten almacenar colecciones de elementos siguiendo el principio LIFO (Last In, First Out), \n    lo que significa que el último elemnto en entrar es el primero en salir.\n    Se puede implementar una pila con un array.\n    conozca más en: https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array\n*/\n        // Sintaxis de creación de una pila\n        let pila = [];\n        console.log(pila);// [] pila vacía\n\n        //Operaciones de inserción\n        pila.push(1);// Inserta un elemento en la pila\n        pila.push(2);// Inserta un elemento en la pila\n        pila.push(3);// Inserta un elemento en la pila\n        console.log(pila);// [1, 2, 3]\n\n        //Operaciones de borrado\n        pila.pop();// Elimina el último elemento de la pila\n        console.log(pila);// [1, 2]\n\n        //Operaciones de actualización\n        pila[pila.length - 1] = 4;// Actualiza el último elemento de la pila\n        console.log(pila);// [1, 4]\n\n\n/* Cola:\n    Las colas permiten almacenar colecciones de elementos siguiendo el principio FIFO (First In, First Out).\n    Se puede implementar una cola con un array.\n    conozca más en: https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array\n\n*/\n\n    // Sintaxis de creación de una cola\n        let cola = [];\n        console.log(cola);// [] cola vacía\n    \n    // Operaciones de inserción\n        cola.push(1);// Inserta un elemento en la cola\n        cola.push(2);// Inserta un elemento en la cola\n        cola.push(3);// Inserta un elemento en la cola\n        console.log(cola);// [1, 2, 3]\n\n    // Operaciones de borrado\n        cola.shift();// Elimina el primer elemento de la cola\n        console.log(cola);// [2, 3]\n\n    // Operaciones de actualización \n        cola[0] = 4;// Actualiza el primer elemento de la cola\n        console.log(cola);// [4, 3]\n\n\n/* Ejemplo de uso de estructuras de datos en Javascript */\n\n/* Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\nconst readline = require('readline');// Importa el módulo readline para leer la entrada por terminal\nconst rl = readline.createInterface({// Crea una interfaz de lectura\n    input: process.stdin,// Establece la entrada por defecto\n    output: process.stdout// Establece la salida por defecto\n});\n\nlet agenda = new Map();// Crea un mapa para almacenar los contactos\n\nfunction buscarContacto(nombre) {\n    if (agenda.has(nombre)) {\n        console.log(`Nombre: ${nombre}, Teléfono: ${agenda.get(nombre)}`);\n    } else {\n        console.log('Contacto no encontrado');\n    }\n}\n\nfunction insertarContacto(nombre, telefono) {\n    agenda.set(nombre, telefono);\n    console.log('Contacto insertado');\n}\n\nfunction actualizarContacto(nombre, telefono) {\n    if (agenda.has(nombre)) {\n        agenda.set(nombre, telefono);\n        console.log('Contacto actualizado');\n    } else {\n        console.log('Contacto no encontrado');\n    }\n}   \n\nfunction eliminarContacto(nombre) {\n    if (agenda.has(nombre)) {\n        agenda.delete(nombre);\n        console.log('Contacto eliminado');\n    } else {\n        console.log('Contacto no encontrado');\n    }\n}\n\nfunction mostrarMenu() {\n    console.log('1. Buscar contacto');\n    console.log('2. Insertar contacto');\n    console.log('3. Actualizar contacto');\n    console.log('4. Eliminar contacto');\n    console.log('5. Salir');\n}\n\nfunction leerOpcion() {\n    rl.question('Introduce una opción: ', (opcion) => {\n        switch (opcion) {\n            case '1':\n                rl.question('Introduce el nombre del contacto: ', (nombre) => {\n                    buscarContacto(nombre);\n                    mostrarMenu();\n                    leerOpcion();\n                });\n                break;\n            case '2':\n                rl.question('Introduce el nombre del contacto: ', (nombre) => {\n                    rl.question('Introduce el teléfono del contacto: ', (telefono) => {\n                        insertarContacto(nombre, telefono);\n                        mostrarMenu();\n                        leerOpcion();\n                    });\n                });\n                break;\n            case '3':\n                rl.question('Introduce el nombre del contacto: ', (nombre) => {\n                    rl.question('Introduce el teléfono del contacto: ', (telefono) => {\n                        actualizarContacto(nombre, telefono);\n                        mostrarMenu();\n                        leerOpcion();\n                    });\n                });\n                break;\n            case '4':\n                rl.question('Introduce el nombre del contacto: ', (nombre) => {\n                    eliminarContacto(nombre);\n                    mostrarMenu();\n                    leerOpcion();\n                });\n                break;\n            case '5':\n                rl.close();\n                break;\n            default:\n                console.log('Opción no válida');\n                mostrarMenu();\n                leerOpcion();\n        }\n    });\n}\n\nmostrarMenu();\nleerOpcion();\n\nrl.on('close', () => {  \n    console.log('Adiós');\n    process.exit(0);\n});\n// Para ejecutar el programa, copia y pega el código en un archivo con extensión .js y ejecútalo con Node.js\n// node nombreArchivo.js\n// Sigue las instrucciones por terminal para interactuar con el programa\n\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/xmunder.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\n// Array\nlet array = [1, \"Hola\", [1, \"Azul\"], 4, true];\nconsole.log(array);\nconsole.log(array[2][0]);\n\n// Object\nlet object = {\n  name: \"Cristian\",\n  surname: \"Gómez\",\n  age: 21,\n};\nconsole.log(object);\n\n// Map\nvar map = new Map();\nmap.set(\"name\", \"Cristian\");\nmap.set(\"surname\", \"Gómez\");\nmap.set(\"age\", 21);\nconsole.log(map);\n\n// Set\nvar set = new Set();\nset.add(1);\nset.add(2);\nconsole.log(set);\n\n// Utiliza operaciones de inserción, borrado, actualización y ordenación.\n\n// Inserción\narray.push(\"Adiós\");\nconsole.log(array);\n\nobject[\"city\"] = \"Neiva\";\nconsole.log(object);\n\nmap.set(\"city\", \"Neiva\");\nconsole.log(map);\n\nset.add(3);\nconsole.log(set);\n\n// Borrado\narray.pop();\nconsole.log(array);\n\ndelete object.city;\nconsole.log(object);\n\nmap.delete(\"city\");\nconsole.log(map);\n\nset.delete(3);\nconsole.log(set);\n\n// Actualización\narray[0] = 2;\nconsole.log(array);\n\nobject.name = \"Cristian\";\nconsole.log(object);\n\nmap.set(\"name\", \"Cristian\");\nconsole.log(map);\n\n// Ordenación\narray.sort();\nconsole.log(array);\n\n// Dificultad extra\n\nclass contacto {\n  constructor(nombre, numero) {\n    this.nombre = nombre;\n    this.numero = numero;\n  }\n}\nagenda = [];\n\nsalir = false;\n\nwhile (salir === false) {\n  console.log(\"Menu de opciones\");\n  console.log(\"1. Buscar contacto\");\n  console.log(\"2. Insertar contacto\");\n  console.log(\"3. Actualizar contacto\");\n  console.log(\"4. Eliminar contacto\");\n  console.log(\"5. Salir\");\n\n  let opción = Number(prompt(\"Ingrese el número de la opción deseada:\"));\n  let nombre = null;\n  let numero = null;\n\n  switch (opción) {\n    case 1:\n      if (agenda.length === 0) {\n        console.log(\"No hay contactos en la agenda.\");\n        break;\n      }\n      nombre = prompt(\"Ingrese el nombre del contacto:\");\n      for (let i = 0; i < agenda.length; i++) {\n        if (agenda[i].nombre === nombre) {\n          console.log(\n            \"Nombre: \" + agenda[i].nombre,\n            \"Número: \" + agenda[i].numero\n          );\n        } else {\n          console.log(\"El contacto no existe en la agenda.\");\n        }\n      }\n      break;\n    case 2:\n      nombre = prompt(\"Ingrese el nombre del contacto:\");\n      for (let i = 0; i < agenda.length; i++) {\n        while (agenda[i].nombre === nombre) {\n          console.log(\n            \"El contacto ya existe en la agenda, ingrese otro nombre.\"\n          );\n          nombre = prompt(\"Ingrese el nombre del contacto:\");\n        }\n      }\n      numero = prompt(\"Ingrese el número del contacto:\");\n      verificarNumero(numero);\n      agenda.push(new contacto(nombre, numero));\n      break;\n    case 3:\n      if (agenda.length === 0) {\n        console.log(\"No hay contactos en la agenda.\");\n        break;\n      }\n      mostrarContactos();\n      let nombreContacto = prompt(\n        \"Ingrese el nombre del contacto que desea actualizar:\"\n      );\n      for (let i = 0; i < agenda.length; i++) {\n        if (agenda[i].nombre === nombreContacto) {\n          nombre = prompt(\"Ingrese el nuevo nombre del contacto:\");\n          numero = prompt(\"Ingrese el nuevo número del contacto:\");\n          verificarNumero(numero);\n          agenda[i].nombre = nombre;\n          agenda[i].numero = numero;\n        }\n      }\n      mostrarContactos();\n      break;\n    case 4:\n      if (agenda.length === 0) {\n        console.log(\"No hay contactos en la agenda.\");\n        break;\n      }\n      mostrarContactos();\n      let nombreContactoEliminar = prompt(\"Ingrese el nombre del contacto:\");\n      for (let i = 0; i < agenda.length; i++) {\n        if (agenda[i].nombre === nombreContactoEliminar) {\n          agenda.splice(i, 1);\n        }\n      }\n      mostrarContactos();\n      break;\n    case 5:\n      salir = true;\n      break;\n  }\n  function mostrarContactos() {\n    for (let i = 0; i < agenda.length; i++) {\n      console.log(\"Nombre: \" + agenda[i].nombre, \"Número: \" + agenda[i].numero);\n    }\n  }\n  function verificarNumero(numero) {\n    while (isNaN(numero) || numero.length <= 10) {\n      console.log(\"El número ingresado no es válido.\");\n      numero = prompt(\"Ingrese el número del contacto:\");\n    }\n  }\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/yesidL12.js",
    "content": "// <------ Objetos --------->\n\nlet objetoLiteral = {}; // Objeto literal vacio\n\nlet user = {\n    email: 'yesid@gmail.com',\n    name: 'Yesid',\n    dirección: {\n        calle: 'Queen st',\n        número: 13,\n    },\n    activo: true,\n    recuperarClave: function () {\n        console.log('Recuperando clave');\n    }\n}\n\n/** No podemos cambiar las propiedades, pero si podemos agregarlo o quitarle propiedades a los objetos y arrays */\n\nconst user1 = {id:1};\n\nuser1.name = 'Yesid'; // Agraga la propiedad name\nuser1.guardar = function () { //Agrega la propiedad guardar\n    console.log('Guardando', user1.name);\n}\n\nuser1.guardar();\n\ndelete user.name; // Elimina la propiedad name\ndelete user1.guardar; // Elimina la propiedad guardar\nconsole.log(user1);\n\n\nconst user2 = Object.freeze({id:1}); // Este método hace que no se pueda modificar\n\nconst user3 = Object.seal({id:1}); // ESte método permite cambiarle los valores a las propiedades eistentes, pero no permite quitarle ni agregarle propiedades.\n\n\n// Factory function\n\n//===> Nos permite crear objetos de una manera sencila y no repetitiva\n\nfunction crearUsuario (name,email) {\n    return {\n        email,\n        name,\n        activo: true,\n        recuperarClave: function() {\n            console.log('Recuperando clave...');\n        }\n    }\n}\n\nlet user4 = crearUsuario('Nicolas', 'nico@gmail.com');\nlet user5 = crearUsuario('felipe', 'felipe@gmail.com');\nconsole.log(user4, user5);\n\n//<--------- array ---------->\n\nconst letras = ['a', 'b'];\n\n// Es posible modificar el contenido de un array, hay 3 métodos.\n\n//Para agregar elementos\n\nletras.push('c'); //Permite agregar elementos al final de un array.\n\nletras.unshift('y', 'y'); // Permite agregar elementos al inicio de un array.\n\nletras.splice(3,0,1,2); // Permite agregar elementos en una posición especifica. El primer dato corresponde al indice donde vamos a comenzar, el segundo a cuantos elementos queremos eliminar, los ultimos dos datos corresponden a los elementos que queremos agregar.\n\n// Para eleminar elementos\n\nconst letras1 = ['a', 'b','c','d'];\n\n//Para eliminar el ultimo elemento\nconst final = letras1.pop();\nconsole.log(final,letras1);\n\n//Para eliminar el primer elemento\nconst comienzo = letras1.shift(); // Nos devuelve el elemento que estamos eliminando.\nconsole.log(comienzo,letras1);\n\n// Para eliminar los elementos entre medio\nconst entremedio = letras1.splice(1,1); // El primer elemento hace referencia a el indice desde el cual se empezará a borrar, y el segundo, cuantos elementos se van a borrar.\nconsole.log(entremedio,letras1);\n\n// Para ordenar\n\nlet numeros = [15, 10. -3];\n\nnumeros.sort(); // Ordena los array de menor a mayor\nnumeros.reverse(); //Lo que hace es revertir el orden del arreglo.\n\nconsole.log(numeros);\n\nlet letras2 = ['z', 'a','d'];\nletras2.sort();\nconsole.log(letras);\n\nlet conMayusculas = ['Z', 'a','d'];\nletras.sort((a,b) => {\n    /**\n     * a antes b => -1\n     * b antes a => 1\n     * si son iguales => 0\n     */\n    let alower = a.toLocaleLowerCase();\n    let blower = b.toLocaleLowerCase();\n\n    if (alower < blower) {\n        return -1;\n    }\n\n    if (alower > blower) {\n        return 1;\n    }\n    return 0;\n});\nconsole.log(letras2);\n\n// Map\nconst usuarios = [\n    {edad:17, nombre: 'Nico'},\n    {edad:13, nombre: 'Chanchito'},\n    {edad:25, nombre: 'Feliz'},\n    {edad:32, nombre: 'Fernanda'},\n];\n\nconst lista = usuarios.map(usuarios => `<li>${usuarios.nombre}<li>`);\nconst html = `<ol>${lista.join('')}<ol>`;\n\nconsole.log(html);\n\nconst mapped = usuarios.map(usuarios => {\n    return {\n        ...usuarios,\n        mayor: usuarios.edad > 17,\n    }\n})\n\nconsole.log(mapped);"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/julia/santiago-munoz-garcia.jl",
    "content": "# Estructuras de datos en Julia\n\n# Array\narray = [1, 2, 3, 4, 5]  # Definición\nprintln(\"Array: \", array)\npush!(array, 6)  # Inserción\nprintln(\"Array después de insertar 6: \", array)\npop!(array)      # Borrado\nprintln(\"Array después de borrar el último elemento: \", array)\narray[2] = 10  # Actualización\nprintln(\"Array después de actualizar el valor en la posición 2: \", array)\nsort!(array)     # Ordenación\nprintln(\"Array ordenado: \", array)\n\n# Diccionario (Dict)\ndiccionario = Dict(\"uno\" => 1, \"dos\" => 2, \"tres\" => 3) # Definición\nprintln(\"\\nDiccionario: \", diccionario)\ndiccionario[\"cuatro\"] = 4  # Inserción\nprintln(\"Diccionario después de insertar 'cuatro': \", diccionario)\ndiccionario[\"tres\"] = 30  # Actualización\nprintln(\"Diccionario después de actualizar el valor de 'tres': \", diccionario)\ndelete!(diccionario, \"dos\")  # Borrado\nprintln(\"Diccionario después de borrar 'dos': \", diccionario)\n\n# Conjunto (Set)\nconjunto = Set([1, 2, 3])  # Definición\nprintln(\"\\nConjunto : \", conjunto)\npush!(conjunto, 4)  # Inserción\nprintln(\"Conjunto después de insertar 4: \", conjunto)\ndelete!(conjunto, 2)  # Borrado\nprintln(\"Conjunto después de borrar 2: \", conjunto)\n\n# Tupla (Tuple)\ntupla = (\"A\", \"B\", \"C\")\nprintln(\"\\nTupla: \", tupla)\n\n# Inserción (no es posible, pero se puede crear una nueva tupla)\nnueva_tupla = (tupla..., \"D\")  \nprintln(\"NUEVA tupla después de 'insertar' 'D': \", nueva_tupla)\n\n# Borrado (no es posible, pero se puede crear una nueva tupla sin un elemento)\ntupla_sin_B = filter(x -> x != \"B\", tupla)  \nprintln(\"NUEVA tupla después de 'borrar' 'B': \", tupla_sin_B)\n\n# Actualización (no es posible, pero se puede crear una nueva tupla con un elemento modificado)\ntupla_actualizada = (\"A\", \"X\", \"C\")  \nprintln(\"NUEVA tupla después de 'actualizar' 'B' a 'X': \", tupla_actualizada)\n\n\n# Rango (Range)\nrango = 1:10  # Definición un rango del 1 al 10\nprintln(\"\\nRango: \", rango)\n\n# Convertir de rango a array\narray_desde_rango = collect(rango)\nprintln(\"Rango convertido a arreglo: \", array_desde_rango)\n\n# Iterando sobre el rango\nprintln(\"Iterando sobre el rango:\")\nfor i in rango\n    print(\"$i \")\nend\nprintln()\n\n# Estructura (Struct)\nstruct Contacto\n    nombre::String\n    telefono::String\nend\n# Las estructuras (structs) son inmutables por defecto\n\n# Agenda de contactos\nagenda = Contacto[]\n\nfunction validar_telefono(telefono::String)::Bool\n    # Verifica que la longitud sea menor o igual a LONGITUD_MAXIMA_TLF\n    LONGITUD_MAXIMA_TLF::Int = 11\n    if length(telefono) > LONGITUD_MAXIMA_TLF\n        return false\n    end\n    # Verifica que todos los caracteres sean dígitos\n    for char in telefono\n        if !(char >= '0' && char <= '9') \n            return false  # Si hay un carácter no numérico, retorna false\n        end\n    end\n    return true \nend\n\n# Función para agregar un contacto\nfunction agregar_contacto(nombre::String, telefono::String)\n    if validar_telefono(telefono)\n        push!(agenda, Contacto(nombre, telefono))\n        println(\"Contacto agregado:\\nNombre: $nombre     Teléfono: $telefono\")\n    else\n        println(\"Número de teléfono inválido. Contacto NO agregado.\")\n    end\nend\n\n# Función para buscar un contacto\nfunction buscar_contacto(nombre::String)\n    for contacto in agenda\n        if contacto.nombre == nombre\n            println(\"Contacto encontrado:\\n Nombre: $(contacto.nombre)      Teléfono: $(contacto.telefono)\")\n            return\n        end\n    end\n    println(\"Contacto no encontrado.\")\nend\n\n# Función para actualizar un contacto\nfunction actualizar_contacto(nombre::String, nuevo_telefono::String)\n    for i in eachindex(agenda)\n        if agenda[i].nombre == nombre\n            if validar_telefono(nuevo_telefono)\n                agenda[i] = Contacto(nombre, nuevo_telefono)\n                println(\"Contacto actualizado:\\nNombre: $nombre     Teléfono: $nuevo_telefono\")\n                return\n            else\n                println(\"Número de teléfono inválido.\")\n                return\n            end\n        end\n    end\n    println(\"Contacto no encontrado.\")\nend\n\n# Función para eliminar un contacto\nfunction eliminar_contacto(nombre::String)\n    for i in eachindex(agenda)\n        if agenda[i].nombre == nombre\n            deleteat!(agenda, i)\n            println(\"Contacto eliminado: $nombre\")\n            return\n        end\n    end\n    println(\"Contacto no encontrado.\")\nend\n\n# Función para mostrar todos los contactos\nfunction mostrar_contactos()\n    if isempty(agenda)\n        println(\"Agenda vacía.\")\n    else\n        println(\"\\n--- Lista de Contactos ---\")\n        for contacto in agenda\n            println(\"Nombre: $(contacto.nombre)     Teléfono: $(contacto.telefono)\")\n        end\n    end\nend\n\n# Menú principal\nfunction menu()\n    while true\n        println(\"\\n--- Agenda de Contactos ---\")\n        println(\"1. Agregar contacto\")\n        println(\"2. Buscar contacto\")\n        println(\"3. Actualizar contacto\")\n        println(\"4. Eliminar contacto\")\n        println(\"5. Mostrar contactos\")\n        println(\"6. Salir\")\n        print(\"Seleccione una opción: \")\n        opcion = readline()\n\n        if opcion == \"1\"\n            print(\"Ingrese el nombre: \")\n            nombre = readline()\n            print(\"Ingrese el número de teléfono: \")\n            telefono = readline()\n            agregar_contacto(nombre, telefono)\n        elseif opcion == \"2\"\n            print(\"Ingrese el nombre del contacto a buscar: \")\n            nombre = readline()\n            buscar_contacto(nombre)\n        elseif opcion == \"3\"\n            print(\"Ingrese el nombre del contacto a actualizar: \")\n            nombre = readline()\n            print(\"Ingrese el nuevo número de teléfono: \")\n            nuevo_telefono = readline()\n            actualizar_contacto(nombre, nuevo_telefono)\n        elseif opcion == \"4\"\n            print(\"Ingrese el nombre del contacto a eliminar: \")\n            nombre = readline()\n            eliminar_contacto(nombre)\n        elseif opcion == \"5\"\n            mostrar_contactos() \n        elseif opcion == \"6\"\n            println(\"Saliendo de la agenda .....\")\n            break # Finalización del bucle while\n        else\n            println(\"Opción no válida. Intente de nuevo.\")\n        end\n    end\nend\n\n# Ejecuta el menú\nmenu()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/kotlin/AnCarlu.kt",
    "content": "import java.lang.System.exit\n\n/**\n * Estructuras soportadas en kotlin\n */\n\nfun estructuras() {\n//Listas\n    val mutableList = mutableListOf(1, 2, 3, 4, 5)\n    println(\"Las listas son colecciones que permiten duplicar elementos $mutableList\")\n    //Inserción\n    mutableList.add(7)\n    println(\"Despues de añadir la lista muestra los siguientes numeros $mutableList\")\n    //Borrado\n    mutableList.remove(5)\n    println(\"Despues de borrar la lista muestra los siguientes numeros $mutableList\")\n    //Actualización\n    mutableList[2] = 8\n    println(\"Actualización del tercer dato de la lista $mutableList\")\n    //Ordenacion\n    mutableList.sort()\n    println(\"Ordenacion de la lista $mutableList\")\n//Set\n    val mutableSet = mutableSetOf(1, 4, 3)\n    println(\"\\nSet son colecciones que no permiten elementos duplicados $mutableSet\")\n    //Insercion\n    mutableSet.add(5)\n    println(\"Despues de añadir a SET $mutableSet\")\n    //Borrado\n    mutableSet.remove(2)\n    println(\"Despues de borrar en SET $mutableSet\")\n    //No se pueden actualizar directamente, pero se puede convertir en una lista ordenada\n    val sorterList = mutableSet.toList().sorted()\n    println(\"SET no se puede ordenar directamente, \\npero se puede convertir en una lista ordenada $sorterList \")\n//Map\n    val mutableMap = mutableMapOf(1 to \"uno\", 2 to \"dos\", 3 to \"tres\")\n    println(\"\\nLos mapas son colecciones de pares clave-valor $mutableMap\")\n    //Insercion\n    mutableMap[4] = \"cuatro\"\n    println(\"Despues de insertar $mutableMap\")\n    //Borrado\n    mutableMap.remove(2)\n    println(\"Despues de borrar $mutableMap \")\n    //Actualizacion\n    mutableMap[3] = \"tres Actualizado\"\n    println(\"Actualización del map en la 3ª posicion\")\n    val sorterMap = mutableMap.toList().sortedBy { it.first }\n    println(\n        \"MAP tampoco se puede actualizar directamente,\" +\n                \"\\npero al igual que SET se pueden convertir en una lista ordenada $sorterMap\"\n    )\n//Array\n    val array = arrayOf(1, 2, 3)\n    println(\"Un array en Kotlin es una estructura de tamaño fijo ${array.joinToString()}\")\n    println(\"No es posible ni añadir ni borrar, pero se puede actualizar\")\n    //Actualizacion\n    array[0] = 4\n    print(array.joinToString())\n    //Ordenacion\n    val sortedArray = array.sortedArray()\n    println(\"\\nAl igual que las anteriores, debemos convertirlo en una lista ordenada\")\n    println(sortedArray.joinToString())\n}\n\n//Data class para representar los contactos\ndata class Contacto(var nombre: String, var telefono: String)\n\n//Clase para realizar las acciones\nclass Agenda {\n    private val contacto = mutableListOf<Contacto>()\n\n    fun removeContact(name: String) {\n        contacto.removeIf {\n            it.nombre == name\n        }\n    }\n\n    fun updateContact(name:String, newName: String, newPhone:String) {\n        val contac = searchContact(name)\n        if (contac != null) {\n            if(newPhone.matches(Regex(\"[0-9]{1,11}\"))) {\n                contac.nombre=newName\n                contac.telefono = newPhone\n            }else{\n                println(\"El numero de telefono no es valido\")\n            }\n        }\n    }\n\n    fun searchContact(name: String): Contacto? {\n        return contacto.find {\n            it.nombre == name\n        }\n    }\n\n    fun addContact(name: String, number: String) {\n        if(number.matches(Regex(\"[0-9]{1,11}\"))){\n            contacto.add(Contacto(name, number))\n        }else{\n            println(\"El numero de telefono no es valido\")\n        }\n\n    }\n\n    fun list() {\n        contacto.forEach {\n            println(it)\n        }\n    }\n\n}\n\nfun main() {\n    estructuras()\n\n    val agenda = Agenda()\n    while (true) {\n        println(\"-------AGENDA-----\")\n        println(\"Selecciona una opcion\")\n        println(\"1. Añadir contacto\")\n        println(\"2. Buscar contactos\")\n        println(\"3. Actualizar contactos\")\n        println(\"4. Eliminar contactos\")\n        println(\"5. Lista de contactos\")\n        println(\"0. Salir\")\n\n        when (readLine()) {\n            \"1\" -> {\n                println(\"Nuevo nombre de contacto:\")\n                val name = readln()\n                println(\"Numero de telefono\")\n                val phone = readln()\n                agenda.addContact(name, phone)\n            }\n\n            \"2\" -> {\n                println(\"Nombre del contacto a buscar\")\n                val name = readln()\n                val contact = agenda.searchContact(name)\n                if (contact == null) {\n                    println(\"No se ha encontrado ningun contacto con ese nombre\")\n                } else {\n                    println(\"Contacto encontrado : \\n$contact\")\n                }\n            }\n\n            \"3\" -> {\n                println(\"Inserte el nombre del contacto que desea actualizar\")\n                val name= readln()\n                val contact=agenda.searchContact(name)\n                if (contact == null) {\n                    println(\"No se ha encontrado ningun contacto con ese nombre\")\n                } else {\n                    println(\"Nuevo nombre de contacto\")\n                    val newName= readln()\n                    println(\"Nuevo numero de telefono\")\n                    val newPhone= readln()\n                    agenda.updateContact(name,newName,newPhone)\n                    println(\"El contacto se ha actualizado correctamente \\n$contact\")\n                }\n            }\n            \"4\" -> {\n                println(\"Introduzca el nombre del contacto a borrar:\")\n                val name = readln()\n                agenda.removeContact(name)\n                println(\"El contacto se ha borrado correctamente\")\n            }\n\n            \"5\" -> {\n                println(\"----LISTA DE CONTACTOS----\")\n                agenda.list()\n            }\n\n            \"0\" -> {\n                println(\"Hasta la proxima!!!\")\n                exit(0)\n            }\n            else -> println(\"No es una opcion valida\\n\")\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/kotlin/Luis-VB.kt",
    "content": "import com.sun.jdi.IntegerType\n\n//*\n//* EJERCICIO:\n//* - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n//* - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n//*\n//* DIFICULTAD EXTRA (opcional):\n//* Crea una agenda de contactos por terminal.\n//* - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n//* - Cada contacto debe tener un nombre y un número de teléfono.\n//* - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n//*   los datos necesarios para llevarla a cabo.\n//* - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n//*   (o el número de dígitos que quieras)\n//* - También se debe proponer una operación de finalización del programa.\n//*/\n\n// List\nfun myDataStructures () {\n    //# List\n    var myList = listOf<String>(\"Ahoj\",\"Ja jsem\",\"dobre\",\"aitjak\")\n    println(myList)\n    println(\"Number of elements: ${myList.size}\")   // Number of elements\n    println(\"Third word of my list is ${myList.get(2)}\")       // Access element at index 2\n    println(\"Index of element \\\"Ja jsem\\\" ${myList.indexOf(\"Ja jsem\")}\")    // Index of element \"Ja jsem\"\n    println(\"Is \\\"Ja jsem\\\" in the list? ${myList.contains(\"Ahoj\")}\")    // Check if \"Ahoj\" is in the list\n    println(\"Is the list empty? ${myList.isEmpty()}\")    // Check if the list is empty\n    println(myList.sortedBy { it })         // Sort the list alphabetically\n    println()\n\n    //# List editable\n    var myEditList = mutableListOf<Int>(1,2,3,4)\n    println(myEditList)\n    myEditList.add(5)                // Insert 5\n    println(myEditList)\n    myEditList.removeAt(2)      // Remove element at index 2\n    println(myEditList)\n    println(myEditList[0])                   // Access element at index 0\n    println(myEditList)\n    myEditList[0] = 10              // Update element at index 0\n    println(myEditList)\n    myEditList.shuffle()            // Shuffle the list\n    println(myEditList)\n    println()\n\n    //# Set\n    var mySet = setOf<Int> (78,15,46,11,23,1)           // Set\n    println(mySet)\n    println(mySet.sorted())                     // Sort the set\n    println()\n    //# Set editable\n    var myEditSet = mutableSetOf<Any> (1,\"Hola\", 3, \"mystringhere\")\n    println(myEditSet)\n    myEditSet.add(345)                  // Insert 345\n    println(myEditSet)\n    myEditSet.add(\"OH lala\")           // Insert \"OH la la\"\n    println(myEditSet)\n    myEditSet.remove(1)         // Remove 1\n    println(myEditSet)\n    println(myEditSet.contains(3))     // Check if 3 is in the set\n    println(myEditSet.isEmpty())       // Check if the set is empty\n\n\n    //# Maps\n    val users = listOf(\n        mapOf(\"name\" to \"Luis\", \"Surname\" to \"Barrera\", \"Alias\" to \"Tunnetopper\", \"Age\" to 41),\n        mapOf(\"name\" to \"Paco\", \"Surname\" to \"Alcaraz\", \"Alias\" to \"Chopito\", \"Age\" to 24),\n        mapOf(\"name\" to \"Marta\", \"Surname\" to \"Garcia\", \"Alias\" to \"MvA\", \"Age\" to 37),\n        mapOf(\"name\" to \"Lucia\", \"Surname\" to \"Areso\", \"Alias\" to \"Lucha\", \"Age\" to 21),\n        mapOf(\"name\" to \"Javier\", \"Surname\" to \"Onesa\", \"Alias\" to \"Javi\", \"Age\" to 31)\n    )\n    //    Lambda expression to print the name and age of each user\n    users.forEach { user ->\n        println(\"Name: ${user[\"name\"]}, Age: ${user[\"Age\"]}\")\n    }\n    //    Lambda expression to print the name and age of each user over 30\n    users.filter { (it[\"Age\"] as Int) > 30 }\n        .forEach { user ->\n            println(\"Name: ${user[\"name\"]}, Age: ${user[\"Age\"]}\")\n        }\n\n}\n\nfun main () {\n\n    myDataStructures()\n}"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/kotlin/OcandoDev.kt",
    "content": "val contactsMap: MutableMap<String, Int> = mutableMapOf()\n\nfun addContact() {\n    print(\"Name of contact: \")\n    val name = readln() ?: \"\"\n\n    if(contactsMap.containsKey(name)){\n        println()\n        println(\"Contact already exists. Please choose a different name.\")\n        return\n    }\n\n    println()\n\n    print(\"Number of contact: \")\n    val numberString = readln().trim() ?: \"\"\n\n    if (!numberString.matches(Regex(\"^\\\\d+$\")) && numberString.length !in 1..10) {\n        println()\n        println(\"Invalid number format! Please enter a numeric string 1 to 11 digits long.\")\n        return\n    }\n\n    val phoneNumber = numberString.toInt()\n\n    contactsMap[name] = phoneNumber\n    println(\"Contact added successfully!\")\n}\n\nfun updateContact(){\n    print(\"Enter the name of the contact you want to update: \")\n    val oldName = readln()\n\n    if(!contactsMap.containsKey(oldName)){\n        println()\n        println(\"Contact not found.\")\n        return\n    }\n\n    println()\n\n    print(\"Insert the new name: \")\n    val newName = readln() ?: \"\"\n\n    if(contactsMap.containsKey(newName)){\n        println()\n        println(\"Contact of $newName already exists. Please choose a different name.\")\n        return\n    }\n\n    println()\n\n    print(\"Insert the new phone number: \")\n    val newNumber = readln().trim() ?: \"\"\n\n    if (!newNumber.matches(Regex(\"^\\\\d+$\")) && newNumber.length !in 1..10) {\n        println()\n        println(\"Invalid number format! Please enter a numeric string 1 to 11 digits long.\")\n        return\n    }\n    val newPhoneNumber = newNumber.toInt()\n\n    println()\n\n    contactsMap.remove(oldName)\n    contactsMap[newName] = newPhoneNumber\n    println(\"The contact has been updated.\")\n}\n\nfun removeContact(){\n    print(\"Which contact do you want to delete?: \")\n    val deletionName = readln() ?: \"\"\n\n    println()\n\n    if(deletionName !in contactsMap){\n        println()\n        println(\"Contact not found.\")\n        return\n    } else {\n        contactsMap.remove(deletionName)\n        println()\n        println(\"The contact has been deleted.\")\n    }\n}\n\nfun searchContact(){\n    print(\"Insert name of contact you are looking for: \")\n    val search = readln() ?: \"\"\n    if(search !in contactsMap){\n        println()\n        println(\"Contact not found.\")\n        return\n    } else {\n        println()\n        println(\"Contact information: $search ${contactsMap[search]}\")\n    }\n}\n\n\nfun main(){\n    //Listas\n    val list = mutableListOf(1, 5, 3, 2, 4)\n\n    //Insercion\n    list.add(6) //Adicion\n    list.add(1, 0) //Adicion en posicion especifica\n\n    //Borrado\n    list.remove(3)\n    list.removeAt(2)\n\n    //Actualizacion\n    list[0] = 10\n\n    //Ordenacion\n    list.sort()\n    list.sortWith(Comparator {a, b -> b - a})\n\n    println(list)\n\n    //Mapas\n    val map = mutableMapOf(\"a\" to 1, \"b\" to 2, \"c\" to 3)\n\n    //Insercion\n    map[\"d\"] = 4\n\n    //Borrado\n    map.remove(\"b\")\n\n    //Actualizacion\n    map[\"a\"] = 10\n\n    // Convertir a lista y ordenar\n    val ordenedList = map.entries.sortedBy { it.key }.map { it.value }\n    println(ordenedList)\n\n    //Conjuntos\n    val mSet = mutableSetOf(1, 2, 3, 4)\n\n    //Insercion\n    mSet.add(5)\n\n    //Borrado\n    mSet.remove(2)\n\n    //Actualizacion\n    mSet.remove(3)\n    mSet.add(30)\n\n    //Convertir a lista y ordenar\n    val ordenedList2 = mSet.toList().sorted()\n\n    println(ordenedList2)\n\n    //Clases con datos\n    data class Person(val name: String, var age: Int)\n\n    var person1 = Person(\"Moure\", 32)\n    var person2 = Person(\"Fernando\", 30)\n\n    // Inserción\n    var person3 = Person(\"Alejandro\", 20)\n\n    // Actualización\n    person1.age = 33\n\n    // Ordenación\n    val personList = listOf(person1, person2, person3).sortedBy { it.age }\n\n    println(personList)\n\n    println()\n\n    //Ejercicio\n\n    println(\"Ejecicio\")\n\n    var closeApp = false\n\n    do {\n        println()\n\n        println(\n            \"Welcome to your console contacts app! \\n\\n\" +\n                    \"1. Add contact\\n\" +\n                    \"2. Update contact information\\n\" +\n                    \"3. Remove contact\\n\" +\n                    \"4. Search contact\\n\" +\n                    \"5. Close app\"\n        )\n\n        println()\n\n        val choice = readln()\n\n        when (choice) {\n            \"1\" -> addContact()\n            \"2\" -> updateContact()\n            \"3\" -> removeContact()\n            \"4\" -> searchContact()\n            \"5\" -> closeApp = true\n            else -> println(\"Invalid choice. Please try again.\")\n        }\n    } while (!closeApp)\n}"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/kotlin/VincentRodriguezR.kt",
    "content": "class principal {\n\n    fun dataTypes(){\n\n        //Punto #1 -> Explorar estructuras de datos en el lenguaje\n\n        //Arrays\n        var arreglo1: Array<Int> = arrayOf(1, 2, 3, 4)\n        var arreglo2 = arrayOf(1, 2, 3, 4)\n        var matriz = arrayOf(\n            intArrayOf(1,2,3),\n            intArrayOf(4,5,6),\n            intArrayOf(7,8,9)\n        )\n\n        //Operaciones con Arrays\n\n        //Iterar Array directamente\n        for(i in arreglo1){\n            println(\"Esta linea se ejecutara por cada elemento que tenga el array\")\n        }\n\n        //Tamaño del Array\n        val tamanio = arreglo1.size\n\n        //Busqueda de elementos en el array\n        val contiene = 9 in arreglo1\n        println(contiene)\n\n        //Copiar Array\n        val arregloCopia = arreglo1.copyOf()\n\n        //Ordenar Array\n        val arregloOrdenado = arreglo1.sort()\n\n        //FIltro de elementos que cumplen una condiciion\n        val arregloFiltro = arreglo1.filter {it > 2}\n\n        //Acceder por indice\n        val primerElemento = arreglo1[0] //Los arrays en Kotlin inician desde la posicion 0\n\n        //Modificar elementos por indice\n        arreglo1[1] = 9\n\n        //Colecciones de datos\n        val coleccion1: Set<Int> = setOf(1, 2, 3)\n        val coleccion2 = setOf(1, 2, 3)\n        val coleccionMutable: MutableSet<Int> = mutableSetOf(1, 2, 3)\n        val coleccionMutable2 = mutableSetOf(1,2,3)\n\n        //Operaciones con Set\n\n        //Adicion de elementos\n        coleccionMutable.add(4)\n\n        //Eliminar un elemnto\n        coleccionMutable.remove(4) //El 4 simboliza el valor, no la posicion del elemento\n\n        //Eliminar todos los elementos\n        coleccionMutable.clear()\n\n        //Listas\n        val lista1: List<Int> = listOf(1, 2, 3)\n        val lista2 = listOf(1, 2, 3)\n        val listaMutable: MutableList<Int> = mutableListOf(1, 2, 3)\n        val listaMutable2 = mutableListOf(1, 2, 3)\n\n        //Operaciones con Listas\n\n        //Agregar elementos\n        listaMutable.add(1, 10) //Primero se coloca la posicion donde se agregara el nuevo valor, luego el valor a agregar\n\n        //Eliminar posicion\n        listaMutable.remove(3) //Elimina el item con el valor indicado, en este caso 3\n        listaMutable.removeAt(0) //Elimina el item basado en la posicion en este caso la posicion fue 0 se eliminara el numero 1\n\n        //Modificar elemento\n        listaMutable[0] = 1\n\n        //Mapas o Diccionarios de datos\n        val mapa1: Map<Int, String> = mapOf( //El primer tipo de dato definido corresponde a la clave y el segundo al valor\n            1 to \"Primero\",\n            2 to \"Segundo\",\n            3 to \"tercero\"\n        )\n\n        val mapa2: Map<Any, Any> = mapOf( //Al usar Any dejamos que el lenguaje infiera el tipo de dato\n            1 to \"Primero\",\n            2 to \"Segundo\",\n            3 to \"tercero\"\n        )\n\n        val mapa3 = mapOf(\n            1 to \"Primero\",\n            2 to \"Segundo\",\n            3 to \"tercero\"\n        )\n\n        val mapaMutable: MutableMap<Int, String> = mutableMapOf(\n            1 to \"Primero\",\n            2 to \"Segundo\",\n            3 to \"tercero\"\n        )\n\n        val mapaMutable2 = mutableMapOf(\n            1 to \"Primero\",\n            2 to \"Segundo\",\n            3 to \"tercero\"\n        )\n\n        //Operaciones con mapas\n\n        //Agregar o actualizar\n        mapaMutable[4] = \"cuarto\" //En este caso la clave no existe entonces se agrega la clave 4 y se le asigna el valor cuarto\n        mapaMutable[1] = \"Primerisimo\" //En este caso como la clave ya existia se le asigna un nuevo valor osea a la clave 1 se le asigna primerisimo\n        mapaMutable.put(5, \"quinto\") //Una alternativa para crear items en el mapa\n\n        //Eliminar un registro (clave, valor)\n        mapaMutable.remove(5) //para eliminar se referencia la clave y se eliminara tanto la clave como el valor\n\n        //Obtener el valor de una clave\n        val valor = mapaMutable[4]\n\n        //iterar de forma rapida el elemento unicamente para funciones de lectura\n        mapaMutable.forEach{ (clave, value) -> //El forEach tambien funciona para listas\n            println(value)\n        }\n    }\n\n    //Punto Extra, programa para la gestion de agenda\n\n    val menu: Map<Int, String> = mapOf(\n        1 to \"Agregar contacto\",\n        2 to \"Buscar contacto\",\n        3 to \"Mostrar todos los contactos\",\n        4 to \"Actualziar contacto\",\n        5 to \"Eliminar contacto\",\n        6 to \"Cerrar programa\",\n    )\n    val menuAux: Map<Int, String> = mapOf(\n        1 to \"Volver a ejecutar accion\",\n        2 to \"Volver al menu principal\"\n    )\n    var selection: String? = \"0\"\n    var selectionAux: String? = \"\"\n    var agenda: MutableMap<Int, List<String?>> = mutableMapOf()\n    var index: Int = 1\n\n    companion object {\n        @JvmStatic\n        fun main(args: Array<String>) {\n            val programa = principal()\n            programa.main()\n        }\n    }\n\n    fun main() {\n        println(\"Bienvenido al gestor de agenda!!!\")\n        showMenu()\n    }\n\n    fun showMenu() {\n        menu.forEach { (id, value) ->\n            println(\"$id. $value\")\n        }\n        println(\"Digite el numero de la accion que desea realizar\")\n        selection = readLine()\n        switch()\n    }\n\n    fun addContact() {\n        println(\"Escriba el nombre del contacto\")\n        var name = readLine()\n        println(\"Escriba el numro del contacto\")\n        var number = readLine()\n        while (number!!.toIntOrNull() == null || number.length > 11) {\n            println(\"Ha ingresado un numero incorrecto o muy largo, intente de nuevo, el largo maximo son 11 digitos\")\n            number = readLine()\n        }\n        val contact: List<String?> = listOf(number, name)\n        agenda?.put(index, contact)\n        index++\n        showMenuAux()\n    }\n\n    fun lookup() {\n        println(\"Digite el nombre o el numero de la persona que desea buscar\")\n        val value = readLine()\n        val filter = agenda.mapValues { (id, list) ->\n            list.filter { it == value }\n        }\n        val toShow = filter.values.flatten()\n        println(\"Se ha encontrado el siguiente contacto: $toShow\")\n        showMenuAux()\n    }\n\n    fun showAll() {\n        println(\"A continuacion, se mostraran todos los contactos en su agenda\")\n        agenda.forEach { (id, value)->\n            println(\"$id. $value\")\n        }\n        if(selection!!.toInt() !== 4 && selection!!.toInt() !== 5){\n            showMenuAux()\n        }\n    }\n\n    fun updateContact() {\n        showAll()\n        println(\"Digite la opcion del contacto que desea editar\")\n        val edit = readLine()\n        println(\"Digite el nuevo nombre\")\n        val name = readLine()\n        println(\"Digite el nuevo numero\")\n        val number = readLine()\n        val list = listOf(number, name)\n        agenda[edit!!.toInt()] = list\n        println(\"Se ha actualizado el contacto de forma exitosa!\")\n        showMenuAux()\n    }\n\n    fun deleteContact() {\n        showAll()\n        println(\"Digite la opcion del contacto que desea eliminar\")\n        val delete = readLine()\n        agenda.remove(delete!!.toInt())\n        println(\"Se ha eliminado el contacto de forma exitosa!\")\n        showMenuAux()\n    }\n\n    fun switch() {\n        when (selection!!.toInt()) {\n            1 -> addContact()\n            2 -> lookup()\n            3 -> showAll()\n            4 -> updateContact()\n            5 -> deleteContact()\n            6 -> true\n        }\n    }\n\n    fun showMenuAux() {\n        menuAux.forEach { (id, value) ->\n            println(\"$id. $value\")\n        }\n        println(\"Digite el numero de la opcion que desea realziar\")\n        selectionAux = readLine()\n        if (selectionAux!!.toInt() == 1) {\n            switch()\n        } else {\n            showMenu()\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/kotlin/adridoce.kt",
    "content": "package com.cursoandroid.roadmap_retos_programacion\n\n/*\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\nfun main() {\n\n    // Arrays\n    val array: Array<Int> = arrayOf(1, 2, 3, 4, 5)\n    val arrayString: Array<String> = arrayOf(\"uno\", \"dos\", \"tres\")\n    // Listas\n    val lista: List<Int> = listOf(1, 2, 3, 4, 5)\n    val listaMutable: MutableList<String> = mutableListOf(\"a\", \"b\", \"c\")\n    // Conjuntos\n    val conjunto: Set<String> = setOf(\"manzana\", \"banana\", \"naranja\")\n    val conjuntoMutable: MutableSet<Int> = mutableSetOf(1, 2, 3)\n    // Mapas\n    val mapa: Map<String, Int> = mapOf(\"uno\" to 1, \"dos\" to 2, \"tres\" to 3)\n    val mapaMutable: MutableMap<String, String> = mutableMapOf(\"a\" to \"apple\", \"b\" to \"banana\")\n\n    agendaContactos()\n\n}\n\nfun agendaContactos() {\n    val contactos = mutableMapOf(\"Adrian\" to \"111222333\", \"Raquel\" to \"444555666\")\n    var opcion: Int? = 0\n\n    while (opcion != 6) {\n\n        println(\"/*------- Agenda -------*/\")\n        println(\"1. Buscar contacto\")\n        println(\"2. Agregar contacto\")\n        println(\"3. Actualizar contacto\")\n        println(\"4. Eliminar contacto\")\n        println(\"5. Ver contactos\")\n        println(\"6. Salir\\n->\")\n\n        val input = readLine()\n        opcion = input?.toInt()\n\n        when (opcion) {\n            1 -> buscarContacto(contactos)\n            2 -> agregarContacto(contactos)\n            3 -> actualizarContacto(contactos)\n            4 -> eliminarContacto(contactos)\n            5 -> mostrarContactos(contactos)\n            6 -> break\n            else -> \"La opcion indicada no es valida\"\n        }\n    }\n}\n\nfun mostrarContactos(contactos: MutableMap<String, String>) {\n\n    if (contactos.isNotEmpty()) {\n        println(\"/*** Contactos ***\\\\\")\n        for ((clave, valor) in contactos) {\n            println(\"$clave - $valor\")\n        }\n    }\n}\n\nfun buscarContacto(contactos: MutableMap<String, String>) {\n    println(\"Introduza el nombre del contacto que desea buscar:\")\n    val contacto = readLine().toString()\n\n    if (contacto in contactos) {\n        println(\"Contacto encontrado: \")\n        println(\"$contacto - ${contactos[contacto]}\")\n    } else {\n        println(\"El contacto no ha sido encontrado\")\n    }\n}\n\nfun agregarContacto(contactos: MutableMap<String, String>) {\n    println(\"Introduza el nombre del contacto:\")\n    val contacto = readLine().toString()\n\n    println(\"Introduzca el numero de telefono: \")\n    val contactPhone = readLine().toString()\n\n    if (contactPhone.matches(Regex(\"\\\\d{9}\"))) {\n        contactos[contacto] = contactPhone\n    }\n\n    contactos[contacto] = contactPhone\n    println(\"El contacto $contacto ha sido agregado a la lista de contactos\")\n}\n\nfun actualizarContacto(contactos: MutableMap<String, String>) {\n    println(\"Introduzca el nombre del contacto que desea modificar: \")\n    val contacto = readLine().toString()\n\n    if (contacto in contactos) {\n        println(\"Desea modificar los datos del contacto $contacto? s/n:\")\n        val check = readLine().toString()\n\n        if (check == \"s\") {\n            println(\"Introduzca el nuevo numero de telefono: \")\n            val newPhone = readLine().toString()\n\n            if (newPhone.matches(Regex(\"\\\\d{9}\"))) {\n                contactos[contacto] = newPhone\n                println(\"Telefono actualizado correctamentes\")\n            } else {\n                println(\"El numero de telefono debe tener 9 cifras\")\n            }\n        } else {\n            println(\"No se ha realizado ningun cambio\")\n        }\n    } else {\n        println(\"El contacto $contacto no se encuentra en la lista de contactos\")\n    }\n}\n\nfun eliminarContacto(contactos: MutableMap<String, String>) {\n    println(\"Introduzca el nombre del contacto que desea eliminar:\")\n    val contacto = readLine().toString()\n\n    if (contacto in contactos) {\n        println(\"Va a eliminar el contacto $contacto de su agenda, esta de acuerdo? s/n\")\n        val check = readLine().toString()\n\n        if (check == \"s\") {\n            contactos.remove(contacto)\n            println(\"El contacto $contacto ha sido eliminado\")\n        } else {\n            println(\"El contacto no ha sido eliminado\")\n        }\n    } else {\n        println(\"El contacto $contacto no se encuentra en la lista de contactos\")\n    }\n}"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/kotlin/blackriper.kt",
    "content": "import kotlin.math.sign\r\n\r\n/*\r\n En kotlin existen tres estructuras de datos\r\n 1. List\r\n 2. Set\r\n 3. Map\r\n estas estructuras pueden ser mutables o inmutables esto se tiene que especificar al crear\r\n la estructura\r\n */\r\n\r\n\r\nfun examplesStructuredData(){\r\n  //  listas\r\n    val narutoCharacters= listOf(\"Naruto\",\"Sasuke\",\"Kakashi\")\r\n    val narutoJutsus= mutableListOf(\"Chidori\",\"Rasegan\",\"Edo tensei\")\r\n\r\n    print(\"lists\\n\")\r\n    println(narutoCharacters)\r\n    println(narutoJutsus)\r\n\r\n\r\n    // set no pueden existir elemetos repetidos\r\n   val narutoVillians= setOf(\"Orochimaru\",\"Itachi\",\"Kisame\",\"Obito\")\r\n   val narutoGirls= mutableSetOf(\"Sakura\",\"Hinata\",\"Ino\")\r\n   print(\"sets\\n\")\r\n   println(narutoVillians)\r\n   println(narutoGirls)\r\n\r\n\r\n  // map\r\n  val narutoVilliansMap= mapOf(\"Orochimaru\" to \"Edo tensei\",\"Itachi\" to \"Amaterasu\",\"Kisame\" to \"samehada\")\r\n  val narutoVilliansMutable= mutableMapOf(\"Orochimaru\" to \"Edo tensei\",\"Itachi\" to \"Amaterasu\",\"Kisame\" to \"samehada\")\r\n  print(\"maps\\n\")\r\n  println(narutoVilliansMap)\r\n  println(narutoVilliansMutable)\r\n}\r\n\r\nfun examplesOperationStructuredData(){\r\n  // solo las listas , mapas, sets mutables pueden ser modificadas\r\n   val narutoJutsus= mutableListOf(\"Chidori\",\"Rasegan\",\"Edo tensei\")\r\n   val narutoGirls= mutableSetOf(\"Sakura\",\"Hinata\",\"Ino\")\r\n   val narutoVilliansMutable= mutableMapOf(\"Orochimaru\" to \"Edo tensei\",\"Itachi\" to \"Amaterasu\",\"Kisame\" to \"samehada\")\r\n\r\n  // insertion element\r\n   println(\"insertion\")\r\n   narutoJutsus.add(\"Katon\")\r\n   println(narutoJutsus)\r\n   narutoGirls.add(\"Temari\")\r\n   println(narutoGirls)\r\n   narutoVilliansMutable[\"Madara\"] = \"Susano\"\r\n   println(narutoVilliansMutable)\r\n\r\n   // remove element\r\n   println(\"removal\")\r\n   narutoJutsus.remove(\"Chidori\")\r\n   println(narutoJutsus)\r\n   narutoGirls.remove(\"Ino\")\r\n   println(narutoGirls)\r\n   narutoVilliansMutable.remove(\"Itachi\")\r\n   println(narutoVilliansMutable)\r\n\r\n   //update element solo aplicable a mapas\r\n   println(\"update\")\r\n   narutoVilliansMutable[\"Orochimaru\"] = \"Soul reanimation\"\r\n   println(narutoVilliansMutable)\r\n\r\n   // ordered\r\n   println(\"ordered\")\r\n   println(narutoJutsus.sorted())\r\n   println(narutoGirls.sorted())\r\n   println(narutoVilliansMutable.values.sorted())\r\n\r\n   }\r\n\r\n// reto lista de contactos\r\nval contacts:MutableMap<String,String> = mutableMapOf()\r\n\r\n// crud de contactos\r\nfun addContact(name:String,phone:String)=contacts.put(name,phone)\r\nfun deleteContact(name:String)=contacts.remove(name)\r\nfun updateContact(name:String,phone:String){\r\n    contacts[name]=phone\r\n}\r\n\r\n// opraciones de contactos\r\nfun readData() {\r\n    println(\"name for new contact:\")\r\n    val name = readLine().toString()\r\n    println(\"number phone  for new contact:\")\r\n    val phone = readLine()!!.filter { it.isDigit() }\r\n    if (phone.length < 10) {\r\n        println(\"invalid phone number\")\r\n    }\r\n    addContact(name, phone)\r\n}\r\n\r\nfun deleteData(){\r\n    println(\"name for delete contact:\")\r\n    val name = readLine()!!.toString()\r\n    deleteContact(name)\r\n}\r\n\r\n\r\n\r\nfun showData(){\r\n   for ((name,phone) in contacts){\r\n       println(\"$name : $phone\")\r\n   }\r\n}\r\n\r\nfun updateData(){\r\n    println(\"name for update number:\")\r\n    val name = readLine()!!.toString()\r\n    println(\"number phone  for update contact:\")\r\n    val phone = readLine()!!.filter { it.isDigit() }\r\n    if (phone.length < 10) {\r\n        println(\"invalid phone number\")\r\n    }\r\n    updateContact(name,phone)\r\n}\r\n\r\n\r\nfun contactAgent(){\r\n var option:Int=0\r\n while (option!=5) {\r\n     println(\"contact agent menu\")\r\n     println(\"1. add contact\")\r\n     println(\"2. delete contact\")\r\n     println(\"3. update number contact\")\r\n     println(\"4. show contact list\")\r\n     println(\"5. exit\")\r\n     option = readLine()!!.toInt()\r\n     when (option) {\r\n         1 -> readData()\r\n         2 -> deleteData()\r\n         3 -> updateData()\r\n         4 -> showData()\r\n         5 -> break\r\n         else -> println(\"invalid option\")\r\n     }\r\n }\r\n}\r\n\r\n\r\n\r\n\r\n\r\nfun main() {\r\n   examplesStructuredData()\r\n   examplesOperationStructuredData()\r\n   contactAgent()\r\n}"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/kotlin/deivitdev.kt",
    "content": "fun main() {\n    // List\n    val list = mutableListOf(\"Java\", \"C\", \"Python\")\n    list.add(\"Kotlin\")\n    list.remove(\"Java\")\n    list[1] = \"C#\"\n    val sortedList = list.sorted()\n    println(sortedList)\n\n    // Set\n    val set = mutableSetOf(\"Java\", \"C\", \"Python\")\n    set.add(\"Kotlin\")\n    set.remove(\"Java\")\n    val sortedSet = set.sorted()\n    println(sortedSet)\n\n    // Map\n    val map = mutableMapOf(\"A\" to \"Java\", \"B\" to \"C\", \"C\" to \"Python\")\n    map[\"D\"] = \"Kotlin\"\n    map.remove(\"A\")\n    map[\"B\"] = \"C#\"\n    val sortedMap = map.toSortedMap()\n    println(sortedMap)\n\n    agendaTelefonica()\n}\n\n// ------------ Agenda Telefonica ------------\n\nval contacts = mutableMapOf<String, Int>()\n\nfun agendaTelefonica() {\n    while (true) {\n        println(\"¿Qué operación quieres realizar?\")\n        println(\"1. Añadir contacto\")\n        println(\"2. Actualizar contacto\")\n        println(\"3. Eliminar contacto\")\n        println(\"4. Buscar contacto\")\n        println(\"5. Salir\")\n        contacts.forEach { (key, value) -> println(\"$key: $value\") }\n        val opcion = readln().toInt()\n        when (opcion) {\n            1 -> addContact()\n            2 -> editContact()\n            3 -> deleteContact()\n            4 -> searchContact()\n            5 -> return\n            else -> println(\"Opción no válida\")\n        }\n    }\n}\n\nfun addContact() {\n    val name = getInput(\"Introduce el nombre del contacto\")\n    val phone = getInput(\"Introduce el número de teléfono\")\n    if (isValidPhoneNumber(phone)) {\n        contacts[name] = phone.toInt()\n    } else {\n        println(\"Numero invalido, debe ser numerico y no mayor a 11 digitos\")\n    }\n}\n\nfun editContact() {\n    val name = getInput(\"Introduce el nombre del contacto\")\n    if (contacts.containsKey(name)) {\n        val phone = getInput(\"Introduce el nuevo número de teléfono\")\n        if (isValidPhoneNumber(phone)) {\n            contacts[name] = phone.toInt()\n        } else {\n            println(\"Numero invalido, debe ser numerico y no mayor a 11 digitos\")\n        }\n    } else {\n        println(\"El contacto no existe\")\n    }\n}\n\nfun deleteContact() {\n    val name = getInput(\"Introduce el nombre del contacto\")\n    if (contacts.containsKey(name)) {\n        contacts.remove(name)\n    } else {\n        println(\"El contacto no existe\")\n    }\n}\n\nfun searchContact() {\n    val name = getInput(\"Introduce el nombre del contacto\")\n    if (contacts.containsKey(name)) {\n        println(\"El número de teléfono de $name es ${contacts[name]}\")\n    } else {\n        println(\"El contacto no existe\")\n    }\n}\n\nfun isValidPhoneNumber(phone: String) = phone.length <= 11 && phone.all { it.isDigit() }\n\nfun getInput(prompt: String): String {\n    println(prompt)\n    return readln()\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/kotlin/didacdev.kt",
    "content": "fun main() {\n\n// ---------- Array ------------\n/*\n    - Número fijo de datos del mismo tipo\n*/\n    val array = arrayOf(0, 1, 2, 3, 4)\n\n    // Obtener\n    println(array[2])\n\n// ----------- List -----------\n/*\n    - Almacena elementos en un orden especificado\n*/\n    val immutableList = listOf(0, 1, 2, 3, 4)\n    val mutableList = mutableListOf(0, 3, 6, 2, 4)\n\n    // Obtener\n    println(immutableList.get(2))\n    println(immutableList[2])\n\n    // Añadir\n    mutableList.add(1)\n\n    // Eliminar\n    mutableList.removeAt(2)\n\n    // Actualizar\n    mutableList[0] = 5\n\n    println(mutableList)\n\n    // Ordenar\n    mutableList.sort()\n    println(mutableList)\n\n// -------- Set -------------\n/*\n    - Almacena elementos no repetidos\n    - No tienen un orden definido\n*/\n\n    val immutableSet = setOf(1, 2, 3, 4)\n    val mutableSet = mutableSetOf(2, 1, 5, 4)\n\n    // Añadir\n    mutableSet.add(3)\n\n    // Eliminar\n    mutableSet.remove(1)\n\n    println(mutableSet)\n\n    // Ordenar\n    val ordenado = mutableSet.sorted()\n    println(ordenado)\n\n// ----------------- Map -------------\n/*\n    - Almacena pares clave-valor del mismo tipo\n    - Claves únicas\n*/\n    val immutableMap = mapOf(1 to \"pepe\", 2 to \"juan\")\n    val mutableMap = mutableMapOf(2 to \"pepe\", 1 to \"juan\")\n\n    // Añadir\n    mutableMap.put(3, \"pedro\")\n    mutableMap[0] = \"ana\"\n\n    // Actualizar\n    mutableMap[1] = \"paco\"\n\n    // Eliminar\n    mutableMap.remove(0)\n\n    println(mutableMap)\n\n    // Ordenar\n    val mapOrdenado = mutableMap.toSortedMap()\n\n    println(mapOrdenado)\n\n// -------------- ArrayDeque ----------------\n/*\n    - Implementación de cola y pila\n    - permite añadir y eliminar el primer o último elemento\n*/\n    val deque = ArrayDeque(listOf(1, 2, 3, 4))\n\n    // Añadir\n    deque.addFirst(0)\n    deque.addLast(5)\n\n    println(deque)\n\n    // Obtener\n    println(deque.first())\n    println(deque.last())\n\n    // Eliminar\n    deque.removeFirst()\n    deque.removeLast()\n\n    println(deque) \n\n    agenda()\n\n}\n\nfun agenda() {\n    println(\"--------------\")\n    println(\"    Agenda    \")\n    println(\"--------------\")\n    val agenda = mutableMapOf<String, Int>()\n    var quit = false\n\n    while(!quit) {\n        println(\"\")\n        println(\"1 - Buscar\")\n        println(\"2 - Insertar\")\n        println(\"3 - Actualizar\")\n        println(\"4 - Eliminar\")\n\n        val entrada = readLine()\n\n        if (entrada != null) {\n            when (entrada) {\n                \"1\" -> search(agenda)\n                \"2\" -> insert(agenda)\n                \"3\" -> update(agenda)\n                \"4\" -> delete(agenda)\n                else -> println(\"Opción incorrecta\")\n            }\n        } else {\n            println(\"No has introducido nada.\")\n        }\n    }\n}\n\nfun search(agenda: MutableMap<String, Int>) {\n    println(\"\")\n    println(\"Nombre del contacto:\")\n\n    val contactName = readLine()\n\n    if (contactName != null) {\n        val contact = agenda[contactName]\n        \n        if (contact != null) {\n\n            println(\" $contactName: $contact\")\n        } else {\n            println(\"No existe el contacto\")\n        }\n    } \n}\n\nfun  insert(agenda: MutableMap<String, Int>) {\n    var name: String = \"\"\n    var number: Int\n\n    println(\"\")\n    println(\"Nombre del contacto:\")\n\n    val contactName = readLine()\n\n    if (contactName != null) {\n        name = contactName\n    } else {\n        println(\"No existe el contacto\")\n    }\n\n    println(\"Número del contacto: \")\n    val contactNumber = readLine()\n    val numberInt = contactNumber?.toInt()\n\n    number = if (numberInt != null) numberInt else 0\n\n    agenda[name] = number\n\n    print(\"$name: $number\")\n\n}\n\nfun update(agenda: MutableMap<String, Int>) {\n    println(\"\")\n    println(\"Nombre del contacto:\")\n\n    val contactName = readLine()\n\n    if (contactName != null) {\n        if (agenda[contactName] != null){\n            println(\"Nuevo número:\")\n            val newNumber = readLine()\n\n            val numberInt = newNumber?.toInt()\n\n            if (numberInt != null) {\n                agenda[contactName] = numberInt\n            }\n        } else {\n            println(\"No existe el contacto\")\n        }\n    } else {\n        println(\"No se ha introducido nada\")\n    }\n}\n\nfun delete(agenda: MutableMap<String, Int>) {\n    println(\"\")\n    println(\"Nombre del contacto\")\n\n    val contactName = readLine()\n\n    if (contactName != null) {\n        if (agenda[contactName] != null) {\n            agenda.remove(contactName)\n        } else {\n            println(\"No existe el contacto\")\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/kotlin/eulogioep.kt",
    "content": "// Función principal que demuestra las estructuras de datos básicas\nfun demostrarEstructurasDeDatos() {\n    // Lista mutable\n    println(\"Lista mutable:\")\n    val listaNumeros = mutableListOf(1, 2, 3, 4, 5)\n    println(\"Original: $listaNumeros\")\n    listaNumeros.add(6)\n    println(\"Después de añadir 6: $listaNumeros\")\n    listaNumeros.removeAt(0)\n    println(\"Después de eliminar el primer elemento: $listaNumeros\")\n    listaNumeros[0] = 10\n    println(\"Después de actualizar el primer elemento a 10: $listaNumeros\")\n    listaNumeros.sort()\n    println(\"Después de ordenar: $listaNumeros\")\n\n    // Conjunto mutable\n    println(\"\\nConjunto mutable:\")\n    val conjuntoFrutas = mutableSetOf(\"manzana\", \"plátano\", \"naranja\")\n    println(\"Original: $conjuntoFrutas\")\n    conjuntoFrutas.add(\"pera\")\n    println(\"Después de añadir 'pera': $conjuntoFrutas\")\n    conjuntoFrutas.remove(\"manzana\")\n    println(\"Después de eliminar 'manzana': $conjuntoFrutas\")\n\n    // Mapa mutable\n    println(\"\\nMapa mutable:\")\n    val mapaEdades = mutableMapOf(\"Alice\" to 25, \"Bob\" to 30)\n    println(\"Original: $mapaEdades\")\n    mapaEdades[\"Charlie\"] = 35\n    println(\"Después de añadir Charlie: $mapaEdades\")\n    mapaEdades.remove(\"Bob\")\n    println(\"Después de eliminar Bob: $mapaEdades\")\n    mapaEdades[\"Alice\"] = 26\n    println(\"Después de actualizar la edad de Alice: $mapaEdades\")\n\n    // Array\n    println(\"\\nArray:\")\n    val arrayLetras = arrayOf(\"A\", \"B\", \"C\", \"D\")\n    println(\"Original: ${arrayLetras.joinToString()}\")\n    arrayLetras[1] = \"Z\"\n    println(\"Después de cambiar B por Z: ${arrayLetras.joinToString()}\")\n}\n\n// Clase para representar un contacto\ndata class Contacto(val nombre: String, val telefono: String)\n\n// Clase para la agenda de contactos\nclass AgendaContactos {\n    private val contactos = mutableListOf<Contacto>()\n\n    fun agregarContacto(nombre: String, telefono: String) {\n        if (validarTelefono(telefono)) {\n            contactos.add(Contacto(nombre, telefono))\n            println(\"Contacto agregado exitosamente.\")\n        } else {\n            println(\"Número de teléfono inválido.\")\n        }\n    }\n\n    fun buscarContacto(nombre: String) {\n        val contactoEncontrado = contactos.find { it.nombre.equals(nombre, ignoreCase = true) }\n        if (contactoEncontrado != null) {\n            println(\"Contacto encontrado: ${contactoEncontrado.nombre} - ${contactoEncontrado.telefono}\")\n        } else {\n            println(\"Contacto no encontrado.\")\n        }\n    }\n\n    fun actualizarContacto(nombre: String, nuevoTelefono: String) {\n        val indice = contactos.indexOfFirst { it.nombre.equals(nombre, ignoreCase = true) }\n        if (indice != -1 && validarTelefono(nuevoTelefono)) {\n            contactos[indice] = Contacto(contactos[indice].nombre, nuevoTelefono)\n            println(\"Contacto actualizado exitosamente.\")\n        } else {\n            println(\"Contacto no encontrado o número de teléfono inválido.\")\n        }\n    }\n\n    fun eliminarContacto(nombre: String) {\n        val eliminado = contactos.removeIf { it.nombre.equals(nombre, ignoreCase = true) }\n        if (eliminado) {\n            println(\"Contacto eliminado exitosamente.\")\n        } else {\n            println(\"Contacto no encontrado.\")\n        }\n    }\n\n    fun mostrarContactos() {\n        if (contactos.isEmpty()) {\n            println(\"La agenda está vacía.\")\n        } else {\n            println(\"Contactos en la agenda:\")\n            contactos.forEach { println(\"${it.nombre} - ${it.telefono}\") }\n        }\n    }\n\n    private fun validarTelefono(telefono: String): Boolean {\n        return telefono.all { it.isDigit() } && telefono.length <= 11\n    }\n}\n\nfun main() {\n    println(\"Demostración de estructuras de datos básicas:\")\n    demostrarEstructurasDeDatos()\n\n    println(\"\\nAgenda de Contactos:\")\n    val agenda = AgendaContactos()\n\n    while (true) {\n        println(\"\\nSeleccione una operación:\")\n        println(\"1. Agregar contacto\")\n        println(\"2. Buscar contacto\")\n        println(\"3. Actualizar contacto\")\n        println(\"4. Eliminar contacto\")\n        println(\"5. Mostrar todos los contactos\")\n        println(\"6. Salir\")\n\n        when (readLine()) {\n            \"1\" -> {\n                println(\"Ingrese el nombre del contacto:\")\n                val nombre = readLine() ?: \"\"\n                println(\"Ingrese el número de teléfono:\")\n                val telefono = readLine() ?: \"\"\n                agenda.agregarContacto(nombre, telefono)\n            }\n            \"2\" -> {\n                println(\"Ingrese el nombre del contacto a buscar:\")\n                val nombre = readLine() ?: \"\"\n                agenda.buscarContacto(nombre)\n            }\n            \"3\" -> {\n                println(\"Ingrese el nombre del contacto a actualizar:\")\n                val nombre = readLine() ?: \"\"\n                println(\"Ingrese el nuevo número de teléfono:\")\n                val nuevoTelefono = readLine() ?: \"\"\n                agenda.actualizarContacto(nombre, nuevoTelefono)\n            }\n            \"4\" -> {\n                println(\"Ingrese el nombre del contacto a eliminar:\")\n                val nombre = readLine() ?: \"\"\n                agenda.eliminarContacto(nombre)\n            }\n            \"5\" -> agenda.mostrarContactos()\n            \"6\" -> {\n                println(\"Saliendo del programa.\")\n                return\n            }\n            else -> println(\"Opción no válida. Intente de nuevo.\")\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/kotlin/miguelex.kt",
    "content": "data class Contacto(val nombre: String, val telefono: String)\n\nclass Agenda {\n    private val contactos = mutableListOf<Contacto>()\n\n    fun buscar(nombre: String): Contacto? {\n        return contactos.find { it.nombre == nombre }\n    }\n\n    fun agregar(nombre: String, telefono: String) {\n        if (telefono.matches(Regex(\"[0-9]{1,11}\"))) {\n            contactos.add(Contacto(nombre, telefono))\n        } else {\n            println(\"Número de teléfono no válido.\")\n        }\n    }\n\n    fun actualizar(nombre: String, nuevoNombre: String, nuevoTelefono: String) {\n        var contacto = buscar(nombre) ?: return\n        if (nuevoTelefono.matches(Regex(\"[0-9]{1,11}\"))) {\n            contacto.nombre = nuevoNombre\n            contacto.telefono = nuevoTelefono\n        } else {\n            println(\"Número de teléfono no válido.\")\n        }\n    }\n\n    fun eliminar(nombre: String) {\n        contactos.removeIf { it.nombre == nombre }\n    }\n\n    fun listar() {\n        contactos.forEach { println(it) }\n    }\n}\n\nfun main() {\n\n    //Array\n    val array = arrayOf(1, 2, 3, 4, 5)\n    \n    // Imprimir el array\n\n    for (i in array) {\n        println(i)\n    }\n\n    // Añadir un elemento al array\n\n    array.set(5, 6)\n\n    // Imprimir el array\n\n    for (i in array) {\n        println(i)\n    }\n\n    // Eliminar un elemento del array\n\n    array.set(5, 0)\n\n    // Imprimir el array\n\n    for (i in array) {\n        println(i)\n    }\n\n    // ordenar el array\n\n    array.sort()\n\n    // Imprimir el array\n\n    for (i in array) {\n        println(i)\n    }\n\n    // Listas\n\n    val lista = mutableListOf(1, 2, 3, 4, 5)    \n\n    // Imprimir la lista\n\n    for (i in lista) {\n        println(i)\n    }\n\n    // Añadir un elemento a la lista\n\n    lista.add(6)\n\n    // Imprimir la lista\n\n    for (i in lista) {\n        println(i)\n    }\n\n    // Eliminar un elemento de la lista\n\n    lista.removeAt(5)\n\n    // Imprimir la lista\n\n    for (i in lista) {\n        println(i)\n    }\n\n    // ordenar la lista\n\n    lista.sort()\n\n    // Imprimir la lista\n\n    for (i in lista) {\n        println(i)\n    }\n\n    // Mapas\n\n    val mapa = mutableMapOf(\"uno\" to 1, \"dos\" to 2, \"tres\" to 3, \"cuatro\" to 4, \"cinco\" to 5)\n\n    // Imprimir el mapa\n\n    for (i in mapa) {\n        println(i)\n    }\n\n    // Añadir un elemento al mapa\n\n    mapa.put(\"seis\", 6)\n\n    // Imprimir el mapa\n\n    for (i in mapa) {\n        println(i)\n    }\n\n    // Eliminar un elemento del mapa\n\n    mapa.remove(\"seis\")\n\n    // Imprimir el mapa\n\n    for (i in mapa) {\n        println(i)\n    }\n\n    // ordenar el mapa\n\n    val mapaOrdenado = mapa.toSortedMap()\n\n    // Imprimir el mapa\n\n    for (i in mapaOrdenado) {\n        println(i)\n    }\n\n    // Conjuntos\n\n    val conjunto = mutableSetOf(1, 2, 3, 4, 5)\n\n    // Imprimir el conjunto\n\n    for (i in conjunto) {\n        println(i)\n    }\n\n    // Añadir un elemento al conjunto\n\n    conjunto.add(6)\n\n    // Imprimir el conjunto\n\n    for (i in conjunto) {\n        println(i)\n    }\n\n    // Eliminar un elemento del conjunto\n\n    conjunto.remove(6)\n\n    // Imprimir el conjunto\n\n    for (i in conjunto) {\n        println(i)\n    }\n\n    // ordenar el conjunto\n\n    val conjuntoOrdenado = conjunto.toSortedSet()\n\n    // Imprimir el conjunto\n\n    for (i in conjuntoOrdenado) {\n        println(i)\n    }\n\n    // Extra\n\n    val agenda = Agenda()\n    var continuar = true\n    while (continuar) {\n        println(\"¿Qué operación desea realizar?\")\n        println(\"1. Buscar contacto\")\n        println(\"2. Agregar contacto\")\n        println(\"3. Actualizar contacto\")\n        println(\"4. Eliminar contacto\")\n        println(\"5. Listar contactos\")\n        println(\"6. Salir\")\n\n        val opcion = readln().toInt()\n\n        when (opcion) {\n            1 -> {\n                println(\"Introduzca el nombre del contacto a buscar:\")\n                val nombre = readln()\n                val contacto = agenda.buscar(nombre)\n                if (contacto != null) {\n                    println(\"Contacto encontrado: $contacto\")\n                } else {\n                    println(\"Contacto no encontrado.\")\n                }\n            }\n            2 -> {\n                println(\"Introduzca el nombre del nuevo contacto:\")\n                val nombre = readln()\n                println(\"Introduzca el número de teléfono del nuevo contacto:\")\n                val telefono = readln()\n                agenda.agregar(nombre, telefono)\n            }\n            3 -> {\n                println(\"Introduzca el nombre del contacto a actualizar:\")\n                val nombre = readln()\n                println(\"Introduzca el nuevo nombre del contacto:\")\n                val nuevoNombre = readln()\n                println(\"Introduzca el nuevo número de teléfono del contacto:\")\n                val nuevoTelefono = readln()\n                agenda.actualizar(nombre, nuevoNombre, nuevoTelefono)\n            }\n            4 -> {\n                println(\"Introduzca el nombre del contacto a eliminar:\")\n                val nombre = readln()\n                agenda.eliminar(nombre)\n            }\n            5 -> {\n                agenda.listar()\n            }\n            6 -> {\n                continuar = false\n            }\n            else -> {\n                println(\"Opción no válida.\")\n            }\n        }\n    }\n    println(\"¡Gracias por usar la agenda de contactos!\")\n\n}"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/kotlin/pedroomar23.kt",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\n// Array \nval myArray = Array(1, 2, 3, 4)\n\n// Insersion \nmyArray.add(5)\n\n// Borrado \nmyArray.removeAt(2)\n\n// Actualizacion \nfor (i in myArray) {\n    print(i)\n}\n\n// Ordenacion \nmyArray.sort()\n\n// Listas \nval myList = ListOf(1, 2, 3, 4)\n\n// Insersion \nmyList.add(5)\n\n// Borrado\nmyList.removeAt(1)\n\n// Actualizacion \nfor (a in myList) {\n    print(a)\n}\n\n// Ordenacion \nmyList.sort()\n\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/kotlin/rikmij.kt",
    "content": "/*\nESTRUCTURAS DE DATOS\n* EJERCICIO:\n- Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n- Utiliza operaciones de inserción, borrado, actualización y ordenación.\n\nDIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n- Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n- Cada contacto debe tener un nombre y un número de teléfono.\n- El programa solicita en primer lugar cuál es la operación que se quiere realizar,\ny a continuación los datos necesarios para llevarla a cabo.\n- El programa no puede dejar introducir números de teléfono no númericos y con más\nde 11 dígitos (o el número de dígitos que quieras).\n- También se debe proponer una operación de finalización del programa.\n*/\n\nfun lists() {\n    val listExample = mutableListOf(\"Qui Gon Jinn\", \"Obi Wan\", \"Mace Windu\")\n    println(listExample)\n\n    println(\"\\n-> Agregar elementos a una lista:\")\n    listExample.add(\"Anakin\")\n    println(listExample)\n\n    val addList = listOf(\"Ahsoka Tano\", \"Luke\", \"Rey\")\n    listExample.addAll(addList)\n    println(listExample)\n\n    println(\"\\n-> Borrar elementos a una lista:\")\n    listExample.remove(\"Rey\")\n    println(listExample)\n\n    listExample.removeAt(2)\n    println(listExample)\n\n    println(\"\\n-> Ordenar elementos a una lista:\")\n    listExample.sort()\n    println(listExample)\n\n    println(\"\\n-> Invertir elementos a una lista:\")\n    listExample.reverse()\n    println(listExample)\n\n    println(\"\\n-> Vaciar una lista:\")\n    listExample.clear()\n    println(listExample)\n}\n\n\nfun sets() {\n    val setExample = mutableSetOf(\"Aragorn\", \"Légolas\", \"Gimli\", \"Gandalf\")\n    println(setExample)\n\n    println(\"\\n-> Añadir elementos a un set:\")\n    setExample.add(\"Gollum\")\n    println(setExample)\n\n    val hobbits = setOf(\"Frodo\", \"Sam\")\n    val comunidadAnillo = setExample.union(hobbits)\n    println(comunidadAnillo)\n\n    println(\"\\n-> Borrar elementos de un set:\")\n    setExample.remove(\"Gollum\")\n    println(comunidadAnillo)\n\n    println(\"\\n-> Ordenar set:\")\n    val comunidadAnilloOrden = comunidadAnillo.sorted()\n    println(comunidadAnilloOrden)\n\n    println(\"\\n-> Borrar un set:\")\n    setExample.removeAll(comunidadAnillo)\n    println(setExample)\n}\n\n\nfun tuples() {\n    val tupleExample = Triple(\"Mario\", \"Luigi\", \"Peach\")\n    println(tupleExample)\n}\n\n\nfun dicts() {\n    val dictExample = mutableMapOf(\"Charmander\" to \"Fuego\",\n        \"Squirtle\" to \"Agua\",\n        \"Bulbasaur\" to \"Planta\")\n    println(dictExample)\n\n    println(\"\\n-> Añadir elementos a un diccionario:\")\n    dictExample.put(\"Pikachu\", \"Eléctrico\")\n    println(dictExample)\n\n    val dict2 = mapOf(\"Nidoran\" to \"Veneno\", \"Pidgey\" to \"Volador\", \"Abra\" to \"Psíquico\", \"Metapod\" to \"Bicho\")\n    val dictSum = dictExample + dict2\n    println(dictSum)\n\n    println(\"\\n-> Borrar elementos de un diccionario:\")\n    dictExample.remove(\"Pikachu\")\n    println(dictExample)\n\n    val dict3 = mapOf(\"Pidgey\" to \"Volador\", \"Metapod\" to \"Bicho\")\n    val dictRest = dictSum - dict3.keys\n    /*hay que especificar keys aquí porque aunque esté en una variable nueva, se está restando el valor\n    de dictSum, y especificamos que borramos las claves\n    Para sumar no hace falta, porque los almacena en un nuevo diccionario, y + detecta automáticamente\n    las claves\n     */\n    println(dictRest)\n\n    println(\"\\n-> Ordenar elementos de un diccionario:\")\n    val dictOrden = dictRest.toSortedMap()\n    println(dictOrden)\n\n    println(\"\\n-> Invertir un diccionario:\")\n    val dictReverse = dictOrden.reversed()\n    println(dictReverse)\n\n    println(\"\\n-> Borrar un diccionario:\")\n    dictOrden.clear()\n    println(dictOrden)\n}\n\n\nfun ejExtra() {\n    val contactList = mutableMapOf(\"Mouredev\" to 3, \"Aris\" to 54)\n\n\n    fun lookForContact(){\n    if (contactList.isEmpty()){\n        println(\"No hay contactos\")\n    }else{\n        println(\"¿Quieres buscar por contacto (c) o por número (n)?: \")\n        val lookFor = readln()\n\n        if (lookFor == \"c\"){\n            println(\"¿Qué contacto quieres buscar?: \")\n            val contact = readln()\n\n            if (contact in contactList){\n                println(\"$contact : ${contactList[contact]}\")\n            }\n        } else if (lookFor == \"n\"){\n            println(\"Qué número quieres buscar?: \")\n            val contactNum: Int = readln().toInt()\n\n            if (contactNum in contactList.values){\n                for ((name, number) in contactList){\n                    if (number == contactNum){\n                        println(\"El número $number pertenece a: $name\")\n                    }\n                }\n            }else{\n                println(\"Este número no está en los contactos\")\n            }\n        }else{\n            println(\"Esta opción no está disponible\")\n        }\n    }\n        readln()\n    }\n\n\n    fun addContact() {\n        println(\"Añada el nombre del contacto\")\n        val contactName = readln()\n\n        println(\"Añada el número de teléfono del contacto\")\n        val contactNumber = readln()\n\n        if (contactNumber.matches(Regex(\"\\\\d{9}\"))){\n            contactList[contactName] = contactNumber.toInt()\n        }else{\n            println(\"Formato de número no válido. Debe tener 9 cifras\")\n            addContact()\n        }\n        readln()\n    }\n\n    fun updateContact() {\n        println(\"¿Quieres actualizar algún contasto?: Sí(y) / No(n)\")\n        val act = readln()\n\n        if (act == \"y\"){\n            println(\"¿Qué contacto quieres actualizar?: \")\n            val contactName = readln()\n\n            if (contactName in contactList){\n                println(\"¿Cuál es el nuevo número?: \")\n                val newNumber = readln()\n\n                if (newNumber.matches(Regex(\"\\\\d{9}\"))){\n                    contactList[contactName] = newNumber.toInt()\n                }else{\n                    println(\"Formato de número no válido. Debe tener 9 cifras\")\n                    updateContact()\n                }\n            }else{\n                println(\"Este contacto no está registrado\")\n                updateContact()\n            }\n        }else if (act == \"n\"){\n            readln()\n        }else{\n            println(\"Opción no válida\")\n            readln()\n            updateContact()\n        }\n    }\n\n\n    fun deleteContact() {\n        println(\"¿Quieres borrar algún contacto?: \")\n        val deleteContact = readln()\n\n        if (deleteContact in contactList){\n            contactList.remove(deleteContact)\n        } else{\n            println(\"No existe ese contacto\")\n            deleteContact()\n        }\n        readln()\n    }\n\n    fun showContacts() {\n        for (contact in contactList){\n            println(contact)\n        }\n        readln()\n    }\n\n\n    fun inicio(){\n        println(\"\\n\\t~~ AGENDA TELEFÓNICA ~~\")\n        print(\"¿Qué quieres hacer?:\\n\" +\n                \"1.- Buscar contacto\\n\" +\n                \"2.- Añadir contacto\\n\" +\n                \"3.- Actualizar listado\\n\" +\n                \"4.- Borrar contacto\\n\" +\n                \"5.- Mostrar contactos\\n\" +\n                \"6.- Salir\\n-> \")\n\n        try{\n            val option = readln().toInt()\n\n            when (option) {\n                1 -> { lookForContact()\n                    inicio() }\n\n                2 -> { addContact()\n                    inicio() }\n\n                3 -> { updateContact()\n                    inicio() }\n\n                4 -> { deleteContact()\n                    inicio() }\n\n                5 -> { showContacts()\n                    inicio() }\n\n                !in 1..6 -> {\n                    println(\"Opción no válida. ELige una de las disponibles\")\n                    inicio() }\n            }\n        }catch (e: NumberFormatException){\n            println(\"Opción no válida, que sea un número del 1 al 6\")\n            inicio()\n        }\n    }\n\n    inicio()\n}\n\n\nfun main() {\n    println(\"*\".repeat(7)+\"ESTRUCTURAS DE DATOS EN KOTLIN\"+\"*\".repeat(7))\n\n    println(\"\\n\\t --> LISTAS\")\n    lists()\n\n    println(\"\\n\\t --> SETS\")\n    sets()\n\n    println(\"\\n\\t --> TUPLES (No son tuplas como tal, pero parecido)\")\n    tuples()\n\n    println(\"\\n\\t --> DICCIONARIOS/MAPS\")\n    dicts()\n\n    println('\\n' + \"-\".repeat(9) + \" EJERCICIO EXTRA \" + \"-\".repeat(9))\n    ejExtra()\n\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/kotlin/tiaguiito3.kt",
    "content": "\n\n// En Kotlin, existen las siguientes estructuras de datos:\n\n/*\nListas: Interfaz que representa una coleccion ordenada de elementos.\nPuedes usar listOf() para una lista inmutable, o\nmutableListOf() para una lista inmutable.\n */\n\nfun listas (): String{\n\n    val listaInmutable = listOf(\"a\", \"b\", \"c\", \"a\")\n    val listaMutable = mutableListOf(\"b\", \"c\", \"a\", \"b\")\n    val listaMutableCleared = mutableListOf(1, 2, 3)\n    val listaMutableAscending = mutableListOf(1,2,3,4,5,6,7,8,9)\n    val listaMutableDisordered = mutableListOf(1,3,7,5,3,3)\n    println(\"Operaciones de insercion en listas\")\n    println(listaMutable)\n    listaMutable.add(\"d\")\n    listaMutable.add(1, \"e\")\n    println(listaMutable)\n    println(\"-\")\n    println(\"Operaciones de borrado en listas\")\n    println(\"Eliminar 'b': ${listaMutable.also { it.remove(\"c\") }}\")\n    println(\"Eliminar por indice: ${listaMutable.also {it.removeAt(2)}}\")\n    println(\"Una lista comun: $listaMutableCleared\")\n    println(\"Lista anterior limpiada: ${listaMutableCleared.also {it.clear()}}\")\n    println(\"-\")\n    println(\"Operacion de actualizacion en lista\")\n    println(\"Lista mutable: $listaMutable\")\n    println(\"Actualizando el valor 'b' de la lista: ${listaMutable.also{it[0] = \"a\"}} \")\n    println(\"-\")\n    println(\"Operaciones de ordenacion en listas\")\n    println(\"Lista desordenada: $listaMutableDisordered\")\n    println(\"Ordenando la anterior lista: ${listaMutableDisordered.also {it.sort()}}\")\n    println(\"Lista ordenada ascendiente: $listaMutableAscending\")\n    println(\"Haciendo que la lista vaya para abajo: ${listaMutableAscending.also{it.sortDescending()}}\")\n    println(\"-\")\n    println(\"Operacion de busqueda en listas\")\n    var valorBuscado = \"c\"\n    println(\"El valor que busco es: $valorBuscado\")\n    var indice = listaInmutable.indexOf(valorBuscado)\n    println(\"El valor que busco se encuentro en el indice: $indice\")\n\n    return \"\"\n        }\n\n/*\nSets: Set es una colección que no permite duplicados.\nPuedes usar setOf() para un conjunto inmutable o mutableSetOf()\npara uno mutable.\n */\n\nfun sets(): String {\n\n    val setInmutable = setOf(\"a\", \"b\", \"c\")\n    val setMutable = mutableSetOf(\"a\", \"b\", \"c\")\n    val setMutableCleared = mutableSetOf(1, 2, 3)\n    println(\"Operacion de insercion en sets\")\n    println(setMutable)\n    setMutable.add(\"d\")\n    println(setMutable)\n\n    println(\"Operaciones de borrado en sets\")\n    println(\"Borrando un valor: ${setMutable.also {it.remove(\"d\")}}\")\n    println(\"Set comun: $setMutableCleared\")\n    println(\"Borrando todos los valores del anterior set: ${setMutableCleared.also {it.clear()}}\")\n\n    //En conjuntos, no se actualizan directamente elementos, normalmente\n    //para cambiar un elemento hay que eliminar el antiguo y agregar el nuevo\n\n    println(\"Operacion de buscado en sets\")\n    val valorBuscado = \"a\"\n    println(\"Valor buscado: $valorBuscado\")\n    if (valorBuscado in setInmutable) println(\"Se encontro el valor buscado\")\n\n    return \"\"\n    }\n\n/*\nMapas: Map es una colección de pares key-value.\nPuedes usar mapOf() para un mapa inmutable o mutableMapOf()\npara uno mutable.\n */\n\nfun maps(): String {\n\n    val mapInmutable = mapOf(\"a\" to 1, \"b\" to 2, \"c\" to 3)\n    val mapMutable= mutableMapOf(\"a\" to 1, \"b\" to 2, \"c\" to 3)\n    val mapMutableCleared = mutableMapOf(1 to \"a\", 2 to \"b\")\n    val mapMutableDisordered = mutableMapOf(\"b\" to 2, \"c\" to 3, \"a\" to 1)\n    var mapMutableOrdered = mapMutableDisordered\n\n    println(\"Operacion de insercion en map\")\n    println(mapMutable)\n    mapMutable[\"d\"] = 4\n    println(mapMutable)\n    println(\"-\")\n    println(\"Operaciones de borrado en maps\")\n    println(\"Borrando un valor por su key: ${mapMutable.also {it.remove(\"c\")}}\")\n    println(\"Un map comun: $mapMutableCleared\")\n    println(\"Borrando todo el map anterior: ${mapMutableCleared.also {it.clear()}}\")\n    println(\"-\")\n    println(\"Operacion de actualizacion en map, es igual a la de insercion\")\n    println(\"Actualizando el valor de la letra d en el map: ${mapMutable.also{it[\"d\"] = 3}}\")\n    println(\"-\")\n    println(\"Operacion de ordenacion en map\")\n    println(mapMutableDisordered)\n    println(\"Ordenando el anterior map: ${mapMutableOrdered.toSortedMap()}\")\n\n    return \"\"\n    }\n\n// Tambien hay arrays mutables e inmutables\n\nfun arrays():String {\n\n    val arrayInmutable = arrayOf(1, 2, 3)\n    // (Arrays mutables, se usan las listas mutables)\n    val arrayMutable = mutableListOf(1, 2, 3)\n    println(\"Los arrays mutables, en verdad son listas mutables\")\n\n    return \"\"\n\n    }\n\n/*\nSecuencias (Sequences): Las secuencias en Kotlin permiten la\nmanipulación eficiente de datos de manera \"Lazy\".\n */\n\nfun sequences ():String {\n    val secuencia = sequenceOf(1, 2, 3, 4, 5)\n    print(\"I don't understand sequences\")\n    return \"-\"\n    }\n\n\n// RETO\n\nfun agendaDeContactos() {\n    val agenda = mutableMapOf<String, String>()\n    var name: String\n    var phone: String\n    var isTrue = true\n\n\n    do {\n        println(\"\")\n        println(\"--- Agenda --- \")\n        println(\"1- Buscar contacto\")\n        println(\"2- Insertar contacto\")\n        println(\"3- Actualizar contacto\")\n        println(\"4- Eliminar contacto\")\n        println(\"5- Salir\")\n        print(\"Elige una opcion: \")\n        val input: String? = readLine() ?: \"\"\n\n        when (input) {\n            \"1\" -> {\n                print(\"Escribe el nombre del contacto que quieres bucar: \")\n                var busquedaContactoName = readLine() ?: \"\"\n                if (busquedaContactoName in agenda) println(\"Su numero es: ${agenda[busquedaContactoName]}\") else println(\"No se ha encontrado el contacto.\")\n                continue\n            }\n            \"2\" -> {\n                print(\"Escribe el nombre del contacto: \")\n                name = readLine() ?: \"\"\n                print(\"Escribe el numero del contacto: \")\n                phone = readLine() ?: \"\"\n                agenda[name] = phone\n                println(\"Contacto insertado!\")\n                continue\n            }\n            \"3\" -> {\n                print(\"Ingresa el nombre del contacto que quieres actualizar: \")\n                var actualizarContactoName = readLine() ?: \"\"\n\n                if (actualizarContactoName in agenda) {\n                    agenda.remove(actualizarContactoName)\n                } else {\n                    println(\"No se ha encontrado el conctacto\")\n                }\n                print(\"Escribe el nuevo nombre para tu contacto: \")\n                var nuevoName = readLine() ?: \"\"\n                print(\"Escribe el nuevo telefono: \")\n                var actualizarContactoPhone = readLine() ?: \"\"\n                agenda[nuevoName] = actualizarContactoPhone\n                println(\"Su contacto se ha actualizado!\")\n                continue\n            }\n            \"4\" -> {\n                print(\"Escribe el nombre del contacto que deseas eliminar: \")\n                var conctactoAEliminar:String? = readLine() ?: \"\"\n\n                if (conctactoAEliminar in agenda) {\n                    agenda.remove(conctactoAEliminar)\n                    println(\"Su contacto se ha eliminado correctamente!\")\n                } else {\n                    println(\"No se ha encontrado el contacto\")\n                }\n\n                continue\n            }\n            \"5\" -> {\n                println(\"Saliendo del programa!\")\n                isTrue = false\n            }\n            else -> {\n                println(\"\")\n                println(\"Por favor, elige una opcion valida\")\n            }\n\n        }\n\n\n    } while(isTrue)\n}\n\n// NOTE: Le faltan muchas funciones, como validar si el input es Int, hay repeticion de codigo y en si la estructura no es la mejor\n// pero siento que es valido mi progreso :)\n\nfun main(args: Array<String>) {\n    println(listas())\n    println(sets())\n    println(maps())\n    println(arrays())\n    println(sequences())\n    agendaDeContactos()\n}\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/kotlin/westwbn.kt",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos. [x]\n * - Cada contacto debe tener un nombre y un número de teléfono. [x]\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo. [x]\n * - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos. [x]\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa. [x]\n */\n\n/*\n*+---------------------+----------------------------------------+\n*| Tipo de colección   | Descripción                            |\n*+---------------------+----------------------------------------+\n*| Lists               | Colecciones ordenadas de artículos.    |\n*+---------------------+----------------------------------------+\n*| Sets                | Colecciones únicas de artículos        |\n*|                     | desordenados.                          |\n*+---------------------+----------------------------------------+\n*| Maps                | Conjuntos de pares clave-valor donde   |\n*|                     | las claves son únicas y se asignan a un|\n*|                     | solo valor.                            |\n*+---------------------+----------------------------------------+\n*| Mutables            | Se pueden modificar                    |\n*+---------------------+----------------------------------------+\n*| Inmutables          | No se pueden modificar (solo lectura)  |\n*+---------------------+----------------------------------------+\n* */\n\nfun contactBook() {\n    val contacts = mutableMapOf<String, Long>()\n\n    fun checkOption(input: String): Int? {\n        return try {\n            input.toInt()\n        } catch (e: NumberFormatException) {\n            println(\"Debes ingresar una opción numérica.\\n\")\n            null\n        }\n    }\n\n    fun contactInfo(option: Int) {\n\n        fun searchContact(name: String): String {\n            return if (contacts.isNotEmpty()) {\n                if (name in contacts) {\n                    \"Nombre: $name\\nNumero: ${contacts[name]}\\n\"\n                } else {\n                    \"No existe un contacto con ese nombre\\n\"\n                }\n            } else {\n                \"La lista de contactos esta vacía.\\n\"\n            }\n        }\n\n        fun viewContacts() {\n            if (contacts.isNotEmpty()) {\n                contacts.forEach { (name, number) -> println(\"Nombre: $name - Número: $number\") }\n            } else {\n                println(\"La lista de contactos esta vacía.\\n\")\n            }\n        }\n\n        fun checkInput(number: String): Long? {\n            return try {\n                number.toLong()\n            } catch (e: NumberFormatException) {\n                println(\"Debes ingresar un número válido y con 11 dígitos\\n\")\n                null\n            }\n        }\n\n        fun checkNumber(number: Long): Boolean {\n            return number.toString().length == 11\n        }\n\n        when (option) {\n            1 -> {\n                println(\"Ingresa el nombre:\")\n                val name = readln()\n\n                println(\"Ingresa el número:\")\n                val input = readln()\n\n                val number: Long? = checkInput(input)\n\n                if (number != null && !checkNumber(number)) {\n                    if (name !in contacts) {\n                        contacts[name] = number\n                    } else {\n                        println(\"Ya existe un contacto con ese nombre.\\n\")\n                    }\n                }\n            }\n\n            2 -> {\n                println(\"Ingresa el nombre:\")\n                val name = readln()\n                println(\"Ingresa el número:\")\n                val input = readln()\n\n                val number: Long? = checkInput(input)\n\n                if (number != null && !checkNumber(number)) {\n                    if (contacts.isNotEmpty() && name in contacts) {\n                        contacts[name] = number\n                    } else {\n                        println(\"No existe un contacto con ese nombre\\n\")\n                    }\n                }\n            }\n\n            3 -> {\n                println(\"Ingresa el nombre:\")\n                val name = readln()\n\n                if (name in contacts) {\n                    println(\"El contacto \\\"$name\\\" fue borrado correctamente.\\n\")\n                    contacts.remove(name)\n                } else {\n                    println(\"No existe un contacto con ese nombre\\n\")\n                }\n            }\n\n            4 -> {\n                println(\"Ingresa el nombre:\")\n                val name = readln()\n                println(searchContact(name))\n            }\n\n            5 -> {\n                viewContacts()\n            }\n\n            0 -> {\n                println(\"Cerrando lista de contactos..\")\n            }\n\n            else -> println(\"Ingresa una opción correcta.\\n\")\n        }\n    }\n\n    do {\n        println(\"Que operación deseas realizar?:\\n1) Agregar contacto\\n2) Actualizar contacto\\n3) Borrar contacto\\n4) Buscar contacto\\n5) Ver lista de contactos\\n0) Finalizar\")\n        val input = readln()\n        val option: Int? = checkOption(input)\n\n        if (option != null) {\n            contactInfo(option)\n        }\n\n    } while (option != 0)\n}\n\nfun main() {\n\n    //    Listas\n    //#Inmutables\n    val inmutableList = listOf(\"Hola\", \"Mundo\")\n    println(inmutableList)\n    //#Mutable\n    val numberList = mutableListOf(12, 1874, 54, 698, 45)\n    //#Inserción\n    numberList.add(2, 134)\n    //#Borrado\n    numberList.removeAt(2)\n    //#Actualización\n    numberList[0] = 74\n    //#Orden\n    numberList.sort()\n    println(numberList)\n\n    //    Set\n    //#Inmutable\n    val inmutableSet = setOf(\"Manzana\", \"Banana\")\n    println(inmutableSet)\n    //#Mutable\n    val shopping = mutableSetOf(\"Leche\", \"Gaseosa\", \"Carne\")\n    //#Inserción\n    shopping.add(\"Huevos\")\n    //#Borrado\n    shopping.remove(\"Carne\")\n\n    //    Map\n    //#Inmutable\n    val inmutableMap = mapOf(\"Uno\" to 1, \"Dos\" to 2, \"Tres\" to 3, \"Cuatro\" to 4, \"Cinco\" to 5)\n    println(inmutableMap.forEach { (t, u) -> println(\"Clave:$t -> Valor:$u\") })\n    //#Mutable\n    val salePrice = mutableMapOf(\"Tornillo\" to 12, \"Tuercas\" to 8, \"Clavos\" to 5, \"Arandelas\" to 0)\n    //#Inserción\n    salePrice[\"Pilas\"] = 50\n    //#Actualización\n    salePrice[\"Tornillo\"] = 10\n    //#Borrado\n    salePrice.remove(\"Arandelas\")\n    println(\"Lista de precios\")\n    salePrice.forEach { (key, value) -> println(\"$key:$$value\") }\n\n    //    Extra*/\n    contactBook()\n}"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/lua/Bert008.lua",
    "content": "--[[\n/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n]]\n-- Tablas\ntabla = {1, 2, 3}\n-- en lua solo existen tablas y strings\ncadena_string = \"Hola Mundo\"\n\n-- Insercion\ntable.insert(tabla, 4)\ntable.insert(tabla, 5)\nprint(\"insercion: \", table.concat(tabla, \", \"))\n-- actualizacion\ntabla[1] = 5 -- el indice en lua comienza con el 1\nprint(\"actualizacion: \", table.concat(tabla, \", \"))\n-- borrar\ntable.remove(tabla, 2) -- eliminamos el elemento 2\nprint(\"borrar: \", table.concat(tabla, \", \"))\n-- ordenar\ntable.sort(tabla)\nprint(\"ordenar: \", table.concat(tabla, \", \"))\n--[[\n* DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n]]\n\ndirectorio = {}\n\nfunction agregarContacto(name, pnum)\n    if directorio[name] then\n        print(\"El contacto ya existe\")\n    else\n        directorio[name] = pnum\n    end\nend\n\nfunction actualizarContacto(name, pnum)\n    if directorio[name] then\n        directorio[name] = pnum\n        print(\"Contacto actualizado\")\n    else\n        print(\"El contacto no existe\")\n    end\nend\n\nfunction eliminar_contacto(nombre)\n    if directorio[nombre] then\n        directorio[nombre] = nil\n        print(\"Contacto aliminado\")\n    else\n        print(\"Este contacto no existe\")\n    end    \nend\n\nfunction mostrarContacto()\n    print(\"Directorio\")\n    if next(directorio) == nil then\n        print(\"No hay contactos aun\")\n    else\n        for name, pnum in pairs(directorio) do\n            print(name.. \": \", pnum)\n        end\n    end\n    \nend\n\nwhile true do\n    \n    print(\"1) AGREGAR CONTACTO\")\n    print(\"2) Actualizar contacto\")\n    print(\"3) Eliminar contacto\")\n    print(\"4) Directorio\")\n    print(\"5) Salir\")\n\n    local input = io.read()\n    local opcion = tonumber(input)\n    \n    if opcion == 1 then\n        print(\"Agregar contacto\")\n        print(\"Nombre: \")\n        local name = io.read()\n        print(\"Numero: \")\n        local pnum = tonumber(io.read())\n        agregarContacto(name, pnum)\n    end\n    if opcion == 2 then\n        print(\"Actualizar contacto\")\n        print(\"Nombre\")\n        local name = io.read()\n        print(\"Numero\")\n        local pnum = tonumber(io.read())\n        actualizarContacto(name, pnum)\n    end\n    if opcion == 3 then\n        print(\"Borrar contacto\")\n        print(\"Contacto a borrar\")\n        local name = io.read()\n        eliminar_contacto(name)\n    end\n\n    if opcion == 4 then\n        print(\"Directorio\")\n        mostrarContacto()\n    end\n\n    if opcion == 5 then\n        break\n    end\nend\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/lua/ansuzgs.lua",
    "content": "-- Estructuras de datos en lua\n-- Lua solo tiene un tipo de dato compuesto: las tablas\n\n-- Definimos una tabla vacia\nmi_tabla = {}\n\n-- Le asignamos un valor a un campo\nmi_tabla[\"nombre\"] = \"Juan\"\nmi_tabla[\"apellido\"] = \"Perez\"\n\n-- Accedemos a un campo\nprint(mi_tabla[\"nombre\"])\n\n-- Actualizamos un campo\nmi_tabla[\"nombre\"] = \"Carlos\"\nprint(mi_tabla[\"nombre\"])\n\n-- Otra forma de acceder a un campo\nprint(mi_tabla.apellido)\n\n-- Definimos una tabla con campos\nmi_tabla2 = {nombre=\"Maria\", apellido=\"Gomez\"}\n\n-- Accedemos a un campo\nprint(mi_tabla2.nombre)\n\n-- Definimos una tabla con campos y una tabla anidada\nmi_tabla3 = {nombre=\"Pedro\", apellido=\"Gonzalez\", direccion = {calle=\"Av. Siempre Viva\", numero=1234}}\n\n-- Accedemos a un campo\nprint(mi_tabla3.direccion.calle)\n\n-- Eliminamos un valor de una tabla\nmi_tabla3.direccion.calle = nil\nprint(mi_tabla3.direccion.calle)\n\n-- Ordenamos una tabla que contiene numeros\nmi_tabla4 = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5}\ntable.sort(mi_tabla4)\nfor i, v in ipairs(mi_tabla4) do\n  print(i, v)\nend\n\n-- Definimos una tabla con varias personas y la Ordenamos\n-- por el campo nombre \npersonas = {\n  {nombre=\"Juan\", apellido=\"Perez\"},\n  {nombre=\"Maria\", apellido=\"Gomez\"},\n  {nombre=\"Pedro\", apellido=\"Gonzalez\"}\n}\ntable.sort(personas, function(a, b) return a.nombre < b.nombre end)\nfor i, v in ipairs(personas) do\n  print(i, v.nombre, v.apellido)\nend\n\n--[[\n--EXTRA\n--]]\n\n-- Agenda\n\nagenda = {}\n\nfunction agregar_contacto(nombre, telefono)\n  agenda[nombre] = telefono\nend\n\nfunction buscar_contacto(nombre)\n  return agenda[nombre]\nend\n\nfunction actualizar_contacto(nombre, telefono)\n  agenda[nombre] = telefono\nend\n\nfunction eliminar_contacto(nombre)\n  agenda[nombre] = nil\nend\n\n-- bucle infinito\nwhile true do\n  print(\"1. Agregar contacto\")\n  print(\"2. Buscar contacto\")\n  print(\"3. Actualizar contacto\")\n  print(\"4. Eliminar contacto\")\n  print(\"5. Salir\")\n  print(\"Opcion:\")\n  opcion = io.read(\"*n\", \"*l\")\n  if opcion == 1 then\n    print(\"Nombre:\")\n    nombre = io.read()\n    print(\"Telefono: \")\n    telefono = io.read()\n    agregar_contacto(nombre, telefono)\n  elseif opcion == 2 then\n    print(\"Nombre: \")\n    nombre = io.read()\n    telefono = buscar_contacto(nombre)\n    if telefono then\n      print(\"Telefono: \" .. telefono)\n    else\n      print(\"No se encontro el contacto\")\n    end\n  elseif opcion == 3 then\n    print(\"Nombre: \")\n    nombre = io.read()\n    print(\"Telefono: \")\n    telefono = io.read()\n    actualizar_contacto(nombre, telefono)\n  elseif opcion == 4 then\n    print(\"Nombre: \")\n    nombre = io.read()\n    eliminar_contacto(nombre)\n  elseif opcion == 5 then\n    break\n  end\nend\n\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/lua/edalmava.lua",
    "content": "-- Las estructuras de datos en Lua son las tablas\n\n-- Matrices\n\nlocal a = {}\nfor i = 1, 1000 do\n    a[i] = 0\nend\n\n-- Puede iniciar una matriz en el índice 0, 1 o cualquier otro valor:\n-- Sin embargo, es costumbre en Lua iniciar matrices con el índice 1\n\na = {}\nfor i = -5, 5 do\n    a[i] = 0\nend\n\nlocal squares = {1, 4, 9, 16, 25, 36, 49, 64, 81}\nprint(\"Cantidad de elementos de la matriz: \", #squares)  --[[\n  Si la tabla es una tabla secuencial (índices numéricos consecutivos, \n  comenzando desde 1), puedes usar el operador # para obtener el tamaño.\n]]\n\n--[[\n  Si la matriz tiene índices no consecutivos o mixtos (es decir, una tabla \n  no secuencial), puedes contar los elementos manualmente.\n]]\nlocal matriz = {10, 20, [5] = 50, [\"clave\"] = \"valor\"}\nlocal size = 0\nfor _ in pairs(matriz) do\n    size = size + 1\nend\nprint(size)\n\n-- Insertar elementos\na = {}\nprint(\"Insertando elementos\")\ntable.insert(a, \"Hola\")\ntable.insert(a, \"Mundo\")\ntable.insert(a, \"Lua\")\ntable.insert(a, 1, \"#\")\nprint(\"Número de elementos insertados: \", #a)\n\n-- Borrar elementos\nprint(\"Removiendo primer elemento\")\ntable.remove(a, 1)  -- Remueve el elemento de la posición 1\n--[[\nfor i = 1, #a do\n    print(a[i])\nend\n]]\n\nprint(table.concat(a, \" \"))\na = {5, 4, 1, 2, 3}\ntable.sort(a)\nprint(\"Organizando elementos: \", table.concat(a, \",\"))\n\nlocal agenda = {}\n\nfunction agregar_contacto()\n    print(\"Nombre: \")\n    local nombre = io.read()\n    print(\"Teléfono: \")\n    local telefono = io.read()\n    agenda[nombre] = telefono\nend\n\nfunction buscar_contacto()\n    print(\"Nombre: \")\n    local nombre = io.read()\n    if agenda[nombre] then\n        print(\"Teléfono: \" .. agenda[nombre])\n    else\n        print(\"No se encontro el contacto\")\n    end\nend\n\nfunction eliminar_contacto()\n    print(\"Nombre: \")\n    local nombre = io.read()\n    if agenda[nombre] then \n        agenda[nombre] = nil\n        print(\"Contacto eliminado\")\n    else\n        print(\"Contacto no encontrado\")\n    end\nend\n\nfunction actualizar_contacto()\n    print(\"Nombre: \")\n    local nombre = io.read()\n    if agenda[nombre] then\n        print(\"Teléfono: \")\n        local telefono = io.read()\n        agenda[nombre] = telefono\n        print(\"Contacto actualizado\")\n    else\n        print(\"Contacto no encontrado\")\n    end\nend\n\nlocal function menu()\n    while true do\n        print(\"\\n\\nMenú Principal\\n\")\n        print(\"1. Agregar nuevo contacto\")\n        print(\"2. Buscar contacto\")\n        print(\"3. Eliminar contacto\")\n        print(\"4. Actualizar contacto\")\n        print(\"5. Salir\")\n        print(\"\\nEscoja su opción: \")\n        local opcion = io.read(\"n\", \"l\")\n\n        if opcion == 1 then\n            agregar_contacto()\n        elseif opcion == 2 then\n            buscar_contacto()\n        elseif opcion == 3 then\n            eliminar_contacto()\n        elseif opcion == 4 then\n            actualizar_contacto()\n        elseif opcion == 5 then\n            break\n        end\n    end\nend\n\nmenu()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/lua/santyjl.lua",
    "content": "--[[\n/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n]]\n\nlocal tabla = { --equivalencia a lista\n    3,8,6,2,7,10,1,11\n}\n\nprint(\"\")\nprint(\"\\ntabla original : \" .. table.concat(tabla , \",\"))\n\n-- aunque la clase table es util , solo funciona para tablas de listas no para clave y valor\n-- su uso es mas recomendable para lista de numeros\n\ntable.insert(tabla , 20)\nprint(\"agregar valor a tabla : \" .. table.concat(tabla , \",\"))\n\ntable.remove(tabla , 1)\nprint(\"eliminar valor de tabla : \" .. table.concat(tabla , \",\"))\n\ntable.sort(tabla)\nprint(\"ordenar la tabla : \".. table.concat(tabla , \",\"))\n\ntabla[1] = 5\nprint(\"actualizar valor de tabla : \" .. table.concat(tabla , \",\") )\n\n\nlocal tabla2 = { -- equivalencia a Diccionarios o JSON\n    Erno_rubik = \"cubo3X3X3\",\n    Einstein = \"E = MC^2\",\n    Euler = \"e\",\n    Emmy_noether = \"Algebra\"\n}\n\n-- Para imprimir una tabla de tipo diccionario, necesitas iterar sobre sus pares clave-valor.\nlocal function mostra_json()\n    for clave, valor in pairs(tabla2) do\n        print(clave .. \" : \" .. valor)\n    end\nend\nprint(\"\\ntabla json original :\")\nmostra_json()\n\n-- Para agregar un nuevo par clave-valor, simplemente asigna el valor a la clave\ntabla2[\"steve_hawkings\"] = \"agujero negro\"\nprint(\"\\nDespues de agregar un nuevo par clave-valor:\")\nmostra_json()\n\n-- eliminar valor de json/tabla\n\ntabla2.Emmy_noether = nil -- nil significa nada\nprint(\"\\neliminando un valor del json\")\nmostra_json()\n\n-- actualización de json\ntabla2.Einstein = \"relatividad\"\ntabla2[\"Euler\"] = \"nodos\"       -- esta es otra forma de cambiar el valor , y si el valor no existe lo crea\nprint(\"\\nactualizacion de valores en el json\")\nmostra_json()\n\n-- extra\n\nlocal function busqueda(lista)\n    print(\"Ingrese el nombre : \")\n    local valor = io.read()\n    return lista[valor]\n\nend\n\nlocal function insercion(lista)\n    print(\"Ingresa el nombre del contacto a agregar : \")\n    local nombre = io.read(\"*l\")\n    print(\"Ingresa el numero del contacto : \")\n    local numero = io.read(\"*n\")\n    lista[nombre] = numero\n\nend\n\nlocal function eliminacion(lista)\n    print(\"Ingrese el nombre del contacto a eliminar : \")\n    local nombre = io.read()\n    lista[nombre] = nil\n\nend\n\nlocal function actualizacion(lista)\n    print(\"Ingrese el nombre del contacto : \")\n    local valor = io.read()\n    print(\"Ingrese el nuevo nombre del contacto  :\")\n    local nombre = io.read()\n    print(\"Ingrese el nuevo numero del usuario :\")\n    local numero = io.read()\n    lista[valor] = nil\n    lista[nombre] = numero\n\nend\n\nlocal function main ()\n    local agenda = {}\n    while true do\n\n        print(\"\\nBienvenido a tu agenda de contactos que vas hacer : \")\n        print(\"1.Agregar nuevo contacto\")\n        print(\"2.Buscar entre los contactos\")\n        print(\"3.actualizar un contacto \")\n        print(\"4.eliminar un contacto \")\n        print(\"5.salir de la agenda de contactos\")\n        print(\"elige conforme al indice : \")\n        local opcion = io.read(\"*n\")\n        io.read()\n\n        if opcion == 1 then\n            insercion(agenda)\n\n        elseif opcion == 2 then\n            local contacto = busqueda(agenda)\n            if contacto then\n                print(\"contacto : \" .. contacto)\n\n            else\n                print(\"contacto no existente\")\n            end\n\n        elseif opcion == 3  then\n            actualizacion(agenda)\n\n        elseif opcion == 4 then\n            eliminacion(agenda)\n\n        elseif opcion == 5 then\n            print(\"salistes de la agenda\")\n            break\n\n        else\n            print(\"opcion no disponible\")\n\n        end\n    end\nend\n\nmain()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/mql4/confley.mq4",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa una agenda de contactos por terminal. - (luego lo implementó xd)\n */\n\n//+------------------------------------------------------------------+\n//| Métodos de apoyo                                                 |\n//+------------------------------------------------------------------+\n// Imprimir un array unidimensional\nvoid PrintArray(int &arr[]) {\n    string output = \"\";\n    int size = ArraySize(arr);\n    for (int i = 0; i < size; i++) {\n        output += \"[\" + i + \"] \" + arr[i] + \", \";\n    }\n    Print(output);\n    Print(\"\");\n}\n\n// Imprimir una matriz (array multidimensional)\nvoid PrintMatrix(double &matrix[][]) {\n    for (int i = 0; i < ArrayRange(matrix, 0); i++) {\n        Print(\"Fila \", i, \": \", matrix[i][0], \", \", matrix[i][1]);\n    }\n    Print(\"\");\n}\n\n//+------------------------------------------------------------------+\n//| Declaración de estructuras y enumeraciones                      |\n//+------------------------------------------------------------------+\nenum OrderType {\n    BUY = 10,\n    SELL,       // Incrementa automáticamente el valor anterior (11)\n    PENDING = 30\n};\n\nstruct TradeInfo {\n    string symbol;       // Símbolo del instrumento\n    double lotSize;      // Tamaño del lote\n    OrderType type;      // Tipo de orden\n};\n\n//+------------------------------------------------------------------+\n//| Función principal                                                |\n//+------------------------------------------------------------------+\nvoid OnStart() {\n    // ** ARRAYS **\n    int array[4];\n    // ArrayResize(array, 4);  // Redimensionar a 3 elementos\n    array[0] = 50;\n    array[1] = 10;\n    array[2] = 30;\n    array[3] = 300;\n    Print(\"Array inicial:\");\n    PrintArray(array);\n\n    // Actualización\n    array[1] = 200;\n    Print(\"Array después de actualización:\");\n    PrintArray(array);\n\n    // Borrado (reduciendo tamaño)\n    ArrayResize(array, 3);\n    Print(\"Array después de borrado:\");\n    PrintArray(array);\n\n    // Ordenación\n    ArraySort(array);\n    Print(\"Array después de ordenación:\");\n    PrintArray(array);\n\n    // SERIES (Acceso inverso a datos históricos)\n    ArraySetAsSeries(array, true);  // Convertir en serie\n    Print(\"Array después de convertir a serie:\");\n    PrintArray(array);\n\n    // ** MATRICES **\n    double matrix[2][2] = {\n        {2.1, 2.2},\n        {1.1, 1.2},\n    };\n    Print(\"Matriz inicial:\");\n    PrintMatrix(matrix);\n\n    // Agregar una fila\n    ArrayResize(matrix, 3);  // Ahora tiene 3 filas\n    matrix[2][0] = 3.1;\n    matrix[2][1] = 3.2;\n    Print(\"Matriz después de agregar una fila:\");\n    PrintMatrix(matrix);\n\n    // Actualización\n    matrix[1][1] = 2.5;\n    Print(\"Matriz después de actualización:\");\n    PrintMatrix(matrix);\n\n    // Ordenamiento \n    ArraySort(matrix); \n    Print(\"Matriz después de ordenación: \");\n    PrintMatrix(matrix); \n\n    // ** STRUCTURES **\n    TradeInfo myTrade;\n    myTrade.symbol = \"EURUSD\";\n    myTrade.lotSize = 0.1;\n    myTrade.type = BUY;\n    Print(\"Información de Trade:\");\n    Print(\"Símbolo: \", myTrade.symbol, \", Lote: \", myTrade.lotSize, \", Tipo: \", EnumToString(myTrade.type));\n\n    // Actualización\n    myTrade.lotSize = 0.2;\n    Print(\"Información de Trade actualizada:\");\n    Print(\"Símbolo: \", myTrade.symbol, \", Lote: \", myTrade.lotSize);\n\n    // ** ENUMERATIONS **\n    OrderType orderType = SELL;\n    if (orderType == SELL) {\n        Print(\"Orden de tipo: \", EnumToString(orderType));\n    }\n}\n\n//+------------------------------------------------------------------+\n//| Observaciones finales                                            |\n//+------------------------------------------------------------------+\n/*\n1. Arrays (unidimensionales):\n    - No es dinámico, por lo que tienes que definir un tamaño al instanciar o cambiar su tamaño en ejecución. \n    - Se pueden redimensionar con `ArrayResize`.\n    - Los elementos que queden fuera del rango de redimensión serán eliminados.\n    - Se pueden ordenar con `ArraySort`.\n    - `ArraySort` solo funciona con elementos númericos. \n    - Convertir un array a \"serie\" cambia el acceso (índices invertidos).\n\n2. Matrices (multidimensionales):\n    - Solo la primera dimensión puede redimensionarse dinámicamente.\n    - La primera dimensión puede ser ordenada. \n\n3. Structures:\n    - Son útiles para agrupar datos heterogéneos.\n    - Las operaciones de actualización se hacen accediendo a los atributos.\n\n4. Enumerations:\n    - Útiles para definir listas de constantes con valores predefinidos y secuenciales.\n    - No se puede usar con strings \n\n5. Limitaciones del lenguaje:\n    - No se puede recibir entrada directamente del usuario a través del terminal.\n    - Faltan estructuras avanzadas como diccionarios y listas dinámicas.\n*/"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/nasm/evanz2608.s",
    "content": "; https://nasm.us\n\n\nSYS_exit: equ 60\nSYS_read: equ 0\nSYS_write: equ 1\nSYS_open   equ 2\nSYS_close  equ 3\nSTDIN: equ 0\nSTDOUT: equ 1\nSTDERR: equ 2\n\nO_CREAT:   equ 0q0100\nO_RDWR:    equ 2\nMODE:      equ 0q0666\n\n%macro get_offset 1\n  mov rax, %1\n  mov rdx, Contact_size\n  mul rdx\n%endmacro\n\n%define get_field(offset, field) Contacts + offset + Contact. %+ field\n\nextern memset\nextern printf\nglobal _start\n\nsection .text\n_start:\n\n  mov rdi, CLEAN_MSG\n  call printstring\n  mov rdi, printf_mask\n  mov rsi, [Contacts_index]\n  mov rdx, [Contacts_capacity]\n  call printf\n\n  mov rdi, MENU_MSG\n  call printstring\n\n  mov rdi, option\n  mov rsi, 1\n  call readstring\n\n  cmp byte [option], '1'\n  je .insert_contact\n  cmp byte [option], '2'\n  je .search_contact\n  cmp byte [option], '3'\n  je .update_contact\n  cmp byte [option], '4'\n  je .delete_contact\n  cmp byte [option], '5'\n  je .save_list\n  cmp byte [option], '6'\n  je _exit\n  jmp .bad_option\n\n.save_list:\n  mov rax, SYS_open\n  lea rdi, [filepath]\n  mov rsi, O_CREAT\n  or rsi, O_RDWR\n  mov rdx, MODE\n  syscall\n  cmp rax, 0\n  jb .failed\n  mov [fd], rax\n\n  mov rax, SYS_write\n  mov rdi, [fd]\n  lea rsi, [Contacts]\n  mov rdx, Contact_size * CONTACT_MAX\n  syscall\n\n  mov rax, SYS_close\n  mov rdi, [fd]\n  syscall\n  jmp _start\n.failed:\n  mov rdi, FAILED_MSG\n  call printstring\n  jmp _exit\n\n.insert_contact:\n  mov rdi, CLEAN_MSG\n  call printstring\n  mov rdi, INSERT_MENU\n  call printstring\n  cmp byte [Contacts_capacity], CONTACT_MAX\n  jae .array_full\n  mov rdi, NAME_MSG\n  call printstring\n  get_offset [Contacts_capacity]\n  lea rdi, [get_field(rax, name)]\n  mov rsi, 0x00\n  mov rdx, NAME_LEN\n  call memset\n  get_offset [Contacts_capacity]\n  lea rdi, [get_field(rax, name)]\n  mov rsi, NAME_LEN\n  call readstring\n  mov rdi, PHONE_MSG\n  call printstring\n  get_offset [Contacts_capacity]\n  lea rdi, [get_field(rax, phone)]\n  mov rsi, PHONE_LEN\n  call readstring\n  mov rax, [Contacts_capacity]\n  mov [Contacts_index], rax\n  inc rax\n  mov [Contacts_capacity], rax\n  jmp .insert_done\n.array_full:\n  mov rdi, FULL_ARRAY_MSG\n  call printstring\n.insert_done:\n  jmp _start\n\n.search_contact:\n  mov rdi, CLEAN_MSG\n  call printstring\n  mov rdi, SEARCH_MENU\n  call printstring\n  mov rdi, NAME_MSG\n  call printstring\n  mov rdi, input_buffer\n  mov rsi, NAME_LEN\n  call readstring\n  mov [Input_length], rax\n  xor rbx, rbx\n  mov qword [Contact_found], 0\n.loop_search:\n  cld\n  get_offset rbx\n  lea rdi, [get_field(rax, name)]\n  lea rsi, [input_buffer]\n  mov rcx, [Input_length]\n  repe cmpsb\n  je .search_found\n  inc rbx\n  cmp rbx, [Contacts_capacity]\n  jl .loop_search\n  jae .search_not_found\n.search_found:\n  mov [Contact_found], rbx\n  mov rdi, FOUND_MSG\n  call printstring\n  mov rdi, NAME_MSG\n  call printstring\n  get_offset [Contact_found]\n  lea rdi, [get_field(rax, name)]\n  call printstring\n  mov rdi, LINEFEED\n  call printstring\n  mov rdi, PHONE_MSG\n  call printstring\n  get_offset [Contact_found]\n  lea rdi, [get_field(rax, phone)]\n  call printstring\n  mov rdi, LINEFEED\n  call printstring\n  lea rdi, [rsp]\n  mov rsi, 1\n  call readstring\n  jmp _start\n.search_not_found:\n  mov rdi, NOT_FOUND_MSG\n  call printstring\n  lea rdi, [rsp]\n  mov rsi, 1\n  call readstring\n  jmp _start\n\n.update_contact:\n  mov rdi, CLEAN_MSG\n  call printstring\n  mov rdi, UPDATE_MENU\n  call printstring\n  mov rdi, NAME_UPDATE_MSG\n  call printstring\n  mov rdi, input_buffer\n  mov rsi, 0x00\n  mov rdx, NAME_LEN + 1\n  call memset\n  mov rdi, input_buffer\n  mov rsi, NAME_LEN\n  call readstring\n  mov [Input_length], rax\n  xor rbx, rbx\n  mov qword [Contact_found], 0\n.update_search:\n  cld\n  get_offset rbx\n  lea rdi, [get_field(rax, name)]\n  lea rsi, [input_buffer]\n  mov rcx, [Input_length]\n  repe cmpsb\n  je .update_found\n  inc rbx\n  cmp rbx, [Contacts_capacity]\n  jl .update_search\n  jae .update_not_found\n.update_found:\n  mov [Contact_found], rbx\n  mov rdi, NAME_MSG\n  call printstring\n  get_offset [Contact_found]\n  lea rdi, [get_field(rax, name)]\n  mov rsi, NAME_LEN\n  call readstring\n  mov rdi, PHONE_MSG\n  call printstring\n  get_offset [Contact_found]\n  lea rdi, [get_field(rax, phone)]\n  mov rsi, PHONE_LEN\n  call readstring\n  mov rdi, UPDATED_MSG\n  call printstring\n  lea rdi, [rsp]\n  mov rsi, 1\n  call readstring\n  jmp _start\n.update_not_found:\n  mov rdi, NOT_FOUND_MSG\n  call printstring\n  lea rdi, [rsp]\n  mov rsi, 1\n  call readstring\n  jmp _start\n\n.delete_contact:\n  mov rdi, DELETE_MENU\n  call printstring\n  mov rdi, NAME_DELETE_MSG\n  call printstring\n  mov rdi, input_buffer\n  mov rsi, 0x00\n  mov rdx, NAME_LEN + 1\n  call memset\n  mov rdi, input_buffer\n  mov rsi, NAME_LEN\n  call readstring\n  mov [Input_length], rax\n  xor rbx, rbx\n  mov qword [Contact_found], 0\n.delete_search:\n  cld\n  get_offset rbx\n  lea rdi, [get_field(rax, name)]\n  lea rsi, [input_buffer]\n  mov rcx, [Input_length]\n  repe cmpsb\n  je .delete_found\n  inc rbx\n  cmp rbx, [Contacts_capacity]\n  jl .delete_search\n  jae .delete_not_found\n.delete_found:\n  mov [Contact_found], rbx\n.delete_move_loop:\n  mov rbx, [Contact_found]\n  cmp rbx, [Contacts_capacity]\n  jae .delete_done\n  get_offset rbx\n  lea rdi, [Contacts + rax]\n  inc rbx\n  get_offset rbx\n  lea rsi, [Contacts + rax]\n  mov rcx, Contact_size\n  rep movsb\n  inc qword [Contact_found]\n  cmp qword [Contact_found], CONTACT_MAX\n  jl .delete_move_loop\n  jmp .delete_done\n.delete_not_found:\n  mov rdi, NOT_FOUND_MSG\n  call printstring\n.delete_done:\n  lea rdi, [rsp]\n  mov rsi, 1\n  call readstring\n  jmp _start\n\n.bad_option:\n  mov rdi, BAD_OPTION_MENU\n  call printstring\n  lea rdi, [rsp]\n  mov rsi, 1\n  call readstring\n  jmp _start\n\n_exit:\n  mov rax, SYS_exit\n  xor rdi, rdi\n  syscall\n\n\nprintstring:\n  mov rbx, rdi\n  xor r12, r12\n.print_char:\n  cmp byte [rbx + r12], 0x00\n  je .print_done\n  mov rax, SYS_write\n  mov rdi, STDOUT\n  lea rsi, [rbx + r12]\n  mov rdx, 1\n  syscall\n  inc r12\n  jmp .print_char\n.print_done:\n  ret\n\nreadstring:\n  enter 1, 0\n  mov rbx, rdi\n  mov r13, rsi\n  xor r12, r12\n.read_character:\n  mov rax, SYS_read\n  mov rdi, STDIN\n  lea rsi, byte [rbp]\n  mov rdx, 1\n  syscall\n  mov al, byte [rbp]\n  cmp al, 0x0A\n  je .read_done\n  cmp r12, r13\n  inc r12\n  jae .read_character\n  mov byte [rbx], al\n  inc rbx\n  jmp .read_character\n.read_done:\n  mov byte [rbx], 0x00\n  mov rax, r12\n  leave\n  ret\n\nsection .rodata\n  NAME_LEN: equ 50\n  PHONE_LEN: equ 10\n  CONTACT_MAX: equ 100\n  CLEAN_MSG:\n    db  0x1B, \"[H\", 0x1B, \"[0J\", 0x00\n  MENU_MSG:\n    db  \"Agenda de Contactos\", 0x0A\n    db  \" 1. Insertar contacto.\", 0x0A\n    db  \" 2. Buscar contacto.\", 0x0A\n    db  \" 3. Actualizar contacto.\", 0x0A\n    db  \" 4. Eliminar contacto.\", 0x0A\n    db  \" 5. Guardar lista.\", 0x0A\n    db  \" 6. Salir.\", 0x0A\n    db  0x0A, \"Seleccione una opcion: \", 0x00\n\n  INSERT_MENU: db \"Insertar contacto\", 0x0A, 0x00\n  SEARCH_MENU: db \"Buscar contacto\", 0x0A, 0x00\n  UPDATE_MENU: db \"Actualizar contacto\", 0x0A, 0x00\n  DELETE_MENU: db \"Eliminar contacto\", 0x0A, 0x00\n  BAD_OPTION_MENU: db \"Opcion incorrecta. Por favor elija una opcion valida.\", 0x0A, 0x00\n\n  NAME_MSG: db \"  Nombre: \", 0x00\n  NAME_UPDATE_MSG: db \"  Nombre del contacto a actualizar: \", 0x00\n  NAME_DELETE_MSG: db \"  Nombre del contacto a eliminar: \", 0x00\n  PHONE_MSG: db \"  Telefono: \", 0x00\n  FULL_ARRAY_MSG: db \"No queda espacio suficiente para añadir mas contactos.\", 0x0A, \"Presione una tecla para continuar.\", 0x00\n  FOUND_MSG: db \"Contacto encontrado\", 0x0A, 0x00\n  NOT_FOUND_MSG: db \"Contacto no encontrado\", 0x00\n  UPDATED_MSG: db \"Contacto actualizado\", 0x00\n  DELETED_MSG: db \"Contacto eliminado\", 0x00\n  FAILED_MSG: db \"Error al abrir el archivo.\", 0x00\n  LINEFEED: db 0x0A, 0x00\n  printf_mask: db \"Index: %d - Capacity: %d\", 0x0A, 0x00\n  filepath: db \"./list.bin\", 0x00\n\nsection .data\n  struc Contact\n    .name: resb NAME_LEN + 1\n    .phone: resb PHONE_LEN + 1\n  endstruc\n\n  Input_length: dq 0\n  option: dq 0\n  Contacts_index: dq 0\n  Contacts_capacity: dq 0\n  Contact_found: dq 0\n  offset1: dq 0\n  offset2: dq 0\n  fd: dq 0\n\nsection .bss\n  input_buffer: resb NAME_LEN + 1\n  Contacts: resb CONTACT_MAX * Contact_size\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/ocaml/luishendrix92.ml",
    "content": "open Printf\n\n(* OCaml offers {b 6} main data structures (the rest are containers that serve\n   a particular task, such as [option]) that can be used to create even more\n   data structures, along with ADTs ({e algebraic data types}) which are\n   heavily useful in creating mutually recursive structures such as trees.\n\n   + List (singly-linked list)\n   + Tuple (2 or more elements)\n   + Array (mutable array type)\n   + Map (strongly-typed immutable key-value pair)\n   + Hashtbl (weakly-typed mutable hashmaps)\n   + Set (immutable typed set of unique items)\n   + Lazy Seq (lazy sequences, similar to streams)\n*)\n\n(** [remove_idx i l] removes the element at index [i] from list [l]. If [i]\n    is not part of [l], the list doesn't change. *)\nlet remove_idx i l = List.filteri (fun idx _ -> idx <> i) l\n\n(** [replace_idx i l e] replaces the element at index [i] from list [l] with a\n    provided element [e]. If [i] is not in [l], the list doesn't change. *)\nlet replace_idx i l e = List.mapi (fun idx elt -> if idx = i then e else elt) l\n;;\n\nlet my_list = [ 50; -4; 60; 0; 12; 1 ] in\nlet my_list = 40 :: my_list in\nlet my_list = List.cons 30 my_list in\nlet my_list = List.append my_list [ 2; 3 ] in\nlet my_list = my_list @ [ 4; 5 ] in\nlet my_list = remove_idx 4 my_list in\nlet my_list = replace_idx 0 my_list 100 in\nlet my_list = List.sort Int.compare my_list in\nList.iter (fun n -> printf \"my_list: %d.\\n\" n) my_list\n\n(* Tuples can't be sorted and they don't need to, their sole purpose is to\n   represent a finite-length ([2] or [3]) set of elements where their position\n   matters (for example, in a coordinate). They can be easily pattern-matched.\n   In functional programming languages, Tuples are also functors that can be\n   mapped, which means, change the contents of the {e nth} element or all.\n   Tuples are also not meant to have their elements deleted.\n*)\n\nmodule Core = struct\n  module Tuple3 = struct\n    let map ~f t3 =\n      match t3 with\n      | a, b, c -> f a, f b, f c\n    ;;\n  end\nend\n;;\n\nlet my_r3_vector = 4.5, 2.0, 1.8 in\nlet my_r3_vector = Core.Tuple3.map my_r3_vector ~f:Float.ceil in\nmatch my_r3_vector with\n| x, y, z -> printf \"my_r3_vector: (%f, %f, %f).\\n\" x y z\n;;\n\n(* Arrays are mutable, sequential blocks of information. Updating elements\n   is constant time compared to linked lists, same as accessing by index.\n   The tradeoff is that removing elements is expensive due to element\n   shifting. Replacing an element at index [n] returns [unit].\n*)\n\nlet my_arr = [| 5; 4; 3; 2; 1 |] in\nlet my_arr = Array.append my_arr [| 0 |] in\nlet my_arr = Array.append (Array.sub my_arr 1 2) (Array.sub my_arr 3 2) in\nmy_arr.(0) <- 10;\nArray.sort Int.compare my_arr;\nArray.iter (fun n -> printf \"my_arr: %d.\\n\" n)\n\n(* Maps are associations between a key and a value, the key's type must be\n   provided to a functor module first in order to make your own [Map].\n   According to the documentation, this module is implemented with a\n   balanced binary tree which greatly improves search and insertion\n   performance (instead of [O(n)] it's now [O(log n)]).\n*)\n\nmodule Stock = Map.Make (String);;\n\nlet my_stock = Stock.empty in\nlet my_stock = Stock.add \"AAPL\" 182.68 my_stock in\nlet my_stock = Stock.add \"NFLX\" 480.33 my_stock in\nlet my_stock = Stock.add \"AMZN\" 150.71 my_stock in\nlet my_stock = Stock.remove \"AAPL\" my_stock in\nlet my_stock = Stock.update \"NFLX\" (Option.map Float.floor) my_stock in\nStock.iter (fun k v -> printf \"Stock %s -> %f\" k v) my_stock\n;;\n\n(* Hash Tables are imperative (mutable) and are extremely useful for dynamic\n   programming algorithms that require some sort of cache. It's also used\n   in lookups, databases, and they provide constant time search. But\n   collisions can happen and they are as good as the hashing function.\n*)\n\nlet my_hash = Hashtbl.create 10 in\nbegin\n  Hashtbl.add my_hash 1.5 \"One point five\";\n  Hashtbl.add my_hash 5.0 \"Five point zero\";\n  Hashtbl.remove my_hash 1.5;\n  Hashtbl.replace my_hash 5.0 \"Five point'o\";\n  Hashtbl.iter (fun k v -> printf \"my_hash: %f=%s.\\n\" k v) my_hash\nend\n\n(* The purpose of a set is to contain unique elements; this means, inserting\n   an element that already exists, will not do anything. Sets are also\n   efficient in checking for existance. It also provides functions that\n   represent set operations such as intersection, difference, etc.\n*)\n\nmodule IntSet = Set.Make (Int);;\n\nlet my_set = IntSet.empty in\nlet my_set = IntSet.add 5 my_set in\nlet my_set = IntSet.add 2 my_set in\nlet my_set = IntSet.add 7 my_set in\nlet my_set = IntSet.add 1 my_set in\nlet my_set = IntSet.remove 1 my_set in\nlet my_set = IntSet.inter (IntSet.of_list [ 7; 3; 2 ]) my_set in\nlet my_set = IntSet.to_list my_set |> List.sort Int.compare |> IntSet.of_list in\nIntSet.iter (fun n -> printf \"my_set: %d.\\n\" n) my_set;\nprintf \"Is 2 in the my_set? %b.\\n\" (IntSet.mem 0 my_set)\n;;\n\n(* Sequences are lazy and sequential (as their name suggest), insertion and\n   deletion are familiar if you've worked with lists, so is mapping and\n   folding. Sequences can also represent an infinite set of data, which won't\n   be used until it's required. Common opeartions are [take] and [drop].\n*)\n\nlet my_seq = Seq.init 1_000_000_000_000 Int.succ in\nlet my_seq = Seq.filter (fun n -> n mod 2 = 0) my_seq in\nlet my_seq = Seq.take 3 my_seq in\nlet my_seq = Seq.cycle my_seq in\nlet my_seq = Seq.take 10 my_seq in\nSeq.iter (fun n -> printf \"my_seq: %d.\\n\" n) my_seq\n\n(* Optional challenge *)\n\nmodule ContactBook = struct\n  module StringMap = Map.Make (String)\n\n  type t = string StringMap.t\n\n  let is_valid_phone phone =\n    let len = String.length phone in\n    let all_numeric phone =\n      String.to_seq phone\n      |> Seq.for_all (fun c ->\n        match c with\n        | '0' .. '9' -> true\n        | _ -> false)\n    in\n    all_numeric phone && len >= 10 && len <= 12\n  ;;\n\n  let create () = StringMap.empty\n  let add = StringMap.add\n  let remove = StringMap.remove\n  let find = StringMap.find_opt\n  let count = StringMap.cardinal\n  let show = StringMap.iter (fun name phone -> printf \"- %s (#%s)\\n\" name phone)\n\n  let update name new_name =\n    StringMap.update name (Option.map (fun _ -> new_name))\n  ;;\nend\n\nlet prompt text =\n  print_string text;\n  Out_channel.flush Out_channel.stdout;\n  In_channel.input_line In_channel.stdin |> Option.value ~default:\"\"\n;;\n\nlet prompt_char text =\n  try String.get (prompt text) 0 with\n  | _ -> '0'\n;;\n\n(* I find the Elm architecture appropriate for TUIs (terminal user interfaces)\n   so I'll try to replicate it here and see how it works.\n   ------------------------------------------------------\n   https://guide.elm-lang.org/architecture/\n*)\n\nlet init = ContactBook.create ()\n\ntype msg =\n  | InsertContact of (string * string)\n  | UpdateContact of (string * string)\n  | DeleteContact of string\n\nlet update msg model =\n  match msg with\n  | InsertContact (name, phone) -> ContactBook.add name phone model\n  | UpdateContact (name, newPhone) -> ContactBook.update name newPhone model\n  | DeleteContact name -> ContactBook.remove name model\n;;\n\ntype route =\n  | MainMenu\n  | Insertion\n  | Deletion\n  | Updating\n  | ListAll\n  | Search\n  | Exit\n\nlet main_menu_view model =\n  begin\n    print_endline \"\\nMy Personal Contact Book\";\n    print_endline \"------------------------\";\n    printf \"Number of contacts: %d\\n\" (ContactBook.count model);\n    print_endline \"\\n1- Add new contact.\";\n    print_endline \"2- Delete existing contact.\";\n    print_endline \"3- Update existing contact.\";\n    print_endline \"4- List all contacts.\";\n    print_endline \"5- Search for a contact.\";\n    print_endline \"6- Exit the application.\";\n    match prompt_char \"\\nChoose an option: \" with\n    | '1' -> Insertion, model\n    | '2' -> Deletion, model\n    | '3' -> Updating, model\n    | '4' -> ListAll, model\n    | '5' -> Search, model\n    | '6' -> Exit, model\n    | _ ->\n      print_endline \"\\nInvalid option, try again...\\n\";\n      MainMenu, model\n  end\n;;\n\nlet insertion_view model =\n  let name = prompt \"\\nContact Full Name: \" in\n  let phone = prompt \"Contact Phone: \" in\n  match name, phone with\n  | _, \"\" | \"\", _ ->\n    print_endline \"\\nInvalid name or phone number; try again!\";\n    Insertion, model\n  | name, phone ->\n    if ContactBook.is_valid_phone phone\n    then (\n      printf \"\\n%s has been successfully added to contacts :)\\n\" name;\n      MainMenu, update (InsertContact (name, phone)) model)\n    else (\n      print_endline \"\\nPhone must be of length 10-12 and have only numbers.\";\n      Insertion, model)\n;;\n\nlet deletion_view model =\n  let name = prompt \"\\nName of the contact you want to delete: \" in\n  (match ContactBook.find name model with\n   | Some _ -> printf \"\\n%s successfully removed!\\n\" name\n   | _ -> printf \"\\n%s was not found in the contact book...\\n\" name);\n  MainMenu, update (DeleteContact name) model\n;;\n\nlet list_all_view model =\n  ContactBook.show model;\n  MainMenu, model\n;;\n\nlet updating_view model =\n  let name = prompt \"\\nName of the contact you want to update: \" in\n  let new_phone = prompt \"Type the new phone number for this contact: \" in\n  (match ContactBook.find name model with\n   | Some phone ->\n     printf \"\\n%s's phone updated from %s to %s!\\n\" name phone new_phone\n   | _ -> printf \"\\n%s was not found in the contact book...\\n\" name);\n  MainMenu, update (UpdateContact (name, new_phone)) model\n;;\n\nlet search_view model =\n  let name = prompt \"\\nName of the contact you want to find: \" in\n  (match ContactBook.find name model with\n   | Some phone -> printf \"\\nFound [%s] with phone #(%s)\\n\" name phone\n   | _ -> printf \"\\n%s was not found in the contact book...\\n\" name);\n  MainMenu, model\n;;\n\nlet rec app_loop route model =\n  let next_route, new_model =\n    match route with\n    | MainMenu -> main_menu_view model\n    | Insertion -> insertion_view model\n    | Deletion -> deletion_view model\n    | Updating -> updating_view model\n    | ListAll -> list_all_view model\n    | Search -> search_view model\n    | Exit -> exit 0\n  in\n  app_loop next_route new_model\n;;\n\napp_loop MainMenu init"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/pascal/miguelex.pas",
    "content": "program miguelex;\n\nconst\n  MaxContactos = 100; { Lo usaremos para el ejercicio extra }\n\ntype\n    tRegistro = record\n        nombre: String[20];\n        edad: Integer;\n        direccion: String[50];\n        telefono: String[9];\n    end;\n\n    Contacto = record { Lo usaremos para el ejercicio extra }\n      Nombre: string;\n      Telefono: string;\n    end;\n\nvar\n\n    ejemploArray: array[1..10] of Integer;\n    i, j, aux: Integer;\n    cadena : String[20];\n    r: tRegistro;\n    c: set of 1..10;\n    Agenda: array[1..MaxContactos] of Contacto; { Lo usaremos para el ejercicio extra }\n    NumContactos: integer; { Lo usaremos para el ejercicio extra }\n\nprocedure MostrarMenu;\nbegin\n  writeln('1. Insertar contacto');\n  writeln('2. Buscar contacto');\n  writeln('3. Actualizar contacto');\n  writeln('4. Eliminar contacto');\n  writeln('5. Mostrar todos los contactos');\n  writeln('6. Salir');\nend;\n\nprocedure InsertarContacto;\nvar\n  NuevoContacto: Contacto;\n  TelefonoValido: Boolean;\nbegin\n  writeln('Ingrese el nombre del contacto:');\n  readln(NuevoContacto.Nombre);\n\n  repeat\n    writeln('Ingrese el número de teléfono:');\n    readln(NuevoContacto.Telefono);\n\n    // Validar que el número de teléfono sea numérico y tenga menos de 12 dígitos\n    // (o el número de dígitos que prefieras)\n    Val(NuevoContacto.Telefono, NumContactos, TelefonoValido);\n\n    if (not TelefonoValido) or (Length(NuevoContacto.Telefono) > 11) then\n      writeln('Número de teléfono no válido. Introduce nuevamente.');\n  until TelefonoValido;\n\n  if NumContactos < MaxContactos then\n  begin\n    NumContactos := NumContactos + 1;\n    Agenda[NumContactos] := NuevoContacto;\n    writeln('Contacto insertado correctamente.');\n  end\n  else\n    writeln('La agenda está llena. Elimina algunos contactos antes de agregar nuevos.');\nend;\n\nprocedure BuscarContacto;\nvar\n  Busqueda: string;\n  Encontrado: Boolean;\n  i: Integer;\nbegin\n  writeln('Ingrese el nombre o parte del nombre del contacto a buscar:');\n  readln(Busqueda);\n\n  Encontrado := False;\n  for i := 1 to NumContactos do\n  begin\n    if Pos(upcase(Busqueda), upcase(Agenda[i].Nombre)) > 0 then\n    begin\n      writeln('Nombre: ', Agenda[i].Nombre);\n      writeln('Teléfono: ', Agenda[i].Telefono);\n      Encontrado := True;\n    end;\n  end;\n\n  if not Encontrado then\n    writeln('Contacto no encontrado.');\nend;\n\nprocedure ActualizarContacto;\nvar\n  NombreActualizar, NuevoTelefono: string;\n  i: Integer;\n  Encontrado: Boolean;\n  TelefonoValido: Boolean;\nbegin\n  writeln('Ingrese el nombre del contacto que desea actualizar:');\n  readln(NombreActualizar);\n\n  Encontrado := False;\n  for i := 1 to NumContactos do\n  begin\n    if upcase(Agenda[i].Nombre) = upcase(NombreActualizar) then\n    begin\n      repeat\n        writeln('Ingrese el nuevo número de teléfono:');\n        readln(NuevoTelefono);\n\n        Val(NuevoTelefono, NumContactos, TelefonoValido);\n\n        if (not TelefonoValido) or (Length(NuevoTelefono) > 11) then\n          writeln('Número de teléfono no válido. Introduce nuevamente.');\n      until TelefonoValido;\n\n      Agenda[i].Telefono := NuevoTelefono;\n      writeln('Contacto actualizado correctamente.');\n      Encontrado := True;\n    end;\n  end;\n\n  if not Encontrado then\n    writeln('Contacto no encontrado.');\nend;\n\nprocedure EliminarContacto;\nvar\n  NombreEliminar: string;\n  i: Integer;\n  Encontrado: Boolean;\nbegin\n  writeln('Ingrese el nombre del contacto que desea eliminar:');\n  readln(NombreEliminar);\n\n  Encontrado := False;\n  for i := 1 to NumContactos do\n  begin\n    if upcase(Agenda[i].Nombre) = upcase(NombreEliminar) then\n    begin\n      Agenda[i] := Agenda[NumContactos];\n      NumContactos := NumContactos - 1;\n      writeln('Contacto eliminado correctamente.');\n      Encontrado := True;\n    end;\n  end;\n\n  if not Encontrado then\n    writeln('Contacto no encontrado.');\nend;\n\nprocedure MostrarTodosLosContactos;\nvar\n  i: Integer;\nbegin\n  writeln('Lista de contactos:');\n  for i := 1 to NumContactos do\n  begin\n    writeln('Nombre: ', Agenda[i].Nombre);\n    writeln('Teléfono: ', Agenda[i].Telefono);\n    writeln('--------------');\n  end;\nend;\n\n\nvar\n  Opcion: integer;\n\nbegin  \n    writeln('Ejemplos con arrays');\n    writeln;\n\n    writeln('Vamos a introducir 5 numeros aleatorios entre el 1 y 10');\n    \n    for i := 1 to 5 do\n        ejemploArray[i] := random(10) + 1;\n\n    writeln;\n\n    writeln('Ahora vamos a mostrarlos');\n    writeln;\n    \n    for i := 1 to 5 do\n        writeln('Posicion ', i, ' valor ', ejemploArray[i]);\n    writeln;\n\n    writeln('Añadimos un nuevo numero al final');\n    ejemploArray[6] := 100;\n\n    writeln('Ahora vamos a mostrarlos');\n    writeln;\n\n    for i := 1 to 6 do\n        writeln('Posicion ', i, ' valor ', ejemploArray[i]);\n    writeln;\n\n    writeln('Vamos a eliminar al elemento en la posicion 2');\n    writeln;\n\n    for i := 2 to 6 do\n        ejemploArray[i] := ejemploArray[i + 1];\n    \n    writeln('Una vez eliminado el elemento en la posicion 2');\n    writeln;\n\n    for i := 1 to 5 do\n        writeln('Posicion ', i, ' valor ', ejemploArray[i]);\n    writeln;\n\n    { Vamos a ordenar el array de menor a mayor }\n    for i := 1 to 5 do\n        for j := 1 to 5 do\n            if ejemploArray[i] < ejemploArray[j] then\n            begin\n                aux := ejemploArray[i];\n                ejemploArray[i] := ejemploArray[j];\n                ejemploArray[j] := aux;\n            end;\n    \n    writeln('Ordenados del menor al mayor:');\n    for i := 1 to 5 do\n        writeln('Posicion ', i, ' valor ', ejemploArray[i]);\n    writeln;\n\n    WriteLn('Se le nota los años a Pascal y no te da las facilidades de otros lenguajes para la ordenacion, por ejemplo, teniendo que hacerla de un modo mas manual');\n    writeln;\n\n    { Ejemplo con cadenas }\n    writeln('Ejemplos con cadenas');\n\n    writeln('Vamos a introducir una cadena');\n    writeln;\n    cadena := 'Miguelex';\n\n    writeln('Vamos a mostrarla');\n    writeln;\n    writeln(cadena);\n    writeln;\n\n    writeln('Vamos a mostrarla al reves');\n    writeln;\n    for i := length(cadena) downto 1 do\n        write(cadena[i]);\n    writeln;\n\n    { Vamos a mostrar la longitud de la cadena }\n    writeln('La longitud de la cadena es ', length(cadena));\n    writeln;\n\n    { Vamos a mostrar la cadena en mayusculas }\n    writeln('La cadena en mayusculas es ', upcase(cadena));\n    writeln;\n\n    { Vamos a mostrar la cadena en minusculas } \n    writeln('La cadena en minusculas es ', lowercase(cadena));\n    writeln;\n\n    { Vamos a añadir un caracter a la cadena }\n    writeln('Vamos a añadir un caracter a la cadena');\n    writeln;\n    cadena := cadena + 'a';\n    writeln('La cadena ahora es ', cadena);\n    writeln;\n\n    { Vamos a eliminar un caracter a la cadena }\n    writeln('Vamos a eliminar un caracter a la cadena');\n    writeln;\n    cadena := copy(cadena, 1, length(cadena) - 1);\n    writeln('La cadena ahora es ', cadena);\n    writeln;\n\n    { Ejemplo con registros }\n    writeln('Ejemplos con registros');\n    writeln;\n    r.nombre := 'Pepe';\n    r.edad := 20;\n    r.direccion := 'Calle de la piruleta';\n    r.telefono := '123456789';\n    \n    writeln('Vamos a mostrar el registro');\n    writeln;\n    writeln('Nombre: ', r.nombre);\n    writeln('Edad: ', r.edad);\n    writeln('Direccion: ', r.direccion);\n    writeln('Telefono: ', r.telefono);\n    writeln;\n\n    { Ejemplo con conjuntos }\n\n    writeln('Ejemplos con conjuntos');\n    writeln;\n    writeln('Vamos a crear un conjunto con los numeros del 1 al 10');\n    writeln;\n    \n    for i := 1 to 10 do\n        write(i, ' ');\n    writeln;\n   \n    c := [1..10];\n    writeln('Vamos a mostrar el conjunto');\n    writeln;\n    for i := 1 to 10 do\n        if i in c then\n            write(i, ' ');\n    writeln;\n    \n    writeln('Vamos a añadir el 11 al conjunto');\n    writeln;\n    c := c + [11];\n    \n    writeln('Vamos a mostrar el conjunto');\n    writeln;\n    for i := 1 to 12 do\n        if i in c then\n            write(i, ' ');\n    writeln;\n    \n    writeln('Vamos a eliminar el 11 del conjunto');\n    writeln;\n    c := c - [11];\n    \n    writeln('Vamos a mostrar el conjunto');\n    writeln;\n    for i := 1 to 10 do\n        if i in c then\n            write(i, ' ');\n    writeln;\n    \n    WriteLn('Para finalizar, vamos a ver el ejercicio extra');\n    writeln;\n\n    NumContactos := 0;\n\n  repeat\n    MostrarMenu;\n    writeln('Ingrese el número de la opción que desea realizar:');\n    readln(Opcion);\n\n    case Opcion of\n      1: InsertarContacto;\n      2: BuscarContacto;\n      3: ActualizarContacto;\n      4: EliminarContacto;\n      5: MostrarTodosLosContactos;\n      6: writeln('Programa finalizado.');\n    else\n      writeln('Opción no válida. Inténtelo de nuevo.');\n    end;\n\n  until Opcion = 6;\n\nend.\n    \n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/php/CeciliaPorras01.php",
    "content": "<?php /*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\n\n //Listas \n\n $my_lists = array(\"Cecilia\", \"Porras\", \"Gonzalez\", \"Porras\", \"Torres\");\n print_r($my_lists);\n\n array_push($my_lists, \"Martha\");//Inserción\nprint_r($my_lists);\n\nunset($my_lists[2]); // Eliminación\nprint_r($my_lists);\n\n$my_lists[1] = \"Porrasssss\"; // Actualización\nprint_r($my_lists);\n\nprint_r($my_lists[5]);//Acceso\n\nsort($my_lists); //Ordenación\nprint_r($my_lists);\n\n\n//Tuplas\n$my_tuples = array(\"Cecilia\", \"Porras\", \"@porrasceci\", \"23\");\nprint_r($my_tuples[3]);//Acceso\n\nsort($my_tuples);//Ordenación\nprint_r($my_tuples);\n\n\n\n//Diccionarios\n$my_dict = array(\"Nombre\" => \"Cecilia\", \"Apellido\" => \"Porras\", \"Edad\" => \"23\", \"Twitter\" => \"@porrasceci\");\nprint_r($my_dict[\"Edad\"]);//Acceso\n\n$my_dict[\"Edad\"] = \"24\";//Actualización\nprint_r($my_dict[\"Edad\"]);\n\nunset($my_dict[\"Twitter\"]);//Eliminación\nprint_r($my_dict);\n\n$my_dict[\"Telefono\"] = \"1234567890\";//Inserción\nprint_r($my_dict);\n\n\n\n\n//Extra \n\n$agenda =[];\n\n    function contacts(){\n\n        global $agenda;\n\n        while (true) {\n         \n        print \"Bienvenido a la agenda de contactos 📕\\n  \";\n        print \"Selecciona una opción:\\n\";\n        print \"1.- Buscar contacto 🔎\\n\";\n        print \"2.- Insertar contacto ➕\\n\";\n        print \"3.- Actualizar contacto 👲🏽\\n\";\n        print \"4.- Eliminar contacto 🗑️\\n\";\n        print \"5.- Salir\\n\";\n\n        $option = readline(\"Opción: \"); \n\n            switch($option){\n                case 1:     \n                    print  \"Has elegido: Buscar contacto 🔎\\n\";\n                        searchContact($agenda);\n                    break;\n                case 2:\n                    print  \"Has elegido: Insertar contacto ➕\\n\";\n                        addContact($agenda);\n                    break;\n                case 3:\n                    print  \"Has elegido: Actualizar contacto 👲🏽\\n\";\n                        updContact($agenda);\n                    break;\n                case 4:\n                    print  \"Has elegido: Eliminar contacto 🗑️\\n\";\n                    break;\n                case 5:\n                    print  \"Saliendo... 👋\\n\";\n                    exit;\n                default:\n                    print  \"❌ Opción no válida. Inténtalo de nuevo.\\n\";\n                    break;\n            }\n        }\n    }\n\n    function getContactInfo() {\n        print \"Introduce el nombre del contacto: \";\n        $name = readline();\n        print \"Introduce el número de teléfono: \";\n        $phone = readline();\n\n        if ($name == \"\" || !preg_match(\"/^[a-zA-Z\\s]+$/\", $name)) {\n            print \"❌ Debes introducir un nombre válido (solo letras y espacios).\\n\";\n            return null;\n        } elseif ($phone == \"\" || !is_numeric($phone) || strlen($phone) != 10) {\n            print \"❌ Debes introducir un número de teléfono válido (10 dígitos).\\n\";\n            return null;\n        } else {\n            return ['name' => $name, 'phone' => $phone];\n        }\n    }\n\n\n    function searchContact($agenda) {\n        $contact = getContactInfo();\n        if ($contact) {\n            foreach($agenda as $entry) {\n                if ($entry['name'] == $contact['name'] && $contact['phone'] == $contact['phone']) {\n                    print  \"Contacto encontrado: \\n\";\n                    print  \"Nombre: \" . $contact['name'] . \"\\n\";\n                    print  \"Teléfono: \" . $contact['phone'] . \"\\n\";\n                }\n\n            }\n      \n            print  \" ❌ Contacto no encontrado\\n\";\n        }\n    }\n\n    function addContact($agenda) {\n        $contact = getContactInfo();\n        $agenda[] = $contact;\n        if ($contact) {\n            print  \"Contacto añadido: \\n\";\n            print  \"Nombre: \" . $contact['name'] . \"\\n\";\n            print  \"Teléfono: \" . $contact['phone'] . \"\\n\";\n        }\n    }\n\n\n    function updContact($agenda) {\n        $contact = getContactInfo();\n        if ($contact) {\n            print  \"Contacto actualizado: \\n\";\n            print  \"Nombre: \" . $contact['name'] . \"\\n\";\n            print  \"Teléfono: \" . $contact['phone'] . \"\\n\";\n        }\n        print  \" ❌ Contacto no actualizado\\n\";\n    }\n\n    function deleteContact($agenda) {\n        $contact = getContactInfo();\n        if ($contact) {\n            foreach ($agenda as $key => $entry) {\n                if ($entry['name'] == $contact['name']) {\n                    unset($agenda[$key]);\n                    print  \"Contacto eliminado: \\n\";\n                    print  \"Nombre: \" . $contact['name'] . \"\\n\";\n                    print  \"Teléfono: \" . $contact['phone'] . \"\\n\";\n                }\n            }\n            print \" ❌ Contacto no eliminado\\n\";\n        }\n    }\n\n\n// Llamamos a la función\ncontacts();\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/php/Hugovrc.php",
    "content": "<?php\n\n// Arrays\necho \"----- Arrays ---- \\n\";\n$marcas_autos = [\"BMW\",\"Ford\",\"Chevrolet\",\"Honda\",\"Mazda\"];\nprint_r($marcas_autos);\n\n// Diccionarios\necho \"----- Diccionario ---- \\n\";\n$modelo_anio = array(\"BMW M3\"=>2012, \"Focus\"=>2015, \"Camaro\"=>2023, \"Civic\"=>2021);\nprint_r($modelo_anio);\n\necho \"----- Agregar elemento ---- \\n\";\n// Insercion de elemento\n$marcas_autos[] = \"Mitsubishi\";\nprint_r($marcas_autos);\n\n// Borrado\necho \"----- Borrar elemento ---- \\n\";\nunset($marcas_autos[2]); //Se agrega el indice del elemento entre corchetes que se quiere borrar\nprint_r($marcas_autos);\n\n// Actualizacion\necho \"----- Modificar elemento ---- \\n\";\n$marcas_autos[0] = \"Toyota\"; // entre corchetes el numero del elemento que se quiere modificar\nprint_r($marcas_autos);\n\n// ordenacion\n//ascendente\necho \"----- Ordenar elementos de forma ascendente ---- \\n\";\nsort($marcas_autos);\nprint_r($marcas_autos);\n\n//descendente\necho \"----- Ordenar elementos de forma descendente ---- \\n\";\nrsort($marcas_autos);\nprint_r($marcas_autos);\n\n//Ascendente segun el valor\necho \"----- Ordenar elementos de forma ascendente por el valor ---- \\n\";\nasort($marcas_autos);\nprint_r($marcas_autos);\n\n//descendente sugun el valor\necho \"----- Ordenar elementos de forma descendente por el valor ---- \\n\";\narsort($marcas_autos);\nprint_r($marcas_autos);\n\n//Ascendente segun la clave\necho \"----- Ordenar elementos de forma ascendente por la clave ---- \\n\";\nksort($marcas_autos);\nprint_r($marcas_autos);\n\n//descendente segun la clave\necho \"----- Ordenar elementos de forma descendente por la clave ---- \\n\";\nkrsort($marcas_autos);\nprint_r($marcas_autos);\n\n// DIFICULTAD EXTRA\necho \"----- DIFICULTAD EXTRA ---- \\n\";\n\n$agenda_contactos = array();\n\n/*echo \"Menu: \n        1.- Buscar \n        2.- Insertar\n        3.- Actualizar\n        4.- Eliminar\n        5.- Salir \\n\";\necho \"Que deseas realizar: \";\nfscanf(STDIN, \"%s\", $accion);\n*/\nwhile ($accion < 5) {\n    echo \"Menu: \n            1.- Buscar \n            2.- Insertar\n            3.- Actualizar\n            4.- Eliminar\n            5.- Salir \\n\";\n    echo \"Que deseas realizar: \";\n    fscanf(STDIN, \"%s\", $accion);\n    if ($accion == 5) break;\n    elseif ($accion == 1) {\n        echo \"que nombre deseas buscar: \";\n        $nombre = trim(fgets(STDIN));\n        if (array_key_exists($nombre, $agenda_contactos)) {\n            echo \"Nombre: \" .$nombre. \"Telefono: \" .$agenda_contactos[$nombre];\n        } else {\n            echo $nombre. \" No existe en la agenda \\n\";\n        }\n    } elseif ($accion == 2) {\n        echo \"Ingresa Nombre: \";\n        $nombre = fgets(STDIN);\n        echo \"Ingresa el telefono: \";\n        $telefono = trim(fgets(STDIN));\n        if (strlen($telefono) <= 10 and is_numeric($telefono)) {\n            $agenda_contactos[$nombre] = $telefono;\n            print_r($agenda_contactos);\n        } else {\n            echo \"El numero de telefono no puede contener mas de 10 digitos y debe ser numerico\\n\";\n        }\n        \n    } elseif ($accion == 3) {\n        echo \"Ingresa el nombre del contacto a modificar: \";\n        $nombre = fgets(STDIN);\n        if (array_key_exists($nombre, $agenda_contactos)) {\n            echo \"ingresa el nuevo numero de telefono: \";\n            $telefono = fgets(STDIN);\n            if (strlen($telefono) <= 10 and is_numeric($telefono)) {\n                $agenda_contactos[$nombre] = $telefono;\n            } else {\n                echo \"El numero de telefono no puede contener mas de 10 digitos y debe ser numerico\\n\";\n            }\n        } else {\n            echo \"Ese contacto no existe en la agenda, intenta de nuevo\\n\";\n        }\n    } elseif ($accion == 4) {\n        echo \"Ingresa el nombre del contacto a eliminar: \";\n        $nombre = fgets(STDIN);\n        if (array_key_exists($nombre, $agenda_contactos)) {\n            unset($agenda_contactos[$nombre]);\n            echo \"Contacto eliminado!!\";\n        } else {\n            echo \"Ese contacto no existe en la agenda, intenta de nuevo\\n\";\n        }\n    }\n}\n?>"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/php/Jeyker-Dev.php",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\n<?php\n    /* Primetra Estructura de Datos Listas Enlazadas Clase SplDoublyLinkedList\n    --  La clase SplDoublyLinkedList proporciona las principales funcionalidades de una lista doblemente enlazada. */\n\n    $spldll = new SplDoublyLinkedList;\n\n    /* Add A New Value */\n    $spldll->add(0, \"0\");\n    $spldll->add(1, \"1\");\n    $spldll->add(2, \"3\");\n    $spldll->add(3, \"10\");\n\n    /* Update A Value */\n    $spldll->offsetSet(2, \"2\");\n\n    print_r($spldll);\n\n        /* Delete A Value */\n    $spldll->offsetUnset(3);\n    print_r($spldll);\n\n        /* Segunda Estructura de Datos Listas Enlazadas Clase SplQueue\n    --  La clase SplStack proporciona la funcionalidad principal de una pila implementada mediante una lista doblemente enlazada estableciendo el modo iterador a SplDoublyLinkedList::IT_MODE_LIFO. */\n\n    $splstack = new SplStack;\n\n        /* Add A New Value */\n    $splstack->add(0, \"0\");\n    $splstack->add(1,\"10\");\n    $splstack->add(2, \"20\");\n\n    print_r($splstack);\n\n    /* Update A Value */\n    $splstack->offsetSet(0, \"1\");\n\n    print_r($splstack);\n\n    /* Delete A Value */\n    $splstack->offsetUnset(2);\n\n    print_r($splstack);\n\n            /* Tercera Estructura de Datos Listas Enlazadas Clase SplStack\n    --  La clase SplQueue proporciona las principales funcionalidades de una cola implementada usando una lista doblemente enlazada al estableciendo el modo del iterador a SplDoublyLinkedList::IT_MODE_FIFO. */\n\n    $splqueue = new SplQueue;\n\n        /* Add A New Value */\n    $splqueue->add(0, \"0\");\n    $splqueue->add(1,\"10\");\n    $splqueue->add(2, \"20\");\n\n    print_r($splqueue);\n\n    /* Update A Value */\n    $splqueue->offsetSet(0, \"1\");\n\n    print_r($splqueue);\n\n    /* Delete A Value */\n    $splqueue->offsetUnset(2);\n\n    print_r($splqueue);\n\n                /* Cuarta Estructura de Datos Listas Enlazadas Clase SplMaxHeap\n    --  La clase SplMaxHeap proporciona la funcionalidad principal de un montículo, manteniendo el máximo en la parte superior. */\n\n    $splmaxheap = new SplMaxHeap;\n\n            /* Add A New Value */\n    $splmaxheap->insert(\"1\");\n    $splmaxheap->insert(\"10\");\n    $splmaxheap->insert(\"20\");\n\n    print_r($splmaxheap);\n\n        /* Delete A Value */\n    $splmaxheap->next();\n\n    print_r($splmaxheap);\n\n                    /* Quinta Estructura de Datos Listas Enlazadas Clase SplMinHeap\n    --  La clase SplMinHeap proporciona la funcionalidad principal de un montículo, manteniendo el mínimo en la parte superior.. */\n\n    $splminheap = new SplMinHeap;\n\n            /* Add A New Value */\n    $splminheap->insert(\"1\");\n    $splminheap->insert(\"10\");\n    $splminheap->insert(\"20\");\n\n    print_r($splminheap);\n\n        /* Delete A Value */\n    $splminheap->next();\n\n    print_r($splminheap);\n\n                    /* Sexta Estructura de Datos Listas Enlazadas Clase SplFixedArray\n    --  la clase SplFixedArray proporciona la funcionalidad principal de un array. La principal diferencia entre SplFixedArray y un array normal de PHP es que la clase SplFixedArray es de longitud fija y sólo permite enteros dentro del rango de índices. La ventaja es que usa menos memoría que un array estándar. */\n\n    $splfixedarray = new SplFixedArray(4);\n\n    /* Add a new Value */\n    $splfixedarray[0] = 0;\n    $splfixedarray[1] = 1;\n    $splfixedarray[2] = 2;\n    $splfixedarray[3] = 4;\n\n    print_r($splfixedarray);\n\n    /* Update a new Value */\n    $splfixedarray->offsetSet(3,3);\n\n    print_r($splfixedarray);\n\n    /* Delete a new Value */\n    $splfixedarray->offsetUnset(3);\n\n    print_r($splfixedarray);\n\n                    /* Septima Estructura de Datos Listas Enlazadas Clase SplObjectStorage\n    -- La clase SplObjectStorage proporciona una correspondencia de objetos de datos o, ignorando los datos, un conjunto de objetos. Este doble propósito puede ser útil en muchos casos relacionados con la necesidad de identificar objetos de forma única.*/\n\n    $splobjectstorage = new SplObjectStorage;\n\n    $object_1 = new stdClass;\n    $object_2 = new stdClass;\n\n    /* Add a new Object */\n    $splobjectstorage[$object_1] = array(0,1,2);\n    $splobjectstorage->attach($object_2, \"Hello\");\n\n    print_r($splobjectstorage);\n\n    /* Update a Object */\n    $splobjectstorage->offsetSet($object_2, \"Hola\");\n\n    print_r($splobjectstorage);\n\n    /* Delete a Object */\n    $splobjectstorage->offsetUnset($object_2);\n\n    print_r($splobjectstorage);\n\n    /*  Ejercicio de Agenda de Contactos    */\n\n    echo \"Bienvenido a la Agenda de Contactos.\\n\";\n    echo \"Las Opciones que se pueden realizar son las siguientes:\\n\";\n    echo \"Ver Lista de Contactos. Coloca 1.\\n\";\n    echo \"Buscar un Contacto en la Lista. Coloca 2.\\n\";\n    echo \"Guardar Contacto. Coloca 3.\\n\";\n    echo \"Actualizar Contacto. Coloca 4.\\n\";\n    echo \"Eliminar Contacto. Coloca 5.\\n\";\n    echo \"Salir de la Agenda. Coloca 6.\\n\";\n\n    Class Contacto\n    {\n        public $nombre;\n        public $numero;\n        public static $agenda;\n        public function __construct($nombre, $numero)\n        {\n            $this->nombre = $nombre;\n            $this->numero = $numero;\n        }   // Here End Constructor\n\n        // Instancia de SPlobjectStorage\n        public static function iniciarAgenda()\n        {\n            self::$agenda = new SplObjectStorage;\n        }   // Here End Function\n\n        // Guarda los Contactos en la Agenda\n        public static function guardar($nuevo_contacto)\n        {\n            self::$agenda->attach($nuevo_contacto);\n            echo \"Contacto Agregado Correctamente\";\n        }   // Here End FUnction\n\n        // Actualiza los Contactos en la Agenda\n        public function actualizar($nombre_actualizar, $numero_actualizar)\n        {\n            $this->nombre = $nombre_actualizar;\n            $this->numero = $numero_actualizar;\n        }   // Here End Function\n\n        // Muestra los Conctactos de la Agenda\n        public function getInfo() \n        {\n            return \"Nombre: $this->nombre, Número: $this->numero\";\n        }   // Here End Function\n\n        // Buscar un contacto\n        public static function find($nombre_buscar)\n        {\n            self::$agenda->rewind();\n            while (self::$agenda->valid()) {\n                $contacto = self::$agenda->current();\n                if ($contacto->nombre == $nombre_buscar) \n                {\n                    return $contacto;\n                }   // Here End If\n                self::$agenda->next();\n            }   // Here End While\n            return false;\n        }   // Here End Function\n\n        // Mostrar todos los contactos en la agenda\n        public static function show()\n        {\n            self::$agenda->rewind();\n\n            while(self::$agenda->valid())\n            {\n                $contactos = self::$agenda->current();\n                echo $contactos->getInfo() . \".\\n\";\n                self::$agenda->next();\n            }   // Here End While\n        }   // Here End Function\n\n        // Elimina los Contactos en la Agenda\n        public function eliminar()\n        { \n\n        }   // Here End Function\n    }   // Here End Class\n\n    // Instancia de Estructura SPLOBJECTSTORAGE\n    Contacto::iniciarAgenda();\n    $agenda = Contacto::$agenda;\n\n    // Crear Objetos de Contactos\n    $contacto_1 = new Contacto(\"Jeyker\", \"04245652392\");\n    $contacto_2 = new Contacto(\"Maria\", \"04263318767\");\n    $contacto_3 = new Contacto(\"Ramon\", \"04125618690\");\n    $contacto_4 = new Contacto(\"Alejandro\", \"04164126754\");\n    $contacto_5 = new Contacto(\"Fernando\", \"04148879135\");\n\n    // Agregar Contactos a la agenda\n    $agenda->attach(object: $contacto_1);\n    $agenda->attach(object: $contacto_2);\n    $agenda->attach(object: $contacto_3);\n    $agenda->attach(object: $contacto_4);\n    $agenda->attach(object: $contacto_5);\n\n    // Pedir al usuario ingresar un dato\n    $numero =  trim(fgets((STDIN)));\n\n    // Validacion para verificar que el dato ingresado sea numerico\n    if(filter_var($numero, FILTER_VALIDATE_INT) === false)\n    {\n        echo \"El Dato a Ingresar Debe Ser un Numero.\\n\";\n        exit;\n    }   // Here End If\n\n    // Validacion para que el numero a ingresar sea entre las opciones dadas\n    if($numero <= 0 || $numero > 6)\n    {\n        echo \"El Dato a Ingresar Debe Ser Entre las Opciones Dadas.\\n\";\n        exit;\n    }   // Here End If\n\n    // Menu de opciones\n    switch($numero)\n    {\n        // Mostras la lista de contactos en la agenda\n        case 1:\n            echo \"Lista de Contactos: \\n\";\n            Contacto::show();\n            break;\n\n        // Buscar un contacto en la agenda\n        case 2:\n            echo \"Ingresa El Nombre del Contacto que Buscas:\\n\";\n            $contacto_buscar = trim(fgets(STDIN));\n            $contacto = Contacto::find($contacto_buscar);\n                if ($contacto) \n                {\n                    echo \"Contacto encontrado: \" . $contacto->getInfo() . \"\\n\";\n                }   // Here End If \n                else \n                {\n                    echo \"No se encontraron contactos.\\n\";\n                }   // Here End Else\n            break;\n\n            // Guardar un Contacto\n        case 3:\n            echo \"Escribe un Nombre para el Contacto: . \\n\";\n            $nombre_contacto = trim(fgets(STDIN));\n\n            echo \"Escribe un Numero para el Contacto: . \\n\";\n            $numero_contacto = trim(fgets(STDIN));\n\n            $contacto_nuevo = new Contacto($nombre_contacto, $numero_contacto);\n\n            $agenda->attach($contacto_nuevo);\n\n            echo \"Contacto Agregado Correctamente.\\n\";\n            break;\n\n        case 4;\n            echo \"Lista de Contactos: \\n\";\n            Contacto::show();\n\n            echo \"Escribe el Nombre del Contacto a Editar: \\n\";\n            $nombre_actualizar = trim(fgets(STDIN));\n\n            $contacto_encontrado = Contacto::find($nombre_actualizar);\n\n            if($contacto_encontrado === false)\n            {\n                echo \"No se Encontraron Contactos con Este Nombre. \\n\";\n            }   // Here End If\n            else\n            {\n                echo \"Ingresa un Nuevo Nombre: \";\n                $nuevo_nombre = trim(fgets(STDIN));\n\n                echo \"Ingresa un Nuevo Numero: \";\n                $nuevo_numero = trim(fgets(STDIN));\n\n                $contacto_encontrado->actualizar($nuevo_nombre, $nuevo_numero);\n                echo \"Contacto Actualizado. \\n\";\n                Contacto::show();\n            }   // Here End Else\n\n            break;\n\n        case 5;\n        Contacto::show();\n\n        echo \"Escribe el Nombre del Contacto que Quieres Eliminar: \";\n        $nombre_eliminar = trim(fgets(STDIN));\n\n        $contacto_eliminar = Contacto::find($nombre_eliminar);\n\n        $agenda->offsetUnset($contacto_eliminar);\n\n        Contacto::show();\n\n        echo \"Contacto Eliminado Correctamente.\\n\";\n        break;\n\n        case 6:\n            echo \"Saliendo de la Agenda.\\n\";\n            break;\n\n            default:\n            echo \"Error Inesperado. Vuelva a Intentar\";\n            break;\n    }   // Here End Switch\n?>"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/php/adrs1166ma.php",
    "content": "<?php \n\n/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\nfunction _start(){echo 'Invocacion<pre>';} // 🔹funciones para el ejemplo\nfunction _end(){echo '</pre><br>';} // 🔹funciones para el ejemplo\n/*\n    🟢 Estructuras de Datos\n*/\n// 🟠 Forma 1 \n$carrito1 = array (\n    'carne' => \"🥩\",\n    'papitas' => \"🍟\",\n    'pizza' => \"🍕\",\n    'chocolate' => \"🍫\",\n    'whafle' => \"🧇\",\n    'huevo' => \"🥚\"\n);\n\n\n// 🟠 Forma 2 \nclass tienda {\n    public $Dato1 = \"🥩\";\n    public $Dato2 = \"🍟\";\n    public $Dato3 = \"🍕\";\n    public $Dato4 = \"🍫\";\n    public $Dato5 = \"🧇\";\n    public $Dato6 = \"🥚\";\n}\n$carrito2 = new tienda();\n\n\n// 🟠 Forma 3 \n$carrito3 = array('🥩','🍟','🍕','🍫','🧇','🥚'); // mas usada en Wordpress\n\n\n// 🟠 Forma 4 \n$carrito4 = ['🥩','🍟','🍕','🍫','🧇','🥚']; // mas usada en Laravel\n//             0  , 1  ,  2  ,  3 ,  4  , 5    |  Indices/posicion general\n\n// Mostrar en pantalla 🔹\n_start();\n// Forma en pantalla\nvar_dump($carrito1);\nvar_dump($carrito2);\nvar_dump($carrito3);\nvar_dump($carrito4);\n// Extrar un Dato en pantalla\necho $carrito1['chocolate']; // Extraer 🍫\necho $carrito2 -> Dato4; // Extraer 🍫\necho $carrito3[3]; // Extraer 🍫\necho $carrito4[3]; // Extraer 🍫\n_end();\n\n\n// 🟠 Ordenamiento \n$abecedario = ['z', 'b', 'h', 'n', 'q', 'v', 'y', 'a', 'c', 'e', 'i', 'o', 'u', 'd', 'f', 'g', 'j', 'k', 'l', 'm', 'p', 'r', 's', 't', 'w', 'x'];\n$numeros = [4, 6 , 2, 1, 9, 3, 5, 8, 7, 11, 19, 13, 10, 20, 14, 18, 12, 17, 15, 16];\n// De menor a mayor\n_start();\nsort($abecedario);\nsort($numeros);\nsort($carrito4);\n// Imprimir\nprint_r($abecedario);\nprint_r($numeros);\nprint_r($carrito4);\n_end();\n\n// Al reves\n_start();\nrsort($abecedario);\nrsort($numeros);\nrsort($carrito4);\n// Imprimir\nprint_r($abecedario);\nprint_r($numeros);\nprint_r($carrito4);\n_end();\n\necho \"🟠 Añadir<br>\"; \n$carrito4 = ['🥩','🍟','🍕','🍫','🧇','🥚']; //array original\n\n_start();\n$carrito4[6] = '🍔'; // agregarlo en el indice 6\nprint_r($carrito4); \n// Ahora tendra estos datos '🥩','🍟','🍕','🍫','🧇','🥚','🍔'\n_end();\n_start();\narray_push($carrito4,'🥓'); // agregarlo al final del arreglo\nprint_r($carrito4); \n// Ahora tendra estos datos '🥩','🍟','🍕','🍫','🧇','🥚','🍔','🥓'\n_end();\n_start();\narray_unshift($carrito4,'🍙'); // agregarlo al inicio del arreglo\nprint_r($carrito4); \n// Ahora tendra estos datos '🍙','🥩','🍟','🍕','🍫','🧇','🥚','🍔','🥓'\n_end();\n\necho \"🟠 Eliminar\"; \n_start();\nunset($carrito4[4]); // Eliminamso chocolate \nprint_r($carrito4); // '🍙','🥩','🍟','🍕','🧇','🥚','🍔','🥓'\n_end();\n_end();\n\n\n\necho \"🟠 Mostrar<br>\"; \n_start();\nforeach ($carrito4 as $producto) {\n    echo $producto.'<br>';\n}\n_end();\n\n\n\n\n// 🟠 Associative Arrays\n$carrito1 = array (\n    'carne' => \"🥩\",\n    'papitas' => \"🍟\",\n    'pizza' => \"🍕\",\n    'chocolate' => \"🍫\",\n    'whafle' => \"🧇\",\n    'huevo' => [\n        'magnitud' => \"kl\",\n        'precio' => 5.50,\n        'informacion' => [\n            'Descripcion' => \"Excelente fuente de vitaminas y minerales\",\n            'icono' => \"🥚\"\n        ]\n    ]   \n);\n\n// Imprimirlo\n_start();\necho $carrito1['huevo']; // ❌\necho '<br>';\necho $carrito1['huevo']['informacion']['Descripcion']; // ✅\necho '<br>';\necho $carrito1['huevo']['informacion']['icono']; // ✅\n_end();\n\necho '<br>';\n\n_start();\necho $carrito1['huevo']['informacion']['pronombre'] = 'Huevito hacker'; // ✅\necho '<br>';\nvar_dump($carrito1);\n_end();\n\n\n\necho '<br>🔥 Extra <br>';\n/*\n    🔥 Extra\n*/\n$agenda = [];\n\n_start();\nfunction extra() {\n\n    global $agenda;\n\n    while (true) {\n    \n        $opcion = readline(\"\\n\\n--------------------------- \\n/- Agenda de Contactos -/ \\n1. Buscar contacto \\n2. Insertar contacto \\n3. Actualizar contacto \\n4. Eliminar contacto \\n5. Salir \\n--------------------------- \\nSeleccione una opción (1-5): \");\n    \n        switch ($opcion) {\n            case 1:\n                buscarContacto($agenda);\n                break;\n            case 2:\n                insertarContacto($agenda);\n                break;\n            case 3:\n                actualizarContacto($agenda);\n                break;\n            case 4:\n                eliminarContacto($agenda);\n                break;\n            case 5:\n                echo \"Saliendo del programa\\n\";\n                exit;\n            default:\n                echo \"Inténtelo de nuevo.\\n\";\n        }\n    }\n}\n\nextra();\n\n\n\nfunction buscarContacto($agenda) {\n    $nombre = readline(\"Ingrese el nombre del contacto a buscar: \");\n    $encontrado = false;\n\n    foreach ($agenda as $contacto) {\n        if ($contacto['nombre'] === $nombre) {\n            echo \"Nombre: {$contacto['nombre']}\\n\";\n            echo \"Teléfono: {$contacto['telefono']}\\n\";\n            $encontrado = true;\n            break;\n        }\n    }\n\n    if (!$encontrado) {\n        echo \"Contacto no encontrado.\\n\";\n    }\n}\n\nfunction insertarContacto(&$agenda) {\n    $nombre = readline(\"Ingrese el nombre del nuevo contacto: \");\n    $telefono = validarTelefono();\n\n    $agenda[] = [\n        'nombre' => $nombre,\n        'telefono' => $telefono\n    ];\n\n    echo \"Contacto insertado con éxito.\\n\";\n}\n\nfunction actualizarContacto(&$agenda) {\n    $nombre = readline(\"Ingrese el nombre del contacto a actualizar: \");\n    $indice = buscarIndiceContacto($agenda, $nombre);\n\n    if ($indice !== -1) {\n        $telefono = validarTelefono();\n        $agenda[$indice]['telefono'] = $telefono;\n        echo \"Contacto actualizado con éxito.\\n\";\n    } else {\n        echo \"Contacto no encontrado.\\n\";\n    }\n}\n\nfunction eliminarContacto(&$agenda) {\n    $nombre = readline(\"Ingrese el nombre del contacto a eliminar: \");\n    $indice = buscarIndiceContacto($agenda, $nombre);\n\n    if ($indice !== -1) {\n        unset($agenda[$indice]);\n        $agenda = array_values($agenda);\n        echo \"Contacto eliminado con éxito.\\n\";\n    } else {\n        echo \"Contacto no encontrado.\\n\";\n    }\n}\n\nfunction buscarIndiceContacto($agenda, $nombre) {\n    foreach ($agenda as $indice => $contacto) {\n        if ($contacto['nombre'] === $nombre) {\n            return $indice;\n        }\n    }\n\n    return -1;\n}\n\nfunction validarTelefono() {\n    while (true) {\n        $telefono = readline(\"Ingrese el número de teléfono: \");\n\n        if (ctype_digit($telefono) && strlen($telefono) <= 8) {\n            return $telefono;\n        } else {\n            echo \"Número de teléfono no válido. Inténtelo de nuevo.\\n\";\n        }\n    }\n}\n_end();\n\n?>"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/php/eulogioep.php",
    "content": "<?php\n\n// Función para ejemplificar las estructuras de datos en PHP\nfunction ejemplosEstructurasDatos() {\n    // Array indexado: equivalente a ArrayList en Java\n    $array = ['Java', 'Python', 'PHP'];\n    echo \"Array indexado: \" . implode(\", \", $array) . \"\\n\";\n\n    // Array asociativo: equivalente a HashMap en Java\n    $arrayAsociativo = [\n        'Uno' => 1,\n        'Dos' => 2,\n        'Tres' => 3\n    ];\n    echo \"Array asociativo: \";\n    print_r($arrayAsociativo);\n\n    // SplFixedArray: array de tamaño fijo\n    $splArray = new SplFixedArray(3);\n    $splArray[0] = 'Rojo';\n    $splArray[1] = 'Verde';\n    $splArray[2] = 'Azul';\n    echo \"SplFixedArray: \" . implode(\", \", $splArray) . \"\\n\";\n\n    // Operaciones\n    unset($array[1]); // Borrado (elimina 'Python')\n    $array[] = 'JavaScript'; // Inserción\n    $array[1] = 'TypeScript'; // Actualización\n    sort($array); // Ordenación\n\n    echo \"Array después de operaciones: \" . implode(\", \", $array) . \"\\n\";\n}\n\n// Función principal para la agenda de contactos\nfunction agendaContactos() {\n    $agenda = [];\n\n    while (true) {\n        echo \"\\n--- Agenda de Contactos ---\\n\";\n        echo \"1. Buscar contacto\\n\";\n        echo \"2. Añadir contacto\\n\";\n        echo \"3. Actualizar contacto\\n\";\n        echo \"4. Eliminar contacto\\n\";\n        echo \"5. Mostrar todos los contactos\\n\";\n        echo \"6. Salir\\n\";\n        echo \"Seleccione una opción: \";\n\n        $opcion = trim(fgets(STDIN));\n\n        switch ($opcion) {\n            case '1':\n                buscarContacto($agenda);\n                break;\n            case '2':\n                anadirContacto($agenda);\n                break;\n            case '3':\n                actualizarContacto($agenda);\n                break;\n            case '4':\n                eliminarContacto($agenda);\n                break;\n            case '5':\n                mostrarContactos($agenda);\n                break;\n            case '6':\n                echo \"¡Hasta luego!\\n\";\n                return;\n            default:\n                echo \"Opción no válida.\\n\";\n        }\n    }\n}\n\nfunction buscarContacto(&$agenda) {\n    echo \"Ingrese el nombre del contacto: \";\n    $nombre = trim(fgets(STDIN));\n    if (isset($agenda[$nombre])) {\n        echo \"Teléfono de $nombre: {$agenda[$nombre]}\\n\";\n    } else {\n        echo \"Contacto no encontrado.\\n\";\n    }\n}\n\nfunction anadirContacto(&$agenda) {\n    echo \"Ingrese el nombre del contacto: \";\n    $nombre = trim(fgets(STDIN));\n    $telefono = solicitarTelefono();\n    $agenda[$nombre] = $telefono;\n    echo \"Contacto añadido con éxito.\\n\";\n}\n\nfunction actualizarContacto(&$agenda) {\n    echo \"Ingrese el nombre del contacto a actualizar: \";\n    $nombre = trim(fgets(STDIN));\n    if (isset($agenda[$nombre])) {\n        $telefono = solicitarTelefono();\n        $agenda[$nombre] = $telefono;\n        echo \"Contacto actualizado con éxito.\\n\";\n    } else {\n        echo \"Contacto no encontrado.\\n\";\n    }\n}\n\nfunction eliminarContacto(&$agenda) {\n    echo \"Ingrese el nombre del contacto a eliminar: \";\n    $nombre = trim(fgets(STDIN));\n    if (isset($agenda[$nombre])) {\n        unset($agenda[$nombre]);\n        echo \"Contacto eliminado con éxito.\\n\";\n    } else {\n        echo \"Contacto no encontrado.\\n\";\n    }\n}\n\nfunction mostrarContactos($agenda) {\n    if (empty($agenda)) {\n        echo \"La agenda está vacía.\\n\";\n    } else {\n        foreach ($agenda as $nombre => $telefono) {\n            echo \"$nombre: $telefono\\n\";\n        }\n    }\n}\n\nfunction solicitarTelefono() {\n    while (true) {\n        echo \"Ingrese el número de teléfono (máximo 11 dígitos): \";\n        $telefono = trim(fgets(STDIN));\n        if (preg_match('/^\\d{1,11}$/', $telefono)) {\n            return $telefono;\n        }\n        echo \"Número no válido. Debe ser numérico y tener máximo 11 dígitos.\\n\";\n    }\n}\n\n// Ejecutamos los ejemplos y la agenda\necho \"Ejemplos de estructuras de datos en PHP:\\n\";\nejemplosEstructurasDatos();\n\necho \"\\nIniciando la agenda de contactos...\\n\";\nagendaContactos();\n\n?>"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/php/gabrielmoris.php",
    "content": "<?php\n/*\n * EXERCISE:\n * - Show examples of creating all default-supported structures in your language.\n * - Use insertion, deletion, update, and sorting operations.\n */\n\n// ARRAY\n$arr = array(1, 2, 3, 4);\n$arr[] = 9; // insertion\nunset($arr[1]); // deletion\n$arr[1] = 33; // Update\nsort($arr); // sorting\nvar_dump($arr);\n\n// ASSOCIATIVE ARRAY\n$asociative_Arr = array(\"name\" => \"Gabriel\", \"age\" => 34);\n$asociative_Arr[\"age\"] = 35; // update\n$asociative_Arr[\"email\"] = \"gabriel@example.com\"; // insert\nksort($asociative_Arr); // sorting\nunset($asociative_Arr[\"email\"]); // delete\n\n// USING: Standard PHP Library (SPL)\n// DOUBLY LINKED LIST: list of nodes linked in both directions. Efficient for stacks and queries.\n$dll = new SplDoublyLinkedList();\n$dll->push(1); //push\n$dll->push(2);\n$dll->pop(); //deletion\n$dll->offsetSet(0, 99); //update\n\n\n// HEAPS: tree-like structures where each node is greater than or equal to its children.\n$heap = new SplMaxHeap();\n$heap->insert(1); // insertion\n$heap->extract(); //deletion\n\n\n// PRIORITY QUEUE: priority queue based on a heap. Elements are ordered by priority.\n$pq = new SplPriorityQueue();\n$pq->insert('A', 1); // Insertion\n$pq->insert('B', 1); // Insertion\n$pq->insert('C', 1); // Insertion\n$pq->extract(); // Deletion\n$pq->insert('B', 2); // Update\n\n// MAP: maps from integers/strings to values. SPL provides a map from objects to data.\n$map = new SplObjectStorage();\n$obj1 = new stdClass();\n$obj2 = new stdClass();\n$map->attach($obj1, 'Value1'); // Insertion\n$map->attach($obj2, 'Value2'); // Insertion\n$map->detach($obj2); // Deletion\n$map[$obj1] = 'UpdatedValue'; // Update\n\n/*\n * EXTRA CHALLENGE (optional):\n * Create a terminal-based contact agenda.\n * - Implement functionalities for search, insertion, update, and deletion of contacts.\n * - Each contact should have a name and a phone number.\n * - The program first prompts for the desired operation, followed by necessary data.\n * - The program should reject non-numeric phone numbers with more than 11 digits (or any other desired digit count).\n * - Also, provide an option to exit the program.\n */\n\n\nfunction agenda($agenda)\n{\n    echo \"\\033c\";\n    echo \"\n    =====AGENDA=====\n    1.- New Contact \n    2.- Search Contact\n    3.- Update contact\n    4.- Delete Contact\n    5.- Exit\n    ================\n     \\n\";\n\n    do {\n        $selection = readline(\"Select an option\\n\");\n        switch ($selection) {\n            case 1:\n                add_contact($agenda);\n                break;\n            case 2:\n                find_contact($agenda);\n                break;\n            case 3:\n                update_contact($agenda);\n                break;\n            case 4:\n                delete_contact($agenda);\n                break;\n            case 5:\n                echo \"\\033c\";\n                echo \"Good bye 👋📞\\n\";\n                exit;\n            default:\n                echo \"This option doesn't exist.\\n\";\n        }\n    } while (true);\n};\n\n// I need to pass by reference the agenda\nfunction add_contact(&$agenda)\n{\n    $name = readline(\"Write the name:\");\n    $number = readline(\"Write the number:\");\n\n    if (strlen($number) > 11) {\n        echo \"The number must be less than 11 digits.\\n\";\n        return;\n    } else {\n        $agenda[$name] = $number;\n    }\n};\nfunction find_contact(&$agenda)\n{\n    $name = readline(\"Write the name:\");\n    if (!array_key_exists($name, $agenda)) {\n        echo \"This contact doesn`t exist\\n\";\n        return;\n    } else {\n        $number = $agenda[$name];\n        echo \"The number of \" . $name . \" is \" . $number . \"\\n\";\n    }\n};\nfunction update_contact(&$agenda)\n{\n    $name = readline(\"Write the name:\");\n    $newName = readline(\"Write the new name:\");\n    $newNumber = readline(\"Write the new number:\");\n    unset($agenda[$name]);\n    $agenda[$newName] = $newNumber;\n};\nfunction delete_contact(&$agenda)\n{\n    $name = readline(\"Write the name to DELETE:\");\n    unset($agenda[$name]);\n};\n\n$contacts = [];\nagenda($contacts);\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/php/kodenook.php",
    "content": "<?php\n\ndeclare(strict_types = 1);\n\n/*\n    Array\n*/\n\n$data = ['fname', 'surname', 'chile', 'america'];\n\n# Insert\narray_unshift($data, 'man'); // insert elements to the begin\narray_push($data, 'july'); // insert elements to the end\n$data[5] = 'php';\n\necho 'insert', PHP_EOL;\necho var_dump($data);\n\n# Update\n$data[5] = 'php?';\n\necho 'update', PHP_EOL;\necho var_dump($data);\n\n# Delete\narray_shift($data); // delete elements to the begin\narray_pop($data); // delete elements to the end\nunset($data[5]);\n\necho 'delete', PHP_EOL;\necho var_dump($data);\n\n# Order\n\n$data = array_reverse($data); // reverse\necho 'reverse', PHP_EOL;\necho var_dump($data);\n\nasort($data); // ascending by value\necho 'ascending by value', PHP_EOL;\necho var_dump($data);\n\narsort($data); // descending by value\necho 'descending by value', PHP_EOL;\necho var_dump($data);\n\nsort($data); // ascending by index\necho 'ascending by index', PHP_EOL;\necho var_dump($data);\n\nrsort($data); // descending by index\necho 'descending by index', PHP_EOL;\necho var_dump($data);\n\nnatsort($data); // by natural order\necho 'by natural order', PHP_EOL;\necho var_dump($data);\n\nnatcasesort($data); // by natural order case insensitive\necho 'by natural order case insensitive', PHP_EOL;\necho var_dump($data);\n\n/*\n    Array  associative\n*/\n\n$data2 = ['fname' => 'fname', 'surname' => 'surname', 'country' => 'chile', 'continent' => 'america'];\n\n# Insert\n$data2['kode'] = 'php';\n\necho 'insert', PHP_EOL;\necho var_dump($data2);\n\n# Update\n$data2['kode'] = 'php?';\n\necho 'update', PHP_EOL;\necho var_dump($data2);\n\n# Delete\nunset($data2['kode']);\n\necho 'delete', PHP_EOL;\necho var_dump($data2);\n\n# Order\n\n$data2 = array_reverse($data2); // reverse\necho 'reverse', PHP_EOL;\necho var_dump($data2);\n\nasort($data2); // ascending by value\necho 'ascending by value', PHP_EOL;\necho var_dump($data2);\n\narsort($data2); // descending by value\necho 'descending by value', PHP_EOL;\necho var_dump($data2);\n\nksort($data2); // ascending by index\necho 'ascending by index', PHP_EOL;\necho var_dump($data2);\n\nkrsort($data2); // descending by index\necho 'descending by index', PHP_EOL;\necho var_dump($data2);\n\nnatsort($data2); // by natural order\necho 'by natural order', PHP_EOL;\necho var_dump($data2);\n\nnatcasesort($data2); // by natural order case insensitive\necho 'by natural order case insensitive', PHP_EOL;\necho var_dump($data2);\n\n/*\n    Exercise\n*/\n\n$option = 0;\n$data = [];\n\nfunction save($array, $number): bool {\n    $isNumber = ctype_alpha($number) ? true : false;\n\n    if (strlen($number) <= 11 and $isNumber) {\n        $array[$name] = $number;\n\n        return true;\n    }\n\n    return false;\n}\n\nwhile ($option != 5) {\n\n    echo \"\\033c\";\n\n    echo '1. search'. PHP_EOL;\n    echo '2. add'. PHP_EOL;\n    echo '3. edit'. PHP_EOL;\n    echo '4. delete'. PHP_EOL;\n    echo '5. exit'. PHP_EOL;\n\n    $option = readline('choose an option: ');\n\n    switch ($option) {\n        case 1:\n            $name = readline('name: ');\n\n            echo $name, PHP_EOL;\n            echo $data[$name];\n\n            sleep(5);\n            break;\n        case 2:\n            $name = readline('name: ');\n            $number = readline('number: ');\n\n            save($data, $number);\n            break;\n        case 3:\n            $name = readline('name: ');\n            $number = readline('number: ');\n\n            save($data, $number);\n            break;\n        case 4:\n            $name = readline('name: ');\n\n            unset($data[$name]);\n            break;\n        default:\n            # code...\n            break;\n    }\n}"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/php/marcode24.php",
    "content": "<?php\n/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\n// Arrays\n$arrayEjemplo = [1, 2, 3, 4, 5];\necho 'Array original: ' . implode(', ', $arrayEjemplo) . PHP_EOL;\n\n// Inserción\narray_push($arrayEjemplo, 6);\necho 'Array después de la inserción: ' . implode(', ', $arrayEjemplo) . PHP_EOL;\n\n// Borrado\narray_pop($arrayEjemplo);\necho 'Array después del borrado: ' . implode(', ', $arrayEjemplo) . PHP_EOL;\n\n// Actualización\n$arrayEjemplo[0] = 10;\necho 'Array después de la actualización: ' . implode(', ', $arrayEjemplo) . PHP_EOL;\n\n// Ordenación\n$arrayOrdenado = $arrayEjemplo;\nsort($arrayOrdenado);\necho 'Array ordenado: ' . implode(', ', $arrayOrdenado) . PHP_EOL;\n\n// Objetos\n$objetoEjemplo = ['nombre' => 'Juan', 'edad' => 25, 'ciudad' => 'Barcelona'];\necho 'Objeto original: ' . implode(', ', $objetoEjemplo) . PHP_EOL;\n\n// Inserción/Actualización\n$objetoEjemplo['profesion'] = 'Ingeniero';\necho 'Objeto después de la inserción/actualización: ' . implode(', ', $objetoEjemplo) . PHP_EOL;\n\n// Borrado\nunset($objetoEjemplo['edad']);\necho 'Objeto después del borrado: ' . implode(', ', $objetoEjemplo) . PHP_EOL;\n\n// Visita mi repo en GitHub para ver y correr los tests de este código --> https://github.com/marcode24/weekly-challenges\n\n?>\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/php/mayerga.php",
    "content": "<?php\n#Array indexados numéricamente\n$data = ['Manuel', 'Bl4ck', 'Wolfy', 'Visionos'];\necho \"Usando print_r():\\n\";\nprint_r($data);\n\n#Array asociativo. También para simular diccionarios\n$assocArray = ['nombre' => 'Juan', 'edad' => 25];\necho \"Usando print_r():\\n\";\nprint_r($assocArray);\n\n#Añadir elemento al final de array\narray_push($data, 'Fresa');\nprint_r($data);\n\n// Agregar un elemento al principio del array\narray_unshift($data, 'Pera');\nprint_r($data);\n\n// Agregar un elemento en una posición específica\narray_splice($data, 2, 0, 'Uva');\nprint_r($data);\n// Cambiar el elemento siguiente dentro del Array\n$moverElemento = 'Pera';\n$posicionActual = array_search($moverElemento, $data); // Obtener la posición actual del elemento\nif ($posicionActual !== false) { // Si el elemento se encuentra en el array\n    $nuevaPosicion = 2; // Nueva posición deseada\n}\nprint_r($data);\n\n#Listas enlazadas (Linked Lists)\n\n\n#Pilas (Stacks)\n\n\n#Colas (Queues)\n\n\n#Árboles (Trees)\n\n\n#Mapas (Maps)\n\n\n#Conjuntos (Sets)\n\n\n/* EXTRA */\n    // Ejercicio extra\n\n    $agenda = [];\n\n    function extra() {\n\n        global $agenda;\n\n        while (true) {\n            echo \"---------- Agenda de Contactos ----------\\n\";\n            echo \"1. Buscar contacto\\n\";\n            echo \"2. Insertar contacto\\n\";\n            echo \"3. Actualizar contacto\\n\";\n            echo \"4. Eliminar contacto\\n\";\n            echo \"5. Salir\\n\";\n            echo \"-----------------------------------------\\n\";\n        \n            $opcion = readline(\"Seleccione una opción (1-5): \");\n        \n            switch ($opcion) {\n                case 1:\n                    buscarContacto($agenda);\n                    break;\n                case 2:\n                    insertarContacto($agenda);\n                    break;\n                case 3:\n                    actualizarContacto($agenda);\n                    break;\n                case 4:\n                    eliminarContacto($agenda);\n                    break;\n                case 5:\n                    echo \"Saliendo del programa. ¡Hasta luego!\\n\";\n                    exit;\n                default:\n                    echo \"Opción no válida. Inténtelo de nuevo.\\n\";\n            }\n        }\n    }\n\n    extra();\n\n\n\n    function buscarContacto($agenda) {\n        $nombre = readline(\"Ingrese el nombre del contacto a buscar: \");\n        $encontrado = false;\n\n        foreach ($agenda as $contacto) {\n            if ($contacto['nombre'] === $nombre) {\n                echo \"Nombre: {$contacto['nombre']}\\n\";\n                echo \"Teléfono: {$contacto['telefono']}\\n\";\n                $encontrado = true;\n                break;\n            }\n        }\n\n        if (!$encontrado) {\n            echo \"Contacto no encontrado.\\n\";\n        }\n    }\n\n    function insertarContacto(&$agenda) {\n        $nombre = readline(\"Ingrese el nombre del nuevo contacto: \");\n        $telefono = validarTelefono();\n\n        $agenda[] = [\n            'nombre' => $nombre,\n            'telefono' => $telefono\n        ];\n\n        echo \"Contacto insertado con éxito.\\n\";\n    }\n\n    function actualizarContacto(&$agenda) {\n        $nombre = readline(\"Ingrese el nombre del contacto a actualizar: \");\n        $indice = buscarIndiceContacto($agenda, $nombre);\n\n        if ($indice !== -1) {\n            $telefono = validarTelefono();\n            $agenda[$indice]['telefono'] = $telefono;\n            echo \"Contacto actualizado con éxito.\\n\";\n        } else {\n            echo \"Contacto no encontrado.\\n\";\n        }\n    }\n\n    function eliminarContacto(&$agenda) {\n        $nombre = readline(\"Ingrese el nombre del contacto a eliminar: \");\n        $indice = buscarIndiceContacto($agenda, $nombre);\n\n        if ($indice !== -1) {\n            unset($agenda[$indice]);\n            $agenda = array_values($agenda); // Reindexar el array después de eliminar un elemento\n            echo \"Contacto eliminado con éxito.\\n\";\n        } else {\n            echo \"Contacto no encontrado.\\n\";\n        }\n    }\n\n    function buscarIndiceContacto($agenda, $nombre) {\n        foreach ($agenda as $indice => $contacto) {\n            if ($contacto['nombre'] === $nombre) {\n                return $indice;\n            }\n        }\n\n        return -1;\n    }\n\n    function validarTelefono() {\n        while (true) {\n            $telefono = readline(\"Ingrese el número de teléfono: \");\n\n            if (ctype_digit($telefono) && strlen($telefono) <= 8) {\n                return $telefono;\n            } else {\n                echo \"Número de teléfono no válido. Inténtelo de nuevo.\\n\";\n            }\n        }\n    }\n?>"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/php/miguelex.php",
    "content": "<?php\n\n    // Ejemplos de estructuras de datos basicos en php\n    \n    // Array\n\n    echo \"Vamos a mostrar en priemr lugar un array \\n\";\n    $array = array(5, 1, 4, 2, 3);\n\n    echo \"El array es: \\n\";\n    print_r($array);\n    echo \"\\n\";\n\n    echo \"El array ordenado es: \\n\";\n    sort($array);\n    print_r($array);\n    echo \"\\n\";\n\n    echo \"El array ordenado al reves es: \\n\";\n    rsort($array);\n    print_r($array);\n    echo \"\\n\";\n\n    $array = array(5, 1, 4, 2, 3); // Vamos volver al array original \n    echo \"Vamos a volver al array original y a mostrar el contenido de la posicion 3: \\n\";\n    echo $array[2]; // 4\n    echo \"\\n\";\n\n    echo \"\\n\\nAhora vamos a añadir un elemento al array y a mostrar su contenido: \\n\";\n    $array[] = 6;\n    print_r($array);\n    echo \"\\n\";\n\n    echo \"\\n\\nAhora vamos a eliminar el elemento con indice 3 del array y a mostrar su contenido: \\n\";\n    unset($array[3]);\n    print_r($array);\n    echo \"\\n\";\n\n    echo \"Vamos a mostrar el contenido de todas las posiciones del array: \\n\";\n    foreach ($array as $valor) {\n        echo \"$valor \\n\";\n    }\n    echo \"\\n\";\n\n    echo \"Vamos a mostrar el contenido de todas las posiciones del array con su indice: \\n\";\n    foreach ($array as $indice => $valor) {\n        echo \"$indice: $valor \\n\";\n    }\n    echo \"\\n\";\n\n    // Array asociativo\n    echo \"\\n\\nAhora vamos a crear un array asociativo y a mostrar su contenido: \\n\";\n    \n    $arrayAsociativo = array(\"uno\" => 1, \"dos\" => 2, \"tres\" => 3);\n    print_r($arrayAsociativo);\n    echo \"\\n\";\n\n    echo \"Vamos a mostrar el contenido de todas las posiciones del array asociativo: \\n\";\n    foreach ($arrayAsociativo as $valor) {\n        echo \"$valor \\n\";\n    }\n    echo \"\\n\";\n\n    echo \"\\n\\nAhora vamos a añadir un elemento al array asociativo y a mostrar su contenido: \\n\";\n    $arrayAsociativo[\"cuatro\"] = 4;\n    print_r($arrayAsociativo);\n    echo \"\\n\";\n\n    echo \"\\n\\nAhora vamos a ordenar el array asociativo y a mostrar su contenido: \\n\";\n    ksort($arrayAsociativo);\n    print_r($arrayAsociativo);\n    echo \"\\n\";\n\n    echo \"\\n\\nAhora vamos a eliminar el elemento con indice 'dos' del array asociativo y a mostrar su contenido: \\n\";\n    unset($arrayAsociativo[\"dos\"]);\n    print_r($arrayAsociativo);\n    echo \"\\n\";\n\n    // pilas\n    echo \"\\n\\nAhora vamos a crear una pila y a mostrar su contenido: \\n\";\n    $pila = array();\n    array_push($pila, 1);\n    array_push($pila, 2);\n    array_push($pila, 3);\n    print_r($pila);\n    echo \"\\n\";\n    \n    echo \"\\n\\nAhora vamos a mostrar el contenido de la pila: \\n\";\n    foreach ($pila as $valor) {\n        echo \"$valor \\n\";\n    }\n    echo \"\\n\";\n\n    echo \"\\n\\nAhora vamos a mostrar el ultimo elemento de la pila: \\n\";\n    echo array_pop($pila);\n    print_r($pila);\n    echo \"\\n\";\n\n    // colas\n    echo \"\\n\\nAhora vamos a crear una cola y a mostrar su contenido: \\n\";\n    $cola = array();\n    array_push($cola, 1);\n    array_push($cola, 2);\n    array_push($cola, 3);\n    print_r($cola);\n    echo \"\\n\";\n\n    echo \"\\n\\nAhora vamos a meter un elemento en la cola y a mostrar su contenido: \\n\";\n    array_unshift($cola, 4);\n    print_r($cola);\n    echo \"\\n\";\n\n    echo \"\\n\\nAhora vamos a mostrar el contenido de la cola: \\n\";\n    foreach ($cola as $valor) {\n        echo \"$valor \\n\";\n    }\n    echo \"\\n\";\n\n    echo \"\\n\\nAhora vamos a mostrar el primer elemento de la cola: \\n\";\n    echo array_shift($cola);\n    print_r($cola);\n    echo \"\\n\";\n\n    // Ejercicio extra\n\n    $agenda = [];\n\n    function extra() {\n\n        global $agenda;\n\n        while (true) {\n            echo \"---------- Agenda de Contactos ----------\\n\";\n            echo \"1. Buscar contacto\\n\";\n            echo \"2. Insertar contacto\\n\";\n            echo \"3. Actualizar contacto\\n\";\n            echo \"4. Eliminar contacto\\n\";\n            echo \"5. Salir\\n\";\n            echo \"-----------------------------------------\\n\";\n        \n            $opcion = readline(\"Seleccione una opción (1-5): \");\n        \n            switch ($opcion) {\n                case 1:\n                    buscarContacto($agenda);\n                    break;\n                case 2:\n                    insertarContacto($agenda);\n                    break;\n                case 3:\n                    actualizarContacto($agenda);\n                    break;\n                case 4:\n                    eliminarContacto($agenda);\n                    break;\n                case 5:\n                    echo \"Saliendo del programa. ¡Hasta luego!\\n\";\n                    exit;\n                default:\n                    echo \"Opción no válida. Inténtelo de nuevo.\\n\";\n            }\n        }\n    }\n\n    extra();\n\n\n\n    function buscarContacto($agenda) {\n        $nombre = readline(\"Ingrese el nombre del contacto a buscar: \");\n        $encontrado = false;\n\n        foreach ($agenda as $contacto) {\n            if ($contacto['nombre'] === $nombre) {\n                echo \"Nombre: {$contacto['nombre']}\\n\";\n                echo \"Teléfono: {$contacto['telefono']}\\n\";\n                $encontrado = true;\n                break;\n            }\n        }\n\n        if (!$encontrado) {\n            echo \"Contacto no encontrado.\\n\";\n        }\n    }\n\n    function insertarContacto(&$agenda) {\n        $nombre = readline(\"Ingrese el nombre del nuevo contacto: \");\n        $telefono = validarTelefono();\n\n        $agenda[] = [\n            'nombre' => $nombre,\n            'telefono' => $telefono\n        ];\n\n        echo \"Contacto insertado con éxito.\\n\";\n    }\n\n    function actualizarContacto(&$agenda) {\n        $nombre = readline(\"Ingrese el nombre del contacto a actualizar: \");\n        $indice = buscarIndiceContacto($agenda, $nombre);\n\n        if ($indice !== -1) {\n            $telefono = validarTelefono();\n            $agenda[$indice]['telefono'] = $telefono;\n            echo \"Contacto actualizado con éxito.\\n\";\n        } else {\n            echo \"Contacto no encontrado.\\n\";\n        }\n    }\n\n    function eliminarContacto(&$agenda) {\n        $nombre = readline(\"Ingrese el nombre del contacto a eliminar: \");\n        $indice = buscarIndiceContacto($agenda, $nombre);\n\n        if ($indice !== -1) {\n            unset($agenda[$indice]);\n            $agenda = array_values($agenda); // Reindexar el array después de eliminar un elemento\n            echo \"Contacto eliminado con éxito.\\n\";\n        } else {\n            echo \"Contacto no encontrado.\\n\";\n        }\n    }\n\n    function buscarIndiceContacto($agenda, $nombre) {\n        foreach ($agenda as $indice => $contacto) {\n            if ($contacto['nombre'] === $nombre) {\n                return $indice;\n            }\n        }\n\n        return -1;\n    }\n\n    function validarTelefono() {\n        while (true) {\n            $telefono = readline(\"Ingrese el número de teléfono: \");\n\n            if (ctype_digit($telefono) && strlen($telefono) <= 8) {\n                return $telefono;\n            } else {\n                echo \"Número de teléfono no válido. Inténtelo de nuevo.\\n\";\n            }\n        }\n    }\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/php/qv1ko.php",
    "content": "<?php\n\n    $contacts = [];\n    $exit = false;\n\n    while (!$exit) {\n        echo \"\\n\\n>> Select an option\\n1) Search contact\\n2) Create contact\\n3) Update contact\\n4) Delete contact\\n0) Exit\\n>> \";\n        $option = readline();\n\n        switch ($option) {\n            case '1':\n                if (count($contacts) > 0) {\n                    echo \"\\n>> Type the contact's name\\n>> \";\n                    $name = readline();\n                    if (array_key_exists($name, $contacts)) {\n                        echo \"\\nContact \" . $name . \" - Phone \" . $contacts[$name];\n                    } else {\n                        echo \"\\nContact not found\";\n                    }\n                } else {\n                    echo \"\\nNo contacts in the address book\";\n                }\n                break;\n\n            case '2':\n                echo \"\\n>> Enter the name of the new contact\\n>> \";\n                $name = readline();\n                do {\n                    echo \"\\n>> Type the phone number of the new contact (9-11 digits)\\n>> \";\n                    $phone = readline();\n                } while (!(strlen($phone) >= 9 && strlen($phone) <= 11 && ctype_digit($phone)));\n                $contacts[$name] = $phone;\n                echo \"Contact successfully created - \" . $name . \" (\" . $phone . \") \";\n                break;\n\n            case '3':\n                echo \"\\n>> Enter the name of the contact to update\\n>> \";\n                $name = readline();\n                if (array_key_exists($name, $contacts)) {\n                    do {\n                        echo \"\\n>> Enter the new phone number (9-11 digits)\\n>> \";\n                        $phone = readline();\n                    } while (!(strlen($phone) >= 9 && strlen($phone) <= 11 && ctype_digit($phone)));\n                    $contacts[$name] = $phone;\n                    echo \"Contact \" . $name . \" updated\";\n                } else {\n                    echo \"\\nContact not found\";\n                }\n                break;\n\n            case '4':\n                echo \"\\n>> Type the name of the contact you want to delete\\n>> \";\n                $name = readline();\n                if (array_key_exists($name, $contacts)) {\n                    unset($contacts[$name]);\n                    echo \"\\nThe contact \" . $name . \" has been deleted\";\n                } else {\n                    echo \"\\nContact not found\";\n                }\n                break;\n\n            case '0':\n                $exit = true;\n                echo \"\\n>> Exiting...\";\n                break;\n\n            default:\n                echo \"\\n>> Invalid option\";\n                break;\n        }\n    }\n\n?>\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/59822.py",
    "content": "from collections import namedtuple, defaultdict, Counter\nimport copy\n#Permite crear tuplas con nombre\n#Counter permite el conteo de elementos en una lista, y tambien contar elementos \n#úncos y repetitivos en coleccion de datos\n\n# ESTRUCTURAS DE DATOS \n\n## lISTA -> colección de elementos ordenados y modificables\n\nlista = [27, 13, 14, 66, 21]\nlista[2] = 54\nprint(lista)\n\nlista.append(9)\nlista.insert(2, 33)\nlista.count(13)\nprint(lista.remove(21))\nprint(lista.pop(2))\nprint(lista.sort())\nprint(lista.reverse())\nprint(lista.clear())\nprint(lista)\nlista.append(9)\nhola = lista.copy()\nprint(hola)\n\n#Copia superficial:\n## Afectará la lista original si se modifica la copia\n\nlista4 = [1,2,3, [3,4,5]]\ncopia_superficial = lista4.copy()\n\ncopia_superficial[3][0] = 100\nprint(lista4, \" La lista original se modifica\")\n\n#Copia profunda:\n## Necesario importar copy, y esta copia no afectará la lista original\n\ncopia_profunda = copy.deepcopy(lista4)\ncopia_profunda[3][0] = 234\nprint(lista4, \" La lista original no se modifica\\n\",copia_profunda, \"Mientras que la copia cambia\" )\n\n\n\n\n\n## TUPLAS -> colección de elementos ordenados e inmutables\n#No podemos agregar ni eliminar elementos\n#Usadas para datos no modificables\ntupla = (5,12,34, \"hola\")\ntupla1 = (1,2,3,4,5,6,7,8,9,10)\nprint(tupla.count(12))\nprint(tupla.index(34))\nprint(min(tupla1))\nprint(max(tupla1))\nresultado = sum(tupla1)\nprint(\"La suma es \", resultado)\n\n# Para ordenar una tupla la convertimos en lista\nlista_tupla = list(tupla1)\nlista_tupla.sort()\nprint(lista_tupla)\ntupla1 = tuple(lista_tupla)\n\n### TUPLAS CON NOMBRES -> NAMEDTUPLE\n#No podemos modificar los datos\n\nPersona = namedtuple('Persona', ['nombre', 'edad', 'ciudad']) #Nombre de la tupla y los elementos\npersona = Persona('Katherinne', 18, 'Bogotá')\n\nprint(f\"Nombre: {persona.nombre} \\nEdad: {persona.edad} \\nCiudad {persona.ciudad}\")\n\n\n#Para iterar\ndef reture(tupla1):\n    tupla_iterada = []\n    for i in tupla1:\n        tupla_iterada.append(i)\n    return \"ok\", tupla_iterada\n        \nprint(reture(tupla1))\n\n\n\n\n\n## DICCIONARIOS -> colección de elementos no ordenados, modificables e indexados\n## Almacenar y7 acceder a datos con claves\n## Contar frencuencias de un elemento\n\n\ndiccionario = {'nombre': 'Katherinne', 'edad' : 18, 'curso': 'Python'}\ndiccionario1 = diccionario.copy()\nprint(diccionario1.items())\nprint(diccionario1.keys())\nprint(diccionario1.pop(\"nombre\"))\nprint(diccionario1.setdefault(\"ciudad\", \"Bogotá\")) #setdefault da un valor por defecto\n\ncamisa ={'marca': 'Adidas'}\nprint(diccionario1.update(camisa))\nkey = {'Pais natal', 'País de trabajo'}\nvalue = \"Colombia\"\npais_ciudad = dict.fromkeys(key, value)\nprint(pais_ciudad)\nprint(len(diccionario1))\nprint(diccionario1.clear())\n#del(diccionario)\n#print(diccionario)\n\ndiccionario['edad'] = 19\nprint(diccionario['curso'], diccionario['edad'])\n\n\n#get(clave, valor por defecto) -> Permite obtener un valor de una clave\nprint(diccionario.get('nombre', 'No existe'))\n\n\ndef letter_frequency_normal(sentence):\n  frequencies = {}  # Diccionario normal\n  for letter in sentence:\n    frequency = frequencies.setdefault(letter, 0)  # Verifica si la clave existe\n    frequencies[letter] = frequency + 1\n  return frequencies\n\ndef letter_frequency_default(sentence):\n  frequencies = defaultdict(int)  # defaultdict con valor por defecto int(0)\n  for letter in sentence:\n    frequencies[letter] += 1\n  return frequencies # defaultdict se puede indexar igual que un diccionario normal\n\nif __name__ == '__main__':\n  print(letter_frequency_normal(\"hola mundo\"))\n  print(letter_frequency_default(\"hola mundo\")) \n  \n##Creditos a Felipe \n\n\n\n## CONJUNTOS -> colección de elementos no ordenados y sin elementos duplicados\n\n\n# Permite eliminar duplicados, hacer operaciones de conjuntos\n# Permite hacer pruebas de pertenencia in not in más rapidas que listas\n### Borra automaticameto los duplicados\nlista_conjunto = [1,2,3,4,5,5,5,4,3,4,320]\nconjunto = set(lista_conjunto)\nconjunto1 = {3,432,4,5634,12,5,1,42,7,2}\n\n#Operacion de conjuntos -> UNIÓN\nunion = conjunto | conjunto1\nprint(\"union \",union)\n\n#Operación de conjuntos -> INTERSECCIÓN\ninterseccion = conjunto & conjunto1\nprint(\"Intersección \", interseccion)\n\n#Operación de conjuntos -> DIFERENCIA\ndiferencia = conjunto - conjunto1\nprint(\"Diferencia \", diferencia)\n\ndiferencia = conjunto1 - conjunto\nprint(\"Diferencia 2\", diferencia)\n\n#Operación de conjuntos  -> issubset(otro_conjunto)\n##Permite saber si los elementos del primer conjutno estan en otro\n\nprint(\"Elementos conjunto estan en el segundo \", conjunto.issubset(conjunto1))\nprint(\"Elementos del segundo conjunto están en el primero \", conjunto.issuperset(conjunto1))\n\n#Operación de conjuntos -> DIFERENCIA SIMESTRICA\n#Diferencia de ambos conjuntos\ndiferencia_simetrica = conjunto ^ conjunto1\nprint(\"Diferencia simetrica \", diferencia_simetrica)\n\n\nconjunto.add(11)\nprint(conjunto)\n\nconjunto.remove(2) #Con error si no está en el set\nconjunto.discard(328193) #No error si no está en el set\nconjunto.pop() #Borra algo aleatorio\n\nprint(32432 in conjunto)\nprint(\"Longitud \", len(conjunto))\nprint(\"Maximo \", max(conjunto))\nprint(\"Minima \", min(conjunto))\nprint(sorted(conjunto))\n\nsuma1 = sum(conjunto)\nprint(\"Suma \", suma1)\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/AChapeton.py",
    "content": "# LISTS\n\n# Crear listas\nmyList = [1, 2, 3, 4, 5]\ncombinedList = ['Hello', 1, 2, True]\n\n# Acceder a listas\nprint(myList[0])\nprint(myList[-1]) # Acceder al ultimo elemento\n\n# Modificar valores de una lista\nmyList[3] = 'New'\nprint(myList)\n\n# Eliminar elementos de una lista\ndel myList[2]\nprint(myList)\n\n\n# SETS\nmySet = set([2, 2, 1, 6, 4, 3, 3, 5, 6])\nprint(mySet)\n\notherSet = {4, 6, 5, 2, 1, 3}\nprint(otherSet)\n\n# Agregar elementos a un set\nmySet.add(8)\n\n# Eliminar elementos de un set\nmySet.remove(3)\nmySet.pop() # Elimina un elemento aleatoreo\n\n# Vaciar un set\nmySet.clear()\n\n# Unit sets\nfirstSet = {1, 3, 5}\nsecoundSet = {2, 4, 6}\nprint(firstSet.union(secoundSet))\n\n\n\n# TUPLA\nmyTupla = (1, 2, 3, 3, 4)\nprint(myTupla)\n\n# Contar la cantidad de veces que un elemento se encuentra en la tupla\nprint(myTupla.count(3))\n\n# Devolver el indice del objeto\nprint(myTupla.index(4))\n\n\n# DICCIONARIO\nmyDiccionario = dict([\n      ('Nombre', 'Andres'),\n      ('Edad', 26),\n      ('Lenguaje', 'Python'),\n])\notherDiccionario = dict([\n      ('Nombre', 'Edith'),\n      ('Edad', 26),\n      ('Lenguaje', 'JavScript'),\n])\nprint(myDiccionario)\n\n# Acceder a valores\nprint(myDiccionario.get('Nombre'))\n\n# Devolver una lista de llaves y valores\nprint(myDiccionario.items())\n\n# Devolver una lista de llaves\nprint(myDiccionario.keys())\n\n# Devolver una lista de valores\nprint(myDiccionario.values())\n\n# Vaciar diccionario\nmyDiccionario.clear()\n\ndef agenda():\n  \n  myAgenda = {}\n\n  def addNewContact(name):\n    phone = input(\"Ingresar numero de telefono: \")\n    if len(phone) > 0 and len(phone) <= 11:\n      myAgenda[name] = phone\n    else:\n      print('El numero no debe ser mayor a 11 caracteres.')\n\n  def searchContactByName(name):\n    if name in myAgenda:\n      print(name, myAgenda[name])\n    else:\n      print('No existe un contacto con el nombre {name}')\n\n  def listAllContacts():\n    for name in myAgenda:\n      print(name, '->', myAgenda[name])\n\n  def deleteContact(name):\n    del myAgenda[name]\n    \n\n  while True:\n    print(\n      \"\"\"\n            AGENDA:\n            1. Agregar contacto\n            2. Buscar contacto\n            3. Actualizar contacto\n            4. Eliminar contacto\n            5. Lista de contactos\n            6. Salir\n      \"\"\"\n    )\n    option = input('\\nEscoger del menu: ')\n\n    match option:\n      case \"1\":\n        print('Agregar contacto')\n        name = input('Introduzca el nombre del contacto: ')\n        addNewContact(name)\n      case \"2\":\n        print('Buscar contacto')\n        name = input('Introduzca el nombre del contacto a buscar: ')\n        searchContactByName(name)\n      case \"3\":\n        print('Actualizar contacto')\n        name = input('Introduzca el nombre del contacto a actualizar: ')\n        if name in myAgenda:\n          addNewContact(name)\n        else:\n          print('No existe un contacto con el nombre {name}')\n      case \"4\":\n        print('Eliminar contacto')\n        name = input('Introduzca el nombre del contacto a eliminar: ')\n        if name in myAgenda:\n          deleteContact(name)\n        else:\n          print('No existe un contacto con el nombre {name}')\n      case \"5\":\n        print('Lista de contactos')\n        listAllContacts()\n      case \"6\":\n        print('Saliendo...')\n        break\n      case _:\n        print('Opcion no valida. Intentar de nuevo.')\n    \n\nagenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/AbelPerezCollado.py",
    "content": "\n# Listas\nlista = [1,2,3,4,5,6,0]\nlista.append(7) # Insercion\nprint(lista)\nlista.remove(2) # Borrado\nprint(lista)\nlista.sort() # Ordenar\nprint(lista)\n\n\n# Sets\nset_1 = set([1,2,3,4,5,6,3,2,3,3])\nprint(set_1)\nset_1.add(17) # Insertar elemento en el set\nprint(set_1)\nset_1.remove(1) # eliminar un elemento del set\nprint(set_1)\nset_2 = set([9,8,7,6,5,5,4,3])\nset_1.update(set_2) # actualizar set\nprint(set_1)\nprint(sorted(set_1)) # Ordenar set\n\n# Tuple\ntupla = (1,2,3,4,5,5,6)\nprint(tupla)\nprint(tupla.count(5)) # Devuelve el numero de veces que esta repetido el elemento\nprint(tupla.index(2)) # Devuelve el indice del objeto\n\n# Diccionario\ndic = {'Nombre':'Abel','Apellido': 'Perez', 'Lenguaje': 'Python'}\ndic['Edad'] = 40 # Insercion\nprint(dic)\ndic.pop('Edad') # Borrar\nprint(dic)\ndic.clear() # Vaciado de diccionario\nprint(dic)\n\n\n# DIFICULTAD EXTRA\nprint('AGENDA DE CONTACTOS')\nprint('1 - Busqueda de contacto')\nprint('2 - Nuevo Contacto')\nprint('3 - Actualizar contacto')\nprint('4 - Borrar contacto')\nopcion = input('Seleccione la opción deseada (0 para salir): ')\n\nagenda = []\n\n\ndef validar_telefono(num):\n    while not num.isdigit() or len(num)>= 11:\n        print('El numero debe ser numerico y no superar los 11 digitos.')\n        num = input('Vuelve a introducir el numero de telefono:')\n    return num\n\nwhile opcion != '0':\n    contacto = {'Nombre':'','Tlfno':''}\n    if opcion == '1':\n        nombre = input('Introduce el nombre del contacto a buscar: ')\n        [print(contacto) for contacto in agenda if contacto['Nombre'] == nombre ]\n        \n    elif opcion == '2':\n        nombre = input('Nombre del contacto: ')\n        telefono = input('Número de telefono: ')\n        telefono = validar_telefono(telefono)\n        contacto['Nombre'] = nombre\n        contacto['Tlfno'] = telefono\n        agenda.append(contacto)\n        \n    elif opcion == '3':\n        nombre = input('Nombre del contacto a modificar: ')\n        for contact in agenda:\n            if contact['Nombre'] == nombre:\n                telefono = input(f'Nuevo telefono para {nombre}')\n                contact['Tlfno'] = validar_telefono(telefono)\n\n            \n    elif opcion == '4':\n        nombre = input('Nombre del contacto a modificar: ')\n        for contact in agenda:\n            if contact['Nombre'] == nombre:\n                agenda.remove(contact)\n                print('Contacto eliminado')\n    elif opcion == '0':\n        print('MUCHAS GRACIAS POR USAR LA AGENDA DE CONTACTOS')\n        break\n    else:\n        print('Opcion no deseada. Seleccione la opcion correcta.')\n    \n    print('1 - Busqueda de contacto')\n    print('2 - Nuevo Contacto')\n    print('3 - Actualizar contacto')\n    print('4 - Borrar contacto')\n    opcion = input('Seleccione la opción deseada (0 para salir): ')\n    "
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/AgustinDamonte17.py",
    "content": "# ===================================\n# PARTE 1: ESTRUCTURAS Y OPERACIONES\n# ===================================\n\nprint(\"====== ESTRUCTURAS DE PYTHON ======\")\n\n# LISTA\nlista = [3, 1, 4]\nprint(\"Lista inicial:\", lista)\nlista.append(2)  # inserción\nprint(\"Lista tras append:\", lista)\nlista[1] = 10  # actualización\nprint(\"Lista tras actualización:\", lista)\nlista.remove(4)  # borrado\nprint(\"Lista tras remove:\", lista)\nlista.sort() #ordenación\nprint(\"Lista ordenada:\", lista)\nprint()\n\n# TUPLA (inmutable, pero se puede crear)\ntupla = (1, 2, 3)\nprint(\"Tupla:\", tupla)\nprint()\n\n# SET (Posición variable - no se puede ordenar)\nconjunto = {5, 2, 8}\nprint(\"Set inicial:\", conjunto)\nconjunto.add(10)  # inserción\nprint(\"Set tras add:\", conjunto)\nconjunto.discard(2)  # borrado\nprint(\"Set tras discard:\", conjunto)\n# No se puede ordenar un set directamente, pero sí convertir\nprint(\"Set ordenado (como lista):\", sorted(conjunto))\nprint()\n\n# DICCIONARIO\ndiccionario = {\"a\": 1, \"b\": 2}\nprint(\"Diccionario inicial:\", diccionario)\ndiccionario[\"c\"] = 3  # inserción\nprint(\"Diccionario tras inserción:\", diccionario)\ndiccionario[\"a\"] = 100  # actualización\nprint(\"Diccionario tras actualización:\", diccionario)\ndel diccionario[\"b\"]  # borrado\nprint(\"Diccionario tras borrado:\", diccionario)\n# Ordenar por clave\nprint(\"Diccionario ordenado por clave:\", dict(sorted(diccionario.items())))\nprint()\n\n# STRING\ntexto = \"hola mundo\"\nprint(\"Texto original:\", texto)\nprint(\"Texto en mayúsculas:\", texto.upper())\nprint(\"Texto reemplazado:\", texto.replace(\"hola\", \"hello\"))\nprint()\n\n\n# ===================================\n# PARTE 2: AGENDA DE CONTACTOS (MENÚ)\n# ===================================\n\ndef validar_telefono(numero):\n    return numero.isdigit() and len(numero) <= 11\n\ndef mostrar_menu():\n    print(\"\\n====== AGENDA DE CONTACTOS ======\")\n    print(\"1. Insertar contacto\")\n    print(\"2. Buscar contacto\")\n    print(\"3. Actualizar contacto\")\n    print(\"4. Eliminar contacto\")\n    print(\"5. Mostrar todos\")\n    print(\"6. Salir\")\n\nagenda = {}\n\nwhile True:\n    mostrar_menu()\n    opcion = input(\"Selecciona una opción (1-6): \")\n\n    if opcion == \"1\":\n        nombre = input(\"Nombre: \").strip()\n        telefono = input(\"Teléfono: \").strip()\n        if validar_telefono(telefono):\n            agenda[nombre] = telefono\n            print(f\"Contacto '{nombre}' agregado.\")\n        else:\n            print(\"Teléfono inválido. Debe ser numérico y de hasta 11 dígitos.\")\n\n    elif opcion == \"2\":\n        nombre = input(\"Nombre a buscar: \").strip()\n        if nombre in agenda:\n            print(f\"{nombre}: {agenda[nombre]}\")\n        else:\n            print(\"Contacto no encontrado.\")\n\n    elif opcion == \"3\":\n        nombre = input(\"Nombre a actualizar: \").strip()\n        if nombre in agenda:\n            nuevo_telefono = input(\"Nuevo teléfono: \").strip()\n            if validar_telefono(nuevo_telefono):\n                agenda[nombre] = nuevo_telefono\n                print(\"Contacto actualizado.\")\n            else:\n                print(\"Teléfono inválido.\")\n        else:\n            print(\"Contacto no encontrado.\")\n\n    elif opcion == \"4\":\n        nombre = input(\"Nombre a eliminar: \").strip()\n        if nombre in agenda:\n            del agenda[nombre]\n            print(\"Contacto eliminado.\")\n        else:\n            print(\"Contacto no encontrado.\")\n\n    elif opcion == \"5\":\n        if not agenda:\n            print(\"Agenda vacía.\")\n        else:\n            print(\"Contactos:\")\n            for nombre, telefono in agenda.items():\n                print(f\"{nombre}: {telefono}\")\n\n    elif opcion == \"6\":\n        print(\"¡Hasta luego!\")\n        break\n\n    else:\n        print(\"Opción inválida. Intenta de nuevo.\")\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/AlainMartz.py",
    "content": "### 03 ESTRUCTURAS DE DATOS ###\n\n##  * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n\n# Listas\n# ------\n\nprelist = list([1,2,2,3,4,5,6,666,7]) # Se construye una lista con el método list\nprint(prelist)\n\nlista = ['mercurio','venus','tierra','marte','jupiter','saturno','urano','neptuno','plutón'] # La lista\nprint(lista)\n\nlista.extend(['planeta x','planeta y','planeta z']) # Extiende la lista según la cantidad de iterables\nprint(lista)\n\nlista.insert(0, 'sol') # inserta un ítem en una posición determinada\nprint(lista)\n\nlista.remove('planeta z') # Remueve un ítem que coincida con el valor dado\nprint(lista)\n\nlista.pop(-1) # Remueve un ítem según el índice colocado\nprint(lista)\n\ndel lista[9:] # Borra elementos de la lista pasando un entero o un slice\nprint(lista)\n\nlista[0] = 'Sol' # Actualización de un valor\nprint(lista)\n\nlista.sort() # Ordena la lista\nprint(lista)\n\nlista.reverse() #Invierte el orden de la lista\nprint(lista)\n\n# Comprehensión de lista\n\nsquared = [x**2 for x in range(1,7)]\nprint(squared)\n\n# Comprehensión de lista anidada\nmultsquared = [[s*i for s in squared] for i in range(2,5)]\nprint(multsquared)\n\n\n# Tuplas\n# ------\n\ntup = tuple(multsquared) # Construir tupla\nprint(tup)\n\ntupla = 1,2,2,3 # Construir tupla\nprint(tupla)\n\ntupla_1 = (1,1,1,\"uno\",2,'alpha',4,True)  # Construir tupla\nprint(tupla_1)\n\nprint(tupla_1[5]) # Acceder a un valor indexado\n\n# tupla_1[0] = 0 # no acepta asignación de nuevos valores, inmutable\n\nprint(tupla_1.count('uno')) # Cuenta un valor\n\n# Diccionario\n# -----------\n\ndicc = dict([                   ## Creación de diccinoario con método dic()\n    ('mar', 'Mediterráneo'),\n    ('oceano', 'Atlántico'),\n    ('longitud', 3700),\n    ('ancho', 1600),\n    ('profundidad', 1430),\n    ('salinidad', 36.2)\n])\nprint(dicc)\n\negeo = {\n    'nombre':'Mar Egeo',\n    'oceano':'Mar Mediterráneo',\n    'cuenca':'cuenca del mar Egeo',\n    'longitud':600,\n    'ancho':400,\n    'profundidad':2639\n    }\n\nprint(egeo) ## Creación de diccionario con llaves\n\negeo['tipo'] = 'Mar' ## Inserción de datos\nprint(egeo)\n\negeo.pop('tipo') ## Eliminación de datos\nprint(egeo)\n\negeo['profundidad'] = 3544 ## Actualización de datos\nprint(egeo)\n\nmar_egeo = egeo.copy() # Devuelve una copia del diccionario\nprint(mar_egeo)\n\nprint(mar_egeo.get('nombre')) # Devuelve el valor de la key\n\nprint(mar_egeo.items())  # Devuelve los pares de key value del diccionario\n\nprint(mar_egeo.keys())  # Devuelve las keys del diccionario\n\nprint(mar_egeo.values())  # Devuelve los values del diccionario\n\n\n\n\n\n\n\n\n\n\n\n\n## Comprehension de diccionarios\n\npoten3 = {x: x**3 for x in (1,2,3,4,5,6,7,8,9,10)}\nprint(poten3)\n\n\n# Sets (conjuntos)\n# ----------------\n\nconj = set([1,1,1,1,2,31,23,12,312])\nprint(conj)\n\nconj2 = {\"alpha\",\"beta\",\"gamma\"}\nprint(conj2)\n\nconj2.add(\"theta\")  # Añade un elemento al conjunto\nprint(conj2)\n\nconj2.remove(\"theta\") # Remueve un elemento del conjunto\nprint(conj2)\n\nconj2.update(conj) # Actualiza el conjunto con otro conjunto, el resultado no está ordenando\nprint(conj2)\n\n\n### Desafío extra\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\"\"\"\n\n#def agenda():\nagenda = dict()\n\ndef mostrar_menu():\n    print(\"\"\"\n    ---------AGENDA---------\n    Qué desea hacer:\n    1. Agregar contacto\n    2. Buscar contacto          \n    3. Actualizar contacto\n    4. Eliminar contacto\n    5. Listar contactos\n    6. Salir de la agenda\n        \"\"\")\n\ndef añadir_contacto():\n    nombre = input(\"Ingrese su nombre: \")\n    \n    telefono = input(\"Ingrese su número, debe ser menor a 11 dígitos\")\n\n    if telefono.isdigit() and len(telefono) <= 11:\n        agenda[nombre] = telefono\n        print (f\"El contacto: {nombre} - {telefono}, se ha registrado exitosamente\")        \n    else:\n        print(\"Número inválido. Asegúrese de que el número tiene menos de 11 dígitos y solo contiene números.\")\n\n\ndef buscar_contacto():      \n    busqueda = int(input(\"Ingrese 1 si desea buscar por nombre y 2 si desea buscar por número: \"))\n    if busqueda == 1:\n        nom = input(\"Ingrese el nombre que desea buscar: \")\n        if nom in agenda:\n            print(f\"El número del contacto es: {nom} - {agenda[nom]}\")\n        else:\n            print(\"Ingrese el nombre nuevamente, verifique mayúsculas y minúsculas\")\n    \n    elif busqueda == 2:\n        num = input(\"Ingrese el número que desea buscar: \")\n        encontrado = False\n\n        for nombre, fono in agenda.items():\n            if fono == num:\n                print(f\"Contacto encontrado: {nombre} - {fono}\")\n                encontrado = True\n                break\n        if not encontrado:\n            print(\"Número inválido o inexistente\")\n    \n    else:\n        print(\"Opción de búsqueda inválida\")            \n\ndef actualizar_contacto():\n    nom_nue = input(\"Ingrese el nombre de contacto que desea actualizar: \")\n\n    if nom_nue in agenda:\n        while True:\n            nuenum = input(\"Ingrese el nuevo número: \")\n            if nuenum.isdigit() and len(nuenum) <= 11:\n                agenda[nom_nue] = nuenum\n                print(f\"Contacto encontrado {nom_nue} - {agenda[nom_nue]}\")\n                break\n            else: \n                print(\"Número inválida, asegúrese que el número tiene 11 o menos dígitos\")\n\n    else:\n        print(\"Contacto no encontrado, compruebe mayúsculas y minúsculas\")\n\n\ndef borrar_contacto():\n    delnom = input(\"Ingrese el nombre que desea eliminar\")\n\n    if delnom in agenda:\n        agenda.pop(delnom)\n        print(f\"El contacto {delnom} se ha elimiado correctamente\")\n    else:\n        print(\"Nombre inválido o no existente. Compruebe mayúsculas, minúsculas y vuelva a ingresarlo\")\n\n\ndef listar_contactos():\n    if agenda:\n        for nom in agenda:\n            print(f\"{nom} - {agenda[nom]}\")    \n    else:\n        print(\"La agenda está vacía\")        \n\n\n\nwhile True:\n    mostrar_menu()\n    opcion = int(input(\"Ingrese una opción: \"))\n    if opcion == 1:\n        añadir_contacto()   \n    elif opcion == 2:\n        buscar_contacto()\n    elif opcion == 3:\n        actualizar_contacto()\n    elif opcion == 4:\n        borrar_contacto()\n    elif opcion == 5:\n        listar_contactos()\n    elif opcion == 6:\n        print(\"Adios, gracias por utilizar la agenda!\")\n        break\n    else:\n        print(\"Ingrese nuevamente el número, escoga un número del 1 al 6\")\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/AlbertoMorilla.py",
    "content": "# #03 ESTRUCTURAS DE DATOS\n\n\n## Ejercicio\n #- Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n #- Utiliza operaciones de inserción, borrado, actualización y ordenación.\n \n### LISTAS\n\nnombres = ['Alberto', 'Ana', 'Laura', 'Teresa', 'Carmen', 'Daniel']\nprint(type(nombres))\n\nvarios = ['Hola', 150, True]\nprint(type(varios))\n\nprint (nombres[2])\nprint (nombres[-1])\nprint (type(varios[1]))\n\nnombres[3:4] = ['Maria Teresa', 'MariCarmen']\nprint (nombres)\n\nnombres.append('Leo')\nprint (nombres)\n\nnombres.extend([\"Angel\", \"Pablo\"])\nprint (nombres)\n\nnombres.remove('Ana')\nprint (nombres)\n\nnombres.insert(1, 'Maria')\nprint (nombres)\n\nnombres.pop(5)\nprint (nombres)\n\nnombres.sort()\nprint (nombres)\n\nclasificacion = [10,7,5,3,1,3]\nprint (clasificacion.count(3))\n\nprint (clasificacion.index(3))\n\nprint ('8' in clasificacion)\n\nnombres.clear()\nprint (nombres)\n\n## TUPLAS\n\ncolores = (\"azul\", \"verde\", \"rojo\", \"negro\")\nnumero = (2,)\n\nprint(type(numero))\nprint(type(colores))\nprint (colores[0])\nprint (colores[-1])\nprint(colores.index('verde'))\nprint(colores.count('azul'))\nprint('rojo' in colores)\n\n## SETS\n\npesos1 = {22, 66, 25}\npesos2 = set([85,55,96,47,122])\nprint(pesos2)\nprint(type(pesos1))\nprint(pesos1.intersection(pesos2))\n\npesos2.add(77)\nprint(pesos2)\n\npesos2.remove(122)\nprint(pesos2)\n\npesos2.discard(51)\nprint(pesos2)\n\npesos2.pop()\nprint(pesos2)\n\npesos2.clear()\nprint(pesos2)\n\n## DICCIONARIO\n\nusuario = dict([\n    ('nombre', 'Juan'),\n    ('edad', 25),\n    ('ciudad', 'Bogota')\n])\nciudades = {'Alberto':'Sevilla', 'Laura':'Granada', 'Toni':'Madrid'}\nprint(usuario)\n\nciudades.popitem()\nprint (ciudades)\nprint (ciudades['Alberto'])\n\nusuario2 = {'telefono':658987412}\nusuario.update(usuario2)\nprint (usuario)\n\nusuario.pop('edad')\nprint (usuario)\n\nciudades = sorted(ciudades.items())\nprint(ciudades)\n\nciudades.clear()\nprint (ciudades)\n\n# DIFICULTAD EXTRA (opcional):\n # Crea una agenda de contactos por terminal.\n # - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n # - Cada contacto debe tener un nombre y un número de teléfono.\n # - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n #   los datos necesarios para llevarla a cabo.\n # - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n #   (o el número de dígitos que quieras)\n # - También se debe proponer una operación de finalización del programa.\n # - El programa debe mostrar la agenda de contactos al finalizar.\n\ndef mi_agenda ():\n\n    def insert_contact():\n        phone = input(\"\\nIntroduce el telefono del contacto: \")\n        if phone.isdigit() and len(phone) > 0 and len(phone) <= 11:\n            agenda[name] = phone\n        else:\n            print(\"El telefono no es correcto, puede que tenga mas de 11 digitos\")\n\n    agenda = {}\n    while True:\n\n        print('1. Buscar contacto')\n        print('2. Insertar contacto')\n        print('3. Actualizar contacto')\n        print('4. Eliminar contacto')\n        print('5. Salir')\n\n        option = input(\"\\nSelecciona una opcion: \")\n\n        match option:\n            case '1':\n                name = input('\\nIntroduce el nombre del contacto que desea buscar: ')\n\n                if name in agenda:\n                    print(f\"El número de telefono de {name} es {agenda[name]}.\")\n                else:\n                    print('\\nNo hay contactos con ese nombre')\n                \n            case '2':\n                name = input(\"\\nIntroduce el nombre del contacto: \")\n                insert_contact()\n        \n            case '3':\n                name = input(\"\\nIntroduce el nombre del contacto que desea actualizar: \")\n                if name in agenda:\n                    insert_contact()\n                else:\n                    print('\\nNo hay contactos con ese nombre')\n                \n            case '4':\n                name = input(\"\\nIntroduce el nombre del contacto que desea eliminar: \")\n                if name in agenda:\n                    del agenda[name]\n                else:\n                    print('\\nNo hay contactos con ese nombre')\n                \n            case '5':\n                print('Saliendo de la agenda.')\n                break\n            case _:\n                print(\"Opción no válida. Por favor, selecciona una opción válida.\")\n\nmi_agenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Aldroide.py",
    "content": "# Ejemplos de la Estructuras de Datos en Python\n\n\"\"\"\nListas: Una lista es una colección ordenada y modificable de elementos. \nPuedes acceder a los elementos de una lista mediante índices.\n\"\"\"\nfrom array import array\nlista = [1, 2, 3, 4, 'cinco', 'seis', 'siete', 8.1, 9.0, 'a', 'b']\n\n\n\"\"\" \nTuplas: Similar a las listas, pero son inmutables, es decir, \nno pueden ser modificadas una vez creadas.\n\"\"\"\ntupla = (1, 2, 3, 'cuatro', 5.0)\n\n\n\"\"\"\nConjuntos (Sets): Un conjunto es una colección no ordenada\nde elementos únicos. Se utilizan para realizar operaciones \nde conjunto como unión, intersección, diferencia, etc\n\"\"\"\nconjunto = {1, 2, 3, 3, 4, 5, 6}\n\n\n\"\"\"\nDiccionarios: Un diccionario es una colección no ordenada de pares clave-valor. \nSe accede a los valores a través de las claves.\n\"\"\"\ndiccionario = {\"clave1\": \"Valor1\", \"numero\": 2, \"lista\": [1, 2, 3]}\n\n\n\"\"\"\nCadenas (Strings): No es una estructura de control como tal pero son utilizadas \npara representar texto y son inmutables\n\"\"\"\ncadena = \"Esto es una cadena de texto\"\n\n\n\"\"\"\nColas y Pilas: Estas estructuras pueden implementarse utilizando listas. \nLas listas pueden actuar como: colas (FIFO - First In, First Out) \ny pilas (LIFO - Last In, First Out).\n\"\"\"\n# Cola\ncola = [1, 2, 3]\ncola.append(4)  # agrega al final\nelemento = cola.pop(0)  # Elimina del principio\n\n# pila\npila = [1, 2, 3]\npila.append(4)  # apgrea al final\npila.pop()  # Elimina del final\n\n\"\"\"\nArrays Similar a las listas, pero más eficientes para almacenar\nelementos del mismo tipo. Requieren la importación del módulo array.\n\"\"\"\n\nmi_array = array('i', [1, 2, 3])\n\n# Dificultad Extra\nagenda = {\n    \"Aldo\": 3112343566\n}\n# Buscar Contactos\n\n\ndef search(name):\n    if name in agenda:\n        return name, agenda[name]\n    return \"No existe\"\n\n# Insertar\n\n\ndef instert(name, phone):\n    agenda[name] = phone\n\n# Actualizar\n\n\ndef update(name, phone):\n    agenda[name] = phone\n\n# Borrar\n\n\ndef delete(name):\n    agenda.pop(name)\n\n\n# Mostrar\ndef show():\n    for name, phone in agenda.items():\n        print(name, \":\", phone)\n\n\nwhile True:\n    print(\"\"\"\n            Operación que desea\n            1.- Buscar\n            2.- Insertar\n            3.- Actualizar\n            4.- Eliminar\n            5.- Mostrar \n            6.- Salir\n          \"\"\")\n    ctrl = True\n    opc = input()\n    match opc:\n        case \"1\":\n            name = input(\"Introduzca el nombre del contacto: \\n\").capitalize()\n            print(search(name))\n        case \"2\":\n            while ctrl:\n                name = input(\"Introduzca nombre del contacto: \").capitalize()\n                phone = input(\"Introduzca número: \")\n                if len(phone) < 5 or len(phone) > 10 or not phone.isdigit():\n                    print(\"Número incorrecto, intenta de nuevo\")\n                else:\n                    instert(name, phone)\n                    ctrl = False\n        case \"3\":\n            name = input(\n                \"Introduzca el nombre del contacto que quiera actualizar: \").capitalize()\n            if name in agenda:\n                phone = input(\"Introduzca el nuevo telefono: \")\n                update(name, phone)\n            else:\n                print(\"Usuario no encontrado\")\n        case \"4\":\n            name = input(\n                \"Introduzca el nombre del contacto que quiera eliminar: \").capitalize()\n            if name in agenda:\n                delete(name)\n            else:\n                print(\"usuario no existe\")\n        case \"5\":\n            show()\n        case \"6\":\n            print(\"Salio del programa\")\n            break\n        case _:\n            print(\"Selecciona una opción valida\")\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Aleran07.py",
    "content": "# 03\n# Estructuras soportadas por defecto en Python\n\n\n### Estructuras de control\n\n\"\"\"\nCondicional if, elif and else\n\"\"\"\nx = 5\nif x > 0:\n    print(\"Mayor a cero\")\nelif x == 0:\n    print(\"Cero\")\nelse:\n    print(\"menor a cero\")\n\n\"\"\"\nBubles\n\"\"\"\n# Bucles for\nfor i in range(5):\n    print(i)\n\n# Bucles while\nwhile i > 0:\n    print(i)\n    i -=1\n\n\"\"\"\"\nControl de flujo de bucles\n\"\"\"\n# break, continue and pass\n\nfor i in range(11):\n    if i == 3:\n        continue # se salta el numero en cuestion\n    elif i == 6:\n        pass # no hace nada\n    elif i == 9:\n        break # rompe el bucle\n    print(i)\n\n\"\"\"\nManejo de errores\n\"\"\"\ntry:\n    print(10 / 0) # Error divicion por cero\nexcept ZeroDivisionError:\n    print(\"Error: división por cero\") # Manejo de error para que permita ejecutar el codigo\nfinally:\n    print(\"Esto siempre se ejecuta\")\n\n# Capturar cualquier error\ntry:\n    num = int(\"hola\")   # Error: no se puede convertir a int\nexcept Exception as e:   # e guarda el error\n    print(\"Ocurrió un error:\", e)\n\n# pruba sin error\ntry:\n    x = 10 / 2\nexcept ZeroDivisionError:\n    print(\"Error: división por cero\")\nelse: # else en si es una excepcion\n    print(\"Todo salió bien:\", x)\n\n\n\"\"\"El bloque finally se ejecuta siempre, haya o no error.\nSe usa mucho para cerrar archivos, conexiones, etc.\"\"\"\ntry:\n    f = open(\"archivo.txt\")\n    contenido = f.read()\nexcept Exception as e:   # e guarda el error\n    print(\"Ocurrió un error:\", e)\nfinally:\n    print(\"Se intentó abrir el archivo\")\n\n\n\"\"\"raise sirve para lanzar manualmente un error.\nEsto es útil si quieres validar condiciones en tu programa.\"\"\"\n\ndef dividir(a, b):\n    if b == 0:\n        raise ValueError(\"El divisor no puede ser cero\")\n    return a / b\n\nprint(dividir(10, 2))  # Funciona\nprint(dividir(10, 0))  # Lanza ValueError\n\n\n\"\"\"\nEstrutura de datos\n\"\"\"\n# listas\nnumeros = [1, 2, 3, 4]\n# insercion en listas\nnumeros.append(5) # agrega al final\nnumeros.insert(0, 1) # inserta 1 en posicion 0\n# actualizar\nnumeros[4] = 7 # cambia el valor en indice 4\n# eliminar\nnumeros = [1, 2, 3, 4]\nnumeros.remove(2)      # Elimina el valor 2\nnumeros.pop(0)         # Elimina el elemento en posición 0\ndel numeros[1]         # Elimina por índice\nprint(numeros)\n# ordenar\nnumeros.append(5)\n# numeros = [5, 2, 8, 1]\nnumeros.sort()           # Ordena de menor a mayor\nprint(numeros)           # [1, 2, 5, 8]\nnumeros.sort(reverse=True)  # Ordena de mayor a menor\nprint(numeros)              # [8, 5, 2, 1]\n\nnueva_lista = sorted(numeros) # se puede usar esta forma para no modificar la lista original\n\n\n# tuplas\ncoordenadas = (10, 20)\n\n# conjuntos\nfrutas = {'manzana', 'pera', 'uva'}\n# insercion en conjuntos\nfrutas.add(\"fresa\")       # Agrega un elemento\nprint(frutas)\n# elimina\nfrutas = {\"manzana\", \"pera\", \"uva\"}\nfrutas.remove(\"pera\")     # Elimina un valor (error si no existe)\nfrutas.discard(\"fresa\")   # Elimina si existe, sin error\nprint(frutas)\n\n\n\n# diccionarios\npersonas = {'nombre': \"ana\",'edad': 25, 'nombre1': 'pepe', 'edad1': 23}\nprint(personas)\npersonas['nombre2'] = \"pedro\"\npersonas['edad2'] = 25    # Inserta una nueva clave con valor\nprint(personas)\n# actualizar\npersonas[\"edad\"] = 40\nprint(personas)\n#eliminar\ndel personas[\"edad\"]       # Elimina una clave\nprint(personas)\n\n# ordenar diccionarios\npersona = {\"c\": 3, \"a\": 1, \"b\": 2}\nordenado = dict(sorted(persona.items()))  # Por clave\nprint(ordenado)\n\n\ncuadrados = [x**2 for x in range(5)]\nprint(cuadrados) # [0, 1, 4, 9, 16]\n\n# funciones anonimas\ncuadrado = lambda x: x**2\nprint(cuadrado(4))  # 16\n\n\n\"\"\"Ejercicio 3\"\"\"\n\nagenda = []\n\ndef mi_agenta():\n\n    opciones = [1, 2, 3, 4, 5]\n\n    def opcion_1():\n        nombre = input(\"Ingrese el nombre del usuario: \").strip()\n        celular = input(\"Ingrese el celular del usuario: \").strip()\n        if not celular.isdigit():\n            print(\"\\nEl numero solo debe contener digitos\")\n            return opcion_1()\n        if len(celular) > 10:\n            print(\"\\nEl numero no debe tener mas de 10 digitos\")\n            return opcion_1()\n        agenda.append({\"nombre\": nombre, \"celular\": celular})\n        print(f\"\\nUsuario '{nombre}' agregado correctamente.\\n\")\n        pantalla()\n\n    def opcion_2():\n        busqueda_usuario = input(\"\\nInserte el nombre del usuario: \").strip()\n        encontrado = False\n        for u in agenda:\n            if u[\"nombre\"].lower() == busqueda_usuario.lower():\n                print(f\"\\nInformacion del usuario: nombre: {u['nombre']} Celular: ({u['celular']})\\n\")\n                encontrado = True\n                pantalla()\n        if not encontrado:\n            print(\"\\nUsuario no existe\\n\")\n            pantalla()\n\n    def opcion_3():\n        name = input(\"\\nInserte el nombre del usuario a actualizar: \").strip()\n        encontrado = False\n        for u in agenda:\n            if u[\"nombre\"] == name:\n                print(f\"\\nInformacion del usuario: nombre: {u['nombre']} Celular: ({u['celular']})\\n\")\n                nuevo_nombre = input(\"Ingrese el nuevo nombre (deje vacio para no cambiar nada: )\")\n                nuevo_celular = input(\"Ingrese el nuevo celular (deje vacio para no cambiar nada: )\")\n                if nuevo_celular:\n                    if not nuevo_celular.isdigit():\n                        print(\"\\nEl numero solo debe contener digitos\")\n                        return opcion_1()\n                    if len(nuevo_celular) > 10:\n                        print(\"\\nEl numero no debe tener mas de 10 digitos\")\n                        return opcion_1()\n                    u[\"celular\"] = nuevo_celular\n                if nuevo_nombre:\n                    u[\"nombre\"] = nuevo_nombre\n\n                print(\"\\nSe a actualizado correctamente.\\n\")\n                pantalla()\n        if not encontrado:\n            print(\"\\nUsuario no existe, no actualiza\\n\")\n            pantalla()\n\n    def opcion_4():\n        name = input(\"\\nInserte el nombre del usuario a eliminar: \").strip()\n        for u in agenda:\n            if u[\"nombre\"] == name:\n                print(f\"\\nInformacion del usuario: nombre: {u['nombre']} Celular: ({u['celular']})\\n\")\n                print(f\"\\nSe a eliminado correctamente a {u['nombre']}\\n\")\n\n                agenda.remove(u)\n                pantalla()\n    def opcion_5():\n        print(\"Saliendo del programa...\")\n        exit()\n\n\n    acciones = {\n    1: opcion_1,\n    2: opcion_2,\n    3: opcion_3,\n    4: opcion_4,\n    5: opcion_5\n    }\n\n    def operacion(y): # don't used\n        if y in opciones:\n            print(f\"Opcion elegida es: {y}\")\n\n\n    def pantalla():\n            while True:\n                try:\n                    x = int(input(\"Que accion deseas realizar:\\n1. Insertar usuario\\n2. Buscar usuario\\n\" \\\n                            \"3. Actualizar usuario\\n4. Eliminar usuario\\n5. Salir\\n\" \\\n                            \"Indique una opción: \"))\n                    if x in opciones:\n                        accion = acciones.get(x, lambda: print(\"Opción no válida\"))\n                        accion()\n                        break\n                    else:\n                        print(\"\\nBoludo es del 1 al 5\\n\")\n                except ValueError:\n                    print(\"\\nSolo se permiten numeros\\n\")\n\n    pantalla()\n\nmi_agenta()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/AllanYSalazarG.py",
    "content": "\"\"\"#03 ESTRUCTURAS DE DATOS\"\"\"\n\n# ----------------------- Listas -----------------------\n# Estas se encierran por corchetes cuadrados []\n\nimport random\n\nprint(\"------ LISTAS ------\\n\")\nlista = [1, 2, 3]\nnuevaLista = list(range(3))  # List recibe un iterable para crear una lista\nprint(f\"Lista original: {lista} | {nuevaLista}\")\nlista.append(4)  # agrega un item al final de la lista\nprint(f\"Agregado \\\"4\\\" con append: {lista}\")\n# lista.extend(lista)\n# agrega el 2do argumento en la posición indicada por el 1er argumento\nlista.insert(1, 5)\nprint(f\"Agregando \\\"5\\\" en índice \\\"1\\\" con insert: {lista}\")\n# Quita el valor de la lista (Si hay muchos iguales, quita el primero)\nlista.remove(5)\nprint(f\"Quitando \\\"5\\\" con remove: {lista}\")\n# Quita el último valor de la lista (como pilas) y regresa el valor quitado\nelementoEliminado = lista.pop()\nprint(f\"Quitando el último valor \\\"{elementoEliminado}\\\" con pop: {lista}\")\n# Regresa el indice donde se encuentra el argumento\nprint(f\"Index de 2: {lista.index(2)}\")\n# Regresa el # de veces que el argumento se repite\nprint(f\"Repet de 2: {lista.count(2)}\")\nlista.sort(reverse=True)\nprint(f\"Lista invertida con sort: {lista}\")\nlista.reverse()\nprint(f\"Lista invertida con reverse: {lista}\")\nlista.clear()  # Vacía la lista\n\n\"\"\"\nPILAS: Se usa list.append() para agregar un elemento a la lista y list.pop() para sacarlo\nUSA LIFO (last in, first out)\n\nCOLAS: Se usa list.append() igual, pero se usa list.popleft() para sacar el primero\nUSA FIFO (first in, first out)\n\nLa diferencia es que se requiere importar deque de collections para poder usarse como cola\n\nSacado de python.org ⬇️\n\nfrom collections import deque\n\nqueue = deque([\"Eric\",\"John\",\"Michael\"])\nqueue.append(\"Terry\") # Agrega a Terry\nqueue.append(\"Graham\") # Agrega a Graham\nqueue.popleft() # Saca al primero en llegar (Eric)\nqueue.popleft() # Saca al segundo en llegar (John)\nqueue # Muestra la cola \"deque([\"Michael\",\"Terry\",\"Graham\"])\"\n\"\"\"\n\n\"\"\"\nComprensión de listas\n\nEs como hacer un for y usando .append() para ir agregando el elemento en cada iteración\n\n# Esto ⬇️\nlistaDeNumeros = []\nfor numero in range(10):\n    listaDeNumeros.append(numero)\n\n# Es equivalente a esto ⬇️\nlistaDeNumeros = [numero for numero in range(10)]\n \"\"\"\n\n\n\"\"\" La instrucción del hace lo mismo que la función pop, pero no devuelve ningún valor \"\"\"\n\n\n# ----------------------- Tuplas -----------------------\n# Estas se encierran por paréntesis ()\n\nprint(\"\\n------ TUPLAS ------\\n\")\ntupla1 = (1, 2, 3)\ntuplaNueva = tuple(range(3))  # tuple recibe un iterable para crear una tupla\n# Al agregar datos separados con comas, tambien se crean las tuplas (empaquetado)\ntupla2 = \"hola\", 1, \"cien\"\nsaludo, entero, numStr = tupla2  # Desempaquetado\nnuevaTupla = tupla1, tupla2  # Podemos crear nuevas tuplas de otras tuplas existentes\n# tupla1.append() # No se pueden modificar las tuplas\n# tupla1.pop()\n# Podemos hacer tuplas con listas\ntuplaConListas = ([1, 2, 3], [4, 5, 6], [7, 8, 9])\nprint(nuevaTupla)\n\n\n# ----------------------- Conjuntos -----------------------\n# Se encierran por llaves {}\n# Colección no ordeneda y sin elementos repetidos\n# Se puede usar la funcion set() para crear un conjunto\n# Se puede usar la comprension de conjuntos (identica a comprension de listas)\n\nprint(\"\\n------ CONJUNTOS ------\\n\")\nfrutas = {\"manzana\", \"naranja\", \"pera\", \"fresa\", \"platano\"}\nlistaVerduras = [\"zanahoria\", \"zanahoria\", \"tomate\",\n                 \"cilantro\", \"tomate\", \"jalapeno\"]\nverdurasSinRepetir = set(listaVerduras)  # set recibe un iterable\n# in indica si un elemento está en una lista o conjunto\nprint(frutas, verdurasSinRepetir, f\"{listaVerduras[1] in verdurasSinRepetir}\")\n\n\n# ----------------------- Diccionarios -----------------------\n# Estos se encierran por llaves {}\n# Estos si o si deben llevar:\n# - Una clave (Los que están con comillas dobles)\n# - Un valor (Los que estan después de \":\" y antes de \",\")\n\nprint(\"\\n------ DICCIONARIOS ------\\n\")\ndiccionario = {\"1erValor\": 1,\n               \"2doValor\": 2,\n               \"3erValor\": 3}\n# dict crea diccionarios desde secuencias de pares clave-valor (\"Clave\": Valor)\nnuevoDiccionario = dict(\n    [(\"Nombre\", \"Allan\"), (\"Apellido\", \"Salazar\"), (\"Edad\", 29)])\n\nprint(diccionario)\nprint(nuevoDiccionario, end=\"\\n\\n\")\n\n# Interaccion con diccionarios\n# items() nos devuelve cada item clave-valor como tupla\nfor item in diccionario.items():\n    print(item)\n\n# si ponemos dos variables, la primera guarda la clave y la segunda el valor\nfor c, v in diccionario.items():\n    print(c, v)\n\n# enumerate() develve cada item indice-valor como tupla\nfor item in enumerate(diccionario):\n    print(item)\n\n# si ponemos dos variables, la primera guarda el indice y la segunda el valor\nfor i, v in enumerate(diccionario):\n    print(i, v)\n\n# ----------------------- EJERCICIO -----------------------\n\n# Creamos la agenda en base a una lista de diccionarios\nagenda = [{\"id\": 1,\n          \"Nombre\": \"Allan\",\n           \"Numero\": 10123456789}]\n\n# Buscando un usuario\n\n\ndef buscarUsuario(nombreUsuario):\n    for usuario in agenda:\n        if nombreUsuario in usuario[\"Nombre\"]:\n            return usuario\n    return \"Usuario no encontrado\"\n\n# Agregando un usuario\n\n\ndef agregarUsuario():\n    nombreNuevoUsuario = str(input(\"Ingresa el nombre: \"))\n    numeroNuevoUsuario = \"0\"\n    # Verificamos que el usuario ingrese un numero correcto\n    while len(numeroNuevoUsuario) != 11:\n        numeroNuevoUsuario = str(input(\"Ingresa el numero: \"))\n        if len(numeroNuevoUsuario) != 11:\n            print(\"Debes ingresar un numero correcto.\")\n        else:\n            agenda.append({\"id\": random.randint(1, 100),\n                           \"Nombre\": nombreNuevoUsuario,\n                           \"Numero\": numeroNuevoUsuario})\n            print(\"Usuario agregado\")\n    return agenda\n\n# Actualizando un usuario\n\n\ndef actualizarUsuario(nombreUsuario):\n    # Verificamos que el usuario exista\n    usuarioEncontrado = buscarUsuario(nombreUsuario)\n    if usuarioEncontrado != \"Usuario no encontrado\":\n        nuevoNombreUsuario = str(input(\"Ingresa el nuevo nombre: \"))\n        usuarioEncontrado[\"Nombre\"] = nuevoNombreUsuario\n        # Conseguimos la ubicacion del usuario encontrado y reemplazamos el nombre\n        for indice, usuario in enumerate(agenda):\n            if usuario[\"Nombre\"] == usuarioEncontrado[\"Nombre\"]:\n                agenda[indice] = usuarioEncontrado\n        print(\"Usuario actualizado\")\n    else:\n        print(usuarioEncontrado)\n    return agenda\n\n# Borrando un usuario\n\n\ndef borrarUsuario(nombreUsuario):\n    # Verificamos que el usuario exista\n    usuarioEncontrado = buscarUsuario(nombreUsuario)\n    if usuarioEncontrado != \"Usuario no encontrado\":\n        # Borramos al usuario encontrado\n        agenda.remove(usuarioEncontrado)\n        print(\"Usuario borrado\")\n    else:\n        print(usuarioEncontrado)\n    return agenda\n\n# Mostrando la agenda completa\n\n\ndef mostrarAgenda():\n    if len(agenda) != 0:  # Verificamos si la agenda no está vacía\n        print(\"Listado de usuarios\")\n        # Mostramos la agenda\n        for usuario in agenda:\n            print(usuario)\n    else:\n        print(\"Agenda sin usuarios\")\n\n# Main\n\n\nwhile True:\n    print(\"\\n------ EJERCICIO ------\\n\")\n    print(\"- Bienvenido a la agenda\\n ¿Qué deseas hacer con tus contactos?\")\n    print(\"1. Buscar\\n2. Agregar\\n3. Actualizar\\n4. Eliminar\\n5. Mostrar\\nSalir. Cierra el programa\")\n    opcion = input(\"$ \")\n    if opcion.lower() == \"salir\":\n        break\n    opcion = int(opcion)\n    if opcion == 1:\n        nombreUsuario = input(\"Ingresa el usuario a buscar: \")\n        print(buscarUsuario(nombreUsuario))\n    elif opcion == 2:\n        agenda = agregarUsuario()\n    elif opcion == 3:\n        nombreUsuario = input(\"Ingresa el usuario a actualizar: \")\n        agenda = actualizarUsuario(nombreUsuario)\n    elif opcion == 4:\n        nombreUsuario = input(\"Ingresa el usuario a borrar: \")\n        agenda = borrarUsuario(nombreUsuario)\n    elif opcion == 5:\n        mostrarAgenda()\n    else:\n        print(\"Selecciona una opción válida\")\n\nprint(\"Hasta luego\")\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Alvaro-Neyra.py",
    "content": "# - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n# Estructuras de datos en Python: (listas, sets, tuplas, dicts)\n# lists\nlista_nueva = [20, True, \"Soy Una Lista\", \"Este es elemento 4\", 100]\nprint(lista_nueva)\n# sets\nconjunto_nuevo = {True, False, \"No existen los elementos repetidos en un set\", 40}\nprint(conjunto_nuevo)\n# tuplas\ntupla_nueva = (True,False,\"Chau\",\"Los elementos de una tupla deben ser inmutables\", 300)\nprint(tupla_nueva)\n# dicts\ndiccionario_nuevo = {\"nombre\": \"Alvaro\", \"tipo de estructura\": \"Diccionario\", \"importante\": True, \"elementos\": 4}\nprint(diccionario_nuevo)\n\n# - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n# -- lists:\n## Insercion\nlista_ejemplo = [20, 30, 40, 50]\n# Anadiendo un elemento en especifico de la lista usando .append()\nlista_ejemplo.append(True)\nprint(f\"Esta es la lista con un elemento anadido usando .append(): {lista_ejemplo}\")\n# Anadiendo un elemento especificando el indice en donde va a estar usando .insert():\nlista_ejemplo.insert(2, 3)\nprint(f\"Esta es la lista con un elemento anadido en el indice especificado usando .insert(): {lista_ejemplo}\")\n# Anadiendo muchos elementos a la vez:\nlista_ejemplo.extend([200, \"Hola\", \"Mundo\", False])\nprint(f\"He anadido muchos elementos a la lista usando .extend(): {lista_ejemplo}\")\n\n## Borrado\n# Eliminando el elemento del indice 3\nlista_ejemplo.pop(3)\nprint(f\"Eliminando un elemento de la lista especificando su indice usando .pop(): {lista_ejemplo}\")\n# Eliminando un elemento de la lista usando remove\nlista_ejemplo.remove(20)\nprint(f\"Eliminando un elemento en especifico de la lista usando .remove(): {lista_ejemplo}\")\n# Vaciando todos los elementos de una lista:\nlista_ejemplo.clear()\nprint(f\"Vaciando la lista con .clear(): {lista_ejemplo}\")\n\n## Actualizacion\n# Invertir el orden de los elementos de la lista:\notra_lista_ejemplo = [30, 1, 2, 3, 4, 210, 30, 47]\notra_lista_ejemplo.reverse()\nprint(f\"He revertido el orden de los elementos de esta lista usando .reverse(): {otra_lista_ejemplo}\")\n\n## Ordenacion \n# Ordenar los elementos numericos de una lista de manera predeterminada (ASC)\nlista_numerica = [300, 1000, 40, 2, 6, 100, 98]\nlista_numerica.sort()\nprint(f\"Esta es la lista de numeros ordenados ASCENDENTEMENTE: {lista_numerica}\")\n# Ordenar los elementos numericos de la lista de manera DESC\notra_lista_numerica = [300, 20, 500, 1000, 8, 10, 1, 2]\notra_lista_numerica.sort(reverse=True)\nprint(f\"Esta es otra lista de numeros ordenadas inversamente: {otra_lista_numerica}\")\n\n# -- tuplas:\n## Los elementos de una tupla son inmutables es decir que no se pueden modificar por lo tanto, no podremos anadir, actualizar ni eliminar elementos.\n\n# -- diccionarios:\n## Anadir:\nejemplo_dict = {\n    \"nombre\": \"Luke\",\n    \"edad\": 1.6,\n    \"actividades\": [\"Jugar\", \"Comer\", \"Amar\"],\n}\n### Especificando con indice, no podremos anadir una clave para el indice en este caso:\nejemplo_dict[3] = True\nprint(f\"Hemos anadido un elemento en un diccionario especificando su indice: {ejemplo_dict}\")\n### Si la clave no existe podemos anadirla con su nuevo valor:\nejemplo_dict[\"es perro?\"] = True\nprint(f\"Hemos anadido clave y valor especificando su clave y su valor: {ejemplo_dict}\")\n### Anadir varios clave y valor usando .update():\nejemplo_dict.update({\"clave 5\": \"valor 5\", \"clave 6\": \"valor 6\"})\nprint(f\"Hemos anadido varios clave y valor en el diccionario usando el metodo .update(): {ejemplo_dict}\")\n### Anadir varios clave y valor usando .setdefault() si la clave no existe:\nejemplo_dict.setdefault(\"nueva_clave\", \"nuevo_valor\")\nprint(f\"Hemos anadido un nuevo valor especificando su clave usando .setdefault(): {ejemplo_dict}\")\n\n## Actualizar:\n### Usando la notacion de corchetes especificando una clave:\nejemplo_dict[\"clave 5\"] = 5\nprint(f\"He actualizado el valor de una clave usando la notacion de corchetes: {ejemplo_dict}\")\n### Usando el metodo .update():\nejemplo_dict.update({\"clave 5\": 50, \"clave 6\": \"Elemento 6\"})\nprint(f\"He actualizado los valores de las claves de un diccionario usando .update(): {ejemplo_dict}\")\n\n## Eliminar:\n### eliminando un valor y clave de un diccionario usando `del`:\ndel ejemplo_dict[\"clave 5\"]\nprint(f\"He eliminado la clave y valor de la clave 5 usando la palabra reservada de Python `del`: {ejemplo_dict}\")\n### Usando el metodo .pop():\n### - Especificando su clave:\nejemplo_dict.pop(\"clave 6\")\nprint(f\"He eliminado la clave y el valor de la clave 6 usando .pop(): {ejemplo_dict}\")\n### Usando el metodo .popitem():\nultimo_elemento_del_dict = ejemplo_dict.popitem()\nprint(f\"He eliminado el ultimo elemento del diccionario usando .popitem(): {ejemplo_dict}\")\n### Eliminando todos los elementos del diccionario:\nejemplo_dict.clear()\nprint(f\"He eliminando todos los elementos del diccionario usando .clear(): {ejemplo_dict}\")\n\n## - sets:\nnuevo_conjunto = {1, 2, 3}\nprint(f\"Este es el conjunto inicial: {nuevo_conjunto}\")\n### Anadir elementos:\n## Anadir un solo elemento usando .add():\nnuevo_conjunto.add(4)\nprint(f\"Anadiendo un nuevo elemento al conjunto usando .add(): {nuevo_conjunto}\")\n## Anadir varios elementos usando .update():\nnuevo_conjunto.update({4,5,6})\nprint(f\"Anadiendo elementos a un conjunto usando el metodo .update (no puede haber elementos repetidos): {nuevo_conjunto}\")\n## .union()\nconjunto_a_anadir = {7,8,9}\nnuevo_conjunto = nuevo_conjunto.union(conjunto_a_anadir)\nprint(f\"He anadido un nuevo conjunto al conjunto principal usando .union(): {nuevo_conjunto}\")\n### Eliminar elementos:\n## Usando .remove():\nnuevo_conjunto.remove(3)\nprint(f\"Eliminando un elemento del conjunto especificando el elemento: {nuevo_conjunto}\")\n## Usando .discard():\nnuevo_conjunto.discard(4)\nprint(f\"Eliminando un elemento usando .discard(): {nuevo_conjunto}\")\n## Usando .pop():\nnuevo_conjunto.pop()\nprint(f\"Eliminando el ultimo elemento del conjunto usando .pop(): {nuevo_conjunto}\")\n### Actualizar elementos:\n## Para actualizar un elemento de un conjunto, debemos primero eliminar ese elemento y luego anadirlo (no se puede actualizar en una posicion en especifico)\n## Primero eliminamos:\nnuevo_conjunto.remove(5)\nprint(f\"Eliminando el elemento 5: {nuevo_conjunto}\")\n## .update()\nnuevo_conjunto.update({5})\nprint(f\"El elemento 5 se elimino y luego se anadio: {nuevo_conjunto}\")\n\n# DIFICULTAD EXTRA (opcional):\ncontactos = []\n\n# Creando una funcion para verificar si existe un contacto duplicado\ndef contacto_duplicado(nombre):\n    global contactos\n    for contacto in contactos:\n        if contacto['nombre'] == nombre:\n            return True\n    return False\n\n# Creando una funcion para anadir un contacto a la lista de contactos\ndef anadir_contacto(nombre, numero):\n    # Verificando si el contacto ya existe en la lista:\n    if not contacto_duplicado(nombre):\n        # Verificando si el numero tiene solo digitos numericos y si tiene 11 digitos como maximo\n        try:\n            numero = int(numero)\n        except:\n            print(f\"El numero tiene que tener solo digitos numericos\")\n            return\n        else:\n            numero = str(numero)\n            if len(numero) > 11:\n                print(\"El numero de contacto debe tener 11 digitos como maximo\")\n                return\n            tieneDigitos = numero.isnumeric()\n            # Si todo esta bien anadelo a la lista de contactos\n            if (tieneDigitos == True):\n                global contactos\n                contactos.append({\n                    \"nombre\": nombre,\n                    \"numero\": numero\n                })\n            return contactos\n    else:\n        print(f\"El contacto ya existe no puede haber duplicados\")\n        return\n\n# Funcion para buscar contacto existente\ndef buscar_contacto(nombre_del_contacto):\n    global contactos\n    # Verificando si el contacto no existe. Si existe imprime en consola el contacto\n    for contacto in contactos:\n        if contacto['nombre'] == nombre_del_contacto:\n            print(contacto)\n            return\n    print(\"No hemos encontrado el contacto\")\n    return\n\n# Funcion que actualiza el contacto existente:\ndef actualizar_contacto(nombre_del_contacto, valor):\n    try:\n        valor = int(valor)\n    except:\n        print(f\"El numero tiene que tener solo digitos numericos\")\n        return\n    else:\n        valor = str(valor)\n        if len(valor) > 11:\n            print(\"El numero de contacto debe tener 11 digitos como maximo\")\n            return\n        global contactos\n        for contacto in contactos:\n            if contacto[\"nombre\"] == nombre_del_contacto:\n                contacto[\"numero\"] = valor\n                return {\"Message\": \"Contacto actualizado\", contacto[\"nombre\"] : contacto[\"numero\"]}\n        print(\"No hemos encontrado el contacto\")\n        return\n\n# Funcion que elimina el contacto\ndef eliminar_contacto(nombre_del_contacto):\n    try:\n        global contactos\n        for contacto in contactos:\n            if contacto[\"nombre\"] == nombre_del_contacto:\n                contactos.remove(contacto)\n                print(\"Contacto Eliminado\")\n                return contactos\n        print(\"No hemos encontrado el contacto a eliminar\")\n        return\n    except Exception as Error:\n        print(f\"Cometiste el siguiente error: {Error}\")\n\n# Funcion que nos permite ver los contactos\ndef ver_contactos():\n    global contactos\n    print(contactos)\n\n\nwhile(True):\n    actividad = input(\"Que deseas hacer con tu lista de contactos? (Ver, Anadir, Actualizar, Buscar y Eliminar) o escribe 'cancelar' para detener el programa: \").lower()\n    if actividad == \"ver\":\n        ver_contactos()\n    elif actividad == \"anadir\":\n        nombre_del_contacto = input(\"Cual es el nombre de tu contacto que deseas anadir?: \").lower()\n        numero_del_contacto = input(\"Cual es el numero de tu contacto que deseas anadir?: \")\n        anadir_contacto(nombre_del_contacto, numero_del_contacto)\n    elif actividad == \"actualizar\":\n        nombre_del_contacto = input(\"Cual es el nombre de contacto que deseas actualizar?: \").lower()\n        numero_del_contacto = input(\"Cual es el numero nuevo para actualizar el contacto?: \")\n        actualizar_contacto(nombre_del_contacto, numero_del_contacto)\n    elif actividad == \"buscar\":\n        nombre_del_contacto = input(\"Que contacto deseas buscar? (poner nombre del contacto): \").lower()\n        buscar_contacto(nombre_del_contacto)\n    elif actividad == \"eliminar\":\n        nombre_del_contacto = input(\"Que contacto deseas eliminar?: \").lower()\n        eliminar_contacto(nombre_del_contacto)\n    elif actividad == \"cancelar\":\n        break"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/AndresMCardenas.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n \n\"\"\"\n\n# Creación de estructuras de datos\n\n# Listas\n\nlistaNumeros = [1, 2, 3, 4, 5] # Lista de números\nprint(listaNumeros)\n\nlistaString = [\"a\", \"b\", \"c\", \"d\", \"e\"] # Lista de strings\nprint(listaString)\n\nlistaMixta = [1, \"a\", 2, \"b\", 3, \"c\"] # Lista mixta\nprint(listaMixta)\n\n# Tuplas\n\ntuplaNumeros = (1, 2, 3, 4, 5) # Tupla de números\nprint(tuplaNumeros)\n\ntuplaString = (\"a\", \"b\", \"c\", \"d\", \"e\") # Tupla de strings\nprint(tuplaString)\n\ntuplaMixta = (1, \"a\", 2, \"b\", 3, \"c\") # Tupla mixta\nprint(tuplaMixta)\n\n# Diccionarios\n\ndiccionarioNumeros = {1: \"uno\", 2: \"dos\", 3: \"tres\", 4: \"cuatro\", 5: \"cinco\"} # Diccionario de números\nprint(diccionarioNumeros)\n\ndiccionarioString = {\"a\": 1, \"b\": 2, \"c\": 3, \"d\": 4, \"e\": 5} # Diccionario de strings\nprint(diccionarioString)\n\ndiccionarioMixto = {1: \"a\", \"b\": 2, 3: \"c\", \"d\": 4, \"e\": 5} # Diccionario mixto\nprint(diccionarioMixto)\n\n#buscar en diccionario\nprint(diccionarioNumeros[1])\n\n#insertar en diccionario\ndiccionarioNumeros[6] = \"seis\"\nprint(diccionarioNumeros)\n\n#actualizar en diccionario\ndiccionarioNumeros[6] = \"SEIS\"\nprint(diccionarioNumeros)\n\n#eliminar en diccionario\ndel diccionarioNumeros[6]\nprint(diccionarioNumeros)\n\n\n# Operaciones de inserción, borrado, actualización y ordenación\n\n# Listas\n\nlistaNumeros.append(6) # Insertar un elemento al final de la lista\nprint(listaNumeros)\n\nlistaNumeros.insert(0, 0) # Insertar un elemento en una posición específica de la lista\nprint(listaNumeros)\n\nlistaNumeros.pop() # Eliminar el último elemento de la lista\nprint(listaNumeros)\n\nlistaNumeros.pop(0) # Eliminar un elemento en una posición específica de la lista\nprint(listaNumeros)\n\nlistaNumeros[0] = 1 # Actualizar un elemento en una posición específica de la lista\nprint(listaNumeros)\n\nlistaNumeros.sort() # Ordenar la lista\nprint(listaNumeros)\n\n# Tuplas\n\n# Las tuplas son inmutables, por lo que no se pueden modificar\n\n# Diccionarios\n\ndiccionarioNumeros[6] = \"seis\" # Insertar un elemento en el diccionario\nprint(diccionarioNumeros)\n\ndiccionarioNumeros[6] = \"SEIS\" # Actualizar un elemento en el diccionario\nprint(diccionarioNumeros)\n\ndel diccionarioNumeros[6] # Eliminar un elemento en el diccionario\nprint(diccionarioNumeros)\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n *   y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n *   y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más\n *   de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.\n\n\"\"\"\n\n# Agenda de contactos\n\nagenda = {} # Diccionario vacío\n\ncontrol = True\n\nopcion = 0\n\n# Funciones de la agenda de contactos \n      \n# Buscar contacto      \ndef buscarContacto():\n  nombre = input(\"Introduzca el nombre del contacto: \").upper()\n  if nombre in agenda:\n    print(\"El número de teléfono de\", nombre, \"es\", agenda[nombre])\n  else:\n    print(\"El contacto\", nombre, \"no existe\")\n\n# Insertar contacto\ndef insertarContacto():\n  nombre = input(\"Introduzca el nombre del contacto: \").upper()\n  if nombre in agenda:\n    print(\"El contacto\", nombre, \"ya existe\")\n  else:\n    numero = input(\"Introduzca el número de teléfono del contacto: \")\n    if numero.isnumeric() and len(numero) > 11:\n      agenda[nombre] = numero\n      print(\"El contacto\", nombre, \"ha sido añadido\")\n    else:\n      print(\"El número de teléfono introducido no es válido\")\n\n# Actualizar contacto\ndef actualizarContacto():\n  nombre = input(\"Introduzca el nombre del contacto: \").upper()\n  if nombre in agenda:\n    numero = input(\"Introduzca el nuevo número de teléfono del contacto con el indicador del pais: \")\n    if numero.isnumeric() and len(numero) > 11:\n      agenda[nombre] = numero\n      print(\"El contacto\", nombre, \"ha sido actualizado\")\n    else:\n      print(\"El número de teléfono introducido no es válido\")\n  else:\n    print(\"El contacto\", nombre, \"no existe\")\n\n# Eliminar contacto\ndef eliminarContacto():\n  nombre = input(\"Introduzca el nombre del contacto: \").upper()\n  if nombre in agenda:\n    del agenda[nombre]\n    print(\"El contacto\", nombre, \"ha sido eliminado\")\n  else:\n    print(\"El contacto\", nombre, \"no existe\")\n\n# Mostrar agenda\ndef mostrarAgenda():\n  print(\"Agenda de contactos\")\n  for nombre, numero in agenda.items():\n    print(nombre, \":\", numero)\n\n# Salir\ndef salir():\n  global control\n  control = False\n  print(\"Fin del programa\")\n\n# Ejecución de la agenda de contactos\nwhile control:\n  print(\"----------------------------------------\")\n  print(\"Agenda de contactos\")\n  print(\"----------------------------------------\")\n  print(\"1. Buscar contacto\")\n  print(\"2. Insertar contacto\")\n  print(\"3. Actualizar contacto\")\n  print(\"4. Eliminar contacto\")\n  print(\"5. Mostrar agenda\")\n  print(\"6. Salir\")\n  print(\"----------------------------------------\")\n  opcion = int(input(\"¿Qué operación desea realizar? \"))\n  print(\"----------------------------------------\")\n  \n  if opcion == 1:\n    buscarContacto()\n  elif opcion == 2:\n    insertarContacto()\n  elif opcion == 3:\n    actualizarContacto()\n  elif opcion == 4:\n    eliminarContacto()\n  elif opcion == 5:\n    mostrarAgenda()\n  elif opcion == 6:\n    salir()\n  else:\n    print(\"Opción incorrecta\")\n\n\n\n  \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Angell4S.py",
    "content": "# Listas\r\nmy_list = [\"Brais\", \"Bl4ck\", \"Wolfy\", \"Visions\"]\r\nprint(my_list)\r\n\r\nmy_list.append(\"Angel\") # Inserción\r\nmy_list.append(\"Angel\")\r\nprint(my_list)\r\n\r\nmy_list.remove('Angel') # Eliminación\r\nprint(my_list)\r\n\r\nprint(my_list[1]) # Acceso\r\nmy_list[1] = 'Cuervillo' # Modificación\r\nprint(my_list)\r\n\r\nmy_list.sort() # Ordenación\r\nprint(my_list)\r\n\r\n# Tuplas\r\nmy_tuple = ('Moure', 'Dev', '@mouredev', '36')\r\nprint(my_tuple[1])# Acceso\r\nprint(my_tuple[3])\r\nmy_tuple = tuple(sorted(my_tuple)) # Ordenación\r\nprint(type(my_tuple))\r\nprint(my_tuple)\r\n\r\n# Sets\r\nmy_set = {'Moure', 'Dev', '@mouredev', '36'}\r\nprint(my_set)\r\nmy_set.add('angel@gmail.com') # Inserción\r\nmy_set.add('angel@gmail.com')\r\nmy_set.remove('Moure') # Eliminación\r\nprint(my_set)\r\n#print(my_set[0])\r\nmy_set = set(sorted(my_set)) # No se puede ordenar, set no es una estructura ordenada\r\nprint(my_set)\r\nprint(type(my_set))\r\n\r\n# Diccionarios\r\nmy_dict: dict = {\r\n   'name':'Moure',\r\n   'surname':'Dev',\r\n   'alias':'@mouredev',\r\n   'edad':'36'\r\n   }\r\nmy_dict['email'] = 'mouredev@gmail.com' # inserción\r\nprint(my_dict)\r\ndel my_dict['surname'] # Eliminación\r\nprint(my_dict)\r\nprint(my_dict['name']) # Acceso\r\nmy_dict['edad'] = '37' # Modificación\r\nprint(my_dict)\r\nmy_dict = dict(sorted(my_dict.items())) # Ordenación \r\nprint(my_dict)\r\nprint(type(my_dict))\r\n\r\n\"\"\"\r\nEXTRA\r\n\"\"\"\r\n\r\ndef my_agenda():\r\n\r\n   agenda = {}\r\n\r\n   def insert_contact():\r\n      phone = input(\"Introduce el teléfono del contacto: \")\r\n      if phone.isdigit() and len(phone) > 0 and len(phone) <= 11:\r\n         agenda[name] = phone\r\n      else:\r\n         print(\"Debes introducir un número de teléfono con menos de 11 dígitos.\")\r\n\r\n   while True:\r\n\r\n      print(\"\")\r\n      print(\"1. Buscar contacto\")\r\n      print(\"2. Insertar contacto\")\r\n      print(\"3. Actualizar contacto\")\r\n      print(\"4. Eliminar contacto\")\r\n      print(\"5. Salir\")\r\n\r\n      option = input(\"\\nSelecciona una opción: \")\r\n\r\n      match option:\r\n         case \"1\":\r\n            name = input(\"Introduce el nombre del contacto a buscar: \")\r\n            if name in agenda:\r\n               print(f\"El número de teléfono de {name} es {agenda[name]}\")\r\n            else:\r\n               print(f\"El contacto {name} no existe\")\r\n         case \"2\":\r\n            name = input(\"Introduce el nombre del contacto a insertar: \")\r\n            insert_contact()\r\n         case \"3\":\r\n            name = input(\"Introduce el nombre del contacto a actualizar: \")\r\n            if name in agenda:\r\n               insert_contact()\r\n            else:\r\n               print(f\"El contacto {name} no existe\")\r\n         case \"4\":\r\n            name = input(\"Introduce el nombre del contacto a eliminar: \")\r\n            if name in agenda:\r\n               del agenda[name]\r\n            else:\r\n               print(f\"El contacto {name} no existe\")\r\n         case \"5\":\r\n            print(\"Saliendo de la agenda.\")\r\n            break\r\n         case _:\r\n            print(\"Opción no válida, Elige una opción del 1 al 5.\")\r\n\r\n\r\nmy_agenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Anvildestroyer.py",
    "content": "# Tipo Listas\nlista = [1, 2, 3, 4]\nlista = list(\"1234\")\nlista = [1, \"Hola\", 3.67, [1, 2, 3]]\n# inserción .append\nl = [1, 2]\nl.append(3)\nprint(l) #[1, 2, 3]\nl = [1, 3]\nl.insert(1, 2)\nprint(l) #[1, 2, 3]\n#Añade .Extend una lista a otra lista\nl = [1, 2]\nl.extend([3, 4])\nprint(l) #[1, 2, 3, 4]\n#  actualizacion\nlista1 = [1,2,3,4,5,10]\nlista1[5] = 20\nprint(lista1)\n#borrado .remove\nl = [1, 2, 3]\nl.remove(3)\nprint(l) #[1, 2]\n#Ordenación .sort\nl = [3, 1, 2]\nl.sort()\nprint(l) #[1, 2, 3]\n# tambien podemos ordenar de mayor a menor si se pasa como parámetro reverse=True\nl = [3, 1, 2]\nl.sort(reverse=True)\nprint(l) #[3, 2, 1]\n\n# Tuplas (son inmutables, no se pueden modificar)\ntupla = (1, 2, 3)\nprint(tupla) #(1, 2, 3)\n#se pueden declarar sin parentesis tambien\ntupla = 1, 2, 3\nprint(tupla)       #(1, 2, 3)\n# Ordenación\ntupla = tuple(sorted(tupla))  \nprint(tupla)\nprint(type(tupla))  #<class 'tuple'>\n\n#Set son muy similar a las listas, pero... no puede haber elementos duplicados, Los set son desordenados, Sus elementos deben ser inmutables\ns = set([5, 4, 6, 8, 8, 1])\nprint(s)       #{1, 4, 5, 6, 8}\nprint(type(s)) #<class 'set'>\n#Remove\ns = set([1, 2])\ns.remove(2)\nprint(s) #{1}\n#Insertar\nl = set([1, 2])\nl.add(3)\nprint(l) #{1, 2, 3}\n\n# Diccionario\nd1 = {\n  \"Nombre\": \"Anvildestroyer\",\n  \"Edad\": 10,\n  \"Documento\": 11111111\n}\nprint(d1)\n#{'Nombre': 'Anvildestroyer', 'Edad': 32, 'Documento': 11111111}\n\n# Eliminación\n#Remove .Clear \nd = {'a': 1, 'b': 2}\nd.clear()\nprint(d) #{}\n\ndel d1[\"Edad\"]  \nprint(f\"eliminando edad:\",d1) \n# Inserción\nd1[\"Nombre\"] = \"AnvilDevstroyer\"  \nprint(f\"insertando nuevo nombre:\",d1)\n# Acceso\nprint(d1[\"Nombre\"])  \n# get()\nd = {'a': 1, 'b': 2}\nprint(d.get('a')) #1\nprint(d.get('z', 'No encontrado')) #No encontrado\n# Actualización\nd1[\"age\"] = \"32\"  \nprint(f\"Actualizando edad:\",d1)\n# Ordenación\nd1 = dict(sorted(d1.items()))  \nprint(f\"Ordenando el directorio:\",d1)\nprint(type(d1))\n\n\n#Extra\ncontactos =  {}\n\ndef menu_usuario():\n    while True:\n        print(\"Agenda de Contactos\\n\"\n        \"Si quiere buscar un contacto presione 1\\n\"\n        \"Si quiere Insentar un contacto presione 2\\n\"\n        \"Si quiere Actualizar un contacto presione 3\\n\"\n        \"Si quiere eliminar un contacto presione 4\\n\"\n        \"Si quiere salir presione 5\")\n        seleccion = input(\"escoja una opcion del siguiente listado: \")\n        if 1 <= int(seleccion) <= 5:\n            if int(seleccion) == 1:\n                buscar_datos_lista()\n            elif int(seleccion) == 2:\n                añadir_datos_lista()\n            elif int(seleccion) == 3:\n                Actualizar_contacto_lista()\n            elif int(seleccion) == 4:\n                Remover_contacto_lista()\n            elif int(seleccion) == 5:\n                print(\"Gracias por usar mi Agenda!\")\n                break\n        else:\n            print(\"Opción no válida. Por favor, seleccione una opción del 1 al 5.\")\n\ndef añadir_datos_lista():\n    global contactos\n    nombre = input(\"Escribe tu nombre: \")\n    apellido = input(\"Ingresa tu apellido: \")  \n    # Validación del número de teléfono\n    while True:\n        telefono = input(\"Ingresa tu telefono: \")\n        if telefono.isdigit() and len(telefono) <= 11:\n            break\n        else:\n            print(\"Por favor, ingresa un número de teléfono válido de hasta 11 dígitos.\")\n    identificador = input(\"Ingresa tu identificador: \")    \n    if identificador in contactos:\n        print(f\"el identificador {identificador} ya existe intenta con otro!!!\")\n    else:\n        contactos[identificador] = [\"Nombre: \" + nombre, \"Apellido: \"+ apellido, \"Telefono: \" + telefono]\n        print (f\"el contacto {identificador} se ha añadido correctamente a la agenda!\")\n\ndef buscar_datos_lista():\n    global contactos\n    identificador = input(\"Ingresa el identificador del contacto que quieres buscar: \")\n    if identificador in contactos:\n        print(f\"el contacto esta en la agenda {contactos[identificador]}\")\n    else:\n        print(\"El contacto no existe.\")\n\ndef Actualizar_contacto_lista():\n    global contactos\n    identificador = input(\"Ingresa el identificador del contacto que quieres Actualizar: \")\n    if identificador in contactos:\n        nombre = input(\"Escribe tu nombre: \")\n        apellido = input(\"Ingresa tu apellido: \")\n        while True:\n            telefono = input(\"Ingresa tu telefono: \")\n            if telefono.isdigit() and len(telefono) <= 11:\n                break\n        contactos[identificador] = [\"Nombre: \" + nombre, \"Apellido: \"+ apellido, \"Telefono: \" + telefono]\n        print (f\"El contacto {identificador} se ha actualizado correctamente!\")\n    else:\n        print(\"El contacto no existe\")\n\ndef Remover_contacto_lista():\n    global contactos\n    identificador = input(\"Ingresa el identificador del contacto que quieres Eliminar: \")\n    if identificador in contactos:\n        del contactos[identificador]\n        print (f\"el contacto {identificador} se ha eliminado correctamente\")\n    else:\n        print(\"El contacto no existe!\")\n\nmenu_usuario()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Aquiles735.py",
    "content": "\n# * EJERCICIO:\n#  * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n#  * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea una agenda de contactos por terminal.\n#  * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n#  * - Cada contacto debe tener un nombre y un número de teléfono.\n#  * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n#  *   los datos necesarios para llevarla a cabo.\n#  * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n#  *   (o el número de dígitos que quieras)\n#  * - También se debe proponer una operación de finalización del programa.\n\n\n                                       #estructuras##\n\nlista = [1, 2, 3, 4]\nlista.sort()  # Ordena la lista en orden ascendente\nprint(lista)\nlista.sort(reverse=True)    # Ordena la lista en orden descendente\nprint(lista)\nlista.append(6)      # Agrega 6 al final de la lista [1, 2, 3, 4, 6]\nprint(lista)  \ndel lista[0]       #elimina el elemento \"0\"(primero) de la lista [2, 3, 4, 6]\nprint(lista)\nlista.remove(3)      #elimina el valor n=3 de la lista\nprint(lista)\nelemento = lista.pop()     #elimina el último elemento de la lista\nprint(lista)\nelemento = lista.pop()     #elimina el último elemento de la lista\nprint(lista)\nlista1 = [3, 1, 4, 1, 5, 9]    ##ordenar creciente-decreciente\nlista_ordenada = sorted(lista1) \nprint(lista_ordenada)   # Ordena la lista en orden ascendente\nlista_ordenada_desc = sorted(lista1, reverse=True) \nprint(lista_ordenada_desc)\n\n\n\ntupla = (1, 3, 2, 4)\nprint(tupla)      # sin modificacion\nlista = list(tupla)  \nprint(lista)      #imprime en forma de lista []\nlista.remove(3)   \nprint(lista)       #elimina el 3 elemento (4) e imprime en forma de lista []\ntupla = tuple(lista)\nprint(tupla)       #imprime en forma de tupla\nlista_ordenada = sorted(tupla) \nprint(lista_ordenada) # Ordena la tupla convirtiéndola a lista\ntupla_ordenada = tuple(lista_ordenada)\nprint(tupla_ordenada)\n\n\n\nconjunto = {1, 2, 3, 4}\nlista_ordenada = sorted(conjunto) #imprime en forma de lista\nprint(lista_ordenada)\nconjunto.add(7)     # Agrega 7 al conjunto\nprint(conjunto)\nconjunto.remove(2)     #remueve el numero 2\nprint(conjunto) \n\n\n\ndiccionario = {\"clave2\":\"clave2\" , \"clave1\":\"clave1\",\"clave3\":\"clave3\"}\ndiccionario_ordenado_claves = dict(sorted(diccionario.items()))\nprint(diccionario_ordenado_claves)     # Ordenar por claves\ndiccionario_ordenado_valores = dict(sorted(diccionario.items(), key=lambda item: item[1]))\nprint(diccionario_ordenado_valores)     #ordenar por valores\ndiccionario[\"clave7\"] = \"clave7\"    # Agrega  nuevos pares de clave-valor 7\ndiccionario['clave5']='clave5'      # Agrega  nuevos pares de clave-valor 5\nprint(diccionario)\ndel diccionario['clave2']    #elimina clave-valor 2\nprint(diccionario)\nvalor = diccionario.pop('clave7')   #elimina clave-valor 7\nprint(valor)\n\n\n\n                # Crea una agenda de contactos por terminal\n\nagenda = {\"maria\":\"25\" , \"zulay\":\"17\",\"rosa\":\"70\" , \"jose\":\"33\"}\nprint(agenda)\nagenda[\"felipe\"] = \"45\"   # agregar elemento clave-valor a la agenda\nprint(agenda)\nagenda_ordenado_claves = dict(sorted(agenda.items()))\nprint(agenda_ordenado_claves) #ordenda la agenda por clave (orden alfabetico de contactos)\nagenda_ordenado_valores = dict(sorted(agenda.items(), key=lambda item: item[1]))\nprint(agenda_ordenado_valores)  #ordenada por valores\ndel agenda['zulay']   #eliminar elemento (clave) de la agenda\nprint(agenda)\nvalor = agenda.pop('jose') # imprime el valor de un elemento sin eliminarlo jose=33\nprint(valor)\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Bert008.py",
    "content": "'''\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n'''\n# Las estructuras en soportadas en Python son las siguientes\nlista = [0, 1, 2, 3, 3]\ntupla = (0, 1, 2, 3, 3)\nconjunto = {1, 2, 3, 3}\ndiccionario = {0: 1, 1: 2, 2: 3, 3: 4}\nprint(lista)\nprint(tupla)\nprint(conjunto)\nprint(diccionario)\n\nprint(type(lista))\nprint(type(tupla))\nprint(type(conjunto))\nprint(type(diccionario))\n\ndef insercion(obj1, obj2):\n    if isinstance(obj1, list):\n        obj1.append(obj2)\n        print(\"insercion: \", obj1)\n    elif isinstance(obj1, tuple):\n        tupla2 = obj1 + (obj2,)  # Corregido el nombre de variable 'tupla' a 'obj1'\n        print(\"insercion: \", tupla2)\n    elif isinstance(obj1, set):\n        obj1.add(obj2)  # Corregido 'conjunto' a 'obj1'\n        print(\"insercion: \", obj1)\n    elif isinstance(obj1, dict):\n        if isinstance(obj2, tuple) and len(obj2) == 2:\n            obj1[obj2[0]] = obj2[1]  # Mejorado para aceptar pares clave-valor\n        else:\n            obj1[len(obj1)] = obj2\n        print(\"insercion: \", obj1)\n\ndef borrar(obj1, obj2):\n    if isinstance(obj1, list):\n        try:\n            obj1.pop(obj2)\n            print(\"borrar: \", obj1)\n        except IndexError:\n            print(f\"Índice {obj2} fuera de rango para la lista\")\n    elif isinstance(obj1, tuple):\n        try:\n            lista_temp = list(obj1)\n            lista_temp.pop(obj2)\n            obj1 = tuple(lista_temp)\n            print(\"borrar: \", obj1)\n        except IndexError:\n            print(f\"Índice {obj2} fuera de rango para la tupla\")\n    elif isinstance(obj1, set):\n        try:\n            obj1.remove(obj2)\n            print(\"borrar: \", obj1)\n        except KeyError:\n            print(f\"Elemento {obj2} no encontrado en el conjunto\")\n    elif isinstance(obj1, dict):\n        try:\n            del obj1[obj2]\n            print(\"borrar: \", obj1)\n        except KeyError:\n            print(f\"Clave {obj2} no encontrada en el diccionario\")\n\ndef actualizar(obj1, obj2):\n    if isinstance(obj1, list):\n        if isinstance(obj2, list):\n            obj1.extend(obj2)\n        else:\n            obj1.append(obj2)\n        print(\"update: \", obj1)\n    elif isinstance(obj1, tuple):\n        if isinstance(obj2, (list, tuple, set)):\n            obj1 += tuple(obj2)\n        else:\n            obj1 += (obj2,)\n        print(\"update: \", obj1)\n    elif isinstance(obj1, set):\n        if isinstance(obj2, (list, tuple, set)):\n            obj1.update(obj2)\n        else:\n            obj1.add(obj2)\n        print(\"update: \", obj1)\n    elif isinstance(obj1, dict):\n        if isinstance(obj2, dict):\n            obj1.update(obj2)\n        elif isinstance(obj2, tuple) and len(obj2) == 2:\n            obj1[obj2[0]] = obj2[1]\n        else:\n            obj1[len(obj1)] = obj2\n        print(\"update: \", obj1)\n\ndef sorting(obj1):\n    if isinstance(obj1, list):\n        try:\n            obj1.sort()\n        except TypeError:\n            print(\"No se puede aplicar sort a una lista con tipos incompatibles\")\n        print(\"ordenar: \", obj1)\n    elif isinstance(obj1, tuple):\n        obj1 = tuple(sorted(obj1, key=lambda x: str(x)))  # Ordena convirtiendo a str para evitar errores\n        print(\"ordenar: \", obj1)\n    elif isinstance(obj1, set):\n        obj1 = sorted(obj1, key=lambda x: str(x))  # Ordena convirtiendo a str para evitar errores\n        print(\"ordenar: \", obj1)\n    elif isinstance(obj1, dict):\n        try:\n            obj1 = dict(sorted(obj1.items(), key=lambda item: item[1]))\n            print(\"ordenar: \", obj1)\n        except TypeError:\n            print(\"No se puede ordenar el diccionario con tipos de valores incompatibles\")\n\nestructuras = [lista, tupla, conjunto,diccionario]\nfor i in estructuras:\n    insercion(i, 3)\n    borrar(i, 2)\n    actualizar(i, 1)\n    sorting(i)\n    print(\"=====================================\")\n'''\n* DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n'''\n\n# directorio\ndirectorio = {}\n\n# entradas\n# ANADIR NUEVO CONTACTO\ndef add_cto(name, pnum):\n    if isinstance(pnum, str) and len(pnum) < 11:\n        directorio[name] = pnum\n\ndef agenda_telefonica():\n    while True:\n        print(\"Agenda telefonica\")\n\n        print(\"1) Agregar contacto nuevo\")\n        print(\"2) Actualizar contacto\")\n        print(\"3) Eliminar contacto\")\n        print(\"4) Mostrar directorio\")\n        print(\"5) Salir de la agenda\")\n\n        input_match = int(input(\"Eliga una opcion \"))\n        match input_match:\n            case 1:\n                print(\"Agregar contacto nuevo\")\n                name = input(\"Nombre: \")\n                pnum = input(\"Numero de telefono: \")\n                add_cto(name, pnum)\n            case 2:\n                print(\"Actualizar contacto\")\n                buscar = input(\"Contacto: \")\n                if buscar in directorio:\n                    print(\"1) Cambiar Nombre\")\n                    print(\"2) Cambiar Numero\")\n                    opcion = int(input(\"Eliga una opcion\"))\n                    if opcion == 1:\n                        print(f\"Cambiar nombre de {buscar} a: \")\n                        nuevo_nombre = input()\n                        directorio[nuevo_nombre] = directorio.pop(buscar)\n                    elif opcion == 2:\n                        print(f\"Cambiar numero del contacto {buscar} a: \")\n                        nuevo_numero = input()\n                        directorio[buscar] = nuevo_numero\n                else:\n                    print(\"Contacto no existe\")\n\n            case 3:\n                print(\"Eliminar contacto\")\n                drop_cto = input()\n                if drop_cto in directorio:\n                    del directorio[drop_cto]\n                    print(\"contacto eliminado\")\n                else:\n                    print(\"contacto no existe\")\n            \n            case 4:\n                print(\"Contactos\")\n                for nombre, pnum in directorio.items():\n                    print(f\"{nombre} -- {pnum}\")\n                    \n            \n            case 5:\n                print(\"Saliendo de la agenda\")\n                break\n\nagenda_telefonica()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/BrianSilvero.py",
    "content": "# Listas\nfrom os import name\n\n\nmy_list:list = [\"Brais\", \"Bl4ck\", \"Wolfy\", \"Visionos\"]\nprint(my_list)\nmy_list.append(\"Castor\") # Inserción\nmy_list.append(\"Castor\")\nprint(my_list)\nmy_list.remove(\"Brais\") # Eliminación\nprint(my_list)\nprint(my_list[1]) # Acceso\nmy_list[1] = \"Cuervillo\" # Actualización\nprint(my_list)\nprint(type(my_list))\n\n\n# Tuplas\nmy_tuple:tuple = (\"Brais\", \"Mouredev\", \"@mouredev\", \"36\")\nprint(my_tuple[1]) # Acceso\nprint(my_tuple[3])\nmy_tuple = tuple(sorted(my_tuple)) # Ordenación\nprint(my_tuple)\nprint(type(my_tuple))\n\n# Sets\nmy_sets:set = {\"Brais\", \"Moure\", \"@mouredev\", \"36\"}\nprint(my_sets)\nmy_sets.add(\"mouredev@gmail.com\") # Insercción\nmy_sets.add(\"mouredev@gmail.com\") # No se puede insertar duplicados\nprint(my_sets)\nmy_sets.remove(\"Moure\") # Eliminación\nprint(my_sets)\nmy_sets = set(sorted(my_sets)) # No se puede ordenar\nprint(my_sets)\nprint(type(my_sets)) \n\n# Diccionario\nmy_dict:dict = {\n    \"name\": \"Brais\",\n    \"surname\": \"Moure\",\n    \"alias\": \"@mouredev\",\n    \"edad\": \"36\"\n}\nmy_dict [\"email\"] = \"mouredev@gmail.com\" # Insercción\nprint(my_dict)\ndel my_dict [\"surname\"] # Eliminación\nprint(my_dict)\nprint(my_dict[\"name\"]) # Acceso\nmy_dict[\"edad\"] = \"37\" # Actualización\nprint(my_dict)\nmy_dict = dict(sorted(my_dict.items())) # Ordenación\nprint(my_dict)\nprint(type(my_dict))\n\n\"\"\"\nExtras\n\"\"\"\n\nagenda = {\n}\ndef insertar_contacto(name):\n    phone = input(\"Introduce un nro de telefono: \")\n    if phone.isdigit() and len(phone) > 0 and len(phone) <= 11:\n        agenda[name] = phone\n    else: \n        print(\"Debes introducir un numero de teléfono un máximo de 11 dígitos.\")\n\ndef my_agenda():\n    \n    \n    while True:\n        \n        print(\"\\n1. Buscar un contacto.\")\n        print(\"2. Insertar un contacto.\")\n        print(\"3. Actualizar un contacto.\")\n        print(\"4. Eliminar un contacto.\")\n        print(\"5. Salir.\")\n        \n        option = input(\"\\nIngresar una opcion: \")\n        \n        match option:\n            case \"1\":\n                name = input(\"\\nIntroduce el nombre del contacto a buscar: \")\n                if name in agenda:\n                    print(f\"El numero de teléfono de {name} es {agenda[name]}.\")\n                else: \n                    print(f\"El contacto {name} no existe.\")\n            case \"2\":\n                name = input(\"Introduce un nombre: \")\n                insertar_contacto(name)\n                pass\n            case \"3\":\n                name = input(\"Que contacto quieres actualizar?: \")\n                if name in agenda:\n                    insertar_contacto(name)\n                else:\n                    print(f\"El contacto {name} no existe.\")\n                pass\n            case \"4\":\n                name = input(\"Que contacto deseas eliminar?: \")\n                if name in agenda:\n                    del agenda[name]\n                    print(\"Su contacto ha sido eliminado con exito!\")\n                else: \n                    print(f\"El contacto {name} no existe.\")\n                pass\n            case \"5\":\n                print(\"Saliendo de la agenda\")\n                break\n            case _:\n                print(\"Opcion no valida. Seleccione una opcion del 1 al 5\")\n                pass\nmy_agenda()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/BryanAlzate007.py",
    "content": " # DIFICULTAD EXTRA (opcional):\n # Crea una agenda de contactos por terminal.\n # - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n # - Cada contacto debe tener un nombre y un número de teléfono.\n # - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n #   los datos necesarios para llevarla a cabo.\n # - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n #   (o el número de dígitos que quieras)\n # - También se debe proponer una operación de finalización del programa.\n\n\n\n\n\n\n#listas\nlistas = [1,2,3,4,\"bryan\",4,5]\n# tuplas este tipo de estructura no es mutable\ntuple = (1,2,3,\"python\")\n#diccionarios\ndiccionarios = {\"nombre\":\"bryan\",\n              \"cedula\":\"1234556\"}\n#conjuntos-sets elementos unicos\nsets = {1,2,3,4}\n#strings (textos)\nstrings= \"creando string\"\n\nagenda=[]\ndef agregarContacto():\n    nombre = input(\"Escribe el nombre de tu contacto: \")\n    try:\n        telefono = int(input(\"Escribe el telefono: \"))\n    except ValueError:\n        print(\"Por favor, ingresa un número válido.\")\n        return\n    agenda.append({nombre: telefono})\n    opciones()\ndef actualizar():\n    nombreActualizar = input(\"Escribe el nombre del contacto a actualizar: \")\n    encontrado = False\n    for contacto in agenda:\n        if nombreActualizar in contacto:\n            nuevoTelefono = input(\"Escribe el nuevo telefono: \")\n            contacto[nombreActualizar] = nuevoTelefono\n            encontrado = True\n            break\n    if not encontrado:\n        print(\"Contacto no encontrado.\")\n    opciones()\n\ndef eliminar():\n    nombreEliminar = input(\"Escribe el nombre del contacto a eliminar: \")\n    encontrado = False\n    for contacto in agenda:\n        if nombreEliminar in contacto:\n            agenda.remove(contacto)\n            encontrado = True\n            break\n    if not encontrado:\n        print(\"Contacto no encontrado.\")\n    opciones()\n    \ndef salir():\n    print(\"gracias por usar Agenda.APP\")\n\ndef vercontactos():\n    print(agenda)\n    print(\"gracias por usar Agenda.APP\")\ndef opciones():\n    opciones=int(input(\"Seleciona una opcion 1-Agregar 2-Actualizar 3-Eliminar 4-Ver Contactos 5-Salir \"))\n    if opciones == 1:\n        agregarContacto()\n\n    elif opciones == 2:\n        actualizar()\n    elif opciones == 4:\n        vercontactos()\n    elif opciones == 5:\n        salir()\n    else:\n        eliminar()\n\n\nopciones()\n\n\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/BuriticaSara.py",
    "content": "03 - Estructuras de datos:\n\nLas estructuras son conjuntos de datos agrupados.\n\"\"\"\n\n#listas: son conjuntos de datos organizados, que se pueden modificar\n#funciones: append(), remove(), [1], sort()\n\nmilista = ['Daniel', 'Sara', 'Silvi', 'Corazón']\nprint(milista)\n\nmilista.append('Toulouse') #inserta el nuevo elemento al final de la lista\nprint(milista)\n\nmilista.remove('Toulouse') #borra el elemento mencionado\nprint(milista)\n\nprint(milista[1]) #acceso a un elemento específico, se pone el lugar del elemento, los lugares siempre empiezan desde 0\n\nmilista[2]= 'Silvano' #actualización, me remplaza un elemento por otro\nprint(milista)\n\nmilista.sort()\nprint(milista)\n\nprint(type(milista))\n\n#Tuplas: son conjuntos de datos pero inmutables, se realizan con parentesis\n#como no lo puedo cambiar no puedo borrar ni cambiar elementos.\n\nmitupla= ('dirección','edad','telefono','1234')\n\nprint(type(mitupla))\n\nprint(mitupla[0]) #acceso a un elemento específico\n\n#puedo usar las siguientes funciones, pero me convierten la tupla en lista, por eso tendría que volver a convertirla en tupla: tuple()\n\nmitupla = tuple(sorted(mitupla))\nprint(mitupla)\nprint(type(mitupla))\n\n#Sets: conjuntos de datos que no mantienen un orden específico. se crean con {} corchetes\n\nmiset = {'a','b','c','d'}\n\nprint(miset)\nprint(type(miset))\n\nmiset.add('e') #agregar un nuevo elemento, no me agrega elementos que ya existen, porque no guarda duplicados\nprint(miset)\n\nmiset.remove('b') #Eliminar un elemento\nprint(miset)\n\n#Diccionario: es un conjunto de datos que guarda elementos y una clave para cada uno de ellos, se crea con {}\n\nmidiccionario = {'primero': '1', 'segundo': '2', 'tercero': '3', 'cuarto': '4'}\nprint(type(midiccionario))\nprint(midiccionario)\n\nprint(midiccionario['segundo']) #Asceso a un elemento, se hace por la clave\nprint(type(midiccionario))\n\nmidiccionario['tercero']= '3.0' #Actualizar un dato, se hace a través de la clave\nprint(midiccionario) \nprint(type(midiccionario))\n\nmidiccionario['quinto']= '5' #Agregar, se escribe la clave y el elemento\nprint(midiccionario)\n\ndel midiccionario['primero'] #borrar un elemento, se llama por la clave\nprint(midiccionario)\n\n\n\"\"\"\nEjercicio extra\n\"\"\"\n\ndef mi_agenda():\n  agenda = {}\n\n  while True:\n\n    print(\"Bienvenida a tu agenda, escribe el número de lo que deseas hacer\")\n    print(\"1. Buscar un contacto\")\n    print(\"2. Agregar un contacto\")\n    print(\"3. Modificar un contacto\")\n    print(\"4. Eliminar un contacto\")\n    print(\"5. Ver tu lista de contatos\")\n    print(\"6. Salir\")\n\n    decision = input()\n\n \n    match decision:\n      case \"1\":\n        name = input(\"Escribe el nombre del contacto que estas buscando:\")\n        if name in agenda:\n          print(f\"El número de {name} es {agenda[name]}\")\n        else:\n          print(f\"El contacto {name} no se encuentra en la agenda\")\n      case \"2\":\n        name = input(\"Escribe el nombre de la persona:\")\n        telefono = input(\"Escribe el número de teléfono:\")\n        if telefono.isdigit() and len(telefono) > 0 and len(telefono) <= 11:\n          agenda[name] = telefono\n        else: \n          print(\"teléfono no valido, por favor escribe un teléfono máximo de 11 digitos\")\n      case \"3\":\n        name = input(\"Escribe el nombre del contacto que deseas modificar:\")\n        if name in agenda:\n          telefono = (input(\"Escribe el nuevo número de teléfono:\"))\n          if telefono.isdigit() and len(telefono) > 0 and len(telefono) <= 11:\n            agenda[name] = telefono\n            print(f\"El nuevo numero de {name} es {agenda[name]}\")\n          else:\n            print(\"telefono no valido, por favor escribe un teléfono máximo de 11 digitos\" )\n        else:\n          print(f\"El contacto {name} no existe\")\n      case \"4\":\n        name = input(\"Escribe el nombre del contacto que deseas eliminar:\")\n        if name in agenda:\n          del agenda[name]\n          print(f\"Tu contacto {name} ha sido borrado\")\n        else:\n          print(f\"El contacto {name} no existe\")\n      case \"5\":\n        print(agenda)\n        break\n      case \"6\":\n        print(\"Hasta luego\")\n        break\n      case _:\n        print(f\"Opción no valida, selecciona una de las 5 opciones\")\n\nmi_agenda()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/C-Gabs.py",
    "content": "#Reto 03\n\n'''EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto\n *   en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n *   y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n *   y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más\n *   de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.'''\n\n\n#Creación de listas\n\nlista_1 = []\n\nlista_2 = list()\n\n#Inserción de elementos\nlista_1 = [\"JavaScript\"]\nprint(lista_1)\nlista_1.append(\"Python\")\nprint(lista_1)\nlista_1.append(\"Kotlin\")\nprint(lista_1)\nlista_1.insert(1,\"Swift\")\nprint(lista_1)\nlista_1.extend([\"C#\",\"C++\",\"Java\"])\nprint(lista_1)\n\nlista_2 = lista_1[:]\nprint()\n#Borrado de elementos\n\nlista_1.pop()\nprint(lista_1)\nlista_1.pop(0)\nprint(lista_1)\nlista_1.remove(\"C++\")\nprint(lista_1)\nlista_1.clear()\nprint(lista_1)\nprint()\n\n#ordenacón de elementos\n\nlista_2.sort()\nprint(lista_2)\nlista_2.reverse()\nprint(lista_2)\nprint()\n\n#actualización de elementos\n\nlista_2[3] = \"Html\"\nprint(lista_2)\nprint(\"\\n\")\n\n#Creación de tuplas\n\ntupla_1 = ()\ntupla_2 = tuple()\n\n#inserción de elementos\n\ntupla_1 = (\"Python\")\nprint(tupla_1)\ntupla_1 = (\"Python\", \"Java\")\nprint(tupla_1)\nprint()\n\n'''Las tuplas son estructuras no mutables,\nestas no se pueden modificar'''\n#tupla_1[1] = \"Html\"\n\n#Borrado de elementos\n\ntupla_1 = ()\nprint(tupla_1)\nprint(\"\\n\")\n\n#Creación de sets\n\nset_1 = set()\nset_2 = set()\n\n#Inserción de elementos\n\nset_2.add(\"Python\")\nprint(set_2)\nset_2.add(\"Kotlin\")\nprint(set_2)\nset_1.add(\"JavaScript\")\nprint(set_1)\nset_1.add(\"Java\")\nprint(set_1)\nset_1.add(\"Swift\")\nprint(set_1)\nset_1.add(\"HTML\")\nprint(set_1)\nprint()\n\n#Borrado de elementos\n\nset_1.discard(\"Java\")\nprint(set_1)\n\nset_1.remove(\"HTML\")\nprint(set_1)\n\nset_1.clear()\nprint(set_1)\nprint()\n\n#Actualización de elementos\nset_2.update({\"Java\",\"Swift\",\"SQL\"})\nprint(set_2)\nset_2.intersection_update({\"Pandas\",\"Python\",\"SQL\",\"Java\",\"HTML\"})\nprint(set_2)\nset_2.symmetric_difference_update({\"Python\",\"Kotlin\",\"SQL\",\"HTML\",\"Java\",\"Pandas\",\"Numpy\"})\nprint(set_2)\nprint(\"\\n\")\n\n'''Los set son estructuras no ordenadas,\npor lo que no tienen operaciones de ordenación\nasociadas'''\n\n#Creación de diccionarios\n\ndict_1 = {}\ndict_2 = dict()\n\n#Inserción de elementos\n\ndict_1[\"Nombre\"] = \"Brais\"\nprint(dict_1)\ndict_1[\"Apellido\"] = \"Moure\"\nprint(dict_1)\ndict_1 = {\"Nombre\":\"Brais\",\"Apellido\":\"Moure\",\"Alias\":\"MoureDev\"}\nprint()\n#Borrado de elementos\n\nretorno = dict_1.pop(\"Apellido\")\nprint(retorno)\nprint(dict_1)\nretorno = dict_1.popitem()\nprint(retorno)\nprint(dict_1)\ndict_1.clear()\nprint(dict_1)\nprint()\n\n#Actualización de elementos\ndict_1 = {\"Nombre\":\"Brais\",\"Apellido\":\"Moure\",\"Alias\":\"MoureDev\",\"Lenguaje\":\"Kotlin\"}\nprint(dict_1)\ndict_1.update({\"Lenguaje\":\"Python\",\"Librerias\":[\"Pandas\", \"Numpy\"]})\nprint(dict_1)\nprint(\"\\n\")\n\n#Reto Extra\n\ncontactos = {}\nopcion_menu = 1\nimport os\nwhile opcion_menu != 0:\n    print(\"AGENDA DE CONTACTOS\")\n    try:\n        opcion_menu = int(input('''\n            Elija una opción\\n\n            1- Buscar contactos\n            2- Agregar contacto\n            3- Actualizar contacto\n            4- Eliminar contacto\n            5- Imprimir agenda                 \n            0- Finalizar programa                   \n            '''))\n        if opcion_menu < 0 or opcion_menu > 5:\n            raise ValueError\n    except ValueError:\n        print(\"Debe ingresar un caracter numérico entre el 0 y el 5\\n\")\n    else:\n        if opcion_menu == 1:\n            os.system(\"cls\")\n            print(\"BUSCAR CONTACTO\")\n            opcion_1 = \"SI\"\n            while opcion_1.upper() != \"NO\":\n                try:\n                    nombre = str(input(\"Ingrese el nombre del contacto \\n\"))\n                except ValueError:\n                    print(\"Valor no válido, debe ingresar una cadena de texto\\n\")\n                else:    \n                    print(f\"{nombre}:\", contactos.get(nombre, \"No se encontró el contacto solicitado\\n\"))\n                finally:    \n                    opcion_1 = str(input(\"Desea buscar otro contacto? SI/NO\\n\"))\n\n        elif opcion_menu == 2:\n            os.system(\"cls\")\n            print(\"AGREGAR CONTACTO\")\n            opcion_2 = \"SI\"\n            while opcion_2.upper() != \"NO\":\n                try:\n                    nombre = str(input(\"Ingrese el nombre del contacto\\n\"))\n                    telefono = int(input(\"Ingrese el número telefonico del contacto\\n\"))\n                    if len(str(telefono)) > 11:\n                        raise ValueError\n                except ValueError:\n                    print('''\n                    Valor no válido\n                    El nombre de contacto debe ser una cadena de texto\n                    El número de telefono debe ser compuesto solo por caracteres numéricos\n                    y no contener mas de 11 caracteres\\n''')\n                else:\n                    contactos[nombre] = telefono\n                    print(contactos)\n                finally:\n                    opcion_2 = str(input(\"Desea agregar otro contacto? SI/NO\\n\"))\n        elif opcion_menu == 3:\n            os.system(\"cls\")\n            print(\"ACTUALIZAR CONTACTO\")\n            opcion_3 = \"SI\"\n            while opcion_3.upper() != \"NO\":\n                try:\n                    nombre = str(input(\"Ingrese el nombre del contacto que desea actualizar\\n\"))\n                    nuevo_nombre = str(input(\"Ingrese el nuevo nombre del contacto\\n\"))\n                    telefono = int(input(\"Ingrese el nuevo número telefonico del contacto\\n\"))\n                    if len(str(telefono)) > 11:\n                        raise ValueError              \n                except ValueError:\n                    print('''\n                    Valor no válido\n                    El nombre de contacto debe ser una cadena de texto\n                    El número de telefono debe ser compuesto solo por caracteres numéricos\n                    y no contener mas de 11 caracteres\\n''')\n                else:\n                    if nombre in contactos.keys():\n                        contactos.pop(nombre)\n                        contactos.update({nuevo_nombre:telefono})\n                        print(contactos)\n                    else:\n                        print(\"El contacto no fue encontrado\")\n                finally:\n                    opcion_3 = str(input(\"Desea actualizar otro contacto? SI/NO\\n\"))\n        elif opcion_menu == 4:\n            os.system(\"cls\")\n            print(\"ELIMINAR CONTACTO\")\n            opcion_4 = \"SI\"\n            while opcion_4.upper() != \"NO\":    \n                try:\n                    nombre = str(input(\"Ingrese el nombre del contacto que desea eliminar\\n\"))\n                except ValueError:\n                    print(\"Valor no válido, debe ingresar una cadena de texto\\n\")\n                else:\n                    if nombre in contactos.keys():\n                        contactos.pop(nombre)\n                        print(contactos)\n                    else:\n                        print(\"El contacto no fue encontrado\")\n                finally:\n                    opcion_4 = str(input(\"Desea eliminar otro contacto? SI/NO\\n\"))\n        elif opcion_menu == 5:\n            os.system(\"cls\")\n            print(\"CONTACTOS\\n\")\n            print(contactos)\n            input(\"presione una tecla para continuar: \")\n        elif opcion_menu == 0:\n            print(\"Adios\")\n        else:\n            print(\"Esta opción no es válida\")"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/CRaphaelAM.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto\n *   en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n *   y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n *   y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más\n *   de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.\n\"\"\"\n\n#LISTAS\n# Creación de una lista\nmi_lista = [10, 20, 30, 40]\n\n# Inserción\nmi_lista.append(50)           # Agrega al final\nmi_lista.insert(2, 25)        # Inserta el valor 25 en el índice 2\n\n# Actualización\nmi_lista[0] = 5               # Cambia el primer elemento\n\n# Borrado\nmi_lista.remove(40)           # Elimina el valor 40\ndel mi_lista[1]               # Elimina el elemento en el índice 1\n\n# Ordenación\nmi_lista.sort()               # Ordena de menor a mayor\n\nprint(mi_lista)  # [5, 25, 30, 50]\n\n#TUPLAS\n# Creación de una tupla\nmi_tupla = (10, 20, 30, 40)\n\n# Las tuplas no soportan inserciones, eliminaciones ni actualizaciones porque son inmutables\nprint(mi_tupla)\n\n#SETs\n# Creación de un conjunto\nmi_conjunto = {10, 20, 30, 40}\n\n# Inserción\nmi_conjunto.add(50)  # Agrega un nuevo elemento\n\n# Borrado\nmi_conjunto.remove(30)  # Elimina el elemento 30\n\n# Actualización\n# No hay actualización directa en un conjunto, pero puedes eliminar y volver a agregar un elemento\n\n# Ordenación (los conjuntos no tienen un orden definido, por lo que primero debemos convertirlo en una lista)\nconjunto_ordenado = sorted(mi_conjunto)\n\nprint(conjunto_ordenado)  # [10, 20, 40, 50]\n\n\n#DICCIONARIOS\n# Creación de un diccionario\nmi_diccionario = {'nombre': 'Un Nombre', 'edad': 26, 'profesion': 'Doctor'}\n\n# Inserción\nmi_diccionario['pais'] = 'España'  # Agrega una nueva clave-valor\n\n# Actualización\nmi_diccionario['edad'] = 27      # Actualiza el valor de la clave 'edad'\n\n# Borrado\ndel mi_diccionario['profesion']  # Elimina la clave 'profesion'\n\n# Ordenación (los diccionarios no son ordenados, pero puedes ordenar las claves y luego acceder a sus valores)\ndiccionario_ordenado = dict(sorted(mi_diccionario.items()))\n\nprint(diccionario_ordenado)  # {'edad': 27, 'nombre': 'Carlos', 'pais': 'Cuba'}\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n *   y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n *   y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más\n *   de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.\n\"\"\"\n\nprint(\"************Dificultad Extra*************\")\n\nagenda = {}\ncontinuar = True\n\nwhile continuar:\n    error = True\n    while error:\n        print(\"\"\" *****Agenda de contactos*****\n        1 - Agregar un contacto.\n        2 - Actualizar un contacto.\n        3 - Buscar un contacto.\n        4 - Eliminar un contacto.\n        5 - Salir.\n        \"\"\")\n        opcion = input(\"Que operacion desea realizar?: \")\n\n        if int(opcion)>5 or int(opcion) <1:\n            print(\"Debe ingresar una opcion valida.\")\n        else: error = False\n\n    print(\"Procesando solicitud...\")\n\n    match opcion:\n        case '1':\n            error_entrada = True\n            while error_entrada:\n                print(\"Ingrese los datos del contacto que desea agregar: \")\n                nombre = input(\"Ingrese el nombre: \")\n                telefono = input(\"Ingrese el telefono: \")\n                if len(telefono) != 11 or not telefono.isdigit():\n                    print(\"Por favor ingrese un numero con formato correcto.\")\n                    continue\n                error_entrada = False\n                    \n            if nombre in agenda:\n                print(\"El contacto parece estar registrado en la agenda.\")\n            else: \n                agenda[nombre] = telefono\n                print(\"Contacto agregado a la agenda con exito.\")\n        \n        case '2': \n            nombre = input(\"Ingrese el nombre del contacto que desea modificar: \")\n            if nombre in agenda:\n                telefono = input(\"Ingrese el nuevo número de teléfono del contacto: \")\n                agenda[nombre] = telefono\n                print(\"Contacto actualizado correctamente.\")\n            else: print(\"El contacto no esta registrado en la agenda.\")\n        \n        case '3':\n            print(\"Desea buscar el contacto por nombre o numero de telefono?: \")\n            criterio = input(\"1- Nombre\\t\\t2- Telefono\\nOpcion:\")\n\n            if criterio == '1':\n                nombre = input(\"Ingrese el nombre que desea buscar: \")\n                if not nombre in agenda:\n                    print(\"El nombre ingresado no esta registrado en la agenda.\")\n                else:\n                    print(f\"\"\"\n                        Informacion de contacto:\n                        Nombre: {nombre}\n                        Telefono: {agenda[nombre]}\n                    \"\"\")\n            elif criterio == '2':\n                telefono = input(\"Ingrese el telefono que desea buscar: \")\n                for nom,telef in agenda.items():\n                    if telefono == telef:\n                        print(f\"\"\"\n                        Informacion de contacto:\n                        Nombre: {nom}\n                        Telefono: {telef}\n                        \"\"\")\n            else: print(\"La opcion ingrasada no es valida.\")\n\n        case '4':\n            nombre = input(\"Ingrese el nombre del contacto que desea eliminar: \")\n            if nombre in agenda:\n                del agenda[nombre]\n            else: print(\"El nombre ingresado no se encuentra registrado en la agenda.\")\n\n    if opcion != 5:\n        continuar = input(\"Desea realizar otra operacion? 1- Si 2- No : \")\n        continuar = True if continuar == '1' else False\n    else: break\n\nprint(\"Saliendo del programa...\")\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Caleb699-hub.py",
    "content": "\"\"\"listas\"\"\"\n\nlista = [\"hola\",\"Caleb\",\"21\",\"python\", True, False]\nprint(lista)\n\n#añadir elementos\n\n#al final de la lista\nlista.append(\"maracuya\")\n\n#en el índice que de indica\nlista.insert(1,False)\n\n#agrega una los elementos de una lista al final\nlista.extend([\"perro\",\"gato\"])\n\n\n#eliminar elementos\n\n#elimina el elemento indicado\nlista.remove(\"maracuya\")\n\n#elimina el elemento de indice indicado\nlista.pop(1)\n\n#elimina la lista\nlista.clear()\n\nprint(lista)\n\n\n\n\"\"\"TUPLAS\"\"\"\n\n\ntupla = (\"hola\",\"Caleb\",\"21\",\"python\", True)\n\n\n#buscar\n\n\n#por indice\nprint(tupla[1])\n\n#verifica su existencia en la tupla\nv = \"hola\" in tupla\nprint(v)\n\n\n\n\"\"\"CONJUNTOS\"\"\"\n\nconjunto = {1,2,3,4,5}\n\n#agregar elemento\nconjunto.add(6)\n\n#elimina elemento\nconjunto.remove(1)\n\n#operaciones con conjuntos\na = {1,2,3}\nb = {3,4,5}\nprint(a | b) #union\nprint(a & b) #intersección\nprint(a - b) #diferencia\n\n\n\n\n\"\"\"DICCIONARIOS\"\"\"\n\n\ndiccionario = {\"Nombre\": \"Caleb\", \"Edad\": 21, \"Pais\": \"Colombia\"}\n\n#agregar elemento\ndiccionario[\"lenguaje_de_programacion\"] = \"Python\"\n\n#eliminar elemento\ndel diccionario[\"Pais\"]\n\nprint(diccionario)\n\n\n\"\"\"\nDIFICULTAD EXTRA\n\"\"\"\n\nagenda_contactos = {}\n\ndef agregar_contacto():\n    nombre_contacto = input(\"Nombre de contacto: \")\n    numero_telefono = input(\"Numero de contacto: \")\n    agenda_contactos[nombre_contacto] = numero_telefono\n    print(\"Su contacto ha sido agregado\")\n\ndef buscar_contacto():\n    nombre_contacto = input(\"Introduzca el nombre de contacto: \")\n    if nombre_contacto in agenda_contactos:\n        print(f\"{nombre_contacto} = {agenda_contactos[nombre_contacto]}\")\n    else:\n        print(\"Contacto no encontrado\")\n\ndef acualizar_contacto():\n    nombre_contacto = input(\"Introduzca el nombre del contacto que va a actualizar: \")\n    if nombre_contacto in agenda_contactos:\n        numero_nuevo = input(\"Introduzca el nuevo número de teléfono: \")\n        agenda_contactos[nombre_contacto] = numero_nuevo\n        print(\"Contacto actualizado\")\n    else:\n        print(\"Contacto no encontrado\")\n\ndef eliminar_contacto():\n    nombre_contacto = input(\"Ingrese el nombre del contacto que desea eliminar: \")\n    if nombre_contacto in agenda_contactos:\n        del agenda_contactos[nombre_contacto]\n        print(\"El contacto ha sido elinminado\")\n    else:\n        print(\"Contacto no encontrado\")\n\ndef lista_contactos():\n    if len(agenda_contactos)==0:\n        print(\"La agenda está vacía\")\n    else:\n        for nombre_contacto,numero_telefono in agenda_contactos.items():\n            print(f\"{nombre_contacto}: {numero_telefono}\")\n\ndef mostrar_menu():\n    print(\"MENÚ DE AGENDA DE CONTACTOS\")\n    print(\"1. Agregar contacto\")\n    print(\"2. Buscar contacto\")\n    print(\"3. Actualizar contacto\")\n    print(\"4. Eliminar contacto\")\n    print(\"5. Lista de contactos\")\n    print(\"6. Salir\")\n\n\nwhile True:\n    mostrar_menu()\n    opcion = int(input(\"Ingrese una opcion del menú: \"))\n\n    if opcion == 1:\n        agregar_contacto()\n    elif opcion == 2:\n        buscar_contacto()\n    elif opcion == 3:\n        acualizar_contacto()\n    elif opcion == 4:\n        eliminar_contacto()\n    elif opcion == 5:\n        lista_contactos()\n    elif opcion == 6:\n        print(\"Programa finalizado\")\n        break\n    else:\n        print(\"Opción no válida, ingrese un valor del menú\")"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Carl6289.py",
    "content": "print(\"Ejemplo con listas (list)\")\nprint(\"Creación\")\nlista_de_compras = [\"arroz\", \"frutas\", \"verduras\", \"leche\", \"huevos\", \"refresco\", \"carne\"] # Creación\nprint(lista_de_compras)\nprint(\"Inserción\")\nlista_de_compras.append(\"pescado\") # Insersión\nprint(lista_de_compras)\nprint(\"Borrado\")\nlista_de_compras.remove(\"refresco\") # Borrado\nprint(lista_de_compras)\nprint(\"Actualización\")\nlista_de_compras[0] = \"cereal\" # Actualización\nprint(lista_de_compras)\nprint(\"Ordenación\")\nlista_de_compras.sort() # Ordenación\nprint(lista_de_compras)\nprint()\n\nprint(\"Ejemplo con diccionarios (dict)\")\ncapitales_venezuela = {\"Zulia\": \"Cabimas\", \"Lara\": \"Barquisimeto\", \"Carabobo\": \"Valencia\"} # Creación\nprint(\"Creación\")\nprint(capitales_venezuela)\nprint(\"Inserción\")\ncapitales_venezuela[\"Distrito Capital\"] = \"Caracas\" # Inserción\nprint(capitales_venezuela)\nprint(\"Borrado\")\ndel capitales_venezuela[\"Lara\"] # Borrado\nprint(capitales_venezuela)\nprint(\"Actualización\")\ncapitales_venezuela[\"Zulia\"] = \"Maracaibo\" # Actualización\nprint(capitales_venezuela)\nprint(\"Ordenación\")\nordenadas = sorted(capitales_venezuela.keys()) # Ordenación\nprint(ordenadas)\nprint()\n\nprint(\"Ejemplo con conjuntos (set)\")\nprint(\"Creación\")\nconjunto_numeros = {45, 34, 12} # Creación\nprint(conjunto_numeros)\nprint(\"Inserción\")\nconjunto_numeros.add(23)\nprint(conjunto_numeros)\nprint(\"Borrado\")\nconjunto_numeros.remove(12)\nprint(conjunto_numeros)\nprint(\"No aplica actualización\")\nprint(\"Ordenación\")\nnumeros_ordenados = sorted(conjunto_numeros)\nprint(numeros_ordenados)\nprint()\n\nprint(\"***AGENDA DE CONTACTOS***\")\nagenda_contactos = {\"carlos\": \"04167209454\", \"norelys\": \"04241503333\"}\ndef listar_agenda(agenda_contactos):\n    for nombre, numero in agenda_contactos.items():\n     print(f\"{nombre}: {numero}\")\nlistar_agenda(agenda_contactos)\n\ndef buscar_contacto(agenda_contactos): # Función buscar\n   while True:\n     nombre_buscado = input(\"Ingrese el contacto a buscar: \")\n     if nombre_buscado in agenda_contactos:\n       numero = agenda_contactos[nombre_buscado]\n       print({nombre_buscado})\n       print({numero})\n       break\n     else:\n        print(\"Este contacto no existe\")\n\ndef insertar_contacto(agenda_contactos): # Función insertar\n   nuevo_nombre = input(\"Ingrese el nombre: \")\n   while True:\n    nuevo_numero = input(\"Ingrese el número (máx. 11 dígitos): \")\n    if not nuevo_numero.isdigit():\n       print(\"El número de teléfono solo debe contener dígitos (0-9)\")\n       continue\n    elif len(nuevo_numero) > 11:\n       print(\"El número debe tener 11 dígitos o menos\")\n       continue\n    else:\n       agenda_contactos[nuevo_nombre] = nuevo_numero\n       print(f\"El contacto {nuevo_nombre} a sido registrado\")\n       print(agenda_contactos)\n       break\n\ndef actualizar_contacto(agenda_contactos): #Función actualizar\n   while True:\n    antiguo_nombre = input(\"Ingrese el nombre exacto a actualizar: \")\n    if antiguo_nombre in agenda_contactos:\n       while True:\n          opcion = input(\"1-Actualizar nombre, 2-Actualizar número: \")\n          if opcion == \"1\":\n             nuevo_nombre = input(f\"Ingrese el nuevo nombre para {antiguo_nombre}: \")\n             nombre_original = agenda_contactos[antiguo_nombre]\n             agenda_contactos[nuevo_nombre] = nombre_original\n             del agenda_contactos[antiguo_nombre]\n             print(\"¡El nombre a sido actualizado!\")\n             print(agenda_contactos)\n             break\n          elif opcion == \"2\":\n             while True:\n                nuevo_numero = input(f\"Ingrese el nuevo número para {antiguo_nombre}: \")\n                if not nuevo_numero.isdigit():\n                   print(\"El número de teléfono solo debe contener dígitos (0-9)\")\n                   continue\n                elif len(nuevo_numero) > 11:\n                   print(\"El número debe tener 11 dígitos o menos\")\n                   continue\n                else:\n                   agenda_contactos[antiguo_nombre] = nuevo_numero\n                   print(\"¡El número a sido actualizado!\")\n                   print(agenda_contactos)\n                break\n          else:\n             print(\"Opción invalida\")\n             continue\n          break      \n    else:\n       print(\"Este contacto no existe\")\n    break          \n\ndef eliminar_contacto(agenda_contactos): # Función eliminar\n   while True:\n      nombre = input(\"Ingrese el contacto a eliminar: \")\n      if nombre not in agenda_contactos:\n       print (\"Este contacto no existe\")\n       break\n      else:\n       while True:\n          opcion = input(f\"¿Esta seguro que desea eliminar a {nombre} de la lista de contactos? (y ó n): \")\n          if opcion == \"y\":\n             del agenda_contactos[nombre]\n             print(\"¡Contacto eliminado!\")\n             print(agenda_contactos)\n             break \n          elif opcion == \"n\":\n             break\n          else:\n             print(\"Opción invalida\")\n      break\n       \nwhile True:\n opcion = input(\"Elija una opción (1-Buscar, 2-Insertar, 3-Actualizar, 4-Eliminar, 5-Salir): \")\n if opcion == \"1\":\n    buscar_contacto(agenda_contactos)\n    continue\n elif opcion == \"2\":\n    insertar_contacto(agenda_contactos)\n    continue\n elif opcion == \"3\":\n    actualizar_contacto(agenda_contactos)\n    continue\n elif opcion == \"4\":\n    eliminar_contacto(agenda_contactos)\n    continue\n elif opcion == \"5\":\n    print(\"***¡Agenda de contactos cerrada!***\")\n    break\n else:\n    print(\"Opción invalida\")"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/CaveroBrandon.py",
    "content": "import sys\n\"\"\"\n* EJERCICIO:\nMuestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\nUtiliza operaciones de inserción, borrado, actualización y ordenación.\n\"\"\"\n\n\n# **** LIST ****\ndef data_structure_list():\n    ordinal_numbers = ['Second', 'Fourth', 'First']  # Create a list\n    ordinal_numbers.remove('Fourth')  # Remove an element from the list\n    ordinal_numbers.append('Third')  # Append/add an element to the list\n    ordinal_numbers.sort()  # Sort the list\n    first_element = ordinal_numbers[0]  # Accessing an element within\n    ordinal_numbers.clear()  # Clear the list\n\n\n# **** TUPLE ****\ndef data_structure_tuple():\n    users_category = (1, 2, 'Trial', 'Freemium', 'Premium', 'Pro')  # Create a tuple\n    category_slice = users_category[2:]  # Slicing the tuple\n    non_users_category = (-1, -2, 'ex member', 'non member')  # Create a second tuple\n    all_categories = users_category + non_users_category  # Concatenation of two tuples\n    is_premium_in_categories = 'Premium' in all_categories  # Verification that the element 'Premium' is in tuple\n    premium_element_count = all_categories.count('Premium')  # Count how many times 'Premium' is in the tuple\n\n\n# **** DICTIONARIES ****\ndef data_structure_dictionaries():\n    players_stats = {'Jordan': 32292, 'Bryant': 33643, 'James': 46675}  # Create a dictionary\n    bryant_points = players_stats['Bryant']  # Accessing the value in the key 'Bryant'\n    players_stats['James'] = 46676  # Updating the value of the key 'James'\n    players_stats['Kareem'] = 38387  # Adding a new value in the dictionary\n    del players_stats['Jordan']  # Removing the element 'Jordan' from the dictionary\n    is_jordan_in_stats = 'Jordan' in players_stats  # Checking if the element 'Jordan' is in the dictionary\n    dictionary_keys = list(players_stats.keys())  # Getting the keys of the dictionary\n    dictionary_values = list(players_stats.values())  # Getting the values of the dictionary\n    soccer_stats = {'Messi': 821, 'Ronaldo': 873}  # Create a second dictionary\n    players_stats.update(soccer_stats)  # Merge the 'Soccer_stats' into the players stats\n    players_stats.clear()  # Clearing the players_stats dictionary\n\n\n# **** SETS ****\ndef data_structure_sets():\n    students_set = {'Brandon', 'Cavero', 'Brandon', 'Andres'}  # Creating a set\n    students_set.add('Moure')  # Adding the element 'Moure' to students_set\n    students_set.remove('Cavero')  # Remove the element 'Cavero' from the student_set\n    is_andres_in_students = 'Andres' in students_set\n    second_students_sets = {'Brandon', 'Kobe', 'Jordan'}  # Create a second set of elements\n    union_students_sets = students_set | second_students_sets  # Union of both sets\n    intersection_students_sets = students_set & second_students_sets  # Intersection of both sets\n    difference_students_sets = students_set - second_students_sets  # Difference of both sets\n    symmetric_students_sets = students_set ^ second_students_sets  # Symmetric difference of both sets\n    students_set.clear()  # Clearing the students_set\n\n\"\"\"\nDIFICULTAD EXTRA (opcional) Crea una agenda de contactos por terminal:\n- Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n- Cada contacto debe tener un nombre y un número de teléfono.\n- El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación los datos  necesarios para llevarla a cabo.\n- El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos (o el número de dígitos que quieras).\n- También se debe proponer una operación de finalización del programa. \n\"\"\"\n\n\ndef display_menu():\n    print('**** MENU ****\\n'\n          '1. Search contact\\n'\n          '2. Insert contact\\n'\n          '3. Update contact\\n'\n          '4. Remove contact\\n'\n          '5. Close\\n')\n    option = input('Select an option: ')\n    try:\n        option = int(option)\n    except ValueError:\n        print('Input an integer value between 1 and 5')\n        display_menu()\n\n    if 0 < int(option) <= 5:\n        if int(option) == 1:\n            search_contact()\n        elif int(option) == 2:\n            insert_contact()\n        elif int(option) == 3:\n            update_contact()\n        elif int(option) == 4:\n            remove_contact()\n        elif int(option) == 5:\n            sys.exit()\n    else:\n        print('Select a correct option between 1 and 5\\n')\n        display_menu()\n\n\ndef search_contact():\n    print('**** SEARCH CONTACT ****')\n    name = input('Input the name of the contact: ')\n    if agenda.get(name) is not None:\n        print(f'{name}', ':', agenda.get(name))\n        display_menu()\n    else:\n        print(f'No contact with name {name} was found')\n        display_menu()\n\n\ndef phone_number_input(name):\n    phone_number = input('Phone number: ')\n    if phone_number.isnumeric() and len(phone_number) <= 11:\n        agenda[name] = int(phone_number)\n        print(f'Contact {name} was successfully saved with phone number {phone_number}')\n        display_menu()\n    else:\n        print('Phone number must be a number with less than 11 digits, please try again')\n        phone_number_input(name)\n\n\ndef insert_contact():\n    print('**** INSERT CONTACT ****')\n    name = input('Name of the contact: ')\n    phone_number_input(name)\n\n\ndef update_contact():\n    print('**** UPDATE CONTACT ****')\n    name = input('Enter the contact name to update: ')\n    if name in agenda:\n        phone_number_input(name)\n    else:\n        print('Contact was not found, try again')\n        update_contact()\n\n\ndef remove_contact():\n    print('**** REMOVE CONTACT ****')\n    name = input('Enter the contact name to remove: ')\n    if name in agenda:\n        del agenda[name]\n        print(f'Contact {name} was successfully removed from the agenda')\n        display_menu()\n    else:\n        print('Contact was not found, try again')\n        remove_contact()\n\n\nagenda = dict()\ndisplay_menu()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/CesarCarmona30.py",
    "content": "'''\n  ESTRUCTURAS DE DATOS\n'''\n\n# Listas\nmy_list = [0, 5, 6, 2, 7, 2, 6, 8, 9, 4, 3, 3]\nprint(f'Mi lista = {my_list}') \nmy_list.append(\"texto\") # Inserción\nmy_list.append(True) # Inserción\nprint(f'Mi lista = {my_list}')\nmy_list.remove(True) # Borrado\nprint(f'Mi lista = {my_list}')\nmy_list[-1] = 10 # Actualización\nprint(f'Mi lista = {my_list}')\nmy_list.sort() # Ordenación\nprint(f'Mi lista = {my_list}')\n\n\n# Tuplas\nmy_tuple = (\"Carne\", \"Verduras\", \"Frutas\", \"Legumbres\")\nprint(f\"Mi tupla: {my_tuple}\")\nmy_tuple = tuple(sorted(my_tuple)) # Ordenación\nprint(f\"Mi tupla: {my_tuple}\")\nprint(type(my_tuple))\n\n# Sets\nmy_set = {\"Mexico, España, Argentina, Colombia, Chile, Peru\"}\nprint(f\"Mi set: {my_set}\") \nmy_set.add(\"Brasil\") # Inserción\nprint(f\"Mi set: {my_set}\")  \nmy_set.remove(\"Brasil\") # Borrado\nprint(f\"Mi set: {my_set}\") \n\n# Diccionario\nmy_dict = {\n  \"name\": \"César\",\n  \"surname\": \"Carmona\",\n  \"age\": \"19\",\n  \"country\": \"Mexico\",\n  \"city\": \"Guadalajara\"\n}\nprint(f\"Mi diccionario: {my_dict}\")\nmy_dict[\"gender\"] = \"Male\" # Inserción\nprint(f\"Mi diccionario: {my_dict}\")\ndel my_dict[\"gender\"] # Borrado\nprint(f\"Mi diccionario: {my_dict}\")\nmy_dict[\"city\"] = \"Mexico City\" # Actualización\nprint(f\"Mi diccionario: {my_dict}\")\nmy_dict = dict(sorted(my_dict.items())) # Ordenación\nprint(f\"Mi diccionario: {my_dict}\")\n\n\n'''\n  EXTRA\n'''\n\ndef my_contacts():\n\n  agenda = {}\n  name = ''\n\n  def insert_contact():\n    number = input(\"Introduce el número: \")\n    if number.isdigit() and len(number) > 0 and len(number) <= 10:\n      agenda[name] = number\n    else:\n      print(\"Introduce un número válido de 10 dígitos.\")\n\n  while True:\n\n    print(\"\\n - AGENDA TELEFÓNICA -\\n\")\n    print(\"1. Buscar contacto\")\n    print(\"2. Insertar contacto\")\n    print(\"3. Actualizar contacto\")\n    print(\"4. Eliminar contacto\")\n    print(\"5. Listar contactos\")\n    print(\"6. Salir\\n\")\n\n    option = input(\"Selecciona una opción: \")\n\n    match option:\n      case \"1\":\n        name = input(\"Introduce el nombre del contacto a buscar: \").lower()\n        if name in agenda:\n          print(f\"{name} - {agenda[name]}\")\n        else:\n          print(f\"{name} no existe.\")\n      case \"2\":\n        name = input(\"Introduce el nombre del nuevo contacto: \").lower()\n        insert_contact()\n        print(f\"{name} creado.\")\n      case \"3\":\n        name = input(\"Introduce el nombre del contacto a actualizar: \").lower()\n        if name in agenda:\n          insert_contact()\n          print(f\"{name} actualizado.\")\n        else:\n          print(f\"{name} no existe.\")\n      case \"4\":\n        name = input(\"Introduce el nombre del contacto a a eliminar: \").lower()\n        if name in agenda:\n          del agenda[name]\n          print(f\"{name} eliminado.\")\n        else:\n          print(f\"{name} no existe.\")\n      case \"5\":\n        if agenda:\n          print('Contactos - Números')\n          for contact, phone in agenda.items():\n            print(f'{contact} - {phone}')\n        else:  \n          print('Agenda vacía, agrega nuevos contactos.')\n      case \"6\":\n        print(\"Saliendo de la agenda.\")\n        break\n      case _:\n        print(\"Elige una opción del 1 al 5.\")\n\nmy_contacts()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Chrisdev00.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\"\"\"\n\n\n#  ------------------------------------- Estructuras de datos------------------------------------------------\n\n\"\"\"\n                             ########## Listas ##########\n\nAlmacenan una colección ordenada y mutable de elementos.\n\"\"\"\n\nlst = list()\nlista = [1, 2, 3, 4, 5]\nprint(lista)\n\n# Inserción\nlista.append(6)\nprint(lista)\n\n# Borrado\nlista.remove(3)\nprint(lista)\n\n# Actualización\nlista[1] = 10\nprint(lista)\n\n# Ordenación\nlista.sort()\nprint(lista)\n\n\n\"\"\"\n                              ######### Tuplas ##########\n\nSimilar a las listas, pero inmutable.\nLas tuplas son inmutables, por lo que no admiten inserción, borrado ni actualización. \nPero Puedes ordenar una tupla convirtiéndola a lista primero.\n\"\"\"\n\nempty_tuple = tuple()\ntupla = (1, 2, 3, 4, 5)\nprint(tupla)\n\ntupla = (1, 2, 5, 4, 3)\n\n# Conversión a lista y ordenación\nlista_tupla = list(tupla)\nlista_tupla.sort()\ntupla_ordenada = tuple(lista_tupla)\nprint(tupla_ordenada)\n\n\"\"\"\n                            ######## Diccionarios #########\n\nAlmacenan pares clave-valor. Los diccionarios no tienen un orden específico.\n\"\"\"\n\nempty_dict = dict()\ndiccionario = {'a': 1, 'b': 2, 'c': 3}\nprint(diccionario['a'])\n\n# Inserción\ndiccionario['d'] = 4\nprint(diccionario)\n\n# Borrado\ndel diccionario['b']\nprint(diccionario)\n\n# Actualización\ndiccionario['a'] = 10\nprint(diccionario)\n\n\"\"\"\n                           ###### Conjuntos #######\n\nAlmacenan elementos únicos sin un orden específico. Los conjuntos no tienen un orden específico.\n\"\"\"\n\nst = set()\nconjunto = {1, 2, 3, 4, 5}\nconjunto.add(6)\nprint(conjunto)\n\nconjunto = {1, 2, 3, 4, 5}\n\n# Inserción\nconjunto.add(6)\nprint(conjunto)\n\n# Borrado\nconjunto.remove(3)\nprint(conjunto)\n\n\"\"\"\n                        #### Cadenas de Texto ####\n\nAlmacenan texto. Las cadenas de texto son inmutables, por lo que no admiten inserción, \nborrado ni actualización. Puedes ordenar una cadena convirtiéndola a lista primero.\n\"\"\"\n\ncadena = \"Hola, mundo!\"\nprint(cadena)\n\n# Conversión a lista y ordenación\nlista_cadena = list(cadena)\nlista_cadena.sort()\ncadena_ordenada = ''.join(lista_cadena)\nprint(cadena_ordenada)\n\n\n\"\"\"\n                ###### Estructuras de control - if-else: #######\n\nPermite tomar decisiones basadas en condiciones.\n\"\"\"\n\nx = 10\nif x > 5:\n    print(\"x es mayor que 5\")\nelse:\n    print(\"x no es mayor que 5\")\n\n\n\n\"\"\"\n                         ####### Bucles-for: #######\n    \nItera sobre una secuencia (por ejemplo, una lista o tupla).\n\"\"\"\n\nfor i in range(5):\n    print(i)\n\n\n\"\"\"\n                      ######## Bucles - while: ########\n    \nEjecuta un bloque de código mientras una condición sea verdadera.\n\"\"\"\n\ncontador = 0\nwhile contador < 5:\n    print(contador)\n    contador += 1\n\n\"\"\"\n                        ####### Funciones ########\n    \nBloques de código reutilizables.\n\"\"\"\n    \ndef suma(a, b):\n    return a + b\n\nresultado = suma(3, 4)\nprint(resultado)\n\n\"\"\"\n                              ####### Clases y Objetos #######\n\nPermiten la programación orientada a objetos.\n\"\"\"\n\nclass Persona:\n    def __init__(self, nombre, edad):\n        self.nombre = nombre\n        self.edad = edad\n\npersona1 = Persona(\"Alice\", 25)\nprint(persona1.nombre)\n\n\nclass Person:\n      def __init__(self, firstname, lastname, age, country, city):\n          self.firstname = firstname\n          self.lastname = lastname\n          self.age = age\n          self.country = country\n          self.city = city\n\n\np = Person('Alice', 'Jhons', 28, 'Finland', 'Helsinki')\nprint(p.firstname)\nprint(p.lastname)\nprint(p.age)\nprint(p.country)\nprint(p.city)\n\n\n\n\n\"\"\"\n                     -------------Dificultad Extra-------------\n\"\"\"\n\n# Funcion para añadir\n\ndef insertar (diccionario):\n\n    name = input(\"Ingrese su nombre: \")\n    phoneNumber = input(\"Ingrese su numero de telefono: \")\n    \n    if phoneNumber.isdigit() and len(phoneNumber) > 0 and len(phoneNumber) <= 8:\n\n        diccionario[name] = phoneNumber\n        print(f\"Se ha insertado correctamente sus datos: {name}: {phoneNumber}\")\n        print(f\"Agenda actualizada: {diccionario}\")\n    else:\n        print(\"!Error debes introducir un numero de telefono un maximo de 8 digitos\")\n\n\n\n# Funcion para buscar \n        \ndef busqueda (diccionario):\n\n    while True:\n        option = input(\"¿Desea hacer una busqueda por nombre (n) o por numero de telefono (t)? \").lower()\n\n        if option == \"n\":\n\n            clave_nombre = input(\"Ingrese el nombre a buscar: \")\n            if clave_nombre in diccionario:\n                nombre_encontrado = diccionario[clave_nombre]\n                print(f\"El nombre fue encontrado: '{clave_nombre}': {nombre_encontrado} \")\n                break\n            else:\n                print(f\"No se encontro el nombre '{clave_nombre}' en la agenda\")\n                break\n\n        elif option == \"t\":\n\n            clave_telefono = input(\"Ingrese el numero de telefono: \")\n            claves_encontradas = [clave for clave, valor in diccionario.items() if valor == clave_telefono]\n            if claves_encontradas:\n                print(f\"Numero de telefono encontrado: '{clave_telefono}': {claves_encontradas}\")\n                break\n            else:\n                print(f\"No se encontro el numero de telefono '{clave_telefono}'.\")\n                break\n        else:\n            print(\"Opcion no valida. Por favor, seleccione 'N' o 'T'.\")\n\n\n# Funcion actualizar\n            \ndef upgrade (diccionario):\n\n    while True:\n        option = input(\"Desea actualizar el nombre (N) o numero de telefono (T): \").lower()\n\n        if option == \"n\":\n            nombre_actualizar = input(\"Ingrese el nombre a actualizar: \")\n            \n            if nombre_actualizar in diccionario:\n                nuevo_nombre = input(\"Ingrese el nuevo nombre: \")\n                diccionario[nuevo_nombre] = diccionario.pop(nombre_actualizar)\n                print(f\"Agenda actualizada: {diccionario}\")\n                break\n            else:\n                print(f\"No se encontro el nombre '{nombre_actualizar}'. No se puede actualizar\")\n\n        elif option == \"t\":\n            telf_actualizar = input(\"Ingrese el numero a actualizar: \")\n            claves_encontradas = [clave for clave, valor in diccionario.items() if valor == telf_actualizar]\n\n            if claves_encontradas:\n                clave_encon = claves_encontradas[0]\n                nuevo_num = input(f\"Ingrese el nuevo numero de telefono para {clave_encon}: \")\n                diccionario[clave_encon] = nuevo_num\n\n                print(f\"Agenda actualizada: {diccionario}\")\n                break\n            else:\n                print(f\"No se encontro el numero '{telf_actualizar}' en el diccionario no se puede actualizar.\")\n                break\n        else:\n            print(\"Opcion no valida seleccione 'N' o 'T'.\")      \n\n\n\n# Funcion borrar\n            \ndef delete (diccionario):\n\n    elimi_nombre = input(\"Ingrese el contacto que desea eliminar: \")\n    if elimi_nombre in diccionario:\n        del diccionario[elimi_nombre]\n    print(f\"Agenda actualizada: {diccionario}\")\n\n\n\n\n# Funcion principal de la agenda telefonica\n    \ndef agenda_tel():\n\n    agenda = {}\n    \n    while True:\n\n        print(\"\")\n        print(\"1. Insertar Contacto\")\n        print(\"2. Buscar contacto\")\n        print(\"3. Actualizar contacto\")\n        print(\"4. Eliminar contacto\")\n        print(\"5. Salir\")\n\n        option = input(\"\\nSelecciona una opcion: \")\n\n        match option:\n            case \"1\":\n                insertar(agenda)\n            case \"2\":\n                busqueda(agenda)\n            case \"3\":\n                upgrade(agenda)\n            case \"4\":\n                delete(agenda)\n            case \"5\":\n                print(\"Saliendo de la agenda\")\n                break\n            case _:\n                print(\"Opcion no valida. Elige una opcion del 1 al 5.\")\n\nagenda_tel()    \n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Complex303.py",
    "content": "\"\"\"\nEstructura de datos\n\"\"\"\n\n#Lista: Mutable (se puede modificar). Más lenta que la tupla. Se declara con []\n\nlista = ['Jose', 'Daniel', 'Julio', 'Maria']\nprint(lista)\n\nlista.append('Eddy') #insercion\nprint(lista)\nlista.remove('Daniel') #Eliminacion\nprint(lista)\nprint(lista[2]) #imprimir la persona que esta en la posicion 2\nlista[2] = 'Ana' #actulizacion, el que estaba en la posicion 2 desaparece\nprint(lista)\nlista.sort() #ordenacion\nprint(lista)\nprint(type(lista))\n\n\n#Tuplas: Inmutable (no se puede modificar). Más rápida que la lista. Se declara con ()\ntupla: tuple = ('Jose', 'Feliciano', 'King', '20')\nprint(tupla[1]) #Feliciano\nprint(tupla[3]) #20\ntupla = tuple(sorted(tupla)) #ordernar la tupla \nprint(tupla)\nprint(type(tupla))\n\n\n\n#Sets: Colección desordenada, sin índices. No permite elementos repetidos. Se declara con {} o set().\nmy_sets: set = {'Jose', 'Feliciano', 'King', '20'}\nprint(my_sets)\nprint(type(my_sets))\nmy_sets.add(\"Curso de programacion\") #Inserccion\nprint(my_sets)\n#print(my_sets[0]) # tendria sentido hacer esto porque es una coleccion sin indice (desordenada)\nmy_sets.remove('King') #Eliminacion\nprint(my_sets)\nmy_sets = set(sorted(my_sets)) #No se puede ordenar\nprint(my_sets)\n\n\n#Diccionario: es una colección desordenada de pares clave-valor, donde cada valor se accede mediante su clave (no por posición).\ndiccionario: dict =  {\n    'name': 'Eddy',\n    'surname': 'Hernandez',\n    'Alias': 'Complex',\n    'age': 23\n}\n\nprint(diccionario)\nprint(diccionario['name']) #me imprime el valor de la clave name\ndiccionario['Email'] = 'Complex781gmail.com' #inserccion\nprint(diccionario)\ndiccionario['age'] = 24 #Actualizacion\nprint(diccionario)\ndel diccionario['surname'] #Eliminacion\nprint(diccionario)\ndiccionario = dict(sorted(diccionario.items())) #Ordenacion. Items  se usa pedir todos los pares de datos (clave y valor) junto\nprint(diccionario)\nprint(type(diccionario))\n\n\"\"\"DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n \"\"\"\n\ndef agenda_contaco():\n\n\n    agenda: dict = {}\n\n    def insertar_contacto():\n        telefono = input('Introduzca el nuevo numero telefonico: ')\n        if telefono.isdigit and len(telefono) >= 0 and len(telefono) <= 11:\n                agenda[nombre] = telefono\n        else: \n                    print('------------------------------------')\n                    print('Debes introducir un numero de telefono maximo de 11 digitos: ')\n\n    def contancto_no_existe():\n         print('------------------------------------')\n         print(f'Contacto {nombre} no existe')\n            \n\n\n    while True:\n\n        print('=============================')\n        print('1. Buscar contacto')\n        print('2. Insertar contacto')\n        print('3. Actualizar contacto')\n        print('4. Eliminar contacto')\n        print('5. Salir')\n        print('=============================')\n\n        opcion = input('\\nElige una opcion: ')\n\n        match opcion:\n            case \"1\":\n                nombre = input('Introduzca el nombre del contacto: ')\n                if nombre in agenda:\n                    print(f'El Telefono de {nombre} es: {agenda[nombre]}')\n                else: \n                    contancto_no_existe()\n\n\n            case \"2\":\n                nombre = input('Introduzca el nombre del contacto: ')\n                insertar_contacto()\n                print('Los datos se han ingresado correctamente!!')\n\n            \n            case \"3\":\n                nombre = input('Introduzca el nombre del contacto: ')\n                if nombre in agenda:\n                    insertar_contacto()\n                    print('Los datos se han actualizado correctamente!!')\n                else: \n                    contancto_no_existe()\n                        \n                \n            case \"4\":\n                nombre = input('Introduzca el nombre del contacto: ')\n                if nombre in agenda:\n                    del agenda[nombre]\n                    print('Los datos se han borrado correctamente!!')\n                else: \n                    contancto_no_existe()\n\n\n            case \"5\":\n                print('------------------------------------')\n                print('saliendo...')\n                break\n             \n\n            case _:\n                print('------------------------------------')\n                print('Opcion no valida. Elige un numero del 1 al 5')\n                print('')\n\n\nagenda_contaco()\n  \n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/D3rk1us.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\"\"\"\n\n# Listas\n\nnombres= ['Maria', 'Nushi', 'Jose', 'Wei']\napellidos = [] #Lista vacía\n\nmatriz = [\n    [1, 2, 4, 6, 9],\n    [10, 20, 40, 80],\n    [11, 22, 33, 44],\n]\n\nnombres.sort()  # Ordenar\nprint(nombres)\n\napellidos.append('Smith') # Insertar\nprint(apellidos)\n\n# Tuplas\n\ntupla1 = \"Prueba\", 34214, 3.2\ntupla2 = tupla1, \"Tres\", \"Cuatro\", 14\n\n# Conjuntos\n\nfrutas = {'Naranja', 'Manzana', 'Pera', 'Uva', 'Granada'}\nfrutas.remove('Uva')    # Borrar\nprint(frutas)\n\n\n# Diccionarios\n\nusuario = {'nombre': 'Marc', 'apellido': 'Spector', 'oficio': 'Agente de Inteligencia'}\nusuario['nombre'] = 'Steven'  # Reemplazar\nprint(usuario)\n\n\n\n# /////////////////////////////////////  DIFICULTAD EXTRA (opcional)  /////////////////////////////////////\n\n\nagenda = [] # Lista para guardar los contactos.\nexit = True # Variable para mantener o terminar el bucle While.\n\n# Funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n\ndef agregar():\n\n    nombre = input(\"Introduce el nombre del contacto: \")\n    numero = input(\"Introduce el número del contacto: \")\n\n    try:\n        # Comprueba si es un número y si tiene menos de 11 dígitos.\n        if isinstance(int(numero), int) and len(numero) <= 11:\n        \n            return agenda.append({'nombre': nombre, 'numero': numero})\n\n    except:\n\n        print(\"El número no debe tener letras y no debe tener más de 11 dígitos.\")\n        agregar()\n\ndef actualizar():\n\n    opcion = input(\"Deseas actualizar el 'nombre' o 'número': \")\n\n    if opcion == 'nombre':\n\n        nombre_actual = input(\"Indica el nombre actual del contacto: \")\n        cambio_nombre = input(\"Indica el nombre al que deseas cambiarlo: \")\n         \n        for contacto in agenda:\n\n            if contacto['nombre'] == nombre_actual:\n                contacto['nombre'] = cambio_nombre\n                return contacto\n\n    elif opcion == 'número':\n        \n        numero_actual = input(\"Indica el número actual del contacto: \")\n        cambio_numero = input(\"Indica el número al que deseas cambiarlo: \")\n        \n        try:\n            \n            if isinstance(int(cambio_numero), int) and len(cambio_numero) <= 11:\n                \n                for contacto in agenda:\n\n                    if contacto['numero'] == numero_actual:\n                        contacto['numero'] = cambio_numero\n                        return contacto\n\n        except:\n\n            print(\"El número no debe tener letras y no debe tener más de 11 dígitos.\")\n            actualizar()\n\n    else:\n        print(\"Escoger entre 'nombre' o 'número'.\")\n    \n    return 'El contacto no ha sido creado.'\n\ndef eliminar():\n    \n    posicion = 0\n    contacto_eliminar = input(\"Nombre del contacto que se va a eliminar: \")\n\n    for contacto in agenda:\n\n        if contacto['nombre'] == contacto_eliminar:\n\n            break\n\n        posicion += 1\n\n    agenda.pop(posicion)\n\n    return agenda\n\ndef buscar():\n\n    nombre = input(\"Introduce el nombre del contacto que deseas buscar: \")\n\n    for contacto in agenda:\n\n        if contacto['nombre'] == nombre:\n            return contacto\n\n\n# Menú de la agenda y parte principal.\n\nwhile exit:\n\n    menu = input(\"¿Qué desea hacer? 'agregar', 'buscar', 'actualizar', 'eliminar', 'mostrar' un contacto o 'salir': \")\n\n    if menu == 'agregar':\n\n        agregar()\n\n    elif menu == 'actualizar':\n\n        print(actualizar())\n\n\n    elif menu == 'eliminar':\n\n        print(eliminar())\n\n    elif menu == 'buscar':\n\n        print(buscar())\n    \n    elif menu == 'mostrar':\n\n        print(agenda)\n    \n    elif menu == 'salir':\n\n        exit = False\n    \n    else:\n        print(\"Debes escoger entre las opciones indicadas: 'añadir', 'buscar'...\")"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/DAVstudy.py",
    "content": "# Estructuras de datos\n\n# Listas\n\n# Crear una lista de numeros del 0 al 4\nmy_list = list(range(5))\nprint(my_list)\n\nmy_list.append(5)  # Añadir un elemento a la lista al final\nmy_list.insert(8, 0)  # Añadir elemento en la posición indexada\nprint(my_list)\n\nprint(my_list[2])  # Llama al elemento en el indice 2\n\nprint(my_list.count(0))  # Funcion para contar cuantos elementos n hay\n\nmy_list.remove(0)  # Elimina el primer elemento en la lista con ese valor\nprint(my_list)\n\nmy_list.pop()  # Devuelve y saca de la lista el ultimo elemento\nprint(my_list)\n\nmy_list.sort()  # Ordena la lista\nprint(my_list)\n\n# Tuplas\n# Crear una tupla\nmy_tuple: tuple = (\"Diego\", \"DevsDav\")\nprint(my_tuple[1])  # Acceso\nindex_devsdav = my_tuple.index(\"DevsDav\")  # Acceder al indice del argumento\nprint(index_devsdav)\nmy_tuple = tuple(sorted(my_tuple))  # Ordenación\nprint(my_tuple)\n\n# Set\nmy_set: set = {\"Diego\", \"Arenas\", \"Devsdav\", \"27\"}\nprint(my_set)\nmy_set.add(\"DAVstudy\")  # Inserción\nmy_set.add(\"DAVstudy\")\nprint(my_set)\nmy_set.remove(\"Arenas\")  # Eliminación\nprint(my_set)\n\n# Dict\nmy_dict: dict = {\n    \"name\": \"Diego\",\n    \"surname\": \"Arenas\",\n    \"alias\": \"Devsdav\",\n    \"age\": 27\n    }\nprint(my_dict)\nname = my_dict[\"name\"]  # Acceso al valor de la key \"name\"\nprint(name)\nmy_dict[\"email\"] = \"devsdav@devsdav.dev\"  # Inserción\nprint(my_dict)\nprint(my_dict.keys())  # Acceso a una lista con todas las llaves\nprint(my_dict.values())  # Acceso a una lista con todos los valores\nprint(my_dict.items())  # Acceso a una lista con tuplas de pares llave-valor\n\nmy_dict = dict(sorted(my_dict.items()))  # Ordenacion\nprint(my_dict)\ndel my_dict  # Eliminación\n\n\n\"\"\"\nEjercicio extra\n\"\"\"\n\n\ndef agenda():\n\n    agenda = {}\n\n    def insert_contact():\n\n        contact_name = input(\"Ingrese el nombre del nuevo contacto: \")\n        if contact_name in agenda:\n            print(\"Error el nombre ya existe, intente nuevamente\")\n        else:\n            phone = input(\"Ingrese el número de contacto: \")\n\n            if phone.isalnum and len(phone) < 11:\n                agenda[contact_name] = phone\n            else:\n                print(\"Error al ingresar el numero\")\n\n    def delete_contact():\n\n        contact_name = input(\"\"\"\n        Ingrese el nombre del contacto que desea eliminar:\n        \"\"\")\n        if contact_name in agenda:\n            del agenda[contact_name]\n        else:\n            print(\"Error no existe contacto con ese nombre\")\n\n    def update_contact():\n\n        option = input(\"\"\"\nPresione la opcion que desea actualizar:\n1. Actualizar nombre de contacto.\n2. Actualizar número de contacto.\n        \"\"\")\n\n        match option:\n\n            case \"1\":\n                contact_name = input(\"Ingrese el nombre actual del contacto: \")\n\n                if contact_name in agenda:\n                    new_name = input(\"Ingrese el nuevo nombre: \")\n                    agenda[new_name] = agenda[contact_name]\n                    del agenda[contact_name]\n                else:\n                    print(\"Error contacto no existe\")\n\n            case \"2\":\n                contact_name = input(\"Ingrese el nombre actual del contacto: \")\n\n                if contact_name in agenda:\n\n                    phone = input(\"Ingrese el nuevo número: \")\n\n                    if phone.isalnum and len(phone) < 11:\n                        agenda[contact_name] = phone\n                        return\n                    else:\n                        print(\"Error al ingresar el numero\")\n                        return\n\n    def search_contact():\n        contact_name = input(\"Ingrese el nombre del contacto que busca: \")\n        if contact_name in agenda:\n            print(f\"Se encontro el contacto {contact_name} y su numero es: {agenda[contact_name]}\")\n        else:\n            print(\"Error contacto no existe\")\n\n    close = False\n\n    while (not close):\n        option = input(\"\"\"\n    Presione la opcion que desea:\n    1. Ingresar nuevo contacto\n    2. Actualizar contacto\n    3. Buscar contacto\n    4. Eliminar contacto\n    5. Mostrar todos los contactos\n    6. Salir\n        \"\"\")\n\n        match option:\n\n            case \"1\":\n                insert_contact()\n            case \"2\":\n                update_contact()\n            case \"3\":\n                search_contact()\n            case \"4\":\n                delete_contact()\n            case \"5\":\n                print(agenda)\n            case \"6\":\n                close = True\n            case _:\n                continue\n\n\nagenda()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/DGrex.py",
    "content": "\"\"\"\n    EJERCICIO:\n    Muestra ejemplos de creación de todas las estructuras soportadas por defecto\n    en tu lenguaje.\n    Utiliza operaciones de inserción, borrado, actualización y ordenación.\n\"\"\"\n\n# listas\n\nmi_lista = [3,5,10,89,10,45,75,32]\n\n#Agregar un valor a la lista\nmi_lista.append(100)\nprint(\"Se agrega un valor a la lista\\n\",mi_lista)\n\n#Insertar un dato en una posicion\nmi_lista.insert(0,11)\nprint(\"\\nInsertar un dato en una posicion\\n\",mi_lista)\n\n#Actualizar dato de una posicion\nmi_lista[1]= 100\nprint(\"\\nActualizar dato de una posicion\\n\",mi_lista)\n\n#Elimina el primer valor identico encontrado\nmi_lista.remove(100)\nprint(\"\\nElimina el primer valor identico encontrado\\n\",mi_lista)\n\n#Eliminar el dato en una posicion\ndel mi_lista[4]\nprint(\"\\nEliminar el dato en una posicion\\n\",mi_lista)\n\n#Ordenar lista\nmi_lista.sort()\nprint(\"\\nOrdenar lista\\n\",mi_lista)\n\n#Lista invertida\nmi_lista.reverse()\nprint(\"\\nLista invertida\\n\",mi_lista)\n\n#Limpiar lista\nmi_lista.clear()\nprint(\"\\nLimpiar lista\\n\",mi_lista)\n\n\n#Tuplas\n\"\"\"\nAdiferencia de las lista las tuplas tienen valores constantes\nes\n\"\"\"\n\nmi_tupla = (\"Nombre\", \"Segundo nombre\", \"Apellido\", \"Apellido\", \"Segundo apellido\")\n\n#Mostrar tupla\nprint(\"\\nMostrar tupla\\n\",mi_tupla)\n\n#Mostrar el dato en una posicion\nprint(\"\\nMostrar dato en una posicion\\n\",mi_tupla[2])\n\n#Contar valores identicos\nprint(\"\\nContar valores identicos\\n\",mi_tupla.count(\"Apellido\"))\nmi_tupla.count(\"Apellido\")\n\n#Mostrar posicion de un valor\nprint(\"\\nMostrar posicion de un valor\\n\",mi_tupla.index(\"Nombre\"))\n\n\n#set\n\"\"\"\nUn set no es una estructura ordenada\n\"\"\"\n\nmi_set = {9,8,7,6,5,4,3,2,1}\n\n#Imprimir el set\nprint(\"\\nImprimir set\\n\",mi_set)\n\n#Agregar un valor\nmi_set.add(10)\nprint(\"\\nAgregar un valor\\n\",mi_set)\n\"\"\"\nEn el set no se permite los valoress repetidos\n\"\"\"\n\n#Comprovar si existe un valor en el set\nprint(\"\\nComprovar si existe un valor en el set\\n\",10 in mi_set)\n\n#Eliminar un valor\nmi_set.remove(10)\nprint(\"\\nEliminar un valor\\n\",mi_set)\n\n#Limpiar set\nmi_set.clear()\nprint(\"\\nLimpiar set\\n\",mi_set)\n\n\n#Diccionarios\n\nmy_diccionario = {\n    \"Marca\": \"Honda\",\n    \"Modelo\": \"CB1\",\n    \"Año\": 2024\n}\n\n#Imprimir diccionario\nprint(\"\\nImprimir diccionario\\n\",my_diccionario)\n\n#Actualizar el valor de una clave\nmy_diccionario[\"Año\"]= 2025\nprint(\"\\nActualizar el valor de una clave\\n\",my_diccionario)\n\n#Agregar clave y valor\nmy_diccionario[\"Color\"]= \"Celeste\"\nprint(\"\\nAgregar clave y valor\\n\",my_diccionario)\n\n#Eliminar una clave y un dato\ndel my_diccionario[\"Color\"]\nprint(\"\\nEliminar una clave y un dato\\n\",my_diccionario)\n\n\n#Encontrar una clave o un valor de la clave en el diccionario\nprint(\"\\nExiste esta clave?\")\nprint(\"Modelo\" in my_diccionario)\n\nprint(\"\\nExiste el valor en la clave?\")\nprint(\"CB1\" in my_diccionario[\"Modelo\"])\n\n\n\"\"\"\n    DIFICULTAD EXTRA (opcional):\n    Crea una agenda de contactos por terminal.\n    Debes implementar funcionalidades de búsqueda, inserción, actualización\n    y eliminación de contactos.\n    Cada contacto debe tener un nombre y un número de teléfono.\n    El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n    y a continuación los datos necesarios para llevarla a cabo.\n    El programa no puede dejar introducir números de teléfono no númericos y con más\n    de 11 dígitos (o el número de dígitos que quieras).\n    También se debe proponer una operación de finalización del programa.\n\"\"\"\n\nimport json\ncontactos = dict()\n\ndef actualizar_o_nuevo_numero(nombre):\n    condicion = True\n    while condicion :\n        numero = input(\"Numero de contacto: \")\n        if numero.isdigit() and len(numero) == 10:\n            contactos[nombre]= numero\n            condicion = False\n        else:\n            print(\"Ingrese un numero correcto\")\n\ndef nuevo_contacto():\n    nombre = input(\"Nombre del contacto: \")\n    actualizar_o_nuevo_numero(nombre)\n    \ndef actualizacion_de_contacto():\n    condicion = True\n    while condicion:\n        nombre = input(\"Nombre del contacto a actualizar: \")\n        if nombre in contactos:\n            actualizar_o_nuevo_numero(nombre)\n            condicion = False\n        else:\n            print(\"Este contacto no existe\")\n   \ndef opcion_usuario():\n    condicion = True\n    while condicion:\n        opcion = input(\"Ingrese una opcion: \")\n        if opcion.isdigit():\n            opcion = int(opcion)\n            if opcion > 0 and opcion < 7:\n                condicion = False\n                return opcion\n            else:\n                print(\"Fuera de rango\")\n        else:\n            print(\"La opccion ingresada es incorrecta\")\n\ndef buscar_contacto():\n    condicion = True\n    while condicion:\n        nombre = input(\"Nombre del contacto a buscar: \")\n        if nombre in contactos:\n            print(f\"\\nNombre: {nombre}\\nNumero: {contactos[nombre]}\")\n            condicion = False\n        else:\n            print(\"Este contacto no existe\")\n\ndef eliminar_contacto():\n    condicion = True\n    while condicion:\n        nombre = input(\"Nombre del contacto a eliminar: \")\n        if nombre in contactos:\n            del contactos[nombre]\n            condicion = False\n            print(f\"Contacto {nombre} eliminado\")\n        else:\n            print(\"Este contacto no existe\")\n\ndef imprimir_contactos():\n     print(json.dumps(contactos, indent=4))\n\ndef iniciar_programa():\n    condicion = True\n    while condicion:\n        print(f\"\\nELIGE UNA OPCION\\n\"\n            \"1. Nuevo contacto\\n\"\n            \"2. Atualizar contaco\\n\"\n            \"3. Buscar contacto\\n\"\n            \"4. Eliminar contacto\\n\"\n            \"5. Ver contactos\\n\"\n            \"6. Salir\\n\")\n        match opcion_usuario():\n            case 1:\n                nuevo_contacto()\n            case 2:\n                actualizacion_de_contacto()\n            case 3:\n                buscar_contacto()\n            case 4:\n                eliminar_contacto()\n            case 5:\n                imprimir_contactos()\n            case 6:\n                condicion = False\n                exit()\n    \n\niniciar_programa()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/DLGAI12.py",
    "content": "\"\"\"\n#03\nESTRUCTURAS DE DATOS\n/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n *   y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n *   y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más\n *   de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.\n */\n\"\"\"\n\n\n\"\"\"Listas\"\"\"\n\nprint(\"\\nLista\")\n# Creación de una lista\nlista = [1, 2, 3, 4, 5]\nprint(\"Lista original\", lista)\n\n# Inserción\nlista.append(6)  # [1, 2, 3, 4, 5, 6]\nprint(\"Insercion del 6\", lista)\n\n# Borrado\ndel lista[0]  # [2, 3, 4, 5, 6]\nprint(\"Borrado del 1\",lista)\n\n# Actualización\n\nlista[0] = 1  # [1, 3, 4, 5, 6]\nprint(\"Actualizacion del 2\", lista)\n\n# Ordenación\nlista.sort()  # [1, 3, 4, 5, 6]\nprint(\"Lista ordenada\",lista)\n\n\"\"\"Diccionarios\"\"\"\nprint(\"\\nDiccionario\")\n# Creación de un diccionario\ndiccionario = {'a': 1, 'b': 2, 'c': 3}\nprint(\"Diccionario Original\",diccionario)\n\n\n# Inserción\ndiccionario['d'] = 4  # {'a': 1, 'b': 2, 'c': 3, 'd': 4}\nprint(\"Incercion de d 4\",diccionario)\n\n# Borrado\ndel diccionario['a']  # {'b': 2, 'c': 3, 'd': 4}\nprint(\"Borrado del a\",diccionario)\n\n\n# Actualización\ndiccionario['b'] = 1  # {'b': 1, 'c': 3, 'd': 4}\nprint(\"Acutalizacion de b\",diccionario)\n\ndiccionario_ordenado = dict(sorted(diccionario.items()))\nprint(\"Diccionario Ordenado\",diccionario_ordenado)  # Output: {'a': 1, 'b': 2, 'c': 3}\n\n\"\"\" Conjuntos:\"\"\"\nprint(\"\\nConjuntos\")\n# Creación de un conjunto\nconjunto = {1, 2, 3, 4, 5}\nprint(\"Conjunto Original\",conjunto)\n\n# Inserción\nconjunto.add(6)  # {1, 2, 3, 4, 5, 6}\nprint(\"Incercion del 6\",conjunto)\n\n# Borrado\nconjunto.remove(1)  # {2, 3, 4, 5, 6}\nprint(\"Borrado del 1\",conjunto)\n\n\n\nnombres = {}\ntelefonos ={}\ncontador=0\n\n\ndef buscar():\n    nombre_buscar=input(\"Escribe el nombre a buscar:\\n\")\n    for i in nombres:\n        if nombres[i]==nombre_buscar:\n            return i\n    return -1   \n\ndef menu():\n    print(\"1.Busqueda\")\n    print(\"2.Insercion\")\n    print(\"3.Actualizacion\")\n    print(\"4.Eliminacion\")\n    print(\"5.Salir\")\n    opcion = int(input(\"Elige una opción: \"))\n    return opcion\n\nwhile True:\n    opcion=menu()\n    \n\n    if(opcion==1):\n        if(contador==0):\n            print(\"No hay registros\")\n        else:\n            posicion=buscar()\n            if(posicion!=-1):\n                    print(\"Registro encontrado:\\n\",nombres[posicion]+\"\\n\"+(str(telefonos[posicion])))\n\n            else:\n                    print(\"Registro no existe\")   \n    elif(opcion==2):    \n        nombre=input(\"Ingresa el nombre:\\n\")\n        try:\n            numero=int(input(\"Ingresa el Numero:\\n\"))\n\n        except:\n            print(\"Carater en un numero de telefono:\\n\")\n        if((len(str(numero))>11)):\n            print(\"Telefonpo mayor a lo requerido\\n\")\n\n        else:\n            nombres[contador]=nombre\n            telefonos[contador]=numero\n            contador+=1\n        print(telefonos)\n        print(nombres)\n        print()            \n    elif(opcion==3):    \n        if(contador==0):\n            print(\"No hay registros\")\n        else:\n            posicion=buscar()\n\n            if(posicion!=-1):\n                print(\"Registro encontrado:\\n\",nombres[posicion]+\"\\n\"+(str(telefonos[posicion])))\n                \n                nombres[posicion]=input(\"Escribe el nombre\\n\")\n                telefonos[posicion]=input(\"Escribe el telefono\\n\")\n\n\n            else:\n                print(\"Registro no existe\") \n\n    elif(opcion==4):    \n\n        if(contador==0):\n            print(\"No hay registros\")\n        else:\n            posicion=buscar()\n\n            if(posicion!=-1):\n                print(\"Registro Eliminado:\\n\",nombres[posicion]+\"\\n\"+(str(telefonos[posicion])))\n                contador-=1\n                nombres[posicion]=\"\"\n                telefonos[posicion]=\"\"\n\n            else:\n                print(\"Registro no existe\") \n\n\n\n\n    elif(opcion==5):    \n        print(\"Salir\")\n        break\n    else:\n        print(\"Opcion Equivocada\")\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/DaniQB99.py",
    "content": "\"\"\"\n\nEJERCICIO:\n  - Muestra ejemplos de creación de todas las estructuras soportadas por defecto\n    en tu lenguaje.\n  - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n\n\"\"\"\n\n''' LISTAS '''\n# Creación de una lista\nmi_lista = ['Daniel', 'Africa', 'Paco', 'Jhon']\nprint(mi_lista)\n\n# Inserción\nmi_lista.append('Victor')\nprint(mi_lista)\n\n# Borrado\nmi_lista.remove('Paco')\nprint(mi_lista)\n\n# Actualización\nmi_lista[0] = 'Francisco'\nprint(mi_lista)\n\n# Ordenación    \nmi_lista.sort()\nprint(mi_lista) # Ordenado alfabéticamente\n\n\n''' TUPLAS '''\n# Creación de una tupla\nmi_tupla = ('Daniel', 'Quiros', '25', 'Don Benito')\nprint(mi_tupla)\n\n# Acesso\nprint(mi_tupla[0]) # Daniel\n\n# Ordenación\nmi_tupla = tuple(sorted(mi_tupla))\nprint(mi_tupla) \n\n''' SETS '''\n# Creación de un conjunto\nmi_set = {1, 2, 3, 4, 5}\nprint(mi_set)\n\n# Acesso\n# Los sets no tienen un orden definido, \n# tendriamos que convertirlo en una lista\n\n# Inserción\nmi_set.add(6)\nmi_set.add(6)  # No se inserta un elemento repetido\nprint(mi_set)\n\n# Borrado\nmi_set.remove(3)\nprint(mi_set)\n\n# Actualización\nmi_set.update({7, 8, 9})\nprint(mi_set)\n\n# Ordenación\nmi_set = set(sorted(mi_set))\nprint(mi_set)\n\n''' DICCIONARIOS '''\n# Creación de un diccionario\nmi_diccionario = {\n    'nombre': 'Daniel', \n    'edad': 25, \n    'profesion': 'Programador'}\nprint(mi_diccionario)\n\n# Acesso\nprint(mi_diccionario['nombre']) # Daniel\n\n# Inserción\nmi_diccionario['pais'] = 'España'\nprint(mi_diccionario)\n\n# Actualización\nmi_diccionario['edad'] = 26\nprint(mi_diccionario)\n\n# Borrado\ndel mi_diccionario['edad']\nprint(mi_diccionario)\n\n# Ordenación\nmi_diccionario = dict(sorted(mi_diccionario.items())) # Ordenado alfabéticamente por items\nprint(mi_diccionario)\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n  Crea una agenda de contactos por terminal.\n  - Debes implementar funcionalidades de búsqueda, inserción, actualización\n    y eliminación de contactos.\n  - Cada contacto debe tener un nombre y un número de teléfono.\n  - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n    y a continuación los datos necesarios para llevarla a cabo.\n  - El programa no puede dejar introducir números de teléfono no númericos y con más\n    de 11 dígitos (o el número de dígitos que quieras).\n  - También se debe proponer una operación de finalización del programa.\n\n\"\"\"\n\nprint('\\n--- EJERCICIO EXTRA ---\\n')\n\ndef my_agenda():\n\n    agenda = {}\n\n    def insert_contact():\n        phone = input('Ingrese el número de teléfono del contacto: ')\n        if phone.isdigit() and len(phone) > 0 and len(phone) <= 11:\n            agenda[name] = phone\n        else:\n             print('El número de teléfono debe tener menos de 11 digitos y ser numérico.')\n\n    while True:\n\n        print('Selecciona una opción:')\n        print('    1. Buscar un contacto')\n        print('    2. Agregar un contacto')\n        print('    3. Actualizar un contacto')\n        print('    4. Eliminar un contacto')\n        print('    5. Salir')\n        \n        opcion = input('\\nOpcion: ')\n\n        match opcion:\n\n            case '1': # Buscar contacto\n                name = input('Ingrese el nombre del contacto que desea buscar: ')\n                if name in agenda:\n                    print(f'El número de telefono del contacto {name} es -> {agenda[name]}.')\n                else: \n                    print(f'El contacto {name} no existe en la agenda.')\n\n            case '2': # Agregar contacto\n                name = input('Ingrese el nombre del contacto: ')\n                insert_contact()\n\n            case '3': # Actualizar contacto\n                name = input('Ingrese el nombre del contacto a actualizar: ')\n                insert_contact()\n\n            case '4': # Eliminar contacto\n                name = input('Ingrese el nombre del contacto a eliminar: ')\n                if name in agenda:\n                    del agenda[name]\n                else: print('El contacto no existe en la agenda.')\n\n            case '5': # Salir\n                print('Saliendo del programa...')\n                break\n\n            case _: # Opcion no valida\n                print('Opcion no valida. Elige una opción válida.\\n')\n\nmy_agenda()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/DaniRojasDev.py",
    "content": "'''\nEstructuras\n'''\n# Listas se crea con []\nlist_A=[\"Dani\", \"Rojas\", \"DaniRojasDev\"]\nprint (type(list_A))\nprint(list_A)\n        # Indice\nprint(list_A[0])\nprint(list_A[1])\nprint(list_A[2])\n        #Reemplazo\nlist_A[2]=\"danirojas@gmail.com\"\nprint(list_A)\nlist_A[2]=\"DaniRojasDev\"\n        #Inserción\nlist_A.append(\"34\") # Al final de la lista\nlist_A.insert(3, \"danirojas@gmail.com\") #En la posición que le indicamos\nprint(list_A)\n        #Borrado\nlist_A.remove(\"danirojas@gmail.com\")\nprint (list_A)\n        #ordenación\nlist_A.sort()\nprint(list_A)\n\nprint (type(list_A))\n\n# Tuplas se crea con ()\ntuple_A=(\"Dani\", \"Rojas\", \"DaniRojasDev\")\nprint (type(tuple_A))\nprint (tuple_A)\n        # Indice\nprint(tuple_A[0])\nprint(tuple_A[1])\nprint(tuple_A[2])\n        #Reemplazo\n#tuple_A[2]=\"danirojas@gmail.com\"     no se puede realizar en una tupla\n\n        #Inserción\n#tuple_A.append(\"34\") # Al final de la lista    no se puede realizar en una tupla\n#tuple_A.insert(3, \"danirojas@gmail.com\") #En la posición que le indicamos       no se puede realizar en una tupla\n\n        #Borrado\n#tuple_A.remove(\"danirojas@gmail.com\")     no se puede realizar en una tupla\n\n        #ordenación\ntuple_A=(sorted(tuple_A))\nprint(tuple_A)\n\nprint (type(tuple_A))\n\n# Diccionario se crea con {} y hay que añadir \"key\":\"valor\"\ndictionary_A={\"Name\": \"Dani\", \"Surname\":\"Rojas\", \"Alias\":\"DaniRojasDev\"}\nprint (type(dictionary_A))\nprint (dictionary_A)\n        # Indice\nprint(dictionary_A[\"Name\"])   #En lugar de buscar por posición se busca por palabra clave (key)\nprint(dictionary_A[\"Surname\"])    #En lugar de buscar por posición se busca por palabra clave (key)\nprint(dictionary_A[\"Alias\"])    #En lugar de buscar por posición se busca por palabra clave (key)\n        #Reemplazo\ndictionary_A[\"Alias\"]=\"danirojas@gmail.com\"\nprint(dictionary_A)\ndictionary_A[\"Alias\"]=\"DaniRojasDev\"\n        #Inserción\ndictionary_A[\"Email\"] = \"danirojas@gmail.com\" # En orden alfabetico\nprint(dictionary_A)\n        #Borrado\ndel dictionary_A[\"Email\"]\nprint (dictionary_A)\n        #ordenación\ndictionary_A=dict(sorted(dictionary_A.items()))\nprint(dictionary_A)\n\nprint (type(dictionary_A))\n\n\n# Set da igual el orden al meter los datos porque los ordena como quiere se crea también con {}\nset_A={\"Dani\", \"Rojas\", \"DaniRojasDev\"}\nprint (type(set_A))\nprint (set_A)\n        #Inserción\nset_A.add(\"34\") \nprint(set_A)\n        #Borrado\nset_A.remove(\"34\")\nprint (set_A)\n        #ordenación\nset_A = set(sorted(set_A))  # No se puede ordenar\nprint(set_A)\n\nprint(type(set_A))\n\nprint(\" \")\nprint(\" \")\n\n'''\nExtra\n'''\nprint(\"Esta es la parte extra\")\nprint(\" \")\n\ndef agenda():\n    agenda={}\n    while True:\n    \n        print(\"\")\n        print(\"Bienvenido a la agenda ¿que quieres hacer?\")\n        print(\"\")\n        print(\"Buscar\")\n        print(\"Insertar\")\n        print(\"Actualizar\")\n        print(\"Borrar\")\n        print(\"Salir\")\n        print(\"\")\n\n        option=input (\"Selecciona una opción: \")\n\n        match option:\n                case \"Buscar\":\n                        name=input(\"Introduce el nombre del contacto que quieres buscar: \")\n                        if name in agenda:\n                            print(\"\")\n                            print(f\"El número de {name} es {agenda[name]}\")   \n                        else:\n                               print(\"\")\n                               print(\"El contacto no existe\")\n                case \"Insertar\":\n                        name=input(\"Inserte nombre del contacto: \")\n                        phone=input(\"Inserte número de telefono: \")\n                        if phone.isdigit() and len(phone)>0 and len(phone)<=11:\n                               agenda[name] = phone\n                               print(\"\")\n                               print(\"Contacto guardado.\")                             \n                        else:\n                               print(\"\")\n                               Print(\"Error, introduce un número de teléfono correcto\")\n\n                case \"Actualizar\":\n                         name=input(\"Introduce el nombre del contacto que quieres actualizar: \")\n                         if name in agenda:\n                            phone=input(\"Inserte nuevo número de telefono: \")\n                            if phone.isdigit() and len(phone)>0 and len(phone)<=11:\n                               agenda[name] = phone\n                               print(\"\")\n                               print(\"Contacto modificado.\")                             \n                            else:\n                               print(\"\")\n                               Print(\"Error, introduce un número de teléfono correcto\")  \n                         else:\n                               print(\"\")\n                               print(\"El contacto no existe\")\n                case \"Borrar\":\n                         name=input(\"Introduce el nombre del contacto que quieres borrar: \")\n                         if name in agenda:\n                            del agenda[name]\n                            print(\"\")\n                            print(\"El contacto ha sido borrado\")   \n                         else:\n                               print(\"\")\n                               print(\"El contacto no existe\")\n                case \"Salir\":\n                         print(\"\")\n                         print(\"Cerrando agenda.\")\n                         break\n                        \n                case _:\n                        print(\"\")\n                        print(\"Seleccione una opción válida\")\n\nagenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Daparradom.py",
    "content": "### Estructuras de Datos ###\n\n\nmi_list = [\"David\",\"Parrado\", 28 , False] # Lista esta compuesta por elementos ordenados, heterogeneos y mutables\n\nmi_tupla = (\"David\",\"Parrado\", 28 , False) # Compuesta por datos ordenados, heterogeneos pero no mutables\n\nmi_set = set([\"David\",\"Parrado\", 28 , False, False]) # Compuesto por datos no ordenados, heterogeneos, mutable, sin repeticion\n\nmi_dict = {\"Nombre\":\"David\", \"Apellido\" :\"Parrado\",\"Edad\":28, \"Casado\" : False} # datos No ordenados, Heterogenea , Mutable, clave : valor\n\nprint(mi_list)\n\n# Metodos y modificaciones para listas\n\nmi_list[0] = \"Alexander\" #Cambia el valor de la posicion 0 de la lista\nmi_list.append(\"Mora\") #Agrega un elemento al final de la lista\nmi_list.count(\"David\") #CUenta el numero de veces que se repite un elemento\nmi_list. index(\"Parrado\") #Devuelve el indice de la primera aparicion de un elemento\nmi_list.remove(28) #Elimina la primera aparicion de un elemento\nmi_list.insert(4,\"Azul\") #Agrega elemento en el indice dado\nmi_list.pop() #Elimina el ultimo dato de la lista y lo retorna\n#mi_list.sort() #Ordena la lista de acuerdo a parametros de ordenacion\nother_list = [6,7,2,3,5,1,9,-4]\nother_list.sort()\nprint(other_list)\nother_list.reverse() #Ordena la lista al reves\nprint(other_list)\n\n#Metodos y modificaciones para tuplas\n\nmi_tupla.count(False)\nmi_tupla.index(False)\nmi_tupla[2] #Acceso al elemento ubicado en el indice 2\n\n#Metodos y modificaciones para sets\n\nmi_set.add(10)\nmi_set.remove(False)\nmi_set.clear()\n\n#Metodos y modificaciones para diccionarios\n\nmi_dict.keys() #Devuelve una lista con las claves\nmi_dict.values() #Devuelve una lista con los valores\nmi_dict.items() # Devueleve una lista de tuplas con clave y valor\nmi_dict.pop(\"Casado\")\nprint(mi_dict)\n\ndef mis_contactos():\n    mis_contactos = {}\n    while True :\n        print (\"Bienvenido al menu de tus contactos\")\n        opcion = input(\"Escoge la opcion  que desees llevar a cabo:\\n b : Buscar contacto\\n a: Agregar contacto\\n ac : Actualizar contacto\\n e : eliminar contacto\\n S: Salir\\n\")\n        if opcion == \"a\" :\n            print (\"Usted ha seleccionado agregar contacto, el numero debe ser de diez digitos\")\n            name= input(\"Ingrese nombre del contacto nuevo: \")\n            number= input(\"Ingrese el numero: \")\n            if len(number) != 10 and type(number) != int:\n                print(\"Debe ingresar un numero tipo int de 10 digitos\")\n            else :\n                mis_contactos[name] = number\n                print(\"El contacto se ha agregado con exito\" , mis_contactos)\n        elif opcion == \"b\" :\n            print (\"Usted ha seleccionado buscar contacto\")\n            name= input(\"Ingrese nombre del contacto: \")\n            validacion = name in mis_contactos \n            if validacion == True :\n                print(f\"El numero de {name} es {mis_contactos[name]}\")\n            else :\n                print(\"El contacto no existe\")\n        elif opcion == \"ac\" :\n            print (\"Usted ha seleccionado actualizar contacto\")\n            name = input(\"Ingrese el nombre del contacto a actualizar: \")\n            validacion = name in mis_contactos \n            if validacion == True :\n                number= input(\"Ingrese numero nuevo: \")\n                mis_contactos[name] = number\n                print(\"El contacto se ha modificado con exito\" , mis_contactos)\n            else :\n                print(\"El contacto no existe\")\n        elif opcion == \"e\" :\n            print (\"Usted ha seleccionado eliminar contacto\")\n            name= input(\"Ingrese el nombre del contacto a eliminar: \")\n            validacion = name in mis_contactos \n            if validacion == True :\n                del mis_contactos[name]\n                print(\"El contacto se ha eliminado con exito\" , mis_contactos)\n            else :\n                print(\"El contacto no existe\")\n        elif opcion == \"S\":\n            print(\"Has salido de tu agenda exitosamente, a continuacion se muestra tu agenda\")\n            print(mis_contactos)\n            break\n        else : \n            print(\"No ha ingresado la opcion correctamente\")\n\n        \n\n\n\n\nmis_contactos()\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/DataCiriano.py",
    "content": "\"\"\"\n* EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n\"\"\"\n\n#-------Strings-------\n\n#Creación de una cadena de una sola línea o de varias\ncadena_caracteres = \"Hola Mundo!!\"\nprint(cadena_caracteres)\n\ncadena_varias_lineas = '''Esto es una cadena de caracteres de varias líneas.\nEs igual a un string de una sola línea, pero se deben poner 3 comillas para \nser creada'''\nprint(cadena_varias_lineas)\n\n#Concatenación de cadenas\ncadena_unida = cadena_caracteres + cadena_varias_lineas\nprint(cadena_unida)\n\n#Formateo de de cadenas\nlenguaje = \"Python\"\nversion = \"3.11.4\"\nprint(f\"Estoy utilizando el lenguake de programación {lenguaje} en la versión {version}\")\n\n#Slicing de cadenas\nprimera_palabra = cadena_varias_lineas[0:4]\nprint(primera_palabra)\n\nultima_palabra = cadena_varias_lineas[-6:]\nprint(ultima_palabra)\n\n#Revertir una cadena\ncadena_invertida = cadena_varias_lineas[::-1]\nprint(cadena_invertida)\n\n#Capitalize \ncadena_mayusculas = cadena_varias_lineas.upper()\nprint(cadena_mayusculas)\n\n#Lower\ncadena_minusculas = cadena_mayusculas.lower()\nprint(cadena_minusculas)\n\n#Eliminar espacios al principio y fianl de unade una cadena\neliminar_espacios = cadena_varias_lineas.lstrip().rstrip()\nprint(f\"Cadena sin espacios {eliminar_espacios}\")\n\n#Algunos métodos de cadenas\nconteo_y = cadena_varias_lineas.count('e')\nprint(f\"Hay {conteo_y} 'y' en la cadena\")\n\nencontrar_a = cadena_varias_lineas.find('a')\nprint(f\"La primera a está en la possición: {encontrar_a}\")\n\nencontrar_ultima_a = cadena_varias_lineas.rfind('a')\nprint(f\"La última 'a' está en la posición {encontrar_ultima_a}\")\n\nempieza_con = cadena_varias_lineas.startswith('A')\nprint(f\"La cadena empiea con 'A': {empieza_con}\")\n\nacaba_con = cadena_varias_lineas.endswith('da')\nprint(f\"La cadena acaba con 'da': {acaba_con}\")\n\nreemplazar = cadena_varias_lineas.replace('e', 'u')\nprint(reemplazar)\n\n#-------Listas-------\n\n#Creación de una lista\nmi_lista = [0,5,3,2,1,4]\nprint(mi_lista)\n\n#Otra forma de crear una lista\nmi_lista_2 = list([\"Hola\", \"Adios\"])\nprint(mi_lista_2)\n\n#Inserción de un elemento mediante el método append()\nmi_lista.append(6)\nprint(f\"Lista método append(): {mi_lista}\")\n\n#Inserción de un elemento mediante el método insert()\nmi_lista.insert(0, \"Hola\")\nprint(f\"Lista método inster(): {mi_lista}\")\n\n#Ampliación de de una lista mediante otra con el método extend()\nmi_lista.extend(mi_lista_2)\nprint(f\"Lista método externd(): {mi_lista}\")\n\n#Borrado de un elemento mediante el método remove()\nmi_lista.remove(\"Adios\")\nprint(f\"Lista método remove(): {mi_lista}\")\n\n#Borrado de un elemento mediante el método pop() (elimina el último elemento)\nmi_lista.pop()\nprint(f\"Lista método pop() {mi_lista}\")\n\n#Borrado de un elemento mediante el método del\ndel mi_lista[0]\nprint(f\"Lista método del: {mi_lista}\")\n\n#Borrado de todos los elementos mediante el clear()\nmi_lista_2.clear()\nprint(f\"Lista vacía con el método clear(): {mi_lista_2}\")\n\n#Ordenación de una lista con el método sort()\nmi_lista.sort(reverse=True)\nprint(f\"Lista ordenada de mayor a menor con el método sort(): {mi_lista}\")\n\n#Ordenación de una lista con el método sorted() y una función\nlista_frutas = [\"manzana\", \"pera\", \"plátano\", \"melocotón\", \"fresa\"]\n\ndef longitud_elementos(elemento):\n    return len(elemento)\n\nlista_ordenada = sorted(lista_frutas, key=longitud_elementos)\nprint(lista_ordenada)\n\n\n#-------Tuplas-------\n\n#Creación de una tupla\nanimales = (\"gato\", \"perro\", \"caballo\", \"vaca\", \"cabra\", \"conejo\")\nprint(animales)\n\n#Otra forma de crear una tupla\nmi_tupla2 = tuple([1,2,3,4,5])\nprint(mi_tupla2)\n\n#Unión de dos tuplas\nunion_tuplas = animales + mi_tupla2\nprint(f\"Unión de las tuplas: {union_tuplas}\")\n\n#Comprobar si un elemento está en la tupla\nprint(\"caballo\" in animales)\n\n#Borrado de una tupla\ndel animales\n\n#Al ser inmutables, las tuplas no se pueden alterar ni ordenar, por lo que solo podemos crearlas y borraralas.\n\n\n#-------Sets-------\n\n#Creación de un set\ntransportes = {\"coche\", \"moto\", \"autobús\", \"tren\", \"avión\"}\nprint(transportes)\n\n#Otro forma de crear un set\ndeportes = set([\"fútbol\", \"baloncesto\", \"atletismo\"])\nprint(deportes)\n\n#Añadir un elemento a un set con el método add()\ndeportes.add(\"balonmano\")\nprint(deportes)\n\n#Añadir varios elementos a un set con el método update()\ndeportes.update([\"escalada\", \"natación\", \"tenis\"])\nprint(deportes)\n\n#Comprobar si son subsets o supersets\nset1 = {1,2,3,4,5}\nset2 = {2,4,5}\nprint(f\"Set1 es superset de set2: {set1.issuperset(set2)}\")\nprint(f\"Set2 es subset de Set1: {set2.issubset(set1)}\")\n\n#Comprobar elemntos comunes entre sets\nprint(f\"La itersección entre set2 y set1 es: {set2.intersection(set1)}\")\n\nprint(f\"set1 y set2 no tienen elementos comunes: {set1.isdisjoint(set2)}\")\n\n#Eliminar un elemento de un set con el método remove()\ntransportes.remove(\"avión\")\nprint(transportes)\n\n#Eliminar todos los elementos de un set con el método clear()\ntransportes.clear()\nprint(transportes)\n\n#Eliminar un set con el método del\ndel transportes\n\n\n#-------Diccionarios-------\n\n#Crear un diccionario\ndict_paises = {\n   \"España\": \"Madrid\",\n   \"Francia\": \"París\",\n   \"Alemania\": \"Berlín\",\n   \"Italia\": \"Roma\",\n   \"Reino Unido\": \"Londres\"\n}\nprint(dict_paises)\n\n#Añadir una nueva clave y un valor al diccionario\ndict_paises[\"Rusia\"] = \"Moscú\"\nprint(dict_paises)\n\n#Modificar un valor de un diccionario\ndict_paises[\"España\"] = \"Barcelona\"\nprint(dict_paises)\n\n#Obtener un valor de un diccionario y pasar un valor si este no existe\ncapital_dict = dict_paises.get(\"Reino Unido\")\nprint(f\"La capital de Reino Unido es: {capital_dict}\")\n\ncapital = dict_paises.get(\"Bélgica\", \"Bruselas\")\nprint(f\"La capital de Bélgia es: {capital}\")\n\n#Comprobar si una clave está en un diccionario\nprint(f\"Francia está en el diccionario: {'Francia' in dict_paises}\")\n\n#Eliminar el último elemento del diccionario\ndict_paises.popitem()\nprint(dict_paises)\n\n#Eliminar un elemento en concreto de un diccionario\ndict_paises.pop('Alemania')\nprint(dict_paises)\n\n#Obtener las claves de un diccionario como una lista\nclaves = dict_paises.keys()\nprint(f\"Las claves del diccionario son: {claves}\")\n\n#Obtner los valores de un diccionario como una lista\nvalores = dict_paises.values()\nprint(f\"Los valores del diccionario son: {valores}\")\n\n#Eliminar todos los elementos del diccionario con el método clear()\ndict_paises.clear()\nprint(f\"El diccionario ahora sta vacío: {dict_paises}\")\n\n#Eliminar el diccionario con el método del\ndel dict_paises\n\n\n\n#-------EXTRA-------\n\ndef agenda():\n    dict_agenda = {\"Bomberos\": '1234', \"Policia\": '091', \"Emergencias\": '112'}\n\n    while True:\n        def menu():\n            print(\"\"\"Accediendo a la agenda de contactos...\\n\n                Elija una opción por favor:\n                -------------------------------------------\n                Opcion 1: Nuevo contacto \n                Opción 2: Busqueda de un contacto existente\n                Opción 3: Editar contacto existente\n                Opcion 4: Eliminar un contacto existente\n                Opcion 5: Salir\\n\"\"\")\n            return int(input(\"Indique una opción: \"))\n\n        opcion = menu()\n\n        if opcion == 1:\n            agregar_contacto(dict_agenda)\n\n        elif opcion == 2:\n            buscar_contacto(dict_agenda)\n\n        elif opcion == 3:\n            editar_contacto(dict_agenda)\n\n        elif opcion == 4:\n            eliminar_contacto(dict_agenda)\n\n        elif opcion == 5:\n            print(\"¡Gracias por usar nuestra agenda! ¡Hasta luego!\")\n            break\n\n\ndef agregar_contacto(diccionario):\n    nombre = input(\"Introduzca el nombre del nuevo contacto: \").lower().capitalize()\n    telefono = input(\"Introduzca un número de teléfono de máximo 11 dígitos: \")\n    \n    while not (telefono.isdecimal() and len(telefono) <= 11):\n        telefono = input(\"Número de teléfono inválido. Vuelva a intentarlo: \")\n        \n    diccionario[nombre] = telefono\n    print(f\"¡Contacto {nombre} añadido correctamente!\\n\")\n    imprimir_contactos(diccionario)\n\n\ndef buscar_contacto(diccionario):\n    print(\"-----Buscador de contactos-----\")\n    contacto = input(\"Introduzca el nombre del contacto: \").lower().capitalize()\n\n    if contacto in diccionario:\n        print(f\"{contacto}: {diccionario[contacto]}\\n\")\n    else:\n        respuesta = input(\"No hay ningún contacto en la agenda con ese nombre. ¿Desea realizar otra acción? Y/N \").lower()\n        if respuesta != 'y':\n            print(\"¡Gracias por usar nuestra agenda! ¡Hasta luego!\")\n\n\ndef editar_contacto(diccionario):\n    print(\"-----Editor de contactos-----\")\n    imprimir_contactos(diccionario)\n    contacto = input(\"Indique el nombre del que desea editar: \").lower().capitalize()\n\n    if contacto in diccionario:\n        respuesta = input(\"¿Desea editar el nombre del contacto (1) o el número (2)? : \")\n        if respuesta == '1':\n            nuevo_nombre = input(\"Introduzca el nuevo nombre de contacto: \").lower().capitalize()\n            diccionario[nuevo_nombre] = diccionario.pop(contacto)\n        elif respuesta == '2':\n            nuevo_numero = input(\"Introduzca el nuevo número de teléfono: \")\n            while not (nuevo_numero.isdecimal() and len(nuevo_numero) <= 11):\n                nuevo_numero = input(\"Número de teléfono inválido. Vuelva a intentarlo: \")\n            diccionario[contacto] = nuevo_numero\n        print(\"Contacto editado correctamente.\\n\")\n        imprimir_contactos(diccionario)\n    else:\n        print(\"No hay ningún contacto en la agenda con ese nombre.\\n\")\n\n\ndef eliminar_contacto(diccionario):\n    print(\"-----Eliminar un contacto-----\")\n    imprimir_contactos(diccionario)\n    contacto = input(\"¿Qué contacto desea eliminar? \").lower().capitalize()\n\n    if contacto in diccionario:\n        valor_eliminado = diccionario.pop(contacto)\n        print(f\"Se eliminó el contacto {contacto} con el valor {valor_eliminado}\\n\")\n        imprimir_contactos(diccionario)\n    else:\n        print(\"No hay ningún contacto en la agenda con ese nombre.\\n\")\n\n\ndef imprimir_contactos(diccionario):\n    print(\"Estos son los contactos almacenados en la agenda:\")\n    for nombre, telefono in diccionario.items():\n        print(f\"{nombre}: {telefono}\")\n    print()\n\n\nagenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/DevKnn.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto\n *   en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n \n */\"\"\"\n \n # Para lista \nx = []\nx.append(8) #Agregar elemento a lista\nx.append(1)\nx.append(2)\nx.append(3)\nx.remove(1) # Eliminar ellemento de la lista\nx.sort() #Ordenar lista\nx.insert(1, 88) # insertar elemento segun su posicion\nx.reverse() #El reverso de la lista\nx.pop() #Eliminar el ultimo elemento de la lista \nx.clear() #Vaciar lista\ndel x #Borrar lista por completo\nx=\"hola\"\nprint(x)\n\n#Para diccionario\nx = {}\nx[\"Pais\"]= \"Venezuela\" # Agreando elemento a la lista\nx[\"Ciudad\"]= \"Maturin\" \ny=x.values() #Muestra el valor de la lista \ny=x.keys() #Muesta la clave del diccionario\nprint(x)\nprint(y)\n\n#Para set\nx = {4,4,4,5,6,7,8,9,10}\nx.discard(10) # Elimina elemento del set\nx.add(60) #agregar elelmento al set\nprint(x)\n\n#Par tupla \nx = ()\nx= (4,5,6,7,8,9,10) #mutable\ny = x.count(4) #conteo del elemento indicado\nprint(y)\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n *   y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n *   y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más\n *   de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.\n \"\"\"\n \n \ndef myAgenda():\n    agenda = {}\n\n    def numeroTelefono():\n        ingreseNumero = input(\"Ingrese su numero telefonico: \")\n        if ingreseNumero.isdigit() and len(ingreseNumero) == 11:\n            agenda[nombre] = numeroTelefono\n            return ingreseNumero\n        else:\n            print(\"Tienes que ingresar 11 digitos\")\n        return numeroTelefono()\n    \n    print(\"\"\"\n          BIENVENIDO A MI AGENDA TELEFONICA\n          Ingrese una opcion:\n          1) Agregar contacto\n          2) Actualizar contacto\n          3) Buscar contacto\n          4) elimar contacto\n          7) Salir de la agenda\n          \"\"\")\n    while True:\n        opcion = int(input(\"Ingrese una opcion: \"))\n        match opcion:\n            case 1:\n                nombre = input(\"Ingrese el nombre del contacto: \")\n                agenda[nombre] = numeroTelefono()\n                print(agenda)\n                print(f\"El contacto {nombre} a sido agregado exitosamente.\")\n            case 2:\n                nombre = input(\"Ingrese el nombre del contacto a actualizar: \")\n                if nombre in agenda:\n                    agenda[nombre]= numeroTelefono()\n                    print(agenda)\n                    print(f\"El contacto {nombre} a sido actualizado exitosamente.\")\n                else:\n                    print(\"El contacto no existe.\")\n            case 3:\n                nombre = input(\"Ingrese el nombre del contacto a buscar: \")\n                if nombre in agenda:\n                    for i,y in agenda.items():\n                        print(i,y)\n                        print(\"La Busqueda fue extiosa\")\n                else:\n                    print(f\"Usuario {nombre} no existe.\")\n            case 4:\n                nombre = input(\"Ingrese el nombre del contacto a eliminar: \")\n                if nombre in agenda:\n                    del agenda[nombre]\n                    print(f\"El contacto {nombre} se ha eliminado exitosamente.\")\n                else:\n                    print(f\"El usuario {nombre} a eliminar no fue encontado\") \n            case 7:\n                print(\"Saliendo de la agenda. Hasta Pronto\")\n                break       \n    return myAgenda\n            \n\nmyAgenda()\n     "
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/DiegoIBB.py",
    "content": "'''\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n'''\n\n#Python tiene 4 estructuras de almacenamiento de datos, estas son las listas, tuplas, set(conjuntos) y diccionarios\n\n#------- LISTAS -------\n\n'''\nLas listas son un tipo de conjunto de datos que pueden ser\nordenados, modificados y permite tener elementos duplicados\n\n'''\n\nlista_1 = [1, 2, 3, 4, 5, 6, 7] #Esto es una lista\nlista_2 = [\"Hola\", 34, 'D', True, 7.0]\nlista_3 = [\"Auto\", \"Tren\", \"Barco\", \"Avion\"]\n\nn_item_l1 = 0\nprint(\"---- Elementos lista 3 ----\")\n\nfor l1 in lista_1:\n    print(f\"Elemento {n_item_l1}: {l1}\")\n    n_item_l1 += 1\n\nn_item_l2 = 0\nprint(\"---- Elementos lista 3 ----\")\n\nfor l2 in lista_2:\n    print(f\"Elemento {n_item_l2}: {l2}\")\n    n_item_l2 += 1\n\nn_item_l3 = 0\nprint(\"---- Elementos lista 3 ----\")\n\nfor l3 in lista_3:\n    print(f\"Elemento {n_item_l3}: {l3}\")\n    n_item_l3 += 1\n\n# -------- Operaciones de inserción, borrado, actualización y ordenación --------\n\n# append() --> Agregar elementos\nlista_1.append(8)\nprint(f\"Usando comando .append añadimos 8 a lista_1: {lista_1}\")\n\n#remove() --> Remover elementos\nlista_2.remove(\"Hola\")\nprint(f\"Usando comando .remove quitamos 'Hola' de lista_2: {lista_2}\")\n\n#pop() --> Eliminar el ultimo elemento\nlista_3.pop()\nprint(f\"Usando comando .pop quitamos el ultimo elemento de lista_3: {lista_3}\")\n\n#reverse() --> Invertir el orden\nlista_1.reverse()\nprint(f\"Usando comando .reverse invertimos el orden de lista_3: {lista_1}\")\n\n#sort() --> Ordenar en de manera ascendente\nlista_3.sort()\nprint(f\"Usando comando .sort ordenamos lista_3 en orden ascendente(alfabetico): {lista_3}\")\n\n#insert() --> Añade un elemento en una determinada posición\nlista_2.insert(5, \"Amigo\")\nprint(f\"Usando comando .insert añadimos un elemento en una determinada posición de lista_2: {lista_2}\")\n\n#count() --> Revisa cuantas veces se repite un determinado item dentro de la lista\nconteo = lista_1.count(4)\nprint(f\"Usando comando .count obentemos la cantidad 4s que contiene lista_1: {conteo}\")\n\n#extend() --> Extiende una lista a partir de otra (une 2 listas)\nlista_2.extend(lista_3)\nprint(f\"Usando comando .extend agregamos los elementos de lista_3 a lista_2 (imprimimos la lista a la que se le agregaron): {lista_2}\") \n\n\n#------- TUPLAS -------\n'''\nLas tuplas son vaiable que pueden almacenar diferentes valores,\na diferencia de las listas sus valores son inmutables (no se pueden\no agregar nuevo valores).\n'''\n\ntupla_1 = (\"Ivan\", \"Sebastian\", \"Dante\", \"Benjamin\", \"Diego\") #Esta es una tupla con un solo tipo de dato\ntupla_2 = (\"Hola\", 3, True, 4.5, 'S') #Esto es una tupla con diferentes tipos de datos\ntupla_3 = (1, 2, 3, 4, 5, 6, 7)\n\nn_item = -1\nprint(\"---- Tupla 1 ----\")\nfor t1 in tupla_1:\n    n_item += 1\n    print(f\"Elemento de tupla {n_item} = {t1}\")\n\nprint(\"---- Tupla 2 ----\")\nfor t2 in tupla_2:\n    n_item += 1\n    print(f\"Elemento de tupla {n_item} = {t2}\")\n\n# -------- Formas de acceder a una tupla --------\n\nprint(f\"Elemento de la tupla 1, posición 0: {tupla_1[0]}\") #Acceder a un elemento de una tupla es por medio del indice\nprint(f\"Elemento de la tupla 1, posición 4: {tupla_1[-1]}\") #Acceder a un elemento de una tupla hacia atras (ultimo elemento)\nprint(f\"Elemento de la tupla 2, posición 2 a 4: {tupla_2[2:5]}\") #Acceder a un rango de elementos de la tupla (2 al 4)\nprint(f\"Elemento de la tupla 2, posición 0 a 2: {tupla_2[:2]}\") #Acceder a un rango de elementos desde la primera posición hasta n (0:2)\nprint(f\"Elemento de la tupla 3, posición 3 a 0: {tupla_3[3:]}\") #Acceder a un rango de elementos desde la ultima posición hasta n (3:)\n\n# -------- Revisar si hay elementos en tuplas --------\n\nif 4 in tupla_3:\n    print(\"4 está en la tupla\")\nelse:\n    print(\"4 no está en la tupla\")\n\n\n# -------- Operaciones de inserción, borrado, actualización y ordenación --------\n    \ni = tupla_3.count(5) #count(): Retorna el número de veces un valor especifico de una tupla\nprint(f\"El elemento 5 está {i} veces\")\n\nf = len(tupla_3) #len(): Retorna el largo de una tupla\nprint(f\"El largo de la tupla es {f}\")\n\nr = tupla_1.index(\"Sebastian\")\nprint(f\"La posición de Sebastian en la tupla es {r}\")\n\n'''\n---- Operaciónes que NO están permitidas en las tuplas ----\n- append() --> Agregar elementos\n- remove() --> Remover elementos\n- pop() --> Eliminar el ultimo elemento\n- reverse() --> Invertir el orden\n- sort() --> Ordenar en de manera ascendente\n- insert() --> Añade un elemento en una determinada posición\n'''\n\n \n#------- CONJUNTOS(SET) -------\n\n'''\nLos sets son conjuntos de datos no ordenados, inmutables y sin\nvalores duplicados, además no se sabe en que orden aparecen al\nimprimirse (toman posiciones aleatorias).\n\nLos items de un set no pueden cambiarse despues de que han sido\ncreados, pero si se pueden añadir y remover items, además, los\nset pueden tener valores de diferentes tipos.\n'''\n\nset_1 = {\"apple\", \"bananna\", \"carrot\", \"lemon\", \"pinapple\", \"watermelon\"}\nset_2 = {1, 2, 3, 4, 5, 6, 7}\nset_3 = {\"hola\", 3, 5.7, True, 'D', False}\n\n#Los items aparecen en orden diferente a los que tenian al crear el set\n\nprint(\"---- Elementos Set 1 ----\")\nn_itemSet_1 = 0\nfor e in set_1:\n    print(f\"Elemento posición {n_itemSet_1}: {e}\")\n    n_itemSet_1 += 1\n\nprint(\"---- Elementos Set 2 ----\")\nn_itemSet_2 = 0\nfor e in set_2:\n    print(f\"Elemento posición {n_itemSet_2}: {e}\")\n    n_itemSet_2 += 1\n\nprint(\"---- Elementos Set 3 ----\")\nn_itemSet_3 = 0\nfor e in set_3:\n    print(f\"Elemento posición {n_itemSet_3}: {e}\")\n    n_itemSet_3 += 1\n\n# -------- Formas de acceder a un set --------\n\n'''\nLas formas de acceder a un item dentro de un set es iterando sobre el\ncon un bucle for o bien consultando directamente si está dentro del set.\n'''\n\nprint(\"pinapple\" in set_1)\nprint(10 in set_2)\nprint(3 in set_3) #En los sets, se toma al valor 1 como True, al 0 como False y viceversa\n\n# -------- Operaciones de inserción, borrado, actualización y ordenación --------\n\n#Para añadir un elemento al set utilizamos el método ADD()\nset_1.add(\"Blueberry\")\nprint(set_1)\n\n#Para combinar sets utilizamos el método UPDATE()\nset_4 = {\"Potatoe\", \"Tomatoe\", \"Lettuce\", \"Onion\"} #En este caso el set_2 recibe los items del set_4, al imprimir el set_2 se visualizan los nuevos datos\nset_1.update(set_4)\nprint(set_1)\n\n#Para remover elementos de un set utilizamos el método REMOVE()\nset_3.remove(5.7)\nprint(set_3)\n\n#Para remover un elemento del set utilizamos el método POP() (este método remueve un elemento random del set)\nset_4.pop(\"Onion\")\nprint(set_4)\n\n'''\nTambien se pueden ver otros tipos de métodos:\n\n- clear() -> Elimina todos los elementos de un set\n- copy() -> Copia un set\n- difference() -> Retorna un set que contiene la diferencia entre 2 o más sets\n- discard() -> Remueve un elemento especifico\n- intersection() -> Retorna un set que es la intersección de los otros sets\n''' \n\n\n#------- DICCIONARIOS -------\n'''\nDiccionarios son usados para guardar datos en parejas clave:valor.\nUn diccionario es una colección la cual está ordenada, es mutable y admite\nelementos duplicados.\n'''\ndictionary_1 = {\n    \"Brand\": \"Ford\",\n    \"Model\": \"Mustang\",\n    \"Year\": 1964\n}\nprint(dictionary_1)\n\n#Se puede referenciar un elemento del diccinario por medio de clave entre corchetes\nprint(dictionary_1[\"Model\"])\n\n#Los diccionarios pueden guardar varios tipos de datos\n\ndictionary_2 = {\n    \"boolean\": True,\n    \"String\": \"hola\",\n    \"Integger\": 25,\n    \"Float\": 7.5,\n    \"List\": [1, 2, 3, 4, 5]\n}\nprint(dictionary_2)\n\n#Podemos usar un método especial para construir diccionarios\nvalor_1 = 0\nvalor_2 = 0\nvalor_3 = 0\n\ndictionary_3 = dict(valor_1 = 23, valor_2 = 43, valor_3 = 65)\nprint(dictionary_3)\n\n# -------- Formas de acceder a un diccionario --------\n\n'''\nPodemos usar 2 métodos particulares, llamar al elemento a partir de su clave\no bien usar el método \"get()\". Tambien podemos usar el método \"keys()\" para obtener una lista\nde todas las claves del diccionario. Por otro lado, se pueden obtener los valores del diccionario\nusando el metodo \"values()\", además podemos imprimir las parejas \"clave:valor\" en forma de tupla.\nFinalmente, podemos revisar si una clave en particular está dentro del diccionario.\n'''\n\n#Usando la clave\nitem_1 = dictionary_2[\"List\"]\nprint(item_1)\n\n#Usando get\nitem_2 = dictionary_2.get(\"String\")\nprint(item_2)\n\n#Consiguiendo las claves del diccionario\nitem_3 = dictionary_1.keys()\nprint(item_3)\n\n#Consiguiendo los valores del diccionario\nitem_4 = dictionary_1.values()\nprint(item_4)\n\n#Consiguiendo las parejas del diccionario en forma de tupla\nitem_5 = dictionary_3.items()\nprint(item_5)\n\n#Tanto en Keys, Values e Items no se reflejan los cambios en el diccionario solo los valores que tiene registrados hasta el momento que se le llame\n\n#Revisando si una clave está en el diccionario\nif \"valor_4\" in dictionary_3:\n    print(\"Valor 4 está en el diccionario 3\")\nelse:\n    print(\"El valor 4 no está en el diccionario 3\")\n\n# -------- Operaciones de inserción, borrado, actualización y ordenación --------\n\n#Ya se vieron get(), keys(), values() e items()\n\n#El método POP elimina un elemento del diccionario, para ello se debe acceder por medio de su clave\ndictionary_1.pop(\"Brand\")\nprint(dictionary_1)\n\n#El método POP ITEM elimina la ultima pareja clave-valor del diccionario\ndictionary_2.popitem()\nprint(dictionary_2)\n\n#El método UPDATE inserta un valor especifico en el diccionario\ndictionary_3.update(valor_4 = 74)\nprint(dictionary_3)\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n\"\"\"\n\ndef updateInfo(name, number): #Recibimos el nombre y número actual del usuario\n    print(\"----- Item to Update -----\")\n    print(\"1) Update Name - 2) Update Number\")\n    itemUpdate = int(input(\"Selec item: \"))\n    if itemUpdate == 1:\n        newName = input(\"New Name contact: \")\n        contacts.pop(name)\n        contacts[newName] = number\n    elif itemUpdate == 2:\n        newNumber = input(\"New number contact: \")\n        contacts[name] = newNumber\n    else:\n        print(\"The option is not allowed\")\n    return contacts #Eventualmente el diccionario podría retornar los valores 2 en forma de lista o tupla y no todo el diccionario\n\n# Construcción del programa\ncontacts = {}\nwhile True:\n    print(\"--- Functions Available ---\")\n    print(\"1. Insertion\")\n    print(\"2. Update\")\n    print(\"3. Delete\")\n    print(\"4. Search Contact\")\n    funcSelected = int(input(\"Selec a function: \"))\n\n    if funcSelected == 1: #---------- Añadir contactos ---------\n        print(\"--- Add a new Contact ---\")\n        contactName = input(\"New Contact: \")\n        while True:\n            contactNumber = input(\"Contact Number: \")\n            if len(contactNumber) < 11:\n                contacts[contactName] = contactNumber\n                break\n            else:\n                print(\"Number excess the limit, try again\")\n    elif funcSelected == 2: #---------- Editar contactos ---------\n        print(\"--- Update a Contact ---\")\n        print(contacts) #Se imprimen los nombres contactos para ver los datos a cambiar\n        selecUser = input(\"Contact: \")\n        info_update = updateInfo(selecUser, contacts[selecUser])\n    elif funcSelected == 3: #---------- Eliminar contactos ---------\n        print(\"--- Delete a Contact ---\")\n        print(contacts)\n        userToDelete = input(\"User to Delete: \")\n        contacts.pop(userToDelete)\n    elif funcSelected == 4:\n        print(\"--- Search Contact ---\")\n        searchContact = input(\"Contact Name: \")\n        if searchContact in contacts:\n            print(f\"The contact {searchContact} exists\")\n        else:\n            print(f\"The contact {searchContact} dosen't exist\")\n    else:\n        print(\"The number is not an option allowed\")\n    # Consultamos si desea seguir realizando operaciones\n    wishContinue = input(\"Another operation (yes/no)?: \")\n    if wishContinue == \"no\":\n        print(\"Program Ended\")\n        print(contacts)\n        break\n    else:\n        continue\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Dkp-Dev.py",
    "content": "\"\"\"\nEJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto\n *   en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n \"\"\"\n\n# Listas\n\nlista: list = [\"Perro\",\"Gato\",\"Conejo\",\"Tortuga\"]     # Es una lista definida por []\nprint(type(lista))\nprint(lista)\n\nlista.append(\"Cuervo\")  # Insercion\nprint(lista)\n\nlista.remove(\"Gato\")    # Eliminacion\nprint(lista)\n\nprint(lista[2])         # Acceso\n\nlista[2] = \"Serpiente\"  # Modificacion en posicion\nprint(lista)\n\nlista.sort()            # Orden alfabetico por defecto\nprint(lista)\n\n# Tuplas son listas inmutables\n\ntupla = (\"Numeros\",\"Letras\",\"Simbolos\")         # Es una tupla definida por () a diferencia de la lista []\nprint(type(tupla))\nprint(tupla)\n\nprint(tupla[2])         # Acceso unicamente\nprint(tupla[0])\n\ntupla = tuple(sorted(tupla))    # Ordenar una tupla consiste en crear una lista a partir de la tupla, ordenarla y transformarla a tupla nuevamente\nprint(type(tupla))\nprint(tupla)\n\n# Sets son basicamente listas desordenadas con el proposito de ser \"eficientes\" y no permite datos duplicados\n\nsett: set = {\"Cuadrado\",\"Circulo\",\"Rectangulo\",\"Triangulo\"}\nprint(type(sett))\nprint(sett)\n\nsett.add(\"Ovalo\")            # Insercion\nsett.add(\"Cuadrado\")         # Aunque se inserte nuevamente un dato, el sistema no lo tomara en cuenta\nprint(sett)\n\nsett.remove(\"Rectangulo\")    # Eliminacion\nprint(sett)                  # La unica forma de \"modificar\" es mediante la insercion y eliminacion de dato\n\nsett = set(sorted(sett))     # No se puede ordenar, se puede convertir a lista y entonces ordenar\nprint(type(sett))\nprint(sett)\n\n# Diccionario se crea con {} pero aqui se asignan claves:valores\n\nmi_dict: dict = {\n    \"Canino\": \"Perro\",      \n    \"Canino\": \"Lobo\",           # Lobo termina borrando a Perro\n    \"Felino\": \"Gato\",\n    \"Roedor\": \"Conejo\"\n}\nprint(type(mi_dict))\nprint(mi_dict)\n\nmi_dict[\"Ave\"] = \"Cotorro\"      # Insercion\nprint(mi_dict)\n\nprint(mi_dict[\"Felino\"])        # Acceso mediante claves\n\nmi_dict[\"Roedor\"] = \"Liebre\"    # Modificacion mediante insercion\nprint(mi_dict)\n\ndel mi_dict[\"Felino\"]           # Eliminacion\nprint(mi_dict)\n\nmi_dict = dict(sorted(mi_dict.items()))     # Ordenar mediante items, cambia a lista y termina en dict, pero ordena las claves\nprint(type(mi_dict))\nprint(mi_dict)\n\n\"\"\"\n DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n *   y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n *   y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más\n *   de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.\n\"\"\"\n\n# Como la agenda en si misma es una funcion entonces desde el inicio se crea.\n\n\ndef mi_agenda():\n\n    agenda = {}     # Esta es la agenda como tal\n    def up_numero():        # Esta es la funcion para añadir/modificar un contacto\n        numero = input(\"Introduce numero de contacto:\")\n        if numero.isdigit() and len(numero) > 0 and len(numero) <= 10:\n            agenda[name] = numero\n            print(\"Contacto añadido.\")\n        else:\n            print(\"Solo se aceptan numeros de hasta 10 digitos.\")\n    \n    while True:     # De esta manera se mantiene la funcion en bucle\n\n        # Se inicia imprimiendo el menu\n\n        print(\"\")\n        print(\"1 - Buscar contacto\")\n        print(\"2 - Agregar Contacto\")\n        print(\"3 - Actualizar contacto\")\n        print(\"4 - Eliminar contactos\")\n        print(\"5 - Salir\")\n        print(\"6 - Ver agenda\")\n\n        option = input(\"Elige la opcion deseada:\")      # Input se utiliza para poder interactuar con terminal\n\n        match option:       # Se puede usar if, elif y else, pero en python existe match\n            case \"1\":\n                name = input(\"Introduce el nombre de contacto:\")\n                if name in agenda:\n                    print(\n                        f\"El numero de {name} es {agenda[name]}\")\n                else:\n                    print(f\"El nombre {name} no existe en la agenda.\")\n            case \"2\":\n                name = input(\"Introduce nombre de contacto:\")\n                up_numero()\n            case \"3\":\n                name = input(\"Introduce el nombre de contacto que desea actualizar:\")\n                if name in agenda:\n                    up_numero()\n                else:\n                    print(f\"El nombre {name} no existe en la agenda.\")\n\n            case \"4\":\n                name = input(\"Introduce el nombre de contacto que desea eliminar:\")\n                if name in agenda:\n                    del agenda[name]\n                    print(\"El contacto se ha borrado.\")\n                else:\n                    print(f\"El nombre {name} no existe en la agenda.\")\n            case \"5\":\n                print(\"Saliendo\")\n                break\n            case \"6\":\n                    print(agenda)\n            case _:\n                print(\"Opcion invalida. Elige del 1 al 6\")\n\n\nmi_agenda()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/ElbaM.py",
    "content": "#### Estructuras de Datos\n# Listas : crear, insertar, actualizar, eliminaer y ordenar Son Mutables\nls=[]\nln=list(range(1,11))\nprint(ln)\nprint(type(ln))\nprint (type(ls))\nls.append('a')\nls.append('c')\nls.append('d')\nprint(ls)\nls[1]='b'\nprint(ls)\nls.pop(2)\nprint(ls)\nls.append('c')\nls.append('m')\nls.append('k')\nls.append('e')\nls.append('r')\nls.append('p')\nprint(ls)\nls.sort()\nprint(ls)\n\na = [-1, 1, 66.25, 333, 333, 1234.5]\nprint(a)\ndel a[0]\nprint (a)\n\n\n# tuplas: crear, insertar,  NO se pueden actualizar, NO se pueden eliminar y ordenar Son Inmutables\nt1=()\nt2=(1,2,3,4)    \nt3 = (5, 6, 7)\nt4=(10,20, 'hola')\nx, y, z = t4\ntunica='Uno',\nprint(type(t1), type(t2), type(t3), type(t4), type(tunica))\nprint (tunica)\n\n# SET: crear, insertar, actualizar, eliminaer y NO se pueden ordenar Son Mutables aceptan solo datos unicos\nconjun1= set()\nconjun2={'elba', 'marina', 'mujica', 'romero', 'elba'}\nconjun3= {'gustavo', 'luis', 'gaby'}\nconjun4= set('abracadraba')    \nprint(type(conjun1), type(conjun2), type(conjun3), type(conjun4))\nprint (conjun1)\nprint(conjun2)\nprint(conjun3)\nprint(conjun4)\nconjun4.remove ('a') \nprint(conjun4)\n\n#comprension\naba = {x for x in 'abracadabra' if x not in 'abc'}\nprint(aba)   \n\n\n# DICCIONARIOS: crear, insertar, actualizar, eliminaer,  ordenar Son Mutables \n\ndicc1={}\ndicc2={'nombre':'elba', 'edad': 55, 'cursos':['python', 'GENAI']}   \ndicc3= dict(nombre='elba', apellido='Mujica', trabajos=['GEMTE', 'TECNosotros'])\nprint(type(dicc1), type(dicc2), type(dicc3))\nprint(dicc1)\nprint(dicc2)\nprint(dicc3)\ndel dicc2['edad']\nprint(dicc2)\n\n#comprension\ndicc5= {x: x**2 for x in (2, 4, 6)}\nprint(dicc5)\n\n#Pruebas de concepto\n#nombre=input('Ingrese su nombre Contacto ')\n#telefono=input('Registre Nuevo Telefono ' )\n#pruebas={nombre:telefono}\n#print(pruebas)\n\n\n# complejidad EXTRA\n\n# 1. Crear un programa que permita ingresar el nombre, telefono  de una persona\n# y guarde esos datos en una lista. El programa debe permitir ingresar los datos de\n\nagenda={}\nentrar=True\n\ndef valida_numero(telefonov):    \n    if telefonov.isdigit() and len(telefonov)<=11:\n        return True\n    else:\n        print('Telefono no valido. Intente de nuevo')\n        return False\n\ndef incluir_contacto(agenda):\n    nombre=input('Ingrese nombre Contacto: ')\n    telefono=input('Registre Telefono Contacto: ')\n    if valida_numero(telefono):\n       print(nombre, telefono)\n       agenda[nombre]= telefono   \n      # print(agenda)\n    return\n\ndef editar_contacto(agenda):\n    nombreE=input('Ingrese nombre Contacto a Editar')\n    telefonon=input('Registre Nuevo Telefono ' )\n    if valida_numero(telefonon):\n        agenda[nombreE]= telefonon   \n      # print(agenda)\n    return\n\ndef eliminar_contacto(agenda):\n    nombre=input('Ingrese su nombre Contacto a Eliminar')\n    del agenda[nombre]\n    print(agenda)\n    return\n\ndef buscar_contacto(agenda):\n    nombreb=input('Ingrese su nombre Contacto a Buscar')\n    print(agenda[nombreb])\n    return\n\ndef menu():\n    print ('AGENDA DE CONTACTO')\n    print  ('iNGRESE opcion') \n    print ('1. Ingresar Contacto')\n    print ('2. Editar Contacto')\n    print ('3. Eliminar Contacto')\n    print ('4. Buscar Contacto')\n    print ('5. Listar Agenda')\n    print ('6 Salir')\n    return\n \ndef listar_agenda(agenda):\n    for k, v in agenda.items():\n        print(k, v)\n    return\n\n\nwhile entrar == True:\n    menu()\n    opcion=input('Ingrese Opcion: ')\n    match opcion:\n        case '1':\n            incluir_contacto(agenda)\n        case '2':\n            editar_contacto (agenda)\n        case '3':\n            eliminar_contacto (agenda)\n        case '4':\n            buscar_contacto (agenda) \n        case '5':\n            # for k, v in agenda.items():\n            #     print(k, v)\n            listar_agenda (agenda)\n            #print(agenda)\n        case '6':\n            entrar=False\n            print ('Hasta Luego')\n            exit\n        case _:\n            print ('Opcion no valida')     \n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/EliasBonnin.py",
    "content": "# Ejercicio 03\n# En el siguiente URL https:/python.org Tenemos la documentacion de phyton.\n# Los retos se encuentran en https://retosdeprogramacion.com\n\n# Estructuras de control\n\n# Variables\nimport time\nimport os\nnombre = 'Elias'\nedad = 26\nlocalidad = 'Posadas'\n\n# Tipo de Estrctura lista\nmy_list = [1, 2, 3, 'Hola']\n\n# Tipo de Estrctura set\nmy_set = {1, 3, 4, 2}\n\n# Tipo de Estrctura diccionario\nmy_dict: dict = {'nombre:': nombre, 'edad:': edad, 'localidad': localidad}\n\n# Tipo de estructura tupla\nmy_tupla: tuple = (4, 5, 1, 8)\n\n# Ejecutamos comando sobre las Estructuras\n\n# Tipo List\n\nprint(my_list)\n\nmy_list.append(4)  # Agrega al final de la lista un elemento.\nprint(my_list)\n\nmy_list.insert(3, 3.5)  # Agrega un elemento a la lista en el lugar especificado\nprint(my_list)\n\nmy_list.remove('Hola')  # Remueve un valor conocido de la lista\nprint(my_list)\n\ndel my_list[0]  # Elimina el primer elemento de la lista\nprint(my_list)\n\nmy_list.pop()  # Eliminamos el ultimo valor de la lista\nprint(my_list)\n\nmy_list[0] = 4  # Actualizamos el valor de la lista asignando otro\nprint(my_list)\n\nmy_list.sort()  # Ordenamos de manera ascenedente\n\nprint(f\"{my_list}\\n\")\n\n# Tuplas\n\nprint(my_tupla[1])  # Acceso\n\nmy_tupla = tuple(sorted(my_tupla))  # Ordenacion\n\nprint(f\"{my_tupla}\\n\")\n\n# Sets\n\nmy_set.add(6)  # Insercion\nprint(my_set)\n\n# No se puede insertar el mismo dato, de esta manera podemos serializar de manera mas facil //my_set.add(6)\n\n# Eso no se puede hacer porque no tiene sentido en el Set //print(my_set[0])\n\nmy_set.remove(6)  # Borrado\n\nmy_set = set(sorted(my_set))  # No se puede ordenar por su naturaleza\nprint(my_set)\n\n\n# Diccionario\n\nprint(my_dict)\n\nprint(my_dict['nombre:'])  # Acceso\n\nmy_dict[\"provincia:\"] = 'Misiones'  # Insercion\n\nmy_dict['localidad'] = 'Garuhape'  # Actualizacion\n\ndel my_dict['edad:']\n\nprint(my_dict)\n\n# Extra\n\n\n# Funciones utiles\n\n\ndef limpiar_consola():\n    os.system('cls' if os.name == 'nt' else 'clear')\n\n# Variables\n\n\nop_interfaz = 0  # Variable que usaremos para movernos sobre la interfaz principal\nnombre_agenda = \"Nombre\"  # Nombre del agendado\nnum_tel = 0  # Numero de Telefono del agendado\n\n# Listas\n\nmy_agenda: dict = {}\n\n# Interfaz - Terminal\n\n\ndef mostrar_menu():\n    print(\"\\n Agenda de contantos\")\n    print(\"1. insertar Contacto\")\n    print(\"2. Actualizar Contacto\")\n    print(\"3. Buscar Contacto\")\n    print(\"4. Borrar Contacto\")\n    print(\"5. Mostrar Agenda y Salir\\n\")\n\n\n# limpiar_consola()\nwhile True:\n    limpiar_consola()\n    mostrar_menu()\n    op_interfaz = input(\"Elegir opcion 1-5\\n\")\n\n    if op_interfaz == \"1\":\n        limpiar_consola()\n        print(\"      Insertar Contacto\\n\")\n        nombre_agenda = input(\"Ingresa el nombre del usuario \\n\")\n        while True:\n            num_tel = input(\"Ingrese el numero de telefono \\n\")\n            if num_tel.isdigit() and len(num_tel) <= 11:\n                my_agenda[nombre_agenda] = num_tel\n                print(\"El contacto se agrego correctamete...\\n\")\n                time.sleep(1)\n                break\n            else:\n                print(\"El numero debe ser solo numeros y debe tener un maximo de 11 digitos \\n\")\n\n    elif op_interfaz == \"2\":\n        limpiar_consola()\n        print(\"      Actualizar un contacto\\n\")\n        while True:\n            nombre_agenda = input(\"Ingrese el Nombre del contacto a Actualizar o ingrese 0 para salir \\n\")\n            if nombre_agenda in my_agenda:\n                while True:\n                    num_tel = input(\"Ingrese el NUEVO numero de telefono \\n\")\n                    if num_tel.isdigit() and len(num_tel) <= 11:\n                        my_agenda[nombre_agenda] = num_tel\n                        print(\"El contacto se actualizo correctamete...\\n\")\n                        time.sleep(1)\n                        break\n                    else:\n                        print(\"El numero debe ser solo numeros y debe tener un maximo de 11 digitos \\n\")\n                break\n            elif nombre_agenda == \"0\":\n                break\n            else:\n                print(\"El nombre de contacto no existe, intente nuevamente\\n\")\n    elif op_interfaz == \"3\":\n        limpiar_consola()\n        print(\"         Buscar un contacto\")\n        while True:\n            nombre_agenda = input(\"Ingrese el Contacto a Buscar o 0 para salir\\n\")\n            if nombre_agenda in my_agenda:\n                print(f\"El Numero de {nombre_agenda} es: {my_agenda[nombre_agenda]}\\n\\n\")\n            elif nombre_agenda == \"0\":\n                break\n            else:\n                print(\"El usuario buscado no Existe\\n\\n\")\n    elif op_interfaz == \"4\":\n        limpiar_consola()\n        print(\"      Borrar un contacto\")\n        while True:\n            nombre_agenda = input(\"Ingrese el Nombre del Contacto a Eliminar o Ingrese 0 para Salir\\n\")\n            if nombre_agenda in my_agenda:\n                del my_agenda[nombre_agenda]\n                print(\"El Contacto a sido Eliminado Correctamente...\\n\")\n                time.sleep(1)\n                break\n            elif nombre_agenda == \"0\":\n                break\n            else:\n                print(\"El Nombre Ingresado no Existe\\n\")\n    elif op_interfaz == \"5\":\n        print(\"Hasta Luego\\n\")\n        print(f\"Agenda de contactos\\n {my_agenda}\")\n        break\n    else:\n        print(\"Opcion no valida\")\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/EmmanuelMMontesinos.py",
    "content": "\"\"\"\r\n/*\r\n * EJERCICIO:\r\n * x Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\r\n * x Utiliza operaciones de inserción, borrado, actualización y ordenación.\r\n *\r\n */\r\n\"\"\"\r\n# Tipos de estructuras:\r\n\r\n# Tupla -> Inmutable\r\ntupla: tuple = (\"dato_1\", \"dato2\", \"dato_3\")\r\n\r\n# Lista -> Mutable\r\nlista: list = [\"dato_1\", \"dato_2\", \"dato_3\"]\r\n\r\n\"\"\"Agragar o Actualizar según índice\"\"\"\r\nlista.insert(0, \"dato_4\")\r\n\r\n\"\"\"Agregar al final\"\"\"\r\nlista.append(\"dato_5\")\r\n\r\n\"\"\"Borrar el último o según índice\"\"\"\r\nlista.pop()\r\n\r\n\"\"\"Borra según el contenido\"\"\"\r\nlista.remove(\"dato_3\")\r\n\r\n\"\"\"Orden normal\"\"\"\r\nlista.sort()\r\n\r\n\"\"\"Invertir Orden\"\"\"\r\nlista.reverse()\r\n\r\n\r\n# Set -> Mutable No Ordenado\r\nset: set = {\"dato_1\", \"dato_2\", \"dato_3\"}\r\n\r\n\"\"\"Agregar\"\"\"\r\nset.add(\"dato_4\")\r\n\r\n\"\"\"Borrar\"\"\"\r\nset.remove(\"dato_2\")\r\n\r\n\"\"\"Borrar el último\"\"\"\r\nset.pop()\r\n\r\n# Diccionario -> Mutable\r\ndiccionario: dict[str:str] = {\"llave\": \"valor\"}\r\n\r\n\"\"\"Agregar\"\"\"\r\ndiccionario[\"llave2\"] = \"valor2\"\r\n\r\n\"\"\"Actualizar\"\"\"\r\ndiccionario[\"llave\"] = \"valor3\"\r\n\r\n\"\"\"Borrar\"\"\"\r\ndiccionario.pop(\"llave\")\r\n\r\n\"\"\"Borrar y mueve el ultimo elemento\"\"\"\r\nelement = diccionario.popitem()\r\n\r\n\"\"\"\r\n* DIFICULTAD EXTRA (opcional):\r\n * Crea una agenda de contactos por terminal.\r\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\r\n * - Cada contacto debe tener un nombre y un número de teléfono.\r\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\r\n *   los datos necesarios para llevarla a cabo.\r\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\r\n *   (o el número de dígitos que quieras)\r\n * - También se debe proponer una operación de finalización del programa.\r\n \"\"\"\r\n\r\n# Diccionario usado como agenda\r\nagenda = {}\r\n\r\n# Clase para crear y gestionar la agenda\r\n\r\n\r\nclass Contacto():\r\n    def add(nombre: str, tlf: str) -> None:\r\n        check = int(tlf)\r\n        if len(tlf) <= 11 and isinstance(check, int) == True:\r\n            agenda[nombre.lower()] = tlf\r\n            print(f\"{nombre} ha sido guardado\")\r\n        else:\r\n            print(f\"El Número {tlf} no es válido\")\r\n    # funcion plantilla para imprimir contactos\r\n\r\n    def imprimir(nombre):\r\n        print(f\"Nombre: {nombre.capitalize()}\\nTlf: {agenda[nombre]}\")\r\n\r\n    # función para buscar contacto, no es necesario el nombre exacto\r\n    def buscar(nombre):\r\n        if nombre.lower() in agenda.keys():\r\n            Contacto.imprimir(nombre)\r\n        else:\r\n            posibles = []\r\n            for contactos in agenda.keys():\r\n                for letras in nombre:\r\n                    if letras in contactos and contactos not in posibles:\r\n                        posibles.append(contactos)\r\n            if len(posibles) >= 1:\r\n                print(\r\n                    f\"No se ha encontrado al contacto -> {nombre} <-, posibles coincidencias:\")\r\n                for posible in posibles:\r\n                    print(f\"- {posible}\")\r\n            else:\r\n                print(f\"No hay ninguna coincidencia con -> {nombre} <-\")\r\n    # Actualizar contacto\r\n\r\n    def actualizar(nombre):\r\n        if nombre in agenda.keys():\r\n            print(f\"información actual:\")\r\n            Contacto.imprimir(nombre)\r\n            opcion = input(\"¿Qué quiere cambiar?\\n1-Nombre\\n2-Tlf\\n--> \")\r\n            if opcion == \"1\":\r\n                nuevo_nombre = input(\"Nuevo nombre: \")\r\n                tlf = agenda[nombre]\r\n                agenda.pop(nombre)\r\n                agenda[nuevo_nombre] = tlf\r\n                print(\"Contacto cambiado:\")\r\n                Contacto.imprimir(nuevo_nombre)\r\n            elif opcion == \"2\":\r\n                nuevo_tlf = input(\"Nuevo Tlf: \")\r\n                check = int(nuevo_tlf)\r\n                if len(nuevo_tlf) <= 11 and isinstance(check, int) == True:\r\n                    agenda[nombre] = nuevo_tlf\r\n                    print(\"Contacto cambiado:\")\r\n                    Contacto.imprimir(nombre)\r\n                else:\r\n                    print(f\"{nuevo_tlf} tiene más de 11 digitos o no es un número\")\r\n            else:\r\n                print(\"Opción incorrecta\")\r\n\r\n    def borrar(nombre):\r\n        if nombre in agenda.keys():\r\n            agenda.pop(nombre)\r\n            print(f\"{nombre} ha sido borrado\")\r\n        else:\r\n            print(f\"{nombre} no esta en la agenda\")\r\n\r\n\r\ndef main():\r\n    salir = False\r\n    while not salir:\r\n        print(\"Agenda\")\r\n        print(\"OPCIONES\")\r\n        print(\"1- Agregar Contacto\")\r\n        print(\"2- Buscar Contacto\")\r\n        print(\"3- Actualizar Contacto\")\r\n        print(\"4- Borrar Contacto\")\r\n        print(\"5- Mostrar Toda la agenda\")\r\n        print(\"6- Salir\")\r\n        opcion = input(\"--> \")\r\n        if opcion == \"1\":\r\n            nombre = input(\"Nombre: \")\r\n            tlf = input(\"Tlf: \")\r\n            Contacto.add(nombre, tlf)\r\n        elif opcion == \"2\":\r\n            nombre = input(\"Nombre a buscar: \")\r\n            Contacto.buscar(nombre)\r\n        elif opcion == \"3\":\r\n            nombre = input(\"¿Qué contacto quiere cambiar?(nombre): \")\r\n            Contacto.actualizar(nombre)\r\n        elif opcion == \"4\":\r\n            nombre = input(\"Nombre del contacto a borrar: \")\r\n            Contacto.borrar(nombre)\r\n        elif opcion == \"5\":\r\n            ciclo = 1\r\n            for contac in agenda:\r\n                print(f\"{ciclo}nº - {contac}\")\r\n        elif opcion == \"6\":\r\n            salir = True\r\n            print(\"Adíos!\")\r\n\r\n\r\nmain()\r\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/EricJoel-code.py",
    "content": "# Estructuras de Datos\n\n# Listas: Colección ordenada y mutable de elementos\n\nmi_lista = [\"Python\",\"Java\",\"C++\",\"C#\" ]\nprint(mi_lista)\n\n#Insertar un elemento en una lista\nmi_lista.append(\"Go\")\nprint(mi_lista)\n\n#Eliminar un elemento de una lista\nmi_lista.remove(\"Java\")\nprint(mi_lista)\n\n#Acceder a un elemento de una lista\nprint(mi_lista[1])\n\n#Actualizar un elemento de una lista\nmi_lista[2] = \"C\"\nprint(mi_lista)\n\n#Ordenar una lista\nmi_lista.sort()\nprint(mi_lista)\n\n# Tuplas: Colección ordenada e inmutable de elementos\n\nmi_tupla = (\"Eric\",\"Joel\", \"22\", \"Python\") \nprint(mi_tupla)\n\n#Acceder a un elemento de una tupla\nprint(mi_tupla[0])\n\n#Ordenar una tupla (convertir a lista y luego ordenar)\nmi_tupla = tuple(sorted(mi_tupla))  \nprint(mi_tupla)\n\n# Sets: Colección no ordenada y mutable de elementos únicos\nmi_set = {\"Python\", \"Java\", \"C++\", \"C#\" }\nprint(mi_set)\n\n#Agregar un elemento a un set\nmi_set.add(\"Go\")\nmi_set.add(\"Go\")  # No se agregará porque ya existe\nprint(mi_set)\n\n#Eliminar un elemento de un set\nmi_set.remove(\"Java\")\nprint(mi_set)\n\n#Ordenar un set: se convierte a lista, se ordena y luego se convierte de nuevo a set esto no mantiene el orden ya que los sets son desordenados\nmi_set = set(sorted(mi_set))  \nprint(mi_set)\n\n# Diccionarios: Colección ordenada, mutable de pares clave-valor\n\nmi_diccionario = {\n    \"nombre\": \"Eric\",\n    \"apellido\": \"Cacuango\",\n    \"edad\": 22,\n    \"ciudad\": \"Otavalo\"\n}\nprint(mi_diccionario)\n\n#Acceder a un valor en un diccionario\nprint(mi_diccionario[\"nombre\"]) # Accede al valor asociado a la clave\nprint(mi_diccionario.get(\"edad\")) # Otra forma de acceder al valor asociado a la clave\n\n#Insertar un par clave-valor en un diccionario\nmi_diccionario[\"profesion\"] = \"Programador\"\nprint(mi_diccionario)\n\n#Borrar un par clave-valor en un diccionario\ndel mi_diccionario[\"ciudad\"]\nprint(mi_diccionario)\n\n#Actualizar un valor en un diccionario\nmi_diccionario[\"edad\"] = 23\nprint(mi_diccionario)\n\n#Ordenar un diccionario por clave (convierte a lista de tuplas, ordena y luego convierte de nuevo a diccionario)\nmi_diccionario = dict(sorted(mi_diccionario.items()))\nprint(mi_diccionario)  # Muestra una lista de tuplas ordenadas por clave\n\n#Extra\n\n# Crea una agenda de contactos por terminal\n\ncontactos = {}\n\n\ndef agregar_contacto():\n    nombre = input(\"Ingrese el nombre del contacto: \")\n    telefono = input(\"Ingrese el numero de telefono del contacto: \")\n    while True:\n        if telefono.isdigit() and len(telefono) > 0 and len(telefono) < 12:\n            contactos[nombre] = telefono\n            print(f\"Contacto {nombre} agregado.\")\n            break\n        else:\n            print(\"Número de teléfono no válido. Debe ser numérico y tener menos de 12 dígitos.\")\n            telefono = input(\"Ingrese nuevamente el numero de telefono del contacto: \")\n    \n\ndef buscar_contacto():\n    nombre = input(\"Ingrese el nombre del contacto a buscar: \")\n    if nombre in contactos:\n        print(f\"Contacto encontrado: {nombre} - {contactos[nombre]}\")\n    else:\n        print(\"Contacto no encontrado.\")\n        \n\ndef eliminar_contacto():\n    nombre = input(\"Ingrese el nombre del contacto a eliminar: \")\n    if nombre in contactos:\n        del contactos[nombre]\n        print(f\"Contacto {nombre} eliminado.\")\n    else:\n        print(\"Contacto no encontrado.\")\n        \n        \ndef actualizar_contacto():\n    nombre = input(\"Ingrese el nombre del contacto a actualizar: \")\n    if nombre in contactos:\n        nuevo_telefono = input(\"Ingrese el nuevo numero de telefono: \")\n        while True:\n            if nuevo_telefono.isdigit() and len(nuevo_telefono) > 0 and len(nuevo_telefono) < 12:\n                contactos[nombre] = nuevo_telefono\n                print(f\"Contacto {nombre} actualizado.\")\n                break\n            else:\n                print(\"Número de teléfono no válido. Debe ser numérico y tener menos de 12 dígitos.\")\n                nuevo_telefono = input(\"Ingrese nuevamente el nuevo numero de telefono: \")\n    else:\n        print(\"Contacto no encontrado\")\n        \n        \ndef mostrar_contactos():\n    if contactos:\n        print(\"Contactos en la agenda:\")\n        for nombre, telefono in contactos.items():\n            print(f\"{nombre} - {telefono}\")\n    else:\n        print(\"No hay contactos en la agenda.\")\n\ndef agenda():\n    \n    while True:\n        print(\"\\n --- Agenda de Contactos ---\")\n        print(\"1. Agregar Contacto\")\n        print(\"2. Buscar Contacto\")\n        print(\"3. Actualizar Contacto\")\n        print(\"4. Eliminar Contacto\")\n        print(\"5. Mostrar Todos los Contactos\")\n        print(\"6. Salir\")\n        print(\"----------------------------\")\n        \n        opcion = input(\"Seleccione una opcion (1-6): \")\n        \n        if opcion == '1':\n            agregar_contacto()\n        elif opcion == '2':\n            buscar_contacto()\n        elif opcion == '3':\n            actualizar_contacto()\n        elif opcion == '4':\n            eliminar_contacto()\n        elif opcion == '5':\n            mostrar_contactos()\n        elif opcion == '6':\n            print(\"Saliendo de la agenda.\")\n            break\n        else:\n            print(\"Opcion no valida. Intente de nuevo.\")\n            \nagenda()\n\n        "
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/FabianRpv.py",
    "content": "# Estructuras de Datos\n\n# Listas:\n\nmi_lista = [1, 2, 3]\n\nmi_lista.append(4) #Añadir al final de la lista\n\nmi_lista.remove(2) #Eliminar valor de la lista\n\ndel mi_lista[0] #Eliminar por posicion de la lista\n\nmi_lista[0] = 5 #Actualizar posicion de la lista\n\nmi_lista.sort() #Ordena la lista\n\nprint(mi_lista)\n\n\n# Tuplas:\n\nmi_tupla = (1, 2, 3, 4)  #Las tuplas son inmutables, no permiten modiicacion directa\n\nnueva_tupla = mi_tupla + (5,)  #Para añadir un nuevo elemento se debe hacer una nueva tupla\n\nnueva_tupla = mi_tupla[:2] + mi_tupla[3:]  #Para eliminar un elemento se debe hacer una nueva tupla\n\nlista_temp = list(mi_tupla)  #Para modificar una tupla se debe pasar a lista y luego volver a convertirla\nlista_temp[1] = 5\nmi_tupla = tuple(lista_temp)\n\nprint(mi_tupla)\nprint(nueva_tupla)\n\n\n# Sets: \n\nmi_set = {1, 2, 3, 4} \n\nmi_set.add(5) # Añadir al set\nmi_set.update([9, 6]) #Añadir varios valores al set \n\nmi_set.remove(4) #Elimina el elemento\nmi_set.discard(10) #Elimina si existe el valor y no da error\n\nprint(mi_set)\n\n\n# Diccionarios: \n\nmi_dict = {'a': 1, 'b': 2, 'c': 3}\n\nmi_dict['h'] = 4  #Añdir nuevo valor\nmi_dict.update({'f': 5, 'e': 6})  #Añadir multiples valores\n\ndel mi_dict['b']  #Eliminar valor\nmi_dict.popitem()  #Elimina el ultimo valor\n\nmi_dict['a'] = 10  #Actualizar valor\nmi_dict.update({'a': 11, 'c': 33})  #Actualizar multiples valores\n\nsort_por_clave = sorted(mi_dict.items())  #Ordenar por clave, devuelve una lista de tuplas\nsort_por_valor = sorted(mi_dict.items(), key = lambda x: x[1])  #Ordena por valor, devuelve una lista de tuplas\n\nprint(mi_dict)\nprint(sort_por_clave)\nprint(sort_por_valor)\n\n\n# Ejercicio:\n\nimport os\n\ntry: \n    agenda = {\n        \"Fabian\": 123456,\n        \"Oscar\": 55555,\n    }\n\n    def mostrar():\n        for contacto in agenda:\n            print(f\"- {contacto} {agenda[contacto]}\")\n            print(\"\")\n\n    def buscar():\n\n        busqueda = input(\"Ingrese Nombre o Numero del contacto: \")\n        print(\"\")\n\n        if busqueda in agenda:\n            print(f\"{busqueda} {agenda[busqueda]}\")\n                    \n        elif busqueda.isdigit() and int(busqueda) in agenda.values():\n            \n            numero = int(busqueda)\n            \n            for clave, valor in agenda.items():\n                \n               if numero == valor:\n                   print(clave, valor)\n\n        else:\n            print(\"Contacto no existente\")\n\n    def agregar():\n       \n        nombre = input(\"Ingrese el nombre del contacto: \")\n        numero = input(\"Ingrese el numero del contacto: \")\n       \n        if nombre and numero.isdigit():\n            if len(numero) > 11:\n                print(\"\")\n                print(\"El numero no puede exceder los 11 digitos\")\n            else:\n                agenda[nombre] = numero\n                print(\"Contacto Agregado Exitosamente\")\n                print(\"\")\n        \n        else:\n            print(\"\")\n            print(\"Ingrese datos validos\")\n\n    def actualizar():\n        \n        busqueda = input(\"Ingrese el nombre del contacto a actualizar: \")\n        print(\"\")\n\n        if busqueda in agenda:\n            print(f\"{busqueda} {agenda[busqueda]}\")\n            print(\"\")\n            numero = input(\"Ingrese el nuevo numero del contacto: \")\n       \n            if numero.isdigit():\n                \n                if len(numero) > 11:\n                    print(\"\")\n                    print(\"El numero no puede exceder los 11 digitos\")\n                \n                else:\n                    agenda[busqueda] = numero\n                    print(\"\")\n                    print(\"Contacto Actualizado Exitosamente\")\n        \n            else:\n                print(\"\")\n                print(\"Ingrese datos validos\")\n\n                    \n        else:\n            print(\"Contacto no existente\")\n\n    def eliminar():\n        \n        contacto = input(\"Ingrese el nombre del contacto a eliminar: \")\n        \n        if contacto in agenda:\n            del agenda[contacto]\n            print(\"\")\n            print(\"Contacto eliminado correctamente\")\n            \n        else:\n            print(\"\")\n            print(\"Contacto no encontrado\")\n            \n    while True:\n\n        os.system('cls')\n            \n        print(\"----------------Agenda-----------------\")\n        print(\"\")\n        print(\"1. Mostrar Contactos\")\n        print(\"2. Buscar Contacto\")\n        print(\"3. Agregar Nuevo Contacto\")\n        print(\"4. Actualizar Contacto\")\n        print(\"5. Eliminar Contacto\")\n        print(\"6. Salir\")\n        print(\"\")\n\n        menu = int(input(\"Seleccione una Opcion: \"))\n\n        match menu:\n\n            case 1: \n\n                os.system('cls')\n                print(\"Contactos: \")\n                print(\"\")\n                mostrar()\n                input(\"Presione Enter para continuar\")\n\n            case 2:\n\n                os.system('cls')\n                print(\"Buscar Contacto:\")\n                print(\"\")\n                buscar()\n                print(\"\")\n                input(\"Presione Enter para continuar\")\n\n            case 3: \n\n                os.system('cls')\n                print(\"Agregar Contacto:\")\n                print(\"\")\n                agregar()\n                print(\"\")\n                input(\"Presione Enter para continuar\")\n\n            case 4:\n\n                os.system('cls')\n                print(\"Actualizar Contacto:\")\n                print(\"\")\n                actualizar()\n                print(\"\")\n                input(\"Presione Enter para continuar\")\n                    \n            case 5:\n\n                os.system('cls')\n                print(\"Eliminar Contacto:\")\n                print(\"\")\n                eliminar()\n                print(\"\")\n                input(\"Presione Enter para continuar\")\n\n            case 6: \n                os.system('cls')\n                print(\"Programa Finalizado. Que tengas buen dia :)\")\n                break\n\n            case _: \n                os.system('cls')\n                print(\"Error: Seleccion una opcion valida\")\n                print(\"\")\n    \nexcept ValueError:\n    \n    print(\"Ingrese solo valores validos\")\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/FedeAirala.py",
    "content": "# Reto #03 ESTRUCTURAS DE DATOS\n\n\"\"\"\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n\n \"\"\"\n\n# Estructuras de datos en Python!\n\n\"\"\" Listas : las listas son estructuras para almacenar datos, estos pueden ser de cualquier tipo, inclusive\n    se pueden almacenar listas dentro una lista. Las listas son ordenadas por un índice donde el primer elemento\n    tiene el índice 0. Estas pueden tener elementos duplicados\n\"\"\"\n\n# Creación de listas.\n\nmy_list = []                                            # Lista vacía\nmy_list_numbers = [1,2,3,4,5]                           # Lista de números\nmy_list_strings = [\"Hola\", \"Python\"]                    # Lista de strings\nmy_list_several = [\"Hola\", 1,2,3, [\"Python\", \"Java\"]]   # Lista con elementos varios\n\nprint (type(my_list))            # Impresión del tipo de la variable my_list: List\nprint (my_list_numbers)\nprint (my_list_strings)\nprint (my_list_several)\nprint (my_list_several[4][1])    # Imprime el segundo elemento de la lista dentro de la lista: Java\n\n\n# Inserción de un elemento a una lista.\n\nmy_list_numbers.append(5)           # append agrega un elemento y lo coloca en el último lugar\nprint (my_list_numbers)\nmy_list_numbers.insert(2,6)         # insert agrega un elemento a una posición indicada en la lista\nprint (my_list_numbers)\nother_list = [\"Hola\", \"Python\"]\nmy_list_numbers.extend(other_list)  # extend extiende la lista agregando cualquier otro tipo de esctructura\nprint (my_list_numbers)\n\n# Borrado de elementos de listas.\n\nmy_list_numbers.remove(5)  # elimina el primer elemento especificado que encuentre en la lista\nprint (my_list_numbers)\nmy_list_numbers.pop(1)     # elimina el elemento que se encuentra en la posición especificada\nprint (my_list_numbers)\ndel my_list_numbers[0]     # este también elimina el elemento que se encuentra en la posición especificada\nprint (my_list_numbers)\n# del my_list_numbers      # elimina lista completa\nmy_list_numbers.clear()    # vacía la lista\nprint (my_list_numbers)\n\n# Actualización de listas\n\nmy_list_strings[1]=\"Mundo\" # Actualiza el índice 1 de la lista: cambia Python por Mundo\nprint(my_list_strings)\n\n# Ordenación de listas\n\nmy_list_order = [4,65,8,4,26,95,1]\nmy_list_order.sort()                # ordena la lista en forma ascendente\nprint (my_list_order)\nmy_list_order.sort (reverse=True)   # ordena la lista en forma descendente\nprint (my_list_order)\n\n\n# Tuplas \n\n\"\"\" Las tuplas permiten almacenar muchos tipos de datos, estos están indexados pero tienen la particularidad de \n    de que son ordenadas e inmutables. Al igual que las listas pueden tener cualquier tipo de elementos.\n\"\"\"\n# Creación de tuplas\n\nmy_tuple = ()                          # Tupla vacía\nprint (type(my_tuple))\nmy_tuple_numbers = (1,2,3,4,5,5,5)     # Tupla de números\nprint (my_tuple_numbers)\n\n# Inserción de elementos a una tupla\n\n# Para ello hay que convertir la lista en una lista, agregar el elemento y luego convertirlo en tupla nuevamente\n\nmy_tuple_numbers = (1,2,3,4,5,5,5)\ntuple_list = list ( my_tuple_numbers)\ntuple_list.append (6)\nmy_tuple_numbers = tuple(tuple_list)\nprint (my_tuple_numbers)\n\n\n# Borrado de Tuplas\n\n# Para eliminar un elemento de una tupla también se debe convertir en una lista, borrar el elemento y volver a tupla.\n\nmy_tuple_numbers = (1,2,3,4,5,5,5)\ntuple_list = list ( my_tuple_numbers)\ntuple_list.remove(5)\nmy_tuple_numbers = tuple(tuple_list)\nprint (my_tuple_numbers)\n\n# Eliminar una tupla\n\n# del my_tuple_numbers\n# print (my_tuple_numbers)\n\n# Conjuntos\n\n\"\"\" Los conjuntos también se utilizan para almacenar elementos, ellos no están ordenados, no admiten duplicados\n    y no son indexados, por lo tanto no se pueden ordenar\n\"\"\"\n\n# Creación de conjuntos\n\nmy_set = {\"\"}           # Conjunto vacío\nprint (type(my_set))\nmy_set_elements = {\"Hola\",1,2,3,3,3,\"Python\"}\nprint(my_set_elements)  # Al imprimir se ve como aparece el elemento 3 una sola vez\n\n# Inserción de un elemento a un conjunto\n\nmy_set_elements.add(\"Mundo\")\nprint (my_set_elements) # Al imprimir se ve como lo agraga al elemento en cualquier posición\n\n# Eliminar un elemento de un conjunto\n\n\"\"\"Para ello no se puede indicar el índice, y al no permitir duplicados, busca el elemento a eliminar\ny lo saca del conjunto\n\"\"\"\n\nmy_set_elements.remove(\"Python\")\nprint (my_set_elements)\n\n\n# Diccionarios\n\n\"\"\" Este tipo de estructura se utiliza para almacenar datos en pares clave:valor.\n    Es una estructura ordenada, se puede modificar y no permite duplicados\n\n\"\"\"\n\n# Creación de un diccionario\n\nmy_dicc = {}            # Crea un diccionario vacío\nprint (type(my_dicc))\nmy_dicc_elements = {\n                    \"name\" :\"María\",\n                    \"surname\":\"López\",\n                    \"age\": 25}\nprint (my_dicc_elements)\n\n# Agregar un elemento a un diccionario\n\nmy_dicc_elements [\"email\"]= \"marialopez@lopez.com\"\nprint (my_dicc_elements)\n\n# Actualizar elementos de un diccionario\n\nmy_dicc_elements[\"age\"]= 30\nprint (my_dicc_elements)\n\n# Eliminar elementos de un diccionario\n\nmy_dicc_elements.pop (\"age\")\nprint (my_dicc_elements)\n\nprint (\"\\n\")\nprint (\"\\n\")\nprint (\"\\n\")\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n \n \"\"\"\n\nprint (\"**********Agenda de Contactos***********\")\nprint (\"                                         \")\n   \n\ncontacts = {}\ntry:\n    def agregar():\n        name = input ( \"Ingrese nombre del contacto a agregar: \")\n        num =  input(\"Ingrese número de teléfono del contacto: \")\n        while True:\n            if num.isdigit() and len(num) < 12 :\n                contacts[name]= num\n                print (contacts)\n                print (f\"El contacto {name} se ha ingresado correctamente\")\n                break\n            else:\n                print (\"Número incorrecto\")\n                num =  (input(\"Ingrese número de teléfono del contacto: \"))\n\n\n    def buscar():\n        name = input (\" Ingrese el nombre del contacto que desea buscar: \")\n        if name in contacts:\n                print (f\"{name} : {contacts[name]}\")\n        else:\n            print (\" El contacto no se encuentra en la agenda\")\n            ag = input (\"Desea agregarlo S/N: \")\n            if ag == \"S\":\n                agregar()\n            elif ag == \"N\":\n                pass\n\n            \n\n    def actualizar():\n        name = input (\"Ingrese el contacto que desea actualizar: \")\n        if name in contacts:\n            num = input (\"Ingrese nuevo número: \")\n            \n            while True:\n                if num.isdigit() and len (num) < 12 :\n                    contacts[name]= num\n                    print (f\"El contacto {name} se ha actualizado correctamente\")\n                    break\n                else:\n                    print (\"Número incorrecto\")\n                    num =  (input(\"Ingrese número de teléfono del contacto: \"))\n        else:\n            print (\"El contacto no existe\")\n\n    def eliminar ():\n        name = input(\"Ingrese nombre de contacto a eliminar:\")\n        if name in contacts:\n            contacts.pop(name)\n            print (f\"Se eliminó el contacto {name}\")\n        else:\n            print (\"El contacto no existe en la agenda\")\n    \n\n    def agenda():\n        \n        while True:\n            print (\"1 ! Buscar , 2 ! Agregar , 3 ! Actualizar, 4 ! Eliminar, 5 ! Lista, 6 ! Salir \")\n            opcion = int(input (\"Ingrese opción: \"))\n\n            if opcion == 1:\n                buscar()\n            elif opcion == 2:\n                agregar()\n            elif opcion == 3:\n                actualizar()\n            elif opcion == 4:\n                eliminar()\n            elif opcion == 5:\n                print (\"Contactos     Número\")\n                for i in contacts:\n                    print (f\"  {i}        {contacts[i]}\")\n            elif opcion == 6:\n                print (\"Ha salido de la agenda\")\n                break\n            else:\n                opcion = input(\"Opción incorrecta, vuela a elegir: \")\n\n    agenda()\n      \nexcept Exception as e:\n    print (e)\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Franz-Arzapalo.py",
    "content": "\"\"\"\nEJERCICIO: ESTRUCTURAS DE DATOS\n - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n   DIFICULTAD EXTRA (opcional):\n  Crea una agenda de contactos por terminal.\n - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n - Cada contacto debe tener un nombre y un número de teléfono.\n - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n   los datos necesarios para llevarla a cabo.\n - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n   (o el número de dígitos que quieras)\n - También se debe proponer una operación de finalización del programa.\n \"\"\"\n\n# 1. Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n\n\"\"\"\nAqui entran los tipos de datos primitivos: Int, Flt, Str y Bool. Pero, no se profundisara en estos porque ya los vimos en un reto anterior.\n\"\"\"\n\n# Numeros complejos:\n\"\"\"\nLos numeros complejos en python es una operacion de numeros reales y numeros imaginarios su uso puede llegar a ser complejo, \ntiene usos matematicos y fisicos pues son utiles para describir ondas electromagnéticas y la corriente electrica.\n\"\"\"\n\nprint(type(x := 3 + 1j)) # Complex\n\n# Se pueden hacer operaciones con los numeros complejos algunas son igual que trabajar con numeros reales pero en otras se siguen\n# otro procedimiento. Pero, estas son solo operaciones simples para hacer uso mas profundo se necesita una libreria (cmath)\n\n# Listas:\n\"\"\"\nSon un tipo de dato que permite almacenar datos de cualquier tipo. Son mutables y dinamicas esto quiere decir que sus datos pueden ser\nmodificados y que se puede añadir o eliminar informacion tambien son anidadas osea que se pueden meter unas dentro de otras y son ordenadas\npues mantienen el orden en el que han sido definidas.\n\"\"\"\n\n# Las listas se pueden definir usando los corchetes [] o usando el comando list().\n\na = [\"Franz\", 19, \"Python\"]\nprint(a) # ['Franz', 19, 'Python']\n\nb = list(\"1234\")\nprint(b) # ['1', '2', '3', '4']\n\nprint(type(a)) # List\nprint(type(b)) # List\n\n# Como se puede ver los datos se separan con comas y la forma de llamarlos es la siguiente.\n\nprint(a[1]) # 19\n\n# El orden de una lista empieza desde el 0, en este ejemplo se tienen 3 datos el primero sera la posicion 0 despues 1 y asi.\n# Tambien se pueden llamar usandos los datos negativos por ejemplo -1 llamara al ultimo aqui por obvias razones no se empieza de 0\n# Pero la logica es la misma haciendo que -2 llame al penultimo y asi.\n\n# Para modificar una de los datos de una lista es tan simple como hacer lo siguiente:\n\na[1] = 20\nprint(a) #['Franz', 20, 'Python'] \n\n# Como se puede observar el valor que era 19 cambio a 20 asi de facil es hacer un cambio.\n\n# Elminar datos de una lista:\n\nc = list(\"abcdefg\") \nprint(c) #['a', 'b', 'c', 'd', 'e', 'f', 'g']\n\n# del elimina el dato que se encuentre en la posicion definida.\n\ndel c[1]\nprint(c) #['a', 'c', 'd', 'e', 'f', 'g']\n\n# Listas anidadas osea que podemos definir listas dentro de listas.\n\nd = ['1', '2', '3', a, b]\nprint(d) #['1', '2', '3', ['Franz', 20, 'Python'], ['1', '2', '3', '4']]\n\n# Esto se puede hacer indefinidamente y para ingresar a esos datos anidados solo tenemos que usar tantos corchetes como los necesitemos.\n\nprint(d[3][0]) # Franz\n\n# y asi podemos ingresar a los datos anidados.\n\n# Tambien podemos sacar datos usando un rago en las posiciones y para definir el rango se usan los corchetes y los dos puntos.\n\nprint(d[0:4]) # ['1', '2', '3', ['Franz', 20, 'Python']]\n\n# Como ya es constumbre en el leguaje cuando definimos un rango tomar el primero pero no el ultima posicion definida.\n# Esto tambien nos sirve para cambiar un rago de datos en las listas usando el = como antes.\n\n# Las listas se pueden combinar con algunois operadores:\n\nprint(d) # ['1', '2', '3', ['Franz', 20, 'Python'], ['1', '2', '3', '4']]\nd += [7, 8, 9]\nprint(d) # ['1', '2', '3', ['Franz', 20, 'Python'], ['1', '2', '3', '4'], 7, 8, 9]\n\n# Otro uso muy util que podemos hacer con las listas es definir muchas variables con su ayuda.\n\ne = [1, 2, 3]\nx , y , z = e\nprint(x, y , z) # 1 2 3\n\n# Obviamente respeta el orden para definirlos.\n\n# La iteracion con listas es facil, mas que en la mayoria de lenguajes.\n\nfor index, dato in enumerate(e):\n    print(index, dato)\n    # 0 1\n    # 1 2\n    # 2 3\n\n# Con enumerate() podemos añadir el valor de la posicion y el dato en estas iteraciones.\n\n# Tambien podemos iterar dos listas a la vez.\n\nfor i1, i2 in zip(a, b):\n    print(i1, i2)\n    # 0 1\n    # 1 2\n    # 2 3\n\n# La ireacion termina cuando se terminan los datos en una de las listas.\n\n# Longitud de una lista.\n# Con el comando len() podemos obener el numero de datos que tiene una lista.\n\ng = ['a', 'b', 'c']\nprint(len(g)) # 3\n\n# Es una herramienta util.\n\n# Elemento append() nos ayuda a añadir un dato al final de la lista.\n\nh = [1, 2 ,3]\nh.append(4)\nprint(h) # [1, 2, 3, 4]\n\n# Como vemos su uso va llamando a la lista y añadiendo .append() mientras que dentro del parentesis se ingresa el dato.\n\n# Elemento extend() sirve para añadir una lista a otroa lista.\n\nj = [1, 2 ,3]\nj.extend([4, 5])\nprint(j) # [1, 2, 3, 4, 5]\n\n# Una diferencia con append() es que extend() añade los datos de la lista y append() lo añade como lista.\n\n# Elemento insert() añade un dato pero en la posicion que se define.\n\nk = list(\"1235678\") \nprint(k) # ['1', '2', '3', '5', '6', '7', '8']\nk.insert(3,4)\nprint(k) # ['1', '2', '3', 4, '5', '6', '7', '8']\n\n# Como vemos primero se ingresa la posicion y despues de la coma el dato que se desea añadir.\n\n# Elemento remove().\n\nprint(k) # ['1', '2', '3', 4, '5', '6', '7', '8']\nk.remove('8')\nprint(k) # ['1', '2', '3', 4, '5', '6', '7']\n\n# Elmina el elemento ingresado dentro del parentesis obviamente tiene que estar en el mismo tipo de dato para poder ser identificado.\n\n# Elemento pop()\n\nprint(k) # ['1', '2', '3', 4, '5', '6', '7']\nk.pop()\nprint(k) # ['1', '2', '3', 4, '5', '6']\n\n# pop() elmina el dato que este en la posicion indicada por defecto esta en -1 la posicion.\n\n# Elemento reverse().\n\nl = [1, 2, 3, 4, 5]\nl.reverse()\nprint(l) # [5, 4, 3, 2, 1]\n\n# Recordemos que las listas conservan el orden en el que se han definido los datos reverse() invierte el orden en el que se han definido.\n\n# Elemento sort().\n\nm = [1, 2 ,7 ,4, 6, 5, 3]\nm.sort()\nprint(m)\n\n# El elemto sort() ordena la lista siempre que esta se pueda ordenar de menor a mayor.\n# Tambien se puede hacer que la ordenen de mayor a menor si ponemos reverse=True en los parametros.\n\n# index().\n\nn = list(\"ABCDEFGHIJK\")\nprint(n) # ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K']\nprint(n.index('A')) # 0\n\n# El elemento index nos permite buscar un dato dentro de una lista y nos devuelve la posicion en la que se encuentras ese dato.\n\n# Sets:\n\"\"\"\nLos sets tambien almacenan datos, pero poseen diferencias con respecto a las listas como: En los sets no se pueden repetir los datos,\notra diferencia es que no mantienen el orden de cuando son definidas y sus elementos son inmutables lo que significa que sus datos\nno pueden ser modificados.\n\"\"\"\n\n# Para definir los sets podemos usar las llaves {} o el comando set() y pasarle un tipo iterable como con el comando list().\n\ns = set(a) # \"a\" es una lista que se creo antes. \nprint(s) # {'Python', 20, 'Franz'}\ns0 = {1, 4, 3, 2, 5}\nprint(s0) # {1, 2, 3, 4, 5}\n\nprint(type(s)) # <class 'set'>\nprint(type(s0)) # <class 'set'>\n\n# Como podemos ver las llaves definen un set y tambien podemos ver que no conservan el orden con el que son definidos.\n\n# Como dije antes si intentamos modifocar uno de sus datos como con las listas.\n# s[0] = 1 TypeError: 'set' object does not support item assignment.\n#  Nos dara ese error.\n\n# Tampoco podemos anidar listas o diccionarios en los sets pues estos tipos de datos son mutables a diferencias de los sets.\n# s1 = {'ejemplo', 'ejemplo2', a} TypeError: unhashable type: 'list'\n# Si lo intetamos nos dara un error en la terminal.\n\n# Sin embargo podemos anidar frozenset que son completamente inmutable sin poder hacer ningun tipo de modificacion.\n# Se crea de la siguiente manera.\n\nfs = frozenset((1, 2))\nprint(type(fs)) # <class 'frozenset'>\n\n# Esta es una sus principales funciones pues no son muy utizadas.\n\n# Los sets tambien se pueden iterar.\n\nfor ss in s0:\n    print(ss)\n# 1\n# 2\n# 3\n# 4\n# 5\n\n# Se asemeja bastante a la iteracion a las listas.\n\n# Elemento len().\n\nlen(s0) # 5\n\n# El elemento len() retorna la cantidad de datos iterablescen este caso 5.\n\n# Operador de pertenencia in.\n\nif 2 in s0:\n    print(\"EL numero 2 esta en el set s0.\")\nelse:\n    print(\"El numero 2 no esta en el set s0\")\n\n# Como vimos en un reto anterior el operador in nos siver para saber si un dato esta dentro de otro.\n\n# Union o | es una forma de unir sets pero recordar que si se repite el mismo valor se eleminara hasta que solo\n# quede uno.\n\nprint(s | s0) # {1, 2, 3, 4, 5, 'Franz', 20, 'Python'}\n\n# Practicamente solo une los datos y los podemos asiganar a un nuevo set.\n\n# AL igual que append() en las listas en los sets tenemos add().\n# Con el que podemos agregar un dato a un set.\n\ns.add(6)\nprint(s) # {1, 2, 3, 4, 5, 6}\n\n# Agregara al set el dato que se ponga en el parentesis pero recordar que no se pueden anidar listas dentro de los sets.\n\n# Y de la misma forma que con las listas en elemento remove pude eliminar un dato de un set.\n\ns.remove(6)\nprint(s) # {1, 2, 3, 4, 5}\n\n# Como vimos eliminar el dato que se ponga entre los parentesis y de no encontrarlos devolvera un error key.\n\n# Elemento discard().\n\ns.discard(5)\nprint(s) # {1, 2, 3, 4}\n\n# Hace la misma funcion que el elemento remove() solo que si no encuentra el dato no devolvera ningun error.\n\n# Elemento pop().\n\ns.pop()\nprint(s) # {2, 3, 4}\n\n# Como los sets no censervan el orden con el que se definen cuando el pop elimina un dato lo hace de forma pseudoaleatoria.\n\n# Elemento clear().\n\ns.clear()\nprint(s) # set()\n\n# El elemento clear elimina todos los datos que esten dentro del set().\n\n# Otras operaciones interesantes:\n# Como obseravaremos estos funcionan poniendo un punto y el elemneto para por ultimo poner el parametro.\n# EJemplos para las operaciones.\n\ns1 = {1, 2, 3, 4, 5}\ns2 = {4, 5, 6, 7, 8}\ns3 = {7, 8, 9, 10, 11}\n\n# Union:\n\nprint(s1.union(s2)) # {1, 2, 3, 4, 5, 6, 7, 8}\nprint(s1.union(s2,s3)) # {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}\n\n# Como vemos podemos usar union para juntar dos a mas sets pero si se repiten algunos datos, estos seran eliminados hasta que quede solo uno.\n\n# Intersection:\n\nprint(s1.intersection(s2)) # {4, 5}\nprint(s1.intersection(s2,s3))  # set()\n\n# Como vemos aqui cuando queremos la interseccion de dos sets nos devuelve los datos que se repiten si ponemos mas solo nos devolvera el dato que\n# se repita todos los sets si no hay ninguno nos devuelve simplemente el tipo set por que estara vacio.\n\n# Asi hay varios elementos:\n\"\"\"\ns1.union(s2[, s3 ...])\ns1.intersection(s2[, s3 ...])\ns1.difference(s2[, s3 ...])\ns1.symmetric_difference(s2)\ns1.isdisjoint(s2)\ns1.issubset(s2)\ns1.issuperset(s2)\ns1.update(s2[, s3 ...])\ns1.intersection_update(s2[, s3 ...])\ns1.difference_update(s2[, s3 ...])\ns1.symmetric_difference_update(s2)\n\"\"\"\n# Asi como elementos hay oprtunidades de trabajar con sets.\n\n# Tuplas:\n\"\"\"\nLas tuplas son parecidas a las listas y a los sets pues almacenan datos y son inmutables osea que no se pueden modificar una vez\ncreadas como los sets estas se definen con los calsicos parentesis () y con una diferencia en que dependiendo como se usar puede ser\nde uso rapido.\n\"\"\"\n\n# Definir una tupla:\n\nTupla = (1, 2, 3)\nprint(type(Tupla)) # <class 'tuple'>\ntupla = 1, 2, 3\nprint(type(tupla)) # <class 'tuple'>\nTUpla = tuple(a)\nprint(TUpla) # ('Franz', 20, 'Python')\nprint(type(TUpla)) # <class 'tuple'>\n\n# Al poner los datos que queremos almacenar entre parentesis se clasificaran como tupla pero si solo separamos datos con comas tambein funciona.\n# y tambien podemos hacer una tupla convirtiendo un grupo de datos iterable con el comando tuple().\n\n# Modificar datos de una tupla:\n# Tupla[0] = 2 TypeError: 'tuple' object does not support item assignment\n# Como las tuplas son un tipo de dato inmutable cuando intentamos cambiar un dato de este devulve un error igual que los sets.\n\n# Anidar:\n\nTuplA = (Tupla, tupla, TUpla)\nprint(TuplA) # ((1, 2, 3), (1, 2, 3), ('Franz', 20, 'Python'))\n\n# A diferencia de los sets las tuplas si premiten anidar tuplas dentro de otras tuplas.\n\n# Iterar:\n\nfor t in TuplA:\n    print(t)\n    # (1, 2, 3)\n    # (1, 2, 3)\n    # ('Franz', 20, 'Python')\n\n# Las iteracion son normales como cualquer otro tipo de dato iterable.\n\n# Asignar:\n\nT, P, A = Tupla\nprint(T, P, A) # 1 2 3\n\n# Tambien se puede asignar datos a las variables de esta forma con las tuplas.\n\n# Caso poco utilizado:\n\nL = (4,)\nprint(type(L)) # <class 'tuple'>\n\n# Se puede definir una tupla de un solo dato es util en casos muy selectivos pero es bueno conocerlo lo mas importante es poner la coma.\n\n# Elemento count:\n\nprint(TuplA.count((1, 2, 3))) # 3\n\n# El elemento count nos permite contar el numero de datos que se repita un dato que ingresemos en el parentesis.(ojo no ingresa en tuplas anidadas)\n\n# Diccionarios:\n\"\"\"\nLos diccionarios son tipos de datos que almacenan infomacion en forma de llave y valor, estos datos se separan por dos puntos y despues\nde ello para separar cada llave y sus valores se usan las comas y estan entre llaves {} igual que los sets, Sus caracteristicas principales\nes que son dinamicos, pues se puden añadir y eliminar elementos, son indexados, pues se pueden acceder a sus valores atravez de sus keys y\nson anidados, porque se pueden poner diccionarios dentro de otros diccionarios.\n\"\"\"\n\n# Definir un diccionario:\n\nd1 = {'Nombre':'Franz', 'Edad': 19, 'Lenguaje':'Python'}\nprint(d1) # {'Nombre': 'Franz', 'Edad': 19, 'Lenguaje': 'Python'}\nprint(type(d1)) # <class 'dict'>\n\n# Como se habia explicado para separar cada llave o key de su valor o value se usan los dos puntos y para definir otro key y value es la coma.\n\n# Se puede definir un diccionario con un comando como los otros tipos de estructura de datos con dict() pero se tienen que cumplir las siguientes condiciones:\n# Deben estar anidados en una lista, deben de estar separados de a dos puede ser en tuplas.\n# Si se pueden cumplir esas dos condiciones el comando hara su funcion.\n# Pero tambien se puede definir diccionarios igualando una variable a un valor y separarlos por comas para igual otra variable dentro de\n# la funcion dict() los convertira en un diccionario.\n\n# Acceder:\n\nprint(d1['Nombre']) # Franz\nprint(d1.get('Edad')) # 19\n\n# Parecido con las listas pero aqui podemos usar las key cambio de la posicion o podemos usar el elemento get() e igualmente poner la key.\n\n# Modificar:\n\nd1['Nombre'] = 'Erick'\nprint(d1['Nombre']) # Erick\n\n# Al igual que con las listas podemos modificar sus elementos pero otra vez cambio de la posicion se usan las keys.\n\n# Asignar:\n\nd1['Ciudad'] = 'Huancayo'\nprint(d1) # {'Nombre': 'Erick', 'Edad': 19, 'Lenguaje': 'Python', 'Ciudad': 'Huancayo'}\n\n# Si ingresamos un parametro que no existe en el diccionario sera como asignar una nueva key y tambien un nuevo valor.\n\n# Iteraciones:\n\nfor i in d1:\n    print(i)\n    # Nombre\n    # Edad\n    # Lenguaje\n    # Ciudad\n\n# De esta forma solo podemos interar las keys.\n\nfor i in d1:\n    print(d1[i])\n    # Erick\n    # 19\n    # Python\n    # Huancayo\n\n# Y de esta forma podemos iterar los value.\n\nfor i, j in d1.items():\n    print(f\"{i} es {j}\")\n    # Nombre es Erick\n    # Edad es 19\n    # Lenguaje es Python\n    # Ciudad es Huancayo\n\n# Para poder iterar las keys y los valores necesitamos poner dos parametros en el bucle y tambien usar el elemento .items() en el diccionario.\n\n# Anidar diccionarios:\n\nanidada1 = {'ejem1':1,'ejem2':2}\nanidada2 = {'ejem3':3,'ejem4':4}\n\nAnidada = {'dic1':anidada1,'dic2':anidada2}\nprint(Anidada) # {'dic1': {'ejem1': 1, 'ejem2': 2}, 'dic2': {'ejem3': 3, 'ejem4': 4}}\n\nprint(Anidada['dic2']['ejem3']) # 3\n\n# Como podemos ver podemos ingresar a cualquier valor de el diccionario anidado si usamos las key como posiciones igual que con las listas.\n\n# clear:\n\nAnidada.clear()\nprint(Anidada) # {}\n\n# El elemento clear elimina todos los valores y key que tenga un diccionario.\n\n# Extencion de get(key, mensaje en caso de no existir value o key):\n\nprint(Anidada.get('Nombre', 'No se encontro value.')) # No se encontro value.\n\n# El segundo parametro solo definine un valor o dato que se mostrara si no encuentra el value no sirve para nada mas.\n\n# items:\n\nprint(type(anidada1.items())) # <class 'dict_items'>\nprint(anidada1.items()) # dict_items([('ejem1', 1), ('ejem2', 2)])\n\n# Convierte un diccionario en una clase de lista que puede ser indexada en una lista normal pero nos permite trabajar con las keys y value a la vez.\n\n# keys().\n\nprint(d1.keys())\n# dict_keys(['Nombre', 'Edad', 'Lenguaje', 'Ciudad'])\n\n# El elemento keys nos devuelve todas las keys del diccionario.\n\n# values().\n\nprint(d1.values())\n# dict_values(['Erick', 19, 'Python', 'Huancayo'])\n\n# El elemento values nos devuelve todos los valores del diccionario.\n\n# pop().\n\nprint(d1.pop('Signo', 'No se encontro la key')) # No se encontro la key\n\n# Al igual que get() con el elemento pop podemos defnir un mensaje en caso de no encotrar la key para que no salte un error.\n\n# popitem().\n\nprint(d1) # {'Nombre': 'Erick', 'Edad': 19, 'Lenguaje': 'Python', 'Ciudad': 'Huancayo'}\nd1.popitem()\nprint(d1) # {'Nombre': 'Erick', 'Edad': 19, 'Lenguaje': 'Python'}\n\n# El elemento popitem elimina un dato aleatorio del diccionario.\n\n# update()\n\nanidada1.update(anidada2)\nprint(anidada1)\n\n# Esta herramineta compara dos diccionarios y si encuentra la misma key en los dos cambia el del primer diccionario por el segundo\n# y de no encontrar la key del segundo en el primero lo creara y la asignara el mismo que el del segundo.\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n  Crea una agenda de contactos por terminal.\n - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n - Cada contacto debe tener un nombre y un número de teléfono.\n - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n   los datos necesarios para llevarla a cabo.\n - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n   (o el número de dígitos que quieras)\n - También se debe proponer una operación de finalización del programa.\n\"\"\"\nag = {}\n\ndef búsqueda ():\n    x = input(\"¿Como se llama el contacto? \")\n    if x in ag:\n        print(f\"El numero de {x} es {ag[x]}\")\n    else:\n        print(f\"El contacto {x} no existe.\")\n\ndef inserción ():\n    x = input(\"Ingrese el nombre del contacto que quiere agregar: \")\n    if x in ag:\n        print(\"\\n Ya existe un contacto con ese nombre \\n Por favor:\")\n        inserción()\n    else:\n        y = input(f\"Ingrese el numero de {x}: \")\n        while len(y) > 9:\n            print(\"El numero no puede tener mas de 9 digitos.\")\n            y = input(f\"Ingrese el numero de {x}: \")\n        print(\"  Contacto - Numero\")\n        for x, y in ag.items():\n            print(f\"  {x} - {y}\")\n\ndef actualización ():\n    x = input(\"Ingrese el nombre del contacto que quiere actualizar: \")\n    if x in ag:\n        y = input(f\"Ingrese el nuevo numero de {x} : \")\n        while len(y) > 9:\n            print(\"El numero no puede tener mas de 9 digitos.\")\n            y = input(f\"Ingrese el nuevo numero de {x} : \")\n        ag[x] = y\n    else:\n        print(\"\\n El contacto no esta en la agenda \\n Por favor:\")\n        actualización()\n\ndef eliminación ():\n    x = input(\"Ingrese el nombre del contacto que quiere elminar: \")\n    if x in ag:\n        ag.pop(x)\n        for x, y in ag.items():\n            print(f\"  {x} - {y}\")\n        print(\"El contacto esta eliminado.\")\n\n\ndef agenda ():\n    o = 1\n    while o != 'no':\n        print('Escoja la funcion que quiere hacer: \\n 1. Búsqueda \\n 2. Inserción \\n 3. Actualización \\n 4. Eliminación \\n 5. Ver_Contactos \\n 6. Salir o no.')\n        o = input('Ingrese el numero o el nombre de la operación: ')\n        if o == '1' or o == 'Búsqueda':\n            búsqueda()\n            o = input('¿Quiere hacer otra operacion? ')\n        elif o == '2' or o == 'Inserción':\n            inserción()\n            o = input('¿Quiere hacer otra operacion? ')\n        elif o == '3' or o == 'Actualización':\n            actualización()\n            o = input('¿Quiere hacer otra operacion? ')\n        elif o == '4' or o == 'Eliminación':\n            eliminación()\n            o = input('¿Quiere hacer otra operacion? ')\n        elif o == '5' or o == 'Ver_Contactos':\n            print(\"  Contacto - Numero\")\n            for x, y in ag.items():\n                print(f\"  {x} - {y}\")\n            o = input('¿Quiere hacer otra operacion? ')\n        elif o == '6' or o == 'Salir' or o == 'no':\n            o = 'no'    \n    else:\n        print(\"La funcion agenda se termino.\")\n\nagenda()\n\n# Fin."
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/GaboDev23.py",
    "content": "''' - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n- Utiliza operaciones de inserción, borrado, actualización y ordenación.\n'''\n\n'''\nListas\nOrdenados: La posición de sus datos importa\nHeterogenea: Puede almacenar distintos tipos de datos\nMutable: Se puede agregar, modificar y eliminar datos cuando quieras\n'''\nlista = [29, True, 3.1415, 'Que onda wacho', 3]\n\nprint(lista) # Mostrando todos los elementos de la lista\nprint(lista[0]) # Mostrando el primer elemento de la lista\n# print(lista[4]) # La lista tiene 4 elementos, pero empiezan desde el indice 0, así que va desde el indice 0 al 3, entonces el indice 4 no existe, por lo que genera un error\nprint(lista[-1]) # Acceder al último elemento de la lista\nprint(lista[-2]) # Acceder al penúltimo elemento de la lista\nprint(lista[1:3]) # Muestra los elementos desde el índice 1 al 3\n\n# Métodos de listas\nlista.append(3) # Agrega un elemento al final de la lista\nprint(lista)\nprint(lista.count(3)) # Cuenta la cantidad de veces que aparece un elemento en la lista\nprint(lista.index(3.1415)) # Nos muestra el índice del primer elemento encontrado en la lista\nlista.remove(3) # Elimina el elemento que tenga el valor pasado por parámetros\nprint(lista)\n\n'''\nTuplas\nOrdenados: La posición de sus datos importa\nHeterogenea: Puede almacenar distintos tipos de datos\nInmutable: No se puede agregar, modificar y eliminar datos un vez creada\n'''\ntupla = ('¿La tierra es plana?', True, False)\nprint(tupla) # Mostramos los datos de la tupla\n\n# Métodos de tuplas\nprint(tupla.count(False))\nprint(tupla.index(True))\nprint((3, )) # Tupla de un solo elemento\n\n'''\nConjuntos\nNo ordenados - No importa la posición de los datos\nHeterogeneo - Solo con datos inmutables\nMutable - Sin repetir\n'''\nprint(set([5, 2, 5, 1, 1.5])) # Puede guardar listas\nprint(set((5, 2, 5, 1, 1.5))) # Puede guardar tuplas\nprint(set('Booooenaaasssss')) # Puede guardar un string (Lo toma como un conjunto de carácteres)\nconjunto = set([1, 3, 3, 4]) # No permite datos repetidos\nprint(conjunto)\n\n# Métodos\nconjunto.add(5) # Agrega un elemento al final de la lista\nprint(conjunto)\nconjunto.remove(1)\nprint(conjunto)\n\nconjunto2 = set([5, 3, 5, 6])\nconjunto3 = set([4, 2])\nprint(conjunto, conjunto2, conjunto3)\nprint(conjunto.intersection(conjunto2)) # Intersección de conjuntos\nprint(conjunto & conjunto2) # Otra manera de obtener la intersección\nprint(conjunto2.issubset(conjunto)) # Comprueba si un elemento está incluído en otro\nprint(conjunto3.issubset(conjunto))\n\n'''\nDiccionario\n- No ordenado - No importa la posición de sus datos\n- Es heterogeneo - Con clave inmutable\n- Mutable - Se puede agregar, modificar y eliminar datos\n'''\ndiccionario = {1: 'Uno', 2: 'Dos'}\nprint(diccionario)\ndiccionario[3] = 'Tres'\nprint(diccionario)\n#Otra forma de crear diccionarios\ndict_lista_tuplas = dict([(1, 'Uno'), (2, 'Dos'), (3, 'Tres')])\ndict_lista_string = dict(Uno = 1, Dos = 2, Tres = 3)\n# La key no debe repetirse, si se repite siempre tomara el primer valor\n\n# Metodos\nprint(diccionario.keys()) # Devuelve las llaves del diccionario\nprint(diccionario.values()) # Devuelve los valores del diccionario\nprint(diccionario.items()) # Devuelve una tupla con los datos del diccionario\ndiccionario.pop(2) # Elimina la segunda clave del diccionario por lo tanto también elimina su valor\nprint(diccionario)\n\nprint()\n\n'''\nDIFICULTAD EXTRA (opcional):\nCrea una agenda de contactos por terminal.\n- Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n- Cada contacto debe tener un nombre y un número de teléfono.\n- El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación los datos necesarios para llevarla a cabo.\n- El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos. (o el número de dígitos que quieras)\n- También se debe proponer una operación de finalización del programa.\n'''\ncontactos = {'A': [], 'B': [], 'C': [], 'D': [], 'F': [], 'G': [], 'H': [], 'I': [], 'J': [], 'K': [], 'L': [], 'M': [], 'N': [], 'O': [], 'P': [], 'Q': [], 'R': [], 'S': [], 'T': [], 'U': [], 'V': [], 'W': [], 'X': [], 'Y': [], 'Z': []}\n\ndef esNumerico(num):\n    if not num.isnumeric():\n        print('El número no es de tipo numérico')\n        return False\n    elif not len(num) == 12:\n        print('El número debe tener 12 carácteres')\n        return False\n    else:\n        return True\n    \ndef buscarContacto(nombre):\n    contactoEncontrado = []\n\n    inicial = nombre[0].upper()\n    if inicial in contactos:\n        for contacto in contactos[inicial]:\n            if nombre.lower() == contacto[0].lower():\n                contactoEncontrado.append(contacto)\n    \n    return contactoEncontrado\nwhile True:\n    seleccion = input('Elige una opción.\\n1. Ingresar contacto.\\n2. Modificar contacto.\\n3. Mostrar Contactos.\\n4. Eliminar contactos.\\n0. Salir del programa.\\n')\n    match seleccion:\n        case '1':\n            print('Ingresar contacto')\n            nombre = input('Ingresa el nombre del contacto: ')\n            numero = input('Ingresa el número del contacto: ')\n            \n            if esNumerico(numero) == False:\n                break\n            \n            for clave in contactos:\n                if clave == nombre[0].upper():\n                    contactos[clave].append([nombre, numero]) \n                    print(f'Agregado: {contactos[clave]}')\n                    break\n        case '2':\n            print('Modificar contacto')\n            nombre = input('Introduce el nombre del contacto que deseas modificar: ')\n            encontrados = buscarContacto(nombre)\n            \n            if encontrados:\n                print(f\"Contacto encontrado: {encontrados}\")\n                nuevoNombre = input('Nuevo nombre (deja vacío si no quieres cambiarlo): ')\n                nuevoNumero = input('Nuevo número (deja vacío si no quieres cambiarlo): ')\n\n                for contacto in encontrados:\n                    inicial = nombre[0].upper()\n                    contactos[inicial].remove(contacto)\n                    \n                    nombreFinal = nuevoNombre if nuevoNombre.strip() else contacto[0]\n                    numeroFinal = nuevoNumero if nuevoNumero.strip() else contacto[1]\n                    nuevaInicial = nombreFinal[0].upper()\n\n                    contactos[nuevaInicial].append([nombreFinal, numeroFinal])\n                    print(\"Contacto modificado con éxito.\")\n                    print(contactos[inicial])\n            else:\n                print(\"Contacto no encontrado.\")\n        case '3':\n            for letra in contactos:\n                if contactos[letra]:\n                    print(f'\\nContactos con {letra}:')\n                    for i, contacto in enumerate(contactos[letra], 1):\n                        print(f'  {i}. Nombre: {contacto[0]}, Número: {contacto[1]}')\n        case '4':\n            print('Eliminar contacto')\n            nombre = input('Introduce el nombre del contacto que quiere eliminar: ')\n            contactoEncontrado = buscarContacto(nombre)\n            if contactoEncontrado == []:\n                print('No se encontró el contacto')\n            else:\n                print(f'Se encontró: {contactoEncontrado}')\n                confirmar = input('¿Deseas eliminar este contacto? (s/n): ').lower()\n                if confirmar == 's':\n                    for contacto in contactoEncontrado:\n                        contactos[nombre[0].upper()].remove(contacto)\n                    print('Contacto eliminado.')\n                else:\n                    print('No se eliminó el contacto')\n                print(contactos[nombre[0]])\n        case '0':\n            print('Programa cerrado')\n            break\n        case _:\n            print('Opción incorrecta, vuelva a intentarlo')"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Gallitofast.py",
    "content": "#Estructuras de datos\n\"\"\"\nListas\n\"\"\"\nMi_lista: list = [\"Gallo\", \"Jose\",\"Miguel\",\"Zuno\"]\nprint(Mi_lista)\nMi_lista.append(\"Michel\") #Inserción\nprint(Mi_lista)\nMi_lista.remove(\"Michel\") #Eliminación\nprint(Mi_lista)\nprint(Mi_lista[0]) #Acceso\nMi_lista[0] = \"Gallolobo\" #Actualización\nMi_lista.sort() #Ordenación\nprint(Mi_lista)\nprint(type(Mi_lista))\n\n\"\"\"\nTuplas\n\"\"\"\nMi_tupla: tuple = (\"Melchor\",\"Gazpar\",\"Baltazar\")\nprint(Mi_tupla[1]) #Acceso\nmy_tuple = tuple(sorted(Mi_tupla)) #Ordenación\n#Se pone tuple antes del sorted por que el sorted convierte en lista\nprint(Mi_tupla)\nprint(type(Mi_tupla))\n\n\"\"\"\nSets\n\"\"\"\nmi_set: set= {\"Gallolobo\",\"Gallitofast\",\"Tacosricos\",\"MESSI\"}\nprint(mi_set)\nmi_set.add(\"messigallito\") # Insercion\nprint(mi_set)\nmi_set.add(\"messigallito\")\nprint(mi_set)\nmi_set.remove(\"Gallolobo\") #Eliminacion\nprint(mi_set)\nmi_set = set(sorted(mi_set)) #No se puede ordenar\nprint(mi_set)\nprint(type(mi_set))\n\n\n#Diccionario\nMi_diccionario: dict = {\n    \"Nombre\": \"Jose\",\n    \"Apellido\": \"Gallo\",\n    \"Alias\": \"Gallolobo\",\n    \"edad\": \"23\"\n}\nMi_diccionario[\"email\"] = \"MessigallitoQgmail.com\" #Insercion\nprint(Mi_diccionario)\ndel Mi_diccionario[\"Alias\"] #Eliminacion\nprint(Mi_diccionario)\nprint(Mi_diccionario[\"Nombre\"])\nMi_diccionario[\"edad\"] = \"24\" #Actualizacion\nprint(Mi_diccionario)\nMi_diccionario = dict(sorted(Mi_diccionario.items()))\nprint(Mi_diccionario)\nprint(type(Mi_diccionario))\n\n\"\"\"\nExtra\n\"\"\"\ndef MI_AGENDA():\n\n    agenda = {}\n\n    def  insert_contact():\n        num_tel = input(\"Introduce el numero telefonico del contacto: \")\n        if num_tel.isdigit() and len(num_tel) > 0 and len(num_tel) <=11:\n            agenda[name] =num_tel\n        else:\n            print(\n                \"Debes introducir un número de teléfono un máximo de 11 dígitos.\")\n\n    while True:\n\n        print(\"\")\n        print(\"1. Buscar contacto\")\n        print(\"2. Insertar contacto\")\n        print(\"3. Actualizar contacto\")\n        print(\"4. Eliminar contacto\")\n        print(\"5. Salir\")\n\n        option = input(\"\\nSelecciona una opción: \")\n\n        match option:\n            case \"1\":\n                name = input(\"Introduce el nombre del contacto a buscar: \")\n                if name in agenda:    \n                    print(f\"el numero de telefono de {name} es {agenda[name]}\")\n                else:\n                    print(f\"El contacto de {name} no existe\")\n            case \"2\":\n                name = input(\"Introduce el nombre del contacto\")\n                insert_contact()\n            case \"3\":\n                name = input(\"Introduce el nombre del contacto que quieres actualizar\")\n                if name in agenda:\n                    insert_contact()\n                else:\n                    print(f\"El contacto {name} no existe.\")\n            case \"4\":\n                name = input(\"Introduce el nombre del contacto a eliminar\")\n                if name in agenda: \n                    del agenda[name]\n                else: \n                    print(f\"El contacto que buscas eliminar no existe\")\n            case \"5\":\n                print(\"Saliendo de la agenda\")\n                break\n            case _:\n                print(\"Opcion no valida. Elige una opcion del 1 al 5\")\nMI_AGENDA()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Gordo-Master.py",
    "content": "\"\"\"\nEstrutura de datos\n\"\"\"\n\n# Listas\nmy_list = []    # Constructor\nmy_other_list = list()  # Constructor\nmy_list.append(\"manzana\")   # Inserción\nmy_list.extend([\"pera\",\"uva\"])  # Inserción\nprint(my_list)\ndel my_list[1]  # Borrado\nprint(my_list)\nmy_list.remove(\"uva\")   # Borrado\nprint(my_list)\nmy_list[0] = \"lechuga\"  # Actualización\nprint(my_list)\nmy_list.extend([\"tomate\",\"queso\",\"mortadela\",\"mayonesa\"])\nprint(my_list)\nmy_list.sort()  # Ordenación\nprint(my_list)\n\n# Tuplas\nmy_tuple = ()   # Constructor\nmy_other_tuple = tuple()    # Constructor\nmy_thrith_tuple = 10, 2, 1  # Constructor\nmy_fourth_tuple = (\"Lunes\", \"Miercoles\", \"Viernes\")  # Constructor\nprint(type(my_thrith_tuple))\nprint(my_thrith_tuple[2])   # Acceso\nmy_thrith_tuple = tuple(sorted(my_thrith_tuple))    # Ordenación\nprint(my_thrith_tuple)\nprint(type(my_thrith_tuple))\n\n# Conjuntos/Sets\nmy_set = set() # Constructor\nmy_other_set = {1,\"Ottawa\",\"Roma\"}  # Constructor\nprint(my_other_set)\nmy_other_set.add(\"Madrid\")  # Inserción\nprint(my_other_set)\nmy_other_set.remove(1)  # Borrado\nprint(my_other_set)\nmy_other_set = set(sorted(my_other_set))    # No se puede ordenar por definición\nprint(my_other_set)\nprint(type(my_other_set))\n\n# Diccionarios\nmy_dict = dict()\nmy_other_dict = {}\nmy_thrith_dict = {\n    \"english\":\"hello world!\",\n    \"español\":\"¡Hola mundo!\"\n}\nprint(my_thrith_dict)\nmy_thrith_dict[\"Deutsch\"] = \"Hallo Welt\"   # Inserción\nprint(my_thrith_dict)\nmy_thrith_dict[\"Deutsch\"] = \"Hallo Welt!\"   # Actualización\nprint(my_thrith_dict)\ndel my_thrith_dict[\"Deutsch\"]   # Actualización\nprint(my_thrith_dict)\nmy_thrith_dict = dict(sorted(my_thrith_dict.items())) # Ordenación\nprint(my_thrith_dict)\nprint(type(my_thrith_dict))\n\n\n\"\"\"\nEjercicio Extra\n\"\"\"\n\ncontact_list = {}\n\ndef find_contact(name: str, contact_list: dict) -> list:\n    if name in contact_list:\n        print(f\"El numero de telefono de {name} es {contact_list[name]}\")\n    else:\n        print(f\"No existe el contacto {name}\")\n    return contact_list\n\ndef insert_contact(name: str, contact_list: dict):\n    if name not in contact_list:\n        number = input(\"Ingrese el número: \")\n        if number.isdigit() and len(number) > 0 and len(number) < 11:\n            contact_list[name] = number\n            print(f\"Contacto: {name}: {number} agregado\")\n        else:\n            print(\"Numero invalido. \\nDebes introducir un numero de telefono con un maximo de 11 dígitos\")\n    else:\n        print(\"El contacto ya existe\")\n    return contact_list\n\n\ndef refresh_contact(name: str, contact_list: dict):\n    if name in contact_list:\n        number = input(\"Ingrese el nuevo número: \")\n        if number.isdigit() and len(number) > 0 and len(number) < 11:\n            contact_list[name] = number\n            print(f\"Contacto: {name}: {number} actualizado\")\n        else:\n            print(\"Numero invalido. \\nDebes introducir un numero de telefono con un maximo de 11 dígitos\")\n    else:\n        print(\"El contacto no existe\")\n    return contact_list\n\ndef del_contact(name: str, contact_list: dict):\n    if name in contact_list:\n        del contact_list[name]\n        print(f\"Contacto: {name} eliminado\")\n    else:\n        print(\"El contacto no existe\")\n    return contact_list\n\ndef show_menu():\n    print(\"*\"*20)\n    print(\"AGENDA DE CONTACTOS.\")\n    print(\"Operaciones:\")\n    print(\"1. Buscar contacto.\")\n    print(\"2. Insertar contacto.\")\n    print(\"3. Actualizar contacto\")\n    print(\"4. Borrar contacto\")\n    print(\"5. Salir\")\n\ndef my_agenda(action=0):\n    contact_list = {}\n    \n    while True:\n        show_menu()\n        action = input(\"Opción: \") \n        match action:\n            case \"1\":\n                contact_list = find_contact(\n                    input(\"Ingrese el nombre del contacto: \"),\n                    contact_list=contact_list\n                )\n            case \"2\": \n                contact_list = insert_contact(\n                    input(\"Ingrese el nombre del contacto: \"),\n                    contact_list=contact_list\n                )\n            case \"3\": \n                contact_list = refresh_contact(\n                    input(\"Ingrese el nombre del contacto: \"),\n                    contact_list=contact_list\n                )\n            case \"4\": \n                contact_list = del_contact(\n                    input(\"Ingrese el nombre del contacto: \"),\n                    contact_list=contact_list\n                )\n            case \"5\": \n                print(\"Saliendo...\")\n                break\n            case _:\n                print(\"Valor invalido, ingrese una opción del 1 al 5\")\n        input(\"\\n\\nPulse enter para continuar\")\n\nmy_agenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/H4cker0n.py",
    "content": "\"\"\"\"\nESTRUCTURAS DE DATOS\n\"\"\"\n# LISTAS \n\nmy_list = [1, 2, 3, 4, 5]\nprint(my_list)\nmy_list.append(6) # inserción al final de la lista\nprint(my_list)\nmy_list.remove(3) # eliminación de un elemento\nprint(my_list)\nprint(my_list[2]) # acceso a un elemento por su índice\nmy_list[1] = 10 # modificación de un elemento\nprint(my_list)\n\nlist2 = [\"python\", \"java\", \"c++\"]\nlist2.sort()\nprint(list2) # ordena la lista alfabéticamente\n\n# TUPLAS\nmy_tuple = (\"carro\", \"moto\", \"bicicleta\", \"45\")\nprint(my_tuple[1])\nprint(my_tuple[3])\nmy_tuple = tuple(sorted(my_tuple))  # ordena la tupla | sorted es una función que devuelve una lista ordenada\nprint(my_tuple)  # muestra la tupla ordenada\nprint(type(my_tuple))  # muestra el tipo de dato\n\n# SETS\nset1 = {\"carro\", \"moto\", \"bicicleta\", \"45\"}\nprint(set1)\nset1.add(\"camioneta\")  # agrega un elemento al set\nprint(set1)\nset1.remove(\"carro\")  # elimina un elemento del set\nprint(set1)\nset1 = set(sorted(set1))  # ordena el set | el set no se puede ordenar \nprint(set1)  \nprint(type(set1))  # muestra el tipo de dato\n\n# DICCIONARIOS\n\nmy_dict = {\n    \"nombre\": \"Juan\",\n    \"edad\": 30,\n    \"ciudad\": \"Madrid\"\n}\nmy_dict[\"pais\"] = \"España\"  # inserción de un nuevo par clave-valor\nprint(my_dict)  \nprint(my_dict[\"nombre\"])  # acceso a un valor por su clave\nmy_dict[\"edad\"] = 31  # modificación de un valor\nprint(my_dict)\ndel my_dict[\"ciudad\"]  # eliminación de un par clave-valor\nprint(my_dict)\nmy_dict = dict(sorted(my_dict.items()))  # ordena el diccionario por sus claves | dict es una función que crea un diccionario\nprint(my_dict)  # muestra el diccionario ordenado\nprint(type(my_dict))  # muestra el tipo de dato\n\n\"\"\"\"\nESTRAS\n\"\"\"\n# Crea una agenda de contactos por terminal.\n# - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n# - Cada contacto debe tener un nombre y un número de teléfono.\n# - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n# los datos necesarios para llevarla a cabo.\n# - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n# (o el número de dígitos que quieras)\n# - También se debe proponer una operación de finalización del programa.\n \ndef main(): \n    agenda = {}\n\n    while True:\n        print(\"\\nAgenda de Contactos\")\n        print(\"1. Buscar contacto\")\n        print(\"2. Insertar contacto\")\n        print(\"3. Actualizar contacto\")\n        print(\"4. Eliminar contacto\")\n        print(\"5. Salir\")\n\n        opcion = input(\"Seleccione una opción: \")\n\n        if opcion == \"1\":\n            buscar_contacto(agenda)\n        elif opcion == \"2\":\n            insertar_contacto(agenda)\n        elif opcion == \"3\":\n            actualizar_contacto(agenda)\n        elif opcion == \"4\":\n            eliminar_contacto(agenda)\n        elif opcion == \"5\":\n            print(\"Saliendo del programa.\")\n            break\n        else:\n            print(\"Opción no válida, intente de nuevo.\")\n\ndef buscar_contacto(agenda):\n    nombre = input(\"Ingrese el nombre del contacto a buscar: \")\n    if nombre in agenda:\n        print(f\"Contacto encontrado: {nombre} - {agenda[nombre]}\")\n    else:\n        print(\"Contacto no encontrado.\")\n\ndef insertar_contacto(agenda):\n    nombre = input(\"Ingrese el nombre del contacto: \")\n    telefono = input(\"Ingrese el número de teléfono (11 dígitos máximo): \")\n\n    if validar_telefono(telefono):\n        agenda[nombre] = telefono\n        print(f\"Contacto {nombre} insertado con éxito.\")\n    else:\n        print(\"Número de teléfono no válido. Debe ser numérico y tener un máximo de 11 dígitos.\")\ndef actualizar_contacto(agenda):    \n    nombre = input(\"Ingrese el nombre del contacto a actualizar: \")\n    if nombre in agenda:\n        telefono = input(\"Ingrese el nuevo número de teléfono (11 dígitos máximo): \")\n        if validar_telefono(telefono):\n            agenda[nombre] = telefono\n            print(f\"Contacto {nombre} actualizado con éxito.\")\n        else:\n            print(\"Número de teléfono no válido. Debe ser numérico y tener un máximo de 11 dígitos.\")\n    else:\n        print(\"Contacto no encontrado.\")        \ndef eliminar_contacto(agenda):\n    nombre = input(\"Ingrese el nombre del contacto a eliminar: \")\n    if nombre in agenda:\n        del agenda[nombre]\n        print(f\"Contacto {nombre} eliminado con éxito.\")\n    else:\n        print(\"Contacto no encontrado.\")\n\ndef validar_telefono(telefono):\n    return telefono.isdigit() and len(telefono) <= 11\nif __name__ == \"__main__\":\n    main()\n    \n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/HarrisonGuerrero18.py",
    "content": "\"\"\"/*\n* EJERCICIO:\n* - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n* - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n*\n* DIFICULTAD EXTRA (opcional):\n* Crea una agenda de contactos por terminal.\n* - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n* - Cada contacto debe tener un nombre y un número de teléfono.\n* - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n*   los datos necesarios para llevarla a cabo.\n* - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n*   (o el número de dígitos que quieras)\n* - También se debe proponer una operación de finalización del programa.\n*/\"\"\"\n\n## Estructura - Listas\n\nlista = []\nprint(f\"Lista base: {lista}\")\n\n# Inserción en listas\n\nwhile True:\n    nombre = input(\"\\nIngresa tu nombre: \")\n    if nombre.replace(\" \", \"\").isalpha() and len(nombre) > 1:\n        lista.append(nombre.title())  # Inserción en la última posición de la lista\n        break\n    else:\n        print(\"Debes ingresar un nombre válido (solo letras y espacios)\")\n\nwhile True:\n    edad_input = input(\"\\nIngresa tu edad: \")\n    if edad_input.isdigit():\n        edad = int(edad_input)\n        if 0 <= edad <= 120:\n            lista.append(edad)\n            break\n        else:\n            print(\"La edad debe estar entre y 120 años\")\n    else:\n        print(\"Debes ingresar un número válido\")\n\nlenguajes_programacion = [\"Python\", \"JavaScript\", \"PHP\", \"TypeScript\", \"C\", \"C#\", \"C++\"]\nlenguajes_str = \", \".join(lenguajes_programacion)\n\nwhile True:\n    respuesta = (\n        input(\n            f\"\\n¿Usaste alguno de estos lenguajes para el reto? {lenguajes_programacion} (si/no): \"\n        )\n        .strip()\n        .lower()\n    )\n\n    if respuesta not in [\"s\", \"n\", \"si\", \"no\"]:\n        print(\"Debes responder con 's' o 'n'\")\n    elif respuesta in [\"s\", \"si\"]:\n        lenguaje_programacion = (\n            input(f\"\\nPerfecto, escribe cual de ellos usaste ({lenguajes_str}): \")\n            .strip()\n            .lower()\n        )\n\n        lenguaje_normalizados = [l.lower() for l in lenguajes_programacion]\n\n        if lenguaje_programacion in lenguaje_normalizados:\n            lista.insert(1, lenguaje_programacion)  # Inserción en la posición 1\n            break\n        else:\n            print(\"Debes ingresar uno de esos lenguajes de programación\")\n    else:\n        print(\"De acuerdo, continuaremos con el programa\")\n        break\n    \nprint(f\"\\n Lista con valores actuales: {lista}\")\n\nprint(\n    \"\"\"\n\\nOkey ahora deberás digitar uno a uno los números de tu año de nacimiento en orden.\nEjemplo: 1-9-9-1 ó 2-0-0-1       \n\"\"\"\n)\n\n\ndef pedir_digito(mensaje):\n    while True:\n        num = input(mensaje)\n        if num.isdigit() and len(num) == 1:\n            return num\n        print(\"Debes seleccionar un solo número válido\")\n\n\nnum_1 = pedir_digito(\"\\nIngresa el primer número de tu año de nacimiento: \")\nnum_2 = pedir_digito(\"\\nIngresa el segundo número de tu año de nacimiento: \")\nnum_3 = pedir_digito(\"\\nIngresa el tercer número de tu año de nacimiento: \")\nnum_4 = pedir_digito(\"\\nIngresa el cuarto número de tu año de nacimiento: \")\n\nlista.extend(\n    [\"Año de Nacimiento:\", num_1, num_2, num_3, num_4]\n)  # Agregar varios elementos\n\nprint(f\"\\nLista actualizada con año de nacimiento: {lista}\")\n\n\n# Actualización de listas\n\nwhile True:\n    nuevo_lenguaje = input(\n        \"\\nIngresa un lenguaje que te gustaría aprender (distinto al de este reto): \"\n    )\n    if nuevo_lenguaje.replace(\" \", \"\").isalpha() and len(nuevo_lenguaje) > 1:\n        lista[1] = nuevo_lenguaje\n        break\n\nprint(\n    f\"\\nLista actualizada reemplazando el lenguaje que estás usando con el que deseas aprender: {lista}\"\n)\n\n# Borrado de listas\n\nlista.clear()\nprint(f\"Lista con elementos borrados: {lista}\")\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Hyromy.py",
    "content": "\"\"\"\nlas listas son arreglos de n cantidad de elementos indeterminados\nsus elementos pueden variar y ser mutables (editables)\n\"\"\"\nlista = [55, 1.77, \"Hyromy\", True]\n\n\n\"\"\"\nlas tuplas son arreglos de una cantidad de elementos definidos\nsus elementos son inmutables (solo de lectura)\n\"\"\"\ntupla = (75, 1.70, \"Chino\", True)\n\n\n\"\"\"\nlos diccionarios son un json y ya xd\n\"\"\"\ndiccionario = {\n    \"clave\": \"valor\",\n    \"key\": \"value\"\n}\n\n\n\"\"\"\nlos conjuntos como unas listas pero sus elementos no son mutables (editables)\nsus elementos son mutables pero no puede contener elementos repetidos\n\"\"\"\nconjunto = {\"alan\", \"vale\", \"julian\", \"alan\"}\n\n\n#operaciones con listas\n#añadir elementos a una lista\nlista.append(\"Luis\")\nprint(lista)\n\n#limpiar una lista entera\nlista.clear()\nprint(lista)\n\n#copiar una lista sin hacer referencia al mismo espacio de memoria\nlista = [1, 4.4, True]\nlista_2 = lista.copy()\nprint(lista)\nprint(lista_2)\n\n#contar elementos en una lista\nlista = [1, 2, 5, 1, 7, 1, 5, 9, 1]\nprint(lista.count(1))\n\n#agregar elementos de una lista a otra\nlista = [1, 2, 3]\nextension = [4, 5, 6]\nlista.extend(extension)\nprint(lista)\n\n#encontrar el indice de un elemento especificado\nlista = [10, 20, 30, 40, 50]\nprint(lista.index(20))\n\n#insertar un elemento en un indice especifico\nlista = [1, 2, 3, 4, 5, 6, 7, 8, 9]\nlista.insert(5, 10)\nprint(lista)\n\n#eliminar un elemento\nlista = [1, 1.2, True, 'Amanda', 'Hyromy']\nborrado_1 = lista.pop() #Hyromy\nborrado_2 = lista.pop(2) # True\nprint(lista)\nprint(borrado_1)\nprint(borrado_2)\n\n#eliminar la primera aparicion de una lista\nlista = [1, 4, 7, 1, 9, 1]\nlista.remove(1)\nprint(lista)\n\n#invertir una lista\nlista = [1, 2, 3, 4, 5]\nlista.reverse()\nprint(lista)\n\n#ordenar una lista\nlista = [6, 2, 8, 3, 9, 1, 5, 4, 7]\nlista.sort()\nprint(lista)\n\nprint(\"\\n\")\n# ---- DIFICULTAD EXTRA ----\n\ncontactos = []\n\ndef crear():\n    name = input(\"Nombre del contacto => \")\n    phone = input(f\"Ingrese numero de {name} => \")\n    \n    if len(phone) != 10:\n        print(\"Numero ingresado no valido\\n\\n\")\n        menu()\n    else:\n        phone = int(phone)\n        contacto = [name, phone]\n        contactos.append(contacto)\n        print(\"Contacto registrado con exito\\n\\n\")\n        menu()\n    \ndef read():\n    name = input(\"Ingrese el nombre del contacto a buscar => \").lower()\n    for i in contactos:\n        if i[0].lower().startswith(name):\n            print(f\"{i[0]}: {i[1]}\")\n    else:\n        print(\"\\n\\n\")\n        menu()\n    \ndef update():\n    name = input(\"Escribe el nombre el contacto que quieras actualizar => \")\n    for i in contactos:\n        if i[0] == name:\n            new_name = input(f\"Escribe el nuevo nombre para {i[0]} (Deja en blanco para no modificar) => \")\n            if new_name != \"\":\n                i[0] = new_name\n                \n            new_phone = input(f\"Escribe el nuevo numero para {i[0]} (Deja en blanco para no modificar) => \")\n            if len(new_phone) != 10:\n                print(\"Numero ingresado no valido\\n\\n\")\n            else:\n                new_phone = int(new_phone)\n                i[1] = new_phone\n    else:\n        print(\"\\n\\n\")\n        menu()\n    \ndef delete():\n    name = input(\"Escribe el nombre del contacto que quieras borrar => \")\n    x = 0\n    for i in contactos:\n        if name == i[0]:\n            confirm = input(f\"Estas seguro que quieres borrar a {i[0]}: {i[1]}? (Y) (N) => \")[0:1].lower()\n            if confirm == \"y\":\n                print(f\"{name} fue eliminado\")\n                contactos.pop(x)\n        x += 1\n    else:\n        print(\"\\n\\n\")\n        menu()\n\ndef menu():\n    print(\"¿Que operacion quieres hacer?\")\n    print(\"(B) Buscar\")\n    print(\"(I) Insertar\")\n    print(\"(A) Actualizar\")\n    print(\"(E) Eliminar\")\n    print(\"(X) Salir\\n\")\n    option = input(\"=> \")[0:1].lower()\n    \n    if option == \"b\":\n        read()\n    elif option == \"i\":\n        crear()\n    elif option == \"a\":\n        update()\n    elif option == \"e\":\n        delete()\n    elif option == \"x\":\n        print(\"\")\n    else:\n        print(\"Operacion no valida\\n\\n\")\n        menu()\nmenu()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Irenetitor.py",
    "content": "#STRUCTURES\n\n#List\nmy_list = [\"Red\", \"Blue\", \"Violet\", \"Pink\", \"Green\"]\nprint(my_list)\n#Adding\nmy_list.append(\"Grey\")\nprint(my_list)\n#Insertion \nmy_list.insert(4, \"Brown\")\nprint(my_list)\n#Deletion\nmy_list.remove(\"Grey\")\nprint(my_list)\n#Update\nmy_list[2] = \"Dark blue\"\nprint(my_list)\n#Sort\nmy_list.sort() #Asc\nprint(my_list)\nmy_list.sort(reverse=True) #Desc\nprint(my_list)\n#Type\nprint(type(my_list))\nprint(hex(id(my_list)))\n'''\nOutput\n['Red', 'Blue', 'Violet', 'Pink', 'Green']\n['Red', 'Blue', 'Violet', 'Pink', 'Green', 'Grey']\n['Red', 'Blue', 'Violet', 'Pink', 'Brown', 'Green', 'Grey']\n['Red', 'Blue', 'Violet', 'Pink', 'Brown', 'Green']\n['Red', 'Blue', 'Dark blue', 'Pink', 'Brown', 'Green']\n['Blue', 'Brown', 'Dark blue', 'Green', 'Pink', 'Red']\n['Red', 'Pink', 'Green', 'Dark blue', 'Brown', 'Blue']\n<class 'list'>\n'''\n\n#Set\nmy_set = {\"Apple\", \"Banana\", \"Plum\", \"Orange\"}\nprint(my_set)\n#Adding\nmy_set.add(\"Cherry\")\nmy_set.add(\"Plum\") #It won’t be added, since sets don’t allow duplicates.\nprint(my_set)\n#Deletion\nmy_set.remove(\"Plum\")\nprint(my_set)\n#Discard\nmy_set.discard(\"Banana\")\nprint(my_set)\n#Update\nmy_set2 = {\"Kiwi\", \"Melon\", \"Raspberry\"}\nmy_set.update(my_set2)\nprint(my_set)\n#Clear(empties the set)\nmy_set2.clear()\nprint(my_set2)\n#Delete\ndel my_set2\n#Type\nprint(type(my_set))\n'''\nOutput\n0x1f4696cd900\n{'Orange', 'Apple', 'Banana', 'Plum'}\n{'Orange', 'Apple', 'Plum', 'Cherry', 'Banana'}\n{'Orange', 'Apple', 'Cherry', 'Banana'}\n{'Orange', 'Apple', 'Cherry'}\n{'Orange', 'Raspberry', 'Melon', 'Apple', 'Kiwi', 'Cherry'}\nset()\n<class 'set'>\n'''\n\n#Tuple\nmy_tuple = (\"Sara\", \"Daniel\", \"Saul\", \"Monica\")\nprint(my_tuple)\n#Access\nprint(my_tuple[3])\nprint(my_tuple[0])\n#Sort. We can use the sort() method, but it will convert our tuple into a list, so we should be aware of that.\nmy_tuple = tuple(sorted(my_tuple))\n#Type\nprint(type(my_tuple))\n'''\nOutput\n('Sara', 'Daniel', 'Saul', 'Monica')\nMonica\nSara\n<class 'tuple'>\n'''\n\n#Dictionary\nmy_dic = {\n    \"Name\":\"Oliver\", \n    \"Surname\":\"Sanchez\", \n    \"Age\":\"28\", \n    \"Email\":\"oliver@gmail.com\"\n    }\nprint(my_dic)\n#Access\nprint(my_dic[\"Name\"])\n\n#Insertion \nmy_dic[\"Pet\"] = \"Dog\"\nprint(my_dic)\n#Deletion\ndel my_dic[\"Surname\"]\nprint(my_dic)\n#Update\nmy_dic[\"Pet\"] = \"Parrot\"\nprint(my_dic)\n#Sort\nmy_dic = dict(sorted(my_dic.items()))\nprint(my_dic)\n#Type\nprint(type(my_dic))\n'''\nOutput\n{'Name': 'Oliver', 'Surname': 'Sanchez', 'Age': '28', 'Email': 'oliver@gmail.com'}\nOliver\n{'Name': 'Oliver', 'Surname': 'Sanchez', 'Age': '28', 'Email': 'oliver@gmail.com', 'Pet': 'Dog'}\n{'Name': 'Oliver', 'Age': '28', 'Email': 'oliver@gmail.com', 'Pet': 'Dog'}\n{'Name': 'Oliver', 'Age': '28', 'Email': 'oliver@gmail.com', 'Pet': 'Parrot'}\n{'Age': '28', 'Email': 'oliver@gmail.com', 'Name': 'Oliver', 'Pet': 'Parrot'}\n<class 'dict'>\n'''\n\n#Exercise\n\ndef my_agenda():\n    agenda = {}\n    def insert_contact(in_name):\n        in_phone = input(\"Enter a telephone number: \").strip()\n        if in_phone.isdigit() and 1 <= len(in_phone) <= 11:\n                agenda[in_name] = in_phone\n        else:\n                print(\"Invalid phone. Use only digits, up to 11 characters.\")\n                \n    while True:\n       \n\n        print(\"\")\n        print(\"1. Search contact\")\n        print(\"2. Insert contact\")\n        print(\"3. Update contact\")\n        print(\"4. Delete contact\")\n        print(\"5. Exit\")\n        option = input(\"\\nSelect an option: \")\n\n        match option:\n            case \"1\":\n                in_name = str(input(\"Enter the name to search for: \")).strip()\n                if in_name in agenda:\n                    print(f\"The telephone number of {in_name} is {agenda[in_name]}\")\n                else:\n                    print(f\"The contact name {in_name} does not exist.\")\n            case \"2\":\n                in_name = str(input(\"Enter a name: \")).strip()\n                insert_contact()\n            \n            case \"3\":\n                in_name = str(input(\"Enter the name to update: \")).strip()\n                if in_name in agenda:\n                    insert_contact()\n                else:\n                    print(f\"The contact name '{in_name}' does not exist.\")\n\n            case \"4\":\n                in_name = str(input(\"Enter the name to delete: \")).strip()\n                if in_name in agenda:\n                    del agenda[in_name]\n                else:\n                    print(f\"The contact name {in_name} does not exist.\")\n            case \"5\":\n                print(\"Exiting agenda\")\n                break\n            case _:\n                print(\"No valid option. Please choose an option between 1 and 5.\")\n\nmy_agenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Ivanpelu7.py",
    "content": "#* DIFICULTAD EXTRA (opcional):\n #* Crea una agenda de contactos por terminal.\n #* - Debes implementar funcionalidades de búsqueda, inserción, actualización\n #*   y eliminación de contactos.\n #* - Cada contacto debe tener un nombre y un número de teléfono.\n #* - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n #*   y a continuación los datos necesarios para llevarla a cabo.\n #* - El programa no puede dejar introducir números de teléfono no númericos y con más\n #*   de 11 dígitos (o el número de dígitos que quieras).\n #* - También se debe proponer una operación de finalización del programa.\n #*/\n\nagenda = {\n    \"Ivan\" : 625325408,\n    \"Juan\" : 634728376,\n    \"Blanca\" : 623746342,\n    \"Pepe\" : 637289476,\n    \"David\" : 671829354\n}\n\ndef buscar(nombre):\n    if nombre not in agenda:\n        return \"El contacto no existe\"\n    \n    return agenda[nombre]\n\ndef insertar(nombre, telefono):\n    agenda[nombre] = telefono\n\ndef actualizar(nombre, telefono):\n    agenda[nombre] = telefono\n\ndef eliminar(nombre):\n    agenda.pop(nombre)\n\n\nwhile True:\n    print(\"Que operacion desea realizar:\")\n    print(\"1. BUSCAR\")\n    print(\"2. INSERTAR\")\n    print(\"3. ACTUALIZAR\")\n    print(\"4. ELIMINAR\")\n    print(\"5. SALIR\")\n    opcion_elegida = int(input())\n\n    if opcion_elegida == 1:\n        nombre = input(\"Introduzca el nombre del contacto: \").capitalize()\n        print(buscar(nombre))\n\n    elif opcion_elegida == 2:\n        nombre = input(\"Introduzca el nombre del nuevo contacto: \").capitalize()\n        telefono = input(\"Introduzca el telefono: \")\n\n        if len(telefono) > 9 or not telefono.isdigit():\n            print(\"Error al introducir el telefono\")\n        else:\n            insertar(nombre, telefono)\n\n    elif opcion_elegida == 3:\n        nombre = input(\"Introduzca el nombre del contacto que quiera actualizar: \").capitalize()\n        telefono = input(\"Introduzca el nuevo telefono: \")\n        actualizar(nombre, telefono)\n\n    elif opcion_elegida == 4:\n        nombre = input(\"Introduzca el nombre del contacto que quiera eliminar: \").capitalize()\n        eliminar(nombre)\n\n    elif opcion_elegida == 5:\n        print(\"Salió del programa\")\n        break\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/JAFeito.py",
    "content": "#Solo la parte de dificultad extra\neleccion = 0\nbase = {}\ndatos = {\"Nombre\": \"\",\"Telefono\": \"\"}\n\nprint(eleccion)\nwhile eleccion != 5:\n    eleccion = int(input( f\"Indique que desa hace: \\n1-buscar\\n2-insertar\\n3-actualizar\\n4-eliminar\\n5-salir\\n\" ))\n    if eleccion == 1:\n       \n        name=input (\"Indique el nombre que desea consultar:\")\n        \n        print(base)\n    elif eleccion == 2:\n        \n        datos[\"Nombre\"] = input(\"Indique el nombre:\")\n        datos[\"Telefono\"] = input(\"Indique el telefono:\")\n        nuevo = len(base)+1\n        base =  {nuevo : datos}\n    \n    elif eleccion == 3:\n        \n        old=input(\"Indique el nombre que desa moficar:\")\n        new=input(\"Indique el nuevo nombre:\")\n        base.replace(old,new)\n\n    elif eleccion == 4:\n        borra = input(\"Indique el nombre que desa eliminar:\")\n        base.pop(borra)\n    elif eleccion == 5:\n        break\n    else:\n        print(\"Introduzca solo 1, 2, 3, 4 o 5 segun su eleccion\")\n        eleccion = input()\n\nprint(\"Gracias por usar nuestro software\")\nprint(base)\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/JAdraz.py",
    "content": "# --- DATA STRUCTURES ---\n\n# --- LISTS ---\nprint(\"\\n LISTS: Ordered mutable collectio that allows duplicate elements\")\n\nmy_list = [0, 1, 2, 3, 4, 5]\n\n# INSERT\nprint(\"\\n\\t INSERT\")\n\nmy_list.append(6) # Insert value at the end of a list\nprint(f\"\\t Insert using .append(): {my_list}\")\n\nmy_list.insert(0, -1) # .insert(position, value)\nprint(f\"\\t Insert using .insert(): {my_list}\")\n\n# DELETE\nprint(\"\\n\\t DELETE\")\nmy_list.remove(-1) # Specify value to be deleted\nprint(f\"\\t Deleting using .remove(): {my_list}\")\n\nmy_list.pop(0) # Specify index of the value to be deleted. If not, it removes the las element\nprint(f\"\\t Deleting using .pop(): {my_list}\")\n\ndel my_list[0] # Deletes the element at the specified index\nprint(f\"\\t Deleting using del: {my_list}\")\n\n# UPDATE\nprint(\"\\n\\t UPDATE\")\n\nmy_list[0] = 1 # Change the value of the position specified with the new one\nprint(f\"\\t Update using indexation: {my_list}\")\n\n# ORDER\nprint(\"\\n\\t ORDER\")\n\nmy_list.sort(reverse=True) # Ascending default, if reverse TRUE descending\nprint(f\"\\t Ordering using .sort(): {my_list}\")\n\nsorted(my_list) # Returns a new sorted list\nprint(f\"\\t Ordering using sorted: {my_list}\")\n\n\n\n\n\n# --- TUPLES ---\nprint(\"\\n TUPLES: Ordered, inmutable collection that allows duplicate elements\")\n\nmy_tuple = (1, 2, 3, 4, 5, 6)\n\n# INSERT, DELETE, UPDATE\nprint(\"\\n\\t INSERT, DELETE, UPDATE\")\n\nprint(f\"\\t Tuples are inmutable so we cannot insert, update or delete data!\")\n\n# ORDER\nprint(\"\\n\\t ORDER\")\n\nsorted(my_tuple) # Returns a new sorted list from a tuple\nprint(f\"\\t Ordering using sorted: {my_tuple} and type: {type(my_tuple)}\")\n\n\n\n\n\n# --- SETS ---\nprint(\"\\n SETS: Unordered, mutable collection with no duplcate elements\")\n\nmy_set = {1, 2, 3, 4, 5, 6}\n\n# INSERT\nprint(\"\\n\\t INSERT\")\n\nmy_set.add(7) # Adds an element to the set\nprint(f\"\\t Insert using .add(): {my_set}\")\n\nmy_set.update([8, 9, 10, 10]) # Adds several elements to the set\nprint(f\"\\t Insert using .update(): {my_set}\")\n\n# DELETE\nprint(\"\\n\\t DELETE\")\n\nmy_set.remove(10) # Removes a specific element (raises an error if the element is not found)\nprint(f\"\\t Deleting using .remove(): {my_set}\")\n\nmy_set.discard(9) # Removes a specific element (Do not raise an error if the element is not found)\nprint(f\"\\t Deleting using .discard(): {my_set}\")\n\nmy_set.pop() # Removes and returns an arbitrary element\nprint(f\"\\t Deleting using .pop(): {my_set}\")\n\nmy_set.clear() # Removes all elements from the set\nprint(f\"\\t Deleting using .clear(): {my_set}\")\n\n# UPDATE\nprint(\"\\n\\t UPDATE\")\n\nprint(\"\\t Sets are unorderes, so elements cannot be updated directly. We must remove the old element and add the new one\")\n\n# ORDER\nprint(\"\\n\\t ORDER\")\n\nprint(\"\\t Sets do not have order, so ordering is not applicable\")\n\n\n\n\n\n# --- DICTIONARIES ---\nprint(\"\\n DICTIONARIES: Unorderes, mutable collection of key-value pairs\")\n\nmy_dict = {\n    \"name\" : \"Jesus\",\n    \"surname\" : \"Adraz\",\n    \"age\" : 28,\n    \"email\" : \"adrazj96@gmail.com\"\n}\n\n# INSERT\nprint(\"\\n\\t INSERT\")\n\nmy_dict[\"phone_number\"] = \"+584140270337\" # Adds a new key-value par or updates the value if the key already exists\nprint(f\"\\t Insert using [key]: {my_dict}\")\n\n# DELETE\nprint(\"\\n\\t DELETE\")\n\nmy_dict.pop(\"email\") # Removes and returns the value associated with the key\nprint(f\"\\t Deleting using .pop(): {my_dict}\")\n\ndel my_dict[\"phone_number\"] # Deletes the key-value pair\nprint(f\"\\t Deleting using del: {my_dict}\")\n\nmy_dict.clear() # Removes all key-value pairs from the dictionary\nprint(f\"\\t Deleting using .clear(): {my_dict}\")\n\n# UPDATE\nprint(\"\\n\\t UPDATE\")\n\nmy_dict[\"email\"] = \"adrazj96@gmail.com\"\nprint(f\"\\t Update using [key]: {my_dict}\")\n\nmy_dict.update({\n    \"name\" : \"Jesus\",\n    \"surname\" : \"Adraz\",\n    \"age\" : 28,\n})\nprint(f\"\\t Update using .update(): {my_dict}\")\n\n# ORDER\nprint(\"\\n\\t ORDER\")\n\nmy_dict_2 = dict(sorted(my_dict.items(), reverse=False)) # We need to create a new dictionary variable to sort it\nprint(f\"\\t Order using sorted: {my_dict_2}\")\n\n\n\n\n\n# --- STRINGS ---\nprint(\"\\n STRINGS: Inmutable sequence of characters\")\n\nmy_string = \"Jesus\"\n\n# INSERT, DELETE, UPDATE\nprint(\"\\n\\t INSERT, DELETE, UPDATE\")\nprint(f\"\\t Strings are immutable, so elements cannot be inserted, updated, or deleted after creation. We can create a new string with the desired changes.\")\n\n# ORDER\nprint(\"\\n\\t ORDER\")\nprint(f\"\\t Strings are inherently ordered by their character sequence.\")\n\nmy_string_2 = ''.join(sorted(my_string))\nprint(f\"\\t Order using sorted: {my_string_2}\")\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\"\"\"\n\ndef my_agenda():\n\n    print(\"\\n\")\n\n    agenda = {}\n\n    while True:\n\n        print(\"1. Search contact\")\n        print(\"2. Add contact\")\n        print(\"3. Update contact\")\n        print(\"4. Delete contact\")\n        print(\"5. Exit\")\n\n        option = input(\"Choose an option: \")\n\n        match option:\n            # Search contact\n            case \"1\" :\n                name = input(\"Enter the name you want to search for: \")\n\n                if name in agenda:\n                    print(f\"The phone number of {name} is: {agenda[name]}\")\n                else:\n                    print(f\"The name {name} was not found!\")\n            \n            # Add contact\n            case \"2\" :\n                name = input(\"Enter the name: \")\n                phone_number = input(\"Enter the phone number: \")\n\n                if phone_number.isdigit() and len(phone_number) > 0 and len(phone_number) <= 11:\n                    agenda[name] = phone_number\n                else:\n                    print(\"You must enter a valid phone number less or equal than 11 digits\")\n            \n            # Update contact\n            case \"3\" :\n                name = input(\"Enter the contact name to be updated: \")\n\n                if name in agenda:\n                    phone_number = input(\"Enter the new phone number: \")\n\n                    if phone_number.isdigit() and len(phone_number) > 0 and len(phone_number) <= 0:\n                        agenda[name] = phone_number\n                else:\n                    print(f\"The contact {name} was not found\")\n            \n            # Delete contact\n            case \"4\" :\n                name = input(\"Enter the contact name to be deleted: \")\n\n                if name in agenda:\n                    del agenda[name]\n                else:\n                    print(f\"The contact {name} was not found!\")\n            \n            # Close agenda\n            case \"5\" :\n                print(\"Closing agenda!\")\n                break\n            \n            # Invalid option\n            case \"\" :\n                print(\"Option not valid. Please, choose an option from 1 to 5\")\n\nmy_agenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/JacMac45.py",
    "content": "# Estructuras de datos en Python!\n\n# Listas : las listas son estructuras para almacenar datos, estos pueden ser de cualquier tipo, inclusive\n# se pueden almacenar listas dentro una lista. Las listas son ordenadas por un índice donde el primer elemento\n# tiene el índice 0. Estas pueden tener elementos duplicados\n\n# Creación de listas.\n\nmy_list = []                                            # Lista vacía\nmy_list_numbers = [1,2,3,4,5]                           # Lista de números\nmy_list_strings = [\"Hola\", \"Python\"]                    # Lista de strings\nmy_list_several = [\"Hola\", 1,2,3, [\"Python\", \"Java\"]]   # Lista con elementos varios\n\nprint (type(my_list))            # Impresión del tipo de la variable my_list: List\nprint (my_list_numbers)\nprint (my_list_strings)\nprint (my_list_several)\nprint (my_list_several[4][1])    # Imprime el segundo elemento de la lista dentro de la lista: Java\n\n# Inserción de elementos a una lista.\n\nmy_list_numbers.insert(2,6)         # insert agrega un elemento a una posición indicada en la lista\nprint (my_list_numbers)\nother_list = [\"Hola\", \"Python\"]\nmy_list_numbers.extend(other_list)  # extend extiende la lista agregando cualquier otro tipo de esctructura\nprint (my_list_numbers)\nmy_list_numbers.append(7)           # append agrega un elemento al final de la lista\nprint (my_list_numbers)\n\n# Borrado de elementos de listas.\n\nmy_list_numbers.remove(5)  # elimina el primer elemento especificado que encuentre en la lista\nprint (my_list_numbers)\nmy_list_numbers.pop(1)     # elimina el elemento que se encuentra en la posición especificada \nprint (my_list_numbers)\ndel my_list_numbers[0]     # este tambien elimina el elemento que se encuentra en la posición especificada\nprint (my_list_numbers)\n# del my_list_numbers      # elimina lista completa\nmy_list_numbers.clear()    # vacía la lista\nprint (my_list_numbers)\n\n# Actualización de listas\n\nmy_list_strings[1]=\"Mundo\" # Actualiza el índice 1 de la lista: cambia Python por Mundo\nprint(my_list_strings)\n\n# Ordenación de listas\n\nmy_list_order = [4,65,8,4,26,95,1]\nmy_list_order.sort()                # ordena la lista en forma ascendente\nprint (my_list_order)\nmy_list_order.sort (reverse=True)   # ordena la lista en forma descendente\nprint (my_list_order)\n\n# Tuplas : Las tuplas son estructuras para almacenar datos, estas pueden ser de cualquier tipo, inclusive\n# se pueden almacenar tuplas dentro una tupla. Las tuplas son ordenadas por un índice donde el primer elemento\n# tiene el índice 0. Estas no pueden tener elementos duplicados y son inmutables\n\n# Creación de tuplas\n\nmy_tuple = ()                          \nprint (type(my_tuple))                 # Impresión del tipo de la variable my_tuple: Tuple\nmy_tuple_numbers = (1,2,3,4,5,5,5)     \nprint (my_tuple_numbers)\n\n# Accediendo a los elementos de una tupla\n\nprint (my_tuple_numbers[0])            # Imprime el primer elemento de la tupla: 1\nprint (my_tuple_numbers[1])            # Imprime el segundo elemento de la tupla: 2\nprint (my_tuple_numbers[2])            # Imprime el tercer elemento de la tupla: 3\nprint (my_tuple_numbers[3])            # Imprime el cuarto elemento de la tupla: 4\n\n# sets : Los sets son estructuras para almacenar datos, estas pueden ser de cualquier tipo, inclusive\n# se pueden almacenar sets dentro un set. Los sets son no ordenados y no pueden tener elementos duplicados\n\n# Creación de sets\n\nmy_set = {1,2,3,4,5,5,5}\nprint (type(my_set))                # Impresión del tipo de la variable my_set: Set\nprint (my_set)\n\n# Inserción de elementos a un set\n\nmy_set.add(6)                       # Agrega un elemento al set\nprint (my_set)\n\n# Borrado de elementos de un set\n\nmy_set.remove(5)                    # Elimina el primer elemento especificado que encuentre en el set\nprint (my_set)\n# my_set.remove(5)                    # Error, ya que no puede haber elementos duplicados en un set\nmy_set.discard(5)                   # Elimina el primer elemento especificado que encuentre en el set\nprint (my_set)\nmy_set.clear()                      # Elimina todos los elementos del set\nprint (my_set)\n\n# Diccionarios : Los diccionarios son estructuras para almacenar datos, estas pueden ser de cualquier tipo, inclusive\n# se pueden almacenar diccionarios dentro un diccionario. Los diccionarios son no ordenados y pueden tener elementos duplicados\n\n# Creación de diccionarios\n\nmy_dicc = {}            # Crea un diccionario vacío\nprint (type(my_dicc))\nmy_dicc_elements = {\n    \"Nombre\": \"Jac\",\n    \"Apellido\": \"Mac\",\n    \"Edad\": 20\n}\n\n# Inserción de elementos a un diccionario\n\nmy_dicc_elements[\"Profesion\"] = \"Desarrollador\" # Agrega un elemento al diccionario\nprint (my_dicc_elements)\n\n# Acceso a los elementos de un diccionario\n\nprint (my_dicc_elements[\"Nombre\"])   # Accede al primer elemento del diccionario: Jac\nprint (my_dicc_elements[\"Apellido\"])# Accede al segundo elemento del diccionario: Mac\nprint (my_dicc_elements[\"Edad\"])    # Accede al tercer elemento del diccionario: 20\n\n# Borrado de elementos de un diccionario\n\ndel my_dicc_elements[\"Profesion\"]   # Elimina el primer elemento del diccionario\nprint (my_dicc_elements)\n\n# Actualización de elementos de un diccionario\n\nmy_dicc_elements[\"Edad\"] = 21       # Actualiza el tercer elemento del diccionario\nprint (my_dicc_elements)\n\n# Ordenación de elementos de un diccionario\n\nmy_dicc_elements = {\n    \"Nombre\": \"Jac\",\n    \"Apellido\": \"Mac\",\n    \"Edad\": 20\n}\n\nmy_dicc_elements = dict(sorted(my_dicc_elements.items()))\nprint (my_dicc_elements)\nprint (type(my_dicc_elements))\nprint()\n\n# DIFICULTAD EXTRA\nprint('*************************')\nprint('*                       *')\nprint('*   AGENDA TELEFÓNICA   *')\nprint('*                       *')\nprint('*************************')\nprint()\n\ndef agenda():\n    \n    datos_agenda = {}\n    \n    while True:\n    \n        print(\"\\n1. Buscar Contacto\")\n        print(\"2. Añadir Nuevo Contacto\")\n        print(\"3. Modificar Contacto\")\n        print(\"4. Eliminar Contacto\")\n        print(\"5. Cerrar\")\n\n        operacion = input(\"\\nSeleccione la operación deseada del 1 al 5: \")\n\n        match operacion:\n            case \"1\":\n                nombre = input(\"\\nIngrese el nombre del contacto: \")\n                if nombre in datos_agenda:\n                    print(f\"El número de teléfono de {nombre} es {datos_agenda[nombre]}\")\n                else:\n                    print(\"El contacto no existe\")\n            case \"2\":\n                nombre = input(\"\\nIngrese el nombre del contacto: \")\n                telefono = input(\"\\nIngrese el telefono del contacto: \")\n                if telefono.isdigit() and len(telefono) > 0 and len(telefono) <= 11:\n                    datos_agenda[nombre] = telefono\n                else: \n                    print(\"telefono no valido, por favor escribe un teléfono máximo de 11 digitos\" )\n            case \"3\":\n                nombre = input(\"\\nIngrese el nombre del contacto a modificar: \")\n                if nombre in datos_agenda:\n                    telefono = input(\"\\nIngrese el nuevo número de teléfono: \")\n                    if telefono.isdigit() and len(telefono) > 0 and len(telefono) <= 11:\n                        datos_agenda[nombre] = telefono\n                    else:\n                        print(\"telefono no valido, por favor escribe un teléfono máximo de 11 digitos\" )\n                else:\n                    print(\"El contacto no existe\")\n            case \"4\":\n                nombre = input(\"\\nIngrese el nombre del contacto a eliminar: \")\n                if nombre in datos_agenda:\n                    del datos_agenda[nombre]\n                else:\n                    print(\"El contacto no existe\")\n                \n            case \"5\":\n                print(\"Cerrarando Agenda\")\n                break\n            case _:\n                print(\"Operación no valida. Elije una de las 5 opciones.\")\n            \n            \nagenda()         \n                \n            \n                \n            \n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Jandresalvar.py",
    "content": "'''\nEstructuras de datos integradas por defecto\n'''\n\n''' \nCadenas de texto (strings):\nLa primera estructura es también un tipo de dato, que mediante bucles, condicionales, funciones, etc. podemos recorrer cada caracter como un elemento independiente, por ejemplo:\n'''\n\nmy_string = 'Hola, Moure' \n\nprint(my_string.casefold()) # Podemos usar metodos (funciones) para manipular strings\n\n#my_string[0] = 'B' # Esto produce un error porque las cadenas son secuencias \"inmutables\" de caracteres\n\nfor letter in my_string: # Podemos recorrer una cadena mediante un bucle\n    print(letter)\n\ndef imprime_nombre(string):\n    if string.startswith('Hola'): # Condicionales\n        return string[string.find(',') + 2 :]\n\nprint(imprime_nombre(my_string))\n\ntexto = 'Python'\nnuevo_texto = texto[:2] + 'x' + texto[3:]\nprint(nuevo_texto)\n\n'''\nListas (list):\nLas listas son estructuras mutables y ordenadas que pueden contener cualquier tipo de dato, por ejemplo:\n'''\n\nmy_list = [1, 2, 3, 4, 5] #Se puede crear una lista con [] o con la funcion list()\n#Decimos que una lista es ordenada porque, aunque no lo vemos, cada elemento tiene asociado un indice que va de 0 hasta n-1, siendo n la cantidad de elementos de la lista\n\nmy_list[0] = 10 # Esto no produce errores, es perfectamente posible porque las listas son mutables\nprint(dir(my_list)) #accedemos a los metodos de un tipo de dato o estructura mediante la funcion dir\nmy_list.append(6)\nmy_list.insert(0, 1)\nmy_list.pop(1)\nprint(my_list)\n\nmy_list.sort(reverse = True)\nprint(my_list)\n\nfor num in my_list:\n    print(num)\n\nmy_list2 = (\"Hola\", 40, 33.35, True)\nmy_list.insert(3, my_list2) # Listas dentro de listas 🤯\nprint(my_list)\n\nfor i in my_list2:\n    print(i)\n\n'''\nTuplas (tuple):\nLas tuplas son muy parecidas a las listas, las diferencian principalmente tres caracteristicas, las tuplas son inmutables, no ordenadas y generalmente se usan para almacenar datos heterogeneos (no es estricto pero por convension lo es)\n'''\nmy_tuple = 1984, 2025, \"Python\"\nprint(my_tuple[1])\n\na, b, c = my_tuple\n\nmy_tuple_2 = ([9, 8, 7, 6], [6, 7, 8, 9]) #Aunque una tupla es inmutable, puede contener objetos mutables\n\nfor item in my_tuple_2:\n    for num in item:\n        print(num)\n\n \n'''\nConjuntos (set):\nEs una colección no ordenada y sin elementos duplicados. Se puede crear un conjunto con {} o la funcion set(), pero para crear un conjunto vacio no se usa {}, pues esto creará un diccionario. Los conjuntos también soportan operaciones matemáticas como la unión, intersección, diferencia, y diferencia simétrica.\n'''\n\njugadores = {\"Cristiano\", \"Messi\", \"Iniesta\", \"Xavi\", \"Messi\", \"Pele\"}\n\nprint(jugadores)\n\n\"Pele\" in jugadores\n\nbucle = {x for x in \"Parangaricutirimicuaro\" if x not in \"abc\"}\nprint(bucle)\n\ns = {1, 3}\ns.add(2)\ns.remove(1) \nsorted(s)\nprint(s)\n\n'''\nDiccionarios (dict):\nUn diccionario es muy similar a un conjunto o una lista. Sin embargo, su principal diferencia es que en lugar de usar indicer núnmericos ordenados, un diccionario utiliza como indice una \"clave\". Cada clave está asociada a un valor, por esto se les llama pares \"clave: valor\". Las claves son únicas dentro del diccionario. En escencia, los elementos de un diccionario son tuplas clave/valor.\n'''\ntelefonos = {'Andres': 3126, 'Moure': 3468, 'Python': 3249}\ntelefonos['Brais'] = 9284\nprint(telefonos)\n\ndel telefonos['Moure']\ntelefonos['Snake'] = 2087\nprint(telefonos)\n\n'Moure' not in telefonos\n'Snake' in telefonos\n\ntels = dict([('Andres', 3126), ('Python', 3249), ('Brais', 9284)])\nprint(tels)\n\nmy_dict = {x: x**2 for x in (2, 4, 6)}\nprint(my_dict)\n\nd = {'b': 2, 'a': 1}\nordenado = dict(sorted(d.items()))\nprint(ordenado)\n\n'''\nEjercicio Extra\n'''\n\ndirectorio = dict()\n\nwhile True:\n\n    print('\\n--- Agenda de Contactos ---')\n    print('Operaciones disponibles: añadir, borrar, buscar, actualizar, salir')\n\n    operacion = input('\\nIngresa la operación: ').lower()\n\n    if operacion == \"salir\": \n        print('¡Hasta luego!')\n        break\n\n    if operacion not in ('añadir', 'borrar', 'buscar', 'actualizar'):\n        print(f'Error: \"{operacion}\" no es una operación valida.')\n        continue\n\n    nombre = input('Nombre del contacto: ').strip()\n    \n    if operacion == 'buscar':\n        if nombre in directorio:\n            print(f'Teléfono: {directorio[nombre]}')\n        else:\n            print('Contacto no encontrado.')\n        continue\n        \n    if operacion == 'borrar':\n        if nombre in directorio:\n            del directorio[nombre]\n            print(f'Contacto \"{nombre}\" eliminado.')\n        else:\n            print('El contacto no existe.')\n        continue\n\n\n    telefono = input('Teléfono: ').strip()\n\n    if not telefono.isdigit():\n        print('Error: El teléfono debe contener solo números.')\n        continue\n    if len(telefono) != 10:\n        print('Error: El teléfono debe tener 10 dígitos.')\n        continue\n\n    if operacion == 'añadir' and nombre in directorio:\n        print('Error: El contacto ya existe. Usa \"actualizar\".')\n        continue\n\n    if operacion == 'actualizar' and nombre not in directorio:\n        print('Error: Contacto no encontrado. Usa \"añadir\".')\n        continue\n    \n    directorio[nombre] = telefono\n    print(f'Contacto \"{nombre}\" {\"actualizado\" if operacion == \"actualizar\" else \"añadido\"}.')\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Jav-mol.py",
    "content": "# --- Estructuras ---\n\n# Listas\nprint('--- Listas ---')\n\nmy_list = list((\"Python\", \"JavaScript\", \"Go\"))\nprint(my_list)\n\nmy_list.append(\"Php\") # -> Insercion\nmy_list.append(\"Ruby\")\nprint(my_list)\n\nmy_list.insert(0,'Typescript')\nprint(my_list)\n\nmy_list.extend(['Java', 'Rust'])\nprint(my_list)\n\nmy_list[0] = 'CSS' #-> Actualizacion\nprint(my_list)\n\nmy_list[0:2] = ['Typescript', 'Python3']\nprint(my_list)\n\nmy_list.sort(key=lambda x:len(x), reverse=True) # -> Ordenacion\nprint(my_list)\n\nmy_list.remove('JavaScript') # -> Eliminacion\nprint(my_list)\n\nmy_list.pop(0)\nprint(my_list)\n\ndel my_list[3:]\nprint(my_list)\n\nmy_list.clear()\nprint(my_list)\n\n\n# Tuples\nprint('\\n--- Tuplas ---')\n\nmy_tuple = tuple(('Samsung', 'Iphone', 'Huawei'))\nprint(my_tuple[1]) # -> Acceso\nprint(my_tuple[2])\n\nprint(sorted(my_tuple, key=lambda x:len(x))) # -> Ordenacion\n\n# Sets\nprint('\\n--- Sets ---')\n\n\nmy_set = set(('Samsung', 'Iphone', 'Huawei'))\nprint(my_set)\n\nmy_set.add('Motorola') # -> Insercion\nprint(my_set)\n\nmy_set.remove('Huawei') # -> Eliminacion\nprint(my_set)\n\nprint(sorted(my_set, reverse=True)) # -> Ordenacion\n\nmy_set.clear() # -> Eliminacion\nprint(my_set)\n\n# Diccionarios\nprint('\\n--- Diccionarios ---')\n\nmy_dict = dict({\n    'name':'Javier',\n    'surname':'Javi',\n    'age': 22,\n    'country':'Argentina'\n})\nprint(my_dict)\n\nmy_dict['name'] = 'Javier Molina' # -> Actualizacion\nprint(my_dict)\n\nmy_dict.update({'email':'javi@example.com', 'name': 'Javier'}) # -> Insercion\nprint(my_dict)\n\nmy_dict.pop('email') # -> Eliminacion\nprint(my_dict)\n\nprint(my_dict.popitem())\nprint(my_dict)\n\nmy_dict = sorted(my_dict.items()) # -< Ordenacion\nprint(my_dict)\n\n\n# --- Ejercicio --- -> Crea una agenda de contactos por terminal.\nimport json\n\nclass Contacto:\n    def __init__(self) -> None:\n        self.data = self.add_data()\n    \n    def add_data(self):\n        \"\"\" \n        Solicita al usuario que ingrese el nombre y el número de teléfono del contacto.\n\n        Returns:\n            dict: Un diccionario con el nombre y el número de teléfono del contacto.\n        \"\"\"\n        while True:\n            name: str = input('Introduce el nombre: ')            \n            phone_number: int = (input('Introduce el numero de telefono: '))\n            \n            if len(phone_number) < 9:\n                print('Ingrese un numero con mas de 9 caracteres')\n                continue\n            \n            return {'name':name, 'phone':int(phone_number)}\n        \nclass AgendaContactos:\n    cont_id:int = 0\n    contactos:dict = {} \n    \n    \n    def agregar_contacto(self):\n        \"\"\" \n        Agrega un nuevo contacto a la agenda de contactos.\n        \"\"\"\n        self.cont_id += 1        \n        contacto = Contacto()        \n        self.contactos[f'id-{self.cont_id}'] = contacto.data\n                \n                \n    def buscar_contacto(self):\n        \"\"\"\n        Busca un contanto por su ID.\n        \"\"\"\n        id:int = input('Introduce el Id: ')\n        print(self.contactos.get(f'id-{id}', 'No se encontro ningun contacto con ese ID'))\n\n    \n    def actualizar_contacto(self):\n        \"\"\" \n        Actualiza un contacto existente en la agenda de contactos.\n        \"\"\"\n        id:int = input('Introduce el ID del contacto que deseas actualizar: ')\n        \n        if f'id-{id}' not in self.contactos.keys():\n            print('Ingrese un ID valido')\n            return        \n        \n        contacto = Contacto()\n        self.contactos[f'id-{id}'] = contacto.data\n    \n        \n    def borrar_contacto(self):\n        \"\"\" \n        Elimina un contacto de la agenda de contactos.\n        \"\"\"\n        id:int = input('Introduce el ID del contacto que deseas borrar: ')\n        self.contactos.pop(f'id-{id}', None)\n    \n    \n    def listar_contactos(self):   \n        \"\"\" \n        Imprime la lista de contactos almacenados en la agenda.\n        \"\"\"       \n        print(json.dumps(self.contactos, indent=4), '\\n')\n        \n\nmenu = \"\"\"1-Agregar\n2-Buscar\n3-Actualizar\n4-Borrar\n5-Listar\n6-Salir\n-> \"\"\"\n\nagenda = AgendaContactos()\n\nfunctions = {\n    \"1\":agenda.agregar_contacto,\n    \"2\":agenda.buscar_contacto,\n    \"3\":agenda.actualizar_contacto,\n    \"4\":agenda.borrar_contacto,\n    \"5\":agenda.listar_contactos,\n    \"6\":'exit'\n}\n\nwhile True:\n    option = input(menu)    \n    function = functions.get(option)\n    if function == 'exit':\n        break    \n    elif not function:\n        print('Ingrese un valor valido')\n        continue\n    function()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/JesusAntonioEEscamilla.py",
    "content": "# #03 - Python -> Jesus Antonio Escamilla\n\n\"\"\"\nEJERCIÓ\n\"\"\"\n#---LISTA---\n# Creando Lista\nprint(\"LISTA\")\nlista = [\"Antonio\", \"Fatima\", \"Maria\", \"Lizette\"]\nprint(lista)\n# INSERCIÓN\nprint(\"INSERCIÓN\")\nlista.append(\"Rosa\")\nprint(lista)\n# ELIMINACIÓN\nprint(\"ELIMINACIÓN\")\ndel lista[2]\nprint(lista)\n# ACTUALIZACIÓN\nprint(\"ACTUALIZACIÓN\")\nlista[0] = \"Jesus\"\nprint(lista)\n# ORDENAMIENTO\nprint(\"ORDENAMIENTO\")\nlista.sort()\nprint(lista)\n\n\n#---DIRECTORIO---\n# Creando Directorio\nprint(\"DIRECTORIO\")\ndiccionario = {\n    \"Papas\": 3,\n    \"Tortas\": 5,\n    \"Queso\": 2,\n    \"Pan\": 1,\n}\nprint(diccionario)\n# INSERCIÓN\nprint(\"INSERCIÓN\")\ndiccionario[\"Pepsi\"] = 4\nprint(diccionario)\n# ELIMINACIÓN\nprint(\"ELIMINACIÓN\")\ndel diccionario[\"Papas\"]\nprint(diccionario)\n# ACTUALIZACIÓN\nprint(\"ACTUALIZACIÓN\")\ndiccionario[\"Tortas\"] = 6\nprint(diccionario)\n# ORDENAMIENTO\nprint(\"ORDENAMIENTO\")\nmi_dicc = dict(sorted(diccionario.items()))\nprint(mi_dicc)\n\n\n#---SETS---\n# Creando Set\nprint(\"SET\")\nconjunto = {\"A\", \"B\", \"C\"}\nprint(conjunto)\n# INSERCIÓN\nprint(\"INSERCIÓN\")\nconjunto.add(\"D\")\nprint(conjunto)\n# ELIMINACIÓN\nprint(\"ELIMINACIÓN\")\nconjunto.remove(\"B\")\nprint(conjunto)\n# ACTUALIZACIÓN\nprint(\"ACTUALIZACIÓN\")\nprint(\"No se puede eliminar directamente pero hay otra forma\")\nconjunto.remove(\"C\")\nconjunto.add(\"E\")\nprint(conjunto)\n# ORDENAMIENTO\nprint(\"ORDENAMIENTO\")\nprint(\"No Existe una forma de ordenamiento\")\n\n\n\n\"\"\"\nEXTRA\n\"\"\"\ndef mostrar_menu():\n    print('\\nAgenda de Contactos')\n    print('1. Insertar Contacto')\n    print('2. Buscar Contacto')\n    print('3. Actualizar Contacto')\n    print('4. Eliminar Contacto')\n    print('5. Mostrar Contacto')\n    print('6. Salir')\n\ndef validar_telefono(telefono):\n    return telefono.isdigit() and len(telefono) <= 11\n\ndef insertar_contacto(agenda):\n    nombre = input('Ingrese el nombre del contacto: ')\n    telefono = input('Ingrese el teléfono del contacto: ')\n    if validar_telefono(telefono):\n        agenda[nombre] = telefono\n        print(f'Contacto {nombre} añadido con éxito')\n    else:\n        print('Numero de telefono no valido. Debe ser numérico y tener un máximo de 10 dígitos')\n\ndef buscar_contacto(agenda):\n    nombre = input('Ingrese el numero de contacto a buscar: ')\n    if nombre in agenda:\n        print(f'Nombre: {nombre}, Teléfono: {agenda[nombre]}')\n    else:\n        print('No se encontró el contacto')\n\ndef actualizar_contacto(agenda):\n    nombre = input('Ingrese el numero de contacto a actualizar: ')\n    if nombre in agenda:\n        nuevo_contacto = input('Ingrese el nuevo numero de teléfono: ')\n        if validar_telefono(nuevo_contacto):\n            agenda[nombre] = nuevo_contacto\n            print(f'Contacto {nombre} actualizado con éxito')\n        else:\n            print('Numero de telefono no valido. Debe ser numérico y tener un máximo de 10 dígitos')\n    else:\n        print('Contacto no encontrado')\n\ndef eliminar_contacto(agenda):\n    nombre = input('Ingrese el numero de contacto a eliminar: ')\n    if nombre in agenda:\n        del agenda[nombre]\n        print(f'Contacto {nombre} eliminado con éxito')\n    else:\n        print('No se encontró el contacto')\n\ndef mostrar_todos_contactos(agenda):\n    if agenda:\n        for nombre, telefono in agenda.items():\n            print(f'Nombre: {nombre}, Teléfono: {telefono}')\n    else:\n        print('No hay contactos en la agenda')\n\ndef main():\n    agenda = {}\n    while True:\n        mostrar_menu()\n        option = input('Seleccione una Opción: ')\n        \n        if option == '1':\n            insertar_contacto(agenda)\n        elif option == '2':\n            buscar_contacto(agenda)\n        elif option == '3':\n            actualizar_contacto(agenda)\n        elif option == '4':\n            eliminar_contacto(agenda)\n        elif option == '5':\n            mostrar_todos_contactos(agenda)\n        elif option == '6':\n            print('Saliendo del Programa...')\n            break\n        else:\n            print('Opción no valida. Intente de nuevo')\nmain()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/JheisonQuiroga.py",
    "content": "\"\"\" Estructuras de datos \nSon formas de almacenar, organizar y manipular los datos en un programa\n\"\"\"\n\n# 1. Listas\n\nmy_lst = [] # Creacion de una lista\nmy_lst.append(\"Duban\") # Inserción de datos\nmy_lst.extend([\"Quiroga\", 26]) # Varios datos\nprint(my_lst)\nmy_lst.pop() # Elimina el ultimo elemento\nmy_lst.remove(\"Duban\") # Elimina un elemento en especifico\nprint(my_lst)\nmy_lst[0] = \"Duban\" # Actualizacion\nprint(my_lst)\nmy_lst = my_lst + [\"Moure\", \"Anderson\"] # Otra forma de agregar datos\nprint(my_lst)\nmy_lst.sort() # Ordenando datos, metodo sort() altera la lista ORIGINAL\nprint(my_lst)\nsecond_list = [19, 98, 6]\nsorted_list = sorted(second_list) # Funcion sorted no altera la lista original\nprint(second_list, sorted_list)\n\n# 2. Tuplas\n# Una tupla es una coleccion de datos ordenada e inmutable\n\ntpl = tuple([\"banana\", \"strawberry\", \"watermelon\", \"apple\"])\nprint(tpl)\nprint(tpl[2]) #Accediendo a los elementos\nprint(tuple(sorted(tpl))) # Ordenando una tupla, cambiando el tipo de dato\n# Eliminando un valor de una tupla\ntpl = list(tpl)\ntpl[0:1] = []\ntpl = tuple(tpl)\nprint(tpl) # ('strawberry', 'watermelon', 'apple')\n\n# Sets\n# Es una colección de datos desorganizada con datos unicos pero mutable, se pueden agregar\n# o eliminar datos pero no el valor de alguno ya que estos si son inmutables\n\nfruits = set([\"Banana\", \"Strawberry\", \"Watermelon\", \"Apple\"])\nprint(fruits)\nfruits.add(\"Grape\") # Inserción\nprint(fruits)\nfruits.remove(\"Grape\") # Borrado\nprint(fruits)\n\n# Diccionarios\n# Es una colección de datos mutable, indexado por pares (clave-valor)\n\nperson = {\n    \"name\": \"Duban\",\n    \"lastname\": \"Quiroga\",\n    \"age\": 25,\n    \"is_married\": False,\n    \"skills\": [\"Python\", \"Java\", \"Git\"]\n}\nprint(person[\"skills\"]) # Accediendo a los valores por medio de las claves\n\nperson[\"location\"] = {\"country\": \"Colombia\", \"city\": \"Bog\"} # Insercion de datos\nprint(person)\nperson[\"location\"][\"city\"] = \"bogota\" # Modificando elementos\nprint(person)\ndeleted_value = person[\"location\"].pop(\"city\") # Eliminando elementos\nprint(person, deleted_value)\nprint(dict(sorted(person.items())))\n\n\"\"\"\nEjercicio extra\n\"\"\"\n# Crear el diccionario que contenga los contactos\ncontacts = {}\n\n\ndef create_contact(name, num):\n    try:\n        num = int(num)\n        if len(str(num)) != 10 or not str(num).isdigit():\n            return f\"Número invalido\"\n        else:\n            contacts[name] = num\n            return f\"Contacto {name} agregado\"\n    except ValueError:\n        return f\"El número solo debe contener digitos.\"\n\n\ndef edit_contact():\n    name = input(\"Nombre del contacto: \")\n    edit = input(\"Que quieres actualizar (nombre/numero)?: \").lower()\n    if edit == \"numero\":\n        number = input(\"Ingresa el nuevo número: \")\n        try:\n            number = int(number)\n            if len(str(number)) == 10:\n                contacts[name] = number\n                return \"Contacto editado\"\n            else:\n                return \"Número invalido, +10 carácteres\"\n        except ValueError:\n            return \"El Número solo debe contener digitos\"\n    else:\n        new_name = input(\"Input the new name: \")\n        contacts[new_name] = contacts.pop(name)\n\ndef search_contact(name):\n    if contacts.get(name):\n        return f\"{name}, número: {contacts[name]}\"\n    else:\n        return f\"El contacto no existe\"\n\ndef delete_contact(name):\n    if name in contacts:\n        contacts.pop(name)\n        return f\"Contacto: {name} Eliminado\"\n    else:\n        return \"El contacto no existe\"\n    \n\n\n\ndef contacts_list(): \n    operacion = 0\n    print(\"Bienvenido a la lista de contactos\")\n\n    while operacion != 6:\n\n        print(\"\"\"Que Operación desea realizar:\n            1. Busqueda\n            2. Inserción\n            3. Actualización\n            4. Borrar algún contacto\n            5. Listar contactos\n            6. Salir de la lista\"\"\")\n        \n        operacion = int(input(\"Introduzca el indice de la operación: \"))\n\n        match operacion:\n            case 1:\n                name = input(\"Introduzca el nombre del contacto: \")\n                print(search_contact(name=name))\n            case 2:\n                name = str(input(\"Nombre del contacto: \"))\n                number = input(\"Número del contacto: \")\n                print(create_contact(name, number))\n            case 3:\n                print(edit_contact())\n            case 4:\n                name = input(\"Introduzca el contacto a eliminar: \")\n                print(delete_contact(name))\n            case 5:\n                for key, value in contacts.items():\n                    print(f\"{key}: {value}\")\n            case 6:\n                print(\"Saliendo de la lista de contactos...\")\n                return\n\ncontacts_list()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Jose-Luis-Lanza.py",
    "content": "# EJERCICIO:\n# - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n# - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n\n# Listas\n# Creacion\nfrutas = [\"manzana\", \"platano\", \"naranja\"]\nprint(frutas)\n\n# Acceso\nprint(frutas[1])\n\n# Inserción\nfrutas.append(\"piña\")\nprint(frutas)\n\n# Borrado\nfrutas.remove(\"platano\")\nprint(frutas)\n\n# Actualización\nprint(frutas)\nfrutas[1] = \"cereza\"\nprint(frutas)\n\n# Ordenación\nfrutas.sort()\nprint(frutas)\n\n# Tipo\nprint(type(frutas))\n\n# Tuplas\n# Las tuplas son inmutables, lo que significa que no podemos cambiar, añadir o eliminar elementos\n# una vez creada la tupla.\n\n# Creacion\npersonal_data = (\"Diego\", \"Velazco\", \"d_velazco@gmail.com\", \"25\")\nprint(personal_data)\n\n# Acceso\nprint(personal_data[2])\n\n# Ordenación\npersonal_data = tuple(sorted(personal_data))\nprint(personal_data)\n\n# Sets\n# Creacion\ncar_brands = {\"Mercedes\", \"Ferrari\", \"Audi\", \"Porsche\", \"Toyota\", \"Nissan\"}\nprint(car_brands)\n\n# Acceso\n# No se puede acceder directamente a un elemento de un set haciendo referencia a un índice o a una clave.\n\n# Inserción\ncar_brands.add(\"Pagani\")\nprint(car_brands)\n\n# Borrado\ncar_brands.remove(\"Mercedes\")\nprint(car_brands)\n\n# Actualización\n# No se puede actualizar directamente un elemento de un set, pero si se puede eliminar y añadir:\ncar_brands.remove(\"Toyota\")\ncar_brands.add(\"Subaru\")\nprint(car_brands)\n\n# Ordenación\n# No se puede ordenar\n\n# Diccionarios\n# Creacion\ncar = {\n    \"brand\" : \"Ford\",\n    \"model\" : \"Mustang\",\n    \"year\" : \"1964\"\n    }\nprint(car)\n\n# Inserción\ncar[\"motor\"] = \"V8\"\nprint(car)\n\n# Borrado\ndel car[\"motor\"]\nprint(car)\n\n# Actualización\ncar[\"year\"] = \"1969\"\nprint(car)\n\n# Ordenación\n# No se puede ordenar\n\n# DIFICULTAD EXTRA (opcional):\n# Crea una agenda de contactos por terminal.\n# - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n# - Cada contacto debe tener un nombre y un número de teléfono.\n# - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n#   los datos necesarios para llevarla a cabo.\n# - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n#   (o el número de dígitos que quieras)\n# - También se debe proponer una operación de finalización del programa.\n\ndef my_agenda():\n\n    agenda = {}\n\n    def search(contact_name):\n        try:\n            print(f\"The phone number of {contact_name} is {agenda[contact_name]}\")\n        except KeyError:\n            print(f\"The contact {contact_name} doesn't exists in the agenda.\")\n\n    def add(contact_name, contact_number):\n        if 1 <= len(contact_number) <= 11:\n            agenda[contact_name] = contact_number\n            print(\"New contact added!\")\n        else:\n            print(\"Wrong phone number, please enter a phone number of a maximum size of 11 digits.\")\n\n    def update(contact_name, contact_number):\n        if contact_name in agenda:\n            if 1 <= len(contact_number) <= 11:\n                agenda[contact_name] = contact_number\n                print(\"Contact updated successfully!\")\n            else:\n                print(\"Wrong phone number, please enter a phone number of a maximum size of 11 digits.\")\n        else:\n            print(f\"The contact {contact_name} doesn't exists in the agenda.\")\n\n    def delete(contact_name):\n        try:\n            del agenda[contact_name]\n            print(\"Contact deleted successfully!\")\n        except KeyError:\n            print(f\"The contact {contact_name} doesn't exists in the agenda.\")\n\n    while True:\n        option = input(\"Type an option: search | add | update | delete | show | exit : \").lower().strip()\n\n        if option == \"search\":\n            name = input(\"Enter contact name: \")\n            search(name)\n\n        elif option == \"add\":\n            name = input(\"Please enter a new contact name: \")\n            number = input(\"Please enter a new phone number: \")\n            add(name, number)\n\n        elif option == \"update\":\n            name = input(\"Enter a contact name to update: \")\n            number = input(\"Enter the new phone number: \")\n            update(name, number)\n\n        elif option == \"delete\":\n            name = input(\"Enter the name of the contact to delete: \")\n            delete(name)\n\n        elif option == \"show\":\n            for name, number in agenda.items():\n                print(f\"Name: {name}, Phone: {number}\")\n\n        elif option == \"exit\":\n            print(\"Closing agenda, goodbye!\")\n            break\n\n        else:\n            print(\"Wrong name option, try with: search | add | update | delete | show | exit\")\n\nmy_agenda()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/JoseAlberto13.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n\"\"\"\n\n# Metodos para estructuras de datos \n# Listas\n\nmi_lista = [\"Hola Python\", \"Esto Es\", \"Una Lista\"]\nprint(mi_lista)\n\n# Inserción\n\nmi_lista.append(\"Inserta al final\")\nprint(mi_lista)\n\nmi_lista.extend(\"FINAL\")\nprint(mi_lista)\n\nmi_lista.insert(4,\"Inserta en una posición i\")\nprint(mi_lista)\n\n# Borrado\n\nmi_lista.remove(\"Hola Python\")\nprint(mi_lista)\n\nmi_lista.pop()\nprint(mi_lista)\n\nmi_lista.pop(0)\nprint(mi_lista)\n\n\"\"\"\nmi_lista.clear()  #Este metódo elimina todos los elementos de la lista\nprint(mi_lista)\n\"\"\"\n\n# Actualización\n\nprint(mi_lista[0])\nmi_lista[0] = \"Actulizamos la lista\"\nprint(mi_lista[0])\nprint(mi_lista)\n\n# Ordenación\n\nmi_lista.sort()\nprint(mi_lista)\n\n\n# Tuplas\n\nmi_tupla = (\"José\", \"Figueroa\", \"@JoseAlberto13\", \"26\")\nprint(type(mi_tupla))\nprint(mi_tupla)\n\n# Inserción\n\ninsertar_tupla = \"Venezuela\"\nmi_nueva_tupla = mi_tupla + (insertar_tupla,) #Para evitar errores se debe incluir una coma antes o despues del elemento a añadir\nprint(type(mi_nueva_tupla))\nprint(mi_nueva_tupla)\n\n\"\"\"\nLas tuplas son inmutables, solo podemos acceder a ellas, mas no modificar su contendio después de su creación.\nPara hacer una \"inserción\" se debe crear nueva tupla, igualandola a la tupla original y sumando la variable o el dato que deseemos agregar . \n\"\"\"\n\n# Ordenación\n\nmi_nueva_tupla = tuple(sorted(mi_nueva_tupla)) #Necesario volver a definir el arreglo como tupla, ya que sorted nos devuelve una LISTA\nprint(type(mi_nueva_tupla))\nprint(mi_nueva_tupla)\n\n\n# Sets\n\nmi_set = {\"Alberto\", \"Lucena\", \"@JoseAlberto13\", \"26\"}\nprint(type(mi_set))\nprint(mi_set)\n\n# Inserción\n\nmi_set.add(\"Chile\")\nprint(mi_set)\n\n# Borrado\n\nmi_set.remove(\"Alberto\")\nprint(mi_set)\n\n\"\"\"\nSet estructura desordenada, no se puede ordenar, la ventaja es que los datos dentro de ella no se pueden duplicar.\nY para actualizar sus datos, la mejor manera es eliminar el dato que querramos reemplazar y añadir el nuevo elemento.\n\"\"\"\n\n\n# Diccionario\n\nmi_diccionario: dict = {\n    \"nombre\" : \"José\",\n    \"apellido\": \"Figueroa\",\n    \"edad\": \"26\",\n    \"nacionalidad\":\"Venezuela\"\n}\nprint(type(mi_diccionario))\nprint(mi_diccionario)\nprint(mi_diccionario[\"nacionalidad\"])\n\n# Inserción\n\nmi_diccionario[\"usuario\"] = \"JoseAlberto13\"\nprint(mi_diccionario)\nprint(type(mi_diccionario))\n\n# Borrado\n\ndel mi_diccionario[\"apellido\"]\nprint(mi_diccionario)\nprint(type(mi_diccionario))\n\n\n# Actualización\n\nmi_diccionario[\"edad\"] = \"27\"\nprint(mi_diccionario)\nprint(type(mi_diccionario))\n\n# Ordenación\n\nmi_diccionario = dict(sorted(mi_diccionario.items()))\nprint(mi_diccionario)\nprint(type(mi_diccionario))\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n\"\"\"\n    \ndef agenda():\n\n    contacto = {}\n\n    def agregar_contacto():\n        celular = (input(\"Celular: \"))\n        if celular.isdigit() and len(celular) > 0 and len(celular)<=11:\n            contacto[nombre] = celular\n        else:\n            print(\"Debes introducir número de teléfono de un máximo de 11 dígitos\")\n    \n    is_on = True\n\n    while is_on:\n        print(\"\\n1. Buscar Contacto\")\n        print(\"2. Agregar Conctacto\")\n        print(\"3. Actualizar Contacto\")\n        print(\"4. Eliminar Contacto\")\n        print(\"5. Salir\")\n\n        opcion = input(\"\\nSelecciona una opción: \")\n\n        match opcion:\n            case \"1\":\n                nombre = input(\"Introduce el nombre del contacto a buscar: \")\n                if nombre in contacto:\n                    print(f\"El número de teléfono de {nombre} es {contacto[nombre]}.\")\n                else:\n                    print(f\"El contacto {nombre} no existe.\")\n            case \"2\":\n                nombre = input(\"Nombre: \")\n                contacto[nombre] = nombre\n                agregar_contacto()\n            case \"3\":\n                nombre = input(\"Introduce el nombre del contacto a actualizar: \")\n                if nombre in contacto:\n                    print(f\"El número de teléfono de {nombre} es {contacto[nombre]}.\")\n                    agregar_contacto()\n                else:\n                    print(f\"El contacto {nombre} no existe.\")\n    \n            case \"4\":\n                nombre = input(\"Introduce el nombre del contacto a eliminar: \")\n                if nombre in contacto:\n                    del contacto[nombre]\n                else:\n                    print(f\"El contacto {nombre} no existe.\")\n            case \"5\":\n                print(\"Saliendo de la agenda\")\n                break\n            case _:\n                print(\"Operacion no válida. Elige una opción del 1 al 5.\")\nagenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/JuanDAW37.py",
    "content": "\"\"\"\n* EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto\n *   en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n *   y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n *   y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más\n *   de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.\n\"\"\"\n# Listas\nlista = [1, 'Hola']\nprint(f'Lista: {lista}')\nprint(type(lista))\nlista.append('Adios') # Añadir\nprint(f'Añadir {lista}')\nlista.remove('Hola') # Borrar\nprint(f'Borrar {lista}')\nprint(lista[0]) # Acceso\nlista[0] = \"Hasta luego\" # Actualización\nprint(f'Actualizar {lista}')\nlista.sort() # Ordenación\nprint(f'Ordenar {lista}')\n\n# Conjuntos\nconjunto = {'1', 'Hola'}\nprint(f'Conjunto: {conjunto}')\nprint(type(conjunto))\nconjunto.add('Adios') # Añadir\nprint(f'Añadir al conjunto {conjunto}')\nconjunto.remove('Adios') # Borrar\nprint(f'Borrar del conjunto {conjunto}')\n\n# Diccionarios\ndiccionario = { 'nombre':'Pepe', 'edad': 37}\nprint(f'Diccionario: {diccionario}')\nprint(type(diccionario))\ndiccionario['email'] = 'pepe37@gmail.com' # Insertar propiedad\nprint(f'Inserción de una propiedad {diccionario}')\ndiccionario['edad'] = 55 # Actualizar propiedad\nprint(f'Actualización de una propiedad {diccionario}')\ndel diccionario['edad'] # Eliminar propiedad\nprint(f'Eliminar una propiedad {diccionario}')\n\n# Tuplas, son inmutables y sus elementos deben ser todos del mismo tipo para poder ordenarlas\ntupla:tuple = ('1', 'Hola')\nprint(f'Tupla: {tupla}')\nprint(type(tupla))\nprint(tupla[0]) # Acceso\nordenada = tuple(sorted(tupla)) # Ordenación\nprint(f'Tupla ordenada: {ordenada}')\n\n# DIFICULTAD EXTRA\nprint('*************************')\nprint('*                       *')\nprint('*   AGENDA TELEFÓNICA   *')\nprint('*                       *')\nprint('*************************')\n\nagenda:dict = { }\n\ndef buscar(telefono:int):        \n    if telefono in agenda:\n        nombre = agenda[telefono]\n        return nombre\n    else:\n        print(f\"¡El teléfono {telefono} no existe!\")    \n\ndef insertar():\n    nombre = input('Introduce el nombre: ')\n    telefono = input('Introduce el telefono ')\n    if telefono.isdigit() and telefono.__len__ == 0 and telefono.__len__ > 11:\n        print('El número de teléfono debe tener entre 1 y 11 dígitos')\n    else:\n        telefono = int(telefono)\n    if telefono in agenda:\n        agenda[telefono] = nombre\n        print(f'Datos actualizados {agenda}')\n    else:\n        agenda[telefono] = nombre\n        print(f'Datos insertados {agenda}')\n\ndef borrar(telefono):    \n    if telefono in agenda:\n        del agenda[telefono]        \n    else:\n        print(f'El teléfono {telefono} no existe')\n\ndef agendar():\n    while True:\n        ope = input('¿Que quieres hacer Buscar, Insertar, Actualizar, Eliminar, Salir [ B / I / A / E / S ] ')\n        ope = ope.lower()\n        match ope:\n            case 'b':\n                telefono = int(input('Introduce el número de teléfono: '))\n                nombre = buscar(telefono)\n                if nombre is None:\n                    print('No existen datos en la agenda')\n                else:\n                    print(f'El nombre asignado al teléfono {telefono} es {nombre}')\n            case 'i':                \n                    insertar()\n            case 'a':\n                    insertar()\n            case 'e':\n                telefono = int(input('Introduce el telefono '))\n                borrar(telefono)\n            case 's':\n                print('Adios!!')\n                break   \n            case _:\n                print('¡Opción no implementada!')\nagendar()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Juanma0416.py",
    "content": "\n\"\"\"\nEstructuras\n\"\"\"\n\n# Listas\nmy_list: list = [\"Loyle\", \"Tyrone\", \"Marifroes\", \"Wesley\"] # Lista \nprint(my_list)\nmy_list.append(\"Barbatuqes\")  # Insertar elemento al final de la lista\nmy_list.append(\"Barbatuqes\")  # Insertar elemento al final de la lista\nprint(my_list)\nmy_list.remove(\"Loyle\")  # Eliminar un elemento en especifico de la lista\nprint(my_list)\nprint(my_list[1])  #  Imprimir un elemento en especifico de la lista en este caso es de la posición 1\nmy_list[1] = \"Tomoko\"  # Actualización de un elemento en especifico de la lista en este caso es de la posición 1\nprint(my_list)\nmy_list.sort()  # Ordenación de la lista en orden alfabético ascendente\nprint(my_list)\nprint(type(my_list))  # Impresión del tipo de dato de la lista\n\n# Tuplas\nmy_tuple: tuple = (\"juancho\", \"mancho\", \"@juancho\", \"28\")  # Tupla, la diferencia entre una lista y una tupla \n# es que la tupla es inmutable, es decir, no se puede modificar\nprint(my_tuple[1])  # Aquí imprimimos el elemento en la posición 1 de la tupla\nprint(my_tuple[3])  # Aquí imprimimos el elemento en la posición 3 de la tupla\nmy_tuple = tuple(sorted(my_tuple))  # Aquí lo que hacemos es ordenar la tupla en orden alfabético ascendente y \n# convertirla en una tupla, osea que se pierde la inmutabilidad de la tupla ya que al hacer sorted() \n# se crea una lista ordenada y luego se convierte en una tupla con tuple()\nprint(my_tuple)\nprint(type(my_tuple))  # Impresión del tipo de dato de la tupla\n\n# Sets\nmy_set: set = {\"juancho\", \"mancho\", \"@juancho\", \"28\"}  # Set, es para almacenar elementos únicos, es decir, no permite duplicados\nprint(my_set)\nmy_set.add(\"loyle@gmail.com\")  # Inserción, si se intenta insertar un elemento que ya existe, no se inserta\nmy_set.add(\"loyle@gmail.com\")\nprint(my_set)\nmy_set.remove(\"juancho\")  # Eliminación, si se intenta eliminar un elemento que no existe, se lanza un error\nprint(my_set)\nmy_set = set(sorted(my_set))  # Ordenación, se \nprint(my_set)\nprint(type(my_set))  # Impresión del tipo de dato del set\n\n# Diccionario\nmy_dict: dict = {\n    \"name\": \"Juancho\",\n    \"surname\": \"Mancho\",\n    \"alias\": \"@juancho\",\n    \"age\": \"28\"\n}  # Diccionario, es para almacenar pares clave-valor, es decir, cada valor tiene una clave asociada\nmy_dict[\"email\"] = \"loyle@gmail.com\"  # Aquí insertamos un nuevo par clave-valor \nprint(my_dict)\ndel my_dict[\"surname\"]  # Aquí eliminamos un par clave-valor\nprint(my_dict)\nprint(my_dict[\"name\"])  # Aquí accedemos a un valor mediante su clave\nmy_dict[\"age\"] = \"28\"  # Aquí actualizamos un valor mediante su clave\nprint(my_dict)\nmy_dict = dict(sorted(my_dict.items()))  # Ordenación, se ordena el diccionario en orden alfabético ascendente\nprint(my_dict)\nprint(type(my_dict))  # Impresión del tipo de dato del diccionario\n\n\"\"\"\nExtra\n\"\"\"\n\n\ndef my_agenda(): # Procedemos con la creación de una agenda para practicar con los diccionarios\n\n    agenda = {} # Creamos un diccionario vacío\n\n    def insert_contact(): # Procedemos con la creación de una función para insertar contactos\n        phone = input(\"Introduce el teléfono del contacto: \") # Pedimos el teléfono del contacto\n        if phone.isdigit() and len(phone) > 0 and len(phone) <= 11: # Validamos que el teléfono sea un número y que tenga entre 1 y 11 dígitos\n            agenda[name] = phone # Insertamos el contacto en el diccionario\n        else:\n            print(\n                \"Debes introducir un número de teléfono un máximo de 11 dígitos.\") # Mensaje de error\n\n    while True: # Procedemos con la creación de un bucle infinito para mostrar el menú y que se rompa cuando el usuario elija la opción 5\n\n        print(\"\") # Salto de línea\n        print(\"1. Buscar contacto\") # Opción 1\n        print(\"2. Insertar contacto\") # Opción 2\n        print(\"3. Actualizar contacto\") # Opción 3\n        print(\"4. Eliminar contacto\") # Opción 4\n        print(\"5. Salir\") # Opción 5\n\n        option = input(\"\\nSelecciona una opción: \") # Pedimos al usuario que elija una opción\n\n        match option: # Procedemos con la creación de un match para que el usuario elija una opción\n            case \"1\":\n                name = input(\"Introduce el nombre del contacto a buscar: \") # Pedimos el nombre del contacto a buscar\n                if name in agenda: # Validamos que el contacto exista\n                    print(\n                        f\"El número de teléfono de {name} es {agenda[name]}.\") # Mostramos el número de teléfono del contacto\n                else:\n                    print(f\"El contacto {name} no existe.\") # Mensaje de error\n            case \"2\":\n                name = input(\"Introduce el nombre del contacto: \") # Pedimos el nombre del contacto\n                insert_contact() # Insertamos el contacto\n            case \"3\":\n                name = input(\"Introduce el nombre del contacto a actualizar: \") # Pedimos el nombre del contacto a actualizar\n                if name in agenda: # Validamos que el contacto exista\n                    insert_contact() # Insertamos el contacto\n                else:\n                    print(f\"El contacto {name} no existe.\") # Mensaje de error\n            case \"4\":\n                name = input(\"Introduce el nombre del contacto a a eliminar: \") # Pedimos el nombre del contacto a eliminar\n                if name in agenda: # Validamos que el contacto exista\n                    del agenda[name] # Eliminamos el contacto\n                else:\n                    print(f\"El contacto {name} no existe.\") # Mensaje de error\n            case \"5\": # Opción 5\n                print(\"Saliendo de la agenda.\") # Mensaje de despedida\n                break\n            case _:\n                print(\"Opción no válida. Elige una opción del 1 al 5.\") # Mensaje de error\n\n\nmy_agenda() # Llamamos a la función\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/KevinED11.py",
    "content": "import dataclasses\nfrom typing import Protocol, Optional, Callable, NamedTuple\n\n\ndiccionario = {\"nombre\": \"Kevin\", \"apellido\": \"Elias\", \"edad\": 23}\ndiccionario[\"direccion\"] = \"Calle falsa 123\"\ndiccionario[\"edad\"] = 24\ndel diccionario[\"direccion\"]\nprint(dict(sorted(diccionario.items(), key=lambda x: x[0])))\n\nlista = [1, 2, 3, 4, 5]\nlista += [6, 7, 8, 9, 10]\nlista.append(11)\nlista.extend([12, 13, 14, 15, 16])\nlista.insert(0, 0)\nlista.remove(0)\nlista.pop()\nlista.clear()\n\ntupla = (1, 2, 3, 4, 5)\nfist_tuple_element = tupla[0]\n\nconjunto = {1, 2, 3, 4, 5}\nconjunto.add(6)\nconjunto.update({7, 8, 9, 10})\nconjunto.remove(6)\nconjunto.discard(7)\nconjunto.pop()\nprint(conjunto)\n\n\n@dataclasses.dataclass\nclass PersonalInfo:\n    name: str\n    phone: str\n\n\nclass AgendaManager(Protocol):\n    contacts: dict[str, PersonalInfo] = {}\n    running: bool = False\n\n    def show(self) -> None:\n        ...\n\n    def add(self, name: str, info: dict) -> None:\n        ...\n\n    def remove(self, name: str) -> None:\n        ...\n\n    def update(self, name: str, info: dict) -> None:\n        ...\n\n    def search(self, name: str) -> Optional[PersonalInfo]:\n        ...\n\n    def print_menu(self) -> None:\n        ...\n\n    def start(self) -> None:\n        ...\n\n\ndef show_contact_manager_menu() -> None:\n    print(\"1. Show contacts\")\n    print(\"2. Add contact\")\n    print(\"3. Remove contact\")\n    print(\"4. Update contact\")\n    print(\"5. Search contact\")\n    print(\"6. Exit\")\n\n\ndef user_input(prompt: str) -> str:\n    return input(prompt)\n\n\ndef is_valid_phone_number(phone: str) -> bool:\n    return phone.isdigit() and 9 < len(phone) <= 11\n\n\nclass SetupMessages(NamedTuple):\n    choose_an_option: str = \"Choose an option: \"\n    invalid_phone_number: Callable = lambda phone: f\"Invalid phone number: {phone}\"\n    contact_not_found: Callable = lambda name: f\"Contact {name} not found\"\n    contact_updated: Callable = lambda name: f\"Contact {name} updated\"\n    contact_added: Callable = lambda name: f\"Contact {name} added\"\n    contact_removed: Callable = lambda name: f\"Contact {name} removed\"\n    contact_already_exists: Callable = lambda name: f\"Contact {name} already exists\"\n    invalid_operation: str = \"Invalid operation, choose a valid option from the menu\"\n    game_already_running: str = \"Game already running\"\n    game_not_running: str = \"Game not running\"\n\n\nclass GameAlreadyRunningException(Exception):\n    pass\n\n\n@dataclasses.dataclass\nclass ContactManager:\n    setup_messages: SetupMessages\n    contacts: dict[str, PersonalInfo] = dataclasses.field(default_factory=dict)\n    running: bool = dataclasses.field(default=False)\n\n    def show(self) -> None:\n        for name, info in self.contacts.items():\n            print(f\"{name}: {info}\")\n\n    def add(self, name: str, info: PersonalInfo) -> None:\n        if self.search(name) is not None:\n            print(self.setup_messages.contact_already_exists)\n            return\n\n        if not is_valid_phone_number(info.phone):\n            print(self.setup_messages.invalid_phone_number(info.phone))\n            return\n\n        self.contacts[name] = info\n\n    def remove(self, name: str) -> None:\n        if self.search(name) is None:\n            print(self.setup_messages.contact_not_found)\n            return\n\n        del self.contacts[name]\n\n    def update(self, name: str, info: PersonalInfo) -> None:\n        current_contact_info = self.search(name)\n        if current_contact_info is None:\n            print(self.setup_messages.contact_not_found)\n            return\n\n        if not is_valid_phone_number(info.phone):\n            print(self.setup_messages.invalid_phone_number(info.phone))\n            return\n\n        current_contact_info_dict = dataclasses.asdict(current_contact_info)\n        for key, new_value in dataclasses.asdict(info).items():\n            if current_contact_info_dict[key] != new_value:\n                setattr(current_contact_info, key, new_value)\n\n        self.contacts[name] = current_contact_info\n\n    def search(self, name: str) -> Optional[PersonalInfo]:\n        return self.contacts.get(name, None)\n\n    def print_menu(self) -> None:\n        show_contact_manager_menu()\n\n    def __exit(self) -> bool:\n        return self.__is_running()\n\n    def __is_running(self) -> bool:\n        return self.running\n\n    def __get_menu_options(self) -> dict[str, Callable]:\n        return {\n            \"1\": self.show,\n            \"2\": self.add,\n            \"3\": self.remove,\n            \"4\": self.update,\n            \"5\": self.search,\n            \"6\": self.__exit,\n        }\n\n    def start(self) -> None:\n        if self.__is_running():\n            raise GameAlreadyRunningException(self.setup_messages.game_already_running)\n\n        self.running = True\n        options_menu = self.__get_menu_options()\n        exit = True\n\n        while self.__is_running():\n            self.print_menu()\n            user_option = user_input(prompt=self.setup_messages.choose_an_option)\n\n            if options_menu[user_option] == exit:\n                break\n\n            if user_option not in options_menu:\n                print(self.setup_messages.invalid_operation)\n                continue\n\n            options_menu[user_option]()\n\n\ndef main(manager: AgendaManager) -> None:\n    manager.start()\n\n\nif __name__ == \"__main__\":\n    manager: AgendaManager = ContactManager(setup_messages=SetupMessages())\n    main(manager=manager)\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Lazar171717ech.py",
    "content": "## 1. ESTRUCTURAS DE DATOS ##\n\n# Listas #\nlista: list = [1, 3, 5, 7, 9] # Aquí creamos una lista. Esta contiene varios datos que pueden ser de distintos tipos\n\nprint(f\"Esta es mi lista: {lista}\")\n\nlista.append(11) # Con el método append estamos añadiendo el dato que nosotros le demos.\nprint(f\"Hemos añadido el 11: {lista}\")\n\nlista.remove(5) # Con el método remove estamos eliminando el dato que nosotros le demos.\nprint(f\"Hemos eliminado el 5: {lista}\")\n\nlista[2] = 13 # Podemos asignar a contenidos de la lista otros datos mediante su posición.\nprint(f\"Hemos cambiado la 3ra posición: {lista}\")\n\nlista.sort() # Con el método sort estamos ordenando los contenidos de la lista en orden numérico o alfabético.\nprint(f\"Hemos ordenado la lista: {lista}\")\n\n# Tuplas #\ntupla: tuple = (0, 2, 4, 6, 8) # A diferencia de las listas, las tuplas no se pueden variar.\n\nprint(f\"Accedemos a la tupla: {tupla[3]}\") # Estamos accediendo a los datos de la tupla\n\nprint(f\"Podemos también concatenar varias tuplas: {tupla + (10, 12, 14)}\") # Al igual que las listas.\n\n# Diccionarios #\ndiccionario: dict = {1: 2, 3: 4, 5: 6, 7: 8} # Aquí guardamos varios datos y asociamos otro a cada uno de ellos.\n# De esta manera, cuando hagamos referencia al primer dato dentro del diccionario, estaríamos haciendo referencia a su asociado.\n\nprint(f\"Nos devuelve los valores asociados: {diccionario.values()}\") \nprint(f\"Podemos acceder al diccionario de varias maneras: {diccionario.get(1)}, {diccionario[1]}\")\nprint(f\"Podemos eliminar del diccionario: {diccionario.pop(1)}\") \nprint(f\"Podemos actualizar el diccionario: {diccionario.update()}\")\n\nprint(diccionario)\n\n\n## 2. RETO EXTRA ##\n\n\ncontactos: list = []\n\nwhile True:\n    commando: str = input(\"\\nComandos:\\nshow\\nsearch\\nadd\\nchange\\nexit\\n> \")\n\n    if commando == \"show\":\n\n        for i in contactos:\n            print(f\"Nombre : {i[0]}, Teléfono: {i[1]}\")\n\n    elif commando == \"search\":\n\n        busqueda: str = input(\"buscar > \")\n        founded: bool = False\n        for i in contactos:\n            if busqueda in [i[0], str(i[1])]:\n                print(f\"Nombre : {i[0]}, Teléfono: {i[1]}\")\n                founded = True\n        if not founded: print(\"No hay resultados\")\n\n    elif commando == \"add\":\n\n        nombre: str = input(\"name\\n> \")\n        tel: str = input(\"tel\\n> \")\n\n        if tel.isdigit() and len(tel) == 11:\n            tel: int = int(tel)\n            contactos.append([nombre, tel])\n            print(f\"Usuario {nombre} añadido\")\n\n        else: print(\"Telefono erroneo\")\n\n    elif commando == \"change\":\n\n        busqueda: str = input(\"buscar > \")\n        founded: bool = False\n        position: int = 0\n        for i in contactos:\n            if busqueda in [i[0], str(i[1])]:\n                founded = True\n                position = contactos.index(i)\n        if not founded: print(\"No hay resultados\")\n        nombre: str = input(\"name\\n> \")\n        tel: str = input(\"tel\\n> \")\n\n        if tel.isdigit() and len(tel) == 11:\n            tel: int = int(tel)\n            contactos[position] = [nombre, tel]\n            print(f\"Usuario {nombre} actualizando\")\n        \n\n    elif commando == \"exit\":\n        print(\"Adiós!\")\n        break\n\n    else: print(\"Comando desconocido\")\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Leonardo-Henao.py",
    "content": "\"\"\"\nEJERCICIO:\n    - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n    - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n\"\"\"\n\n# region Ejercicio simple\n\n\ndef my_print(\n    arg, title: str = '', space: int = 20, symbol: str = \"-\", color: str = None\n):\n    \"\"\"\n    Imprime el dato recibido anticipando una linea horizontal para su separación.\n\n    Parameters\n    ---\n    arg: Cualquier dato a imprimir por consola\n    title: Titulo para identificar cada separación\n    space: Cantidad de espacios o symbol a dibujar\n    symbol: Símbolo a agregar para alinear\n    \"\"\"\n    all_colors = {\n        'blue': \"\\033[1;34m{}\\033[0m\",\n        'yellow': \"\\033[1;33m{}\\033[0m\",\n        \"cyan\": \"\\033[1;36m{}\\033[0m\",\n        \"white\": \"\\033[1;0m{}\\033[0m\",\n        \"red\": \"\\033[1;31m{}\\033[0m\",\n    }\n\n    if not color or not color in all_colors.keys():\n        color_print = all_colors['blue']\n    else:\n        color_print = all_colors[color]\n\n    print(color_print.format(symbol * space + title))\n    if not arg == None:\n        print(arg)\n\n\ndef lists():\n    \"\"\"\n    Listas\n\n    Sintaxis\n    ---\n    nombre_var = [datos]\n\n    Características\n    ---\n    - Permiten modificar los elementos después de creada la lista.\n    - Permite insertar multiples tipos de datos en una sola lista. Ej: [enteros, booleanos, string...]\n    - Permite datos repetidos. Ej: [1, 50, 50, 3]\n    \"\"\"\n\n    # Ejemplos\n    my_numbers_list = [1, 2, 3, 4]\n    my_string_list = [\"H\", \"o\", \"l\", \"a\"]\n    my_mix_list = [1, \"Hola\", True]\n\n    # Yo utilizare esta para los siguientes puntos inserción, borrado, actualización y ordenación\n    my_list = [x for x in range(20)]  # la sentencia crea una lista de 20 elementos\n    my_print(my_list, \"Creación de lista\")\n\n    # region Inserción\n    # - Insertion al final de la lista\n    my_list.append(180)\n    my_print(my_list, \"Inserción al final de la lista\")\n\n    # - Inserción en posición indicada\n    my_list.insert(3, 250)\n    my_print(my_list, \"Inserción en la posición indicada de la lista\")\n\n    # endregion\n\n    # region Borrado\n    # - Borrar el elemento al final de la lista\n    my_list.pop()\n    my_print(my_list, \"Borrado del ultimo elemento\")\n\n    # - Borrar un elemento en la posición indicada y lo retorna(el elemento eliminado)\n    item_eliminated = my_list.pop(4)\n    my_print(item_eliminated, \"Borrado elemento en posición, retorna elemento borrado\")\n\n    # endregion\n\n    # region Actualización\n    # - Debes pasar la posición, en este caso (-1) estoy actualizando la ultima posición. Ej: my_list[2] = 450\n    my_list[-1] = 450\n    my_print(my_list, \"Actualización ultima posición\")\n    # endregion\n\n    # region Ordenamiento\n    # - Ordenamiento por defecto (ascendente)\n    my_list.sort()\n    my_print(my_list, \"Ordenamiento por defecto (ascendente)\")\n\n    # - Ordenamiento personalizado (creare otra lista)\n    new_list = [\n        {\"name\": \"Carlos\", \"age\": 30},\n        {\"name\": \"Marina\", \"age\": 21},\n        {\"name\": \"Raquel\", \"age\": 34},\n        {\"name\": \"Juan\", \"age\": 18},\n    ]\n\n    new_list.sort(key=lambda x: x['age'])\n    my_print(new_list, \"Ordenamiento personalizado, orden de edad\")\n\n    # - Ordenamiento personalizado descendente\n    new_list.sort(key=lambda x: x['age'], reverse=True)\n    my_print(new_list, \"Ordenamiento personalizado, Descendente\")\n\n    # endregion\n\n\ndef tuples():\n    \"\"\"\n    Tuples\n\n    Sintaxis\n    ---\n    nombre_var = (datos)\n\n    Características\n    ---\n    - No permite modificación después de su creación\n    - Son mas ligeras en memoria que las listas\n    - Permite insertar multiples tipos de datos en una sola lista. Ej: [enteros, booleanos, string...]\n    - Permite datos repetidos. Ej: [1, 50, 50, 3]\n    \"\"\"\n    my_tuple = (1, 2, 3, \"Hola\", 3)\n    my_print(my_tuple, \"Creación de tupla\")\n\n\ndef sets():\n    \"\"\"\n    Conjuntos\n\n    Sintaxis\n    ---\n    - Conjunto con datos:\n\n            nombre_var = {datos}\n\n    - Conjunto de datos vació:\n\n            nombre_var = set()\n\n    Características\n    ---\n    - Datos desordenados\n    - No permite datos duplicados\n    - No se pueden actualizar posiciones (pero se puede agregar y eliminar)\n    - Su creación vacía debe ser con set() no con {} ya que este ultimo creara otro tipo de dato(diccionario)\n    - Permite insertar multiples tipos de datos en una sola lista. Ej: [enteros, booleanos, string...]\n    - El orden en que se añaden los elementos puede cambiar\n    - Al crear un conjunto con set y pasarle como argumento una lista, la iterara y dejara solamente los elementos que no estén repetidos\n    \"\"\"\n\n    # region Creación\n    # Este sera el conjunto que utilizare para los siguientes ejemplos de Inserción...\n    my_set = {1, 2, 3, 4, \"Hola\"}\n    my_print(my_set, \"Creación de conjunto\")\n\n    var_to_add = \"leonardohenao.com\"\n\n    # Creo un nuevo conjunto con set. Creara el conjunto vació para después agregar elementos\n    my_new_set = set()\n    my_print(my_new_set, \"Creación de conjunto con función set()\")\n\n    # Creo un conjunto con set y le paso una variable la cual iterara\n    my_new_set_with_var = set(var_to_add)\n    my_print(\n        my_new_set_with_var,\n        \"Creación de conjunto pasando una variable con un string (leonardohenao.com)\",\n    )\n\n    my_other_new_set = set([1, 3, 5, 6, 1, 5])\n    my_print(my_other_new_set, \"Creación de conjunto con lista y datos repetidos\")\n\n    # endregion\n\n    # region Inserción\n    my_set.add(56)\n    my_set.add(\"Carro\")\n    # Nota en la impresión del conjunto que no se agrego este nuevo valor\n    my_set.add(56)\n    # Este nuevo \"carro\" lo toma como un nuevo elemento. Distingue de mayúsculas o minúsculas\n    my_set.add(\"carro\")\n    # Analiza como se agrega esta variable en un set cuando ya esta creado\n    my_set.add(var_to_add)\n\n    my_print(my_set, \"Inserción elementos en conjunto\")\n\n    # endregion\n\n    # region Borrado\n    # - En este caso, pop() elimina el primer elemento del conjunto\n    my_set.pop()\n    my_print(my_set, \"Eliminación con pop(). Primer elemento, si, primero\")\n\n    # - Eliminar un elemento en especifico\n    my_set.remove(var_to_add)\n    my_print(my_set, f\"Eliminación de un elemento en especifico. {var_to_add}\")\n\n    # endregion\n\n    # Actualización(elemento o posición) y ordenamiento no son posibles\n\n\ndef dictionaries():\n    \"\"\"\n    Diccionarios\n\n    Sintaxis\n    ---\n    my_dict = {\"key_name\": value}\n\n    Características\n    ---\n    - Permite datos de tipo llave:valor (tipo JSON)\n    - Palabras llave únicas\n    \"\"\"\n\n    # region Creación\n    my_dict = {\n        \"name\": \"Teodoro\",\n        \"age\": 23,\n        \"address\": \"CO\",\n        \"website\": \"leonardohenao.com\",\n    }\n    my_print(my_dict, \"Creación de diccionario\")\n\n    # endregion\n\n    # region Inserción\n    my_dict['height'] = 1.78\n    my_print(my_dict, \"Inserción de elementos\")\n    # endregion\n\n    # region Borrado\n    # - pop requiere la llave a eliminar y regresa el valor eliminado\n    data_removed = my_dict.pop('address')\n    my_print(my_dict, \"Borrado de elemento con pop(). (address)\")\n    my_print(data_removed, space=0)\n    # - del elimina sin mas el dato y la llave seleccionada\n    del my_dict[\"age\"]\n    my_print(my_dict, \"Borrado de elemento con del. (age)\")\n\n    # endregion\n\n    # region Actualización\n    my_dict[\"name\"] = \"Leonardo Henao\"\n    my_print(my_dict, \"Actualización de datos. (name)\")\n\n    # endregion\n\n    # region Ordenamiento\n    # sorted retorna una lista de las llaves ordenadas alfabéticamente\n    keys_from_my_list = sorted(my_dict)\n    new_dict = {}\n    for k in keys_from_my_list:\n        new_dict[k] = my_dict[k]\n\n    my_print(None, \"Ordenamiento ascendente\")\n    my_print(keys_from_my_list, \"Llaves del diccionario ordenadas\", space=5)\n    my_print(new_dict, \"Nuevo diccionario ordenado\", space=5)\n\n    # endregion\n\n\n\"\"\"\n# Pilas\n    Las pilas son un concepto de datos de estructura lineal.\n    LIFO: Donde el ultimo dato en ingresar es el primero en salir.\n    FIFO: Donde el primer dato en ingresar es el primero en salir.\n\n    Para el ejemplo cree una clase llamada MyStack a la cual voy a dotar con las funciones/métodos que yo o mi equipo utilizara,\n    también puedes utilizar queue de la librería de python, yo no la utilizare para que se vea el concepto un poco mas claro.\n\n    Al crear nuestra propia clase también controlamos las funciones/métodos a utilizar ya que por lo regular la lista es privada y la modificación de dicha lista debe ser interna de la clase, también optimizamos el uso de la memoria.\n\"\"\"\n\n\nclass MyStack:\n    def __init__(self, data: list):\n        self.__my_data = data\n\n    def pop(self):\n        pass\n\n    def push(self, new_data):\n        self.__my_data.append(new_data)\n\n    def size(self):\n        return len(self.__my_data)\n\n\n# region Pilas (LIFO [Last in - First out])\nclass MyStackLifo(MyStack):\n    def __init__(self, data: list):\n        super().__init__(data)\n\n    def pop(self):\n        \"\"\"\n        Elimina el ultimo elemento de la lista y lo retorna\n        \"\"\"\n        return self._MyStack__my_data.pop()\n\n\ndef stack_lifo():\n    \"\"\"\n    Para LIFO se crea adicional una clase que implementa MyStackLifo la cual tiene el método pop con el funcionamiento indicado(eliminar el ultimo elemento de la lista).\n    \"\"\"\n    my_stack = MyStackLifo([\"Carlos\", \"Maria\", \"Juan\", \"Pedro\"])\n    my_print(my_stack._MyStack__my_data, \"Creación de pila LIFO\")\n\n    # region Inserción\n    my_stack.push(\"Leonardo\")\n    my_print(my_stack._MyStack__my_data, \"Insertando datos a pila LIFO\")\n\n    # endregion\n\n    # region Borrar\n    my_stack.pop()\n    my_print(my_stack._MyStack__my_data, \"Borrado de elemento de pila LIFO\")\n\n    # endregion\n\n    # Actualización y ordenamiento no son aconsejables dentro de las pilas, si utilizas la librería de python por defecto no tendrás estos métodos\n\n\n# endregion\n\n\n# region Pilas (FIFO [First in - First out])\nclass MyStackFifo(MyStack):\n    def __init__(self, data: list):\n        super().__init__(data)\n\n    def pop(self):\n        \"\"\"\n        Elimina el primer elemento de la lista y lo retorna\n        \"\"\"\n        assert self.size != 0\n        return self._MyStack__my_data.pop(0)\n\n\ndef stack_fifo():\n    \"\"\"\n    Para FIFO se crea adicional una clase que implementa MyStackFifo la cual tiene el método pop con el funcionamiento indicado(eliminar el primer elemento de la lista).\n    \"\"\"\n    my_stack = MyStackFifo([\"request1\", \"request2\", \"request3\"])\n    my_print(my_stack._MyStack__my_data, \"Creación de pila FIFO\")\n\n    # region Inserción\n    stack_length = my_stack.size()\n    my_stack.push(f\"request{stack_length+1}\")\n    my_print(my_stack._MyStack__my_data, \"Inserción de datos a la pila FIFO\")\n    # endregion\n\n    # region Eliminación\n    try:\n        # my_stack.pop()\n        # my_stack.pop()\n        # my_stack.pop()\n        my_stack.pop()\n    except:\n        pass\n    finally:\n        my_print(my_stack._MyStack__my_data, \"Eliminación de datos de la pila FIFO\")\n\n    # endregion\n\n    # Actualización y ordenamiento no son aconsejables dentro de las pilas, si utilizas la librería de python por defecto no tendrás estos métodos\n\n\n# endregion\n\n# Quitar el comentario a la función del tipo de dato que desea revisar\n# lists()\n# tuples()\n# sets()\n# dictionaries()\n# stack_lifo()\n# stack_fifo()\n\n# endregion\n\n# region Ejercicio dificultad extra\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\nCrea una agenda de contactos por terminal.\n    - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n    - Cada contacto debe tener un nombre y un número de teléfono.\n    - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación los datos necesarios para llevarla a cabo.\n    - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos (o el número de dígitos que quieras).\n    - También se debe proponer una operación de finalización del programa.\n\"\"\"\n\n\n# Agenda\nclass PhoneBook:\n    def __init__(self):\n        self.__phone_book = [\n            {\"name\": \"Carlos\", \"phone_number\": 89098},\n            {\"name\": \"Marcos\", \"phone_number\": 98780},\n            {\"name\": \"Mariela\", \"phone_number\": 23654},\n            {\"name\": \"Mouredev\", \"phone_number\": 911},\n        ]\n\n    def insert_data(self, name: str, phone_number: int):\n        \"\"\"\n        Agrega un nuevo contacto\n\n        Parameters\n        ---\n        name: Nombre del nuevo contacto\n        phone_number: Numero de teléfono del nuevo contacto\n        \"\"\"\n        self.__phone_book.append({\"name\": name, \"phone_number\": phone_number})\n\n    def remove_data(self, id: int):\n        \"\"\"\n        Elimina un contacto\n\n        Parameters\n        ---\n        id: Posición del contacto en la lista\n        \"\"\"\n        self.__phone_book.pop(id)\n\n    def update_data(self, id, name=None, phone=None):\n        \"\"\"\n        Selecciona un elemento de la agenda con la posición (id) y actualiza el dato que no sea null en los parámetros\n\n        Parameters\n        ---\n        id: Posición del contacto\n        name: Nuevo nombre del contacto\n        phone: Nuevo numero del contacto\n        \"\"\"\n        if name:\n            self.__phone_book[id]['name'] = name\n\n        if phone:\n            self.__phone_book[id]['phone_number'] = phone\n\n    def search(self, name: str):\n        \"\"\"\n        Busca un contacto por su nombre, también retorna las coincidencias con el nombre\n\n        Parameters:\n        ---\n        name: Nombre o fragmento del nombre de un contacto\n\n        Return\n        ---\n        list : Contactos encontrados o lista vacía\n        \"\"\"\n        result = []\n        for i, x in enumerate(self.__phone_book):\n            if (x['name'].lower()).find(name.lower()) == 0:\n                result.append({\"id\": i, **x})\n\n        return result\n\n    def get_all(self):\n        \"\"\"\n        Obtiene una lista de todos los contactos guardados\n        \"\"\"\n        return self.__phone_book\n\n    def size(self):\n        \"\"\"\n        Obtiene el tamaño de la lista de los contactos\n        \"\"\"\n        return len(self.__phone_book)\n\n\nmy_phone_book = PhoneBook()\n\nmax_length_phone_number = 5\n# Lista de los contactos encontrados\ncontacts_selected = []\n\n\ndef print_all_phonebook():\n    \"\"\"\n    Imprime todos los contactos guardados en la agenda\n    \"\"\"\n    my_print(None, title=\"Contactos\", color='yellow', space=4)\n    for i, c in enumerate(my_phone_book.get_all()):\n        my_print(\n            None,\n            title=f\"{i} | \\t Nombre: {c['name']} \\t Teléfono: {c['phone_number']}\",\n            space=2,\n            symbol=' ',\n            color=\"white\",\n        )\n\n\ndef print_a_phonebook(**arg):\n    \"\"\"\n    Imprime los datos de un contacto seleccionado\n\n    Parameters\n    ---\n    **arg : Diccionario con datos del contacto a imprimir\n    \"\"\"\n    my_print(\n        None,\n        title=f\"{arg['id']} | \\t Nombre: {arg['name']} \\t Teléfono: {arg['phone_number']}\",\n        space=2,\n        symbol=' ',\n        color=\"white\",\n    )\n\n\ndef remove_contact(id_: int):\n    \"\"\"\n    Elimina un contacto\n\n    Parameter\n    ---\n    id_ : ID del contacto\n    \"\"\"\n    my_phone_book.remove_data(id_)\n    my_print(None, title=\"Contacto eliminado correctamente 🚩\", space=4, color=\"yellow\")\n\n\ndef my_print_error(message: str):\n    \"\"\"\n    Muestra en consola un error\n\n    Parameters\n    ---\n    message: Mensaje del error\n    \"\"\"\n    my_print(None, title=message, space=0, color=\"red\")\n\n\ndef show_menu():\n    \"\"\"\n    Muestra el menu principal\n    \"\"\"\n    my_print(\n        None, title=f\"Bienvenido(a) a tu agenda telefónica 📱\", space=0, color=\"cyan\"\n    )\n    my_print(\n        None,\n        title=\"[1] Ver todos tus contactos \\n  [2] Buscar un contacto \\n  [3] Agregar un contacto \\n  [0] Cerrar\",\n        space=2,\n        color='white',\n        symbol=' ',\n    )\n\n\ndef show_menu_search_contact():\n    \"\"\"\n    Muestra el menu para buscar un contacto por su nombre\n    \"\"\"\n    global contacts_selected\n\n    my_print(None, title=\"Buscar contactos\", color='yellow', space=4)\n    to_search = input(\"Ingresa el nombre o parte del nombre del contacto: \")\n    contacts_selected = my_phone_book.search(to_search)\n\n    if not contacts_selected:\n        my_print(\n            None,\n            title=\"No se encontró un contacto con ese nombre\",\n            space=4,\n            color='yellow',\n        )\n    else:\n        my_print(\n            None,\n            title=\"Contactos encontrados:\",\n            space=4,\n            color='yellow',\n        )\n\n        for x in contacts_selected:\n            print_a_phonebook(**x)\n\n        show_submenu_contact()\n\n\ndef show_menu_editar(id_contact: int):\n    \"\"\"\n    Muestra el menu para editar un contacto\n\n    Parameters\n    ---\n    id_contact: ID del contacto previamente seleccionado\n    \"\"\"\n    my_print(\n        None,\n        title=\"Puedes ingresar [0] para dejar el dato como esta 😇\",\n        space=4,\n        color=\"yellow\",\n    )\n    new_name = input(\"Ingresa el nuevo nombre: \")\n    new_num = None\n\n    while True:\n        try:\n            input_num = int(\n                input(\n                    f\"Ingresa el nuevo numero (mínimo y máximo {max_length_phone_number} caracteres): \"\n                )\n            )\n\n            if input_num == 0:\n                break\n            elif len(str(input_num)) != max_length_phone_number:\n                raise ValueError\n            else:\n                new_num = input_num\n                break\n\n        except ValueError:\n            my_print_error(\"Valor ingresado invalido 💀 \")\n\n    my_phone_book.update_data(\n        id_contact, new_name if new_name != '0' else None, new_num if new_num else None\n    )\n    my_print(None, title=\"Contacto editado correctamente 😎\", space=4, color=\"yellow\")\n\n\ndef show_submenu_contact():\n    \"\"\"\n    Muestra el submenu con las opciones para editar o eliminar un contacto\n    \"\"\"\n    ids_contact_selected = [x['id'] for x in contacts_selected]\n    my_print(\n        None,\n        title=\"Opciones disponibles: \\n [1] Editar [2] Eliminar [3] Regresar al menu principal\",\n        color=\"yellow\",\n        space=0,\n    )\n\n    try:\n        option_submenu = int(input(\"Selecciona una opción:\"))\n\n        # Editar contacto\n        if option_submenu == 1:\n            while True:\n                contact_selected = int(\n                    input(\"Selecciona el ID del contacto a editar: \")\n                )\n                if not contact_selected in ids_contact_selected:\n                    my_print_error(\"ID seleccionado invalido 💀 \")\n                    continue\n\n                show_menu_editar(contact_selected)\n                break\n\n        # Eliminar contacto\n        elif option_submenu == 2:\n            while True:\n                contact_selected = int(\n                    input(\"Selecciona el ID del contacto a eliminar: \")\n                )\n                if not contact_selected in ids_contact_selected:\n                    my_print_error(\"ID seleccionado invalido 💀 \")\n                    continue\n\n                remove_contact(contact_selected)\n                break\n        elif option_submenu == 3:\n            pass\n        elif not option_submenu == 1 or not option_submenu == 2:\n            raise ValueError()\n\n    except ValueError:\n        my_print_error(\"Opción seleccionada invalida 💀\")\n        show_submenu_contact()\n\n\ndef show_menu_add_contact():\n    \"\"\"\n    Muestra el menu para agregar un contacto\n    \"\"\"\n    my_print(None, title=\"Agregar nuevo contacto\", color='yellow', space=4)\n    new_name = None\n    new_num = None\n\n    while True:\n        name = input(\"Ingresa el nuevo nombre: \")\n        if len(name) == 0:\n            my_print_error(\"El nombre no puede estar vació\")\n            continue\n        else:\n            new_name = name\n            break\n\n    while True:\n        input_num = input(\n            f\"Ingresa el nuevo numero de teléfono (mínimo y máximo {max_length_phone_number} caracteres): \"\n        )\n\n        if len(input_num) != max_length_phone_number:\n            my_print_error(\n                f\"El numero de teléfono no puede estar vació y debe tener {max_length_phone_number} caracteres\"\n            )\n        else:\n            try:\n                new_num = int(input_num)\n            except:\n                my_print_error(\"Valor ingresado invalido (solo números) 💀 \")\n                continue\n            else:\n                break\n\n    my_phone_book.insert_data(new_name, new_num)\n    my_print(None, title=\"Contacto agregado correctamente 🗽\", space=4, color=\"yellow\")\n\n\ndef start_app():\n    while True:\n        show_menu()\n\n        try:\n            option_selected = 0\n            try:\n                option_selected = int(input(\"Selecciona una opción: \"))\n            except ValueError:\n                my_print_error(\"Opción seleccionada invalida 💀\")\n                continue\n\n            if option_selected == 1:\n                print_all_phonebook()\n\n            if option_selected == 2:\n                show_menu_search_contact()\n\n            if option_selected == 3:\n                show_menu_add_contact()\n\n            if option_selected == 0:\n                my_print(\n                    None,\n                    title=\"👋 Hasta la proxima!\",\n                    space=0,\n                    color='cyan',\n                )\n                break\n        except KeyboardInterrupt:\n            my_print(\n                None,\n                title=\"👋 Hasta la proxima!\",\n                space=0,\n                color='cyan',\n            )\n            exit()\n\n\nstart_app()\n\n# endregion\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Lio7master.py",
    "content": "# EJERCICIO:\n# - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n# - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n#\n# DIFICULTAD EXTRA (opcional):\n# Crea una agenda de contactos por terminal.\n# - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n# - Cada contacto debe tener un nombre y un número de teléfono.\n# - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n#   los datos necesarios para llevarla a cabo.\n# - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n#   (o el número de dígitos que quieras)\n# - También se debe proponer una operación de finalización del programa.\n\n#Una estructura es una forma de organizar datos.\n\n#Lista es la primera estructura de datos, pueden separarse en otros lenguajes entre listas y arrays.\n\nmy_list: list = [\"Leo\", \"Ari\", \"Chava\", \"Steph\", \"Juan\"] #Se cuenta desde la posicion 0, en este caso es del 0 al 5\n\nprint(type(my_list))\nprint(my_list)\n\nmy_list.append(\"Poncho\")#Insercion de un dato nuevo\n\nprint(my_list)\n#El orden de una lista/array normalmente es el orden de inserción de cada uno de los elementos.\nmy_list.remove(\"Leo\")\nprint(my_list)\n\nprint(my_list[4])  #Accesamos a la lista en la posicion 4\nmy_list[4] = \"Dylan\" #Actualizamos la lista en la posicion 4\nprint(my_list)\n\nmy_list.sort() #ordenamos en este caso son strings, el sistema por default los ordenara alfabeticamente\nprint(my_list)\n\nmy_list_number = [5,6,3,7,5,8,9,4,2,1] #declaro una lista de numeros para comprobar en el caso de numerico como se ordenan lo elementos.\n\nmy_list_number.sort()# por default el sistema los ordena de menor a mayor\nprint(my_list_number)\nprint(\"--------------\")\n\n#Las tuplas es una estructura de datos donde se pueden igual que en la lista se pueden guardar varios datos, pero no pueden ser modificados por lo que son mas seguras.\n#solo se puende hacer operaciones de acceso.\nmy_tupla: tuple = (\"Leo\", \"Lio7master\", \"@lio7\", \"31\")\nprint(type(my_tupla))\n\nprint(my_tupla[0])\nprint(my_tupla[1])\nprint(my_tupla[2])\nprint(my_tupla[3])\n\nsorted_list = sorted(my_tupla)#Una funcion predefinida del sistema, y nos lo ordenara mientras los datos sean el mismo tipo de dato, \n#pero sorted nos devolviendo un objeto que es una Lista.\n\n#solo declare la variable sorted para demostrar como se transforma la tupla a una lista ordenada en este caso.\nprint(sorted_list)\nprint(type(sorted_list))\n\n#Ahora que tenemos la lista, para volver el manejo a una tupla que es manejada debemos indicar el casteo de la misma.\nmy_tupla = tuple(sorted_list)\nprint(my_tupla)\nprint(type(my_tupla))\nprint(\"--------------\")\n#Las tuplas en casos es eficiente porque desde su definicion es un espacio de memoria reservado que no cambiara, lo que perminte un manejo eficiente.\n\n#SET's son estructuras desordenodas, optimas para guardar y recorrer muchos datos, pero no para acceder a los mismos.\n# son estructuras optimas, todas las estructuras son hash para que sean faciles de manejar.\n\nmy_set = {\"Leo\", \"Lio7master\", \"@lio7\", \"31\"} # Por definicion el set no se puede ordenar\nprint(type(my_set))\n\nmy_set.add(\"correo@dominio.com\")\nmy_set.add(\"correo@dominio.com\") #La estructura es optimizada, lo que permite  que no se ingresen valores duplicados.\nprint(my_set)\n#print(my_set[0]) No hay operacion de acceso, Generaria error porque no tiene sentido solicitar una posicion porque no sabemos si encontraremos algo en ella.\n\nmy_set.remove(\"Leo\")#Eliminamos\nprint(my_set)\n\nmy_set = set(sorted(my_set))\nprint(my_set)\nprint(type(my_set))\nprint(\"--------------\")\n\n#my_set.update() #No significa que actualiza un dato, sino que amplia los datos que ya tenemos en el set con otros.\n#para actualizar un dato, deberiamos eliminar el valor y insertar el actualizado.\n\n#Dicionario, se genera como un set pero debemos declararlo con una clave valor, en python los diccionarios son ordenado por concepto.\n\nmy_dict: dict = {\n    \"name\":\"leonardo\", \n    \"alias\": \"Lio7master\", \n    \"age\": \"36\", \n    \"ocupation\": \"dev\"\n    }\nprint(type(my_dict))\nprint(my_dict)\n\nprint(my_dict[\"name\"])#Al ser un diccionarion debemos acceder por medio de la clave para optener el valor.\n\nmy_dict[\"email\"] = \"correo@dominio.com\" #Insertamos el nuevo valor en la clave nueva.\nprint(my_dict)\nmy_dict[\"age\"] = \"31\" #Actualizamos indicando diretamente cual es la clave que deceamos modificar, en caso que no existirea se insertaria.\nprint(my_dict)\n\ndel my_dict[\"name\"] #Para este tipo de datos, directamente ocuparemos la operacion del reservada de python para realizar la eliminacion de un elemento del diccionario.\nprint(my_dict)\n\nfail_sort = sorted(my_dict) # Esto oredenara la lista pero destructivamente, porque se quedara con las claves mas no ordenara los valores.\nprint(fail_sort)\ntuplas_order_dict = sorted(my_dict.items()) #ahora al indicar items que es una operacion de los diccionarios,\n#sort accedera a los valores y los ordenara como se espera, sinembargo es debulto como una lista de tuplas. \nprint(tuplas_order_dict)\nprint(type(tuplas_order_dict))\nmy_dict = dict(tuplas_order_dict)\nprint(my_dict)\nprint(type(my_dict))\nprint(\"--------------\")\n\n#EXTRA! Agenda...\n\ndef my_agenda():\n\n    agenda = {}\n    def insert_contac(name):\n        phone = input(\"\\nIntroduce el telefono del contacto: \")\n        if phone.isdigit() and len(phone) == 10:\n            agenda[name]= phone\n    #is_runing = True #puede hacerce con una bandera\n    while True:\n        print(\"\")\n        print(\"1. Buscar contacto\")\n        print(\"2. Insert contacto\")\n        print(\"3. Actualizar un contacto\")\n        print(\"4. Elimina un contacto\")\n        print(\"5. Salir\")\n\n        option = input(\"\\nSelecciona una opcion: \")\n        #pass # es una condicion logica de python que permite saltar una opcion del switch/match\n        match option:\n            case \"1\":\n                name = input(\"\\nBusca el nombre del contacto: \")\n                if name in agenda:\n                    print(f\"\\nNombre contacto: {name}\")\n                    print(f\"Numero de telefono: {agenda[name]}\")\n                else:\n                    print(f\"No existe {name}\")\n            case \"2\":\n                name = input(\"\\nInserta el nombre del contacto: \")\n                insert_contac(name)\n            case \"3\":\n                name = input(\"\\nNombre del contacto a actualizar: \")\n                if name in agenda:\n                    insert_contac(name)\n                else:\n                    print(\"No existe el contacto\")\n            case \"4\":\n                name = input(\"\\nNombre del contacto a eliminar: \")\n                if name in agenda:\n                    print(f\"Se eliminara a {name}... \\n\")\n                    check = input(\"Seguro? ingresa SI \")\n                    if check == \"SI\":\n                        del agenda[name]\n                    else:\n                        print(\"Eliminacion abortada.\")\n                else:\n                    print(f\"No existe {name}\")\n            case \"5\":\n                print(\"Saliendo de la agenda\")\n                break\n            case _:\n                print(\"Opcion no valida. Elige del 1 al 5\")\n\nmy_agenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Lioomx.py",
    "content": "\n''' Las estructuras de datos son una forma de organizar y \nalmacenar datos de manera que podamos acceder y modificarlos \nde manera eficiente.\nAlgunos ejemplos comunes de estructuras de datos son \nlistas, pilas, colas, conjuntos y diccionarios. \n'''\n\n''' Listas (list) ''' \n'''\nColecciones ordenadas y mutables (Pueden cambiar sus elementos)\n''' \n\nlist = [1, 2, 3, 4, 5] # Pueden ser de tipo númerico, mixto ó vacía\nprint(list[0]) # Accede al primer elemento\n\n# Modificar una lista \nlist.append(6) # Agrega un elemento al final\nlist[1] = 20 # Cambia el elemento 1 por el número 20\nlist.insert(3, 6) # Agrega un elemento en un indice específico\nprint(list) \n\n# Elimina elementos\nlist.remove(5) # Elimina el primer elemento que coincida\nlist.pop (1) # Elimina un elemento por índice (o el último si no se especifica)\ndel list[0] # Elimina un elemento o un rango de la lista\nprint(list)\n\n# Cortar listas (Slicing)\nlist_1 = [10, 20, 30, 40, 50]\nprint(list_1[1:4]) # [20, 30, 40]\nprint(list_1[:3]) # [10, 20, 30]\nprint(list_1[2:1]) # [30, 40, 50]\nprint(list_1[::-1]) # [50, 40, 30, 20, 20] # lista invertida\n\n# Operaciones comunes\nprint(len(list_1)) # Número de elementos\n\nlist_2 = [1, 2]\nlist_3 = [3, 4]\nprint(list_2 + list_3) # Concatencación\n\nprint([0] * 5) # Repetición\n\nnumbers = [10, 20, 30]\nprint(20 in numbers) # Busqueda\nprint(numbers.index(20))\n\n# Métodos utiles de listas\nnumeros = [4, 2, 3, 1]\nnumeros.sort() # Ordenar en orden ascendente\nprint(numeros)  # [1, 2, 3, 4]\nnumeros.reverse() # Invertir el orden la lista\nprint(numeros)  # [4, 3, 2, 1]\nprint(numeros.count(2))  # 1 # Contar las apariciones de un elemento\ncopia = numeros.copy() # Crear una copia de la lista\nprint(copia)  # [4, 3, 2, 1]\n\n''' Tuplas (tuple)'''\n'''\nSon colecciones ordenadas pero inmutables \n(no pueden cambiar sus elementos después de crearlas)\n'''\n\nmy_tupla = (1, 2, 3, 4, 5)\nprint(my_tupla[1])\n\n# Crear una tupla\nmi_tupla = (1, 2, 3, 4, 5)\notra_tupla = \"a\", \"b\", \"c\"  # También válido\ntupla_vacia = ()\nuna_tupla = (42,)  # Tupla de un solo elemento, con una coma al final\n\n# Acceder a los elementos\nmi_tupla = (10, 20, 30, 40, 50)\nprint(mi_tupla[0])   # 10\nprint(mi_tupla[-1])  # 50\n\n\n# Inmutabilidad. \n# No puedes modificar una tupla después de crearla. Esto significa que los siguientes intentos darán error\nmi_tupla = (1, 2, 3)\n# mi_tupla[1] = 10  # Esto da error\n# mi_tupla.append(4)  # Esto también da error\n# Sin embargo, si la tupla contiene elementos mutables como listas, puedes modificar esos elementos internos.\ntupla_con_lista = (1, [2, 3], 4)\ntupla_con_lista[1][0] = 99\nprint(tupla_con_lista)  # (1, [99, 3], 4)\n\n# Unión de tuplas\nt1 = (1, 2, 3)\nt2 = (4, 5, 6)\nprint(t1 + t2)  # (1, 2, 3, 4, 5, 6)\n\n# Repetición de tuplas\nt = (1, 2)\nprint(t * 3)  # (1, 2, 1, 2, 1, 2)\n\n# Verificar si un elemento está en una tupla\nt = (10, 20, 30)\nprint(20 in t)  # True\nprint(50 in t)  # False\n\n# Metodos utiles\nt = (1, 2, 3, 2, 4, 2)\nprint(t.count(2))  # 3 (el 2 aparece tres veces)\nprint(t.index(3))  # 2 (el índice del primer 3)\n\n# Desempaquetado de tuplas\n# Puedes \"desempaquetar\" los elementos de una tupla directamente en variables.\n\nt = (1, 2, 3)\na, b, c = t\nprint(a, b, c)  # 1 2 3\n\n# También puedes usar el operador * para desempacar el resto de los elementos:\nt = (1, 2, 3, 4, 5)\na, *b, c = t\nprint(a)  # 1\nprint(b)  # [2, 3, 4]\nprint(c)  # 5\n\n''' Conjuntos (set)'''\n\nmi_conjunto = {1, 2, 3, 3, 4}\nprint(mi_conjunto)  # {1, 2, 3, 4}\nmi_conjunto.add(5)  # Agregar un elemento\nmi_conjunto.remove(2)  # Eliminar un elemento\n\n''' Diccionarios (dict)'''\n\nmi_diccionario = {\"nombre\": \"Juan\", \"edad\": 25, \"ciudad\": \"Madrid\"}\nprint(mi_diccionario[\"nombre\"])  # Acceder al valor asociado a una clave\nmi_diccionario[\"edad\"] = 26      # Modificar un valor\nmi_diccionario[\"pais\"] = \"España\"  # Agregar un nuevo par clave-valor\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/LittleMabbit.py",
    "content": "'''\n* - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n* - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n'''\n\n# Listas - Arreglo o lista de elementos en forma ordenada, es mutable (puede modificarse)\nwork_elements = ['Cuchillos', 'Tabla para cortar', 'Peso', 'Mesa', 'Aro']\nprices = [200, 800, 600, 12000, 2000, 500]\n\nprices.append(4000) # Inserción.\nprint(prices)\n\nwork_elements.remove('Peso') # Borrado\nprint(work_elements)\n\nwork_elements[1] = 'Tabla para picar' # Actualizado a traves del acceso y reasignación del indice accedido.\nprint(work_elements)\n\nwork_elements.sort() # Ordenado de lista.\nprint(work_elements)\nprices.sort() # Ordena la lista de los números.\nprint(prices)\n\n# Tuplas - Estructuras de datos mas estrictas, indicado por un paréntesis. Son inmutables, no pueden modificarse sus valores a no ser que se cambie a una lista, se modifique y luego se transforme de nuevo a una tupla.\n\nuser_data = ('Little', 'Mabbit', '@LittleMabit', '5')\nnew_data = tuple(sorted(user_data))\nprint(new_data)\n\n# Sets - Es una colección de datos no ordenada, no cambiable (solo se puede añadir y remover nuevos items) y no indexada. Es decir no tiene orden, no se le puede acceder por indice y solo puedes añadir y removes items. Tampoco permiten valores duplicados.\n\nset_of_applications = {'Facebook', 'Twitter', 'Instagram', 'X'}\nprint(type(set_of_applications))\nset_of_applications.add('LinkedIn') # Inserción\nprint(set_of_applications)\nset_of_applications.remove('Facebook') # Borrado\nprint(set_of_applications)\n# set_of_applications[0] # No es indexable. Tampoco ordenable como ya vimos antes.\n\n# Diccionarios - Grupo de valores que llevan una llave y un valor (key:value). La colección de valores es modificable, es ordenada, pero no permite valores duplicados.\ncar = {\n  \"brand\": \"McLaren\",\n  \"year\": 2024,\n  \"model\": \"720S\"\n   \n}\n\ncar['Tires'] = 4 # Inerseción, entre corchetes el valor key, y el valor asignado es el value.\nprint(car)\nprint(car['brand']) # Acceso, entre corchetes la key a acceder.\ncar['year'] = 2023 # Actualización.\nprint(car)\ndel car['Tires'] # Eliminación, para la eliminación utilizamos la palabra reservada 'del'.\nprint(car)\nsorted_cars = dict(sorted(car.items())) # Items sorteados, ordenación.\nprint(sorted_cars)\nprint(type(sorted_cars))\n\n'''\nEXTRA\n'''\ndef agenda():\n    contacts = {'Cesar': '3125632154', 'Kira': '85463215', 'Jose': '521456325'}\n    while True:\n\n      print(\"1. Buscar contacto\")\n      print(\"2. Insertar contacto\")\n      print(\"3. Actualizar contacto\")\n      print(\"4. Eliminar contacto\")\n      print(\"5. Salir\")\n\n      chosen_option = input('Por favor, selecciona la opción que necesitas: ')\n\n      if chosen_option == '2':\n          phone_number = input('Por favor, ingresa el número de celular: ')\n          contact_name = input('Por favor, ingresa nombre del contacto: ')\n          if phone_number.isdigit() and len(phone_number) > 0 and len(phone_number) <= 11:\n            if phone_number not in contacts:\n              contacts[contact_name] = phone_number\n              print('Contacto añadido exitosamente!')\n          else:\n            print('El número debe tener entre 1 y 11 dígitos. No puedes poner texto aquí. \\nPor favor, verifica el numero e intenta nuevamente')\n            \n      elif chosen_option == '3':\n        old_contact = input('Ingresa el nombre del contacto que deseas actualizar: ')\n        if old_contact in contacts:\n          phone_number = input('Por favor, ingresa el número de celular: ')\n          if phone_number.isdigit() and len(phone_number) > 0 and len(phone_number) <= 11:\n            contact_name = input('Por favor, ingresa nombre del contacto: ')\n            del contacts[old_contact]\n            contacts[contact_name] = phone_number\n            print(f'Tu contacto ha sido actualizado: Nuevo nombre: {contact_name}, nuevo número de teléfono: {contacts[contact_name]}')\n          else:\n             print('El número debe tener entre 1 y 11 dígitos. No puedes poner texto aquí. \\nPor favor, verifica el numero e intenta nuevamente')\n        else:\n            print('No pudimos encontrar la información, intenta de nuevo.')\n\n      elif chosen_option == '1':\n        find_contact = input('¿Qué contacto deseas encontrar?: ')\n        if find_contact in contacts:\n          print(f'El número telefónico de {find_contact} es: {contacts[find_contact]}.')\n        else:\n          print('Tu contacto no ha sido encontrado, por favor intenta nuevamente.')\n    \n      elif chosen_option == '4':\n        name = input('Qué contacto deseas eliminar? ')\n        if name in contacts:\n            print(f\"Eliminaste el contacto especificado\")\n            del contacts[name]\n        else:\n            print('El contacto que quieres eliminar no ha sido encontrado.')\n\n      elif chosen_option == '5':\n        print('Saliendo del programa')\n        break\n\n      else:\n        print('Opción no válida')\n\nagenda()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/LucasRebuffo.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto\n *   en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n *   y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n *   y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más\n *   de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.\n */ \"\"\"\n\n## Estructuras de datos\n\n## Listas --> Coleccion de elementos\n\nfrom ast import main\nfrom os import name\n\n\nmy_list = [\"lista\", \"5\", \"False\", \"1.2\"]\nprint(my_list)\nmy_list.append(\"al final\")  # Agregar\nprint(my_list)\nmy_list.remove(\"lista\")  # Borrar\nprint(my_list)\ni = 1\nmy_list[i] = \"valor reemplazado\"  # Actualizar\nprint(my_list)\nmy_list.sort()  # Ordenar\nprint(my_list)\n\n## Tuplas --> Conjunto datos no mutable\n\nmy_tuple = (\"1\", \"tupla\", \"2.5\", \"True\")\nprint(my_tuple)\nprint(my_tuple[2])  # Acceso\nmy_tuple = tuple(sorted(my_tuple))  # Ordenar\nprint(my_tuple)\n\n## Sets --> Colleccion no ordenada con elementos no repetidos\n\nmy_set = {\"set\", \"6\", \"1.3\", \"False\"}\nprint((my_set))\nmy_set.add(\"pepe\")  # Agregar\nprint(my_set)\nmy_set.discard(\"set\")  # Borrar\nprint(my_set)\nmy_set = set(sorted(my_set))  # No se ordena\nprint(my_set)\n\n## Diccionarios --> Coleccion de clave valor\n\nmy_dict = {\n    \"estructura\": \"dicionario\",\n    \"1\": \"True\",\n}\nprint(my_dict)\nmy_dict[\"nueva llave\"] = \"nuevo valor\"  # Agregar\nprint(my_dict)\nprint(my_dict[\"estructura\"])  # Acceder\nmy_dict[\"estructura\"] = \"nuevo diccionario\"  # Actualizar\nprint(my_dict)\ndel my_dict[\"1\"]  # Borrar\nprint(my_dict)\nmy_dict = dict(sorted(my_dict.items()))  # Ordenamiento\nprint(my_dict)\n\n\"\"\" \n* DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n *   y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n *   y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más\n *   de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.\n */  \"\"\"\n\n\ndef agregar_contacto(agenda: dict, contacto_nombre, contacto_numero: str):\n\n    if len(contacto_numero) <= 11 and contacto_numero.isdigit():\n        agenda[contacto_nombre] = contacto_numero\n        print(\"\")\n        return agenda\n    else:\n        print(\"El numero ingresado no es valido.\")\n        print(\"\")\n        return agenda\n\n\ndef listar_contactos(agenda: dict):\n    print(\"Los contactos en tu agenda son: \")\n    print(\"\")\n    for contacto, numero in agenda.items():\n        print(f\"Contacto: {contacto} Numero : {numero}\")\n    print(\"\")\n\n\ndef buscar_contacto(agenda: dict, nombre_contacto):\n    if agenda[nombre_contacto]:\n        print(f\"EL contacto {nombre_contacto} tiene nuemro: {agenda[nombre_contacto]}\")\n        print(\"\")\n    else:\n        print(\"No esta en la agenda\")\n        print(\"\")\n\n\ndef actualizar_contacto(agenda: dict, nombre_contacto, nuevo_numero):\n    if agenda[nombre_contacto]:\n        agenda[nombre_contacto] = nuevo_numero\n        return agenda\n    else:\n        print(\"No esta en la agenda\")\n        print(\"\")\n\n\ndef eliminar_contacto(agenda: dict, nombre_contacto):\n    if agenda[nombre_contacto]:\n        del agenda[nombre_contacto]\n        return agenda\n    else:\n        print(\"No esta en la agenda\")\n        print(\"\")\n\nif __name__ == \"__main__\":\n\n    print(\"\")\n    print(\"\")\n    print(\"\")\n\n    agenda: dict = {}\n    while 1:\n\n        print(\"Que operacion quieres realizar ?\")\n        print(\"\")\n        print(\"1 . Agregar\")\n        print(\"2 . Borrar\")\n        print(\"3 . Actualizar\")\n        print(\"4 . Buscar\")\n        print(\"5 . Listar\")\n        print(\"6 . Salir\")\n        print(\"\")\n\n        op = input(\"Ingrese la operacion.\")\n        print(\"\")\n\n        match op:\n            case \"1\":\n                contacto = input(\"Ingrese contacto: \")\n                numero = input(\"Ingrese numero: \")\n                agenda = agregar_contacto(agenda, contacto, numero)\n            case \"2\":\n                contacto = input(\"Ingrese contacto: \")\n                agenda = eliminar_contacto(agenda, contacto)\n            case \"3\":\n                contacto = input(\"Ingrese contacto: \")\n                numero_nuevo = input(\"Ingrese numero: \")\n                actualizar_contacto(agenda, contacto, numero_nuevo)\n            case \"4\":\n                contacto = input(\"Ingrese contacto: \")\n                buscar_contacto(agenda, contacto)\n            case \"5\":\n                listar_contactos(agenda)\n            case \"6\":\n                print(\"Saliendo de agenda ...\")\n                break\n            case _:\n                print(\"Operacion no soportada\")\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Lumanet.py",
    "content": "# Listas\nlista: list = [\"Uno\", \"Dos\", \"Tres\", \"Cuatro\"] # Creación\nprint(lista) # Impresión\nlista.append(\"Cinco\")  # Inserción \nprint(lista) \nlista.insert(1, \"One\") # Inserción en la posición 1\nprint(lista)\nlista.remove(\"Uno\") # Eliminación \nprint(lista)\nprint(lista[1]) # Acceso al elemento en la posición 1\nlista[1] = \"Three\" # Actualización del elemento en la posición 1\nprint(lista[-1]) # Acceso al último elemento\nprint(lista)\nlista.sort() # Ordenación de la lista\nprint(lista)\nprint(type(lista)) # Tipo de la variable\n\n# Tuplas\ntupla = (\"Marcos\", \"Lumanet\", \"@lumanet\", \"42\") # Creación\nprint(tupla[1]) # Acceso al elemento en la posición 1\nprint(tupla[2]) # Acceso al elemento en la posición 3\nprint(tupla[-1]) # Acceso al último elemento\nprint(tupla[-2]) # Acceso al penúltimo elemento\ntupla = tuple(sorted(tupla)) # Ordenación de la tupla\nprint(tupla) \nprint(type(tupla)) # Tipo de la variable\n\n# Sets\nmi_set = {\"Marcos\", \"Lumanet\", \"@lumanet\", \"42\"} # Creación\nprint(mi_set) \nmi_set.add(\"miemail@gmail.com\") # Inserción\nmi_set.add(\"miemail@gmail.com\") # Inserción duplicada (no se añade)\nprint(mi_set)\nmi_set.remove(\"@lumanet\") # Eliminación\nprint(mi_set)\nmi_set = set(sorted(mi_set)) # Ordenación (no se puede ordenar)\nprint(mi_set)\nprint(type(mi_set)) # Tipo de la variable\n\n# Diccionario\nmy_dict: dict = {\n    \"nombre\": \"Marcos\",\n    \"apellido\": \"Lumanet\",\n    \"alias\": \"@lumanet\",\n    \"edad\": \"41\"\n} # Creación\nprint(my_dict)\nmy_dict[\"email\"] = \"miemail@gmail.com\" # Inserción\nprint(my_dict)\ndel my_dict[\"apellido\"] # Eliminación \nprint(my_dict)\nprint(my_dict[\"nombre\"]) # Acceso al valor de la clave \"nombre\"\nmy_dict[\"edad\"] = \"42\" # Actualización del valor de la clave \"edad\"\nprint(my_dict)\nmy_dict = dict(sorted(my_dict.items())) # Ordenación del diccionario por clave \nprint(my_dict)\nprint(type(my_dict)) # Tipo de la variable\n\n\"\"\"\nCrea una contacto de contactos por terminal.\n- Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n- Cada contacto debe tener un nombre y un número de teléfono.\n- El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n  los datos necesarios para llevarla a cabo.\n- El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n  (o el número de dígitos que quieras)\n- También se debe proponer una operación de finalización del programa.\n\"\"\"\n\ndef contactos():\n\n    contacto = {} # Creación del diccionario de contactos\n\n    def insert_contact(): # Función para insertar un contacto\n        telefono = input(\"Introduce el teléfono del contacto: \")\n        if telefono.isdigit() and len(telefono) > 5 and len(telefono) <= 11: # Validación del número de teléfono\n            contacto[nombre] = telefono # Inserción o actualización del contacto en el diccionario de contactos\n        else:\n            print(\"Debes introducir un número de teléfono entre 5 y 11 dígitos.\")\n\n    while True:\n        print(\"\")\n        print(\"1. Buscar contacto\")\n        print(\"2. Nuevo contacto\")\n        print(\"3. Actualizar contacto\")\n        print(\"4. Eliminar contacto\")\n        print(\"5. Salir\")\n\n        option = input(\"\\nSelecciona una opción: \")\n\n        match option:\n            case \"1\":\n                nombre = input(\"Introduce el nombre del contacto a buscar: \")\n                if nombre in contacto: # Búsqueda del contacto en el diccionario de contactos \n                    print(f\"El número de teléfono de {nombre} es {contacto[nombre]}.\")\n                else:\n                    print(f\"El contacto {nombre} no existe.\")\n            case \"2\":\n                nombre = input(\"Introduce el nombre del contacto: \")\n                insert_contact() # Llamada a la función para insertar un contacto\n            case \"3\":\n                nombre = input(\"Introduce el nombre del contacto que deseas actualizar: \")\n                if nombre in contacto: # Búsqueda del contacto en el diccionario de contactos\n                    insert_contact() # Llamada a la función para actualizar el teléfono del contacto\n                else:\n                    print(f\"El contacto {nombre} no existe.\")\n            case \"4\":\n                nombre = input(\"Introduce el nombre del contacto que deseas eliminar: \")\n                if nombre in contacto:\n                    del contacto[nombre] # Eliminación del contacto en el diccionario de contactos\n                else:\n                    print(f\"El contacto {nombre} no existe.\")\n            case \"5\":\n                print(\"Saliendo de contactos.\")\n                break\n            case _: # Opción no válida\n                print(\"Opción no válida. Elige una opción del 1 al 5.\")\n\ncontactos()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Maanghel.py",
    "content": "\"\"\"\nEJERCICIO:\n- Muestra ejemplos de creación de todas las estructuras soportadas por \ndefecto en tu lenguaje.\n- Utiliza operaciones de inserción, borrado, actualización y ordenación.\n\nDIFICULTAD EXTRA (opcional):\nCrea una agenda de contactos por terminal.\n- Debes implementar funcionalidades de búsqueda, inserción, actualización y\neliminación de contactos.\n- Cada contacto debe tener un nombre y un número de teléfono.\n- El programa solicita en primer lugar cuál es la operación que se quiere\nrealizar, y a continuación los datos necesarios para llevarla a cabo.\n- El programa no puede dejar introducir números de teléfono no numéricos y con más de\n11 dígitos. (o el número de dígitos que quieras)\n- También se debe proponer una operación de finalización del programa.\n\"\"\"\n\n# listas\nlista_numeros = [1, 2, 5, 4, 3]\nprint(f\"Listas:\\n{lista_numeros}\")\n\nprint(f\"\\n{lista_numeros[0]}\")  # acceder a un elemento\n\nlista_numeros.append(6)  # añadir al final\nprint(f\"\\n{lista_numeros}\")\n\nlista_numeros.insert(0, 0)  # añadir al principio\nprint(f\"\\n{lista_numeros}\")\n\nlista_numeros.index(2)  # buscar un elemento\nprint(f\"\\n{lista_numeros}\")\n\nlista_numeros.remove(3)  # eliminar un elemento\nprint(f\"\\n{lista_numeros}\")\n\nlista_numeros.pop()  # eliminar el último elemento\nprint(f\"\\n{lista_numeros}\")\n\nlista_numeros.sort()  # ordenar\nprint(f\"\\n{lista_numeros}\")\n\nlista_numeros.reverse()  # invertir\nprint(f\"\\n{lista_numeros}\")\n\ntotal_elementos = lista_numeros.count(2)  # contar elementos\nprint(f\"\\n{total_elementos}\")\n\nnew_numeros = lista_numeros.copy()  # copiar\nprint(f\"\\n{new_numeros}\")\n\nnew_numeros.extend([7, 8, 9])  # añadir varios elementos al final u otra lista\nprint(f\"\\n{new_numeros}\")\n\nlista_numeros.clear()  # vaciar\nprint(f\"\\n{lista_numeros}\")\n\n\n# tuplas\ntupla_numeros = (1, 2, 5, 4, 3)\nprint(f\"\\nTuplas:\\n{tupla_numeros}\")\n\nprint(f\"\\n{tupla_numeros[0]}\") # acceder a un elemento\n\ncontar = tupla_numeros.count(2)  # contar elementos\nprint(f\"\\n{contar}\")\n\nlugar_posicional = tupla_numeros.index(3)  # buscar un elemento\nprint(f\"\\n{lugar_posicional}\")\n\nnumeros_ordenados = sorted(tupla_numeros)  # ordenar(retorna una lista)\nprint(f\"\\n{numeros_ordenados}\")\n\ndel tupla_numeros  # eliminar la tupla\n\n\n# diccionarios\ndiccionario_datos = {\n    \"nombre\": \"Juan\",\n    \"edad\": 30,\n    \"ciudad\": \"Madrid\"\n}\nprint(f\"\\nDiccionarios:\\n{diccionario_datos}\")\n\nprint(f\"\\n{diccionario_datos[\"nombre\"]}\")  # acceder a un elemento\n\nclaves_diccionario = diccionario_datos.keys()  # obtener claves\nprint(f\"\\n{claves_diccionario}\")\n\nvalores_diccionario = diccionario_datos.values()  # obtener valores\nprint(f\"\\n{valores_diccionario}\")\n\nclave_valor_diccionario = diccionario_datos.items()  # obtener clave-valor\nprint(f\"\\n{clave_valor_diccionario}\")\n\ndiccionario_datos.update({\"telefono\": \"123456789\"})  # añadir un elemento\nprint(f\"\\n{diccionario_datos}\")\n\ndiccionario_datos.setdefault(\"sexo\", \"masculino\")  # añadir un elemento si no existe\nprint(f\"\\n{diccionario_datos}\")\n\ndiccionario_datos.pop(\"telefono\")  # eliminar un elemento\nprint(f\"\\n{diccionario_datos}\")\n\ndiccionario_datos.popitem()  # eliminar el último elemento\nprint(f\"\\n{diccionario_datos}\")\n\nobtener_dato = diccionario_datos.get(\"nombre\")  # obtener un elemento\nprint(f\"\\n{obtener_dato}\")\n\nlista_claves = list(diccionario_datos.keys())  # convertir claves a lista\nnuevo_diccionario = diccionario_datos.fromkeys(lista_claves, \"desconocido\")  # crear un diccionario con claves\nprint(f\"\\n{nuevo_diccionario}\")\n\ncopia_diccionario = diccionario_datos.copy()  # copiar\nprint(f\"\\n{copia_diccionario}\")\n\ncopia_diccionario.clear()  # vaciar\nprint(f\"\\n{copia_diccionario}\")\n\n\n# conjuntos\nconjunto_numeros = {1, 2, 5, 4, 3}\nprint(f\"\\nConjuntos:\\n{conjunto_numeros}\")\n\nconjunto_numeros.add(6)  # añadir un elemento\nprint(f\"\\n{conjunto_numeros}\")\n\nconjunto_numeros.pop()  # eliminar un elemento aleatorio\nprint(f\"\\n{conjunto_numeros}\")\n\nconjunto_numeros.remove(2)  # eliminar un elemento, si no existe lanza error KeyError\nprint(f\"\\n{conjunto_numeros}\")\n\nconjunto_numeros.discard(8)  # eliminar un elemento, si no existe no lanza error\nprint(f\"\\n{conjunto_numeros}\")\n\nnuevo_conjunto = conjunto_numeros.union([8,9])  # unir conjuntos\nprint(f\"\\n{nuevo_conjunto}\")\n\nconjunto_numeros.update([7, 8, 9])  # añadir varios elementos\nprint(f\"\\n{conjunto_numeros}\")\n\ndiferencia = conjunto_numeros.difference(nuevo_conjunto)  # diferencia entre conjuntos\nprint(f\"\\n{diferencia}\")\n\ninterseccion = conjunto_numeros.intersection(nuevo_conjunto)  # intersección entre conjuntos\nprint(f\"\\n{interseccion}\")\n\nsimetria = conjunto_numeros.symmetric_difference(nuevo_conjunto)  # simetría entre conjuntos\nprint(f\"\\n{simetria}\")\n\nconjunto_numeros.clear()  # vaciar\nprint(f\"\\n{conjunto_numeros}\")\n\n# EXTRA\n\nclass Agenda:\n    def __init__(self):\n        self.contactos = {}\n        self.menu()\n\n    def menu(self):\n        while True:\n            print(\"\\nAgenda de Contactos\")\n            print(\"1. Añadir contacto\")\n            print(\"2. Buscar contacto\")\n            print(\"3. Actualizar contacto\")\n            print(\"4. Eliminar contacto\")\n            print(\"5. Mostrar contactos\")\n            print(\"6. Salir\")\n            opcion = input(\"Selecciona una opción: \")\n\n            if opcion == \"1\":\n                self.añadir_contacto()\n            elif opcion == \"2\":\n                self.buscar_contacto()\n            elif opcion == \"3\":\n                self.actualizar_contacto()\n            elif opcion == \"4\":\n                self.eliminar_contacto()\n            elif opcion == \"5\":\n                self.mostrar_contactos()\n            elif opcion == \"6\":\n                print(\"Gracias por usar la agenda.\")\n                self._pausar()\n                break\n            else:\n                print(\"Opción no válida.\")\n\n    def añadir_contacto(self):\n        \"\"\"añadir un contacto a la agenda\"\"\"\n        nombre = input(\"Introduce el nombre del contacto: \")\n        telefono = input(\"Introduce el número de teléfono (10 dígitos): \")\n        if not telefono.isdigit() or len(telefono) != 10:\n            print(\"Número de teléfono no válido.\")\n            self._pausar()\n            return\n        self.contactos[nombre] = telefono\n        print(f\"Contacto {nombre} añadido con éxito.\")\n        self._pausar()\n\n    def buscar_contacto(self):\n        \"\"\"buscar un contacto en la agenda\"\"\"\n        nombre = input(\"Introduce el nombre del contacto a buscar: \")\n        if nombre in self.contactos:\n            print(f\"Contacto encontrado: {nombre} - {self.contactos[nombre]}\")\n        else:\n            print(\"Contacto no encontrado.\")\n        self._pausar()\n\n    def actualizar_contacto(self):\n        \"\"\"actualizar un contacto en la agenda\"\"\"\n        nombre = input(\"Introduce el nombre del contacto a actualizar: \")\n        if nombre in self.contactos:\n            telefono = input(\"Introduce el nuevo número de teléfono (10 dígitos): \")\n            if not telefono.isdigit() or len(telefono) != 10:\n                print(\"Número de teléfono no válido.\")\n                self._pausar()\n                return\n            self.contactos[nombre] = telefono\n            print(f\"Contacto {nombre} actualizado con éxito.\")\n        else:\n            print(\"Contacto no encontrado.\")\n        self._pausar()\n\n    def eliminar_contacto(self):\n        \"\"\"eliminar un contacto de la agenda\"\"\"\n        nombre = input(\"Introduce el nombre del contacto a eliminar: \")\n        if nombre in self.contactos:\n            del self.contactos[nombre]\n            print(f\"Contacto {nombre} eliminado con éxito.\")\n        else:\n            print(\"Contacto no encontrado.\")\n        self._pausar()\n\n    def mostrar_contactos(self):\n        \"\"\"mostrar todos los contactos de la agenda\"\"\"\n        if not self.contactos:\n            print(\"No hay contactos en la agenda.\")\n        else:\n            print(\"Contactos en la agenda:\")\n            for nombre, telefono in self.contactos.items():\n                print(f\"{nombre} - {telefono}\")\n        self._pausar()\n\n    def _pausar(self):\n        input(\"Presiona Enter para continuar...\")\n\nif __name__ == \"__main__\":\n    Agenda()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/MarcosE-FerretoE.py",
    "content": "\"\"\"EJERCICIO:\n\"\"\"\n\n# Estructuras\n\n\n# Lista\nmi_lista_lenguajes = [\"Python\", \"Java\", \"Kotlin\", \"Dart\", \"JavaScript\", \"C\"]\nprint(mi_lista_lenguajes)  # Lista original\n\n\nmi_lista_lenguajes.append(\"Swift\")  # Insertar al final\nprint(mi_lista_lenguajes)\nmi_lista_lenguajes.insert(2, \"Go\")  # Insertar en una posición específica\nprint(mi_lista_lenguajes)\n\n\nmi_lista_lenguajes.remove(\"Python\")  # Borrado\nprint(mi_lista_lenguajes)\nmi_lista_lenguajes.pop()  # Eliminar el último elemento\nprint(mi_lista_lenguajes)\n\nmi_lista_lenguajes[4] = \"TypeScript\"  # actualización\nprint(mi_lista_lenguajes)\n\nmi_lista_lenguajes.sort()\nprint(mi_lista_lenguajes)  # ordenación\n\n# Tupla (No se puede alterar, es inmutable)\nmi_tupla_coordenadas = (56, 112, 100)\n\n\n# Set (No se puede ordenar)\nmi_set_colores = {\"Azul\", \"Rojo\", \"Morado\", \"Celeste\", \"Amarillo\"}\nprint(mi_set_colores)  # Set original\n\nmi_set_colores.add(\"Verde\")  # Inserción\nprint(mi_set_colores)\n\nmi_set_colores.remove(\"Azul\")  # Borrado\nprint(mi_set_colores)\n\n# Diccionario\nmi_diccionario = {\n    \"Python\": 1991,\n    \"Java\": 1995,\n}\nprint(mi_diccionario)  # Diccionario original\n\nmi_diccionario[\"JavaScript\"] = \"1995\"  # Inserción (Agregar un nuevo elemento)\nprint(mi_diccionario)\n\ndel mi_diccionario[\"Python\"]  # Borrado (Eliminar un elemento por su clave)\nprint(mi_diccionario)\n\nmi_diccionario[\"Java\"] = \"29\"  # Actualización (Modificar el valor de una clave)\nprint(mi_diccionario)\n\n# Cadenas\nmi_cadena_nombre = \"Python\"\nmi_cadena_hola = \"Hola, mundo!\"\n\n\n\"\"\"DIFICULTAD EXTRA\n\"\"\"\n\ncontactos = []\n\n\n# Función para añadir un contacto\ndef agregar_contacto(nombre, telefono):\n    # Comprueba que el número de teléfono es válido\n    if not telefono.isdigit() or len(telefono) > 8:\n        print(\"El número de teléfono no es válido.\")\n        print(\"Debes introducir un numero máximo de 8 dígitos.\")\n        return\n\n    # Añadimos el contacto a la lista\n    contactos.append({\"nombre\": nombre, \"telefono\": telefono})\n\n\n# Función para buscar un contacto\ndef buscar_contacto(nombre):\n    # Buscamos el contacto en la lista\n    for contacto in contactos:\n        if contacto[\"nombre\"] == nombre:\n            return contacto\n\n    # Si no se encuentra el contacto, devolvemos None\n    return None\n\n\n# Función para actualizar un contacto\ndef actualizar_contacto(nombre, nuevo_nombre, nuevo_telefono):\n    # Buscamos el contacto en la lista\n    contacto = buscar_contacto(nombre)\n\n    # Si no se encuentra el contacto, devolvemos None\n    if contacto is None:\n        return None\n\n    # Actualizamos el contacto\n    contacto[\"nombre\"] = nuevo_nombre\n    contacto[\"telefono\"] = nuevo_telefono\n\n\n# Función para eliminar un contacto\ndef eliminar_contacto(nombre):\n    # Buscamos el contacto en la lista\n    contacto = buscar_contacto(nombre)\n\n    # Si no se encuentra el contacto, devolvemos None\n    if contacto is None:\n        return None\n\n    # Eliminamos el contacto de la lista\n    contactos.remove(contacto)\n\n\n# Función para mostrar los contactos\ndef mostrar_contactos():\n    if not contactos:\n        print(\"No hay contactos.\")\n        return\n\n    # Recorremos la lista de contactos y mostramos cada contacto\n    for contacto in contactos:\n        print(f\"{contacto['nombre']}: {contacto['telefono']}\")\n\n\n# Función principal\ndef main():\n    print(\"Agenda de contactos\")\n    print(\"-------------------\")\n    print(\"1. Agregar contacto\")\n    print(\"2. Buscar contacto\")\n    print(\"3. Actualizar contacto\")\n    print(\"4. Eliminar contacto\")\n    print(\"5. Mostrar contactos\")\n    print(\"6. Salir\")\n\n    # Pedimos al usuario que elija una opción\n    opcion = input(\"Elige una opción: \")\n\n    while opcion != \"6\":\n\n        if opcion == \"1\":\n            nombre = input(\"Nombre: \")\n            telefono = input(\"Teléfono: \")\n            agregar_contacto(nombre, telefono)\n\n        elif opcion == \"2\":\n            nombre = input(\"Nombre: \")\n            contacto = buscar_contacto(nombre)\n\n            if contacto is None:\n                print(\"El contacto no existe.\")\n\n            else:\n                print(f\"Nombre: {contacto['nombre']}\")\n                print(f\"Teléfono: {contacto['telefono']}\")\n\n        elif opcion == \"3\":\n            nombre = input(\"Nombre: \")\n            nuevo_nombre = input(\"Nuevo nombre: \")\n            nuevo_telefono = input(\"Nuevo teléfono: \")\n            actualizar_contacto(nombre, nuevo_nombre, nuevo_telefono)\n\n        elif opcion == \"4\":\n            nombre = input(\"Nombre: \")\n            eliminar_contacto(nombre)\n\n        elif opcion == \"5\":\n            mostrar_contactos()\n\n        elif opcion == \"6\":\n            exit()\n\n        else:\n            print(\"Opción no válida.\")\n\n        print(\"Agenda de contactos\")\n        print(\"-------------------\")\n        print(\"1. Agregar contacto\")\n        print(\"2. Buscar contacto\")\n        print(\"3. Actualizar contacto\")\n        print(\"4. Eliminar contacto\")\n        print(\"5. Mostrar contactos\")\n        print(\"6. Salir\")\n\n        opcion = input(\"Elige una opción: \")\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Matc-Channel.py",
    "content": "\n# LISTAS\nmy_list: list = [\"Brais\", \"Black\", \"Wolfy\", \"Visionos\"]\nprint(my_list)\n\n# AÑADIR o INSERCIÓN\nmy_list.append(\"Kramer\")\nprint(my_list)\n\n# ELIMINACIÓN\nmy_list.remove(\"Brais\")\nprint(my_list)\n\n# ACEDER A UNA POSICIÓN\nprint(my_list[0])\nprint(my_list[1])\nprint(my_list[2])\nprint(my_list[3])\n# print(my_list[4])   # => No hay POSICIÓN 4; ERROR\n\n# ACTUALIZACIÓN\nmy_list[1] = \"Paquita\"\nprint(my_list)\n\n# ORDENACIÓN\nmy_list.sort()\nprint(my_list)  # ORDENA ALFABETICAMENTE\nprint(type(my_list))\n\n\n# TUPLAS\n\n# Estructura deonde podemos almacenar mas de 1 DATO\n# Pero las TUPLAS son INMUTABLES\n# Para uso de DATOS IMUTABLES\nmy_tuple: tuple = (\"Brais\", \"Moure\", \"@mouredev\", \"36\")\n# ACCESO  A UNA POSICIÓN\nprint(my_tuple[1])\nprint(my_tuple[3])\n# print(my_tuple[4])  # => No hay POSICIÓN 4; ERROR\n\n# USO DE sorted()...devuelve una LISTA\nmy_tuple = sorted(my_tuple)     # Pero muestra ERROR por datos 36 int\n# Pero se tranasforma a LISTA\n# Por lo que se pude CASTEAR a TUPLA\n\n# ORDENACIÓN\nmy_tuple = tuple(sorted(my_tuple))  # => sorted ordenará numeros y textosaa\nprint(my_tuple)\nprint(type(my_tuple))\n\n\n# SETS\n# Son otros tipos de ESTRUCTURAS\nmy_set: set = {\"Brais\", \"Moure\", \"@mouredev\", \"36\"}\nprint(my_set)\n# INSERCIÓN\nmy_set.add(\"mouredev@gmail.com\")\nmy_set.add(\"mouredev@gmail.com\")    # => NO GUARDA DUPLICADOS\n# ELIMINACIÓN\nmy_set.remove(\"Moure\")\nprint(my_set)\n# ORDENACIÓN\nmy_set = set(sorted(my_set))    # => NO SE PUEDE ORDENAR UN SET\nprint(my_set)\n# print(my_set[0])    # => NO SE PUEDE ACCEDER\n\nprint(type(my_set))\n\n\n# DICCIONARIOS\n'''\n# 03 ESTRUCTURA DE DATOS\n'''\n\n# LISTAS\n# son ORDENADAS, es una ESTRUCTURA para guardar varios ELEMENTOS\nmy_list = [\"Brais\", \"Black\", \"Wolfy\", \"Visionos\"]\nprint(my_list)\n# añadir una INSERCCÓN la LISTA\nmy_list.append(\"Castor\")\nprint(my_list)\n# ELIMINACIÓN\nmy_list.remove(\"Brais\")\nprint(my_list)\n# ACTUALIZACIÓN de ELEMENTOS de la LISTA\n# Saber PRIMERO la POSICIÓN\nmy_list[1]  # => Acceder a posición Wolfy\nmy_list[1] = \"Cuervillo\"\nprint(my_list)\n# OREDENACIÓN alfabeticamente\nmy_list.sort()\nprint(my_list)\nprint(type(my_list))    # => VER tipo de DATO\nprint(\"\\n\")\n\n# OTRA ESTRUTURAS\n# TUPLA(Podemos guardar más de 1 dato, no actualizable)\nmy_tuple = (\"Brais\", \"Moure\", \"@mouredev\", \"36\")\n# Acceso a DATOS\nprint(my_tuple[1])\nprint(my_tuple[2])\nprint(my_tuple[3])\n# ORDENAR una TUPLA\nmy_tuple = tuple(sorted(my_tuple))  # => 1ero cambiar a 36 a str\nprint(my_tuple)\nprint(type(my_tuple))\n\n# SETS\n# Otros TIPOS DE ESTRUCTURA\n# Bueno para GUARDAR, RECORRER pero no para BUSCAR DATOS\nmy_set = {\"Brais\", \"Moure\", \"@mouredev\", \"36\"}\n# INSERIÓN\nmy_set.add(\"mouredev@gmail.com\")\nmy_set.add(\"mouredev@gmail.com\")    # => No inresa DATOS dobles\nmy_set.remove(\"Moure\")  # => ELIMINACIÓN\nprint(my_set)\nmy_set = set(sorted(my_set))    # => NO SE PUEDE ORDENAR\nprint(my_set)\nprint(type(my_set))\nprint(\"\\n\")\n\n# DICCIONARIO\n# Otra ESTRUCTURA\nmy_dict: dict = {\n    \"name\": \"Brais\",\n    \"surname\": \"Moure\",\n    \"alias\": \"@mouredev\",\n    \"age\": \"36\"\n}\n\n# PRUEBAS\n# INSERCIÓN\nmy_dict[\"e-mail\"] = \"mouredev@gmail.com\"\nprint(my_dict)\n# ELIMINACIÓN\ndel my_dict[\"surname\"]\nprint(my_dict)\n# ACCESO\nprint(my_dict[\"name\"])\n# ACTUALIZACIÓN\nmy_dict[\"name\"] = \"Kramer\"\nprint(my_dict)\n# ORDENACIÓN\nmy_dict = dict(sorted(my_dict.items()))\nprint(my_dict)\nprint(type(my_dict))\nprint(\"-\" * 15)\n\n'''\nEXTRA\n\n/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por\n * defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n *   y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere\n * realizar, y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no numéricos y\n * con más de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.\n */\n'''\n\n\ndef my_agenda():\n\n    agenda = {}\n\n    def insert_contact():\n        phone = input(\"Ingresa el teléfono del contacto:\")\n        if phone.isdigit() and len(phone) > 0 and len(phone) <= 11:\n            agenda[name] = phone\n        else:\n            print(\n                \"Introducir un número de teléfono de\"\n                \" menos de 11 dígitos\"\n            )\n\n    while True:\n\n        print(\"1. Buscar contacto\")\n        print(\"2. Insertar contacto\")\n        print(\"3. Actualizar contacto\")\n        print(\"4. Eliminar contacto\")\n        print(\"5. Salir\")\n\n        option = input(\"Selecciona una opción: \")\n        match option:\n            case \"1\":\n                name = input(\"Introduce el nombre del contacto a buscar: \")\n                if name in agenda:\n                    print(\n                        f\"El número de teléfono de {name} es:{agenda[name]}.\")\n                else:\n                    print(f\"<<El contacto {name} no existe.>>\")\n                pass\n            case \"2\":\n                name = input(\"Ingresa el nombre del contacto: \")\n                insert_contact()\n                pass\n            case \"3\":\n                name = input(\"Introduce el nombre del contacto a actualizar: \")\n                if name in agenda:\n                    insert_contact()\n                else:\n                    print(f\"<<El contacto {name} no existe.>>\")\n                pass\n            case \"4\":\n                name = input(\"Introduce el nombre del contacto a eliminar: \")\n                if name in agenda:\n                    del agenda[name]\n                    print(f\">>>Se eliminó el contacto {name}.<<<\")\n                else:\n                    print(f\"<<El contacto {name} no existe.>>\")\n                pass\n            case \"5\":\n                print(\"Gracias por usar la agenda\\n\"\n                      \"¡Hasta la próxima!\\n\"\n                      \">>Saliendo de la agenda...\")\n                break\n            case _:\n                print(\n                    \"<<Opción no válida. Elige una opción\" +\n                    \" correcta del 1-5.>>\"\n                    )\n\n\nmy_agenda()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/MercedesDF.py",
    "content": "# Listas (List)\nmi_lista = [5, 3, 8, 1]\nmi_lista.append(7)  # Inserción\nmi_lista.remove(3)   # Borrado\nmi_lista[2] = 10     # Actualización\nmi_lista.sort()      # Ordenación\nprint(f\"Lista: {mi_lista}\")\n\n# Tuplas (Tuple) - Inmutables\nmi_tupla = (4, 1, 6, 2)\n# No se pueden modificar directamente, pero se puede crear una nueva tupla\nnueva_tupla = mi_tupla + (8,)  # Inserción creando una nueva tupla\nprint(f\"Tupla: {nueva_tupla}\")\n\n# Conjuntos (Set)\nmi_conjunto = {9, 2, 5}\nmi_conjunto.add(7)  # Inserción\nmi_conjunto.discard(2)  # Borrado\n# No hay actualización directa, se puede remover y añadir de nuevo\nmi_conjunto.remove(5)\nmi_conjunto.add(6)  # Simulando una \"actualización\"\nprint(f\"Conjunto: {mi_conjunto}\")\n\n# Diccionarios (Dict)\nmi_diccionario = {\"a\": 1, \"b\": 2, \"c\": 3}\nmi_diccionario[\"d\"] = 4  # Inserción\ndel mi_diccionario[\"b\"]  # Borrado\nmi_diccionario[\"a\"] = 10  # Actualización\n# Los diccionarios no tienen un orden explícito\nprint(f\"Diccionario: {mi_diccionario}\")\n\n\n#PROGRAMA EXTRA:\n# Funciones para las operaciones de la agenda\ndef mostrar_menu():\n    print(\"\\nAgenda de Contactos\")\n    print(\"1. Añadir contacto\")\n    print(\"2. Buscar contacto\")\n    print(\"3. Actualizar contacto\")\n    print(\"4. Eliminar contacto\")\n    print(\"5. Listar contactos\")\n    print(\"6. Salir\")\n\ndef es_numero_valido(numero):\n    return numero.isdigit() and len(numero) <= 11\n\ndef añadir_contacto(agenda):\n    nombre = input(\"Introduce el nombre: \")\n    numero = input(\"Introduce el número de teléfono: \")\n    if es_numero_valido(numero):\n        agenda[nombre] = numero\n        print(f\"Contacto {nombre} añadido correctamente.\")\n    else:\n        print(\"Número no válido. Debe ser numérico y tener hasta 11 dígitos.\")\n\ndef buscar_contacto(agenda):\n    nombre = input(\"Introduce el nombre a buscar: \")\n    if nombre in agenda:\n        print(f\"Nombre: {nombre}, Teléfono: {agenda[nombre]}\")\n    else:\n        print(f\"Contacto {nombre} no encontrado.\")\n\ndef actualizar_contacto(agenda):\n    nombre = input(\"Introduce el nombre a actualizar: \")\n    if nombre in agenda:\n        nuevo_numero = input(\"Introduce el nuevo número de teléfono: \")\n        if es_numero_valido(nuevo_numero):\n            agenda[nombre] = nuevo_numero\n            print(f\"Contacto {nombre} actualizado correctamente.\")\n        else:\n            print(\"Número no válido. Debe ser numérico y tener hasta 11 dígitos.\")\n    else:\n        print(f\"Contacto {nombre} no encontrado.\")\n\ndef eliminar_contacto(agenda):\n    nombre = input(\"Introduce el nombre a eliminar: \")\n    if nombre in agenda:\n        del agenda[nombre]\n        print(f\"Contacto {nombre} eliminado correctamente.\")\n    else:\n        print(f\"Contacto {nombre} no encontrado.\")\n\ndef listar_contactos(agenda):\n    print(\"Lista de Contactos:\")\n    for nombre, numero in agenda.items():\n        print(f\"Nombre: {nombre}, Teléfono: {numero}\")\n    print(f\"total contactos: {len(agenda)}\")\n\n# Programa principal\ndef main():\n    agenda = {}\n    while True:\n        mostrar_menu()\n        opcion = input(\"Elige una opción: \")\n\n        if opcion == \"1\":\n            añadir_contacto(agenda)\n        elif opcion == \"2\":\n            buscar_contacto(agenda)\n        elif opcion == \"3\":\n            actualizar_contacto(agenda)\n        elif opcion == \"4\":\n            eliminar_contacto(agenda)\n        elif opcion == \"5\":\n            listar_contactos(agenda)\n        elif opcion == \"6\":\n            print(\"Saliendo del programa...\")\n            break\n        else:\n            print(\"Opción no válida. Inténtalo de nuevo.\")\n\nif __name__ == \"__main__\":\n    main()\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/MiguelAngelEc.py",
    "content": "\n# DIFICULTAD EXTRA (opcional):\n# Crea una agenda de contactos por terminal.\n\ncontac = [\n    {\n        \"nombre\": \"Miguel Angel\",\n        \"apellido\": \"Castillo\", \n        \"edad\": 22,\n        \"numero\": 123456789\n    }\n]\n\n#Mostrar Menu\ndef mostrar_menu():\n    print(\"\\n=== AGENDA DE CONTACTOS ===\")\n    print(\"1. Buscar contacto\")\n    print(\"2. Agregar contacto\")\n    print(\"3. Ver contactos\")\n    print(\"4. Eliminar contacto\")\n    print(\"5. Editar contacto\")\n    print(\"6. Salir\")\n    print(\"=\" * 27)\n\n# Funcion de buscar contactos\ndef buscar_contacto():\n    print(\"\\n--- Buscar contacto ---\")\n    if not contac:\n        print(\"No hay contactos en la agenda.\")\n        return\n    \n    search = input(\"Ingrese el valor a buscar: \").lower().strip()\n    print(\"-\" * 20)\n    \n    encontrados = []\n    for i, contacto in enumerate(contac):\n        for valor in contacto.values():\n            if search in str(valor).lower():\n                encontrados.append((i, contacto))\n                break\n    \n    if encontrados:\n        print(f\"Se encontraron {len(encontrados)} contacto(s):\")\n        for i, contacto in encontrados:\n            print(f\"\\nContacto #{i+1}:\")\n            print(f\"Nombre: {contacto['nombre']}\")\n            print(f\"Apellido: {contacto['apellido']}\")\n            print(f\"Edad: {contacto['edad']}\")\n            print(f\"Número: {contacto['numero']}\")\n    else:\n        print(\"No se encontraron contactos con ese criterio.\")\n\n# Funcion de Agregar Contactos\ndef agregar_contacto():\n    print(\"\\n--- Agregar contacto ---\")\n    try:\n        nombre = input(\"Ingrese el nombre: \").strip()\n        apellido = input(\"Ingrese el apellido: \").strip()\n        edad = int(input(\"Ingrese la edad: \"))\n        numero = input(\"Ingrese el número: \").strip()\n        \n\n        if not nombre or not apellido:\n            print(\"Error: El nombre y apellido no pueden estar vacíos.\")\n            return\n        \n        if edad < 0 or edad > 150:\n            print(\"Error: Edad inválida.\")\n            return\n            \n        nuevo_contacto = {\n            \"nombre\": nombre.title(),  # Primera letra mayúscula\n            \"apellido\": apellido.title(),\n            \"edad\": edad,\n            \"numero\": numero\n        }\n        \n        contac.append(nuevo_contacto)\n        print(\"✓ Contacto agregado con éxito.\")\n        \n    except ValueError:\n        print(\"Error: La edad debe ser un número válido.\")\n        \n# Funcion de Ver Contactos\ndef ver_contactos():\n    print(\"\\n--- Ver contactos ---\")\n    if not contac:\n        print(\"No hay contactos en la agenda.\")\n        return\n    \n    print(\"-\" * 20)\n    for i, contacto in enumerate(contac):\n        print(f\"\\nContacto #{i+1}:\")\n        print(f\"Nombre: {contacto['nombre']}\")\n        print(f\"Apellido: {contacto['apellido']}\")\n        print(f\"Edad: {contacto['edad']}\")\n        print(f\"Número: {contacto['numero']}\")\n\n# Funcion de Eliminar Contactos\ndef eliminar_contacto():\n    print(\"\\n--- Eliminar contacto ---\")\n    if not contac:\n        print(\"No hay contactos en la agenda.\")\n        return\n    ver_contactos()\n    try:\n        indice = int(input(f\"\\nIngrese el número del contacto a eliminar (1-{len(contac)}): \")) - 1\n        if 0 <= indice < len(contac):\n            contacto_eliminado = contac.pop(indice)\n            print(f\"✓ Contacto {contacto_eliminado['nombre']} {contacto_eliminado['apellido']} eliminado.\")\n        else:\n            print(\"Error: Número de contacto inválido.\")\n    except ValueError:\n        print(\"Error: Debe ingresar un número válido.\")\n        \n# Funcion de Editar Contactos\ndef editar_contacto():\n    print(\"\\n--- Editar contacto ---\")\n    if not contac:\n        print(\"No hay contactos para editar.\")\n        return\n    \n    ver_contactos()\n    try:\n        indice = int(input(f\"\\nIngrese el número del contacto a editar (1-{len(contac)}): \")) - 1\n        if 0 <= indice < len(contac):\n            contacto = contac[indice]\n            print(f\"\\nEditando: {contacto['nombre']} {contacto['apellido']}\")\n            \n            nuevo_nombre = input(f\"Nuevo nombre ({contacto['nombre']}): \").strip()\n            nuevo_apellido = input(f\"Nuevo apellido ({contacto['apellido']}): \").strip()\n            nueva_edad = input(f\"Nueva edad ({contacto['edad']}): \").strip()\n            nuevo_numero = input(f\"Nuevo número ({contacto['numero']}): \").strip()\n            \n\n            if nuevo_nombre:\n                contacto['nombre'] = nuevo_nombre.title()\n            if nuevo_apellido:\n                contacto['apellido'] = nuevo_apellido.title()\n            if nueva_edad:\n                contacto['edad'] = int(nueva_edad)\n            if nuevo_numero:\n                contacto['numero'] = nuevo_numero\n                \n            print(\"✓ Contacto actualizado con éxito.\")\n        else:\n            print(\"Error: Número de contacto inválido.\")\n    except ValueError:\n        print(\"Error: Valores inválidos ingresados.\")\n \n# Funcion Principal Ejecuta el Programa       \ndef main():\n    print(\"¡Bienvenido a tu Agenda de Contactos!\")\n    \n    while True:\n        mostrar_menu()\n        try:\n            opcion = int(input(\"Seleccione una opción (1-6): \"))\n            \n            if opcion == 1:\n                buscar_contacto()\n            elif opcion == 2:\n                agregar_contacto()\n            elif opcion == 3:\n                ver_contactos()\n            elif opcion == 4:\n                eliminar_contacto()\n            elif opcion == 5:\n                editar_contacto()\n            elif opcion == 6:\n                print(\"\\n¡Gracias por usar la agenda! ¡Hasta luego! 👋\")\n                break\n            else:\n                print(\"Error: Opción inválida. Seleccione del 1 al 6.\")\n                \n        except ValueError:\n            print(\"Error: Debe ingresar un número válido.\")\n        except KeyboardInterrupt:\n            print(\"\\n\\n¡Programa interrumpido por el usuario!\")\n            break\n        \n\n        input(\"\\nPresione Enter para continuar...\")\n\n# Ejecutar el programa\nif __name__ == \"__main__\":\n    main()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/MirandaYuber.py",
    "content": "print('######  LISTAS  ######')  # Son mutables\nprint()\n\nmy_list = [1, 2]\nprint(f'Lista: {my_list}')\n\nmy_list.append(10)\nprint(f'Append(Agrega elementos al final de la lista): {my_list}')\n\nmy_list.remove(10)\nprint(f'Remove(Elimina el elemento de la lista): {my_list}')\n\nmy_list[0] = 0\nprint(f'Actualizar por index: {my_list}')\n\nprint(f'Acceder al valor por el index: {my_list[1]}')\n\nmy_list.extend([11, 12, 13, 14, 15])\nprint(f'Extend(Agrega una lista al final de la lista): {my_list}')\n\nprint(f'Index(Obtener posición del elemento indicado): {my_list.index(11)}')\n\nmy_list.insert(2, 9)\nprint(f'Insert(Inserta un elemento segun el indice): {my_list}')\n\nprint(f'Pop(Devuelve el ultimo elemento): {my_list.pop()}')\n\nprint(f'Count(Devuelve conteo de cuantos elementos hay en la lista): {my_list.count(1)}')\n\nmy_list.sort(reverse=True)\nprint(f'Sort(Ordena la lista descendente): {my_list}')\nmy_list.sort()\nprint(f'Sort(Ordena la lista ascendente): {my_list}')\nmy_list.reverse()\nprint(f'Reverse(Desordena la lista sin ordenarla antes): {my_list}')\nprint()\nprint()\n\n\nprint('######  TUPLAS  ######')  # Son inmutables\nprint()\n\nmy_tuple = ('1', '2', '3')\nprint(f'Tupla: {my_tuple}')\n\nprint(f'Obtener por posición[index]: {my_tuple[1]}')\n\nprint(f\"Ordenar: {tuple(sorted(my_tuple))}\")\n\nprint(f'Len(Obtener tamaño de la tupla): {len(my_tuple)}')\n\nprint(f'Obtener por rango de posición[index_inicial:index_final]: {my_tuple[1:]}')\n\nmy_tuple2 = (1,)\nprint(f'Crear una tupla con un solo valor (value,): {my_tuple2}')\nprint()\nprint()\n\n\nprint('######  SETS  ######')  # Son como listas sin orden especifico y sin valores repetidos\nprint()\n\nmy_set = {4, 1, 9, 6}\nprint(f'Set: {my_set}')\n\nmy_set.add(2)\nprint(f'Add(Agrega nuevo elemento): {my_set}')\n\nprint(f'In(Revisar si existe un elemento dentro del set): {4 in my_set}')\n\nmy_set.remove(4)\nprint(f\"Remove: {my_set}\")\n\nprint()\nprint()\n\n\nprint('######  STRINGS  ######')\nprint()\n\nmy_string = 'Yuber Miranda, Python'\nprint(f'String: {my_string}')\n\nprint(f'Len(Obtener tamaño del string: {len(my_string)})')\n\nprint(f'Obtener caracter por pocisión([1]): {my_string[1]}')\n\nprint(f'Obtener caracter por rango de pocisión ([1:5]): {my_string[1:5]}')\n\nprint(f'In(Buscar una cadena dentro del string): {\"a\" in my_string}')\n\nprint(f'Split(Guarda la cadena en un arreglo): {my_string.split()}')\n\nnew_list = my_string.split(\",\")\nprint(f'Split(Guarda la cadena en una lista indicandole el caracter): {new_list}')\n\nprint(f'Join(Unir la lista en un string): {\",\".join(new_list)}')\n\nprint(f'Strip(Remover espacios vacios del string): {\" example@example.net\".strip()}')\n\nprint(f'Strip(Remover caracteres del string): {\"aeioub\".strip(\"aei\")}')\nprint()\nprint()\n\n\nprint('######  DICIONARIOS  ######')  # Similiar a una lista parecido a un JSON\nprint()\n\nmy_dictionary: dict = {\n    'name': 'Yuber',\n    'surname': 'Miranda',\n    'alias': '@ye_minrandaa',\n    'age': 22\n}\nprint(f'Diccionario: {my_dictionary}')\n\nprint(f'Acceder al valor por medio de la clave(my_dictionary[\"tag\"]): {my_dictionary[\"name\"]}')\n\nmy_dictionary['email'] = 'ye_mirandaa@yuber-miranda.website'\nprint(f'Agregar una clave con su valor al diccionario: {my_dictionary}')\n\ndel my_dictionary['email']\nprint(f'Eliminar del diccionario un valor por su clave: {my_dictionary}')\n\nprint(f'Keys(Obtener las keys del diccionario): {my_dictionary.keys()}')\n\nprint(f'Values(Obtener los valores del diccionario): {my_dictionary.values()}')\n\nprint('Recorrer un diccionario con un for:')\nfor key, value in my_dictionary.items():\n    print(key, value)\n\nprint(f'Buscar dentro de un diccionario por la clave: {\"x\" in my_dictionary}')\n\nprint(f'Obtener valor de un diccionario por la clave: {my_dictionary.get(\"x\")}')\n\nprint(f'Si no existe la clave, retorna un valor por defecto: {my_dictionary.get(\"t\", 9)}')\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/NeosV.py",
    "content": "# estructuras en python\n\"\"\"\nlist = [1, 2, 3,4]\n\ntuplas = [1,2,3,4] #los objetos de la tupla son inmutables una vez declarados\n\ndiccionario = {\"a\": 1, \"b\":2 } #incuyre una key y un value asignado\n\nset = set([1 , 2, 45, 6 ,7 ,9, 5, 2, 2, 3])\nprint (set)\n\nfrozenset = frozenset([1, 2, 3, 4, 5]) #una vez iniciado es inmutable\n\n\n#Insercion, borrado , actualizacion y ordenacion\n\nlista = [1,2,2,1,45,6,7,2,12,543,23,5,6,9]\n\nlista.append (9)\nprint (lista)\n\nlista.insert (2,3)\nprint (lista)\n\nlista[2] = 0\n\nprint (lista)\n\nlista.remove (9)\n\nprint (lista)\n\ndel lista[3]\nprint (lista)\n\nlista.sort()\nprint (lista)\n\nsorted(lista)\nprint (lista) \"\"\"\n\n\n# Ejercicio Dificultad Extra \n\nagenda = {}\n\ndef my_agenda():\n\n    def insert_agenda():\n\n        phone = input(\"Ingrese el teléfono del contacto: \")\n\n        if phone.isdigit() and len(phone) > 0 and len(phone) <= 10:\n            agenda[name] = phone\n            \n        else: \n            print(\"El número debe tener 10 dígitos o menos.\")\n\n    while True:\n    \n        print(\"\")\n        print(\"1. Buscar contacto\")\n        print(\"2. Insertar contacto\")\n        print(\"3. Actualizar contacto\")\n        print(\"4. Eliminar contacto\")\n        print(\"5. Salir\")\n\n        option = input (\"Selecciona una opción: \") \n\n        match option:\n\n            case \"1\":\n                name = input(\"Ingrese el nombre del contacto a buscar: \")\n                if name in agenda:  \n                    print (f\"El número asociado al contacto {name} es {agenda[name]}.\" )\n                else:\n                    print (f\"El contacto {name} no existe.\")\n\n            case \"2\":\n                 name = input(\"Ingrese el nombre del nuevo contacto: \")\n                 insert_agenda()\n                 print (\"Contacto agregado correctamente\")\n\n            case \"3\":\n                name = input(\"Ingrese el nombre del contacto a actualizar: \")\n                if name in agenda :\n                    insert_agenda()\n                    print (\"Telefono actualizado correctamente\")\n                else: \n                    print (f\"El contacto {name} no existe.\")\n\n            case \"4\":\n                name = input(\"Ingrese el nombre del contacto a eliminar: \")\n                if name in agenda :\n                    del agenda [name]\n                else: \n                    print (f\"El contacto {name} no existe.\")\n\n            case \"5\":\n                print (\"Saliendo de la agenda.\")\n                break\n\n            case _:\n                print (\"Opción no válida, selecciona una opción del 1 al 5.\")\n\nmy_agenda()\n\n\n\n   \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/NicoHeguaburu.py",
    "content": "#ESTRUCTURA DE DATOS\n#lista (list)\nlista = [1,2,3,4,5]\nlista.append(6) #agregar un elemento a la lista\nprint(lista)\nlista.remove(2) #eliminacion del elemento\nprint(lista)\nlista[0] = 7 #actualizacion del elemento\nprint(lista)\nlista.sort() #orden de los elementos\nprint(lista)\n\n#tupla (tuple)\ntupla = (1,2,3,4) #son inmutables no se pueden modificar\nprint (tupla)\n\n#diccionario (dict)\ndiccionario = {\n    \"Nombre\": \"Nicolás\",\n    \"Edad\": 22,\n    \"Estatura\": 1.87\n    }\ndiccionario[\"Ciudad\"] = \"Montevideo\"   #agregar un elemento clave-valor\nprint(diccionario)\ndiccionario[\"Edad\"] = 23    #actualizacion del valor\nprint(diccionario[\"Edad\"])\ndel diccionario[\"Estatura\"]   #eliminacion de clave-valor\nprint(diccionario)\n\n#Conjunto (set)\nconjunto = {1,2,3,4,5} #estructuras desordenadas sin duplicados\nconjunto.add(9) #agregar un elemento\nprint(conjunto)\nconjunto.remove(4)\nprint(conjunto)\n\n\n\n\n# DIFICULTAD EXTRA\n# AGENDA\n\nmi_agenda = {}\n\ndef agendar():\n    nombre = input(\"nombre:\")\n    numero = int(input(\"numero:\"))\n    while len(str(numero)) != 8:\n        print(\"numero incorrecto\")\n        numero = int(input(\"numero:\"))\n    agendado = {\"Nombre\": nombre, \"Numero\": numero}\n    mi_agenda[nombre] = agendado\n    print(\"se a agendado correctamente el contacto\")\n\n\n\ndef actualizar():\n    nombre_actualizar = input(\"nombre de contacto a actualizar: \")\n    if nombre_actualizar in mi_agenda:\n        nuevo_numero = input(\"Nuevo numero:\")\n        if len(str(nuevo_numero)) == 8:\n            mi_agenda[nombre_actualizar][\"Numero\"] = nuevo_numero\n        else:\n            print(\"numero incorrecto\")\n    else:\n        print(\"no existe el contacto\")\n\n\ndef eliminar():\n    nombre_eliminar = input(\"nombre de contacto a eliminar: \")\n    if nombre_eliminar in mi_agenda:\n        del mi_agenda[nombre_eliminar]\n        print(f\"Se a elmiminado el contacto {nombre_eliminar}\")\n    else:\n        print(\"no existe el contacto\")\n        \ndef busqueda():\n    nombre_buscar = input(\"nombre de contacto a buscar: \")\n    if nombre_buscar in mi_agenda:\n        print(mi_agenda[nombre_buscar])\n    else:\n        print(\"no existe el contacto\")\n\n\ndef menu():\n    print(\"Menu de la agenda\")\n    print(\"1----------Agendar contacto\")\n    print(\"2----------Eliminar contacto\")\n    print(\"3----------Buscar contacto\")\n    print(\"4----------Actualizar contacto\")\n    print(\"5----------Salir\")\n\n    accion = input()\n    if accion == \"1\":\n        agendar()\n    elif accion == \"2\":\n        eliminar()\n    elif accion == \"3\":\n        busqueda()\n    elif accion == \"4\":\n        actualizar()\n    elif accion == \"5\":\n        exit()\n    else:\n        print(\"Digite un numero valido\")\n    menu()\n\n\nmenu()\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Nicojsuarez2.py",
    "content": "'''\n# #03 ESTRUCTURAS DE DATOS\n> #### Dificultad: Media | Publicación: 15/01/24 | Corrección: 22/01/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n'''\nlista = [1, 2, 3, 4, 5]\nlista.append(6)\nlista.remove(3)\nlista[2] = 10\nlista.sort()\nlista.reverse()\n\nprint('-' * 100)\n\ndict = {\n    \"nombre\": \"Nico\",\n    \"edad\": 23,\n    \"ciudad\": \"Bogotá\"\n}\ndict[\"edad\"] = 24\ndict[\"profesion\"] = \"Desarrollador\"\ndict.pop(\"ciudad\")\n\n\nprint('-' * 100)\n\ntupla = (1, 2, 3, 4, 5)\ntupla.count(2)\ntupla.index(4)\n\n\nset = {1, 2, 3, 4, 5}\nset.add(6)\nset.remove(3)\nset.add(10)\nset.pop()\nset.clear()\nset.add(1)\nset.add(2)\nset.add(3)\n\nlistadelista = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]\nlistadelista[0].append(4)\nlistadelista[1].remove(5)\nlistadelista[2][2] = 10\nlistadelista.sort()\nlistadelista.reverse()\n\n\n\ndictofdict = {\n    \"persona1\": {\n        \"nombre\": \"Nico\",\n        \"edad\": 23,\n        \"ciudad\": \"Bogotá\"\n    },\n    \"persona2\": {\n        \"nombre\": \"Juan\",\n        \"edad\": 24,\n        \"ciudad\": \"Medellín\"\n    },\n    \"persona3\": {\n        \"nombre\": \"Pedro\",\n        \"edad\": 25,\n        \"ciudad\": \"Cali\"\n    }\n}\ndictofdict[\"persona1\"][\"edad\"] = 24\ndictofdict[\"persona1\"][\"profesion\"] = \"Desarrollador\"\ndictofdict[\"persona1\"].pop(\"ciudad\")\n\nprint('-' * 100)\n\ndef agenda(): \n    agenda = {}\n    while True:\n        print(\"1. Añadir contacto\")\n        print(\"2. Buscar contacto\")\n        print(\"3. Actualizar contacto\")\n        print(\"4. Eliminar contacto\")\n        print(\"5. Salir\")\n\n        opcion = int(input(\"¿Qué operación deseas realizar? \"))\n\n        match opcion:\n            case 1:\n                nombre = input(\"Nombre: \")\n                telefono = input(\"Teléfono: \")\n                if telefono.isdigit() and len(telefono) == 11:\n                    agenda[nombre] = telefono\n                else:\n                    print(\"Número de teléfono no válido\")\n            case 2:\n                nombre = input(\"Nombre: \")\n                if nombre in agenda:\n                    print(f\"Teléfono: {agenda[nombre]}\")\n                else:\n                    print(\"Contacto no encontrado\")\n            case 3:\n                nombre = input(\"Nombre: \")\n                if nombre in agenda:\n                    telefono = input(\"Teléfono: \")\n                    if telefono.isdigit() and len(telefono) == 11:\n                        agenda[nombre] = telefono\n                    else:\n                        print(\"Número de teléfono no válido\")\n                else:\n                    print(\"Contacto no encontrado\")\n            case 4:\n                nombre = input(\"Nombre: \")\n                if nombre in agenda:\n                    agenda.pop(nombre)\n                else:\n                    print(\"Contacto no encontrado\")\n            case 5:\n                break\n            case _:\n                print(\"Opción no válida\")\n\nagenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/NightAlchemist.py",
    "content": "#----------------------------------------\n#Lists - is a collection which is ordered and changeable. Allows duplicate members.\n#----------------------------------------\n\n#Creating a list\n\nfirst_list = [1, 2, 3, 4, 5]    #Note the square brackets\nprint(first_list)\n\n#Lists can contain different types of data\n\nmixed_list = [1, 2.5, \"string\", True]\nprint(mixed_list)\n\n#Lists can be nested\n\nnested_list = [1, 2, [3, 4, 5], 6]\nprint(nested_list)\n\n#Empty list\n\nempty_list = []\nprint(empty_list)\n\n#----------------------------------------\n#tuple - is a collection which is ordered and unchangeable. Allows duplicate members.\n#----------------------------------------\n\n#Creating a tuple\n\nfirst_tuple = (1, 2, 3, 4, 5)   #Note the parentheses\nprint(first_tuple)\n\n#Tuples can contain different types of data\n\nmixed_tuple = (1, 2.5, \"string\", True)\nprint(mixed_tuple)\n\n#Tuples can be nested\n\nnested_tuple = (1, 2, (3, 4, 5), 6)\nprint(nested_tuple)\n\n#Single element tuple\n\nsingle_element_tuple = (1,)    #Note the comma\nprint(single_element_tuple)\n\n#Empty tuple\n\nempty_tuple = ()\nprint(empty_tuple)\n\n#----------------------------------------\n#set - is a collection which is unordered, unchangeable and unindexed. No duplicate members.\n#----------------------------------------\n\n#Creating a set\n\nfirst_set = {1, 2, 3, 4, 5}   #Note the curly braces\nprint(first_set)\n\n#Sets can contain different types of data\n\nmixed_set = {1, 2.5, \"string\", True}\nprint(mixed_set)\n\n#Empty set\n\nempty_set = set()\nprint(empty_set)\n\n#----------------------------------------\n#dictionary - is a collection which is ordered and changeable. No duplicate members.\n#----------------------------------------\n\n#Creating a dictionary\n\nfirst_dict = {   #Note the curly braces\n    \"name\": \"John\",\n    \"age\": 30,\n    \"city\": \"New York\"\n}\nprint(first_dict)\n\n#Dictionaries can contain different types of data\n\nmixed_dict = {\n    \"name\": \"John\",\n    \"age\": 30,\n    \"city\": \"New York\",\n    \"is_student\": True\n}\nprint(mixed_dict)\n\n#Nested dictionary\n\nnested_dict = {\n    \"name\": \"John\",\n    \"age\": 30,\n    \"address\": {\n        \"street\": \"Main Street\",\n        \"city\": \"New York\"\n    }\n}\nprint(nested_dict)\n\n#Empty dictionary\n\nempty_dict = {}\nprint(empty_dict)\n\n#----------------------------------------\n#inserting elements in a list, tuple, set, dictionary\n#----------------------------------------\n\n#lists\n\n#append() - adds an element at the end of the list\n\nfirst_list = [1, 2, 3, 4, 5]\nfirst_list.append(6)    #Append 6 at the end\nprint(first_list)   #Output: [1, 2, 3, 4, 5, 6]\n\n#insert() - adds an element at the specified position\n\nfirst_list = [1, 2, 3, 4, 5]\nfirst_list.insert(2, 6)   #Insert 6 at index 2\nprint(first_list)   #Output: [1, 2, 6, 3, 4, 5]\n\n#extend() - adds elements of a list to another list\n\nfirst_list = [1, 2, 3, 4, 5]\nsecond_list = [6, 7, 8]\nfirst_list.extend(second_list)    #Add elements of second_list to first_list\nprint(first_list)   #Output: [1, 2, 3, 4, 5, 6, 7, 8]\n\n#tuples\n\n#Tuples are immutable, so you can't add elements to them\n\n#sets\n\n#add() - adds an element to the set\n\nfirst_set = {1, 2, 3, 4, 5}\nfirst_set.add(6)    #Add 6 to the set\nprint(first_set)    #Output: {1, 2, 3, 4, 5, 6}\n\n#update() - adds elements of a set to another set\n\nfirst_set = {1, 2, 3, 4, 5}\nsecond_set = {6, 7, 8}\nfirst_set.update(second_set)    #Add elements of second_set to first_set\nprint(first_set)    #Output: {1, 2, 3, 4, 5, 6, 7, 8}\n\n#dictionaries\n\n#update() - adds elements of a dictionary to another dictionary\n\nfirst_dict = {\n    \"name\": \"John\",\n    \"age\": 30\n}\nsecond_dict = {\n    \"city\": \"New York\"\n}\nfirst_dict.update(second_dict)    #Add elements of second_dict to first_dict\n\nprint(first_dict)    #Output: {'name': 'John', 'age': 30, 'city': 'New York'}\n\n#----------------------------------------\n#deleting elements in a list, tuple, set, dictionary\n#----------------------------------------\n\n#lists\n\n#remove() - removes the first occurrence of the element with the specified value\n\nfirst_list = [1, 2, 3, 4, 5]\nfirst_list.remove(3)    #Remove 3 from the list\nprint(first_list)    #Output: [1, 2, 4, 5]\n\n#pop() - removes the element at the specified position\n\nfirst_list = [1, 2, 3, 4, 5]\nfirst_list.pop(2)    #Remove element at index 2\nprint(first_list)    #Output: [1, 2, 4, 5]\n\n#del - removes the element at the specified position\n\nfirst_list = [1, 2, 3, 4, 5]\ndel first_list[2]    #Remove element at index 2\nprint(first_list)    #Output: [1, 2, 4, 5]\n\n#del - removes the entire list\n\nfirst_list = [1, 2, 3, 4, 5]\ndel first_list    #Remove the entire list\n#print(first_list)    #This will raise an error\n\n#clear() - removes all elements from the list\n\nfirst_list = [1, 2, 3, 4, 5]\nfirst_list.clear()    #Remove all elements\nprint(first_list)    #Output: []\n\n#tuples\n\n#Tuples are immutable, so you can't delete elements from them\n\n#sets\n\n#remove() - removes the specified element\n\nfirst_set = {1, 2, 3, 4, 5}\nfirst_set.remove(3)    #Remove 3 from the set\nprint(first_set)    #Output: {1, 2, 4, 5}\n\n#discard() - removes the specified element\n\nfirst_set = {1, 2, 3, 4, 5}\nfirst_set.discard(3)    #Remove 3 from the set\nprint(first_set)    #Output: {1, 2, 4, 5}\n\n#pop() - removes a random element\n\nfirst_set = {1, 2, 3, 4, 5}\nfirst_set.pop()    #Remove a random element\nprint(first_set)    #Output: {2, 3, 4, 5}\n\n#clear() - removes all elements from the set\n\nfirst_set = {1, 2, 3, 4, 5}\nfirst_set.clear()    #Remove all elements\nprint(first_set)    #Output: set()\n\n#dictionaries\n\n#pop() - removes the element with the specified key\n\nfirst_dict = {\n    \"name\": \"John\",\n    \"age\": 30\n}\nfirst_dict.pop(\"age\")    #Remove the element with key \"age\"\nprint(first_dict)    #Output: {'name': 'John'}\n\n#popitem() - removes the last inserted key-value pair\n\nfirst_dict = {\n    \"name\": \"John\",\n    \"age\": 30\n}\nfirst_dict.popitem()    #Remove the last inserted key-value pair\nprint(first_dict)    #Output: {'name': 'John'}\n\n#del - removes the element with the specified key\n\nfirst_dict = {\n    \"name\": \"John\",\n    \"age\": 30\n}\ndel first_dict[\"age\"]    #Remove the element with key \"age\"\nprint(first_dict)    #Output: {'name': 'John'}\n\n#del - removes the entire dictionary\n\nfirst_dict = {\n    \"name\": \"John\",\n    \"age\": 30\n}\ndel first_dict    #Remove the entire dictionary\n#print(first_dict)    #This will raise an error\n\n#clear() - removes all elements from the dictionary\n\nfirst_dict = {\n    \"name\": \"John\",\n    \"age\": 30\n}\nfirst_dict.clear()    #Remove all elements\nprint(first_dict)    #Output: {}\n\n#----------------------------------------\n#accessing elements in a list, tuple, set, dictionary\n#----------------------------------------\n\n#lists\n\n#Accessing elements by index\n\nfirst_list = [1, 2, 3, 4, 5]\nprint(first_list[2])    #Output: 3\n\n#Accessing elements by negative index\n\nfirst_list = [1, 2, 3, 4, 5]\nprint(first_list[-2])    #Output: 4\n\n#Accessing elements by range of indices\n\nfirst_list = [1, 2, 3, 4, 5]\nprint(first_list[1:4])    #Output: [2, 3, 4]\n\n#Accessing elements by negative range of indices\n\nfirst_list = [1, 2, 3, 4, 5]\nprint(first_list[-4:-1])    #Output: [2, 3, 4]\n\n#Accessing elements by range of indices with step\n\nfirst_list = [1, 2, 3, 4, 5]\nprint(first_list[1:4:2])    #Output: [2, 4] (start:stop:step)\n\n#tuples\n\n#Accessing elements by index\n\nfirst_tuple = (1, 2, 3, 4, 5)\nprint(first_tuple[2])    #Output: 3\n\n#Accessing elements by negative index\n\nfirst_tuple = (1, 2, 3, 4, 5)\nprint(first_tuple[-2])    #Output: 4\n\n#Accessing elements by range of indices\n\nfirst_tuple = (1, 2, 3, 4, 5)\nprint(first_tuple[1:4])    #Output: (2, 3, 4)\n\n#Accessing elements by negative range of indices\n\nfirst_tuple = (1, 2, 3, 4, 5)\nprint(first_tuple[-4:-1])    #Output: (2, 3, 4)\n\n#Accessing elements by range of indices with step\n\nfirst_tuple = (1, 2, 3, 4, 5)\nprint(first_tuple[1:4:2])    #Output: (2, 4) (start:stop:step)\n\n#sets\n\n#Sets are unordered, so you can't access elements by index\n\n#dictionaries\n\n#Accessing elements by key\n\nfirst_dict = {\n    \"name\": \"John\",\n    \"age\": 30\n}\nprint(first_dict[\"name\"])    #Output: John\n\n#Accessing elements using get()\n\nfirst_dict = {\n    \"name\": \"John\",\n    \"age\": 30\n}\nprint(first_dict.get(\"name\"))    #Output: John\n\n#Accessing elements using items()\n\nfirst_dict = {\n    \"name\": \"John\",\n    \"age\": 30\n}\nfor key, value in first_dict.items():\n    print(key, value)    #Output: name John, age 30\n\n#----------------------------------------\n#ordering elements in a list, tuple, set, dictionary\n#----------------------------------------\n\n#lists\n\n#sort() - sorts the list\n\nfirst_list = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]\nfirst_list.sort()\nprint(first_list)    #Output: [1, 1, 2, 3, 3, 4, 5, 5, 5, 6, 9]\n\n#reverse() - reverses the list\n\nfirst_list = [1, 2, 3, 4, 5]\nfirst_list.reverse()\nprint(first_list)    #Output: [5, 4, 3, 2, 1]\n\n#tuples\n\n#Tuples are immutable, so you can't order them\n\n#sets\n\n#Sets are unordered, so you can't order them\n\n#dictionaries\n\n#sorted() - sorts the dictionary by key\n\nfirst_dict = {\n    \"name\": \"John\",\n    \"age\": 30,\n    \"city\": \"New York\"\n}\nsorted_dict = dict(sorted(first_dict.items()))\nprint(sorted_dict)    #Output: {'age': 30, 'city': 'New York', 'name': 'John'}\n\n#----------------------------------------\n#Extra - Contact List\n#----------------------------------------\n\ndef my_agenda():\n    contacts = {}  # Dictionary to store contacts\n\n    while True:\n        print(\"\\nContact Agenda\")\n        print(\"1. Add Contact\")\n        print(\"2. Search Contact\")\n        print(\"3. Update Contact\")\n        print(\"4. Delete Contact\")\n        print(\"5. Show Contacts\")\n        print(\"6. Exit\")\n        \n        choice = input(\"Choose an option (1-6): \").strip()\n\n        match choice:\n            case \"1\":\n                name = input(\"Enter contact name: \").strip()\n                phone = input(\"Enter phone number (max 11 digits): \").strip()\n                if phone.isdigit() and len(phone) <= 11:\n                    contacts[name] = phone\n                    print(f\"Contact {name} added successfully.\")\n                else:\n                    print(\"Invalid phone number. It must be numeric and up to 11 digits.\")\n            \n            case \"2\":\n                name = input(\"Enter contact name to search: \").strip()\n                if name in contacts:\n                    print(f\"{name}: {contacts[name]}\")\n                else:\n                    print(\"Contact not found.\")\n\n            case \"3\":\n                name = input(\"Enter contact name to update: \").strip()\n                if name in contacts:\n                    new_phone = input(\"Enter new phone number (max 11 digits): \").strip()\n                    if new_phone.isdigit() and len(new_phone) <= 11:\n                        contacts[name] = new_phone\n                        print(f\"Contact {name} updated successfully.\")\n                    else:\n                        print(\"Invalid phone number. It must be numeric and up to 11 digits.\")\n                else:\n                    print(\"Contact not found.\")\n\n            case \"4\":\n                name = input(\"Enter contact name to delete: \").strip()\n                if name in contacts:\n                    del contacts[name]\n                    print(f\"Contact {name} deleted successfully.\")\n                else:\n                    print(\"Contact not found.\")\n\n            case \"5\":\n                if contacts:\n                    print(\"\\nYour Contacts:\")\n                    for name, phone in contacts.items():\n                        print(f\"{name}: {phone}\")\n                else:\n                    print(\"No contacts available.\")\n\n            case \"6\":\n                print(\"Exiting program. Goodbye!\")\n                break\n\n            case _:\n                print(\"Invalid option. Please choose between 1 and 6.\")\n\n# Run the contact agenda\nmy_agenda()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Nightblockchain30.py",
    "content": "'''\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n\n'''\n\n#BUILT IN DATA STRUCTURES\n\n## 1. List\nmy_list = [2,3,4,-10-4]\nother_list = list()\nmy_new_list = [x for x in my_list if x >= 0]\n\n\n# Using listComp: select all columns of matrix in one line\nmatrix = [\n    [1, 2, 3, 4],\n    [5, 6, 7, 8],\n    [9, 10, 11, 12],\n]\n\ntranspuesta = []\nfor i in range(len(matrix)):\n    column_list = []\n    for column in matrix:\n        column_list.append(column[i])\n    transpuesta.append(column_list)\n    #print(transpuesta)\nprint(f\"Sin usar listas de comprensión: {transpuesta}\")\n\nlistcomp_transpuesta = [[column[i] for column in matrix] for i in range(len(matrix))]\nprint(f\"Usando listas de comprensión: {listcomp_transpuesta}\")\n\n\n## 2. Tuples\n# Son una estructura inmutable aunque puede contener datos mutables como las listas etc...\nmy_tuple = (1234,6789,\"Alonso\",\"Mimi\",[9,10,11])\nother_tuple = tuple()\n\n# Empaquetado VS Desempaquetado de secuencias\ntupla_palabras = (\"word1\",\"word2\",\"word3\")\n# Proceso de desempaquetado de secuencias: IMPORTANTE--> Siempre el número de variables de la izquierda tiene que sel igual al número de la secuencia\nw1, w2, w3 = tupla_palabras\nprint(f\"Mi palabra1: es {w1.upper()}, mi palabra2: {w2.upper()} y la tercera es: {w3.upper()}\")\n\n## 3.Sets. Es una estructura de datos NO ordenada de elementos ÚNICOS \nmi_set = {\"manzana\",\"pera\",\"pera\",\"manzana\",\"platano\",\"uvas\"}\nprint(f\"Mi set SIN setComprension: {mi_set}\")\n\nsetComp = {x for x in mi_set}\nprint(f\"Mi set CON setComprension: {setComp}\")\n\na = {x for x in \"abracadabra\" if x not in \"abc\"}\nprint(a)\n\n\n## 4. Dict: A diferencia de estructuras como las listas o las tuplas los diccionarios NO SE INDEXAN de forma numérica sino a través de claves\nmy_dict = {\n    \"nombre\":\"Mimi\",\n    \"edad\": 26,\n    \"profesión\":\"Periodista\"\n}\n# Imprimo solo las llaves del diccionario\nprint(list(my_dict))\n# También podemos crear dict con DictComp\ndict_al_cuadrado = {\"Num(\"+str(x)+\")\":\"Potencia(\"+str(x*2)+\")\" for x in dict_numerico}\n\nprint(\" ----------------------------------- \")\n\n'''\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n\n'''\nagenda = {}\n\ndef agregar_contacto():\n    isContinue = True\n    while isContinue:\n        name = str(input(\"Introduce el nombre del contacto: \"))\n        phone = input(\"Introduce el número del contacto: \")\n\n        if name not in agenda:\n            if (phone.isdigit()) and (0 < len(phone) <= 11):\n                agenda[name] = phone\n                print(\"✅ Contacto agregado\")\n                isContinue = False\n            else:\n                print(\"💥 ERROR: Introduce datos válidos por favor \")\n        else:\n            print(\"💥 ERROR: Usuario ya existente. \")\n\n\ndef buscar_contacto():\n    name = input(\"Introduce el nombre del usuario que quieres: \\n\")\n    if name in agenda:\n        print(f\" ▶▶▶ El número de {name.upper()} es {agenda[name]}\")\n    else:\n        print(\"💥 ERROR: Usuario no existe \")\n\n\ndef eliminar_contacto():\n    name = input(\"Introduce el nombre del usuario que quieres eliminar: \\n\")\n    if name in agenda:\n        del agenda[name]\n        print(f\" ▶▶▶ El usuario {name.upper()} ha sido eliminado \")\n    else:\n        print(\"💥 ERROR: Usuario no existente. \")\n\n\ndef actualizar_contacto():\n    name = input(\"Introduce el nombre del usuario que quieres actualizar: \\n\")\n    phone = input(\"Introduce el numero del usuario que quieres actualizar: \\n\")\n    if name in agenda:\n        print(f\" ▶▶▶ El usuario {name.upper()} ha sido actualizado \")\n        agenda[name] = phone\n    else:\n        print(\"💥 ERROR: Usuario no existente. \")\n\n\nwhile True:\n    print(\"\"\" \n        << Agenda Nightblockchain30 >>\n        \n            1. Agregar un contacto\n            2. Buscar un contacto\n            3. Eliminar un contacto\n            4. Actualizar un contacto\n            5. Salir de la agenda\n\"\"\")\n    option = int(input(\"Elige una de las siguientes opciones: \\n\"))\n\n    match option:\n        case 1:\n            agregar_contacto()\n        case 2:\n            buscar_contacto()\n        case 3:\n            eliminar_contacto()\n        case 4:\n            actualizar_contacto()\n        case 5:\n            break\n        \n\nprint(f\"Gracias por tu confianza! Saludos‼\")\n        \n\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/NoMeLlamoDante.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n\"\"\"\n# Listas \nmy_list = [\"pera\",\"uva\",\"manzana\", 1, 2, 3, False, True]\nprint(type(my_list))\nprint(my_list)\n\n#! Accedder a los elementos\nprint(my_list[0]) # pera\nprint(my_list[-1]) # True\nprint(my_list[1:3]) # ['uva', 'manzana']\nprint(my_list[-5:]) # [1, 2, 3, False, True]\n\n### Verificar si un elemento está en la lista\nif \"uva\" in my_list:\n    print(\"La uva está en la lista\")\n\n#! Modificar elementos\nmy_list[1:3] = \"piña\", \"limon\" # Reemplaza uva Y manzana\nprint(my_list)\n\n#! Agregar Elementos\n#* Agregar un elemento\nmy_list.insert(1,\"sandia\")\nmy_list.append(\"elemento agregado al final\")\nprint(my_list)\n\n#* Agregar una lista a otra lista\nmy_other_list = [\"rosas\", \"girasoles\"]\nmy_list.extend(my_other_list)\nprint(my_list)\n\n#! Eliminar elementos\n#* Eliminar un elemento usano el elemento\nmy_list.remove(\"elemento agregado al final\")\n\n#* Eliminar un elemento usando el índice\nmy_list.pop(8)\ndel my_list[7]\nprint(my_list)\n\n#* Eliminar todos los elemmentos de la lista\nmy_list.clear()\nprint(my_list)\n\n#! Ordenar Listas\nlista_numeros = [6, 1, 5, 3, 4, 2]\nprint(lista_numeros)\n\nlista_frutas = [\"pera\",\"uva\",\"manzana\", \"limon\", \"sandia\"]\nprint(lista_frutas)\n\n#* Orenar numericos\nlista_numeros.sort()\nprint(lista_numeros)\n\n#* Ordenar numericos inversamente\nlista_numeros.sort(reverse=True)\nprint(lista_numeros)\n\n#* Ordenar Alfabéticamente\nlista_frutas.sort()\nprint(lista_frutas)\n\n#* Ordenar Alfabéticamente inversamente\nlista_frutas.sort(reverse=True)\nprint(lista_frutas)\n\n#* Ordenar por otros criterios (longitud)\nlista_frutas.sort(key = lambda x: len(x))\nprint(lista_frutas)\n\n# Tuplas\ntupla_animales = (\"perro\", \"gato\", \"raton\")\nprint(type(tupla_animales))\nprint(tupla_animales)\n\n### Acceder a elementos\nprint(tupla_animales[0]) # perro\nprint(tupla_animales[-1]) # raton\nprint(tupla_animales[:2]) # ('perro', 'gato')\nprint(tupla_animales[-2:]) # ('gato', 'raton')\n\n#! Verificar si existe un dato en una tupla\nif \"perro\" in tupla_animales:\n    print(\"El perro está en la tupla\")\n\n#! Modificar tuplas\n\"\"\"\nLas tuplas son inmutables, por lo que no se pueden modificar,\npero si se pueden copiar a iterable (como las listas), modificar y reasignar\n! Esto se puede aplicar para \n* modificar un elemmento\n* eliminar elemmentos\n* agregar elemmentos\n* concatenar tuplas\n\"\"\"\n# Sets\nset_mezclado = {\"cebolla\", \"tomate\", \"ajo\", 1, 2, 3, False, True}\nprint(type(set_mezclado))\nprint(set_mezclado)\n\n#! Acceder a elementos\n\"\"\"\nNo se puede acceder a elementos de un set por índice o llave\naunque se puede verificar si un elemento se encuentra entro de un set o no\n\"\"\"\n\nif \"tomate\" in set_mezclado:\n    print(\"El tomate está en el set\")\n    \n#! Agregar elementos\n#* Agregar un elemento\nset_mezclado.add(\"papa\")\nprint(set_mezclado)\n\n#* Agregar varios elementos\nespecias = {\"oregano\", \"comino\", \"paprika\"}\nset_mezclado.update(especias) #Tambien funciona .union()\nprint(set_mezclado)\n\n#! Eliminar elementos\nset_mezclado.remove(True)\nset_mezclado.pop() #Pop no perite indice, elimina el primer elemento\nprint(set_mezclado)\n\nset_mezclado.clear()\nprint(set_mezclado)\n\n# Diccionarios\ndiccionario_ingredientes = {\n    \"tomate\":{\n        \"cantidad\": 2,\n        \"categoria\": \"verdura\",\n        \"color\": \"rojo\",\n    },\n    \"papa\":{\n        \"cantidad\": 1,\n        \"categoria\": \"verdura\",\n        \"color\": \"amarillo\",\n    },\n    \"coco\":{\n        \"cantidad\": 3,\n        \"categoria\": \"fruta\",\n        \"color\": \"blanco\",\n    }\n}\nprint(type(diccionario_ingredientes))\nprint(diccionario_ingredientes)\n\n#! Acceder a elementos\nprint(diccionario_ingredientes[\"tomate\"]) # {'cantidad': 2, 'categoria': 'verdura', 'color': 'rojo'}\nprint(diccionario_ingredientes[\"tomate\"][\"cantidad\"]) # 2\nelement = diccionario_ingredientes.get(\"coco\")\nprint(element) # {'cantidad': 3, 'categoria': 'fruta', 'color': 'blanco'}\nprint(element.keys()) # dict_keys(['cantidad', 'categoria', 'color'])\nprint(element.values()) # dict_values([3, 'fruta', 'blanco'])\n\n#! Modificar elementos\nelement[\"cantidad\"] = 4\nprint(element)\n\nelement.update({\"cantidad\": 5, \"color\": \"cafe\"})\nprint(element)\n\n#! Agregar elementos\ndiccionario_ingredientes[\"cebolla\"] = {\n    \"cantidad\": 1,\n    \"categoria\": \"verdura\",\n    \"color\": \"morado\",\n}\nprint(diccionario_ingredientes)\n\nelement.update({\"sabor\": \"dulce\"})\nprint(element)\n\n#! Eliminar elementos\ndiccionario_ingredientes.pop(\"papa\")\nprint(diccionario_ingredientes)\n\ndiccionario_ingredientes.popitem() #Elimina el último elemento\nprint(diccionario_ingredientes)\n\ndel diccionario_ingredientes[\"tomate\"]\nprint(diccionario_ingredientes)\n\n#! Vaciar Diccionario\nelement.clear() \nprint(element)\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n\"\"\"\n\nagenda = {}\nopciones = (\"1\", \"2\", \"3\", \"4\", \"0\")\n\ndef buscar_contacto(nombre:str):\n    if nombre in agenda:\n        return f\"Nombre: {nombre}, Telefono: {agenda[nombre]}\"\n    return False\n\ndef agregar_contacto(nombre:str, telefono:int):\n    if not buscar_contacto(nombre.lower()):\n        agenda[nombre] = telefono\n        return f\"{nombre} agregado correctamente\"\n    return False\n\ndef modificar_contacto(nombre:str, telefono:int):\n    if buscar_contacto(nombre):\n        agenda[nombre] = telefono\n        return f\"{nombre} actualizado a {agenda[nombre]} \"\n    return False\n\ndef eliminar_contacto(nombre:str):\n    if buscar_contacto(nombre):\n        agenda.pop(1)\n        return f\"{nombre} eliminado\"\n    return False\n\ndef solicitarNombre():\n    while True:\n        nombre = input(\"Ingrese el nombre o 0 para salir: \")\n        if nombre.isdigit():\n            print(f\"Nombre invalido {nombre}\")\n            continue\n        elif nombre == \"0\":\n            return False\n        return nombre\n\ndef solicitarNumero():\n    while True:\n        telefono = input(\"Ingrese Telefono o 0 para salir: \")\n        if telefono.isnumeric() and len(telefono) == 10:\n            return telefono\n        elif telefono == \"0\":\n            return False\n        print(f\"Numero invalido: {telefono}\")\n\ndef interfaz():\n    print(\"Bienvenido a la agenta de contactos\")\n    \n    # Ciclo infinito\n    while True:\n        # Mostrar opciones\n        print(f\"\"\"\n            Actualmente hay {len(agenda)} {\"contacto\" if len(agenda) < 2 else \"contactos\"}  en la agenda\n            Inserte la opción deseada:\n            1. Buscar contacto\n            2. Agregar contacto\n            3. Actualizar contacto\n            4. Eliminar contacto\n            0. Salir\n            \"\"\")\n        \n        # Leer la opción y verifica si es válida\n        entrada = input(\"Opción: \")\n        if entrada not in opciones:\n            print(\"Opción no válida\")\n            continue\n        \n        # Salir\n        if entrada == \"0\":\n            print(\"Gracias por usar la agenda, adios\")\n            break\n        \n        # Buscar contacto\n        if entrada == \"1\":\n            print(\"Buscar contacto\")\n            nombre = solicitarNombre()\n            contacto = buscar_contacto(nombre)\n            if contacto:\n                print(contacto)\n            else:\n                print(\"Registro no encontrado\")\n        \n        # Agregar contacto (Mexico, 10 Numeros)\n        if entrada == \"2\":\n            print(\"Agregar contacto\")\n            nombre = solicitarNombre()\n            if nombre:\n                telefono = solicitarNumero()\n                if telefono:\n                    print(agregar_contacto(nombre, telefono))\n        \n        # Actualizar contacto\n        if entrada == \"3\":\n            print(\"Actualizar contacto\")\n            nombre = solicitarNombre()\n            if nombre:\n                contacto = buscar_contacto(nombre)\n                if not contacto:\n                    print(\"Registro no encontrado\")\n                    continue\n                print(contacto)\n                telefono = solicitarNumero()\n                if telefono:\n                    print(modificar_contacto(nombre, telefono))\n                    \n        # Eliminar contacto\n        if entrada == \"4\":\n            print(\"Eliminar contacto\")\n            nombre = solicitarNombre()\n            if nombre:\n                contacto = buscar_contacto(nombre)\n                if not contacto:\n                    print(\"Registro no encontrado\")\n                    continue\n                print(eliminar_contacto(nombre))\n\ninterfaz()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Pablo25.py",
    "content": "# 03 - Python - ESTRUCTURAS DE DATOS\n# Las estructuras de datos, son formas de organizar y almacenar datos de manera eficiente.\n# Cada uno con propiedades diferentes para diferentes usos.\n# La elección correcta de la estructura de datos puede mejorar significativamente el rendimiento y la legibilidad del código.\n\n#EJERCICIO:\n'''* - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.'''\n\n# Listas\nmi_lista = [1, 2, 3, 4, 5]\n\n# Tuplas\nmi_tupla = (1, 2, 3, 4, 5)\n\n# Conjuntos\nmi_conjunto = {1, 2, 3, 4, 5}\n\n# Diccionarios\nmi_diccionario = {\"uno\": 1, \"dos\": 2, \"tres\": 3}\n\n'''* - Utiliza operaciones de inserción, borrado, actualización y ordenación.'''\n\n# Operaciones en listas\nmi_lista.append(6)  # Inserción\nmi_lista.remove(2)  # Borrado\nmi_lista[0] = 0     # Actualización\nmi_lista.sort()     # Ordenación\n\n# Operaciones en tuplas\nmi_tupla = mi_tupla + (6,)  # Inserción (creando una nueva tupla)\nmi_tupla = mi_tupla[:1] + mi_tupla[2:]  # Borrado (creando una nueva tupla)\nmi_tupla = (0,) + mi_tupla[1:]  # Actualización (creando una nueva tupla)\n\n# Operaciones en conjuntos\nmi_conjunto.add(6)  # Inserción\nmi_conjunto.remove(2)  # Borrado\nmi_conjunto.update([7, 8])  # Actualización\nmi_conjunto = set(sorted(mi_conjunto))  # Ordenación\n\n# Operaciones en diccionarios\nmi_diccionario[\"cuatro\"] = 4  # Inserción\ndel mi_diccionario[\"dos\"]      # Borrado\nmi_diccionario[\"uno\"] = 0      # Actualización\nmi_diccionario = dict(sorted(mi_diccionario.items()))  # Ordenación\n\n'''* - Recorre las estructuras de datos con bucles.'''\n\n# Recorrido de listas\nfor elemento in mi_lista:\n    print(elemento)\n\n# Recorrido de tuplas\nfor elemento in mi_tupla:\n    print(elemento)\n\n# Recorrido de conjuntos\nfor elemento in mi_conjunto:\n    print(elemento)\n\n# Recorrido de diccionarios\nfor clave, valor in mi_diccionario.items():\n    print(clave, valor)\n\n'''* - Comprueba si tu lenguaje soporta estructuras de datos avanzadas\n(pilas, colas, listas enlazadas, árboles, grafos, tablas hash, etc.) y crea ejemplos de uso.'''\n# Python soporta pilas y colas a través de listas y la biblioteca collections.\n\nfrom collections import deque\n\n# Ejemplo de pila\npila = []\npila.append(1)\npila.append(2)\npila.append(3)\nprint(pila.pop())  # Salida: 3\n\n# Ejemplo de cola\ncola = deque()\ncola.append(1)\ncola.append(2)\ncola.append(3)\nprint(cola.popleft())  # Salida: 1\n\n# Ejemplo de tabla hash (diccionario en Python)\ntabla_hash = {}\ntabla_hash[\"clave1\"] = \"valor1\"\ntabla_hash[\"clave2\"] = \"valor2\"\nprint(tabla_hash[\"clave1\"])  # Salida: valor1\n\n'''DIFICULTAD EXTRA (opcional):\n * - Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n     y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no numéricos, \n     y con más de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.'''\n\n# Implementación de una agenda de contactos v1.0, con ayuda de copilot\nagenda = {} # Diccionario para almacenar contactos \ndef agregar_contacto(nombre, telefono):\n    if not telefono.isdigit() or len(telefono) > 11:\n        print(\"Número de teléfono no válido.\")\n        return\n    agenda[nombre] = telefono\n    print(f\"Contacto {nombre} agregado.\")\n\ndef buscar_contacto(nombre):\n    return agenda.get(nombre, \"Contacto no encontrado.\")\n\ndef actualizar_contacto(nombre, nuevo_telefono):\n    if not nuevo_telefono.isdigit() or len(nuevo_telefono) > 11:\n        print(\"Número de teléfono no válido.\")\n        return\n    if nombre in agenda:\n        agenda[nombre] = nuevo_telefono\n        print(f\"Contacto {nombre} actualizado.\")\n    else:\n        print(\"Contacto no encontrado.\")\n\ndef eliminar_contacto(nombre):\n    if nombre in agenda:\n        del agenda[nombre]\n        print(f\"Contacto {nombre} eliminado.\")\n    else:\n        print(\"Contacto no encontrado.\")\n\n# Implementación de una agenda de contactos v1.1, mejorando la estructura del código con ayuda de copilot y DeepSeek\ndef main():\n    agenda = {} # Diccionario para almacenar contactos\n    while True: # Interfaz de usuario\n        print(\"\\nAgenda de Contactos\") # Menú de opciones, \\n → \"Nueva línea\" (como presionar ENTER) Es un carácter de escape que crea un salto de línea.\n        print(\"1. Agregar contacto\")\n        print(\"2. Buscar contacto\")\n        print(\"3. Actualizar contacto\")\n        print(\"4. Eliminar contacto\")\n        print(\"5. Salir\")\n        opcion = input(\"Seleccione una opción: \")\n        if opcion == '1':\n            nombre = input(\"Ingrese el nombre del contacto: \")\n            telefono = input(\"Ingrese el número de teléfono: \")\n            agregar_contacto(agenda,nombre, telefono)\n        elif opcion == '2':\n            nombre = input(\"Ingrese el nombre del contacto a buscar: \")\n            print(buscar_contacto(agenda, nombre))\n        elif opcion == '3':\n            nombre = input(\"Ingrese el nombre del contacto a actualizar: \")\n            nuevo_telefono = input(\"Ingrese el nuevo número de teléfono: \")\n            actualizar_contacto(agenda, nombre, nuevo_telefono)\n        elif opcion == '4':\n            nombre = input(\"Ingrese el nombre del contacto a eliminar: \")\n            eliminar_contacto(agenda, nombre)\n        elif opcion == '5':\n            print(\"Saliendo de la agenda.\")\n            break\n        else:\n            print(\"Opción no válida. Intente de nuevo.\")\n\ndef agregar_contacto(agenda, nombre, telefono):\n    if not telefono.isdigit() or len(telefono) > 11:\n        print(\"Número de teléfono no válido.\")\n        return\n    agenda[nombre] = telefono\n    print(f\"Contacto {nombre} agregado.\")\n\ndef buscar_contacto(agenda, nombre):\n    return agenda.get(nombre, \"Contacto no encontrado.\")\n\ndef actualizar_contacto(agenda, nombre, nuevo_telefono):\n    if not nuevo_telefono.isdigit() or len(nuevo_telefono) > 11:\n        print(\"Número de teléfono no válido.\")\n        return\n    if nombre in agenda:\n        agenda[nombre] = nuevo_telefono\n        print(f\"Contacto {nombre} actualizado.\")\n    else:\n        print(\"Contacto no encontrado.\")\n\ndef eliminar_contacto(agenda, nombre):\n    if nombre in agenda:\n        del agenda[nombre]\n        print(f\"Contacto {nombre} eliminado.\")\n    else:\n        print(\"Contacto no encontrado.\")\nif __name__ == \"__main__\":\n    main()\n\n# Implementación de una agenda de contactos v1.1.1, mejorando la funcionalidad de búsqueda\n# y agregando opción para mostrar todos los contactos, con ayuda de copilot y DeepSeek\ndef main():\n    agenda = {} # Diccionario para almacenar contactos\n    while True: # Interfaz de usuario\n        print(\"\\nAgenda de Contactos\") # Menú de opciones, \\n → \"Nueva línea\" (como presionar ENTER) Es un carácter de escape que crea un salto de línea.\n        print(\"1. Agregar contacto\")\n        print(\"2. Buscar contacto\")\n        print(\"3. Actualizar contacto\")\n        print(\"4. Eliminar contacto\")\n        print(\"5. Mostrar todos los contactos\")  # Nueva opción para mostrar todos los contactos\n        print(\"6. Salir\")\n        opcion = input(\"Seleccione una opción: \")\n        if opcion == '1':\n            nombre = input(\"Ingrese el nombre del contacto: \")\n            telefono = input(\"Ingrese el número de teléfono: \")\n            agregar_contacto(agenda,nombre, telefono)\n        elif opcion == '2':\n            nombre = input(\"Ingrese el nombre del contacto a buscar: \")\n            print(buscar_contacto(agenda, nombre))\n        elif opcion == '3':\n            nombre = input(\"Ingrese el nombre del contacto a actualizar: \")\n            nuevo_telefono = input(\"Ingrese el nuevo número de teléfono: \")\n            actualizar_contacto(agenda, nombre, nuevo_telefono)\n        elif opcion == '4':\n            nombre = input(\"Ingrese el nombre del contacto a eliminar: \")\n            eliminar_contacto(agenda, nombre)\n        elif opcion == '5':\n            mostrar_todos(agenda)\n        elif opcion == '6':\n            print(\"Saliendo de la agenda.\")\n            break\n        else:\n            print(\"Opción no válida. Intente de nuevo.\")\n\ndef agregar_contacto(agenda, nombre, telefono):\n    if not telefono.isdigit() or len(telefono) > 11:  # Validar teléfono\n        print(\"Número de teléfono no válido.\")\n        return\n    nombre_normalizado = nombre.lower().strip()  # Normalizar nombre Ana → ana\n    if nombre_normalizado in agenda:\n        print(f\"¡{nombre} ya existe con teléfono {agenda[nombre_normalizado]}!\") # Verificar si ya existe\n        reemplazar = input(\"¿Reemplazar? (s/n): \") # Si existe: mostrar info y preguntar reemplazo\n        if reemplazar.lower() != 's': # Si no existe o sí reemplazar: agregar/actualizar\n            return False\n    agenda[nombre_normalizado] = telefono\n    print(f\"Contacto {nombre} agregado/actualizado.\") # Dar feedback al usuario\n    return True\n\ndef buscar_contacto(agenda, nombre):\n    nombre_normalizado = nombre.lower().strip()\n    resultados = {nombre: telefono for nombre, telefono in agenda.items() \n                 if nombre_normalizado in nombre.lower()}\n    if not resultados: # Si no hay resultados, retorna mensaje amigable\n        return \"No se encontraron contactos.\"\n    output = \"Contactos encontrados:\\n\"  # Formatear resultados más legibles\n    for nombre, telefono in resultados.items():\n        output += f\"  📞 {nombre}: {telefono}\\n\"\n    return output\n\ndef actualizar_contacto(agenda, nombre, nuevo_telefono):\n    if not nuevo_telefono.isdigit() or len(nuevo_telefono) > 11:\n        print(\"Número de teléfono no válido.\")\n        return False\n    nombre_normalizado = nombre.lower().strip()\n    if nombre_normalizado in agenda:\n        agenda[nombre_normalizado] = nuevo_telefono\n        print(f\"Contacto {nombre} actualizado.\")\n        return True\n    else:\n        print(\"Contacto no encontrado.\")\n        return False\n    \ndef mostrar_todos(agenda): # Nueva función para mostrar todos los contactos, con formato legible sugerido por DeepSeek\n    print(\"\\n--- CONTACTOS ACTUALES ---\")\n    for nombre, telefono in agenda.items():\n        print(f\"  '{nombre}': '{telefono}'\")\n    print(\"--------------------------\")\n\ndef eliminar_contacto(agenda, nombre):\n    nombre_normalizado = nombre.lower().strip()\n    if nombre_normalizado in agenda:\n        del agenda[nombre_normalizado]\n        print(f\"Contacto {nombre} eliminado.\")\n        return True\n    else:\n        print(\"Contacto no encontrado.\")\n        return False\nif __name__ == \"__main__\":\n    main()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Paprikaistkrieg.py",
    "content": "#Estructuras de Datos\n\n\"\"\"\nSon formas de organizar y almacenar información para que podamos trabajar con ella de manera eficiente.\nSon como cajas o contenedores que nos permiten guardar datos, acceder a ellos, modificarlos o recorrerlos según lo que necesitemos\n\"\"\"\n\n\"\"\"Ejemplos de Estructuras de Datos\"\"\"\n\n#Listas(list)\n\n\"\"\"Es una estructura de datos que permite almacenar una colección de elementos ordenados y modificables. Pueden contener distintos tipos de datos\"\"\"\n\nfrom test.support import MAX_Py_ssize_t\n\n\nmy_list = [\"mango\", \"wilson\", \"benito\", \"toby\"]\nprint(my_list)\n\n\"\"\"\n🔧 Útiles cuando necesitas acceder por posición, agregar o eliminar elementos que se pueden modificar de esta manera.\n\"\"\"\nmy_list.append(\"lachiquita\")  # Agregar un elemento al final de la lista (insercion o append)\nprint(my_list)\nmy_list.remove(\"lachiquita\")  # Eliminar un elemento específico de la lista (eliminar o remove)\nprint(my_list)\nprint(my_list[2])  # Acceder a un elemento por su posición (indexado o indexing)\nmy_list[2] = \"benito2\" #actualizacion por indexing\nprint(my_list)\nmy_list.sort()  # asi python Ordena la lista alfabéticamente (lo hace de esta manera por defecto, es posible cambiar el comportamiento del orden) (ordenar o sort)\nprint(my_list)\n\n#Tuplas(tuple)\n\"\"\"\nes una estructura de datos similar a las listas, pero con la diferencia de que son inmutables (no se pueden modificar una vez creadas). Se definen utilizando paréntesis () en lugar de corchetes [].\n\nEjemplo de tupla:\n\"\"\"\nmi_tupla: tuple = (\"mango\", \"wilson\", \"benito\", \"toby\", \"4\")\nprint(mi_tupla)\n\n\"\"\"\n🔧 Útiles cuando necesitas almacenar un conjunto de elementos que no deben cambiar a lo largo del tiempo. (por ejemplo, datos personales, coordenadas geográficas)\n\"\"\"\nprint(mi_tupla[1])  #(acceso) Acceder a un elemento por su posición (indexado o indexing) son las unicas que se podran realizar\n#mi_tupla[1] = \"benito2\"  # Esto generará un error porque las tuplas son inmutables\nprint(mi_tupla.count(\"benito\"))  # Contar cuántas veces aparece un elemento en la tupla (count)\nmi_tupla = tuple(sorted(mi_tupla))  #(ordenacion) Ordenar los elementos de la tupla (sorted) #esto devuelve una lista ordenada, no modifica la tupla original\nprint(type(mi_tupla))  # Verificar el tipo de dato haya terminado en tuple (type)\n\n\n\n#Conjuntos(set)\n\"\"\"\nEs una estructura de datos que permite almacenar una colección de elementos únicos y no ordenados. Se definen utilizando llaves {}.\nbuenas estructuras para guardar, recorrer muchos datos, pero no para buscar datos (los datos se hashean) toda la logica de estas mismas usa hashing/hash para que sea mas facil de localizar\nesto evita duplicados (una coleccion de elementos unicos)\n\nEjemplo de conjunto:\n\"\"\"\nmy_set: set = {\"mango\", \"wilson\", \"benito\", \"toby\", \"4\"}\nprint(my_set)\n\n\"\"\"\n🔧 Útiles cuando necesitas almacenar elementos únicos y no te importa el orden. (por ejemplo, etiquetas, categorías)\n\"\"\"\nmy_set.add(\"lachiquita\")  # Agregar un elemento al conjunto (insercion o add)\nprint(my_set)\nmy_set.remove(\"lachiquita\")  # Eliminar un elemento específico del conjunto (eliminar o remove)\nprint(my_set)\nprint(\"benito\" in my_set)  # Verificar si un elemento está en el conjunto (membership)\nmy_set = set(sorted(my_set))\nprint(my_set)  #(ordenacion) Ordenar los elementos del conjunto (sorted) #esto devuelve una lista ordenada, pero no modifica el conjunto original debido al set\nprint(type(my_set))  # Verificar el tipo de dato haya terminado en set (type)\n\n#Diccionarios(dict)\n\"\"\"\nEs una estructura de datos que permite almacenar pares de clave-valor. Se definen utilizando llaves {} y dos puntos : para separar las claves de los valores.\n\nEjemplo de diccionario:\n\"\"\"\nmi_diccionario: dict = {\n    \"nombre\": \"mango\",\n    \"edad\": 5,\n    \n}\nprint(mi_diccionario)\n\n\"\"\"\n🔧 Útiles cuando necesitas asociar valores únicos (claves) con información adicional (valores). (por ejemplo, información de contacto, configuraciones)\n\"\"\"\nmi_diccionario[\"color\"] = \"amarillo\"  # Agregar un nuevo par clave-valor (insercion o add)\nprint(mi_diccionario[\"color\"])  # Acceder a un valor por su clave (acceso o indexing)\nmi_diccionario[\"edad\"] = 6  # Actualizar un valor por su clave (actualización)\nprint(mi_diccionario)\ndel mi_diccionario[\"color\"]  # Eliminar un par clave-valor (eliminacion o del)\nprint(mi_diccionario)\nmi_diccionario = dict(sorted(mi_diccionario.items()))  #(ordenacion) Ordenar los elementos del diccionario por clave (sorted)\nprint(type(mi_diccionario))  # Verificar el tipo de dato haya terminado en dict (type)\n\n#XTRA\n\"\"\"\n Crea una agenda de contactos por terminal.\n Debes implementar funcionalidades de búsqueda, inserción, actualización\n y eliminación de contactos.\n Cada contacto debe tener un nombre y un número de teléfono.\nEl programa solicita en primer lugar cuál es la operación que se quiere realizar,\ny a continuación los datos necesarios para llevarla a cabo.\nEl programa no puede dejar introducir números de teléfono no numéricos y con más\nde 11 dígitos (o el número de dígitos que quieras).\nTambién se debe proponer una operación de finalización del programa.\n\"\"\"\n\n\ndef my_agenda():\n    agenda = {}\n\n    while True:\n        print(\"Seleccione una operación:\")\n        print(\"1. Buscar contacto\")\n        print(\"2. Agregar contacto\")\n        print(\"3. Actualizar contacto\")\n        print(\"4. Eliminar contacto\")\n        print(\"5. Salir\")\n        opcion = input(\"Seleciona una opcion \")\n\n        if opcion == \"1\":\n            nombre = input(\"Ingrese el nombre del contacto a buscar: \")\n            if nombre in agenda:\n                print(f\"Teléfono de {nombre}: {agenda[nombre]}\")\n            else:\n                print(\"Contacto no encontrado.\")\n\n        elif opcion == \"2\":\n            nombre = input(\"Ingrese el nombre del nuevo contacto: \")\n            telefono = input(\"Ingrese el número de teléfono: \")\n            if not telefono.isdigit():\n                print(\"El número debe contener solo dígitos.\")\n            elif len(telefono) != 10:\n                print(\"El número debe tener exactamente 10 dígitos.\")\n            elif nombre in agenda:\n                print(\"Ya existe un contacto con ese nombre.\")\n            else:\n                agenda[nombre] = telefono\n                print(\"Contacto agregado correctamente.\")\n\n\n        elif opcion == \"3\":\n            nombre = input(\"Ingrese el nombre del contacto a actualizar: \")\n            if nombre in agenda:\n                nuevo_nombre = input(\"Ingrese el nuevo nombre del contacto: \")\n                telefono = input(\"Ingrese el nuevo número de teléfono: \")\n                if not telefono.isdigit():\n                    print(\"El número debe contener solo dígitos.\")\n                elif len(telefono) != 10:\n                    print(\"El número debe tener exactamente 10 dígitos.\")\n                else:\n                    agenda[nuevo_nombre] = telefono\n                    if nuevo_nombre != nombre:\n                        del agenda[nombre]\n            else:\n                print(\"Contacto no encontrado.\")\n\n        elif opcion == \"4\":\n            nombre = input(\"Ingrese el nombre del contacto a eliminar: \")\n            if nombre in agenda:\n                del agenda[nombre]\n                print(\"Contacto eliminado.\")\n            else:\n                print(\"Contacto no encontrado.\")\n\n        elif opcion == \"5\":\n            print(\"Saliendo de la agenda.\")\n            break\n\n        else:\n            print(\"Opción no válida. Por favor, seleccione una opción del 1 al 5.\")\n\n    return agenda\n\nmy_agenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Paula2409.py",
    "content": "\"\"\" \n/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n \"\"\"\n \ndef data_structures():\n    # Create list, dict, set and tuple\n    my_list = []\n    my_dict = {}\n    my_set = set()\n    my_tuple = ('a',6,0,6,'a',(5,9))\n    # Frozenset receive an interable\n    my_frozenset_1 = (5,6,9,'a',(8,9,7))\n    my_frozenset_1 = frozenset(my_frozenset_1)\n    my_frozenset_2 = (5,7,9,'b',(8,1,7))\n    my_frozenset_2 = frozenset(my_frozenset_2)\n    \n    ''' Insert element '''\n    # List at the end\n    my_list.append(5)\n    my_list.append(6)\n    my_list.append('p')\n    \n    # List at specific index\n    my_list.insert(2,4) \n    my_list.insert(0,9)\n    \n    # Dict at specific key\n    my_dict['a'] = 1\n    my_dict['b'] = 2\n    # Update dict\n    my_dict['a'] = 6\n    \n    # Sets are unordered and unindexed\n    my_set.add(5)\n    my_set.add(3)\n    my_set.add(9)\n    my_set.add('a')\n              \n    ''' Remove element '''\n    # List\n    my_list.pop() # At the end\n    my_list.pop(0) # At index\n    my_list.remove(6) # Remove specific element\n    \n    # Dict\n    my_dict.pop('a')\n    my_dict.pop('c',0) # Return default value\n    del my_dict['b']\n    \n    # Set\n    my_set.pop() # Random element\n    my_set.remove(3) # Error if element doesn't exist\n    my_set.discard(5) # No error if element is not present\n    \n    ''' Sort '''\n    # List\n    my_list.sort()\n    \n    # Dict. We need method sorted. We organized keys and then create a new dictionary with the keys organized\n    keys_my_dict = my_dict.keys()\n    sorted_keys = sorted(keys_my_dict)\n    new_my_dict = {}\n    for key in sorted_keys:\n        new_my_dict[key] = my_dict[key]\n        \n    ''' Clear '''\n    # List\n    my_list.clear() # or my_list = []\n    \n    # Dict\n    my_dict.clear()\n    \n    # Set\n    my_set = set()\n        \n    # Tuple are immutable. This are some operations:\n    my_tuple.count('a') \n    my_tuple.index(6)\n    my_tuple.index(6,2) # Initialize search index at 2\n    my_tuple = () # Clear\n    \n    # Frozenset are also immutable.\n    my_new_frozenset = my_frozenset_1.copy()\n    my_frozenset_1.difference(my_frozenset_2)\n    my_frozenset_1.intersection(my_frozenset_2)\n\ndata_structures()\n\nagenda = {}\ndef my_agenda():\n    option = int(input(f'''\n        ****** BIENVENIDO ******\n        1. Nuevo contacto\n        2. Buscar contacto\n        3. Actualizar contacto\n        4. Borrar contacto\n        5. Visualizar agenda\n        6. Salir \n        Ingrese una opcion para operar: '''))\n \n    while option != 6:\n        if option == 1:\n            name = input('Por favor ingrese el nombre del contacto: ')\n            if name in agenda:\n                print('El contacto ya se encuentra en la agenda')\n            else:\n                telephone = int(input('Ingrese el numero telefonico (maximo 11 digitos): '))\n                \n                while len(str(telephone)) > 11 or telephone == 0:\n                    telephone = int(input('Por favor, ingrese un numero valido: '))\n                agenda[name] = telephone\n                print('Contacto agregado correctamente')\n            \n        if option == 2:\n            name_search = input('Ingrese el nombre del contacto a buscar: ')\n            if name_search in agenda:\n                print(f'El contacto es {name_search} y el telefono {agenda[name_search]}')\n            else:\n                print('El contacto no se encuentra en la agenda')\n                \n        if option == 3:\n            update = input('Ingrese el contacto a actualizar: ')\n            if update in agenda:\n                response = int(input('Si desea actualizar nombre ingrese 1, si lo que desea actualizar es telefono ingrese 2 '))\n                if response == 1:\n                    update_name = input('Ingrese el nombre nuevo: ')\n                    agenda[update_name] = agenda[update]\n                if response == 2:\n                    update_telephone = int(input('Ingrese el nuevo telefono, maximo 11 digitos: '))\n                    while len(str(telephone)) > 11 or telephone == 0:\n                        update_telephone = int(input('Por favor, ingrese un numero valido: '))\n                    agenda[update] = update_telephone\n                    print(f'El contacto se modifico correctamente')\n            else:\n                print('El contacto no se encuentra en la agenda')\n                    \n        if option == 4:\n            delete_contact = input('Ingrese el contacto a eliminar: ')\n            if delete_contact in agenda:\n                del agenda[delete_contact]\n                print('Contacto eliminado')\n            else:\n                print('El contacto no se encuentra en la agenda')\n        \n        if option == 5:\n            for key,value in agenda.items():\n                print(f'Nombre: {key} - Telefono: {value}')  \n                \n        option = int(input(f'''\n        ****** BIENVENIDO ******\n        1. Nuevo contacto\n        2. Buscar contacto\n        3. Actualizar contacto\n        4. Borrar contacto\n        5. Visualizar agenda\n        6. Salir \n        Ingrese una opcion para operar: '''))\n        \nmy_agenda()  \n    "
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/PyTorDev.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto\n *   en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n *   y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n *   y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no numéricos y con más\n *   de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.\n */\n\"\"\"\n\"\"\" Descomentar si se quieren ver resultados. Comentado no molesta a la ejecucion de la agenda\n# Listas\nmi_lista = list() #Contructor\nsegunda_lista = [] #Declaracion directa (Se podrian añadir directametne los elementos de la lista)\n\nsegunda_lista = [\"Manolo\", 57, \"Visual Basic\"]\nprint(type(segunda_lista))\n\n# Tuplas\nmi_tupla = tuple() #Contructor\nsegunda_tupla = () #Declaracion directa (Se podrian añadir directametne los elementos de la lista)\n\nmi_tupla = (1, 45, 23, 57, 42)\nprint(type(mi_tupla))\n\n# Set\nmi_set = set() #Contructor\nsegundo_set = {} #Para que esto sea un set y no un diccionario, hay que poner sus elementos como se indica abajo\n\nsegundo_set = {\"Hola papa\", \"Quiero ser developer\", 12, \"Sigue soñando\"}\nprint(type(segundo_set))\n\n# Diccionario\nmi_dict = dict() #Contructor\nsegundo_dict = {} #Para que esto no sea un set sino un diccionario, hay que poner sus elementos como se indica abajo\n\nsegundo_dict = {\n  \"Saludo\": \"Hola papa\",\n  \"Objetivo\": \"Quiero ser developer\",\n  \"Tiempo\": 12, \"Golpe\": \"Sigue soñando\"}\nprint(type(segundo_dict))\n\n#Funciones de inserción\n\nsegunda_lista.insert(0, \"Patata\")\nprint(segunda_lista)\nsegunda_lista.append(\"puerro\")\nprint(segunda_lista)\nsegunda_lista[1] = \"Me' Colao\"\nprint(segunda_lista)\nmi_lista = [1, 45, 23, 57, 42]\n\n#Funciones de borrado\n\nsegunda_lista.remove(\"puerro\")\nprint(segunda_lista)\nprint(segunda_lista.pop())\nprint(segunda_lista)\ndel segunda_lista\n#print(segunda_lista) da error porque ya no existe segunda_lista\n\n#Funciones de ordenado\n\nmi_lista.sort()\nprint(mi_lista)\nmi_lista.reverse()\nprint(mi_lista)\n\"\"\"\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n *   y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n *   y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no numéricos y con más\n *   de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.\n\"\"\"\n\nagenda = list()\n\n#Crear aqui el menu de la agenda\ndef menu():\n  print(\"-------------------\")\n  print(\"Agenda de contactos\")\n  print(agenda)\n  print(\"Elija una opcion\")\n  print(\"-------------------\")\n  opcion = input(\"\"\"  1 Añadir contacto\n  2 Modificar contacto\n  3 Buscar contacto\n  4 Eliminar contacto\n  5 Cerrar la agenda (se perderan los contactos)\n  Su opcion aqui:                 \n  \"\"\")\n  if (opcion == \"1\"):\n    add_contact()\n  elif (opcion == \"2\"):\n    edit_contact()\n  elif (opcion == \"3\"):\n    search_contact()\n  elif (opcion == \"4\"):\n    delete_contact()\n  elif (opcion == \"5\"):\n    print(\"Hasta otra!\")\n    print(\"__________________________________________________________\")\n    exit()\n  else: \n    print(\"Elije una opcion valida\")\n    menu()\n\ndef add_contact():\n  name = input(\"Introduce un Nombre: \")\n  number = input(\"Introduce un Telefono: \")\n  contacto = {\n    \"nombre\": name,\n    \"telefono\": number\n  }\n  agenda.append(contacto)\n  print(name, \"a sido añadido a tus contactos\")\n  menu()\n\ndef edit_contact():\n  i = input(\"¿Que contacto quieres editar?: \")\n  contact = next((contact for contact in agenda if contact[\"nombre\"] == i), None)\n  if contact is None:\n    print(\"No se encontró el contacto\")\n    menu()\n\n  confirmado = input(\"Usted va a editar el contacto elegido, confirme pulsando enter\")\n  if (confirmado == \"\"):\n    new_name = input(\"Introduce el nuevo Nombre: \")\n    new_number = input(\"Introduce el nuevo numero: \")\n    \n    for i, old_contact in enumerate (agenda):\n      if old_contact == contact:\n        agenda[i] = {\"nombre\": new_name, \"telefono\": new_number}\n        print(\"Se a actualizado el contacto correctamente\")\n        break\n      else: print(\"Hubo algun error\")  \n\n  else:\n    print(\"Regresando al menu principal\")\n  menu()    \n\ndef search_contact():\n  contact = input(\"Introduce el nombre a buscar: \")\n  found = False\n  for asked_contact in agenda:\n      if asked_contact[\"nombre\"] == contact:\n\n        print(\"-------------------------------------\")\n        print(\"Nombre:\", asked_contact[\"nombre\"])\n        print(\"Telefono:\", asked_contact[\"telefono\"])\n        print(\"-------------------------------------\")\n        \n        found = True\n        break\n  if not found:\n    print(\"Contacto no encontrado\")\n  menu()\n\n  \n\n  menu()\n\ndef delete_contact():\n  contact = input(\"¿Que contacto desea eliminar?: \")\n\n  confirmado = input(\"Usted va a eliminar el contacto elegido, confirme pulsando enter\")\n  if (confirmado == \"\"):    \n    for i, del_contact in enumerate (agenda):\n      if del_contact[\"nombre\"] == contact:\n        del agenda[i]\n        print(agenda)\n        print(f\"{contact} ha sido eliminado\")\n        break\n      else: print(\"Hubo algun error\")  \n\n  else:\n    print(\"Regresando al menu principal\")\n  menu()\n\nmenu()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Ramirofordev.py",
    "content": "# Estructuras de datos                   \n\n# Listas \nnumbers = [1, 2, 3, 4, 5]\nprint(numbers)\nnumbers.append(8) # Insercion\nnumbers.remove(1) # Eliminacion\nprint(numbers)\nprint(numbers[1]) # Acceso\nnumbers.insert(3, 6) # Actualizacion\nnumbers[3] = 7 # Actualizacion\nprint(numbers)\n\n# Tuple\nmy_tuple = (\"Nacho\", \"Ramiro\", \"kuro\", \"jose@gmail\")\nprint(my_tuple[1]) # acceso\nmy_tuple = tuple(sorted(my_tuple)) # ordenacion\nprint(my_tuple)\n\n# Sets\nmy_set = {\"pollo\", \"gato\", \"perro\", \"vaca\"}\nmy_set.add(\"ganso\") # Insercion\nmy_set.discard(\"vaca\") # Eliminacion\nmy_set.pop() # Eliminacion\nmy_set = set(sorted(my_set))\nprint(my_set)\n\n# Diccionarios\nmy_dict = {\n    'name': \"Nacho\",\n    'age': 18,\n    'job': 'assistant',\n    'year': 2006\n}\nmy_dict.pop('job') # Eliminacion\nmy_dict.popitem() # Eliminacion\nprint(my_dict)\nprint(my_dict[\"age\"]) # Acceso\nmy_dict[\"age\"] = 20 # Insercion\n\n# Ejercicio opcional\n\ncontactos = {}\n\nprint(contactos)\n\ndef buscar():\n    dato = input(\"Por favor inserta el nombre del contacto: \").title()\n    if dato in contactos:\n        print(\"Contacto encontrado aqui tienes sus datos: \\n\" \\\n              f\"Nombre: {dato}\" \\\n                f\"Numero: {contactos[dato]}\")\n\ndef insertar():\n    nombre = input(\"Por favor ingrese el nombre del contacto: \").title()\n    while True:\n        numero = input(\"Porfavor ingrese el numero: \").strip()\n        if numero.isalnum() and len(numero) <= 11:\n            contactos[nombre] = numero\n            break\n        else:\n            print(\"Numero invalido porfavor intentelo de nuevo\")\n            pass\n\ndef actualizar():\n    r = input(\"Que dato desea actualizar: \\n\" \\\n              \"1. Nombre.\\n\" \\\n                \"2. Numero.\")\n    if r == \"1\":\n        old_name = input(\"Dame el nombre del contacto que deseas cambiar: \").title()\n        new_name = input(\"Dame el nuevo nombre: \").title()\n        if old_name in contactos:\n            contactos[new_name] = contactos.pop(old_name)\n        else:\n            print(\"Contacto no encontrado\")\n    elif r == \"2\":\n        name = input(\"Dame el nombre del contacto: \").title()\n        new_number = input(\"Dame el nuevo numero: \").replace(\" \", \"\")\n        if name  or new_name in contactos:\n            if new_number.isalnum() and len(new_number) <= 11:\n                contactos[name] = new_number\n            else:\n                print(\"Numero invalido\")\n        else:\n            print(\"Contacto no encontrado\")\n    else:\n        print(\"Opcion invalida\")\n\ndef borrar():\n    contacto = input(\"Que contacto deseas eliminar, introduce su nombre por favor: \").title()\n    if contacto in contactos:\n        del contactos[contacto]\n    else:\n        print(\"No se encontro ese contacto\")\n\ndef opciones(respuesta): \n    funciones = {\n        \"1\": buscar,\n        \"2\": insertar,\n        \"3\": actualizar,\n        \"4\": borrar\n    }\n    return funciones[respuesta]() # llamara a la funcion usando la respuesta como su llave\n\nwhile True:\n    r = input(\"Bienvenido a la agenda de contactos\\n\" \\\n    \"Elige una de las siguientes opciones: \\n\" \\\n    \"1. Buscar un contacto\\n\" \\\n    \"2. Insertar un nuevo contacto. \\n\" \\\n    \"3. Actualizar un contacto. \\n\" \\\n    \"4. Eliminar un contacto. \\n\" \\\n    \"5. Salir del menu.\\n\")\n\n    if r in [\"1\", \"2\", \"3\", \"4\"]:\n        opciones(r)\n    elif r == \"5\":\n        print(\"Gracias por usar la agenda\")\n        break\n    else:\n        print(\"Opcion no valida porfavor vuelva a intentar.\")\n        pass\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Rickubb.py",
    "content": "# Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n# lista o pila\nnombres = [\"Rick\", \"Andy\", \"Jinx\"]\nprint(f\"Lista o pila: {nombres}\")\n# tupla\nnumeros = (1,2,3)\nprint(f\"Tupla: {numeros}\")\n# conjunto\nnumeros_2 = {4,5,6}\nprint(f\"Conjunto: {numeros_2}\")\n# conjunto inmutable\nnumeros_3 = frozenset({4,5,6})\nprint(f\"Conjunto inmutable: {numeros_3}\")\n# diccionario\nsignificados = {\n    \"name\" : \"Nombre\",\n    \"username\": \"Nombre de usuario\"\n}\nprint(f\"Diccionario: {significados}\")\n# bytearray\nbytearray(5)\nprint(f\"Bytearray: {bytearray(5)}\")\n# rango\nrange(2)\nprint(f\"Rango: {range(10)}\")\n# memory view\nmemoryview(bytes(5))\nprint(f\"Memoryview: {memoryview(bytes(5))}\")\nprint(\"\")\n\n# Utiliza operaciones de inserción, borrado, actualización y ordenación.\n# lista o pila\n# inserción\n# agrega un elemento al final\nnombres.append(\"Luna\")\nnombres.append(\"Candy\")\nprint(f\"Inserción: {nombres}\")\n# agrega multiples elementos al final\nnombres.extend(\"Luna\")\nprint(f\"Inserción: {nombres}\")\n# agrega un elemento al indice\nnombres.insert(0,\"Snoopy\")\nprint(f\"Inserción: {nombres}\")\n#borrado\n# especifico\nnombres.remove(\"Luna\")\nprint(f\"Borrado: {nombres}\")\n# por indice o ultimo\nnombres.pop(5)\nprint(f\"Borrado: {nombres}\")\nnombres.pop()\nprint(f\"Borrado: {nombres}\")\n#actualización\nnombres[5] = \"a\"\nprint(f\"Borrado: {nombres}\")\n#ordenación\n#alfabetico\nnombres.sort()\nprint(nombres)\n#invierte\nnombres.reverse()\nprint(nombres)\n\n#conjuntos\n# inserción\n# agrega un elemento al final\nnumeros_2.add(7)\nnumeros_2.add(8)\nnumeros_2.add(9)\nnumeros_2.add(10)\nnumeros_2.add(11)\nnumeros_2.add(12)\nprint(numeros_2)\n#eliminación\n#elimina el numero mencionado\nnumeros_2.remove(7)\nprint(numeros_2)\n#elimina el numero mencionado, sin error si no existe\nnumeros_2.discard(6)\nprint(numeros_2)\n#elimina y devuelve un elemento aleatorio\nnumeros_2.pop()\nnumeros_2.pop()\nprint(numeros_2)\n\n#diccionarios\n# inserción/actualización\nsignificados.update({\n    \"pass\": \"Contrasena\",\n    \"name\" : \"Nombres\",\n    \"username\" : \"Nombres de usuario\",\n    \"password\" : \"qwerty\",\n    \"email\" : \"@hotmail.com\"\n\n})\nprint(f\"Diccionario actualizado: {significados}\")\n# eliminación directa\nsignificados.pop(\"pass\")\nprint(f\"Diccionario eliminado: {significados}\")\n#elimino el ultimo item\nsignificados.popitem()\nprint(f\"Diccionario eliminado: {significados}\")\n\n\n\"\"\"\n* Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n\"\"\"\n\ncontactos = {}\n\nMIN_DIGITOS = 10\nMAX_DIGITOS = 11\n\ndef verificar_tel(telefono):\n    telefono = telefono.strip()\n\n    if not telefono.isdigit():\n        raise ValueError(\"El telefono debe ser numérico\")\n\n    if len(telefono) < MIN_DIGITOS:\n        raise ValueError(f\"El telefono debe tener al menos {MIN_DIGITOS} dígitos\")\n\n    if len(telefono) > MAX_DIGITOS:\n        raise ValueError(f\"El telefono no debe tener más de {MAX_DIGITOS} dígitos\")\n\n    return telefono  # lo devuelvo validado (string)\n\ndef agenda(n):\n    match n:\n        case 1:\n            print(\"1. Buscar contacto\")\n            nombre = input(\"Ingrese el nombre del contacto: \").strip()\n            if nombre in contactos:\n                return contactos[nombre]\n            return f\"Contacto {nombre} no existe\"\n\n        case 2:\n            print(\"2. Insertar contacto\")\n            nombre = input(\"Ingrese el nombre del contacto: \").strip()\n            if nombre in contactos:\n                return print(f\"El contacto con nombre {nombre} ya existe!\")\n\n            while True:\n                telefono = input(\"Ingrese el teléfono del contacto: \")\n                try:\n                    telefono = verificar_tel(telefono)  # aquí puede hacer raise\n                    break\n                except ValueError as e:\n                    print(e)\n\n            contactos.update({nombre: telefono})\n            return print(f\"Contacto {nombre} insertado\")\n\n        case 3:\n            print(\"3. Actualizar contacto\")\n            nombre = input(\"Ingrese el nombre del contacto que desea actualizar: \").strip()\n            if nombre not in contactos:\n                return print(f\"El contacto con nombre {nombre} no existe!\")\n\n            while True:\n                numero = input(f\"Ingrese el numero del contacto {nombre} que desea actualizar: \")\n                try:\n                    numero = verificar_tel(numero)  # aquí puede hacer raise\n                    break\n                except ValueError as e:\n                    print(e)\n\n            contactos.update({nombre: numero})\n            return print(f\"El contacto con nombre {nombre} se actualizo!\")\n\n        case 4:\n            print(\"4. Eliminar contacto\")\n            nombre = input(\"Ingrese el nombre del contacto: \").strip()\n            if nombre in contactos:\n                contactos.pop(nombre)\n                return print(f\"El contacto con nombre {nombre} se elimino!\")\n            return print(f\"El contacto con nombre {nombre} no existe!\")\n\n        case 0:\n            return \"0. Finalizar programa\"\n\n        case _:\n            return \"Digite un número valido\"\n\n\nn = 1\n\nwhile n != 0:\n    print(\"1. Buscar contacto\")\n    print(\"2. Insertar contacto\")\n    print(\"3. Actualizar contacto\")\n    print(\"4. Eliminar contacto\")\n    print(\"0. Finalizar programa\")\n\n    n = input(\"Ingrese el número de la operación que quiere realizar: \")\n    try:\n        n = int(n)\n    except ValueError:\n        print(\"Debe ingresar un número valido\")\n    else:\n        print(agenda(n))\n\n\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Rodrigoghr.py",
    "content": "'''\n/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n '''\nprint('\\n1. Listas')\nprint('*********') \nedades = [18, 28, 23, 10]\nprint(f'Lista: {edades}')\n\nprint('\\nOperaciones de Listas')\nprint('*********************')\n\nprint('\\ta) Inserción:')\nedades.append(24)\nprint(f'\\tInsertamos el número 24 a la lista: {edades}')\n\nedades.insert(2,30)\nprint(f'\\tSe inserta el número 30 en el índice 2: {edades}')\n\nprint('\\n\\tb) Eliminar:')\nedades.remove(23)\nprint(f'\\tElimina el número 23 de la lista: {edades}')\n\nedades.pop()\nprint(f'\\tElimina el último número de la lista: {edades}')\n\nedades.pop(1)\nprint(f'\\tElimina el elemento de la posición 1: {edades}')\n\nprint('\\n\\tc) Actualizar:')\nedades[1] = 45\nprint(f'\\tActualiza el valor en la posición 1: {edades}')\n\nprint('\\n\\td) Ordenar:')\nedades.sort()\nprint(f'\\tOrden ascendente: {edades}')\n\nedades.sort(reverse = True)\nprint(f'\\tOrden descendente: {edades}')\n\nprint('\\n2. Tuplas')\nprint('*********') \nmi_tupla = (1,2,5,4,7,3,2,1,9)\nprint(f'\\tmi_tupla: {mi_tupla}')\n\nprint('\\n3. Diccionario')\nprint('**************') \nmi_alumno = {'nombre' : 'Rodrigo', 'genero': 'M', 'edad':25, 'cursos' : ['python','javascript','github']}\nprint(f'\\tAlumno: {mi_alumno}')\n\nprint('\\nOperaciones')\nprint('***********')\n\nprint('\\ta) Inserción:')\nmi_alumno['nota'] = 20\nprint(f'\\tInsertamos la clave \"nota\" y el valor \"20\": {mi_alumno}')\n\nprint('\\n\\tb) Eliminar:')\ndel mi_alumno['genero']\nprint(f'\\tEliminamos la clave \"genero\" con su valor: {mi_alumno}')\n\nmi_alumno.pop('edad')\nprint(f'\\tEliminamos la clave \"edad\" con su valor: {mi_alumno}')\n\nprint('\\n\\tc) Actualizar:')\nmi_alumno['nombre'] = 'Luis'\nprint(f'\\tActualiza el valor de la clave \"nombre\": {mi_alumno}')\n\nprint('\\n\\td) Ordenar:')\nmi_alumno = dict(sorted(mi_alumno.items()))\nprint(f'\\tOrden ascendente: {mi_alumno}')\n\nprint('\\n4. Conjuntos')\nprint('**************') \nfrutas = {'manzana', 'platano', 'naranja', 'fresa'}\nprint(f'\\tFrutas: {frutas}')\n\nprint('\\nOperaciones')\nprint('***********')\n\nprint('\\ta) Inserción:')\nfrutas.add('melon')\nprint(f'\\tInsertamos la fruta \"melon\" al conjunto: {frutas}')\n\nprint('\\n\\tb) Eliminar:')\nfrutas.remove('manzana')\nprint(f'\\tEliminamos la fruta \"manzana\" del conjunto: {frutas}')\n\nfrutas.pop()\nprint(f'\\tEliminamos una fruta del conjunto: {frutas}')\n\n\nprint('\\n\\tc) Actualizar:')\nprint(f'\\tNo se puede actualizar un elemento específico')\n\nprint('\\n\\td) Ordenar:')\nprint(f'\\tOrdenamos el conjunto: {sorted(frutas)}')\n\n'''\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n '''\n # Dificulta Extra\ndef buscar(agenda):\n    nombre = input('Ingrese nombre: ')\n    if nombre in agenda:\n        print(f'Nombre: {nombre} , Teléfono : {agenda[nombre]}')\n    else:\n        print('Contacto no encontrado!')\n\ndef valida_telefono(telefono):\n    return telefono.isdigit() and len(telefono) > 0 and len(telefono) <= 11\n\ndef insertar(agenda):\n    nombre = input('Ingrese nombre: ')\n    telefono = input('Ingrese número de teléfono: ')\n    \n    if valida_telefono(telefono):\n        agenda[nombre] = telefono\n        print(f'Contacto {nombre} con número de teléfono {agenda[nombre]} ¡Registrado!')\n    else:\n        print(\"¡Numero de teléfono inválido! Debe ser numérico y de 11 dígitos como máximo\")\n\ndef actualizar(agenda):\n    nombre = input('Ingrese nombre: ')\n    \n    if nombre in agenda:\n        telefono = input('Ingrese nuevo número de telefono: ')\n        if valida_telefono(telefono):\n            agenda[nombre] = telefono\n            print(f'Contacto {nombre} actualizado con número {agenda[nombre]}')\n        else:\n            print(\"¡Numero de teléfono inválido! Debe ser numérico y de 11 dígitos como máximo\")\n    else:\n        print('Contacto no encontrado!')\n\ndef eliminar(agenda):\n    nombre = input('Ingrese nombre: ')\n    if nombre in agenda:\n        del agenda[nombre]\n        print(f'Contacto {nombre} ¡Eliminado!')\n    else:\n        print('Contacto no encontrado!')\n\ndef main():\n    agenda = {}\n    \n    while True:\n        print(\"\\nAgenda de contactos\")\n        print(\"\\t1. Buscar contacto\")   \n        print(\"\\t2. Insertar contacto\")   \n        print(\"\\t3. Actualizar contacto\")   \n        print(\"\\t4. Eliminar contacto\")   \n        print(\"\\t5. Salir\")    \n        \n        opcion = input(\"\\nSelecciona una opción: \")\n        \n        match opcion:\n            case '1':\n                buscar(agenda)\n            case '2':\n                insertar(agenda)\n            case '3':\n                actualizar(agenda)\n            case '4':\n                eliminar(agenda)\n            case \"5\":\n                print(\"Cerrando agenda...\")\n                break\n            case _:\n                print(\"Opción inválida. Elige del 1 al 5.\")\n                \n\nif __name__ == '__main__':\n    main()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/RoniPG.py",
    "content": "# @RoniPG\n\t\n# LISTA\n\n#Constructor de la lista\n \nlista = list()\nsegunda_lista=[]\nprint(\"El tamaño de la lista es de: \"+ str(len(lista))) \nprint(\"El tamaño de la lista es de: \"+ str(len(segunda_lista)))\n\n#Asignacion de valores\n\"\"\"\nPodemos asignarles distintos tipos de datos.\nPueden repetirse el valor de los datos\nPuedes convertir los datos en variables.\n\"\"\"\nlista = [1, 2, 3, 4, 5]\nprint(\"El tamaño de la lista es de: \"+ str(len(lista)))\nprint(\"Los datos de la lista son: \"+ str(lista))\nsegunda_lista.append(\"Hola\") \nsegunda_lista.append(\"Lista\")\nsegunda_lista.append(2)\nprint(\"El tamaño de la lista es de: \"+ str(len(segunda_lista)))\nprint(\"Los datos de la lista son: \"+ str(segunda_lista))\nprimero,segundo,tercero,cuarto,quinto = lista # --> Tiene que coincidir el numero de variables con los datos de la lista\nprint(segundo, primero, cuarto, quinto, tercero) # print(segundo + primero + cuarto + quinto + tercero) --> Suma los datos\nsaludo, tipo, numero = segunda_lista\nprint(saludo, tipo, numero) # o tambien --> print(saludo + tipo + str(numero))\nprint(lista + segunda_lista) # concatenar listas\nsegunda_lista.insert(1, \"Nueva\")\nprint(segunda_lista)\n\n#Eliminar datos\n\nprint(\"Elminamos por valor \\\"Nueva\\\"\")\nsegunda_lista.remove(\"Nueva\")\nprint(segunda_lista)\nprint(segunda_lista.pop()) # --> Elimina el ultimo valor y te lo devuelve\nprint(segunda_lista) \nprint(lista.pop(2))\nprint(lista)\nprint(\"Elminamos por indice [2]\")\ndel lista[2] # Elimina el valor del indice que le indiquemos\nprint(lista)\n#lista.clear() --> Esto borrara todos los datos de la lista\n\n#Actualizar / Ordenar datos\n\nprint(lista)\nlista[2]=3\nprint(lista)\nprint(segunda_lista)\nsegunda_lista[1]=\"Mundo\"\nprint(segunda_lista)\n# lista[3]=4 --> si el indice no se encuentra dentro de lista salta IndexError.\nsegunda_lista.reverse() # --> Damos la vuelta a la lista\nprint(segunda_lista)\nsublista= lista[0:2] # --> Cortamos la lista desde el indice 0 hasta el indice 2\nprint(sublista)\nprint(segunda_lista.sort()) # --> Ordenamos la lista\n\n#TUPLAS\n\n#Constructor de la tupla\n\ntupla = tuple()\nsegunda_tupla = ()\n\n#Asignacion de valores\n\"\"\"\nPodemos asignarles distintos tipos de datos.\nPueden repetirse el valor de los datos.\nLos datos son invariables.\nPuedes convertir los datos en variables.\n\"\"\"\ntupla = (\"Primera Tupla: \", 1, 2, 3, 4, 5)\nprint(tupla)\nsegunda_tupla=(\"Segunda Tupla: \", 6, 7, 8, 9)\nprint(tupla + segunda_tupla) # --> Concatenacion de tuplas\nsub_tupla= tupla[1:6] # --> Cortamos la tupla desde el indice 1 hasta el indice 6\nprint(sub_tupla)\ntexto,primero,segundo,tercero,cuarto,quinto= tupla\nprint (texto)\n\n#Eliminar datos\n\"\"\"\nUtilizamos la funcion del sistema.\nLa variable deja de existir.\n\"\"\"\ndel sub_tupla # Eliminamos la variable sub_tupla\n\n#SETS\n\n#Constructor de los SETS\n\nprimer_set= set()\nsegundo_set={} \n\n#Asignacion de valores\n\"\"\"\nPodemos asignarles distintos tipos de datos.\nLos datos de guaradan sin orden.\nLos datos no admiten valores repeditos.\n\"\"\"\n\nsegundo_set={\"Segundo set: \", 1, 2 ,3 ,4}\nprint(segundo_set) # --> Se imprime en orden aleatorio\nprimer_set.add(\"Primer set: \")\nprimer_set.add(5)\nprimer_set.add(6)\nprimer_set.add(7)\nprimer_set.add(8)\nprint(primer_set)# --> Se imprime en orden aleatorio\nsegundo_set.add(3)\nprint(segundo_set) # --> No añade el valor repetido\nprint(primer_set.union(segundo_set)) # Concatenamos 2 sets\n\n#Eliminar datos\n\nprint(\"Elminamos por valor \\\"Segundo set: \\\"\")\nsegundo_set.remove(\"Segundo set: \")\nprint(segundo_set)\nprint(segundo_set.pop()) # --> Elimina el ultimo valor y te lo devuelve\nprint(segundo_set) \nprimer_set.clear() #--> Esto borrara todos los datos de la lista\nprint(primer_set)\ndel primer_set # Eliminamos la variable primer_set\n\n#DICCIONARIO\n\n#Constructor de los diccionarios\n\ndiccionario=dict()\nsegundo_diccionario= {}\n\n#Asignacion de valores\n\"\"\"\nPodemos asignarles distintos tipos de datos.\nLos datos de guaradan con clave:valor.\nLos datos admiten valores de tipo clave:set(), entre otros.\n\"\"\"\nsegundo_diccionario={\"Nombre:\":\"segundo_diccionario\", # --> Añadimos datos clave:valor string:string\n                     \"primero\":1, \"segundo\":2, \"tercero\":3} # --> Añadimos datos clave:valor string:int\ndiccionario={\"Nombre:\":\"diccionario\", \n             4 :\"cuarto\", 5:\"quinto\", 6:\"sexto\",\n             \"Resto\":{7,8,9}}# --> Añadimos datos clave:valor string:set()\nprint(segundo_diccionario)\nprint(diccionario)\nprint(diccionario[\"Nombre:\"])\n\n#Actualizar los valores\n\ndiccionario[\"Resto\"] = {\"Siete,\",\"Ocho\", \"Nueve\"} # --> Se sobreescriben los datos\nprint(diccionario[\"Resto\"])\nprint(segundo_diccionario)\nsegundo_diccionario[\"Numeros negativos:\"] = {-1, -2, -3} # --> Se añaden datos al dicccionario\nprint(segundo_diccionario)\n\n#Eliminar datos\n\ndel segundo_diccionario[\"Numeros negativos:\"] # --> Borramos los datos de la clave \"Numeros negativos:\"\nprint(segundo_diccionario) \n\n\"\"\"\n DIFICULTAD EXTRA (opcional):\n Crea una agenda de contactos por terminal.\n - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n - Cada contacto debe tener un nombre y un número de teléfono.\n - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n   los datos necesarios para llevarla a cabo.\n - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n   (o el número de dígitos que quieras)\n - También se debe proponer una operación de finalización del programa.\n\n\"\"\"\ncontador=0\nsub_contador=0\nopcion=\"0\"\nagenda= dict()\nwhile opcion != \"5\":\n    print(\"\\n*************Agenda de Contactos*************\")\n    print()\n    print(\"Decida la opcion que quiera realizar:\")\n    print()\n    print(\"Opcion 1: Buscar contacto\")\n    print(\"Opcion 2: Nuevo contacto\")\n    print(\"Opcion 3: Actualizar contacto\")\n    print(\"Opcion 4: Eliminar contacto\")\n    print(\"Opcion 5: Salir\")\n    print()\n    opcion=input(\"Intruzca el numero de la opcion que desee: \")\n\n    if opcion == \"1\":\n        print(\"\\nNombre\\t\\t\\tNumero\")\n        for nombre,numero in agenda.items():\n            print(f\"{nombre}\\t\\t\\t{numero}\")\n    elif opcion == \"2\":\n        nombre=input(\"Introduzca el nombre de la persona: \")\n        numero=input(\"Introduzca el numero de la persona: \")\n        if len(numero) > 11:\n            print(\"El numero supera el limite\")\n        else :\n            for i in numero:\n                if i !='0' and i !='1' and i !='2' and i !='3' and i !='4' and i !='5' and i !='6' and i !='7' and i !='8' and i !='9': \n                    print(\"No ha introducido un numero\")\n                    break\n                agenda[nombre]=numero\n    elif opcion == \"3\":\n        print(\"Decida la opcion que quiera realizar:\")\n        print()\n        print(\"Opcion 1: Actualizar nombre\")\n        print(\"Opcion 2: Actualizar numero\")\n        print()\n        sub_opcion=input(\"Intruzca el numero de la opcion que desee: \")\n        if sub_opcion==\"1\":\n            numero=input(\"Introduzca el numero de la persona: \")\n            if len(numero) > 11:\n                print(\"El numero supera el limite\")\n            else :\n                for i in numero:\n                    if i !='0' and i !='1' and i !='2' and i !='3' and i !='4' and i !='5' and i !='6' and i !='7' and i !='8' and i !='9': \n                        print(\"No ha introducido un numero\")\n                        break                    \n                for key,values in agenda.items():\n                    if(numero == values):\n                        print(f\"El numero coincide con el nombre : {key}\")\n                        actualizar_nombre=key\n                        nombre=input(\"Introuduce el nuevo nombre: \") \n                    else:\n                        sub_contador= sub_contador +1\n                    contador=contador +1\n                if contador==sub_contador:\n                    print(f\"\\nEl numero: {numero} no encuentra coincidencias.\")\n                    contador=0\n                    sub_contador=0\n                else:\n                    del agenda[actualizar_nombre]\n                    actualizar_nombre=\"\"\n                    agenda[nombre]=numero\n        elif sub_opcion==\"2\":\n            flag=False\n            nombre=input(\"Introduce el nombre de la persona: \")\n            for key,values in agenda.items():\n                if(nombre == key):\n                    numero=input(\"Introduzca el numero de la persona: \")\n                    if len(numero) > 11:\n                        print(\"El numero supera el limite\")\n                    else :\n                        for i in numero:\n                            if i !='0' and i !='1' and i !='2' and i !='3' and i !='4' and i !='5' and i !='6' and i !='7' and i !='8' and i !='9': \n                                print(\"No ha introducido un numero\")\n                                flag=True\n                                break\n                else:\n                    sub_contador= sub_contador +1\n                contador=contador +1\n            if contador==sub_contador:\n                print(f\"\\nEl nombre: {nombre} no encuentra coincidencias.\")\n                contador=0\n                sub_contador=0\n            if flag==False:\n                agenda[nombre]=numero\n        else:\n            print(\"Opcion erronea\")\n    elif opcion == \"4\":\n        print(\"\\nNombre\\t\\t\\tNumero\")\n        for nombre,numero in agenda.items():\n            print(f\"{nombre}\\t\\t\\t{numero}\")\n        nombre=input(\"Introuduce el nombre de la persona que desea eliminar: \")\n        for key,values in agenda.items():\n            if(nombre == key):  \n                del agenda[nombre]\n            else:\n                sub_contador= sub_contador +1\n            contador = contador +1\n        if(sub_contador==contador):\n            print(f\"\\nEl nombre: {nombre} no encuentra coincidencias.\")\n            contador=0\n            sub_contador=0\n    elif opcion==\"5\":\n        print(\"Fin del programa\")\n        break\n    else:\n        print(\"Opcion erronea.\")\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/RuhlMirko.py",
    "content": "import os\n\nprint(\"Listas\")\nnumber_list = [0, 1, 2, 3, 4, 5]  # Crea una lista con Ints\nstring_list = [\"A\", \"B\", \"C\", \"D\"]  # Crea una lista con Strings\nprint(f\"{number_list}\\n{string_list}\")\n\nstring_list.append(\"E\")  # Agrega un elemento a una lista creada\nstring_list.remove(\"A\")  # Remueve un elemento buscado por coincidencias\nnumber_list.pop(5)  # Remueve un elemento buscado por indice\nstring_list[1] = \"F\"  # Accede y actualiza un item de la lista por indice\nstring_list.sort()  # Ordena la lista de forma alfabetica. Tambien util para lista de numeros\nprint(f\"nuevas listas:\\n{number_list} \\n{string_list}\")\n\nprint(\"\\nTuplas\")\n\ntupla = (\"Python\", \"Ejercicio 03\", \"Estructura de datos\", \"RuhlMirko.py\")\nprint(tupla)\nprint(tupla[2])  # Devuelve el valor de la tupla buscado por indice\nprint(tuple(sorted(tupla)))  # Ordena la tupla por orden alfabetico. Tambien util para tupla de numeros\n\nprint(\"\\nSets\")\nmy_set = {\"Python\", \"Ejercicio 03\", \"Estructura de datos\", \"RuhlMirko.py\"}\nprint(my_set)\nmy_set.add(\"Java\")  # Agrega un elemento a un set\nmy_set.remove(\"Python\")  # Remueve un elemnto del set\nprint(my_set)\n\nprint(\"\\nDiccionarios\")\nmy_dict = {\n    \"#00\": \"Sintaxis, variables, tipos de datos y hola mundo\",\n    \"#02\": \"Funciones\",\n    \"#01\": \"Operadores y estructuras de control\"\n}\n\nprint(my_dict[\"#01\"])  # Acceso de datos por clave\nmy_dict[\"#03\"] = \"Estructuras de datos\"  # Agrega un elemento al diccionario\nmy_dict[\"#02\"] = \"Funciones y alcance\"  # Actualiza un elemnto ya declarado\nmy_dict[\"#03\"] = \"Estructuras de datos\"  # Agrega un elemento al diccionario\nprint(my_dict)\n\nmy_dict.pop(\"#03\")  # Una manera de eliminar un elemento\nmy_dict[\"#03\"] = \"Estructuras de datos\"\ndel my_dict[\"#03\"]  # Otra manera de eliminar un elemento\n\nmy_dict = dict(sorted(my_dict.items()))\nprint(my_dict)\n\nprint(\"\\nDificultad extra: \")\ncontact_dict = {}\nwhile True:\n    user_choice = int(input(\"\\nBienvenido a tu agenda de contactos\"\n                            \"\\n1) Ingresar nuevo contacto\"\n                            \"\\n2) Buscar contacto\"\n                            \"\\n3) Actualizar contacto\"\n                            \"\\n4) Eliminar contacto\"\n                            \"\\n5) Mostrar lista de contactos\"\n                            \"\\n\\n0) Salir del programa\"\n                            \"\\nElija la operacion: \"))\n    match user_choice:\n        case 0:\n            break\n        case 1:\n            while True:\n                name = input(\"Enter the new contact name: \").lower()\n\n                while True:\n                    try:\n                        number = int(input(\"Enter the cellphone number: \"))\n                        number_length = len(str(number))\n                        break\n                    except ValueError:\n                        print(\"Enter a valid number\")\n\n                while True:\n                    if number_length > 11:\n                        number = input(\"You can only enter 11 digits, Enter the number again: \")\n                        number_length = len(number)\n                    else:\n                        break\n\n                contact_dict[name] = number\n                break\n        case 2:\n            search_term = input(\"Ingrese el nombre del contacto: \").lower()\n            try:\n                print(f\"Cellphone number of {search_term}: {contact_dict[search_term]}\")\n            except KeyError:\n                print(f\"{search_term} not available in your contact list.\")\n\n        case 3:\n            search_term = input(\"Ingrese el nombre del contacto a actualizar : \").lower()\n\n            if search_term in contact_dict:\n                contact_dict[search_term] = input(\"Enter the new number: \")\n            else:\n                print(f\"{search_term} not available in your contact list.\")\n        case 4:\n            search_term = input(\"Ingrese el nombre del contacto a eliminar: \")\n            if search_term in contact_dict:\n                del contact_dict[search_term]\n            else:\n                print(f\"{search_term} not available in your contact list.\")\n        case 5:\n            print(contact_dict)\n        case _:\n            print(\"\\nEnter a valid option\\n\")\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Rusanov16.py",
    "content": "\"\"\"\nEJERCICIO:\n- Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n- Utiliza operaciones de inserción, borrado, actualización y ordenación.\n\nDIFICULTAD EXTRA (opcional):\nCrea una agenda de contactos por terminal.\n- Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n- Cada contacto debe tener un nombre y un número de teléfono.\n- El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n  los datos necesarios para llevarla a cabo.\n- El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n  (o el número de dígitos que quieras)\n- También se debe proponer una operación de finalización del programa.\n\"\"\"\n\n#*-------------------------------------------------------------------------------------------------------------#\n\n\"\"\"\n- Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n- Utiliza operaciones de inserción, borrado, actualización y ordenación.\n\"\"\"\n\nprint(\"-----------------------------------------------------------------------------------------------------\")\n#Listas\nprint(\"LISTAS\")\nlista = [1,2,3,4]\nprint(f\"Esto es una lista = {lista}\")\n\n#Inserción\nlista.append(3)\nprint(f\"Con la función append se añaden nuevos elementos al final de la lista {lista}\")\n\n#Borrado\nlista.remove(1)\nprint(f\"Con la función remove se eliminan el valor de los elementos que esten dentro de la lista {lista}\")\n\n#Actualizacion\nlista[2] = 20\nprint(f\"Para actualizar valores de la lista hay que indicar con [el indice que se quiere actualizar] {lista}\")\n\n#Ordenacion\nlista.sort()\nprint(f\"Para ordenar los valores de los elementos de la lista, se utiliza la función sort {lista}\")\n\nprint(\"-----------------------------------------------------------------------------------------------------\")\n\n#Set\nprint(\"SET\")\n#Forma uno: Usando la función set()\nset_forma_uno = set([1,2,4,5])\nprint(f\"Estos es un set: {set_forma_uno}\")\nprint(f\"Una forma de hacer un set es con la función set(): {set_forma_uno}\")\n#Forma dos: Usando {}\nset_forma_dos = {1,2,3,4,5}\nprint(f\"Otra forma de hacer un set es definiendo con: {set_forma_dos}\")\n#IMPORTANTE: Los elementos de un set deben ser inmutables.\n\n#Inserccion\nset_forma_uno.add(8) #Forma uno\nset_forma_dos.add(66) #Forma dos\nprint(f\"Para insertar elementos dentro del set, se usa la función add(): {set_forma_uno} y {set_forma_dos}\")\n\n#Borrado\nset_forma_uno.remove(8) #Forma uno\nset_forma_dos.remove(66) #Forma dos\nprint(f\"Una forma de eliminar elementos dentro del set es usando la función remove(): {set_forma_uno} y {set_forma_dos}\")\n\nprint(\"-----------------------------------------------------------------------------------------------------\")\n\n#Tuplas\nprint(\"TUPLAS\")\ntupla_uno = (1,2,4) #Forma 1\ntupla_dos = 1,2,3,4 #Forma 2\nprint(f\"Esto es una tupla {tupla_uno}\")\n#IMPORTANTE: Los elementos de un set deben ser inmutables.\nprint(\"-----------------------------------------------------------------------------------------------------\")\n\n#Diccionario\nprint(\"DICCIONARIO\")\ndic_uno = {'Fruta':'Manzana',\n           'Hortaliza':'Zanahoria'}\nprint(f\"Esto ez un diccionario: {dic_uno}\")\n\n#Actualizar\ndic_uno['Fruta'] = \"Durazno\" \nprint(f\"Para actualizar valores del diccionario hay que indicar con [elemento que se quiere actualizar]: {dic_uno}\")\n\n#*-------------------------------------------------------------------------------------------------------------#\n\"\"\"\nDIFICULTAD EXTRA (opcional):\nCrea una agenda de contactos por terminal.\n- Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n- Cada contacto debe tener un nombre y un número de teléfono.\n- El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n  los datos necesarios para llevarla a cabo.\n- El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n  (o el número de dígitos que quieras)\n- También se debe proponer una operación de finalización del programa.\n\"\"\"\n#*-------------------------------------------------------------------------------------------------------------#\n\nagenda_contactos = {\n    'Carlos': '10985565324',\n    'Juan' : '18709253628'}\n\n# INSERTAR CONTACTO\ndef insertar_contactos():\n    nombre = input(\"Indique su nombre: \")\n    telefono = input(\"Indique su número de teléfono: \")\n\n    if len(telefono) <= 11 and telefono.isdigit() and int(telefono) >= 0:\n        agenda_contactos[nombre] = telefono\n        print(f\"Contacto {nombre} agregado correctamente.\")\n    else:\n        print(\"Número de teléfono inválido. Debe ser numérico y tener hasta 11 dígitos.\")\n\n# BUSCAR CONTACTO\ndef buscar_contacto():\n    nombre = input(\"Indique el nombre del contacto: \")\n    if nombre in agenda_contactos:\n        print(f\"Contacto {nombre}: {agenda_contactos[nombre]}\")\n    else:\n        print(f\"El contacto {nombre} no se encontró en la agenda.\")\n\n# ACTUALIZAR CONTACTO\ndef actualizar_contactos():\n    nombre = input(\"Indique el nombre del contacto que desea actualizar: \")\n    if nombre in agenda_contactos:\n        nuevo_telefono = input(\"Indique el nuevo número de teléfono: \")\n\n        if len(nuevo_telefono) <= 11 and nuevo_telefono.isdigit() and int(nuevo_telefono) >= 0:\n            agenda_contactos[nombre] = nuevo_telefono\n            print(f\"Teléfono de {nombre} actualizado correctamente.\")\n        else:\n            print(\"Número de teléfono inválido. Debe ser numérico y tener hasta 11 dígitos.\")\n    else:\n        print(f\"El contacto {nombre} no se encontró en la agenda.\")\n\n# ELIMINAR CONTACTOS\ndef eliminar_contactos():\n    nombre = input(\"Indique el nombre del contacto que desea eliminar: \")\n    if nombre in agenda_contactos:\n        del agenda_contactos[nombre]\n        print(f\"El contacto {nombre} ha sido eliminado correctamente.\")\n    else:\n        print(f\"El contacto {nombre} no se encontró en la agenda.\")\n\nmenu = True\n\nwhile menu:\n    print(\"---------------------------------------------------\")\n    print(\"BIENVENIDOS A LA AGENDA DE CONTACTOS\")\n    print(\"---------------------------------------------------\")\n    print(\"¿QUÉ PROCESO QUIERE REALIZAR?\")\n    print(\"-----------------------------\")\n    print(\"|1.| BUSCAR CONTACTO         |\")\n    print(\"|2.| CREAR CONTACTO          |\")\n    print(\"|3.| ACTUALIZAR CONTACTO     |\")\n    print(\"|4.| ELIMINAR CONTACTO       |\")\n    print(\"|5.| VER AGENDA DE CONTACTOS |\")\n    print(\"|6.| SALIR                   |\")\n\n    opcion = input(\"Indique la opción que desea realizar: \")\n\n    if opcion == \"1\":\n        buscar_contacto()\n    elif opcion == \"2\":\n        insertar_contactos()\n    elif opcion == \"3\":\n        actualizar_contactos()\n    elif opcion == \"4\":\n        eliminar_contactos()\n    elif opcion == \"5\":\n        print(f\"Agenda de Contactos = {agenda_contactos}\")\n    elif opcion == \"6\":\n        print(\"¡Hasta luego!\")\n        break\n    else:\n        print(\"Opción inválida. Intente nuevamente.\")\n\n\n\n  \n  \n#\"-------------------------------------------------------------------------------------------\"#\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Sac-Corts.py",
    "content": "\"\"\"\n  EJERCICIO\n\"\"\"\n# Listas\nmi_lista = [5, 2, 9, 1, 5, 6]\n# Inserción\nmi_lista.append(3)  # Añade el elemento 3 al final\nprint(\".append:\", mi_lista)\nmi_lista.insert(1, 4)  # Inserta el elemento 4 en la posición 1\nprint(\".insert:\", mi_lista)\n# Borrado\nmi_lista.remove(5)  # Elimina la primera ocurrencia del elemento 5\nprint(\".remove:\", mi_lista)\nelemento = mi_lista.pop(2)  # Elimina el elemento en la posición 2 y lo retorna\nprint(\".pop\", mi_lista)\n# Actualización\nmi_lista[0] = 10  # Actualiza el primer elemento a 10\nprint(\"Actualización:\", mi_lista)\n# Ordenación\nmi_lista_ordenada = sorted(mi_lista)  # Retorna una nueva lista ordenada\nprint(\"Lista ordenada:\", mi_lista_ordenada)\nmi_lista.sort()  # Ordena la lista en su lugar\nprint(\".sort:\", mi_lista)\n\n# Tuplas\nmi_tupla = (5, 2, 9, 1, 5, 6)\n# Las tuplas son inmutables, por lo que no se pueden modificar directamente. Sin embargo, se pueden crear nuevas tuplas combinando otras. ###\n# Actualización (crear una nueva tupla)\nnueva_tupla = mi_tupla[:2] + (10,) + mi_tupla[3:]\n# Ordenación\ntupla_ordenada = tuple(sorted(mi_tupla))\nprint(\"Tupla original:\", mi_tupla)\nprint(\"Nueva tupla:\", nueva_tupla)\nprint(\"Tupla ordenada:\", tupla_ordenada)\n\n# Conjuntos o Sets\nmi_conjunto = {5, 2, 9, 1, 5, 6}\nprint(\"Conjunto:\", mi_conjunto)\n# Inserción\nmi_conjunto.add(3)  # Añade el elemento 3\nprint(\".add:\", mi_conjunto)\n# Borrado\nmi_conjunto.remove(5)  # Elimina el elemento 5\nprint(\".remove:\", mi_conjunto)\nmi_conjunto.discard(7)  # Elimina el elemento 7 si existe, si no, no hace nada\nprint(\".discard:\", mi_conjunto)\n### Actualización ###\n# No se puede actualizar un elemento específico en un conjunto, pero se pueden añadir y eliminar elementos.\n# Ordenación (crear una lista ordenada a partir del conjunto)\nconjunto_ordenado = sorted(mi_conjunto)\nprint(\"Conjunto ordenado:\", conjunto_ordenado)\n\n# Diccionarios\nmi_diccionario = {'a': 5, 'b': 2, 'c': 9, 'd': 1}\nprint(\"Diccionario:\", mi_diccionario)\n# Inserción\nmi_diccionario['e'] = 6  # Añade un nuevo par clave-valor\nprint(\"Inserción:\", mi_diccionario)\n# Borrado\ndel mi_diccionario['b']  # Elimina el par con clave 'b'\nprint(\"del:\", mi_diccionario)\nvalor = mi_diccionario.pop('c')  # Elimina el par con clave 'c' y retorna su valor\nprint(\".pop:\", mi_diccionario)\n# Actualización\nmi_diccionario['a'] = 10  # Actualiza el valor asociado a la clave 'a'\nprint(\"Actualización:\", mi_diccionario)\n# Ordenación (crear una lista de claves ordenadas)\nclaves_ordenadas = dict(sorted(mi_diccionario.items()))\nprint(\"Claves ordenadas:\", claves_ordenadas)\n\n\"\"\"\nDIFICULTAD EXTRA\n\"\"\"\ncontactos = {}\n\n# Función para mostrar menú\ndef mostrar_menu():\n    print(\"\\nAgenda de Contactos\")\n    print(\"1. Insertar contacto\")\n    print(\"2. Buscar contacto\")\n    print(\"3. Actualizar contacto\")\n    print(\"4. Eliminar contacto\")\n    print(\"5. Salir\")\n    return input(\"Selecciona una opción: \")\n\n# Función para validar el número de teléfono\ndef validar_numero(telefono):\n    if telefono.isdigit() and 1 <= len(telefono) <= 11:\n        return True\n    else: \n        return False \n\n# Función para insertar un contacto\ndef insertar_contacto():\n    nombre = input(\"Introduce el nombre del contacto: \")\n    telefono = input(\"Introduce el número de teléfono del contacto (máximo 11 dígitos): \")\n    if validar_numero(telefono):\n        contactos[nombre] = telefono\n        print(f\"Contacto {nombre} añadido.\")\n    else: \n        print(\"Número de teléfono no válido. Debe ser numérico y no exceder 11 dígitos.\")\n     \n# Función para buscar un contacto\ndef buscar_contacto():\n    nombre = input(\"Introduce el nombre del contacto: \")\n    if nombre in contactos:\n        print(f\"Nombre: {nombre}, Teléfono: {contactos[nombre]}\")\n    else:\n        print(f\"El contacto {nombre} no está en la agenda.`\")\n\n# Función para actualizar un contacto\ndef actualizar_contacto():\n    nombre = input(\"Introduce el nombre del contacto que deseas actualizar: \")\n    if nombre in contactos: \n        nuevo_telefono = input(\"Introduce el nuevo número de teléfono (máximo 11 dígitos): \")\n        if validar_numero(nuevo_telefono):\n            contactos[nombre] = nuevo_telefono\n            print(f\"Contacto {nombre} actualizado.\")\n        else: \n            print(\"Número de teléfono no válido. Debe ser numérico y no exceder 11 dígitos.\")\n    else: \n        print(f\"El contacto {nombre} no está en la agenda.\")\n\n# Función para eliminar un contacto\ndef eliminar_contacto():\n    nombre = input(\"Introduce el nombre del contacto que deseas eliminar: \")\n    if nombre in contactos:\n        del contactos[nombre]\n        print(f\"Contacto {nombre} eliminado.\")\n    else:\n        print(f\"El contacto {nombre} no está en la agenda.\")\n\n# Función principal\ndef principal():\n    while True:\n        opcion = mostrar_menu()\n        if opcion == '1':\n            insertar_contacto()\n        elif opcion == '2':\n            buscar_contacto()\n        elif opcion == '3':\n            actualizar_contacto()\n        elif opcion == '4':\n            eliminar_contacto()\n        elif opcion == '5':\n            print(\"Saliendo del programa.\")\n            break\n        else:\n            print(\"Opción no válida. Por favor, selecciona una opción del 1 al 5.\")\n\n\nprincipal()\nprint(contactos)"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/SaezMD.py",
    "content": "# #03 ESTRUCTURAS DE DATOS\n#### Dificultad: Media | Publicación: 15/01/24 | Corrección: 22/01/24\n\n\"\"\"\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n\"\"\"\n\n#Lists\nlist = [\"campo\", \"tierra\", \"playa\", \"montaña\"]\nprint(list)\n#add:\nlist.append(\"rio\")\nprint(list)\n#remove:\nlist.remove(\"campo\")\nprint(list)\n#remove:\nlist.pop(2)\nprint(list)\n#insert:\nlist.insert(0,\"huerto\")\nprint(list)\n#sort:\nlist.sort()\nprint(list)\nlist.sort(reverse=True)\nprint(list)\n#access:\nprint(list[2])\n\n#Tuples (inmutable lists)\nnumbs = (1,2,3,4,5,8)\nprint(numbs)\n#Access:\nprint(numbs[4:6])\n#Sort and generate a tuple:\nmyTuple = tuple(sorted(numbs))\n\n#Sets (non sorted structure)\nmySet = {\"saul\",\"Saez\", 38}\nprint(mySet)\nmySet.add(\"saul\") #Error! Duplicated\nmySet.remove(\"Saez\")\nprint(mySet)\nsortedSet = set(sorted(mySet)) #You can't use the sorted\n\n#Matrix (define the type)\nfrom array import array\nnumsMatrix = array('f',[1.5,4.5,7.5,2.5])\nprint(numsMatrix)\n#modify:\nnumsMatrix[0]=3.5\nprint(numsMatrix)\n\n# Dictionaries: key+value\nbooks = {\"title\":\"Ready Player One\"}\nprint(books)\n#add:\nbooks[\"Autor\"]=\"just one\"\nprint(books)\n#remove:\nbooks.pop(\"Autor\")\nprint(books)\n#update:\nbooks[\"title\"]=\"The green book\"\nprint(books)\n\n#Search\n#Get Value:\nprint(books[\"title\"])\n#Get Key:\nfor title, book in books.items():\n    if book == \"The green book\":\n        print(f\"Key: {title} - Value: {book}\")    \n\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.\n\"\"\"\nimport re\n\nagenda = {\n    \"Name\": \"\",\n    \"Telephone\": \"\"\n}\n\ndef checkTelephoneNumber(toCheck) -> bool:\n    \"\"\"function to check if the telephone number is a number and less than 12 digits\"\"\"\n    if re.match('[0-9]{9,13}', toCheck):\n        return True\n    return False\n\ndef insert():\n    \"\"\"function to insert names and telephones\"\"\"\n    insertNameUser = input(\"Enter name:\")\n    insertTelephoneUser = input(\"Enter phone number:\")\n    if not checkTelephoneNumber(insertTelephoneUser): #Check if the phone format is correct\n        return print(f\"Phone number is not valid. Wrong: {insertTelephoneUser}. Max lenght: 13. Min lenght: 9. Only numbers.\")\n\n    if insertNameUser in agenda:\n        return print(\"Name already in agenda.\")\n    \n    #add new name and phone\n    agenda[insertNameUser]=insertTelephoneUser\n    print(agenda)\n    return print(f\"New insert OK. Name: {insertNameUser} - Telephone: {insertTelephoneUser}\")   \n\ndef search():\n    \"\"\"function to search by name or telephone\"\"\"\n    searchNameOrTelephoneUser = input(\"Enter name or phone for search:\")\n\n    if checkTelephoneNumber(searchNameOrTelephoneUser): #Check if the phone format is correct and if it's a number\n        for name, phone in agenda.items():\n            if phone == searchNameOrTelephoneUser:\n                return print(f\"Name: {name} - Telephone: {phone}\")     #return value or key\n    else: #no digit\n        if not searchNameOrTelephoneUser in agenda: #check if value exists\n            return print(\"Name not in agenda.\")\n        return print(f\"Name: {searchNameOrTelephoneUser} - Telephone: {agenda[searchNameOrTelephoneUser]}\")\n        \ndef update():\n    \"\"\"function to update name and telephone\"\"\"\n    updateNameUser = input(\"Enter name to update:\")\n    #check if name exists\n    if not updateNameUser in agenda:\n        return print(\"Name not in agenda.\")\n    newUpdateNameUser = input(\"Enter New name to update:\")\n    newUpdateTelephoneUser = input(\"Enter New phone to update:\")\n    if not checkTelephoneNumber(newUpdateTelephoneUser): #Check if the phone format is correct\n        return print(f\"Phone number is not valid. Wrong: {newUpdateTelephoneUser}. Max lenght: 13. Min lenght: 9. Only numbers.\")\n\n    #remover and create again\n    agenda.pop(updateNameUser)\n    agenda[newUpdateNameUser]=newUpdateTelephoneUser\n    return print(f\"User updated. New register is Name: {newUpdateNameUser} - Telephone: {newUpdateTelephoneUser}\")\n\ndef erase():\n    \"\"\"function to erase by name\"\"\"\n    eraserNameUser = input(\"Enter name to erase:\")\n    #Check if register exist\n    if not eraserNameUser in agenda:\n        return print(\"Name not in agenda.\")\n    #Erase the register\n    agenda.pop(eraserNameUser)\n    return print(f\"Register erased! {eraserNameUser}\")\n\ndef mainCaller():\n    \"\"\"main function to control the agenda options\"\"\"\n    while True:\n        inputUser = input(\"Enter operation: (Search/Insert/Update/Erase or Exit)\")\n        if inputUser == \"Exit\":\n            return print(\"Exiting and closing agenda! \\nBye\")\n        elif inputUser == \"Search\":\n            search()\n        elif inputUser == \"Insert\":\n            insert()\n        elif inputUser == \"Update\":\n            update()\n        elif inputUser == \"Erase\":\n            erase()\n        else:\n            print(\"Please select a correct option!\")\n\nmainCaller()\n\ndef maincaller2():\n    while True:\n        option = input(\"Enter operation: (Search/Insert/Update/Erase or Exit)\")\n        match option:\n            case \"Exit\":\n                break\n            case \"Search\":\n                pass\n            case \"Insert\":\n                pass\n            case \"Update\":\n                pass\n            case \"Erase\":\n                pass\n\n        \n        \n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/SaicoBys.py",
    "content": "#1 Estructuras de datos soportadas por defecto en Python\n\n# Listas (mutables, ordenadas)\nlista_numeros = [5, 2, 8, 1, 9]\nprint(\"Lista original:\", lista_numeros)\n\n# Inserción\nlista_numeros.append(3)  # Agrega al final\nlista_numeros.insert(2, 7)  # Inserta en una posición específica\nprint(\"Lista después de inserciones:\", lista_numeros)\n\n# Borrado\ndel lista_numeros[0]  # Borra por índice\nlista_numeros.remove(8)  # Borra por valor\nprint(\"Lista después de borrados:\", lista_numeros)\n\n# Actualización\nlista_numeros[1] = 4\nprint(\"Lista después de actualización:\", lista_numeros)\n\n# Ordenación\nlista_numeros.sort()  # Ordena de forma ascendente\nprint(\"Lista ordenada:\", lista_numeros)\n\n# Tuplas (inmutables, ordenadas)\ntupla_colores = (\"rojo\", \"verde\", \"azul\")\nprint(\"\\nTupla original:\", tupla_colores)\n\n# Conjuntos (mutables, no ordenados, sin duplicados)\nconjunto_frutas = {\"manzana\", \"pera\", \"banana\"}\nprint(\"\\nConjunto original:\", conjunto_frutas)\n\nconjunto_frutas.add(\"uva\")  # Inserción\nconjunto_frutas.remove(\"pera\")  # Borrado\nprint(\"Conjunto después de operaciones:\", conjunto_frutas)\n\n# Diccionarios (mutables, no ordenados, pares clave-valor)\ndiccionario_edades = {\"Ana\": 25, \"Carlos\": 30, \"Laura\": 22}\nprint(\"\\nDiccionario original:\", diccionario_edades)\n\ndiccionario_edades[\"Pedro\"] = 35  # Inserción\ndel diccionario_edades[\"Carlos\"]  # Borrado\ndiccionario_edades[\"Laura\"] = 23  # Actualización\nprint(\"Diccionario después de operaciones:\", diccionario_edades)\n\n# Ejercicio\n\ncontactos = {}  # Diccionario para almacenar los contactos\n\ndef agregar_contacto(nombre, telefono):\n    if nombre in contactos:\n        print(\"El contacto ya existe.\")\n    else:\n        contactos[nombre] = telefono\n        print(\"Contacto agregado exitosamente.\")\n\ndef buscar_contacto(nombre):\n    if nombre in contactos:\n        print(f\"El número de teléfono de {nombre} es: {contactos[nombre]}\")\n    else:\n        print(\"El contacto no existe.\")\n\ndef actualizar_contacto(nombre, nuevo_telefono):\n    if nombre in contactos:\n        contactos[nombre] = nuevo_telefono\n        print(\"Contacto actualizado exitosamente.\")\n    else:\n        print(\"El contacto no existe.\")\n\ndef eliminar_contacto(nombre):\n    if nombre in contactos:\n        del contactos[nombre]\n        print(\"Contacto eliminado exitosamente.\")\n    else:\n        print(\"El contacto no existe.\")\n\nwhile True:\n    operacion = input(\"¿Qué deseas hacer? (agregar, buscar, actualizar, eliminar, salir): \")\n\n    if operacion == \"agregar\":\n        nombre = input(\"Nombre del contacto: \")\n        telefono = input(\"Teléfono del contacto: \")\n        agregar_contacto(nombre, telefono)\n    elif operacion == \"buscar\":\n        nombre = input(\"Nombre del contacto: \")\n        buscar_contacto(nombre)\n    elif operacion == \"actualizar\":\n        nombre = input(\"Nombre del contacto: \")\n        nuevo_telefono = input(\"Nuevo teléfono del contacto: \")\n        actualizar_contacto(nombre, nuevo_telefono)\n    elif operacion == \"eliminar\":\n        nombre = input(\"Nombre del contacto: \")\n        eliminar_contacto(nombre)\n    elif operacion == \"salir\":\n        break\n    else:\n        print(\"Operación no válida.\")"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Seni889.py",
    "content": "\nmylista = [\"Andy\", \"Josue\", \"Josue\"]\nprint(mylista)\n\n# mylista.append(\"Jordy\")\n# print(mylista)\n\n# mylista.extend(\"papa\")\n# print(mylista)\n\n# mylista.insert(1, \"Reyes\")\n# print(mylista)\n\n# mylista[1] = \"Maria\"\n# print(mylista)\n\n# mylista.sort()\n# print(mylista)\n\n# mylista.reverse()\n# print(mylista)\n\n# mylista.copy()\n# print(mylista)\n\nprint(mylista.count(\"Josue\"))\n\n#listas\nreseta = [\"arroz\", \"aceite\", \"camote\", \"cebolla\", \"arroz\", \"aceite\"]\nalimento = [\"ceviche\", \"arroz con pollo\", \"sudado\"]\nanimales= [\"Leon\", \"caballo\", \"tigre\", \"perro\"]\n\nprint(reseta)\nprint(alimento)\nprint(animales)\n\n#contamos\nprint(reseta.count(\"arroz\"))\n\nprint(reseta.count(\"camote\"))\n\nprint(reseta.index(\"aceite\"))\n\nalimento.append(\"arroz chaufa\")\nprint(alimento)\nalimento.insert(3, \"arroz con pato\")\nprint(alimento)\n\nalimento.sort()\nprint(alimento)\n\nalimento.pop()\nprint(alimento)\n# animales.remove(\"\")\n# animales.clear(\"\")\n\n#usar listas\nnumeros = [3, 4, 5, 6]\nnumeros.append(7)\nnumeros.append(8)\nnumeros.append(10)\n\nnumeros.insert(6, 9)\nprint(numeros)\n\nnumeros.pop()\nprint(numeros)\n\nnumeros.pop()\nprint(numeros)\n\nnumeros.remove(8)\nprint(numeros)\n\nnumeros.reverse()\nprint(numeros)\n\nprint(numeros.index(5))\nprint(numeros.index(5, 1 ))\nprint(numeros)\n\n#usar listas como colas\n\n#tuplas\ndatos = (\"Jose\", \"Rey\", \"21\")\n\nprint(datos)\nprint(datos[1])\n\ndatos = tuple(sorted(datos))\nprint(type(datos))\n\n#set\nalimentos = {\"pan\", \"aceite\", \"verduras\"}\n\nalimentos.add(\"queso\")\nalimentos.update([\"queso\", \"leche\", \"galletas\"])\nalimentos.remove(\"verduras\")\nalimentos.pop()\nalimentos.discard(\"Kevin\")\nalimentos = set(sorted(alimentos)) #Se intenta ordenar pero no se puede\nprint(type(alimentos))\nprint(alimentos)\n\n#diccionario\n\ncomidas = {\"ceviche\" : \"nombre\", \"cebolla\" : \"ingrediente\", \n           \"arroz\": \"implemento\"}\ncomidas[\"limon\"] = \"necesario\" #insersion\ncomidas[\"ceviche\"] = \"plato\" #actualizacion\n\ndel comidas[\"cebolla\"]  #eliminacion datos\n\n# comidas = sorted(comidas) #solo regresa los items\n\ncomidas = dict(sorted(comidas.items())) #un diccionario que se ordeno \n\n\nprint(comidas)\n\n\n\"\"\"\nEXTRA\n\"\"\"\n\ndef agendas():\n\n    agenda = {}\n\n    while True:\n\n    \n\n        print(\"1. Buscar contacto\")\n        print(\"2. Insertar contacto\")\n        print(\"3. actualiza contacto\")\n        print(\"4. elimina contactos\")\n        print(\"5. salir\")\n        \n\n\n        opcion = input(\"Ingresa la operacion que deseas 1 ... 5: \")\n\n        match opcion:\n            case \"1\":\n                nombre = input(\"Ingrese el nombre que desea buscar: \")\n                if nombre in agenda:\n                    print(f\"El usuario con el nombre: {nombre} y su numero es : {agenda[nombre]}\")\n                    print(\"La busqueda fue exitosa\")\n\n                else:\n                    print(f\"El usuarios: {nombre} no se encuentra\")\n\n            case \"2\":\n                nombre = input(\"Ingrese contacto: \")\n                telefono = input(\"Ingrese numero de telefono: \")\n                if telefono.isdigit() and len(telefono) > 0 and len(telefono) <=9:\n                    agenda[nombre] = telefono\n                else:\n                    print(\"Ingrese un numero que no sobrepase los 9 digitos\")\n\n            case \"3\":\n                \n                nombre = input(\"Ingrese el nombre que desea actualizar: \")\n                if nombre in agenda:\n                    telefono = input(\"Ingrese el contacto que desea actualizar: \")\n                    if telefono.isdigit() and len(telefono) > 0 and len(telefono) <= 9:\n                        agenda[nombre] = telefono\n                    else:\n                        print(\"Ingrese un numero valido\")\n                else:\n                    print(\"El contacto no existe\")\n\n\n\n            case \"4\":\n                nombre = input(\"Ingresa el contacto que deseas eliminar: \")\n                if nombre in agenda:\n                    del agenda[nombre]\n                    print(\"Eliminacion exitosa\")\n                else:\n                    print(f\"El contacto {nombre} no existe\")\n            \n            case \"5\":\n                print(\"Saliendo del programa\")\n                break\n\n\n\n   \n\nagendas()\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/SergioGI99.py",
    "content": "\"\"\"\n--------------------\nESTRUCTURAS DE DATOS\n--------------------\nEJERCICIO:\n- Muestra ejemplos de creación de todas las estructuras soportadas por defecto\nen tu lenguaje.\n- Utiliza operaciones de inserción, borrado, actualización y ordenación.\n\nDIFICULTAD EXTRA (opcional):\nCrea una agenda de contactos por terminal.\n- Debes implementar funcionalidades de búsqueda, inserción, actualización\ny eliminación de contactos.\n- Cada contacto debe tener un nombre y un número de teléfono.\n- El programa solicita en primer lugar cuál es la operación que se quiere realizar,\ny a continuación los datos necesarios para llevarla a cabo.\n- El programa no puede dejar introducir números de teléfono no númericos y con más\nde 11 dígitos (o el número de dígitos que quieras).\n- También se debe proponer una operación de finalización del programa.\n\"\"\"\n# Ejercicio\nmy_tuple = (1, 2, 3)\nmy_set = {1, 2, 3}\nmy_list = [1, 2, 3]\n\nmy_list.append(4)\nprint(my_list)\n\nmy_list.extend([5, 6, 7])\nprint(my_list)\n\nmy_list.insert(2, 2.5)\nprint(my_list)\n\nmy_list.remove(2.5)\nprint(my_list)\n\nmy_list.pop(1)\nprint(my_list)\n\nmy_list.reverse()\nprint(my_list)\n\n# Extra\nimport re\n\ncontactos = {\n\"sergio\" : 666666666\n}\ndef agenda(action):\n\n    def input_name():\n        inputName: str = input(\"Escribe el nombre del contacto: \")\n        patternName = r\"[A-Za-z]\"\n        if re.search(patternName, inputName):\n            return inputName\n        else:\n            print(\"Nombre de contacto invalido.\")\n            return input_name()\n    \n    def input_number():\n        inputNumber:int = input(\"Escribe un número de telefono: \")\n        patternNumber = r\"[0-9]\"\n        if re.search(patternNumber, inputNumber):\n            return inputNumber\n        else:\n            print(\"Numero de telefono invalido.\")\n            return input_number()\n\n    def añadir():\n        name = input_name()\n        if not name in contactos.keys():\n            number = input_number()\n            contactos[name] = number\n            print(name, \"ha sido añadido a la agenda.\")\n        else:\n            print(\"El contacto ya existe\")\n\n    def buscar():\n        name = input_name()\n        if name in contactos.keys():\n            search = contactos.get(name)\n            print(f\"El numero de \", name, \" es \", search)\n        else:\n            print(\"El contacto no existe\")\n\n    def eliminar():\n        name = input_name()\n        if name in contactos.keys():\n            confirmation = input(f\"Vuelve a escribir el nombre para confirmar:\\n\")\n            if name == confirmation:\n                print(f\"{name} ha sido eliminado de la agenda\")\n                contactos.pop(name)\n            else:\n                print(\"No coincide el nombre\")\n                eliminar()\n        else:\n            print(\"El nombre no aparece en la agenda\")\n        \n    def actualizar():\n        name = input_name()\n        if name in contactos.keys():\n            new_pass = input_number()\n            contactos[name] = new_pass\n            print(f\"{name} ha sido actualizado\")\n        else:\n            print(\"El contacto no existe\")\n\n    if action == \"añadir\":\n        añadir()\n    elif action == \"eliminar\":\n        eliminar()\n    elif action == \"actualizar\":\n        actualizar()\n    elif action == \"buscar\":\n        buscar()\n    elif action == \"salir\":\n        return print(\"Cerrando la agenda de contactos...\")\n    else:\n        print(f\"No se ha encontrado ninguna acción que se llame: {action}\")\n        agenda(input(\"Selecciona otra acción: \"))\n\n    agenda(input(\"Elije otra acción: \"))\n\nagenda(input(\"Que acción quieres realizar(añadir/eliminar/actualiar/buscar/salir): \"))\n\nprint(\"Se ha cerrado la agenda de contactos.\")"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/SooHav.py",
    "content": "#03 ESTRUCTURAS DE DATOS\n\n#Estructuras nativas soportadas por Python\n#Operaciones: inserción, borrado, actualización y ordenación.\n\n\"\"\"\nListas en Python \nPropiedades: mutables, dinámicas, ordenadas, indexadas, \npueden ser anidadas y contener varios tipos de datos\n\"\"\"\nlista = list()\nlista = [\"Sofi\", 2024, \"SooHav\", \"Python\"]\n\nprint(lista[2]) #SooHav\nprint(lista[-1]) #Python\n\n#Inserción\nlista.append(1)\nprint(lista) #[\"Sofi\", 2024, \"SooHav\", \"Python\", 1]\n\nlista.extend([6.5, 7])\nprint(lista) #[\"Sofi\", 2024, \"SooHav\", \"Python\", 1, 6.5, 7]\n\nlista.insert(4, \"Junior\")\nprint(lista) # [\"Sofi\", 2024, \"SooHav\", \"Python\", \"Junior\", 1, 6.5, 7]\n\n#Borrado\ndel lista[6] \nprint(lista)# 6.5\n\nlista.remove(7)\nprint(lista) # 7\n\nlista.pop()\nprint(lista) # 1\n\n#Actualización\nlista[0] = \"Sofia\"\nprint(lista)\n\nlista_num =[1, 10, 20, 4, 8, 2]\nlista_num[1:3] = [9, 3]\nprint(lista_num)\n\n#Ordenación\nlista.reverse()\nprint(lista) # ['Junior', 'Python', 'SooHav', 2024, 'Sofia']\n\nlista_num =[1, 9, 3, 4, 8, 2]\nlista_num.sort()\nprint(lista_num) #[1, 2, 3, 4, 8, 9]\n\nlista_num.sort(reverse=True)\nprint(lista_num) #[9, 8, 4, 3, 2, 1\n\nprint(lista.index(\"Python\")) # 1\n\n\"\"\"\nSet en Python \nPropiedades: inmutables, desordenadas,no admite \nduplicados y puede contener varios tipos de datos\n\"\"\"\nmi_set = set()\nmi_set = {\"Sofi\", 2024, \"SooHav\", \"Python\"}\n\n#Inserción\nmi_set.add(1)\nprint(mi_set) #{1, 2024, 'Python', 'SooHav', 'Sofi'}\n\n#Borrado\nmi_set.remove(1)\nprint(mi_set) #{\"Sofi\", 2024, \"SooHav\", \"Python\"}\n\nmi_set.discard(2024)\nprint(mi_set) #{\"Sofi\", \"SooHav\", \"Python\"}\n\nmi_set.pop()\nprint(mi_set) #{\"Sofi\", \"Python\"} elimina elemento aleatorio\n\nmi_set.clear()\nprint(mi_set) #set()\n\n#Actualización\nmi_set2 = {\"Sofi\", 2024, \"SooHav\", \"Python\"}\nmi_set.update(mi_set2) #unión con otro conjunto\nprint(mi_set)\n\n\"\"\"\nTuplas en Python \nPropiedades: inmutables, rapidas, ordenadas, indexadas, \npueden ser anidadas y pueden contener varios tipos de datos\n\"\"\"\nmi_tupla = tuple()\nmi_tupla = (\"Sofi\", 2024, \"SooHav\", \"Python\")\n\n#Metodos varios, ya que al ser inmutables no se pueden aplicar \n#metodos de inserción, borrado o actualización \n\nmi_tupla = (\"Sofi\", 2024, \"SooHav\", \"Python\")\nprint(mi_tupla.count(\"Sofi\")) #1\nprint(mi_tupla.index(\"Sofi\")) #0\n\nmi_tupla2 = (1, 2, 5, 0)\nprint(sorted(mi_tupla2)) #sorted no soporta tipos mixtos de datos\n\n\"\"\"\nDicconarios en Python \nColección de elementos, donde cada uno tiene una llave \"key\" y un valor \"value\".\nPropiedades: dinámicos, indexados, anidados \n\"\"\"\n\nmi_diccionario = dict()\nmi_diccionario  = {\"nombre\":\"Sofia\", \"año\": 2024, \"alias\": \"SooHav\", \"lenguaje\": \"Python\"}\n\nfor key in mi_diccionario:\n    print(key)\n\nfor key, item in mi_diccionario.items():\n    print(key, item)\n\nit = mi_diccionario.items()\nprint(it)\n\nk = mi_diccionario.keys()\nprint(k)\n\nprint(list(mi_diccionario.values()))\n\n#Inserción y actualización\nmi_diccionario.update({'año': 2023, 'nombre': \"Soo\"}) #{'nombre': 'Soo', 'año': 2023, 'alias': 'SooHav', 'lenguaje': 'Python'}\nprint (mi_diccionario)\n\nmi_diccionario['nombre'] = \"Sofi\" \nprint (mi_diccionario)\n\n#Borrado\nvalor_eliminado= mi_diccionario.pop('nombre')\nprint(valor_eliminado)\n\npar_eliminado = mi_diccionario.popitem() #el último item\nprint(par_eliminado)\n\ndel mi_diccionario['alias']\nprint (mi_diccionario)\n\nmi_diccionario.clear() #borra todos los items\nprint (mi_diccionario)\n\n#Ordenación\n#las claves se mantienen en el orden en que fueron insertadas pero se pueden\n#usar funciones de orden y devuelve una lista\nmi_diccionario = {'nombre': 'Soo', 'año': 2023, 'alias': 'SooHav', 'lenguaje': 'Python'}\n\nclaves_ordenadas = sorted(mi_diccionario.keys()) #como lista\nprint (claves_ordenadas)\n\nitems_ordenados = sorted(mi_diccionario.items()) #como lista\nprint (items_ordenados)\n\n#DIFICULTAD EXTRA: Crea una agenda de contactos por terminal\n\n\"\"\" \n- Debes implementar funcionalidades de búsqueda, inserción, actualización \ny eliminación de contactos.\n - Cada contacto debe tener un nombre y un número de teléfono.\n - El programa solicita en primer lugar cuál es la operación que se quiere realizar, \n y a continuación los datos necesarios para llevarla a cabo.\n - El programa no puede dejar introducir números de teléfono no númericos y con más\n de 11 dígitos (o el número de dígitos que quieras).\n - También se debe proponer una operación de finalización del programa.\n \"\"\"\n\nclass Contacto:\n    def __init__(self, nombre, apellido, telefono):\n        self.nombre = nombre\n        self.apellido = apellido\n        self.telefono = telefono\n  \n    def mostrar_contactos(self):\n        print(f\"Datos de {self.nombre} {self.apellido}: {self.telefono}\")\n\n    def buscar_contacto(self,contactos):\n      if (self.nombre, self.apellido) in contactos:\n          contacto = contactos[self.nombre, self.apellido]\n          print(f\"Datos de {contacto.nombre} {contacto.apellido}: {contacto.telefono}\")\n      else:\n          print(f\"{self.nombre} {self.apellido} no se encuentra en la agenda.\")\n\n    def agregar_a_agenda(self, contactos):\n        if len(self.telefono) <= 12:\n            contactos[(self.nombre, self.apellido)] = self\n            print(f\"{self.nombre} {self.apellido} fue agregado a la agenda.\")\n        else:\n            print(\"Error: El número de teléfono debe tener hasta 12 caracteres.\")\n\n    def actualizar_en_agenda(self, contactos, nuevo_telefono):\n        if (self.nombre, self.apellido) in contactos:\n            if len(nuevo_telefono) <= 12:\n                contactos[(self.nombre, self.apellido)].telefono = nuevo_telefono\n                print(f\"Teléfono de {self.nombre} {self.apellido} actualizado.\")\n            else:\n                print(\"Error: El número de teléfono debe tener hasta 12 caracteres.\")\n        else:\n            print(f\"{self.nombre} {self.apellido} no se encuentra en la agenda. No se puede actualizar.\")\n\n    def eliminar_de_agenda(self, contactos):\n        if (self.nombre, self.apellido) in contactos:\n            del contactos[(self.nombre, self.apellido)]\n            print(f\"{self.nombre} {self.apellido} se eliminó de la agenda.\")\n        else:\n            print(f\"{self.nombre} {self.apellido} no se encuentra en la agenda. No se puede eliminar.\")\n\n#diccionario vacio para agenda de contactos\ncontactos = dict() \n\n#Bucle para trabajar por consola\nwhile True:\n    opcion = input(\n        \"Seleccione una opción numérica:\\n\"\n        \"1. Agenda completa\\n\"\n        \"2. Buscar un contacto\\n\"\n        \"3. Agregar un contacto\\n\"\n        \"4. Actualizar un contacto\\n\"\n        \"5. Eliminar contacto\\n\"\n        \"6. Salir: \"\n    )\n\n    if opcion == \"1\":\n        for contacto_clave, contacto_valor in contactos.items():\n            contacto_valor.mostrar_contactos()\n    elif opcion == \"2\":\n        nombre, apellido = input(\"Ingrese el nombre y apellido a buscar: \").split() #divide el string en nombre y apellido \n        contacto = Contacto(nombre, apellido, \"\")  # teléfono vacío para buscar contacto\n        contacto.buscar_contacto(contactos)\n    elif opcion == \"3\":\n        nombre, apellido, telefono = input(\"Ingrese el nombre, apellido, y teléfono a agendar (separados por espacio): \").split()\n        nuevo_contacto = Contacto(nombre, apellido, telefono)\n        nuevo_contacto.agregar_a_agenda(contactos)\n    elif opcion == \"4\":\n        nombre, apellido, telefono = input(\"Ingrese el nombre, apellido, y nuevo teléfono a actualizar (separados por espacio): \").split()\n        contacto_actualizar = Contacto(nombre, apellido, telefono)\n        contacto_actualizar.actualizar_en_agenda(contactos, telefono)\n    elif opcion == \"5\":\n        nombre, apellido = input(\"Ingrese el nombre y apellido a eliminar: \").split()\n        contacto_eliminar = Contacto(nombre, apellido, \"\")  \n        contacto_eliminar.eliminar_de_agenda(contactos)\n    elif opcion == \"6\":\n        print(\"Saliendo del programa. ¡Vuelve pronto!\")\n        break\n    else:\n        print(\"Opción no válida. Inténtalo de nuevo.\")\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/ThePhobos01.py",
    "content": "# Estructuras de datos\n\nlist = [1, 2, 3, 4] #Lista, mutable y ordenada\nprint(list)\n\nmy_tuple = (1, 2, 3, 4) #Tupla, inmutables\nprint(my_tuple)\n\nmy_set = {1, 2, 3, 4} #Conjunto, mutable, no ordenada\nprint(my_set)\n\nmi_diccionario = {\n    'Nombre': 'Daniel',\n    'Apellido': 'Pineda',\n    'Edad': 24\n} # Diccionario\nprint(mi_diccionario)\n\n# Metodos para modificar listas\n\nlist.append('Phobos')\nprint(list)\n\nlist.remove('Phobos')\nprint(list)\n\nlist[1] = 'Hola'\nprint(list)\n\nlist[1] = 6\n\nlist.sort()\nprint(list)\n\n# Metodos para tuplas\n\nmy_tuple = tuple(sorted(my_tuple))\n\n# Metodos para set\n\nprint(type(my_set))\n\nmy_set.add('Phobos')\nprint(my_set)\n\nmy_set.remove('Phobos')\nprint(my_set)\n\n#Metodos para diccionarios\n\nprint(type(mi_diccionario))\nprint(mi_diccionario['Nombre'])\n\nmi_diccionario['Email'] = 'danielpineda@gmail.com'\nprint(mi_diccionario)\n\nmi_diccionario['Edad'] = 25\nprint(mi_diccionario)\n\ndel mi_diccionario['Apellido']\nprint(mi_diccionario)\n\n'''\nDificultad extra\n'''\n\ndef my_agenda():\n\n    agenda = {}\n\n    def insert_contact():\n        phone = input(\"Introduce el teléfono del contacto: \")\n        if phone.isdigit() and len(phone) > 0 and len(phone) <= 11:\n            agenda[name] = phone\n        else:\n            print(\n                \"Debes introducir un número de teléfono un máximo de 11 dígitos.\")\n\n    while True:\n\n        print(\"\")\n        print(\"1. Buscar contacto\")\n        print(\"2. Insertar contacto\")\n        print(\"3. Actualizar contacto\")\n        print(\"4. Eliminar contacto\")\n        print(\"5. Salir\")\n\n        option = input(\"\\nSelecciona una opción: \")\n\n        match option:\n            case \"1\":\n                name = input(\"Introduce el nombre del contacto a buscar: \")\n                if name in agenda:\n                    print(\n                        f\"El número de teléfono de {name} es {agenda[name]}.\")\n                else:\n                    print(f\"El contacto {name} no existe.\")\n            case \"2\":\n                name = input(\"Introduce el nombre del contacto: \")\n                insert_contact()\n            case \"3\":\n                name = input(\"Introduce el nombre del contacto a actualizar: \")\n                if name in agenda:\n                    insert_contact()\n                else:\n                    print(f\"El contacto {name} no existe.\")\n            case \"4\":\n                name = input(\"Introduce el nombre del contacto a a eliminar: \")\n                if name in agenda:\n                    del agenda[name]\n                else:\n                    print(f\"El contacto {name} no existe.\")\n            case \"5\":\n                print(\"Saliendo de la agenda.\")\n                break\n            case _:\n                print(\"Opción no válida. Elige una opción del 1 al 5.\")\n\n\nmy_agenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/TheReDNooB.py",
    "content": "# Estructuras de control\n\n##Listas\n\nthis_list=[\"cuadernos\", \"lapices\", \"borrador\", \"libros\"]\nprint(this_list,type(this_list))\n\n#insercion\nthis_list.append(\"tijeras\")\nprint(this_list)\n\nthis_list.insert(1, \"colores\")\nprint(this_list)\n\nother_list = [\"bolso\", \"regla\", \"marcadores\"]\nthis_list.extend(other_list)\nprint(this_list)\n\n#borrado\nthis_list.remove(\"bolso\")\nprint(this_list)\n\nthis_list.pop()\nprint(this_list)\n\nthis_list.pop(2)\nprint(this_list)\n\ndel this_list[0]\nprint(this_list)\n\n#actualizacion\nthis_list.insert(1, \"lonchera\")\nprint(this_list)\n\nthis_list[2] = \"goma\"\nprint(this_list)\n\nthis_list[3:5] = [\"lapices\", \"esferos\"]\nprint(this_list)\n\n#orden\nthis_list.sort()\nprint(this_list)\n\nnumber_list = [1,5,7,9,4,2,7,9,4,2]\nnumber_list.sort()\nprint(number_list)\n\nthis_list.sort(reverse=True)\nnumber_list.sort(reverse=True)\nprint(this_list,number_list)\nprint(\"--------------------------------------------------------\\n\")\n\n##Tuplas\n\npartes_pc = (\"CPU\", \"GPU\", \"memoria Ram\", \"Almacenamiento\")\nprint(partes_pc)\n\n#insercion\ntupla_list = list(partes_pc)\ntupla_list.append(\"SSD\")\npartes_pc = tuple(tupla_list)\nprint(partes_pc)\n\n#actualizacion\ntupla_list = list(partes_pc)\ntupla_list[2] = \"RAM\"\npartes_pc = tuple(tupla_list)\nprint(partes_pc)\n\n#borrado\ntupla_list = list(partes_pc)\ntupla_list.pop()\npartes_pc = tuple(tupla_list)\nprint(partes_pc)\n\n#ordenamiento\ntupla_list = list(partes_pc)\ntupla_list.sort()\npartes_pc = tuple(tupla_list)\nprint(partes_pc)\nprint(\"--------------------------------------------------------\\n\")\n\n##Sets\n\nfruits = {\"Orange\", \"Banana\", \"Apple\", \"Strawberry\"}\n\n#insercion\nfruits.add(\"Potato\")\nprint(fruits)\n\n#no se puede ordenar\n\n#borrado\nfruits.remove(\"Strawberry\")\nprint(fruits)\n\nfruits.pop()\nprint(fruits)\nprint(\"--------------------------------------------------------\\n\")\n\n##Diccionarios\ncarro = {\n    \"color\":\"rojo\",\n    \"modelo\":\"tesla\",\n    \"año\":\"2025\"\n}\n\nprint(carro)\n\n#insercion\ncarro[\"puertas\"] = \"4\"\nprint(carro)\n\n#actualizacion\ncarro.update({\"color\":\"azul\"})\nprint(carro)\n\n#borrado\ncarro.pop(\"color\")\nprint(carro)\n\ncarro.popitem()\nprint(carro)\n\n#ordenacion\ncarro = dict(sorted(carro.items()))\nprint(carro)\nprint(\"--------------------------------------------------------\\n\")\n\n\n# Extra\ndef agenda():\n    print(\"Agenda de contactos\")\n    contactos = {}\n\n    #agregar contacto\n    def agregar_contacto():\n        name = input(\"Ingrese el nombre del nuevo contacto: \")\n        phone = input(\"Ingrese el telefono del contacto: \")\n        if phone.isdigit() and len(phone) > 0 and len(phone) <= 11:\n            contactos[name] = phone\n        else:\n            print(\"Debes introducir un número de teléfono un máximo de 11 dígitos.\")\n\n\n    while True:\n        print(\"\"\"\n            Operaciones\n            ------------\n            1. buscar\n            2. agregar\n            3. actualizar\n            4. eliminar\n            5. salir\n        \"\"\")\n        operacion = input(\"Que operacion desea realizar: \")\n\n        match operacion:\n            case \"1\":\n                #buscar contacto\n                name = input(\"ingrese el nombre del contacto: \")\n                if name in contactos:\n                    print(f\"nombre: {name} - telefono: {contactos[name]}\")\n                else:\n                    print(\"el contacto no exite\")\n            case \"2\":\n                agregar_contacto()\n            case \"3\":\n                #actualizar contacto\n                name = input(\"ingrese el nombre del contacto: \")\n                if name in contactos:\n                    agregar_contacto()\n                else:\n                    print(\"el contacto no exite\")\n            case \"4\":\n                #eliminar contacto\n                name = input(\"ingrese el nombre del contacto: \")\n                if name in contactos:\n                    contactos.pop(name)\n                else:\n                    print(\"el contacto no exite\")\n            case \"5\":\n                print(\"adios\")\n                break\n            case _:\n                print(\"Opción no válida. Elige una opción del 1 al 5.\")\n\nagenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Tomu98.py",
    "content": "\"\"\" Reto 03: Estructuras de datos \"\"\"\n\n# Listas\nmy_list: list = [\"Tomu\", \"Pecas\", \"Jere\"]\nprint(my_list)\nmy_list.append(\"Cris\") # Inserción\nprint(my_list)\nmy_list.remove(\"Cris\") # Eliminación\nprint(my_list)\nprint(my_list[1]) # Acceso\nmy_list[1] = \"Pequitas\" # Actualización\nprint(my_list)\nmy_list.sort() # Ordenación\nprint(my_list)\n\n# Tuplas\nmy_tuple: tuple = (\"Abel\", \"Tomu\", \"@Tomu98\", \"25\")\nprint(my_tuple)\nprint(my_tuple[1]) # Acceso\nprint(my_tuple[2])\nprint(my_tuple[3])\nmy_tuple = tuple(sorted(my_tuple)) # Ordenación\nprint(my_tuple)\nprint(type(my_tuple))\n\n# Sets\nmy_set: set = {\"Abel\", \"Tomu\", \"@Tomu98\", \"25\"}\nprint(my_set)\nmy_set.add(\"tomu@dev.py\") # Inserción\nmy_set.add(\"tomu@dev.py\")\nprint(my_set)\nmy_set.remove(\"Abel\") # Eliminación\nprint(my_set)\nmy_set = set(sorted(my_set)) # No se puede ordenar\nprint(my_set)\nprint(type(my_set))\n\n# Diccionarios\nmy_dict: dict = {\"name\":\"Abel\",\n                 \"alias\":\"Tomu\",\n                 \"age\":\"25\"\n}\nprint(my_dict)\nmy_dict[\"email\"] = \"tomu@dev.py\" # Inserción\nprint(my_dict)\ndel my_dict[\"email\"] # Eliminación\nprint(my_dict)\nprint(my_dict[\"alias\"]) # Acceso\nmy_dict[\"age\"] = \"26\" # Actualización\nprint(my_dict)\nmy_dict = dict(sorted(my_dict.items())) # Ordenación\nprint(my_dict)\nprint(type(my_dict))\n\n\n\n\"\"\" Reto extra \"\"\"\n\ndef my_agenda():\n\n    agenda = {}\n\n    def insert_contact():\n        phone = input(\"Introduce el teléfono del contacto: \")\n        if phone.isdigit() and len(phone) > 0 and len(phone) <= 11:\n            agenda[name] = phone\n        else:\n            print(\"Debes introducir un número de teléfono un máximo de 11 digitos\")\n\n    while True:\n        print(\"\")\n        print(\"1. Buscar contacto\")\n        print(\"2. Insertar contacto\")\n        print(\"3. Actualizar contacto\")\n        print(\"4. Eliminar contacto\")\n        print(\"5. Salir\")\n\n        option = input(\"\\nSelecciona una opción: \")\n\n        match option:\n            case \"1\":\n                name = input(\"Introduce el nombre del contacto a buscar: \")\n                if name in agenda:\n                    print(f\"El número de teléfono de {name} es {agenda[name]}.\")\n                else:\n                    print(f\"El contacto '{name}' no existe\")\n            case \"2\":\n                name = input(\"Introduzca el nombre del contacto: \")\n                insert_contact()\n            case \"3\":\n                name = input(\"Introduce el nombre del contacto a actualizar: \")\n                if name in agenda:\n                    insert_contact()\n                else:\n                    print(f\"El contacto '{name}' no existe\")\n            case \"4\":\n                name = input(\"Introduce el nombre del contacto a eliminar: \")\n                if name in agenda:\n                    del agenda[name]\n                else:\n                    print(f\"El contacto '{name}' no existe\")\n            case \"5\":\n                print(\"Saliendo de la agenda.\")\n                break\n            case _:\n                print(\"Opción no válida. Elige una opción del 1 al 5.\")\n\nmy_agenda()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/TroyNebula.py",
    "content": "from array import array\r\nfrom collections import deque\r\n'''\r\n * EJERCICIO:\r\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\r\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación\r\n'''\r\n\r\n# Listas ----------------------------------------\r\n# Colección ordenada y modificable de elementos. Puedes acceder a los elementos de una lista mediante índices.\r\n\r\nmi_lista= [\"Troy\", \"Brais\", \"Moure\"]\r\nmi_lista.append (\"Dev\") # Inserción al final de la lista\r\nprint (mi_lista[3])  # Output Dev\r\nmi_lista.remove (\"Brais\") # Debo decirle cual sino retorna ValueError\r\nprint(mi_lista)\r\nmi_lista.pop(1) # Elimina la posición 1 que es Moure, si no le digo el índicie borra el último\r\nprint(mi_lista)\r\nmi_lista.insert (0, \"Nebula\") # Inserción en una posición concreta\r\nprint(mi_lista)\r\nveces= mi_lista.count(\"Troy\") # cuenta las veces que sale la palabra Troy\r\nprint (veces, \"vez / veces\")\r\nmi_lista.sort()  # Ordenación\r\nprint(mi_lista)\r\nmi_lista.reverse()  # invierte la lista\r\nprint(mi_lista)\r\nmi_lista_copiada= mi_lista.copy() # hago una copia\r\nmi_lista.clear() # La limpio\r\nprint(mi_lista)\r\nprint(mi_lista_copiada)\r\nprint(type(mi_lista))\r\n\r\n# Tuplas ----------------------------------------\r\n# Inmutable, no se puede modificar una vez creada\r\nmi_tupla= (20,10,30)\r\nprint(mi_tupla[1])  # Acceso\r\nmi_tupla = tuple(sorted(mi_tupla))  # Ordenación\r\nprint(mi_tupla)\r\nprint(type(mi_tupla))\r\n\r\n# Conjunto o set ----------------------------------------\r\n# Colección no ordenada de elementos únicos. Para verificación de pertenencia y eliminación de entradas duplicadas. No se puede ordenar.\r\nconjunto = {1, 2, 3, 3, 4, 5}\r\nconjunto.add(6)  # Inserción\r\nprint(conjunto)\r\nconjunto.remove(6)  # Eliminación\r\nprint(conjunto)\r\nprint(type(conjunto))\r\n\r\n# Diccionario ----------------------------------------\r\n# Colección no ordenada clave-valor. Se accede a los valores por las claves.\r\nmi_dict = {\"clave\": \"valor\", \r\n           \"nombre\": \"Troy\", \r\n           \"nick\": \"Nebula\",\r\n           \"lista\": mi_lista,\r\n           \"lista2\": [1,2,3]\r\n           }\r\nprint(mi_dict)\r\nmi_dict[\"email\"] = \"troynebula@gmail.com\"  # Inserción\r\nprint(mi_dict)\r\ndel mi_dict[\"clave\"]  # Eliminación\r\nprint(mi_dict)\r\nprint(mi_dict[\"nombre\"])  # Acceso\r\nmi_dict[\"nick\"] = \"Troy Nebula\"  # Actualización\r\nprint(mi_dict)\r\nmi_dict = dict(sorted(mi_dict.items())) # Ordenación, pero me la da en una lista de tupla ordenadas.\r\n# tengo que volver a pasarlo a diccionario usando dict pero en la misma frase como he puesto\r\nprint(mi_dict)\r\nprint(type(mi_dict))\r\n\r\n# Colas y Pilas ----------------------------------------\r\n\r\npila = []\r\npila.append(10) # Inserción\r\npila.append(20)\r\npila.append(30)\r\nprint (\"pila:\", pila)\r\n\r\n# Eliminar elementos de la pila (pop) El último en entrar es el primero en salir\r\nelemento = pila.pop()  # Elimina y retorna el último elemento agregado (30)\r\nprint(elemento)  # Output: 30\r\n\r\nprint(pila)  # Output: [10, 20]\r\n\r\n# Deque  ----------------------------------------\r\n# (double-ended queue)  Mucho más rápido que colas y pilas\r\n# Lista doblemente finalizada, fácil para insertar/eliminar en principios o finales\r\n\r\nmi_deque = deque()\r\n\r\nmi_deque.append(10)\r\nmi_deque.append(20)\r\nmi_deque.append(30)\r\nprint (mi_deque)\r\n\r\nmi_deque.appendleft(5)  #inserta al principio\r\nprint (mi_deque)\r\n\r\nprint(mi_deque[1]) # la posicioon 1 es el 10, la 0 es el 5 que acabamos de añadir\r\n\r\nmi_deque.pop() #elimina el último\r\nmi_deque.popleft() #elimina el primero\r\n\r\nprint(mi_deque) \r\n\r\n# Arrays ----------------------------------------\r\n# Como las listas, pero más eficientes para almacenar elementos del mismo tipo. \r\n# Es necesaria la importación del módulo array.\r\n\r\nmi_array = array('i', [1, 2, 3])\r\n\r\n'''\r\nDIFICULTAD EXTRA (opcional):\r\n * Crea una agenda de contactos por terminal.\r\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\r\n * - Cada contacto debe tener un nombre y un número de teléfono.\r\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\r\n *   los datos necesarios para llevarla a cabo.\r\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\r\n *   (o el número de dígitos que quieras)\r\n * - También se debe proponer una operación de finalización del programa.\r\n '''\r\n\r\n# Podría hacerlo con if cada opcion pero hay una nueva que es match\r\n# Uso match porque solo reviso el valor de una variable (opcion)\r\n# Necesito un bucle para que se ejecute mientras no le de a salir, un while\r\n    \r\ndef agenda():\r\n\r\n    dict_agenda = {}  # Creo mi diccionario agenda vacío\r\n\r\n    def insertar_contacto(nombre):  # No me funcionaba ni guardaba porque no pasaba la variable nombre en esta función y no estaba definida\r\n        telef = input(\"Introduce el teléfono del contacto:\")\r\n        if telef.isdigit() and len(telef) ==13:  # podría poner len(telef) >0 and len(telef) <=13\r\n            dict_agenda[nombre] = telef\r\n            print (f\"Has introducido, Nombre: {nombre} y teléfono: {telef}\")\r\n            print (dict_agenda) \r\n        else:\r\n            print (\"Introduce un número de teléfono válido. Ejemplo 0034666123123\")\r\n\r\n    navegando= True  # Podría poner solamente while True y luego un break donde fuese a salir\r\n    while navegando:  # Mientras sea True se sigue repiendo la agenda son más lineas pero por el momento lo veo más claro\r\n\r\n        opcion = input (\"---------------------\\n1. Introduce contacto\\n2. Busca contacto\\n3. Actualiza contacto\\n4. Elimina contacto\\n5. Salir\\n---------------------\\nIntroduce una opción y pulsa Enter:\")\r\n\r\n        match opcion:  # un switch\r\n            case \"1\":\r\n                nombre= input(\"Introduce el nombre del contacto:\")\r\n                insertar_contacto(nombre)  # No olvidar pasar el  nombre\r\n                \r\n            case \"2\":\r\n                nombre= input(\"Introduce el nombre del contacto a buscar:\")\r\n                if nombre in dict_agenda:\r\n                    print (f\"El número te teléfono del contacto: {nombre} es {dict_agenda[nombre]}\")\r\n                else:\r\n                    print (f\"El nombre introducido {nombre} no existe, prueba de nuevo\")\r\n            case \"3\":\r\n                nombre = input(\"Introduce el nombre del contacto a actualizar:\")\r\n                if nombre in dict_agenda:\r\n                    nuevo_nombre = input(\"Introduce el nuevo nombre del contacto:\")\r\n                    if nuevo_nombre != nombre:\r\n                        del dict_agenda[nombre]\r\n                        insertar_contacto(nuevo_nombre)\r\n                    else:\r\n                        print(\"El nuevo nombre debe ser diferente al nombre original.\")\r\n                else:\r\n                    print(f\"El nombre introducido {nombre} no existe, prueba de nuevo.\")\r\n            case \"4\":\r\n                nombre= input(\"Introduce el nombre del contacto a exterminar:\")\r\n                if nombre in dict_agenda:\r\n                    del dict_agenda[nombre]\r\n                    print (f\"{nombre} Exterminate!\")\r\n                else:\r\n                    print (f\"El nombre introducido {nombre} no existe, prueba de nuevo\")\r\n            case \"5\":\r\n                print (\"¡Gracias por usar nuestro sistema de agenda!\")\r\n                navegando = False\r\n            case _: # Si escribre una opción distinta a las propuestas\r\n                print (\"No reconocido. Escribe del 1 al 5, ¡gracias!\")\r\n\r\nagenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Txuky.py",
    "content": "### estructuras ###\n\n## Listas\n\n# Crear una lista\nlist_a =list()\nlist_b =[]\n\nprint(type(list_a))\nprint(type(list_b))\n# datos de una lista\nlist_b = ['txuky', 'Francesc', 'More', 56, 169.5, True,56]\n\n#acceso a los datos\nprint('=*' * 30)\n\nprint(list_b)\nprint(list_b[0])\nprint(list_b.index('Francesc'))\nprint(list_b.count(56))\nlist_b.pop()\n\n# insertar, añadir y eliminar datos de la lista\nprint('=*' * 30)\n\nlist_b.append(55)\nlist_b.insert(3, 'Verde')\nprint(list_b)\nlist_b[3]='Amarillo'\nprint(list_b)\nlist_b.remove('Amarillo')\nprint(list_b)\nlist_b[0]='Azul'\nprint(list_b)\ndel list_b[0]\nprint(list_b)\n\n\n# assignar datos de una lista a variables \nprint('=*' * 30)\n\n# segun orden de lista\nname, surname, age, weight, subscribed, age_2 = list_b\n\nif subscribed == True:\n    print(f'Me llamo {name}{surname} tengo {age} y mido {weight} y estoy subscrito ')\nelse:\n    print(f'Me llamo {name}{surname} tengo {age} y mido {weight} y no estoy subscrito ')\n\n# segun indice\nage, weight, surname, name, age_2, subscribed = list_b[2], list_b[3], list_b[1], list_b[0], list_b[5], list_b[4]\n\nif subscribed == True:\n    print(f'Me llamo {name}{surname} tengo {age} y mido {weight} y estoy subscrito ')\nelse:\n    print(f'Me llamo {name}{surname} tengo {age} y mido {weight} y no estoy subscrito ')\n\n# manejo de las listas\nprint('=*' * 30)\n\nlist_a = list_b.copy()\nprint(list_a)\n\nlist_a.reverse()\nprint(list_a)\n\nlist_a.pop(-1)\nlist_a.pop(-1)\nlist_a.pop(1)\nprint(list_a)\nlist_a.sort() #solo funciona si los elementos son del mimoo typo o num o str\nprint(list_a)\n\nlist_a.clear()\nprint(list_a)\n\n## Tuplas\n\n\n# Crear una tuple\ntuple_a =tuple()\ntuple_b =()\n\nprint(type(tuple_a))\nprint(type(tuple_b))\n# datos de una tuple\ntuple_b = ('txuky', 'Francesc', 'More', 56, 169.5, True,56)\nprint(type(tuple_b))\n\n#acceso a los datos\nprint('=*' * 30)\n\nprint(tuple_b)\nprint(tuple_b[0])\nprint(tuple_b.index('Francesc'))\nprint(tuple_b.count(56))\n# tuple_b.pop()\n\n# insertar, añadir y eliminar datos de la lista\nprint('=*' * 30)\n\n#tuple_b.append(55)\n#tuple_b.insert(3, 'Verde')\n#tuple_b[3]='Amarillo'\n#tuple_b.remove('Amarillo')\n#tuple_b[0]='Azul'\n#del tuple_b[0]\nprint(tuple_b)\nprint('Las tuples sin INMUTABLES')\n\n# assignar datos de una lista a variables \nprint('=*' * 30)\n\n# desempaquetado de tupla\n\nalias, name, surname, age, weight, subscribed, age_2 = tuple_b\n\nif subscribed == True:\n    print(f'Me llamo {name}{surname} tengo {age} y mido {weight} my alias es : {alias} y estoy subscrito ')\nelse:\n    print(f'Me llamo {name}{surname} tengo {age} y mido {weight} my alias es : {alias} y no estoy subscrito ')\n\n''' # segun indice no funciona\nage, weight, surname, name, alias, age_2, subscribed = tuple_b[3], tuple_b[4], tuple_b[2], tuple_b[1], alias[0] tuple_b[6], tuple_b[5]\n'''\n# manejo de las listas\nprint('=*' * 30)\n\ntuple_a = tuple_b\nprint(tuple_a)\nprint(type(tuple_a))\n\ntuple_c = tuple_a, (1, 2, 3, 4)\nprint(tuple_c)\nprint(type(tuple_c))\nelem_tupla = len(tuple_c)\nprint(f'Cuantos elementos tiene tuple_c: {elem_tupla} ')\nprint('Elemento 0 :',end=\" \" ) \nprint(tuple_c[0])\nprint('Elemento 1 ', tuple_c[1])\nprint('Cada uno de los dos elemntos de la tuple es una lista, pero la tuple solo tiene 2 elemntos')\n\n# como son inmutables no funciona nada que las pueda modificar tipo .sort .reverse ,clear\n\n# Sets \nprint('=*' * 30)\n\ncelta_staff = set()\ncelta_gamers = {'Coke', 'Aidoo', 'Alfon', 'Javi','Javi', 'Manu', 'Martin', 'Hugo', 'Alfon' }\nprint(type(celta_staff))\nprint(type(celta_gamers))\n\nprint(celta_gamers)\n#devuelve los elementos no repetidos\n#los sets sobre todo se indican par verificacion de permanencia y eliminacion de duplicados\n\ncelta_staff = {'Claudio', 'Nando', 'Alejandro', 'Jesus', 'Nando'}\n\npersonaje = 'Nando'\n\nif personaje in celta_gamers:\n    print ('Coke es jugador del Celta')\nelif personaje in celta_staff:\n    print ('Coke es parte del staff del Celta')\nelse:\n    print('Coke no pertenece al Celta')\n\nprint('=*' * 30)\n\nnums_a = {1, 2, 4 ,5 ,6 ,7}\nnums_b = {3, 5, 5, 7, 8, 4, 22, 9, 0}\nprint(nums_a)\nprint(nums_b)\n\nprint(nums_a - nums_b)\nprint(nums_a & nums_b)\nprint(nums_a | nums_b)\nprint(nums_a ^ nums_b)\n\n# podemos eliminar elementos o limpiar el set y añadir nuevos\n\ncelta_gamers.remove('Alfon')\nprint(celta_gamers)\n\ncelta_staff.clear()\nprint(len(celta_staff))\n\ncelta_staff.add('Alfon')\nprint(len(celta_staff))\nprint(celta_staff)\ncelta_staff.add('Claudio')\nprint(len(celta_staff))\nprint(celta_staff)\n\n\n# diccionarios \nprint('=*' * 30)\n\n# construccion\ncodig_cli = {'Francesc':'c125', 'Ricardo':'c135', 'Carmen':'c100'}\nalias_cli = dict(c125='Txuky', c135 = 'King', c100 = 'Mqueen')\n#alias_cli = dict(one='Txuky', two = 'King', three = 'Mqueen')\n\nprint(type(codig_cli))\nprint(type(alias_cli))\n\nprint(list(codig_cli))\nprint(len(codig_cli))\nprint(alias_cli['c125'])\nprint('Ricardo' in codig_cli)\nprint('King' in alias_cli)\nprint('c135' in alias_cli)\n\ncodig_cli['Pedro'] = 'c180' #inserta una nueva key con su valor\nprint(codig_cli)\n\ncodig_cli = dict(sorted(codig_cli.items()))\nprint(codig_cli)\n\n# podemos operar con los diccionarios \nprint('=*' * 30)\n\nprint(alias_cli)\nalias_cli['c100'] = 'Toga' # Asigna el valor [key]\nprint(alias_cli['c100'])\n\ndel alias_cli['c135'] # Elimina [key]\nprint(alias_cli)\n\nalias_cli_2 = alias_cli.copy()\nprint(alias_cli_2.items())\nprint(alias_cli_2.keys())\nprint(alias_cli_2.values())\n\nalias_cli_2.setdefault('c135', 'NeTeam')\nprint(alias_cli_2)\n\nlist_contc = ['Tel', 'Email', 'Adres' ]\ncontact_cli = dict.fromkeys(list_contc)\nprint(contact_cli)\n\n\n### Extra\nprint('=*' * 30)\n\ndef agenda_cont():\n    \n    agenda = {}\n\n    def ins_contac():\n        telef = input('Introducir telefono: ')\n        if telef.isdigit() and len(telef) <= 9:\n            agenda[nom] = telef\n        else:\n            print('El telefono no puede tener  mas de 9 igitos')\n\n    while True:\n        print('')\n        print('Menu Opciones')\n        print('1. Buscar contacto')\n        print('2. Insertar contacto')\n        print('3. Actualizar contacto')\n        print('4. Eliminar contacto')\n        print('5. Salir')\n\n        option = input('\\nSeleccione una opcion: ')\n\n        match option:\n            case '1':\n                nom = input('Introduce el nombre del contacto a buscar: ')\n                if nom in agenda:\n                    print(f'El telefono de {nom} es {agenda[nom]}.')\n                else:\n                    print(f'El contacto {nom} no existe.')\n            case '2':\n                nom = input('Introduce el nombre del contacto: ')\n                ins_contac()\n            case '3':\n                nom = input('introduce nombre del contacto a actulizar: ')\n                if nom in agenda:\n                    ins_contac()\n                else:\n                    print(f'El contacto {nom} no existe debes crearlo.')\n            case '4':\n                nom = input('Introduce el nombre del contacto a borrar: ')\n                if nom in agenda:\n                    del agenda[nom]\n                else:\n                    print(f'El contacto {nom} no existe no se puede borrar.')\n            case '5':\n                print('Hasta pronto')\n                break\n            case _:\n                print('Opcion no valida elije una opcion entre el 1 y el 5')\n\nagenda_cont()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/VictorRivero1204.py",
    "content": "# Listas\n\nmy_list: list= [\"Victor\", \"Jose\", \"Maria\"]\nprint (my_list)\nmy_list.append(\"Daysi\") #Inserción\nmy_list.append(\"Daysi\")\nprint (my_list)\nmy_list.remove(\"Victor\") # Eliminacion\nprint (my_list)\nprint(my_list[1]) #Acceso\nmy_list[1] = \"Victor\" #Actualizacion\nprint (my_list)\nmy_list.sort() #Ordenacion\nprint (my_list)\n\n# Tuplas\nmy_tuple: tuple = (\"Victor\", \"VictorRivero1204\", \"23\")\nprint(my_tuple[1]) #Acceso\nmy_tuple = tuple(sorted(my_tuple)) #Ordenacion\nprint(my_tuple)\n\n# Sets\n\nmy_set: set = {\"Victor\", \"VictorRivero1204\", \"23\"}\nprint(my_set)\nmy_set.add(\"Victor.rivero1204@gmail.com\") #Insecion\nmy_set.add(\"Victor.rivero1204@gmail.com\")\nprint(my_set)\nmy_set.remove(\"Victor\") #Eliminacion\nprint(my_set)\nmy_set = sorted(my_set) #No se puede ordenar\nprint(my_set)\nprint(type(my_set))\n\n# Diccionario\n\nmy_dict: dict = {\n    \"name\":\"Victor\", \n    \"username\":\"VictorRivero1204\", \n    \"correo\":\"victor.rivero1204@gmail.com\", \n    \"edad\":23\n}\nprint(my_dict)\nmy_dict[\"alias\"] = \"Vitico\" #insercion\ndel my_dict[\"username\"] #Eliminacion\nprint(my_dict)\nprint(my_dict[\"name\"]) #Acceso\nmy_dict[\"edad\"] = 24 #Actualizacion\nprint(my_dict)\nmy_dict = dict(sorted(my_dict.items())) #Ordenacion\nprint(my_dict)\nprint(type(my_dict))\n\n\"\"\"\n EXTRA\n\"\"\"\n\ndef my_agenda():\n\n    agenda = {}\n\n    def insert_contact():\n        phone = input(\"Introduce el numero del contacto: \")\n        if phone.isdigit() and len(phone) > 0 and len(phone) <=11:\n                agenda[name] = phone\n        else:\n            print(\"\" \\\n            \"El numero de telefono no puede superar los 11 digitos.\")\n\n    while True:\n\n        print(\"\")\n        print(\"1. Buscar contacto\")\n        print(\"2. insertar contacto\")\n        print(\"3. actualizar contacto\")\n        print(\"4. eliminar contacto\")\n        print(\"5. salir\")\n\n        option = input(\"\\nSelecciona una opcion: \")\n    \n        match option:\n            case \"1\":\n                name = input(\"Introduce el nombre del contacto a buscar: \")\n                if name in agenda:\n                    print(f\"el numero de telefono de contacto {name} es: {agenda[name]}\")\n                else:\n                    print(f\"El contacto {name} no existe. \")\n            case \"2\":\n                name = input(\"Introduce el nombre del contacto: \")\n                insert_contact()\n            case \"3\":\n                name = input (\"Introduce el nombre del contacto a actualizar: \")\n                if name in agenda:\n                    insert_contact()\n                else:\n                    print(f\"El contacto {name} no existe: \")\n            case \"4\":\n                name = input(\"Introduce el nombre del contacto a eliminar: \")\n                if name in agenda:\n                    del agenda[name]\n                else:\n                    print(f\"El contacto no existe: \")\n                pass\n            case \"5\":\n                print(\"Saliendo de la agenda\")\n                break \n            case _:\n                print(\"Opcion no valida, elija una valida\")\n\nmy_agenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/VictorZm0h.py",
    "content": "# #03 ESTRUCTURAS DE DATOS\r\n#### Dificultad: Media | Publicación: 15/01/24 | Corrección: 22/01/24\r\n'''\r\n/*\r\n * EJERCICIO:\r\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\r\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\r\n *\r\n * DIFICULTAD EXTRA (opcional):\r\n * Crea una agenda de contactos por terminal.\r\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\r\n * - Cada contacto debe tener un nombre y un número de teléfono.\r\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\r\n *   los datos necesarios para llevarla a cabo.\r\n * - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\r\n *   (o el número de dígitos que quieras)\r\n * - También se debe proponer una operación de finalización del programa.\r\n */\r\n```\r\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\r\n\r\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\r\n\r\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\r\n'''\r\n\r\n# Estructuras de datos en Python\r\n# Listas\r\nmi_lista = [3, 1, 4, 1, 5]\r\nprint(mi_lista)\r\nmi_lista.append(9)  # Inserción\r\nprint(\"Inserción: \" + str(mi_lista))\r\nmi_lista.insert(1, 2)  # Inserción en posición concreta\r\nprint(\"Inserción en posición concreta: \" + str(mi_lista))\r\nmi_lista.remove(1)  # Borrado\r\nprint(\"Borrado: \" + str(mi_lista))\r\nmi_lista2 = [2,4,6,8,4,10,4,12]\r\nwhile 4 in mi_lista2:\r\n    mi_lista2.remove(4)\r\nprint(\"Borrado de todas las ocurrencias\" + str(mi_lista2))  # Borrado de todas las ocurrencias\r\nmi_lista[0:2] = 10, 11    # Actualización utilizando slicing\r\nprint(\"Actualización utilizando slicing: \" + str(mi_lista))\r\nmi_lista.sort()  # Ordenación\r\nprint(\"Orden ascendente: \" + str(mi_lista))\r\nmi_lista.sort(reverse=True)  # Ordenación inversa\r\nprint(\"Orden descendente: \" + str(mi_lista))\r\n\r\n# Tuplas\r\nmi_tupla = (3, 1, 4, 1, 5)\r\nprint(mi_tupla)\r\n\r\n# Conjuntos\r\nmi_conjunto = {3, 1, 4, 1, 5}\r\nprint(mi_conjunto)\r\nmi_conjunto.add(9)  # Inserción\r\nprint(\"Inserción: \" + str(mi_conjunto))\r\nmi_conjunto.discard(1)  # Borrado\r\nprint(\"Borrado: \" + str(mi_conjunto))\r\n\r\n# Diccionarios\r\nmi_diccionario = {'a': 1, 'b': 2, 'c': 3}\r\nprint(mi_diccionario)\r\nmi_diccionario['d'] = 5  # Inserción\r\nprint(\"Inserción: \" + str(mi_diccionario))\r\nmi_diccionario['d'] = 4  # Actualización\r\nprint(\"Actualización: \" + str(mi_diccionario))\r\ndel mi_diccionario['a']  # Borrado\r\nprint(\"Borrado: \" + str(mi_diccionario))\r\nmi_diccionario2 = {'h': 7, 'u': 10, 'e': 6, 'v': 0, 'i': 9, 't': 8, 'o': 5, 'r': 4}\r\nmi_diccionario2 = dict(sorted(mi_diccionario2.items()))  # Ordenación por clave\r\nprint(\"Ordenación por clave: \" + str(mi_diccionario2))\r\nmi_diccionario2 = dict(sorted(mi_diccionario2.items(), key=lambda item: item[1]))  # Ordenación por valor\r\nprint(\"Ordenación por valor: \" + str(mi_diccionario2))\r\n\r\n# Dificultad extra: Agenda de contactos\r\nagenda={}\r\ndef mostrar_menu():\r\n    print(\"\\n--- Agenda de Contactos ---\")\r\n    print(\"1. Añadir contacto\")\r\n    print(\"2. Buscar contacto\")\r\n    print(\"3. Actualizar contacto\")\r\n    print(\"4. Eliminar contacto\")\r\n    print(\"5. Mostrar todos los contactos\")\r\n    print(\"6. Salir\")\r\ndef es_numero_valido(numero):\r\n    return numero.isdigit() and len(numero) <= 11\r\nwhile True:\r\n    mostrar_menu()\r\n    opcion=input(\"Seleccione una opción (1-6): \")\r\n    if opcion==\"1\":\r\n        nombre=input(\"Ingrese el nombre del contacto: \")\r\n        numero=input(\"Ingrese el número de teléfono: \")\r\n        if es_numero_valido(numero):\r\n            agenda[nombre]=numero\r\n            print(f\"Se ha agregado el contacto {nombre} con el número: {numero}.\")\r\n        else:\r\n            print(\"Número de teléfono no válido.\")\r\n    elif opcion==\"2\":\r\n        nombre=input(\"Ingrese el nombre del contacto a buscar: \")\r\n        if nombre in agenda:\r\n            print(f\"Contacto encontrado: {nombre} - {agenda[nombre]}\")\r\n        else:\r\n            print(\"Contacto no encontrado.\")\r\n    elif opcion==\"3\":\r\n        nombre=input(\"Ingrese el nombre del contacto a actualizar: \")\r\n        if nombre in agenda:\r\n            numero=input(\"Ingrese el nuevo número de teléfono: \")\r\n            if es_numero_valido(numero):\r\n                agenda[nombre]=numero\r\n                print(f\"El numero de contacto de {nombre} se ha actualizado.\")\r\n            else:\r\n                print(\"Número de teléfono no válido.\")\r\n        else:\r\n            print(\"Contacto no encontrado.\")\r\n    elif opcion==\"4\":\r\n        nombre=input(\"Ingrese el nombre del contacto a eliminar: \")\r\n        if nombre in agenda:\r\n            del agenda[nombre]\r\n            print(f\"Contacto {nombre} eliminado.\")\r\n        else:\r\n            print(\"Contacto no encontrado.\")\r\n    elif opcion==\"5\":\r\n        if agenda:\r\n            print(\"\\n--- Contactos en la Agenda ---\")\r\n            for nombre, numero in agenda.items():\r\n                print(f\"{nombre}: {numero}\")\r\n        else:\r\n            print(\"La agenda está vacía.\")\r\n    elif opcion==\"6\":\r\n        print(\"Saliendo de la agenda. ¡Hasta luego!\")\r\n        break\r\n    else:\r\n        print(\"Opción no válida. Por favor, seleccione una opción del 1 al 6.\")\r\n\r\n\r\n\r\n        \r\n\r\n\r\n\r\n\r\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Yani-Git.py",
    "content": "#Listas: estructura que sirve para guardar varios elementos de forma ordenada\n\nmy_list: list = [\"Yani\", \"Inés\", \"Pedro\", \"Tomás\"]\n\nprint (my_list)\n\nmy_list.append (\"Castor\") # inserción \nmy_list.append (\"Castor\")\nprint (my_list)\n\nmy_list.remove (\"Yani\") # eliminación\n\nprint (my_list)\n\n\"\"\"\npara poder actualizar un elemento de la lista primero hay que acceder al elemento \nhay que acceder por la posición que ocupa el elemmento\n\"\"\"\nmy_list[1]\n\nprint (my_list[1]) #acceso \n\nmy_list[1] = \"Patricia\" # si quisiera actualizar a Pedro tendría que acceder a la lista y a su posición darle un nuevo valor por ej: Patricia \n \nprint (my_list) \n\nmy_list.sort ()  #oredenación  # por defecto sigue un criterio designado por el sistema \n\nprint (my_list)  #sort:  ordena alfabeticamente \n\nprint (type(my_list))\n\n# Tuplas: estructuras donde podemos guardar mas de un dato\n#las tuplas son inmutables, como están creadas quedarán, la iliminación, inserción, actualización etc. no existirá en la tupla\n\nmy_tuple: tuple = (\"Yani\", \"Barr\", \"Yanines\", \"47\")\n\nprint (my_tuple[1]) #lo único que podría hacer con la tupla son operaciones de acceso\n\nprint (my_tuple[3])\n\nmy_tuple = tuple (sorted (my_tuple))  # se puede hacer la ordenación con cierto truco \n\nprint (my_tuple)\n\nprint (type(my_tuple))\n\n#Sets:sirven para evitar duplicados,  son otro tipo de estructuras, es desordenado, no podemos confiar en la posición que vaya a agregar el elemento, los set son ideales para guardar muchos datos y recorrerlos pero NO para buscar datos \n\nmy_set = {\"Yani\", \"Barr\", \"Yanines\", \"47\"}\n\nprint (my_set)\n\nmy_set.add (\"yanines2025@gmail.com\") #inserción \n\nmy_set.add (\"yanines2025@gmail.com\") #no se pueden agregar duplicados, esta estructura observa que el elemento está insertado y no agrega el duplicado  \n\nprint (my_set)\n\nmy_set.remove(\"Yanines\") #eliminación \n\nprint (my_set)\n\nmy_set  = set (sorted (my_set)) #el set no se puede ordenar\n\nprint (my_set)\n\nprint (type(my_set))\n\n#diccionario: hay que agregarle una clave \n\nmy_dict: dict = {\n    \"name\":\"Yani\", \n    \"surname\": \"Barr\", \n    \"alias\": \"Yanines\", \n    \"age\": \"47\"\n}\n\nmy_dict [\"email\"] = \"yanines2025@gmail.com\"  #inserción \nprint (my_dict)\n\ndel my_dict [\"surname\"] #eliminación \n\nprint (my_dict)\n\nprint (my_dict[\"name\"]) #acceso \n\nmy_dict [\"age\"] = \"48\" #actualización \n\nmy_dict = dict (sorted (my_dict.items ())) # ordenación \n\nprint (my_dict)\n\nprint (type(my_dict))\n\n\"\"\"\nExtra \n\n\"\"\"\n\ndef my_agenda ():\n\n    agenda = {}\n\n    def insert_contact(): \n            phone = input (\"Introduce el numero del contacto : \")\n            if phone.isdigit () and len(phone) >0 and len(phone) <= 8:\n                        agenda [name] = phone\n            else: \n                print (\n                        \"Debes introducir un  número de teléfono con menos de 11 dígitos.\")\n\n    while True: \n\n\n        print (\"\")\n        print (\"1. Buscar contacto\")\n        print (\"2. Insertar contacto\")\n        print (\"3. actualizar contacto\")\n        print (\"4. eliminar contacto\")\n        print (\"5. salir\")\n\n        option = input (\"\\nSelecciona una opción: \")\n\n\n        match option:\n\n            case \"1\":\n\n                name = input (\"Introduce el nombre del contacto a buscar: \") # Buscar\n                if name in agenda:\n                    print (f\"El número de teléfono {name} es {agenda [name]}.\")\n                else:\n                    print (f\"El contacto y el nombre {name} no se ha encontrado. \")\n            \n            case \"2\":\n\n                name = input (\"Introduce el nombre del contacto : \")  # Insertar \n                #phone = input (\"Introduce el numero del contacto : \")\n\n                insert_contact()\n           \n            case \"3\":\n\n                name = input (\"Introduce el nombre del contacto a actualizar: \") # Actualizar \n                if name in agenda:\n                    insert_contact()\n                else:\n                    print (f\"el contacto {name} no existe.\")    \n           \n            case \"4\":\n\n                name = input (\"Introduce el nombre del contacto a eliminar: \")   # Eliminar\n                if name in agenda:\n                    del agenda [name]\n                else: \n                    print (f\"El contacto {name} no existe.\")\n          \n            case \"5\":\n                    \n                    print (\"Saliendo de la agenda.\")\n                    break\n           \n            case _:\n\n                print (\"Opción no válida. Elige una opción del 1 al 5.\")\n\n  \n  \n  \n    \"\"\"\n\n    if option == \"1\":\n        elif option == \"2\": \n            \n    \"\"\"\n\nmy_agenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/YgriegaSB.py",
    "content": "mi_lista = [1, 2, 3, 4, 5]\nmi_tupla = (1, 2, 3, 4, 5)\nmi_diccionario = {'a': 1, 'b': 2, 'c': 3}\nmi_conjunto = {1, 2, 3, 4, 5}\nmi_cadena = \"Hola, mundo!\"\nmi_entero = 42\nmi_flotante = 3.14\nmi_booleano = True\n\n\n\"\"\"\n\n# PROGRAM EXERCISE\n\n\"\"\"\n\ncontacts = {}\ncontacts.update({'Nicolas': 96697572})\ncontacts.update({'Nicole': 2312312312})\ncontacts.update({'Francisca': 112223334})\n\ndef check_input(celular):\n    if isinstance(celular, str) and len(str(celular)) <= 11:\n        return True\n    else:\n        return False\n\ndef search_contact():\n    entry = input(\"\\n Escribe el nombre del contacto o ALL para ver todos los contactos => \")\n    if entry == 'all' or entry == 'ALL':\n        for name, celular in contacts.items():\n            print (\"\\nNombre: \", name)\n            print (\"Celular: \", celular)\n    elif entry.lower() in (key.lower() for key in contacts):\n        entry = entry[0].upper() + entry[1:]\n        print (\"\\nNombre: \" , entry)\n        print (\"Celular: \" , contacts.get(entry))\n    else:\n        print (\"\\n!!!!!!!!!!!No se ha podido encontrar el contacto!!!!!!!!!!!\")\n\ndef insert_contact():\n    nombre = input(\"Nombre: \")\n    if nombre.lower() in (key.lower() for key in contacts):\n        print (\"\\nEl contacto \" , nombre , \" ya existe\")\n    else:\n        celular = input(\"Celular: \")\n        if(check_input(celular) == True):\n            contacts.update({nombre: celular})\n            print(\"\\nCONTACTO ANIADIDO SATISFACTORIAMENTE OK!\\n\")\n        else:\n            print (\"\\nEl número de teléfono no es válido - ingrese solo numeros (11 max)\")\n    \ndef delete_contact():\n    entry = input(\"\\n Escribe el nombre del contacto que quiere eliminar => \")\n    if entry.lower() not in (key.lower() for key in contacts):\n        print (\"\\nEl contacto \" , entry , \" no existe\")\n    else:\n        key_correct_case = next(key for key in contacts if key.lower() == entry.lower())\n        contacts.pop(key_correct_case)\n        print(\"\\nCONTACTO ELIMINADO SATISFACTORIAMENTE OK!\\n\")\n    \ndef update_contact():\n    entry = input(\"\\n Escribe el nombre del contacto que quieres actualizar => \")\n    entry_lower = entry.lower()\n    if entry_lower in (key.lower() for key in contacts):\n        celular = input(\"Celular: \")\n        if(check_input(celular) == True):\n            key_correct_case = next(key for key in contacts if key.lower() == entry_lower)\n            contacts[key_correct_case] = celular\n            print(\"\\nCONTACTO ACTUALIZADO SATISFACTORIAMENTE OK!\\n\")\n        else:\n            print (\"\\nEl número de teléfono no es válido - ingrese solo numeros (11 max)\")\n    else:\n        print (\"\\n!!!!!!!!!!!No se ha podido encontrar el contacto!!!!!!!!!!!\")\n\ndef sort_contacts():\n    return sorted(contacts.items())\n\nprint(\"------------- Agenda de contactos -------------\")\ndef contactos():\n    end_pogram = True\n    while end_pogram == True:\n\n        print(\"\\nQue operacion desea realizar?\")\n        option = input(\"Crear (C), Borrar (B) , Actualizar (A), Buscar (S), Ordenar (O) => \")\n        if option == \"C\" or option == \"c\":\n            insert_contact()\n        elif option == \"B\" or option == \"b\":\n            delete_contact()\n        elif option == \"A\" or option == \"a\":\n            update_contact()\n        elif option == \"S\" or option == \"s\":\n            search_contact()\n        elif option == \"O\" or option == \"o\":\n            print(\"\\nContactos: \", sort_contacts())\n\n        finish = input(\"\\nDesea finalizar el programa? Yes(Y) No(N): \")\n        if finish == \"Y\" or finish == \"y\":\n            end_pogram = False\n            break\n        elif finish == \"N\" or finish == \"n\":\n            end_pogram = True\n        else:\n            print(\"\\n!!!!!!!!!!!Por favor ingrese una opcion valida!!!!!!!!!!!\")    \n\ncontactos()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Yisusocanto.py",
    "content": "#ESTRUCTURAS DE DATOS\n\n#lISTAS\n\nlista_frutas = [\"manzana\", \"pera\", \"piña\"]\nprint(f\"lista inicial: {lista_frutas}\")\n#insercion\nlista_frutas.append(\"naranja\")\nprint(f\"se inserta el elemento naranja al final de la lista: {lista_frutas}\")\n\nlista_frutas.insert(0, \"fresa\")\nprint(f\"se inserta el elemento fresa en un indice especifico : {lista_frutas}\")\n#eliminacion\nlista_frutas.remove(\"piña\")\nprint(f\"se elimina el elemnto piña de la lista: {lista_frutas}\")\n#actualizacion\nlista_frutas[1] = \"mandarina\"\nprint(f\"se actualiza el indice 1 de la lista de manzana a mandarina: {lista_frutas}\")\n#ordenacion\nlista_frutas.reverse()\nprint(f\"revierte el orden de la lista: {lista_frutas}\")\n\nlista_frutas.sort()\nprint(f\"ordena la lista de forma ascendente: {lista_frutas}\")\n\nlista_frutas.sort(reverse=True)\nprint(f\"ordena la lista de forma descendente : {lista_frutas}\")\n\nlista_frutas.sort(key=len)\nprint(f\"ordena la lista por longitus de cadenas: {lista_frutas}\")\n\nlista_frutas_nueva = sorted(lista_frutas)\n\nprint(f\"crea y ordena una nueva lista sin modificar a la original: {lista_frutas_nueva}\")\nprint(f\"lista original: {lista_frutas}\")\n\n#Tuplas\n\ntupla_numeros = (1,  2, 3)\n\nprint(tupla_numeros)\n\n#diccionario\n\nnotas_estudiantes = {\"jesus\": 20, \"pedro\": 16, \"carlos\": 10}\nprint(notas_estudiantes)\n\nnotas_estudiantes[\"jose\"] = 5\nprint(f\"agregar un par al diccionario: {notas_estudiantes}\") #insercion\n\ndel notas_estudiantes[\"carlos\"]\nprint(f\"eliminar un par del diccionario: {notas_estudiantes}\") #eliminar\n\nnotas_estudiantes[\"pedro\"] = 4\nprint(f\"se actualiza el valor de la clave carlos: {notas_estudiantes}\") #actualizar\n\n\n#extra\n\ndef agenda():\n\n\tdef insertar_numero():\n\t\tphone = input(\"Ingrese el nuevo numero de telefono \")\n\t\tif phone.isdigit() and len(phone) > 0 and len(phone) <= 11:\n\t\t\tagenda_contactos[name] = phone\n\t\telse:\n\t\t\tprint(\"Por favor ingresa un numero mayor que 0 e igual o menor que 11\")\n\n\n\tagenda_contactos = {}\n\n\twhile True:\n\t\tprint(\"\")\n\t\tprint(\"1. Buscar contacto\")\n\t\tprint(\"2. Nuevo contacto\")\n\t\tprint(\"3. Actualizar contacto\")\n\t\tprint(\"4. Eliminar contacto\")\n\t\tprint(\"5. Salir\")\n\t\tprint(\"\")\n\t\t\n\t\tsel = input(\"Selecciona una opcion: \")\n\n\t\tif sel == \"1\":\n\t\t\tname = input(\"Ingrese el contacto que desea buscar: \")\n\t\t\tif name in agenda_contactos:\n\t\t\t\tprint(f\"Este es el numero de telefono: {agenda_contactos[name]}\")\n\t\t\telse:\n\t\t\t\tprint(\"El contacto no existe\")\t\t\n\t\t\n\t\telif sel == \"2\":\n\t\t\tname = input(\"Ingrese el nombre del nuevo contacto: \")\n\t\t\tif name in agenda_contactos:\n\t\t\t\tprint(\"Este contacto ya existe\")\n\t\t\telse:\n\t\t\t\tinsertar_numero()\n\n\t\telif sel == \"3\":\n\t\t\tname = input(\"Ingresa el nombre del contacto: \")\n\t\t\tif name in agenda_contactos:\n\t\t\t\tinsertar_numero()\n\t\t\telse:\n\t\t\t\tprint(\"Este contacto no existe\")\n\n\n\t\telif sel == \"4\":\n\t\t\tname = input(\"Ingrese el nombre del contacto que desee eliminar: \")\n\t\t\tif name in agenda_contactos:\n\t\t\t    del agenda_contactos[name]\n\t\t\telse:\n\t\t\t    print(\"Este contacto no existe\")\n\t\telif sel == \"5\":\n\t\t\tbreak             \n\t\t\t\n\nagenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/YorjanVarela.py",
    "content": "\"\"\"Ejercicio: - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\"\"\"\n\n#Creacion de estructuras de datos\n\n#listas\nmi_lista = [1,2,3,4,5]\n\n\n# Acceder al primer elemento\n(mi_lista[0])  # Salida: 1\n\n# Acceder al último elemento\n(mi_lista[-1])  # Salida: 5\n\n# Acceder a un rango de elementos\n(mi_lista[1:4])  # Salida: [2, 3, 4]   \n\n# Acceder a un rango de elementos con saltos\n(mi_lista[::2])  # Salida: [1, 3, 5]\n\n# Agregar un elemento al final de la lista\nmi_lista.append(6)\n(mi_lista)  # Salida: [1, 2, 3, 4, 5, 6]\n\n# Eliminar un elemento de la lista\nmi_lista.remove(3)\n(mi_lista)  # Salida: [1, 2, 4, 5, 6]\n\n# Actualizar un elemento de la lista\nmi_lista[2] = 7\n(mi_lista)  # Salida: [1, 2, 7, 5, 6]\n\n\n#Tuplas\n\n# Crear una tupla vacía\nmi_tupla = ()\n\n# Crear una tupla con elementos\nmi_tupla = (1, 2, 3, 4, 5)\n\n# Acceder a un elemento de la tupla\n(mi_tupla[0])  # Salida: 1\n\n# Acceder a un rango de elementos de la tupla\n(mi_tupla[1:4])  # Salida: (2, 3, 4)\n\n# Acceder a un rango de elementos de la tupla con saltos\n(mi_tupla[::2])  # Salida: (1, 3, 5)   \n\n# Acceder a la longitud de la tupla\n(len(mi_tupla))  # Salida: 5\n\n# Acceder a la cantidad de veces que aparece un elemento en la tupla\n(mi_tupla.count(3))  # Salida: 1\n\n#conjuntos\n\n# Crear un conjunto vacío\nmi_conjunto = set()\n\n# Crear un conjunto con elementos    \nmi_conjunto = {1, 2, 3, 4, 5}\n\n# Acceder a un elemento del conjunto    \n(mi_conjunto)  # Salida: {1, 2, 3, 4, 5}   \n\n# Agregar un elemento al conjunto\nmi_conjunto.add(6)\n(mi_conjunto)  # Salida: {1, 2, 3, 4, 5, 6}\n\n# Eliminar un elemento del conjunto\nmi_conjunto.remove(3)\n(mi_conjunto)  # Salida: {1, 2, 4, 5, 6}\n\n# Actualizar un elemento del conjunto\nmi_conjunto.update({3})\n(mi_conjunto)  # Salida: {1, 2, 3, 4, 5, 6}\n\n# DICCIONARIOS\n\n# Crear un diccionario vacío\nmi_diccionario = {}\n\n# Crear un diccionario con elementos\nmi_diccionario = {\n    \"clave1\": \"valor1\",\n    \"clave2\": \"valor2\",\n    \"clave3\": \"valor3\"\n}   \n\n# Acceder a un elemento del diccionario\n(mi_diccionario[\"clave1\"])  # Salida: \"valor1\"\n\n# Acceder a todos los elementos del diccionario \n(mi_diccionario)  # Salida: {'clave1': 'valor1', 'clave2': 'valor2', 'clave3': 'valor3'}\n\n# Agregar un elemento al diccionario\nmi_diccionario[\"clave4\"] = \"valor4\"\n(mi_diccionario)  # Salida: {'clave1': 'valor1', 'clave2': 'valor2', 'clave3': 'valor3', 'clave4': 'valor4'}\n\n# Eliminar un elemento del diccionario\ndel mi_diccionario[\"clave2\"]\n(mi_diccionario)  # Salida: {'clave1': 'valor1', 'clave3': 'valor3', 'clave4': 'valor4'}\n\n\n#Programa extra agenda de contactos por terminal   \n\n\n\nagenda = {\n    \"Lucas\": 12345678,   \n    \"Luis\": 23456789,\n    \"Maria\": 34567890}  #parte basica de la agenda de contactos. Basicamente un diccionario y así es como quiero que se muestre en terminal\n\ndef mostrar_lista(agenda): #definimos la funcion para mostrar la lista de contactos\n    print(\"Lista de contactos:\")\n    for nombre, telefono in agenda.items():\n        print(f\"{nombre}: {telefono}\")\n\ndef insertar_contacto(agenda): #definimos la funcion para insertar un contacto\n    nombre = input(\"Introduce el nombre del contacto: \")\n    telefono = input(\"Introduce el número de teléfono: \")\n    if telefono.isdigit() and len(telefono) <= 11:\n        agenda[nombre] = telefono\n        print(\"Contacto agregado.\")\n    else:\n        print(\"Número de teléfono no válido.\")\n\ndef buscar_contacto(agenda): #definimos la funcion para buscar un contacto\n    nombre = input(\"Introduce el nombre del contacto: \")\n    if nombre in agenda:\n        print(f\"El número de teléfono de {nombre} es {agenda[nombre]}\")\n    else:\n        print(\"Contacto no encontrado.\")\n\ndef actualizar_contacto(agenda): #definimos la funcion para actualizar un contacto\n    nombre = input(\"Introduce el nombre del contacto: \")\n    if nombre in agenda:\n        nuevo_numero = input(\"Introduce el nuevo número de telón: \")\n        if nuevo_numero.isdigit() and len(nuevo_numero) <= 11:\n            agenda[nombre] = nuevo_numero\n            print(\"Contacto actualizado.\")\n        else:\n            print(\"Numero de telón no valido.\")\n    else:\n        print(\"Contacto no encontrado.\")    \n\ndef eliminar_contacto(agenda): #definimos la funcion para eliminar un contacto\n    nombre = input(\"Introduce el nombre del contacto: \")\n    if nombre in agenda:\n        del agenda[nombre]\n        print(\"Contacto eliminado.\")\n    else:\n        print(\"Contacto no encontrado.\")\n\ndef mostrar_menu(): #definimos la funcion para mostrar el menu\n    print(\"1. Insertar contacto\")\n    print(\"2. Buscar contacto\")\n    print(\"3. Actualizar contacto\")\n    print(\"4. Eliminar contacto\")\n    print(\"5. Mostrar lista de contactos\")\n    print(\"6. Salir\")\n    opcion = input(\"Seleccione una opcción: \")\n    return opcion\n\ndef main(): #definimos la funcion principal\n    agenda = {}\n    while True:\n        opcion = mostrar_menu()\n        if opcion == \"1\":\n            insertar_contacto(agenda)\n        elif opcion == \"2\":\n            buscar_contacto(agenda)\n        elif opcion == \"3\":\n            actualizar_contacto(agenda)\n        elif opcion == \"4\":\n            eliminar_contacto(agenda)\n        elif opcion == \"5\":\n            mostrar_lista(agenda)\n        elif opcion == \"6\":\n            print(\"Saliendo del programa...\")\n            break\n        else:\n            print(\"Opción no válida. Inténtalo de nuevo.\")\n\nif __name__ == \"__main__\":\n    main() #llamamos a la funcion principal\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Zequy40.py",
    "content": "EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n\n# Crear una lista array\nmi_lista = [1, 2, 3, 4, 5]\n\n# Agregar un elemento al final de la lista\nmi_lista.append(6)\n\n# Insertar un elemento en una posición específica\nmi_lista.insert(2, 10)\n\n# Eliminar un elemento por valor\nmi_lista.remove(3)\n\n# Eliminar un elemento por índice\ndel mi_lista[1]\n\n# Actualizar un elemento por índice\nmi_lista[0] = 100\n\n# Ordenar la lista de forma ascendente\nmi_lista.sort()\n\n# Ordenar la lista de forma descendente\nmi_lista.sort(reverse=True)\n\n# Crear un conjunto de lista\nmi_conjunto = {1, 2, 3, 4, 5}\n\n# Agregar un elemento al conjunto\nmi_conjunto.add(6)\n\n# Eliminar un elemento por valor\nmi_conjunto.remove(3)\n\n# Eliminar un elemento de forma segura si existe\nmi_conjunto.discard(10)\n\n# Crear un diccionario con clave:valor\nmi_diccionario = {\"nombre\": \"Juan\", \"edad\": 25, \"ciudad\": \"Ciudad de México\"}\n\n# Agregar una nueva clave-valor al diccionario\nmi_diccionario[\"ocupacion\"] = \"Estudiante\"\n\n# Eliminar una clave-valor por clave\ndel mi_diccionario[\"edad\"]\n\n\n# Actualizar el valor de una clave\nmi_diccionario[\"nombre\"] = \"Carlos\"\n\n   \n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n\nlist_peoples = []\n\n\ndef is_duplicate(name, lastname, phone):\n    newName = name.strip().capitalize()\n    newLastname = lastname.strip().capitalize()\n    newPhone = phone.strip()\n\n    for people in list_peoples:\n        if (\n            people[\"name\"] == newName\n            and people[\"lastname\"] == newLastname\n            and people[\"phone\"] == newPhone\n        ):\n            return True\n    return False\n\n\ndef add_people():\n    name = input('Ingrese el nombre: ').strip()\n    lastname = input('Ingrese el apellido: ').strip()\n    phone = input('Ingrese el numero de telefono: ').strip()\n\n    if not phone.isdigit() or len(phone) > 11:\n        print('Número de teléfono no válido. Debe ser numérico y tener hasta 11 dígitos.')\n        return\n\n    if is_duplicate(name, lastname, phone):\n        print('El nombre, apellido y telefono ya existen, ingrese otro.')\n    else:\n        newName = name.strip().capitalize()\n        newLastname = lastname.strip().capitalize()\n        newPhone = phone.strip()\n\n        list_peoples.append({'name': newName, 'lastname': newLastname, 'phone': newPhone})\n        print(f'El nombre {newName} y el apellido {newLastname} se han registrado.')\n\n\ndef show():\n    print(\"Lista de personas:\")\n    for person in list_peoples:\n        print(f\"Nombre: {person['name']}, Apellido: {person['lastname']}, Telefono:{person['phone']}\")\n\n\nwhile True:\n    add_people()\n\n    next_input = input('Desea ingresar otro nombre y apellido? (s/n): ')\n    if next_input.lower() == 'n':\n        break\n    elif next_input.lower() == 's':\n        wish = input('¿Que desea hacer ahora? Ingresar otro nombre (i), Ver (v), actualizar(a), o borrar(b): ')\n\n        if wish.lower() == 'v':\n            show()\n        elif wish.lower() == 'i':\n            add_people()\n        elif wish.lower() == 'a':\n            show()\n            input_to_update = input(\"¿Cuál quieres actualizar?\")\n\n            for person in list_peoples:\n               if person['name'] == input_to_update:\n                  print(\"Seleccione el campo que desea actualizar:\")\n                  print(\"1. Nombre\")\n                  print(\"2. Apellido\")\n                  print(\"3. Teléfono\")\n            \n                  choice = input(\"Ingrese el número del campo a actualizar: \")\n                     if choice == \"1\":\n                        new_data = input(\"Ingrese el nuevo nombre: \")\n                        person['name'] = new_data\n                     elif choice == \"2\":\n                        new_data = input(\"Ingrese el nuevo apellido: \")\n                        person['lastname'] = new_data\n                     elif choice == \"3\":\n                        new_data = input(\"Ingrese el nuevo número de teléfono: \")\n                        person['phone'] = new_data\n                     else:\n                         print(\"Opción no válida. No se realizó ninguna actualización.\")\n\n\n        elif wish.lower() == 'b':\n            show()\n            input_to_delete = input(\"¿Cuál quieres borrar?\")\n            list_peoples = [person for person in list_peoples if person['name'] != input_to_delete]\n        else:\n            print(\"La opción elegida no es correcta.\")\n    else:\n        print(\"La opción elegida no es correcta.\")\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/Zerek247.py",
    "content": "\"\"\" CREACION DE TODAS LAS ESTRUCTURAS DE DATOS EN PYTHON \"\"\"\n\n''' --------------- LISTAS -------------------------'''\n\n#Las listas son coleccions ordenadas y mutables que permiten elementos duplicados\n\n''''Creación de una lista con elementos'''\n\nmi_lista = [1,2,3,4,5]\n\n''' AGREGAR '''\n\n# Agrega al final\nmi_lista.append(6) \nprint(mi_lista)\n\n# Agrega en la posición 2\nmi_lista.insert(2,4)\nprint(mi_lista)\n\n''' BORRADO '''\n\n# Elimina el primer elemento con valor 3\nmi_lista.remove(4)\nprint(mi_lista)\n\n# Elimina y retorna el elemeto en la posición 0\nborrado = mi_lista.pop(5)\nprint(mi_lista)\n\n''' ACTUALIZACIÓN '''\n\n# Modifica el elemento en la posición 1\nmi_lista[1] = 10\nprint(mi_lista)\n\n''' ORDENACION '''\n\n#Ordena la lista de mayor a menor\nmi_lista.sort()\nprint(mi_lista)\n\n# Ordena la lista de menor a mayor\nmi_lista.sort(reverse=True)\nprint(mi_lista)\n\n\n''' --------------- TUPLAS -------------------------'''\n\n'''Creación'''\nmi_tupla = (1,2,3,4,5)\n\n'''Las tuplas son inmutables, por los tanto, no se pueden modificar directamente'''\n\n\n''' --------------- CONSJUNTOS -------------------------'''\n\n'''CREACIÓN'''\n\nmi_conjunto = {1,2,3,4,5,6}\nprint(mi_conjunto)\n\n'''INSERCION'''\n\n# Agrega un elemento al conjunto\nmi_conjunto.add(11)\nprint(mi_conjunto)\n\n'''BORRADO'''\n\n# Elimina un elemento del conjunto\nmi_conjunto.remove(3)\nprint(mi_conjunto)\n\n# Elimina un elemento si está presente, no lanza error si no está\nmi_conjunto.discard(15)\nprint(mi_conjunto)\n\n'''ACTUALIZACIÓN'''\n\n#Los conjuntos no soportan actualización de elementos individuales, pero se pueden unir conjuntos\nmi_conjunto.update({2,6,7,9,3})\nprint(mi_conjunto)\n\n\n'''ORDENACIÓN'''\n\n# Los conjuntos no mantienen un orden especifico y no se pueden ordenar directamente\n# Podemos convertirlo a lista si necesitmos ordenar\nmi_lista_ordenada = sorted(mi_conjunto)\nprint(mi_lista_ordenada)\n\n\n\n''' --------------- CONJUNTOS -------------------------'''\n\n'''CREACIÓN'''\n\nmi_diccionario = {\n    \"a\" : 1,\n    \"b\" : 2,\n    \"c\" : 3\n}\nprint(mi_diccionario)\n\n'''INSERCION'''\n\n# Agrega una nueva clave-valor\nmi_diccionario[\"d\"] = 8\nprint(mi_diccionario)\n\n'''BORRADO'''\n\n# Elimina una clave valor\ndel mi_diccionario[\"b\"]\nprint(mi_diccionario)\n\n# Elimina y retorna el valor asociado a la clave\nvalor_borrado = mi_diccionario.pop(\"a\")\nprint(mi_diccionario)\n\n'''ACTUALIZACION'''\n\n# Modifica el valor asociado a una clave\nmi_diccionario[\"c\"] = 10\nprint(mi_diccionario)\n\n'''ORDENACIÓN'''\n\n# Los diccionarios a partir de python 3.7 mantienen el orden de insercion de claves\n# Para ordenar por claves:\nmi_diccionario_ordenado = dict(sorted(mi_diccionario.items()))\nprint(mi_diccionario_ordenado)\n\n# Para ordenar por valores:\nmi_diccionario_ordenado_valores = dict(sorted(mi_diccionario.items(), key=lambda item: item[1]))\nprint(mi_diccionario_ordenado_valores)\n\n\n\n''' --------------- DIFICULTAD EXTRA -------------------------'''\n\n'''Crea una agenda de contactos por terminal.\nDebes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\nCada contacto debe tener un nombre y un número de teléfono.\nEl programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\nlos datos necesarios para llevarla a cabo.\nEl programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n(o el número de dígitos que quieras)\nTambién se debe proponer una operación de finalización del programa.'''\n\n\ndef es_numero_valido(numero):\n    return numero.isdigit() and len(numero) <= 11\n\n\ndef insertar_contacto(agenda):\n    nombre = input(\"Inserte el nombre del contacto: \")\n    numero = input(\"Introduce el número de teléfono: \")\n    if es_numero_valido(numero):\n        agenda[nombre] = numero\n        print(f\"Contacto {nombre} añadido con un número {numero}\")\n    else:\n        print(\"Numero de teléfono no válido. Debe ser numérico y de hasra 11 dígitos\")\n        \n\ndef buscar_contacto(agenda):\n    nombre = input(\"Introduce el nombre del contacto a buscar: \")\n    if nombre in agenda:\n        print(f\"Nombre: {nombre}, Teléfono: {agenda[nombre]}\")\n    else: print(\"Contacto no encontrado\")\n    \n\ndef actualizar_contacto(agenda):\n    nombre = input(\"Iintroduce el nombre del contacto a actualizar: \")\n    if nombre in agenda:\n        numero = input(\"Introduce el nuevo numero de teléfono: \")\n        if es_numero_valido(numero):\n            agenda[nombre] = numero\n            print(f\"Contacto {nombre} actualizado con el nuevo número {numero}\")\n        else:\n            print(\"Número de teléfono no válido. Debe ser numérico y de hasta 11 dígitos\")\n    else:\n        print(\"Contacto no encontrado\")\n\n\ndef eliminar_contacto(agenda):\n    nombre = input(\"Introduce el nombre del contacto a eliminar: \")\n    if nombre in agenda:\n        del agenda[nombre]\n        print(f\"Contacto {nombre} eliminado\")\n    else:\n        print(\"Contacto no encontrado\")\n\ndef mostrar_menu():\n    print(\"\\nAgenda de contactos\")\n    print(\"\\n1. Insertar contacto\")   \n    print(\"\\n2. Buscar contacto\")   \n    print(\"\\n3. Actualizar contacto\")   \n    print(\"\\n4. Eliminar contacto\")   \n    print(\"\\n5. Salir\")    \n    return input(\"Selecciona una opción: \")\n\ndef main():\n    agenda = {}\n    while True:\n        opcion = mostrar_menu()\n        \n        if opcion == '1':\n            insertar_contacto(agenda)\n        elif opcion == '2':\n            buscar_contacto(agenda)\n        elif opcion == '3':\n            actualizar_contacto(agenda)\n        elif opcion == '4':\n            eliminar_contacto(agenda)\n        elif opcion == '5':\n            break\n        else:\n            print(\"Opción no valida. Por favor, selecciona una opción del 1 al 5\")\n            \nif __name__ == \"__main__\":\n    main()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/a-mayans.py",
    "content": "# TIPOS DE ESTRUCTURAS DE DATOS\n\n## LISTAS -> colección de elementos ordenados y modificables\n''' \n- Son accesibles por el indice \n- se pueden modificar \n- No tienen porque ser homogéneas\n- No tienen un tamaño fijo (podemos añadir elementos)\n- Se pueden iterar\n- Se pueden ordenar\n'''\n\nmi_lista = [27, 13, 14, 66, 21]\nprint(mi_lista) \n\n# 1. Inserción\nmi_lista.append(88) # con append añade un elemento en la ultima posicion de la lista\nprint(mi_lista)\n\nmi_lista.insert(2, 30) # con insert podemos indicar el índice donde queremos introducir un elemento y el elemento a introducir\nprint(mi_lista)\n\n# 2. Borrado\nelemento_borrado = mi_lista.pop(2) # con pop eliminamos el elemento indicándole el índice\nmi_lista.remove(13) # con remove eliminamos el elemento indicando su valor, no el índice\nprint(mi_lista)\nprint(elemento_borrado)\n\n# 3. Actualización (modificación del elemento)\nmi_lista[4] = 77\nprint(mi_lista)\n\n# 4. Ordenación\nlista_ordenada = sorted(mi_lista) # con sorted y guardándola en una nueva variable, evitamos modificar la original. \n# con sort -> mi_lista.sort() -> modificariamos la lista original\nprint(lista_ordenada)\nprint(mi_lista)\n\n\n## TUPLAS -> colección de elementos ordenados e inmutables\n''' \n- Son accesibles por el indice \n- No se pueden modificar \n- No tienen porque ser homogéneas\n- Tienen un tamaño fijo \n- Se pueden iterar\n- Se pueden ordenar\n'''\n\nmi_tupla = (44, 11, 77, 55, 99)\nprint(mi_tupla)\n\n# 1. Inserción -> No se puede, una tupla es inmutable\n# 2. Borrado -> No se puede, una tupla es inmutable. La única manera es eliminar la tupla completa con la palabra reservada ( del )\n# 3. Actualización -> No se puede, una tupla es inmutable\n\n# 4. Ordenación \ntupla_ordenada = sorted(mi_tupla)\nprint(tuple(tupla_ordenada))\n\n\n## SETS (conjuntos) -> Una colección de elementos únicos e inmutables\n''' \n- Son accesibles iterandolo \n- Se pueden modificar \n- No tienen porque ser homogéneas\n- No tienen un tamaño fijo \n- Se pueden iterar\n- No se pueden ordenar\n'''\n\nmi_set = {22, 88, 33, 66}\nprint(mi_set)\n\n# 1. Inserción\nmi_set.add(99) # con add se añade el elemento, pero no tiene una posicion (índidce) fijo\nprint(mi_set)\nmi_set.update([1,2,3]) # con upadate([elementos]) podemos añadir varios elementos a la vez\nprint(mi_set)\n\n# 2. Borrado\nmi_set.remove(33) # se elimina el elemento indicado. Si no se encuentra arroja un error\nprint(mi_set)\nmi_set.discard(3) # se elimina el elemento indicado. Este no arroja error si no se encuentra\nprint(mi_set)\n\n# 3. Actualización -> no se puede modificar directamente indicando el elemento. Se debe borrar primero, y agregar el nuevo\n# 4. Ordenación -> No se pueden ordenar ya que los conjuntos son no indexados e inmutables\n\n\n## DICCIONARIOS -> Una colección modificable de pares clave-valor\n''' \n- Son accesibles por claves \n- Se pueden modificar \n- No tienen porque ser homogéneas\n- No tienen un tamaño fijo \n- Se pueden iterar\n- No se pueden ordenar como tal, si no como una lista de tuplas ( lo ordena alfabeticamente por las claves )\n'''\n\nmi_diccionario = {\n    \"nombre\": \"Alejandro\",\n    \"edad\": 30,\n    \"ciudad\": \"Palma\",\n    \"puntuacion\": 27.27\n}\nprint(mi_diccionario)\n\n# 1. Inserción\nmi_diccionario['ocupacion'] = 'Programador' # añadimos entre [] la clave, y igualamos al valor\nprint(mi_diccionario)\n\n# 2. Borrado\ndel mi_diccionario['ciudad'] # con del eliminamos la clave, en consecuencia se elimina el par clave-valor\nprint(mi_diccionario)\n\n# 3. Actualización\nmi_diccionario['puntuacion'] = 95.27 # indicamos la clave de la cual queremos modificar el valor\nprint(mi_diccionario)\n\n# 4. Ordenación\nprint(\"Diccionario ordenado:\", sorted(mi_diccionario.items()))\n\n\n\n# EJERCICIO EXTRA\nimport re\n\nagenda = {}\n\nwhile True:\n    print(\"\\n--- OPERACIONES AGENDA ---\")\n    print(\"1. Buscar contacto\")\n    print(\"2. Añadir contacto\")\n    print(\"3. Actualizar contacto\")\n    print(\"4. Eliminar contacto\")\n    print(\"5. Mostrar todos los contactos\")\n    print(\"6. Salir\")\n\n    opcion = input(\"\\nIngrese el número de la operación que desea realizar: \")\n\n    if opcion == '1':\n        nombre = input(\"Ingrese el nombre del contacto a buscar: \")\n        if nombre in agenda:\n            print(f\"Nombre: {nombre}, Teléfono: {agenda[nombre]}\")\n        else:\n            print(f\"El contacto {nombre} no existe en la agenda.\")\n\n    elif opcion == '2':\n        nombre = input(\"Ingrese el nombre del contacto: \")\n        telf = input(\"Ingrese el número de teléfono: \")\n        if re.match(r'^\\d{1,11}$', telf):\n            agenda[nombre] = telf\n            print(f\"Contacto {nombre} añadido correctamente.\")\n        else:\n            print(\"Número de teléfono no válido. Debe ser numérico y tener entre 1 y 11 dígitos.\")\n\n    elif opcion == '3':\n        nombre = input(\"Ingrese el nombre del contacto a actualizar: \")\n        if nombre in agenda:\n            telf = input(\"Ingrese el nuevo número de teléfono: \")\n            if re.match(r'^\\d{1,11}$', telf):\n                agenda[nombre] = telf\n                print(f\"Contacto {nombre} actualizado correctamente.\")\n            else:\n                print(\"Número de teléfono no válido. Debe ser numérico y tener entre 1 y 11 dígitos.\")\n        else:\n            print(f\"El contacto {nombre} no existe en la agenda.\")\n\n    elif opcion == '4':\n        nombre = input(\"Ingrese el nombre del contacto a eliminar: \")\n        if nombre in agenda:\n            del agenda[nombre]\n            print(f\"Contacto {nombre} eliminado correctamente.\")\n        else:\n            print(f\"El contacto {nombre} no existe en la agenda.\")\n\n    elif opcion == '5':\n        print(\"\\n--- Lista de Contactos ---\")\n        for nombre, telf in agenda.items():\n            print(f\"Nombre: {nombre}, Telf: {telf}\")\n\n    elif opcion == '6':\n        print(\"Saliendo del programa. ¡Hasta luego!\")\n        break\n\n    else:\n        print(\"Opción no válida. Por favor, ingrese un número del 1 al 6.\")"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/abascal92.py",
    "content": "'''\n/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n '''\n\n#region Estructuras de datos\n#region Listas\nprint(\"----------Listas----------\")\nlista = [1, 2, 3, 4, 5]\nprint(lista)\nprint(lista[3])\nlista.append(6)\nprint(lista)\nlista.pop(2)\nprint(lista)\nlista.sort(reverse = True)\nprint(lista)\nlista[0] = 10\nprint(lista)\nlista.clear()\nprint(lista)\n#endregion\n\n#region Tuplas\nprint(\"----------Tuplas----------\")\ntupla = (1, 2, 3, 4, 5)\nprint(tupla)\nprint(tupla[3])\nprint(tupla.count(3))\nprint(tupla.index(4))\n#endregion\n\n#region Diccionarios\nprint(\"----------Diccionarios----------\")\ndiccionario = {\"nombre\": \"Alejandro\", \"apellido\": \"Abascal\", \"edad\": 31 }\nprint(diccionario)\nprint(diccionario[\"nombre\"])\ndiccionario[\"edad\"] = 32\nprint(diccionario)\ndiccionario[\"telf\"] = 123456789\nprint(diccionario)\ndiccionario.pop(\"apellido\")\nprint(diccionario)\ndiccionario.clear()\nprint(diccionario)\n#endregion\n\n#region Conjuntos\nprint(\"----------Conjuntos----------\")\nconjunto = {1, 2, 3, 4, 5}\nprint(conjunto)\nconjunto.add(6)\nprint(conjunto)\nconjunto.remove(3)\nprint(conjunto)\nconjunto.clear()\nprint(conjunto)\n#endregion\n#endregion\n\n#region DIFICULTAD EXTRA\nagenda = { \"Alejandro\": 123456789, \"Alvaro\": 987654321 }\n#region Funciones\ndef busqueda_contacto():\n    nombre = input(\"Introduzca el nombre del contacto a buscar: \").capitalize()\n    if nombre in agenda:\n        print(f\"Contacto encontrado: {nombre} - {agenda[nombre]}\\n\")\n    else:\n        print(f\"No se ha encontrado el contacto {nombre}\\n\")\n\ndef insertar_contacto():\n    nombre = input(\"Introduzca el nombre del contacto a guardar: \").capitalize()\n    telf = input(\"Introduzca el teléfono del contacto a guardar: \")\n    if telf.isdigit() and len(telf) == 9:\n        agenda[nombre] = telf\n        print(f\"Contacto guardado: {nombre} - {agenda[nombre]}\\n\")\n    else:\n        print(\"Número de teléfono no válido\\n\")\n\ndef actualizar_contacto():\n    nombre = input(\"Introduzca el nombre del contacto a actualizar: \").capitalize()\n    if nombre in agenda:\n        telf = input(\"Introduzca el nuevo teléfono del contacto: \")\n        if telf.isdigit() and len(telf) == 9:\n            agenda[nombre] = telf\n            print(f\"Contacto actualizado: {nombre} - {agenda[nombre]}\\n\")\n        else:\n            print(\"Número de teléfono no válido\\n\")\n    else:\n        print(f\"No se ha encontrado el contacto {nombre}\\n\")\n\ndef eliminar_contacto():\n    nombre = input(\"Introduzca el nombre del contacto a eliminar: \").capitalize()\n    if nombre in agenda:\n        agenda.pop(nombre)\n        print(f\"Contacto {nombre} eliminado\\n\")\n    else:\n        print(f\"No se ha encontado el contacto {nombre}\\n\")\n\ndef mostrar_agenda():\n    print(\"\\nTodos los contactos de la agenda: \")\n    for nombre in agenda:\n        print(f\"{nombre} - {agenda[nombre]}\")\n    print(\"\")\n\ndef main():\n    print(\"\\n\\n\\n\\nBienvenido a la agenda de contactos\\n\")\n    salir = False\n    while not salir:\n        print(\"1. Buscar contacto: \")\n        print(\"2. Insertar contacto: \")\n        print(\"3. Actualizar contacto: \")\n        print(\"4. Eliminar contacto: \")\n        print(\"5. Ver contactos: \")\n        print(\"6. Salir\\n\")\n\n        opcion = input(\"Qué quiere hacer: \")\n\n        match opcion:\n            case \"1\":\n                busqueda_contacto()\n            case \"2\":\n                insertar_contacto()\n            case \"3\":\n                actualizar_contacto()\n            case \"4\":\n                eliminar_contacto()\n            case \"5\":\n                mostrar_agenda()\n            case \"6\":\n                print(\"\\nHasta la proxima!\")\n                salir = True\n            case _:\n                print(\"Opción no válida\\n\")\n#endregion\nmain()\n#endregion"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/adolfolozaa.py",
    "content": "\"\"\"\r\nEJERCICIO:\r\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto\r\n *   en tu lenguaje.\r\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\r\n *\r\n * DIFICULTAD EXTRA (opcional):\r\n * Crea una agenda de contactos por terminal.\r\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\r\n *   y eliminación de contactos.\r\n * - Cada contacto debe tener un nombre y un número de teléfono.\r\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\r\n *   y a continuación los datos necesarios para llevarla a cabo.\r\n * - El programa no puede dejar introducir números de teléfono no númericos y con más\r\n *   de 11 dígitos (o el número de dígitos que quieras).\r\n * - También se debe proponer una operación de finalización del programa.\r\n\"\"\"\r\n\r\n# Listas\r\nprint('LISTS')\r\nmy_list: list = ['Adolfo','Gaby', 'Adolfi', 'Manuela', 'Tomas', 'Josemaria']\r\nprint(my_list)\r\nmy_list.append('Francisco')  #Insercion\r\nprint(my_list)\r\nmy_list.remove('Francisco')  #borrado\r\nprint(my_list)\r\nprint(my_list[1])     #Acceso\r\nmy_list[1] = 'Gabriela'   #actualizacion\r\nprint(my_list[1])\r\nmy_list.sort()      #Ordenacion\r\nprint(my_list)\r\nprint(type(my_list))\r\n\r\n# Tuplas  son inmutables\r\nprint('TUPLES')\r\nmy_tuple: tuple = ('Adolfo', 'Loza', 'ALA', '56')\r\nprint(my_tuple[1])\r\nprint(type(my_tuple))\r\n#para que sirve?\r\nmy_tuple = tuple(sorted(my_tuple))  #sorted la ordena y convierte en lista, con tuple lo covertimos en tupla nuevamente\r\nprint(type(my_tuple))\r\nprint(my_tuple)\r\n\r\n# Sets   No conservan la posicion, se evitan duplicados, no se puede ordenar\r\nprint('SETS')\r\nmy_set = {'Adolfo', 'Loza', 'ALA', '56'}\r\nprint(my_set)\r\nprint(type(my_set))\r\nmy_set.add('adolfolozaa@gmail.com')   # Insercion\r\nmy_set.add('adolfolozaa@gmail.com')   # Insercion duplicado\r\nprint(my_set)\r\nmy_set.remove('ALA')   #elimiar\r\nprint(my_set)\r\n\r\n# Diccionario\r\nmy_dict: dict = {'Nombre': 'Adolfo',\r\n                 'Apellido': 'Loza',\r\n                 'Alias': 'ALA',\r\n                 'Edad': '56'}\r\nprint(my_dict)\r\nprint(type(my_dict))\r\n\r\nprint(my_dict['Nombre']) # se accede por clave\r\nmy_dict['Email'] = 'adolfolozaa@gmail.com'  # Insercion\r\nmy_dict['Edad'] = '57'  # Actualizacion\r\nprint(my_dict)\r\n\r\ndel my_dict['Alias']   # Eliminacion\r\nprint(my_dict)\r\nmy_dict1 = sorted(my_dict) # al ordenar solo aparecen claves y como una lista\r\nprint(my_dict1)\r\nprint(type(my_dict1))\r\n\r\nmy_dict2 = sorted(my_dict.items()) # al ordenar con items una lista de tuplas\r\nprint(my_dict2)\r\nprint(type(my_dict2))\r\n\r\nmy_dict3 = dict(sorted(my_dict.items())) # convertimos a dict la lista de tuplas\r\nprint(my_dict3)\r\nprint(type(my_dict3))\r\n\r\n'''\r\nDIFICULTAD EXTRA (opcional):\r\n * Crea una agenda de contactos por terminal.\r\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\r\n *   y eliminación de contactos.\r\n * - Cada contacto debe tener un nombre y un número de teléfono.\r\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\r\n *   y a continuación los datos necesarios para llevarla a cabo.\r\n * - El programa no puede dejar introducir números de teléfono no númericos y con más\r\n *   de 11 dígitos (o el número de dígitos que quieras).\r\n * - También se debe proponer una operación de finalización del programa.\r\n'''\r\n\r\nagenda: dict= {'Adolfo': '22233344'}\r\n# funciones\r\ndef val_num():\r\n    if  telefono.isdigit() and len(telefono) <= 11:\r\n        print('numero valido')\r\n        return\r\n    else:\r\n        print('Numero no valido')\r\n        if seleccion == '2':\r\n            insercion()\r\n        else:\r\n            actualizacion()\r\n\r\n\r\ndef menu_gen():\r\n    print('Menu General')\r\n    print('Que desea hacer? 1. Busqueda, 2. Insercion, 3. Actualizacion, otro. salir')\r\n    global seleccion\r\n    seleccion = input('Ingrese su seleccion? ')\r\n    seleccion = str(seleccion)\r\n    if seleccion == '1' or seleccion == '2' or seleccion == '3':\r\n        print ('Usted ha seleccionado: '+ dict_selec[seleccion])\r\n    else:\r\n        print('Opcion no valida')\r\n\r\n    if seleccion == '1':\r\n        busqueda()\r\n    elif seleccion == '2':\r\n        insercion()\r\n    elif seleccion == '3':\r\n        actualizacion()\r\n    else:\r\n        print('Gracias por utilizar nuestro servicio de agenda!!!')\r\n\r\n\r\ndef menu2():\r\n    seleccion2 = input('Desea continuar en: 1. '+  dict_selec[seleccion]+ '?' + ' o ir a 2. Menu General? ' )\r\n    if seleccion2 == '1':\r\n        if  dict_selec[seleccion] == 'Busqueda':\r\n            busqueda()\r\n        elif  dict_selec[seleccion] == 'Insercion':\r\n            insercion()\r\n        elif  dict_selec[seleccion] == 'Actualizacion':\r\n            actualizacion()\r\n        else:\r\n            print('opcion no valida')\r\n\r\n    elif seleccion2 == '2':\r\n        menu_gen()\r\n    else:\r\n        print('Gracias por utilizar nuestro servicio de agenda!!!')\r\n\r\ndef busqueda():\r\n    contacto = input('Ingrese nombre del contacto? ')\r\n    print('Contacto ingresado es ' + contacto)\r\n    try:\r\n        print('su telefono es: '+ agenda[contacto])\r\n    except:\r\n        print('Contacto no encontrado')\r\n    finally:\r\n        menu2()\r\n\r\ndef insercion():\r\n    nombre = input('Ingrese nombre del contacto nuevo? ')\r\n    global telefono\r\n    telefono = input('Ingrese telefono del contacto? ')\r\n    val_num()\r\n    agenda[nombre] = telefono\r\n    print(agenda)\r\n    menu2()\r\n\r\ndef actualizacion():\r\n    nombre = input('Ingrese nombre del contacto a actualizar? ')\r\n    if nombre not in  agenda:\r\n        print('No es contacto ')\r\n        actualizacion()\r\n    else:\r\n        global telefono\r\n        telefono = input('Ingrese telefono nuevo del contacto? ')\r\n        val_num()\r\n        agenda[nombre] = telefono\r\n        print(agenda)\r\n        menu2()\r\n\r\n\r\nprint('Agenda por Terminal')\r\ndict_selec = {'1': 'Busqueda', '2': 'Insercion', '3': 'Actualizacion'}\r\nglobal telefono\r\nmenu_gen()\r\n\r\n\r\n\r\n\r\n\r\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/adra-dev.py",
    "content": "\"\"\"\nEJERCICIO:\n- Muestra ejemplos de creación de todas las estructuras soportadas\npor defecto en tu lenguaje.\n- Utiliza operaciones de inserción, borrado, actualización y \nordenación.\n\nDIFICULTAD EXTRA (opcional):\n- Crea una agenda de contactos por terminal.\n- Debes implementar funcionalidades de búsqueda, inserción, \nactualización y eliminación de contactos.\n- Cada contacto debe tener un nombre y un número de teléfono.\n- El programa solicita en primer lugar cuál es la operación que se \nquiere realizar, y a continuación los datos necesarios para llevarla \na cabo.\n- El programa no puede dejar introducir números de teléfono no \nnúmericos y con más de 11 dígitos. (o el número de dígitos que \nquieras)\n- También se debe proponer una operación de finalización del \nprograma.\n\nby adra-dev.\n\"\"\"\n\n\"\"\"\nEstructuras de Datos:\n    Una estructura de datos es una forma de organizar, gestionar, y\n    almacenar conjutos de datos para acceder a ellos y manipularlos\n    de manera eficiente, de acuerdo con el problema que estamos \n    resolviendo. El término técnico es Tipo de Dato Abstracto (TDA),\n    pues representan tipos de datos más complejos que, además de \n    almacenar valores determinados en una organización concreta de \n    los mismos, proporcionan operaciones con fines específicos.\n\"\"\"\n\n\"\"\"\nListas:\n    Las listas son secuencias ordenadas de objetos o valores de \n    cualquier tipo.\n\"\"\"\n\n\n# Creación\nlista = [] # lista vacía\nlista = list() # lista vacía\nlista = [1] # lista con un único elemento\nlista = [3, 4] # lista con dos elementos\nlista = [3, 5.6, 'coche'] # lista con tres elementos de distinto tipo\nlista = list(range(5)) # lista con los valores del 0 al 4\n\nprint(lista)\n\n# Inserción de elementos\n\nlista[len(lista):] = [9] # Añade el elemento al final de la lista.\nprint(lista)\n\nlista.append(10) # Añade el elemento al final de la lista.\nprint(lista)\n\nlista.extend(range(4)) # Añade, al final de la lista, todos los elementos del iterable\nprint(lista)\n\n\nlista.insert(2,6) # Inserta un nuevo elemento en la lista en la posición indicada por el primer argumento\nprint(lista)\n\n# Actualización\n\nlista[2] = 2 # Actualiza un valor en especifico, en base a su índice\nprint(lista)\n\n\nlista[8:11] = [8, 9, 10, 11] # Actualiza los valores dentro de un rango de índices\nprint(lista)\n\n# Ordenación\n\nlista.sort() # modifica la lista ordenando sus elementos, si tenemos elementos de distinto tipo no comparables arroja un error\nprint(lista)\n\nlista.sort(reverse=True) # ordena de manera inversa\nprint(lista)\n\n# Borrado\n\ndel lista[10] # Elimina el elemente en base al indice indicado como argumento\nprint(lista)\n\nlista.remove(9) # Elimina de la lista el primer (y solo el primer) elemento  con el valor indicado\nprint(lista)\n\nlista.pop(8) # Elimina el elemento que ocupa la posicion indicada y devuelve su valor.\nprint(lista)\n\nlista.clear() # vacia la lista, elimina todos sus elementos\nprint(lista)\n\nlista = [] # vacia la lista, elimina todos sus elementos\nprint(lista)\n\ndel lista[:]  # vacia la lista, elimina todos sus elementos\nprint(lista)\n\n\n\"\"\"\nPilas:\n    Una estructura de tipo pila es una lista en la que los elementos\n    se añaden al final y se sacan del final; es decir, extraemos \n    siempre el elemento añadido más recientemente. A este tipo de \n    estructuras támbien se les denomina stack o LIFO (Last In, First\n    Out).\n\"\"\"\n\n# Este codigo simula la accion de deshacer\n\n# inicializamos la pila\nacciones = [] \n\n# guardamos las acciones del usuario\nacciones.append(\"escribir: 'h'\")\nacciones.append(\"escribir: 'o'\")\nacciones.append(\"escribir: 'y'\")\nacciones.append(\"negrita: 'hoy'\")\n\n# mostramos el contenido\nprint(acciones)\n\n# deshacemos el ultimo cambio y ponemos en cursiva\nprint(\"sacamos:\", acciones.pop())\nacciones.append(\"cursiva: 'hoy'\")\n\n# mostramos estado final de la pila\nprint(acciones)\n\n\n\"\"\"\nColas:\n    Una cola es una lista en la que los elementos llegan por un lado \n    y salen por otro. Támbien se les denomina FIFO (First In, First\n    Out), pues el primero elemento en llegar es el primero en salir.\n\"\"\"\n\n# Este codigo simula una cola de clientes en el supermercado\n\nfrom collections import deque\n\n# Iniciamos la cola\ncola = deque()\n\n# llegan 5 clientes a la cola \nfor i in range(5):\n    cliente = 'cliente ' + str(i+1)\n    print('Llega', cliente)\n    cola.append(cliente)\n    print('Cola:', cola)\n\n\n# salen todos los clientes de la cola \nwhile len(cola) > 0:\n    print('Sale', cola.popleft())\n    print('Qedan:', cola)\n\n\n\"\"\"\nTuplas:\n    Una tupla es un tipo de dato compuesto por varios valores en un \n    orden determinado. similares a las listas, las tuplas son, en \n    cambio, <<inmutables>>. podemos accedera  sus elementos, pero no\n    cambiar sus valores ni modificar el numero de elementos de la \n    misma.\n\"\"\"\n\n\n# Creación\ntupla = () # tupla vacía\ntupla = tuple() # tupla vacía\nsingleton = 3.1415,  # tupla con un único elemento\ntupla = (3, 4) # tupla con dos elementos\ntupla = (singleton, 3, 5.6, 'coche') # tupla anidada con diferentes elementos\ntupla = tuple(range(5)) # tupla con los valores del 0 al 4\n\n\n# Inserción de elementos\n\ndatos = ('Antonio', 'Gutiérrez', 36, '+34 555 343 232')\nprint(datos)\n\n\ndatos = ('Antonio', 'Gutiérrez', 46, '+34 555 343 232') # El valor no puede modificarse es necesario crear una nueva tupla\nprint(datos)\n\nsingleton += tupla # Se pueden añadir tuplas a tuplas\nprint(singleton)\n\n# Borrado\n\ndel singleton\n\n\n\"\"\"\nConjuntos:\n    Un conjunto es unico y no puede almacenar dos elementos iguales.\n    Además, los elementos no guardan orden alguno, por tanto, un \n    conjunto no es una secuencia. Esto impide indexar sus elementos o\n    acceder a ellos mediante una posición. Si es posible reocrrer el \n    conjunto iterando sobre su contenido, pero no se garantiza orden \n    alguno.\n\"\"\"\n\n# Creacion\nletras = set('abracadabra')\nprint(letras)\n\n# Borrado \ndel letras\n\n\n\"\"\"\nDiccionarios:\n    En programación, existe una estructura de datos con varias \n    denominaciónes posibles: <<arreglo asociativo>>, <<memoria \n    asociativa>>, <<tabla hash>> o, sencillamente <<diccionario>>.\n    \n    Los diccionarios de Python están implementados como tablas hash\n    de crecimiento dinámico y búsqueda abierta pseudoaleatoria ante\n    colisiones.\n\"\"\"\n\n# Creación\n\nprecio_kilo = {} # diccionario vacío\n\nprecio_kilo = dict() # diccionario vacío\n\nprecio_kilo = {'pera': 2.34, 'tomate': 1.98, 'manzana': 2.50} # usando llaves {}\n\nprecio_kilo = dict(pera= 2.34, tomate= 1.98, manzana= 2.50) # usando llaves lla función dict()\n\nprecio_kilo = dict(zip(['pera', 'tomate', 'manzana'], [2.3, 1.98, 2.5])) # pares de tuplas\n\nprecio_kilo = dict([('pera', 2.34), ('tomate', 1.98), ('manzana', 2.50)]) # usando llaves {}\n\n# Inserción\n\nprecio_kilo['uva'] = 3.2\nprint(precio_kilo)\n\n# actualizacion\n\n\nprecio_kilo.update(pera= 4.20, tomate= 2.98)\nprint(precio_kilo)\n\nprecio_kilo['uva'] = 5.5\nprint(precio_kilo)\n\n# Eliminación\n\n\nprecio_kilo.pop('tomate')\nprint(precio_kilo)\n\ndel precio_kilo['uva'] \nprint(precio_kilo)\n\nprecio_kilo.clear()\nprint(precio_kilo)\n\n\n\"\"\"\nExtra\n\"\"\"\n\n\n# -*- coding: utf-8 -*-\n\"\"\"\nCreated on Tue Jan 16 10:48:59 2024\n\nCrea una agenda de contactos por terminal\n\"\"\"\n__author__ = \"adra-dev\"\n__copyright__ = \"roadmap-retps-programacion\"\n__credits__ = \"adra-dev\"\n__license__ = \"GPL\"\n__version__ = \"1.0\"\n__email__ = \"alfaroar98@gmail.com\"\n__status__ = \"Development\"\n\n\n\ncampos = ('nombre', 'apellidos', 'email', 'telefono')\n\ncontactos = []\n\n\ndef input_contact():\n    \n    contacto = {}\n\n    for campo in campos:\n        \n        if campo == 'telefono':\n            valor = input(campo + ': ')\n            \n            if len(valor) > 0 and len(valor) < 12:\n                contacto[campo] = valor\n                contactos.append(contacto)\n            else: return print('Numero no valido')\n\n        valor = input(campo + ': ')\n        \n        if len(valor) > 0:\n            contacto[campo] = valor\n\n    contactos.append(contacto)\n\n    return print(f\"El contacto {contacto} ha sido agregado\")\n\n\ndef delete_contact():\n\n    nombre = input(\"Ingresa el nombre: \")\n    telefono = input(\"Ingresa el telefono: \")\n\n    for contacto in contactos:\n        if nombre and telefono in contacto.values():\n            index = contactos.index(contacto)\n            del contactos[index]\n            \n        else:\n            return print(\"Contacto no encontrado.\")\n    return print(\"Contacto eliminado: \", contacto)\n    \n\ndef search_contact():\n\n    nombre = input(\"Ingresa el nombre: \")\n    telefono = input(\"Ingresa el telefono: \")\n\n    for contacto in contactos:\n        if nombre and telefono in contacto.values():\n           return print(\n            f\"\"\"El Contacto {nombre} con el telefono {telefono}\n            si esta en la lista de contactos.\"\"\")\n        else:\n            return print(\"Contacto no encontrado.\")\n\n\ndef update_contact():\n\n    nombre = input(\"Ingresa el nombre: \")\n    telefono = input(\"Ingresa el telefono: \")\n    \n    for contacto in contactos:\n        if nombre and telefono in contacto.values():\n                index = contactos.index(contacto)\n                \n                print(\"Introduce los valores a actualizar.\")\n                \n                for campo in campos:\n                    valor = input(campo + ': ')\n        \n                    if len(valor) > 0 and len(valor) <= 12:\n                        contacto[campo] = valor\n                \n                del contactos[index]\n                contactos.insert(index, contacto)\n\n    return print(f\"El contacto {nombre} ha sido Actualizado\")\n            \n\n\ncontinuar = 's'\n\nwhile continuar in ('s', 'S'):\n\n    \n\n    estados = ['Introducir', 'Eliminar', 'Buscar', 'Actualizar']\n\n    print('Bienvenido a la agenda python, estas son tus opciones')\n    print('------')\n\n    for estado in estados:\n        print(estado)\n    print('------')\n\n    estado = input('Que operacion quieres realizar?:').capitalize()\n    print('------')\n\n    if estado == 'Introducir':\n        input_contact()\n        print('------')\n\n    elif estado == 'Buscar':\n        search_contact()\n        print('------')\n\n    elif estado == 'Actualizar':\n        update_contact()\n        print('------')\n\n    elif estado == 'Eliminar':\n        delete_contact()\n        print('------')\n\n    else:\n        print('Opcion no valida')\n        print('------')\n\n    continuar = input('Quieres continuar? s\\n:')\n\n\nfor contacto in contactos:\n\n    for k,v in contacto.items():\n        print(k + ': ' +v)     \n        #mostramos esto para facilitar la lectura \n        print('------')"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/agusrosero.py",
    "content": "# Estructuras de Datos\n\n# LISTAS\nlistas = [1, 2, 3, 4, 5]\nlistas.append(1)\nlistas.insert(1, 2)\nlista = listas.copy()\nlista[1] = 10\nlista.sort()\nprint(lista)\n\n# TUPLAS\nmi_tupla = (1, 2, 3, 4)\nelemento = mi_tupla[1]\ntupla_nueva = mi_tupla + (5, 6, 7)\nprint(mi_tupla)\n\n# Conjuntos\nmi_conjunto = {'hello', 'world', 'python'}\nmi_conjunto.add('java')\nconjuntos = mi_conjunto.copy()\nconjuntos.remove('world')\nconjuntos.discard('hello')\nconjuntos.update({'hello', 'world'})\nconjuntos.clear()\nconjuntos.add('python')\nprint(conjuntos)\n\n# Diccionarios\nmi_diccionario = {'clave': 'valor', 'color': 'rojo'}\nmi_diccionario['edad'] = 23\ndiccionario = mi_diccionario.copy()\ndiccionario.pop('color')\ndel diccionario['clave']\ndiccionario.update({'edad': 23})\ndiccionario.clear()\nprint(diccionario)\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/ainaragmt.py",
    "content": "# Listas\nprint(\"\\nListas\")\nmy_list = [1,3,7,5,8,2,0]\nprint(my_list)\nprint(type(my_list))\nmy_list.append(10) # insertar\nprint(my_list)\nmy_list.remove(5) # eliminar\nprint(my_list)\nmy_list[2] = 4 # acceder y actualizar\nprint(my_list)\nmy_list.sort() # ordenar\nprint(my_list)\n\n# Tuplas (no modificables)\nprint(\"\\nTuplas\")\nmy_tuple = (\"Ainara\", \"ainaragmt\", \"Python\")\nprint(my_tuple)\nprint(type(my_tuple))\nprint(my_tuple[1]) # acceder\nmy_tuple = tuple(sorted(my_tuple)) # ordenar una tupla\nprint(my_tuple)\n\n# Sets (estructura desordenada)\nprint(\"\\nSets\")\nmy_set = {\"Ainara\", \"ainaragmt\", \"Python\"}\nprint(my_set)\nprint(type(my_set))\nmy_set.add(\"ainaragmt@gmail.com\") # insertar\nprint(my_set)\nmy_set.add(\"ainaragmt@gmail.com\") # no se vuelve a insertar (no hay datos duplicados)\nprint(my_set)\nmy_set.remove(\"Python\") # eliminar\nprint(my_set)\n# my_set.update() sirve para concatenar más datos\n# si queremos actualizar algún dato lo mejor es eliminarlo y insertarlo\n\n# Diccionario\nprint(\"\\nDiccionario\")\nmy_dict = {\n    1: {\"name\": \"Ainara\", \"number\": 1},\n    3: {\"name\": \"Marta\", \"number\": 2},\n    2: {\"name\": \"Lucía\", \"number\": 3}\n}\nprint(my_dict)\nprint(my_dict[1])\nprint(type(my_dict))\ndel my_dict[1] # eliminar\nprint(my_dict)\nmy_dict = dict(sorted(my_dict.items())) # ordenar\nprint(my_dict)\n\n'''\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n'''\nprint(\"\\nEjercicio de dificultad extra\") # idea: crear una función\n\nsalir = 0\nagenda = {\n    \"Ainara\": 1234\n}\n\nwhile salir == 0:\n    print(f\"\\nAgenda: {agenda}\\n\")\n\n    # idea: match + case\n    x = int(input(\"Elige la función que desees y pulsa enter: \\n1. Buscar contacto\\n2. Insertar contacto\\n3. Actualizar contacto\\n4. Eliminar contacto\\n5. Salir\\n\"))\n    while x != 1 and x != 2 and  x != 3 and x != 4 and x != 5:\n        print(\"\\nEl número elegido no existe.\\n\")\n        x = int(input(\"¿Qué quieres hacer? \\n1. Buscar contacto\\n2. Insertar contacto\\n3. Actualizar contacto\\n4. Eliminar contacto\\n\"))\n    print(x)\n\n    if x == 5:\n        salir = 1\n\n    elif x == 1:\n        nombre = str(input(\"\\nEscribe el nombre del contacto que quieres buscar: \"))\n        if nombre in agenda:\n            print(f\"El número de {nombre} es {str(agenda[nombre])}\")\n        else:\n            print(f\"{nombre} no está en la lista.\")\n\n    elif x == 2:\n        nombre = input(\"\\nEscribe el nombre del contacto que quieres añadir: \")\n        numero_str = input(\"Escribe el número del contacto que quieres añadir: \")\n        # idea: numero.isdigit()\n        try:\n            numero_int= int(numero_str)\n            if len(numero_str) > 11:\n                print(\"Error: Número con más de 11 dígitos.\\n\")\n            else:\n                agenda[nombre] = numero_int\n                print(\"\\nContacto añadido:\")\n        except ValueError:\n            print(\"Error: Número no numérico.\\n\")\n    \n    elif x == 3:\n        # idea: codigo repetido del case 2 -> crear una función común\n        nombre = input(\"\\nEscribe el nombre del contacto que quieres actualizar: \")\n        if nombre not in agenda:\n            print(\"El contacto no está en la agenda\\n\")\n        else:\n            numero_str = input(\"Escribe el número del contacto que quieres actualizar: \")\n            try:\n                numero_int= int(numero_str)\n                if len(numero_str) > 11:\n                    print(\"Error: Número con más de 11 dígitos.\\n\")\n                else:\n                    agenda[nombre] = numero_int\n                    print(\"\\nContacto actualizado:\")\n            except ValueError:\n                print(\"Error: Número no numérico.\\n\")\n\n    elif x == 4:\n        nombre = str(input(\"\\nEscribe el nombre del contacto que quieres eliminar: \"))\n        if nombre not in agenda:\n            print(\"El contacto no está en la agenda\\n\")\n        else:\n            del agenda[nombre]"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/alanshakir.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\"\"\"\n\n#Listas\nmy_list = []  # creacion lista vacia\nmy_list = [\"alan\", \"ramirez\", 20, 1985, \"alan2085@gmail.com\" ]\nprint(my_list)\n\nmy_list.append(1.73) #insercion\nprint(my_list)\n\ndel my_list[1] #borra elemento posicion 1\nprint(my_list)\n\nmy_list [2] = 2014 #actualizacion\nprint(my_list) \n\nmy_list = [\"alan\", \"ramirez\", \"matheo\", \"alan2085@gmail.com\" ]\nmy_list.sort() #ordenacion\nprint(my_list) \n\n#tuplas\nmy_tuple = () # creacion tupla vacia\nmy_tuple = (25, 86, 85, 2014, 5, 2024, 3) #las tuplas son inmutables no se pueden modificar\nprint(my_tuple)\n\nmy_tuple2 = (25,85,47)\nprint(my_tuple + my_tuple2) #las tuplas se pueden concatenar \n\n\n\n#Set\nmy_set = {} #creacion set vacio\nmy_set = {\"Alan\", \"Nicolle\", \"Giselle\", \"Matheo\"}\nprint(my_set)\n\nmy_set.add(\"Shakir\") #insercion\nprint(my_set)\n\nmy_set.update([\"ramirez\"]) #actualizacion de la lista\nprint(my_set)\n\nmy_set.remove(\"Alan\") #borrado\nprint(my_set)\n\n#Diccionario\nmy_dictionary = dict() #creacion diccionario vacio\nmy_dictionary = {\"name\":\"alan\", \"surname\": \"ramirez\", \"age\": 39, \"email\": \"alan2085@gmail.com\"}\nprint(my_dictionary)\n\nmy_dictionary[\"address\"] = \"Chile\" #insercion\nprint(my_dictionary)\n\nmy_dictionary[\"age\"] = 38  #actualizacion\nprint(my_dictionary)\n\nmy_dictionary.pop(\"surname\") #borrado por clave\nprint(my_dictionary)\ndel my_dictionary[\"age\"] #borrado por clave\nprint(my_dictionary)\nmy_dictionary.popitem() #borra ultimo elemento\nprint(my_dictionary)\n\n###### DIFICULTAD EXTRA ##########\nprint(\"vamos a crear la agenda de contacto.!\")\ncount_contact = int(input(\"ingrese la cantidad de contactos de desea crear: \"))\nprint(type(count_contact))\nmy_contacts = dict()\n#creacion lista de contactos\nwhile count_contact > 0:\n    contact = input(\"ingrese el nombre del contacto: \")\n    number = input(\"ingrese el numero del contacto, debe ser menor a 11 digitos: \")\n    if len(number) > 11:\n        number = input(\"ingrese el numero del contacto, debe ser menor a 11 digitos: \")\n    else:\n        my_contacts[contact] = number\n    count_contact-= 1\nprint(my_contacts)\n#Operaciones de la agenda\nwhile True:\n    print(\"Si desea actualizar numero de contacto presione 1: \")\n    print(\"Si desea eliminar numero de contacto presione 2:   \")\n    print(\"Si desea buscar numero de contacto presione 3:     \")\n    print(\"Si desea salir del sistema presione 4:             \")\n\n    option = int(input(\"Seleccione una opcion: \"))\n\n    if option == 1:\n        contact = input(\"ingrese el nombre del contacto: \")\n        if contact in my_contacts:\n             number = int(input(\"ingrese el numero del contacto, debe ser menor a 11 digitos: \"))\n             my_contacts[contact] = number\n        else:\n            print(\"Contacto no existe\")\n    elif option == 2:\n        contact = input(\"ingrese el nombre del contacto: \")\n        if contact in my_contacts:\n             del my_contacts[contact]\n        else:\n            print(\"Contacto no existe\")\n    elif option == 3:\n        contact = input(\"ingrese el nombre del contacto: \")\n        if contact in my_contacts:\n             print(my_contacts[contact]) \n        else:\n            print(\"Contacto no existe\")\n    elif option == 4:\n        print(\"Hasta Luego\")\n        break\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/alberba.py",
    "content": "\nimport time\n\n\nlista: list = [\"Jose\", \"Juan\", \"Miguel\"]\nprint(lista)\n\n# Inserción\nlista.append(\"Samuel\")\nprint(lista)\n\n# Borrado\nlista.remove(\"Jose\")\nprint(lista)\n\n# Actualización\nlista[2] = \"Albert\"\nprint(lista)\n\n# Ordenación\nlista.sort()\nprint(lista)\n\n# EXTRA\n\ndef agenda():\n\n    def insertar_contacto():\n        print(\"Introduce el teléfono del contacto\")\n        telefono = input()\n        if telefono.isdigit() and len(telefono) <= 11:\n            lista[nombre] = telefono\n        else:\n            print(\"Introduce un número de teléfono de cómo máximo 11 dígitos\")\n\n    lista = dict()\n\n    while True:\n        print(\"¿Que operación quieres hacer?\")\n        print(\"1. Nuevo Contacto\\t2. Actualizar contacto\\n3. Buscar contacto\\t4. Eliminar contacto\\n5. Salir de la agenda\")\n\n        opcion = int(input())\n\n        match opcion:\n\n            case 1:\n                print(\"Introduce el nombre del contacto\")\n                nombre = input()\n                insertar_contacto()\n                \n            case 2:\n                print(\"Introduce el nombre del contacto que quieres actualizar\")\n                nombre = input()\n                if nombre in lista:\n                    insertar_contacto()\n                else:\n                    print(\"El nombre del contacto no figura en la lista\")\n                \n            case 3:\n                print(\"Introduce el nombre del contacto que desee buscar: \")\n                nombre = input()\n                print(lista[nombre]) if nombre in lista else print(\"No se encuentra el contacto\")\n            case 4:\n                print(\"Introduce el nombre del contacto que quieres eliminar\")\n                nombre = input()\n                if nombre in lista:\n                    lista.pop(nombre)\n                else:\n                    print(\"El nombre del contacto no figura en la lista\")\n            case 5:\n                print(\"Saliento de la agenda\")\n                break\n            case _:\n                print(\"Opción no válida\")\n\n        # Tiempo de espera para poder leer el mensaje\n        time.sleep(1.5)\n\n\nagenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/albertorevel.py",
    "content": "from enum import Enum\n\n# @author Alberto Revel\n\n\"\"\"\n- Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n\"\"\"\n\nprint(\"\\n**** PART 1 - CREATING DATA STRUCTURES ****\\n\")\n\n\n# PART 1.1 - Lists\n\nprint(\"\\n** 1.1 - LISTS **\\n\")\n\nlist1 = []\nlist2 = list()\nprint(f\"\"\"There are two ways to create lists, that produces the same result\n - 'list1 = []' -> {list1}\n - 'list2 = list()' ->  {list2}\\n\"\"\")\n\nlist1 = [1,2,True,'something',5,1]\nlist2 = list([1,2,True,'something',5,1])\nprint(f\"\"\"\\nWe can initiate lists with some elements (that can have different types)\n - list1 = '[1,2,True,'something',5,1]' ->  {list1}\n - list2 = 'list([1,2,True,'something',5,1])' -> {list2}\\n\"\"\")\n\n\n# PART 1.2 - Sets\n\nprint(\"\\n** 1.2 - SETS **\\n\")\n\nset1 = {1,2,\"3\",True,1}\nprint(\"\"\"Sets are created like lists but whitout duplicates (1 is equivalent to True)\n - 'set1 = {1,2,\"3\",True,1}' -> \"\"\" + f\"{set1}\\n\")\n\n\n# PART 1.3 - Tuples\n\nprint(\"\\n** 1.3 - TUPLES **\\n\")\n\ntuple1 = (1,2,\"3\",True,1)\nprint(\"\"\"Tuples are inmutables lists\n - 'tuple1 = (1,2,\"3\",True,1)' -> \"\"\" + f\"{tuple1}\\n\")\n\n\n# PART 1.4 - Matrixes\n\nprint(\"\\n** 1.4 - MATRIXES **\\n\")\n\nmatrix1 = [['X','O',' '], ['X','O',' '], ['O','X','X ']]\nprint(f\"\"\"A matrix is a list containing other lists\n - 'matrix1 = [['X','O',' '], ['X','O',' '], ['O','X','X ']]'\n      -> {matrix1}\\n\"\"\")\n\n\n# PART 1.5 - Dictionaries\n\nprint(\"\\n** 1.5 - DICTIONARIES **\\n\")\n\ndictionary1 = {\"name\": \"Alberto\", \"surname\": \"Revel\", \"birthYear\": 1992}\nprint(\"\"\"A dictionary contains key-value pairs\n - \"dictionary1 = {'name': 'Alberto', 'surname': 'Revel', 'brithYear': 1992}'\n      -> \"\"\"+f\"{dictionary1}\\n\")\n\ndictionary2 = dict(name = \"Alberto\", surname = \"Revel\", birthYear = 1992)\nprint(\"\"\"There's other way to create a dictionary\n - \"dictionary2 = dict(name = \"Alberto\", surname = \"Revel\", birthYear = 1992)\n      -> \"\"\"+f\"{dictionary2}\\n\")\n\n\"\"\"\n- Utiliza operaciones de inserción, borrado, actualización y ordenación.\n\"\"\"\n\n\nprint(\"\\n**** PART 2 - OPERATING WITH DATA STRUCTURES ****\\n\")\n\n\n# PART 2.1 - List\n\nprint(\"\\n** 2.1 - LIST **\\n\")\nlist3 = [5,2,-1,10,0]\nprint(f\"Being the initial list : {list3}\")\nlist3.append(2)\nprint(f\" - We add the element '2' at the end with append(): {list3}\")\nlist3.extend([5,9,1])\nprint(f\" - We add the elements '[5,9,1]' at the end with extend() : {list3}\")\nlist3.insert(2,4)\nprint(f\" - We add the element '4' at the position 2 with insert(): {list3}\")\nlist3+=[8,11]\nprint(f\" - We add the elements '[8,11]' at the end through concatenation: {list3}\")\nlist3.remove(2)\nprint(f\" - We remove the first element '2' with remove() : {list3}\")\nlist3.pop()\nprint(f\" - We remove the last element with pop(): {list3}\")\nlist3.pop(5)\nprint(f\" - We remove the element at position 5 with pop(): {list3}\")\nlist3.sort(reverse=True)\nprint(f\" - We sort the list in reverse order with sort(reverse=): {list3}\")\nlist3.clear()\nprint(f\" - We remove all the elements with clear() : {list3}\")\n\n# PART 2.2 - Set\n\nprint(\"\\n** 2.2 - SET **\\n\")\nset2 = {5,2,-1,10,0}\nprint(f\"Being the initial set : {set2}\")\nset2.add(3)\nprint(f\" - We add the element '3' with add() : {set2}\")\nset2.add(3)\nprint(f\" - We add the element '3' with add() (nothing happens because duplicates aren't possible in a set) : {set2}\")\nset2.update([5,9,1])\nprint(f\" - We add the elements '[5,9,1]' with update() : {set2}\")\nset2.remove(2)\nprint(f\" - We remove the element '2' with remove() : {set2}\")\nset2.discard(2)\nprint(f\" - We remove the element '2' with discard() if present : {set2}\")\nset2.discard(3)\nprint(f\" - We remove the element '3' with discard() if present : {set2}\")\nset2.pop()\nprint(f\" - We remove an arbitrary element with pop() : {set2}\")\nset2.intersection_update({1,2,3,4,5,8,9,11})\nprint(\" - We keep only the elements contained in set and in '{1,2,3,4,5,8,9,11}' with intersection_update(): \"+f\"{set2}\")\nset2.difference_update({1,2,8,6,10})\nprint(\" - We remove the elements contained in '{1,2,8,6,10}' with difference_update(): \"+f\"{set2}\")\nset2.symmetric_difference_update({1,2,8,9,10})\nprint(\" - We keep only the elements contained in set or in '{1,2,8,9,10}' but not both with symmetric_difference_update(): \"+f\"{set2}\")\nset2.clear()\nprint(f\" - We remove all the elements with clear() : {set2}\")\n\n# PART 2.3 - Tuple\n\nprint(\"\\n** 2.3 - TUPLE **\\n\")\ntuple2 = (5,2,-1,10,0)\nprint(f\"Being the initial tuple : {tuple2}\")\ntuple2+=(3,)\nprint(f\" - We add the element '3' using the addition operator : {tuple2}\")\ntuple2+=(8,2)\nprint(f\" - We add the elements '(8,2)' using the addition operator : {tuple2}\")\ntuple2 = tuple(sorted(tuple2))\nprint(f\" - We sort the tuple by converting it to a list and then converting it to a tuple again : {tuple2}\")\n\n\n# PART 2.4 - Matrix\n\nprint(\"\\n** 2.4 - Matrix **\\n\")\nmatrix2 = [['X','O','X'], ['X','O',' '], ['O','X','X ']]\nprint(f\"Being the initial matrix : {matrix2}\")\nmatrix2.append(['O','O','X'])\nprint(f\" - We add the elements '['O','O','X']' with append() : {matrix2}\")\nmatrix2.pop()\nprint(f\" - We remove elements at the end with pop() : {matrix2}\")\nmatrix2.sort()\nprint(f\" - We sort matrixes with sort() : {matrix2}\")\nprint(\"PS: As a matrix is a list of lists, all list operations are allowed\")\n\n\n# PART 2.5 - Dictionaries\n\nprint(\"\\n** 2.5 - DICTIONARIES **\\n\")\n\ndictionary3 = {\"name\": \"Alberto\", \"surname\": \"Revel\", \"birthYear\": 1992}\nprint(f\"Being the initial dictionary : {dictionary3}\")\ndictionary3.update({\"town\" : \"Barcelona\"})\nprint(f\" - We add elements from another dictionary with update() : {dictionary3}\")\ndictionary3[\"hairColor\"]=\"brown\"\nprint(f\" - We add elements by assigning a value to a inexistent key with 'dictionary3['hairColour']= 'brown'' : {dictionary3}\")\ndictionary3 = dict(sorted(dictionary3.items()))\nprint(f\" - We sort the items by its keys sorting the items with 'dict(sorted(dictionary3.items()))' : {dictionary3}\")\ndictionary3.pop(\"town\")\nprint(f\" - We remove the element by its key with pop() : {dictionary3}\")\ndictionary3.popitem()\nprint(f\" - We remove a random element with popitem() : {dictionary3}\")\ndictionary3.clear()\nprint(f\" - We remove all the elements with clear() : {dictionary3}\")\nprint(\"\\n\\n\")\n\n\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n\"\"\"\n\nmy_contact_book = {}\nmin_digits = 1\nmax_digits = 11\n\n\n# Main Menu\n\ndef main_program():\n     print(\"\\n--> Welcome to the contacts book v3 <--\")\n     selected_op = 1\n     while selected_op > 0:\n          selected_op = query_user_input()\n          perform_operation(selected_op)\n     print(\"\\n--> Ending program, See you soon! <--\\n\")\n\n\ndef query_user_input():\n      selected_op = -1\n      try:\n            selected_op =  int(input(\"\"\"\\nPlease, try an operation by typying the operation number:\n                  - 0: Exit\n                  - 1: Search a contact\n                  - 2: Add a contact\n                  - 3: Update a contact\n                  - 4: Delete a contact\\n\"\"\"))\n      except ValueError:\n            print(\"Please, select a valid option\")\n            selected_op = query_user_input()\n      return selected_op\n\ndef query_contact_name():\n     contact_name = str(input(\"\\nPlease, enter the name of the contact: \"))\n\n     try:\n        validate_name(contact_name)\n     except Exception as e:\n        print(\"ERROR\" + str(e))\n\n     return contact_name\n\ndef query_contact_number():\n     contact_number = str(input(\"\\nPlease, enter the number of the contact: \"))\n\n     try:\n        contact_number = convert_str_to_int(contact_number)\n        validate_number(contact_number)\n        return contact_number\n     except Exception as e:\n        print(e.args)\n\ndef perform_operation(selected_op):\n     match selected_op:\n          case Operations.SEARCH.value:\n               search_operation()\n          case Operations.ADDITION.value:\n               add_operation()\n          case Operations.UPDATE.value:\n               update_operation()\n          case Operations.DELETION.value:\n               delete_operation()\n\n\ndef search_operation():\n     contact_name = query_contact_name()\n     contact_number = search_contact(contact_name)\n\n     if contact_number != None and len(str(contact_number)) > 0:\n          print(f\"\\nContact found -> {contact_name}: {contact_number}\")\n     else:\n          print(f\"\\nThere's no contact in address book with name: {contact_name}\")\n\n     print(\"\\n\")\n\ndef add_operation():\n     contact_name = query_contact_name()\n     contact_number = query_contact_number()\n\n     try:\n          add_contact(contact_name, contact_number)\n     except ContactAlreadyExistsException as e:\n          print(\"Contact cannot be added\" + str(e))\n     else:\n          print(\"\\nContact added\\n\")\n\ndef update_operation():\n     contact_name = query_contact_name()\n     contact_number = query_contact_number()\n\n     update_contact(contact_name, contact_number)\n\n     print(\"\\nContact updated\\n\")\n\ndef delete_operation():\n     contact_name = query_contact_name()\n     try:\n        delete_contact(contact_name)\n        print(\"\\nContact deleted\\n\")\n     except:\n         print(\"\\nContact not found, it cannot be deleted\\n\")\n\n# Menu operations\n\ndef search_contact(name):\n     return find_contact(name)\n\ndef add_contact(name, number):\n     validate_contact_addition(name, number)\n     set_contact(name, number)\n\n\ndef update_contact(name, number):\n     old_contact = find_contact(name)\n     if old_contact != None:\n          set_contact(name, number)\n     else:\n          raise ContactNotFoundException\n\n\n# Contact Operations\ndef set_contact(name, number):\n      my_contact_book[name] = number\n\ndef find_contact(name):\n      return my_contact_book[name] if name in my_contact_book else None\n\ndef delete_contact(name):\n      return my_contact_book.pop(name)\n\n# Validations\ndef validate_contact_addition(name, number):\n     if name in my_contact_book:\n            raise ContactAlreadyExistsException\n     validate_number(number)\n     validate_name(name)\n\ndef validate_number(number):\n      if not(isinstance(number,int)):\n            raise NumberNoDigitCharsException\n      elif len(str(number)) < min_digits or len(str(number)) > max_digits:\n            raise NumberExtensionException\n      else:\n            pass\n\ndef validate_name(name):\n\n      if not(isinstance(name,str)):\n            raise NumberNoDigitCharsException\n      elif len(name.strip()) == 0:\n            raise NameCannotBeVoid\n\n# Utils\ndef convert_str_to_int(str_from):\n     try:\n        return int(str_from)\n     except:\n        return str_from\n\n# Enums\nclass Operations(Enum):\n     EXIT = 0\n     SEARCH = 1\n     ADDITION = 2\n     UPDATE = 3\n     DELETION = 4\n\n\n# Exceptions\nclass ContactAlreadyExistsException(Exception):\n    \"The contact already exists, update the contact instead adding it again\"\n    pass\n\nclass ContactNotFoundException(Exception):\n    \"The contact doesn't exist\"\n    pass\n\nclass NumberNoDigitCharsException(Exception):\n    \"Phone number can only contain digits\"\n    pass\n\nclass NumberExtensionException(Exception):\n    f\"Phone number length has to be between {min_digits} and {max_digits} digits\"\n    pass\n\nclass NameFormatError(Exception):\n    f\"Contact name has no valid type, please check introduced characters\"\n    pass\n\nclass NameCannotBeVoid(Exception):\n    f\"Contact name cannot be empty\"\n    pass\n\n\nmain_program()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/alcaan16.py",
    "content": "\"\"\"/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto\n *   en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n *   y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n *   y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más\n *   de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.\n */\n \"\"\"\nagenda= {}\n\n\ndef my_agenda(opcion=0):\n\n    def insertar():\n        name = input(\"introduce el nombre del contacto: \")\n        telefono = input(\"introduce el telefono del contacto: \")\n        if telefono.isdigit and len(telefono) > 1 and len(telefono) <= 11:\n            agenda[name] = telefono\n        else:\n            print(\"el numero no es valido\")\n\n    while True:\n\n        print(\"\\n******************\")\n        print(\"1. Buscar contacto\")\n        print(\"2. Insertar contacto\")\n        print(\"3. Actualizar contacto\")\n        print(\"4. Eliminar contacto\")\n        print(\"5. Salir\")\n        print(\"******************\")\n\n        opcion = input(\"\\nIntroduce la opcion deseada: \" )\n\n        match opcion:\n            case \"1\":\n                print(\"1. Buscar contacto\")\n                if len(agenda) == 0:\n                    print(\"no hay contactos\")\n                else:\n                    buscar = input(\"introduce el nombre a buscar: \")\n                    if buscar in agenda:\n                        print (f\"el numero de telefono del contacto {buscar} es: {agenda[buscar]}\")\n                    else:\n                        print(f\"no existe el contacto {buscar}\")\n            case \"2\":\n                print(\"2. Insertar contacto\")\n                insertar()\n            case \"3\":\n                if len(agenda) == 0:\n                    print(\"no hay contactos\")\n                else:\n                    print(\"3. Actualizar contacto\")\n                    buscar = input(\"introduce el nombre del contacto a modificar: \")\n                    if buscar in agenda:\n                        insertar()\n                    else:\n                        print(f\"no existe el contacto {buscar}\")                   \n            case \"4\":\n                if len(agenda) == 0:\n                    print(\"no hay contactos\")\n                else:\n                    print(\"4. Eliminar contacto\")\n                    buscar = input(\"introduce el nombre a eliminar: \")\n                    if buscar in agenda:\n                        del agenda[buscar]\n                    else:\n                        print(f\"no existe el contacto {buscar}\")\n            case \"5\":\n                print(\"5. Salir\")\n                break\n            case _:\n                print (\"Introduce una opcion valida. Desde el 1 al 5\")\nmy_agenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/alejo-digital.py",
    "content": "# 03 ESTRUCTURA DE DATOS\n\n\"\"\"\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto\n *   en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n *   y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n *   y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no numéricos y con más\n *   de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.\n\"\"\"\n\n# Estructuras de datos en Python\n\n# Listas\nmi_lista = [1, 2, 3, 4, 5]\nmi_lista.append(6)  # Inserción\nmi_lista.remove(3)  # Borrado\nmi_lista[0] = 10  # Actualización\nmi_lista.sort()  # Ordenación\nprint(\"Mi lista es:\", mi_lista)\n# Tuplas\nmi_tupla = (1, 2, 3, 4, 5)\n# Las tuplas son inmutables, no se pueden modificar directamente\nprint(\"Mi tupla es:\", mi_tupla)\n# Conjuntos\nmi_conjunto = {1, 2, 3, 4, 5}\nmi_conjunto.add(6)  # Inserción\nmi_conjunto.discard(3)  # Borrado\nprint(\"Mi conjunto es:\", mi_conjunto)\n# Diccionarios\nmi_diccionario = {'nombre': 'Alejandro', 'edad': 30}\nmi_diccionario['edad'] = 31  # Actualización\nmi_diccionario['telefono'] = '123456789'  # Inserción\ndel mi_diccionario['nombre']  # Borrado\nprint(\"Mi diccionario es:\", mi_diccionario)\n\n# DIFICULTAD EXTRA: Agenda de contactos por terminal\n\ndef agenda_contactos():\n    agenda = {}\n\n    while True:\n        print(\"\\nAgenda de Contactos\")\n        print(\"1. Buscar contacto\")\n        print(\"2. Insertar contacto\")\n        print(\"3. Actualizar contacto\")\n        print(\"4. Eliminar contacto\")\n        print(\"5. Salir\")\n\n        opcion = input(\"Selecciona una opción: \")\n\n        if opcion == '1':\n            nombre = input(\"Introduce el nombre del contacto a buscar: \")\n            if nombre in agenda:\n                print(f\"Contacto encontrado: {nombre} - {agenda[nombre]}\")\n            else:\n                print(\"Contacto no encontrado.\")\n\n        elif opcion == '2':\n            nombre = input(\"Introduce el nombre del nuevo contacto: \")\n            telefono = input(\"Introduce el número de teléfono: \")\n            if telefono.isdigit() and len(telefono) <= 11:\n                agenda[nombre] = telefono\n                print(f\"Contacto {nombre} añadido.\")\n            else:\n                print(\"Número de teléfono no válido.\")\n\n        elif opcion == '3':\n            nombre = input(\"Introduce el nombre del contacto a actualizar: \")\n            if nombre in agenda:\n                telefono = input(\"Introduce el nuevo número de teléfono: \")\n                if telefono.isdigit() and len(telefono) <= 11:\n                    agenda[nombre] = telefono\n                    print(f\"Contacto {nombre} actualizado.\")\n                else:\n                    print(\"Número de teléfono no válido.\")\n            else:\n                print(\"Contacto no encontrado.\")\n\n        elif opcion == '4':\n            nombre = input(\"Introduce el nombre del contacto a eliminar: \")\n            if nombre in agenda:\n                del agenda[nombre]\n                print(f\"Contacto {nombre} eliminado.\")\n            else:\n                print(\"Contacto no encontrado.\")\n\n        elif opcion == '5':\n            print(\"Saliendo de la agenda, hasta pronto.\")\n            break\n\n        else:\n            print(\"Opción no válida, por favor intenta de nuevo.\")\n\n# Llamada a la función de la agenda de contactos\nagenda_contactos()\nprint(\"\\nFin del reto. ¡Sigue practicando y aprendiendo!\")"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/alejomazov.py",
    "content": "\n\n\n\n##sets \n\nmy_set = {\"Alejandro\", \"Kevin\", \"Carmenza\", 36} # no se puede ordenar y no se repiten\nmy_set.add (24)\nmy_set.add (24)\nprint (my_set)\nmy_set.remove (\"Alejandro\")\nprint(my_set)\n\n#diccionarios\n\ndiccionario = {\n    \"nombre\": \"alejandro\",\n    \"edad\":24, \n    \"apellido\":\"Mazo\"\n    }\nprint (diccionario)\n\ndiccionario[\"sexo\"] = \"Masculino\"\nprint (diccionario)\ndel diccionario[\"edad\"]\nprint (diccionario)\nprint(list(diccionario))\nprint (sorted(diccionario))\n\n\n#Tuplas\ntuplas:tuple = (\"hola\", \"Kevin\", \"Carmenza\", 36) # pueden ser de distintos tipos, pero son inmutables\nprint (tuplas[1])\n\n#Listas \n\nlista = [1,2,3,4,5,6,6] #Es mutable, se pueden repetir elementos \nlista.append (5)\nprint(lista)\nlista.sort()\nprint(lista)\nlista.pop(2)\nprint(lista)\nlista[2] = \"Fabian\"\nprint(lista)\n\n\n##extra\n\n\ncontactos = {\n    \"Nombre\":[],\n    \"Apellido\":[],\n    \"Numero\":[]\n}\ndef menu():\n    print(\"\\n      Contactos\\n\\n¿Que operacion desea realizar?\\n\\n     ----Menu----\")\n    print(\"\\n1. Agregar contacto.\\n2. Buscar contacto\\n3. Eliminar contacto.\\n4. Actualizar contacto.\\n5. Salir.\\n \")\n\ndef agregar():\n    print(\"Ingresa el nombre: \")\n    nombre = str(input())\n    contactos[\"Nombre\"].append(nombre)\n    print(\"Ingresa el apellido: \")\n    apellido = str(input())\n    contactos[\"Apellido\"].append(apellido)\n    while True:\n        print(\"Ingresa el numero de telefono: \")\n        try:\n            numero = int(input())\n            numero_str = str(numero)\n            count = len(numero_str)\n            if count <= 11:\n                contactos[\"Numero\"].append(numero)\n                print (\"contacto agregado\")\n                break\n            else:\n                print (\"Ingrese un numero de 11 digitos\")\n        except ValueError as e:\n            print(f\"Ingrese un numero correcto.... error {e}\")\n\n\ndef buscar():\n    nombre = str(input(\"Ingrese el nombre de contacto que desea buscar:\\n\"))\n    apellido = str(input(\"ingrese el apellido del contato que desea buscar:\\n\"))\n\n    for nombres, apellidos, numeros in zip(contactos[\"Nombre\"],contactos[\"Apellido\"],contactos[\"Numero\"]):\n        if nombre == nombres and apellido == apellidos:\n            print (nombres,apellidos, numeros)\n\n\ndef eliminar():\n    nombre = str(input(\"Ingrese el nombre del contacto que desea eliminar:\\n\"))\n    apellido = str(input(\"ingrese el apellido del contato que desea eliminar:\\n\"))\n\n    for nombres, apellidos, numeros in zip(contactos[\"Nombre\"],contactos[\"Apellido\"],contactos[\"Numero\"]):\n        if nombre == nombres and apellido == apellidos:\n            contactos[\"Nombre\"].remove(nombre)\n            contactos[\"Apellido\"].remove(apellido)\n            contactos[\"Numero\"].remove(numeros)\n\n\n            print(\"Usuario eliminado\")\n\ndef actualizar():\n    nombre = str(input(\"Ingrese el nombre del contacto que desea actualizar:\\n\"))\n    apellido = str(input(\"ingrese el apellido del contato que desea actualizar:\\n\"))\n\n    for i in range(len(contactos[\"Nombre\"])):\n     if nombre == contactos[\"Nombre\"][i] and apellido == contactos[\"Apellido\"][i]:\n         update_tel = int(input(\"Ingrese el numero nuevo: \"))\n         contactos[\"Numero\"][i] = update_tel\n         print(\"Contacto actualizado\")\n         return\n\n\n\ndef salir():\n    print(\"Saliendo...\")\n\n\n\nwhile True:\n    menu()\n    opcion= int(input())\n    if opcion > 5 or opcion < 1:\n        print(\"Seleccione una opcion del menu\")\n    else:\n        if opcion == 1:\n            agregar()    \n        elif opcion == 2:\n            buscar()\n        elif opcion == 3:\n            eliminar()\n        elif opcion == 4:\n            actualizar()\n        elif opcion == 5:\n            salir()\n            break    \n        else:\n            print(\"Selecione una opcion correcta\")\n\n        \n\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/alexdevrep.py",
    "content": "'''\n/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n'''\n\n# Listas \n\n#Creación de una lista\nmi_lista = [1,2,3,4,5,6]\n\n#Inserción de un elemento en la lista\nmi_lista.append(7) \nprint(\"Esta es la lista con un valor nuevo añadido:\",mi_lista)\n\n#Borrado de un elemento de la lista \nmi_lista.remove(3)\nprint(\"Esta es la lista pero con el número tres quitado:\",mi_lista)\n\n#Actualización de la lista \nmi_lista[3]= 33 # ahora el 4º elemento de la lista será 33\nprint(\"Hemos cambiando el valor del número que ocupa la 4º plaza por 33\", mi_lista)\n#Ordenación de la lista\nmi_lista.sort()\nprint(\"Aquí tenemos la lista ordenada de menor a mayor\", mi_lista)\n\nprint(\"/----------------/\")\n#Tuplas\n\n#Creación de una tupla \nmi_tupla = (1,2,3,4,5,6)\n\n#Inserción de un elemento en la tupla\nnumero = 18 #las tuplas son inmutables por lo que para añadir un nuevo elemento debemos crear una\nnueva_tupla = mi_tupla + (numero,) \nprint (\"así añadimos un nuevo elemento a una tupla\",nueva_tupla)\n\n#Borrado de un elemento de la tupla \nnumero_a_eliminar = 3 #las tuplas son inmutables por lo que para eliminar un elemento debemos crear una\nmi_tupla_2 = tuple(x for x in mi_tupla if x != numero_a_eliminar)\nprint(\"esta es una tupla nueva sin el número 3\",mi_tupla_2)\n\n#Actualización de la tupla \nnumero_actualizado = 33 #las tuplas son inmutables por lo que para actualizar un elemento debemos crear una\nmi_tupla_3 = tuple (numero_actualizado if x == 1 else x for x in mi_tupla)\nprint(\"esta es una tupla nueva pero cambiando el 1 por un 33\", mi_tupla_3)\n\n#Ordenación de la tupla\ntupla_ordenada = tuple(sorted(list(mi_tupla_3)))\nprint (\"esta es la tupla anterior ordenada de menor a mayor\",tupla_ordenada)\n\nprint(\"/----------------/\")\n#conjuntos (los diccionarios se crean igual pero los elementos son pares clave-valor)\n\n#Creacción de un conjunto\nmi_conj = {1,2,3,4,5,6} \n\n#Inserción de un elemento en el conjunto\nmi_conj.add(9)\nprint(\"Este es el conjunto con un valor nuevo añadido:\",mi_conj)\n\n#Borrado de un elemento del conjunto  \nmi_conj.remove(3)\nprint(\"Este es el conjunto pero con el número tres quitado:\",mi_conj)\n\n#Actualización del conjunto\nmi_conj.remove(1)\nmi_conj.add (33)\nprint(\"para actualizar un conjunto hay que quitar y añadir un numero\",mi_conj)\n#Ordenación del conjunto\nconjuto_ordenado = set(sorted(list(mi_conj)))\nprint(\"esta es la manera de ordenar un conjunto\",conjuto_ordenado)\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/andres54-coder.py",
    "content": "'''\nEstructuras de datos en Python\n'''\n\n# Listas\n# Las listas son colecciones ordenadas de elementos que pueden ser de cualquier tipo\n\nmy_list = [\"Hola\", \"hi\", \"hello\", \"ciao\"]\nprint(my_list)\nmy_list.append(\"salut\") # Agrega un elemento al final de la lista\nprint(my_list)\nmy_list.remove(\"hi\") # Elimina un elemento de la lista\nprint(my_list)\nprint(my_list[0]) # Accede al primer elemento de la lista\nmy_list[0] = \"Hola!\" # Modifica el primer elemento de la lista\nprint(my_list)\n\n# Tuplas\n# Las tuplas son colecciones ordenadas de elementos que no pueden ser modificadas\nmy_tuple: tuple = (\"Hola\", \"hi\", \"@hello\", \"22\")\nprint(my_tuple)\nprint(my_tuple[0]) # Accede al primer elemento de la tupla\nmy_tuple = tuple(sorted(my_tuple)) # Ordena los elementos de la tupla\nprint(my_tuple)\n\n#sets\n# Los sets son colecciones no ordenadas de elementos únicos\nmy_set = {\"Hola\", \"hi\", \"hello\", \"ciao\", \"22\"}\nprint(my_set)\nmy_set.add(\"salut\") # Agrega un elemento al set\nprint(my_set)\nmy_set.remove(\"hi\") # Elimina un elemento del set\nprint(my_set)\nmy_set = set(sorted(my_set)) # el set no se pued ordenar\nprint(my_set)\n\n# Diccionarios\n\nmy_dict : dict = { \"spanish\":\"Hola\", \"english\":\"hi\", \"english\":\"@hello\",\"number\": \"22\"}\nprint(my_dict[\"english\"])\nmy_dict[\"french\"] = \"salut\" # Agrega un elemento al diccionario\nprint(my_dict)\nmy_dict[\"number\"] = \"33\" # Modifica un elemento del diccionario\nprint(my_dict)\ndel my_dict[\"english\"] # Elimina un elemento del diccionario\nprint(my_dict)\nmy_dict = dict(sorted(my_dict.items())) # Ordena los elementos del diccionario\nprint(my_dict)\n\n'''\nExtra\n'''\n\ndef my_agenda():\n    agenda = {}\n    def insert_contact( ):\n        phone = input(\"Introduce el nuevo teléfono: \")\n        if phone.isdigit() and len(phone) > 0 and len(phone) <= 11:\n            agenda[name] = phone\n        else:\n            print(\"Debes introducir un número de teléfono válido menor a 11 dígitos\")\n    while True:\n        print(\"\")\n        print(\"1. Buscar contacto\")\n        print(\"2. Insertar contacto\")\n        print(\"3. Actualzar contacto\")\n        print(\"4. Eliminar contacto\")\n        print(\"5. Salir\")\n        option = input(\"\\nSeleccione una opción: \")\n        match option:\n            case \"1\":\n                name = input(\"Introduce el nombre: \")\n                if name in agenda:\n                    print(f\"{name}: {agenda[name]}\")\n                else:\n                    print(\"Contacto no encontrado\")\n            case \"2\":\n                name = input(\"Introduce el nombre: \")\n                insert_contact()\n            case \"3\":\n                name = input(\"Introduce el nombre: \")\n                if name in agenda:\n                    insert_contact()\n                else:\n                    print(\"Contacto no encontrado\")\n            case \"4\":\n                name = input(\"Introduce el nombre: \")\n                if name in agenda:\n                    del agenda[name]\n                    print(\"Contacto eliminado\")\n                else:\n                    print(\"Contacto no encontrado\")\n            case \"5\":\n                print(\"Saliendo de la agenda\")\n                break\n            case _:\n                print(\"Opción no válida\")\n                my_agenda()\nmy_agenda() # Llama a la función my_agenda"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/andresgcastillo.py",
    "content": "# Listas\nlista = [1, 2, 3, 4, 5]\nlista.append(6)  # Inserción\nlista.remove(1)  # Borrado\nlista[0] = 7  # Actualización\nlista.sort(reverse=True)  # Ordenación\nprint(\"Lista:\", lista)\n\n# Tuplas\ntupla = (1, 2, 3, 4, 5)\n# Las tuplas son inmutables, por lo que no se pueden insertar, borrar o actualizar elementos\nprint(\"Tupla:\", tupla)\n\n# Conjuntos\nconjunto = {1, 2, 3, 4, 5}\nconjunto.add(6)  # Inserción\nconjunto.remove(1)  # Borrado\n# Los conjuntos son inmutables, por lo que no se pueden actualizar elementos\n# Los conjuntos no mantienen un orden, por lo que no se pueden ordenar\nprint(\"Conjunto:\", conjunto)\n\n# Diccionarios\ndiccionario = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}\ndiccionario['f'] = 6  # Inserción\ndel diccionario['a']  # Borrado\ndiccionario['b'] = 7  # Actualización\ndiccionario = dict(sorted(diccionario.items()))  # Ordenación\nprint(\"Diccionario:\", diccionario)\n\n#Dificultad Extra\nagenda = {}\n\nwhile True:\n    print(\"\\n1. Insertar contacto\")\n    print(\"2. Buscar contacto\")\n    print(\"3. Actualizar contacto\")\n    print(\"4. Eliminar contacto\")\n    print(\"5. Salir\")\n\n    opcion = input(\"\\nElige una opción: \")\n\n    if opcion == '1':\n        nombre = input(\"Introduce el nombre del contacto: \")\n        telefono = input(\"Introduce el número de teléfono del contacto: \")\n        if not telefono.isdigit() or len(telefono) > 11:\n            print(\"Número de teléfono no válido\")\n        else:\n            agenda[nombre] = telefono\n\n    elif opcion == '2':\n        nombre = input(\"Introduce el nombre del contacto a buscar: \")\n        if nombre in agenda:\n            print(\"El número de teléfono es\", agenda[nombre])\n        else:\n            print(\"Contacto no encontrado\")\n\n    elif opcion == '3':\n        nombre = input(\"Introduce el nombre del contacto a actualizar: \")\n        if nombre in agenda:\n            telefono = input(\"Introduce el nuevo número de teléfono: \")\n            if not telefono.isdigit() or len(telefono) > 11:\n                print(\"Número de teléfono no válido\")\n            else:\n                agenda[nombre] = telefono\n        else:\n            print(\"Contacto no encontrado\")\n\n    elif opcion == '4':\n        nombre = input(\"Introduce el nombre del contacto a eliminar: \")\n        if nombre in agenda:\n            del agenda[nombre]\n        else:\n            print(\"Contacto no encontrado\")\n\n    elif opcion == '5':\n        break\n\n    else:\n        print(\"Opción no válida\")"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/angelsanchezt.py",
    "content": "\"\"\"\n * EJERCICIO: ESTRUCTURAS DE DATOS\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n\"\"\"\nprint(\"EJERCICIO: ESTRUCTURAS DE DATOS\")\n\n\"\"\"\nListas\n\"\"\"\nprint(\"LISTAS\")\nmy_list: list = [\"Nueva York\", \"Tokio\", \"Londres\", \"París\", \"Shanghai\"]\nprint(my_list)\n\n# Inserción: Adicionar un item al fian de la lista\nmy_list.append(\"Beijing\") \nmy_list.append(\"Moscú\")\nprint(f\"La lista despues de insertar las ciudades de Beijin y Moscú: {my_list}\")\n\n# Eliminar un item de la lista\nmy_list.remove(\"Tokio\")\nprint(f\"La lista despues de eliminar la ciudad Tokio: {my_list}\")\n\n# Actualización de un item de la lista\nmy_list[3] = \"Dubai\"\nprint(f\"La lista despues de actualizar la posición 3: {my_list}\")\n\n# Ordenacion\nmy_list.sort()\nprint(f\"La lista ordenada es: {my_list}\") \n\n# Buscar el valor de una posición de la lista\nprint(f\"El elemento 'Nueva York' esta en la posición: {my_list.index('Nueva York')}\")\n\n# Invertir la lista:\nmy_list.reverse()\nprint(f\"la Lista ordenada de forma inversa es: {my_list}\")\n\n# Imprimir el tipo de objeto de la list\nprint(f\"El tipo de la lista es: {type(my_list)}\")\nprint(\"\\n\")\n\n\"\"\"\nTuplas\n\"\"\"\nprint(\"Tupla\")\n# Definición de una tupla\nmy_tuple: tuple = (\"manzana\", \"plátano\", \"naranja\", \"fresa\", \"uva\")\n\n# Imprimir la tupla\nprint(my_tuple)\n\nprint(my_tuple[1])  # Acceso\n\nprint(my_tuple[3])\n\nmy_tuple = tuple(sorted(my_tuple))  # Ordenación\nprint(my_tuple)\n\nprint(type(my_tuple))\nprint(\"\\n\")\n\n\"\"\"\nSets\n\"\"\"\nprint(\"SETS\")\n# Definición de un set\nmy_set: set = {\"Nueva York\", \"Tokio\", \"Londres\", \"París\", \"Shanghai\"}\n\n# Imprimir el set\nprint(my_set)\n\nmy_set.add(\"Moscú\")  # Inserción\nmy_set.add(\"Moscú\")\nprint(my_set)\nmy_set.remove(\"Shanghai\")  # Eliminación\nprint(my_set)\n\nmy_set = set(sorted(my_set))  # No se puede ordenar\nprint(my_set)\n\nprint(type(my_set))\n\n# Diccionario\n# Definición de un diccionario\nmy_dict: dict = {\n    \"nombre\": \"Juan\",\n    \"apellido\" : \"Casas\",\n    \"edad\": 30,\n    \"ciudad\": \"Madrid\",\n    \"profesión\": \"Ingeniero\"\n}\n\n# Imprimir el diccionario\nprint(my_dict)\n\nmy_dict[\"email\"] = \"juan.casas@gmail.com\"  # Inserción\nprint(my_dict)\n\ndel my_dict[\"apellido\"]  # Eliminación\nprint(my_dict)\n\nprint(my_dict[\"nombre\"])  # Acceso\n\nmy_dict[\"edad\"] = 36  # Actualización\nprint(my_dict)\n\nmy_dict = dict(sorted(my_dict.items()))  # Ordenación\nprint(my_dict)\n\nprint(type(my_dict))\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n \"\"\"\n\n\ndef my_agenda():\n\n    agenda = {}\n\n    def insert_contact():\n        phone = input(\"Introduce el teléfono del contacto: \")\n        if phone.isdigit() and len(phone) > 0 and len(phone) <= 11:\n            agenda[name] = phone\n        else:\n            print(\n                \"Debes introducir un número de teléfono un máximo de 11 dígitos.\")\n\n    while True:\n\n        print(\"\")\n        print(\"1. Buscar contacto\")\n        print(\"2. Insertar contacto\")\n        print(\"3. Actualizar contacto\")\n        print(\"4. Eliminar contacto\")\n        print(\"5. Salir\")\n\n        option = input(\"\\nSelecciona una opción: \")\n\n        match option:\n            case \"1\":\n                name = input(\"Introduce el nombre del contacto a buscar: \")\n                if name in agenda:\n                    print(\n                        f\"El número de teléfono de {name} es {agenda[name]}.\")\n                else:\n                    print(f\"El contacto {name} no existe.\")\n            case \"2\":\n                name = input(\"Introduce el nombre del contacto: \")\n                insert_contact()\n            case \"3\":\n                name = input(\"Introduce el nombre del contacto a actualizar: \")\n                if name in agenda:\n                    insert_contact()\n                else:\n                    print(f\"El contacto {name} no existe.\")\n            case \"4\":\n                name = input(\"Introduce el nombre del contacto a a eliminar: \")\n                if name in agenda:\n                    del agenda[name]\n                else:\n                    print(f\"El contacto {name} no existe.\")\n            case \"5\":\n                print(\"Saliendo de la agenda.\")\n                break\n            case _:\n                print(\"Opción no válida. Elige una opción del 1 al 5.\")\n\n\nmy_agenda()\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/annnerssv.py",
    "content": "#----LISTAS----\n\nmi_lista_nombres = [\"Jhan\", \"Awasa\", \"Bryan\", \"PanaMiguel\"] #Lista de cadena\nmi_lista_numeros = [21, 20, 19, 22] #Lista de numeros \n\n#--Listas anidadas--\nmi_lista_de_listas = [[1,2,3], [4,5,6],[7,8,9]] #Lista de listas de numeros\nmi_lista_mixta = [\"Jhan\", 19, [2,0,0,3]] #Lista mixta de cadenas, numero y lista\nmi_lista_de_diccionarios = [{\"nombre\" : \"jhan\", \"edad\": \"21\"}] #Lista de diccionarios\nmi_lista_de_tuplas = [(1,2,3), (3,4,5)] #Lista de Tuplas\n\n\n#-Metodos de Listas-\nprint(mi_lista_nombres) #Imprimimos la lista antes de usar los metodos\nmi_lista_nombres.append(\"Gabriel\") #Insertar elementos a una lista\nprint(mi_lista_nombres)\nmi_lista_nombres.remove(\"Jhan\") #Remover elementos de una lista\nprint(mi_lista_nombres)\nmi_lista_nombres[0] = \"Antonio\" #Acceder a la posición del elemento de una lista y modificarlo\nprint(mi_lista_nombres)\nmi_lista_nombres.sort() #Ordenar de menor a mayor o en orden alfabetico\nprint(mi_lista_nombres)\n\n\nprint(\"-------------------------------------------------------------------------------------------\")\n\n#----TUPLAS---- \n\nmi_tupla = (\"Hola\", \"soy\",\"una\",\"tupla\")\nmi_tupla_anidada = (\"Hola\", [1,2,3], 4, {'clave': 'valor'}) \nprint(type(mi_tupla))\nprint(mi_tupla)\nprint(mi_tupla_anidada)\nprint(mi_tupla[2]) #Acceso al elemento de una tupla\n\n#--Convertir lista a tupla--\n\nmi_lista_a_tupla = [\"Lista\", \"convertida\", \"a\", \"tupla\"]\nprint(mi_lista_a_tupla)\nprint(tuple(mi_lista_a_tupla))\n\n\n\n#----SETS----\n\nmi_set = {\"Hola\", \"soy\", \"un\", \"set\"}\nprint(mi_set)\nmi_set.add(\"nuevo\") #Insertar un nuevo elemento a un set\nprint(mi_set)\nmi_set.remove(\"Hola\") #Eliminar un elemento de un set\nprint(type(mi_set))\nmi_primer_set = {1,2,3}\nmi_segundo_set = {4,5,6}\n\nprint(mi_primer_set|mi_segundo_set) #Union de 2 sets\n\n\n#----DICCIONARIOS----\n\nmi_diccionario = {'nombre':'Jhan', 'edad': 22, 'correo':'jhan.aries.jp@gmail.com'}\nprint(mi_diccionario)\nprint(type(mi_diccionario))\n\nprint(mi_diccionario[\"nombre\"]) #Acceso al valor nombre del diccionario \n\nmi_diccionario['usuario'] = 'Pier' #Añadir un nuevo elemento de clave - valor al diccionario\nprint(mi_diccionario)\n\nmi_diccionario['nombre'] = 'Aries' #Modifición de un valor del diccionario\nprint(mi_diccionario)\n\ndel mi_diccionario['usuario'] #Eliminación de un elemento de clave - valor del diccionario \nprint(mi_diccionario)\n\n\n\n\n#----EJERCICIO EXTRA----\n\ncontactos = {}\n\n\ndef añadirContacto(): \n    telefono = input('Ingrese el numero de telefono del contacto: ')\n    if telefono.isdigit() and len(telefono) > 0 and len(telefono) <= 11:\n        contactos[nombre] = telefono\n        print(contactos)\n    else:\n        print('Ingresa un numero de telefono valido')\n\n\ndef buscarContacto():\n    nombre = input('Ingresa el nombre del contacto a buscar: ')\n    if nombre in contactos:\n        print(f'Contacto encontrado  \\n Nombre:{nombre}\\n Telefono: {contactos[nombre]}')\n    else:\n        print(f'El contacto {nombre} no se encuentra en la lista')\n\ndef actualizarContacto():\n    nombre = input('Ingrese el nombre del contacto a atualizar')\n    if nombre in contactos:\n        añadirContacto()\n    else:\n        print('Ingresa un contacto valido')\n\ndef eliminarContacto():\n    nombre = input('Ingresa el nombre del contacto a eliminar')\n\n    if nombre in contactos:\n        del contactos[nombre]\n        print('Contacto eliminado correctamente...')\n    else:\n        print('El contacto a eliminar no existe')\n    \n\n\nsalir = False\n\nwhile not salir:\n    \n    print('''---Bienvenido a la agenda de contactos,¿Qué actividad deseas realizas?---\n        1. Añadir un contacto\n        2. Buscar un contacto\n        3. Actualizar un contacto\n        4. Eliminar un contacto\n        5. Listar contactos\n        6. Salir\n''')\n    \n    opcion = int(input(\"Elige una opcion: \"))\n\n    if __name__ == '__main__':\n        if opcion == 1:\n            nombre = input('Ingresa el nombre del contacto')\n            añadirContacto()\n        elif opcion == 2:\n            buscarContacto()\n        elif opcion == 3:\n            actualizarContacto()\n        elif opcion == 4:\n            eliminarContacto()\n        elif opcion == 5:\n            print(contactos)\n        elif opcion == 6:\n            print('Saliendo del Sistema...')\n            salir = True\n        else:\n            print('Ingrese una opción valida')\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/any7dev.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */ \"\"\"\n\n# LISTAS\nlista = [1, 2, 3, 4] # También -> lista = list(\"1234\")\nprint(lista)\n\n# Insercción al final de la lista\nlista.append(5)\nprint(lista)\n# Insercción en índice indicado\nlista.insert(2, 2.5)\nprint(lista)\n# Insercción de lista\nlista.extend([0, 7, 8])\nprint(lista)\n\n# Actualizar elemento\nlista[6] = 6\nprint(lista)\n\n# Borra elemento dado\nlista.remove(2.5)\nprint(lista)\n# Borra elemento según posición\ndel lista[4]\nprint(lista)\n# Borra el último elemento de la lista\nlista.pop()\nprint(lista)\n\n# Invierte la lista\nlista.reverse()\nprint(lista)\n# Ordena la lista\nlista.sort()\nprint(lista)\n\n# Borra toda la lista\nlista.clear()\nprint(lista)\n\n\n# TUPLAS\ntupla = (1, 2, 3) # También -> tupla = 1, 2, 3\nprint(tupla)\n\n\n# SETS (CONJUNTOS)\nconjunto = {1, 7, 6, 5, 8, 2} # También -> conjunto = set([1, 7, 6, 5, 8, 2])\nprint(conjunto)\n\n# Añade elemento al final\nconjunto.add(9)\nprint(conjunto)\n# Añade varios elementos y si está, no hace nada\nconjunto.update([9, 3, 5, 4])\nprint(conjunto)\n\n# Eliminar elemento dado\nconjunto.remove(6)\nprint(conjunto)\n# Eliminar elemento dado y no hace nada si no existe\nconjunto.discard(6)\nprint(conjunto)\n# Elimina elemento aleatorio\nconjunto.pop()\nprint(conjunto)\n# Borra todo el set\nconjunto.clear()\nprint(conjunto)\n\n\n# DICCIONARIOS\ndiccionario = {\"Nombre\": \"Ana\", \"Edad\": 37, \"Teléfono\": 412567} # También -> diccionario = dict([(\"Nombre\", \"Ana\"), (\"Edad\", 37), (\"Teléfono\", 412567)])\nprint(diccionario)                                                         # diccionario = dict(Nombre= \"Ana\", Edad= 37, Teléfono= 412567)\n\n# Actualizar elemento\ndiccionario[\"Teléfono\"] = 421576 \nprint(diccionario)\n# Si no existe, se crea\ndiccionario[\"Dirección\"] = \"Calle Rumbo\"\nprint(diccionario)\n# Actualizar elemento\ndiccionario.update({\"Teléfono\": 423576}) \nprint(diccionario)\n# Si no existe, se crea\ndiccionario.update({\"Profesión\":\"Estudiante\"})\nprint(diccionario)\n\n# Borra la clave indicada con su valor\ndiccionario.pop(\"Edad\")\nprint(diccionario)\n# Borra de forma aleatoria un elemento\ndiccionario.popitem()\nprint(diccionario)\n# Borra el diccionario\ndiccionario.clear()\nprint(diccionario)\n\n\n\n# DIFICULTAD EXTRA\ndef menu():\n    while True:\n        print(f\"\\n\\t1-Mostrar Agenda\\n\\t2-Buscar contacto\\n\\t3-Insertar o actualizar contacto\\n\\t4-Borrar contacto\\n\\t5-Salir\")    \n        opcion = input(f\"\\nEscribe el número de la opción a realizar: \")\n        match opcion:\n            case \"1\": \n                  mostrar()\n            case \"2\":\n                  buscar()\n            case \"3\": \n                  insertar()\n            case \"4\": \n                    borrar()\n            case \"5\": \n                print(f\"Saliendo de la agenda\\n\")\n                break                   \n            case _: \n                  print(\"Opción incorrecta\")\n\ndef mostrar():\n    if not agenda:\n        print(f\"Agenda Vacía {agenda}\")\n    else:\n        for clave, valor in agenda.items():\n            print(f\"{clave}-{valor}\")\n\ndef buscar():\n    if not agenda:\n        print(f\"Agenda Vacía {agenda}\")\n    else:\n        contacto = input(\"Dime el nombre a buscar: \")\n        contacto = agenda.get(contacto, \"Contacto no encontrado\")     \n        print(f\"\\t\\t\\t {contacto}\")      \n\ndef insertar():\n    while True:\n        nombre = input(f\"Dime el nombre: \")\n        if nombre and not nombre.isnumeric():\n            if nombre in agenda:\n                print(\"Contacto encontrado, lo vas a actualizar\")\n            else:\n                print(\"Vas a crear un nuevo contacto\")\n            while True:\n                telefono = input(f\"Teléfono: \")\n                if telefono and telefono.isnumeric() and len(telefono) == 9:\n                    agenda[nombre] = telefono\n                    break\n                else:\n                    print(\"Error: No se cumplen las validaciones. El teléfono debe ser número entero y tener 9 dígitos\")\n            break\n        else:\n            print(\"Error: No se cumplen las validaciones. El contacto debe tener un nombre no numérico\")\n        \ndef borrar():\n    if not agenda:\n        print(f\"Agenda Vacía {agenda}\")\n    else:\n        nombre = input(f\"Dime el nombre: \")\n        agenda.pop(nombre, \"Contacto no encontrado\")     \n        \n                     \n\nif __name__ == '__main__':\n    global agenda\n    agenda = {}\n    menu()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/augustdev2003.py",
    "content": "\"\"\"Estructuras de datos\"\"\"\n\n# LISTAS\n\nlist()  # Crea una lista vacía\n\nempty_list = []\n\nlanguages = ['Python', 'JavaScript', 'Go', 'PHP']\n\nfibonacci = [0, 1, 1, 2, 3, 5, 8, 13]\n\ndata = ['Tenerife', {\"cielo\": \"limpio\", \"temp\": 25},\n        453, (28.1283971, -16.57372)]\n\n# Conversión desde cadena de texto\n\nprint(list('Python'))\n\n# Conversión a partir de un rango\n\nprint(list(range(0, 10)))\n\n# Operaciones en listas\n\ndata.append('Python')  # Inserción\ndata.append(12)\nprint(data)\ndata.insert(1, 'Argentina')  # Inserción mediante índice\ndata[1] = 'España'  # Actualización\nprint(data)\n# Cuatro formas de borrar elementos de ua lista\ndel data[2]  # Por su índice\nprint(data)\ndata.remove('España')  # Por su valor\nprint(data)\n# Por índice(extracción) - .pop() no solo borra un elemento sino que nos ayuda a recuperar el elemento\nelement = data.pop()\nprint(element)\nprint(data)\ndata[1:3] = []  # Por su rango\nprint(data)\n# Ordenación - sorted() NO modifica la lista original, crea una nueva.\nsorted(languages)\nprint(languages)\nlanguages.sort()  # .sort() SI modifica la lista original\n# Tanto .sort() como sorted() aceptan un parámetro 'reverse' para indicar la forma en que se ordena\nsorted(languages, reverse=True)\nprint(languages)\n\n# TUPLAS\n\nempty_tuple = ()\n\ntenerife_geoloc = (28.46824, -16.25462)\n\nthree_countries = ('Argentina', 'España', 'Chile')\n\n# Para crear una tupla con un único elemento, tendremos que hacerlo de la siguiente forma:\n\none_item_tuple = ('Python',)\n\n# Las tuplas son inmutables, esto quiere decir que no podemos modificarlas,\n# eliminar elementos, ni agregar.\n\nprint(tuple(sorted(three_countries)))  # Ordenación\n\n# DICCIOONARIOS\n\nempty_dict = {}\n\nmy_dict = {\n    \"name\": 'Augusto',\n    \"surname\": 'Ojeda Rosso',\n    \"age\": 20,\n}\nprint(my_dict)\n\nperson = dict(\n    name='Juan',\n    surname='Rodriguez',\n    age=30,\n)\nprint(person)\n\n# Es posible crear un diccionario especificanod sus claves y un valor único\n\nunique_value = dict.fromkeys('abcdef', 1)\nprint(unique_value)\n\n# Operaciones en diccionarios\n\nperson['job'] = 'Data scientist'  # Inserción\nprint(person)\nperson['job'] = 'Backend Developer'  # Actualización\ndel person['surname']  # Eliminación\nprint(person)\nsorted_dict = dict(sorted(person.items()))  # Ordenación\nprint(sorted_dict)\n\n# SETS\n\nlottery = {32, 10, 23, 1, 8}\nprint(lottery)\n\n# La única forma de crear un set vacío es de la siguiente manera:\nmy_set = set()\nprint(my_set)\n\n# Operaciones con sets\n\nlottery.add(14)  # Inserción\nprint(lottery)\nlottery.remove(1)  # Eliminación\nprint(lottery)\nsorted(lottery)  # No se puede ordenar\nprint(lottery)\n\n\"\"\"\nExtra\n\"\"\"\n\n\ndef agenda():\n    agenda = {}\n\n    def insert_contact():\n        phone_number = input(\"Introduce tu número de teléfono: \")\n        if phone_number.isdigit() and len(phone_number) > 0 and len(phone_number) <= 11:\n            agenda[insert_name] = phone_number\n        else:\n            print('Introduce un número de teléfono con un máximo de 11 digitos')\n\n    while True:\n        print(\n            \"\"\"\n            1- Buscar contacto.\n            2- Insertar contacto.\n            3- Actualizar contacto.\n            4- Eliminar contacto.\n            5- Salir.\n            \"\"\"\n        )\n        option = input(\"\\nSelecciona una opción: \")\n        print(option)\n\n        match option:\n            case \"1\":\n                insert_name = input(\n                    \"Introduce el nombre del contácto a buscar: \")\n                if insert_name in agenda:\n                    print(\n                        f'El número de teléfono de {insert_name} es {agenda[insert_name]}.')\n                else:\n                    print(\n                        f'El número de teléfono de {insert_name} no está registrado.')\n\n            case \"2\":\n                insert_name = input(\n                    \"Introduce el nombre del contácto a registrar: \")\n                if insert_name == \"\":\n                    print(insert_name)\n                else:\n                    insert_contact()\n\n            case \"3\":\n                insert_name = input(\n                    \"Introduzca el nombre del contácto para actualizar: \")\n                if insert_name in agenda:\n                    insert_contact()\n                else:\n                    print(f'El contacto {insert_name} no existe.')\n\n            case \"4\":\n                insert_name = input(\n                    \"Introduce el nombre del contácto a eliminar: \")\n                if insert_name in agenda:\n                    del agenda[insert_name]\n                else:\n                    print(f'El contacto {insert_name} no existe')\n\n            case \"5\":\n                print(\"Saliendo de la agenda.\")\n                break\n\n            case _:\n                print(\"Opción no válida, elige una opción correcta.\")\n\n\nagenda()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/avcenal.py",
    "content": "\"\"\"\nESTRUCTURAS DE DATOS\n\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n\"\"\"\n\n\"\"\"\nLISTAS\n\"\"\"\nprint(\"\\n\")\nprint(\"LISTAS\")\n#Deben contener el mismo tipo de dato\nmy_integer_list = [1,4,18,23,89,55,73,18]\nmy_string_list = [\"Alex\",\"Valderrama\",\"Cenalmor\",\"Sole\",\"González\"]\n\n#Búsqueda\nprint(\"Búsqueda\")\nprint(f\"Con la función index() podemos buscar un elemento en la lista y obetener su posición. \\\"Valderrama\\\" por ejemplo se encuentra en la posición {my_string_list.index(\"Valderrama\")} de my_string_list\")\nprint(f\"También con count() podemos buscar las ocurrencias de un elemento dentro de la lista, por ejemplo el 18 en my_integer_list aparece: {my_integer_list.count(18)} veces\")\n\n#Inserción\nprint(\"\\n\")\nprint(\"Inserción\")\nmy_integer_list.insert(3,33)\nprint(f\"Mediante .insert(), se \\\"inserta\\\" un 33 en la posición 3 de my_integer_list: {my_integer_list}\")\nmy_string_list.append(\"Velasco\")\nprint(f\"También se puede añadir un nuevo elemento al final con append(), por ejemplo, la cadena \\\"Velasco\\\" al final de my_string_list: {my_string_list}\")\nmy_other_integer_list = [2,62,47]\nmy_integer_list.extend(my_other_integer_list)\nprint(f\"Podemos añadir a la lista my_integer_list una nueva lista my_other_integer_list {my_other_integer_list} con el método extend(): {my_integer_list}\")\n\n#Actualización\nprint(\"\\n\")\nprint(\"Actualización\")\nmy_integer_list[3] = 99\nprint(f\"Podemos actualizar un elemento de la lista mediante su índice, por ejemplo inclimos el \\\"99\\\" en la posición 3 de my_integer_list: {my_integer_list}\")\n\n#Ordenación\nprint(\"\\n\")\nprint(\"Ordenación\")\nmy_integer_list.sort()\nmy_string_list.sort()\nprint(f\"Las listas son estructuras iterables que se pueden ordenar con la función sort(). my_integer_list quedaría ordenada así: {my_integer_list}\")\nprint(f\"Y my_string_list quedaría asi: {my_string_list}\")\n\n\n#Borrado\nprint(\"\\n\")\nprint(\"Borrado\")\nerased_integer = my_integer_list.pop()\nerased_string = my_string_list.pop()\nprint(f\"Podemos usar el método pop() para quitar el último elemento de la lista y guardarlo, por ejemplo ejecutándolo en my_integer_list, quitamos {erased_integer} y la lista queda {my_integer_list}\")\nprint(f\"Igual para my_string_list, con pop() quito {erased_string} y la lista queda: {my_string_list}\")\nerased_string = my_string_list.pop(1)\nprint(f\"O podemos indicar el índice del elemento a desapilar, por ejemplo ejecutando my_string_list.pop(1), quito \\\"{erased_string}\\\" y la lista queda {my_string_list}\")\nmy_integer_list.remove(18)\nprint(f\"Con remove() puedo elimitar un item concreto, por ehjemplo, borro un \\\"18\\\" de my_integer_list: {my_integer_list}\")\nmy_string_list.clear()\nprint(f\"También podemos borrar el contenido de la lista con clear(), si lo ejecuto en my_string_list: {my_string_list} queda una lista vacía\")\n\n\"\"\"\nTUPLAS\n\"\"\"\n#Al ser estructuras inmutables no se pueden realizar operaciones de actualización, borrado o inserción. Tampoco de ordenación.\n#Podríamos modificar la tupla pasándola a una lista y usar las operaciones anteriores\nprint(\"\\n\")\nprint(\"TUPLAS\")\nprint(\"Búsqueda\")\nmy_tuple = (38, 1.82,\"Alex\",\"Valderrama\")\n\nprint(f\"No existe una función de búsqueda como tal, aunque podemos obtener el índice de un elemento de la tupla con index(), por ejemplo \\\"Valderrama\\\" está en el índice {my_tuple.index(\"Valderrama\")}\")\nprint(f\"O con count() podemos ver las ocurrencias de un elemento de la tupla, por ejemplo el número 38 aparece {my_tuple.count(38)}\")\nprint(f\"Y podemos acceder a sus elementos con el íncide, como en las lístas, por tanto my_tuple[2] = {my_tuple[2]}\")\n\n\"\"\"\nSETS\n\"\"\"\nprint(\"\\n\")\nprint(\"SETS\")\n\nmy_set = {38, 1.82,\"Alex\",\"Valderrama\"}\n#Al ser estrucuras no ordenadas, no se pueden acceder a los elementos u ordenar\n\n#Búsqueda: no hay un método como tal, se tiene que hacer con operadores de pertenencia como \"in\"\nprint(\"\\n\")\nprint(\"Búsqueda\")\nprint(f\"Para saber si un elemento está en el set usamos por ejemplo \\\"Alex\\\" in my_set y devuelve un boolean: {\"Valderrama\" in my_set}\")\n\n#Inserción\nprint(\"\\n\")\nprint(\"Inserción\")\nmy_set.add(\"avcenal\")\nprint(f\"Con el método add(), podemos añadir un elemento adicional, en este caso my_set.add(\\\"avcenal\\\"): {my_set}\")\nmy_set.add(\"avcenal\")\nprint(f\"Si añadimos un item existente, no se va a repetir: my_set.add(\\\"avcenal\\\") --> {my_set}\")\n\n#Actualización\nprint(\"\\n\")\nprint(\"Actualización\")\nmy_iterable = [20,75,90]\nmy_set.update(my_iterable)\nprint(f\"Con el método update() podemos actualizar el set con un iterable como my_iterable, quedando: {my_set}\")\nmy_other_set = {\"Cenalmor\", \"Growth Specialist\"}\nmy_union_set = my_set.union(my_other_set)\nprint(f\"También se pueden usar métodos como union() para unir dos sets asigándo la unión a una variable nueva: {my_union_set}\")\nmy_dif_set = my_union_set.difference(my_set)\nprint(f\"O el método diferencia, que nos devuelve solo los valores diferentes entre my_union_set y my_set: {my_dif_set}\")\n\n#Borrado\nprint(\"\\n\")\nprint(\"Borrado\")\nmy_erased_element = my_set.pop()\nprint(f\"Como en las listas, podemos usar pop() para desapilar el último elemento de esa ejecución: Desapilamos {my_erased_element} y el set queda: {my_set}\")\nmy_set.clear()\nprint(f\"Y el borrado lo hacemos con el método clear() que borra los elementos del set {my_set}\")\n\n\"\"\"\nDICCIONARIOS\n\"\"\"\n#Como son estructuras no ordenadas, no tienen métodos de ordenación\nmy_dict = {\n    \"Nombre\":\"Alex\",\n    \"Apellido\":\"Valderrama\",\n    \"Edad\":38,\n    \"Lenguajes\":{\"Python\",\"Swift\",\"Javascript\"},\n    \"medida\":1.82\n}\n#Búsqueda:\nprint(\"\\n\")\nprint(\"Búsqueda\")\nprint(f\"Para la búsqueda dentro de un diccionario podemos usar los operadores de pertenencia y devuelbe un boolean: \\\"Valderrama\\\" in my_dict.values() = {\"Valderrama\" in my_dict.values()}\")\nprint(f\"En cambio si no usamos .values() busca dentro de las propiedades: \\\"Valderrama\\\" in my_dict() = {\"Valderrama\" in my_dict}; \\\"Apellido\\\" in my_dict = {\"Apellido\" in my_dict}\")\nprint(f\"También si sabemos la clave, podemos acceder directamente al valor con my_dict.get(\\\"Nombre\\\"): {my_dict.get(\"Nombre\")} o directamente usando algo del tipo my_dict[\\\"Nombre\\\"]: {my_dict[\"Nombre\"]}\")\n\n#Inserción\nprint(\"\\n\")\nprint(\"Inserción\")\nmy_dict[\"Nick\"] = \"avcenal\"\nprint(f\"Se puede insertar un nuevo par clave:valor simplemente con my_dict[\\\"nueva_clave\\\"]=\\\"nuevo_valor\\\": {my_dict}\")\n\n#Actualización\nprint(\"\\n\")\nprint(\"Actualización\")\nmy_dict[\"Nombre\"] = \"Alejandro\"\nprint(f\"Podemos actualizar el valor de un key directamente con my_dict[key] = value: {my_dict}\")\n\n#Borrado\nprint(\"\\n\")\nprint(\"Borrado\")\nerased_element = my_dict.pop(\"medida\")\nprint(f\"Podemos usar el método pop() y al pasarle una de las keys como argumento, el valor se desapila, lo podemos guardar en una variable y la clave se elimina del diccionario {erased_element}\")\nprint(my_dict)\nerased_item = my_dict.popitem()\nprint(f\"Tambien podemos usar el método .popitem() que hace lo mismo que pop(), pero en este caso si desapila el último valor del diccionario y elimina la clave, pudiendo guardar el valor en una variable {erased_item}\")\ndel my_dict[\"Edad\"]\nprint(f\"Igualmente podemos usar del para borrar un par clave:valor sin almacenarlo en ningún sitio {my_dict}\")\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n *   y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n *   y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más\n *   de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.\n\"\"\"\nimport time,re\n\ndef insert_contact(one_dict): #pasar por parámetro name y phone, evaluar su longitud y si es distinto de 0, preguntar que confirme el dato y no preguntarlo\n    phone_pattern = r\"^\\+34[6|7|8]{1}[0-9]{8}\"\n    name = input(\"Dime el nombre del contacto: \")\n    match = None\n    while match == None:\n        phone = input(\"Ahora dime el teléfono del contacto: \")\n        match = re.search(phone_pattern,phone)\n        if match == None:\n            print(\"Parece que el formato de tu número de teléfono no es válido. Trata de usar el formato +34123456789 por favor\")\n            time.sleep(2)\n\n    one_dict[name] = phone\n    print(\"El contacto ha sido guardado en la agenda 👍\")\n    time.sleep(2)\n    print(\"\\n\")\n    return one_dict\n\ndef update_contact_after_find(one_dict,name):\n    option = \"\"\n    phone_pattern = r\"^\\+34[6|7|8]{1}[0-9]{8}\"\n    match = None\n    while option!=\"N\" or option!=\"T\":\n        option = input(\"¿Qué quieres actualizar, el nombre o el teléfono?(N/T)\")\n        option = option.upper()\n        if option == \"N\":\n            new_name = input(\"Ok, dime el nombre: \")\n            phone = one_dict[name]\n            del one_dict[name]\n            one_dict[new_name]=phone\n            return one_dict,new_name\n        elif option == \"T\":\n            while match == None:\n                new_phone = input (\"Ok dime el número de teléfono: \")\n                match = re.search(phone_pattern,new_phone)\n                if match == None:\n                    print(\"Parece que el formato de tu número de teléfono no es válido. Trata de usar el formato +34123456789 por favor\")\n                    time.sleep(2)\n            one_dict[name] = new_phone\n            return one_dict,name\n        else:\n            print(\"La opción no es válida, prueba de nuevo\")\n    \ndef erase_contact(one_dict,data):\n    if data.startswith(\"+\"):\n        name_list = list(one_dict.keys())\n        phone_list = list(one_dict.values())\n        if data in phone_list:\n            index = phone_list.index(data)\n            del one_dict[name_list[index]]\n            print(\"El contacto ha quedado borrado de la Agenda\")\n        #else:\n         #   print(\"No existe un contacto con ese número de teléfono dentro de la Agenda\")\n    else:\n        try:\n            del one_dict[data]\n            print(\"El contacto ha quedado borrado de la Agenda\")\n        except KeyError:\n            print(\"No existe un contacto con ese número de teléfono dentro de la Agenda\")\n    return one_dict\n\n        \ndef find_contact(one_dict,mode):\n    option = \"\"\n    insert_option = \"\"\n    update_option = \"\"\n    phone_pattern = r\"^\\+34[6|7|8]{1}[0-9]{8}$\"\n    while option!=\"N\" or option!=\"T\":\n        option = input(\"¿Quieres buscar por nombre o por teléfono?(N/T)\")\n        option = option.upper()\n        if option == \"N\":\n            try:\n                name = input(\"Perfecto, dime el nombre por favor: \")\n                print(f\"He encontrado a {name} en la agenda. Su teléfono es {one_dict[name]}\")\n                time.sleep(1)\n                print(\"\\n\")\n            except KeyError:\n                print(\"Parece que el contacto que buscas no está en la agenda\")\n                time.sleep(1)\n                print(\"\\n\")\n                while insert_option!=\"Y\" or insert_option!=\"N\":\n                    insert_option = input(\"¿Quieres incluirlo?(Y/N)\")\n                    insert_option = insert_option.upper()                             \n                    if insert_option == \"Y\":\n                        print(\"Ok\")\n                        insert_contact(one_dict)\n                        break\n                    elif insert_option == \"N\":\n                        print(\"Entendido\")\n                        time.sleep(1)\n                        print(\"\\n\")\n                        break\n                    else:\n                        print(\"La opción no es válida, prueba de nuevo\")\n                        time.sleep(1)\n                        print(\"\\n\")\n                        \n            else:\n                if mode == \"find\":\n                    update_option = \"\"\n                    while (update_option!=\"Y\" or update_option!=\"N\"):\n                        update_option = input(\"¿Quieres actualizar el contacto?(Y/N)\")\n                        update_option = update_option.upper()\n                        if update_option == \"Y\":\n                            one_dict,name = update_contact_after_find(one_dict,name)\n                            print(f\"El nombre del contacto ahora es {name} y el teléfono es {one_dict[name]}\")\n                            time.sleep(2)\n                            print(\"\\n\")\n                            break\n                        elif update_option == \"N\":\n                            print(\"Entendido\")\n                            time.sleep(1)\n                            print(\"\\n\")\n                            break\n                        else:\n                            print(\"La opción no es válida, prueba de nuevo\")\n                            time.sleep(1)\n                            print(\"\\n\")\n                            \n                elif mode == \"update\":\n                    one_dict,name = update_contact_after_find(one_dict,name)\n                    print(f\"El nombre del contacto es ahora {name} y el teléfono es {one_dict[name]}\")\n                    time.sleep(2)\n                    print(\"\\n\")\n                    break\n                elif mode == \"erase\":\n                    erase_contact(one_dict,name)\n                    time.sleep(2)\n                    print(\"\\n\")\n                    break\n        \n        elif option ==\"T\":\n                update_option = \"\"\n                match = None\n                while match == None:\n                    phone = input(\"Perfecto, dime el teléfono por favor: \")\n                    match = re.search(phone_pattern,phone)\n                    if match == None:\n                        print(\"Parece que el formato de tu número de teléfono no es válido. Trata de usar el formato +34123456789 por favor\")\n                        time.sleep(2)\n                if phone in one_dict.values():\n                    print(\"¡¡Lo encontré!!\")\n                    phone_list = list(one_dict.values())\n                    name_list = list(one_dict.keys())\n                    index = phone_list.index(phone)\n                    time.sleep(2)\n                    if mode == \"find\":\n                        print(f\"El nombre del contacto es {name_list[index]} y el teléfono es {phone}\")\n                        while update_option != \"Y\" or update_option!=\"N\":\n                            update_option = input(\"¿Quieres actualizar el contacto?(Y/N)\")\n                            update_option = update_option.upper()\n                            if update_option == \"Y\":\n                                one_dict,name = update_contact_after_find(one_dict,name_list[index])\n                                print(f\"El nombre del contacto ahora es {name} y el teléfono es {one_dict[name]}\")\n                                print(\"\\n\")\n                                time.sleep(2)\n                                break\n                            elif update_option == \"N\":\n                                print(\"Entendido\")\n                                time.sleep(1)\n                                print(\"\\n\")\n                                break\n                            else:\n                                print(\"La opción no es válida, prueba de nuevo\")\n                                time.sleep(1)\n                                print(\"\\n\")\n                    elif mode == \"update\":\n                        one_dict,name = update_contact_after_find(one_dict,name_list[index])\n                        print(f\"El nombre del contacto ahora es {name} y el teléfono es {one_dict[name]}\")\n                        print(\"\\n\")\n                        time.sleep(2)\n                        break    \n                    elif mode == \"erase\":\n                        erase_contact(one_dict,phone)\n                        time.sleep(2)\n                        print(\"\\n\")\n                        break\n\n                else:\n                    print(\"Parece que el contacto que buscas no está en la agenda\")\n                    insert_option = \"\"\n                    while insert_option!=\"Y\" or insert_option!=\"N\":\n                        insert_option = input(\"¿Quieres incluirlo?(Y/N)\")\n                        insert_option = insert_option.upper()\n                        if insert_option == \"Y\":\n                            print(\"Ok\")\n                            insert_contact(one_dict)\n                            break\n                        elif insert_option == \"N\":\n                            print(\"Entendido\")\n                            time.sleep(1)\n                            print(\"\\n\")\n                            break\n                        else:\n                            print(\"La opción no es válida, prueba de nuevo\")\n                            time.sleep(1)\n                            print(\"\\n\")\n        else:\n            print(\"La opción no es válida, prueba de nuevo\")\n            time.sleep(1)\n            print(\"\\n\")\n\n        return(one_dict)\n\nmy_agenda = dict()\noption = \"\"\nprint(\"\\n\")\nprint(\"---------------------------------------------------\")\nprint(\"BIENVENIDO/A AL SISTEMA DE AGENDA DE AVCENAL.DEV\")\nwhile option != \"F\":\n    print(\"---------------------------------------------------\")\n    option= input(\"¿Que es lo que quieres hacer?🤔\\n- Buscar contacto(B)👀\\n- Insertar contacto(I)⬇️\\n- Actualizar contacto(A)🔄\\n- Eliminar contacto(E)❌\\n- Finalizar(F)⏩️\\n\\n---> Introduce tu Opción: \")\n    option = option.upper()\n    if option == \"B\":\n        find_contact(my_agenda,\"find\")\n    elif option == \"I\":\n        insert_contact(my_agenda)\n    elif option ==\"A\":\n        find_contact(my_agenda,\"update\")\n    elif option == \"E\":\n        find_contact(my_agenda,\"erase\")\n\nprint(\"Gracias por usar el sistema de Agenda de AVCENAL.DEV. Un saludo\")\nprint(\"\\n\")\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/axelprz.py",
    "content": "\"\"\"  * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación. \"\"\"\n \n\"\"\"--------------------------- Listas ---------------------------\"\"\"\n # Creación de una lista\nmi_lista = [1, 2, 3, 4, 5]\n\n# Inserción al final\nmi_lista.append(6)\n\n# Inserción en una posición específica\nmi_lista.insert(2, 10)\n\n# Actualización de un elemento\nmi_lista[1] = 20\n\n# Borrado de un elemento por valor\nmi_lista.remove(4)\n\n# Borrado de un elemento por índice\ndel mi_lista[0]\n\n# Ordenación ascendente\nmi_lista.sort()\n\n# Ordenación descendente\nmi_lista.sort(reverse=True)\n\nprint(\"Lista despues de operaciones:\", mi_lista)\n\n\"\"\"--------------------------- Tuplas ---------------------------\"\"\"\n# Creación de una tupla\nmi_tupla = (1, 2, 3, 4, 5)\n\n# Acceso a elementos por índice\nelemento = mi_tupla[2]\n\n# Concatenación de tuplas\notra_tupla = (6, 7, 8)\nnueva_tupla = mi_tupla + otra_tupla\n\nprint(\"Elemento de la tupla:\", elemento)\nprint(\"Nueva tupla:\", nueva_tupla)\n\n\"\"\"--------------------------- Conjuntos ---------------------------\"\"\"\n# Creación de un conjunto\nmi_conjunto = {1, 2, 3, 4, 5}\n\n# Inserción\nmi_conjunto.add(6)\n\n# Borrado por valor\nmi_conjunto.remove(3)\n\n# Actualización con otro conjunto\notro_conjunto = {4, 5, 6, 7}\nmi_conjunto.update(otro_conjunto)\n\nprint(\"Conjunto después de operaciones:\", mi_conjunto)\n\n\"\"\"--------------------------- Diccionarios ---------------------------\"\"\"\n# Creación de un diccionario\nmi_diccionario = {'a': 1, 'b': 2, 'c': 3}\n\n# Inserción o actualización de un par clave-valor\nmi_diccionario['d'] = 4\n\n# Borrado por clave\ndel mi_diccionario['b']\n\n# Acceso a valores por clave\nvalor = mi_diccionario['c']\n\n# Obtención de claves y valores\nclaves = mi_diccionario.keys()\nvalores = mi_diccionario.values()\n\nprint(\"Valor del diccionario:\", valor)\nprint(\"Claves del diccionario:\", claves)\nprint(\"Valores del diccionario:\", valores)\n\n\"\"\" * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa. \"\"\"\n \nnombres = []\ntelefonos = []\nj = 0\n \ndef buscar_contacto(x):\n    while(j == 0):\n        contador = 0\n        print(\"1) Buscar por nombre\")\n        print(\"2) Buscar por numero de telefono\")\n        print(\"3) Volver atras\")\n        try:\n            opcion_busqueda = int(input(\"Selecciona el tipo de busqueda: \"))\n        except:\n            print(\"Error: Esta opcion debe contener solo numeros\")\n            continue\n        print(\"---------------------------------\")\n        if opcion_busqueda == 1:\n            nombre = input(\"Ingrese el nombre del contacto que desea buscar: \")\n            for i in nombres:\n                if nombre == i:\n                    print(\"Contacto encontrado con exito\");\n                    print(\"Nombre: \" + nombres[contador])\n                    print(\"Telefono: \" + str(telefonos[contador]))\n                    print(\"---------------------------------\")\n                    if x == 1:\n                        return contador\n                    break\n                else:\n                    contador += 1   \n        elif opcion_busqueda == 2:\n            while(j == 0):\n                try:\n                    telefono = int(input(\"Ingrese el numero del contacto que desea buscar: \"))\n                except:\n                    print(\"Error: Esta opcion debe contener solo numeros\")\n                    continue   \n                for i in telefonos:\n                    if telefono == i:\n                        print(\"Contacto encontrado con exito\");\n                        print(\"Nombre: \" + nombres[contador])\n                        print(\"Telefono: \" + str(telefonos[contador]))\n                        print(\"---------------------------------\")\n                        if x == 1:\n                            return contador\n                        break\n                    else:\n                        contador += 1  \n                break\n        elif opcion_busqueda == 3:\n            print(\"---------------------------------\")\n            break\n        else:\n            print(\"Opcion incorrecta\")\n            print(\"---------------------------------\")\n            \ndef insertar_contacto():\n    while(j == 0):\n        nombres.append(input(\"Ingrese el nombre: \"))\n        try:\n            telefono = int(input(\"Ingrese el numero de telefono: \"))\n        except:\n            print(\"Error: Esta opcion debe contener solo numeros\")\n            continue\n        telefonos.append(telefono)\n        print(\"Contacto agregado con exito\")\n        print(\"---------------------------------\")\n        opcion_insertar = input(\"Si desea añadir otro contacto pulse la tecla 'a': \")\n        if opcion_insertar != 'a':\n            print(\"---------------------------------\")\n            break\n\ndef actualizar_contacto():\n    indice = buscar_contacto(1)\n    while(j == 0):\n        print(\"1) Actualizar nombre\")\n        print(\"2) Actualizar numero de telefono\")\n        print(\"3) Buscar otro contacto\")\n        print(\"4) Volver atras\")\n        try:\n            opcion_actualizar = int(input(\"Seleccione una opcion: \"))\n        except:\n            print(\"Error: Esta opcion debe contener solo numeros\")\n            continue\n        print(\"---------------------------------\")\n        if opcion_actualizar == 1:\n            nombres[indice] = input(\"Ingrese el nuevo nombre para este contacto: \")\n            print(\"Contacto actualizado con exito\")\n            print(\"---------------------------------\")\n        elif opcion_actualizar == 2:\n            while(j == 0):\n                try:\n                    telefono = int(input(\"Ingrese el nuevo telefono para este contacto: \"))\n                except:\n                    print(\"Error: Esta opcion debe contener solo numeros\")\n                    continue\n                telefonos[indice] = telefono\n                print(\"Contacto actualizado con exito\")\n                print(\"---------------------------------\")\n                break\n        elif opcion_actualizar == 3:\n            indice = buscar_contacto(1)\n            print(\"---------------------------------\")\n        elif opcion_actualizar == 4:\n            print(\"---------------------------------\")\n            break\n            \ndef eliminar_contacto():\n    indice = buscar_contacto(1)\n    while(j == 0):\n        opcion_eliminar = input(\"Pulse la tecla 'a' para confirmar la eliminacion de este contacto: \")\n        print(\"---------------------------------\")\n        if opcion_eliminar != 'a':\n            while(j == 0):\n                print(\"1) Buscar otro contacto\")\n                print(\"2) Volver atras\")\n                try:\n                    opcion_eliminar2 = int(input(\"Elija una opcion: \"))\n                except:\n                    print(\"Error: Esta opcion debe contener solo numeros\")\n                    continue\n                print(\"---------------------------------\")\n                break\n            if opcion_eliminar2 == 1:\n                indice = buscar_contacto(1)\n                print(\"---------------------------------\")\n            elif opcion_eliminar2 == 2:\n                print(\"---------------------------------\")\n                break\n        else:\n            del nombres[indice]\n            del telefonos[indice]\n            print(\"Contacto eliminado con exito\")\n            while(j == 0):\n                print(\"1) Buscar otro contacto\")\n                print(\"2) Volver atras\")\n                try:\n                    opcion_eliminar2 = int(input(\"Elija una opcion: \"))\n                except:\n                    print(\"Error: Esta opcion debe contener solo numeros\")\n                    continue\n                print(\"---------------------------------\")\n                break\n            if opcion_eliminar2 == 1:\n                indice = buscar_contacto(1)\n                print(\"---------------------------------\")\n            elif opcion_eliminar2 == 2:\n                print(\"---------------------------------\")\n                break\n            \nwhile(j == 0):\n    print(\"Bienvenido a tu agenda de contactos\")\n    print(\"---------------------------------\")\n    print(\"1) Buscar un contacto\")\n    print(\"2) Insertar un contacto\")\n    print(\"3) Actualizar un contacto\")\n    print(\"4) Eliminar un contacto\")\n    print(\"5) Salir\")\n    print(\"---------------------------------\")\n    try:\n        opcion = int(input(\"Selecciona la operacion a realizar: \"))\n    except:\n        print(\"Error: Esta opcion debe contener solo numeros\")\n        continue\n    if opcion == 1:\n        buscar_contacto(0)\n    elif opcion == 2:\n        insertar_contacto()\n    elif opcion == 3:\n        actualizar_contacto()\n    elif opcion == 4:\n        eliminar_contacto()\n    elif opcion == 5:\n        print(\"Cerrando agenda de contactos\")\n        print(\"---------------------------------\")\n        break\n    else:\n        print(\"Opcion incorrecta, intentelo de nuevo\")\n        print(\"---------------------------------\")\n\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/blancowilson.py",
    "content": "# Estructura de datos\n#Listas\nmy_list:list = []\nmy_second_list:list = []\n\nfor i in range(5):\n    my_list.append(i+1)\n    my_second_list.append(2**i)\n\nprint(my_list)\nprint(my_second_list)\nmy_list.extend(my_second_list)\nmy_list.remove(2)\nprint(my_list)\nprint(my_list.index(2))\nmy_list.sort()\nprint(my_list)\n## recorrer listas\nfor i, v in enumerate(['tic', 'tac', 'toe']):\n    print(i, v)\n\nprint(\"usando ZIP\")\nquestions = ['name', 'quest', 'favorite color', 'other cuestion','No matter this']\nanswers = ['lancelot', 'the holy grail', 'blue']\nfor q, a in zip(questions, answers):\n    print('What is your {0}?  It is {1}.'.format(q, a))\n\n\n\n# Compresion de listas\nmy_second_list = [x**2 for x in range(10)]\nprint(my_second_list)\nmy_vector = []\nx,y=0,0\nmy_vector = [(x,y) for x in range(10) for y in range(10)]\nprint(my_vector)\nprint(my_vector[51])\n\n## En reversa\nprint(\"for using reversed\")\nfor i in reversed(range(1, 10, 2)):\n    print(i)\n\n# sort a lis usin sorted\nbasket = sorted(['apple', 'orange', 'apple', 'pear', 'orange', 'banana'])\nfor i in basket:\n    print(i)\n# El uso de set() en una secuencia elimina los elementos duplicados. El uso de sorted() en\n# combinación con set() sobre una secuencia es una forma idiomática de recorrer elementos \n# únicos de la secuencia ordenada.\n\nbasket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']\nfor f in sorted(set(basket)):\n    print(f)\n\n\nimport math\nraw_data = [56.2, float('NaN'), 51.7, 55.3, 52.5, float('NaN'), 47.8]\nfiltered_data = []\nfor value in raw_data:\n    if not math.isnan(value):\n        filtered_data.append(value)\n\nprint(filtered_data)\n\nprint()\nprint(\"***** Diccionarios *******\")\n\ntel = {'jack': 4098, 'sape': 4139}\ntel['guido'] = 4127\nprint(tel)\ndel tel['sape']\ntel['irv'] = 4127\nprint(tel)\nprint(\"convertir a lista \",list(tel))\nprint(f'Verificar si un valor existe en diccionario \"guido\" in tel ,{\"guido\" in tel}')\n## dos formas de crear un diccionario con dict\ndictionari2=dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])\ndictionari3=dict(sape=4139, guido=4127, jack=4098)\nprint(dictionari2)\nprint(dictionari3)\nprint(dictionari2 == dictionari3)\n\nknights = {'gallahad': 'the pure', 'robin': 'the brave'}\nfor k, v in knights.items():\n    print(k, v)\n\nfrom tkinter import *\nfrom tkinter import ttk\ncontacts =[ {\n    'name': 'John',\n    'last_name': 'Doe',\n    'phone': '123-456-7890',\n    'email': 'john.doe@example.com'\n}]\n\n\nroot = Tk()\nroot.title(\"Agenda\")\n\nname = StringVar()\nlast_name = StringVar()\nphone = StringVar()\nmail = StringVar()\n\ndef empty_table():\n    rows = trvContacts.get_children()\n    for row in rows:\n        trvContacts.delete(row)\n\ndef fill_table():\n    empty_table()\n    for index,row in enumerate(contacts):\n        print(index)\n        trvContacts.insert('', END,index,text=index,values=tuple(row.values()) )\n\n\ndef add_contact():\n    new_contac ={'name': name.get(),\n     'last_name': last_name.get(),\n     'phone': phone.get()}\n    contacts.append(new_contac)\n    fill_table()\n   \n\n\ndef delte_contact():\n    pass\n\n\ndef modify_contact():\n    pass\n\n\nframe = LabelFrame(root, text=\"Formualari de contacto\")\nframe.place(x=50, y=50, width=600, height=800)\n\nlblname = Label(frame, text='Nombre').grid(column=0,row=0,padx=5,pady=10)\ntxtName = Entry(frame, textvariable=name)\ntxtName.grid(column=1, row=0,padx=5,pady=10)\n\nlbllast_name = Label(frame, text='Apellido').grid(column=2,row=0,padx=5,pady=10)\ntxtlast_name = Entry(frame, textvariable=last_name)\ntxtlast_name.grid(column=3, row=0,padx=5,pady=10)\n\nlblphone = Label(frame, text='Phone').grid(column=0,row=1)\ntxtphone = Entry(frame, textvariable=phone)\ntxtphone.grid(column=1, row=1)\n\nlblmail = Label(frame, text='e-Mail').grid(column=2,row=1)\ntxtmail = Entry(frame, textvariable=mail)\ntxtmail.grid(column=3, row=1)\n\ntrvContacts = ttk.Treeview(frame)\ntrvContacts.grid(column=0,row=3,columnspan=4)\ntrvContacts[\"columns\"]=('name','lastName','phone','mail')\ntrvContacts.column('#0',width=0,stretch=NO)\ntrvContacts.column('name',width=100,anchor=CENTER)\ntrvContacts.column('lastName',width=100,anchor=CENTER)\ntrvContacts.column('phone',width=50,anchor=CENTER)\ntrvContacts.column('mail',width=100,anchor=CENTER)\ntrvContacts.heading('#0', text='')\ntrvContacts.heading('name',text='Nombre',anchor=CENTER)\ntrvContacts.heading('lastName',text='Apellido',anchor=CENTER)\ntrvContacts.heading('phone',text='phone',anchor=CENTER)\ntrvContacts.heading('mail',text='e-Mail',anchor=CENTER)\n\nbtnDelete = Button(frame, text='Eliminar', command=lambda:delte_contact)\nbtnDelete.grid(column=1, row=4)\nbtnAdd = Button(frame, text='Agregar', command=add_contact)\nbtnAdd.grid(column=2, row=4)\nbtnModify = Button(frame, text='Eliminar', command=lambda:modify_contact)\nbtnModify.grid(column=3, row=4)\n\n\n\n\n\n\nfill_table()\n\nroot.mainloop()\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/c3sarmx.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto\n *   en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n *   y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n *   y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no numéricos y con más\n *   de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.\n */\n\"\"\"\n\n# ========== Listas ==========\n\nnumeros = [1, 2, 3, 4]\nprint(numeros)\n\n# == Insercción ==\n\nnumeros.append(5)\nprint(numeros) #* append() → agrega al final\n\n# == Borrado ==\n\nnumeros.remove(1)\nprint(numeros) #* remove() → borra por valor\n\nnumeros.pop(0) #* pop() -> Borrado por indice\nprint(numeros)\n\n# == Actualización ==\n\nnumeros[1] = 10 #* Cambiar un valor por índice:\nprint(numeros)\n\n# == Ordenación ==\n\nnumeros.sort() #* sort() -> Ordena la lista\nprint(numeros)\n\nordenada = sorted(numeros) #* sorted() -> Devuelve una nueva lista\nprint(ordenada)\n\n\"\"\"\nREFUERZO:\n\nCrea una lista llamada edades con estos valores:\n[25, 18, 30, 22]\n\nLuego:\nAgrega el número 40\nElimina el 18\nCambia el 22 por 23\nOrdena la lista\nImprime el resultado final\n\"\"\"\n\nedades = [25, 18, 30, 22]\n\nedades.append(40)\nprint(edades)\n\nedades.remove(18)\nprint(edades)\n\nedades[2] = 23\nprint(edades)\n\nedades.sort()\nprint(edades)\n\n# ========== Tuplas ==========\n\nmy_tuple = (\"Lio\", \"Gutierrez\", \"c3sarmx\")\nprint(my_tuple[0]) #* Acceso por indice\nmy_tuple = tuple(sorted(my_tuple)) #* Ordenación\nprint(my_tuple) \n\n# ========== Sets ==========\n\nmy_set = {\"Lio\", \"Gutierrez\", \"c3sarmx\"}\nprint(my_set)\nmy_set.add(\"c3sar.mx@gmail.com\") #* Insercción\nprint(my_set)\nmy_set.remove(\"Gutierrez\") #* Borrado\nprint(my_set)\n\n\n#* REFUERZO #*\n\n\"\"\"\nCrea un set llamado usuarios con:\n{\"Ana\", \"Luis\", \"Ana\", \"Pedro\"}\n\nImprime el set\nAgrega \"María\"\nElimina \"Luis\"\nImprime el resultado final\n\"\"\"\n\nusers = {\"Ana\", \"Luis\", \"Ana\", \"Pedro\"}\nprint(users)\n\nusers.add(\"María\")\nusers.remove(\"Luis\")\n\nprint(users)\n\n# ========== Diccionarios ==========\n\nuser = {\n    \"name\": \"Lio\",\n    \"user\": \"c3sarmx\",\n    \"email\": \"lioo.py@gmail.com\",\n    \"age\": 25\n}\nprint(user)\n\nuser[\"alias\"] = \"lioodev\" #* Insercción\nprint(user)\n\nprint(user[\"name\"]) #* Acceso\n\nuser[\"age\"] = 24 #* Actualización\nprint(user)\n\ndel user[\"age\"] #* Eliminación\nprint(user)\n\nuser = dict(sorted(user.items())) #* Ordenación\nprint(user)\n\n#* REFUERZO #*\n\n\"\"\" \nCrea un diccionario agenda con:\n\"Lio\" → \"5512345678\"\n\"Ana\" → \"5587654321\"\n\nImprime el teléfono de \"Lio\"\nActualiza el teléfono de \"Ana\"\nElimina a \"Lio\"\nImprime la agenda final\n\"\"\"\n\ncontactos = {\n    \"Lio\": 5512345678,\n    \"Ana\": 5587654321 \n}\nprint(contactos)\n\nprint(contactos[\"Lio\"])\n\ncontactos[\"Ana\"] = 5561542101\n\ndel contactos[\"Lio\"]\nprint(contactos)\n\n\n#* EXTRA\n\nprint(\"========== Extra ==========\")\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n* Crea una agenda de contactos por terminal.\n* - Debes implementar funcionalidades de búsqueda, inserción, actualización\n*   y eliminación de contactos.\n* - Cada contacto debe tener un nombre y un número de teléfono.\n* - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n*   y a continuación los datos necesarios para llevarla a cabo.\n* - El programa no puede dejar introducir números de teléfono no numéricos y con más\n*   de 11 dígitos (o el número de dígitos que quieras).\n* - También se debe proponer una operación de finalización del programa.\n\"\"\"\n\n\"\"\"\nAGENDA DE CONTACTOS (Reto 03 - Dificultad extra)\n\nRequisitos:\n- Búsqueda, inserción, actualización y eliminación de contactos\n- Cada contacto: nombre + teléfono\n- No permitir teléfonos: con caracteres no numéricos, con más de 11 dígitos (puedes ajustar el límite)\n- Opción para finalizar el programa\n\"\"\"\n\ndef my_agenda(): # Definimos la agenda\n    \n    agenda = {}\n    # Creamos un bucle 'while'  \n    def insert_contact():\n        phone = input(\"Teléfono del contacto: \")\n        if phone.isdigit() and len(phone) > 0 and len(phone) <= 11:\n            agenda[name] = phone\n            return True\n        else:\n            print(\"El número telefonico es incorrecto.\")\n            return False\n\n    while True: \n\n# Mostramos al usuario las opciones disponibles\n        print(\"\")\n        print(\"1. Buscar contacto\")\n        print(\"2. Insertar contacto\")\n        print(\"3. Actualizar contacto\")\n        print(\"4. Eliminar contacto\")\n        print(\"5. Salir\")\n\n# Definimos una variable 'Opción' para que el usuario ingrese la opción a elegir.\n        option = input(\"\\nSelecciona una opción: \")\n\n        match option:\n            case \"1\":\n                name = input(\"Introduce el nombre del contacto a buscar: \")\n                if name in agenda:\n                    print(f\"El número de telefono de {name} es {agenda[name]}\")\n                else: \n                    print(f\"El contacto {name} no existe.\")\n            case \"2\":\n                name = input(\"Nombre del contacto: \")\n                if name in agenda:\n                    print(f\"El contacto ya existe. Usa la opción 'Actualizar' si deseas modificarlo.\")\n                else:\n                    if insert_contact():\n                        print(f\"Contacto {name} se guardó exitosamente.\")\n            case \"3\":\n                name = input(\"Introduce el nombre del contacto a actualizar: \")\n                if name in agenda:\n                    if insert_contact():\n                        print(f\"Contacto {name} se actualizó exitosamente.\")\n                else: \n                    print(f\"El contacto {name} no existe.\")\n            case \"4\":\n                name = input(\"Itroduce el contacto a eliminar: \")\n                if name in agenda:\n                    del agenda[name]\n                    print(f\"Contacto {name} eliminado correctamente.\")\n                else:\n                    print(f\"El contacto {name} no existe.\")\n            case \"5\":\n                print(\"Saliendo de la agenda.\")\n                break # Con ´break' al elegir una de las opciones cerramos el programa.\n            case _:\n                    print(\"Opción no valida. Elige una opción del 1 al 5.\")\n\nmy_agenda()\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/carrenoalexander.py",
    "content": "\"\"\"\n * Estruturas de datos\n\"\"\"\n\n# Lista\n\nmy_list = [1, 1, 2, 3, 5, 6]\nprint(my_list)\nprint(type(my_list))\n\nmy_list.insert(4, 4)  # Inserción\nprint(my_list)\n\nmy_list.remove(6)  # Borrado\nprint(my_list)\n\nmy_list[0] = 0  # Actualización\nprint(my_list)\n\nmy_list.sort(reverse=True)  # Ordenación descendente\nprint(my_list)\n\n# Tupla\n\nmy_tuple = (1, 2, 3, 4, 5)\nprint(my_tuple)\nprint(type(my_tuple))\n\n# Set\n\nmy_set = {1, 2, 3, 4, 5}\nprint(my_set)\nprint(type(my_set))\n\nmy_set.add(6)  # Inserción\nprint(my_set)\n\nmy_set.remove(6)  # Borrado\nprint(my_set)\n\n# Diccionario\n\nmy_dict = {\n    \"Month\": \"April\",\n    \"Day\": \"Monday\",\n    \"Year\": 2024\n}\nprint(my_dict)\nprint(type(my_dict))\n\nmy_dict[\"Century\"] = \"XXI\"  # Inserción\nprint(my_dict)\n\ndel my_dict[\"Century\"]  # Borrado\nprint(my_dict)\n\nmy_dict[\"Month\"] = \"August\"  # Actualización\nprint(my_dict)\n\nmy_dict = dict(sorted(my_dict.items()))  # Ordenación\nprint(my_dict)\n\n\"\"\"\n * Extra\n\"\"\"\n\ndef menu():\n    print(\"=====================================\")\n    print(\"WELCOME TO THE CONTACTS AGENDA\")\n    print(\"1. Search contact\")\n    print(\"2. Insert contact\")\n    print(\"3. Update contact\")\n    print(\"4. Delete contact\")\n    print(\"5. Exit\")\n    print(\"=====================================\")\n\nmenu()\n\ndef contacts_agenda():\n\n    agenda = {}\n\n    def validate_phone_number(phone):\n        return phone.isdigit() and len(phone) == 10\n\n    while True:\n        option = input(\"Choose an option: \")\n\n        match option:\n            case \"1\":\n                name = input(\"Enter the name to search: \")\n                if name in agenda:\n                    print(f\"The phone number of {name} is {agenda[name]}\")\n                else:\n                    print(\"Contact not found\")\n            case \"2\":\n                name = input(\"Enter the name to insert: \")\n                phone = input(\"Enter the phone: \")\n                if validate_phone_number(phone):\n                    agenda[name] = phone\n                    print(\"Contact inserted\")\n                else:\n                    print(\"Invalid phone number\")\n            case \"3\":\n                name = input(\"Enter the name to update the phone: \")\n                if name in agenda:\n                    phone = input(\"Enter the new phone: \")\n                    if validate_phone_number(phone):\n                        agenda[name] = phone\n                        print(\"Contact updated\")\n                    else:\n                        print(\"Invalid phone number\")\n                else:\n                    print(\"Contact not found\")\n            case \"4\":\n                name = input(\"Enter the name to delete: \")\n                if name in agenda:\n                    del agenda[name]\n                    print(\"Contact deleted\")\n                else:\n                    print(\"Contact not found\")\n            case \"5\":\n                print(\"Exiting...\")\n                break\n            case _:\n                print(\"Invalid option... Retry\")\n\ncontacts_agenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/cbuenrostrovalverde.py",
    "content": "'''\n/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n */\n '''\n\n# Listas, tuplas, conjuntos, diccionarios\n\n# LISTA\nverduras = ['tomate', 'lechuga', 'patata']\n\n# Insertar elementos\nverduras.append('calabacín')\n\n# Borrar elementos\nverduras.remove('tomate')\n\n# Actualizar\nverduras[1] = 'berenjena'\n\n# Ordenar\nverduras.sort()\n\nprint(verduras)\n\n# TUPLA\n\ntupla = (1, 2, 3, 4, 5, 6, 7, 20)\n\n'En una tupla no se pueden modificar los datos'\n\n#   CONJUNTOS\n\ncolores = {'rojo', 'amarillo', 'verde', 'azul'}\n\n# Añadir datos al conjunto\ncolores.add('naranja')\n\n# Borrar pese a que no exista dentro del conjunto\ncolores.discard('violeta')\n\n# Actualizar datos\ncolores.update('lo que quieras tú')\n\n# Ordenar (convertirá el conjunto en una lista)\ncolores_ordenados = sorted(colores)\n\n# DICCIONARIOS\n\nalumnos = {\n    'nombre': 'Carlos',\n    'edad': 20\n}\n\n# Insetar y actualizar datos\nalumnos['apellido'] = 'Buenrostro'\n\nalumnos['edad'] = 30\n\n# Eliminar datos\n\ndel alumnos['edad']\n\n# Ordenación\n\nsorted_alumnos = dict(sorted(alumnos.items()))\nprint(alumnos)\n\n'''\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n'''\n\nlista_contactos = []\nagenda = {}\n\ndef mostrar_menu():\n    print(\"\\n--- AGENDA DE CONTACTOS ---\")\n    print(\"1. Añadir contacto\")\n    print(\"2. Buscar contacto\")\n    print(\"3. Actualizar contacto\")\n    print(\"4. Eliminar contacto\")\n    print(\"5. Ver todos los contactos\")\n    print(\"6. Salir\")\n\ndef telefono_valido(telefono):\n    return telefono.isdigit() and len(telefono) <= 11\n\ndef añadir_contacto(agenda):\n    nombre = input('Introduzca el nombre del contacto: ').strip()\n    telefono = input('Introduzca un teléfono: ').strip()\n    if not telefono_valido (telefono):\n        print('Introduzca por favor un teléfono válido. Máximo 11 números')\n    agenda[nombre] = telefono\n    print(f'Contacto {nombre} ha sido añadido con éxito.')\n\ndef buscar_contacto(agenda):\n    nombre = input('Introduzca un nombre para la búsqueda: ')\n    if nombre in agenda:\n        print(f'{nombre}: {agenda[nombre]}')\n    else:\n        print(f'Ese nombre no se encuentra en su agenda de contactos.')\n\ndef actualizar_contacto(agenda):\n    nombre = input('Introduzca el nombre del contacto: ')\n    if nombre in agenda:\n        nuevo_telefono = input('Introduzca nuevo teléfono: ').strip()\n        if not telefono_valido(nuevo_telefono):\n            print('Teléfono no válido')\n            return \n        agenda[nombre] = nuevo_telefono\n        print('Contacto actualizado con éxito.')\n    else:\n        print('El contacto no se enucuentra dentro de su agenda.')\n\ndef eliminar_contacto(agenda):\n    nombre = input('Introduzca el nombre de su contacto a eliminar: ')\n    if nombre in agenda:\n        del agenda[nombre]\n        print('Contacto eliminado')\n    else:\n        print('No se ha podido encontrar el contacto a eliminar.')\n    \ndef mostrar_agenda(agenda):\n    if not agenda:\n        print('Agenda vacía')\n    else:\n        for nombre, telefono in agenda.items():\n            print(f'{nombre}:{telefono}')\n\nwhile True:\n    mostrar_menu()\n    opcion = input('Bienvenido a tu agenda virutal. \\n Por favor, escoja una opción: ')\n    if opcion == 1:\n        añadir_contacto(agenda)\n    elif opcion == 2:\n        buscar_contacto(agenda)\n    elif opcion == 3:\n        actualizar_contacto(agenda)\n    elif opcion == 4:\n        eliminar_contacto(agenda)\n    elif opcion == 5:\n        mostrar_agenda(agenda)\n    elif opcion == 'Salir'.lower():\n        print('Saliendo de la aplicación')\n        break\n    else:\n        print('Opción no válida. Inténtelo de nuevo.')\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/cdbiancotti.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n#  * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n\n# List\nlista_vacia = []\nlista = [1, 2, 3, 4, 5, 6]  # tambien se puede utilizar list()\nprint('Lista 1:', lista)\n# Insercion\nlista.insert(0, 0)\nprint('Lista 1 post insert:', lista)\nlista.append(6)\nprint('Lista 1 post append:', lista)\nlista.extend([34, 55])\nprint('Lista 1 post extend:', lista)\n# Actualización\nlista[2:4] = [10]\nprint('Lista 1 post asignacion por slicing:', lista)\nlista[-1] = 55\nprint('Lista 1 post modificacion de valor en la posicion -1:', lista)\n# Borrado\nlista2 = lista[:]\nprint('Lista 2 pre clear:', lista2)\nlista2.clear()\nprint('Lista 2 post clear:', lista2)\nlista.pop()\nprint('Lista 1 post pop:', lista)\nlista.remove(1)\nprint('Lista 1 post remove:', lista)\ndel lista[3]\nprint('Lista 1 post del:', lista)\n# Ordenamiento\nlista.sort()\nprint('Lista 1 post sort:', lista)\nlista.sort(reverse=True)\nprint('Lista 1 post reverse sort:', lista)\nlista.reverse()\nprint('Lista 1 post reverse:', lista)\n\n# Tuple\ntupla_vacia = ()\ntupla = (1, 2, 3, 4, 5, 6)\nprint('Tupla 1:', tupla)\n# Las tuplas no admiten insercion, actualización, borrado, ordenamiento ya que son inmutables\n\n# Set\nset_vacio = set()\nprint('Set vacio:', set_vacio)\nset_con_datos1 = {11, 2, 3, 4, True, 'test', ('Prueba', 'tupla')}\nprint('Set 1:', set_con_datos1)\nset_con_datos2 = set((11, 2, 3, 4, True, 'test', ('Prueba', 'tupla')))\nprint('Set 2:', set_con_datos2)\nset_con_datos3 = set([11, 2, 3, 4, True, 'test', ('Prueba', 'tupla')])\nprint('Set 3:', set_con_datos3)\n# inserción\nset_vacio.add('Dato nuevo')\nprint('Set vacio con add:', set_con_datos3)\nset_vacio.update('Dato nuevo', )\nprint('Set vacio con update despues del add:', set_con_datos3)\n# borrado\nset_con_datos3.remove(('Prueba', 'tupla'))\nprint('Set 3 post remove:', set_con_datos3)\nset_con_datos3.discard('EAEA')\nprint('Set 3 post discard:', set_con_datos3)\nset_con_datos3.pop()\nprint('Set 3 post pop:', set_con_datos3)\nset_con_datos3.clear()\nprint('Set 3 post clear:', set_con_datos3)\n# actualización\nset_con_datos2.difference_update((2, 3,))\nprint('Set 2 post difference update:', set_con_datos2)\nset_con_datos2.intersection([11, True])\nprint('Set 2 post intersection update:', set_con_datos2)\n# Los sets no pueden ordenarse ya que sus elementos no estan ordenados por un indice como los otros tipos de daots.\n\n# Dictionary\ndicc = {\n    1: 'test',\n    (2, 'si'): 123,\n    'llave': [1, 2, 3, 4.5],\n    True: {11, 3, 1, 2, 15, 6, 3, 46, 3, 6, 34}\n}  # tambien se puede utilizar dict()\n# Las llaves pueden ser cualquier valor inmutable, los valores cualquier tipo de dato\ndicc_vacio = {}\nprint('Dicc:', dicc)\n# Insercion y Actualización\ndicc['nuevo valor'] = 333\nprint('Dicc con \"nuevo valor\":', dicc)\ndicc2 = {'key1': \"value1\", 'llave': 'Cambie mi valor'}\ndicc.update(dicc2)\nprint('Dicc post update with dict:', dicc)\ntuple_to_dict = ((1, 'nuevo valor de key \"1\"'), (\"key2\", (\"soy\", \"una\", \"tupla\")))\ndicc.update(tuple_to_dict)\nprint('Dicc post update with tuple:', dicc)\ndicc_vacio.setdefault(\"lista\", []).append(15)\ndicc_vacio['lista'].append(20)\nprint('Dicc vacio post setdefault:', dicc_vacio)\n# Borrado\ndel dicc[True]\nprint('Dicc post del:', dicc)\nvalue_popped = dicc.pop('key2')\nprint('Dicc post pop:', dicc, ', value popped:', value_popped)\nitem_popped = dicc.popitem()\nprint('Dicc post popitem:', dicc, ', item popped:', item_popped)\ndicc.clear()\nprint('Dicc post clear:', dicc)\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea una agenda de contactos por terminal.\n#  * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n#  * - Cada contacto debe tener un nombre y un número de teléfono.\n#  * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n#  *   los datos necesarios para llevarla a cabo.\n#  * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n#  *   (o el número de dígitos que quieras)\n#  * - También se debe proponer una operación de finalización del programa.\n#  */\n\nfrom typing import List, TypedDict, Optional\n\n\nclass Person(TypedDict):\n    name: str\n    number: str\n\n\nclass Agenda:\n    def __init__(self) -> None:\n        self.__agenda: List[Person] = []\n\n    def search(self, name: str) -> None:\n        search_result = [person for person in self.__agenda if name in person[\"name\"]]\n        if not search_result:\n            print(f\"No se encontraron contactos relacionados con \\\"{name}\\\"\")\n            return\n\n        print(f\"Listado de contactos relacionados con {name}:\")\n        for i, person in enumerate(search_result):\n            print(f\"{i}. {person[\"name\"]}: {person[\"number\"]}\")\n\n    def create(self, name: str) -> None:\n        contact = self.__get_contact_data_by_name(name)\n\n        while True:\n            number = input(\"Ingrese el numero de telefono: \")\n            if self.__number_validator(number):\n                break\n\n        print(f\"Se agrego el contacto {name} correctamente a la agenda.\")\n\n    def delete(self, name: str) -> None:\n        old_agenda_length = len(self.__agenda)\n        self.__agenda = [person for person in self.__agenda if person['name'] != name]\n        new_agenda_length = len(self.__agenda)\n        if old_agenda_length != new_agenda_length:\n            print(f\"Se elimino correctamente el contacto {name}\")\n        else:\n            print(f\"{name} no corresponde a un contacto de la agenda.\")\n\n    def update(self, name: str) -> None:\n        contact = self.__get_contact_data_by_name(name)\n        if contact is None:\n            print(f\"No existe el contacto con nombre {name}\")\n            return\n\n        while True:\n            number = input(\"Ingrese el numero de telefono: \")\n            if self.__number_validator(number):\n                break\n\n        contact[\"number\"] = number\n        print(\"Se actualizo correctamente el numero de telefono.\")\n\n    def __get_contact_data_by_name(self, name: str) -> Optional[Person]:\n        persons = [person for person in self.__agenda if name in person[\"name\"]]\n        if persons:\n            return persons[0]\n\n    def __number_validator(self, incoming_number: str):\n        if not incoming_number.isnumeric() or len(incoming_number) > 11:\n            print(\"El numero de telefono debe ser un numero de no mas de 11 digitos.\")\n            return False\n        return True\n\n\ndef main():\n    agenda = Agenda()\n    while True:\n        print('''\n========================\n          Menu\n========================\n1. Buscar contacto\n2. Agregar contacto\n3. Actualizar contacto\n4. Eliminar contacto\n5. Salir\n''')\n        selected_option = input(\"Ingrese la opcion a realizar: \")\n        contact_name = input(\"Ingrese el nombre de contacto: \")\n        match selected_option:\n            case '1':\n                agenda.search(contact_name)\n            case '2':\n                agenda.create(contact_name)\n            case '3':\n                agenda.update(contact_name)\n            case '4':\n                agenda.delete(contact_name)\n            case '5':\n                print(\"Hasta luego...\")\n                return\n            case _:\n                print(\"Ingreso una opcion incorrecta, vuelva a intentarlo.\")\n\n\nmain()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/cesar-ch.py",
    "content": "# ----- Listas\n# Creación\nlista = [1, 2, 3, 4, 5]\nlista_vacia = []\nlista_mezclada = [1, \"dos\", True, 3.14]\n\n# Inserción\nlista.append(6)\nlista.insert(2, 4)\n\n# Borrado\nlista.remove(2)\nlista.pop()\n\n# Actualización\nlista[1] = 2\n\n# Ordenación\nlista.sort()\nlista.sort(reverse=True)\n\n# ----- Tuplas\n# Creación\ntupla = (1, 2, 3, 4, 5)\ntupla_vacia = ()\ntupla_mezclada = (1, \"dos\", True, 3.14)\n\n# Inserción y borrado\n# No es posible insertar o borrar elementos en una tupla\n\n# Actualización\n# No es posible actualizar elementos en una tupla\n\n# Ordenación\n# No es posible ordenar una tupla\n\n# ----- Diccionarios\n# Creación\ndiccionario = {\"uno\": 1, \"dos\": 2, \"tres\": 3, \"cuatro\": 4, \"cinco\": 5}\ndiccionario_vacia = {}\ndiccionario_mezclado = {\"uno\": \"dos\", \"tres\": True, \"cuatro\": 3.14}\n\n# Inserción\ndiccionario[\"seis\"] = 6\n\n# Borrado\ndel diccionario[\"seis\"]\n\n# Actualización\ndiccionario[\"uno\"] = 0\n\n# Ordenación\n# No es posible ordenar un diccionario\n\n# ----- Sets\n# Creación\nconjunto = {1, 2, 3, 4, 5}\nconjunto_vacia = set()\nconjunto_mezclado = {1, \"dos\", True, 3.14}\n\n# Inserción\nconjunto.add(6)\n\n# Borrado\nconjunto.remove(2)\nconjunto.pop()\n\n# Actualización\n# No es posible actualizar elementos en un conjunto\n\n# Ordenación\n# No es posible ordenar elemetos en un conjunto\n\n\n# DIFICULTAD EXTRA\ndef crear_agenda():\n    agenda = []\n    run = True\n\n    while run:\n        operacion = input(\n            \"\"\"Ingrese la operación a realizar:\n            1. Buscar contacto\n            2. Insertar contacto\n            3. Actualizar contacto\n            4. Eliminar contacto\n            5. Salir\n        \"\"\"\n        )\n\n        if operacion == \"1\":\n            if len(agenda) == 0:\n                print(\"Agenda vacía\")\n                continue\n\n            nombre = input(\"Ingrese el nombre del contacto a buscar: \")\n\n            contacto_encontrado = False\n            for contacto in agenda:\n                if contacto[\"nombre\"] == nombre:\n                    print(\"Contacto encontrado:\", contacto)\n                    contacto_encontrado = True\n                    break\n\n            if not contacto_encontrado:\n                print(\"Contacto no encontrado\")\n\n        elif operacion == \"2\":\n            nombre = input(\"Ingrese el nombre del contacto a insertar: \")\n            telefono = input(\"Ingrese el teléfono del contacto a insertar: \")\n\n            if not telefono.isdigit() or not (6 <= len(telefono) <= 11):\n                print(\"El número de teléfono no es válido.\")\n                break\n\n            nuevo_contacto = {\"nombre\": nombre, \"telefono\": telefono}\n            agenda.append(nuevo_contacto)\n            print(\"Contacto insertado:\", nuevo_contacto)\n\n        elif operacion == \"3\":\n            nombre = input(\"Ingrese el nombre del contacto a actualizar: \")\n            contacto_encontrado = False\n\n            for contacto in agenda:\n                if contacto[\"nombre\"] == nombre:\n                    contacto[\"telefono\"] = input(\n                        \"Ingrese el nuevo teléfono del contacto: \"\n                    )\n                    print(\"Contacto actualizado:\", contacto)\n                    contacto_encontrado = True\n                    break\n\n            if not contacto_encontrado:\n                print(\"Contacto no encontrado\")\n\n        elif operacion == \"4\":\n            nombre = input(\"Ingrese el nombre del contacto a eliminar: \")\n            contacto_encontrado = False\n\n            for contacto in agenda:\n                if contacto[\"nombre\"] == nombre:\n                    agenda.remove(contacto)\n                    print(\"Contacto eliminado.\")\n                    contacto_encontrado = True\n                    break\n\n            if not contacto_encontrado:\n                print(\"Contacto no encontrado\")\n\n        elif operacion == \"5\":\n            run = False\n            print(\"Agenda creada:\", agenda)\n\n        else:\n            print(\"Operación no válida\")\n\n\ncrear_agenda()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/clmiranda.py",
    "content": "# Estructuras de Datos\n# LISTAS (mutables)\n\n# Inserción\nmi_lista = [4, 7, 90, 15, 37, 25, 19]\nmi_lista.append(123)\nprint(mi_lista)\n\n# Borrado 'remove'\nmi_lista.remove(90)\nprint(mi_lista)\n\n# Borrado 'del'\ndel mi_lista[0]\nprint(mi_lista)\n\n# Borrado 'pop'\nmi_lista.pop(1)\nprint(mi_lista)\n\n# Actualización\nmi_lista[-1] = 456\nprint(mi_lista)\n\n# Ordenación\nmi_lista.sort(reverse=True)\nprint(mi_lista)\n\n\n\n# TUPLAS (inmutables, no pueden ser modificadas una vez son declaradas)\n# Pueden ser convertidas a listas para realizar modificaciones \n\nmi_tupla = (48, 7, 19, 14, 2, 67)\ntupla_lista = list(mi_tupla)\ntupla_lista.sort()\nprint(tuple(tupla_lista))\n\n\n\n# CONJUNTOS (sets, no permite valores duplicados, son desordenados)\nmi_set = {27, 8, 16, 4, 78, 16, 5, 8}\nmi_set.add(333)\nprint(mi_set)\n\n# Borrado 'discard' no arroja error si no se encuentra el valor\nmi_set.discard(117)\nprint(mi_set)\n\n\n\n# DICCIONARIOS (manejan valores tipo 'clave:valor')\nmi_dict = {'nombre': 'Cliver', 'edad': 27, 'lenguajes': ['Python', 'JavaScript', 'C#']}\nprint(mi_dict)\n\n# Inserción\nmi_dict['frameworks'] = ['react', 'angular']\nprint(mi_dict)\n\n# Borrado\ndel mi_dict['lenguajes']\nprint(mi_dict)\n\n# Actualización\nmi_dict['nombre'] = 'Juan'\nprint(mi_dict)\n\n\n\n# Ejercicio, dificultad extra\nfrom colorama import Fore, Style\n\nglobal users_dict\nusers_dict = list(dict())\n\n\ndef validate_user_exists(name):\n    find_name = [i for i in users_dict if i[\"name\"].lower() == name]\n    return find_name[0] if len(find_name) == 1 else None\n\n\ndef validate_phone(phone):\n    if isinstance(phone, int) and len(str(phone)) <= 11:\n        return True\n    return False\n\n\ndef validate_name(name):\n    if name != \"\":\n        return True\n    return False\n\n\ndef search_user(name):\n    user_found = validate_user_exists(name)\n    return f\"{Fore.GREEN}Contacto: {user_found}\" if user_found else f\"{Fore.RED}El contacto {name} no ha sido registrado!\"\n         \n\ndef add_user(name, phone):\n    if validate_name(name):\n        if validate_phone(phone):\n            users_dict.append({\"name\": name, \"phone\": phone})\n            return f\"{Fore.GREEN}Contacto {name} agregado!\"\n        return f\"{Fore.RED}El número no debe exceder de 11 dígitos!\"\n    return f\"{Fore.RED}Debe ingresar un nombre de contacto!\"\n\n\ndef update_contact(name):\n    user_found = validate_user_exists(name)\n    if user_found:\n         try:\n            new_name = input(\"Ingrese el nuevo nombre: \")\n            new_phone = int(input(\"Ingrese el nuevo teléfono: \"))\n            if validate_name(name):\n                if validate_phone(new_phone):\n                    index = users_dict.index(user_found)\n                    users_dict[index][\"name\"] = new_name\n                    users_dict[index][\"phone\"] = new_phone\n                    return f\"{Fore.GREEN}Contacto {new_name} actualizado correctamente!\"\n                return f\"{Fore.RED}El número no debe exceder de 11 dígitos!\"\n            return f\"{Fore.RED}Debe ingresar un nombre de contacto!\"\n         except:\n            print(Fore.RED + \"Debe ingresar sólo números!\")\n    return f\"{Fore.RED}El contacto no se encuentra registrado!\"\n\n\ndef delete_contact(name):\n    user_found = validate_user_exists(name)\n    if user_found:\n         index = users_dict.index(user_found)\n         del users_dict[index]\n         return f\"{Fore.GREEN}Contacto {name} eliminado correctamente!\"\n    return f\"{Fore.RED}El contacto no se encuentra registrado!\"\n\n\nwhile True:\n    print(Style.RESET_ALL)\n    try:\n        option = int(input(\"\"\"          ***************AGENDA DE CONTACTOS***************\n1.- Buscar un contacto.\n2.- Agregar un contacto.\n3.- Actualizar los datos de un contacto.\n4.- Eliminar un contacto.\n5.- Ver todos los contactos.\n0.- Finalizar programa.\n\"\"\"))\n        if option == 0:\n            break\n        match option:\n            case 1:\n                name = input(\"Ingrese el nombre del contacto a buscar: \").lower()\n                print(search_user(name))\n            case 2:\n                try:\n                    name = input(\"Nombre de contacto: \")\n                    phone = int(input(\"Teléfono del contacto (sólo números, hasta 11 dígitos): \"))\n                    print(add_user(name, phone))\n                except:\n                    print(Fore.RED + \"Debe ingresar sólo números!\")\n            case 3:\n                  name = input(\"Ingrese el nombre del contacto a actualizar: \").lower()\n                  print(update_contact(name))\n            case 4:\n                  name = input(\"Ingrese el nombre del contacto a eliminar: \").lower()\n                  print(delete_contact(name))\n            case 5:\n                print(f\"{Fore.GREEN}{users_dict}\")\n            case _:\n                print(Fore.RED + \"Opción incorrecta\")\n    except:\n        print(Fore.RED + \"Debe ingresar una de las 4 opciones!\")"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/cristianfloyd.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n#  * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n#  *\n#  */\n\n\n# Ejemplos de estructuras de datos en Python\n# Lista\nfrom typing import Optional\n\nprint(\"=\" * 80)\nprint(\"Listas en Python:\")\nmi_lista = [3, 1, 4, 1, 5]\nprint(\"Lista original:\", mi_lista)\nmi_lista.append(9)  # Inserción\nprint(\"Después de insertar 9:\", mi_lista)\nmi_lista.remove(1)  # Borrado\nprint(\"Después de borrar 1:\", mi_lista)\nmi_lista[0] = 10  # Actualización\nprint(\"Después de actualizar el primer elemento a 10:\", mi_lista)\nmi_lista.sort()  # Ordenación\nprint(\"Después de ordenar:\", mi_lista)\n\n# Diccionario\nprint(\"=\" * 80)\nprint(\"\\nDiccionarios en Python:\")\nmi_dict = {\"nombre\": \"Cristian\", \"edad\": 30, \"ciudad\": \"Quilmescity\"}\nprint(\"\\nDiccionario original:\", mi_dict)\n\nmi_dict.pop(\"ciudad\")  # borrado\nprint(f\"Eliminada la ciudad: {mi_dict}\")\n\nmi_dict[\"edad\"] = 31  # actualización\nprint(f\"Actualizada la edad: {mi_dict}\")\n\nmi_dict[\"profesion\"] = [\"Desarrollador\"]  # inserción\nprint(f\"Insertada la profesión: {mi_dict}\")\n\nmi_dict[\"profesion\"].append(\"Profesor\")  # actualización\nprint(f\"Actualizada la profesión: {mi_dict}\")\n\nmi_dict_ordenado = dict(sorted(mi_dict.items()))  # ordenación\nprint(f\"Diccionario ordenado por claves: {mi_dict_ordenado}\")\n\n# Conjunto\nprint(\"=\" * 80)\nprint(\"\\nConjuntos en Python:\")\nmi_set = {1, 5, 8, 0, 6, 7, 9}\nprint(\"\\nConjunto original:\", mi_set)\n\n# No se puede actualizar un set directamente, pero se puede eliminar y añadir\nmi_set.add(10)  # Inserción\nprint(\"Después de insertar 10:\", mi_set)\n\nmi_set.remove(0)  # Borrado\nprint(\"Después de borrar 0:\", mi_set)\n\nprint(\"=\" * 80)\nprint(\"Tuplas en Python:\")\n\nmi_tupla: tuple = (4, 2, 10, 6, 8)\nprint(\"Tupla original:\", mi_tupla)\n\nmi_tupla_ordenada = tuple(sorted(mi_tupla))  # Ordenación\nprint(\"Tupla ordenada:\", mi_tupla_ordenada)\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea una agenda de contactos por terminal.\n#  * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n#  * - Cada contacto debe tener un nombre y un número de teléfono.\n#  * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n#  *   los datos necesarios para llevarla a cabo.\n#  * - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n#  *   (o el número de dígitos que quieras)\n#  * - También se debe proponer una operación de finalización del programa.\n\n\ndef mi_agenda():\n    agenda: dict = {}\n\n    def opciones():\n        print(\"\")\n        print(\"1. Buscar contacto\")\n        print(\"2. Insertar contacto\")\n        print(\"3. Actualizar contacto\")\n        print(\"4. Eliminar contacto\")\n        print(\"5. Salir\")\n\n    def contacto_existe(nombre: str) -> bool:\n        if nombre in agenda:\n            return True\n        else:\n            return False\n    \n    def get_nombre(prompt: str) -> str:\n        return str(input(prompt)).strip().upper()\n    \n    def get_telefono(prompt: str) -> str:\n        telefono = str(input(prompt)).strip()\n        if es_nro_telefono_valido(telefono):\n            return telefono\n        else:\n            print(\n                \"Debes introducir un número de teléfono un máximo de 11 dígitos.\"\n            )\n            return \"\"\n\n    def es_nro_telefono_valido(telefono: str) -> bool:\n        return telefono.isdigit() and 0 < len(telefono) <= 11\n\n    def eliminar_contacto(nombre: str):\n        del agenda[nombre]\n        print(f\"El contacto {nombre} ha sido eliminado.\")\n\n    def insertar_contacto(nombre: str, telefono: str):\n        agenda[nombre] = telefono\n\n    def actualizar_contacto(nombre: str, telefono: Optional[str] = None) -> bool:\n        if contacto_existe(nombre) and (\n            telefono is None or es_nro_telefono_valido(telefono)\n        ):\n            if telefono is not None:\n                agenda[nombre] = telefono\n                return True\n            elif telefono is None:\n                nuevo_telefono = input(\"Introduce el nuevo teléfono del contacto: \")\n                if es_nro_telefono_valido(nuevo_telefono):\n                    agenda[nombre] = nuevo_telefono\n                    return True\n                else:\n                    print(\n                        \"Debes introducir un número de teléfono un máximo de 11 dígitos.\"\n                    )\n                    return False\n        else:\n            print(f\"El contacto {nombre} no existe.\")\n            return False\n\n    while True:\n        opciones()\n        input_option = input(\"\\nSelecciona una opción: \")\n\n        match input_option:\n            case \"1\":\n                nombre = get_nombre(\"Introduce el nombre del contacto a buscar: \")\n                if nombre in agenda:\n                    print(f\"\\nEl número de teléfono de {nombre} es {agenda[nombre]}.\")\n                    while True:\n                        input(\"Presione cualquier tecla para continuar...\")\n                        break\n            case \"2\":\n                nombre = get_nombre(\"Introduce el nombre del contacto a insertar: \")\n                phone = get_telefono(\"Introduce el teléfono del contacto: \")\n                insertar_contacto(nombre, phone)\n            case \"3\":\n                nombre = get_nombre(\"Introduce el nombre del contacto a actualizar: \")\n                actualizar_contacto(nombre) if contacto_existe(nombre) else print(\n                    f\"El contacto {nombre} no existe.\"\n                )\n            case \"4\":\n                nombre = get_nombre(\"Introduce el nombre del contacto a eliminar: \")\n                eliminar_contacto(nombre) if contacto_existe(nombre) else print(\n                    f\"El contacto {nombre} no existe.\"\n                )\n            case \"5\":\n                print(\"Saliendo...\")\n                break\n            case _:\n                print(\"Opción no válida\")\n                continue\n\n\nmi_agenda()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/d0ubt0.py",
    "content": "\n#Arrays  o Tuplas\ntupla = tuple(range(1,10))\nprint(tupla)\n#No permite ninguna operacion por defecto, se pueden realizar pero su funcion no es esa\n\n#Listas\nlista = list(range(1,10,2))\nlista.append(15)\nlista.insert(-3, 23)\nlista.pop(0)\nprint(lista)\nlista.sort()\nprint(lista)\n\n#Sets\nset1 = {11,10,5,3,2,5}\nset1.add(15)\nset1.remove(3)\nset1.pop()\nprint(set1)\n\n#Diccionarios\ndiccionario = {'nombre': 'd0ubt0'}\ndiccionario['edad'] = 20\nprint(diccionario['edad'])\ndiccionario['lenguaje'] = 'Python'\ndel diccionario['lenguaje']\nprint(diccionario)\n\n#EXTRA\nimport re\nclass Persona:\n    def __init__(self,nombre:str,numero:str) -> None:\n        self.nombre:str = nombre\n        self.numero:str = numero\n\n    def __str__(self) -> str:\n        return f'Nombre: {self.nombre}  Numero: {self.numero}'\n    \nclass Agenda:\n    def __init__(self) -> None:\n        self.lista_personas :list[Persona] = []\n        self.patron = r'^\\d{1,11}$'\n        print('Agenda creada')\n        self.interfaz()\n\n    def _crear_persona(self):\n        nombre = input('Nombre de la persona: ')\n        numero = self._preguntar_numero()\n        return Persona(nombre,numero)\n    \n    def mostrar_personas(self):\n        for i in self.lista_personas:\n            print(i)\n\n\n    def agregar_persona(self):\n        persona = self._crear_persona()\n        print('Persona Agregada')\n        print(persona)\n        self.lista_personas.append(persona)\n        \n    \n    def _buscar_por_numero(self,numero:str):\n        for i ,persona in enumerate(self.lista_personas):\n            if persona.numero == numero:\n                return i\n            \n    def _preguntar_numero(self):\n        numero = input('Numero de telefono: ')\n        while not bool(re.match(self.patron,numero)):\n            print('Numero de telefono invalido.Intente de nuevo')\n            numero = input('Numero de telefono: ')\n        return numero\n            \n    def actualizar_persona(self,numero:str):\n        index = self._buscar_por_numero(numero)\n        if index == None:\n            print('Persona no encontrada')\n        else:\n            print('Actualice los datos de ',self.lista_personas[index])\n            persona = self._crear_persona()\n            self.lista_personas[index] = persona\n            print('Persona actualizada')\n\n    def eliminar_persona(self,numero:str):\n        index = self._buscar_por_numero(numero)\n        if index == None:\n            print('Persona no encontrada')\n        else:\n            del self.lista_personas[index]\n            print('Persona eliminada')\n\n    def interfaz(self):\n        while True:\n            print()\n            accion  = input('Que accion quieres realizar: Agregar[0] , Eliminar[1] , Actualizar[2] , Eliminar[3] , Mostrar Agenda[4], Salir[5]\\nAccion: ')\n            if accion == '0':\n                print('Agregar persona')\n                self.agregar_persona()\n            elif accion == '1':\n                print('Eliminar persona por numero')\n                n = self._preguntar_numero()\n                self.eliminar_persona(n)\n            elif accion == '2':\n                print('Actualizar persona por numero')\n                n = self._preguntar_numero()\n                self.actualizar_persona(n)\n            elif accion == '3':\n                print('Actualizar persona por numero')\n                n = self._preguntar_numero()\n                self.eliminar_persona(n)\n            elif accion == '4':\n                print('Agenda completa')\n                self.mostrar_personas()\n            else:\n                break\n                \n\nagenda = Agenda()\n        \n\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/daniel-sanabria0419.py",
    "content": "'''\nESTRUCTURA DE DATOS\npython ofrece diferentes estructuras que permiten organizar, almacenar y manipular datos de diferentes maneras\n'''\n\n#0-1 listas\n\nmy_list = [1,2,3,\"hola\", 4.2, True] #se puede almacenar elementos de cualquier tipo se pueden modificar\nprint(my_list) \n\n\n#insersion de listas\nmy_list.append(\"hola\")\nmy_list.insert(2,\"adios\")\nprint(my_list) \n\n#eliminacion de listas\n\nmy_list.remove(\"hola\")\nmy_list.pop(3)\nprint(my_list) \n\n#slicing listas recourre la lista y la guarda\n\nmy_second_list = my_list[1::2]\nprint(my_second_list)\n\n#actualizacion de lista\n\nmy_second_list[0] = \"actualice lista\" \nprint(my_second_list)\n\n#ordenar listas\n\ndesorder_list = [6,3,7,2,100,6,3,1]\n\ndesorder_list.sort()\nprint(desorder_list)\n\n#tuplas\nmy_tuple = (1,2,3,\"adios\", 3.2, False) #listas pero nose peuden modificar\nprint(my_tuple)\n\n\n#acceder a los datos\nprint(my_tuple[0])\n\n#convertir en lista para que sea modificable\n\nlist_temporal = list(my_tuple)\n\nlist_temporal.append(\"insersion de datos a la lista\")\nmy_tuple = tuple(list_temporal)\n\nprint(my_tuple)\n\n#diccionario\n#tipo de almacenamieto en par donde se almacena su clave y su valor y se puede modificar\nmy_dictionary = {\"uno\" : 1, \"dos\" : 2, \"hello\": \"hola\", \"estado\": False, \"decimal\" : 3.2} \nprint(my_dictionary)\n\n#insercion de datos en diccionarios\nmy_dictionary['nuevo numero'] = 100\n\n\n#eliminacion de datos\n\ndel my_dictionary[\"estado\"]\nprint(my_dictionary)\nprint(my_dictionary.pop(\"hello\"))\nprint(my_dictionary)\n\n#conjuntos\n#se puede almacenar cualquier valor y modificar pero con elementos unicos y su orden siempre varia\nmy_set = { 3, 3, 5, 1, 2, 2, \"hola\", \"hola\", False, False}\nprint(my_set)\n\nmy_frozenset = frozenset([1, 2, 3, 3, 4, \"hello\", False]) #esto es un conjunto pero en este cambia que no se pueda modificar\nprint(my_frozenset)\n\n\n#operaciones matematicas con set\n\nA = {1, 2, 3, 4}\nB = {3, 4, 5, 6}\n\n# Unión (elementos en A o B)\nunion = A | B  # {1, 2, 3, 4, 5, 6}\nprint(union)\n\n# Intersección (elementos en A y B)\ninterseccion = A & B  # {3, 4}\nprint(interseccion)\n\n# Diferencia (elementos en A pero no en B)\ndiferencia = A - B  # {1, 2}\nprint(diferencia)\n\n# Diferencia simétrica (elementos en A o B, pero no en ambos)\ndif_simetrica = A ^ B  # {1, 2, 5, 6}\nprint(dif_simetrica)\n\n\n\n#cadenas\n\nmy_string = \"esto tambien es una estructura de datos\" #secuencia inmutable de caracteres\nprint(my_string)\n\n\ndef agenda_contactos():\n    list_contact={}\n   \n    while True:\n            accion = input(\"Bienvenido a la agenda de sus contactos \\n\"\n            \"Introduzca alguna de las siguientes opciones: \\n\"\n            \"1. Guardar Contacto\\n\"\n            \"2. Buscar Contacto\\n\"\n            \"3. Eliminar Contacto\\n\"\n            \"4. Actualizar Contacto\\n\"\n            \"0. Salir de la lista de Contactos\\n\"\n            \"Intrduzca el numero de la opcion que desa ----->\")\n            \n    \n            match accion:\n                case \"1\":\n                    name_contact = input(\"Como desea que se llame el nuevo contacto\\n\")\n                    if name_contact in list_contact:\n                        print(\"El contacto ya existe\")\n                    else:\n                        number_contact = input(\"Introduzca el numero\\n\")\n                        if len(number_contact) > 11:\n                    \n                            print(\"debe ingresar un numero menor a 11 digitos\\n\")\n                        else:\n                            list_contact[name_contact] = number_contact\n                            print(f\"Su numero a sido agregado asi quedo sus contactos\\n {list_contact}\\n\")\n                case \"2\":\n                    name_contact = input(\"Ingrese el nombre del contacto que desea buscar\\n\")\n                    if name_contact not in list_contact:\n                           print(\"El contacto no existe\\n\")\n                    else:\n                         print(f\"El numero de {name_contact} es = {list_contact[name_contact]}\")\n                case \"3\":\n                    name_contact = input(\"Ingrese el nombre del contacto que desea eliminar\\n\")\n                    if name_contact not in list_contact:\n                        print(\"El contacto no existe\")\n                    else:\n                         del list_contact[name_contact]\n                         print(f\"El contacto {name_contact} a sido eliminado, su agenda quedo asi\\n {list_contact}\\n\")\n                case \"4\":\n                    name_contact = input(\"Ingrese el nombre del contacto que desea editar\\n\")\n                    if name_contact not in list_contact:\n                         print(\"El contacto no existe\")\n                    else:\n                        number_contact = input(\"Ingrese el numero nuevo\\n\")\n                        if len(number_contact) > 11:\n                            print(\"el numero no peude ser mayor a 11 digitos\")\n                        else: \n                            list_contact[name_contact] =  number_contact  \n                            print(f\"El contacto de {name_contact} a sido actualizaado con el numero {number_contact} asi quedo sus contacto\\n {list_contact}\")   \n                case \"0\":\n                      print(\"salio del programa. Adios\")\n                      break\n                case _:\n                      print(\"No valido ingrese un dato que sea valido\")  \n\n              \n                \n                           \nagenda_contactos()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/danielhdzr.py",
    "content": "# #03 ESTRUCTURAS DE DATOS\n#### Dificultad: Media | Publicación: 15/01/24 | Corrección: 22/01/24\n\n## Ejercicio\n\n''' * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n '''\n\ndef main():\n    # CREAMOS LISTA\n    this_is_a_list = [1, 2, 3, 4]\n    print(this_is_a_list)\n    # insertar podemos usar el metodo insert en el index que deseamos (en este caso lo inserto al inicio)\n    this_is_a_list.insert(0, 0)\n    print(this_is_a_list)\n    # actualizar podemos usar el metodo append (agrega el objeto al final de la lista)\n    this_is_a_list.append(5)\n    print(this_is_a_list)\n    # ordenar podemos usar el metodo sort (yo lo use para odenarlo al reves con el parametro reverse=True)\n    this_is_a_list.sort(reverse=True)\n    print(this_is_a_list)\n    # borrar el contenido de la lista (no la lista en si misma) podemos usar el metodo clear\n    this_is_a_list.clear()\n    print(this_is_a_list)\n    \n    # CREAMOS DICCIONARIO\n    this_is_a_dictionary = {\"key1\" : 1, \"key2\" : 2, \"key3\" : 3}\n    print(this_is_a_dictionary)\n    # insertar, nombramos una nueva key en el diccionario, y asignamos su value correspondiente\n    this_is_a_dictionary[\"key4\"] = 4\n    print(this_is_a_dictionary)\n    # actualizar los objetos de un dict, incluyendo en este los objetos de un segundo dict\n    this_is_another_dictionary = {\"key5\": 5}\n    this_is_a_dictionary.update(this_is_another_dictionary)\n    print(this_is_a_dictionary)\n     # podemos actualizar, si accedemos al key que queremos modificar y le reasignamos un value nuevo\n    this_is_a_dictionary[\"key4\"] = \"four\"\n    print(this_is_a_dictionary)\n    # Nuevo diccionario\n    new_dict = {\"one\":1, \"three\":3, \"two\": 2, \"five\": 5, \"four\" : 4}\n    # ordenar mediante la funcion sorted y un dict comprehension (ordenando por keys)\n    # Ya que las keys son str, se ordenan en orden alfabetico\n    sorted_by_keys = {key: new_dict[key] for key in sorted(new_dict)}\n    print(f\"Sorted by keys: {sorted_by_keys}\")\n\n    # ordenar mediante la funcion sorted y un dict comprehension (ordenado por values)\n    sorted_by_values = {k: v for k, v in sorted(new_dict.items(), key=lambda item: item[1])}\n    print(f\"Sorted by values: {sorted_by_values}\")\n\n     # O bien podemos ordenar usando el modulo OrderedDict\n     # Ya que las keys son str, se ordenan en orden alfabetico\n    from collections import OrderedDict\n    ordered_dictionary = OrderedDict(sorted(new_dict.items()))\n    print(ordered_dictionary)\n    # Para borrar el contenido de la lista (no la lista en si misma) podemos usar el metodo clear\n    this_is_a_dictionary.clear()\n    print(this_is_a_dictionary)\n    new_dict.clear()\n    print(new_dict)\n\n    # CREAMOS SET (desordenado, no admite duplicados)\n    this_is_a_set = {2, 1, 3}\n    print(this_is_a_set)\n    # insertar podemos usar el metodo add y se agrega al final\n    this_is_a_set.add(4)\n    print(this_is_a_set)\n    # actualizar podemos usar el metodo update que actualiza el set uniendo los datos de otro set\n    new_set = {6, 5}\n    print(new_set)\n    this_is_a_set.update(new_set)\n    print(this_is_a_set)\n    # ordenar podemos convertir el set a una lista y ordenar la lista\n    list_from_set = sorted(this_is_a_set)\n    print(list_from_set)\n    # borrar el contenido del set usamos el metodo clear\n    this_is_a_set.clear()\n    print(this_is_a_set)\n\n    # CREAMOS TUPLA (inmutable)\n    this_is_a_tuple = (1, 2, 3, 4)\n    print(this_is_a_tuple)\n    # insertar y actualizar, convertimos la tupla a lista, le agregamos el miembro nuevo, y la reconvertimos a tupla\n    print(\"Tupla convertida a lista para insertar y actualizar\")\n    list_from_tuple = list(this_is_a_tuple)\n    list_from_tuple.append(5)\n    print(f\"Lista despues del append (insertamos) {list_from_tuple}\")\n\n    list_from_tuple.insert(4, 4.5)\n    print(f\"Lista despues del insert (actualizamos) {list_from_tuple}\")\n\n    this_is_a_tuple = tuple(list_from_tuple)\n    print(this_is_a_tuple)\n   \n    # ordenar la tupla, la convertimos a lista, usamos sort, y la reconvertimos a tupla tuple(\"nombre de la lista\")\n    unordered_tuple = (4,2,5,3,1)\n    print(f\"Tupla desordenada {unordered_tuple}\")\n    ordered_list = list(unordered_tuple)\n    ordered_list.sort()\n    unordered_tuple = tuple(ordered_list)\n    print(f\"Tupla Ordenada {unordered_tuple}\")\n    # borrar la tuple usamos la palabra reservada del\n    del this_is_a_tuple\n    \nif __name__==\"__main__\":\n    main()\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/davidrguez98.py",
    "content": "\"\"\" # #03 ESTRUCTURAS DE DATOS\n> #### Dificultad: Media | Publicación: 15/01/24 | Corrección: 22/01/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**. \"\"\"\n\n#LISTAS\n\nlistas = [1, 2, 3, 4]\nprint(listas)\n\nlistas.append(1)    #Inserción\nprint(listas)\nlistas.remove(2)    #Borrar\nprint(listas)\nlistas[1] = 5       #Actualizar\nprint(listas)\nlistas.sort()       #Ordenar\nprint(listas)\n\n#TUPLAS\n\ntuplas = (0, 1, 2, 3, 4)\nprint(tuplas)\n\ntuplas = tuple(sorted(tuplas))  #Ordenar\nprint(tuplas)\n\n#SETS\n\nmy_set = {\"David\", \"Rodriguez\", \"@davidrguez98\", \"26\"}\nprint(my_set)\n\nmy_set.add(\"ropeda98@gmail.com\")    #Inserción\nprint(my_set)\n\nmy_set.remove(\"David\")              #Borrar\nprint(my_set)\n\n#DICCIONARIOS\n\ndiccionario = {\n    \"hola\" : \"1\",\n    \"adios\" : \"2\",\n    \"you\" : \"7\"\n}\nprint(diccionario)\n\nprint(diccionario[\"hola\"])                          #Acceso\n\ndiccionario[\"hey\"] = \"3\"                            #Incersión\nprint(diccionario)\n\ndiccionario[\"hey\"] = \"4\"                            #Actualización\nprint(diccionario)\n\ndel diccionario[\"adios\"]                            #Borrar\nprint(diccionario)\n\ndiccionario = dict(sorted(diccionario.items()))     #Ordenar\nprint(diccionario)\n\n\"\"\"  * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */ \"\"\"\n\ndef my_agend():\n\n    agend = {}\n\n    def insert_contact():\n        phone_number = input(\"Introduce el número del contacto: \")\n        if phone_number.isdigit() and len(phone_number) > 0 and len(phone_number) < 12:\n            agend[name] = phone_number\n            print(f\"El contacto {name} con teléfono {phone_number} se ha añadido correctamente\")\n        else:\n            print(\"\\nEl teléfono marcado es incorrecto. Introduce un teléfono válido con un máximo de 11 dígitos\")\n\n    while True:\n\n        print(\"\")\n        print(\"1. Buscar un contacto.\")\n        print(\"2. Añade un contacto.\")\n        print(\"3. Actualiza un contacto.\")\n        print(\"4. Elimina un contacto.\")\n        print(\"5. Salir de la agenda.\")\n        selection = input(\"\\nSelecciona una de las opciones anteriores: \")\n\n\n        match selection:\n            case \"1\":\n                name = input(\"Introduce el nombre del contacto que quiere buscar: \")\n                if name in agend:\n                    print(f\"El número de teléfono del contacto {name} es {agend[name]}\")\n                else:\n                    print(\"\\nEl contacto que ha introducido no está en su agenda\")\n            case \"2\":\n                name = input(\"Introduce el nombre del contacto que quiere añadir: \")\n                insert_contact()\n            case \"3\":\n                name = input(\"Introduce el nombre del contacto que quiere actualizar: \")\n                insert_contact()\n            case \"4\":\n                name = input(\"Introduce el nombre del contacto que quiere eliminar: \")\n                if name in agend:\n                    print(f\"El contacto {name} ha sido eliminado\")\n                    del agend[name]\n                else:\n                    print(f\"\\nEl contacto {name} no está en su agenda.\")\n            case \"5\":\n                break\n            case \"6\":\n                print(\"\\nLa opción marcada no es correcta. Selecciona un número del 1 al 5.\")\n\nmy_agend()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/dchevesich.py",
    "content": "def my_agenda():\n    diccionario = {}\n\n    def agregar_usuario():\n        telefono = input(\n            \"Ingrese numero de telefono no debe superar los 11 caracteres\")\n        if telefono.isdigit() and len(telefono) < 11:\n            diccionario[usuario] = telefono\n        else:\n            print(\"numero no cumple condiciones\")\n\n    while True:\n        print(\"Bienvenido a la terminal\")\n        print(\"1. Ingresar usuario: \")\n        print(\"2. Para Buscar usuario: \")\n        print(\"3. Para Eliminar usuario: \")\n        print(\"4. Para Actualizar usuario: \")\n        print(\"5. Para salir.\")\n        opcion_usuario = input(\"Ingrese una opción: \")\n        match opcion_usuario:\n            case \"1\":\n                usuario = input(\"Ingrese usuario: \")\n                agregar_usuario()\n            case \"2\":\n                usuario = input(\"Ingrese usuario a buscar: \")\n                if usuario in diccionario:\n                    print(\n                        f\"El número de teléfono de {usuario} es {diccionario[usuario]}.\")\n                else:\n                    print(f\"Usuario {usuario} no encontrado\")\n            case \"3\":\n                usuario = input(\"Introduce el usuario a eliminar: \")\n                if usuario in diccionario:\n                    del diccionario[usuario]\n                    print(\"Usuario eliminado correctamente\")\n                else:\n                    print(\"Usuario no existe\")\n            case \"4\":\n                usuario = input(\"Introduce el usuario a actualizar: \")\n                if usuario in diccionario:\n                    agregar_usuario()\n                else:\n                    print(\"Usuario no existe\")\n            case \"5\":\n                print(\"Saliendo del programa\")\n                break\n            case _:\n                print(\"Opcion invalida favor de leer las intrucciones\")\n\n\nmy_agenda()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/dimasb69.py",
    "content": "import os\n\"\"\"\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto\n *   en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n *   y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n *   y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no numéricos y con más\n *   de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.\n\"\"\"\n\n#En Python se pede usar Listas Tuplas Set  y Diccionarios. asi com archivos externos para alamcenar estructuras\n# que ya\n# hoy\n# en dia estan integradas en el lenguaje de forma nativa como sqlite, json, etc\n#en estos ejemplos usaremos en Tuplas Diccionarios Sets y listas\n\n\n#Ejemplo de lista\nlista = [1,3,'Hola Mundo',5,7]\nprint ('lista original')\nprint (lista)\nprint ('\\n')\n\"\"\"Las listas son una estructura de datos que permite almacenar una coleccion de elementos\nde cualquier tipo de dato, las listas son mutables, es decir que pueden cambiar su contenido y puede tener valores duplicados\ny se declara con corchetes []\"\"\"\n\n#Ejemplo de tupla\ntupla = (1,3,'Hola Mundo',5,7)\nprint ('tupla original')\nprint (tupla)\nprint ('\\n')\n\"\"\"Las tuplas son una estructura de datos que permite almacenar una coleccion de elementos\nde cualquier tipo de dato, las tuplas son inmutables, es decir que no pueden cambiar su contenido y puede tener valores duplicados\ny se declara con parentesis ()\"\"\"\n\n#Ejemplo de diccionario\ndiccionario = {'clave1': 1, 'clave2': 'Hola Mundo', 'clave3': 3, 'clave4': 5, 'clave5': 7}\nprint ('diccionario original')\nprint (diccionario)\nprint ('\\n')\n\"\"\"Los diccionarios son una estructura de datos que permite almacenar una coleccion de elementos\nde cualquier tipo de dato, los diccionarios son mutables, es decir que pueden cambiar su contenido\nLos diccionarios se caracterizan por tener una clave y un valor, es decir que la clave es un identificador y el valor es lo que vamos a almacenar\ny puede tener valores duplicados pero la clave debe ser unica\ny se declara con llaves {}\"\"\"\n\n#Ejemplo de set\nset = {1,3,'Hola Mundo',5,7}\nprint ('set original')\nprint (set)\nprint ('\\n')\n\"\"\"Los sets son una estructura de datos que permite almacenar una coleccion de elementos\nde cualquier tipo de dato, los sets son mutables, es decir que pueden cambiar su contenido\nLos sets se caracterizan por tener elementos unicos, es decir que no se pueden repetir elementos\ny se declara con llaves {}\"\"\"\n\n#Manejo de listas\nprint(\"\\nManejo de listas\")\n#agregamos un elemento a la lista\nlista.append(6)\nprint ('lista con append')\nprint (lista)\n#borramos un elemento de la lista\nlista.remove(6)\nprint ('lista con remove')\nprint (lista)\n#ordenamos la lista\nprint ('para ordenar la lista se usa el metodo sorted iterando la lista todos los elementos deben ser comparables si '\n       'hay alguno que no lo sea se da error')\ndef funcionOrder(l):\n    try:\n        sorted(l)\n        return 'ordenada'\n    except Exception as e:\n        return f'{e}'\nprint (funcionOrder(lista))\nprint('cambiamos el valor de la lista que contiene string y ordenamos nuevamente')\nlista[2] = 8\nprint ('lista con update')\nprint (lista)\nlista.sort()\nprint ('lista con sort')\nprint (lista)\n#modificamos un elemento de la lista\nlista[0] = 7\nprint ('lista con update, se cambia el valor de un elemento en la posicion 0')\nprint (lista)\n#borramos todos los elementos de la lista\nlista.clear()\nprint ('lista con clear')\nprint (lista)\n\n\n#Manejo de tuplas\nprint(\"\\nManejo de tuplas\")\nprint('como son inmutables no podemos agregar o borrar elementos u ordenar')\n#como son inmutables no podemos agregar o borrar elementos\n\n\n#Manejo de diccionarios\nprint(\"\\nManejo de diccionarios\")\n#agregamos un elemento a la diccionario\ndiccionario['clave4'] = 'valor4'\nprint ('diccionario con append')\nprint (diccionario)\n#borramos un elemento de la diccionario\ndel diccionario['clave4']\nprint ('diccionario con remove')\nprint (diccionario)\n#ordenamos la diccionario\n#para ordenar la diccionario se usa el metodo sorted iterando la diccionario todos los elementos deben ser comparables si\n#hay alguno que no lo sea se da error\ndef ordenar_diccionario(d):\n    try:\n        new_d = dict(sorted(d.items(), key=lambda item: item[1]))\n        print( 'ordenada')\n        print (new_d)\n        diccionario.clear()\n        diccionario.update(new_d)\n    except Exception as e:\n        print( f'{e}')\nprint('intentamos ordenar el diccionario con el string')\nprint (ordenar_diccionario(diccionario))\n#modificamos un elemento de la diccionario\nprint('cambiamos el valor de la diccionario que contiene string y ordenamos nuevamente')\ndiccionario['clave2'] = 9\nprint (ordenar_diccionario(diccionario))\n#Modificamos un elemento de la diccionario\nprint ('diccionario con update')\nprint('')\ndiccionario['clave1'] = 999\nprint (diccionario)\n#borramos todos los elementos de la diccionario\ndiccionario.clear()\nprint ('diccionario con clear')\nprint (diccionario)\n\n#Manejo de sets\nprint(\"\\nManejo de sets\")\n#agregamos un elemento a la set\nprint ('Al agregar y si son iguales a otro elemento lo ignora')\nset.add(6)\nprint ('set con el item agredado')\nprint (set)\n#borramos un elemento de la set\nset.remove(6)\nprint ('set con remove')\nprint (set)\n#modificamos un elemento y ordenamos la set\nprint ('el set no permite modificar los elementos y si intentamos ordernar un set no nos sirve por que al orderna '\n       'retorna una lista y no un set')\n#unir dos sets\nprint('una unir dos sets se usa el metodo union')\nset1 = set.copy()\nset2 = {10,20,16}\nset3 = set1.union(set2)\nprint ('set con union')\nprint (set3)\n#interseccion de dos sets\nprint('otra forma de unir dos sets es con el metodo intersection, une los set y devuelve solo los elementos en comun '\n      'y lo retorna eordenado')\nset4 = set.intersection(set3)\nprint ('set con intersection')\nprint (set4)\n#diferencia de dos sets\nprint('otra forma de unir dos sets es con el metodo difference, une los set y devuelve solo los elementos que estan '\n      'en el set 1 y no en el set 2 y lo retorna eordenado')\nset5 = set2.difference(set4)\nprint ('set con difference')\nprint (set5)\n#borramos todos los elementos de la set\nset.clear()\nprint ('set con clear')\nprint (set)\n\n\n\"Crea una agenda de contactos por terminal.\"\nprint('\\n\\nAgenda de contactos, que usa el nombre como clave y el telefono como valor y se guarda en un diccionario')\nprint('-'*100)\nprint('\\n\\n')\nagenda = {}\n\ndef telefonoValido():\n    telefono = input(\"Introduzca el telefono: \")\n    while True:\n        if len(telefono) > 11 and len(telefono) < 9:\n            print(\"Telefono no valido, intenta de nuevo\\n\")\n            telefono = input(\"Telefono: \")\n        elif not telefono.isdigit():\n            print(\"Telefono no valido, intenta de nuevo\\n\")\n            telefono = input(\"Telefono: \")\n        else:\n            break\n    return telefono\n\ndef limpiar_pantalla():\n    \"\"\"Limpia la consola.\"\"\"\n    if os.name == 'nt':\n        # Windows\n        os.system('cls')\n    else:\n        # Linux, macOS, etc.\n        os.system('clear')\n\nwhile True:\n    print(\"1. Nuevo contacto\")\n    print(\"2. Buscar un contacto\")\n    print(\"3. Ver agenda\")\n    print(\"4. Editar un contacto\")\n    print(\"5. Eliminar un contacto\")\n    print(\"6. Terminar\")\n    opcion = input(\"Selecciona una opcion: \")\n    if opcion == \"1\":\n        nombre = input(\"Nombre: \")\n        telefono = telefonoValido()\n        agenda[nombre.upper()] = telefono\n        limpiar_pantalla()\n    elif opcion == \"2\":\n        nombre = input(\"Nombre: \")\n        nombre = nombre.upper()\n        limpiar_pantalla()\n        if nombre in agenda:\n            print(f\"Telefono: {agenda[nombre]} \\n\\n\")\n        else:\n            limpiar_pantalla()\n            print(\"Contacto no encontrado\\n\\n\")\n    elif opcion == \"3\":\n        limpiar_pantalla()\n        for nombre, telefono in agenda.items():\n            print(f\"{nombre}: {telefono}\")\n        print(\"\\n\\n\")\n    elif opcion == \"4\":\n        nombre = input(\"Introduce el Nombre a editar: \")\n        nombre = nombre.upper()\n        if nombre in agenda:\n            telefono = telefonoValido()\n            agenda[nombre] = telefono\n            limpiar_pantalla()\n            print(f\"{nombre} actualizado \\n\\n\")\n        else:\n            limpiar_pantalla()\n            print(\"Contacto no encontrado\\n\\n\")\n    elif opcion == \"5\":\n        nombre = input(\"Introduce el Nombre a eliminar: \")\n        nombre = nombre.upper()\n        if nombre in agenda:\n            del agenda[nombre]\n            limpiar_pantalla()\n            print(f\"{nombre} eliminado \\n\\n\")\n        else:\n            limpiar_pantalla()\n            print(\"Contacto no encontrado\\n\\n\")\n    elif opcion == \"6\":\n        limpiar_pantalla()\n        print(\"Hasta pronto\\n\\n\")\n        break\n    else:\n        limpiar_pantalla()\n        print(\"Opcion no valida, elige una opcion del 1 al 6 \\n\")\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/duendeintemporal.py",
    "content": "#3 { Retos para Programadores } ESTRUCTURAS DE DATOS\n# # Assigning the print function to log\nlog = print\n\n# Primitive Data Types\n# Number: Represents both integer and floating-point numbers.\n# Python uses the built-in float type to represent both integers and floating-point values.\n\nage = 35  # Integer\ntotal = 118.87  # Floating-point\nlog('age:', age, ', total:', total)  # age: 35, total: 118.87\nlog(0.3)  # 0.3\n# To define a floating-point value, you must include a decimal point and at least one number after the decimal point.\n\noct_num = 0o45  # Octal representation\nlog(oct_num)  # 37\n\nhex_num = 0x2f  # Hexadecimal representation\nlog(hex_num)  # 47\n# Note: Numbers created using octal or hexadecimal format are treated as decimal numbers in all arithmetic operations.\n\n# There is a special numeric value called NaN (Not a Number) in Python, represented by float('nan').\n# It indicates when an operation intended to return a number has failed.\n# For example, dividing any number by 0 raises an error in Python, unlike JavaScript.\n\n# The value NaN has unique properties. Any operation involving NaN always returns NaN.\n# In Python, we can check for NaN using math.isnan().\n\nimport math\n\nlog('Hi man how you doing?' * 4)  # Hi man how you doing?Hi man how you doing?Hi man how you doing?Hi man how you doing?\nlog(math.isnan(math.nan))  # True, since NaN is not equal to itself\n\n# For this reason, Python provides the math.isnan() function.\n\ntry:\n    # Attempt to check if the value is NaN\n    print(math.isnan(\"04\"))  # This will raise a TypeError\nexcept TypeError as e:\n    # Handle the TypeError that occurs when the input is not a float\n    print(f\"Error: {e}. The input must be a float. Cannot be converted to NaN\")\n\n# Note: There is a particular difference between the float() and int() functions when they are used to convert types.\n\n# String: Represents a sequence of characters.\n# The str data type represents a sequence of zero or more Unicode characters.\n# Strings can be delineated by either double quotes (\"), single quotes ('), or triple quotes (''' or \"\"\")\n\ndreamy_girl = \"Lucy\"\nsong = dreamy_girl + ' in the sky with diamonds'\nsong_info = f'\"{song}\" is a song from The Beatles that alludes to LSD'\nlog(song_info)  # \"Lucy in the sky with diamonds\" is a song from The Beatles that alludes to LSD\n\n# Character Literals\n# The String data type includes several character literals to represent nonprintable or otherwise useful characters.\n# In Python, escape sequences are similar to JavaScript.\n\n# Example of escape sequences:\n# \\n New line\n# \\t Tab\n# \\\\ Backslash (\\)\n# \\' Single quote (')\n# \\\" Double quote (\")\n\n# Template literals in Python can be achieved using f-strings.\nnum1 = 40\nnum2 = 80\n\nsum_result = f'{num1} + {num2} = {num1 + num2}'\nlog(sum_result)  # \"40 + 80 = 120\"\n\n# Raw Strings\n# In Python, raw strings can be created by prefixing the string with 'r'.\n# This prevents escape sequences from being processed.\n\n# Unicode demo\n# \\u57A8 is the 垨 character.\nlog('\\u57A8')  # 垨\n\n# Raw string demo\nlog(r'\\u57A8')  # \\u57A8\n\n# Newline demo\nlog('first line\\nsecond line')  # first line\\nsecond line\nlog(r'first line\\nsecond line')  # first line\\nsecond line\n\n# Boolean: Represents a logical entity and can have two values: True and False.\n# The Boolean type is one of the most frequently used types in Python.\n# In Python, True and False are case-sensitive and distinct from numeric values.\n\nis_checked = True\nlog(not is_checked)  # False\n# Note that the Boolean literals True and False are case-sensitive.\n\n# Undefined: A variable that has been declared but has not yet been assigned a value.\nsomebody = None  # In Python, None is used to represent the absence of a value.\nlog(somebody)  # None\n\nexplicitly_undefined = None  # Using None instead of void(0)\nlog(explicitly_undefined)  # None\n# Note: The use of void(0) is not applicable in Python.\n\n# Null: Represents the intentional absence of any object value.\n# In Python, None is commonly used to initialize variables.\nanimals = None\nlog(animals)  # None\n\n# Symbol: A unique and immutable primitive value, often used as object property keys.\n# Python does not have a direct equivalent to JavaScript's Symbol, but we can use unique objects.\n\nclass UniqueSymbol:\n    def __init__(self, name):\n        self.name = name\n\nId = UniqueSymbol('xm')\nother_id = UniqueSymbol('xm')\nlog('equal symbols:', Id == other_id)  # False, as they are different instances\n\n# You can also use unique identifiers as object properties.\n\n# Create a unique identifier for the email property\nemail_symbol = UniqueSymbol('email')\n\nclass User:\n    def __init__(self, name, email):\n        self.name = name\n        self.__dict__[email_symbol.name] = email  # Use the unique symbol as the key for the email property\n\n    # Method to get the email\n    def get_email(self):\n        return self.__dict__[email_symbol.name]\n\n# Create a new user\nuser1 = User('Barbarella', 'softbaby@something.com')\n\nlog(user1.name)  # Barbarella\nlog(user1.get_email())  # softbaby@something.com\n\n# Trying to access the email property directly\nlog(user1.__dict__.get(email_symbol.name))  # softbaby@something.com\nlog(getattr(user1, 'email', None))  # None, as 'email' is not a property of the object\n\n# BigInt: Represents integers with arbitrary precision.\nbig_number = 765466743212345679874653358945321\nlog(big_number)  # 765466743212345679874653358945321\n\n# Note: Many modern cryptographic libraries and implementations do use arbitrary precision integers\n# to handle large integers, especially for operations that involve large prime numbers.\n\n# Reference Data Types\n\n# Object: A collection of key-value pairs. In Python, this is represented by a dictionary.\ndebian = {\n    'name': 'Debian',\n    'description': 'Ardilla parlante cuyo nucleo esta basado en un Sistema Operativo del mismo nombre, lucha contra el Sistema establecido y habita más alla del Borde(el Universo conocido)',\n    'location': 'No Found',\n}\n\n# Method to simulate speaking (not directly translatable from JS arrow function)\ndef speak():\n    log(debian['description'])\n\n# Call the speak function\nspeak()  # Ardilla parlante cuyo nucleo esta basado en un Sistema Operativo del mismo nombre, lucha contra el Sistema establecido y habita más alla del Borde(el Universo conocido)\n\nimport random\n\n# Array: A special type of object used to store ordered collections of values.\n# In Python, lists are used to store ordered collections of values and can hold elements of any type.\n\nfriends = ['Susan', 'Maryatta', 'Denise', 'Luna', 'Kena', 'Maria']\nlog(friends)  # Logs the list of friends\n\n# Function: A special type of object that can be called to perform a specific task.\n# Functions can also be stored in variables, passed as arguments, and returned from other functions.\n\nfrom_value = 4\nto_value = 12\n\ndef random_value(from_value, to_value):\n    return random.randint(from_value, to_value)\n\ncount = from_value\nwhile count <= to_value:\n    log('random value:', random_value(from_value, to_value))\n    count += 1\n# Logs: numbers between 4 and 12 inclusive\n\n# Specialized Data Structures\n# Set: A collection of unique values. In Python, sets can store any type of value, and duplicate values are automatically removed.\n\nunique_numbers = {4, 4, 3, 5, 8, 1, 8, 1, 7}\nlog(unique_numbers)  # Logs: {1, 3, 4, 5, 7, 8}\n\n# Dictionary: A collection of key-value pairs where keys can be of any type.\n# In Python, dictionaries maintain the insertion order of their elements.\n\nmap_dict = {}\nmap_dict['gopi_name'] = 'Khamala'\nmap_dict['age'] = 35\nlog(map_dict['gopi_name'])  # Logs: Khamala\n\n# Note: Python does not have a direct equivalent to WeakSet and WeakMap.\n# However, we can use weak references from the `weakref` module.\n\nimport weakref\n\n# Define a custom class that can be weakly referenced\nclass MyObject:\n    pass\n\n# WeakSet: Similar to a Set, but it holds \"weak\" references to its values.\nweak_set = weakref.WeakSet()\nobj = MyObject()  # Create an instance of MyObject\nweak_set.add(obj)\nprint(obj in weak_set)  # Logs: True\n\n# WeakMap: Similar to a Map, but it holds \"weak\" references to its keys.\nweak_map = weakref.WeakKeyDictionary()\nkey_obj = MyObject()  # Create an instance of MyObject\nweak_map[key_obj] = \"crasylady\"\nprint(weak_map[key_obj])  # Logs: crazylady\n\n# Note: Garbage collection allows memory management by automatically allocating what is needed\n# and reclaiming memory that is no longer being used.\n\n# Typed Arrays: Python does not have a direct equivalent to JavaScript's typed arrays.\n# However, we can use the `array` module for similar functionality.\n\nfrom array import array\n\n# int8Array: Represents an array of 8-bit integers.\nint8_array = array('b', [-3, 5, -8, 99, 76])\nlog(int8_array.tolist())  # Logs: [-3, 5, -8, 99, 76]\n\n# Uint8Array: Represents an array of 8-bit unsigned integers.\nuint8_array = array('B', [1, 2, 3])\n\n# Uint8ClampedArray: Not directly available in Python, but we can clamp values manually.\nuint8_clamped_array = [max(0, min(255, x)) for x in [-1, 256, 100]]\n\n# Int16Array: Represents an array of 16-bit signed integers.\nint16_array = array('h', [1, -2, 3])\n\n# Uint16Array: Represents an array of 16-bit unsigned integers.\nuint16_array = array('H', [1, 2, 3])\n\n# Int32Array: Represents an array of 32-bit signed integers.\nint32_array = array('i', [1, -2, 3])\n\n# Uint32Array: Represents an array of 32-bit unsigned integers.\nuint32_array = array('I', [1, 2, 3])\n\n# Float32Array: Represents an array of 32-bit floating-point numbers.\nfloat32_array = array('f', [1.5, 2.5, 3.5])\n\n# Float64Array: Represents an array of 64-bit floating-point numbers.\nfloat64_array = array('d', [1.5, 2.5, 3.5])\n\n# BigInt64Array: Python's int can handle arbitrary precision, so we can use it directly.\nbig_int64_array = [1, 2, 3]  # Using a regular list for BigInt64Array\n\n# BigUint64Array: Similar to BigInt64Array, using regular list for BigUint64Array.\nbig_uint64_array = [1, 2, 3]\n\n# Logs: [1, 2, 3]\n# Note: In Python, integers can be of arbitrary precision, so we don't have a specific BigInt type.\n\n# Simulating a window event listener in a web environment\n# In Python, we don't have a direct equivalent to the browser's window object,\n# but we can simulate the behavior using a function.\n\ndef on_load():\n    # Simulating the body of a web page\n    body_style = {\n        'background': '#000',\n        'text-align': 'center'\n    }\n    \n    title = 'Retosparaprogramadores #3.'\n    title_style = {\n        'font-size': '3.5vmax',\n        'color': '#fff',\n        'line-height': '100vh'\n    }\n    \n    # Simulating the addition of the title to the body\n    log(f\"Title: {title} (styled with {title_style})\")\n    \n    # Simulating an alert\n    print('Retosparaprogramadores #3. ')\n\n# Simulating the load event\non_load()\n\n\n'''   EXTRA DIFFICULTY (optional):\n   Create a contact book via the terminal.\n       You must implement functionalities for searching, inserting, updating, and deleting contacts.\n       Each contact must have a name and a phone number.\n       The program first asks which operation you want to perform, and then the necessary data to carry it out.\n       The program cannot allow the input of non-numeric phone numbers and those with more than 11 digits (or the number of digits you choose).\n       An option to terminate the program should also be provided.\n'''\n\nimport re\n\n# Initialize an empty list to store contacts\ncontacts = []\n\ndef show_menu():\n    print(\"--- List of Contacts ---\")\n    print(\"1. Insert Contact\")\n    print(\"2. Search Contact\")\n    print(\"3. Update Contact\")\n    print(\"4. Delete Contact\")\n    print(\"5. Exit\")\n    \n    option = input(\"Choose an Option: \")\n    if option == '1':\n        insert_contact()\n    elif option == '2':\n        search_contact()\n    elif option == '3':\n        update_contact()\n    elif option == '4':\n        delete_contact()\n    elif option == '5':\n        print(\"Exiting the program...\")\n    else:\n        print(\"No Valid Option. Try again.\")\n        show_menu()\n\ndef insert_contact():\n    try:\n        name = input(\"Type the contact name: \")\n        \n        telefone = input(\"Type the telephone number (11 digits): \")\n        if not re.match(r'^\\d{11}$', telefone):\n            print(\"Invalid telephone number. Must be a numeric value and have 11 digits.\")\n            return show_menu()\n        \n        email = input(\"Type the email of the contact: \")\n        email_regex = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$'\n        if not re.match(email_regex, email):\n            print(\"Invalid email. Must be a valid email address.\")\n            return show_menu()\n        \n        contacts.append({'name': name, 'telefone': telefone, 'email': email})\n        print(f\"Contact {name} added.\")\n    \n    except Exception as error:\n        print(\"An error occurred:\", error)\n    finally:\n        show_menu()\n\ndef search_contact():\n    name = input(\"Enter the name of the contact to search: \")\n    contact = next((c for c in contacts if c['name'].lower() == name.lower()), None)\n    if contact:\n        print(f\"Contact found: {contact['name']}, Telefone: {contact['telefone']}, Email: {contact['email']}\")\n    else:\n        print(\"Contact not found.\")\n    show_menu()\n\ndef update_contact():\n    try:\n        name = input(\"Type the name of the contact to update: \")\n        contact = next((c for c in contacts if c['name'].lower() == name.lower()), None)\n        \n        if contact:\n            telefone = input(\"Type the new telephone number (11 digits): \")\n            if re.match(r'^\\d{11}$', telefone):\n                contact['telefone'] = telefone\n                print(f\"Contact {name} updated with new number.\")\n            else:\n                print(\"Invalid telephone number. Must be a numeric value and have 11 digits.\")\n            \n            email = input(\"Type the email of the contact: \")\n            email_regex = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$'\n            if re.match(email_regex, email):\n                contact['email'] = email\n                print(f\"Contact {name} updated with new email.\")\n            else:\n                print(\"Invalid email. Must be a valid email address.\")\n        else:\n            print(\"Contact not found.\")\n    \n    except Exception as error:\n        print(\"An error occurred:\", error)\n    finally:\n        show_menu()\n\ndef delete_contact():\n    name = input(\"Type the name of the contact to delete: \")\n    index = next((i for i, c in enumerate(contacts) if c['name'].lower() == name.lower()), None)\n    if index is not None:\n        deleted_contact = contacts.pop(index)\n        print(f\"Contact {deleted_contact['name']} deleted.\")\n    else:\n        print(\"Contact not found.\")\n    show_menu()\n\n# Start the program\nshow_menu()\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/eamartin96.py",
    "content": "# #03 ESTRUCTURAS DE DATOS\n# Muestra ejemplos de creacion de todas las estructuras soportadas por defecto en tu lenguaje\n# Utiliza operaciones de inserccion, borrado, actualizacion y ordenacion.\n\n# Lista\nprint(\"List\")\nList = [\"Python\", \"C\", \"JavaScript\", \"Ruby\"]\nprint(List)\n\n## Insercion\nprint(\"New element to append: 'Go'\")\nList.append(\"Go\")\nprint(\"New List\", List)\n\nprint(\"New element to insert: 'HTML' in position 1\")\nList.insert(1, \"HTML\")\nprint(\"New List\", List)\n\n## Borrado\nprint(\"Element to remove: 'Ruby'\")\nList.remove(\"Ruby\")\nprint(\"New List\", List)\n\nprint(\"Element to pop: 'Python'\")\nList.pop(0)\nprint(\"New List\", List)\n\n## Ordenamiento\nprint(\"Ordered List\")\nList.sort()\nprint(\"New List\", List)\n\n# Lista\nList = [\"Python\", \"C\", \"JavaScript\", \"Ruby\"]\nprint(List)\n\n## Insercion\nprint(\"New element to append: 'Go'\")\nList.append(\"Go\")\nprint(\"New List\", List)\n\nprint(\"New element to insert: 'HTML' in position 1\")\nList.insert(1, \"HTML\")\nprint(\"New List\", List)\n\n## Borrado\nprint(\"Element to remove: 'Ruby'\")\nList.remove(\"Ruby\")\nprint(\"New List\", List)\n\nprint(\"Element to pop: 'Python'\")\nList.pop(0)\nprint(\"New List\", List)\n\n## Ordenamiento\nprint(\"Ordered List\")\nList.sort()\nprint(\"New List\", List)\n## Primer elemento de la lista\nprint(\"First element of List\")\nprint(List[0])\n\n## Ultimo elemento de la lista\nprint(\"Last element of List\")\nprint(List[-1])\n\nprint()\n\n#----------------------------------------------------------\n# Dictionary\nprint(\"Dictionary\")\nDictionary = {0:\"Python\", 1:\"C\", 2:\"JavaScript\", 3:\"Ruby\"}\n\n## Accessar por medio de clave\nprint(\"Accesing element using key\")\nprint(Dictionary[0])\n\n## Accessar usando get\nprint(\"Accesing element using get\")\nprint(Dictionary.get(1))\n\nprint()\n#----------------------------------------------------------\n# Tuple\nprint(\"Tuple\")\nTuple = (\"Python\", \"C\", \"JavaScript\", \"Ruby\")\nprint(Tuple)\n\n## Primer elemento de la lista\nprint(\"First element of Tuple\")\nprint(Tuple[0])\n\n## Ultimo elemento de la lista\nprint(\"Last element of Tuple\")\nprint(Tuple[-1])\n\nprint()\n#----------------------------------------------------------\n# Dificultad Extra\n'''\n Crea una agenda de contactos por terminal.\n - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n - Cada contacto debe tener un nombre y un número de teléfono.\n - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n   los datos necesarios para llevarla a cabo.\n - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n   (o el número de dígitos que quieras)\n - También se debe proponer una operación de finalización del programa.\n'''\n\nagenda = {}\n\ndef search(data):\n    if data.isdigit():\n        for key, value in agenda.items():\n            if value == int(data):\n                print(f\"{key}: {value}\")\n    else:\n        if data in agenda:\n            print(f\"{data}: {agenda[data]}\")\n\ndef insert(name, number):\n    if name not in agenda:\n        agenda[name] = number\n    else:\n        print(f\"{name} is in the agenda\")\ndef remove(name):\n    print(f\"{name}: {agenda[name]} was removed\")\n    del agenda[name]\n\ndef show():\n    for item in agenda:\n        print(f\"{item}: {agenda[item]:>5}\")\ndef update(name, number):\n    agenda[name] = number\n\ndef main():\n    while True:\n        print(\"Phone Agenda\")\n        option = input(\"1: Serach\\n2: Insert\\n3: Remove\\n4: Show\\n5: Update\\nX: Exit\\n\\t Option: \")\n        if option == '1':\n            data = input(\"Enter a name or number: \")\n            search(data)\n        if option == '2':\n            name = input(\"Enter a name: \")\n            while True:\n                number = input(\"Enter a number: \")\n                if not number.isdigit() or len(number) > 10:\n                    print(\"Number is not valid, try again\")\n                else:\n                    break\n            insert(name, number)\n        if option == '3':\n            name = input(\"Enter a name: \")\n            remove(name)\n        if option == '4':\n            show()\n        if option == '5':\n            name = input(\"Enter a name: \")\n            number = int(input(\"Enter a number: \"))\n            update(name, number)\n        if option == 'X':\n            break\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/eberstr.py",
    "content": "\nlista = [1, 2, \"text\", True]\ndiccionario = {\"llave\": \"valor\", \"llave2\": \"valor\"}\nconjunto = {'se', 'puede', 'definir', 'con', 'set'}\ntupla = (1,\"Texto\", lista)\n\n# Operaciones de Insercion\nlista.append(\"nuevo\")\nlista.extend('abc')\nlista.insert(0, \"primero\")\n\ndiccionario['nuevo'] = 'nuevo2'\n\nconjunto.add('nuevo')\n\n# borrado\nlista.remove('a')\nlista.pop(1)\nlista.clear()\n\ndiccionario.pop('nuevo')\n\nconjunto.remove('nuevo')\n\n# Actualizacion\nlista[1] = 'valor'\n\ndiccionario['llave'] = 'Nllave'\n\nconjunto2 = {1,2,3}\nconjunto.update(conjunto2)\n\n# ordenacion\nlista.sort()\nlista.reverse()\n\n# Extra\n\ndef agregar(nombre: str, numero: str):\n    if nombre not in contactos:\n        contactos[nombre]=numero\n        print(f\"Contacto '{nombre}' agregado.\")\n    else:\n        print(\"\\nEl contacto ya existe.\")\n\ndef buscar(nombre: str):\n    if nombre in contactos:\n        for key, value in contactos.items():\n            if key == nombre:\n                print(key,\":\",value)\n    else:\n        print(\"\\nEl contacto no existe.\")\n\ndef actualizar(nombre: str, numero: str):\n    if nombre in contactos:\n        contactos[nombre]=numero\n        print(f\"Contacto {nombre} actualizado.\")\n    else:\n        print(\"\\nEl contacto no existe.\")\n    \n\ndef eliminar(nombre: str, numero=None):\n    if nombre in contactos:\n        contactos.pop(nombre)\n    else:\n        print(\"\\nEl contacto no existe.\")\n    \ncontactos = {'pepe': 1231234, 'chuy': 555555}\n\ndef main():\n    while True:\n        print(\"\\n----- Agenda -----\")\n        print(\"1. Agregar contacto\")\n        print(\"2. Buscar contacto\")\n        print(\"3. Actualizar contacto\")\n        print(\"4. Eliminar contacto\")\n        print(\"5. Ver contactos\")\n        print(\"6. Salir\")\n        opcion = input(\"Selecciona una opcion: \")\n         \n        if opcion == \"1\":\n            print(\"\\nAgregar\")\n            nombre, numero = input(\"Ingresa el nombre y numero: \").split()\n            agregar(nombre, numero)\n        elif opcion == \"2\":\n            print(\"\\nBuscar\")\n            nombre = input(\"Nombre: \")\n            buscar(nombre)\n        elif opcion == \"3\":\n            print(\"\\nActualizar\")\n            nombre, numero = input(\"Ingresa el nombre y numero: \").split()\n            actualizar(nombre, numero)\n        elif opcion == \"4\":\n            print(\"\\nEliminar\")\n            nombre = input(\"Nombre: \")\n            eliminar(nombre)\n        elif opcion == \"5\":\n            print(\"\\nContatos\")\n            for key, value in contactos.items():\n                print(f\"{key}:{value}\")\n        elif opcion == \"6\":\n            break\n        else:\n            print(\"Opcion incorrecta\")\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/eduhumanes91.py",
    "content": "'''\n/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n'''\n\n# Creación de estructuras de datos en Python\n# Listas\nlista = [1, 2, 3, 4, 5]\nprint(lista)\n\n# Tuplas\ntupla = (1, 2, 3, 4, 5)\nprint(tupla)\n\n# Diccionarios\ndiccionario = {'clave1': 'valor1', 'clave2': 'valor2'}\nprint(diccionario)\n\n# Conjuntos\nconjunto = {1, 2, 3, 4, 5}\nprint(conjunto)\n\n# Operaciones de inserción, borrado, actualización y ordenación\n# Listas\nlista.append(6)\nprint(lista)\n\nlista.remove(6)\nprint(lista)\n\nlista[0] = 0\nprint(lista)\n\nlista.sort()\nprint(lista)\n\n# Tuplas\n# No se pueden modificar, por lo que no se pueden hacer inserciones, borrados ni actualizaciones\n# Sí se pueden ordenar\ntupla_ordenada = sorted(tupla)\nprint(tupla_ordenada)\n\n# Diccionarios\ndiccionario['clave3'] = 'valor3'\nprint(diccionario)\n\ndel diccionario['clave3']\nprint(diccionario)\n\ndiccionario['clave1'] = 'nuevo_valor1'\nprint(diccionario)\n\n# Conjuntos\nconjunto.add(6)\nprint(conjunto)\n\nconjunto.remove(6)\nprint(conjunto)\n\n# No se pueden hacer actualizaciones ni ordenaciones\n# Sí se pueden hacer inserciones y borrados\n# Para ordenar un conjunto, hay que convertirlo a lista\nlista_conjunto = list(conjunto)\nlista_conjunto.sort()\nconjunto_ordenado = set(lista_conjunto)\nprint(conjunto_ordenado)\n\n# Agenda de contactos\nagenda = {\"Eduardo Humanes Saiz\": \"651488455\", \"Juan Pérez\": \"666555444\", \"María López\": \"611222333\", \"Ana García\": \"633444555\"}\n\nprint(\"\\n ****Agenda de contactos**** \\n\")\nprint(\"¿Que operación desea realizar? \\n 1. Buscar contacto\\n 2. Añadir contacto\\n 3. Actualizar contacto\\n 4. Eliminar contacto\\n 5. Salir\\n\")\n\noperacion = int(input(\"Por favor, introduzca el número de la operación que desea realizar: \"))\n\ndef buscar_contacto():\n    nombre = input(\"Por favor, introduzca el nombre del contacto que desea buscar: \")\n    if nombre in agenda:\n        print(f\"El número de teléfono de {nombre} es {agenda[nombre]}\")\n    else:\n        print(f\"El contacto {nombre} no se encuentra en la agenda\")\n        return\n\ndef anadir_contacto():\n    nombre = input(\"Por favor, introduzca el nombre del contacto que desea añadir: \")\n    telefono = input(\"Por favor, introduzca el número de teléfono del contacto que desea añadir: \")\n    if telefono.isdigit() and len(telefono) == 9:\n        agenda[nombre] = telefono\n        print(f\"El contacto {nombre} con número de teléfono {telefono} ha sido añadido a la agenda\")\n    else:\n        print(\"El número de teléfono introducido no es válido\")\n        return\n\ndef actualizar_contacto():\n    nombre = input(\"Por favor, introduzca el nombre del contacto que desea actualizar: \")\n    if nombre in agenda:\n        telefono = input(\"Por favor, introduzca el nuevo número de teléfono del contacto: \")\n        if telefono.isdigit() and len(telefono) == 9:\n            agenda[nombre] = telefono\n            print(f\"El número de teléfono de {nombre} ha sido actualizado a {telefono}\")\n        else:\n            print(\"El número de teléfono introducido no es válido\")\n            return\n    else:\n        print(f\"El contacto {nombre} no se encuentra en la agenda\")\n        return\n\ndef eliminar_contacto():\n    nombre = input(\"Por favor, introduzca el nombre del contacto que desea eliminar: \")\n    if nombre in agenda:\n        del agenda[nombre]\n        print(f\"El contacto {nombre} ha sido eliminado de la agenda\")\n    else:\n        print(f\"El contacto {nombre} no se encuentra en la agenda\")\n        return\n\ndef salir():\n    print(\"Hasta luego!\")\n    exit()\n\nif operacion == 1:\n    buscar_contacto()\nelif operacion == 2:\n    anadir_contacto()\nelif operacion == 3:\n    actualizar_contacto()\nelif operacion == 4:\n    eliminar_contacto()\nelif operacion == 5:\n    salir()\nelse:\n    print(\"Operación no válida\")\n    exit()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/eonOzux.py",
    "content": "# Instrucciones =>\n# * EJERCICIO:\n# * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto\n# *   en tu lenguaje.\n# * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n# *\n\nlista = [ 2, 56, 11, 32, 1, 9]\n\nx = 1\nlista.append(x)\nprint(lista) \n# Agrega un ítem al final de la lista. Equivale a Lista + x. \n\nlista.insert(3, x)\nprint(lista) \n# Inserta un ítem en una posición dada. El primer argumento es el índice del ítem delante del cual se insertará, por lo tanto a.insert(0, x) inserta al principio de la lista y a.insert(len(a), x) equivale a a.append(x).\n\nlista.remove(x)\nprint(lista) \n# Quita el primer ítem de la lista cuyo valor sea x. Lanza un ValueError si no existe tal ítem.\n\nlista.pop(3)\nprint(lista) \n# Remove the item at the given position in the list, and return it. If no index is specified, a.pop() removes and returns the last item in the list. It raises an IndexError if the list is empty or the index is outside the list range.\n\nlista.clear()\nprint(lista) \n# Elimina todos los elementos de la lista. Equivalente a del a[:].\n\nlista_ind = [4, 56, 34]\nlista_ind.index(56)\nprint(lista_ind) \n# Retorna el índice basado en cero del primer elemento cuyo valor sea igual a x. Lanza una excepción ValueError si no existe tal elemento.\n\nlista.count(x)\nprint(lista) \n# Retorna el número de veces que x aparece en la lista.\n\nlista.sort(key=None, reverse=False)\nprint(lista) \n# Ordena los elementos de la lista in situ (los argumentos pueden ser usados para personalizar el orden de la lista, \n\nlista.reverse()\nprint(lista) \n# Invierte los elementos de la lista in situ. Es una manera distinta y corta de usar el metodo de list con la operacion -1\n\nlista.copy()\nprint(lista) \n# Retorna una copia superficial de la lista. Equivalente a a[:].\n\n#TUPLAS \n\ntuplas = ( 7, 15, 44, 2, 76)\ntupla_lista = list(tuplas)\ntupla_lista.sort()\nprint(tuple(tupla_lista))\n\n# DICCIONARIOS\n\nmotofavorita = {\n  \"marca\": \"BMW\",\n  \"model\": \"GS1250R\",\n  \"año\": 2024\n}\n\nprint(motofavorita[\"model\"])\n\nmotofavorita['nombre'] = 'Juan Ignacio'\nprint(motofavorita)\n\n# * DIFICULTAD EXTRA (opcional):\n# * Crea una agenda de contactos por terminal.\n# * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n# *   y eliminación de contactos.\n# * - Cada contacto debe tener un nombre y un número de teléfono.\n# * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n# *   y a continuación los datos necesarios para llevarla a cabo.\n# * - El programa no puede dejar introducir números de teléfono no númericos y con más\n# *   de 11 dígitos (o el número de dígitos que quieras).\n# * - También se debe proponer una operación de finalización del programa.\n \ndef validar_telefono(telefono):\n  \n  # Función para validar el número de teléfono.\n\n  # Args:\n    # telefono: El número de teléfono ingresado por el usuario (string).\n\n  # Returns:\n    #True si el número es válido, False en caso contrario.\n    \n  # Validar longitud del número (máximo 11 dígitos)\n  if len(telefono) > 11:\n    print(\"No puede ser mas de 11 digitos\")\n    return False\n  \n\n  # Validar que solo sean números enteros\n  for digito in telefono:\n    if not digito.isdigit():\n      return False\n\n  return True\n\ndef solicitar_informacion():\n  \"\"\"\n  Función para solicitar información al usuario y validarla.\n\n  Returns:\n    Un diccionario con la información del usuario.\n  \"\"\"\n  agenda = {}\n\n  while True:\n    nombre = input(\"Ingrese su nombre: \")\n    if nombre:\n      agenda[\"nombre\"] = nombre\n      break\n    else:\n      print(\"Error: El nombre no puede estar vacío.\")\n\n  while True:\n    telefono = input(\"Ingrese su número de teléfono (máximo 11 dígitos): \")\n    if validar_telefono(telefono):\n      agenda[\"telefono\"] = telefono\n      break\n    else:\n      print(\"Error: El número de teléfono no es válido. Ingrese solo números enteros (máximo 11 dígitos).\")\n\n  while True:\n    pais = input(\"Ingrese su país de residencia: \")\n    if pais:\n      agenda[\"pais\"] = pais\n      break\n    else:\n      print(\"Error: El país no puede estar vacío.\")\n\n  return agenda\n\ndef main():\n  \"\"\"\n  Función principal para ejecutar el programa.\n  \"\"\"\n  datos_usuario = solicitar_informacion()\n\n  print(\"\\nInformación del usuario:\")\n  for clave, valor in datos_usuario.items():\n    print(f\"{clave}: {valor}\")\n\nif __name__ == \"__main__\":\n  main()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/evilpotato04.py",
    "content": "#/*\n# * EJERCICIO:\n# * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n# * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n\n# ======= LISTAS =======\ngenshin_impact_personajes = [\"Lumine\", \"Paimon\"]\n\ngenshin_impact_personajes.append(\"Amber\") # agrega un elemento\nprint(genshin_impact_personajes)\n\ngenshin_impact_personajes.extend([\"Kaeya\", \"Lisa\"]) # agrega una lista de elementos\nprint(genshin_impact_personajes)\n\ngenshin_impact_personajes.insert(1, \"Diluc\") # agrega un nuevo elemento según el índice\nprint(genshin_impact_personajes)\n\ngenshin_impact_personajes.remove(\"Paimon\") # elimina un elemento específico\nprint(genshin_impact_personajes)\n\ngenshin_impact_personajes.pop() # elimina el ultimo elemento\nprint(genshin_impact_personajes)\n\ngenshin_impact_personajes.pop(2) # elimina un elemento según el índice\nprint(genshin_impact_personajes)\n\ngenshin_impact_personajes.clear() # elimina a todos los elementos de la lista\nprint(genshin_impact_personajes)\n\n# ------------\ngenshin_impact_personajes.extend([\"Qiqi\", \"Noelle\", \"Xinyan\"])\n\nprint(genshin_impact_personajes.count(\"Qiqi\")) # cuenta cuántas veces un mismo elemento aparece\n\ngenshin_impact_personajes.reverse() # invierte el orden de los elementos\nprint(genshin_impact_personajes)\n\ngenshin_impact_personajes2 = genshin_impact_personajes.copy() # copia la lista\ngenshin_impact_personajes2.append(\"Paimon\")\nprint(genshin_impact_personajes)\nprint(genshin_impact_personajes2)\n\n# ------------\ndel genshin_impact_personajes2[2]    # elimina el elemento correspondiente al índice\nprint(genshin_impact_personajes2)\n\ndel genshin_impact_personajes2[1:3]  # elimina elementos dentro del periodo\nprint(genshin_impact_personajes2)\n\ndel genshin_impact_personajes2[:]    # otra manera de eliminar a todos los elementos de la lista\nprint(genshin_impact_personajes2)\n\n\n# ======= TUPLAS =======\ngenshin_impact_ciudades = (\"Mondstadt\", 'Liyue', \"Sumeru\", \"Inazuma\", \"Fontaine\")\n\nciudad_1, ciudad_2, ciudad_3, ciudad_4, ciudad_5 = genshin_impact_ciudades\n\nprint(f\"\"\"\n        ciudad 1: {ciudad_1},\n        ciudad 2: {ciudad_2},\n        ciudad 3: {ciudad_3},\n        ciudad 4: {ciudad_4},\n        ciudad 5: {ciudad_5},\n      \"\"\")\n\n# ======= DICCIONARIO =======\ngenshin_impact_arcontes = {\n    \"Barbatos\": \"Anemo Archon\",\n    \"Morax\": \"Geo Archon\",\n    \"Raiden Shogun\": \"Electro Archon\",\n    \"Nahida\": \"Dendro Archon\",\n    \"Focalors\": \"Hydro Archon\",\n    \"Murata\": \"Pyro Archon\",\n    \"Tsaritsa\": \"Cryo Archon\"\n}\n\ndel genshin_impact_arcontes[\"Barbatos\"] # elimina el elemento correspondiente a la clave\nprint(genshin_impact_arcontes)\n\ngenshin_impact_arcontes[\"Barbatos\"] = \"Anemo Archon\" # agrega un nuevo elemento\n\nprint(\"Focalors\" in genshin_impact_arcontes) # devuelve True si la clave existe en el diccionario\nprint(\"Focalors\" not in genshin_impact_arcontes) # devuelve True si la clave no existe en el diccionario\n\n# *\n# * DIFICULTAD EXTRA (opcional):\n# * Crea una agenda de contactos por terminal.\n# * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n# * - Cada contacto debe tener un nombre y un número de teléfono.\n# * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n# *   los datos necesarios para llevarla a cabo.\n# * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n# *   (o el número de dígitos que quieras)\n# * - También se debe proponer una operación de finalización del programa.\n# */\n\ndef open_lista(contactos):\n    id_contacto = 1\n    print(\"\")\n    for contacto in contactos:\n        print(f\"\"\"      {id_contacto}. {contacto[\"apellido\"]}, {contacto[\"nombre\"]}: {contacto[\"e-mail\"]}\"\"\")\n        id_contacto += 1\n    print(\"\")\n\ndef insert_contacto(contactos):\n    nombre = input(\"Insert new contact's name: \")\n    apellido = input(\"Insert new contact's last name: \")\n    email = input(\"Insert new contact's e-mail: \")\n\n    contactos.append({ \"nombre\": nombre, \"apellido\": apellido, \"e-mail\": email })\n    print(\"New contact was added!\")\n    print(\"\")\n    return contactos\n\ndef remove_contacto(contactos):\n    email = input(\"Insert the e-mail to be removed: \")\n    contactos_nuevos = contactos.copy()\n    for contacto in contactos:\n        if contacto[\"e-mail\"] == email:\n            contactos_nuevos.remove(contacto)\n            print(\"The contact was removed!\")\n    print(\"\")\n    return contactos_nuevos\n\ndef agenda_de_contactos():\n    print(\"========= EVIL POTATO AGENDA =========\")\n    contactos = [{ \"nombre\": \"Samunta\", \"apellido\": \"Lemos\", \"e-mail\": \"samunta@evilpotato.com\" }]\n\n    while True:\n        print(f\"\"\"\n            To open the contact list, digit option 1\n            To insert a new contact, digit option 2\n            To remove some contact from list, digit 3\n            To close the agenda, digit option 9\n            \"\"\")\n        opcion = input(\"What do you want to do? \")\n\n        match opcion:\n            case \"1\":\n                open_lista(contactos)\n            case \"2\":\n                contactos = insert_contacto(contactos)\n            case \"3\":\n                contactos = remove_contacto(contactos)\n            case \"9\":\n                print(\"Thank you for using this aplication! Bye! <3 <3 <3\")\n                return\n            case _:\n                print(\"Invalid option! Please, digit a valid option (1, 2, 3 or 9)\")\n\nagenda_de_contactos()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/fborjalv.py",
    "content": "# ESTRUCTURAS - inserción, borrado, actualización y ordenación\n\n# LIST ARRAY \n\nprint(\"LISTAS\")\n\nlist_user: list = [\"Angel\", \"Borja\", \"Zaida\",  \"Carlos\", \"Maite\", \"Pedro\"]\nprint(list_user)\n\n# inserción\nlist_user.append(\"Carolina\")\nprint(list_user)\n\n# borrado\nlist_user.remove(\"Carlos\")\nprint(list_user)\n\n# actualización\n\nlist_user[0] = \"Ángel\"\nprint(list_user)\n\n# ordenación\nlist_user.sort(reverse=False)\nprint(list_user)\n\n\n# TUPLAS \nprint(\"TUPLAS: son inmutables\")\nlist_compra: tuple = (\"pan\", \"leche\", \"verduras\", \"huevos\", \"aceite\")\nprint(list_compra)\n\n#ordenación - se tiene que transformar en lista\nlist_compra_ordenada = sorted(list_compra)\nprint(list_compra_ordenada, type(list_compra_ordenada))\nprint(tuple(list_compra_ordenada), type(tuple(list_compra_ordenada)))\n\n# SET - CONJUNTOS\nprint(\"SETs: elementos únicos, no repetidos\")\nset_coches: set = {\"Ford\", \"Toyota\", \"Mercedes\", \"BMW\", \"Renault\"}\n\nprint(set_coches)\n\n#inserción\nset_coches.add(\"Hyundai\")\nprint(set_coches)\nset_coches.add(\"Ford\") # NO SE AÑADE PORQUE ESTARÍA DUPLICADO\n\n# borrado\nset_coches.remove(\"Renault\")\nprint(set_coches)\n\n# ordenar\nset_coches_ord = sorted(set_coches) \nprint(set_coches_ord, type(set_coches_ord))\nprint(set(set_coches_ord), type(set(set_coches_ord))) # NO SE PUEDEN ORDENAR, TIENEN QUE SER LISTAS\n\n# DICCIONARIOS \nprint(\"DICCIONARIOS\")\n\nbbdd_coches: dict = {\n    \"Ford\": 23445,\n    \"BMW\": 43525,\n    \"Toyota\": 34543,\n    \"Mercedes\": 34885,\n}\n\nprint(bbdd_coches)\n\n# inserción\n\nbbdd_coches[\"Hyundai\"] = 45356\nprint(bbdd_coches)\n\n# borrado\n\nbbdd_coches.pop(\"Toyota\")\ndel bbdd_coches[\"BMW\"]\nprint(bbdd_coches)\n\n# actualización\n\nbbdd_coches[\"Ford\"] = \"No disponible\"\nprint(bbdd_coches)\n\n# ordenación\n\nprint(sorted(bbdd_coches))\n\n# EJERCICIO \n\ndef func_agenda():\n    \n    agenda = {\n        \"borja\": 234234243\n    }\n    \n    def nuevo_contacto(nombre, telefono):\n        if telefono.isdigit() and len(telefono) > 0 and len(telefono) < 11:\n            agenda[nombre] = telefono\n        else:\n            print(\n                \"Debes introducir un número de teléfono un máximo de 11 dígitos.\")\n\n    option = input(\"\"\"\n            Introduce una de las siguientes opciones:\n\n            1. Buscar un contacto\n            2. Añadir un nuevo contacto\n            3. Actualizar un contacto\n            4. Eliminar un contacto\n            5. Salir \"\"\")\n            \n    if option == \"1\": \n        nombre = input(\"Buscar por nombre: \")\n        if nombre in agenda:\n            print(f\"El numero de telefóno de {nombre} es {agenda[nombre]}\")\n        else:\n            print(\"el nombre no está en la agenda\")\n    elif option == \"2\":\n        nombre = input(\"Introduce el nombre del nuevo contacto: \")\n        telefono = input(\"Introduce el telefono del nuevo contacto: \")\n        nuevo_contacto(nombre, telefono) \n\n    elif option == \"3\":\n        nombre = input(\"Introduce el nombre que quieres actualizar: \")\n        if nombre in agenda:\n            telefono = input(\"Introduce el nuevo telefono del contacto: \")\n            nuevo_contacto(nombre, telefono) \n        else:\n            print(\"El contacto no existe\")\n\n    elif option == \"4\": \n        nombre = input(\"Introduce el contacto que quieres eliminar: \")\n        if nombre in agenda:\n            del agenda[nombre]\n        else:\n            print(\"El contacto no existe\")\n    elif option == \"5\":\n        print(\"saliendo del programa...\")\n\nfunc_agenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/fishellVvv.py",
    "content": "# Estructura - Listas\nmy_list = [\"Marcelino\", \"Victor\", \"Juanlu\", \"Jose\"]\nprint(my_list[1]) # acceso\nprint(my_list)\nmy_list.append(\"Pepito\") # inserción\nprint(my_list)\nmy_list.remove(\"Victor\") # borrado\nprint(my_list)\nmy_list[1] = \"Juan Luis\" # actualización\nprint(my_list)\nmy_list.sort() # ordenación\nprint(my_list)\n\n# Estructura - Tuplas\nmy_tuple = (\"Victor\", \"Vigil\", \"fishell\", \"1983\")\nprint(my_tuple[2]) # acceso\nprint(my_tuple)\nmy_tuple = tuple(sorted(my_tuple)) # ordenación\nprint(my_tuple)\n\n# Estructuras - Sets\nmy_set = {\"Picual\", \"Cornezuelo\", \"Manzanilla\"}\nprint(my_set)\nmy_set.add(\"Verdial\") # inserción\nprint(my_set)\nmy_set.remove(\"Manzanilla\") # borrado\nprint(my_set)\n\n# Estructura - Diccionario\nmy_dict = {\n    \"model\": \"CL500\", \n    \"year\": \"2023\",\n    \"brand\": \"Honda\"\n}\nprint(my_dict[\"model\"]) # acceso\nprint(my_dict)\nmy_dict[\"style\"] = \"Scrambler\" # inserción/actualización\nprint(my_dict)\ndel my_dict[\"year\"] # borrado\nprint(my_dict)\nmy_dict = dict(sorted(my_dict.items())) # ordenación\nprint(my_dict)\n\n# Extra\ndef my_agenda():\n\n    contact_book = {\n        \"Marcelino\": 600220001,\n        \"Juan Luis\": 600220002,\n        \"Jose\": 600220003, \n        \"Pepito\": 600220004\n    }\n\n    while True:\n\n        print(\"\\n***Agenta de contactos***\")\n        print(\"1. Buscar contacto\")\n        print(\"2. Añadir contacto\")\n        print(\"3. Actualizar contacto\")\n        print(\"4. Eliminar contacto\")\n        print(\"0. Salir\")\n\n        option = input(\"\\nIndica una opción: \")\n\n        match option:\n            case \"0\":\n                conf = input(\"Escribe SALIR para confirmar: \")\n                if conf.lower() == \"salir\":\n                    print(\"Saliendo de la agenda...\")\n                    break\n            case \"1\":\n                buscado = input(\"Nombre: \")\n                if buscado in contact_book:\n                    print(f\"Tlf: {contact_book[buscado]}\")\n                else:\n                    print(f\"El contacto {buscado} no existe\")\n            case \"2\":\n                name = input(\"Nombre: \")\n                phone = input(\"Tlf: \")\n                if phone.isdigit() and len(phone) == 9:\n                    contact_book[name] = phone\n                    print(\"Contacto guardado\")\n                else:\n                    print(\"Número de teléfono no válido, debe tener 9 dígitos\")\n            case \"3\":\n                buscado = input(\"Nombre: \")\n                if buscado in contact_book:\n                    phone = input(\"Tlf: \")\n                    if phone.isdigit() and len(phone) == 9:\n                        contact_book[buscado] = phone\n                        print(\"Contacto actualizado\")\n                    else:\n                        print(\"Número de teléfono no válido, debe tener 9 dígitos\")\n                else:\n                    print(f\"El contacto {buscado} no existe\")\n            case \"4\":\n                buscado = input(\"Nombre: \")\n                if buscado in contact_book:\n                    del contact_book[buscado]\n                    print(\"Contacto eliminado\")\n                else:\n                    print(f\"El contacto {buscado} no existe\")\n            case _:\n                print(\"Indica un valor de 1 a 4 (0 para salir)\")\n\n        input(\"Pulsa ENTER para continuar\")\n\nmy_agenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/franvozzi.py",
    "content": "# Lista (colección mutable y ordenada)\nmiLista = [1, 2, 3, 4, 5]\nprimerElementoLista = miLista[0] # Acceder al 1\n\nmiLista.append(6) # Agrega un sexto elemento\nmiLista.insert(2, 15) # Agrega en una posición específica\n\nmiLista.remove(3) # Eliminar elementos por valor\n\neliminaElemento = miLista.pop(1) # Elimina por índice\n\nlogitudLista = len(miLista) # Longitud lista\n\nfor elemento in miLista:\n    print(elemento) # Recorrer e imprimir lista\n\n# Tuplas (colección ordenada e inmutable)\nmiTupla = (1, 2, 3, 4, 5) \n\nprimerElementoTupla = miTupla[0] # Acceder a primer elemento\n\nlongitudTupla = len(miTupla) # Longitud tupla\n\nfor elemento in miTupla:\n    print(elemento) # Recorre tupla\n    \n# Conjuntos\nmiConjunto = {1, 2, 3, 4, 5}\nmiConjunto.add(6) # Añadir elementos\nmiConjunto.remove(3) # Remover elementos\nestaPresente = 4 in miConjunto # Devuelve True, sí está presente\n\notroConjunto = {4, 5, 6, 7}\n\nunion = miConjunto | otroConjunto\n\ninterseccion = miConjunto & otroConjunto\n\ndiferencia = miConjunto - otroConjunto\n\ndiferenciaSimetrica = miConjunto ^ otroConjunto\n\nfor elemento in miConjunto:\n    print(elemento) #recorre conjunto\n\n\nmiDiccionario = {\"clave1\": \"valor1\", \"clave2\": \"valor2\"}\n\nvalor = miDiccionario[\"clave1\"] # Acceso a valor\nmiDiccionario[\"clave1\"] = \"nuevoValor1\"\nmiDiccionario[\"clave3\"] = \"valor3\"\ndel miDiccionario[\"clave2\"] # Elimina clave-valor\n\nclaves = miDiccionario.keys() # Obtener claves\nvalor = miDiccionario.values() # Obtener valores\n\nfor clave, valor in miDiccionario.items():\n    print(f\"{clave}: {valor}\")\n    \n# Desafío EXTRA\ndef myAgenda ():\n    agenda = {}\n    \n    def insertContact():\n        phone = input(\"Introduce el número del contacto: \")\n        if phone.isdigit() and len(phone) > 0 and len(phone) <= 11:\n            agenda[name] = phone\n        else: \n            print(\"Debes introducir un número de teléfono con menos de 12 dígitos\")\n    \n    while True:\n        \n        print(\"\")\n        print(\"1. Buscar contacto\")\n        print(\"2. Insertar contacto\")\n        print(\"3. Actualizar contacto\")\n        print(\"4. Eliminar contacto\")\n        print(\"5. Salir\") \n        \n        option = input(\"\\nSelecciona una opción: \")\n        \n        match option:\n            case \"1\":\n                name = input(\"Introduce el nombre del contacto: \")\n                if name in agenda:\n                    print(f\"El número de teléfono de {name} es {agenda[name]}\")\n                else:\n                    print(\"Usuario inexistente.\")\n            case \"2\":\n                name = input(\"Introduce el nombre del contacto: \")\n                insertContact()\n            case \"3\":\n                name = input(\"Introduce el nombre del contacto a actualizar: \")\n                if name in agenda:\n                    insertContact()\n                else:\n                    print(f\"El contacto {name} no existe\")\n            case \"4\":\n                if name in agenda:\n                    del agenda[name]\n                else:\n                    print(\"Usuario inexistente.\")\n            case \"5\":\n                print(\"Saliendo de la agenda.\")\n                break\n            case _:\n                print(\"Opción no valida. Elige una opción del 1 al 5.\") \n                \n\nmyAgenda ()    "
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/franxiscodev.py",
    "content": "# Listas\nmy_list = [\"a\", \"b\", \"z\", \"c\", \"y\", \"e\"]\nprint(my_list)\nprint(my_list[0])\nprint(my_list[1])\nmy_list.append(\"f\")\nprint(my_list)\nmy_list.insert(0, \"b\")\nprint(f\"insert 0,b {my_list}\")\n# my_list.remove(\"b\")\nprint(my_list.pop(0))\nprint(my_list)\nmy_list.sort()\nprint(my_list)\n# Crear una lista de números\nnumbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n\n# tuplas ()\nprint(\"Tuplas\")\nmy_tuple: tuple = (\"z\", \"b\", \"c\", \"a\", \"y\", \"e\")\nprint(my_tuple)\nprint(my_tuple[0])\n'''\n# inmutables\nmy_tuple = my_tuple.append(\"d\")\nprint(my_tuple)\n'''\nmy_tuple = tuple(sorted(my_tuple))\nprint(my_tuple)\nprint(type(my_tuple))\n\n# Sets\nmy_set = {\"a\", \"b\", \"z\", \"c\", \"y\", \"e\"}\nprint(my_set)\nmy_set.add(\"f\")\nprint(my_set)   # {'a', 'b', 'c', 'e', 'f', 'y', 'z'}\nmy_set.remove(\"f\")  # {'a', 'b', 'c', 'e', 'y', 'z'}\nprint(my_set)   # {'a', 'b', 'c', 'e', 'y', 'z'}\nmy_set.discard(\"f\")  # {'a', 'b', 'c', 'e', 'y', 'z'}\nprint(my_set)   # {'a', 'b', 'c', 'e', 'y', 'z'}\nmy_set.pop()\nprint(my_set)   # {'b', 'c', 'e', 'y', 'z'}\n\n# Diccionarios\nmy_dict = {\n    \"name\": \"Francisco\",\n    \"last_name\": \"Gonzalez\",\n    \"age\": 25\n}\nprint(my_dict)\nprint(my_dict[\"name\"])\nprint(my_dict[\"last_name\"])  # Gonzalez\nprint(my_dict[\"age\"])   # 25\nmy_dict[\"age\"] = 26\nprint(my_dict[\"age\"])   # 26\nmy_dict[\"city\"] = \"Medellin\"\nprint(my_dict)\n# {'name': 'Francisco', 'last_name': 'Gonzalez', 'age': 26}\nmy_dict.pop(\"city\")\nprint(my_dict)\ndel my_dict[\"age\"]\nprint(my_dict)\n\nprint(\"get\")\nprint(my_dict.get(\"name\", \"No encontrado\"))  # Francisco\nprint(my_dict.get(\"nombre\", \"No encontrado\"))  # No encontrado\n\n'''\nExtra\n'''\n\n\ndef my_agenda():\n    agenda = {}\n\n    def print_no_contact(name: str) -> str:\n        return f\"Contacto no encontrado {name}\"\n\n    def insert_contact(name: str, phone: str) -> None:\n        if (phone.isdigit() and len(phone) < 10):\n            agenda[name] = phone\n            print(f\"Contacto agregado/actualizado {name}: {phone}\")\n        else:\n\n            print(\"Número de teléfono inválido\")\n\n    while True:  # Ciclo infinito\n        print(\"\\nAgenda\")\n        print(\"1. Buscar contacto\")\n        print(\"2. Agregar contacto\")\n        print(\"3. Actualizar contactos\")\n        print(\"4. Eliminar contactos\")\n        print(\"5. Print dict\")\n        print(\"6. Salir\")\n        option = input(\"Opción: \")\n        match option:\n            case \"1\":\n                name = input(\"Buscar Nombre: \")\n                if name in agenda:\n                    print(f\"{name}: {agenda[name]}\")\n                else:\n                    print(print_no_contact(name))\n            case \"2\":\n                name = input(\"Agregar Nombre: \")\n                phone = input(\"Agregar Teléfono: \")\n                insert_contact(name, phone)\n            case \"3\":\n                name = input(\"Nombre para actualizar: \")\n                if name in agenda:\n                    phone = input(\"Teléfono: \")\n                    insert_contact(name, phone)\n                else:\n                    print(print_no_contact(name))\n            case \"4\":\n                name = input(\"Eliminar Nombre: \")\n                if name in agenda:\n                    del agenda[name]\n                    print(f\"Contacto eliminado  {name}\")\n                else:\n                    print(print_no_contact(name))\n            case \"5\":   # Print dict\n                print(agenda)\n            case \"6\":\n                break\n            case _:\n                print(\"Opción no válida\")\n\n\nmy_agenda()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/gabrielramos02.py",
    "content": "# 03 Estructuras de Datos\n\n# Listas\nfrom asyncio.windows_events import NULL\nfrom os import system\n\n\nmy_list = [0, 1, 2]\nmy_list.append(1) # Insercion\nmy_list[1] = 3    # Actualizacion\nmy_list.remove(2) # Borrado\nmy_list.sort()    # Ordenacion\nprint(\"Lista:\",my_list)\n\n\n# Tuplas\nmy_tuple = (0, 1, 2)      # Las tuplas no pueden ser editadas\nprint(\"Tupla:\",my_tuple)\n\n\n# Set\nmy_set = {0, 1, 2} \nmy_set.add(3)       # Insercion\nmy_set.remove(1)    # Borrado\nprint(\"Sets:\",my_set)\n\n\n# Dicts\nmy_dict = {\"Nombre\": \"Empty\", \"Edad\": 21}\nmy_dict[\"Nombre\"] = \"Gabriel\" # Actualizacion\ndel my_dict[\"Edad\"]           # Borrado\nmy_dict[\"Ocupacion\"] = \"Estudiante\" # Insercion\nprint(\"Diccionario:\",my_dict)\n\n###  Agenda  ###\nagenda = list()\ndef menu():\n    entrada = int()\n    while True:\n        try:\n            system(\"cls\")\n            print(\"Seleciona una opcion 1-Agregar 2-Actualizar 3-Eliminar 4-Ver Contactos 5-Salir \")\n            entrada = int(input())\n        except ValueError or entrada <= 5 or entrada < 1:\n            print(\"Ingrese un numero valido\")\n        if entrada == 1:\n            agregar()\n        elif entrada == 2:\n            actualizar()\n        elif entrada == 3:\n            eliminar()\n            pass\n        elif entrada == 4:\n            system(\"cls\")\n            if len(agenda) == 0:\n                print(\"Agenda sin contactos\")\n                system(\"pause\")\n            else: \n                for contacto in agenda:\n                    print(f\"Nombre: {contacto[\"Nombre\"]}\")\n                    print(f\"Numero de Telf: {contacto[\"Numero de Telf\"]}\")\n                system(\"pause\")\n        else:break\n\ndef agregar():\n    system(\"cls\")\n    nuevo_contacto = dict()\n    nombre = input(\"Escribe el nombre de tu contacto: \")\n    num_telf = int()\n    try:\n        num_telf = int(input(\"Introduzca el numero de telefono: \"))\n    except ValueError or len(str(num_telf)) > 11:\n        print(\"Por favor, ingresa un número válido.\")\n    nuevo_contacto[\"Nombre\"] = nombre\n    nuevo_contacto[\"Numero de Telf\"] = num_telf\n    print(\"Contacto Agregado\")\n    system(\"pause\")\n    agenda.append(nuevo_contacto)\n    return\n\ndef actualizar():\n    system(\"cls\")\n    if len(agenda) == 0:\n        print(\"Agenda sin contactos\")\n        system(\"pause\")\n        return\n    while True:\n        system(\"cls\")\n        for contacto in agenda:\n            print(f\"Nombre: {contacto[\"Nombre\"]}\")\n            print(f\"Numero de Telf: {contacto[\"Numero de Telf\"]}\")\n        nombre = input(\"Que contacto desea actualizar: \")\n        encontrado = False\n        for contacto in agenda:\n            if nombre == contacto[\"Nombre\"]:\n                num_telf = int()\n                try:\n                    system(\"cls\")\n                    num_telf = int(input(\"Introduzca el nuevo numero de telefono: \"))\n                except ValueError or len(str(num_telf)) > 11:\n                    print(\"Por favor, ingresa un número válido.\")\n                contacto[\"Numero de Telf\"] = num_telf\n                encontrado = True\n                return\n        if not encontrado:\n            system(\"cls\")\n            print(\"No se ha encontrado el contacto\")\n            system(\"pause\")\n\ndef eliminar():\n    system(\"cls\")\n    if len(agenda) == 0:\n        print(\"Agenda sin contactos\")\n        system(\"pause\")\n        return\n    while True:\n        system(\"cls\")\n        for contacto in agenda:\n            print(f\"Nombre: {contacto[\"Nombre\"]}\")\n            print(f\"Numero de Telf: {contacto[\"Numero de Telf\"]}\")\n        nombre = input(\"Que contacto desea eliminar: \")\n        encontrado = False\n        for contacto in agenda:\n            if nombre == contacto[\"Nombre\"]:\n                system(\"cls\")\n                print(\"Contacto eliminado\")\n                system(\"pause\")\n                agenda.remove(contacto)\n                encontrado = True\n                return\n        if not encontrado:\n            system(\"cls\")\n            print(\"No se ha encontrado el contacto\")\n            system(\"pause\")\n                    \n\n        \nmenu()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/garos01.py",
    "content": "# Creación de una lista\nmi_lista = [1, 2, 3, 4, 5]\n\n# Inserción\nmi_lista.append(6)\n\n# Borrado\nmi_lista.remove(3)\n\n# Actualización\nmi_lista[0] = 10\n\n# Ordenación\nmi_lista.sort()\n\nprint(mi_lista)\n\n\n# Creación de una tupla\nmi_tupla = (1, 2, 3, 4, 5)\n\n# Las tuplas son inmutables, por lo que no se pueden actualizar ni modificar después de la creación\n# Puedes acceder a elementos de la tupla, pero no puedes cambiarlos\n\n# Ordenación (creando una nueva tupla ordenada)\ntupla_ordenada = tuple(sorted(mi_tupla))\n\nprint(tupla_ordenada)\n\n\n# Creación de un conjunto\nmi_conjunto = {1, 2, 3, 4, 5}\n\n# Inserción\nmi_conjunto.add(6)\n\n# Borrado\nmi_conjunto.remove(3)\n\n# No hay actualización en los conjuntos, ya que los elementos son únicos\n\n# No hay ordenación en los conjuntos, ya que son desordenados por naturaleza\n\nprint(mi_conjunto)\n\n\n# Creación de un diccionario\nmi_diccionario = {\"clave1\": \"valor1\", \"clave2\": \"valor2\", \"clave3\": \"valor3\"}\n\n# Inserción\nmi_diccionario[\"clave4\"] = \"valor4\"\n\n# Borrado\ndel mi_diccionario[\"clave2\"]\n\n# Actualización\nmi_diccionario[\"clave1\"] = \"nuevo_valor\"\n\n# No hay ordenación en los diccionarios, ya que son estructuras basadas en claves\n\nprint(mi_diccionario)\n\n\n# Ejercicio extra\nusuarios = {}\nidentificadores = []\n\n\ndef new_user():\n    nombre = input(\"Ingrese el nombre: \")\n\n    numero_telefono = input(\"Ingrese el numero de telefono: \")\n    while not numero_telefono.isdigit() or len(numero_telefono) != 10:\n        print(\"Error: El numero debe contener 10 digitos\")\n        numero_telefono = input(\"Igrese el numero de telefono: \")\n\n    identificador = len(identificadores) + 1\n    identificadores.append(identificador)\n\n    usuarios[identificador] = {\"nombre\": nombre, \"numero_telefono\": numero_telefono}\n\n    print(\n        f\"Usuario guardado correctamente. Identificador: {identificador}, nombre: {nombre}\"\n    )\n\n\ndef show_user(id_usuario):\n    if id_usuario in usuarios:\n        usuario = usuarios[id_usuario]\n        print(f\"Informacion del usuario con ID {id_usuario}\")\n        print(f\"Nombre: {usuario['nombre']}\")\n        print(f\"Numero de telefono: {usuario['numero_telefono']}\")\n    else:\n        print(f\"No se encontro el usuario con ID {id}\")\n\n\ndef edit_user(id_usuario):\n    if id_usuario in usuarios:\n        usuario_actual = usuarios[id_usuario]\n\n        nombre = (\n            input(f\"Ingrese el nuevo nombre ({usuario_actual['nombre']}): \")\n            or usuario_actual[\"nombre\"]\n        )\n\n        numero_telefono = (\n            input(\n                f\"Ingrese el nuevo número de teléfono ({usuario_actual['numero_telefono']}): \"\n            )\n            or usuario_actual[\"numero_telefono\"]\n        )\n\n        usuarios[id_usuario] = {\n            \"nombre\": nombre,\n            \"numero_telefono\": numero_telefono,\n        }\n\n        print(f\"Información del usuario con ID {id_usuario} actualizada con éxito.\")\n    else:\n        print(f\"No se encontró un usuario con el ID {id_usuario}.\")\n\n\ndef delete_user(id_usuario):\n    if id_usuario in usuarios:\n        del usuarios[id_usuario]\n        identificadores.remove(id_usuario)\n        print(f\"Usuario con ID: {id_usuario} eliminado con exito\")\n    else:\n        print(f\"No se encontro el usuario con ID: {id_usuario}\")\n\n\ndef list_user():\n    print(\"\\nLista de usuarios registrados:\")\n    for identificador in identificadores:\n        print(identificador)\n\n\n# Menu Principal\nwhile True:\n    print(\"\\nMenú:\")\n    print(\"A.- Registrar nuevos usuarios\")\n    print(\"B.- Listar usuarios\")\n    print(\"C.- Ver información de un usuario por ID\")\n    print(\"D.- Editar información de un usuario por ID\")\n    print(\"E.- Eliminar usuario por ID\")\n    print(\"F.- Finalizar el programa\")\n\n    opcion = input(\"Seleccione una opción (A/B/C/D/E/F): \").upper()\n\n    if opcion == \"A\":\n        new_user()\n    elif opcion == \"B\":\n        list_user()\n    elif opcion == \"C\":\n        id_usuario = int(input(\"Ingrese el ID del usuario que desea ver: \"))\n        show_user(id_usuario)\n    elif opcion == \"D\":\n        id_usuario = int(input(\"Ingrese el ID del usuario que desea editar: \"))\n        edit_user(id_usuario)\n    elif opcion == \"E\":\n        id_usuario = int(input(\"Ingrese el ID del usuario que desea eliminar: \"))\n        delete_user(id_usuario)\n    elif opcion == \"F\":\n        print(\"Programa finalizado.\")\n        break\n    else:\n        print(\"Opción no válida. Por favor, seleccione una opción correcta.\")\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/ggilperez.py",
    "content": "# Sets\nprint(\"SETS\")\nmy_set = {4, 3, 1, 2}\nprint(my_set)\n\n# Insert\nmy_set.add(5)\nprint(my_set)\n\n# Deleted\nmy_set.remove(1)\nprint(my_set)\n\n# Can't sort by default, need to cast to list to be sorted and cast again to set\nprint(set(sorted(my_set)))\n\n# Lists\nprint(\"LISTS\")\nmy_list = [1, 2, 3, 4]\nprint(my_list)\n\n# Insert\nmy_list.append(5)\nprint(my_list)\nmy_list.insert(0, 6)\nprint(my_list)\n\n# Read\nprint(my_list[2])\n\n# Update\nmy_list[2] = 9\nprint(my_list)\n\n# Delete\nmy_list.remove(3)\nprint(my_list)\n\n# Sort\nmy_list.sort()\nprint(my_list)\n\n# Tuples\nprint(\"TUPLES\")\nmy_tuple = (4, 2, 3, 1)\nprint(my_tuple)\n\n# Read\nprint(my_tuple[1])\n\n# Can't sort by default, need to cast to list to be sorted and cast again to set\nprint(tuple(sorted(my_tuple)))\n\n# Dicts / hashmaps\nprint(\"DICTS\")\nmy_dict = {\"one\": 1, \"two\": 2, \"three\": 3, \"four\": 4}\nprint(my_dict)\n\n# Insert\nmy_dict[\"five\"] = 5\nprint(my_dict)\n\n# Read\nprint(my_dict[\"five\"])\nprint(my_dict.get(\"five\"))\n\n# Update\nmy_dict[\"five\"] = 55\nprint(my_dict)\n\n# Delete\nmy_dict.pop(\"two\")\nprint(my_dict)\n\n# Sort by key (keys must be same type)\nprint(dict(sorted(my_dict.items())))\n\n# Sort by value (values must be same type)\nprint(dict(sorted(my_dict.items(), key=lambda x: x[1])))\n\n\n# EXTRA\ndef agenda():\n    agenda = {}\n\n    def show_menu():\n        print(\"(1) Insert contact\")\n        print(\"(2) Search contact\")\n        print(\"(3) Update contact\")\n        print(\"(4) Remove contact\")\n        print(\"(5) Close program\")\n\n    def is_valid_phone(phone: str) -> bool:\n        return phone.isdigit() and len(phone) > 0 and len(phone) <= 11\n\n    def ask_for_name():\n        return input(\"Contact name: \")\n\n    def ask_for_phone():\n        phone = input(\"Contact phone: \")\n        if not is_valid_phone(phone):\n            print(\"Invalid phone number.\")\n            return\n        return phone\n\n    def insert_contact():\n        name = ask_for_name()\n        if name in agenda:\n            print(\"Contact already exists. Choose update option.\")\n            return\n\n        phone = ask_for_phone()\n        if phone is None:\n            return  # invalid phone\n\n        agenda[name] = phone\n        print(\"Contact saved.\")\n\n    def search_contact():\n        name = ask_for_name()\n        if name in agenda:\n            print(f\"Contact {name}. Phone: {agenda[name]}\")\n        else:\n            print(\"Contact not found.\")\n\n    def update_contact():\n        name = ask_for_name()\n        if name not in agenda:\n            print(\"Contact not found.\")\n            return\n\n        phone = ask_for_phone()\n        if phone is None:\n            return  # invalid phone\n\n        agenda[name] = phone\n        print(\"Contact updated.\")\n\n    def remove_contact():\n        name = ask_for_name()\n        if name not in agenda:\n            print(\"Contact not found.\")\n            return\n\n        agenda.pop(name)\n        print(\"Contact removed.\")\n\n    while True:\n        show_menu()\n        option = input(\"Select an option: \")\n        if option == '1':\n            insert_contact()\n        elif option == '2':\n            search_contact()\n        elif option == '3':\n            update_contact()\n        elif option == '4':\n            remove_contact()\n        elif option == '5':\n            print(\"Exiting...\")\n            break\n        else:\n            print(\"Choose a correct option.\")\n\n\nagenda()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/gjbecerrae.py",
    "content": "### Estructuras de datos ###\n\n#listas ----\nprint('\\n\\nListas --------------------------------------\\n ')\nmiLista = ['item1', 'item2', 'item3', 'item4', 'item5', 'item0']\nmiLista.append('item6')\nmiLista.extend(['item7','item8'])\nprint('miLista completa -> ', miLista)\nprint('Veces que item1 esta en la lista -> ', miLista.count('item1'))\nprint('El index de item3 es -> ', miLista.index('item3'))\nmiLista.remove('item2')\nprint('item2 ha sido removido -> ', miLista)\nprint('Lista actual -> ', miLista)\nmiLista.sort()\nprint('Lista ordenada -> ', miLista)\n\n#\n#Tuplas ---\nprint('\\nTuplas --------------------------------------\\n ')\nprint('Son inmutables\\n ')\nmiTupla = ('hola','Python')\nprint('Mi tupla es ', miTupla)\nprint('El numero de veces que \\'hola\\' se encuentra en miTupla es ->', miTupla.count('hola'))\nprint('el Indice de \\'Pytnon\\, es -> ', miTupla.index('Python'))\nmiTupla2 = ([1,2,3],[4,5,6])\nprint('miTupla2 es ', miTupla2 )\nprint('Las listas dentro de miTupla2 son objetos mutables, voy a cambiar el item \\'3\\' pour un \\'10\\'')\nmiTupla2[0][2] = 10\nprint('miTupla2 es ', miTupla2 )\n\n#Conjuntos ---\nprint('\\nConjuntos -------------------------------------- ')\nprint('se usa para evitar duplicados\\n ')\nbasket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}\nprint(basket)    \nprint('Orange esta en el basket? ','orange' in basket)\n\n#Diccionarios ---\nprint('\\nDiccionarios -------------------------------------- ')\nmiDict = {'key1':'value1', 'key2':'value2'}\nprint('miDict es ', miDict)\nmiDict['key3'] = 'value3'\nprint('Adiciiono key3: \\n', miDict )\nmiDict.pop('key2')\nprint('Borro key2: \\n', miDict )\n\n#Ejercicio Opcional ---\nprint('\\nejercicio Opcional -------------------------------------- \\n')\nagenda = {}\n\n#La agenda sera un diccionario key= nombre appellido value=telefono\n#ej {'Juan Montoya':'07071010101, 'Pedro Perez':'07071010102'}, se puede buscar al usuario por su nombre y apellido\ncontinuar = True\nwhile continuar:\n\n    opcion = input('''Que quieres hacer?:\\n \n    1. Crear un nuevo contacto\\n \n    2. Buscar un contacto\\n \n    3. Modificar un contacto\\n\n    4. Eliminar un contacto\\n\n    5. Salir\\n''')\n\n    if opcion == '1':\n        print('Has seleccionado crear un nuevo contacto\\n')\n        nuevoContacto = input('Ingresa el nombre de tu contacto\\n').lower()\n\n        while True:\n            numeroNuevoContacto = input('Por favor incluye solo digitos sin espacios en tu numero y maximo 11\\n')\n            if numeroNuevoContacto.isdigit() and len(numeroNuevoContacto) < 12:\n                agenda[nuevoContacto] = numeroNuevoContacto\n                break\n        print(f'Tu contacto {agenda} ha sido guardado\\n ')\n\n\n    elif opcion == '2':\n        print('Has seleccionado buscar un contacto ')\n        buscarContacto = input('Cual es el nombre y appellido de tu contacto ')\n\n        if buscarContacto.lower() in agenda:\n            #Capitalize nombre y apellido solo para mostrarlo lindo\n            nombre = buscarContacto.split()\n            for i in range (len(nombre)):\n                nombre[i] = nombre[i].capitalize()\n            nombreCapitalized = ' '.join(nombre)        \n            print(f'Tu contacto existe -> Nombre: {nombreCapitalized} Numero: {agenda[buscarContacto.lower()]}')\n\n    elif opcion == '3':\n        modificarContacto = input('Cual es el nombre y apellido de tu contacto? ').lower()\n        opcionModificar = input('Ingresa \\'nombre\\' o \\'numero\\' depende lo que quieras modificar ')\n        \n        if opcionModificar == 'nombre':\n            nuevoNombre = input('Cual es el nuevo nombre y appellido del contacto? ').lower()\n            mantenerNumero = agenda[modificarContacto]\n            agenda.pop(modificarContacto)\n            agenda[nuevoNombre] = mantenerNumero\n\n        elif opcionModificar == 'numero':\n            while True:\n                nuevoNumero = input('Cual es el nuevo numero del contacto?\\n')\n                if nuevoNumero.isdigit():\n                    agenda[modificarContacto] = nuevoNumero\n                    break\n                else:\n                    print('Por favor incluye solo digitos en tu numero\\n')\n        print(f'Tu contacto {agenda} ha sido modificado\\n ')\n    \n    elif opcion == '4':\n        eliminarContacto = input('Cual es el nombre y appellido del contacto que deseas eliminar? ').lower()\n\n        if eliminarContacto in agenda:\n            agenda.pop(eliminarContacto)\n            print('El contacto ha sido eliminado ')\n        \n        else:\n            print('Este contacto no existe ')\n    \n    elif opcion == '5':\n        continuar = False\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/gmbarrios.py",
    "content": "# Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n\n# 1. Lista\nlista_1 = [14, 15, 22, 50, 77, 75, 42]\nlista_2 = ['futbol', 'baseball', 'basketball', 'hockey', 'tenis']\nlista_3 = [[1, 2, 3], 4, 5, 6]\nlista_4 = ['lista', 9, 8, 7, 'mezclada']\nprint(lista_1)\nprint(lista_2)\nprint(lista_3)\nprint(lista_4)\n\n# 2. Tupla\ntupla_1 = (10, 11, 12, 13, 14, 15)\ntupla_2 = ('a', 'b', 'c', [1, 2, 3])\nprint(tupla_1)\nprint(tupla_2)\n\n# 3. Diccionario\ndicc_1 = {\n    \"Ronaldo\": \"Real Madrid\",\n    \"Messi\": \"Barcelona\",\n    \"Busquets\": \"Barcelona\",\n    \"Marcelo\": \"Real Madrid\",\n    \"Casillas\": \"Real Madrid\",\n}\nprint(dicc_1)\n\n# 4. Set\nset_1 = {44, 55, 66, 77, 88, 99}\nprint(set_1)\n\n\n# Utiliza operaciones de inserción, borrado, actualización y ordenación.\n# 1. Listas\n\nlista_1.append(40) # Agregar al final de la lista.\nlista_1.insert(1, 5) # Agregar en una posición determinada.\nprint(lista_1)\nlista_1.pop() # Eliminar el ultimo elemento de la lista.\nlista_1.remove(75) # Eliminar un valor determinado.\nprint(lista_1)\nlista_1.clear() # Eliminar todos los elementos de la lista.\nprint(lista_1)\nlista_2[0] = 'football'\nprint(lista_2)\nlista_2.sort() # Ordenar de forma ascendente.\nprint(lista_2)\nlista_3.reverse() # Ordenar de forma descendente.\nprint(lista_3)\n\n# 2. Tuplas: son inmutables\n\n# 3. Diccionarios\n\ndicc_1['Nazario'] = 'Real Madrid'\ndicc_1.pop('Ronaldo')\ndel dicc_1['Busquets']\nprint(dicc_1)\n\n# 4. Sets\nset_1.add(111)\nset_1.pop()\nset_1.remove(44)\nprint(set_1)\n\n\n# Dificultad extra. Creación de una agenda de contactos.\n\ndef my_agenda():\n\n    agenda = {}\n\n    def insert_contact():\n        phone = input(\"Insert phone number: \")\n        if phone.isdigit() and len(phone) > 0 and len(phone) <= 11:\n            agenda[name] = phone\n        else:\n            print(\"Not a valid phone number\")\n    \n    while True:\n\n        print(\"\")\n        print(\"1. Search contact\")\n        print(\"2. Insert contact\")\n        print(\"3. Update contact\")\n        print(\"4. Delete contact\")\n        print(\"5. Exit\")\n\n        option = input(\"Select your choice: \")\n\n        match option:\n            case \"1\":\n                name = input(\"Insert contact's name: \")\n                if name in agenda:\n                    print(f\"{name}'s number is {agenda[name]}.\")\n                else:\n                    print(f\"{name} does not exist.\")\n            \n            case \"2\":\n                name = input(\"Insert contact's name: \")\n                insert_contact()\n            \n            case \"3\":\n                name = input(\"Insert contact's name: \")\n                if name in agenda:\n                    insert_contact()\n                else:\n                    print(f\"{name} does not exist.\")\n            \n            case \"4\":\n                name = input(\"Insert contact's name: \")\n                if name in agenda:\n                    del agenda[name]\n                else:\n                    print(f\"{name} does not exist.\")\n            \n            case \"5\":\n                print(\"Exiting agenda...\")\n                break\n\n            case _:\n                print(\"Non valid option.\")\n            \n\nmy_agenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/gmigues.py",
    "content": "\"\"\"\n#03\nESTRUCTURAS DE DATOS\n/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n *   y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n *   y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más\n *   de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.\n */\n\"\"\"\n\n### LISTAS ### \nlista = [1, 2,2,2,3, 4, 5, 6]\nprint(type(lista))\n\n#Agregar elementos\nlista.append('E')\nlista.extend(['A', '@'])\nprint(lista)\n\n#Eliminar elementos\nlista.remove('A')\nprint(lista)\n\n#Seleccionar items\nprint(lista[0])\n\nprint(\"-----------------------------\")\n\n### TUPLAS ###\nmi_tupla = (1,2,2,2,2,3,4,5)\nprint(type(mi_tupla))\n\n#Seleccionar items\nprint(mi_tupla[1])\n\n#Contar cuantas veces aparece un elemento\nprint(mi_tupla.count(2))\n\n\n\nprint(\"-----------------------------\")\n\n# DICCIONARIOS\n\n# Crear un diccionario\nmi_diccionario = {\n    \"nombre\": \"Juan\",\n    \"edad\": 30,\n    \"ciudad\": \"Madrid\"\n}\nprint(mi_diccionario)\n\n# Acceder a valores\nprint(mi_diccionario[\"nombre\"])  \n\n# Agregar un nuevo par clave-valor\nmi_diccionario[\"profesión\"] = \"Ingeniero\"\n\n# Actualizar un valor existente\nmi_diccionario[\"edad\"] = 31\n\n# Eliminar un par clave-valor\ndel mi_diccionario[\"ciudad\"]\n\n\nprint(mi_diccionario)  \n\n\nprint(\"-----------------------------\")\n\n# SETS\n\n# Crear conjuntos\nconjunto_a = {1, 2, 3}\nconjunto_b = {3, 4, 5}\n\n# Operaciones\nprint(type(conjunto_a))\nprint(\"Inserción\", conjunto_b.add(6))\nprint(\"Eliminación\", conjunto_b.remove(6))\nprint(\"Unión:\", conjunto_a | conjunto_b)  # Unión\nprint(\"Intersección:\", conjunto_a & conjunto_b)  # Intersección\nprint(\"Diferencia:\", conjunto_a - conjunto_b)  # Diferencia\nprint(\"Diferencia simétrica:\", conjunto_a ^ conjunto_b)  # Diferencia simétrica\n\n\n\nprint(\"-----------------------------\")\n\n\n### AGENDA ###\n\nprint('---BIENVENIDO A LA AGENDA ---')\nagenda = {\n    \"Pepe\": 12345678,\n    \"Maria\": 87654321\n}\noperacion =\"\"\nwhile operacion != \"5\":\n    operacion = input('''\n                      \n\n                ---------------------------    \n                Que Operación desea hacer:\n                ---------------------------\n\n                1- Busqueda de contacto\n                2- Actualizacion de contacto\n                3- Ingresar nuevo contacto\n                4- Eliminacion de contacto\n                5- Salir\n                ''')\n\n    if operacion == \"1\":\n        usuario = input('Ingrese el nombre del usuario: ')\n        if usuario in agenda:\n            print((f\"Usuario {usuario}, Telefono:\", agenda[usuario]))\n        else:\n            print(\"El usuario ingresado no existe en la agenda.\")\n            continue\n    elif operacion == \"2\":\n        usuario = input(\"Que usuario desea modificar?: \")\n        if usuario in agenda:\n            nuevo_numero = input(f'Ingrese el nuevo numero de telefono para el usuario {usuario}: ')\n            if len(nuevo_numero) == 8 and nuevo_numero.isdigit():\n                nuevo_numero = int(nuevo_numero)\n                agenda[usuario] = nuevo_numero\n                print(f\"Se ha actualizado correctamente los datos del usuario {usuario}\")\n            else:\n                print(\"Numero ingresado no es valido\")\n        else:\n            print('El usuario ingresado no existe en la agenda')\n    elif operacion == \"3\":\n        nuevo_usuario = input('Ingrese el nombre del nuevo usuario: ')\n        nu_tel = input(\"Ingrese el telefono: \")\n        if len(nu_tel) == 8 and nu_tel.isdigit():\n            nu_tel = int(nu_tel)\n            agenda[nuevo_usuario] = nu_tel\n            print(f'Se ha agregado correctamente el usuario {nuevo_usuario} a la agenda')\n        else:\n            print('Los datos ingresados no son correctos')\n            continue\n    elif operacion == \"4\":\n        del_user = input(\"Ingrese el usuario que desea eliminar: \")\n        if del_user in agenda:\n            del agenda[del_user]\n            print(f'El usuario {del_user} ha sido eliminado de la agenda.')\n        else:\n            print('El usuario ingresado no se encuentra en la agenda')\n            continue\n    elif operacion == \"5\":\n        break\n    else:\n        print('La opcion igresada no es correcta.')\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/gonzadev28.py",
    "content": "\"\"\"* EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\"\"\"\n\n#Listas\nmi_lista: list = [1, 7, 34, 76, 98, 9] #\"list\" es para definir el tipo de variable(lista)\nprint(mi_lista)\n\nmi_lista.insert(0, 2) #En la posicion 0 inserta el valor de \"2\"\nmi_lista.append(10) #Insercion de valor \"10\" en la lista\nmi_lista.remove(76) #Elimina el valor de \"76\" de la lista\ndel mi_lista[5] #Elimina elemento de la lista en la posicion[5]\nmi_lista[2] = 35 #Actualiza el elemento de la posicion[2] (\"34\" a \"35\")\nmi_lista.sort() #Ordenacion de la lista de menor a mayor\nprint(mi_lista)\n\n#Tuplas\nmi_tupla: tuple = (\"Aprendo\", \"Python\", \"Youtube\", \"Mouredev\") #\"tuple\" es para definir el tipo de variable(tupla)\nprint(mi_tupla)\n\nprint(mi_tupla[1]) #Acceso en la posicion [1] de la tupla (\"Python\")\nmi_tupla = tuple(sorted(mi_tupla)) #Ordena la tupla por orden alfabetico\nprint(mi_tupla)\n\n#Sets\nmi_set: set = {\"Java\", \"Python\", \"C#\", \"Cobol\", \"C#\"} #\"set\" es para definir el tipo de variable(sets)\nprint(mi_set) #El set no admite datos repetidos(\"C#\")\n\nmi_set.add(\"Ruby\") #Insercion de \"Ruby\" en el set\nmi_set.remove(\"Java\") #Eliminacion de \"Java\" en el set\nprint(mi_set)\n\n#Diccionario\nmi_diccionario: dict = { #\"dict\" es para definir el tipo de variable(diccionario)\n    \"Nombre\": \"Gonzalo\",\n    \"Lenguaje\": \"Python\",\n    \"Github\": \"gonzadev28\",\n    \"Edad\": 30\n}\nprint(mi_diccionario)\n\nmi_diccionario[\"Ocupacion\"] = \"Estudiante\" #Insercion del campo \"Ocupacion: Estudiante\" al diccionario\ndel mi_diccionario[\"Edad\"] #Eliminacion del campo \"Edad\" al diccionario\nmi_diccionario[\"Lenguaje\"] = \"JS\" #Actualizacion del campo \"Lenguaje\" (\"Python\" a \"JS\")\nprint(mi_diccionario[\"Nombre\"]) #Acceso a campo \"Nombre\"\nprint(mi_diccionario)\n\n\"\"\"DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\"\"\"\n\ndef mi_agenda():\n    agenda: dict = {}\n    while True:\n        print(\"==========================================\")\n        print(\"Selecciona una de las siguientes opciones:\")\n        print(\"==========================================\")\n        print(\"1 - Buscar contacto\")\n        print(\"2 - Ingresar contacto\")\n        print(\"3 - Actualizar contacto\")\n        print(\"4 - Eliminar contacto\")\n        print(\"5 - Salir\\n\")\n        \n        opcion = input(\"Ingrese una de las opciones: \")\n\n        match opcion:\n            case \"1\":\n                nombre = input(\"Ingrese el nombre del contacto a buscar: \")\n                if nombre in agenda:\n                    print(\"El numero de telefono es: \", agenda[nombre])\n                else:\n                    print(\"Contacto no existe\")\n            case \"2\":\n                nombre = input(\"Ingrese el nombre del contacto: \")\n                telefono = input(\"Ingrese el telefono del contacto: \")\n                if telefono.isdigit() and len(telefono) > 0 and len(telefono) <= 9:\n                    agenda[nombre] = telefono\n                else:\n                    print(\"Telefono debe ser menor de 10 digitos\")\n            case \"3\":\n                nombre = input(\"Ingrese el nombre del contacto que desea actualizar: \")\n                if nombre in agenda:\n                    telefono = input(\"Ingrese el telefono del contacto: \")\n                    if telefono.isdigit() and len(telefono) > 0 and len(telefono) <= 9:\n                        agenda[nombre] = telefono\n                    else:\n                        print(\"Telefono debe ser menor de 10 digitos\")\n                else:\n                    print(\"Contacto no existe\")\n            case \"4\":\n                nombre = input(\"Ingrese nombre del contacto que desea eliminar: \")\n                if nombre in agenda:\n                    del agenda[nombre]\n                else:\n                    print(\"Contacto no existe\")\n            case \"5\":\n                break\n            case _:\n                print(\"Opcion invalida\")\n            \nmi_agenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/gringoam.py",
    "content": "# Listas\nmy_list: list = [\"Brais\", \"Bl4ck\", \"Wolfy\", \"Visionos\"]\nprint(my_list)\nmy_list.append(\"Castor\")  # Inserción\nmy_list.append(\"Castor\")\nprint(my_list)\nmy_list.remove(\"Brais\")  # Eliminación\nprint(my_list)\nprint(my_list[1])  # Acceso\nmy_list[1] = \"Cuervillo\"  # Actualización\nprint(my_list)\nmy_list.sort()  # Ordenación\nprint(my_list)\nprint(type(my_list))\n\n# Tuplas\nmy_tuple: tuple = (\"Brais\", \"Moure\", \"@mouredev\", \"36\")\nprint(my_tuple[0])  # Acceso\nprint(my_tuple[3])\nmy_tuple = tuple(sorted(my_tuple))  # Ordenación\nprint(my_tuple)\nprint(type(my_tuple))\n\n# Sets\nmy_set: set = {\"Brais\", \"Moure\", \"@mouredev\", \"36\"}\nprint(my_set)\nmy_set.add(\"mouredev@gmail.com\")  # Inserción\nmy_set.add(\"mouredev@gmail.com\")\nprint(my_set)\nmy_set.remove(\"Moure\")  # Eliminación\nprint(my_set)\nmy_set = set(sorted(my_set))  # No se puede ordenar\nprint(my_set)\nprint(type(my_set))\n\n# Diccionario\nmy_dict: dict = {\n    \"name\": \"Brais\",\n    \"surname\": \"Moure\",\n    \"alias\": \"@mouredev\",\n    \"age\": \"36\"\n}\nmy_dict[\"email\"] = \"mouredev@gmail.com\"  # Inserción\nprint(my_dict)\ndel my_dict[\"surname\"]  # Eliminación\nprint(my_dict)\nprint(my_dict[\"name\"])  # Acceso\nmy_dict[\"age\"] = \"37\"  # Actualización\nprint(my_dict)\nmy_dict = dict(sorted(my_dict.items()))  # Ordenación\nprint(my_dict)\nprint(type(my_dict))\n\n\"\"\"\nExtra\n\"\"\"\n#Agenda\n\nagenda={}\n\ndef insert_contact():\n    phone = input(\"Introduce el teléfono del contacto: \")\n    if phone.isdigit() and len(phone) > 0 and len(phone) <= 11:\n        agenda[nombre] = phone\n    else:\n        print(\n                \"Debes introducir un número de teléfono un máximo de 11 dígitos.\")\n  \n       \n\nwhile True:\n     print(\"Agenda:\")\n     print(\"Ingrese operaci+on a realizar\")\n     print(\"1) Aregar contacto.\")\n     print(\"2) Borrar contacto.\")\n     print(\"3) Buscar contacto.\")\n     print(\"4) Actualizar contacto.\")\n     print(\"5) Salir.\")\n\n     op=input()\n     match op:\n        case \"1\":\n          nombre=input(\"Ingrese nombre del contacto: \")\n          insert_contact()\n        case \"2\":\n         nombre=input(\"Ingrese nombre del contacto: \")\n         if nombre in agenda:\n            del agenda[nombre]\n            print(f\"El contacto {nombre} fue eliminado\")\n         else:\n              print(\"El contacto no existe\")\n        case \"3\":\n         nombre=input(\"Ingrese nombre del contacto: \")\n         if nombre in agenda:\n           print(f\"Contacto  encontrado nombre: {nombre} teléfono: {agenda[nombre]} \")\n         else:\n              print(\"El contacto no existe\")\n        case \"4\":\n         nombre=input(\"Ingrese nombre del contacto: \")  \n         if nombre in agenda:\n           insert_contact()\n         else:\n           print(\"El contacto no existe\")  \n        case \"5\":\n          break\n\nprint(agenda)\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/guillermo-k.py",
    "content": "''' * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n'''\n\n# Listas\nprint(\"LISTAS\")\nlista = [1,'dos',3.14,[15,2]]\nprint(\"BUSQUEDA\")\nprint(\"Busqueda por indice (buscamos el valor ubicado en el indice '2'): \",lista[2])\nprint(\"Busqueda de indice por item (buscamos el indice de '3.14'): \",lista.index(3.14))\nprint(\"------\")\nprint(\"INSERCION\")\nprint(lista)\nprint(\"Al final (agregamos el string 'Hola mundo' al final de la lista)\")\nlista.append(\"Hola mundo\")\nprint(lista)\nprint(\"Entre medio (agregamos el número '3' en la segunda posición)\")\nlista.insert(2,3)\nprint(lista)\nprint(\"Agregamos los elementos de un iterable al final de la lista\")\nlista.extend({5,3,8})\nprint(lista)\nprint(\"-----\")\nprint(\"ACTUALIZACIÓN\")\nprint(\"Actualizamos el item ubicado en la posición '0' dentro de la sub-lista ubicada en la posición '4' de la lista\")\nlista[4][0] = 1\nprint(lista)\nprint(\"-----\")\nprint(\"BORRADO\")\nprint(\"Borramos el elemento de la lista cuyo valor es 'Hola mundo'\")\nlista.remove(\"Hola mundo\")\nprint(lista)\nprint(\"Borramos el ultimo elemento de la lista\")\nlista.pop()\nprint(lista)\nprint(\"Borramos el elemento ubicado en la posición 4 de la lista\")\nlista.pop(4)\nprint(lista)\nprint(\"-----\")\nprint(\"ORDENAMIENTO\")\nprint(\"Invertimos el orden de la lista\")\nlista.reverse()\nprint(lista)\nprint(\"Ordenamos 'alfabeticamente' la lista\")\nprint(\"Para ello, primero 'unificamos' los tipos de datos\")\nlista[4]=2\nprint(lista)\nlista.sort()\nprint(lista)\nprint(\"-----\")\nprint(\"-----\")\n\nprint(\"TUPLAS\")\ntupla = (1,2,3,'cuatro')\nprint(tupla)\nprint(\"BUSQUEDA\")\nprint(\"Busqueda por indice (buscamos el valor ubicado en el indice '2'): \",tupla[2])\nprint(\"Busqueda de indice por item (buscamos el indice de '3'): \",tupla.index(3))\nprint(\"-----\")\nprint(\"Las tuplas, por definición, son objetos inmutables, por lo cual, no se las puede modificar(agregar, asignar o borrar)\")\nprint(\"-----\")\nprint(\"-----\")\n\nprint(\"DICCIONARIOS\")\ndicc = {\"nombre\": \"Guillermo\",\n        \"edad\": 38,\n        \"pais\": \"Argentina\",\n        \"lenguaje\":\"PYTHON\"\n        }\nprint(dicc)\nprint(\"-----\")\nprint(\"BUSQUEDA (buscamos el valor por la clave)\")\nprint(dicc[\"lenguaje\"])\nprint(\"-----\")\nprint(\"INSERCION (agregamos el par [apellido:Köster])\")\ndicc[\"apellido\"]=\"Köster\"\nprint(dicc)\nprint(\"-----\")\nprint(\"RE-ASIGNACIÓN (cambiamos el valor asignado a 'edad')\")\ndicc[\"edad\"] = 39\nprint(dicc)\nprint(\"-----\")\nprint(\"BORRADO (borramos el par lenguaje:python)\")\ndicc.pop(\"lenguaje\")\nprint(dicc)\nprint(\"-----\")\nprint(\"Siendo los diccionarios estructuras no ordenadas, no hay metodos para realizar ordenamientos\")\nprint(\"-----\")\nprint(\"-----\")\n\nprint(\"CONJUNTOS\")\nconjunto = {1,4,3,3,\"Python\",\"Kotlin\",(1,4)} \n'''Notese que en la declaración del conjunto se incluyo 2 veces el número 3,\n    pero este estara una sola vez, ya que los conjuntos no admiten repetidos.\n    No ocurre lo mismo con los números 1 y 4, ya que en la segunda aparición \n    se encuentran dentro de una tupla, lo que lo convierte en un objeto distinto'''\nprint(conjunto)\nprint(\"-----\")\nprint(\"INSERCIÓN\")\nprint(\"SIMPLE agregamos el número 500 al conjunto\")\nconjunto.add(500)\nprint(conjunto)\nprint(\"-----\")\nprint(\"BORRADO borramos el string 'Kotlin'\")\nconjunto.discard('Kotlin')\nprint(conjunto)\nprint(\"-----\")\nprint(\"Borrado aleatoreo (se borra un elemento cualquiera del conjunto)\")\nconjunto.pop()\nprint(conjunto)\nprint(\"Siendo los conjuntos estructuras no ordenadas, no hay metodos para realizar ordenamientos\")\nprint(\"-----\")\nprint(\"-----\")\n\n'''\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n '''\nagenda = []\ndef corre_agenda():\n    def seleccion_tarea():\n        print(\"Seleccione la operación a ralizar:\")\n        print(\"1.- Buscar contacto\")\n        print(\"2.- Crear contacto\")\n        print(\"3.- Modificar contacto\")\n        print(\"4.- Eliminar contacto\")\n        print(\"0.- Cerrar agenda\") \n        return opcion_numerica(range(5))\n    \n    def buscar():\n        nombre = input().upper()\n        resultado = []\n        if len(nombre)>0:\n            for i in agenda:\n                if nombre in i[0]:\n                    resultado.append(i)\n        else:\n            resultado = agenda\n        if len(resultado) > 0:\n            for contacto in resultado:\n                print(f\"{resultado.index(contacto)}.- {contacto[0].capitalize()}: {contacto[1]}\")\n        else:\n            print(\"Contancto no encontrado\")\n        return resultado\n\n\n    def crear():\n        nombre = pedir_nombre()\n        numero = pedir_numero()\n        respuesta = \"\"\n        while respuesta != \"Y\" and respuesta != \"N\":\n            print(f\"Se agregara el contacto: {nombre.capitalize()} con el número {numero}. ¿Es correcto? (Y/N)\")\n            respuesta = input().upper()\n        if respuesta == \"Y\":\n            agenda.append([nombre,numero])\n            agenda.sort(key=lambda contacto: contacto[0])\n        else:\n            print(\"Operación cancelada\")\n\n    def modificar():\n        opciones = buscar()\n        if len(opciones)>1:\n            print(\"Seleccione el contacto a modificar\")\n            opciones = opciones[opcion_numerica(range(len(opciones)))]\n        elif len(opciones)==0:\n            print(\"Intente nuevamente\")\n        print(\"seleccione el campo a modificar:\")\n        print(\"1._ Nombre\")\n        print(\"2._ Número\")\n        print(\"3._ Ámbos\")\n        campo = opcion_numerica((1,2,3))\n        match campo:\n            case 1:\n                agenda[agenda.index(opciones)][0] = pedir_nombre()\n            case 2:\n                agenda[agenda.index(opciones)][1] = pedir_numero()\n            case 3:\n                agenda[agenda.index(opciones)][0] = pedir_nombre()\n                agenda[agenda.index(opciones)][1] = pedir_numero()\n        agenda.sort(key=lambda contacto: contacto[0])\n\n\n    def eliminar(contacto=None):\n        if not contacto:\n            print(\"Ingrese el nombre (o parte del mismo) del conacto a eliminar\")\n            contacto = buscar()\n            if len(contacto)>1:\n                print(\"Seleccione el contacto a eliminar\")\n                contacto = contacto[opcion_numerica(range(len(contacto)))]\n            elif len(contacto)==0:\n                print(\"Intente nuevamente\")\n                return False\n        print(f\"Se borrara permanentemente el contacto: {contacto[0].capitalize()} con el número {contacto[1]}. ¿Es correcto? (Y/N)\")\n        respuesta = input().upper()\n        if respuesta == \"Y\":\n            agenda.remove(contacto)\n            return True\n        return False\n\n    def pedir_nombre():\n        nombre = \"\"\n        while True:\n            print(\"Ingrese el nombre del contacto\")\n            nombre = input().upper()\n            if len(nombre) == 0:\n                print(\"El campo 'nombre' no puede estar vacio\")\n            else:\n                return nombre\n    \n    def pedir_numero():\n        while True:\n            print(\"Ingrese el número\")\n            numero = opcion_numerica()\n            if numero < 100000000000:\n                numero = int(numero)\n                if not existe_numero(numero):\n                    return numero\n                else:\n                    print(\"El numero ya se encuentra registrado\")\n            else:\n                print(\"El número puede tener maximo 11 digitos\")\n            \n    \n    def opcion_numerica(rango = None):\n        while True:\n            opcion = input()\n            if opcion.isdigit():\n                if not rango or int(opcion) in rango:\n                    return int(opcion)\n                else:\n                    print(\"Opcion no valida\")\n            else:\n                print(\"Se debe ingresar un numero\")\n\n    def existe_numero(numero):\n        for i in agenda:\n            if i[1] == numero:\n                return True\n        return False\n\n\n    abierta = True\n    while abierta:\n        opcion = seleccion_tarea()\n        match opcion:\n            case 1:\n                print(\"Ingrese el nombre (o parte del mismo) del contacto a buscar\")\n                buscar()\n            case 2:\n                crear()\n            case 3:\n                print(\"Ingrese el nombre (o parte del mismo) del conacto a modificar\")\n                modificar()\n            case 4:\n                eliminar()\n            case 0:\n                abierta = False\n                print(\"Gracias por utilizar la agenda. Nos vemos pronto\")\ncorre_agenda()\n\n        \n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/h4ckxel.py",
    "content": "# Listas\nprint(\"Vamos a crer una lista\")\nmiLista = [1,8,4,2,5,6]\n\n# Imprimir lista\nprint(f\"La lista es: {miLista}\")\n\n# Añadir elemento a la lista\nmiLista.append(3)\nprint(f\"La lista queda asi tras insertar el 3: {miLista}\")\n\n# Añadir elemento en una posicion concreta\nmiLista.insert(2, 10)\nprint(f\"La lista queda asi tras insertar el 10 en la posicion 2: {miLista}\")\n\n# Eliminar un elemento de la lista\nmiLista.remove(2)\nprint(f\"La lista tras eliminar el 2 es: {miLista}\")\n\n# Buscar un elemento en una posicion de la lista \nprint(f\"La elemento den la posicion 5 de la lista es: {miLista.index(5)}\")\n\n# Ordenar una lista\nmiLista.sort()\nprint(f\"La lista ordenada es: {miLista}\") \n\n# Invertir una lista\nmiLista.reverse()\nprint(f\"La lista ordenada de forma inversa es: {miLista}\")\n\n# Comprobar si un elemento esta en la lista\nprint(f\"¿Esta el numero 10 en la lista?: {10 in miLista}\")\n\nprint(\"\\n\")\n\n# Tuplas\nprint(\"Vamos a crear una tupla\")\nmiTupla = (1,2,6,7,4,2,8)\n\nprint(f\"El contenido de mi tupla es {miTupla}\")\n\n# añadir elemento a una tupla\nmiTupla += (5,)\nprint(f\"El contenido de mi tupla tras añadir el 5 es: {miTupla}\")\n\n# convertir una tupla en una lista\nmiLista = list(miTupla)\nprint(f\"El contenido de mi lista es: {miLista}\")\n\n# Convertir una lista en una tupla\nmiTupla = tuple(miLista)\nprint(f\"El contenido de mi tupla es: {miTupla}\")\n# No se pueden añadir o eliminar elementos en una tupla\n\n#ordenar tupla\nmiTupla = sorted(miTupla)\nprint(f\"El contenido de mi tupla ordenada es: {miTupla}\")\n\n# Buscar un elemento en una tupla\nprint(f\"El elemento 8 esta en la posicion {miTupla.index(8)}\")\n\n#Juntar dos tuplas\nmiTupla2 = (10,11,12)\nmiTupla += miTupla2\nprint(f\"El contenido de mi tupla tras juntarla con otra es: {miTupla}\")\n\nprint(\"\\n\")\n\n# Conjuntos\nprint(\"Vamos a crear un conjunto\")\n\n# Crear un conjunto\nmiConjunto = set()\nprint(f\"El contenido de mi conjunto es: {miConjunto}\")\n# Añadir elementos al conjunto\nmiConjunto.add(1)\nmiConjunto.add(2)\nmiConjunto.add(3)\n\nprint(f\"El contenido de mi conjunto es: {miConjunto}\")\n# Eliminar un elemento del conjunto\nmiConjunto.discard(1)\nprint(f\"El contenido de mi conjunto es: {miConjunto}\")\n\n# Comprobar si un elemento esta en el conjunto\nprint(f\"¿Esta el numero 2 en el conjunto?: {2 in miConjunto}\")\n\n# Juntar conjuntos\nmiConjunto2 = {3,4,5}\nmiConjunto = miConjunto.union(miConjunto2)\nprint(f\"El contenido de mi conjunto tras juntarlo con otro es: {miConjunto}\")\n\n# Diferencia entre conjuntos\nmiConjunto = {1,2,3,4,5}\nmiConjunto2 = {3,4,5,6,7}\nmiConjunto = miConjunto.difference(miConjunto2)\nprint(f\"El contenido de mi conjunto tras hacer la diferencia con otro es: {miConjunto}\")\n\n# Interseccion entre conjuntos\nmiConjunto = {1,2,3,4,5}\nmiConjunto2 = {3,4,5,6,7}\nmiConjunto = miConjunto.intersection(miConjunto2)\nprint(f\"El contenido de mi conjunto tras hacer la interseccion con otro es: {miConjunto}\")\n\nprint(\"\\n\")\n\n# Diccionarios\nprint(\"Vamos a crear un diccionario\")\n\n# Crear un diccionario\nmiDiccionario = {\"Alemania\":\"Berlin\", \"Francia\":\"Paris\", \"España\":\"Madrid\", \"Italia\":\"Roma\"}\nprint(f\"El contenido de mi diccionario es: {miDiccionario}\")\n\n# Añadir un elemento al diccionario\nmiDiccionario[\"Portugal\"] = \"Lisboa\"\nprint(f\"El contenido de mi diccionario es: {miDiccionario}\")\n\n# Eliminar un elemento del diccionario\ndel miDiccionario[\"Portugal\"]\nprint(f\"El contenido de mi diccionario es: {miDiccionario}\")\n\n# Extra\n\nagenda = {}\n\ndef showMenu():\n    print(\"\\nAgenda de Contactos\")\n    print(\"1. Buscar contacto\")\n    print(\"2. Insertar contacto\")\n    print(\"3. Actualizar contacto\")\n    print(\"4. Eliminar contacto\")\n    print(\"5. Mostrar todos los contactos\")\n    print(\"6. Salir\")\n\ndef searchContact():\n    nombre = input(\"Ingrese el nombre del contacto a buscar: \")\n    if nombre in agenda:\n        print(f\"Nombre: {nombre}, Teléfono: {agenda[nombre]}\")\n    else:\n        print(f\"El contacto {nombre} no existe en la agenda.\")\n\ndef addContact():\n    nombre = input(\"Ingrese el nombre del contacto: \")\n    telefono = input(\"Ingrese el número de teléfono: \")\n\n    # Validar que el número de teléfono sea numérico y tenga la longitud deseada\n    if telefono.isdigit() and len(telefono) <= 11:\n        agenda[nombre] = telefono\n        print(f\"Contacto {nombre} insertado correctamente.\")\n    else:\n        print(\"Número de teléfono no válido.\")\n\ndef updateContact():\n    nombre = input(\"Ingrese el nombre del contacto a actualizar: \")\n    if nombre in agenda:\n        nuevo_telefono = input(\"Ingrese el nuevo número de teléfono: \")\n\n        # Validar que el número de teléfono sea numérico y tenga la longitud deseada\n        if nuevo_telefono.isdigit() and len(nuevo_telefono) <= 11:\n            agenda[nombre] = nuevo_telefono\n            print(f\"Contacto {nombre} actualizado correctamente.\")\n        else:\n            print(\"Número de teléfono no válido.\")\n    else:\n        print(f\"El contacto {nombre} no existe en la agenda.\")\n\ndef removeContact():\n    nombre = input(\"Ingrese el nombre del contacto a eliminar: \")\n    if nombre in agenda:\n        del agenda[nombre]\n        print(f\"Contacto {nombre} eliminado correctamente.\")\n    else:\n        print(f\"El contacto {nombre} no existe en la agenda.\")\n\ndef listContact():\n    if agenda:\n        print(\"\\nLista de contactos:\")\n        for nombre, telefono in agenda.items():\n            print(f\"Nombre: {nombre}, Teléfono: {telefono}\")\n    else:\n        print(\"La agenda está vacía.\")\n\n# Menú principal\nwhile True:\n    showMenu()\n    opcion = input(\"Seleccione una opción (1-6): \")\n\n    if opcion == \"1\":\n        searchContact()\n    elif opcion == \"2\":\n        addContact()\n    elif opcion == \"3\":\n        updateContact()\n    elif opcion == \"4\":\n        removeContact()\n    elif opcion == \"5\":\n        listContact()\n    elif opcion == \"6\":\n        print(\"¡Hasta luego!\")\n        break\n    else:\n        print(\"Opción no válida. Por favor, seleccione una opción del 1 al 6.\")"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/haroldAlb.py",
    "content": "### 1 - LISTAS ###\nprint('## 1 - LISTAS ##')\n# Creación de listas\nprint('# Creación de listas #')\nlista_nombres= ['Ana', 'Mario', 'Olga', 'Marco']\nprint(lista_nombres)\n\n# añadir un elemento a la lista\nprint('# añadir un elemento a la lista #')\nlista_nombres.append('Maria')\nprint(lista_nombres)\n\n# borrar un elemento\nprint('# borrar un elemento #')\nlista_nombres.remove('Ana')\nprint(lista_nombres)\n\n# Acceso a un elemeto de la lista\nprint('# Acceso a un elemeto de la lista #')\nprint(lista_nombres[1])\n\n# Actualizar un elemento\nprint('# Actualizar un elemento #')\nlista_nombres[1]= 'Luis'\nprint(lista_nombres)\n\n# Ordenar elementos\nprint('# Ordenar elementos #') \nprint(f'Ordenado como lo hemos creado --> {lista_nombres}')\nlista_nombres.sort()\nprint(f'Ordenado con SORT() ------------> {lista_nombres}') # ordena por orden alfabetico de la 'a' a la 'z'\nlista_nombres.reverse()\nprint(f'Ordenado con REVERSE() ---------> {lista_nombres}') # ordena por orden alfabetico de la 'z' a la 'a'\n\n### 2 - TUPLAS ###\nprint('### 2 - TUPLAS ###')\n# Creación de Tuplas\nprint('# Creación de Tuplas #')\ntupla_nombres= ('Harold', 'Ana','Olga', 'Mario', 666)\nprint(tupla_nombres)\n\n# Acceso a un elemeto de la Tupla\nprint('# Acceso a un elemeto de la Tupla #')\nprint(tupla_nombres[1])\n\n# Desempaquetado de Tuplas\nprint('# Desempaquetado de Tuplas #')\npersona_tupla = (\"Ana\", \"Conejos\", 47)\nnombre, apellido, edad = persona_tupla\nprint(nombre)\nprint(apellido)\nprint(edad)\n\n### 3 - SETS ###\nprint('### 3 - SETS ###')\n# Creación de Sets\nprint('## Creación de Sets ##')\nset_num1= {2, 5, 1, 9}\nprint(set_num1)\nlist_num= [10, 90, 50]\nset_num2= set(list_num)\nprint(set_num2)\n\n# añadir un elemento a un Set\nprint('# Agregar elementos #')\nset_num1.add(7)\nprint(set_num1)\n\n# borrar un elemento de un Set\nprint('# borrar un elemento de un Set#')\nset_num1.remove(2) # Si el elemento no está en el Set, el interprete lanzará un error\nprint(set_num1)\nset_num2.discard(30) # No arrojará un error si el elemento no está presente en el conjunto\nprint(set_num2)\nset_num2.pop() # Elimina un elemento al azar\nprint(set_num2)\n\n# Acceso a un elemeto del Set\nprint('# Acceso a un elemeto del Set #')\nprint(\"No se puede acceder a los elementos de un Set mediante indice,\\npero si podemos recorrerlo con un bucle 'for'\\no preguntar si un valor está presente con un 'in'\")\nfor x in set_num1:\n    print(x)\nif 90 in set_num2:\n    print(f'90 si está')\n\n### 4 - DICCIONARIOS ###\nprint('### 4 - DICCIONARIOS ###')\n\n# Creación de un diccionario\nprint('# Creación de un diccionario #')\ndict_Usuario= {\n    'Nombre' : 'Mario',\n    'Apellidos' : 'Albiñana',\n    'Alias' : 'Marito',\n    'Edad' : 7\n}\nprint(dict_Usuario) \n\n# añadir un elemento a un Diccionario\nprint('# Añadir un elemento a un Diccionario#')\ndict_Usuario['email'] = 'marioalb@gmail.com'\nprint(dict_Usuario)\n\n# Acceso a un elemento de un Diccionario\nprint('# Acceso a un elemento de un Diccionario #')\nprint(dict_Usuario['Nombre'])\n\n# Actualizar un elemento de un Diccionario\nprint('# Actualizar un elemento de un Diccionario #')\ndict_Usuario['Apellidos'] = 'Albiñana Conejos'\nprint(dict_Usuario)\n\n# Borrar un elemento de un Diccionario\nprint('# Borrar un elemento de un Diccionario #')\ndel dict_Usuario['Alias']\nprint(dict_Usuario)\n\nvalorBorrado= dict_Usuario.pop('email') # Elimina y devuelve el valor de la clave eliminada\nprint(f'{valorBorrado} ha sido eliminado del diccionario\\nAhora hay {dict_Usuario}')\n\n### EJERCICIO EXTRA OPCIONAL ###\nprint('### EJERCICIO EXTRA OPCIONAL ###')\n\nejecucion= True\nmenu= ''' ##### AGENDA DE CONTACTOS #####\n[A]ñadir contacto\n[B]uscar contacto\n[E]liminar contacto\na[C]tualizar contacto\n[S]alir de la aplicación'''\n\ndef añadir_contacto(name, tlf):\n    global agenda\n    agenda.append({'nombre':name, 'tlf':tlf})\n\ndef buscar_contacto(busqueda):\n    for x in agenda:\n        if x ['nombre'] == busqueda:\n            print(f'{x['nombre']} : {x['tlf']}')\n\ndef borrar_contacto(nombre_borrar):\n    count= 0\n    for contacto in agenda:\n        if contacto ['nombre'] == nombre_borrar:\n            agenda.pop(count)\n            print(f'{nombre_borrar} fue borrado con exito!')\n            break\n        else:\n            count += 1\n\n    if count == len(agenda):\n        print(f'{nombre_borrar} no se haya en la agenda')\n\ndef actualizar_contacto(busqueda, clave):\n    global agenda\n    count= 0\n    for nombre in agenda:\n        if nombre['nombre'] == busqueda:\n            if clave == 'n':\n                nombre_actualizar= input(f'Actualizar el nombre de \\'{busqueda}\\' a: ')\n                agenda[count]['nombre'] = nombre_actualizar\n                print(agenda[count])\n            elif clave == 't':\n                tlf_actualizar= input(f'Actualizar el tlf de \\'{busqueda}\\' a: ')\n                agenda[count]['tlf'] = tlf_actualizar\n                print(agenda[count])\n            elif clave == 'a':\n                nombre_actualizar= input(f'Actualizar el nombre de \\'{busqueda}\\' a: ')\n                tlf_actualizar= input(f'Actualizar el tlf de \\'{nombre_actualizar}\\' a: ')\n                agenda[count]['nombre'] = nombre_actualizar\n                agenda[count]['tlf'] = tlf_actualizar\n                print(agenda[count])\n        count += 1\n\nwhile ejecucion:\n    print(menu)\n    char=input('Introduce opción: ')\n    end= True\n\n    if char == 'a' or char == 'A': # añadir contacto\n        Nombre= input('Introduce el nombre del contacto: ')\n\n        while end:\n            Tlf= input('Introduce el teléfono del contacto: ')\n            if Tlf.isnumeric() and len(Tlf) < 10:\n                añadir_contacto(Nombre, Tlf)\n                end= False\n\n    elif char == 'b' or char == 'B': # buscar contacto\n        nombre_busqueda= input('Indica el nombre a buscar:')\n\n        buscar_contacto(nombre_busqueda)\n\n    elif char == 'e' or char == 'E': # borrar contacto\n        nombre_eliminar= input('Indica el nombre a borrar: ')\n\n        borrar_contacto(nombre_eliminar)\n\n    elif char == 'c' or char == 'C': # actualizar contacto\n        nombre_busqueda= input('Introduce nombre contacto a actualizar: ')\n        clave_actualizar= input('Que quiere actualizar:\\n[n]ombre\\n[t]eléfono\\n')\n\n        actualizar_contacto()\n\n    elif char == 's' or char == 'S': # salir aplicación\n        print('Adios!')\n        ejecucion= False\n\n    else: # opción incorrecta\n        print('Opción incorreceta. Vuelva a introducir opción')\n\n\n# Timing del video por donde me he quedado (EJERCICIO EXTRA OPCIONAL) -> 2.23.00"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/hectordbh.py",
    "content": "\"\"\"EJERCICIO\"\"\"\n\n# --------- lista ------------\nl = [] # lista vacía\n\n# Operación de inserción de datos en la lista\nfor i in range(5):\n    l.append(i)\nprint(l)\n\n# Operación de actualización de un elemento\nl[2] = 7\nprint(l)\n\n# Operación de borrado de un elemento\nl.remove(4)\nprint(l)\n\n# Operación de ordenación de elementos\nl_ordenada = sorted(l)\nprint(l_ordenada)\n\n# --------- Tupla ------------\nt = (1, 2, 3, 4) # tupla\n\ndicc = {} # diccionario vacío\n\n# Operación de inserción de datos en el diccionario\ndicc[\"Inserción 1\"] = \"Este es el valor para la primera inserción\"\ndicc[\"Inserción 2\"] = \"Este se corresponde con la segunda inserción\"\nprint(dicc)\n\n# Operación de actualización de datos en el diccionario\ndicc[\"Inserción 2\"] = \"Segunda inserción modificada\"\nprint(dicc)\n\n# Operación de borrado de un elemento\ndel dicc[\"Inserción 1\"]\nprint(dicc)\n\n# ------- Conjunto -----------\ncj = {\"Pedro\"} # Conjunto\nprint(cj)\n\n# Operación de inserción de datos en el conjunto\ncj.add(\"Jose\")\nprint(cj)\n\n# Operación de actualización de datos en el conjunto\ncj.update([\"Luis\", \"Ana\", \"Isabel\"])\nprint(cj)\n\n# Operación de borrado de datos en el conjunto\ncj.remove(\"Pedro\")\nprint(cj)\n\n# DIFICULTAD EXTRA\n\nclass Diary():\n    \"\"\"\n    Clase para crear agendas con los atributos y métodos\n    correspondientes\n    \"\"\"\n    def __init__(self):\n        self.contacts = []\n        self.elec = str()\n        self.n = 0\n        self.register = int()\n\n    diccInst = {\"A\": \"añadir registro\", \"F\": \"búscar registro\",\n                \"U\": \"modificar registro\", \"E\": \"eliminar registro\",\n                \"S\": \"ver todos los registros\", \"Q\": \"salir del programa\"}\n\n    @classmethod\n    def methods(cls):\n        \"\"\"\n        Método que informa de las operaciones disponibles en cada\n        instancia del Diary\n        \"\"\"\n        print(\"Después de crear el objeto de la clase Diary llama\",\n              \"al método 'election' para realizar alguna de las\",\n              \"siguientes operaciones:\\n\"+\n              \"(Debes indicar la letra mayúscula que tiene asociada)\\n\")\n        for key, value in Diary.diccInst.items():\n            print(f\"{key}: {value}\")\n\n    def election(self):\n        \"\"\"\n        Método para tomar la elección del usuario\n        \"\"\"\n        self.elec = input(\"Elige una operación: \").upper()\n\n        if self.elec == \"A\":\n            return self.insert()\n\n        if self.elec == \"F\":\n            print(\"\\nIndica qué tipo de registro quieres buscar: N (nombre)\",\n              \", P (teléfono) o R (número de registro)\")\n            type_search = str(input(\"Tipo de registro: \")).upper()\n            return self.search(type_search)\n\n        if self.elec == \"U\":\n            print()\n            return self.update()\n\n        if self.elec == \"E\":\n            print()\n            return self.delete()\n\n        if self.elec == \"S\":\n            print(\"\\n------ AGENDA ------\")\n            for item in self.contacts:\n                print(f\"{item[0]} --> Nombre: {item[1]}, teléfono: {item[2]}\")\n\n        if self.elec == \"Q\":\n            return self.__del__\n\n    def insert(self):\n        \"\"\"\n        Método para añadir un registro al diario\n        \"\"\"\n        print()\n        name = str(input(\"Nombre: \"))\n        phone = input(\"Teléfono: \")\n\n        if len(phone) > 11 or len(phone) < 9:\n            print(\"\\nEl número de teléfono no puede tener más de\"+\n                  \" 11 caracteres ni menos de 9\")\n        elif phone != int:\n            print(\"\\nNo se puede introducir un número no numérico en\"+\n                  \" el campo teléfono\")\n        else:\n            self.n += 1\n            self.contacts.append([self.n, name, phone])\n            print(\"\\nEl contacto ha sido añadido a la agenda\")\n\n    def search(self, s):\n        \"\"\"\n        Método para buscar un registro en la agenda\n        \"\"\"\n        if s == \"P\":\n            phone_number = str(input(\"Indica el número de teléfono: \"))\n            for item in self.contacts:\n                if item[2] == phone_number:\n                    print(f\"\\nRegistro: {item[0]} --> Nombre: {item[1]}, teléfono: {item[2]}\")\n\n        if s == \"N\":\n            contact_name = str(input(\"Indica el nombre del contacto: \"))\n            for item in self.contacts:\n                if item[1] == contact_name:\n                    print(f\"\\nRegistro: {item[0]} --> Nombre: {item[1]}, teléfono: {item[2]}\")\n\n        if s == \"R\":\n            self.register = int(input(\"Indica el número de registro: \"))\n            for item in self.contacts:\n                if item[0] == self.register:\n                    print(f\"\\nRegistro: {item[0]} --> Nombre: {item[1]}, teléfono: {item[2]}\")\n\n    def update(self):\n        \"\"\"\n        Método para modificar el registro indicado\n        \"\"\"\n        self.search(\"R\")\n        change = str(input(\"\\n¿Qué quieres cambiar? (P: teléfono, N: nombre, A: todo): \")).upper()\n\n        if change == \"N\":\n            new_name = str(input(\"Indica el nuevo nombre: \"))\n            self.contacts[self.register - 1][1] = new_name\n            print(\"\\nRegistro actualizado\")\n            print(f\"\\nRegistro: {self.contacts[self.register - 1][0]} --> \\\n                  Nombre: {self.contacts[self.register - 1][1]}, \\\n                    teléfono: {self.contacts[self.register - 1][2]}\")\n\n        if change == \"P\":\n            new_phone = str(input(\"Indica el nuevo teléfono: \"))\n            self.contacts[self.register - 1][2] = new_phone\n            print(\"\\nRegistro actualizado\")\n            print(f\"\\nRegistro: {self.contacts[self.register - 1][0]} --> \\\n                  Nombre: {self.contacts[self.register - 1][1]}, \\\n                    teléfono: {self.contacts[self.register - 1][2]}\")\n\n        if change == \"A\":\n            new_name = str(input(\"Indica el nuevo nombre: \"))\n            new_phone = str(input(\"Indica el nuevo teléfono: \"))\n            self.contacts[self.register - 1][1] = new_name\n            self.contacts[self.register - 1][2] = new_phone\n            print(\"\\nRegistro actualizado\")\n            print(f\"\\nRegistro: {self.contacts[self.register - 1][0]} --> \\\n                  Nombre: {self.contacts[self.register - 1][1]}, \\\n                    teléfono: {self.contacts[self.register - 1][2]}\")\n\n    def delete(self):\n        \"\"\"\n        Método para eliminar un registro\n        \"\"\"\n        self.search(\"R\")\n        desition = str(input(\"\\nSeguro que quieres borrar el registro? (Y: sí, N: no): \")).upper()\n        if desition == \"Y\":\n            self.contacts.remove(self.contacts[self.register - 1])\n            print(\"\\nRegistro eliminado de la agenda\")\n        else:\n            print(\"\\nVeo que lo has pensado mejor\")\n\n    def __del__(self):\n        \"\"\"\n        Método para borrar la instancia y salir de la aplicación\n        \"\"\"\n        print(\"\\nAcabas de destruir el objeto creado para esta agenda\")\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/hectorio23.py",
    "content": "# Autor: Héctor Adán \n# GitHub: https://github.com/hectoiro23\n\n'''\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n'''\n\ncontacts = []\n\ndef menu():\n    while True:\n        print(\"************ Sistema de Gestion de contactos *************\")\n        print(\"[1] - Busqueda de Contactos\")\n        print(\"[2] - Insercion de Contactos\")\n        print(\"[3] - Actualizacion de Contactos\")\n        print(\"[4] - Eliminacion de Contactos\")\n        print(\"[5] - Imprimir todos los contactos\")\n        print(\"[6] - Terminar el programa\")\n\n        choose = input(\"Escoge una opcion: \")\n\n        if choose == '1':\n            buscar_contacto()\n        elif choose == '2':\n            agregar_contacto()\n        elif choose == '3':\n            actualizar_contacto()\n        elif choose == '4':\n            eliminar_contacto()\n        elif choose == '5':\n            imprimir_contactos()\n        elif choose == '6':\n            print(\"Programa terminado. Adios.\")\n            break\n        else:\n            print(\"Opcion invalida. Intentalo de nuevo.\")\n        print(\"\\n\\n\")\n\ndef buscar_contacto():\n    patron = input(\"Ingresa el registro que quieras buscar (nombre/telefono): \")\n    print(\"\\n\")\n\n    encontrado = False\n    for nombre, telefono in contacts:\n        if nombre == patron or telefono == patron:\n            print(f\"Registro encontrado: {nombre} <- {telefono}\")\n            encontrado = True\n            break\n\n    if not encontrado:\n        print(\"Dato no encontrado\")\n\ndef agregar_contacto():\n    nombre = input(\"Ingresa el nombre del nuevo contacto: \")\n    telefono = input(\"Ingresa el numero de telefono del nuevo contacto: \")\n\n    if len(telefono) > 11 or not telefono.isdigit():\n        print(\"Numero de telefono invalido. Debe tener hasta 11 digitos y ser numerico.\")\n        return\n\n    contacts.append((nombre, telefono))\n    print(\"Contacto agregado exitosamente.\")\n\ndef actualizar_contacto():\n    nombre = input(\"Ingresa el nombre del contacto que quieres actualizar: \")\n\n    encontrado = False\n    for i, (nombre_contacto, telefono_contacto) in enumerate(contacts):\n        if nombre_contacto == nombre:\n            nuevo_telefono = input(f\"Ingresa el nuevo numero de telefono para {nombre}: \")\n\n            if len(nuevo_telefono) > 11 or not nuevo_telefono.isdigit():\n                print(\"Numero de telefono invalido. Debe tener hasta 11 digitos y ser numerico.\")\n                return\n\n            contacts[i] = (nombre_contacto, nuevo_telefono)\n            print(\"Contacto actualizado exitosamente.\")\n            encontrado = True\n            break\n\n    if not encontrado:\n        print(\"Contacto no encontrado.\")\n\ndef eliminar_contacto():\n    nombre = input(\"Ingresa el nombre del contacto que quieres eliminar: \")\n\n    for i, (nombre_contacto, telefono_contacto) in enumerate(contacts):\n        if nombre_contacto == nombre:\n            del contacts[i]\n            print(\"Contacto eliminado exitosamente.\")\n            return\n\n    print(\"Contacto no encontrado.\")\n\ndef imprimir_contactos():\n    print(\"\\n\\n\")\n    for nombre, telefono in contacts:\n        print(f\"{nombre} <- {telefono}\\n\\n\")\n\nif __name__ == \"__main__\":\n    menu()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/hendrycode.py",
    "content": "#Listas\nprint(\"-----------Seccion de lista-------------\")\nprint(\"list is a collection which is ordered and changeable. allows duplicates members\")\nmy_list = [100,22,13,4,5]\n#añadir\nmy_list.append(\"Hola\")#se añade de ultimo\nmy_list.insert(0, 20)\nprint(my_list)\n#remover\nmy_list.remove(20) #remueve la primera ocurrencia del elemento y si no esta devuele una excepcion\nmy_list.pop()#remueve un elemento y te devuelve su index, por default remueve el ultimo\nprint(my_list)\n#ordenar\nmy_list.sort()# se puede pasar el parametro \"reverse\" con un valor booleano, solo funciona con INT\nprint(my_list)\n\nprint(\"-----------Seccion de tupla-------------\")\nprint(\"is a collection which is ordered and unchangeable. allows duplicate member\")\n#las tuplas son inmutables por lo que no se pueden modificar\nmy_tuple = (12,1,4,50,24)\nprint(f\"{my_tuple} las tuplas son inmutables\")\n#obtener la primera ocurrencia de un valor y devolver el index\nmy_tuple.index(4)\n\nprint(\"-----------Seccion de Set-------------\")\nprint(\"is a collection which is unordered and unchangeable. dont allow duplicate member\")\nmy_set = {10,2,30,5,40,5}\n\n#añadir\nmy_set.add(1034)\n\n\n#update uniendo otro iterable\nmy_set.update({100,200,300})\nprint(my_set)\n\n#remover\nmy_set.remove(5)\nprint(f\"This is my set without 5: {my_set}\")\n\n#limpiar todo el set\nmy_set.clear()\nprint(my_set)\n\nprint(\"-----------Seccion de Diccionario-------------\")\nprint(\"is a collection which is ordered** and and changeable. dont allows\")\n\nmy_dict = {\n    \"Nombre\": \"Hendry\",\n    \"Edad\": 23,\n    \"¿Casado?\": True\n}\nprint(my_dict)\n#añadir un objeto al diccionario\nprint(\"Añadiendo\")\nmy_dict[\"lenguajes de programacion\"] = [\"Python\", \"Javascript\", \"React\", \"HTML\", \"Css\", \"Django\", \"Postgress\"]\nprint(my_dict)\n\n#actualizar un objeto\nmy_dict.update({\"Nombre\": \"Alberto\"})\nprint(my_dict)\n\n#obtener un objeto\nr = my_dict.get(\"lenguajes de programacion\")\nprint(r)\nr2 = my_dict[\"lenguajes de programacion\"]\nprint(r2)\n\n#removin an iten\ndel my_dict[\"Edad\"]\nprint(my_dict)\n\nmy_dict.pop(\"¿Casado?\")\nprint(my_dict)\n\nprint(\"-----------------Ejercicio---------------------\")\n\nfrom time import sleep\n\ncontactos = {}\n\ndef mostrar_bienvenida():\n    print(\"\"\"\n    Hola! Bienvenido a tu agenda personal de contacto. ¿En qué te puedo ayudar?\n    \n    1 - Buscar contacto.\n    2 - Guardar un contacto.\n    3 - Actualizar un contacto.\n    4 - Eliminar un contacto.\n    5 - Mostrar todos los contactos\n    6 - Cerrar la agenda.\n    \"\"\")\n\ndef buscar_contacto():\n    nombre = input(\"Introduce el nombre del contacto a buscar: \")\n    if nombre in contactos:\n        print(f\"Contacto encontrado: {nombre}, Teléfono: {contactos[nombre]}\")\n    else:\n        print(\"Contacto no encontrado.\")\n\ndef guardar_contacto():\n    nombre = input(\"Introduce el nombre del contacto a guardar: \")\n    telefono = input(\"Introduce el número de teléfono a guardar: \")\n    \n    if not nombre or not isinstance(nombre, str):\n        print(\"Por favor ingrese un nombre válido.\")\n        return\n    \n    if not telefono.isdigit() or len(telefono) != 11:\n        print(\"Ingrese un teléfono válido (debe tener exactamente 11 dígitos).\")\n        return\n    \n    print(f\"Guardando en la agenda a {nombre} con el siguiente número de teléfono: {telefono}\")\n    contactos[nombre] = telefono\n    sleep(2)\n    print(\"¡Guardado con éxito!\")\n\ndef actualizar_contacto():\n    nombre = input(\"Introduce el nombre del contacto a actualizar: \")\n    if nombre in contactos:\n        nuevo_telefono = input(\"Introduce el nuevo número de teléfono: \")\n        if nuevo_telefono.isdigit() and len(nuevo_telefono) == 11:\n            contactos[nombre] = nuevo_telefono\n            print(\"Contacto actualizado con éxito.\")\n        else:\n            print(\"Número de teléfono no válido.\")\n    else:\n        print(\"Contacto no encontrado.\")\n\ndef eliminar_contacto():\n    nombre = input(\"Introduce el nombre del contacto a eliminar: \")\n    if nombre in contactos:\n        del contactos[nombre]\n        print(\"Contacto eliminado con éxito.\")\n    else:\n        print(\"Contacto no encontrado.\")\n\ndef cerrar_agenda():\n    print(\"Finalizando programa...\")\n    sleep(2)\n    print(\"¡Hasta luego!\")\n    return False\n\ndef mostrar_contactos():\n    print(\"-----Lista de contactos-----\")\n    for nombre, telefono in contactos.items():\n        print(f\"Nombre: {nombre}\")\n        print(f\"Telefono: {telefono}\")\n\noptions = {\n    1: buscar_contacto,\n    2: guardar_contacto,\n    3: actualizar_contacto,\n    4: eliminar_contacto,\n    5: mostrar_contactos,\n    6: cerrar_agenda\n}\n\nif __name__ == \"__main__\":\n    while True:\n        mostrar_bienvenida()\n        try:\n            seleccion_usuario = int(input(\"Selecciona el número de tu operación, por favor: \"))\n        except ValueError:\n            print(\"Por favor, ingresa un número válido.\")\n            continue\n\n        \n        funcion_seleccionada = options.get(seleccion_usuario)\n\n        if funcion_seleccionada:\n            \n            resultado = funcion_seleccionada()\n            if resultado == False:  \n                break\n        else:\n            print(\"Por favor, selecciona un número válido entre el 1 y el 6.\")"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/hozlucas28.py",
    "content": "\"\"\"Module for HEAP structure\"\"\"\nimport heapq\nfrom collections import deque\n\n\n\"\"\"\n    Structures...\n\"\"\"\n\n# List - Array of elements\nLIST = [1, 2, 3]\nprint(\"List structure: <LIST NAME> = [<ELEMENTS...>]\")\nprint(f\"LIST = [1, 2, 3] --> LIST = {LIST}\")\n\n# Tuple - Immutable array of elements\nTUPLE = (1, 2, 3)\nprint(\"\\nTuple structure: <TUPLE NAME> = (<ELEMENTS...>)\")\nprint(f\"TUPLE = (1, 2, 3) --> TUPLE = {TUPLE}\")\n\n# Set - Collection of unique elements\nSET = {\"first\", \"second\", \"third\"}\nprint(\"\\nSet structure: <SET NAME> = {<ELEMENTS...>}\")\nprint(\"SET = {'first', 'second', 'third'} --> SET =\", SET)\n\n# Dictionary - An object like JavaScript\nDICTIONARY = {\n    \"first_name\": \"Lucas\",\n    \"last_name\": \"Hoz\",\n}\nprint(\"\\nDictionary structure: <DICTIONARY NAME> = {<PROPERTIES...>}\")\nprint(\n    \"DICTIONARY = { 'first_name': 'Lucas', 'last_name': 'Hoz' } --> DICTIONARY =\",\n    DICTIONARY,\n)\n\n# Heap - Binary tree\nHEAP = [1, 5, 3, 4, 2, 8, 7, 9]\nheapq.heapify(HEAP)\nprint(\"\\nHeap structure: <HEAP NAME> = [<ELEMENTS...>]; heapq.heapify(<HEAP NAME>)\")\nprint(f\"HEAP = [1, 5, 3, 4, 2, 8, 7, 9]; heapq.heapify(HEAP) --> HEAP = {HEAP}\")\n\n# Stacks and Queues\nSTACK = deque([20, 21, 22])\nprint(\"\\nStack structure: <STACK NAME> = deque([<ELEMENTS...>])\")\nprint(f\"STACK = deque([20, 21, 22]) --> STACK = {STACK}\")\n\n\nprint(\n    \"\\n# ---------------------------------------------------------------------------------- #\"\n)\n\n\"\"\"\n    Insert, delete, update, and sort operations\n\"\"\"\n\nMY_LIST = [1, 2, 3]\n\nMY_TUPLE = (1, 2, 3)\n\nMY_SET = {\"first\", \"second\", \"third\"}\n\nMY_DICTIONARY = {\n    \"first_name\": \"Lucas\",\n    \"last_name\": \"Hoz\",\n}\n\n\n# Insert an element at the end of a List structure\nMY_LIST.append(4)\nprint(\n    \"\\nInsert an element at the end of a List structure: <LIST NAME>.append(<ELEMENT>)\"\n)\nprint(f\"[1, 2, 3].append(4) --> MY_LIST = {MY_LIST}\")\n\n# Delete an element of a List structure\nMY_LIST.remove(2)\nprint(\n    \"\\nDelete an element of a List structure: <LIST NAME>.remove(<ELEMENT TO DELETE>)\"\n)\nprint(f\"[1, 2, 3, 4].remove(2) --> MY_LIST = {MY_LIST}\")\n\n# Update an element of a List structure\nMY_LIST[1] = 3 * 2\nprint(\n    \"\\nUpdate an element of a List structure: <LIST NAME>[<INDEX OF THE ELEMENT TO UPDATE>] = <NEW VALUE>\"\n)\nprint(f\"[1, 3, 4][1] = 3 * 2 --> MY_LIST = {MY_LIST}\")\n\n# Sort elements of a List structure\nMY_LIST.sort(reverse=True)\nprint(\"\\nSort elements of a List structure: <LIST NAME>.sort(<ARGUMENTS...>)\")\nprint(f\"[1, 6, 4].sort(reverse=True) --> MY_LIST = {MY_LIST}\")\n\n\n# Insert an element in a Set structure\nMY_SET.add(\"fourth\")\nprint(\"\\nInsert an element in a Set structure: <SET NAME>.add(<ELEMENT>)\")\nprint(\"{'first', 'second', 'third'}.add('fourth') --> MY_SET =\", MY_SET)\n\n# Delete an element of a Set structure\nMY_SET.discard(\"second\")\nprint(\"\\nDelete an element of a Set structure: <SET NAME>.add(<ELEMENT>)\")\nprint(\"{'first', 'second', 'third', 'fourth'}.discard('second') --> MY_SET =\", MY_SET)\n\n\n# Insert an property in a Dictionary structure\nMY_DICTIONARY[\"country\"] = \"Argentina\"\nprint(\n    \"\\nInsert an property in a Dictionary structure: <DICTIONARY NAME>[<KEY OF THE NEW PROPERTY>] = <VALUE OF THE NEW PROPERTY>\"\n)\nprint(\n    \"{ 'first_name': 'Lucas', 'last_name': 'Hoz' }['country'] = 'Argentina' --> MY_DICTIONARY =\",\n    MY_DICTIONARY,\n)\n\n# Delete a property of a Dictionary structure\nMY_DICTIONARY.pop(\"last_name\")\nprint(\n    \"\\nDelete a property of a Dictionary structure: <DICTIONARY NAME>.pop(<KEY OF THE PROPERTY TO DELETE>)\"\n)\nprint(\n    \"{ 'first_name': 'Lucas', 'last_name': 'Hoz', 'country': 'Argentina' }.pop('last_name') --> MY_DICTIONARY =\",\n    MY_DICTIONARY,\n)\n\n# Update a property of a Dictionary structure\nMY_DICTIONARY.update({\"first_name\": \"Nahuel\"})\nprint(\n    \"\\nUpdate a property of a Dictionary structure: <DICTIONARY NAME>.update({ <KEY OF THE PROPERTY TO UPDATE>: <NEW VALUE> })\"\n)\nprint(\n    \"{ 'first_name': 'Lucas', 'country': 'Argentina' }.update({ 'first_name': 'Nahuel' }) --> MY_DICTIONARY =\",\n    MY_DICTIONARY,\n)\n\n\nprint(\n    \"\\n# ---------------------------------------------------------------------------------- #\\n\"\n)\n\n\"\"\"\n    Additional challenge...\n\"\"\"\n\nCONTACTS: list[dict[str, str]] = []\n\n\ndef find_contact_index(name: str):\n    \"\"\"Find index of the contact using the name\"\"\"\n    i = 0\n    for contact in CONTACTS:\n        if contact[\"name\"].upper() == name.upper():\n            return i\n        i += 1\n\n    return -1\n\n\ndef get_contact_name(message: str, message_on_invalid: str, should_exist: bool):\n    \"\"\"Get contact name from an input\"\"\"\n    name = input(message)\n    if name == \"\":\n        return \"\"\n\n    while (\n        find_contact_index(name=name) == -1\n        if should_exist\n        else find_contact_index(name=name) != -1\n    ):\n        name = input(message_on_invalid)\n        if name == \"\":\n            break\n\n    return name\n\n\ndef get_contact_phone_number(message: str, message_on_invalid: str):\n    \"\"\"Get contact name from an input\"\"\"\n    phone_number = input(message)\n    if phone_number == \"\":\n        return \"\"\n\n    while not is_valid_phone_number(phone_number):\n        phone_number = input(message_on_invalid)\n        if phone_number == \"\":\n            break\n\n    return phone_number\n\n\ndef is_valid_phone_number(phone_number: str):\n    \"\"\"Check if phone number is a valid one\"\"\"\n    return len(phone_number) <= 11 and phone_number.isdigit()\n\n\nEXIT = False\n\nwhile not EXIT:\n    OPERATION = input(\n        \"Select an operation ('Show', 'Find', 'Insert', 'Update', 'Delete' or 'Exit'):\"\n    ).upper()\n\n    if OPERATION == \"SHOW\":\n        print(f\"Contacts: {CONTACTS}\")\n    elif OPERATION == \"FIND\":\n        NAME = get_contact_name(\n            message=\"Enter the name of the contact:\",\n            message_on_invalid=\"The contact doesn't exists! Enter another name:\",\n            should_exist=True,\n        )\n        if NAME == \"\":\n            continue\n\n        PHONE_NUMBER = CONTACTS[find_contact_index(name=NAME)][\"phone_number\"]\n        print(f\"Contact info: {NAME} / {PHONE_NUMBER}\")\n\n    elif OPERATION == \"INSERT\":\n        NAME = get_contact_name(\n            message=\"Enter the name of the new contact:\",\n            message_on_invalid=\"The contact already exists! Try with another name:\",\n            should_exist=False,\n        )\n        if NAME == \"\":\n            continue\n\n        PHONE_NUMBER = get_contact_phone_number(\n            message=\"Enter the phone number of new contact:\",\n            message_on_invalid=\"Invalid phone number! Enter a valid one:\",\n        )\n        if PHONE_NUMBER == \"\":\n            continue\n\n        CONTACTS.append({\"name\": NAME, \"phone_number\": PHONE_NUMBER})\n        print(\"Contact inserted!\")\n\n    elif OPERATION == \"UPDATE\":\n        NAME = get_contact_name(\n            message=\"Enter the name of the contact to update:\",\n            message_on_invalid=\"The contact doesn't exists! Enter another name:\",\n            should_exist=True,\n        )\n        if NAME == \"\":\n            continue\n\n        NEW_NAME = get_contact_name(\n            message=\"Enter the new name:\",\n            message_on_invalid=\"There is a contact with this name! Try another one:\",\n            should_exist=False,\n        )\n        if NEW_NAME == \"\":\n            continue\n\n        NEW_PHONE_NUMBER = get_contact_phone_number(\n            message=\"Enter the new phone number:\",\n            message_on_invalid=\"Invalid phone number! Enter a valid one:\",\n        )\n        if NEW_PHONE_NUMBER == \"\":\n            continue\n\n        CONTACTS[find_contact_index(name=NAME)] = {\n            \"name\": NEW_NAME,\n            \"phone_number\": NEW_NAME,\n        }\n        print(\"Contact updated!\")\n\n    elif OPERATION == \"DELETE\":\n        NAME = get_contact_name(\n            message=\"Enter the name of the contact to delete:\",\n            message_on_invalid=\"The contact doesn't exists! Enter another name:\",\n            should_exist=True,\n        )\n        if NAME == \"\":\n            continue\n\n        del CONTACTS[find_contact_index(name=NAME)]\n        print(\"Contact deleted!\")\n\n    elif OPERATION == \"EXIT\":\n        EXIT = True\n        print(\"Program finished!\")\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/iban99.py",
    "content": "#Listas\nmi_lista :list = [\"Miriam\", \"Iban\", 25, \"Futbol\"]\n\nmi_lista.append(\"Analista\") #Importante el orden de inserción \nprint(mi_lista)\n\nmi_lista.remove(25) #Borrado de elementos\nprint(mi_lista)\n\nmi_lista[1] = \"Gil\" #Actualización\nprint(mi_lista)\n\nmi_lista.sort()\nprint(mi_lista) #Ordenación\n\n#Tuplas\nmi_tupla :tuple = (\"Miriam\", \"Iban\", \"miban\", \"25\")\nprint(mi_tupla[1])\n\nmi_tupla = tuple(sorted(mi_tupla)) #El sorted cambia a lista una tupla\nprint(type(mi_tupla))\nprint(mi_tupla)\n\n\n#Diccionarios\nmi_dict : dict = {\n    \"name\": \"Miriam\", \n    \"apellido\": \"Iban\", \n    \"alias\":\"miban\", \n    \"edad\":\"25\"\n}\n\nprint(mi_dict[\"name\"]) #Acceso\nprint(type(mi_dict))\n\nmi_dict[\"email\"] = \"miriamiban@gmail.com\" #Inserción\nprint(mi_dict)\n\nmi_dict[\"edad\"] = \"26\" #Actualización\nprint(mi_dict)\n\ndel mi_dict[\"apellido\"] #Eliminar\nprint(mi_dict)\n\nmi_dict = dict(sorted(mi_dict.items())) #Ordenación\nprint(mi_dict)\n\n#Sets\nmi_set : set= {\"Miriam\", \"Iban\", \"miban\", \"25\"}\nprint(type(mi_set))\n\nmi_set.add(\"miriamiban@gmail.com\")\nprint(mi_set)\n#Estructura no ordenada, evita duplicados\n\nmi_set.remove(\"Miriam\") #Eliminar\nprint(mi_set)\n\nmi_set = set(sorted(mi_set)) #No se puede ordenar\n\n\n#Extra\ndef my_agenda():\n    \n    agenda :dict = {}\n    \n    def insertContact():\n        number = input(\"Introduce el número: \")\n        if number.isdigit() and len(number) > 0 and len(number) <=11:\n            agenda[name] = [number]\n        else:\n            print(\"Debes introducir un número correcto.\")\n    \n    while True:\n\n        print(\"1.Buscar contacto\")\n        print(\"2.Insertar contacto\")\n        print(\"3.Actualizar contacto\")\n        print(\"4.Borrar contacto\")\n        print(\"5.Salir\")\n        \n        option = input(\"\\n Selecciona una opción: \")\n        \n        match option:\n            case \"1\":\n                name = input(\"Introduce el nombre que quieres buscar: \")\n                if name in agenda:\n                    print(f\"El numero de teléfono de {name} es {agenda[name]}\")\n                else:\n                    print(f\"El contacto {name} no existe.\")\n            case \"2\":\n                name = input(\"Introduce el nombre: \")\n                insertContact()\n            case \"3\":\n                name = input(\"Introduce el nombrea actualizar: \")\n                if name in agenda:\n                    insertContact()\n                else:\n                    print(f\"El contacto {name} no existe.\")\n            case \"4\":\n                name = input(\"Introduce el nombrea eliminar: \")\n                if name in agenda:\n                    del agenda[name]\n                else:\n                    print(f\"El contacto {name} no existe.\") \n            case \"5\":\n                print(\"Saliendo de la agenda.\")\n                break\n            case _:\n                print(\"Opción no válida. Elige una opción del 1 al 5.\")\n\nmy_agenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/icedrek.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n *   y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n *   y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más\n *   de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.\n\"\"\"\n# LISTAS (list)\n# Lista de elementos, puede contener varios tipos. Ordenada, mutable y admite duplicados\nvariable_lista: list = [1, 2, \"3\"]\n\n# - Insercion\n#   - Insertar valor al final de la lista\nvariable_lista.append(4)\n#   - Insertar otra lista al final de la lista\nvariable_lista.extend([5, 6])\n#   - los dos anteriores se pueden hacer tambien asi:\nvariable_lista += [7]\n#   - Inserta valor(4) en el indice indicado(6)\nvariable_lista.insert(6, 4)\n\n# - Borrado\n#   - Borra el primer valor que coincida\nvariable_lista.remove(4)\n#   - Borra el valor que se encuentra en el indice indicado\ndel variable_lista[2]\n#   - Borra el valor que se encuentra en el indice indicado.\n#   - Si no se pone nada borra el último elemento\nvariable_lista.pop()\n\n# - Actualizacion\n#   - Se actualiza el indice(3) con el valor indicado(9)\nvariable_lista[3] = 9\n\n# - Ordenacion\nvariable_lista.sort()  # Orden ascendente\nvariable_lista.sort(reverse=True)  # Orden descendente\n\n# CONJUNTOS (set)\n# Lista de elementos, puede contener varios tipos. Desordenada, inmutable y no admite duplicados\nvariable_set: set = {1, 3, 5}\nvariable_set2 = {6, 7}\nvariable_set3 = {2, 4}\n\n# - Insercion\n#   - Insertar un valor\nvariable_set.add(4)\n#   - Insertar varios valores\nvariable_set.update([9, 8, 7])\nvariable_set.union(variable_set3)\n#   - insertar un conjunto(set) a otro conjunto(set)\nvariable_set |= variable_set2\n\n# - Borrado\n#   - Elimina el valor especificado\nvariable_set.remove(3)\nvariable_set.discard(8)\n#   - Elimina un valor aleatorio\nvariable_set.pop()\n#   - Eliminar valores que existan en otro conjunto\nvariable_set -= variable_set2\nvariable_set = variable_set.difference(variable_set3)\n#   - Elimina todos los valores del conjunto\nvariable_set.clear()\n# - Actualizacion - No se hace\n# - Ordenacion - No se hace\n\n\n# TUPLAS (tuple)\n# Lista de elementos, puede contener varios tipos. Ordenada, inmutable y admite duplicados\nvariable_tupla: tuple = (1, \"2\", 3)\n\n# - Insercion\n#   - Insertar valores al final de la tupla\nvariable_tupla += (4, 5, 6)\n#   - Insertar valores en un lugar concreto de la tupla\nvariable_tupla = variable_tupla[:2] + (11,) + variable_tupla[2:]\n\n# - Borrado\n#   - Eliminar un elemento segun el indice\nvariable_tupla = variable_tupla[:4] + variable_tupla[4 + 1:]\n\n# - Actualizacion\n#   - Actualiza un elemento segun indice\nvariable_tupla = variable_tupla[:2] + (9,) + variable_tupla[2 + 1:]\n\n#   - Ordenacion. No se hace\n\n\n# DICCIONARIOS(dictionary)\n# lista de clave:valor. Ordenada, mutable y no admite duplicados\nvariable_diccionario: dict = {\"letra1\": \"a\", \"letra2\": \"b\", \"letra3\": \"c\"}\nvariable_diccionario2 = dict([(\"numero1\", 1), (\"numero2\", 2)])\nvariable_diccionario3 = dict(letra1=\"z\", letra4=\"d\", letra5=\"e\")\n\n# - Insercion\n#   - Inserta un elemento en el diccionario\nvariable_diccionario[\"letra6\"] = \"f\"\n# - Borrado\n#   - Borra el par asociado a la clave indicada\nvariable_diccionario2.pop(\"numero1\")\n#   - Borra un par aleatorio\nvariable_diccionario3.popitem()\n#   - Borra todos los elementos\nvariable_diccionario2.clear()\n# - Actualizacion\n#   - Actualiza un valor existente\nvariable_diccionario[\"letra1\"] = \"h\"\n#   - Actualiza los valores que existen en el primer diccionario con los valores del segundo.\n#   - Si alguno de los valores del segundo no esta en el primere, se añaden\nvariable_diccionario.update(variable_diccionario3)\n\n# - Ordenacion\nvariable_diccionario = dict(sorted(variable_diccionario.items()))\n\n# NOTA: Se puede obtener una lista de todas las claves con .keys() y de todos los valores con .values()\n\n\n# EJERCICIO EXTRA\nimport os\nimport time\n\ndb_contacts: dict = {}\n\n\ndef contacts():\n    while True:\n        time.sleep(1.5)\n\n        option = main_menu()\n\n        if option == 0:\n            continue\n        elif option == 1:\n            insert_contact()\n        elif option == 2:\n            select_contact()\n        elif option == 3:\n            update_contact()\n        elif option == 4:\n            delete_contact()\n        elif option == 5:\n            select_all_contacts()\n        else:\n            break\n\n\ndef clear_screen():\n    os.system(\"cls\" if os.name == \"nt\" else \"clear\")\n\n\ndef main_menu():\n    clear_screen()\n\n    print(\"1-Añadir contacto\")\n    print(\"2-Consultar contacto\")\n    print(\"3-Modificar contacto\")\n    print(\"4-Borrar contacto\")\n    print(\"5-Listar todos los contactos\")\n    print(\"6-Salir\\n\")\n\n    option = validate_option(input(\"Selecciona una opción: \"))\n\n    return option\n\n\ndef validate_option(option):\n    if option.isnumeric():\n        if int(option) in range(1, 7):\n            return int(option)\n        else:\n            print(\"introduce una opcion del 1 al 6\")\n    else:\n        print(\"El valor introducido no es numérico\")\n\n    return 0\n\n\ndef insert_contact():\n    contact_name = input(\"Introduce nombre del contacto: \")\n    contact_phone = validate_phone(input(\"Introduce telefono del contacto: \"))\n\n    if contact_name in db_contacts:\n        print(\"El contacto ya existe en la agenda\")\n        return\n\n    if contact_phone != 0:\n        db_contacts[contact_name] = contact_phone\n        print(f\"Contacto añadido: {contact_name} - {contact_phone}\")\n\n\ndef select_contact():\n    contact_name = input(\"Introduce nombre del contacto: \")\n    if contact_name not in db_contacts:\n        print(\"No se ha encontrado el contacto\")\n        return\n\n    contact_phone = db_contacts[contact_name]\n    print(f\"Contacto: {contact_name} - Telefono: {contact_phone}\")\n    time.sleep(1.5)\n\n\ndef update_contact():\n    contact_name = input(\"Introduce nombre del contacto a modificar: \")\n    contact_new_phone = input(\"Introduce nuevo telefono del contacto: \")\n\n    contact_old_phone = db_contacts[contact_name]\n\n    if contact_old_phone == contact_new_phone:\n        print(\"Telefono antiguo y nuevo son el mismo, no se actualiza\")\n        return\n\n    db_contacts[contact_name] = contact_new_phone\n    print(\"Contacto modificado\")\n\n\ndef delete_contact():\n    contact_name = input(\"Introduce nombre del contacto a eliminar: \")\n\n    if contact_name not in db_contacts:\n        print(\"El contacto no existe en la agenda\")\n        return\n\n    db_contacts.pop(contact_name)\n    print(\"Contacto borrado\")\n\n\ndef select_all_contacts():\n    db_contacts_sorted = dict(sorted(db_contacts.items()))\n\n    for contact in db_contacts_sorted:\n        print(f\"Contacto: {contact} - Telefono: {db_contacts[contact]}\")\n\n    time.sleep(3)\n\n\ndef validate_phone(contact_phone):\n    if contact_phone.isnumeric():\n        return int(contact_phone)\n    else:\n        print(\"Debes introducir un número válido\")\n\n    if len(contact_phone) == 9:\n        print(\"El numero debe tener 9 dígitos\")\n\n    return 0\n\n\ncontacts()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/idiegorojas.py",
    "content": "\"\"\"\nListas\nSon colecciones ordenadas y mutables de elementos\n\"\"\"\n\n# Creacion de listas\nmi_lista = [1,2,3,4,5]\n\n# Inserccion\nmi_lista.append(5) # Inserta el numero 5 al final de la lista\nmi_lista.insert(2, 2.5) # Inserta el numero 2.5 en la posicion 2\n\n# Borrado\nmi_lista.remove(2.5) # Elimina el primer elemento con valor 2.5\ndel mi_lista[0] # Elimina el elemento en la posicion numero 0\n\n# Actualizacion\nmi_lista[1] = 10 # Actualiza el elemento en la posicion 1 a 10\n\n# Ordenacion\nmi_lista.sort() # Ordena la lista de forma ascendente\nmi_lista.sort(reverse=True) # Ordena la lista de forma descendente\n\nprint(mi_lista)\n\n\n\"\"\"\nTuplas\nSon colecciones ordenadas e inmutables de elementos\nPara modificar una tupla, se debe crear una nueva\n\"\"\"\n\n# Creacion\nmi_tupla = (1,2,3,4,5)\n\n# Ordenacion\nlista_ordenada = sorted(mi_tupla)\nmi_tupla_ordenada = tuple(lista_ordenada)\nprint(mi_tupla_ordenada)\n\n\n\"\"\"\nConjuntos\nSon colecciones no ordenadas y mutables de elementos unicos\n\"\"\"\n\n# Creacion\nmi_conjunto = {1,2,3,4,5}\n\n# Inserccion\nmi_conjunto.add(6) # Añade un elemento al conjunto\n\n# Borrado\nmi_conjunto.remove(2) # Elimina el elemento 2 del conjunto\nmi_conjunto.discard(3) # Elimina el elemnto 3 si esta presente\n\n# Actualizacion\n# Los conjuntos no poseen index por lo cual para actualizar un elemento, primero se debe eliminar y luego añadir el nuvo elemento\n\n# Ordenacion\nlista_ordenada = sorted(mi_conjunto) # Ordena el conjunto y devuelve una lista\nprint(mi_conjunto)\n\n\n\"\"\"\nDiccionarios\nSon colecciones no ordenadas de pares clave - valor\n\"\"\"\n\n# Creacion\nmi_diccionario = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}\n\n# Inserccion \nmi_diccionario['f'] = 6 # Añade un nuevo par clave -valor\n\n# Borrado\ndel mi_diccionario['b'] # Elimina el par con la clave 'b'\nmi_diccionario.pop('a') # Elimina y devuelve el valor asociado con la clave 'a'\n\n# Actualizacion\nmi_diccionario['c'] = 30 # Actualiza el valor asociado a la clave 'c' por 30\n\n# Ordenacion\n# Los diccionarios no tienen un orden, pero se puede ordenar por clave o valor\ndict_ordenado_por_clave = dict(sorted(mi_diccionario.items()))\ndict_ordenado_por_valor = dict(sorted(mi_diccionario.items(), key=lambda item: item[1]))\n\nprint(dict_ordenado_por_clave)\nprint(dict_ordenado_por_valor)\n\n\n\"\"\"\nExtra\n\"\"\"\n\ndef agenda_contactos():\n\n    agenda = {}\n\n    def insertar():\n        nombre = input('Por favor ingrese el nombre del contacto: ')\n        while True:\n            numero = input('Por favor ingresa el numero del contacto:')\n            if numero.isdigit() and 5 <= len(numero) <= 11:\n                agenda[nombre] = numero\n                print(f'Contacto {nombre} agregado correctamente.')\n                break\n            else:\n                print('Numero de contacto invalido. Debe tener entre 5 a 11 Digitos.')\n\n    def eliminar():\n        nombre = input('Por favor ingrese el nombre del contacto que desea eliminar: ')\n        if nombre in agenda:\n            del agenda[nombre]\n            print(f'Contacto {nombre} eliminado correctamente.')\n        else:\n            print(f'Contacto {nombre} no encontrado.')\n\n    def actualizar():\n        nombre = input('Por favor ingresa el nombre del contacto que deseas actualizar: ')\n        if nombre in agenda:\n            print(f\"\"\"Seleccione una de las siguientes opciones:\n                a. Actualizar nombre de contacto\n                b. Actualizar numero de contacto\"\"\")\n            actualizacion = input('Inserte la opcion a elegir: ')\n            if actualizacion == 'a':\n                nuevo_nombre = input('Por favor ingrese el nuevo nombre de contacto: ')\n                agenda[nuevo_nombre] = agenda.pop(nombre)\n            elif actualizacion == 'b':\n                nuevo_numero = input('Por favor ingrese el nuevo numero de contacto: ')\n                agenda[nombre] = nuevo_numero\n        else:\n            print(f'Contacto {nombre} no encontrado.')\n\n    def buscar():\n        nombre = input('Por favor ingrese el nombre del contacto que desea buscar: ')\n        if nombre in agenda:\n            print(f'El numero de {nombre} es {agenda[nombre]}.')\n        else:\n            print(f'El contacto {nombre} no encontrado.')\n    \n    while True:\n        print('Bienvenido a tu agenda')\n        print(f\"\"\"Que operacion deseas realizar: \n            a. Inserta contacto\n            b. Eliminar contacto\n            c. Actualizar contacto\n            d. Buscar contacto\n            e. Salir\n            \"\"\")\n        \n        opcion_usuario = input('Por favor ingresa la opcion a seleccionar: ')\n\n        if opcion_usuario == 'a':\n            insertar()\n        elif opcion_usuario == 'b':\n            eliminar()\n        elif opcion_usuario == 'c':\n            actualizar()\n        elif opcion_usuario == 'd':\n            buscar()\n        elif opcion_usuario == 'e':\n            print('Saliendo de la agenda...')\n            break\n        else:\n            print('Opcion no valida, por favor intenta de nuevo.')\n\nagenda_contactos()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/ignaciovihe.py",
    "content": "\"\"\"\nEstructuras de datos\n\"\"\"\n\n\"\"\"\nMuestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n\"\"\"\n\n#Listas - Creación - Estructura mutable - ordenable - indexable\n\nmy_list = list()\nmy_second_list = []\nprint(type(my_list))\nprint(type(my_second_list))\n\nmy_list = list((1,\"dos\", 3, \"cuatro\")) # de esta forma hay que pasarle un iterable\nprint(my_list)\n\nmy_list = [1,\"dos\", 3, \"cuatro\"] # De esta forma se le pueden pasar los elementos directamente\nprint(my_list)\n\n# Tupla - Creación - Estructura inmutable - ordenable - indexable\n\nmy_tuple = tuple()\nmy_second_tuple = ()\nprint(type(my_tuple))\nprint(type(my_second_tuple))\n\nmy_tuple = tuple(my_list) #de esta forma hay que pasarle un iterable\nprint(my_tuple)\n\nmy_list = (1,\"dos\", 3, \"cuatro\")\nprint(my_tuple)\n\n# Set - Creación - Estructura mutable - no permite duplicados - no ordenable - no indexable\n\nmy_set = set()\nmy_second_set = {} #No se puede crear un set vacio de esta forma ya que se crea un diccionario.\nmy_third_set ={1} # Si se le añade un valor ya se considera un set.\nprint(type(my_set))\nprint(type(my_second_set)) \nprint(type(my_third_set)) \n\nmy_set = set((1,\"dos\", 3, \"cuatro\", 3, \"dos\", 5)) # al crear un set no se repiten los duplicados. Necesita iterable.\nprint(my_set)\n\nmy_set = {1, 2, 3, 4, 3, 2, 1}\nprint(my_set)\n\n#Diccionario - Creación - Estructura mutable - no claves duplicadas - mantiene el orden - indexable (clave-valor)\n\nmy_dict = dict()\nmy_second_dict = {}\nprint(type(my_dict))\nprint(type(my_dict))\n\nmy_dict = dict(nombre=\"Ana\", edad=25, ciudad=\"Madrid\")\nprint(my_dict)\n\nmy_dict = {\"nombre\": \"Ana\", \"edad\": 25, \"ciudad\": \"Madrid\"}\nprint(my_dict)\n\nlist_of_tuples = [(\"nombre\", \"Ana\"), (\"edad\", 25), (\"ciudad\", \"Madrid\")]\nmy_dict = dict(list_of_tuples)\nprint(my_dict)\n\nkeys = [\"nombre\", \"edad\", \"ciudad\"]\nmy_dict = dict.fromkeys(keys, \"Desconocido\")\nprint(my_dict)\n\nkeys = [\"nombre\", \"edad\", \"ciudad\"]\nvalues = [\"Ana\", 25, \"Madrid\"]\nmy_dict = dict(zip(keys, values))\nprint(my_dict)\n\n\n\n\"\"\"\nUtiliza operaciones de inserción, borrado, actualización y ordenación.\n\"\"\"\nprint(\"----------# Listas - Inserción-----------\")\n\n# Listas - Inserción\nmy_list = [1, 'dos', 3, 'cuatro']\nmy_other_list = [\"seis\", 7]\n\nmy_list.append(\"cinco\") # Inserta un elemento al final\nprint(my_list)\n\nmy_list.insert(3, 3.5) # Inserta un elemento en un indice especifico\nprint(my_list)\n\nmy_list.extend(my_other_list) # Extiende la lista con los elementos de otro iterable\nprint(my_list)\n\nmy_list += (8,\"nueve\") #Otra forma de extender una lista\nprint(my_list)\n\nmy_list[5:5] = [4.5, 4.75] # Se insertan elementos en una posición especifica. \nprint(my_list) #my_list[5,6] = [4.5, 4.75] --> Se perderia un elemento\n\nprint(\"----------# Listas - borrado-----------\")\n\n# Listas - Borrado\nelement = my_list.pop() #Saca el ultimo elemento de la lista y lo devuelve. Sin parametro.\nprint(element)\nprint(my_list)\n\nelement = my_list.pop(3)#Con índice saca el elemento marcado y lo devuelve\nprint(element)\nprint(my_list)\n\nmy_list.remove(4.75)# Eliminar por valor, si no esta devuelve ValueError\nprint(my_list)\n\ndel my_list[4] #Elimina un elemento por indice\nprint(my_list)\n\ndel my_list[0:2] # Elimina un rango de elementos\nprint(my_list)\n\nmy_list.clear() # Vacia la lista\nprint(my_list)\n\ndel my_list#Elimina toda la lista. Ya no podremos referirnos a ella.\n#print(my_list)\n\nprint(\"----------# Listas - Actualización-----------\")\n\n# Listas - Actualización\nmy_list = [1, 2, \"tres\", 4, 5]\nprint(my_list)\n\nmy_list[2] = 3 # Modifica por indice\nprint(my_list)\n\nmy_list[1:3] = [20, 30] # Modifica varios elementos con slicing\nprint(my_list)\n\nprint(\"----------# Listas - Ordenación-----------\")\n\n# Listas - Ordenación\nmy_list = [5, 2, 9, 1, 7]\nprint(my_list)\nmy_list.sort()  # Ordena de menor a mayor (orden ascendente)\nprint(my_list)\n\nmy_list = [5, 2, 9, 1, 7]\nprint(my_list)\nmy_list.sort(reverse=True)  # Ordena de mayor a menor (orden descendente)\nprint(my_list)\n\nmy_list = [5, 2, 9, 1, 7]\nnew_list = sorted(my_list)  # Crea una nueva lista ordenada\nprint(new_list)  \nprint(my_list)\n\n\n\n# Tuplas - Las tuplas son inmutables, no se puede insertar, modificar ni eliminar elementos tras crearlas.\n\n\nprint(\"----------# Sets - Inserción-----------\")\n# Set - Insercción\n\nmy_set = {1, 2, 3, 4}\nmy_set.add(5) # inserta un elemento\nprint(my_set)\nmy_set.add(2) # si insertas repetido no hará nada, al no permitir repetidos.\nprint(my_set)\nmy_set.update([6, 4, 7])# Actualiza el set con otro iterable\nprint(my_set)\n\nprint(\"----------# Sets - Borrado-----------\")\n# Set - Borrado\n\nmy_set.remove(3)  # Elimina el valor 3 del set. Si no esta genera KeyError.\nprint(my_set)\n\nmy_set.discard(7)  # Elimina el valor 2 del set pero no lanza error si no esta.\nprint(my_set)\n\nmy_set.discard(7)  # No hace nada si el valor no está en el set\nprint(my_set)\n\nmy_set = {1, 2, 3, 4}\nremoved_element = my_set.pop()  # Elimina un elemento aleatorio\nprint(my_set)  \n# Puede imprimir algo como {2, 3, 4} (pero el orden es indeterminado)\nprint(removed_element)\n\nmy_set.clear()  # Elimina todos los elementos del set\nprint(my_set)\n\n# No se pueden actualizar valores ni ordenar el set, ya que son colecciones no ordenadas.\nprint(\"----------# Sets - Ordenación-----------\")\nmy_set = {\"Pedro\", \"Ana\", \"Ignacio\"}\nprint(my_set)\nmy_set = sorted(my_set) #Al ordenar un set lo convierte en una lista.\nprint(type(my_set))\n\nprint(\"----------# Diccionarios - Inserción - Actualización-----------\")\n# Diccionarios - Insercción - Actualización\n\n\nmy_dict = {'a': 1, 'b': 2, 'c': 3}\nmy_dict['d'] = 4 # Insertamos una nueva clave 'd' con su valor\nprint(my_dict)\nmy_dict['d'] = \"cuatro\" # Si ya exixte la clave, se actualiza su valor\nprint(my_dict)\n\nmy_dict.update({'b': 25, 'e': 50})  # Actualiza 'b' y agrega 'e'.Varios elementos de una.\nprint(my_dict)\n\nprint(\"----------# Diccionarios - Borrado-----------\")\n# Diccionarios - Borrado\n\nmy_dict = {'a': 1, 'b': 2, 'c': 3, 'd': 4}\nprint(my_dict)\ndel my_dict['b'] # Borrar la clave 'b'\nprint(my_dict)\n\nremoved_value = my_dict.pop('c') # Elimina la clave 'c' y obtiene su valor.\nprint(my_dict)\nprint(\"Valor removido:\", removed_value)\n\nremoved_item = my_dict.popitem() # Elimina el ultimo item y obtiene el item.\nprint(my_dict)\nprint(\"Elemento removido:\", removed_item)\n\nmy_dict.clear() # Vacia el diccionario\nprint(my_dict)\n\nprint(\"----------# Diccionarios - Ordenado-----------\")\n# Diccionarios - Ordenado. Normalmente son estructuras no ordenadas, pero se pueden ordenadar por clave o valor.\n\nmy_dict = {'a': 3, 'b': 1, 'c': 2}\nsorted_by_keys = dict(sorted(my_dict.items())) # Ordenar por claves (alfabéticamente)\nprint(sorted_by_keys)\n\nsorted_by_values = dict(sorted(my_dict.items(), key=lambda item: item[1])) # Ordenar por valores\nprint(sorted_by_values)\n\n# Ordenar por valores de manera descendente\nsorted_descending = dict(sorted(my_dict.items(), key=lambda item: item[1], reverse=True))\nprint(sorted_descending)\n\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\nCrea una agenda de contactos por terminal.\n- Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n- Cada contacto debe tener un nombre y un número de teléfono.\n- El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n  los datos necesarios para llevarla a cabo.\n- El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n  (o el número de dígitos que quieras)\n- También se debe proponer una operación de finalización del programa.\n\"\"\"\n\ndef agenda():\n    \n    def search(contact_data):\n        if contact_data.isnumeric():\n            number_ok = validate_number(contact_data)\n            if number_ok:\n                reverse_contacts = {v: k for k, v in contacts.items()}\n                if contact_data in reverse_contacts.keys():\n                    print(f\"Nombre: {reverse_contacts[contact_data]} - Telefono: {contact_data}\")\n                    return [reverse_contacts[contact_data], contact_data]\n                else:\n                    print(\" Contacto no encontrado.\")\n                    return None\n        else:\n            if contact_data in contacts.keys():\n                print(f\"Nombre: {contact_data} - Telefono: {contacts[contact_data]}\")\n                return [contact_data , contacts[contact_data]]\n            else:\n                print(\" Contacto no encontrado.\")\n                return None      \n\n    def insert(contact_name):\n        data_ok = False\n        while not data_ok:\n            \n            telefon = input(\"Introduce el telefono: \")\n            data_ok = validate_number(telefon)\n            if data_ok:\n                contacts[name] = telefon\n                print(\"Contacto insertado\")\n            else:\n                continue\n\n    def modify(contact_name):\n        result = search(contact_name)\n        if result:\n            print(\"Qué quieres modificar: \")\n            print(\"1. Nombre\")\n            print(\"2. Telefono\")\n            while True:    \n                modify_option = input(\"Introduce opción: \")\n                match modify_option:\n                    case \"1\":\n                        delete(contact_name)\n                        new_contact_name = input(\"Introduce el nuevo nombre: \")\n                        contacts[new_contact_name] = result[1]\n                        break\n                    case \"2\":\n                        insert(contact_name)\n                        break\n                    case _ :\n                        print(\"Opción incorrecta.\")\n        else:\n            print(\"Contacto no encontrado\")\n\n    def delete(contact_name):\n        if contact_name in contacts.keys():\n            del contacts[contact_name]\n        else:\n            print(\"Contacto no encontrado.\")\n\n\n    def validate_number(number:str) -> bool:\n        if number.isnumeric() and len(number) <= 11:\n            return True\n        else:\n            print(\"El número debe ser númerico y tener como máximo 11 digitos\")\n            return False\n\n\n    ended = False\n    contacts = {}\n    while not ended:\n        print(contacts)\n        print(\"Operaciones\")\n        print(\"\")\n        print(\"1. Buscar\")\n        print(\"2. Insertar\")\n        print(\"3. Modificar\")\n        print(\"4. Borrar\")\n        print(\"5. Cerrar\")\n        print(\"\")\n\n        operation = input(\"Introduce operacion: \")\n        match operation:\n            case \"1\":\n                data = input(\"Introduce un dato para buscar: \")\n                search(data)\n            case \"2\":\n                name = input(\"Introduce el nombre: \")\n                insert(name)\n            case \"3\":\n                name = input(\"Introduce el nombre a modificar: \")\n                modify(name)\n            case \"4\":\n                name = input(\"Introduce un nombre para borrar: \")\n                delete(name)\n            case \"5\":\n                ended = True\n            case _ :\n                print(\"Opcion incorrecta\")\n                continue\n\n\nagenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/inmortalnight.py",
    "content": "# 03 - Python\n\n# Estructuras de datos y operaciones básicas\n\n# List - conjunto de elementos\nlist = [1, 2, 3, 4, 5]\nlist.append(6) # Operación de inserción\nlist.insert(0, 0) # Operación de inserción\nlist.remove(6) # Operación de borrado\nlist[0] = 0 # Operación de actualización\nlist.sort() # Operación de ordenación\nlist.reverse() # Operación de ordenación inversa\n\n# Turple - conjunto inmutable de elementos, sin operaciones\ntuple = (1, 2, 3, 4, 5)\nsorted(tuple) # Operación de ordenación\n\n# Set - conjunto único de elementos, sin duplicados\nset_element = {1, 2, 3, 4, 5}\nset_element.add(6) # Operación de inserción\nset_element.discard(6) # Operación de borrado\n\n# Dictionary - conjunto de elementos tipo key,value\ndictionary = {\"one\": 1, \"two\": 2, \"three\": 3}\ndictionary[\"four\"] = 4 # Operación de inserción\ndictionary.pop(\"four\") # Operación de borrado\ndictionary[\"one\"] = 0 # Operación de actualización\ndictionary.update({\"five\": 5}) # Operación de actualización\n\nfrom collections import deque\n\n# Heap - Binary Tree\nheap = [1, 5, 3, 4, 2, 8, 7, 9]\n\n# Stacks and queues\nstack = deque([1, 2, 3, 4, 5])\n\n\n\n# EXTRA: Agenda de contactos\n\n# Crear contacto; dictionary con nombre y número de teléfono\ncontactos = {}\n# Menú de opciones\nrun = True\nwhile run:\n    print(\"*** Agenda de contactos ***\")\n    print(\"Elija una opción:\")\n    print(\"1. Buscar contacto\")\n    print(\"2. Insertar contacto\")\n    print(\"3. Actualizar contacto\")\n    print(\"4. Eliminar contacto\")\n    print(\"5. Salir\")\n    try:\n        opcion = int(input())\n        if opcion == 1:\n            nombre = input(\"Ingrese el nombre del contacto: \")\n            if nombre in contactos:\n                print(f\"{nombre}: {contactos[nombre]}\")\n            else:\n                print(\"Contacto no encontrado.\")\n        elif opcion == 2:\n            nombre = input(\"Ingrese el nombre del contacto: \")\n            telefono = input(\"Ingrese el número de teléfono: \")\n            if telefono.isdigit() and len(telefono) <= 11:\n                contactos[nombre] = int(telefono)\n                print(\"Contacto agregado.\")\n            else:\n                print(\"Número de teléfono inválido.\")\n        elif opcion == 3:\n            nombre = input(\"Ingrese el nombre del contacto: \")\n            if nombre in contactos:\n                telefono = input(\"Ingrese el nuevo número de teléfono: \")\n                if telefono.isdigit() and len(telefono) <= 11:\n                    contactos[nombre] = int(telefono)\n                    print(\"Contacto actualizado.\")\n                else:\n                    print(\"Número de teléfono inválido.\")\n            else:\n                print(\"Contacto no encontrado.\")\n        elif opcion == 4:\n            nombre = input(\"Ingrese el nombre del contacto: \")\n            if nombre in contactos:\n                del contactos[nombre]\n                print(\"Contacto eliminado.\")\n            else:\n                print(\"Contacto no encontrado.\")\n        elif opcion == 5:\n            print(\"Saliendo...\")\n            run = False\n        else:\n            print(\"Opción no válida.\")\n    except ValueError:\n        print(\"Por favor, ingrese un número válido.\")"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/ipfabio.py",
    "content": "\"\"\"\nEstructura de Datos\n\"\"\"\n\n# Listas\nmy_list: list = [\"Marcos\", \"Menelao\", \"Hercules\", \"Aquiles\"]\nprint(my_list)\nmy_list.append(\"Minos\")\nprint(f\"Agregamos Minos: {my_list}\")\nmy_list.remove(\"Aquiles\")\nprint(f\"Removemos Aquiles de la lista: {my_list}\")\nprint(f\"Primer elemento de la lista: {my_list[0]}\")\nmy_list[0] = \"Patroclo\"\nprint(f\"Actualizamos a Patrcolo en la primera posición: {my_list}\")\nmy_list.sort()\nprint(f\"Ordenamos la lista: {my_list}\")\n\n# Tuplas: Inmutable\nmy_tuple: tuple = (\"Marcos\", \"@Menelao\", \"Minos\", \"22\")\nprint(my_tuple[1]) # Acceso\nmy_tuple = tuple(sorted(my_tuple)) # Sorted devuelve una lista para alterar el orden. Volvemos a convertirla en inmutable tupla.\nprint(my_tuple)\nprint(type(my_tuple))\n\n# Sets: No guarda duplicados, desordenada\nmy_set: set = {\"Marcos\", \"Minos\", \"@Menelao\", \"22\"}\nprint(my_set)\nmy_set.add(\"Hercules\")\nprint(my_set)\nmy_set.remove(\"Minos\")\nprint(my_set)\nmy_set.update([\"Marcos\",\"Minos\"]) # Esto solo concatena datos.\n# La manera de actualizar datos, sería borrar el dato y agregar el nuevo\nmy_set = set(sorted(my_set)) # No se puede ordenar\nprint(type(my_set))\n\n# Diccionarios: \"Key\":\"Value\"\n\nmy_dict: dict = {\"name\":\"Marcos\",\"Aliado?\":\"Minos\",\"X\":\"@Menelao\",\"edad\":\"22\"}\nprint(my_dict)\nmy_dict[\"email\"] = \"Marcos&Menelao@gmail.com\" # Inserción\nmy_dict[\"edad\"] = \"33\" # Actualización\nprint(f\"Agregamos Email y actualizamos la edad: {my_dict}\")\ndel my_dict[\"Aliado?\"] # Eliminación\n# my_dict.pop(\"Aliado?\")\nprint(my_dict)\nprint(my_dict[\"name\"]) # Acceso\nmy_dict = dict(sorted(my_dict.items())) # Ordenación\nprint(my_dict)\nprint(type(my_dict))\n\n# Extra\n\ndef options():\n    print(\" ----- \")\n    print(\"1. Agregar contacto\")\n    print(\"2. Buscar contacto\")\n    print(\"3. Actualizar contacto\")\n    print(\"4. Mostrar Agenda\")\n    print(\"5. Eliminar contacto\")\n    print(\"6. Salir de Agenda\")\n    print(\"\\n\")\n\n\ndef corroborar_telefono(telefono):\n    return telefono.isdigit() and 0 <= len(telefono) <= 11\n\ndef pedir_nombre():\n     return input(\"Ingresa un nombre: \")\n\ndef pedir_telefono():\n    while True:\n        telefono = input(\"Ingresa un número de teléfono: \")\n        if corroborar_telefono(telefono):\n            return telefono\n        else:\n            print(\"Número de teléfono inválido. Debe ser números y hasta 11 dígitos.\")\n        \n\ndef agenda():\n\n    agenda:dict = {}\n\n\n    def agregar_contacto():\n        nombre = pedir_nombre()\n        telefono = pedir_telefono()\n        agenda[nombre] = telefono\n        print(f\"Contacto {nombre} agregado correctamente\")\n    \n    def buscar_contacto():\n        nombre = pedir_nombre()\n        if nombre in agenda:\n            print(f\"Contacto {nombre}, telefono {agenda[nombre]}\")\n        else:\n            print(f\"Contacto {nombre} no encontrado.\")\n\n    def actulizar_contacto():\n        nombre = pedir_nombre()\n        if nombre in agenda:\n            telefono = pedir_telefono()\n            agenda[nombre] = telefono\n            print(f\"Contacto {nombre} actualizado correctamente\")\n        else:\n            print(f\"Contacto {nombre} no encontrado\")\n\n    def mostrar_agenda():\n        if agenda:\n            print(agenda)\n        else:\n            print(\"No hay contactos\\nPrueba agregando uno.\")\n\n    def eliminar_contacto():\n        nombre = pedir_nombre()\n        if nombre in agenda:\n            del agenda[nombre]\n            print(f\"Contacto {nombre} eliminado.\")\n        else:\n            print(f\"Contacto {nombre} no encontrado\")\n    \n\n\n    while True:\n        options()\n        actions = input(\"Ingrese alguna de las opciones: \")\n        match actions:\n            case \"1\":\n                agregar_contacto()\n            case \"2\":\n                buscar_contacto()\n            case \"3\":\n                actulizar_contacto()\n            case \"4\":\n                mostrar_agenda()\n            case \"5\":\n                eliminar_contacto()\n            case \"6\":\n                print(\"Saliendo de Agenda...\")\n                break\n            case _:\n                print(f\"Opción {actions} no válida.\")\n\nif __name__ == '__main__':\n    agenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/isilanes.py",
    "content": "import json\n\n\nMAX_TLF_DIGITS = 11\n\n\ndef list_operations():\n    print(\"\\nOperaciones con LISTAS:\")\n    my_list = [1, 2]\n    print(f\"La lista inicial: my_list == {my_list}\")\n\n    my_list.append(3)\n    print(f\"La lista tras añadir un 3:\")\n    print(\"\"\"    my_list.append(3)\"\"\")\n    print(f\"    my_list == {my_list}\")\n\n    my_list.extend([4, 5])\n    print(f\"La lista tras añadir [4, 5]:\")\n    print(\"\"\"    my_list.extend([4, 5])\"\"\")\n    print(f\"    my_list == {my_list}\")\n\n    last = my_list.pop()\n    print(f\"La lista tras eliminar el último valor ({last}):\")\n    print(\"\"\"    last = my_list.pop()\"\"\")\n    print(f\"    my_list == {my_list}\")\n\n    my_list.remove(2)\n    print(f\"La lista tras eliminar el 2:\")\n    print(\"\"\"    my_list.remove(2)\"\"\")\n    print(f\"    my_list == {my_list}\")\n\n    my_list[2] = 0\n    print(f\"La lista tras actualizar su tercer valor:\")\n    print(\"\"\"    my_list[2] = 0\"\"\")\n    print(f\"    my_list == {my_list}\")\n\n    print(f\"La lista ordenada, sin modificar la original: {sorted(my_list)}\")\n    print(f\"Efectivamente, la lista sigue siendo {my_list}\")\n\n    my_list.sort(reverse=True)\n    print(f\"Ahora hemos ordenado la lista in-place, en order inverso:\")\n    print(\"\"\"    my_list.sort(reverse=True)\"\"\")\n    print(f\"    my_list == {my_list}\")\n\n\ndef tuple_operations():\n    print(\"\\nOperaciones con TUPLAS:\")\n    my_tuple = (1, 2)\n    print(f\"La tupla inicial: my_tuple == {my_tuple}\")\n\n    my_tuple = my_tuple + (3, 4, 5)\n    print(\"Las tuplas no se pueden modificar.\", end=\"\")\n    print(\" Para extenderla tendremos que crear una nueva tupla (que puede sobreescribir la original):\")\n    print(\"\"\"    my_tuple = my_tuple + (3, 4, 5)\"\"\")\n    print(f\"    my_tuple == {my_tuple}\")\n\n    print(\"Las tuplas, por tanto, no pueden tener valores añadidos, eliminados, o modificados.\")\n    print(f\"La tupla se puede ordenar sin modificar la original:\")\n    print(f\"    x = tuple(sorted(my_tuple, reverse=True))\")\n    print(f\"    x == {tuple(sorted(my_tuple, reverse=True))}\")\n    print(f\"Pero, lógicamente, no puede ordenarse in-place.\")\n\n\ndef set_operations():\n    print(\"\\nOperaciones con SETS:\")\n    my_set = {1, 2}\n    print(f\"El set inicial: my_set == {my_set}\")\n\n    print(\"En un set se puede insertar un valor:\")\n    my_set.add(3)\n    print(f\"    my_set.add(3)\")\n    print(f\"    my_set == {my_set}\")\n\n    print(\"Si añadimos un valor duplicado, no tendrá efecto:\")\n    my_set.add(2)\n    print(f\"    my_set.add(2)\")\n    print(f\"    my_set == {my_set}\")\n\n    print(\"Podemos unir dos sets, y obtendremos un tercer set que contendrá a ambos, pero sin duplicados:\")\n    other_set = {2, 3, 4}\n    third_set = my_set | other_set\n    print(\"    other_set = {2, 3, 4}\")\n    print(\"    third_set = my_set | other_set\")\n    print(f\"    third_set == {third_set}\")\n\n    print(\"Podemos eliminar elementos de un set mediante su valor:\")\n    my_set.remove(2)\n    print(\"    my_set.remove(2)\")\n    print(f\"    my_set == {my_set}\")\n\n    print(\"En cuanto a actualizar un set, hemos visto que podemos añadir o eliminar elementos.\")\n    print(\"Sin embargo, los sets son colecciones desordenadas. A diferencia de una lista, no tendría\")\n    print(\"sentido pedir a un set que se cambie el valor de su enésimo elemento. Adicionalmente, los\")\n    print(\"elementos de un set tienen que ser inmutables (aunque el set en sí es mutable).\")\n\n    print(\"Como hemos dicho, un set es una colección desordenada. No tiene sentido ordenar un set in-place.\")\n    print(\"Lo que sí podemos es pedir una representación ordenada del set (como con listas o tuples):\")\n    print(\"    x = tuple(sorted(my_set, reverse=True))\")\n    print(f\"    x == {tuple(sorted(my_set, reverse=True))}\")\n    print(\"Sin embargo:\")\n    print(\"    x = set(sorted(my_set, reverse=True))\")\n    print(f\"    x == {set(sorted(my_set, reverse=True))}\")\n\n\ndef dict_operations():\n    print(\"\\nOperaciones con DICCIONARIOS:\")\n    my_dict = {\"a\": 1, \"b\": 2}\n    print(f\"El diccionario original: my_dict == {my_dict}\")\n\n    my_dict[\"c\"] = 3\n    print(\"Podemos insertar valores en un diccionario accediendo a una clave que todavía no existía:\")\n    print(\"\"\"    my_dict[\"c\"] = 3\"\"\")\n    print(f\"    my_dict == {my_dict}\")\n\n    other_dict = {\"d\": 4, \"f\": 5}\n    my_dict.update(other_dict)\n    print(f\"También podemos insertar valores de un diccionario en otro:\")\n    print(\"\"\"    other_dict = {\"d\": 4, \"f\": 5}\"\"\")\n    print(\"\"\"    my_dict.update(other_dict)\"\"\")\n    print(f\"    my_dict == {my_dict}\")\n\n    del my_dict[\"b\"]\n    print(f\"Podemos eliminar un par clave/valor del dicionario usando la clave:\")\n    print(\"\"\"    del my_dict[\"b\"]\"\"\")\n    print(f\"    my_dict == {my_dict}\")\n\n    my_dict[\"a\"] = 11\n    print(f\"Si la clave ya existe, en vez de insertar, lo que hacemos es actualizar el valor:\")\n    print(\"\"\"    my_dict[\"a\"] = 11\"\"\")\n    print(f\"    my_dict == {my_dict}\")\n\n    other_dict = {\"c\": -1, \"d\": -2}\n    my_dict.update(other_dict)\n    print(\"Si insertamos valores de un diccionario en otro, y una o varias claves ya existen, serán actualizadas:\")\n    print(\"\"\"    other_dict = {\"c\": -1, \"d\": -2}\"\"\")\n    print(\"\"\"    my_dict.update(other_dict)\"\"\")\n    print(f\"    my_dict == {my_dict}\")\n\n    print(\"Un diccionario es una colección de elementos sin orden, por lo tanto no tiene sentido ordenarlo in-place.\")\n    print(\"Sin embargo si podemos generar una representación ordenada. Por ejemplo, por orden de clave inversa:\")\n    print(f\"    x = dict(sorted(my_dict.items(), reverse=True))\")\n    print(f\"    x == {dict(sorted(my_dict.items(), reverse=True))}\")\n\n    print(\"También podemos ordenar por valor (o cualquier función arbitraria que use claves y/o valores).\")\n    print(\"Por ejemplo, ordenemos numéricamente por valor:\")\n    print(f\"    x = dict(sorted(my_dict.items(), key=lambda e: e[1]))\")\n    print(f\"    x == {dict(sorted(my_dict.items(), key=lambda e: e[1]))}\")\n\n\ndef extra():\n    \"\"\"\n    Given the simplicity of the request, we could implement the contacts as a dict\n    where the key is the name, and the value is the telephone number. However, for\n    extensibility, we will implement a dictionary {id: contact}, where 'contact'\n    is a dict {\"name\": ..., \"phone\": ...}.\n    \"\"\"\n    contacts = {}\n\n    while True:\n        option = input(\"Escoge accion: [0] imprimir, [1] insertar, [2] buscar, [3] actualizar, [4] eliminar, [q] salir: \")\n\n        if option == \"q\":\n            break\n        elif option == \"0\":\n            print(json.dumps(contacts, indent=4))\n        elif option == \"1\":\n            contacts = insert_contact(contacts)\n        elif option == \"2\":\n            search_contacts(contacts)\n        elif option == \"3\":\n            contacts = update_contact(contacts)\n        elif option == \"4\":\n            contacts = delete_contact(contacts)\n        else:\n            print(\"Opción desconocida. Ignorando.\")\n\n\ndef insert_contact(contacts: dict) -> dict:\n    \"\"\"\n    Given current contacts 'contacts', insert a new contact and return updated contacts.\n\n    Args:\n        contacts (dict):\n            Current contact dict.\n\n    Returns:\n        A dictionary with updated contacts.\n    \"\"\"\n    name = input(\"Introduce el nombre del nuevo contacto: \")\n\n    if not name:\n        print(\"No introdujiste ningún nombre. Abortando inserción...\")\n        return contacts\n\n    if find_contacts(contacts, name=name):\n        res = input(f\"Un contacto llamado '{name}' ya existe. ¿Deseas añadir otro con el mismo nombre? [y/n]: \")\n        if res == \"y\":\n            print(\"De acuerdo, proseguimos...\")\n        else:\n            print(\"De acuerdo, abortamos inserción...\")\n            return contacts\n\n    phone = input(f\"Introduce el número de teléfono de '{name}': \")\n    while not is_valid_phone(phone):\n        phone = input(f\"Introdujiste un teléfono. Por favor, introduce un teléfono númerico y de hasta {MAX_TLF_DIGITS} dígitos: \")\n\n    new_id = get_new_id(contacts)\n    print(f\"Introduciendo contacto '{name}' con teléfono '{phone}' con ID = {new_id}\")\n\n    contacts[new_id] = {\n        \"name\": name,\n        \"phone\": int(phone),\n    }\n\n    return contacts\n\n\ndef update_contact(contacts: dict) -> dict:\n    \"\"\"\n    Given current contacts 'contacts', update an existing contact and return updated contacts.\n\n    Args:\n        contacts (dict):\n            Current contact dict.\n\n    Returns:\n        A dictionary with updated contacts.\n    \"\"\"\n    name, phone = prompt_for_search()\n\n    contact_ids = find_contacts(contacts, name=name, phone=phone)\n\n    if not contact_ids:\n        print(\"Lo sentimos, no hay ningún contacto con esos datos. Abortando actualización...\")\n        return contacts\n    elif len(contact_ids) > 1:\n        print(\"Parece que hay más de un contacto con esos datos:\")\n        for contact_id in contact_ids:\n            print(contacts[contact_id])\n        print(\"Por favor, repite la búsqueda con parámetros más estrictos.\")\n        return contacts\n\n    contact_id = contact_ids[0]\n    print(f\"Modificando el contacto {contacts[contact_id]}\")\n    name = input(f\"Introduce el nuevo nombre para el contacto con ID = {contact_id} (deja vacío para ignorar): \")\n    phone = input(f\"Introduce el nuevo teléfono para el contacto con ID = {contact_id} (deja vacío para ignorar): \")\n    phone = int(phone) if is_valid_phone(phone) else None\n\n    if not name and not phone:\n        print(\"No solicitaste ningún cambio. Abortanco actualización...\")\n        return contacts\n\n    if name:\n        contacts[contact_id][\"name\"] = name\n\n    if phone:\n        contacts[contact_id][\"phone\"] = phone\n\n    return contacts\n\n\ndef delete_contact(contacts: dict) -> dict:\n    \"\"\"\n    Given current contacts 'contacts', remove an existing contact and return updated contacts.\n\n    Args:\n        contacts (dict):\n            Current contact dict.\n\n    Returns:\n        A dictionary with updated contacts.\n    \"\"\"\n    name, phone = prompt_for_search()\n\n    contact_ids = find_contacts(contacts, name=name, phone=phone)\n\n    if not contact_ids:\n        print(\"Lo sentimos, no se encontró ningún contacto con esos parámetros. Abortando eliminación...\")\n        return contacts\n\n    print(f\"Encontrados {len(contact_ids)} contacto{'' if len(contact_ids) == 1 else 's'} con esos parámetros\")\n    for contact_id in contact_ids:\n        print(contacts[contact_id])\n    res = input(\"¿Estás seguro de querer borrarlos todos? [y/n]: \")\n\n    if res != \"y\":\n        print(\"Abortando eliminación...\")\n        return contacts\n\n    for contact_id in contact_ids:\n        print(f\"Eliminando contacto con ID = {contact_id}...\")\n        del contacts[contact_id]\n\n    return contacts\n\n\ndef prompt_for_search() -> tuple[str | None, int | None]:\n    name = input(\"Introduce el nombre del contacto a buscar (deja vacío para ignorar): \")\n    phone = input(\"Introduce el teléfono del contacto a buscar (deja vacío para ignorar): \")\n\n    name = name or None\n    phone = int(phone) if is_valid_phone(phone) else None\n\n    return name, phone\n\n\ndef is_valid_phone(phone: str) -> bool:\n    \"\"\"\n    Given a potential phone number 'phone', return True if it is a valid phone number.\n    Otherwise, return False.\n\n    Args:\n        phone (str):\n            Phone number to check.\n\n    Returns:\n        True if phone valid, False otherwise.\n    \"\"\"\n    try:\n        phone = int(phone)\n    except ValueError:\n        return False\n\n    if phone >= 10**MAX_TLF_DIGITS:\n        return False\n\n    return True\n\n\ndef search_contacts(contacts: dict) -> None:\n    \"\"\"\n    Given current contacts, ask the user for parameters to search by, and print out\n    the results of the search.\n\n    Args:\n        contacts (dict):\n            The contact directory to search.\n\n    Returns:\n        Nothing.\n    \"\"\"\n    name, phone = prompt_for_search()\n\n    for contact_id in find_contacts(contacts, name=name, phone=phone):\n        print(contacts[contact_id])\n\n\ndef get_new_id(contacts: dict) -> int:\n    \"\"\"\n    Given a contact directory 'contacts', find a free ID, in the form of the first\n    integer larger than the largest ID so far.\n    \"\"\"\n    if not contacts:\n        return 1\n\n    return sorted(contacts.keys())[-1] + 1\n\n\ndef find_contacts(contacts: dict, name: str | None = None, phone: int | None = None) -> list[int]:\n    \"\"\"\n    Given a contact directory 'contacts', find and return the IDs of the contact within it\n    matching the query parameters. If 'name' is provided, filter contacts by that name.\n    If tlf is given, filter contacts by that number.\n\n    Args:\n        contacts (dict):\n            Contact directory where the contacts will be searched.\n        name (optional str):\n            Filter contacts by that name.\n        phone (optional int):\n            Filter contacts by that number.\n\n    Returns:\n        List of IDs of contacts matching the filtering criteria.\n    \"\"\"\n    if not contacts:\n        return []\n\n    filtered_ids = []\n    for contact_id, contact in contacts.items():\n        if name is not None and contact[\"name\"] != name:\n            continue\n\n        if phone is not None and contact[\"phone\"] != phone:\n            continue\n\n        filtered_ids.append(contact_id)\n\n    return filtered_ids\n\n\ndef main():\n    list_operations()\n    tuple_operations()\n    set_operations()\n    dict_operations()\n\n\nif __name__ == \"__main__\":\n    main()\n    extra()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/ivangdev.py",
    "content": "# -------------------- Estructuras de datos -----------------\n# Coleccion ordenada, mutables, permiten duplicados\nlista = [1, 2, 3]\n# Coleccion ordenada, inmutables, permiten duplicados\ntupla = (1, 2, 3, 8, 5, 4)\n# Coleccion desordenada, sin duplicados\nconjuntos = {1, 2, 3, 3}\n# Pares clave:valor, mutables, no permiten claves repetidas\ndiccionario = {\n    1: {\"nombre\": \"Ivan\", \"edad\": 25},\n    2: {\"nombre\": \"Camilo\", \"edad\": 20},\n    3: {\"nombre\": \"vanessa\", \"edad\": 30},\n}\n\n\n# ------------------- Operaciones ---------------------------\n# ---------------------- Lista ------------------------------\n# Insercion\nlista.append(\"Hola\")  # Inserta al final de la lista\nlista.insert(0, \"Posicion 0\")  # Inserta en la posicion especifica\nlista.extend([2, 4])  # Agrega varios elemetnos de una vez\nprint(lista)\n\n# Borrado\nlista.remove(\"Hola\")  # Elimina la primera aparicion del valor pasado\nlista.pop()  # Elimina y retorna el elemento en el indice\n# lista.clear()  # Vacia la lista\nprint(lista)\n\n# Actualizacion\nlista[1] = \"Actualizacion\"\nprint(lista)\n\n# Ordenacion\nlista_2 = [\"a\", \"b\", \"c\", \"x\", \"y\", \"z\", \"e\"]\nlista_2.sort()  # Ordena la lista\nprint(lista_2)\nlista_2.sort(reverse=True)  # Orden descendente\nprint(lista_2)\nnueva_lista = sorted(lista_2)  # Nueva lista ordenada\n\nprint(nueva_lista)\n\n# ---------------------------------- Tupla ----------------------------\n# No permite insercion, borrado, actualizacion\n# Ordenacion\nnueva_tupla = sorted(tupla)\nprint(nueva_tupla)\n\n# -------------------- Conjuntos -------------------------------------\n# NO hay actualizacion\n# Insercion\nconjuntos.add(\"Hola\")  # Inserta al final del conjunto\nprint(conjuntos)\nconjuntos.update(\"A\", \"B\", \"C\")  # Agrega varios elementos\nprint(conjuntos)\n\n# Borrado\nconjuntos.remove(\"A\")  # Elimina un elemento si existe - error si no existe\nprint(conjuntos)\nconjuntos.discard(\"B\")  # Elimina un elemento si existe - no error\nprint(conjuntos)\nconjuntos.pop()  # Elimina y retorna un elemento arbitrario\nprint(conjuntos)\n# conjuntos.clear()  # Vacia el conjunto\n\n# Ordenacion\nconjunto_1 = {1, 2, 5, 3, 4}\nnuevo_conjunto = sorted(conjunto_1)\nprint(nuevo_conjunto)\n\n# ----------------------- Diccionarios ------------------------------\n# Inserccion\ndiccionario[\"nombre\"] = \"Raul\"  # Agrega o reemplaza\nprint(diccionario)\ndiccionario.update({\"nombre\": \"hernesto\"})  # Agregao o actualiza\nprint(diccionario)\n\n# Borrado\npop = diccionario.pop(\"nombre\")  # Elimina y devuelve el valor\nprint(pop)\npopitem = diccionario.popitem()  # Elimina y devuelve el ultimo valor\nprint(popitem)\ndel diccionario[1]  # Elimina par por clave\nprint(diccionario)\n# diccionario.clear()  # Vacia el diccionario\n\n# Actualizacion -> Igual que inserccion\n\n# Ordenacion no tiene directamente, se usa sorted\nnuevo_diccionario = sorted(diccionario)\nprint(nuevo_diccionario)\n\n\n# DIFICULTAD EXTRA (opcional):\n#  * Crea una agenda de contactos por terminal.\n#  * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n#  * - Cada contacto debe tener un nombre y un número de teléfono.\n#  * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n#  *   los datos necesarios para llevarla a cabo.\n#  * - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n#  *   (o el número de dígitos que quieras)\n#  * - También se debe proponer una operación de finalización del programa.\n#\n\nprint(\"------------------ Agenda de Contactos ----------------\")\nagendaContactos = {}\ncontador_id = 1\n\n\ndef busqueda():\n    valor = input(\"Que contacto busca: \")\n    for id, datos in agendaContactos.items():\n        if datos[\"nombre\"].lower() == (valor.lower()):\n            return print(id, datos)\n    return print(\"No existe\")\n\n\ndef insercion():\n    global contador_id\n    global agendaContactos\n    nombre = input(\"Ingrese nombre: \")\n    telefono = input(\"Ingrese Telefono: \")\n\n    if telefono.isdigit() and len(telefono) <= 11:\n        agendaContactos[contador_id] = {\"nombre\": nombre, \"telefono\": int(telefono)}\n        contador_id += 1\n        print(\"Contacto agregado\")\n    else:\n        print(\"Numero telefono no puede superar los 11 digitos\")\n\n\ndef actualizacion():\n    global agendaContactos\n    nombre = input(\"Ingrese contacto que busca: \")\n    nuevo_Nombre = input(\"Ingrese nuevo nombre: \")\n    telefono = input(\"Ingrese Telefono: \")\n    for id_contacto, datos in agendaContactos.items():\n        if datos[\"nombre\"].lower() == nombre.lower():\n            if telefono.isdigit() and len(telefono) <= 11:\n                datos[\"nombre\"] = nuevo_Nombre\n                datos[\"telefono\"] = int(telefono)\n                print(\"Contacto actualizado\")\n                return\n    print(\"No existe el contacto\")\n\n\ndef eliminar():\n    nombre = input(\"Que contacto desea eliminar: \")\n    encontrado = False\n    id_eliminar = None\n    for id, datos in agendaContactos.items():\n        if datos[\"nombre\"].lower() == nombre.lower():\n            id_eliminar = id\n            encontrado = True\n            break\n\n    if encontrado:\n        agendaContactos.pop(id_eliminar)\n        print(\"Contacto eliminado\")\n    else:\n        print(\"No existe el contacto\")\n\n\n# insercion(\"Ivan\", 1111111111)\n# insercion(\"Raul\", 9999999999)\n# print(agendaContactos)\n\n# actualizacion(\"Ivan\", \"Ivan G\", 123456789)\n# print(agendaContactos)\n\n# print(busqueda())\n# print(eliminar())\n# print(agendaContactos)\n\nwhile True:\n    opcion = input(\n        \"---- Agenda de contactos ---- \\nIngrese su opcion: \\n1. Buscar contacto. \\n2. Agregar contacto. \\n3. Actualizar contacto. \\n4. Eliminar contacto. \\n5. Salir\\nIngrese su opcion: \"\n    )\n\n    match opcion:\n        case \"1\":\n            busqueda()\n        case \"2\":\n            insercion()\n        case \"3\":\n            actualizacion()\n        case \"4\":\n            eliminar()\n        case \"5\":\n            print(\"Fin\")\n            break\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/javierfiestasbotella.py",
    "content": "''''EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.'''\nprint('_______LISTAS___________')\nejemplo=[1,45,876,7,34,2]\nprint(sorted(ejemplo))#lista ordenada\nprint(ejemplo.pop())#borrado ultimo elemnto de la lista\nprint(ejemplo)#lista actualizada\nprint(ejemplo.clear())#borrado de la lista\n\nprint('_______TUPLAS___________')\nejemplo_2=(3,654,57,2,9)\nprint(sorted(ejemplo_2))#tupla ordenada\nprint(ejemplo_2)#tupla actualizada\n#del ejemplo_2();borrado de la tupla\n\n\nprint('_______DICCIONARIOS___________')\nejemplo_3={1:'azul',2:'rojo',3:'verde',4:'blanco'}\n\nclaves_ordenadas = sorted(ejemplo_3.keys())\nvalores_ordenados = [ejemplo_3[clave] for clave in claves_ordenadas]#ordena \n\nprint(\"Claves ordenadas:\", claves_ordenadas)\nprint(\"Valores ordenados:\", valores_ordenados)\ndel ejemplo_3[3]#elimina clave y su valor\nejemplo_3[1] = 'rosa'#cambiamos el valor\nejemplo_3.clear()#Elimina el diccionario\n\nprint(\"Diccionario después de borrar:\", ejemplo_3)\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/javierjoyera.py",
    "content": "#Creación de Listas\n'''\nLas listas en Python son colecciones ordenadas y modificables. Pueden contener elementos de diferentes tipos, numericos, decimales, strings, etc.\n'''\nmy_list = [4, 2, 12, 1, 5, \"gato\", \"perro\", \"zapato\", 3.4]\n\n#Operaciones con Listas\n#Inserción\nmy_list.append(8)\nprint(my_list)\nmy_list.insert(0, 3) #Inserta el 3 en la posición 0\nprint(my_list)\n\n#Borrado\nmy_list.remove(12) #Borra el 12 por el valor\nprint(my_list)\n\ndel my_list[0] #Borra el elemento en la posición 0 \nprint(my_list)\n\nmy_list.pop() #Borra el último elemento\nprint(my_list)\n\n#update \nmy_list[0] = 10 #Actualiza el valor en la posición 0\n\n#Ordenación\nmy_new_list  = [1,9, 12, 3, 5, 0, 23, 8, 11]\nprint(my_new_list)\nmy_new_list.sort() #Ordena la lista\nprint(my_new_list)\n\n#Creación de Tuplas\n'''\nLas tuplas son colecciones ordenadas e inmutables. Una vez creadas, no puedes modificar sus elementos.\nLas operaciones de inserción, borrado y actualización no son aplicables a las tuplas debido a su naturaleza inmutable. \nSin embargo podemos convertir una tupla en una lista, modificarla y volver a convertirla en tupla.\n'''\nmy_tuple = (1, 2, 3, 4, 5)\n\n#Convertir tupla en lista\nmy_list = list(my_tuple)\nprint(my_list)\n\n#Convertir lista en tupla\nmy_tuple = tuple(my_list)\nprint(my_tuple)\n\n#Creación de Conjuntos\n'''\nLos conjuntos son colecciones desordenadas y no indexadas. No permiten elementos duplicados.\n'''\nmy_set = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}\n\n#Operaciones con Conjuntos\n#Inserción\nmy_set.add(11)\nprint(my_set)\n\n#Borrado\nmy_set.remove(11)\n\n#Creación de Diccionarios\n'''\nLos diccionarios son colecciones no ordenadas que almacenan pares clave-valor. No permiten elementos duplicados.\n'''\nmy_dict = {\"nombre\": \"Javier\", \"apellido\": \"Joyera\", \"edad\": 30}\n\n#Operaciones con Diccionarios\n#Inserción\nmy_dict[\"pais\"] = \"España\"\nprint(my_dict)\n\n#Borrado\ndel my_dict[\"pais\"]\nprint(my_dict)\n\n#update\nmy_dict[\"edad\"] = 27\nprint(my_dict)\n\n\n#EJECRCICIO OPCIONAL\nprint(\"---------------------\")\nprint(\"EJERCICIO OPCIONAL\")\nprint(\"---------------------\")\n\n\ndef show_menu():\n    print(\"\\nAgenda de Contactos\")\n    print(\"1. Añadir contacto\")\n    print(\"2. Buscar contacto\")\n    print(\"3. Actualizar contacto\")\n    print(\"4. Eliminar contacto\")\n    print(\"5. Salir\")\n    return input(\"Selecciona una opción: \")\n\ndef validar_telefono(numero):\n    return numero.isdigit() and len(numero) == 9\n\n\ndef añadir_contacto(agenda):\n    nombre = input(\"Introduce el nombre del contacto: \")\n    numero = input(\"Introduce el número de teléfono (9 digitos): \")\n    if validar_telefono(numero):\n        agenda[nombre] = numero\n        print(\"Contacto añadido.\")\n    else:\n        print(\"Número de teléfono inválido.\")\n\ndef actualizar_contacto(agenda):\n    nombre = input(\"Introduce el nombre del contacto: \")\n    if nombre in agenda:\n        numero = input(\"Introduce el nuevo número de teléfono: \")\n        if validar_telefono(numero):\n            agenda[nombre] = numero\n            print(\"Contacto actualizado.\")\n        else:\n            print(\"Número de teléfono inválido.\")\n    else:\n        print(\"Contacto no encontrado.\")\n\ndef eliminar_contacto(agenda):\n    nombre = input(\"Introduce el nombre del contacto: \")\n    if nombre in agenda:\n        del agenda[nombre]\n        print(\"Contacto eliminado.\")\n    else:\n        print(\"Contacto no encontrado.\")        \n\n\n\ndef buscar_contacto(agenda):\n    nombre = input(\"Introduce el nombre del contacto: \")\n    print(agenda.get(nombre, \"Contacto no encontrado.\"))\n\n\n\ndef main():\n    agenda = {}\n    while True:\n        opcion = show_menu()\n        if opcion == '1':\n            añadir_contacto(agenda)\n        elif opcion == '2':\n            buscar_contacto(agenda)\n        elif opcion == '3':\n            actualizar_contacto(agenda)\n        elif opcion == '4':\n            eliminar_contacto(agenda)\n        elif opcion == '5':\n            print(\"Saliendo de la agenda...\")\n            break\n        else:\n            print(\"Opción no válida.\")\n\nif __name__ == \"__main__\":\n    main()    "
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/javirub.py",
    "content": "'''\n/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n'''\n\n#Listas: Son secuencias mutables usadas normalmente para almacenar objetos homogeneos\nfrutas = ['naranja', 'manzana', 'fresa', 'pera']\nprint(f'Esta es una lista: {frutas}')\n\n#Inserción\nfrutas.insert(0, 'melocoton')\nprint(f'Vamos a insertar en el indice 0 melocoton {frutas}')\n\n#Borrado\nfrutas.remove('fresa')\nprint(f'Vamos a borrar la fresa {frutas}')\n\n#Actualización\nfrutas[2] = 'kiwi'\nprint(f'Vamos a cambiar el indice 2 por kiwi {frutas}')\n\n#Ordenación\nfrutas.sort()\nprint(f'Vamos a ordenar alfabeticamente las frutas: {frutas}')\n\n#Tuplas: Son secuencias inmutables, usadas normalmente para almacenar información heterogenea\nletras = tuple('abc')\nprint(f'Esto es una tupla : {letras}') #No se puede operar sobre ella ya que es inmutable\n\n#Rangos: Es una secuencia inmutable de numero, normalmente usada para hacer un número determinado de loops en los bucles for\nrango = range(10)\nprint(f'Esto es un rango: {rango}')\n\n#String: Se usan para almacenar caracteres, también son inmutables\ncadena = 'Hola mundo'\nprint(f'Esto es un string: {cadena}')\n\n#Diccionarios: Asocia claves con valores\npersonas = {\n    'juan': {\n        'nombre': 'Juan',\n        'edad': 25,\n        'ciudad': 'Valencia'},\n    'javier': {\n        'nombre': 'Javier',\n        'edad': 26,\n        'ciudad': 'Paris'\n    }\n}\nprint(f'Esto es un diccionario: {personas}')\n#Inserción\npersonas['juan']['ocupacion'] = 'Desarrollador'\nprint(f'Vamos a insertarle una ocupación a juan: {personas}')\n#Borrado\ndel personas['javier']['edad']\nprint(f'Vamos a borrarle la edad a javier: {personas}')\n#Actualización\npersonas['juan']['edad'] = 26\nprint(f'Vamos a cambiarle la edad a Juan: {personas}')\n\n#Conjuntos: Colección no ordenada de elementos únicos\npares = {0,2, 4, 6, 8, 10}\nprint(f'Esto es un conjunto {pares}')\n#Inserción\npares.add(14)\nprint(f'Hemos añadido 14 al conjunto: {pares}')\n#Borrado\npares.remove(6)\nprint(f'Hemos borrado el 6 del conjunto: {pares}')\n#No se puede actualizar ni ordenar\n\n#Estructuras de control de flujo\nfor i in range(2):\n    if i==0:\n        print('Esto es un if dentro de un bucle for')\n    else:\n        print('Esto es un else dentro de un bucle for')\n\ni = 0\nwhile i < 2:\n    print(f'Esto es la iteración {i+1} de un bucle while')\n    i += 1\n\n#Funciones\ndef suma(a, b):\n    print(f'Esto es una función que suma {a} y {b}: {a + b}')\nsuma(5,4)\n\n#Clases y objetos\nclass Persona:\n    def __init__(self, nombre, edad):\n        self.nombre = nombre\n        self.edad = edad\n\njuan = Persona('Juan', 26)\n\nprint(f'juan es un objeto con nombre: {juan.nombre} y edad: {juan.edad}')\n\n#Actualización\njuan.edad += 1\nprint(f'Juan ha cumplido {juan.edad} años')\n\n#Inserción\njuan.ocupacion = 'Desarrollador'\nprint(f'Juan ha adquirido la ocupación de: {juan.ocupacion}')\n\n#Borrado\ndel juan.ocupacion\ntry:\n    print(f'Juan esta trabajando de {juan.ocupacion}')\nexcept:\n    print('Juan ha perdido su ocupación')\n\n#Ejercicio EXTRA\n''' \n* DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n '''\n\nagenda = {} #Iniciamos el diccionario agenda\ndef add_contact():\n    name = input(\"Ingrese el nombre del contacto a agregar: \")\n    phone = input(\"Ingrese el número de telefono de su contacto: \")\n    if (len(phone) > 11):\n        print('Error, el número es muy largo')\n\n    elif not phone.isnumeric():\n        print('Error, solo puedes introducir numeros para el numero de telefono.')\n\n    else:\n        agenda[name] = {'nombre' : name, 'telefono' : phone}\n        print('Se ha agregado correctamente el contacto')\n\n    menu()\n\ndef search():\n    name = input(\"Introduzca el nombre del contacto que desea consultar: \")\n    if name in agenda:\n        print(agenda[name])\n    else:\n        print(f'La persona {name} no se encuentra en su agenda.')\n\n    menu()\n\ndef update_contact():\n    name = input(\"Introduzca el nombre del contacto que desea actualizar: \")\n    if name in agenda:\n        agenda[name]['telefono'] = input('Ingrese el nuevo telefono de su contacto: ')\n    else:\n        print(f'La persona {name} no se encuentra en su agenda')\n\n    menu()\n\ndef delete_contact():\n    name = input(\"Introduzca el nombre del contacto que desea eliminar: \")\n    if name in agenda:\n        del agenda[name]\n    else:\n        print(f'La persona {name} no se encuentra en su agenda')\n\n    menu()\n\ndef show_contacts():\n    print(f'Estos son sus contactos: {agenda}')\n    menu()\n\ndef menu():\n    print('Menu de agenda contactos. Seleccione una opción: ')\n    print('1 - Agregar contacto')\n    print('2 - Borrar contacto')\n    print('3 - Mostrar contactos')\n    print('4 - Actualizar contacto')\n    print('5 - Salir de la agenda')\n    option = input()\n    if option == '1':\n        add_contact()\n    elif option == '2':\n        delete_contact()\n    elif option == '3':\n        show_contacts()\n    elif option == '4':\n        update_contact()\n\n    elif option == '5':\n        print('Hasta la vista')\n\n    else:\n        print('Por favor, introduzca un número del 1 al 5.')\n        menu()\n\nmenu()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/javitron100.py",
    "content": "# ESTRUCTURAS DE DATOS\r\n\r\n# Listas\r\nmi_lista = [1, 35, 23, 11, 34]\r\nprint(mi_lista[3])\r\n\r\nmi_lista.append(5)\r\nprint(mi_lista)\r\n\r\nmi_lista.insert(1, 12)\r\nprint(mi_lista)\r\n\r\nmi_lista.remove(12)\r\nprint(mi_lista)\r\n\r\nmi_lista.pop()\r\nprint(mi_lista)\r\n\r\nmi_lista.sort()\r\nprint(mi_lista)\r\n\r\nmi_lista.reverse()\r\nprint(mi_lista)\r\n\r\n# Tuplas\r\nmi_tupla = (1, 56, 14, 77, 6, 13)\r\nprint(mi_tupla)\r\n\r\n# Sets\r\nmi_set = {1, 2, 3, 4, 5, 6, 7}\r\nprint(type(mi_set))\r\nprint(mi_set)\r\nprint(mi_set)\r\nprint(mi_set)\r\n\r\nmi_set.add(14)\r\nprint(mi_set)\r\n\r\nmi_set.remove(3)\r\nprint(mi_set)\r\n\r\n# Diccionarios\r\n\r\nmi_diccionario = {\r\n    \"Nombre\" : \"Javier\", \r\n    \"Edad\" : 50, \r\n    \"Telefono\" : \"642123487\"\r\n\r\n}\r\n\r\nprint(mi_diccionario)\r\nprint(mi_diccionario[\"Nombre\"])\r\n\r\n# Dificultad Extra\r\nopcion = \"\"\r\nagenda = [\r\n            {\"Nombre\" : \"javi\", \"Telefono\" : \"11111\"}, \r\n            {\"Nombre\" : \"pepe\", \"Telefono\" : \"22222\"}, \r\n            {\"Nombre\" : \"toni\", \"Telefono\" : \"33333\"}, \r\n            {\"Nombre\" : \"carla\", \"Telefono\" : \"44444\"}\r\n        ]\r\n\r\ndef insertar_contacto():\r\n\r\n    contacto = {\"Nombre\" : \"\", \"Telefono\" : \"\"}\r\n\r\n    nom = input(\"Nombre: \")\r\n    tel = input(\"Teléfono: \")\r\n    if tel.isdigit() and len(tel) in range(1, 12):\r\n        contacto[\"Nombre\"] = nom\r\n        contacto[\"Telefono\"] = tel\r\n        agenda.append(contacto)\r\n    else:\r\n        print(\"El número de teléfono no es válido, no se ha grabado la entrada.\")\r\n\r\ndef borrar_contacto(busqueda):\r\n    for contacto in agenda:\r\n            if contacto[\"Nombre\"] == busqueda:\r\n                agenda.remove(contacto)\r\n\r\ndef actualizar_contacto(busqueda):\r\n    for contacto in agenda:\r\n            if contacto[\"Nombre\"] == busqueda:\r\n                tel = input(\"Nuevo número de teléfono: \")\r\n                if tel.isdigit() and len(tel) in range(1, 12):\r\n                    contacto[\"Telefono\"] = tel\r\n                else: \r\n                    print(\"Teléfono no válido. No se actualiza.\")\r\n\r\ndef buscar_contacto(busqueda):\r\n    for contacto in agenda:\r\n        if contacto[\"Nombre\"] == busqueda:\r\n            print(contacto)\r\n\r\n    \r\n\r\nwhile opcion != \"0\":\r\n    \r\n    if opcion == \"1\":\r\n       insertar_contacto()\r\n\r\n    if opcion == \"2\":\r\n        borrar_contacto(input(\"Nombre a borrar de la agenda: \"))\r\n\r\n    if opcion == \"3\":\r\n        actualizar_contacto(input(\"Nombre a actualizar: \"))\r\n\r\n    if opcion == \"4\":\r\n        buscar_contacto(input(\"Nombre a buscar: \"))\r\n\r\n    if opcion == \"5\":\r\n        print(agenda)\r\n\r\n    print(\"1.- Insertar contacto\")\r\n    print(\"2.- Borrar contacto\")\r\n    print(\"3.- Actualizar contacto\")\r\n    print(\"4.- Buscar contacto\")\r\n    print(\"5.- Mostrar agenda\")\r\n    opcion = input(\"Elige una opcion (0 para terminar el programa): \")\r\n    \r\n\r\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/jcdm60.py",
    "content": "# #03 ESTRUCTURAS DE DATOS\n#### Dificultad: Media | Publicación: 15/01/24 | Corrección: 22/01/24\n\n## Ejercicio\n\n#\n# EJERCICIO:\n# - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n# - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n#\n# DIFICULTAD EXTRA (opcional):\n# Crea una agenda de contactos por terminal.\n# - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n# - Cada contacto debe tener un nombre y un número de teléfono.\n# - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n#   los datos necesarios para llevarla a cabo.\n# - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n#   (o el número de dígitos que quieras)\n# - También se debe proponer una operación de finalización del programa.\n#\n\n# LISTAS\n# Creación de una lista\nmi_lista = [1, 2, 3, 4, 5]\n\n# Inserción de un elemento al final de la lista\nmi_lista.append(6)\n\n# Borrado de un elemento por valor\nmi_lista.remove(2)\n\n# Actualización de un elemento por índice\nmi_lista[1] = 15\n\n# Ordenación de la lista\nmi_lista.sort()\n\nprint(mi_lista)\n\n# TUPLAS\n# Creación de una tupla\nmi_tupla = (1, 2, 3, 4, 5)\n\n# Acceso a un elemento por índice\nelemento = mi_tupla[3]\n\n# Concatenación de tuplas\nnueva_tupla = mi_tupla + (6, 7, 8)\n\nprint(elemento)\nprint(nueva_tupla)\n\n# CONJUNTOS\n# Creación de un conjunto\nmi_conjunto = {1, 2, 3, 4, 5}\n\n# Inserción de un elemento\nmi_conjunto.add(6)\n\n# Borrado de un elemento por valor\nmi_conjunto.remove(3)\n\n# Actualización del conjunto con otro conjunto\nmi_conjunto.update({7, 8, 9})\n\nprint(mi_conjunto)\n\n# AGENDA DE CONTACTOS\nagenda = {}\n\ndef mostrar_menu():\n    print(\"\\n** Agenda de Contactos **\")\n    print(\"1. Mostrar contactos\")\n    print(\"2. Buscar contacto\")\n    print(\"3. Añadir contacto\")\n    print(\"4. Actualizar contacto\")\n    print(\"5. Eliminar contacto\")\n    print(\"6. Salir\")\n\ndef mostrar_contactos():\n    print(\"\\n** Lista de Contactos **\")\n    for nombre, telefono in agenda.items():\n        print(f\"{nombre}: {telefono}\")\n\ndef buscar_contacto():\n    nombre = input(\"Ingrese el nombre del contacto a buscar: \")\n    if nombre in agenda:\n        print(f\"{nombre}: {agenda[nombre]}\")\n    else:\n        print(f\"{nombre} no encontrado en la agenda.\")\n\ndef añadir_contacto():\n    nombre = input(\"Ingrese el nombre del nuevo contacto: \")\n    telefono = input(\"Ingrese el número de teléfono: \")\n    \n    if telefono.isdigit() and len(telefono) <= 11:\n        agenda[nombre] = telefono\n        print(f\"Contacto {nombre} añadido correctamente.\")\n    else:\n        print(\"Número de teléfono no válido. Asegúrate de ingresar un número numérico máximo de 11 dígitos.\")\n\ndef actualizar_contacto():\n    nombre = input(\"Ingrese el nombre del contacto a actualizar: \")\n    if nombre in agenda:\n        nuevo_telefono = input(\"Ingrese el nuevo número de teléfono: \")\n        \n        if nuevo_telefono.isdigit() and len(nuevo_telefono) <= 11:\n            agenda[nombre] = nuevo_telefono\n            print(f\"Contacto {nombre} actualizado correctamente.\")\n        else:\n            print(\"Número de teléfono no válido. Asegúrate de ingresar un número numérico máximo de 11 dígitos.\")\n    else:\n        print(f\"{nombre} no encontrado en la agenda.\")\n\ndef eliminar_contacto():\n    nombre = input(\"Ingrese el nombre del contacto a eliminar: \")\n    if nombre in agenda:\n        del agenda[nombre]\n        print(f\"Contacto {nombre} eliminado correctamente.\")\n    else:\n        print(f\"{nombre} no encontrado en la agenda.\")\n\n# Programa principal\nwhile True:\n    mostrar_menu()\n    opcion = input(\"Seleccione una opción (1-6): \")\n\n    if opcion == '1':\n        mostrar_contactos()\n    elif opcion == '2':\n        buscar_contacto()\n    elif opcion == '3':\n        añadir_contacto()\n    elif opcion == '4':\n        actualizar_contacto()\n    elif opcion == '5':\n        eliminar_contacto()\n    elif opcion == '6':\n        print(\"Programa finalizado.\")\n        break\n    else:\n        print(\"Opción no válida. Por favor, elija una opción del 1 al 6.\")\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/jesusgdev.py",
    "content": "\"\"\"\nEJERCICIO:\n 1. Muestra ejemplos de creación de todas las estructuras soportadas por defecto\n    en tu lenguaje.\n 2. Utiliza operaciones de inserción, borrado, actualización y ordenación.\n \n * DIFICULTAD EXTRA (opcional):\n 3. Crea una agenda de contactos por terminal.\n *  Debes implementar funcionalidades de búsqueda, inserción, actualización\n    y eliminación de contactos.\n *  Cada contacto debe tener un nombre y un número de teléfono.\n *  El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n    y a continuación los datos necesarios para llevarla a cabo.\n *  El programa no puede dejar introducir números de teléfono no numéricos y con más\n    de 11 dígitos (o el número de dígitos que quieras).\n *  También se debe proponer una operación de finalización del programa.\n\"\"\"\n\n# Estructuras de datos basicas\n\n# 1. List o listas\n\n# Creation\nfruits = [\"apple\", \"pineaple\", \"banana\", \"cherry\", \"banana\"]\nprint(\"List of fruits: \", fruits)\n\n# Insercion\nfruits.append(\"orange\")    # agrego un elemento al final de la lista\nfruits.insert(1, \"kiwi\")    # inserto un elemento en una posicion especifica de la lista\nprint(\"After insertion:\", fruits)\n\n# Deletion\nfruits.remove(\"banana\")    # elimina la primera ocurrencia que coincida con el elemento indicado\ndeleted_item = fruits.pop()    # elimina y devuelve el ultimo elemento de la lista\nprint(\"After deletion:\", fruits)\nprint(\"Deleted item:\", deleted_item)\n\n# Update\nfruits[0] = \"green apple\"   # Modifica un elemento de la lista por indice\nprint(\"After update:\", fruits)\n\n# Sorting and reverse\nfruits.sort()   # Ordena los elementos de la lista en orden ascendente\nprint(\"Sorted list:\", fruits)\nfruits.reverse()\nprint(\"Reversed list:\", fruits)\n\n# 2. Tuples o tuplas\n\n# Creation\ncoordinates = (15, 55)  \nprint(\"Original tuple:\", coordinates)\n\n# Access\nprint(\"First value:\", coordinates[0])   # Devuelve un elemento de la tupla indicado por el indice\n\n# \"Update\" via conversion to list\ncoordinates = list(coordinates)\ncoordinates[0] = 99\ncoordinates = tuple(coordinates)\nprint(\"Modified tuple:\", coordinates)\n\n# 3. Sets\n\n# Creation\nnumbers = {1, 2, 3, 4}\nprint(\"Original set:\", numbers)\n\n# Insertion\nnumbers.add(5)\nnumbers.update([6, 7])              # Agrega multiples elementos\nprint(\"After insertion:\", numbers)\n\n# Deletion\nnumbers.remove(2)                   # Elimina un elemento pero genera un error si el indice no existe \nnumbers.discard(10)                 # No genera error si el indice no existe\nremoved = numbers.pop()             # Elimina un elemento de manera arbitraria\nprint(\"After deletion:\", numbers)\nprint(\"Popped element:\", removed)\n\nprint(\"Sorted set:\", sorted(numbers))  # Devuelve una lista ordenada, es temporal ya que no se puede ordenar un set\n\n# Set operations\nodds = {1, 3, 5}\nevens = {2, 4, 6}\nprint(\"Union:\", odds | evens)\nprint(\"Intersection:\", odds & evens)\n\n# 4. Dictionaries o Diccionarios\n\n# Creation\nperson = {\"name\": \"John\", \"age\": 30}\nprint(\"Original dictionary:\", person)\n\n# Insertion\nperson[\"city\"] = \"New York\"    # Agrega la llave y el valor indicado al diccionario\nprint(\"After insertion:\", person)\n\n# Deletion\ndel person[\"age\"]   # Elimina tanto la llave indicada como el valor del diccionario\nremoved_city = person.pop(\"city\")   # Elimina tanto la llave indicada como el valor del diccionario, y devuelve como resultado el valor asociado a la llave indicada\nprint(\"After deletion:\", person)\nprint(\"Removed value:\", removed_city)\n\n# Update\nperson[\"name\"] = \"John Doe\"    # Modifica el valor de la llave indicada por un valor especificado \nprint(\"After update:\", person)\n\n# Sorting by keys\nsorted_dict = dict(sorted(person.items()))  # Ordena el diccionario por llave en orden alfabetico ascendente\nprint(\"Sorted dictionary (by key):\", sorted_dict)\n\n# Other operations\nprint(\"Keys:\", list(person.keys()))    # Genera una lista de las llaves del diccionario \nprint(\"Values:\", list(person.values()))    # Genera una lista de los valores de las llaves del diccionario \nprint(\"Items:\", list(person.items()))    # Genera una lista de tuplas, donde cada tupla contiene la llave con su respectivo valor      \n\n# 5. Strings o cadenas de texto\n\n# Creation\nmessage = \"Hello World\"\nprint(\"Original string:\", message)\n\n# Access\nprint(\"First character:\", message[0])   # Devuelve el primer caracter de la cadena de texto\nprint(\"Last character:\", message[-1])   # Devuelve el ultimo caracter de la cadena de texto\n\n# Update (esto crea una nueva cadena de texto)\nmessage = message.replace(\"World\", \"Python\")    # Remplaza una palabra de la cadena de texto(primer argumento) por una nueva palabra(segundo argumento)\nprint(\"After replacement:\", message)\n\n# Deletion by slice (Esto crea una nueva cadena de texto)\nmessage = message[0:5]  # Extrae un segmento especifico de la cadena de texto y borra el resto\nprint(\"After slicing:\", message)\n\n# Sorting characters alphabetically\nsorted_chars = ''.join(sorted(\"zebra\"))    # Ordena de manera ascendente los caracteres de un string y los almacena en un nuevo string vacio \nprint(\"Sorted string characters:\", sorted_chars)\n\n# String methods\ntext = \"  Python is FUN  \"\nprint(\"Lower:\", text.lower())   # Devuelve la cadena de texto en minusculas\nprint(\"Upper:\", text.upper())   # Devuelve la cadena de texto en mayusculas\nprint(\"Stripped:\", text.strip())    # Elimina los espacion en blanco del inicio y el final de la cadena de texto\nprint(\"Split:\", text.split())    # Devuelve una lista con cada palabra de la cadena de texto como elemento de la lista\n\n\"\"\"\n6. Crea una agenda de contactos por terminal.\n *  Debes implementar funcionalidades de búsqueda, inserción, actualización\n    y eliminación de contactos.\n *  Cada contacto debe tener un nombre y un número de teléfono.\n *  El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n    y a continuación los datos necesarios para llevarla a cabo.\n *  El programa no puede dejar introducir números de teléfono no numéricos y con más\n    de 11 dígitos (o el número de dígitos que quieras).\n *  También se debe proponer una operación de finalización del programa.\n\"\"\"\n\ncontactbook = {}\n\n# ---------------------------------------------------------\n# Esta función valida si un nombre ingresado es válido.\n# Elimina los espacios y verifica que todos los caracteres\n# restantes sean alfabéticos (letras). Retorna True o False.\n# ---------------------------------------------------------\n\ndef valid_name(name):\n    without_spaces = name.replace(\" \", \"\")\n    return without_spaces.isalpha() and len(without_spaces) > 0\n\n# ---------------------------------------------------------\n# Esta función permite agregar un nuevo contacto al diccionario.\n# Verifica que el nombre no contenga caracteres inválidos y\n# que no exista ya en la agenda, ignorando diferencias entre\n# mayúsculas y minúsculas. También valida el número de teléfono.\n# ---------------------------------------------------------\n\ndef add_contacts():\n    name = input(\"Agrega el nombre del contacto: \")\n\n    # Validación del nombre: debe contener solo letras y espacios.\n    if not valid_name(name):\n        print(\"\\n❌ Error: El nombre del contacto solo debe contener letras y espacios\")\n        return\n\n    # La funcion .strip() permite borrar los espacios ubicados antes y despues del nombre\n    name_lower = name.strip().lower()\n\n    # Verificación de existencia previa del contacto (sin importar mayúsculas)\n    for name_saved in contactbook:\n        if name_saved.lower() == name_lower:\n            print(\"\\n⚠️ El contacto ya existe! El guardado del nombre es sensible a mayusculas y minusculas.\")\n            return\n\n    phone_number = input(\"Agrege el numero de telefono (Debe tener un maximo de 11 digitos): \")\n\n    # Validación del número: debe contener solo dígitos y tener máximo 11 caracteres\n    if not phone_number.isdigit() or len(phone_number) > 11:\n        print(\"\\n❌ Error: el numero de telefono solo debe contener numneros y un maximo de 11 digitos\")\n        return\n    \n    else:\n        contactbook[name] = phone_number\n        print(f\"\\n✅ El contacto {name} fue agregado!\")\n\n# ---------------------------------------------------------\n# Esta función permite buscar un contacto por nombre.\n# Si el nombre es válido y existe en la agenda, se muestra\n# su número asociado.\n# ---------------------------------------------------------\n\ndef search_contact():\n    name = input(\"Agrega el contacto que deseas buscar: \")\n\n    # Validación del nombre ingresado\n    if not valid_name(name):\n        print(\"\\n❌ Error: El nombre del contacto solo debe contener letras y espacios\")\n        return\n\n    # Búsqueda directa en el diccionario\n    if name in contactbook:\n        print(f\"{name} : {contactbook[name]}\")\n    else:\n        print(\"\\n😅 El contacto no existe!\")\n        return\n    \n# ---------------------------------------------------------\n# Esta función permite actualizar el número telefónico\n# de un contacto existente.\n# ---------------------------------------------------------  \n    \ndef update_contact():\n    name = input(\"Agrega el contacto que deseas actualizar: \")\n\n    # Validación del nombre\n    if not valid_name(name):\n        print(\"\\n❌ Error: El nombre del contacto solo debe contener letras y espacios\")\n        return\n    \n    # Verificación de existencia del contacto\n    if name in contactbook:\n        phone_number = input(\"Agrega el nuevo numero del contacto\")\n        contactbook[name] = phone_number\n        print(f\"\\n✅ El contacto {name} ha sido actualizado!\")\n        return\n    else:\n        print(\"\\n😅 El contacto no existe!\")\n        return\n    \n# ---------------------------------------------------------\n# Esta función permite eliminar un contacto existente\n# de la agenda, si este se encuentra registrado.\n# ---------------------------------------------------------\n    \ndef remove_contact():\n    name = input(\"\\nAgrega el contacto que deseas eliminar: \")\n\n    # Validación del nombre\n    if not valid_name(name):\n        print(\"\\n❌ Error: El nombre del contacto solo debe contener letras y espacios\")\n        return\n\n    # Verificación de existencia y eliminación\n    if name in contactbook:\n        del contactbook[name]\n        print(f\"\\n🔥 El contacto {name} ha sido eliminado!\")\n        return\n    else:\n        print(\"\\n😅 El contacto no existe!\")\n        return\n\n# ---------------------------------------------------------\n# Esta función imprime todos los contactos registrados\n# en la agenda. Si la agenda está vacía, informa al usuario.\n# ---------------------------------------------------------\n\ndef show_contacts():\n\n    if len(contactbook) == 0:\n        print(\"\\n⚠️ La agenda esta vacia, ingrese un contacto\")\n        return\n\n    print(\"\\n📋 Esta es la lista de contactos:\")\n\n    for name in contactbook:\n        print(f\"🔹{name} : {contactbook[name]}\")\n\n# ---------------------------------------------------------\n# Menú principal del programa. Permite al usuario seleccionar\n# una opción y repite el proceso hasta que elija salir.\n# ---------------------------------------------------------\n\nwhile True:\n    print(\"\\n📱 AGENDA DE CONTACTOS 📱\\n\"+\n          \"1. Agregar Contacto\\n\"+\n          \"2. Buscar Contacto\\n\"+\n          \"3. Actualizar Contacto\\n\"+\n          \"4. Borrar Contacto\\n\"+\n          \"5. Mostrar Contactos\\n\"\n          \"6. Salir\")\n    \n    option = input(\"\\n📌 Selecciona una opcion ( 1 - 6): \")\n\n    # Validación de entrada: debe ser un número entre 1 y 6\n    if not option.isdigit():\n        print(\"⚠️ El menu solo acepta valores entre el 1 y el 6\")\n        continue\n\n    option = int(option)\n\n    if option < 1 or option > 6:\n        print(\"⚠️ El menu solo acepta valores entre el 1 y el 6\")\n        continue\n\n\n    if option == 1:\n        add_contacts()\n    elif option == 2:\n        search_contact()\n    elif option == 3:\n        update_contact()\n    elif option == 4:\n        remove_contact()\n    elif option == 5:\n        show_contacts()\n    elif option == 6:\n        break"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/jesusway69.py",
    "content": "import os\nos.system ('cls')\n\n\"\"\"\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n\"\"\"\n#LISTA , ESTRUCTURA DE ELEMENTOS MUTABLES QUE PUEDEN SER DE VARIOS TIPOS \nprint (\"LISTA\" , \"\\n-----\")\nlista = [1, 3.5, 7j, \"Hola\", \"Python\", True, None, [4, 5], (1, \"hola\", False)]\nprint(type(lista))\n[print(i , end =' ') for i in lista]#Forma simplificada de bucle for con instrucción de impresión\nlista.append(\"Elemento al final\") #Agrega elemento al final\nprint(lista)\nlista.insert(2 ,\"elemento agregado en la posición 2\") # Inserta elemento en la posición determinada \nprint(lista)\nlista.remove((1, \"hola\", False)) #Borra el elemento especificado\nprint(lista)\nprint(\"Veces que se repite el nº 1 y/o el booleano True: \",lista.count(1))\n# devuelve el nº de repeticiones de un elemento (devuelve 2 porque interpreta el True como otro 1)\n#el método .count también es válido pata tuplas\nlista.reverse()# El método .reverse invierte el orden de los elementos de la lista\nprint(lista)\n\n\n#TUPLA , ESTRUCTURA DE ELEMENTOS INMUTABLES QUE PUEDEN SER DE VARIOS TIPOS\nprint (\"\\nTUPLA\" , \"\\n-----\")\ntupla = 1, 2, 2, 3.5, 7j, \"Hola\", \"Python\", True, None, [4,5,6], [1,2,3] #Se puede declarar con o sin paréntesis\nprint(type(tupla))\n[print(i, end =' ') for i in tupla] #Forma simplificada de bucle for con instrucción de impresión\nprint('')\ntupla_vacia =() #Declaración de una tupla vacía\nprint (len(tupla_vacia)) #de longitud 0\ntupla_un_elemento = \"elemento único\", #Declaración de una tupla con un solo elemento\nprint(len(tupla_un_elemento))#de longitud 1\nprint(tupla_un_elemento)\nprint (tupla.index(\"Python\")) #Devuelve la posición del elemento especificado\nprint (tupla)\n\n\n#SET , ESTRUCTURA MUTABLE DE ELEMENTOS ÚNICOS\nprint (\"\\nSET\" , \"\\n---\")\nset1 = {7, 9, 2, 8, 4, 5, 6, 1, 8, 3, 0, 14, 8, 1, 10, 4, 3, 3}\nset2 = {15, 28, 31, 4, 28, 2, 50, 1, 8, 20, 10, 7, 14, 3, 12, 19}\nprint(type(set1))\n[print(i, end = ' ') for i in set1]#Forma simplificada de bucle for con instrucción de impresión\nprint(\"\\n\")\nfor i in set2:       #Forma tradicional de bucle for\n    print(i, end=' ')#con instrucción de impresión\nprint('\\n')       \nprint (set1-set2)# muestra los elementos que solo existen en set1 y no están en set2\n#Equivalente a print(set1.difference(set2))\nprint (set2-set1)# muestra los elementos que solo existen en set2 y no están en set1\n#Equivalente a print(set2.difference(set1))\nprint (set1 & set2)# muestra únicamente los elementos que existen a la vez en ambos sets\n# Equivalente a print (set1.intersection(set2))\nprint (set1 | set2)# muestra todos los elementos de ambos sets sin repeticiones\n# Equivalente a print(set1.union(set2))\nprint (set1 ^ set2)# muestra los elementos de ambos sets que están en uno u otro set pero no en ambos \n# Equivalente a print(set1.symmetric_difference(set2))\nset1.discard(7) #El método .discart elimina un elemento definido del set\n#print (set1)\n\n\n#FROZENSET , ESTRUCTURA INMUTABLE DE ELEMENTOS ÚNICOS\nprint (\"\\nFROZENSET\" , \"\\n---------\")\nfrozen_set  = frozenset([1, 0, 3, 5, 9, 6, 1, 3, 4, 8, 7, 2])\nprint(type(frozen_set))\n[print(i , end = ' ') for i in frozen_set]\nprint('\\n')#Los métodos son los mismos que en set salvo los que modifiquen el contenido como .discart\n\n#DICCIONARIO , ESTRUCTURA EN FORMATO CLAVE-VALOR INDEXADA POR LA CLAVE\nprint (\"\\nDICCIONARIO\" , \"\\n-----------\")\ndiccionario = {\n\"Italia\" : \"Roma\",\n\"España\" : \"Madrid\",\n\"Francia\" : \"París\",\n\"Alemania\" : \"Berlín\"\n}\nprint(type(diccionario))\n[print(paises , end = ' ') for paises in diccionario] #Iteración sólo mostrando claves (capitales)\n[print(\"\\n\",paises, capitales , end = ' ') for paises, capitales in diccionario.items()] #Iteración mostrando claves y valores \nprint (\"\\n\",diccionario[\"España\"])# Búsqueda de un valor por su clave\n\n#Creación de diccionario con cálculo, se da un nº como clave y su valor será el resultado de la operación \nnumeros_al_cubo = {n: n**3 for n in (2,4,6)}\nprint (numeros_al_cubo)\nnumeros_entre_dos = {n: n/2 for n in (2,4,6)}\nprint (numeros_entre_dos)\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n *   y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n *   y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más\n *   de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.\"\"\"\nprint (\"\\nEJERCICIO\" , \"\\n---------\")\n\nagenda = {\n\"Antonio\":\"123456789\",\n\"Luis\" : \"987654321\",\n\"Marta\" : \"321987654\",\n\"Carlos\": \"123789456\",\n\"Steven\": \"456789123\",\n\"Sandra\" : \"654987321\",\n\"Francois\" : \"321654987\"\n}\n\n\n\n\ndef buscar():\n  \n    nombre = input(\"Introduzca nombre a buscar:  \").capitalize()\n    \n    if  nombre in agenda:\n        print(\"El usuario\", nombre, \"existe con nº de tlf:\" , agenda[nombre])\n    else :\n        print(\"El usuario\" , str(nombre) , \"no existe\")\ndef añadir():\n   \n    nombre = input(\"Introduzca el nombre del usuario a añadir:\").capitalize()\n    tlf = input(\"Introduzca el número de teléfono: \")\n    if  len(tlf)  in range (9,12) and tlf.isdigit():    \n        agenda[nombre] = tlf\n        print(f\"El usuario {nombre} se ha añadido correctamente.\")        \n    else:\n        print(\"Sólo se admiten nº de teléfono con entre 9 y 11 dígitos numéricos\")\n\ndef borrar():\n    nombre = input(\"Introduzca el usuario a eliminar : \").capitalize()\n\n    if nombre in agenda:\n        agenda.pop(nombre)\n        print(\"El usuario\", str(nombre), \"se ha eliminado correctamente\")\n\n    else : print(\"El usuario\", nombre , \"no existe\")\n\n\n\n\nwhile True:\n print (\"\"\"\\nSeleccione una opcion:\n       1- Buscar contacto\n       2- Añadir contacto\n       3- Borrar contacto\n       4- Mostrar agenda\n       5- Salir\"\"\")\n opcion = input()\n\n if opcion == \"1\":\n  buscar()\n elif opcion == \"2\":\n  añadir()\n elif opcion == \"3\":\n  borrar()\n elif opcion == \"4\":\n    print (\"AGENDA\",\n           \"\\n------------------\")\n    [print(\"\\n\",k, v , end = ' ') for k, v in agenda.items()]\n    print(\"\\n------------------\")\n    print(\"\\n\")\n elif opcion == \"5\":\n   print(\"Programa finalizado.\")\n   break\n else:\n    print (\"Sólo se pueden introducir opciones numéricas del 1 al 5\")\n\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/jfdacovich.py",
    "content": "\"\"\"\nEstructuras de datos en Python\n\"\"\"\n\n# Listas\nprint(\"----------Listas----------\")\nmy_list = [3, 2, 1, 4, 5, 7, 8, 1, 21, 32]\nprint(my_list)\nmy_list.append(\"hola\") # Agregar un elemento al final de la lista\nprint(my_list)\nmy_list.insert(3, \"Insertado\") # Insertar elementos en una posición específica\nprint(my_list)\nmy_list.remove(\"hola\") # Eliminando elementos\nprint(my_list)\nmy_list.pop(3) # Eliminando elementos por posición\nprint(my_list)\nmy_list.sort() # Ordenando elementos\nprint(my_list)\nprint(my_list.count(1)) # Contnado elementos\nmy_list.reverse() # Invirtiendo el orden los elementos\nprint(my_list)\n\n# Tuplas\nprint(\"----------Tuplas----------\")\nmy_tuple = (\"jfdacovich\", \"python\", 3, 3, 2, 1)\nprint(my_tuple.count(3)) # Contando elementos\nprint(my_tuple.index(\"python\")) # Buscando elementos\nprint(my_tuple[1]) # Accediendo a elementos\nprint(my_tuple[1:3]) # Accediendo a un rango de elementos\nprint(my_tuple)\n\n# Diccionarios\nprint(\"----------Diccionarios----------\")\nmy_dict = {\"nombre\": \"jfdacovich\", \"edad\": 111, \"ciudad\": \"Xxxxxx\"}\nprint(my_dict)\nprint(my_dict[\"nombre\"]) # Accediendo a elementos\nprint(my_dict.get(\"nombre\")) # Accediendo a elementos\nmy_dict[\"nombre\"] = \"jfdacovich2\" # Modificando elementos\nprint(my_dict)\nmy_dict[\"apellido\"] = \"Python\" # Agregando elementos\nprint(my_dict)\nprint(my_dict.keys()) # Obteniendo las llaves\nprint(my_dict.values()) # Obteniendo los valores\nprint(my_dict.items()) # Obteniendo los elementos\nprint(my_dict.pop(\"nombre\")) # Eliminando elementos\nprint(my_dict)\nmy_dict.clear() # Limpiando el diccionario\nmy_dict.update({\"nombre\": \"jfdacovich\", \"edad\": 111, \"ciudad\": \"Xxxxxx\"}) # Actualizando el diccionario\nmy_dict2 = my_dict.copy() # Copiando el diccionario\nprint(my_dict2)\nmy_dict2.pop(\"nombre\")\nprint(my_dict2)\ndel my_dict2[\"edad\"] # Eliminando elementos\n\n# Conjuntos\nprint(\"----------Conjuntos----------\")\nmy_set = {\"jfdacovich\", \"python\", 3, 3, 2, 1}\nprint(my_set)\nmy_set.add(\"hola\") # Agregando elementos\nprint(my_set)\nprint(my_set.discard(\"python\")) # Eliminando elementos\nprint(my_set)\nprint(my_set.pop()) # Eliminando elementos\nprint(my_set)\n# print(my_set.clear()) # Limpiando el conjunto\nprint(f\"my_set: {my_set}\")\nmy_set2 = {1, 2, 3, 4, \"java\", \"sql\"}\nprint(my_set2.union(my_set)) # Uniendo conjuntos\nprint(my_set2.intersection(my_set)) # Intersecando conjuntos\nprint(my_set2.difference(my_set)) # Diferencia de conjuntos\nprint(my_set2.symmetric_difference(my_set)) # Diferencia simétrica de conjuntos\nmy_set2.update(my_set) # Actualizando el conjunto\nprint(my_set2)\nmy_set2.remove(\"jfdacovich\") # Eliminando elementos\nprint(my_set2)\nmy_set2.clear() # Limpiando el conjunto\nprint(my_set2)\n\n\"\"\"\nExtra\n\"\"\"\n\ndef agenda():\n    print(\"----------Agenda----------\")\n    contactos = {}\n    def buscar_contacto(nombre):\n        if nombre in contactos:\n            print(f\"El número de teléfono de {nombre} es {contactos[nombre]}\")\n        else:\n            print(\"El contacto no existe\")\n\n    def validacion_actualizacion(nombre, telefono):\n        if telefono.isdigit() and 0 < len(telefono) <= 11:\n            contactos[nombre] = telefono\n            return True\n        return False\n\n    def agregar_contacto(nombre, telefono):\n        if validacion_actualizacion(nombre, telefono):\n            print(\"Contacto agregado correctamente\")\n        else:\n            print(\"Número de teléfono inválido\")\n\n    def actualizar_contacto(nombre, telefono):\n        if nombre in contactos:\n            if validacion_actualizacion(nombre, telefono):\n                print(\"Contacto actualizado correctamente\")\n            else:\n                print(\"Número de teléfono inválido\")\n        else:\n            print(\"El contacto no existe\")\n\n    def eliminar_contacto(nombre):\n        if nombre in contactos:\n            del contactos[nombre]\n            print(\"Contacto eliminado correctamente\")\n        else:\n            print(\"El contacto no existe\")\n\n    while True:\n        print(\"----------Menú:\")\n        print(\"1. Buscar contacto\")\n        print(\"2. Agregar contacto\")\n        print(\"3. Actualizar contacto\")\n        print(\"4. Eliminar contacto\")\n        print(\"5. Salir\")\n\n        opcion = input(\"\\nIngrese una opción: \")\n\n        match opcion:\n            case \"1\":\n                nombre = input(\"Ingrese el nombre del contacto: \")\n                buscar_contacto(nombre)\n            case \"2\":\n                nombre = input(\"Ingrese el nombre del contacto: \")\n                telefono = input(\"Ingrese el número de teléfono del contacto: \")\n                agregar_contacto(nombre, telefono)\n            case \"3\":\n                nombre = input(\"Ingrese el nombre del contacto que desea actualizar: \")\n                telefono = input(\"Ingrese el nuevo número de teléfono del contacto: \")\n                actualizar_contacto(nombre, telefono)\n            case \"4\":\n                nombre = input(\"Ingrese el nombre del contacto que desea eliminar: \")\n                eliminar_contacto(nombre)\n            case \"5\":\n                print(\"Hasta luego\")\n                break\n            case _:\n                print(\"La opcion que indicas no es válida, por favor intenta de nuevo\")\n\nagenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/jgutierrez9891.py",
    "content": "\"\"\"\nEstructuras de datos\n\"\"\"\n\n# Listas\n\nciudades = [\"Bogotá\", \"Cali\", \"Medellín\", \"Cartagena\", \"Santa Marta\", \"Bucaramanga\"]\n\n#Agregar elemento al final\nciudades.append('Pereira')\nprint(ciudades)\n\n# Remover elemento\nciudades.remove('Cali')\nprint(ciudades)\n\n# Insertar elemento en una posición dada\nciudades.insert(3, \"Montería\")\nprint(ciudades)\n\n# Eliminar elemento en una posicióno dada\nciudades.pop(5)\nprint(ciudades)\n\n# Ordenar elementos\nciudades.sort()\nprint(ciudades)\n\n# Actualizar elemento\nciudades[1] = \"Cartagena de Indias\"\nprint(ciudades)\n\n#Tuplas\n\nanimales_salvajes = \"pájaro\", \"león\", \"ratón\", \"pez\", \"murciélago\", \"liebre\"\n\n# Las tuplas son inmutables: no se puede agregar, modificar o eliminar elementos\n\n# Seleccionar elemento\nprint(animales_salvajes[2])\n\n# Anidar otra tupla\nanimales = \"perro\", animales_salvajes\nprint(animales)\n\n# Diccionarios\n\ntelefonos = {'Jose': 34973904, 'Andrea': 4343240, 'Eduardo': 38105735, 'Luisa': 44340904}\n\n# Seleccionar elemento\nprint (telefonos['Andrea'])\n\n# Añadir elemento\ntelefonos['Alberto'] = 31735540\nprint (telefonos)\n\n# Eliminar elemento\ndel telefonos['Eduardo']\nprint (telefonos)\n\n# Ordenar elementos\nprint (dict (sorted(telefonos.items())))\n\n# Actualizar elemento\ntelefonos['Andrea'] = 1234567\nprint (telefonos)\n\n\n\"\"\"\nExtra\n\"\"\"\n\ncontactos = {'Jose': 34973904, 'Andrea': 4343240, 'Eduardo': 38105735, 'Luisa': 44340904}\n\ndef consultar_contacto():\n    nombre = input(f\"Ingrese el nombre del contacto que desea buscar:\\n\")\n    if nombre in contactos.keys():\n        print (f\"El teléfono de {nombre} es {contactos[nombre]}\")\n        print(contactos)\n    else:\n        print(\"El nombre ingresado no se encuentra en los contactos\")\n    \n\ndef agregar_contacto():\n    nombre = input(f\"Ingrese el nombre del contacto que desea agregar:\\n\")\n    telefono = input(f'Ingrese el teléfono del contacto\\n')\n    if telefono.isdigit() and len(telefono) <= 11:\n        contactos[nombre] = int(telefono)\n        print (f\"El contacto {nombre} ha sido agregado a su lista\")\n        print(contactos)\n    else:\n        print(\"El teléfono ingresado no es válido. Debe ser un valor numérico de máximo 11 dígitos\")\n\ndef actualizar_contacto():\n    nombre = input(f\"Ingrese el nombre del contacto que desea actualizar:\\n\")\n    if nombre in contactos.keys():\n        telefono = input(f'Ingrese el nuevo teléfono del contacto\\n')\n        if telefono.isdigit() and len(telefono) <= 11:\n            contactos[nombre] = int(telefono)\n            print (f\"El teléfono de {nombre} ha sido actualizado a {telefono}\")\n            print(contactos)\n        else:\n            print(\"El teléfono ingresado no es válido. Debe ser un valor numérico de máximo 11 dígitos\")\n    else:\n        print(\"El nombre ingresado no se encuentra en los contactos\")\n    \n\ndef eliminar_contacto():\n    nombre = input(f\"Ingrese el nombre del contacto que desea eliminar:\\n\")\n    if nombre in contactos.keys():\n        del contactos[nombre]\n        print (f\"El contacto {nombre} ha sido eliminado\")\n        print(contactos)\n    else:\n        print(\"El nombre ingresado no se encuentra en los contactos\")\n    \n\ndef admin_contactos():\n    accion = 0\n    while True:\n        accion = input(\"Ingresa la acción a realizar:\\n\"\n                    \"1: buscar contacto\\n\"\n                    \"2: agregar contacto\\n\"\n                    \"3: actualizar contacto\\n\"\n                    \"4: eliminar contacto\\n\"\n                    \"5: Terminar programa\\n\")\n\n        match accion:\n            case \"1\":\n                consultar_contacto()\n            case \"2\":\n                agregar_contacto()\n            case \"3\":\n                actualizar_contacto()\n            case \"4\":\n                eliminar_contacto()\n            case \"5\":\n                print(\"Gracias por utilizar la lista de contactos\")\n                break\n            case _:\n                print(\"No ha ingresado una opción válida.\")\n\n\nadmin_contactos()\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/jhoshmc.py",
    "content": "\n\"\"\"\n* Estructuras\n\"\"\"\n#!listas, \n#* son estructuras ordenadas donde vamos a guardar elementos, como un array \n# print(\"----------------listas-------------------------\")\n# my_list = [\"juan\",\"pedro\",\"ana\",\"maria\"]\n# print(my_list)\n# my_list.append(\"mario\") #* agregar un nuevo elemento a la lista\n# print(my_list)\n# my_list.remove(\"ana\") #* eliminar un elemento de la lista, en esta caso por valor\n# print(my_list)\n# my_list[1]= \"armando\" #* actualizar un elemento de la lista, en este caso por posición\n# print(my_list)\n# my_list.sort() #* mostrar la lista ordenada, con el ordenamiento predeterminado, se puede cambiar \n# print(my_list)\n# print(type(my_list))\n\n# #! tupla\n# #* es una estructura donde se puede guardar mas de un dato, pero son inmutables, \n# #* (como se crean, se quedan , no cambian), va entre parentesis ()\n# print(\"---------------- tuplas --------------------\")\n# my_tupla= ( \"mauro\",\"acuario\",\"algo@gmail.com\",'20')\n# print(my_tupla)\n# #* solo se puede hacer operaciones de acceso\n# print(my_tupla[2])\n# print(type(my_tupla))\n# #* se puede cambiar la tupla a una lista para ordarla, con sorted()\n# my_tupla= sorted(my_tupla) #* sorted(), devulve una lista ordenada\n# print(my_tupla)\n# print(type(my_tupla))\n# #* cambiar la lista otra vez a tupla con el constructor de tupla\n# my_tupla= tuple(my_tupla)\n# print(my_tupla)\n# print(type(my_tupla))\n\n# #! Set\n# #* son otro tipo de estructura, van entre corchetes {}, no permiten valores repetidos, \n# #* set es una estructura desordenada(no se puede fiar de la posición de un elemento) \n# #* transforma sus datos en hash \n# print(\"---------------- set -----------------\")\n# my_set: set ={\"mauro\",\"acuario\",\"algo@gmail.com\",'20'}\n# print(my_set)\n# print(type(my_set))\n# my_set.add(\"maria\") #* insertar elemento\n# print(my_set)\n# my_set.remove(\"20\") #* eliminar un elemento\n# my_set=sorted(my_set) #* ordenarlo, combirtiendolo a lista\n# print(my_set)\n# print(type(my_set))\n# my_set= set(my_set)\n# print(my_set)\n# print(type(my_set))\n\n# #! Diccionario\n# #* el formato en que se guardan los datos es clave, valor (key, value)\n# #* en python los diccionarios, son ordenados por defecto\n# print(\"------------ dictionario-----------------------\")\n# my_dic: dict ={\n#   \"name\":\"mauro\",\n#   \"signo\":\"acuario\",\n#   \"gmail\":\"algo@gmail.com\",\n#   \"age\":'20'}\n# print(my_dic)\n# print(type(my_dic))\n# my_dic[\"fav_food\"]=\"pato guisado\" #* se esta insertando una nueva clave y valor\n# print(my_dic)\n# print(my_dic[\"name\"]) #* se accede mediante la clave, no hay posiciones\n# my_dic[\"age\"]=\"21\" #* actualizar un elemento\n# print(my_dic)\n# del my_dic[\"signo\"] #* eliminar un elemento \n# print(my_dic)\n# my_dic= dict(sorted(my_dic.items())) #* ordenar, es importante poner items(), para que devuelva las claves y los valores\n# print(my_dic)\n\n\"\"\"\n*Extra\n\"\"\"\nimport re\npatron = r\"^\\d{1,11}$\"  # Expresión regular para validar números de 1 a 11 dígitos\nagenda_contactos={}\ndef verificar_numero(nombre,telefono):\n  if re.fullmatch(patron,telefono):\n    agenda_contactos[nombre]=telefono\n    return True\n  else:\n    print(\"el numero ingresado no puede ser mayor a 11 dijitos \\n\")\n    return False \n\n\ndef ingresar_contacto():\n  print(\"\\n\\t ingresar contacto: \\n\")\n  nombre=input(\"ingresa el nombre: \")\n  telefono= input(\"ingresa el numero de telefono: \")\n  verificado=verificar_numero(nombre,telefono)\n  if verificado:\n    print(\"\\nnuevo contacto agregado \\n\")\n  \n\ndef buscar_contacto(nombre):\n  print(\"\\n\\t buscar contacto: \\n\")\n  if nombre in agenda_contactos:\n    print(f\"contacto encontrado: \\n${nombre} Movil:${agenda_contactos[nombre]}\")\n    return True\n  else:\n    print(f\"el contacto: ${nombre} no existe \\n\")\n    return False\n\ndef actualizar_contacto():\n  print(\"\\n\\t actualizar contacto: \\n\")\n  nombre = input(\"ingrese el nombre del contacto: \")\n  existe = buscar_contacto(nombre)\n  if existe:\n    telefono= input(\"ingrese el nuevo numero de telefono: \")\n    verificado= verificar_numero(nombre,telefono)\n    if verificado:\n      print(\"\\n contacto actualizado\\n\")\n\n    \n\ndef borrar_contacto():\n  print(\"\\n\\t borrar contacto: \\n\")\n  nombre= input(\"ingrese el nombre del contacto: \")\n  existe= buscar_contacto(nombre)\n  if existe:\n    del agenda_contactos[nombre]\n    print(\"\\n contacto eliminado\")\n  \n\ndef ordenar_contactos():\n  print(\"\\t\\n ordenar contactos: \\n\")\n  agenda_ordenada= dict(sorted(agenda_contactos.items()))\n  print(agenda_ordenada)\n  print(\"\\n\")\n  \ndef agenda():\n  \n  while True:\n    print(\"\\t Menu de agenda : \\n\")\n    print(\"1. ingresar contacto \")\n    print(\"2. buscar contacto\")\n    print(\"3. actualizar contacto\")\n    print(\"4. borrar contacto\")\n    print(\"5. ordenar contactos\")\n    print(\"6. salir\")\n    #* input rejoge lo que selecciona el usuario desde la terminal\n    option=input(\" \\n ingresa la opcion: \")\n\n    match option:\n      case '1':\n        ingresar_contacto()\n      case '2':\n        nombre= input(\"ingrese el nombre del contacto: \")\n        buscar_contacto(nombre)\n      case '3':\n        actualizar_contacto()\n      case '4':\n        borrar_contacto()\n      case '5':\n        ordenar_contactos()\n      case '6':\n        print(\"\\n saliendo del programa adios\\n\")\n        break\n      case _: print(\"opcion no valida\")\n  \n\n\nagenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/jorgeadamowicz.py",
    "content": "## Listas\n\nmy_full_pets_list = [\"lara\", \"bruno\", \"vicente\", \"chiqui\", \"olivia\",\"shelly\", \"emmy\"]\nprint(my_full_pets_list)\n\n## Insercióin: agregar un elemento a la lista (metodo Iserción append)\nmy_full_pets_list.append(\"isa\")\nmy_new_pets_list= my_full_pets_list\n\n#(metodo Inserción insert)\n#my_full_pets_list.insert (1,\"Isa\")# insertará el nombre de mi nueva mascota en la posición \"1\"\nprint(my_new_pets_list)\n\n## Borrado: borra elementos de la lista (metodo remove)\nmy_new_pets_list.remove (\"lara\")\nmy_new_pets_list.remove (\"bruno\")\nmy_new_pets_list.remove (\"vicente\")\nmy_new_pets_list.remove (\"shelly\")\n#aquí se podría utilizar un bucle para iterar y eliminar todos los valores de una vez:\nmy_dead_pets_list = (\"lara\",\"bruno\",\"vicente\",\"shelly\")\nfor element in my_dead_pets_list:\n    if element in my_new_pets_list:\n        my_new_pets_list.remove(element)\nmy_current_pets = my_new_pets_list\nprint(my_current_pets)\n\n## Actualización: asignamos un nuevo valor a la posicion establecida\nprint(my_current_pets[2])\nmy_current_pets[2] = (\"emma\")\nprint(my_current_pets)\n\n## Ordenamiento: permite ordenar los elementos\nmy_current_pets.sort()\nprint(my_current_pets)\n\n### Tuplas ###\n\nmy_pesonal_data= (\"jorge\", \"adamowicz\", \"51\", \"chorch\")\nprint(my_pesonal_data)\nprint(type(my_pesonal_data))\n\"\"\"\n# Las tuplas son inmutables o que significa que no se pueden cambiar una vez creadas. \nEsto incluye la inserción, eliminación o modificación de los elementos dentro de una tupla.\n\"\"\"\n# Acceso: \nprint(my_pesonal_data[2]) #imprime el dato correspondiente a la posición \"2\"\nprint(my_pesonal_data.count(\"jorge\")) #contará cuntas veces apararece en dato del parametro\nprint(my_pesonal_data.index(\"chorch\")) #indicará la posición del parametro asignado. \n\n### Sets ###\n\nMy_sports_set = {\"motocross\", \"surf\", \"snowboard\"}\nprint(My_sports_set)\n\n# Inserción:\n\nMy_sports_set.add(\"mtb\")\nprint(My_sports_set)\n\n#Borrado: \n\nMy_sports_set.remove(\"motocross\")\nprint(My_sports_set)\n\n### Diccionarios ###\nMy_personal_data_dict ={\n    \"nombre\": \"jorge\",\n    \"apellido\": \"adamowicz\",\n    \"edad\": \"51\",\n    \"alias\": \"chorch\"\n    }\nprint(My_personal_data_dict)\n\n#Inserción:\nMy_personal_data_dict [\"deportes\"] = \"mtb\", \"motocross\", \"surf\", \"snowboard\"\nprint(My_personal_data_dict)\n\n#Borrado:\ndel My_personal_data_dict[\"alias\"]\nprint(My_personal_data_dict)\n\n#Actualización: \nMy_personal_data_dict[\"nombre\"]= \"George\"\n\nprint(My_personal_data_dict[\"nombre\"]) # Acceso:\n\n#### Extra ####\n\n\"\"\"\nla declaración \"match\" aun no la conocia pero siguiendo un poco el video pude entender su\nimplementación en este ejercicio... que me costó bastante resolver. voy a intentar hacerlo\nutilizando en control de flujo de (if, elif, else), pero mas tarde, todavia me sale humo\nde la cabeza! saludos y una vez mas gracias!\n\"\"\"\n\ndef my_contact_list():\n    telephone_book = {}\n\n    while True:\n        print(\"\")\n        print(\"1. Buscar un contacto\")\n        print(\"2. Insertar un contacto\")\n        print(\"3. Actualizar un contacto\")\n        print(\"4. Eliminar un contacto\")\n        print(\"5. salir de la agenda\")\n\n        option = input(\"\\n selecciona una opción: \")\n\n        match option:\n            case \"1\":\n                name = input(\"\\n Ingresa el nombre de contacto: \")\n                if name in telephone_book:\n                    print(f\"\\n el numero de {name} es: {telephone_book[name]}.\")\n                else: \n                    print(f\"\\n el nombre {name} no está en la agenda\")\n                \n            case \"2\":\n                name = input(\"\\n Ingresa el nombre de contacto: \")\n                number = input(\"\\n Ingresa el numero de telefono: \")\n                if number.isdigit() and len(number) <=11 :# verifica si el numero es valido\n                    telephone_book [name]= number #asigna el valor numero a la key nombre\n                else:\n                    print(\"ingresa un número telefónico válido\")\n            case \"3\":\n                name = input(\"\\n Ingresa el nombre de contacto que quieres actualizar: \")\n                if name in telephone_book:\n                    number = input(\"\\n Ingresa el numero de telefono: \")\n                    if number.isdigit() and len(number) <=11 :\n                        telephone_book [name]= number\n                    else:\n                        print(\"ingresa un número telefónico válido\")                \n                else:\n                    print(f\"\\n el nombre {name} no está en la agenda\")\n\n            case \"4\":\n                name = input(\"\\n Ingresa el nombre de contacto que quieres eliminar: \")\n                if name in telephone_book:\n                    del telephone_book[name]\n                else:\n                    print(f\"\\n el nombre {name} no está en la agenda\")\n            case \"5\":\n                print(\"has salido de la agenda\")\n                break\n            case _:\n                print(\"Escribe una opción válida entre 1 y 5\")\n \nmy_contact_list()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/jose-larss.py",
    "content": "\"\"\"\nEstructuras\n\"\"\"\n\n# Listas\n\n# Creacion\nlista1 = [1, 2, 3, 5, 7, 8, 'a', 'b', 'r']\nlista2 :list = [1, 2, 3, 5, 7, 8, 345, 100, 111]\n\nprint(lista1)\nprint(lista2)\n\n# Inserción al final de la lista\nlista1.append(345)\n\nprint(lista1)\n\n# Eliminación\nlista1.remove(1)\n\nprint(lista1)\n\n# Acceso\nprint(lista1[4])\n\n# Actualización\nlista1[4] = \"jose\"\n\nprint(lista1)\n\n# Ordenación\nlista2.sort()\nprint(lista2)\n\n# Tuplas\n\n# Creacion\ntupla1: tuple = (1, 2, 3, 5, 7, 8, 345, 100, 111)\ntupla2 = (1, 2, 3, 5, 7, 8, 345, 100, 111)\n\nprint(tupla1)\nprint(tupla2)\n\n# Acceso\nprint(tupla1[3])\n\n\n# Ordenación\ntupla1 = tuple(sorted(tupla1))\ntupla2 = sorted(tupla2)\nprint(tupla1)\nprint(tupla2)\n\n# SETS\n\n# Creacion\nset1 = set([1, 2, 3, 5, 7, 8, 'a', 'b', 'r'])\nset2 = {1, 2, 3, 5, 7, 8, 'a', 'b', 'r'}\n\nprint(set1)\nprint(set2)\n\n# Inserción al final de la lista\nset1.add(5678)\nset2.add(\"piano\")\n\nprint(set1)\nprint(set2)\n\n# Eliminación\nset1.remove(1)\nset1.discard(45678) # borra el elemento pero sino existe lo descarta\n\nprint(set1)\n\n\n# Ordenación\n#set1 = set(sorted(set1)) # No se puede ordenar\n#print(set1)\n\n# Diccionarios\n\n# Creacion\ndicc1 = {'name':'jose', 'apellido':'castro', 'años':45, 'nacionalidad':'España', 'pais':'España'}\ndicc2 :dict = {'name':'jose', 'apellido':'castro', 'años':45, 'nacionalidad':'España', 'pais':'España'}\n\nprint(dicc1)\nprint(dicc2)\n\n# Inserción al final de la lista\ndicc1['email'] = \"pepe@pepe.com\"\n\nprint(dicc1)\n\n# Eliminación\ndel dicc1['name']\n\nprint(dicc1)\n\n# Acceso\nprint(dicc1['años'])\n\n# Actualización\ndicc1['años'] = 34\n\nprint(dicc1)\n\n# Ordenación\ndicc1 = dict(sorted(dicc1.items()))\ndicc2 = sorted(dicc1.items())\nprint(dicc1)\nprint(dicc2)\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\"\"\"\n\ndef my_agenda():\n    agenda = {}\n\n    def insertar():\n        tel = input(\"Introduce el teléfono del contacto.\")\n        if len(tel) > 0 and len(tel) <= 11 and tel.isdigit():\n            agenda[nombre] = tel\n        else:\n            print(\"Debes introducir un número con menos de 11 digitos\")\n\n    while True:\n        print(\"*************AGENDA*****************\")\n        print(\"1 Búsqueda: \")\n        print(\"2 Inserción: \")\n        print(\"3 Actualización: \")\n        print(\"4 Eliminación: \")\n        print(\"5 Salir\")\n        print(\"************************************\")\n\n        opcion = input(\"Que operación deseas realizar?: \")\n\n        match opcion:\n            case '1':\n                nombre = input(\"Introduce el nombre a buscar: \")\n                if nombre in agenda:\n                    print(f\"El numero de teléfono de {nombre} es {agenda[nombre]}.\")\n                else:\n                    print(f\"El contacto {nombre} NO existe.\")\n            case '2':\n                nombre = input(\"Introduce el nombre a buscar: \")\n                insertar()\n            case '3':\n                nombre = input(\"Introduce el nombre a actualizar: \")\n                if nombre in agenda:\n                    insertar()\n                else:\n                    print(f\"El contacto {nombre} NO existe.\")\n            case '4':\n                nombre = input(\"Introduce el nombre a eliminar: \")\n                if nombre in agenda:\n                    del agenda[nombre]\n                    print(f\"{nombre} se ha eliminado con éxito\")\n                else:\n                    print(f\"El contacto {nombre} NO existe.\")\n            case '5':\n                print(\"Saliendo de la agenda!!\")\n                break\n            case _:\n                print(\"Opción no válida. Elige una opción del 1 al 5.\")\n\n\nmy_agenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/josecox13.py",
    "content": "\n#Lista\nprint('\\n -----Listas-----')\nlista_nombre = ['Juan', 'Pepe', 'Fran'] #Definición\nprint(lista_nombre)\nlista_nombre.append('Jaime') #Inserción\nprint(lista_nombre)\nlista_nombre.remove('Pepe') #Eliminación\nprint(lista_nombre)\nlista_nombre[1] = 'Jorge' #Actualización\nprint(lista_nombre)\nlista_nombre.sort() #Ordenación\nprint(lista_nombre)\n\n#Conjunto o set \nprint('\\n -----Set-----')\nmi_set = {1,1,3,4,7}\nprint(mi_set)\nmi_set.add(8) #Inserción\nprint(mi_set)\nmi_set.remove(1) #Eliminación\nprint(mi_set)\nmi_set = sorted(mi_set) #esto lo convertirá en una lista\n\n#Diccionario\nprint('\\n -----Diccionarios-----') #definición\nmi_diccionario = {'nombre':'Juan',\n                'trabajo':'desarrollador IA',\n                'edad':'30'}\nprint(mi_diccionario)\nprint(mi_diccionario['edad']) #acceso\nmi_diccionario['empresa'] = 'Microsoft' #actualización o añadir una entrada\nprint(mi_diccionario)\ndel mi_diccionario['edad'] #borrado de una entrada\ndiccionario_ordenado = dict(sorted(mi_diccionario.items())) #ordenación\nprint(diccionario_ordenado)\n\n\n\n#Tupla\nprint('\\n -----Tuplas-----')\nmi_tupla = ('Fran', 'Cuesta', 'Microsoft', 'Madrid')\n#No se puede alterar ni modificar, solo acceder\nprint(mi_tupla[2])\nmi_tupla = tuple(sorted(mi_tupla)) #Siempre que todos los componentes de la tupla sean del mismo tipo de dato\n\n#Ejercicio extra\nprint('\\n -----Ejercicio extra -----')\ncontactos = {'Lola':'672456241', 'Javi':'613782346'} \ndef agenda():\n    while True: #esto se va a ejecutar infinitas veces\n        print('Bienvenido a su agenda. Las opciones disponibles son:')\n        print('1. Buscar un contacto')\n        print('2. Insertar contacto')\n        print('3. Actualizar contacto')\n        print('4. Eliminar contacto')\n        print('5. Finalizar sesión')\n        opcion = input(str('¿Qué desea realizar? '))\n        if opcion == '1':\n            nombre = input(str('Introduzca el nombre del contacto a buscar: '))\n            if nombre in agenda:\n                telefono = contactos[nombre]\n                print(f'El teléfono de {nombre} es {telefono} \\n')\n            else:\n                print('Teléfono no encontrado')\n        elif opcion == '2':\n            nombre = input(str('Introduzca el nombre del contacto que quiere añadir: '))\n            telefono = input(str(f'Introduzca el teléfono de {nombre}: '))\n            while len(telefono) >= 11:\n                print('Telefono no válido. Introduzca un teléfono con la longitud correcta')\n                telefono = input(str(f'Introduzca el teléfono de {nombre}: '))\n            contactos[nombre] = telefono\n            print ('Teléfono correctamente añadido')\n        elif opcion == '3':\n            nombre = input(str('Introduzca el nombre del contacto que quiere modificar: '))\n            telefono = input(str(f'Introduzca el nuevo teléfono de {nombre}: '))\n            while len(telefono) >= 11:\n                print('Telefono no válido. Introduzca un teléfono con la longitud correcta')\n                telefono = input(str(f'Introduzca el teléfono de {nombre}: '))\n            contactos[nombre] = telefono\n            print ('Teléfono correctamente modificado')\n        elif opcion == '4':\n            nombre = input(str('Introduzca el nombre del contacto que quiere borrar: '))\n            if nombre in agenda:\n                del agenda[nombre]\n            else:\n                print('No existe en su agenda este contacto')\n        elif opcion == '5':\n            print('Sesion terminada')\n            break\n        else:\n            print('Comando no válido. Vuelva a introducir un comando')    \n\nagenda()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/joshu725.py",
    "content": "# Estructuras #\n\n# Listas (inserción, borrado, actualización y ordenación)\nlist = [\"Pedro\", \"Luis\", \"David\"]\nprint(list)\nlist.append(\"Fernando\")\nprint(list)\nlist.remove(\"Luis\")\nprint(list)\nprint(list[1])\nlist[1] = \"Alejandra\"\nprint(list)\nlist.sort()\nprint(list)\nprint(type(list))\n\n# Tuplas (inmutables)\ntuple = (\"Jessica\", 76, \"Ashley\", 23.12, True)\nprint(tuple)\nprint(tuple[3])\nprint(type(tuple))\n\n# Sets (malas para buscar datos porque siempre estan desordenadas)\nset = {\"Jessica\", 76, \"Ashley\", 23.12, True}\nprint(set)\nset.add(13)\nset.add(13)  # Evita duplicados\nprint(set)\nset.remove(\"Ashley\")\nprint(set)\nprint(type(set))\n\n# Diccionario (clave: valor)\ndictionary = {\n    \"name\": \"Josh\",\n    \"username\": \"joshu725\",\n    \"email\": \"joshu725@gmail.com\"\n}\nprint(dictionary[\"username\"])\ndictionary[\"age\"] = 23\nprint(dictionary)\ndel dictionary[\"age\"]\nprint(dictionary)\nprint(type(dictionary))\n\n# Extra #\n\ndef agenda():\n\n    contacts = {}\n\n    def add_number(name, number):\n        if number.isdigit() and len(number) == 10:\n            contacts[name] = number\n        else:\n            print(\"Ingresa un número de 10 dígitos\")\n\n    while True:\n        print(\"==========================\")\n        print(\"1. Insertar\")\n        print(\"2. Actualizar\")\n        print(\"3. Eliminar\")\n        print(\"4. Buscar\")\n        print(\"\\n5. Salir\")\n        print(\"==========================\")\n        option = input(\"> \")\n\n        match option:\n            case \"1\":\n                name = input(\"Introduce un nombre: \")\n                number = input(\"Introduce el telefono: \")\n                add_number(name, number)\n            case \"2\":\n                name = input(\"Introduce un nombre a actualizar: \")\n                if name in contacts:\n                    number = input(\"Introduce el nuevo teléfono: \")\n                    add_number(name, number)\n                else:\n                    print(\"No se ha encontrado el contacto\")\n            case \"3\":\n                name = input(\"Introduce un nombre a eliminar: \")\n                if name in contacts:\n                    del contacts[name]\n                else:\n                    print(\"No se ha encontrado el contacto\")\n            case \"4\":\n                name = input(\"Introduce un nombre a buscar: \")\n                if name in contacts:\n                    print(f\"El número de {name} es: {contacts[name]}\")\n                else:\n                    print(\"No se ha encontrado el contacto\")\n            case \"5\":\n                print(\"Saliendo...\")\n                break\n            case _:\n                print(\"Opción inválida, ingresa un número del 1 al 5\")\n\nagenda()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/jptxaya.py",
    "content": "#Estructuras de datos\n\n#Listas\nprint(\"Listas\")\nmy_list = [3,4,\"Lista\"]\n\n#CRUD on List\nmy_list2 = list()\n#Insert\nmy_list2.insert(0,\"Dato_0\")\nprint(my_list2)\nmy_list2.append(\"Dato Final\")\nprint(my_list2)\nmy_list2.insert(1,\"Dato_1\")\nprint(my_list2)\n#Update\nmy_list2[1] = \"Dato_1_update\"\nprint(my_list2)\n#Remove\nmy_list2.remove(\"Dato Final\")\nprint(my_list2)\n#Read\nprint(my_list2[0])\n#Sort\nmy_list2.append(\"Aa\")\nmy_list2.sort()\nprint(my_list2)\n\n#Tuplas\nprint(\"Tuplas\")\n#Create\nmy_tupla = (\"dato1\",\"dato2\",\"aato3\")\nprint(my_tupla)\n#Read\nprint(my_tupla[1])\n#No permite operaciones Insert,Append,Delete ni Sort\n\n#Set\nprint(\"Sets\")\nmy_set = {\"set1\",\"set2\",\"set3\"}\nprint(my_set)\n#Insert\nmy_set.add(\"set4\")\nprint(my_set)\nmy_set.add(\"set4\") #Solo permite valores unicos\nprint(my_set)\n#Read\nfor elem in my_set:\n    print(elem)\n#Remove\nmy_set.remove(\"set4\")\nprint(my_set)\n#No update\n\n#Dictionaries\nprint(\"Dictionaries\")\n\nmy_dict = {\"k0\":\"value0\",\"k1\":\"value1\",\"k2\":\"value2\"}\nprint(my_dict)\n\n#Read\nprint(my_dict[\"k1\"])\nprint(my_dict.get(\"k1\"))\n\n#Insert\nmy_dict[\"k4\"] = \"new_value1\"\nprint(my_dict)\n\n#Update\nmy_dict.update({\"k5\":\"new_value5\"}) #Es un insert\nprint(my_dict)\n\nmy_dict.update({\"k5\":\"update_value5\"}) #Es un update\nprint(my_dict)\n\n#Delete\ndel my_dict[\"k4\"]\nprint(my_dict)\n#or\nmy_dict.pop(\"k5\") #Devuelve el valor\nprint(my_dict)\n\n#Dificultad Extra\nimport re\n\n\ndef validar_numtlfno( num ):\n    if re.search(\"^[0-9]{1,11}$\",num):\n        return True\n    else:\n        return False\n\n\nmy_contact = {}\nwhile True:\n    print(\"AllContacts\")\n    print(my_contact)\n    print(\"Introducir la opcion seleccionada:\")\n    print(\"1- Añadir Contacto\")\n    print(\"2- Consultar Contacto\")\n    print(\"3- Modificar Contacto\")\n    print(\"4- Borrar Contacto\")\n    print(\"5- Salir\")\n    option = input(\"Selecciona una opcion:\")\n    match option:\n        case \"5\":\n            break\n        case \"1\":\n            num_tlfno = input(\"Introducir numero de telefono:\")\n            if validar_numtlfno(num_tlfno):\n                nombre = input(\"Introducir nombre:\")\n                my_contact[num_tlfno] = nombre\n            else:\n                print(\"Formato incorrecto. El numero de telefono tiene que ser un numero de 1 a 11 digitos\")\n        case \"2\":\n            print(\"Que desea realizar:\")\n            print(\"1-Buscar por numero de telefono\")\n            print(\"2-Buscar por nombre de contacto\")\n            find_option = input(\"Seleccione la opcion:\")\n            match find_option:\n                case \"1\":\n                    find_num_tlfno = input(\"Introduce el número de telefono a buscar:\")\n                    if my_contact.get(find_num_tlfno):\n                        print(f\"***Telefono:{find_num_tlfno} Nombre:{my_contact.get(find_num_tlfno)}\")\n                    else:\n                        print(\"Ningun contacto encontrado\")\n                case \"2\":\n                    find_contact = input(\"Introduce el nombre del contacto:\")\n                    cont = 0\n                    for elem in my_contact.items():\n                        if elem[1] == find_contact:\n                            cont += 1\n                            print(f\"***Telefono:{elem[0]} Nombre:{elem[1]}\")\n            \n                    print(f\"Telefonos encontrados: {cont}\")\n        case \"3\":\n            find_num_tlfno = input(\"Introduce el número de telefono a modificar:\")\n            if my_contact.get(find_num_tlfno):\n                new_contact = input(\"Introduce nuevo nombre de contacto\")\n                my_contact[find_num_tlfno] = new_contact\n            else:\n                print(\"Ningun contacto encontrado para modificar\")\n        case \"4\":\n            find_num_tlfno = input(\"Introduce el número de telefono a borrar:\")\n            if my_contact.get(find_num_tlfno):\n                 my_contact.pop(find_num_tlfno)\n            else:\n                print(\"Ningun contacto encontrado para borrar\")\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/jtrujilloalcocer.py",
    "content": "# ESTRUCTURAS DE DATOS\n\n#   EJERCICIO:\n#   - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n#   - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n#  \n#   DIFICULTAD EXTRA (opcional):\n#   Crea una agenda de contactos por terminal.\n#   - Debes implementar funcionalidades de búsqueda, inserción, actualización\n#    y eliminación de contactos.\n#   - Cada contacto debe tener un nombre y un número de teléfono.\n#   - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n#     y a continuación los datos necesarios para llevarla a cabo.\n#   - El programa no puede dejar introducir números de teléfono no númericos y con más\n#     de 11 dígitos (o el número de dígitos que quieras).\n#   También se debe proponer una operación de finalización del programa.\n \n# ESTRUCTURA DE DATOS\n#-LAS LISTAS son mutables esto quiere decir que se pueden modificar\nlist_1 = [1,2,3,4,5] \nlist_2 = [6,7,8,9,10]\n\n#INSERTAR / BORRAR / ACTUALIZAR / ORDENAR\nlist_1.append(6) #Agrega un elemento al final de la lista\nlist_2.insert(0,5) #Agrega un elemento en la posición 0   \nlist_1.extend([7,8,9,10]) #Agrega varios elementos al final de la lista\nlist_2.append([11,12,13,14,15]) #Agrega una lista al final de la lista\nlist_1.pop() #Elimina el último elemento de la lista\nlist_2.remove(6) #Elimina el elemento 6 de la lista\nlist_1.clear() #Elimina todos los elementos de la lista\nlist_2[0] = 1 #Actualiza el elemento en la posición 0\nlist_1.sort() #Ordena la lista\nlist_2.reverse() #Invierte la lista\nlist_1.count(1) #Cuenta cuantas veces aparece el elemento 1 en la lista\n\n#-LAS TUPLAS son inmutables esto quiere decir que no se pueden modificar\ntuppla_1 = (1,2,3,4,5)\ntuppla_2 = (6,7,8,9,10)\n\n#INSERTAR / BORRAR / ACTUALIZAR / ORDENAR\ntuppla_1.count(1) #Cuenta cuantas veces aparece el elemento 1 en la tupla\ntuppla_2.index(6) #Devuelve el índice del elemento 6 en la tupla\ntuppla_1 + tuppla_2 #Concatena las tuplas\ntuppla_1 * 2 #Repite la tupla 2 veces\n\n#-LOS DICCIONARIOS son mutables \ndict_1 = {'nombre':'Juan', 'edad': 25, 'cursos': ['Python','Django','Flask']}\ndict_2 = {'nombre':'Maria', 'edad': 30, 'cursos': ['Python','Django','Flask']}\n\n#INSERTAR / BORRAR / ACTUALIZAR / ORDENAR\ndict_1['nombre'] = 'Juan Carlos' #Actualiza el valor de la clave nombre\ndict_2['cursos'].append('MongoDB') #Agrega un elemento a la lista de cursos \ndict_1.pop('edad') #Elimina la clave edad\ndict_2.popitem() #Elimina el último elemento insertado\ndict_1.clear() #Elimina todos los elementos del diccionario\ndict_2.update({'nombre':'Maria', 'edad': 30, 'cursos': ['Python','Django','Flask']}) #Actualiza el diccionario\ndict_1.keys() #Devuelve las claves del diccionario\ndict_2.values() #Devuelve los valores del diccionario\n    \n#-LOS CONJUNTOS son mutables\nconjunto_1 = {1,2,3,4,5}\nconjunto_2 = {6,7,8,9,10}\n\n#INSERTAR / BORRAR / ACTUALIZAR / ORDENAR\nconjunto_1.add(6) #Agrega un elemento al conjunto\nconjunto_2.remove(6) #Elimina el elemento 6 del conjunto\nconjunto_1.discard(6) #Elimina el elemento 6 del conjunto\nconjunto_2.pop() #Elimina un elemento aleatorio del conjunto\nconjunto_1.clear() #Elimina todos los elementos del conjunto\nconjunto_2.update([11,12,13,14,15]) #Agrega varios elementos al conjunto\n\n#-LAS COLAS son mutables\ncola_1 = [1,2,3,4,5]\ncola_2 = [6,7,8,9,10]\n\n#INSERTAR / BORRAR / ACTUALIZAR / ORDENAR\ncola_1.append(6) #Agrega un elemento al final de la cola\ncola_2.insert(0,5) #Agrega un elemento en la posición 0\ncola_1.pop(0) #Elimina el elemento en la posición 0\ncola_2.remove(6) #Elimina el elemento 6 de la cola\ncola_1.clear() #Elimina todos los elementos de la cola\ncola_2[0] = 1 #Actualiza el elemento en la posición 0   \n\n#-LAS PILAS son mutables\npila_1 = [1,2,3,4,5]\npila_2 = [6,7,8,9,10]\n\n#INSERTAR / BORRAR / ACTUALIZAR / ORDENAR\npila_1.append(6) #Agrega un elemento al final de la pila\npila_2.insert(0,5) #Agrega un elemento en la posición 0\npila_1.pop() #Elimina el último elemento de la pila\npila_2.pop(0) #Elimina el elemento en la posición 0\npila_1.clear() #Elimina todos los elementos de la pila\npila_2[0] = 1 #Actualiza el elemento en la posición 0\n\n#PROGRAMA DE AGENDA DE CONTACTOS    \nagenda = {} #Diccionario para almacenar los contactos\n\ndef insertar_contacto(): #Función para insertar un contacto\n    print('Insertar contacto:')\n    nombre = input('Nombre:') #Solicita el nombre del contacto   \n    telefono = input('Teléfono:') #Solicita el teléfono del contacto \n    if nombre in agenda: #Verifica si el contacto ya existe\n        print('El contacto ya existe')\n    else:\n        agenda[nombre] = telefono #Agrega el contacto a la agenda\n        print('Contacto agregado')\n\ndef buscar_contacto(): #Función para buscar un contacto\n    print('Buscar contacto:')\n    nombre = input('Nombre:') #Solicita el nombre del contacto\n    if nombre in agenda: #Verifica si el contacto existe\n        print('Teléfono:', agenda[nombre]) #Muestra el teléfono del contacto\n    else:\n        print('El contacto no existe') \n\ndef actualizar_contacto(): #Función para actualizar un contacto\n    print('Actualizar contacto:')\n    nombre = input('Nombre:') #Solicita el nombre del contacto\n    if nombre in agenda: #Verifica si el contacto existe\n        telefono = input('Teléfono:') #Solicita el nuevo teléfono del contacto\n        agenda[nombre] = telefono #Actualiza el teléfono del contacto\n        print('Contacto actualizado')\n    else:\n        print('El contacto no existe')\n        \ndef eliminar_contacto(): #Función para eliminar un contacto\n    print('Eliminar contacto:')\n    nombre = input('Nombre:') #Solicita el nombre del contacto\n    if nombre in agenda: #Verifica si el contacto existe\n        del agenda[nombre] #Elimina el contacto de la agenda\n        print('Contacto eliminado')\n    else:\n        print('El contacto no existe')        \n               \ndef menu(): #Función para mostrar el menú\n    print('Agenda de contactos')\n    print('1. Buscar contacto')\n    print('2. Insertar contacto')\n    print('3. Actualizar contacto')\n    print('4. Eliminar contacto')\n    print('5. Salir')\n    opcion = int(input('Seleccione una opción: '))  #Solicita la opción a realizar\n    return opcion\n    \n#funcion main\ndef main():\n    opcion = 0\n    while opcion != 5: #Muestra el menú hasta que se seleccione la opción 5\n        opcion = menu()\n        if opcion == 1:\n            buscar_contacto()\n        elif opcion == 2:\n            insertar_contacto()\n        elif opcion == 3:\n            actualizar_contacto()\n        elif opcion == 4:\n            eliminar_contacto()\n        elif opcion == 5:\n            print('Fin del programa')\n        else:\n            print('Opción no válida')  \n                     \nmain() #Ejecuta el programa\n            "
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/juanRCoder.py",
    "content": "'''Estructura de datos'''\n# Listas -> conjunto de elementos mutables, pueden cambiar sus datos.\nlista = ['1', 'a', '2', 'b', '3']\nlista.append('c')       # agrega 'c'\nlista.remove('2')       # remueve '2'\nlista[1] = 'A'          # actualiza 'a' por 'A'\nlista = sorted(lista)   # ordena de manera ascendente\n# ['1', '3', 'A', 'b', 'c']\n\n# Tupas -> estructura de datos inmutable, no se pueden cambiar sus elementos.\ntupla = (2001, 31, 31)\ntupla.count(31)         # cuenta elementos 31\ntupla.index(31)         # devuelve posicion\n\n# Conjuntos (set) estrcutura de datos mutables y con elementos unicos desordenados.\nconjunto = {1, 4, 10, 3, 11}\nconjunto.pop()          # elimina elemento aleatorio\nconjunto.add(9)         # agrega elemento al conjunto\nconjunto.remove(3)      # remueve elemento por el valor\n\n\n# Diccionarios (set) estructura de datos mutable, son de pares (c-v)\ndiciconario = {'name': 'juan', 'lastName': 'ramirez'}\ndiciconario.get('name', 'no encontrado') # buscar elemento por clave, si no mostrar segundo parametro por defecto\ndiciconario.keys()      # lista de claves\ndiciconario.values()    # lista de valores\ndiciconario.items()     # lista de claves y valores\n\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea una agenda de contactos por terminal.\n\n#  * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n#  *   y eliminación de contactos.\n\n#  * - Cada contacto debe tener un nombre y un número de teléfono.\n\n#  * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n#  *   y a continuación los datos necesarios para llevarla a cabo.\n\ncontactos = [['pepe', 123456789], ['maria', 987645321]]\nestatus = True\n\ndef buscar():\n    print('BUSCAR CONTACTO:')\n    estado = True\n    while estado:\n        print('Buscar por?\\n1.Nombre\\n2.Numero\\n3.Salir')\n        option_search = input('Opcion: ')\n        if option_search == '1':\n            nombre_find = input('Nombre del contacto: ')\n            print([contact for contact in contactos if contact[0] == nombre_find] or 'No encontrado')\n        elif option_search == '2':\n            nombre_find = input('Numero del contacto: ')\n            if nombre_find.isdigit(): \n                nombre_find = int(nombre_find)\n                print([contact for contact in contactos if contact[1] == option_search] or 'No encontrado')\n            else:\n                 print('Ingresar numero valido')\n        else:\n            estado = False\n            return \n\ndef agregar():\n    estatus_agregar = True\n    \n    while estatus_agregar:\n        print('AGREGAR CONTACTO:\\n1.Agregar Contacto\\n2.Salir')\n        option_add = int(input('opcion: '))\n    \n        if option_add == 1:\n            name = input('Nombre del contacto: ')\n            num_contact = input('Número del contacto: ')\n            contactos.append([name, num_contact])\n            print('Contacto Agregado')\n        elif option_add == 2:\n            estatus_agregar = False\n    return\n    \ndef update():\n    estatus_update = True\n    while estatus_update:\n        print('ACTUALIZAR CONTACTOS:')\n        print('1.Lista Contactos\\n2.Nombre\\n3.Numero\\n4.Salir')\n        opcion_update = input('opcion: ')\n            \n        if opcion_update == '1':\n            print(contactos);\n            \n        elif opcion_update == '2':\n            name_update = input('Nombre del contacto: ')\n            for contacto in contactos:\n                if contacto[0] == name_update:\n                    name_update = input(f'Actualizar {name_update} por: ')\n                    contactos[0][0] = name_update\n            print('Nombre no encontrado')\n        \n        elif opcion_update == '3':\n            num_update = int(input('Numero del contacto: '))\n            for contacto in contactos:\n                if contacto[1] == num_update:\n                    num_update = input(f'Actualizar {num_update} por: ')\n                    contactos[0][1] = num_update\n            print('Numero no encontrado')\n            \n        else:\n            estatus_update = False\n    return \n\ndef delete():\n    estatus_delete = True\n    while estatus_delete:\n        print('ELIMINAR CONTACTOS:')\n        print('1.Lista Contactos\\n2.Eliminar\\n3.Salir')\n        opcion_update = input('opcion: ')\n        \n        if opcion_update == '1':\n            print(contactos);\n            \n        elif opcion_update == '2':\n            name_delete = input('Nombre del contacto: ')\n            encontrado = False\n            for contacto in contactos:\n                if contacto[0] == name_delete:\n                    print(f'Eliminar a {name_delete} de tus contactos? 1.SI 2.NO')\n                    name_delete = input('opcion: ')\n                    if name_delete == '1':\n                        contactos.remove(contacto)\n                        print('Contacto eliminado')\n                    encontrado = True\n                    break\n            \n            if not encontrado:\n                print('Contacto no encontrado')\n\n        else:\n            estatus_delete = False\n    return \n    \n                 \nwhile estatus:\n    print('AGENDA DE CONTACTOS:')\n    print('Operaciones Principales: \\n1. Buscar Contacto\\n2. Agregar Contacto\\n3. Actualizar Contacto\\n4. Eliminar Contacto\\n5. Cerrar Programa')\n    opcion = int(input('Opcion: '))\n\n    if opcion == 1:\n        buscar()\n    elif opcion == 2:\n        agregar()\n    elif opcion == 3:\n        update()\n    elif opcion == 4:\n        delete()\n    elif opcion == 5:\n        estatus = False"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/juanchernandezdev.py",
    "content": "### Python Data Structures ###\n\n#! List\n\nmy_list = [1, 6, 3, 10, 5]\nprint(my_list)\n\nmy_str = 'hello'\nprint(list(my_str))\n\n# Append\nmy_list.append(8)\nprint(my_list)\n\n# Remove\nmy_list.remove(8)\nprint(my_list)\n\n# Insert\nmy_list.insert(2, 50)\nprint(my_list)\n\n# Sort\nmy_list.sort()\nprint(my_list)\n\n#! Dictionary\n\nmy_dict = { 'name': 'John', 'lastname': 'Doe', 'age': 44}\nprint(my_dict)\n\n# Add\nmy_dict['country'] = 'Norway'\nprint(my_dict)\n\n# Remove\nmy_dict.pop('name')\nprint(my_dict)\n\n# Update\nmy_dict['lastname'] = 'new lastname'\nprint(my_dict)\n\n# Order\nprint(sorted(my_dict.keys()))\n\n#! Tuple\n\nmy_tuple = (1, 2, 3, 8, 7, 4)\nprint(my_tuple)\n\n#* Since tuples are immutable you can't add or remove items.\n\n# Order\nprint(sorted(my_tuple))\n\n#! Set\nmy_set = {1, 2, 3, 5, 8, 12, 3, 3, 4, 5} # The 3 will be only one time since sets don't allow duplicated items.\nprint(my_set)\n\n# Add\nmy_set.add(50)\nprint(my_set)\n\n# Remove\nmy_set.remove(4)\nprint(my_set)\n\n# Update\nmy_second_set = {100, 200, 500}\nmy_set.update(my_second_set)\nprint(my_set)\n\n# Order\nprint(sorted(my_set))\n\n#! Optional Challenge\nprint('---Optional Challenge---')\n\n# Start the program\n# Give the user a set of option, to insert, search, update, or remove a contact\n# Ask the user for the data corresponding to the operation that was selected\n# Execute the selected operation\n# Verify that telephone number data type is numeric and contains no more than 11 digits\n# Notify the user if the operation was successful or not\n# Ask the user to add another contact or to end the programm\n\ncontacts_list = []\nid = 1\n\nuser_start = input('Please type start to run the program: ')\nrun_program = False\n\nif user_start == 'start':\n  run_program = True\n  \ndef search_contact(contact_name, list):\n    for contact in list:\n      if contact_name == contact['contact_name'].lower():\n        return contact\n      \ndef update_contact(contact_name, list):\n    for contact in list:\n      index = list.index(contact)\n      if contact_name == list[index]['contact_name'].lower():\n        print(list[index]['contact_name'])\n        new_name = input('Type the new name for your contact: ').lower()\n        new_phone = input('Type the new phone for your contact: ').lower()\n        list[index]['contact_name'] = new_name\n        list[index]['contact_phone'] = new_phone\n        print(f'Contact updated: {list[index]['contact_name']} - {list[index]['contact_phone']}')\n      \ndef delete_contact(contact_name, list):\n    for contact in list:\n      index = list.index(contact)\n      if contact_name == list[index]['contact_name'].lower():\n        print(list[index]['contact_name'])\n        del list[index]\n        print('Contact deleted')\n        \ndef show_contacts(list):\n    if len(list) == 0:\n      print('Your contact list is empty')\n    \n    for contact in list:\n      print(f'{contact['contact_name']} - {contact['contact_phone']}')\n  \n  \nwhile run_program == True:\n  print('----Choices----')\n  user_choice = input('a: Add contact\\nb: Search contact\\nc: Update contact\\nd: Remove contact\\ne: Show all contacts\\nType the corresponding letter to perform an action or type \"exit\" to end the program: ').lower()\n  \n  if user_choice== 'exit':\n    run_program = False\n  \n  # Add Contact\n  \n  if user_choice == 'a':\n    print('----New Contact----')\n    contact_name: str = input('Enter your contact name: ').title()\n    contact_phone: str = input('Enter your contact phone number: ')\n    \n    if not contact_phone.isnumeric():\n      print('Phone number should contain only numbers!')\n    \n    if len(contact_phone) > 11:\n      print('Phone number should contain only 11 digits or less')\n    else:\n      new_contact = {'id': id, 'contact_name': contact_name, 'contact_phone': contact_phone }\n      id += 1\n      contacts_list.append(new_contact)\n    \n  # Search Contact\n      \n  if user_choice == 'b':\n    print('----Search Contact----')\n    contact_name: str = input('Type the name of the contact you want to search: ').lower()\n    contact = search_contact(contact_name, contacts_list)\n    print(f'Contact name: {contact['contact_name'].title()}\\nContact phone number: {contact['contact_phone']}')\n  \n  # Update Contact\n  \n  if user_choice == 'c':\n    print('----Search Update----')\n    contact_name: str = input('Type the name of the contact you want to update: ').lower()\n    update_contact(contact_name, contacts_list)\n  \n  # Remove Contact\n    \n  if user_choice == 'd':\n    print('----Remove Contact----')\n    contact_name: str = input('Type the name of the user you want to remove: ').lower()\n    delete_contact(contact_name, contacts_list)\n  \n  # Show Contacts\n      \n  if user_choice == 'e':\n    print('----Contacts----')\n    show_contacts(contacts_list)\n  "
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/juandaherrera.py",
    "content": "'''\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n *\n'''\n\nfrom dataclasses import dataclass, field\nfrom typing import Callable, Optional, Union\n\nVALID_OPERATIONS = (\"1\", \"2\", \"3\", \"4\", \"5\", \"exit\")\n\n\n@dataclass()\nclass Contact:\n    \"\"\"Representa un contacto con nombre y número de teléfono.\n\n    Attributes:\n        name (str): El nombre del contacto.\n        number (int): El número telefónico del contacto.\n\n    Raises:\n        ValueError: Si el número telefónico tiene más de 11 dígitos.\n    \"\"\"\n\n    name: str\n    number: int\n\n    def __post_init__(self):\n        \"\"\"Verifica la validez del número telefónico al inicializar el contacto.\"\"\"\n        if len(str(self.number)) > 11:\n            raise ValueError(\"El número telefónico no puede tener más de 11 dígitos.\")\n\n\n@dataclass()\nclass Directory:\n    \"\"\"Representa una agenda de contactos.\n\n    Attributes:\n        contacts (list[Contact]): Una lista de Contact que representa la agenda.\n    \"\"\"\n\n    contacts: list[Contact] = field(default_factory=list)\n\n    def search_contact(self, name: str, return_index: bool = False) -> Optional[Union[Contact, int]]:\n        \"\"\"Busca un contacto por nombre.\n\n        Args:\n            name (str): El nombre del contacto a buscar.\n            return_index (bool): Si es True, devuelve el índice del contacto en lugar del contacto mismo.\n\n        Returns:\n            Optional[Union[Contact, int]]: El contacto o su índice si se encuentra, None en caso contrario.\n        \"\"\"\n        if self.contact_exists(name):\n            for index, contact in enumerate(self.contacts):\n                if contact.name.lower() == name.lower():\n                    return contact if not return_index else index\n        else:\n            return None\n\n    def insert_contact(self, new_contact: Contact) -> None:\n        \"\"\"Inserta un nuevo contacto en la agenda.\n\n        Args:\n            new_contact (Contact): El contacto a agregar.\n\n        Prints:\n            Mensaje de éxito o error.\n        \"\"\"\n        if self.contact_exists(new_contact.name):\n            print(f\"Contacto con el nombre {new_contact.name} ya existe.\")\n        else:\n            try:\n                self.contacts.append(new_contact)\n                print(f\"{new_contact.name} fue agregado con éxito en la agenda.\")\n            except Exception as e:\n                print(e)\n\n    def update_contact(self, modified_contact: Contact) -> None:\n        \"\"\"Actualiza un contacto existente.\n\n        Args:\n            modified_contact (Contact): El contacto con la información actualizada.\n\n        Prints:\n            Mensaje de éxito, error o solicitud de confirmación para agregar el contacto si no existe.\n        \"\"\"\n        contact_index = self.search_contact(modified_contact.name, return_index=True)\n        if contact_index:\n            self.contacts[contact_index] = modified_contact\n            print(f\"El contacto {modified_contact.name} fue actualizado con éxito.\")\n        else:\n            print(\n                f\"El contacto {modified_contact.name} no existe en la agenda.\",\n                \"\\n\",\n                \"Desea agregarlo? (Si/No)\",\n            )\n            response = input()\n            if response.lower() == \"si\":\n                self.insert_contact(modified_contact)\n\n    def delete_contact(self, name: str) -> None:\n        \"\"\"Elimina un contacto de la agenda por nombre.\n\n        Args:\n            name (str): El nombre del contacto a eliminar.\n\n        Prints:\n            Mensaje de éxito o error.\n        \"\"\"\n        contact = self.search_contact(name)\n        if contact:\n            self.contacts.remove(contact)\n            print(f\"El contacto {name} fue eliminado con éxito\")\n        else:\n            print(f\"El contacto {name} no existe en la agenda.\")\n\n    def display_contacts(self):\n        \"\"\"Muestra todos los contactos de la agenda.\"\"\"\n        if self.contacts:\n            for contact in self.contacts:\n                print(f\"Nombre: {contact.name}, Número: {contact.number}\")\n        else:\n            print(\"No hay contactos en la agenda.\")\n\n    def contact_exists(self, name: str) -> bool:\n        \"\"\"Verifica si existe un contacto con un determinado nombre.\n\n        Args:\n            name (str): El nombre del contacto a verificar.\n\n        Returns:\n            bool: True si el contacto existe, False en caso contrario.\n        \"\"\"\n        return any(contact.name.lower() == name.lower() for contact in self.contacts)\n\n\n# Funciones para solicitar entrada del usuario\ndef request_input(prompt: str, validation: Optional[Callable[[str], bool]] = None) -> str:\n    \"\"\"Solicita entrada al usuario hasta que cumpla con la validación.\n\n    Args:\n        prompt (str): El mensaje a mostrar al usuario.\n        validation (Optional[Callable[[str], bool]]): La función de validación que debe pasar la entrada.\n\n    Returns:\n        str: La entrada del usuario que pasó la validación.\n    \"\"\"\n    while True:\n        user_input = input(prompt)\n        if not validation or validation(user_input):\n            return user_input\n\n\ndef validate_operation(operation: str) -> bool:\n    \"\"\"Valida si la operación ingresada es válida.\n\n    Args:\n        operation (str): La operación a validar.\n\n    Returns:\n        bool: True si la operación es válida, False en caso contrario.\n\n    Prints:\n        Mensaje pidiendo una operación válida si la entrada es inválida.\n    \"\"\"\n    if operation.lower() in VALID_OPERATIONS:\n        return True\n    print(\"Por favor ingrese una operación válida.\")\n    return False\n\n\ndef validate_number(number: str) -> bool:\n    \"\"\"Valida si el número ingresado es válido (numérico y no más de 11 dígitos).\n\n    Args:\n        number (str): El número a validar.\n\n    Returns:\n        bool: True si el número es válido, False en caso contrario.\n\n    Prints:\n        Mensaje pidiendo un número válido si la entrada es inválida.\n    \"\"\"\n    try:\n        number = int(number)\n        return True\n    except ValueError:\n        print(\"Por favor ingrese un número válido.\")\n        return False\n\n\ndef main():\n    directory = Directory()\n    while True:\n        print(\"---------------------------------------------------------------------\")\n        print(\"Operaciones posibles:\")\n        print(\n            \"1. Buscar contacto\",\n            \"2. Agregar contacto\",\n            \"3. Actualizar contacto\",\n            \"4. Eliminar contacto\",\n            \"5. Mostrar todos los contactos\",\n            sep=\"\\n\",\n        )\n        print(\"Si desea salir de la aplicación escriba la palabra 'Exit'\")\n        operation = request_input(\"Digite la opción: \", validate_operation)\n        print(\"************************************************\")\n\n        if operation.lower() == \"exit\":\n            break\n\n        if operation == \"1\":\n            name = request_input(\"Ingrese el nombre que desea buscar: \")\n            contact = directory.search_contact(name)\n            contact_print = contact if contact else f\"El contacto con número {name} no existe en la agenda.\"\n            print(contact_print)\n        elif operation == \"2\":\n            name = request_input(\"Ingrese el nombre del contacto: \")\n            number = request_input(\"Ingrese el número del contacto: \", validate_number)\n            try:\n                contact = Contact(name=name, number=int(number))\n                directory.insert_contact(contact)\n            except Exception as e:\n                print(e)\n        elif operation == \"3\":\n            name = request_input(\"Ingrese el nombre del contacto que va a actualizar: \")\n            number = request_input(\"Ingrese el nuevo número del contacto: \", validate_number)\n            try:\n                contact = Contact(name=name, number=int(number))\n                directory.update_contact(contact)\n            except Exception as e:\n                print(e)\n        elif operation == \"4\":\n            try:\n                name = request_input(\"Ingrese el nombre del contacto que desea eliminar: \")\n                directory.delete_contact(name=name)\n            except Exception as e:\n                print(e)\n        elif operation == \"5\":\n            directory.display_contacts()\n\n        print(\"************************************************\")\n        next_iter = request_input(\"Desea continuar? (si, no): \", lambda choice: choice.lower() in (\"si\", \"no\", \"exit\"))\n        if next_iter in (\"no\", \"exit\"):\n            break\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/juanmax2.py",
    "content": "\"\"\"\nEstructuras de datos\n\"\"\"\n# Lista\nmy_list = [\"Juanma\", \"Maria\", \"David\", \"Adri\"]\nprint(my_list)\nprint(type(my_list))\n# Añadir nuevo dato al final de la lista\nmy_list.append(\"Carlos\")\nprint(my_list)\n\n# Borrar dato de la lista\nmy_list.remove(\"Adri\")\nprint(my_list)\n\n# Actualizar un dato en la lista\nmy_list[2] = \"Adri\"\nprint(my_list)\n\n# Ordenar la lista\nmy_list.sort() # Por defecto lo hace de forma alfabetica o ascendente\nprint(my_list)\n\n# Tuplas\n# Las tuplas son inmutables con lo cual solo se puede acceder a ella\n# para ver sus datos\nmy_tupla = (\"Juanma\", \"juanmax2\", \"32\")\nprint(my_tupla)\nprint(type(my_tupla))\n# Ordenar una tupla\nmy_tupla = tuple(sorted(my_tupla))\n# Hay que especificar tuple para hacer el sorted porque sino\n# devolveria una lista\nprint(my_tupla)\n\n# Sets (conjuntos)\n# Son estructuras desordenadas y no se puede acceder por indice\n# No albergan datos iguales entre si (\"Juanma\", \"Juanma\")\nmy_set = {\"Juanma\", \"juanmax2\", \"32\"}\nprint(my_set)\nprint(type(my_set))\n# Añadir datos\nmy_set.add(\"batman\")\nprint(my_set)\n\n# Eliminar datos\nmy_set.remove(\"32\") # Sin indice, con el valor\nprint(my_set)\n\n# El set no se puede ordenar porque por defecto no hay indices\n\n# Diccionario\n\nmy_dict = {\n    \"nombre\" : \"Juanma\",\n    \"edad\" : 32,\n    \"profesion\" : \"estudiante\"\n    }\nprint(my_dict)\nprint(type(my_dict))\n\n# Insertar datos\n# Hay que acceder por la clave\nmy_dict[\"email\"] = \"juanma@gmail.com\"\nprint(my_dict)\n\n# Actualizar datos\nmy_dict[\"edad\"] = 33\nprint(my_dict)\n\n# Borrar datos\ndel my_dict[\"email\"]\nprint(my_dict)\n\n# Ordenar\nmy_dict = dict(sorted(my_dict.items()))\nprint(my_dict)\n\n\"\"\"\nEjercicio opcional\n* Crea una agenda de contactos por terminal.\nDebes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\nCada contacto debe tener un nombre y un número de teléfono.\nEl programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\nlos datos necesarios para llevarla a cabo.\nEl programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n(o el número de dígitos que quieras)\nTambién se debe proponer una operación de finalización del programa.\n\"\"\"\nmy_agenda = {}\n\ndef menu_opciones():\n    \"\"\"Esta función se encarga de mostrar el menu de opciones por pantalla\"\"\"\n    print(\"Bienvenido usuario!\")\n    print(\"-------------------\")\n    print(\"-------------------\")\n    print(\n        \"\"\"\n        1 - Añadir contacto.\n        2 - Buscar contacto.\n        3 - Eliminación de contacto.\n        4 - Actualización de contacto.\n        5 - Mostrar lista de contactos.\n        6 - Salir del programa.\n        \"\"\"\n        )\n    print(\"-------------------\")\n    print(\"-------------------\")\n    \ndef recibir_opcion():\n    \"\"\"Esta funcion se encarga de recibir la opcion que queremos y retornarla\"\"\"\n    num = int(input(\"Por favor seleccione una opción: \"))\n    return num\n\ndef validar_numero(nombre):\n    \"\"\"Esta funcion se encarga de recibir un nombre y validar si el numero de telefono que\n    introducimos es correcto, devuelve el dato a nuestra agenda\"\"\"\n    \n    numero = input(\"Introduce el número de telefono: \")\n    if numero.isdigit() and len(numero) > 0 and len(numero) <= 11:\n        my_agenda[nombre] = numero\n    else: \n        print(\"Numero no valido\")\n        \ndef buscar_contacto():\n    \"\"\"Esta función se encarga de buscar un contacto en nuestra agenda\"\"\"\n    \n    nombre = input(\"Introduce el nombre de la persona: \")\n    if nombre in my_agenda:\n        print(f\"El contacto {nombre} tiene el número {my_agenda[nombre]}\")       \n    else:\n        print(f\"El contacto {nombre} no encontrado\")\n        \ndef añadir_contacto():\n    \"\"\"Esta función se encarga de añadir contactos a nuestra agenda\"\"\"\n    \n    nombre = input(\"Introduce el nombre del contacto: \")\n    validar_numero(nombre)\n\ndef eliminar_contacto():\n    \"\"\"Esta función se encarga de eliminar contactos existentes en nuestra agenda\"\"\"\n    \n    nombre = input(\"Introduce el nombre del contacto que quieres eliminar: \")\n    if nombre in my_agenda:\n        del my_agenda[nombre]\n    else:\n        print(f\"El contacto {nombre} no existe\")\n    \ndef actualizar_contacto():\n    \"\"\"Esta función se encarga de actualizar contactos de nuestra agenda\"\"\"\n    \n    nombre = input(\"Introduce el nombre del contacto a actualizar: \")\n    if nombre in my_agenda:\n        validar_numero(nombre)\n        \ndef mostrar_contactos():\n    \"\"\"Esta funcón se encarga de mostrar los contactos de nuestra agenda\"\"\"\n    \n    for nombre, numero in my_agenda.items():\n        print(f\"Nombre : {nombre} Número : {numero} \")\n        \n\ndef salir_programa():\n    \"\"\"Esta funcón muestra que estamos cerrando el programa\"\"\"\n    \n    print(\"Cerrando programa...\")\n    print(\"Fin de la ejecución\")\n    return continuar == False\n\n\n\n# Caso de uso\ncontinuar = True\nwhile continuar == True:\n    menu_opciones()\n    opcion = recibir_opcion()\n    if opcion == 1:\n        añadir_contacto()\n    elif opcion == 2:\n        buscar_contacto()\n    elif opcion == 3:\n        eliminar_contacto()\n    elif opcion == 4:\n        actualizar_contacto()\n    elif opcion == 5:\n        mostrar_contactos()\n    elif opcion == 6:\n        salir_programa()\n        continuar = False\n    else:\n        print(\"No es una opción valida\")\n        "
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/juanppdev.py",
    "content": "# Listas\n\n## Creación\nmi_lista = [1, 2, 3, 4, 5]\n\n## Inserción\nmi_lista.append(6) # Agrega el elemento 6 al final de la lista\nmi_lista.insert(2, 10) # Inserta el elemento 10 en la posición 2\n\n## Borrado\nmi_lista.pop() # Elimina y devuelve el último elemento de la lista\nmi_lista.pop(2) # Elimina y devuelve el elemento en la posición 2\ndel mi_lista[1] # Elimina el elemento en la posición 1\n\n## Actualización\nmi_lista[0] = 20 # Actualiza el valor del elemento en la posición 0 a 20\n\n## Ordenación\nmi_lista.sort() # Ordena los elementos de la lista de menor a mayor\nmi_lista.sort(reverse=True) # Ordena los elementos de la lista de mayor a menor\n\n# Tuplas\n\n## Creación\nmi_tupla = (1, 2, 3, 4, 5)\n\n\"\"\"\n    Inserción y borrado:\n\nComo las tuplas son inmutables, no se pueden realizar operaciones de inserción o borrado directamente. Sin embargo, se pueden crear nuevas tuplas a partir de las existentes.\n\nActualización:\n\nComo las tuplas son inmutables, no se pueden realizar operaciones de actualización directamente.\n\nOrdenación:\n\nComo las tuplas son ordenadas, se pueden ordenar de la misma manera que las listas.\n\"\"\"\n\n# Conjuntos\n\n## Creación\nmi_conjunto = {1, 2, 3, 4, 5}\n\n## Inserción\nmi_conjunto.add(6) # Agrega el elemento 6 al conjunto\n\n## Borrado\nmi_conjunto.remove(3) # Elimina el elemento 3 del conjunto\n\n\"\"\"\n    Actualización:\n\nNo se pueden realizar operaciones de actualización directamente en los conjuntos, ya que solo pueden contener elementos únicos.\n\nOrdenación:\n\nLos conjuntos no están ordenados, pero se pueden convertir en listas y ordenarlas.\n\"\"\"\n\n# Diccionarios\n\n## Creación\nmi_diccionario = {'clave1': 1, 'clave2': 2, 'clave3': 3}\n\n## Inserción\nmi_diccionario['clave4'] = 4 # Agrega la clave-valor ('clave4', 4) al diccionario\n\n## Borrado\ndel mi_diccionario['clave2'] # Elimina la clave-valor ('clave2', 2) del diccionario\n\n## Actualización\nmi_diccionario['clave1'] = 20 # Actualiza el valor de la clave 'clave1' a 20\n\n\"\"\"\n    Ordenación:\n\nLos diccionarios no están ordenados, pero se pueden convertir en listas de tuplas y ordenarlas.\n\"\"\"\n\n## Ejercicio Extra\n# Agenda de contactos\n\nimport json\n\ndef cargar_contactos():\n    \"\"\"Carga los contactos desde un archivo JSON.\"\"\"\n    try:\n        with open(\"contactos.json\", \"r\") as f:\n            contactos = json.load(f)\n    except FileNotFoundError:\n        contactos = {}\n    return contactos\n\ndef guardar_contactos(contactos):\n    \"\"\"Guarda los contactos en un archivo JSON.\"\"\"\n    with open(\"contactos.json\", \"w\") as f:\n        json.dump(contactos, f)\n\ndef agregar_contacto():\n    \"\"\"Agrega un nuevo contacto a la agenda.\"\"\"\n    nombre = input(\"Nombre del contacto a agregar: \")\n    if nombre not in contactos:\n        telefono = input(\"Número de teléfono del contacto: \")\n        contactos[nombre] = telefono\n        guardar_contactos(contactos)\n        print(f\"\\nSe ha agregado el contacto {nombre} a la agenda.\")\n    else:\n        print(f\"\\nEl contacto {nombre} ya existe en la agenda.\")\n\ndef buscar_contacto():\n    \"\"\"Busca un contacto por su nombre y muestra su número de teléfono.\"\"\"\n    nombre = input(\"Nombre del contacto a buscar (o deje en blanco para mostrar todos los contactos): \")\n    if nombre == \"\":\n        print(\"\\nNombre\\t\\tTeléfono\")\n        print(\"----------------------------------\")\n        for nombre, telefono in contactos.items():\n            print(f\"{nombre}\\t\\t{telefono}\")\n    elif nombre in contactos:\n        print(f\"\\nEl número de teléfono de {nombre} es {contactos[nombre]}\")\n    else:\n        print(f\"\\nNo se encontró ningún contacto con el nombre {nombre}.\")\n\ndef actualizar_contacto():\n    \"\"\"Actualiza el número de teléfono de un contacto existente.\"\"\"\n    nombre = input(\"Nombre del contacto a actualizar: \")\n    if nombre in contactos:\n        telefono = input(\"Nuevo número de teléfono del contacto: \")\n        contactos[nombre] = telefono\n        guardar_contactos(contactos)\n        print(f\"\\nSe ha actualizado el contacto {nombre} en la agenda.\")\n    else:\n        print(f\"\\nNo se encontró ningún contacto con el nombre {nombre}.\")\n\ndef eliminar_contacto():\n    \"\"\"Elimina un contacto existente.\"\"\"\n    nombre = input(\"Nombre del contacto a eliminar: \")\n    if nombre in contactos:\n        del contactos[nombre]\n        guardar_contactos(contactos)\n        print(f\"\\nSe ha eliminado el contacto {nombre} de la agenda.\")\n    else:\n        print(f\"\\nNo se encontró ningún contacto con el nombre {nombre}.\")\n\ncontactos = cargar_contactos()\n\nwhile True:\n    print(\"\\nAgenda de contactos\")\n    print(\"----------------------------------\")\n    print(\"1. Agregar contacto\")\n    print(\"2. Buscar contacto\")\n    print(\"3. Actualizar contacto\")\n    print(\"4. Eliminar contacto\")\n    print(\"5. Salir\")\n    opcion = int(input(\"Seleccione una opción: \"))\n    if opcion == 1:\n        agregar_contacto()\n    elif opcion == 2:\n        buscar_contacto()\n    elif opcion == 3:\n        actualizar_contacto()\n    elif opcion == 4:\n        eliminar_contacto()\n    elif opcion == 5:\n        break\n    else:\n        print(\"Opción inválida. Intente de nuevo.\")\n\nguardar_contactos(contactos)"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/julianbuitragocharry-dev.py",
    "content": "\"\"\" ESTRUCTURAS \"\"\"\n# LISTAS\nlenguages = ['C', 'Python', 'C#', 'Java', 'JavaScript', 'Visual Basic']\nprint(lenguages[0]) # Access \nprint(lenguages[1])\n\nlenguages.insert(1, 'C++') # Insertion\nprint(lenguages)\nlenguages.append('Cobol')\n\nlenguages.pop() # Remove\nprint(lenguages)\nlenguages.remove('Cobol') \nprint(lenguages)\n\nlenguages[1] = 'C--' # Update\nprint(lenguages)\n\nlenguages.reverse() # Ordering \nprint(lenguages)\nlenguages.sort()\nprint(lenguages)\n\nprint(type(lenguages))\n\n# TUPLAS\nframeworks = ('Angular', 'React', 'Svelte', 'Vue')\nprint(frameworks[0]) # Access\nprint(frameworks[1]) \n\nframeworks = tuple(sorted(frameworks)) # Ordering\nprint(frameworks)\n\nprint(type(frameworks)) \n\n# CONJUNTOS\nme = {'Julian', 'Enrique', 'juls@developer.com', 17}\nprint(me)\n\nme.add('u20212001@university.edu.co') # Insertion\nprint(me)\n\nme.remove('u20212001@university.edu.co') # Remove\nprint(me)\n\nprint(type(me))\n\n# DICCIONARIOS\nme = {\n    'name' : 'Julien',\n    'surname' : 'Enrique',\n    'alias' : 'Kike',\n    'age' : 17,\n    'developer' : ['fronted', 'backend']\n}\n\nprint(me['name']) # Access\n\nme['name'] = 'Julian' # Insertion\nprint(me)\n\ndel me['alias'] # remove\nprint(me)\n\nme['age'] = 18 # Update\nprint(me)\n\nme = dict(sorted(me.items())) # Ordering\n\nprint(type(me))\ndef agenda():\n    agenda = {}\n    \n    def ingresar_contacto(nombre):\n        numero = input('Ingresa el numero de telefono:\\n')\n        if numero.isdigit() and (len(numero) <= 11) and (len(numero) > 0):\n            agenda[nombre] = numero\n        else:\n            print('Ingresa un número máximo de 11 dígitos\\n')\n\n    while True:\n        choice = input(\"\"\"\\nOperación a realizar en la agenda de contactos:\n        1. Insertar\n        2. Buscar\n        3. Actualizar \n        4. Eliminar\n        5. Salir\\n\n        \"\"\")\n\n        if choice == '1':\n            name_contact = input('\\nIngresa el nombre del contacto:\\n')\n            ingresar_contacto(name_contact)\n        elif choice == '2':\n            name_contact = input('\\nIngresa el contacto a buscar:\\n')\n            if name_contact in agenda:\n                print(f'\\nEl número de teléfono de {name_contact} es: {agenda[name_contact]}')\n            else:\n                print(f'\\nEl contacto {name_contact} no existe en la agenda')\n        elif choice == '3':\n            name_contact = input('\\nIngresa el nombre del contacto a actualizar:\\n')\n            if name_contact in agenda:\n                ingresar_contacto(name_contact)\n            else:\n                print(f'\\nEl contacto {name_contact} proporcionado no existe')\n        elif choice == '4':\n            name_contact = input('\\nIngresa el nombre del contacto a eliminar:\\n')\n            if name_contact in agenda:\n                del agenda[name_contact]\n                print(f'\\nEl contacto {name_contact} ha sido eliminado de la agenda')\n            else:\n                print(f'\\nEl contacto {name_contact} proporcionado no existe')\n        elif choice == '5':\n            break\n        else:\n            print('\\nElige una opción válida\\n')\n\nagenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/juserdev.py",
    "content": "\"\"\"\n  * EJERCICIO:\n  * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n  * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n  *\n  * DIFICULTAD EXTRA (opcional):\n  * Crea una agenda de contactos por terminal.\n  * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n  * - Cada contacto debe tener un nombre y un número de teléfono.\n  * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n  *   los datos necesarios para llevarla a cabo.\n  * - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n  *   (o el número de dígitos que quieras)\n  * - También se debe proponer una operación de finalización del programa.\n\"\"\"\n\n### lsita ###\n\n\"\"\" my_list = [\"Juan\", \"Rodriguez\", \"34\", \"juserdev\"]\nprint(my_list)\n\nmy_list.append(\"laura\")\nprint(my_list)\n\nmy_list.remove(\"laura\")\nprint(my_list)\n\nmy_list_copy = my_list.copy() # Esta funcion crea un acopia de la variable original\nmy_list_copy.append(\"laura\")\nprint(my_list_copy)\n\nprint(my_list.count(\"hola\")) # esta funcion cuanta cuntas veces se repite lo que esta dentro de los parentesis \nprint(my_list.count(\"34\"))\n\nmy_list.pop() # Elemina el ultimo indice de la lista\nprint(my_list)\n\nmy_list.remove(\"Juan\") # Elimna el elemento que tenga escrito dentro de los paretesis\nprint(my_list)\n\nmy_list.reverse() # devuele la listra de tras pa lante\nprint(my_list)\n\nprint(my_list[0]) # selecciona el valor en el indice declarado entre corchetes\n\nedad, nombre = my_list # destructurar\n\nprint(edad)\nprint(nombre)\n\nprint(my_list)\n\nmy_list.append(\"juan\")\nprint(my_list)\n\nmy_list.insert( 2, \"juserdev\") # agrega un valor en la posicion indicada\nprint(my_list)\n\nmy_list.sort() # ordena\nprint(my_list)\n\nmy_list.clear() # con esta funcion limpa la lista\nprint(my_list)\n\n### Tupla ###\n\nmy_tupla = (34, 1.70, \"juan\", \"rodriguez\", \"juan\")\nprint(my_tupla)\n\nprint(my_tupla.index(34)) # Busca y nos devuelve el indice del valor dentro de los parentesis\nprint(my_tupla.count(\"juan\"))\nmy_tupla = list(my_tupla) # lo transforme en lista para poder modificarlo\nmy_tupla[4] = \"juserdev\"\nprint(type(my_tupla))\nprint(my_tupla)\nmy_tupla = tuple(my_tupla) # lo transforme en tupla nuevamente\nprint(type(my_tupla))\nprint(my_tupla)\n\n### Set\n\nmy_set = {\"juan\", \"rodriguez\", 34, 1.70}\nprint(type(my_set))\nprint(my_set) # muestra el contenido en desorden\n\nmy_set.add(\"juserdev\") # Agrega contenido al set\nprint(my_set) \nprint(len(my_set)) # esta funcion sirve con todos para contantar la cantidad de elementos que hay\n\nprint(\"juserdev\" in my_set) # confima si existe el elemento #-> true\nprint(\"juserdeve\" in my_set) # confima si existe el elemento #-> false\n\nmy_set.remove(\"juserdev\")\nprint(my_set)\n\nmy_other_set = {\"juserdev\", \"colombia\"}\n\nmy_set = my_set.union(my_other_set).union({\"python\"})\nprint(my_set)\n\n# my_set.clear() # -> elimina el contenido del set\n# print(my_set) \n# del my_set # -> borra el set\n\n\n### dictcionary\n\nmy_dict = {\n  \"nombre\": \"juan\",\n  \"apellido\": \"rodirguez\",\n  \"edad\": 34,\n  \"lenguajes\": {\n    \"python\",\n    \"typescript\",\n    \"css\"\n  }\n}\n\nprint(my_dict)\nprint(my_dict[\"nombre\"])\n\nmy_dict[\"nombre\"] = \"Sebastian\"\nprint(my_dict)\nprint(my_dict[\"nombre\"])\n# print(my_dict[1])\n\nmy_dict[\"calle\"] = \"monda\" # agregue una clave llamada calle y le puse de nombre monda\nprint(my_dict)\n\nprint( \"Sebastian\" in my_dict)\nprint( \"nombre\" in my_dict) # Busca por clave y no por valor\n\ndel my_dict[\"calle\"] # Borra un elemento especifico\nprint(my_dict)\n\nprint(my_dict.items())\nprint(my_dict.keys())\nprint(my_dict.values()) \"\"\"\n\n\n### Dificultad extra\n\ndef my_agenda():\n  \n  agenda = {}\n\n  def insert_contact():\n    phone = input(\"Escriba el numero de contacto: \")\n    if phone.isdigit() and len(phone) > 0 and len(phone) <= 11:\n      agenda[name] = phone\n    else:\n      print(\"Debes introducir un numero de telefono con maximo 11 digitos\")\n    \n  while True:\n\n    print(\"\")\n    print(\"1. Buscar contacto\")\n    print(\"2. Insertar contacto\")\n    print(\"3. Actualizar contacto\")\n    print(\"4. Mostrar contacto\")\n    print(\"5. Eliminar contacto\")\n    print(\"6. Salir\")\n\n    option = input(\"\\nSelecciona una option: \")\n\n    match option:\n      case \"1\":\n        name = input(\"Intruce el nombre del contacto a buscar: \")\n        if name in agenda:\n          print(f\"El numero de telefono de {name} es {agenda[name]}\")\n        else:\n          print(f\"El contacto {name} no existe\")\n      case \"2\":\n        name = input(\"Introduce el nombre del contacto: \")\n        insert_contact()\n      case \"3\":\n        name = input(\"Introduce el nombre del contacto a actualizar: \")\n        if name in agenda:\n          insert_contact()\n        else:\n          print(f\"El contacto {name} no existe.\")\n      case \"4\":\n        print(agenda)\n      case \"5\":\n        name = input(\"Introduce el nombre del contact a eliminar: \")\n        if name in agenda:\n          del agenda[name]\n        else:\n          print(f\"El contacto {name} no existe\")\n      case \"6\":\n        print(\"Saliendo de la agenda.\")\n        break\n      case _:\n        print(\"Opcion no valida. Elige una opcion del 1 al 5.\")\n\nmy_agenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/k-90.py",
    "content": "### 03 Estructuras de Datos\n\n### Listas\n\nlenguajes = [\"python\",\"cobol\",\"javascript\",\"swift\",\"java\"]\nlenguajes.append(\"python\")\nlenguajes.append(\"cobol\")\nlenguajes.pop(1)\nlenguajes.pop(0)\nlenguajes.sort()\nprint(lenguajes.index(\"python\"))\nprint(len(lenguajes))\nlenguajes.clear()\nprint(lenguajes)\n\n### Listas de comprensión\n\ncuadrados = []\nfor x in range(10):\n    cuadrados.append(x**2)\n\nprint(cuadrados)\n\ncombinaciones = []\nfor x in [3,4,5]:\n    for y in [1,7,9]:\n        if x != y:\n            combinaciones.append((x,y))\n\nprint(combinaciones)\n\n### Listas de compresión anidadas\n\nmatriz = [\n    [1,2,3,],\n    [5,6,7,],\n    [9,10,11,]\n]\nmatrix = [[row[i] for row in matriz] for i in range (3)]\nprint(matrix)\n\nprint(list(zip(*matriz)))\n\n### Tuplas\n\ntuples = (\"manzana\",\"pera\",\"8\",\"platano\",\"mango\")\nprint(\"manzana\" in tuples)\nprint(tuples[2])\ntuples = tuple(sorted(tuples))\nprint(tuples)\n\n\n\n### Set\n\nfruits = {\"naranja\",\"melon\",\"sandia\",\"melocoton\"}\nfruits.add(\"albaricoque\") \nfruits.remove(\"naranja\")\nprint(fruits)\n\n\n\n### Diccionario\n\nmi_diccionario: dict = {\n    \"name\":\"Enrique\",\n    \"Surname\":\"Castro\",\n    \"Edad\":\"33\",\n    \"e-mail\":\"kikedev@kikadev.com\"\n}\nmi_diccionario[\"web\"] = \"losfijos.dev\"\nprint(mi_diccionario)\ndel mi_diccionario[\"Surname\"]\nprint(mi_diccionario)\nprint(mi_diccionario[\"e-mail\"])\nmi_diccionario[\"Edad\"] = \"34\"\nprint(mi_diccionario)\nmi_diccionario = dict(sorted(mi_diccionario.items()))\nprint(mi_diccionario)\n\n\n### Extra\n\ndef agenda():\n\n    agenda = {}\n\n    def añadir_contacto():\n        telefono = input(\"Introduce número de telefono:\")\n        if telefono.isdigit() and len(telefono) > 0 and len(telefono) <= 11:\n            agenda[name] = telefono\n        else:\n            print(\"Debe introducir un numero de 11 digitos\")\n    \n    while True:\n\n        print(\"\")\n        print(\"1.Buscar Contacto\")\n        print(\"2.Insertar Contacto\")\n        print(\"3.Actualizar Contacto\")\n        print(\"4.Eliminar Contacto\")\n        print(\"5.Salir\")\n\n        opciones = input(\"\\nEliga una opcion:\")\n\n        match opciones:\n            case \"1\":\n                name = input(\"Introduce nombre de contacto a buscar:\")\n                if name in agenda:\n                    print(f\"El numero de telefono de {name} es {agenda[name]}.\")\n                else:\n                    print(f\"El contacto {name} no existe.\")\n            case \"2\":\n                name = input(\"Introduce el nombre de contacto:\")\n                añadir_contacto()\n            case \"3\":\n                name = input(\"Introduce el nombre del contacto a actualizar:\")\n                if name in agenda:\n                    añadir_contacto()\n                else:\n                    print(f\"El contacto {name} no existe.\")\n            case \"4\":\n                name = input(\"Introduce el nombre del contacto a eliminar:\")\n                if name in agenda:\n                    del agenda[name]\n                else:\n                    print(f\"El contacto {name} no existe.\")\n            case \"5\":\n                print(\"Saliendo de la agenda\")\n                break\n            case _:\n                print(\"Opción no valida. Eliga una opcion del 1 al 6.\")\n\nagenda()\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/keltoi-dev.py",
    "content": "\"\"\"* EJERCICIO:\n* - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n* - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n*\n* DIFICULTAD EXTRA (opcional):\n* Crea una agenda de contactos por terminal.\n* - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n* - Cada contacto debe tener un nombre y un número de teléfono.\n* - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n*   los datos necesarios para llevarla a cabo.\n* - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n*   (o el número de dígitos que quieras)\n* - También se debe proponer una operación de finalización del programa.\n\"\"\"\nimport re\n\n# Tuplas - Son inmutables, se pueden iterar\nprint(\"TUPLAS\")\ntupla = (1, 2, 3, 4, 1)\n# tupla = tuple([1, 2, 3])\nprint(type(tupla))\nprint(tupla)\n\n# Iterar tuplas\nprint(\"ITERAR TUPLAS\")\nfor dato in tupla:\n    print(dato)\n\nprint(len(tupla))  # Muestra la cantidad de elementos\n\n# Metodos tuplas\nprint(\"METODOS TUPLAS\")\nprint(tupla.count(1))  # cuenta los elementos que son 1\nprint(tupla.index(4))  # imprime el el indice del valor 4\n\n# Listas - Son mutables, se pueden iterar\nprint(\"LISTAS\")\nlista = [1, 2, 3, 4]\n# lista = list(\"123\")\nprint(type(lista))\nprint(lista)\n\na, b, c, d = lista\nprint(f\"{a} - {b} - {c} - {d}\")\n\n# Iterar listas\nprint(\"ITERAR LISTAS\")\nfor dato in lista:\n    print(dato)\n\nprint(len(lista))  # Muestra la cantidad de elementos\n\n# Metodos\nprint(\"METODOS LISTAS\")\nlista.remove(3)  # Remueve el elemento 3\nprint(lista)\n\nlista.extend([5, 6])  # Se extiende la lsita con uno o varios elementos\nprint(lista)\n\nlista.append(7)  # Se agrega un valor al final de la lista\nprint(lista)\n\nlista.insert(2, 3)  # Se inserta un 3 en la posicion 2\nprint(lista)\n\nlista.pop()  # Se elimina el ultimo valor\nprint(lista)\n\nlista.reverse()  # La oredena en sentido inverso\nprint(lista)\n\nlista.sort()  # La ordena de menor a mayor\nprint(lista)\n\nprint(\n    lista[3]\n)  # Imprime el valor de la lista en la posicion 3 (comienza a contar desde 0)\n\nprint(lista.index(4))  # Imprime la posicion del elemento 4\n\n# Set - Son inmutables, se pueden iterar, no permite datos repetidos y desordenados\nprint(\"SETS\")\ns = set([2, 1, 4, 2, 3, 1])\nprint(type(s))\nprint(s)\n\n# Iterar sets\nprint(\"ITERAR SETS\")\nfor dato in s:\n    print(dato)\n\nprint(len(s))  # Muestra la cantidad de elementos\n\nprint(\"METODOS DE SETS\")\ns.add(5)  # Agrega el valor 5\nprint(s)\n\ns.remove(3)  # Remueve el valor 3\nprint(s)\n\ns.pop()  # Remueve un valor al azar\nprint(s)\n\ns.clear()  # Vacia el set\nprint(s)\n\n# Diccionarios - Son mutables, se pueden iterar\nprint(\"DICCIONARIOS\")\ndiccionario = {\"Juan\": \"juan@mail.com\", \"Maria\": \"maria@mail.com\"}\n# diccionario = dict([(\"Juan\", \"juan@mail.com\"), (\"Maria\", \"maria@mail.com\")])\nprint(type(diccionario))\nprint(diccionario)\n\nprint(\"ITERAR DICCIONARIOS\")\nfor x, y in diccionario.items():\n    print(f\"clave: {x}, valor: {y}\")\n\nprint(\"METODOS DE DICCIONARIOS\")\nprint(\n    diccionario.get(\"Juan\", \"No existe\")\n)  # Muestra el valor para la clave, si no existe muestra el segundo parametro\n\nprint(diccionario.items())  # Muestra todos los items del diccionario\n\nprint(diccionario.keys())  # Muestra todos los keys del diccionario\n\nprint(diccionario.values())  # Muestra todos los valores del diccionario\n\ndiccionario.pop(\"Juan\")  # Elimina el item con esa key\nprint(diccionario)\n\nd = {\"Jose\": \"jose@mail.com\"}\ndiccionario.update(d)  # Agrega un item o si existe lo modifica\nprint(diccionario)\n\ndiccionario.clear()  # Vacia el diccionario\nprint(diccionario)\n\n\"\"\"\nDIFICULTAD EXTRA\n\"\"\"\n\n\n# Funcion de menu de opciones\ndef menu():\n    opciones = \"1234\"\n    print(\"\\nBIENVENIDO A LA AGENDA:\")\n    print(\"1 - Dar de alta\")\n    print(\"2 - Dar de baja\")\n    print(\"3 - Consultar\")\n    print(\"4 - Modificar\")\n    print(\"\\n0 - Salir\\n\")\n    global seleccion\n    global decision\n    seleccion = input(\"seleccione una opcion: \")\n    if seleccion in opciones:\n        decision = True\n    else:\n        decision = False\n\n\n# Funcion para dar de alta\ndef alta(posicion: dict, contador: int):\n    patron = \"^\\d{13}$\"\n    name = input(\"Ingrese el nombre: \")\n    phone = input(\"Ingrese el telefono (debe tener 13 digitos): \")\n    if re.match(patron, phone):\n        prov = {str(contador): [name, phone]}\n        posicion.update(prov)\n        contador += 1\n    else:\n        print(\"El telefono ingresado es incorrecto\")\n        print(\"Debe tener 13 digitos\")\n        alta(posicion, contador)\n    return posicion, contador\n\n\n# Funcion para dar de baja\ndef baja(posicion: dict):\n    mostrar(posicion)\n\n    x = input(\"\\nIngrese que ID quiere dar de baja: \")\n    if posicion.get(x, \"no\") == \"no\":\n        print(\"El item no existe\")\n        return baja(posicion)\n    posicion.pop(x)\n\n    return posicion\n\n\n# Funcion de consulta\ndef consulta(posicion: dict):\n    mostrar(posicion)\n    x = input(\"\\nPresione una tecla para continuar\")\n    if x != \"\":\n        return\n\n\n# Funcion para modificar\ndef modificar(posicion: dict):\n    mostrar(posicion)\n\n    x = input(\"\\nIngrese que ID quiere modificar: \")\n    if posicion.get(x, \"no\") == \"no\":\n        print(\"El item no existe\")\n        return modificar(posicion)\n\n    name = input(\"Ingrese el nombre a modificar: \")\n    phone = input(\"Ingrese el telefono a modificar: \")\n    prov = {str(x): [name, phone]}\n    posicion.update(prov)\n\n    return posicion\n\n\n# Funcion para mostrar la agenda\ndef mostrar(posicion: dict):\n    print(\"-\" * 43)\n    print(f'{\"ID\":4} {\"NOMBRE\":25} {\"TELEFONO\":17}')\n\n    for i in posicion:\n        print(f\"{i:4} {posicion[i][0]:25} {posicion[i][1]:12}\")\n    print(\"-\" * 43)\n\n\n# Inicia mostrando un menu de opciones\nposicion = {}\ncontador = 0\n\nmenu()\nwhile decision:\n    if seleccion == \"1\":\n        posicion, contador = alta(posicion, contador)\n        menu()\n    elif seleccion == \"2\":\n        posicion = baja(posicion)\n        menu()\n    elif seleccion == \"3\":\n        consulta(posicion)\n        menu()\n    elif seleccion == \"4\":\n        posicion = modificar(posicion)\n        menu()\n\nprint(\"Ha salido de la agenda!!\")\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/kenysdev.py",
    "content": "# ╔══════════════════════════════════════╗\n# ║ Autor:  Kenys Alvarado               ║\n# ║ GitHub: https://github.com/Kenysdev  ║\n# ║ 2024 -  Python                       ║\n# ╚══════════════════════════════════════╝\n\n# ************************\n# 1. Estructuras de datos.\n# ************************\n# ------------------------\n# list (Lista):\n# ------------------------\n# Permite almacenar datos de cualquier tipo.\n# Son mutables y dinámicas.\nlista1 = [1, 2, 3, 4]  # sintaxis\nlista2 = list(\"1234\")  # Crear pasando un objeto iterable\nlista3 = [1,2], [2, 3] # listas anidadas\n# pueden almacenar tipos de datos distintos.\nlista = [1, \"Hola\", 3.67, [1, 2, 3], False] \n\n# ------------------------\n# set (conjunto):\n# ------------------------\n# Similar a las listas, pero con ciertas diferencias:\n# - no conserva elementos duplicados.\n# - no mantienen el orden de cuando son declarados.\n# - Sus *elementos* son inmutables,\n#   Significa que no pueden ser modificados.\n# - se implementa intercrearnte utilizando una tabla hash. \nset1 = {1, 2, 3, 4} # sintaxis                      \nset2 = set(lista1)  # pasando un objeto iterable.\n# con distintos tipos de datos, no listas ni diccionarios.\nconjunto = {1, \"dos\", (3, 4), 3.14, True}\n\n# ------------------------\n# tuple (Tupla):\n# ------------------------\n# Muy parecida a las listas, pero:\n# - con la salvedad de que son inmutables,significa que\n#   no pueden ser modificadas,ordenadas o eliminadas.\n# - las tuplas pueden ser más rápidas.\ntupla1 = (1, 2, 3)            # sintaxis\ntupla2 = 1, 2, 3              # <-- or\ntupla3 = tuple(set1)          # pasando un objeto iterable\ntupla4 = ((1, 2), (\"a\", \"b\")) #tuplas anidadas\n# pueden almacenar distintos tipos de datos.\ntupla  = (1, \"dos\", [3, 4], {\"clave\": \"valor\"}, 5.0)\n\n# ------------------------\n# dict (Diccionario):\n# ------------------------\n# Permite almacenar su contenido en forma de llave y valor.\n# sintaxis:\nmy_dict1 = {\n    \"crear\": \"Ben\",\n    \"Age\": 27,\n    \"Id\": 1003882\n}\n# pasando un objeto iterable:\nmy_list = [(\"a\", 1), (\"b\", 2), (\"c\", 3)]\nmy_dict2 = dict(my_list)\n\n# diccionarios anidados:\nmy_dict3 = {\n    \"anidado1\" : my_dict1,\n    \"anidado2\" : my_dict2,\n    \"anidado3\" : dict(lista3)\n}\n\n# *****************************************\n# 2. operaciones con estructuaras de datos.\n# *****************************************\n# ------------------------\n# inserción:\n# ------------------------\n# * en listas:\nlista1.append(5)      # añadir un elemento\nlista1.extend([6, 8]) # múltiples elementos.\nlista1.insert(6, 7)   # en una posición o índice.\nlista1 += [9, 10]     # usando operador.\nprint(lista1)         \n\n# * en conjuntos:\nset1.add(5)          # añadir un elemento\nset1.update({6, 7})  # múltiples elementos.\nprint(set1)\n\n# * en tuplas: no es posible añadir un elemento.\n\n# * en diccionarios:\n# si existen solo se modificará el valor.\nmy_dict2[\"d\"] = 4                 # añadir un elemento.\nmy_dict2.update({\"e\": 5, \"f\": 6}) # múltiples\nprint(my_dict2)\n\n# ------------------------\n# Acceder:\n# ------------------------\n# * a listas y tuplas:\nprint(lista[2])       # usando el indice.\nprint(tupla[-2])      # indice en sentido contrario.\na, b, c, d, e = lista # asignar a n variales.\nprint(lista[0:2])     # a múltiples elementos.\nprint(lista.index(1)) # devuelve el índice.\nprint(lista.count(1)) # cuantos elementos iguales.\n\n# * a conjuntos:\n# No puedes acceder a los elementos por índice,como \n# lo harías en una lista o tupla.\nprint(set1)\nprint(conjunto.union(set2)) # mezclar sets.\n# aquellos elementos que pertenecen a ambos sets.\nprint(conjunto.intersection(set2))\n\n# * a un diccionario:\nprint(my_dict2[\"f\"])            # Acceder al valor asociado con la clave \"f\"\nprint(my_dict2.get(\"f\"))        # <--^ otra manera.\nprint(my_dict2.get(\"g\", \"N/A\")) # Si \"g\" no está presente, devuelve \"N/A\"\nprint(list(my_dict2.items()))   # devuelve una lista con los keys y values.\nprint(list(my_dict2.keys()))    # devuelve una lista con todas las keys.\nprint(list(my_dict2.values()))  # devuelve una lista con todos los values.\n\n# ------------------------\n# Modificacion:\n# ------------------------\n# * de listas:\nlista[2] = 12                # elemento específico.\nlista[0:3] = [2, \"hi\", 4.50] # múltiples elementos.\n\n# * de *conjuntos* y *tuplas* no es posible.\n\n# * de diccionarios:\n# Si no existe se creará una nueva clave.\nmy_dict2[\"d\"] = 4                 # añadir un elemento.\nmy_dict2.update({\"e\": 5, \"f\": 6}) # múltiples\n# Las claves en un diccionario no pueden modificarse directamente.\n\n# ------------------------\n# Eliminación:\n# ------------------------\n# * en listas\ndel lista[2]       # elemento en indice específico.\nlista.remove(\"hi\") # un argumento especifico\nlista.pop()        # elimina el ultimo elemento.\n\n# * en conjuntos:\nset2.remove(4)  # elimina el elemento, si no existe muestra error.\nset2.discard(6) # elimina, si no se encuentra no hace nada.\nset2.pop()      # elimina un elemento aleatorio.\nset2.clear      # elimina todos los elementos.\n\n# * en tuplas: no es posible eliminar un elemento.\n\n# * en diccionarios:\ndel my_dict3[\"anidado1\"]        # Eliminar un elemento por clave.\nprint(my_dict3.pop(\"anidado2\")) # Eliminar y obtener el valor mediante la clave.\nprint(my_dict3.popitem())       # Eliminar y obtener el último par clave-valor.\nmy_dict3.clear                  # Eliminar todos los elementos del diccionario.\ndel my_dict3                    # Eliminar el diccionario completo.\n\n# NOTA: Recuerda que estas operaciones de eliminación pueden generar un error si \n# intentas eliminar una clave que no existe.\n\n# ------------------------\n# Ordenación.\n# ------------------------\n# * de listas:\nlista1.reverse()          # inverte el órden.\nlista1.sort()             # de menor a mayor por defecto.\nlista1.sort(reverse=True) # de mayor a menor.\n\n# * de *conjuntos* y *tuplas* no es posible.\n\n# * de diccionarios:\n# Orden en diccionarios se implementó a partir de Python v3.7.\nmy_dict2 = dict(sorted(my_dict2.items(), key=lambda x: x[1])) # por Valores:\nmy_dict2 = dict(sorted(my_dict2.items())) # Ordenar por Claves.\n\n# ------------------------\n# Iteración:\n# ------------------------\n# * en una lista o tupla.\nfor l in lista:\n    print(l)\n\n# en múltiples listas o tuplas.\nfor l1, l2 in zip(lista1, lista2):\n    print(l1, l2)\n\n# Si necesitamos un índice acompañado con la lista tupla.\nfor index, l in enumerate(tupla):\n    print(index, l)\n\n# usando los índices de una lista o tupla.\nfor i in range(0, len(lista1)):\n    print(lista1[i])\n\n# ------------------------\n# * en un conjunto:\nfor elemento in set1: \n    print(elemento)\n\n# ------------------------\n# * en un diccionario:\nfor clave in my_dict2:\n    # Iterar sobre las claves y acceder a los valores\n    print(clave, my_dict2[clave])\n\nfor clave, valor in my_dict2.items():\n    # Obtener pares clave-valor con items()\n    print(clave, valor)\n\n# ************************\n# 3. Ejercicio:\n# ************************\n'''\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n *   y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n *   y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más\n *   de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.\n'''\nmi_agenda = {\"ayuda\" : \"911\"}\ndef agenda():\n    def select():\n        option = input(\"Número de opción: \")\n        match option:\n            case \"1\": crear()\n            case \"2\": buscar()\n            case \"3\": lista()\n            case \"4\": editar()\n            case \"5\": eliminar()\n            case '6': print(\"Adios\")\n            case _: print(\"numero 1 -> 6\"); select()\n\n    def add_num(nombre):\n        numero = input(\"Escriba el número: \")\n        if numero == \"6\": agenda()\n        elif numero.isdigit() and len(numero) > 0 and len(numero) <= 11:\n            mi_agenda[nombre] = numero\n            print(\"Guardado\"); agenda()\n        else: add_num(nombre)\n\n    def crear():\n        print(\"Crear contacto o 6. Salir\")\n        nombre = input(\"Escriba el nombre: \")\n        if len(nombre) <1: crear()\n        elif nombre == \"6\": agenda()\n        elif nombre in mi_agenda:\n            print(\"El nombre ya existe.\"); crear()\n        else: add_num(nombre)   \n        \n    def buscar():\n        print(\"Buscar contacto o 6. Salir\")\n        nombre = input(\"Escriba el nombre:\\n\")\n        if nombre == \"6\": agenda()\n        elif nombre in mi_agenda: \n            print(mi_agenda[nombre]); agenda()\n        else: print(\"Contacto no encontrado.\"); buscar()\n    \n    def lista():\n        ordenar_agenda = dict(sorted(mi_agenda.items())) # ordenar abc\n        for nombre, numero in ordenar_agenda.items(): \n            print(f\"{nombre}: {numero}\")\n        agenda()\n\n    def editar():\n        print(\"Editar contacto o 6. Salir\")\n        nombre = input(\"Escriba el nombre: \")\n        if nombre == \"6\": agenda()\n        elif nombre in mi_agenda: add_num(nombre)\n        else: print(\"Contacto no encontrado.\"); editar()\n\n    def eliminar():\n        print(\"Eliminar contacto o 6. Salir\")\n        nombre = input(\"Escriba el nombre: \")\n        if nombre == \"6\": agenda()\n        elif nombre in mi_agenda:\n            del mi_agenda[nombre]\n            print(\"Contacto eliminado\")\n            agenda()  \n        else: print(\"Contacto no encontrado.\"); eliminar()\n\n    print(\"\"\"\n    Agenda de contactos\n╔═══════════════════════════╗\n║ 1. Nuevo      4. Editar   ║\n║ 2. Buscar     5. Eliminar ║\n║ 3. Lista      6. Salir    ║\n╚═══════════════════════════╝\n    \"\"\")\n    select()\n\nagenda()\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/knowledgesoftdev.py",
    "content": "import sys\n'''\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n'''\n#El append: para agregar un elemento en una lista al final\nlista=[1,2,3]\nlista.append(4)\n\n#Se puede agreagr list dentro de una lista\nlista.append([5,6])\n\n#Extend: sirve para agregar muchos elementos al final\nlista.extend([7,8])\n\n#insert: para agregar un elemto, escogiendo la posicion y colocando el elemento\nlista.insert(3,10)\n\n#remove: para poder borrar un elemento de una lista\nlista.remove(10)\n\n#pop: para poder eleiminar un valor por posicion\nlista.pop(0)\n\n#clear:poder vaciar nuestra lista, el cual se eliminar todos los elementos\n    #lista.clear()\n\n#index: metodo para poder buscar el elemento si esta en esa posicion\n    #lista.index(2,0)\n\n#cout: cuenta cuantos valores se repirte en mi lista\nlista.extend([7,9,5])\nrepeticion=lista.count(5)\n\n#Eliminar dicho elemento por posicion, para poder ordenar\n#sort order nado de manera ascendente\nlista.pop(3)\nlista.sort()\n\n#reverse: para poder revertir dicha lista\nlista.reverse()\n\n#copy practicamente sacar una copia de un lista\nnuevaCopia=lista.copy()\n\n#print(lista,\"-\",nuevaCopia)\n\n'''\n* DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n'''\n\ndef validarTelefono(telefono):\n    if not telefono.isdigit() or len(telefono)>11:\n        return False\n    return True\n\ndef buscarPersona(lista,nombre):\n    for i,contacto in enumerate(lista):\n        if contacto[\"nombre\"].strip().lower() == nombre.strip().lower():\n            return i\n    return -1\n\ndef agenda():\n    lista_agenda=[]\n    print(\"Agenda\")\n    while True:\n        print(\"Escoger una de estas opcion:\")\n        print(\"0: Buscar\")\n        print(\"1: Insertar\")\n        print(\"2: Actualizar\")\n        print(\"3: Eliminar\")\n        print(\"4: Listar\")\n        print(\"5: Salir\")\n        opcion=int(input(\"Colocar opcion: \"))\n        if opcion==0:\n            nombre=input(\"Ingresar nombre a buscar:\")\n            posicion=buscarPersona(lista_agenda,nombre)\n            if posicion!=-1:\n                contacto=lista_agenda[posicion]\n                print(f\"Contacto encontrado: {contacto['nombre']} - {contacto['telefono']}\")\n            else:\n                print(\"Contacto no encontrado\")\n        elif opcion==1:\n            nombre=input(\"Colocar tu nombre: \").strip()\n            telefono=input(\"Colocar tu telefono: \").strip()\n            if validarTelefono(telefono):\n                lista_agenda.append({\"nombre\":nombre, \"telefono\":telefono})\n                print(\"Contacto Agregado Correctamente\",lista_agenda)\n            else:\n                print(\"El telefono debe ser numerico y no puede tener mas de 11 digitos\")\n        elif opcion==2:\n            #buscar\n            nombre=input(\"Colocar tu nombre: \")\n            posicion=buscarPersona(lista_agenda,nombre)\n            if posicion!=-1:\n                    nuevo_nombre=input(\"Colocar tu nombre: \")\n                    nuevo_telefono=input(\"Colocar tu telefono: \")\n                    if validarTelefono(nuevo_telefono):\n                        lista_agenda[posicion][\"nombre\"]=nuevo_nombre\n                        lista_agenda[posicion][\"telefono\"]=nuevo_telefono\n                        print(\"Contacto Actualziad\",lista_agenda)\n                    else:\n                        print(\"El telefono debe ser numerico y no puede tener mas de 11 digitos\")\n            else:\n                print(\"Contacto no encontrado\")\n        elif opcion==3:\n            persona=input(\"Colocar tu nombre: \")\n            posicion=buscarPersona(lista_agenda,persona)\n            if posicion!=-1:\n                lista_agenda.pop(posicion)\n                print(\"Eliminado\")\n            else:\n                print(\"Contacto no encontrado\")\n        elif opcion==4:\n            print(\"Listar\",lista_agenda)\n        elif opcion==5:\n            print(\"Estas Saliendo\")\n            break\n\nagenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/kodenook.py",
    "content": "\nimport time\n\n\"\"\" List \"\"\"\n\ncars = ['bmw', 'ferrari', 'toyota']\n\n''' Insert '''\ncars.append('lamborghini') # insert to the end\ncars.insert(2, 'bugatti') # Insert at a index\n\nprint(cars)\n\n''' Edit '''\ncars[0] = 'maserati'\n\nprint(cars)\n\n''' Delete '''\ncars.pop(1) # delete index or default(last)\ncars.remove('toyota') # delete by value\n\nprint(cars)\n\n''' Order '''\ncars.reverse() # reverse\nprint(cars)\n\ncars.sort() # ascending\nprint(cars)\n\ncars.sort(reverse = True) # descending\nprint(cars)\n\n\"\"\" Tuples \"\"\"\n\nfruits = ('apple', 'banana', 'orange')\n\nprint(fruits)\n\n''' tuples are inmutable '''\n\n\"\"\" Sets \"\"\"\n\ncountries = {'chile', 'germany', 'japan'}\n\n''' Set items are unchangeable '''\n\n''' insert '''\n\ncountries.add('spain')\nprint(countries)\n\n''' delete '''\n\ncountries.remove('germany') # if not exist will raise an error\ncountries.discard('sweden') # if not exist will not raise an error\ncountries.pop() # remove an random item\nprint(countries)\n\n\"\"\" Dictionaries \"\"\"\n\nperson = {\n    'name': 'kodenook',\n    'country': 'chile'\n}\n\n''' insert '''\n\nperson['continent'] = 'america'\nperson.update({'car': 'lamborghini'}) # edit, if key not exist add\nprint(person)\n\n''' edit '''\n\nperson['car'] = 'ferrari'\nprint(person)\n\n''' delete '''\n\nperson.pop('country')\ndel person['name']\nperson.popitem() # remove the last inserted\nprint(person)\n\n\"\"\" Exercise \"\"\"\n\noption = 0\ndata = {}\n\nwhile (option != 5):\n\n    print('\\033c')\n\n    print('1. search')\n    print('2. add')\n    print('3. edit')\n    print('4. delete')\n    print('5. exit')\n\n    option = int(input('choose a option: '))\n\n    if option == 1:\n        name = input('name: ')\n\n        if name in data:\n            print(data[name])\n\n            time.sleep(5)\n\n    elif option == 2:\n        name = input('name: ')\n        number = input('number: ')\n\n        if name in data:\n            data[name] = number\n\n    elif option == 3:\n        name = input('name: ')\n        number = input('number: ')\n\n        if name in data:\n            data[name] = number\n\n    elif option == 4:\n        name = input('name: ')\n\n        if name in data:\n            del data[name]\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/kuroz00.py",
    "content": "# Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n# Utiliza operaciones de inserción, borrado, actualización y ordenación.\n\n\n'''\n-> La lista es una colección ordenada y modificable. Permite miembros duplicados.\n-> Tupla es una colección ordenada e inmutable. Permite miembros duplicados.\n-> Set es una colección desordenada, inmutable* y no indexada. No hay miembros duplicados.\n-> El diccionario es una colección ordenada** y modificable. No hay miembros duplicados.\n'''\n\ndef lista():\n    miListaStr = ['naranja', 'banana', 'durazno']\n    miListaBool = [True, True, False]\n    miListaNum = [0,1,2,3,4]\n    miListaX = [0 , 1, 'naranja', True, 'banana', 3, 4, 5, False, 'durazno']\n    laLista = list(('banana', 'banana', 'pomelo')) #Funcion constructor lista\n    print('\\n',type(miListaStr),\n          '\\n', miListaStr,\n          '\\n', miListaBool,\n          '\\n', miListaNum,\n          '\\n', miListaX,\n          '\\n', laLista\n          ,'\\n'\n          )\n    \n    #Impresion de un valor en particular de la lista:\n    print('\\n', 'Primer elemento de la lista con strings: ', miListaStr[0],\n          '\\n', 'Ultimo elemento de la lista con booleanos: ', miListaBool[-1],\n          '\\n', 'Cuarto elemento de la lista numerica: ', miListaNum[3]\n          )\n    #Impresion de valores en un margen dentro de la lista: \n    print('\\n', 'Primeros 4 valores de lista X: ', miListaX[0:4],\n          '\\n', 'Todos los valores desde el indice 2: ', miListaX[2:], \n          '\\n', 'Todos los valores hasta el indice 4: ', miListaX[:4]  \n          )\n    #Verificar si existe un valor en particular dentro de la lista, de ser el caso, cambiarlo por otro mas delicioso:\n    if 'durazno' in miListaX:\n        print('\\n', 'La lista X contiene el string DURAZNO... lo cambiare por doritos')\n        miListaX[-1] = 'doritos'\n        print('\\n', miListaX, '\\n', 'Ahora que todos los string en la lista sean doritos', '\\n')\n        for i in range(len(miListaX)):\n            if isinstance(miListaX[i], str): #verificar si el valor es de tipo str\n                miListaX[i] = 'doritos'\n        print(miListaX, '\\n', 'mucho mejor', '\\n')\n\n\n    #Cambiar los valores dentro de un margen de indices:\n    miListaBool[0:] = [True, True, True, True] #cambiar todos los valores de esta lista a true\n    print('\\n', 'Ahora mi lista booleana tiene solo valores verdaderos.', '\\n', miListaBool)\n    \n    miListaNum[2:4] = [0, 0, 0]\n    print('\\n', 'Cambie del inidice 2 al 4 los valores por 0: ', '\\n', miListaNum, '\\n',)\n    \n\n    #utilizando el insert es posible insertar valores en la lista, sin reemplazar los valores ya existentes en la misma\n    listaDias = ['lunes', 'martes', 'jueves', 'viernes', 'sabado']\n    listaDias.insert(2, 'miercoles')\n    listaDias.insert(6, 'domingo')\n    print('lista de dias:', listaDias)\n\n    #Utilizando append podemos insertar elementos al final de la lista\n    listaMeses2 = ['mayo', 'junio', 'julio', 'agosto', 'septiembre', 'octubre']\n    listaMeses2.append('noviembre')\n    listaMeses2.append('diciembre')\n    print('\\n', 'lista de meses incompleta: ', listaMeses2)\n    \n    #Extend es una funcion que nos permite incorporar una lista a otra, tambien tuplas,conjuntos, diccionarios...\n    listaMeses1 = ['enero', 'febrero', 'marzo', 'abril']\n    listaMeses1.extend(listaMeses2)\n    print('\\n','lista de meses completa: ', listaMeses1)\n\n\n    #Remove() y pop() para eliminar elementos de una lista \n    listaPaises = ['chile', 'argentina', 'mexico', 'peru', 'bolivia', 'ecuador'] \n    listaPaises.remove('peru')\n    print('\\n', 'lista de paises excluyendo a peru', listaPaises)\n\n    listaPaises = ['chile', 'argentina', 'mexico', 'peru', 'bolivia', 'ecuador'] \n    listaPaises.pop(3)\n    print('\\n', 'lista de paises excluyendo a peru nuevamente', listaPaises)\n\n    #Ordenar una lista de menor a mayor y en orden alfabetico\n    listaString = ['papaya', 'kiwi', 'arandano', 'manzana', 'banana', 'palta']\n    listaInt = [1, 6, 4, 3, 8, 10, 2, 2]\n\n    listaString.sort()\n    listaInt.sort()\n    print('\\n', listaString, '\\n', listaInt)\n\n    #Ordenar de forma descendiente \n    listaString.sort(reverse = True)\n    listaInt.sort(reverse = True)\n    print('\\n', listaString, '\\n', listaInt)\n\n \ndef tupla():\n    #al igual que las listas los valores en las tuplas pueden repetirse, pero no se pueden alterar su contenido.\n    tuplaSimple = ('league of legend', 'overwatch', 'rust', 'the finals', 'league of legend')\n\n    #tuplaSimple.remove('rust') ERROR\n    #tuplaSimple.insert('minecraft') ERROR\n    #tuplaSimple.append('osu') ERROR\n\n    #pueden contener cualquier tipo de dato\n    tupla1 = ('apple', 'banana', 'cherry')\n    tupla2 = (1, 5, 7, 9, 3)\n    tupla3 = (True, False, False)\n    tuplaX = ('apple', 7, 9, 3, False, False)\n    print('\\n', type(tuplaX),\n          '\\n', 'tupla con strings', tupla1, \n          '\\n', 'tupla con enteros', tupla2, \n          '\\n', 'tupla con booleanos', tupla3, \n          '\\n', 'tupla con todo!', tuplaX, '\\n'\n          )\n    miTupla = tuple(('banana', 'manzana', 'sandia')) #constructor de tupla\n\n\n    #Cambiar su valores\n    #las tuplas son inmutables, por lo que primero se deben pasar a lista para despues reconvertir en tupla\n    laTupla = ('manzana', 'patata', 'melon', 'uva')\n    print(laTupla)\n    laLista = list((laTupla))\n    laLista[0] = 'pera'\n    laTupla = tuple((laLista))\n    print(laTupla, '\\n')\n\n    #Agregar elementos\n    #al igual que anteriormente, se puede converitir tupla en lista para agregar elementos\n    laLista = list((laTupla))\n    laLista.append('jugo de naranja!')\n    laTupla = tuple((laLista))\n    print(laTupla, '\\n')\n\n    #Eliminar elementos\n    #mas de lo mismo, solo convertimos en lista y usamos remove o pop\n    laLista = list((laTupla))\n    laLista.remove('patata')\n    laLista.pop(0)\n    laTupla = tuple((laLista))\n    print(laTupla, '\\n')\n\n\ndef setF():\n    miSet = {'sombrero', 'botas', 'traje', 'pantalon'}\n    print('\\n', 'set de ropa', miSet, '\\n') #siempre saldra desordenado\n\n    miSet = {'sombrero', 'botas', 'traje', 'pantalon', 'pantalon', 'pantalon', 'pantalon', 'pantalon'}\n    print('\\n', 'set de ropa con elemento repetido', miSet, '\\n') #se ignoran los valores duplicados, no estan permitidos\n\n    miSet = {'sombrero', 'botas', 'traje', 'pantalon', True, 1}\n    print('True y 1  ', miSet, '\\n') #son considerados como lo mismo, por lo que cuenta como elemento duplicado\n    miSet = {'sombrero', 'botas', 'traje', 'pantalon', False, 0}\n    print('False y 0  ', miSet, '\\n')\n\n    set1 = {\"manzana\", \"banana\", \"tomate\"}\n    set2 = {1, 5, 7, 9, 3}\n    set3 = {True, False, False}\n    tuplaX = {'apple', 7, 9, 3, False, False}\n    print('\\n', type(tuplaX),\n          '\\n', set1,\n          '\\n', set2,\n          '\\n', set3, '\\n'\n          )\n    \n    crearSet = set(('banana', 'pan', 'tomate', 'leche')) #constructor de set\n    print(crearSet)\n    \n    #no se puede acceder mediante un indice a los valores de un set\n    #no obstante se pueden recorrer mediante un bucle\n    for x in crearSet:\n        print(x)\n\n    #una vez creado el set no se pueden cambiar sus elementos, pero si agregar nuevos!\n    crearSet.add('naranja') #mediante 'add'\n    print(crearSet, '\\n')\n\n    #agregar elementos desde otro set\n    set1.update(set2)\n    print(set1, '\\n')\n\n    #Remover elementos de un set.\n    set1.remove('manzana')\n    set1.discard(3)\n    print(set1, '\\n')\n      # tambien se puede utilizar el metodo POP() pero esto eliminara un elemento aleatorio\n\n\ndef diccionario():\n    miDiccionario = {'rojo':'red', 'verde':'green', 'azul':'blue'}\n    miDiccionario['amarillo'] = 'yellow' #INGRESAR elementos en el diccionario\n    miDiccionario['rojo'] = 'RED' #CAMBIAR valor de la clave por otro(en este casos olo lo puse en mayusculas)\n    miDiccionario['verde']\n\n    print(miDiccionario['azul'], '\\n') #blue\n    print(miDiccionario.keys()) #solo las claves\n    print(miDiccionario.values(), '\\n') #solo los valores\n\n    usuarioDatos = dict(name = 'pepe', especie = 'rana', edad = '1000 años', pais = 'chile') #constructor de diccionarios. DICT\n    print(usuarioDatos, '\\n')\n\n    #Eliminar elementos de un diccionario\n    usuarioDatos.pop('edad') #POP eliminara la clave especifica que le demos como argumento\n    print(usuarioDatos)\n\n    #popitem() eliminara el ultimo elemento ingresado, antiguamente eliminaba uno al azar\n    #del eliminara cualquier elemento con el nombre que le demos\n    #clear() es un metodo que vacia el diccionario \n\nlista()\ntupla()\nsetF()\ndiccionario()\n\n##################### Dificultad extra.- ##################### \nprint('\\n','\\n','\\n','\\n','\\n')\n\ndef agendaTelefonica():\n    listaContactos = [['pepe', 10323234666], ['juan', 30142424352]]\n    i = False\n\n    def buscarContacto():\n        nombre = input('Nombre del contacto: ')\n        for x in range(len(listaContactos)):\n            if nombre in listaContactos[x]:\n                print('Numero de', nombre, ': ', listaContactos[x][1])\n                break\n            print('Ese contacto no se encuentra en la lista.')\n                \n    \n    def verContactos():\n        longitudLista = len(listaContactos) \n        for x in range(longitudLista):\n            elemento = listaContactos[x]\n            print(elemento)\n    \n    def agregarContacto():\n        nombreContacto = input('Nombre ')\n\n        try:\n            numeroContacto = int(input('Numero: '))\n        except ValueError:\n            print('Debe ingresar un valor numerico!')\n        \n        cantDigitos = (numeroContacto)\n        cantDigitos = str(cantDigitos)\n        cantDigitos = len(cantDigitos)\n    \n        while cantDigitos > 11:\n            try:\n                numeroContacto = int(input('Numero no puede superar los 11 digitos: '))\n            except ValueError:\n                print('Debe ingresar un valor numerico!')\n            cantDigitos = str(numeroContacto)\n            cantDigitos = len(cantDigitos)\n\n        registroContacto = [nombreContacto, numeroContacto]\n        listaContactos.append(registroContacto)\n    \n    def editarContacto():\n        contacto_a_editar = input('Que contacto desea editar?')\n        for x in range(len(listaContactos)):\n            if contacto_a_editar in listaContactos[x]:\n                try:\n                    opcion = int(input('Numero de la opcion->  1.- nombre 2.- numero'))\n                except ValueError:\n                    print('Debe ingresar un numero.')\n                    break\n                if opcion == 1:\n                    listaContactos[x][0] = input('Ingrese nuevo nombre: ')\n                elif opcion == 2:\n                    try:\n                         listaContactos[x][1] = int(input('Ingrese nuevo numero: '))\n                    except ValueError:\n                        print('Debe ingresar un valor valido.')\n                        break\n\n    def borrarContacto():\n        contacto_a_eliminar = input('Nombre del contacto que desea eliminar: ')\n        for x in range(len(listaContactos)):\n            if contacto_a_eliminar in listaContactos[x]:\n                listaContactos.remove(listaContactos[x])\n                break\n            else:\n                print('Contacto no esta en la lista.')\n\n\n    while i != True:\n        print('Agenda ', '\\n',\n            '1.- buscar contacto', '\\n',\n            '2.- ver lista de contactos', '\\n',\n            '3.- agregar contacto', '\\n',\n            '4.- editar contacto', '\\n',\n            '5.- eliminar contacto', '\\n',\n            '6.- cerrar programa', '\\n'\n            )\n        try:\n            opcion = int(input('seleccione numero para una accion: '))\n        except ValueError:\n            print('ingrese numero solamente.')\n            continue\n\n        if opcion == 6:\n            i = True\n        elif opcion > 6 and opcion < 1:\n            print('Opcion no valida', '\\n')\n\n        if opcion == 1:\n            buscarContacto()\n        elif opcion == 2:\n            verContactos()\n        elif opcion == 3:\n            agregarContacto()\n        elif opcion == 4:\n            editarContacto()\n        elif opcion == 5:\n            borrarContacto()\n    \nagendaTelefonica()\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/linerlander.py",
    "content": "# Listas\n\nmy_list = list()\nmy_list: list = ['Brais','Bl4ck','Wolfy','Liner','Hanny']\nprint(my_list)\n\nmy_list.append('Yamid') # INSERCIÓN  ---> Añadir un elemento al final de la lista\nmy_list.append('Yamid') \nprint(my_list)\n\nmy_list.insert(0,'Celeste') # INSERCIÓN  ---> Añadir un elemento en la lista deacuerdo al indice  \nprint(my_list)\n\nmy_list.remove('Brais') # ELIMINACIÓN  ---> Eliminar un elemento en la lista deacuerdo al valor dado  \nprint(my_list)\n\nprint(my_list[1]) # Acceso\n\nmy_list[1] = 'Cuervillo' # Actualización\nprint(my_list) \n\nmy_list.sort()# Ordeanación\nprint(my_list)\n\n# Tuplas\n\nmy_tuple = tuple()\nmy_tuple: tuple = ('Liner','LanderDev','@landerdev','24')\n\nprint(my_tuple[1]) # Acceso\nprint(my_tuple[3])\n\nmy_tuple = tuple(sorted(my_tuple)) # Ordenación\nprint(my_tuple)\nprint(type(my_tuple))\n\n# set \n\nmy_set = set()\nmy_set = {'Liner','LanderDev','@landerdev','24'} \nprint(my_set)\n\nmy_set.add('linerlander@gmail.com') # Inserción\n\nmy_set.add('linerlander@gmail.com') # Evita duplicado\nmy_set.remove('Liner') # Eliminación\nprint(my_set)\n\nmy_set = set(sorted(my_set)) # No se puede ordenar\nprint(my_set)\nprint(type(my_set))\n\n# Diccionario\n\nmy_dict = dict()\nmy_dict: dict = {\n    'name':'Liner',\n    'surname':'LanderDev'\n    ,'alias':'@landerdev',\n    'age':'24'\n}\nmy_dict['email'] = 'linerlander@gmail.com' #Inserción\nprint(my_dict)\n\nprint(my_dict['alias']) # Acceso\n\nmy_dict['age'] = '37' # Actualización\nprint(my_dict)\n\ndel my_dict['name'] # Eliminación\nprint(my_dict)\n\nmy_dict = dict(sorted(my_dict.items())) # Ordenación\nprint(my_dict)\n\nprint(type(my_dict))\n\n'''\nDificultad Extra\n'''\n\ndef my_agenda():\n    agenda = {}\n\n    def inser_contact():\n        phone = input('Introduce el teléfono del contacto: ')\n        if phone.isdigit() and len(phone) > 0 and len(phone) <= 11:\n            agenda[name] = phone\n        else:\n            print('Debes introducir un número de teléfono con un máximo de 12 dígitos.')\n    def no_existe():\n        print(f'El contacto {name} no existe.')\n    \n    while True:\n        print('\\n')\n        print('#### AGENDA ######')\n        print('\\n1. Buscar contacto')\n        print('2. Insertar contacto')\n        print('3. Actualizar contacto')\n        print('4. Eliminar contacto')\n        print('5. Salir')\n\n        option = input('\\nSeleciona una opción: ')\n        print(option)\n\n        match option:\n            case '1':\n                name = input('Introduce el nombre del contacto a buscar: ')\n                if name in agenda:\n                    print(f'El número de teléfono de {name} es {agenda[name]}.')\n                else:\n                    no_existe()\n                pass\n            case '2':\n                name = input('Introduce el nombre del contacto a insertar: ')\n                inser_contact()\n            case '3':\n                name = input('Introduce el nombre del contacto a actualizar: ')\n                if name in agenda:\n                   inser_contact() \n                else:\n                    no_existe()\n            case '4':\n                name = input('Introduce el nombre del contacto a eliminar: ')\n                if name in agenda:\n                    del agenda[name]\n                else:\n                    no_existe()\n\n            case '5':\n                print('Saliendo de la agenda.')\n                break\n            case _:\n                print('Opción no válida. ELige una opción del 1 al 5')\n\nmy_agenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/luisssSoto.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n#  * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea una agenda de contactos por terminal.\n#  * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n#  * - Cada contacto debe tener un nombre y un número de teléfono.\n#  * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n#  *   los datos necesarios para llevarla a cabo.\n#  * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n#  *   (o el número de dígitos que quieras)\n#  * - También se debe proponer una operación de finalización del programa.\n#  */\n\n\"\"\"Lists, Tuples, Dictionaries and Sets\"\"\"\n'''Lists are mutable'''\nzoo=['rhino', 'elephant']\nprint(zoo)\n\n#looking forward\nmyfavoriteAnimal = zoo[0]\nprint(myfavoriteAnimal)\n\n#insert an element\nzoo.append('owl')\nprint(zoo)\n\n#delete last element\nanotherZoo = zoo.pop()\nprint(anotherZoo)\n\n#remove one element\nzoo.remove('rhino')\nprint(zoo)\n\n#update\nzoo.insert(1, 'lion')\n\n#order a list\nzoo.sort()\nprint(zoo)\nprint()\n\n'''tuples'''\n#they are immutable, so that there are lots of limitations\nt = (1,2,2,4,6,1,3)\nprint(t)\n\nprint(1 in t)\nprint(2 not in t)\n\n'''Dictionaries'''\nd = {'dog': 'perro', 'cat': 'gato'}\n\n'''iterate and indexar for the dictionaries'''\nfor americanAnimal in d:\n    print(americanAnimal, end=' ')\nprint()\n\nfor spanishAnimal in d:\n    print(d[spanishAnimal], end=' ')\nprint()\n\n'''Set'''\n#It couldn't exist more than 1 element in the set\ns = {1,2,2,9}\nprint(s)\nprint()\n\n'''Exercise'''\ntelephoneDiary = {'Luis': 3310147389}\nconditional = True\nwelcome = '''Tell me what would you do first:\n                    type...\n                    1 to add a contact\n                    2 to search a contact\n                    3 to update a contact\n                    4 to delete a contact\n                    5 to exit the program: '''\ndef lookingContact(name):\n    try:\n        return telephoneDiary[name]\n    except LookupError as e:\n        print('The name was not found', e) \n\nwhile conditional == True:\n    print('Welcome to your personal telephone diary')\n    request = int(input(welcome))\n    match request:\n        case 1:\n            addContact = input('what about if we add some names on it before start, what is the name of the contact:')\n            if addContact in telephoneDiary:\n                print(\" Be careful, It seems like that contact already exist\")\n                request = \"wanna you do...\\n\" + welcome\n            else:\n                addNumber = input('yes, now what about if you tell me a number of this contact only ten numbers please: ')\n                if addNumber.isdigit() == True and len(addNumber) == 10:\n                    addNumber = int(addNumber)\n                    telephoneDiary[addContact] = addNumber\n                    print(f'The contact: {addContact}, was added with the next number: {addNumber}')\n                    print(telephoneDiary)\n                else:\n                    print('Only ten numbers please 🤨')\n        case 2:\n            searchContact = input('what is the exactly name, that we are looking forward: ')\n            if searchContact in telephoneDiary:\n                print(f'Here is your contact: {searchContact}', telephoneDiary[searchContact])\n            else:\n                print('Sorry but we can\\'t find the contact')\n        case 3:\n            searchContact = input(\"What's the contact that you want to update: \")\n            if searchContact in telephoneDiary:\n                updateNumber = input('Tell me the new number: ')\n                if updateNumber.isdigit() == True and len(updateNumber) == 10:\n                    updateNumber = int(updateNumber)\n                    telephoneDiary[searchContact] = updateNumber\n                else: print('Only ten numbers 😤')\n            else:\n                print('Sorry but we can\\'t find the contact')\n        case 4:\n            searchContact = input('What is the contact who you will get deleted from your list: ')\n            if searchContact in telephoneDiary:\n                telephoneDiary.pop(searchContact)\n                print(f'the contact: {searchContact} was deleted')\n            else:\n                print('Sorry but we can\\'t find the contact')\n        case 5:\n            conditional = False\nprint(telephoneDiary)\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/m1l0j05.py",
    "content": "\"\"\"\nExplicacion teórica:\n\n1. Listas: \n    Secuencia mutable de elementos. Se define con corchetes. Ejemplo: `mi_lista = [1, 2, 3]`.\n2. Tuplas: \n    Secuencia inmutable de elementos. Se define con paréntesis. Ejemplo: `mi_tupla = (1, 2, 3)`.\n3. Conjuntos: \n    Colección no ordenada de elementos únicos. Se define con llaves. Ejemplo: `mi_conjunto = {1, 2, 3}`.\n4. Diccionarios: \n    Colección de pares clave-valor. Se define con llaves y dos puntos. Ejemplo: `mi_diccionario = {'clave': 'valor'}`.\n5. Colas (Queue): \n    Estructura de datos FIFO (First In, First Out) para almacenar elementos.\n6. Pilas (Stack): \n    Estructura de datos LIFO (Last In, First Out) para almacenar elementos.\n7. Arreglos (mediante NumPy): \n    Estructuras eficientes para trabajar con datos numéricos multidimensionales en arrays.\n\n\"\"\"\n# Ejercicios\n# Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n# Utiliza operaciones de inserción, borrado, actualización y ordenación.\n\n# Lista\nmi_lista = [1, 2, 3, 4, 5]\n\n# Inserción en lista\nmi_lista.append(6)\nprint(\"Lista después de inserción:\", mi_lista)\n\n# Borrado en lista\nmi_lista.remove(3)\nprint(\"Lista después de borrado:\", mi_lista)\n\n# Actualización en lista\nmi_lista[0] = 10\nprint(\"Lista después de actualización:\", mi_lista)\n\n# Ordenación en lista\nmi_lista.sort()\nprint(\"Lista ordenada:\", mi_lista)\n\n# Tupla\n# No se pueden realizar operaciones de inserción, borrado, o actualización en tuplas\nmi_tupla = (1, 2, 3, 4, 5)\n\n# Conjunto\nmi_conjunto = {1, 2, 3, 4, 5}\n\n# Inserción en conjunto\nmi_conjunto.add(6)\nprint(\"Conjunto después de inserción:\", mi_conjunto)\n\n# Borrado en conjunto\nmi_conjunto.remove(3)\nprint(\"Conjunto después de borrado:\", mi_conjunto)\n\n# Diccionario\nmi_diccionario = {'clave1': 'valor1', 'clave2': 'valor2', 'clave3': 'valor3'}\n\n# Inserción y actualización en diccionario\nmi_diccionario['clave4'] = 'valor4'\nmi_diccionario['clave1'] = 'nuevo_valor1'\nprint(\"Diccionario después de inserción y actualización:\", mi_diccionario)\n\n# Borrado en diccionario\ndel mi_diccionario['clave2']\nprint(\"Diccionario después de borrado:\", mi_diccionario)\n\n# Cola (Queue) y Pila (Stack)\n# No hay operaciones directas de actualización o ordenación.\n# Cola (Queue)\nfrom queue import Queue\n\nmi_cola = Queue()\nmi_cola.put(1)\nmi_cola.put(2)\nmi_cola.put(3)\n\nprint(\"Cola:\", mi_cola)\n\n# Arreglo (NumPy)\nimport numpy as np\n\nmi_arreglo = np.array([1, 2, 3, 4, 5])\n\n# Actualización en arreglo\nmi_arreglo[0] = 10\nprint(\"Arreglo después de actualización:\", mi_arreglo)\n\n# Ordenación en arreglo\nmi_arreglo.sort()\nprint(\"Arreglo ordenado:\", mi_arreglo)\n\n\n# Ejercicio extra: Agenda de contactos por terminal\n\nimport os\nimport sys\nimport signal\nimport time\n\n### Paleta de colores ###\n### FUNCIONES PREDEFINIDAS PARA IMPRIMIR EN COLORES ###\ndef info_1(skk): print(\"\\033[34m{}\\033[0m\" .format(skk))        ###--- AZUL 1 ---###\ndef succes_1(skk): print(\"\\033[32m{}\\033[0m\" .format(skk))      ###--- VERDE 1 ---###\ndef warning_1(skk): print(\"\\033[33m{}\\033[0m\" .format(skk))     ###--- AMARILLO 1 ---###\n\n### Funcion de captura de Ctrl+c ###\ndef sig_handler(sig, frame):\n        info_1('\\n\\n[!] Saliendo del programa ...\\n')\n        sys.exit(0)\n\n\n### Funcion para limpiar terminal\ndef clean_terminal():\n    operative_system = os.name\n\n    if operative_system == 'posix':  # Linux y macOS\n        os.system('clear')\n    elif operative_system == 'nt':  # Windows\n        os.system('cls')\n    else:\n        warning_1('[!] No se pudo determinar el sistema operativo. La terminal no pudo ser limpiada.')\n\n# Variables globales\ncontact_book = {\n    'Juan': '1234567890',\n    'Maria': '2345678901',\n    'Carlos': '3456789012',\n    'Laura': '4567890123',\n    'Alejandro': '5678901234',\n}\n\n# Funciones\ndef welcome():\n    info_1('\\n\\n[+] Bienvenido a su agenda de contactos')\n\ndef check_book(contacts):\n    if len(contacts) == 0:\n        info_1('\\n\\n[+] Su agenda esta vacia.')\n    else:\n        info_1('\\n\\n[+] Su contactos son:')\n        for contact, number in contacts.items():\n            print('   \\033[96m[-]\\033[0m \\033[32m{}\\033[0m - {}'.format(contact, number))\n            time.sleep(0.1)\n\ndef check_name(contacts, prompt):\n    name_input = input(''.format(info_1(prompt)))\n    if name_input in contacts:\n        contact_exit = True\n    else:\n        contact_exit = False\n    return (name_input, contact_exit)\n\ndef check_number(prompt):\n    while True:\n        number_input = input(''.format(info_1(prompt)))\n        try:\n            if int(number_input):\n                if len(number_input) < 12:\n                    return number_input\n                else:\n                    warning_1('\\n[!] Número no valido. Excede la logitud máxima de 11 digitos, compruebelo. ')\n        except ValueError as error:\n            warning_1('[!] Por favor, introduzca un número valido. ')\n\ndef user_options():\n    info_1('\\n\\n[+] ¿Qué desea hacer?')\n    time.sleep(0.1)\n    succes_1('    [1] Introducir un nuevo contacto. ')\n    time.sleep(0.1)\n    succes_1('    [2] Actualizar un contacto.')\n    time.sleep(0.1)\n    succes_1('    [3] Borrar un contacto.')\n    time.sleep(0.1)\n    succes_1('    [4] Borrar la agenda.')\n    time.sleep(0.1)\n    succes_1('    [5] Salir de la agenda.')\n\n    while True:\n        option_input = input(''.format(info_1('\\n[+] Indique su eleccion:')))\n        try:\n            if int(option_input) <= 0 or int(option_input) > 5:\n                warning_1('[!] Por favor, elija una opción valida. ')\n            else:\n                return int(option_input)\n        except ValueError as error:\n            warning_1('[!] Por favor, elija una opción valida. ')\n\ndef exit_book():\n    info_1('\\n\\n[+] Cerrando la agenda.\\n\\n')\n    time.sleep(0.5)\n    return sys.exit(0)\n\ndef new_contact(contacts):\n    prompt_name = '\\n[+] Indique el nombre del contacto:'\n    name_input = check_name(contacts, prompt_name)\n    if name_input[1]:\n        warning_1('\\n[!] Ya existe el contacto.')\n        time.sleep(1)\n        return\n    prompt_number = '\\n[+] Indique el número del contacto:'\n    number_input = check_number(prompt_number)\n    contact_book[name_input[0]] = int(number_input)\n    return\n\ndef delete_contact(contacts):\n    prompt_name = '\\n[+] Indique el nombre del contacto que quiere borrar:'\n    name_input = check_name(contacts, prompt_name)\n    if name_input[1] == False:\n        warning_1('\\n[!] No existe el contacto para borrar.')\n        time.sleep(1)\n        return\n    else:\n        del contacts[name_input[0]]\n        info_1('\\n[+] Contacto borrado correctamente.')\n        return\n\n    #contact_book[name_input[0]] = int(number_input)\n\ndef update_contact(contacts):\n    prompt_name = '\\n[+] Indique el nombre del contacto que quiere actulizar:'\n    name_input = check_name(contacts, prompt_name)\n    if name_input[1] == False:\n        warning_1('\\n[!] No existe el contacto para actualizar.')\n        time.sleep(1)\n        return\n    prompt_number = '\\n[+] Indique el número del nuevo contacto:'\n    number_input = check_number(prompt_number)\n    contact_book[name_input[0]] = int(number_input)\n\ndef delete_book(contacts):\n    return contacts.clear()\n\ndef update_contact_book(user_option, contacts):\n    if user_option == 1:\n        new_contact(contacts)\n    if user_option == 2:\n        update_contact(contacts)   \n    if user_option == 3:\n        delete_contact(contacts)\n    if user_option == 4:\n        delete_book(contacts)\n    if user_option == 5:\n        exit_book()\n\n# Entrada del programa\nif __name__ == '__main__':\n    signal.signal(signal.SIGINT, sig_handler)\n    clean_terminal()\n    while True:\n        welcome()\n        check_book(contact_book)\n        user_option = user_options()\n        update_contact_book(user_option, contact_book)\n        clean_terminal()\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/majinka10.py",
    "content": "# Listas\n\nlista = [1] # Creación\nprint(lista)\nlista[0] = 2 # Asignación\nprint(lista)\nlista.append(3) # Insertar elemento al final\nprint(lista)\nlista.insert(2, 4) # Insertar elemento en un indice\nprint(lista)\nlista.pop(-1) # Eliminar elemento de la lista por el indice\nprint(lista)\nlista.reverse() # Invertir la lista\nprint(lista)\nlista.sort() # Ordernar la lista en orden ascendente\nprint(lista) \nlista.remove(2) # Elimina un elemento determinado de la lista\nprint(lista) \n\nprint()\n\n# Tuplas inmutables (no se pueden modificar)\n\ntupla = (2, 3, 4)   \n\nprint(f\"Tupla normal: {tupla}\")\n\ndef cuadrado(numero:int) -> int:\n    return numero ** 2\n\ntupla_cuadrado = tuple(map(cuadrado, tupla))\n\nprint(f\"Tupla de cuadrados: {tupla_cuadrado}\")\n\nprint()\n\n# Diccionarios mutable y no ordenado\n\ndiccionario = {'clave': 'valor', 'clave2': [1, 2, 3], 'clave3': False}\nprint(diccionario)\n\ndiccionario['clave4'] = 41 # Insertar elemento al final\nprint(diccionario)\n\ndiccionario.pop('clave') # Eliminar un elemento por la clave\nprint(diccionario)\n\ndiccionario['clave3'] = True # Actualizar valor de una clave\nprint(diccionario)\n\nun_valor = diccionario['clave2'] # Acceder a un valor por la clave\nprint(un_valor)\n\nif 'clave2' in diccionario: # Verificar si existe una clave en el diccionario\n    print('La clave está en el diccionario.')\nelse:\n    print('La clave no está en el diccionario.')\n\n# Sets (conjuntos), no se permite modificar un elemento, no tienen orden.\n    \nlista_a_set = set(lista) # puedo crear un set a partir de una lista\nprint(lista_a_set)\n\nmi_set = {1, 3, 4, 5} # Creacion del set\nprint(mi_set)\n\nmi_set.add(4) # Agregar un elemento al set\nprint(mi_set)\n\nmi_set.update({6, 7}) # Agregar varios elementos al set\nprint(mi_set)\n\nmi_set.remove(4) # Eliminar un elemento del set\nprint(mi_set)\n\nprint()\n\n# Ejercicio EXTRA\n\ndef leer_nombre():\n    while True:\n        entrada = input(\"Ingresa el nombre exacto de tu contacto\\n\")\n        if entrada.isalpha() and len(entrada) > 0:\n            return entrada\n        else:\n            print(\"La entrada debe ser un nombre.\")\n\ndef leer_numero():\n    while True:\n        entrada = input(\"Ingresa el número de teléfono.\\n\")\n        if entrada.isnumeric() and len(entrada) <= 11:\n            return entrada\n        else:\n            print(\"La entrada no es numérica o tiene más de 11 números.\")\n\ncontactos = {'Nombre': 400, 'Felipe': 300}\n\ndef opciones():\n    while True:\n        print('¿Qué deseas realizar?')\n        print('1. Buscar un contacto')\n        print('2. Agregar un contacto')\n        print('3. Actualizar un contacto')\n        print('4. Eliminar un contacto')\n        print('5. Salir')\n\n        accion = input()\n\n        if accion == '1':\n            buscar()\n        elif accion == '2':\n            insertar()\n        elif accion == '3':\n            actualizar()\n        elif accion == '4':\n            eliminar()\n        elif accion == '5':\n            print('Adiós.')\n            break\n        else:\n            print('Inválido.')\n\ndef buscar():\n    nombre = leer_nombre()\n    if nombre in contactos:\n        print(f\"Nombre: {nombre}. Teléfono: {contactos[nombre]}.\")\n    else:\n        print(f\"El contacto '{nombre}' no existe.\")\n\ndef insertar():\n    nombre = leer_nombre()\n    numero = leer_numero()\n    contactos[nombre] = numero\n    print(f\"El contacto {nombre} ha sido añadido.\")\n\ndef actualizar():\n\n    nombre = leer_nombre()\n    if nombre in contactos:\n        print(f\"Nombre: {nombre}. Teléfono: {contactos[nombre]}.\")\n    else:\n        print(f\"El contacto {nombre} no existe.\")\n\n    def actualizar_numero(nombre: str, nuevo_numero: int):\n        contactos[nombre] = nuevo_numero\n        print('El número de teléfono del contacto ha sido actualizado.')\n    \n    def actualizar_nombre(nombre: str, nuevo_nombre: str):\n        contactos[nuevo_nombre] = contactos.pop(nombre)\n        print('El nombre del contacto ha sido actualizado.')\n\n    def opciones_actualizar(nombre: str):\n        accion = input(\"1. Deseo cambiar el número.\\n2. Deseo cambiar el nombre.\\n\")\n\n        if accion == '1':\n            nuevo_numero = leer_numero()\n            actualizar_numero(nombre, nuevo_numero)\n        elif accion == '2':\n            nuevo_nombre = leer_nombre()\n            actualizar_nombre(nombre, nuevo_nombre)\n        else:\n            print('Inválido.')\n            opciones_actualizar()\n\n    opciones_actualizar(nombre)\n        \n\ndef eliminar():\n    nombre = leer_nombre()\n    if nombre in contactos:\n        print(f\"Nombre: {nombre}. Teléfono: {contactos[nombre]}.\")\n    else:\n        print(f\"El contacto {nombre} no existe.\")\n    \n    def opciones_eliminar():\n        acccion = input('¿Quieres eliminar este contacto?\\n1. Sí.\\n2. No\\n')\n\n        if acccion == '1':\n            contactos.pop(nombre)\n            print('El contacto ha sido eliminado.')\n        elif acccion == '2':\n            print('Te perdono.')\n        else:\n            opciones_eliminar()\n        \n    opciones_eliminar()\n\nopciones()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/mallcca.py",
    "content": "'''\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n '''\n\nprint('-----------------------------------------------------------')\nprint('Ejemplo de tuplas')\nprint('-----------------------------------------------------------')\ntup = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)\nprint(tup)\n\nprint('- Seleccionando un elemento')\nprint(tup[2])\nprint('- Agregando elementos a una tupla')\nprint(tup + (100, 200))\nprint('- Actualizando elementos de una tupla')\ntry:\n    tup[2] = 300\nexcept:\n    print('- No se pueden eliminar elementos porque una tupla es inmutable ')\nprint('- Eliminando elementos de una tupla')\nprint('No se pueden eliminar elementos porque una tupla es inmutable')\nprint('- Ordenando elementos de una tupla')\nprint(tuple(sorted(tup, reverse=True)))\n\nprint('-----------------------------------------------------------')\nprint('Ejemplo de listas')\nprint('-----------------------------------------------------------')\nlist = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\nprint(list)\n\nprint('- Seleccionando un elemento')\nprint(list[2])\nprint('- Agregando elementos a una lista')\nlist.append(200)\nprint(list)\nprint('- Actualizando elementos a una lista')\nlist[0] = -100\nprint(list)\nprint('- Eliminando elementos a una lista')\ndel list[0]\nprint(list)\nprint('- Ordenando elementos de una lista')\nlist.sort(reverse=True)\nprint(list)\n\n\nprint('-----------------------------------------------------------')\nprint('Ejemplo de diccionarios')\nprint('-----------------------------------------------------------')\ndict = {1: 'one', 2: 'two', 3: 'three', 4: 'four', 5: 'five', 6: 'six', 7: 'seven', 8: 'eight', 9: 'nine', 10: 'ten'}\nprint(dict)\n\nprint('- Seleccionando un elemento')\nprint(dict[2])\nprint('- Agregando elementos a una dict')\ndict[11] = 'eleven'\nprint(dict)\nprint('- Actualizando elementos a una dict')\ndict[2] = 'dos'\nprint(dict)\nprint('- Eliminando elementos a una dict')\nval_eliminado = dict.pop(1)\nprint(val_eliminado)\nprint(dict)\nprint('- Ordenando elementos de una dict')\ndict_2 ={x: dict[x] for x in sorted(dict, reverse=True)}\nprint(dict_2)\n\n\nprint('-----------------------------------------------------------')\nprint('Ejemplo de set')\nprint('-----------------------------------------------------------')\nv_set = {1, 2, 3, 4, 100}\nprint(v_set)\n\nprint('- Seleccionando un elemento')\nprint('Los elementos no se pueden consultar directamente solo se puede usar in')\nprint(2 in v_set)\nprint('- Agregando elementos a un set')\nv_set.add(200)\nprint(v_set)\nprint('- Actualizando elementos a un set')\nprint('No se puede modificar un valor de un set')\nprint('- Eliminando elementos a un set')\nv_set.remove(100)\nprint(v_set)\nprint('- Ordenando elementos de un set')\nv_set_2 = sorted(v_set, reverse=True)\nprint(v_set_2)\n\n'''\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n'''\n# Funciones\ndef f_inicio():\n    print('-----------------------PANTALLA DE INICIO------------------')\n    print('-- 1. Consultar un contacto')\n    print('-- 2. Agregar un contacto')\n    print('-- 3. Editar un contacto')\n    print('-- 4. Eliminar un contacto')\n    print('-- 5. Salir')\n    print('-----------------------PANTALLA DE INICIO------------------')\n\ndef f_input_telf():\n    flag = 0\n    while flag == 0:\n        telefono = input('Ingrese el número del contacto [Màximo 9 digitos]: ')\n        try:\n            if int(telefono) >= 100000000 and int(telefono) <= 1000000000:\n                return telefono\n        except:\n            pass\n        print('-- !El número debe tner 9 dígitos ...')\n\ndef f_consultar(dict):\n    if not dict:\n        print('-- !Agenda vacía...')\n    for nom in dict.keys():\n        print('-- ' + nom + ': ' + dict[nom])\n\ndef f_editar(nom_con, dict, opc=100):\n    if opc == '3':\n        if nom_con not in dict:\n            input('El contacto no existe...')\n            return \n    \n    tel_con = f_input_telf()\n    dict[nom_con] = tel_con\n\ndef f_agregar(nom_con, dict):\n    if nom_con in dict:\n        opcion_sn = input('El contacto ya existe desea modificarlo (S/N)?...: ')\n        if opcion_sn.upper() == 'N':\n            return        \n    \n    f_editar(nom_con, dict)    \n\ndef f_eliminar(nom_con, dict):\n    if nom_con in dict:\n        del dict[nom_con]\n        print('Contacto eliminado ...')\n\n        return\n    print('Contacto no existe ...')\n    \n    \n# Variables iniciales\nagenda = {}\n\nwhile True:\n    f_inicio()\n    opcion = input('Ingree una opción: ')\n\n    if opcion == '1':\n        f_consultar(agenda)\n    elif opcion == '2':\n        nom_contacto = input('Ingrese el nombre del contacto: ')\n        f_agregar(nom_contacto, agenda)\n    elif opcion == '3':\n        nom_contacto = input('Ingrese el nombre del contacto: ')\n        f_editar(nom_contacto, agenda, opcion)\n    elif opcion == '4':\n        nom_contacto = input('Ingrese el nombre del contacto: ')\n        f_eliminar(nom_contacto, agenda)\n    elif opcion == '5':\n        print('-- !Saliendo del programa ...')\n    else:\n        print('--!Opción no válida ...')\n        \n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/manjaitan.py",
    "content": "# ESTRUCTURAS DE DATOS en python:\n\n# listas, tuplas, diccionarios:\n\n# LISTAS (mutables).\n\ndeportes = ['ciclismo','atletismo','motociclismo','automovilismo']\n\n# insertar en lista: \ndeportes.append('barranquismo')\nprint (type(deportes))\nprint (deportes)\n\n\n# borrado en lista:\ndeportes.remove('barranquismo')\nprint (type(deportes))\nprint(deportes)\n\n# actualizar elemento de lista: (actualizamos la posición 3 de la lista, retiramos )\ndeportes[3] = 'barranquismo'\nprint (type(deportes))\nprint  (deportes)\n\n# Ordenacion de listas:\ndeportes.sort() # ordena los items de la lista alfabeticamente.\nprint (type(deportes))\nprint(deportes)\n\n# TUPLAS: (inmutables)\n\nnumeros = (1,2,3,4,5,6,7,8,9,10) # A diferencia de las listas, las tuplas se crean entre parentesis.\nprint (type(numeros))\nprint (numeros)\n\nnumeros = 1,2,3,4,5,6,7,8,9,10 # Otra forma de declarar las tuplas.\nprint (type(numeros))\nprint (numeros)\n\n# DICCIONARIOS:\n\ndiccionario = {} # creamos el diccionario.\ndiccionario1 = {\n    \"nombre\" : \"Antonio Perez Fernández\",\n    \"usuario\" : \"antonio\",\n    \"perfil\" : \"admin\"\n    \n}\n\n\nprint (type(diccionario))\nprint (diccionario)\nprint (type(diccionario1))\nprint (diccionario1)\n\ndiccionario2 = {\n    \"nombre\" : \"manjaitan\",\n    \"usuario\" : \"manjaitan\",\n    \"perfil\" : \"admin\"\n    \n}\n\n# Añadimos clave:valor del diccionario2.\ndiccionario2['perfil1']='propietario'\ndiccionario2['estado']='activo'\nprint (diccionario2)\n\n# Borrar clave:valor del diccionario2.\ndel diccionario2[\"estado\"]\nprint(diccionario2)\n\n# Actualizar valores del diccionario2.\ndiccionario2[\"perfil1\"]='delegado'\nprint(diccionario2)\n\n# Eliminar diccionario completo.\ndel diccionario2\n# print(diccionario2) # lo comentamos para no generar error.\n\n#### OPCIONAL:\n\nopciones = [\n\"1. Búsqueda de contacto\",\n\"2. Crear nuevo contacto\",\n\"3. Actualización de contacto\",\n\"4. Eliminación de contacto\",\n\"5. Salir\"\n]\n\n# Creamos un diccionario con las claves y valores que necesitamos.\ncontacto = {\n    'Angel' : '123123123',\n    'Pedro' : '123123321',\n    'Fran' : '321321321',\n    }\n    \n\nwhile True:\n    print ('########## MENU OPCIONES ###############')\n    print ('Valores del diccionario')\n    print (contacto)\n    print ('#########################################')\n    \n    for opcion in opciones:\n        print(opcion)\n        \n    opcion = input(\"Ingrese una opción: \")\n    \n    if (opcion == '5'): \n        break\n    \n    elif (opcion == '1'):\n        \n        print('##### BUSQUEDA DE CONTACTO ########')\n        \n        busca = input(\"Ingrese nombre de contactoa a buscar: \")\n        res_get = contacto.get(busca, 2000)\n        \n        if ( res_get == 2000):\n            \n            print('elemento no encontrado')\n            \n        else:\n            \n            print ('elemento encontrado')\n            print (busca)\n            print (contacto.get(busca))\n    \n    elif (opcion == '2'):\n        \n        print('##### CREACION DE NUEVO CONTACTO ########')\n        n = input ('Ingrese nombre de contacto: ')\n        t = input('Ingrese número telefono contacto: ')\n        \n        if (len(t) >= 11):\n            print ('nº de telefono +11 digitos no es correcto, no se inserta registro')\n        elif (t.isalpha()): \n            print ('nº de telefono contiene caracteres alphanumericos')\n        else:\n            print ('campos OK, se inserta nuevo contacto en diccionario')\n            contacto.setdefault(n,t)\n    \n    elif (opcion == '3'):\n        \n        print('##### ACTUALIZACION DE UN CONTACTO ########')\n        \n        nam_upd = input(\"Ingrese nombre de contacto a actualizar: \")\n        tel_upd = input('Ingrese número telefono contacto: ')\n        \n        get_bus = contacto.get(nam_upd, 3000)\n        \n        if ( get_bus == 3000):\n            print('elemento no encontrado')\n        elif (tel_upd.isalpha()): \n            print ('nº de telefono contiene caracteres alphanumericos')\n        elif (len(tel_upd) >= 11):\n            print ('nº de telefono +11 digitos no es correcto, no se actualiza registro')\n        else:\n            print ('campos OK, se actualiza el contacto')\n            contacto.update({nam_upd:tel_upd})\n        \n    elif (opcion == '4'):\n    \n        print ('##### ELIMINAR CONTACTO ########')\n        print(contacto)\n        e = input ('Ingrese nombre de contacto que desea eliminar: ')\n        res_del = contacto.get(e, 5000)\n        \n        if ( res_del == 5000):\n            print('elemento no encontrado')\n        else:\n            print ('elemento encontrado')\n            contacto.pop(e)\n            print ('elemento borrado')"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/marcelosanchez166.py",
    "content": "# EJERCICIO:\n# - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n# - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n\n# DIFICULTAD EXTRA (opcional):\n# Crea una agenda de contactos por terminal.\n# - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n# - Cada contacto debe tener un nombre y un número de teléfono.\n# - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n#   los datos necesarios para llevarla a cabo.\n# - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n#   (o el número de dígitos que quieras)\n# - También se debe proponer una operación de finalización del programa.\n\nlista = [1, 2, 3, 4, 5]\ntupla = (1, 2, 3, 4, 5)\ndiccionario = {\n    \"nombre\": \"Juan\",\n    \"edad\": 30,\n    \"ciudad\": \"Madrid\"\n}\nsets = {1, 2, 3, 4, 5}\n# Operaciones con lista\nlista.append(6)  # Inserción\nlista.remove(2)  # Borrado\nlista[0] = 10  # Actualización\nlista.sort()  # Ordenación\nprint(\"Lista:\", lista)\n\n# Operaciones con tupla (inmutable, no se pueden modificar)\nprint(\"Tupla:\", tupla)\n# Tuplas no permiten inserción, borrado o actualización, pero se pueden crear nuevas tuplas\ntupla_nueva = tupla + (6,)  # Creación de nueva tupla\nprint(\"Nueva tupla:\", tupla_nueva)\n# Tuplas no permiten ordenación, pero se pueden convertir a lista\ntupla_a_lista = list(tupla)\nprint(\"Tupla convertida a lista:\", tupla_a_lista)\n\n\n# Operaciones con diccionario\ndiccionario[\"edad\"] = 31  # Actualización\ndiccionario[\"pais\"] = \"España\"  # Inserción\nprint(\"Diccionario:\", diccionario)\ndiccionario.pop(\"ciudad\")  # Borrado\nprint(\"Diccionario después de borrar ciudad:\", diccionario)\n# Ordenación de diccionario por claves\ndiccionario_ordenado = dict(sorted(diccionario.items()))\nprint(\"Diccionario ordenado por claves:\", diccionario_ordenado)\n# Ordenación de diccionario por valores\ndiccionario_ordenado_valores = dict(sorted(diccionario.items()))\nprint(\"Diccionario ordenado por valores:\", diccionario_ordenado_valores)\n\n\n# Operaciones con sets\nsets.add(6)  # Inserción\nsets.discard(2)  # Borrado\nprint(\"Set:\", sets)\n# Sets no permiten actualización, pero se pueden crear nuevos sets\nsets_nuevo = sets.union({7, 8})  # Creación de nuevo set\nprint(\"Nuevo set:\", sets_nuevo)\n\n# Agenda de contactos\nagenda = {}\n\n\ndef agregar_contacto(nombre, telefono):\n    if telefono.isdigit() and len(telefono) <= 11:\n        agenda[nombre] = telefono\n        print(f\"Contacto {nombre} agregado con éxito.\")\n    else:\n        print(\"Número de teléfono no válido. Debe ser numérico y tener hasta 11 dígitos.\")\n\n\ndef buscar_contacto(nombre):\n    if nombre in agenda:\n        print(f\"Contacto encontrado: {nombre} - {agenda[nombre]}\")\n    else:\n        print(f\"Contacto {nombre} no encontrado.\")\n\n\ndef actualizar_contacto(nombre, telefono):\n    if nombre in agenda:\n        if telefono.isdigit() and len(telefono) <= 11:\n            agenda[nombre] = telefono\n            print(f\"Contacto {nombre} actualizado con éxito.\")\n        else:\n            print(\"Número de teléfono no válido. Debe ser numérico y tener hasta 11 dígitos.\")\n    else:\n        print(f\"Contacto {nombre} no encontrado.\")\n\n\ndef eliminar_contacto(nombre):\n    if nombre in agenda:\n        del agenda[nombre]\n        print(f\"Contacto {nombre} eliminado con éxito.\")\n    else:\n        print(f\"Contacto {nombre} no encontrado.\")\n\n\ndef mostrar_agenda():\n    if agenda:\n        print(\"Agenda de contactos:\")\n        for nombre, telefono in agenda.items():\n            print(f\"{nombre}: {telefono}\")\n    else:\n        print(\"La agenda está vacía.\")\n\n\ndef main():\n    while True:\n        print(\"\\nOpciones:\")\n        print(\"1. Agregar contacto\")\n        print(\"2. Buscar contacto\")\n        print(\"3. Actualizar contacto\")\n        print(\"4. Eliminar contacto\")\n        print(\"5. Mostrar agenda\")\n        print(\"6. Salir\")\n\n        opcion = input(\"Seleccione una opción: \")\n\n        if opcion == \"1\":\n            nombre = input(\"Ingrese el nombre del contacto: \")\n            telefono = input(\"Ingrese el número de teléfono: \")\n            agregar_contacto(nombre, telefono)\n        elif opcion == \"2\":\n            nombre = input(\"Ingrese el nombre del contacto a buscar: \")\n            buscar_contacto(nombre)\n        elif opcion == \"3\":\n            nombre = input(\"Ingrese el nombre del contacto a actualizar: \")\n            telefono = input(\"Ingrese el nuevo número de teléfono: \")\n            actualizar_contacto(nombre, telefono)\n        elif opcion == \"4\":\n            nombre = input(\"Ingrese el nombre del contacto a eliminar: \")\n            eliminar_contacto(nombre)\n        elif opcion == \"5\":\n            mostrar_agenda()\n        elif opcion == \"6\":\n            print(\"Saliendo del programa...\")\n            break\n        else:\n            print(\"Opción no válida. Intente de nuevo.\")\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/mariovelascodev.py",
    "content": "#Listas\nprint(\"----LISTAS----\")\n\nlista = [1, 2, 3, 4, \"hola\"]\nprint(lista)\n\n#Eliminación  de datos de una lista\ndel lista[4]\nprint(f\"Hemos eliminado un dato de la lista {lista}\")\n\n#Añadir elementos al final de una lista\nlista.append(28)\nprint(f\"Elemento añadido al final de la lista {lista}\")\n\n#Añadir una lista a la lista inicial\nlista.extend([6,100])\nprint(f\"Nueva lista añadida a la lista inicial {lista}\")\n\n#Añadir un dato en el indice indicado\nlista.insert(1, 255)\nprint(f\"Elemento añadido en la posicion [1] de la lista {lista}\")\n\n#Borrado de un elemento de una lista\nlista.remove(3)\nprint(f\"Borrado de un elemento de la lista {lista}\")\n\n#Eliminación por defecto del último elemento de una lista\nlista.pop()\nprint(f\"Eliminación por defecto del último elemento de la lista {lista}\")\n\n#Invertir el orden de la lista\nlista.reverse()\nprint(f\"Lista en orden inverso {lista}\")\n\n#Ordena los elementos de la lista de menor a mayor por defecto\nlista.sort()\nprint(f\"Ordenados los elementos de la lista de menor a mayor {lista}\")\n\n#Ordena los elementos de la lista de mayor a menor\nlista.sort(reverse=True)\nprint(f\"Ordenados los elementos de la lista de menor a mayor {lista}\")\n\nprint(\"----SET----\")\n\nconjunto = {5, 4, 6, 8, 8, 1}\nprint(conjunto)\n\n#Añadir elemento\nconjunto.add(\"Python\")\nprint(f\"Añadir elemento en un set {conjunto}\")\n\n#Eliminar elemento indicado\nconjunto.remove(5)\nprint(f\"Eliminación del elemento indicado {conjunto}\")\n\n#Eliminación aleatoria de un elemento\nconjunto.pop()\nprint(f\"Eliminación aleatoria de un elemento {conjunto}\")\n\n#Actualización de los elementos\nconjunto.update({\"Manzana\", 34, True})\nprint(f\"Actualización de los elementos del set {conjunto}\")\n\n#Eliminación de todos los elementos\nconjunto.clear()\nprint(f\"Eliminación de todos los elementos {conjunto}\")\n\nprint(\"----TUPLAS----\")\n\ntupla = (1, 2, 3)\nprint(f\"{tupla}\\n Las tuplas son una lista de valores inmutables, con lo cual no se le pueden hacer ninguna operación de insercción, borrado, actualización y ordenación\")  \n\nprint(\"----DICCIONARIOS----\")\n\ndiccionario = {\n    \"nombre\": \"Mario\",\n    \"edad\": 33,\n    \"altura\": 1.80,\n    \"developer\": True \n}\nprint(diccionario)\n\n#Inserción de valores del diccionario\ndiccionario[\"telefono\"] = 123456789\nprint(f\"Se ha modificado el valor de la clave nombre del diccionario {diccionario}\")\n\n#Eliminar la key indicada del diccionario\ndiccionario.pop(\"altura\")\nprint(f\"Se elimina una key del diccionario {diccionario}\")\n\n#Eliminar de forma aleatoria un elemento del diccionario\ndiccionario.popitem()\nprint(f\"Eliminación aleatoria de un elemento del diccionario {diccionario}\")\n\n#Actualizar diccionario con otro diccionario\ndiccionario1 = {\n    \"lenguajes\": [\"python\", \"js\", \"html\", \"css\"]\n}\n\ndiccionario.update(diccionario1)\nprint(f\"Actualizado de un diccionario con otro diccionario {diccionario}\")\n\n#Eliminar todo el contenido del diccionario\ndiccionario.clear()\nprint(f\"Eliminamos todo el contenido del diccionario {diccionario}\")\n\nprint(\"----EXTRA----\")\n\ndef contact_list():\n    \n    #Creamos un diccionario, que contendra el nombre y el teléfono de los contactos\n    agenda = {\n    \"Mario\": 123456678,\n    \"Sara\": 1423423435\n    }\n\n    #Creamos un variable booleana para poder controlar el bucle del menu de opciones\n    leave = True\n\n    #Creamos bucle que contentra el menu de opciones\n    while leave == True:\n\n        #Mostramos las opciones del menu y preguntamos al usuario que desea hacer\n        print(\"1 - Búsqueda de contacto\\n2 - Añadir contacto\\n3 - Actualizar contacto\\n4 - Eliminar contacto\\n5 - Salir\")\n        ask = input(\"¿Qué desea hacer? \")\n        answer = int(ask)\n\n        #Dependiendo de la opción seleccionada el menu entrará en dicha opción\n        if answer == 1:\n            #Se introduce por consola el nombre del usuario a buscar\n            search = input(\"Introduce el nombre del contacto a buscar \")\n            try:\n                print(agenda[search])\n            except KeyError:\n                print(\"Usuario no encontrado\")\n        elif answer == 2:\n            #Añadimos el nombre y el número de teléfono del nuevo contacto\n            add = input(\"Añade el nombre del nuevo contacto \")\n            condition = True\n            #Si el número de teléfono no tiene 9 dígitos o no es un número, se le pedirá al usuario que vuelva a introducir el número\n            while condition == True:\n                number = input(\"Añade el número de teléfono \")\n                if len(number) == 9:\n                    try:\n                        agenda[add] = int(number)\n                        print(\"Añadido el contacto\")\n                        condition = False\n                    except ValueError:\n                        print(\"No has introducido un número\")\n                else:\n                    print(\"La longitud del número es menor o superior a 9 dígitos\")\n        elif answer == 3:\n            #Se pide por consola el nombre del contacto y el número de teléfono que se actualizará\n            update_name = input(\"Añade el nombre del contacto \")\n            update_phone = input(\"Añade el número de teléfono a actualizar \")\n            agenda[update_name] = update_phone\n            print(\"Actualizado el número de teléfono del contacto\")\n        elif answer == 4:\n            #Se pide por consola el nombre del contacto a eliminar\n            remove = input(\"Añade el nombre del contacto a eliminar \")\n            agenda.pop(remove)\n            print(f\"Eliminado el contacto de {remove}\")\n        elif answer == 5:\n            #Finaliza el programa\n            leave = False\n        else:\n            print(\"Introduce un número entre 1 y 5\")\n\ncontact_list()\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/maxiRica.py",
    "content": "import os\ndef limpiar(): # Como si voy ejecutando más de una vez me \"ensucia\" la terminal, creo una función para que me limpie antes de arrancar\n    os.system('cls' if os.name == 'nt' else 'clear')\n\n\"\"\"\nLISTAS. En Python no existen Arrays. Las listas permiten la heterogeneidad de tipos de variables\ndentro de la lista, a diferencia de las Arrays que solo permiten tener variables del mismo tipo\n\"\"\"\nlimpiar()\nlista=[\"primero\",2,3.0]\nprint(f\"Inicio la lista siguiente: {lista}\\n\")\n\n# .insert(`indice`,objeto) posiciona en el índice señalado (indice) un valor (objeto)\nlista.insert(2,\"segundo\")\nprint(f\"Añado segundo a la lista en la posición 2: {lista}\\n\")\n\n# .append(objeto) añado al final un nuevo valor\nlista.append(\"tercero\")\nprint(f\"Uso append para incorporar valor al final: {lista}\\n\")\n\n# .remove(objeto) eliminia primer objeto que coincida dentro de la lista\nremove = \"segundo\"\nlista.remove(remove)\nprint(f\"Uso de remove para eliminar el valor \\\"{remove}\\\" de la lista: {lista}\\n\")\n\n# .pop(indice) elimina el valor de la posición indicada. Si no lo acompañas se borra el último (sirve para creaciones de pilas)\nlista.pop()\nprint(f\"Borra el último de la lista con pop, o si indicas la posición, borra el de la posición: {lista}\\n\")\n\n# .index(elemento) retorna el indice de la posición del elemento\nprint(f\"Me da la posición del elemento que le paso en la búsqueda con .index(2): {lista}\")\nprint(f\"{lista.index(2)}\\n\")\n\n# .copy() copia la lista en una nueva lista\nnueva_lista = lista.copy()\nprint(f\"Con .copy copias el contenido en una nueva lista (nueva_lista = lista.copy()): nueva_lista = {nueva_lista}\\n\")\n\n# .clear() limpia los valores de la lista\nlista.clear()\nprint(f\"Con .clear borras el contenido de la lista: {lista}\\n\")\n\n# .sort() ordenas los valores de manera ascendente\nnueva_lista.remove(\"primero\")\nnueva_lista.sort(reverse=True)\nprint(f\"He realizado un nueva_lista.sort() para ordenar los valores con carácter ascendente, o descendente (lo he creado descendente): {nueva_lista}\\n\")\n\n# .reverse() invierte el orden\nnueva_lista.reverse()\nprint(f\"Con la función .reverse() invierto el orden de los valores en la lista: {nueva_lista}\\n\")\n\n# . count(elemento) me responde con la cantidad de veces que se encuentra ese elemento dentro de la lista\ncontador = nueva_lista.count(2)\nprint(f\"Con .count(elemento) me devuelve la cantidad de veces que se encuentra dentro de la lista nueva_lista.count(2): {contador}\\n\")\n\n# Se puede mostrar un elemento haciendo referència a su indice\ntry:\n   elemento = nueva_lista[2]\n   print(f\"muestro el puesto 2, con nueva_lista[2]: {elemento}\\n\")\n\nexcept IndexError: \n    print(\"nueva_lista[2]: ¡¡Error en el índice!!\\n\")\n\n# Se puede ver los elementos de la lista desde la cola indicando un valor negativo, desde -1 (último)\nprint(f\"muestra último elemento haciendo refereréncia en el index con el -1. nueva_lista[-1]: {nueva_lista[-1]}\\n\")\n\n# Se puede modificar los elementos señalizando el elemento en el indice\nnueva_lista[-1]=4\nprint(f\"modifico el último elemento. nueva_lista[-1]=4: nueva_lista={nueva_lista}\\n\")\n\n\"\"\"\nTuplas. La tupla es una lista que a posterioridad serán inmutables los elementos, ordenados y indexados.\nSe inicializan con parentesis, o sin ellos.\n\"\"\"\nprint(\"TUPLAS\\n\")\ntuplaA=3,5,1,\"primero\",\"segundo\",\"tercero\"\nprint(f\"valores de tuplaA: {tuplaA}\\n\")\n\n#llamada a los elementos mediante el índice\nprint(f\"vamos a sacar el 1er valor de la tupla tuplaA[0]: {tuplaA[0]}\\n\")\n\n#función de count como en las listas\nprint(f\"Usamos la función .count() para que nos de el resultado de la cantidad de veces que existe dentro de la tupla. tuplaA.count(1): {tuplaA.count(1)}\\n\")\n\n\"\"\"\nDiccionarios.\nTiene clave y valor. Las claves son inmutables, y el valor se puede modificar\n\"\"\"\n# asignación de valores\nmi_Diccionario = {\"nombre\":\"juan\", \"apellidos\": \"perez mujica\"}\nprint(f\"asigno los valores del diccionario mi_Diccionario: {mi_Diccionario}\\n\")\n\n# canvio del valor en una llave\nmi_Diccionario[\"apellidos\"]=\"Ruiz Gallardo\"\nprint(f\"cambio los valores de los apellidos a Ruiz Gallardo: {mi_Diccionario}\\n\")\n\n# acceso y modificaciones de los valores y claves de un diccionario\n\nprint(mi_Diccionario.keys()) # entrega las claves del diccionario\nprint(\"\\n\")\n\nprint (mi_Diccionario.values()) # entrega los valores del diccionario\nprint(\"\\n\")\n\nprint(mi_Diccionario.popitem()) # entrega última clave-valor y lo eleimina\nprint(f\"Ahora mi_Diccionario tiene los elementos: {mi_Diccionario}\\n\")\n\n\"\"\"\nAGENDA\n\"\"\"\n\nagenda ={}\nwhile True:\n    while True:         # iniciamos la consulta de que quiere hacer el usuario\n        limpio=input(\"limpio la pantalla? (si) o (no): \")\n        if limpio==\"si\": \n            limpiar()\n        elif limpio==\"no\":\n            pass\n        print(\"\\n\")\n        print(\"++++++++++++++++++++++++++++++++++++++++++\")\n        print(\"           A G E N D A\\n\")\n        print(\"++++++++++++++++++++++++++++++++++++++++++\\n\")\n        print(\"1- Busqueda de un contacto\\n\")\n        print(\"2- Inserción de un contacto\\n\")\n        print(\"3- Actualización de un contacto\\n\")\n        print(\"4- Eliminación de un contacto\\n\")\n        print(\"5- Listado de contactos\\n\")\n        print(\"6- EXIT\\n\")\n        \n        entrada=input(\"escribe opción: \\n\")\n        if agenda == {} and (entrada==\"1\" or entrada==\"3\" or entrada==\"4\" or entrada==\"5\"):\n            print(\"la agenda está vacia\\n\")\n            continue\n        elif entrada == \"1\" or entrada == \"2\" or entrada == \"3\" or entrada ==\"4\" or entrada==\"5\" or entrada==\"6\":\n            print(\"procesando\\n\")\n            break\n        else:\n            print(\"no has escogido correctamente\")    \n\n    # Gestionamos la opción decidia\n\n    if entrada == \"1\":                  # OPCIÓN 1- Busqueda de contacto\n        nombre=input(\"nombre: \")\n        elemento= agenda.get(nombre)\n        if elemento == None:\n            print(\"no existe contacto\")\n        else:\n            print(elemento)\n\n    elif entrada == \"2\":                # OPCIÓN 2- Introducción de contacto\n        print(\"introducimos un nuevo contacto\\n\")\n        nombre=input(\"nombre: \")\n        apellidos=input(\"apellidos: \")\n        telefono=input(\"teléfono: \")\n        agenda[nombre] = [apellidos, telefono]\n        \n\n    elif entrada == \"3\":                # OPCIÓN 3- solicitamos que contacto quiere actualizar y el que\n        bucle=True\n        while bucle:\n            \n            nombre=input(\"dame el nombre del contacto a actualizar: \")\n            print(\"que quieres realizar: \\n\")\n            print(\"1- actualizar nombre: \\n\")\n            print(\"2- actualizar apellidos: \\n\")\n            print(\"3- actualizar telefono: \\n\")\n            print(\"4- volver\")\n            opcion=input(\"escribe la opción: \")\n\n            if opcion==\"1\":\n                if nombre in agenda:\n                    nuevo_contacto=agenda.pop(nombre)\n                    nuevo_nombre=input(\"introduce el nuevo nombre: \")\n                    agenda[nuevo_nombre]=nuevo_contacto\n                    apellidos_diccionario=agenda.get(nuevo_nombre)\n                print(\"contacto actualizado: \",nuevo_nombre,*apellidos_diccionario)\n                bucle=False\n            elif opcion==\"2\":\n                if nombre in agenda:\n                    nuevo_apellido=input(\"introduce los apellidos: \\n\")\n                    valores=agenda.get(nombre)\n                    tel=valores[1]\n                    agenda[nombre]=[nuevo_apellido,tel]\n                    valores=agenda.get(nombre)\n                print(\"contacto actualizado: \",nombre, *valores)\n            elif opcion==\"3\":\n                if nombre in agenda:\n                    nuevo_telefono=input(\"introduce el nuevo teléfono: \\n\")\n                    valores=agenda.get(nombre)\n                    apell=valores[0]\n                    agenda[nombre]=[apell,nuevo_telefono]\n                    valores=agenda.get(nombre)\n                print(\"contacto actualizado: \",nombre, *valores)\n                bucle=False\n            elif opcion==\"4\":\n                bucle=False\n    elif entrada == \"4\":                # OPCIÓN 4- solicitamos que contacto quiere eliminar\n        bucle=True\n        while bucle:\n            contacto_elim=input(\"dame el nombre del contacto a eliminar: \")\n            if contacto_elim in agenda:\n                alerta=input(\"estas seguro que quieres borrar el contacto?? (si - no): \")\n                if alerta==\"si\": \n                    agenda.pop(contacto_elim)\n                    print(\"contacto eliminado\\n\")\n                    bucle=False\n                elif alerta==\"no\":\n                    bucle=False\n    elif entrada == \"5\":                # listamos los contactos\n        bucle=True\n        for clave in agenda:\n            valores=agenda.get(clave)\n            print(clave,*valores) \n            bucle=False\n    elif entrada == \"6\":\n        break\n                \n            "
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/mensius87.py",
    "content": "\"\"\"\n#03 ESTRUCTURAS DE DATOS\nDificultad: Media | Publicación: 15/01/24 | Corrección: 22/01/24\n\nEjercicio\n\n/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\"\"\"\n\n# listas: colección ordenada y mutable de elementos\nprint(\"::::::::::::::::::::::::::::::::::::: LISTAS :::::::::::::::::::::::::::::::::::::\")\nlista_colores = [\"rojo\", \"verde\", \"azul\", \"amarillo\", \"marrón\", \"naranja\", \"blanco\", \"negro\"]\n\nprint(f\"Lista inicial:\\n{lista_colores}\\n\")\n\n\n# Inserción en listas\nlista_colores.append(\"violeta\")\n\nprint(f\"Añadido color violeta:\\n {lista_colores}\\n\")\n\n\n# Actualización del nuevo color (cambio de violeta por fucsia).\nlista_colores[-1] = \"fucsia\"\n\nprint(f\"Cambiado color violeta por fucsia:\\n {lista_colores}\\n\")\n\n\n# Borrado del color\nlista_colores.remove(\"fucsia\")\n\nprint(f\"Eliminado color fucsia:\\n {lista_colores}\\n\")\n\n\n# Ordenado alfabético\nlista_colores.sort()\n\nprint(f\"Lista ordenada:\\n {lista_colores}\\n\\n\")\n\n\n\n# Tuplas: colección ordenada e inmutable (no se puede modificar una vez creada ni añadir ni eliminar nada)\nprint(\"::::::::::::::::::::::::::::::::::::: TUPLAS :::::::::::::::::::::::::::::::::::::\")\ntupla_paises = (\"España\", \"Portugal\", \"USA\", \"Alemania\", \"Suecia\")\n\nprint(f\"Tupla inicial:\\n{tupla_paises}\\n\")\n\n\n# Ordenar tupla (indirectamente)\ntupla_ordenada = tuple(sorted(tupla_paises))\n\nprint(f\"Tupla ordenada:\\n{tupla_ordenada}\\n\\n\")\n\n\n\n# Conjuntos: colección desordenada y mutable de elementos únicos (no se pueden modificar ni ordenar)\nprint(\"::::::::::::::::::::::::::::::::::::: CONJUNTOS :::::::::::::::::::::::::::::::::::::\")\nconjunto_numeros = {1, 2, 3, 4, 5}\nprint(f\"Conjunto inicial:\\n{conjunto_numeros}\\n\")\n\nconjunto_numeros.add(10)\nprint(f\"Conjunto con añadido:\\n{conjunto_numeros}\\n\")\n\nconjunto_numeros.remove(2)\nprint(f\"Conjunto eliminando el nº2:\\n{conjunto_numeros}\\n\\n\")\n\n\n\n# Diccionarios: colección desordenada (ordenada a partir de Python 3.7) y mutable de pares clave-valor.\nprint(\"::::::::::::::::::::::::::::::::::::: DICCIONARIOS :::::::::::::::::::::::::::::::::::::\")\ndiccionario_spa_eng = {\"manzana\": \"apple\", \"hola\": \"Hello\", \"silla\": \"chair\"}\nprint(f\"Diccionario original:\\n {diccionario_spa_eng}\\n\")\n\n# Añadir un elemento\ndiccionario_spa_eng[\"mundo\"] = \"word\"\nprint(f\"Diccionario con añadido:\\n{diccionario_spa_eng}\\n\")\n\n# Modificar un elemento\ndiccionario_spa_eng[\"mundo\"] = \"world\"\nprint(f\"Diccionario con corrección:\\n{diccionario_spa_eng}\\n\")\n\n# Eliminar un elemento\ndel diccionario_spa_eng[\"silla\"]\nprint(f\"Diccionario con elemento eleminado:\\n{diccionario_spa_eng}\\n\")\n\n# Ordenar diccinario\ndiccionario_ordenado = dict(sorted(diccionario_spa_eng.items()))\nprint(f\"Diccionario ordenado:\\n{diccionario_ordenado}\\n\\n\")\n\n\n\n\nprint(\"::::::::::::::::::::::::::::::::::::: EXTRA :::::::::::::::::::::::::::::::::::::\")\n\nagenda = {}\n\n\ndef buscar_contacto():\n    contacto_a_buscar = input(\"Introduce el nombre del contacto a buscar: \")\n\n    if contacto_a_buscar in agenda.keys():\n        print(f\"{contacto_a_buscar}: {agenda[contacto_a_buscar]}\\n\")\n\n    else:\n        print(\"El contacto no existe, inténtalo de nuevo.\")\n        pass\n\n\ndef anadir_contacto():\n    nombre = input(\"Introduce el nombre del contacto: \")\n    numero = int(input(\"Introduce el número de 9 cifras: \"))\n\n    while len(str(numero)) != 9 or numero in agenda.values():\n\n        if len(str(numero)) != 9:\n            numero = int(input(\"Error. Tiene que tener 9 cifras: \"))\n\n        elif numero in agenda.values():\n            numero = int(input(f\"Error. El número {numero} ya existe en la agenda: \"))\n\n    else:\n        print(f\"{nombre} se ha agregado a la agenda correctamente.\\n\")\n\n        agenda[nombre] = numero\n\n\ndef modificar_contacto():\n    contacto_a_modificar = input(\"Introduce el nombre del contacto a modificar: \")\n\n    if contacto_a_modificar not in agenda.keys():\n        print(\"El nombre no existe en la agenda, inténtalo de nuevo.\")\n        modificar_contacto()\n\n    else:\n        del agenda[contacto_a_modificar]\n\n        nombre = input(\"Introduce el nuevo nombre del contacto: \")\n        numero = int(input(\"Introduce el nuevo número de 9 cifras: \"))\n\n        while len(str(numero)) != 9 or numero in agenda.values():\n\n            if len(str(numero)) != 9:\n                numero = int(input(\"Error. Tiene que tener 9 cifras: \"))\n\n            elif numero in agenda.values():\n                numero = int(input(f\"Error. El número {numero} ya existe en la agenda: \"))\n\n        agenda[nombre] = numero\n        print(f\"{contacto_a_modificar} se ha modificado correctamente.\\n\")\n\n\ndef eliminar_contacto():\n    contacto_a_eliminar = input(\"Introduce el nombre del contacto a eliminar: \")\n\n    if contacto_a_eliminar in agenda.keys():\n\n        del agenda[contacto_a_eliminar]\n\n        print(f\"El contacto {contacto_a_eliminar} se ha eliminado correctamente.\\n\")\n\n    else:\n        print(\"El contacto no existe, inténtalo de nuevo.\")\n        pass\n\n\ndef ver_contactos():\n\n    agenda_ordenada = dict(sorted(agenda.items()))\n\n    for contacto, numero in agenda_ordenada.items():\n        print(f\"{contacto}: {numero}\")\n\n\nopcion_elegida = 0\n\nwhile opcion_elegida != 6:\n\n    # Creación del menú y bucle\n    print(\"\"\"\n\n        ### Agenda Telefónica ###\n\n        ¿Qué deseas hacer?:\n\n              [1] - Buscar\n              [2] - Añadir\n              [3] - Modificar\n              [4] - Eliminar\n              [5] - Ver todos los contactos\n              [6] - Salir\n    \"\"\")\n\n    opcion_elegida = int(input())\n\n    match opcion_elegida:\n        case 1:\n            buscar_contacto()\n        case 2:\n            anadir_contacto()\n        case 3:\n            modificar_contacto()\n        case 4:\n            eliminar_contacto()\n        case 5:\n            ver_contactos()\n        case 6:\n            opcion_elegida = 6\n\n\nprint(\"\\nGracias por utilizar la agenda. Hasta pronto!!!\")\n\n\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/mhayhem.py",
    "content": "# @author: Mhayhem\n\n# - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n# - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n\n\"\"\" list \"\"\"\n# crear una lista\n\nmy_list = [\"Dany\", \"Mhayhem\", \"Python\", \"Valladolid\"]\nmy_list_2 = list([21, 3, 99, 1, 0, 10])\n\n# acceder a un elemento dentro de la lista\n\nprint(my_list[2]) # se accede através de su índice (en programción el primero es el 0) => python\n\n# añadir un elemento al final de la lista\n\nmy_list.append(\"España\")\nprint(my_list) # ['Dany', 'Mhayhem', 'python', 'valladolid', 'España']\n\n# insertar un elemento en una posición concreta\n\nmy_list.insert(0, \"Humano\")\nprint(my_list) # ['humano', 'Dany', 'Mhayhem', 'python', 'valladolid', 'España']\n\n# actualizar un elemento\n\nmy_list[0] = \"Alien\"\nprint(my_list) # ['Alien', 'Dany', 'Mhayhem', 'python', 'valladolid', 'España']\n\n# eliminar un elemento\n\nmy_list.remove(\"España\")\nprint(my_list) # ['Dany', 'Mhayhem', 'python', 'valladolid'] \n\n# eliminar el ultimo elemento\n\nmy_list.pop() # también podrias elegir el índice a eliminar => my_list.pop(2)\nprint(my_list) # ['Dany', 'Mhayhem', 'python'] \n\n# eliminar toda la lista\n\nmy_list.clear() \nprint(my_list) # []\n\n# ordenar una lista\n\nmy_list_2.sort() \nprint(my_list_2) # [0, 1, 3, 10, 21, 99] si usamor sort(reverse=True) se ordenaría al contrario\n\n\"\"\" tuple \"\"\"\n# crear una tupla\n\nmy_tuple = (\"Dany\", 42)\nmy_tuple_2 = tuple([\"Mhayhem\", \"Python\"])\n\n# acceder a un elemento dentro de la tupla\nprint(my_tuple[0]) # Dany\n\n\"\"\" las tuplas son inmutables, por lo que no se puede ni añadir ni eliminar elementos \nni actualizarlas, para eso habría que convertirlas a listas y retornarlas a tuplas \"\"\"\n\n\"\"\" set \"\"\"\n# crear un set\nmy_set = {\"Dany\", \"Mhayhem\", \"Valladolid\"}\nmy_set_2 = set([\"Python\", \"Java\", \"C++\"])\n\n\"\"\" los set no tienen orden especifico, no se puede acceder a los elementos através de índices, tampoco se pueden duplicar elementos \"\"\"\n\n# añadir un elemento\n\nmy_set.add(\"España\") # se añade un elemento al final, no se puede elegir la posición\nprint(my_set) # se imprime sin orden \n\n# eliminar un elemento\n\nmy_set.remove(\"España\")\nprint(my_set) \nmy_set_2.discard(\"Go\") # discard() no daría error si el elemento ha borrar no existe, remove() si daría error\nprint(my_set_2)\nmy_set_2.pop() # pop() borraría un elemento al azar, ya que no estan ordenados\nprint(my_set_2)\n\n# actualizar mediante asignación no se podría, podiamos usar update() para actualizarlo con otra estructura iterable\nmy_set_2.update(my_set)\nprint(my_set_2)\n\n# elimminar todo el set\n\nmy_set_2.clear()\nprint(my_set_2) \n\n\"\"\" dict \"\"\"\n# crear un dict\nmy_dict = {\"name\": \"Dany\", \"alias\":\"Mhayhem\"}\nmy_dict_2 = dict([(\"name\", \"Dany\"),(\"alias\", \"Mhayhem\")])\nmy_dict_3 = dict(name=\"Dany\", alias=\"Mhayhem\")\n\n# acceder a un valor\n\nprint(my_dict[\"alias\"])\n\n# añadir elemento\nmy_dict[\"city\"] = \"Valladolid\"\nprint(my_dict) # {\"name\": \"Dany\", \"alias\":\"Mhayhem\", \"city\": \"Valladolid\"}\n\n# actualizar elemento\n\nmy_dict[\"city\"] = \"Madrid\"\nprint(my_dict) # {\"name\": \"Dany\", \"alias\":\"Mhayhem\", \"city\": \"madrid\"}\nmy_dict_2.update({\"city\":\"Valladolid\"})\nprint(my_dict_2) # {\"nombre\": \"Dany\", \"alias\":\"Mhayhem\", \"city\": \"Valladolid\"}\n\nmy_dict_2.pop(\"alias\")\nprint(my_dict_2) # {\"name\": \"Dany\"} \n\n# eliminar todo el dict\n\nmy_dict_3.clear()\nprint(my_dict_3) # {}\n\"\"\"\"\"\"\n\n\"\"\" hay una plabra reservada para hacer una eliminación completa, incluida la referencía en memoría, del: del my_dict\"\"\"\n# DIFICULTAD EXTRA (opcional):\n# Crea una agenda de contactos por terminal.\n# - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n# - Cada contacto debe tener un nombre y un número de teléfono.\n# - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n#   los datos necesarios para llevarla a cabo.\n# - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n#   (o el número de dígitos que quieras)\n# - También se debe proponer una operación de finalización del programa.\n\n\"\"\" Extra \"\"\"\n\n# comprobar que la longitud del número sea 11 y que sean solo dígitos\ndef checking_phone_num():\n    while True:\n        try:\n            num = int(input(\"Número de telélefono: \\n\"))\n            lenError = len(str(num)) != 11\n        except ValueError:\n            print(\"Solo admite números\")\n        if not lenError:\n            break\n        else:\n            print(\"La longitud del número debe ser de 11 dígitos\")\n    return num\n            \n# guardar nombre delccontacto\ndef contact_name():\n    return input(\"Nombre del contacto: \\n\").capitalize()\n        \n\n# crear contacto e insertarlo a la agenda\ndef create_contact(book_contact):\n    name = contact_name()\n    phone_num = checking_phone_num()\n    book_contact.update({name: phone_num})\n    print(\"contacto creado\") \n    return book_contact\n    \n # actualizar contacto   \ndef update_contact(book_contact):\n    name = contact_name()\n    if name not in book_contact.keys():\n        print(\"El contacto no existe\")\n    else:    \n        phone_num = checking_phone_num()\n        book_contact[name] = phone_num\n        print(f\"Contacto actualizado: {name}: {book_contact[name]}\")\n    return book_contact\n\n# buscar contacto\ndef serching_contact(book_contact):\n    name = contact_name()\n    if name in book_contact.keys():\n        print(f\"{name}: {book_contact[name]}\")\n    else:\n        print(\"El contacto no existe\")\n         \n# borrar contacto\ndef delete_contact(book_contact):\n    name = contact_name()\n    if name not in book_contact.keys():\n        print(\"El contacto no exisate\")\n    else:\n        book_contact.pop(name)\n        print(f\"Contacto {name} ha sido elíminado\")\n    return book_contact\n\ndef contact_phone():\n    book_contact= {}\n    if not book_contact:\n        print(\"La agenda esta vacía, cree un nuevo contacto\")\n        create_contact(book_contact)\n    while True:\n        option = input(\"Que operación quiere realizar: [C]rear, [A]ctualizar, [B]uscar, [E]liminar, [S]alir\\n\").lower()\n        match option : # es el switch de JS\n            case \"s\":\n                print(\"Cerrando prógrama\")\n                break\n            case \"c\":\n                create_contact(book_contact)\n            case \"a\":\n                update_contact(book_contact)\n            case \"b\":\n                serching_contact(book_contact)\n            case \"e\":\n                delete_contact(book_contact)\n            case _: # seria como un else\n                print(\"Opción no válida\")\n            \n    \n    print(book_contact)\n\n        \ncontact_phone()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/miguelex.py",
    "content": "# Listas\nprint(\"Vamos a crer una lista\")\nmiLista = [1,8,4,2,5,6]\n\n# Imprimir lista\nprint(f\"La lista es: {miLista}\")\n\n# Añadir elemento a la lista\nmiLista.append(3)\nprint(f\"La lista queda asi tras insertar el 3: {miLista}\")\n\n# Añadir elemento en una posicion concreta\nmiLista.insert(2, 10)\nprint(f\"La lista queda asi tras insertar el 10 en la posicion 2: {miLista}\")\n\n# Eliminar un elemento de la lista\nmiLista.remove(2)\nprint(f\"La lista tras eliminar el 2 es: {miLista}\")\n\n# Buscar un elemento en una posicion de la lista \nprint(f\"La elemento den la posicion 5 de la lista es: {miLista.index(5)}\")\n\n# Ordenar una lista\nmiLista.sort()\nprint(f\"La lista ordenada es: {miLista}\") \n\n# Invertir una lista\nmiLista.reverse()\nprint(f\"La lista ordenada de forma inversa es: {miLista}\")\n\n# Comprobar si un elemento esta en la lista\nprint(f\"¿Esta el numero 10 en la lista?: {10 in miLista}\")\n\nprint(\"\\n\")\n\n# Tuplas\nprint(\"Vamos a crear una tupla\")\nmiTupla = (1,2,6,7,4,2,8)\n\nprint(f\"El contenido de mi tupla es {miTupla}\")\n\n# añadir elemento a una tupla\nmiTupla += (5,)\nprint(f\"El contenido de mi tupla tras añadir el 5 es: {miTupla}\")\n\n# convertir una tupla en una lista\nmiLista = list(miTupla)\nprint(f\"El contenido de mi lista es: {miLista}\")\n\n# Convertir una lista en una tupla\nmiTupla = tuple(miLista)\nprint(f\"El contenido de mi tupla es: {miTupla}\")\n# No se pueden añadir o eliminar elementos en una tupla\n\n#ordenar tupla\nmiTupla = sorted(miTupla)\nprint(f\"El contenido de mi tupla ordenada es: {miTupla}\")\n\n# Buscar un elemento en una tupla\nprint(f\"El elemento 8 esta en la posicion {miTupla.index(8)}\")\n\n#Juntar dos tuplas\nmiTupla2 = (10,11,12)\nmiTupla += miTupla2\nprint(f\"El contenido de mi tupla tras juntarla con otra es: {miTupla}\")\n\nprint(\"\\n\")\n\n# Conjuntos\nprint(\"Vamos a crear un conjunto\")\n\n# Crear un conjunto\nmiConjunto = set()\nprint(f\"El contenido de mi conjunto es: {miConjunto}\")\n# Añadir elementos al conjunto\nmiConjunto.add(1)\nmiConjunto.add(2)\nmiConjunto.add(3)\n\nprint(f\"El contenido de mi conjunto es: {miConjunto}\")\n# Eliminar un elemento del conjunto\nmiConjunto.discard(1)\nprint(f\"El contenido de mi conjunto es: {miConjunto}\")\n\n# Comprobar si un elemento esta en el conjunto\nprint(f\"¿Esta el numero 2 en el conjunto?: {2 in miConjunto}\")\n\n# Juntar conjuntos\nmiConjunto2 = {3,4,5}\nmiConjunto = miConjunto.union(miConjunto2)\nprint(f\"El contenido de mi conjunto tras juntarlo con otro es: {miConjunto}\")\n\n# Diferencia entre conjuntos\nmiConjunto = {1,2,3,4,5}\nmiConjunto2 = {3,4,5,6,7}\nmiConjunto = miConjunto.difference(miConjunto2)\nprint(f\"El contenido de mi conjunto tras hacer la diferencia con otro es: {miConjunto}\")\n\n# Interseccion entre conjuntos\nmiConjunto = {1,2,3,4,5}\nmiConjunto2 = {3,4,5,6,7}\nmiConjunto = miConjunto.intersection(miConjunto2)\nprint(f\"El contenido de mi conjunto tras hacer la interseccion con otro es: {miConjunto}\")\n\nprint(\"\\n\")\n\n# Diccionarios\nprint(\"Vamos a crear un diccionario\")\n\n# Crear un diccionario\nmiDiccionario = {\"Alemania\":\"Berlin\", \"Francia\":\"Paris\", \"España\":\"Madrid\", \"Italia\":\"Roma\"}\nprint(f\"El contenido de mi diccionario es: {miDiccionario}\")\n\n# Añadir un elemento al diccionario\nmiDiccionario[\"Portugal\"] = \"Lisboa\"\nprint(f\"El contenido de mi diccionario es: {miDiccionario}\")\n\n# Eliminar un elemento del diccionario\ndel miDiccionario[\"Portugal\"]\nprint(f\"El contenido de mi diccionario es: {miDiccionario}\")\n\n# Extra\n\nagenda = {}\n\ndef showMenu():\n    print(\"\\nAgenda de Contactos\")\n    print(\"1. Buscar contacto\")\n    print(\"2. Insertar contacto\")\n    print(\"3. Actualizar contacto\")\n    print(\"4. Eliminar contacto\")\n    print(\"5. Mostrar todos los contactos\")\n    print(\"6. Salir\")\n\ndef searchContact():\n    nombre = input(\"Ingrese el nombre del contacto a buscar: \")\n    if nombre in agenda:\n        print(f\"Nombre: {nombre}, Teléfono: {agenda[nombre]}\")\n    else:\n        print(f\"El contacto {nombre} no existe en la agenda.\")\n\ndef addContact():\n    nombre = input(\"Ingrese el nombre del contacto: \")\n    telefono = input(\"Ingrese el número de teléfono: \")\n\n    # Validar que el número de teléfono sea numérico y tenga la longitud deseada\n    if telefono.isdigit() and len(telefono) <= 11:\n        agenda[nombre] = telefono\n        print(f\"Contacto {nombre} insertado correctamente.\")\n    else:\n        print(\"Número de teléfono no válido.\")\n\ndef updateContact():\n    nombre = input(\"Ingrese el nombre del contacto a actualizar: \")\n    if nombre in agenda:\n        nuevo_telefono = input(\"Ingrese el nuevo número de teléfono: \")\n\n        # Validar que el número de teléfono sea numérico y tenga la longitud deseada\n        if nuevo_telefono.isdigit() and len(nuevo_telefono) <= 11:\n            agenda[nombre] = nuevo_telefono\n            print(f\"Contacto {nombre} actualizado correctamente.\")\n        else:\n            print(\"Número de teléfono no válido.\")\n    else:\n        print(f\"El contacto {nombre} no existe en la agenda.\")\n\ndef removeContact():\n    nombre = input(\"Ingrese el nombre del contacto a eliminar: \")\n    if nombre in agenda:\n        del agenda[nombre]\n        print(f\"Contacto {nombre} eliminado correctamente.\")\n    else:\n        print(f\"El contacto {nombre} no existe en la agenda.\")\n\ndef listContact():\n    if agenda:\n        print(\"\\nLista de contactos:\")\n        for nombre, telefono in agenda.items():\n            print(f\"Nombre: {nombre}, Teléfono: {telefono}\")\n    else:\n        print(\"La agenda está vacía.\")\n\n# Menú principal\nwhile True:\n    showMenu()\n    opcion = input(\"Seleccione una opción (1-6): \")\n\n    if opcion == \"1\":\n        searchContact()\n    elif opcion == \"2\":\n        addContact()\n    elif opcion == \"3\":\n        updateContact()\n    elif opcion == \"4\":\n        removeContact()\n    elif opcion == \"5\":\n        listContact()\n    elif opcion == \"6\":\n        print(\"¡Hasta luego!\")\n        break\n    else:\n        print(\"Opción no válida. Por favor, seleccione una opción del 1 al 6.\")"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/mikelm2020.py",
    "content": "# Estructuras de datos\n# Diccionarios\n\n\ndef dictionary_structure():\n    cubes = {x: x**3 for x in range(1, 11)}\n    print(f\"El diccionario de cubos es: {cubes}\")\n\n    # Inserción\n    cubes[11] = 11**3\n    print(\"Se inserta la llave 11 para obtener su cubo:\")\n    print(cubes)\n\n    # Borrado\n    # Elimina con pop la clave 5\n    cubes.pop(5)\n    print(\"Elimina con el método pop la clave 5 del diccionario cubes\")\n    print(cubes)\n\n    # Elimina con popitem el último par clave: valor\n    cubes.popitem()\n    print(\n        \"Elimina con el método popitem el último par clave: valor del diccionario cubes\"\n    )\n    print(cubes)\n\n    # Elimina con del par clave:valor de clave 7\n    del cubes[7]\n    print(\n        \"Elimina con el método del el par clave: valor del diccionario cubes con clave 7\"\n    )\n    print(cubes)\n\n    # Modificación\n    # Asignar el valor 50 a la clave 3\n    cubes[3] = 50\n    print(\"Asignar el valor 50 a la clave 3\")\n    print(cubes)\n\n    # Ordenación\n    # Orden ascendente\n    print(\"Orden ascendente\")\n    print(dict(sorted(cubes.items())))\n\n    # Orden descendente\n    print(\"Orden descendente\")\n    print(dict(sorted(cubes.items(), reverse=True)))\n\n    # Elimina todos los elementos del diccionario\n    cubes.clear()\n    print(\"Elimina todos los elementos del diccionario\")\n    print(cubes)\n\n\n# Listas\ndef list_structure():\n    squares = [x**2 for x in range(1, 11)]\n    print(f\"La lista de cuadrados es: {squares}\")\n\n    # Inserción\n    # Inserta el cuadrado de 11 con append\n    squares.append(11**2)\n    print(\"Inserta el cuadrado de 11 con el método append\")\n    print(squares)\n\n    # Inserta el cuadrado de 12 despues del indice 3\n    squares.insert(3, 12**2)\n    print(\"Inserta el cuadrado de 12 despues del indice 3\")\n    print(squares)\n\n    # Borrado\n    # Quita el item de la lista con valor 81\n    squares.remove(81)\n    print(\"Quita el item de la lista con valor 81\")\n    print(squares)\n\n    # Quita el item de la posición 2 de la lista\n    squares.pop(2)\n    print(\"Quita el item de la posición 2 de la lista\")\n    print(squares)\n\n    # Quita el último item de la lista\n    squares.pop()\n    print(\"Quita el último item de la lista\")\n    print(squares)\n\n    # Actualización\n    # Actualiza con el valor 30 el item de la posición 4 de la lista\n    squares[4] = 30\n    print(\"Actualiza con el valor 30 el item de la posición 4 de la lista\")\n    print(squares)\n\n    # Ordenación\n    # Odenación ascendente\n    squares.sort()\n    print(\"Odenación ascendente\")\n    print(squares)\n\n    # Odenación descendente\n    print(\"Odenación descendente\")\n    print(sorted(squares, reverse=True))\n\n    # Eliminación total de los items de la lista\n    squares.clear()\n    print(\"Eliminación total de los items de la lista\")\n    print(squares)\n\n\ndef set_structure():\n    # Conjuntos sets\n    letters = set([\"a\", \"b\", \"c\", \"d\", \"e\"])\n    print(f\"El conjunto letters es: {letters}\")\n\n    # Inserción\n    # Inserta la letra f al Conjunto con add\n    letters.add(\"f\")\n    print(\"Inserta la letra f al Conjunto con el método add\")\n    print(letters)\n\n    # Inserta las letras que no se repiten en el conjunto, de la lista siguiente:\n    # ['c', 'd', 'e', 'f', 'g', 'h', 'i']\n    other_list = [\"c\", \"d\", \"e\", \"f\", \"g\", \"h\", \"i\"]\n    letters.update(other_list)\n    print(\"Inserta las letras que no se repiten en el conjunto, de la lista siguiente:\")\n    print(other_list)\n    print(letters)\n\n    # Borrado\n    # Borra la letra h con remove\n    letters.remove(\"h\")\n    print(\"Borra la letra h con el método remove\")\n    print(letters)\n\n    # Borra la letra e con discard\n    letters.discard(\"e\")\n    print(\"Borra la letra e con discard\")\n    print(letters)\n\n    # Borra una letra aleatoriamente\n    letters.pop()\n    print(\"Borra una letra aleatoriamente\")\n    print(letters)\n\n    # Ordenación\n    # Orden ascendente\n    print(\"Orden ascendente\")\n    print(set(sorted(letters)))\n\n    # Orden descendente\n    print(\"Orden descendente\")\n    print(set(sorted(letters, reverse=True)))\n\n    # Borrado total de elementos\n    letters.clear()\n    print(\"Borrado total de elementos\")\n    print(letters)\n\n    # Tuplas\n\n\ndef tuple_structure():\n    numbers_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n    numbers_tuple = tuple(numbers_list)\n    print(\"Las listas son estructuras de datos mutables\")\n    print(numbers_list)\n    print(\n        \"Las tuplas son estructuras de datos inmutables por lo tanto no se pueden modificar una vez creadas\"\n    )\n    print(numbers_tuple)\n\n    # Ordenación\n    # Orden ascendente\n    print(\"Orden ascendente\")\n    print(tuple(sorted(numbers_tuple)))\n\n    # Orden descendente\n    print(\"Orden descendente\")\n    print(tuple(sorted(numbers_tuple, reverse=True)))\n\n\ndef add_contact(name):\n    phone = input(\"Registra el teléfono del contacto: \")\n    if validate_phone(phone):\n        diary_object[name] = phone\n    else:\n        print(\"El teléfono es inválido\")\n\n    print(diary_object)\n\n\ndef find_contact(name):\n    if name in diary_object:\n        print(f\"Nombre: {name} Teléfono: {diary_object[name]} \")\n    else:\n        print(\"Contacto inexistente\")\n\n\ndef update_contact(name):\n    if name in diary_object:\n        phone = input(\"Registra el nuevo teléfono del contacto: \")\n        if validate_phone(phone):\n            diary_object[name] = phone\n        else:\n            print(\"El teléfono es inválido\")\n    else:\n        print(\"Contacto inexistente\")\n\n    print(diary_object)\n\n\ndef delete_contact(name):\n    if name in diary_object:\n        del diary_object[name]\n        print(\"Contacto eliminado correctamente\")\n    else:\n        print(\"Contacto inexistente\")\n\n    print(diary_object)\n\n\ndef validate_name(name):\n    return name.isalpha() and len(name) >= 3\n\n\ndef validate_phone(phone):\n    return phone.isdigit() and len(phone) == 10\n\n\ndiary_object = {}\n\n\ndef diary():\n    while True:\n        print(\n            \"\"\"\n    A G E N D A   D E   C O N T A C T O S\n            Selecciona una opción:\n            1. - Agregar un contacto\n            2. - Buscar un contacto\n            3. - Actualizar un contacto\n            4. - Eliminar un contacto\n            5. - Salir de la Agenda\n            \"\"\"\n        )\n        response = input(\"Opción deseada: \")\n        match response:\n            case \"1\":\n                name = input(\"Introduce el nombre del contacto \")\n                if validate_name(name):\n                    add_contact(name.capitalize())\n                else:\n                    print(\"Nombre invalido del contacto\")\n            case \"2\":\n                name = input(\"Introduce el nombre del contacto a buscar \")\n                if validate_name(name):\n                    find_contact(name.capitalize())\n                else:\n                    print(\"Nombre invalido del contacto\")\n            case \"3\":\n                name = input(\"Introduce el nombre del contacto a actualizar \")\n                if validate_name(name):\n                    update_contact(name.capitalize())\n                else:\n                    print(\"Nombre invalido del contacto\")\n            case \"4\":\n                name = input(\"Introduce el nombre del contacto a eliminar \")\n                if validate_name(name):\n                    delete_contact(name)\n                else:\n                    print(\"Nombre invalido del contacto\")\n            case \"5\":\n                break\n            case _:\n                print(\"Opción inválida: Debe ser del 1 al 5\")\n\n\nif __name__ == \"__main__\":\n    dictionary_structure()\n    list_structure()\n    set_structure()\n    tuple_structure()\n    diary()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/monicavaquerano.py",
    "content": "# 03 ESTRUCTURAS DE DATOS\n# Mónica Vaquerano\n# https://monicavaquerano.dev\nimport os, time\n\nos.system(\"clear\")\n\"\"\"\nEJERCICIO:\n- Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n\"\"\"\nprint(\"\\nEstructuras de datos (Data Structures):\\n\")\n# Lists\nlista = [1, 2, 3, 4, 5]\nprint(f\"- List: esta es una lista: {lista}\")\n# Tuples\ntupla = (1, 2, \"hola\")\nprint(f\"- Tuple: este un tuple: {tupla}\")\n# Sets o conjuntos\nconjunto = {\"apple\", \"orange\", \"apple\", \"pear\", \"orange\", \"banana\"}\nprint(\n    f'- Set: este es un ejemplo de set(\"apple\", \"orange\", \"apple\", \"pear\", \"orange\", \"banana\") = {conjunto}'\n)\n# Dictionaries\ndiccionario = {\"monica\": 123, \"tanya\": 456}\nprint(f\"- Dictionary: este es un ejemplo de dictionary -> {diccionario}\")\n\n\n\"\"\"\n- Utiliza operaciones de inserción, borrado, actualización y ordenación.\n\"\"\"\n\nprint(\"\\nOperaciones de inserción, borrado, actualización y ordenación:\")\n\n\n# Lists o listas\nprint(\"\\n- En lists o listas:\")\n\n# list.append(x)\nprint(\n    f\"\\nlist.append(x):\\npara agregar une elemento a una lista usamos lista.append(x): {lista}\",\n    end=\" \",\n)\nlista.append(6)\nprint(f\"-> lista.append(6) = {lista}\")\n# list.extend(iterable)\nprint(\n    f\"\\nlist.extend(iterable):\\npara extender con más elementos usamos list.extend(iterable): {lista}\",\n    end=\" \",\n)\nlista.extend([7, 8, 9])\nprint(f\"-> lista.extend([7, 8, 9]) = {lista}\")\n# list.insert(i, x)\nprint(\n    f\"\\nlist.insert(i, x):\\npara insertar un elemento usamos list.insert(i, x): {lista}\",\n    end=\" \",\n)\nlista.insert(0, 5)\nprint(f\"-> lista.insert(0, 5) = {lista}\")\n# list.remove(x)\nprint(\n    f\"\\nlist.remove(x):\\npara remover el primer elemento que coincida con x usamos list.remove(x): {lista}\",\n    end=\" \",\n)\nlista.remove(5)\nprint(f\"-> lista.remove(5) = {lista}\")\n# list.pop([i])\nprint(\n    f\"\\nlist.pop([i]):\\npara remover un elemento según su posición en la lista usamos list.pop([i]): {lista}\",\n    end=\" \",\n)\nlista.pop(0)\nprint(f\"-> lista.pop(0) = {lista}\")\n# list.clear()\nprint(\n    f\"\\nlist.clear():\\npara remover todos los elementos en la lista usamos list.clear(): {lista}\",\n    end=\" \",\n)\nlista.clear()\nprint(f\"-> lista.clear() = {lista}\")\n\nfruits = [\"orange\", \"apple\", \"pear\", \"banana\", \"kiwi\", \"apple\", \"banana\"]\n\n# list.index(x[, start[, end]])\nprint(\n    f\"\\nlist.index(x[, start[, end]]):\\npara buscar el índice de un elemento, desde una posición hasta otra o el final en la lista usamos list.index(x[, start[, end]]):\\n{fruits}\",\n    end=\" \",\n)\nprint(f\"-> fruits.index('banana', 4) = {fruits.index('banana', 4)}\")\n\n# list.count(x)\nprint(\n    f\"\\nlist.count(x):\\npara saber el número de veces que x aparece en la lista usamos list.count(x): {fruits}\",\n    end=\" \",\n)\nprint(f\"-> fruits.count('apple') = {fruits.count('apple')}\")\n# list.sort(*, key=None, reverse=False)\nprint(\n    f\"\\nlist.sort(*, key=None, reverse=False):\\nordenar la lista usamos list.sort(*, key=None, reverse=False): {fruits}\",\n    end=\" \",\n)\nfruits.sort()\nprint(f\"-> fruits.sort() = {fruits}\")\n# list.reverse()\nprint(\n    f\"\\nlist.reverse():\\npara revertir la lista usamos list.reverse(): {fruits}\",\n    end=\" \",\n)\nfruits.reverse()\nprint(f\"-> fruits.reverse() = {fruits}\")\n# list.copy()\nprint(\n    f\"\\nlist.copy():\\npara hacer una copia superficial de la lista usamos list.copia():\\nfruits = {fruits}\",\n    end=\" \",\n)\ncopia = fruits.copy()\nprint(f\"-> copia = fruits.copy() -> copia = {copia}\")\n\n\n# Tuples o tuplas\nprint(\"\\n- En tuples o tuplas:\")\nprint(\n    \"Una tupla no admite cambios y por lo tanto, es inmutable. Solo puede ser cambiada si se convierte a lista y devuelta a tuple.\"\n)\nx = (\"apple\", \"banana\", \"cherry\")\ny = list(x)\ny[1] = \"kiwi\"\nx = tuple(y)\nprint(\n    f\"x = ('apple', 'banana', 'cherry')\\ny = list(x)\\ny[1] = 'kiwi'\\nx = tuple(y)\\nx = {x}\"\n)\n\n\n# Sets o conjuntos\nprint(\"\\n- En sets o conjuntos:\")\nprint(\n    \"Los items de un Set son inmutables, pero se pueden remover items y agregar nuevos.\"\n)\n\n#  Add\nperiodic_table = set()\nmetals = (\"Fe\", \"Mg\", \"Au\", \"Au\", \"Zn\")\nperiodic_table.add(metals)\nnon_metals = (\"C\", \"H\", \"O\", \"F\", \"Cl\")\nperiodic_table.add(non_metals)\nprint(\n    f\"\\nset.add(x): agrega un item a un set.\\nperiodic_table = set()\\nmetals = ('Fe', 'Mg', 'Au', 'Au', 'Zn')\\nperiodic_table.add(metals)\\nnon_metals = ('C', 'H', 'O', 'F', 'Cl')\\nperiodic_table.add(non_metals)\"\n)\nprint(f\"periodic_table = {periodic_table}\")\n\n# Update\nmylist = [\"kiwi\", \"orange\"]\nperiodic_table.update(mylist)\nprint(\n    f\"\\nset.update(iterable): agrega cualquier iterable a un set.\\nmylist = ['kiwi', 'orange']\\nperiodic_table.update(mylist)\"\n)\nprint(f\"periodic_table = {periodic_table}\")\n\n# Remove o discard\nthisset = {\"apple\", \"banana\", \"cherry\", \"mango\"}\nthisset.remove(\"banana\")\nprint(\n    f\"\\nset.remove(x) o discard(x): remueve cualquier item de un set.\\nthisset = set('apple', 'banana', 'cherry', 'mango')\\nthisset.remove('banana')\"\n)\nprint(f\"thisset = {thisset}\")\n\n# Pop\nx = thisset.pop()\nprint(\n    f\"\\nset.pop(): este método remueve un item al azar.\\nthisset.pop() = {x}\\nthisset = {thisset}\"\n)\n\n# Clear\nthisset.clear()\nprint(f\"\\nset.clear(): este método vacía el set.\\nthisset.clear()\\nthisset = {thisset}\")\n\n# Del\ndel thisset\ntry:\n    print(thisset)\nexcept NameError:\n    print(\n        \"\\ndel set: este método elimina por completo el set.\\ndel thisset\\nprint(thisset) -> genera un error ya que 'thisset' ya no existe\"\n    )\n\n\n# Dictionaries o diccionarios\nprint(\"\\n- En dictionaries o diccionarios:\")\n\n# Update\nthisdict = {\"brand\": \"Ford\", \"model\": \"Mustang\", \"year\": 1964}\nprint(\n    f\"\\ndict.update(k, v): se puede cambiar un valor específico solo refiriéndose a su key o usando update(key, valor).\\nthisdict = {thisdict}\\nthisdict['year'] = 2018\"\n)\nthisdict[\"year\"] = 2018\nprint(f\"thisdict = {thisdict}\")\nthisdict.update({\"year\": 2020})\nprint(\"thisdict.update({'year'': 2020})\")\nprint(f\"thisdict = {thisdict}\")\n\n# Add\nprint(\n    f\"\\ndict.add(k, v): se puede agregar un item usando un nuevo valor de key y asignándole un valor o usando update(key, valor) de igual forma.\\nthisdict['color'] = 'red' o \",\n    end=\"\",\n)\nprint(\"thisdict.update({'color': 'red'})\")\nthisdict.update({\"color\": \"red\"})\nprint(f\"thisdict = {thisdict}\")\n\n# Remove\n# Pop\nprint(\n    f\"\\ndict.pop(k): remueve el item con esa key específica.\\nthisdict = {thisdict}\\nthisdict.pop('model')\",\n)\nthisdict.pop(\"model\")\nprint(f\"thisdict = {thisdict}\")\n\n# Popitem\nprint(\n    f\"\\ndict.popitem(): remueve el item con úlitma key agregada.\\nthisdict = {thisdict}\\nthisdict.popitem()\",\n)\nthisdict.popitem()\nprint(f\"thisdict = {thisdict}\")\n\n# del dict[k]\nprint(\n    f\"\\ndel dict[k]: remueve el item con esa key específica.\\nthisdict = {thisdict}\\ndel thisdict('year')\",\n)\ndel thisdict[\"year\"]\nprint(f\"thisdict = {thisdict}\")\n\n# del dict\ndel thisdict\ntry:\n    print(thisdict)\nexcept NameError:\n    print(\n        \"\\ndel dict: este método elimina por completo el diccionario.\\ndel thisdict\\nprint(thisdict) -> genera un error ya que 'thisdict' ya no existe\"\n    )\n\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\nCrea una agenda de contactos por terminal.\n- Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n- Cada contacto debe tener un nombre y un número de teléfono.\n- El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación los datos necesarios para llevarla a cabo.\n- El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos (o el número de dígitos que quieras)\n- También se debe proponer una operación de finalización del programa.\n\"\"\"\n\n\ncontacts = {\n    \"monica\": {\"phone\": 1234567890, \"address\": \"avenida 123\"},\n    \"ana\": {\"phone\": 1234567890, \"address\": \"calle 123\"},\n}\n\n\ndef showContacts():\n    os.system(\"clear\")\n    print(f\"{'========================= Contact List =========================':^60}\")\n    if len(contacts) == 0:\n        print(\"\\nContact list is empty.\")\n    else:\n        title = f\"|{'Name':^20}|{'Phone':^20}|{'Address':^20}|\"\n        print(title)\n        for key, value in contacts.items():\n            print(f\"| {key.capitalize():<19}\", end=\"|\")\n            for subvalue in value.values():\n                print(f\" {str(subvalue).capitalize():<19}\", end=\"|\")\n            print()\n        print(\n            f\"{'================================================================':^60}\"\n        )\n\n\ndef searchContact():\n    os.system(\"clear\")\n    print(\"=== Search ===\")\n    nameInput = input(\"Input contact's name: > \").strip().lower()\n    if nameInput in contacts.keys():\n        print(\"\\n--- Contact Info ---\")\n        print(\n            f\"Name: {nameInput.capitalize()}\\nPhone: {contacts[nameInput]['phone']}\\nAddress: {contacts[nameInput]['address'].capitalize()}\"\n        )\n    else:\n        print(\"\\nContact not found.\")\n\n\ndef addContact():\n    os.system(\"clear\")\n    print(\"=== Add ===\")\n    name = input(\"Input contact's name: > \").strip().lower()\n    while True:\n        try:\n            phone = int(input(\"Input contact's phone: > \"))\n            break\n        except ValueError:\n            print(\"Phone must be a number.\")\n    address = input(\"Input contact's address: > \").strip().lower()\n    if name not in contacts.keys():\n        if len(str(phone)) <= 11:\n            contacts[name] = {\"phone\": phone, \"address\": address}\n            print(\"\\nContact has been successfuly added.\")\n        else:\n            print(\"\\nPhone number can't have more than 11 digits.\")\n    else:\n        print(\"\\nContact already exists.\")\n\n\ndef updateContact():\n    os.system(\"clear\")\n    print(\"=== Update ===\")\n    name = input(\"Input contact's name: > \").strip().lower()\n    if name in contacts.keys():\n        print(f\"\\n--- {name.capitalize()}'s new info ---\")\n        while True:\n            try:\n                newPhone = int(input(\"Update phone: > \"))\n                break\n            except ValueError:\n                print(\"Phone must be a number.\")\n        newAddress = input(\"Update address: > \").strip().lower()\n        if len(str(newPhone)) <= 11:\n            contacts[name] = {\"phone\": newPhone, \"address\": newAddress}\n            print(\"\\nContact successfully updated.\")\n        else:\n            print(\"\\nPhone number can't have more than 11 digits.\")\n    else:\n        print(\"\\nContact not found.\")\n\n\ndef deleteContact():\n    os.system(\"clear\")\n    print(\"=== Delete ===\")\n    if len(contacts) == 0:\n        print(\"\\nContact list is empty.\")\n    else:\n        name = input(\"Input contact's name: > \").strip().lower()\n        if name in contacts.keys():\n            sureInput = (\n                input(\n                    f\"\\nAre you sure you want to delete {name.capitalize()}'s contact info? y/n? > \"\n                )\n                .strip()\n                .lower()\n            )\n            if sureInput[0] == \"y\":\n                del contacts[name]\n                print(f\"\\n{name.capitalize()}'s contact info was successfully deleted.\")\n            else:\n                print(f\"\\n{name.capitalize()}'s contact info was not deleted.\")\n        else:\n            print(\"\\nContact not found.\")\n\n\ngoInput = input(\"\\nIr a DIFICULTAD EXTRA (opcional): y/n? > \").strip().lower()\nif goInput[0] == \"y\":\n    while True:\n        os.system(\"clear\")\n        print(\"\\nDIFICULTAD EXTRA (opcional):\\n\")\n        print(\"=== Contact List ===\")\n        menuInput = (\n            input(\"1: View all\\n2: Search\\n3: Add\\n4: Update\\n5: Delete\\n6: Exit\\n> \")\n            .strip()\n            .lower()\n        )\n        if menuInput == \"1\" or menuInput[0] == \"v\":\n            while True:\n                showContacts()\n                againInput = input(\"\\nGo back to main menu? y/n? : > \").strip().lower()\n                if againInput == \"\":\n                    continue\n                elif againInput[0] == \"y\":\n                    break\n                else:\n                    continue\n        elif menuInput == \"2\" or menuInput[0] == \"s\":\n            while True:\n                searchContact()\n                againInput = input(\"\\nSearch other contact? y/n? : > \").strip().lower()\n                if againInput == \"\":\n                    continue\n                elif againInput[0] == \"y\":\n                    continue\n                else:\n                    break\n        elif menuInput == \"3\" or menuInput[0] == \"a\":\n            addContact()\n            time.sleep(2)\n        elif menuInput == \"4\" or menuInput[0] == \"u\":\n            updateContact()\n            time.sleep(2)\n        elif menuInput == \"5\" or menuInput[0] == \"d\":\n            deleteContact()\n            time.sleep(2)\n        elif menuInput == \"6\" or menuInput[0] == \"e\":\n            break\n        else:\n            continue\nelse:\n    pass\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/mordevspt.py",
    "content": "\"\"\"\n- Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n\"\"\"\n# Listas - Se pueden modificar\nprint(\"Listas \\n\")\nlistaMeses = [\"Enero\",\"Febrero\",\"Marzo\",\"Abril\",\"Mayo\",\"Junio\",\"Julio\",\"Agosto\",\"Septiembre\",\"Octubre\",\"Noviembre\",\"Diciembre\"]\nprint(listaMeses)\nprint(type(listaMeses))\n# Nota: Si hacemos un return desde una función, los valores han de ir entre corchetes\n\n# Tuplas - No se pueden modificar\nprint(\"Tuplas \\n\")\ntuplaDiasSemana = (\"Lunes\",\"Martes\",\"Miercoles\",\"Jueves\",\"Viernes\",\"Sabado\",\"Domingo\")\nprint(tuplaDiasSemana)\nprint(type(tuplaDiasSemana))\n# Nota: Si hacemos un return desde una función, los valores han de ir entre comas, sin paréntesis\n\n# Diccionario - Clave valor\nprint(\"Diccionario \\n\")\ndicMesesDias = {\n    \"Enero\":31,\n    \"Febrero\":28,\n    \"Marzo\":31,\n    \"Abril\":30,\n    \"Mayo\":31,\n    \"Junio\":30,\n    \"Julio\":31,\n    \"Agosto\":31,\n    \"Septiembre\":30,\n    \"Octubre\":31,\n    \"Noviembre\":30,\n    \"Diciembre\":31\n}\nfor clave,valor in dicMesesDias.items():\n    print(f\"El mes {clave} tiene {valor} dias\")\nprint(type(dicMesesDias))\n\n# Conjuntos - No ordeandos y sin valores duplicados\nprint(\"Conjunto \\n\")\nconjuntoFruta = set()\nconjuntoFruta = {\"Manzana\",\"Platano\",\"Naranja\",\"Pera\",\"Platano\",\"Mandarina\"}\n# No se imprime en el orden en el que se introdujeron los datos y los datos repetidos solo muestra uno\nprint(conjuntoFruta)\nprint(type(conjuntoFruta))\n\n\"\"\"\n- Utiliza operaciones de inserción, borrado, actualización y ordenación.\n\"\"\"\n\n# Usaremos los ejemplos estructuras usados en la primera parte del ejercicio\n\n# Operaciones de inserción\nprint(\"\\n Operaciones de inserción \\n\")\n# Listas\nlistaMeses.append(\"Decimotercermes\")  # Se agrega al final de la lista\nlistaMeses.insert(5,\"sextomes\") # Se agrega en la posición que indiquemos de la lista (Empieza en 0)\nprint(f\"{listaMeses} \\n\")\n# Diccionario\ndicMesesDias[\"Decimotercermes\"] = 45\nfor clave,valor in dicMesesDias.items():\n    print(f\"El mes {clave} tiene {valor} dias\")\n# Conjunto\nconjuntoFruta.add(\"Pomelo\")\nprint(conjuntoFruta)\n\n# Operaciones de borrado\nprint(\"\\n Operaciones de borrado \\n\")\n# Listas\nlistaMeses.remove(\"Decimotercermes\")\nlistaMeses.pop(5)\nprint(f\"{listaMeses} \\n\")\nlistaABorrar = [1,2,3,4,5]\nlistaABorrar.clear() # Limpia la lista y la deja vacía\nprint(f\"{listaABorrar} \\n\")\n# Diccionario\ndicMesesDias.pop(\"Decimotercermes\")\nfor clave,valor in dicMesesDias.items():\n    print(f\"El mes {clave} tiene {valor} dias\")\n# Conjuntos\nconjuntoFruta.discard(\"Pomelo\")\nprint(conjuntoFruta)\nconjuntoFruta.remove(\"Pera\")\nprint(conjuntoFruta)\n\n# Operaciones de actualización\nprint(\"\\n Operaciones de actualización \\n\")\n# Listas\nlistaMeses[5] = \"julio\"\nprint(f\"{listaMeses} \\n\")\n# Diccionario\ndicMesesDias.update({\"Diciembre\":45})\nfor clave,valor in dicMesesDias.items():\n    print(f\"El mes {clave} tiene {valor} dias\")\n# Conjuntos\nconjuntoFruta2 = {\"Melon\",\"Sandia\"}\nconjuntoFruta.update(conjuntoFruta2)\nprint(conjuntoFruta)\n\n# Operaciones de ordenación\nprint(\"\\n Operaciones de ordenacion \\n\")\n# Listas\n# No modifica la lista original y ordena sin diferenciar mayúsculas y minúsculas, aparte de se más eficiente\nsorted(listaMeses)\nprint(f\"{listaMeses} \\n\")\n# Modifica la lista original y ordena diferenciando mayúsculas y minúsculas, aparte de se menos eficiente\nlistaMeses.sort() \nprint(f\"{listaMeses} \\n\")\n# Diccionario\nfor clave,valor in sorted(dicMesesDias.items()):\n    print(f\"El mes {clave} tiene {valor} dias\")\n# Conjuntos\nprint(sorted(conjuntoFruta))\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\nCrea una agenda de contactos por terminal.\n- Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n- Cada contacto debe tener un nombre y un número de teléfono.\n- El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación \nlos datos necesarios para llevarla a cabo.\n- El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos. \n(o el número de dígitos que quieras)\n- También se debe proponer una operación de finalización del programa.\n\"\"\"\n\n\"\"\" Necesitamos un menú inicial, usaremos un bucle While para que no se salga hasta que no se decida\ny se muestre si la opción seleccionada no es la correcta\"\"\"\n\nimport os\nimport time\n\n\"\"\"\n* BBDD TEMPORAL\n- Lista que actúa como una BBDD para a la aplicación\n\"\"\"\n# Inicial, sin datos\ncontactosAgenda = []\n\n# Pruebas, con Datos\n# contactosAgenda = [\n#     [\"Pepe\",645875932],\n#     [\"Juan\",645875931],\n#     [\"Juan Pablo\",645875934],\n#     [\"Pepe Viña\",645875938]\n# ] \n\n\"\"\"\n# VARIABLES\n- Las usaremos en diferentes partes de la aplicación\n\"\"\"\ntimeoutMenuPrincipal = 2\ntimeoutMenuSeccion = 1\nnumeroIntentosMax = 3\n\n\"\"\"\n* CÓDIGO GENÉRICO REUTILIZABLE\n- Pequeñas porciones de código a usar en diferentes lugares de la aplicación\n\"\"\"\n# Mensaje de Salida\ndef mensajeSalidaAPP():\n    # Limpiar pantalla\n    os.system('cls')\n    # Mostrar mensaje\n    print(\"¡Hasta pronto!\")\n\n# Cuando acabamos en una sección damos un tiempo para mostrar el resultado y re-direccionar al inicio de la aplicación\ndef volverInicioApp():\n    print(f\"Será redireccionado al menú principal ...\")\n    time.sleep(timeoutMenuPrincipal)\n    menuAgenda()\n\n# Cuando acabamos en una sección damos un tiempo para mostrar el resultado y re-direccionar al inicio de la aplicación\ndef volverSeccionApp(seccion:str):\n    print(f\"Será redireccionado al menú {seccion} ...\")\n    time.sleep(timeoutMenuSeccion)\n    # Según la elección re-dirigimos a una sección u otra\n    if seccion in \"buscar\":\n        buscarContacto()\n    elif seccion in \"nuevo\":\n        nuevoContacto()\n    elif seccion in \"actualizar\":\n        actualizarContacto()\n    elif seccion in \"eliminar\":\n        eliminarContacto()\n    elif seccion in \"principal\":\n        menuAgenda()\n\n\"\"\"\n* COMPROBACIONES\n- Pequeñas funciones reutilizables cuyo objetivo es comprobar datos en la BBDD principalmente\n\"\"\"\n# Comprobar si existen contactos en la BBDD\n# Objetivo: Devolver el número de contactos si existe alguno en la BBDD\ndef existenContactos():\n    if len(contactosAgenda) > 0:\n        return True\n    else:\n        return False\n\n# Comprobar y no Mostrar si se ha encontrado un contacto almacenado en la agenda\n# Objetivo: Comprboar y no Mostrar los datos de un contacto en BBDD (ID, NOMBRE o TELEFONO)\ndef existeElContacto(id=-1,nombre=\"\",telefono=0):\n    # Por los Test unitarios\n    if isinstance(telefono,str):\n        telefono = int(telefono)\n    # Recorremos la BBDD en busca del contacto en base a los datos que nos facilitan\n    for i in range(0,len(contactosAgenda)):\n        pacienteEncontrado = False\n        # Si encontramos una coincidencia asignamos los valores antes de devolverlos\n        if id <= len(contactosAgenda) and id >= 0 and nombre == \"\" and telefono == 0:\n            if id == i:\n                nombre = contactosAgenda[i][0]\n                telefono = contactosAgenda[i][1]\n                pacienteEncontrado = True\n                break\n        elif nombre != \"\":\n            if nombre in contactosAgenda[i][0]:\n                nombre = contactosAgenda[i][0]\n                telefono = contactosAgenda[i][1]\n                pacienteEncontrado = True\n                break\n        elif telefono != 0:\n            if telefono == contactosAgenda[i][1]:\n                nombre = contactosAgenda[i][0]\n                telefono = contactosAgenda[i][1]\n                pacienteEncontrado = True\n                break\n    # Depende de la resolución, devolvemos una u otra cosa\n    if pacienteEncontrado:\n        return True,i,nombre,telefono\n    else:\n        print(\"No existe el contacto.\")\n        return False,i,nombre,telefono\n\n# Mostrar UN solo contacto almacenado o no en la agenda\n# Objetivo: Mostrar los datos de un contacto en BBDD (ID) o Eliminado (pasando todos los datos)\ndef mostrarUnContacto(id=-1,nombre=\"\",telefono=0):\n    # Por los Test unitarios\n    if isinstance(telefono,str):\n        telefono = int(telefono)\n    # Si nos facilitan el ID\n    if id <= len(contactosAgenda) and id >= 0 and nombre == \"\" and telefono == 0:\n        print(\"-----\")\n        print(f\"Nº {id+1}:\")\n        print(f\"Nombre: {contactosAgenda[id][0]}\")\n        print(f\"Telefono: {contactosAgenda[id][1]}\")\n        print(\"-----\")\n        # Comprobar respuesta\n        return True\n    # Si nos facilitan el Nombre o Teléfono\n    elif nombre != \"\" and telefono != 0:\n        print(\"-----\")\n        print(f\"Nº {id+1}:\")\n        print(f\"Nombre: {nombre}\")\n        print(f\"Telefono: {telefono}\")\n        print(\"-----\")\n        # Comprobar respuesta\n        return True\n    else:\n        # No se encuentra ningún contacto con los datos proporcionados\n        #print(\"No existe el contacto.\")\n        return False\n    \n# Mostrar UNO O VARIOS contactos en la BBDD\n# Objetivo: Mostrar los diferentes contactos en BBDD según el filtro pasado, pensado para las búsquedas de contactos\n# antes de proceder a seleccionar y proceder a modificar o eliminar\ndef mostrarContactosFiltrados(tipo,valor):\n    try:\n        # Si hemos encontrado algún contacto o no\n        contactoEncontrado = False\n        # Por los Test unitarios\n        # if tipo == \"telefono\":\n        #     if isinstance(valor,str):\n        #         valor = int(valor)\n        # Recorremos la lista sin agregar un +1 porque si no se pasa\n        for i in range(0,len(contactosAgenda)):\n            if tipo == \"nombre\" and valor in contactosAgenda[i][0]:\n                print(\"-----\")\n                print(f\"Nº {i+1}:\")\n                print(f\"Nombre: {contactosAgenda[i][0]}\")\n                print(f\"Teléfono: {contactosAgenda[i][1]}\")\n                contactoEncontrado = True\n            if tipo == \"telefono\" and valor == contactosAgenda[i][1]:\n                print(\"-----\")\n                print(f\"Nº {i+1}:\")\n                print(f\"Nombre: {contactosAgenda[i][0]}\")\n                print(f\"Teléfono: {contactosAgenda[i][1]}\")\n                contactoEncontrado = True\n        # Comprobamos si ha encontrado algún paciente\n        if contactoEncontrado:\n            return True\n        else:\n            print(f\"No se ha encontrado un contacto por el {tipo}: {valor} \\n\")\n            return False\n    except Exception as e:\n        print(f\"Ha ocurrido algún tipo de error inexperado: {valor} \\n Detalles del error: {str(e)}\")\n        \n# Mostrar TODOS los contactos almacenados en la agenda\n# Objetivo: Mostrar al usuario TODOS los contactos, bien para consultarlos o para\n# que pueda elegir el código (ID) y posteriormente actualizar o eliminar el contacto\ndef listarTodosLosContactos():\n    for i in range(0,len(contactosAgenda)):\n        print(\"-----\")\n        print(f\"Nº {i+1}:\")\n        print(f\"Nombre: {contactosAgenda[i][0]}\")\n        print(f\"Telefono: {contactosAgenda[i][1]}\")\n    # Devolvemos por defecto True\n    return True\n\n\"\"\"\n* PREGUNTAS\n- Funciones de preguntas a realizar al usuario\n\"\"\"\n# Identificación de contacto\n# Objetivo: Identificamos al contacto que deseamos actualizar o eliminar\ndef identificarContacto():\n    # Intentos\n    intentos = 1\n    # Pregunta\n    identificadorContacto = input(\"Ingrese el número de contacto en la agenda: \")\n    # Procedemos con las preguntas\n    while intentos < numeroIntentosMax:\n        \n        if len(identificadorContacto) > 0:\n            # Convertimos a Numérico\n            identificadorContacto = int(identificadorContacto)\n            # Comprobamos que sea un número válido\n            if identificadorContacto > 0 and identificadorContacto <=len(contactosAgenda):\n                # Comprobamos que el identificador existe antes de proseguir\n                resultado = existeElContacto(identificadorContacto-1)\n                # Si el resultado es correcto devolvemos los datos\n                if resultado[0]:\n                    return resultado\n                break\n            else:\n                print(f\"Debe introducir un idencitificador válido entre el 1 al {len(contactosAgenda)} \\n\")\n                intentos += 1\n                identificadorContacto = input(\"Ingrese el número de contacto en la agenda: \")\n\n        else:\n            print(f\"Debe introducir un idencitificador válido entre el 1 al {len(contactosAgenda)} \\n\")\n            intentos += 1\n            identificadorContacto = input(\"Ingrese el número de contacto en la agenda: \")\n\n# Preguntar el dato a usar para la búsqueda del contacto\n# Objetivo: dar la posibilidad de buscar un contacto en base a los criterios de búsqueda seleccionado y datos facilitados\ndef preguntarDatosContactoAgenda(tipo):\n    try:\n        print(f\"Busqueda de contacto por {tipo}\")\n        valorBusqueda = input(\"Introduzca el valor a buscar: \")\n        if len(valorBusqueda) > 0:\n            # Si es nombre no tenemos que transformar los caracteres a numérico\n            if tipo ==\"nombre\":\n                resultado = mostrarContactosFiltrados(tipo=tipo,valor=valorBusqueda)\n                if resultado:\n                    return True\n                else:\n                    return False\n            # El teléfono ha de ser numérico, en caso de no ser así, asignamos un valor que nunca encontrará un contacto\n            elif tipo == \"telefono\":\n                # Convertimos a Numérico\n                # if isinstance(valorBusqueda,str):\n                #     valorBusqueda = int(valorBusqueda)\n                # Si todo va bien\n                resultado = mostrarContactosFiltrados(tipo=tipo,valor=valorBusqueda)\n                if resultado:\n                    return True\n                else:\n                    return False\n        else:\n            print(\"Debe introducir un valor válido para buscar un contacto\")\n            preguntarDatosContactoAgenda(tipo)\n    except:\n        print(\"\\n 2 Ha ocurrido algún tipo de error inexperado. \\n\")\n        \n\n# Volver a la sección donde estemos o a la pantalla principal\n# Objetivo: dar la posibilidad de volver a la sección anterior o volver al menú principal\ndef preguntarDondeVolver(seccion:str):\n    # Intentos\n    intentos = 1\n    # Controlamos la selección del usuario\n    seleccionVolver = False\n    secciónSeleccionada = seccion\n    # Pregunta\n    respuesta = input(f\"¿Desea volver a {seccion.capitalize()} o salir al menú principal? (v/s): \")\n    # Donde volveremos tras la acción que hayamos realizado\n    while intentos < numeroIntentosMax:\n        if respuesta != \"v\" and respuesta != \"V\" and respuesta != \"s\" and respuesta != \"S\":\n            print(\"Debe responder 'v' o 's' \\n\")\n            intentos += 1\n            # Pregunta\n            respuesta = input(f\"¿Desea volver a {seccion.capitalize()} o salir al menú principal? (v/s): \")\n        elif respuesta == \"v\" or respuesta == \"V\":\n            seleccionVolver = True\n            break\n        elif respuesta == \"s\" or respuesta == \"S\":\n            secciónSeleccionada=\"principal\"\n            seleccionVolver = True\n            break\n    \n    # Si todo ha ido bien, pasamos los datos\n    if seleccionVolver:\n        volverSeccionApp(seccion=secciónSeleccionada)\n        #return True\n    else:\n        volverSeccionApp(seccion=secciónSeleccionada)\n        #return False\n            \n# No existen contactos para buscar, actualizar o eliminar\n# Objetivo: dar la posibilidad de agregar un nuevo contacto desde otra sección diferente a Nuevo Contacto\ndef preguntarAgregarNuevoContacto():\n    # Intentos\n    intentos = 1\n    # Controlamos la selección del usuario\n    seleccionNuevoContacto = False\n    # Existen contactos anteriores\n    existenContactosAnteriores = False\n    if existenContactos():\n        existenContactosAnteriores = True\n    # Mostramos un mensaje si no existen contactos en BBDD\n    if not existenContactosAnteriores:\n        print(\"Actualmente no hay contactos en la agenda. \\n\")\n    # Pregunta\n    respuesta = input(f\"¿Desea agregar un contacto? (s/n): \")\n    # Añadimos un nuevo contacto sí o no\n    while intentos < numeroIntentosMax:\n        if respuesta != \"s\" and respuesta != \"S\" and respuesta != \"n\" and respuesta != \"N\":\n            print(\"Debe responder 's' o 'n' para proceder a agregar o no un nuevo contacto \\n\")\n            intentos += 1\n            # Pregunta\n            respuesta = input(f\"¿Desea agregar un contacto? (s/n): \")\n        elif respuesta == \"n\" or respuesta == \"N\":\n            print(\"No se ha agregar un nuevo contacto \\n\")\n            break\n        elif respuesta == \"s\" or respuesta == \"S\":\n            print(\"A continuación deberá agregar los datos del nuevo contacto. \\n\")\n            seleccionNuevoContacto = True\n            break\n    \n    # Si todo ha ido bien, pasamos los datos\n    if seleccionNuevoContacto:\n        return True\n    else:\n        return False\n\n# Datos del nuevo contacto\n# Objetivo: Preguntas datos sobre del Nuevo Contacto a ingresar en BBDD\ndef preguntasNuevoContacto():\n    # Intentos\n    intentos = 1\n    # ¿Se han resuelto todas las preguntas?\n    resultaPreguntaNombre = False\n    resultaPreguntaTelefono = False\n    # Pregunta \n    nombreNuevoContacto = input(\"Ingrese el Nombre del nuevo contacto: \")\n    # Comprobaciones\n    while intentos < numeroIntentosMax:\n        if len(nombreNuevoContacto) >= 1 and nombreNuevoContacto.replace(' ','').isalpha():\n            intentos = 1\n            resultaPreguntaNombre = True\n            break\n        else: \n            print(\"\\n El nombre ha de contener exclusivamente caracteres \\n\")\n            intentos += 1\n            # Pregunta \n            nombreNuevoContacto = input(\"Ingrese el Nombre del nuevo contacto: \")\n    # Telefono  \n    if resultaPreguntaNombre:\n        # Pregunta\n        telefonoNuevoContacto = input(\"Ingrese el teléfono del contacto Máximo 12 números): \")\n        # Comprobaciones\n        while intentos < numeroIntentosMax:\n            if len(telefonoNuevoContacto) >= 1 and len(telefonoNuevoContacto) <= 12:\n                if not telefonoNuevoContacto.isnumeric:\n                    telefonoNuevoContacto = int(telefonoNuevoContacto)\n                resultaPreguntaTelefono = True\n                break\n            else:\n                print(\"\\n El telefono ha de contener exclusivamente números y con un máximo de 12 números. \\n\")\n                intentos += 1\n                # Pregunta\n                telefonoNuevoContacto = input(\"Ingrese el teléfono del contacto Máximo 12 números): \")\n    # Si todo ha ido bien, pasamos los datos\n    if resultaPreguntaNombre and resultaPreguntaTelefono:\n        return nombreNuevoContacto,telefonoNuevoContacto\n    else: \n        print(\"\\n Datos proporcionados no son válidos. \\n\")\n        #volverSeccionApp(seccion=\"principal\")\n\n# Actualizar un contacto existente\n# Objetivo: Preguntas datos para actualizar un contacto existente en BBDD\ndef preguntasActualizadoContacto(id,nombre,telefono):\n    # Intentos\n    intentos = 1\n    # Para controlar si actualizamos alguno de los valores\n    resultaPreguntaNombre = False\n    resultaPreguntaTelefono = False\n    # Mensaje al usuario\n    print(\"*** Si no desea modificar el nombre presione Enter.\\n\")\n    # Pregunta\n    nombreNuevoContacto = input(f\"Modifique el nombre del contacto ({nombre}): \")\n    # Nombre\n    while intentos < numeroIntentosMax:\n        if nombreNuevoContacto == \"\":\n            print(\"No se ha modificado el nombre del contacto \\n\")\n            nombreNuevoContacto = nombre\n            break\n        elif len(nombreNuevoContacto) > 1 and nombreNuevoContacto.replace(' ','').isalpha():\n            intentos = 1\n            resultaPreguntaNombre = True\n            break\n        else: \n            print(\"\\n El nombre ha de contener exclusivamente caracteres \\n\")\n            intentos += 1\n            # Pregunta\n            nombreNuevoContacto = input(f\"Modifique el nombre del contacto ({nombre}): \")\n    # Telefono    \n    telefonoNuevoContacto = input(f\"Modifique el teléfono del contacto ({telefono}): \")\n    while intentos < numeroIntentosMax:\n        if telefonoNuevoContacto == \"\":\n            print(\"No se ha modificad el teléfono del contacto \\n\")\n            telefonoNuevoContacto = telefono\n            break\n        elif len(telefonoNuevoContacto) > 1 and len(telefonoNuevoContacto) <= 12:\n            # if not telefonoNuevoContacto.isnumeric:\n            #     telefonoNuevoContacto = int(telefonoNuevoContacto)\n            telefonoNuevoContacto = int(telefonoNuevoContacto)\n            resultaPreguntaTelefono = True\n            break\n        else:\n            print(\"\\n El telefono ha de contener exclusivamente números y con un máximo de 12 números. \\n\")\n            intentos += 1\n            # Pregunta\n            telefonoNuevoContacto = input(f\"Modifique el teléfono del contacto ({telefono}): \")\n    \n    # Si todo ha ido bien, pasamos los datos\n    if resultaPreguntaNombre or resultaPreguntaTelefono:\n        print(\"Procedemos a actualizar todos los datos del contacto ... \\n\")\n        return True, id, nombreNuevoContacto, telefonoNuevoContacto\n    elif resultaPreguntaNombre and not resultaPreguntaTelefono: \n        print(\"Procedemos a actualizar el nombre del contacto ... \\n\")\n        return True, id, nombreNuevoContacto, False\n    elif not resultaPreguntaNombre and resultaPreguntaTelefono: \n        print(\"Procedemos a actualizar el teléfono del contacto ... \\n\")\n        return True, id, False, telefonoNuevoContacto\n    else:\n        return False, id, nombreNuevoContacto, telefonoNuevoContacto\n            \n# Eliminar un contacto existente\n# Objetivo: Preguntas que contacto se desea elimianr de la BBDD\ndef preguntasEliminadoContacto(id,nombre,telefono):\n    # Intentos\n    intentos = 1\n    # Controlamos la selección del usuario\n    seleccionEliminacion = False\n    # Pregunta\n    respuesta = input(f\"¿Desea eliminar al contacto con Nombre ({nombre}) con el Teléfono ({telefono})? (s/n): \")\n    # Eliminamos sí o no\n    while intentos < numeroIntentosMax:\n        if respuesta != \"s\" and respuesta != \"S\" and respuesta != \"n\" and respuesta != \"N\":\n            print(\"Debe responder 's' o 'n' para proceder con la eliminación o no del contacto\\n\")\n            intentos += 1\n            # Pregunta\n            respuesta = input(f\"¿Desea eliminar al contacto con Nombre ({nombre}) con el Teléfono ({telefono})? (s/n): \")\n        elif respuesta == \"n\" or respuesta == \"N\":\n            break\n        elif respuesta == \"s\" or respuesta == \"S\":\n            seleccionEliminacion = True\n            break\n        else: \n            print(\"Debe responder 's' o 'n' para proceder con la eliminación o no del contacto\\n\")\n            intentos += 1\n    \n    # Si todo ha ido bien, pasamos los datos\n    if seleccionEliminacion:\n        return True, id\n    else:\n        return False, id\n\n\"\"\"\n* MODIFICACIÓN DE BBDD\n\"\"\"\n\n# BBDD - Agregado de los datos de un nuevo contacto facilitado por el usuario a la agenda\ndef agregarNuevoContacto(nombre,telefono):\n    # Agregamos la lista en la BBDD\n    contactosAgenda.append([nombre,telefono])\n    # Comprobamos que los datos están en la BBDD\n    resultado = existeElContacto(nombre=nombre,telefono=telefono)\n    # retornamos si se agregó o no, es decir,que existe en BBDD tras el agregado\n    return resultado\n        \n# BBDD - Actualizar los datos de un contacto por otros datos de la agenda\ndef actualizarContactoExistente(id,nombre,telefono):\n    # Actualizamos los datos, según los datos que nos pasen a actualizar\n    if len(nombre) > 0:\n        contactosAgenda[id][0]=nombre\n    if telefono > 1:\n        contactosAgenda[id][1]=telefono\n    # Comprobamos que los datos están en la BBDD, cualquierea de los dos\n    if  nombre in contactosAgenda[id][0] or telefono == contactosAgenda[id][1]:\n        return True\n    else:\n        return False\n         \n# BBDD - Agregado de los datos del contacto proporcionado de la Agenda\ndef eliminarContactoExistente(id):\n    # Agregamos la lista en la BBDD\n    returnValue = contactosAgenda.pop(id)\n    # Comprobamos que los datos ya no están en la BBDD\n    if returnValue:\n        return True\n    else:\n        return False\n        \n\"\"\"\n* SECCIONES / OPERACIONES\n- Se trata de las diferentes secciones / operaciones disponibles desde el menú principal\n\"\"\"\n# SECCIÓN BUSCAR CONTACTOS\ndef buscarContacto():\n    # Limpiar pantalla\n    os.system('cls')\n    # Inicio del Menú\n    print(\"\\n BÚSQUEDA DE CONTACTOS \\n\")\n    # Comprobamos su hay contactos, en aso de no existir, preguntamos si quieren agregar uno nuevo\n    if not existenContactos():\n        resultado = preguntarAgregarNuevoContacto()\n        if resultado:\n            nuevoContacto()\n        else:\n            # Re-enviamos al menú principal\n            volverInicioApp()\n    else:\n        # Menú de opciones de búsqueda de contacto\n        menuOpcionesBusquedaContacto()\n\n# SECCIÓN NUEVO CONTACTO\ndef nuevoContacto():\n    # Limpiar pantalla\n    os.system('cls')\n    # Inicio del Menú\n    print(\"\\n NUEVO CONTACTO \\n\")\n    # Comprobamos si hay contactos existentes\n    if not existenContactos():\n        print(\"Actualmente no hay contactos disponibles en la agenda.\")\n    else:\n        # Nos guardamos el número de contactos habidos en la agenda\n        print(f\"Nº de contactos existentes : {len(contactosAgenda)} \\n\")\n    # Preguntamos al usuario\n    nombreNuevoContacto, telefonoNuevoContacto = preguntasNuevoContacto()\n    # Agregamos los datos en la agenda\n    resultado = agregarNuevoContacto(nombre=nombreNuevoContacto,telefono=telefonoNuevoContacto)\n    if resultado[0]:\n        print(\"Nuevo contacto agregado a la Agenda\")\n        # Mostramos datos del contacto recién agregado\n        mostrarUnContacto(id=resultado[1])\n    else:\n        print(\"Nuevo contacto No fue agregado a la Agenda\")\n    # Re-enviamos al menú principal\n    volverInicioApp()\n\n# SECCIÓN ACTUALIZAR UN CONTACTO EXISTENTE\ndef actualizarContacto():\n    # Limpiar pantalla\n    os.system('cls')\n    # Inicio del Menú\n    print(\"\\n ACTUALIZAR CONTACTO \\n\")\n    \n    # Comprobamos su hay contactos, en aso de no existir, preguntamos si quieren agregar uno nuevo\n    if not existenContactos():\n        resultado = preguntarAgregarNuevoContacto()\n        if resultado:\n            nuevoContacto()\n        else:\n            # Re-enviamos al menú principal\n            volverInicioApp()\n    else:\n        # Nos guardamos el número de contactos habidos en la agenda\n        print(f\"Nº de contactos existentes : {len(contactosAgenda)} \\n\")\n        \n    # Preguntamos al usuario\n    datosContactoAModificar = identificarContacto()\n    # Actualizamos los datos del contacto\n    resultado = preguntasActualizadoContacto(id=datosContactoAModificar[1],nombre=datosContactoAModificar[2],telefono=datosContactoAModificar[3])\n    # Verificamos que podemos proceder con la actualización del contacto\n    if resultado[0]:\n        if actualizarContactoExistente(id=resultado[1],nombre=resultado[2],telefono=resultado[3]):\n            print(\"Modificación realizada\")\n            # Contacto anterior\n            print(\"Contacto anterior\")\n            mostrarUnContacto(id=resultado[1],nombre=datosContactoAModificar[2],telefono=datosContactoAModificar[3])\n            print(\"Contacto actualizado\")\n            # Contacto actualizado\n            mostrarUnContacto(id=resultado[1])\n            # Re-enviamos al menú principal\n            volverInicioApp()\n    else:\n        print(\"Modificación no realizada, no había nada que actualizar\")\n        # Re-enviamos al menú principal\n        volverInicioApp()\n\n# SECCIÓN ELIMINACIÓN DE CONTACTOS\ndef eliminarContacto():\n    # Limpiar pantalla\n    os.system('cls')\n    # Inicio del Menú\n    print(\"\\n ELIMINAR CONTACTO \\n\") \n    \n    # Comprobamos su hay contactos, en aso de no existir, preguntamos si quieren agregar uno nuevo\n    if not existenContactos():\n        resultado = preguntarAgregarNuevoContacto()\n        if resultado:\n            nuevoContacto()\n        else:\n            # Re-enviamos al menú principal\n            volverInicioApp()\n    else:\n        # Nos guardamos el número de contactos habidos en la agenda\n        print(f\"Nº de contactos existentes : {len(contactosAgenda)} \\n\")\n        \n    # Preguntamos al usuario\n    datosContactoAEliminar = identificarContacto()\n    # Actualizamos los datos del contacto\n    resultado = preguntasEliminadoContacto(id=datosContactoAEliminar[1],nombre=datosContactoAEliminar[2],telefono=datosContactoAEliminar[3])\n    # Verificamos que podemos proceder con la actualización del contacto\n    if resultado[0]:\n        if eliminarContactoExistente(id=resultado[1]):\n            print(\"Eliminación realizada del contacto:\")\n            # Contacto eliminado\n            mostrarUnContacto(id=resultado[1],nombre=datosContactoAEliminar[2],telefono=datosContactoAEliminar[3])\n            # Re-enviamos al menú principal\n            volverInicioApp()\n    else:\n        print(\"Modificación no realizada, no había nada que eliminar\")\n        # Re-enviamos al menú principal\n        volverInicioApp()\n\n\"\"\"\n* OPCIONES DE MENÚS\n- Opciones que corresponden a los diferentes menús\n\"\"\"\n# Menú de opciones de la agenda\nopcionesMenuPrincipal = {\n    1:\"Buscar contacto\",\n    2:\"Nuevo contacto\",\n    3:\"Actualizar contacto\",\n    4:\"Eliminar contacto\",\n    0:\"Salir\"\n}\n\n# Selección de búsqueda\nopcionesBusquedaContacto = {\n    1:\"Buscar por Nombre\",\n    2:\"Buscar por Teléfono\",\n    3:\"Mostrar todos los contactos\",\n    0:\"Volver\"\n}\n\n\"\"\"\n* MENUS\n- Diferentes menús a mostrar en las diferentes secciones u operaciones\n\"\"\"\n\n# Función con el menú de la agenda\ndef menuAgenda():\n    # Limpiar pantalla\n    os.system('cls')\n    # Inicio del menú\n    print(\"\\n MENU AGENDA DE CONTACTOS \\n\")\n    for clave,valor in opcionesMenuPrincipal.items():\n        print(f\"{clave} - {valor}.\")\n    try:\n        seleccionaOpcionMenu = input(\"\\n Seleccione una opción: \")\n        # Podriamos usar un While que ejecute en bucle la app mientras no sea 0 por ejemplo, pero no lo haremos en esta ocasión\n        # Verificamos que es un número lo que han introducido \n        if seleccionaOpcionMenu.isnumeric():    \n            # pasamos a int el valor pasado\n            seleccionaOpcionMenu = int(seleccionaOpcionMenu)\n            # Verificamos si el número pasado está dentro de la lista del menú\n            if seleccionaOpcionMenu in list(opcionesMenuPrincipal.keys()):\n                # Depende de la opcón hacemos una cosa u otra\n                if seleccionaOpcionMenu == 0:\n                    mensajeSalidaAPP()\n                # Buscar contacto\n                if seleccionaOpcionMenu == 1:\n                    buscarContacto()\n                # Nuevo contacto\n                if seleccionaOpcionMenu == 2:\n                    nuevoContacto()\n                # Actualizar contacto\n                if seleccionaOpcionMenu == 3:\n                    actualizarContacto()\n                # Eliminar contacto\n                if seleccionaOpcionMenu == 4:\n                    eliminarContacto()\n            else:\n                menuAgenda()\n        else:\n            menuAgenda()   \n    except:\n        print(\"\\n Ha ocurrido algún tipo de error inexperado. \\n\")\n\n# Función del menún de opciones de búsqueda\ndef menuOpcionesBusquedaContacto():\n    # Limpiar pantalla\n    os.system('cls')\n    # Inicio del Menú\n    print(\"\\n MENU BUSQUEDA DE CONTACTOS \\n\")\n    for clave,valor in opcionesBusquedaContacto.items():\n        print(f\"{clave} - {valor}.\")\n    try:\n        seleccionaOpcionMenuBusqueda = input(\"\\n Seleccione una opción: \")\n        # Verificamos que es un número lo que han introducido \n        if seleccionaOpcionMenuBusqueda.isnumeric():    \n            # pasamos a int el valor pasado\n            seleccionaOpcionMenuBusqueda = int(seleccionaOpcionMenuBusqueda)\n            # Verificamos si el número pasado está dentro de la lista del menú\n            if seleccionaOpcionMenuBusqueda in list(opcionesBusquedaContacto.keys()):\n                # Buscar contacto por nombre\n                if seleccionaOpcionMenuBusqueda == 1:\n                    preguntarDatosContactoAgenda(tipo=\"nombre\")\n                    # Dar opción de volver al menú\n                    preguntarDondeVolver(seccion=\"buscar\")\n                # Buscar contacto por teléfono\n                if seleccionaOpcionMenuBusqueda == 2:\n                    preguntarDatosContactoAgenda(tipo=\"telefono\")\n                    # Dar opción de volver al menú\n                    preguntarDondeVolver(seccion=\"buscar\")\n                # Mostrar todos los contactos\n                if seleccionaOpcionMenuBusqueda == 3:\n                    listarTodosLosContactos()\n                    # Dar opción de volver al menú\n                    preguntarDondeVolver(seccion=\"buscar\")\n                # Salir al menú principal\n                if seleccionaOpcionMenuBusqueda == 0:\n                    # Dar opción de volver al menú\n                    menuAgenda()\n            else:\n                menuOpcionesBusquedaContacto()\n        else:\n            menuOpcionesBusquedaContacto()   \n    except:\n        print(\"\\n Ha ocurrido algún tipo de error inexperado. \\n\")\n\n\"\"\"\n# Inicio del programa\n\"\"\"\nmenuAgenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/mouredev.py",
    "content": "\"\"\"\nEstructuras\n\"\"\"\n\n# Listas\nmy_list: list = [\"Brais\", \"Bl4ck\", \"Wolfy\", \"Visionos\"]\nprint(my_list)\nmy_list.append(\"Castor\")  # Inserción\nmy_list.append(\"Castor\")\nprint(my_list)\nmy_list.remove(\"Brais\")  # Eliminación\nprint(my_list)\nprint(my_list[1])  # Acceso\nmy_list[1] = \"Cuervillo\"  # Actualización\nprint(my_list)\nmy_list.sort()  # Ordenación\nprint(my_list)\nprint(type(my_list))\n\n# Tuplas\nmy_tuple: tuple = (\"Brais\", \"Moure\", \"@mouredev\", \"36\")\nprint(my_tuple[1])  # Acceso\nprint(my_tuple[3])\nmy_tuple = tuple(sorted(my_tuple))  # Ordenación\nprint(my_tuple)\nprint(type(my_tuple))\n\n# Sets\nmy_set: set = {\"Brais\", \"Moure\", \"@mouredev\", \"36\"}\nprint(my_set)\nmy_set.add(\"mouredev@gmail.com\")  # Inserción\nmy_set.add(\"mouredev@gmail.com\")\nprint(my_set)\nmy_set.remove(\"Moure\")  # Eliminación\nprint(my_set)\nmy_set = set(sorted(my_set))  # No se puede ordenar\nprint(my_set)\nprint(type(my_set))\n\n# Diccionario\nmy_dict: dict = {\n    \"name\": \"Brais\",\n    \"surname\": \"Moure\",\n    \"alias\": \"@mouredev\",\n    \"age\": \"36\"\n}\nmy_dict[\"email\"] = \"mouredev@gmail.com\"  # Inserción\nprint(my_dict)\ndel my_dict[\"surname\"]  # Eliminación\nprint(my_dict)\nprint(my_dict[\"name\"])  # Acceso\nmy_dict[\"age\"] = \"37\"  # Actualización\nprint(my_dict)\nmy_dict = dict(sorted(my_dict.items()))  # Ordenación\nprint(my_dict)\nprint(type(my_dict))\n\n\"\"\"\nExtra\n\"\"\"\n\n\ndef my_agenda():\n\n    agenda = {}\n\n    def insert_contact():\n        phone = input(\"Introduce el teléfono del contacto: \")\n        if phone.isdigit() and len(phone) > 0 and len(phone) <= 11:\n            agenda[name] = phone\n        else:\n            print(\n                \"Debes introducir un número de teléfono un máximo de 11 dígitos.\")\n\n    while True:\n\n        print(\"\")\n        print(\"1. Buscar contacto\")\n        print(\"2. Insertar contacto\")\n        print(\"3. Actualizar contacto\")\n        print(\"4. Eliminar contacto\")\n        print(\"5. Salir\")\n\n        option = input(\"\\nSelecciona una opción: \")\n\n        match option:\n            case \"1\":\n                name = input(\"Introduce el nombre del contacto a buscar: \")\n                if name in agenda:\n                    print(\n                        f\"El número de teléfono de {name} es {agenda[name]}.\")\n                else:\n                    print(f\"El contacto {name} no existe.\")\n            case \"2\":\n                name = input(\"Introduce el nombre del contacto: \")\n                insert_contact()\n            case \"3\":\n                name = input(\"Introduce el nombre del contacto a actualizar: \")\n                if name in agenda:\n                    insert_contact()\n                else:\n                    print(f\"El contacto {name} no existe.\")\n            case \"4\":\n                name = input(\"Introduce el nombre del contacto a a eliminar: \")\n                if name in agenda:\n                    del agenda[name]\n                else:\n                    print(f\"El contacto {name} no existe.\")\n            case \"5\":\n                print(\"Saliendo de la agenda.\")\n                break\n            case _:\n                print(\"Opción no válida. Elige una opción del 1 al 5.\")\n\n\nmy_agenda()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/mplatab.py",
    "content": "\"\"\"\nEstructuras de datos por defecto de python\n\"\"\"\n\n# Listas\nmy_list = [\"orange\", 'banana', 'pear', 'apple', 'kiwi']\nprint(my_list)\n\nmy_list.append(\"grape\") # Inserción\nprint(my_list)\n\nmy_list.remove(\"pear\") # Eliminación\nprint(my_list)\n\nmy_list[1] = 'strawberry' # Actualización\nprint(my_list)\n\nmy_list.sort() # Ordenación\nprint(my_list)\nprint(type(my_list))\n\n# Tuplas -> son inmutables\nmy_tuple = (\"Marcos\", \"Plata\", \"@mplatab\", \"25\")\nprint(my_tuple[1]) # Acceso\nprint(my_tuple[3])\n\nmy_tuple = tuple(sorted(my_tuple)) # Ordenación\nprint(my_tuple)\nprint(type(my_tuple))\n\n# Sets -> por definición es una estructura desordenada y no agrega datos duplicados\nmy_set = {\"Marcos\", \"Plata\", \"@mplatab\", \"25\"}\nprint(my_set)\nmy_set.add(\"mjsilver98\") # Inserción\n\nmy_set.remove(\"25\") # Eliminacion\n\nmy_set = set(sorted(my_set)) # no se puede ordenar\nprint(my_set)\nprint(type(my_set))\n\n# Diccionario -> key:value\n\nmy_dict: dict = {\"age\": 25, \"name\": \"Marcos\", \"last_name\": \"Plata\"}\n\nmy_dict[\"email\"] = \"example@gmail.com\" # Inserción\nprint(my_dict)\n\ndel(my_dict[\"last_name\"]) # Eliminación\nprint(my_dict)\n\nmy_dict[\"age\"] = 26 # Actualización\nprint(my_dict)\n\n\nmy_dict = dict(sorted(my_dict.items())) # Ordenación\nprint(my_dict)\nprint(type(my_dict))\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):ẞ\n\"\"\"\n\ndef my_agenda():\n    agenda = {}\n\n    def insert_contact():\n        phone = input(\"Ingrese el nuevo número de telefono: \")\n        if phone.isdigit() and len(phone) > 0 and len(phone) <= 11:\n            agenda[name] = phone\n        else:\n            print(\"Introduccion un número de telefeno máximo de 11 dígitos\")\n\n    while True:\n        print(\"1. Buscar contacto\")\n        print(\"2. Insertar contacto\")\n        print(\"3. Actualizar contacto\")\n        print(\"4. Eliminar contacto\")\n        print(\"5. Salir\")\n\n        option = input(\"\\nSeleciona una opción: \")\n        match option:\n            case \"1\":\n                name = input(\"Ingrese el nombre del contacto que desee buscar: \").lower()\n                if name in agenda:\n                    print(f\"El número de teléfono de {name} es {agenda[name]}.\")\n                else:\n                    print(f\"El contacto {name} no existe\")    \n            case \"2\":\n                name = input(\"Ingresa el nombre de contacto: \").lower()\n                insert_contact()\n            case \"3\":\n                name = input(\"Ingrese el nombre del contacto que desea actualizar: \").lower()\n                if name in agenda:\n                    insert_contact()\n                else:\n                    print(f\"El contacto {name} no existe\")    \n            case \"4\":\n                name = input(\"Ingrese el nombre del contacto que desea eliminar: \").lower()\n                if name in agenda:\n                    del(agenda[name])\n                else:\n                    print(f\"El contacto {name} no existe\")    \n\n            case \"5\":\n                print(\"Salir de la agenda\")\n                break\n            case _:\n                print(\"Opción no valida. Elige una opción del 1 al 5\")\n    \n\nmy_agenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/mrodara.py",
    "content": "# ESTRUCTURAS DE DATOS EN PYTHON\n\n######## CADENAS DE CARACTERES (Tipo de dato inmutable) #######################\n\ncadena = \"Hola que tal\"\n\nprint('Concatenación: ' + cadena + cadena)\n\nprint('Repetición: ' + cadena*3)\n\nprint('Indexación: ' + cadena[0] + cadena[1])\n\nprint('Longitud de la cadena (len): ' + str(len(cadena)))\n\n# Las cadenas se pueden recorrer\n\ncadena = 'informática'\n\nfor caracter in cadena:\n  print(caracter, \" \" ,  end=\"\")\n  \n'''\nOperadores de pertenencia: Se puede comprobar si un elemento (subcadena) pertenece o no \na una cadena de caracteres con los operadores in y not in.\n'''\nprint('á' in cadena)\n\nprint('p' in cadena)\n\nprint('p' not in cadena)\n\n\"\"\"\nSlice (rebanada): Puedo obtener una subcadena de la cadena de caracteres. \nSe indica el carácter inicial, y el carácter final, además podemos indicar opcionalmente un salto. \nSi no se indica el carácter inicial se supone que es desde el primero, sino se indica el carácter final \nse supone que es hasta el final. \nPor último podemos usar salto negativo para empezar a contar desde el final.\n\"\"\"\n\ncadena = \"inteligencia artifical\"\n\nprint(cadena[2:5])\n\nprint(cadena[2:7:2])\n\nprint(cadena[:5])\n\nprint(cadena[5:])\n\nprint(cadena[-1:-3])\n\nprint(cadena[::-1])\n\nprint(cadena[::-2])\n\n# Podemos convertir cualquier número en una cadena de caracteres utilizando la función str()\nnum = str(123)\n\nprint(type(num))\n\n\n######## FIN CADENAS DE CARACTERES (Tipo de dato inmutable) #######################\n\n######## LISTAS (Tipo de dato mutable) #######################\n\nmy_list = [1,2,3,4,5]\n\n# Las listas pueden almacenar distintos tipos de datos\nmy_list2 = [1, 'hola', True]\n\n# También se pueden definir listas vacías para luego agregarle elementos\nmy_list3 = []\n\n# Podemos obtener el valor de una posición concreta de la lista mediante su índice (base-0)\n# Esto quiere decir que los elementos de la lista van desde el 0 hasta el nro. de elementos - 1\n\nprint(my_list2[1]) # retorna la cadena\n\n# Añadir elementos a una lista (método append) \nmy_list3.append(1)\nprint(my_list3)\n\nnew_list = [2,3,4,5]\n\n# Añadir una lista a otra lista\nmy_list3.extend(new_list)\nprint(my_list3)\n\n# Añadimos más elementos a la lista de manera automatizada\nfor i in range(1,5):\n    my_list3.append(i * 2)\n\n# Actualizar un dato de la lista\nmy_list3[0] = 3 * my_list3[0]\nprint(my_list3)\n\n# La ordenación de una lista se puede realizar mediante la función sorted()\n\nprint(sorted(my_list3))\n\n# Importante las variables en python son por referencia luego no podemos asignar un lista a otra para copiarla\nmy_list4 = my_list3\n\nprint(my_list3)\n\nmy_list4[0] = 100\n\nprint(my_list3)\n\n# Lo correcto es hacer esto\n\nmy_list4 = [i for i in my_list3] # List comprenhension\n\nprint(my_list3)\nprint(my_list4)\n\nmy_list4[0] = 0\n\nprint(my_list3)\nprint(my_list4)\n\n# También podemos realizar operaciones de pertenencia\n\nprint(0 in my_list4)\n\nprint(100 in my_list4)\n\n# Recorrido de listas\n\n# Usando bucle for\nfor i in my_list4:\n    print(i, \",\" ,end=\"\")\n\n# Mediante slice\n\nprint(my_list4[0:]) # Imprime toda la lista\nprint(my_list4[0:3]) # Imprime los elementos desde la posición 0 hasta la 2\nprint(my_list4[::-1]) # Imprime la lista en orden inverso\nprint(my_list4[::2]) # Imprime los elementos de la lista de 2 en 2\nprint(my_list4[1::2]) # Imprime los elementos de la lista de 2 en 2 pero empezando desde la posición 1\n\n\n# Se pueden repetir listas\n\nmy_list5 = my_list4 * 2\nprint(my_list5)\n\n# Se pueden concatenar listas\nmy_list6 = my_list4 + my_list5\nprint(my_list6)\n\n# Se pueden eliminar elementos de una lista\nmy_list6.pop() # Elimina el último elemento de la lista\nprint(my_list6)\nmy_list6.pop(0) # Elimina el primer elemento de la lista\nprint(my_list6)\n\n# Se pueden eliminar elementos de una lista por su valor\nmy_list6.remove(0) # Elimina el primer elemento que coincida con el valor\nprint(my_list6)\n\n# Podemos conocer el número de elementos de una lista\nprint(len(my_list6))\n\n# Podemos conocer el índice de un elemento en la lista\nprint(my_list6.index(2))\nprint(my_list6.index(2, 1)) # Busca el elemento a partir de la\n# posición 1\n\n# Podemos contar cuántas veces se repite un elemento en la lista\nprint(my_list6.count(2))\n\n# Podemos invertir el orden de los elementos de una lista\nmy_list6.reverse()\nprint(my_list6)\n\n# Uso de funciones predefinidas sobre elementos de una lista\nprint(max(my_list6))\nprint(min(my_list6))\nprint(sum(my_list6))\nprint(sum(my_list6)/len(my_list6)) # Promedio de los elementos de la lista\n\n######## FIN DE LISTAS ###########\n\n######## TUPLAS (TIPO DE DATO INMUTABLE) ##################################\n\n# Las tuplas son similares a las listas pero no se pueden modificar una vez creadas\nmy_tuple = (1,2,3,4,5)\n# print(my_tuple[0] = 10) # Esto no se puede hacer porque las tuplas son inmutables\n'''\n Las tuplas se pueden recorrer.\n Operadores de pertenencia: in y not in.\n Concatenación: +\n Repetición: *\n Indexación\n Slice\n\nEntre las funciones definidas podemos usar: len, max, min, sum, sorted\n'''\n######## FIN TUPLAS (TIPO DE DATO INMUTABLE) ##################################\n\n######## DICCIONARIOS (MAPAS) ##################################\n\n# Los diccionarios son una estructura de datos que permite almacenar pares clave-valor\n# Las claves deben ser únicas y los valores pueden ser de cualquier tipo\n\n# Creación de un diccionario\nmy_dict = {'nombre': 'Juan', 'edad': 25, 'cursos': ['Python', 'Java', 'JavaScript']}\n\nmy_dict2 = {} # Diccionario vacío\n\n# Acceso a los elementos de un diccionario\nprint(my_dict['nombre'])\nprint(my_dict['edad'])\n\n# Modificación de un valor de un diccionario\nmy_dict['nombre'] = 'Pedro'\nprint(my_dict['nombre'])\n\n# Añadir un nuevo par clave-valor\nmy_dict['sexo'] = 'M'\nprint(my_dict)\n\n# Eliminar un par clave-valor\ndel my_dict['sexo']\nprint(my_dict)\n\n# Recorrer un diccionario\n# Recorrer las claves\n\nfor key in my_dict.keys():\n  print(key, end=\" \")\n\n# Recorrer los valores\nfor value in my_dict.values():\n  print(value, end=\"\")\n\n# Recorrer los pares clave-valor\nfor key, value in my_dict.items():\n  print(f'{key} : {value}')\n\n######## FIN DICCIONARIOS (MAPAS) ##################################\n\n########  EJERCICIO EXTRA - AGENDA DE CONTACTOS  ########\n\nend = False\nphone_values = [\"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \"0\"]\ncontact_list = []\n\nwhile not end:\n  #Imprimir menu de opciones\n  print('#### AGENDA DE CONTACTOS POR TERMINAL ####')\n  print(\"1. Añadir un contacto\")\n  print(\"2. Buscar un contacto\")\n  print(\"3. Modificar un contacto\")\n  print(\"4. Eliminar un contacto\")\n  print(\"5. Salir de la agenda.\")\n  \n  option = int(input(\"¿Qué deseas hacer? (1-5): \"))\n  \n  # Control de opción introducida\n  while option not in range(1, 6):\n    print(\"Error: Debes introducir un valor entre 1 y 5.\")\n    option = int(input(\"¿Qué deseas hacer?\"))\n  \n  # Gestión de la opción\n  if option == 1:\n    print(\"Añadir un contacto\")\n    name = input(\"Introduce el nombre del contacto: \")\n    while name == \"\" or len(name) < 3:\n      print(\"Error: El nombre debe tener al menos 3 caracteres.\")\n      name = input(\"Introduce el nombre del contacto: \")\n      \n    phone = input(\"Introduce el número de teléfono (máximo 11 digitos entre el 0 y el 9): \")\n    while phone == \"\" or len(phone) > 11:\n      print(\"Error: Debes introducir un número de teléfono válido: \")\n      phone = input(\"Introduce el número de teléfono (máximo 11 digitos entre el 0 y el 9): \")\n    \n    # Comprobación adicional de que el usuario solo mete dígitos en el campo phone\n    for digit in phone:\n      if digit not in phone_values:\n        print(\"Error: El número introducido tiene valores no válidos para un nro. de teléfono, se autocompleta con 0000 y después deberás modid¡ficarlo\")\n        phone = \"0000\"\n        continue\n    \n    # Agregamos los valores \n    contact = {\"name\" : name, \"phone\" : phone}\n    contact_list.append(contact)\n    \n    print(f\"Se ha añadido el contacto: {contact} a la agenda\")\n    \n  elif option == 2:\n    print(\"Buscar un contacto\")\n    name = input(\"Introduce el nombre del contacto a buscar: \")\n    while name == \"\" or len(name) < 3:\n      print(\"Error: El nombre debe tener al menos 3 caracteres.\")\n      name = input(\"Introduce el nombre del contacto a buscar: \")\n    \n    for contact in contact_list:\n      if contact[\"name\"].lower() == name.lower():\n        print(\"Contacto encontrado\")\n        print(f\"Nombre: {contact['name']}, teléfono: {contact['phone']}\")\n        break\n      else:\n        print(\"Contacto no encontrado, si desea añadirlo puede hacerlo\")\n      \n  elif option == 3:\n    print(\"Modificar un contacto\")\n    name = input(\"Introduce el nombre del contacto a modificar: \")\n    while name == \"\" or len(name) < 3:\n      print(\"Error: El nombre debe tener al menos 3 caracteres.\")\n      name = input(\"Introduce el nombre del contacto a buscar: \")\n    \n    for contact in contact_list:\n      if contact[\"name\"].lower() == name.lower():\n        print(\"Contacto encontrado\")\n        name = input(\"Introduce el nuevo nombre de contacto o nada si no se va a modificar este campo: \")\n        phone = input(\"Introduce el número de teléfono (máximo 11 digitos entre el 0 y el 9): \")\n        while phone == \"\" or len(phone) > 11:\n          print(\"Error: Debes introducir un número de teléfono válido: \")\n          phone = input(\"Introduce el número de teléfono (máximo 11 digitos entre el 0 y el 9): \")\n        \n        #Modificamos los datos\n        contact[\"name\"] = name if name != \"\" else contact[\"name\"]\n        contact[\"phone\"] = phone\n        \n        print(f\"Se ha modificado el contacto, ahora se muestra así: {contact}\")\n        break\n      else:\n        print(\"Contacto no encontrado, si desea añadirlo puede hacerlo\")\n  elif option == 4:\n    print(\"Eliminar un contacto\")\n    name = input(\"Introduce el nombre del contacto a modificar: \")\n    while name == \"\" or len(name) < 3:\n      print(\"Error: El nombre debe tener al menos 3 caracteres.\")\n      name = input(\"Introduce el nombre del contacto a buscar: \")\n    for contact in contact_list:\n      if contact[\"name\"].lower() == name.lower():\n        print(\"Contacto encontrado, se procede a su eliminación...\")\n        del contact[\"name\"]\n        print(\"Proceso de eliminación completado...\")\n        break\n      else:\n        print('El contacto no se encuentra en la agenda, luego no es posible su eliminación.')\n  else:\n    end = True\n    print(\"Fin de la aplicación\")\n\n########  FIN EJERCICIO EXTRA - AGENDA DE CONTACTOS  ########"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/mvidalb.py",
    "content": "'''\nEstructuras\n'''\n\n# Listas\nmy_list:list = [\"Brais\", \"Pedro\", \"Mario\", \"Edu\"]\nprint(my_list)\nmy_list.append(\"Javier\")    # Inserción\nprint(my_list)\nmy_list.remove(\"Brais\")     # Eliminación\nprint(my_list)\nprint(my_list[1])           # Acceso\nmy_list[1] = \"José\"\nprint(my_list)              # Actualización\nmy_list.sort()              # Ordenación\nprint(my_list)\n\n# Tuplas - estructura inmutable\nmy_tuple:tuple = (\"Mario\", \"Vidal\", \"mvidalb\", \"40\")\nprint(my_tuple[1])              # Acceso\nmy_tuple = sorted(my_tuple)     # Devuelve una lista a partir de una tupla\n\n# Sets - estructura desordenada, evita datos duplicados\nmy_set:set = {\"Mario\", \"Vidal\", \"mvidalb\", \"40\"}\nmy_set.add(\"abc@gmail.com\")     # Inserción\nmy_set.add(\"abc@gmail.com\")\nprint(my_set)\nmy_set.remove(\"Vidal\")          # Eliminación\nprint(my_set)\nsorted(my_set)                  # Devuelve una lista a partir de un set\nprint(my_set)\n\n# Diccionario\nmy_dict:dict = {\n    \"name\":\"Mario\", \n    \"apellido\":\"Vidal\", \n    \"mote\":\"mvidalb\", \n    \"edad\":\"40\"\n    }\nprint(my_dict[\"name\"])          # Acceso\ndel my_dict[\"apellido\"]         # Eliminación\nmy_dict[\"mote\"] = \"garrulo\"     # Inserción\nsorted(my_dict.items())         # DEvuelve una lista\n\n\n'''\nEjercicio extra\n'''\ndef my_agenda():\n    \n    agenda = {}\n    while True:\n\n        print(\"\\nAGENDA\")\n        print(\"1. Buscar contacto\")\n        print(\"2. Insertar contacto\")\n        print(\"3. Actualizar contacto\")\n        print(\"4. Eliminar contacto\")\n        print(\"5. Salir\")\n\n        option = input(\"\\nSelecciona una opción: \")\n\n        match option:\n            case \"1\":\n                name = input(\"Introduce el contacto a buscar: \")\n                if name in agenda:\n                    print(f\"Contacto encontrado: \\n{name} - {agenda[name]}\")\n                else:\n                    print(f\"El contacto {name} no existe.\")\n            case \"2\":\n                name = input(\"\\nIntroduce el contacto a guardar: \")\n                phone = input(\"Introduce el número a guardar: \")\n                if phone.isdigit() and len(phone) <= 11:\n                    agenda[name] = phone\n                    print(\"\\nContacto guardado!\")\n                else:\n                    print(\"Debes de introducir un número de teléfono con máximo 11 dígitos.\")\n            case \"3\":\n                name = input(\"Introduce el contacto a actualizar: \")\n                if name in agenda:\n                    phone = input(\"\\ntroduce el número del contacto: \")\n                    if phone.isdigit() and len(phone) <= 11:\n                        agenda[name] = phone\n                        print(\"\\nContacto actualizado!\")\n                else:\n                    print(\"Debes de introducir un número de teléfono con máximo 11 dígitos.\")\n            case \"4\":\n                name = input(\"Introduce el contacto a eliminar: \")\n                if name in agenda:\n                    del agenda[name]\n                    print(\"Contacto eliminado.\")\n                else:\n                    print(f\"El contacto {name} no existe.\")\n            case \"5\":\n                print(\"Saliendo de la agenda.\")\n                break\n            case _:\n                print(\"Opción no válida, elige una opción del 1 al 5.\")\n\n        \nmy_agenda()\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/neslarra.py",
    "content": "\"\"\"\n EJERCICIO:\n - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n\n DIFICULTAD EXTRA (opcional):\n Crea una agenda de contactos por terminal.\n - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n - Cada contacto debe tener un nombre y un número de teléfono.\n - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n   los datos necesarios para llevarla a cabo.\n - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n   (o el número de dígitos que quieras)\n - También se debe proponer una operación de finalización del programa.\n\"\"\"\nimport json                   # para poder dar persistencia a los contactos de la actividad extra.\n\n# Tupla: es inmutable => no la puedo modificar (como se crea queda). Está indexada: a cada elemento le corresponde una posición.\nprint(f\"-- Tuplas {'-' * 50}\")\nmaterias = ('matemáticas', 'ciencias', 'lenguas', 'deportes', 'talleres', 'sociales')\nprint(f\"El curso cuenta con {materias.__len__()} materias -> {materias}\")\nmateria = materias[3]\nindice = materias.index(\"deportes\")\nprint(f\"Buscar la materia que está en el índice 3: materia = materias[3] => {materia}\")\nprint(f\"Buscar la posición de la materia 'deportes': indice = materias.index('deportes') => {indice}\", end=\"\\n\\n\")\n\n# Set: es nmutable => admite remociones y agragados PERO no modificar un elemento. Es única => sus elementos NO se repiten. NO está indexado.\n# Frozenset es un set INMUTABLE.\nprint(f\"-- Set {'-' * 50}\")\ncitricos = {'naranja', 'limón', 'manzana', 'mandarina', 'bergamota', 'naranja', 'cidra', 'limón', 'pomelo', 'lima'}\nprint(f\"Cítricos: {citricos}\")\ncitricos.discard('manzana')      # la diferencia entre discard y remove es que el primero NO da error si el elemento a eliminar no existe.\ncitricos.add('kiwi')\nprint(f\"Elimino la 'manzana': citricos.discard('manzana')\")\nprint(f\"y agrego el 'kiwi': citricos.add('kiwi')\")\nprint(f\"Cítricos: {citricos}\")\ncosas_agrias = {'limón', 'ruibarbo', 'pomelo', 'berenjena', 'lima', 'rúcula', 'vinagre'}\ncitricos_agrios = cosas_agrias.intersection(citricos)\nprint(f\"Cítricos Agrios: cosas_agrias.intersection(citricos) => {citricos_agrios}\")\nprint(f\"Cítricos Dulces: citricos.difference(citricos_agrios) => {citricos.difference(citricos_agrios)}\", end=\"\\n\\n\")\n\n# Lista: es mutable => la puedo modificar. También está indexada.\nprint(f\"-- Listas {'-' * 50}\")\nnotas: list = [1, 4, 8, 5, 1, 4, 9, 9, 4, 6, 6, 5, 3, 6, 4, 1, 11, 4, 8.75, 9]\nindice = notas.index(11)\nnotas.remove(11)\nnotas.insert(indice, 10)\nprint(f\"Buscar la posición de la nota '11': indice = materias.index('11') => {indice}\")\nprint(f\"Eliminar la nota '11': notas.remove(11)\")\nprint(f\"e insertar una nueva nota '10': notas.insert(indice, 10)\")\nindice = notas.index(8.75)\nnotas[indice] = 9\nprint(f\"Buscar la posición de la nota '8.75': indice = notas.index(8.75)\")\nprint(f\"y reemplazar con un '9': notas[indice] = 9\")\nnotas.append(7)\nprint(f\"Agregar nuevas notas: notas.append(7)\")\nprint(f\"También se puede ordenar la lista y operar con sus elementos.\")\nprint(f\"Notas: {notas}\")\nprint(f\"Alumnos: {notas.__len__()}\")\nprint(f\"Promedio: {(sum(notas) / notas.__len__()).__round__(2)}\")\nnotas.sort()\nprint(f\"Notas ordenadas: {notas}\")\nprint(f\"Mediana:{notas[(notas.__len__() // 2)]}\")\nmoda = -1\nfor n in set(notas):                                    # Transformo la lista en un set para contar las ocurrencias de cada elemento.\n    moda = n if notas.count(n) > moda else moda\nprint(f\"Moda: {moda}\")\nprint(f\"Nota más baja: {min(notas)}\")\nprint(f\"Nota más alta: {max(notas)}\")\ndesaprobados = [1 for x in notas if x < 4].__len__()\nprint(f\"Desaprobados: {desaprobados}\")\nprint(f\"Aprobados: {notas.__len__() - desaprobados}\", end=\"\\n\\n\")\n\n# Diccionario: es mutable => la puedo modificar. NO está indexada. Se accede por clave.\nprint(f\"-- Diccionarios {'-' * 50}\")\nsaludos = {\"español\": \"hola\", \"inglés\": \"hello\", \"latín\": \"salve\"}\nprint(f\"{saludos}\")\nprint(f\"Busco si una clave está dentro del diccionario y muestro el valor: if 'inglés' in saludos.keys()\")\nif \"inglés\" in saludos.keys():\n    print(f\"Inglés: {saludos['inglés']}\")\nprint(f\"Muestro las claves: saludos.keys()\")\nprint(f\"{saludos.keys()}\")\nprint(f\"Muestro los valores: saludos.values()\")\nprint(f\"{saludos.values()}\")\nprint(f\"Agrego una nueva entrada: saludos['italiano'] = 'ciao'\")\nsaludos[\"italiano\"] = \"ciao\"\nprint(f\"Elimino una entrada: del saludos['latín']\")\ndel saludos[\"latín\"]\nmundo_traducido = {\"español\": \"mundo\", \"inglés\": \"world\", \"latín\": \"orbe\", \"italiano\": \"mondo\", \"portugués\": \"mundo\", \"francés\": \"monde\"}\nprint(f\"Modifico entradas asignando un nuevo valor a la clave: saludos[key] = 'nuevo valor'\")\nfor key, value in saludos.items():\n    saludos[key] = value + \" \" + mundo_traducido[key]\nprint(f\"{saludos}\", end=\"\\n\\n\")\n\n# Complejidad extra:\nprint(f\"-- Complejidad extra {'-' * 50}\")\ncontactos = {}\ncontactos_modificados = False\n\n\ndef cargar_contactos() -> bool:\n    global contactos\n    try:\n        with open(\"contactos.json\", \"r\") as cntos:\n            contactos = json.load(cntos)\n        return True\n    except Exception as e:\n        print(f\"Error cargando contactos: {e}\")\n        return False\n\n\ndef guardar_contactos() -> bool:\n    global contactos\n    try:\n        with open(\"contactos.json\", \"w\") as cntos:\n            json.dump(contactos, cntos, indent=4, sort_keys=True)\n        print(\"Contactos guardados !!!\")\n        return True\n    except Exception as e:\n        print(f\"Error guardando contactos: {e}\")\n        return False\n\n\ndef validar_contacto(nombre: str) -> bool:\n    if nombre in contactos.keys():\n        print(f\"El contacto YA existe !!!\")\n        return False\n    return True\n\n\ndef validar_telefono(telefono: str) -> bool:\n    if not telefono.isnumeric():\n        print(f\"Solo ingresar dígitos !!!\")\n        return False\n    if telefono.__len__() not in range(5, 12):\n        print(f\"Faltan o sobran dígitos !!!\")\n        return False\n    return True\n\n\ndef alta_contacto() -> bool:\n    global contactos\n    global contactos_modificados\n\n    def nuevo_nombre() -> str:\n        while True:\n            nombre = input(\"Nombre del nuevo contacto ('--' para cancelar): \").title()\n            if nombre != \"--\" and not validar_contacto(nombre):\n                continue\n            return nombre\n\n    def nuevo_numero() -> str:\n        while True:\n            telefono = input(\"Teléfono ('--' para cancelar): \")\n            if telefono != \"--\" and not validar_telefono(telefono):\n                continue\n            return telefono\n\n    nombre = nuevo_nombre()\n    telefono = nuevo_numero() if nombre != \"--\" else \"--\"\n\n    if \"--\" not in (nombre, telefono):\n        contactos[nombre] = telefono\n        contactos_modificados = True\n\n    return True\n\n\ndef baja_contacto() -> bool:\n    global contactos\n    global contactos_modificados\n\n    nombre = buscar_contacto()\n    if nombre != \"--\":\n        del contactos[nombre]\n        contactos_modificados = True\n\n    return True\n\n\ndef buscar_contacto() -> str:\n    nombre = \"\"\n    while True:\n        nombre = input(\"Ingresar patrón de búsqueda (-- para cancelar): \").lower()\n        if nombre == \"--\":\n            break\n        nombres = [n for n in contactos.keys() if n.lower().__contains__(nombre)]\n\n        if nombres.__len__() == 0:\n            print(\"No hubo coincidencia.\")\n            continue\n\n        nombres.append(\"Volver\")\n\n        for p, n in enumerate(nombres):\n            print(f\"{p} - Nombre: {n}  /  Teléfono: {contactos[n] if n != 'Volver' else '--'}\")\n\n        opcion = \"-1\"\n        while int(opcion) not in range(0, nombres.__len__()):\n            opcion = input(f\"Seleccione un nombre de contacto (0 - {nombres.__len__() - 1}): \")\n        nombre = nombres[int(opcion)]\n\n        break\n\n    return nombre if nombre != \"Volver\" else \"--\"\n\n\ndef modifica_contacto() -> bool:\n    global contactos\n    global contactos_modificados\n\n    def nuevo_nombre() -> str:\n        while True:\n            nombre = input(\"Nombre del nuevo contacto (Enter si no cambia): \").title()\n            if nombre and not validar_contacto(nombre):\n                continue\n            return nombre\n\n    def nuevo_numero() -> str:\n        while True:\n            telefono = input(\"Teléfono (Enter si no cambia): \")\n            if telefono and not validar_telefono(telefono):\n                continue\n            return telefono\n\n    nombre = buscar_contacto()\n    if nombre != \"--\":\n        telefono = contactos[nombre]\n\n        while True:\n            nombre_nuevo = nuevo_nombre()\n            telefono_nuevo = nuevo_numero()\n\n            if nombre_nuevo or telefono_nuevo:\n                if nombre_nuevo:\n                    del contactos[nombre]\n                    nombre = nombre_nuevo\n                contactos[nombre] = telefono_nuevo if telefono_nuevo else telefono\n                contactos_modificados = True\n            break\n\n    return True\n\n\ndef ver_contacto() -> bool:\n    for nombre, telefono in contactos.items():\n        print(f\"Nombre: {nombre}  /  Teléfono: {telefono}\")\n\n    return True\n\n\ndef salir() -> bool:\n    return False\n\n\ndef menu() -> str:\n    opciones = {\"0\": \"salir\", \"1\": \"alta\", \"2\": \"baja\", \"3\": \"modifica\", \"4\": \"ver\", \"5\": \"buscar\"}\n    opcion = \"-1\"\n    print(\"\"\"\n    Elija la opción a ejecutar:\n       1 - Alta de contacto\n       2 - Baja de contacto\n       3 - Modificación de contacto\n       4 - Ver contactos\n       5 - Buscar contacto\n       0 - Salir\n    \"\"\")\n    while int(opcion) not in range(0, opciones.__len__()):\n        opcion = input(f\"Ingresar opcion (0-{opciones.__len__() - 1}): \")\n\n    return opciones[opcion]\n\n\ndef main():\n    if not cargar_contactos():\n        print(F\"No hay contactos disponibles => cargar el primer contacto.\")\n        alta_contacto()\n\n    while True:\n        operacion = menu()\n        ejecutar = operacion + (\"()\" if operacion == \"salir\" else \"_contacto()\")\n        if not eval(ejecutar):\n            break\n\n    guardar_contactos() if contactos_modificados else None\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/njaimev.py",
    "content": "# Una estructura de dato es un \"contenedor\" que permite organizar, almacenar y manipular datos de manera eficiente.\n# Tenemos las listas, tuplas, conjuntos, diccionaros, también pilas y colas en collections.\n# Esto nos ayuda a organizar datos para optimizar la eficiencia y rendimiento.\n# Reduce la complejidad en la manipulación de grande volúmenes de información.\n# Facilita el acceso, búsqueda y modificación de los datos de manera efectiva.\n\n# LISTAS (list)\n# Almacena colecciones de elementos ordenados y modificables, puede ser cualquier tipo de dato.\n\nmi_lista = [1, 35, \"Gato\", 7.25, True]\nmi_lista2 = [1, 47, 23, 78, 12]\n\nmi_lista.append(\"Edificio\")                   #Inserta al final\nmi_lista.pop()                                #Elimina el último elemento\nmi_lista.insert(2, \"Perro\")                   #Inserta en una posición específica\nmi_lista[4] = 15                              #Actualiza el dato en un índice específico\nmi_lista[1:3] = [20, 40]                      #Reemplaza una porción\nmi_lista2.sort()                              #Ordena en su lugar menor a mayor\nnueva_lista = sorted(mi_lista2, reverse=True) #Crea una nueva lista ordenada mayor a menor\n\nprint(mi_lista)\nprint(mi_lista2)\n\n# TUPLAS (tuple)\n# Son como las listas, pero INMUTABLES (no pueden modificarse).\n# Util para datos que no deben cambiar.\n\nmi_tupla = (10, 70, 20, 50)\nmi_tupla = tuple(sorted(mi_tupla))  #Ordena la tupla, pero convirtiendola en otra lista, al decirle tuple, vuelve a convertirla en tupla\n\nprint(mi_tupla)\n\n\n# CONJUNTOS (set)\n# Colección NO ordenada de elementos únicos (no hay duplicados).\n# Utiles para operaciones de conjuntos como unión, intersección y diferencia.\n\nmi_conjunto = {1, 8, 15, 3, 14, 15}\nmi_conjunto.add(4)          #Inserta al final\nmi_conjunto.add(3)          #No se inserta porque es duplicado\nmi_conjunto.remove(3)       #Elimina el valor nombrado\nmi_conjunto.discard(5)      #Elimina el valor nombrado, no da error si no existe\nmi_conjunto.pop()           #Elimina un elemento aleatorio\nlista_ordenada = sorted(mi_conjunto) #Ordena, pero convertido en lista, NO SE PUEDE ORDENAR UN SET\n\nprint(mi_conjunto)\nprint(lista_ordenada)\n\n# DICCIONARIOS (dict)\n# Almacena pares clave-valor, donde la clave es única y se asocia a un valor.\n# Permite acceso rápido a los datos mediante la clave.\n\nmi_diccionario = {\"nombre\": \"Juan\", \"edad\": 30, \"ciudad\": \"Santiago\"}\nmi_diccionario[\"comuna\"] = \"Las Condes\"                     #Inserta una nueva clave-valor\nmi_diccionario.pop(\"edad\")                                  #Elimina la clave mencionada\nmi_diccionario.popitem()                                    #Elimina un elemento aleatorio\nmi_diccionario.clear()                                      #Elimina todos los elementos\nmi_diccionario[\"nombre\"] = \"Matías\"                         #Actualiza el valor de la clave mencionada\nmi_diccionario.update({\"ciudad\": \"Arica\", \"pais\": \"Chile\"}) #Actualiza y/o agrega datos\n\nprint(mi_diccionario)\n\n#En diccionarios se ordena por: claves, valores o pares clave-valor\n\nclaves_ordenadas = sorted(mi_diccionario.keys())                      #Ordena las claves por orden alfabético\nvalores_ordenados = sorted(mi_diccionario.values())                   #Ordena los valores por orden alfabetico o menor a mayor\nitems_ordenados = sorted(mi_diccionario.items(), key=lambda x: x[1])  #Ordena pares clave-valor según el valor\n\nprint(claves_ordenadas)\nprint(valores_ordenados)\nprint(items_ordenados)\n\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n\"\"\"\n\n\ndef contactos():\n\n    agenda = {}\n\n    while True:\n\n        print(\"\")\n        print(\"1. Buscar contacto\")\n        print(\"2. Insertar contacto\")\n        print(\"3. Actualizar contacto\")\n        print(\"4. Eliminar contacto\")\n        print(\"5. Salir\")\n\n        option = input(\"Seleccione una opción del 1 al 5: \")\n\n        match option:\n            \n            case \"1\":\n                nombre = input(\"Nombre a buscar: \")\n                if nombre in agenda:\n                    print(f\"El número de {nombre} es {agenda[nombre]}.\")\n                else:\n                    print(f\"El contacto {nombre} no existe.\")\n\n            case \"2\":\n                nombre = input(\"Nombre: \")\n                numero = input(\"Número: \")\n                if numero.isdigit() and len(numero) > 0 and len(numero) <= 11:\n                    agenda[nombre] = numero\n                    print(\"Contacto agregado exitosamente.\")\n                else:\n                    print(\"Introduce un numero válido (Máx. 11 dígitos)\")\n\n            case \"3\":\n                nombre = input(\"Nombre del contacto a actualizar: \")\n                if nombre in agenda:\n                    numero = input(\"Nuevo número: \")\n                    if numero.isdigit() and len(numero) > 0 and len(numero) <= 11:\n                        agenda[nombre] = numero\n                        print(\"Contacto actualizado.\")\n                    else:\n                        print(\"Introduce un numero válido (Máx. 11 dígitos)\")\n\n                else:\n                    print(\"Contacto {nombre} no existe.\")\n\n                \n            case \"4\":\n                nombre = input(\"Nombre de contacto a eliminar: \")\n                if nombre in agenda:\n                    del agenda[nombre]\n                    print(\"Contacto eliminado.\")\n                else:\n                    print(\"Contacto {nombre} no existe.\")\n\n            case \"5\":\n                print(\"Saliendo\")\n                break\n            case _:\n                print(\"Opción inválida, seleccione una opción  del 1 al 5.\")\n\ncontactos()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/nlarrea.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n\"\"\"\n\n# LISTS\n\nfrom audioop import reverse\n\n\nfruits = [\"apple\", \"orange\", \"pear\", \"banana\"]\n\n# Insert new items\n\nfruits.append(\"melon\")\nfruits.insert(2, \"strawberry\")\nprint(fruits)\n# ['apple', 'orange', 'strawberry', 'pear', 'banana', 'melon']\n\nfruits = [\"apple\", \"orange\", \"pear\", \"banana\"]\nfruits.extend([\"melon\", \"strawberry\"])  # add multiple items at the end\nprint(fruits)  # ['apple', 'orange', 'pear', 'banana', 'melon', 'strawberry']\n\n# Remove items from list\n\nfruits.pop(2)  # removes by index -> IndexError if item not found\nfruits.remove(\"melon\")  # removes by value -> ValueError if item not found\nprint(fruits)  # ['apple', 'orange', 'banana', 'strawberry']\n\n# Update the list\n\n# Negative indexes -> from back to front\nfruits[-1] = \"banana\"\nprint(fruits)  # ['apple', 'orange', 'banana', 'banana']\n\n# Positive indexes -> from front to back\nfruits[2] = \"pear\"\nprint(fruits)  # ['apple', 'orange', 'pear', 'banana']\n\n# Order lists\n\n# Ascending order -> without modifying the original\nasc_fruits = sorted(fruits)\nprint(asc_fruits)  # ['apple', 'banana', 'orange', 'pear']\nprint(fruits)  # ['apple', 'orange', 'pear', 'banana']\n\n# Ascending order -> modifying the original\nfruits.sort()\nprint(fruits)  # ['apple', 'banana', 'orange', 'pear']\n\n# Descending order -> without modifying the original\ndes_fruits = list(reversed(fruits))\nprint(des_fruits)  # ['pear', 'orange', 'banana', 'apple']\nprint(fruits)  # ['apple', 'banana', 'orange', 'pear']\n\n# Descending order -> modifying the original\nfruits.reverse()\nprint(fruits)  # ['pear', 'orange', 'banana', 'apple']\n\n# SETS -> remove duplicates\n\nfruit_set = {\"apple\", \"orange\", \"pear\", \"banana\", \"banana\"}\nprint(fruit_set)\n# {'pear', 'orange', 'banana', 'apple'} -> it also modifies the order\n\n# Insert new items\n\nfruit_set.add(\"melon\")\nprint(fruit_set)  # {'pear', 'melon', 'banana', 'orange', 'apple'}\n\n# Remove one item\n\nfruit_set.remove(\"pear\")  # if item not found -> KeyError\nprint(fruit_set)  # {'melon', 'apple', 'banana', 'orange'}\n\nfruit_set.discard(\"orange\")  # if item not found -> nothing happens\nprint(fruit_set)\n\n# Remove all\n\nfruit_set.clear()\nprint(fruit_set)  # set()\n\n# DICTIONARIES\n\nperson = {\"name\": \"Naia\", \"age\": 25}\n\n# Insert new data\n\nperson[\"country\"] = \"Spain\"\nprint(person)\n# {'name': 'Naia', 'age': 25, 'country': 'Spain'}\n\n# Update data\n\nperson[\"age\"] = 26\nprint(person)\n# {'name': 'Naia', 'age': 26, 'country': 'Spain'}\n\n# Remove data\n\n# .pop() -> receives a key and returns the removed value\nperson.pop(\"country\")  # if key not found -> KeyError\nprint(person)\n# {'name': 'Naia', 'age': 26}\n\nperson.pop(\"country\", \"Not country found\")\n# default value given -> no error raising, returns default\nprint(person)\n# {'name': 'Naia', 'age': 26}\n\n\n\"\"\"\n/* DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\"\"\"\n\ncontact_list: list[dict] = []\n\n\ndef print_menu():\n    print(\"\\nWhat do you want to do?\")\n    print(\"1. Add contact\")\n    print(\"2. Find contact\")\n    print(\"3. Update contact\")\n    print(\"4. Remove contact\")\n    print(\"5. View contact list\")\n    print(\"6. Exit\")\n\n\ndef print_contact_data(\n    name: str, number: str, print_message: bool = True\n) -> None:\n    if print_message:\n        print(\"\\nHere is the contact data:\")\n\n    print(f\" - Name: {name}\")\n    print(f\" - Phone: {number}\")\n\n\ndef print_contact_list() -> None:\n    if len(contact_list) == 0:\n        print(\"\\nThere are not contacts yet.\")\n        return\n\n    print(\"\\nThese are the stored contacts:\")\n    for contact in contact_list:\n        print_contact_data(**contact, print_message=False)\n        print()\n\n\ndef check_correct_phone(number: str) -> bool:\n    if len(number) > 11:\n        print(\"\\nThe phone number must be less than 11 characters length.\")\n    elif not number.isdigit():\n        print(\"\\nThe phone number must be a number.\")\n    else:\n        return True\n\n    return False\n\n\ndef add_contact(name, number) -> bool:\n    is_correct_phone = check_correct_phone(number)\n\n    if not is_correct_phone:\n        return False\n\n    if find_contact_by_name(name):\n        print(\"\\nThe introduced name already exists.\")\n        return False\n\n    contact_list.append({\"name\": name, \"number\": number})\n    print(\"\\nThe new contact has been created.\")\n    print_contact_data(name, number)\n    return True\n\n\ndef find_contact_by_name(name_to_find) -> dict | None:\n    try:\n        return [\n            contact\n            for contact in contact_list\n            if contact.get(\"name\") == name_to_find\n        ][0]\n    except IndexError:\n        return None\n\n\ndef find_contact_index(name, number) -> int | None:\n    try:\n        return contact_list.index({\"name\": name, \"number\": number})\n    except ValueError:\n        return None\n\n\ndef update_contact(old_data, new_data) -> bool:\n    contact_index = find_contact_index(**old_data)\n\n    if contact_index is None:\n        print(\"\\nThe contact doesn't exist.\")\n        return False\n\n    contact_list[contact_index] = {**new_data}\n    print_contact_data(**new_data)\n    return True\n\n\ndef remove_contact(name, number) -> bool:\n    contact_index = find_contact_index(name, number)\n\n    if contact_index is None:\n        print(\"\\nThe contact doesn't exist.\")\n        return False\n\n    removed_contact = contact_list.pop(contact_index)\n    print(\"\\nContact removed successfully.\")\n    print(\"This is the removed data:\")\n    print_contact_data(**removed_contact, print_message=False)\n    return True\n\n\ndef run():\n    print_menu()\n    option = input(\"Select your option (1-6): \")\n\n    if option == \"1\":\n        # ADD CONTACT\n\n        new_name = input(\"\\nEnter the new name:\\n> \")\n\n        contact = find_contact_by_name(new_name)\n        if contact:\n            print(\"\\nThe contact already exists. Use another name instead.\")\n            run()\n\n        new_number = input(\"Enter the new phone number:\\n> \")\n\n        add_contact(new_name, new_number)\n        run()\n\n    elif option == \"2\":\n        # FIND CONTACT\n\n        name = input(\"\\nEnter the name to find:\\n> \")\n\n        contact = find_contact_by_name(name)\n        if not contact:\n            print(\"\\nNo contact has been found.\")\n        else:\n            print_contact_data(**contact)\n\n        run()\n\n    elif option == \"3\":\n        # UPDATE CONTACT\n\n        old_name = input(\"\\nEnter the name of the contact to update:\\n> \")\n\n        contact = find_contact_by_name(old_name)\n        if not contact:\n            print(\"\\nThe contact doesn't exist.\")\n\n        new_data = {**contact}\n        print(\"\\nWhat do you want to update?\")\n        print(\"1. Contact name\")\n        print(\"2. Contact phone number\")\n        modifier = input(\"Select (1-2): \")\n\n        if modifier == \"1\":\n            new_data[\"name\"] = input(\"\\nEnter the new name:\\n> \")\n            update_contact(contact, new_data)\n        elif modifier == \"2\":\n            new_number = input(\"\\nEnter the new number:\\n> \")\n\n            is_correct_number = check_correct_phone(new_number)\n            if not is_correct_number:\n                run()\n\n            new_data[\"number\"] = new_number\n            update_contact(contact, new_data)\n        else:\n            print(\"\\nNot a correct option.\")\n\n        run()\n\n    elif option == \"4\":\n        # REMOVE CONTACT\n\n        c_name = input(\"\\nEnter the name of the contact to remove:\\n> \")\n\n        contact = find_contact_by_name(c_name)\n        if not contact:\n            print(\"\\nThe contact doesn't exist.\")\n            run()\n\n        remove_contact(**contact)\n        run()\n\n    elif option == \"5\":\n        # VIEW CONTACT LIST\n\n        print_contact_list()\n        run()\n\n    elif option == \"6\":\n        # EXIT\n\n        return\n\n    else:\n        print(\"\\nOption not allowed.\")\n        run()\n\n\nrun()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/nox456.py",
    "content": "\"\"\"\nListas\n\"\"\"\n\nnums = [1,2,3,4]\n\n# borrado\nnums.pop(0) # por índice\nnums.remove(2) # por valor\nnums.clear() # eliminar todos los elementos de la lista\n\n# inserción\nnums.append(5)\nnums.insert(1, 10) # por índice\nnums.extend([1,5]) # extender de otra lista\n\n# actualización\nnums[0] = 11 # por indice\n\n# ordenación\nnums.sort()\n\n\"\"\"\nTuplas\n\"\"\"\n\nnumsTuple = (10,2,13,42,5)\n\n# obtener valores\nnumsTuple[0] # 1\n\n# ordenación\nsorted(numsTuple)\n\n\"\"\"\nSet\n\"\"\"\n\nnumsSet = {1,3,5,6}\n\n# borrado\nnumsSet.pop() # primer elemento\nnumsSet.remove(3) # por valor\nnumsSet.clear() # eliminar todos los elementos\nnumsSet.discard(5) # eliminar si existe en el set\n\n# inserción\nnumsSet.add(7)\n\n# actualización\nnumsSet.update({20,30})\n\n\"\"\"\nDiccionario\n\"\"\"\n\nperson = {'name': 'michael', 'last_name': 'bay'}\n\n# inserción\nperson['age'] = 30\n\n# borrado\nperson.pop('last_name')\ndel person['age']\n\n# actualización\nperson['name'] = \"gabriel\"\n\n\"\"\"\nOpcional\n\"\"\"\n\ncontactos = []\nprint(\"****AGENDA****\")\nwhile True :\n    print(\"1. Buscar contactos (por nombre)\")\n    print(\"2. Crear contacto\")\n    print(\"3. Actualizar contacto\")\n    print(\"4. Eliminar contacto\")\n    print(\"5. Salir\")\n\n    opcion = int(input(\"Eliga su operación: \"))\n\n    if opcion == 1:\n        nombre = input(\"Ingrese el nombre del contacto: \")\n        contactosEncontrados = []\n        for contacto in contactos:\n            if contacto['nombre'] == nombre:\n                contactosEncontrados.append(contacto)\n\n        if len(contactosEncontrados) == 0:\n            print(f\"No hay contactos con el nombre {nombre}\")\n        else:\n            print(f\"El número de {nombre} es {contactosEncontrados[0]['télefono']}\")\n    elif opcion == 2:\n        nombre = input(\"Ingrese el nombre del contacto: \")\n        tlf = input(\"Ingrese el número de télefono: \")\n        if not tlf.isdigit():\n            print(\"El número de télefono debe ser numérico!!\")\n            continue\n        if len(tlf) != 11:\n            print(\"El número de télefono debe tener 11 digitos!!\")\n            continue\n\n        contactos.append({'nombre': nombre, 'télefono': tlf})\n        print(\"Contacto agregado!\")\n    elif opcion == 3:\n        nombre = input(\"Ingrese el nombre del contacto que quiere actualizar: \")\n        contactosEncontrados = []\n        for contacto in contactos:\n            if contacto['nombre'] == nombre:\n                contactosEncontrados.append(contacto)\n\n        if len(contactosEncontrados) == 0:\n            print(f\"No hay contactos con el nombre {nombre}\")\n        else:\n            tlf = input(\"Ingrese el nuevo número de télefono: \")\n            if not tlf.isdigit():\n                print(\"El número de télefono debe ser numérico!!\")\n                continue\n            if len(tlf) != 11:\n                print(\"El número de télefono debe tener 11 digitos!!\")\n                continue\n            contactos[contactos.index(contactosEncontrados[0])]['télefono'] = tlf\n            print(\"Contacto acutalizado!\")\n            continue\n    elif opcion == 4:\n        nombre = input(\"Ingrese el nombre del contacto que quiere eliminar: \")\n        contactosEncontrados = []\n        for contacto in contactos:\n            if contacto['nombre'] == nombre:\n                contactosEncontrados.append(contacto)\n        if len(contactosEncontrados) == 0:\n            print(f\"No hay contactos con el nombre {nombre}\")\n        else:\n            contactos.pop(contactos.index(contactosEncontrados[0]))\n            print(\"Contacto eliminado!\")\n            continue\n    elif opcion == 5:\n        break\n\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/oniricoh.py",
    "content": "# ###############################################################################\n# ###Estructuras de datos\n# ###############################################################################\n# array = [[1, 2, 3],\n#           [4, 5, 6],\n#           [7, 8, 9]]\n\n# lista = [\"oro\", \"plata\", \"cobre\", \"hierro\", \"diamante\"]\n\n# tupla = (1, 3, 4, 5)\n\n# diccionario = {\"dani\":34,\n#                 \"pedro\":42,\n#                 \"ana\": 56,\n#                 \"manolo\": 15}\n\n# mi_conjunto = {1, 9, 8, 5, 6, 2}\n\n\n# #############################LISTA#############################################\n# print(\"\\nLista\") \n# # insercion\n# lista.append(\"estalacmita\")\n# lista.insert(1, \"roca\")\n# print(lista)\n# #borrado\n# borrado = lista.pop(1)\n# lista.remove(\"oro\")\n# print(lista) \n# #actualizacion\n# lista[2] = \"arena\"\n# print(lista)\n# #ordenacion\n# list_sorted = sorted(lista)\n# print(list_sorted)\n# lista.reverse()\n# print(lista)\n\n\n# ##############################MATRIZ###########################################\n# print(\"\\nMatriz\") \n# #insercion\n# array.append([10, 11, 12])\n# #borrado\n# array.remove([1, 2, 3])\n# #actualizacion\n# array[0][1] = \"new\"\n# #ordenacion\n# array.sort(reverse=True)\n# print(array)\n\n\n# ##########################TUPLA################################################\n# print(\"\\nTupla\") \n# # insercion:\n# tupla_a_lista = list(tupla)\n# tupla_a_lista.append(22)\n# tupla = tuple(tupla_a_lista)\n# print(tupla)\n\n\n# ###############################DICIONARIO######################################\n# print(\"\\nDicionario\") \n# #insercion/actualizacion\n# diccionario[\"ana\"] = 5\n# #borrado\n# del diccionario[\"manolo\"]\n# #ordenacion\n# sorted(diccionario.items())\n# print(diccionario)\n\n\n# #########################CONJUNTOS / sets ############################################\n# print(\"\\nconjuntos\")\n# #insercion\n# mi_conjunto.add(15)\n# #borrado\n# mi_conjunto.remove(1)\n# #actualizacion\n# #inmutables\n# #ordenacion:\n# mi_lista_ordenada = set(sorted(mi_conjunto))\n# print(type(mi_conjunto))\n# print(mi_lista_ordenada)\n\n\n# print()\n# print()\n# print()\n# ##############################################################################\n### DIFICULTAD EXTRA\n##############################################################################\n\ndiary = dict()\n\ndef new_contact(name, phone):\n    diary[name] = phone\n    print(f\"contacto {name} agregado\")\n\ndef update_contact(name, phone):\n    diary[name] = phone\n    print(f\"contacto {name} agregado\")\n\ndef phone_contact(name):\n    if name in diary:\n        print()\n        print(f\"Numero Telefono: {diary[name]}\")\n        print()\n    else:\n        print(f\"El contanto {name} no existe\")\n    \ndef remove_contact(name):\n    if name in diary:\n        del diary[name]\n        print(f\"{name} ha sido eliminado de la agenda\")\n    else:\n        print(f\"No se encontró el contacto {name}\")\n\n\ndef main():\n    while True:\n        print(\"MENU:\")\n        print(\"1. Nuevo contacto\")\n        print(\"2. Buscar telefono de contacto\")\n        print(\"3. Eliminar un contacto\")\n        print(\"4. Cambiar numero de un contacto\")\n        print(\"5. ver agenda completa\")\n        print(\"6. salir\")\n        order = input(\"\\ncuál es la operación que se quiere realizar:\")\n        if order==\"6\" or order==\"salir\":\n            print(\"Adios!\")\n            break \n        else:\n            options(order)\n\ndef options(order):    \n    if order==\"1\" or order==\"nuevo contacto\":\n        name = input(\"Nombre del contacto: \")\n        phone = phone_number()\n        new_contact(name, phone)\n    \n    elif order==\"2\" or order==\"Buscar telefono de contacto\":\n         name = input(\"Nombre del contacto: \")\n         phone_contact(name)\n\n    elif order==\"3\" or order==\"eliminar un contacto\":\n        name = input(\"Nombre del contacto: \")\n        remove_contact(name)\n    \n    elif order==\"4\" or order==\"cambiar numero de un contacto\":\n        name = input(\"Nombre del contacto: \")\n        phone = phone_number()\n        update_contact(name, phone)\n    \n    elif order==\"5\" or order==\"ver agenda completa\":\n        for key, value in diary.items():\n            print(f\"{key}: {value}\")   \n    \n    else:\n        print(\"Error opcion no valida\")   \n\ndef phone_number():\n    while True:\n        phone = input(\"Telefono del contacto: \")\n        if phone.isdigit() and len(phone) == 9:\n            break\n        else:\n            print(\"Numero de telefono no valido.\")\n            print(\"Por favor, escribe un numero valido.\")\n    return int(phone)\n    \nmain()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/oriaj3.py",
    "content": "# #03 ESTRUCTURAS DE DATOS\n#### Dificultad: Media | Publicación: 15/01/24 | Corrección: 22/01/24\n#import\nfrom queue import Queue\nimport numpy as np\nimport sys\nfrom colorama import Fore, Back\n\n\n\n## Ejercicio\n\"\"\" \n*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n \"\"\"\n### EJEMPLOS DE CREACIÓN DE ESTRUCTURAS DE DATOS ###\n \n### LISTAS ###\n# Las listas son una estructura de datos usada para guardar variables. Permiten variables de distintos tipos de datos, mutables \n# y se pueden ordenar, se pueden repetir elementos, se pueden modificar, se pueden añadir y quitar elementos. \n#Creación\nlista = [1,2,3,4,5]\nlista2 = [\"hola\", \"que\", \"tal\"]\n\n#Insercción \nlista.append(6)\nlista2.append(\"estas\")\n\n#Borrado\nlista.remove(2)\nlista2.remove(\"que\")\n\n#Actualización\nlista[0] = 0\nlista2[0] = \"adios\"\n\n#Ordenación\nprint(lista)\n\n#ordena de mayor a menor\nlista.sort(reverse=True)\nprint(lista)\n\n#Ordena  alfabeticamente\nprint(lista2)\nlista2.sort()  \nprint(lista2)\n\n### TUPLAS ###\n#Las tuplas son una estructura de datos usada para guardar variables. Permiten variables de distintos tipos de datos, inmutables \n# y no se pueden ordenar, no se pueden repetir elementos, no se pueden modificar, no se pueden añadir y quitar elementos.\n\n#Creación\ntupla = (1,2,3,4,5)\ntupla2 = (\"hola\", \"que\", \"tal\")\n\n#Insercción\n#No se puede insertar\n\n#Borrado\n#No se puede borrar\n\n#Actualización\n#No se puede actualizar\n\n#Ordenación\n#No se puede ordenar\n\n### DICCIONARIOS ###\n#Los diccionarios son una estructura de datos usada para guardar variables. Permiten variables de distintos tipos de datos, \n# mutables y se pueden ordenar, no se pueden repetir elementos, se pueden modificar, se pueden añadir y quitar elementos.\n\n#Creación\ndiccionario = {\n    \"uno\":1, \n    \"dos\":2, \n    \"tres\":3, \n    \"cuatro\":4, \n    \"cinco\":5}\n\ndiccionario2 = {\n    \"nombre\" : \"Juan\",\n    \"apellido\" : \"Perez\",\n    \"edad\" : 18,\n    \"telefono\" : 123456789\n}\n\n#Insercción\ndiccionario[\"seis\"] = 6\n\ndiccionario2[\"direccion\"] = \"calle falsa 123\"\n\n#Borrado\ndiccionario.pop(\"uno\")\ndiccionario2.pop(\"edad\")\n\n#Actualización\ndiccionario[\"dos\"] = 22\ndiccionario2[\"nombre\"] = \"Pedro\"\n\n#Ordenación\n#No se puede ordenar\nprint(diccionario)\nprint(diccionario2)\n\n### SETS ###\n#Los sets son una estructura de datos usada para guardar variables. Permiten variables de distintos tipos de datos, mutables \n# y se pueden ordenar, no se pueden repetir elementos, se pueden modificar, se pueden añadir y quitar elementos.\n#Creación\nset = {1,2,3,4,5, 2, 3, 4, 5}\nprint(set)\n\n#Insercción\nset.add(6)\nset.add(2)\nprint(set)\n\n#Borrado\nset.remove(2)\n\n#Actualización\n#No se puede actualizar\n\n#Ordenación\n#No se puede ordenar\n\n### COLAS ###\n#Las colas son una estructura de datos usada para guardar variables. Permiten variables de distintos tipos de datos, mutables \n# y se pueden ordenar, no se pueden repetir elementos, se pueden modificar, se pueden añadir y quitar elementos.\n#Las cosas sirven para guardar datos en orden FIFO (First In First Out), es decir, el primero que entra es el primero que sale.\n\n#Creación\nprint(\"### COLAS ###\")\ncola = Queue()\n\n#Insercción\ncola.put(1)\ncola.put(2)\ncola.put(3)\n\niterator = cola.queue\n\nfor elemento in iterator:\n    print(elemento)\n\ncola.get()\n\nfor elemento in iterator:\n    print(elemento)\n#Borrado\ncola.get()\n\n#Actualización\n#No se puede actualizar\n\n#Ordenación\n#No se puede ordenar\n\n### PILAS ###\n#Las pilas son una estructura de datos usada para guardar variables. Permiten variables de distintos tipos de datos, mutables \n# y se pueden ordenar, no se pueden repetir elementos, se pueden modificar, se pueden añadir y quitar elementos.\n\n#Las pilas sirven para guardar datos en orden LIFO (Last In First Out), es decir, el último que entra es el primero que sale.\n\n#Creación\n\npila = []\n\n#Insercción\npila.append(1)\npila.append(2)\npila.append(3)\nprint(pila)\n\n#Borrado\npila.pop()\n\n#Visualización\nprint(pila)\n\n#Actualización\npila[0] = 0\n\nprint(pila)\n\n#Ordenación\npila.sort(reverse=True)\nprint(pila)\n\n### Arreglos (mediante NumPy) ###\n#Los arreglos son una estructura de datos usada para guardar variables. Permiten variables de distintos tipos de datos, mutables\n# y se pueden ordenar, no se pueden repetir elementos, se pueden modificar, se pueden añadir y quitar elementos.\n#Los arreglos sirven para guardar datos numéricos multidimensionales en arrays.\n\n### Arreglo de una dimensión ###\n#Creación\narray_1 = np.array([1,2,5,4,3])\n\n#Insercción\narray_1 = np.append(array_1, 6)\n\n#Borrado\narray_1 = np.delete(array_1, 0)\n\n#Actualización\narray_1[0] = 0\n\n#Ordenación\narray_1.sort()\n\nprint(f\"Arreglo de una dimensión: {array_1}\")\n\n### Arreglo de dos dimensiones ###\narray_2 = np.array([[5,4,3,2,1], [11,7,8,9,10]])\n\n#Insercción\narray_2 = np.append(array_2, [[6,12,13,14,15]], axis=0)\n\n#Actualización\narray_2[0][0] = 0\n\n#Ordenación\narray_2.sort()\n\nprint(f\"Arreglo de dos dimensiones: {array_2}\")\n\n#Borrado\narray_2 = np.delete(array_2, 0, axis=0)\n\nprint(f\"Arreglo de dos dimensiones: {array_2}\")\n\n### Existen arreglos de N dimensiones, por eso no los voy a representar todos ###\n#Funcionan de manera similar a los anteriores\n\ninput(\"Pulsa enter para continuar y entrar a la agenda...\")\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n\"\"\"\n\n\n### AGENDA DE CONTACTOS ### \n### Función para colorear los prints con Colorama ###\ndef titulo(texto):\n    print(Fore.CYAN + Back.WHITE + texto)\n    print()\n    \ndef texto(texto):\n    print(Fore.WHITE + Back.BLACK + texto)\n    \ndef error(texto):\n    print(Fore.WHITE + Back.RED + texto)\n    \ndef tabla(texto):\n    print(Fore.WHITE + Back.CYAN + texto)\n\ndef validacion(texto):\n    print(Fore.WHITE + Back.GREEN + texto)\n\ndef esperar(mensaje=\"Pulsa enter para continuar...\"):\n    texto(mensaje)\n    input()\n    \n\n\n#TODO: Pasar inputs a try catch \n#TODO: Meter colores/formato a la agenda. \nclass agenda:\n    def __init__(self):\n        self.agenda_nombres = {}\n        self.agenda_telefonos = {}\n\n    def comprobar_telefono(self, telefono):\n        if(isinstance(telefono, int) and telefono>99999999 and telefono<1000000000):  #Comprueba si el telefono es un telefono entre 100000000 y 999999999\n            if telefono in self.agenda_telefonos: \n                return False\n            else:\n                return True\n        else:\n            return None\n    \n    def comprobar_nombre(self, nombre):\n        if(isinstance(nombre, str) and len(nombre)>1): #Comprueba si el nombre es un string y el tamaño es mayor a 1. \n            if nombre in self.agenda_nombres:\n                return False\n            else:\n                return True\n        else:\n            return None\n    \n    def insertar_contacto(self, nombre, telefono):\n        if self.comprobar_telefono(telefono) and self.comprobar_nombre(nombre):\n            self.agenda_nombres[nombre] = telefono\n            self.agenda_telefonos[telefono] = nombre\n            return True \n        else:\n            return False\n              \n    def buscar_contacto_nombre(self,nombre):\n        if nombre in self.agenda_nombres:\n            return self.agenda_nombres[nombre]\n        else:\n            return None\n        \n    def buscar_contacto_telefono(self,telefono):\n        if telefono in self.agenda_telefonos:\n            return self.agenda_telefonos[telefono]\n        else:\n            return None\n        \n    def actualizar_contacto_nuevo_telefono(self, nombre, nuevo_telefono):\n        if nombre in self.agenda_nombres:\n            #La comprobación ahora es negada, porque ya existen en la agenda por tanto, si devuelve false,\n            #es que no existen en la agenda y además tienen el formato valido sino devolveria None\n            if not self.comprobar_nombre(nombre) and (isinstance(nuevo_telefono, int) and nuevo_telefono>99999999 and nuevo_telefono<1000000000):\n                self.eliminar_contacto_nombre(nombre)\n                self.agenda_nombres[nombre] = nuevo_telefono\n                self.agenda_telefonos[nuevo_telefono] = nombre\n            else:\n                return \"El contacto no se ha podido actualizar\"\n        else:\n            return None\n        \n    def actualizar_contacto_nuevo_nombre(self,nuevo_nombre, telefono):\n        if telefono in self.agenda_telefonos:\n            #La comprobación ahora es negada, porque ya existen en la agenda por tanto, si devuelve false,\n            #es que no existen en la agenda y además tienen el formato valido sino devolveria None\n            if not self.comprobar_telefono(telefono) and (isinstance(nuevo_nombre, str) and len(nuevo_nombre)>1):\n                self.eliminar_contacto_telefono(telefono)\n                self.agenda_nombres[nuevo_nombre] = telefono\n                self.agenda_telefonos[telefono] = nuevo_nombre\n            else:\n                return \"El contacto no se ha podido actualizar\"\n        else:\n            return None\n        \n    def eliminar_contacto_nombre(self,nombre):\n        if nombre in self.agenda_nombres:    \n            telefono = self.agenda_nombres[nombre]\n            del self.agenda_telefonos[telefono]\n            del self.agenda_nombres[nombre]\n        else:\n            return None\n        \n    def eliminar_contacto_telefono(self,telefono):\n        if telefono in self.agenda_telefonos:\n            nombre = self.agenda_telefonos[telefono]\n            del self.agenda_telefonos[telefono]\n            del self.agenda_nombres[nombre]\n        else:\n            return None\n\n    def clear_screen(self):\n        sys.stdout.write(\"\\033[2J\\033[1;1H\") #Limpia la pantalla\n\n    def print_menu(self):\n        self.clear_screen()\n        titulo(\"** Agenda de contactos **\")\n        texto(\"0. (M)ostrar agenda\")\n        texto(\"1. (I)nsertar contacto\")\n        texto(\"2. (B)uscar contacto\")\n        texto(\"3. (A)ctualizar contacto\")\n        texto(\"4. (E)liminar contacto\")\n        texto(\"5. (S)alir\")\n\n    def get_option(self):\n        while True:\n            option = input(\"Introduce la opción que deseas: \")\n            option = option.strip()\n            if option in [\"0\", \"1\", \"2\", \"3\", \"4\", \"5\", \"M\", \"m\", \"I\", \"i\", \"B\", \"b\", \"A\", \"a\", \"E\", \"e\", \"S\", \"s\"]:\n                return option\n            else:\n                error(\"Opción no válida.\")\n                esperar()\n                break\n                \n    def add_contact(self):\n        self.clear_screen()\n        titulo(\"1. (I)nsertar contacto\")\n        nombre = input(\"Introduce el nombre del contacto: \")\n        while True:\n            telefono = input(\"Introduce el número de teléfono del contacto: \")\n            if telefono.isdigit():\n                telefono = int(telefono)\n                break\n            else:\n                error(\"El número de teléfono no es válido.\")\n        if (self.insertar_contacto(nombre, telefono)):\n            mensaje = \"El contacto con el nombre \" + nombre + \" y teléfono \" + str(telefono) + \" ha sido insertado correctamente.\"\n            validacion(mensaje)\n        else:\n            error(\"El contacto no se ha podido insertar.\")\n        \n        esperar()\n\n    def search_contact(self):\n        self.clear_screen()\n        titulo(\"2. (B)uscar contacto\")\n        try:\n            contacto_a_buscar = input(\"Introduce el nombre o el teléfono del contacto que deseas buscar: \")\n            if contacto_a_buscar.isdigit():\n                contacto_a_buscar = int(contacto_a_buscar)\n            else: \n                contacto_a_buscar = str(contacto_a_buscar)\n        except ValueError:    \n            error(\"El contacto introducido no es un número.\")\n            \n        if(isinstance(contacto_a_buscar, int)):\n            resultado = self.buscar_contacto_telefono(contacto_a_buscar)\n            if resultado is None: \n                error(\"No se ha encontrado el contacto\")\n            else:\n                validacion(\"El contacto con el teléfono \" + str(contacto_a_buscar) + \" es \" + resultado)\n        elif(isinstance(contacto_a_buscar, str)):\n            resultado = self.buscar_contacto_nombre(contacto_a_buscar)\n            if resultado is None: \n                error(\"No se ha encontrado el contacto\")\n            else:\n                validacion(\"El contacto con el nombre \" + contacto_a_buscar + \" es \" + str(resultado))\n        esperar()\n        \n    def update_contact(self):\n        self.clear_screen()\n        titulo(\"3. (A)ctualizar contacto\")\n        texto(\"Para actualizar un contacto, puedes:\")\n        texto(\"1. Introducir un nombre existente y un número de teléfono nuevo.\")\n        texto(\"2. Introducir un número de teléfono existente y un nombre nuevo.\")\n        texto(\"El programa se encargará de actualizar el contacto automáticamente.\")\n        while True: \n            try:\n                nombre = input(\"Introduce el nombre del contacto: \")\n                break\n            except ValueError:\n                error(\"El nombre introducido no es válido.\")\n            \n        while True:\n            try:\n                telefono = int(input(\"Introduce el número de teléfono del contacto: \"))\n                break\n            except ValueError:\n                error(\"El número de teléfono introducido no es válido.\")\n                  \n        if nombre in self.agenda_nombres:\n            self.actualizar_contacto_nuevo_telefono(nombre, telefono)\n            validacion(\"El contacto con el nombre \" + nombre + \" ha sido actualizado correctamente.\")\n        elif telefono in self.agenda_telefonos:\n            self.actualizar_contacto_nuevo_nombre(nombre, telefono)\n            validacion(\"El contacto con el teléfono \" + str(telefono) + \" ha sido actualizado correctamente.\")\n        else:\n            error(\"El contacto con el nombre \" + nombre + \" y telefono \" + str(telefono) + \"no se encuentra en la agenda.\")\n        esperar()\n\n    def delete_contact(self):\n        self.clear_screen()\n        titulo(\"4. (E)liminar contacto\")\n        contacto_a_eliminar = input(\"Introduce el nombre o el número del contacto que deseas eliminar: \")\n        if contacto_a_eliminar.isdigit():\n            contacto_a_eliminar = int(contacto_a_eliminar)\n        else: \n            contacto_a_eliminar = str(contacto_a_eliminar)\n            \n        if contacto_a_eliminar in self.agenda_nombres: \n            self.eliminar_contacto_nombre(contacto_a_eliminar)\n        elif contacto_a_eliminar in self.agenda_telefonos: \n            self.eliminar_contacto_telefono(contacto_a_eliminar)\n        else:\n            error(\"No se ha encontrado el contacto\")\n        esperar()\n        \n    def mostrar_agenda(self):\n        self.clear_screen()\n        titulo(\"0. (M)ostrar agenda\")\n        texto(\"Nombre\\t\\tTeléfono\")\n        for nombre, telefono in self.agenda_nombres.items():\n            tabla(nombre + \"\\t\\t\" + str(telefono))\n        esperar()\n        \n    def ejecutor(self):\n\n        while True:\n            self.print_menu()\n            option = self.get_option()\n            if option == \"0\" or option == \"M\" or option == \"m\":               #0. (M)ostrar agenda\n                self.mostrar_agenda()\n            if option == \"1\" or option == \"I\" or option == \"i\":               #1. (I)nsertar contacto\n                self.add_contact()\n            elif option == \"2\" or option == \"B\" or option == \"b\":             #2. (B)uscar contacto\n                self.search_contact()\n            elif option == \"3\" or option == \"A\" or option == \"a\":             #3. (A)ctualizar contacto\n                self.update_contact()\n            elif option == \"4\" or option == \"E\" or option == \"e\":             #4. (E)liminar contacto\n                self.delete_contact()\n            elif option == \"5\" or option == \"S\" or option == \"s\":             #5. (S)alir\n                break\n\nif __name__ == \"__main__\":\n    agenda = agenda()\n    agenda.insertar_contacto(\"Uno\", 611111111)\n    agenda.insertar_contacto(\"Dos\", 611111112)\n    agenda.insertar_contacto(\"Tres\", 611111113)\n    agenda.insertar_contacto(\"Cuatro\", 611111114)\n    agenda.insertar_contacto(\"Cinco\", 611111115)\n    agenda.insertar_contacto(\"Seis\", 611111116)\n    agenda.insertar_contacto(\"Siete\", 611111117)\n\n    agenda.ejecutor()\n    \n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/pabloche73.py",
    "content": "# Estructuras de datos\r\n\r\n# Listas\r\n\r\nmi_lista = [1,2,2,3,4,2,5]\r\nprint(type(mi_lista))\r\nprint(mi_lista)\r\nprint(mi_lista.count(2)) # Cuenta cantidad de ocurrencias del valor que le pasemos\r\nmi_lista.append(11) # Agrega e imprime al final de la lista el valor que le pasemos\r\nprint(mi_lista)\r\nmi_lista.insert(0,0) # Agrega en el indice 0 el valor 0\r\nprint(mi_lista)\r\nvalor_eliminado =mi_lista.pop() #Elimina y devuelve por defecto el ultimo elemento de la lista\r\nprint(mi_lista)\r\nprint(f\"Se elimino el {valor_eliminado}\")\r\nmi_lista.sort() # Ordena la lista de menor a mayor por defecto\r\nmi_lista.remove(2) # Elimina la primer ocurrencia de un valor en la lista\r\nmi_lista[2] = 32 # Actualiza el valor del indice 2 a 32\r\nprint(mi_lista)\r\n\r\n# Tuplas\r\n\r\nmi_tupla = (1,2,3,4,5,4,1)\r\nprint(mi_tupla)\r\nlista = list(mi_tupla) # Para modificar una tupla primero debemos convertira en lista\r\nprint(lista)\r\nlista.pop()\r\nlista.append(8)\r\nlista[0]=10\r\nlista.insert(3,7)\r\nlista.sort()\r\nmi_tupla = tuple(lista) # Una vez realizadas las modificaciones convertimos la lista en tupla\r\nprint(mi_tupla)\r\n\r\n# Sets\r\n\r\nmi_set = {1,2,3,4} # Las tuplas no pueden repetir valores\r\nprint(mi_set)\r\nmi_set.add(1) # Al intentar agregar un valor existente no da error pero no se agrega\r\nprint(mi_set)\r\nmi_set.clear() # Elimina todo el contenido del set\r\nprint(mi_set)\r\nmi_set.add(1) # Agrega un valor al Set\r\nprint(mi_set)\r\nmi_set.add(2) # Agrega otro a continuacion\r\nprint(mi_set)\r\nmi_set.remove(1) # Elimina el elemento cuyo valor es 1\r\nprint(mi_set)\r\n\r\n\"\"\"\r\nPara ordenar un Set se procede como hicimos para ordenar una tupla, pasamos el set a lista, ordenamos y volvemos a convertir la lista a set\r\n\"\"\"\r\n\r\n# Diccionarios\r\n\r\nmi_dic = {\r\n    \"Nombre\": \"Pablo\",\r\n    \"Edad\": 51,\r\n    \"Pais\": \"Argentina\"\r\n}\r\n\r\nprint(mi_dic)\r\nmi_dic[\"Nombre\"] = \"Alberto\" # Actualiza un valor accediendo por su clave\r\nprint(mi_dic)\r\nmi_dic[\"Ciudad\"] = \"Madrid\" # Agrega una nueva clave y le da un valor\r\nprint(mi_dic)\r\nvalor_elim = mi_dic.pop(\"Ciudad\") # Elimina la clave Ciudad y almacena el valor en una clave\r\nprint(mi_dic)\r\nprint(f\"Valor eliminado: {valor_elim}\")\r\n\r\n# Extra! Extra! Agenda telefónica\r\n\r\nmi_agenda = {} # Este diccionario va a usar los nombres como clave\r\n\r\ndef verificar_telefono(phone): # Verifica que el telefono ingresado sea digito y tenga mas de 8 caracteres\r\n    es_digito = phone.isdigit()\r\n    long_valida = len(phone) > 8\r\n    return es_digito and long_valida\r\n\r\ndef contacto_existente(name): # Verifica que el contacto ingresado exista\r\n    existe = name in mi_agenda\r\n    return existe \r\n\r\ndef agregar_contacto(new_contact):\r\n    if contacto_existente(new_contact):\r\n        print(\"*********  El contacto ya existe  ***********\")\r\n    else:\r\n        b=True\r\n        while b:\r\n            telefono = input(\"Telefono: \")\r\n            if verificar_telefono(telefono):\r\n                mi_agenda[new_contact]=telefono\r\n                print(\"******  Contacto agregado con éxito  *******\")\r\n                b=False\r\n            else:\r\n                print(\"***********  Telefono no válido  ***********\")\r\n          \r\n\r\ndef eliminar_contacto(del_contact):\r\n    if contacto_existente(del_contact):\r\n        del mi_agenda[del_contact]\r\n        print(\"*************  Eliminado  *************\")    \r\n    else:\r\n        print(\"*******  El contacto no existe  ********\")\r\n\r\ndef buscar_contacto(search_contact):\r\n    if contacto_existente(search_contact):\r\n        print (f\"Encontrado, {search_contact}, Tel: {mi_agenda[search_contact]}\")\r\n    else:\r\n        print(\"*******  El contacto no existe  ********\")\r\n\r\ndef modificar_contacto(mod_contact):\r\n\r\n    if contacto_existente(mod_contact):\r\n        print (f\"Encontrado, {mod_contact}, Tel: {mi_agenda[mod_contact]}\")  \r\n        b=True\r\n        while b:\r\n            mod_phone = input(\"Ingrese nuevo telefono: \")\r\n            if verificar_telefono(mod_phone):\r\n                mi_agenda[mod_contact]=mod_phone\r\n                print(\"************  Actualizado **************\")\r\n                b=False\r\n            else:\r\n                print(\"***********  Telefono no válido  ***********\")\r\n    else:\r\n        print(\"*******  El contacto no existe  ********\")\r\n\r\ndef mostrar_todos():\r\n    if len(mi_agenda) > 0:\r\n        print(mi_agenda)\r\n    else:\r\n        print(\"********** No hay contactos ************\")\r\n    \r\ninicio = True\r\n\r\nwhile inicio:\r\n    print()\r\n    print()\r\n    print()\r\n    print(\"A   G   E   N   D   A\")\r\n\r\n    print(\"1.Agregar contacto\")\r\n    print(\"2.Eliminar contacto\")\r\n    print(\"3.Buscar contacto\")\r\n    print(\"4.Modificar telefono de contacto\")\r\n    print(\"5.Mostrar todos los contactos\")\r\n    print(\"6.Salir\")\r\n    print()\r\n    opcion = input(\"¿Qué desea hacer?: \")\r\n    print(\"________________________________\")\r\n    print()\r\n\r\n    match opcion:\r\n        case \"1\":           \r\n            nombre=input(\"Nombre a agregar: \")\r\n            agregar_contacto(nombre)\r\n        case \"2\":\r\n            nombre=input(\"Nombre a eliminar: \")\r\n            eliminar_contacto(nombre)\r\n        case \"3\":\r\n            nombre=input(\"Nombre a buscar: \")\r\n            buscar_contacto(nombre)\r\n        case \"4\":\r\n            nombre=input(\"Nombre a buscar: \")\r\n            modificar_contacto(nombre)\r\n        case \"5\":\r\n            mostrar_todos()\r\n        case \"6\":\r\n            inicio=False\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n      \r\n\r\n\r\n\r\n\r\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/pakiuh.py",
    "content": "'''\r\n/*\r\n * EJERCICIO:\r\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\r\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\r\n *\r\n '''\r\n\r\n#Ejemplos de creacion de Listas, Sets, Diccionario, Tuplas\r\n\r\nlist_hobits = [\"Frodo\", \"Bilbo\", \"Sam\", \"Pippin\", \"Frodo\"] #La diferencia con set o conjuntos es que pueden tener elementos duplicados\r\n\r\ntupla_posicion_monte_destino = (24, 36) #inmutalbe\r\n\r\ndiccionario_magia = {\r\n    \"nombre_mago\" : \"Gandalf\",\r\n    \"poderes\" : [\"fuego_destino\", \"luz_poder\"]\r\n}\r\n\r\nset_armas = {\"espada\", \"lanza\", \"pistola\", \"escopeta\"}\r\nprint(list_hobits)\r\nprint(tupla_posicion_monte_destino)\r\nprint(diccionario_magia)\r\nprint(set_armas)\r\n\r\n#Inserción en cada lista\r\nlist_hobits.append(\"Elrond\")\r\n#Las tuplas no se pueden añadir\r\ndiccionario_magia[\"Edad\"] = 5600000\r\nset_armas.add(\"lanzallamas\") \r\nprint(list_hobits)\r\nprint(tupla_posicion_monte_destino)\r\nprint(diccionario_magia)\r\nprint(set_armas)\r\n\r\n#Borrado\r\n'''\r\nlist_hobits.pop(5)\r\ndiccionario_magia.pop(\"Edad\")\r\ndel diccionario_magia[\"nombre_mago\"]\r\ndiccionario_magia.popitem()\r\n\r\nset_armas.remove(\"lanzallamas\")\r\nprint(list_hobits)\r\nprint(tupla_posicion_monte_destino)\r\nprint(diccionario_magia)\r\nprint(set_armas)\r\n'''\r\n\r\n#Actualización\r\nlist_hobits[0] = \"Sam\"\r\ndiccionario_magia[\"Edad\"] = 10 #Ojo las claves no se pueden modificar\r\nset_armas #Los sets tampoco pueden modificarse\r\nprint(list_hobits)\r\nprint(tupla_posicion_monte_destino)\r\nprint(diccionario_magia)\r\nprint(set_armas)\r\n\r\n#Ordenación\r\nlist_hobits.sort()\r\n\r\n'''\r\n* DIFICULTAD EXTRA (opcional):\r\n * Crea una agenda de contactos por terminal.\r\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\r\n * - Cada contacto debe tener un nombre y un número de teléfono.\r\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\r\n *   los datos necesarios para llevarla a cabo.\r\n * - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\r\n *   (o el número de dígitos que quieras)\r\n * - También se debe proponer una operación de finalización del programa.\r\n */\r\n'''\r\n#Creamos diccionario ejemplo\r\ncontacto_agenda = {\"nombre\": \"Paco\",\r\n                   \"Telefono\": \"664770496\"}\r\ncontactos = [\r\n    {\"nombre\": \"Paco\",\r\n     \"Telefono\": \"664770496\"},\r\n     {\"nombre\": \"Lidia\",\r\n      \"Telefono\":\"626899639\"}\r\n]\r\nprint(contactos)\r\n\r\n# Definimos funciones.\r\ndef es_telefono_valido(telefono):#para verificar que son números y menos de 11 dígitos\r\n    return telefono.isdigit() and len(telefono)<=11\r\n\r\ndef añadir():\r\n    nombre = input(\"Dime el nombre de la persona que quieres añadir:\")\r\n    telefono = input(\"Teléfono: \")\r\n    if es_telefono_valido(telefono):\r\n        print(\"Telefono valido\")\r\n    else:\r\n        input(\"Número de teléfono inválido. Sólo números y máximo 11 dígitos: \")\r\n    \r\n\r\n    contactos.append(\r\n        {\"nombre\": nombre,\r\n         \"Teléfono\": telefono}\r\n    )\r\n\r\ndef buscar():\r\n    nombre_buscado = input(\"Dime el nombre de la persona que quieres buscar: \")\r\n    for contacto in contactos:\r\n        if contacto[\"nombre\"] == nombre_buscado:\r\n            print(f\"El teléfono de {contacto[\"nombre\"]} es {contacto[\"Telefono\"]}\")\r\n\r\ndef actualizar():\r\n    nombre_buscado = input(\"Dime el nombre de la persona que quieres actualizar: \")\r\n    for contacto in contactos:\r\n        if contacto[\"nombre\"] == nombre_buscado:\r\n            campo_actualizar = input(f\"Escribe 1 si quieres actualizar el nombre: {contacto[\"nombre\"]}\\nEscribe 2 si quieres actualizar el teléfono: {contacto[\"Telefono\"]}\\n? \")\r\n            if campo_actualizar == \"1\":\r\n                nombre_nuevo = input(\"Introduce el nuevo nombre: \")\r\n                contacto[\"nombre\"] = nombre_nuevo\r\n            elif campo_actualizar == \"2\":\r\n                telefono_nuevo = input(\"Introduce el nuevo número de teléfono: \")\r\n                contacto[\"Telefono\"] = telefono_nuevo\r\n    menu_principal()\r\n\r\ndef eliminar():\r\n    nombre_buscado = input(\"Dime el nombre de la persona que quieres eliminar: \")\r\n    for contacto in contactos:\r\n        if contacto[\"nombre\"] == nombre_buscado:\r\n            confirmar_eliminacion = input(f\"Estas seguro quer quieres eliminar los datos de:  {contacto[\"nombre\"]} Telefono:  {contacto[\"Telefono\"]}(S/N)?: \")\r\n            if confirmar_eliminacion == \"S\":\r\n                contactos.remove(contacto)\r\n            else:\r\n                print(\"Ok no lo eliminamos\")\r\n                menu_principal()\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n# Menú de seleccionar acción:\r\ndef menu_principal():\r\n    print(\"Escoge la acción que quieres hacer en tu agenda?\")\r\n    print(\"1 búsqueda contacto\")\r\n    print(\"2 añadir contacto\")\r\n    print(\"3 actualizar contacto\")\r\n    print(\"4 eliminar contacto\")\r\n    accion_menu = input()\r\n    if accion_menu == \"1\":\r\n        buscar()\r\n    elif accion_menu == \"2\":\r\n        añadir()\r\n    elif accion_menu == \"3\":\r\n        actualizar()\r\n    elif accion_menu == \"4\":\r\n        eliminar()\r\n    \r\n    print(contactos)\r\n\r\nmenu_principal()\r\nprint(contactos)"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/pedro-blasco.py",
    "content": "\"\"\"\nEJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto\n *   en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n\"\"\"\n# Listas\nlista = [1, 2, 3, 4, 5]  # Creación de una lista, sus valores pueden modificarse y puede contener cualquier tipo de dato\nprint(lista)  # Imprime la lista completa\n\n# Tuplas\ntupla = (1, 2, 3, 4, 5) # Creación de una tupla, sus valores no pueden modificarse y puede contener cualquier tipo de dato\nprint(tupla)  # Imprime la tupla completa\n\n# Diccionarios\ndiccionario = {\n    \"nombre\": \"Pedro\", \n    \"edad\": 19, \n    \"nacionalidad\": \"Argentino\"} \n# Creación de un diccionario, sus valores pueden modificarse y se accede a ellos mediante claves\nprint(diccionario)  # Imprime el diccionario completo\nprint(diccionario[\"nombre\"])  # Imprime el valor asociado a la clave \"nombre\"\nprint(diccionario[\"edad\"])  # Imprime el valor asociado a la clave \"edad\"\nprint(diccionario[\"nacionalidad\"])  # Imprime el valor asociado a la clave \"nacionalidad\"\n\n# Conjuntos\nconjunto = {1, 2, 3, 4, 5} # Creación de un conjunto, sus valores pueden modificarse pero no se pueden repetir y puede contener cualquier tipo de dato, es lo mismo que una lista pero sin orden y sin elementos repetidos\nprint(conjunto)  # Imprime el conjunto completo\n\n# Operaciones de inserción, borrado, actualización y ordenación\n# Inserción y actualización, ya que en Python no existe una operación de inserción específica para los diccionarios, se utiliza la asignación para insertar o actualizar un valor asociado a una clave\n\nlista.append(6)  # Inserta el número 6 al final de la lista\nprint(lista)  # Imprime la lista después de la inserción\n\ndiccionario[\"profesion\"] = \"Programador\"  # Inserta una nueva clave \"profesion\" con el valor \"Programador\" en el diccionario\nprint(diccionario)  # Imprime el diccionario después de la inserción\n\ndiccionario[\"edad\"] = 20 # Actualiza el valor de la clave \"edad\" a 20 en el diccionario\nprint(diccionario) # Imprime el diccionario después de la actualización\n\nconjunto.add(6) # Inserta el número 6 en el conjunto\nprint(conjunto) # Imprime el conjunto después de la inserción\n\n# Borrado\nlista.remove(3)  # Elimina el número 3 de la lista, si no existe genera un error\nprint(lista)  # Imprime la lista después del borrado\n\ndel diccionario[\"edad\"]  # Elimina la clave \"edad\" y su valor del diccionario\nprint(diccionario)  # Imprime el diccionario después del borrado\n\nconjunto.remove(3) # Elimina el número 3 del conjunto, si no existe genera un error\nprint(conjunto) # Imprime el conjunto después del borrado\n\n# Ordenación\nlista = [5, 2, 9, 1, 3]  # Creación de una lista desordenada\nprint(\"Lista origninal:\", lista)  # Imprime la lista original antes de la ordenación\nlista.sort()  # Ordena la lista de menor a mayor\nprint(lista)  # Imprime la lista después de la ordenación\n\nlista.sort(reverse=True)  # Ordena la lista de mayor a menor, el parámetro reverse=True indica que se debe ordenar en orden inverso\nprint(lista)  # Imprime la lista después de la ordenación\n\nlista.sort(key=lambda x: x % 2)  # Ordena la lista colocando primero los números pares y luego los impares, el parámetro key=lambda x: x % 2 indica que se debe ordenar según el resultado de la función lambda, que devuelve 0 para los números pares y 1 para los números impares\nprint(lista)  # Imprime la lista después de la ordenación\n\n#lambda es una función anónima, es decir, una función sin nombre que se define en una sola línea de código, se utiliza para crear funciones pequeñas y simples que se pueden pasar como argumentos a otras funciones, como en este caso a la función sort() para indicar el criterio de ordenación. Parece complicado pero es muy útil para evitar tener que definir una función completa solo para un criterio de ordenación específico.\n\nlista.sort(key=lambda x: x % 2, reverse=True)  # Ordena la lista colocando primero los números impares y luego los pares, el parámetro key=lambda x: x % 2 indica que se debe ordenar según el resultado de la función lambda, que devuelve 0 para los números pares y 1 para los números impares, el parámetro reverse=True indica que se debe ordenar en orden inverso\nprint(lista)  # Imprime la lista después de la ordenación\n\n# Ordenación de un diccionario por sus claves\ndiccionario = {\"b\": 2, \"a\": 1, \"c\": 3}  # Creación de un diccionario desordenado\nprint(\"Diccionario original:\", diccionario)  # Imprime el diccionario original antes de la ordenación\ndiccionario_ordenado = dict(sorted(diccionario.items())) # Ordena el diccionario por sus claves, el método sorted() devuelve una lista de tuplas ordenada por las claves, luego se convierte de nuevo a un diccionario con la función dict()\n#sorted() es una función que ordena cualquier iterable, como listas, tuplas o diccionarios, y devuelve una nueva lista ordenada. En este caso, se utiliza para ordenar las tuplas devueltas por el método items() del diccionario, que contiene las claves y valores del diccionario. Al ordenar estas tuplas, se ordena el diccionario por sus claves.\n#dict() es una función que convierte una lista de tuplas en un diccionario, donde cada tupla debe contener exactamente dos elementos, el primero se convierte en la clave y el segundo en el valor del diccionario. En este caso, se utiliza para convertir la lista de tuplas ordenada por las claves de nuevo a un diccionario.\nprint(diccionario_ordenado)  # Imprime el diccionario después de la ordenación por claves\n\n# Ordenación de un diccionario por sus valores\ndiccionario_ordenado_por_valores = dict(sorted(diccionario.items(), key=lambda item: item [1])) # Ordena el diccionario por sus valores, el parámetro key=lambda item: item[1] indica que se debe ordenar según el segundo elemento de cada tupla, que corresponde al valor del diccionario, si fuera item[0] se ordenaría por las claves, haciendo lo mismo que en el ejemplo anterior\nprint(diccionario_ordenado_por_valores)  # Imprime el diccionario después de la ordenación por valores\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\"\"\"\nagenda = {}  # Creación de un diccionario vacío para almacenar los contactos\n\ndef mostrar_menu():\n    print(\"1. Agregar contacto nuevo\")\n    print(\"2. Buscar contacto\")\n    print(\"3. Actualizar contacto\")\n    print(\"4. Eliminar contacto\")\n    print(\"5. Mostrar todos los contactos\")\n    print(\"6. Salir\")\n\ndef agregar_contacto():\n    nombre = input(\"Ingrese el nombre del contacto: \")\n    telefono = input(\"Ingrese el número de teléfono del contacto: \")\n    if not telefono.isdigit() or len(telefono) > 11: # Verifica que el número de teléfono sea numérico  y no tenga más de 11 dígitos\n        print(\"Número de teléfono no válido. Debe ser numérico y tener como máximo 11 dígitos.\")\n        return\n    if nombre in agenda:\n        print(f\"Contacto '{nombre}' ya existe en la agenda. Use la opción de actualización para modificarlo.\")\n        return\n    if telefono in agenda.values():\n        print(f\"El número de teléfono '{telefono}' ya está asociado a otro contacto en la agenda. Use la opción de actualización para modificarlo.\") \n        return\n    else:\n        agenda[nombre] = telefono # Agrega la clave nombre con el valor telefono al diccionario agenda\n        print(f\"Contacto '{nombre}' agregado exitosamente.\")\n    input(\"Presione Enter para continuar...\") # Pausa el programa para que el usuario pueda leer el mensaje antes de volver al menú\n\ndef buscar_contacto():\n    nombre = input(\"Ingrese el nombre del contacto a buscar: \")\n    if nombre in agenda: # Verifica que el nombre introducido existe en el diccionario agenda\n        print(f\"El número de teléfono de '{nombre}' es: {agenda[nombre]}\") # Imprime el número de teléfono asociado a la clave nombre\n    else:\n        print(f\"Contacto '{nombre}' no se ha encontrado en la agenda.\")\n    input(\"Presione Enter para continuar...\") # Pausa el programa para que el usuario pueda leer el mensaje antes de volver al menú\n\ndef actualizar_contacto():\n    print(\"1. Actualizar nombre del contacto\")\n    print(\"2. Actualizar número de teléfono del contacto\")\n    opcion = input(\"Seleccione la opción: \")\n    if opcion == \"1\":\n        nombre_actual = input(\"Ingrese el nombre actual del contacto: \")\n        if nombre_actual in agenda: # Verifica que el nombre actual existe en el diccionario agenda\n            nuevo_nombre = input(\"Ingrese el nuevo nombre del contacto: \")\n            agenda[nuevo_nombre] = agenda.pop(nombre_actual) # Reemplaza el nombre actual con el nuevo nombre, utilizando el método pop() para eliminar la clave nombre_actual y obtener su valor, que se asigna a la nueva clave nuevo_nombre\n            print(f\"Nombre del contacto actualizado de '{nombre_actual}' a '{nuevo_nombre}'.\")\n        else: \n            print(f\"Contacto '{nombre_actual}' no se ha encontrado en la agenda.\")\n    elif opcion == \"2\":\n        nombre = input(\"Ingrese el nombre del contacto: \")\n        if nombre in agenda:\n            nuevo_telefono = input(\"Ingrese el nuevo número de telefono del contacto: \")\n            if not nuevo_telefono.isdigit() or len(nuevo_telefono) > 11: # Verifica que sea un digito numero y no sobrepase los 11 dígitos\n                print(\"Número de teléfono no válido. Debe ser numérico y tener como máximo 11 dígitos.\")\n                input(\"Presione Enter para continuar...\") # Pausa el programa para que el usuario pueda leer el mensaje antes de volver al menú\n                return\n            if nuevo_telefono in agenda.values():\n                print(f\"El número de teléfono '{nuevo_telefono}' ya está asociado a otro contacto en la agenda.\") \n                input(\"Presione Enter para continuar...\") # Pausa el programa para que el usuario pueda leer el mensaje antes de volver al menú\n                return\n            else:\n                agenda[nombre] = nuevo_telefono # Actualiza el numero asociado al nombre del contacto\n                print(f\"Número de teléfono del contacto '{nombre}' actualizado exitosamente.\")\n        else:\n            print(f\"Contacto '{nombre}' no se ha encontrado en la agenda.\")\n    else:\n        print(\"Opción no válida.\")\n    input(\"Presione Enter para continuar...\") # Pausa el programa para que el usuario pueda leer el mensaje antes de volver al menú\n        \ndef eliminar_contacto():\n    nombre = input(\"Ingrese el nombre del contacto que desea eliminar: \")\n    if nombre in agenda: # Verifica que el nombre introducido existe en el diccionario agenda\n        del agenda[nombre] # Elimina la clave nombre y su valor asociado del diccionario agenda\n        print(f\"Contacto '{nombre}' eliminado exitosamente.\")\n    else:\n        print(f\"Contacto '{nombre}' no se ha encontrado en la agenda.\")\n    input(\"Presione Enter para continuar...\") # Pausa el programa para que el usuario pueda leer el mensaje antes de volver al menú\n    \ndef mostrar_contactos():\n    if agenda:\n        print(\"Contactos en la agenda:\")\n        for nombre, telefono in agenda.items(): # Itera sobre las claves y valores del diccionario agenda utilizando el método items()\n            print(f\"Nombre: {nombre}, Teléfono: {telefono}\") # Imprime el nombre y el número de teléfono de cada contacto\n    else:\n        print(\"La agenda está vacía.\")\n    \n    input(\"Presione Enter para continuar...\") # Pausa el programa para que el usuario pueda leer el mensaje antes de volver al menú\n\nwhile True:\n    mostrar_menu() # Muestra el menú de opciones al usuario\n    opcion = input(\"Seleccione una opción: \") # Solicita al usuario que seleccione una opción del menú\n    if opcion == \"1\":\n        agregar_contacto() # Llama a la función para agregar un nuevo contacto\n    elif opcion == \"2\":\n        buscar_contacto() # Llama a la función para buscar un contacto por su nombre\n    elif opcion == \"3\":\n        actualizar_contacto() # Llama a la función para actualizar el nombre o el número de teléfono de un contacto existente\n    elif opcion == \"4\":\n        eliminar_contacto() # Llama a la función para eliminar un contacto por su nombre\n    elif opcion == \"5\":\n        mostrar_contactos() # Llama a la función para mostrar todos los contactos en la agenda\n    elif opcion == \"6\":\n        print(\"Saliendo del programa. ¡Hasta luego!\") # Imprime un mensaje de despedida antes de salir del programa\n        break # Termina el bucle y finaliza el programa\n    else:\n        print(\"Opción no válida. Por favor, seleccione una opción del 1 al 6.\")\n        \n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/pguillo02.py",
    "content": "#Python es un lenguaje con una amplia gama de estructuras de datos.\n\n#Listas, son mutables y aceptan datos de cualquier tipo mezclados, están indexados y no poseen un tamañó fijo\n\nlista = [1,  True, \"hola\"]\n\nprint(lista[0])\n\nlista.append(2)\n\nprint(lista)\n\nlista.pop(3)\n\nprint(lista)\n\nlista.remove(\"hola\")\nprint(lista)\n\nlista.sort()\nprint(lista)\n\n#Tuplas, son estructuras inmutables que no se pueden modificar una vez declaradas. Permiten mezclar datos de distinto tipo\n\ntupla = (1,2,\"hola\")\nprint(tupla)\n\nprint(tupla.count(1))\n\nprint(tupla[1])\n\n#Sets, son estructuras mutables y dinámicas que admiten distintos tipos de elemento. Su particularidad es que no están indexadas\n#ni permiten duplicados. Lo que los hace útiles para ciertos programas.\n\nsets = {1,2,3,4}\n\nsets.add(\"hola\")\nsets.add(\"hola\")\n\nprint(sets)\n\nsets.remove(3)\n\nprint(sets)\n\n#Diccionarios, estructuras dinámicas y mutables, aceptan todo tipo de datos y trabajan en parejas clave:valor \n\ndiccionario = {1:\"fasd\", 2: 3, 3:\"adfad\"}\n\ndiccionario.pop(1)\n\nprint(diccionario)\n\ndiccionario[5]=\"fsdfaf\"\n\nprint(diccionario)\n\n#OPCIONAL\nagenda = {}\n\ndef interaccion_agenda():\n    print(\"Qué desea hacer\")\n    operacion =int(input(\"Añadir(1), Eliminar(2), Modificar(3), Buscar(4), Parar(5): \"))\n\n    if operacion == 1:\n        nombre = input(\"Nombre del contacto: \")\n        try:\n            numero = int(input(\"Número: \"))\n\n            if len(str(numero))>9:\n                print(\"El número no puede tener más de 9 dígitos\")\n                interaccion_agenda()\n\n        except ValueError:\n            print(\"Tiene que ser un número\")\n            interaccion_agenda()\n\n        agenda[nombre] = numero\n\n        interaccion_agenda()\n    \n    elif operacion == 2:\n        nombre = input(\"Nombre que desea eliminar: \")\n        try:\n            agenda.pop(nombre)\n        except:\n            print(\"El contacto no está en la agenda\")\n            interaccion_agenda()\n            \n        interaccion_agenda()\n\n    elif operacion == 3:\n        nombre = input(\"Nombre del contacto a modificar: \")\n        try:\n            nuevo_numero = int(input(\"Nuevo número: \"))\n\n            if len(str(nuevo_numero))>9:\n                print(\"El número no puede tener más de 9 dígitos\")\n                interaccion_agenda()\n\n        except ValueError:\n            print(\"Tiene que ser un número\")\n            interaccion_agenda()\n\n        agenda[nombre] = nuevo_numero\n\n        interaccion_agenda()\n    \n    elif operacion == 4:\n        nombre = input(\"Nombre del contacto a buscar: \")\n\n        try:\n            print(agenda[nombre])\n        except KeyError:\n            print(\"Contacto no existente\")\n            interaccion_agenda()\n\n        interaccion_agenda()\n\n    elif operacion == 5:\n        return 0 \n\ninteraccion_agenda()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/pipngpop.py",
    "content": "\"\"\"\nESTRUCTURAS DE DATOS\n\"\"\"\n\n# Listas -> para guardr varios datos de forma ordenada\nmy_list = [\"Hosi\", \"Loli\", \"Paca\"]\nprint(my_list)\nmy_list.append(\"Jacobo\") #para INSERTAR elementos a la lista\nprint(my_list)\nmy_list.remove(\"Paca\") #para ELIMINAR elementos de la lista\nprint(my_list)\nprint(my_list[1]) #para ACCEDER a la posición 1 \nmy_list[1]=\"Cosini\" #para ACTUALIZAR la posición 1\nprint(my_list)\nmy_list.sort() #para ORDENAR\nprint(my_list)\n\n#Tuplas -> estructuras inmutables donde guardar datos\nmy_tuple = (\"Hosi\", \"Eloso\", \"20\") # el 20 podría ser int pero con el SORTED nos daría problemas\nprint(my_tuple[1]) #solo puedo hacer operaciones de ACCESO\n#si aplicaramos sorted a la tupla, nos devolverá una lista\n#para evitar eso haremos:\nmy_tuple=tuple(sorted(my_tuple))\nprint (my_tuple)\n\n#Sets -> NO se puede ORDENAR\nmy_set = {\"Hosi\", \"Eloso\", \"20\"}\nprint(my_set)\nmy_set.add(\"hosi@gmail.com\") #no puedo añadir 2 veces lo mismo. los sets evitan DUPLICADOS\nprint(my_set)\nmy_set.remove(\"Eloso\") #para eliminar elementos\nprint(my_set)\n#sorted(my_set) #si aplicamos esto nos devolvería una LISTA\nprint(type(my_set)) \n\n# Diccionario\nmy_dict: dict = {\n    \"Nombre\":\"Hosi\",\n    \"Apellido\":\"Eloso\",\n    \"Edad\":\"20\",\n    \"Email\":\"hosi@gmail.com\"\n} #asociamos una clave a cada valor\nprint(my_dict[\"Apellido\"]) #para ACCEDER a un elemento\nmy_dict[\"Email\"] = \"Hosi@gmail.com\" # para AÑADIR un elemento al diccionario\nprint(my_dict)\nmy_dict[\"Edad\"] = \"21\" #para ACTUALIZAR elementos\nprint(my_dict)\ndel my_dict[\"Email\"] #para ELIMINAR un elemento del diccionario\nprint(my_dict)\nmy_dict = dict(sorted(my_dict.items())) # para ORDENAR\nprint(my_dict)\n\n\n'''\nExtra\n'''\n'''\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n *   y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n *   y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no numéricos y con más\n *   de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.\n'''\n\nmi_agenda: dict = {\n    \"Hosi\":123456789,\n    \"Loli\":789456123,\n    \"Paca\":456789123,\n    \"Jacobo\":123789456\n}\n\nprint(\"Tu agenda actual es:\")\nprint(mi_agenda)\nacabar=\"y\"\nwhile acabar==\"y\":\n    print(\"Tienes las siguientes opciones:\")\n    print(\"1: Añadir un número\")\n    print(\"2: Editar un número\")\n    print(\"3: Eliminar un número\")\n    opc=input(\"Elige una opción: \")\n    opc=int(opc)\n\n    if opc == 1:\n        i=0\n        new_name=input(\"Introduce el nombre del nuevo contacto: \")\n        while i < 1:\n            new_num=input(\"Introduce el nuevo número: \") \n            digitos_num=len(new_num)\n            new_num=int(new_num)\n            if type(new_num)!=int or digitos_num>11:\n                print(\"Introduce un número válido\")\n            else:\n                mi_agenda[new_name] = new_num\n                i+=1\n    elif opc == 2:\n        act_nombre=input(\"Introduce el nombre del contacto que se quiere actualizar: \")\n        new_num=input(\"Introduce el nuevo número: \")\n        new_num=int(new_num)\n        mi_agenda[act_nombre]=new_num \n    elif opc == 3:\n        bor_nombre=input(\"Introduce el nombre del contacto a eliminar\")\n        del mi_agenda[bor_nombre]\n\n    print(\"Ahora tu agenda es la siguiente:\")\n    print(mi_agenda)\n    acabar=input(\"Quieres hacer algo más? [y/n]: \")\n\nprint(\"Fin\")\n\n'''\nSU SOLUCIÓN:\ndef my_agenda():\n\n    agenda = {}\n\n    def insert_contact():\n        phone = input(\"Introduce el teléfono del contacto: \")\n        if phone.isdigit() and len(phone) > 0 and len(phone) <= 11:\n            agenda[name] = phone\n        else:\n            print(\n                \"Debes introducir un número de teléfono un máximo de 11 dígitos.\")\n\n    while True:\n\n        print(\"\")\n        print(\"1. Buscar contacto\")\n        print(\"2. Insertar contacto\")\n        print(\"3. Actualizar contacto\")\n        print(\"4. Eliminar contacto\")\n        print(\"5. Salir\")\n\n        option = input(\"\\nSelecciona una opción: \")\n\n        match option:\n            case \"1\":\n                name = input(\"Introduce el nombre del contacto a buscar: \")\n                if name in agenda:\n                    print(\n                        f\"El número de teléfono de {name} es {agenda[name]}.\")\n                else:\n                    print(f\"El contacto {name} no existe.\")\n            case \"2\":\n                name = input(\"Introduce el nombre del contacto: \")\n                insert_contact()\n            case \"3\":\n                name = input(\"Introduce el nombre del contacto a actualizar: \")\n                if name in agenda:\n                    insert_contact()\n                else:\n                    print(f\"El contacto {name} no existe.\")\n            case \"4\":\n                name = input(\"Introduce el nombre del contacto a a eliminar: \")\n                if name in agenda:\n                    del agenda[name]\n                else:\n                    print(f\"El contacto {name} no existe.\")\n            case \"5\":\n                print(\"Saliendo de la agenda.\")\n                break\n            case _:\n                print(\"Opción no válida. Elige una opción del 1 al 5.\")\n\n\nmy_agenda()\n\n\n\n'''\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/pirrin22.py",
    "content": "'''\nEstructuras de datos\n'''\n\n# Listas.\n\nmy_list = ['Pirrin', 'Python', 36, 7.5] # lista origen\nprint(my_list)\n\nmy_list.append('Apple')  # Lista con un elemento añadido al final de la lista\nprint(my_list)\n\nmy_list.remove('Python') # Lista con un elemento eliminado mediante nombre valor\nprint(my_list)\n\nmy_list[0] = 'PirrinDev' # modificacion de elemento mediante indice\nprint(my_list)\n\nif 'PirrinDev' in my_list: # Comprovacion de pertenencia de un elemento\n    print('Si, PirrinDev esta en lista')\n\nmy_other_list = [4 , 16, 'Ford']\n\nmy_list.extend(my_other_list) # Agregar una lista a otra\nprint(my_list)\n\nmy_integer_list = [5, 16, 24, 98, 4, 12] \n\nmy_integer_list.sort() # Ordenar lista de menor a mayor o en orden alfabetico de la A -> z\nprint(my_integer_list)\n\nmy_integer_list.sort(reverse=True) # Ordenar lista de mayor a menor o en orden alfabetico de la z -> A\nprint(my_integer_list)\n\nmy_list.clear() # Vaciar una lista\nprint(my_list)\n\ndel my_list # Eliminar una lista por completo\n\n\n\n# Tuplas\n\n'''\nLas tuplas son inmutables, no habra ningun ejemplo con funcion de insercion.\n'''\n\nmy_tuple = (4, 16 ,200, 84) \n\n\nif 16 in my_tuple: # Comprovacion de pertenencia de un elemento\n    print('Si, 16 esta en la tupla')\n\nprint(len(my_tuple)) # Revision de cuantos elementos tiene la Tupla\n\nsorted_my_tuple = sorted(my_tuple) # Ordenacion de los elementos de la Tupla.\nprint(sorted_my_tuple)\n\nprint(my_tuple.count(16)) # Revision de cuantos elementos del numero '16' hay en la tupla\n\nprint(my_tuple.index(200)) # Comprovacion de en que posicion de indice esta el numero '200'\n\nmin_my_tuple = min(my_tuple) # Comprovacion del numero menor de la Tupla\nprint(min_my_tuple)\n\nmax_my_tuple = max(my_tuple) # Comprovacion del numero mayor de la Tupla\nprint(max_my_tuple)\n\ndel my_tuple # Eliminar una tupla\n#print(my_tuple)\n\n\n\n# Sets\n\n'''\nLos sets son estructuras desordenadas, por eso nunca se imprimiran en el mismo orden.\nEn el momento de eliminar deberemos hacerlo por elemento y no por indice.\n'''\n\nmy_set = {4, 6, 12, 3, 45}\n\nif 12 in my_set: # Comprovacion de pertenencia\n    print('Si, 12 esta en el set')\n\nmy_set.add('Pirrin') # Añadir un elemento al Set\nprint(my_set)\n\nmy_set.update([10, 300]) # Añadir varios elementos al Set\nprint(my_set)\n\nmy_set.remove(10) # Eliminar un elemento (En el caso de la funcion 'remove()' nos dara un error en el caso que no este el elemnto).\nprint(my_set)\n\nmy_set.discard('Pirrin') # Eliminar un elemento (En el caso de la funcion 'discard()' no salta ningun error en el caso de que no este el elemento).\nprint(my_set)\n\nprint(my_set.pop()) # La funcion 'pop()'  elimina un elemento aleatiorio y te lo muestra. \n\nmy_set.clear() # Vaciar el Set.\nprint(my_set)\n\nmy_set_impares = {1, 3, 5, 7, 9}\nmy_set_primos = {1, 2, 3, 5, 7, 9}\n\nmy_union_sets = my_set_impares.union(my_set_primos) # Union de los dos sets, no permite duplicados.\nprint(my_union_sets)\n\nmy_intersection_sets = my_set_impares.intersection(my_set_primos) # La funcion 'intersection()' nos da los numeros repetidos de cada set que le pidamos.\nprint(my_intersection_sets)\n\nmy_diferencia_sets = my_set_primos.difference(my_set_impares) # La funcion 'difference()' te muestra la diferencia entere los dos sets.\nprint(my_diferencia_sets)\n\n\n\n# Diccionarios\n\nmy_dict = {\n    'Marca' : 'Seat',\n    'Modelo' : 'Leon',\n    'Año' : 2016\n}\n\nmy_dict['City'] = 'New York' # Operacion de insercion poniendo la clave entre corchetes y el valor despues del igual.\nprint(my_dict)\n\nmy_dict['Año'] = 2022 # Operacion para cambiar un valor de los que ya tenemos en el diccionario.\nprint(my_dict)\n\nmy_dict.update({'CP' : 10018, 'Pneumaticos' : 'Michelin'}) # Operacion para añadir varios elementos.\nprint(my_dict)\n\nmy_dict.setdefault('Cambio', 'Automatico') # Operacion para insertar una clave valor que no exista en el diccionario.\nprint(my_dict)\n\nprint(my_dict.pop('Año')) # Operacion de borrado de un elemento del diccionario\nmy_dict.pop('CP')\nprint(my_dict)\n\n\nsorted_my_dict = dict(sorted(my_dict.items())) # Operacion de ordenado del diccionario\nprint(sorted_my_dict)\n\n\n\n# Ejercicio dificultad extra.\n\n\n\ndef agenda():\n\n    my_agenda = {}\n\n    def comprovacion():\n        numero = input(f'Inserta el numero de telefono: ')\n        if numero.isdigit() and len(numero) > 0 and len(numero) <= 11:\n            my_agenda[nombre] = numero\n            print(f'El contacto {nombre} se guardo.')\n        else:\n            print('El numero debe contener como maximo 11 digitos.')\n    \n    \n    while True:\n\n        print('')\n        print('1. Buscar un contacto')\n        print('2. Insertar un contacto')    \n        print('3. Actulizar un contacto')\n        print('4. Eliminar un contacto')\n        print('5. Salir')\n        \n        option = input('Selecciona una opcion: ')\n\n        match option:\n            case '1':\n                nombre = input('Introduce el nombre a busar: ')\n                if nombre in my_agenda:\n                    print(f'El numero de {nombre} es {my_agenda[nombre]}')\n                else:\n                    print(f'El contacto {nombre} no exsiste')\n            case '2':\n                nombre = input('Inserta el nombre: ')\n                comprovacion()\n                            \n            case '3':\n                nombre = input('De que contacto quieres cambier el nombre: ')\n                if nombre in my_agenda:\n                     comprovacion()\n                else:\n                    print(f'El contacto {nombre} no existe.')\n            case '4':\n                nombre = input('Que contacto quieres eliminar: ')\n                if nombre in my_agenda:\n                    del my_agenda[nombre]\n                    print(f'El contacto {nombre} se elimino.')\n                else:\n                    print(f'El contacto {nombre} no existe.')\n            case '5':\n                print('Saliendo de la agenda')\n                break\n            case _:\n                print('Elige una opcion entre las que aparecen.')\n\n\n\n\n\nagenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/pwrxman.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto\n *   en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n\"\"\"\n# Creando LISTA Usando Brackets\nmy_list: list = [\"Brais\", \"Black\", 4 , True, 3.1416, [\"a\", \"b\", \"c\", \"d\"]]   \n\n# Creando LISTA Using the list() constructor to make a List:\nthislist = list((\"xerox\", \"tomas\", \"apple\", \"banana\", \"cherry\")) # note the double round-brackets\nprint(thislist)                    \nprint(my_list)\n\nempty_list = list() # this is an empty list, no item in the list\n\nmy_list.append(\"Castor\")  # Inserción\nprint(my_list)\nmy_list.remove(\"Brais\")  # Eliminación\nprint(my_list)\nprint(my_list[1])  # Acceso al segundo elemento, recuerda que empieza en cero\nmy_list[1] = \"Cuervillo\"  # Actualización\nprint(my_list)\n\nthislist.sort()\nprint(thislist)\n\nlst = ['item1','item2','item3', 'item4', 'item5']\nf_item, s_item, t_item, *rest = lst  # Hace un emparejamiento de cada nombre de estos con el correspondiente elemento de la lista\n                        # El *rest crea una lista con los elementos restantes \nprint(f_item)     # item1\nprint(t_item)    # item2\nprint(s_item)     # item3\nprint(rest)           # ['item4', 'item5']\nprint(type(my_list))\n\n\n# Creando TUPLE con parentesis\nmy_tuple: tuple = (\"Andrei\", \"Med\", \"@amed\", \"66\")\nprint(my_tuple)\n\n# Creando TUPLE usando el constructor\nthistuple = tuple((\"apple\", \"banana\", \"cherry\")) # note the double round-brackets\nprint(thistuple)\n\nprint(my_tuple[1])  # Acceso\nprint(my_tuple[3])\nmy_tuple = tuple(sorted(my_tuple))  # Ordenación\nprint(my_tuple)\nprint(type(my_tuple))\n\n\n# Creando un SET usando llaves {}\nmy_set: set = {\"Brais\", \"Moure\", \"@mouredev\", \"36\"}\nprint(my_set)\n\n# Creando un SET usando e constructor\nthisset = set((\"apple\", \"banana\", \"cherry\")) # note the double round-brackets\nprint(thisset) \n\n\nmy_set.add(\"mouredev@gmail.com\")  # Inserción\nprint(my_set)\nmy_set.remove(\"Moure\")  # Eliminación\nprint(my_set)\nmy_set = set(sorted(my_set))  # No se puede ordenar\nprint(my_set)\nprint(type(my_set))\n\n# Creando un Diccionario usando {}\nmy_dict: dict = {\n    \"name\": \"Brais\",\n    \"surname\": \"Moure\",\n    \"alias\": \"@mouredev\",\n    \"age\": \"36\"\n}\nprint(my_dict)\n\n# Creating a Dictionary Using the dict() method to make a dictionary:\nthisdict = dict(name = \"John\", age = 36, country = \"Norway\")\nprint(thisdict)\n\n\nmy_dict[\"email\"] = \"mouredev@gmail.com\"  # Inserción\nprint(my_dict)\ndel my_dict[\"surname\"]  # Eliminación\nprint(my_dict)\nprint(my_dict[\"name\"])  # Acceso\nmy_dict[\"age\"] = \"37\"  # Actualización\nprint(my_dict)\nmy_dict = dict(sorted(my_dict.items()))  # Ordenación\nprint(my_dict)\nprint(type(my_dict))\n\n\n# Diccionario anidado\nchild1 = {\n  \"name\" : \"Emil\",\n  \"year\" : 2004\n}\nchild2 = {\n  \"name\" : \"Tobias\",\n  \"year\" : 2007\n}\nchild3 = {\n  \"name\" : \"Linus\",\n  \"year\" : 2011\n}\n\nmyfamily = {\n  \"child1\" : child1,\n  \"child2\" : child2,\n  \"child3\" : child3\n} \n\nprint(child1)\nprint(child2)\nprint(child3)\nprint(myfamily)\n\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n *   y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n *   y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más\n *   de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.\n\"\"\"\n\nagenda = {}\n\ndef searching():\n    print(\"\\nBuscando contactoF\")\n    nombre = input(\"Dime el nombre a Buscar: \")\n    if nombre in agenda.keys():\n        print(f\"Encontre el nombre {nombre} solicitado y su teléfono es {agenda[nombre]}\\n\")\n      \n    else:\n        print(f\"No existe el contacto {nombre}\\n\")    \n\n\ndef adding():\n    print(\"\\nAñadiendo contactoF\")\n    nombre = input(\"Dime el nombre del nuevo contacto: \")\n    if nombre in agenda.keys():\n        print(f\"Ya existe un contacto con el nombre -> {nombre} y telefono {agenda[nombre]}\\n\\n\")\n              \n    else:\n        # print(f\"Nombre no Duplicado  ============>  nombre = {nombre}\")\n        tel = input(\"Introduce el número telefónico del contacto: \")\n        if tel.isdigit() and len(tel) > 0 and len(tel) <= 11:\n            agenda[nombre] = tel\n            print(f\"Se añadió nuevo contacto nombre: {nombre} y telefono {agenda[nombre]}\\n\\n\")\n\n        else:\n            print(\"Debes introducir un teléfono solo con números y un máximo de 11 dígitos.\\n\\n\")   \n\ndef updating():\n    print(\"Modificar contactoF\")\n    nombre = input(\"Dime el nombre del contacto que deseas actualizar: \")\n    if nombre in agenda.keys():\n        tel = input(\"Dime el nuevo telefono  para este contacto: \")\n        agenda[nombre] = tel\n        print(f\"Se actualizó el contacto {nombre} con el telefono {agenda[nombre]}\\n\\n\")\n    else:\n        print(f\"No existe el contacto {nombre}\\n\")\n\ndef deleting():\n    print(\"Eliminando contactoF\")      \n    nombre = input(\"Dime el nombre del contacto que deseas eliminar: \")\n    if nombre in agenda.keys():\n        agenda.pop(nombre)\n        print(f\"Se eliminó el contacto {nombre}\")\n    else:\n        print(f\"No existe el contacto {nombre}\\n\")\n\ndef my_agenda():\n\n    operacion = \"0\"\n    \n    while operacion != \"5\": \n        print(\"1. Buscar Contacto\")\n        print(\"2. Añadir Nuevo Contacto\")\n        print(\"3. Modificar Contacto\")\n        print(\"4. Eliminar Contacto\")\n        print(\"p. Genrra Lista de Contactos\")\n        print(\"5. Terminar\")\n\n        operacion = input(\"Seleccione la operación deseada: \")\n\n        match operacion:\n          case \"1\":\n              searching()\n          \n          case \"2\":\n              adding()\n          \n          case \"3\":\n              updating()\n\n          case \"4\":\n              deleting()\n          \n          case \"p\":\n              for x, y in agenda.items():\n                  print(x, y) \n\n          case \"5\":\n            print(\"Terminar\")  \n            break\n\n          case _:\n            print(\"Opcion seleccionada NO válida.\")               \n\nmy_agenda()\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/pyramsd.py",
    "content": "'''\nMuestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\nUtiliza operaciones de inserción, borrado, actualización y ordenación.\n'''\n#   Lista:\nlista = [1, 2, 3, 4, 5, 15, 30]\nprint(lista)\n\n#       insercion\nlista.append(60) # --> se añade al ultimo\nprint(lista)\n\nlista.insert(0, 50) # --> .insert(indice, elemento)\n\n#       borrado\nelementoBorrado = lista.pop(4) # --> eliminamos el elemento de dicho indice\nlista.remove(15) # --> eliminamos con el nombre del elemento\nprint(elementoBorrado)\nprint(lista)\n\n#       actualizacion\nlista[5] = 20\nprint(lista)\n\n#       ordenacion\nlistOrdenada = sorted(lista) # --> sin modificar la lista original\nlista.sort() # --> modificando la lista original\nprint(listOrdenada)\nprint(lista)\n\nprint()\n\n#   Tupla. NOTA: En las tuplas no se pueden hacer ningun tipo de modificaciones\ntupla = (100, 25, 3, 47, 5, 61, 7, 88, 93)\nprint(tupla)\n\n#       ordenacion\ntuplaOrdenada = sorted(tupla)\nprint(tuple(tuplaOrdenada))\n\nprint()\n\n#   Sets. NOTA: No se pueden ordenar\nmiSet = {123, 235235, 46, 345, 3453, 2323}\nprint(miSet)\n\n#       insercion\nmiSet.add(90)\nprint(miSet)\nmiSet.update([77, 11])\nprint(miSet)\n\n#       borrado\nmiSet.remove(90) # --> borra indicando el elemento\nprint(miSet)\nmiSet.discard(123)\nprint(miSet)\n\nprint()\n\n#   Diccionarios\ndicc = {1:'a', 2:'b', 3:'c', 4:'d', 5:'e'}\nprint(dicc)\n\n#       insercion\ndicc[6] = 'f'\nprint(dicc)\n\n#       borrado\ndel dicc[4]\nprint(dicc)\n\n#       actualizacion\ndicc[1] = 'Sergio'\nprint(dicc)\n\n#       ordenacion\ndiccionarioOrdenado = sorted(dicc.items())\nprint(diccionarioOrdenado)\n\nprint()\n\n# EXTRA\n'''\nCrea una contactos de contactos por terminal.\nDebes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\nCada contacto debe tener un nombre y un número de teléfono.\nEl programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\nlos datos necesarios para llevarla a cabo.\nEl programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n(o el número de dígitos que quieras)\nTambién se debe proponer una operación de finalización del programa.\n'''\nimport re\n\ncontactos = {}\n\nwhile True:\n    print('CONTACTOS')\n    print('1. Buscar contacto\\n2. Añadir contacto \\\n          \\n3. Actualizar contacto\\n4. Borrar contacto\\\n          \\n5. Mostrar contactos\\n6. Salir')\n\n    choice = input(\"Ingrese el número de la operación que desea realizar: \")\n\n    if choice == '1':\n        nombre = input(\"Buscar nombre: \")\n        if nombre in contactos:\n            print(f\"Nombre: {nombre}, Teléfono: {contactos[nombre]}\")\n            print()\n        else:\n            print(f\"El contacto {nombre} no existe en la contactos.\\n\")\n\n    elif choice == '2':\n        nombre = input(\"Ingrese el nombre del contacto: \")\n        telf = input(\"Ingrese el número de dicho contacto: \")\n        if re.match(r'^\\d{9}$', telf):\n            contactos[nombre] = telf\n            print(f\"Contacto {nombre} añadido correctamente.\\n\")\n        else:\n            print(\"Error!. Debe ser numérico y tener 9 dígitos.\\n\")\n\n    elif choice == '3':\n        nombre = input(\"Ingrese el nombre del contacto a actualizar: \")\n        if nombre in contactos:\n            telf = input(\"Ingrese el nuevo número de teléfono: \")\n            if re.match(r'^\\d{9}$', telf):\n                contactos[nombre] = telf\n                print(f\"Contacto {nombre} actualizado correctamente.\\n\")\n            else:\n                print(\"Error!. Debe ser numérico y tener 9 dígitos.\\n\")\n        else:\n            print(f\"El contacto {nombre} no existe en la contactos.\\n\")\n\n    elif choice == '4':\n        nombre = input(\"Ingrese el nombre del contacto a eliminar: \")\n        if nombre in contactos:\n            del contactos[nombre]\n            print(f\"Contacto {nombre} eliminado correctamente.\\n\")\n        else:\n            print(f\"El contacto {nombre} no existe en la contactos.\\n\")\n\n    elif choice == '5':\n        print(\"\\n--- Lista de Contactos ---\")\n        if len(contactos) != 0: \n            for nombre, telf in contactos.items():\n                print(f\"Nombre: {nombre}, Telf: {telf}\")\n        else:\n            print('No Hay contactos\\n')\n        print()\n\n    elif choice == '6':\n        print(\"Saliste del programa\")\n        break\n\n    else:\n        print(\"Opción no válida. Ingrese un número del 1 al 6.\")\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/quejuan52.py",
    "content": "'''EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n '''\n\n# listas \n\nlistasNombres = ['Juan','Carlos','Ricardo','Maria']\nlistasNumeros = [2,5,6,9,0]\nlistaMix = [2,5,'f','r']\nprint (listasNombres)\nprint (listasNumeros)\nprint (listaMix)\n# tuplas \n\ntuplaFrutas = ('Manzana','Uva','Naranja','Mandarina')\ntuplaNumeros = (2,4,6,8)\nprint(tuplaFrutas)\nprint(tuplaNumeros)\n\n# set \n\nconjuntoPlanetas = {'marte','venus','jupiter'}\nprint(conjuntoPlanetas)\n\n# diccionarios \n\ndiccionario = {'IDE':'integrate Development Enviroment','OOP': 'Object oriented programming'}\n\n# Operaciones de inserción, borrado, actualización y ordenación\n\n# listas\n\nlistasNombres.append('Ricardo') # para agregar un elemento a nuestra lista \nlistasNombres.insert(2,'Cesar') #agregando un elemento en una posicion indicada\nlistasNombres.remove('Maria')  # estoy eliminando un elemento de la lista \nlistasNombres.pop()  # elimina el ultimo elemento que se agrego en la lista\nlistasNombres.clear() # para limpiar todos los elementos de la lista \nlistasNombres.sort() # ordena la lista\n\n# tuplas\n'''las tuplas no se pueden modificar o eliminar como las listas son tipos inmutables'''\n\n# Diccionarios\n\ndiccionario ['PK'] = 'Primary key'#estamos agragando una nueva llave a nuestro diccionario\ndiccionario.pop('OOP') # para eliminar un elemento de nuestro diccionario \ndiccionario ['IDE'] = 'valor nuevo'# modifica el valor de la llave de nuestro diccionario \n\n# Set\n\nconjuntoPlanetas.add('Tierra') # agregando un elemento a nuestro conjunto\nconjuntoPlanetas.remove('Tierra') # para eliminar un elemento del diccionario \nconjuntoPlanetas.discard('jupiter') # para eliminar un elemento del diccionario \ndel conjuntoPlanetas # borrado por completo \n\n'''DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n *   y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n *   y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más\n *   de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.'''\n\nclass AgendaContactos:\n    def __init__(self):\n        self.contactos = {}\n\n    def agregar_contacto(self, nombre, telefono):\n        if not telefono.isdigit() or len(telefono) > 11:\n            print(\"Número de teléfono no válido.\")\n            return\n        self.contactos[nombre] = telefono\n        print(f\"Contacto {nombre} agregado correctamente.\")\n\n    def buscar_contacto(self, nombre):\n        if nombre in self.contactos:\n            print(f\"Nombre: {nombre}, Teléfono: {self.contactos[nombre]}\")\n        else:\n            print(f\"Contacto {nombre} no encontrado.\")\n\n    def actualizar_contacto(self, nombre, telefono):\n        if nombre in self.contactos:\n            if not telefono.isdigit() or len(telefono) > 11:\n                print(\"Número de teléfono no válido.\")\n                return\n            self.contactos[nombre] = telefono\n            print(f\"Contacto {nombre} actualizado correctamente.\")\n        else:\n            print(f\"Contacto {nombre} no encontrado.\")\n\n    def eliminar_contacto(self, nombre):\n        if nombre in self.contactos:\n            del self.contactos[nombre]\n            print(f\"Contacto {nombre} eliminado correctamente.\")\n        else:\n            print(f\"Contacto {nombre} no encontrado.\")\n\n    def mostrar_contactos(self):\n        print(\"Lista de contactos:\")\n        for nombre, telefono in self.contactos.items():\n            print(f\"Nombre: {nombre}, Teléfono: {telefono}\")\n\n\nagenda = AgendaContactos()\n\nwhile True:\n    print(\"\\nSeleccione una operación:\")\n    print(\"1. Agregar contacto\")\n    print(\"2. Buscar contacto\")\n    print(\"3. Actualizar contacto\")\n    print(\"4. Eliminar contacto\")\n    print(\"5. Mostrar contactos\")\n    print(\"6. Salir\")\n\n    opcion = input(\"Ingrese el número de la operación: \")\n\n    if opcion == \"1\":\n        nombre = input(\"Ingrese el nombre del contacto: \")\n        telefono = input(\"Ingrese el número de teléfono: \")\n        agenda.agregar_contacto(nombre, telefono)\n\n    elif opcion == \"2\":\n        nombre = input(\"Ingrese el nombre del contacto a buscar: \")\n        agenda.buscar_contacto(nombre)\n\n    elif opcion == \"3\":\n        nombre = input(\"Ingrese el nombre del contacto a actualizar: \")\n        telefono = input(\"Ingrese el nuevo número de teléfono: \")\n        agenda.actualizar_contacto(nombre, telefono)\n\n    elif opcion == \"4\":\n        nombre = input(\"Ingrese el nombre del contacto a eliminar: \")\n        agenda.eliminar_contacto(nombre)\n\n    elif opcion == \"5\":\n        agenda.mostrar_contactos()\n\n    elif opcion == \"6\":\n        print(\"Saliendo del programa. ¡Hasta luego!\")\n        break\n\n    else:\n        print(\"Opción no válida. Intente nuevamente.\")\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/qv1ko.py",
    "content": "contacts = {}\nrun = True\n\nwhile run:\n\n    option = input(\"Select one option:\\n1) Search contact\\n2) Create contact\\n3) Update contact\\n4) Delete contact\\n0) Exit\\n>> \")\n    \n    if option == \"1\":\n        if len(contacts) > 0:\n            name = input(\"Enter the name of the contact\\n>> \")\n            if name in contacts:\n                phone = contacts[name]\n                print(f\"\\n>> {name} - {phone}\")\n            else:\n                print(\"\\n>> Contact does not exist\")\n        else:\n            print(\"\\n>> You have no contacts\")\n    \n    elif option == \"2\":\n        name = input(\"Enter the name of the new contact\\n>> \")\n        while True:\n            phone = input(\"Type the phone number of the new contact\\n>> \")\n            if phone.isdigit() and 9 <= len(phone) <= 11:\n                break\n            else:\n                print(\"Phone number must be between 9 and 11 digits.\")\n        contacts[name] = phone\n    \n    elif option == \"3\":\n        if len(contacts) > 0:\n            name = input(\"Type the name of the contact to update\\n>> \")\n            if name in contacts:\n                while True:\n                    phone = input(\"Type the phone number\\n>> \")\n                    if phone.isdigit() and 9 <= len(phone) <= 11:\n                        break\n                    else:\n                        print(\"Phone number must be between 9 and 11 digits.\")\n                contacts[name] = phone\n                print(f\"\\n>> {name} - {phone}\")\n            else:\n                print(\"\\n>> Contact does not exist\")\n        else:\n            print(\"\\n>> You have no contacts\")\n    \n    elif option == \"4\":\n        name = input(\"Type the name of the contact to delete\\n>> \")\n        if name in contacts:\n            del contacts[name]\n            print(f\"\\n>> Contact {name} deleted.\")\n        else:\n            print(\"\\n>> Contact does not exist\")\n    \n    elif option == \"0\":\n        run = False\n        print(\"Leaving...\")\n    \n    else:\n        print(\"\\n>> Invalid option\")\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/qwik-zgheib.py",
    "content": "# list\nlist_i: list[int] = [1, 2, 3, 4, 5]\nlist_i.append(6)\nlist_i.remove(3)\nlist_i[0] = 10\nlist_i.sort()\nprint(\"list_i:\", list_i)\n\n# tuple\ntuple_i: tuple = (1, 2, 3, 4, 5)\nprint(\"tuple_i\", tuple_i)\n\n\n# set\nset_i: set[int] = {1, 2, 3, 4, 5}\nset_i.add(6)\nset_i.remove(3)\nprint(\"set_i:\", set_i)\n\n# dictionary\ndict_i: dict[str, int] = {\"a\": 1, \"b\": 2, \"c\": 3}\ndict_i[\"d\"] = 4\ndel dict_i[\"b\"]\ndict_i[\"a\"] = 10\ndict_sorted_i = dict(sorted(dict_i.items(), key=lambda item: item[1]))\n\n\nprint(\"dict_i:\", dict_i)\nprint(\"dict_i order:\", dict_sorted_i)\n\n\n# -- extra challenge\nclass Contact:\n    def __init__(self, name: str, phone: int):\n        self.name: str = name\n        self.phone: int = phone\n\n    def __str__(self):\n        return f\"Name: {self.name}, Phone: {self.phone}\"\n\n\nclass ContactValidator:\n    @staticmethod\n    def validate_name(name: str) -> bool:\n        return len(name) > 0\n\n    @staticmethod\n    def validate_phone(phone: str) -> bool:\n        try:\n            int(str(phone).replace(\"+\", \"\"))\n            return len(phone) >= 11\n        except ValueError:\n            return False\n\n\nclass ContactRepository:\n    def __init__(self):\n        self.contacts: list = []\n\n    def add_contact(self, contact: Contact):\n        self.contacts.append(contact)\n\n    def remove_contact(self, name: str):\n        self.contacts: list = [c for c in self.contacts if c.name != name]\n\n    def update_contact(self, name: str, new_contact: Contact):\n        for i, contact in enumerate(self.contacts):\n            if contact.name == name:\n                self.contacts[i] = new_contact\n                return\n\n    def find_contact(self, name: str) -> Contact:\n        for contact in self.contacts:\n            if contact.name == name:\n                return contact\n        return None\n\n    def list_contacts(self):\n        return sorted(self.contacts, key=lambda x: x.name)\n\n\nclass ContactService:\n    def __init__(self, repository: ContactRepository, validator: ContactValidator):\n        self.repository = repository\n        self.validator = validator\n\n    def add_contact(self, name: str, phone: int):\n        if self.validator.validate_name(name) and self.validator.validate_phone(phone):\n            contact = Contact(name, phone)\n            self.repository.add_contact(contact)\n        else:\n            print(\"invalid contact information.\")\n\n    def remove_contact(self, name: str):\n        self.repository.remove_contact(name)\n\n    def update_contact(self, name: str, new_name: str, new_phone: int):\n        if self.validator.validate_name(new_name) and self.validator.validate_phone(\n            new_phone\n        ):\n            new_contact = Contact(new_name, new_phone)\n            self.repository.update_contact(name, new_contact)\n        else:\n            print(\"invalid contact information.\")\n\n    def find_contact(self, name: str) -> Contact:\n        return self.repository.find_contact(name)\n\n    def list_contacts(self):\n        return self.repository.list_contacts()\n\n\ndef main():\n    repository = ContactRepository()\n    validator = ContactValidator()\n    service = ContactService(repository, validator)\n\n    while True:\n        print(\"\\n--- Contacts Agenda ---\")\n        print(\"[1] insert contact\")\n        print(\"[2] delete contact\")\n        print(\"[3] update contact\")\n        print(\"[4] search contact\")\n        print(\"[5] show contacts\")\n        print(\"[6] exit\")\n\n        option = input(\"select an option: \")\n\n        if option == \"1\":\n            name = input(\"contact name: \")\n            phone = input(\"contact phone: \")\n            service.add_contact(name, phone)\n        elif option == \"2\":\n            name = input(\"enter contact name to delete: \")\n            service.remove_contact(name)\n        elif option == \"3\":\n            name = input(\"enter contact name to update: \")\n            new_name = input(\"new name of the contact: \")\n            new_phone = input(\"new phone of the contact: \")\n            service.update_contact(name, new_name, new_phone)\n        elif option == \"4\":\n            name = input(\"enter contact name to search: \")\n            contact = service.find_contact(name)\n            if contact:\n                print(contact)\n            else:\n                print(\"contact not found.\")\n        elif option == \"5\":\n            contacts = service.list_contacts()\n            for contact in contacts:\n                print(contact)\n        elif option == \"6\":\n            print(\"exiting program.\")\n            break\n        else:\n            print(\"invalid option. try again.\")\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/rantamhack.py",
    "content": "#!/usr/bin/python3\n#!/usr/bin/python3\n\nprint(\"\\n\\n======================LISTAS======================\\n\\n\")\n\n'''\nLISTAS - Se representan entre corchetes y pueden tener elementos repetidos. Es una estructura ordenada y modificable en el tiempo\nPueden hacerse de de cualquier tipo de datos incluso mezclándolos\n'''\nlist_strings = [\"Luis\", \"María\", \"Helena\",\n                \"Pedro\", \"Ignacio\", \"Jose\", \"Zoe\", \"Candela\"]\nprint(list_strings)\nlist_numbers = [3, 7, 52, 45, 9, 8, 8, 8, 7, 5]\nprint(list_numbers)\nlist_mixed = [\"Luis\", 7, 52, 9, \"Helena\", \"ignacio\", 55]\nprint(list_mixed)\n\n# Inserción\nlist_strings.append(\"Juan\")  # Añade un elemento al final de la lista\nprint(list_strings)\n\nlist_strings.insert(3, \"Cristina\")  # Añade un elemento en la posición indicada\nprint(list_strings)\n\n# Actualización\n# Actualiza la lista cambiando la posición indicada por el nuevo elemento\nlist_strings[-1] = \"Angel\"\nprint(list_strings)\n\n# Ordenación\nlist_strings.sort()  # Ordena la lista (en éste caso alfabeticamente)\nprint(list_strings)\n\n# Borrado\nlist_strings.pop(0)  # Borra el elemento indicado de la lista\nprint(list_strings)\n\nlist_strings.pop()  # Borra el ultimo elemento de la lista\nprint(list_strings)\n\n\nprint(\"\\n\\n======================TUPLAS======================\\n\\n\")\n\n'''\nTuplas - Se representan entre parentesis y como las listas pueden tener elementos repetidos. Es una estructura ordenada y no\nmodificable. Puede hacerse de cualqier tipo de datos incluso mezclándolos\n'''\ntuple_strings = (\"Luis\", \"María\", \"Helena\", \"Pedro\",\n                 \"Ignacio\", \"Jose\", \"Zoe\", \"Candela\")\nprint(tuple_strings)\ntuple_numbers = (3, 7, 52, 45, 9, 8, 8, 8, 7, 5)\nprint(tuple_numbers)\ntuple_mixed = (\"Luis\", 7, 52, 9, \"Helena\", \"ignacio\", 55)\nprint(tuple_mixed)\n\n# Las tuplas son inmutables por lo que una vez creadas no se pueden transformar\n\n\nprint(\"\\n\\n======================DICCIONARIOS======================\\n\\n\")\n\n'''\nDiccionarios - Se representan entre llaves y cada elemento consta de una combinación entre una llave y un valor. Es una estructura no organizada\ny modificable en el tiempo. La clave y el valor deben de estar separados por dos puntos. Los pares de elementos iran separados por comas.\n'''\n\nevaluation = {\n    \"Luis\": 5,\n    \"María\": 7.5,\n    \"Helena\": 9,\n    \"Pedro\": 3.8,\n    \"Ignacio\": 2\n}\nprint(evaluation)\n\n# Inserción\n\nevaluation[\"Candela\"] = 6.5  # Añade un elemento al diccionario\nprint(evaluation)\n\nprint(evaluation.keys())  # Lista las claves del diccionario\n\nprint(evaluation.values())  # Lista los valores del diccionario\n\n# Borrado\nevaluation.pop(\"Luis\")  # También se podria usar \"del evaluation[\"Luis\"]\"\nprint(evaluation)\n\n# Ordenación\n\nevaluation_sort = sorted(evaluation.items())\nprint(evaluation_sort)\n\n# Actualización\n\nevaluation.update({\"Miguel\": 5})\nprint(evaluation)\n\nprint(\"\\n\\n======================SETS======================\\n\\n\")\n\n'''\nSets - Se representan entre corchetes y a diferencia de listas y tuplas no pueden tener elementos repetidos es una estructura no organizada\nmodificable en el tiempo\n'''\n\nset_strings = set([\"Luis\", \"María\", \"Helena\", \"Pedro\",\n                  \"Ignacio\", \"Jose\", \"Zoe\", \"Candela\"])\nprint(set_strings)\nset_numbers = set([3, 7, 52, 45, 9, 8, 5])\nprint(set_numbers)\nset_mixed = set([\"Luis\", 7.5, 9, \"Helena\", \"ignacio\", 55])\nprint(list_mixed)\n\n# Inserción\nset_strings.add(\"Miguel\")\nprint(set_strings)\n\n# Borrado\nset_strings.remove(\"Pedro\")  # Elimina el elemento indicado\nprint(set_strings)\n\nset_strings.pop()  # Elimina un elemento aleatorio\nprint(set_strings)\n\n# Ordenación\nprint(sorted(set_strings))\n\n# Actualización\nset_strings.update(set_numbers)\nprint(set_strings)\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/raulG91.py",
    "content": "\n'''List '''\nprint(\"--List--\")\nlist1 = [6,19,5,3]\nprint(\"List: \", list1)\nlist1.append(1)\nprint(\"Append operation: \",list1)\nlist1.sort()\nprint(\"Sort list : \" , list1)\nlist1[2] = 2\nprint(\"Update element at position 3: \",list1)\nlist1.pop(-1)\nprint(\"Remove last element :\", list1)\n\n'''Tuples'''\nprint(\"--Tuples--\")\ntuple = (4,10,3)\nprint(\"Tuple: \", tuple)\n\n'''Set'''\nprint(\"--Set--\")\nset_int = {4,8,5}\nprint(\"Set: \", set_int)\nset_int.add(16)\nprint(\"Add operation: \",set_int)\nset_int.remove(8)\nprint(\"Romve operation: \", set_int)\n\n'''Dictionary'''\n\nprint(\"--Dictionary--\")\n\nmy_dict = {'blue':'azul','orange':'naranja'}\nprint(\"Dictionary: \",my_dict)\nmy_dict['green'] = 'verde'\nprint(\"Add operaion: \",my_dict)    \nmy_dict['green'] = 'azul'\nprint(\"Update operation: \",my_dict) \ndel(my_dict['green'])\nprint(\"Delete operation: \", my_dict)          \n\ndef check_phone_number(number:str) -> bool:\n    if number.isdigit() and len(number) == 9:\n        return True\n    else:\n        return False\ndef telephone_agenda():\n    \n    agenda = {}\n    \n    while True:\n        print(\"Enter 1 to create a new contact\")\n        print(\"Enter 2 to update a contact\" )\n        print(\"Enter 3 to look for a contact\")\n        print(\"Enter 4 to remove a contact\")\n        print(\"Enter 5 to exit the program\")\n        \n        option = int(input())\n        \n        if option == 1:\n            print(\"Enter name for new contact: \")\n            name = input()\n            print(\"Enter number for new contact: \")\n            tel = input()\n            if check_phone_number(tel):\n                agenda[name] = tel\n            else:\n                print(\"Incorrect telephone number\")\n        \n        elif option == 2:\n            print(\"Enter name for contact to be updated: \")\n            name = input()\n            if name in agenda:\n                print(\"Enter new telephone number: \")\n                tel =input()\n                if check_phone_number(tel):\n                    agenda[name] = tel\n                    print(agenda)\n                else:\n                    print(\"Incorrect telephone number\")\n            else:\n                print(\"Contact doesn't exist in the agenda\")    \n        elif option == 3:\n            print(\"Enter the name of the contact\")\n            name = input()\n            if name in agenda:\n                print(\"Phone number is: \",agenda[name])\n            else:\n                print(\"Contact is not in the agenda\")    \n        elif option == 4:\n            print(\"Enter the name of the contact\")\n            name = input()\n            if name in agenda:\n                del(agenda[name])\n                print(\"Phone number was deleted: \", agenda)\n            else:\n                print(\"Contact is not in the agenda\")   \n        else: \n            break\n\ntelephone_agenda()        "
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/rayn1er.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto\n#  *   en tu lenguaje.\n#  * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea una agenda de contactos por terminal.\n#  * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n#  *   y eliminación de contactos.\n#  * - Cada contacto debe tener un nombre y un número de teléfono.\n#  * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n#  *   y a continuación los datos necesarios para llevarla a cabo.\n#  * - El programa no puede dejar introducir números de teléfono no numéricos y con más\n#  *   de 11 dígitos (o el número de dígitos que quieras).\n#  * - También se debe proponer una operación de finalización del programa.\n#  */\n\n# listas \n# en python podemos crear listas creando una variable y asignandole a ella corchetes o utilizando el metodo list, las listas son mutables, por lo que podemos agregar y eliminar elementos de ella\n\nmy_list = [1,2,3,4,5] # creando con corchetes\nmy_list_2 = list(['i','am','a','list']) # ccreando utilizando list\nmy_list_3 = [1,'string',True] # las listas pueden almacenanr diferentes tipos de datos\n\nprint(my_list,my_list_2,my_list_3)\n\nprint(my_list_2[1]) # podemos obtener un dato individual si utilizamos corchetes luego de la misma junto con su indice\nprint(my_list_2[-1]) # tambien podemos obtener un dat utilizando indices negativos para empezar a contar desde el final de la lista\nprint(my_list_2[1:3]) # tambien se puede obtener una sublista separando dos indices con 2 puntos\n\nmy_list_2[2] = 'A' #podemos cambiar un elemento escribiendo junto a corchetes el indice del elemento que se quiere cambiar junto a su nuevo valor\nprint(my_list_2) # imprime la nueva lista modificada\n\nmy_list_2.append('of elements') # el metodo append nos sirve para agregar elementos al final de la lista\nprint(my_list_2)\nmy_list_2.pop() # el metodo pop nos sirve para eliminar elementos al final de la lista\nprint(my_list_2.count('i')) # el metodo count nos sirve para contar la cantidad de veces que se repite un elemento\nprint(my_list_2.index('i')) # el metodo index nos devuelve la posicion de la primera aparicion de un elemento\nmy_list_2.remove('i') #el metodo remove elimina la primera aparicion de un elemento\nprint(my_list_2)\nmy_list_2.sort() # las listas tambien poseen el metodo sort, el cual nos sirve para ordenar la lista de manera alfabetica\nprint(my_list_2)\n\n# tuplas\n# podemos crear tuplas utilizando parentesis o mediante el metodo tuple, las tuplas no son mutables, lo que significa que no podemos modificarlas una vez creadas\n\nmy_tuple_1 = ('element 1','element 2','element 3')\nmy_tuple_2 = tuple(('element 1','element 2','element 3'))\nmy_tuple_3 = ('elementstring',True,2000) #al igual que las listas, las tuplas pueden contener elementos de distintos tipos\nprint(my_tuple_1,my_tuple_2,my_tuple_3)\n\nprint(my_tuple_1[1]) #para aceder a sus elementos usamos corchetes igual que en las listas\n\nprint(my_tuple_1.count('element 1')) # se puede contar la cantidad de veces que aparece un elemento\nprint(my_tuple_1.index('element 3')) # tambien nos muestra el indice de un elemento\n\n# conjuntos\n# para crear conjuntos en python podemos utilizar llaves o el metodo set, los conjuntos pueden contener multiples tipos de datos, pero no puede contener datos repetidos\n\nmy_set = set([1,1,2,2,3,3,4,4])\nmy_set_2 = set([3,4,5,6])\nprint(my_set) #al imprimir observamos que solo tenemos un dato a pesar de que hemos colocado dos de ellos al crear el conjunto\nmy_set.add(5) #podemos anadir elementos utilizando el metodo add\nprint(my_set)\nmy_set.remove(5) # se pueden eliminar elementos utilizando el metodo remove\nprint(my_set)\nprint(my_set.intersection(my_set_2)) # el metodo intersection nos devuelve los elementos que se encuentren en dos conjuntos\nprint(my_set_2.issubset(my_set)) #issubset nos sirve para verificar si los elementos de un conjunto estan en otro\n\n# diccionarios \n# los diccionarios nos permiten agregar elementos con una clave y un valor, estos se crean mediante los corchetes, tambien se pueden crear utilizando el metodo dict, los diccionarios son mutables, lo que significa que podemos agregar y eliminar valores\n\nmy_dict = {\"name\" : 'raul', 'age' : 25, 'country' : 'venezuela'}\n\nprint(my_dict)\nprint(my_dict['name']) # podemos ver el valor de una llave utlizando corchetes \nmy_dict['name'] = 'rayn1er' # podemos cambiar el valor de una llave con un = \nprint(my_dict)\nmy_dict['hobby'] = 'programming' # si le agregamos un valor a una llave que no existe, se agregara al final del diccionario\nprint(my_dict)\nprint(my_dict.keys()) # el metodo key nos devuelve una lista con las claves\nprint(my_dict.values()) # el metodo value nos devuelve una lista con los valores\nprint(my_dict.items()) # el metodo items devuelve una lista con los pares de datos clave y valor\nmy_dict.pop('country') # podemos eliminar una clave y su valor utilizando el metodo pop\nprint(my_dict)\n\n\n\n\nagenda = {}    \n\nwhile True:\n\n      \n    print('''\n        Bienvenido a la agenda\n        \n        Ingrese la operacion que desea realizar:\n          \n          1 - Buscar contacto\n          2 - Agregar contacto\n          3 - Actualizar contacto\n          4 - Eliminar contacto\n          5 - Ver contactos\n          6 - Cerrar agenda\n\n''')\n    \n    option = int(input(\"Ingrese una opcion -> \"))\n    if option == 1:\n        value = input(\"Ingrese el nombre del contacto -> \")\n        if value in agenda:\n            print()\n            print(f'{value} - {agenda[value]}')\n        else:\n            print()\n            print(\"Este contacto no se encuentra en la agenda\")\n\n    if option == 2:\n        value = input(\"Ingrese el nombre del contacto -> \")\n        if value in agenda:\n            print()\n            print(\"Este contacto ya esta en la agenda\")\n        else:\n            number = int(input(\"Ingrese el numero del contacto -> \"))\n            agenda[value] = number\n    if option == 3:\n        value = input(\"Ingrese el nombre del contacto -> \")\n        if value in agenda:\n            number = int(input(\"Ingrese el nuevo numro del contacto -> \"))\n            agenda[value] = number\n            print()\n            print(f'su contacto {value} ha sido actualizado con exito!')\n        else:\n            print()\n            print(\"Este contacto no se encuentra en la agenda\")\n    \n    if option == 4:\n        value = input(\"Ingrese el nombre del contacto -> \")\n        if value in agenda:\n            agenda.pop(value)\n            print()\n            print(f'Su contacto ha sido eliminado con exito!')\n        else:\n            print(f'Su contacto no se encuentra en la agenda')\n    if option == 5:\n\n        if len(agenda) == 0:\n            print()\n            print(f\"No hay contactos en la agenda\")\n        else:\n            for key, value in agenda.items():\n                print(f'{key} - {value}')\n    if option == 6:\n        print('Cerrando agenda')\n        break\n    \n    "
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/raynerpv2022.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n \n \"\"\"\n\n# listas\n\n# myList = [1,2,3,4,5,6,7,8,9,0]\n# myList.append(0) # agregar al final\n# myList.insert(2,555) # agregar en posicion indicada\n# print(myList)\n# myList.remove(0) # eliminar  el elemento indicado\n# print(myList)\n# myList[0] = 222 # cambiar valor de una posicion\n# print(myList)\n# myList.sort()\n\n# #tuplas\n\n# myTupla = (8,10,7,100,3,4,5)\n# print(type(myTupla))\n# o = tuple(sorted(myTupla))\n# print(type(o), o)\n\n# #set\n# mySet = set(myList )\n# print(type(mySet))\n# mySet.add(0)\n# mySet.remove(555)\n# print(mySet)\n\n\n# # #dic\n# myDic = {1:\"a\",2:\"b\",3:\"c\"}\n# print(myDic)\n# v= myDic.get(1)\n# print(v)\n# i = myDic.items( )\n# print(i)\n# k = myDic.keys()\n# print(k)\n# vv = myDic.values()\n# print(vv)\n# myDic[101] = \"z\"\n# myDic[1] = \"A\"\n# print(myDic)\n# del myDic[1]\n# print(myDic)\n# orded = dict(sorted(myDic.items()))\n# print(orded)\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n\n\"\"\"\nagenda = dict()\ndef Agenda():\n     \n    while True:\n        print( \"*-*- M E N U -*-*\")\n        print(\"MOSTRAR TODOS (MT)\")\n        print(\"INSERTAR (I)\")\n        print(\"ACTUALIZAR(A)\")\n        print(\"ELIMINAR (E)\")\n        print(\"BUSCAR (B)\")\n        print(\"SALIR (S)\")\n\n        operacion = input(\"\\nSeleccione opcion : \")\n        match operacion:\n            case \"I\":\n                Insertar()\n\n            case   \"A\":\n                Actualizar()\n\n            case  \"MT\":\n                Mostrar_Todos()\n            \n            case \"E\":\n                Eliminar()\n\n            case   \"B\":\n                Buscar()\n\n            case \"S\":\n                break\n            case _:\n                print(\"OPCION no VALida, de nuevo\")\n\ndef agenda_empty():\n    if  not agenda :\n        print(\"AGENDA VACIA\")\n        return 1\n\ndef Mostrar_Todos():\n    print(\"\\tMOSTrar AGENDA\")\n    \n    if agenda_empty():\n        return\n    \n    print(\"NOMBRE\", \"TELEFONO\")\n    for k,v in agenda.items():\n        print(k,v)\n\ndef Insertar():\n    print(\"INSERTAR\")\n\n    nombre = input(\"NOMBRE :\")\n    if busqueda(nombre) != 0:\n        print(nombre, \"Usuario ya existe\")\n        return\n    tel = input(\"Telefono :\")\n    tel = validar_telefono(tel)\n    if tel  != 0:\n        agenda[nombre] = tel\n    else:\n        return\n    print(agenda)\n\ndef Actualizar():\n    print(\"ACTUALIZAR\")\n    if agenda_empty():\n        return\n    nombre = input(\"Usuario a Actualizar :\")\n    if busqueda(nombre) != 0:\n        print(nombre, \" : \" , agenda[nombre])\n        new_telefono = input(\"Nuevo telefono \")\n        new_telefono = validar_telefono(new_telefono)\n        if new_telefono > 0 :\n            agenda[nombre] = new_telefono\n            print(nombre, \" : \" , agenda[nombre])\n    else:\n        print(\"Usuario no encontrado\")\n        \n\n    \n\ndef Eliminar():\n    print(\"ELIMINAR\")\n    if agenda_empty():\n        return\n    nombre = input(\"Usuario a eliminar:\")\n    if busqueda(nombre) != 0:\n        print(nombre, \" : \" , agenda[nombre])\n        del agenda[nombre]\n        print(nombre, \" : ELIMINADO\"  )\n    else:\n        print(\"Usuario no encontrado\")\n\ndef busqueda(nombre):\n    if not agenda.get(nombre):\n        return 0\n\ndef Buscar():\n    print(\"BUSCAR\")\n    \n    if agenda_empty():\n        return\n    \n    nombre = input(\"Nombre a localizar :\")\n   \n    if busqueda(nombre) != 0:\n        print(nombre, \" : \" , agenda[nombre])\n    else:\n        print(\"Usuario no encontrado\")\n        \n\n\ndef validar_telefono(movil) -> int:  \n\n    print(\"VALIDANDO DATOS... \")\n    try:\n        new_movil = int(movil)\n    except ValueError:\n        print(\"Error en datos, SOLO NUMEROS\")\n        return 0\n    \n    # mas de 5 cifras no permitido\n    if new_movil > len(str(new_movil)) >6:\n        print(\"Error en datos, telefonos mayores que 5, NO PERMITIDOS\")\n        return 0\n\n    print(\"DATOS CORRECTOS\")\n    return new_movil\n    \n\nAgenda()\n\n\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/restevean.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n\"\"\"\n\n# Creación de estructuras de datos\n# List\nmy_list = [1, 2, 3, 4, 5]\nmy_list.append(6)  # Insertion\nmy_list.remove(1)  # Deletion\nmy_list[0] = 7  # Update\nmy_list.sort()  # Sorting\n\n# Tuple\nmy_tuple = (1, 2, 3, 4, 5)\n\n# Dictionary\nmy_dict = {'one': 1, 'two': 2, 'three': 3, 'four': 4}\ndel my_dict['one']  # Deletion\nmy_dict['two'] = 22  # Update\nsorted_dict = dict(sorted(my_dict.items()))  # Sorting\n\n# Set\nmy_set = {1, 2, 3, 4, 5}\nmy_set.add(6)  # Insertion\nmy_set.remove(1)  # Deletion\n# Update is not applicable for sets as they only contain unique values\nmy_sorted_set = sorted(my_set)  # Sorting\n\n\n# Extra difficulty\nclass Contact:\n    def __init__(self, name, phone):\n        self.name = name\n        self.phone = phone\n\n\nclass ContactBook:\n    def __init__(self):\n        self.contacts = []\n\n    def insert(self, name, phone):\n        self.contacts.append(Contact(name, phone))\n\n    def delete(self, name):\n        self.contacts = [c for c in self.contacts if c.name != name]\n\n    def update(self, name, phone):\n        for c in self.contacts:\n            if c.name == name:\n                c.phone = phone\n\n    def search(self, name):\n        for c in self.contacts:\n            if c.name == name:\n                return c\n        return None\n\n\ndef main():\n    book = ContactBook()\n\n    while True:\n        operation = input(\"Enter operation (insert, delete, update, search, quit): \")\n\n        if operation == \"quit\":\n            break\n\n        if operation == \"insert\":\n            name = input(\"Enter name: \")\n            phone = input(\"Enter phone: \")\n            if not phone.isdigit() or len(phone) > 11:\n                print(\"Invalid phone number\")\n                continue\n            book.insert(name, phone)\n\n        elif operation == \"delete\":\n            name = input(\"Enter name: \")\n            book.delete(name)\n\n        elif operation == \"update\":\n            name = input(\"Enter name: \")\n            phone = input(\"Enter new phone: \")\n            if not phone.isdigit() or len(phone) > 11:\n                print(\"Invalid phone number\")\n                continue\n            book.update(name, phone)\n\n        elif operation == \"search\":\n            name = input(\"Enter name: \")\n            contact = book.search(name)\n            if contact:\n                print(f\"Name: {contact.name}, Phone: {contact.phone}\")\n            else:\n                print(\"Contact not found\")\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/rianojnicolas.py",
    "content": "from collections import OrderedDict, defaultdict, deque\nfrom array import array\nimport re\n# 1. Ejemplos de estructuras de datos\n\n# 1.1 Listas\nmyList = [1, 2, 3, 4, 5]\nprint(f'Lista = {myList}\\n')\n\n## 1.1.1 Listas como Pilas\n\"\"\"\nUltimo elemento que se añade, es el primer elemento que se retira\n\"\"\"\nmyStack = myList\nprint(f'Pila inicial = {myStack}')\nmyStack.append(6)\nmyStack.append(7)\nprint(f'Pila agregando elementos = {myStack}')\nmyStack.pop()\nprint(f'Pila quitando elemento = {myStack}')\nmyStack.pop()\nprint(f'Pila quitando elemento = {myStack}\\n')\n\n## 1.1.2 Listas como Colas\n\"\"\"\nEl primer elemento que se añade, es el primer que se retira\n\"\"\"\nmyListDeque = deque([\"Duvan\", \"Jhon\", \"Camilo\"])\nprint(f'Cola inicial = {myListDeque}')\nmyListDeque.append(\"Fabian\")\nmyListDeque.append(\"Yuri\")\nprint(f'Cola agregando elementos = {myListDeque}')\nmyListDeque.popleft()\nprint(f'Cola quitando elementos = {myListDeque}')\nmyListDeque.popleft()\nprint(f'Cola quitando elementos = {myListDeque}\\n')\n\n# 1.2 Tuplas\nmyTuple = (1, 2, 3, 4, 5)\n\n# 1.3 Diccionarios\nmyDict = {1: \"hola\", 2: \"mundo\", 3: \",\", 4: \"soy\", 5: \"rianojnicolas\"}\n\n# 1.4 Conjuntos (Sets)\nmySet = {1, 2, 3}\n\n# 1.5 Colecciones\n\n## 1.5.1 Diccionarios Ordenados\nmyOd = OrderedDict()\nmyOd['first']  = 'one'\nmyOd['second'] = 'two'\nmyOd['third']  = 'three'\nprint(f'Diccionario Ordenado {myOd}\\n')\n\n## 1.5.2 Diccionario Predeterminado\nprices = defaultdict(int)\nprices['carrots']\nprint(f'Diccionario Predeterminado = {prices}\\n')\n\n## 1.5.3 Queue (Cola)\nmydeque = deque([1, 2, 3, 4])\nprint(f'La cola (deque) = {mydeque}\\n')\n\n# 1.6 Matrices\nmyArray = array('f', [1.0, 1.5, 2.0, 2.5])\nprint(f'Matriz = {myArray}\\n')\n\n# 2. Operando con las estructuras\nprint(\"Operaciones con las Estructuras\\n\")\n\n# Listas\nprint(f'Lista Inicial = {myList}')\nmyList.append(6) # Insercion\nprint(f'Lista despues de agregar un elemento = {myList}')\nmyList.pop(1) # Borrado\nprint(f'Lista luego de borrar un elemento = {myList}')\nmyList[0] = 100 # Actualizacion\nprint(f'Lista actualizada = {myList}')\nmyList.sort() # Ordenacion\nprint(f'Lista ordenada = {myList}\\n')\n\n# Diccionarios\nprint(f'Diccionario Inicial = {myDict}')\nmyDict[6] = \"un ingeniero electronico\" # Insercion\nprint(f'Diccionario despues de agregar un elemento = {myDict}')\ndel myDict[1] # Borrado\nprint(f'Diccionario luego de borrar un elemento = {myDict}')\nmyDict[5] = \"nicolas\" # Actualizacion\nprint(f'Diccionario actualizado = {myDict}')\nmyOrderDict1 = sorted(myDict) # ordenacion de claves\nmyOrderDict2 = sorted(myDict.values()) # ordenacion de valores\nmyOrderDict3 = OrderedDict(sorted(myDict.items())) # ordenacion de elementos por clave\nprint(f'Diccionario ordenado 1 = {myOrderDict1}')\nprint(f'Diccionario ordenado 2 = {myOrderDict2}')\nprint(f'Diccionario ordenado 3 = {myOrderDict3}\\n')\n\n# Tuplas \nprint(f'Tupla Inicial = {myTuple}')\n\"\"\"\nRecordar que una tupla es un tipo de estructura inmutable, por lo tanto,\nno se puede agregar o borrar elementos. Para hacer estas operaciones, se\npuede transformar a una lista y luego volver a una tupla.\n\"\"\"\n# Insercion\nmyNewTuple = list(myTuple)\nmyNewTuple.append(100)\nmyNewTuple = tuple(myNewTuple)\nprint(f'Tupla despues de agregar un elemento = {myNewTuple}')\n# Borrado\nmyNewTuple = list(myNewTuple)\nmyNewTuple.pop(2) # Eliminar posicion 2 de la lista\nmyNewTuple = tuple(myNewTuple)\nprint(f'Tupla luego de borrar un elemento = {myNewTuple}')\n# Actualizacion\nmyNewTuple = list(myNewTuple)\nmyNewTuple[0] = 3500\nmyNewTuple = tuple(myNewTuple)\nprint(f'Tupla actualizada = {myNewTuple}')\n# Ordenacion\nmyNewTuple = tuple(sorted(myNewTuple))\nprint(f'Tupla ordenada = {myNewTuple}\\n')\n\n# Set\nprint(f'Set Inicial = {mySet}')\nmySet.add(6)\nmySet.add(1000) # Insercion\nprint(f'Set despues de agregar elementos = {mySet}')\nmySet.discard(3)\nmySet.remove(2) # Borrado\nprint(f'Set luego de borrar un elemento = {mySet}')\nmySet.discard(1)\nmySet.add(55) # Actualizacion\nprint(f'Set actualizado = {mySet}')\nmySet = sorted(mySet) # Se ordena pero queda de tipo lista\nmySet = set(mySet)\nprint(f'Set ordenado = {mySet}\\n')\n\n# -----------------------------------------------------------\n# DIFICULTAD EXTRA\n# -----------------------------------------------------------\ndirContacts = {\n    \"3015675434\" : \"Lucho Diaz\",\n    \"3106742354\" : \"Rigoberto Uran\",\n    \"3205438756\" : \"Pedro Urango\"\n}\n\ndef welcome_Menu():\n    print(\"\"\"\nHola !!, soy tu agenda de contactos. Aca puedes agregar, \nactualizar, borrar y buscar cualquiera de tus contactos.\n\nRecuerda que el contacto simplemente tiene el nombre y el\ntelefono correspondiente.\n\n¡¡¡ Comencemos!!!  \n        \"\"\")\n    name = input(\"Ingresa tu nombre: \")\n    option = mainMenu(name)\n    return option\n\n\ndef mainMenu(userName):\n    print(f'{userName}, escoge alguna de las siguientes opciones:')\n    print(\"\"\"\n    1. Busqueda de contactos\n    2. Agregar un contacto\n    3. Actualizar un contacto\n    4. Eliminar un contacto\n    5. Salir \n        \"\"\")\n    option = input(\"Ingresa la acción a realizar: \")\n    while (option != '1' and option != '2' and option != '3' and option != '4' and option != '5'):\n        print(\"Ingresaste un valor erroneo, vuelvelo a intentar\")\n        option = input(\"Ingresa la acción a realizar: \")\n    return option\n\n\ndef check_Input(numberContact):\n    patron = r\"^\\d{10}$\" # Expresión regular para comprobar que tenga 10 dígitos y no contenga ningún carácter alfabético\n    # Devolver True si el número cumple el patrón, o False en caso contrario\n    return re.match(patron, numberContact) is not None\n\n\ndef printContacts(dirContacts):\n    print(\"Tu agenda queda de la siguiente manera:\")\n    for clave, valor in dirContacts.items():\n        print(f'{valor} su numero es {clave}')\n\ndef find_Contact(numberContact, nameContact, option):\n    if (option == \"1\"):\n        contact = dirContacts.get(numberContact)\n        print(f'El numero de celular {numberContact} le corresponde a {contact}')\n    elif (option == \"2\"):\n        keys = []\n        for clave, valor in dirContacts.items():\n            if valor == nameContact:\n                keys.append(clave)\n        print(f'{nameContact} tiene el numero de celular {str(keys)}')\n\n\ndef add_Contact(numberContact, nameContact):\n    dirContacts[numberContact] = nameContact\n    print(f'Agregaste a tu agenda de contactos el nombre {nameContact}')\n    print(f'y le asignaste el numero de celular {numberContact} \\n')\n\n    printContacts(dirContacts)\n\n\ndef del_Contact(numberContact, nameContact, option):\n    if (option == \"1\"):\n        contact = dirContacts.get(numberContact)\n        print(f'Estas seguro que deseas eliminar el contacto de {contact} con el numero {numberContact}')\n        delete = input(\"Ingresa Yes/No: \")\n        if (delete == \"Yes\"):\n            del dirContacts[numberContact]\n    \n    elif (option == \"2\"):\n        keys = []\n        for clave, valor in dirContacts.items():\n            if valor == nameContact:\n                keys.append(clave)\n        for item in keys:\n            print(f'Encontramos que para el contacto de {dirContacts.get(item)} se tiene el numero {item}')\n            delete = input(\"Deseas Eliminarlo totalmente Yes/No: \")\n            if (delete == \"Yes\"):\n                del dirContacts[item]\n            elif (delete == \"No\"):\n                continue\n            else:\n                print(\"Ingresaste una opción incorrecta\")\n\n\ndef update_Contact(numberContact, nameContact, option):\n    if (option == \"1\"):\n        contact = dirContacts.get(numberContact)\n        print(f'Vas a actualizar el contacto de {contact} con el numero {numberContact}')\n        print(f'¿Que numero deseas colocar ahora al contacto {contact}?')\n        newNumberContact = input(\"Ingresalo aqui: \")\n\n        while not check_Input(newNumberContact):\n            print(\"Ingresaste un valor erroneo, vuelvelo a intentar\")\n            newNumberContact = input(\"Ingresalo nuevamente: \")\n        \n        print(f'Vas a actualizar {numberContact} por {newNumberContact}')\n        update = input(\"¿ Estas segur@ de realizar esta operacion ? (Yes/No): \")\n        if (update == \"Yes\"):\n            del dirContacts[numberContact]\n            dirContacts[newNumberContact] = contact\n\n    elif (option == \"2\"):\n        keys = []\n        for clave, valor in dirContacts.items():\n            if valor == nameContact:\n                keys.append(clave)\n        \n        for item in keys:\n            print(f'Encontramos que para el contacto de {dirContacts.get(item)} se tiene el numero {item}')\n            newNameContact = input(\"Ingresa el nuevo nombre que le pondras al contacto: \")\n            print(f'Vas a actualizar {nameContact} por {newNameContact}')\n            update = input(\"Deseas actualizar el nombre ¿ Yes/No ?: \")\n            if (update == \"Yes\"):\n                dirContacts[numberContact] = newNameContact\n        \n        printContacts(dirContacts)\n\ndef execute_Option(option, still):\n    if (option == '1'):\n        print(\"\"\"\n        Para realizar la busqueda de algun contacto tienes dos opciones:\n            1. Buscar por el numero de telefono\n            2. Buscar por el nombre de contacto\n        \"\"\")\n        optionSearch = input(\"Ingresa la opcion que quieres: \")\n        \n        while (optionSearch != '1' and optionSearch != '2'):\n            print(\"Ingresaste un valor erroneo, vuelvelo a intentar\")\n            optionSearch = input(\"Ingresa la opcion que quieres: \")\n        \n        if (optionSearch == '1'):\n            numberContact = input(\"Ingresa el numero de telefono a buscar: \")\n\n            while not check_Input(numberContact):\n                print(\"Ingresaste un valor erroneo, vuelvelo a intentar\")\n                numberContact = input(\"Ingresa el numero de telefono a buscar: \")\n                \n            find_Contact(numberContact, \"0\", optionSearch)\n        elif (optionSearch == '2'):\n            nameContact = input(\"Ingresa el nombre del contacto a buscar: \")\n            find_Contact(\"0\", nameContact, optionSearch)\n        still = True\n\n    elif(option == '2'):\n        nameContact = input(\"Ingresa el nombre del contacto que vas a agregar: \")\n        numberContact = input(\"Ingresa el numero de telefono: \")\n\n        while not check_Input(numberContact):\n            print(\"Ingresaste un valor erroneo, vuelvelo a intentar\")\n            numberContact = input(\"Ingresa nuevamente el numero de telefono: \")\n\n        add_Contact(numberContact, nameContact)\n        still = True\n\n    elif(option == '3'):\n        print(\"\"\"\n        Para realizar la actualizacion de algun contacto tienes dos opciones:\n            1. Actualizar el numero de telefono\n            2. Actualizar el nombre de contacto\n        \"\"\")\n        optionUpdate = input(\"Ingresa la opcion que quieres: \")\n        \n        while (optionUpdate != '1' and optionUpdate != '2'):\n            print(\"Ingresaste un valor erroneo, vuelvelo a intentar\")\n            optionUpdate = input(\"Ingresa la opcion que quieres: \")\n        \n        if (optionUpdate == '1'):\n            numberContact = input(\"Ingresa el numero de telefono que vas a actualizar: \")\n\n            while not check_Input(numberContact):\n                print(\"Ingresaste un valor erroneo, vuelvelo a intentar\")\n                numberContact = input(\"Ingresa de nuevo el numero de telefono: \")\n                \n            update_Contact(numberContact, \"0\", optionUpdate)\n\n        elif (optionUpdate == '2'):\n            nameContact = input(\"Ingresa el nombre del contacto a buscar: \")\n            update_Contact(\"0\", nameContact, optionUpdate)    \n        still = True\n\n    elif(option == '4'):\n        print(\"\"\"\n        Para eliminar un contacto tienes dos opciones:\n            1. Eliminar por el numero de telefono\n            2. Eliminar por el nombre de contacto\n        \"\"\")\n        optionDel = input(\"Ingresa la opcion que quieres: \")\n\n        while (optionDel != '1' and optionDel != '2'):\n            print(\"Ingresaste un valor erroneo, vuelvelo a intentar\")\n            optionDel = input(\"Ingresa la opcion que quieres: \")\n        \n        if (optionDel == '1'):\n            numberContact = input(\"Ingresa el numero de telefono a buscar: \")\n\n            while not check_Input(numberContact):\n                print(\"Ingresaste un valor erroneo, vuelvelo a intentar\")\n                numberContact = input(\"Ingresa el numero de telefono a buscar: \")\n                \n            del_Contact(numberContact, \"0\", optionDel)\n        elif (optionDel == '2'):\n            nameContact = input(\"Ingresa el nombre del contacto a buscar: \")\n            del_Contact(\"numberContact\", nameContact, optionDel)\n\n        still = True\n    elif(option == \"5\"):\n        still = False\n    \n    return still\n\n\ndef run():\n    x = True\n    while(x):\n        userOption = welcome_Menu()\n        x = execute_Option(userOption, True)\n\n\nif __name__ == '__main__':\n    run()    "
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/rigo93acosta.py",
    "content": "'''\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n'''\n\n## List\nlist_1 = []\nlist_2 = list()\nprint(type(list_1))\nlist_3  = [\"Hola\", \"mundo\"]\nprint(list_3)\nlist_3.append(\"!\")\nprint(list_3)\nlist_3.remove(\"Hola\")\nprint(list_3)\nprint(list_3[0])\nlist_3[0] = \"Rigo\"\nprint(list_3)\nlist_3.sort()\nprint(list_3)\n\n## Tuple\n# Tipo Inmutable\ntuple_1: tuple = (\"Rigo\", \"Acosta\", \"@rigo93acosta\", \"30\")\nprint(tuple_1)\nprint(type(tuple_1))\ntuple_1 = tuple(sorted(tuple_1)) # Sort truco\nprint(tuple_1)\nprint(type(tuple_1))\n\n## Sets\nmy_set = {\"Rigo\", \"Acosta\", \"@rigo93acosta\", \"30\"}\nprint(my_set)\nprint(type(my_set))\nmy_set.add(\"rigo93acosta@gmail.com\") # Insert\nprint(my_set)\n# print(my_set[0]) # Estructura superoptima, no hay posicion directa\nmy_set.add(\"rigo93acosta@gmail.com\") # Evita datos duplicados (No lo inserta)\nprint(my_set)\nmy_set.remove(\"Rigo\")\nprint(my_set)\n# La actualización sería eliminando y luego insertando. No confundir con el update\nprint(sorted(my_set))\nprint(set(sorted(my_set))) # La ordenación carece de sentido pues las posiciones no son fijas\n\n## Dictionary\ndict_1: dict = {\"name\": \"Rigoberto\", \"surname\": \"Acosta\", \"alias\": \"@rigo93acosta\", \"age\": \"30\"}\nprint(dict_1)\nprint(type(dict_1))\ndict_1[\"email\"] = \"rigo93acosta@gmail.com\"  # Insert\nprint(dict_1)\n# print(dict_1[0])  # Error \nprint(dict_1[\"name\"]) # Correct!\ndict_1[\"name\"] = \"Rigo\" # Update\nprint(dict_1)\ndel dict_1[\"email\"] # Delete\nprint(dict_1)\n# Sort\ndict_1 = sorted(dict_1.items())\nprint(dict_1)\ndict_1 = dict(dict_1)\nprint(dict_1)\n\n\n## Extra\n## Puede mejorarse el check del número de teléfono\n## y del nombre con funciones.\n\nagenda = {}\n\ndef get_number_phone():\n    pass\n\nwhile True:\n    print(\"Agenda Telefónica:\")\n    print(\"1- Insertar\")\n    print(\"2- Buscar\")\n    print(\"3- Actualizar\")\n    print(\"4- Eliminar\")\n    print(\"5- Ver Agenda\")\n    print(\"Escriba 'Exit' para salir\\n\")\n    answer = input(\"Selecciona una opción: \")\n    \n    if answer == \"Exit\":\n        break\n    \n    elif int(answer) == 5:  # View Agenda\n        if len(agenda) == 0:\n            print(\"\\nAgenda Empty\\n\")\n        else:\n            for name, number in agenda.items():\n                print(f'Nombre: {name} -> Teléfono: {number}\\n')\n    \n    elif int(answer) == 1: # Insert\n        name = input(\"\\nEscriba el nombre: \")\n        if name in agenda.keys(): # Check name\n            print(\"\\nEste contacto esta agendado.\\n\")\n        else:\n            number_phone = input(\"Escriba el número de teléfono: \") # Check new number\n            number_len = len(number_phone)\n            while True:\n                if number_len > 0 and number_len <= 11 and number_phone.isnumeric(): # Check new number\n                    agenda[name] = int(number_phone)\n                    break\n                else:\n                    print(\"El número es incorrecto, repita de nuevo\")\n                    number_phone = input(\"Escriba el número de teléfono: \")\n                    number_len = len(number_phone)\n                    \n    \n    elif int(answer) == 2: # Search\n        print(\"\\nBuscar por: \\n1-Nombre: \\n2-Número:\")\n        answer = input(\"Inserte opción: \")\n       \n        if int(answer) == 1: \n            name = input(\"\\nEscriba el nombre: \")\n            if name in agenda.keys(): # Check name\n                print(f'\\nNombre: {name} -> Teléfono: {agenda[name]}\\n')\n            else:\n               print(\"\\nEl nombre no está agendado\\n\") \n        \n        elif int(answer) == 2:\n            number_phone = input(\"Escriba el número de teléfono: \") # Check new number\n            number_len = len(number_phone)\n            while True:\n                if number_len > 0 and number_len <= 11 and number_phone.isnumeric(): # Check new number\n                    \n                    if int(number_phone) in agenda.values():\n                        for name_1, number_1 in agenda.items(): # Search name link number phone\n                            if int(number_phone) == number_1:\n                                print(f'\\nNombre: {name_1} -> Teléfono: {number_1}\\n')\n                            break\n                    else:\n                        print(\"\\nEl número de teléfono no está agendado\\n\")\n                    break\n                else:\n                    print(\"El número es incorrecto, repita de nuevo\")\n                    number_phone = input(\"Escriba el número de teléfono: \")\n                    number_len = len(number_phone)\n\n            if int(number_phone) in agenda.values(): # Ch\n                for name_1, number_1 in agenda.items(): # Search name link number phone\n                    if int(number_phone) == number_1:\n                        print(f'\\nNombre: {name_1} -> Teléfono: {number_1}\\n')\n            else:\n                print(\"\\nEl número de teléfono no está agendado\\n\")\n\n    elif int(answer) == 3: # Update\n        print(\"\\nActualizar: \\n1-Nombre: \\n2-Número:\")\n        answer = input(\"Inserte opción: \")\n        \n        if int(answer) == 2:\n            name = input(\"Escriba el nombre: \")\n            if name in agenda.keys(): # Check name\n                number_phone = input(\"Escriba el número de teléfono: \") # Check new number\n                number_len = len(number_phone)\n                while True:\n                    if number_len > 0 and number_len <= 11 and number_phone.isnumeric(): # Check new number\n                        agenda[name] = int(number_phone) # Change Number\n                        break\n                    else:\n                        print(\"El número es incorrecto, repita de nuevo\")\n                        number_phone = input(\"Escriba el número de teléfono: \")\n                        number_len = len(number_phone)\n            else:\n                print(\"\\nEl nombre no está agendado\\n\")\n        \n        elif int(answer) == 1:\n            number_phone = input(\"Escriba el número de teléfono: \") # Check new number\n            number_len = len(number_phone)\n            while True:\n                if number_len > 0 and number_len <= 11 and number_phone.isnumeric(): # Check new number\n                    number = number_phone\n                    break\n                else:\n                    print(\"El número es incorrecto, repita de nuevo\")\n                    number_phone = input(\"Escriba el número de teléfono: \")\n                    number_len = len(number_phone)    \n            \n            name = input(\"Escriba el nombre: \")\n            if int(number) in agenda.values(): # Existe el numero\n                for name_1, number_1 in agenda.items():\n                    if int(number) == number_1:\n                        temp_name = name_1 # Nombre Viejo\n                        break\n                agenda[name] = int(number) # Nombre Nuevo\n                del agenda[temp_name] # Eliminando contancto con Nombre Viejo\n            else:\n                print(\"\\nEl número de teléfono no está agendado\\n\")\n    \n    elif int(answer) == 4: # Delete\n        print(\"\\nEliminar empleando: \\n1-Nombre: \\n2-Número:\")\n        answer = input(\"Inserte opción: \")\n\n        if int(answer) == 1:\n            name = input(\"\\nEscriba el nombre: \")\n            if name in agenda.keys(): # Check name\n                del agenda[name]\n            else:\n                print(\"\\nEl nombre no está agendado\\n\")\n        \n        elif int(answer) == 2:\n            number_phone = input(\"Escriba el número de teléfono: \") # Check new number\n            number_len = len(number_phone)\n            while True:\n                if number_len > 0 and number_len <= 11 and number_phone.isnumeric(): # Check new number\n                    number = number_phone\n                    break\n                else:\n                    print(\"El número es incorrecto, repita de nuevo\")\n                    number_phone = input(\"Escriba el número de teléfono: \")\n                    number_len = len(number_phone)\n\n            if int(number) in agenda.values(): # Existe el numero\n                for name_1, number_1 in agenda.items():\n                    if int(number) == number_1:\n                        break\n                del agenda[name_1] # Eliminando contancto con Nombre Viejo\n            else:\n                print(\"\\nEl número de teléfono no está agendado\\n\")\n\n    else: # No case\n        print(\"\\nElige una de las opciones\\n\")"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/rikmij.py",
    "content": "import os\nimport re\n\nprint('*'*7, 'ESTRUCTURAS DE DATOS EN PYTHON', '*'*7)\nprint('\\t--> LISTAS')\nlista_ejemplo = [\"Yoda\", \"Qui Gon Jinn\", \"Obi Wan\", \"Mace Windu\"]\nprint(lista_ejemplo)\n\nprint(\"\\n-> Agregar elementos a una lista\")\nlista_ejemplo.append(\"Anakin\")\nprint(lista_ejemplo)\n\nlista_ejemplo.insert(4, \"Ahsoka Tano\")\nprint(lista_ejemplo)\n\nlista_ejemplo.extend([\"Luke\", \"Rey\"])\nprint(lista_ejemplo)\n\nprint(\"\\n-> Borrar elementos de una lista\")\nlista_ejemplo.remove(\"Qui Gon Jinn\")\nprint(lista_ejemplo)\n\nlista_ejemplo.pop(2)\nprint(lista_ejemplo)\n\nprint(\"\\n-> Ordenar la lista\")\nlista_ejemplo.sort()\nprint(lista_ejemplo)\n\nprint(\"\\n-> Invertir la lista\")\nlista_ejemplo.reverse()\nprint(lista_ejemplo)\n\nprint(\"\\n-> Borrar toda la lista\")\nlista_ejemplo.clear()\nprint(lista_ejemplo)\n\n\nprint('\\n\\t--> SETS')\nset_ejemplo = set([\"Aragorn\", \"Légolas\", \"Gimli\", \"Gandalf\"])\nprint(set_ejemplo)\n\nprint(\"\\n-> Agregar elementos a un set\")\nset_ejemplo.add(\"Frodo\")\nprint(set_ejemplo)\n\nprint(\"\\n-> Combinar sets\")\nhobbits = {\"Sam\", \"Frodo\"}  # {} también declara sets\ncomunidad_anillo = set_ejemplo.union(hobbits)\nprint(comunidad_anillo)\n\ngollum_saruman = {\"Gollum\", \"Saruman\"}\ncomunidad_anillo.update(gollum_saruman)\nprint(comunidad_anillo)\n\n\nprint(\"\\n-> Borrar elementos a un set\")\ncomunidad_anillo.remove(\"Gollum\")\ncomunidad_anillo.discard(\"Saruman\")\ncomunidad_anillo.pop()\nprint(comunidad_anillo)\n\nprint(\"\\n-> Borrar un set\")\ncomunidad_anillo.clear()\nprint(comunidad_anillo)\n\n\nprint('\\n\\t--> TUPLES')\ntuple_ejemplo = (\"Mario\", \"Luigi\", \"Peach\")\nprint(tuple_ejemplo)\n\nprint('\\n-> \"Agregar\" elementos a un tuple (concatenar tuplas)')\ntoad_yoshi = (\"Toad\", \"Yoshi\")\nprint(tuple_ejemplo + toad_yoshi)\n\n\nprint('\\n\\t--> DICCIONARIOS')\ndicc_ejemplo = {\"Charmander\": \"Fuego\",\n                \"Squirtle\": \"Agua\",\n                \"Bulbasaur\": \"Planta\",\n                \"Pikachu\": \"Eléctrico\"}\nprint(dicc_ejemplo)\n\nprint('\\n-> Agregar elementos a un diccionario')\ndicc_ejemplo[\"Pidgey\"] = \"Volador\"\nprint(dicc_ejemplo)\n\nprint('\\n-> Borrar elementos a un diccionario')\ndicc_ejemplo.pop(\"Pidgey\")\nprint(dicc_ejemplo)\n\ndicc_ejemplo.popitem()\nprint(dicc_ejemplo)\n\nprint('\\n-> Actualización de un diccionario')\ndicc_2 = {\"Nidoran\": \"Veneno\", \"Beedrill\": \"Bicho\", \"Abra\": \"Psíquico\"}\n\ndicc_ejemplo.update(dicc_2)\n\nprint(dicc_ejemplo)\n\nprint(\"\\n-> Borrar un diccionario\")\ndicc_ejemplo.clear()\nprint(dicc_ejemplo)\n\n\nprint('\\n\\t','*'*13, \"EXTRA\", '*'*13)\n\ncontact_list = {}\n\ndef inicio():\n    print(\"\\n\\t~~ Agenda telefónica ~~\")\n\n    try:\n        option = int(input('''¿Qué quieres hacer?:\n            1.- Buscar contacto\n            2.- Añadir contacto\n            3.- Actualizar listado\n            4.- Borrar contacto\n            5.- Mostrar contactos\n            6.- Salir\\n-> '''))\n\n        if option == 1:\n            lookfor_contact()\n        \n        elif option == 2:\n            add_contact()\n        \n        elif option == 3:\n            update_contacts()\n        \n        elif option == 4:\n            delete_contacts()\n        \n        elif option == 5:\n            show_contacts()\n        \n        elif option == 6:\n            pass\n        \n        else:\n            print(\"Opción no válida\")\n            inicio()\n    \n    except ValueError:\n        print(\"Ingrese una opción válida\")\n        inicio()\n\n\ndef end_funct():\n    print(input(\"\\nPulsa cualquier tecla para volver al inicio\"))\n    os.system(\"cls\")\n    inicio()\n\n\ndef lookfor_contact():\n    if len(contact_list) == 0:\n        print(\"La lista de contactos está vacía\")\n    \n    else:\n        look_for = input(\"¿Quieres buscar por contacto (C) o por número (Num)?: \").lower()\n\n        while look_for != \"c\" and look_for != \"num\":\n            look_for = input(\"Opción no válida. ¿Por contacto (C) o por número(Num)?: \").lower()\n\n        if look_for == \"c\":\n            contact = input(\"¿Qué contacto quieres buscar?: \")\n        \n            if contact in contact_list:\n                print(f\"\\nAquí está el contacto que buscaba:\\n{contact} : {contact_list[contact]}\")\n                end_funct()\n            \n            else:\n                print(\"Ese contacto no está en la lista\")\n\n        elif look_for == \"num\":\n            contact_num = input(\"¿Cuál es el número del contacto?: \")\n\n            if contact_num in contact_list.values():\n                for name, number in contact_list.items():\n                    if str(number) == contact_num:\n                        print(f\"\\nEl número \\\"{number}\\\" pertenece a: {name}\")\n            else:\n                print(\"Ese número no coincide con ningún contacto\")\n            \n            end_funct()\n\n\ndef add_contact():\n    name = input(\"Ingrese nombre del contacto: \")\n    number = input(\"Ingrese el número del contacto: \")\n\n    if re.match(\"\\d{9}\", number):\n        contact_list[name] = number\n    else:\n        print(\"El formato de número no es válido. Introduce un número de 9 cifras\")\n    \n    end_funct()\n\n\ndef update_contacts():\n    update = input(\"Quieres actualizar algún contacto?: Sí(s) / No(n)\").lower()\n\n    if update == \"s\":\n        contact = input(\"¿Qué contacto quieres actualizar?\")\n\n        if contact in contact_list:\n            new_number = int(input(\"ingrese su número de teléfono\"))\n\n            if re.match(\"\\d{9}\", new_number):\n                contact_list[contact] = new_number\n        else:\n            print(\"No existe ese contacto\")\n        end_funct()\n    \n    elif update == \"n\":\n        end_funct()\n    \n    else:\n        while update != \"s\" or update != \"n\":\n            print(\"Opción no válida. Ingrese \\\"s\\\" o \\\"n\\\"\")\n            update_contacts()\n\ndef delete_contacts():\n    contact = input(\"¿Qué contacto quieres borrar?: \")\n\n    if contact in contact_list:\n        contact_list.pop(contact)\n    else:\n        print(\"Este usuario no existe\")\n    \n    end_funct()\n\n\ndef show_contacts():\n    for contact in contact_list.items():\n        print(contact)\n    \n    end_funct()\n\n\ninicio()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/santiago434c.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\n\"\"\"\n\n#ESTRUCTURAS\n\n#Listas\nlista = [1, 10, 100, 1000]\nprint(lista)\n\n#Inserción\nlista.append(88)\nprint(lista)\n\n#Actualizacion\nlista[0] = 23\n\n#Borrado\nlista.remove(10)\n\n#Ordenación\nlista.sort()\n\n#Tupla - Estructura inmutable\ntupla = (3, 90, 200, 301, 55)\nprint(tupla)\n\n#Acceso\nprint(tupla[3])\n\n#Ordenacion de Tupla\ntupla = tuple(sorted(tupla))\nprint(tupla)\nprint(type(tupla))\n\n#Set - No ordenada - No admite duplicados - No se puede acceder a una posicion\nmi_set = {1 , 5, 9, 22, 4}\nprint(mi_set)\n\n#Insercion\nmi_set.add(\"KDB\")\nprint(mi_set)\n\n#Actualizacion - Añadir mas datos\n#mi_set.update()\n\n#Borrado\nmi_set.remove(5)\nprint(mi_set)\n\n#Ordenacion - los set no tiene orden\n\n#Diccionario\ndic = {\"name\" : \"Diego\",\n        \"age\" : 35,\n        \"job\" : \"Trucker\",\n        \"height (m)\" : 1.70,\n        \"active\" : True}\n\nprint(dic)\n\n#Insercion\ndic[\"brand\"] = \"JRR10\"\nprint(dic)\n\n#Eliminacion\ndel dic[\"job\"]\nprint(dic)\n\n#Actualizacion\ndic[\"height (m)\"] = 1.75\nprint(dic)\n\n#Ordenacion\ndic = dict(sorted(dic.items()))\nprint(dic)\nprint(type(dic))\n\n\n#Extra\n\nagenda = {\"james\" : 12345678901,\n          \"karim\" : 98765432122,\n           \"moran\": 12345987600}\n\ndef acciones_agenda():\n    #pedir al usuario que accion desea relaizar\n    print(\"1 Insertar \\n 2 Eliminar \\n 3 Actualizar \\n 4 Buscar \\n 5 Salir\")\n    accion = int(input(\"Ingrese la accion que desea realizar: \"))\n    #Insertar\n    if accion == 1:\n        nombre = input(\"Ingrese el nombre del contacto que desea insertar: \")\n        numero = input(\"Ingrese el nuevo numero de 11 digitos: \")\n        if len(numero) == 11 and numero.isdigit() == True: #Control tamaño del numero \n            agenda[nombre] = numero\n            print(agenda)\n            acciones_agenda()\n        else: #Insertar numero valido\n            print(\"El numero no es valido - debe tener 11 digitos unicamente numeros\")\n            print(type(numero))\n            acciones_agenda()\n    #Eliminar\n    elif accion == 2:\n        nombre = input(\"Ingrese el nombre del contacto que desea eliminar: \")\n        try: #Trata de eliminar el contacto\n            del agenda[nombre]\n            print(agenda)\n            acciones_agenda()\n        except: #Si no existe el contacto\n            print(f\"La accion no se pudo completar, revise los datos ingresados \\n No exite el contacto: {nombre}\")\n            acciones_agenda()\n    #Actualizar\n    elif accion == 3:\n        nombre = input(\"Ingrese el nombre del contacto que desea actualizar: \")\n        if nombre in agenda: #Comprobar si exite el contacto a actualizar\n            numero = input(\"Ingrese el nuevo numero de 11 digitos: \")\n            if len(numero) == 11 and numero.isdigit() == True: #Control tamaño del numero\n              agenda[nombre] = numero\n              print(agenda)\n              acciones_agenda()\n            else: #Errores de tamaño del numero o str\n              print(\"El numero no es valido - debe tener 11 digitos unicamente numeros\")\n              acciones_agenda()\n        else: #Si no existe el contacto\n            print(f\"La accion no se pudo completar, revise los datos ingresados \\n No exite el contacto: {nombre}\")\n            acciones_agenda()\n    #Buscar\n    elif accion == 4:\n        nombre = input(\"Ingrese el nombre del contacto que desea consultar: \")\n        try: #Traer el numero del contacto\n            print(agenda[nombre])\n            acciones_agenda()\n        except: #Si no existe el contacto\n            print(f\"La accion no se pudo completar, revise los datos ingresados. \\n No exite el contacto: {nombre}\")\n            acciones_agenda()\n    #Salir\n    elif accion == 5:\n        print(\"Gracias por usar la agenda\")\n    #Error de accion\n    else:\n        print(\"La opcion ingresada no es valida\")\n        acciones_agenda()\n\nacciones_agenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/santiagobailleres.py",
    "content": "''' * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.'''\n\n# Creación de estructuras de datos\n# Listas\nlist=[1,2,3,4,5]\nprint(\"Lista:\",list)\n# Inserción\nlist.append(6)\nprint(\"Lista con inserción:\",list)\n# Borrado\nlist.remove(6)\nprint(\"Lista con borrado:\",list)\n# Actualización\nlist[1]=0\nprint(\"Lista con actualización:\",list)\n# Ordenación\nlist.sort()\nprint(\"Lista ordenada:\",list)\n# Inversión\nlist.reverse()\nprint(\"Lista invertida:\",list)\n# acceso\nprint(\"Elemento en la posición 2:\",list[2])\nprint('Tipo :' , type(list))\n\n# Tuplas\ntuple_=(1,2,3,5,4)\nprint(\"Tupla:\",tuple_)\n# No se pueden modificar, borrar o actualizar\n# Ordenación\ntuple2=sorted(tuple_) # devuelve una lista ordenada\ntuple=tuple(sorted(tuple_)) # convierte la lista ordenada en tupla\nprint(\"Tupla ordenada:\",tuple)\n# acceso\nprint(\"Elemento en la posición 2:\",tuple[2])\nprint('Tipo :' , type(tuple))\n\n# Diccionarios\ndict_={\"Nombre\":\"Santiago\",\"Apellido\":\"Bailleres\"}\nprint(\"Diccionario:\",dict_)\n# Inserción\ndict_[\"Edad\"]=25\nprint(\"Diccionario con inserción:\",dict_)\n# Borrado\ndel dict_[\"Edad\"]\nprint(\"Diccionario con borrado:\",dict_)\n# Actualización\ndict_[\"Nombre\"]=\"Santiago Bailleres\"\nprint(\"Diccionario con actualización:\",dict_)\n# Ordenación\ndict2=sorted(dict_) # devuelve una lista ordenada\ndict3=dict(sorted(dict_.items())) # es necesario poner .items()? \n# si no se pone .items() da error porque no se puede ordenar un diccionario\n# convierte la lista ordenada en diccionario\nprint(\"Diccionario ordenado:\",dict3)\n# acceso\nprint(\"Valor de la clave 'Nombre':\",dict_[\"Nombre\"])\nprint('Tipo :' , type(dict_))\ndicc= {1: 2, 2: 4, 3: 1}\ndicc=dict(sorted(dicc.items())) #se puede ordenar un diccionario por clave o por valor\nprint('Diccionario ordenado por clave:',dicc)\n# si se ordena por valor se debe hacer asi:\ndicc=dict(sorted(dicc.items(), key=lambda x: x[1])) # x[1] es el valor de cada par clave-valor\nprint('diccionario ordenado por valor:',dicc)\n# si se quieren reestablecer las claves se puede hacer asi:\ndicc=dict(enumerate(dicc.values(),1)) # se enumeran los valores empezando en 1\nprint('diccionario con claves reestablecidas:',dicc)\n\n# Conjuntos\nset={1,2,3,4,5} # un conjunto no puede tener elementos duplicados y no tiene orden\n# es util para eliminar duplicados de una lista o tupla y para realizar operaciones de conjuntos\n# como union, interseccion, diferencia, etc.\nprint(\"Conjunto:\",set)\n# Inserción\nset.add(6)\nprint(\"Conjunto con inserción:\",set)\n# Borrado\nset.remove(6)\nprint(\"Conjunto con borrado:\",set)\n# Actualización\nset.add(0)\nprint(\"Conjunto con actualización:\",set)\n# Ordenación\n# no se puede ordenar un conjunto\n# acceso\n# no se puede acceder a un elemento por su posición\nprint('Tipo :' , type(set))\n# Operaciones de conjuntos\nset2={4,5,6,7,8}\nprint(\"Conjunto 2:\",set2)\nprint(\"Union:\",set.union(set2))\nprint(\"Intersección:\",set.intersection(set2))\nprint(\"Diferencia:\",set.difference(set2)) \nprint(\"Diferencia simétrica:\",set.symmetric_difference(set2))\nprint(\"Subconjunto:\",set.issubset(set2)) # para que sea subconjunto todos los elementos de set deben estar en set2\nprint(\"Superconjunto:\",set.issuperset(set2)) # para que sea superconjunto todos los elementos de set2 deben estar en set\nprint(\"Disjuntos:\",set.isdisjoint(set2)) # si no tienen elementos en común\n\n# EXTRA\n'''Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.'''\n# Agenda de contactos\ndef mi_agenda():  \n    agenda={}\n    while True:\n        print('')\n        print('1. Buscar contacto')\n        print('2. Insertar contacto')\n        print('3. Actualizar contacto')\n        print('4. Eliminar contacto')\n        print('5. Mostrar agenda')\n        print('6. Salir')\n        option=input('\\nSeleccione una opción: ')\n        if option=='1':\n            name=input('Ingrese el nombre del contacto que desea buscar: ')\n            if name in agenda:\n                print(f'Nombre: {name}, Teléfono: {agenda[name]}')\n            else:\n                print('Contacto no encontrado')\n        elif option=='2':\n            name= input('Ingrese el nombre del contacto que desea insertar: ')\n            phone=input('Ingrese el teléfono del contacto: ')\n            if phone.isdigit() and len(phone)<=11 and len(phone)>0:\n                agenda[name]=phone\n                print('Contacto insertado')\n            else:\n                print('El número de teléfono debe ser numérico y tener máximo 11 dígitos')\n        elif option=='3':\n            name=input('Ingrese el nombre del contacto que desea actualizar: ')\n            if name in agenda:\n                phone=input('Ingrese el nuevo teléfono del contacto: ')\n                if phone.isdigit() and len(phone)<=11 and len(phone)>0:\n                    agenda[name]=phone\n                    print('Contacto actualizado')\n                else:\n                    print('El número de teléfono debe ser numérico y tener máximo 11 dígitos')\n            else:\n                print('Contacto no encontrado')\n        elif option=='4':\n            name = input('Ingrese el nombre del contacto que desea eliminar: ')\n            if name in agenda:\n                del agenda[name]\n                print('Contacto eliminado')\n            else:\n                print('Contacto no encontrado')\n        elif option=='5':\n            print('Agenda de contactos:')\n            for name,phone in agenda.items():\n                print(f'Nombre: {name}, Teléfono: {phone}')\n        elif option=='6':\n            print('Saliendo de la agenda...')\n            break\n        else:\n            print('Opción no válida, ingrese un número del 1 al 6')\nmi_agenda()\n\n\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/santiagobima.py",
    "content": "#Muestra  ejemplos de creacion de todas las estructuras soportadas por defecto en tu lenguaje\n\n#lista: Estructura ordenada / también conocido como array , en python como tal Array en python no exite.\n#ordenada y modificable. Su orden es su orden de insercion de los elementos.\n\nlista = ['carlos','pedro','santiago','marcos','maria']\nprint(lista)\n\nlista.append('fabiana') #insercion\n\nlista.remove('carlos') #borrar\n\nprint(lista[1])\n\nlista[1] = 'antonella'\n\nlista[0] = 'geremy'\n\nlista.sort()   ###ordenacion### #por defecto de forma ascendente y alfabetica \n\nprint(lista)\nprint(type(lista))\n\n\n#TUPLAS // Se usan en estructuras de datos rígidos para no meter la mano.\n\nmitupla= ('fabiana','victoria','40','boligrafo')\n\nprint(mitupla[0])\nprint(mitupla[1])\nmitupla = tuple(sorted(mitupla)) ##LO que nos devuelve es una lista si solo dejo sorted.!! Ademas tuve que poner el 40 en string. sino no lo deja acomodar.\nprint(type(mitupla))\n\n\n#SETS\n#Estructura no ordenada pero no permite duplicados.\n#EL SET POR DEFINICION ES UNA ESTRUCTURA DESORDENADA ! ! NO ME PUEDO FIAR DE LA POSICION DE UN ELEMENTO !!\n\n#Sets no tengo operacion de acceso !!!  No hay nada que me asegure que va haber en esa posición.\n\n\nmiset = {'3434','13435','40349','549340','santiago'}\nmiset.add('jorge')\nmiset.add('jorge') ###NO lo va a dejar de duplicar.\nmiset.add('santiago@gmail.com')\nmiset.remove('3434') #La eliminacion si funciona !!!\n#Lo mejor si quiero reemplazar un dato es elimianr ese dato y agregar otro.\n\nmiset = set(sorted(miset)) #Por deficiion el set no se puede ordenar. No es una estructura ordenada.!\n\nprint(type(miset))\nprint(miset)\n\n\n\n#Por definicion los diccionarios no son ordenados pero en realidad si acaba siendo ordenados por la forma en que en python han decidido que sean ordenados pero ha sudio una decision de implementacion. Por eso solo puedo acceder a valores por clave.\n\ndiccionario = {'nombre':'santiago','edad':37,'nacionalidad': 'hungaro'}\n\ndiccionario['idioma'] = 'ingles' #agrego un valor.\n\ndiccionario['nombre'] = 'jeremy' #modifico un valor.\n\ndel diccionario['edad'] #elimino #del es una operacion reservada del sistema.\n\n#si solo le paso sorted solo pilla las claves\ndiccionario = dict(sorted(diccionario.items())) #acabo terminando esta lista de tuplas en un diccionario. \n\nprint(type(diccionario))\nprint(diccionario)\n\n\n#BONUS -->>>:  D IFI CULTA D EX TR A \n\ndef telefono(nombre,agenda):\n    \n    numero = input('dame el numero')\n    if numero.isdigit() and len(numero) <= 11:\n        \n        agenda[nombre] = numero\n        \n    else:\n        print('no cumple con los requisitos basicos')\n                 \ndef agendita():\n    \n    agenda = {}\n          \n    while True:\n        \n        print(\"1. Buscar contacto\")\n        print(\"2. Insertar contacto\")\n        print(\"3. Actualizar contacto\")\n        print(\"4. Eliminar contacto\")\n        print(\"5. Salir\")\n        \n        opcion = input('\\ndame un numero y vamos a ver ')\n        \n        #En PYTHON EL SWICHT SE LLAMA MATCH:\n        \n        match opcion:\n            \n            case '1':\n                nombre = input('dame el nombre a buscar')\n                if nombre in agenda:\n                    print(nombre)\n                    \n                else:\n                    print('no esta en la agenda')\n                    \n            case '2':\n                nombre = input('dame el nombre a agregar')\n                \n                telefono(nombre,agenda)\n                \n            case'3':\n                \n               nombre = input('dame el nombre a actualizar')\n               if nombre in agenda:\n                   telefono(nombre,agenda)\n               else:\n                   print('no existe')\n                    \n            \n            case '4':\n                \n               name = input('dime a quien debemos eliminar')\n               \n               if name in agenda:\n                   del agenda[name] \n                   \n               else:\n                   print(f'el contadto {name} no existe bro')\n                \n            case '5':\n                print('saliendo del programa')\n                break\n            case _:\n                print('Opcion no valida. Elige una opcion del 1 al 5.')\n                \n\nif __name__ == '__main__':\n    agendita()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/santyjL.py",
    "content": "#03 ESTRUCTURAS DE DATOS\n\"\"\"\n/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n *   y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n *   y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más\n *   de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.\n */\n\"\"\"\n\n#listas\ndef listas ():\n    lista : list= [1,2,3,4,5,6,7,8,9,10]\n    print(\"lista original : \" , lista)\n\n    #inserción\n    lista.append(11) #agrega al final\n    lista.insert(0 , 0) #agrega elemento con el indice\n    print(\"inserción : \" , lista )\n\n    #borrado\n    lista.pop(-1) #elimina segun el indice\n    lista.remove(0) #elimina por el valor/elemento\n    print(\"borrado : \" , lista )\n\n    #actualización\n    lista[0] = 4\n    print(\"actualización : \" , lista )\n\n    #ordenación\n    lista.sort(reverse=True)#de mayor a menor\n    print(\"de mayor a menor:\" , lista)\n    lista.sort(reverse=False)#de menor a mayor\n    print(\"de menor a mayor:\" , lista)\n\n\ndef tuplas():\n    tupla : tuple = 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 # tambien se pueden crear haci (1,2,3,4,5...)\n    print(\"tupla original\" , tupla)\n\n    #acceso de elemento\n    print(\"acceso a tupla : \" , tupla[2])#igual que las listas\n\n    #concatenacion\n    print(\"tupla concatenada : \" , tupla + (11 , 12, 13))\n\n    #ordenación\n    print(\"de mayor a menor:\" , sorted(tupla , reverse=True))#con la funcion sorted\n    print(\"de menor a mayor:\" , sorted(tupla))\n\n\ndef conjuntos():\n    conjunto : set = {1,2,3,4,5,6,7,8,9,10}\n    print(\"conjunto original\" , conjunto)\n\n    #inserción\n    conjunto.add(11)\n    conjunto.add(0)\n    print(\"inserciones : \", conjunto)\n\n    #borrado\n    conjunto.remove(11)\n    print(\"borrado remove : \" , conjunto)\n    conjunto.pop()\n    print(\"borrado pop\" , conjunto)\n\n    #actualización\n    conjunto.update({11,12,13})\n    print(\"actualización : \" , conjunto)\n\n\ndef diccionarios():\n    diccionario: dict ={\"nombre\" : \"apellido\",\n                        \"Homero\" : \"Simpson\",\n                        \"Brais\" : \"moure\"}\n\n    print(\"diccionario original : \" , diccionario)\n\n    #inserción\n    diccionario[\"nombre_nuevo\"] = \"nuevo apellido\"#nueva clave y valor\n    print(\"inserción : \" , diccionario)\n\n    #borrado\n    diccionario.pop(\"nombre_nuevo\") #con pop se elimina el valor que pide es la clave\n    print(\"borrado : \" , diccionario)\n\n    #actualizacion\n    diccionario[\"santiago\"] = diccionario.pop(\"nombre\") #para actualizar la clave\n    diccionario[\"santiago\"] = \"Lopez\" #para actualizar el valor\n    print(\"actualizacion : \" , diccionario)\n\n\nprint(\"\\n-----------Listas---------------\")\nlistas()\nprint(\"\\n-----------Tuplas---------------\")\ntuplas()\nprint(\"\\n-----------conjuntos---------------\")\nconjuntos()\nprint(\"\\n-----------diccionarios---------------\")\ndiccionarios()\nprint(\"\\n\\n\")\n\n\n\n### Extra\ncontactos : dict = {\n        \"fernandez\" : \"1111 1111\",\n        \"julieta\" : \"2222 2222\",\n        \"jose\" : \"3333 3333\",\n        \"juancho\" : \"4444 4444\",\n        }\n\n\ndef busqueda():\n\n    key = input(\"Introduzca el nombre del contacto : \")\n    if key in contactos:\n        print(f\"{key} - {contactos[key]}\")\n    else :\n        print(\"contacto no existente\")\n\n\ndef inserción():\n\n    nombre = input(\"Ingrese el nombre del nuevo contacto: \")\n    numero = input(\"Ingrese el número de teléfono: \")\n\n    if numero.isdigit() and len(numero) <= 11:\n\n        contactos[nombre] = numero\n        print(f\"Contacto {nombre} añadido correctamente.\")\n\n    else:\n        print(\"Número de teléfono no válido. Asegúrate de ingresar un número numérico máximo de 11 dígitos.\")\n\n\ndef actualizacion():\n\n    antiguo_nombre=input(\"introduzca el nombre a cambiar : \")\n    nuevo_nombre=input(\"introduzca el nuevo nombre : \")\n\n    if antiguo_nombre in contactos:\n\n        contactos[nuevo_nombre] = contactos.pop(antiguo_nombre)\n        print(\"se cambio correctamente\")\n\n    else : print(\"el contacto a cambiar no existe\")\n\n\ndef eliminar():\n\n    nombre = input(\"introduzca el nombre a eliminar : \")\n\n    if nombre in contactos:\n        contactos.pop(nombre)\n        print(\"se elimino correctamente\")\n\n    else : print(\"contacto no existente , intente de nuevo\")\n\n\nwhile True:\n    print(\"\"\"\\nLista de contactos\n                Acciones :\n                1.mirar contactos\n                2.buscar contactos\n                3.añadir contactos\n                4.actualizar contactos\n                5.eliminar contactos\n                6.cerrar lista de contactos\"\"\")\n    opcion = int(input(\"eliga segun el indice : \"))\n\n    try :\n\n        if opcion == 1 :\n            for contacto , numero in contactos.items():\n                print(f\"{contacto} -- {numero}\")\n\n        elif opcion == 2 :\n            busqueda()\n\n        elif opcion == 3 :\n            inserción()\n\n        elif opcion == 4 :\n            actualizacion()\n\n        elif opcion == 5 :\n            eliminar()\n\n        elif opcion == 6 :\n            print(\"progama finalizado\")\n            break\n\n        else :\n            print(\"no esta en el indice\")\n\n    except Exception as error :\n        print(\"a sucedido un error , Error : \" , error)\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/sarismejiasanchez.py",
    "content": "# #03 ESTRUCTURAS DE DATOS\n\n# Lists\n\"\"\"\nList: is a collection which is ordered and changeable(modifiable). \nAllows duplicate members.\n\"\"\"\nprint(\"Lists\\n\")\n# Crear una lista\nfruits = list()\nvegetables = []\nprint(type(fruits))\nprint(type(vegetables))\n\nfruits = ['banana', 'orange', 'mango', 'lemon']                     # list of fruits\nvegetables = ['Tomato', 'Potato', 'Cabbage','Onion', 'Carrot']      # list of vegetables\nprint(f\"Fruits: {fruits}\")\nprint(f\"Vegetables: {vegetables}\")\n\n# Modifying Lists\n# List is a mutable or modifiable ordered collection of items. Lets modify the fruit list.\nfruits[1] = \"watermelon\"\nprint(f\"Fruits: {fruits}\")\n\n# Adding Items to a List\n# To add item to the end of an existing list we use the method append().\nfruits.append(\"apple\")\nprint(f\"Fruits: {fruits}\")\n\n# Inserting Items into a List\n\"\"\"\nWe can use insert() method to insert a single item at a specified index in a list. \nNote that other items are shifted to the right. \nThe insert() methods takes two arguments:index and an item to insert.\n\"\"\"\nfruits.insert(2, 'pineapple') # insert pineapple between watermelon and mango\nprint(f\"Fruits: {fruits}\")\n\n# Removing Items from a List\n# The remove method removes a specified item from a list\nfruits.remove(\"banana\")\nprint(f\"Fruits: {fruits}\")\n\n# Removing Items Using Pop\n# The pop() method removes the specified index, (or the last item if index is not specified):\nfruits.pop() # Remove de last item\nprint(f\"Fruits: {fruits}\")\nfruits.pop(2) # Remove index 3 (lemon)\nprint(f\"Fruits: {fruits}\")\n\n# Removing Items Using Del\n\"\"\"\nThe del keyword removes the specified index and it can also be used to delete items within index range. \nIt can also delete the list completely\n\"\"\"\ndel fruits[0]\nprint(f\"Fruits: {fruits}\")\n#del fruits\n#print(fruits)       # This should give: NameError: name 'fruits' is not defined\n\n# Clearing List Items\n# The clear() method empties the list:\nfruits.clear()\nprint(f\"Fruits: {fruits}\")      # []\n\n\n\n\n# Tuples\n\"\"\"\nTuple: is a collection which is ordered and unchangeable or unmodifiable(immutable). \nAllows duplicate members.\n\"\"\"\nprint(\"\\nTuples\")\n\n# Creating a Tuple\nfruits = ()\nvegetables = tuple()\nprint(type(fruits))\nprint(type(vegetables))\n\n# Changing Tuples to Lists\nfruits = ('banana', 'orange', 'mango', 'lemon')\nfruits = list(fruits)\nfruits[0] = 'apple'\nfruits.append(\"watermelon\")\nprint(f\"Fruits List: {fruits}\")     # ['apple', 'orange', 'mango', 'lemon']\nfruits = tuple(fruits)\nprint(f\"Fruits Tuple: {fruits}\")     # ('apple', 'orange', 'mango', 'lemon')\n\n# Joining Tuples\n# We can join two or more tuples using + operator\nfruits = ('banana', 'orange', 'mango', 'lemon')\nvegetables = ('Tomato', 'Potato', 'Cabbage','Onion', 'Carrot')\nfruits_and_vegetables = fruits + vegetables\nprint(f\"Fruits and Vegetables: {fruits_and_vegetables}\")\n\n# Sorted\nprint(f\"Fruits Ordenado: {sorted(fruits)}\")\n\n# Deleting Tuples\n\"\"\"\nIt is not possible to remove a single item in a tuple \nbut it is possible to delete the tuple itself using del.\n\"\"\"\nfruits = ('banana', 'orange', 'mango', 'lemon')\ndel fruits\n#print(fruits) # NameError: name 'fruits' is not defined\n\n\n\n# Sets\n\"\"\"\nSet: is a collection which is unordered, un-indexed and unmodifiable, but we can add new items to the set. \nDuplicate members are not allowed.\n\"\"\"\nprint(\"\\nSets\")\n\n# Creating a Set\nfruits = set()\nvegetables = {'tomato', 'potato', 'cabbage','onion', 'carrot'}\nprint(type(fruits))\nprint(type(vegetables))\n\n# Adding Items to a Set\n# Add one item using add()\nvegetables.add(\"avocado\")\nprint(f\"Vegetables: {vegetables}\")\n\n\"\"\"\nAdd multiple items using update() The update() allows to add multiple items to a set. \nThe update() takes a list argument.\n\"\"\"\nfruits.update([\"mango\", \"banana\", \"watermelon\"])\nprint(f\"Fruits: {fruits}\")\n\n# Removing Items from a Set\n\"\"\"\nWe can remove an item from a set using remove() method. \nIf the item is not found remove() method will raise errors, \nso it is good to check if the item exist in the given set. \nHowever, discard() method doesn't raise any errors.\n\"\"\"\nvegetables.remove(\"cabbage\")\nprint(f\"Vegetables: {vegetables}\")\n\n# vegetables.remove(\"potatoes\") # KeyError: 'potatoes'\n# print(f\"Vegetables: {vegetables}\")\n\nvegetables.discard(\"potatoes\")\nprint(f\"Vegetables: {vegetables}\")\n\n# Clearing Items in a Set\n# If we want to clear or empty the set we use clear method.\nfruits.clear()\nprint(f\"Fruits: {fruits}\")  # Fruits: set()\n\n# Deleting a Set\n# If we want to delete the set itself we use del operator.\ndel fruits\n# print(f\"Fruits: {fruits}\")  # NameError: name 'fruits' is not defined\n\n# Converting List to Set\nfruits = ['banana', 'orange', 'mango', 'lemon','orange', 'banana']\nprint(f\"Fruits: {fruits}\") \nfruits = set(fruits) # {'mango', 'lemon', 'banana', 'orange'}\nprint(f\"Fruits: {fruits}\") \n\n\n# Dictionaries\n\"\"\"\nDictionary: is a collection which is unordered, changeable(modifiable) and indexed. \nNo duplicate members.\n\"\"\"\nprint(\"\\nDictionaries\")\n\n# Creating a Dictionary\nperson = {}\nprint(type(person))\nperson = {\n    'first_name':'Sara',\n    'last_name':'Mejia',\n    'age':31,\n    'country':'Colombia',\n    'skills':['PL/SQL', 'Oracle Apex', 'Python'],\n    'address':{\n        'street':'Medellin',\n        'zipcode':'050001'\n    }\n    }\nprint(type(person))\nprint(person)\n\n# Adding Items to a Dictionary\nperson['job_title'] = 'Especialista en Programación Aplicada'\nprint(f\"job_title: {person['job_title']}\")\nperson['skills'].append('RPA')\nprint(f\"skills: {person['skills']}\")\nprint(person)\n\n# Modifying Items in a Dictionary\nperson['first_name'] = 'Maria'\nprint(f\"first_name: {person['first_name']}\")\n\n# Removing Key and Value Pairs from a Dictionary\n\"\"\"\npop(key): removes the item with the specified key name:\npopitem(): removes the last item\ndel: removes an item with specified key name\n\"\"\"\nperson.pop('age')\nprint(person)\n\nperson.popitem()\nprint(person)\n\ndel person['country']\nprint(person)\n\n# Clearing a Dictionary\nperson.clear()\nprint(f\"Person: {person}\") # Person: {}\n\n# Deleting a Dictionary\ndel person\n# print(f\"Person: {person}\") # NameError: name 'person' is not defined\n\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n\"\"\"\n\ndef my_agenda():\n\n    agenda = {}\n\n    \"\"\"\n    Cada contacto debe tener un nombre y un número de teléfono.\n    \"\"\"\n    def insert_contact():\n        phone = input(\"Introduce el teléfono del contacto: \")\n        \"\"\"\n        El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n        (o el número de dígitos que quieras)\n        \"\"\"\n        if phone.isdigit() and len(phone) > 0 and len(phone) <= 11:\n            agenda[name] = phone\n        else:\n            print(\n                \"Debes introducir un número de teléfono un máximo de 11 dígitos.\")\n\n    while True:\n        \"\"\"\n        Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n        \"\"\"\n        print(\"\")\n        print(\"1. Buscar contacto\")\n        print(\"2. Insertar contacto\")\n        print(\"3. Actualizar contacto\")\n        print(\"4. Eliminar contacto\")\n        print(\"5. Salir\") # También se debe proponer una operación de finalización del programa.\n\n        \"\"\"\n        El programa solicita en primer lugar cuál es la operación que se quiere realizar, \n        y a continuación los datos necesarios para llevarla a cabo.\n        \"\"\"\n        option = input(\"\\nSelecciona una opción: \")\n\n        match option:\n            case \"1\":\n                name = input(\"Introduce el nombre del contacto a buscar: \")\n                if name in agenda:\n                    print(\n                        f\"El número de teléfono de {name} es {agenda[name]}.\")\n                else:\n                    print(f\"El contacto {name} no existe.\")\n            case \"2\":\n                name = input(\"Introduce el nombre del contacto: \")\n                insert_contact()\n            case \"3\":\n                name = input(\"Introduce el nombre del contacto a actualizar: \")\n                if name in agenda:\n                    insert_contact()\n                else:\n                    print(f\"El contacto {name} no existe.\")\n            case \"4\":\n                name = input(\"Introduce el nombre del contacto a a eliminar: \")\n                if name in agenda:\n                    del agenda[name]\n                    print(f\"Se eliminó el contacto {name}.\")\n                else:\n                    print(f\"El contacto {name} no existe.\")\n            case \"5\":\n                print(\"Saliendo de la agenda.\")\n                break\n            case _:\n                print(\"Opción no válida. Elige una opción del 1 al 5.\")\n\nmy_agenda()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/sniker1223.py",
    "content": "my_list = [\"orange\", \"apple\", \"banana\"]\nprint(my_list)\nmy_list.append(\"grape\")  # Insert\nprint(my_list)\nmy_list.remove(\"orange\")  # Remove\nprint(my_list)\nprint(my_list[1])  # Get\nmy_list[1] = \"watermelon\"  # Update\nprint(my_list)\nmy_list.sort()  # Sort\nprint(my_list)\n\n# Tuple\nmy_tuple: tuple = (\"orange\", \"apple\", \"banana\", \"3\")\nprint(my_tuple[1])  # Access\nmy_tuple = tuple(sorted(my_tuple))  # Sort\nprint(my_tuple)\nprint(type(my_tuple))\n\n# Sets\nmy_set = {\"orange\", \"apple\", \"banana\", \"3\"}\nprint(my_set)\nmy_set.add(\"sniker@gmail.com\")  # Insert\nprint(my_set)\nmy_set.remove(\"orange\")  # Remove\nprint(my_set)\nmy_set = set(sorted(my_set))  # It can't sorted\nprint(my_set)\nprint(type(my_set))\n\n# Dictionary\nmy_dict: dict = {\n    \"name\": \"Sniker\",\n    \"surname\": \"Dev\",\n    \"age\": \"20\"\n}\nmy_dict[\"email\"] = \"sniker@gmail.com\"  # Insert\nprint(my_dict)\ndel my_dict[\"surname\"]  # Remove\nprint(my_dict)\nprint(my_dict[\"name\"])  # Access\nmy_dict[\"age\"] = \"43\"  # Update\nprint(my_dict)\nmy_dict = dict(sorted(my_dict.items()))\nprint(my_dict)\nprint(type(my_dict))\n\n\"\"\"\nExtra\n\"\"\"\n\ndef my_contacts():\n  \n  contacts = {}\n  \n  while True:\n    \n    print(\"\")\n    print(\"1. Search contact\")\n    print(\"2. Enter contact\")\n    print(\"3. Update contact\")\n    print(\"4. Remove contact\")\n    print(\"5. Exit\")\n\n    option = input(\"\\nSelect an option: \")\n    \n    match option:\n      case \"1\":\n        name = input(\"Enter the name of the contact to search \")\n        if name in contacts:\n          print(f\"The phone number of the {name} is {contacts[name]}\")\n        else:\n          print(f\"The contact {name} doesnt exist\")\n      case \"2\":\n        name = input(\"\\nEnter contact name: \")\n        phone = input(\"\\nEnter contact phone: \")\n        if phone.isdigit() and len(phone) > 0 and len(phone) <= 10:\n          contacts[name] = phone\n        else:\n          print(\"You must enter a phone with a maximum of 11 digits\")\n      case \"3\":\n        name = input(\"Enter the name of the contact to update \")\n        phone = input(\"\\nEnter contact phone: \")\n        if phone.isdigit() and len(phone) > 0 and len(phone) <= 10:\n          contacts[name] = phone\n        else:\n          print(\"You must enter a phone with a maximum of 10 digits\")\n      case \"4\":\n        name = input(\"Enter the name of the contact to remove \")\n        if name in contacts:\n          del contacts[name]\n      case \"5\":\n        print(\"Exit of contacts\")\n        break\n      case _:\n        print(\"Select a valid option\")\n\nmy_contacts()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/sorubadguy.py",
    "content": "\"\"\"\nEstructuras\n\"\"\"\n\n\"\"\"\n#Listas\n\"\"\"\n\nlista_vacia = []\nfrutas = [\"manzana\", \"naranja\", \"mandarina\", \"durazno\"]\nprint(lista_vacia)\nprint(type(frutas))\nprint(frutas)\n\n#Agregar un elemento al final\n\nfrutas.append(\"melon\")\nprint(\"\\nagrego melon\")\nprint(frutas)\n\n#Agregar un elemento en el lugar deseado\nprint(\"\\nagrego Anana\")\nfrutas.insert(2, \"anana\")\nprint(frutas)\n\n#Eliminar elemento de la lista\nprint(\"\\nElimino naranja\")\nfrutas.remove(\"naranja\")\nprint(frutas)\n\n#Ordeno los items de la lista\nprint(\"\\nOrdeno los elementos de la lista\")\nfrutas.sort()\nprint(frutas)\n\n#Invierto el orden de los elementos de la lista\nprint(\"\\nInvierto el orden de los elementos de la lista\")\nfrutas.reverse()\nprint(frutas)\n\n#Actualizacion\nprint(\"\\nActualizo el segundo item\")\nfrutas[1] = \"pera\"\nprint(frutas)\n\n#Eliminar todos los elementos de la lista\nprint(\"\\nVacio la lista\")\nfrutas.clear()\nprint(frutas)\n\n\"\"\"\nTuplas\n\"\"\"\n\ntupla_vacia = ()\nanimales = (\"gato\", \"perro\", \"oso\")\nprint(type(animales))\nprint(tupla_vacia)\nprint(animales)\nprint(animales[2]) #acceder\n\n#Ordenar\nanimales = tuple(sorted(animales))\nprint(animales)\n\n\"\"\"\nSet\n\"\"\"\nset_vacio = {}\nnombres = {\"Lucas\",\"Carlos\",\"Alfredo\",\"Ramon\"}\nprint(set_vacio)\nprint(type(nombres))\nprint(nombres)\nprint(len(nombres))\n\n#Agrego elemento\nnombres.add(\"Alejandro\")\nprint(nombres)\n\n#Quito Elemento\nnombres.remove(\"Carlos\")\nprint(nombres)\n\n\n\"\"\"\nDiccionario\n\"\"\"\n\ndiccionario = {\n    \"nombre\" : \"Lucas\",\n    \"Apellido\" : \"Martinez\",\n    \"nick\" : \"Sorubadguy\",\n    \"edad\" : \"30\"\n}\n\nprint(f\"Diccionario\\n{diccionario}\")\nprint(diccionario[\"nombre\"])#Acceso\ndiccionario[\"edad\"] = 31 #actualizacion\nprint(diccionario)\ndiccionario[\"idioma\"] = \"español\" #Agregar item\nprint(diccionario)\ndiccionario.pop(\"edad\") #Eliminar item\nprint(diccionario)\ndiccionario.clear() #Limpiar diccionario\nprint(diccionario)\n\n\"\"\"\nExtra\n\"\"\"\n\ndef buscar_contacto(nombre, telefonos):\n    try:\n        print(f\"nombre: {nombre}, telefono: {telefonos[nombre]}\")\n    except:\n        print(\"El contacto deseado no existe\")\n\ndef agregar_contacto(nombre, numero,telefonos):\n    if(numero.isdigit() and len(numero) > 0 and len(numero) <= 11):\n        telefonos[nombre] = numero\n        print(\"La operacion se realizo correctamente\")\n    else:\n        print(\"el formato del telefono no es compatible\")\n\n\ndef eliminar_contacto(nombre,telefonos):\n    telefonos.pop(nombre)\n\ndef agenda():\n    op = 0\n    agenda_telefonica = {\n        \"carlos\" : 1234556,\n        \"pedro\" : 2234\n    }\n    while(op != 5):\n        print(f\"Ingrese la opcion deseada\")\n        print(f\"1: Buscar contacto\")\n        print(f\"2: Agregar contacto\")\n        print(f\"3: Eliminar contacto\")\n        print(f\"4: Actualisar Contacto\")\n        op = input(\"Ingrese la opcion deseada: \")\n\n        match op:\n            case \"1\":\n                nombre = input(\"Ingrese el nombre del contacto a buscar: \")\n                buscar_contacto(nombre, agenda_telefonica)\n            case \"2\":\n                nombre = input(\"Ingrese el nombre del contacto a ingresar: \")\n                numero = input(\"Ingrese el numero de telefono del contacto\")\n                agregar_contacto(nombre, numero, agenda_telefonica)\n            case \"3\":\n                nombre = input(\"Ingrese el nombre del contacto a eliminar: \")\n                eliminar_contacto(nombre, agenda_telefonica)\n            case \"4\":\n                nombre = input(\"Ingrese el nombre del contacto a editar: \")\n                telefono = input(\"Ingrese el nuevo numero del contacto: \")\n                agregar_contacto(nombre, telefono, agenda_telefonica)\n            case \"5\":\n                print(\"Saliendo\")\n                break\n            case _:\n                print(\"Opcion no encontrada\")\n    \n\n\n\nagenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/sunjamer.py",
    "content": "\"\"\"\nestructuras de datos \n\"\"\"\n\n# listas: varios elementos ordenados.\n\nmi_lista = [\"Brais\", \"Nombre2\", \"sunjamer\"] # entre corchetes\nprint (mi_lista)\n\nmi_lista.append(\"Cristina\")   # inserción dato\nprint(mi_lista)\n\nmi_lista.remove(\"sunjamer\")  #eliminar dato\nprint(mi_lista)\n\nprint(mi_lista[1])  # acceder a una posicion\n\nmi_lista[1] = \"patatatuelas\"  # actualizaion\nprint(mi_lista)\n\nmi_lista.sort()   # ordenación, si es texto, ordenación alfabética\nprint(mi_lista)\nprint(type(mi_lista))\n\n\n# tuplas\n\nmi_tupla: tuple = (\"sunjamer\", \"Pedro\", \"@canal_sunjamer\", \"47\")\nprint(mi_tupla)\nprint(type(mi_tupla))\n\nprint(mi_tupla[2])\nprint(mi_tupla[3])   # acceso a datos de la tupla\n\nmi_tupla = tuple(sorted(mi_tupla))    # ordenación de la tupla\nprint(mi_tupla)\nprint(type(mi_tupla))\n\n# sets\n\nmi_set = {\"sunjamer\", \"Pedro\", \"@canal_sunjamer\", \"47\"}\n\nprint(mi_set)\nprint(type(mi_set))\n\nmi_set.add(\"sunjamer@gmail.com\")  # inserción\nprint(mi_set)  # no se puede acceder a una posición concreta\nmi_set.add(\"sunjamer@gmail.com\")\nprint(mi_set) # no se puede añadir elementos si estan duplicados\n\nmi_set.remove(\"Pedro\")  # eliminación\nprint(mi_set)\n\nmi_set = set (sorted(mi_set))  # no se puede ordenar\nprint(mi_set)\n\n\n# Diccionario\n\nmi_dict: dict = {\n    \"nombre\":\"Pedro\",\n    \"apellido\":\"Pérez\",\n    \"nick\":\"sunjamer\",\n    \"edad\":\"47\"\n}\n\nprint(mi_dict)\nprint(type(mi_dict))\n\nmi_dict[\"email\"] = \"sunjamer@gmail.com\"  # inserción \nprint(mi_dict)\n\ndel mi_dict[\"apellido\"]  # eliminación\nprint(mi_dict)\n\nprint (mi_dict[\"nombre\"])  # acceso\n\nmi_dict[\"edad\"] = 48    # actualización\nprint(mi_dict)\n\nmi_dict = dict(sorted(mi_dict.items())) # ordenación\nprint(mi_dict)\nprint(type(mi_dict))\n\n# extra\n\ndef mi_agenda():\n\n    agenda = {}\n    \n    while True:\n    \n        print(\"\")\n        print(\"1. Buscar contacto\")\n        print(\"2. Insertar contacto\")\n        print(\"3. Actualizar contacto\")\n        print(\"4. Eliminar contacto\")\n        print(\"5. Salir\")\n\n        opcion = input(\"\\nSelecciona una opción: \")\n\n        match opcion:\n            case \"1\":\n                nombre = input(\"entra el nombre del contacto a buscar: \")\n                if nombre in agenda:\n                    print(f\"el telefono de {nombre} es {agenda[nombre]}.\")\n                else:\n                    print(\"el nombre no existe en la agenda\")\n                    \n            case \"2\":\n                nombre = input(\"entra el nombre del contacto: \")\n                telefono = input(\"entra el teléfono del contacto: \")\n                if telefono.isdigit() and len(telefono) > 0 and len(telefono) <= 11:\n                    agenda[nombre] = telefono\n                else:\n                    print (\"debes introducir un número de 11 digitos como máximo\")\n            case \"3\":\n                pass\n            case \"4\":\n                nombre = input(\"entra el nombre del contacto a eliminar: \")\n                if nombre in agenda:\n                    del agenda[nombre]\n                    print(f\"el contacto {nombre} se ha eliminado\")\n                else:\n                    print(\"el nombre no existe en la agenda\")\n            case \"5\":\n                print (\"saliendo del programa Agenda\")\n                break\n            case _:\n                print(\"Opción no válida. Escoge una opción del 1 al 5.\")\n    \n\n\nmi_agenda()\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/switchdays.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n *   y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n *   y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más\n *   de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.\n \"\"\"\n\n# Ejemplos de estructuras:\n\nmy_list = []\nmy_tuple = ()\nmy_set = set()\nmy_dict = {}\n\n# Dificultad extra:\n\ndef agenda():\n\n    agenda = {}\n    input_operacion = None\n\n    while input_operacion != \"salir\":\n\n        completed = False\n        print(\"AGENDA:\")\n        print(\"----------------------------------------\")\n        print(agenda)\n        print(\"----------------------------------------\")\n        input_operacion = input(\"Seleccione la operación que quiere realizar: \\n Buscar \\n Insertar \\n Actualizar \\n Eliminar \\n Salir\\n\").lower()\n\n        if input_operacion == \"buscar\":\n\n            input_nombre = input(\"Indique el nombre del contacto: \")\n\n            if input_nombre in agenda:\n                print(agenda[input_nombre])\n            else:\n                print(\"No existe ningún contacto con ese nombre.\")\n        \n        elif input_operacion == \"insertar\":\n\n            input_nombre = input(\"Introduce el nombre del contacto: \")\n\n            if input_nombre in agenda:\n                print(\"El contacto\" + input_nombre + \" ya existe.\")\n\n            else:\n                while not completed:\n                    input_numero = input(\"Introduce el número del contacto: \")\n                    numero_telefono = tuple(input_numero)\n\n                    if len(numero_telefono) == 9 and input_numero.isnumeric():\n                        completed = True\n                        agenda [input_nombre] = input_numero\n                        print(\"Se ha añadido el contacto \" + input_nombre + \" con el número: \" + input_numero + \" a la agenda.\")\n                    \n                    else:\n                        print(\"Número de teléfono no válido.\")\n\n        elif input_operacion == \"actualizar\":\n\n            print(agenda.keys())\n            input_nombre = input(\"Que contacto quieres actualizar? \")\n\n            if input_nombre in agenda:\n\n                while not completed:\n\n                    input_numero = input(\"Introduce el nuevo número del contacto: \")\n                    numero_telefono = tuple(input_numero)\n\n                    if len(numero_telefono) == 9 and input_numero.isnumeric():\n                        completed = True\n                        agenda [input_nombre] = input_numero\n                        print(\"El contacto \" + input_nombre + \" se ha actualizado correctamente.\")\n                        \n                    else:\n                        print(\"Número de teléfono no válido.\")\n            else: \n                print(\"Este contacto no existe\")\n\n        elif input_operacion == \"eliminar\":\n            \n            print(agenda.keys())\n            input_nombre = input(\"Que contacto quieres eliminar? \")\n\n            if input_nombre in agenda:\n                del agenda[input_nombre]\n                print(\"El contacto \" + input_nombre + \" se eliminó correctamente\")\n            else:\n                print(\"Este contacto no existe\")\n\n        else:\n            print(\"Instrucción no válida. Introduce una instrucción válida.\")\n\nagenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/thezhizn.py",
    "content": "'''\nEstructuras de datos\n\n'''\n\"\"\" LISTAS \"\"\" \nmy_list = ['hola' , 'hi', 'hello']\nprint(type(my_list))\n# esta es la sintaxis de una lista comun y corriente\nmy_list.append('hola')\nprint(my_list)\n#con .append podemos agregar un dato extra la lista \nmy_list.extend('bye')\nprint(my_list)\n#con .extend extiendes la lista agregando letra por letra a la lista ejem: bye = 'b', 'y', 'e'\nmy_list.remove(\"hi\")\nprint(my_list)\n#con .remove podemos borrar un dato de nuestra lista \nprint(my_list[2])\n#de esta forma llamamos al dato que esta en la posición que indiquemos con el numero (siempre se cuenta desde cero)\nmy_list.insert(3,\"hasta luego\")\nprint(my_list)\n#con .insert podemos agregar a la lista y decidir la ubicacion señalando primero el numero de posicióny luego lo que agregaremos\n#en este caso indica que 'hasta luego' va despues de la posición 3\nmy_list[3] = \"hi\"\nprint(my_list)\n# de esta forma actualizamos un dato, indicando la posición que queremos cambiar en la variable y escibimos el nuevo dato\nprint(my_list.count('hola')) #aparece dos veces\nprint(my_list.count('vaca')) #aparece cero veces\n#con .count contamos la cantidad de veces que aparece lo que escribamos en nuestra lista\nprint(my_list.sort())\n# sort es una funcion de ordenado en este caso ordenara de forma alfabetica \n#si fueran numeros lo haria de forma ascendente aunque tambien le podemos ordenar la forma que quisieramos \nprint(my_list)\nmy_list.reverse()\nprint(my_list)\n#Con .reverse podemos invertir el orden de la lista, podemos ver por consola como esta invertido a la ordenacion que hizo el .sort\nprint(my_list.pop(2))\n#con .pop borramos un elemento de la lista reprersentado por el numero de posicion que tenga en la lista y nos da por terminal el elemento borrado en este caso 'hola'\nprint(my_list)\n#imprimimos para ver que despues de usar .pop en nuestra lista solo se imprime un 'hola' ya que el otro fue removido\n\n'''Tuplas'''\n#Una tupla es similar a una lista pero unas cuantas diferencias\n#Estan formadas por valores separadas por comas y siempre se encierran en paréntesis\n#son inmutables, no se puden alterar (no se pueden agregar ni eliminar datos de la tupla)\nmy_tuple = ('manzana')\nprint(type(my_tuple))\n#Podemos ver que la clase de la variable es STR\nmy_tuple = ('manzana',)\nprint(type(my_tuple))\n#pero en el momento en que ponemos la coma la clase paso a ser una Tupla \n\n'''Conjuntos / set'''\n#Un conjunto es una estructura de dato que sirve para verificar pertenencias y eliminar entradas duplicadas\n\nprint(type({'pera'})) \nprint(type(set('pera')))\n#Los conjuntos se representan usando las llaves '{}' o usando 'set()'\n\nprint(type({}))\n#si escribimos solo '{}' crearemos un diccionario y no un conjunto vacio\nprint(type(set()))\n#para el conjunto vacio se escribe 'set()'\nmy_set = {'mesa', 'silla', 'cama', 'mesa', 'puerta', 'cama'}\nprint(my_set)\n#Las entradas no son ordenadas y los elementos no se repiten y en terminal solo aparecera {'mesa','silla','puerta','cama'}\n\na = set('adios')\nb = set('arroz')\n#en los conjuntos podemos usar operaciones matematicas\nprint(f\"letras que hay en 'a' y no en 'b' {a - b}\")\nprint(f\"letras que hay en 'b' y no en 'a' {b - a}\")\nprint(f\"letras que hay en 'a' o 'b' o ambas {a | b}\")\nprint(f\"letras que hay en ambas {a & b}\")\nprint(f\"letras que hay en 'a' o 'b' pero no en ambas {a ^ b}\")\n\n'''diccionarios'''\n#Los diccionarios funcionan teniendo una palabra clave y un valor a esa palabra clave:\nedades = {'michael':23, 'roger':35, 'dayara':17}\nprint(type(edades))\n#este tipo de datos es un 'dict'\nedades['santos'] = 45\nprint(edades)\n# de esta forma podemos agregar un nuevo dato clave:valor a nuestro diccionario\n\ndel edades['dayara']\nprint(edades)\n#usando 'del' podemos eliminar la clave del diccionario \n\nedades['roger']= 27 \nprint(edades)\n# de esta forma podemos actualizar datos de una lista \n\nprint(list(edades))\n#de esta forma podemos imprimir las claves que tengas en nuestro diccionario\n\nmy_dict = dict ([('mesas', 10), ('vasos', 12), ('cucharas', 33)])\nprint(my_dict)\nprint(type(my_dict))\n#De esta forma podemos crear tambien una lista siguiendo el orden clave y valor y segura siendo un \"dict\"\n  \n\"\"\"\nextra \n\"\"\"\n\ndef my_agenda():\n\n   agenda = {}\n\n   def act_save():\n     celular = input(f\"Ingresa el numero de {nombre} \")\n     if celular.isdigit() and len(celular) >0 and len(celular) <=9:\n       agenda[nombre] = celular\n     else:\n       print(\"Porfavor ingresa un numero de celular valido. \")\n\n   while True:\n    \n    print(\"\")\n    print(\"1. busqueda de contacto\")\n    print(\"2. guardar nuevo contacto\")\n    print(\"3. actualizar contacto\")\n    print(\"4. eliminar contacto\")\n    print(\"5. salir\")\n\n    opciones = input(\"\\nPor favor selecciona cual operacion deseas realizar: \")\n\n    match opciones:\n      case \"1\":\n        nombre = input(f\"Ingresa el nombre del contacto. \")\n        if nombre in agenda:\n          print(f\"El numero de {nombre} es {agenda[nombre]}. \")\n        else:\n          print(f\"el contacto {nombre} no esta en la agenda. \")\n      case \"2\":\n        nombre = input(f\"Ingresa el nombre del contacto. \")\n        act_save() \n      case \"3\":\n        nombre = input(f\"Ingresa el nombre del contacto que quieres actualizar. \")\n        if nombre in agenda:\n          act_save()\n        else:\n          print(f\"El nombre {nombre} no esta en la agenda. \")\n      case \"4\":\n        nombre = input(f\"Ingresa el nombre del contacto que quieras eliminar. \")\n        if nombre in agenda:\n          print(f\"El contacto {nombre} a sido eliminado\")\n          del agenda[nombre]\n        else:\n          print(\"El contacto no existe en la agenda. \")\n      case \"5\":\n        print(\"Estamos saliendo del sistema, muchas gracias. \")\n        break\n      case _:\n        print(\"Porfavor selecciona el numero de una de las opciones. \")\n\nmy_agenda()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/thonys07.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n \"\"\"\n\"\"\"Estructuras\"\"\"\n#listas\nlista:list=[1,2,343,4,5,6]\nprint(lista)\nprint(type(lista))\nlista.pop() #borra segun indice, por defecto -1\nprint(lista)\nlista.append(123)#inserta un valor en la ultima posicion\nprint(lista)\nlista.insert(254,3)#inserta un valor en el indice indicado\nprint(lista)\nlista.remove(4)#elimina el valor indicado\nprint(lista)\nlista.sort()\nprint(lista)\nprint(lista[4])#Acceso al valor en la posicion indicada\nlista[0]=555 #actualizacion\nprint(lista)\n\n#tuplas\ntupla:tuple=(1,2,3,4,564,645,2323,23)\nprint(tupla,type(tupla))\nprint(\"ordenando de mayor a menor: \", sorted(tupla, reverse=True)) #ordenado de mayor a menor\nprint(\"ordenando de menor a mayor: \", sorted(tupla)) #ordenado de menor a mayor\n\n#sets\nset1:set={1,2,45,5,33,65,8}\nprint(set1)\nset1.add(7)\nprint(set1)\nset1.remove(5)\nprint(set1)\nset1=set(sorted(set1))\nprint(set1)\n\n#dictionaries\ndicc:dict={1:\"a\",2:\"b\",3:\"c\"}\nprint(dicc)\ndicc[4]=\"d\"\nprint(dicc)\ndicc.pop(2)\nprint(dicc)\ndel dicc[1]\nprint(dicc)\nprint(dicc[3])\ndicc= dict(sorted(dicc.items()))\nprint(dicc)\n\n\"\"\"EXTRAAAA\n\"\"\"\nclass Agenda:\n    def __init__(self):\n        self.contactos = {}\n\n    def buscar_contacto(self, nombre):\n        if nombre in self.contactos:\n            return self.contactos[nombre]\n        else:\n            return None\n\n    def agregar_contacto(self, nombre, telefono):\n        if nombre not in self.contactos:\n            self.contactos[nombre] = telefono\n            print(\"Contacto agregado correctamente.\")\n        else:\n            print(\"El contacto ya existe en la agenda.\")\n\n    def actualizar_contacto(self, nombre, telefono):\n        if nombre in self.contactos:\n            self.contactos[nombre] = telefono\n            print(\"Contacto actualizado correctamente.\")\n        else:\n            print(\"El contacto no existe en la agenda.\")\n\n    def eliminar_contacto(self, nombre):\n        if nombre in self.contactos:\n            del self.contactos[nombre]\n            print(\"Contacto eliminado correctamente.\")\n        else:\n            print(\"El contacto no existe en la agenda.\")\n\n    def mostrar_contactos(self):\n        if self.contactos:\n            print(\"Lista de contactos:\")\n            for nombre, telefono in self.contactos.items():\n                print(f\"{nombre}: {telefono}\")\n        else:\n            print(\"La agenda está vacía.\")\n\nif __name__ == \"__main__\":\n    agenda = Agenda()\n\n    while True:\n        print(\"\\nOperaciones disponibles:\")\n        print(\"1. Buscar contacto\")\n        print(\"2. Agregar contacto\")\n        print(\"3. Actualizar contacto\")\n        print(\"4. Eliminar contacto\")\n        print(\"5. Mostrar todos los contactos\")\n        print(\"6. Salir\")\n\n        opcion = input(\"Seleccione una opción: \")\n\n        if opcion == \"1\":\n            nombre = input(\"Ingrese el nombre del contacto a buscar: \")\n            contacto = agenda.buscar_contacto(nombre)\n            if contacto:\n                print(f\"Teléfono de {nombre}: {contacto}\")\n            else:\n                print(\"El contacto no existe en la agenda.\")\n\n        elif opcion == \"2\":\n            nombre = input(\"Ingrese el nombre del contacto: \")\n            telefono = input(\"Ingrese el número de teléfono: \")\n            if telefono.isdigit() and len(telefono) <= 11:\n                agenda.agregar_contacto(nombre, telefono)\n            else:\n                print(\"El número de teléfono no es válido.\")\n\n        elif opcion == \"3\":\n            nombre = input(\"Ingrese el nombre del contacto a actualizar: \")\n            telefono = input(\"Ingrese el nuevo número de teléfono: \")\n            if telefono.isdigit() and len(telefono) <= 11:\n                agenda.actualizar_contacto(nombre, telefono)\n            else:\n                print(\"El número de teléfono no es válido.\")\n\n        elif opcion == \"4\":\n            nombre = input(\"Ingrese el nombre del contacto a eliminar: \")\n            agenda.eliminar_contacto(nombre)\n\n        elif opcion == \"5\":\n            agenda.mostrar_contactos()\n\n        elif opcion == \"6\":\n            print(\"¡Hasta luego!\")\n            break\n\n        else:\n            print(\"Opción no válida. Por favor, seleccione una opción válida.\")\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/tito-delpino.py",
    "content": "# * EJERCICIO:\n# * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n# * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n\n# Listas\nlista = [6,3,7,4,8,9,2]\nprint(lista)\n\nlista.append(34) # agregar elementos\nprint(lista)\nlista.remove(2) # eliminar elementos\nprint(lista)\nlista[1] = 22 # cambiar valor de un indice, en este caso el 1\nprint(lista)\nlista.sort() # ordenar de menor a mayor valor\nprint(lista)\n\n# Tuplas - Solo permiten acceso a ellas, son inmutables\ntupla = (6,3,7,4,8,9,2)\nprint(tupla)\n\nprint(tupla[3]) # printea indice 3\ntupla = tuple(sorted(tupla)) # indicamos el tipo de dato (tuple) ya que sorter funciona con listas\nprint(tupla)\n\n# Sets - un set no puede ser ordenado o actualizado, tiene un orden aleatorio\nset_conjunto = {6,3,7,4,8,9,2}\nset_conjunto.add(99)\nprint(set_conjunto)\nset_conjunto.add(99) # solo contiene elementos unicos sin repeticion, no se agregara este valor\nprint(set_conjunto)\nset_conjunto.remove(2) # elimina el elemento con valor 2, sin tener cuenta el indice, si el elemento no existe, lanza error\nprint(set_conjunto)\nset_conjunto.discard(2) # si el elemento 2 no existe no lanza error\nprint(set_conjunto)\nset_conjunto.update([23,44]) # agregamos varios valores de golpe\nprint(set_conjunto)\nprint(type(set_conjunto))\nset_conjunto.clear() # vacia el set completo\nprint(set_conjunto)\n\n# Diccionarios\ndiccionario = {'clave': 'valor', 'esto es la clave':'esto es el valor de esa clave'}\nprint(diccionario)\ndiccionario['nueva clave'] = 'valor agregado'\nprint(diccionario)\ndiccionario['nueva clave'] = 'valor actualizado'\nprint(diccionario)\n\nprint(diccionario['clave']) # printea 'valor'\ndiccionario['clave'] = 'valor actualizado'\nprint(diccionario['clave']) # valor actualizado'\n\nprint(diccionario['esto es la clave']) # printea 'esto es el valor de esa clave'\nprint(diccionario['nueva clave']) # printea 'valor agregado'\n\nfor clave, valor in diccionario.items():\n    print(clave) # podemos printear las claves\n    print(valor) # podemos printear los valores\n\nprint(\"/\" * 50)\n\n\"\"\" DIFICULTAD EXTRA (opcional):\n    Crea una agenda de contactos por terminal.\n* Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n* Cada contacto debe tener un nombre y un número de teléfono.\n* El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n* los datos necesarios para llevarla a cabo.\n* El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n* (o el número de dígitos que quieras)\n* También se debe proponer una operación de finalización del programa.\"\"\"\n\ndef mostrar_agenda():\n    for nombre, telefono in agenda.items():\n        print(\"--Nombre:\", nombre, \"- Telefono:\", telefono )\n\ndef buscar_contacto(contacto):\n    try:\n        print(\"--Telefono -\", agenda[contacto])\n    except:\n        print(\"No existe este contacto\")\n\ndef agregar_contacto(contacto):\n    if contacto in agenda:\n        print(\"Contacto ya en agenda\")\n    else:\n        telefono = input(\"Indica el telefono: \")\n        if len(telefono) >= 10:\n            print(\"El telefono no puede contener mas de 10 digitos\")\n        else:\n            print(\"Agregado a agenda\")\n            agenda[contacto] = int(telefono)\n\ndef actualizar_contacto(contacto):\n    if contacto not in agenda:\n        print(\"No existe este contacto\")\n    else:\n        eleccion = input(\"Si quieres actualizar tambien el nombre pulsa 1 sino pulsa 2: \")\n        if eleccion == '1':\n            nuevo_nombre = input(\"Indica el nuevo nombre: \")\n            del agenda[contacto]\n            agregar_contacto(nuevo_nombre.title())\n        elif eleccion == '2':\n            nuevo_telefono = input(\"Indica el nuevo telefono: \")\n            if len(nuevo_telefono) >= 10:\n                print(\"El telefono no puede contener mas de 10 digitos\")\n            else:\n                print(\"Contacto actualizado\")\n                agenda[contacto] = int(nuevo_telefono)\n\ndef eliminar_contacto(contacto):\n    if contacto not in agenda:\n        print(\"Este nombre no esta entre tus contactos\")\n    else:\n        print(\"Contacto eliminado\")\n        del agenda[contacto]\n\n\n# main\nagenda = {\"Tito Del Pino\":123456, \"Ana\":654321, \"Brais\":456789, \"Siri\": 987654}\n\nwhile True:\n    # menu\n    print(\"---------------Agenda telefonica----------------\")\n    print(\"Selecciona un numero de operacion a realizar\")\n    print(\"1 - Mostar agenda\\n\"\n        \"2 - Buscar contacto\\n\" \\\n        \"3 - Agregar contacto\\n\" \\\n        \"4 - Actualizar contacto\\n\" \\\n        \"5 - Eliminar contacto\\n\" \\\n        \"6 - Salir\")\n    print('-' * 50)\n    \n    # input de usuario\n    eleccion_usuario = int(input(\"Indica la opcion a realizar: \"))\n\n    # acciones del menu\n    if eleccion_usuario == 1:\n        mostrar_agenda()\n    elif eleccion_usuario == 2:\n        contacto_a_buscar = input(\"Nombre del contacto a buscar: \")\n        buscar_contacto(contacto_a_buscar.title())\n    elif eleccion_usuario == 3:\n        contacto_a_agregar = input(\"Nombre del contacto a agregar: \")\n        agregar_contacto(contacto_a_agregar.title())\n    elif eleccion_usuario == 4:\n        contacto_a_actualizar = input(\"Nombre del contacto a actualizar: \")\n        actualizar_contacto(contacto_a_actualizar.title())\n    elif eleccion_usuario == 5:\n        contacto_a_eliminar = input(\"Nombre del contacto a eliminar: \")\n        eliminar_contacto(contacto_a_eliminar.title())\n    elif eleccion_usuario == 6:\n        print(\"Saliendo de la agenda...\")\n        break\n    else:\n        print('Debe selecionar una de las opciones del menu')"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/tobiBordino.py",
    "content": "'''\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n *   y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n *   y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más\n *   de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.\n'''\n\n#! Listas: estructura que permite almacenar datos de cualquier tipo en forma ordenada.\nprint(\" --- Listas --- \")\nmy_list = [1, 2, 3, 4, 5]\nprint(my_list)\n\nmy_list.append(6)\nprint(my_list, \"Agrego un elemento al final de la lista\")\n\nmy_list.pop()\nprint(my_list, \"Elimino el último elemento de la lista\")\n\nmy_list.insert(2, 10) # (posición, elemento) === my_list[2] = 10\nprint(my_list, \"Inserto un elemento en la posición 2\")\n\nmy_list.remove(10)\nprint(my_list, \"Elimino el elemento 10 de la lista\")\n\nmy_list.sort()\nprint(my_list, \"Ordeno la lista\")\n\nmy_list.reverse()\nprint(my_list, \"Invierto la lista\")\n\n#! Tuplas: estructura que permite almacenar datos de cualquier tipo en forma ordenada.\nprint(\" --- Tuplas --- \")\n# La diferencia con las listas es que las tuplas son inmutables, es decir, no se pueden modificar.\nmy_tuple = (1, 2, 3, 4, 5)\nprint(my_tuple)\n# my_tuple.append(6) # Error\n\n# Acceso a la tupla\nprint(my_tuple[0]) # 1\n# Ordeno la tupla (devuelve una lista porque hace como un iterable)\nprint(sorted(my_tuple)) # [1, 2, 3, 4, 5]\nprint(type(sorted(my_tuple))) # <class 'list'>\nprint(type(my_tuple)) # <class 'tuple'>\n\n#! Sets: estructura que permite almacenar datos de cualquier tipo en forma desordenada. Permite eliminar elementos repetidos.\nprint(\" --- Sets --- \")\nmy_set = {1, 2, 3, 4, 5}\nprint(my_set)\n\nmy_set.add(6)\nmy_set.add(6) # No se puede repetir elementos en un set (no se agrega porque ya existe)\nprint(my_set, \"Agrego un elemento al set\")\n\nmy_set.remove(6)\nprint(my_set, \"Elimino un elemento del set\")\n\n#? No se puede acceder a un elemento del set porque no tiene índices (no es ordenado)\n# print(my_set[0]) # Error\n\nmy_set.update([6, 7, 8, 9, 10])\nprint(my_set, \"Agrego varios elementos al set\")\n\n#! Diccionarios: se guardan los datos en pares clave-valor. No se pueden repetir las claves. Los diccionarios no son ordenados.\nprint(\" --- Diccionarios --- \")\n\nmy_dict: dict = {\n    \"nombre\": \"Tobias\",\n    \"apellido\": \"Bordino\",\n    \"edad\": 21\n}\nprint(my_dict)\n\nmy_dict[\"edad\"] = 22\nprint(my_dict, \"Actualizo la edad\")\n\nmy_dict[\"ubicación\"] = \"Córdoba\"\nprint(my_dict, \"Agrego un elemento al diccionario\")\n\nmy_dict.pop(\"ubicación\")\nprint(my_dict, \"Elimino un elemento del diccionario\")\ndel my_dict[\"edad\"]\nprint(my_dict, \"Elimino un elemento del diccionario\")\n\n# Forma de ordenar un diccionario\nmy_dict = dict(sorted(my_dict.items()))\nprint(my_dict, \"Ordeno el diccionario\")\n\n\"\"\"\nEXTRA\n\"\"\"\n#! Agenda de contactos\nprint(\" --- Agenda de contactos --- \")\n\ndef my_agenda():\n\n    agenda = {}\n\n    def insert_contact():\n        phone = input(\"Ingrese el nuevo teléfono del contacto: \")\n        if phone.isdigit() and len(phone) > 0 and len(phone) <= 11:\n            agenda[name] = phone\n            print(\"Contacto actualizado con éxito\")\n        else:\n            print(\"El teléfono ingresado es inválido\")\n\n    while True:\n        print(\"\")\n        print(\"1. Buscar contacto\")\n        print(\"2. Insertar contacto\")\n        print(\"3. Actualizar contacto\")\n        print(\"4. Eliminar contacto\")\n        print(\"5. Salir\")\n\n        option = int(input(\"\\nIngrese una opción: \"))\n\n        match option:\n            case 1:\n                print(\"Buscar contacto\")\n                name = input(\"Ingrese el nombre del contacto: \")\n                if name in agenda:\n                    print(f\"El teléfono de {name} es {agenda[name]}.\")\n                else:\n                    print(f\"El contacto {name} no existe\")\n\n            case 2:\n                print(\"Insertar contacto\")\n                name = input(\"Ingrese el nombre del contacto: \")\n                insert_contact()\n                    \n            case 3:\n                print(\"Actualizar contacto\")\n                name = input(\"Ingrese el nombre del contacto: \")\n                if name in agenda:\n                    insert_contact()\n                else:\n                    print(f\"El contacto {name} no existe\")\n\n            case 4:\n                print(\"Eliminar contacto\")\n                name = input(\"Ingrese el nombre del contacto: \")\n                if name in agenda:\n                    del agenda[name]\n                    print(f\"El contacto {name} ha sido eliminado\")\n                else:\n                    print(f\"El contacto {name} no existe\")\n\n            case 5:\n                print(\"Saliendo de la agenda...\")\n                break\n            case _:\n                print(\"Opción inválida (Opción de 1 a 5)\")\n                my_agenda()\n\nmy_agenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/toral24.py",
    "content": "'''\n/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n'''\n\n#Listas unidimensionales\n\ncompra = ['yogures', 'pan', 'tomate']\n\n#listas bidimensionales\n\nmatriz = [[1,3],[2,4]]\n\n#diccionario\n\ndatos = {\n    \"nombre\": \"toral\",\n    \"edad\": 25,\n    \"profesión\": \"informático\"\n}\nprint(datos[\"nombre\"])\n#tuplas\n\nnumeros = (1,2,3,4)\n\n#inserción\n\ncompra.append('naranjas')\nprint(compra)\n\n#inserción en diccionario\n\ndatos[\"nacionalidad\"] = 'español'\nprint(datos)\n\n#borrado\n\ndel compra[2]\nprint(compra)\n\n#actualización\n\ncompra[1] = 'pan de molde'\nprint(compra)\n\n#ordenación\n\ncompra.sort()\nprint(compra)\n\n'''\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n *   y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n *   y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más\n *   de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.\n'''\nagenda = {}\ncontroller = False\n\ndef verificador(num):\n    try:\n        return int(num)\n    except:\n        print(\"no has introducido un número\")\nwhile controller == False:\n    action = input(\"que acción quieres llevar a cabo: \\n I para insertar \\n E para eliminar \\n A para actualizar \\n B para buscar \\n S para salir \\n\").upper()\n    if action == \"I\":\n        nombre = input(\"introduzca el nombre del contacto que quiere insertar: \")\n        numero = input(\"introduzca el número de telefono que quiere insertar: \")\n        if len(numero) == 9:\n\n            agenda[nombre] = verificador(numero)\n        else:\n            print(\"el número introducido no es correcto\")\n    elif action == \"E\":\n        nombre = input(\"Introduce el nombre del contacto que quieres borrar: \")\n        if nombre in agenda:\n            del agenda[nombre]\n        else:\n            print(\"el nombre intrudcido no se encuentra en la agenda\")\n    elif action == \"A\":\n        nombre = input(\"Introduce el nombre del contacto que quieres actualizar: \")\n        if nombre in agenda:\n            numero = input(\"Introduce el número de telefono actualizado: \")\n            if agenda[nombre] == numero:\n                print(\"el numero introducido es el mismo que se encuentra en la agenda\")\n            else:\n                agenda[nombre] = numero\n        else:\n            print(\"el nombre intrudcido no se encuentra en la agenda\")\n    elif action == \"B\":\n        nombre = input(\"Introduce el nombre del contacto que quieres buscar: \")\n        if nombre in agenda:\n            print(f'El número de {nombre} es {agenda[nombre]}')\n        else:\n            print(\"el nombre intrudcido no se encuentra en la agenda\")\n    elif action == \"S\":\n        controller = True\n    print(agenda)\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/vdroiid.py",
    "content": "from collections import deque\r\n\"\"\"\r\n    Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\r\n    Utiliza operaciones de inserción, borrado, actualización y ordenación.\r\n\"\"\"\r\n#--------------Listas--------------#\r\nlista = []\r\n# Agrega un ítem al final de la lista\r\nlista.append(1)\r\nlista.append(4)\r\n# Agrega un ítem en una posición dada\r\nlista.insert(0, 2)\r\n# Quita el ítem que se especifique en el parámetro \r\nlista.remove(4)\r\n# Quita el elemento en la posición especificada o, sin argumento, el último\r\nlista.pop()\r\n# Elimina todos los elementos de la lista. Equivale a del lista[:]\r\nlista.clear()\r\nfor i in range(5):\r\n    lista.append(i)\r\n# Hace que la lista se ordene alrevés\r\nlista.reverse()\r\n# Para actualizar los datos de la lista se puede hacer mediante el índice\r\nlista[0]=5\r\n# Quita el primer ítem de la lista. HAy que importar deque: from collections import deque\r\nlista = deque(lista)\r\nlista.popleft()\r\n# Quita el ítem especificando su índice\r\ndel lista[0]\r\n\r\n# --------------Tuplas--------------#\r\n# Se puede definir una tupla así:\r\nt = 321, 675, 'Hola'\r\nt[2] # Selecciona el último ítem\r\n# Aunque la tupla es inmutable es, posible agregarle una lista y, por ende, crecer la lista\r\ntupla = t, [1,2,3,4]\r\n# Agregamos un nuevo elemento a la lista\r\ntupla[1].append(5)\r\n# Esto define una tupla vacía\r\nempty = ()\r\n# Esto crea una tupla con un ítem\r\nsingleton = ('Hola',)\r\n# Esto empaqueta los variables dentro de una tupla\r\nletra = 'A'\r\nnumero = 1\r\nsimbolo = '$'\r\ntupla_nueva = letra, numero, simbolo\r\n# print(tupla_nueva)\r\n# print(singleton)\r\n#--------------Conjuntos--------------#\r\n# Esto crea un conjunto vacío\r\nconjunto = set()\r\n# Esto crea un conjunto de datos\r\nbasket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}\r\n# Separa las letras y crear un conjunto. Además, elimina cualquier reptido que haya\r\nunicos = set(\"sisisinonono\")\r\n#--------------Diccionarios--------------#\r\n# De est manera se declara un diccionario vació:\r\ndiccionario = {}\r\n# De esta menar se puede ingresar datos\r\ndiccionario['nombre'] = 'vdroid'\r\n# Se actualiza de la la siguiente manera\r\ndiccionario['nombre'] = 'vdroiid'\r\n# Es decir, si existe la clave, actualiza el valor, de lo contarrio lo agrega en el diccionario\r\ndiccionario['apellido'] = \"Perez\"\r\n# De esta menera se puede ordenar el diccionario mediente los claves\r\nsorted(diccionario.keys())\r\n# De esta manera se puede eliminar un elemento en el diccionario\r\ndel diccionario['nombre']\r\n# Además se puede eliminar específicamente el último elementp de la lista:\r\ndiccionario.popitem()\r\n# print(diccionario)\r\n\"\"\"\r\n * DIFICULTAD EXTRA (opcional):\r\n * Crea una agenda de contactos por terminal.\r\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\r\n * - Cada contacto debe tener un nombre y un número de teléfono.\r\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\r\n *   los datos necesarios para llevarla a cabo.\r\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\r\n *   (o el número de dígitos que quieras)\r\n * - También se debe proponer una operación de finalización del programa.\r\n\"\"\"\r\n\"\"\"\r\nNota. Es posible que haya nombres de contactos repetitivos, pero no es el caso del número de teléfono\r\n\"\"\"\r\n\r\n# Datos de inicio, para probar\r\nlista_contacto = ['Vdroid', '1234567898']\r\n\r\ndef buscar(nombre, telefono):\r\n    if nombre in lista_contacto and telefono in lista_contacto:\r\n        indice = 0\r\n        # 'c' es el dato que contiene el 'indice' de la lista \r\n        for indice, c in enumerate(lista_contacto):\r\n            t = indice+1\r\n            if c == nombre and lista_contacto[t] == telefono:\r\n                name = c\r\n                phone = lista_contacto[t]\r\n    else: return 0\r\n    return name, phone\r\n\r\ndef insertar(nombre, telefono):\r\n    if nombre not in lista_contacto or telefono not in lista_contacto:\r\n        lista_contacto.append(nombre)\r\n        lista_contacto.append(telefono)\r\n        return \"Contacto registrado correcamente.\"\r\n    else: \r\n        return \"El contacto ya existe o no cumple con los requisitos. Velve a intentarlo.\"\r\ndef actualizar(nombre, telefono, new_name, new_phone):\r\n    indice = 0\r\n    # 'c' es el dato que contiene el 'indice' de la lista \r\n    for indice, c in enumerate(lista_contacto):            \r\n        t = indice+1\r\n        if c == nombre and lista_contacto[t] == telefono:\r\n            lista_contacto[indice] = new_name\r\n            lista_contacto[t] = new_phone\r\n            return \"Se actualizó correctamente el contacto.\"\r\n    else: return \"No se pudo actualizar el contato. Vuelve a intentarlo.\"\r\n\r\ndef eliminar(nombre, telefono):\r\n    # 'c' es el dato que contiene el 'indice' de la lista \r\n    for indice, c in enumerate(lista_contacto):\r\n        t = indice+1\r\n        if c == nombre and lista_contacto[t] == telefono:\r\n            del lista_contacto[indice]\r\n            del lista_contacto[indice]\r\n            return \"Se eliminó correctamente el contacto.\"\r\n    return \"Algo salió mal, vuelve a intentarlo.\"\r\n\r\ndef entrada():\r\n    while True:\r\n        # Funcionamiento principal\r\n        print(\"\"\"\r\n        1. Buscar contacto\r\n        2. Insertar contacto nuevo\r\n        3. Actualizar contacto\r\n        4. Eliminar un contacto\r\n        5. Salid del programa\r\n        \"\"\")\r\n        opcion = input(\"¿En qué te puedo ayudar? Elige una opción (escribe el número):\")\r\n        salida = int(opcion)\r\n\r\n        if salida >= 0 and salida <= 6:\r\n            salida = int(opcion)\r\n            break\r\n    return salida\r\n        \r\ndef main():\r\n    while True:\r\n        numero = entrada()\r\n        # Para ver lista completa es posible poner la opción 6\r\n\r\n        if numero <= 6:\r\n            # 1. Buscar contacto\r\n            if numero == 1:\r\n                nombre_a = input(\"Para que podamos buscar el contacto, porporciona el nombre de este, por favor:\\n\")\r\n                telefono_a = input(\"Para que podamos buscar el contacto específico del usario, porporciona el número telefónico:\\n\")\r\n                a = buscar(nombre_a, telefono_a)\r\n                if  a != 0:\r\n                    print(\"\\nDatos de contacto:\")\r\n                    print(\"Nombre de contacto: {}\".format(a[0]), \"Número de teléfono: {}\".format(a[1]), sep=\"\\n\")\r\n                else: print(\"Lo siento, el nombre y número telefónico no se encuentran registrado\")\r\n            # 2. Insertar contacto nuevo\r\n            elif numero == 2:\r\n               \r\n                # Convertirá en mayúscula la primera letra y omitirán los espacios en el inicio\r\n                nombre_b = input(\"Escribe el nombre del contacto: \").strip().capitalize()\r\n                telefono_b = input(\"Escribe el número telefónico: \")\r\n                if len(telefono_b) == 10 and telefono_b.isdigit():\r\n                    b = insertar(nombre_b, telefono_b)\r\n                    if b != 0:\r\n                        print(b)\r\n                    else: print(b)\r\n                else:\r\n                    print(\"Error al ingresar datos, el número de contacto debe ser exactamente 10 dígitos y de tipo numérico. Vuelve a intentarlo.\")\r\n            # 3. Actualizar contacto\r\n            elif numero == 3:\r\n                nombre_c = input(\"Escribe el nombre del contacto actual: \")\r\n                telefono_c = input(\"Ahora el número telefónico: \")\r\n                if nombre_c in lista_contacto and telefono_c in lista_contacto:\r\n                    new_name = input(\"Escribe el nuevo nombre del contacto: \")\r\n                    new_phone = input(\"Ahora el nuevo número de telefóno: \")\r\n                    if len(telefono_c) == 10 and telefono_c.isdigit():\r\n                        c = actualizar(nombre_c, telefono_c, new_name, new_phone)\r\n                        print(c)\r\n                    else:\r\n                        print(\"No es posible registrar el contacto si no cumple con la regla general de un contacto. Vuelve a intentarlo.\")\r\n                else:\r\n                    print(\"Posiblemente no se ha registrado el contato que proporcionaste. Vuelve a intentarlo.\")\r\n            # 4. Eliminar un contacto\r\n            elif numero == 4:\r\n                nombre_d = input(\"Escribe el nombre del contacto que desea eliminar: \")\r\n                telefono_d = input(\"Ahora el número telefónico: \")\r\n                if nombre_d in lista_contacto and telefono_d in lista_contacto:\r\n                    if len(telefono_d) == 10 and telefono_d.isdigit():\r\n                        d = eliminar(nombre_d, telefono_d)\r\n                        print(d)\r\n                    else:\r\n                        print(\"No es posible registrar el contacto si no cumple con la regla general de un contacto. Vuelve a intentarlo.\")\r\n                else:\r\n                    print(\"Posiblemente no existe el contacto registrado. Vuelve a intentarlo.\")\r\n            # 5. Salid del programa\r\n            elif numero == 5:\r\n                break\r\n            # Opción extra\r\n            elif numero == 6:\r\n                print(lista_contacto)\r\n            else:\r\n                print(\"Opción inválida. Intente de nuevo.\")\r\n        else:\r\n            print(\"Opción inválida. Intente de nuevo.\")\r\n    return print(\"Saliste del programa...\")\r\nmain()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/vicman-182.py",
    "content": "'''\n03 ESTRUCTURAS DE DATOS\nDificultad: Media | Publicación: 15/01/24 | Corrección: 22/01/24\n'''\n\n''' * EJERCICIO: '''\n\n'''\n* DIFICULTAD EXTRA (opcional):\n* Crea una agenda de contactos por terminal.\n* - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n* - Cada contacto debe tener un nombre y un número de teléfono.\n* - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n*   los datos necesarios para llevarla a cabo.\n* - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n*   (o el número de dígitos que quieras)\n* - También se debe proponer una operación de finalización del programa.\n*/\n'''\n\n\n'''\n* - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n* - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n'''\n\n''' *** Listas *** '''\n\n# Declarar una lista\nmi_lista = [1,2,3,4,5,6]\n\n# Insertar un elemento al final de la lista.\nmi_lista.append(2)\nprint(mi_lista)\n\n# Modificar un elemento\nmi_lista[2] = 8\nprint(mi_lista)\n\n# Borrar el ultimpo elemento de una lista\nmi_lista.append(\"Este elemento sera borrado\") # Añadimos un elemento al final de la lista para borrarlo en las siguientes lineas del codigo\nprint(mi_lista)\n\nmi_lista.pop()\nprint(mi_lista)\n\n# Ordenar los datos de la lista usando el metodo sort()\n\nmi_lista.sort()\nprint(mi_lista)\n\n\n''' *** Tuplas *** '''\n\n\n''' *** Sets *** '''\n\n\n''' *** Diccionarios *** '''"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/victorfer69.py",
    "content": "#LISTAS\n\nmy_list = [\"Victor\", \"Brais\", \"Carl\"]   #Lista inicial (mutable)\nprint(my_list)\n\nmy_list.append(\"Jorge\")     #Añadimos a Jorge\nprint(my_list)\n\nmy_list.remove(\"Carl\")      #Eliminamos a Carl\nprint(my_list)\n\nmy_list[1] = \"Mouredev\"     #Acceso y modificacion de Brais\nprint(my_list)\n\nmy_list.sort()              #Ordena la lista (alfabéticamente, menor -> mayor)\nprint(my_list)\n\n\n#TUPLAS\n\nmy_tuple = (\"Victor\", \"Juan\", \"32\")     #Tupla inicial (inmutable)\nprint(my_tuple)\n\nprint(my_tuple[2])          #Acceso\n\nmy_tuple_2 = sorted(my_tuple)           #Ordena una tupla y ...\nprint(type(my_tuple_2))     #ahora es una lista en vez de una tupla\nprint(my_tuple_2)\n\n\n#SET\nmy_set = {\"Victor\", \"Juan\", \"32\"}       #Set inicial (estructura desordenada)\nprint(my_set)\n\nmy_set.add(\"Hola\")          #Añadimos pero no sabemos la posicion de Hola\nprint(my_set)\n\n#print(my_set[0])           No hay operacion de acceso\n\nmy_set.remove(\"32\")         #Eliminamos 32\nprint(my_set)\n\nmy_set_2 = set(sorted(my_set))          #No se puede ordenar\nprint(my_set_2)\n\n\n#DICCIONARIO\nmy_dict: dict = {\n    \"name\": \"Victor\",\n    \"age\": \"32\",\n    \"alias\": \"Jose\"\n}\n\nprint(my_dict)\n\nprint(my_dict[\"name\"])      #Acceso\n\nmy_dict[\"email\"] = \"qwerty\" #Añadir nueva clave/valor\nprint(my_dict)\n\nmy_dict[\"email\"] = \"asdf\"   #Acceso y modificacion del email\nprint(my_dict)\n\ndel my_dict[\"age\"]          #Eliminamos la edad\nprint(my_dict)\n\nmy_dict_2 = dict(sorted(my_dict.items()))   #Diccionario ordenado\nprint(my_dict_2)\n\n\n#EJERCICIO EXTRA\n\ndef my_agenda():\n\n    salir = False\n    agenda = {}\n\n    def insert_tel():\n        tel = input(\"Dime el telefono: \")\n        if tel.isdigit() and len(tel) > 0 and len(tel) <= 11:\n            agenda[name] = tel\n        else:\n            print(\"Telefono invalido\")\n\n    while not salir:\n\n        print(\"\\n1. Buscar contacto\")\n        print(\"2. Insertar contacto\")\n        print(\"3. Actualizar contacto\")\n        print(\"4. Eliminar contacto\")\n        print(\"5. Salir\")\n\n        option = input(\"\\nSeleccione la opcion: \")\n\n        match option:\n            case \"1\":\n                \n                name = input(\"Dime el nombre: \")\n                if name in agenda:\n                    print(f\"Nombre: {name} y telefono {agenda[name]}.\")\n                else:\n                    print(f\"El nombre {name} no existe\")\n\n            case \"2\":\n\n                name = input(\"Dime el nombre: \")\n                insert_tel()\n                \n            case \"3\":\n\n                name = input(\"Dime el nombre: \")\n                if name in agenda:\n                    insert_tel()\n                else:\n                    print(f\"Usuario {name} no existe\")\n\n            case \"4\":\n\n                name = input(\"Dime el nombre: \")\n                if name in agenda:\n                    del agenda[name]\n                    print(f\"Usuario {name} eliminado\")\n                else:\n                    print(f\"El nombre {name} no existe\")\n\n            case \"5\":\n\n                print(\"Saliendo de la agenda\")\n                salir = True\n\n            case _:\n                \n                print(\"Operación no válida\")\n\n\n\nprint(\"**********************\")\nprint(\"Bienvenido a la agenda\")\nmy_agenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/warclimb.py",
    "content": "# #03 ESTRUCTURAS DE DATOS\n#### Dificultad: Media | Publicación: 15/01/24 | Corrección: 22/01/24\n\n## Ejercicio\n\"\"\"\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n \"\"\"\n\n# Los tipos de estrucutras de datos en Python son: listas, tuplas, diccionarios y conjuntos\n\n\"\"\"LISTAS\n    - conjunto de datos ordenados por índices\"\"\"\nherramientas = [\"martillo\", \"destornillador\", \"sierra\", \"taladro\"]\n\n# insercion\nherramientas.append(\"alicates\")\n# borrado\nherramientas.remove(\"sierra\")\n# actualizacion\nherramientas[2] = \"serrucho\"\n# ordenacion\nherramientas.sort()\n\n\"\"\"TUPLAS\n    - Igual que las tablas pero inmutables, se usan para datos que no van a cambiar\"\"\"\npower_rangers = (\"Jason\", \"Zack\", \"Billy\", \"Trini\", \"Kimberly\")\n\n# Las tuplas no se pueden editar, asi que: ¯\\_(ツ)_/¯\n\n\"\"\"Diccionarios:\n    - conjunto de datos ordenados por claves. en este caso la clave es la herramienta y el valor representa la resistencia.\"\"\"\nherramientas_dict = {\"martillo\": 40, \"destornillador\": 6, \"sierra\": 20, \"taladro\": 80}\n\n# insercion\nherramientas_dict[\"alicates\"] = 10\n# borrado\ndel herramientas_dict[\"sierra\"]\n# actualizacion\nherramientas_dict[\"taladro\"] = 90\n\n\"\"\"CONJUNTOS / SETS\n- conjunto de datos no ordenados, no se pueden repetir\"\"\"\nherramientas_set = {\"martillo\", \"destornillador\", \"sierra\", \"taladro\"}\n\n# insercion\nherramientas_set.add(\"alicates\")\n# borrado\nherramientas_set.remove(\"sierra\")\n# actualizacion\nherramientas_set.add(\"serrucho\")\n\n\"\"\" DIFICULTAD EXTRA \"\"\"\n\"\"\" * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n\"\"\"\n\n# Vamos a volvernos locos\n# Esto no tiene mucho sentido porque no voy a reutilizar estas funciones, pero bueno.\n\ndef agregar_contacto(contactos):\n    nombre = input(\"Introduce el nombre del contacto: \")\n    telefono = input(\"Introduce el teléfono del contacto: \")\n    if telefono.isnumeric() and len(telefono) == 11:\n        contactos[nombre] = telefono\n        print(\"-\"*20)\n        print(f\"Contacto {nombre} añadido\")\n        print(\"-\"*20)\n    else:\n        print(\"-\"*20)\n        print(\"Teléfono incorrecto\")\n        print(\"-\"*20)\n\ndef buscar_contacto(contactos):\n    nombre = input(\"Introduce el nombre del contacto: \")\n    if nombre in contactos:\n        print(\"-\"*20)\n        print(nombre, \":\", contactos[nombre])\n        print(\"-\"*20)\n    else:\n        print(\"-\"*20)\n        print(\"No existe el contacto\")\n        print(\"-\"*20)\n\ndef actualizar_contacto(contactos):\n    nombre = input(\"Introduce el nombre del contacto: \")\n    if nombre in contactos:\n        telefono = input(\"Introduce el teléfono del contacto: \")\n        contactos[nombre] = telefono\n        print(\"-\"*20)\n        print(\"Contacto actualizado\")\n        print(\"-\"*20)\n    else:\n        print(\"-\"*20)\n        print(\"No existe el contacto\")\n        print(\"-\"*20)\n\ndef borrar_contacto(contactos):\n    nombre = input(\"Introduce el nombre del contacto: \")\n    if nombre in contactos:\n        del contactos[nombre]\n    else:\n        print(\"-\"*20)\n        print(\"No existe el contacto\")\n        print(\"-\"*20)\n\nif __name__ == \"__main__\":\n    contactos = {}\n    while True:\n        print(\"¿Qué quieres hacer?\")\n        print(\"1. Añadir contacto\")\n        print(\"2. Buscar contacto\")\n        print(\"3. Actualizar contacto\")\n        print(\"4. Borrar contacto\")\n        print(\"5. Salir\")\n        opcion = int(input(\"Introduce una opción: \"))\n        if opcion == 1:\n            agregar_contacto(contactos)\n        elif opcion == 2:\n            buscar_contacto(contactos)\n        elif opcion == 3:\n            actualizar_contacto(contactos)\n        elif opcion == 4:\n            borrar_contacto(contactos)\n        elif opcion == 5:\n            break\n        else:\n            print(\"-\"*20)\n            print(\"Opción incorrecta\")\n            print(\"-\"*20)\n    print(\"-\"*20)\n    print(\"Fin\")\n    print(\"-\"*20)"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/willianl731.py",
    "content": "## EJERCICIO: ESTRUCTURAS DE DATOS\n\n# Este script muestra ejemplos de las estructuras de datos de Python\n# y sus operaciones comunes.\n\n# --- 1. Listas (Lists) ---\n# Son colecciones ordenadas y mutables (se pueden cambiar).\nprint(\"--- 1. Listas ---\")\n\n# Creación\nmi_lista = [3, 1, 4, 1, 5, 9]\nprint(f\"Lista inicial: {mi_lista}\")\n\n# Inserción\nmi_lista.append(2) # Añade al final\nmi_lista.insert(0, 6) # Añade en una posición específica\nprint(f\"Tras inserción: {mi_lista}\")\n\n# Borrado\nmi_lista.remove(4) # Borra la primera aparición de un valor\ndel mi_lista[0] # Borra por índice\nprint(f\"Tras borrado: {mi_lista}\")\n\n# Actualización\nmi_lista[1] = 2 # Cambia el valor en un índice\nprint(f\"Tras actualización: {mi_lista}\")\n\n# Ordenación\nmi_lista.sort() # Ordena la lista original\nprint(f\"Lista ordenada: {mi_lista}\\n\")\n\n\n# --- 2. Tuplas (Tuples) ---\n# Son colecciones ordenadas e inmutables (NO se pueden cambiar).\nprint(\"--- 2. Tuplas ---\")\n\n# Creación\nmi_tupla = (3, 1, 4, 1, 5, 9)\nprint(f\"Tupla inicial: {mi_tupla}\")\n\n# Inserción, borrado y actualización NO son posibles directamente.\n# La \"solución\" es crear una nueva tupla a partir de la original.\n# Por ejemplo, para \"actualizar\":\nmi_tupla_actualizada = mi_tupla[:2] + (100,) + mi_tupla[3:]\nprint(f\"Tupla 'actualizada': {mi_tupla_actualizada}\")\n\n# Ordenación\n# La función sorted() devuelve una LISTA ordenada a partir de la tupla.\nlista_ordenada_de_tupla = sorted(mi_tupla)\nprint(f\"Tupla ordenada (como lista): {lista_ordenada_de_tupla}\\n\")\n\n\n# --- 3. Conjuntos (Sets) ---\n# Son colecciones desordenadas, mutables y de elementos ÚNICOS.\nprint(\"--- 3. Conjuntos ---\")\n\n# Creación (los duplicados se eliminan solos)\nmi_set = {3, 1, 4, 1, 5, 9, 2, 2}\nprint(f\"Set inicial: {mi_set}\")\n\n# Inserción\nmi_set.add(6) # Añade un nuevo elemento\nprint(f\"Tras inserción: {mi_set}\")\n\n# Borrado\nmi_set.remove(1) # Borra un elemento\nprint(f\"Tras borrado: {mi_set}\")\n\n# Actualización no es posible por índice (no están ordenados).\n# Simplemente se borra el antiguo y se añade el nuevo.\n\n# Ordenación\n# sorted() devuelve una LISTA ordenada a partir del set.\nlista_ordenada_de_set = sorted(mi_set)\nprint(f\"Set ordenado (como lista): {lista_ordenada_de_set}\\n\")\n\n\n# --- 4. Diccionarios (Dictionaries) ---\n# Son colecciones desordenadas (aunque recuerdan el orden de inserción en Python 3.7+),\n# mutables y formadas por pares clave-valor.\nprint(\"--- 4. Diccionarios ---\")\n\n# Creación\nmi_diccionario = {\"nombre\": \"Willian\", \"edad\": 51, \"ciudad\": \"Santiago\"}\nprint(f\"Diccionario inicial: {mi_diccionario}\")\n\n# Inserción\nmi_diccionario[\"profesion\"] = \"Programador\"\nprint(f\"Tras inserción: {mi_diccionario}\")\n\n# Borrado\ndel mi_diccionario[\"ciudad\"]\nprint(f\"Tras borrado: {mi_diccionario}\")\n\n# Actualización\nmi_diccionario[\"edad\"] = 26\nprint(f\"Tras actualización: {mi_diccionario}\")\n\n# Ordenación\n# Se puede ordenar por clave, devolviendo una lista de tuplas (clave, valor).\ndiccionario_ordenado_por_clave = sorted(mi_diccionario.items())\nprint(f\"Diccionario ordenado por clave: {diccionario_ordenado_por_clave}\\n\")\n\n\"\"\" agenda de contactos por terminal\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no numéricos y con más de 4 dígitos.\n * - También se debe proponer una operación de finalización del programa.\n\"\"\"\n\nprint(\"--- AGENDA DE CONTACTOS ---\")\n# opcion 1\n\n# --- Funciones de Validación (Reglas) ---\n\ndef validar_nombre(nombre):\n    \"\"\"Devuelve True si el nombre solo contiene letras y espacios.\"\"\"\n    # .replace(' ', '') quita los espacios para que isalpha() funcione con nombres compuestos.\n    # .strip() comprueba que no sea una cadena vacía o solo espacios.\n    if nombre and nombre.replace(' ', '').isalpha():\n        return True\n    else:\n        print(\"Error: El nombre solo puede contener letras y espacios.\")\n        return False\n\ndef validar_telefono(telefono):\n    \"\"\"Devuelve True si el teléfono es numérico y tiene 11 dígitos.\"\"\"\n    if telefono.isdigit() and len(telefono) == 11:\n        return True\n    else:\n        print(\"Error: El teléfono debe ser numérico y tener exactamente 11 dígitos.\")\n        return False\n\n# --- Funciones de la Agenda ---\n\ndef agregar_contacto(agenda, nombre, telefono):\n    \"\"\"Añade un contacto a la agenda.\"\"\"\n    if nombre in agenda:\n        print(f\"Error: El contacto '{nombre}' ya existe.\")\n    else:\n        agenda[nombre] = telefono\n        print(f\"Contacto '{nombre}' añadido con éxito.\")\n\ndef actualizar_contacto(agenda, nombre):\n    \"\"\"Actualiza el teléfono de un contacto existente.\"\"\"\n    if nombre in agenda:\n        print(f\"El teléfono actual de {nombre} es {agenda[nombre]}.\")\n        nuevo_telefono = input(\"Introduce el nuevo número de teléfono: \")\n        # Validamos el nuevo número antes de actualizar\n        if validar_telefono(nuevo_telefono):\n            agenda[nombre] = nuevo_telefono\n            print(\"Contacto actualizado con éxito.\")\n    else:\n        print(f\"Error: El contacto '{nombre}' no se encontró.\")\n\ndef buscar_contacto(agenda, nombre):\n    \"\"\"Busca un contacto y muestra su teléfono.\"\"\"\n    if nombre in agenda:\n        print(f\"-> Contacto encontrado: {nombre}, Teléfono: {agenda[nombre]}\")\n    else:\n        print(f\"Error: El contacto '{nombre}' no se encontró.\")\n\ndef borrar_contacto(agenda, nombre):\n    \"\"\"Borra un contacto de la agenda.\"\"\"\n    if nombre in agenda:\n        del agenda[nombre]\n        print(f\"Contacto '{nombre}' borrado con éxito.\")\n    else:\n        print(f\"Error: El contacto '{nombre}' no existe.\")\n\ndef mostrar_contactos(agenda):\n    \"\"\"Muestra todos los contactos de la agenda.\"\"\"\n    print(\"\\n--- LISTA DE CONTACTOS ---\")\n    if not agenda:\n        print(\"La agenda está vacía.\")\n    else:\n        for nombre, telefono in agenda.items():\n            print(f\"- {nombre}: {telefono}\")\n    print(\"--------------------------\\n\")\n\n# --- Programa Principal (Menú) ---\n\nagenda_contactos = {}\n\nwhile True:\n    print(\"\\nElige una opción:\")\n    print(\"1. Añadir contacto\")\n    print(\"2. Actualizar contacto\")\n    print(\"3. Buscar contacto\")\n    print(\"4. Borrar contacto\")\n    print(\"5. Mostrar todos los contactos\")\n    print(\"6. Salir\")\n    \n    opcion = input(\"Introduce el número de la opción: \")\n    \n    if opcion == \"1\":\n        nombre = input(\"Introduce el nombre: \")\n        if validar_nombre(nombre):\n            telefono = input(\"Introduce el teléfono (11 dígitos): \")\n            if validar_telefono(telefono):\n                agregar_contacto(agenda_contactos, nombre, telefono)\n    \n    elif opcion == \"2\":\n        nombre = input(\"¿Qué contacto quieres actualizar? \")\n        if validar_nombre(nombre):\n            actualizar_contacto(agenda_contactos, nombre)\n    \n    elif opcion == \"3\":\n        nombre = input(\"¿Qué contacto quieres buscar? \")\n        if validar_nombre(nombre):\n            buscar_contacto(agenda_contactos, nombre)\n    \n    elif opcion == \"4\":\n        nombre = input(\"¿Qué contacto quieres borrar? \")\n        if validar_nombre(nombre):\n            borrar_contacto(agenda_contactos, nombre)\n    \n    elif opcion == \"5\":\n        mostrar_contactos(agenda_contactos)\n    \n    elif opcion == \"6\":\n        print(\"¡Hasta luego!\")\n        break\n    \n    else:\n        print(\"Opción no válida. Por favor, elige un número del 1 al 6.\")\n\n# opcion 2\n\"\"\"\nclass ContactBook:\n    def __init__(self):\n        self.contacts = {}\n\n    def is_valid_name(self, name):\n        return name.replace(\" \", \"\").isalpha() and name.strip() != \"\"\n\n    def is_valid_phone(self, phone):\n        return phone.isdigit() and len(phone) == 4\n\n    def add_contact(self, name, phone):\n        if not self.is_valid_name(name):\n            return \"nombre_invalido\"\n        if not self.is_valid_phone(phone):\n            return \"telefono_invalido\"\n        self.contacts[name] = phone\n        return \"exito\"\n\n    def search_contact(self, name):\n        if not self.is_valid_name(name):\n            return \"nombre_invalido\"\n        return self.contacts.get(name)\n\n    def update_contact(self, old_name, new_name, new_phone):\n        if not self.is_valid_name(old_name) or not self.is_valid_name(new_name):\n            return \"nombre_invalido\"\n        if old_name not in self.contacts:\n            return \"no_existe\"\n        if not self.is_valid_phone(new_phone):\n            return \"telefono_invalido\"\n        if old_name != new_name and new_name in self.contacts:\n            return \"nombre_duplicado\"\n        del self.contacts[old_name]\n        self.contacts[new_name] = new_phone\n        return \"exito\"\n\n    def delete_contact(self, name):\n        if name in self.contacts:\n            del self.contacts[name]\n            return True\n        return False\n\n    def show_all_contacts(self):\n        if not self.contacts:\n            print(\"\\nLa agenda está vacía.\")\n            return\n        print(\"\\nContactos:\")\n        for name, phone in self.contacts.items():\n            print(f\"Nombre: {name}, Teléfono: {phone}\")\n\ndef main():\n    agenda = ContactBook()\n    \n    while True:\n        print(\"\\n=== AGENDA DE CONTACTOS ===\")\n        print(\"1. Añadir contacto\")\n        print(\"2. Buscar contacto\")\n        print(\"3. Actualizar contacto\")\n        print(\"4. Eliminar contacto\")\n        print(\"5. Mostrar todos los contactos\")\n        print(\"6. Salir\")\n        \n        option = input(\"\\nSeleccione una opción (1-6): \")\n        \n        if option == \"1\":\n            name = input(\"Introduzca el nombre del contacto (solo letras): \")\n            phone = input(\"Introduzca el número de teléfono (exactamente 4 dígitos): \")\n            result = agenda.add_contact(name, phone)\n            if result == \"exito\":\n                print(\"Contacto añadido exitosamente.\")\n            elif result == \"nombre_invalido\":\n                print(\"Error: El nombre solo puede contener letras y no puede estar vacío.\")\n            else:\n                print(\"Error: El número debe ser numérico y tener exactamente 4 dígitos.\")\n\n        elif option == \"2\":\n            name = input(\"Introduzca el nombre del contacto a buscar (solo letras): \")\n            result = agenda.search_contact(name)\n            if result == \"nombre_invalido\":\n                print(\"Error: El nombre solo puede contener letras y no puede estar vacío.\")\n            elif result:\n                print(f\"Teléfono de {name}: {result}\")\n            else:\n                print(\"Contacto no encontrado.\")\n\n        elif option == \"3\":\n            old_name = input(\"Introduzca el nombre del contacto a actualizar (solo letras): \")\n            new_name = input(\"Introduzca el nuevo nombre (solo letras, presione Enter para mantener el mismo): \")\n            new_phone = input(\"Introduzca el nuevo número de teléfono (exactamente 4 dígitos): \")\n            \n            # Si el usuario no ingresa un nuevo nombre, mantenemos el anterior\n            if new_name.strip() == \"\":\n                new_name = old_name\n                \n            result = agenda.update_contact(old_name, new_name, new_phone)\n            if result == \"exito\":\n                print(\"Contacto actualizado exitosamente.\")\n            elif result == \"nombre_invalido\":\n                print(\"Error: Los nombres solo pueden contener letras y no pueden estar vacíos.\")\n            elif result == \"telefono_invalido\":\n                print(\"Error: El número debe ser numérico y tener exactamente 4 dígitos.\")\n            elif result == \"nombre_duplicado\":\n                print(\"Error: Ya existe un contacto con ese nombre.\")\n            else:\n                print(\"Error: Contacto no encontrado.\")\n\n        elif option == \"4\":\n            name = input(\"Introduzca el nombre del contacto a eliminar: \")\n            if agenda.delete_contact(name):\n                print(\"Contacto eliminado exitosamente.\")\n            else:\n                print(\"Contacto no encontrado.\")\n\n        elif option == \"5\":\n            agenda.show_all_contacts()\n\n        elif option == \"6\":\n            print(\"¡Hasta luego!\")\n            break\n\n        else:\n            print(\"Opción no válida. Por favor, seleccione una opción del 1 al 6.\")\n\nif __name__ == \"__main__\":\n    main()\n\n\"\"\""
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/worlion.py",
    "content": "# List\nmy_list = [5, 3, 1, 4, 2]\nprint (\"\\n\\n____ LISTAS____\");\n\nprint(f\" - Lista:\\t\\t\\t{my_list}\")\nmy_list.append(8)\nprint(f\" - Lista (añado el 8):\\t\\t{my_list}\")\nmy_list.remove(3)\nprint(f\" - Lista (borro el 3):\\t\\t{my_list}\")\nmy_list[2] = 99\nprint(f\" - Lista (actualizo la pos 3):\\t{my_list}\")\nmy_list.sort()\nprint(f\" - Lista (ordenada):\\t\\t{my_list}\")\n\n# Tuple\nmy_tuple = (5, 3, 1, 4, 2)\nprint (\"\\n\\n____ TUPLAS ____\");\n\nprint(f\" - Tuple:\\t\\t\\t{my_tuple}\")\nprint(\" - Tuple: Las tuplas son inmutables, no se pueden insertar, borrar, actualizar o ordenar elementos.\")\n\n# Set\nmy_set = {5, 3, 1, 4, 2}\nprint (\"\\n\\n____ SETS ____\");\n\nprint(f\" - Set:\\t\\t\\t\\t{my_set}\")\nmy_set.add(8)\nprint(f\" - Set (añado el 8):\\t\\t{my_set}\")\nmy_set.remove(3)\nprint(f\" - Set (borro el 3):\\t\\t{my_set}\")\n\nprint(\" - Set: los sets son conjuntos no ordenados y sin elementos repetodos, no se pueden actualizar ni ordenar elementos.\")\n\n\n# Dictionary\nmy_dict = {'j': 'value1', 'g': 'value2', 'a': 'value3'}\nprint (\"\\n\\n____ DICTIONARY ____\");\nprint(f\" - Diccionario:\\t\\t\\t\\t\\t{my_dict}\")\nmy_dict['d'] = 'value4'\nprint(f\" - Diccionario (añado el 'f'):\\t\\t\\t{my_dict}\")\n\nmy_dict.pop('a')\nprint(f\" - Diccionario (borro el 'a' (del o pop)):\\t{my_dict}\")\n\nmy_dict['a'] = 'NUEVO VALOR'\nprint(f\" - Diccionario (actualizo el 'j'):\\t\\t{my_dict}\")\n\nprint(\" - Diccionario (ordenado):\")\nfor key in sorted(my_dict):\n    print(f\"\\t\\t\\t - {key}: {my_dict[key]}\")  \n\n\"\"\"\nDIFICULTAD EXTRA (opcional): AGENDA\n\"\"\"\ndef agenda():\n    \n    # Clase Agenda (Dictionary)\n    agenda = {}\n    \n    # Búsqueda de un contacto\t\n    def search_contact():\n        name = input(\"Introduce el nombre del contacto a buscar: \")\n        if name in agenda:\n            print(f\" -> Contacto encontrado. Nombre: {name} - Teléfono: {agenda.get(name)}\")\n        else:\n            print(\"El contacto no existe\")\n    \n    # Añadir/Actualizar un contacto\n    def insert_contact(update = False):\n        if(update):\n            name_msg = \"Introduce el nombre del contacto a actualizar: \"\n            tlfn_msg = \"Introduce el nuevo teléfono del contacto: \"\n        else:\n            name_msg = \"Introduce el nombre del contacto: \"\n            tlfn_msg = \"Introduce el teléfono del contacto: \"\n            \n        name = input(name_msg)\n        valid = False\n        while(not(valid)):\n            phone = input(tlfn_msg)\n            if(phone.isdigit() and len(phone) == 9):\n                print(\"Teléfono correcto\")\n                agenda[name] = phone\n                valid = True\n            else:\n                retry = input(\" # Teléfono no valido # ¿Desea volver a intentarlo? (s/n): \")\n                if(retry.lower == \"n\"):\n                    valid = True\n                else:\n                    print(\"Vuelva a intentarlo...\")\n    \n    # Borrar un contacto\n    def delete_contact():\n        name = input(\"Introduce el nombre del contacto a borrar: \")\n        if name in agenda:\n            agenda.pop(name)\n            print(f\"Contacto '{name}' borrado\")\n        else:\n            print(\"El contacto no existe\")\n\n    def show_agenda():\n        print(\"Listado de contactos: \")\n        for key in agenda:\n            print(f\"\\t - {key}: {agenda[key]}\")\n        \n\n    # Mostrar menú de la agenda\n    def menu():\n        print(\"\\n AGENDA DE CONTACTOS\\n\")\n        print(\"\\t 1.- Búsqueda de un contacto\")            \n        print(\"\\t 2.- Añadir un contacto\")            \n        print(\"\\t 3.- Actualización de un contacto\")            \n        print(\"\\t 4.- Borrar un contacto\")         \n        print(\"\\t 5.- Mostrar agenda (extra)\")         \n        print(\"\\t 0.- Salir\")         \n    \n        option = input(\"\\nSelecciona una opción: \")\n        return option\n    \n    # Procesar la opción seleccionada\n    def process_option(option):\n        if(option == \"1\"):\n            search_contact()\n        elif(option == \"2\"):\n            insert_contact()\n        elif(option == \"3\"):\n            insert_contact(True)\n        elif(option == \"4\"):\n            delete_contact()\n        elif(option == \"5\"):\n            show_agenda()\n        elif(option == \"0\"):\n            print(\"Saliendo de la agenda...\")\n        else:\n            print(\"Opción no válida loco!\")\n        return option\n        \n    def main():\n        option = \"\"\n        while(option != \"0\"):\n            option = menu()\n            process_option(option)\n        \n    main()\n    \nagenda()\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/xemita007.py",
    "content": "@ -1,232 +0,0 @@\n# Ejercicio 03 Estructuras de Datos\n\n###Listas\n\nmiLista = list()  ## se convierte a lsita cualquier variable\nmiOtraLista = []  ##se declara con el corchete\n\nprint(len(miOtraLista))  ## cuenta elementos de la lsita\n\nmiLista = [5, 8, 7, 4, 5, 8, 7, 9]  ## inserción de datos\n\nmiLista\n\n# Operación de ordenación\nprint(\"Operaciones de ordenación\")\n\nmiLista.reverse()\nprint(miLista)\n\nmiLista.sort()\nprint(miLista)\n\n# Operación de inserción\nprint(\"Operaciones de inserción\")\n\nmiLista.append(20)  # Lo añade al final\nmiLista.insert(0, 25)  # Lo añade donde espesifiquemos en este caso el primero\n\nprint(miLista)\n\n\n# Operación de actualización\nprint(\"Operaciones de actualización\")\n\nmiLista[0] = 1  # modificamos el elemento primero por un 0\nprint(miLista)\n\n\n# Operación de busqueda\nprint(\"Operaciones de busqueda\")\nelementos = miLista.__len__()\nelemento1 = miLista[0]\nprint(miLista)\nelementoUltimo = miLista[-1]\nprint(\"Cantidad de elementos de la lista... \", elementos)\nprint(\"Primer elemento de la lista... \", elemento1)\nprint(\"Ultimo elemento de la lista... \", elementoUltimo)\nprint(\"Cuantas veces aparece el numero 8: \", miLista.count(8))\nprint(\"En que indice se encuentra el numero 8: \", miLista.index(8))\nprint(\"Quiero ver desde el indice 0 al 4\", miLista[0:5])\n\n# Operación de borrado\nprint(\"Operaciones de borrado\")\nmiLista.pop(0)  # Borrado por indice\nmiLista.remove(20)  # Borrado por valor\ndel miLista[-1]\nprint(miLista)\nmiLista.clear()\nprint(\"Despues del clear mi lista es: \", miLista)\n\n### Tuplas\nmyTuple = tuple()\nmyTuple = (\"Antonio\", \"Juan\", \"Pepe\", \"Cristian\")\n\nprint(len(myTuple))  ## cuenta elementos de la lsita\nprint(myTuple.__len__())\n\n# Operación de inserción\nprint(\"Operaciones de inserción\")\n\nmyTuple = (\"Antonio\", \"Juan\", \"Pepe\", \"Cristian\")\n\ncadena = \"Chema\"\nmyTuple = myTuple + (cadena,)\n\n\nprint(myTuple)\n\n# Operación de ordenación\nprint(\"Operaciones de ordenación\")\nmyTuple = tuple(sorted(myTuple))\nprint(myTuple)\n\n\n# Operación de actualización\nprint(\"Operaciones de actualización\")\nmyTuple = list(myTuple)\nmyTuple[0] = \"Jose\"\nmyTuple.insert(0, \"Primero\")\nmyTuple = tuple(myTuple)\nprint(myTuple)\n\n# Operación de busqueda\nprint(\"Operaciones de busqueda\")\n\nprint(myTuple[0])\nprint(myTuple[-1])\nprint(myTuple[0:2])\n\nprint(myTuple.index(\"Chema\"))\n\n# Operación de borrado\nprint(\"Operaciones de borrado\")\n\n\n# Sets\n\nmySet = set()\n\n\nprint(\"Operaciones de inserción\")\n\nmySet = {\"chema\", \"jose\", \"rodolfo\", \"juan\", \"moure\"}\nmySet.add(\"carlos\")\nmySet.add(\"carlos\")  # no duplica los datos\nprint(mySet)\n\nprint(\"Operaciones de ordenación en set no tiene sentido\")\n\n\nprint(\"Operaciones de actualización en set no tiene sentido \")\n\n\nprint(\"Operaciones de busqueda en set no tiene sentido\")\n\n\nprint(\"Operaciones de borrado\")\n\nmySet.pop()  # elimina al azar por que no se ordena no tiene sentido\nmySet.remove(\"jose\")\nprint(mySet)\n\n\n# Diccionarios\nmyDict = dict()\nmyDict = {}\nprint(\"Operaciones de insert\")\n\nmyDict = {\"Nombre\": \"Chema\", \"Apellido\": \"Galvez\", \"Correo\": \"xemita_007@hotmail.com\"}\nprint(myDict)\n\nmyDict = {\n    \"Nombre\": \"Chema\",\n    \"Apellido\": \"Galvez\",\n    \"Correo\": \"xemita_007@hotmail.com\",\n    \"Lenguajes\": {\"java\", \"Python\", \"Kotlin\"},\n}\n\nmyDict[\"Calle\"] = \"calle murillo 5\"\nprint(myDict)\n\n\nprint(\"Operaciones de ordenación\")\nmyDict = dict(sorted(myDict.items()))  # ordenar por clave\nprint(myDict)\n\nprint(\"Operaciones de actualización\")\n\nmyDict[\"Nombre\"] = \"Jose Manuel\"\n\nprint(myDict[\"Nombre\"])\n\nprint(\"Operaciones de busqueda\")\n\nprint(\"nombre del diccionario es: \", myDict[\"Nombre\"])\n\n\nprint(\"Operaciones de borrado\")\n\nmyDict.popitem()  # elimina el ultimo elemento del diccionario\nprint(myDict)\ndel myDict[\"Correo\"]\nprint(myDict)\n\n##DIFICULTA EXTRA\nagendaList = list()\n\nwhile True:\n    print(\n        \"Bienvenido a la agenda que desea realizar: 1:inserción,2:actualización,3:busqueda, 4:eliminación, 5:Listar y 6:Salir\"\n    )\n    consola = int(input())\n    print(consola)\n    if consola == 1:\n        contacto = {\"nombre\": \"\", \"Telefono\": \"\"}\n        contacto[\"nombre\"] = input(\"Inserter el nombre: \")\n        contacto[\"Telefono\"] = input(\"Inserter el telefono: \")\n        if contacto[\"Telefono\"].__len__() <= 11 and contacto[\"Telefono\"].isdigit():\n            agendaList.append(contacto)\n        else:\n            print(\"Error Introducir solo digitos maximo 11\")\n\n    elif consola == 2:\n        print(\"Actualizar\")\n        contactoA = input(\"nombre que desea actualizar: \")\n        if contacto[\"nombre\"] == contactoA:\n            contacto[\"nombre\"] = input(\"nombre nuevo: \")\n            contacto[\"Telefono\"] = input(\"Telefono nuevo: \")\n            if contacto[\"Telefono\"].__len__() <= 11 and contacto[\"Telefono\"].isdigit():\n                agendaList.append(contacto)\n            else:\n                print(\"Error Introducir solo digitos maximo 11\")\n        else:\n            print(\"el conctacto no se encuentra\")\n\n    elif consola == 3:\n        print(\"Busqueda\")\n        contactoB = input(\"nombre que desea buscar: \")\n        if contacto[\"nombre\"] == contactoB:\n            print(\"Encontrado: \", contacto[\"nombre\"], contacto[\"Telefono\"])\n\n        else:\n            print(\"Contacto no encontrado intentelo de nuevo\")\n    elif consola == 4:\n        print(\"Eliminación\")\n        contactoE = input(\"nombre que desea Eliminar: \")\n        if contacto[\"nombre\"] == contactoE:\n            del contacto[\"nombre\"], contacto[\"Telefono1\"]\n        else:\n            print(\"Contacto no encontrado intentelo de nuevo\")\n    elif consola == 5:\n        for contacto in agendaList:\n            print(f\"Nombre: {contacto['nombre']}, Teléfono: {contacto['Telefono']}\")\n    elif consola == 6:\n        print(\"Salir\")\n        break\n    else:\n        print(\"por favor selecciones una de las opciones\")\n\n\nprint(\"se imprime la lista: \")\nprint(agendaList)"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/yah1r404.py",
    "content": "'''\nESTRUCTURAS DE DATOS\n'''\n\n# LISTAS\n\nmy_ice_cream = [\"coconut\", \"vanilla\", \"chocolate\", \"oreo\"]\nprint(my_ice_cream)\nmy_ice_cream.append(\"cookies and cream\")\nmy_ice_cream.append(\"cookies and cream\") # INSERCIÓN\nprint(my_ice_cream)\nmy_ice_cream.remove(\"coconut\") # ELIMINACIÓN\nprint(my_ice_cream)\nprint(my_ice_cream[1]) # ACCESO\nmy_ice_cream[1] = \"strawberry\" # ACTUALIZACIÓN\nprint(my_ice_cream)\nmy_ice_cream.sort() # ORDENACIÓN\nprint(my_ice_cream)\nprint(type(my_ice_cream))\n\n# TUPLAS\n\nmy_tupla = (\"Yahir\", \"yah1r404\", \"Sulu\", \"22\")\nprint(my_tupla[1])\nprint(my_tupla[3])\nmy_tupla = tuple(sorted(my_tupla))\nprint(my_tupla)\nprint(type(my_tupla))\n\n# SETS\n\nmy_set = {\"Yahir\", \"yah1r404\", \"Sulu\", \"22\"}\nprint(my_set)\nmy_set.add(\"yah1r.sulu18@gmail.com\")\nmy_set.add(\"yah1r.sulu18@gmail.com\") # INSERCIÓN\nprint(my_set)\nmy_set.remove(\"Sulu\") # ELIMINACIÓN\nprint(my_set)\nmy_set = set(sorted(my_set))\nprint(my_set)\nprint(type(my_set))\n\n# DICCIONARIO\n\nmy_dict : dict = {\n    \"name\" : \"Yahir\",\n    \"username\" : \"yah1r404\",\n    \"surname\" : \"Sulu\",\n    \"age\" : \"22\"\n}\nmy_dict[\"email\"] = \"yah1r.sulu18@gmail.com\" # INSERCIÓN\nprint(my_dict)\ndel my_dict[\"surname\"] # ELIMINACIÓN\nprint(my_dict[\"name\"]) # ACCESO\nmy_dict[\"age\"] = \"23\" # ACTUALIZACIÓN\nprint(my_dict)\nmy_dict = dict(sorted(my_dict.items())) # ORDENACIÓN\nprint(my_dict)\nprint(type(my_dict))\n\n'''\nTAREA EXTRA\n'''\n\ndef my_agenda():\n\n    agenda = {}\n\n    while True:\n\n        print(\"\")\n        print(\"1. BUSCAR CONTACTO\")\n        print(\"2. INSERTAR CONTACTO\")\n        print(\"3. ACTUALIZAR CONTACTO\")\n        print(\"4. ELIMINAR CONTACTO\")\n        print(\"5. SALIR\")\n\n        option = input(\"\\nSelecciona una opción: \")\n    \n        match option:\n            case \"1\":\n                name = input(\"Introduce el nombre del contacto: \")\n                if name in agenda:\n                    print(f\"El número de teléfono de {name} es {agenda[name]}.\")\n                else:\n                    print(f\"El usuario {name} no existe.\")\n            case \"2\":\n                name = input(\"Escribe el nombre del contacto: \")\n                phone = input(\"Escribe el número telefónico del contacto: \")\n                if phone.isdigit() and len(phone) > 0 and len(phone) <= 11:\n                    agenda[name] = phone\n                else:\n                    print(\"Debes introducir un número de teléfono con un máximo de 11 dígitos.\")\n            case \"3\":\n                name = input(\"Introduce el nombre del contacto a actualizar: \")\n                if name in agenda:\n                    phone = input(\"Escribe el nuevo número telefónico del contacto: \")   \n                    if phone.isdigit() and len(phone) > 0 and len(phone) <= 11:\n                        agenda[name] = phone\n                    else:\n                        print(\"Debes introducir un número de teléfono con un máximo de 11 dígitos.\")                    \n                else:\n                    print(f\"El usuario {name} no existe.\")\n            case \"4\":\n                name = input(\"Introduce el nombre del contacto a eliminar: \")\n                if name in agenda:\n                    del agenda[name]\n                else:\n                    print(f\"El usuario {name} no existe.\")\n\n            case \"5\":\n                print(\"Cerrando la agenda\")\n                break\n            case _:\n                print(\"Opción no válida. Elige un número del 1 al 5\")\n\n\n\n\n\n\n\n\n\nmy_agenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/ycanas.py",
    "content": "# --------- Estructuras de Datos\n\n# I. Listas\n\nprint(\"\\n\" + \" Listas \".center(60, \"-\") + \"\\n\")\n\nmi_lista = [1, 2, 3, 4, 5]\nprint(\"creación\", mi_lista)\n\nmi_lista.append(6)\nprint(\"inserción (append)\", mi_lista)\n\nmi_lista.extend([7, 8])\nprint(\"inserción (extend)\", mi_lista)\n\nmi_lista.insert(0, 0)\nprint(\"inserción (insert)\", mi_lista)\n\nmi_lista[8] = -1\nprint(\"actualización ([])\", mi_lista)\n\nmi_lista.sort()\nprint(\"ordenación (sort)\", mi_lista)\n\nmi_lista.remove(-1)\nprint(\"borrado (remove)\", mi_lista)\n\nmi_lista.pop(0)\nprint(\"borrado (pop)\", mi_lista)\n\nmi_lista.clear()\nprint(\"borrado (clear)\", mi_lista)\n\n\n# II. Tuplas\n\nprint(\"\\n\" + \" Tuplas \".center(60, \"-\") + \"\\n\")\n\nmi_tupla = (1, 2, 3, 4)\nprint(\"creación\", mi_tupla)\n\nprint(\"Las tuplas son inmutables, no se pueden insertar, borrar o actualizar elementos una vez creadas.\")\n\n\n# III. Conjuntos\n\nprint(\"\\n\" + \" Conjuntos \".center(60, \"-\") + \"\\n\")\n\nmi_conjunto = {\"manzana\", \"pera\", \"naranja\", \"durazno\"}\nprint(\"creación\", mi_conjunto)\n\nmi_conjunto.add(\"mandarina\")\nprint(\"inserción (add)\", mi_conjunto)\n\nmi_conjunto.update([\"fresa\", \"lulo\"])\nprint(\"actualización\", mi_conjunto)\n\nprint(\"Los diccionarios no son colecciones ordenadas\")\n\nmi_conjunto.remove(\"manzana\")\nprint(\"borrado (remove)\", mi_conjunto)\n\nmi_conjunto.discard(\"fresa\")\nprint(\"borrado (discard)\", mi_conjunto)\n\n\n# IV. Diccionarios\n\nprint(\"\\n\" + \" Diccionarios \".center(60, \"-\") + \"\\n\")\n\nmi_diccionario = {\"nombre\": \"yair\", \"apellido\": \"cañas\"}\nprint(\"creación\", mi_diccionario)\n\nmi_diccionario[\"altura\"] = 1.76\nprint(\"inserción ([])\", mi_diccionario)\n\nmi_diccionario.update({\"altura\": 1.75})\nprint(\"actualización (update)\", mi_diccionario)\n\nmi_diccionario[\"altura\"] = 1.76\nprint(\"actualización ([])\", mi_diccionario)\n\nmi_diccionario = dict(sorted(mi_diccionario.items()))\nprint(\"ordenación (sorted())\", mi_diccionario)\n\nmi_diccionario.pop(\"altura\")\nprint(\"borrado (pop)\", mi_diccionario)\n\nmi_diccionario.popitem()\nprint(\"borrado (popitem)\", mi_diccionario)\n\nmi_diccionario.clear()\nprint(\"borrado (clear)\", mi_diccionario)\n\n\n# --------- Extra\n\ncontactos = {\"Esposa\": 3123456789, \"Novia1\": 3112345678, \"Novia2\": 3101234567}\nprint(\"\\n\" + \" Agenda \".center(60, \"-\"))\n\nwhile True:\n    opcion = None\n\n    while opcion is None:\n        numero = input(\n            \"\\n1. Ver Contactos\" + \n            \"\\n2. Buscar contacto\" + \n            \"\\n3. Guardar contacto\" + \n            \"\\n4. Eliminar contacto\" + \n            \"\\n5. Actualizar contacto.\" + \n            \"\\n0. Salir.\" + \n            \"\\n\\nOpcion: \"\n        )\n\n        if numero.isdigit():\n            opcion = int(numero)\n\n\n    if opcion == 1:\n        print(\"\\nContactos: \\n\")\n        for nombre, numero in sorted(contactos.items()):\n            print(nombre + ':', numero)\n\n\n    elif opcion == 2:\n        if not bool(contactos):\n            print(\"contactos vacios\")\n            continue\n        \n        \n        busqueda = input(\"\\nNombre del contacto: \")\n\n        if not busqueda in contactos:\n            print(\"El contacto no existe.\")\n            continue\n        \n        print(\"Número:\", contactos[busqueda])\n\n\n    elif opcion == 3:\n        numero = input(\"Número de contacto: \")\n\n        if not numero.isdigit():\n            print(\"Número no valido.\")\n            continue\n\n        if int(numero) in contactos.values():\n            print(\"El número ya existe.\")\n            continue\n\n        numero = int(numero)\n\n        nombre = input(\"Nombre del contacto: \")\n\n        if nombre in contactos.keys():\n            print(\"El contacto ya existe.\")\n            continue\n\n        contactos[nombre.title()] = numero\n\n\n    elif opcion == 4:\n        nombre = input(\"Nombre del contacto: \")\n\n        if not nombre in contactos.keys():\n            print(\"El contacto no existe.\")\n            continue\n\n        contactos.pop(nombre)\n        print(\"Contacto eliminado.\")\n\n\n    elif opcion == 5:\n        nombre = input(\"Nombre del contacto: \")\n\n        if not nombre in contactos.keys():\n            print(\"El contacto no existe.\")\n            continue\n\n        \n        numero = input(\"Número de contacto: \")\n\n        if not numero.isdigit():\n            print(\"Número no valido.\")\n            continue\n\n        contactos[nombre] = numero\n\n    else:\n        break"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/yenneralayon142.py",
    "content": "#Estructura de Datos\n\n#List\nlista: list = [1,3,4,5,7]\nlista.append(6) #Inserción\nprint(lista)\nlista.remove(7) #Delete\nprint(lista)\nprint(lista[2]) #Acceso\nlista[1] = 9    #Actualización\nprint(lista)\nlista.sort()    #Ordenacion\nprint(type(lista))\n\n\n#Tuplas (No se pueden agregar ni eliminar)\nmytuple: tuple = (1,2,3)\nprint(mytuple[1]) # Acceso\nmytuple = tuple(sorted(mytuple)) # Ordenación\nprint(mytuple)\nprint(type(mytuple))\n\n\n#Sets(No se puede ordenar)\nmyset: set ={1,2,4,5,6}\nmyset.add(29) #Inserción\nmyset.add(29)\nprint(myset)\nmyset.remove(2) #Eliminación\nprint(myset)\nprint(type(myset))\n\n\n#Diccionario\nmydict:dict = {\n    \"age\": \"18\",\n    \"name\": \"Yenner\"\n}\n\nmydict[\"hobby\"] = \"futbol\" #Inserción\nprint(mydict)\ndel mydict[\"age\"] #Eliminación\nprint(mydict)\nprint(mydict[\"name\"])#Acceso\nmydict[\"age\"] = \"21\" #Actualización\nprint(mydict)\nmydict = dict(sorted(mydict.items())) #Ordenación\nprint(mydict)\nprint(type(mydict))\n\n\n\ndef myagenda():\n\n    agenda = {}\n\n    def insert_contact():\n        phone = input(\"Introduce el número de contacto:   \")\n        if phone.isdigit() and len(phone) > 0 and len(phone) <= 11:\n            agenda[name] = phone\n        else:\n            print(\"Introduce un número de telefono de almenos 11 digitos\")\n\n\n    while True:\n\n        print(\"\")\n        print(\"1. Buscar contacto\")\n        print(\"2. Insertar contacto\")\n        print(\"3. Actualizar contacto\")\n        print(\"4. Eliminar contacto\")\n        print(\"5. Salir\")\n\n        option = input(\"\\nSelecciona una opción: \")\n\n        match option:\n            case \"1\":\n                name = input(\"Introduce el nombre del contacto a buscar: \")\n                if name in agenda:\n                    print(\n                        f\"El número de teléfono de {name} es {agenda[name]}.\")\n                else:\n                    print(f\"El contacto {name} no existe.\")\n            case \"2\":\n                name = input(\"Introduce el nombre del contacto: \")\n                insert_contact()\n            case \"3\":\n                name = input(\"Introduce el nombre del contacto a actualizar: \")\n                if name in agenda:\n                    insert_contact()\n                else:\n                    print(f\"El contacto {name} no existe.\")\n            case \"4\":\n                name = input(\"Introduce el nombre del contacto a a eliminar: \")\n                if name in agenda:\n                    del agenda[name]\n                else:\n                    print(f\"El contacto {name} no existe.\")\n            case \"5\":\n                print(\"Saliendo de la agenda.\")\n                break\n            case _:\n                print(\"Opción no válida. Elige una opción del 1 al 5.\")\n\nmyagenda()\n\n\n\n    \n\n\n\n\n \n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/yharyarias.py",
    "content": "# Listas\n\n# Lista vacia\nlista: list = []\n\n# Lista con elementos\nmi_lista = [1, 2, 3, 4, 5]\nprint(mi_lista)\n\n# Inserción al final de la lista\nmi_lista.append(6)\nprint(mi_lista)\n\n# Borrado de un elemento por valor\nmi_lista.remove(3)\nprint(mi_lista)\n\n# Borrado de un elemento por posición\ndel mi_lista[1]\nprint(mi_lista)\n\n# Actualización de un elemento por índice\nmi_lista[1] = 10\nprint(mi_lista)\n\n# Búsqueda de un elemento por posición\nelemento_en_posicion = mi_lista[2]\nprint(elemento_en_posicion)\n\n# Ordenación de la lista\nmi_lista.sort()\nprint(mi_lista)\n\n# -----------------------------------------------\n\n# Tuplas\n\n# Creación de una tupla\nmi_tupla: tuple = (1, 2, 3, 4, 5)\nprint(mi_tupla)\n# No se pueden realizar operaciones de inserción, borrado o actualización en tuplas\n\n# Tipo de estructura de datos\nprint(type(mi_tupla))\n\n# Ordenación de la tupla\nmi_tupla_ordenada = tuple(sorted(mi_tupla))\nprint(mi_tupla_ordenada)\n\n# -----------------------------------------------\n\n# Sets\n\n# Update - Elimina y agrega un nuevo dato\n\n# Sort - NO se pueden ordenar\n\n# Creación de un conjunto\nmi_conjunto: set = {1, 2, 3, 4, 5}\n\n# Inserción de un elemento\nmi_conjunto.add(6)\n\n# Borrado de un elemento por valor\nmi_conjunto.remove(3)\n\n# No se pueden realizar operaciones de actualización en conjuntos\n# No se garantiza un orden específico en los conjuntos\n\nprint(mi_conjunto)\n\nconjunto_ordenado = set(sorted(mi_conjunto))\n\n\n# -----------------------------------------------\n\n# Diccionarios\n\n# Creación de un diccionario\nmi_diccionario: dict = {'a': 1, 'b': 2, 'c': 3}\n\n# Acceder a un valor por medio de la clave\nprint(mi_diccionario['a'])\n\n# Inserción/Actualización de un par clave-valor\nmi_diccionario['d'] = 4\n\n# Borrado de un elemento por clave\ndel mi_diccionario['b']\n\n# No se pueden realizar operaciones de ordenación en diccionarios\n\nprint(mi_diccionario)\n\n# Ordenación\n\ndict_ordenado = dict(sorted(mi_diccionario.items()))\nprint(dict_ordenado)\n\n# ----------------------------------------------\n\n# DIFICULTAD EXTRA (opcional):\n\n# Busqueda, inserción, actualización y eliminación\n# Contacto (nombre, numero de telefono)\n# Solicita que operación desea realizar y luego los datos para realizarla\n# Evaluar los numeros de telefono para que sean solo numeros y de 11 dijitos\n# También se debe proponer una operación de finalización del programa.\n\ndef validar_telefono(telefono):\n    return len(telefono) == 11 and telefono.isdigit()\n\ndef mi_agenda(agenda: dict):\n    while True:\n        print(\"--- Agenda personal ---\")\n        print('''\n            Opciones:\n                1. Buscar\n                2. Insertar\n                3. Actualizar\n                4. Eliminar\n                0. Salir\n            ''')\n        \n        opcion = int(input(\"Seleccione una opción: \"))\n\n        if opcion == 1:\n            contacto_buscar = input(\"Ingresa el nombre del contacto que deseas buscar: \")\n            if contacto_buscar in agenda:\n                print(\"Nombre: \", contacto_buscar, \" - Teléfono: \", agenda[contacto_buscar])\n            else:\n                print(\"Contacto no encontrado\")\n\n        elif opcion == 2:\n            nombre_agregar = input(\"Ingresa el nombre: \")\n            telefono_agregar = input(\"Ingresa el número telefónico: \")\n            if validar_telefono(telefono_agregar):\n                agenda[nombre_agregar] = telefono_agregar\n                print(\"Agenda: \\n\", agenda.items())\n            else:\n                print(\"El número de teléfono no tiene el formato correcto\")\n\n        elif opcion == 3:\n            nombre_actualizar = input(\"Ingresa el nombre del contacto que deseas actualizar: \")\n            if nombre_actualizar in agenda:\n                print(\"No se permite actualizar el nombre, solo el número de teléfono\")\n                numero_actualizar = input(\"Ingresa el número del contacto que deseas actualizar (11 dígitos y solo caracteres numéricos): \")\n                if validar_telefono(numero_actualizar):\n                    agenda[nombre_actualizar] = numero_actualizar\n                    print(\"Agenda: \\n\", agenda.items())\n                else:\n                    print(\"El número de teléfono no tiene el formato correcto\")\n            else:\n                print(\"El contacto no existe\")\n\n        elif opcion == 4:\n            nombre_eliminar = input(\"Ingresa el nombre del contacto que deseas eliminar: \")\n            if nombre_eliminar in agenda:\n                del agenda[nombre_eliminar]\n                print(\"Contacto eliminado satisfactoriamente\")\n                print(\"Agenda: \\n\", agenda.items())\n            else:\n                print(\"Contacto no encontrado\")\n\n        elif opcion == 0:\n            print(\"Ha salido de su agenda de contactos\")\n            break\n\nmi_agenda({\"Jesus\": \"3209029933\", \"Maria\": \"3150987732\"})\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/yoezequiel.py",
    "content": "# Función para limpiar la pantalla\ndef limpiar_pantalla():\n    print(\"\\033[H\\033[J\")\n\n\ndef validar_telefono(telefono):\n    return telefono.isdigit() and len(telefono) <= 11\n\n\ndef agregar_contacto(agenda):\n    nombre = input(\"Introduce el nombre del contacto: \")\n    telefono = input(\"Introduce el número de teléfono: \")\n\n    if not validar_telefono(telefono):\n        print(\"Número de teléfono no válido.\")\n        return\n\n    agenda[nombre] = telefono\n    print(\"Contacto agregado correctamente.\")\n\n\ndef buscar_contacto(agenda):\n    nombre = input(\"Introduce el nombre del contacto a buscar: \")\n    if nombre in agenda:\n        print(\"Nombre: {}, Teléfono: {}\".format(nombre, agenda[nombre]))\n    else:\n        print(\"Contacto no encontrado.\")\n\n\ndef actualizar_contacto(agenda):\n    nombre = input(\"Introduce el nombre del contacto a actualizar: \")\n    if nombre in agenda:\n        telefono = input(\"Introduce el nuevo número de teléfono: \")\n\n        if not validar_telefono(telefono):\n            print(\"Número de teléfono no válido.\")\n            return\n\n        agenda[nombre] = telefono\n        print(\"Contacto actualizado correctamente.\")\n    else:\n        print(\"Contacto no encontrado.\")\n\n\ndef eliminar_contacto(agenda):\n    nombre = input(\"Introduce el nombre del contacto a eliminar: \")\n    if nombre in agenda:\n        del agenda[nombre]\n        print(\"Contacto eliminado correctamente.\")\n    else:\n        print(\"Contacto no encontrado.\")\n\n\ndef main():\n    agenda = {}\n\n    while True:\n        limpiar_pantalla()\n        print(\"--- Agenda de Contactos ---\")\n        print(\"1. Agregar contacto\")\n        print(\"2. Buscar contacto\")\n        print(\"3. Actualizar contacto\")\n        print(\"4. Eliminar contacto\")\n        print(\"5. Salir\")\n\n        opcion = input(\"Elija una opción: \")\n\n        if opcion == \"1\":\n            agregar_contacto(agenda)\n        elif opcion == \"2\":\n            buscar_contacto(agenda)\n        elif opcion == \"3\":\n            actualizar_contacto(agenda)\n        elif opcion == \"4\":\n            eliminar_contacto(agenda)\n        elif opcion == \"5\":\n            print(\"Saliendo del programa.\")\n            break\n        else:\n            print(\"Opción no válida. Inténtelo de nuevo.\")\n\n        input(\"Presiona Enter para continuar...\")\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/zakkdrte.py",
    "content": "\n# ESTRUCTURAS DE DATOS\n\n#   EJERCICIO:\n#   - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n#   - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n#  \n#   DIFICULTAD EXTRA (opcional):\n#   Crea una agenda de contactos por terminal.\n#   - Debes implementar funcionalidades de búsqueda, inserción, actualización\n#    y eliminación de contactos.\n#   - Cada contacto debe tener un nombre y un número de teléfono.\n#   - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n#     y a continuación los datos necesarios para llevarla a cabo.\n#   - El programa no puede dejar introducir números de teléfono no númericos y con más\n#     de 11 dígitos (o el número de dígitos que quieras).\n#   También se debe proponer una operación de finalización del programa.\n \n# LISTS #\n\n\nmy_list:list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\nprint(f\"MY LIST:\\n{my_list}\")\nprint(f\"Su length: {len(my_list)}\")\nprint(f\"Su type: {type(my_list)}\")\n\n# OPERATIONS WITH LIST #\n\n# add a item in the list\nmy_list.append(11) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]\nprint(my_list)\n\n# count times that it's in the list     # [1{0}, 2{1}, 3{2}, 4{3}, 5{4}, 6{5}, 7{6}, 8{7}, 9{8}, 10{9}, 11{10}]       position ==> {}\nprint(my_list.count(5)) #   ==> 1\n\n# search index of item  # [1{0}, 2{1}, 3{2}, 4{3}, 5{4}, 6{5}, 7{6}, 8{7}, 9{8}, 10{9}, 11{10}]       position ==> {}\nprint(my_list.index(5)) # ==> 4\n\n# extend a list adding another list in its\nmy_list.extend(my_list)\nprint(my_list)      # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]\n\n# insert a item in a position and move all items to the right\nmy_list.insert(0,0) # # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]\nprint(my_list)\n\n# Do a pop to a item for a index\nmy_list.pop(-1) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\nprint(my_list)\n\n# reverse the list\nmy_list.reverse()   # [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]\nprint(my_list)\n\n# remove one item\nmy_list.remove(0)   # [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]\nprint(my_list)\n\n# delete item or items from a list\ndel my_list[:11]    # [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]\nprint(my_list)\n\n# sorted a list\nmy_list.sort()  # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\nprint(my_list)\n\n# clear a list \nmy_list.clear() # []\nprint(my_list)\n\n## CREATING A LIST COMPREHENSION ## \n\n# creatind with fot into the list\nlist_with_for:list = [i for i in range(1,21)]\nprint(list_with_for)\nprint(f\"Su length: {len(list_with_for)}\")\nprint(f\"Su type: {type(list_with_for)}\")\n\n# creating without for into the list\n\nother_list_with_for:list = []\n\nfor i in range(1, 21):\n    other_list_with_for.append(i)\n\nprint(other_list_with_for)\nprint(f\"Su length: {len(other_list_with_for)}\")\nprint(f\"Su type: {type(other_list_with_for)}\")\n\n\n## TUPLES ##\n\nmy_tuple:tuple = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)\nmy_other_tuple:tuple = (1, 1, 1, 2, 3, 4, 4, 5, 5, 5, 5, 6, 7, 8, 9, 10)\nprint(my_tuple)\nprint(f\"Su length: {len(my_tuple)}\")\nprint(f\"Su type: {type(my_tuple)}\")\n\nprint(f\"Searching which ocurrences there is in the tuple with the item ==> (5)\\nMy First Tuple: {my_tuple.count(5)}\\nMy Second Tuple:  {my_other_tuple.count(5)}\")\n\nprint(my_tuple.index(7))\n\n\n## SETS ##\n\nmy_set:set= {2, 5, \"rodrigo\",\"ricardo\"}\nprint(type(my_set))\n\nmy_set.add(\"roberto\")\nprint(my_set)\n\nmy_set_comprehension:set = {i for i in range(1, 21)}\nprint(my_set_comprehension)\n\nprint(my_set.difference(my_set_comprehension))\n\nmy_set.remove(\"ricardo\")\nprint(my_set)\n\nprint(my_set.intersection(my_set_comprehension))\n\nmy_set.clear()\nprint(my_set)\n\n\n## DICITONARIES ## \nmy_dict = {\"username\":\"roberto\",\"email\":\"robertogzz@gmail.com\",\"password\":\"roberto123456789\",\"url_site\":\"https://www.robertogzz.com/home/\"}\nprint(f\"Su type: {type(my_dict)}\")\n\nprint(f\"obteniendo el email: {my_dict.get(\"email\")}\")\n\nprint(my_dict.items())\n\nprint(my_dict.values())\n\nprint(my_dict.keys())\n\nprint(my_dict.fromkeys(my_dict,\"jajajajaja XD\"))\n\nmy_dict.popitem()\nprint(my_dict)\nmy_dict.popitem()\nprint(my_dict)\n\nmy_dict.pop(\"email\")\nprint(my_dict)\n\nmy_dict.clear()\nprint(my_dict)\n\n\n## EXTRA ## \n\n\n\n\ncontacts_agenda: list = [{\"name\":\"Juan\",\"phone_number\":8125562398},\n                        {\"name\":\"Gerardo\",\"phone_number\":8123489756},\n                        {\"name\":\"Lucas\",\"phone_number\":8153846379},\n                        {\"name\":\"Rodrigo\",\"phone_number\":8158251008}]\n\ndef check_number(number: int):\n    if type(number) == int:\n        number = str(number)\n        if len(number) == 10:\n            number = int(number)\n            return True\n    else:\n        return False\n    \ndef verification_user(phone_number: str):\n    for i in contacts_agenda:\n        if phone_number in i.values() :\n            \n            return False\n        else:\n            return True\n\ndef creat_function(name: str = None, phone_number: str = None):\n    name = input(\"WRITE NAME:\\n\")\n    phone_number = input(\"WRITE PHONE NUMBER:\\n\")\n    phone_number = int(phone_number)\n    def checking_contact(contacts_agenda):    \n        if verification_user(phone_number):\n            contacts_agenda.append({\"name\":name,\"phone_number\":phone_number})\n            return contacts_agenda\n        else:\n            print(\"THERE'S A USER WITH THIS PHONE NUMBER\")\n            return do_it()\n    if check_number(phone_number):\n        return checking_contact(contacts_agenda)   \n    else:\n        return print(\"THE NUMBER IS BIGGER THAN NORMAL, OR ISN'T OF TYPE INT\")\n\ndef read_function(number_or_name: str = None, data: str = None):\n    number_or_name = input(\"write how do you wanna find the contact:==> [name/phone]\\n\")\n    number_or_name.lower()\n    \n    if number_or_name == \"phone\":\n        data = input(\"WRITE THE PHONE NUMBER'S CONTACT THAT DO YOU WANNNA FIND:\\n\")\n        data = int(data)\n        try:\n        \n            contact = (filter(lambda number: number[\"phone_number\"] == data, contacts_agenda))\n            contact_list = list(contact)\n            return contact_list\n        except:    \n            return \"NO SE ENCONTRO NINGUN USUARIO\", do_it()\n        \n    elif number_or_name == \"name\":\n        data = input(\"WRITE THE NAME'S CONTACT THAT DO YOU WANNNA FIND:\\n\")\n        data = data.capitalize()\n        try:\n        \n            contact = (filter(lambda name: name[\"name\"] == data, contacts_agenda))\n            contact_list = list(contact)\n            return contact_list\n        except:    \n            return \"NO SE ENCONTRO NINGUN USUARIO\", do_it()\n    else:\n        print(\"You don't write the correct word or you write nothing\")\n        input(\"sou yo stil want to find some contact? ==> [yes/not]\\n\")\n        if \"yes\":\n            return read_function()\n        elif\"not\":\n            return do_it()\n\ndef update_function():\n    data = input(\"write the phone number from the contact that do you want to edit:\\n\")\n    data = int(data)\n    contact = (filter(lambda number: number[\"phone_number\"] == data, contacts_agenda))\n    contact = list(contact)\n    if contact:\n        print(f'This is the contact:\\n{contact}')\n        choice_value = input(\"what do you want to edit in this contact: ==> [name/phone/both]\\n\")\n        if choice_value == \"name\":\n            name = input(\"What will be your new name?:\\n\")\n            contact[0].update({\"name\":name})\n            return contact \n        \n        elif choice_value == \"phone\":\n            phone = input(\"What will be your new phone?:\\n\")\n            contact[0].update({\"phone_number\":phone})\n            return contact\n        elif choice_value == \"both\":\n            name = input(\"What will be your new name?:\\n\")\n            phone = input(\"What will ber your new phone?:\\n\")\n            contact[0].update({\"name\":name,\"phone_number\":phone})\n            return contact\n\n            \n        print(\"There's not this contact\")\n        return do_it()\n\ndef delete_function():\n    data = input(\"write the phone number from the contact that do you want to delete:\\n\")\n    data = int(data)\n    \n    for item in contacts_agenda:\n        if data in item.values():\n            contacts_agenda.remove(item)\n            return contacts_agenda\n        else:\n            print(\"there is not a contact's number with this phone number\")\n            return delete_function()\n        \ndef do_it(parameter:str=None):\n    yes_or_not:str = None\n    parameter = input(\"WHAT DO YOU WANNA DO?:   ==> CRUD(Creat, Read, Update, Delete)\\n\")\n    parameter = parameter.capitalize()\n    if parameter == \"Creat\":\n        return creat_function()\n    elif parameter == \"Read\":\n        return read_function()\n    elif parameter == \"Update\":\n        return update_function()\n    elif parameter == \"Delete\":\n        return delete_function()\n    else:\n        print(\"PLEASE WRITE THE FUNCTION THAT DO YOU WANNA DO\\n IF YOU WANNA WRITE AGAIN WRITE (YES) AND IF YOU DON'T WANT WRITE (NOT) OR JUST IGNORE IT\")\n        yes_or_not = input(\"\")\n        if yes_or_not == \"yes\":\n            return do_it()\n        else:\n            pass\n            \n   \nprint(do_it())"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/python/zetared92.py",
    "content": "# ESTRUCTURAS DE DATOS\n\n# LISTAS\nprint(f\"This is my list:\")\nmyList: list = [\"Bruce\", \"Diana\", \"Barry\", \"Victor\", \"Kal-El\", \"Arthur\"]\nprint(myList)\n\n# Inserción\nmyList.append(\"Hal Jordan\")\nprint(myList)\n\n# Eliminación\nmyList.remove(\"Victor\")\nprint(myList)\n\n# Acceso\nprint(myList[4])\n# Actualización\nmyList[4] = \"Oliver Queen\"\nprint(myList)\n\n# Ordenación\nmyList.sort()\nprint(myList)\nprint(type(myList))\n\n# TUPLAS\nmyTuple: tuple = (\"Bruce\", \"Wayne\", \"Batman\", \"1988\")\n# Acceso\nprint(myTuple[2])\nprint(myTuple[1])\n# Ordenación\nmyTuple = tuple(sorted(myTuple))\nprint(myTuple)\nprint(type(myTuple))\n\n# SETS\nmySet: set = {\"Bruce\", \"Wayne\", \"Batman\", \"1988\"}\nprint(mySet)\n# Inserción\nmySet.add(\"Wayne Enterprises\")\nprint(mySet)\n# Eliminación\nmySet.remove(\"Batman\")\nprint(mySet)\n# Los sets no pueden ser ordenados\nprint(mySet)\nprint(type(mySet))\n\n# DICCIONARIOS\nmyDict: dict = {\n    \"name\": \"Bruce\",\n    \"surname\" : \"Wayne\",\n    \"aka\": \"Batman\",\n    \"year\" : \"1988\",\n}\n# Inserción\nmyDict[\"Company\"]=\"Wayne Enterprises\" \nprint(myDict)\n# Eliminación\ndel myDict[\"aka\"]\nprint(myDict)\n# Acceso\nprint(myDict[\"name\"])\n# Actualización\nmyDict[\"year\"] = \"1989\"\nprint(myDict)\n# Ordenación\nmyDict = dict(sorted(myDict.items()))\nprint(myDict)\nprint(type(myDict))\n\n\n# 🧩 DIFICULTAD EXTRA 🧩\n\ndef myAgenda():\n\n    agenda = {}\n    print(\"Welcome to the contact book Peacemaker\")\n\n    def insertContact():\n        phone = input(\"Input the number of the new contact\")\n        if phone.isdigit() and len(phone) > 0 and len(phone) <= 9:\n            agenda[name] = phone\n        else:\n            print(\"Invalid phone number\")\n    \n    while True:\n        print(\"OPTIONS\")\n        print(\"1.-Search\")\n        print(\"2.-Insert new contact\")\n        print(\"3.-Update a contact\")\n        print(\"4.-Delete contact\")\n        print(\"5.-Exit\")\n\n        option = input(\"\\nSelect an option: \")\n\n        match option:\n            case \"1\":\n                name = input (\"Input the contact name: \")\n                if name in agenda:\n                    print(f\"The {name}'s phone number is: {agenda[name]}.\")\n                else:\n                    print(\"This contact does not exist\")\n            case \"2\":\n                name = input (\"Input the name of the new contact: \")\n                insertContact()\n            case \"3\":\n                name = input(\"Input the contact name you want to update\")\n                if name in agenda:\n                    insertContact()\n                else:\n                    print(f\"The {name}'s contact does not exist\")\n            case \"4\":\n                name = input(\"Input the contact you want to delete: \")\n                if name in agenda:\n                    del agenda[name]\n                else:\n                    print(f\"This contact does not exist\")\n            case \"5\":\n                print(\"Disconnecting\")\n                break\n            case _:\n                print(\"No valid option, select an option 1-5\")\n\nmyAgenda()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/r/Micromantic.R",
    "content": "#\n# EJERCICIO:\n# - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n# - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n#\n\n### Estructuras de datos\n\n## Vector\n\n# Creacion\n\nvector_de_numeros <- c(1:10)\n\nvector_de_numeros\n\n# Insercion\n\nvector_de_numeros <- c(vector_de_numeros, 11:20)\n\nvector_de_numeros\n\n# Borrado\n\nvector_de_numeros <- vector_de_numeros[-(5:15)]\n\nvector_de_numeros\n\n# Actualizacion\n\nvector_de_numeros <- vector_de_numeros * 5\n\nvector_de_numeros\n\n# Ordenacion\n\nvector_de_numeros <- sort(vector_de_numeros, decreasing = TRUE)\n\nvector_de_numeros\n\n## Lista\n\n# Creacion\n\nlista <- list(\n  string = \"hola\",\n  enteros = 1:10,\n  booleano = TRUE,\n  lista_pequeña = list(\"chao\", 11:20, FALSE)\n)\n\nlista\n\n# Insercion\n\nlista <- list(lista, complejo = 5i)\n\nlista\n\n# Borrado\n\nlista <- lista[-1]\n\nlista\n\n# Actualizacion\n\nlista$booleano <- TRUE\n\nlista\n\n# Ordenacion\n\nlista <- lista[order(unlist(lista), decreasing = TRUE)]\n\nlista\n\n## Data frame\n\n# Creacion\n\ndata_frame <- data.frame(\n  \"Materias\" = c(\n    \"Matematica\",\n    \"Estadistica\",\n    \"Computacion\"\n  ),\n  \"Notas\" = sample(1:20,\n    size = 3,\n    replace = TRUE\n  )\n)\ndata_frame\n\n# Insercion\n\ndata_frame <- cbind(data_frame, \"Semestre\" = \"I\")\n\ndata_frame\n\n# Borrado\n\ndata_frame <- data_frame[1:2]\n\ndata_frame\n\n# Actualizacion\n\ndata_frame$Notas <- data_frame$Notas / 2\n\ndata_frame\n\n# Ordenacion\n\ndata_frame <- sort_by(\n  x = data_frame,\n  y = data_frame$Notas\n)\n\ndata_frame\n\n## Matrix\n\n# Creacion\n\nmatrix <- matrix(c(1:9),\n  nrow = 3,\n  ncol = 3\n)\nmatrix\n\n# Insercion\n\nmatrix <- cbind(matrix, c(10:12))\n\nmatrix\n\n# Borrado\n\nmatrix <- matrix[1:3, 2:3]\n\nmatrix\n\n# Actualizacion\n\nmatrix <- matrix^2\n\nmatrix\n\n# Ordenacion\n\nmatrix <- sort(x = matrix)\n\nmatrix\n\n## Factor\n\n# Creacion\n\nfactor <- factor(c(\n  \"Carro\",\n  \"Moto\"\n))\n\nfactor\n\n# Insercion\n\nfactor <- factor(c(as.character(factor), \"Barco\"))\n\nfactor\n\n# Borrado\n\nfactor <- factor[-2]\n\nfactor <- droplevels(factor)\n\nfactor\n\n# Actualizacion\n\nfactor <- factor(paste0(as.character(factor), \" azul\"))\n\nfactor\nlevels(factor)\n\n# Ordenacion\n\nfactor <- factor(factor, levels = sort(levels(factor), decreasing = TRUE))\n\nfactor\n\n\n# DIFICULTAD EXTRA (opcional):\n# Crea una agenda de contactos por terminal.\n# - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n# - Cada contacto debe tener un nombre y un número de teléfono.\n# - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n#   los datos necesarios para llevarla a cabo.\n# - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n#   (o el número de dígitos que quieras)\n# - También se debe proponer una operación de finalización del programa.\n#\n\n# Crear un data frame para la agenda\n\n## Para crear la agenda, me apoyé en otras funciones:\n## La primera genera nombres aleatorios usados en EEUU (paquete \"babynames\").\n## La segunda genera numeros de teléfono falsos con un formato similar al usado en Venezuela.\n## La tercera se usa para validar que los números de teléfono sean numericos y que su longitud sea de 11.\n\nlibrary(babynames)\nlibrary(tidyverse)\n\ngenerar_tlf <- function(x) {\n  numero <- c()\n\n  for (i in 1:x) {\n    digitos <- sprintf(\"%07d\", sample(0000000:9999999, size = 1))\n    numero <- c(numero, paste0(\"0422\", digitos))\n  }\n  numero\n}\n\nconstruir_agenda <- function(x = 10) {\n  \n  agenda <<-data.frame(\n    \"Nombre\" = sample(c(unique(babynames::babynames$name)), size = x),\n    \"Telefono\" = sample(c(generar_tlf(x)))\n  ) \n}\n\nvalidar_telefono <- function(telefono) {\n  return(grepl(\"^[0-9]{11}$\", telefono))\n}\n\n\nconstruir_agenda()\n\nrevisar_agenda <- function() {\n  repeat {\n    cat(\"Selecciona una operación: 1) Buscar 2) Insertar 3) Actualizar 4) Eliminar 5) Salir\\n\")\n    opcion <- readLines(con = stdin(), n = 1)\n\n    if (opcion == \"1\") {\n      cat(\"Ingresa el nombre de la persona: (ej: Daniel, sin comillas)\\n\")\n\n      buscar_nombre <- readLines(con = stdin(), n = 1)\n\n      while (!(buscar_nombre %in% agenda$Nombre)) {\n        cat(\"Ese nombre no está en la agenda, por favor, intenta nuevamente:\")\n        buscar_nombre <- readLines(con = stdin(), n = 1)\n      }\n\n      print(agenda %>% filter(Nombre == buscar_nombre))\n\n      cat(\"\\nRegresarás al menú principal.\\n\\n\")\n      \n    } else if (opcion == \"2\") {\n      cat(\"Ingresa el nombre de la persona que quieres agregar: (ej: Daniel, sin comillas)\\n\")\n\n      agregar_nombre <- readLines(con = stdin(), n = 1)\n\n      cat(\"Ingresa el número de teléfono: (ej: 04221234567)\\n\")\n\n      agregar_numero <- readLines(con = stdin(), n = 1)\n\n      while (validar_telefono(agregar_numero) == FALSE) {\n        cat(\"Ese teléfono no es válido, por favor, intenta nuevamente:\")\n        agregar_numero <- readLines(con = stdin(), n = 1)\n      }\n\n      agenda <<- rbind(agenda, c(agregar_nombre, agregar_numero))\n      \n      cat(\"\\nEl número de\", agregar_nombre, \"fue agregado con éxito. Regresarás al menú principal.\\n\\n\")\n      \n    } else if (opcion == \"3\") {\n      cat(\"Ingresa el nombre de la persona que quieres actualizar: (ej: Daniel, sin comillas)\\n\")\n\n      actualizar_nombre <- readLines(con = stdin(), n = 1)\n\n      while (!(actualizar_nombre %in% agenda$Nombre)) {\n        cat(\"Ese nombre no está en la agenda, por favor, intenta nuevamente:\")\n        actualizar_nombre <- readLines(con = stdin(), n = 1)\n      }\n\n      cat(\"Ingresa el nuevo número de teléfono: (ej: 04221234567)\\n\")\n\n      actualizar_numero <- readLines(con = stdin(), n = 1)\n\n      while (validar_telefono(actualizar_numero) == FALSE) {\n        cat(\"Ese teléfono no es válido, por favor, intenta nuevamente:\")\n        actualizar_numero <- readLines(con = stdin(), n = 1)\n      }\n\n      agenda <<- agenda %>% mutate(Telefono = if_else(Nombre == actualizar_nombre,\n        actualizar_numero,\n        Telefono\n      ))\n\n      cat(\"\\nEl número de\", actualizar_nombre, \"fue actualizado con éxito. Regresarás al menú principal.\\n\\n\")\n      \n    } else if (opcion == \"4\") {\n      cat(\"Ingresa el nombre de la persona que quieres eliminar: (ej: Daniel, sin comillas)\\n\")\n\n      eliminar_nombre <- readLines(con = stdin(), n = 1)\n\n      while (!(eliminar_nombre %in% agenda$Nombre)) {\n        cat(\"Ese nombre no está en la agenda, por favor, intenta nuevamente:\")\n        eliminar_nombre <- readLines(con = stdin(), n = 1)\n      }\n\n      agenda <<- agenda %>% filter(Nombre != eliminar_nombre)\n\n      cat(\"\\nEl número de\", eliminar_nombre, \"fue eliminado con éxito. Regresarás al menú principal.\\n\\n\")\n    }\n    if (opcion == \"5\") break\n    # Implementa el resto de opciones aquí\n  }\n}\n\nrevisar_agenda()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/ruby/kodenook.rb",
    "content": "require 'set'\n\n=begin\n    array\n=end\n\ncars = ['bwm', 'ferrari']\n\n# insert\ncars << 'mazda'\ncars.push('chevrolet')\ncars.unshift('toyota') # add to the end\n\nputs cars\n\n# insert\n\ncars[0] = 'peugeot'\n\nputs cars\n\n# delete\n\ncars.pop # delete to the end\ncars.shift # delete to the first\ncars.delete('ferrari') # deletes by value\ncars.delete_at(1) # deletes by index\n\nputs cars\n\n=begin\n    hashes\n=end\n\ngrades = { :mark => 15, :jimmy => 10, :jack => 10 }\n\n# insert\n\ngrades.store(:elon, 13)\n\nputs grades\n\n# edit\n\ngrades[:mark] = 14\n\nputs grades\n\n# delete\n\ngrades.delete(:elon)\n\nputs grades\n\n=begin\n    Sets\n=end\n\nfruits = Set['apple', 'orange', 'lemon']\n\n\n# insert\n\nfruits.add('banana') # add and return set\nfruits.add?('banana') # add and return nil if value exists\n\nputs fruits\n\n# delete\n\nfruits.delete('banana') # deletes and return set\nfruits.delete?('banana') # deletes and return nil if value exists\n\nputs fruits\n\n=begin\n    Exercise\n=end\n\noption = 0\ndata = {}\n\nwhile option != 5 do\n\n    puts \"\\033c\"\n\n    puts '1. search'\n    puts '2. add'\n    puts '3. edit'\n    puts '4. delete'\n    puts '5. exit'\n\n    print 'choose an option: '\n    option = gets.to_i\n\n    case option\n        when 1\n            print 'name: '\n            name = gets\n\n            puts data[name]\n\n            sleep(5)\n        when 2\n            print 'name: '\n            name = gets\n            print 'number: '\n            number = gets\n\n            data.store(name, number)\n        when 3\n            print 'name: '\n            name = gets\n            print 'number: '\n            number = gets\n\n            data[name] = number\n        when 4\n            print 'name: '\n            name = gets\n\n            data.delete(name)\n    end\n\nend"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/rust/brockar.rs",
    "content": "use std::collections::HashMap;\nfn main() {\n    // Vector, similar al ArrayList\n    let mut v: Vec<i32> = vec![1, 3, 2, 5, 4, 7];\n\n    v.remove(1);\n    v.push(6);\n\n    // Ordenar vector\n    v.sort();\n\n    // Para imprimir un vector se agrega :? al {}\n    println!(\"Vector ordenado: {:?}\", v);\n\n    // String\n    let _s: String = String::from(\"Hola, mundo!\");\n    // No se puede ordenar\n\n    // Tupla\n    let tup = (1, \"hola\", 3.0);\n    // Una tupla no se puede modificar\n\n    println!(\"Tupla: {:?}\", tup);\n\n    // HashMap,\n    // guarda datos tipo Clave, Valor\n    // importar los HashMap (Esto iría al principio del archivo)\n    //use std::collections::HashMap;\n\n    let mut scores = HashMap::new();\n    // Insertar (Clave, Valor)\n    scores.insert(\"Juan\", 42);\n    scores.insert(\"Maria\", 30);\n\n    println!(\"HashMap: {:?}\", scores);\n    scores.remove(\"Maria\");\n    println!(\"HashMap con Maria eliminada: {:?}\", scores);\n\n    // No se puede ordenar un HashMap ya se accede mediante la clave y no por posición de los\n    // elementos.\n\n    // HashSet,\n    // guarda datos tipo Clave y no permite repetidos (Sin orden)\n    // Para importar el HashSet\n    use std::collections::HashSet;\n\n    // Creación\n    let mut unique_numbers = HashSet::new();\n    // Insertar\n    unique_numbers.insert(1);\n    unique_numbers.insert(3);\n    unique_numbers.insert(9);\n    unique_numbers.insert(7);\n\n    // Otra vez, no se puede ordenar un set ya que no es una estructura iterable.\n    println!(\"HashSet: {:?}\", unique_numbers);\n    unique_numbers.insert(7);\n    println!(\"HashSet con el 7 insertado dos veces: {:?}\", unique_numbers);\n\n    // VecDeque es una cola de doble extremo.\n    use std::collections::VecDeque;\n    let mut deque = VecDeque::new();\n    deque.push_front(1);\n    deque.push_back(2);\n    deque.push_front(3);\n\n    println!(\"Deque: {:?}\", deque);\n\n    println!(\"\\n\\nEXTRA EXTRA\");\n    extra();\n}\n\nuse std::io::{self, BufRead, Write};\nuse std::process::Command;\n//use std::time::Duration;\n//use std::{i32, thread};\n\nfn extra() {\n    println!(\"Presiona Enter para ingresar a la funcionalidad extra...\");\n    // Leer una línea de entrada del usuario\n    let stdin = io::stdin();\n    let _ = stdin.lock().lines().next();\n\n    // Hacer que el programa espere durante 2 segundos\n    //thread::sleep(Duration::from_secs(2));\n    let output = Command::new(\"clear\")\n        .status()\n        .expect(\"Failed to clear terminal\");\n\n    if output.success() {\n        let mut contacts: HashMap<String, u32> = HashMap::new();\n\n        loop {\n            println!(\"=== Agenda de Contactos ===\");\n            println!(\"1. Buscar contacto\");\n            println!(\"2. Insertar contacto\");\n            println!(\"3. Actualizar contacto\");\n            println!(\"4. Eliminar contacto\");\n            println!(\"5. Imprimir agenda\");\n            println!(\"6. Salir\");\n\n            print!(\"Ingrese el número de la operación que desea realizar: \");\n            io::stdout().flush().unwrap();\n\n            let mut opcion = String::new();\n            io::stdin()\n                .read_line(&mut opcion)\n                .expect(\"Error al leer la entrada\");\n\n            // Verificación de que sea un número\n            let numero: u32 = match opcion.trim().parse() {\n                Ok(numero) => numero,\n                Err(_) => {\n                    opcion_invalida();\n                    continue;\n                }\n            };\n\n            match numero {\n                1 => buscar_contacto(&contacts),\n                2 => insertar_contacto(&mut contacts),\n                3 => actualizar_contacto(&mut contacts),\n                4 => eliminar_contacto(&mut contacts),\n                5 => imprimir_agenda(&mut contacts),\n                6 => break,\n                _ => opcion_invalida(), // Si no es un número del 1 al 5\n            }\n        }\n    } else {\n        println!(\"Failed to clear terminal\");\n    }\n}\n\nfn buscar_contacto(agenda: &HashMap<String, u32>) {\n    clear_terminal();\n\n    println!(\"\\nIngrese el nombre del contacto a buscar: \");\n    let mut nombre: String = String::new();\n\n    io::stdin()\n        .read_line(&mut nombre)\n        .expect(\"Error al leer la entrada\");\n\n    nombre = nombre.trim().to_string();\n    match agenda.get(&nombre) {\n        Some(telefono) => println!(\"El número del contacto {} es: {}\", nombre, telefono),\n        None => println!(\"No se encontro el contacto\"),\n    }\n}\n\nfn insertar_contacto(agenda: &mut HashMap<String, u32>) {\n    clear_terminal();\n\n    println!(\"\\nIngrese el nombre del contacto a agregar: \");\n    let mut nombre: String = String::new();\n    io::stdin()\n        .read_line(&mut nombre)\n        .expect(\"Error al leer la entrada\");\n\n    nombre = nombre.trim().to_string();\n\n    println!(\"Ingrese el número del contacto: \");\n    let mut numero_s: String = String::new();\n    io::stdin()\n        .read_line(&mut numero_s)\n        .expect(\"Error al leer la entrada\");\n\n    if numero_s.len() > 11 {\n        println!(\"El número debe tener hasta 11 digitos\");\n        return;\n    }\n\n    let numero: u32 = match numero_s.trim().parse() {\n        Ok(numero) => numero,\n        Err(_) => {\n            opcion_invalida();\n            return;\n        }\n    };\n\n    agenda.insert(nombre.clone(), numero);\n    println!(\"Contacto agendado: {} \\nCon el numero: {}\", nombre, numero);\n}\n\nfn actualizar_contacto(agenda: &mut HashMap<String, u32>) {\n    println!(\"\\nIngrese el nombre del contacto a modificar: \");\n    let mut nombre: String = String::new();\n    io::stdin()\n        .read_line(&mut nombre)\n        .expect(\"Error al leer la entrada\");\n    nombre = nombre.trim().to_string();\n\n    if agenda.contains_key(&nombre.clone()) {\n        println!(\"Ingrese el nuevo número del contacto: \");\n        let mut numero_s: String = String::new();\n        io::stdin()\n            .read_line(&mut numero_s)\n            .expect(\"Error al leer la entrada\");\n\n        if numero_s.len() > 11 {\n            println!(\"El número debe tener hasta 11 digitos\");\n            return;\n        }\n\n        let numero: u32 = match numero_s.trim().parse() {\n            Ok(numero) => numero,\n            Err(_) => {\n                opcion_invalida();\n                return;\n            }\n        };\n\n        agenda.insert(nombre, numero);\n    } else {\n        println!(\"El contacto no existe\");\n    }\n}\n\nfn eliminar_contacto(agenda: &mut HashMap<String, u32>) {\n    println!(\"\\nIngrese el nombre del contacto a modificar: \");\n    let mut nombre: String = String::new();\n    io::stdin()\n        .read_line(&mut nombre)\n        .expect(\"Error al leer la entrada\");\n    nombre = nombre.trim().to_string();\n\n    if agenda.contains_key(&nombre.clone()) {\n        agenda.remove(&nombre);\n        println!(\"Contacto {} eliminado\", nombre);\n    } else {\n        println!(\"El contacto no existe\");\n    }\n}\n\nfn opcion_invalida() {\n    clear_terminal();\n    println!(\"Entrada inválida, por favor, ingresa una entrada válida.\");\n}\n\nfn clear_terminal() {\n    Command::new(\"clear\")\n        .status()\n        .expect(\"Failed to clear terminal\");\n}\n\nfn imprimir_agenda(agenda: &mut HashMap<String, u32>) {\n    let multi_line = \"\n ____________________________________________\\n\n/                                            \\\\\\n\n|              Agenda de Contactos           |\\n\n|____________________________________________|\";\n    println!(\"{}\", multi_line);\n    if !agenda.is_empty() {\n        for (k, v) in agenda {\n            println!(\"|   Nombre: {}, numero: {}             |\", k, v);\n        }\n        println!(\"|____________________________________________|\");\n    } else {\n        println!(\"Agenda vacia\");\n    }\n}"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/rust/gabrielmoris.rs",
    "content": "/*\n * EXERCISE:\n * - Provide examples of creating all default-supported structures in your language.\n * - Use insertion, deletion, updating, and sorting operations.\n *\n */\n\nuse std::io::{ self };\nuse std::collections::HashMap;\n\nfn main() {\n    // Arays: Are Fixed size. They are created with [T; N] there T is type and N is size\n    let mut array: [i32; 5] = [1, 5, 2, 4, 3];\n    array.sort(); // it doesnt return the sorted array, it justs sorts the original array;\n    let found = array.binary_search(&5);\n    array[3] = 5;\n    println!(\"{:?}\", found);\n\n    // Vectors: Are dynamic in size\n    let mut fruits: Vec<&str> = vec![\"apple\", \"banana\", \"cherry\"];\n    fruits.push(\"orange\");\n    let fruits_to_string = fruits.join(\"/\");\n    print!(\"{fruits_to_string}\\n\");\n    let dramatic_fruits: Vec<String> = fruits\n        .iter()\n        .map(|x| format!(\"{}!\", x))\n        .collect();\n    println!(\"{:?}\", dramatic_fruits);\n    let filter_fruits: Vec<String> = dramatic_fruits\n        .iter()\n        .filter(|x| x.contains(\"pp\"))\n        .cloned()\n        .collect();\n    // I need to clone and collect to actually send the filtered vector\n    println!(\"{:?}\", filter_fruits);\n\n    // Tuples: Are fixed size and can handle different types\n    let tup = (71, \"a\", false);\n    let first = tup.0.to_owned();\n    print!(\"{:?}\\n\", first);\n\n    // Structs: User-defined data types that can hold data of different types\n    struct Person {\n        name: String,\n        age: u32,\n        is_student: bool,\n    }\n    let gabriel = Person {\n        name: String::from(\"Gabriel\"),\n        age: 34,\n        is_student: false,\n    };\n    let student_status = if gabriel.is_student { \"\" } else { \"not \" };\n    print!(\n        \"my name is {}, I have {} years old and I am {}a student\\n\",\n        gabriel.name,\n        gabriel.age,\n        student_status\n    );\n\n    // Enums: User-defined data types that represent a fixed set of possibilities\n    #[derive(Debug)]\n    enum Color {\n        _Red,\n        Green,\n        _Blue,\n    }\n    let my_color = Color::Green;\n    println!(\"{:?}\", my_color);\n\n    // HashMaps: unordered collections of key-value pairs\n    // use std::collections::HashMap; It is already imported, but I note here as a cutiosity that it must be imported.\n    let mut scores: HashMap<String, u32> = HashMap::new();\n    scores.insert(\"Alice\".to_string(), 90);\n    scores.insert(\"Bob\".to_string(), 85);\n    let it_print = scores.get_key_value(\"Alice\");\n    println!(\"{:?}\", it_print);\n    challenge()\n}\n/*\n * EXTRA CHALLENGE (optional):\n * Create a terminal-based contact agenda.\n * - Implement functionalities for searching, inserting, updating, and deleting contacts.\n * - Each contact should have a name and a phone number.\n * - The program first prompts the user to choose the desired operation,\n *   and then collects the necessary data to carry it out.\n * - The program should not allow non-numeric phone numbers with more than\n *   11 digits (or the number of digits you prefer).\n * - Additionally, propose an operation to exit the program.\n */\n\nfn challenge() {\n    let mut contacts: HashMap<String, String> = HashMap::new();\n\n    loop {\n        println!(\n            \"\n            ===========================\n            What would you like to do?\n            1. Add a contact\n            2. Delete a contact\n            3. Search a contact\n            4. Edit a contact\n            5. Exit\n            ===========================\n            \"\n        );\n\n        let mut input = String::new();\n        io::stdin().read_line(&mut input).expect(\"Failed to read line\");\n\n        let choice: u32 = input.trim().parse().expect(\"Invalid input\");\n\n        match choice {\n            1 => add_contact(&mut contacts),\n            2 => delete_contact(&mut contacts),\n            3 => search_contact(&mut contacts),\n            4 => edit_contact(&mut contacts),\n            5 => {\n                println!(\"Goodbye!\");\n                break;\n            }\n            _ => println!(\"Invalid choice. Please try again.\"),\n        }\n\n        println!();\n    }\n}\n\nfn add_contact(contacts: &mut HashMap<String, String>) {\n    println!(\"Enter the contact Name\");\n    let mut name: String = String::new();\n    io::stdin().read_line(&mut name).expect(\"Failed to read name\");\n    let name: String = name.trim().to_string();\n    println!(\"Enter the phone number\");\n    let mut phone: String = String::new();\n    io::stdin().read_line(&mut phone).expect(\"Failed to read phone\");\n    let phone: String = phone.trim().to_string();\n\n    if phone.len() > 11 {\n        println!(\"The phone number must be shorter than 11 digits.\")\n    } else {\n        contacts.insert(name, phone);\n    }\n}\n\nfn delete_contact(contacts: &mut HashMap<String, String>) {\n    println!(\"Enter the contact Name that you want to DELETE\");\n    let mut name: String = String::new();\n    io::stdin().read_line(&mut name).expect(\"Failed to read name\");\n    let name: String = name.trim().to_string();\n\n    contacts.remove(&name);\n    println!(\"{name} has ben deleted.\");\n}\n\nfn search_contact(contacts: &mut HashMap<String, String>) {\n    println!(\"Enter the contact Name\");\n    let mut name: String = String::new();\n    io::stdin().read_line(&mut name).expect(\"Failed to read name\");\n    let name: String = name.trim().to_string();\n    let found_contact = contacts.get(&name);\n\n    match found_contact {\n        Some(phone) => println!(\"{}'s phone is {}\", name, phone),\n        None => println!(\"Contact not found.\"),\n    }\n}\n\nfn edit_contact(contacts: &mut HashMap<String, String>) {\n    println!(\"Enter the contact Name\");\n    let mut name = String::new();\n    io::stdin().read_line(&mut name).expect(\"Failed to read name\");\n    let name = name.trim().to_string();\n\n    // Separate scope for the immutable reference\n    {\n        let found_contact = contacts.get(&name);\n\n        match found_contact {\n            Some(existing_name) => {\n                // Clone the existing name to avoid borrowing issues\n                let existing_name_clone = existing_name.clone();\n                contact_edition(contacts);\n                contacts.remove(&existing_name_clone);\n            }\n            None => {\n                println!(\n                    \"Contact not found. Do you want to add a new contact with this name? (y/n)\"\n                );\n                let mut response = String::new();\n                io::stdin().read_line(&mut response).expect(\"Failed to read response\");\n                let response = response.trim().to_lowercase();\n\n                if response == \"y\" || response == \"yes\" {\n                    add_contact(contacts);\n                } else {\n                    println!(\"No changes made.\");\n                }\n            }\n        }\n    } // Immutable reference ends here\n\n    // Now you can safely mutate `contacts` outside the inner scope\n}\n\nfn contact_edition(contacts: &mut HashMap<String, String>) {\n    println!(\"Enter New Name\");\n    let mut new_name = String::new();\n    io::stdin().read_line(&mut new_name).expect(\"Failed to read name\");\n    let new_name = new_name.trim().to_string();\n\n    println!(\"Enter the new phone number\");\n    let mut phone = String::new();\n    io::stdin().read_line(&mut phone).expect(\"Failed to read phone\");\n    let phone = phone.trim().to_string();\n\n    if phone.len() > 11 {\n        println!(\"The phone number must be shorter than 11 digits.\");\n    } else {\n        // Insert the updated contact\n        contacts.insert(new_name, phone);\n    }\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/rust/kenysdev.rs",
    "content": "// no advertencia(variables no utilizadas)\n#![allow(unused_variables)]\n/*\n╔═══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado                ║\n║ GitHub: https://github.com/Kenysdev   ║\n║ 2024 -  Rust                          ║\n╚═══════════════════════════════════════╝\n\n-----------------------------------------\n* ESTRUCTURAS DE DATOS\n-----------------------------------------\n*/\nuse std::io::{self, Write};\nuse std::collections::HashSet;\nuse std::collections::HashMap;\n\nfn main() {\n    //_____________________________________________\n    // * Tupla\n    // - Para agrupar varios valores de distintos tipos.\n    // - Tienen una longitud fija.\n    let tuple: (i8, &str, bool) = (12, \"abc\", true);\n    \n    // Obtener los valores individuales\n    let (a, b, c) = tuple;\n    println!(\"tupla: {a}-{b}-{c}\");\n    \n    // Acceder mediante índice\n    println!(\"item-tupla: {}\", tuple.2);\n\n    //_____________________________________________\n    // * Arreglo\n    // - Cada elemento debe tener el mismo tipo.\n    // - Tienen una longitud fija.\n    let array = [1, 2, 3, 4];\n\n    //  Inicializar para contener el mismo valor.\n    let array = [3; 4]; // [3, 3, 3, 3]\n\n    // Especificar tipo de un arreglo\n    let array: [i32; 4] = [1, 2, 3, 4];\n\n    // Acceder mediante índice\n    println!(\"item-array: {}\", array[3]);\n\n    //_____________________________________________\n    // * Vectores (Vec<T>)\n    // - Solo valores del mismo tipo.\n    // - Puede cambiar de tamaño.\n    let vector: Vec<i32> = Vec::new();\n\n    // Creará un nuevo vector con valores dados.\n    // Rust puede inferir que el tipo.\n    let mut vector = vec![\"a\", \"b\", \"c\"];\n\n    // Agregar elementos\n    vector.push(\"d\");\n    vector.push(\"e\");\n\n    // Acceder mediante índice o *get*\n    println!(\"item-vector: {}\", vector[1]);\n\n    match vector.get(10) {\n        Some(valor) => println!(\"item-vector: {valor}\"),\n        None => println!(\"indice en vector fuera de rango.\"),\n    }\n    \n    // NOTE: \n    // - Si es por *indice* causará que el programa falle cuando\n    //   intente acceder a un elemento que no existe.\n    // - si es con *get* simplemente devuelve *None* sin entrar en pánico.\n    // Modificar\n    vector[4] = \"z\"; \n    println!(\"item-vector: {}\", vector[4]);\n\n    // Eliminar\n    vector.remove(4);\n    // Eliminar ultimo y obtener\n    if let Some(last) = vector.pop() { \n        println!(\"delete-vector: {last}\");\n    }\n\n    // Buscar\n    // Devuelve el índice del primer elemento que cumple con la condición.\n    let index = vector.iter().position(|&i| i == \"c\");\n    match index {\n        Some(idx) => println!(\"indice-vector: {idx}\"),\n        None => println!(\"no se encontró.\"),\n    }\n    \n    // Devuelve una referencia al primer elemento que cumple con la condición.\n    let item: Option<&&str> = vector.iter().find(|&&i| i == \"c\");\n    match item {\n        Some(&i) => println!(\"Elemento-vector: {i}\"),\n        None => println!(\"no se encontró.\"),\n    }\n\n    //_____________________________________________\n    // * HashSet\n    // - Debe contener elementos del mismo tipo.\n    // - Puede cambiar de tamaño.\n    // - No guarda duplicados.\n    // - Sin indice ni orden.\n    let mut set: HashSet<&str> = HashSet::new();\n\n    // Agregar elementos\n    set.insert(\"a\"); \n    set.insert(\"b\"); \n    set.insert(\"c\");\n\n    // Verificar\n    if set.contains(\"b\") {\n        println!(\"El conjunto contiene 'b'\");\n    }\n    \n    // elimionar\n    set.remove(\"c\");\n\n    //_____________________________________________\n    // * HashMap\n    // - De pares clave-valor\n    let mut contacts: HashMap<String, u64> = HashMap::new();\n\n    // Agregar elementos\n    contacts.insert(\"Ben\".to_string(), 111);\n    contacts.insert(\"zoe\".to_string(), 222);\n    contacts.insert(\"Dan\".to_string(), 333);\n\n    // Acceder\n    if let Some(value) = contacts.get(\"Dan\") {\n        println!(\"Valor de 'Dan' es: {value}\");\n    } \n\n    // Eliminar\n    if let Some(value) = contacts.remove(\"c\") {\n        println!(\"Se eliminó clave 'Dan' y valor {value}\");\n    }\n    \n    // Iterar\n    for (key, value) in &contacts {\n        println!(\"Nombre: {key}, Numero: {value}\");\n    }\n    \n    /*_____________________________________________\n    // * Ejercicio:\n    * Crea una agenda de contactos por terminal.\n    * - Debes implementar funcionalidades de búsqueda, inserción, \n        actualización y eliminación de contactos.\n    * - Cada contacto debe tener un nombre y un número de teléfono.\n    * - El programa solicita en primer lugar cuál es la operación \n        que se quiere realizar y a continuación los datos necesarios\n        para llevarla a cabo.\n    * - El programa no puede dejar introducir números de teléfono no\n        númericos y con más de 11 dígitos.\n    * - También se debe exister operación de finalización del programa.\n    */\n\n    contact_book(&mut contacts);\n}\n\nconst MSG: &str  = \"\nAgenda de contactos\n╔═══════════════════════════╗\n║ 1. Nuevo      4. Editar   ║\n║ 2. Buscar     5. Eliminar ║\n║ 3. Lista      6. Salir    ║\n╚═══════════════════════════╝\n\";\n\nfn contact_book(contacts: &mut HashMap<String, u64>) {\n    println!(\"{MSG}\");\n    let option: String = input(\"Escriba opción: \");\n    \n    match option.trim() {\n        \"1\" => create(contacts),\n        \"2\" => search(contacts),\n        \"3\" => list(contacts),\n        \"4\" => edit(contacts),\n        \"5\" => delete(contacts),\n        \"6\" => println!(\"Adiós\"),\n        _ => {\n            println!(\"Número 1 -> 6\");\n            contact_book(contacts);\n        }\n    }\n}\n\nfn create(contacts: &mut HashMap<String, u64>) {\n    println!(\"Crear contacto o '6' para Salir\");\n    let name: String = input(\"Escriba el nombre: \");\n    \n    if name.is_empty() {\n        create(contacts);\n    } else if name == \"6\" {\n        contact_book(contacts);\n    } else if !contacts.contains_key(&name) {\n        add_num(name, contacts);\n    } else {\n        println!(\"El nombre ya existe.\\n\");\n        create(contacts);\n    }\n}\n\nfn add_num(name: String, contacts: &mut HashMap<String, u64>) {\n    let num: String = input(\"Escriba el número: \");\n    if num == \"6\" {\n        contact_book(contacts);\n    } else if !num.is_empty() && num.len() < 12 && is_integer(&num) {\n        contacts.insert(name.clone(), num.parse::<u64>().unwrap());\n        println!(\"Guardado\");\n        contact_book(contacts);\n    } else {\n        println!(\"Ingrese un número con menos de 11 dígitos.\");\n        add_num(name, contacts)\n    }\n}\n\nfn search(contacts: &mut HashMap<String, u64>) {\n    println!(\"Buscar contacto o '6' para Salir\");\n    let name: String = input(\"Escriba el nombre: \");\n    if name == \"6\" {\n        contact_book(contacts);\n    } else if let Some(value) = contacts.get(&name) {\n        println!(\"{name} - {value}\\n\");\n        search(contacts);\n    } else {\n        println!(\"Contacto no encontrado.\\n\");\n        search(contacts);\n    }\n}\n\nfn list(contacts: &mut HashMap<String, u64>) {\n    for (name, number) in &mut *contacts {\n        println!(\"{name} - {number}\");\n    }\n    contact_book(contacts);\n}\n\nfn edit(contacts: &mut HashMap<String, u64>) {\n    println!(\"Editar contacto o '6' para Salir\");\n    let name: String = input(\"Escriba el nombre: \");\n    if name == \"6\" {\n        contact_book(contacts);\n    } else if contacts.contains_key(&name) {\n        add_num(name, contacts);\n    } else {\n        println!(\"Contacto no encontrado.\\n\");\n        edit(contacts)\n    }\n}\n\nfn delete(contacts: &mut HashMap<String, u64>) {\n    println!(\"Eliminar contacto o '6' para Salir\");\n    let name: String = input(\"Escriba el nombre: \");\n    if name == \"6\" {\n        contact_book(contacts);\n    } else if let Some(value) = contacts.remove(&name) {\n        println!(\"{name} - {value} fue eliminado.\");\n        contact_book(contacts);\n    } else {\n        println!(\"Contacto no encontrado.\\n\");\n        delete(contacts);\n    }\n}\n\nfn is_integer(var: &str) -> bool {\n    if let Ok(numero) = var.parse::<u64>() {\n        true\n    } else {\n        false\n    }\n}\n\nfn input(msg: &str) -> String {\n    print!(\"{msg}\");\n    io::stdout().flush().expect(\"Error: limpiar búfer\");\n\n    let mut input_txt: String = String::new();\n    io::stdin()\n        .read_line(&mut input_txt)\n        .expect(\"Error al leer la entrada\");\n\n    input_txt.trim().to_string()\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/rust/raulfauli.rs",
    "content": "/// #03 ESTRUCTURAS DE DATOS\n///\n/// Para compilar y ejecutar este código, ejecuta el siguiente comando desde el directorio principal:\n///\n/// `rustc ./Roadmap/03\\ -\\ ESTRUCTURAS\\ DE\\ DATOS/rust/raulfauli.rs && ./raulfauli && rm raulfauli`\n///\nuse std::io;\n\nfn main() {\n    // Array de tamaño fijo\n    let mut languages: [&str; 4] = [\"Rust\", \"Java\", \"Kotlin\", \"Swift\"];\n\n    // Iterar sobre un array\n    languages.iter().for_each(|lang| println!(\"{}\", lang));\n\n    // languages.push(\"Python\"); // Error: no se puede modificar un array\n    languages[0] = \"Rust Lang\"; // Ok\n\n    let length = languages.len();\n    println!(\"Número de lenguajes: {}\", length);\n\n    let first = languages[0]; // También languages.get(0);\n    println!(\"First lenguage: {first}\");\n\n    let first = languages.first().unwrap();\n    println!(\"First lenguages: {first}\");\n\n    let last = languages[length - 1];\n    println!(\"Last lenguage: {last}\");\n\n    let last = languages.last().unwrap();\n    println!(\"Last lenguages: {last}\");\n\n    let contains = languages.contains(&\"Dart\");\n    println!(\"Languages: {:?} contains Dart? {}\", languages, contains);\n\n    // Vector\n    let mut numbers: Vec<i32> = vec![1, 2, 3, 4, 5];\n    numbers.push(6);\n    numbers.remove(0);\n    numbers.extend([7, 8, 9].iter().cloned());\n\n    let contains = numbers.contains(&3);\n    println!(\"Numbers: {:?} contains 3? {}\", numbers, contains);\n\n    // Tuplas (2 maneras de declararlas)\n    let location = (10, 20);\n    println!(\"Location: ({}, {}) type (i32, i32)\", location.0, location.1);\n\n    let x = Location(10, 20);\n    println!(\"Location: ({}, {}) type Location\", x.0, x.1);\n\n    // Estructuras\n    let person = Person {\n        name: String::from(\"Raúl\"),\n        phone: 123_456_789,\n    };\n\n    println!(\"{}: {}\", person.name, person.phone);\n\n    // Estructura con implementación\n    let person2 = Person::new(\"Fayu\", 777_777_777);\n    println!(\"{}: {}\", person2.name, person2.phone);\n\n    // Extra\n    let mut agenda: Vec<Person> = vec![person, person2];\n    loop {\n        println!(r#\"\n        1. Añadir contacto\n        2. Eliminar contacto\n        3. Buscar contacto\n        4. Listar contactos\n        5. Salir \"Crtl + C\"\n        \"#);\n\n        let mut input = String::new();\n        io::stdin().read_line(&mut input).unwrap();\n        match input.trim() {\n            \"1\" => add_contact(&mut agenda),\n            \"2\" => delete_contact(&mut agenda),\n            \"3\" => find_contacts(&agenda),\n            \"4\" => list_contacts(&agenda),\n            \"5\" => break,\n            _ => println!(\"Opción no válida\"),\n        }\n    }\n}\n\nstruct Location(i32, i32);\n\nstruct Person {\n    name: String,\n    phone: u64,\n}\n\nimpl Person {\n    fn new(name: &str, phone: u64) -> Person {\n        Person {\n            name: String::from(name),\n            phone,\n        }\n    }\n}\n\nfn add_contact(agenda: &mut Vec<Person>) {\n    let name = input_name();\n    let phone = input_phone();\n\n    let person = Person::new(&name, phone);\n    agenda.push(person);\n}\n\nfn delete_contact(agenda: &mut Vec<Person>) {\n    let name = input_name();\n\n    let index = agenda.iter().position(|person| person.name == name).unwrap();\n    if Some(index).is_some() {\n        agenda.remove(index);\n    }\n}\n\nfn find_contacts(agenda: &Vec<Person>) {\n    let name = input_name();\n\n    agenda.iter().for_each(|person| {\n        if person.name == name {\n            println!(\"{}: {}\", person.name, person.phone);\n        }\n    });\n}\n\nfn list_contacts(agenda: &Vec<Person>) {\n    agenda.iter().for_each(|person| {\n        println!(\"{}: {}\", person.name, person.phone);\n    });\n}\n\nfn input_name() -> String {\n    println!(\"Nombre:\");\n\n    let name = loop {\n        let mut input = String::new();\n        io::stdin().read_line(&mut input).unwrap();\n\n        input = input.trim().to_string();\n\n        if input.is_empty() {\n            println!(\"Nombre es requerido\");\n        } else {\n            break input;\n        }\n    };\n\n    return name;\n}\n\nfn input_phone() -> u64 {\n    println!(\"Teléfono:\");\n\n    let phone = loop {\n        let mut input = String::new();\n        io::stdin().read_line(&mut input).unwrap();\n\n        input = input.trim().replace(\" \", \"\");\n        if input.len() > 11 {\n            println!(\"Teléfono no válido\");\n            continue;\n        }\n\n        let phone: u64 = match input.trim().parse() {\n            Ok(num) => num,\n            Err(_) => {\n                println!(\"Teléfono debe ser un número\");\n                continue;\n            }\n        };\n\n        break phone;\n    };\n\n    return phone;\n}\n\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/scala/rianojnicolas.scala",
    "content": "import scala.util.matching.Regex\nimport collection.immutable.SortedMap \nimport scala.collection.immutable.SortedSet\n\nobject Main {\n    def main(args: Array[String]): Unit = {\n\n        // 1. Estrucutras de datos\n\n        // 1.1 Listas:\n        val myList = List(1, 2, 3, 4, 5)\n        println(s\"Lista = $myList\\n\")\n\n        // 1.2 Secuencias:\n        val mySeq = Seq(1, 2, 3, 4, 5)\n        println(s\"Secuencia = $mySeq\\n\")\n\n        // 1.2 Maps:\n        val myMap = Map(1 -> \"one\", 2 -> \"two\")\n        println(s\"Map = $myMap\\n\")\n\n        // 1.3 Tuplas:\n        val myTupla = (1, \"one\", 7.0, \"seven\")\n        println(s\"Tupla = $myTupla\\n\")\n\n        // 1.4 Array:\n        val myArray = Array(1, 2, 3, 4, 5)\n        println(s\"Array = ${myArray.toString}\\n\")\n\n        // 1.5 Vector:\n        val myVector = Vector(1, 2, 3, 4, 5)\n        println(s\"Vector = $myVector\\n\")\n\n        // 1.6 Sets:\n        val mySet = Set(1, 2, 3, 4, 5)\n        println(s\"Set = $mySet\\n\")\n\n        // 2. Operando con las estructuras\n\n        // Listas:\n        println(s\"Lista Inicial = ${myList}\")\n        var secondList = myList :+ 6 // Insercion\n        println(s\"Lista despues de agregar un elemento = ${secondList}\")\n        var secondList_filter = secondList.filter(_!=3) // Borrado\n        println(s\"Lista despues de borrar elementos = ${secondList_filter}\")\n        var secondList_updated = secondList_filter.updated(1, 10) // Actualizacion\n        println(s\"Lista actualizada = ${secondList_updated}\")\n        var secondList_sorted = secondList_updated.sorted // Ordenacion\n        println(s\"Lista ordenada = ${secondList_sorted}\\n\")\n\n        // Secuencias:\n        println(s\"Secuencia Inicial = ${mySeq}\")\n        var secondSeq = mySeq :+ 6 // Insercion\n        println(s\"Secuencia despues de agregar un elemento = ${secondSeq}\")\n        var secondSeq_filter = secondSeq.filter(_!=3) // Borrado\n        println(s\"Secuencia despues de borrar elementos = ${secondSeq_filter}\")\n        var secondSeq_updated = secondSeq_filter.updated(1, 10) // Actualizacion\n        println(s\"Secuencia actualizada = ${secondSeq_updated}\")\n        var secondSeq_sorted = secondSeq_updated.sorted // Ordenacion\n        println(s\"Secuencia ordenada = ${secondSeq_sorted}\\n\")\n\n        // Maps:\n        println(s\"Map Inicial = ${myMap}\")\n        var sencondMap = myMap + (100 -> \"One hundred\") + (3 -> \"Three\")  // Insercion\n        println(s\"Map despues de agregar un elemento = ${sencondMap}\")\n        var secondMap_filter = sencondMap - 1 // Borrado\n        println(s\"Map despues de borrar el elemento con clave 1 = ${secondMap_filter}\")\n        var secondMap_updated = secondMap_filter + (3 -> \"Tres\") // Actualizacion\n        println(s\"Map actualizado = ${secondMap_updated}\")\n        var secondMap_sorted = SortedMap.empty[Int, String] ++ secondMap_updated // Ordenacion\n        println(s\"Map ordenado = ${secondMap_sorted}\\n\")\n\n        // Tuplas\n        println(s\"Tupla Inicial = ${myTupla}\")\n        var sencondTupla =  myTupla ++ (300, 10) // Insercion\n        println(s\"Tupla despues de agregar elementos = ${sencondTupla}\")\n        var secondTupla_delete = (sencondTupla._1, sencondTupla._3, sencondTupla._5, sencondTupla._6) \n        println(s\"Tupla despues de borrar = ${secondTupla_delete}\")\n        var secondTupla_updated = (secondTupla_delete._1, 8, secondTupla_delete._3, secondTupla_delete._4)  // Actualizacion\n        println(s\"Tupla actualizada = ${secondTupla_updated}\")\n        var secondList_Tuple = (secondTupla_updated).toList // Ordenar\n        var secondListTupla_order = secondList_Tuple.sorted\n        var SecondTupla_ordered = secondListTupla_order match {\n            case List(a, b) => (a,b)\n            case List(a, b, c) => (a,b,c)\n            case List(a, b, c, d) => (a,b,c,d)\n        }\n        println(s\"Tupla ordenada = ${SecondTupla_ordered}\\n\")\n\n        // Arrays No se puede visualizar muy bien\n        // No encontre mucha documentación al respecto\n        println(s\"Array Inicial = ${myArray} \\n\")\n\n        // Vectores\n        println(s\"Vector Inicial = ${myVector}\")\n        var sencondVector =  myVector ++ Vector(300, 10) // Insercion\n        println(s\"Vector despues de agregar un elemento = ${sencondVector}\")\n        val elementoEliminar = 10\n        var secondVector_delete = sencondVector.filterNot(_ == elementoEliminar) // Borrar\n        println(s\"Vector despues de borrar = ${secondVector_delete}\")\n        val indice = 3\n        val nuevoValor = 500\n        var sencondVector_updated = secondVector_delete.updated(indice, nuevoValor) // Actualización\n        println(s\"Vector actualizado = ${sencondVector_updated}\")\n        var secondVector_sorted = sencondVector_updated.sorted // Ordenar\n        println(s\"Vector ordenado = ${secondVector_sorted}\\n\")\n\n        // Sets\n        println(s\"Set Inicial = ${mySet}\")\n        var secondSet =  mySet + 300 + 10 // Insercion\n        println(s\"Set despues de agregar elementos = ${secondSet}\")\n        var secondSet_delete = secondSet - 5 // Borrado\n        println(s\"Set despues de borrar = ${secondSet_delete}\")\n        var secondSet_up1 = secondSet_delete - 3\n        var secondSet_update = secondSet_up1 + 1050 // Actualizacion\n        println(s\"Set actualizado = ${secondSet_update}\")\n        var set_sorted = secondSet_update.to(SortedSet) // Ordenar\n        println(s\"Set ordenado = ${set_sorted}\\n\")\n\n        // ----------------------------------------------------------- \n        // DIFICULTAD EXTRA                                          |\n        // -----------------------------------------------------------\n        var mapContacts = Map(\n            \"3015675434\" -> \"Lucho Diaz\",\n            \"3106742354\" -> \"Rigoberto Uran\",\n            \"3205438756\" -> \"Pedro Urango\")\n\n        def welcome_Menu(): String = {\n            println(\"\"\"\n                Hola !!, soy tu agenda de contactos. Aca puedes agregar, \n                actualizar, borrar y buscar cualquiera de tus contactos.\n\n                Recuerda que el contacto simplemente tiene el nombre y el\n                telefono correspondiente.\n\n                ¡¡¡ Comencemos!!!  \n                \"\"\")\n            println(\"Ingresa tu nombre: \")\n            var name = scala.io.StdIn.readLine()\n            println(\"Ingresa tu nombre: \")\n            var option = mainMenu(name)\n            return option\n        }\n\n        def mainMenu(userName:String): String = { \n            println(s\"$userName, escoge alguna de las siguientes opciones: \")\n            println(\"\"\"\n                1. Busqueda de contactos\n                2. Agregar un contacto\n                3. Actualizar un contacto\n                4. Eliminar un contacto\n                5. Salir \n                \"\"\")\n            println(\"Ingresa la acción a realizar: \")\n            var option = scala.io.StdIn.readLine()\n            while (option != \"1\" && option != \"2\" && option != \"3\" && option != \"4\" && option != \"5\") {\n                println(\"Ingresaste un valor erroneo, vuelvelo a intentar\")\n                println(\"Ingresa la acción a realizar: \")\n                option = scala.io.StdIn.readLine() \n            }\n            return option\n        }\n\n        def check_Input(numberContact: String): Boolean =  {\n            val patron: Regex = \"\"\"^\\d{10}$\"\"\".r\n            // Expresión regular para comprobar que tenga 10 dígitos y no contenga ningún carácter alfabético\n            // Devolver True si el número cumple el patrón, o False en caso contrario\n            return patron.findFirstIn(numberContact).isDefined\n        }\n\n        def printContacts(mapContacts: Map[String, String]): Unit = {\n            println(\"Tu agenda queda de la siguiente manera:\")\n            for ((clave, valor) <- mapContacts) {\n                println(s\"${valor} su numero es ${clave}\")\n            }\n        }\n\n        def find_Contact(numberContact: String, nameContact: String, option: String): Unit = {\n            if (option == \"1\") {\n                var contact = mapContacts.getOrElse(numberContact, \"No existe el numero de celular\")\n                println(s\"El numero de celular ${numberContact} le corresponde a ${contact}\")\n            }\n            else if (option == \"2\") {\n                var keys: List[String] = List()\n                for ((clave, valor) <- mapContacts) {\n                    if (valor == nameContact) {\n                        keys = keys ::: List(clave)\n                    }\n                }\n                println(s\"${nameContact} tiene el numero de celular ${keys.mkString(\", \")}\")\n            }\n        }\n\n        def add_Contact(numberContact: String, nameContact: String): Unit = {\n            mapContacts ++= Map(numberContact -> nameContact)\n            println(s\"Agregaste a tu agenda de contactos el nombre ${nameContact}\")\n            println(s\"y le asignaste el numero de celular ${numberContact} \\n\")\n            printContacts(mapContacts)\n        }\n\n        def del_Contact(numberContact: String, nameContact: String, option: String): Unit = {\n            if (option == \"1\") {\n                var contact = mapContacts.getOrElse(numberContact, \"No existe el numero de celular\")\n                println(s\"¿Estas seguro que deseas eliminar el contacto de ${contact} con el numero ${numberContact}?\")\n                println(\"Ingresa Yes/No: \")\n                val delete = scala.io.StdIn.readLine()\n                if (delete == \"Yes\"){\n                    mapContacts = mapContacts - numberContact\n                }\n            }\n            else if (option == \"2\") {\n                var keys: List[String] = List()\n                for ((clave, valor) <- mapContacts) {\n                    if (valor == nameContact) {\n                        keys = keys ::: List(clave)\n                    }\n                }   \n                for (item <- keys) {\n                    println(s\"Encontramos que para el contacto de ${mapContacts.getOrElse(item, \"No existe el numero de celular\")} se tiene el numero ${item}\")\n                    println(\"Deseas Eliminarlo totalmente Yes/No: \")\n                    var delete = scala.io.StdIn.readLine()\n                    if (delete == \"Yes\") {\n                        mapContacts = mapContacts - item\n                    }\n                    else if (delete == \"No\") {}\n                    else {\n                        println(\"Ingresaste una opción incorrecta\")\n                    }\n                }\n            }\n        }\n\n        def update_Contact(numberContact: String, nameContact: String, option: String): Unit = {\n            if (option == \"1\") {\n                var contact = mapContacts.getOrElse(numberContact, \"No existe el numero de celular\")\n                println(s\"Vas a actualizar el contacto de ${contact} con el numero ${numberContact}\")\n                println(s\"¿Que numero deseas colocar ahora al contacto ${contact}?\")\n                println(\"Ingresalo aqui: \")\n                var newNumberContact = scala.io.StdIn.readLine()\n\n                while (!(check_Input(newNumberContact))){\n                    println(\"Ingresaste un valor erroneo, vuelvelo a intentar\")\n                    println(\"Ingresalo nuevamente: \")\n                    newNumberContact = scala.io.StdIn.readLine()\n                }\n                \n                println(s\"Vas a actualizar ${numberContact} por ${newNumberContact}\")\n                println(\"¿ Estas segur@ de realizar esta operacion ? (Yes/No): \")\n                var update = scala.io.StdIn.readLine()\n                if (update == \"Yes\"){\n                    mapContacts = mapContacts - numberContact\n                    mapContacts ++= Map(newNumberContact -> contact)\n                }\n            }\n            else if (option == \"2\"){\n                var keys: List[String] = List()\n                for ((clave, valor) <- mapContacts) {\n                    if (valor == nameContact) {\n                        keys = keys ::: List(clave)\n                    }\n                }\n                \n                for (item <- keys) {\n                    println(s\"Encontramos que para el contacto de ${mapContacts.getOrElse(item, \"No existe el numero de celular\")} se tiene el numero ${item}\")\n                    println(s\"Ingresa el nuevo nombre que le pondras al contacto: \")\n                    var newNameContact = scala.io.StdIn.readLine()\n                    println(s\"Deseas actualizar el nombre ${nameContact} por ${newNameContact} Yes/No: \")\n                    var update = scala.io.StdIn.readLine()\n                    if (update == \"Yes\") {\n                        mapContacts = mapContacts - item\n                        mapContacts ++= Map(item -> newNameContact)\n                    }    \n                }\n            \n                printContacts(mapContacts)\n            }\n        }\n\n\n        def execute_Option(option: String): Boolean = {\n            var still = true\n            if (option == \"1\") {\n                println(\"\"\"\n                Para realizar la busqueda de algun contacto tienes dos opciones:\n                    1. Buscar por el numero de telefono\n                    2. Buscar por el nombre de contacto\n                \"\"\")\n                println(\"Ingresa la opcion que quieres: \")\n                var optionSearch = scala.io.StdIn.readLine()\n                \n                while ((optionSearch != \"1\") && (optionSearch != \"2\")) {\n                    println(\"Ingresaste un valor erroneo, vuelvelo a intentar\")\n                    println(\"Ingresa la opcion que quieres: \")\n                    optionSearch = scala.io.StdIn.readLine()\n                }\n\n                if (optionSearch == \"1\") {\n                    println(\"Ingresa el numero de telefono a buscar: \")\n                    var numberContact = scala.io.StdIn.readLine()\n                        \n                    while (!(check_Input(numberContact))) {\n                        println(\"Ingresaste un valor erroneo, vuelvelo a intentar\")\n                        println(\"Ingresa el numero de telefono a buscar: \")\n                        numberContact = scala.io.StdIn.readLine()\n                    }\n                    find_Contact(numberContact, \"0\", optionSearch)\n                }\n                else if (optionSearch == \"2\") {\n                    println(\"Ingresa el nombre del contacto a buscar: \")\n                    var nameContact = scala.io.StdIn.readLine()\n                    find_Contact(\"0\", nameContact, optionSearch)\n                }\n                still = true\n            }\n            else if(option == \"2\") {\n                println(\"Ingresa el nombre del contacto que vas a agregar: \")\n                var nameContact = scala.io.StdIn.readLine()\n                println(\"Ingresa el numero de telefono: \")\n                var numberContact = scala.io.StdIn.readLine()\n\n                while (!(check_Input(numberContact))) {\n                    println(\"Ingresaste un valor erroneo, vuelvelo a intentar\")\n                    println(\"Ingresa el numero de telefono a buscar: \")\n                    numberContact = scala.io.StdIn.readLine()\n                }\n                add_Contact(numberContact, nameContact)\n                still = true\n            }\n            else if(option == \"3\") {\n                println(\"\"\"\n                Para realizar la actualizacion de algun contacto tienes dos opciones:\n                    1. Actualizar el numero de telefono\n                    2. Actualizar el nombre de contacto\n                \"\"\")\n                println(\"Ingresa la opcion que quieres: \")\n                var optionUpdate = scala.io.StdIn.readLine()\n                \n                while ((optionUpdate != \"1\") && (optionUpdate != \"2\")) {\n                    println(\"Ingresaste un valor erroneo, vuelvelo a intentar\")\n                    println(\"Ingresa la opcion que quieres: \")\n                    optionUpdate = scala.io.StdIn.readLine()\n                }\n                if (optionUpdate == \"1\") {\n                    println(\"Ingresa el numero de telefono que vas a actualizar: \")\n                    var numberContact = scala.io.StdIn.readLine()\n\n                    while (!(check_Input(numberContact))) {\n                        println(\"Ingresaste un valor erroneo, vuelvelo a intentar\")\n                        println(\"Ingresa el numero de telefono a buscar: \")\n                        numberContact = scala.io.StdIn.readLine()\n                    }  \n                    update_Contact(numberContact, \"0\", optionUpdate)\n                }\n                else if (optionUpdate == \"2\") {\n                    println(\"Ingresa el nombre del contacto a buscar: \")\n                    var nameContact = scala.io.StdIn.readLine()\n                    update_Contact(\"0\", nameContact, optionUpdate) \n                }   \n                still = true\n            }\n            else if(option == \"4\") {\n                println(\"\"\"\n                Para eliminar un contacto tienes dos opciones:\n                    1. Eliminar por el numero de telefono\n                    2. Eliminar por el nombre de contacto\n                \"\"\")\n                println(\"Ingresa la opcion que quieres: \")\n                var optionDel = scala.io.StdIn.readLine()\n\n                while ((optionDel != \"1\") && (optionDel != \"2\")) {\n                    println(\"Ingresaste un valor erroneo, vuelvelo a intentar\")\n                    println(\"Ingresa la opcion que quieres: \")\n                    var optionDel = scala.io.StdIn.readLine()\n                }\n                \n                if (optionDel == \"1\") {\n                    println(\"Ingresa el numero de telefono a buscar: \")\n                    var numberContact = scala.io.StdIn.readLine()\n\n                    while (!(check_Input(numberContact))) {\n                        print(\"Ingresaste un valor erroneo, vuelvelo a intentar\")\n                        println(\"Ingresa el numero de telefono a buscar: \")\n                        numberContact = scala.io.StdIn.readLine()\n                    }\n                    del_Contact(numberContact, \"0\", optionDel)\n                }\n                else if (optionDel == \"2\") {\n                    println(\"Ingresa el nombre del contacto a buscar: \")\n                    var nameContact = scala.io.StdIn.readLine()\n                    del_Contact(\"numberContact\", nameContact, optionDel)\n                }\n                still = true\n            }\n            else if(option == \"5\") {\n                still = false\n            }                \n            return still\n        }\n\n\n        def run(): Unit = {\n            var x = true\n            while(x) {\n                var userOption = welcome_Menu()\n                x = execute_Option(userOption)\n            }\n        }\n        \n        run()\n    }\n}"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/sql/Nicojsuarez2.sql",
    "content": "# #03 ESTRUCTURAS DE DATOS\n> #### Dificultad: Media | Publicación: 15/01/24 | Corrección: 22/01/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/sql/eulogioep.sql",
    "content": "-- Crear la tabla de contactos\nCREATE TABLE contactos (\n    id INTEGER PRIMARY KEY AUTOINCREMENT,\n    nombre VARCHAR(100) NOT NULL,\n    telefono VARCHAR(11) NOT NULL,\n    CONSTRAINT telefono_valido CHECK (telefono REGEXP '^[0-9]{1,11}$')\n);\n\n-- Insertar algunos contactos de ejemplo\nINSERT INTO contactos (nombre, telefono) VALUES ('Juan Pérez', '12345678901');\nINSERT INTO contactos (nombre, telefono) VALUES ('María García', '98765432100');\n\n-- Buscar un contacto\nSELECT nombre, telefono FROM contactos WHERE nombre = 'Juan Pérez';\n\n-- Añadir un nuevo contacto\nINSERT INTO contactos (nombre, telefono) VALUES ('Ana López', '55566677788');\n\n-- Actualizar un contacto\nUPDATE contactos SET telefono = '11122233344' WHERE nombre = 'María García';\n\n-- Eliminar un contacto\nDELETE FROM contactos WHERE nombre = 'Ana López';\n\n-- Mostrar todos los contactos\nSELECT nombre, telefono FROM contactos ORDER BY nombre;\n\n-- Procedimiento almacenado para añadir un contacto (si el RDBMS lo soporta)\nDELIMITER //\nCREATE PROCEDURE añadir_contacto(IN p_nombre VARCHAR(100), IN p_telefono VARCHAR(11))\nBEGIN\n    IF p_telefono REGEXP '^[0-9]{1,11}$' THEN\n        INSERT INTO contactos (nombre, telefono) VALUES (p_nombre, p_telefono);\n        SELECT 'Contacto añadido con éxito' AS mensaje;\n    ELSE\n        SELECT 'Número de teléfono no válido' AS mensaje;\n    END IF;\nEND //\nDELIMITER ;\n\n-- Llamada al procedimiento almacenado\nCALL añadir_contacto('Carlos Rodríguez', '12345678901');\n\n-- Vista para mostrar todos los contactos\nCREATE VIEW vista_contactos AS\nSELECT nombre, telefono FROM contactos ORDER BY nombre;\n\n-- Usar la vista\nSELECT * FROM vista_contactos;"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/swift/18miguelgalarza.swift",
    "content": "//: [Previous](@previous)\n\n/*\n * 18miguelgalarza.swift Release #03 - swift\n * EJERCICIO: #03 ESTRUCTURAS DE DATOS\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\n\nimport Foundation\nimport SwiftUI\nimport PlaygroundSupport\n\n\nvar greeting = \"Hello, playground\"\n\n//Estructuras soportadas por swift\n\nstruct structPersona {\n/*\n Struct: cuando haces set en una variable o constante se asigna el valor original y no una referencia\n struct: Las estructuras no admiten la herencia en Swift. No puedes heredar propiedades o métodos de otra estructura ni de una clase.\n */\n    var nombre: String\n    var apellido: String\n    var edad: Int\n    var sexo:Character\n}\n\nclass automovil {\n/* Las clases pueden compartirse en todo el código\n */\n    var color = \"neutro\"\n    var precio = 0\n    var numeroLlantas = 4\n\n    init(color: String, precio: Int) {\n        self.color = color\n        self.precio = precio\n    }\n    \n    init (){}\n    \n    func encender() -> Bool{return true}\n    func apagar() -> Bool{return true}\n    func acelerar() -> Bool{return true}\n}\n\nvar objetoKia = automovil()\n\nobjetoKia.encender()\n\nenum DiaDeLaSemana {\n    case lunes\n    case martes\n    case miercoles\n    case jueves\n    case viernes\n    case sabado\n    case domingo\n}\n\nprotocol ConductaCanina {\n    func ladrar()\n    func correr()\n}\n\n\nextension String {\n    func hacerMayusculas() -> String {\n        return self.uppercased()\n    }\n}\n\n\nfunc intercambiar<T>(_ a: inout T, _ b: inout T) {\n    let temp = a\n    a = b\n    b = temp\n}\n\n//Tuplas\nlet coordenadas = (3.0, 4.0)\n\n//Closures\nlet miCierre = { (nombre: String) -> String in\n    return \"Hola, \\(nombre)!\"\n}\n\nlet saludo = miCierre(\"Mundo\") // saludo = \"Hola, Mundo!\"\n\n//Optionals\nvar nombre: String? = \"Juan\"\n\n\n//guards Statements: Usado para salir temprano de una función si ciertas condiciones no se cumplen\nlet patinetas = [\"skateboard\", \"longboards\",\"penny\"]\n\nenum MiError: Error {\n    case ErrorConocido\n}\n\nguard let patin = patinetas.last else {\n    print(\"No existe patineta\")\n    throw MiError.ErrorConocido\n}\n\n//print(\"\\u{2713} Ejemplo de guard para buscar : \\(patin)\")\n\n\n/*\n* DIFICULTAD EXTRA (opcional):\n* Crea una agenda de contactos por terminal.\n* - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n* - Cada contacto debe tener un nombre y un número de teléfono.\n* - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n*   los datos necesarios para llevarla a cabo.\n* - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n*   (o el número de dígitos que quieras)\n* - También se debe proponer una operación de finalización del programa.\n*/\n\nclass Contacto {\n    \n    var nombre:String = \"\"\n    var numeroContacto:String = \"\"  //trabeje con 6 para ejecutar pruebas más rápidas\n    \n    init(_ nombre: String, _ numeroContacto: String) {\n        self.nombre = nombre\n        self.numeroContacto = numeroContacto\n    }\n    \n    init() {\n    }\n\n}\n\nvar listaDeContacto: [Contacto] = []  //variable global que hará la función de una Base de datos\n\n\nfunc agenda(_ operacion:Character, _ contacto:Contacto ){\n    \n    // Crear un array de objetos Persona\n    //CRUD\n    switch operacion {\n    case \"C\": //opción create\n        listaDeContacto.append(contacto)\n        print(\"\\nSUCCESS:create, tu lista de contactos ahora tiene  \\(listaDeContacto.count) contactos\")\n        \n    case \"R\":  //opción read\n       \n        // Buscar en el arreglo de personas por el nombre\n        let contactoConNumeroBuscado = listaDeContacto.filter { $0.numeroContacto == contacto.numeroContacto }\n\n        if contactoConNumeroBuscado.isEmpty {\n            print(\"\\nERROR(CRUD): No se encontró ningún contacto con el número '\\(contacto.numeroContacto )'.\")\n        } else {\n            for contacto in contactoConNumeroBuscado {\n                print(\"\\nSUCCESS:read Se encontró a \\(contacto.nombre) con número de contacto \\(contacto.numeroContacto) \")\n            }\n        }\n        \n    case \"U\": //opción update\n      \n        // Buscar el primer contacto que tenga el numero que deseas actualizar\n        if let contactoAActualizar = listaDeContacto.first(where: { $0.numeroContacto == contacto.numeroContacto  }) {\n           \n            // Modificar las propiedades del objeto encontrado, para el ejemplo será un dato en duro\n            contactoAActualizar.numeroContacto = \"080081\"\n            \n            // Mostrar el objeto actualizado\n            print(\"\\nSUCCESS:update - Contacto actualizado: \\(contactoAActualizar.nombre) tiene ahora un número de contacto \\(contactoAActualizar.numeroContacto)\")\n        } else {\n            print(\"\\nERROR(CRUD): No se encontró ningún contacto con el nombre '\\(contacto.numeroContacto)'.\")\n        }\n               \n    case \"D\": //opción delete\n     \n        //buscamos la posicion del contacto que vamos a eliminar\n        if let index = listaDeContacto.firstIndex(where: { $0.numeroContacto == contacto.numeroContacto  }) {\n           \n            // Modificar las propiedades del objeto encontrado, para el ejemplo será un dato en duro\n            listaDeContacto.remove(at: index)\n            \n            // Mostrar el objeto actualizado\n            print(\"\\nSUCCESS: delete - Contacto : \\(contacto.nombre) - \\(contacto.numeroContacto) eliminado\")\n        } else {\n            print(\"\\nERROR(CRUD): No se encontró ningún contacto con el número '\\(contacto.numeroContacto)'.\")\n        }\n  \n        \n    default: print(\"\\nERROR(CRUD): no existe esta operación ****\")\n    }\n    \n    \n    imprimirListaContacto()\n    \n}\nfunc validaSoloNumeros(_ cadena: String) -> Bool {\n//Función para validar que la cadena solo contenga números\n    return !cadena.isEmpty && cadena.rangeOfCharacter(from: CharacterSet.decimalDigits.inverted) == nil\n}\n\nfunc imprimirListaContacto(){\n    \n    print(\"**** Cantidad de contactos actualizados: \\(listaDeContacto.count) ****\")\n    for contacto in listaDeContacto {\n        print(\"Nombre: \\(contacto.nombre) - Número: \\(contacto.numeroContacto) \")\n    }\n    \n}\n\n\nstruct ContentView: View {\n    @State private var nombre: String = \"\"\n    @State private var numerocontacto: String = \"\"\n    @State private var operacion: String = \"\"\n    private var contacto = Contacto()\n    \n    var body: some View {\n                \n        VStack {\n            Text(\"Agenda de Contactos\")\n                .font(.title)\n                .fontWeight(.bold)\n                .foregroundColor(.blue)\n                .padding()\n            \n            TextField(\"Nombre\", text: $nombre)\n                .padding()\n            \n            TextField(\"Número de Contacto\", text: $numerocontacto)\n                .padding()\n            \n            TextField(\"operacion(C,R,U,D)\", text: $operacion)\n                .padding()\n            \n            Button(\"Aceptar\") {\n    \n                \n                if validaSoloNumeros(numerocontacto) && numerocontacto.count <= 6  && !operacion.isEmpty && !nombre.isEmpty && numerocontacto.count >= 0 {\n \n                    //Se permite al parámetro \"operacion\" que acepte cualquier OTRO caracter con el fin de generar crash en el programa.\n                    \n                    agenda(Character(operacion),Contacto(nombre,numerocontacto))\n        \n                    \n                }else{\n                    \n                    //validacionnes en consola\n                    print(\"************* validaciones ***************\")\n                    print(nombre.isEmpty ? \"Agregar nombre\":\"\")\n                    print(numerocontacto.count == 0 ? \"Agregar número de contacto\":\"\")\n                    print(!validaSoloNumeros(numerocontacto) ? \"Usar únicamente números en el contacto\":\"\")\n                    print(numerocontacto.count > 6  ? \"El número de contacto sólo puede tener máximo 6 dígitos\":\"\")\n                    print(operacion.isEmpty  ? \"Operador no puede ser nulo\":\"\")\n      \n                    \n                    \n                }\n                \n            }// button Aceptar\n            .padding()\n\n                      \n             Button(\"Cerrar\") {\n                          \n                PlaygroundPage.current.finishExecution()\n                          \n            }\n            .padding()\n\n                      \n        }\n        .padding()\n    }\n}\n\nPlaygroundPage.current.setLiveView(ContentView())\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/swift/PineroDev.swift",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\nimport Foundation\n\n// Arrays - El orden de los elementos es importante\n// pero no es importante que se repitan\n\n//Ejemplos de creación\nvar arraryString = [\"Pepe\", \"Juan\", \"Luis\"]\nvar arraOfString = Array(arrayLiteral: \"Pepe\", \"Juan\", \"Luis\")\n\n//Contador\nvar arrayString2 = [\"Pepe\", \"Juan\", \"Luis\"]\nprint(\"The arrayString2 contain \\(arrayString2.count) elements\")\nprint(arrayString2 [0])\n\n//Agregador e inserción\narrayString2.append(\"Maria\")\narrayString2 += [\"Ana\", \"Susana\"]\nprint(arrayString2)\narrayString2.insert(\"Juanito\", at: 0)\nprint(arrayString2)\n\n//Ordenanción\narrayString2.sort()\nprint(arrayString2)\n\n//Actualizacion\narrayString2[6] = \"Mercedes\"\nprint(arrayString2)\n\n//Borrado\narrayString2.remove(at: 0)\narrayString2.removeFirst()\nprint(arrayString2)\n\narrayString2.removeAll()\nif arrayString2.isEmpty{\n    print(\"El arrayString2 esta vacio\")\n}else{\n    print(\"El arrayString2  contiene elementos\")\n}\n\n\n// Set - El orden de los elementos no es importante\n// pero si que no se repitan\n\n// Ejemplo de creación\nvar setString = Set([\"Pepe\", \"Juan\", \"Luis\"])\nvar setOfString = Set(arrayLiteral: \"Pepe\", \"Juan\", \"Luis\")\n\nprint(\"The setString contain \\(setString.count) elements\")\nprint(setString)\n\n// Inserción\nsetString.insert(\"Maria\")\nprint(setString)\n\n// Comprobación\nprint(setString.contains(\"Pepe\"))\n\n// Borrado\nsetString.remove(\"Juan\")\nprint(setString)\nif setString.isEmpty{\n    print(\"El setString esta vacio\")\n}else{\n    print(\"El setString contiene elementos\")\n}\n\n\n// Diccionarios - Cada valor tiene asociado una clave\n// tampoco estan ordenados\n\n// Ejemplos de creación\nvar dictionary: [String: String] = [:]\n\nvar dictionaryWithValues: [String: String] = [\"Nombre\": \"Pedro\",\n                                              \"Apellido\": \"Garcia\",\n                                              \"Ciudad\": \"Murcia\"]\nprint(dictionaryWithValues)\nprint(\"The dictionaryWithValues contain \\(dictionaryWithValues.count) elements\")\n\n// Agregación\ndictionaryWithValues[\"Edad\"] = \"25\"\nprint(dictionaryWithValues)\n\n// Comprobación\nprint(dictionaryWithValues.keys.contains(\"Nombre\"))\n\n// Actualizacion\ndictionaryWithValues.updateValue( \"30\", forKey: \"Edad\")\nprint(dictionaryWithValues)\n\n// Borrado\ndictionaryWithValues.removeValue(forKey: \"Ciudad\")\ndictionaryWithValues[\"Edad\"] = nil\nprint(dictionaryWithValues)\ndictionaryWithValues.removeAll()\nif dictionaryWithValues.isEmpty{\n    print(\"El dictionaryWithValues esta vacio\")\n}else{\n    print(\"El dictionaryWithValues contiene elementos\")\n}\n\n//----------------------------------------------\n//----------------------------------------------\n//----------------------------------------------\n// Ejercicio DIFICULTAD EXTRA\n\nfunc agenda(){\n    print(\"---------------------------\")\n    print(\"|  Bienvenido a la agenda |\")\n    print(\"|                         |\")\n    print(\"|      By PineroDev       |\")\n    print(\"---------------------------\")\n    print(\"Elige una opción:\")\n    print(\"1 - Buscar\")\n    print(\"2 - Crear\")\n    print(\"3 - Actualizar\")\n    print(\"4 - Borrar\")\n    print(\"5 - Mostrar listado\")\n    print(\"6 - Salir\")\n    let opcion = readLine()\n        \n        switch opcion {\n        case \"1\":\n            buscarContacto()\n        case \"2\":\n            agregarContacto()\n        case \"3\":\n            actualizarContacto()\n        case \"4\":\n            borrarContacto()\n        case \"5\":\n            mostrarListado()\n        case \"6\":\n            print(\"Gracias por usar la agenda\")\n            sleep(5)\n            break\n        default:\n            print(\"Opcion incorrecta\")\n            sleep(5)\n            agenda()\n        }\n    }\n\nvar diccionarioAgenda: [String: Int] = [:]\n\nfunc buscarContacto() {\n    var nombre: String = \"\"\n    print(\"Introduzca el nombre del contacto a buscar:\")\n    if let nombreIngresado = readLine(){\n        nombre = nombreIngresado\n    }\n    if diccionarioAgenda.isEmpty{\n        print(\"Agregue un contacto primero\")\n    }else if let datos = diccionarioAgenda[nombre]{\n        print(\"Nombre: \\(nombre) - Telefono:\\(datos)\" )\n    }else {\n        print(\"El contacto \\(nombre) no se encuentra en la agenda\")\n    }\n    sleep(5)\n    agenda()\n}\n\nfunc agregarContacto() {\n    var nombre: String = \"\"\n    var numero: Int = 0\n    \n    print(\"Agregar Contacto\")\n    print(\"Ingrese nombre:\")\n    \n    if let nombreIngresado = readLine(){\n        nombre = nombreIngresado\n    }\n    \n    print(\"Ingrese telefono:\")\n    if let numeroIngresado = readLine(){\n        if let numeroIngresado = Int(numeroIngresado){\n            if numeroIngresado < 99999999999 && numeroIngresado > 1 {\n                numero = numeroIngresado\n            }else {\n                print(\"El numero de telefono debe ser de menos de 12 digitos\")\n                agenda()\n            }\n        }else {\n            print( \"Debe ingresar un numero valido\")\n            agenda()\n            }\n    }\n    diccionarioAgenda[nombre] = numero\n    print(\"Contacto agragado exitosamente\")\n    sleep(3)\n    agenda( )\n}\n\nfunc actualizarContacto() {\n    var nombre: String = \"\"\n    var nombreActual: String = \"\"\n    var numero: Int = 0\n    \n    print(\"Introduzca el nombre del contacto a actualizar:\")\n    if let nombreIngresado = readLine(){\n        nombreActual = nombreIngresado\n    }\n    if diccionarioAgenda.keys.contains(nombreActual){\n        print( \"Ingrese el nuevo nombre:\")\n        if let nombreActualizado = readLine(){\n            nombre = nombreActualizado\n            print(\"Ingrese telefono:\")\n            if let numeroIngresado = readLine(){\n                if let numeroIngresado = Int(numeroIngresado){\n                    if numeroIngresado < 99999999999 && numeroIngresado > 1 {\n                        numero = numeroIngresado\n                    }else {\n                        print(\"El numero de telefono debe ser de menos de 12 digitos\")\n                    }\n                }else {\n                    print( \"Debe ingresar un numero valido\")\n                }\n            }\n        }\n    }else{\n        print(\"El contacto \\(nombreActual) no existe\")\n    }\n    diccionarioAgenda[nombreActual] = nil\n    diccionarioAgenda[nombre] = numero\n    //diccionarioAgenda.updateValue( numero, forKey: nombreActual )\n    print(\"Contacto actualizado con exito\")\n    sleep(5)\n    agenda()\n}\n\nfunc borrarContacto() {\n    var nombre: String = \"\"\n    print(\"Introduzca el nombre del contacto a borrar:\")\n    if let nombreIngresado = readLine(){\n            nombre = nombreIngresado\n    }\n    if diccionarioAgenda.keys.contains(nombre) {\n        diccionarioAgenda[nombre] = nil\n        print( \"El Contacto \\(nombre) ha sido borrado con exito\")\n    }else {\n        print(\"El contacto \\(nombre) no existe\")\n    }\n    sleep(5)\n    agenda()\n}\n    \nfunc mostrarListado() {\n    print(diccionarioAgenda)\n    sleep(10)\n    agenda()\n    }\n\n\nagenda( )\n        \n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/swift/allbertoMD.swift",
    "content": "import Foundation\n\n// Array\nprint(\"\\nArray\")\nvar myArray: [Int] = [20, -2, 39, 88, 1024, -210, 72]\nprint(myArray)\n\n\n// Metodos de inserción\nprint(\"\\nMetodos de Inserción\")\n\n// Inserta un 50 al final del array\nmyArray.append(50)\nprint(myArray)\n\n// Concatena un el array [800, 129. 0] al final del array\nmyArray.append(contentsOf: [800, -129, 0])\nprint(myArray)\n\n// Inserta 420 en la posición 0 del array\nmyArray.insert(420, at: 0)\nprint(myArray)\n\n// Concatena el array [12, -874, 48] en la posición 3 del array\nmyArray.insert(contentsOf: [12, -874, 48], at: 3)\nprint(myArray)\n\n// Concatena el array [222, 57] al final del array\nmyArray += [222, 57]\nprint(myArray)\n\n\n// Metodos de borrado\nprint(\"\\nMetodos de Borrado\")\n\n// Borra el elemento 1 del array\nmyArray.remove(at: 1)\nprint(myArray)\n\n// Borra el ultimo elemento del array\nmyArray.removeLast()\nprint(myArray)\n\n// Borra el primer elemento del array\nmyArray.removeFirst()\nprint(myArray)\n\n// Borra los elementos del 2 al 4 del array\nmyArray.removeSubrange(2...4)\nprint(myArray)\n\n// Borra todos los elementos que complan con la condicion. La condicion es los multiplos de 3\nmyArray.removeAll { $0 % 3 == 0}\nprint(myArray)\n\n// Borra todos los elementos del array\nmyArray.removeAll()\nprint(myArray)\n\n\n// Metodos de actualización\nprint(\"\\nMetodos de Actualización\")\n\n// Actualiza el array con los nuevos valores\nmyArray = [420, 20, -2, 12, -874, 48, 39, 88, 1024, -210, 72, 50, 800, -129, 0, 222, 57]\nprint(myArray)\n\n// Actualiza el la posición 1 del array con 770\nmyArray[1] = 770\nprint(myArray)\n\n// Actualiza el -2 y el 12 por el 903, 11, 4 \nmyArray.replace([-2, 12], with: [903, 111, 4])\nprint(myArray)\n\n// Actualiza del elemento 4 al 7 del arrau por 96, 414, 33, 1739\nmyArray.replaceSubrange(4...7, with: [96, 414, 33, 1739])\nprint(myArray)\n\n\n// Metodos de ordenación\nprint(\"\\nMetodos de Ordenación\")\n\n// Ordena los elementos de menor a mayor y lo asigna a una variable\nvar sortedArray = myArray.sorted()\nprint(sortedArray)\n\n// Ordena los elementos de mayor a menor, da la vuelta al array anteriormente ordenado\nsortedArray.reverse()\nprint(sortedArray)\n\n// Ordena los elementos de menor a mayor y lo asigna a la variable\nsortedArray = myArray.sorted { $0 < $1 }\nprint(sortedArray)\n\n// Ordena los elementos de menor a mayor y lo asigna a la variable\nsortedArray = myArray.sorted { $0 > $1 }\nprint(sortedArray)\n\n// Ordena los elementos de menor a mayor\nmyArray.sort { $0 < $1 }\nprint(myArray)\n\n// Ordena los elementos de mayor a menor\nmyArray.sort { $0 > $1 }\nprint(myArray)\n\n\n\n\n// Diccionario\nprint(\"\\nDiccionario\")\nvar myDictionary: [Int:String] = [\n    9 : \"nueve\",\n    2 : \"dos\",\n    34 : \"treinta y cuatro\",\n    0 : \"cero\"\n]\nprint(myDictionary)\n\n\n// Metodos de inserción\nprint(\"\\nMetodos de inserción\")\n\n// Inserta la clave 7 con el valor \"siete\" al diccionario\nmyDictionary[7] = \"siete\"\nprint(myDictionary)\n\n// Inserta el valor \"ciento uno\" con la clave 101\nmyDictionary.updateValue(\"ciento uno\", forKey: 101)\nprint(myDictionary)\n\n// Inserta los valores del nuevo dicionario a myDictionary\nvar newDictionary = [38 : \"treinta y ocho\"]\nmyDictionary.merge(newDictionary) { (_, newValue) in newValue }\nprint(myDictionary)\n\n\n// Metodos de borrado\nprint(\"\\nMetodos de Borrado\")\n\n// Borra el elemento con la clave 34\nmyDictionary.removeValue(forKey: 34)\nprint(myDictionary)\n\n// elimina el elemento con la clave 101\nif let index = myDictionary.index(forKey: 101) {\n    myDictionary.remove(at: index)\n}\nprint(myDictionary)\n\n// Borra todos los elementos de Diccionario\nmyDictionary.removeAll()\nprint(myDictionary)\n\n\n// Metodos de actualización\nprint(\"\\nMetodos de Actualización\")\n\n// Actualiza el diccionario con los nuevos valores\nmyDictionary = [\n    34: \"treinta y cuatro\", \n    0: \"cero\",\n    2: \"dos\",\n    38: \"treinta y ocho\",\n    7: \"siete\",\n    101: \"ciento uno\",\n    9: \"nueve\"\n]\nprint(myDictionary)\n\n// Actualiza el elemento con la clave 2 a \"d o s\"\nmyDictionary[2] = \"d o s\"\nprint(myDictionary)\n\n// Actualiza el elemento con la clave 0 a \"ce ro\"\nmyDictionary.updateValue(\"ce ro\", forKey: 0)\nprint(myDictionary)\n\n// Actualiza el elementos con la clave 38 a \"treintayocho\"\nnewDictionary[38] = \"treintayocho\"\nmyDictionary.merge(newDictionary) { (_, newValue) in newValue }\nprint(myDictionary)\n\n\n// Metoos de ordenación\nprint(\"\\nMetodos de Ordenación\")\n\n// Ordenar los elementos por clave de menor a mayor\nlet dictionaryByGreaterKey = myDictionary.sorted { $0.key < $1.key }\nprint(dictionaryByGreaterKey)\n\n// Ordenar los elementos por clave de mayor a menor \nlet dictionaryByLessKey = myDictionary.sorted { $0.key > $1.key }\nprint(dictionaryByLessKey)\n\n// Ordenar los elementos por valor de menor a mayor\nlet dictionaryByGreaterValue = myDictionary.sorted { $0.value < $1.value }\nprint(dictionaryByGreaterValue)\n\n// Ordenar los elementos por valor de mayor a menor\nlet dictionaryBuLessValue = myDictionary.sorted { $0.value > $1.value }\nprint(dictionaryBuLessValue)\n\n\n\n\n// Set\nprint(\"\\nSet\")\nvar mySet: Set<Int> = [11, 84, 8, -12, -2, 883, -100]\nprint(mySet)\n\n\n// Metodos de inserción\nprint(\"\\nMetodos de inserción\")\n\n// Inserta el 7 en cualquier posición del set\nmySet.insert(7)\nprint(mySet)\n\n// Inserta el 500 en cualquier posición del set\nmySet.update(with: 500)\nprint(mySet)\n\n\n// Metodos de borrado\nprint(\"\\nMetodos de borrado\")\n\n// Borrar el elemento seleccionado del set\nmySet.remove(500)\nprint(mySet)\n\n// Borrar el primer elemento del set\nmySet.removeFirst()\nprint(mySet)\n\n// Borrar todos los elementos del set\nmySet.removeAll()\nprint(mySet)\n\n\n// Metodos de aztualización\nprint(\"\\nMetodos de Actualización\")\n\n// Actualiza el set con los nuevos elementos\nmySet = [11, 7, 84, 8, -100, -12, 883]\nprint(mySet)\n\n// Actualiza los elementos del set con los elementos de los dos sets sin los elementos repetidos\nlet newSet: Set<Int> = [1, 2, 3, 11, -100]\nmySet.formUnion(newSet)\nprint(mySet)\n\n// Actualiza el set con los elementos repetidos en ambos sets\nmySet.formIntersection(newSet)\nprint(mySet)\n\n// Actualiza el set con todos los elementos menos los que esten repetidos en ambos sets\nmySet = [11, 7, 84, 8, -100, -12, 883]\nmySet.subtract(newSet)\nprint(mySet)\n\n\n// Metodos de Ordenación\nprint(\"\\nMetodos de Ordenación\")\n\nlet sortedSet = mySet.sorted()\nprint(sortedSet)\n\n\n\n\n// Tupla\nprint(\"\\nTupla\")\nvar myTuple = (12, 4, 74, 9)\nprint(myTuple)\n\n// LAS TUPLAS SON INMUTABLES!!!\n\n\n\n\n// Dificultad extro\n\nvar contacts: [String : String] = [\n    \"Sam\" : \"+1 696120338\",\n    \"Jhonn\" : \"+1 555989001\",\n    \"Jessica\" : \"+34 768341099\",\n    \"Marta\" : \"+34 647290001\"\n]\n\nshowMenu()\n\nvar validInput: Bool = true\n\nprint(\"Introduce Una Opción\")\n\nwhile validInput {\n    if let input = readLine() {\n        switch input {\n            case \"1\":\n                addContact()\n            case \"2\":\n                removeContact()\n            case \"3\":\n                updateContact()\n            case \"4\":\n                searchContact()\n            case \"exit\":\n                validInput = false\n                print(\"Salir\")\n            default:\n                print(\"Opción no valida\")\n        }\n    }\n}\n\nfunc showMenu() {\n    print(\"[1]-Añadir Contacto\")\n    print(\"[2]-Borrar Contacto\")\n    print(\"[3]-Actualizar Contacto\")\n    print(\"[4]-Buscar Contacto\")\n    print(\"[exit]-Salir Del Menu\")\n}\n\nfunc addContact() {\n    var name = \"\"\n    var phone = \"\"\n    var validNumber: Bool = false\n\n    print(\"Nuevo Contacto\")\n    print(\"Introduce un Nombre\")\n\n    if let input = readLine() {\n        name = input\n    }\n    print(\"Nombre Introducido\")\n    print(\"Introduce un Numero de Telefono, Ejemplo: +12 292298799\")\n\n    while phone.count > 14 || phone.count < 12 || validNumber == false {\n        if let input = readLine() {\n            phone = input\n            validNumber = evaluateString(phone)\n        }\n        if phone.count > 14 || phone.count < 12 || validNumber == false {\n            print(\"Numero no valido\")\n            print(\"Introduce un Numero de Telefono, Ejemplo: +12 292298799\")\n        } else {\n            print(\"Numero Introducido\")\n        }\n    }\n    contacts.updateValue(phone, forKey: name)\n\n    sleep(2)\n\n    showMenu()\n}\n\nfunc removeContact() {\n    print(\"Borrar Contacto\")\n    print(\"Introduce un Numbre\")\n\n    while true {\n        if let input = readLine() {\n            if let index = contacts.index(forKey: input) {\n                contacts.remove(at: index)\n                \n                print(\"Contacto Eliminado\")\n                \n                break\n\n            } else {\n                print(\"Nombre no Encontrado\")\n                print(\"Introdule un Nombre\")\n            }\n        }\n    }\n    sleep(2)\n\n    showMenu()\n}\n\nfunc updateContact() {\n    var name = \"\"\n    var phone = \"\"\n    var validNumber: Bool = false\n\n    print(\"Actualizar Contacto\")\n    print(\"Introduce un Nombre\")\n\n    while true {\n        if let input = readLine() {\n            name = input\n        }\n        if let _: Dictionary<String, String>.Index = contacts.index(forKey: name) {\n            print(\"Introduce unn numero de telefono, Ejemplo: +12 292298799 \")\n\n            while phone.count > 14 || phone.count < 12 || validNumber == false {\n                if let input: String = readLine() {\n                    phone = input\n                    validNumber = evaluateString(phone)\n                }\n                if phone.count > 14 || phone.count < 12 || validNumber == false {\n                    print(\"Numero no Valido\")\n                    print(\"Introduce un Numero de Telefono, Ejemplo: +12 292298799\")\n                }\n            }\n            print(\"Contacto Actualizado\")\n\n            break\n\n        } else {\n            print(\"Nombre no Encontrado\")\n            print(\"Introduce el Nombre\")\n        }\n    }\n    contacts[name] = phone\n\n    sleep(2)\n\n    showMenu()\n}\n\nfunc searchContact() {\n    print(\"Buscar Contacto\")\n    print(\"Introduce un Nombre\")\n\n    while true {\n        if let input = readLine() {\n            if let value = contacts[input] {\n                print(\"El Contacto \\(input) Tiene el Numero de Telefono: \\(value)\")\n                \n                break\n\n            } else {\n                print(\"Nombre no Encontrado\")\n                print(\"Introduce un Nombre\")\n            }\n        }\n    }\n    sleep(2)\n\n    showMenu()\n}\nprint(contacts)\n\nfunc evaluateString(_ string: String) -> Bool {\n    let validCharacters: String = \" +1234567890\"\n    \n    for character in string {\n        if !validCharacters.contains(character) {\n            return false        }\n    }\n    return true\n}\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/swift/blackriper.swift",
    "content": "import Foundation\n\n/*arrays*/\n\nvar arrayNum = [1, 2, 3, 4, 5, 6, 7] // Mutable\n\n\n// Agregar valores\narrayNum.append(8) // Agrega el valor dentro del array\narrayNum.insert(0, at: 2) // Añade el valor 0 en la posición 2.\nprint(\"arrayNumAdd = \\(arrayNum)\")\n\n\n// Eliminar valores\narrayNum.removeLast() // Elimina el último valor del array\narrayNum.remove(at:3) // Elimina el valor ubicado en la posición 3\narrayNum.removeFirst() // Elimina el primer valor del array\narrayNum.removeSubrange(4...5) // Elimina los valores del 3 al 5\nprint(\"arrayNumDelete = \\(arrayNum)\")\n\n\n// actualizar valores\narrayNum = [100, 110, 120, 130, 140, 150, 160, 170, 180, 190]\narrayNum[4] = 125 // Actualiza el valor de la 4ta ubicación (130->125)\nprint(\"arrayNumUpdate = \\(arrayNum)\")\n\n// Actualización de un valor concreto\narrayNum.replace([100, 110], with: [25, 50])\nprint(\"arrayNumReplace = \\(arrayNum)\")\n\n/* sets de datos*/\nvar mySet = Set<Int>(arrayNum)\nprint(\"mySet = \\(mySet)\")\n\n// agregar elementos\nmySet.insert(11)\nprint(\"mySetAdd = \\(mySet)\")\n\n// borrar elementos\nmySet.remove(11)\nprint(\"mySetDelete = \\(mySet)\")\n\n// actualizar \nmySet = [100, 110, 120, 130, 140, 150, 160, 170, 180, 190]\nprint(\"mySetUpdate = \\(mySet)\")\n\n// ordenar\nprint(\"mySetSorted = \\(mySet.sorted())\")\n\n/* diccionarios*/\nvar myDictionary = [Int:String]()\n// agregar datos \nmyDictionary = [001:\"Turing\", 002: \"Schrödinger\"]\nmyDictionary[003] = \"Planck\"\nmyDictionary[004] = \"Bohr\"\nmyDictionary[005] = \"Oppenheimer\"\nmyDictionary[006] = \"Einstein\"\nprint(\"myDictionary = \\(myDictionary)\")\n\n// actualizar datos \nmyDictionary.updateValue(\"Erwin Schrödinger\", forKey: 002)\nprint(\"myDictionaryUpdate = \\(myDictionary)\")\n\n// borrar datos\nmyDictionary.removeValue(forKey: 002)\nprint(\"myDictionaryDelete = \\(myDictionary)\")\n\n\n\n\n// ejercicio extra \n\n// funcion para validar siel numero es  valido\n\nfunc isValidNumber(_ number: String) -> Bool {\n    var valid = false\n    for char in number {\n        if char.isNumber {\n            valid=true\n        }\n    }\n   return valid \n}\n\n\n// funcion para agregar contacto\nfunc addContact()->[String:String]{\n   var contact:[String: String] = [:]\n   var correct:Bool=false\n\n  while correct==false{\n        print(\"Input the contact name:\")\n        let name=readLine() ?? \"\"\n        print(\"Input the phone number of the contact\")\n        let number=readLine() ?? \"\"\n        \n        if isValidNumber(number) && number.count == 10{\n            contact.updateValue(number, forKey: name)\n            print(\"New contact accepted\")\n            correct=true\n        }else{\n            print(\"Invalid phone number\")\n        }\n    }\n  return contact\n}\n\nfunc showAllContacts(_ contacts:[[String:String]]){\n    print(\"Lists of contacts\")\n    for contact in contacts{\n         for (key,value) in contact{\n            print(\"Name: \\(key) Number: \\(value)\")\n     \n        }       \n    }\n\n}\n\n\n\nfunc bookOfContacts(){\n    var option:String=\"0\"\n    var contacts :[[String:String]] = []\n    \n    while option != \"4\"{\n        print(\"Select an option:\")\n        print(\"1.-Show all contacts\")\n        print(\"2.-Insert new contact\")\n        print(\"3.-Delete contact\")\n        print(\"4.-Exit\")\n        \n        option = readLine() ?? \"\"\n        \n       switch option {\n        case \"1\":\n            showAllContacts(contacts)\n           \n        case \"2\":\n           let contact=addContact()\n           contacts.append(contact)\n\n        case \"3\":\n            print(\"Input the  name contact you want to delete:\")\n            let name=readLine() ?? \"\"\n            contacts.removeAll(where: {$0.keys.contains(name)})\n            print(\"The \\(name)'s contact has been deleted\")\n        \n        case \"4\":\n            print(\"Exit contact list\")\n            \n\n        default:\n           print(\"Option invalid\")\n           \n        }\n    }\n}\n\nbookOfContacts()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/swift/didacdev.swift",
    "content": "import Foundation\n\n//---------------- Array --------------------\n/*\n- Valores del mismo tipo ordenados.\n- Puede incluir valores respetidos.\n*/\nlet immutableArray: Array<String> // Immutable\nvar mutableArray: Array<String> = []\nvar arrayDos = Array(repeating: 0, count: 3)\nvar arrayTres = [0, 1, 2, 3]\nvar arrayCuatro = arrayTres + arrayDos\n\n// Añadir\nmutableArray.append(\"Hola\")\nprint(mutableArray)\narrayTres += [4, 5, 6]\nprint(arrayTres)\n\n// Obtener\nprint(arrayTres[0])\n\n// Cambiar\nmutableArray[0] = \"adios\"\nprint(mutableArray)\narrayTres[2...4] = [0, 0]\nprint(arrayTres)\n\n// Insertar \narrayTres.insert(4, at: 4)\nprint(arrayTres)\n\n// Eliminar\narrayTres.remove(at: 2)\nprint(arrayTres)\narrayTres.removeLast()\nprint(arrayTres)\narrayTres.removeFirst()\nprint(arrayTres)\narrayTres.removeAll()\nprint(arrayTres)\n\n\n//------------------- Set ------------\n/*\n- Distintos valores de un mismo tipo sin ordenar\n*/\nvar emptySet = Set<String>()\nvar setDos: Set<Int> = [2, 1, 5, 4, 3]\n\n// Añadir\nemptySet.insert(\"Pepe\")\nprint(emptySet)\n\n// Eliminar\nif let nombre = emptySet.remove(\"Pepe\") {\n    print(nombre)\n} else {\n    print(\"No existe\")\n}\n\n// Ordenar\nlet ordenado = setDos.sorted()\nprint(ordenado)\n\n//---------------- Dictionary -------------\n/*\n- Asociaciones clave-valor del mismo tipo\n- Claves únicas\n- No ordenados\n*/\n\nvar emptyDict: [Int: String] = [:]\nvar dictDos = [2: \"Pepe\", 1: \"Juan\"]\n\n// Actualizar\ndictDos[1] = \"Pedro\"\nprint(dictDos)\ndictDos.updateValue(\"Pablo\", forKey: 2)\nprint(dictDos)\n\n// Añadir\ndictDos[0] = \"Ana\"\nprint(dictDos)\n\n// Eliminar\ndictDos.removeValue(forKey: 0)\nprint(dictDos)\n\nprint()\n\nfunc agenda() {\n    print(\"------------\")\n    print(\"    Agenda  \")\n    print(\"------------\")\n    var agenda: [String: Int] = [:]\n    let quit = false\n\n    while(!quit) {\n        print()\n        print(\"1 - Buscar\")\n        print(\"2 - Insertar\")\n        print(\"3 - Actualizar\")\n        print(\"4 - Eliminar\")\n\n        if let entrada = readLine() {\n\n            switch entrada {\n                case \"1\":\n                    search(agenda: &agenda)\n                case \"2\":\n                    insert(agenda: &agenda)\n                case \"3\":\n                    update(agenda: &agenda)\n                case \"4\":\n                    delete(agenda: &agenda)\n                default:\n                    print(\"Opción incorrecta.\")\n            }\n\n        } else {\n            print(\"No has introducido nada.\")\n        }\n    }\n}\n\nfunc search(agenda: inout [String: Int]) {\n    print()\n    print(\"Nombre del contacto: \")\n\n    if let contactName = readLine() {\n        if let contact = agenda[contactName] {\n            print(\"\\(contactName): \\(contact)\")\n        } else {\n            print(\"No existe el contacto\")\n        }\n    }\n}\n\nfunc insert(agenda: inout [String: Int]) {\n    var name: String = \"\"\n    var number: Int = 0\n\n    print()\n    print(\"Nombre del contacto: \")\n\n    if let contactName = readLine() {\n        name = contactName\n    }\n    \n    print(\"Número del contacto: \")\n\n    if let contactNumber = readLine() {\n        if let numberInt = Int(contactNumber) {\n            number = numberInt\n        } else {\n            print(\"Entrada incorrecta\")\n        }\n    }\n\n    agenda[name] = number\n\n    print(\"\\(name): \\(number)\")\n}\n\nfunc update(agenda: inout [String: Int]) {\n    print()\n    print(\"Nombre del contacto: \")\n\n    if let contactName = readLine() {\n        if let contactExist = agenda[contactName] {\n            print(\"Nuevo número:\")\n\n            if let newNumber = readLine() {\n                if let numberInt = Int(newNumber) {\n                    agenda[contactName] = numberInt\n                }\n            } \n        } else {\n            print(\"No existe el contacto\")\n        }\n    }\n}\n\nfunc delete(agenda: inout [String: Int]) {\n    print()\n    print(\"Nombre del contacto\")\n\n    if let contactName = readLine() {\n        if let contactExist = agenda[contactName] {\n            agenda.removeValue(forKey: contactName)\n        } else {\n            print(\"El contacto no existe\")\n        }\n    }\n}\n\nagenda()\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/swift/karys4.swift",
    "content": "// Types of data structure\n\n// Array: Stores an ordered collection of elements of the same data type.\nvar daysOfTheWeek = [\"Monday\",\"Tuesday\",\"Wednesday\",\"Thursday\",\"Friday\"]\ndaysOfTheWeek.append(\"Saturday\")\nvar firstDay = daysOfTheWeek[0]\ndaysOfTheWeek.sort()\ndaysOfTheWeek.removeAll()\n\n// Set: Stores an unordered collection of elements of the same data type.\nvar favoriteMusic: Set = [\"Pop\",\"Rock\",\"Electronic\",\"Jazz\"]\nfavoriteMusic.insert(\"Country\")\nfavoriteMusic.remove(\"Pop\")\n//favoriteMusic.sorted(by:>)\n\n// Dictionary: Stores associations between keys of the same type and values of the same type in a collection with no defined ordering.\nvar seasons = [\"Winter\": \"Cold\", \"Summer\": \"Hot\", \"Autumn\": \"Windy\", \"Fall\": \"Colorful\"]\nseasons[\"Other\"] = \"Random weather\"\nseasons[\"Fall\"] = nil\n//seasons.sorted(by: <)\n\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/swift/kontroldev.swift",
    "content": "import Foundation\n\n/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\n\n// Crear un array de enteros\nvar numeros = [1, 2, 3, 4, 5]\n\n// Insertar un elemento al final del array\nnumeros.append(6)\n\n// Borrar el primer elemento del array\nnumeros.removeFirst()\n\n// Actualizar el valor del tercer elemento del array\nnumeros[2] = 7\n\n// Ordenar el array de forma ascendente\nnumeros.sort()\n\n// Crear un set de cadenas\nvar colores = Set([\"rojo\", \"verde\", \"azul\"])\n\n// Insertar un elemento al set\ncolores.insert(\"amarillo\")\n\n// Borrar un elemento del set\ncolores.remove(\"rojo\")\n\n// Comprobar si el set contiene un elemento\ncolores.contains(\"verde\")\n\n// Crear un diccionario que asocia nombres con edades\nvar personas = [\"Ana\": 25, \"Luis\": 30, \"Pedro\": 28]\n\n// Insertar un par clave-valor al diccionario\npersonas[\"Marta\"] = 27\n\n// Borrar un par clave-valor del diccionario\npersonas[\"Luis\"] = nil\n\n// Actualizar el valor de una clave del diccionario\npersonas[\"Pedro\"] = 29\n\n// Ordenar el diccionario por clave\nlet ordenado = personas.sorted(by: {$0.key < $1.key})\n\n// Crear una tupla con dos elementos\nvar coordenada = (x: 10, y: 20)\n\n// Acceder al primer elemento de la tupla\ncoordenada.x\n\n// Actualizar el valor del segundo elemento de la tupla\ncoordenada.y = 15\n\n// Crear un enum con casos asociados a valores\nenum Estacion: String {\n    case primavera = \"Marzo\"\n    case verano = \"Junio\"\n    case otono = \"Septiembre\"\n    case invierno = \"Diciembre\"\n}\n\n// Crear una variable de tipo enum\nvar estacionActual = Estacion.primavera\n\n// Acceder al valor asociado al caso del enum\nestacionActual.rawValue\n\n// Crear un struct con propiedades y métodos\nstruct Rectangulo {\n    var ancho: Double\n    var alto: Double\n    \n    // Método para calcular el área\n    func area() -> Double {\n        return ancho * alto\n    }\n    \n    // Método para comparar si dos rectángulos son iguales\n    func igualA(otro: Rectangulo) -> Bool {\n        return self.ancho == otro.ancho && self.alto == otro.alto\n    }\n}\n\n// Crear una instancia de struct\nvar rect1 = Rectangulo(ancho: 5, alto: 10)\n\n// Acceder a una propiedad del struct\nrect1.ancho\n\n// Llamar a un método del struct\nrect1.area()\n\n// Crear otra instancia de struct\nvar rect2 = Rectangulo(ancho: 10, alto: 5)\n\n// Comparar dos instancias de struct\nrect1.igualA(otro: rect2)\n\n// Crear una clase con propiedades, métodos e inicializador\nclass Circulo {\n    var radio: Double\n    var color: String\n    \n    // Inicializador de la clase\n    init(radio: Double, color: String) {\n        self.radio = radio\n        self.color = color\n    }\n    \n    // Método para calcular el perímetro\n    func perimetro() -> Double {\n        return 2 * 3.14 * radio\n    }\n    \n    // Método para cambiar el color\n    func cambiarColor(nuevoColor: String) {\n        self.color = nuevoColor\n    }\n}\n\n// Crear una instancia de clase\nvar circ1 = Circulo(radio: 3, color: \"rojo\")\n\n// Acceder a una propiedad de la clase\ncirc1.radio\n\n// Llamar a un método de la clase\ncirc1.perimetro()\n\n// Cambiar el valor de una propiedad de la clase\ncirc1.cambiarColor(nuevoColor: \"azul\")\n\n\n\n// DIFICULTAD EXTRA (opcional):\n// Crear un diccionario vacío para almacenar los contactos\nvar agenda: [String: String] = [:]\n\n// Crear una variable para controlar el bucle\nvar continuar = true\n\n// Mostrar un mensaje de bienvenida\nprint(\"Bienvenido a la agenda de contactos\")\n\n// Iniciar el bucle\nwhile continuar {\n    // Mostrar las opciones disponibles\n    print(\"Seleccione una opción:\")\n    print(\"1. Buscar un contacto\")\n    print(\"2. Insertar un contacto\")\n    print(\"3. Actualizar un contacto\")\n    print(\"4. Eliminar un contacto\")\n    print(\"5. Salir\")\n    \n    // Leer la opción del usuario\n    let opcion = readLine() ?? \"\"\n    \n    // Ejecutar la opción elegida\n    switch opcion {\n    case \"1\":\n        // Buscar un contacto\n        print(\"Introduzca el nombre del contacto que desea buscar:\")\n        let nombre = readLine() ?? \"\"\n        if let numero = agenda[nombre] {\n            print(\"El número de teléfono de \\(nombre) es \\(numero)\")\n        } else {\n            print(\"No se ha encontrado ningún contacto con ese nombre\")\n        }\n    case \"2\":\n        // Insertar un contacto\n        print(\"Introduzca el nombre del contacto que desea insertar:\")\n        let nombre = readLine() ?? \"\"\n        print(\"Introduzca el número de teléfono del contacto que desea insertar:\")\n        let numero = readLine() ?? \"\"\n        // Validar que el número sea numérico y tenga menos de 11 dígitos\n        if let _ = Int(numero), numero.count < 11 {\n            agenda[nombre] = numero\n            print(\"Se ha insertado el contacto \\(nombre) con el número \\(numero)\")\n        } else {\n            print(\"El número de teléfono no es válido\")\n        }\n    case \"3\":\n        // Actualizar un contacto\n        print(\"Introduzca el nombre del contacto que desea actualizar:\")\n        let nombre = readLine() ?? \"\"\n        if agenda[nombre] != nil {\n            print(\"Introduzca el nuevo número de teléfono del contacto:\")\n            let numero = readLine() ?? \"\"\n            // Validar que el número sea numérico y tenga menos de 11 dígitos\n            if let _ = Int(numero), numero.count < 11 {\n                agenda[nombre] = numero\n                print(\"Se ha actualizado el contacto \\(nombre) con el número \\(numero)\")\n            } else {\n                print(\"El número de teléfono no es válido\")\n            }\n        } else {\n            print(\"No se ha encontrado ningún contacto con ese nombre\")\n        }\n    case \"4\":\n        // Eliminar un contacto\n        print(\"Introduzca el nombre del contacto que desea eliminar:\")\n        let nombre = readLine() ?? \"\"\n        if agenda[nombre] != nil {\n            agenda[nombre] = nil\n            print(\"Se ha eliminado el contacto \\(nombre)\")\n        } else {\n            print(\"No se ha encontrado ningún contacto con ese nombre\")\n        }\n    case \"5\":\n        // Salir\n        print(\"Gracias por usar la agenda de contactos\")\n        continuar = false\n    default:\n        // Opción inválida\n        print(\"La opción introducida no es válida\")\n    }\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/swift/miguelex.swift",
    "content": "import Foundation\n\n// Arrays\n\nvar numeros = [1, 2, 3, 4, 5]\n\n// Mostrar el array\n\nprint(\"Array original: \\(numeros)\")\n\n// Añadir un elemento al final del array\n\nnumeros.append(10)\n\n// Mostrar el array\n\nprint(\"Array con un elemento añadido: \\(numeros)\")\n\n// Borrar el primer elemento del array\n\nnumeros.removeFirst()\n\n// Mostrar el array\n\nprint(\"Array con el primer elemento borrado: \\(numeros)\")\n\n// Actualizar el valor del tercer elemento del array\n\nnumeros[2] = 13\n\n// Mostrar el array\n\nprint(\"Array con el tercer elemento actualizado: \\(numeros)\")\n\n// Ordenar el array de forma ascendente\n\nnumeros.sort()\n\n// Mostrar el array\n\nprint(\"Array ordenado de forma ascendente: \\(numeros)\")\n\n// Sets\n\nvar frutas = Set([\"Platano\", \"Manzana\", \"Pera\"])\n\n// Mostrar el set\n\nprint(\"Set original: \\(frutas)\")\n\n// Añadir un elemento al set\n\nfrutas.insert(\"Sandia\")\n\n// Mostrar el set\n\nprint(\"Set con un elemento añadido: \\(frutas)\")\n\n// Borrar un elemento del set\n\nfrutas.remove(\"Platano\")\n\n// Mostrar el set\n\nprint(\"Set con un elemento borrado: \\(frutas)\")\n\n// Comprobar si el set contiene un elemento\n\nprint(\"El set contiene Manzana: \\(frutas.contains(\"Manzana\"))\")\n\n// Diccionarios\n\nvar ruedas = [\"Coche\": 4, \"Triciclo\": 3, \"Bicicleta\": 2]\n\n// Mostrar el diccionario\n\nprint(\"Diccionario original: \\(ruedas)\")\n\n// Añadir un par clave-valor al diccionario\n\nruedas[\"Monociclo\"] = 1\n\n// Mostrar el diccionario\n\nprint(\"Diccionario con un par clave-valor añadido: \\(ruedas)\")\n\n// Borrar un par clave-valor del diccionario\n\nruedas[\"Monociclo\"] = nil\n\n// Mostrar el diccionario\n\nprint(\"Diccionario con un par clave-valor borrado: \\(ruedas)\")\n\n// Actualizar el valor de una clave del diccionario\n\nruedas[\"Triciclo\"] = 4\n\n// Mostrar el diccionario\n\nprint(\"Diccionario con el valor de una clave actualizado: \\(ruedas)\")\n\n// Ordenar el diccionario por clave\n\nprint(\"Diccionario ordenado por clave: \\(ruedas.sorted(by: {$0.key < $1.key}))\")\n\n// Tuplas\n\nvar coordenada = (x: 0, y: 0)\n\n// Mostrar la tupla\n\nprint(\"Tupla original: \\(coordenada)\")\n\n// Acceder al primer elemento de la tupla\n\nprint(\"Primer elemento de la tupla: \\(coordenada.x)\")\n\n// Actualizar el valor del segundo elemento de la tupla\n\ncoordenada.y = -20\n\n// Mostrar la tupla\n\nprint(\"Tupla con el segundo elemento actualizado: \\(coordenada)\")\n\n// Enums\n\nenum Coordenada: String {\n    case N = \"Norte\"\n    case S = \"Sur\"\n    case E = \"Este\"\n    case W = \"Oeste\"\n}\n\n// Mostrar el enum\n\nprint(\"Enum original: \\(Coordenada.N.rawValue)\")\n\n// Crear una variable de tipo enum\n\nvar miCoordenada = Coordenada.W\n\n// Acceder al valor asociado al caso del enum\n\nprint(\"Valor asociado al caso del enum: \\(miCoordenada.rawValue)\")\n\n// Structs\n\nstruct Coche {\n    var motor: Int\n    var ruedas: Int\n    \n    // Método para calcular el área\n    func precio() -> Int {\n        return motor * ruedas * 1000 / 3\n    }\n}\n\n// Crear una instancia de struct\n\nvar miCoche = Coche(motor: 1500, ruedas: 4)\n\n// Mostrar una propiedad del struct\n\nprint(\"Propiedad del struct: \\(miCoche.motor)\")\n\n// Llamar a un método del struct\n\nprint(\"Método del struct: \\(miCoche.precio())\")\n\n// Extra\n\nvar agenda: [String: String] = [:]\n\n// Crear una variable para controlar el bucle\nvar continuar = true\n\n// Mostrar un mensaje de bienvenida\nprint(\"Mi Agenda\")\n\nfunc menu() {\n    print(\"1. Buscar un contacto\")\n    print(\"2. Insertar un contacto\")\n    print(\"3. Actualizar un contacto\")\n    print(\"4. Eliminar un contacto\")\n    print(\"5. Salir\")\n    print(\"Selecciones opción:\")\n}\n    \nfunc findPerson() {\n\n    print(\"Nombre del contacto:\")\n    let nombre = readLine() ?? \"\"\n    if let numero = agenda[nombre] {\n        print(\"El número de teléfono de \\(nombre) es \\(numero)\")\n    } else {\n        print(\"Contacto no disponible\")\n    }\n}\n\nfunc addPerson(){\n    print(\"Nombre del contacto:\")\n    let nombre = readLine() ?? \"\"\n    print(\"Telefono:\")\n    let numero = readLine() ?? \"\"\n\n    if let _ = Int(numero), numero.count < 11 {\n        agenda[nombre] = numero\n        print(\"Contacto añadido\")\n    } else {\n        print(\"Telefono no valido\")\n    }\n}\n\nfunc erasePerson(){\n    print(\"Contacto a borrar:\")\n    let nombre = readLine() ?? \"\"\n    if agenda[nombre] != nil {\n        agenda[nombre] = nil\n        print(\"Eliminado\\(nombre)\")\n    } else {\n        print(\"Contacto no existente\")\n    }\n}\n\nfunc updatePerson(){\n    print(\"Contacto a actualziar:\")\n    let nombre = readLine() ?? \"\"\n    if agenda[nombre] != nil {\n        print(\"Nuevo telefonoo:\")\n        let numero = readLine() ?? \"\"\n        // Validar que el número sea numérico y tenga menos de 11 dígitos\n        if let _ = Int(numero), numero.count < 11 {\n            agenda[nombre] = numero\n            print(\"Actualziado correctamente\")\n        } else {\n            print(\"Telefono no valido\")\n        }\n    } else {\n        print(\"Contacto no existente\")\n    }\n}\n\n\n// Iniciar el bucle\nwhile continuar {\n    menu()\n    let opcion = readLine() ?? \"\"\n    \n    switch opcion {\n        case \"1\":\n            // Buscar persona\n           findPerson()\n        case \"2\":\n            // Insertar un contacto\n            addPerson()\n        case \"3\":\n            // Actualizar un contacto\n            updatePerson()\n        case \"4\":\n            // Eliminar un contacto\n            erasePerson()\n        case \"5\":\n            // Salir\n            print(\"Cerrando agenda\")\n            continuar = false\n        default:\n            // Opción inválida\n            print(\"Error\")\n    }\n}\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/swift/pedroomar23.swift",
    "content": "import Foundation\n\n/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\n// Ejemplos de estructuras \nstruct Person { // Ejemplo 1\n    var nombre: String \n    var age: Int \n}\nPerson(nombre: \"Julio\", age: 20) // Llamar a la instancia de la estructura\nprint(\"El perfil de la persona es\", Person(nombre: \"Julio\", age: 20)) // Print en la consola la instancia de la estructura\n\nstruct Car { // Ejemplo 2\n    var motor = 20\n    var espejos = 25\n    var gomas = 30\n\n    func BuyCar(motor: Int, espejos: Int, gomas: Int) -> Int {\n        return motor + espejos / gomas * 100\n    }\n\n    print(\"El resultado de la combinada 20 + 25 / 30 * 100 es \\(BuyCar(motor: 20, espejos: 25, gomas: 30))\")\n}\nCar(motor: 20, espejos: 25, gomas: 30)\nprint(\"El precio de las piezas de los carros es\", Car(motor: 20, espejos: 25, gomas: 30))\n\n// Array de cadena de texto (String)\nvar nombres = Set([\"Pedro\", \"Juan\", \"Oscar\"])\n\nnombres.insert(\"Carlos\") // Añadir un elemento al Array\nprint(\"El elemento añadido es \\(nombres)\")\n\nnombres.contains(\"Pedro\") // Comprobar si exite un elemento en el Array\nprint(\"Comprobando si esta Pedro en el Array \\(nombres)\")\n\nnombres.sorted() // Ordenar de forma ascendente el Array \nprint(\"El array ordenado de forma ascendente \\(nombres)\")\n\nnombres.remove(\"Pedro\") // Eliminar un elemento del Array \nprint(\"El elemento eliminado es Carlos \\(nombres)\")\n\n// Array de cadena de enteros (Int)\nvar numeros = [1, 2, 3, 4]\n\nnumeros.append(5) // Añadir un entero al Array\nprint(\"5 es el nuevo entero en el array\")\n\nnumeros.removeFirst(1) // Eliminar un entero del Array\nprint(\"El primer entero eliminado es \\(numeros)\")\n\nnumeros.removeAll() // Eliminar todos los enteros del Array\nprint(\"Todos lo enteros del Array eliminados \\(numeros)\")\n\nnumeros.sorted() // Ordenar los enteros de forma ascendente\nprint(\"Ordenado el Array \\(numeros)\")\n\nnumeros.contains(3) // Comprobando si hay un enetero en específico en el Array\nprint(\"Comprobando si 3 esta en el Array\")\n\n\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/swift/zetared92.swift",
    "content": "import Foundation\n\n// RETO #03 ESTRUCTURAS DE DATOS\n\n// ARRAYS\nvar arrayNum = [1, 2, 3, 4, 5, 6] // Mutable\nlet arrayNumLet = [6, 5, 4, 3, 2, 1] // Inmutable\n\n// Agregar valores\narrayNum.append(4) // Agrega el valor dentro del array\narrayNum.insert(0, at: 2) // Añade el valor 0 en la posición 2.\n\n// Eliminar valores\narrayNum.removeLast() // Elimina el último valor del array\narrayNum.remove(at:3) // Elimina el valor ubicado en la posición 3\narrayNum.removeFirst() // Elimina el primer valor del array\narrayNum.removeSubrange(3...5) // Elimina los valores del 3 al 5\n\n// Eliminar todo el array\narrayNum.removeAll()\n\n// Actualización de datos del array\narrayNum = [100, 110, 120, 130, 140, 150, 160, 170, 180, 190] // Actualiza al nuevo array\narrayNum[4] = 125 // Actualiza el valor de la 4ta posición (130->125)\n\n// Actualización de un valor concreto\narrayNum.replace([100, 110], with: [25, 50])\n\n// Actualización de un subrange\narrayNum.replaceSubrange(3...6, with:[75, 100, 125, 150])\n\n\n// Ordenaciones\nvar sortedArray = arrayNum.sorted() // Ordena de menor a mayor los valores\nsortedArray.reverse() // De mayor a menor inviertiendo el array anterior\nsortedArray = arrayNum.sorted {$0 < $1} // De menor a mayor asignándole una var\nsortedArray = arrayNum.sorted {$0 > $1} // De mayor a menor asignándole una var\narrayNum.sort {$0 < $1} // Ordenación de elementos de menor a mayor\narrayNum.sort {$0 > $1} // Ordenación de elementos de mayor a menor\n\n\n// DICCIONARIOS\nlet myClassicDictionary = Dictionary<Int, String>() // Forma clásica\nvar myDictionary = [Int:String]() // Forma moderna\n\n// Añadir datos\nmyDictionary = [001:\"Turing\", 002: \"Schrödinger\"]\n\n// Añadir un solo dato\nmyDictionary[003] = \"Planck\"\nmyDictionary[004] = \"Bohr\"\nmyDictionary[005] = \"Oppenheimer\"\nmyDictionary[006] = \"Einstein\"\n\n// Acceso a un dato\nmyDictionary[002]\n\n// La clave del diccionario es única\nmyDictionary[002] = \"Schrödinger\"\nmyDictionary.updateValue(\"Erwin Schrödinger\", forKey: 002) // Opción clásica\nmyDictionary[002]\n\n// Borrado de datos\nmyDictionary[002] = nil // La palabra nil significa nulo. Esta es la opción moderna.\nmyDictionary.removeValue(forKey:002) // Opción clásica.\nmyDictionary.removeAll()\n\n// Ordenación\nvar myDicGreaterKey = myDictionary.sorted {$0.key < $1.key} // Menor a mayor\nvar myDicLessKey = myDictionary.sorted {$0.key > $1.key} // Mayor a menor\nvar myDicGreaterVal = myDictionary.sorted {$0.value < $1.value} // Menor a mayor\nvar myDicLessVak = myDictionary.sorted {$0.value > $1.value} // Mayor a menor\n\n\n// SETS\nvar mySet: Set<Int> = [10, 20, 30, 40, 50, 60, 70, 80. 90]\n\nmySet.insert(100) // Inserta el valor 100 dentro del set\nmySet.update(with:00) // Inserta el 00 dentro del set independientemente de su posición\n\n// Borrado\nmySet.remove(50)\nmySet.removeFirst()\nmySet.removeLast()\nmySet.removeAll()\n\n// Ordenación\nlet sortedSet = mySet.sorted()\n\n\n// TUPLAS\n/* No es una colección pero actúa como tal. Agrupan múltiples valores en un solo valor\ncompuesto. Los valores pueden ser de cualquier tipo y no tienen que ser del mismo tipo\nentre sí.*/\n            // Name, Surname, Age, Height\nvar person = (\"Zeta\", \"Red\", 31, 1.70) // Tipos: String, String, Int, Double.\nperson.2 // De esta manera accedemos a un valor determinado en la tupla.\nvar (name, surname, age, height) = person // De esta manera estamos asignando los valores de nuestra tupla\nAge\nvar personNameTuples = (name: \"Zeta\", surname: \"Red\", age: 31, height: 1.70)\npersonNameTuples.Age // Esta es una manera de acceder a valores concretos usando el nombre.\n\n// 🧩 DIFICULTAD EXTRA 🧩\nvar contacts: [String: String] = [\n    \"Princess Diana\" : \"678905467\",\n    \"Barry Allen\" : \"654321231\",\n    \"Dick Grayson\" : \"690877809\",\n    \"Jim Gordon\" : \"686754857\",\n    \"Alfred Pennyworth\" : \"606321074\",\n    \"Selina Kyle\" : \"620897645\",\n]\n\nvar next = true\nprint(\"Welcome to the contact book Mr. Wayne\")\n\n// Bucle\nwhile next {\n    print(\"Select an option:\")\n    print(\"1.-Search\")\n    print(\"2.-Insert new contact\")\n    print(\"3.-Update a contact\")\n    print(\"4.-Delete contact\")\n    print(\"5.-Exit\")\n\n    let option = readLine () ?? \"\"\n\n    switch option {\n    case \"1\":\n        print(\"Input the contact name:\")\n        let name = readLine() ?? \"\"\n        if let num = contacts[name] {\n            print(\"The \\(name)'s phone number is: \\(num)\")\n        } else {\n            print(\"This contact does not exist\")\n        }\n    case \"2\":\n        print(\"Input the name of the new contact\")\n        let name = readLine() ?? \"\"\n        print(\"Input the number of the new contact\")\n        let num = readLine() ?? \"\"\n        // The new contact must meet the entry requirements\n        if let _ = Int(num), num.count < 9 {\n            contacts[name] = num\n            print(\"New contact accepted\")\n        } else {\n            print(\"Invalid phone number\")\n        }\n    case \"3\":\n        print(\"Input the contact name you want to update\")\n        let name = readLine() ?? \"\"\n        if contacts[name] != nil {\n            print(\"Input the new phone number\")\n            let num = readLine() ?? \"\"\n            if let _ = Int(num), num.count < 9 {\n                contacts[name] = num\n                print(\"The \\(name)'s phone number is update now\")\n            } else {\n                print(\"Invalid phone number\")\n            }\n        } else {\n            print(\"This contaxt does not exist\")\n        }\n    case \"4\":\n        print(\"Input the contact you want to delete:\")\n        let name = readLine() ?? \"\"\n        if contacts[name] != nil {\n            contacts[name] = nil\n            print(\"The \\(name)'s contact has been deleted\")\n        } else {\n            print(\"This contact does not exist\")\n        }\n    case \"5\":\n        print(\"Every damn night and yet.. I'm still here\")\n        next = false\n    default:\n        print(\"Invalid option\")\n    }\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/typescript/AChapeton.ts",
    "content": "// **** TIPOS DE ESTRUCTURAS ****\n\n// ** ARRAYS **\n// Tiene dos formas distintas de tiparlo pero ambas dan el mismo resultado\n// Se pueden combinar los tipos de datos que se permiten almacenar o incluso personalizarlos, a estos elementos se les llama Tuplas\nlet numbers: number[] = [2, 4, 6, 8]\nlet letters: string[] = ['p', 'b', 'd', 'q']\nlet combined: Array<string | boolean> = ['abc', true, 'def', false] //No se permite otro tipo de dato que no sea String o Boolean\n\ninterface User {\n  id: number, \n  name: string,\n  subscribed: boolean\n}\n\nlet users: User[] = [\n  {\n    id: 1, \n    name: 'Andres',\n    subscribed: true\n  },\n  {\n    id: 2, \n    name: 'Brais',\n    subscribed: false\n  },\n  {\n    id: 3, \n    name: 'Chape',\n    subscribed: false\n  },\n  {\n    id: 4, \n    name: 'Jesus',\n    subscribed: true\n  },\n  {\n    id: 5, \n    name: 'Midudev',\n    subscribed: true\n  },\n  {\n    id: 6, \n    name: 'Teffcode',\n    subscribed: false\n  }\n]\nconsole.log('users', users)\n\n// Operaciones en Arrays\n\n//Push - Agregar elementos al final\nconst pushUser = {\n    id: 11, \n    name: 'Moure',\n    subscribed: true\n}\nusers.push(pushUser)\nconsole.log('push', users)\n\n//Unshift - Agregar elementos al inicio\nconst unshiftUser = {\n    id: 0, \n    name: 'Mouredev',\n    subscribed: false\n}\nusers.unshift(unshiftUser)\nconsole.log('unshift', users)\n\n//Splice - Agregar elementos en cualquier posicion\n//El primer parametro es para indicar en que posicion agregarlo\n//El segundo parametro es para indicar cuantos elementos se reemplazarian (0 es ningun elemento)\n//El tercer parametro es el elemento a agregar\nconst spliceUser = {\n    id: 12, \n    name: 'Chape',\n    subscribed: false\n}\nusers.splice(2, 0, spliceUser)\nconsole.log('splice', users)\n\n//Pop - Eliminar el ultimo elemento\nusers.pop()\nconsole.log('pop', users)\n\n//Shift - Eliminar el primer elemento\nusers.shift()\nconsole.log('shift', users)\n\n//Splice - Eliminar un elemento en cualquier posicion\n//El primer parametro es la posicion del elemento\n//El segundo parametro es la cantidad de elementos a eliminar desde la posiocion indicada\nusers.splice(2, 1)\nconsole.log('splice', users)\n\n//Filter - Crea un nuevo array con los elementos que cumplan el criterio\nconst fiteredUsers = users.filter(user => user.id < 10)\nconsole.log('filter', fiteredUsers)\n\n//Sort - Metodo para ordenar datos\nlet unorderedArray = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5];\n\n// Ordenar el array\nunorderedArray.sort((a, b) => a - b);\nconsole.log('sort', unorderedArray)\n\n\n// ** SETS **\nlet mySet: Set<number> = new Set()\n\n//Add - Agregar un valor\nmySet.add(1)\nmySet.add(2)\nmySet.add(3)\n// mySet.add('string') - No se permite porque el Set fue tipado de solo numeros\nconsole.log('add', mySet)\n\n//Has - Verificar si un valor existe dentro del Set\nmySet.has(1) //true\nmySet.has(3) //false\n\n//Delete - Elimina un valor\nmySet.delete(1)\nconsole.log('delete', mySet)\n\n//Size - Devuelve el tama;o del set\nconsole.log('size', mySet.size)\n\n//Clear - Eliminar todos los elementos\nmySet.clear()\nconsole.log('clear', mySet)\n\n\n// ** OBJETOS **\n//En TypeScript, se suele declarar la estructura de un objeto por medio de Interface\n//Para agregar o eliminar una nueva propiedad, no se podria directamente crer un objeto y a ese colocarle la nueva propiedad, ya que este objeto iria en base al tipado de la interfaz\n\ninterface Person{\n  name: string,\n  age: number,\n  genre: string\n}\n\n\n\n// *** EJERCICIO EXTRA *** \n\ninterface Contact {\n  nombre: string | null,\n  telefono: number | null,\n}\n\nconst contacts: Contact[] = []\n\nconst agregarContacto = () => {\n  let newName: string | null = null;\n  let newPhone: string | null = null;\n\n  do {\n    newName = prompt('Nombre: ');\n    if (!newName) {\n      console.log('Por favor, ingresa un nombre válido.');\n    }\n  } while (!newName);\n\n  do {\n    newPhone = prompt('Telefono: ');\n    if (!newPhone) {\n      console.log('Por favor, ingresa un número de teléfono válido.');\n    }\n  } while (!newPhone);\n\n  const newContact = {\n    nombre: newName,\n    telefono: parseInt(newPhone)\n  };\n  \n  contacts.push(newContact)\n}\n\nconst buscarContacto = () => {\n  let searchedName : string | null = null;\n  do {\n    searchedName = prompt('Buscar por nombre: ')\n  } while (!searchedName);\n  const searchedResult : Contact | undefined = contacts.find(contact => contact.nombre.toLowerCase() === searchedName.toLowerCase())\n  if(searchedResult === undefined){\n    alert(searchedName + ' no existe') \n  }else{\n    alert(JSON.stringify(searchedResult, null, 2)) \n  }\n}\n\nconst actualizarContacto = () => {\n  let searchedName: string | null = null\n  do{\n    searchedName = prompt('Buscar por nombre: ')\n  }while(!searchedName)\n  const searchedResult: number | undefined = contacts.findIndex(contact => contact.nombre.toLowerCase() === searchedName.toLowerCase())\n  if(searchedResult === undefined){\n    alert(searchedName + ' no existe') \n  }else{\n    let newName : string | null = null;\n    let newPhone : string | null = null;\n    do{\n      newName = prompt('Nuevo nombre', contacts[searchedResult]?.nombre || '')\n      contacts[searchedResult].nombre = newName\n    }while(newName === null)\n    do{\n      newPhone = prompt('Nuevo telefono', contacts[searchedResult]?.telefono.toString() || '')\n      contacts[searchedResult].telefono = parseInt(newPhone)\n    }while(newPhone === null)\n    alert(searchedName + ' fue actualizado a ' + newName) \n  }\n}\n\nconst eliminarContacto = () => {\n  let searchedName : string | null = null;\n  do {\n    searchedName = prompt('Nombre de contacto a eliminar: ')\n  } while (!searchedName);\n  const searchedResult: number | undefined = contacts.findIndex(contact => contact.nombre.toLowerCase() === searchedName.toLowerCase())\n  if(searchedResult === undefined){\n    alert(searchedName + ' no existe') \n  }else{\n    if (searchedResult >= 0 && searchedResult < contacts.length) {\n      contacts.splice(searchedResult, 1);\n      alert(searchedName + ' fue eliminado')\n    } else {\n      console.log('Índice inválido');\n    }\n  }\n}\n\nconst listarContactos = () => {\n  const contactsString = JSON.stringify(contacts, null, 2);\n  alert(contactsString);\n}\n\nconst agendaApp = () => {\n  let option: string | null = ''\n  const menu: string = 'MENU: \\n 1. Agregar nuevo contacto \\n 2. Buscar contacto \\n 3. Actualizar contact \\n 4. Eliminar un contacto \\n 5. Listar todos los contactos \\n 6. Salir'\n\n  while (option !== '6') {\n    option = prompt(menu)\n\n    switch (option) {\n      case '1':\n        agregarContacto()\n        break;\n      case '2':\n        buscarContacto()\n        break;\n      case '3':\n        actualizarContacto()\n        break;\n      case '4':\n        eliminarContacto()\n        break;\n      case '5':\n        listarContactos()\n        break;\n      case '6':\n        break;\n      default:\n        console.log('Opcion no valida. Intentar de nuevo.')\n        break;\n    }\n  }\n}\n\nagendaApp()\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/typescript/Andeveling.ts",
    "content": "// Ejemplos de estructuras de datos\n// Arrays\nconst numeros: number[] = [1, 2, 3, 4, 5]\n\n// Inserción\nnumeros.push(6) // Agrega un elemento al final\nnumeros.unshift(0) // Agrega un elemento al principio\n\n// Borrado\nnumeros.pop() // Elimina el último elemento\nnumeros.shift() // Elimina el primer elemento\n\n// Actualización\nnumeros[6] = 8\nnumeros[7] = 10\nnumeros[8] = 20\n\n// Objetos\nlet persona = {\n  nombre: \"Juan\",\n  apellido: \"\",\n  edad: 30,\n  estaActiva: true,\n}\n\n// Inserción\npersona.apellido = \"Pérez\"\n// Borrado Lógico\npersona.estaActiva = false\n// Actualización\npersona.edad = 40\n\n// Tuplas\nconst tupla: [number, string, boolean] = [1, \"andres\", true]\n\n// Enum\nenum Color {\n  Rojo,\n  Verde,\n  Azul,\n}\nlet color: Color = Color.Rojo\n\n// Uniones de Tipos\nlet variable: number | string\nvariable = 123\nvariable = \"andres\"\n\n// Agenda de contactos\nimport * as readline from \"readline\"\n\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout,\n})\n\nclass Entity {\n  id: number\n  constructor() {\n    this.id = this.generateId()\n  }\n\n  generateId(): number {\n    let id = Math.floor(Math.random() * 10000)\n    return id\n  }\n}\nclass Contact extends Entity {\n  name: string\n  cellphone: string\n  constructor(name: string, cellphone: string) {\n    super()\n    this.name = name\n    this.cellphone = cellphone\n  }\n}\nclass Validator {\n  static validateName(name: string): boolean {\n    return /^[a-zA-Z\\s]{3,15}$/.test(name)\n  }\n\n  static validateCellphone(cellphone: string): boolean {\n    return /^\\d{10}$/.test(cellphone)\n  }\n}\nclass AddressBook extends Entity {\n  private static instance: AddressBook\n  private contacts: Array<Contact> = []\n\n  private constructor() {\n    super()\n  }\n\n  public static getInstance(): AddressBook {\n    if (!AddressBook.instance) {\n      AddressBook.instance = new AddressBook()\n    }\n    return AddressBook.instance\n  }\n  addContact(contact: Contact) {\n    this.contacts.push(contact)\n  }\n\n  getContacts() {\n    return this.contacts\n  }\n\n  deleteContact(id: number) {\n    const findContact = this.findById(id)\n    if (findContact) {\n      this.contacts = this.contacts.filter((contact) => contact.id !== id)\n    } else {\n      console.log(`Contact not found with id ${id}`)\n    }\n  }\n\n  updateContact(id: number, contact: Contact) {\n    const findContact = this.findById(id)\n    if (findContact) {\n      findContact.name = contact.name\n      findContact.cellphone = contact.cellphone\n    } else {\n      console.log(`Contact not found with id ${id}`)\n    }\n  }\n\n  findById(id: number) {\n    const findContact = this.contacts.find((contact) => contact.id === id)\n    if (findContact) {\n      return findContact\n    } else {\n      return null\n    }\n  }\n}\n\nasync function main() {\n  let execute = true\n\n  const menu = async () => {\n    console.log(\"Welcome to Address Book\")\n    console.log(\"Choose an option:\")\n    console.log(\"1. Add contact\")\n    console.log(\"2. Show contacts\")\n    console.log(\"3. Search contact\")\n    console.log(\"4. Delete contact\")\n    console.log(\"5. Update contact\")\n    console.log(\"6. Exit\")\n\n    const answer = await questionAsync(\"Enter an option: \")\n    const option = Number(answer)\n\n    if (option < 1 || option > 6) {\n      console.log(\"Invalid option\")\n      await menu() // Reiterar el menú si la opción es inválida\n      return\n    }\n\n    const addressBook = AddressBook.getInstance()\n    let name = \"\"\n    let cellphone = \"\"\n\n    switch (option) {\n      case 1:\n        console.log(\"Add contact\")\n        do {\n          name = await questionAsync(\"Enter name, only letters, min 3 max 15 chars: \")\n          if (!Validator.validateName(name)) console.warn(\"Invalid name\")\n        } while (!Validator.validateName(name))\n\n        do {\n          cellphone = await questionAsync(\"Enter cellphone, only numbers and 10 digits: \")\n          if (!Validator.validateCellphone(cellphone)) console.warn(\"Invalid cellphone\")\n        } while (!Validator.validateCellphone(cellphone))\n\n        const newContact = new Contact(name, cellphone)\n\n        addressBook.addContact(newContact)\n        console.log(`Contact added: ${name} - ${cellphone}`)\n        await menu() // Llamar nuevamente a la función de menú para continuar\n        break\n      case 2:\n        console.log(\"Show contacts\")\n        const contacts = AddressBook.getInstance().getContacts()\n        if (contacts.length === 0) {\n          console.log(\"No contacts found\")\n        }\n        console.table(contacts)\n        break\n      case 3:\n        console.log(\"Search contact\")\n        const id = await questionAsync(\"Enter contact id to search: \")\n        const contactFind = addressBook.findById(Number(id))\n        if (contactFind) {\n          console.log(contactFind)\n        } else {\n          console.error(`Contact not found with id ${id}`)\n        }\n        break\n      case 4:\n        console.log(\"Delete contact\")\n        const idDelete = await questionAsync(\"Enter contact id to delete: \")\n        const contactDelete = addressBook.findById(Number(idDelete))\n        if (contactDelete) {\n          addressBook.deleteContact(Number(idDelete))\n          console.log(`Contact deleted: ${contactDelete.name} - ${contactDelete.cellphone}`)\n        } else {\n          console.error(`Contact not found with id ${idDelete}`)\n        }\n\n        break\n      case 5:\n        console.log(\"Update contact\")\n        const idUpdate = await questionAsync(\"Enter contact id to update: \")\n        const contactUpdate = addressBook.findById(Number(idUpdate))\n        if (contactUpdate) {\n          do {\n            name = await questionAsync(\"Enter name, only letters, min 3 max 15 chars: \")\n            if (!Validator.validateName(name)) console.warn(\"Invalid name\")\n          } while (!Validator.validateName(name))\n\n          do {\n            cellphone = await questionAsync(\"Enter cellphone, only numbers and 10 digits: \")\n            if (!Validator.validateCellphone(cellphone)) console.warn(\"Invalid cellphone\")\n          } while (!Validator.validateCellphone(cellphone))\n        }\n\n        break\n      case 6:\n        execute = false\n        rl.close()\n        console.log(\"Goodbye!\")\n        break\n      default:\n        console.log(\"Invalid option\")\n    }\n\n    if (execute) {\n      await menu() // Si aún se debe ejecutar, mostrar el menú nuevamente\n    }\n  }\n\n  await menu() // Llamar a la función de menú para comenzar\n}\n\nasync function questionAsync(question: string): Promise<string> {\n  return new Promise((resolve) => {\n    rl.question(question, (answer) => {\n      resolve(answer)\n    })\n  })\n}\n\nmain()\n\n\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/typescript/Guillemduno.ts",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n */\n\n/**\n *\n * DATOS PRIMITIVOS\n *\n *  */\n// undefined\nconst noDefinido: undefined = undefined;\nconsole.log(typeof noDefinido);\n\n// null\nconst isNull: null = null;\nconsole.log(typeof isNull);\n\n// booleano\nconst tengoFe: boolean = true;\nconsole.log(typeof tengoFe);\n\n// number\nconst partidosGanados: number = 5;\nconsole.log(typeof partidosGanados);\n\n// string\nconst titulo: string = \"La casa de papel\";\nconsole.log(typeof titulo);\n\n/**\n *\n * OBJETOS\n *\n * */\n\n// Arrays\nlet misHobbies: string[] = [\"Fotografía\", \"Cómics\"];\nlet edatAmigos: number[] = [23, 25, 21, 24];\n\n// Tuplas\nlet artist: [string, number] = [\"Bon Iver\", 2];\n\n/**\n *  Maps ( a diferència de los arrays no se tiene en cuenta el orden de los elementos,\n *  se accede a ellos mediante la clave).\n *\n * */\n\nlet myMap = new Map<string, number>([\n  [\"Guillem\", 34],\n  [\"Carol\", 23],\n]);\n\nmyMap.set(\"Anna\", 35); // Añade una clave y un valor.\n\nmyMap.get(\"Carol\"); // Obtenemos el valor de la clave 'Carol', 23.\n\nmyMap.has(\"Carol\"); // Comprueba que exista la clave 'Carol'.\n\nmyMap.delete(\"Carol\"); // Elimina esta clave.\n\nconsole.log(myMap.get(\"Carol\")); // Devuelve undefined.\n\nfor (const [key, value] of myMap) {\n  console.log(key + \" - \" + value); // Mostramos todas las claves y valores.\n}\n\n// Set los elementos pueden ser de qualquier tipo y no se tiene en cuenta el orden;\n\nlet misDatos = new Set();\n\nmisDatos.add(20);\nmisDatos.add([\"pepino\", \"almendras\"]);\nmisDatos.add({ nombre: \"Pepe\", edad: 14 });\nmisDatos.add(\"Escuela de dibujo\");\nmisDatos.has(20); // true.\n\nfor (const iterator of misDatos) {\n  console.log(iterator); // Mostramos los diferentes elementos.\n}\n\n/**\n * Stack (Pila) - datos estructurados en forma de lista.\n *\n * LIFO last in first out - El último que entra, es el primero en salir.\n *\n * */\n\n// Ejemplo con un array.\nlet misFrutas: string[] = [\"Fresas\", \"Manzanas\", \"Platanos\"];\n\nmisFrutas.push(\"Naranjas\");\nconsole.log(misFrutas);\nmisFrutas.pop();\nconsole.log(misFrutas);\n\n/**\n * QUEU (Cola) - datos estructurados en forma de lista\n *\n * FIFO First in first out - El primero que entra, es el primero en salir.\n *\n */\n\nlet pedidos: string[] = [\"Enviar pedido 1\", \"Enviar pedido 2\"];\npedidos.push(\"Enviar pedido 3\");\nconsole.log(pedidos);\npedidos.shift();\nconsole.log(pedidos);\n\n/**\n * LISTAS ENLAZADAS\n *\n * Similares a un array\n * los elementos NO son almacenados en memoria o indice en particular\n * cada elemento es un objecto que apunta al siguiente objeto.\n * Cada elemento contiene un nodo que se compone de un valor y enlace al siguiente nodo.\n * Si una lista esta vacía, la cabezera es una referencia nula.\n *\n * Ventajas: removidos o agregados sin importar orden. Al contrario que los arrays.\n * Desventajas: las operaciones de busqueda son lentas.\n *              uso mayor de memoria que los arreglos\n *\n * Tipos de listas enlazadas:\n *  - individuales\n *  - doblemente enlazadas\n *  - circulares enlazadas\n *\n * Ejemplo lista enlazada individual:\n */\n\nclass Nodo {\n  constructor(private value: number, public siguiente: any = null) {\n    this.value = value;\n    this.siguiente = null;\n  }\n}\n\nclass listaEnlazada {\n  private cabezera: any;\n  private cola: any;\n  constructor() {\n    this.cabezera = null;\n    this.cola = null;\n  }\n\n  append(valor: number) {\n    const newNode = new Nodo(valor);\n    if (!this.cabezera) {\n      this.cabezera = newNode;\n    } else {\n      this.cola.siguiente = newNode;\n    }\n\n    this.cola = newNode;\n  }\n\n  traverse(callback: any) {\n    let currentNode = this.cabezera;\n\n    while (currentNode !== null) {\n      callback(currentNode);\n      currentNode = currentNode.siguiente;\n    }\n  }\n}\n\nconst printNode = (node: any) => console.log(node.value);\n\nlet miLista = new listaEnlazada();\n\nmiLista.append(6);\nmiLista.append(8);\nmiLista.append(9);\n\nmiLista.traverse(printNode);\n\n/**\n * Trees (Arboles) - Estructura de datos en forma de arbol.\n *\n * Parten de un nodo raiz, y tienen una relación padre / hijo.\n * Los nodos que no tienen hijo, se llaman nodos hoja (leaf nodes).\n * La altura del arbol, se determina por la cantidad de connexiones padre /hijo.\n *\n * Un ejemplo de estructura de arbol seria el model DOM (Document Object Model).\n *\n * Hay diferentes tipos de estructuras de arbol, però las más comunes són:\n *  - Binary trees\n *  - Heaps\n *  */\n\n/**\n * Graphs (Grafos) - Estructura de datos en forma de gràfico.\n *\n * No parten de un nodo raiz. Todos los nodos estan conectados entre ellos.\n *\n * Las estructuras de datos gràfico són útiles para la creacion de aplicaciones\n * de redes sociales.\n *\n * Hay diferentes tipos de grafos\n *  - Directos e indirectos\n *  - Pesado o ligeros.\n */\n\n/*\n * EJERCICIO EXTRA:\n *\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización\n *   y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n *   y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más\n *   de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.\n */\n\ninterface tipoContacto {\n  nombre: string;\n  telefono: number | null;\n}\n\nclass Contacto implements tipoContacto {\n  public nombre: string;\n  public telefono: number;\n  constructor(nombre: string, telefono: number) {\n    this.nombre = nombre;\n    this.telefono = telefono;\n  }\n}\n\nclass ListaContactos {\n  private lista: tipoContacto[];\n  private contacto: Contacto;\n  constructor() {\n    this.lista = [];\n    this.contacto = { nombre: \"\", telefono: 0 };\n  }\n\n  // Buscar\n  buscar(nombre: string) {\n    if (this.lista.length > 0) {\n      let encontrado = false;\n      this.lista.forEach((element) => {\n        if (element.nombre == nombre) {\n          console.log(`Se ha encontrado este contacto ${element.nombre} - ${element.telefono}`);\n          encontrado = true;\n        }\n      });\n      if (!encontrado) {\n        console.log(`No se ha encontrado ningun contacto con el nombre ${nombre}`);\n      }\n    } else {\n      console.log(\"No existe ningun contacto.\");\n    }\n  }\n\n  // Inserir\n  inserir(nombre: string, telefono: number) {\n    const contacto = new Contacto(nombre, telefono);\n    this.lista.push(contacto);\n    console.log(`El contacto (${contacto.nombre}) se ha inscrito correctamente`);\n  }\n\n  // Actualizar\n  actualizar(nombre: string, telefono: number) {\n    let encontrado = false;\n    this.lista.forEach((element) => {\n      if (element.nombre === nombre) {\n        element.telefono = telefono;\n        console.log(`El contacto (${element.nombre}) se ha actualizado correctamente`);\n        encontrado = true;\n      }\n    });\n    if (!encontrado) {\n      console.log(`El contacto ${nombre} no existe, por eso no se puede actualizar.`);\n    }\n  }\n\n  // Eliminar\n  eliminar(nombre: string) {\n    const index = this.lista.findIndex((item) => item.nombre === nombre);\n\n    if (index !== -1) {\n      this.lista.splice(index, 1);\n      console.log(`El contacto ${nombre} se ha eliminado de la Agenda de Contactos.`);\n    } else {\n      console.log(`El contacto  ${nombre} no existe.`);\n    }\n  }\n\n  // Mostrar todos los contactos\n  mostrarContactos() {\n    console.log(\"======== CONTACTOS =======\");\n    if (this.lista.length > 0) {\n      this.lista.forEach((element, indice) => {\n        console.log(`Nombre: ${element.nombre}, teléfono: ${element.telefono}`);\n      });\n    } else {\n      console.log(\"No hay contactos que mostrar.\");\n    }\n\n    console.log(\"==========================\");\n  }\n}\n\nlet miListaContactos = new ListaContactos();\nlet salirContactos = false;\n\nwhile (salirContactos === false) {\n  // Menú inicial\n  const accion = prompt(`\n    ==================\n    AGENDA CONTACTOS\n    ==================\n    ______________________________________________\n    \n    Qué acción quieres realizar? (teclear el número) \n    \n    Buscar (1) \n    Inserir (2)\n    Actualizar (3)\n    Mostar (4)\n    Eliminar (5) \n    Salir (6)\n    ______________________________________________`);\n\n  switch (accion) {\n    case \"1\": // Buscar\n      const buscarNombre = prompt(\"Escribe el nombre del contacto a buscar.\");\n      if (buscarNombre) {\n        miListaContactos.buscar(buscarNombre);\n      }\n      break;\n    case \"2\": // Inserir\n      const inserirNombre = prompt(\"Escribe el nombre\");\n      const inserirTelefono: any = prompt(\"Escribe el telefono (max 11 números)\");\n\n      // Validación todo números\n      const regExp = /[a-z A-Z]/;\n      const tieneLetras = regExp.test(inserirTelefono.toString());\n\n      // Validación cantidad caracteres\n      let tieneMas = false;\n      if (inserirTelefono.length >= 11) {\n        tieneMas = true;\n      } else {\n        tieneMas = false;\n      }\n\n      if (inserirNombre && inserirTelefono && !tieneLetras && tieneMas === false) {\n        miListaContactos.inserir(inserirNombre, parseInt(inserirTelefono));\n      } else {\n        console.log(`El contacto ${inserirNombre}, no se ha podido inserir correctamente.`);\n      }\n      break;\n    case \"3\": // Actualizar\n      const contactoActualizar = prompt(\"Escribe el nombre del contacto a buscar.\");\n      const telefonoActualizar = prompt(\"Escribe el nuevo telefono.\");\n      if (contactoActualizar && telefonoActualizar) {\n        miListaContactos.actualizar(contactoActualizar, parseInt(telefonoActualizar));\n      } else {\n        console.log(`Por falta de datos, el contacto ${contactoActualizar} no se ha podido actualizar.`);\n      }\n      break;\n\n    case \"4\": // Mostrar\n      miListaContactos.mostrarContactos();\n      break;\n\n    case \"5\": // Eliminar\n      const contactoEliminar = prompt(\"Escribe el nombre del contacto a eliminar.\");\n      if (contactoEliminar) {\n        miListaContactos.eliminar(contactoEliminar);\n      } else {\n        console.log(\"No has escrito ningun nombre.\");\n      }\n      break;\n\n    case \"6\": // Salir\n      salirContactos = true;\n      console.log(\"Saliste de la Agenda de Contactos, hasta pronto!\");\n      break;\n\n    default:\n      console.log(\"Hola seleccione un número de acción a realizar!\");\n      break;\n  }\n}\n\n/**\n * Recursos consultados:\n *\n *  - https://www.freecodecamp.org/news/data-structures-in-javascript-with-examples/\n *  - https://www.youtube.com/watch?v=yxqBvC6YMgA\n *\n */\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/typescript/Igledev.ts",
    "content": "// 1º Ejemplos de creación de todas las estructuras soportadas.\n// En TypeScript hay tanto estructuras de datos como de tipos, vamos a verlos!\n    // -- Boolean\n    let dev: boolean = true;\n    // -- Number\n    let decimal : number = 6;\n    let hexadecimal : number = 0xf35d;\n    let binario : number = 0o1010;\n    let octal : number = 0o272;\n    // -- String\n    let username : string = 'IgleDev';\n    // -- Array\n    let notas : number[] = [9, 4, 8, 5];\n    let frutas : Array<string> = ['manzana', 'kiwi', 'platano'];\n    // -- Tupla\n    let nombreEdad : [string, number];\n    nombreEdad = ['Igledev', 19]; // Si hicieramos 'x = [10, \"hello\"];' daría error.\n    // -- Enum\n    enum Color{Rojo, Verde, Azul}\n    let color : Color = Color.Rojo;\n    // -- Any\n    let gatos : any = 4;\n    // -- Void\n    function gustar() : void {\n        console.log('Me gusta TypeScript!');\n    }\n    // -- Undefined\n    let sin_definir : undefined = undefined;\n    // -- Null\n    let vacio : null = null;\n    // -- Never\n    function error(mensaje_error: string): never {\n        throw new Error(mensaje_error);\n    }\n    // -- Objeto\n    let obj : object = { Igledev: 'Programador Web' };\n    // -- Union Type\n    let estado : number | string;\n    estado = 10;\n    estado = 'Con muchas ganas';\n    //Intersection Type\n    interface Programador {\n        nombre : string;\n    }\n    \n    interface Tecnologia {\n        lenguaje : string;\n    }\n    \n    let coder : Programador & Tecnologia = {\n        nombre: 'Igledev',\n        lenguaje: 'TypeScript',\n    };\n// 2º Operaciones de inserción, borrado, actualización y ordenación.\n    // -- Insercción\n    let numeros_favoritos : number[] = [];\n\n        // -- Insertar al final\n        numeros_favoritos.push(8);\n\n        // -- Insertar al principio\n        numeros_favoritos.unshift(5);\n\n        // -- Insertar en una posición específica\n        numeros_favoritos.splice(1,0,4);\n        // Nos saldría el 4 en la mitad de los números: 5/4/8\n\n    // -- Lo mostramos\n    console.log('Array utilizando insercción' + numeros_favoritos);\n\n    // -- Borrado\n        // Borra el final\n        numeros_favoritos.pop();\n\n        // Borra el principio\n        numeros_favoritos.shift();\n\n        // Borra una posición específica\n        numeros_favoritos.splice(2, 1);\n        // Nos quedaríamos solo con 4\n\n    // -- Lo mostramos\n    console.log(\"Array después del borrado:\" + numeros_favoritos);\n\n    // -- Actualizar\n        numeros_favoritos[1] = 10;\n\n    // -- Lo mostramos\n    console.log(\"Array después de la actualización:\" + numeros_favoritos);\n\n    // -- Ordenacion\n    // Tenemos 2 tipos\n        // -- Numérica\n            let notas_desordenadas : number[] = [9,4,8,2,5,6];\n\n            // -- De forma Ascendente\n            let notas_ascendentes : number[] = notas_desordenadas.slice().sort((a,b) => a - b);\n                // El Slice sin pasarle argumentos nos devuelve una copia del Array original\n                /**El argumento que se pasa a sort() es una función de comparación. \n                 * La función (a, b) => a - b indica que los elementos se deben ordenar de manera ascendente. \n                 * Si el resultado de la resta a - b es negativo, significa que a es menor que b, \n                 * por lo que a debe ir primero \n                 *\n                */\n\n            // -- De forma Descendente\n            let notas_descendentes : number[] = notas_desordenadas.slice().sort((a, b) => b - a);\n        \n        // -- Las mostramos\n        console.log('Array sin modificaciones: ' + notas_desordenadas);\n        console.log('Array con las notas ascendentes: ' + notas_ascendentes);\n        console.log('Array con las notas descendentes: ' + notas_descendentes);\n\n        // -- String\n            let tecnologias_desordenadas : string[] = ['TypeScript' , 'JavaScript' , 'Git' , 'Angular' , 'HTML'];\n\n            // Ordenar alfabéticamente\n            let tecnologias_ordenadas: string[] = tecnologias_desordenadas.slice().sort();\n        // -- Las mostramos\n        console.log('Array original: ' + tecnologias_desordenadas);\n        console.log('Array ordenado alfabéticamente: ' + tecnologias_ordenadas);\n\n// 3º Ejercicio Extra\n// Definimos un tipo para los contactos\ntype Contactos = {\n    nombre: string;\n    telefono: string;\n};\n\nlet salir = false;\nconst agenda : Contactos[] = [];\n\nwhile(salir == false){\n    console.log(\"\\nOperaciones disponibles:\");\n    console.log(\"1. Buscar contacto\");\n    console.log(\"2. Insertar contacto\");\n    console.log(\"3. Actualizar contacto\");\n    console.log(\"4. Eliminar contacto\");\n    console.log(\"5. Salir\");\n\n    let opcion : string = prompt('Elija que quiere hacer') as string;\n\n    switch(opcion){\n        case '1':\n            let nombreUsuario = prompt('Ingresa el nombre del Usuario');\n            let encontrado = agenda.find(c => c.nombre === nombreUsuario);\n\n            if(encontrado){\n                console.log('Nombre: ' + encontrado.nombre + ' - Teléfono: ' + encontrado.telefono);\n            }else{\n                console.log('Usuario no encontrado');\n            }\n        break;\n        case '2':\n            let nombre = prompt('Ingresa el nombre del nuevo contacto') as string;\n            let telefono = '';\n\n            while(!/^\\d+$/.test(telefono) || telefono.length > 11){\n                telefono = prompt('Ingrese el número de teléfono del contacto: ') as string;\n                if(!/^\\d+$/.test(telefono) || telefono.length > 11){\n                    console.log(\"Número de teléfono no válido. Debe contener dígitos y tener 11 dígitos.\");\n                }\n            }\n\n            agenda.push({nombre , telefono});\n            console.log('Contacto Agreado');\n        break;\n        case '3':\n            let nombreActulizado = prompt(\"Ingrese el nombre del contacto que desea actualizar: \");\n            let nContacto = agenda.findIndex(c => c.nombre === nombreActulizado);\n          \n            if (nContacto !== -1) {\n                let nTelefono = '';\n          \n                while (!/^\\d+$/.test(nTelefono) || nTelefono.length > 11) {\n                    nTelefono = prompt(\"Ingrese el nuevo número de teléfono: \") as string;\n                    if (!/^\\d+$/.test(nTelefono) || nTelefono.length > 11) {\n                      console.log(\"Número de teléfono no válido. Debe contener solo dígitos y tener como máximo 11 dígitos.\");\n                    }\n                }\n          \n              agenda[nContacto].telefono = nTelefono;\n              console.log(\"Contacto actualizado correctamente.\");\n            } else {\n              console.log(\"Contacto no encontrado.\");\n            }\n\n        break;\n        case '4':\n            let nombreBorrar = prompt(\"Ingrese el nombre del contacto que desea eliminar: \");\n            let nContactoBorrar = agenda.findIndex(c => c.nombre === nombreBorrar);\n          \n            if (nContactoBorrar !== -1) {\n              // Eliminamos el contacto del array\n              agenda.splice(nContactoBorrar, 1);\n              console.log(\"Contacto eliminado correctamente.\");\n            } else {\n              console.log(\"Contacto no encontrado.\");\n            }\n\n        break;\n        case '5':\n            console.log('Un placer haberte servido de ayuda');\n            salir = true;\n\n        break;\n        default:\n            console.log('Te equivocaste de numero')\n    }\n}"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/typescript/RicJDev.ts",
    "content": "//EJERCICIO\n//ARRAYS\nconst arr1: number[] = [23, 10, 20, 40, 12];\n\ninterface Car {\n\tmodel: string;\n\tyear: number;\n\tprice: number;\n}\n\nconst someCarsModels: Car[] = [\n\t{\n\t\tmodel: 'Honda Civic',\n\t\tyear: 2012,\n\t\tprice: 10100,\n\t},\n\t{\n\t\tmodel: 'Toyota Corolla',\n\t\tyear: 2010,\n\t\tprice: 10200,\n\t},\n\t{\n\t\tmodel: 'Nissan Centra',\n\t\tyear: 2012,\n\t\tprice: 20300,\n\t},\n];\n\n//Inserción\nsomeCarsModels.push({\n\tmodel: 'Chevrolet Aveo',\n\tyear: 2010,\n\tprice: 11300,\n});\n\nsomeCarsModels.unshift({\n\tmodel: 'Honda Fit',\n\tyear: 2010,\n\tprice: 14300,\n});\n\nlet carToSplice: Car = {\n\tmodel: 'Peugeot 208',\n\tyear: 2019,\n\tprice: 19800,\n};\n\nsomeCarsModels.splice(2, 0, carToSplice);\n\n//Búsqueda\nlet includesResult = someCarsModels.includes(carToSplice);\nconsole.log('El elemento existe dentro del array?', includesResult);\n\nlet index = someCarsModels.indexOf(carToSplice);\nconsole.log(someCarsModels[index]);\n\nlet findResult = someCarsModels.find((car) => {\n\treturn car.model == 'Toyota Corolla';\n});\nconsole.log(findResult);\n\nindex = someCarsModels.findIndex((car) => {\n\treturn car.model == 'Chevrolet Aveo';\n});\nconsole.log(someCarsModels[index]);\n\n//Actualización\nsomeCarsModels[index] = {\n\tmodel: 'Toyota Yaris',\n\tyear: 2017,\n\tprice: 18800,\n};\n\nconsole.log(someCarsModels[index]);\n\n//Eliminación\nsomeCarsModels.pop();\nsomeCarsModels.shift();\nsomeCarsModels.splice(2, 1);\nsomeCarsModels.length = 0;\n\nconsole.log(someCarsModels);\n\n//Otros\narr1.sort((a, b) => {\n\treturn b - a;\n});\nconsole.log(arr1);\n\n//OBJETOS\nconst obj1 = {\n\tkey: 'value',\n};\n\n//Inserción\ntype dinamicKeysValuesObj = { [key: string]: number | object };\n\nconst obj2: dinamicKeysValuesObj = {\n\tid: 102,\n};\n\nobj2.user = {\n\tname: 'Ric',\n\tage: 21,\n};\nconsole.log(obj2);\n\n//Búsqueda\nconsole.log(obj2.user);\n\n//Actualización\nobj2.user = {\n\tname: 'Joshua',\n\tage: 19,\n};\nconsole.log(obj2);\n\n//Eliminación\ndelete obj2.user;\n\nconsole.log(obj2);\n\n//SETS\nconst mySet = new Set(arr1);\nconsole.log(mySet);\n\n//Inserción\nmySet.add(22);\nconsole.log(mySet);\n\n//Búsqueda\nlet names: Set<string> = new Set(['Joe', 'Jill', 'Steve']);\n\nlet setHasResult = names.has('Jill');\nconsole.log('El elemento existe dentro del set?', setHasResult);\n\n//Actualización\nconst namesArr = Array.from(names);\nnamesArr[1] = 'Juan';\n\nnames = new Set(namesArr);\n\n//Eliminación\nnames.delete('Juan');\nmySet.clear();\nconsole.log(mySet, names);\n\n//MAPS\nconst myMap = new Map([\n\t['key1', 'value1'],\n\t['key2', 'value2'],\n]);\n\nconsole.log(myMap);\n\n//Inserción\nmyMap.set('key3', 'value3');\n\nconsole.log(myMap);\n\n//Búsqueda\nconst mapValue = myMap.get('key1');\n\nconsole.log(mapValue);\n\n//Actualización\nmyMap.set('key3', 'value3');\n\n//Eliminación\nmyMap.delete('key2');\n\nconsole.log(myMap);\n\n//EXTRA\nimport * as readline from 'readline';\n\nconst rl = readline.createInterface({\n\tinput: process.stdin,\n\toutput: process.stdout,\n});\n\nconst contacts = new Map();\nconst phoneRegex = /(\\d{4})\\-(\\d{7})/;\n\nfunction addContact() {\n\tconsole.log('\\nAGREGAR CONTACTO');\n\n\trl.question('Nombre del contacto? ', (name) => {\n\t\tif (contacts.has(name)) {\n\t\t\tconsole.log('El contacto ya ha sido registrado');\n\n\t\t\tmenu();\n\t\t} else {\n\t\t\trl.question('Número de teléfono del contacto? ', (phone) => {\n\t\t\t\tif (phoneRegex.test(phone)) {\n\t\t\t\t\tcontacts.set(name, phone);\n\t\t\t\t\tconsole.log('Contacto registrado exitosamente!');\n\t\t\t\t} else {\n\t\t\t\t\tconsole.log('Formato inválido. Por favor seguir el formato 0000-0000000');\n\t\t\t\t}\n\n\t\t\t\tmenu();\n\t\t\t});\n\t\t}\n\t});\n}\n\nfunction updateContact() {\n\tconsole.log('\\nACTUALIZAR CONTACTO');\n\n\trl.question('Nombre del contacto? ', (name) => {\n\t\tif (contacts.has(name)) {\n\t\t\trl.question('Nuevo número de teléfono del contacto? ', (phone) => {\n\t\t\t\tif (phoneRegex.test(phone)) {\n\t\t\t\t\tcontacts.set(name, phone);\n\t\t\t\t\tconsole.log('Contacto actualizado exitosamente!');\n\t\t\t\t} else {\n\t\t\t\t\tconsole.log('Formato inválido. Por favor seguir el formato 0000-0000000');\n\t\t\t\t}\n\n\t\t\t\tmenu();\n\t\t\t});\n\t\t} else {\n\t\t\tconsole.log('No existe ese contacto');\n\n\t\t\tmenu();\n\t\t}\n\t});\n}\n\nfunction searchContact() {\n\tconsole.log('\\nBUSCAR CONTACTO');\n\n\trl.question('Nombre del contacto? ', (name) => {\n\t\tif (contacts.has(name)) {\n\t\t\tlet phone = contacts.get(name);\n\t\t\tconsole.log(`findResultado: ${name}, ${phone}`);\n\t\t} else {\n\t\t\tconsole.log('Contacto no registrado');\n\t\t}\n\n\t\tmenu();\n\t});\n}\n\nfunction deleteContact() {\n\tconsole.log('\\nELIMINAR CONTACTO');\n\n\trl.question('Nombre del contacto? ', (name) => {\n\t\tif (contacts.has(name)) {\n\t\t\tcontacts.delete(name);\n\t\t\tconsole.log('Contacto eliminado exitosamente!');\n\t\t} else {\n\t\t\tconsole.log('Contacto no registrado');\n\t\t}\n\n\t\tmenu();\n\t});\n}\n\nfunction getContactsList() {\n\tconsole.log('\\nLISTA DE CONTACTOS:');\n\n\tif (contacts.size > 0) {\n\t\tcontacts.forEach((phone, name) => {\n\t\t\tconsole.log(`- ${name}: ${phone}`);\n\t\t});\n\t} else {\n\t\tconsole.log('No hay registros');\n\t}\n\n\tmenu();\n}\n\nfunction exit() {\n\tconsole.log('\\nSaliendo de la app...');\n\trl.close();\n}\n\nfunction menu() {\n\tconsole.log('\\nAGENDA DE CONTACTOS');\n\n\tconst optionMethods = new Map([\n\t\t['1', addContact],\n\t\t['2', updateContact],\n\t\t['3', searchContact],\n\t\t['4', deleteContact],\n\t\t['5', getContactsList],\n\t\t['6', exit],\n\t]);\n\n\tconsole.log(\n\t\t'1. Agregar contacto\\n2. Actualizar contacto\\n3. Buscar contacto\\n4. Eliminar contacto\\n5. Listar contactos\\n6. Salir'\n\t);\n\n\trl.question('Elija una opción (1 - 6) ', (option) => {\n\t\tconst method = optionMethods.get(option) || menu;\n\n\t\tmethod();\n\t});\n}\n\nmenu();\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/typescript/RobertoAmaroHub.ts",
    "content": "import * as readline from 'readline';\n\n/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n**/\nfunction printArray(array: any[],text?:string){\n    if(text){\n        console.log(\"\\n\"+text);\n    }\n    for(let i of array){\n        console.log(i);\n    }\n}\n//**************Arrays************************\nlet animales: string[] = [\"Perro\",\"Gato\",\"Pez\"]\nprintArray(animales);\n//Agregar un elemento utilizando push -> Te permite agregar un elemento al final del array.\nanimales.push(\"Cocodrilo\");\nprintArray(animales, \"nuevo dato agregado:\");\n\n//Acceder a un elemento\nlet primerAnimal: string=animales[0];\nconsole.log(\"\\n\"+primerAnimal);\n\n//Saber la longitud del array\nconsole.log(`\\ntotal de elementos en el array: ${animales.length}`) //Imprimirá cuantas cadenas de texto que hay dentro del array\n\n//Modificar contenido\nanimales[animales.length-1] = \"Castor\"\nprintArray(animales,\"Último elemento modificado:\")\n\n//Readonly -Previene que el array sea editado después de haber sido creado e inicializado. Evitando así problemas futuros en la estructura del programa por modificaciones indebidas.\nlet ints: readonly number[]=[3,2,1];\n//ints.push(2); //Error: Property \"push\" does not exist on type \"readonly number[]\".\n\n//Eliminar elemento utilizando pop -> Te permite eliminar el último elemento que hay en el array.\nanimales.pop() //eliminamos al Castor que es el último elemento\nprintArray(animales,\"Último elemento eliminado:\")\n\n//Funciones disponibles de un array\n//Concat -Devolverá un array con los nuevos valores que le pasemos cómo parámetros a esta función. Dichos parámetros podrán ser un valor suelto u otra array con valores del mismo tipo de dato:\n//concat(value1, value2, value3, ..... , valueN);\nlet autos:string[]=[\"Civic\",\"Hilux\",\"F150\"];\nlet masAutos:string[]=[\"Corvette\",\"M3\",\"Oddysey\"];\nlet autosTotal=autos.concat(masAutos);\nprintArray(autosTotal,\"\\nLista de autos:\");\n\n//every -> Nos permite conocer, mediante una función dada que tiene que devolver un booleano, si todos los elementos del array pasan la prueba.\n//every(callback[, thisObject]);\nlet everyArray:number[]=[3,4,5,6,7,8];\nlet resEvery=everyArray.every((value)=>value>2); //Preguntamos si cada elemento dentro del array es mayor a 2\nconsole.log(`\\nel resultado de la prueba es: ${resEvery}`); //Para este caso la respuesta es true\n\n//filter -> Devolverá un array con el contenido que pase correctamente por la función de filtro. Dicha función de filtro tendrá el mismo funcionamiento que la función \"every\".\n//filter (callback[, thisObject]);\nlet filterArray:number[] = [23,4,6,72,1,100,3];\nlet resFilter = filterArray.filter((value)=>value%3==0);\nprintArray(resFilter,\"\\nNuevo arreglo filtrando solo multiplos de 3: \");\n\n//forEach -> Nos permite recorrer todos los índices de un array mediante una función callback. Dicha función tendrá como parámetro el valor del índice del array según se vaya ejecutando de manera secuencial.\n//forEach(callback[, thisObject]);\n//NOTA: Hay que tener especial cuidado con esto. Se ejecutará de manera asíncrona y no detendrá el flujo de ejecución de la aplicación a menos que nosotros se lo indiquemos explícitamente.\nlet forEachArray: number[]=[34,5,6,1,3,4,100];\nfunction printForEach(value:number){\n    console.log(value);\n}\nconsole.log(\"\\nValores del forEach:\");\nforEachArray.forEach(printForEach);\n\n//indexOf -> Nos devolverá el índice donde se encuentra el valor dado cómo parámetro. Devolverá -1 en caso de que no exista. El parámetro \"fromIndex\" nos permite definir desde que índice del array comenzar siendo 0 el valor por defecto:\n//indexOf(searchElement[, fromIndex]);\nlet indexOfArray:number[]=[34,5,22,66,2,1,9];\nconsole.log(\"\\nPosición del indexOfArray 22:\");\nfor(let i in indexOfArray){\n    console.log(`${i} : ${indexOfArray[i]}`);\n}\nconsole.log(indexOfArray.indexOf(22));\n\n//join -> Nos permite convertir el contenido del array en una cadena de texto con un separador que le daremos a la función como parámetro:\n//join(separator);\nlet joinArray:string[] = [\"Primero\", \"Segundo\", \"Tercero\"];\nconsole.log(\"\\nElementos de la función join:\")\nconsole.log(joinArray.join(\" / \"));\n\n//lastIndexOf -> Similar a indexOf pero comenzando por el final del array en dirección al comienzo de esta. Nos devolverá le número del índice donde se encuentra el valor dado como parámetro. \n//El parámetro \"fromIndex\" nos permite definir un offset desde donde comenzará a contar.\n//lastIndexOf(searchElement[, fromIndex]);\nlet lastIndexOfArray: number[] = [32,45,1,3,56,2];\nconsole.log(\"\\nLastIndexOf de 56:\")\nfor(let i in lastIndexOfArray){\n    console.log(`${i} : ${lastIndexOfArray[i]}`);\n}\nlet resLastIndexOf=lastIndexOfArray.lastIndexOf(56)\nconsole.log(resLastIndexOf);\n\n//map -> Devolverá un array con los valores que retorna la función dada cómo parámetro por cada uno de los elementos del array.\n//map(callback[, thisObject])\nlet mapArray:number[] = [2,46,72,2,1];\nprintArray(mapArray.map((value)=>(value*2)),\"mapArray valores por 2:\");\n\n//reduce -> Este método aplica una función simultáneamente contra dos valores de la matriz (de izquierda a derecha) para reducirla a un solo valor. El parámetro \"initalValue\" será el valor inicial al que se empezará a sumar.\n//reduce(callback[, initialValue]);\nlet reduceArray:number[] = [2,4,62,0,1];\nconsole.log(`reduce result: ${reduceArray.reduce((v1, v2)=>v1-v2)}`);\n\n//reduceRight -> Similar a \"reduce\" pero comenzará a reducir de derecha a izquierda.\n//reduceRight(callback[, initialValue]);\nlet reduceRightArray:number[] = [2,4,62,0,1];\nconsole.log(`reduceRight result: ${reduceRightArray.reduceRight((v1, v2)=>v1-v2)}`);\n\n//reverse -> Esta función devolverá una copia del array pero con los elementos al revés. El primero pasando a ser el último, y viceversa.\n//reverse();\nlet reverseArray:number[]=[1,2,3,4,5];\nprintArray(reverseArray.reverse(),\"Resultado del array en reversa:\");\n\n//shift -> Elimina el primer elemento del array.\n//shift();\nlet shiftArray:number[] = [3,2,1];\nconsole.log(`Elemento eliminado: ${shiftArray.shift()}`);\n\n//slice -> Nos permite extraer una porción del array en cuestión. El parámetro \"begin\" es el índice desde el que partirá y \"end\" donde terminará. Si \"end\" no existe la función devolverá desde \"begin\" hasta el final del array.\n//slice( begin [,end] );\nlet sliceArray:number[] = [4,3,1,3,5,6,4,6,78,9,0]\nprintArray(sliceArray.slice(8),\"Nuevo arreglo cortando desde el índice 8:\");\nprintArray(sliceArray.slice(3,8),\"Nuevo arreglo cortando desde el índice 3 hasta el 8:\");\n\n//some -> Nos permite conocer si alguno de los elementos del array pasa la prueba que le especificaremos en la función dada como parámetro.\n//some(callback[, thisObject]);\nlet someArray:number[] = [32,4,6,37,0,3]\nconsole.log(`el arreglo contiene el número 37: ${someArray.some((value)=>value==37)}`);\n\n//sort -> Nos permite ordenar un array mediante la comparación sobre una función dada.\n//sort( compareFunction );\n//Al no pasarle una función de ordenación, y ser cadenas de texto los valores, los ordenará alfabéticamente.\nlet sortArray:string[]=[\"zorro\",\"gato\",\"araña\",\"pavo\"];\nprintArray(sortArray.sort(),\"Ordenado alfabéticamente:\")\n\n//splice -> Nos permite modificar el contenido de los elementos de un array. Los nuevo elementos modificarán el valor de los antiguos elementos. \"Index\" será el índice desde donde comenzaremos a modificar, \"howMany\" cuantos elementos se modificarán a partir del index.\n//splice(index, howMany, [element1][, ..., elementN]);\nvar spliceArray = [\"orange\", \"mango\", \"banana\", \"sugar\", \"tea\"];  \nvar removed = spliceArray.splice(2, 0, \"water\");  \nconsole.log(\"\\nAfter adding 1: \" + spliceArray );  \nconsole.log(\"removed is: \" + removed); \n          \nremoved = spliceArray.splice(3, 1);  \nconsole.log(\"\\nAfter removing 1: \" + spliceArray );  \nconsole.log(\"removed is: \" + removed);\n\n//unshift -> Nos permite agregar uno, o más, elementos al comienzo del array y nos retornará la nueva longitud.\n//unshift( element1, element2, ..., elementN );\nlet unshiftArray:number[]=[3,4,5,2];\nlet resUnshift=unshiftArray.unshift(9);\nconsole.log(`\\n nueva longitud del array: ${resUnshift}`)\nprintArray(unshiftArray);\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\nvar prompt = require(\"prompt-sync\")();\n\nclass Contacto {\n    private _nombre: string;\n    private _telefono: number;\n\n    constructor(){\n        this._nombre=\"\";\n        this._telefono=0;\n    }\n\n    get nombre(): string {\n        return this._nombre;\n    }\n    set nombre(value: string) {\n       this._nombre=value;\n    }\n    \n    get telefono(): number{\n        return this._telefono;\n    }\n    set telefono(value: number){\n        this._telefono=value;\n    }\n    \n}\n\nlet contactos:Contacto[]=[];\nlet nuevoContacto= new Contacto();\nnuevoContacto.nombre=\"Roberto\";\nnuevoContacto.telefono=23244;\ncontactos.push(nuevoContacto);\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nlet optionsArray:string[]=[\"Buscar\",\"Insertar\", \"Actualizar\", \"Eliminar\", \"Cerrar Aplicación\"];\nfunction menuOpciones(value, i){\n    console.log(`[${i}] - ${value}`)\n}\n\nfunction respuestaIncorrecta(){\n    console.log('Respuesta incorrecta');\n    regresarAlMenu();\n}\n\nfunction regresarAlMenu(){\n    let answer=prompt(`\\n¿Desea regresar al menú principal? [Y/N]`)\n    if(answer.trim().toLocaleLowerCase()==\"n\"){\n        cerrarAplicacion();\n    } else if(answer.trim().toLocaleLowerCase()==\"y\"){\n        menuPrincipal();\n    } else {\n        respuestaIncorrecta();\n    }\n}\n\nfunction findContactByName(nombre:string):Contacto{\n    return contactos.find(contact=>contact.nombre.trim().toLocaleLowerCase().includes(nombre.trim().toLocaleLowerCase()));;\n}\n\nfunction buscarContacto(){\n    let res=prompt(`Escribe el nombre del contacto a buscar:`);\n    let _contacto=findContactByName(res);\n    if(_contacto){\n        console.log(`Datos del contacto, nombre: ${_contacto.nombre}, teléfono: ${_contacto.telefono}`)\n    } else {\n        console.log(`No fue posible encontrar al contacto \"${res}\".`)\n    }\n    regresarAlMenu();\n}\n\nfunction eliminarContacto(){\n    printArray(contactos, \"Contactos registrados:\")\n    let res = prompt(`Escribe el nombre del contacto a eliminar:`)\n    let _contacto=findContactByName(res);\n    if(_contacto){\n        contactos.splice(contactos.indexOf(_contacto),1);\n        console.log(`El contacto \"${_contacto.nombre}\" con número de telefono ${_contacto.telefono} fue eliminado con éxito`)\n        console.log(contactos);\n    } else {\n        console.log(`El contacto ${res} no se encuentra en la agenda`)\n    }\n    regresarAlMenu();\n}\n\nfunction modificarContacto(){\n    printArray(contactos, \"Contactos registrados:\")\n    let contactoModificar = prompt(`Escribe el nombre del contacto a modificar:`)\n    let nombre=prompt(\"Ingrese el nuevo nombre del contacto:\");\n    let numero=prompt(\"Ingrese el nuevo teléfono del contacto:\")\n    let _contacto=findContactByName(contactoModificar);\n    let _newCont: Contacto= validarContacto(nombre, numero);\n    if(_newCont!=null){\n        contactos[contactos.indexOf(_contacto)]=_newCont;\n        console.log(`Los datos del contacto \"${_contacto.nombre}\" fueron modificados`)\n        console.log(contactos);\n        regresarAlMenu();\n    } else {\n        modificarContacto();\n    }\n}\n\nfunction validarContacto(nombre:string, numero: number): Contacto{\n    let _cont: Contacto= new Contacto();\n    if(nombre.length>0){\n        _cont.nombre=nombre;\n    }else{\n        console.log(\"Nombre invalido, inténtelo de nuevo\")\n        return null;\n    }\n    if(isNaN(numero)){\n        console.log(\"El número de teléfono solo puede contener números sin espacios, inténtelo de nuevo\")\n        return null;\n    } else if(numero.toString().length>11){\n        console.log(\"El número de teléfono no puede ser mayor a 11 dígitos, inténtelo de nuevo\")\n        return null;\n    } else {\n        _cont.telefono=+numero;\n    }\n    return _cont;\n}\n\nfunction agregarContacto(){\n    let _cont:Contacto= new Contacto();\n    let nombre=prompt(\"Ingrese el nombre del contacto:\");\n    let numero=prompt(\"Ingrese el teléfono del contacto:\")\n    _cont=validarContacto(nombre, numero);\n    if(_cont!=null){\n        let res=contactos.push(_cont);\n        console.log(contactos)\n        console.log(`Contacto agregado correctamente: ${contactos[res-1].nombre}, ${contactos[res-1].telefono}`);\n        regresarAlMenu();\n    } else {\n        agregarContacto();\n    }\n   \n}\n\nfunction menuPrincipal(){\n    console.log(\"\\n*********Agenda de contactos*********\");\noptionsArray.forEach(menuOpciones);\n    let answer = prompt(\"Elige el número de la opción que necesitas:\");\n        switch(answer) {\n        case \"0\":\n            console.log(\"\\n********Buscador de contactos*********\")\n            buscarContacto();\n            break;\n        case \"1\":\n            console.log(\"\\n********Agregar nuevo contacto*********\")\n            agregarContacto();\n            break;\n        case \"2\":\n            console.log(\"\\n********Modificar Contacto*********\")\n            modificarContacto();\n            break;\n        case \"3\":\n            console.log(\"\\n********Eliminar contacto*********\")\n            eliminarContacto();\n            break;\n        case \"4\":\n            console.log(\"\\n\")\n            cerrarAplicacion();\n            break;\n        default:\n            console.log(\"\\n\")\n            respuestaIncorrecta();\n        }\n}\nfunction cerrarAplicacion(){\n    console.log('Aplicación Finalizada');\n    rl.close();\n}\nmenuPrincipal();\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/typescript/Sac-Corts.ts",
    "content": "// *** Arrays *** //\n// Creation\nlet numbers: number[] = [5, 2, 1, 8, 3];\n\n// Insertion\nnumbers.push(7);\nnumbers.splice(2, 0, 6)\n\n// Erased\nnumbers.pop();\nnumbers.splice(2, 1);\n\n// Update\nnumbers[1] = 9;\n\n// Sort\nnumbers.sort((a, b) => a - b);\nconsole.log(numbers);\n\n// *** Objects *** //\n// Creation\ntype Person = {name: string, age?: number, email? : string}\nlet person: Person = { name: \"Isaac\", age: 22 }; \n\n// Insertion\nperson.email = \"isaac@gmail.com\";\n\n// Erased \ndelete person.age;\n\n// Update\nperson.name = \"Geovanni\";\nconsole.log(person);\n\n// *** Sets *** //\n// Creation \nlet numbersSet: Set<number> = new Set([1, 2, 3, 4]);\n\n// Insertion\nnumbersSet.add(5);\n\n// Erased\nnumbersSet.delete(2);\n\n// Update\n// There is no direct operation to update a value in a Set,\n// the old one must be removed and the new one added.\nnumbersSet.delete(4);\nnumbersSet.add(0);\n\n// Sort\nlet sortedNumbersSet = new Set([...numbersSet].sort((a, b) => a - b));\nconsole.log(numbersSet);\nconsole.log(sortedNumbersSet);\n\n// *** Maps *** //\n// Creation\nlet map: Map<string, number> = new Map([[\"a\", 1], [\"b\", 2]]);\n\n// Insertion\nmap.set(\"c\", 3);\n\n// Erased \nmap.delete(\"b\");\n\n// Update \nmap.set(\"a\", 10);\n\n// Sort\nlet sortedMap = new Map([...map.entries()].sort((a, b) => a[1] - b[1]));\nconsole.log(map);\nconsole.log(sortedMap);\n\n// *** Extra Exercise *** //\nimport * as readline from 'readline';\n\ninterface Contact {\n    name: string;\n    phone: string;\n}\n\nconst contacts: Contact[] = [];\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nfunction prompt(question: string): Promise<string> {\n    return new Promise((resolve) => rl.question(question, resolve));\n}\n\nfunction isValidPhone(phone: string): boolean {\n    return /^\\d{1,11}$/.test(phone);\n}\n\nasync function main() {\n    while (true) {\n        console.log('\\nContact book');\n        console.log('1. Search contact');\n        console.log('2. Add contact');\n        console.log('3. Update contact');\n        console.log('4. Delete contact');\n        console.log('5. Exit');\n\n        const choice = await prompt('Choose an option: ');\n\n        switch (choice) {\n            case '1':\n                await searchContact();\n                break;\n            case '2':\n                await addContact();\n                break;\n            case '3':\n                await updateContact();\n                break;\n            case '4':\n                await deleteContact();\n                break;\n            case '5':\n                console.log('Leaving the program...');\n                rl.close();\n                return;\n            default:\n                console.log('Invalid option');\n                break;\n        }\n    }\n}\n\nasync function searchContact() {\n    const name = await prompt(\"Enter the name of the contact to search: \");\n    const contact = contacts.find(c => c.name === name);\n    if (contact) {\n        console.log(`Name: ${contact.name}, Phone: ${contact.phone}`);\n    } else {\n        console.log(\"Contact not found\");\n    }\n}\n\nasync function addContact() {\n    const name = await prompt(\"Enter the name of the new contact: \");\n    const phone = await prompt(\"Enter the phone (max 11 digits): \");\n\n    if (!isValidPhone(phone)) {\n        console.log(\"Invalid phone number, please try again\");\n        return;\n    }\n\n    contacts.push({ name, phone });\n    console.log(\"Contact added\");\n}\n\nasync function updateContact() {\n    const name = await prompt(\"Enter the name of the contact to update: \");\n    const contact = contacts.find(c => c.name === name);\n    \n    if (!contact) {\n        console.log(\"Contact not found\");\n        return;\n    }\n\n    const newPhone = await prompt(\"Enter the new phone number (max 11 digits): \");\n\n    if (!isValidPhone(newPhone)) {\n        console.log(\"Invalid phone number, please try again\");\n        return;\n    }\n\n    contact.phone = newPhone;\n    console.log(\"Contact updated\");\n}\n\nasync function deleteContact() {\n    const name = await prompt(\"Enter the name of the contact to delete: \");\n    const index = contacts.findIndex(c => c.name === name);\n\n    if (index === -1) {\n        console.log(\"Contact not found\");\n        return;\n    }\n\n    contacts.splice(index, 1);\n    console.log(\"Contact deleted\");\n}\n\nmain().catch(err => console.error(err));"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/typescript/Sharah07.ts",
    "content": "// *** ESTRUCTURAS DE DATOS EN TYPESCRIPT\n\n\n// Array: Es una colección ordenada de elementos, puede almacenar cualquier tipo de datos.\nlet persona : (number | string)[] = ['Sharah', 22, 'Hola!'];\nlet numeros = [5, 3, 6, 1];\n\nnumeros.push(8);\nnumeros.splice(2, 0, 7); //Inserción.\nnumeros[2] = 3; //Actualización.\nnumeros[2]; //Acceder\nnumeros.splice(2, 1); //Eliminación.\nnumeros.sort((a,b)=> a - b); //Ordenación.\n\n//Tuplas: son como arrays con un número fijo de elementos y tipos específicos de datos.\nlet miTupla: [string, number];\nmiTupla=[\"Sharah\", 19];\nconsole.log(miTupla[1]); //acceder\nmiTupla[1]= 20; //actualizar\n\n/** Objetos: Sirve para almacenar y organizar datos como pares clave-valor.\n *  Los objetos son una colección de datos (propiedades) y/o comportamientos (métodos),\n * cada propiedad de un objeto tiene un nombre (clave) y un valor.\n * ( Los métodos son como propiedades que albergan una función como valor, en lugar de contacto. )\n */\nconst personaSaludar = {\n    nombre: 'Sharah',\n    edad: 20,\n    saludar: function(){\n        console.log('Hola, ',this.nombre,'!');\n    }\n};\n//Objetos anidados. Son objetos que contienen más objetos.\n//(Básicamente estos objetos tienen propiedades que contienen más propiedades.) \nconst infoPersona ={\n    nombre: 'Sharah',\n    edad: 20,\n    ubicacion:{\n        pais: 'Colombia',\n        departamento: 'Valle de Cauca'\n    }\n}\ninfoPersona['email'] = 'sharah@gmail'; //Inserción.\ninfoPersona.ubicacion.departamento = 'Valle Del Cauca'; //Actualización.\ndelete infoPersona.email; //Eliminación.\n\n/** Mapas: Son colecciones de datos clave-valor, a diferencia de los objetos estos permiten cualquier tipo de dato\n *  como clave(incluyendo objetos) y mantienen el orden de inserción de las claves.\n *  Las claves no pueden repetirse. \n */\n\nlet miMapa = new Map<string, number>();\nmiMapa.set(\"Sharah\", 20); //Insertar\nmiMapa.set(\"Juan\", 31);\nmiMapa.set(\"Sofia\", 26); \nconsole.log(miMapa.get(\"Sofia\")); //Acceder\nconsole.log(miMapa.has(\"julia\")); //verificar si existe\nmiMapa.delete(\"Sofia\"); //eliminar\nmiMapa.set(\"Juan\", 32); //actualizar\n//mapa inicializado con valores usando un Array de Tuplas\nlet miMapa2 =new Map([\n    [\"Julia\", 32],\n    [\"David\", 27],\n    [\"Oscar\", 22]\n]);\n\n/** Sets: Permiten almacenar una colección de valores únicos.\n * Los valores no pueden repetirse, permite cualquier tipo de datos y mantiene el orden de inserción.\n */\n\nconst miSet = new Set<number>([2,8,4]);\nmiSet.add(5).add(7).add(9); //Insertar valores\nmiSet.delete(5) //Eliminación.\nconsole.log(miSet.has(7)); //verificar existencia\nlet setOrdenado = new Set([... miSet].sort((a,b)=> a-b));// ordenar(hay q convertirlo en array)\nlet nuevoSet = new Set(setOrdenado);\nconsole.log(nuevoSet);\n//Actualización:(No se puede actualizar directamente un set. Eliminas un elemento y agregas el otro.)\n\n//Extra\n\nfunction miAgenda(){\n    \n    const readline = require(\"readline\");\n    \n    process.stdin.resume();\n    const rl = readline.createInterface({\n        input: process.stdin,\n        output: process.stdout\n    });\n    rl.on(\"SIGINT\", () => {\n        console.log(\"\\nInterrupción detectada. Cerrando el programa...\");\n        rl.close();\n        process.exit(0);\n      });\n    const agenda = new Map();\n    function preguntarAccion(){\n        rl.question('Desea salir del programa?', (salir) =>{\n            const salir2 = salir.normalize(\"NFD\").replace(/[\\u0300-\\u036f]/g, \"\");\n            if(salir2.toLowerCase() == 'si'){\n                console.log('Cerrando programa...');\n                return rl.close();\n                \n            }\n            console.log('1. Añadir contacto.');\n            console.log('2. Buscar contacto.');\n            console.log('3. Actualizar contacto.');\n            console.log('4. Eliminar contacto.');\n            console.log('5. Ver agenda.');\n        \n            rl.question(\"Qué acción desea realizar? \", (accionRealizar) => {\n                const valorRecibido = parseInt(accionRealizar)\n                switch(valorRecibido){\n                    case 1:\n                        rl.question('Ingrese el nombre:', (nombre) => {\n                            rl.question('Ingrese el número:', (numero) =>{\n                                const esNumero = parseInt(numero);\n                                if(isNaN(esNumero) || numero.length > 11){\n                                console.log('Información no valida');\n                                return preguntarAccion();\n                                }\n                                agenda.set(nombre, esNumero);\n                                console.log('contacto añadido');\n                                preguntarAccion();\n                            });\n                        }); \n                        break;\n                    case 2:\n                        rl.question('Ingrese el nombre que desea buscar.', (buscar) =>{\n                            if(agenda.has(buscar)){\n                                console.log('nombre: ' + buscar + ', número: '+ agenda.get(buscar));\n                                preguntarAccion();\n\n                            }else{\n                                console.log('contacto no encontrado');\n                                preguntarAccion();\n                            }\n                        });\n                        break;\n                    case 3:\n                        rl.question('Ingrese el nombre del contacto a actualizar.', (actualizar)=>{\n                            agenda.delete(actualizar)\n                            rl.question('Ingrese nueva información, nombre:', (nuevoNombre)=>{\n                                rl.question('número:', (nuevoNumero)=>{\n                                    const esNumero = parseInt(nuevoNumero);\n                                    if(isNaN(esNumero) || nuevoNumero.length > 11 ){\n                                    console.log('Información no valida');\n                                    preguntarAccion(); \n                                    }\n                                    agenda.set(nuevoNombre, esNumero);\n                                    console.log('contacto actualizado')\n                                    preguntarAccion();\n                                   \n\n                                } );\n                            });\n                        });\n                        break;\n                    case 4:\n                        rl.question('Ingrese el nombre que desea eliminar.', (eliminar)=>{\n                            agenda.delete(eliminar);\n                            console.log('contacto eliminado.')\n                            preguntarAccion();\n                        });\n                        break;\n                    case 5:\n                        console.log(agenda);\n                        preguntarAccion();\n                        break;\n                    default:\n                        console.log('valor incorrecto.');\n                        preguntarAccion();\n                        break;\n                }\n                \n                \n            });\n        })\n    }   \n    preguntarAccion();\n}\n\nmiAgenda();"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/typescript/Sniker1223.ts",
    "content": "/**\n\n\n//Array\nlet numbers: number[] = [5, 3, 9, 1];\nconsole.log(numbers);\nnumbers.push(7); // Insert\nconsole.log(numbers);\nnumbers.splice(1, 1);//Delete\nconsole.log(numbers);\nnumbers[2] = 10;//update\nconsole.log(numbers);\nnumbers.sort((a, b) => a - b);//sort\nconsole.log(numbers);\n\n//Tuples\nlet person: [String, number] = ['Alice', 25];\nconsole.log(person);\nperson = ['Bob', 30]; //Not possible, only assign\nconsole.log(person);\nperson[1] = 35; //Update\nconsole.log(person);\n// Detele is not permitted and sort is not common\n\n//Sets\nlet uniqueNumbers: Set<number> = new Set([3, 1, 4]);\nconsole.log(uniqueNumbers);\nuniqueNumbers.add(2); //Insert\nconsole.log(uniqueNumbers);\nuniqueNumbers.delete(3); //Delete\nconsole.log(uniqueNumbers);\nuniqueNumbers.delete(4);// There's not update directly, first delete and then add.\nuniqueNumbers.add(5);\nconsole.log(uniqueNumbers);\n\n//Maps\nlet userAge: Map<String, number> = new Map([\n  ['Richard', 50],\n  ['Alice', 25],\n  ['Bob', 25]\n]);\nconsole.log(userAge);\nuserAge.set('Charlie', 35); //Insert\nconsole.log(userAge);\nuserAge.delete('Bob'); //Delete\nconsole.log(userAge);\nuserAge.set('Alice', 26); //Update\nconsole.log(userAge);\nlet sortedUsers = Array.from(userAge.entries()).sort((a, b) => a[1] - b[1]);// Convert to Array then sort by age\nconsole.log(sortedUsers);\n\n//Objects\nlet personInfo: { [key: string]: any } = {\n  name: 'Alice',\n  age: 25\n};\nconsole.log(personInfo);\npersonInfo.city = 'New York'; //Insert\nconsole.log(personInfo);\ndelete personInfo.age; //Delete\nconsole.log(personInfo);\npersonInfo.name = 'Bob'; //Update\nconsole.log(personInfo);\nlet sortedKeys = Object.keys(personInfo).sort(); //Convert to Array then sort \nconsole.log(sortedKeys);\n\n//Readonly Arrays\nlet readonlyNumbers: readonly number[] = [1, 2, 3];\nconsole.log(readonlyNumbers);\n//Try to update, insert, delete can generate an error\n\n//Readonly Tuples\nlet readonlyPerson: readonly [String, number] = ['Alice', 25];\nconsole.log(readonlyPerson);\n//Try to update, insert, delete can generate an error\n\n//Enums\nenum Color {\n  Red = 1,\n  Green,\n  Blue\n}\nconsole.log(Color);\nlet c: Color = Color.Green; //Access\nconsole.log(c);\n//Try to update, insert, delete, sort can generate an error\n \n\n*/\n\n// Extra\nimport * as readline from 'readline';\n\ntype Contact = {\n  name: string,\n  phone: string\n};\n\nclass ContactAgenda {\n  private contacts: Contact[] = [];\n\n  validatePhone(phone: string): boolean {\n    const phoneRegex = /^\\d{1,11}$/;\n    return phoneRegex.test(phone);\n  }\n\n  addContact(name: string, phone: string): void {\n    if (this.validatePhone(phone)) {\n      this.contacts.push({ name, phone });\n      console.log(\"Added successfully.\");\n    } else {\n      console.log(\"Phone is not valid. Phone must contain only numbers and have 11 digits.\");\n    }\n  }\n\n  searchContact(name: string): void {\n    const result = this.contacts.filter(contact => contact.name.toLowerCase() === name.toLowerCase());\n    if (result.length > 0) {\n      console.log(\"Contacts found.\");\n      result.forEach(contact => console.log(`Name: ${contact.name}, Phone: ${contact.phone}`));\n    } else {\n      console.log(\"Contacts not found.\")\n    }\n  }\n\n  updateContact(name: string, newPhone: string): void {\n    const contact = this.contacts.find(contact => contact.name.toLowerCase() === name.toLowerCase());\n    if (contact) {\n      if (this.validatePhone(newPhone)) {\n        contact.phone = newPhone;\n        console.log(\"Phone updated successfully.\");\n      } else {\n        console.log(\"Phone is not valid.\");\n      }\n    } else {\n      console.log(\"Contact not found.\")\n    }\n  }\n\n  deleteContact(name: string): void {\n    const initialLeng = this.contacts.length;\n    this.contacts = this.contacts.filter(contact => contact.name.toLowerCase() !== name.toLowerCase());\n    if (this.contacts.length < initialLeng) {\n      console.log(\"Contact delete successfully.\");\n    } else {\n      console.log(\"Contact not found.\");\n    }\n  }\n}\n\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout\n});\n\nconst agenda = new ContactAgenda();\n\nfunction showMenu() {\n  console.log(\"\\nOptions:\");\n  console.log(\"1. Add contact\");\n  console.log(\"2. Search contact\");\n  console.log(\"3. Update contact\");\n  console.log(\"4. Delete contact\");\n  console.log(\"5. Exit\");\n\n  rl.question(\"Select an option: \", (option) => {\n    switch (option) {\n      case '1':\n        rl.question(\"Type the name: \", (nameToAdd) => {\n          rl.question(\"Type the phone: \", (phoneToAdd) => {\n            agenda.addContact(nameToAdd, phoneToAdd);\n            showMenu();\n          });\n        });\n        break;\n      case '2':\n        rl.question(\"Type the name to search: \", (nameToSearch) => {\n          agenda.searchContact(nameToSearch);\n          showMenu();\n        });\n        break;\n      case '3':\n        rl.question(\"Type the contact to update: \", (nameToUpdate) => {\n          rl.question(\"Type the new phone\", (newPhone) => {\n            agenda.updateContact(nameToUpdate, newPhone);\n            showMenu();\n          });\n        });\n        break;\n      case '4':\n        rl.question(\"Type the contact to delete: \", (nameToDelete) => {\n          agenda.deleteContact(nameToDelete);\n          showMenu();\n        });\n        break;\n      case '5':\n        console.log(\"Quit... \");\n        rl.close();\n        break;\n      default:\n        console.log(\"Invalid choice. Try again. \");\n        showMenu();\n    }\n  });\n}\nshowMenu();"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/typescript/XhuaSpy.ts",
    "content": "let contactos : Map<string , number> = new Map();\n\nfunction pedirNombre() : string {\n    let nombre : string | null;\n    do {\n        nombre = prompt(\"Ingresa el nombre:  \");\n    } while ( !nombre );\n    return nombre;\n}\n\nfunction validarNumero(numero: number) : boolean {\n    return numero < 10000000000 && numero > 999999999;\n}\n\nfunction crearContacto() {\n    let nombre : string | null;\n    let numero : number;\n    do {\n        nombre = prompt(\"Ingresa el nombre:\");\n        numero = Number(prompt(\"ingresa el numero: \"));\n    } while ( !nombre || isNaN(numero) || !validarNumero(numero));\n\n    return {\n        \"nombre\": nombre.toString(),\n        \"numero\": numero,\n    };\n}\n\ndo {\n    let nombre : string;\n    let contacto : {nombre : string, numero: number};\n\n    console.log(\"1. Agregar un contacto\");\n    console.log(\"2. Buscar un contacto\");\n    console.log(\"3. Eliminar un contacto\");\n    console.log(\"4. Actualizar un contacto\");\n    console.log(\"5. Ver todos los contactos\");\n    console.log(\"6. Salir\");\n\n    var operacion : number = Number(prompt(\":  \"));\n\n    switch (operacion) {\n        case 1: \n            contacto = crearContacto(); \n            contactos.set(contacto.nombre, contacto.numero);\n            break;\n        \n        case 2: \n            nombre = pedirNombre();\n            if (contactos.get(nombre))\n                console.log({\"nombre\": nombre, \"numero\": contactos.get(nombre)});\n            else \n                console.log(\"paila\");\n            break;\n        \n        case 3: \n            nombre = pedirNombre();\n            if (!(contactos.delete(nombre)))\n                console.log(\"paila\");\n            break;\n        \n        case 4:\n            nombre = pedirNombre();\n            if (contactos.get(nombre)) {\n                contacto = crearContacto();\n                contactos.delete(nombre)\n                contactos.set(contacto.nombre, contacto.numero);\n            }\n            else \n                console.log(\"paila\");\n            break;\n\n        case 5:\n            console.log(Array.from(contactos.entries()));\n            break;\n    }\n\n} while ( operacion != null && operacion != 6);\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/typescript/cubandeveloper89.ts",
    "content": "// ***  Estructura de Datos  ***\n\n// !    Array\nlet my_list = ['Brais', 'midudev', 'el_gato'];\n\nlet num_list = [2, 5, 7, 3, 7];\n\nconsole.log(my_list);\n\nmy_list.push('John')  // * añadir al final\nconsole.log(my_list);\n\nmy_list.unshift('Python')   // * añadir al inicio\nconsole.log(my_list);   \n\nconsole.log(my_list[0]);    // * accediendo a un elemento en mi lista segun su posición \n\nmy_list.pop()       // * elimina el ultimo elemento de la lista\nconsole.log(my_list);\n\nmy_list.shift()       // * elimina el primer elemento de la lista\nconsole.log(my_list);\n\nlet my_second_list = my_list.slice(1, 3);   // * crea un nuevo array con elementos del primero\nconsole.log(my_second_list);\n\n\nmy_list.splice(2,1);    // * elimina elementos segun su posicion\nconsole.log(my_list);\n\nmy_list[1] = 'mouredev';    // * actualizar un elemento segun su posicion\nconsole.log(my_list);\n\nmy_list.push('John');\nmy_list.push('Doe'); \nmy_list.sort();             //  * Ordenar los elementos del array\nconsole.log(my_list);\n\n\n\n// !     Set \nlet my_set:any = new Set();\nmy_set.add(3);                  // * añadiendo valores\nmy_set.add('ordenador');\nmy_set.add(true);\nmy_set.add('45');\nconsole.log(my_set);\n\n\nconsole.log(my_set.has('ordenador'));\n\nmy_set.delete('45')             // * eliminando por elemento\n\nconsole.log(my_set);\n\nconsole.log(my_set.size);       // * muestra el tamaño del set\n\n\n// !     Map\nlet my_map = new Map();\nmy_map.set('a', 1);             // * insertando elementos \nmy_map.set('b', 2);\nmy_map.set('c', 3);\n\nconsole.log(my_map);\n\nmy_map.set('a', 89);            // * actualizando elemento\nconsole.log(my_map);\n\nmy_map.delete('b');             // * eliminando elemento\nconsole.log(my_map);\n\n\n// !    Objects\nlet my_obj = {};                    //  * 2 maneras de declarar un objeto\nlet my_second_obj = new Object();\n\nmy_obj.name = 'Camilo'              //  *   insertando elementos clave/valor\nmy_obj.age = 35;\nmy_obj.profession = 'influencer'\nconsole.log(my_obj);\n\nmy_obj.name = 'Brais';              // * actualizando elementos\nconsole.log(my_obj);\n\ndelete my_obj.profession;           // * eliminando elemento\nconsole.log(my_obj);\n\n                            // ? *** Ejercicio Extra ***\n\nconst prompt = require('prompt-sync')({sigint:true});\n\ninterface Contacto {\n    nombre: string;\n    telefono: string;\n}\n\nconst agenda: Contacto[] = [];\n\nfunction mostrarMenu() {\n    console.log(\"Agenda de Contactos\");\n    console.log(\"1. Buscar contacto\");\n    console.log(\"2. Insertar contacto\");\n    console.log(\"3. Actualizar contacto\");\n    console.log(\"4. Eliminar contacto\");\n    console.log(\"5. Salir\");\n}\n\nfunction buscarContacto(nombre: string) {\n    const contacto = agenda.find(c => c.nombre === nombre);\n    if (contacto) {\n        console.log(\"Contacto encontrado:\");\n        console.log(contacto);\n    } else {\n        console.log(\"Contacto no encontrado.\");\n    }\n}\n\nfunction insertarContacto() {\n    const nombre = prompt(\"Ingrese el nombre del contacto:\");\n    let telefono = prompt(\"Ingrese el número de teléfono:\");\n\n    // Validación del número de teléfono\n    while (!/^\\d{11}$/.test(telefono)) {\n        console.log(\"El número de teléfono debe tener 11 dígitos.\");\n        telefono = prompt(\"Ingrese el número de teléfono:\");\n    }\n\n    const nuevoContacto: Contacto = { nombre, telefono };\n    agenda.push(nuevoContacto);\n    console.log(\"Contacto agregado exitosamente.\");\n}\n\nfunction actualizarContacto(nombre: string) {\n    const indice = agenda.findIndex(c => c.nombre === nombre);\n    if (indice !== -1) {\n        const nuevoTelefono = prompt(\"Ingrese el nuevo número de teléfono:\");\n        agenda[indice].telefono = nuevoTelefono;\n        console.log(\"Contacto actualizado exitosamente.\");\n    } else {\n        console.log(\"Contacto no encontrado.\");\n    }\n}\n\nfunction eliminarContacto(nombre: string) {\n    const indice = agenda.findIndex(c => c.nombre === nombre);\n    if (indice !== -1) {\n        agenda.splice(indice, 1);\n        console.log(\"Contacto eliminado exitosamente.\");\n    } else {\n        console.log(\"Contacto no encontrado.\");\n    }\n}\n\nfunction main() {\n    let opcion: string;\n    do {\n        mostrarMenu();\n        opcion = prompt(\"Ingrese una opción:\");\n\n        switch (opcion) {\n            case \"1\":\n                const nombreBuscar = prompt(\"Ingrese el nombre a buscar:\");\n                buscarContacto(nombreBuscar);\n                break;\n            case \"2\":\n                insertarContacto();\n                break;\n            case \"3\":\n                const nombreActualizar = prompt(\"Ingrese el nombre a actualizar:\");\n                actualizarContacto(nombreActualizar);\n                break;\n            case \"4\":\n                const nombreEliminar = prompt(\"Ingrese el nombre a eliminar:\");\n                eliminarContacto(nombreEliminar);\n                break;\n            case \"5\":\n                console.log(\"Saliendo del programa...\");\n                break;\n            default:\n                console.log(\"Opción inválida.\");\n        }\n    } while (opcion !== \"5\");\n}\n\nmain();\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/typescript/david-git-dev.ts",
    "content": "/*\n  EJERCICIO:\n  - Muestra ejemplos de creación de todas las estructuras soportadas por defecto\n    en tu lenguaje.\n  - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n */\n//arrays\nconst array:string[]=[];\narray.push('comienzo'); // operacion de insercion\narray[0] ='actualizacion';//operacion de actualizacion\narray.push('medio');\narray.push('final');\narray.push('error');\narray.pop()//operacion de borrado\narray.sort();//operacion de ordenamiento\n//tuplas\nconst tupla: [number,string]=[0,'zero']// en la practica son para datos que no van a cambiar pero por alguna extraña razon todavia se puede usar push sobre tuplas y el editor no genera problema.\ntupla.push(1,'as')//operacion de agregacion\ntupla[0] = 999 //operacion de actualizacion\ntupla.pop()//operacion de borrado\n//--> todas las operaciones anteriores sobre la tupla no son recomendadas de hacer porque ese no es el sentido de la tupla pero se pueden hacer\n//enums\nconst enum States{Incoming , Loading , Success}// no se pueden realizar operaciones de modificacion con esta estructura\n//Set\nlet dontRepeatYourSelf = new Set([1,2,3,4]) // sobre esta estructura no se puede modificar directamente un valor ya introducido, ademas no permite datos repetidos.\ndontRepeatYourSelf.add(5) // agregacion\ndontRepeatYourSelf.delete(3)//borrado\n//ejemplo de como podria hacerse una operacion de 'ordenacion' sobre un set\ndontRepeatYourSelf = new Set([...dontRepeatYourSelf].sort((a,b)=>b-a))\n//mapas\nconst map = new Map()\nmap.set('clave','valor')//agregacion\nmap.set('clave','actualizacion')//actualizacion\nmap.delete('clave')//borrado\n//objetos\nconst objeto: { [key: string]: any } = {};\nobjeto.propiedadUno = \"propiedad1\"; //operaciones de agregacion\nobjeto.propiedadDos = \"propiedad2\";\ndelete objeto.propiedadUno;//operaciones de borrado\nobjeto.propiedadDos = \"actualizacion\"; //operaciones de actualizacion\n\n/* DIFICULTAD EXTRA (opcional):*/\nconsole.log(`\n  Hola, bienvenido a tu agenda de contactos\n    ¿Que deseas realizar?\n    1- Agregar contacto\n    2- Actualizar contacto\n    3- Eliminar contacto\n    ?- Buscar contacto\n  Deja la respuesta vacia para salir de la agenda-->\n    `);\n  type Contacto = {\n    nombre: string;\n    numero: number;\n  };\n  type Agenda = {\n    [key: string]: Contacto;\n  };\n  const agenda: Agenda = {};\n  let opcion: string | null;\n  do {\n    let id: string | null;\n\n    let informacion: string | null;\n    opcion = prompt(`\n    1- Agregar contacto\n    2- Actualizar contacto\n    3- Eliminar contacto\n    ?- Buscar contacto\n    Deja la respuesta vacia para salir de la agenda-->\n    `);\n\n    switch (opcion) {\n      case \"1\":\n        informacion = prompt(\n          \"Introduce el nombre y el telefono separados por una coma para cada par de (nombre,telefono) campo(ej): juan perez,4612349178\"\n        );\n        if (informacion) agregar(informacion);\n        break;\n      case \"2\":\n        id = prompt(\n          \"Introduce el nombre o el telefono para actualizar los datos del contacto...\"\n        );\n        informacion = prompt(\n          \"Introduce tus nuevos datos...(ej): juan perez,4612349178\"\n        );\n        if (id && informacion) actualizar(id, informacion);\n        break;\n      case \"3\":\n        id = prompt(\"Introduce el nombre o el telefono para borrar el contacto\");\n        if (id) eliminar(id);\n        break;\n      case \"?\":\n        id = prompt(\"Introduce el nombre o el telefono para buscarlo:\");\n        if (id) buscar(id);\n        break;\n      default:\n        console.log(`Saliendo de la aplicacion....`);\n        break;\n    }\n    console.log(agenda)\n  } while (opcion);\n\n  function agregar(datos: string) {\n    const [nombre, numero] = datos.split(\",\");\n    if (nombre && esUnNumeroValido(numero)) {\n      const registro: Contacto = {\n        nombre: nombre,\n        numero: Number(numero),\n      };\n      agenda[window.crypto.randomUUID()] = registro;\n    } else {\n     error();\n    }\n  }\n  function actualizar(id: string, contacto: string) {\n    console.warn(\"Actualizando....\");\n    const [nombre, numero] = contacto.split(\",\");\n    const res = Object.entries(agenda).find(\n      ([, contacto]) => contacto.nombre == id || contacto.numero == Number(id)\n    );\n    if (res && esUnNumeroValido(numero)) {\n      const uuid = res![0];\n      agenda[uuid].nombre = nombre;\n      agenda[uuid].numero = Number(numero);\n      console.log(\"Actualizado\");\n    }else{\n  error();\n    }\n\n  }\n  function eliminar(id: string) {\n    console.warn(\"Eliminando...\");\n    const uuid = buscar(id);\n    const res = delete agenda[uuid]\n      ? \"Contacto eliminado....\"\n      : \"Perdona... quien?\";\n    console.log(res);\n  }\n  function buscar(id: string): string {\n    let uuid = \"\";\n\n    const res = Object.entries(agenda).find(\n      ([, contacto]) => contacto.nombre == id || contacto.numero == Number(id)\n    );\n\n    if (res) {\n      uuid = res[0];\n      console.log(`\n  Vaya! a quien tenemos aqui?.....\n  ${res}\n  `);\n      alert(`\n  Vaya! a quien tenemos aqui?.....\n  ${JSON.stringify(res)}\n  `);\n    } else {\n     error()\n    }\n\n    return uuid;\n  }\n  function esUnNumeroValido(numero: string): boolean {\n    return !isNaN(Number(numero)) && numero.length < 11;\n  }\n\n  function error(){\n     console.warn(\n        \"ups....algo salio mal.Revisa si tus datos son registrado correctamente, no se admiten numeros de mas de 11 digitos\"\n      );\n      alert(\n        \"ups....algo salio mal.Revisa si tus datos son registrado correctamente, no se admiten numeros de mas de 11 digitos\"\n      );\n  }"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/typescript/duendeintemporal.ts",
    "content": "/*\n * { Retos para programadores } #3 ESTRUCTURAS DE DATOS\n * \n * Based on \"Professional JavaScript for Web Developers\" by Matt Frisbie (z-lib.org) for accurate information in some comments.\n * TypeScript - Official URL: https://www.typescriptlang.org/\n * \n * In TypeScript, there are several built-in data structures that you can use to store and manipulate data. \n * Here is a list of the most common ones, with additional TypeScript-specific insights.\n */\n\nlet log = console.log;\n\n/* Primitive Data Types */\n\n// Number: Represents both integer and floating-point numbers. In TypeScript, you can explicitly annotate the type.\nlet age: number = 35; // Integer\nlet total: number = 118.87; // Floating-point\nlog('age: ', age + ', total: ', total); // age: 35, total: 118.87\nlog(0.3); // 0.3\n\nlet octNum: number = 0o45;\nlog(octNum); // 37\n\nlet hexNum: number = 0x2f;\nlog(hexNum); // 47\n\n// NaN (Not a Number) is a special value that indicates that an operation that should return a number has failed.\nlet greeting: string = 'Hi man how you doing?';\nlet someNumber: any = greeting + 4; // Using `any` is discouraged in TypeScript; prefer `unknown` for safer type handling.\nlog(someNumber); // Hi man how you doing?4\n\nlet someValue: any = \"04\";\nlog(isNaN(someValue)); // false  ( because it can be converted to a number )\n\n// String: Represents a sequence of characters. In TypeScript, strings can be annotated with the `string` type.\nlet dreamyGirl = \"Lucy\";\nlet song = dreamyGirl + ' in the sky with diamonds';\nlet songInfo = `\"${song}\" is a song from The Beatles that alludes to LSD`;\nlog(songInfo); // \"Lucy in the sky with diamonds\" is a song from The Beatles that alludes to LSD\n\n// Template literals and special characters\nlet num1: number = 40;\nlet num2: number = 80;\nlet sum: string = `${num1} + ${num2} = ${num1 + num2}`;\nlog(sum); // \"40 + 80 = 120\"\n\nlog(`\\u57A8`); // 垨\nlog(String.raw`\\u57A8`); // \\u57A8\n\nlog(`first line\\nsecond line`);\n// first line\n// second line\nlog(String.raw`first line\\nsecond line`); // \"first line\\nsecond line\"\n\n// Boolean: Represents a logical entity with two values: `true` and `false`. In TypeScript, booleans are explicitly typed.\nlet isChecked: boolean = true;\nlog(!isChecked); // false\n\n// Undefined: A variable that has been declared but not assigned. In TypeScript, you can use `undefined` as a type.\nlet somebody: unknown; // Using `unknown` is safer than `any` for uninitialized variables.\nlog(somebody); // undefined\n\n// Null: Represents the intentional absence of any object value. In TypeScript, `null` is a subtype of all other types.\nlet animals: null = null;\nlog(animals); // null\n\n// Symbol: A unique and immutable primitive value, often used as an object property key. In TypeScript, symbols are explicitly typed.\nconst Id: symbol = Symbol('xm');\nconst otherId: symbol = Symbol('xm');\nlog('equal symbols: ', Id == otherId); // false\n\nconst emailSymbol: symbol = Symbol('email');\n\nclass User {\n    constructor(name: string, email: string) {\n        this.name = name;\n        this[emailSymbol] = email; // Using a symbol as a unique property key.\n    }\n    name: string;\n\n    getName() {\n        return this.name;\n    }\n\n    getEmail() {\n        return this[emailSymbol];\n    }\n}\n\nconst user1 = new User('Barbarella', 'softbaby@something.com');\nconsole.log(user1.name); // Barbarella\nconsole.log(user1.getEmail()); // softbaby@something.com\n\n// BigInt: Represents integers with arbitrary precision. In TypeScript, BigInt literals require the `n` suffix.\nlet bigNumber: bigint = BigInt(765466743212345679874653358945321);\nlog(bigNumber); // 765466743212345647593078160097280n\n\n/* Reference Data Types */\n\n// Object: A collection of key-value pairs. In TypeScript, you can define interfaces or types to describe the shape of objects.\ninterface Debian {\n    name: string;\n    description: string;\n    location: string;\n    speak: () => void;\n}\n\nlet debian: Debian = {\n    name: 'Debian',\n    description: 'Ardilla parlante cuyo núcleo está basado en un Sistema Operativo del mismo nombre, lucha contra el Sistema establecido y habita más allá del Borde (el Universo conocido)',\n    location: 'No Found',\n\n    speak: () => {\n        console.log(this.description);\n    }\n};\n\nlog(debian.description); // Ardilla parlante cuyo núcleo está basado en un Sistema Operativo del mismo nombre, lucha contra el Sistema establecido y habita más allá del Borde (el Universo conocido)\n\n// Array: An ordered collection of values. In TypeScript, arrays are explicitly typed.\nlet friends: string[] = ['Susan', 'Maryatta', 'Denise', 'Luna', 'Kena', 'Maria'];\nlog(friends); // [ 'Susan', 'Maryatta', 'Denise', 'Luna', 'Kena', 'Maria' ]\n\n// Function: A special type of object that can be called to perform a specific task. In TypeScript, functions can have explicit parameter and return types.\nlet from: number = 4, to: number = 12;\nconst randomValue = (from: number, to: number): number => {\n    return Math.floor(Math.random() * (to - from + 1)) + from;\n};\n\nlet count: number = from;\nwhile (count < to) {\n    log('random value: ', randomValue(from, to));\n    count++;\n}  /*  Possible Output: \nrandom value:  9\nrandom value:  6\nrandom value:  9\nrandom value:  12\nrandom value:  6\nrandom value:  7\nrandom value:  4\nrandom value:  8\n */\n\n/* Specialized Data Structures */\n\n// Set: A collection of unique values. In TypeScript, sets are generic and can be explicitly typed.\nlet uniqueNumbers = new Set<number>([4, 4, 3, 5, 8, 1, 8, 1, 7]);\nlog(uniqueNumbers); // Set(6) { 4, 3, 5, 8, 1, 7 }\n\n// Map: A collection of key-value pairs where keys can be of any type. In TypeScript, maps are generic and can be explicitly typed.\nlet map = new Map<string, any>();\nmap.set('gopi_name', 'Khamala');\nmap.set('age', 35);\nlog(map.get('gopi_name')); // Khamala\n\n// WeakSet: Similar to Set, but holds \"weak\" references to its values. In TypeScript, WeakSets are generic.\nlet weakSet = new WeakSet<object>();\nlet obj = {};\nweakSet.add(obj);\nlog(weakSet.has(obj)); // true\n\n// WeakMap: Similar to Map, but holds \"weak\" references to its keys. In TypeScript, WeakMaps are generic.\nlet weakMap = new WeakMap<object, string>();\nlet keyObj = {};\nweakMap.set(keyObj, \"crazylady\");\nlog(weakMap.get(keyObj)); // crazylady\n\n/* Typed Arrays */\n\n// Int8Array: Represents an array of 8-bit signed integers.\nlet int8Array = new Int8Array([-3, 5, -8, 99, 76]);\nlog(int8Array); // Int8Array(5) [ -3, 5, -8, 99, 76 ]\n\n// Uint8Array: Represents an array of 8-bit unsigned integers.\nlet uint8Array = new Uint8Array([1, 2, 3]);\nlog(uint8Array); // Uint8Array(3) [ 1, 2, 3 ]\n\n// Uint8ClampedArray: Represents an array of 8-bit unsigned integers, but with values \"clamped\" to the range [0, 255].\nlet uint8ClampedArray = new Uint8ClampedArray([-1, 256, 100]);\nlog(uint8ClampedArray); // Uint8ClampedArray(3) [ 0, 255, 100 ]\n\n// Int16Array: Represents an array of 16-bit signed integers.\nlet int16Array = new Int16Array([1, -2, 3]);\nlog(int16Array); // Int16Array(3) [ 1, -2, 3 ]\n\n// Uint16Array: Represents an array of 16-bit unsigned integers.\nlet uint16Array = new Uint16Array([1, 2, 3]);\nlog(uint16Array); // Uint16Array(3) [ 1, 2, 3 ]\n\n// Int32Array: Represents an array of 32-bit signed integers.\nlet int32Array = new Int32Array([1, -2, 3]);\nlog(int32Array); // Int32Array(3) [ 1, -2, 3 ]\n\n// Uint32Array: Represents an array of 32-bit unsigned integers.\nlet uint32Array = new Uint32Array([1, 2, 3]);\nlog(uint32Array); // Uint32Array(3) [ 1, 2, 3 ]\n\n// Float32Array: Represents an array of 32-bit floating-point numbers.\nlet float32Array = new Float32Array([1.5, 2.5, 3.5]);\nlog(float32Array); // Float32Array(3) [ 1.5, 2.5, 3.5 ]\n\n// Float64Array: Represents an array of 64-bit floating-point numbers.\nlet float64Array = new Float64Array([1.5, 2.5, 3.5]);\nlog(float64Array); // Float64Array(3) [ 1.5, 2.5, 3.5 ]\n\nlog('Retos para programadores #3'); // Retos para programadores #3"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/typescript/eulogioep.ts",
    "content": "import * as readline from 'readline';\n\n// Creamos una interfaz de readline\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\n// Definimos un tipo para los contactos\ntype Contact = {\n    name: string;\n    phone: string;\n};\n\n// Función para ejemplificar las estructuras de datos en TypeScript\nfunction ejemplosEstructurasDatos(): void {\n    // Array: equivalente a ArrayList en Java\n    let array: string[] = ['Java', 'Python', 'TypeScript'];\n    console.log('Array:', array);\n\n    // Set: conjunto sin duplicados\n    let set: Set<number> = new Set([1, 2, 2, 3, 4]);\n    console.log('Set:', set);\n\n    // Map: equivalente a HashMap en Java\n    let map: Map<string, number> = new Map();\n    map.set('Uno', 1);\n    map.set('Dos', 2);\n    map.set('Tres', 3);\n    console.log('Map:', map);\n\n    // Operaciones\n    array.splice(1, 1); // Borrado (elimina 'Python')\n    array[1] = 'JavaScript'; // Actualización\n    array.sort(); // Ordenación\n\n    console.log('Array después de operaciones:', array);\n}\n\n// Función principal para la agenda de contactos\nfunction agendaContactos(): void {\n    let agenda: Map<string, string> = new Map();\n\n    function mostrarMenu(): void {\n        console.log(\"\\n--- Agenda de Contactos ---\");\n        console.log(\"1. Buscar contacto\");\n        console.log(\"2. Añadir contacto\");\n        console.log(\"3. Actualizar contacto\");\n        console.log(\"4. Eliminar contacto\");\n        console.log(\"5. Mostrar todos los contactos\");\n        console.log(\"6. Salir\");\n        rl.question(\"Seleccione una opción: \", manejarOpcion);\n    }\n\n    function manejarOpcion(opcion: string): void {\n        switch (opcion) {\n            case '1':\n                buscarContacto();\n                break;\n            case '2':\n                anadirContacto();\n                break;\n            case '3':\n                actualizarContacto();\n                break;\n            case '4':\n                eliminarContacto();\n                break;\n            case '5':\n                mostrarContactos();\n                break;\n            case '6':\n                console.log(\"¡Hasta luego!\");\n                rl.close();\n                return;\n            default:\n                console.log(\"Opción no válida.\");\n                mostrarMenu();\n        }\n    }\n\n    function buscarContacto(): void {\n        rl.question(\"Ingrese el nombre del contacto: \", (nombre: string) => {\n            if (agenda.has(nombre)) {\n                console.log(`Teléfono de ${nombre}: ${agenda.get(nombre)}`);\n            } else {\n                console.log(\"Contacto no encontrado.\");\n            }\n            mostrarMenu();\n        });\n    }\n\n    function anadirContacto(): void {\n        rl.question(\"Ingrese el nombre del contacto: \", (nombre: string) => {\n            solicitarTelefono((telefono: string) => {\n                agenda.set(nombre, telefono);\n                console.log(\"Contacto añadido con éxito.\");\n                mostrarMenu();\n            });\n        });\n    }\n\n    function actualizarContacto(): void {\n        rl.question(\"Ingrese el nombre del contacto a actualizar: \", (nombre: string) => {\n            if (agenda.has(nombre)) {\n                solicitarTelefono((telefono: string) => {\n                    agenda.set(nombre, telefono);\n                    console.log(\"Contacto actualizado con éxito.\");\n                    mostrarMenu();\n                });\n            } else {\n                console.log(\"Contacto no encontrado.\");\n                mostrarMenu();\n            }\n        });\n    }\n\n    function eliminarContacto(): void {\n        rl.question(\"Ingrese el nombre del contacto a eliminar: \", (nombre: string) => {\n            if (agenda.delete(nombre)) {\n                console.log(\"Contacto eliminado con éxito.\");\n            } else {\n                console.log(\"Contacto no encontrado.\");\n            }\n            mostrarMenu();\n        });\n    }\n\n    function mostrarContactos(): void {\n        if (agenda.size === 0) {\n            console.log(\"La agenda está vacía.\");\n        } else {\n            agenda.forEach((telefono: string, nombre: string) => {\n                console.log(`${nombre}: ${telefono}`);\n            });\n        }\n        mostrarMenu();\n    }\n\n    function solicitarTelefono(callback: (telefono: string) => void): void {\n        rl.question(\"Ingrese el número de teléfono (máximo 11 dígitos): \", (telefono: string) => {\n            if (/^\\d{1,11}$/.test(telefono)) {\n                callback(telefono);\n            } else {\n                console.log(\"Número no válido. Debe ser numérico y tener máximo 11 dígitos.\");\n                solicitarTelefono(callback);\n            }\n        });\n    }\n\n    mostrarMenu();\n}\n\n// Ejecutamos los ejemplos y la agenda\nconsole.log(\"Ejemplos de estructuras de datos en TypeScript:\");\nejemplosEstructurasDatos();\n\nconsole.log(\"\\nIniciando la agenda de contactos...\");\nagendaContactos();"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/typescript/fravelz.ts",
    "content": "// Array ******************************************************************** //\n\nlet lista: number[] = [4, 6, 1, 7, 5, 8, 2, 3]\nconsole.log(`Lista original: ${lista}`)\n\n//Inserción\nlista.push(0) //Agrego un elemento al final de la lista \n// [4, 6, 1, 7, 5, 8, 2, 3, 0]\n\nlista.unshift(9) //Agrego un elemento al principio de la lista\n// [9, 4, 6, 1, 7, 5, 8, 2, 3, 0]\n\nlista.splice(2, 0, 10) //Agrego el 10 en la posición 3\n// [9, 4, 10, 6, 1, 7, 5, 8, 2, 3, 0]\n\n//Borrado\nlista.pop() //Elimino el ultimo elemento de la lista\n// [9, 4, 10, 6, 1, 7, 5, 8, 2, 3]\n\nlista.shift() //Elimino el primer elemento de la lista\n// [4, 10, 6, 1, 7, 5, 8, 2, 3]\n\nlista.splice(3, 1) //Elimino el elemento en la posición 4\n// [4, 10, 6, 7, 5, 8, 2, 3]\n\n//Actualización\nlista[6] = 9 //Reemplazo el elemento de la posición 7\n// [4, 10, 6, 7, 5, 8, 9, 3]\n\n//Ordenación\nlista.sort(function (a, b): number { return a - b }) //Ordeno la lista de menor a mayor\n// [3, 4, 5, 6, 7, 8, 9, 10]\n\nlista.reverse() //Ordeno la lista de mayor a menor\n// [10, 9, 8, 7, 6, 5, 4, 3]\n\n// Objet ******************************************************************** //\nlet person: { name: string, lastname: string, age: bigint } = {\n    name: \"Fra\",\n    lastname: \"velz\",\n    age: 9999999n\n}\n\n//Inserción\n\n// error en typescript porque el tipo del objeto no tiene la propiedad \"ciudad\"\n// person[\"ciudad\"] = \"Rosario\"\n\n//Borrado\n// error en typescript porque el operador delete no se puede usar para eliminar \n// propiedades de un objeto que tiene un tipo definido\n// delete person.lastname\n\n//Actualización\nperson.name = \"Javier\"\n// { name: 'Javier', age: 9999999n, ciudad: 'Rosario' }\n\n// Map ********************************************************************** //\n\nlet mapa: Map<string, string> = new Map()\n\n//Inserción\nmapa.set(\"rojo\", \"red\")\nmapa.set(\"verde\", \"green\")\nmapa.set(\"azul\", \"blue\")\n// { 'rojo' => 'red', 'verde' => 'green', 'azul' => 'blue' }\n\n//Borrado\nmapa.delete(\"verde\")\n// { 'rojo' => 'red', 'azul' => 'blue' }\n\n//Actualización\nmapa.set(\"rojo\", \"vermelho\")\n// { 'rojo' => 'vermelho', 'azul' => 'blue' }\n\nlet mapa2: WeakMap<object, string> = new WeakMap();\n\n/* { <object> => 'valor' } a diferencia del Map, el WeakMap no impide que el\nobjeto clave sea recolectado por el garbage collector si no hay otras referencias\na él. Esto significa que si el objeto clave es eliminado, la entrada\ncorrespondiente en el WeakMap también será eliminada automáticamente.\n*/\n\n// Set ********************************************************************** //\n\nlet numeros: Set<number> = new Set([4, 6, 1, 7])\n// { 4, 6, 1, 7 }\n\n//Inserción\nnumeros.add(0)\n// { 4, 6, 1, 7, 0 }\n\n//Borrado\nnumeros.delete(1)\n// { 4, 6, 7, 0 }\n\nlet sets: WeakSet<object> = new WeakSet();\n\n/* { <object>, <object>, ... } a diferencia del Set, el WeakSet no impide que los\nobjetos sean recolectados por el garbage collector si no hay otras referencias\na ellos. Esto significa que si un objeto es eliminado, la entrada correspondiente\nen el WeakSet también será eliminada automáticamente.\n*/\n\n/* *****************************************************************************\nDIFICULTAD EXTRA (opcional):\nCrea una agenda de contactos por terminal.\n- Debes implementar funcionalidades de búsqueda, inserción, actualización\n    y eliminación de contactos.\n- Cada contacto debe tener un nombre y un número de teléfono.\n- El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n    y a continuación los datos necesarios para llevarla a cabo.\n- El programa no puede dejar introducir números de teléfono no númericos y con más\n    de 11 dígitos (o el número de dígitos que quieras).\n- También se debe proponer una operación de finalización del programa.\n***************************************************************************** */\n\n\nlet agenda: Map<string, string> = new Map()\n\nimport readline from 'readline'\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nfunction obtenerInput(pregunta: string): Promise<string> {\n    return new Promise((resolve) => {\n        rl.question(pregunta, (respuesta) => { resolve(respuesta); });\n    });\n}\n\nasync function main() {\n    while (true) {\n        console.log(`\\n****************************************`);\n        console.log(\"* 1. Search contact\");\n        console.log(\"* 2. Add contact\");\n        console.log(\"* 3. Update contact\");\n        console.log(\"* 4. Delete contact\");\n        console.log(\"* 5. Exit\");\n        console.log(`****************************************`);\n\n        const op = await obtenerInput('* > Please enter an option: ');\n\n        switch (op) {\n            case \"1\": {\n                let nombre = await obtenerInput(\"* > Enter name to search: \");\n\n                if (agenda.get(nombre))\n                    console.log(`The phone number for ${nombre} is: ${agenda.get(nombre)}`);\n\n                else\n                    console.log(`The contact ${nombre} does not exist in the agenda`);\n                break;\n            }\n\n            case \"2\": {\n                let nombre = await obtenerInput('Name: ');\n                let telefono = await obtenerInput('Phone number: ');\n\n                const isValidPhone = /^[0-9]{1,11}$/.test(telefono)\n\n                if (isValidPhone && telefono.length > 0 && telefono.length < 12) {\n                    agenda.set(nombre, telefono);\n                    console.log(\"The contact was successfully created\");\n                } else {\n                    console.log(\"You must enter a number with less than 12 digits\");\n                }\n\n                break;\n            }\n\n            case \"3\": {\n                let nombre = await obtenerInput('* > Enter the name of the contact to update: ');\n\n                if (agenda.get(nombre)) {\n                    let telefono = await obtenerInput('* > Enter the new phone number: ');\n\n                    if (!isNaN(Number(telefono)) && telefono.length > 0 && telefono.length < 12) {\n                        agenda.set(nombre, telefono);\n                        console.log(\"The contact was successfully updated\");\n                    } else {\n                        console.log(\"You must enter a number with less than 12 digits\");\n                    }\n\n                } else {\n                    console.log(`The contact ${nombre} does not exist in the agenda`);\n                }\n                break;\n            }\n\n            case \"4\": {\n                let nombre = await obtenerInput('* > Enter the name of the contact to delete: ');\n\n                if (agenda.has(nombre)) {\n                    agenda.delete(nombre);\n                    console.log(`The contact ${nombre} was successfully deleted`);\n\n                } else {\n                    console.log(`The contact ${nombre} does not exist in the agenda`);\n                }\n                break;\n            }\n\n            default: console.log(\"Invalid option. Please try again.\");\n        }\n\n        if (op === \"5\") {\n            console.log(\"Exiting the program...\");\n            rl.close();\n            break;\n        }\n    }\n}\n\nmain();\n\nexport { };\n\n// > Autor: Fravelz\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/typescript/giovanyosorio.ts",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\n// Creación de estructuras de datos en TypeScript\n// Array\nlet array = [1, 2, 3, 4, 5];\nconsole.log(array);\n\n// Operaciones de inserción y borrado\narray.push(6);\nconsole.log(array);\narray.pop();\nconsole.log(array);\n\n// Operaciones de actualización\narray[0] = 0;\nconsole.log(array);\n\n// Operaciones de ordenación\narray.sort((a, b) => a - b);\nconsole.log(array);\n\n// Set\nlet set = new Set([1, 2, 3, 4, 5]);\nconsole.log(set);\n\n// Operaciones de inserción y borrado\nset.add(6);\nconsole.log(set);\nset.delete(6);\nconsole.log(set);\n\n// Map\nlet map = new Map([\n  ['a', 1],\n  ['b', 2],\n  ['c', 3],\n]);\nconsole.log(map);\n\n// Operaciones de inserción y borrado\nmap.set('d', 4);\nconsole.log(map);\nmap.delete('d');\nconsole.log(map);\n\n// Operaciones de actualización\nmap.set('a', 0);\nconsole.log(map);\n\n// Operaciones de ordenación\nmap.set('e', 5);\nconsole.log(map);\nconsole.log([...map.entries()].sort((a, b) => a[1] - b[1]));\n\n// Agenda de contactos\nlet agenda = new Map<string, string>();\n\nfunction addContact(name: string, phone: string): void {\n  agenda.set(name, phone);\n}\n\nfunction removeContact(name: string): void {\n  agenda.delete(name);\n}\n\nfunction updateContact(name: string, phone: string): void {\n  agenda.set(name, phone);\n}\n\nfunction searchContact(name: string): void {\n   agenda.get(name);\n}\n\n// Ejemplo de uso\naddContact('Giovany', '1234567890');\naddContact('Juan', '0987654321');\nconsole.log(agenda);\nremoveContact('Juan');\nconsole.log(agenda);\nupdateContact('Giovany', '0987654321');\nconsole.log(agenda);\nsearchContact('Giovany');\nconsole.log(agenda);\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/typescript/hozlucas28.ts",
    "content": "/*\n    Estructuras...\n*/\n\n// Array\nconst arr: string[] = ['Hello', 'World']\nconsole.log('Array structure: const <ARRAY NAME>: <DATA TYPE>[] = [<ELEMENTS...>]')\nconsole.log(`const arr: string[] = ['Hello', 'World'] --> arr = [${arr}]`)\n\n// Tuple\nconst tuple: [string, number] = ['Lucas', 21]\nconsole.log(\"\\nTuple structure: const <TUPLE NAME>: [<DATA TYPE OF 'N' ELEMENT...>] = [<ELEMENTS...>]\")\nconsole.log(`const tuple: [string, number] = ['Lucas', 21] --> tuple = [${tuple}]`)\n\n// Object\nconst obj: Record<string, string> = {\n\tapple: 'Manzana',\n\tbanana: 'Banana',\n\torange: 'Naranja',\n}\n\nconsole.log(\n\t'\\nObject structure: const <OBJECT NAME>: Record<<DATA TYPE OF KEYS>, <DATA TYPE OF VALUES>> = {<PROPERTIES...>}'\n)\nconsole.table(obj)\n\n// Enum\nenum MyCustomEnum {\n\tfirstName = 'Lucas',\n\tlastName = 'Hoz',\n}\nconsole.log('\\nEnum structure: enum <ENUM NAME> {<ELEMENTS...>}')\nconsole.table({\n\tfirstName: MyCustomEnum.firstName,\n\tlastName: MyCustomEnum.lastName,\n})\n\nconsole.log('\\n# ---------------------------------------------------------------------------------- #')\n\n/*\n    Insert, delete, update, and sort operations\n*/\n\nlet array: number[] = []\nlet object: Record<string, string> = {}\n\n// Insert element/s at the end of an array structure\narray.push(1, 2, 3, 4, 5, 6, 7, 8)\nconsole.log('\\nInsert element/s at the end of an array structure: <ARRAY NAME>.push(<ELEMENTS...>)')\nconsole.log(`[].push(1, 2, 3, 4, 5, 6, 7, 8) --> array = [${array}]`)\n\n// Insert element/s at the beginning of an array structure\narray.unshift(-2, -1, 0)\nconsole.log('\\nInsert element/s at the beginning of an array structure: <ARRAY NAME>.unshift(<ELEMENTS...>)')\nconsole.log(`[1, 2, 3, 4, 5, 6, 7, 8].unshift(-2, -1 , 0) --> array = [${array}]`)\n\n// Delete an element of an array structure\narray = array.filter((_, index) => index !== 4)\nconsole.log(\n\t'\\nDelete an element of an array structure: <ARRAY NAME> = <ARRAY NAME>.filter((_, index) => index !== <INDEX OF THE ELEMENT TO DELETE>)'\n)\nconsole.log(\n\t`[-2, -1 , 0, 1, 2, 3, 4, 5, 6, 7, 8] = [-2, -1 , 0, 1, 2, 3, 4, 5, 6, 7, 8].filter((_, index) => index !== 4) --> array = [${array}]`\n)\n\n// Delete the first element of an array structure\narray.shift()\nconsole.log('\\nDelete the first element of an array structure: <ARRAY NAME>.shift()')\nconsole.log(`[-2, -1 , 0, 1, 3, 4, 5, 6, 7, 8].shift() --> array = [${array}]`)\n\n// Delete the last element of an array structure\narray.pop()\nconsole.log('\\nDelete the last element of an array structure: <ARRAY NAME>.pop()')\nconsole.log(`[-1, 0, 1, 3, 4, 5, 6, 7, 8].pop() --> array = [${array}]`)\n\n// Update an element of an array structure\narray[6] = 6 * 2\nconsole.log('\\nUpdate an element of an array structure: <ARRAY NAME>[<INDEX OF THE ELEMENT TO UPDATE>] = <NEW VALUE>')\nconsole.log(`[-1, 0, 1, 3, 4, 5, 6, 7][6] = 6 * 2 --> array = [${array}]`)\n\n// Sort an array structure\narray.sort((a, b) => a - b)\nconsole.log('\\nSort an array structure: <ARRAY NAME>.sort(<SORT FUNCTION>)')\nconsole.log(`[-1, 0, 1, 3, 4, 5, 12, 7].sort((a, b) => a - b) --> array = [${array}]`)\n\n// Insert property/ies into an object structure\nobject = {\n\t...object,\n\tfirst: '1°',\n\tsecond: '2°',\n\tthird: '3°',\n}\nconsole.log('\\nInsert property/ies into an object structure: <OBJECT NAME> = {...<OBJECT NAME>, <PROPERTIES...>}')\nconsole.log(`{} = {\n\t...{},\n\tfirst: '1°',\n\tsecond: '2°',\n\tthird: '3°',\n} --> object = {${Object.entries(object)}}`)\n\n// Delete a property of an object structure\ndelete object['second']\nconsole.log(\"\\nDelete a property of an object structure: delete <OBJECT NAME>['<KEY OF THE PROPERTY TO DELETE>'])\")\nconsole.log(`delete {first: '1°', second: '2°', third: '3°'}['second'] --> object = {${Object.entries(object)}}}`)\n\n// Update a property of an object structure\nobject['first'] = 'First place'\nconsole.log(\"\\nUpdate a property of an object structure: <OBJECT NAME>['KEY OF THE PROPERTY TO UPDATE'] = <NEW VALUE>\")\nconsole.log(`{first: '1°', third: '3°'}['first'] = 'First place' --> object = {${Object.entries(object)}}}`)\n\nconsole.log('\\n# ---------------------------------------------------------------------------------- #')\n\n/*\n    Additional challenge...\n*/\n\ntype Contact = {\n\tname: string\n\tphoneNumber: string\n}\n\ntype Operation = 'FIND' | 'INSERT' | 'UPDATE' | 'DELETE' | 'EXIT'\n\nconst contacts: Contact[] = []\n\nconst getContactInfo = (name: string): Contact | undefined =>\n\tcontacts.find((value) => value.name.toUpperCase() === name.toUpperCase())\n\nconst getContactName = (msg: string, msgOnInvalid: string, shouldExist: boolean): string | null => {\n\tlet name = prompt(msg)\n\tif (!name) return null\n\n\tconst contactInfo = getContactInfo(name)\n\tconst condition = shouldExist ? contactInfo === undefined : contactInfo !== undefined\n\twhile (condition) {\n\t\tname = prompt(msgOnInvalid)\n\t\tif (!name) break\n\t}\n\n\treturn name\n}\n\nconst getContactPhoneNumber = (msg: string, msgOnInvalid: string): string | null => {\n\tlet phoneNumber = prompt(msg)\n\tif (!phoneNumber) return null\n\n\twhile (!isValidPhoneNumber(phoneNumber)) {\n\t\tphoneNumber = prompt(msgOnInvalid)\n\t\tif (!phoneNumber) break\n\t}\n\n\treturn phoneNumber\n}\n\nconst isValidPhoneNumber = (phoneNumber: string): boolean =>\n\tphoneNumber.length <= 11 && (phoneNumber.match(/[^0-9]/g) ?? []).length === 0\n\nlet exit = false\nwhile (!exit) {\n\tconst operation = (\n\t\tprompt(\"Select an operation ('Find', 'Insert', 'Update', 'Delete' or 'Exit'):\") ?? ''\n\t).toUpperCase() as Operation\n\n\tswitch (operation) {\n\t\tcase 'FIND':\n\t\t\tconst contactName = getContactName(\n\t\t\t\t'Enter the name of the contact:',\n\t\t\t\t\"The contact doesn't exists! Enter another name:\",\n\t\t\t\ttrue\n\t\t\t)\n\t\t\tif (!contactName) continue\n\n\t\t\tconst contactInfo = getContactInfo(contactName)\n\t\t\tconsole.log(`Contact info: ${contactInfo?.name} / ${contactInfo?.phoneNumber}`)\n\t\t\tbreak\n\n\t\tcase 'INSERT':\n\t\t\tconst newContactName = getContactName(\n\t\t\t\t'Enter the name of the new contact:',\n\t\t\t\t'The contact already exists! Try with another name:',\n\t\t\t\tfalse\n\t\t\t)\n\t\t\tif (!newContactName) continue\n\n\t\t\tlet newContactPhoneNumber = getContactPhoneNumber(\n\t\t\t\t'Enter the phone number of new contact:',\n\t\t\t\t'Invalid phone number! Enter a valid one:'\n\t\t\t)\n\t\t\tif (!newContactPhoneNumber) continue\n\n\t\t\tcontacts.push({\n\t\t\t\tname: newContactName,\n\t\t\t\tphoneNumber: newContactPhoneNumber,\n\t\t\t})\n\n\t\t\tconsole.log('Contact inserted!')\n\t\t\tbreak\n\n\t\tcase 'UPDATE':\n\t\t\tconst contactNameToUpdate = getContactName(\n\t\t\t\t'Enter the name of the contact to update:',\n\t\t\t\t\"The contact doesn't exists! Enter another name:\",\n\t\t\t\ttrue\n\t\t\t)\n\t\t\tif (!contactNameToUpdate) continue\n\n\t\t\tconst newName = getContactName('Enter the new name:', 'There is a contact with this name! Try another one:', false)\n\t\t\tif (!newName) continue\n\n\t\t\tconst newPhoneNumber = getContactPhoneNumber('Enter the new phone number:', 'Invalid phone number! Enter a valid one:')\n\t\t\tif (!newPhoneNumber) continue\n\n\t\t\tconst contactToUpdate = contacts.findIndex((value) => value.name.toUpperCase() === contactNameToUpdate.toUpperCase())\n\t\t\tcontacts[contactToUpdate] = {\n\t\t\t\tname: newName,\n\t\t\t\tphoneNumber: newPhoneNumber,\n\t\t\t}\n\n\t\t\tconsole.log('Contact updated!')\n\n\t\t\tbreak\n\n\t\tcase 'DELETE':\n\t\t\tconst contactNameToDelete = getContactName(\n\t\t\t\t'Enter the name of the contact to delete:',\n\t\t\t\t\"The contact doesn't exists! Enter another name:\",\n\t\t\t\ttrue\n\t\t\t)\n\t\t\tif (!contactNameToDelete) continue\n\n\t\t\tconst contactToDelete = contacts.findIndex((value) => value.name.toUpperCase() === contactNameToDelete.toUpperCase())\n\t\t\tcontacts.splice(contactToDelete, 1)\n\n\t\t\tconsole.log('Contact deleted!')\n\t\t\tbreak\n\n\t\tcase 'EXIT':\n\t\t\tconsole.log('Program finished!')\n\t\t\texit = true\n\t\t\tbreak\n\n\t\tdefault:\n\t\t\tbreak\n\t}\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/typescript/ialmontedr0.ts",
    "content": "/**\r\n * Creacion de todas las estructuras soportadas por defecto en Typescript.\r\n */\r\n\r\n/**\r\n * Arrays\r\n */\r\n\r\n// Array de strings\r\nconst cadenas: string[] = [\"Hola\", \"Mundo\", \"TypeScript\"];\r\n\r\n// Array de numeros\r\nconst numeros: number[] = [1, 2, 3, 4, 5];\r\n\r\n// Array de objetos (con la misma estructura)\r\nconst Personas = [\r\n  {\r\n    nombre: \"Juan\",\r\n    edad: 25,\r\n    direccion: \"Calle 123\",\r\n  },\r\n  {\r\n    nombre: \"Ana\",\r\n    edad: 30,\r\n    direccion: \"Calle 456\",\r\n  },\r\n];\r\n\r\n/**\r\n * Sets\r\n */\r\n\r\n// Set de strings\r\nconst setCadenas = new Set([\"Hola\", \"Mundo\", \"TypeScript\"]);\r\n\r\n// Set de numeros\r\n\r\nconst setNumeros = new Set([1, 2, 3, 4, 5]);\r\n\r\n// Set de objetos (con la misma estructura)\r\n\r\nconst setPersonas = new Set([\r\n  {\r\n    nombre: \"Juan\",\r\n    edad: 25,\r\n    direccion: \"Calle 123\",\r\n  },\r\n  {\r\n    nombre: \"Ana\",\r\n    edad: 30,\r\n    direccion: \"Calle 456\",\r\n  },\r\n]);\r\n\r\n/**\r\n * Maps\r\n */\r\n\r\n// Map de strings como llaves y numeros como valores\r\n\r\nconst mapCadenasNumeros = new Map([\r\n  [\"Hola\", 1],\r\n  [\"Mundo\", 2],\r\n  [\"TypeScript\", 3],\r\n]);\r\n\r\n// Map de objetos (con la misma estructura) como llaves y strings como valores\r\n\r\nconst mapPersonasCadenas = new Map([\r\n  [\r\n    {\r\n      nombre: \"Juan\",\r\n      edad: 25,\r\n      direccion: \"Calle 123\",\r\n    },\r\n    \"Persona 1\",\r\n  ],\r\n  [\r\n    {\r\n      nombre: \"Ana\",\r\n      edad: 30,\r\n      direccion: \"Calle 456\",\r\n    },\r\n    \"Persona 2\",\r\n  ],\r\n]);\r\n\r\n/**\r\n * Operaciones de inserción, borrado, actualización y ordenación\r\n */\r\n\r\n// Insercion\r\n// Arrays\r\nstrings.push(\"Nueva cadena\");\r\nnumbers.push(6);\r\n\r\n// Sets\r\nsetStrings.add(\"Nueva cadena\");\r\nsetNumbers.add(6);\r\n\r\n// Maps\r\nmapStringsNumbers.set(\"Nueva cadena\", 4);\r\nmapPersonasStrings.set(\r\n  {\r\n    nombre: \"Jose\",\r\n    edad: 35,\r\n    direccion: \"Calle 789\",\r\n  },\r\n  \"Persona 3\"\r\n);\r\n\r\n// Borrado\r\n// Arrays\r\nstrings.splice(strings.indexOf(\"Nueva cadena\"), 1);\r\nnumbers.splice(numbers.indexOf(6), 1);\r\n\r\n// Sets\r\nsetStrings.delete(\"Nueva cadena\");\r\nsetNumbers.delete(6);\r\n\r\n// Maps\r\nmapStringsNumbers.delete(\"Nueva cadena\");\r\nmapPersonasStrings.delete({\r\n  nombre: \"Jose\",\r\n  edad: 35,\r\n  direccion: \"Calle 789\",\r\n});\r\n\r\n// Actualización\r\n// Arrays\r\n\r\nstrings[strings.indexOf(\"Hola\")] = \"Nuevo Hola\";\r\n\r\n// Sets\r\nsetStrings.forEach((value, key, set) => {\r\n  if (value === \"Hola\") {\r\n    set.delete(value);\r\n    set.add(\"Nuevo Hola\");\r\n  }\r\n});\r\n\r\n// Maps\r\nmapStringsNumbers.forEach((value, key, map) => {\r\n  if (key === \"Hola\") {\r\n    map.delete(key);\r\n    map.set(\"Hola\", 5);\r\n  }\r\n});\r\n\r\n// Ordenación\r\n// Arrays\r\n\r\nstrings.sort();\r\nnumbers.sort((a, b) => b - a);\r\n\r\n// Sets\r\nconst sortedSetStrings = new Set([...setStrings].sort());\r\nconst sortedSetNumbers = new Set([...setNumbers].sort((a, b) => b - a));\r\n\r\n// Maps\r\nconst sortedMapStringsNumbers = new Map([...mapStringsNumbers].sort());\r\nconst sortedMapPersonasStrings = new Map([...mapPersonasStrings].sort());"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/typescript/jesusEs1312.ts",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\n// Arrays\nlet stringArray: string[]   = [\"Spider Man\", \"Batman\"];// Type String\nlet numberArray: number[]   = [1, 2, 3, 4, 5];// Type number\nlet booleanArray: boolean[] = [true, false];// Type boolean\nlet readOnlyArray: readonly string[] = [\"Hello\", \"World\"];// Type ReaonlyArray<string>\nlet obj: any = { x:0 };// Type Any (Special Type)\n\nconsole.log(\"Array inicial: \" + stringArray);\n\n//--- push (Add new element to the end)\nstringArray.push(\"Super Man\");\nconsole.log(\"Agregar un elemento (push): \" + stringArray);\n\n//--- Pop (Removes the last element from an array and returns it)\nconsole.log(\"Eliminar un elemento (pop): \" + stringArray.pop()); \n\n//--- sort\nstringArray.sort();\nconsole.log(\"Array ordenado (sort): \" + stringArray);\n\n//--- Tuple Type\ntype stringNumberPair = [string, number];// Tuple type of string and number \n\nfunction doSomething(stringNumberPair: [string, number]): string {\n    const a = stringNumberPair[0];// const a: string\n    const b = stringNumberPair[1];// const b: number\n    return a + b;\n}\n\nconsole.log(\n    doSomething([\"Hello \", 13])\n);\n\n/**\n * StringNumberBooleans describes a tuple whose first two elements are string and number respectively, \n * but which may have any number of booleans following.\n */\ntype StringNumberBooleans = [string, number, ...boolean[]];\nconst a: StringNumberBooleans = [\"hello\", 1];\nconst b: StringNumberBooleans = [\"beautiful\", 2, true];\nconst c: StringNumberBooleans = [\"world\", 3, true, false, true, false, true];\n    \nconsole.log(a);\n\n//--- Set\nconst setA: Set<number> = new Set([1,2,3]);\nconst setB: Set<number> = new Set([4,5,3]);\n\n//--- Map\nconst mapA: Map<number, string> = new Map([\n    [1, \"one\"],\n    [2, \"two\"],\n    [4, \"four\"]\n]);\n\n//--- EXTRA\nconst numberRegexp = /^[0-9]+$/;\n\ninterface NumberValidation {\n    isAcceptable(s: string): boolean;\n}\n\nexport class Contact implements NumberValidation{\n    public name: string | null = \"\";\n    public cel:  string | null = \"\";\n    \n    isAcceptable(s: string | null): boolean {\n        return (s?.length == 11 || s?.length == 10) && numberRegexp.test(s);\n    }\n\n\n}\n\n//Map de contactos\nlet contacts: Map<string | null, Contact> = new Map();\n\n//--- Agregar contacto\nfunction addContact(): void {\n    let name: string | null = \"\" ; \n    let cel:  string | null = \"\";\n    let contact = new Contact();\n\n    name = prompt(\"Escribe el nombre del contacto:\");\n    \n    do{\n        if(cel != \"\"){\n            alert(\"El celular no es correcto, intenta de nuevo\");\n        }\n        cel  = prompt(\"Escribe el celular del contacto (Solo numeros y menos de 11 digitos)\");\n    } while(!contact.isAcceptable(cel));\n    \n\n    contact.name = name;\n    contact.cel  = cel;\n    contacts.set(name, contact);//Agregamos el contacto\n    alert(\"¡Se agrego el contacto exitosamente!\");\n    console.log(contacts);\n}\n\n//--- Encontrar contacto por nombre\nfunction findContactByName(): void {\n    let nameFind: string | null;\n    let contactFind: Contact | undefined = new Contact();\n    nameFind = prompt(\"Ingresa el nombre del contacto a buscar:\");\n    contactFind = contacts.get(nameFind);\n    if (contactFind == undefined) {\n        alert(\"¡No se encontro el nombre!\");\n    } else {\n        alert(\n            \"Nombre: \" + contactFind.name?.concat(\" \\n\") +\n            \"Celular: \" + contactFind.cel\n        );\n    }\n}\n\nfunction updateContactByName(): void {\n    //Contacto a actualizar\n    let contactUpdate: Contact = new Contact();\n    let nameUpdate: string | null = \"\";\n    let celUpdate: string | null = \"\";\n    let nameFind: string | null = \"\";\n    let contactFind: Contact | undefined = new Contact();\n\n    nameFind = prompt(\"Ingresa el nombre del contacto que quieres actualizar:\");\n    contactFind = contacts.get(nameFind);\n    if(contactFind == undefined){\n        alert(\"¡No se encontro el nombre del contacto\");\n    } else {\n        nameUpdate = prompt(\"Ingresa el nuevo nombre:\");\n        do{\n            if(celUpdate != \"\"){\n                alert(\"El celular no es correcto, intenta de nuevo\");\n            }\n            celUpdate  = prompt(\"Escribe el celular del contacto (Solo numeros y menos de 11 digitos)\");\n        } while(!contactFind.isAcceptable(celUpdate));\n\n        contactUpdate.name = nameUpdate;\n        contactUpdate.cel  = celUpdate;\n        contacts.set(nameUpdate, contactUpdate);\n        contacts.delete(nameFind);\n        alert(\"¡Contacto actualizado exitosamente!\");\n    }\n}\n\nfunction deleteContactByName(): void {\n    let nameFind: string | null = \"\";\n    nameFind = prompt(\"Ingresa el nombre a eliminar:\");\n    if(contacts.delete(nameFind)){\n        alert(`¡El contacto ${nameFind} se elimino exitosamente!`);\n    } else {\n        alert(`¡El contacto ${nameFind} no existe¡`);\n    }\n}\n\nfunction findAllContacts(): void {\n    let numberContact: number = 1;\n    contacts.forEach((contact) => {\n        alert(\n            numberContact + \".-\\n\" + \n            \"Name: \" + contact.name + \"\\n\" +\n            \"Cel: \"  + contact.cel + \"\\n\"\n        );\n        numberContact++;\n    });\n}\n\nfunction agendaApp(): void {\n    let option: string | null= \"\";\n    const menu: string = \"Menu: \\n 1. Agregar \\n 2. Buscar \\n 3. Actualizar \\n 4. Eliminar \\n 5. Listar contactos \\n 6. Salir\";\n\n    while(option !== '6') {\n        option = prompt(menu);\n        switch(option){\n            case '1':\n                addContact();\n                break;\n            case '2':\n                findContactByName();\n                break;\n            case '3':\n                updateContactByName();\n                break;\n            case '4':\n                deleteContactByName();\n                break;\n            case '5':\n                findAllContacts();\n                break;\n            case '6':\n                alert(\"Bye\");\n                break;\n            default:\n                alert(\"¡Opcion no valida!\");\n                break;\n        }\n    }\n}\n\nagendaApp();\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/typescript/juserdev.ts",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\n//OBJETO\ninterface Person {\n    names: string;\n    age: number;\n}\n\nlet persona1: Person = {\n    names: \"Sebastian Rodriguez\",\n    age: 33,\n}\n\nconsole.log(persona1)\nconsole.log(`La edad de ${persona1.names} es de ${persona1.age} años`)\n\ninterface Person { //insercion opcional directo en interface\n    city?: string\n}\n\npersona1.city = \"Barranquilla\"\nconsole.log(persona1)\nconsole.log(`La edad de ${persona1.names} es de ${persona1.age} años y su ciudad es en ${persona1.city}`)\n\npersona1.age = 34 //actualizacion\nconsole.log(`Cambiamos la edad de persona1, antes era 33 y ahora es: ${persona1.age}`)\n\npersona1[\"hobby\"] = \"Tocar la guitarra\" // insercion directa \nconsole.log(persona1)\n\ndelete persona1.city //borre la propiedad city de persona1\nconsole.log(persona1)\n\n\n// ARRAY\n\nconst myArray: number[] = [1,2,3,4,5] // este es un array de numeros\nconsole.log(myArray)\n\nmyArray.push(6) //push se utiliza para agregar\nconsole.log(myArray)\n\nconst lastElement = myArray.pop() //ELIMINA EL ULTIMO ELEMENTO DEL ARRAY\nconsole.log(lastElement)\nconsole.log(myArray)\n\nconst firstElement = myArray.shift() // ELIMINA EL PRIMER ELEMENTO DEL ARRAY\nconsole.log(firstElement)\nconsole.log(myArray)\n\nmyArray.unshift(0,1) // AGREGA 1 O VARIOS ELEMENTOS AL COMIENZO DEL ARRAY\nconsole.log(myArray)\n\nmyArray.splice(1, 0, 10) //agrega un elemento en la posicion deseada\nconsole.log(myArray)\n\nmyArray.splice(1, 1) // ELIMINA UN ELEMENTO EN LA POSICION DESEADA\nconsole.log(myArray)\n\nmyArray.sort() // ORDENA EN EL ARRAY EN ORDEN ACENDENTE\nconsole.log(myArray)\n\nmyArray.reverse() // INVIERTE EL ORDEN DE LOS ELEMENTOS\nconsole.log(myArray)\n\n// CLASES = MAPS\n\nconst myMap = new Map<string, number>() // CREACION DE CLASE\n\nmyMap.set(\"sebastian\", 30) //INSERCION CON .SET\nmyMap.set(\"laura\", 31)\nconsole.log(myMap)\n\nlet laura = myMap.get(\"laura\") // BUSQUEDA\nconsole.log(laura)\n\nmyMap.delete(\"laura\") // ELIMINA UNA CLASE DEL MAP\nconsole.log(myMap)\n\n// VERIFICA SI EXISTE LA CLASE\nconsole.log(myMap.has(\"sebastian\"))\nconsole.log(myMap.has(\"laura\"))\n\nconsole.log(myMap.size) // CON SIZE PUEDO SABER EL TAMAÑO DEL MAP\n\n// SET\n\nconst mySet = new Set<number>([1,2,3,4,5])\nconsole.log(mySet)\n\nmySet.add(6) // INSERCION\nconsole.log(mySet)\nmySet.add(5) // NO ACEPTA DUPLICACIONES\nconsole.log(mySet)\n\nmySet.delete(2) //BORRA\nconsole.log(mySet)\n\nconsole.log(mySet.has(2)) // VERIFICA SI CONTIENE EL ELEMENTO Y DEVUELVE TRUE O FALSE\nconsole.log(mySet.has(4)) // VERIFICA SI CONTIENE EL ELEMENTO Y DEVUELVE TRUE O FALSE\n\nconsole.log(mySet.size) // MUESTRA EL TAMAÑO DE SET\n\nmySet.clear() // LIMPIA TODO EL SET\nconsole.log(mySet)\nconsole.log(mySet.size)\n\n// EXTRA - AGENDA DE CONTACTOS\n\nconst readline = require(\"readline\")!\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n})\n\nconst contactos = new Map<string, string>()\n\nconst addContact = ()=>{\n    rl.question(\"Escriba su nombre: \", (nombre:string)=>{\n        rl.question(\"Escriba su numero de celular: \", (celular:string)=>{\n            const regex = /^\\d{1,9}$/;\n            if (contactos.has(nombre)) {\n                console.log(\"El contacto ya existe\")\n                console.log(\"\")\n                addContact()\n            }else {\n                if (!regex.test(celular)) {\n                    contactos.set(nombre, celular)\n                    console.log(\"\")\n                    console.log(`Contacto nuevo: ${nombre}: ${contactos.get(nombre)}`)\n                    console.log(\"\")\n                    console.log(`Tienes \"${contactos.size}\" contactos`)\n                    console.log(\"\")\n                    agenda()\n                } else{\n                    console.log(\"esta errado\")\n                    addContact()\n                }\n            }\n            \n        })\n    })\n}\n\nconst searchContacts = ()=>{\n    rl.question(\"Escribe el nombre del contacto que deseas buscar: \",(nombre: string)=>{\n        if (contactos.has(nombre)) {\n            console.log(\"\")\n            console.log(`nombre: ${nombre}`)\n            console.log(`telefono: ${contactos.get(nombre)}`)\n            console.log(\"\")\n            agenda()\n        } else{\n            console.log(\"el contacto no existe\")\n            agenda()\n        }\n    })\n}\n\nconst deleteContact = ()=>{\n    console.table(contactos)\n    console.log(\"\")\n    if (contactos.size === 0) {\n        console.log(\"no hay contactos para eliminar\")\n        console.log(\"\")\n        agenda()\n    } else{\n        rl.question(\"Escriba el nombre del contacto que desea eliminar: \", (nombre:string)=>{\n            let deleteContact = nombre\n            contactos.delete(nombre)\n            console.log(\"\")\n            console.table(contactos)\n            console.log(\"\")\n            console.log(`Contacto \"${deleteContact}\" eliminado`)\n            agenda()\n        })\n    }\n}\n\nconst replaceContact = ()=>{\n    rl.question(\"Cual es el contacto que deseas reemplazar: \", (nombre: string)=>{\n        let usuario: string = nombre\n        let telefono = contactos.get(nombre)\n        console.log(\"\")\n        if (contactos.has(nombre)) {\n            console.log(`${usuario}: ${telefono}`)\n            console.log(\"\")\n            rl.question(\"que deseas reemplazar, nombre o telefono: \", (opcion: string)=>{\n                if (opcion === \"nombre\") {\n                    contactos.delete(nombre)\n                    console.log(\"\")\n                    rl.question(\"cual es el nuevo nombre: \", (nuevoNombre: string)=>{\n                        contactos.set(nuevoNombre, telefono!)\n                        console.table(contactos)\n                        console.log(\"contacto reemplazado\")\n                        console.log(\"\")\n                        agenda()\n                    })\n                } else if (opcion === \"telefono\") {\n                    contactos.delete(nombre)\n                    console.log(\"\")\n                    rl.question(\"cual es el nuevo telefono: \", (nuevoTelefono: string)=>{\n                        contactos.set(usuario, nuevoTelefono)\n                        console.table(contactos)\n                        console.log(\"contacto reemplazado\")\n                        console.log(\"\")\n                        agenda()\n                    })\n                }\n            })\n        } else {\n            console.log(`El contacto ${nombre} no existe`)\n            console.log(\"\")\n            agenda()\n        }\n    })\n}\n\nconst viewContact = ()=>{\n    console.table(contactos)\n    console.log(\"\")\n    console.log(`Total contactos: ${contactos.size}`)\n    console.log(\"\")\n    agenda()\n}\n\nconst agenda = ()=>{\n    console.log(\"BIENVENIDO A TU AGENDA DE CONTACTOS\")\n    console.log(\"\")\n    rl.question(`Que deseas hacer ahora:\n        1. Agregar contacto\n        2. Buscar contacto\n        3. Eliminar contacto\n        4. Reemplazar contacto\n        5. Mostrar contactos\n        6. Salir\n    \n        `,(numero:string) =>{\n            switch (numero) {\n                case \"1\":\n                    addContact()\n                    break;\n                case \"2\":\n                    searchContacts()\n                    break\n                case \"3\":\n                    deleteContact()\n                    break\n                case \"4\":\n                    replaceContact()\n                    break\n                case \"5\":\n                    viewContact()\n                    break\n                case \"6\":\n                    rl.close()\n                default:\n                    break;\n            }\n        })\n}\n\nagenda()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/typescript/kodenook.ts",
    "content": "\n/*\n    Array\n*/\n\nlet fruits: string[] = ['apple', 'orange', 'banana']\n\n// insert\n\nfruits.push('mango')\nfruits[4] = 'grapes'\nfruits.unshift('lemon')\n\nconsole.log(fruits)\n\n// edit\n\nfruits[1] = 'grapes'\n\nconsole.log(fruits)\n\n// delete\n\nfruits.pop()\nfruits.shift()\ndelete fruits[3]\n\nconsole.log(fruits)\n\n/*\n    Sets\n*/\n\nlet letters = new Set(['a', 'b', 'c'])\n\n// insert\n\nletters.add('f')\n\nconsole.log(letters)\n\n// delete\n\nletters.delete('b')\n\nconsole.log(letters)\n\n/*\n    Tuples\n*/\n\nlet employee: [number, string] = [1, 'steve']\n\n// insert\n\nemployee.push(2, 'bill')\nemployee.unshift(3, 'david')\n\n\nconsole.log(employee)\n\n// edit\n\nemployee[1] = 'jeff'\n\nconsole.log(employee)\n\n// delete\n\nemployee.shift()\nemployee.pop()\n\nconsole.log(employee)\n\n/*\n    Maps\n*/\n\nlet person = new Map<string, string>([\n    ['name', 'kodenook'],\n    ['country', 'chile']\n])\n\n// insert\n\nperson.set('continent', '')\n\nconsole.log(person)\n\n// insert\n\nperson.set('continent', 'america')\n\nconsole.log(person)\n\n// delete\n\nperson.delete('continent')\n\nconsole.log(person)"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/typescript/marcode24.ts",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\n// Ejemplos de estructuras de datos\n\n// Arrays\nconst arrayEjemplo: number[] = [1, 2, 3, 4, 5];\nconsole.log(\"Array original:\", arrayEjemplo);\n\n// Inserción\narrayEjemplo.push(6);\nconsole.log(\"Array después de la inserción:\", arrayEjemplo);\n\n// Borrado\narrayEjemplo.pop();\nconsole.log(\"Array después del borrado:\", arrayEjemplo);\n\n// Actualización\narrayEjemplo[0] = 10;\nconsole.log(\"Array después de la actualización:\", arrayEjemplo);\n\n// Ordenación\nconst arrayOrdenado: number[] = [...arrayEjemplo].sort();\nconsole.log(\"Array ordenado:\", arrayOrdenado);\n\n// Objetos\ninterface ObjetoEjemplo {\n  nombre: string;\n  edad: number;\n  ciudad: string;\n}\n\nconst objetoEjemplo: ObjetoEjemplo = { nombre: \"Juan\", edad: 25, ciudad: \"Barcelona\" };\nconsole.log(\"Objeto original:\", objetoEjemplo);\n\n// Inserción/Actualización\nobjetoEjemplo.profesion = \"Ingeniero\";\nconsole.log(\"Objeto después de la inserción/actualización:\", objetoEjemplo);\n\n// Borrado\ndelete objetoEjemplo.edad;\nconsole.log(\"Objeto después del borrado:\", objetoEjemplo);\n\n// Visita mi repo en GitHub para ver y correr los tests de este código --> https://github.com/marcode24/weekly-challenges\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/typescript/markc1234.ts",
    "content": "(() => {    \n    // EJERCICIO:\n    // Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n    // array\n    const arr:number[] = [1,2,3,4]\n    const arr2: Array<string> = [\"a\", \"e\", \"i\", \"o\", \"u\"]\n\n    // tupla\n    const tup1: [number, string, boolean] = [10, \"cadena\", true]\n\n    // enum\n    enum DiasSemana {\n        \"LUNES\"= \"lunes\",\n        \"MARTES\"= \"martes\",\n        \"MIERCOLES\"= \"miercoles\",\n        \"JUEVES\"= \"jueves\",\n        \"VIERNES\"= \"viernes\",\n        \"SABADO\"= \"sabado\",\n        \"DOMINGO\"= \"domingo\",\n    }\n\n    // interface (objetos)\n    interface Person {\n        name: string;\n        age: number;\n    }\n    let person: Person = { name: \"Fabricio\", age: 20 };\n    \n    // clases\n    class Animal {\n        name: string;\n        constructor(name: string) {\n            this.name = name;\n        }\n        move(distance: number = 0) {\n            console.log(`${this.name} moved ${distance} meters.`);\n        }\n    }\n    let dog = new Animal(\"Dog\");\n    dog.move(10);\n\n    // genericos\n    function identity<T>(arg: T): T {\n        return arg;\n    }\n    let output = identity<string>(\"myString\");\n    \n    // maps y sets\n    let map = new Map<string, number>();\n    map.set(\"one\", 1);\n    map.set(\"two\", 2);\n\n    let set = new Set<number>();\n    set.add(1);\n    set.add(2);\n\n    // union types\n    let union: string | number;\n    union = \"hello\";\n    union = 42;\n\n    // intersection types\n    interface Name {\n        name: string;\n    }\n    interface Age {\n        age: number;\n    }\n    type PersonType = Name & Age;\n    let personIntersection: PersonType = { name: \"Alice\", age: 25 };\n\n    // Utiliza operaciones de inserción, borrado, actualización y ordenación.\n    arr2.push(\"A\", \"E\", \"I\", \"O\", \"U\")\n    arr.pop()\n\n    \n    // DIFICULTAD EXTRA (opcional):\n    // Crea una agenda de contactos por terminal.\n    // Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n    // Cada contacto debe tener un nombre y un número de teléfono.\n    // El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación los datos necesarios para llevarla a cabo.\n    // El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos. (o el número de dígitos que quieras)\n    // También se debe proponer una operación de finalización del programa.\n})()"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/typescript/miguelangelmz21.ts",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto\n *   en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n *   y a continuación los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no numéricos y con más\n *   de 11 dígitos (o el número de dígitos que quieras).\n * - También se debe proponer una operación de finalización del programa.\n */\n\n// Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n    let arr: number[] = [1, 2, 3, 4, 5]; // Array de números\n    console.log(\"Array original:\", arr);            \n    let arr2: string[] = [\"A\", \"B\", \"C\"]; // Array de cadenas de texto\n    console.log(\"Array de cadenas:\", arr2);\n    let arr3: boolean[] = [true, false, true]; // Array de boolean\n    console.log(\"Array de booleanos:\", arr3);\n    let arr4: (number | string)[] = [1, \"dos\", 3, \"cuatro\"]; // Array de números y cadenas\n    console.log(\"Array mixto:\", arr4);\n    let arr5: Array<number> = new Array(1, 2, 3); // Otra forma de crear un array de números\n    console.log(\"Array creado con el constructor:\", arr5);\n    let arr6: Array<string> = new Array(\"A\", \"B\", \"C\"); // Otra forma de crear un array de cadenas\n    console.log(\"Array de cadenas creado con el constructor:\", arr6);\n    let arr7: Array<boolean> = new Array(true, false, true); // Otra forma de crear un array de booleanos\n    console.log(\"Array de booleanos creado con el constructor:\", arr7);\n    let obj: { [key: string]: number } = { \"uno\": 1, \"dos\": 2, \"tres\": 3 }; // Objeto con claves y valores numéricos\n    console.log(\"Objeto original:\", obj);\n    let set: Set<string> = new Set([\"A\", \"B\", \"C\"]); // Set de cadenas de texto\n    console.log(\"Set original:\", set);\n    let map: Map<string, number> = new Map([[\"uno\", 1], [\"dos\", 2], [\"tres\", 3]]); // Mapa con claves de tipo cadena y valores numéricos\n    console.log(\"Mapa original:\", map);\n\n// Utiliza operaciones de inserción, borrado, actualización y ordenación.\n    arr.push(6); // Inserción\n    console.log(\"Array después de insertar 6:\", arr);\n    arr.splice(0, 1); // Borrado\n    console.log(\"Array después de borrar el primer elemento:\", arr);\n    arr[0] = 10; // Actualización\n    console.log(\"Array después de actualizar el primer elemento a 10:\", arr);\n    arr.sort((a, b) => a - b); // Ordenación\n    console.log(\"Array después de ordenar:\", arr);\n    obj[\"cuatro\"] = 4; // Inserción\n    console.log(\"Objeto después de insertar 'cuatro':\", obj);\n    delete obj[\"dos\"]; // Borrado\n    console.log(\"Objeto después de borrar 'dos':\", obj);\n    obj[\"uno\"] = 11; // Actualización\n    console.log(\"Objeto después de actualizar 'uno' a 11:\", obj);\n    set.add(\"D\"); // Inserción\n    console.log(\"Set después de insertar 'D':\", set);\n    set.delete(\"B\"); // Borrado\n    console.log(\"Set después de borrar 'B':\", set);\n    set.forEach(value => console.log(\"Valor en el set:\", value)); // Iteración\n    map.set(\"cuatro\", 4); // Inserción\n    console.log(\"Mapa después de insertar 'cuatro':\", map);\n    map.delete(\"dos\"); // Borrado\n    console.log(\"Mapa después de borrar 'dos':\", map);    \n    map.set(\"uno\", 11); // Actualización\n    console.log(\"Mapa después de actualizar 'uno' a 11:\", map);\n\n// DIFICULTAD EXTRA (opcional):\n\n//  Crea una agenda de contactos por terminal.    \n//  - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n//  - Cada contacto debe tener un nombre y un número de teléfono.   \n\n//  - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n//    y a continuación los datos necesarios para llevarla a cabo.\n//  - El programa no puede dejar introducir números de teléfono no numéricos y con más\n//    de 11 dígitos (o el número de dígitos que quieras).\n//  - También se debe proponer una operación de finalización del programa.\n\n//  - El programa solicita en primer lugar cuál es la operación que se quiere realizar,\n//    y a continuación los datos necesarios para llevarla a cabo.\n//  - El programa no puede dejar introducir números de teléfono no numéricos y con más\n//    de 11 dígitos (o el número de dígitos que quieras).\n//  - También se debe proponer una operación de finalización del programa.\nlet agenda: Map<string, string> = new Map();\nfunction isValidPhoneNumber(phone: string): boolean {\n    const phoneRegex = /^\\d{1,11}$/; // Validación de números de teléfono de hasta 11 dígitos\n    return phoneRegex.test(phone);\n}\nfunction showMenu() {\n    console.log(\"Seleccione una operación:\");\n    console.log(\"1. Insertar contacto\");\n    console.log(\"2. Actualizar contacto\");\n    console.log(\"3. Eliminar contacto\");\n    console.log(\"4. Buscar contacto\");\n    console.log(\"5. Mostrar agenda\");\n    console.log(\"6. Salir\");\n}\nfunction insertContact(name: string, phone: string) {\n    if (isValidPhoneNumber(phone)) {\n        agenda.set(name, phone);\n        console.log(`Contacto ${name} insertado con éxito.`);\n    } else {\n        console.log(\"Número de teléfono no válido.\");\n    }\n}\nfunction updateContact(name: string, phone: string) {\n    if (agenda.has(name)) {\n        if (isValidPhoneNumber(phone)) {\n            agenda.set(name, phone);\n            console.log(`Contacto ${name} actualizado con éxito.`);\n        } else {\n            console.log(\"Número de teléfono no válido.\");\n        }\n    } else {\n        console.log(`Contacto ${name} no encontrado.`);\n    }\n}\nfunction deleteContact(name: string) {\n    if (agenda.has(name)) {\n        agenda.delete(name);\n        console.log(`Contacto ${name} eliminado con éxito.`);\n    } else {\n        console.log(`Contacto ${name} no encontrado.`);\n    }\n}\nfunction searchContact(name: string) {\n    if (agenda.has(name)) {\n        console.log(`Contacto encontrado: ${name} - ${agenda.get(name)}`);\n    } else {\n        console.log(`Contacto ${name} no encontrado.`);\n    }\n}\nfunction showAgenda() {\n    if (agenda.size > 0) {\n        console.log(\"Agenda de contactos:\");\n        agenda.forEach((phone, name) => {\n            console.log(`${name}: ${phone}`);\n        });\n    } else {\n        console.log(\"La agenda está vacía.\");\n    }\n}\nfunction main(): void {\n    showMenu();\n\n    const operation = prompt(\"Seleccione una operación (1-6):\");\n\n    switch (operation) {\n        case '1': {\n            const name = prompt(\"Ingrese el nombre del contacto:\");\n            const phone = prompt(\"Ingrese el número de teléfono:\");\n            if (name && phone) {\n                insertContact(name, phone);\n            }\n            main();\n            break;\n        }\n        case '2': {\n            const name = prompt(\"Ingrese el nombre del contacto a actualizar:\");\n            const phone = prompt(\"Ingrese el nuevo número de teléfono:\");\n            if (name && phone) {\n                updateContact(name, phone);\n            }\n            main();\n            break;\n        }\n        case '3': {\n            const name = prompt(\"Ingrese el nombre del contacto a eliminar:\");\n            if (name) {\n                deleteContact(name);\n            }\n            main();\n            break;\n        }\n        case '4': {\n            const name = prompt(\"Ingrese el nombre del contacto a buscar:\");\n            if (name) {\n                searchContact(name);\n            }\n            main();\n            break;\n        }\n        case '5':\n            showAgenda();\n            main();\n            break;\n        case '6':\n            console.log(\"Saliendo del programa.\");\n            break;\n        default:\n            console.log(\"Operación no válida. Intente nuevamente.\");\n            main();\n    }\n}\n// Iniciar el programa\nconsole.log(\"Bienvenido a la agenda de contactos.\");\nmain();"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/typescript/miguelex.ts",
    "content": "// Ejemplo de array\n\nlet array: number[] = [1, 2, 3, 4, 5];\nconsole.log(array);\n\n// Añadiendo un elemento al final del array\n\narray.push(6);\nconsole.log(array);\n\n// Añadiendo un elemento al principio del array\n\narray.unshift(0);\nconsole.log(array);\n\n// Añadir en un índice concreto\n\narray.splice(3, 0, 3.5);\nconsole.log(array);\n\n// Eliminar el último elemento del array\n\narray.pop();\nconsole.log(array);\n\n// Eliminar el primer elemento del array\n\narray.shift();\nconsole.log(array);\n\n// Eliminar un elemento en un índice concreto\n\narray.splice(3, 1);\nconsole.log(array);\n\n// Ejemplo de objeto\n\nlet objeto: { [key: string]: string | number } = {\n    nombre: \"Miguel\",\n    apellidos: \"Delgado\",\n    edad: 20\n}\n\nconsole.log(objeto);\n\n// Añadir campo a un objeto\n\nobjeto.direccion = \"Calle falsa 123\";\nconsole.log(objeto);\n\n// Eliminar campo de un objeto\n\ndelete objeto.edad;\nconsole.log(objeto);\n\n// Ejemplo de map\n\nlet mapa: Map<string, string | number> = new Map();\n\nmapa.set(\"nombre\", \"Miguel\");\nmapa.set(\"apellidos\", \"Delgado\");\nmapa.set(\"edad\", 20);\n\nconsole.log(mapa);\n\n// Añadir al mapa\n\nmapa.set(\"direccion\", \"Calle falsa 123\");\nconsole.log(mapa);\n\n// Eliminar del mapa\n\nmapa.delete(\"edad\");\nconsole.log(mapa);\n\n// Ejemplo de set\n\nlet set: Set<string | number> = new Set();\n\nset.add(\"Miguel\");\nset.add(\"Delgado\");\nset.add(20);\n\nconsole.log(set);\n\n// Añadir al set\n\nset.add(\"Calle falsa 123\");\nconsole.log(set);\n\n// Eliminar del set\n\nset.delete(20);\nconsole.log(set);\n\n// Extra\n\nimport readline from 'readline';\n\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout\n});\n\nconst agenda: { [key: string]: string } = {};\n\nfunction validarNumeroTelefono(numero: string): boolean {\n  return /^\\d{1,11}$/.test(numero);\n}\n\nfunction ejecutarPrograma(): void {\n  rl.question('¿Qué operación deseas realizar? (buscar, insertar, actualizar, eliminar, salir): ', (operacion: string) => {\n    operacion = operacion.toLowerCase();\n\n    if (operacion === 'salir') {\n      console.log('Saliendo del programa. ¡Hasta luego!');\n      rl.close();\n    } else if (operacion === 'buscar') {\n      rl.question('Ingrese el nombre del contacto a buscar: ', (nombre: string) => {\n        if (agenda[nombre]) {\n          console.log(`Nombre: ${nombre}, Teléfono: ${agenda[nombre]}`);\n        } else {\n          console.log(`El contacto \"${nombre}\" no se encuentra en la agenda.`);\n        }\n        ejecutarPrograma(); \n      });\n    } else if (operacion === 'insertar') {\n        rl.question('Ingrese el nombre del nuevo contacto: ', (nombre: string) => {\n        rl.question('Ingrese el número de teléfono del nuevo contacto: ', (telefono: string) => {\n          if (validarNumeroTelefono(telefono)) {\n            agenda[nombre] = telefono;\n            console.log(`Contacto \"${nombre}\" insertado correctamente.`);\n          } else {\n            console.log('Número de teléfono no válido. Debe ser numérico y tener entre 1 y 11 dígitos.');\n          }\n          ejecutarPrograma(); \n        });\n      });\n    } else if (operacion === 'actualizar') {\n        rl.question('Ingrese el nombre del contacto a actualizar: ', (nombre: string) => {\n        if (agenda[nombre]) {\n          rl.question('Ingrese el nuevo número de teléfono: ', (nuevoTelefono: string) => {\n            if (validarNumeroTelefono(nuevoTelefono)) {\n              agenda[nombre] = nuevoTelefono;\n              console.log(`Contacto \"${nombre}\" actualizado correctamente.`);\n            } else {\n              console.log('Número de teléfono no válido. Debe ser numérico y tener entre 1 y 11 dígitos.');\n            }\n            ejecutarPrograma(); \n          });\n        } else {\n          console.log(`El contacto \"${nombre}\" no se encuentra en la agenda.`);\n          ejecutarPrograma(); \n        }\n      });\n    } else if (operacion === 'eliminar') {\n        rl.question('Ingrese el nombre del contacto a eliminar: ', (nombre: string) => {\n        if (agenda[nombre]) {\n          delete agenda[nombre];\n          console.log(`Contacto \"${nombre}\" eliminado correctamente.`);\n        } else {\n          console.log(`El contacto \"${nombre}\" no se encuentra en la agenda.`);\n          ejecutarPrograma(); \n        }\n      });\n    }\n  });\n}\n\nejecutarPrograma();\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/typescript/mikelroset.ts",
    "content": "\n// --------------------------------- ARRAYS --------------------------------- //\n/* Un array es una colección ordenada de elementos. Puede contener cualquier \n * tipo de dato, incluyendo otros arrays. Los arrays se pueden declarar de \n * varias maneras, como en la siguiente línea:\n */\nconst myArray: number[] = [1, 2, 3, 4, 5];\n\n// Accediendo a elementos\nmyArray[0]; // 1\nmyArray[1]; // 2\nmyArray[2]; // 3\nmyArray[3]; // 4\nmyArray[4]; // 5\n\n// Longitud\nmyArray.length; // 5\n\n// Añadiendo elementos\nmyArray.push(6); // [1, 2, 3, 4, 5, 6]\n\n// Eliminando el último elemento\nmyArray.pop(); // [1, 2, 3, 4, 5]\n\n// Eliminando el primer elemento\nmyArray.shift(); // [2, 3, 4, 5]\n\n// Añadiendo elementos al inicio\nmyArray.unshift(0); // [0, 2, 3, 4, 5]\n\n// Cortando elementos\nmyArray.splice(2, 2); // [2, 3]\n\n// Uniendo arrays\nlet otherArray: number[] = [1, 2, 3];\nmyArray.concat(otherArray); // [1, 2, 3, 1, 2, 3]\n\n// Invirtiendo el array\nmyArray.reverse(); // [5, 4, 3, 2, 1]\n\n// Ordenando el array\nmyArray.sort(); // [1, 2, 3, 4, 5]\n\n// Buscando elementos\nmyArray.indexOf(3); // 2\nmyArray.lastIndexOf(3); // 4\n\n// Copiando array\nlet copyArray: number[] = myArray.slice(); // [1, 2, 3, 4, 5]\n\n// Copiando array con inicio y final\nlet copyArray2: number[] = myArray.slice(1, 4); // [2, 3, 4]\n\n// Copiando array con inicio y final negativos\nlet copyArray3: number[] = myArray.slice(-3, -1); // [3, 4]\n\n// Copiando array con inicio y final negativos\nlet copyArray5: number[] = myArray.slice(-3, -1); // (Error corrected) should be [3, 4]\n\n\n// --------------------------------- OBJECTS -------------------------------- //\n/* Un objeto es una colección de pares clave-valor, donde las claves son cadenas \n * de texto y los valores pueden ser cualquier tipo de dato. Los objetos se \n * pueden declarar de varias maneras, como en la siguiente línea:\n */\ntype PersonInfo = {\n  name: string;\n  age: number;\n  city?: string;\n};\nconst myObject: PersonInfo = { name: \"John\", age: 25 };\n\n// Accediendo a propiedades\nmyObject.name; // \"John\"\nmyObject.age; // 25\n\n// Longitud\nObject.keys(myObject).length; // 2\n\n// Añadiendo propiedades\nmyObject.city = \"New York\"; // { name: \"John\", age: 25, city: \"New York\" }\n\n// Eliminando propiedades\ndelete myObject.city; // { name: \"John\", age: 25 }\n\n/* Cortando propiedades: Hacer que 'age' sea opcional en la definición del \ntipo para usar delete */\nconst { age, ...rest } = myObject; // { name: \"John\" }\nconst myObjectWithoutAge = { ...rest };\n\n// Uniendo objetos\nlet otherObject: PersonInfo = { name: \"Jane\", age: 30 };\nlet combinedObject: PersonInfo = { \n  ...myObject, \n  ...otherObject \n}; // { name: \"Jane\", age: 30 }\n\n// Copiando objeto\nlet copyObject: object = myObject; // { name: \"John\", age: 25 }\n\n// Copiando objeto con propiedades\nlet copyObject2: object = Object.assign(\n  {}, \n  myObject\n); // { name: \"John\", age: 25 }\n\n// Copiando objeto con propiedades y métodos\nclass Person {\n  name: string;\n  age: number;\n  constructor(name: string, age: number) {\n    this.name = name;\n    this.age = age;\n  }\n  sayHello() {\n    console.log(`Hello, my name is ${this.name}`);\n  }\n}\nlet person = new Person(\"John\", 25);\nlet copyObject3: object = Object.assign(\n  { sayHello: person.sayHello.bind(person) }, \n  person\n); // { name: \"John\", age: 25, sayHello: [Function: sayHello] }\n\n\n// ---------------------------------- MAPAS --------------------------------- //\n/* Un Map es una colección de pares clave-valor, pero a diferencia de un objeto,\n * las claves pueden ser de cualquier tipo, no solo cadenas.\n * Los mapas preservan el orden de inserción.\n */\nconst myMap: Map<string, number> = new Map();\n\n// Accediendo a elementos\nmyMap.get(\"key\"); // undefined\n\n// Añadiendo elementos\nmyMap.set(\"key\", 10); // Map { \"key\" => 10 }\n\n// Accediendo a elementos\nmyMap.get(\"key\"); // 10\n\n// Eliminando elementos\nmyMap.delete(\"key\"); // Map {}\n\n// Copiando mapa\nlet copyMap: Map<string, number> = myMap; // Map { \"key\" => 10 }\n\n// Copiando mapa con elementos\nlet copyMap2: Map<string, number> = new Map(myMap); // Map { \"key\" => 10 }\n\n// Copiando mapa con elementos y valores\nlet copyMap3: Map<string, number> = new Map(\n  myMap.entries()\n);\n\n\n// ---------------------------------- SETS ---------------------------------- //\n/* Un Set es una colección de valores únicos. No permite duplicados y, como los \n * mapas, preserva el orden de inserción.\n */\nconst mySet: Set<number> = new Set();\n\n// Accediendo a elementos\nmySet.has(10); // false\n\n// Añadiendo elementos\nmySet.add(10); // Set { 10 }\n\n// Eliminando elementos\nmySet.delete(10); // Set {}\n\n// Copiando set\nlet copySet: Set<number> = mySet; // Set { 10 }\n\n// Copiando set con elementos\nlet copySet2: Set<number> = new Set(mySet); // Set { 10 }\n\n// Copiando set con elementos y valores\nlet copySet3: Set<number> = new Set(\n  mySet.values()\n);\n\n\n// --------------------------------- WEAKMAP -------------------------------- //\n/* Un WeakMap es similar a un Map, pero sus claves deben ser objetos. Además, \n * no previene que los objetos claves sean recolectados por el recolector de \n * basura si no tienen más referencias.\n */\n\nconst myWeakMap: WeakMap<object, string> = new WeakMap();\n\n// Accediendo a elementos\nmyWeakMap.get(myObject); // undefined\n\n// Añadiendo elementos\nmyWeakMap.set(myObject, \"Hola\"); // WeakMap { { [object Object]] => \"Hola\" }\n\n// Eliminando elementos\nmyWeakMap.delete(myObject); // WeakMap {}\n\n// Copiando mapa\nlet copyWeakMap: WeakMap<object, string> = myWeakMap; \n// WeakMap { { [object Object]] => \"Hola\" }\n\n\n// --------------------------------- WEAKSET -------------------------------- //\n/* Un WeakSet es como un Set, pero solo admite objetos como valores. Al igual \n * que el WeakMap, los objetos dentro del WeakSet pueden ser recolectados si ya \n * no hay otras referencias hacia ellos.\n */\nconst myWeakSet: WeakSet<object> = new WeakSet();\n\n// Accediendo a elementos\nmyWeakSet.has(myObject); // false\n\n// Añadiendo elementos\nmyWeakSet.add(myObject); // WeakSet { { [object Object] } }\n\n// Eliminando elementos\nmyWeakSet.delete(myObject); // WeakSet {}\n\n// Copiando set\nlet copyWeakSet: WeakSet<object> = myWeakSet; \n// WeakSet { { [object Object] } }\n\n\n// --------------------------------- ENUMS ---------------------------------- //\n/* Los enums permiten definir un conjunto de valores constantes con nombres \n * asociados a un valor (pueden ser numéricos o de cadena).\n */\nenum MyEnum {\n    FIRST = \"FIRST\",\n    SECOND = \"SECOND\"\n}\n\nconst myEnum: MyEnum = MyEnum.FIRST;\n\n// Accediendo a elementos\nMyEnum.FIRST; // \"FIRST\"\nMyEnum.SECOND; // \"SECOND\"\n\n// Copiando enum\nlet copyEnum: MyEnum = myEnum; \n// \"FIRST\"\n\n// Copiando enum con elementos\nlet copyEnum2: MyEnum = MyEnum.FIRST; \n// \"FIRST\"\n\n\n// -------------------------- BONUS EJERCICIO ------------------------------- //\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\ntype Contact = {\n  name: string;\n  phone: number;\n};\n\nclass Agenda {\n  contacts: Contact[];\n\n  constructor() {\n    this.contacts = [];\n  }\n\n  addContact(contact: Contact) {\n    this.contacts.push(contact);\n  }\n\n  findContact(name: string): Contact | undefined {\n    return this.contacts.find((contact) => contact.name === name);\n  }\n\n  updateContact(contact: Contact) {\n    const index = this.contacts.findIndex((c) => c.name === contact.name);\n    if (index !== -1) {\n      this.contacts[index] = contact;\n    } else {\n      this.addContact(contact);\n    }\n  }\n\n  deleteContact(name: string) {\n    const index = this.contacts.findIndex((c) => c.name === name);\n    if (index !== -1) {\n      this.contacts.splice(index, 1);\n    } else {\n      console.log(`${name} no existe`);\n    }\n  }\n\n  listContacts() {\n    console.log(this.contacts);\n  }\n}\n\nconst agenda = new Agenda();\nconst options: string[] = [\n  \"[1] Añadir contacto\",\n  \"[2] Buscar contacto\",\n  \"[3] Actualizar contacto\",\n  \"[4] Eliminar contacto\",\n  \"[5] Listar contactos\",\n  \"[6] Salir\",\n];\n\nconst runContactApp = (): void => {\n  const option = prompt(\n    \"Elige una opción:\\n\" +\n      options.map((o) => `  ${o}`).join(\"\\n\")\n  );\n\n  switch (option) {\n    case \"1\":\n      const addName = prompt(\"Ingrese el nombre: \");\n      if (!addName) {\n        console.log(\"Por favor ingrese un nombre válido.\");\n        break;\n      }\n\n      const addPhone = prompt(\"Ingrese el número de teléfono: \");\n      if (!addPhone) {\n        console.log(\"Por favor ingrese un número de teléfono válido.\");\n        break;\n      }\n      if (addPhone.length > 11) {\n        console.log(\"El número de teléfono debe tener 11 dígitos.\");\n        break;\n      }\n      if (!/^\\d+$/.test(addPhone)) {\n        console.log(\"El número de teléfono debe ser numérico.\");\n        break;\n      }\n      const addContact: Contact = { name: addName, phone: parseInt(addPhone) };\n      agenda.addContact(addContact);\n      break;\n      \n    case \"2\": \n      const findName = prompt(\"Ingrese el nombre del contacto a buscar: \");\n      if (!findName) {\n        console.log(\"Por favor ingrese un nombre válido.\");\n        break;\n      }\n      const findContact = agenda.findContact(findName);\n      if (findContact) {\n        console.log(findContact);\n      }\n      else {\n        console.log(`${findContact} no existe`);\n        break;\n      }\n      break;\n\n    case \"3\":\n      const updateName = prompt(\"Ingrese el nombre del contacto a actualizar: \");\n      if (!updateName) {\n        console.log(\"Por favor ingrese un nombre válido.\");\n        break;\n      }\n      const updatePhone = prompt(\"Ingrese el número de teléfono del contacto a actualizar: \");\n      if (!updatePhone) {\n        console.log(\"Por favor ingrese un número de teléfono válido.\");\n        break;\n      }\n      if (updatePhone.length > 11) {\n        console.log(\"El número de teléfono debe tener 11 dígitos.\");\n        break;\n      }\n      if (!/^\\d+$/.test(updatePhone)) {\n        console.log(\"El número de teléfono debe ser numérico.\");\n        break;\n      }\n      const updateContact: Contact = { name: updateName, phone: parseInt(updatePhone) };\n      agenda.updateContact(updateContact);\n      break;\n\n    case \"4\":\n      const deleteName = prompt(\"Ingrese el nombre del contacto a eliminar: \");\n      if (!deleteName) {\n        console.log(\"Por favor ingrese un nombre válido.\");\n        break;\n      }\n      agenda.deleteContact(deleteName);\n      break;\n\n    case \"5\":\n      agenda.listContacts();\n      break;\n\n    case \"6\":\n      break;\n\n    default:\n      console.log(\"Opción no válida. Inténtalo de nuevo.\");\n      break;\n  }\n}\n\nrunContactApp();\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/typescript/mxtrar23.ts",
    "content": "// Estructuras\n\n// Array\nconst listaFrutas = ['Manzana','Pera','Kiwi','Fresa'];\nconsole.log(listaFrutas);\n\nlistaFrutas.push('Melocotón') // Insercion\nlistaFrutas.push('Piña')\nconsole.log(listaFrutas);\n\nlistaFrutas.push('Fresa') // Eliminación\nconsole.log(listaFrutas);\n\nconsole.log(listaFrutas[2]); // Acceso\n\n\nlistaFrutas[1]='Cereza' // Actualizacion\nconsole.log(listaFrutas);\n\nlistaFrutas.sort(); // Ordenamiento\nconsole.log(listaFrutas);\n\n\n//Map\n\nlet edades = new Map()\n\nedades.set('Jorge',35) // Insercion\nedades.set('Carlos',28)\nedades.set('Emilio',15)\nconsole.log(edades);\nconsole.log(edades.size); // Tamaño\n\n\nconsole.log(edades.get('Jorge')); // Acceso\n\nedades.set('Emilio',19)// Actualización\nconsole.log(edades);\n\nedades.delete('Carlos') // Eliminación\nconsole.log(edades);\n\n\n//set\n\nconst notebook = new Set()\n\nnotebook.add(1);// Inssercion\nnotebook.add('Hola');\nnotebook.add(['Fresa','Naranja']);\nnotebook.add({dia:'mañana',hora:'9:00am'});\n\nconsole.log(notebook);\n\nconsole.log(notebook.size); // Tamaño\n\nconsole.log(notebook.has('Hola')); // Comprueba\n\nnotebook.delete(1) // Eliminación\nconsole.log(notebook);\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/typescript/nlarrea.ts",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\n// ARRAY\n\nconst fruits: string[] = ['apple', 'orange', 'pear', 'banana'];\n\n// Insert new items\n\nfruits.push('melon');               // append at the end\nfruits.unshift('strawberry');       // insert at the beginning\nfruits.splice(2, 0, 'pineapple');   // insert in position 2 (starts at 0)\n\nconsole.log(fruits);\n// [ 'strawberry', 'apple', 'pineapple', 'orange', 'pear', 'banana', 'melon' ]\n\n// Remove items from array\n\nfruits.pop();           // removes 'melon' and returns it from array\nfruits.shift();         // removes 'strawberry' and returns it\nfruits.splice(2, 1);    // removes the item in position 2 (starts at 0)\n\nconsole.log(fruits);    // [ 'apple', 'pineapple', 'pear', 'banana' ]\n\n// Update the array\n\nfruits[1] = 'peach';    // Modify the item at index 1 to 'peach'\nconsole.log(fruits);    // [ 'apple', 'peach', 'pear', 'banana' ]\nfruits.splice(2, 1, 'melon');   // Remove item at 2nd index and add there the 'melon' value\nconsole.log(fruits);            // [ 'apple', 'peach', 'melon', 'banana' ]\n\n// Order arrays\n\nconsole.log(fruits);    // [ 'apple', 'peach', 'melon', 'banana' ]\nconst orderedFruits: string[] = fruits.slice().sort();    // Order without modifying the original\nconsole.log(fruits);    // [ 'apple', 'peach', 'melon', 'banana' ]\nconsole.log(orderedFruits); // [ 'apple', 'banana', 'melon', 'peach' ]\n\nconst numbers = [1, 4, 2, 8, 11];\nlet orderedNumbers: number[] = numbers.slice().sort((a, b) => a - b);   // to order numbers in ascending\nconsole.log(orderedNumbers);    // [ 1, 2, 4, 8, 11 ]\norderedNumbers = numbers.slice().sort((a, b) => b - a);   // to order numbers in descending\nconsole.log(orderedNumbers);    // [ 11, 8, 4, 2, 1 ]\n\n\n// SET -> removes duplicates\n\nconst fruitsSet: Set<string> = new Set(['apple', 'orange', 'pear', 'banana', 'banana']);\nconsole.log(fruitsSet);\n// Set { 0: 'apple', 1: 'orange', 2: 'pear', 3: 'banana' }\n\n// Insert new items\n\nfruitsSet.add('melon');\nconsole.log(fruitsSet);\n// Set { 0: 'apple', 1: 'orange', 2: 'pear', 3: 'banana', 4: 'melon' }\n\n// Remove one item\n\nfruitsSet.delete('pear');\nconsole.log(fruitsSet);\n// Set { 0: 'apple', 1: 'orange', 2: 'banana', 3: 'melon' }\n\n// Remove all\n\nfruitsSet.clear();\nconsole.log(fruitsSet);\n// Set {}\n\n\n// OBJECTS\n\ninterface Person {\n    name: string,\n    age: number,\n    country?: string\n}\n\nconst person: Person = {\n    name: 'Naia',\n    age: 25\n};\n\n// Insert new data\n\nperson.country = 'Spain';\nconsole.log(person);\n// { name: 'Naia', age: 25, country: 'Spain' }\n\n// Update data\n\nperson.age = 26;\nconsole.log(person);\n// { name: 'Naia', age: 26, country: 'Spain' }\n\n// Remove data\n\ndelete person.country;\nconsole.log(person);\n// { name: 'Naia', age: 26 }"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/typescript/pcosin.ts",
    "content": "// ESTRUCTURA DE DATOS\n\n// arrays:\n\nconst arr: number[] = [1, 2, 3, 4, 5];\n\narr.pop();\n\nconsole.log(arr);\n\n// Tuples\n\nconst tuple: [string, number] = [\"Daniel\", 23];\n\n// Objetos:\n\nconst obj: {\n  nombre: string;\n  edad: number;\n  online: boolean;\n} = {\n  nombre: \"Pablo\",\n  edad: 42,\n  online: false,\n};\n\n// Clases\n\nclass Person {\n  name: string;\n  constructor(name: string) {\n    this.name = name;\n  }\n\n  sayHello() {\n    console.log(`Hola ${this.name}`);\n  }\n}\n\nconst person1 = new Person(\"Pablo\");\nconsole.log(person1.sayHello());\n\n// Interface\n\ninterface Animal {\n  name: string;\n  age: number;\n}\n\nlet perro: Animal = { name: \"Pupi\", age: 9 };\n\nperro = { name: \"Dodo\", age: 3 };\n\nconsole.log(perro);\n\n// Enum\n\nenum Colores {\n  Rojo,\n  Verde,\n  Azul,\n}\n\nlet color: Colores = Colores.Verde;\n\ncolor = Colores.Azul;\n\n// Sets\n\nlet someSet: Set<number> = new Set();\n\nsomeSet.add(23);\nsomeSet.add(44);\nsomeSet.add(109);\n\nsomeSet.delete(23);\n\nconsole.log(someSet);\n\n// Map\n\nlet mapa: Map<string, number> = new Map();\n\nmapa.set(\"uno\", 1);\nmapa.set(\"dos\", 2);\nmapa.set(\"tres\", 3);\n\nmapa.delete(\"dos\");\n\nmapa.set(\"uno\", 10);\n\nconsole.log(mapa);\n\n//Extra\n\nimport * as readlineSync from \"readline-sync\";\n\nconst agenda: {\n  nombre: string;\n  telefono: string;\n}[] = [];\n\nfunction agregarContacto(): void {\n  try {\n    const nombre: string = readlineSync.question(\n      \"Ingrese el nombre del nuevo contacto: \"\n    );\n    let telefono: string;\n    while (true) {\n      telefono = readlineSync.question(\n        \"Ingrese el teléfono del nuevo contacto: \"\n      );\n\n      if (/^\\d{1,11}$/.test(telefono)) {\n        break;\n      } else {\n        console.log(\n          \"El teléfono debe ser numérico y tener 11 dígitos. Inténtelo de nuevo.\"\n        );\n      }\n    }\n\n    const nuevoContacto = { nombre, telefono };\n\n    agenda.push(nuevoContacto);\n\n    console.log(\"El nuevo registro ha sido creado con éxito\");\n  } catch (error) {\n    console.error(error);\n  }\n}\n\nfunction mostrarAgenda(): void {\n  if (agenda.length !== 0) {\n    agenda.forEach((contacto) => {\n      console.log(\n        `\\nNombre: ${contacto.nombre} \\nTeléfono: ${contacto.telefono}`\n      );\n    });\n  } else {\n    console.log(\"No hay contactos aún. Ingrese un nuevo contacto\");\n  }\n}\n\nfunction buscarContacto(): void {\n  const nombre: string = readlineSync.question(\n    \"Ingrese el nombre del contacto que busca: \"\n  );\n  const encontrado = agenda.find(\n    (valor) => valor.nombre.toLocaleLowerCase() === nombre.toLocaleLowerCase()\n  );\n  if (encontrado) {\n    console.log(\n      `El contacto es ${encontrado.nombre} y su teléfomo es ${encontrado.telefono}`\n    );\n  } else {\n    console.log(\"No se encuentra el contacto\");\n  }\n}\n\nfunction eliminarContacto(): void {\n  const nombre: string = readlineSync.question(\n    \"Ingrese el nomnre del contacto que quiere elminar: \"\n  );\n  const encontrado = agenda.find(\n    (valor) => valor.nombre.toLocaleLowerCase() === nombre.toLocaleLowerCase()\n  );\n  if (encontrado) {\n    const confirmacion: string = readlineSync.question(\n      `¿Quiere eliminar a ${encontrado.nombre} cuyo teléfono es ${encontrado.telefono}? Escriba: si / no: `\n    );\n    switch (confirmacion) {\n      case \"si\":\n        eliminar(encontrado);\n        break;\n      case \"no\":\n        console.log(\"No se elimna el contacto\");\n        break;\n      default:\n        console.log(\"Opción no válida. Inténtelo de nuevo.\");\n    }\n  } else {\n    console.log(\"No se encuentra el contacto\");\n  }\n\n  function eliminar(contacto: { nombre: string; telefono: string }): void {\n    const index = agenda.findIndex((c) => c.nombre === contacto.nombre);\n    agenda.splice(index, 1);\n    console.log(\"El contacto ha sido eliminado con éxito.\");\n  }\n}\n\nfunction editarContacto(): void {\n  const nombre: string = readlineSync.question(\n    \"Ingrese el nombre del contacto que quiere editar: \"\n  );\n\n  const indice = agenda.findIndex(\n    (c) => c.nombre.toLocaleLowerCase() === nombre.toLocaleLowerCase()\n  );\n\n  if (indice !== -1) {\n    console.log(\n      `Contacto encontrado: ${agenda[indice].nombre} - ${agenda[indice].telefono}`\n    );\n\n    const nuevoNombre: string = readlineSync.question(\n      \"Ingrese el nuevo nombre (deje en blanco para mantener el actual): \"\n    );\n    const nuevoTelefono: string = readlineSync.question(\n      \"Ingrese el nuevo teléfono (deje en blanco para mantener el actual): \"\n    );\n\n    agenda[indice].nombre = nuevoNombre || agenda[indice].nombre;\n    agenda[indice].telefono = nuevoTelefono || agenda[indice].telefono;\n\n    console.log(\"El contacto ha sido actualizado con éxito.\");\n  } else {\n    console.log(\"No se encuentra el contacto en la agenda.\");\n  }\n}\n\nfunction main(): void {\n  let bucle: boolean = true;\n  while (bucle) {\n    console.log(\"\\n== Menú ==\");\n    console.log(\"1. Agregar contacto\");\n    console.log(\"2. Mostrar contactos\");\n    console.log(\"3. Buscar contactos\");\n    console.log(\"4. Eliminar contacto\");\n    console.log(\"5. Actualizar contacto\");\n    console.log(\"6. Salir\");\n\n    const opcion = readlineSync.questionInt(\"Seleccione una opción: \");\n\n    switch (opcion) {\n      case 1:\n        agregarContacto();\n        break;\n      case 2:\n        mostrarAgenda();\n        break;\n      case 3:\n        buscarContacto();\n        break;\n      case 4:\n        eliminarContacto();\n        break;\n      case 5:\n        editarContacto();\n        break;\n      case 6:\n        console.log(\"Saliendo de la aplicación. ¡Hasta luego!\");\n        bucle = false;\n        break;\n      default:\n        console.log(\"Opción no válida. Inténtelo de nuevo.\");\n    }\n  }\n}\n\nmain();\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/typescript/qv1ko.ts",
    "content": "main();\n\nfunction main(): void {\n\n    let contacts: { [key: string]: string } = {};\n    let exit: boolean = false;\n    let option: string | null = \"\";\n    let phone: string | null = \"\";\n\n    while (!exit) {\n\n        option = prompt(\"\\nSelect an option\\n1) Search contact\\n2) Create contact\\n3) Update a contact\\n4) Delete contact\\n0) Exit\\n>> \");\n\n        switch (option) {\n            case \"1\":\n                if (Object.keys(contacts).length > 0) {\n                    option = prompt(\"\\nEnter the name of the contact\\n>> \");\n                    if (typeof option === \"string\" && option in contacts) {\n                        console.log(\"\\n>> Contact \" + option +  \" - \" + contacts[option]);\n                    } else {\n                        console.log(\"\\n>> Contact not found...\");\n                    }\n                } else {\n                    console.log(\"\\n>> You have no contacts in your address book...\")\n                }\n                break;\n\n            case \"2\":\n                option = prompt(\"\\nType the name of the new contact\\n>> \");\n                if (typeof option === \"string\") {\n                    do {\n                        phone = prompt(\"\\nType the phone number of the new contact\\n>> \");\n                    } while (typeof phone === \"string\" && (!/^\\d+$/.test(phone) || phone.length < 9 || phone.length > 11));\n                    if (option && phone) {\n                        contacts[option] = phone;\n                    }\n                }\n                break;\n\n            case \"3\":\n                if (Object.keys(contacts).length > 0) {\n                    option = prompt(\"\\nType the name of the contact you want to update\\n>> \");\n                    if (typeof option === \"string\" && option in contacts) {\n                        do {\n                            phone = prompt(\"\\nType the new contact's phone number\\n>> \");\n                        } while (typeof phone === \"string\" && (!/^\\d+$/.test(phone) || phone.length < 9 || phone.length > 11));\n                        if (option && phone) {\n                            contacts[option] = phone;\n                        }\n                        console.log(\"\\n>> Contact \" + option +  \" - \" + contacts[option]);\n                    } else {\n                        console.log(\"\\n>> Contact not found...\");\n                    }\n                } else {\n                    console.log(\"\\n>> You have no contacts in your address book...\")\n                }\n                break;\n\n            case \"4\":\n                if (Object.keys(contacts).length > 0) {\n                    option = prompt(\"\\nType the name of the contact you want to delete\\n>> \");\n                    if (typeof option === \"string\" && option in contacts) {\n                        delete contacts[option];\n                        console.log(\"\\n>> Contact \" + option + \" deleted\");\n                    } else {\n                        console.log(\"\\n>> Contact not found...\");\n                    }\n                } else {\n                    console.log(\"\\n>> You have no contacts in your address book...\")\n                }\n                break;\n\n            case \"0\":\n                exit = true;\n                console.log(\"\\n>> Leaving...\");\n                break;\n        \n            default:\n                console.log(\"\\n>> Invalid option...\");\n                break;\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/typescript/qwik-zgheib.ts",
    "content": "import { createInterface } from \"readline\";\n\n/* -- exercise */\nlet fruits: string[] = [\"Apple\", \"Banana\", \"Cherry\"];\n\nfruits.push(\"Date\");\nconsole.log(\"Array after insertion:\", fruits);\nfruits.pop();\nconsole.log(\"Array after deletion:\", fruits);\nfruits[1] = \"Blueberry\";\nconsole.log(\"Array after update:\", fruits);\nfruits.sort();\nconsole.log(\"Sorted array:\", fruits);\n\nlet colors: Set<string> = new Set([\"red\", \"green\", \"blue\"]);\ncolors.add(\"yellow\");\nconsole.log(\"Set after insertion:\", colors);\ncolors.delete(\"green\");\nconsole.log(\"Set after deletion:\", colors);\n\nlet fruitsMap: Map<string, number> = new Map([\n  [\"apple\", 5],\n  [\"banana\", 10],\n  [\"cherry\", 15],\n]);\nfruitsMap.set(\"date\", 20);\nconsole.log(\"Map after insertion:\", fruitsMap);\nfruitsMap.delete(\"banana\");\nconsole.log(\"Map after deletion:\", fruitsMap);\nfruitsMap.set(\"cherry\", 18);\nconsole.log(\"Map after update:\", fruitsMap);\n\nlet sentence: string = \"Hello, world!\";\nlet newSentence: string = sentence.replace(\"world\", \"JavaScript\");\nconsole.log(\"String after replacement:\", newSentence);\nlet modifiedSentence: string = \"Hey \" + sentence + \" Have a nice day!\";\nconsole.log(\"String after insertion:\", modifiedSentence);\nlet removedText: string = sentence.replace(\", world\", \"\");\nconsole.log(\"String after deletion:\", removedText);\n\n/* -- extra challenge */\nconst rl = createInterface({\n  input: process.stdin, // execute: npm i --save-dev @types/node\n  output: process.stdout, // execute: npm i --save-dev @types/node\n});\n\ninterface Contact {\n  name: string;\n  phoneNumber: string;\n}\n\nlet contacts: Contact[] = [];\n\nconst isNumeric = (str: string): boolean => {\n  return /^\\d+$/.test(str);\n};\n\nconst addContact = (name: string, phoneNumber: string): void => {\n  contacts.push({ name, phoneNumber });\n  console.log(`Contact ${name} added successfully.`);\n};\n\nconst searchContact = (name: string): void => {\n  let foundContacts: Contact[] = contacts.filter((contact) => contact.name.toLowerCase() === name.toLowerCase());\n  if (foundContacts.length > 0) {\n    console.log(`Found ${foundContacts.length} contacts:`);\n    foundContacts.forEach((contact) => console.log(`Name: ${contact.name}, Phone Number: ${contact.phoneNumber}`));\n  } else console.log(`No contacts found with name '${name}'.`);\n};\n\nconst updateContact = (name: string, newPhoneNumber: string): void => {\n  let foundContact: Contact | undefined = contacts.find((contact) => contact.name.toLowerCase() === name.toLowerCase());\n  if (foundContact) {\n    foundContact.phoneNumber = newPhoneNumber;\n    console.log(`Phone number updated for contact '${name}'.`);\n  } else console.log(`Contact '${name}' not found.`);\n};\n\nconst deleteContact = (name: string): void => {\n  let initialLength: number = contacts.length;\n  contacts = contacts.filter((contact) => contact.name.toLowerCase() !== name.toLowerCase());\n  if (contacts.length < initialLength) console.log(`Contact '${name}' deleted successfully.`);\n  else console.log(`Contact '${name}' not found.`);\n};\n\nconst handleUserInput = (): void => {\n  rl.question(`\\nChoose an operation:\\n1. Add contact\\n2. Search contact\\n3. Update contact\\n4. Delete contact\\n5. Exit\\n`, function (option) {\n    switch (option.trim()) {\n      case \"1\":\n        rl.question(`Enter name: `, function (name) {\n          rl.question(`Enter phone number: `, function (phoneNumber) {\n            if (isNumeric(phoneNumber) && phoneNumber.length <= 11) addContact(name, phoneNumber);\n            else console.log(`Invalid phone number format.`);\n\n            handleUserInput();\n          });\n        });\n        break;\n      case \"2\":\n        rl.question(`Enter name to search: `, function (name) {\n          searchContact(name);\n          handleUserInput();\n        });\n        break;\n      case \"3\":\n        rl.question(`Enter name to update: `, function (name) {\n          rl.question(`Enter new phone number: `, function (phoneNumber) {\n            if (isNumeric(phoneNumber) && phoneNumber.length <= 11) updateContact(name, phoneNumber);\n            else console.log(`Invalid phone number format.`);\n\n            handleUserInput();\n          });\n        });\n        break;\n      case \"4\":\n        rl.question(`Enter name to delete: `, function (name) {\n          deleteContact(name);\n          handleUserInput();\n        });\n        break;\n      case \"5\":\n        rl.close();\n        break;\n      default:\n        console.log(`Invalid option. Please choose a valid operation.`);\n        handleUserInput();\n    }\n  });\n};\n\nconsole.log(\"Welcome to the Contact Agenda!\");\n\nhandleUserInput();\n\nrl.on(\"close\", () => {\n  console.log(\"Exiting the Contact Agenda. Goodbye!\");\n  process.exit(0);\n});\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/typescript/rubenplazavi.ts",
    "content": "/**\n * Estructuras de datos en typescript\n * \n * @author rubenplazavi\n * @version 1.0\n * \n * \n * index:\n * 1. Arrays\n * 2. Tuplas\n * 3. Enumeraciones\n * 4. Objetos\n * 5. Mapas\n * 6. Conjuntos\n * 7. Pilas\n * 8. Colas\n * 9. Listas enlazadas\n * 10. Árboles\n * 11. Grafos\n * \n * \n * * EJERCICIO:\n * - Muestra ejemplos de creación de todas las estructuras soportadas por defecto en tu lenguaje.\n * - Utiliza operaciones de inserción, borrado, actualización y ordenación.\n * \n *  * DIFICULTAD EXTRA (opcional):\n * Crea una agenda de contactos por terminal.\n * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n * - Cada contacto debe tener un nombre y un número de teléfono.\n * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n *   los datos necesarios para llevarla a cabo.\n * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n *   (o el número de dígitos que quieras)\n * - También se debe proponer una operación de finalización del programa.\n */\n\n//!--------------------- Arrays -------------------\nconsole.log(\"Arrays\");\nlet arrayOfNumbers: number[] = [1,2,3,4,5];\nlet arrayOfNumbers2: Array<number> = new Array(1,2,3,4,5);\nlet arrayOfNumbers3: number[] = [];\n\nlet arrayOfStrings: Array<string> = [\"a\",\"b\",\"c\",\"d\",\"e\"];\nlet ArrayOfMixedTypes: Array<any> = [\"a\", 1, {name:\"John\", surname:\"Doe\"}, true];\n\nconsole.log(\"array of numbers: \",arrayOfNumbers);\nconsole.log(arrayOfNumbers2);\nconsole.log(arrayOfNumbers3);\nconsole.log(\"array of strings: \", arrayOfStrings);\nconsole.log(\"array of mixed types: \", ArrayOfMixedTypes);\n\n//Inserción\narrayOfNumbers.push(6);\nconsole.log(arrayOfNumbers);\n\n//Borrado\narrayOfNumbers.pop();\nconsole.log(arrayOfNumbers);\n\narrayOfNumbers.splice(1, 1);\nconsole.log(\"Borrado 2o elemento: \", arrayOfNumbers);\n\n//Actualizacion\narrayOfNumbers[2] = 7;\nconsole.log(\"actualizacion de array de numeros: \", arrayOfNumbers);\n\narrayOfStrings[2] = \"w\";\nconsole.log(\"actualizacion de array de strings: \", arrayOfStrings);\t\n\n//Ordenacion\narrayOfNumbers.sort((a, b) => b - a);\nconsole.log(\"Ordenacion descendente de array de numeros: \",arrayOfNumbers);\n\narrayOfStrings.sort((a, b) => b.localeCompare(a));\nconsole.log(\"Ordenacion descendente de array de strings: \",arrayOfStrings);\n\n//!--------------------- Tuplas -------------------\n\nlet product: [number, string] = [1, \"Tornillos\"];\nconsole.log(product[0], product[1]);\n\nproduct.push(2, \"Ladrillos\");\nproduct.push(3, \"Pisos\");\n\nconsole.log(product);\n\nproduct.pop();\nproduct.pop();\n\nconsole.log(product);\n\nconsole.log(product[1])\n\n\n//!--------------------- Enumeraciones -------------------\n/**\n * Un enum (enumeración) en TypeScript es un tipo de dato especial que permite definir un conjunto de constantes con nombre.\n * Los enums en TypeScript tienen dos tipos principales: enum numéricos y enum de cadena.\n * \n * Uso: Permiten a las variables ser uno de los valores predefinidos, mejorando la legibilidad y seguridad del código.\n * Valores Específicos: Pueden tener valores numéricos o strings específicos.\n * Operaciones: Se pueden convertir entre strings y números, y se pueden iterar, pero no se pueden modificar después de su definición.\n */\nenum DAYS{\n    Lunes = 1,\n    Martes = 2,\n    Miercoles = 3,\n    Jueves = 4,\n    Viernes = 5,\n    Sabado = 6,\n    Domingo = 7,\n}\nenum WEEK_DAYS{\n    Lunes = \"lunes\",\n    Martes = \"martes\",\n    Miercoles = \"miercoles\",\n    Jueves = \"jueves\",\n    Viernes = \"viernes\",\n    Sabado = \"sabado\",\n    Domingo = \"domingo\",\n}\n\nconsole.log(\"iterar enmueracion dias de la semana cuando son strings: \");\nfor( let day in WEEK_DAYS){\n    console.log(WEEK_DAYS[day]);\n}\n\nconsole.log(\"iterar enmueracion dias de la semana cuando son numéricos\\n (nota, en este caso, es bidireccional, escribe la clave y el valor del enum): \");\nObject.keys(DAYS).forEach(key => console.log(key));\n\n\n//!--------------------- Objetos -------------------\n//Creacion\ntype User = {\n    name: string,\n    surname: string,\n    age: number,\n    address?: {\n        street: string,\n        number: number,\n        city: string,\n        country?: string\n    }\n}\nconst carlos: User = {\n    name: \"Carlos\",\n    surname: \"Perez\",\n    age: 30,\n}\nconsole.log(\"Datos Usuario Carlos: \", carlos);\n\n//Inserción\ncarlos.address = {\n    street: \"Calle Mayor\",\n    number: 1,\n    city: \"Madrid\",\n    country: \"España\"\n}\nconsole.log(\"Datos añadidos de direccion para Carlos: \", carlos);\n\n//Borrado\n// delete carlos.age;  // No se puede borrar la edad, porque es campo obligatorio\n//? Todo lo que se quiera borrar debe ser opcional en la declaración del tipo\n\ndelete carlos.address.country;\nconsole.log(\"Datos address pais borrados: \", carlos);\nconsole.log(arrayOfNumbers);\n\n//Actualizacion\ncarlos.age = 31;\nconsole.log(\"Datos Actualizados edad Carlos: \", carlos);\n\n//Ordenacion\n\n//!--------------------- Maps -------------------\n/**\n * Los objetos Map son colecciones de tuplas tipo llave-valor. Una llave en Map puede aparecer solo una vez; \n * es única en la colección de Map. Un objeto Map es iterado por sus tuplas llave-valor —un bucle for...of \n * regresa un arreglo de [llave, valor] por cada iteración. La iteración sucede en orden de inserción, \n * la cual corresponde al orden en el que cada tupla llave-valor fue incertada inicialmente en el map por el método set()\n *  (eso es, si no había una llave con el mismo valor en el map, cuando set() fué llamado).\n\nLa especificación requiere que los maps sean implementados \"que, en promedio, proporcione tiempos de acceso que \nsean sublineales al numero de elementos en la colección\". Por lo tanto, podría ser representado internamente como una \ntabla hash (con una busqueda O(1)), un árbol de búsqueda (con una busqueda de O(log(N))), o cualquier otra estructura de \ndatos, mientras la complejidad sea mejor que O(N).\n */\n\n//Creación\nconst mapInicializado: Map<string, any> = new Map([[\"name\", \"Miriam\"], [\"surname\", \"Rosado\"]]); // Solo para la inicializacion se puede varios valores\nlet variableMap = new Map();  // implícito Map<any, any>\n\n\n\nconsole.log(\"mapInicializado: \", mapInicializado.set(\"age\", 30));\nconsole.log(\"variableMap (sin inicializar): \", variableMap);\n\n//Inserción\nvariableMap.set(\"age\", 30);\nvariableMap.set(\"name\", \"Carlos\");\nvariableMap.set(\"surname\", \"Perez\");\n\nmapInicializado.set(\"age\", 30);\nmapInicializado.set(\"address\", {\n    street: \"Calle Mayor\",\n    number: 1,\n    city: \"Madrid\",\n    country: \"España\"\n});\n\nconsole.log(\"mapInicializado y con inserción de edad y address: \", mapInicializado.set(\"age\", 30));\nconsole.log(\"variableMap ya inicializada: \", variableMap);\n\n//Borrado\nmapInicializado.delete(\"surname\");\n\nmapInicializado.size;\n\n//Actualizacion\nmapInicializado[\"age\"]= 31;\n\nconsole.log(\"mapInicializado con actualizacion de edad: \", mapInicializado);\n\n// Claves\nconst keys: IterableIterator<string> = mapInicializado.keys();\n\n//Ordenacion\n//?En este caso no se puede ordenar, está ordenado pororden de inserción...\n\n\n//!--------------------- Sets -------------------\n\n/** Los objetos Set son colecciones de valores. Puede iterar a través de los elementos de un conjunto en orden \n * de inserción. Un valor en un Set solo puede ocurrir una vez; es único en la colección del Set.\n*/\n\n// creación\nlet mySet1 = new Set([1,\"Carlos\", true]);\nconsole.log(\"mi primer set: \",mySet1);\n\n\n//Inserción\nmySet1.add(\"Carpintero\");\n// No se le puede añadir un objeto al set:\n/**\n * \n * This code attempts to add an object additionalValues to the set mySet1. However, since sets in TypeScript only store\n * unique primitive values, adding an object will not work as expected. Instead, it will add the object as a reference,\n * and if the same object is added again, it will be treated as a duplicate and not added to the set. If you want to add \n * unique key-value pairs to a data structure, you might want to consider using a Map instead\n * \n * Error de compilación: ------------------------------------\n * const additionalValues = {a:1, b:3};\n * mySet1.add(additionalValues);\n * \n */\nmySet1.add(1); // solo admite valores únicos, como el 1 ya está no lo va a añadir\nmySet1.add(\"Carlos\");\nconsole.log(\"mi set con un nuevo elemento: \",mySet1);\n\n//Borrado\nmySet1.delete(\"Carpintero\");\nconsole.log(\"mi set borrando carpintero: \",mySet1);\n\n//Actualizacion\n//? No se pueden actualizar los valores de un Set, solo es válido para almacenar datos únicos\n\n//Ordenacion\n//? No se pueden ordenar los set\n\nconsole.log(\"Metodo has, para comprobar si existe el elemento dentro del set: \",mySet1.has(\"carpintero\"));\nmySet1.has(\"Carlos\");\n\n\n\n//!--------------------- Conjuntos -------------------\n//!--------------------- Pilas -------------------\n//!--------------------- Colas -------------------\n//!--------------------- Listas enlazadas -------------------\n//!--------------------- Árboles -------------------\n//!--------------------- Grafos -------------------"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/typescript/victor-Casta.ts",
    "content": "//Utiliza operaciones de inserción, borrado, actualización y ordenación\n//stack | Pilas\n\nclass Stack {\n  items: Array<number>;\n\n  constructor() {\n    this.items = [];\n  }\n\n  insert(numberInserted: number) {\n    this.items.push(numberInserted);\n  }\n\n  remove() {\n    this.items.pop();\n  }\n\n  update(numberUpdated: number) {\n    if (this.items.length > 0) {\n      this.items[this.items.length - 1] = numberUpdated;\n    } else {\n      console.log('La lista está vacía');\n    }\n  }\n\n  ordination() {\n    this.items.sort((a, b) => a - b);\n  }\n}\n\nconst stack: Stack = new Stack();\nstack.insert(1);\nstack.insert(2);\nstack.insert(3);\nstack.insert(4);\nstack.insert(5);\nconsole.log(`insert: ${stack.items}`);\nstack.remove();\nconsole.log(`Remove: ${stack.items}`);\nstack.update(6);\nconsole.log(`Update: ${stack.items}`);\nstack.ordination();\nconsole.log(`Ordination: ${stack.items}`);\n\n//Queue | Colas\n\nclass Queue {\n  items: Array<number> = [];\n  constructor() {\n    this.items = [];\n  }\n\n  insert(item: number) {\n    this.items.push(item);\n  }\n\n  remove() {\n    this.items.shift();\n  }\n\n  update(item: number) {\n    this.items[0] = item;\n  }\n\n  ordenation() {\n    this.items.sort((a, b) => a - b);\n  }\n}\n\nconst queue = new Queue();\nqueue.insert(1);\nqueue.insert(2);\nqueue.insert(3);\nqueue.insert(4);\nconsole.log(`Inserted: ${queue.items}`);\nqueue.remove();\nconsole.log(`Removed: ${queue.items}`);\nqueue.update(5);\nconsole.log(`Updated: ${queue.items}`);\nqueue.ordenation();\nconsole.log(`Ordered: ${queue.items}`);\n\n//Linked list | Listas linkeadas\nclass PrincipalNode {\n  data: number;\n  next: PrincipalNode | null;\n  constructor(value: number) {\n    this.data = value;\n    this.next = null;\n  }\n}\n\nclass LinkedList {\n  head: PrincipalNode | null;\n\n  constructor() {\n    this.head = null;\n  }\n\n  insertAtEnd(value: number) {\n    const newNode = new PrincipalNode(value);\n\n    if (!this.head) {\n      this.head = newNode;\n      return;\n    }\n\n    let current = this.head;\n    while (current.next !== null) {\n      current = current.next;\n    }\n\n    current.next = newNode;\n  }\n\n  deleteNode(value: number) {\n    if (!this.head) {\n      return;\n    }\n\n    if (this.head.data === value) {\n      this.head = this.head.next;\n      return;\n    }\n\n    let current = this.head;\n    while (current.next !== null) {\n      if (current.next.data === value) {\n        current.next = current.next.next;\n        return;\n      }\n      current = current.next;\n    }\n  }\n\n  updateNode(oldValue: number, newValue: number) {\n    let current = this.head;\n    while (current !== null) {\n      if (current.data === oldValue) {\n        current.data = newValue;\n        return;\n      }\n      current = current.next;\n    }\n  }\n\n  sortList() {\n    if (!this.head || !this.head.next) {\n      return;\n    }\n\n    let current: PrincipalNode | null = this.head;\n    let index: PrincipalNode | null;\n    let temp: number;\n\n    while (current !== null) {\n      index = current.next;\n      while (index !== null) {\n        if (current.data > index.data) {\n          temp = current.data;\n          current.data = index.data;\n          index.data = temp;\n        }\n        index = index.next;\n      }\n      current = current.next;\n    }\n  }\n}\n\nconst myList = new LinkedList();\nmyList.insertAtEnd(3);\nmyList.insertAtEnd(1);\nmyList.insertAtEnd(2);\nmyList.insertAtEnd(5);\n\nconsole.log(\"Lista original:\");\nlet current = myList.head;\nwhile (current !== null) {\n  console.log(`Node: ${current.data}`);\n  current = current.next;\n}\n\nmyList.deleteNode(2);\nconsole.log(\"Lista después de eliminar el nodo con valor 2:\");\ncurrent = myList.head;\nwhile (current !== null) {\n  console.log(`Node: ${current.data}`);\n  current = current.next;\n}\n\nmyList.updateNode(1, 4);\nconsole.log(\"Lista después de actualizar el nodo con valor 1 a 4:\");\ncurrent = myList.head;\nwhile (current !== null) {\n  console.log(`Node: ${current.data}`);\n  current = current.next;\n}\n\nmyList.sortList();\nconsole.log(\"Lista ordenada:\");\ncurrent = myList.head;\nwhile (current !== null) {\n  console.log(`Node: ${current.data}`);\n  current = current.next;\n}\n\n\n//tablas de hash\nclass HashTable {\n  private table: Array<Array<[string, any]>>;\n  private size: number;\n\n  constructor(size: number) {\n      this.table = new Array(size);\n      this.size = size;\n  }\n\n  private hash(key: string): number {\n      let hash = 0;\n      for (let i = 0; i < key.length; i++) {\n          hash += key.charCodeAt(i);\n      }\n      return hash % this.size;\n  }\n\n  set(key: string, value: any): void {\n      const index = this.hash(key);\n      if (!this.table[index]) {\n          this.table[index] = [];\n      }\n      this.table[index].push([key, value]);\n  }\n\n  get(key: string): any {\n      const index = this.hash(key);\n      const bucket = this.table[index];\n      if (bucket) {\n          for (const pair of bucket) {\n              if (pair[0] === key) {\n                  return pair[1];\n              }\n          }\n      }\n      return undefined;\n  }\n\n  remove(key: string): void {\n      const index = this.hash(key);\n      const bucket = this.table[index];\n      if (bucket) {\n          this.table[index] = bucket.filter((pair) => pair[0] !== key);\n      }\n  }\n}\n\n// Uso de la tabla hash\nconst myHashTable = new HashTable(10);\nmyHashTable.set(\"apple\", 5);\nmyHashTable.set(\"banana\", 10);\nmyHashTable.set(\"orange\", 15);\n\nconsole.log(myHashTable.get(\"apple\"));  // Output: 5\nconsole.log(myHashTable.get(\"banana\")); // Output: 10\nconsole.log(myHashTable.get(\"orange\")); // Output: 15\n\nmyHashTable.remove(\"banana\");\nconsole.log(myHashTable.get(\"banana\")); // Output: undefined"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/typescript/victoriaparraf.ts",
    "content": "//ARRAYS\n//Creacion de un array\nlet numeros: number[] = [5,3,4,6,7,1];\n//insertar en un array\nnumeros.push(10); // Agregar al final\nnumeros.unshift(0); // Agregar al inicio\nconsole.log(numeros);\n//borrar elementos de un array\nnumeros.pop(); // Eliminar el último elemento\nnumeros.shift(); // Eliminar el primer elemento\nconsole.log(numeros);\n//actualizar elementos\nnumeros[2] = 7; // Actualizar el tercer elemento\nconsole.log(numeros);\n//ordenar\nnumeros.sort((a, b) => a - b); // Ordenar en orden ascendente\nconsole.log(numeros); \n\n//TUPLAS\n//Creacion de tuplas\nlet persona: [string, number] = [\"Victoria\", 23];\n//Insercion y actualizacion (no se pueden insertar nuevos elementos)\npersona[0] = \"Vanessa\";\npersona[1] = 24;\nconsole.log(persona);\n\n//CONJUNTOS(sets)\n//creacion\nlet conjunto: Set<number> = new Set([1,2,3,4]);\n//Insercion\nconjunto.add(5);\nconjunto.add(3); // No se agregará ya que 3 ya está presente\nconsole.log(conjunto); // Set { 1, 2, 3, 4, 5 }\n//borrar\nconjunto.delete(2);\nconsole.log(conjunto); // Set { 1, 3, 4, 5 }\n//verificar y tamano\nconsole.log(conjunto.has(3)); // true\nconsole.log(conjunto.size); // 4\n\n//MAPAS \n//creacion\nlet mapa: Map<string, number> = new Map([\n    [\"uno\", 1],\n    [\"dos\", 2]\n]);\n//insertar\nmapa.set(\"tres\", 3);\nconsole.log(mapa); // Map { 'uno' => 1, 'dos' => 2, 'tres' => 3 }\n//borrar\nmapa.delete(\"dos\");\nconsole.log(mapa); // Map { 'uno' => 1, 'tres' => 3 }\n//actualizar\nmapa.set(\"uno\", 10);\nconsole.log(mapa); // Map { 'uno' => 10, 'tres' => 3 }\n//iterar\nmapa.forEach((valor, clave) => {\n    console.log(`${clave}: ${valor}`);\n});\n// uno: 10\n// tres: 3\n\n//OPERADORES\n//Crear objeto\nlet personaObj = {\n    nombre: \"Victoria\",\n    edad: 23\n};\n//Insertar y actualizar\npersonaObj[\"profesion\"] = \"Ingeniera\"; // Inserción\npersonaObj.edad = 22; // Actualización\nconsole.log(personaObj); // { nombre: 'Alice', edad: 31, profesion: 'Ingeniera' }\n//borrar\n//delete personaObj.profesion;\nconsole.log(personaObj); // { nombre: 'Alice', edad: 31 }\n//iteracion\nfor (let clave in personaObj) {\n    if (personaObj.hasOwnProperty(clave)) {\n        console.log(`${clave}: ${personaObj[clave]}`);\n    }\n}\n// nombre: Alice\n// edad: 31\n\n/**************************************************************/\n\n/*EXTRAAA */\nimport * as readline from 'readline';\n\n// Crear una interfaz para leer datos desde la consola\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\n// Estructura de datos para almacenar los contactos\ninterface Contacto {\n    nombre: string;\n    telefono: string;\n}\n\nlet contactos: Contacto[] = [];\n\n// Función para mostrar el menú\nfunction mostrarMenu(): void {\n    console.clear();\n    console.log(\"Bienvenido a tus Contactos\");\n    console.log(\"1. Agregar un nuevo contacto\");\n    console.log(\"2. Editar un contacto\");\n    console.log(\"3. Buscar un contacto\");\n    console.log(\"4. Eliminar un contacto\");\n    console.log(\"5. Salir\");\n}\n\n// Función para agregar un nuevo contacto\nfunction agregarContacto(): void {\n    rl.question(\"Ingrese el nombre del contacto: \", (nombre: string) => {\n        rl.question(\"Ingrese el número de teléfono: \", (telefono: string) => {\n            if (telefono.match(/^\\d{1,11}$/)) {\n                contactos.push({ nombre, telefono });\n                console.log(\"Contacto agregado exitosamente.\");\n            } else {\n                console.log(\"Número de teléfono inválido. Debe ser numérico y tener hasta 11 dígitos.\");\n            }\n            setTimeout(myAgenda, 1000); // Volver al menú principal\n        });\n    });\n}\n\n// Función para editar un contacto\nfunction editarContacto(): void {\n    rl.question(\"Ingrese el nombre del contacto a editar: \", (nombre: string) => {\n        let contacto = contactos.find(c => c.nombre === nombre);\n        if (contacto) {\n            rl.question(\"Ingrese el nuevo número de teléfono: \", (telefono: string) => {\n                if (telefono.match(/^\\d{1,11}$/)) {\n                    contacto.telefono = telefono;\n                    console.log(\"Contacto actualizado exitosamente.\");\n                } else {\n                    console.log(\"Número de teléfono inválido. Debe ser numérico y tener hasta 11 dígitos.\");\n                }\n                setTimeout(myAgenda, 1000); // Volver al menú principal\n            });\n        } else {\n            console.log(\"Contacto no encontrado.\");\n            setTimeout(myAgenda, 1000); // Volver al menú principal\n        }\n    });\n}\n\n// Función para buscar un contacto\nfunction buscarContacto(): void {\n    rl.question(\"Ingrese el nombre del contacto a buscar: \", (nombre: string) => {\n        let contacto = contactos.find(c => c.nombre === nombre);\n        if (contacto) {\n            console.log(`Nombre: ${contacto.nombre}, Teléfono: ${contacto.telefono}`);\n        } else {\n            console.log(\"Contacto no encontrado.\");\n        }\n        setTimeout(myAgenda, 1000); // Volver al menú principal\n    });\n}\n\n// Función para eliminar un contacto\nfunction eliminarContacto(): void {\n    rl.question(\"Ingrese el nombre del contacto a eliminar: \", (nombre: string) => {\n        let indice = contactos.findIndex(c => c.nombre === nombre);\n        if (indice !== -1) {\n            contactos.splice(indice, 1);\n            console.log(\"Contacto eliminado exitosamente.\");\n        } else {\n            console.log(\"Contacto no encontrado.\");\n        }\n        setTimeout(myAgenda, 1000); // Volver al menú principal\n    });\n}\n\n// Función principal para manejar el menú y las opciones\nfunction myAgenda(): void {\n    mostrarMenu();\n    rl.question(\"Ingrese una opción: \", (respuesta: string) => {\n        let opcion: number = parseInt(respuesta);\n\n        switch (opcion) {\n            case 1:\n                agregarContacto();\n                break;\n            case 2:\n                editarContacto();\n                break;\n            case 3:\n                buscarContacto();\n                break;\n            case 4:\n                eliminarContacto();\n                break;\n            case 5:\n                console.log(\"Salir\");\n                rl.close(); // Cerrar la interfaz después de recibir la entrada\n                return; // Salir de la función para evitar que se vuelva a mostrar el menú\n            default:\n                console.log(\"Opción no válida. Intente de nuevo.\");\n                setTimeout(myAgenda, 1000); // Volver al menú principal\n                break;\n        }\n    });\n}\n\nmyAgenda();\n\n\n\n\n"
  },
  {
    "path": "Roadmap/03 - ESTRUCTURAS DE DATOS/vb.net/kenysdev.vb",
    "content": "' ╔══════════════════════════════════════╗\n' ║ Autor:  Kenys Alvarado               ║\n' ║ GitHub: https://github.com/Kenysdev  ║\n' ║ 2024 -  VB.NET                       ║\n' ╚══════════════════════════════════════╝\n\n' ESTRUCTURAS DE DATOS\n' --------------------\nImports System.Formats\n\nModule Program\n\n    Sub Main(args As String())\n        '_______________________________________________________\n        ' Arrays(Arreglos):\n        ' - Colección de elementos del mismo tipo almacenados en posiciones contiguas de memoria.\n        ' - Acceso rápido a elementos por índice.\n        Console.WriteLine(\"Arreglos\")\n\n        Dim numeros = New Integer(2) {}\n        Dim palabras = New String() {\"Hola\", \"Mundo\"}\n\n        ' Inserción:\n        numeros(0) = 3\n        numeros(1) = 2\n        numeros(2) = 1\n\n        ' Acceder:\n        Console.WriteLine(numeros(0))\n\n        ' Modificar:\n        palabras(1) = \"Ben\"\n\n        ' Ordenación:\n        Array.Sort(numeros)\n\n        ' Iteración:\n        For i = 0 To numeros.Length - 1\n            Console.WriteLine(\"Índice \" & i & \": \" & numeros(i))\n        Next\n        ' Nota: Los arreglos en VB.Net son de tamaño fijo después de la inicialización.\n\n        '_______________________________________________________\n        ' List(Listas):\n        ' - Dinámicas y redimensionables, permiten almacenar elementos del mismo tipo.\n        ' - Flexibilidad en la manipulación de datos.\n        Console.WriteLine(vbCrLf & \"Listas\")\n\n        Dim nombres As New List(Of String)\n        Dim abc As New List(Of String) From {\"a\", \"c\", \"d\", \"e\"}\n\n        ' Inserción:\n        nombres.Add(\"Ben\") ' Agrega elemento al final de la lista.\n        abc.Insert(1, \"b\") ' Agrega un elemento en una posición específica.\n\n        ' Acceder:\n        Console.WriteLine(abc(1))\n\n        ' Modificar:\n        nombres(0) = \"Zoe\"\n\n        ' Eliminacion:\n        abc.Remove(\"a\")\n        abc.RemoveAt(1) ' por indice \n        abc.RemoveAll(Function(x) x = \"c\") ' todas las ocurrencias\n\n        ' Ordenación:\n        abc.Sort()\n\n        ' Iteración:\n        For Each i As String In abc\n            Console.WriteLine(i)\n        Next\n\n        '_______________________________________________________\n        ' Dictionary(Diccionarios):\n        ' - Asocian claves únicas con valores, permitiendo búsquedas eficientes.\n        ' - Almacenar y recuperar datos con base en claves.\n        Console.WriteLine(vbCrLf & \"Diccionarios\")\n\n        Dim nombre_edad As New Dictionary(Of String, Integer)\n        Dim dic As New Dictionary(Of String, Integer) From {\n            {\"a\", 1},\n            {\"b\", 2}\n        }\n\n        ' Inserción:\n        nombre_edad(\"Zoe\") = 21\n        dic.Add(\"c\", 3)\n\n        ' Acceder:\n        Console.WriteLine(dic(\"b\"))\n        ' No mostrar excepción en caso de no existir.\n        Dim valorx As String = Nothing\n        If dic.TryGetValue(\"b\", valorx) Then\n            Console.WriteLine(valorx)\n        End If\n\n        ' Modificar:\n        nombre_edad(\"Zoe\") = 27\n\n        ' Eliminacion:\n        dic.Remove(\"c\")\n\n        ' Iteración:\n        For Each valor As Integer In dic.Values ' o dic.Keys\n            Console.WriteLine(valor)\n        Next\n\n        '_______________________________________________________\n        ' HashSet(Conjuntos):\n        ' - Colección sin duplicados, sin orden definido.\n        ' - Verificación de pertenencia y eliminación de duplicados.\n        Console.WriteLine(vbCrLf & \"Conjuntos\")\n\n        Dim miConjunto As New HashSet(Of Integer)\n        Dim otroConjunto = New HashSet(Of Integer) From {2, 3, 4}\n\n        ' Inserción:\n        miConjunto.Add(1)\n        miConjunto.Add(2)\n\n        ' Buscar:\n        If otroConjunto.Contains(3) Then\n            Console.WriteLine($\"El conjunto contiene el elemento 3: {otroConjunto.Contains(3)}\")\n        End If\n\n        ' Eliminacion:\n        miConjunto.Remove(2)\n\n        ' Verificación:\n        Console.WriteLine(miConjunto.Contains(1))\n\n        ' Operaciones:\n        miConjunto.UnionWith(otroConjunto)     ' Unión de conjuntos\n        miConjunto.IntersectWith(otroConjunto) ' Intersección de conjuntos\n        miConjunto.ExceptWith(otroConjunto)    ' Diferencia de conjuntos\n\n        ' Iteración:\n        For Each elemento As Integer In otroConjunto\n            Console.WriteLine(elemento)\n        Next\n\n        '_______________________________________________________\n        ' Matrices:\n        ' - Estructura bidimensional organizada en filas y columnas.\n        ' - Representar datos tabulares.\n        Console.WriteLine(vbCrLf & \"Matrices\")\n\n        Dim mtx1(2, 2) As Integer\n        Dim mtx2(,) As Integer = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}\n\n        ' asignación:\n        mtx1(0, 0) = 1\n        mtx1(0, 1) = 2\n        mtx1(0, 2) = 3\n\n        ' Acceder:\n        Console.WriteLine(mtx1(0, 1))\n\n        ' Iteración:\n        Dim filas = mtx2.GetLength(0)\n        Dim columnas = mtx2.GetLength(1)\n        For i = 0 To filas - 1\n            For j = 0 To columnas - 1\n                Console.Write(mtx2(i, j) & \" \")\n            Next\n            Console.WriteLine()\n        Next\n\n        '_______________________________________________________\n        ' Tuple(tuplas):\n        ' - Agrupación de elementos heterogéneos como una entidad única.\n        ' - Son inmutables.\n        ' - Devolver múltiples valores desde un método.\n        Console.WriteLine(vbCrLf & \"tuplas\")\n\n        Dim miTupla = (1, \"hola\", 3.14, True)\n        Dim tuplaConNombres = (numero:=1, saludo:=\"hola\", pi:=3.14, esCierto:=True)\n        Dim item1 As Object = 1\n        Dim item2 As Object = \"hola\"\n        Dim miTupla2 = New ValueTuple(Of Object, Object)(item1, item2)\n\n        ' Acceder:\n        Console.WriteLine(miTupla.Item1)\n        Console.WriteLine(tuplaConNombres.saludo)\n\n        '_______________________________________________________\n        ' Ejercicio:\n        ' * Crea una agenda de contactos por terminal.\n        ' * - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n        ' * - Cada contacto debe tener un nombre y un número de teléfono.\n        ' * - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n        ' *   los datos necesarios para llevarla a cabo.\n        ' * - El programa no puede dejar introducir números de teléfono no númericos y con más de 11 dígitos.\n        ' *   (o el número de dígitos que quieras)\n        ' * - También se debe proponer una operación de finalización del programa.\n        Console.WriteLine(vbCrLf & \"Ejercicio\")\n\n        While True\n            Agenda()\n        End While\n    End Sub\n\n    Dim miAgenda As New Dictionary(Of String, String)\n    Dim msg_home As String = (\"\n Agenda de contactos\n╔═══════════════════════════╗\n║ 1. Nuevo      4. Editar   ║\n║ 2. Buscar     5. Eliminar ║\n║ 3. Lista      6. Salir    ║\n╚═══════════════════════════╝\n\")\n    Sub Agenda()\n        Console.WriteLine(msg_home)\n        Console.Write(\"Número de opción: \")\n        Dim opcion As String = Console.ReadLine()\n\n        Select Case opcion\n            Case \"1\"\n                Crear()\n            Case \"2\"\n                Buscar()\n            Case \"3\"\n                Lista()\n            Case \"4\"\n                Editar()\n            Case \"5\"\n                Eliminar()\n            Case \"6\"\n                Console.WriteLine(\"Adios\")\n                Environment.Exit(0)\n            Case Else\n                Console.WriteLine(\"Número 1 -> 6\")\n        End Select\n    End Sub\n\n    Sub Crear()\n        Console.WriteLine(\"Crear contacto o 6 para Salir\")\n        Console.Write(\"Escriba el nombre: \")\n        Dim nombre As String = Console.ReadLine()\n\n        If nombre.Length < 1 Then\n            Crear()\n        ElseIf nombre = \"6\" Then\n            Console.WriteLine(\"Cancelado\")\n        ElseIf miAgenda.ContainsKey(nombre) Then\n            Console.WriteLine(\"El nombre ya existe.\")\n        Else\n            Console.Write(\"Escriba el número: \")\n            Dim numero As String = Console.ReadLine()\n\n            If Integer.TryParse(numero, Nothing) AndAlso numero.Length > 0 AndAlso numero.Length <= 11 Then\n                miAgenda(nombre) = numero\n                Console.WriteLine(\"Guardado\")\n            Else\n                Console.WriteLine(\"Número no válido.\")\n            End If\n        End If\n    End Sub\n\n    Sub Buscar()\n        Console.WriteLine(\"Buscar contacto o 6 para Salir\")\n        Console.Write(\"Escriba el nombre: \" & vbCrLf)\n        Dim nombre As String = Console.ReadLine()\n\n        If nombre = \"6\" Then\n            Console.WriteLine(\"Cancelado\")\n        ElseIf miAgenda.ContainsKey(nombre) Then\n            Console.WriteLine(miAgenda(nombre))\n        Else\n            Console.WriteLine(\"Contacto no encontrado.\")\n        End If\n    End Sub\n\n    Sub Lista()\n        Dim ordenarAgenda As New SortedDictionary(Of String, String)(miAgenda)\n\n        For Each entry In ordenarAgenda\n            Console.WriteLine($\"{entry.Key}: {entry.Value}\")\n        Next\n    End Sub\n\n    Sub Editar()\n        Console.WriteLine(\"Editar contacto o 6 para Salir\")\n        Console.Write(\"Escriba el nombre: \")\n        Dim nombre As String = Console.ReadLine()\n\n        If nombre = \"6\" Then\n            Console.WriteLine(\"Cancelado\")\n        ElseIf miAgenda.ContainsKey(nombre) Then\n            Console.Write(\"Escriba el nuevo número: \")\n            Dim nuevoNumero As String = Console.ReadLine()\n\n            If Integer.TryParse(nuevoNumero, Nothing) AndAlso nuevoNumero.Length > 0 AndAlso nuevoNumero.Length <= 11 Then\n                miAgenda(nombre) = nuevoNumero\n                Console.WriteLine(\"Contacto editado\")\n            Else\n                Console.WriteLine(\"Número no válido.\")\n            End If\n        Else\n            Console.WriteLine(\"Contacto no encontrado.\")\n        End If\n    End Sub\n\n    Sub Eliminar()\n        Console.WriteLine(\"Eliminar contacto o 6 para Salir\")\n        Console.Write(\"Escriba el nombre: \")\n        Dim nombre As String = Console.ReadLine()\n\n        If nombre = \"6\" Then\n            Console.WriteLine(\"Cancelado\")\n        ElseIf miAgenda.ContainsKey(nombre) Then\n            miAgenda.Remove(nombre)\n            Console.WriteLine(\"Contacto eliminado\")\n        Else\n            Console.WriteLine(\"Contacto no encontrado.\")\n        End If\n    End Sub\nEnd Module\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/arduino/santyjl.ino",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\nString string1 = \"Hola Mundo \";\nString string2 = \"esto es arduino\";\n\nvoid setup() {\n  Serial.begin(9600);\n\n  // Acceso a caracteres específicos\n  char tercerCaracter = string1[2];\n  Serial.print(\"Acceso a caracteres específicos: \");\n  Serial.println(tercerCaracter);\n\n  // Subcadenas\n  String subcadena = string1.substring(0, 5);\n  Serial.print(\"Subcadena: \");\n  Serial.println(subcadena);\n\n  // Longitud\n  int longitud = string1.length();\n  Serial.print(\"Longitud: \");\n  Serial.println(longitud);\n\n  // Concatenación\n  String string3 = string1 + string2;\n  Serial.print(\"Concatenación: \");\n  Serial.println(string3);\n\n  // Repetición\n  String repeticiones = repetirCadena(string3, 2);\n  Serial.print(\"Repeticiones: \");\n  Serial.println(repeticiones);\n\n  // Recorrido\n  Serial.print(\"Recorrido: \");\n  for (int i = 0; i < string3.length(); i++) {\n    char caracter = string3[i];\n    Serial.print(caracter);\n  }\n  Serial.println();\n\n  // Conversión a mayúsculas y minúsculas\n  string3.toUpperCase();\n  Serial.print(\"Mayúsculas: \");\n  Serial.println(string3);\n  string3.toLowerCase();\n  Serial.print(\"Minúsculas: \");\n  Serial.println(string3);\n\n  // Reemplazo\n  string3.replace(\"Arduino\", \"microPython\");\n  Serial.print(\"Reemplazo: \");\n  Serial.println(string3);\n\n  // División\n  int espacioIndex = string3.indexOf(' ');\n  String primeraPalabra = string3.substring(0, espacioIndex);\n  String segundaPalabra = string3.substring(espacioIndex + 1);\n  Serial.print(\"División - Primera Palabra: \");\n  Serial.println(primeraPalabra);\n  Serial.print(\"División - Segunda Palabra: \");\n  Serial.println(segundaPalabra);\n\n  // Unión\n  String concatenacion = primeraPalabra + \" \" + segundaPalabra;\n  Serial.print(\"Unión: \");\n  Serial.println(concatenacion);\n\n  // Interpolación\n  int variable = 42;\n  String mensaje = \"El valor de la variable es \" + String(variable);\n  Serial.print(\"Interpolación: \");\n  Serial.println(mensaje);\n\n  // Verificación\n  if (string3.indexOf(\"arduino\") != -1) {\n    Serial.println(\"Contiene 'arduino'\");\n  }\n\n  //extra reto\n  String resultadoPalindromo = palindromo(\"reconocer\");\n  Serial.print(\"Palíndromo: \");\n  Serial.println(resultadoPalindromo);\n\n  String resultadoAnagramas = Anagramas(\"listen\", \"silent\");\n  Serial.print(\"Anagramas: \");\n  Serial.println(resultadoAnagramas);\n\n  String resultadoIsograma = isograma(\"murcielago\");\n  Serial.print(\"Isograma: \");\n  Serial.println(resultadoIsograma);\n}\n\nvoid loop() {\n  // Tu código en el loop, si es necesario\n}\n\nString repetirCadena(String cadena, int veces) {\n  String resultado = \"\";\n  for (int i = 0; i < veces; i++) {\n    resultado += cadena;\n  }\n  return resultado;\n}\n\nString palindromo(String texto) {\n  if (texto != invertirTexto(texto)) {\n    return \"no es un palíndromo\";\n  } else {\n    return \"si es un palíndromo\";\n  }\n}\n\nString Anagramas(String texto1, String texto2) {\n  if (texto1.length() != texto2.length()) {\n    return \"no es un anagrama\";\n  }\n\n  for (int i = 0; i < texto1.length(); i++) {\n    char caracter = texto1[i];\n\n    if (texto2.indexOf(caracter) == -1) {\n      return \"no es un anagrama\";\n    }\n  }\n\n  // Si pasa todas las verificaciones, son anagramas\n  return \"si es un anagrama\";\n}\n\nString isograma(String texto) {\n  for (int i = 0; i < texto.length(); i++) {\n    char caracter = texto[i];\n\n    if (texto.indexOf(caracter, i + 1) != -1) {\n      return \"no es un isograma\";\n    }\n  }\n  return \"si es un isograma\";\n}\n\nString invertirTexto(String texto) {\n  String textoInvertido = \"\";\n  int longitud = texto.length();\n\n  for (int i = longitud - 1; i >= 0; i--) {\n    textoInvertido += texto[i];\n  }\n\n  return textoInvertido;\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/bash/drvito1977.sh",
    "content": "#!/bin/bash\n\n# Función para mostrar ejemplos de operaciones con cadenas de caracteres\nfunction ejemplos_cadenas {\n  cadena=\"Hola Mundo\"\n\n  # Acceso a caracteres específicos\n  primer_caracter=${cadena:0:1} # Obtiene el primer carácter de la cadena\n  ultimo_caracter=${cadena: -1} # Obtiene el último carácter de la cadena\n  echo \"Primer carácter: $primer_caracter\"\n  echo \"Último carácter: $ultimo_caracter\"\n\n  # Subcadenas\n  subcadena=${cadena:0:4} # Obtiene una subcadena desde el inicio hasta el cuarto carácter\n  echo \"Subcadena: $subcadena\"\n\n  # Longitud de la cadena\n  longitud=${#cadena} # Calcula la longitud de la cadena\n  echo \"Longitud de la cadena: $longitud\"\n\n  # Concatenación\n  concatenada=\"${cadena}!\" # Concatenación de la cadena con un signo de exclamación\n  echo \"Concatenación: $concatenada\"\n\n  # Repetición (simulación)\n  repetida=$(printf \"%.0sHa\" {1..3}) # Repite \"Ha\" tres veces\n  echo \"Repetición: $repetida\"\n\n  # Recorrido de la cadena\n  echo \"Recorrido de la cadena:\"\n  for (( i=0; i<${#cadena}; i++ )); do\n    echo \"${cadena:$i:1}\" # Imprime cada carácter de la cadena en una nueva línea\n  done\n\n  # Conversión a mayúsculas y minúsculas\n  mayusculas=${cadena^^} # Convierte la cadena a mayúsculas\n  minusculas=${cadena,,} # Convierte la cadena a minúsculas\n  echo \"Mayúsculas: $mayusculas\"\n  echo \"Minúsculas: $minusculas\"\n\n  # Reemplazo\n  reemplazo=${cadena/Mundo/Bash} # Reemplaza \"Mundo\" por \"Bash\" en la cadena\n  echo \"Reemplazo: $reemplazo\"\n\n  # División\n  IFS=' ' read -r -a palabras <<< \"$cadena\" # Divide la cadena en palabras usando el espacio como delimitador\n  echo \"División en palabras: ${palabras[@]}\"\n\n  # Unión\n  unidas=$(IFS=,; echo \"${palabras[*]}\") # Une las palabras con una coma como separador\n  echo \"Unión de palabras: $unidas\"\n\n  # Interpolación\n  interpolacion=\"La cadena es: $cadena\" # Interpolación de la cadena en otra cadena\n  echo \"Interpolación: $interpolacion\"\n\n  # Verificación\n  if [[ $cadena == *\"Mundo\"* ]]; then\n    echo \"La cadena contiene 'Mundo'\" # Verifica si la cadena contiene la palabra \"Mundo\"\n  fi\n}\n\n# Función para comprobar si una palabra es un palíndromo\nfunction es_palindromo {\n  palabra=$1\n  invertida=$(echo $palabra | rev) # Invierte la palabra\n  if [[ $palabra == $invertida ]]; then\n    echo \"$palabra es un palíndromo\" # Comprueba si la palabra es igual a su versión invertida\n  else\n    echo \"$palabra no es un palíndromo\"\n  fi\n}\n\n# Función para comprobar si dos palabras son anagramas\nfunction son_anagramas {\n  palabra1=$(echo $1 | grep -o . | sort | tr -d \"\\n\") # Ordena las letras de la primera palabra\n  palabra2=$(echo $2 | grep -o . | sort | tr -d \"\\n\") # Ordena las letras de la segunda palabra\n  if [[ $palabra1 == $palabra2 ]]; then\n    echo \"$1 y $2 son anagramas\" # Comprueba si las palabras ordenadas son iguales\n  else\n    echo \"$1 y $2 no son anagramas\"\n  fi\n}\n\n# Función para comprobar si una palabra es un isograma\nfunction es_isograma {\n  palabra=$1\n  letras=$(echo $palabra | grep -o . | sort | uniq -d) # Busca letras duplicadas\n  if [[ -z $letras ]]; then\n    echo \"$palabra es un isograma\" # Comprueba si no hay letras duplicadas\n  else\n    echo \"$palabra no es un isograma\"\n  fi\n}\n\n# Llamada a la función de ejemplos de cadenas\nejemplos_cadenas\n\n# Comprobaciones de palabras\npalabra1=\"radar\"\npalabra2=\"dormir\"\npalabra3=\"amor\"\npalabra4=\"roma\"\npalabra5=\"isograma\"\n\necho\nes_palindromo $palabra1\nes_palindromo $palabra2\n\necho\nson_anagramas $palabra3 $palabra4\n\necho\nes_isograma $palabra5"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/bash/rantamhack.sh",
    "content": "#!/bin/bash\n\necho -e \"\\n\\n===============================OPERACIONES CON STRINGS===============================\\n\\n\"\n\n# Concatenacion\na=\"Hello\"\nb=\" World\"\nc=$a$b\necho $c\n\n# Multiplicar una cadena\na=\"Hello World\"\nfor i in $(seq 1 5);do\n    echo $a\ndone\n\n# Iterar en una cadena de texto\na=\"Hello World\"\nfor i in $a;do\n    echo $i\ndone\n\n# Convertir una cadena de texto a mayusculas\nstring=\"¡Es cierto! Siempre he sido nervioso, muy nervioso, terriblemente nervioso.\"\necho ${string^^}\n\n# Convertir una cadena de texto a minusculas\nstring=\"¡Es cierto! Siempre he sido nervioso, muy nervioso, terriblemente nervioso.\"\necho ${string,,}\n\n# cortar una cadena por el final\nstring=\"¡Es cierto! Siempre he sido nervioso, muy nervioso, terriblemente nervioso.\"\necho ${string: -9}\n\n# cortar una cadena por el principio\nstring=\"¡Es cierto! Siempre he sido nervioso, muy nervioso, terriblemente nervioso.\"\necho ${string: 12}\n\n# cortar una cadena por el principio y por el final\nstring=\"¡Es cierto! Siempre he sido nervioso, muy nervioso, terriblemente nervioso.\"\necho ${string: 12:-9}\n\n# Reemplazar texto\nstring=\"¡Es cierto! siempre he sido nervioso, muy nervioso, terriblemente nervioso.\" \necho ${string/s/z}   # Cambia solo la primera letra\necho ${string//s/z}  # Cambia todas las letras coincidentes\n\n# Contando los caracteres que tiene la cadena\nstring=\"¡Es cierto! siempre he sido nervioso, muy nervioso, terriblemente nervioso.\" \necho ${#string}\n\n# Interpolar\nstring=\"'¡Es cierto! siempre he sido nervioso, muy nervioso, terriblemente nervioso'\" \nauthor=\"Edgar Allan Poe\"\necho \"El texto $string es el comienzo de una novela de $author\"\n\necho -e \"\\n\\n===============================DIFICULTAD EXTRA===============================\\n\\n\"\n\nread -p \"Introduce la palabra que quieres comprobar: \" var\n\nfunction palindromo(){\n    var=${var,,}\n    var=${var//\" \"/\"\"}\n    if [[ $(rev <<< \"$var\") == \"$var\" ]]; then\n        echo \"$var es un palindromo\"\n    else\n        echo \"$var no es un palindromo\"\n    fi\n}\n\npalindromo "
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/bash/santyjL.sh",
    "content": "#!/bin/bash\n\n: \"\n/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n * - Análisis de longitud\n * - Comparación de caracteres\n */\n\"\n\nstring1=\"hola\"\nstring2=\"mundo\"\n\n# Acceso a caracteres específicos\necho \"Primer carácter de string1: ${string1:0:1}\"  # Primer carácter\necho \"Último carácter de string2: ${string2: -1}\"  # Último carácter\n\n# longitud\necho \"Longitud de string1: ${#string1}\"  # Longitud de string1\necho \"Longitud de string2: ${#string2}\"  # Longitud de string2\n\n# Concatenacion\necho \"Concatenación: $string1 - $string2\"  # Concatenación de dos cadenas\n\n# Repeticion\nrepeated_string=\"\"\nfor i in {1..3}; do\n\trepeated_string+=\"$string1\"\ndone\necho \"Repetición de string1: $repeated_string\"\n\n# recorrido\nfor (( i=0; i<${#string1}; i++ )); do\n\techo \"Carácter en posición $i de string1: ${string1:i:1}\"\ndone\n\n# conversión a mayúsculas\necho \"String1 en mayúsculas: ${string1^^}\"\n\n# conversión a minúsculas\necho \"String1 en minúsculas: ${string1,,}\"\n\n# Reemplazo\necho \"Reemplazo de 'ho' por 'o' en string1: ${string1/ho/O}\"  # Reemplaza la primera ocurrencia\n\n# División\nIFS=',' read -r -a words <<< \"$string1, $string2, esto, esta, separando, por, comas\"  # Divide en palabras\necho \"División de string1 y string2 en palabras: ${words[@]}\"  # siempre reemplazo los lugares con espacios\n\n# Unión\nunion_string=\"$string1$string2\"\necho \"Unión de string1 y string2: $union_string\"\n\n# Interpolación\necho \"Interpolación: $string1 y $string2 son cadenas de caracteres.\"\n\n# Verificación\nif [[ $string1 == *\"hola\"* ]]; then\n  \techo \"string1 contiene 'hola'\"\nelse\n  \techo \"string1 no contiene 'hola'\"\nfi\n\nfunction es_poligroma(){\n    local palabra_input=$1\n    local palabra_invertida=$(echo \"$palabra_input\" | rev)\n\n    if [[ \"$palabra_input\" == \"$palabra_invertida\" ]]; then\n        echo \"La palabra ${palabra_input} es poligroma\"\n    else\n        echo \"La palabra ${palabra_input} no es poligroma\"\n    fi\n}\n\nfunction es_anagrama(){\n\tlocal palabra1=$1\n\tlocal palabra2=$2\n\n\tif [[ ${#palabra1} -ne ${#palabra2} ]]; then\n\t\techo \"Las palabras no son anagramas, ya que tienen diferente longitud\"\n\t\treturn 0\n\tfi\n\n\n\tfor (( i=0; i<${#palabra1}; i++ )); do\n\t\tcaracter=${palabra1:i:1}\n\t\tif [[ ! $palabra2 =~ $caracter ]]; then\n\t\t\techo \"Las palabras no son anagramas\"\n\t\t\treturn 0\n\t\tfi\n\tdone\n\n\techo \"Las palabras son anagramas\"\n\n}\n\nfunction es_isograma(){\n\n\tlocal palabra_input=$1\n\tlocal palabra_nueva=\"\"\n\n\tfor (( i=0; i<${#palabra_input}; i++ )); do\n\t\tif [[ $palabra_nueva == *\"${palabra_input:i:1}\"* ]]; then\n\t\t\techo \"La palabra ${palabra_input} no es isograma\"\n\t\t\treturn 0\n\t\tfi\n\t\tpalabra_nueva+=\"${palabra_input:i:1}\"\n\tdone\n\n\techo \"La palabra ${palabra_input} es isograma\"\n}\n\nfunction analisis_final() {\n\tlocal palabra1=$1\n\tlocal palabra2=$2\n\n\techo -e \"\\nAnálisis de longitud:\"\n\techo \"Longitud de '$palabra1': ${#palabra1}\"\n\techo \"Longitud de '$palabra2': ${#palabra2}\"\n\n\techo \"Comparación de caracteres:\"\n\tif [[ \"$palabra1\" == \"$palabra2\" ]]; then\n\t\techo \"Las palabras son iguales.\"\n\telse\n\t\techo \"Las palabras son diferentes.\"\n\tfi\n\n\techo \"Verificando si son palíndromos:\"\n\tes_poligroma \"$palabra1\"\n\tes_poligroma \"$palabra2\"\n\n\techo \"Verificando si son anagramas:\"\n\tes_anagrama \"$palabra1\" \"$palabra2\"\n\n\techo \"Verificando si son isogramas:\"\n\tes_isograma \"$palabra1\"\n\tes_isograma \"$palabra2\"\n}\n\n# Llamada a la función principal\nanalisis_final \"uva\" \"oso\"\n\n\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/c/N0HagoNada.c",
    "content": "#include <stdio.h>\n#include <string.h>\n#include <ctype.h>\n#include <stdlib.h>\n\n#define MAX_LEN 100\n\n// Función para comprobar si una palabra es un palíndromo\nint esPalindromo(char *palabra)\n{\n    int longitud = strlen(palabra);\n    for (int i = 0; i < longitud / 2; i++)\n    {\n        if (tolower(palabra[i]) != tolower(palabra[longitud - i - 1]))\n        {\n            return 0; // No es palíndromo\n        }\n    }\n    return 1; // Es palíndromo\n}\n\n// Función para comprobar si dos palabras son anagramas\nint sonAnagramas(char *palabra1, char *palabra2)\n{\n    int count[256] = {0};\n    int i;\n\n    for (i = 0; palabra1[i] && palabra2[i]; i++)\n    {\n        count[(int)tolower(palabra1[i])]++;\n        count[(int)tolower(palabra2[i])]--;\n    }\n\n    if (palabra1[i] || palabra2[i])\n    { // Si las palabras son de diferente longitud\n        return 0;\n    }\n\n    for (i = 0; i < 256; i++)\n    {\n        if (count[i])\n        {\n            return 0; // No son anagramas\n        }\n    }\n    return 1; // Son anagramas\n}\n\n// Función para comprobar si una palabra es un isograma\nint esIsograma(char *palabra)\n{\n    int count[256] = {0};\n\n    for (int i = 0; palabra[i]; i++)\n    {\n        if (count[(int)tolower(palabra[i])])\n        {\n            return 0; // No es isograma\n        }\n        count[(int)tolower(palabra[i])]++;\n    }\n    return 1; // Es isograma\n}\nint main()\n{\n    // Definición de la cadena original\n    char str[] = \"Hola mundo\";\n    char copia[20]; // Para operaciones que necesitan una copia\n\n    // Acceso a caracteres específicos\n    printf(\"Primer caracter: %c\\n\", str[0]);\n\n    // Subcadenas\n    strncpy(copia, str + 5, 5); // Copia \"mundo\" en copia\n    copia[5] = '\\0';            // Añade manualmente el carácter nulo\n    printf(\"Subcadena: %s\\n\", copia);\n\n    // Longitud\n    printf(\"Longitud: %lu\\n\", strlen(str));\n\n    // Concatenación\n    char saludo[20] = \"Hola\";\n    strcat(saludo, \", mundo\");\n    printf(\"Concatenación: %s\\n\", saludo);\n\n    // Conversión a mayúsculas\n    for (int i = 0; str[i]; i++)\n    {\n        str[i] = toupper(str[i]);\n    }\n    printf(\"A mayúsculas: %s\\n\", str);\n\n    // Conversión a minúsculas\n    for (int i = 0; str[i]; i++)\n    {\n        str[i] = tolower(str[i]);\n    }\n    printf(\"A minúsculas: %s\\n\", str);\n\n    // Recorrido\n    printf(\"Recorrido: \");\n    for (int i = 0; str[i]; i++)\n    {\n        printf(\"%c\", str[i]);\n    }\n    printf(\"\\n\");\n\n    // División (Tokenización)\n    char str2[] = \"Hola mundo, prueba\"; // Nueva cadena para evitar modificar la original en la tokenización\n    printf(\"División:\\n\");\n    char *token = strtok(str2, \" ,\");\n    while (token != NULL)\n    {\n        printf(\"%s\\n\", token);\n        token = strtok(NULL, \" ,\");\n    }\n\n    // Verificación (Buscar Subcadena)\n    strcpy(copia, \"Hola mundo\"); // Restablecer copia a un valor conocido\n    if (strstr(copia, \"mundo\") != NULL)\n    {\n        printf(\"Subcadena encontrada.\\n\");\n    }\n    else\n    {\n        printf(\"Subcadena no encontrada.\\n\");\n    }\n\n    char palabra1[MAX_LEN], palabra2[MAX_LEN];\n\n    printf(\"Introduce la primera palabra: \");\n    scanf(\"%99s\", palabra1);\n    printf(\"Introduce la segunda palabra: \");\n    scanf(\"%99s\", palabra2);\n\n    // Comprobar si las palabras son palíndromos\n    printf(\"'%s' es un palíndromo? %s\\n\", palabra1, esPalindromo(palabra1) ? \"Sí\" : \"No\");\n    printf(\"'%s' es un palíndromo? %s\\n\", palabra2, esPalindromo(palabra2) ? \"Sí\" : \"No\");\n\n    // Comprobar si las palabras son anagramas\n    printf(\"'%s' y '%s' son anagramas? %s\\n\", palabra1, palabra2, sonAnagramas(palabra1, palabra2) ? \"Sí\" : \"No\");\n\n    // Comprobar si las palabras son isogramas\n    printf(\"'%s' es un isograma? %s\\n\", palabra1, esIsograma(palabra1) ? \"Sí\" : \"No\");\n    printf(\"'%s' es un isograma? %s\\n\", palabra2, esIsograma(palabra2) ? \"Sí\" : \"No\");\n\n    return 0;\n}"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/c/d1d4cum.c",
    "content": "#include <string.h>\n#include <stdbool.h>\n#include <stdio.h>\n#include <string.h>\n#include <ctype.h>\n\n\n/*\nchar name[] = \"Diego\";\nchar hello[20] = {'H', 'e', 'l', 'l', 'o', ' ', '\\0'};\nchar saludo[] = \"\\tHola \\\"amigo\\\"\";\nprintf(\"%s\\n\", name);\nprintf(\"%s\\n\", hello);\nprintf(\"%s\\n\", saludo);\n\n// Acceso\nprintf(\"%c\\n\", name[0]);\n\n//Modificar\nname[0] = 'd';\nprintf(\"%s\\n\", name);\n\n//Interar\nint length = sizeof(name) / sizeof(name[0]);\n\nfor (int i = 0; i < length; i++) {\n    printf(\"%c\\n\", name[i]);\n}\n\n// Tamaño\nint size = strlen(saludo);\nprintf(\"%d\\n\", size);\n\n//Concatenar\nstrcat(hello, name);\nprintf(\"%s\\n\", hello);\n\n//Copiar\nchar str[20];\nstrcpy(str, hello);\nprintf(\"%s\\n\", str);\n\n//Comparar\nprintf(\"%d\\n\", strcmp(hello, str));\n*/\n\n\nbool isPalindrome(const char *str) {\n    int len = strlen(str);\n    char backwards[len + 1];\n\n    for (int i = 0; i < len; i++) {\n        backwards[i] = str[len - 1 - i];\n    }\n    backwards[len] = '\\0';\n\n    if (strcmp(str, backwards) == 0) {\n        return true;\n    }\n\n    return false;\n}\n\nbool areAnagrams(char *str1, char *str2) {\n    int count[256] = {0}; // Asumiendo ASCII\n\n    // Si las longitudes son diferentes, no pueden ser anagramas\n    if (strlen(str1) != strlen(str2)) {\n        return false;\n    }\n\n    // Incrementar el conteo de caracteres para str1\n    // y decrementar el conteo de caracteres para str2\n    for (int i = 0; str1[i] && str2[i]; i++) {\n        count[(unsigned char)str1[i]]++;\n        count[(unsigned char)str2[i]]--;\n    }\n\n    // Verificar si todos los conteos son cero\n    for (int i = 0; i < 256; i++) {\n        if (count[i] != 0) {\n            return false;\n        }\n    }\n\n    return true;\n}\n\nbool isIsogram(char str[]) {\n    int len = strlen(str);\n    int frequency[256] = {0};\n\n    for (int i = 0; i < len; i++) {\n        char ch = tolower((unsigned char)str[i]);\n\n        if (frequency[(unsigned char)ch] > 0) {\n            return false;\n        }\n        frequency[(unsigned char)ch]++;\n    }\n\n    return true;\n}\n\nint main() {\n\n    char firstWord[30];\n    char secondWord[30];\n\n    printf(\"Escribe la primera palabra\\n > \");\n    scanf(\"%s\", firstWord);\n    printf(\"Escribe la segunda palabra\\n > \");\n    scanf(\"%s\", secondWord);\n\n    if (isPalindrome(firstWord)) {\n        printf(\"%s es un palíndromo\\n\", firstWord);\n    }\n    if (isPalindrome(secondWord)) {\n        printf(\"%s es un palíndromo\\n\", secondWord);\n    }\n\n    if (areAnagrams(firstWord, secondWord)) {\n        printf(\"%s y %s son anagramas\\n\", firstWord, secondWord);\n    }\n\n    if (isIsogram(firstWord)) {\n        printf(\"%s es un isograma\\n\", firstWord);\n    }\n    if (isIsogram(secondWord)) {\n        printf(\"%s es un isograma\\n\", secondWord);\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/c/jchavescaceres.c",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n/*\nFunctions defined in string.h:\n\nstrcpy \nstrcat \nstrcmp \nstrcoll \nstrxfrm (NOT COVERED)\nstrdup \nstrchr \nstrrchr \nstrcspn \nstrspn \nstrpbrk \nstrstr \nstrtok \nstrtok_r \nstrlen \nstrerror \nstrerror_r \nstrerrordesc_np (NOT COVERED) \nstrerrorname_np  (NOT COVERED)\nstrerror_l \nstrsep \nstrsignal \nstpcpy \n\nstrncpy \nstrncat \nstrncmp \nstrndup \nstrnlen \nstpncpy \n*/\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <locale.h>\n\nvoid advanced();\n\n/*\n1 if a word is the same reading from left to right and from right to left, e.g. noon\n*/\nint isPalindrome (const char* inString1, const char* inString2);\n\n/*\n1 if both words are anagram: different word but with exactly same letters in a different order, e.g. night and thing\n*/\nint isAnagrame (const char* inString1, const char* inString2);\n\n/*\n1 if all letters of a word appear the same time, e.g. dialogue all letters appears just one, intestines all letters appears twice\n*/\nint isIsograme (const char* inString);\n\nvoid main () {\n\n\tconst char *string1 = \"Cadena 1\";\n\tconst char *string2 = \"Cadena 2\";\n\tchar *ptr = NULL;\n\tchar buffer [200];\n\tchar buffer2 [200];\n\n\tsetlocale(LC_COLLATE, \"es_ES.UTF-8\");\n\n\t/* Copy */\n\tmemset (buffer, 0, sizeof (buffer));\n\tstrcpy (buffer, string1);\n\tprintf (\"String1: %s, strcpy (buffer, string1), buffer: %s\\n\", string1, buffer);\n\n\t/* Copy but n characters*/\n\tmemset (buffer, 0, sizeof (buffer));\n\tstrncpy (buffer, string1, 4);\n\tprintf (\"String1: %s, strncpy (buffer, string1, %d), buffer: %s\\n\", string1, 4, buffer);\n\n\t/* Concat */\n\tmemset (buffer, 0, sizeof (buffer));\n\tstrcpy (buffer, string1);\n\tprintf (\"buffer: %s, string2: %s, strcat (buffer, string2), \", buffer, string2);\n\tstrcat (buffer, string2);\n\tprintf (\"buffer: %s\\n\", buffer);\n\n\t/* Concat n characters */\n\tmemset (buffer, 0, sizeof (buffer));\n\tstrcpy (buffer, string1);\n\tprintf (\"buffer: %s, string2: %s, strcat (buffer, string2, %d), \", buffer, string2, 4);\n\tstrncat (buffer, string2, 4);\n\tprintf (\"buffer: %s\\n\", buffer);\n\n\n\t/* Compare */\n\tstrcpy (buffer, string1);\n\tprintf( \"String1: %s, buffer: %s, strcmp (buffer, string1) = %d\\n\", string1, buffer, strcmp (buffer, string1));\n\n\t/* Compare n characters*/\n\tprintf( \"String1: %s, String2: %s, strncmp (string1, string2, %d) = %d\\n\", string1, string2, 4, strncmp (string1, string2, 4));\n\n\t/* Compare using locale LC_COLLATE */\n\tstrcpy (buffer, string1);\n\tprintf( \"String1: %s, buffer: %s, strcoll (buffer, string1) = %d\\n\", string1, buffer, strcoll (buffer, string1));\n\n\t/* Duplicate string, memory allocated must be freed */\n\tptr = strdup (string1);\n\tprintf( \"String1: %s, strdup: %s\\n\", string1, ptr);\n\tfree (ptr);\n\tptr = NULL;\n\t\n\t/* Duplicate string but n characters, memory allocated must be freed */\n\tptr = strndup (string1, 4);\n\tprintf( \"String1: %s, strndup(%d): %s\\n\", string1, 4, ptr);\n\tfree (ptr);\n\tptr = NULL;\n\n\t/* Find position (pointer) of character in string */\n\tprintf( \"String1: %s, strchr (a): %s\\n\", string1, strchr (string1, 'a'));\n\n\t/* Find last position (pointer) of character in string */\n\tprintf( \"String1: %s, strrchr (a): %s\\n\", string1, strrchr (string1, 'a'));\n\n\t/* Search in string1 if it starts with \"Cad\" and return following position*/\n\tprintf( \"String1: %s, strspn (string1, \\\"Cad\\\"): %lu\\n\", string1, strspn (string1, \"Cad\"));\n\n\t/* Search in string1 the characters b, c or d, return first position found */\n\tprintf( \"String1: %s, strcspn (string1, \\\"bcd\\\"): %lu\\n\", string1, strcspn (string1, \"bcd\"));\n\n\t/* Search in string1 the characters b, c or d, return pointer first position found */\n\tprintf( \"String1: %s, strpbrk (string1, \\\"a\\\"): %s\\n\", string1, strpbrk (string1, \"bcd\"));\n\n\t/* Search in string1 the string2, return pointer first position found */\n\tprintf( \"String1: %s, strstr (string1, \\\"dena\\\"): %s\\n\", string1, strstr (string1, \"dena\"));\n\n\t/* Split a string into tokens, to get all tokens then call the function with NULL value after the first time */\n\tchar testStrtok [] = \"1, 2, 3 y 4\";\n\tprintf( \"strtok (%s, \\\",\\\"): \", testStrtok);\n\tprintf( \"%s\\n\", strtok (testStrtok, \"-,\"));\n\tprintf( \"strtok (NULL, \\\",\\\"): %s\\n\", strtok (NULL, \"-,\"));\n\n\t/* Same as strtok but savePtr keep status in sucesive calls */\n\tchar * savePtr = NULL;\n\tchar testStrtok_r [] = \"1, 2, 3 y 4\";\n\tprintf( \"strtok_r (%s, \\\",\\\", &savePtr): \", testStrtok_r);\n\tprintf( \"%s\\n\", strtok_r (testStrtok_r, \"-,\", &savePtr));\n\tprintf( \"strtok_r (NULL, \\\",\\\", &savePtr): %s\\n\", strtok_r (NULL, \"-,\", &savePtr));\n\tprintf( \"strtok_r (NULL, \\\",\\\", &savePtr): %s\\n\", strtok_r (NULL, \"-,\", &savePtr));\n\n\t/* Another implementation of tokens separator, testStrsep is updated with rest of string after token */\n\tchar *testStrsep = malloc (200); \n\tchar *copiaTestStrsep = testStrsep;\n\tstrcpy (testStrsep , \"1, 2, 3 y 4\");\n\tprintf( \"strsep (%s, \\\",\\\"): \", testStrsep);\n\tprintf( \"%s\\n\", strsep (&testStrsep, \"-,\"));\n\tprintf( \"%s\\n\", testStrsep);\n\tfree (copiaTestStrsep);\n\n\t/* String length without counting \\0 at the end */\n\tprintf( \"String1: %s, strlen (string1): %lu\\n\", string1, strlen (string1));\n\n\t/* String length with a maximum characters without counting \\0 at the end */\n\tprintf( \"String1: %s, strnlen (string1, %d): %lu\\n\", string1, 4, strnlen (string1, 4));\n\tprintf( \"String1: %s, strnlen (string1, %d): %lu\\n\", string1, 400, strnlen (string1, 400));\n\t\n\t/* System error message, several implementations */\n\tprintf( \"strerror 4 %s\\n\", strerror (4));\n\tstrerror_r (4, buffer, sizeof (buffer) / sizeof (char));\n\tprintf( \"strerror 4 %s\\n\", buffer);\n\tprintf( \"strerror_l 4 %s\\n\", strerror_l (4, 0));\n\n\t/* Signal name as string */\n\tprintf( \"Signal %d, name %s \\n\", 15, strsignal (15));\n\n\tadvanced();\n\n\n};\n\nchar* getWord() {\n\tconst unsigned int MAX_BUFFER=200;\n        char buffer [MAX_BUFFER];\n        char *res = NULL;\n\n        printf(\"\\nNombre : \");\n        fgets (buffer, MAX_BUFFER, stdin);\n        buffer [strlen (buffer)-1] = '\\0'; /* remove \\n */\n        res = malloc (strlen (buffer)+1);\n\n        strcpy (res, buffer);\n\n        return res;\n};\n\nvoid advanced() {\n\n\tchar* words[2] ;\n\n\n\tprintf (\"Escribe primera palabra : \");\n\twords[0] = getWord();\n\tprintf (\"Escribe segunda palabra : \");\n\twords[1] = getWord();\n\n\tprintf (\"%s y %s %s son palíndromo\\n\", words[0], words[1], (isPalindrome (words[0], words[1]) ? \"\": \"no\"));\n\tprintf (\"%s y %s %s son anagramas\\n\", words[0], words[1], (isAnagrame (words[0], words[1]) ? \"\": \"no\"));\n\tprintf (\"%s %s es isograma\\n\", words[0], (isIsograme (words[0]) ? \"\": \"no\"));\n\tprintf (\"%s %s es isograma\\n\", words[1], (isIsograme (words[1]) ? \"\": \"no\"));\n\n\n\tfree (words[0]);\n\tfree (words[1]);\n};\n\nint isPalindrome (const char* inString1, const char* inString2) {\n\tint res = 1;\n\n\tif (strlen( inString1) == strlen (inString2)) {\n\t\tfor (int i = 0, mySize1 = strlen (inString1), j = strlen (inString2)-1; i < mySize1, j >=0; i++, j--) {\n\t\n\t\t\t\tif (inString1 [i] != inString2 [j]) {\n\t\t\t\t\t/* Is not a palindrome */\n\t\t\t\t\tres = 0;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t};\n\t}\n\telse {\n\t\tres = 0;\n\t};\n\treturn res;\n};\n\nvoid orderWord (char* word) {\n\n\tconst int sizeString = strlen(word);\n\tchar temp=0;\n\n\tfor (int i=1 ; i<sizeString ; i++) {\n\t\tfor (int j= 0; j < sizeString-i ; j++)  {\n\t\t\tif (word[j] > word[j+1]) {\n\t\t\t\ttemp=word[j];\n\t\t\t\tword[j]=word[j+1];\n\t\t\t\tword[j+1]=temp;\n\t\t\t}\n\t\t}\n\t}\n}\n\n\nint isAnagrame (const char* inString1, const char* inString2) {\n\n\tchar* string1 = malloc (strlen (inString1)+1);\n\tchar* string2 = malloc (strlen (inString1)+1);\n\tint res = 0;\n\n\tstrcpy (string1, inString1);\n\tstrcpy (string2, inString2);\n\n\t/* Order both words, if equal then they are anagrames */\n\torderWord (string1);\n\torderWord (string2);\n\n\tif (strcmp (string1, string2) == 0) {\n\n\t\tres = 1;\n\t};\n\n\tfree (string1);\n\tfree (string2);\n\n\treturn res;\n};\n\nint isIsograme (const char* inString) {\n\n\tint firstCount = 0;\n\tint count = 0;\n\tchar firstChar = 0;\n\tchar lastChar = 0;\n\tchar* string1 = malloc (strlen (inString)+1);\n\n\tint res = 1;\n\n\tstrcpy (string1, inString);\n\torderWord (string1);\n\n\t/* Count how many times each character appears */\n\tfor (int i = 0, mySize = strlen (string1) ; i < mySize; i++) {\n\n\t\tif (firstChar == 0) {\n\t\t\tfirstChar = string1 [i];\n\t\t\tfirstCount = 1;\n\t\t}\n\t\telse if (string1 [i] == firstChar) {\n\t\t\tfirstCount++;\n\t\t}\n\t\telse if (lastChar == 0) {\n\t\t\tlastChar = string1 [i];\n\t\t\tcount = 1;\n\t\t}\n\t\telse if (lastChar == string1 [i]) {\n\t\t\tcount++;\n\t\t}\n\t\telse if (lastChar != string1 [i]) {\n\t\t\tif (count != firstCount) {\n\t\t\t\tres=0;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tlastChar = string1 [i];\n\t\t\t\tcount = 1;\n\t\t\t};\n\t\t};\n\t};\n\tif (res == 1 && count != firstCount) {\n\t\tres = 0;\n\t};\n\n\tfree (string1);\n\treturn res;\n};\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/c/srvariable.c",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\n#define MSG1 \"Hola Mundo, esto es C.\"\n#define MSG2 \"Mundo\"\n\n#include <stdio.h>\n#include <string.h>\n#include <stdlib.h>\n#include <ctype.h>\n\nvoid\tft_strtoupper(char *str);\nvoid\tft_strtolower(char *str);\nchar\t*ft_strjoin(const char *s1, const char *s2);\nchar\t**ft_split(const char *s1, char delim);\nvoid\tft_freesplit(char ***split);\nint\t\tis_palindrome(const char *s1);\nint\t\tis_anagram(const char *s1, const char *s2);\nint\t\tis_isogram(const char *s1);\n\nint\tmain(void)\n{\n\t/* === 1 === */\n\tchar\ts1[100] = MSG1;\n\tchar\ts2[100] = MSG2;\n\tchar\t*ret = NULL;\n\tint\t\tret2 = 0;\n\tchar\t**ret3 = NULL;\n\n\tprintf(\"\\nAplicando stpcpy, para copiar s2 a s1\\n\");\n\tprintf(\"Antes -> s1: %s, s2: %s, ret: %s\\n\", s1, s2, ret);\n\tret = stpcpy(s1, s2);\n\tprintf(\"Después -> s1: %s, s2: %s, ret: %s\\n\", s1, s2, ret);\n\tprintf(\"stpcpy devuelve un puntero al final de s1\\n\");\n\tprintf(\"Dirección de memoria de s1: %p\\n\", s1);\n\tprintf(\"Dirección de memoria de ret: %p\\n\", ret);\n\n\tprintf(\"\\nRestaurando los valores originales...\\n\");\n\tstpcpy(s1, MSG1);\n\tret= NULL;\n\n\tprintf(\"\\nAplicando strcat, para concatenar s2 a s1\\n\");\n\tprintf(\"Antes -> s1: %s, s2: %s, ret: %s\\n\", s1, s2, ret);\n\tret = strcat(s1, s2);\n\tprintf(\"Después -> s1: %s, s2: %s, ret: %s\\n\", s1, s2, ret);\n\tprintf(\"strcat devuelve un puntero al inicio de s1\\n\");\n\tprintf(\"Dirección de memoria de s1: %p\\n\", s1);\n\tprintf(\"Dirección de memoria de ret: %p\\n\", ret);\n\n\tprintf(\"\\nRestaurando los valores originales...\\n\");\n\tstpcpy(s1, MSG1);\n\tret = NULL;\n\n\tprintf(\"\\nAplicando strchr, para encontrar la primera ocurrencia de 'a' en s1\\n\");\n\tprintf(\"Antes -> s1: %s, ret: %s\\n\", s1, ret);\n\tret = strchr(s1, 'a');\n\tprintf(\"Después -> s1: %s, ret: %s\\n\", s1, ret);\n\tprintf(\"strchr devuelve un puntero a la primera ocurrencia\\n\");\n\tprintf(\"Dirección de memoria de s1: %p\\n\", s1);\n\tprintf(\"Dirección de memoria de ret: %p\\n\", ret);\n\n\tprintf(\"\\nRestaurando los valores originales...\\n\");\n\tstpcpy(s1, MSG1);\n\tret = NULL;\n\n\tprintf(\"\\nAplicando strcmp, para comparar s1 y s2\\n\");\n\tprintf(\"Antes -> s1: %s, s2: %s, ret2: %d\\n\", s1, s2, ret2);\n\tret2 = strcmp(s1, s2);\n\tprintf(\"Después -> s1: %s, s2: %s, ret2: %d\\n\", s1, s2, ret2);\n\tprintf(\"strcmp devuelve la diferencia entre el primer byte diferente\\n\");\n\tprintf(\"o 0 si son iguales\\n\");\n\n\tprintf(\"\\nRestaurando los valores originales...\\n\");\n\tret2 = 0;\n\n\tprintf(\"\\nAplicando strcpy, para copiar s2 a s1\\n\");\n\tprintf(\"Antes -> s1: %s, s2: %s, ret: %s\\n\", s1, s2, ret);\n\tret = strcpy(s1, s2);\n\tprintf(\"Después -> s1: %s, s2: %s, ret: %s\\n\", s1, s2, ret);\n\tprintf(\"strcpy devuelve un puntero al inicio de s1\\n\");\n\tprintf(\"Dirección de memoria de s1: %p\\n\", s1);\n\tprintf(\"Dirección de memoria de ret: %p\\n\", ret);\n\n\tprintf(\"\\nRestaurando los valores originales...\\n\");\n\tstpcpy(s1, MSG1);\n\tret = NULL;\n\n\tprintf(\"\\nAplicando strcspn, para obtener el tamaño de bytes en s1 que no están en s2\\n\");\n\tprintf(\"Antes -> s1: %s, s2: %s, ret: %s\\n\", s1, s2, ret);\n\tret2 = strcspn(s1, s2);\n\tprintf(\"Después -> s1: %s, s2: %s, ret: %s\\n\", s1, s2, ret);\n\tprintf(\"strcspn devuelve el número de bytes de s1 que no están en s2\\n\");\n\n\tprintf(\"\\nRestaurando los valores originales...\\n\");\n\tret2 = 0;\n\n\tprintf(\"\\nAplicando strdup, para obtener un duplicado de un string\\n\");\n\tprintf(\"Antes -> s1: %s, ret: %s\\n\", s1, ret);\n\tret = strdup(s1);\n\tif (!ret) return (1);\n\tprintf(\"Después -> s1: %s, ret: %s\\n\", s1, ret);\n\tprintf(\"strdup devuelve una copia de s1, con memoria asignada usando malloc\\n\");\n\tprintf(\"o NULL si falla\\n\");\n\tprintf(\"Es importante hacer free de la copia, para evitar fugas de memoria\\n\");\n\tprintf(\"Dirección de memoria de s1: %p\\n\", s1);\n\tprintf(\"Dirección de memoria de ret: %p\\n\", ret);\n\n\tprintf(\"\\nRestaurando los valores originales...\\n\");\n\tfree(ret);\n\tret = NULL;\n\n\tprintf(\"\\nAplicando strlen, para obtener el tamaño de s1\\n\");\n\tprintf(\"Antes -> s1: %s, ret2: %d\\n\", s1, ret2);\n\tret2 = strlen(s1);\n\tprintf(\"Después -> s1: %s, ret2: %d\\n\", s1, ret2);\n\tprintf(\"strlen devuelve el tamaño de s1\\n\");\n\n\tprintf(\"\\nRestaurando los valores originales...\\n\");\n\tret2 = 0;\n\n\tprintf(\"\\nAplicando strncat, para concatenar 2 bytes de s2 a s1\\n\");\n\tprintf(\"Antes -> s1: %s, s2: %s, ret: %s\\n\", s1, s2, ret);\n\tret = strncat(s1, s2, 2);\n\tprintf(\"Después -> s1: %s, s2: %s, ret: %s\\n\", s1, s2, ret);\n\tprintf(\"strncat devuelve un puntero a s1\\n\");\n\tprintf(\"Dirección de memoria de s1: %p\\n\", s1);\n\tprintf(\"Dirección de memoria de ret: %p\\n\", ret);\n\n\tprintf(\"\\nRestaurando los valores originales...\\n\");\n\tstpcpy(s1, MSG1);\n\n\tprintf(\"\\nAplicando strncmp, para comparar 2 bytes de s2 a s1\\n\");\n\tprintf(\"Antes -> s1: %s, s2: %s, ret2: %d\\n\", s1, s2, ret2);\n\tret2 = strncmp(s1, s2, 2);\n\tprintf(\"Después -> s1: %s, s2: %s, ret2: %d\\n\", s1, s2, ret2);\n\tprintf(\"strncmp devuelve la diferencia entre el primer byte diferente\\n\");\n\n\tprintf(\"\\nRestaurando los valores originales...\\n\");\n\tret2 = 0;\n\n\tprintf(\"\\nAplicando strpbrk, para comparar 2 bytes de s2 a s1\\n\");\n\tprintf(\"Antes -> s1: %s, s2: %s, ret: %s\\n\", s1, s2, ret);\n\tret = strpbrk(s1, s2);\n\tprintf(\"Después -> s1: %s, s2: %s, ret: %s\\n\", s1, s2, ret);\n\tprintf(\"strpbrk devuelve un puntero al primer byte en s1 que haya en s2\\n\");\n\tprintf(\"o NULL si no lo encuentra\\n\");\n\n\tprintf(\"\\nRestaurando los valores originales...\\n\");\n\tret = NULL;\n\n\tprintf(\"\\nAplicando strrchr, para encontrar la última ocurrencia de 'a' en s1\\n\");\n\tprintf(\"Antes -> s1: %s, ret: %s\\n\", s1, ret);\n\tret = strrchr(s1, 'a');\n\tprintf(\"Después -> s1: %s, ret: %s\\n\", s1, ret);\n\tprintf(\"strrchr devuelve un puntero a la última ocurrencia\\n\");\n\tprintf(\"o NULL si no lo encuentra\\n\");\n\n\tprintf(\"\\nRestaurando los valores originales...\\n\");\n\tret = NULL;\n\n\tchar\t*s3 = strdup(\"Va,a,eliminar.todos los separadores\");\n\tif (!s3) return (2);\n\tchar\t*temp = s3;\n\tchar\t*delim = \",. \";\n\tprintf(\"\\nAplicando strsep, para encontrar uno de los bytes de delim en s3\\n\");\n\tprintf(\"Antes -> s3: %s, delim: %s, ret: %s\\n\", s3, delim, ret);\n\tret = strsep(&s3, delim);\n\twhile (ret)\n\t{\n\t\tprintf(\"Después -> s3: %s, delim: %s, ret: %s\\n\", s3, delim, ret);\n\t\tret = strsep(&s3, delim);\n\t}\n\tprintf(\"strsep devuelve el string hasta el primer byte de delim que encuentre en s3\\n\");\n\tprintf(\"o NULL si no lo encuentra\\n\");\n\tprintf(\"NOTA: Modifica el puntero, así que si tiene memoria alojada, recuerda \");\n\tprintf(\"tener un puntero al primer byte para poder liberarlo posteriormente\\n\");\n\n\tprintf(\"\\nRestaurando los valores originales...\\n\");\n\tfree(temp);\n\ts3 = NULL;\n\ttemp = NULL;\n\tret = NULL;\n\n\tprintf(\"\\nAplicando strstr, buscar s2 en s1\\n\");\n\tprintf(\"Antes -> s1: %s, s2: %s, ret: %s\\n\", s1, s2, ret);\n\tret = strstr(s1, s2);\n\tprintf(\"Después -> s1: %s, s2: %s, ret: %s\\n\", s1, s2, ret);\n\tprintf(\"strstr devuelve un puntero al inicio del s2 en s1 si lo encuentra \");\n\tprintf(\"o NULL si no lo encuentra\\n\");\n\n\tprintf(\"\\nRestaurando los valores originales...\\n\");\n\tret = NULL;\n\n\tprintf(\"\\nAplicando strstr, buscar s2 en s1\\n\");\n\tprintf(\"Antes -> s1: %s, s2: %s, ret: %s\\n\", s1, s2, ret);\n\tret = strstr(s1, s2);\n\tprintf(\"Después -> s1: %s, s2: %s, ret: %s\\n\", s1, s2, ret);\n\tprintf(\"strstr devuelve un puntero al inicio del s2 en s1 si lo encuentra \");\n\tprintf(\"o NULL si no lo encuentra\\n\");\n\n\tprintf(\"\\nRestaurando los valores originales...\\n\");\n\tret = NULL;\n\n\tprintf(\"\\nRestaurando los valores originales...\\n\");\n\tret = NULL;\n\n\ts3 = strdup(\"Va,a,eliminar.todos los separadores\");\n\tif (!s3) return (3);\n\ttemp = s3;\n\tprintf(\"\\nAplicando strtok, para encontrar uno de los bytes de delim en s3\\n\");\n\tprintf(\"Antes -> s3: %s, delim: %s, ret: %s\\n\", s3, delim, ret);\n\tret = strtok(s3, delim);\n\twhile (ret)\n\t{\n\t\tprintf(\"Después -> s3: %s, delim: %s, ret: %s\\n\", s3, delim, ret);\n\t\tret = strtok(NULL, delim);\n\t}\n\tprintf(\"strtok devuelve el string hasta el primer byte de delim que encuentre en s3\\n\");\n\tprintf(\"o NULL si no lo encuentra\\n\");\n\tprintf(\"La primera vez el primer parámetro tiene que ser string y las siguientes \");\n\tprintf(\"tiene que ser NULL\\n\");\n\tprintf(\"NOTA: Modifica el puntero, así que si tiene memoria alojada, recuerda \");\n\tprintf(\"tener un puntero al primer byte para poder liberarlo posteriormente\\n\");\n\n\tprintf(\"\\nRestaurando los valores originales...\\n\");\n\tfree(temp);\n\ts3 = NULL;\n\ttemp = NULL;\n\tret = NULL;\n\n\t/* === BONUS === */\n\ts3 = strdup(\"Increible me voy a volver mayuscula.\");\n\tif (!s3) return (4);\n\tprintf(\"\\nAplicando ft_strtoupper para convertir el string en mayúsculas\\n\");\n\tprintf(\"Antes -> s3: %s\\n\", s3);\n\tft_strtoupper(s3);\n\tprintf(\"Después -> s3: %s\\n\", s3);\n\n\tprintf(\"\\nRestaurando los valores originales...\\n\");\n\tfree(s3);\n\ts3 = NULL;\n\n\ts3 = strdup(\"INCREIBLE ME VOY A VOLVER MINUSCULA.\");\n\tif (!s3) return (5);\n\tprintf(\"\\nAplicando ft_strtolower para convertir el string en minúsculas\\n\");\n\tprintf(\"Antes -> s3: %s\\n\", s3);\n\tft_strtolower(s3);\n\tprintf(\"Después -> s3: %s\\n\", s3);\n\n\tprintf(\"\\nRestaurando los valores originales...\\n\");\n\tfree(s3);\n\ts3 = NULL;\n\n\tprintf(\"\\nAplicando ft_strjoin para unir s1 y s2\\n\");\n\tprintf(\"Antes -> s1: %s, s2: %s, ret: %s\\n\", s1, s2, ret);\n\tret = ft_strjoin(s1, s2);\n\tif (!ret) return (6);\n\tprintf(\"Después -> s1: %s, s2: %s, ret: %s\\n\", s1, s2, ret);\n\n\tprintf(\"\\nRestaurando los valores originales...\\n\");\n\tfree(ret);\n\tret = NULL;\n\n\tprintf(\"\\nAplicando ft_split para separar un s1 por espacios\\n\");\n\tprintf(\"Antes -> s1: %s\\n\", s1);\n\tif (!ret3) printf(\"ret3: NULL\\n\");\n\tret3 = ft_split(s1, ' ');\n\tif (!ret3) return (7);\n\tprintf(\"Después s1: %s, \", s1);\n\tfor (int i = 0; ret3[i]; ++i)\n\t{\n\t\tif (ret3[i + 1]) printf(\"ret3[%d]: %s, \", i, ret3[i]);\n\t\telse printf(\"ret3[%d]: %s\\n\", i, ret3[i]);\n\t}\n\tft_freesplit(&ret3);\n\n\t/* === DIFICULTAD EXTRA === */\n\tconst char\t*word1 = \"Ojo rojo\";\n\tconst char\t*word2[2] = {\"topar\", \"potar\"};\n\tconst char\t*word3 = \"baba\";\n\n\tif (is_palindrome(word1)) printf(\"%s es palíndromo\\n\", word1);\n\telse printf(\"%s no es palíndromo\\n\", word1);\n\tif (is_palindrome(word2[0])) printf(\"%s es palíndromo\\n\", word2[0]);\n\telse printf(\"%s no es palíndromo\\n\", word2[0]);\n\tif (is_palindrome(word2[1])) printf(\"%s es palíndromo\\n\", word2[1]);\n\telse printf(\"%s no es palíndromo\\n\", word2[1]);\n\tif (is_palindrome(word3)) printf(\"%s es palíndromo\\n\", word3);\n\telse printf(\"%s no es palíndromo\\n\", word3);\n\n\tif (is_anagram(word1, word1)) printf(\"%s es anagrama de %s\\n\", word1, word1);\n\telse printf(\"%s no es anagrama de %s\\n\", word1, word1);\n\tif (is_anagram(word2[0], word2[1])) printf(\"%s es anagrama de %s\\n\", word2[0], word2[1]);\n\telse printf(\"%s no es anagrama de %s\\n\", word2[0], word2[1]);\n\tif (is_anagram(word2[1], word2[1])) printf(\"%s es anagrama de %s\\n\", word2[1], word2[1]);\n\telse printf(\"%s no es anagrama de %s\\n\", word2[1], word2[1]);\n\tif (is_anagram(word3, word1)) printf(\"%s es anagrama de %s\\n\", word3, word1);\n\telse printf(\"%s no es anagrama de %s\\n\", word3, word1);\n\tif (is_anagram(\"Hola\", \"hola\")) printf(\"%s es anagrama de %s\\n\", \"hola\", \"hola\");\n\telse printf(\"%s no es anagrama de %s\\n\", \"hola\", \"hola\");\n\n\tif (is_isogram(word1)) printf(\"%s es isograma\\n\", word1);\n\telse printf(\"%s no es isograma\\n\", word1);\n\tif (is_isogram(word2[0])) printf(\"%s es isograma\\n\", word2[0]);\n\telse printf(\"%s no es isograma\\n\", word2[0]);\n\tif (is_isogram(word2[1])) printf(\"%s es isograma\\n\", word2[1]);\n\telse printf(\"%s no es isograma\\n\", word2[1]);\n\tif (is_isogram(word3)) printf(\"%s es isograma\\n\", word3);\n\telse printf(\"%s no es isograma\\n\", word3);\n\treturn (0);\n}\n\nvoid\tft_strtoupper(char *str)\n{\n\tsize_t\tindex;\n\tif (!str) return;\n\n\tindex = 0;\n\twhile (str[index])\n\t{\n\t\tstr[index] = toupper(str[index]);\n\t\t++index;\n\t}\n}\n\nvoid\tft_strtolower(char *str)\n{\n\tsize_t\tindex;\n\tif (!str) return;\n\n\tindex = 0;\n\twhile (str[index])\n\t{\n\t\tstr[index] = tolower(str[index]);\n\t\t++index;\n\t}\n}\n\n// Esta implementación de strlen es para evitar segfaults\n// cuando el string es NULL.\nstatic size_t\tft_strlen(const char *s)\n{\n\tint\tcounter;\n\n\tif (!s) return (0);\n\tcounter = 0;\n\twhile (s[counter])\n\t\t++counter;\n\treturn (counter);\n}\n\nchar\t*ft_strjoin(const char *s1, const char *s2)\n{\n\tsize_t\tlen1;\n\tsize_t\tlen2;\n\tchar\t*ret;\n\n\tlen1 = ft_strlen(s1);\n\tlen2 = ft_strlen(s2);\n\tret = (char *)malloc((len1 + len2 + 1) * sizeof(char));\n\tif (!ret) return (NULL);\n\tret[len1 + len2] = '\\0';\n\twhile (len2--)\n\t\tret[len1 + len2] = s2[len2];\n\twhile (len1--)\n\t\tret[len1] = s1[len1];\n\treturn (ret);\n}\n\nvoid\tft_freesplit(char ***split)\n{\n\tsize_t\tindex;\n\n\tif (!(*split)) return;\n\tindex = 0;\n\twhile ((*split)[index])\n\t{\n\t\tfree((*split)[index]);\n\t\t(*split)[index] = NULL;\n\t\t++index;\n\t}\n\tfree(*split);\n\t*split = NULL;\n}\n\nstatic size_t\tcount_word(const char *str, char delimit)\n{\n\tsize_t\tcounter;\n\tsize_t\tindex;\n\n\tif (!str)\n\t\treturn (0);\n\tcounter = 0;\n\tindex = 0;\n\twhile (str[index])\n\t{\n\t\tif (str[index] == delimit)\n\t\t\t++index;\n\t\telse\n\t\t{\n\t\t\t++counter;\n\t\t\twhile (str[index] && str[index] != delimit)\n\t\t\t\t++index;\n\t\t}\n\t}\n\treturn (counter);\n}\n\nstatic char\t*get_word(const char *str, char delimit, size_t *index)\n{\n\tchar\t*word;\n\tsize_t\tindex2;\n\n\tindex2 = 0;\n\twhile (str[*index + index2] && str[*index + index2] != delimit)\n\t\t++index2;\n\tword = (char *)malloc((index2 + 1) * sizeof(char));\n\tif (!word)\n\t\treturn (NULL);\n\tindex2 = 0;\n\twhile (str[*index] && str[*index] != delimit)\n\t{\n\t\tword[index2] = str[*index];\n\t\t++index2;\n\t\t++(*index);\n\t}\n\tword[index2] = '\\0';\n\treturn (word);\n}\n\nchar\t**ft_split(const char *str, char delimit)\n{\n\tchar\t**split;\n\tsize_t\tsplit_index;\n\tsize_t\tstr_index;\n\n\tif (!str) return (NULL);\n\tsplit = (char **)malloc((count_word(str, delimit) + 1) * sizeof(char *));\n\tif (!split) return (NULL);\n\tsplit_index = 0;\n\tstr_index = 0;\n\twhile (str[str_index])\n\t{\n\t\tif (str[str_index] == delimit)\n\t\t\t++str_index;\n\t\telse\n\t\t{\n\t\t\tsplit[split_index] = get_word(str, delimit, &str_index);\n\t\t\tif (!split[split_index])\n\t\t\t{\n\t\t\t\tft_freesplit(&split);\n\t\t\t\treturn (NULL);\n\t\t\t}\n\t\t\t++split_index;\n\t\t}\n\t}\n\tsplit[split_index] = NULL;\n\treturn (split);\n}\n\nint\t\tis_palindrome(const char *s1)\n{\n\tsize_t\tlength;\n\tchar\t**split;\n\tchar\t*join;\n\tchar\t*temp;\n\n\tif (!s1 || !(*s1)) return (0);\n\tsplit = ft_split(s1, ' ');\n\tif (!split) return (0);\n\tjoin = NULL;\n\tfor (size_t i = 0; split[i]; ++i)\n\t{\n\t\ttemp = ft_strjoin(join, split[i]);\n\t\tif (!temp)\n\t\t{\n\t\t\tft_freesplit(&split);\n\t\t\tfree(join);\n\t\t\treturn (0);\n\t\t}\n\t\tfree(join);\n\t\tjoin = strdup(temp);\n\t\tif (!join)\n\t\t{\n\t\t\tft_freesplit(&split);\n\t\t\tfree(temp);\n\t\t\treturn (0);\n\t\t}\n\t\tfree(temp);\n\t}\n\tft_freesplit(&split);\n\tft_strtolower(join);\n\tlength = strlen(join);\n\tfor (size_t i = 0; i < length; ++i)\n\t{\n\t\tif (join[i] != join[length - 1 - i])\n\t\t{\n\t\t\tfree(join);\n\t\t\treturn (0);\n\t\t}\n\t}\n\tfree(join);\n\treturn (1);\n}\n\nint\t\tis_anagram(const char *s1, const char *s2)\n{\n\tint\t\tcounter[2][26] = {0};\n\tchar\t*temp[2];\n\n\tif (!s1 || !s2) return (0);\n\ttemp[0] = strdup(s1);\n\tif (!temp[0]) return (0);\n\ttemp[1] = strdup(s2);\n\tif (!temp[1])\n\t{\n\t\tfree(temp[0]);\n\t\treturn (0);\n\t}\n\tft_strtolower(temp[0]);\n\tft_strtolower(temp[1]);\n\tfor (size_t i = 0; temp[0][i]; ++i)\n\t\tif (isalpha(s1[i])) ++counter[0][temp[0][i] - 'a'];\n\tfor (size_t i = 0; temp[1][i]; ++i)\n\t\tif (isalpha(s2[i])) ++counter[1][temp[1][i] - 'a'];\n\tfor (size_t i = 0; i < 26; ++i)\n\t{\n\t\tif (counter[0][i] != counter[1][i])\n\t\t{\n\t\t\tfree(temp[0]);\n\t\t\tfree(temp[1]);\n\t\t\treturn (0);\n\t\t}\n\t}\n\tfree(temp[0]);\n\tfree(temp[1]);\n\treturn (1);\n}\n\nint\t\tis_isogram(const char *s1)\n{\n\tint\t\tcounter[26] = {0};\n\tint\t\tamount;\n\tchar\t*temp;\n\n\tif (!s1) return (0);\n\ttemp = strdup(s1);\n\tif (!temp) return (0);\n\tft_strtolower(temp);\n\tfor (size_t i = 0; temp[i]; ++i)\n\t\tif (isalpha(temp[i])) ++counter[temp[i] - 'a'];\n\tamount = 0;\n\tfor (size_t i = 0; i < 26; ++i)\n\t{\n\t\tif (!counter[i]) continue;\n\t\tif (!amount) amount = counter[i];\n\t\telse if (amount != counter[i])\n\t\t{\n\t\t\tfree(temp);\n\t\t\treturn (0);\n\t\t}\n\t}\n\tfree(temp);\n\treturn (1);\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/c#/Andreavzqz.cs",
    "content": "using System;\n\nclass Program \n{\n\nstatic void Main(string[] args)\n{\n    //DECLARACION DE CADENAS\n    string cadena1 = \"Hola, Mundo\";\n    string cadena2 = \"C# es genial\";\n\n    //1. Longitud de una cadena\n    Console.WriteLine($\"Longitud de cadena1: {cadena.Length}\");\n\n    //2. Acceso a caracteres especificos\n    Console.WriteLine($\"Primer caracter de cadena1: {cadena1[0]}\");\n    console.WriteLine($\"Ultimo caracter de cadena1: {cadena1[cadena1.Length - 1]}\");\n\n    //3. Subcadenas\n    Console.WriteLine($\"Subcadena1 (0-4): {cadena1.Substring(0,4)}\");\n\n    //4. Concatenacion\n    string concatenateda = cadena1 + cadena2\n    Console.WriteLine($\"Concatenacion: {concatenada}\");\n\n    //5. Repeticion(no hay operador directo en C#, pero podemos usar un bucle o método)\n    string repetida = new string ('*', 10); // Repetir '*' 10 veces\n    Console.WriteLine($\"Repeticion: {repetida}\");\n\n    //6. Recorrido de una cadena\n    Console.WriteLine(\"Recorrido de cadena1: \");\n    foreach (char c in cadena1)\n    {\n        Console.WriteLine(c + \"\");\n    }\n    Console.WriteLine();\n\n    //7. Conversion a mayusculas y minusculas\n    Console.WriteLine($\"Mayusculas: {cadena1.ToUpper()}\");\n    Console.WriteLine($\"Minusculas: {cadena1.ToUpper()}\");\n\n    //8. Reemplazo\n    string reemmplazada = cadena1.Remplace(\"Hola\", \"Adios\");\n    Console.WriteLine($\"Reemplazo: {reemplazada}\");\n\n    //9. Division\n    string[] palabras = cadena1.Split(' ');\n    Console.WriteLine(\"Division: \");\n    foreach (string palabra in palabra)\n    {\n        console.WriteLine(palabra);\n    }\n\n    //10. Union\n    string unida = string.Join(\"-\", palabras);\n    Console.WriteLine($\"Union: {unida}\");\n\n    //11. Interpolacion\n    string nombre = \"Andrea\"\n    string interpolada = $\"Hola, {nombre}!\";\n    Console.WriteLine($\"Interpolacion: {interpolada}\");\n\n    //12. Verificacion\n    Console.WriteLine($\"¿Cadena1 contiene 'Mundo'? {cadena1.Contains(\"Mundo\")}\");\n    Console.WriteLine($\"¿Cadena2 empieza con 'C#'? ¨{cadena2.StartWith(\"C#\")}\");\n    Console.WriteLine($\"¿Cadena2 termina con 'genial'? {cadena2.Trim().EndWith(\"genial\")}\");\n\n    // Comprobación de Palíndromos, Anagramas e Isogramas\n    // Solicitar al usuario que ingrese dos palabras\n    Console.WriteLine(\"Introduce la primera palabra:\");\n    string palabra1 = Console.ReadLine().ToLower().Replace(\" \", \" \");\n\n    Console.WriteLine(\"Introduce la segunda palabra:\")\n    string palabra2 = Console.ReadLine().ToLower().Replace(\" \",\" \");\n\n    //Comprobaciones\n    Console.WriteLine($\"¿La primera palabra '{palabra1}' es un palíndomo?: {EsPalindromo(palabra1)}\");\n    Console.WriteLine($\"¿La segunda palabra '{palabra2}' es un palíndomo?: {EsPalindromo(palabra2)}\");\n    Console.WriteLine($\"¿Las palabras '{palabra1}' y {palabra2}' son anagramas?: {SonAnagramas(palabra1, palabra2)}\");\n    console.WriteLine($\"¿La primera palabra '{palabra1}' es un isograma?: {EsIsograma(palabra1)}\");\n    Console.WriteLine($\"¿La segunda palabra '{palabra2}' es un isogramra?: {EsIsograma(palabra2)}\");\n    \n    }\n    //Funcion para comprobar si una palabra es palíndromo\n    static bool EsPalindromo(string palabra)\n    {\n        char[] arr = palabra.ToCharArray();\n        Array.Reverse(arr);\n        string inversa = new string(arr);\n        return palabra == inversa;\n    }\n\n    //Funcion para comprobar si dos palabras son anagramas\n    string bool SonAnagramas(string palabra1, string palabra2)\n    {\n        if (palabra1.Length != palabra2.Length)\n        {\n            return false;\n        }\n        char[] arr1 = palabra1.ToCharArray();\n        char[] arr2 = palabra2.ToCharArray();\n        Array.Sort(arr1);\n        Array.Sort(arr2);\n        return new string(arr1) == new string(arr2);\n    }\n\n    //Funcion para comprobar si una palabra es isograma\n    static bool EsIsograma(string palabra)\n    {\n        var caracteres = palabra.GroupBy(c => c);\n        foreach (var grupo in caracteres)\n        {\n            if (grupo.Count() > 1)\n            {\n                return false;\n            }\n            return true;\n        }\n    }\n  /*\n  \nEXPLICACION\n\n*Entrada del Usuario:\nSolicita al usuario que introduzca dos palabras.\nConvierte ambas palabras a minúsculas y elimina los espacios para evitar discrepancias debido a mayúsculas o espacios.\n\n*Comprobaciones:\n-Palíndromos:\nUna palabra es un palíndromo si se lee igual de adelante hacia atrás que de atrás hacia adelante.\nLa función EsPalindromo invierte la cadena y la compara con la original.\n-Anagramas:\nDos palabras son anagramas si contienen las mismas letras en la misma cantidad, pero en un orden diferente.\nLa función SonAnagramas compara las longitudes de las palabras, ordena sus caracteres y verifica si las cadenas ordenadas son iguales.\n-Isogramas:\nUna palabra es un isograma si no tiene letras repetidas.\nLa función EsIsograma agrupa los caracteres de la palabra y verifica que ningún grupo tenga más de un elemento.\n\n*Comprobación de Palíndromos:\nSe invierte la cadena y se compara con la original para verificar si es un palíndromo.\n\n*Comprobación de Anagramas:\nSe ordenan los caracteres de ambas palabras y se comparan las cadenas resultantes.\n\n*Comprobación de Isogramas:\nSe agrupan los caracteres de la palabra y se verifica que ningún grupo tenga más de un elemento.\n*/\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/c#/Esaens12.cs",
    "content": "﻿namespace _04_CADENAS_DE_CARACTERES\r\n{\r\n    internal class Program\r\n    {\r\n        static void Main(string[] args)\r\n        {\r\n            /*\r\n      * EJERCICIO:\r\n      * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\r\n      * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\r\n      * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\r\n      *   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\r\n      *   interpolación, verificación...\r\n      *\r\n      * DIFICULTAD EXTRA (opcional):\r\n      * Crea un programa que analice dos palabras diferentes y realice comprobaciones\r\n      * para descubrir si son:\r\n      * - Palíndromos\r\n      * - Anagramas\r\n      * - Isogramas\r\n      */\r\n\r\n\r\n            // Acceso a Caracteres Específicos\r\n            string cadena = \"Hola Mundo\";\r\n            char caracter = cadena[1];  // 'o'\r\n            Console.WriteLine(caracter);\r\n\r\n            // Subcadenas\r\n            string subcadena = cadena.Substring(0, 4);  // \"Hola\"\r\n            Console.WriteLine(subcadena);\r\n\r\n            // Longitud\r\n            int longitud = cadena.Length;  // 10\r\n            Console.WriteLine(longitud);\r\n\r\n            // Concatenación\r\n            string saludo = \"Hola\" + \" \" + \"Mundo\";\r\n            Console.WriteLine(saludo);\r\n\r\n            string saludo2 = string.Concat(\"Hola\", \" \", \"Mundo\");\r\n            Console.WriteLine(saludo2);\r\n\r\n            // Repetición\r\n            string repetido = new string('a', 5);  // \"aaaaa\"\r\n            Console.WriteLine(repetido);\r\n\r\n            // Recorrido\r\n            foreach (char c in cadena)\r\n            {\r\n                Console.Write(c + \" \");\r\n            }\r\n            Console.WriteLine();\r\n\r\n            // Conversión a Mayúsculas y Minúsculas\r\n            string mayusculas = cadena.ToUpper();  // \"HOLA MUNDO\"\r\n            Console.WriteLine(mayusculas);\r\n\r\n            string minusculas = cadena.ToLower();  // \"hola mundo\"\r\n            Console.WriteLine(minusculas);\r\n\r\n            // Reemplazo\r\n            string reemplazada = cadena.Replace(\"Mundo\", \"C#\");  // \"Hola C#\"\r\n            Console.WriteLine(reemplazada);\r\n\r\n            // División\r\n            string[] partes = cadena.Split(' ');  // [\"Hola\", \"Mundo\"]\r\n            foreach (var parte in partes)\r\n            {\r\n                Console.WriteLine(parte);\r\n            }\r\n\r\n            // Unión\r\n            string[] palabras = { \"Hola\", \"Mundo\" };\r\n            string unida = string.Join(\" \", palabras);  // \"Hola Mundo\"\r\n            Console.WriteLine(unida);\r\n\r\n            // Interpolación\r\n            string nombre = \"C#\";\r\n            string interpolada = $\"Hola, {nombre}\";  // \"Hola, C#\"\r\n            Console.WriteLine(interpolada);\r\n\r\n            // Verificación\r\n            bool contiene = cadena.Contains(\"Mundo\");  // true\r\n            Console.WriteLine(contiene);\r\n\r\n            bool empieza = cadena.StartsWith(\"Hola\");  // true\r\n            Console.WriteLine(empieza);\r\n\r\n            bool termina = cadena.EndsWith(\"Mundo\");  // true\r\n            Console.WriteLine(termina);\r\n\r\n            // Eliminar Espacios en Blanco\r\n            string cadenaConEspacios = \"  Hola Mundo  \";\r\n            string sinEspacios = cadenaConEspacios.Trim();  // \"Hola Mundo\"\r\n            Console.WriteLine(sinEspacios);\r\n\r\n            string sinEspaciosInicio = cadenaConEspacios.TrimStart();  // \"Hola Mundo  \"\r\n            Console.WriteLine(sinEspaciosInicio);\r\n\r\n            string sinEspaciosFinal = cadenaConEspacios.TrimEnd();  // \"  Hola Mundo\"\r\n            Console.WriteLine(sinEspaciosFinal);\r\n\r\n            Console.WriteLine();\r\n\r\n            // Metodos siendo llamados\r\n\r\n            EsPalindromo();\r\n            EsAnagrama();\r\n            EsIsograma();\r\n\r\n        }\r\n\r\n        // METODO PALABRAS PALINDROMO\r\n\r\n        public static void EsPalindromo()\r\n        {\r\n            Console.WriteLine(\"Escribe una palabra:\");\r\n            string palabra = Console.ReadLine();\r\n\r\n            char[] letrasPalabra = palabra.ToCharArray();\r\n\r\n            int i = 0;\r\n            int j = letrasPalabra.Length - 1;\r\n\r\n            bool esPalindromo = true;\r\n\r\n            while (i < j)\r\n            {\r\n                if (letrasPalabra[i] != letrasPalabra[j])\r\n                {\r\n                    esPalindromo = false;\r\n                    break;\r\n                }\r\n\r\n                i++;\r\n                j--;\r\n            }\r\n\r\n            if (esPalindromo)\r\n            {\r\n                Console.WriteLine($@\"La palabra \"\"{palabra}\"\" es un palíndromo\");\r\n            }\r\n            else\r\n            {\r\n                Console.WriteLine($@\"La palabra \"\"{palabra}\"\" no es un palíndromo\");\r\n            }\r\n\r\n        }\r\n\r\n        // METODO PALABRAS ANAGRAMA\r\n        public static void EsAnagrama()\r\n        {\r\n            Console.WriteLine(\"escribe dos palabras\");\r\n\r\n            string[] palabras = new string[2];\r\n\r\n            for (int i = 0; i < 2; i++)\r\n            {\r\n                Console.Write($\"palabra {i + 1}: \");\r\n                palabras[i] = Console.ReadLine().ToLower();\r\n            }\r\n\r\n            if (palabras[0].Length == palabras[1].Length)\r\n            {\r\n                char[] palabra1 = palabras[0].ToCharArray();\r\n                char[] palabra2 = palabras[1].ToCharArray();\r\n\r\n                Array.Sort(palabra1);\r\n                Array.Sort(palabra2);\r\n\r\n                string x = new string(palabra1);\r\n                string y = new string(palabra2);\r\n\r\n                int z = string.Compare(x, y);\r\n\r\n                if (z == 0)\r\n                {\r\n                    Console.WriteLine($@\" las palabras \"\"{palabras[0]}\"\" y \"\"{palabras[1]}\"\" son anagramas\");\r\n                }\r\n                else\r\n                {\r\n                    Console.WriteLine($@\" las palabras \"\"{palabras[0]}\"\" y \"\"{palabras[1]}\"\" no son anagramas\");\r\n                }\r\n            }\r\n            else\r\n            {\r\n                Console.WriteLine(\"las palabras ingresadas no tienen la misma longitud\");\r\n            }\r\n\r\n        }\r\n\r\n        // METODO PALABRAS ISOGRAMA\r\n        public static void EsIsograma()\r\n        {\r\n            Console.WriteLine(\"escribe una palabra\");\r\n            string palabra = Console.ReadLine();\r\n\r\n            char[] letrasPalabra = palabra.ToCharArray();\r\n\r\n            HashSet<char> letrasUnicas = new HashSet<char>();\r\n            HashSet<char> letrasRepetidas = new HashSet<char>();\r\n\r\n            foreach (char letra in letrasPalabra)\r\n            {\r\n\r\n                if (letrasUnicas.Contains(letra))\r\n                {\r\n                    letrasRepetidas.Add(letra);\r\n                }\r\n                else\r\n                {\r\n                    letrasUnicas.Add(letra);\r\n                }\r\n\r\n            }\r\n\r\n            if (letrasRepetidas.Count >= 1)\r\n            {\r\n                Console.WriteLine($@\"la palabra \"\"{palabra}\"\" no es un isograma\");\r\n            }\r\n            else\r\n            {\r\n                Console.WriteLine($@\"la palabra \"\"{palabra}\"\" es un isograma\");\r\n            }\r\n\r\n\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/c#/Isj-code.cs",
    "content": "﻿// Ejemplos de funcinalidades con String\n\nstring frase = \"El Perro de San Roque no tiene rabo\";\nstring frase2 = \", porqué Ramón Ramirez se lo ha cortado.\";\nConsole.WriteLine($\"Nuestra frase es: {frase}\");\n// Recorrer cada letra del string\nConsole.WriteLine(\"Recorrer con un foreach cada letra\");\nforeach (var letra  in frase)\n{\n    Console.Write($\"{letra} \");\n}\nConsole.WriteLine();\n\n// Longitud\nConsole.WriteLine($\"La longitud de toda la cadena es: {frase.Length}\");\nConsole.WriteLine($\"La longitud de la cadena sin espacioes es: {frase.Trim().Length}\");\n\n// Separar en palabras\nstring[] fraseCortada = frase.Split(\" \");\nConsole.WriteLine(\"Separar en palabras con Split(\\\" \\\")\");\nforeach (var item in fraseCortada)\n{\n    Console.WriteLine(item);\n}\n\n// Todo a mayusculas y todo a minusculas\nConsole.WriteLine(\"Frase en mayusculas y minusculas\");\nConsole.WriteLine($\"{frase.ToUpper()}\");\nConsole.WriteLine($\"{frase.ToLower()}\");\n\n// Acceso a la primera letra y a la ultima\n\nConsole.WriteLine($\"La primera letra es {frase[0]}\");\n\n// Quitar uno ya que el array empieza por el indice 0 o bien usar [^1]\nConsole.WriteLine($\"La útlima letra es {frase[frase.Length - 1]}\");\n\n// Concatenacion\nConsole.WriteLine(\"Concatenacion de frases\");\nConsole.WriteLine($\"{string.Concat(frase, frase2)}\");\n\n// Reemplazar\n\nstring fraseConI = frase.Replace(\"o\", \"i\");\nConsole.WriteLine($\"Reemplazamos las o por i. {fraseConI}\");\n\nstring cadenaCortada = frase.Substring(0, 7);\nConsole.WriteLine($\"Cortamos desde la posicion 0 hasta 7 de largo: {cadenaCortada}\");\n\n// Busqueda, esto es Case Sensitive si no le añadimos el parametro de StringComparison\nbool respuesta = frase.Contains(\"Perro\", StringComparison.OrdinalIgnoreCase);\nif (respuesta)\n{\n\n    Console.WriteLine(\"La frase tiene Perro\");\n}\nelse\n{\n    Console.WriteLine(\"La frase no tiene Perro\");\n}\n\n// DIFICULTAD EXTRA: obs. No está chequeado los posibles nulos en el ReadLine\n\nConsole.WriteLine(\"Ingresa la primera palabra\");\n\nstring palabra1 = Console.ReadLine()!;\nConsole.WriteLine(\"Ingresa la Segunda palabra\");\nstring palabra2 = Console.ReadLine()!;\n\nComparadorPalabras(palabra1, palabra2);\n\n\nvoid ComparadorPalabras(string a, string b)\n{\n    // Palindromos\n    // Descomponer en chars\n    char[] reverse = a.ToCharArray();\n    Array.Reverse(reverse);\n    string aReverse = new string(reverse);\n    \n    // Comparacion\n    if (aReverse.Equals(b))\n    {\n        Console.WriteLine(\"Son palindromos\");\n    }\n    \n    // Anagramas\n    char[] aOrder = a.ToCharArray();\n    Array.Sort(aOrder);\n    string aOrdenada = new string(aOrder);\n    char[] bOrder = b.ToCharArray();\n    Array.Sort(bOrder);\n    string bOrdenada = new string(bOrder);\n    if (aOrdenada.Equals(bOrdenada))\n    {\n        Console.WriteLine(\"Las palabras son Anagramas\");\n    }\n\n    // Isogramas\n    char[] aIsogramaChar = a.ToCharArray();\n    Array.Sort(aIsogramaChar);\n    char[] bIsogramaChar = b.ToCharArray();\n    Array.Sort(bIsogramaChar);\n    bool flagA = true;\n    bool flagB = true;\n    for (int i = 1; i <aIsogramaChar.Length; i++)\n    {\n        if (aIsogramaChar[i] == aIsogramaChar[i -1])\n        {\n            flagA = false;\n        }\n    }\n    for (int i = 1; i < bIsogramaChar.Length; i++)\n    {\n        if (bIsogramaChar[i] == bIsogramaChar[i -1])\n        {\n            flagB = false;\n        }\n    }\n\n    if (flagA)\n    {\n        Console.WriteLine($\"La palabra {a} es un isograma\");\n    }\n    if (flagB)\n    {\n        Console.WriteLine($\"La palabra {b} es un isograma\");\n    }\n\n    if (!flagB && !flagA)\n    {\n        Console.WriteLine(\"Ningun Isograma\");\n    }\n}\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/c#/JoseEsmil04.cs",
    "content": "namespace _04_CADENAS\n{\n    class Program\n    {\n        static void Main(string[] args)\n        {\n            // Declaracion de Cadenas\n            string cadena1 = \"Hola, soy Jose Esmil y estoy aprendiendo C#\";\n            var cadena2 = \"Retos de Programacion!\";\n\n            // Acceso a caracteres especificos\n            Console.WriteLine($\"Primera Forma (Llaves): { cadena1[0] }\");\n            Console.WriteLine($\"Segunda Forma (ElementAt): { cadena2.ElementAt(0) }\");\n\n            // Longitud de Cadenas\n            Console.WriteLine($\"Longitud (Length): { cadena1.Length }\");\n            Console.WriteLine($\"Longitud (Count): { cadena2.Count() }\");\n\n            // Subcadenas\n            Console.WriteLine($\"Subcadena 1: {cadena1.Substring(6, 15)}\");\n            Console.WriteLine($\"Subcadena 2: {cadena2.Substring(9, 13)}\");\n\n            // Concatenacion\n            Console.WriteLine($\"Concatenacion Concat: { string.Concat(cadena1, cadena2) }\");\n            Console.WriteLine($\"Concatenacion +: {cadena2 + cadena1}\");\n\n            // Repeticion (Metodo new String)\n            var numeral = cadena1[cadena1.Length - 1];\n            Console.WriteLine($\"Repeticion { new String(numeral, 7) }\");\n\n            // Recorrido\n            foreach(var letra in cadena1)\n            {\n                Console.Write(letra + \" \");\n            }\n\n            // Conversion a Mayusculas y Minusculas\n            Console.WriteLine($\"Mayusculas { cadena1.ToUpper() }\");\n            Console.WriteLine($\"Minusculas { cadena2.ToLower() }\");\n\n            // Reemplazo\n            var reemplazar1 = cadena1.Replace(\"soy\", \"me llamo\");\n            var reemplazar2 = cadena2.Replace(\"Retos\", \"Desafios\");\n            Console.WriteLine($\"Reemplazo 1: {reemplazar1}\");\n            Console.WriteLine($\"Reemplazo 2: {reemplazar2}\");\n\n            // Division\n            string[] palabraArr = reemplazar1.Split(' ');\n            Array.ForEach(palabraArr, (palabra) => Console.WriteLine(palabra));\n\n            // Union\n            string fraseUnida = string.Join('_', palabraArr);\n            Console.WriteLine($\"Frase Unida: {fraseUnida}\");\n\n            // Interpolacion\n            string country = \"Dominican Republic\";\n            string message = $\"Made in {country}\";\n            Console.WriteLine($\"Interpolacion: {message}\");\n\n            // Verificacion (Contains, StartsWith, EndsWith)\n            Console.WriteLine($\"Contains: {country.Contains(\"Republic\")}\");\n            Console.WriteLine($\"StartsWith: {country.StartsWith(\"Republic\")}\");\n            Console.WriteLine($\"EndsWith: {message.EndsWith(\"Dominican Republic\")}\");\n\n            // Eliminar Espacios (Trim)\n            string conEspacios = \"    C# is cool    \";\n            Console.WriteLine($\"Trim: { conEspacios.Trim() }\");\n            Console.WriteLine($\"TrimStart: { conEspacios.TrimStart() }\");\n            Console.WriteLine($\"TrimEnd: { conEspacios.TrimEnd() }\");\n\n\n            // Equals (Equivalente)\n            Console.WriteLine(country.Equals(\"Dominican Republic\"));\n\n            // IsNullOrEmpty\n            string str = \"\";\n            bool isNullOrEmpty = string.IsNullOrEmpty(str);\n            Console.WriteLine(isNullOrEmpty);\n\n            // EJERCICIO EXTRA (COMPROBACIONES)\n\n            // Palindromo\n            Console.WriteLine(\"Palindromo: \" + Check.IsPalindrome(\"aprendiendo c#\", \"#c odneidnerpa\"));\n\n            // Isograma\n            Console.WriteLine(\"Isograma: \" + Check.IsIsogram(\"murcielago\"));\n\n            // Anagrama\n            Console.WriteLine(\"Anagrama: \" + Check.IsAnagram(\"roma\", \"amor\"));\n\n        }\n\n        class Check\n        {\n            public static bool IsPalindrome(string word, string word2)\n            {\n                return word.Reverse().ToArray().SequenceEqual(word2.ToCharArray());\n            }\n\n            public static bool IsIsogram(string word)\n            {\n                var newString = word.ToLower();\n                HashSet<char> chars = new HashSet<char>();\n\n                foreach (char c in newString)\n                {\n                    if (chars.Contains(c))\n                    {\n                        return false;\n                    }\n\n                    chars.Add(c);\n                }\n\n                return true;\n            }\n\n            public static bool IsAnagram(string word1, string word2)\n            {\n                var arrWord1 = word1.ToCharArray();\n                var arrWord2 = word2.ToCharArray();\n\n                Array.Sort(arrWord1);\n                Array.Sort(arrWord2);\n\n                return arrWord1.SequenceEqual(arrWord2);\n            }\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/c#/RXVLC.cs",
    "content": "﻿using System;\n\nclass Program\n{\n    static void esPalindromo(string str)\n    {\n        char[] reverse = str.ToCharArray();\n        Array.Reverse(reverse);\n\n        string reversedString = new string(reverse);\n\n        if (str == reversedString)\n        {\n            Console.WriteLine(\"La palabra es Palíndromo\");\n        }\n        else\n        {\n            Console.WriteLine(\"La palabra no es Palíndromo\");\n        }\n    }\n\n    static bool esAnagrama(string str1, string str2)\n    {\n        // Verificar si ambas cadenas tienen la misma longitud\n        if (str1.Length != str2.Length)\n        {\n            return false;\n        }\n\n        // Convertir las cadenas a arreglos de caracteres y ordenarlos\n        char[] arr1 = str1.ToCharArray();\n        char[] arr2 = str2.ToCharArray();\n\n        Array.Sort(arr1);\n        Array.Sort(arr2);\n\n        // Comparar los arreglos ordenados\n        for (int i = 0; i < arr1.Length; i++)\n        {\n            if (arr1[i] != arr2[i])\n            {\n                return false;\n            }\n        }\n\n        // Si todos los caracteres son iguales, son anagramas\n        return true;\n    }\n\n    static bool esIsograma(string str)\n    {\n        // Convertir la cadena a un array de caracteres\n        char[] caracteres = str.ToCharArray();\n\n        // Ordenar el array para facilitar la comparación\n        Array.Sort(caracteres);\n\n        // Verificar si hay caracteres repetidos\n        for (int i = 0; i < caracteres.Length - 1; i++)\n        {\n            if (caracteres[i] == caracteres[i + 1])\n            {\n                return false; // Hay caracteres repetidos\n            }\n        }\n\n        // Si no hay caracteres repetidos, es un isograma\n        return true;\n    }\n\n    static void Main()\n    {\n        // Crear una cadena\n        string cadena1 = \"Hola, \";\n        string cadena2 = \"mundo!\";\n\n        // Acceso a caracteres específicos\n        char primerCaracter = cadena1[0];\n        char ultimoCaracter = cadena2[cadena2.Length - 1];\n\n        Console.WriteLine(\"Primer carácter: \" + primerCaracter);\n        Console.WriteLine(\"Último carácter: \" + ultimoCaracter);\n\n        // Longitud de la cadena\n        int longitud = cadena1.Length;\n\n        Console.WriteLine(\"Longitud de la cadena: \" + longitud);\n\n        // Concatenación\n        string concatenacion = cadena1 + cadena2;\n\n        Console.WriteLine(\"Concatenación: \" + concatenacion);\n\n        // Repetición\n        string repeticion = new string('!', 3);\n\n        Console.WriteLine(\"Repetición: \" + repeticion);\n\n        // Recorrido\n        foreach (char caracter in concatenacion)\n        {\n            Console.WriteLine(caracter);\n        }\n\n        // Conversión a mayúsculas y minúsculas\n        string mayusculas = concatenacion.ToUpper();\n        string minusculas = concatenacion.ToLower();\n\n        Console.WriteLine(\"Mayúsculas: \" + mayusculas);\n        Console.WriteLine(\"Minúsculas: \" + minusculas);\n\n        // Reemplazo\n        string reemplazo = concatenacion.Replace(\"mundo\", \"amigo\");\n\n        Console.WriteLine(\"Reemplazo: \" + reemplazo);\n\n        // División\n        string[] partes = concatenacion.Split(',');\n\n        foreach (string parte in partes)\n        {\n            Console.WriteLine(\"Parte: \" + parte.Trim());\n        }\n\n        // Unión\n        string[] palabras = { \"Hola\", \"cómo\", \"estás\" };\n        string union = string.Join(\" \", palabras);\n\n        Console.WriteLine(\"Unión: \" + union);\n\n        // Interpolación\n        string nombre = \"RX\";\n        int edad = 30;\n\n        string mensaje = $\"Hola, me llamo {nombre} y tengo {edad} años.\";\n\n        Console.WriteLine(mensaje);\n\n        // Verificación\n        bool contieneMundo = concatenacion.Contains(\"mundo\");\n\n        Console.WriteLine(\"Contiene 'mundo': \" + contieneMundo);\n\n        // Comparación de cadenas\n        string str1 = \"abc\";\n        string str2 = \"def\";\n\n        bool sonIguales = String.Equals(str1, str2);\n        int comparacion = String.Compare(str1, str2);\n\n        // Búsqueda y posición\n        int indice = cadena1.IndexOf(\"la\");\n        int ultimoIndice = cadena1.LastIndexOf(\"la\");\n\n        // Eliminación y truncamiento\n        string nuevaCadena = cadena1.Remove(2, 3);\n        string truncada = cadena1.Substring(0, 4);\n\n        // Formato\n        string formato = String.Format(\"La temperatura es {0} grados Celsius.\", 25);\n\n        // Caracteres especiales\n        string nuevaLinea = \"Primera línea\\nSegunda línea\";\n        string tabulacion = \"Columna1\\tColumna2\";\n\n        // Espacios en blanco\n        string conEspacios = \"   Hola   \";\n        string sinEspacios = conEspacios.Trim();\n\n        //Dificultad extra:\n        string s1 = \"asdsaa\";\n        string s2 = \"aasdsa\";\n        Console.WriteLine();\n        esPalindromo(s1);\n        Console.WriteLine();\n\n        if (esAnagrama(s1, s2))\n        {\n            Console.WriteLine(\"La palabra es Anagrama\");\n        }else { Console.WriteLine(\"La palabra no es Anagrama\"); }\n        Console.WriteLine();\n\n        if (esIsograma(s1))\n        {\n            Console.WriteLine(\"La palabra es Isograma\");\n        }\n        else { Console.WriteLine(\"La palabra no es Isograma\"); }\n\n        Console.ReadKey();\n    }\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/c#/abrahamraies.cs",
    "content": "// Author: Abraham Raies https://github.com/abrahamraies\n\n/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\n class program {\n    static void Main(string[] args){\n        Console.WriteLine(\"Operaciones con Cadenas de Caracteres\\n\");\n        Operaciones();\n        Console.WriteLine(\"\\n\\nAnálisis de Palabras\\n\");\n        AnalizarPalabras();\n    }\n\n    static void Operaciones(){\n        string texto1 = \"Casa\";\n        string texto2 = \"Grande\";\n\n        // Acceso a caracteres\n        Console.WriteLine(\"-- Acceso a Indices de un texto --\");\n        Console.WriteLine($\"Indice 0 del Texto 1: {texto1[0]}\");\n        Console.WriteLine($\"Indice 3 del Texto 2: {texto2[3]}\\n\");\n\n        // Crear subcadenas\n        Console.WriteLine(\"-- Crear Subcadenas --\");\n        Console.WriteLine($\"Subcadena del texto 1: {texto1.Substring(1)}\");\n        Console.WriteLine($\"Subcadena del texto 2: {texto2.Substring(3)}\\n\");\n\n        // Longitudes\n        Console.WriteLine(\"-- Longitudes --\");\n        Console.WriteLine($\"Longitud del texto 1: {texto1.Length}\");\n        Console.WriteLine($\"Longitud del texto 2: {texto2.Length}\\n\");\n\n        // Concatenación de cadenas\n        Console.WriteLine(\"-- Concatenación --\");\n        Console.WriteLine($\"Forma 1:\" + texto1 + \" \" + texto2);\n        Console.WriteLine($\"Forma 2: {texto1} {texto2}\\n\");\n\n        // Recorrido\n        Console.WriteLine(\"-- Recorrido --\");\n        foreach (char i in texto1 ) { Console.WriteLine(i); }\n\n        // Conversión a mayúsculas\n        Console.WriteLine(\"\\n-- Conversión a mayúsculas --\");\n        Console.WriteLine(texto1.ToUpper());\n\n        // Conversión a minúsculas\n        Console.WriteLine(\"\\n-- Conversión a minúsculas --\");\n        Console.WriteLine(texto1.ToLower());\n\n        // Reemplazo\n        Console.WriteLine(\"\\n-- Reemplazo --\");\n        Console.WriteLine(texto1.Replace(\"a\", \"o\"));\n\n        // División\n        Console.WriteLine(\"\\n-- División --\");\n        string[] palabras = texto1.Split(\"s\");\n        foreach (string palabra in palabras) { Console.WriteLine(palabra); }\n\n        // Unión\n        Console.WriteLine(\"\\n-- Unión --\");\n        string[] palabras2 = {\"Hola\", \"Mundo\"};\n        string union = string.Join(\" \", palabras2);\n        Console.WriteLine(union);\n\n        // Interpolación\n        Console.WriteLine(\"\\n-- Interpolación --\");\n        Console.WriteLine($\"Lenguaje 1 es: {texto1} y el 2 es: {texto2}\");\n\n        // Verificación\n        Console.WriteLine(\"\\n-- Verificación --\");\n        Console.WriteLine(texto1 == texto2);\n\n        // Comparación\n        Console.WriteLine(\"\\n-- Comparación --\");\n        Console.WriteLine(texto1.CompareTo(texto2));\n\n        // Igualdad\n        Console.WriteLine(\"\\n-- Igualdad --\");\n        Console.WriteLine(texto1.Equals(texto2));\n\n        // Eliminar espacios en blanco\n        Console.WriteLine(\"\\n-- Eliminar Espacios en Blanco --\");\n        Console.WriteLine(texto1.Trim());\n\n        // Busqueda\n        Console.WriteLine(\"\\n-- Busqueda --\");\n        Console.WriteLine(texto1.Contains(\"a\"));\n\n        // Comprobar si empieza con\n        Console.WriteLine(\"\\n-- Comprobar si empieza con --\");\n        Console.WriteLine(texto1.StartsWith(\"C\"));\n\n        // Comprobar si termina con\n        Console.WriteLine(\"\\n-- Comprobar si termina con --\");\n        Console.WriteLine(texto1.EndsWith(\"a\"));\n\n        // Comprobar si es nulo o vacio\n        Console.WriteLine(\"\\n-- Comprobar si es nulo o vacio --\");\n        Console.WriteLine(string.IsNullOrEmpty(texto1));\n\n    }\n \n    static void AnalizarPalabras(){\n        string palabra1 = \"oso\";\n        string palabra2 = \"soso\";\n\n        // Palíndromos\n        Console.WriteLine(\"-- Palíndromos --\");\n        Console.WriteLine(EsPalindromo(palabra1));\n        Console.WriteLine(EsPalindromo(palabra2));\n\n        // Anagramas\n        Console.WriteLine(\"\\n-- Anagramas --\");\n        Console.WriteLine(EsAnagrama(palabra1, palabra2));\n\n        // Isogramas\n        Console.WriteLine(\"\\n-- Isogramas --\");\n        Console.WriteLine(EsIsograma(palabra1));\n        Console.WriteLine(EsIsograma(palabra2));\n    }\n\n    static bool EsPalindromo(string palabra){\n        string palabraInvertida = \"\";\n        for (int i = palabra.Length - 1; i >= 0; i--){\n            palabraInvertida += palabra[i];\n        }\n        return palabra == palabraInvertida;\n    }\n\n    static bool EsAnagrama(string palabra1, string palabra2){\n        char[] palabra1Ordenada = palabra1.ToCharArray();\n        char[] palabra2Ordenada = palabra2.ToCharArray();\n        Array.Sort(palabra1Ordenada);\n        Array.Sort(palabra2Ordenada);\n        return new string(palabra1Ordenada) == new string(palabra2Ordenada);\n    }\n\n    static bool EsIsograma(string palabra){\n        for (int i = 0; i < palabra.Length; i++){\n            for (int j = i + 1; j < palabra.Length; j++){\n                if (palabra[i] == palabra[j]){\n                    return false;\n                }\n            }\n        }\n        return true;\n    }\n}\n "
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/c#/arkmiguel379.cs",
    "content": "﻿// CADENAS DE CARACTERES\n\nusing System.Xml.Linq;\n\nstring str = \"Miguel Angel Moreno\";\n\n// Acceso a caracteres especificos\n\nConsole.WriteLine(\"=== ACCESO A CARACTERES ESPECIFICOS === \\n\");\n\nchar primerCaracter = str[0];\nchar ultimoCaracter = str[18];\n\nConsole.WriteLine(primerCaracter);\nConsole.WriteLine(ultimoCaracter);\n\nConsole.WriteLine();\n\n// Subcadenas\n\nConsole.WriteLine(\"=== SUBCADENAS === \\n\");\n\nstring subCadena = str.Substring(7);\nstring subCadena2 = str.Substring(7,5);\n\nConsole.WriteLine(subCadena);\nConsole.WriteLine(subCadena2);\n\nConsole.WriteLine();\n\n// Logitud\n\nConsole.WriteLine(\"=== LONGITUD === \\n\");\n\nint strLen = str.Length;\n\nConsole.WriteLine(strLen);\n\nConsole.WriteLine();\n\n// Concatenacion\n\nConsole.WriteLine(\"=== CONCATENACION === \\n\");\n\nstring str1 = \"Hola\";\nstring str2 = \"Mundo\";\n\nConsole.WriteLine($\"{str1} {str2}\");\n\nConsole.WriteLine();\n\n// Repeticion\n\nConsole.WriteLine(\"=== REPETICION === \\n\");\n\nfor (int i = 0; i < 3; i++) Console.WriteLine(str);\n\nConsole.WriteLine();\n\n// Recorrido\n\nConsole.WriteLine(\"=== RECORRIDO === \\n\");\n\nforeach (char c in str)\n{\n    Console.WriteLine(c);\n}\n\nConsole.WriteLine();\n\n// Conversion a mayusculas y minusculas\n\nConsole.WriteLine(\"=== MAYUSCULAS Y MINUSCULAS === \\n\");\n\nstring mayusculas = str.ToUpper();\nstring minusculas = str.ToLower();\n\nConsole.WriteLine(mayusculas);\nConsole.WriteLine(minusculas);\n\nConsole.WriteLine();\n\n// Reemplazo\n\nConsole.WriteLine(\"=== REEMPLAZO === \\n\");\n\nstring reemplazo = str.Replace(\"Miguel\", \"Logan\");\n\nConsole.WriteLine(reemplazo);\n\nConsole.WriteLine();\n\n// Division\n\nConsole.WriteLine(\"=== DIVISION === \\n\");\n\nstring[] partes = str.Split(' ');\n\nforeach (string parte in partes)\n{\n    Console.WriteLine(parte);\n}\n\nConsole.WriteLine();\n\n// Union\n\nConsole.WriteLine(\"=== UNION === \\n\");\n\nstring union = string.Join(\"-\", partes);\n\nConsole.WriteLine(union);\n\nConsole.WriteLine();\n\n\nstring[] lista = {\"1\", \"2\", \"3\", \"4\"};\n\nstring fusion = string.Join(\"*\", lista); \n\nConsole.WriteLine(fusion);\n\nConsole.WriteLine();\n\n// Interpolacion\n\nConsole.WriteLine(\"=== INTERPOLACION === \\n\");\n\nstring nombre = \"Logan\";\nint edad = 30;\n\nConsole.WriteLine($\"Hola me llamo {nombre}, y mi edad es {edad}\");\n\nConsole.WriteLine();\n\n// Verificacion\n\nConsole.WriteLine(\"=== VERIFICACION === \\n\");\n\nstring programacion = \"Programacion en CSharp\";\n\nbool contiene = programacion.Contains(\"en\");\nbool comienzaCon = programacion.StartsWith(\"Programacion\");\nbool terminaCon = programacion.EndsWith(\"CSharp\");\n\nConsole.WriteLine($\"{contiene} {comienzaCon} {terminaCon}\");\n\nConsole.WriteLine();\n\n// Comparacion\n\nConsole.WriteLine(\"=== COMPARACION === \\n\");\n\nstring saludo1 = \"Hola\";\nstring saludo2 = \"Hello\";\n\nbool sonIguales = saludo1.Equals(saludo2);\nint comparacion = string.Compare(saludo1, saludo2);  // Compara dos cadenas y devuelve un valor entero que indica su orden relativo\n\nConsole.WriteLine(sonIguales);\nConsole.WriteLine(comparacion);\n\nConsole.WriteLine();\n\n// Eliminacion de espacios en blanco\n\nConsole.WriteLine(\"=== ELIMINACION ESPACIOS EN BLANCO === \\n\");\n\nstring cadenaConEspacios = \"  Programacion en CSharp  \";\n\nstring sinEspacios = cadenaConEspacios.Trim();\n\nConsole.WriteLine(sinEspacios);\n\nConsole.WriteLine();\n\n// Busqueda\n\nConsole.WriteLine(\"=== BUSQUEDA === \\n\");\n\nint indice = str.IndexOf(\"Angel\");\nbool verificacion = str.Contains(\"Moreno\");\n\nConsole.WriteLine(indice);\nConsole.WriteLine(verificacion);\n\nConsole.WriteLine();\n\n// ========== EXTRA =============\n\nConsole.WriteLine(\"=== EXTRA === \\n\");\n\nvoid AnalyzeWords(string str1, string str2)\n{\n    void Palindromo(string str1, string str2)\n    {\n        char[] newStr1 = str1.ToLower().ToCharArray();\n        Array.Reverse(newStr1);\n        string Str1R = new (newStr1);\n\n        bool like1 = str1.Equals(Str1R);\n\n\n        char[] newStr2 = str2.ToLower().ToCharArray();\n        Array.Reverse(newStr2);\n        string Str2R = new (newStr2);\n\n        bool like2 = str2.Equals(Str2R);\n\n        if (like1 && like2)\n        {\n            Console.WriteLine(\"Las dos palabras son palindromas\");\n        }\n        else if (like1 && !like2)\n        {\n            Console.WriteLine(\"Solo la primera palabra es palindroma\");\n        }\n        else if (!like1 && like2)\n        {\n            Console.WriteLine(\"Solo la segunda palabra es palindroma\");\n        }\n        else if (!like1 && !like2) \n        { \n             Console.WriteLine(\"Ninguna palabra es palindroma\"); \n        }\n\n        Console.WriteLine();\n    }\n\n    void Anagrama(string str1, string str2)\n    {\n        char[] newStr1 = str1.ToCharArray();\n        Array.Sort(newStr1);\n        string str1S = new(newStr1);\n\n        char[] newStr2 = str2.ToCharArray();\n        Array.Sort(newStr2);\n        string str2S = new(newStr2);\n\n        bool sortWord = str1S.Equals(str2S);\n\n        if (sortWord)\n        {\n            Console.WriteLine(\"Las palabras son un anagrama\");\n        }\n        else\n        {\n            Console.WriteLine(\"Las palabras no son un anagrama\");\n        }\n\n        Console.WriteLine();\n    }\n\n    void Isograma(string str1, string str2)\n    {\n        if (str1.Length == str1.Distinct().Count())\n        {\n            Console.WriteLine(\"La primera palabra es un isograma\");\n        }\n        else\n        {\n            Console.WriteLine(\"La primera palabra no es un isograma\");\n        }\n\n        Console.WriteLine();\n\n        if (str2.Length == str2.Distinct().Count())\n        {\n            Console.WriteLine(\"La segunda palabra es un isograma\");\n        }\n        else\n        {\n            Console.WriteLine(\"La segunda palabra no es un isograma\");\n        }\n\n        Console.WriteLine();\n    }\n\n    Palindromo(str1, str2);\n    Anagrama(str1, str2);\n    Isograma(str1, str2);\n        \n}\n\nAnalyzeWords(\"murcielago\", \"reconocer\");\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/c#/charlerodriguez3.cs",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n\n */\n\nstring word = \"This is a word\";\nstring word2 = \"Hello\";\nstring word3 = \"World\";\nstring word4 = null;\n\nConsole.WriteLine(word.IndexOf('s'));// find the specific position of the first letter found\nConsole.WriteLine(word.Substring(0,4);// substrings\nConsole.WriteLine(word.Length);//length of the string\n//Options for concatenation\nConsole.WriteLine(word2 + word3);\nConsole.WriteLine(\"value of word2 {0} and value of word3 {1}\",word2, word3);\nConsole.WriteLine($\"{word2} {word3}\");\nConsole.WriteLine(String.Concat(word,word2,word3));\nConsole.WriteLine(word.Replace('i','@'));//replacing\nConsole.WriteLine(String.IsNullOrWhiteSpace(word4));\n\n/*\n* DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas \n */\n\n     string word = \"roma\";\n    string word2 = \"amor\";\n    string word3 = \"cuaderno\";\n    string word4 = \"educaron\";\n    string word5 = \"retos\";\n    string word6 = \"acondicionar\";\n\nArray.Sort(word3.ToCharArray());\n\n\n\nConsole.WriteLine(isPalindrome(word, word2));//true\nConsole.WriteLine(isPalindrome(word, word3));//false\nConsole.WriteLine(isAnagram(word3, word4));//true\nConsole.WriteLine(isAnagram(word, word4));//false\nConsole.WriteLine(isIsogram(word5));//true\nConsole.WriteLine(isIsogram(word6));//false\n\n\nstatic bool isPalindrome(string word, string word2) => word.Reverse().ToArray().SequenceEqual(word2.ToCharArray());\nstatic bool isAnagram(string word, string word2)\n{\n    char[] newWord = word.ToCharArray();\n    char[] newWord2 = word2.ToCharArray();\n    Array.Sort(newWord);\n    Array.Sort(newWord2);\n    if (newWord.SequenceEqual(newWord2)) return true;\n    \n    return false;\n}\nstatic bool isIsogram(string wordI) => wordI.Length == wordI.Distinct().Count();"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/c#/devcherry1.cs",
    "content": "/****  CADENAS DE CARACTERES  *******\n * \n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\n *   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\n *   interpolación, verificación...\n */\n\nusing System;\nusing System.Linq; //Para usar Reverse()\n\nclass Program\n{\n    static void Main()\n    {\n        //longitud\n        string corta = \"LOL\";\n        int cortaL = corta.Length;\n\n        //vacia\n        string vacia = string.Empty;\n\n        //Concat\n        string larguisima = string.Concat(\"Laughing a \", \"lot \", corta);\n\n        //Interpolacion\n        string mensaje = $\"He was {larguisima}\";\n\n        //Substring\n        string porcion = mensaje.Substring(15);\n\n        //Busqueda\n        var indice = mensaje.IndexOf(\"lot\"); //Encuentra la posición de una subcadena.\n\n        //Contiene\n        bool isThere = mensaje.Contains(\"Laughing\"); //Verifica si contiene una subcadena. True|False\n\n        //Verificar cómo comienza o termina la cadena.\n        bool inicio = mensaje.StartsWith(\"He\"); //true\n        bool fin = mensaje.EndsWith(\"lol\"); //true\n\n        //Reemplazar texto\n        string mensaje2 = mensaje.Replace(\"He\", \"She\"); //reemplaza He con She\n\n        //Mayusculas y minusculas\n        string gritar = mensaje2.ToUpper();\n        string susurrar = corta.ToLower();\n\n        //Dividir y unir cadenas\n        string texto = \"uno,dos,tres\";\n        string[] partes = texto.Split(','); // [\"uno\", \"dos\", \"tres\"]\n        // Divide la cadena en un arreglo basado en un delimitador.\n        string unido = string.Join(\"-\", partes); // \"uno-dos-tres\"\n        // Une un arreglo en una sola cadena.\n\n        //Trim - Elimina espacios al inicio y al final de la cadena.\n        string saludo = \"   Hola, mundo!   \";\n        Console.WriteLine(texto.Trim()); // \"Hola, mundo!\"\n\n        Console.WriteLine(gritar);\n\n        Extra.Palindromo(\"reconocer\");\n        Extra.Palindromo(\"cielo\");\n        Extra.Anagrama(\"amor\", \"roma\");\n        Extra.Isograma(\"murcielago\");\n    }\n}\n/* DIFICULTAD EXTRA (opcional):\n* Crea un programa que analice dos palabras diferentes y realice comprobaciones\n* para descubrir si son:\n* - Palíndromos\n* - Anagramas\n* - Isogramas\n*/\nclass Extra\n{\n    public static void Palindromo(string palabra1)\n    {\n        // Invertir la palabra - .Reverse es un metodo para Arrays\n        string palabraInvertida = new string(palabra1.Reverse().ToArray());\n\n        // Comparar la palabra original con la invertida\n        if (palabra1 == palabraInvertida)\n        {\n            Console.WriteLine($\"La palabra \\\"{palabra1}\\\" es un palíndromo.\");\n        }\n        else\n        {\n            Console.WriteLine($\"La palabra \\\"{palabra1}\\\" no es un palíndromo.\");\n        }\n    }\n    public static void Anagrama(string palabra1, string palabra2)\n    {\n        // Ordenar las letras de ambas palabras alfabeticamente\n        string palabra1Ordenada = new string(palabra1.OrderBy(c => c).ToArray());\n        string palabra2Ordenada = new string(palabra2.OrderBy(c => c).ToArray());\n\n        // Comparar las palabras ordenadas\n        if (palabra1Ordenada == palabra2Ordenada)\n        {\n            Console.WriteLine($\"{palabra1} y {palabra2} son anagramas.\");\n        }\n        else\n        {\n            Console.WriteLine($\"{palabra1} y {palabra2} no son anagramas.\");\n        }\n    }\n    public static void Isograma(string palabra1) \n    //Un isograma es una palabra en la que ninguna letra se repite.\n    {\n        foreach (char letra in palabra1)\n        {\n            if (palabra1.Count(c => c == letra) > 1)\n            {\n                Console.WriteLine($\"La palabra {palabra1} no es un isograma\");\n                break;\n            }\n        }\n        Console.WriteLine($\"La palabra {palabra1} si es un isograma\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/c#/estuardodev.cs",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\nclass Program\n{\n\n    public static void Main(string[] args)\n    {\n        Operaciones(\"C#\", \"Python\");\n        Console.WriteLine(\"\\n-- Dificultad Extra --\\n\");\n        DificultadExtra(\"Palindromo\", \"Isograma\");\n        Console.WriteLine(\"\\n----\\n\");\n        DificultadExtra(\"Ana\", \"OlLo\");\n    }\n\n    private static void Operaciones(string texto1, string texto2)\n    {\n        // Acceso a caracteres\n        Console.WriteLine(\"-- Acceso a Indices de un texto --\");\n        Console.WriteLine($\"Indice 0 del Texto 1: {texto1[0]}\");\n        Console.WriteLine($\"Indice 3 del Texto 2: {texto2[3]}\\n\");\n\n        // Crear subcadenas\n        Console.WriteLine(\"-- Crear Subcadenas --\");\n        Console.WriteLine($\"Subcadena del texto 1: {texto1.Substring(1)}\");\n        Console.WriteLine($\"Subcadena del texto 2: {texto2.Substring(3)}\\n\");\n\n        // Longitudes\n        Console.WriteLine(\"-- Longitudes --\");\n        Console.WriteLine($\"Longitud del texto 1: {texto1.Length}\");\n        Console.WriteLine($\"Longitud del texto 2: {texto2.Length}\\n\");\n\n        // Concatenación de cadenas\n        Console.WriteLine(\"-- Concatenación --\");\n        Console.WriteLine($\"Forma 1:\" + texto1 + \" \" + texto2);\n        Console.WriteLine($\"Forma 2: {texto1} {texto2}\\n\");\n\n        // Repetición\n        Console.WriteLine(\"-- Repetición --\");\n        for (int i = 0; i < 3; i++) { Console.WriteLine(texto1); }\n        for (int i = 0; i < 3; i++) { Console.WriteLine(texto2); }\n\n        // Recorrido\n        Console.WriteLine(\"\\n-- Recorrido --\");\n        foreach (char i in texto1 ) { Console.WriteLine(i); }\n\n        // Conversión a mayúsculas\n        Console.WriteLine(\"\\n-- Conversión a mayúsculas --\");\n        Console.WriteLine(texto1.ToUpper());\n        Console.WriteLine(texto2.ToUpper());\n\n        // Conversión a minúsculas\n        Console.WriteLine(\"\\n-- Conversión a minúsculas --\");\n        Console.WriteLine(texto1.ToLower());\n        Console.WriteLine(texto2.ToLower());\n\n        // Reemplazo\n        Console.WriteLine(\"\\n-- Reemplazo --\");\n        Console.WriteLine(texto1.Replace('#', '+'));\n        Console.WriteLine(texto2.Replace('o', '0'));\n\n        // Unión\n        Console.WriteLine(\"\\n-- Unión --\");\n        Console.WriteLine(texto1.Concat(texto2));\n\n        // Interpolación\n        Console.WriteLine(\"\\n-- Interpolación --\");\n        Console.WriteLine($\"Lenguaje 1 es: {texto1} y el 2 es: {texto2}\");\n\n        // Verificación\n        Console.WriteLine(\"\\n-- Verificación --\");\n        Console.WriteLine(texto1 == texto2);\n\n    }\n\n    // Dificultad Extra\n    private static void DificultadExtra(string texto1, string texto2)\n    {\n        // Anagrama\n        bool EsAnagrama()\n        {\n            char[] arreglo1 = texto1.ToLower().ToCharArray();\n            char[] arreglo2 = texto2.ToLower().ToCharArray();\n\n            Array.Sort(arreglo1);\n            Array.Sort(arreglo2);\n\n            return arreglo1.SequenceEqual(arreglo2);\n        }\n\n        if (EsAnagrama())\n        {\n            Console.WriteLine(\"Los textos son anagramas.\");\n        }\n        else\n        {\n            Console.WriteLine(\"Los textos no son anagramas\");\n        }\n\n        // Palíndromos\n        string txt1 = texto1.ToLower();\n        string txt2 = texto2.ToLower();\n\n        if (txt1.Equals(new string(txt1.Reverse().ToArray())))\n        {\n            Console.WriteLine($\"{texto1} es palíndromo.\");\n\n            if (txt2.Equals(new string(txt2.Reverse().ToArray())))\n            {\n                Console.WriteLine($\"{texto2} es palíndromo.\");\n            }\n            else\n            {\n                Console.WriteLine($\"{texto2} no es palíndromo.\");\n            }\n        } else if (txt2.Equals(new string(txt2.Reverse().ToArray())))\n        {\n            Console.WriteLine($\"{texto1} no es palíndromo.\");\n            Console.WriteLine($\"{texto2} es palíndromo.\");\n        }\n        else\n        {\n            Console.WriteLine($\"{texto1} no es palíndromo.\");\n            Console.WriteLine($\"{texto2} no es palíndromo.\");\n        }\n\n        // Isogramas\n        \n        string text1 = texto1.ToLower();\n        string text2 = texto2.ToLower();\n\n        if(text1.Length == text1.Distinct().Count())\n        {\n            Console.WriteLine($\"{texto1} es Isograma\");\n        }\n        else\n        {\n            Console.WriteLine($\"{texto1} no es Isograma\");\n        }\n\n        if (text2.Length == text2.Distinct().Count())\n        {\n            Console.WriteLine($\"{texto2} es Isograma\");\n        }\n        else\n        {\n            Console.WriteLine($\"{texto2} no es Isograma\");\n        }\n\n\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/c#/isaacus98.cs",
    "content": "﻿/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\n *   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\n *   interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\nnamespace RetosProgramacion2024\n{\n    internal class Program\n    {\n        private static int VariableGlobal = 1000;\n\n        static void Main(string[] args)\n        {\n            string str = \"Hola\";\n            string str2;\n\n            // String to char array\n            char[] chr = str.ToCharArray();\n            for (int i = 0; i < chr.Length; i++)\n            {\n                Console.WriteLine(chr[i]);\n            }\n\n            // Longitud string\n            Console.WriteLine(str.Length);\n\n            // Concatenación string\n            str = \"string 1\";\n            str2 = \"string 2\";\n\n            str += str2;\n            Console.WriteLine(str);\n\n\n            str = \"string 1\";\n            str2 = \"string 2\";\n\n            str = String.Join(' ', str, str2);\n            Console.WriteLine(str);\n\n            // Repetición string\n            // Assigna una caracter a la string un numero determinado de veces\n            str = new string('a', 5);\n            Console.WriteLine(str);\n\n            // Recorrer string\n            str = \"Hola, soy una string\";\n\n            for (int i = 0;i < str.Length;i++)\n            {\n                Console.WriteLine(str[i]);\n            }\n\n            // Conversión mayusculas y minusculas\n            Console.WriteLine(str);\n            Console.WriteLine(str.ToUpper());\n            Console.WriteLine(str.ToLower());\n\n            // Reemplazo\n            // Remplaza el los caracteres de una string por otro\n            Console.WriteLine(str);\n            Console.WriteLine(str.Replace('o', '?'));\n\n            // Dividir cadena\n            // El split divide la cadena en subcadenas\n            string[] palabras = str.Split(' ');\n            Console.WriteLine(String.Join(\" \", palabras));\n\n            // Unión\n            string[] nombres = { \"isaac\", \"sergi\", \"josep\" };\n            Console.WriteLine(String.Join(\" \", nombres));\n\n\n            // Interpolación\n            str = \"interpolada\";\n            Console.WriteLine($\"Esta cadena es {str}\");\n\n\n            // Format\n            Console.WriteLine(String.Format(\"Hola, esto es una {0} con {1}\", \"string\", \"formato\"));\n\n            // Verificación\n            // Sirve para verificar si la candena contiene el un determinado valor dentro de la cadena\n            str = \"Hola Mundo\";\n            Console.WriteLine(str.Contains(\"Hola\"));\n\n            // Substring\n            // Recupera una subcadena de la instacia indicando el indice del qual quieres empezar\n            // y la cantidad de caracteres que quieres. Si no se indica la cantidad recupera todo lo que hay despues del indice\n            str = \"hola Mundo\";\n            Console.WriteLine(str.Substring(1,3));\n\n            // Recupera una subcadena de la instancia empezado por la izquierda.\n            // Solo se indica la cantidad de caracteres que queremos recuperar\n            Console.WriteLine(str.PadLeft(4));\n\n            // Hace lo mismo que PadLeft pero empezando por la derecha\n            Console.WriteLine(str.PadRight(5));\n\n            // Comparación\n            str = \"Hola\";\n            str2 = \"Hola\";\n            Console.WriteLine(str.Equals(str2));\n            Console.WriteLine(str.Equals(str2));\n\n            // Insert\n            // Sirve para insertar un caracter en una posición determinada de la string\n            str = str.Insert(str.Length, \"!\");\n            Console.WriteLine(str);\n\n            // Remove\n            // Sirve para quitar un caracter o varios caracteres de una string en una posición determinada\n            str = str.Remove(str.Length-1);\n            Console.WriteLine(str);\n\n            // Trim\n            // El trim sirve para eliminar los espacios que hay tanto al principio como al final del string\n            str = \"            hola    \";\n            Console.WriteLine(str);\n            Console.WriteLine(str.Trim());\n\n            // Reto extra\n            Console.WriteLine(\"\\nReto extra\");\n\n            Console.WriteLine(AnalizarPalabra(\"salas\", \"salas\"));\n            Console.WriteLine(AnalizarPalabra(\"cava\", \"vaca\"));\n            Console.WriteLine(AnalizarPalabra(\"centrifugado \", \"\"));\n            Console.WriteLine(AnalizarPalabra(\"casa\", \"vaca\"));\n        }\n\n        private static string AnalizarPalabra(string str1, string str2)\n        {\n            if (EsPalindromo(str1, str2))\n                return $\"La palabra {str1} es un palíndromo\";\n\n            if (EsAnagrama(str1, str2))\n                return $\"La palabra {str2} es un anagra de {str1}\";\n\n            if (EsIsograma(str1))\n                return $\"La palabra {str1} es un isograma\";\n\n            return $\"La palabra {str1} no es un palíndromo, anagrama o isograma\"; \n        }\n\n        private static bool EsPalindromo(string str1, string str2)\n        {\n            char[] palabra = str2.ToCharArray();\n            palabra.Reverse();\n            str2 = String.Concat(palabra);\n\n            return str1 == str2;\n        }\n\n        private static bool EsAnagrama(string str1, string str2)\n        {\n            if (str1.Length != str2.Length)\n                return false;\n\n            char[] palabra1 = str1.ToCharArray();\n            char[] palabra2 = str2.ToCharArray();\n\n            Array.Sort(palabra1);\n            Array.Sort(palabra2);\n\n            for (int i = 0; i < palabra1.Length; i++)\n            {\n                if (palabra1[i] != palabra2[i]) \n                    return false;\n            }\n\n            return true;\n        }\n\n        private static bool EsIsograma(string str)\n        {\n            char[] palabra = str.ToCharArray();\n            Array.Sort(palabra);\n\n            for (int i = 1;i < palabra.Length; i++)\n            {\n                if (palabra[i - 1] == palabra[i])\n                    return false;\n            }\n\n            return true;\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/c#/jamerrq.cs",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n*/\n\nusing System;\n\nclass Strings\n{\n    // Acceso a caracteres específicos\n    // https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/indexers/using-indexers\n    static void getChars()\n    {\n        Console.WriteLine(\"string str = \\\"Hello C#!\\\";\");\n        string str = \"Hello C#!\";\n        Console.WriteLine(\"str[0]: \" + str[0]); // H\n        Console.WriteLine(\"str[6]: \" + str[6]); // W\n    }\n\n    // Subcadenas\n    // https://learn.microsoft.com/en-us/dotnet/api/system.string.substring?view=net-8.0\n    static void getSubstrings()\n    {\n        Console.WriteLine(\"string str = \\\"Hello C#!\\\";\");\n        string str = \"Hello C#!\";\n        Console.WriteLine(\"str.Substring(6): \" + str.Substring(6)); // C#!\n        Console.WriteLine(\"str.Substring(0, 5): \" + str.Substring(0, 5)); // Hello\n    }\n\n    // Longitud\n    // https://learn.microsoft.com/en-us/dotnet/api/system.string.length?view=net-8.0\n    static void getLength()\n    {\n        Console.WriteLine(\"string str = \\\"Hello C#!\\\";\");\n        string str = \"Hello C#!\";\n        Console.WriteLine(\"str.Length: \" + str.Length); // 12\n    }\n\n    // Concatenación\n    // https://learn.microsoft.com/en-us/dotnet/api/system.string.concat?view=net-8.0\n    static void getConcatenation()\n    {\n        Console.WriteLine(\"string str1 = \\\"Hello\\\";\");\n        Console.WriteLine(\"string str2 = \\\"C#!\\\";\");\n        string str1 = \"Hello\";\n        string str2 = \"C#!\";\n        Console.WriteLine(\"string.Concat(str1, str2): \" + string.Concat(str1, str2)); // HelloC#!\n    }\n\n    // Repetición\n    // https://blog.nimblepros.com/blogs/repeat-string-in-csharp/\n    static void getRepetition()\n    {\n        /*\n          C# no provee como tal un método para repetir una cadena, pero puedes hacerlo usando la función Repeat de la clase Enumerable.\n        */\n        Console.WriteLine(\"string text = \\\"Hello\\\";\");\n        Console.WriteLine(\"int n = 3;\");\n        string text = \"Hello\";\n        int n = 3;\n        Console.WriteLine(\"string.Concat(Enumerable.Repeat(text, n)): \" + string.Concat(System.Linq.Enumerable.Repeat(text, n))); // HelloHelloHello\n    }\n\n    // Recorrido\n    // https://learn.microsoft.com/en-us/dotnet/api/system.string.tochararray?view=net-8.0\n    static void getTraversal()\n    {\n        Console.WriteLine(\"string str = \\\"Hello C#!\\\";\");\n        string str = \"Hello C#!\";\n        char[] arr = str.ToCharArray();\n        foreach (char c in arr)\n        {\n            Console.WriteLine(c);\n        }\n    }\n\n    // Conversión a mayúsculas y minúsculas\n    // https://learn.microsoft.com/en-us/dotnet/api/system.string.toupper?view=net-8.0\n    // https://learn.microsoft.com/en-us/dotnet/api/system.string.tolower?view=net-8.0\n    static void getCaseConversion()\n    {\n        Console.WriteLine(\"string str = \\\"Hello C#!\\\";\");\n        string str = \"Hello C#!\";\n        Console.WriteLine(\"str.ToUpper(): \" + str.ToUpper()); // HELLO C#!\n        Console.WriteLine(\"str.ToLower(): \" + str.ToLower()); // hello c#!\n    }\n\n    // Reemplazo\n    // https://learn.microsoft.com/en-us/dotnet/api/system.string.replace?view=net-8.0\n    static void getReplacement()\n    {\n        Console.WriteLine(\"string str = \\\"Hello C#!\\\";\");\n        string str = \"Hello C#!\";\n        Console.WriteLine(\"str.Replace(\\\"C#\\\", \\\"World\\\"): \" + str.Replace(\"C#\", \"World\")); // Hello World!\n    }\n\n    // División\n    // https://learn.microsoft.com/en-us/dotnet/api/system.string.split?view=net-8.0\n    static void getSplit()\n    {\n        Console.WriteLine(\"string str = \\\"Hello C#!\\\";\");\n        string str = \"Hello C#!\";\n        string[] arr = str.Split(' ');\n        foreach (string s in arr)\n        {\n            Console.WriteLine(s);\n        }\n    }\n\n    // Unión\n    // https://learn.microsoft.com/en-us/dotnet/api/system.string.join?view=net-8.0\n    static void getJoin()\n    {\n        Console.WriteLine(\"string[] arr = {\\\"Hello\\\", \\\"C#!\\\"};\");\n        string[] arr = { \"Hello\", \"C#!\" };\n        Console.WriteLine(\"string.Join(\\\" \\\", arr): \" + string.Join(\" \", arr)); // Hello C#!\n    }\n\n    // Interpolación\n    // https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/interpolated\n    static void getInterpolation()\n    {\n        Console.WriteLine(\"string name = \\\"C#\\\";\");\n        string name = \"C#\";\n        Console.WriteLine($\"Hello {name}!\"); // Hello C#!\n    }\n\n    // Verificación\n    // https://learn.microsoft.com/en-us/dotnet/api/system.string.contains?view=net-8.0\n    static void getVerification()\n    {\n        Console.WriteLine(\"string str = \\\"Hello C#!\\\";\");\n        string str = \"Hello C#!\";\n        Console.WriteLine(\"str.Contains(\\\"C#\\\"): \" + str.Contains(\"C#\")); // True\n    }\n\n    /*\n     * DIFICULTAD EXTRA (opcional):\n     * Crea un programa que analice dos palabras diferentes y realice\n       comprobaciones para descubrir si son:\n     * - Palíndromos\n     * - Anagramas\n     * - Isogramas\n    */\n\n    // Palíndromos\n    static void isPalindrome(string str)\n    {\n        int l = 0;\n        int h = str.Length - 1;\n        while (h > l)\n        {\n            if (str[l++] != str[h--])\n            {\n                Console.WriteLine(\"No es un palíndromo\");\n                return;\n            }\n        }\n        Console.WriteLine(\"Es un palíndromo\");\n    }\n\n    // Anagramas\n    static void isAnagram(string str1, string str2)\n    {\n        if (str1.Length != str2.Length)\n        {\n            Console.WriteLine(\"No es un anagrama\");\n            return;\n        }\n        char[] arr1 = str1.ToCharArray();\n        char[] arr2 = str2.ToCharArray();\n        Array.Sort(arr1);\n        Array.Sort(arr2);\n        for (int i = 0; i < arr1.Length; i++)\n        {\n            if (arr1[i] != arr2[i])\n            {\n                Console.WriteLine(\"No es un anagrama\");\n                return;\n            }\n        }\n        Console.WriteLine(\"Es un anagrama\");\n    }\n\n    // Isogramas\n    static void isIsogram(string str)\n    {\n        for (int i = 0; i < str.Length; i++)\n        {\n            for (int j = i + 1; j < str.Length; j++)\n            {\n                if (str[i] == str[j])\n                {\n                    Console.WriteLine(\"No es un isograma\");\n                    return;\n                }\n            }\n        }\n        Console.WriteLine(\"Es un isograma\");\n    }\n\n    // Resumen ejercicio extra\n    static void MainExtra()\n    {\n        Console.WriteLine(\"========================================\");\n        Console.WriteLine(\"============= PALÍNDROMOS ==============\");\n        Console.WriteLine(\"========================================\\n\");\n        Console.WriteLine($\"isPalindrome(\\\"reconocer\\\"): \");\n        isPalindrome(\"reconocer\");\n        Console.WriteLine($\"isPalindrome(\\\"hola\\\"): \");\n        isPalindrome(\"hola\");\n        Console.WriteLine(\"\\n========================================\");\n        Console.WriteLine(\"============== ANAGRAMAS ===============\");\n        Console.WriteLine(\"========================================\\n\");\n        Console.WriteLine($\"isAnagram(\\\"hola\\\", \\\"aloh\\\"): \");\n        isAnagram(\"hola\", \"aloh\");\n        Console.WriteLine($\"isAnagram(\\\"hola\\\", \\\"mundo\\\"): \");\n        isAnagram(\"hola\", \"mundo\");\n        Console.WriteLine(\"\\n========================================\");\n        Console.WriteLine(\"============== ISOGRAMAS ===============\");\n        Console.WriteLine(\"========================================\\n\");\n        Console.WriteLine($\"isIsogram(\\\"reconocer\\\"): \");\n        isIsogram(\"reconocer\");\n        Console.WriteLine($\"isIsogram(\\\"hola\\\"): \");\n        isIsogram(\"hola\");\n        Console.WriteLine($\"isIsogram(\\\"mundo\\\"): \");\n        isIsogram(\"mundo\");\n    }\n\n    // Función principal\n    static void Main()\n    {\n        Console.WriteLine(\"========================================\");\n        Console.WriteLine(\"=============== CARACTERES =============\");\n        Console.WriteLine(\"========================================\\n\");\n        getChars();\n        Console.WriteLine(\"\\n========================================\");\n        Console.WriteLine(\"============== SUBCADENAS ==============\");\n        Console.WriteLine(\"========================================\\n\");\n        getSubstrings();\n        Console.WriteLine(\"\\n========================================\");\n        Console.WriteLine(\"=============== LONGITUD ===============\");\n        Console.WriteLine(\"========================================\\n\");\n        getLength();\n        Console.WriteLine(\"\\n========================================\");\n        Console.WriteLine(\"============== CONCATENACIÓN ===========\");\n        Console.WriteLine(\"========================================\\n\");\n        getConcatenation();\n        Console.WriteLine(\"\\n========================================\");\n        Console.WriteLine(\"=============== REPETICIÓN =============\");\n        Console.WriteLine(\"========================================\\n\");\n        getRepetition();\n        Console.WriteLine(\"\\n========================================\");\n        Console.WriteLine(\"=============== RECORRIDO ==============\");\n        Console.WriteLine(\"========================================\\n\");\n        getTraversal();\n        Console.WriteLine(\"\\n========================================\");\n        Console.WriteLine(\"= CONVERSIÓN A MAYÚSCULAS Y MINÚSCULAS =\");\n        Console.WriteLine(\"========================================\\n\");\n        getCaseConversion();\n        Console.WriteLine(\"\\n========================================\");\n        Console.WriteLine(\"=============== REEMPLAZO ==============\");\n        Console.WriteLine(\"========================================\\n\");\n        getReplacement();\n        Console.WriteLine(\"\\n========================================\");\n        Console.WriteLine(\"=============== DIVISIÓN ===============\");\n        Console.WriteLine(\"========================================\\n\");\n        getSplit();\n        Console.WriteLine(\"\\n========================================\");\n        Console.WriteLine(\"=============== UNIÓN ==================\");\n        Console.WriteLine(\"========================================\\n\");\n        getJoin();\n        Console.WriteLine(\"\\n========================================\");\n        Console.WriteLine(\"============== INTERPOLACIÓN ===========\");\n        Console.WriteLine(\"========================================\\n\");\n        getInterpolation();\n        Console.WriteLine(\"\\n========================================\");\n        Console.WriteLine(\"=============== VERIFICACIÓN ===========\");\n        Console.WriteLine(\"========================================\\n\");\n        getVerification();\n        Console.WriteLine(\"\\n========================================\");\n        Console.WriteLine(\"============= EJERCICIO EXTRA ============\");\n        Console.WriteLine(\"========================================\\n\");\n        MainExtra();\n    }\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/c#/kenysdev.cs",
    "content": "/* ╔══════════════════════════════════════╗\n   ║ Autor:  Kenys Alvarado               ║\n   ║ GitHub: https://github.com/Kenysdev  ║\n   ║ 2024 -  C#                           ║\n   ╚══════════════════════════════════════╝\n   ----------------------------------------\n   # Cadenas de Caracteres\n   ----------------------------------------\n*/\nusing System.Text;\n// ________________________________________\n// Declaración e inicialización\nstring msg;      \nstring msg1 = \"\";\nstring old_path = \"c:\\\\Program Files\";\nstring new_path = @\"c:\\Program Files\"; // literal\nstring text = @\"Permite cadenas de varias líneas, caracteres \nde barra diagonal inversa o comillas dobles insertadas.\";\n// Tabulación horizontal.\nstring columns = \"Column 1\\tColumn 2\\tColumn 3\"; \n// Salto de línea.\nstring rows = \"Row 1\\r\\nRow 2\\r\\nRow 3\";\n\n// ________________________________________\n// Longitud\nstring str1 = \"abcd\";\nint length = str1.Length;\nConsole.WriteLine(\"longitud: \" + length);\n\n// ________________________________________\n// Método Trim \nstring str2 = \"   str   \";\n// Eliminar los caracteres en blanco al inicio y al final.\nstring trim_str = str2.Trim();\nConsole.WriteLine(trim_str);\n// Eliminar al inicio.\nstring trim_start = str2.TrimStart();\nConsole.WriteLine(trim_start);\n// Eliminar al final.\nstring trim_end = str2.TrimEnd();\nConsole.WriteLine(trim_end);\n\n// ________________________________________\n// Extraer una parte de la cadena.\nstring str3 = \"Hello, world!\";\nstring newStr3 = str3.Substring(7, 5);\nConsole.WriteLine(newStr3); // World\n\n// Eliminar una parte de la cadena.\nvar sb = new StringBuilder(str3);\nsb.Remove(7, 5);\nConsole.WriteLine(sb.ToString()); // Hello, !\n\n// ________________________________________\n// Reemplazar un carácter por otro\nstring str4 = \"abc def\";\nstring newStr4 = str4.Replace(\"c\", \"C\");\nConsole.WriteLine(newStr4); // abC def\nnewStr4 = str4.Replace(\"def\", \"DEF\");\nConsole.WriteLine(newStr4); // abc DEF\n\n// ________________________________________\n// Mayúsculas\nstring str5 = \"abc\";\nstring newStr5 = str5.ToUpper();\nConsole.WriteLine(newStr5); // ABC\n\n// ________________________________________\n// Minúsculas\nstring str6 = \"ABC\";\nstring newStr6 = str6.ToLower();\nConsole.WriteLine(newStr6); // abc\n\n// ________________________________________\n// Concatenación\nstring str_a = \"a\";\nstring str_b = \"b\";\nint int_r = 7;\nstring combined_str = str_a + \"-\" + str_b + \"=\" + int_r.ToString();\nConsole.WriteLine(combined_str); // a-b=7\n\n// ________________________________________\n// Interpolación\nstring name = \"Ben\";\nint age = 21; \nConsole.WriteLine($\"Soy {name} y tengo {age} años.\");\n\n// ________________________________________\n// Acceso\nstring str7 = \"abcd\";\nchar endChar = str7[3];\nConsole.WriteLine(endChar); // d\n\n// verificación\nConsole.WriteLine(str7.Contains(\"bc\")); // true\n\n// ________________________________________\n// Iterar\nforeach (char c in str7)\n{\n    Console.WriteLine(c);\n}\n\n/* ________________________________________\nEjercicio:\n* Crea un programa que analice dos palabras diferentes y realice comprobaciones\n* para descubrir si son:\n* - Palíndromos (Igual ambas direcciones)\n* - Anagramas   (Reordenamiento de las letras de otra palabra)\n* - Isogramas   (No hay letras repetidas)\n*/\n\nvoid exs(string str1, string str2)\n{\n    bool isAnagram = str1.OrderBy(c => c).SequenceEqual(str2.OrderBy(c => c));\n    \n    Console.WriteLine(@$\"\n    ________________________________________\n    \"\"{str1}\"\" es un palíndromo?: {str1 == new string(str1.Reverse().ToArray())}\n    \"\"{str2}\"\" es un palíndromo?: {str2 == new string(str2.Reverse().ToArray())}\n\n    \"\"{str1}\"\" es un anagrama de \"\"{str2}\"\"?: {isAnagram}\n\n    \"\"{str1}\"\" es un isograma?: {str1.Length == str1.Distinct().Count()}\n    \"\"{str2}\"\" es un isograma?: {str2.Length == str2.Distinct().Count()}\n    \");\n}\n\nexs(\"reconocer\",\"vida\");\nexs(\"notas\",\"santo\");\nexs(\"héroe\",\"radar\");\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/c#/vasilealexandru02.cs",
    "content": "public class vasilealexandru02\n{\n\n    static void Main(string[] args)\n    {\n\n\n        /*\n         * EJERCICIO:\n         * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n         * en tu lenguaje. Algunas de esas operaciones podran ser (busca todas las que puedas):\n         * - Acceso a caracteres especficos, subcadenas, longitud, concatenacin, repeticin, recorrido,\n         *   conversin a maysculas y minsculas, reemplazo, divisin, unin, interpolacin, verificacin...\n         */\n\n\n        string miCadena = \"Hola\";\n        string miCadena2 = \" Mundo\";\n        string holaMundo = miCadena + miCadena2;\n        Console.WriteLine(\"Cadena concatenada: \" + holaMundo);\n        string subcadena = holaMundo.Substring(miCadena.Length);\n        Console.WriteLine(\"Subcadena: \" + subcadena);\n\n        char miCaracterEspecifico = subcadena[1];\n\n        Console.WriteLine(\"Carcter especfico: \" + miCaracterEspecifico);\n        string largoCadenaInterpolacion = $\"El largo de mi cadena: {holaMundo}, es de {holaMundo.Length} caracteres \";\n        Console.WriteLine(largoCadenaInterpolacion);\n\n        Console.WriteLine($\" Mi texto en maysculas: {largoCadenaInterpolacion.ToUpper()}\");\n        Console.WriteLine($\" Mi texto en minsculas: {largoCadenaInterpolacion.ToLower()}\");\n\n        Console.WriteLine($\"Estas dos cadenas son iguales: {miCadena.Equals(miCadena2)}\");\n\n        var cadenaComoLista = holaMundo.ToList();\n\n        cadenaComoLista.ForEach(letra =>\n        {\n            Console.WriteLine($\"Letra {letra}\");\n        });\n\n        Console.WriteLine(\"Mi cadena: \" + holaMundo + \", contiene la subcadena\" + miCadena2 + \": \" + holaMundo.Contains(miCadena2));\n\n\n        var caracteres = holaMundo.ToCharArray();\n        string cadenaSeparadaPorComas = String.Join(\",\", caracteres);\n\n        Console.WriteLine(\"Letras separadas por un caracter: \" + cadenaSeparadaPorComas); ;\n\n        string holaMundoI = holaMundo.Replace('o', 'i');\n\n        Console.WriteLine(\"Intercambiando caracteres: \" + holaMundoI);\n\n        //compararPalabras(\"amor\", \"ana\"); --> test palabras palndromas\n        //compararPalabras(\"lacteo\", \"coleta\"); --> test palabras anagramas\n        compararPalabras(\"fotolitografia\", \"litofotografia\"); //--> test palabras anagramas\n        //compararPalabras(\"murcilago\", \"mewing\"); --> test palabras isogramas\n\n        /*\n        * DIFICULTAD EXTRA (opcional):\n        * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n        * para descubrir si son:\n        * - Palndromos\n        * - Anagramas\n        * - Isogramas\n        */\n\n        void compararPalabras(string palabra, string palabraDos)\n        {\n            // Comprobar si las palabras son palndromas\n\n            string palabraInversa = String.Join(\"\", palabra.Reverse());\n            Console.WriteLine($\"La palabra {palabra} es palndroma: {palabraInversa.Equals(palabra)}\");\n\n            string palabraDosInversa = String.Join(\"\", palabraDos.Reverse());\n            Console.WriteLine($\"La palabra {palabraDos} es palndroma: {palabraDosInversa.Equals(palabraDos)}\");\n            var test2 = palabraDos.Reverse();\n\n            bool anagrama = false;\n            List<bool> checks = new List<bool>();\n            // Comprobar si las palabras son anagramas\n            if (palabra.Length == palabraDos.Length && !palabra.Equals(palabraDos))\n            {\n\n                var palabraArray = palabra.ToList();\n                palabraArray.ForEach(c =>\n                {\n                    checks.Add(palabraDos.Contains(c));\n                });\n                anagrama = !checks.Contains(false);\n            }\n\n\n            Console.WriteLine($\"Las palabras: {palabra} y {palabraDos} son anagramas: {anagrama}\");\n            // Comprobar si las palabras son isogramas\n\n            HashSet<char> caracteres = new HashSet<char>();\n\n            palabra.ToList().ForEach(c => caracteres.Add(c));\n            Console.WriteLine($\"La palabra {palabra} es isograma: {palabra.Length == caracteres.Count}\");\n\n            caracteres.Clear();\n\n            palabraDos.ToList().ForEach(c => caracteres.Add(c));\n\n            Console.WriteLine($\"La palabra {palabraDos} es isograma: {palabraDos.Length == caracteres.Count}\");\n\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/c#/victormugo.cs",
    "content": "﻿using System.ComponentModel.DataAnnotations;\nusing System.Diagnostics.Metrics;\n\nnamespace _04_cadenas\n{\n    internal class Program\n    {\n        static void Main(string[] args)\n        {\n            /*\n             * EJERCICIO:\n             * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n             * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n             * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\n             *   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\n             *   interpolación, verificación...\n             *\n             * DIFICULTAD EXTRA (opcional):\n             * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n             * para descubrir si son:\n             *  - Palíndromos\n             *  - Anagramas\n             *  - Isogramas\n            */\n\n            string cadena = \"Hola que tal\";\n\n            // Interpolación\n            Console.WriteLine($\"Cadena: {cadena}\");\n\n            // Conversión a mayúsculas\n            Console.WriteLine($\"Mayusculas: {cadena.ToUpper()}\");\n\n            // Conversión a minusculas\n            Console.WriteLine($\"Minusculas: {cadena.ToLower()}\");\n\n            // Longitud de caracteres\n            Console.WriteLine($\"Longitud: {cadena.Count()}\");\n\n            // División\n            string[] partes = cadena.Split(\" \");\n            Console.WriteLine($\"Partes {partes.Length}\");\n            for (int i = 0; i < partes.Length; i++) \n            { \n                Console.WriteLine($\"Parte: {partes[i]}\");\n            }\n\n            // Verificación\n            if (String.IsNullOrEmpty(cadena))\n            {\n                Console.WriteLine(\"Cadena vacía\");\n            }\n\n            // Reemplazo\n            Console.WriteLine($\"Reemplazo: {cadena.Replace(\" \", \",\")}\");\n            Console.WriteLine($\"Reemplazo: {cadena.Replace(\",\", \" \")}\");\n\n            // Subcadenas\n            Console.WriteLine($\"Subcadenas: {cadena.Substring(1,7)}\");\n\n            // Indice\n            Console.WriteLine($\"Indice: {cadena.IndexOf(\"q\")}\");\n\n            // Eliminar:\n            Console.WriteLine($\"Eliminar: {cadena.Remove(4)}\");\n\n            // Último indice\n            Console.WriteLine($\"Ultimo indice: {cadena.LastIndexOf(\"a\")}\");\n            \n            // Concatenación\n            string cadena2 = \". Estoy muy bien\";\n            Console.WriteLine($\"Concatenación: {cadena += cadena2}\");\n\n            // Obtener caracters\n            for (int i = 0; i < cadena.Length; i++)\n            {\n                Console.WriteLine(cadena[i]);\n            }\n\n            // Join\n            string[] cadenas = { \"Hola\", \"esto\", \"es\", \"un\", \"test\" };\n            Console.WriteLine($\"Join: {string.Join(\" \", cadenas)}\");\n\n            // Verificación\n            Console.WriteLine($\"Verificación: {cadenas.Contains(\"Hola\")}\");\n            Console.WriteLine($\"Verificación: {cadenas.Contains(\"Adios\")}\");\n\n\n            // ---------------------- EJERCICIO\n            Console.WriteLine(\"Introduzca palabra 1: \");\n            string palabra1 = Console.ReadLine();\n\n            Console.WriteLine(\"Introduzca palabra 2: \");\n            string palabra2 = Console.ReadLine();\n\n            if (!String.IsNullOrEmpty(palabra1) && !String.IsNullOrEmpty(palabra2))\n            {\n                palabra1 = palabra1.ToLower().Trim();\n                palabra2 = palabra2.ToLower().Trim();\n\n\n                // --- Palíndromo: Un palíndromo es una palabra o frase que se lee igual en un sentido que en otro\n                if (VerificaPalindromo(palabra1, palabra2))\n                {\n                    Console.WriteLine($\"{palabra1} y {palabra2} son palíndromos\");\n                }\n                else\n                {\n                    Console.WriteLine($\"{palabra1} y {palabra2} NO son palíndromos\");\n                }\n\n\n\n                // --- Anagrama: Los anagramas son cambios en el orden de las letras de una palabra que dan lugar a otra palabra diferente (caso y saco)\n                if (VerificaAnagrama(palabra1, palabra2))\n                {\n                    Console.WriteLine($\"{palabra1} y {palabra2} son Anagramas\");\n                }\n                else\n                {\n                    Console.WriteLine($\"{palabra1} y {palabra2} NO son Anagramas\");\n                }\n\n\n\n                // --- Isograma: Es una palabra o frase en la que cada letra aparece el mismo número de veces.\n                // Si cada letra aparece solo una vez será un heterograma, si aparece dos, un isogroma de segundo orden y así sucesivamente\n                if (VerificaIsograma(palabra1))\n                {\n                    Console.WriteLine($\"{palabra1} es Isograma\");\n                }\n                else\n                {\n                    Console.WriteLine($\"{palabra1} NO es Isograma\");\n                }\n\n                if (VerificaIsograma(palabra2))\n                {\n                    Console.WriteLine($\"{palabra2} es Isograma\");\n                }\n                else\n                {\n                    Console.WriteLine($\"{palabra2} NO es Isograma\");\n                }\n            }\n        }\n\n\n        /// <summary>\n        /// Método para verificar si una palabra es palíndromo\n        ///  Un palíndromo es una palabra o frase que se lee igual en un sentido que en otro\n        /// </summary>\n        /// <param name=\"word\"></param>\n        /// <returns></returns>\n        public static bool VerificaPalindromo(string word1, string word2)\n        {\n            try\n            {\n                if (word1.Length == word2.Length)\n                {\n\n                    for (int i = 0; i < word1.Length; i++)\n                    {\n                        if (word1[i] != word2[word2.Length - i - 1])\n                        {\n                            return false;\n                        }\n                    }\n                    return true;\n                }\n                else\n                {\n                    return false;\n                }\n            }\n            catch (Exception e)\n            {\n                Console.WriteLine(e.Message);\n                return false;\n            }\n        }\n\n\n        /// <summary>\n        /// Método para verificar si dos palabras son Anagramas\n        /// Los anagramas son cambios en el orden de las letras de una palabra que dan lugar a otra palabra diferente (caso y saco)\n        /// </summary>\n        /// <param name=\"word1\"></param>\n        /// <param name=\"word2\"></param>\n        /// <returns></returns>\n        public static bool VerificaAnagrama(string word1, string word2)\n        {\n            try\n            {\n                int counter = 0;\n\n                if (word1.Length == word2.Length)\n                {\n                    for (int i = 0; i < word1.Length; i++)\n                    {\n                        for (int j = 0; j < word2.Length; j++)\n                        {\n                            if (word1[i] == word2[j] )\n                            {\n                                counter++;\n                                break;\n                            }\n                        }\n                    }\n\n                    if (counter == word1.Length)\n                    {\n                        return true;\n                    }\n\n                    return false;\n                } \n                else\n                {\n                    return false;\n                }\n            }\n            catch (Exception e)\n            {\n                Console.WriteLine(e.Message);\n                return false;\n            }\n        }\n\n\n        /// <summary>\n        /// Método para verificar si una palabra es Isograma\n        /// Es una palabra o frase en la que cada letra aparece el mismo número de veces. \n        /// Si cada letra aparece solo una vez será un heterograma, si aparece dos, un isogroma de segundo orden y así sucesivamente\n        /// </summary>\n        /// <param name=\"word1\"></param>\n        /// <param name=\"word2\"></param>\n        /// <returns></returns>\n        public static bool VerificaIsograma(string word)\n        {\n            try\n            {\n                int counter = 0;\n\n                for (int i = 0; i < word.Length; i++)\n                {\n                    for (int j = 0; j < word.Length; j++)\n                    {\n                        if (i != j && word[i] == word[j])\n                        {\n                            counter++;\n                        }\n                    }\n\n                    if (counter > 1)\n                    {\n                        return false;\n                    }\n                    counter = 0;\n                }\n                return true;\n            }\n            catch (Exception e)\n            {\n                Console.WriteLine(e.Message);\n                return false;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/c#/vixxtory.cs",
    "content": "﻿using static System.Runtime.InteropServices.JavaScript.JSType;\n\nnamespace Cadenas\n{\n    class Program\n    {\n\n        static void Main(string[] args)\n        {\n            string text = \"Hello, World!\";\n            //Longitud de cadena \n            int length = text.Length;\n            Console.WriteLine(\"La longitud de la cadena es: \" + length);\n\n            //Método Trim: eliminar los caracteres en blanco al inicio y al final de una cadena \n            //Los caracteres en blanco incluyen espacios, tabulaciones y saltos de línea.\n            string textTrim = \"   Hello, World!   \";\n            string trimText = textTrim.Trim();\n            Console.WriteLine(\"La cadena original es: \" + textTrim);\n            Console.WriteLine(\"La cadena después de utilizar Trim es: \" + trimText);\n\n            //Método TrimEnd: eliminar los caracteres en blanco al final de una cadena de caracteres.\n            string trimEndText = textTrim.TrimEnd();\n            Console.WriteLine(\"La cadena original es: \" + textTrim);\n            Console.WriteLine(\"La cadena después de utilizar TrimEnd es: \" + trimEndText);\n\n            //Método TrimStart:  eliminar los caracteres en blanco al inicio de una cadena.\n            string trimStartText = textTrim.TrimStart();\n            Console.WriteLine(\"La cadena original es: \" + textTrim);\n            Console.WriteLine(\"La cadena después de utilizar TrimStart es: \" + trimStartText);\n\n            /*\n            ELIMINAR O CORTAR PARTE DE LA CADENA\n            */\n            //Método Substring (desde el carácter en la posición 7 hasta la posición 5 después de él)\n            string newText = text.Substring(7, 5);\n            Console.WriteLine(\"La cadena original es: \" + text);\n            Console.WriteLine(\"La nueva cadena es: \" + newText);\n\n            //Metodo Substring: Recorta una cadena\n            string newTextSubString = text.Substring(7); //desde el carácter en la posición 7 hasta el final\n            Console.WriteLine(\"La cadena original es: \" + text);\n            Console.WriteLine(\"La nueva cadena es: \" + newTextSubString);\n\n            //Metodo Replace: Reemplaza un carácter por otro, también una subcadena por otra subcadena\n            string newTextReplace = text.Replace('o', 'O');\n            Console.WriteLine(\"La cadena original es: \" + text);\n            Console.WriteLine(\"La nueva cadena es: \" + newTextReplace);\n\n            string newTextReplace2 = text.Replace(\"Hello\", \"Hi\");\n            Console.WriteLine(\"La cadena original es: \" + text);\n            Console.WriteLine(\"La nueva cadena es: \" + newTextReplace2);\n\n            //Método ToUpper: convierte una cadena a mayúsculas\n            //(Si se desea modificar la cadena original, se debe asignar la nueva cadena a la misma variable)\n            string newTextToUpper = text.ToUpper();\n            Console.WriteLine(\"La cadena original es: \" + text);\n            Console.WriteLine(\"La nueva cadena es: \" + newTextToUpper);\n\n            //Método ToLower: convierte una cadena a minúsculas.\n            string newTextToLower = text.ToLower();\n            Console.WriteLine(\"La cadena original es: \" + text);\n            Console.WriteLine(\"La nueva cadena es: \" + newTextToLower);\n\n            /*\n             * CONCATENACION DE STRING \n             */\n            //La mas comun es con el operador +\n            string firstString = \"Hola\";\n            string secondString = \"Manuelita\";\n            string combinedString = firstString + \" \" + secondString + \"!\";\n            Console.WriteLine(combinedString);\n\n            //Metodo Concat\n            string combinedString2 = string.Concat(firstString, \" \", secondString, \"!\");\n            Console.WriteLine(combinedString2);\n\n            /*\n             * CONCATENAR NUMEROS Y STRING\n             */\n            //Primero es necesario convertir los números a cadenas de caracteres mediante el método ToString()\n            int number = 42;\n            string message = \"La respuesta es: \" + number.ToString();\n            Console.WriteLine(message);\n\n            //INTERPOLACION DE STRING: es una forma de crear una nueva cadena a partir de una plantilla de cadena y valores dinámicos.\n            //La sintaxis para la interpolación de cadenas es $\"{expression}\", donde expression es una expresión que se evalúa y se convierte en una cadena.\n\n            string name = \"John\";\n            int age = 30;\n            Console.WriteLine($\"Mi nombre es {name} y tengo {age} años.\");\n\n            //Tambien puede realizarse el formateo con el metodo Format\n            Console.WriteLine(string.Format(\"Mi nombre es {0} y tengo {1} años\", name, age));\n\n            //ACCESO A CARACTERES\n            //Se puede acceder a los caracteres individuales de una cadena utilizando el índice.\n            //El indice de una cadena comienza en cero y se extiende hasta la longitud de la cadena menos uno.\n            string message2 = \"Hola Victoria\";\n            char firstCharacter = message2[0];\n            char sixthCharacter = message2[5];\n            Console.WriteLine($\"The first character is: {firstCharacter}\");\n            Console.WriteLine($\"The sixth character is: {sixthCharacter}\");\n\n            //CARACTERES ESPECIALES\n            //Se representan mediante secuencias de escape, que comienzan con el carácter de barra invertida (\\)\n            /*\n             Algunos ejemplos son:\n            \\n: nueva línea\n            \\r: retorno de carro\n            \\t: tabulación\n            \\\\: barra invertida\n            \\\": comilla doble\n            \\': comilla simple\n             */\n            string message11 = \"Hello\\nWorld\";\n            Console.WriteLine(message11);\n\n            string message22 = \"Hello\\rWorld\";\n            Console.WriteLine(message22);\n\n            string message3 = \"Hello\\tWorld\";\n            Console.WriteLine(message3);\n\n            string message4 = \"Hello\\\\World\";\n            Console.WriteLine(message4);\n\n            string message5 = \"Hello\\\"World\";\n            Console.WriteLine(message5);\n\n            string message6 = \"Hello\\'World\";\n            Console.WriteLine(message6);\n\n            //Metodo Parse: Conversion entre cadenas y otros tipos de datos\n            string numeroTexto = \"10\";\n            int numeroParse = int.Parse(numeroTexto);\n            string stringBooleano = \"false\";\n            Console.WriteLine(numeroParse.GetType());\n            Console.WriteLine(bool.Parse(stringBooleano).GetType());\n\n            //Metodo Split(): permite dividir una cadena en subcadenas utilizando un separador específico.\n            string s1 = \"Hola,amigo, ¿cómo estás?\";\n            string[] stringSplit = s1.Split(',');\n            foreach (var word in stringSplit)\n            {\n                Console.WriteLine($\"<{stringSplit}>\");\n            }\n\n            //Metodo Contains(value): true si el parámetro de value aparece dentro de esta cadena; en caso contrario, false.\n            Console.WriteLine(s1.Contains(\"Hola\"));\n            Console.WriteLine(s1.Contains(\"?\"));\n        }\n    }\n}\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/c++/Fravelz.cpp",
    "content": "#include <iostream> \n#include <string>\n#include <vector>\n\nusing namespace std;\n\n// ********************** #04 - Cadena de Caracteres ********************** //\n\nbool palindromos(string texto);\nbool anagramas(string texto1, string texto2);\nbool isogramas(string texto1);\n\nint main() {\n    /*\n    Hay en c++, hay 2 formas basicas de crear una cadena de caracteres:\n    1. char[10] (El objecto char como vector)\n    2. string (Libreria Estandar)\n    */\n\n    char texto1[11] = \"Hola Mundo\";\n\n    string texto2 = \"Hola Mundo :)\";\n    \n    //* Insersion en flujo de salida (Insertar datos para imprimir en pantalla)\n\n    cout << texto1 << \" - \" << texto2 << '\\n'; // Hola Mundo - Hola Mundo :)\n    \n    //* Concatenacion\n\n    // Se puede concatenar si el primer objecto es string\n\n    cout << (texto1 + texto2) << \"\\n\"; // Hola MundoHola Mundo :)\n    cout << (texto2 + \" # 2\") << \"\\n\"; // Hola Mundo :) # 2\n    cout << (texto2 + \" + \" + texto1) << \"\\n\"; // Hola Mundo :) + Hola Mundo\n\n    //* Indexacion\n    cout << (texto1[1]) << \"\\n\"; // o \n    cout << (texto2[5]) << \"\\n\"; // M\n    cout << (texto2.at(5)) << \"\\n\"; // M (lanza error si se sale del rango)\n\n    //! (Char no tiene Las siguientes propiedad)\n\n    //* Longitud (Esos dos son lo mismo y llaman a la misma funcion interna)\n    cout << (texto2.length()) << \"\\n\"; // 13 (Solo para string)\n    cout << (texto2.size()) << \"\\n\"; // 13 (Para contenedores, como arreglos)\n    \n    //* Slicing (Porcion)\n    cout << (texto2.substr(5, 8)) << \"\\n\"; // Mundo :)\n    \n    //* Busqueda\n    cout << (texto2.find(\":)\")) << \"\\n\"; // 11\n\n    //* Remplazar\n    texto2.replace(5, 5, \"universo\"); \n    cout << texto2; // Hola universo :)\n\n// ********************** Ejercicio Dificultad Extra ********************** //\n    cout << '\\n';\n\n    cout << palindromos(\"ini\")        << '\\n'; // 0 (true)\n    cout << palindromos(\"hola\")       << '\\n'; // 1 (false)\n\n    cout << anagramas(\"roma\", \"amor\") << '\\n'; // 1 (false)\n    cout << anagramas(\"roma\", \"amo\")  << '\\n'; // 0 (true)\n\n    cout << isogramas(\"Suma\")        << '\\n'; // 1 (false)\n    cout << isogramas(\"intestinos\")  << '\\n'; // 0 (true)\n\n\n    return 0;\n}\n\nbool palindromos(string texto) {\n    string new_texto;\n\n    for (int x = texto.length(); x > 0; x--) {\n        new_texto += texto[x-1];\n    }\n\n\n    if (new_texto == texto) { return true; }\n    return false;\n};\n\nbool anagramas(string texto1, string texto2) {\n    \n    auto encontrar = [](char caracter, string text) {\n        int contador = 0;\n\n        for (char i : text) {\n            if (i == caracter) { contador++; }\n        }\n        return contador;\n    };\n\n    for (char caracter1 : texto1) {\n        if (encontrar(caracter1, texto1) != encontrar(caracter1, texto2)){\n            return false;\n        }\n    }\n    return true;\n}\n\nbool isogramas(string texto1) {\n    int veces = 0;\n    \n    auto encontrar = [](char caracter, string text) {\n        int contador = 0;\n\n        for (char i : text) {\n            if (i == caracter) { contador++; }\n        }\n        return contador;\n    };\n\n    veces = encontrar(texto1[0], texto1);\n\n    for (char caracter1 : texto1) {\n        if (encontrar(caracter1, texto1) != veces){\n            return false;\n        }\n    }\n    return true;\n}"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/c++/RoniPG.cpp",
    "content": "// @RoniPG\n\n#include <iostream>\n#include <set>\n#include <string>\n#include <cstring>\n#include <algorithm>\n\nvoid Palindromo(std::string);\nvoid Anagrama(std::string,std::string);\nvoid Isograma(std::string);\n\nint main(){\n\n\tstd::string ejemplo=\"Hola Mundo\";\n\tstd::string ejemplo2(\"Hello World\");\n\tstd::string vacio=\"\";\n\tstd::basic_string <char> alias_string; //std::basic_string es la superclase de la clase std::string\n\n\n\tsize_t encontrar = ejemplo.find(\"Mundo\");\n\t(encontrar!=std::string::npos) // --> std::string::npos Se utiliza para verificar si la subcadena fue encontrada o no.\n\t? std::cout << \"Valor encontrado\" << std::endl : std::cout << \"Valor encontrado\"<<std::endl;\n\tstd::cout << ejemplo.append (\"\\tAñadido\") // --> Añade al final de la cadena de carateres otra cadena de caracteres que le pasemos\n\t<<\tstd::endl;\n\tstd::cout << ejemplo.assign (ejemplo2) // --> Sobrescribe el valor que le pasamos como parametro\n\t<< std::endl;\n\tejemplo=\"Hola Mundo\";\n\tstd::cout << ejemplo.at(1) // --> Devuelve el valor en la poscion que le indiquemos\n\t<< std::endl;\n\tstd::cout << ejemplo.back() // --> Devuelve el ultimo valor de la cadena de caracteres\n\t<< std::endl;\n\tchar * c_str = new char [ejemplo.length()+1];\n\tstd::string::iterator begin =ejemplo.begin(); // --> Devuelve un iterador que apunta al primer carácter de la cadena\n\tstd::strcpy(c_str,ejemplo.c_str()); // --> Devuelve un puntero a una cadena de caracteres estilo C(terminada en NULL(\\0))\n\tstd::cout<< c_str << std::endl;\n\tstd::cout << ejemplo.capacity() // --> Devuelve el numero maximo de caracteres que puede contener sin necesidad de asignar mas memoria\n\t<< std::endl;\n\tstd::string::const_iterator iter = ejemplo.cbegin(); // --> Devuelve un iterador constante que apunta a la primera posicion de la cadena de caracteres\n\tfor( /*no hace falta iniciar el iterador*/;\n\titer != ejemplo.cend(); // --> Devuelve un iterador constante que apunta a la ultima posicion de la cadena de caracteres\n\titer++){std::cout<<*iter<<std::endl;}\n\tstd::cout << \"antes del clear: \"<<ejemplo<<std::endl; ejemplo.clear(); // --> Vacia la cadena y libera el espacio en memoria asociada a su almacenamiento\n\tstd::cout << \" Despues del clear: \"<<ejemplo<<std::endl;\n\tejemplo.append(\"Hola Mundo\");\n\tstd::cout << ejemplo.compare(\"Hola Mundo\") // -->Compara dos cadenas de caracteres y devuelve un numero con la diferencia lexicografica\n\t<< std::endl;\t\t\t\t\t\t\t\t\t\t\t\t\t\t//\t\tentre las dos cadenas\n\tchar buffer[ejemplo.length()]; size_t copy = ejemplo.copy(buffer, 6, 0); // --> Copiar una parte de una cadena en otro array o buffer\n\tbuffer[copy]='\\0'; std::cout << buffer << std::endl; //\n\tstd::string::const_reverse_iterator crbegin=ejemplo.crbegin();// --> Devuelve un iterador constante que apunta a la primera posicion de la cadena de caracteres\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  //\t en orden inverso\n\tfor( /*no hace falta iniciar el iterador*/;\n\tcrbegin != ejemplo.crend(); // --> Devuelve un iterador constante que apunta a la ultima posicion de la cadena de caracteres contando en orden inverso\n\tcrbegin++){std::cout<<*crbegin;}\n\tstd::cout << std::endl;\n\tconst char * const_data = ejemplo.data(); // --> Obtener un puntero al array de caracteres internos de una cadena(para lectura)\n\tstd::cout << const_data << std::endl;\n\tchar * no_const_data = const_cast<char *>(ejemplo.data()); // --> Obtener un puntero al array de caracteres internos de una cadena(para lectura/escritura)\n\tno_const_data[0]='h'; std::cout << no_const_data << std::endl;\n \tstd::cout << std::boolalpha << ejemplo.empty() // --> Verifica si la cadena esta vacia, si esta vacia devuelve True sino False.\n\t<< std::endl;\n \tstd::string::iterator end = ejemplo.end(); // --> Devuelve un iterador que apunta justo despues del ultimo caracter de la cadena\n \tstd::cout << ejemplo.erase(6) // --> Se utiliza para eliminar datos dentro de una cadena ya sea por posicion o por rango\n \t<< std::endl;\n \tejemplo= \"Hola Mundo\";\n\tstd::cout << ejemplo.find(\"ola\") // --> Se utiliza para buscar un caracter o una cadena de caracteres especifica, devuelve la posicion de la cadena/caracter\n\t<< std::endl;\n\tstd::cout << \"first not of: \"<< ejemplo.find_first_not_of(\"ola\") // -->Se utiliza para buscar cualquier caracter de una cadena de caracteres dada, devuelve la primera posicion que no coincida con la cadena de caracteres dada\n\t<< std::endl;\n\tstd::cout << \"first of: \"<< ejemplo.find_first_of(\"ola\") // --> Se utiliza para buscar cualquier caracter de una cadena de caracteres dada, devuelve la primera coincidencia encontrada\n\t<< std::endl;\n\tstd::cout << \"last not of: \"<<ejemplo.find_last_not_of(\"ola\") // --> Se utiliza para buscar cualquier caracter de una cadena de caracteres dada, devuelve la ultima posicion que no coincida con la cadena de caracteres dada\n\t<< std::endl;\n\tstd::cout << \"last of: \"<<ejemplo.find_last_of(\"ola\") // --> Se utiliza para buscar cualquier caracter de una cadena de caracteres dada, devuelve la ultima coincidencia encontrada\n\t<< std::endl;\n\tchar& front = ejemplo.front(); // --> Devuelve una referencia al primer carácter de la cadena\n\tstd::cout << front\t<< std::endl;\n\tstd::allocator<std::string> myAllocator = ejemplo.get_allocator(); // --> Devuelve el objeto allocator asociado con la cadena\n\tstd:: string* my_string = myAllocator.allocate(1);\n\tnew (my_string) std::string(ejemplo, myAllocator);\n\tstd::cout << \"Valor del string construido: \" << *my_string << std::endl;\n\tmy_string->~basic_string(); myAllocator.deallocate(my_string, 1);\n\tejemplo.insert(ejemplo.end(),{' ','N','u','e','v','o'}); // --> Inserta elementos dentro de la cadena\n\tstd::cout << ejemplo << std::endl;\n\tstd::cout << ejemplo.length() // --> Se utiliza para obtener la longitud (número de caracteres) de la cadena de caracteres\n\t<< std::endl;\n\tstd::cout << ejemplo.max_size() // --> Devuelve el tamaño máximo posible que puede tener la cadena de caracteres\n\t<< std::endl;\n\tstd::cout << ejemplo.operator +=('o') << std::endl; // -->  Invocar explícitamente el operadorX como un metodo()\n\tejemplo.pop_back(); // --> Se utiliza para eliminar el último carácter de una cadena\n\tstd::cout << std::endl;\n\tejemplo.push_back('.'); // --> Se utiliza para añadir un caracter en la ultima posicion de una cadena\n\tstd::cout << ejemplo << std::endl;\n\tstd::string::reverse_iterator rbegin = ejemplo.rbegin(); // --> Se utiliza para obtener un iterador que apunta al último elemento de una cadena ya que la 'r' se refiere a reversa.\n\tstd::string::reverse_iterator rend = ejemplo.rend(); // --> Se utiliza para obtener un iterador que apunta al primer elemento de una cadena ya que la 'r' se refiere a reversa..\n\tfor (;rbegin != rend; ++rbegin) { std::cout << *rbegin;\t} std::cout<<std::endl;\n\tstd::cout << ejemplo.replace(2, 4, \"123\") // --> Se utiliza para reemplazar subcadenas en una cadena dada\n\t<< std::endl;\n\tstd::cout << ejemplo.rfind('o') // --> Es utilizada para buscar la última ocurrencia de una subcadena dentro de una cadena.\n\t<<std::endl;\n\tstd::cout << \"Tamaño antes del reserve: \" << ejemplo.capacity() << std::endl;\n\tejemplo.reserve(20); // --> Se utiliza para reservar espacio en la memoria para una cadena de caracteres\n\tstd::cout << \"Tamaño despues del reserve: \"<< ejemplo.capacity() << std::endl;\n\tstd::cout << \"Tamaño antes del resize: \" << ejemplo.length() << \" cadena: \" << ejemplo << std::endl;\n\tejemplo.resize(20,'*'); // --> Se utiliza para cambiar el Tamaño de la cadena\n\tstd::cout << \"Tamaño despues del resize: \"<< ejemplo.length() << \" cadena: \" << ejemplo << std::endl;\n\tstd::cout << \"Tamaño antes del shrink_to_fit: \" << ejemplo.capacity() << std::endl;\n\tejemplo.shrink_to_fit(); // --> Se utiliza para reducir la capacidad de la cadena al mínimo necesario para almacenar su contenido actual\n\tstd::cout << \"Tamaño despues del shrink_to_fit: \"<< ejemplo.capacity() << std::endl;\n\tstd::cout << ejemplo.size() << std::endl; // --> Se utiliza para obtener el número de caracteres en la cadena\n\tstd::cout << ejemplo.substr(4) << std::endl; // --> Se utiliza para extraer una subcadena de la cadena original\n\tstd::cout << \"Ejemplo antes del intercambio: \" << ejemplo << std::endl;\n    std::cout << \"Ejemplo 2 antes del intercambio: \" << ejemplo2 << std::endl;\n\tejemplo.swap(ejemplo2); // --> Se utiliza para intercambiar el contenido de dos cadenas.\n\tstd::cout << \"Ejemplo despues del intercambio: \" << ejemplo << std::endl;\n\tstd::cout << \"Ejemplo 2 despues del intercambio: \" << ejemplo2 << std::endl;\n\n\t/* DIFICULTAD EXTRA (opcional):\n\t * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n\t * para descubrir si son:\n\t * - Palíndromos\n\t * - Anagramas\n\t * - Isogramas\n\t */\n\n\tPalindromo(\"Anilina\");\n\tAnagrama(\"Amor\", \"Roma\");\n\tIsograma(\"Centrifugado\");\n\n\treturn 0;\n}\nvoid Palindromo(std::string a){\n\t/* Palindromo:\n\t * Palabra o frase cuyas letras están dispuestas de tal manera que resulta la misma leída de izquierda a derecha que de derecha a izquierda.\n\t * Por ejemplo: anilina\n\t */\n\tstd::string subA=a;\n\tstd::string aux=\"\";\n\tstd::transform(subA.begin(), subA.end(), subA.begin(), ::tolower);\n\tstd::string::reverse_iterator aReverse= subA.rbegin();\n\tstd::string::reverse_iterator rend= subA.rend();\n\tfor(;aReverse != rend;aReverse++){\n\t\taux += *aReverse;\n\t}\n\tif (subA.compare(aux)==0) {\n\t\tstd::cout << \"La palabra: \"<<a<<\".Es Palindromo\" << std::endl;\n\t}else {\n\t\tstd::cout << \"La palabra: \"<<a<<\".No es Palindromo\"<< std::endl;\n\t}\n}\nvoid Anagrama(std::string a,std::string b){\n\t/* Anagrama:\n\t * Cambio en el orden de las letras de una palabra o frase que da lugar a otra palabra o frase distinta.\n\t * Por ejemplo: Amor --> Roma\n\t */\n\tstd::string a1=a;\n\tstd::string b1=b;\n\tstd::transform(a1.begin(), a1.end(), a1.begin(), ::tolower);\n\tstd::transform(b1.begin(), b1.end(), b1.begin(), ::tolower);\n\tstd::sort(a1.begin(), a1.end());\n\tstd::sort(b1.begin(), b1.end());\n\tif (a1.compare(b1)==0) {\n\t\tstd::cout << a << \" y \" << b << \" son Anagramas\" << std::endl;\n\t} else {\n\t\tstd::cout << a << \" y \" << b << \" no son Anagramas\" << std::endl;\n\t}\n}\nvoid Isograma(std::string a){\n\t/* Un isograma es una palabra o frase en la que cada letra aparece el mismo número de veces.\n\t * Si cada letra aparece solo una vez será un heterograma, si aparece dos, un isogroma de segundo orden y así sucesivamente.\n\t * Por ejemplo:\n\t * Heterogramas: yuxtaponer, centrifugado, luteranismo.\n\t * Isogramas con una repetición o de segundo orden: acondicionar, escritura, intestinos.\n\t */\n\tbool flag=false;\n\tint count=0;\n\tstd::transform(a.begin(), a.end(), a.begin(), ::tolower);\n\tstd::set<char> subA;\n\tfor ( int i = 0; i < a.length(); i++) {\n\t\tsubA.insert(a.at(i));\n\t}\n\tfor(char character: subA){\n\t\tfor (int i = 0; i < a.length(); i++) {\n\t\t\tif (character == a.at(i)) {\n\t\t\t\tcount++;\n\t\t\t}\n\t\t}\n\t\tstd::cout << \"La letra: \\\"\"<<character<<\"\\\" esta repetida: \" << count << \" veces.\"<<std::endl;\n\t\tif(count>1){\n\t\t\tflag=true;\n\t\t}\n\t\tcount=0;\n\t}\n\tif (flag) {\n\t\tstd::cout<<\"Es un isograma\"<<std::endl;\n\t}else {\n\t\tstd::cout<<\"Es un heterograma\"<<std::endl;\n\t}\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/c++/Vid92.cpp",
    "content": "#include <iostream>\n#include <string>\n#include <algorithm>\n\nusing namespace std;\n\n\nvoid palindromo(string palabra){\n    string wordPrueba;\n    for(int i=(palabra.length()-1);i>=0;i--){\n        wordPrueba += palabra[i];\n    }\n    if(wordPrueba == palabra){\n        cout<<palabra + \"... es un palindromo!\"<<endl;\n    }else{\n        cout<<palabra + \"... no es un palindromo!\"<<endl;\n    }\n}\n\nvoid anagrama(string palabra1, string palabra2){\n    int count = 0;\n    string palabra3;\n    palabra3 = palabra2;\n    if(palabra1.length()==palabra2.length()){\n        for(int i=0;i<palabra1.length();i++){\n            for(int j=0;j<palabra1.length();j++){\n                if(palabra1[i] == palabra2[j]){\n                    count++;\n                    palabra2[j] = '\\0';\n                    break;\n                }\n            }\n        }\n        \n        if (count == palabra1.length()){\n            cout<<palabra1 + \" es anagrama de \"+ palabra3+\"!\"<<endl;\n        }else{\n            cout<<palabra1+\" no es anagrama de \"+palabra3+\"!\"<<endl;\n        }\n        \n    }else{\n        cout<<palabra1+\" no es anagrama de \"+palabra2+\"!\"<<endl;\n    }\n}\n\nvoid isograma(string palabra){\n    string temp = palabra;\n    string tmp = palabra;\n    int cont = 0;\n    int conteo[palabra.length()];\n    for(int i=0;i<palabra.length();i++){\n        cont = 0;\n        palabra = tmp;\n        for(int j=0;j<palabra.length();j++){\n            if((palabra[i]==tmp[j])&&(palabra[i]!='0')&&(tmp[j]!='\\0')){\n                tmp[j] = '\\0';\n                cont++;\n                conteo[i] = cont;\n            }\n        }\n    }\n    \n    int num = 0;\n    for(int n=0;n<temp.length();n++){\n        if(conteo[n]>=2){\n            num++;\n        }\n    }\n    \n    if(num>2){\n        cout<<temp+\" es un isograma!\"<<endl;\n    }else{\n        cout<<temp+\" no es un isograma!\"<<endl;\n    }\n}\n\nvoid analizar(string word1,string word2){\n    palindromo(word1);\n    palindromo(word2);\n    anagrama(word1,word2);\n    isograma(word1);\n    isograma(word2);\n}\n\n\nint main()\n{\n    //Concatenacion\n    string name = \"Mario \";\n    string last_name = \"Gonzales\";\n    \n    cout<<name+last_name<<endl;\n    \n    //Longitud\n    string tamaño = \"longitud\";\n    \n    cout<<\"longitud: \"<<tamaño.length()<<endl;\n    cout<<\"longitud: \"<<tamaño.size()<<endl;\n    \n    //minuscula, mayuscula\n    int ch = 0x70; //p\n    \n    cout<<\"minuscula: \"<<tolower(ch)<<endl; //p\n    cout<<\"mayuscula: \"<<toupper(ch)<<endl; //P\n    \n    //replace\n    name.replace(0,1,\"rosa\");\n    cout<<\"replace: \"<<name<<endl;\n    \n    //erase\n    tamaño.erase(5);\n    cout<<\"erase: \"<<tamaño<<endl;\n    \n    //buscar\n    string oracion = \"La manzana es roja o verde\";\n    //bool pos = oracion.find(\"i\");\n    \n    cout<<\"posicion: \"<<(oracion.find(\"roja\"))<<endl;\n    //cout<<\"posicion: \"<<pos<<endl;\n    \n    //subcadena\n    string subcadena = \"Hola mundo\";\n    cout<<\"subcadena: \"<<(subcadena.substr(0, 5))<<endl;\n    \n    //Ejercicio extra\n    analizar(\"roma\",\"amor\");\n\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/c++/hectorio23.cpp",
    "content": "// ##########################################################################\n// ##################### Librerias requeridas ###############################\n// ##########################################################################\n#include <algorithm>\n#include <iostream>\n#include <string>\n\n/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\n// Declaracion de la funcion la cual retornara una caadena de carateres \n// distinra en caso de ser polidromo, anagrama o isograma respectivamente\nstd::string  discoverType(std::string&, std::string&);\nbool anagrama(std::string, std::string);\nbool isograma(std::string);\n\n\nint main() {\n    // Las siguientes variables almacenan las palabras\n    //insertadas por el usuario \n    std::string value1, value2;\n\n    std::cout << \"Inserta la primera palabra: \";\n    std::cin >> value1;\n\n    std::cout <<  \"Ahora inserta la segunda palabra: \";\n    std::cin >> value2;\n\n\n    std::string cadena1 = \"Hola\";\n    std::string cadena2 = \"Mundo\";\n\n    // Modifican la variable original transformando sus caracteres en minusculas\n    transform(value1.begin(), value1.end(), value1.begin(), ::tolower);\n    transform(value2.begin(), value2.end(), value2.begin(), ::tolower);\n\n\n    // Se llama a la función discoverType, la cual devuelve una cadena dependiendo de \n    // si las palabras ingresadas por el usuario forman parte de un palíndromo, anagrama o isograma.\n    // Para lograr esto, se invocan otras funciones cuyo único propósito es verificar \n    // si las palabras cumplen con las especificaciones dadas.\n    std::cout << discoverType(value1, value2);\n\n    // Concatenación de dos cadenas\n    std::string concatenacion = cadena1 + \" \" + cadena2;\n    std::cout << \"Concatenación: \" << concatenacion << \"\\n\";\n\n    // Se elimina cualquier espacio de la cadena de caracteres\n    std::string cadenaPrueba = concatenacion;\n    cadenaPrueba.erase(std::remove_if(cadenaPrueba.begin(), cadenaPrueba.end(), ::isspace), cadenaPrueba.end());\n    std::cout << \"Cadena sin espacios en blanco \" << cadenaPrueba << \"\\n\";\n\n    // Obtencion de la longitud de dos cadenas\n    std::cout << \"Longitud de la cadena 1: \" << cadena1.length() << \"\\n\";\n    std::cout << \"Longitud de la cadena 2: \" << cadena2.size() << \"\\n\";\n\n    // Acceso a caracteres individuales\n    std::cout << \"Primer caracter de la cadena 1: \" << cadena1[0] << \"\\n\";\n    std::cout << \"Último caracter de la cadena 2: \" << cadena2.back() << \"\\n\";\n\n    // Comparación\n    if (cadena1 == cadena2) {\n        std::cout << \"Las cadenas son iguales\" << \"\\n\";\n    } else {\n        std::cout << \"Las cadenas son diferentes\" << \"\\n\";\n    }\n\n    // Subcadena H o l a   M u n d o\n    //           1 2 3 4 5 6 7 8 9 \n    std::string subcadena = concatenacion.substr(5, 9); // Extrae \"Mundo\"\n    std::cout << \"Subcadena: \" << subcadena << \"\\n\";\n\n    // Búsqueda \n    std::string buscar = \"Mundo\";\n    size_t posicion = concatenacion.find(buscar);\n    if (posicion != std::string::npos) {\n        std::cout << \"La cadena '\" << buscar << \"' fue encontrada en la posición \" << posicion << \"\\n\";\n    } else {\n        std::cout << \"La cadena '\" << buscar << \"' no fue encontrada\" << \"\\n\";\n    }\n\n    // Modificación\n    concatenacion.replace(5, 10, \"Universo\");\n    std::cout << \"Después de reemplazar 'Mundo' por 'Universo': \" << concatenacion << \"\\n\";\n\n    return 0;\n}\n\n\n// ##########################################################################\n// ##################### ZONA DE FUNCIONES ##################################\n// ##########################################################################\n\n\n// Esta es la funcion encargada de realizar el \n// ejercicio extra\nstd::string  discoverType(std::string& value1, std::string& value2) {\n    \n    // Se guarda una variable local la cual sera modificada\n    // para posteriormente ser comparada con la segunda palabra.\n    // Se puede observar que se ordena de manera contraria <reverse> \n    std::string valueReverse  = value1;\n    reverse(valueReverse.begin(), valueReverse.end());\n\n    if (valueReverse == (value2)) return \"\\nLas palabras anteriormente insertadas forman en realidad son un polidromo\\n\\n\";\n    else if (isograma(value1) && isograma(value2)) return \"\\nAmbas palabras son isogramas\\n\\n\";\n    else if (isograma(value1) || isograma(value2)) return \"\\nUna de las palabras es un isograma\\n\\n\";\n    else if (anagrama(value1, value2)) return \"\\nEs un anagrama\\n\\n\";\n\n    return \"\\nLas palabras proporcionadas no cumplen con las condiciones para ser un polidromo, isograma, anagrama\\n\";\n}\n\n// Funcion que comprueba que la palabra dada sea un isograma\n// comprueba que las letras sean unicas dentro de la cadena\n// de caracteres, en caso de encontrarse alguna coincidencia\n// inmediatamente saldra de la funcion retornando un valor booleano\n// falso y no seguira mas con la comprobacion,\nbool isograma(std::string palabra) {\n    std::string _tmp_ = \"\";\n\n    for (auto item: palabra) {\n\n        for (auto element: _tmp_)  if (item == element) return false;\n\n        _tmp_ += item;\n    }\n\n    return true;\n}\n\n// Comprueaba que realmente las palabras dadas sean anagramas.\n// Primero comprueba que las palabras tengan la misma longitud\n// Segundo ordena de manera alfabetica las palabras dadas, ejemplo: cerebro -> bceeorr\n// Lo hace con ambas palabras, finalmente, en caso de ser un anagrama, lel\n// producto resultante sera dos palabras identicas\nbool anagrama(std::string palabra1, std::string palabra2) {\n\n    sort(palabra1.begin(), palabra1.end());\n    sort(palabra2.begin(), palabra2.end());\n\n    if (palabra1.length() != palabra2.length() || palabra1 != palabra2) return false;\n    return true;\n}"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/c++/jhoshmc.cpp",
    "content": "/*\n* EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n*/\n#include<iostream>\n#include <cstring> // copiar, concatenar, mayuscula_strupr, minuscula_strlwr\n#include <string.h> // comparar\n#include <algorithm> // reverse_cadena\n#include <cctype> // tolower\n#include <ctype.h> // toupper\n\n\nusing namespace std;\n\nvoid copiar_strcpy();\nvoid comparar_strcmp();\nvoid concatenar_strcat();\nvoid mayusculas_strupr();\nvoid minuscula_strlwr();\nvoid reverse_cadena();\n//* extra\nstring tolower_p(string);\nstring eliminar_espacios(string);\nvoid respuesta_solo(string, string);\nvoid respuesta_duo(string, string, string);\nvoid ejercicio_extra();\nbool palindromo(string);\nbool anagrama(string, string);\nbool isograma(string);\n\nint main(){\n\n  copiar_strcpy();\n  comparar_strcmp();\n  concatenar_strcat();\n  mayusculas_strupr();\n  minuscula_strlwr();\n  reverse_cadena();\n\n  ejercicio_extra();\n\n  return 0;\n}\n\nvoid copiar_strcpy(){\n  //? strcpy copiar una cadena de caracteres de una úbicación a otra\n  //! sintaxis:  char *strcpy(char *destino, const char *origen);\n\n  cout << \"\\n\\t---------------- strcpy (copiar)-------------\\n\";\n  char origen[] = \"hola mundo\"; // cadena origen\n  char destino[strlen(origen + 1)]; // el puntero destino tine que tener espacio para la cadena origen, mas caracter final nulo\n  strcpy(destino, origen); // desdpues de esto, la variable destino tambien tendrá el valor \"hola mundo\"\n  cout << \"origen: \" << origen << endl;\n  cout << \"destino: \" << destino << endl;\n}\n\nvoid comparar_strcmp(){\n  //? strcmp compara uno a uno los caracteres de las cadenas hasta encontrarlas o encontrar una diferencia\n  //* devuelve 0 si ambas cadenas son iguales\n  //* devuelve un valor negativo si la primera cadena es menor a la segunda en valor lexicografico\n  //* devuelve un valor positivo si la primera es mayor a la segunda en valor lexicografico\n  //! sintaxis: int strcmp(const char *s1, const char *s2);\n  //* s1 y s2 son los punteros a las cadenas a las cuales se desea comparar\n\n  cout << \"\\n\\t ----------------strcmp (comparar)--------------\\n\";\n  char str1[] = \"hola\";\n  char str2[] = \"mundo\";\n  int resultado = strcmp(str1, str2);\n  cout << \"resultado: \" << resultado << endl;\n  if(resultado ==0){\n    cout << \"ambas cadenas son iguales\" << endl;\n  }else if(resultado > 0){\n    cout << \"la primera cadena es mayor\" << endl;\n  }else{\n    cout << \"la segunda cadena es mayor\" << endl;\n  }\n}\n\nvoid concatenar_strcat(){\n  //? strcat se utiliza para concatenar cadenas, agrega una copia de la cadena origen al final de la cadena destino\n  //? y devuelve la direccion a la que apunta la variable destino\n  //! sintaxis: strcat(char *destino, const char *fuente)\n  //* es importante que la cadena destino deve ser los suficiente grande para contener la cadena resultante \n  //* incluyendo el valor nulo del final\n  cout << \"\\n\\t --------------strcat (concatenar)-----------\\n\";\n\n  char cadena_1[20] = \"Esta cadena\";\n  char cadena_2[20] = \"ocupa 2\";\n  char cadena_3[20] = \"hola\";\n\n  strcat(cadena_1, cadena_2);\n  strcat(cadena_3, \" como estas?\");\n\n  cout<< \"cadena 1: \" << cadena_1 << endl;\n  cout << \"cadena 3: \" << cadena_3 << endl;\n}\n\nvoid mayusculas_strupr(){\n  //? strupr convierte las letras contenidas en la cadena en mayusculas y devuelve el puntero a la cadena\n  //* strupr no esta en todas las implementaciones, pero se puede usar _strupr_s en visual , este requiere\n  //* el tamaño del array como segundo argumento o un array de tamaño conocido en tiempo de compilacion.\n\n  cout << \"\\n\\t ------------strupr (mayusculas)-----------\\n\";\n  char texto[] = \"hola lector\";\n  cout << \"cadena original: \" << texto << endl;\n  strupr(texto); // al parecer si se puedo :v\n  // _strupr_s(texto, sizeof(texto));\n  cout << \"el texto en mayuscula es: \" << texto << endl;\n\n  //* usando toupper\n  char a = 'a';\n  cout << a << endl;\n  a = toupper(a);\n  cout << \"toupper char: \" << a << endl;\n\n  //* usando trannsform \n  string tex = \"hola\";\n  transform(tex.begin(), tex.end(), tex.begin(), ::toupper);\n  cout << \"toupper string: \" << tex << endl;\n}\n\nvoid minuscula_strlwr(){\n  //? strlwr convierte a las letras de la cadena de caracteres en minusculas y devuleve un puntero a la cadena\n  cout << \"\\n\\t ----------strlwr (minusculas)------------\\n\";\n  char texto[] = \"HOLA LECTOR\";\n  cout << \"texto original: \" << texto<<endl;\n  strlwr(texto);\n  cout << \"texto en minusculas es: \" << texto << endl;\n\n  //* usando tolower\n  char a = 'A';\n  cout << a<<endl;\n  a = tolower(a);\n  cout << \"tolower en char: \" << a << endl;\n\n  //* usando transform, para combertir todos los caracteres de una cadena en minuscula\n  string str = \"HOLA\";\n  cout << str << endl;\n  transform(str.begin(), str.end(),str.begin(), ::tolower);\n  cout << \"tolower con trasform: \" << str << endl;\n}\n\nvoid reverse_cadena(){\n  cout << \"\\n\\t ------------reverse------------------\\n\";\n  string texto = \"hola mundo\";\n  cout << \"el texto original es: \" << texto << endl;\n  reverse(texto.begin(), texto.end());\n  cout << \"el texto invertido es: \" << texto << endl;\n}\n\n/*\n* DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n*/\n\n\nstring tolower_p(string palabra){\n   transform(palabra.begin(), palabra.end(), palabra.begin(), ::tolower);\n   return palabra;\n}\n\nstring eliminar_espacios(string palabra){\n \n  palabra.erase(remove(palabra.begin(), palabra.end(), ' '), palabra.end());\n  return palabra;\n}\n\nbool palindromo(string palabra){\n  //? palabra que se lee igual en ambos sentidos\n  //! ejemplo renoconocer, Dábale arroz a la zorra el abad\n  palabra = tolower_p(palabra);\n  string copia = palabra;\n  reverse(palabra.begin(), palabra.end());\n  return palabra == copia;\n}\n\nbool anagrama(string palabra_1, string palabra_2){\n  //? palabra o frase formada al reordenar las letras de una palabra o oracion original\n  //! ejemplo de GOTA, sale GATO\n  //* no puede ser un anagrama si los tamaños son diferentes\n  if(palabra_1.size() != palabra_2.size()){\n    return false;\n  }\n\n  //* ordenar ambas palabras\n  sort(palabra_1.begin(), palabra_1.end());\n  sort(palabra_2.begin(), palabra_2.end());\n\n  return palabra_1 == palabra_2;\n}\n\nbool isograma(string palabra){\n  //? es un tipo de diagrama que representa cualidades o circunstancias iguales referidas a cosas distintas\n  //! También se refiere a una palabra en la cual ninguna letra se repite\n\n  for (size_t i = 0; i < palabra.size() - 1;i++){\n    if(palabra[i]== palabra[i+1]){\n      return false;\n    }\n  }\n\n  return true;\n}\n//* respusta de una palabra , con el tipo\nvoid respuesta_solo(string palabra, string mensaje){\n  cout << \"la palabra: \" << palabra << mensaje << endl;\n  cout << endl;\n}\n\nvoid respuesta_duo(string palabra_1, string palabra_2,string texto){\n  cout << \"la palabra: \" << palabra_1 << \" y la palaba: \" << palabra_2 << texto << endl;\n  cout << endl;\n}\n\n//* funcion principal \nvoid ejercicio_extra(){\n\n  string palabra_1;\n  string palabra_2;\n  \n  bool respuesta_1, respuesta_2,respuesta_anagrama;\n  cout << \"ingrese la primera palabra: \";\n  getline(cin, palabra_1);\n  cout << \"ingrese la segunda palabra: \";\n  getline(cin, palabra_2);\n  \n  string compacto_1= eliminar_espacios(palabra_1);\n  string compacto_2= eliminar_espacios(palabra_2);\n\n  respuesta_1 = palindromo(compacto_1);\n  respuesta_2 = palindromo(compacto_2);\n\n  //* ver si las palabras son palindroma, anagrama o isograma\n\n if(respuesta_1){\n   respuesta_solo(palabra_1, \" es palindromo\");\n }else{\n   respuesta_1 = isograma(compacto_1);\n   if(respuesta_1){\n     respuesta_solo(palabra_1, \" es isograma\");\n   }\n }\n\n if(respuesta_2){\n   respuesta_solo(palabra_2, \" es palindromo\");\n }else{\n   respuesta_2 = isograma(compacto_2);\n   if(respuesta_2){\n     respuesta_solo(palabra_2, \" es isograma\");\n   }\n }\n\n respuesta_anagrama=anagrama(compacto_1, compacto_2);\n if(respuesta_anagrama){\n   respuesta_duo(palabra_1, palabra_2, \" ambas son anagramas\");\n }\n}"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/c++/m-doce.cpp",
    "content": "#include <iostream>\r\n#include <cstring>\r\n\r\n#define MAX_SIZE 50\r\n\r\nint Longitud(char word[])\r\n{\r\n    int i = 0;\r\n\r\n    while(*word)\r\n    {\r\n        i++;\r\n        word++;\r\n    }\r\n\r\n    return i;\r\n}\r\n\r\nbool EsPalindronmo(char word[])\r\n{\r\n    bool check = true;\r\n    int size = Longitud(word);\r\n    char first = word[0];\r\n    char last = word[size-1];\r\n\r\n    for(int i=0; i<size/2; i++)\r\n    {\r\n        if(first != last)\r\n        {\r\n            check = false;\r\n            break;\r\n        }\r\n        else\r\n        {\r\n            first = word[i];\r\n            last = word[size-1-i];\r\n        }\r\n    }\r\n\r\n    return check;\r\n}\r\n\r\nbool SonAnagramas(char wordA[], char wordB[])\r\n{\r\n    bool check = true;\r\n    bool charCheck;\r\n    int sizeA = Longitud(wordA);\r\n    int sizeB = Longitud(wordB);\r\n\r\n    if(sizeA != sizeB)\r\n        check = false;\r\n    else\r\n    {\r\n        for(int i=0; i<sizeA; i++)\r\n        {\r\n            charCheck = false;\r\n\r\n            for(int j=0; j<sizeB; j++)\r\n            {\r\n                if(wordA[i] == wordB[j])\r\n                {\r\n                    charCheck = true;\r\n                    break;\r\n                }\r\n            }\r\n\r\n            if(!charCheck)\r\n                break;\r\n        }\r\n    }    \r\n\r\n    return (check and charCheck);\r\n}\r\n\r\nbool EsIsograma(char word[])\r\n{\r\n    bool check = true;\r\n    int size = Longitud(word);\r\n\r\n    for(int i=0; i<size; i++)\r\n    {\r\n        for(int j=(i+1); j<size; j++)\r\n        {\r\n            if(word[i] == word[j])\r\n            {\r\n                check = false;\r\n                break;\r\n            }\r\n        }\r\n\r\n        if(!check)\r\n            break;\r\n    }\r\n\r\n    return check;\r\n}\r\n\r\nint main()\r\n{\r\n    // - - - PALÍNDROMOS - - -\r\n    char word[MAX_SIZE];\r\n    printf(\"Ingrese una palabra para saber si es un palindromo: \");\r\n    scanf(\"%s\", &word);\r\n    if(EsPalindronmo(word))\r\n    printf(\"La palabra %s es un palindromo\\n\", word);\r\n    else\r\n    printf(\"La palabra %s no es un palindromo\\n\", word);\r\n    \r\n    // - - - ANAGRAMAS - - -\r\n    char wordA[MAX_SIZE], wordB[MAX_SIZE];\r\n    printf(\"Ingrese una palabra: \");\r\n    scanf(\"%s\", &wordA);\r\n    printf(\"Ingrese otra palabra para saber si es un anagrama de %s: \", wordA);\r\n    scanf(\"%s\", &wordB);\r\n    if(SonAnagramas(wordA, wordB))\r\n    printf(\"Las palabras %s y %s son anagramas.\\n\", wordA, wordB);\r\n    else\r\n    printf(\"Las palabras %s y %s no son anagramas.\\n\", wordA, wordB);\r\n\r\n    // - - - ISOGRAMAS - - -\r\n    char wordC[MAX_SIZE];\r\n    printf(\"Ingrese una palabra para saber si es un isograma: \");\r\n    scanf(\"%s\", &wordC);\r\n    if(EsIsograma(wordC))\r\n    printf(\"La palabra %s es un isograma\\n\", wordC);\r\n    else\r\n    printf(\"La palabra %s no es un isograma\\n\", wordC);\r\n\r\n    printf(\"Fin del programa.\\n\");\r\n    \r\n    return 0;\r\n}"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/cobol/any7dev.cbl",
    "content": "     /*\n      * EJERCICIO:\n      * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n      * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n      * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n      *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n      *\n      * DIFICULTAD EXTRA (opcional):\n      * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n      * para descubrir si son:\n      * - Palíndromos\n      * - Anagramas\n      * - Isogramas\n      */\n\n       IDENTIFICATION DIVISION.\n       PROGRAM-ID. RETO-04.\n       DATA DIVISION.\n       FILE SECTION.\n       WORKING-STORAGE SECTION.\n      *CADENAS PARA EJEMPLO\n           77 CADENA1 PIC X(10) VALUE \"HOLA MUNDO\".\n           77 CADENA2 PIC X(10).\n           77 CADENA3 PIC X(5) VALUE \"RETOS\".\n           77 CADENA4 PIC X(2) VALUE \"DE\".\n           77 CADENA5 PIC X(12) VALUE \"PROGRAMACION\".\n           77 CADENA6 PIC X(21).\n           77 CADENA7 PIC X(12) VALUE \"ROADMAP 2024\".\n           77 CADENA8 PIC X(10) VALUE \"hola mundo\".\n           77 CADENA9 PIC X(35) VALUE \"Cadena con espacios al final\".\n           77 CADENA10 PIC X(50) VALUE \"     Cadena con espacios al \"-\n                                       \"principio\".\n      *ENTEROS PARA EJEMPLO\n           77 CONTADOR PIC 9(2).\n           77 LONG PIC 9(2).\n\n      *CADENAS PARA EJERCICIO EXTRA\n           77 PALABRA1 PIC X(20).\n           77 PALABRA2 PIC X(20).\n           77 CARACTER PIC X.\n           77 PALABRA4 PIC X(20).\n           77 FRASE PIC X(200).\n           77 CARACI PIC X.\n           77 CARACJ PIC X.\n      *ENTEROS PARA EJERCICIO EXTRA\n           77 REPE1 PIC 9.\n           77 REPE2 PIC 9 VALUE 0.\n           77 CONT PIC 9(2) VALUE 1.\n           77 LONG1 PIC 9(3).\n           77 LONG2 PIC 9(3).\n           77 RESTO PIC 9.\n           77 MITAD PIC 9(2).\n           77 I PIC 9(2) VALUE 1.\n           77 J PIC 9(2).\n\n       PROCEDURE DIVISION.\n\n           DISPLAY SPACES.\n           DISPLAY \"---OPERACIONES CON CADENAS---\".\n           DISPLAY SPACES.\n\n      *CONVERTIR EN MAYUSCULAS\n       MAYUSCULAS.\n           DISPLAY \"-CONVERTIR EN MAYUSCULAS\".\n           DISPLAY CADENA8.\n           DISPLAY FUNCTION UPPER-CASE(CADENA8).\n      *Para guardar en variable\n           MOVE FUNCTION UPPER-CASE(CADENA8) TO CADENA2.\n           DISPLAY CADENA2.\n           DISPLAY SPACES.\n\n      *CONVERTIR EN MINUSCULAS\n       MINUSCULAS.\n           DISPLAY \"-CONVERTIR EN MINUSCULAS\".\n           DISPLAY CADENA1.\n           DISPLAY FUNCTION LOWER-CASE(CADENA1).\n      *Para guardar en variable\n           MOVE FUNCTION LOWER-CASE(CADENA1) TO CADENA2.\n           DISPLAY CADENA2.\n           DISPLAY SPACES.\n\n      *EXTRAER LA LONGITUD DE UNA CADENA.\n       LONGITUD.\n           DISPLAY \"-LONGITUD\"\n           DISPLAY CADENA9.\n      *Hay que tener en cuenta que en esto en cobol te dice la longitud de la variable\n           MOVE FUNCTION LENGTH(CADENA9) TO LONG.\n           DISPLAY \"Longitud variable: \" LONG.\n      *Para saber exactamente la longitud quitando los espacios del final:\n           COMPUTE LONG = FUNCTION LENGTH\n                              (FUNCTION TRIM(CADENA9, TRAILING)).\n           DISPLAY \"Longitud sin espacios al final: \" LONG.\n      *Si los espacios estuvieran al principio:\n           DISPLAY CADENA10.\n           COMPUTE LONG = FUNCTION LENGTH\n                              (FUNCTION TRIM(CADENA10, LEADING)).\n           DISPLAY \"Longitud sin espacios al principio: \" LONG.\n           DISPLAY SPACES.\n\n      *INVERTIR CADENA\n       INVERTIR.\n           DISPLAY \"-INVERTIR\"\n           DISPLAY CADENA1.\n           MOVE FUNCTION REVERSE(CADENA1) TO CADENA2.\n           DISPLAY CADENA2.\n           DISPLAY SPACES.\n\n      *INSPECCIONAR LA CADENA. NOS SIRVE PARA CONTAR O SUSTITUIR\n       CONTAR.\n           DISPLAY \"-CONTAR\"\n           DISPLAY CADENA1.\n      *Contar todos los caracteres.\n           INSPECT CADENA1 TALLYING CONTADOR FOR CHARACTERS.\n           DISPLAY CONTADOR.\n           MOVE 0 TO CONTADOR.\n      *Contar todas las \"O\"\n           INSPECT CADENA1 TALLYING CONTADOR FOR ALL \"O\".\n           DISPLAY CONTADOR.\n           DISPLAY SPACES.\n       SUSTITUIR.\n           DISPLAY \"-SUSTITUIR\"\n      *SUSTITUYE TODAS LAS LETRAS \"A\" POR 4.\n           DISPLAY CADENA7.\n           INSPECT CADENA7 REPLACING ALL \"A\" BY \"4\"\n           DISPLAY CADENA7.\n           DISPLAY SPACES.\n\n      *EXTRAER LOS CANTIDAD DE CARACTERES QUE QUIERAS DE UNA CADENA DESDE EL PRINCIPIO\n      *He elegido los primeros 7\n       PREFIJO.\n           DISPLAY \"-PREFIJO\"\n           DISPLAY CADENA1.\n           MOVE CADENA1(1:7) TO CADENA2.\n           DISPLAY CADENA2.\n           DISPLAY SPACES.\n      *Se puede usar para sacar también los ultimos caracteres. He elegido los ultimos 3\n       SUFIJO.\n           DISPLAY \"-SUFIJO\"\n           DISPLAY CADENA1.\n           MOVE CADENA1(8:3) TO CADENA2.\n           DISPLAY CADENA2.\n           DISPLAY SPACES.\n\n      *CONCATENAR VARIAS CADENAS EN OTRA\n       CONCATENAR.\n           DISPLAY \"-CONCATENAR\"\n           DISPLAY CADENA3.\n           DISPLAY CADENA4.\n           DISPLAY CADENA5.\n           STRING CADENA3 \" \" CADENA4 \" \" CADENA5\n           DELIMITED BY SIZE INTO CADENA6.\n           DISPLAY CADENA6.\n           DISPLAY SPACES.\n\n      *DIVIDIR CADENA EN VARIAS SUBCADENAS\n       DIVIDIR.\n           DISPLAY \"-DIVIDIR\"\n           DISPLAY CADENA1.\n           UNSTRING CADENA1 DELIMITED BY SPACE INTO CADENA2, CADENA6\n           END-UNSTRING\n           DISPLAY CADENA2.\n           DISPLAY CADENA6.\n           DISPLAY SPACES.\n\n\n      *DIFICULTAD EXTRA\n           DISPLAY SPACES.\n           DISPLAY \"-----DIFICULTAD EXTRA-----\".\n           DISPLAY SPACES.\n\n       PALINDROMOS.\n      *Palabra o expresión que es igual si se lee de izquierda a derecha que de derecha a izquierda.\n           DISPLAY \"-PALINDROMO\"\n           DISPLAY \"INTRODUCE LA FRASE O PALABRA: \".\n           ACCEPT FRASE.\n           MOVE FUNCTION LOWER-CASE(FRASE) TO FRASE.\n           COMPUTE LONG1 = FUNCTION LENGTH\n                              (FUNCTION TRIM(FRASE, TRAILING)).\n           DIVIDE LONG1 BY 2 GIVING MITAD REMAINDER RESTO.\n           MOVE LONG1 TO J.\n           PERFORM UNTIL I > MITAD\n               PERFORM UNTIL J < MITAD\n                   MOVE FRASE(I:LONG1) TO CARACI\n                   IF CARACI = SPACE\n                       ADD 1 TO I\n                       MOVE FRASE(I:LONG1) TO CARACI\n                   END-IF\n                   MOVE FRASE(J:1) TO CARACJ\n                   IF CARACJ = SPACE\n                       SUBTRACT 1 FROM J\n                       MOVE FRASE(J:1) TO CARACJ\n                   END-IF\n                   IF CARACI = CARACJ\n                       ADD 1 TO I\n                       SUBTRACT 1 FROM J\n                   ELSE\n                       DISPLAY \"NO ES PALINDROMO\"\n                       GO TO ANAGRAMAS\n                   END-IF\n               END-PERFORM\n           END-PERFORM.\n           DISPLAY \"ES PALINDROMO\".\n           DISPLAY SPACES.\n\n       ANAGRAMAS.\n      *Una palabra es anagrama de otra si las dos tienen las mismas letras, con el mismo número de apariciones, pero en un orden diferente.\n           DISPLAY \"-ANAGRAMAS\"\n           DISPLAY \"INTRODUCE LA PRIMERA PALABRA: \".\n           ACCEPT PALABRA1.\n           DISPLAY \"INTRODUCE LA SEGUNDA PALABRA: \".\n           ACCEPT PALABRA4.\n           MOVE FUNCTION LOWER-CASE(PALABRA1) TO PALABRA1.\n           MOVE FUNCTION LOWER-CASE(PALABRA4) TO PALABRA4.\n           IF PALABRA1 = PALABRA4\n               DISPLAY \"NO SON ANAGRAMAS\"\n           ELSE\n               COMPUTE LONG1 = FUNCTION LENGTH\n                           (FUNCTION TRIM(PALABRA1, TRAILING))\n               COMPUTE LONG2 = FUNCTION LENGTH\n                           (FUNCTION TRIM(PALABRA4, TRAILING))\n               IF LONG1 NOT EQUAL LONG2\n                   DISPLAY \"NO SON ANAGRAMAS\"\n               ELSE\n                   MOVE FUNCTION REVERSE(PALABRA1) TO PALABRA2\n                   IF CADENA2 = PALABRA4\n                       DISPLAY \"ANAGRAMAS\"\n                   ELSE\n                       MOVE FUNCTION LENGTH(PALABRA1) TO LONG1\n                       ADD 1 TO LONG1\n                       PERFORM UNTIL CONT = LONG1\n                           MOVE PALABRA1(CONT:1) TO CARACTER\n                           INSPECT PALABRA4 TALLYING REPE1 FOR ALL\n                           CARACTER REPLACING FIRST CARACTER BY SPACE\n                           ADD 1 TO CONT\n                           MOVE 0 TO REPE1\n                       END-PERFORM\n                       IF PALABRA4 EQUAL SPACES\n                           DISPLAY \"ANAGRAMAS\"\n                       ELSE\n                           DISPLAY \"NO SON ANAGRAMAS\"\n                       END-IF\n                   END-IF\n               END-IF\n           END-IF.\n           DISPLAY SPACES.\n\n       ISOGRAMAS.\n      *Un isograma es una palabra o frase en la que cada letra aparece el mismo número de veces.\n           MOVE 1 TO CONT.\n           DISPLAY \"-ISOGRAMAS\".\n           DISPLAY \"INTRODUCE PALABRA: \".\n           ACCEPT PALABRA1.\n           MOVE FUNCTION LOWER-CASE(PALABRA1) TO PALABRA1.\n           COMPUTE LONG1 = FUNCTION LENGTH\n                           (FUNCTION TRIM(PALABRA1, TRAILING))\n           ADD 1 TO LONG1\n           PERFORM UNTIL CONT = LONG1\n               MOVE PALABRA1(CONT:1) TO CARACTER\n               INSPECT PALABRA1 TALLYING REPE1 FOR ALL CARACTER\n               IF REPE2 = 0\n                   MOVE REPE1 TO REPE2\n               END-IF\n               IF REPE1 NOT EQUAL REPE2\n                   DISPLAY \"NO ES ISOGRAMA\"\n                   STOP RUN\n               ELSE\n                   ADD 1 TO CONT\n                   MOVE 0 TO REPE1\n               END-PERFORM\n           DISPLAY \"ES ISOGRAMA\".\n           STOP RUN.\n\n       END PROGRAM RETO-04.\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/cobol/keltoi-dev.cbl",
    "content": "      * EJERCICIO:\n      * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n      * en tu lenguaje. Algunas de esas operaciones podrÃ­an ser (busca todas las que puedas):\n      * - Acceso a caracteres especÃ­ficos, subcadenas, longitud, concatenaciÃ³n, repeticiÃ³n, recorrido,\n      *   conversiÃ³n a mayÃºsculas y minÃºsculas, reemplazo, divisiÃ³n, uniÃ³n, interpolaciÃ³n, verificaciÃ³n...\n      *\n      * DIFICULTAD EXTRA (opcional):\n      * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n      * para descubrir si son:\n      * - PalÃ­ndromos\n      * - Anagramas\n      * - Isogramas\n\n       IDENTIFICATION DIVISION.\n       PROGRAM-ID. RETO-04.\n       ENVIRONMENT DIVISION.\n       CONFIGURATION SECTION.\n       SPECIAL-NAMES.\n           CLASS a-z IS \"a\" THRU \"z\", SPACE, \"ñ\".\n       DATA DIVISION.\n       FILE SECTION.\n       WORKING-STORAGE SECTION.\n       77  texto PIC X(11) VALUE \"Hola COBOL!\".\n       77  cadena PIC X(15) VALUE \"Hola mundo!\".\n       77  palabra-1 PIC X(15).\n       77  palabra-2 PIC X(15).\n       77  palabra-3 PIC X(15).\n       77  concatenado PIC X(60).\n       77  contador PIC 99 VALUE ZERO.\n       77  largo PIC 99 VALUE ZERO.\n       77  largo2 PIC 99 VALUE ZERO.\n       77  corte PIC 9 VALUE ZERO.\n       77  I PIC 99 VALUE ZERO.\n       77  J PIC 99 VALUE ZERO.\n       77  K PIC 99 VALUE ZERO.\n\n       PROCEDURE DIVISION.\n       Operaciones-con-strings.\n\n      * Longitud de la cadena\n       DISPLAY FUNCTION LENGTH-AN(texto).\n       INSPECT texto TALLYING contador FOR CHARACTERS.\n       DISPLAY \"Tiene \" contador \" caracteres\".\n\n      * Contando cuantas veces se repite una letra\n       MOVE ZERO to contador.\n       INSPECT cadena TALLYING contador FOR ALL \"o\".\n       DISPLAY \"Tiene \" contador \" letras 'o'\".\n\n      * Contando cuantos hay antes del primer espacio\n       MOVE ZERO to contador.\n       INSPECT texto TALLYING contador FOR CHARACTERS BEFORE\n           INITIAL \" \".\n       DISPLAY \"Tiene \" contador \" letras antes del espacio\".\n\n      * Contando cuantos hay despues del primer espacio\n       MOVE ZERO to contador.\n       INSPECT texto TALLYING contador FOR CHARACTERS AFTER\n           INITIAL \" \".\n       DISPLAY \"Tiene \" contador \" letras despues del espacio\".\n\n      * Buscando una letra en la cadena\n       MOVE ZERO to contador.\n       INSPECT texto TALLYING contador FOR LEADING \"Hola\".\n       DISPLAY \"Tiene la cadena contiene 'Hola'? 0=no y 1=si: \"contador.\n\n      * Reemplaza todos los caracteres por otro\n       INSPECT texto REPLACING CHARACTERS BY \"*\".\n       DISPLAY texto.\n       MOVE \"Hola COBOL!\" to texto.\n\n      * Reemplaza todas las o por i\n       INSPECT cadena REPLACING ALL \"o\" BY \"i\".\n       DISPLAY cadena.\n       MOVE \"Hola mundo!\" to cadena.\n\n      * Reemplaza la palabra Hola por Bye si esta antes del primer espacio\n       INSPECT cadena REPLACING ALL \"Hola\" BY \"Bye \" BEFORE INITIAL \" \".\n       DISPLAY cadena.\n       MOVE \"Hola mundo!\" to cadena.\n\n      * Cambiar todo a mayusculas\n       DISPLAY FUNCTION UPPER-CASE(cadena)\n\n      * Cambiar todo a minusculas\n       DISPLAY FUNCTION LOWER-CASE(cadena)\n\n      * Invertir una cadena\n       DISPLAY FUNCTION REVERSE(cadena)\n\n      * Mostrar el tercer caracter de la cadena\n       DISPLAY cadena(4:1)\n\n      * Division de cadenas\n       MOVE \"Juan-Jose-Pedro\" TO cadena.\n       UNSTRING cadena DELIMITED BY \"-\" INTO\n               palabra-1\n               palabra-2\n               palabra-3.\n       DISPLAY \"Se dividio la cadena '\" cadena \"' en estas plabras\".\n\n       DISPLAY palabra-1.\n       DISPLAY palabra-2.\n       DISPLAY palabra-3.\n\n      * Union de cadenas\n       STRING \"Nombre 1: \", palabra-1, \"Nombre 2: \", palabra-3\n           DELIMITED BY SIZE INTO concatenado.\n\n       DISPLAY concatenado.\n\n      * DIFICULTAD EXTRA\n       Comienzo.\n           PERFORM Toma-palabra.\n           MOVE palabra-3 TO palabra-1\n\n           PERFORM Toma-palabra.\n           MOVE palabra-3 TO palabra-2.\n\n           DISPLAY \"--- Palindromos ---\".\n           PERFORM Palindromos.\n\n           MOVE palabra-1 TO palabra-3.\n           DISPLAY \"--- Isogramas ---\".\n           PERFORM Isogramas.\n           IF corte = 1\n               DISPLAY \"La palabra \" palabra-1 \" NO es un isograma\"\n           ELSE\n               DISPLAY \"La palabra \" palabra-1 \" es un isograma\".\n\n           MOVE palabra-2 TO palabra-3.\n           PERFORM Isogramas.\n           IF corte = 1\n               DISPLAY \"La palabra \" palabra-2 \" NO es un isograma\"\n           ELSE\n               DISPLAY \"La palabra \" palabra-2 \" es un isograma\".\n\n           DISPLAY \"--- Anagramas ---\".\n           PERFORM Anagramas.\n\n\n           STOP RUN.\n\n       Toma-palabra.\n           DISPLAY \"Ingrese una palabra (sin acentos)\"\n           ACCEPT palabra-3.\n           MOVE FUNCTION LOWER-CASE(palabra-3) TO palabra-3.\n\n           IF palabra-3 is NOT a-z\n               DISPLAY \"El dato ingresado es erroneo\"\n               PERFORM Toma-palabra.\n\n      * Palabras que se leen igual al derecho y al reves\n       Palindromos.\n           MOVE FUNCTION REVERSE(palabra-1) TO palabra-3.\n           IF FUNCTION TRIM(palabra-1) = FUNCTION TRIM(palabra-3)\n               DISPLAY \"La palabra \" palabra-1 \" es un palindromo\"\n           ELSE\n               DISPLAY \"La palabra \" palabra-1 \" NO es un palindromo\".\n\n           MOVE FUNCTION REVERSE(palabra-2) TO palabra-3.\n           IF FUNCTION TRIM(palabra-2) = FUNCTION TRIM(palabra-3)\n               DISPLAY \"La palabra \" palabra-2 \" es un palindromo\"\n           ELSE\n               DISPLAY \"La palabra \" palabra-2 \" NO es un palindromo\".\n\n      * Isograma tienen todas las letras distintas\n       Isogramas.\n           MOVE ZERO TO corte.\n           MOVE ZERO TO largo.\n           INSPECT palabra-3 TALLYING largo FOR CHARACTERS\n                   BEFORE INITIAL \" \".\n           PERFORM Vuelta-1 VARYING I FROM 1 BY 1 UNTIL I = largo.\n\n       Vuelta-1.\n           COMPUTE K = I + 1\n           PERFORM Vuelta-2 VARYING J FROM K BY 1 UNTIL J > largo.\n\n       Vuelta-2.\n           IF palabra-3(I:1) = palabra-3(J:1)\n               MOVE 1 TO corte.\n\n      * Anagrama palabras distintas con las mismas letras\n       Anagramas.\n           MOVE ZERO TO largo.\n           MOVE ZERO TO largo2.\n\n           INSPECT palabra-1 TALLYING largo FOR CHARACTERS\n                   BEFORE INITIAL \" \".\n           INSPECT palabra-2 TALLYING largo2 FOR CHARACTERS\n                   BEFORE INITIAL \" \".\n\n           MOVE ZERO TO corte.\n\n           IF largo = largo2\n               PERFORM Recorre VARYING I FROM 1 BY 1 UNTIL I > largo.\n           IF corte = 0\n               DISPLAY \"La palabra \" palabra-1\n                   \"es un anagrama de la palabra \" palabra-2\n           ELSE\n               DISPLAY \"La palabra \" palabra-1\n                   \"NO es un anagrama de la palabra \" palabra-2.\n\n       Recorre.\n           MOVE ZERO TO J.\n           MOVE ZERO TO K.\n           INSPECT palabra-1 TALLYING J FOR ALL palabra-1(I:1).\n           INSPECT palabra-2 TALLYING K FOR ALL palabra-1(I:1).\n           IF J NOT = K\n               MOVE 1 TO corte.\n\n       END PROGRAM RETO-04.\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/dart/D3rk1us.dart",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n */\n\nvoid main() {\n\n  String cadena1 = 'Cadena con comillas simples.';\n  String cadena2 = \"Cadena con comillas dobles.\";\n  String cadena3 = '''\n  Cadena\n  multilinea \n  de tres comillas simples''';\n\n  print(cadena1);\n  print(cadena2);\n  print(cadena3);\n\n  // Subcadenas\n  print(cadena1.substring(0, 10));\n\n  // Longitud\n  print(cadena2.length);\n\n  // Concatenación\n  print(\"Concatenación: \" + cadena2); \n\n  // Repetición\n  for (int i = 0; i <= 2; i++) {\n    print('Repetición');\n  }\n\n  // Recorrido\n  for (var c = 0; c < cadena2.length; c++) {\n    print(cadena2[c]);\n  }\n  \n  // Conversión a mayúsculas y minúsculas\n  print(cadena1.toUpperCase());\n  print(cadena3.toLowerCase());\n\n  // Reemplazo\n  print(cadena2.replaceAll('Cadena', 'Ejemplo'));\n\n  // División\n  print(cadena1.split(' '));\n\n  // Unión\n  print(cadena1.split(' ').join('-'));\n\n  // Interpolación\n  print(\"Esto es una $cadena2\");\n\n  // Verificación\n  print(cadena1 == cadena2);\n  print(cadena1.compareTo(cadena3));\n\n  /*\n  * DIFICULTAD EXTRA (opcional):\n  * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n  * para descubrir si son:\n  * - Palíndromos\n  * - Anagramas\n  * - Isogramas\n  */\n\n  String palabra1 = 'ana';\n  String palabra2 = 'amor';\n\n  print('$palabra1: ${palindromo(palabra1)}');\n  print('$palabra2: ${palindromo(palabra2)}');\n\n  print('$palabra1 y $palabra2: ${anagrama(palabra1, palabra2)}');\n\n  print('$palabra1: ${isograma(palabra1)}');\n  print('$palabra2: ${isograma(palabra2)}');\n\n}\n\nString palindromo(String palabra) {\n  \n  var palPalabra = palabra.split('').reversed.join();\n  \n  if (palabra == palPalabra) {\n    return 'Es un palíndromo';\n  } else {\n    return 'No es palíndromo';\n  }\n}\n\nString anagrama(String palabra1, String palabra2) {\n  \n  var anPalabra1 = palabra1.split('');\n  anPalabra1.sort();\n  \n  var anPalabra2 = palabra2.split('');\n  anPalabra2.sort();\n \n  if (anPalabra1.join() == anPalabra2.join()) {\n    return 'Son anagramas.';\n  } else {\n    return 'No son anagramas.';\n  }\n}\n\nString isograma(String palabra) {\n  int count = 0;\n  var comprobar = palabra.split('');\n\n  for (int i = 0; i < comprobar.length; i++) {\n\n    for (var caracter in comprobar) {\n      if (caracter == palabra[i]) {\n        count += 1;\n        if (count == 2) {\n          return 'No es Isograma';\n        }\n      }\n    }\n    count = 0;\n  }\n  return 'Es un Isograma.';\n}"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/dart/bluefeatherdev.dart",
    "content": "/*\n* EJERCICIO:\n* Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n* en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n* - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n*   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n*\n* DIFICULTAD EXTRA (opcional):\n* Crea un programa que analice dos palabras diferentes y realice comprobaciones\n* para descubrir si son:\n* - Palíndromos\n* - Anagramas\n* - Isogramas\n*/\n\n/// [DIFICULTAD EXTRA]:\nvoid checkTwoWords(String word1, String word2) {\n  /// Analizar si son [palíndromos] individualmente:\n  var reversedWord1 = word1.split('').reversed.join();\n  var reversedWord2 = word2.split('').reversed.join();\n  print('¿\"$word1\" es palíndrome? : ${word1 == reversedWord1}');\n  print('¿\"$word2\" es palíndrome? : ${word2 == reversedWord2}');\n\n  /// Analizar si son [anagramas] entre sí:\n  dynamic charsWord1 = word1.split('')..sort();\n  dynamic charsWord2 = word2.split('')..sort();\n  charsWord1 = charsWord1.join();\n  charsWord2 = charsWord2.join();\n  print('¿\"$word1\" y \"$word2\" son anagramas? : ${charsWord1 == charsWord2}');\n\n  /// Analizar si son [isogramas] individualmente:\n  bool isIsogram(String word) {\n    bool isIsogramWord = true;\n    Set setWord = word.split('').toSet();\n    List listWord = setWord.toList();\n    for (var char in listWord) {\n      var countChar = RegExp(char).allMatches(word).length;\n      if (countChar > 1) { \n        isIsogramWord = false;\n        break;\n      }\n    }\n    return isIsogramWord;\n  }\n  print('¿\"$word1\" es un isograma? : ${isIsogram(word1)}');\n  print('¿\"$word2\" es un isograma? : ${isIsogram(word2)}');\n}\n\nvoid main() {\n  /// Cadenas de ejemplo para operaciones:\n  String myString = 'Hello, Dart!';\n  String text1 = 'Blue';\n  String text2 = 'Feather';\n  String text3 = 'Banana';\n  String text4 = '  Hello  ';\n  \n  /// 1. [Concatenación]:\n  print(text1 + ' ' + text2);             // Blue Feather\n  print('Blue' ' ' 'Feather');            // Blue Feather\n\n  /// 2. [Repetición]:\n  print(text1 * 2);                       // BlueBlue\n  print(text2 * 3);                       // FeatherFeatherFeather\n\n  /// 3. [Indexación]:\n  print(text1[0]);                        // B\n  print(text1[1]);                        // l\n  print(text1[2]);                        // u\n  print(text1[3]);                        // e\n  print(text1[text1.length - 1]);         // e\n\n  /// 4. [Longitud]:\n  print(text1.length);                    // 4\n\n  /// 5. [Slicing]:\n  print(myString.substring(0, 5));        // Hello\n  print(myString.substring(7, 11));       // Dart\n\n  /// 6. [Búsqueda]:\n  print(myString.contains('Dart'));       // true\n\n  /// 7. [Reemplazo]:\n  print(text3.replaceAll('a', 'e'));      // Benene\n  print(text3.replaceAllMapped('a', \n    (w) => 'e'                            // Benene\n  ));  \n  print(text3.replaceFirst('a', 'e'));    // Benana\n  print(text3.replaceFirstMapped('a', \n    (w) => 'e'                            // Benana\n  ));  \n  print(text3.replaceRange(0, 2, 'Le'));  // Lenana\n\n  /// 8. [División]:\n  print(myString.split(', '));            // [Hello, Dart!]\n\n  /// 9. [Mayúsculas y minúsculas]:\n  print(myString.toLowerCase());          // hello, dart!\n  print(myString.toUpperCase());          // HELLO, DART!\n\n  /// 10. [Eliminar espacio en extremos]:\n  print(text4.trim());                    // hello\n  print(text4.trimLeft());                // hello  \n  print(text4.trimRight());               //   hello  \n\n  /// 11. [Búsqueda al principio y al final]:\n  print(text1.startsWith('B'));           // true\n  print(text1.startsWith('b'));           // false\n  print(text1.endsWith('e'));             // true\n  print(text1.endsWith('E'));             // false\n\n  /// 12. [Búsqueda de posición]:\n  print(text1.indexOf('u'));              // 2\n  print(myString.indexOf('Dart'));        // 7\n\n  /// 13. [Búsqueda de ocurrencias]:\n  final countA \n    = RegExp('a').allMatches(text3).length;\n  print(countA);                          // 3\n\n  /// 14. [Interpolación]:\n  print('text1: ${text1}');               // text1: Blue\n  print('text2: ${text2}');               // text2: Feather\n  print('text3: ${text3}');               // text3: Banana\n\n  /// 15. [Lista de caracteres]:\n  print(text1.split(''));                 // [B, l, u, e]\n  print(text2.split(''));                 // [F, e, a, t, h, e, r]\n  print(text3.split(''));                 // [B, a, n, a, n, a]\n\n  /// 16. [Lista de cadenas a cadena]:\n  List<String> list = [text1, ' ', text2];\n  print(list.join());                     // Blue Feather\n\n  /// 17. [Cadenas a tipos numéricos]:\n  print(int.parse('23'));                 // 23\n  print(double.parse('1.6180'));          // 1.818\n  print(num.parse('23'));                 // 23\n  print(num.parse('1.6180'));             // 1.818\n\n  /// 18. Otros métodos: `.allMatches()`:\n  var exp = RegExp(r'a');\n  var found = exp.allMatches(text3);\n  for (var match in found) {\n    print('Match \"${match.group(0)}\" en posición ${match.start}');\n  }\n\n  /// 19. Otros métodos: `.codeUnitAt()`:\n  print(text1.codeUnitAt(0));             // 66              \n  print(text1.codeUnitAt(1));             // 108    \n  print(text1.codeUnitAt(2));             // 117\n  print(text1.codeUnitAt(3));             // 101\n\n  /// 20. Otros métodos: `.compareTo()`:\n  print(text1.compareTo(text1));          // 0\n  print(text1.compareTo(text2));          // -1\n  print(text1.compareTo(text3));          // 1 \n\n  /// 21. Otros métodos: `.lastIndexOf()`:\n  print(text3.lastIndexOf('a'));          // 5\n\n  /// 22. Otros métodos: `.matchAsPrefix()`:\n  var regExp = RegExp(r'Dart');\n  var match = regExp.matchAsPrefix(myString, 7);\n  print(match);                           // Match found\n\n  /// 23. Otros métodos: `.padLeft()`:\n  print(myString.padLeft(16, '+'));       // ++++Hello, Dart!\n\n  /// 24. Otros métodos: `.padRight()`:\n  print(myString.padRight(16, '+'));      // Hello, Dart!++++\n  \n  /// 25. Otros métodos: `.splitMapJoin()`:\n  print(text4.splitMapJoin(RegExp(r'Hello'),\n    onMatch: (m) => '${m[0]}',\n    onNonMatch: (n) => '*',\n  ));                                     // *Hello*\n\n  /// 25. Otros métodos: `.toString()`:\n  print(23.toString());                   // '23'\n\n  /// 26. [Getters de String]:\n  print(myString.codeUnits);              // [72, 101, 108, 108, 111, 44, 32, 68, 97, 114, 116, 33]\n  print(myString.hashCode);               // 181428680\n  print(myString.isEmpty);                // false\n  print(myString.isNotEmpty);             // true\n  print(myString.length);                 // 12\n  print(myString.runes);                  // (72, 101, 108, 108, 111, 44, 32, 68, 97, 114, 116, 33)\n  print(myString.runtimeType);            // String\n\n  /// 27. Operador `*` en String:\n  print('Hello' * 2);                     // HelloHello\n\n  /// 28. Operador `+` en String:\n  print('Hello' + ' ' + 'Dart');          // Hello Dart\n\n  /// 29. Operador `==` en String:\n  print('Flutter' == 'React');            // False\n\n  /// 30. Operador `!=` en String:\n  print('Flutter' != 'React');            // True\n\n  /// 31. Operador `[]` en String:\n  print('Hello'[1]);                      // e\n\n  /// [DIFICULTAD EXTRA]:\n  checkTwoWords('ana', 'john');           // ejemplo para palíndromes\n  checkTwoWords('amor', 'roma');          // ejemplo para anagramas\n  checkTwoWords('hola', 'hello');         // ejemplo para isogramas\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/dart/marinaortells.dart",
    "content": "/// URL del sitio web oficial: https://dart.dev/\n\nimport 'dart:io';\n\nvoid main() {\n\n  var dart = 'dart'; // Declaración de strings/cadena de caracterses\n  var python = 'PYTHON';\n  var python2 = 'python';\n  var frase = '         Me gusta programar en dart     ';\n  var multilinea = ''' Esto es un\n  texto multilínea. \n  ¿Cómo estás? \n  ''';\n  var mensaje = 'Hola, me llamo Marina';\n\n\n  print('$dart + \" \" + $python'); // Concatenación de strings \n  /// Se interpola con ${}\n  print(dart.toUpperCase()); // Convertir a mayúsculas\n  print(python.toLowerCase()); // Convertir a minúsculas\n  print(frase.trim()); // ELimina los espacios en blanco\n  print(frase.startsWith('Me')); // Verificar si comienza con esa cadena\n  print(frase.contains(\"programar\")); // Verifica si contiene esa cadena\n  print(dart == python); // Verificar si las dos cadenas son iguales\n  print(python2.length); // Longitud de una candena\n  print(mensaje.replaceAll(\"Marina\", \"María\"));\n\n  List<String> char = mensaje.split(''); // División de un string\n  /// Esto es una forma de recorrer\n  for (var caracteres in char) { // .runes lo divide en caracteres\n    print(caracteres);\n  }\n  /// Otra forma de recorrer pero devuelve en Unicode\n  for(var char in mensaje.runes) {\n    print(char);\n  }\n\n  init();\n\n}\n\n/// Dificultad extra\n\nvoid init() {\n  print(\"Introduce una palabra: \"); \n  var pal1 = (stdin.readLineSync())!.toLowerCase();\n  List<String> pal1Split = pal1!.split('').toList();\n  print(\"¿La palabra es isograma?: ${isograma(pal1Split)}\");\n  print(\"¿La palabra es un palíndromo?: ${palindromo(pal1Split)}\");\n  print(\"¿Las palabras son anagramas?: ${anagramas(pal1Split)}\");\n}\n\nbool? isograma(List<String> palabra) {\n  /// Isograma: Una frase/palabra donde no hay letras repetidas\n  for (int i = 0; i < palabra.length - 1; i++) {\n    for (int j = i + 1; j < palabra.length; j++) {\n      if (palabra[i] == palabra[j]) {\n        return false;\n      }\n    } \n  } return true;\n}\n\nbool? palindromo(List<String> palabra) {\nif (palabra.join() == palabra.reversed.join()) {\n  return true;\n} else { return false; }\n}\n\nbool? anagramas(List<String> palabra1) {\n  print(\"Introduce otra palabra: \"); \n  var palabra2 = stdin.readLineSync();\n  List<String> palabra2Split = palabra2!.split('').toList();\n  \n  if (palabra1.length != palabra2Split.length) {\n    return false;\n  }\n\n  for (int i = 0; i < palabra1.length; i++) {\n    if (!palabra2Split.contains(palabra1[i])) {\n      return false;\n    }\n  }\n\n  for (int j = 0; j < palabra2Split.length; j++) {\n    if (!palabra1.contains(palabra2Split[j])) {\n      return false;\n    }\n  }\n\n  return true;\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/dart/raulfauli.dart",
    "content": "/// #04 CADENAS DE CARACTERES\n\nvoid main() {\n  String cadena = \"Hola Mundo!\";\n\n  print('Primer caracter: ${cadena[0]}');\n\n  print('Subcadena: ${cadena.substring(0, 4)}');\n\n  print('Longitud: ${cadena.length}');\n\n  print('Eliminar espacios: ${cadena.trim()}');\n\n  print('Concatenación: ${cadena + \" \" + cadena}');\n\n  print('Repetición: ${cadena * 3}');\n\n  print('Recorrido: ${cadena.split(\"\").toList()}');\n\n  print('División: ${cadena.split(\" \")}');\n\n  print('Unión: ${cadena.split(\" \").join(\" - \")}');\n\n  print('Mayúsculas: ${cadena.toUpperCase()}');\n\n  print('Minúsculas: ${cadena.toLowerCase()}');\n\n  print('Reemplazo: ${cadena.replaceAll(\"o\", \"0\")}');\n\n  // Validaciones\n  print('Es vacío: ${cadena.isEmpty}');\n\n  print('Existe la letra \"o\": ${cadena.contains(\"o\")}');\n\n  print('Validar si es un número: ${cadena.contains(new RegExp(r'[0-9]'))}');\n\n  print('Empieza por \"Hola\": ${cadena.startsWith(\"Hola\")}');\n\n  print('Termina por \"Mundo!\": ${cadena.endsWith(\"Mundo!\")}');\n\n  print('Posición de la letra \"M\": ${cadena.indexOf(\"M\")}');\n\n  print('Posición de la última letra \"o\": ${cadena.lastIndexOf(\"o\")}');\n\n  print('Posición de un carácter que no existe: ${cadena.indexOf(\"x\")}'); // -1\n\n  var noAlphanumericIndex = cadena.indexOf(new RegExp(r'[^0-9a-z\\s]', caseSensitive: false));\n  print('Carácter no alfanumérico: ${cadena[noAlphanumericIndex]}');\n\n  var numero = \"123\";\n  print('Transformar a número: ${int.parse(numero)}');\n  print('Transformar a número: ${double.parse(numero)}');\n  // print('Transformar a número: ${int.parse(cadena)}'); // Error\n  print('Transformar a número: ${int.tryParse(cadena)}'); // null\n  print('Transformar a cadena: ${numero.toString()}');\n\n  // Extra\n  String palindrome = 'Logré ver gol.';\n  print('¿Es palíndromo \"$palindrome\"? ${isPalindrome(palindrome)}');\n\n  String word1 = 'Brasil';\n  String word2 = 'Silbar';\n  print('¿Son anagramas \"$word1\" y \"$word2\"? ${isAnagram(word1, word2)}');\n\n  String isogram = 'Centrifugadlos';\n  print('¿Es isograma \"$isogram\"? ${isIsogram(isogram)}');\n\n  String isogram2 = 'bebe';\n  print('¿Es isograma de segundo ordern \"$isogram2\"? ${isIsogram(isogram2)}');\n\n  print('Compruebo el caso contrario:');\n  print(isPalindrome('No palindromo'));\n  print(isAnagram('No', 'Anagrama'));\n  print(isIsogram('No isograma'));\n}\n\n// Reemplar carácteres no alfabéticos y acentos y pasar a minúsculas\nList<String> getCharList(String cadena) {\n  cadena = cadena.toLowerCase();\n  String accents = 'áéíóúü';\n  String noAccents = 'aeiouu';\n  for (int i = 0; i < accents.length; i++) {\n    cadena = cadena.replaceAll(accents[i], noAccents[i]);\n  }\n  cadena = cadena.replaceAll(new RegExp(r'[^a-z]'), '');\n\n  return cadena.split('').toList();\n}\n\nbool isPalindrome(String phrase) {\n  var characters = getCharList(phrase);\n\n  return characters.join() == characters.reversed.join();\n}\n\nbool isAnagram(String word1, String word2) {\n  var characters1 = getCharList(word1);\n  var characters2 = getCharList(word2);\n\n  characters1.sort();\n  characters2.sort();\n\n  return characters1.join() == characters2.join();\n}\n\nbool isIsogram(String word) {\n  List<String> characters = getCharList(word);\n  Map<String, int> charactersCount = {};\n  for (var character in characters) {\n    charactersCount[character] = (charactersCount[character] ?? 0) + 1;\n  }\n\n  var firstCount = charactersCount.values.first;\n\n  return charactersCount.values.every((count) => count == firstCount);\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/dart/teren91.dart",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\n *   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\n *   interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\n\nvoid main()\n{\n  //NOTA IMPORTANTE: En Dart, las cadenas de caracteres se pueden definir con comillas simples o dobles\n  //                y se pueden usar indistintamente. En este ejemplo se usan comillas dobles.\n\n  // Hay multitud de operaciones que se pueden realizar con cadenas de caracteres.\n  // A continuación se muestran algunos ejemplos de las más comunes:\n\n  String cadena = \"Hola Mundo\";\n  \n  // Substring -> devuelve una subcadena de la cadena original\n  // indexOf -> devuelve la posición de la primera ocurrencia de un carácter\n  print('Operación - Substring + indexOf: ${cadena.substring(0, cadena.indexOf(' '))}'); // Hola\n\n  // length -> devuelve la longitud de la cadena\n  print('Operación - length:  ${cadena.length}'); // 10\n  \n  // toUpperCase -> devuelve la cadena en mayúsculas\n  print('Operación - toUpperCase: ${cadena.toUpperCase()}'); // HOLA MUNDO\n\n  // toLowerCase -> devuelve la cadena en minúsculas\n  print('Operación - toLowerCase: ${cadena.toLowerCase()}'); // hola mundo\n\n  // replaceAll -> devuelve la cadena reemplazando todas las ocurrencias de un carácter por otro\n  print('Operación - replaceAll: ${cadena.replaceAll('o', '0')}'); // H0la Mund0\n\n  // replaceRange -> devuelve la cadena reemplazando los caracteres entre dos posiciones\n  print('Operación - replaceRange: ${cadena.replaceRange(0, 4, 'Adios')}'); // Adios Mundo\n\n  // replaceFirst -> devuelve la cadena reemplazando la primera ocurrencia de un carácter\n  print('Operación - replaceFirst: ${cadena.replaceFirst('o', '0')}'); // H0la Mundo\n\n\n  // split -> devuelve una lista de cadenas separadas por un carácter\n  print('Operación - split: ${cadena.split(' ')}'); // [Hola, Mundo]\n\n  // trim -> devuelve la cadena sin espacios al principio ni al final\n  print('Operación - trim: ${cadena.trim()}'); // Hola Mundo\n\n  // trimLeft -> devuelve la cadena sin espacios al principio\n  print('Operación - trimLeft: ${cadena.trimLeft()}'); // Hola Mundo\n\n  // trimRight -> devuelve la cadena sin espacios al final\n  print('Operación - trimRight: ${cadena.trimRight()}'); // Hola Mundo\n\n  // contains -> devuelve true si la cadena contiene un carácter o una subcadena\n  print('Operación - contains(Hola): ${cadena.contains('Hola')}'); // true\n  print('Operación - contains(M): ${cadena.contains('M')}'); // true\n  print('Operación - contains(X): ${cadena.contains('X')}'); // true\n\n  // startsWith -> devuelve true si la cadena empieza por un carácter o una subcadena\n  print('Operación - startsWith(Hola): ${cadena.startsWith('Hola')}'); // true\n\n  // endsWith -> devuelve true si la cadena termina por un carácter o una subcadena\n  print('Operación - endsWith(do): ${cadena.endsWith('do')}'); // true\n\n  // compareTo -> devuelve un número negativo si la cadena es menor que otra, 0 si son iguales\n  // o un número positivo si la cadena es mayor que otra\n  print('Operación - compareTo: ${cadena.compareTo('Hola Mundo')}'); // 0\n  print('Operación - compareTo: ${cadena.compareTo('Hola Mundo!')}'); // -1\n  print('Operación - compareTo: ${cadena.compareTo('H')}'); // 1\n\n  // codeUnitAt -> devuelve el código Unicode de un carácter en una posición determinada\n  print('Operación - codeUnitAt: ${cadena.codeUnitAt(0)}'); // 72\n\n  // join -> devuelve una cadena uniendo los elementos de una lista\n  List<String> lista = ['Hola', 'Mundo'];\n  print('Operación - join: ${lista.join(' ')}'); // Hola Mundo\n\n  //EJERCICIO EXTRA\n\n  // Palíndromo\n  String palindromo = \"Dabale arroz a la zorra el abad\";\n  print('Es palíndromo \"$palindromo\": ${esPalindromo(palindromo)}'); // true \n\n  // Anagrama\n  String palabra1 = \"Mary\";\n  String palabra2 = \"Army\";\n  print('Es anagrama \"$palabra1\" y \"$palabra2\"?: ${esAnagrama(palabra1, palabra2)}'); // true\n\n  // Isograma\n  String isograma = \"Isograma\";\n  String isograma2 = \"Murcielago\";\n  print('Es isograma \"$isograma\": ${esIsograma(isograma)}'); // false\n  print('Es isograma \"$isograma2\": ${esIsograma(isograma2)}'); // true\n\n}\n\nbool esPalindromo(String cadena)\n{\n  //Limpiar espacios y convertir a minúsculas\n  String cadenaLimpia = cadena.toLowerCase().replaceAll(' ', '');\n  \n  //Invertir cadena: \n  //  1º - convertir a minúsculas \n  //  2º - eliminar espacios \n  //  3º - convertir a lista\n  //  4º - invertir lista \n  //  5º - convertir a cadena\n  String cadenaInvertida = cadena.toLowerCase().replaceAll(' ', '').split('').reversed.join();\n\n  if (cadenaLimpia == cadenaInvertida)\n    return true;\n\n  return false;\n}\n\nbool esAnagrama(String palabra1, String palabra2)\n{\n\n  //Convertir a minúsculas\n  palabra1 = palabra1.toLowerCase();\n  palabra2 = palabra2.toLowerCase();\n\n  //Ambas palabras deben tener la misma longitud\n  if (palabra1.length != palabra2.length)\n    return false;\n\n  // Todas las letras de la palabra1 deben estar en la palabra2\n  for (int i = 0; i < palabra1.length; i++)\n  {\n    if (!palabra2.contains(palabra1[i]))\n      return false;\n  }\n\n  // Todas las letras de la palabra2 deben estar en la palabra1\n  for (int i = 0; i < palabra2.length; i++)\n  {\n    if (!palabra1.contains(palabra2[i]))\n      return false;\n  }  \n\n  return true;\n}\n\nbool esIsograma(String cadena)\n{\n  //Convertir a minúsculas\n  cadena = cadena.toLowerCase();\n\n  //Recorrer la cadena\n  for (int i = 0; i < cadena.length; i++)\n  {\n    //Si la cadena contiene más de una ocurrencia de un carácter, no es isograma\n    if (cadena.indexOf(cadena[i]) != cadena.lastIndexOf(cadena[i]))\n      return false;\n  }\n\n  return true;\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/delphi/fduron.dpr",
    "content": "(*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podran ser (busca todas las que puedas):\n * - Acceso a caracteres especficos, subcadenas, longitud, concatenacin, repeticin,\n *   recorrido, conversin a maysculas y minsculas, reemplazo, divisin, unin,\n *   interpolacin, verificacin...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palndromos\n * - Anagramas\n * - Isogramas\n *)\n\nprogram fduron;\n\n{$APPTYPE CONSOLE}\n\n{$R *.res}\n\nuses\n  System.SysUtils;\n\n//Palabras o frases que se leen igual al derecho y al reves\nfunction EsPalindromo(const Palabra1, Palabra2: String): Boolean;\nbegin\n  Result := True;\n  var P := Palabra1 + Palabra2;\n  P := P.Replace(' ', '').ToUpper; //Eliminar los espacios\n  var Centro := P.Length div 2;\n  for var C := 1 to Centro do\n    if P[C] <> P[P.Length - C + 1] then\n      Exit(False);\nend;\n\n//Palabra o frase formada a partir de una primera palabra o frase\nfunction EsAnagrama(const Palabra1, Palabra2: String): Boolean;\nvar\n  Idx: Integer;\nbegin\n  Result := True;\n  var P1 := Palabra1.Replace(' ', '').ToUpper; //Eliminar los espacios\n  var P2 := Palabra2.Replace(' ', '').ToUpper; //Eliminar los espacios\n\n  if (P1.Length <> P2.Length) or (P1.Equals(P2)) then\n    Exit(False);\n\n  for var C := 1 to P1.Length do\n  begin\n    Idx := P2.IndexOf(P1[C]);\n    P2 := P2.Remove(Idx, 1);\n  end;\n\n  Result := P2.IsEmpty;\nend;\n\n//Palabras o frases donde no se repite ninguna letra\nfunction EsIsograma(const Palabra: String): Boolean;\nvar\n  Idx: Integer;\nbegin\n  Result := True;\n  var P1 := Palabra.Replace(' ', '').ToUpper; //Eliminar los espacios\n\n  for var C := 1 to P1.Length do\n    if P1.CountChar(P1[C]) > 1 then\n      Exit(False);\nend;\n\nprocedure DificultadExtra;\n\n  procedure EvaluarPalabras(const Palabra1, Palabra2: String);\n  begin\n    if EsPalindromo(Palabra1, Palabra2) then\n      WriteLn('>>Las palabras forman un palndromo')\n    else\n      WriteLn('>>Las palabras NO forman un palndromo');\n\n    if EsAnagrama(Palabra1, Palabra2) then\n      WriteLn('>>Las palabras forman un anagrama')\n    else\n      WriteLn('>>Las palabras NO forman un anagrama');\n\n    if EsIsograma(Palabra1) then\n      WriteLn('>>La primera palabra es un isograma')\n    else\n      WriteLn('>>La primera palabra NO es un isograma');\n\n    if EsIsograma(Palabra2) then\n      WriteLn('>>La primera palabra es un isograma')\n    else\n      WriteLn('>>La primera palabra NO es un isograma');\n  end;\n\nvar\n  PrimeraPalabra: String;\n  SegundaPalabra: String;\n  Continua: Char;\nbegin\n  WriteLn;\n  WriteLn('************************************************');\n  WriteLn(' DIFICULTAD EXTRA');\n  WriteLn(' Escribe dos palabras o frases para analizarlas');\n  WriteLn('************************************************');\n  WriteLn;\n  repeat\n    Write('Escribe la primera palabra o frase: ');\n    ReadLn(PrimeraPalabra);\n    Write('Escribe la segunda palabra o frase: ');\n    ReadLn(SegundaPalabra);\n\n    EvaluarPalabras(PrimeraPalabra, SegundaPalabra);\n\n    WriteLn;\n    Write('Deseas intentar otra vez? (S/N): ');\n    ReadLn(Continua);\n  until UpperCase(Continua) = 'N';\nend;\n\nvar\n  Cadena1, Cadena2, Cad1EntreComillas: String;\n  Resultado: Integer;\nbegin\n  Cadena1 := 'Cadena A';\n  Cadena2 := 'Cadena B';\n\n  //Existen varias versiones del mtodo Compare, a continuacin tres ejemplos:\n  //Comparar dos cadenas:\n  Resultado := String.Compare(Cadena1, Cadena2);\n  //Comparar un substring de 6 caracteres iniciando en la posicion 0:\n  Resultado := String.Compare(Cadena1, 0, Cadena2, 0, 6);\n  //Comparar utilizando la cadena inicial como base:\n  Resultado := Cadena1.CompareTo(Cadena2);\n  //Resultado ser < 0 cuando Cadena1 se encuentre antes de Cadena2\n  //Resultado ser = 0 cuando ambas cadenas sean iguales\n  //Resultado ser > 0 cuando Cadena1 se encuentre despus de Cadena2\n\n  if Resultado < 0 then\n    WriteLn(Cadena1 , ' se ordena antes de ', Cadena2)\n  else\n  if Resultado > 0 then\n    WriteLn(Cadena1, ' se ordena despus de ', Cadena2)\n  else\n    WriteLn(Cadena1, ' y ', Cadena2, ' son iguales');\n\n  Cad1EntreComillas := Cadena1.QuotedString('\"');\n  WriteLn(Cad1EntreComillas, ' en minusculas: ', Cadena1.ToLower);\n  WriteLn(Cad1EntreComillas, ' contiene ', Cadena1.CountChar('a'), ' letras \"a\" ');\n  WriteLn(Cad1EntreComillas, ' en Mayusculas: ', Cadena1.ToUpper);\n  WriteLn(Cad1EntreComillas, ' contiene \"ad\": ', Cadena1.Contains('ad'));\n  WriteLn(Cad1EntreComillas, ' sin comillas: ', Cad1EntreComillas.DeQuotedString('\"') );\n  WriteLn(Cad1EntreComillas, ' termina con \"A\": ', Cadena1.EndsWith('A'));\n  WriteLn(Cad1EntreComillas, ' inicia con \"Cad\": ', Cadena1.EndsWith('Cad'));\n  WriteLn(Cad1EntreComillas, ' posicin de \"A\": ', Cadena1.IndexOf('A') );\n  WriteLn(Cad1EntreComillas, ' posicin de \"A\", \"B\" o \"C\": ',\n    Cadena1.IndexOfAny(['A', 'B', 'C']) );\n  WriteLn(Cad1EntreComillas, ' en la posicin 0 es el delimitador \" : ',\n    Cad1EntreComillas.IsDelimiter('\"', 0) );\n  WriteLn(Cad1EntreComillas, ' est vacio: ', Cad1EntreComillas.IsEmpty);\n  //Cadena1.IsNullOrEmpty\n  //Cadena1.IsNullOrWhiteSpace\n  WriteLn(Cad1EntreComillas, ' uniendo cadenas separadas con | : ',\n    String.Join('|', [Cadena1, Cadena2, Cadena1])\n    );\n  WriteLn(Cad1EntreComillas, ' posicin del ltimo delimitador [\"]: ',\n    Cad1EntreComillas.LastDelimiter('\"')\n    );\n  WriteLn(Cad1EntreComillas, ' ltima posicin de \"na\": ',\n    Cad1EntreComillas.LastIndexOf('na')\n    );\n  WriteLn(Cad1EntreComillas, ' removiendo 2 caracteres texto a partir de la posicion 3: ',\n    Cad1EntreComillas.Remove(3, 2));\n  WriteLn(Cad1EntreComillas, ' En tamao 15, rellenando con # a la izquierda: ',\n    Cadena1.PadLeft(15, '#') );\n  WriteLn(Cad1EntreComillas, ' En tamao 15, rellenando con # a la derecha: ',\n    Cadena1.PadRight(15, '#') );\n  WriteLn(Cad1EntreComillas, ' reemplazando a por 4: ',  Cadena1.Replace('a', '4') );\n  WriteLn('Separando ', Cad1EntreComillas, ' en elementos delimitados por ''a'' :');\n  var Splits := Cadena1.Split(['a']);\n  for var Elemento in Splits do\n    WriteLn(Elemento);\n\n  WriteLn('Tamao de ', Cadena1, ': ', Cadena1.Length);\n\n  //Concatenacin\n  Cadena1 := '    ' + Cadena1 + Cadena2 + '    ';\n  WriteLn('Cadena1 ahora es: ', Cadena1.QuotedString);\n  WriteLn(Cadena1.QuotedString, ' sin espacios a la izquierda: ',\n    Cadena1.TrimLeft.QuotedString);\n  WriteLn(Cadena1.QuotedString, ' sin espacios a la derecha: ',\n    Cadena1.TrimRight.QuotedString );\n\n  DificultadExtra;\n\nend.\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/ejercicio.md",
    "content": "# #04 CADENAS DE CARACTERES\n> #### Dificultad: Media | Publicación: 22/01/24 | Corrección: 29/01/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/elixir/edalmava.exs",
    "content": "# Concatenación de cadenas\ncadena1 = \"Programando con\"\ncadena2 = \"Elixir\"\nIO.puts cadena1 <> \" \" <> cadena2\n\n# Interpolación de cadenas\nIO.puts \"#{cadena1} #{cadena2}\"\n\nIO.puts \"Cadena: \" <> cadena1\nIO.puts \"Longitud de la cadena: #{String.length(cadena1)}\"\n\n# Acceso a un caracter específico\nIO.puts \"Primer caracter de la cadena: #{String.at(cadena1, 0)}\"\n\n# Subcadenas\nIO.puts \"Primeros cinco caracteres: #{String.slice(cadena1, 0..4)}\" # slice(string, range)\nIO.puts \"Primeros cinco caracteres: #{String.slice(cadena1, 0, 5)}\" # slice(string, start, length)\n\n# Invertir una cadena\ncadena = \"anitalavalatina\"\nIO.puts String.reverse(cadena)\n\n# Repetir o duplicar una cadena\ncadena3 = \"*****\"\nIO.puts String.duplicate(cadena3, 5)\n\n# Buscar si la cadena tiene un contenido dado\nIO.puts \"La cadena contiene 'lava': #{String.contains?(cadena, \"lava\")}\"\n\n# División de una cadena en palabras\ncadena = \"Anita lava la tina\"\n[nombre | _resto] = String.split cadena\nIO.puts nombre\n\n# Dividir una cadena basada en un patrón\n[primero | _resto] = String.split(\"1,2,3,4,5\", \",\")\nIO.puts \"Primer Número: #{primero}\"\n\n# Reemplazar partes de una cadena\ncadena = \"Loro\"\nIO.puts String.replace(cadena, \"r\", \"c\")\n\n# cambiar a mayúscula\nIO.puts String.upcase cadena\n\n# Cambiar a minúscula\nIO.puts String.downcase cadena\n\n# RETO EXTRA\n\ndefmodule Grapheme do\n  def anagrams?(a, b) when is_binary(a) and is_binary(b) do\n    sort_string(a) == sort_string(b)\n  end\n\n  def sort_string(string) do\n    string\n    |> String.downcase()\n    |> String.graphemes()\n    |> Enum.sort()\n  end\n\n  def isograms?(string) do\n    string\n    |> String.downcase()\n    |> String.graphemes()\n    |> Enum.frequencies()\n    |> Enum.all?(fn {_k, v} -> v == 1 end)\n  end\nend\n\ncheck = fn (word1, word2) ->\n  word1 = word1 |> String.trim() |> String.downcase()\n  word2 = word2 |> String.trim() |> String.downcase()\n  IO.puts \"Palabra 1: #{word1} y Palabra 2: #{word2}\"\n  IO.puts \"Primera palabra es palindromo: #{String.reverse(word1) === word1}\"\n  IO.puts \"Segunda palabra es palindromo: #{String.reverse(word2) === word2}\"\n  IO.puts \"Las dos palabras son anagramas (solución 1): #{String.bag_distance(word1, word2) === 1.0}\"\n  IO.puts \"Las dos palabras son anagramas (solución 2): #{Grapheme.anagrams?(word1, word2)}\"\n  IO.puts \"La primera palabra es isograma: #{Grapheme.isograms?(word1)}\"\n  IO.puts \"La segunda palabra es isograma: #{Grapheme.isograms?(word2)}\"\n  IO.puts \"\"\nend\n\ncheck.(\"amor\", \"roma\")\ncheck.(\"radar\", \"anitalavalatina\")\ncheck.(\"python\", \"murciélago\")\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/fortran/LeandroCFD.f90",
    "content": "program CHARACTER\n    implicit none\n\n    integer :: n,n1,n2,n3=0,n4=0,i\n    character (len=30):: texto,texto1,texto2,texto5=\"\",texto6=\"\"\n    character (len=10):: texto3,texto4\n    character :: letra\n\n    texto1=\"Hola\"\n    texto2=\" DeviDec\"\n\n    !OPERACIONES CON CADENAS DE CARACTERES EN FORTRAN\n    !Concatenación\n    texto=trim(texto1)//trim(texto2) !trim elimina los espacios al final de la cadena\n    print*,texto\n\n    !Longitud\n    n=len(texto) !Longitud de la cadena \"texto\"\n    print*,\"La longitud de texto es: \",n\n    n=len_trim(texto) !Longitud de la cadena \"texto\" sin espacios en blanco\n    print*,\"La longitud de texto sin espacios en blanco es: \",n\n\n    !Partes de cadenas\n    texto=texto2(:4) !\"texto\" será lo que hay en la posición 1 hasta la 4 de la cadena \"texto2\"\n    print*,texto\n    texto=texto2(4:8) !\"texto\" será lo que hay en la posición 4 hasta la 8 de la cadena \"texto2\"\n    print*,texto\n\n    !Posición de cadena de caracteres\n    n=index(texto2,'Dec') !La función index busca la posición de la cadena \"Dec\" en la cadena \"texto2\"\n    print*,\"La posición de 'Dec' en texto2 es: \",n\n\n    !Posición de cualquier caracter dentro de una cadena\n    n=scan(texto2, 'Hijo') !La función scan busca la posición de cualquier caracter de la cadena \"Hijo\" en \"texto2\"\n    print*,\"La posición de algún caracter de 'Hijo' en texto2 es: \",n !En este caso la letra i de \"Hijo\" se encuentra en la \n    !posición 5 de la cadena \"texto2\"\n\n    !Conversión de tipos\n    write(texto,'(I10)') n !Convierte un número entero en una cadena\n    print*,texto\n    texto2=\"9\"\n    read(texto2,'(I1)') n !Convierte una cadena a número entero\n    print*,n\n\n    !Repetación\n    texto=repeat(trim(texto1),5)\n    print*,texto\n\n    !Reemplazo\n    texto(5:)=\" DeviDec\" !Se reemplazan los caracteres de \"texto\" desde la posición 5 hasta el final por \" DeviDec\"\n    print*,texto\n\n    !Verificación\n    n=verify(texto, \"Hola DeviFlow\") !La función devuelve la posición del primer carácter en \"texto\" que no está en \"Hola DeviFlow\"\n    print*,n !El unico caracter que esta en \"texto\" y que no esta en \"Hola DeviFlow\" es la c, que se encuentra en la posición 12\n\n    !Eliminación de espacios\n    texto1=\"                Hola\"\n    texto=adjustl(texto1) !La función adjustl elimina todos los espacios en blanco de la izquierda de la cadena\n    print*,texto1\n    print*,texto\n    texto3=\"Hola      \"\n    texto4=\" Devidec\"\n    texto=texto3//texto4\n    print*,\"Sin la función adjustr: \",texto\n    texto=adjustr(texto3)//texto4 !La función adjustr elimina todos los espacios en blanco de la derecha de la cadena\n    print*,\"Con la función adjustr: \",texto\n    texto=trim(texto3)//trim(texto4) !La función trim elimina todos los espacios en blanco de la cadena\n    print*,\"Con la función trim: \",texto\n\n    !DIFICULTAD EXTRA\n    print*,\"***********************************************************\"\n    print*,\"PROGRAMA DE DETECCIÓN DE PALÍNDROMOS, ANAGRAMAS Y ISOGRAMAS\"\n    print*,\"***********************************************************\"\n    print*,\"\"\n    print*,\"Ingrese la primera palabra en minusculas: \"\n    read*,texto1\n    print*,\"Ingrese la segunda palabra en minusculas: \"\n    read*,texto2\n    print*,\"\"\n    n1=len_trim(texto1) !Se determina la longitud de la cadena de texto\n    n2=len_trim(texto2)\n\n    do i=1,n1\n        texto5(i:i)=texto1(n1+1-i:n1+1-i) !Se escribe la cadena al reves\n        letra=texto1(i:i) !Se guarda una letra de texto1\n        n=scan(texto1(i+1:),letra) !Se revisa si la letra esta en otra parte de la cadena\n        if (n/=0) then\n            n3=n3+1  !Si la palabra texto1 NO es un anagrama n3/=0                      \n        end if\n    end do\n    do i=1,n2\n        texto6(i:i)=texto2(n2+1-i:n2+1-i) !Se realiza lo mismo para la cadena texto2\n        letra=texto2(i:i)\n        n=scan(texto2(i+1:),letra)\n        if (n/=0) then\n            n4=n4+1                        \n        end if\n    end do\n\n    !PALÍNDROMO\n    if (texto5==texto1 .and. texto6==texto2) then\n        print*,trim(texto1),\": Es un palíndromo\"\n        print*,trim(texto2),\": Es un palíndromo\"\n    else if (texto5==texto1) then\n        print*,trim(texto1),\": Es un palíndromo\"\n        print*,trim(texto2),\": No es un palíndromo\"\n    else if (texto6==texto2) then\n        print*,trim(texto1),\": No es un palíndromo\"\n        print*,trim(texto2),\": Es un palíndromo\"\n    else\n        print*,trim(texto1),\": No es un palíndromo\"\n        print*,trim(texto2),\": No es un palíndromo\"\n    end if\n\n    !ANAGRAMA\n    n=verify(texto1,texto2) !Se verifica si existe un caracter diferente entre texto1 y texto2\n\n    if (n==0) then\n        print*,trim(texto1),\": es un anagrama de \",trim(texto2)\n    else \n        print*,trim(texto1),\": No es un anagrama de \",trim(texto2)        \n    end if\n\n    !ISOGRAMA\n    if (n3==0 .and. n4==0) then\n        print*,trim(texto1),\": es un isograma\"\n        print*,trim(texto2),\": es un isograma\"\n    else if (n3==0) then\n        print*,trim(texto1),\": es un isograma\"\n        print*,trim(texto2),\": No es un isograma\"\n    else if (n4==0) then\n        print*,trim(texto1),\": No es un isograma\"\n        print*,trim(texto2),\": es un isograma\"\n    else \n        print*,trim(texto1),\": No es un isograma\" \n        print*,trim(texto2),\": No es un isograma\"         \n    end if\n  \nend program CHARACTER"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/go/AmadorQuispe.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"unicode\"\n)\n\nfunc main() {\n\tmessage := `Hola como estas`\n\totherMessage := \"amigo programador\"\n\t//# Concatenación\n\tfmt.Println(message + \", \" + otherMessage + \".\")\n\t//# Longitud de la cadena\n\tfmt.Println(\"Longitud de la cadena es :\", len(message))\n\t//# Repetición\n\tfmt.Println(strings.Repeat(message, 2))\n\t//# búsqueda\n\tfmt.Println(\"Empieza con 'Ho'?:\", strings.HasPrefix(message, \"Ho\"))\n\tfmt.Println(\"Termina con 'as'?:\", strings.HasSuffix(message, \"s\"))\n\tfmt.Println(\"Veces que se repite la letra 'o':\", strings.Count(message, \"o\"))\n\t//# conversión a mayúsculas y minúsculas\n\tfmt.Println(\"Conversión a mayúsculas:\", strings.ToUpper(message))\n\tfmt.Println(\"Conversión a minúsculas:\", strings.ToLower(message))\n\t//# reemplazo\n\tfmt.Println(\"Reemplazar 'r' por 'T':\", strings.ReplaceAll(otherMessage, \"r\", \"T\"))\n\t//# división\n\tfmt.Println(\"Dividir por espacio :\", strings.Split(message, \" \"))\n\t//# unión\n\tsplitString := strings.Fields(message)\n\tfmt.Println(\"Unir palabras de \", splitString, \" :\", strings.Join(splitString, \" \"))\n\t//# verificación\n\tfmt.Println(\"Contiene 'mo'?:\", strings.Contains(message, \"mo\"))\n\t//# interpolación\n\tfmt.Printf(\"Mensaje :%s\\n\", message)\n\t//# Acceso a carácter por el indice\n\tfmt.Printf(\"Carácter en el indice 3 de %s : es '%s'\\n\", message, string(message[3]))\n\t//# sub cadenas\n\tfmt.Println(\"sub cadena :\", message[1:4])\n\tresult := isPalindrome(\"radar\")\n\tfmt.Println(result)\n\t//# EXTRA\n\t//Palindrome, si al revertir se lee lo mismo\n\tfmt.Printf(\"¿'radar' es palindrome? : %v \\n\", isPalindrome(\"radar\"))\n\tfmt.Printf(\"¿'hola' es palindrome? : %v \\n\", isPalindrome(\"hola\"))\n\t//Anagrama, si ambas tienen las mismas letras\n\tfmt.Printf(\"¿'roma' y 'amor' son anagramas ? :%v\\n\", isAnagram(\"roma\", \"amor\"))\n\t//Isograma, palabra o frase en la que cada letra aparece el mismo número de veces Vivienne\n\tfmt.Printf(\"¿'escritura' es Isograma ? :%v\\n\", isIsogram(\"escritura\"))\n\tfmt.Printf(\"¿'Dermatoglyphics' es Isograma ? :%v\\n\", isIsogram(\"Dermatoglyphics\"))\n\tfmt.Printf(\"¿'vivienne ss' es Isograma ? :%v\\n\", isIsogram(\"vivienne ss\"))\n}\n\nfunc isPalindrome(s string) bool {\n\tif len(s) <= 1 {\n\t\treturn true\n\t}\n\tiLeft := 0\n\tiRight := len(s) - 1\n\n\tfor iLeft < iRight {\n\t\tif s[iLeft] != s[iRight] {\n\t\t\treturn false\n\t\t}\n\t\tiLeft++\n\t\tiRight--\n\t}\n\n\treturn true\n}\nfunc isAnagram(s1, s2 string) bool {\n\tif len(s1) != len(s2) {\n\t\treturn len(s1) != len(s2)\n\t}\n\tcharCount := make(map[int32]int)\n\tfor _, char := range s1 {\n\t\tcharCount[char]++\n\t}\n\tfor _, char := range s2 {\n\t\tcharCount[char]--\n\t\tif charCount[char] < 0 {\n\t\t\treturn false\n\t\t}\n\t}\n\tfor _, count := range charCount {\n\t\tif count != 0 {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc isIsogram(s string) bool {\n\tif len(s) <= 2 {\n\t\treturn true\n\t}\n\n\tcharCount := make(map[rune]int)\n\tfor _, char := range s {\n\t\tif !unicode.IsLetter(char) {\n\t\t\tcontinue\n\t\t}\n\t\tcharCount[char]++\n\t}\n\tvar lenIsogram int\n\tfor _, v := range charCount {\n\t\tlenIsogram = v\n\t\tbreak\n\t}\n\tfor _, v := range charCount {\n\t\tif lenIsogram != v {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/go/FreyFonseca117.go",
    "content": "// # #04 CADENAS DE CARACTERES\n// > #### Dificultad: Media | Publicación: 22/01/24 | Corrección: 29/01/24\n\n// ## Ejercicio\n\n// ```\n// /*\n//  * EJERCICIO:\n//  * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n//  * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n//  * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n//  *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n//  *\n//  * DIFICULTAD EXTRA (opcional):\n//  * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n//  * para descubrir si son:\n//  * - Palíndromos\n//  * - Anagramas\n//  * - Isogramas\n//  */\n// ```\n// #### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\n// Sigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n// > Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n\npackage main\n\nimport (\n\t\"fmt\"\n\t\"sort\"\n\t\"strings\"\n)\n\n// palindromo verifica si una palabra es un palíndromo.\nfunc palindromo(s string) bool {\n\ts = strings.ToLower(s)\n\trunes := []rune(s)\n\ti, j := 0, len(runes)-1\n\tfor i < j {\n\t\tif runes[i] != runes[j] {\n\t\t\treturn false\n\t\t}\n\t\ti++\n\t\tj--\n\t}\n\treturn true\n}\n\n// anagrama verifica si dos palabras son anagramas.\nfunc anagrama(a, b string) bool {\n\ta = strings.ReplaceAll(strings.ToLower(a), \" \", \"\")\n\tb = strings.ReplaceAll(strings.ToLower(b), \" \", \"\")\n\n\tif len(a) != len(b) {\n\t\treturn false\n\t}\n\taRunes := []rune(a)\n\tbRunes := []rune(b)\n\n\t// Ordenar los caracteres para comparar\n\tsort.Slice(aRunes, func(i, j int) bool { return aRunes[i] < aRunes[j] })\n\tsort.Slice(bRunes, func(i, j int) bool { return bRunes[i] < bRunes[j] })\n\n\treturn string(aRunes) == string(bRunes)\n}\n\n// isograma verifica si una palabra es un isograma (no tiene letras repetidas).\nfunc isograma(s string) bool {\n\ts = strings.ToLower(s)\n\tseen := make(map[rune]bool)\n\tfor _, r := range s {\n\t\tif r < 'a' || r > 'z' { // Ignorar caracteres que no sean letras\n\t\t\tcontinue\n\t\t}\n\t\tif seen[r] {\n\t\t\treturn false\n\t\t}\n\t\tseen[r] = true\n\t}\n\treturn true\n}\n\nfunc main() {\n\t// OPERACIONES CON CADENAS (STRINGS)\n\ts := \"Hello, GoLang!\"\n\n\tfmt.Println(\"=== OPERACIONES CON STRINGS ===\")\n\n\t// 1. Acceso a caracteres específicos\n\tfmt.Println(\"Primer carácter:\", string(s[0]))\n\n\t// 2. Subcadenas\n\tfmt.Println(\"Subcadena (índices 7 a 13):\", s[7:13])\n\n\t// 3. Longitud de la cadena\n\tfmt.Println(\"Longitud:\", len(s))\n\n\t// 4. Concatenación\n\ts2 := \" Welcome!\"\n\tfmt.Println(\"Concatenado:\", s+s2)\n\n\t// 5. Repetición\n\tfmt.Println(\"Repetido:\", strings.Repeat(\"Go! \", 3))\n\n\t// 6. Recorrido (iterar sobre cada carácter)\n\tfmt.Print(\"Recorrido: \")\n\tfor _, ch := range s {\n\t\tfmt.Printf(\"%c \", ch)\n\t}\n\tfmt.Println()\n\n\t// 7. Conversión a mayúsculas y minúsculas\n\tfmt.Println(\"Mayúsculas:\", strings.ToUpper(s))\n\tfmt.Println(\"Minúsculas:\", strings.ToLower(s))\n\n\t// 8. Reemplazo\n\tfmt.Println(\"Reemplazado:\", strings.Replace(s, \"GoLang\", \"Go\", 1))\n\n\t// 9. División y unión\n\tdividido := strings.Split(s, \" \")\n\tfmt.Println(\"Dividido:\", dividido)\n\tfmt.Println(\"Unido:\", strings.Join(dividido, \" | \"))\n\n\t// 10. Interpolación\n\tfmt.Println(\"Interpolado:\", fmt.Sprintf(\"La cadena '%s' tiene longitud %d.\", s, len(s)))\n\n\t// 11. Verificación de contenido\n\tfmt.Println(\"Contiene 'Go':\", strings.Contains(s, \"Go\"))\n\tfmt.Println(\"Empieza con 'Hello':\", strings.HasPrefix(s, \"Hello\"))\n\tfmt.Println(\"Termina con '!':\", strings.HasSuffix(s, \"!\"))\n\n\t// -------------------------------------------------------------------\n\t// DIFICULTAD EXTRA: Análisis de palabras (palíndromos, anagramas, isogramas)\n\tfmt.Println(\"\\n=== ANÁLISIS DE PALABRAS ===\")\n\n\t// Ejemplo para palíndromo\n\tword1, word2 := \"racecar\", \"hello\"\n\tfmt.Printf(\"'%s' es palíndromo? %v\\n\", word1, palindromo(word1))\n\tfmt.Printf(\"'%s' es palíndromo? %v\\n\", word2, palindromo(word2))\n\n\t// Ejemplo para anagramas\n\tword3, word4 := \"listen\", \"silent\"\n\tfmt.Printf(\"'%s' y '%s' son anagramas? %v\\n\", word3, word4, anagrama(word3, word4))\n\n\t// Ejemplo para isograma\n\tword5, word6 := \"machine\", \"programming\"\n\tfmt.Printf(\"'%s' es isograma? %v\\n\", word5, isograma(word5))\n\tfmt.Printf(\"'%s' es isograma? %v\\n\", word6, isograma(word6))\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/go/MiguelP-Dev.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n)\n\nfunc main() {\n\n\t// Declaracion de variables\n\tvar longString = \" Esto es una cadena de texto \"\n\tvar sayHi = \"Hello, World\"\n\tvar godev = \"https://go.dev\"\n\tvar numericString = \"1234567\"\n\tvar numbers = 567890\n\tvar runicString rune = 'a'\n\tvar lang = \"golang\"\n\n\t// Concatenación\n\tfmt.Println(\"Concatenación con paquetes: \", strings.Join([]string{\"Hola\", \"Golang!\"}, \", \"))\n\tfmt.Println(\"Concatenación con siḿbolo de suma: \", \"Hola \"+\"Mundo \"+\"de \"+\"Desarrolladores.\")\n\tfmt.Println(\"concatenación de variables\", sayHi+\" \"+\" \"+longString)\n\n\t// interpolación\n\tfmt.Printf(\"Esta es la página oficial del lenguaje %s: %s\\n\", lang, godev)\n\tinterpolacion := fmt.Sprintf(\"Esta es la página oficial del lenguaje %s: %s\", lang, godev)\n\tfmt.Println(interpolacion)\n\n\t// Búsqueda\n\tfmt.Println(\"Busca una palabra: \", strings.Contains(longString, \"una\"))\n\tfmt.Println(\"Busca algunos caracteres: \", strings.ContainsAny(longString, \"abc\"))\n\tfmt.Println(\"Busca un caracter unicode: \", strings.ContainsRune(longString, 'a'))\n\n\t// Reemplazo de una palabra\n\tfmt.Println(\"Reemplazo de palabra: \", strings.Replace(sayHi, \"World\", \"Golang\", 1))\n\n\t// Cuenta la cantidad de veces que una cadena aparece e otra\n\tfmt.Println(\"Cuenta las veces que aparece una cadena\", strings.Count(longString, \"a\"))\n\n\t// División de Cadena\n\tfmt.Println(\"Division de cadena(Slice): \", strings.Split(\"Hello-Gophers-of-world\", \"-\"))\n\n\t// Conversión a Mayúsculas\n\tfmt.Println(\"Conversión a mayúsculas: \", strings.ToUpper(sayHi))\n\n\t// Conversión a Minúsculas\n\tfmt.Println(\"Converión a minúsculas: \", strings.ToLower(longString))\n\n\t// Recorte de Espacios(Principio y fin de la cadena)\n\tfmt.Println(\"Recorte de espacios (Principio y Fin): \", strings.Trim(longString, \" \"))\n\n\t// Conversión de Rune a Cadena\n\tfmt.Println(\"Unicode a Cadena de texto: \", strconv.QuoteRuneToASCII(runicString))\n\tfmt.Println(\"Unicode a Cadena de texto: \", strconv.QuoteRune(runicString))\n\tfmt.Println(\"Unicode a Cadena de texto: \", strconv.QuoteRuneToGraphic(runicString))\n\n\t// Cálculo de Longitud\n\tfmt.Println(\"longitud de una cadena: \", len(longString))\n\n\t// Formateo de Cadenas: fmt Aplica formateo específico a cadenas, como sprintf.\n\tvalue := fmt.Sprintf(\"Tipo: %T Valor: %s Espacio de memoria: %v\\n \", longString, longString, &longString)\n\tfmt.Println(\"Formateo: \", value)\n\n\t// Verificación de Prefijo\n\tfmt.Println(\"Verificar prefijo(https://): \", strings.HasPrefix(godev, \"https://\"))\n\n\t// Verificación de Sufijo\n\tfmt.Println(\"Verificar sufijo(.dev): \", strings.HasSuffix(godev, \".dev\"))\n\n\t// Repetición de Cadena: strings Crea una nueva cadena repitiendo una existente un número específico de veces.\n\tfmt.Println(\"Repetición de cadenas: \", strings.Repeat(\"go \", 4))\n\n\t// Conversión de Cadena a Entero: strconv Convierte una cadena que representa un número en su valor entero.\n\tn, _ := strconv.Atoi(numericString)\n\tfmt.Printf(\"Conversión de cadena a entero: Tipo: %T Valor: %d\\n\", n, n)\n\n\t// Conversión de Entero a Cadena: strconv Convierte un valor entero en su representación de cadena.\n\tITS := strconv.Itoa(numbers)\n\tfmt.Printf(\"Conversión de entero a cadena: Tipo: %T Valor: %s\\n\", ITS, ITS)\n\n\t// Extra: Palabras palindromas\n\n\tfmt.Println(\"'Somos', ¿es una palabra palindroma?: \", palindromeWord(\"somos\"))\n\tfmt.Println(\"'Hola', ¿es una palabra palindroma?: \", palindromeWord(\"hola\"))\n\n\t// Extra: Anagramas\n\tfmt.Println(\"'Amor y Roma', ¿son anagrama?: \", anagramWord(\"AmoR\", \"RoMa\"))\n\tfmt.Println(\"'Verde y Rojo', ¿son anagrama?: \", anagramWord(\"Verde\", \"rOjo\"))\n\n\t// Extra: Isogramas\n\tfmt.Println(\"'Murciélago' ¿es un isograma?: \", isogramWord(\"murciélago\"))\n\tfmt.Println(\"'Pan' ¿es un isograma?: \", isogramWord(\"pan\"))\n\tfmt.Println(\"'Pasta' ¿es un isograma?: \", isogramWord(\"pasta\"))\n\n}\n\nfunc palindromeWord(word string) bool {\n\tif len(word) == 0 {\n\t\treturn false\n\t} else if len(word) == 1 {\n\t\treturn true\n\t} else {\n\t\trunes := []rune(word)\n\t\tn := len(runes)\n\t\tfor i := 0; i < n/2; i++ {\n\t\t\trunes[i], runes[n-1-i] = runes[n-1-i], runes[i]\n\t\t}\n\t\treversed := string(runes)\n\n\t\tif reversed != word {\n\t\t\treturn false\n\t\t}\n\t\treturn true\n\t}\n}\n\nfunc anagramWord(x, y string) bool {\n\t// Verificamos si tienen diferente longitud (por definición no pueden serlo)\n\tif len(x) != len(y) {\n\t\treturn false\n\t}\n\n\t// las dividimos con Split mientras las paso a minúsculas a la vez\n\tsplited1 := strings.Split(strings.ToLower(x), \"\")\n\tsplited2 := strings.Split(strings.ToLower(y), \"\")\n\n\t// Las ordenamos\n\tsort.Strings(splited1)\n\tsort.Strings(splited2)\n\n\t// Iteramos sobre ellas para comparar si son iguales\n\tfor i := 0; i < len(splited1); i++ {\n\t\tcompared := splited1[i] == splited2[i]\n\t\tif !compared {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc isogramWord(s string) bool {\n\tword := strings.ToLower(s)\n\n\truneCount := make(map[rune]int)\n\n\tfor _, r := range word {\n\t\truneCount[r]++\n\t}\n\n\tvar firstCount int\n\tfor _, count := range runeCount {\n\t\tfirstCount = count\n\t\tbreak\n\t}\n\n\tfor _, count := range runeCount {\n\t\tif count != firstCount {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/go/N0HagoNada.go",
    "content": "package main\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\t\"unicode\"\n)\n\nfunc main() {\n\tscanner := bufio.NewScanner(os.Stdin)\n\n\tfor {\n\t\tfmt.Println(\"Introduce una palabra (o escribe 'exit' para salir):\")\n\t\tscanner.Scan()\n\t\tpalabra := strings.TrimSpace(scanner.Text())\n\n\t\tif palabra == \"exit\" {\n\t\t\tbreak\n\t\t}\n\n\t\tif esPalindromo(palabra) {\n\t\t\tfmt.Println(palabra, \"es un palíndromo.\")\n\t\t} else {\n\t\t\tfmt.Println(palabra, \"no es un palíndromo.\")\n\t\t}\n\n\t\tif esIsograma(palabra) {\n\t\t\tfmt.Println(palabra, \"es un isograma.\")\n\t\t} else {\n\t\t\tfmt.Println(palabra, \"no es un isograma.\")\n\t\t}\n\n\t\tfmt.Println(\"Introduce otra palabra para comparar si son anagramas (o escribe 'exit' para salir):\")\n\t\tscanner.Scan()\n\t\totraPalabra := strings.TrimSpace(scanner.Text())\n\n\t\tif otraPalabra == \"exit\" {\n\t\t\tbreak\n\t\t}\n\n\t\tif esAnagrama(palabra, otraPalabra) {\n\t\t\tfmt.Println(palabra, \"y\", otraPalabra, \"son anagramas.\")\n\t\t} else {\n\t\t\tfmt.Println(palabra, \"y\", otraPalabra, \"no son anagramas.\")\n\t\t}\n\t}\n\toperacioneStrings()\n\tTestStringIterationWithRange()\n\tTestStringEqualsCaseInsensitive()\n}\n\nfunc operacioneStrings() {\n\t// Imprimir cadena\n\tfmt.Println(\"Let's print out this string.\")\n\t// Concatenar\n\tfmt.Println(\"Sammy\" + \"Shark\")\n\t// Aplicar mayúsculas y minúsculas\n\tss := \"Sammy Shark\"\n\tfmt.Println(strings.ToUpper(ss))\n\tfmt.Println(strings.ToLower(ss))\n\t// Funciones de busqueda de cadena\n\t/* strings.HasPrefix \tRealiza búsquedas en la cadena desde el principio.\n\tstrings.HasSuffix \tRealiza búsquedas en la cadena desde el final.\n\tstrings.Contains \tRealiza búsquedas en cualquier parte de la cadena.\n\tstrings.Count \tCuenta la cantidad de veces que aparece la cadena.*/\n\tfmt.Println(strings.HasPrefix(ss, \"Sammy\"))\n\tfmt.Println(strings.HasSuffix(ss, \"Shark\"))\n\tfmt.Println(strings.Contains(ss, \"Sh\"))\n\tfmt.Println(strings.Count(ss, \"S\"))\n\t// Determina la longuitud de la cadena\n\topenSource := \"Jhon contributes to open source.\"\n\tfmt.Println(len(openSource))\n\t// manipulación de Cadenas, strings.Join, strings.Split, strings.ReplaceAll\n\tfmt.Println(strings.Join([]string{\"sharks\", \"crustaceans\", \"plankton\"}, \",\"))\n\tballoon := \"Sammy has a balloon.\"\n\ts := strings.Split(balloon, \" \")\n\tfmt.Printf(\"%q\", s)\n\tfmt.Println()\n\t// strings Filed ignora espacios en blanco\n\tdata := \"  username password   email\tdate\"\n\tfields := strings.Fields(data)\n\tfmt.Printf(\"%q\", fields)\n\t// ReplaceAll toma uan cadena original y realiza una sustitución\n\tfmt.Println(strings.ReplaceAll(balloon, \"has\", \"had\"))\n\t// Eliminar espacios en blanco\n\tfmt.Println(strings.TrimSpace(data)) // que pasa aqui ?\n\tfmt.Println(strings.TrimSpace(\" \\t\\n Hello, Gophers \\n\\t\\r\\n\"))\n\t// Trim retorna un slice del string quitando\n\tfmt.Println(strings.Trim(\"¡¡¡Hello, Gophers!!!\", \"!¡\"))\n\t// Builder para construir un string\n\twords := []string{\"Hola\", \" \", \"Mundo\"}\n\n\tvar builder strings.Builder\n\n\tfor _, w := range words {\n\t\tbuilder.WriteString(w)\n\t}\n\n\tresult := builder.String()\n\tfmt.Println(result)\n\t// Comparar tamaño\n\n\t// create three strings\n\tstring1 := \"Programiz\"\n\tstring2 := \"Programiz Pro\"\n\tstring3 := \"Programiz\"\n\n\t// compare strings\n\tfmt.Println(string1+\" vs \"+string2+\":\", strings.Compare(string1, string2)) // -1\n\tfmt.Println(string2+\" vs \"+string3+\":\", strings.Compare(string2, string3)) // 1\n\tfmt.Println(string1+\" vs \"+string3+\":\", strings.Compare(string1, string3)) // 0\n}\n\n// Iterar sobre un String\nfunc TestStringIterationWithRange() {\n\tfmt.Println()\n\tnamestring := \"omar barra\"\n\tfor _, v := range namestring {\n\t\tfmt.Printf(\"%q\\n\", v)\n\t}\n}\n\n// Compara igualdad sin importar case\nfunc TestStringEqualsCaseInsensitive() {\n\tgot := \"Go is Awesome!\"\n\texpect := \"go is awesome!\"\n\n\tif !strings.EqualFold(got, expect) {\n\t\tfmt.Printf(\"expected %s got %s\", expect, got)\n\t}\n}\n\nfunc esPalindromo(s string) bool {\n\ts = strings.ToLower(s)\n\tizquierda := 0\n\tderecha := len(s) - 1\n\n\tfor izquierda < derecha {\n\t\t// Avanzar izquierda si no es letra o número\n\t\tfor izquierda < derecha && !unicode.IsLetter(rune(s[izquierda])) && !unicode.IsNumber(rune(s[izquierda])) {\n\t\t\tizquierda++\n\t\t}\n\t\t// Retroceder derecha si no es letra o número\n\t\tfor izquierda < derecha && !unicode.IsLetter(rune(s[derecha])) && !unicode.IsNumber(rune(s[derecha])) {\n\t\t\tderecha--\n\t\t}\n\n\t\tif s[izquierda] != s[derecha] {\n\t\t\treturn false\n\t\t}\n\n\t\tizquierda++\n\t\tderecha--\n\t}\n\n\treturn true\n}\n\nfunc esAnagrama(palabra1, palabra2 string) bool {\n\t// contienen el mismo número de ocurrencias de cada letra en orden diferente\n\tif len(palabra1) != len(palabra2) {\n\t\treturn false\n\t}\n\tcuenta := make(map[rune]int)\n\n\tfor _, letra := range strings.ToLower(palabra1) {\n\t\tif unicode.IsLetter(letra) {\n\t\t\tcuenta[letra]++\n\t\t}\n\t}\n\n\tfor _, letra := range strings.ToLower(palabra2) {\n\t\tif unicode.IsLetter(letra) {\n\t\t\tcuenta[letra]--\n\t\t\tif cuenta[letra] < 0 {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t}\n\n\tfor _, valor := range cuenta {\n\t\tif valor != 0 {\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn true\n}\nfunc esIsograma(palabra string) bool {\n\t// No tiene letras repetidas\n\tusado := make(map[rune]bool)\n\tfor _, letra := range strings.ToLower(palabra) {\n\t\tif letra == '-' || letra == ' ' {\n\t\t\tcontinue\n\t\t}\n\t\tif _, ok := usado[letra]; ok {\n\t\t\treturn false\n\t\t}\n\t\tusado[letra] = true\n\t}\n\treturn true\n}\nfunc InvertirString(s string) string {\n\t// Convierte el string a un slice de runas para manejar adecuadamente caracteres Unicode.\n\trunas := []rune(s)\n\tfor i, j := 0, len(runas)-1; i < j; i, j = i+1, j-1 {\n\t\t// Intercambia los elementos.\n\t\trunas[i], runas[j] = runas[j], runas[i]\n\t}\n\t// Convierte el slice de runas de vuelta a string.\n\treturn string(runas)\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/go/edalmava.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\t// Concatenación de cadenas\n\tcadena1 := \"Hola,\"\n\tcadena2 := \" mundo\"\n\tresultado := cadena1 + cadena2 // Resultado: \"Hola, mundo\"\n\tfmt.Println(\"Cadena original: \", resultado)\n\n\t// El acceso a los caracteres de una cadena se realiza mediante índices\n\tcadena := \"Golang\"\n\tprimerCaracter := cadena[0] // 'G'\n\tfmt.Println(\"Primer caracter de Golang: \", string(primerCaracter))\n\n\t// Iterar sobre una cadena con caracteres UTF-8\n\tfor i, c := range resultado {\n\t\tfmt.Printf(\"Índice: %d, Carácter: %c\\n\", i, c)\n\t}\n\n\t// Extraer partes de una cadena utilizando un rango de índices\n\tsubcadena := resultado[0:4] // \"Hola\"\n\tfmt.Println(\"Extraer una subcadena: \", subcadena)\n\n\t// Longitud de una cadena en bytes\n\tlongitud := len(resultado) // 11\n\tfmt.Println(\"Longitud de la cadena: \", longitud)\n\n\t// Verificar si una cadena esta vacía\n\tcadenaVacia := \"\"\n\testaVacia := len(cadenaVacia) == 0 // true\n\tif estaVacia {\n\t\tfmt.Println(\"La cadena esta vacía\")\n\t}\n\n\t// Verificar si una cadena contiene una subcadena\n\tcontiene := strings.Contains(resultado, \"mundo\")\n\tfmt.Println(\"La cadena contiene la palabra mundo: \", contiene)\n\n\t// Encontrar el índice de la primera aparición de una subcadena dentro de otra\n\tindice := strings.Index(resultado, \"mundo\") // 6\n\tfmt.Println(\"Índice de la primera aparición de mundo: \", indice)\n\n\t// Para comparar cadenas ignorando diferencias de mayúsculas y minúsculas\n\tigual := strings.EqualFold(\"GoLang\", \"golang\") // true\n\tfmt.Println(\"Las cadenas son iguales: \", igual)\n\n\t// Dividir una cadena en un slice de subcadenas, utilizando un delimitador especificado.\n\tpartes := strings.Split(resultado, \", \") // []string{\"Hola\", \"mundo\"}\n\tfmt.Println(partes[0], partes[1])\n\n\t// Para unir un slice de cadenas en una sola cadena con un delimitador.\n\tunido := strings.Join(partes, \", \") // \"Hola, mundo\"\n\tfmt.Println(unido)\n\n\t// Covertir a minúsculas y mayúsculas\n\tminusculas := strings.ToLower(cadena) // \"hola, mundo\"\n\tmayusculas := strings.ToUpper(cadena) // \"HOLA, MUNDO\"\n\tfmt.Println(\"Cadena en minúscula: \", minusculas)\n\tfmt.Println(\"Cadena en mayúscula: \", mayusculas)\n\n\t// Eliminar espacios al principio y al final de la cadena\n\tcadenaConEspacios := \"   Hola, mundo   \"\n\tcadenaLimpia := strings.TrimSpace(cadenaConEspacios) // \"Hola, mundo\"\n\tfmt.Println(\"Cadena sin espacios al principio y al final: \", cadenaLimpia)\n\n\t// Reemplazar partes de una cadena\n\treemplazada := strings.Replace(resultado, \"mundo\", \"Go\", 1) // \"Hola, Go\"\n\tfmt.Println(\"Cadena Reemplazada: \", reemplazada)\n\n\t// Repetir una cadena un número n de veces\n\trepetir := strings.Repeat(\"*\", 10)\n\tfmt.Println(repetir)\n\n\t// Salidas formateadas\n\tnombre := \"Edalmava\"\n\tedad := 30\n\t/*\n\t\t    %s - cadena de texto\n\t\t\t%d - entero decimal\n\t\t\t%f - coma flotante\n\t*/\n\tfmt.Printf(\"Nombre: %s, Edad: %d\\n\", nombre, edad)\n\n\t// Devolver una cadena formateada\n\tcadenaFormateada := fmt.Sprintf(\"Nombre: %s, Edad: %d\\n\", nombre, edad)\n\tfmt.Println(cadenaFormateada)\n\n\t// Enviar salida formateada a un archivo\n\tarchivo, err := os.Create(\"salida.txt\")\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tdefer archivo.Close()\n\tfmt.Fprintf(archivo, \"Nombre: %s, Edad: %d\\n\", nombre, edad)\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/go/hozlucas28.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strings\"\n)\n\nfunc main() {\n\t/*\n\t   String operations...\n\t*/\n\n\t// Get length of a string\n\tconst strLength int = len(\"Hello World!\")\n\tfmt.Println(\"Get length of a string: len(<STRING NAME>)\")\n\tfmt.Printf(\"len('Hello World!') --> %d\", strLength)\n\n\t// Get char of a string\n\tvar char byte = \"Hello World!\"[1]\n\tfmt.Println(\"\\n\\nGet char of a string: <STRING NAME>[<INDEX OF THE CHAR>]\")\n\tfmt.Printf(\"'Hello World!'[1] --> %c\", char)\n\n\t// Get substring of a string\n\tvar substring string = \"Hello World!\"[2:9]\n\tfmt.Println(\"\\n\\nGet substring of a string: <STRING NAME>[<START>, <END - 1>]\")\n\tfmt.Printf(\"'Hello World!'[2:9] --> '%s'\", substring)\n\n\t// String to uppercase\n\tvar uppercaseStr string = strings.ToUpper(\"Buenos Aires\")\n\tfmt.Println(\"\\n\\nString to uppercase: strings.ToUpper(<STRING NAME>)\")\n\tfmt.Printf(\"strings.ToUpper('Buenos Aires') --> '%s'\", uppercaseStr)\n\n\t// String to lowercase\n\tvar lowercaseStr string = strings.ToLower(\"USA\")\n\tfmt.Println(\"\\n\\nString to lowercase: strings.ToLower(<STRING NAME>)\")\n\tfmt.Printf(\"strings.ToLower('USA') --> '%s'\", lowercaseStr)\n\n\t// Repeat a string\n\tvar repeatedStr string = strings.Repeat(\"Juana\", 2)\n\tfmt.Println(\"\\n\\nRepeat a string: strings.Repeat(<STRING NAME>, <NUMBER OF REPEATS>)\")\n\tfmt.Printf(\"strings.Repeat('Juana', 2) --> '%s'\", repeatedStr)\n\n\t// Concat two strings\n\tconst concatedStr01 string = \"Lucas\" + \"Hoz\"\n\tfmt.Println(\"\\n\\nConcat two strings: <FIRST STRING NAME> + <SECOND STRING NAME> + <'N' STRING NAME...>\")\n\tfmt.Printf(\"'Lucas ' + 'Hoz' --> '%s'\", concatedStr01)\n\n\t// Replace substring of a string\n\tvar replacedStr string = strings.ReplaceAll(\"Hello Python!\", \"Python\", \"Golang\")\n\tfmt.Println(\"\\n\\nReplace substring of a string: strings.ReplaceAll(<STRING NAME>, <SUBSTRING TO SEARCH>, <NEW SUBSTRING>)\")\n\tfmt.Printf(\"strings.ReplaceAll('Hello Python!', 'Python', 'Golang') --> '%s'\", replacedStr)\n\n\t// Compare start of a string\n\tvar compareStart bool = strings.HasPrefix(\"Lucas\", \"ho\")\n\tfmt.Println(\"\\n\\nCompare start of a string: strings.HasPrefix(<STRING NAME>, <SUBSTRING TO FIND>)\")\n\tfmt.Printf(\"strings.HasPrefix('Lucas', 'ho') --> %t\", compareStart)\n\n\t// Compare end of a string\n\tvar compareEnd bool = strings.HasSuffix(\"Lucas\", \"as\")\n\tfmt.Println(\"\\n\\nCompare end of a string: strings.HasSuffix(<STRING NAME>, <SUBSTRING TO FIND>)\")\n\tfmt.Printf(\"strings.HasSuffix('Lucas', 'as') --> %t\", compareEnd)\n\n\t// Check if a string includes a substring\n\tvar includes bool = strings.Contains(\"Lucas\", \"c\")\n\tfmt.Println(\"\\n\\nCheck if a string includes a substring: strings.Contains(<STRING NAME>, <SUBSTRING TO FIND>)\")\n\tfmt.Printf(\"strings.Contains('Lucas', 'c') --> %t\", includes)\n\n\t// Check if a string matches a regex\n\tregexStr, _ := regexp.MatchString(`[luc]`, \"Lucas\")\n\tfmt.Println(\"\\n\\nCheck if a string matches a regex: regexp.MatchString(<REGEX>, <STRING NAME>)\")\n\tfmt.Printf(\"regexp.MatchString(`[luc]`, 'Lucas') --> %t\", regexStr)\n\n\t// Check if a string is equal to another string\n\tvar commonComparison int = strings.Compare(\"Lucas\", \"LuCaS\")\n\tfmt.Println(\"\\n\\nCheck if a string is equal to another string: strings.Compare(<FIRST STRING NAME>, <SECOND STRING NAME>)\")\n\tfmt.Printf(\"strings.Compare('Lucas', 'LuCaS') --> %d\", commonComparison)\n\n\tfmt.Println(\"\\n\\n# ---------------------------------------------------------------------------------- #\")\n\n\t/*\n\t   Additional challenge...\n\t*/\n\n\tarr01 := []string{\"level\", \"hello\", \"racecar\", \"world\", \"madam\", \"programming\", \"deed\", \"javascript\"}\n\tpalindromeWords := getPalindromeWords(arr01)\n\tfmt.Println(\"\\nPalindrome words of\", arr01, \"-->\", palindromeWords)\n\n\tarr02 := [][]string{\n\t\t{\"listen\", \"silent\"},\n\t\t{\"hello\", \"world\"},\n\t\t{\"good\", \"dog\"},\n\t}\n\tanagramWords := getAnagramWords(arr02)\n\tfmt.Println(\"\\nAnagram words of\", arr02, \"-->\", anagramWords)\n\n\tarr03 := []string{\"hello\", \"world\", \"isogram\", \"javascript\", \"python\", \"algorithm\"}\n\tisogramWords := getIsogramWords(arr03)\n\tfmt.Println(\"\\nIsogram words of\", arr03, \"-->\", isogramWords)\n}\n\nfunc getPalindromeWords(words []string) []string {\n\tvar palindromeWords []string\n\n\tfor _, word := range words {\n\t\tvar reversedWord strings.Builder\n\t\tfor j := len(word) - 1; j >= 0; j-- {\n\t\t\tvar char byte = word[j]\n\t\t\treversedWord.WriteByte(char)\n\t\t}\n\n\t\tvar isPalindrome bool = strings.EqualFold(word, reversedWord.String())\n\t\tif isPalindrome {\n\t\t\tpalindromeWords = append(palindromeWords, word)\n\t\t}\n\t}\n\n\treturn palindromeWords\n\n}\n\nfunc getAnagramWords(pairOfWords [][]string) [][]string {\n\tvar anagramWords [][]string\n\n\tfor _, words := range pairOfWords {\n\t\tword01, word02 := words[0], words[1]\n\n\t\tvar longestWord string = word02\n\t\tif len(word01) > len(word02) {\n\t\t\tlongestWord = word01\n\t\t}\n\n\t\tuniqueChars := make(map[rune]bool)\n\t\tfor _, char := range longestWord {\n\t\t\tuniqueChars[char] = true\n\t\t}\n\n\t\tisAnagram := true\n\t\tfor _, char := range word01 {\n\t\t\tif !uniqueChars[char] {\n\t\t\t\tisAnagram = false\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tif isAnagram {\n\t\t\tanagramWords = append(anagramWords, words)\n\t\t}\n\t}\n\n\treturn anagramWords\n}\n\nfunc getIsogramWords(words []string) []string {\n\tvar isogramsWords []string\n\n\tfor _, word := range words {\n\t\tvar wordFmt string = strings.ReplaceAll(word, \" \", \"\")\n\n\t\tuniqueChars := make(map[rune]bool)\n\t\tfor _, char := range wordFmt {\n\t\t\tuniqueChars[char] = true\n\t\t}\n\n\t\tif len(wordFmt) == len(uniqueChars) {\n\t\t\tisogramsWords = append(isogramsWords, word)\n\t\t}\n\t}\n\n\treturn isogramsWords\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/go/kodenook.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\nfunc main() {\n\t/*\n\t\tString Functions\n\t*/\n\n\tvar word string = \"hello, Go\"\n\n\tfmt.Println(strings.Contains(word, \"hello\"))\n\tfmt.Println(strings.Count(word, \"l\"))\n\tfmt.Println(strings.Index(word, \"Go\"))\n\tfmt.Println(strings.LastIndex(word, \"Go\"))\n\tfmt.Println(strings.Repeat(word, 2))\n\tfmt.Println(strings.Replace(word, \"Go\", \"Go!\", 1))\n\tfmt.Println(strings.ToLower(word))\n\tfmt.Println(strings.ToUpper(word))\n\tfmt.Println(strings.Trim(word, \"eho\"))\n\tfmt.Println(strings.TrimSpace(word))\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/go/miguelex.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"sort\"\n\t\"strings\"\n)\n\nfunc main() {\n\t// Operaciones básicas sobre cadenas de texto\n\ttexto := \"Hola, mundo!\"\n\n\t// Interpolación de cadenas (uso de plantillas de cadena)\n\tnombre := \"Migue\"\n\tlenguaje := \"PHP\"\n\tmensaje := fmt.Sprintf(\"Hola, me llamo %s y trabajo con %s años.\", nombre, lenguaje)\n\tfmt.Println(mensaje)\n\n\t// Longitud de la cadena\n\tlongitud := len(texto)\n\tfmt.Printf(\"La longitud de la cadena %s es %d caracteres\\n\", texto, longitud)\n\n\t// Obtener el carácter en una posición específica\n\tprimerCaracter := string(texto[0])\n\tfmt.Printf(\"El primer carácter de %s es %s\\n\", texto, primerCaracter)\n\n\t// Concatenar dos cadenas\n\tnuevaCadena := texto + \" Go\"\n\tfmt.Printf(\"La nueva cadena de unir %s con Go es %s\\n\", texto, nuevaCadena)\n\n\t// Convertir la cadena a minúsculas\n\tminusculas := strings.ToLower(texto)\n\tfmt.Printf(\"%s en minúsculas es %s\\n\", texto, minusculas)\n\n\t// Convertir la cadena a mayúsculas\n\tmayusculas := strings.ToUpper(texto)\n\tfmt.Printf(\"%s en mayúsculas es %s\\n\", texto, mayusculas)\n\n\t// Obtener una subcadena\n\tsubcadena := texto[0:4]\n\tfmt.Printf(\"La subcadena de %s entre las posiciones 0 y 4 es %s\\n\", texto, subcadena)\n\n\t// Reemplazar parte de la cadena\n\treemplazada := strings.Replace(texto, \"Hola\", \"Saludos\", 1)\n\tfmt.Printf(\"Vamos a reemplazar Hola por Saludos: %s\\n\", reemplazada)\n\n\t// Operaciones adicionales sobre cadenas de texto\n\ttextoConEspacios := \"   Hola,      mundo!   \"\n\n\t// Eliminar espacios en blanco al principio y al final\n\tsinEspaciosExtremos := strings.TrimSpace(textoConEspacios)\n\tfmt.Printf(\"Cadena sin espacios al principio y al final: %s\\n\", sinEspaciosExtremos)\n\n\t// Eliminar todos los espacios en blanco\n\tsinEspacios := strings.ReplaceAll(textoConEspacios, \" \", \"\")\n\tfmt.Printf(\"Cadena sin espacios: %s\\n\", sinEspacios)\n\n\t// Unión de dos cadenas\n\tcadena1 := \"Moure\"\n\tcadena2 := \"Dev\"\n\tunionCadenas := fmt.Sprintf(\"%s %s\", cadena1, cadena2)\n\tfmt.Printf(\"La unión de las cadenas %s y %s es %s\\n\", cadena1, cadena2, unionCadenas)\n\n\t// Intersección de dos cadenas (caracteres comunes)\n\tinterseccionCadenas := interseccionDeCadenas(cadena1, cadena2)\n\tfmt.Printf(\"Intersección de las cadenas %s y %s es %s\\n\", cadena1, cadena2, interseccionCadenas)\n\n\t// Acceso a caracteres específicos (por posición)\n\ttercerCaracter := string(texto[2])\n\tfmt.Printf(\"El tercer carácter de %s es %s\\n\", texto, tercerCaracter)\n\n\t// Repetición de una cadena\n\tcadenaRepetida := strings.Repeat(\"Hola \", 3)\n\tfmt.Printf(\"Cadena Hola repetida 3 veces queda %s\\n\", cadenaRepetida)\n\n\t// Recorrido de una cadena (usando un bucle)\n\tfor i, char := range texto {\n\t\tfmt.Printf(\"Carácter en posición %d: %c\\n\", i, char)\n\t}\n\n\t// Conversión a título (primera letra en mayúscula)\n\ttitulo := strings.Title(strings.ToLower(texto))\n\tfmt.Printf(\"La cadena %s como título %s\\n\", texto, titulo)\n\n\t// División de una cadena en un array de substrings\n\tpalabras := strings.Fields(texto)\n\tfmt.Printf(\"Palabras en la cadena %s son %v\\n\", texto, palabras)\n\n\t// Verificación de si una cadena comienza o termina con ciertos caracteres\n\tcomienzaCon := strings.HasPrefix(texto, \"Hola\")\n\tfmt.Printf(\"¿La cadena %s comienza con 'Hola'? %t\\n\", texto, comienzaCon)\n\n\tterminaCon := strings.HasSuffix(texto, \"mundo!\")\n\tfmt.Printf(\"¿La cadena %s termina con 'mundo!'? %t\\n\", texto, terminaCon)\n\n\t// Verificar si una cadena es palíndromo\n\tfmt.Printf(\"¿Es '%s' un palíndromo? %t\\n\", texto, esPalindromo(texto))\n\tfmt.Printf(\"¿Es 'Ana' un palíndromo? %t\\n\", esPalindromo(\"Ana\"))\n\n\t// Verificar si una cadena es un anagrama\n\tfmt.Printf(\"¿Es 'listen' un anagrama de 'silent'? %t\\n\", esAnagrama(\"listen\", \"silent\"))\n\n\t// Verificar si una cadena es un isograma\n\tfmt.Printf(\"¿Es 'programming' un isograma? %t\\n\", esIsograma(\"programming\"))\n}\n\n// Función para la intersección de dos cadenas (caracteres comunes)\nfunc interseccionDeCadenas(cadena1, cadena2 string) string {\n\tset1 := make(map[rune]struct{})\n\tset2 := make(map[rune]struct{})\n\n\tfor _, char := range cadena1 {\n\t\tset1[char] = struct{}{}\n\t}\n\n\tfor _, char := range cadena2 {\n\t\tset2[char] = struct{}{}\n\t}\n\n\tvar interseccion []rune\n\tfor char := range set1 {\n\t\tif _, exists := set2[char]; exists {\n\t\t\tinterseccion = append(interseccion, char)\n\t\t}\n\t}\n\n\tsort.Slice(interseccion, func(i, j int) bool {\n\t\treturn interseccion[i] < interseccion[j]\n\t})\n\n\treturn string(interseccion)\n}\n\n// Función para verificar si una cadena es palíndromo\nfunc esPalindromo(cadena string) bool {\n\tsinEspacios := strings.Join(strings.Fields(cadena), \"\")\n\tinvertida := invertirCadena(sinEspacios)\n\treturn strings.ToLower(sinEspacios) == strings.ToLower(invertida)\n}\n\n// Función para invertir una cadena\nfunc invertirCadena(cadena string) string {\n\trunes := []rune(cadena)\n\tfor i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {\n\t\trunes[i], runes[j] = runes[j], runes[i]\n\t}\n\treturn string(runes)\n}\n\n// Función para verificar si una cadena es un anagrama\nfunc esAnagrama(cadena1, cadena2 string) bool {\n\tlimpiaCadena := func(cadena string) string {\n\t\treturn strings.Join(strings.Fields(cadena), \"\")\n\t}\n\n\tlimpiaCadena1 := limpiaCadena(cadena1)\n\tlimpiaCadena2 := limpiaCadena(cadena2)\n\n\treturn ordenarCadena(limpiaCadena1) == ordenarCadena(limpiaCadena2)\n}\n\n// Función para ordenar una cadena\nfunc ordenarCadena(cadena string) string {\n\trunes := []rune(cadena)\n\tsort.Sort(sortRunes(runes))\n\treturn string(runes)\n}\n\n// Tipo de datos para ordenar los runes\ntype sortRunes []rune\n\nfunc (s sortRunes) Len() int           { return len(s) }\nfunc (s sortRunes) Less(i, j int) bool { return s[i] < s[j] }\nfunc (s sortRunes) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }\n\n// Función para verificar si una cadena es un isograma\nfunc esIsograma(cadena string) bool {\n\tcaracteres := make(map[rune]struct{})\n\n\tfor _, char := range cadena {\n\t\tif _, exists := caracteres[char]; exists {\n\t\t\treturn false\n\t\t}\n\t\tcaracteres[char] = struct{}{}\n\t}\n\n\treturn true\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/go/qwik-zgheib.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"sort\"\n\t\"strings\"\n)\n\ntype WordAnalyzer interface {\n\tIsPalindrome(word string) bool\n\tIsAnagram(word1, word2 string) bool\n\tIsIsogram(word string) bool\n}\n\ntype SimpleWordAnalyzer struct{}\n\nfunc NewSimpleWordAnalyzer() *SimpleWordAnalyzer {\n\treturn &SimpleWordAnalyzer{}\n}\n\nfunc (wa *SimpleWordAnalyzer) IsPalindrome(word string) bool {\n\tfor i := 0; i < len(word)/2; i++ {\n\t\tif word[i] != word[len(word)-1-i] {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc (wa *SimpleWordAnalyzer) IsAnagram(word1, word2 string) bool {\n\tif len(word1) != len(word2) {\n\t\treturn false\n\t}\n\tword1 = strings.ToLower(word1)\n\tword2 = strings.ToLower(word2)\n\tword1 = SortString(word1)\n\tword2 = SortString(word2)\n\treturn word1 == word2\n}\n\nfunc (wa *SimpleWordAnalyzer) IsIsogram(word string) bool {\n\tletters := make(map[rune]bool)\n\tfor _, char := range word {\n\t\tif char != ' ' && letters[char] {\n\t\t\treturn false\n\t\t}\n\t\tletters[char] = true\n\t}\n\treturn true\n}\n\nfunc SortString(s string) string {\n\tsChars := strings.Split(s, \"\")\n\tsort.Strings(sChars)\n\treturn strings.Join(sChars, \"\")\n}\n\nfunc main() {\n\t// Acceso a caracteres específicos\n\tword := \"Hello\"\n\tfmt.Println(\"Character at index 1:\", word[1])\n\n\t// Longitud de la cadena\n\tfmt.Println(\"Length of the word:\", len(word))\n\n\t// Concatenación de cadenas\n\totherWord := \"World\"\n\tfmt.Println(\"Concatenated:\", word+otherWord)\n\n\t// Conversión a mayúsculas y minúsculas\n\tfmt.Println(\"Uppercase:\", strings.ToUpper(word))\n\tfmt.Println(\"Lowercase:\", strings.ToLower(word))\n\n\t// Reemplazo de caracteres\n\tfmt.Println(\"Replaced:\", strings.Replace(word, \"e\", \"E\", -1))\n\n\t// Verificación de una subcadena\n\tfmt.Println(\"Contains 'lo'?\", strings.Contains(word, \"lo\"))\n\n\t// Subcadenas\n\tfmt.Println(\"Substring:\", word[1:4])\n\n\t// División de una cadena\n\tfmt.Println(\"Split:\", strings.Split(\"one,two,three\", \",\"))\n\n\t// Unión de cadenas\n\tparts := []string{\"one\", \"two\", \"three\"}\n\tfmt.Println(\"Join:\", strings.Join(parts, \", \"))\n\n\t// Recorrido de la cadena\n\tfor _, char := range word {\n\t\tfmt.Printf(\"%c \", char)\n\t}\n\tfmt.Println()\n\n\t// extra exercise\n\twa := NewSimpleWordAnalyzer()\n\n\tword1 := \"radar\"\n\tword2 := \"listen\"\n\tword3 := \"evil\"\n\tword4 := \"Debit card\"\n\tword5 := \"Bad credit\"\n\n\tfmt.Printf(\"%s is a palindrome: %t\\n\", word1, wa.IsPalindrome(word1))\n\tfmt.Printf(\"%s is a palindrome: %t\\n\", word2, wa.IsPalindrome(word2))\n\n\tfmt.Printf(\"%s and %s are anagrams: %t\\n\", word3, word4, wa.IsAnagram(word3, word4))\n\tfmt.Printf(\"%s and %s are anagrams: %t\\n\", word4, word5, wa.IsAnagram(word4, word5))\n\n\tfmt.Printf(\"%s is an isogram: %t\\n\", word3, wa.IsIsogram(word3))\n\tfmt.Printf(\"%s is an isogram: %t\\n\", word4, wa.IsIsogram(word4))\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/go/thegera4.go",
    "content": "/*\n * EJERCICIO:\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\npackage main\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\nfunc main() {\n\n\t//Algunas operaciones con strings. Para mas operaciones revisar documentacion de paquete \"strings\"\n\n\t// Acceso a caracteres específicos (ASCII)\n\tfmt.Println(\"***Acceso a caracteres específicos***\")\n\tfmt.Println(\"Hola\"[0]) // 72\n\tfmt.Println(\"Hola\"[1]) // 111\n\tfmt.Println(\"Hola\"[2]) // 108\n\tfmt.Println(\"Hola\"[3]) // 97\n\n\t// Subcadenas\n\tfmt.Println(\"***Subcadenas***\")\n\tfmt.Println(\"Hola\"[0:2]) // Ho\n\tfmt.Println(\"Hola\"[1:3]) // ol\n\tfmt.Println(\"Hola\"[2:4]) // la\n\n\t// Longitud\n\tfmt.Println(\"***Longitud***\")\n\tfmt.Println(len(\"Hola\")) // 4\n\n\t//Count\n\tfmt.Println(\"***Conteo***\")\n\tfmt.Println(strings.Count(\"Hola mundo\", \"o\")) // 2\n\n\t// Concatenación\n\tfmt.Println(\"***Concatenación***\")\n\tfmt.Println(\"Hola\" + \" mundo\") // Hola mundo\n\tvar s string = \"nuevo\"\n\tfmt.Printf(\"Otro string %s\\n\",s) // Otro string nuevo\n\tvar s1 string = \"mas\"\n\tvar s2 string = \"variables\"\n\tfmt.Printf(\"Otro string %s con %s %s\\n\",s,s1,s2) // Otra cadena doble cadena\n\n\t// Repetición\n\tfmt.Println(\"***Repetición***\")\n\tfmt.Println(strings.Repeat(\"Hola\", 3)) // HolaHolaHola\n\n\t// Conversión a mayúsculas y minúsculas\n\tfmt.Println(\"***Conversión a mayúsculas y minúsculas***\")\n\tfmt.Println(strings.ToUpper(\"Hola\")) // HOLA\n\tfmt.Println(strings.ToLower(\"Hola\")) // hola\n\n\t// Reemplazo\n\tfmt.Println(\"***Reemplazo***\")\n\tfmt.Println(strings.Replace(\"Hola mundo\", \"mundo\", \"gente\", 1)) // Hola gente\n\n\t// División\n\tfmt.Println(\"***División***\")\n\tfmt.Println(strings.Split(\"Hola mundo\", \" \")) // [Hola mundo]\n\n\t// Unión\n\tfmt.Println(\"***Unión***\")\n\tslice := []string{\"Hola\", \"mundo\"}\n\tfmt.Println(strings.Join(slice, \" \")) // Hola mundo\n\n\t// Verificación\n\tfmt.Println(\"***Verificación***\")\n\tfmt.Println(strings.Contains(\"Hola mundo\", \"mundo\")) // true\n\tfmt.Println(strings.Contains(\"Hola mundo\", \"gente\")) // false\n\n\t//Prefijo y sufijo\n\tfmt.Println(\"***Prefijo y sufijo***\")\n\tfmt.Println(strings.HasPrefix(\"Hola mundo\", \"Hola\")) // true\n\tfmt.Println(strings.HasSuffix(\"Hola mundo\", \"mundo\")) // true\n\n\t// Palíndromos\n\tfmt.Println(\"***Extra: Palindromos***\")\n\tfmt.Println(isPalindrome(\"Anita lava la tina\")) // true\n\tfmt.Println(isPalindrome(\"Roma\")) // false\n\n\t// Anagramas\n\tfmt.Println(\"***Extra: Anagramas***\")\n\tfmt.Println(isAnagram(\"gato\", \"Toga\")) // true\n\tfmt.Println(isAnagram(\"Anita\", \"tina\")) // false\n\n\t// Isogramas\n\tfmt.Println(\"***Extra: Isogramas***\")\n\tfmt.Println(isIsogram(\"murcielago\")) // true\n\tfmt.Println(isIsogram(\"anita\")) // false\n\n}\n\n// Palíndromos - Palabras que se leen igual de izquierda a derecha que de derecha a izquierda\nfunc isPalindrome(str string) bool {\n\tstr = strings.ToLower(str) // Convierte la cadena a minúsculas\n\tstr = strings.Replace(str, \" \", \"\", -1)  // Elimina los espacios en blanco\n\n\tfor i := 0; i < len(str)/2; i++ { // Recorre la mitad de la cadena\n\t\tif str[i] != str[len(str)-1-i] { // Compara el caracter actual con el simétrico\n\t\t\treturn false // Si no son iguales, regresa false\n\t\t}\n\t}\n\treturn true // Si no se encontraron diferencias, regresa true\n}\n\n// Anagramas\nfunc isAnagram(s1, s2 string) bool {\n\ts1 = strings.ToLower(s1) // Convierte las cadenas a minúsculas\n\ts2 = strings.ToLower(s2)\n\n\tif len(s1) != len(s2) { // Si las cadenas no tienen la misma longitud, regresa false directamente (no pueden ser anagramas)\n\t\treturn false\n\t}\n\n\tm := make(map[rune]int) // Crea un mapa para contar las ocurrencias de cada caracter\n\n\tfor _, c := range s1 { // Recorre cada caracter de la primera cadena\n\t\tm[c]++ // Cuenta cuantas veces aparece cada caracter\n\t}\n\n\tfor _, c := range s2 { //Recorre cada caracter de la segunda cadena\n\t\tm[c]-- // Resta 1 a la cuenta de cada caracter\n\t}\n\n\tfor _, v := range m { // Recorre el mapa\n\t\tif v != 0 { // Si alguna cuenta no es 0,\n\t\t\treturn false // regresa false (no son anagramas)\n\t\t}\n\t}\n\n\treturn true // Si todas las cuentas son 0, regresa true (son anagramas)\n}\n\n// Isogramas\nfunc isIsogram(s string) bool {\n\tm := make(map[rune]bool) // Crea un mapa para almacenar los caracteres únicos\n\n\tfor _, c := range s { // Recorre cada caracter de la cadena\n\t\tif m[c] { // Si el caracter ya está en el mapa,\n\t\t\treturn false // regresa false (no es un isograma)\n\t\t}\n\t\tm[c] = true // Si el caracter no está en el mapa, lo agrega\n\t}\n\n\treturn true // Si no se encontraron caracteres repetidos, regresa true (es un isograma)\n}"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/AbelADE.java",
    "content": "/**\n *Solución al ejercicio #04 CADENAS DE CARACTERES.\n * \n * @author AbelADE\n */\npublic class AbelADE {\n\n    public static boolean isPalindrome(String text) {\n        String text2 = \"\";\n        for (int i = (text.length() - 1); i >= 0; i--) {\n            text2 += text.charAt(i);\n        }\n        return text.equals(text2);\n    }\n\n    public static boolean isAnagram(String text1, String text2) {\n        if (text1.length() != text2.length()) {\n            return false;\n        }\n\n        for (int i = 0; i < text1.length(); i++) {\n            if (!text2.toLowerCase().contains(String.valueOf(text1.charAt(i)).toLowerCase())) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    public static boolean isHeterogram(String text) {\n        for (int i = 0; i < text.length(); i++) {\n            for (int j = i + 1; j < text.length(); j++) {\n                if (text.charAt(i) == text.charAt(j)) {\n                    return false;\n                }\n            }\n        }\n        return true;\n    }\n\n    public static boolean isIsogram(String text) {  \n        HashSet<Integer> counters = new HashSet<>();\n        boolean addCounter;\n        \n        int counter;\n        for (int i = 0; i < text.length(); i++) {\n            counter = 0;\n            addCounter = false;\n            String char1 = Character.toString(text.charAt(i)).toLowerCase();\n            \n            for (int j = i+1; j < text.length(); j++) {\n                String char2 = Character.toString(text.charAt(j)).toLowerCase();\n                if (char1.equals(char2)) {\n                    counter++;\n                    addCounter = true;\n                }\n            }\n            \n            if (addCounter) {\n                counters.add(counter);\n            }\n        }\n      \n        return counters.size()==1;\n    }\n\n    /**\n     * @param args the command line arguments\n     */\n    public static void main(String[] args) {\n        /**\n         * Muestra ejemplos de todas las operaciones que puedes realizar con\n         * cadenas de caracteres en tu lenguaje.\n         */\n\n        String text = \"Este es un texto de prueba\";\n\n        System.out.println(\"Opciones en Java: \");\n        System.out.println();\n\n        //Obtener un caracter según posición\n        System.out.println(\"Caracter: \" + text.charAt(0));\n\n        //Diferencia de longitud entre un texto y otro\n        System.out.println(\"Diferencia de longitud: \" + text.compareTo(\"Este\"));\n\n        //Comparar si son iguales\n        System.out.println(\"¿Son iguales? : \" + text.equals(\"Este\"));\n\n        //Comparar si son iguales sin tener en cuenta las mayúsulas\n        System.out.println(\"¿Son iguales? (ignorando mayúsculas): \" + text.equalsIgnoreCase(\"este es un texto de prueba\"));\n\n        //Concatenar texto\n        System.out.println(\"Concatenar texto: \" + text.concat(\" en Java\"));\n\n        //Para ver si contiene una subcadena\n        System.out.println(\"¿Contiene el texto? : \" + text.contains(\"Este\"));\n\n        //Para ver si termina por una subcadena\n        System.out.println(\"¿Termina por? : \" + text.endsWith(\"Este\"));\n\n        //Encontrar el íncide de una subcadena dentro del texto\n        System.out.println(\"Indice de subcadena: \" + text.indexOf(\"texto\"));\n\n        //Encontrar el íncide de un caracter dentro del texto\n        System.out.println(\"Indice de caracter: \" + text.indexOf('E'));\n\n        //Para ver si no tiene contenido o solo tiene espacios en blanco\n        System.out.println(\"¿No tiene contenido o solo tiene espacios en blanco? : \" + text.isBlank());\n\n        //Para ver si no tiene contenido\n        System.out.println(\"¿No tiene contenido? : \" + text.isEmpty());\n\n        //Encontrar el último íncdice de una subcadena dentro del texto\n        System.out.println(\"Último índice de subcadena: \" + text.lastIndexOf(\"texto\"));\n\n        //Encontrar el último íncide de un caracter dentro del texto\n        System.out.println(\"Último índice de caracter: \" + text.lastIndexOf('E'));\n\n        //Longitud del texto\n        System.out.println(\"Longitud: \" + text.length());\n\n        //Repite el texto n veces\n        System.out.println(\"Repite el texto: \" + text.repeat(2));\n\n        //Remplaza una subcadena dentro del texto por otra\n        System.out.println(\"Remplaza texto: \" + text.replace(\"Este es\", \"Soy\"));\n\n        //Comprueba si empieza por una subcadena\n        System.out.println(\"¿Empieza por? : \" + text.startsWith(\"Este\"));\n\n        //Devuelve la secuencia de caracteres que se encuentra entre los índices indicados\n        System.out.println(\"Secuencia de caracteres (por índices): \" + text.subSequence(0, 10));\n\n        //Devuelve la subcadena que se encuentra entre los índices indicados\n        System.out.println(\"Subcadena (por índices): \" + text.substring(0, 10));\n\n        //Devuelve el texto a partir del índice\n        System.out.println(\"Texto a partir de índice: \" + text.substring(10));\n\n        //Texto en minúsculas\n        System.out.println(\"Texto en minúsculas: \" + text.toLowerCase());\n\n        //Texto en mayúsculas\n        System.out.println(\"Texto en mayúsculas: \" + text.toUpperCase());\n\n        /**\n         * DIFICULTAD EXTRA (opcional):\n         */\n        System.out.println();\n        System.out.println(\"DIFICULTAD EXTRA (opcional):\");\n        System.out.println();\n\n        System.out.println(\"¿Es palíndromo? : \" + isPalindrome(\"323\"));\n\n        System.out.println(\"¿Es anagrama? : \" + isAnagram(\"Listen\", \"Silent\"));\n\n        System.out.println(\"¿Es heterograma? : \" + isHeterogram(\"yuxtaponer\"));\n\n        System.out.println(\"¿Es isograma? : \" + isIsogram(\"papelera\"));\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/Alextc35.java",
    "content": "/*                                                                                                                \n * EJERCICIO:                                                                                                     \n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres                        \n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):                          \n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,                 \n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...             \n *                                                                                                                \n * DIFICULTAD EXTRA (opcional):                                                                                   \n * Crea un programa que analice dos palabras diferentes y realice comprobaciones                                  \n * para descubrir si son:                                                                                         \n * - Palíndromos                                                                                                  \n * - Anagramas                                                                                                    \n * - Isogramas                                                                                                    \n */\n\nimport java.util.Arrays;\n\npublic class Alextc35 {\n        public static void main(String[] args) {\n                // Acceso a caracteres específicos\n                System.out.println(\"\\n--- Caracteres específicos ----\");\n                String texto = \"Hola Mundo\"; // String con 10 caracteres\n                char caracter = texto.charAt(5); // Índice [0-9]\n                System.out.println(\"Texto completo: \" + texto);\n                System.out.println(\"- Caracter en el índice 5: \" + caracter); // M\n                System.out.println(\"-------------------------------\\n\");\n\n                // Subcadenas\n                System.out.println(\"--------- Subcadenas ----------\");\n                System.out.println(\"Texto completo: \" + texto);\n                String subcadena1 = texto.substring(0, 4); // Hola\n                String subcadena2 = texto.substring(5); // Mundo\n                System.out.println(\"- Primera subcadena: \" + subcadena1\n                                + \"\\n- Segunda subcadena: \" + subcadena2);\n                System.out.println(\"-------------------------------\\n\");\n\n                // Longitud\n                System.out.println(\"---------- Longitud -----------\");\n                System.out.println(\"Texto completo: \" + texto);\n                int longitud = texto.length(); // 10\n                System.out.println(\"- Longitud de la cadena: \" + longitud);\n                System.out.println(\"-------------------------------\\n\");\n\n                // Concatenación\n                System.out.println(\"-------- Concatenación --------\");\n                System.out.println(\"Subcadena1: \" + subcadena1\n                                + \"\\nSubcadena2: \" + subcadena2\n                                + \"\\n- Subcadena1+Subcadena2: \" + subcadena1 + subcadena2);\n                System.out.println(\"-------------------------------\\n\");\n\n                // Repetición\n                System.out.println(\"--------- Repetición ----------\");\n                texto = \"Hola \";\n                System.out.println(\"Texto completo: \" + texto);\n                String repetido = texto.repeat(3); // Repite la cadena 3 veces\n                System.out.println(\"- Cadena repetida: \" + repetido);\n                System.out.println(\"-------------------------------\\n\");\n\n                // Recorrido\n                System.out.println(\"---------- Recorrido ----------\");\n                texto = \"Hola Mundo\";\n                System.out.println(\"Texto completo: \" + texto);\n                for (int i = 0; i < texto.length(); i++) {\n                        System.out.println(\"- Caracter en el índice \" + i + \": \"\n                                        + texto.charAt(i));\n                }\n                System.out.println(\"-------------------------------\\n\");\n\n                // Conversión a mayúsculas y mínusculas\n                System.out.println(\"--- Conversión a mayús y mínus ---\");\n                String mayusculas = texto.toUpperCase();\n                String minusculas = texto.toLowerCase();\n                System.out.println(\"Texto completo: \" + texto);\n                System.out.println(\"- Texto en mayúsculas: \" + mayusculas\n                                + \"\\n- Texto en minúsculas: \" + minusculas);\n                System.out.println(\" ------------------------------\\n\");\n\n                // Reemplazo\n                System.out.println(\"---------- Reemplazo ----------\");\n                System.out.println(\"Texto completo: \" + texto);\n                String reemplazado = texto.replace(\"Mundo\", \"Java\"); // Reemplaza \"Mundo\" por \"Java\"\n                System.out.println(\"- Cadena después del reemplazo:\\n\" + reemplazado);\n                System.out.println(\"-------------------------------\\n\");\n\n                // División\n                System.out.println(\"---------- División -----------\");\n                texto = \"Hola,Mundo,Java\";\n                System.out.println(\"Texto completo: \" + texto);\n                String[] palabras = texto.split(\",\"); // Divide la cadena por comas\n                for (String palabra : palabras) {\n                        System.out.println(\"- Palabra: \" + palabra);\n                }\n                System.out.println(\"-------------------------------\\n\");\n\n                // Unión\n                System.out.println(\"------------ Unión ------------\");\n                StringBuilder builder = new StringBuilder();\n                builder.append(\"Hola\");\n                builder.append(\" \");\n                builder.append(\"Mundo\");\n                String resultado = builder.toString();\n                System.out.println(\"- Cadena unida: \" + resultado);\n                System.out.println(\"-------------------------------\\n\");\n\n                // Interpolación\n                System.out.println(\"-------- Interpolación --------\");\n                texto = \"Mundo\";\n                int edad = 23;\n                String mensaje = String.format(\"Hola %s, tienes %d años.\", texto, edad);\n                System.out.println(mensaje);\n                System.out.println(\"-------------------------------\\n\");\n\n                // Verificación\n                System.out.println(\"-------- Verificación ---------\");\n                texto = \"Hola Mundo\";\n                boolean contiene = texto.contains(\"Mundo\"); // True\n                boolean empiezaCon = texto.startsWith(\"Hola\"); // True\n                boolean terminaCon = texto.endsWith(\"Mundo\"); // True\n                System.out.println(\"- Contiene 'Mundo': \" + contiene\n                                + \"\\n- Empieza con 'Hola': \" + empiezaCon\n                                + \"\\n- Termina con 'Mundo': \" + terminaCon);\n                System.out.println(\"-------------------------------\\n\");\n\n                // Opcional\n\n                // Palíndromos\n                System.out.println(\"--------- Palíndromo ----------\");\n                String oracion = \"Anita lava la tina\";\n                System.out.println(oracion + \"\\n¿Es palíndromo?: \"\n                                + palindromo(oracion) + \"\\n\");\n\n                oracion = \"Mi slim\";\n                System.out.println(oracion + \"\\n¿Es palíndromo?: \"\n                                + palindromo(oracion));\n                System.out.println(\"-------------------------------\\n\");\n\n                // Anagramas\n                System.out.println(\"--------- Anagramas -----------\");\n                String palabra1 = \"Amor\";\n                String palabra2 = \"Roma\";\n                System.out.println(\"¿\" + palabra1 + \" y \" + palabra2 + \" son anagramas?: \" +\n                                anagrama(palabra1, palabra2) + \"\\n\");\n\n                palabra1 = \"Robo\";\n                palabra2 = \"Bolo\";\n                System.out.println(\"¿\" + palabra1 + \" y \" + palabra2 + \" son anagramas?: \" +\n                                anagrama(palabra1, palabra2));\n                System.out.println(\"-------------------------------\\n\");\n\n                // Isogramas\n                System.out.println(\"--------- Isogramas -----------\");\n                String palabra = \"Joven\";\n                System.out.println(palabra + \"\\n¿es un isograma?: \" + isograma(palabra)\n                                + \"\\n\");\n\n                palabra = \"Carnaval\";\n                System.out.println(palabra + \"\\n¿es un isograma?: \" + isograma(palabra));\n                System.out.println(\"-------------------------------\\n\");\n        }\n\n        // Palíndromos\n        public static boolean palindromo(String palabra) {\n                // Pasamos a mínusculas y omitimos los espacios\n                palabra = palabra.toLowerCase().replace(\" \", \"\"); // Los \" \" se eliminan\n                String palabraInversa = \"\"; // Inicializamos la palabraInversa\n                for (int i = palabra.length() - 1; i >= 0; i--) { // Recorremos al revés la palabra\n                        palabraInversa += palabra.charAt(i); // Guardamos cada carácter\n                }\n                if (palabra.equals(palabraInversa)) {\n                        return true; // Si son iguales, true\n                } else {\n                        return false; // Si no, false\n                }\n        }\n\n        // Anagramas\n        public static boolean anagrama(String palabra1, String palabra2) {\n                if (palabra1.length() != palabra2.length()) {\n                        return false;\n                } // Si no tienen la misma longitud, directamente false\n\n                palabra1 = palabra1.toLowerCase(); // Palabra a mínusculas\n                palabra2 = palabra2.toLowerCase(); // Palabra a mínusculas\n                char[] charsPalabra1 = new char[palabra1.length()]; // Array de chars\n                char[] charsPalabra2 = new char[palabra2.length()]; // Array de chars\n\n                // Amor\n                for (int i = 0; i < palabra1.length(); i++) {\n                        charsPalabra1[i] = palabra1.charAt(i);\n                }\n\n                // Roma\n                for (int i = 0; i < palabra2.length(); i++) {\n                        charsPalabra2[i] = palabra2.charAt(i);\n                }\n\n                // Las ordenamos, y si son iguales, son anagramas\n                Arrays.sort(charsPalabra1);\n                Arrays.sort(charsPalabra2);\n\n                if (Arrays.equals(charsPalabra1, charsPalabra2)) {\n                        return true; // Si son iguales true\n                } else {\n                        return false; // Si no, false\n                }\n        }\n\n        // Isogramas\n        public static boolean isograma(String palabra) {\n                palabra = palabra.toLowerCase(); // Transformamos la palabra a mínusculas\n                char[] letras = new char[palabra.length()]; // Array de chars\n                for (int i = 0; i < palabra.length(); i++) {\n                        letras[i] = palabra.charAt(i); // Añadimos cada letra al Array\n                }\n\n                Arrays.sort(letras); // Ordenamos las letras en orden\n                char buffer = ' '; // Creamos un buffer para ver la letra anterior\n\n                for (char letra : letras) {\n                        if (buffer == letra) { // Si dos letras son iguales,\n                                return false; // devolver false\n                        }\n                        buffer = letra; // Añadimos la letra al buffer\n                }\n                return true; // Si ninguna es igual, devolver true\n        }\n}"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/AmadorQuispe.java",
    "content": "import java.util.Arrays;\n\npublic class AmadorQuispe {\n    public static void main(String[] args) {\n        opStrins();\n        String string1 = \" taco cat\";\n        long startTime = System.nanoTime();\n        System.out.println(\"Es palindrome :\" + isPalindrome(string1));\n        System.out.println(System.nanoTime() - startTime);\n\n        long startTime1 = System.nanoTime();\n        System.out.println(\"Es anagrama con conteo : \" + isAnagramWithCounting(\"termo\", \"remot\"));\n        System.out.println(System.nanoTime() - startTime1);\n\n        long startTime2 = System.nanoTime();\n        System.out.println(\"Es anagrama con oredenamiento : \" + isAnagramWithSort(\"termo\", \"remot\"));\n        System.out.println(System.nanoTime() - startTime2);\n\n        long startTime3 = System.nanoTime();\n        System.out.println(\"Es isogram : \" + isIsogram(\"termometro\"));\n        System.out.println(System.nanoTime() - startTime3);\n\n    }\n\n    private static void opStrins() {\n        String string = \"Hello World, RoadMap 2024\";\n        String anotherString = new String(\"Hello World, Roadmap 2024\");\n        // length(), numero de caracteres\n        System.out.println(\"longitud :\" + string.length());\n        // charAt - Devuelve el valor del carácter en el índice especificado\n        System.out.println(\"Carácter en el indice 1: \" + string.charAt(1));\n\n        // compareTo(String anotherString) Compara dos cadenas lexicográficamente.\n        // retorna 0 si son iguales y diferente a 0 si no lo son\n        System.out.println(\"Comparación : \" + string.compareTo(anotherString));\n        // compareToIgnoreCase(String anotherString) hace lo mismo que compareTo pero\n        // ignora diferencias mayúsculas y minúsculas\n        System.out.println(\"Comparación IgnoreCase : \" + string.compareToIgnoreCase(anotherString));\n        // concat(String str) , Concatena la cadena especificada al final de esta cadena\n        System.out.println(\"Concatenación : \" + string.concat(\"!!!\"));\n        // contains(CharSequence s), Devuelve verdadero si y sólo si esta cadena\n        // contiene la secuencia especificada de valores de caracteres\n        System.out.println(\"Contiene? :\" + string.contains(\"2024\"));\n        // contentEquals(CharSequence s) se utiliza para comparar cos cadenas\n        System.out.println(\"Comparar : \" + string.contentEquals(anotherString));\n        // endsWith(String suffix) Prueba si esta cadena termina con el sufijo\n        // especificado\n        System.out.println(\"Termina con 2024? : \" + string.endsWith(\"2024\"));\n        // equals(Object anObject), Compara dos cadenas con el objeto especificado\n        System.out.println(\"Es igual ? : \" + string.equals(anotherString));\n        // equalsIgnoreCase(Object anObject), Compara dos cadenas con el objeto\n        // especificado, ignora mayúsculas de minúsculas\n        System.out.println(\"Es igual IgnoreCase? : \" + string.equalsIgnoreCase(anotherString));\n        // format(String format, Object... args), Devuelve una cadena formateada\n        // utilizando la cadena de formato y los argumentos especificados.\n        System.out.println(\"Formateo: \" + String.format(\"Inicio %s final!!!\", string));\n        // indexOf(String str), Devuelve el índice dentro de esta cadena de la primera\n        // aparición de la sub cadena especificada\n        System.out.println(\"Indice de 'W' : \" + string.indexOf(\"W\"));\n        // join(CharSequence delimiter, CharSequence... elements)\n        // Devuelve una nueva cadena compuesta por copias de los elementos CharSequence\n        // unidas con una copia del delimitador especificado\n        System.out.println(\"Unión: \" + String.join(\" - \", string, anotherString));\n        // matches(String regex), Indica si esta cadena coincide o no con la expresión\n        // regular dada\n        System.out.println(\"Uso de expresiones regulares : \" + string.matches(\"[A-Z].*\"));\n        // replace(char oldChar, char newChar), Devuelve una cadena resultante de\n        // reemplazar todas las apariciones de oldChar en esta cadena con newChar.\n        System.out.println(\"Reemplazo:  \" + string.replace(\"o\", \"0\"));\n        // replaceAll(String regex, String replacement)\n        // Reemplaza cada sub cadena de esta cadena que coincide con la expresión\n        // regular dada con el reemplazo dado\n        System.out.println(\"Reemplazo regex: \" + string.replaceAll(\"[0-9]\", \"-\"));\n        // replaceFirst(String regex, String replacement)\n        // Reemplaza la primera sub cadena de esta cadena que coincide con la expresión\n        // regular dada con el reemplazo dado.\n        System.out.println(\"Reemplazo regex primera aparición: \" + string.replaceFirst(\"o\", \"#\"));\n        // split(String regex)\n        // Divide la cadena entre coincidencias de la expresión regular dada\n        String[] strings = string.split(\" \");\n        System.out.println(\"Division: \" + Arrays.toString(strings));\n        // startsWith(String prefix), Prueba si esta cadena comienza con el prefijo\n        // especificado\n        System.out.println(\"Empieza con ?: \" + string.startsWith(\"H\"));\n        // substring(int beginIndex, int endIndex)\n        // Devuelve una cadena que es una sub cadena de esta cadena. endIndex(exclusivo)\n        System.out.println(\"Sub cadena: \" + string.substring(0, 5));\n        // toLowerCase(), Convierte todos los caracteres de esta cadena a minúsculas\n        // utilizando las reglas de la configuración regional predeterminada.\n        System.out.println(\"A minúsculas: \" + string.toLowerCase());\n        // toUpperCase(), Convierte todos los caracteres de esta cadena a mayúsculas\n        // utilizando las reglas de la configuración regional predeterminada.\n        System.out.println(\"A mayúsculas: \" + string.toUpperCase());\n        // trim(), elimina espacios al inicio y al final\n        System.out.println(\"Sin espacios inicio y final:\" + string.trim());\n    }\n\n    private static boolean isPalindrome(String str) {\n        String strWithoutSpaces = str.replaceAll(\"\\s\", \"\");\n        int lRight = strWithoutSpaces.length() - 1;\n        int lLeft = 0;\n        while (lLeft < lRight) {\n            char s1 = strWithoutSpaces.charAt(lLeft++);\n            char s2 = strWithoutSpaces.charAt(lRight--);\n            if (s1 != s2)\n                return false;\n        }\n        return true;\n        // o este\n        // return strWithoutSpaces.contentEquals(new\n        // StringBuffer(strWithoutSpaces).reverse());\n    }\n\n    private static boolean isAnagramWithSort(String str1, String str2) {\n        if (str1.length() != str2.length())\n            return false;\n        char[] arr1 = str1.toCharArray();\n        char[] arr2 = str2.toCharArray();\n        Arrays.sort(arr1);\n        Arrays.sort(arr2);\n\n        return Arrays.equals(arr1, arr2);\n    }\n\n    private static boolean isAnagramWithCounting(String str1, String str2) {\n        int CHARACTER_RANGE = 256;\n        if (str1.length() != str2.length())\n            return false;\n        int count[] = new int[CHARACTER_RANGE];\n        for (int i = 0; i < str1.length(); i++) {\n            count[str1.charAt(i)]++;\n            count[str2.charAt(i)]--;\n        }\n        for (int i = 0; i < CHARACTER_RANGE; i++) {\n            if (count[i] != 0) {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    private static boolean isIsogram(String str) {\n        str = str.toLowerCase();\n        int len = str.length();\n\n        char arr[] = str.toCharArray();\n\n        Arrays.sort(arr);\n        for (int i = 0; i < len - 1; i++) {\n            if (arr[i] == arr[i + 1])\n                return false;\n        }\n        return true;\n    }\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/AnaLauDB.java",
    "content": "public class AnaLauraDB {\n    public static void main(String[] args) {\n        String text1 = \"Ana Laura\";\n        String text2 = \"estas repasando logica de programacion\";\n\n        // Concatenar cadenas de caracteres\n        String concatenated = text1 + \" \" + text2;\n        System.out.println(\" \" + concatenated);\n\n        // Obtener la longitud de una cadena\n        int length = concatenated.length();\n        System.out.println(\"La longitud de la cadena es: \" + length);\n\n        // Convertir a mayusculas\n        String upperCase = concatenated.toUpperCase();\n        System.out.println(\"La cadena en mayusculas es: \" + upperCase);\n\n        // Convertir a minusculas\n        String lowerCase = concatenated.toLowerCase();\n        System.out.println(\"La cadena en minusculas es: \" + lowerCase);\n\n        // Reemplazar una subcadena\n        String replaced = concatenated.replace(\"Ana\", \"Ana Lau\");\n        System.out.println(\"La cadena con reemplazo es: \" + replaced);\n\n        // Dividir la cadena en un arreglo de subcadenas\n        String[] split = concatenated.split(\" \");\n        System.out.println(\"La cadena dividida en subcadenas es:\");\n        for (String str : split) {\n            System.out.println(str);\n        }\n\n        // Comparar cadenas si son iguales\n        String anotherText = \"Ana Laura estas repasando Logica de Programacion\";\n        boolean areEqual = concatenated.equals(anotherText);\n        System.out.println(\"Las cadenas son iguales: \" + areEqual);\n        // Comparar cadenas ignorando mayusculas y minusculas\n        boolean areEqualIgnoreCase = concatenated.equalsIgnoreCase(anotherText);\n        System.out.println(\"Las cadenas son iguales (ignorando mayusculas y minusculas):\" + areEqualIgnoreCase);\n\n        // Interpoacion de cadenas\n        String interpolated = String.format(\"Hola %s, %s\", text1, text2);\n        System.out.println(\"Interpoacion de cadenas: \" + interpolated);\n\n        // Verificar si una cadena contiene otra\n        boolean contains = concatenated.contains(\"repasando\");\n        System.out.println(\"La cadena contiene 'repasando': \" + contains);\n\n        // EXTRA\n        // --- Análisis de dos palabras ---\n        String palabra1 = \"amor\";\n        String palabra2 = \"roma\";\n\n        // Palíndromo\n        boolean esPalindromo1 = palabra1.equalsIgnoreCase(new StringBuilder(palabra1).reverse().toString());\n        boolean esPalindromo2 = palabra2.equalsIgnoreCase(new StringBuilder(palabra2).reverse().toString());\n        System.out.println(\"¿'\" + palabra1 + \"' es palíndromo?: \" + esPalindromo1);\n        System.out.println(\"¿'\" + palabra2 + \"' es palíndromo?: \" + esPalindromo2);\n\n        // Anagrama\n        boolean sonAnagramas = sonAnagramas(palabra1, palabra2);\n        System.out.println(\"¿'\" + palabra1 + \"' y '\" + palabra2 + \"' son anagramas?: \" + sonAnagramas);\n\n        // Isograma\n        boolean esIsograma1 = esIsograma(palabra1);\n        boolean esIsograma2 = esIsograma(palabra2);\n        System.out.println(\"¿'\" + palabra1 + \"' es isograma?: \" + esIsograma1);\n        System.out.println(\"¿'\" + palabra2 + \"' es isograma?: \" + esIsograma2);\n    }\n\n    // Función para comprobar anagramas\n    public static boolean sonAnagramas(String w1, String w2) {\n        w1 = w1.replaceAll(\"\\\\s+\", \"\").toLowerCase();\n        w2 = w2.replaceAll(\"\\\\s+\", \"\").toLowerCase();\n        if (w1.length() != w2.length())\n            return false;\n        char[] arr1 = w1.toCharArray();\n        char[] arr2 = w2.toCharArray();\n        java.util.Arrays.sort(arr1);\n        java.util.Arrays.sort(arr2);\n        return java.util.Arrays.equals(arr1, arr2);\n    }\n\n    // Función para comprobar isogramas\n    public static boolean esIsograma(String palabra) {\n        palabra = palabra.toLowerCase();\n        java.util.HashSet<Character> letras = new java.util.HashSet<>();\n        for (char c : palabra.toCharArray()) {\n            if (letras.contains(c))\n                return false;\n            letras.add(c);\n        }\n        return true;\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/AndrewCodev.java",
    "content": "import java.util.*;\n\npublic class AndrewCodev {\n\tpublic static void main(String[] args) {\n\n\t\tAndrewCodev andrewCodev = new AndrewCodev();\n\t\t// CONCATENACIÓN con operador +\n\t\tString cadena1 = \"Andrew\";\n\t\tString cadena2 = \"Codev\";\n\n\t\tSystem.out.println(\"Concatenando: \" + cadena1 + \" + \" + cadena2 + \" = \" + cadena1 + cadena2);\n\n\t\t// OBTENER LONGITUD con length()\n\t\tString cadena3 = cadena1 + cadena2;\n\t\tSystem.out.println(\"La palabra: \" + cadena3 + \" tiene \" + (cadena1 + cadena2).length() + \" caracteres\");\n\n\t\t// Acceder a un caracter indivudual con charAt(0)\n\t\tSystem.out.println(\"La sexta letra de la palabra \" + cadena3 + \" es: \" + cadena3.charAt(5) + \"\\n\");\n\n\t\t// Comparar cadenas de caracteres.\n\t\tString str1 = \"Prueba\";\n\t\tString str2 = \"prueba\";\n\t\tboolean comparar = str1.equals(str2);\n\n\t\tString mensaje = comparar ? str1 + \" y \" + str2 + \": Son iguales\"\n\t\t\t\t: str1 + \" y \" + str2\n\t\t\t\t\t\t+ \": Son diferentes, debido a que equeals() \\nverifica que los caracteres sean exactamente iguales incluyendo las Mayusculas y las Minusculas\";\n\t\tSystem.out.println(mensaje);\n\n\t\tSystem.out.println(\"\\n\");\n\t\tcomparar = str1.equalsIgnoreCase(str2);\n\t\tmensaje = comparar ? str1 + \" y \" + str2\n\t\t\t\t+ \": Son iguales ya que equalsIgnoreCase() solo compara las palabras y omite las Mayusculas y Minusculas\"\n\t\t\t\t: str1 + \" y \" + str2 + \": Son diferentes\";\n\t\tSystem.out.println(mensaje);\n\n\t\tSystem.out.println(\"\\n\");\n\t\tint comparar2 = str1.compareTo(str2);\n\t\tmensaje = comparar2 == 0 ? str1 + \" y \" + str2 + \": Son iguales\"\n\t\t\t\t: str1 + \" y \" + str2\n\t\t\t\t\t\t+ \": Son diferentes, debido a que compareTo() \\nverifica que los caracteres sean exactamente iguales \\nincluyendo las Mayusculas y las Minusculas y nos da como resultado un número negativo: \"\n\t\t\t\t\t\t+ comparar2;\n\t\tSystem.out.println(mensaje);\n\n\t\tSystem.out.println(\"\\n\");\n\t\tcomparar2 = str1.compareToIgnoreCase(str2);\n\t\tmensaje = comparar2 == 0 ? str1 + \" y \" + str2\n\t\t\t\t+ \": Son iguales ya que compareToIgnoreCase() solo compara las palabras y omite las Mayusculas y Minusculas\"\n\t\t\t\t: str1 + \" y \" + str2 + \": Son diferentes\";\n\t\tSystem.out.println(mensaje);\n\n\t\t// SUBCADENA\n\t\tstr1 = \"Hola mundo\";\n\t\tString subcadena = str1.substring(5);\n\t\tSystem.out.println(\"La subcadena es: \" + subcadena);\n\n\t\tString criterio = \"mundo\";\n\n\t\t// BUSQUEDA DE SUBCADENAS\n\t\tint indice = str1.indexOf(criterio); // indice será 5\n\t\tboolean contiene = str1.contains(criterio); // contiene será true\n\n\t\tSystem.out.println(\"\\nEl indice es: \" + indice + \" y \" + (contiene ? \"Contiene la palabra buscada: \" + criterio\n\t\t\t\t: \"No contiene la palabra buscada: \" + criterio));\n\n\t\t// MODIFICAR CADENA str1.replace(\n\t\tSystem.out.println(\"\\nLa palabra: \" + str1 + \" se ha modificado por: \" + str1.replace(str1, cadena3));\n\n\t\t// MAYUSCULAS Y MINISCULAS\n\n\t\tSystem.out.println(\"Todo en MAYUSCULAS: \" + str1.toUpperCase());\n\t\tSystem.out.println(\"Todo en minusculas: \" + str1.toLowerCase());\n\n\t\t// DIFICULTAD EXTRA\n\t\tSystem.out.println(\"\\nDIFICULTAD EXTRA\\n\");\n\n\t\t// Verificando si las palabras son palindromos o no\n\t\tString palabra1 = \"amor\";\n\t\tSystem.out.println(andrewCodev.isPalindromo(palabra1));\n\t\tString palabra2 = \"remar\";\n\t\tSystem.out.println(andrewCodev.isPalindromo(palabra2));\n\n\t\t// Verificando si ambas palabras son Anagramas\n\t\tSystem.out.println(andrewCodev.sonAnagramas(palabra1, palabra2));\n\n\t\t// Verificando si es Isograma\n\t\tSystem.out.println(andrewCodev.isIsograma(palabra1));\n\t\tSystem.out.println(andrewCodev.isIsograma(palabra2));\n\n\t}\n\n\tpublic String isPalindromo(String palabra) {\n\t\tint contCaracteres = palabra.length();\n\t\tint posicionLetra = contCaracteres - 1;\n\t\tString mensaje = \"\";\n\t\tString compararPalabra = \"\";\n\n\t\tfor (int j = 0; j < contCaracteres; j++) {\n\t\t\tcompararPalabra = compararPalabra + palabra.charAt(posicionLetra);\n\t\t\tposicionLetra--;\n\t\t}\n\n\t\t// Comprobando si la palabra es un palindromo\n\t\tif (palabra.equalsIgnoreCase(compararPalabra)) {\n\t\t\tmensaje = \"La palabra: \" + palabra + \" es un palindromo\";\n\t\t} else {\n\t\t\tmensaje = \"La palabra: \" + palabra + \" no es un palindromo\";\n\t\t}\n\n\t\treturn mensaje;\n\t}\n\n\tpublic String sonAnagramas(String palabra1, String palabra2) {\n\t\tString mensaje = \"\";\n\t\t// Convertimos las palabras en arrys de caracteres\n\t\tchar[] arregloPalabra1 = palabra1.replaceAll(\"[\\\\s]\", \"\").toLowerCase().toCharArray();\n\t\tchar[] arregloPalabra2 = palabra2.replaceAll(\"[\\\\s]\", \"\").toLowerCase().toCharArray();\n\n\t\t// ordenamos los arrays\n\t\tArrays.sort(arregloPalabra1);\n\t\tArrays.sort(arregloPalabra2);\n\n\t\tif (Arrays.equals(arregloPalabra1, arregloPalabra2)) {\n\t\t\tmensaje = palabra1 + \" y \" + palabra2 + \" son anagramas.\";\n\t\t} else {\n\t\t\tmensaje = palabra1 + \" y \" + palabra2 + \" no son anagramas.\";\n\t\t}\n\t\treturn mensaje;\n\t}\n\n\tpublic String isIsograma(String palabra) {\n\t\tString mensaje = \"\";\n\t\tboolean isorama = true;\n\t\tSet<Character> caracteres = new HashSet<>();\n\n\t\tfor (char c : palabra.toCharArray()) {\n\t\t\tif (!caracteres.add(c)) {\n\t\t\t\tisorama = false;\n\t\t\t}\n\t\t}\n\n\t\tif (isorama) {\n\t\t\tSystem.out.println(\"La palabra \" + palabra + \" es un Isorama\");\n\t\t} else {\n\t\t\tSystem.out.println(\"La palabra \" + palabra + \" no es un Isorama\");\n\t\t}\n\n\t\treturn mensaje;\n\t}\n}\n\n/*\n * EJERCICIO: Muestra ejemplos de todas las operaciones que puedes realizar con\n * cadenas de caracteres en tu lenguaje. Algunas de esas operaciones podrían ser\n * (busca todas las que puedas): - Acceso a caracteres específicos, subcadenas,\n * longitud, concatenación, repetición, recorrido, conversión a mayúsculas y\n * minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional): Crea un programa que analice dos palabras\n * diferentes y realice comprobaciones para descubrir si son: - Palíndromos -\n * Anagramas - Isogramas\n */"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/DanielBelenguer.java",
    "content": "import java.util.Arrays;\n\npublic class DanielBelenguer {\n/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\n *   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\n *   interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\npublic static void main(String[] args) {\n    \n    // Creación de cadenas de caracteres\n    String cadena = \"Hola\";\n\n    // Acceso a los caracteres específicos\n    System.out.println(cadena.charAt(0)); // H\n    System.out.println(cadena.charAt(2)); // l\n\n    // Concatenación o unión\n    String cadena2 = \" Mundo!\";\n    cadena = cadena.concat(cadena2);\n\n    System.out.println(cadena); // Hola Mundo!\n\n    // Repetición\n    System.out.println(cadena.repeat(3)); // Hola Mundo!Hola Mundo!Hola Mundo!\n\n    // Subcadenas\n    System.out.println(cadena); // Esta es la cadena que partimos y vamos a separarla en 2 subcadenas\n\n    String subcadena1 = cadena.substring(0, 4); \n    String subcadena2 = cadena.substring(5, 11);\n\n    System.out.println(\"Subcadena 1: \" + subcadena1);\n    System.out.println(\"Subcadena 2: \" + subcadena2);\n\n    // Longitud\n    int longitud = cadena.length();\n    System.out.println(\"Longitud de la cadena: \" + longitud);\n\n    // Recorrido\n    \n    for (int i = 0; i < cadena.length(); i++) {\n        System.out.println(cadena.charAt(i));\n    }\n\n    int sizecadena = 0;\n    while (sizecadena < cadena.length()) {\n        System.out.println(cadena.charAt(sizecadena));\n        sizecadena++;\n    }\n\n    for (char caracter : cadena.toCharArray()) {\n        System.out.println(caracter);   \n        \n    }\n\n    // Conversión a mayúsculas y minúsculas\n\n    System.out.println(cadena.toUpperCase());\n\n    System.out.println(cadena.toLowerCase());\n\n    // Reemplazo\n    System.out.println(cadena.replace(\"Hola\", \"Adios\"));\n\n    // División\n    String[] palabras = cadena.split(\" \");\n    for (String palabra : palabras) {\n        System.out.println(palabra);\n    } /* Con esto lo que conseguimos es separar por el espacio en blanco, si quieres separar por otra cosa, solo tienes que cambiar \n        el argumento del método split */\n\n    // Interpolación\n        String nombre = \"Daniel\";\n        int edad = 35;\n        String mensaje = String.format (\"Hola, mi nombre es %s y tengo %d años\", nombre, edad);\n        System.out.println(mensaje);\n\n    // Verificación\n    \n    System.out.println(cadena.contains(\"Hola\")); // true\n    System.out.println(cadena.contains(\"Adios\")); // false\n\n\n    // Ejercicio extra\n\n    String palabra1 = \"arroz\";\n    String palabra2 = \"zorra\";\n\n    // Comprobacion si son Palíndromos\n    if (palabra2.equals(new StringBuilder(palabra1).reverse().toString())) {\n        System.out.println(\"La palabra \" + palabra1 + \" es un palíndromo\");\n    } else {\n        System.out.println(\"La palabra \" + palabra1 + \" no es un palíndromo\");\n    }\n\n    // Comprobacion si son Anagramas\n    if (palabra1.length() == palabra2.length()) {\n        char[] palabra1Array = palabra1.toCharArray();\n        char[] palabra2Array = palabra2.toCharArray();\n        Arrays.sort(palabra1Array);\n        Arrays.sort(palabra2Array);\n        if (Arrays.equals(palabra1Array, palabra2Array)) {\n            System.out.println(\"Las palabras \" + palabra1 + \" y \" + palabra2 + \" son anagramas\");\n        } else {\n            System.out.println(\"Las palabras \" + palabra1 + \" y \" + palabra2 + \" no son anagramas\");\n        }\n    } else {\n        System.out.println(\"Las palabras \" + palabra1 + \" y \" + palabra2 + \" no son anagramas\");\n    }\n\n    // Comprobacion si son Isogramas\n    boolean isIsograma = true;\n    for (int i = 0; i < palabra1.length(); i++) {\n        for (int j = i + 1; j < palabra1.length(); j++) {\n            if (palabra1.charAt(i) == palabra1.charAt(j)) {\n                isIsograma = false;\n                break;\n            }\n        }\n    }\n    System.out.println(isIsograma ? \"La palabra \" + palabra1 + \" es un isograma\" : \"La palabra \" + palabra1 + \" no es un isograma\");\n\n\n\n\n}\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/DiegoIBB.java",
    "content": "package Cadena_de_Caracteres_04;\nimport java.util.ArrayList;\nimport java.util.Scanner;\nimport java.util.Dictionary;\nimport java.util.HashMap;\nimport java.util.Hashtable;\n\n\n/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\n\npublic class Cadena_de_Caracteres {\n\n\tpublic static void main(String[]args) {\n\t\t\n\t\t//OPERACIONES BASICAS\n\t\t\n\t\t// Concatenar\n\t\tString string_1 = \"cadena 1\";\n\t\tString string_2 = \"cadena 2\";\n\t\tString string_3 = \" segundo elemento\";\n\n\t\tSystem.out.println(string_1 + \" más \" + string_2);\n\t\tSystem.out.println(string_1.concat(string_3)); // Método CONCAT\n\t\t\n\t\t//Indexar\n\t\tString string_4 = \"elemento\";\n\t\tSystem.out.println(string_4.indexOf(\"m\"));//Por caracter\n\t\t\n\t\t\n\t\t\n\t\t// METODOS ESPECIALES\n\t\t\n\t\tString cadena_1 = \"Hola mundo\";\n\t\tString cadena_2 = \"HELLO\";\n\t\tString cadena_3 = \"MINUSCULAS\";\n\t\tString cadena_4 = \"mayusculas\";\n\t\tString cadena_5 = \"Esta es una cadena\";\n\t\tString cadena_6 = \"Caracter\";\n\t\tString cadena_7 = \"Listado de caracteres\";\n\t\t\n\t\t//Método charAt, retorna un carácter a partir de un indice\n \t\tSystem.out.println(\"---- METODO CHAR AT ----\");\n\t\tSystem.out.println(cadena_1.charAt(3));\n\n\t\t//Método Length cuenta la cantidad de caracteres de una string\n \t\tSystem.out.println(\"---- METODO LENGTH ----\");\n\t\tSystem.out.println(cadena_1.length());\n\t\t\n\t\t//Método Replace cuenta la cantidad de caracteres de una string\n \t\tSystem.out.println(\"---- METODO REPLACE ----\");\n\t\tSystem.out.println(cadena_2.replace(\"L\", \"R\"));\n\t\t\n\t\t//Método ToLowerCase convierte los caracteres en mayusculas a minusculas\n \t\tSystem.out.println(\"---- METODO LOWERCASE ----\");\n \t\tSystem.out.println(cadena_3.toLowerCase());\n\n\t\t//Método ToUperCase convierte los caracteres en minusculas a mayusculas\n \t\tSystem.out.println(\"---- METODO UPPERCASE ----\");\n \t\tSystem.out.println(cadena_4.toUpperCase());\n \t\t\n \t\t//Método Split, convierte una cadena en unas serie de subcadenas en formato array\n \t\tSystem.out.println(\"---- METODO SPLIT ----\");\n \t\tString [] split_1 = cadena_5.split(\" \"); //Creamos un array y dividimos la cadena a partir de un caracter espacio(\" \")\n \t\tString part_1 = split_1[1]; // Podemos guardar los valores del array en variables\n \t\t\n \t\tSystem.out.println(split_1[0]);\n \t\tSystem.out.println(part_1);\n \t\tSystem.out.println(split_1[2]);\n \t\tSystem.out.println(split_1[3]);\n\n \t\t//Metodo endsWith, nos permite saber si una cadena termina con uno o varios caracteres especificos, devuelve true o false\n \t\tSystem.out.println(\"---- METODO ENDSWITH ----\");\n \t\tSystem.out.println(cadena_6.endsWith(\"Cara\"));\n \t\tSystem.out.println(cadena_6.endsWith(\"ter\"));\n \t\tSystem.out.println(cadena_6.endsWith(\"r\"));\n \t\t\n \t\t//Metodo startsWith, a diferencia de endsWith nos permite saber si una cadena empieza con uno o varios caracteres especificos\n \t\tSystem.out.println(\"---- METODO STARTSWITH ----\");\n \t\tSystem.out.println(cadena_6.startsWith(\"Car\"));\n \t\tSystem.out.println(cadena_6.startsWith(\"ter\"));\n \t\tSystem.out.println(cadena_6.startsWith(\"C\"));\n \t\t\n \t\t//Metodo getChars, junta un grupo de caracteres en un array \n\t\tchar[] ch = new char[7]; //En la declaración del array especificamos la cantidad de caracteres si la string tiene más se muestran espacios en blanco\n \t\tcadena_7.getChars(0, 7, ch, 0); // (caracte-inicial, caracter-final, array, desfase)\n \t\tSystem.out.println(ch);\n \t\t\n \t\t\n\t\t// OPERACIONES\n \t\t\n \t\t//Reversa a una cadena, invertimos el orden de una cadena\n \t\tSystem.out.println(\"-------- OPERACION REVERSA -------\");\n \t\tString cadenaOriginal = \"Cadena al reves\";\n \t\tString cadenaReversa = \"\";\n \t\t\n \t\tfor (int i = 0; i < cadenaOriginal.length(); i++) {\n \t\t\tSystem.out.println(cadenaOriginal.charAt(i));\n \t\t\tcadenaReversa = cadenaOriginal.charAt(i) + cadenaReversa;\n \t\t}\n \t\tSystem.out.println(cadenaReversa);\n \t\t\n \t\t\n \t\t/*\n \t\t* DIFICULTAD EXTRA (opcional):\n \t\t* Crea un programa que analice dos palabras diferentes y realice comprobaciones\n \t\t* para descubrir si son:\n \t\t* - Palíndromos\n \t\t* - Anagramas\n \t\t* - Isogramas\n \t\t*/\n \t\t\n \t\t// ---------- PALINDROMO ---------\n \t\tScanner palindromo = new Scanner(System.in);\n \t\tSystem.out.println(\"Frase:\");\n \t\tString palindromo_1 = palindromo.nextLine();\n \t\tString frase_reves = \"\";\n \t\tString frase_sinEspacios = \"\";\n \t\t\n \t\t//Pasamos todas las letras a minusculas\n \t\tString palindromo_op = palindromo_1.toLowerCase();\n \t\t\n \t\t//Invierte la frase\n \t\tfor (int l=0; l < palindromo_op.length(); l++) {\n \t\t\tif (palindromo_1.charAt(l) == ' ') {\n \t\t\t\tcontinue;\n \t\t\t}else if (palindromo_op.charAt(l) != ' ') {\n \t\t\t\tfrase_reves = palindromo_op.charAt(l) + frase_reves;\n \t\t\t}\n \t\t}\n \t\t\n \t\t//Frase original sin espacios (invertimos la frase que ya habiamos invertido, esta vez sin espacios)\n \t\tfor (int s=0; s < frase_reves.length(); s++){\n \t\t\tfrase_sinEspacios = frase_reves.charAt(s) + frase_sinEspacios;\n \t\t}\n \t\t\n \t\t\n \t\tSystem.out.println(palindromo_op);\n \t\tSystem.out.println(frase_sinEspacios);\n \t\tSystem.out.println(frase_reves);\n \t\t\n\t\tif (frase_sinEspacios.equals(frase_reves)) { //CUANDO QUEREMOS COMPARAR EL CONTENIDO DE 2 CADENAS DEBEMOS USAR EL METODO EQUALS()\n \t\t\tSystem.out.println(\"La frase es un palindromo\");\n \t\t}else {\n \t\t\tSystem.out.println(\"La frase no es un palindromo \");\n \t\t}\n\t\t\n\t\t/* Si hacemos una comparación tradicional \"if(cadena_1 == cadena_2)\"\n\t\t * lo que estamos haciendo es comparar si la instancia es la misma,\n\t\t * sin embargo la instancia no es la misma\n\t\t * \n\t\t * (instancia) String frase_reves es distinto a (instancia) String palindromo_1 \n\t\t * \n\t\t * la forma correcta de evaluar si el contenido de 2 cadenas es el mismo es por medio del\n\t\t * método equals()\n\t\t * \n\t\t * */\n\t\t\t\t\n \t\t// ---------- ANAGRAMA ---------\n\t\t\t\t\n\t\t//Entregar 2 palabras y ver si una es un anagrama de la otra\n\t\t\n\t\t//Entrada de palabras\n\t\tScanner palabra_1 = new Scanner(System.in);\n\t\tSystem.out.println(\"Palabra 1: \");\n\t\tString word_1 = palabra_1.nextLine();\n\t\t\n\t\tScanner palabra_2 = new Scanner(System.in);\n\t\tSystem.out.println(\"Palabra 2: \");\n\t\tString word_2 = palabra_2.nextLine();\n\t\t\n\t\tanagrama(word_1, word_2);\n\n \t\t// ---------- ISOGRAMA ---------\n\t\t\n\t\tScanner palabra_3 = new Scanner(System.in);\n\t\tSystem.out.println(\"Palabra 3: \");\n\t\tString word_3 = palabra_3.nextLine();\n\t\t\n\t\t\n\t\tSystem.out.println(isograma(word_3));\n\t\t\n\t\t\n\t\tScanner palabra_4 = new Scanner(System.in);\n\t\tSystem.out.println(\"Palabra 4: \");\n\t\tString word_4 = palabra_4.nextLine();\n\t\t\n\t\tSystem.out.println(isograma_2(word_4));\n\t\t\n\t}\n\t\n\tpublic static String anagrama(String cadena_1, String cadena_2) {\n\t\t\n\t\tString cadena_1_toLow;\n\t\tString cadena_2_toLow;\n\t\t\n\t\t//Convertimos las cadenas originales a minusculas\n\t\tcadena_1_toLow = cadena_1.toLowerCase(); //Guardamos la primera cadena con todos los caracteres en  minusculas\n\t\tcadena_2_toLow = cadena_2.toLowerCase(); //Guardamos la segunda cadena con todos los caracteres en  minusculas\n\n\t\t//Obtenemos el largo de cada cadena\n\t\tint cadena_1len = cadena_1.length();\n\t\tint cadena_2len = cadena_2.length();\n\t\tint counter = 0;\n\t\tint charCounter = 0;\n\t\t\n\t\tArrayList<Character> letra_cadena_1 = new ArrayList<Character>();\n\t\tArrayList<Character> letra_cadena_2 = new ArrayList<Character>();\n\t\t\n\t\tfor(int c=0; c < cadena_1len; c++) { //Para añadir caracteres de la primera palabra en una lista\n\t\t\tletra_cadena_1.add(cadena_1_toLow.charAt(c));\n\t\t}\n\t\tfor(int d = 0; d < cadena_2len; d++) { //Para añadir caracteres de la segunda palabra en una lista\n\t\t\tletra_cadena_2.add(cadena_2_toLow.charAt(d));\n\t\t}\n\t\t\n\t\t//Recorremos la segunda cadena a partir de cada caracter de la primera cadena\n\t\tif(cadena_1len == cadena_2len){\n\t\t\tfor(int e = 0; e < cadena_1len; e++) {\n\t\t\t\tcharCounter = 0;\n\t\t\t\tfor(int f = 0; f < cadena_2len; f++) {\n\t\t\t\t\tif(cadena_1_toLow.charAt(e) == cadena_2_toLow.charAt(f)) {\n\t\t\t\t\t\t//System.out.println(\"Element \" + cadena_1_toLow.charAt(e) + \" is in both strings\");\n\t\t\t\t\t\tcharCounter += 1;\n\t\t\t\t\t\tcounter += 1;\n\t\t\t\t\t\t//Esta sección reduce en 1 el contador si se repite más de una vez //Resolver que no se repita la impresión del mismo caracater 2 veces\n\t\t\t\t\t\tif(charCounter > 1) {\n\t\t\t\t\t\t\tcounter -= 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tSystem.out.println(\"Element \" + cadena_1_toLow.charAt(e) + \" is in both strings\");\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\t\n\t\t\t\t}\n\t\t\t\t//System.out.println(charCounter);\n\t\t\t}\n\t\t\t\n\t\t\t//Establecemos que 2 palabras son anagramas si tienen los mismos caracteres\n\t\t\t\n\t\t\tif (counter == cadena_1len) {\n\t\t\t\tSystem.out.println(\"The strings are anagrams\");\n\t\t\t}else {\n\t\t\t\tSystem.out.println(\"The strings are not anagramas\");\n\t\t\t}\n\t\t}else {\n\t\t\tSystem.out.println(\"The strings are not anagramas\");\n\t\t}\n\t\t\n\t\tSystem.out.println(\"Length of both strings: \" + cadena_1len + \" and \" + cadena_2len); \n\t\tSystem.out.println(\"Characters that coincide: \" + cadena_1len + \" and \" + counter); //Counter difiere del largo de la primera cadena si hay caracteres repetidos\n\n\t\t\n\t\treturn \"La palabra es un anagrama\";\n\t}\n\t\n\t\n\t\t// ---------- ISOGRAMA ---------\n\n\t//Entregar 1 palabra y ver si se repiten la misma cantidad de veces cada una de sus letras\n\t\n\t//Señalamos que el resultado a retornar es un Diccionario\n\tpublic static Dictionary isograma(String cadena_3) {\n\t\tString cadena_3_low;\n\t\tcadena_3_low = cadena_3.toLowerCase();\n\t\t\n\t\tDictionary<Character, Integer> dictCaracteres = new Hashtable<>();\n\t\t\n\t\tfor(int i=0; i < cadena_3_low.length(); i++) {\n\t\t\t\tdictCaracteres.put(cadena_3_low.charAt(i), 1);\n\t\t}\n\t\t\n\t\treturn dictCaracteres;\n\t}\n\t\n\t\n\t//Señalamos que el resultado a retornar es un HashMap\n\n\tpublic static HashMap isograma_2(String cadena_3) {\n\t\tString cadena_4_low;\n\t\tcadena_4_low = cadena_3.toLowerCase();\n\t\t\n\t\tHashMap<Character, Integer> hashMapCaracteres = new HashMap<>();\n\t\t\n\t\tfor(int i=0; i < cadena_4_low.length(); i++) {\n\t\t\tfor(int e=0; e < cadena_4_low.length(); e++) {\n\t\t\t\tif(cadena_4_low.charAt(i) == hashMapCaracteres.get(e)) {\n\t\t\t\t\thashMapCaracteres.put(cadena_4_low.charAt(i), 1);\n\t\t\t\t}else {\n\t\t\t\t\thashMapCaracteres.put(cadena_4_low.charAt(i), 2);\n\t\t\t\t}\n\t\t\t}\n\t\t\t//hashMapCaracteres.put(cadena_4_low.charAt(i), 1);\n//\t\t\tif(cadena_4_low.charAt(i) == hashMapCaracteres.get(cadena_4_low.charAt(i))) { //Buscar método que verifique que un elemento está en el diccionario\n//\t\t\t\thashMapCaracteres.put(cadena_4_low.charAt(i), 1);\n//\t\t\t}\n\t\t}\n\t\t\n\t\treturn hashMapCaracteres;\n\t}\n\t\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/FranDev200.java",
    "content": "import java.util.Arrays;\nimport java.util.Scanner;\n\npublic class FranDev200 {\n\n    static void main() {\n    /*\n        Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n        en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n        - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n        conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n\n     */\n\n        String string = \"Hola, Java!\";\n\n        System.out.println(\"Mayusculas: \" + string.toUpperCase());\n        System.out.println(\"Minusculas: \" + string.toLowerCase());\n        System.out.println(\"Caracter de la posicion 5: \" + string.charAt(5)); // Espacio en blanco\n        System.out.println(\"Caracter de la posicion 0: \" + string.charAt(0));\n        System.out.println(\"Comparacion ignorando mayusculas y minusculas: \" + string.equalsIgnoreCase(\"Hola, java!\"));\n        System.out.println(\"Comparacion contando mayusculas y minusculas: \" + string.equals(\"Hola, java!\"));\n        System.out.println(\"Concatenacion: \" + string.concat(\". Adios, Python!\") );\n        System.out.println(\"¿Contiene \\\"ol\\\"?: \" + string.contains(\"ol\"));\n        System.out.println(\"¿Contiene \\\"java\\\"?: \" + string.contains(\"java\"));\n        System.out.println(\"Acaba en \\\"Java\\\": \" + string.endsWith(\"Java\"));\n        System.out.println(\"Posicion de la letra 'a': \" + string.indexOf('a'));\n        System.out.println(\"¿Está en blanco?: \" + string.isBlank());\n        string = \" \";\n        System.out.println(\"¿Está vacío?: \" + string.isEmpty()); // Los espacios cuentan como contenido, asi que no esta vacio.\n        string = \"Hola, Java!\";\n        System.out.println(\"Cuantos caracteres tiene: \" + string.length());\n        System.out.println(\"Repetir la cadena: \" + string.repeat(3));\n        System.out.println(\"Remplazar caracteres: \" + string.replace(\"a\", \"o\"));\n        System.out.println(\"Pasar una cadena a array: \" + Arrays.stream(string.split(\",\")).toList());\n        System.out.println(\"Caracteres entre la posicion 3 y 7: \" + string.substring(3, 7));\n        string = \"   Hola, Java!        \";\n        System.out.println(string);\n        System.out.println(string.trim()); // Elimina los espacios al principio y final de la cadena\n        string = string.trim();\n        System.out.println(\"¿Empieza por \\\"h\\\"?: \" + string.startsWith(\"h\"));\n        System.out.println(\"¿Empieza por \\\"Ho\\\"?: \" + string.startsWith(\"Ho\"));\n\n        /*\n            DIFICULTAD EXTRA (opcional):\n            Crea un programa que analice dos palabras diferentes y realice comprobaciones\n            para descubrir si son:\n            - Palíndromos\n            - Anagramas\n            - Isogramas\n         */\n\n        Scanner scan = new Scanner(System.in);\n        System.out.print(\"Introduce la primera palabra: \");\n        String word1 = scan.nextLine();\n        System.out.print(\"Introduce la segunda palabra: \");\n        String word2 = scan.nextLine();\n\n        System.out.println(\"¿Las palabras introducidas son palíndromos?: \");\n        System.out.println(word1 + \": \" + palindromo(word1));\n        System.out.println(word2 + \": \" + palindromo(word2));\n        System.out.println(\"¿Las palabras introducidas son anagramas?: \");\n        System.out.println(anagrama(word1, word2));\n        System.out.println(\"¿Las palabras introducidas son isogramas?: \");\n        System.out.println(word1 + \": \" + isograma(word1));\n        System.out.println(word2 + \": \" + isograma(word2));\n\n    }\n\n    public static boolean palindromo(String word){\n\n        boolean result = false;\n        char[] charSequence = word.toLowerCase().toCharArray();\n        for(int i = charSequence.length - 1, j = 0; i >= 0; i--, j++){\n            if(charSequence[i] == charSequence[j]){\n                result = true;\n            }else {\n                result = false;\n                break;\n            }\n        }\n        return result;\n    }\n\n    public static boolean anagrama(String word1, String word2){\n\n        if(word1.length() != word2.length()){\n            return false;\n        }\n\n        boolean result = false;\n\n        for(int i = 0; i < word1.length(); i++){\n            for(int j = 0; j < word2.length(); j++){\n                if(word1.toLowerCase().charAt(i) == word2.toLowerCase().charAt(j)){\n                    result = true;\n                    break;\n                }else{\n                    result = false;\n                }\n            }\n\n            if(result == false){\n                break;\n            }\n\n        }\n        return result;\n\n    }\n\n    public static boolean isograma(String word){\n        boolean result = false;\n        int letterCounter = 0;\n        char[] charSequence = word.toLowerCase().toCharArray();\n        char[] charSequence2 = word.toLowerCase().toCharArray();\n        for(int i = 0; i < charSequence.length; i++){\n            letterCounter = 0;\n            for (int j = 0; j < charSequence2.length; j++){\n\n                if(word.toLowerCase().charAt(j) == charSequence[i]){\n                    letterCounter++;\n                }\n\n            }\n\n            if(letterCounter == 1){\n                result = true;\n            }else if( letterCounter > 1){\n                result = false;\n                break;\n            }else{\n                result = false;\n            }\n\n        }\n        return result;\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/Gerthai08.java",
    "content": "import java.util.Arrays;\nimport java.util.Scanner;\n\npublic class Gerthai08 {\n    public static void main(String[] args) {\n\n        //Motrar una cadena de texto\n        System.out.println(\"=====Cadena de texto=====\");\n        String texto = \"Hola, esto es una Cadena de texto\";\n        System.out.println(texto);\n\n        //Concatenación\n        System.out.println(\"=====Concatenación de textos=====\");\n        String concatenacion = \" , estoy programando con java\";\n        System.out.println(texto + concatenacion);\n        System.out.println(texto.concat(concatenacion)); //Método para concatenar\n\n        //Longitud de una cadena\n        System.out.println(\"=====Longitud de la cadena de texto=====\");\n        String txt = \"abcdefghijklmnopq\";\n        System.out.println(\"La longitud del texto es de: \" + txt.length());\n\n        //Texto en mayúsculas y en minúsculas\n        System.out.println(\"=====Texto en mayúsculas=====\");\n        System.out.println(txt.toUpperCase());\n        System.out.println(\"=====Texto en minúsculas=====\");\n        System.out.println(txt.toLowerCase());\n\n        //Encontrar la posición de la palabra que quiero buscar\n        System.out.println(\"=====Buscar palabra por indice=====\");\n        System.out.println(texto.indexOf(\"Cadena\")); //tiene que dar como resultado el índice donde empieza la palabra asignada\n\n        //Caracteres especiales\n        System.out.println(\"=====Asignar comillas dobles=====\");\n        System.out.println(\"Somos los llamados \\\"Vikingos\\\" del norte\"); //la barra invertida se coloca antes para asignar la comilla doble\n        System.out.println(\"=====Asignar comillas simples=====\");\n        System.out.println(\"Somos los llamados \\'Vikingos\\' del norte\");\n        System.out.println(\"=====Asignar comillas Barra invertida=====\");\n        System.out.println(\"Somos los llamados \\\\Vikingos\\\\ del norte\");\n        System.out.println(\"=====Asignar salto de linea=====\");\n        System.out.println(\"Aplicando salto de \\nlinea\");\n        System.out.println(\"=====Asignar retorno de carro=====\");\n        System.out.println(\"Hola \\rMundo\"); //Tiene que retornar solamente la palabra \"Mundo\", ya que el cursor vuelve al inicio\n        System.out.println(\"=====Asignar tabulador=====\");\n        System.out.println(\"Hola \\tMundo\");\n        System.out.println(\"=====Borrar una letra=====\");\n        System.out.println(\"Hol\\ba Mund\\bo\");\n        System.out.println(\"=====Asignar salto de pagina=====\");\n        System.out.println(\"Hola \\fMundo\");\n\n        //subcadenas\n        System.out.println(\"=====Subcadena sin argumento \\\"FINAL\\\"=====\");\n        System.out.println(texto.substring(6));\n        System.out.println(\"=====Subcadena con argumento \\\"FINAL\\\"=====\");\n        System.out.println(texto.substring(6, 24));\n\n        //repetición\n        System.out.println(\"=====Repetición de texto=====\");\n        System.out.println((texto + \"\\n\").repeat(3));\n\n        //acceso a un carácter desde una posición específica\n        System.out.println(\"=====Traer carácter desde una posición especifica=====\");\n        System.out.println(texto.charAt(3));\n\n        //Recorrido\n        System.out.println(\"=====Recorrido de texto=====\");\n        for (int i = 0; i < txt.length(); i++) {\n            System.out.println(txt.charAt(i));\n        }\n\n        //reemplazo+\n        System.out.println(\"=====Reemplazando=====\");\n        System.out.println(texto.replace(\"Hola\", \"Bienvenidos\"));\n\n        //división\n        String division = \"rojo,verde,azul,amarillo\";\n        System.out.println(\"=====División por comas=====\");\n        String[] colores = division.split(\",\");\n        for (String c : colores) {\n            System.out.println(c);\n        }\n\n        System.out.println(\"=====División por espacios=====\");\n        String[] espacios = texto.split(\" \");\n        for (String p : espacios){\n            System.out.println(p);\n        }\n\n        //union (join)\n        System.out.println(\"=====Método de union=====\");\n        String join = String.join(\" \", \"Juan\", \"Pedro\", \"Homar\");\n        System.out.println(join);\n\n        //Interpolación\n        System.out.println(\"=====Implementando la interpolación=====\");\n        String interpolacion = \"Hola %s! Estamos en el %,d\";\n        System.out.println(String.format(interpolacion,\"Mundo\",2025));\n\n        //Verificación\n        String texto1 = \"Hola\";\n        String texto2 = \"hola\";\n        String texto3 = \" \";\n        String texto4 = \"Ejemplo de texto\";\n\n        System.out.println(\"=====Metodo de verificación \\\"equals\\\"=====\");\n        System.out.println(\"Equals: \" + texto1.equals(texto2)); //false\n\n        System.out.println(\"=====Metodo de verificación \\\"equalsIgnoreCase\\\"=====\");\n        System.out.println(\"EqualsIgnoreCase: \" + texto1.equalsIgnoreCase(texto2)); //true\n\n        System.out.println(\"=====Metodo de verificación \\\"contains\\\"=====\");\n        System.out.println(\"Contains: \" + texto4.contains(\"tex\")); //true\n\n        System.out.println(\"=====Metodo de verificación \\\"startsWith\\\"=====\");\n        System.out.println(\"startsWith: \" + texto4.startsWith(\"Eje\")); //true\n\n        System.out.println(\"=====Metodo de verificación \\\"isEmpty\\\"=====\");\n        System.out.println(\"isEmpty: \" + \"\".isEmpty()); //true\n\n        System.out.println(\"=====Metodo de verificación \\\"isBlank\\\"=====\");\n        System.out.println(\"isBlank: \" + texto3.isBlank()); //true\n\n        //Ejercicio opcional\n        extra();\n\n    }\n    public static void extra(){\n        Scanner scanner = new Scanner(System.in);\n        boolean running = true;\n\n        System.out.println(\"¡Bienvenidos al juego de las palabras!\");\n\n        while (running){\n            System.out.println(\"\\nElige como quieres analizar la palabra\");\n            System.out.println(\"1. Palíndromo\");\n            System.out.println(\"2. Anagrama\");\n            System.out.println(\"3. Isograma\");\n            System.out.println(\"4. Salir\");\n            System.out.println(\"Selecciona una opción: \");\n\n            String option = scanner.nextLine().trim();\n\n            switch (option){\n                case \"1\":\n                    isPalindrome(scanner);\n                    break;\n                case \"2\":\n                    isAnagram(scanner);\n                    break;\n                case \"3\":\n                    isIsogram(scanner);\n                    break;\n                case \"4\":\n                    running = false;\n                    System.out.println(\"¡Hasta la próxima!\");\n                    break;\n                default:\n                    System.out.println(\"Opción no valida, intentalo de nuevo.\");\n            }\n        }\n        scanner.close();\n    }\n\n    private static void isIsogram(Scanner scanner) {\n        String palabra = pedirDato(scanner, \"Ingrese la palabra a analizar: \").toLowerCase().replaceAll(\"\\\\s+\", \"\");\n\n        boolean Isogram = true;\n\n        for (int i = 0; i < palabra.length(); i++) {\n            char letra = palabra.charAt(i);\n            //Si la letra a parece mas de una vez\n            if(palabra.indexOf(letra) != palabra.lastIndexOf(letra)){\n                Isogram = false;\n                break;\n            }\n        }\n        if (Isogram){\n            System.out.println(\"La palabra analizada es un Isograma\");\n        }else{\n            System.out.println(\"La palabra analizada no es un Isograma\");\n        }\n    }\n\n    private static void isAnagram(Scanner scanner) {\n        //Pedimos las dos palabras\n        String palabra1 = pedirDato(scanner,\"Ingrese la primer palabra: \").toLowerCase().replaceAll(\"\\\\s+\", \"\");\n        String palabra2 = pedirDato(scanner,\"Ingrese la segunda palabra: \").toLowerCase().replaceAll(\"\\\\s+\", \"\");;\n\n        //Convertimos a array de caracteres\n        char[] array1 = palabra1.toCharArray();\n        char[] array2 = palabra2.toCharArray();\n\n        //Ordenamos los arrays\n        Arrays.sort(array1);\n        Arrays.sort(array2);\n\n        //Comparamos\n        if(Arrays.equals(array1,array2)){\n            System.out.println(\"Las palabras que asignaste son Anagramas\");\n        }else{\n            System.out.println(\"Las palabras que asignaste no son Anagramas\");\n        }\n    }\n    //Verificación de palíndromo\n    private static void isPalindrome(Scanner scanner) {\n        String palabra = pedirDato(scanner,\"Ingrese la palabra a analizar: \");\n\n        //Normalizar: minúsculas y sin espacios\n        palabra = palabra.toLowerCase().replaceAll(\"\\\\s\",\"\");\n\n        //Invertir la palabra\n        String invertida = new StringBuilder(palabra).reverse().toString();\n\n        if (palabra.equals(invertida)) {\n            System.out.println(\"La palabra \\\"\"+ palabra +\"\\\" es un palíndromo. \");\n        }else{\n            System.out.println(\"La palabra \\\"\"+ palabra +\"\\\" no es un palíndromo. \");\n        }\n    }\n\n    //Metodo para introducir texto informativo y asignar el nombre a la variable scanner\n    private static String pedirDato(Scanner scanner, String mensaje){\n        System.out.println(mensaje);\n        return scanner.nextLine().trim();\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/GlossyPath.java",
    "content": "/**\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\n *   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\n *   interpolación, verificación...\n * \n * @version v1.0\n * \n * @since 20/06/2024\n * \n * @author GlossyPath\n */\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\n\npublic class GlossyPath {\n    \n    public static void main(String[] args) {\n        \n        String cadena = \"Premature optimization is the root of all evil.\";\n        String cadena2 =\"listen silent\";\n\n        //acceso a caracteres específicos.\n        System.out.println(\"Primer caracter de la cadena es: \" + cadena.charAt(0));\n\n        //acceso a subcadenas específicos. Tenemos varias maneras.\n        //indice que comenzamos en adelante.\n        System.out.println(\"Imprimimos desde el primer caracter en adelante. ->\" + cadena.substring(1));\n\n        //desde donde hasta donde.\n        System.out.println(\"Imprimimos desde el noveno caracter hasta el bigésimo segundo. ->\" +  cadena.substring(9, 22));\n\n        //tamaño de la cadena.\n        System.out.println(\"Longitud de la cadena es de: \" +cadena.length() + \"caracteres\");\n\n        //concatenación de cadenas.\n        System.out.println(cadena.concat(\" Try to avoid it.\"));\n\n        //repetición de la cadena las veces que marquemos al método repeat().\n        System.out.println(cadena.substring(0).repeat(2));\n\n        //recorremos las palabras y buscamos la primera(findFirst) palabra donde tengamos el caracter 'i' en una posición mayor que 1.\n        System.out.println(Arrays.stream(cadena.split(\"\\\\s+\")).filter(s-> s.indexOf('i')> 1).findFirst());\n\n        //convertimos los caracteres de la cadena a mayusculas\n        System.out.println(cadena.toUpperCase());\n\n        //convertimos los caracteres de la cadena a minúsculas\n        System.out.println(cadena.toLowerCase());\n\n        //intercambiamos el primer elemento por el segundo.\n        System.out.println(cadena.replaceAll(\"\\\\s+\", \"-\"));\n        System.out.println(cadena.replaceAll(\"i\", \"-\"));\n\n        //intercambiamos el primer caracter por el segundo\n        System.out.println(cadena.replace('a', 'A'));\n       \n        //divide en partes el String y devuelve el tercero\n        System.out.println(cadena.split(\"\\\\s+\")[3]);\n\n        //cogemos un array y lo unimos\n        String[] palabras = {\"Try\", \"to\", \"avoid\", \"it\"};\n        System.out.println(String.join(\" \", palabras));\n\n        //interpolamos frase/palabra a partir del décimo caracter.\n        System.out.println(String.format(\"Early %s\", cadena.substring(10)));\n\n        //comprovamos si la cadena contiene el argumento pasado\n        System.out.println(cadena.contains(\"evil\"));\n\n        //comprovamos si el índice pasado como argumento empieza en 'o' el indice en adelante acaba en '.'\n        System.out.println(cadena.substring(10).endsWith(\".\"));\n        System.out.println(cadena.substring(10).startsWith(\"o\"));\n\n        //llamamos al método para comprobar si la palabra pasada como argumento es un palíndromo.\n        System.out.println(isPalindromo(\"ANNA\"));\n\n        //llamamos al método para comprobar si la palabra pasada como argumento es un isograma.\n        System.out.println(isIsograma(\"ANNA\"));\n\n        //llamamos al método para comprobar si algunas de las palabras pasadas como argumento son anagrama entre ellas.\n        System.out.println(isAnagrama(cadena2));\n        System.out.println(isAnagrama(cadena));\n\n    }\n\n    /**\n         *  DIFICULTAD EXTRA (opcional):\n         * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n         * para descubrir si son:\n         * - Palíndromos\n         * - Anagramas\n         * - Isogramas\n         * \n         */\n\n    /*\n     * Descripción: método para averiguar si la palabra pasada es un palíndromo\n     */\n    public static boolean isPalindromo(String palabra) {\n\n        return palabra.equals(new StringBuilder(palabra).reverse().toString());\n    }\n\n    /*\n     * Descripción: método para averiguar si la palabra pasada es un palíndromo\n     */\n    public static boolean isIsograma(String palabra) {\n\n        return palabra.chars().distinct().count() == palabra.length();\n    }\n\n    /*\n     * Descripción: método para averiguar si la frase/palabras pasadas son un anagrama.\n     */\n     public static boolean isAnagrama(String cadena) {\n\n        List<String>palabras = new ArrayList<>();\n\n        if(cadena == null || cadena.isEmpty()){\n            return false;\n        }\n\n        String[] palabrasArray = cadena.trim().split(\"\\\\s+\");\n\n        palabras = Arrays.asList(palabrasArray);\n\n        for(int i = 0; i<palabras.size()-1; i++){\n\n            char[] palabra = palabras.get(i).toCharArray();\n            char[] palabraSiguiente = palabras.get(i+1).toCharArray();\n\n            Arrays.sort(palabra);\n            Arrays.sort(palabraSiguiente);\n\n            if(!Arrays.equals(palabra, palabraSiguiente)){\n                return false;\n            }\n        }\n        return true;\n     }\n\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/Guillermo-Munoz.java",
    "content": "import java.util.Map;\nimport java.util.function.Function;\nimport java.util.stream.Collectors;\n\n/**\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n * \n * @version v1.0\n * \n * @since 04/03/2026\n * \n * \n * @author Guillermo-Munoz\n */\n\npublic class GuillermoMunoz {\n\n    \n    public static void main(String[] args) {\n\n        //Declaramos dos cadenas de caracteres\n        // → Crea SIEMPRE un objeto nuevo en el HEAP general\n        String cadenaUno = new String(\"Me apasiona la programación\"); // Instanciamos la clase String. Que sería una creación explicita de la clase.\n        String cadenaDos = new String(\"Donde esta el maltido bug\"); // Instanciamos la clase String. Que sería una creación explicita de la clase.\n        // → Va al \"String Pool\" (una zona especial dentro del HEAP)\n        // Si ya existe esa cadena, reutiliza la referencia\n        String cadenaTres = \"Me apasiona la programación\"; //Crear implícitamente la cadena de texto. Es decir, simplemente le asignamos el valor al objeto.\n        String cadenaCuatro = \"Donde esta el maltido bug\"; //Crear implícitamente la cadena de texto. Es decir, simplemente le asignamos el valor al objeto.\n\n        // == Comparacion referencias (direcciones de memoria)\n        System.out.println(\"****  Metodo ==  ****\");\n        System.out.println(\"Comparacion referencias: \" + (cadenaUno == cadenaTres)); //false, porque son objetos diferentes en memoria\n        System.out.println(\"Comparacion referencias: \" + (cadenaDos == cadenaCuatro)); //false, porque son objetos diferentes en memoria\n\n        // equals() Comparacion de contenido\n        System.out.println(\"****  Metodo equals()  ****\");\n        System.out.println(\"Comparacion contenido: \" + cadenaUno.equals(cadenaTres)); //true, porque el contenido es el mismo\n        System.out.println(\"Comparacion contenido: \" + cadenaDos.equals(cadenaCuatro)); //true, porque el contenido es el mismo  \n\n        // Longitud de la cadena\n        System.out.println(\"****  Metodo length()  ****\");\n        System.out.println(\"Longitud cadenaUno: \" + cadenaUno.length());\n        System.out.println(\"Longitud cadenaDos: \" + cadenaDos.length());\n        System.out.println(\"Longitud cadenaTres: \" + cadenaTres.length());\n        System.out.println(\"Longitud cadenaCuatro: \" + cadenaCuatro.length());\n\n        //Subcadena\n        System.out.println(\"****  Metodo substring()  ****\");\n        System.out.println(\"Subcadena cadenaUno (0, 2): \" + cadenaUno.substring(0, 2)); // \"Me\"\n        System.out.println(\"Subcadena cadenaDos (0, 6): \" + cadenaDos.substring(0, 6)); // \"Donde\"  \n\n        // Concatenación\n        System.out.println(\"****  Metodo concat()  ****\");\n        System.out.println(\"Concatenacion cadenaUno + cadenaDos: \" + cadenaUno.concat(cadenaDos)); // \"Me apasiona la programaciónDonde esta el maltido bug\"\n        System.out.println(\"Concatenación cadenaTres + Palabra : \" + cadenaTres.concat(\" es genial\")); // \"Me apasiona la programación es genial\"\n\n        //Repetición\n        System.out.println(\"****  Metodo repeat()  ****\");  \n        System.out.println(\"Repeticion cadenaUno 3 veces: \" + cadenaUno.repeat(3)); // \"Me apasiona la programaciónMe apasiona la programaciónMe apasiona la programación\"\n        System.out.println(\"Repeticion cadenaDos 2 veces: \" + cadenaDos.repeat(2)); // \"Donde esta el maltido bugDonde esta el maltido bug\"\n\n        //Recorrido\n        System.out.println(\"****  Metodo charAt()  ****\");  \n        for (int i = 0; i < cadenaUno.length(); i++){\n            System.out.println(\"Caracter en posicion \" + i + \": \" + cadenaUno.charAt(i)); // Imprime cada caracter de la cadenaUno\n        }\n        \n        // Conversión a mayúsculas y minúsculas\n        System.out.println(\"****  Metodo toUpperCase() y toLowerCase()  ****\");\n        System.out.println(\"CadenaUno en mayusculas: \" + cadenaUno.toUpperCase()); // \"ME APASIONA LA PROGRAMACIÓN\"\n        System.out.println(\"CadenaDos en minusculas: \" + cadenaDos.toLowerCase()); // \"donde esta el maltido bug\"\n\n        // Reemplazo\n        System.out.println(\"****  Metodo replace()  ****\"); \n        System.out.println(\"Reemplazo en cadenaUno (programación por coding): \" + cadenaUno.replace(\"programación\", \"coding\")); // \"Me apasiona la coding\"\n        System.out.println(\"Reemplazo en cadenaDos (bug por error): \" + cadenaDos.replace(\"bug\", \"error\")); // \"Donde esta el maltido error\"\n\n        // División\n        System.out.println(\"****  Metodo split()  ****\");\n        String[] palabrasCadenaUno = cadenaUno.split(\" \"); // Divide la cadenaUno en palabras\n        System.out.println(\"Division cadenaUno en palabras: \");\n        for (String palabra : palabrasCadenaUno) {\n            System.out.println(palabra); // Imprime cada palabra de la cadenaUno\n        }\n\n        // Unión\n        System.out.println(\"****  Metodo join()  ****\");        \n        String[] palabras = {\"Me\", \"apasiona\", \"la\", \"programación\"};\n        String cadenaUnida = String.join(\" \", palabras); // Une las palabras con un espacio\n        System.out.println(\"Union de palabras: \" + cadenaUnida); // \"Me apasiona la programación\"\n        // Interpolación (en Java se puede hacer con String.format)\n        System.out.println(\"****  Metodo String.format()  ****\");\n        String nombre = \"Guillermo\";\n        int edad = 100;\n        String mensajeInterpolado = String.format(\"Hola, mi nombre es %s y tengo %d años.\", nombre, edad); // Interpola las variables en la cadena\n        System.out.println(\"Mensaje interpolado: \" + mensajeInterpolado); // \"Hola, mi nombre es Guillermo y tengo 100 años.\"    \n\n        // Verificación\n        System.out.println(\"****  Metodo startsWith() y endsWith()  ****\");\n        System.out.println(\"¿cadenaUno empieza con 'Me'? \" + cadenaUno.startsWith(\"Me\")); // true\n        System.out.println(\"¿cadenaDos termina con 'bug'? \" + cadenaDos.endsWith(\"bug\")); // true\n        System.out.println(\"¿cadenaTres contiene 'teclado'? \" + cadenaTres.contains(\"teclado\")); // false\n        System.out.println(\"¿cadenaCuatro contiene 'ratón'? \" + cadenaCuatro.contains(\"ratón\")); // false\n\n        // Comprobamos el metodo esPalindromo\n        System.out.println(\"****  Metodo esPalindromo()  ****\");  \n        System.out.println(\"OTTO es palindromo?: \" + esPalindormo(\"OTTO\"));\n        System.out.println(\"PESO es palindromo?: \" + esPalindormo(\"PESO\"));\n\n        // Comprobamor el metodo anagrama\n        System.out.println(\"****  Metodo esAnagrama()  ****\");  \n        System.out.println(\"La palabra casa es anagrama de saca?: \" + esAnagrama(\"casa\", \"saca\"));\n        System.out.println(\"La palabra casa es anagrama de tarta?: \" + esAnagrama(\"casa\", \"tarta\"));\n\n        // Comprobar el metodo Isograma\n        System.out.println(\"****  Metodo esIsograma()  ****\");  \n        System.out.println(\"La palabra aro es un isograma?: \" + esIsograma(\"aro\"));\n        System.out.println(\"La palagra carro es isograma?: \" + esIsograma(\"carro\"));\n\n\n\n\n\n    }\n\n\n// Ejercicio Extra Crea un programa que analice dos palabras diferentes y realice comprobaciones para descubrir si son: - Palíndromos- Anagramas- Isogramas\n\n    // Palindromos\n    public static boolean esPalindormo(String palabra){\n\n        // Limpieza\n        palabra = palabra.toLowerCase().replaceAll(\"\\\\s\", \"\");\n        String finalPalabra = palabra;\n\n        return java.util.stream.IntStream\n                        .range(0, palabra.length() / 2 )\n                        .allMatch(i -> finalPalabra.charAt(i) == \n                                        finalPalabra.charAt(finalPalabra.length() - 1 - i));\n        \n    }\n\n    // Anagrama\n    public static boolean esAnagrama(String a, String b){\n\n        // Limpieza\n        a = a.toLowerCase().replaceAll(\"\\\\s\", \"\");\n        b = b.toLowerCase().replaceAll(\"\\\\s\", \"\");\n\n        // Comprobar si tiene la misma longitud\n        if(a.length() != b.length()) return false;\n\n        Map<Character, Long> mapa1 = a.chars()\n                .mapToObj(c -> (char) c)\n                .collect(Collectors.groupingBy(\n                    Function.identity(),\n                    Collectors.counting()\n                ));\n\n        Map<Character, Long>  mapa2 = b.chars()\n                .mapToObj(c -> (char) c)\n                .collect(Collectors.groupingBy(\n                    Function.identity(),\n                    Collectors.counting()\n                ));        \n                \n\n        return mapa1.equals(mapa2);\n    }\n\n    // Isograma\n    public static Boolean esIsograma(String a){\n\n        // Limpieza\n        a = a.toLowerCase().replaceAll(\"\\\\s\", \"\");\n\n        Map<Character, Long> frecuencia = a.chars()\n        .mapToObj(c -> (char) c )\n        .collect(Collectors.groupingBy(\n            Function.identity(),\n            Collectors.counting()\n        ));\n\n        return frecuencia.values().stream()\n                .allMatch(count -> count == 1);\n    }\n\n\n\n\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/GustavoGomez19.java",
    "content": "import java.lang.reflect.Array;\nimport java.util.Arrays;\nimport java.util.Scanner;\n\n/**\n * GustavoGomez19\n */\npublic class GustavoGomez19 {\n\n    public static void main(String[] args) {\n        // Ejemplos de las operaciones con cadenas de carácteres en Java\n\n        // Creación de una cadena de forma literal\n        String name = \"Gustavo\";\n        // Creacupin de una cadena por medio de instancia\n        String lastName = new String(\"Gomez\");\n        // Concatenacion de Strings\n        String fullName = name + lastName;\n        // Comparción si son el mismo objeto\n        boolean mismoObj = name == lastName;\n\n        /* EJEMPLO STRING MÉTODOS */\n        String nombreCompleto = \"Gustavo Adolfo Gómez Quiñones\";\n        // Conocer el número de carácteres de una cadena\n        System.out.println(\"Cantidad de carácteres: \" + nombreCompleto.length());\n        // Convertir la cadena a MAYÚSCULA\n        System.out.println(\"Cadena en mayúscula: \" + nombreCompleto.toUpperCase());\n        // Convertir la cadena a minúscula\n        System.out.println(\"Cadena en minúscula: \" + nombreCompleto.toLowerCase());\n        // Comparación de String a nivel de valor\n        System.out.println(\"Gustavo\".equals(nombreCompleto));\n        // Comparación de String a nivel de valor ignorando mayúsculas\n        System.out.println(\"gustavo adolfo gómez quiñones\".equalsIgnoreCase(nombreCompleto));\n        // Comparación de carácteres. Comparación de orden léxico - gráfico\n        // Si el valor es 0 las cadenas son iguales\n        System.out.println(\"Gustavo Adolfo Gómez Quiñones\".compareTo(nombreCompleto));\n        // Si el valor es negativo la cadena es menor a 'nombreCompleto'\n        System.out.println(\"Gustavo\".compareTo(nombreCompleto));\n        // Si el valor es positivo la cadena es mayor a \"Gustavo\"\n        System.out.println(nombreCompleto.compareTo(\"Gustavo\"));\n        // Obtener un carácter en especial\n        System.out.println(\"Carácter del indice 5: \" + nombreCompleto.charAt(5));\n        // Obtener de forma dinámica el último carácter\n        System.out.println(\"Último carácter: \" + nombreCompleto.charAt(nombreCompleto.length() - 1));\n        // Obtener un fragmento del String .subString(int a, int b) puede recibir 1 o 2\n        // argumentos\n        // y siempre el primer argumento es inclusive\n        System.out.println(\"subString con un argumento: \" + nombreCompleto.substring(15));\n        System.out.println(\"subString con dos argumentos: \" + nombreCompleto.substring(0, 14));\n        /*\n         * Método replace(). Sirve para reemplazar un carácter por otro, recibe 2\n         * parámetros, uno\n         * es el carácter a cambiar que es conocido como 'target' y el otro parámetro es\n         * por el cual\n         * será reemplazado y es conocido como replacement\n         */\n        String cadena = \"Hijo\";\n        System.out.println(\"Antes del cambio: \" + cadena);\n        System.out.println(\"Después del cambio: \" + cadena.replace(\"o\", \"@\"));\n        /*\n         * Método indexOf(). Permite saber si se encuentra algún carácter dentro del\n         * String y retorna el índice\n         * de la primer incidencia, puede recibir como parámetro un String o un char\n         */\n        System.out.println(\"Número del indice de la letra solicitada: \" + nombreCompleto.indexOf('a'));\n        /*\n         * Método lastIndexOf(). Permite saber si se encuentra algún carácter dentro del\n         * String y retorna el índice\n         * de la última incidencia, puede recibir como parámetro un String o un char, si\n         * no encuentra coincidencia,\n         * retorna un número negativo\n         */\n        System.out.println(\"Número del indice de la letra solicitada: \" + nombreCompleto.lastIndexOf('s'));\n        /*\n         * Método contains(). Recibe una cadena y retorna true o false, dependiendo el\n         * caso\n         */\n        System.out.println(\"Contiene? \" + nombreCompleto.contains(\"Adolfo\"));\n        /*\n         * Método startsWith(). Recibe una secuencia de carácteres, se usa para saber\n         * con cual carácter o cadena\n         * empieza la cadena y retorna true o false dependiendo el caso\n         */\n        System.out.println(\"inicia? \" + nombreCompleto.startsWith(\"G\"));\n        /*\n         * Método endsWith(). Recibe una secuencia de carácteres, se usa para saber con\n         * cual carácter o cadena\n         * finaliza la cadena y retorna true o false dependiendo el caso\n         */\n        System.out.println(\"Finaliza? \" + nombreCompleto.endsWith(\".\"));\n        /*\n         * Método trim(). Elimina los espacios en blanco al principio y al final que\n         * pueda tener el String\n         */\n        String ejemplo = \"   Ejemplo   \";\n        System.out.println(ejemplo);\n        System.out.println(ejemplo.trim());\n\n        /*\n         * Ejercicio dificultad extra\n         * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n         * para descubrir si son:\n         * - Palíndromos\n         * - Anagramas\n         * - Isogramas\n         */\n        Scanner input = new Scanner(System.in);\n        System.out.print(\"Ingrese la primer palabra: \");\n        String palabraUno = input.nextLine();\n        System.out.print(\"Ingrese la segunda palabra: \");\n        String palabraDos = input.nextLine();\n\n        \n        // Anagrama\n        if (esAnagrama(palabraUno, palabraDos)) {\n            System.out.println(\"Las palabras \" + palabraUno + \" y \" + palabraDos + \" son anagramas\");\n        } else {\n            System.out.println(\"Las palabras \" + palabraUno + \" y \" + palabraDos + \" no son anagramas\");\n        }\n\n        //Palindromo\n        String frase = \"anita lava la tina\";\n        if (esPalindromo(frase)) {\n            System.out.println(\"La frase '\" + frase + \"' es un palindromo\");\n        } else {\n            System.out.println(\"La frase \" + frase + \" no es un palindromo\");\n        }\n\n        // Isograma\n        String isograma = \"murcielago\";\n        if (esIsograma(isograma)) {\n            System.out.println(\"La palabra \" + isograma + \" es un isograma.\");\n        } else {\n            System.out.println(\"La palabra \" + isograma + \" no es un isograma.\");\n        }\n        \n\n    }\n\n    // Método para saber si dos palabras son anagramas\n    public static boolean esAnagrama(String palabraUno, String palabraDos){\n        palabraUno = palabraUno.replaceAll(\"\\\\s\", \"\").toLowerCase();\n        palabraDos = palabraDos.replaceAll(\"\\\\s\", \"\").toLowerCase();\n\n        // Verificación si las dos palabras son diferentes en su longitud\n        if (palabraUno.length() != palabraDos.length()) {\n            return false;\n        }\n\n        // Conversión de las palabras en arreglos de carácteres y se ordenan\n        char[] arrayPalabraUno = palabraUno.toCharArray();\n        char[] arrayPalabraDos = palabraDos.toCharArray();\n        Arrays.sort(arrayPalabraUno);\n        Arrays.sort(arrayPalabraDos);\n\n        // Comparación de los arrays de carácteres\n        return Arrays.equals(arrayPalabraUno, arrayPalabraDos);\n    }\n\n    // Método para saber si una frase es palindromo\n    public static boolean esPalindromo(String frase){\n        frase = frase.replaceAll(\"\\\\s\", \"\").toLowerCase();\n        // Longitud de la frase\n        int longitud = frase.length();\n\n        // Comparación de los carácteres de la frase desde los extremsos hacía adentro\n        for (int i = 0; i < longitud / 2; i++) {\n            if (frase.charAt(i) != frase.charAt(longitud - 1 - i)) {\n                return false; // En caso de que los carácteres no coincidan, no es un palindromo.\n            }\n        }\n        return true; // La frase es un palindromo\n    }\n\n    // Método para deterninar un anagrama\n    public static boolean esIsograma(String isograma){\n        isograma = isograma.replaceAll(\"\\\\s\", \"\").toLowerCase();\n\n        // Arreglo que almacena la frecuencia de cada letra\n        int[] frecuenciaLetra = new int[26]; // Se toma en consideración las letras del alfabeto ingles\n\n        // Iteración sobre cada letra de la palabra\n        for (char letra : isograma.toCharArray()) {\n            int indice = letra - 'a'; // Se convierte la letra en un indice entre 0 y 25\n            if (frecuenciaLetra[indice] > 0) {\n                return false; // Si se encuentra que la letra ya ha aparecido, no es un isograma\n            }\n            frecuenciaLetra[indice]++; //Se incrementa la frecuencia de la letra\n        }\n        return true; // La palabra es un isograma\n    }\n\n}"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/Jeigar2.java",
    "content": "import java.util.Arrays;\nimport java.util.List;\n\npublic class Jeigar2 {\n    /*\n     * EJERCICIO:\n     * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n     * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n     * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n     *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n     *\n     * DIFICULTAD EXTRA (opcional):\n     * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n     * para descubrir si son:\n     * - Palíndromos\n     * - Anagramas\n     * - Isogramas\n     */\n    public static void main(String[] args) {\n        String cadena = \"La vida es bella porque Dios te ama siempre\";\n        System.out.println(\"acceso al 2º carácter específico \" + cadena.charAt(1));\n        System.out.println(\"subcadena del 24 al final \" + cadena.substring(24));\n        System.out.println(\"subcadena del 24 al 28 \" + cadena.substring(24,28));\n        System.out.println(\"longitud: \" + cadena.length());\n        System.out.println(\"concatenación \" + cadena + \" / \" + cadena.substring(24));\n        System.out.println(\"repetición \" + cadena.substring(24,29).repeat(3));\n        System.out.println(\"recorrido: \" + Arrays.stream(cadena.split(\"\\s\")).filter(s->s.indexOf('o')>1).findFirst());\n        System.out.println(\"Mayúsculas: \" + cadena.toUpperCase());\n        System.out.println(\"Minúsculas: \" + cadena.toLowerCase());\n        System.out.println(\"Reemplazo: \\n\" + cadena.replaceAll(\".\",\"-\") + \"\\n\" + cadena + \"\\n\" + cadena.replaceAll(\".\", \"-\") );\n        System.out.println(\"division: sexta palabra \" + cadena.split(\"\\s\")[5]);\n        System.out.println(\"Unión \" + String.join(\" \", \"Dios,te,ama\".split(\",\")));\n        System.out.println(\"Interpolación: \" + String.format(\"Deja que %s sea %s\", cadena.substring(24,28), cadena.substring(24,28)));\n        System.out.println(\"Verificación: \" + cadena.contains(\"Dios\"));\n        System.out.println(\"Verificación: \" + cadena.substring(24).startsWith(\"Dios\"));\n        System.out.println(\"Verificación: \" + cadena.substring(0,28).endsWith(\"Dios\"));\n        String palindromo = \"dabale arroz a la zorra el abad\".replaceAll(\" \", \"\");\n        System.out.println(\"Es palindromo: \" + isPalindromo(palindromo));\n        System.out.println(\"Es isograma: \" + isIsograma(\"hola\"));\n        System.out.println(\"Es anagrama: \" + isAnagrama(\"roma amor mora\"));\n        System.out.println(\"Es anagrama: \" + isAnagrama(\"roma amor mori\"));\n    }\n\n    public static boolean isPalindromo(String cadena){\n        return cadena.equals(new StringBuilder(cadena).reverse().toString());\n    }\n\n    public static boolean isIsograma(String cadena){\n        return cadena.chars().distinct().count() == cadena.length();\n    }\n\n    public static boolean isAnagrama(String cadena) {\n        boolean continuar = false;\n        String[] palabras = cadena.split(\" \");\n        if (palabras != null && palabras.length > 0) {\n            List<String> listaPalabras = Arrays.asList(palabras);\n            int totalPalabras = listaPalabras.size();\n            int totalLetrasPrimeraPalabra = listaPalabras.getFirst().length();\n            String primeraPalabra = listaPalabras.getFirst();\n            long totalPalabrasCoincidenLargo = listaPalabras.stream().filter(s -> s.length() == totalLetrasPrimeraPalabra).count();\n            continuar = (totalPalabras == totalPalabrasCoincidenLargo);\n\n            boolean[][] posicionBool = new boolean[totalLetrasPrimeraPalabra][totalPalabras];\n\n            if (continuar) {\n                // comprobar todas las palabras y letras\n                for (int letra = 0; letra < totalLetrasPrimeraPalabra; letra++) {\n                    for (int palabra = 1; palabra < totalPalabras; palabra++) {\n                        posicionBool[letra][palabra] = palabras[palabra].indexOf(primeraPalabra.charAt(letra)) >= 0;\n                    }\n                }\n            }\n            // comprobar si hay algun valor false\n            for (int letra = 0; letra < totalLetrasPrimeraPalabra; letra++) {\n                for (int palabra = 1; palabra < totalPalabras; palabra++) {\n                    if (!posicionBool[letra][palabra]) {\n                        return false;\n                    }\n                }\n            }\n        }\n        return continuar;\n    }\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/JesusAntonioEEscamilla.java",
    "content": "/** #04 - Java -> Jesus Antonio Escamilla */\n\nimport java.util.Arrays;\nimport java.util.HashSet;\nimport java.util.Set;\n\npublic class JesusAntonioEEscamilla {\n    public static void main(String[] args) {\n    //---EJERCIÓ---\n    // Cadenas de caracteres\n        //--STRING--\n        String str = \"Hola Mundo\";\n        System.out.println(\"STRING -> \" + str);\n        char ch = str.charAt(3);\n        System.out.println(\"Carácter -> \" + ch);\n\n        //--SUB-CADENA--\n        String subStr = str.substring(5, 10);\n        System.out.println(\"Sub-Cadena -> \" + subStr);\n\n        //--LONGITUD--\n        int length = str.length();\n        System.out.println(\"Longitud -> \" + length);\n\n        //--CONCATENACIÓN--\n        String str1 = \"Jesus\";\n        String resultado = str.concat(\", soy \" + str1);\n        System.out.println(\"Concatenación -> \" + resultado);\n\n        //--REPETICIÓN--\n        //No hay método directo en Java, pero se puede usar StringBuilder\n        String repeated = str.repeat(3);\n        System.out.println(\"Repetición -> \" + repeated);\n\n        //--MAYÚSCULAS Y MINÚSCULAS--\n        String upper = str.toUpperCase();\n        String lower = str.toLowerCase();\n        System.out.println(\"Mayúsculas -> \" + upper);\n        System.out.println(\"Minúsculas -> \" + lower);\n\n        //--REMPLAZO--\n        String replaced = str.replace(\"Mundo\", \"Java\");\n        System.out.println(\"Remplazo -> \" + replaced);\n\n        //--DIVISION--\n        String str__ = \"Hola,Mundo,Java\";\n        String[] parts = str__.split(\",\");\n        System.out.println(\"Division -> \" + Arrays.toString(parts));\n\n        //--UNION--\n        String[] words = {\"Hola\", \"Mundo\", \"Java\"};\n        String joined = String.join(\"\", words);\n        System.out.println(\"Union -> \" + joined);\n\n        //--INTERPOLACIÓN--\n        String nombre = \"Antonio\";\n        String str_ = String.format(\"Hola %s\", nombre);\n        System.out.println(\"Interpolación -> \" + str_);\n\n        //--VERIFICACIÓN--\n        // -IGUALDAD-\n        String str3 = \"Hola Mundo\";\n        boolean isEqual = str.equals(str3);\n        System.out.println(\"Verificación-Igualdad (Hola Mundo = Hola Mundo) -> \" + isEqual);\n\n        // -EMPIEZA-\n        boolean startsWith = str.startsWith(\"Hola\");\n        System.out.println(\"Verificación-Principio (Hola Mundo = Hola) -> \" + startsWith);\n\n        // -TERMINA-\n        boolean endsWith = str.endsWith(\"Mundo\");\n        System.out.println(\"Verificación-Termina (Hola Mundo = Mundo) -> \" + endsWith);\n\n        // -CONTIENE-\n        boolean contains = str.contains(\"Mundo\");\n        System.out.println(\"Verificación-Contiene (Hola Mundo = Hola-Mundo) -> \" + contains);\n\n    //---EXTRA---\n        EXTRA(\"radar\", \"roma\");\n    }\n\n    /**-----DIFICULTAD EXTRA-----*/\n\n    public static void EXTRA(String palabra1, String palabra2) {\n        palabra1 = palabra1.toLowerCase();\n        palabra2 = palabra2.toLowerCase();\n        System.out.println(\"Palíndromo\");\n        System.out.println(palabra1 + \" es un Palíndromo: \" + esPalíndromo(palabra1));\n        System.out.println(palabra2 + \" es un Palíndromo: \" + esPalíndromo(palabra2));\n        \n        System.out.println(\"Anagrama\");\n        System.out.println(palabra1 + \" y \" + palabra2 + \" son Anagramas: \" + sonAnagramas(palabra1, palabra2));\n        \n        System.out.println(\"Isograma\");\n        System.out.println(palabra1 + \" es un Isograma: \" + esIsograma(palabra1));\n        System.out.println(palabra2 + \" es un Isograma: \" + esIsograma(palabra2));\n    }\n\n    public static boolean esPalíndromo(String word){\n        word = word.toLowerCase();\n        String invert = new StringBuilder(word).reverse().toString();\n        return word.equals(invert);\n    }\n\n    public static boolean sonAnagramas(String word1, String word2){\n        word1 = word1.toLowerCase();\n        word2 = word2.toLowerCase();\n        if(word1.length() != word2.length()){\n            return false;\n        }\n        char[] array1 = word1.toCharArray();\n        char[] array2 = word2.toCharArray();\n        Arrays.sort(array1);\n        Arrays.sort(array2);\n        return Arrays.equals(array1, array2);\n    }\n\n    public static boolean esIsograma(String word){\n        Set<Character> character = new HashSet<>();\n        for (char c : word.toCharArray()) {\n            if (character.contains(c)) {\n                return false;\n            }\n            character.add(c);\n        }\n        return true;\n    }\n\n    /**-----DIFICULTAD EXTRA-----*/\n}"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/JesusEs1312.java",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\nimport java.util.Arrays;\n\npublic class JesusEs1312 {\n    public static void main(String[] args) {\n        // Ejemplo de acceso a caracteres específicos\n        String cadena = \"Hola mundo\";\n        System.out.println(cadena.charAt(0)); // H\n        System.out.println(cadena.charAt(1)); // o\n        System.out.println(cadena.charAt(2)); // l\n        System.out.println(cadena.charAt(3)); // a\n\n        // Ejemplo de longitud\n        System.out.println(cadena.length()); // 10\n\n        // Ejemplo de concatenación\n        String cadena2 = \"Hola\";\n        String cadena3 = \" mundo\";\n        System.out.println(cadena2 + cadena3); // Hola mundo\n        System.out.println(cadena2.concat(cadena3)); // Hola mundo\n\n        // Ejemplo de repetición\n        System.out.println(cadena2.repeat(3)); // HolaHolaHola\n\n        // Ejemplo de recorrido\n        for (int i = 0; i < cadena.length(); i++) {\n            System.out.println(cadena.charAt(i));\n        }\n\n        // Ejemplo de conversión a mayúsculas y minúsculas\n        System.out.println(cadena.toUpperCase()); // HOLA MUNDO\n        System.out.println(cadena.toLowerCase()); // hola mundo\n\n        // Ejemplo de reemplazo\n        System.out.println(cadena.replace(\"Hola\", \"Adiós\")); // Adiós mundo\n\n        // Ejemplo de división\n        String[] palabras = cadena.split(\" \");\n        for (String palabra : palabras) {\n            System.out.println(palabra);\n        }\n\n        // Ejemplo de unión\n        String[] palabras2 = {\"Hola\", \"mundo\"};\n        System.out.println(String.join(\" \", palabras2)); // Hola mundo\n\n        // Ejemplo de interpolación\n        String nombre = \"Juan\";\n        int edad = 25;\n        System.out.println(\"Hola, mi nombre es \" + nombre + \" y tengo \" + edad + \" años\");\n        System.out.println(String.format(\"Hola, mi nombre es %s y tengo %d años\", nombre, edad));\n\n        // Ejemplo de verificación\n        System.out.println(cadena.contains(\"Hola\")); // true\n        System.out.println(cadena.startsWith(\"Hola\")); // true\n        System.out.println(cadena.endsWith(\"mundo\")); // true\n\n        // Ejemplo de funciones extra\n        funcionExtra(\"oso\", \"oso\");\n    }\n\n    public static void funcionExtra(String palabra1, String palabra2) {\n        // Palíndromos\n        System.out.println(palabra1.equals(new StringBuilder(palabra1).reverse().toString()) ? \"Es palíndromo\" : \"No es palíndromo\");\n        System.out.println(palabra2.equals(new StringBuilder(palabra2).reverse().toString()) ? \"Es palíndromo\" : \"No es palíndromo\");\n\n        // Anagramas\n        char[] palabra1Array = palabra1.toCharArray();\n        char[] palabra2Array = palabra2.toCharArray();\n        Arrays.sort(palabra1Array);\n        Arrays.sort(palabra2Array);\n        System.out.println(Arrays.equals(palabra1Array, palabra2Array) ? \"Son anagramas\" : \"No son anagramas\");\n\n        // Isogramas\n        System.out.println(palabra1.length() == palabra1.chars().distinct().count() ? \"Es isograma\" : \"No es isograma\");\n        System.out.println(palabra2.length() == palabra2.chars().distinct().count() ? \"Es isograma\" : \"No es isograma\");\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/JimsimroDev.java",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\n *   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\n *   interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\npublic class JimsimroDev {\n\n  public static void print(String... strs) {\n    for (String str : strs) {\n      System.out.print(\" \" + str);\n    }\n    System.out.println();\n  }\n\n  public static void main(String[] args) {\n    String divLine = \":::::::::::::::::::::::::::::\";\n    // operaciones\n    String str = \"Hola\";\n    String str1 = \"Java\";\n\n    // concatenación\n    System.out.println(divLine);\n    print(str + \",\", str1 + \"!\");\n    System.out.println(str.concat(\", \" + str1 + \"!\"));\n\n    // repetición\n    System.out.println(divLine);\n    System.out.println(str.repeat(4));\n    for (int i = 0; i < 3; i++) {\n      System.out.println(str);\n    }\n\n    // Indexacion\n    System.out.println(divLine);\n    String caracteres = String.valueOf(str.charAt(0)) + str.charAt(1) + str.charAt(2) + str.charAt(3);\n    System.out.println(caracteres);\n\n    // longitud\n    System.out.println(divLine);\n    System.out.println(str1.length());\n\n    // porcion\n    System.out.println(divLine);\n    System.out.println(str.substring(1, 4));\n    System.out.println(str.substring(0, 2));\n    System.out.println(str.substring(1));\n\n    // Busqueda\n    System.out.println(divLine);\n    System.out.println(str.contains(\"l\"));\n    System.out.println(str.contains(\"q\"));\n\n    // Reemplazo\n    System.out.println(divLine);\n    String remplazar = \"Primera línea Segunda línea Tercera línea\";\n    System.out.println(str.replace(\"o\", \"a\"));\n    System.out.println(remplazar.replaceAll(\" \", \"#\"));// reemplazo los espacios por * puedes remplazar todas las\n                                                       // Ocurrencias de lo que quieras asi\n\n    // División\n    System.out.println(divLine);\n    String[] parte = str1.split(\"v\");\n    System.out.println(Arrays.toString(parte));\n\n    // Dive la cande por el salto de linea e imprime cada linea\n    System.out.println(divLine);\n    String miString = \"Primera línea\\nSegunda línea\\nTercera línea\";\n    System.out.println(miString);\n\n    // Valida si la candena esta vacia o esta en blanco devuelve true\n    System.out.println(miString.isBlank());\n    String cadena = \"\";\n    String cadena1 = \" \";\n    System.out.println(cadena.isBlank());\n    System.out.println(cadena1.isBlank());\n\n    // Valida si esta vacia la cadena y si es 0 devuelve true\n    System.out.println(cadena.isEmpty());\n    System.out.println(cadena1.isEmpty());\n\n    // mayúsculas, minúsculas y letras en mayúsculas\n    System.out.println(divLine);\n    print(str.toUpperCase());\n    print(str.toLowerCase());\n\n    // Eliminación de espacio al principion y al final\n    System.out.println(divLine);\n    System.out.println(divLine);\n    System.out.println(\" Jimmis J \".trim() + \"Simanca\");\n\n    // Busqueda al principio y al final\n    System.out.println(divLine);\n    System.out.println(str.startsWith(\"Ho\"));\n    System.out.println(str.startsWith(\"Ja\"));\n    System.out.println(str.endsWith(\"la\"));\n    System.out.println(str.endsWith(\"va\"));\n\n    // Busqueda de la posción\n    System.out.println(divLine);\n    String str2 = \"Java es tremendo y es el mas robusto\";\n    System.out.println(divLine);\n    System.out.println(str2.indexOf(\"es\"));\n    System.out.println(str2.indexOf(\"tremendo\"));\n    System.out.println(str2.indexOf('n'));\n    System.out.println(str2.lastIndexOf(\"es\"));\n\n    // Ocurrencias\n    System.out.println(divLine);\n    int contador = 0;\n    for (int i = 0; i < str2.length(); i++) {\n      if (str2.charAt(i) == 'e') {\n        contador++;\n      }\n    }\n    System.out.println(contador);\n\n    // Formateo\n    System.out.println(divLine);\n    System.out.printf(\"Saludo: %s, lenguaje: %s\", str, str1);\n    String s = String.format(\"\\nSaludo: %s, lenguaje: %s\\n\", str, str2);\n    System.out.println(s);\n\n    // Transformar lista a cadenas\n    print(divLine);\n    List<String> lista = Arrays.asList(str, \",\", str1, \"!\");\n    print(String.join(\" \", lista));\n\n    // Transformaciones\n    print(divLine);\n    String str3 = \"1234567\";\n    System.out.println(Integer.valueOf(str3));\n\n    String str4 = \"1234567.123\";\n    System.out.println(Double.valueOf(str4));\n\n    // EXTRA\n    print(divLine);\n    comprobar(\"anilina\", \"locos\");\n    print(divLine);\n    comprobar(\"amor\", \"roma\");\n    print(divLine);\n\n    Map<Character, Integer> strDic = new HashMap<>();\n    String lenguaje = \"phytonphytonphytonphyton\";\n    for (int i = 0; i < lenguaje.length(); i++) {\n      char letraActual = lenguaje.charAt(i);\n      strDic.put(letraActual, strDic.getOrDefault(letraActual, 0) + 1);\n    }\n\n    boolean isograma = true;\n    List<Integer> valores = new ArrayList<>(strDic.values());\n    Integer longitud = valores.get(0);\n    for (Integer contar : valores) {\n      if (contar != longitud) {\n        isograma = false;\n        break;\n      }\n    }\n    System.out.println(isograma);\n  }\n\n  public static void comprobar(String str, String str1) {\n    System.out.println(\"Palindromo!\");\n    validarPalindromo(str);\n    validarPalindromo(str1);\n    System.out.println(isPalindromo1(str));\n    System.out.println(isPalindromo1(str1));\n\n    System.out.println(\"Anagramas!\");\n    String strOrdenada = sort(str);\n    String str1Ordenada = sort(str1);\n    System.out.printf(\"%s es un anagrama de %s ? %b\\n\", str, str1, strOrdenada.equals(str1Ordenada));\n\n  }\n\n  private static boolean isPalindromo(String str) {\n    for (int i = 0; i < str.length() / 2; i++) {\n      if (str.charAt(i) == str.charAt(str.length() - 1)) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  private static boolean isPalindromo1(String str) {\n    String invertida = new StringBuilder(str).reverse().toString();\n    if (str.equals(invertida)) {\n      return true;\n    }\n    return false;\n  }\n\n  private static void validarPalindromo(String str) {\n    if (isPalindromo(str)) {\n      System.out.printf(\"La palabra %s es un Palindromo\\n\", str);\n    } else {\n      System.out.printf(\"La palabra %s no es un Palindromo\\n\", str);\n    }\n  }\n\n  private static String sort(String str) {\n    char[] strArray = str.toCharArray();\n    Arrays.sort(strArray);\n    String ordanada = new String(strArray);\n    return ordanada;\n  }\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/Josegs95.java",
    "content": "import java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class Josegs95 {\n    public static void main(String[] args) {\n        //Operaciones con cadenas\n        String miString = \"Esta es mi cadena\";\n        System.out.println(miString); //Out: Esta es mi cadena\n\n        //Acceso a un carácter en especifico\n        System.out.println(miString.charAt(2)); //Out: t\n\n        //Crear una subcadena\n        String miSubString = miString.substring(11);\n        System.out.println(miSubString); //Out: cadena\n\n        //Longitud de una cadena\n        System.out.println(miSubString.length()); //Out: 6\n\n        //Concadenación\n        System.out.println(miString.concat(\" concadenada\")); //Out: Esta es mi cadena concadenada\n\n        //Repetición\n        System.out.println(miSubString.repeat(2)); //Out: cadenacadena\n\n        //Búsqueda de una cadena\n        System.out.println(miString.contains(\"mi\")); //Out: true\n\n        //Búsqueda del índice de una cadena\n        System.out.println(miString.indexOf(\"cadena\")); //Out: 11\n\n        //Conversión a mayúsculas y minúsculas\n        System.out.println(miString.toUpperCase()); //Out: ESTA ES MI CADENA\n        System.out.println(miString.toLowerCase()); //Out: esta es mi cadena\n\n        //Comparación de cadenas\n        System.out.println(miString.equals(miSubString)); //Out: false\n\n        //Verificación si empieza o termina por una cadena\n        System.out.println(miString.startsWith(\"Esta\")); //Out: true\n        System.out.println(miString.endsWith(\"subcadena\")); //Out: false\n\n        //Reemplazo de carácteres o cadenas\n        System.out.println(miString.replace(' ', '_')); //Esta_es_mi_cadena\n\n        //División de una cadena por un patrón\n        String[] division = miString.split(\" \");\n        System.out.println(Arrays.toString(division)); //Out: [Esta, es, mi, cadena]\n\n        //Eliminación de espacios\n        String cadEspacios = \"   Esta es mi cadena con espacios en blanco \";\n        System.out.println(cadEspacios.trim()); //Out: \"Esta es mi cadena con espacios en blanco\"\n        System.out.println(cadEspacios.strip()); //Out: \"Esta es mi cadena con espacios en blanco\"\n        System.out.println(cadEspacios.stripLeading()); //Out: \"Esta es mi cadena con espacios en blanco \"\n        System.out.println(cadEspacios.stripTrailing()); //Out: \"   Esta es mi cadena con espacios en blanco\"\n\n        //Formateo e interpolación\n        double nPi = 3.141592;\n        System.out.println(String.format(\"%.2f\", nPi)); //Out: 3,14\n        String nombre = \"Jose\";\n        String lenguaje = \"Java\";\n        System.out.println(String.format(\"Hola, soy %s y estoy escribiendo en %s\", nombre, lenguaje));\n                            //Out: Hola, soy Jose y estoy escribiendo en Java\n\n        //Separación en lista de caracteres\n        char[] caracteres = miSubString.toCharArray();\n        System.out.println(Arrays.toString(caracteres)); //Out: [c, a, d, e, n, a]\n\n        //Transformación de una lista de cadenas en una sola cadena\n        String[] cadenas = {\"Mi\", \"cadena\", \"separada\"};\n        System.out.println(String.join(\" \", cadenas)); //Out: Mi cadena separada\n\n        //Reto\n        System.out.println(\"\\n\");\n        retoFinal(\"rayar\", \"popolele\");\n    }\n\n    public static void retoFinal(String word1, String word2){\n        System.out.println(\"¿La palabra '\" + word1 + \"' es un palíndromo?: \" + isPalindrome(word1));\n        System.out.println(\"¿La palabra '\" + word2 + \"' es un palíndromo?: \" + isPalindrome(word2));\n        System.out.println(\"¿La palabra '\" + word1 + \"' es un anagrama de \" + word2 + \"?: \" + areAnagram(word1, word2));\n        System.out.println(\"¿La palabra '\" + word1 + \"' es un isograma?: \" + isIsogram(word1));\n        System.out.println(\"¿La palabra '\" + word2 + \"' es un isograma?: \" + isIsogram(word2));\n    }\n\n    private static boolean isPalindrome(String w1){\n        StringBuilder sb = new StringBuilder();\n        sb.append(w1);\n        return sb.reverse().toString().equals(w1);\n    }\n\n    private static boolean areAnagram(String w1, String w2){\n        char[] charArray1 = w1.toCharArray();\n        char[] charArray2 = w2.toCharArray();\n        Arrays.sort(charArray1);\n        Arrays.sort(charArray2);\n\n        return Arrays.equals(charArray1, charArray2);\n    }\n\n    private static boolean isIsogram(String w1){\n        Map<Character, Integer> letters = new HashMap<>();\n        for (Character c : w1.toCharArray())\n            letters.put(c, letters.get(c) == null ? 1 : (letters.get(c) + 1));\n        for (Map.Entry<Character, Integer> entry : letters.entrySet()){\n            if (letters.get(w1.charAt(0)) != entry.getValue())\n                return false;\n        }\n\n        return true;\n    }\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/Karolle.java",
    "content": "import java.util.Arrays;\n\npublic class Karolle {\n    public static void main(String[] args) {\n        // Operaciones con Strings\n        String cadena = \"Hola Mundo\";\n        System.out.println(\"Longitud: \" + cadena.length());\n        System.out.println(\"Carácter específico: \" + cadena.charAt(0));\n        System.out.println(\"Subcadena: \" + cadena.substring(0, 4));\n        System.out.println(\"Concatenación: \" + cadena.concat(\" de Java\"));\n        System.out.println(\"Mayúsculas: \" + cadena.toUpperCase());\n        System.out.println(\"Minúsculas: \" + cadena.toLowerCase());\n        System.out.println(\"Reemplazo: \" + cadena.replace('o', 'a'));\n        String[] division = cadena.split(\" \");\n        System.out.println(\"División: \" + Arrays.toString(division));\n        String union = String.join(\"-\", division);\n        System.out.println(\"Unión: \" + union);\n        \n        // Verificación de palíndromos, anagramas e isogramas\n        String palabra1 = \"amor\";\n        String palabra2 = \"roma\";\n        \n        System.out.println(\"¿Son palíndromos? \" + esPalindromo(palabra1, palabra2));\n        System.out.println(\"¿Son anagramas? \" + esAnagrama(palabra1, palabra2));\n        System.out.println(\"¿Son isogramas? \" + (esIsograma(palabra1) && esIsograma(palabra2)));\n    }\n\n    static boolean esPalindromo(String palabra1, String palabra2) {\n        return new StringBuilder(palabra1).reverse().toString().equals(palabra2);\n    }\n\n    static boolean esAnagrama(String palabra1, String palabra2) {\n        char[] array1 = palabra1.toCharArray();\n        char[] array2 = palabra2.toCharArray();\n        Arrays.sort(array1);\n        Arrays.sort(array2);\n        return Arrays.equals(array1, array2);\n    }\n\n    static boolean esIsograma(String palabra) {\n        for (int i = 0; i < palabra.length(); i++) {\n            for (int j = i + 1; j < palabra.length(); j++) {\n                if (palabra.charAt(i) == palabra.charAt(j)) {\n                    return false;\n                }\n            }\n        }\n        return true;\n    }\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/Kine-jdf.java",
    "content": "import java.util.Arrays;\nimport java.util.HashMap;\n\npublic class Kine_jdf {\n    public static void main(String[] args) {\n        // Operaciones con Strings\n    String str = \"Esta es mi cadena\";\n    System.out.println(\"Longitud: \" + str.length());\n     System.out.println(\"Carácter específico: \" + str.charAt(0));\n    System.out.println(\"Subcadena: \" + str.substring(0, 4));\n     System.out.println(\"Concatenación: \" + str.concat(\" de Java\"));\n     System.out.println(\"Mayúsculas: \" + str.toUpperCase());\n     System.out.println(\"Minúsculas: \" + str.toLowerCase());\n    System.out.println(\"Reemplazo: \" + str.replace('o', 'a'));\n    String[] division = str.split(\" \");\n    System.out.println(\"División: \" + Arrays.toString(division));\n    String union = String.join(\"-\", division);\n    System.out.println(\"Unión: \" + union);\n        \n         System.out.println(\"Palindromo Zorra - Arroz \" + palindromo(\"Zorra\", \"Arroz\")); //true\n         System.out.println(\"No es palindromo Casa - Saco \" + palindromo(\"Casa\", \"Saco\")); //false\n\n  System.out.println(\"Anagrama Lacteo Coleta: \" + anagram(\"lacteo\",\"coleta\"));\n\n  System.out.println(\"Isograma Musica: \" + isograma(\"Musica\"));  /true\nSystem.out.println(\"Isograma Intestinos: \" + isograma(\"Intestinos\"));  //true\nSystem.out.println(\"Isograma Entender: \" + isograma(\"Entender\"));  //false\n    }\n\nstatic boolean palindromo(String uno, String dos){\n    boolean son=false;\n    String aux=\"\";\n if(uno.length()==dos.length()){\n     \n     for (int j= uno.length(); j>0;j--){\naux +=  uno.charAt((j-1)); }\n     \n      }\n    \n    if(aux.equalsIgnoreCase(dos)){son=true;}\n    \n    \n    return son; }  //\n\nstatic boolean  anagram (String uno, String dos){\n         boolean son=false; \n         char[] aux;\n          char[] aux2;\n         if(uno.length()==dos.length()){\n             \n             aux = uno.toLowerCase().toCharArray();\n             aux2=dos.toLowerCase().toCharArray();\n            Arrays.sort(aux);\n            Arrays.sort(aux2);\n           son = Arrays.equals(aux,aux2);\n     }       \n               return son; }\n\n//metodo que analiza tanto heterogramas (todas letras sin repetir) como isograma(cuando una letra se repite, que se repita un nro par)\n static boolean isograma(String palabra) {\n        HashMap<Character, Integer> frecuencias = new HashMap<>();\n\n        for (char letra : palabra.toCharArray()) {\n            frecuencias.put(letra, frecuencias.getOrDefault(letra, 0) + 1);\n        }\n\n        for (int frecuencia : frecuencias.values()) {\n            if (frecuencia > 1) {\n                // Verificar si el número de apariciones es impar\n                if (frecuencia % 2 != 0) {\n                    return false;\n                }\n            }\n        }\n        return true;\n    }\n        \n\n   \n\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/Ldre3.java",
    "content": "import java.util.*;\nimport java.util.function.Function;\nimport java.util.stream.Collectors;\n\npublic class Ldre3 {\n    public static void main(String[] args) {\n        String cadena = \"Cadena\";\n        System.out.println(cadena.replace(\"a\",\"m\"));\n        System.out.println(cadena.toLowerCase());\n        System.out.println(cadena.toUpperCase());\n        System.out.println(cadena.concat(\"cadena\"));\n        System.out.println(cadena.charAt(2));\n        System.out.println(cadena.substring(1,3));\n        System.out.println(cadena.contains(\"en\"));\n        System.out.println(cadena.repeat(3));\n        System.out.println(Arrays.toString(cadena.split(\"\")));\n        System.out.println(anagram(\"Caca\",\"Ioio\"));\n        System.out.println(anagram(\"Perro\",\"Rrope\"));\n        System.out.println(isogram(\"Perro\"));\n        System.out.println(isogram(\"paolpola\"));\n    }\n    /*\n     * EJERCICIO:\n     * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n     * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n     * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\n     *   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\n     *   interpolación, verificación...\n\n     */\n\n\n    /*\n\n     * DIFICULTAD EXTRA (opcional):\n     * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n     * para descubrir si son:\n     * - Palíndromos\n     * - Anagramas\n     * - Isogramas\n     */\n\n    private static boolean palindrome (String cadena1){\n      return cadena1.contentEquals(new StringBuilder(cadena1).reverse());\n    };\n    private static boolean anagram (String cadena1, String cadena2){\n        if(cadena1.length()!=cadena2.length()) return false;\n        String str1 = cadena1.toLowerCase().chars().sorted().collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append).toString();\n        String str2 = cadena2.toLowerCase().chars().sorted().collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append).toString();\n\n        return str1.equals(str2);\n    }\n\n    private static boolean isogram(String cadena) {\n        Map<Character, Long> collect = cadena.chars().mapToObj(c -> (char) c)\n                .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));\n        return collect.values().stream().allMatch(x -> x.equals(collect.get(cadena.charAt(0))));\n    }\n\n}"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/LucasAG01.java",
    "content": "import java.util.Arrays;\n\npublic class LucasAG01 {\n    public static void main(String[] args) {\n        /*\n    Operaciones\n     */\n\n        String s1 = \"hola\";\n        String s2 = \"Java\";\n\n\n        //concatenacion\n\n        System.out.println(s1+\", \"+s2);\n\n        String s3= s1.concat(\" \").concat(s2); //hola java\n\n        //Longitud\n\n        int length=s2.length();\n        System.out.println(\"Longitud: \"+length);\n\n        //Acceder a un caracter específico\n\n        char ch=s2.charAt(1); //'a'\n\n        //Comparacion de cadenas\n\n        String compas2=\"Java\";\n        boolean iguales = s1.equals(compas2); //false  Conque falle una mayuscula, dará false\n\n        boolean iguales2 = s2.equalsIgnoreCase(compas2); //true\n\n\n        //Subcadenas\n\n        String substr1= s1.substring(0,4); //hola\n        String substr2= s2.substring(0,2); //Ja\n\n        //Reemplazar\n\n        String replace=s1.replace('a','4');\n        String replace2=s2.replace(\"Java\",\"Python\");\n\n        //Dividir cadenas\n\n        String divi = \"Java,Python,C++,Socorro\";\n\n        String[] langua =divi.split(\",\"); //Se dividem por la coma, se crea una lista.\n\n        //Mayusculas y minusculas\n\n        String upper = s1.toUpperCase();\n        String lower = s2.toLowerCase();\n\n        //Eliminar espacios en blanco\n\n        String espacios= \"    Hola java   \";\n        String trimmed = espacios.trim(); // \"Hola Java\";\n\n        //Verificar si empieza y termina\n\n        boolean empiezapor= s1.startsWith(\"H\"); //false\n        boolean terminapor =s2.endsWith(\"a\"); //true\n\n\n        //Conversion\n\n        int num = 12345678;\n        String nums = \"12345678\";\n\n        String numString= String.valueOf(num);\n        String empiezapor2=String.valueOf(empiezapor); //\"false\" en cadena\n\n        int nums2=Integer.parseInt(nums);\n\n\n\n\n        //Buscar dentro de una cadena\n\n        int index1=s1.indexOf('a'); //solo dirá la posicion del 1º char que encuentre.\n\n        //invertir cadena\n\n        String reverse = new StringBuilder(s1).reverse().toString();\n\n        //Ver s hay cosas en blanco\n        boolean blanco= s1.isEmpty();\n\n\n        //StringBuilder y StringBuffer\n\n        /*\n        clases usadas para la manipulaciuon de cadenas de carcteres.\n\n        StringBuilder\n        No es seguro para hilos: No es sincronizado, lo que lo hace más rápido para uso en un solo hilo.\n        Eficiente en rendimiento: Ideal para manipular cadenas cuando se hacen muchas modificaciones.\n        Mutable: Permite cambiar el contenido de la cadena sin crear nuevos objetos en memoria.\n        Métodos comunes: append() \"añadir texto al final\", insert(5, \"java \"), delete(), reverse(), replace()\n\n\n        StringBuffer\n        Seguro para hilos: Sus métodos están sincronizados, lo que lo hace adecuado para entornos multihilo.\n        Menos eficiente que StringBuilder: Debido a la sincronización, las operaciones pueden ser más lentas en comparación con StringBuilder.\n        Mutable: Al igual que StringBuilder, permite modificar el contenido de la cadena sin crear nuevos objetos.\n        Métodos comunes: Al igual que StringBuilder, ofrece métodos como append(), insert(), delete(), reverse(), replace().\n\n         */\n\n\n\n\n    }\n\n    public static void check (String uno, String dos){\n\n        //Palidromo Se lee igual hacia adelante y hacia atrás.\n\n        System.out.println(uno.equals(new StringBuilder(uno).reverse().toString()) ? \"ES PALI\" :\"NO ES PALI\");\n        System.out.println(uno.equals(new StringBuilder(dos).reverse().toString()) ? \"ES PALI\" :\"NO ES PALI\");\n\n        /*\n        uno.equals(...):\n\n        uno: Es la cadena original que quieres verificar.\n        uno.equals(...): El método equals() compara si la cadena original (uno) es igual a la cadena que se pasa como argumento. Si son iguales, devolverá true; de lo contrario, devolverá false.\n\n        new StringBuilder(uno):\n        Aquí creas un nuevo objeto de tipo StringBuilder, que es una clase en Java que permite manipular eficientemente cadenas de texto (a diferencia de String, que es inmutable).\n        Pasas la cadena uno como argumento al constructor para que el StringBuilder contenga la misma secuencia de caracteres que uno.\n\n        .reverse():\n        El método reverse() invierte el contenido del StringBuilder. Es decir, cambia el orden de los caracteres.\n\n\n        .toString():\n        El método toString() convierte el StringBuilder (que tiene la cadena invertida) de vuelta a un objeto de tipo String.\n\n\n\n        El uso de ? y : en Java es parte del operador ternario, que es una forma abreviada de la estructura if-else.\n        condición: Una expresión booleana que se evalúa. Si es true, se elige el valor a la izquierda de :, si es false, se elige el valor a la derecha.\n        valor_si_true: El valor que se devolverá si la condición es true.\n        valor_si_false: El valor que se devolverá si la condición es false.\n        */\n\n\n        //Anagrama  Palabra o frase formada al reorganizar las letras de otra.\n\n        //Vamos a convertir un sitrng a una cadena de carcteres, la ordenamos y revisamos\n        char[] cadena1 =uno.toCharArray();\n        char[] cadena2 =dos.toCharArray();\n\n        //Metodos de arrays con cada clase, puede haber centenares de metodosd\n        Arrays.sort(cadena1);\n        Arrays.sort(cadena2);\n\n        System.out.println(Arrays.equals(cadena1,cadena2) ? \"Son anagrama\" : \"No son anagrama\");\n\n        //Isograma: Palabra o frase donde ninguna letra se repite.\n\n        System.out.println(uno.length()==uno.chars().distinct().count() ? \"Es isosgrama\" : \"No lo es\");\n        System.out.println(dos.length()==dos.chars().distinct().count() ? \"Es isosgrama\" : \"No lo es\");\n\n        /*\n        uno.length: longitud\n\n        uno.chars: Este método devuelve un Stream de int que representa los códigos de los caracteres en la cadena uno.\n                   Cada carácter de la cadena se convierte en su valor Unicode (código de carácter).\n\n        disatinc: revisa si son diferentes, eliminado los duplicados\n\n        count: contea los carcteres depues de la eliminacion de carcters\n\n        Resumen:  Esta es la condición que se está evaluando.\n                  Compara la longitud original de la cadena (uno.length()) con la cantidad de caracteres únicos en la cadena (uno.chars().distinct().count()).\n                  Si ambos valores son iguales, significa que ningún carácter se repite en la cadena, lo que indica que la cadena es un isograma.\n                  Si son diferentes, significa que hay al menos un carácter repetido, lo que indica que no es un isograma.\n\n         */\n\n    }\n\n\n\n\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/Qv1ko.java",
    "content": "import java.util.Arrays;\nimport java.util.HashSet;\nimport java.util.Set;\n\npublic class Qv1ko {\n\n    public static void main(String[] args) {\n        program(\"provide\", \"seasonal\");\n    }\n\n    private static void program(String word1, String word2) {\n\n        System.out.println(isPalindrome(word1) ? \"The word \" + word1 + \" is a palindrome\" : \"The word \" + word1 + \" is not a palindrome\");\n        System.out.println(isPalindrome(word2) ? \"The word \" + word2 + \" is a palindrome\" : \"The word \" + word2 + \" is not a palindrome\");\n\n        System.out.println(areAnagrams(word1, word2) ? \"The words \" +  word1 + \" and \" +  word2 + \" are anagrams\" : \"The words \" +  word1 + \" and \" +  word2 + \" are not anagrams\");\n\n        System.out.println(isIsogram(word1) ? \"The word \" + word1 + \" is an isogram\" : \"The word \" + word1 + \" is not an isogram\");\n        System.out.println(isIsogram(word2) ? \"The word \" + word2 + \" is an isogram\" : \"The word \" + word2 + \" is not an isogram\");\n\n    }\n\n    private static boolean isPalindrome(String word) {\n\n        int len = word.length();\n\n        for (int i = 0; i < len / 2; i++) {\n            if (word.charAt(i) != word.charAt(len - i - 1)) {\n                return false;\n            }\n        }\n\n        return true;\n\n    }\n\n    private static boolean areAnagrams(String word1, String word2) {\n\n        if (word1.length() != word2.length()) {\n            return false;\n        }\n\n        char[] lettersWord1 = word1.toCharArray();\n        char[] lettersWord2 = word2.toCharArray();\n\n        Arrays.sort(lettersWord1);\n        Arrays.sort(lettersWord2);\n\n        return Arrays.equals(lettersWord1, lettersWord2);\n\n    }\n\n    public static boolean isIsogram(String word) {\n\n        Set<Character> letters = new HashSet<>();\n\n        for (char letter : word.toCharArray()) {\n            if (!letters.add(letter)) {\n                return false;\n            }\n        }\n\n        return true;\n\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/RodrigoGit87.java",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\nimport java.util.*;\nimport java.util.ArrayList;\n\npublic class RodrigoGit87 {\n\n    // extra\n    public static void checkWord(String string1, String string2) {\n        // Normalizar las palabras (convertir a minúsculas y eliminar espacios)\n        String palabra1 = string1.toLowerCase().replace(\" \", \"\");\n        String palabra2 = string2.toLowerCase().replace(\" \", \"\");\n\n        System.out.println(\"\\n=== ANÁLISIS DE PALABRAS ===\");\n        System.out.println(\"Palabra 1: \" + string1);\n        System.out.println(\"Palabra 2: \" + string2);\n        System.out.println(\"============================\\n\");\n\n        // Verificar palíndromos\n        boolean esPalindromo1 = esPalindromo(palabra1);\n        boolean esPalindromo2 = esPalindromo(palabra2);\n\n        System.out.println(\"¿'\" + string1 + \"' es palíndromo? \" + esPalindromo1);\n        System.out.println(\"¿'\" + string2 + \"' es palíndromo? \" + esPalindromo2);\n\n        // Verificar anagramas\n        boolean sonAnagramas = sonAnagramas(palabra1, palabra2);\n        System.out.println(\"\\n¿Son anagramas? \" + sonAnagramas);\n\n        // Verificar isogramas\n        boolean esIsograma1 = esIsograma(palabra1);\n        boolean esIsograma2 = esIsograma(palabra2);\n\n        System.out.println(\"\\n¿'\" + string1 + \"' es isograma? \" + esIsograma1);\n        System.out.println(\"¿'\" + string2 + \"' es isograma? \" + esIsograma2);\n    }\n\n    // Método auxiliar para verificar si una palabra es palíndromo\n    private static boolean esPalindromo(String palabra) {\n        int longitud = palabra.length();\n        for (int i = 0; i < longitud / 2; i++) {\n            if (palabra.charAt(i) != palabra.charAt(longitud - 1 - i)) {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    // Método auxiliar para verificar si dos palabras son anagramas\n    private static boolean sonAnagramas(String palabra1, String palabra2) {\n        // Si tienen diferente longitud, no pueden ser anagramas\n        if (palabra1.length() != palabra2.length()) {\n            return false;\n        }\n\n        // Convertir las palabras a arrays de caracteres y ordenarlos\n        char[] chars1 = palabra1.toCharArray();\n        char[] chars2 = palabra2.toCharArray();\n\n        Arrays.sort(chars1);\n        Arrays.sort(chars2);\n\n        // Comparar los arrays ordenados\n        return Arrays.equals(chars1, chars2);\n    }\n\n    // Método auxiliar para verificar si una palabra es isograma\n    private static boolean esIsograma(String palabra) {\n        // Usar un conjunto para verificar caracteres únicos\n        java.util.HashSet<Character> caracteresVistos = new java.util.HashSet<>();\n\n        for (int i = 0; i < palabra.length(); i++) {\n            char c = palabra.charAt(i);\n            // Si el carácter ya existe en el conjunto, no es isograma\n            if (caracteresVistos.contains(c)) {\n                return false;\n            }\n            caracteresVistos.add(c);\n        }\n        return true;\n    }\n\n    public static void main(String[] args) {\n        // --- STRINGS ---\n        System.out.println(\"--- operaciones básicas con Strings \");\n        //los Strings son objetos (no tipos primitivos) y tienen una característica fundamental: son inmutables.\n        // Esto significa que cuando creas un String, no puedes modificarlo.\n        // Cuando \"modificas\" un String (por ejemplo, pasándolo a mayúsculas), Java no cambia el original, sino que crea uno nuevo en memoria\n        String vacio = \"\";\n        String saludo = \"Hola Mundo\";\n        // .length devuelve la longitud\n        IO.println(vacio.length()); // <-- 0\n        IO.println(saludo.length()); // <-- 11\n        // .isEmpty, booleano, devuelve true si el length == 0\n        IO.println(vacio.isEmpty());\n        IO.println(saludo.isEmpty());\n        // isBlank(): Devuelve true si la cadena está vacía o solo contiene espacios en\n        IO.println(vacio.isBlank());\n        IO.println(saludo.isBlank());\n\n        System.out.println(\"--- operaciones comparación con Strings \");\n        // .equals(otro string) y equalsIgnoreCase(otro string), comparan el string d la\n        // variable con el string entre parentesis\n        IO.println(saludo.equalsIgnoreCase(\"hola mundo\"));\n        IO.println(saludo.equalsIgnoreCase(vacio));\n        // compareTo(otro string): Devuelve un número (0 si son iguales, negativo si la\n        // primera es menor alfabéticamente, positivo si es mayor). Muy útil para\n        // ordenar listas.\n        String saludoInverso = \"Mundo Hola\";\n        IO.println(saludo.compareToIgnoreCase(saludoInverso));\n\n        System.out.println(\"--- operaciones busqueda y acceso\");\n        // charAt(int indice)\n        IO.println(saludo.charAt(0));\n        // contains(CharSequence s) Devuelve true si la cadena contiene la secuencia\n        // indicada\n        IO.println(saludoInverso.contains(\"Mundo\")); // true, por que \"Mundo\" si esta contenido en saludoInverso\n        // indexof, Devuelve la posición de la primera aparición del texto buscado.\n        // Devuelve -1 si no lo encuentra.\n        IO.println(saludo.indexOf(\"u\"));\n\n        System.out.println(\"--- modificacion\");\n        // siguientes metodos devuelven un NUEVO String, no reemplazan el original\n        String original = \" Retos de MoureDev\";\n        IO.println(original.length());\n        IO.println(original.indexOf(\"M\"));\n        // substring(int inicio, int fin): Extrae una parte de la cadena. El índice fin\n        // es exclusivo (no se incluye)\n        String cortado = original.substring(0, 10);\n        IO.println(cortado);\n        // .trim() <-- Quita espacios del principio y del final\n        IO.println(original.trim());\n        // .toLowerCase y .toUpperCase\n        String enMayus = original.toUpperCase();\n        String enMinus = original.toLowerCase();\n        IO.println(enMayus + \" : \" + enMinus);\n        // replace <- remplaza caracteres o secuencias\n        String kit = \"kit\";\n        String reemplazado = kit.replace(\"i\", \"a\");\n        IO.println(kit + \"-\" + reemplazado);\n        \n\n\n        System.out.println(\"--- Dividir y unir\");\n        System.out.println(\".split()\");\n        // Util con texto separado por comas , lineas, puntos .... DEvuelven un array\n        // split()\n        String listaContactos = \"Juan, Alfredo, RodrigoGit87, MoureDev, El gato volador\";\n        String[] contactos = listaContactos.split(\",\");\n        for (String c : contactos) {\n            System.out.print(c);\n        }\n        // String.join() <-- Une texto separado\n        System.out.println(\"\\n.join()\");\n        String años = String.join(\",\", \"2020\", \"2021\", \"2022\", \"2023\");\n        IO.println(años);\n        // es mas usado para ArrayList\n        ArrayList<String> añosList = new ArrayList<>();\n        añosList.add(\" 2024\");\n        añosList.add(\" 2025\");\n        añosList.add(\" 2026\");\n        añosList.add(\" 2027\");\n\n        String resultado = String.join(\"/\", añosList);\n        IO.println(resultado);\n\n        System.out.println(\"--- Conversion\");\n        String numRandom = \"500\";\n        // Integer.valueOf() <-- De String a Integer (objeto wrapper), q es util cuando\n        // queremos usar lo devuelto para añadir a una List por ejemplo\n        int añosInteger = Integer.valueOf(numRandom);\n        IO.println(\"Integer: \" + añosInteger);\n        // Integer.parseInt(): Devuelve un int (tipo primitivo)., q es mas usado en\n        // operaciones aritméticas\n        int añosInt = Integer.parseInt(numRandom);\n        IO.println(\"int: \" + añosInt);\n        // String.valueOf(): Convierte cualquier tipo primitivo (int, double, boolean) a\n        // String\n        double estatura = 1.81;\n        String altura = String.valueOf(estatura);\n        IO.println(altura);\n        // forma rápida (y menos purista) añadiendo una cadena vacia al int, se\n        // convierte en String automaticamente por Java\n        String alturaRapida = estatura + \"\";\n        //tocharArray <- Convierte un string en un array de caracteres\n        String palabra = \"palabra\";\n        char[] letras = palabra.toCharArray();\n        IO.println(letras); \n        // Arrays.sort (ordena un array de caracteres pro orden alfabetico ' o numerico')\n        Arrays.sort(letras);\n        IO.println(letras);\n            //podemos usar el metodo de comparacion equals con los arrays tambien\n            char[] letras2 = {'a','b','c'};\n            IO.println(Arrays.equals(letras, letras2));        \n\n\n        System.out.println(\"\\n\\n========================================\");\n        System.out.println(\" EXTRA: \");\n        System.out.println(\"========================================\");\n\n        // Ejemplo 1: Palíndromos\n        checkWord(\"ana\", \"oso\");\n\n        // Ejemplo 2: Anagramas\n        checkWord(\"amor\", \"roma\");\n\n        // Ejemplo 3: Isogramas\n        checkWord(\"murcielago\", \"python\");\n\n        // Ejemplo 4: Combinación\n        checkWord(\"reconocer\", \"arenero\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/RoniPG.java",
    "content": "// @Roni\n\nimport java.util.Arrays;\nimport java.util.Iterator;\nimport java.util.Set;\nimport java.util.TreeSet;\nimport java.util.stream.IntStream;\nimport java.util.stream.Stream;\n\npublic class CADENAS_DE_CARACTERES_04 {\n\n\tpublic static void main(String[] args) {\n\t\t\t\n\t\t//Crear una cadena de caracteres\n\t\t\n\t\tString ejemplo = \"Hola Mundo\";\n\t\tString ejemplo2; ejemplo2 = \"Hello World\"; // --> Otra manera de crear\n\t\t\n\t\t//Mostrar cracter por su posicion\n\t\t\n\t\tSystem.out.println(ejemplo.charAt(0)); // --> Mostrar el caracater en la posicion 0 de la cadena\n\t\tSystem.out.println(ejemplo.codePointAt(0)); // --> Mostrar el valor del caracter en la posicion 0 de la cadena en codigo Unicode\n\t\tSystem.out.println(ejemplo.codePointBefore(4)); // --> Mostrar el valor del caracter en la posicion (4-1) de la cadena en codigo Unicode \n\t\tSystem.out.println(ejemplo.compareTo(ejemplo2)); // --> Comparamos dos cadenas de caracteres mediante el codigo Unicode para determinar \n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t//cual es mayor\n\t\tSystem.out.println(ejemplo.compareToIgnoreCase(ejemplo2)); // --> Comparamos dos caracteres o cadenas de caracteres, sin tener encuenta\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t      //las mayusculas/minusculas, mediante el codigo Unicodepara determinar cual es mayor\n\t\tSystem.out.println(ejemplo.concat(ejemplo2)); // --> Concatenamos dos cadenas de caracteres\n\t\tSystem.out.println(ejemplo.contains(\"Hola\")); // --> Comprueba si dentro de la cadena de caracteres se encuentran los mismos caracteres\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t//que en el parametro dado\n\t\tSystem.out.println(ejemplo.contentEquals(ejemplo2)); // --> Comprueba si dos cadenas de caracteres son exactamente iguales\n\t\tSystem.out.println(ejemplo.endsWith(\"Mundo\")); // --> Comprueba si la cadena de caracteres termina igual que la cadena que le pasemos\n\t\tSystem.out.println(ejemplo.equals(ejemplo2)); // --> Comprueba que la cadenas de caracteres sea exactamente igual en contenido a \n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// un objeto de tipo string\n\t\tSystem.out.println(ejemplo.equalsIgnoreCase(\"HoLa mUnDo\")); // --> Comprueba que la cadenas de caracteres sea exactamente igual en contenido \n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// a un objeto de tipo string sin tener en cuenta las mayusculas/minusculas\n\t\tSystem.out.println(ejemplo.getBytes()); // --> Devuelve un array de bytes a partir de la cadena de caracteres\n\t\tSystem.out.println(ejemplo.hashCode()); // --> Devuelve el un codigo(hashCode) generado apartir de la cadena de caracteres\n\t\tSystem.out.println(ejemplo.indent(5)); // --> Devuelve la cadena de caracteres con espacios en blanco al principio que le indiquemos como parametro\n\t\tSystem.out.println(ejemplo.indexOf('o')); // --> Devuelve la primera posicion del caracter indicado dentro de la cadena de caracteres\n\t\tSystem.out.println(ejemplo.indexOf(\"la\")); // --> Devuelve la primera posicion de la cadena de caracteres que coincida con la cadena de caracteres\n\t\t\t\t\t\t\t\t\t\t\t\t\t// del parametro\n\t\tSystem.out.println(ejemplo.indexOf('o', 3)); // --> Devuelve la primera posicion del caracter indicado apartir de la posicion indicada y que si se \n\t\t\t\t\t\t\t\t\t\t\t\t\t// encuentra dentro de la cadena de caracteres\n\t\tSystem.out.println(ejemplo.indexOf(\"la\", 6)); // --> Devuelve la primera posicion del la cadena de caracteres que coincida con la cadena de caracteres\n\t\t\t\t\t\t\t\t\t\t\t\t\t//del parametro apartir de la posicion indicada\n\t\tSystem.out.println(ejemplo.isBlank()); //Devuelve True si la cadena de caracteres esta compuesta de espacios en blanco, o si no contiene nada.\n\t\tSystem.out.println(ejemplo.isEmpty()); //Devuelve True si la cadena de caracteres no contiene nada (si ejemplo.length()==0).\n\t\tSystem.out.println(ejemplo.lastIndexOf('o')); // --> Devuelve la ultima posicion del caracter indicado dentro de la cadena de caracteres\n\t\tSystem.out.println(ejemplo.lastIndexOf(\"la\")); // --> Devuelve la ultima posicion de la cadena de caracteres que coincida con la cadena de caracteres\n\t\t\t\t\t\t\t\t\t\t\t\t\t// del parametro\n\t\tSystem.out.println(ejemplo.lastIndexOf('o',3)); // --> Devuelve la primera posicion del caracter indicado apartir de la posicion indicada\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t//(en orden inverso)y si se encuentra dentro de la cadena de caracteres\n\t\tSystem.out.println(ejemplo.lastIndexOf(\"la\", 6)); // --> Devuelve la posicion del la cadena de caracteres que coincida con la cadena de caracteres\n\t\t\t\t\t\t\t\t\t\t\t\t\t//del parametro apartir de la posicion indicada en orden inverso\n\t\tSystem.out.println(ejemplo.length()); // --> Devuelve el tamaño de la cadena de caracteres\n\t\tSystem.out.println(ejemplo.matches(\"(.*)un(.*)\")); // --> Busca dentro de la cadena de caracteres mediante Expresiones Regulares (RegEx)\n\t\tSystem.out.println(ejemplo.repeat(2)); // --> Devuelve la cadena de caracteres repetida tanta veces como le indiquemos\n\t\tSystem.out.println(ejemplo.replace('o','e')); // --> Reemplaza el primer caracter por el segundo en toda la cadena de caracteres\n\t\tSystem.out.println(ejemplo.replace(ejemplo, ejemplo2)); // --> Reemplaza la primera cadena de caracteres por la segunda\n\t\tSystem.out.println(ejemplo.replaceAll(\"un\", \"dos\")); //  --> Reemplaza la primera cadena de caracteres por la segunda utilizando la busqueda RegEX\n\t\tSystem.out.println(ejemplo.replaceFirst(\"o\", \"i\")); // --> Reemplaza la primera cadena de caracteres por la segunda en la primera coincidencia\n\t\tSystem.out.println(ejemplo.startsWith(\"Ho\")); // --> Devuelve True si la cadena de caracteres empieza exactamente igual que la cadena de caracteres del parametro, \n\t\t\t\t\t\t\t\t\t\t\t\t\t\t// si el paramero esta vacio, o es .equals() a la cadena de caracteres\n\t\tSystem.out.println(ejemplo.startsWith(\"la\", 1)); // --> Devuelve True si la cadena de caracteres empieza exactamente igual que la cadena de caracteres del parametro \n\t\t\t\t\t\t\t\t\t\t\t\t\t\t// y en el indice indicado, si el paramero esta vacio, o es .equals() a la cadena de caracteres\n\t\tSystem.out.println(\"\t\tEjemplo\\s\\s\\s\\s\".strip()); // --> Devuelve la cadena de caracteres sin los espacios en blanco del principio y del final\n\t\tSystem.out.println(\"    Hola\\n        Mundo\\n    Adios\".stripIndent()); // --> Devuelve la cadena de caracteres sin los espacios en blanco del principio de cada \n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  //linea y que coincidan en tamaño.\n\t\tSystem.out.println(\"\t\tEjemplo\".stripLeading()); // --> Devuelve la cadena de caracteres sin los espacios en blanco del principio.\n\t\tSystem.out.println(\"Ejemplo\t\t\".stripTrailing()); // --> Devuelve la cadena de caracteres sin los espacios en blanco del final.\n\t\tSystem.out.println(ejemplo.substring(4)); // --> Devuelve una cadena de cararacteres apartir del indice dado\n\t\tSystem.out.println(ejemplo.substring(1, 4)); // --> Devuelve una cadena de cararacteres apartir del primer indice hasta el segundo indice.\n\t\tSystem.out.println(ejemplo.toCharArray()); // --> Devuelve un array de caracteres (no asignable a un String/cadena de caracteres)\n\t\tSystem.out.println(ejemplo.toLowerCase()); // --> Devuelve una la cadena de caracteres en minuscula\n\t\tInteger num = 5;\n\t\tSystem.out.println(num.toString()); // --> Devuelve la representacion en cadena de caracteres de un objeto\n\t\tSystem.out.println(ejemplo.toUpperCase()); // --> Devuelve una la cadena de caracteres en mayuscula\n\t\tSystem.out.println(ejemplo.translateEscapes()); // --> Traduce los escapes de teclado ej:\"\\u005Cn\"(salto de linea)\n\t\tSystem.out.println(\"\t\tEjemplo\\s\\s\\s\\s\".trim()); // --> Devuelve la cadena de caracteres sin los espacios en blanco del principio y del final\n\t\tSystem.out.println(ejemplo.getClass()); // --> Devuelve la clase del objeto\n\t\tString [] split = ejemplo.split(\" \");// --> Devuelve un array de cadenas de caracteres divididos por la cadena de caracteres que le indiquemos\n\t\tSystem.out.println(\"Primera posicion del array: \"+split[0]+\"\\nSegunda posicion del array: \"+split[1]);\n\t\tsplit = ejemplo.split(\"o\",2);// --> Devuelve un array de cadenas de caracteres divididos por la cadena de caracteres que le indiquemos y \n\t\t\t\t\t\t\t\t\t// con un indice del maximo de divisiones que queremos realizar\n\t\tSystem.out.println(\"Primera posicion del array: \"+split[0]+\"\\nSegunda posicion del array: \"+split[1]);\n\t\tSystem.out.println(ejemplo.subSequence(2, 8)); // --> Devuelve una cadena de cararacteres apartir del primer indice hasta el segundo indice.\n\t\tStream<String> lines = \"Hola\\nNuevo\\nMundo\".lines(); // --> Devuelve un stream de líneas extraídas de la cadena de caracteres, separadas por terminadores de línea.\n\t\tlines.forEach(System.out::println);\n\t\t\n\t\t/* DIFICULTAD EXTRA (opcional):\n\t\t * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n\t\t * para descubrir si son:\n\t\t * - Palíndromos\n\t\t * - Anagramas\n\t\t * - Isogramas\n\t\t */\n\t\tPalindromo(\"Anilina\");\n\t\tAnagrama(\"Roma\",\"Ramo\");\n\t\tIsograma(\"Acondicionar\");\n\t}\t\t\n\tpublic static void Palindromo(String a) {\n\t\t/* Palindromo: \n\t\t * Palabra o frase cuyas letras están dispuestas de tal manera que resulta la misma leída de izquierda a derecha que de derecha a izquierda.\n\t\t * Por ejemplo: anilina\n\t\t */\n\t\tString aux=\"\";\n\t\tfor(int i = a.length()-1; i>=0 ; i--) {\n\t\t\taux += a.charAt(i);\n\t\t}\n\t\tif(aux.equalsIgnoreCase(a)) {\n\t\t\tSystem.out.println(\"\\nSon Palabras Palindromas\");\n\t\t}else {\n\t\t\tSystem.out.println(\"No son palabras Palindromas\");\n\t\t}\n\t}\n\tpublic static void Anagrama(String a, String b) {\n\t\t/* Anagrama:\n\t\t * Cambio en el orden de las letras de una palabra o frase que da lugar a otra palabra o frase distinta.\n\t\t * Por ejemplo: Amor --> Roma\n\t\t */\n\t\tchar[] a1= a.toLowerCase().toCharArray();\n\t\tchar[] b1= b.toLowerCase().toCharArray();\n\t\tArrays.sort(a1);\n\t\tArrays.sort(b1);\n\t\tString sortA=\"\";\n\t\tString sortB=\"\";\n\t\tfor (int i = 0; i < a1.length; i++) {\n\t\t\tsortA += a1[i];\n\t\t}\n\t\tfor (int i = 0; i < b1.length; i++) {\n\t\t\tsortB += b1[i];\n\t\t}\n\t\tif (a.length()!= b.length()) {\n\t\t\tSystem.out.println(\"No son anagramas\");\n\t\t}\n\t\telse if (sortA.equals(sortB)) {\n\t\t\tSystem.out.println(\"Son anagramas\");\n\t\t}\n\t\telse {\n\t\t\tSystem.out.println(\"No son anagramas\");\n\t\t}\n\t}\n\tpublic static void Isograma(String a) {\n\t\t/* Un isograma es una palabra o frase en la que cada letra aparece el mismo número de veces.\n\t\t * Si cada letra aparece solo una vez será un heterograma, si aparece dos, un isogroma de segundo orden y así sucesivamente.\n\t\t * Por ejemplo:\n\t\t * Heterogramas: yuxtaponer, centrifugado, luteranismo.\n\t\t * Isogramas con una repetición o de segundo orden: acondicionar, escritura, intestinos.\n\t\t */\n\t\tboolean flag= false;\n\t\tint count=0;\n\t\tTreeSet<Character> subA = new TreeSet<>();\n\t\tfor (int i = 0; i < a.length(); i++) {\n\t\t\tsubA.add(a.charAt(i));\n\t\t}\n\t\tfor (Character character : subA) {\n\t\t\tfor (int i = 0; i < a.length(); i++) {\n\t\t\t\tif (character.equals(a.charAt(i))) {\n\t\t\t\t\tcount++;\t\t\t\t\t\n\t\t\t\t}\t\t\t\t\n\t\t\t}\n\t\t\tSystem.out.println(\"La letra: \\\"\"+character+\"\\\" esta repetida: \"+count+\" veces.\");\n\t\t\tif (count>1) {\n\t\t\t\tflag=true;\n\t\t\t}\n\t\t\tcount=0;\n\t\t}\n\t\tif(flag) {\n\t\t\tSystem.out.println(\"Es un isograma\");\n\t\t}else {\n\t\t\tSystem.out.println(\"Es un heterograma\");\n\t\t}\t\t\t\t\n\t}\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/SDM29GH.java",
    "content": "import java.util.Scanner;\n\npublic class SDM29GH {\n\n    public static void main(String[] args) {\n        \n        String ejemploCadena = \"Operaciones de cadena de caracteres\";\n        String cadena1 = \"Hola Mundo\"; String cadena2 = \"Bienvenido\"; String cadena3 = \"Bienvenido\"; String cadena4 = \"BIENVENIDO\";\n        String cadena5 = \"Mundo\"; String cadena6 = \"Hola\"; String cadenaVacía = \"\";\n        \n        System.out.println(ejemploCadena);\n\n        /* Método charAt(int index):Retorna el caracter específico en la posición que indica el index.\n        Para n cantidad de caracteres, primer posición = 0 y ultima posición = n-1*/\n        System.out.println(\"El primer caracter del ejemplo de la cadena es: \" + ejemploCadena.charAt(0));\n        System.out.println(\"El septimo caracter del ejemplo de la cadena es: \" + ejemploCadena.charAt(6));\n        System.out.println(\"El ultimo caracter del ejemplo de la cadena es: \" + ejemploCadena.charAt(34));\n\n        // Método equals(String str): Sirve para comparar si dos cadenas son iguales.Retona true de ser igual y false si no.\n        System.out.println(\"Método equals(String str)\");\n        System.out.println(\"Se compara entre cadena1 y cadena2: \"+cadena1.equals(cadena2));\n        System.out.println(\"Se compara entre cadena2 y cadena3: \"+cadena2.equals(cadena3));\n\n        /* Método equalsIgnoreCase(String str): Sirve para comparar si dos cadenas son iguales, ignorando la grafía de la palabra. \n        Devuelve true ser iguales y false si no.*/\n        System.out.println(\"Método equalsIgnoreCase(String str)\");\n        System.out.println(\"Se compara entre ejemploCadena y cadena1: \"+ejemploCadena.equalsIgnoreCase(cadena1));\n        System.out.println(\"Se compara entre cadena2 y cadena1: \"+cadena2.equalsIgnoreCase(cadena3));\n        System.out.println(\"Se compara entre cadena3 y cadena4: \"+cadena3.equalsIgnoreCase(cadena4));\n\n        /* Método compareTo(String otraCadena): Compara dos cadenas de caracteres alfabéticamente. Retorna 0 por iguales, entero negativo \n        si la primera es menor o entero positivo si la primera es mayor.*/\n        System.out.println(\"Método compareTo(String otraCadena)\");\n        System.out.println(\"Se compara entre cadena1 y cadena2: \" + cadena1.compareTo(cadena2));\n        System.out.println(\"Se compara entre cadena2 y cadena1: \" + cadena2.compareTo(cadena1));\n        System.out.println(\"Se compara entre cadena2 y cadena3: \" + cadena2.compareTo(cadena3));\n\n        // Método concat(String st): Concatena la cadena del parámetro al final de la primera cadena.\n        System.out.println(\"Método concat(String st)\");\n        System.out.println(\"Concatenación entre cadena1 y cadena2: \" + cadena1.concat(cadena2));\n\n        // Método contains(CharSequence s): Retorna true si la cadena contiene la secuencia tipo char del parámetro.\n        System.out.println(\"Método contains(CharSequence)\");\n        System.out.println(\"Para saber si cadena1 contiene la secuencia cadena5: \"+ cadena1.contains(cadena5));\n        System.out.println(\"Para saber si cadena1 contiene la secuencia cadena6: \"+ cadena1.contains(cadena6));\n\n        // Método endsWith(String suffix): Retorna verdadero si la cadena es igual al final del parámetro\n        System.out.println(\"Método endsWith(String suffix)\");\n        System.out.println(\"Para saber si cadena5 es igual al final de cadena1: \" + cadena1.endsWith(cadena5));\n        System.out.println(\"Para saber si cadena6 es igual al final de cadena1: \" + cadena1.endsWith(cadena6));\n\n\n        // Método indexOf(String str): Retorna el índice de la primera ocurrencia de la cadena del parámetro\n        System.out.println(\"Método indexOf(String str) en la frase: \" + ejemploCadena );\n        System.out.println(\"La palabra cadena está desde el índice: \" + ejemploCadena.indexOf(\"cadena\"));\n\n        // Método is Empty(): Retorna verdadero si la longitud de la cadena es 0\n        System.out.println(\"Método isEmpty()\");\n        System.out.println(\"Para saber si cadena1 está vacía: \" + cadena1.isEmpty());\n        System.out.println(\"Para saber si cadena1 está vacía: \" + cadenaVacía.isEmpty());\n\n        // Método length(): Para tener la longitud de la cadena\n        System.out.println(\"La longitud del ejemplo de la cadena es: \" + ejemploCadena.length() + \"caracteres\");\n\n        /* Método replaceAll(String regex, String replacement): Reemplaza todas las ocurrencias de la cadena del primer parámetro \n        por la del segundo */\n        System.out.println(\"Método replaceAll(String regex, String replacement)\");\n        System.out.println(\"Reemplazar la palabra cadena por texto ejemploCadena: \" + ejemploCadena.replaceAll(\"cadena\", \"texto\"));\n\n\n        // Método split(String regex): Divide la cadena en subcadenas y las guarda en un arreglo\n        System.out.println(\"Método split(String regex)\");\n        String[] arreglo = ejemploCadena.split(\" \");\n        System.out.println(\"La cadena se divide en: \" + arreglo.length + \" palabras\");\n        for (int i = 0; i < arreglo.length; i++) {\n            System.out.println(\"Palabra \" + (i + 1) + \": \" + arreglo[i]);\n        }\n\n\n        // Método startsWith(String prefix): Retorna verdadero si la cadena comienza con la cadena del parámetro\n        System.out.println(\"Método startsWith(String prefix)\");\n        System.out.println(\"Para saber si cadena1 comienza con la palabra Hola: \" + cadena1.startsWith(\"Hola\"));\n        System.out.println(\"Para saber si cadena1 comienza con la palabra Bienvenido: \" + cadena1.startsWith(\"Bienvenido\"));\n        System.out.println(\"Para saber si cadena1 comienza con la palabra Bienvenido: \" + cadena1.startsWith(\"Bienvenido\"));\n\n\n        /* Método substring(int beginIndex, int endIndex): Retorna una subcadena desde el índice del primer parámetro \n        hasta el índice del segundo parámetro */\n        System.out.println(\"Método substring(int beginIndex, int endIndex)\");\n        System.out.println(\"La subcadena de cadena1 desde el índice 0 hasta el índice 3 es: \" + cadena1.substring(0, 3));\n        System.out.println(\"La subcadena de cadena1 desde el índice 1 hasta el índice 5 es: \" + cadena1.substring(1, 5));\n        System.out.println(\"La subcadena de cadena1 desde el índice 2 hasta el índice 6 es: \" + cadena1.substring(2, 6));\n\n\n        // Método toLowerCase(): Convierte la cadena a minúsculas\n        System.out.println(\"Método toLowerCase()\");\n        System.out.println(\"La cadena1 en minúsculas es: \" + cadena1.toLowerCase());\n        System.out.println(\"La cadena2 en minúsculas es: \" + cadena2.toLowerCase());\n        System.out.println(\"La cadena3 en minúsculas es: \" + cadena3.toLowerCase());\n        System.out.println(\"La cadena4 en minúsculas es: \" + cadena4.toLowerCase());\n        System.out.println(\"La cadena5 en minúsculas es: \" + cadena5.toLowerCase());\n        System.out.println(\"La cadena6 en minúsculas es: \" + cadena6.toLowerCase());\n\n\n        // Método toUpperCase(): Convierte la cadena a mayúsculas\n        System.out.println(\"Método toUpperCase()\");\n        System.out.println(\"La cadena1 en mayúsculas es: \" + cadena1.toUpperCase());\n        System.out.println(\"La cadena2 en mayúsculas es: \" + cadena2.toUpperCase());\n        System.out.println(\"La cadena3 en mayúsculas es: \" + cadena3.toUpperCase());\n        System.out.println(\"La cadena4 en mayúsculas es: \" + cadena4.toUpperCase());\n        System.out.println(\"La cadena5 en mayúsculas es: \" + cadena5.toUpperCase());\n        System.out.println(\"La cadena6 en mayúsculas es: \" + cadena6.toUpperCase());\n        \n        // EXTRA\n\n        /* PALÍNDROMO: palabra, frase, número o cualquier otra secuencia de unidades\n        que tiene la propiedad de leerse igual hacia adelante que hacia atrás. */ \n        /*Ejemplo:\n        Palabra: \"anilina\", \"arenera\".\n        Frase: \"Anita lava la tina\".\n        Número: 12321. */\n        \n        System.out.println(\"Método Palíndromo\");\n\n        Scanner entrada = new Scanner(System.in);\n\n        System.out.println(\"Ingrese la palabra, frase o número: \");\n        String palabra = entrada.nextLine();\n        System.out.println(\"La palabra, frase o número \" + palabra + \" ¿es un palíndromo?\");\n        palíndromo(palabra);\n        \n    }\n    public static void palíndromo(String palabra) {\n        String cadenaInvertida = \"\";\n        for (int i = palabra.length() - 1; i >= 0; i--) {\n            cadenaInvertida += palabra.charAt(i);\n        }\n        if (palabra.equals(cadenaInvertida)) {\n            System.out.println(\"Es Palíndromo\");\n        } else {\n            System.out.println(\"No es palíndromo\");\n        }\n    }\n\n}\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/SandLeon.java",
    "content": "import java.util.Arrays;\n\npublic class SandLeon {\n    public static void main(String[] args) {\n\n        String text = \" Los sueños no funcionan a menos que tu trabajes en ellos. \";\n        String text2 = \"Cada dia es una nueva oportunidad para intentarlo otra vez.\";\n\n        //Longitud del texto, incluye espacios.\n        System.out.println(\"Longitud de cadena: \" + text.length());\n\n        //Comparar dos cadenas.\n        System.out.println(\"Comparar cadenas: \" + text.equals(text2));\n        System.out.println(\"Comparar cadenas ignorando case: \" + text.equalsIgnoreCase(text2));//Ignorando mayúsculas y minúsculas.\n\n        // Convierte a array de caracteres.\n        System.out.println(Arrays.toString(text.toCharArray()));\n\n        // Transforma a Mayúsculas o Minúsculas.\n        System.out.println(\"Texto en Mayúsculas: \" + text.toUpperCase());\n        System.out.println(\"Texto en minúsculas: \" + text2.toLowerCase());\n\n        //Devuelve true solo si toda la cadena cumple exactamente con el patrón\n        System.out.println(\"Cumple el patron? \" + text2.matches(\"[a-z]+\\\\d+\"));   //[a-z] Cualquier letra de a hasta z en minúscula.\n        // \\\\d , un dígito numérico.\n\n        //Devuelve tru o false si contiene la cadena \"x\".\n        System.out.println(\"Contiene \\\"trabajes\\\" : \" + text.contains(\"trabajes\"));\n\n        //Comprobar si está vacío.\n        System.out.println(\"Está vacío?: \" + text2.isEmpty());\n\n        //Elimina espacios al principio y al final.\n        System.out.println(text);\n        System.out.println(text.trim());\n\n        //Reemplazar\n        System.out.println(\"Hola me llamo Sandra\".replace(\"a\",\"e\"));\n        System.out.println(text.replace(\"sueños\",\"duendes\"));\n\n        //Repetición cadenas\n        System.out.println(\"Vacaciones \".repeat(4));\n\n        // Dar formato\n        String name = \"Sandra\";\n        int age = 35;\n        System.out.printf(\"Hola, %s. tengo %d años.%n\", name, age);\n\n        //Substraer subcadena\n        System.out.println(text2.substring(6));//Desde posición 6 hasta final.(Los espacios cuentan.)\n\n        //Acceso a un caracter.\n        System.out.println(text2.charAt(5));//por indice 5\n        System.out.println(text.charAt(text.length()-2));//Penúltima posición.\n\n        //Concatenar\n        System.out.println(text + \" \" + text2);\n\n        // DIFICULTAD EXTRA\n\n        //Palíndromo.\n        System.out.println(isPalindrome(\"Farolillo\"));\n        System.out.println(isPalindrome(\"reconocer\"));\n\n        //Anagrama\n        System.out.println(isAnagram(\"caseta\",\"alfombra\"));\n        System.out.println(isAnagram(\"Riesgo\",\"sergio\"));\n\n        //Isograma.\n        System.out.println(isIsogram(\"Abecedario\"));\n        System.out.println(isIsogram(\"plumero\"));\n\n\n\n    }\n\n    /* DIFICULTAD EXTRA (opcional):\n     * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n     * para descubrir si son:\n     * - Palíndromos\n     * - Anagramas\n     * - Isogramas\n     */\n\n    //PALÍNDROMO\n\n    public static boolean isPalindrome(String str1){\n        System.out.println(\"La palabra \" + \"\\\"\" + str1 + \" \\\"  es palíndromo?\");\n        return  str1.equals(new StringBuilder(str1).reverse().toString());\n    }\n\n    //ANAGRAMA\n    public static boolean isAnagram(String str1, String str2){\n\n        System.out.println(\"La palabra \" + \"\\\"\" + str1 + \"\\\" y  \\\"\" + str2 +\"\\\" \" + \"son anagrama?\");\n\n        //  Quitar espacios y convertimos todo a minúsculas.\n        str1 = str1.replaceAll(\"\\\\s\", \"\").toLowerCase();\n        str2 = str2.replaceAll(\"\\\\s\", \"\").toLowerCase();\n\n        if(str1.length() != str2.length()){\n            return false;\n        }\n        // Crear arrays de chars para ordenarlos.\n        char[] array1 = str1.toCharArray();\n        char [] array2 = str2.toCharArray();\n        //Ordenar arrays.\n        Arrays.sort(array1);\n        Arrays.sort(array2);\n        // Comparación arrays.\n        return Arrays.equals(array1,array2);\n    }\n\n    //ISOGRAMA\n\n    public static boolean isIsogram(String str1){\n\n        System.out.println(\"La palabra \" + \"\\\"\" + str1 + \" \\\"  es isograma?\");\n\n        //Ignorar espacios, tildes y mayúsculas.\n        str1 = str1.toLowerCase().replaceAll(\"[^a-záéíóúüñ]\", \"\");\n        return str1.length() == str1.chars().distinct().count();\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/TofeDev.java",
    "content": "import java.util.Arrays;\nimport java.util.HashSet;\nimport java.util.Set;\n\npublic class TofeDev {\n    public static void main(String[] args) {\n        \n        String texto = \"El día de hoy está soleado\";\n        String texto2 = \"puede que hoy llueva\";\n\n        //Acceso a un caracter específico\n        char caracter = texto.charAt(3);\n        System.out.println(caracter); //d\n\n        //Subcadena\n        String subcadena = texto.substring(14, 26);\n        System.out.println(subcadena); //está soleado\n\n        //Longitud\n        int longitud = texto.length();\n        System.out.println(longitud); //26\n\n        //Concatenación\n        String concatenacion = texto + \" y \" + texto2;\n        System.out.println(concatenacion);\n\n        //División\n        String[] division = \"rojo, amarillo, azul, morado\".split(\", \");\n        for (int i = 0; i <division.length; i++) {\n            System.out.println(division[i]);\n        }\n\n        //Conversión mayúsculas\n        String mayuscula = texto.toUpperCase();\n        System.out.println(mayuscula);\n\n        //Conversión minúscula\n        String minuscula = texto.toLowerCase();\n        System.out.println(minuscula);\n\n        //Reemplazo\n        String reemplazado = texto.replace(\"soleado\", \"nublado\");\n        System.out.println(reemplazado);\n\n        //Verificación\n        boolean contiene = texto.contains(\"hoy\");\n        System.out.println(contiene); //true\n\n        /* DIFICULTAD EXTRA (opcional):\n        * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n        * para descubrir si son:\n        * - Palíndromos\n        * - Anagramas\n        * - Isogramas\n        */ \n\n        String palabra1 = \"reconocer\";\n        String palabra2 = \"ballena\";\n        String palabra3 = \"llenaba\";\n        String palabra4 = \"cuervo\";\n\n        palindromo(palabra1); //True\n        palindromo(palabra4); //False\n\n        anagrama(palabra2, palabra3); //True\n        anagrama(palabra3, palabra4); //False\n\n        isograma(palabra4); //True\n        isograma(palabra1); //False\n    }\n\n        //Palíndromo\n    public static void palindromo(String palabra) {\n        String palabraInvertida = \"\";\n        for (int i = palabra.length() - 1; i >= 0; i--) {\n            palabraInvertida += palabra.charAt(i);\n        }\n        if (palabra.equals(palabraInvertida)) {\n            System.out.println(\"Es palíndromo\");\n        } else {\n            System.out.println(\"No es palíndromo\");\n        }\n    }\n\n        //Anagrama\n    public static void anagrama(String pal1,String pal2) {\n        char[] chars1 = pal1.toLowerCase().toCharArray();\n        char[] chars2 = pal2.toLowerCase().toCharArray();\n        Arrays.sort(chars1);\n        Arrays.sort(chars2);\n        if (Arrays.equals(chars1, chars2)) {\n            System.out.println(\"Es un anagrama\");\n        } else {\n            System.out.println(\"No es un anagrama\");\n        }\n    }\n\n        //Isograma\n    public static void isograma(String palabra) {\n        Set<Character> letras = new HashSet<>();\n        char[] cadenaToChar = palabra.toCharArray();\n        for(char letra : cadenaToChar){\n           letras.add(letra);\n        }\n        if (palabra.length() == letras.size()) {\n            System.out.println(\"Es un isograma\");\n        } else {\n            System.out.println(\"No es un isograma\");\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/Worlion.java",
    "content": "import java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.HashMap;\n\npublic class Worlion {\n    /*\n * EJERCICIO: #04 CADENAS DE CARACTERES\n */\n\n    public static void main(String[] args) {\n        new Worlion().run();\n    }\n    \n    public void run() {\n        base();\n        analiceWords(\"arroz\", \"zorra\");\n    }\n\n    public void base() {\n        String cadena = \"Hola Mundo\";\n        System.out.println(\"Cadena original: \" + cadena);\n\n        // Acceso a caracteres específicos\n        System.out.println(\"Primer caracter: \" + cadena.charAt(0));\n        System.out.println(\"Último caracter: \" + cadena.charAt(cadena.length() - 1));\n\n        // Subcadenas\n        System.out.println(\"Subcadena desde la posición 5: \" + cadena.substring(5));\n        System.out.println(\"Subcadena desde la posición 5 hasta la 7: \" + cadena.substring(5, 8));\n\n        // Longitud\n        System.out.println(\"Longitud de la cadena: \" + cadena.length());\n\n        // Concatenación\n        System.out.println(\"Concatenación: \" + cadena.concat(\" desde Java\"));\n\n        // Repetición\n        System.out.println(\"Repetición: \" + cadena.repeat(3));\n\n        // Recorrido\n        for (int i = 0; i < cadena.length(); i++) {\n            System.out.println(\"Caracter en la posición \" + i + \": \" + cadena.charAt(i));\n        }\n\n        // Conversión a mayúsculas y minúsculas\n        System.out.println(\"Mayúsculas: \" + cadena.toUpperCase());\n        System.out.println(\"Minúsculas: \" + cadena.toLowerCase());\n\n        // Reemplazo\n        System.out.println(\"Reemplazo de 'Hola' por 'Adiós': \" + cadena.replace(\"Hola\", \"Adiós\"));\n\n        // División\n        String[] palabras = cadena.split(\" \");\n        for (String palabra : palabras) {\n            System.out.println(\"Palabra: \" + palabra);\n        }\n\n        // Unión\n        System.out.println(\"Unión de palabras: \" + String.join(\" \", palabras));\n\n        // Interpolación\n        String nombre = \"Mundo\";\n        System.out.println(\"Interpolación: Hola \" + nombre);\n\n        // Verificación\n        System.out.println(\"¿La cadena contiene 'Mundo'?: \" + cadena.contains(\"Mundo\"));\n    }\n /*\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\n    public void analiceWords(String word1, String word2) {\n\n        System.out.println(\" \\n ---- 🌩 DIFICULTAD EXTRA 🌩 ----\\n\");\n\n        System.out.println(\"Analizando las palabas: '\" + word1 + \"'' y '\" + word2+\"'\");\n\n        System.out.println(\"Es palíndromo '\"+ word1 +\"'': \" + palindrome(word1));\n        System.out.println(\"Es palíndromo '\"+ word2 +\"'': \" + palindrome(word2));\n        System.out.println(\"Son anagramas: \" + anagram(word1, word2));\n        System.out.println(\"Es isograma '\"+ word1 +\"'': \" + isogram(word1));\n        System.out.println(\"Es isograma '\"+ word2 +\"'': \" + isogram(word2));\n\n    }\n\n    private boolean palindrome(String word){\n        return new StringBuilder(word).reverse().toString().equals(word);\n    }\n    private boolean anagram(String word1, String word2) {\n        String w1 = word1.chars().sorted().collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append).toString();\n        String w2 = word2.chars().sorted().collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append).toString();\n\n        return w1.equals(w2);\n    }\n    private boolean isogram(String word) {\n        HashMap<Character, Integer> map = new HashMap<>();\n\n        word.chars().forEach( c -> map.merge( (char)c, 1, Integer::sum));\n\n        Integer first = map.values().stream().findFirst().get();\n\n        return map.values().stream().allMatch(c -> c.equals(first));\n    }\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/alexdevrep.java",
    "content": "package Cadena_de_caracteres;\n/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\n *   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\n *   interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\npublic class Cadena_de_caracteres {\n    //Creando una cadena de caracteres\n   static String mi_cadena = \"Soy una cadena de caracteres\";\n\n    public static void main(String[] args){\n        //Acceder a caracteres específicos\n        System.out.println(mi_cadena.charAt(2));\n\n        //Creación de subcadenas\n        System.out.println(mi_cadena.substring(8,14));\n\n        //Calcular la longitud de la cadena de caracteres\n        System.out.println(mi_cadena.length());\n\n        //Concatenación de cadenas\n        System.out.println(mi_cadena.concat(\" y estoy creada por alexdevrep\"));\n\n        //Repetición de una cadena de caracteres\n        System.out.println(mi_cadena.repeat(3));\n\n        //Recorrido de la cadena de caracteres\n        for ( int i=0; i<mi_cadena.length();i++){\n            System.out.println(mi_cadena.charAt(i));\n\n        }\n\n        //Conversión de la cadena a mayúsculas\n        System.out.println(mi_cadena.toUpperCase());\n\n        //Conversión de la cadena a minúsculas\n        System.out.println(mi_cadena.toLowerCase());\n\n        //Reemplazo de los caracteres de la cadena\n        System.out.println(mi_cadena.replace('c','k'));\n\n        //División de la cadena de caracteres\n        System.out.println(mi_cadena.split(\" \"));\n\n        //Unión de una cadena de caracteres\n        String[] partes ={\"Hola\",\"mundo\"};\n        System.out.println(String.join(\",\",partes));\n\n        //Interpolación de texto en la cadena de caracteres\n        String nombre = \"Alexdevrep\";\n        System.out.println(String.format(\"Hola, %s\", nombre));\n\n        //Verificación de caracteres\n        System.out.println(mi_cadena.startsWith(\"S\"));\n\n\n\n\n\n\n    }\n\n\n}\n\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/alvarofernandezavalos.java",
    "content": "import java.util.Arrays;\n\npublic class alvarofernandezavalos {\n\n  public static void main(String[] args) {\n\n    String palabra = \"Alvaro.Fernandez.Avalos\";\n\n    System.out.println(\"Longitud: \"+palabra.length());\n    System.out.println(\"Mayúsculas: \"+palabra.toUpperCase());\n    System.out.println(\"Minúsculas: \"+palabra.toLowerCase());\n    System.out.println(\"Reemplazo: \"+palabra.replace('a', 'i'));\n    String [] split = palabra.split(\"\\\\.\");\n    for (String string : split) {\n      System.out.println(\"División: \"+string);\n    }\n    StringBuilder builder = new StringBuilder();\n    builder.append(\"Hola ! \")\n      .append(palabra.replace('.', ' '))\n      .append(\" !\");\n    System.out.println(\"String Builder: \"+builder.toString());\n    System.out.println(\"Recortar: \"+palabra.replace('.', ' ').trim());\n\n    String palabra1 = \"Raton\";\n    String palabra2 = \"Notar\";\n    System.out.println(palabra1 + \" y \" + palabra2 +\" son palíndromos \"+ palindromo(palabra1, palabra2));\n\n    palabra1 = \"Nacionalista\";\n    palabra2 = \"Altisonancia\";\n    System.out.println(palabra1 + \" y \" + palabra2 +\" son anagramas \"+ anagramas(palabra1, palabra2));\n\n    palabra1 = \"Dermatoglyphics\";\n    System.out.println(palabra1 + \"es isograma\" + isograma(palabra1));\n  }\n\n  private static boolean isograma(String palabra1) {\n    for (int i = 0; i < palabra1.length(); i++) {\n      for (int x = i + 1; x < palabra1.length(); x++) {\n        if (palabra1.charAt(i) == palabra1.charAt(x)) {\n            return false;\n        }\n      }\n    }\n    return true;\n  }\n\n  private static boolean palindromo(String palabra1, String palabra2) {\n    if (palabra1.length()!=palabra2.length()) return false;\n    for (int i = 0, x = palabra2.length() -1 ; i < palabra1.length() - 1; i++, x--) {\n      if (palabra1.toLowerCase().charAt(i)!=palabra2.toLowerCase().charAt(x)) return false;\n    }\n    return true;\n  }\n\n  private static boolean anagramas(String palabra1, String palabra2) {\n    char[] charsPalabra1 = palabra1.toLowerCase().toCharArray();\n    char[] charsPalabra2 = palabra2.toLowerCase().toCharArray();\n    Arrays.sort(charsPalabra1);\n    Arrays.sort(charsPalabra2);\n    return Arrays.equals(charsPalabra1, charsPalabra2);\n  }\n\n\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/asjordi.java",
    "content": "public class Main {\n\n    public static void main(String[] args) {\n        // Operaciones con Strings\n        opStrings();\n\n        String str1 = \"oso\";\n        String str2 = \"oso\";\n\n        System.out.println(str1 + \" es palíndromo de \" + str2 + \": \" + esPalindromo(str1, str2));\n        System.out.println(str1 + \" es anagrama de \" + str2 + \": \" + esAnagrama(str1, str2));\n        System.out.println(str1 + \" es isograma de \" + str2 + \": \" + esIsograma(str1, str2));\n\n    }\n\n    public static void opStrings() {\n        // Declarar un String\n        String str = \"lorem ipsum dolor sit amet consectetur adipiscing elit\";\n        // Obtener longitud de un String\n        System.out.println(\"Longitud de str: \" + str.length());\n        // Obtener un caracter de un String\n        System.out.println(\"Primer caracter de str: \" + str.charAt(0));\n        // Obtener un substring de un String\n        System.out.println(\"Substring de str: \" + str.substring(0, 5));\n        // Obtener la posición (índice) de un carácter en un String\n        System.out.println(\"Posición de 'i' en str: \" + str.indexOf('i'));\n        // Obtener el índice de la última posición de un carácter en un String\n        System.out.println(\"Ultima posición de 'i' en str: \" + str.lastIndexOf('i'));\n        // Obtener un arreglo de Strings a partir de un String\n        System.out.println(\"Arreglo de Strings a partir de str: \" + str.split(\" \"));\n        // Obtener un arreglo de caracteres a partir de un String\n        System.out.println(\"Arreglo de caracteres a partir de str: \" + str.toCharArray());\n        // Obtener un String a partir de un arreglo de caracteres\n        System.out.println(\"String a partir de un arreglo de caracteres: \" + new String(str.toCharArray()));\n        // Obtener un String a partir de un arreglo de Strings\n        System.out.println(\"String a partir de un arreglo de Strings: \" + String.join(\" \", str.split(\" \")));\n        // Repetir un String n veces\n        System.out.println(\"Repetir un String n veces: \" + str.repeat(2));\n        // Obtener un String en mayúsculas\n        System.out.println(\"String en mayúsculas: \" + str.toUpperCase());\n        // Obtener un String en minúsculas\n        System.out.println(\"String en minúsculas: \" + str.toLowerCase());\n        // Obtener un String sin espacios al inicio y al final\n        System.out.println(\"String sin espacios al inicio y al final: \" + str.trim());\n        // Obtener un String reemplazando caracteres\n        System.out.println(\"String reemplazando caracteres: \" + str.replace('i', 'a'));\n        // Obtener un String reemplazando caracteres con expresiones regulares\n        System.out.println(\"String reemplazando caracteres con expresiones regulares: \" + str.replaceAll(\"i\", \"a\"));\n        // Comparar Strings case sensitive\n        System.out.println(\"Comparar Strings: \" + str.equals(\"lorem ipsum\"));\n        // Comparar Strings case insensitive\n        System.out.println(\"Comparar Strings: \" + str.equalsIgnoreCase(\"lorem ipsum\"));\n        // Verificar si un String empieza con un prefijo\n        System.out.println(\"Verificar si un String empieza con un prefijo: \" + str.startsWith(\"lorem\"));\n        // Verificar si un String termina con un sufijo\n        System.out.println(\"Verificar si un String termina con un sufijo: \" + str.endsWith(\"elit\"));\n        // Verificar si un String es vacío\n        System.out.println(\"Verificar si un String es vacío: \" + str.isEmpty());\n        // Verificar si un String no es vacío y no contiene espacios en blanco\n        System.out.println(\"Verificar si un String no es vacío y no contiene espacios en blanco: \" + str.isBlank());\n        // Concatenar Strings\n        System.out.println(\"Concatenar Strings: \" + str.concat(\" dolor sit amet\"));\n        System.out.println();\n    }\n\n    /**\n     * Crea un programa que analice dos palabras diferentes y realice comprobaciones para descubrir si son:\n     * Palíndromos\n     * Anagramas\n     * Isogramas\n     */\n\n    public static boolean esPalindromo(String str1, String str2) {\n        return str1.equals(new StringBuilder(str2).reverse().toString());\n    }\n\n    public static boolean esAnagrama(String str1, String str2) {\n        String sortedStr1 = str1.chars().sorted().collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append).toString();\n        String sortedStr2 = str2.chars().sorted().collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append).toString();\n        return sortedStr1.equals(sortedStr2);\n    }\n\n    public static boolean esIsograma(String str1, String str2) {\n        String distinctStr1 = str1.chars().distinct().collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append).toString();\n        String distinctStr2 = str2.chars().distinct().collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append).toString();\n        return distinctStr1.equals(distinctStr2);\n    }\n\n\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/cesar-ch.java",
    "content": "// #04 CADENAS DE CARACTERES\n\n// Ejercicio\n\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class Main {\n    public static void main(String[] args) {\n        // Acceso a caracteres específicos:\n        String cadena = \"Hola, mundo!\";\n        char primerCaracter = cadena.charAt(0);\n        System.out.println(\"Primer caracter: \" + primerCaracter);\n\n        // Subcadenas:\n        String subcadena = cadena.substring(0, 4);\n        System.out.println(\"Subcadena: \" + subcadena);\n\n        // Longitud:\n        int longitud = cadena.length();\n        System.out.println(\"Longitud: \" + longitud);\n\n        // Concatenación:\n        String concatenacion = cadena.concat(\" Java\");\n        System.out.println(\"Concatenación: \" + concatenacion);\n\n        // Repetición:\n        String repeticion = cadena.repeat(3);\n        System.out.println(\"Repetición: \" + repeticion);\n\n        // Recorrido\n        for (int i = 0; i < cadena.length(); i++) {\n            char caracter = cadena.charAt(i);\n            System.out.println(\"Caracter: \" + i + \" - \" + caracter);\n        }\n\n        // Conversión a mayúsculas y minúsculas\n        String mayusculas = cadena.toUpperCase();\n        String minusculas = cadena.toLowerCase();\n        System.out.println(\"Mayúsculas: \" + mayusculas);\n        System.out.println(\"Minúsculas: \" + minusculas);\n\n        // Reemplazo:\n        String reemplazada = cadena.replace(\"mundo\", \"Java\");\n        System.out.println(\"Reemplazada: \" + reemplazada);\n\n        // División:\n        String[] division = cadena.split(\",\");\n        System.out.println(\"Division: \" + Arrays.toString(division));\n\n        // Unión\n        String[] arrayDePalabras = { \"Hola\", \"mundo\", \"Java\" };\n        String union = String.join(\" \", arrayDePalabras);\n        System.out.println(\"Union: \" + union);\n\n        // Interpolación\n        String interpolacion = String.format(\"Saludo: %s, Lenguaje: %s\", arrayDePalabras[0], arrayDePalabras[2]);\n        System.out.println(\"Interpolación: \" + interpolacion);\n\n        // Verificación\n        boolean empiezaConHola = cadena.startsWith(\"Hola\");\n        boolean terminaConMundo = cadena.endsWith(\"mundo!\");\n        System.out.println(\"Empieza con Hola: \" + empiezaConHola);\n        System.out.println(\"Termina con mundo: \" + terminaConMundo);\n\n        comprobarPalabra(\"Java\", \"Kotlin\");\n    }\n\n    private static void comprobarPalabra(String palabra1, String palabra2) {\n        System.out.println(\"Es palindromo: \" + esPalindromo(palabra1, palabra2));\n        System.out.println(\"Es anagrama: \" + esAnagrama(palabra1, palabra2));\n        System.out.println(\"Es isogama: \" + esIsogama(palabra1, palabra2));\n    }\n\n    private static boolean esPalindromo(String palabra1, String palabra2) {\n        if (palabra1.length() != palabra2.length()) {\n            return false;\n        }\n        return palabra1.toLowerCase().equals(new StringBuilder(palabra2.toLowerCase()).reverse().toString());\n    }\n\n    private static boolean esAnagrama(String palabra1, String palabra2) {\n        if (palabra1.length() != palabra2.length()) {\n            return false;\n        }\n        char[] chars1 = palabra1.toLowerCase().toCharArray();\n        char[] chars2 = palabra2.toLowerCase().toCharArray();\n        Arrays.sort(chars1);\n        Arrays.sort(chars2);\n        return Arrays.equals(chars1, chars2);\n    }\n\n    private static boolean esIsogama(String palabra1, String palabra2) {\n        if (palabra1.length() != palabra2.length()) {\n            return false;\n        }\n        Map<Character, Integer> charCounter = new HashMap<>();\n        for (char c : palabra1.toLowerCase().toCharArray()) {\n            charCounter.put(c, charCounter.getOrDefault(c, 0) + 1);\n        }\n\n        for (char c : palabra2.toLowerCase().toCharArray()) {\n            if (charCounter.containsKey(c)) {\n                charCounter.put(c, charCounter.get(c) - 1);\n            } else {\n                return false;\n            }\n        }\n        return charCounter.values().stream().allMatch(value -> value == 0);\n    }\n}"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/chartypes.java",
    "content": "\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class chartypes {\n\n    // Strings Operations\n    static void stringsOperations() {\n        String text = \"Hellodah\";\n        // Specific charracter\n        System.out.println(text.charAt(0));\n        // Concat\n        System.out.println(text.concat(\" world!\"));\n        // Substrings\n        System.out.println(text.substring(2));\n        // Length\n        System.out.println(text.length());\n        // Repeat\n        System.out.println(text.repeat(2));\n        // Upper Case\n        System.out.println(text.toUpperCase());\n        // Lower Case\n        System.out.println(text.toLowerCase());\n        // Replace\n        System.out.println(text.replace('H', 'j'));\n        // Union\n        System.out.println(String.join(\" - \", text, \"world\", \"!\", \"!\", \"!\"));\n        // Division\n        System.out.println(Arrays.toString(text.split(\"o\")));\n        // Contains\n        System.out.println(text.contains(\"Hello\"));\n        System.out.println(\"\\n-----------------------\\nExercise:\");\n\n    }\n\n    // Exercise Services\n    static boolean isPalindrome(String text) {\n        StringBuilder strBuilder = new StringBuilder();\n        for (int i = text.length() - 1; i >= 0; i--) {\n            strBuilder.append(text.charAt(i));\n        }\n        String reversedText = new String(strBuilder);\n        return text.equalsIgnoreCase(reversedText);\n\n    }\n\n    static Map<Character, Integer> lettersCounter(String text) {\n        Map<Character, Integer> counter = new HashMap<>();\n        for (char character : text.toCharArray()) {\n            counter.put(character, counter.getOrDefault(character, 0) + 1);\n        }\n        return counter;\n    }\n\n    static boolean isIsogram(String text) {\n        Map<Character, Integer> counter = lettersCounter(text);\n\n        int len = counter.get(text.charAt(0));\n\n        for (int value : counter.values()) {\n            if (value != len)\n                return false;\n        }\n        return true;\n\n    }\n\n    static boolean isAnagram(String text1, String text2) {\n        Map<Character, Integer> text1Counter = lettersCounter(text1);\n        Map<Character, Integer> text2Counter = lettersCounter(text2);\n        for (Map.Entry<Character, Integer> entry : text1Counter.entrySet()) {\n            char letter = entry.getKey();\n            int counter = entry.getValue();\n            try {\n                if (text2Counter.get(letter) != counter)\n                    return false;\n\n            } catch (NullPointerException e) {\n                return false;\n            }\n        }\n        return true;\n\n    }\n\n    static void exercise(String text1, String text2) {\n        text1 = text1.toLowerCase();\n        text2 = text2.toLowerCase();\n\n        // Palindrome\n        System.out.println(\"\\nPALIDROME:\");\n        if (isPalindrome(text1))\n            System.out.println(\"YES \" + text1 + \" is a palidrome\");\n        else\n            System.out.println(\"NO \" + text1 + \" is NOT a palidrome\");\n        if (isPalindrome(text2))\n            System.out.println(\"YES \" + text2 + \" is a palidrome\");\n        else\n            System.out.println(\"NO \" + text2 + \" is NOT a palidrome\");\n\n        // Anagram\n        System.out.println(\"\\nANAGRAM:\");\n        if (isAnagram(text1, text2))\n            System.out.println(\"YES \" + text1 + \" is a anagram of \" + text2);\n        else\n            System.out.println(\"NO \" + text1 + \" is NOT a anagram of \" + text2);\n\n        // Isogram\n        System.out.println(\"\\nISOGRAM:\");\n        if (isIsogram(text1))\n            System.out.println(\"YES \" + text1 + \" is a isogram\");\n        else\n            System.out.println(\"NO \" + text1 + \" is NOt a isogram\");\n        if (isIsogram(text2))\n            System.out.println(\"YES \" + text2 + \" is a isogram\");\n        else\n            System.out.println(\"NO \" + text2 + \" is NOt a isogram\");\n\n    }\n\n    public static void main(String[] args) {\n\n        stringsOperations();\n        exercise(\"reinier\", \"ambidextrously\");\n        exercise(\"angel\", \"glean\");\n        exercise(\"save\", \"vase\");\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/danhingar.java",
    "content": "import java.util.*;\n\npublic class danhingar {\n\n    public static void main(String[] args) {\n        String cadena = \"Hola\";\n        String cadena1 = \"Mundo\";\n\n        //Concatenación\n        System.out.println(cadena.concat(\" \").concat(cadena1));\n        System.out.println(cadena+\" \"+cadena1);\n\n        //Longitud\n        System.out.println(\"Longitd cadena: \"+cadena.length());\n\n        //Repetición\n        System.out.println(cadena.concat(\" \").repeat(3));\n\n        //Indexación\n        System.out.println(cadena.charAt(3));\n\n        //Porción\n        System.out.println(cadena.substring(2));\n        System.out.println(cadena.substring(0,1));\n      \n        //Búsqueda\n        System.out.println(cadena.contains(\"l\"));\n\n        //Reemplazo\n        System.out.println(cadena.replace(\"a\", \"o\"));\n\n        //Division\n        System.out.println(List.of(cadena1.split(\"n\")));\n        System.out.println(List.of(cadena1.splitWithDelimiters(\"n\",cadena1.indexOf(\"n\"))));\n        System.out.println(List.of(cadena1.split(\"[ud]\")));\n\n        //Mayusculas y minuscuulas\n        System.out.println(cadena.toUpperCase());\n        System.out.println(cadena.toLowerCase());\n        \n        //Eliminar espacion en blanco\n        String cadena3 =\"hola mundo \";\n        System.out.println(cadena3.stripTrailing());\n        System.out.println(cadena3.trim());\n        System.out.println(cadena3.strip());\n\n        //Búsqueda al principio y final\n        System.out.println(cadena3.startsWith(\"hol\"));\n        System.out.println(cadena3.endsWith(\"la\"));\n        System.out.println(cadena1.startsWith(\"Mu\"));\n        System.out.println(cadena3.trim().endsWith(\"do\"));\n\n        //Búsqueda por posición\n        System.out.println(\"Hola Mundo, Java!\".indexOf(\"Mundo\"));\n\n        //Interpolación\n        System.out.println(String.format(\"Hola %s, %s!\", cadena1,\"Java\"));\n\n        //Transformación en lista\n        System.out.println(cadena3.toCharArray()[0]);\n\n        //Transformacion a cadena\n        List<String> list = List.of(cadena,cadena1);\n        System.out.println(String.join(\" \", list));\n\n        //Comprobaciones varias\n        System.out.println(cadena.isBlank());\n        System.out.println(cadena.isEmpty());\n        System.out.println(cadena.matches(\"d\"));\n        System.out.println(cadena.equalsIgnoreCase(cadena1));\n\n        //EXTRA\n        check(\"roma\", \"amor\");\n    \n    }\n\n    private static void check(String word1,String word2){\n        isPalindrome(word1,word2);\n        isAnagram(word1,word2);\n        isIsogram(word1,word2);\n    }\n\n    private static void isPalindrome(String word1,String word2){\n        \n        System.out.println(String.format(\"¿%s es un palíndromo?: %b\", word1,checkPalindrome(word1)));\n        System.out.println(String.format(\"¿%s es un palíndromo?: %b\", word2,checkPalindrome(word2)));\n    }\n\n    private static boolean checkPalindrome(String word) {\n       String reverseWord =\"\";\n       for(int i=word.length()-1;i>=0;i--){\n        reverseWord+=word.charAt(i);\n       }\n       return word.equals(reverseWord);\n      \n    }\n\n    private static void isAnagram(String word1,String word2){\n        System.out.println(String.format(\"¿%s y %s son anagramas?: %b\", word1,word2,checkAnagram(word1,word2)));\n    }\n\n    private static Object checkAnagram(String word1,String word2) {\n        char[] letters1 = word1.replace(\" \", \"\").toCharArray();\n        char[] letters2 = word2.replace(\" \", \"\").toCharArray();\n        Arrays.sort(letters1);\n        Arrays.sort(letters2);\n        return Arrays.equals(letters1, letters2);\n    }\n\n    private static void isIsogram(String word1,String word2){\n        System.out.println(String.format(\"¿%s es un isodrama?: %b\", word1,checkIsogram(word1)));\n        System.out.println(String.format(\"¿%s es un isodrama?: %b\", word2,checkIsogram(word2)));\n    }\n\n    private static Object checkIsogram(String word1) {\n        for(int i=0; i<word1.length()-1;i++){\n            char letter =word1.charAt(i);\n            if(word1.indexOf(letter)!=word1.lastIndexOf(letter)){\n                return false;\n            }\n        }\n        return true;\n    }\n    \n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/deathwing696.java",
    "content": "\nimport java.util.Arrays;\nimport java.util.Scanner;\n\n/*\n * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license\n * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template\n */\n\n/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podran ser (busca todas las que puedas):\n * - Acceso a caracteres especficos, subcadenas, longitud, concatenacin, repeticin, recorrido,\n *   conversin a maysculas y minsculas, reemplazo, divisin, unin, interpolacin, verificacin...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palndromos\n * - Anagramas\n * - Isogramas\n */\n\n/**\n *\n * @author death\n */\npublic class deathwing696 {\n    \n    private Scanner lectura = new Scanner(System.in);\n    \n    public static void main(String[] args)\n    {\n        String palabra1 = \"amor\", palabra2 = \"Roma\";\n        Boolean palindromo1, palindromo2, anagrama, isograma1, isograma2;\n        \n        palindromo1 = EsPalindromo(palabra1);\n        palindromo2 = EsPalindromo(palabra2);\n        anagrama = EsAnagrama(palabra1, palabra2);\n        isograma1 = EsIsograma(palabra1);\n        isograma2 = EsIsograma(palabra2);\n        \n        if (palindromo1 && isograma1)\n            System.out.println(\"La palabra \" + palabra1 + \" es palndromo e isograma\");\n        else if (palindromo1)\n            System.out.println(\"La palabra \" + palabra1 + \" es palndromo\");\n        else if (isograma2)\n            System.out.println(\"La palabra \" + palabra1 + \" es un isograma\");\n        \n        if (palindromo2 && isograma2)\n            System.out.println(\"La palabra \" + palabra2 + \" es palndromo e isograma\");\n        else if (palindromo2)\n            System.out.println(\"La palabra \" + palabra2 + \" es palndromo\");\n        else if (isograma2)\n            System.out.println(\"La palabra \" + palabra2 + \" es un isograma\");\n        \n        if (anagrama)\n            System.out.println(\"Las palabras \" + palabra1 + \" y \" + palabra2 + \" son anagramas\");\n        \n    }\n    \n    private static Boolean EsPalindromo(String palabra)\n    {\n        String palabraReves;\n        \n        palabra = palabra.replace(\"\\\\s\", \"\").toLowerCase();\n        \n        palabraReves = new StringBuilder(palabra).reverse().toString();\n        \n        return palabra.equals(palabraReves);\n    }\n    \n    private static Boolean EsAnagrama(String palabra1, String palabra2)\n    {\n        char [] array1, array2;\n        \n        palabra1 = palabra1.replace(\"\\\\s\", \"\").toLowerCase();\n        palabra2 = palabra2.replace(\"\\\\s\", \"\").toLowerCase();\n        array1 = palabra1.toCharArray();\n        Arrays.sort(array1);\n        array2 = palabra2.toCharArray();        \n        Arrays.sort(array2);\n        \n        return Arrays.equals(array1, array2);\n    }\n    \n    private static Boolean EsIsograma(String palabra)\n    {\n        for (int i = 0; i < palabra.length();  i++)\n        {\n            for (int j = i + 1; j < palabra.length(); j++)\n            {\n                if (palabra.charAt(i) == palabra.charAt(j))\n                    return false;\n            }\n        }\n        \n        return true;\n    }\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/estuardodev.java",
    "content": "package org.example;/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\nimport java.util.Arrays;\n\npublic class estuardodev {\n    public static void main(String[] args) {\n        operaciones(\"C#\", \"Python\");\n        System.out.println(\"\\n-- Dificultad Extra --\\n\");\n        dificultadExtra(\"Palindromo\", \"Isograma\");\n        System.out.println(\"\\n----\\n\");\n        dificultadExtra(\"Ana\", \"OlLo\");\n    }\n\n    private static void operaciones(String texto1, String texto2) {\n        // Acceso a caracteres\n        System.out.println(\"-- Acceso a Indices de un texto --\");\n        System.out.println(\"Indice 0 del Texto 1: \" + texto1.charAt(0));\n        System.out.println(\"Indice 3 del Texto 2: \" + texto2.charAt(3) + \"\\n\");\n\n        // Crear subcadenas\n        System.out.println(\"-- Crear Subcadenas --\");\n        System.out.println(\"Subcadena del texto 1: \" + texto1.substring(1));\n        System.out.println(\"Subcadena del texto 2: \" + texto2.substring(3) + \"\\n\");\n\n        // Longitudes\n        System.out.println(\"-- Longitudes --\");\n        System.out.println(\"Longitud del texto 1: \" + texto1.length());\n        System.out.println(\"Longitud del texto 2: \" + texto2.length() + \"\\n\");\n\n        // Concatenación de cadenas\n        System.out.println(\"-- Concatenación --\");\n        System.out.println(\"Forma 1:\" + texto1 + \" \" + texto2);\n        System.out.println(\"Forma 2: \" + texto1 + \" \" + texto2 + \"\\n\");\n\n        // Repetición\n        System.out.println(\"-- Repetición --\");\n        for (int i = 0; i < 3; i++) {\n            System.out.println(texto1);\n        }\n        for (int i = 0; i < 3; i++) {\n            System.out.println(texto2);\n        }\n\n        // Recorrido\n        System.out.println(\"\\n-- Recorrido --\");\n        for (char i : texto1.toCharArray()) {\n            System.out.println(i);\n        }\n\n        // Conversión a mayúsculas\n        System.out.println(\"\\n-- Conversión a mayúsculas --\");\n        System.out.println(texto1.toUpperCase());\n        System.out.println(texto2.toUpperCase());\n\n        // Conversión a minúsculas\n        System.out.println(\"\\n-- Conversión a minúsculas --\");\n        System.out.println(texto1.toLowerCase());\n        System.out.println(texto2.toLowerCase());\n\n        // Reemplazo\n        System.out.println(\"\\n-- Reemplazo --\");\n        System.out.println(texto1.replace('#', '+'));\n        System.out.println(texto2.replace('o', '0'));\n\n        // Unión\n        System.out.println(\"\\n-- Unión --\");\n        System.out.println(texto1.concat(texto2));\n\n        // Interpolación\n        System.out.println(\"\\n-- Interpolación --\");\n        System.out.println(\"Lenguaje 1 es: \" + texto1 + \" y el 2 es: \" + texto2);\n\n        // Verificación\n        System.out.println(\"\\n-- Verificación --\");\n        System.out.println(texto1.equals(texto2));\n    }\n\n    // Dificultad Extra\n\n    // Anagrama\n    static boolean esAnagrama(String texto1, String texto2) {\n        char[] arreglo1 = texto1.toLowerCase().toCharArray();\n        char[] arreglo2 = texto2.toLowerCase().toCharArray();\n\n        Arrays.sort(arreglo1);\n        Arrays.sort(arreglo2);\n\n        return Arrays.equals(arreglo1, arreglo2);\n    }\n    private static void dificultadExtra(String texto1, String texto2) {\n        if (esAnagrama(texto1, texto2   )) {\n            System.out.println(\"Los textos son anagramas.\");\n        } else {\n            System.out.println(\"Los textos no son anagramas\");\n        }\n\n        // Palíndromos\n        String txt1 = texto1.toLowerCase();\n        String txt2 = texto2.toLowerCase();\n\n        if (txt1.equals(new StringBuilder(txt1).reverse().toString())) {\n            System.out.println(texto1 + \" es palíndromo.\");\n\n            if (txt2.equals(new StringBuilder(txt2).reverse().toString())) {\n                System.out.println(texto2 + \" es palíndromo.\");\n            } else {\n                System.out.println(texto2 + \" no es palíndromo.\");\n            }\n        } else if (txt2.equals(new StringBuilder(txt2).reverse().toString())) {\n            System.out.println(texto1 + \" no es palíndromo.\");\n            System.out.println(texto2 + \" es palíndromo.\");\n        } else {\n            System.out.println(texto1 + \" no es palíndromo.\");\n            System.out.println(texto2 + \" no es palíndromo.\");\n        }\n\n        // Isogramas\n        String text1 = texto1.toLowerCase();\n        String text2 = texto2.toLowerCase();\n\n        if (text1.length() == text1.chars().distinct().count()) {\n            System.out.println(texto1 + \" es Isograma\");\n        } else {\n            System.out.println(texto1 + \" no es Isograma\");\n        }\n\n        if (text2.length() == text2.chars().distinct().count()) {\n            System.out.println(texto2 + \" es Isograma\");\n        } else {\n            System.out.println(texto2 + \" no es Isograma\");\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/eulogioep.java",
    "content": "public class eulogioep {\n    public static void main(String[] args) {\n        // Declaración de una cadena\n        String texto = \"Hola, mundo!\";\n\n        // 1. Acceso a caracteres específicos\n        char primerCaracter = texto.charAt(0);\n        System.out.println(\"1. Primer carácter: \" + primerCaracter);\n\n        // 2. Subcadenas\n        String subcadena = texto.substring(0, 4);\n        System.out.println(\"2. Subcadena: \" + subcadena);\n\n        // 3. Longitud\n        int longitud = texto.length();\n        System.out.println(\"3. Longitud: \" + longitud);\n\n        // 4. Concatenación\n        String otraCadena = \" Bienvenidos\";\n        String concatenacion = texto.concat(otraCadena);\n        System.out.println(\"4. Concatenación: \" + concatenacion);\n\n        // 5. Repetición\n        String repetida = texto.repeat(3);\n        System.out.println(\"5. Repetición: \" + repetida);\n\n        // 6. Recorrido\n        System.out.print(\"6. Recorrido: \");\n        for (char c : texto.toCharArray()) {\n            System.out.print(c + \" \");\n        }\n        System.out.println();\n\n        // 7. Conversión a mayúsculas y minúsculas\n        System.out.println(\"7. Mayúsculas: \" + texto.toUpperCase());\n        System.out.println(\"   Minúsculas: \" + texto.toLowerCase());\n\n        // 8. Reemplazo\n        String reemplazo = texto.replace(\"mundo\", \"Java\");\n        System.out.println(\"8. Reemplazo: \" + reemplazo);\n\n        // 9. División\n        String[] palabras = texto.split(\", \");\n        System.out.println(\"9. División: \" + String.join(\" | \", palabras));\n\n        // 10. Unión\n        String[] arrayPalabras = {\"Java\", \"es\", \"genial\"};\n        String union = String.join(\" \", arrayPalabras);\n        System.out.println(\"10. Unión: \" + union);\n\n        // 11. Interpolación (en Java se usa concat o StringBuilder)\n        String nombre = \"Alice\";\n        int edad = 30;\n        String interpolacion = \"Me llamo \" + nombre + \" y tengo \" + edad + \" años.\";\n        System.out.println(\"11. Interpolación: \" + interpolacion);\n\n        // 12. Verificación\n        boolean empiezaCon = texto.startsWith(\"Hola\");\n        boolean terminaCon = texto.endsWith(\"!\");\n        boolean contiene = texto.contains(\"mundo\");\n        System.out.println(\"12. Empieza con 'Hola': \" + empiezaCon);\n        System.out.println(\"    Termina con '!': \" + terminaCon);\n        System.out.println(\"    Contiene 'mundo': \" + contiene);\n\n        // DIFICULTAD EXTRA\n        System.out.println(\"\\nDIFICULTAD EXTRA:\");\n        String palabra1 = \"amor\";\n        String palabra2 = \"roma\";\n\n        System.out.println(\"Palabra 1: \" + palabra1);\n        System.out.println(\"Palabra 2: \" + palabra2);\n        System.out.println(\"¿Son palíndromos? \" + esPalindromo(palabra1) + \", \" + esPalindromo(palabra2));\n        System.out.println(\"¿Son anagramas? \" + sonAnagramas(palabra1, palabra2));\n        System.out.println(\"¿Son isogramas? \" + esIsograma(palabra1) + \", \" + esIsograma(palabra2));\n    }\n\n    // Método para verificar si una palabra es un palíndromo\n    public static boolean esPalindromo(String palabra) {\n        String reversa = new StringBuilder(palabra).reverse().toString();\n        return palabra.equalsIgnoreCase(reversa);\n    }\n\n    // Método para verificar si dos palabras son anagramas\n    public static boolean sonAnagramas(String palabra1, String palabra2) {\n        if (palabra1.length() != palabra2.length()) {\n            return false;\n        }\n        char[] chars1 = palabra1.toLowerCase().toCharArray();\n        char[] chars2 = palabra2.toLowerCase().toCharArray();\n        java.util.Arrays.sort(chars1);\n        java.util.Arrays.sort(chars2);\n        return java.util.Arrays.equals(chars1, chars2);\n    }\n\n    // Método para verificar si una palabra es un isograma\n    public static boolean esIsograma(String palabra) {\n        return palabra.length() == palabra.toLowerCase().chars().distinct().count();\n    }\n}"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/frannmv.java",
    "content": "import java.lang.String;\nimport java.util.*;\n\nimport static java.lang.StringTemplate.STR;\n\npublic class frannmv {\n\n    public static void main(String[] args) {\n    /*  ************\n        Operaciones con Cadenas de Caracteres\n        ************\n    */\n        String cadena = \"RoadMap 2024\";\n\n        char caracterEspecifico = cadena.charAt(0); // Acceso a Caracter Especifico\n        System.out.println(caracterEspecifico);\n\n        System.out.println(cadena.substring(8)); // Substring - Desde la posicion pasada por parametro hasta\n                                                          // el final del String\n\n        System.out.println(cadena.substring(0,7)); // Substring - Desde la posicion pasada en el pirmer parametro hasta\n                                                  // la posicion del segundo parametro - 1\n\n        System.out.println(cadena.length()); // Longitud de la Cadena\n\n        System.out.println(cadena.concat(\" Con Java\").concat(\" - OOP\")); // Concatenacion\n\n        System.out.println(cadena.repeat(2)); // Repetición - El String \"cadena\" se repite 2 veces\n\n        System.out.println(cadena.toUpperCase()); // Conversion a mayuscula\n\n        System.out.println(cadena.toLowerCase()); // Conversion a minuscula\n\n        String reemplazarCaracter = cadena.replace('4','5');\n        System.out.println(reemplazarCaracter); // Reemplazar Caracter\n\n        String reemplazarCadena = cadena.replace(\"RoadMap\", \"MapRoad\");\n        System.out.println(reemplazarCadena); // Reemplazar Cadena\n\n        String nuevaCadena = \"Java-Object-Oriented-Programming\";\n        String[] palabras = nuevaCadena.split(\"-\"); // División\n        for(String palabra : palabras){\n            System.out.println(palabra);\n        }\n\n        String cadenaConcatenada = cadena + nuevaCadena;\n        System.out.println(cadenaConcatenada); // Union - Concatenacion\n\n        nuevaCadena = \"Java\";\n        String inter = STR.\"Estoy programando en \\{nuevaCadena}\";\n        System.out.println(inter); // Interpolación\n\n        inter = String.format(\"Estoy programando en %s\", nuevaCadena);\n        System.out.println(inter); // Interpolación\n\n        System.out.println(nuevaCadena.equals(cadena)); // Verificacion\n\n    /*  ************\n        Extra\n        ************\n    */\n        Scanner keyboard = new Scanner(System.in);\n        System.out.println(\"Ingrese la primera palabra: \");\n        String palabra1 = keyboard.nextLine();\n\n        System.out.println(\"Ingrese la segunda palabra: \");\n        String palabra2 = keyboard.nextLine();\n\n        mostrarResultados(palabra1,palabra2);\n    }\n\n    private static String darVuelta(String s){\n        char[] caracteres = s.toCharArray();\n        StringBuilder newString = new StringBuilder();\n        for(int i = caracteres.length - 1; i >= 0; i--){\n            newString.append(caracteres[i]);\n        }\n        return newString.toString();\n    }\n    private static boolean esPalindromo(String s) {\n        String cadenaEnReversa = darVuelta(s);\n        return s.equals(cadenaEnReversa);\n    }\n\n    private static int cantidadQueAparece(char c, char[] array){\n        int vecesQueAparece = 0;\n        for(int i = 0; i<array.length; i++){\n            if(array[i] == c)\n                vecesQueAparece++;\n        }\n        return vecesQueAparece;\n    }\n    private static void cargarMapa(Map<Character,Integer> a, String s){\n        char[] c = s.toCharArray();\n        for(char caracter : c){\n            a.putIfAbsent(caracter,cantidadQueAparece(caracter,c));\n        }\n    }\n    private static boolean sonAnagrama(String s1, String s2) {\n        Map<Character, Integer> cadena1 = new HashMap<>();\n        Map<Character, Integer> cadena2 = new HashMap<>();\n\n        cargarMapa(cadena1,s1);\n        cargarMapa(cadena2,s2);\n\n        for(Map.Entry<Character,Integer> entry : cadena1.entrySet()){\n            if(cadena2.containsKey(entry.getKey()) && entry.getValue() == cadena2.get(entry.getKey())){\n\n            }else{\n                return false;\n            }\n        }\n        return true;\n    }\n   private static boolean esIsograma(String s){\n       Set<Character> caracteres = new HashSet<>();\n       char[] cadenaToChar = s.toCharArray();\n       for(char caracter : cadenaToChar){\n           caracteres.add(caracter);\n       }\n       return s.length() == caracteres.size();\n   }\n    private static void mostrarResultados(String palabra1, String palabra2){\n        System.out.println(String.format(\"La palabra %s es palindromo: %b\",palabra1,esPalindromo(palabra1)));\n        System.out.println(String.format(\"La palabra %s es palindromo: %b\",palabra2,esPalindromo(palabra2)));\n        System.out.println(\"-----------------------------------------\");\n\n        System.out.println(String.format(\"Las palabra %s y %s son anagrama: %b\",palabra1,palabra2, sonAnagrama(palabra1,palabra2)));\n        System.out.println(\"-----------------------------------------\");\n\n        System.out.println(String.format(\"La palabra %s es isograma: %b\",palabra1,esIsograma(palabra1)));\n        System.out.println(String.format(\"La palabra %s es isograma: %b\",palabra2,esIsograma(palabra2)));\n        System.out.println(\"-----------------------------------------\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/hernanR.java",
    "content": "public class hernanR {\n    public static void main(String[] args) {\n        // Crear una cadena\n        String cadena = \"Hola Mundo\";\n        System.out.println(cadena);\n\n        // Concatenar cadenas\n        String cadena2 = \" desde Java\";\n        System.out.println(cadena + cadena2);\n\n        // Obtener la longitud de una cadena\n        System.out.println(cadena.length());\n\n        // Acceder a un carácter específico\n        System.out.println(cadena.charAt(0));\n\n        // Comparar cadenas\n        String cadena3 = \"Hola Mundo\";\n        System.out.println(cadena.equals(cadena3));\n\n        // Buscar en una cadena\n        System.out.println(cadena.contains(\"Mundo\"));\n\n        // Extraer una subcadena\n        System.out.println(cadena.substring(5, 10));\n\n        // Convertir a mayúsculas o minúsculas\n        System.out.println(cadena.toUpperCase());\n        System.out.println(cadena.toLowerCase());\n\n        // Reemplazar caracteres o palabras\n        System.out.println(cadena.replace(\"Mundo\", \"Hernan\"));\n\n        // Eliminar espacios en blanco\n        String cadena4 = \"    Hola Mundo    \";\n        System.out.println(cadena4.trim());\n\n        // Dividir una cadena\n        String cadena5 = \"Hola,Mundo\";\n        String[] partes = cadena5.split(\",\");\n        for (String parte : partes) {\n            System.out.println(parte);\n        }\n\n        // Convertir otros tipos a cadena\n        int numero = 123;\n        System.out.println(String.valueOf(numero));\n\n        // Comprobar si está vacía\n        System.out.println(cadena.isEmpty());\n\n        // Repetir una cadena\n        System.out.println(cadena.repeat(3));\n\n        // Convertir a un array de caracteres\n        char[] caracteres = cadena.toCharArray();\n        for (char caracter : caracteres) {\n            System.out.println(caracter);\n        }\n\n        /*\n         * * DIFICULTAD EXTRA (opcional):\n         * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n         * para descubrir si son:\n         * - Palíndromos\n         * - Anagramas\n         * - Isogramas\n         */\n        String palabra1 = \"reconocer\";\n        String palabra2 = \"recorren\";\n        System.out.println(esPalindromo(palabra1));\n        System.out.println(sonAnagramas(palabra1, palabra2));\n\n    }\n\n    // Método para comprobar si una palabra es palíndromo\n    public static boolean esPalindromo(String palabra) {\n        return palabra.equals(new StringBuilder(palabra).reverse().toString());\n    }\n\n    // Método para comprobar si dos palabras son anagramas\n    public static boolean sonAnagramas(String palabra1, String palabra2) {\n        return palabra1.length() == palabra2.length()\n                && new StringBuilder(palabra1).reverse().toString().equals(palabra2);\n    }\n\n    // Método para comprobar si una palabra es isograma\n    public static boolean esIsograma(String palabra) {\n        return palabra.length() == palabra.chars().distinct().count();\n    }\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/inmortalnight.java",
    "content": "// 04 - CADENAS DE CARACTERES\n\nimport java.util.ArrayList;\nimport java.util.Scanner;\n\npublic class inmortalnight {\n    public static void main(String[] args) {\n        // Ejemplos de operaciones con cadenas de caracteres\n        String cadena = \"Hola Mundo\";\n        System.out.println(\"Cadena: \" + cadena);\n        System.out.println(\"Longitud: \" + cadena.length());\n        System.out.println(\"Caracter en la posición 4: \" + cadena.charAt(4));\n        System.out.println(\"Subcadena desde la posición 5: \" + cadena.substring(5));\n        System.out.println(\"Concatenación: \" + cadena.concat(\" desde Java\"));\n        System.out.println(\"Repetición: \" + cadena.repeat(3));\n        System.out.println(\"Recorrido: \");\n        for (int i = 0; i < cadena.length(); i++) {\n            System.out.println(cadena.charAt(i));\n        }\n        System.out.println(\"Mayúsculas: \" + cadena.toUpperCase());\n        System.out.println(\"Minúsculas: \" + cadena.toLowerCase());\n        System.out.println(\"Reemplazo: \" + cadena.replace(\"Hola\", \"Adiós\"));\n        System.out.println(\"División: \" + cadena.split(\" \")[0]);\n        System.out.println(\"Unión: \" + String.join(\" \", \"Hola\", \"Mundo\"));\n        System.out.println(\"Interpolación: \" + String.format(\"Hola %s\", \"Mundo\"));\n        System.out.println(\"Verificación: \" + cadena.equals(\"Hola Mundo\"));\n        \n        comprobar();\n    }\n    // EXTRA: Comprobaciones\n    public static void comprobar() {\n        System.out.println(\"------Comprobaciones-----\");\n        System.out.println(\"Nota: las comprobaciones dan prioridad a la primera palabra introducida\");\n        // Entrada de datos\n        Scanner scanner = new Scanner(System.in);\n        System.out.print(\"Introduce la primera palabra: \");\n        String palabra1 = scanner.nextLine();\n        System.out.print(\"Introduce la segunda palabra: \");\n        String palabra2 = scanner.nextLine();\n        // Comprobaciones\n        System.out.println(\"Palíndromo: \" + esPalindromo(palabra1));\n        System.out.println(\"Anagrama: \" + esAnagrama(palabra1, palabra2));\n        System.out.println(\"Isograma: \" + esIsograma(palabra1));\n        scanner.close();\n    }\n    // Palindromo: es una palabra o frase que se lee igual de izquierda a derecha que de derecha a izquierda\n    public static boolean esPalindromo(String palabra) {\n        return palabra.equals(new StringBuilder(palabra).reverse().toString());\n    }\n    // Anagrama: es una palabra o frase que contiene las mismas letras que otra palabra o frase\n    public static boolean esAnagrama(String palabra1, String palabra2) {\n        ArrayList<Character> lista1 = new ArrayList<>();\n        for (char c : palabra1.toCharArray()) {\n            lista1.add(c);\n        }\n        ArrayList<Character> lista2 = new ArrayList<>();\n        for (char c : palabra2.toCharArray()) {\n            lista2.add(c);\n        }\n        lista1.sort(Character::compareTo);\n        lista2.sort(Character::compareTo);\n        return lista1.equals(lista2);\n    }\n    // Isograma: es una palabra o frase que no contiene letras repetidas\n    public static boolean esIsograma(String palabra) {\n        return palabra.chars().distinct().count() == palabra.length();\n    }\n}"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/jcrodmir.java",
    "content": "import java.util.*;\n\npublic class Strings {\n\n    //Strings are Immutable must assignment to replace the value,\n    static String  word=\"A new World with many words\";\n    static String word2= \"Pepe\";\n\n    public static void main(String[] args) {\n        //charAt\n        System.out.println(\"Method charAt return Character: \" + word.charAt(1));\n\n        System.out.println(\"Method length return int: \" + word.length());\n\n        System.out.println(\"Method Format return String with the format that will us: \" + String.format(\"Format String %s and decimal %d\", word2, 15));\n\n        System.out.println(\"Method subString return String: \" + word.substring(6, 11));\n\n        System.out.println(\"Method contains return boolean: \" + word.contains(\"World\"));\n\n        System.out.println(\"Method join return String with the new element: \" + String.join(\"/\", word, word2));\n\n        System.out.println(\"Method equals return boolean: \" + word.equals(word2));\n\n        System.out.println(\"Method equalsignoreCase return boolean : \" + word.equalsIgnoreCase(word2));\n        ////////////////////////////////////////////////////////////////////////////////////////\n        System.out.println(\"Method replace return String: \" + word.replace(\"o\", \"a\"));\n\n        System.out.println(\"Method split return array: \" + Arrays.toString(word.split(\"\\\\s\")));//Make an Array with each word for the sentence\n\n        System.out.println(\"Method intern return String: \" + word2.intern());//It returns an interned string\n\n        System.out.println(\"Method indexOf return int: \" + word.indexOf(\"World\"));//The beginning for the Word \"World\" when not find is -1\n\n        System.out.println(\"Method toLowerCase return String: \" + word.toLowerCase());\n\n        System.out.println(\"Method toUpperCase return String: \" + word.toUpperCase());\n\n        System.out.println(\"Method trim return String: \" + word.trim());\n\n        System.out.println(\"Method valueOf return String: \" + String.valueOf(123));//Convert the int to String\n\n        System.out.println(\"Method valueOf return String: \" + word.concat(word2));\n\n        System.out.println(\"Method valueOf return String: \" + word.compareTo(word2));//With the result 0 we know that are equals\n\n\n        //To compare two Strigs we can use ==,equals and compareTo()\n\n        //StringBuffer is the same that builder but is synchronised and protect the thread\n\n        //StringBuilder To create a mutable String\n        System.out.println(\"****************StringBuilder***************\");\n        StringBuilder sb=new StringBuilder(\"Example for StringBuilder\");\n        sb.append(\" other String Append\");\n        System.out.println(\"Method Append  add something: \" + sb.toString());\n        sb.insert(0,\"1. \");\n        System.out.println(\"Method Insert add something in the index: \" + sb.toString());\n\n        sb.replace(28,sb.length(),\" new String\");\n        System.out.println(\"Method replace: \" + sb.toString());\n        sb.delete(0,2);\n        System.out.println(\"Method delete with start to end: \" + sb.toString());\n        sb.reverse();\n        System.out.println(\"Method reverse: \" + sb.toString());\n        sb.reverse();\n        System.out.println(\"Method capacity give us the capacity for the builder \" + sb.capacity());\n\n\n        //Extra\n        System.out.println(\"EXTRA EXERCISE\");\n        Scanner sc1= new Scanner(System.in);\n        System.out.println(\"First word: \");\n        String firstWord= sc1.next();\n        Scanner sc2= new Scanner(System.in);\n        System.out.println(\"Second word: \");\n        String secondWord= sc1.next();\n\n        StringBuilder sbPalindrome=new StringBuilder(firstWord).reverse();\n\n        if(sbPalindrome.toString().equals(secondWord)){\n            System.out.println(\"They are Palindrome\");\n        }\n        else{\n            System.out.println(\"They are not Palindrome\");\n        }\n\n\n        if(Arrays.equals(firstWord.chars().sorted().toArray(), secondWord.chars().sorted().toArray())){\n            System.out.println(\"They are Anagram\");\n        }\n        else{\n            System.out.println(\"They are not Anagram\");\n        }\n\n\n        if(isIsogram(firstWord)){\n            System.out.println(\"The first word is an Isogram\");\n        }else{\n            System.out.println(\"The first word is not an Isogram\");\n        }\n\n\n\n    }\n\n    public static boolean isIsogram(String word) {\n\n        Map<Character, Integer> charCount = new HashMap<>();\n\n        for (int i = 0; i < word.length(); i++) {\n            char c = word.charAt(i);\n            charCount.put(c, charCount.getOrDefault(c, 0) + 1);\n        }\n\n        int frequency = charCount.get(word.charAt(0));\n\n        for (int count : charCount.values()) {\n            if (count != frequency) {\n                return false;\n            }\n        }\n        return true;\n    }\n}"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/julian98789.java",
    "content": "\nimport java.util.Arrays;\nimport java.util.HashSet;\nimport java.util.Scanner;\nimport java.util.Set;\n\npublic class reto4_4 {\n    public static void main(String[] args) {\n        Scanner input = new Scanner(System.in);\n        String str = \"Hola, Mundo\";\n\n        // Acceso a caracteres específicos\n        char caracter = str.charAt(0);\n        System.out.println(\"Caracter en la posición 0: \" + caracter);\n\n        // Subcadenas\n        String subcadena = str.substring(0, 4);\n        System.out.println(\"Subcadena (0-4): \" + subcadena);\n\n        // Longitud\n        int longitud = str.length();\n        System.out.println(\"Longitud: \" + longitud);\n\n        // Concatenación\n        String saludo = \"Hola\" + \", \" + \"Mundo\";\n        System.out.println(\"Concatenación: \" + saludo);\n\n        // Repetición\n        String repetida = \"Hola\".repeat(3);\n        System.out.println(\"Repetición: \" + repetida);\n\n        // Recorrido\n        System.out.print(\"Recorrido: \");\n        for (char c : str.toCharArray()) {\n            System.out.print(c + \" \");\n        }\n        System.out.println();\n\n        // Conversión a mayúsculas y minúsculas\n        String mayusculas = str.toUpperCase();\n        String minusculas = str.toLowerCase();\n        System.out.println(\"Mayúsculas: \" + mayusculas);\n        System.out.println(\"Minúsculas: \" + minusculas);\n\n        // Reemplazo\n        String reemplazo = str.replace('o', 'a');\n        String reemplazoPalabra = str.replace(\"Hola\", \"Adios\");\n        System.out.println(\"Reemplazo de caracteres: \" + reemplazo);\n        System.out.println(\"Reemplazo de palabras: \" + reemplazoPalabra);\n\n        // División\n        String[] palabras = str.split(\", \");\n        System.out.println(\"División: \");\n        for (String palabra : palabras) {\n            System.out.println(palabra);\n        }\n\n        // Unión\n        String[] partes = { \"Hola\", \"Mundo\" };\n        String unido = String.join(\", \", partes);\n        System.out.println(\"Unión: \" + unido);\n\n        // Interpolación (Formateo de cadenas)\n        String nombre = \"Juan\";\n        int edad = 30;\n        String mensaje = String.format(\"Mi nombre es %s y tengo %d años.\", nombre, edad);\n        System.out.println(\"Interpolación: \" + mensaje);\n\n        // Verificación\n        boolean empiezaCon = str.startsWith(\"Hola\");\n        boolean terminaCon = str.endsWith(\"Mundo\");\n        boolean contiene = str.contains(\"Mundo\");\n        System.out.println(\"Empieza con 'Hola': \" + empiezaCon);\n        System.out.println(\"Termina con 'Mundo': \" + terminaCon);\n        System.out.println(\"Contiene 'Mundo': \" + contiene);\n\n        System.out.println(\"\\n ****Desafio**** \\n\");\n\n        System.out.println(\"ingrese la primera palabra \\n\");\n        String p1 = input.nextLine();\n\n        System.out.println(\"ingrese la segunda palabra \\n\");\n        String p2 = input.nextLine();\n\n        if (anagrama(p1, p2)) {\n            System.out.println(p1 + \" y \" + p2 + \" Es un anagrma \\n\");\n        } else {\n            System.out.println(p1 + \" y \" + p2 + \" No es un anagrma\\n\");\n        }\n\n        polindromo(p1, p2);\n        isograma(p1, p2);\n    }\n\n    public static void polindromo(String p1, String p2) {\n        p1.replaceAll(\"\\\\s\", \"\").toLowerCase();\n        p2.replaceAll(\"\\\\s\", \"\").toLowerCase();\n\n        int n1 = p1.length();\n        int n2 = p2.length();\n        boolean poli1 = true;\n        boolean poli2 = true;\n\n        for (int i = 0; i <= n1 / 2; i++) {\n\n            if (p1.charAt(i) != p1.charAt(n1 - 1 - i)) {\n\n                poli1 = false;\n            }\n        }\n        if (poli1) {\n            System.out.println(\"La palabra \" + p1 + \" es polindroma \\n\");\n        } else {\n            System.out.println(\"La palabra \" + p1 + \" no es polindroma \\n\");\n        }\n\n        for (int i = 0; i <= n2 / 2; i++) {\n            if (p2.charAt(i) != p2.charAt(n2 - 1 - i)) {\n\n                poli2 = false;\n\n            }\n\n        }\n        if (poli2) {\n            System.out.println(\"La palabra \" + p2 + \" es polindroma \\n\");\n        } else {\n            System.out.println(\"La palabra \" + p2 + \" no es polindroma \\n\");\n        }\n\n    }\n\n    public static boolean anagrama(String p1, String p2) {\n        p1.replaceAll(\"\\\\s\", \"\").toLowerCase();\n        p2.replaceAll(\"\\\\s\", \"\").toLowerCase();\n\n        if (p1.length() != p2.length()) {\n            return false;\n        }\n\n        char arr1[] = p1.toCharArray();\n\n        char arr2[] = p2.toCharArray();\n\n        Arrays.sort(arr1);\n        Arrays.sort(arr2);\n\n        return Arrays.equals(arr1, arr2);\n    }\n\n    public static void isograma(String p1, String p2) {\n        p1.replaceAll(\"\\\\s\", \"\").toLowerCase();\n        p2.replaceAll(\"\\\\s\", \"\").toLowerCase();\n\n        int n = p1.length();\n        int n2 = p2.length();\n        boolean iso = true;\n        boolean iso2 = true;\n        \n      Set<Character> vistoCharacters = new HashSet<>();\n\n      for (int i = 0; i < n; i++) {\n        char caracterActual = p1.charAt(i);\n        if (vistoCharacters.contains(caracterActual)) {\n            iso = false;\n            break;\n        }\n        vistoCharacters.add(caracterActual);\n      }\n        if (iso) {\n            System.out.println(\"La palabra \" + p1 + \"SI es un isograma \\n\");\n        }else{\n            System.out.println(\"La palabra \" + p1 + \"no es un isograma \\n\");\n        }\n\n        for (int i = 0; i < n2; i++) {\n            char caracterActual = p2.charAt(i);\n            if (vistoCharacters.contains(caracterActual)) {\n                iso = false;\n                break;\n            }\n            vistoCharacters.add(caracterActual);\n          }\n            if (iso) {\n                System.out.println(\"La palabra \" + p2 + \" SI es un isograma\\n\");\n            }else{\n                System.out.println(\"La palabra \" + p2 + \" No es un isograma \\n\");\n            }\n    }\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/kilianhc.java",
    "content": "package retosProgramacion;\n\nimport java.util.Arrays;\nimport java.util.Scanner;\n\npublic class RetoCinco {\n\n    public static void main(String[] args) {\n\n        //Operaciones con cadenas de caracteres\n        //Concatenación\n        String a = \"Hola\";\n        String b = \"Java\";\n        System.out.println(a + \" \" + b + \"!\");\n\n        //Repetición\n        System.out.println(a + \" \" + a + \" \" + a);\n\n        //Indexación \n        System.out.println(a.charAt(0));\n\n        //Longitud\n        System.out.println(b.length());\n\n        //Búsqueda ||comprobar si una cadena contiene algo\n        System.out.println(a.contains(\"H\"));\n\n        //Comprobar si una cadena esta vacía o si contiene algo\n        System.out.println(b.isEmpty());\n\n        //Reemplazo\n        System.out.println(a.replace(\"H\", \"h\"));\n\n        //Mayúsculas y minúsculas\n        System.out.println(a.toUpperCase());\n        System.out.println(b.toLowerCase());\n\n        //Eliminación de espacios al principio y al final\n        System.out.println(\" Kilianhc \".trim() + \"@hotmail.com\");\n\n        //División*****\n        System.out.println(a.split(\"l\", 2));\n\n        //Comparación\n        System.out.println(a.equals(b));\n        System.out.println(a.equalsIgnoreCase(\"holA\"));\n\n        //Buscar posición\n        System.out.println(a.indexOf(\"l\"));\n\n        //Verificar el comienzo y final de la cadena\n        System.out.println(b.startsWith(\"J\"));\n        System.out.println(b.endsWith(\"A\"));\n\n        //Obtener una parte de la cadena\n        System.out.println(b.substring(1, 3));\n\n        //Convertir cadena en array*****\n        char[] array = b.toCharArray();\n        System.out.println(array);\n\n        //Formatear cadenas\n        System.out.printf(\"Hola, %s\\n\", b);\n\n        //Convertir un tipo primitivo a cadena\n        int numero = 123;\n        String numeroCadena = String.valueOf(numero);\n        System.out.println(numeroCadena);\n\n        //Concatenación de múltiples cadenas (usando toString)\n        StringBuilder builder = new StringBuilder();\n        builder.append(a);\n        builder.append(\" \");\n        builder.append(b);\n        String mensajeFinal = builder.toString();\n        System.out.println(mensajeFinal);\n\n        //Comparación de cadenas con orden lexicográfico\n        System.out.println(a.compareTo(b));\n\n        //Invertir una cadena\n        String invertida = new StringBuilder(a).reverse().toString();\n        System.out.println(invertida);\n\n        RetoCinco cadenas = new RetoCinco();\n        cadenas.palindromo();\n\n    }\n\n    //EXTRA\n    public void palindromo() {\n        Scanner leer = new Scanner(System.in);\n        boolean analisis = true;\n\n        while (analisis) {\n            System.out.println(\"---------Análisis de palabras---------\\n\"\n                    + \"Elige una opción para analizar las palabras: \\n\"\n                    + \"1. Palíndromos\\n\"\n                    + \"2. Anagramas\\n\"\n                    + \"3. Isogramas\\n\"\n                    + \"4. Salir del programa\\n\");\n\n            int opcion = leer.nextInt();\n            String palabra1;\n            String palabra2;\n\n            switch (opcion) {\n                case 1:\n                    System.out.println(\"Ingrese la primera palabra: \\n\");\n                    palabra1 = leer.next().replaceAll(\" \", \"a\");\n                    String invertida1 = new StringBuilder(palabra1).reverse().toString();\n                    System.out.println(\"Ingrese la segunda palabra: \\n\");\n                    palabra2 = leer.next().replaceAll(\" \", \"a\");\n                    String invertida2 = new StringBuilder(palabra2).reverse().toString();\n                    if (palabra1.equalsIgnoreCase(invertida1) && palabra2.equalsIgnoreCase(invertida2)) {\n                        System.out.println(\"Las dos palabras son palíndromos\\n\");\n                    } else if (palabra1.equalsIgnoreCase(invertida1)) {\n                        System.out.println(\"Sólo la primera palabra es un palíndromo\\n\");\n                    } else if (palabra2.equalsIgnoreCase(invertida2)) {\n                        System.out.println(\"Sólo la segunda palabra es un palíndromo\\n\");\n                    } else {\n                        System.out.println(\"Ninguna de las 2 palabras es un palíndromo\\n\");\n                    }\n                    break;\n                case 2:\n                    System.out.println(\"Ingrese la primera palabra: \\n\");\n                    palabra1 = leer.next().replaceAll(\" \", \"a\").toLowerCase();\n                    char[] letra1 = palabra1.toCharArray();\n                    Arrays.sort(letra1);\n                    System.out.println(\"Ingrese la segunda palabra: \\n\");\n                    palabra2 = leer.next().replaceAll(\" \", \"a\").toLowerCase();\n                    char[] letra2 = palabra2.toCharArray();\n                    Arrays.sort(letra2);\n                    if (palabra1.length() == palabra2.length() && Arrays.equals(letra1, letra2)) {\n                        System.out.println(\"Las palabras son anagramas\\n\");\n                    } else {\n                        System.out.println(\"Las palabras no son anagramas\");\n                    }\n                    break;\n                case 3:\n                    System.out.println(\"Ingrese la primera palabra: \\n\");\n                    palabra1 = leer.next().replaceAll(\" \", \"a\").toLowerCase();\n                    System.out.println(\"Ingrese la segunda palabra: \\n\");\n                    palabra2 = leer.next().replaceAll(\" \", \"a\").toLowerCase();\n                    if (palabra1.length() == palabra1.chars().distinct().count() && palabra2.length() == palabra2.chars().distinct().count()) {\n                        System.out.println(\"Las dos palabras son isogramas\");\n                    } else if (palabra1.length() == palabra1.chars().distinct().count()) {\n                        System.out.println(\"Sólo la primera palabra es un isograma\");\n                    } else if (palabra2.length() == palabra2.chars().distinct().count()) {\n                        System.out.println(\"Sólo la segunda palabra es un isograma\");\n                    } else {\n                        System.out.println(\"Ninguna de las palabras es un isograma\");\n                    }\n                    break;\n                case 4:\n                    System.out.println(\"Salió del programa\");\n                    analisis = false;\n                    break;\n            }\n\n        }\n        leer.close();\n    }\n\n}\n\n\n/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\n *   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\n *   interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/kleyner098.java",
    "content": "import java.util.Arrays;\nimport java.util.Collection;\nimport java.util.HashMap;\n\n\npublic class kleyner098 {\n    /*\n     * EJERCICIO:\n     * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de\n     * caracteres en tu lenguaje. Algunas de esas operaciones podrían ser (busca\n     * todas las que puedas):\n     * - Acceso a caracteres específicos, subcadenas, longitud,\n     * concatenación,repetición, recorrido,conversión a mayúsculas y minúsculas,\n     * reemplazo, división, unión,interpolación, verificación...\n     */\n\n    public static void main(String[] args) {\n        // Declaración e inicialización de una cadena\n        String cadena1 = \"hola\";\n        String cadena2 = \"mundo\";\n        String cadena3 = \"HOLA\";\n        String cadena4 = \"Un lago AZUL\";\n        String cadena5 = \"Vamos al lago azul\";\n        String cadena6 = \"cadena\";\n        String cadena7 = \"\";\n        String cadena8 = \"deshacer\";\n\n        // Mostrar la longittud de la cadena\n        System.out.println(\"Longitud: \" + cadena1.length());\n        // Obtener un caracter específicando un indice\n        System.out.println(\"El carácter que ocupa la posicion 3 es :\" + cadena1.charAt(3));\n        // Obtener un cadena específicando un indice\n        System.out.println(\"Obteción de la cadena: \" + cadena4.substring(3, 7));\n        // Obtener el índice de la primera ocurrencia de un caráter\n        System.out.println(\"El índice del caracter h en la palabra \\\"hola\\\" es: \" + cadena1.indexOf('h'));\n        // Obtener el índice de la primera ocurrencia de una cadena\n        System.out.println(\"El índice del la cadena \\\"un\\\" en la palabra \\\"mundo\\\" es: \" + cadena2.indexOf(\"un\"));\n        // Obtener el índice de la primera ocurrencia de una cadena empezando por la\n        // derecha\n        System.out.println(\"El índice del la caráter \\'a\\' en la palabra \\\"cadena\\\"  empezando por la derecha es: \"\n                + cadena6.lastIndexOf('a'));\n\n        // Conparación de cadena\n        System.out.println(\"Comparación entre \\\"hola\\\" y la \\\"HOLA\\\" con método equals(): \" + cadena1.equals(cadena3));\n        // Conparación de cadena ignorando mayúscula y minúscula\n        System.out.println(\n                \"Comparación entre \\\"hola\\\" y la \\\"HOLA\\\" con método equalsIgnoreCase(), ignorando mayúscula y minúscula: \"\n                        + cadena1.equalsIgnoreCase(cadena3));\n        // String es una clase, por lo que utilizar el comparador == no sirve, ya que\n        // estaría comparando las referencia de los objetos String\n        // Comparar fragmento de candenas\n        System.out.println(\"Comprobación de frgamento de cadena: \" + cadena4.regionMatches(3, cadena5, 9, 4));\n        // Comparar fragmento de candenas ignorando mayúscula y minúscula\n        System.out.println(\"Comprobación de frgamento de cadena: \" + cadena4.regionMatches(true, 8, cadena5, 14, 4));\n        // Comparación alfabética, devuelve un int. Si es cero, son iguales; si es\n        // negativo, la cadena invocante va antes en orden alfabetico que la cadena\n        // pasada por parámetro; si es positivo va despues.\n        System.out.println(\"Comprobación alfabética de cadenas: \" + cadena1.compareTo(cadena2));\n        // Comparación alfabética ignorando ignorando mayúscula y minúscula\n        System.out.println(\"Comprobación alfabética de cadenas: \" + cadena1.compareToIgnoreCase(cadena3));\n        // Comprobación de cadena vacía\n        System.out.println(\"Cadena vacía: \" + cadena7.isEmpty());\n        // Comprobar si una cadena contine una subcadena\n        System.out.println(\"Comprobación de si contiene: \" + cadena5.contains(\"azul\"));\n        // Comprobación de prefijo y sufijo\n        System.out.println(\"Comprobación de prefijo \\\"des\\\" en la palabra \\\"deshacer\\\": \" + cadena8.startsWith(\"des\"));\n        System.out.println(\"Comprobación de sufijo \\\"er\\\" en la palabra \\\"deshacer\\\": \" + cadena8.endsWith(\"er\"));\n        // Concatenación\n        String nuevaCadena = cadena1 + \" \" + cadena2;\n        System.out.println(\"Concatenación: \" + nuevaCadena);\n        // Otra forma de concatenar\n        System.out.println(\"Otra forma de concatenación: \" + cadena1.concat(\" \" + cadena2));\n        // Conversión de tipos\n        int num = 1;\n        boolean boleano = false;\n        double otherNum = 43.23;\n        System.out.println(\"Conversión de tipos de variable: Int-\" + String.valueOf(num) + \", boolean-\"\n                + String.valueOf(boleano) + \", double-\" + String.valueOf(otherNum));\n        //Conversión a miniscúlas\n        System.out.println(cadena4.toLowerCase());\n        //Conversión a miniscúlas\n        System.out.println(cadena4.toUpperCase());\n        //Sustituir cadena \n        System.out.println(cadena5.replace(\"azul\", \"rojo\"));\n        //Romper cadena \n        String[] cadenaArray = cadena5.split(\" \");\n        System.out.println(Arrays.toString(cadenaArray));\n        //Unión de cadenas\n        System.out.println(String.join(\" \", cadena1,cadena2,cadena3,cadena2));\n        // Crear una array de caracteres\n        char[] charArray = cadena5.toCharArray();\n        System.out.println(Arrays.toString(charArray));\n\n        //Palíndromos\n        \n        String palabra1 = \"zorra\";\n        String palabra2 = \"arroz\";\n        System.out.printf(\"Las palabras %1$s y %2$s son palíndromos: %3$s\\n\",palabra1,palabra2, palindromos(palabra1, palabra2));\n        System.out.printf(\"Las palabras %1$s y %2$s son anagramas: %3$s\\n\",palabra1,palabra2, palindromos(palabra1, palabra2));\n        String palabra3 = \"intestinos\";\n        System.out.printf(\"La palabra %1$s es isograma: %2$s\\n\",palabra3, isograma(palabra3));\n    }\n\n    /* \n    * DIFICULTAD EXTRA (opcional):\n     * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n     * para descubrir si son:\n     * - Palíndromos\n     * - Anagramas\n     * - Isogramas\n     */\n    static public boolean palindromos(String cadena1, String cadena2){\n        boolean palindromo = false;\n        String cadInvertida = \"\";\n        for (int i = cadena2.length() -1 ; i >= 0; i--) {\n            cadInvertida += cadena2.charAt(i);\n        }\n        if (cadInvertida.toLowerCase().equals(cadena1.toLowerCase())) {\n            palindromo = true;\n        }\n        return palindromo;\n    }\n\n    static public boolean anagrama(String cadena1, String cadena2){\n        boolean anagrama = false;\n        if (cadena1.length() == cadena2.length()) {\n            char[] charArray1 = cadena1.toCharArray();\n            Arrays.sort(charArray1);\n            char[] charArray2 = cadena2.toCharArray();\n            Arrays.sort(charArray2);\n            if(charArray1.equals(charArray2)){\n                anagrama = true;\n            }\n        }\n        return anagrama;\n    }\n\n    static public boolean isograma(String cadena){\n        boolean isograma = true;\n        HashMap<Character,Integer> palabra = new HashMap<>();\n        for (int i = 0; i < cadena.length(); i++) {\n            if(!(palabra.containsKey(cadena.charAt(i)))){\n                palabra.put(cadena.charAt(i), 1);\n            }else{\n                Integer nuevoValor = palabra.get(cadena.charAt(i)) + 1;\n                palabra.put(cadena.charAt(i), nuevoValor);\n            }\n\n            Collection<Integer> contadorLetras = palabra.values();\n            for (Integer values : contadorLetras) {\n                if(values != 1 && values % 2 != 0){\n                    isograma = false;\n                    break;\n                }\n            }\n        }\n        return isograma;\n    }\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/lautarorisso.java",
    "content": "public class LogicaJava04 {\n\n    public static void main(String[] args) {\n\n        // Crear Strings\n        String texto = \"Backend Java\";\n        String otro = \"Developer\";\n\n        System.out.println(\"Texto original: \" + texto);\n\n        // Longitud\n        System.out.println(\"Longitud: \" + texto.length());\n\n        // Acceso a un carácter\n        System.out.println(\"Primer carácter: \" + texto.charAt(0));\n\n        // Subcadena\n        System.out.println(\"Subcadena (0,7): \" + texto.substring(0, 7));\n\n        // Concatenación\n        String concatenado = texto + \" \" + otro;\n        System.out.println(\"Concatenado: \" + concatenado);\n        String resultado = texto.concat(\" Developer\");\n        System.out.println(resultado);\n\n        // Repetición\n        String repetido = \"Ja\".repeat(3);\n        System.out.println(\"Repetido: \" + repetido);\n\n        // Recorrido carácter por carácter\n        System.out.print(\"Recorrido: \");\n        for (int i = 0; i < texto.length(); i++) {\n            System.out.print(texto.charAt(i) + \" \");\n        }\n        System.out.println();\n\n        // Mayúsculas y minúsculas\n        System.out.println(\"Mayúsculas: \" + texto.toUpperCase());\n        System.out.println(\"Minúsculas: \" + texto.toLowerCase());\n\n        // Reemplazo\n        System.out.println(\"Reemplazo: \" + texto.replace(\"Java\", \"Spring\"));\n\n        // Dividir (split)\n        String[] partes = texto.split(\" \");\n        System.out.println(\"Split:\");\n        for (String p : partes) {\n            System.out.println(\"- \" + p);\n        }\n\n        // Unir (join)\n        String unido = String.join(\" | \", \"Java\", \"Spring\", \"Backend\");\n        System.out.println(\"Join: \" + unido);\n\n        // Interpolación (String.format)\n        String nombre = \"Lau\";\n        int edad = 21;\n        String mensaje = String.format(\"Hola %s, tenés %d años\", nombre, edad);\n        System.out.println(\"Interpolación: \" + mensaje);\n\n        // Verificaciones\n        System.out.println(\"Contiene 'Java': \" + texto.contains(\"Java\"));\n        System.out.println(\"Empieza con 'Back': \" + texto.startsWith(\"Back\"));\n        System.out.println(\"Termina con 'Java': \" + texto.endsWith(\"Java\"));\n\n        // Comparación de Strings\n        String a = \"Hola\";\n        String b = \"Hola\";\n        System.out.println(\"equals(): \" + a.equals(b)); // true\n        System.out.println(\"== : \" + (a == b));         // puede ser true o false\n\n        // Vacío / espacios\n        String vacio = \"\";\n        String espacios = \"   \";\n        System.out.println(\"isEmpty(): \" + vacio.isEmpty());\n        System.out.println(\"isBlank(): \" + espacios.isBlank());\n\n        // Trim\n        String conEspacios = \"   Java   \";\n        System.out.println(\"Trim: '\" + conEspacios.trim() + \"'\");\n\n        // Conversión String ↔ número\n        int numero = Integer.parseInt(\"123\");\n        String numeroTexto = String.valueOf(456);\n        System.out.println(\"String a int: \" + numero);\n        System.out.println(\"Int a String: \" + numeroTexto);\n\n        // Comparación lexicográfica\n        System.out.println(\"compareTo: \" + \"abc\".compareTo(\"abd\")); // < 0\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/mariovelascodev.java",
    "content": "import java.util.ArrayList;\nimport java.util.Collections;\n\npublic class mariovelascodev {\n\n    public static void main(String[] args) {\n         String greeting = \"Hola, Java\";\n\n         //Longitud del string\n        System.out.println(\"Longitud de la cadena de texto: \"+greeting.length());\n\n        //Métodos para poner toda la cadena en mayúsculas y en minúsculas\n        System.out.println(greeting);\n        System.out.println(greeting.toUpperCase());\n        System.out.println(greeting.toLowerCase());\n\n        //Encontrar carácter en una cadena\n        System.out.println(\"El primer carácter 'a' en la cadena \\\"\"+greeting+\"\\\" esta en el indice: \"\n                +greeting.indexOf(\"a\"));\n\n        System.out.println(\"El último carácter 'a' en la cadena \\\"\"+greeting+\"\\\" esta en el indice: \"\n                +greeting.lastIndexOf(\"a\"));\n\n        System.out.println(\"En el indice 6 de la cadena\\\"\"+greeting+\"\\\" contiene la letra: \"+greeting.charAt(6));\n\n        //Comparación de cadenas\n        String farewell = \"Adios, Java\";\n        String greetingUppercase = greeting.toUpperCase();\n\n        System.out.println(\"\\\"\"+greeting+\"\\\" es igual que \\\"\"+farewell+\"\\\": \"+greeting.equals(farewell));\n        System.out.println(\"\\\"\"+greeting+\"\\\" es igual que \\\"\"+farewell+\"\\\": \"+greeting.equalsIgnoreCase(farewell));\n\n        System.out.println(\"\\\"\"+greeting+\"\\\" es igual que \\\"\"+greetingUppercase+\"\\\": \"\n                +greeting.equals(greetingUppercase));\n        System.out.println(\"\\\"\"+greeting+\"\\\" es igual que \\\"\"+greetingUppercase+\"\\\": \"\n                +greeting.equalsIgnoreCase(greetingUppercase));\n\n        //Eliminar espacios en blanco\n        String greetingWithSpaces = \"   Hola, Java  \";\n        System.out.println(\"Antes: [\" + greetingWithSpaces + \"]\");\n        System.out.println(\"Despues:  [\" + greetingWithSpaces.trim() + \"]\");\n\n        //Devolver valor Unicode\n        int firstUnicodeValue = greeting.codePointAt(0);\n        int secondUnicodeValue = greeting.codePointBefore(3);\n\n        System.out.println(\"El carácter Unicode de la posición 0 en la cadena \\\"\"+greeting+\"\\\" es: \"\n                +firstUnicodeValue);\n        System.out.println(\"El carácter Unicode despues de la posición 3 en la cadena \\\"\"+greeting+\"\\\" es: \"\n                +secondUnicodeValue);\n\n        //Concatenar cadenas\n        String concatString = greeting.concat(farewell);\n        System.out.println(concatString);\n\n        //Ver si cadena contiene caracteres\n        System.out.println(\"La cadena \\\"\"+greeting+\"\\\" contiene la palabra 'Java': \"+greeting.contains(\"Java\"));\n        System.out.println(\"La cadena \\\"\"+greeting+\"\\\" contiene la palabra 'JavaScript': \"\n                +greeting.contains(\"JavaScript\"));\n        System.out.println(\"La cadena \\\"\"+greeting+\"\\\" contiene la palabra 'java': \"\n                +greeting.contentEquals(\"java\"));\n\n        //Ver si la cadena termina o empieza con los caracteres especificados\n        System.out.println(\"La cadena \\\"\"+greeting+\"\\\" termina por 'ava': \"+greeting.endsWith(\"ava\"));\n        System.out.println(\"La cadena \\\"\"+greeting+\"\\\" termina por 'e': \"+greeting.endsWith(\"e\"));\n\n        System.out.println(\"La cadena \\\"\"+greeting+\"\\\" empieza por 'Hol': \"+greeting.startsWith(\"Hol\"));\n        System.out.println(\"La cadena \\\"\"+greeting+\"\\\" empieza por 'o': \"+greeting.startsWith(\"o\"));\n\n        //Formateo de cadena\n        String myStr = \"¡Hola %s! Un kilobyte es %,d bytes.\";\n        String result = String.format(myStr, \"Mundo\", 1024);\n        System.out.println(result);\n\n        //Ver si una cadena está vacía\n        String emptyString = \"\";\n        System.out.println(\"¿La cadena está vacía? \"+greeting.isEmpty()+\" devuelve falso si la cadena no está vacía\");\n        System.out.println(\"¿La cadena está vacía? \"+emptyString.isEmpty()+\" devuelve verdadero si la cadena está vacía\");\n\n        //Unir con separador específico\n        String fruits = String.join(\" \", \"Orange\", \"Apple\", \"Mango\");\n        System.out.println(fruits);\n\n        //Reemplazar valor específicado\n        String newGreeting = greeting.replace(\"J\", \"L\");\n        System.out.println(newGreeting);\n\n        String text = \"I love cats. Cats are very easy to love. Cats are very popular.\";\n        String replace_word = text.replaceAll(\"(?i)cats\", \"Dog\");\n        System.out.println(replace_word);\n\n        //Subcadenas\n        String substringGreeting = greeting.substring(0, 4);\n        String otherSubstringGreeting = greeting.substring(6);\n\n        System.out.println(substringGreeting);\n        System.out.println(otherSubstringGreeting);\n\n        /*Extra*/\n        System.out.println(\"----------EXTRA----------\");\n        /*\n         * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n         * para descubrir si son:\n             * - Palíndromos\n             * - Anagramas\n             * - Isogramas\n        */\n\n        palindrome(\"amad\", \"dama\");\n        palindrome(\"casa\", \"barco\");\n\n        anagram(\"nacionalista\", \"altisonancia\");\n        anagram(\"nacimiento\", \"cimiento\");\n        anagram(\"the alias men\", \"alan smithee\");\n\n        isogram(\"casa\");\n        isogram(\"murcielago\");\n\n    }\n\n    public static void palindrome(String word1, String word2){\n        String reversedWord1 = \" \";\n        for (int i =word1.length()-1; i >= 0; i--) {\n            reversedWord1 += word1.charAt(i);\n        }\n        if (reversedWord1.trim().equals(word2)) {\n            System.out.println(\"Las palabras introducidas son palíndromos\");\n        }else {\n            System.out.println(\"Las palabras introducidas no son palíndromos\");\n        }\n    };\n\n    public static void anagram(String word1, String word2){\n        ArrayList<String> listWord1 = new ArrayList<String>();\n        ArrayList<String> listWord2 = new ArrayList<String>();\n\n        //Metemos los caracteres de la cadena en un string\n        for(int i = 0; i < word1.length(); i++){\n            listWord1.add(word1.charAt(i) + \"\");\n        }\n\n        for(int i = 0; i < word2.length(); i++){\n            listWord2.add(word2.charAt(i) + \"\");\n        }\n\n        //Ordenamos los ArrayList y lo guardamos en una variable string para comparar\n        Collections.sort(listWord1);\n        Collections.sort(listWord2);\n\n        String sortWord1 = \"\";\n        String sortWord2 = \"\";\n        for(String letter1 : listWord1){\n            sortWord1 += letter1;\n        }\n\n        for(String letter2 : listWord2){\n            sortWord2 += letter2;\n        }\n\n        //Comparamos las dos cadenas introducidas quitando los espacios en blanco\n        if(sortWord1.trim().equals(sortWord2.trim())){\n            System.out.println(\"Las palabra introducidas son un anagrama\");\n        }\n        else{\n            System.out.println(\"Las palabras introducidas no son un anagrama\");\n        }\n    };\n\n    public static void isogram(String word){\n        String saveWord = \"\";\n\n        boolean isIsogram = true;\n\n        //Recorremos la palabra y comprobamos si tiene letras repetidas\n        for(int i = 0; i < word.length(); i++){\n            if (saveWord.contains(word.charAt(i) + \"\")) {\n                isIsogram = false;\n            }else{\n                saveWord += word.charAt(i);\n            }\n        }\n        if (isIsogram) {\n            System.out.println(\"La palabra \"+word+\" es un isograma\");\n        }else{\n            System.out.println(\"La palabra \"+word+\" no es un isograma\");\n        }\n    };\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/martinbohorquez.java",
    "content": "import java.util.*;\nimport java.util.stream.Collectors;\n\n/**\n * #04 CADENAS DE CARACTERES\n *\n * @author martinbohorquez\n */\npublic class martinbohorquez {\n    /**\n     * Operaciones<p>\n     * Concatenación, Repeat, ChartAt, Length, Substring\n     */\n    private static final String STRING_1 = \"Hola\";\n    private static final String STRING_2 = \"Java\";\n    private static final String STRING_3 = \"\\s Road to World Cup  \\n\";\n\n    public static void main(String[] args) {\n\n        System.out.println(STRING_1 + \", \" + STRING_2 + \"!\");//Concatenación\n        System.out.println(STRING_1.repeat(3));//Repeat\n        System.out.println(STRING_1.charAt(2));//ChartAt\n        System.out.println(STRING_1.length());//Length\n\n        System.out.println(STRING_1.substring(1, STRING_1.length() - 1));//Substring\n        System.out.println(STRING_1.contains(\"ol\"));//Contains\n\n        System.out.println(STRING_1.toLowerCase());//toLowerCase\n        System.out.println(STRING_1.toUpperCase());//toUpperCase\n\n        System.out.println(STRING_1.replace(\"H\", \"S\"));//replace\n\n        System.out.println(\"----- STRIP AND TRIM ------\");\n        System.out.println(\"'\" + STRING_3 + \"'\");\n        System.out.println(\"'\" + STRING_3.strip() + \"'\");//strip\n        System.out.println(\"'\" + STRING_3.stripLeading() + \"'\");\n        System.out.println(\"'\" + STRING_3.stripTrailing() + \"'\");\n        System.out.println(\"'\" + STRING_3.stripIndent() + \"'\");\n        System.out.println(\"'\" + STRING_3.trim() + \"'\");//trim\n\n        System.out.println(\"----- REPLACE AND SPLIT ------\");\n        System.out.println(\"'\" + STRING_3.replace(\" \", \"\") + \"'\");//replace\n        System.out.println(\"'\" + STRING_3.replaceAll(\"[oa]\", \"u\") + \"'\");//replaceAl\n        System.out.println(Arrays.stream(STRING_3.split(\"o\")).toList());//split\n\n        System.out.println(\"----- REVERSE ------\");\n        StringBuilder sb = new StringBuilder(STRING_3);\n        System.out.println(sb.reverse());//reverse\n\n        System.out.println(STRING_2.startsWith(\"Ja\"));\n        System.out.println(STRING_1.endsWith(\"la\"));\n\n        System.out.println(STRING_3.indexOf(\"o\"));//indexOf\n        System.out.println(STRING_3.lastIndexOf(\"o\"));\n        System.out.println(STRING_3.indexOf(\"ad\"));\n\n        System.out.printf(\"Esto es una interpolación: %s, %s!%n\", STRING_1, STRING_2);//interpolación\n\n        System.out.println(Arrays.stream(STRING_2.split(\"\")).sorted().toList());//transformar a lista ordenada\n\n        System.out.println(STRING_2.chars()//transformar a lista ordenada\n                .mapToObj(c -> (char) c)\n                .sorted()\n                .toList());\n\n        /*\n         * DIFICULTAD EXTRA\n         * Palíndromos\n         * Anagramas\n         * Isogramas\n         */\n        System.out.println();\n        System.out.println(\"DIFICULTAD EXTRA:\\n\");\n\n        String text1 = \"Anita lava la tina\";\n        String text2 = \"Radar\";\n        System.out.println(\"¿'\" + text1 + \"' es un palíndromo? : \" + isPalindrome(text1));\n        System.out.println(\"¿'\" + text2 + \"' es un palíndromo? : \" + isPalindrome(text2));\n\n        String text3 = \"Listen\";\n        String text4 = \"Silent\";\n        System.out.println(\"¿El conjunto de '\" + text3 + \"' y '\" + text4 + \"' es un anagrama? : \"\n                + isAnagram(text3, text4));\n\n        String text5 = \"Yuxtaponer\";\n        System.out.println(\"¿'\" + text5 + \"' es un heterograma? : \" + isHeterogram(text5));\n\n        String text6 = \"Intestines\";\n        System.out.println(\"¿'\" + text6 + \"' es un isograma? : \" + isIsogram(text6));\n    }\n\n    private static boolean isPalindrome(String text) {\n        text = text.replace(\" \", \"\").toLowerCase();\n        StringBuilder sb = new StringBuilder(text);\n        return sb.reverse().toString().equals(text);\n    }\n\n    private static boolean isAnagram(String text1, String text2) {\n        return sorted(text1.toLowerCase()).equals(sorted(text2.toLowerCase()));\n    }\n\n    private static String sorted(String text) {\n        return text.chars()\n                .mapToObj(c -> (char) c)\n                .sorted()\n                .toList()\n                .toString();\n    }\n\n    private static boolean isHeterogram(String text) {\n        long sizeText = text.length();\n        Set<Character> textSet = getSet(text);\n        return sizeText == textSet.size();\n    }\n\n    private static Set<Character> getSet(String text) {\n        return text.toLowerCase()\n                .chars()\n                .mapToObj(c -> (char) c)\n                .collect(Collectors.toSet());\n    }\n\n    private static boolean isIsogram(String text) {\n        Map<Character, Integer> diccionario = new HashMap<>();\n        Set<Character> setText = getSet(text.toLowerCase());\n        if (text.length() % setText.size() != 0) {\n            return false;\n        }\n        setText.forEach(k -> diccionario.put(k, countLetters(text.toLowerCase(), k)));\n        return new HashSet<>(diccionario.values()).size() == 1;\n    }\n\n    private static Integer countLetters(String text, Character k) {\n        return (int) text.toLowerCase().chars().mapToObj(c -> (char) c)\n                .filter(c -> c.equals(k))\n                .count();\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/miguelex.java",
    "content": "public class miguelex {\n\n    public static boolean isPalindromo(String cadena) {\n        return cadena.toLowerCase().contentEquals(new StringBuilder(cadena.toLowerCase()).reverse());\n    }\n\n    public static boolean isAnagrama(String cadena1, String cadena2) {\n        if (cadena1.length() != cadena2.length()) return false;\n        String str1 = cadena1.toLowerCase().chars().sorted().collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append).toString();\n        String str2 = cadena2.toLowerCase().chars().sorted().collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append).toString();\n        return str1.equals(str2);\n    }\n\n    public static boolean isIsograma(String cadena) {\n        return cadena.toLowerCase().chars().distinct().count() == cadena.length();\n    }\n    public static void main(String[] args) {\n        String cadena = \"Hola Mundo\";\n        System.out.println(cadena);\n        System.out.println(cadena.replace(\"a\",\"m\"));\n        System.out.println(cadena.toLowerCase());\n        System.out.println(cadena.toUpperCase());\n        System.out.println(cadena.concat(\" desde Java\"));\n        System.out.println(cadena.charAt(2));\n        System.out.println(cadena.substring(1,3));\n        System.out.println(cadena.contains(\"en\"));\n        System.out.println(cadena.repeat(3));\n        System.out.println(cadena.split(\" \"));\n        System.out.println(\"Es Ana un palindromo? \" + isPalindromo(\"Ana\"));\n        System.out.println(\"Es Amanecer un palindromo? \" + isPalindromo(\"Amanecer\"));\n        System.out.println(\"Amor y Roma son anagramas? \"+ isAnagrama(\"Amor\",\"Roma\"));\n        System.out.println(\"Carbon y Petroleo son anagramas? \"+ isAnagrama(\"Carbon\",\"Petroleo\"));\n        System.out.println(\"Murcielago es un isograma? \"+ isIsograma(\"Murcielago\"));\n        System.out.println(\"Miguelex es un isograma? \"+ isIsograma(\"Miguelex\"));\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/mtirador.java",
    "content": "import java.util.Arrays;\nimport java.util.Scanner;\n\npublic class mtirador {\n\n public static void main(String[] args) {\n\n    /*Operaciones con caracteres */\n\n    /*Recorrer */\n    String cad=\"Hola Mundo\";\n    for(int i=0;i<cad.length();i++){\n        char caracter=cad.charAt(i);\n        System.out.println(i+\"-----\"+ caracter);\n    }\n\n    /*Acceso a caracteres específicos */\n\n    char car=cad.charAt(3);\n    System.out.println(car);\n\n    /*Longitud */\n\n    System.out.println(\"Logitud\"+ cad.length());\n\n    /*Repeticion */\n    System.out.println(\"Repeticion: \"+ cad.repeat(2));\n\n    //Conversión a mayúsculas y minúsculas\n    System.out.println(\"Minúsculas: \"+ cad.toLowerCase());\n    System.out.println(\"Mayúsculas: \"+ cad.toUpperCase());\n\n    //Reemplazo\n\n    String cambio=cad.replace(\"Hola\", \"Hello\");\n    System.out.println(\"Reemplazado: \"+ cambio);\n\n    \n    //División\n\n     String[] div= cad.split(\",\");\n     System.out.println(\"Division: \" + Arrays.toString(div));\n\n     // Unión\n\n    String[] words = { \"Hola\", \"mundo\", \"Java\" };\n    String union = String.join(\" \", words);\n    System.out.println(\"Union: \" + union);\n\n    //Interpolación\n    String interpol = String.format(\"Saludo: %s, Lenguaje: %s\", words[0], words[2]);\n    System.out.println(\"Interpolación: \" + interpol);\n\n    // Verificación\n    System.out.println(\"Vamos a verificar esta frase: \"+ cad);\n    boolean empieza = cad.startsWith(\"Hola\");\n    boolean termina = cad.endsWith(\"mundo!\");\n    System.out.println(\"Empieza con Hola: \" + empieza);\n    System.out.println(\"Termina con mundo: \" + termina);\n\n\n    /*Ejercicio */\n\n    System.out.println(\"Ingrese una palabra:\");\n    Scanner ent=new Scanner(System.in);\n    String palabra1 = ent.nextLine();\n    System.out.println(\"Ingrese otra palabra:\");\n    String palabra2 = ent.nextLine();\n    String palabraInvertida=\"\";\n    String palabraInvertida2=\"\";\n\n\n    Palindromo(palabra1, palabra2, palabraInvertida, palabraInvertida2);\n    Anagrama(palabra1, palabra2);\n    Heterograma(palabra1, palabra2);\n\n\n    ent.close();\n }\n \n/*Heterograma */\nstatic void Heterograma(String palabra1, String palabra2) {\n    boolean esHet1 = true;\n    boolean esHet2= true;\n    \n        for (int i = 0; i < palabra1.length() - 1; i++) {\n            for (int j = i + 1; j < palabra1.length(); j++) {\n                if (palabra1.charAt(i) == palabra1.charAt(j)) {\n                    esHet1 = false;\n                    break;\n                }\n            }\n            if (!esHet1) {\n                break;\n            }\n        }\n    \n        if (esHet1) {\n            System.out.println(palabra1 +\"-->Es un heterograma\");\n        } else {\n            System.out.println(palabra1+ \"-->No es un heterograma\");\n        }\n    \n    \n    for (int i = 0; i < palabra2.length() - 1; i++) {\n            for (int j = i + 1; j < palabra2.length(); j++) {\n                if (palabra2.charAt(i) == palabra2.charAt(j)) {\n                    esHet2 = false;\n                    break;\n                }\n            }\n            if (!esHet2) {\n                break;\n            }\n        }\n    \n       \n        if (esHet2) {\n            System.out.println(palabra2 +\"-->Es un heterograma\");\n        } else {\n            System.out.println(palabra2+ \"-->No es un heterograma\");\n        }\n}\n\n/*Anagrama */\nstatic void Anagrama(String palabra1, String palabra2) {\n    char[] word1 = palabra1.toCharArray();\n    char[] word2 = palabra2.toCharArray();\n    Arrays.sort(word1);\n    Arrays.sort(word2);\n    \n    boolean esAnagrama = Arrays.equals(word1, word2);\n    \n    if (esAnagrama) {\n        System.out.println(palabra1+\" y \"+ palabra2+ \"--> Son anagramas\");\n    } else {\n        System.out.println(palabra1+\" y \"+ palabra2+ \"--> No son anagramas\");\n      \n    }\n}\n\n/*Palindromo */\nstatic void Palindromo(String palabra1, String palabra2, String palabraInvertida, String palabraInvertida2) {\n    for(int i=palabra1.length()-1;i>=0;i--){\n        palabraInvertida+=palabra1.charAt(i);\n    }\n    for (int i = palabra2.length() - 1; i >= 0; i--) {\n        palabraInvertida2 += palabra2.charAt(i);\n    }\n    \n    if(palabra1.equalsIgnoreCase(palabraInvertida)){\n        System.out.println(\"Es palindromo-->\" + palabra1);\n    \n    }else{\n        System.out.println(palabra1+ \"--> No es palindromo\");\n    }\n    \n    if(palabra2.equalsIgnoreCase(palabraInvertida2)){\n        System.out.println(\"Es palindromo-->\" + palabra2);\n    \n    }else{\n        System.out.println(palabra2 +\"--> No es palindromo\");\n    }\n\n\n}\n\n\n\n}\n\n    \n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/java/simonguzman.java",
    "content": "\nimport java.util.*;\npublic class simonguzman {\n    public static void main(String[] args) {\n        \n        String str1 = \" Hello \";\n        String str2 = \" Challenge # 03 \";\n        String str3 = \" character \";\n        String str4 = \" strings \";\n\n        //Concatenar\n        String concatenatedString = str1 + str2 + str3 + str4;\n        System.out.println(concatenatedString);\n        String concatenatedString2 = str1.concat(concatenatedString);\n        System.out.println(concatenatedString2);\n        \n        //Obtener caracter en posicion especifica\n        char ch = str1.charAt(2);\n        System.out.println(ch);\n\n        //Subcadena de una cadena\n        String sub = str1.substring(2);\n        System.out.println(sub);\n        String sub2 = str1.substring(2, 4);\n        System.out.println(sub2);\n\n        //Longitud de una cadena\n        int len = str1.length();\n        System.out.println(len);\n\n        //comparando 2 cadenas(sensible a las mayusculas)\n        boolean isEqual = str1.equals(\" HELLO \");\n        System.out.println(isEqual);\n        //Comparando 2 cadenas(sin importar las mayusculas)\n        boolean isEqual2 = str1.equalsIgnoreCase(\" HELLO \");\n        System.out.println(isEqual2);\n\n        //Comparacion alfabetica de 2 cadenas(sensible a mayusculas)\n        int compare = str1.compareTo(\" hello \");\n        System.out.println(compare);\n        //Comparacion alfabetica de 2 cadenas(sin importar las mayusculas)\n        int compare2 = str1.compareToIgnoreCase(\" hello \");\n        System.out.println(compare2);\n\n        //Repetir una cadena\n        String repeatString = str1.repeat(3);\n        System.out.println(repeatString);\n\n        //Reemplazar caracteres\n        String charReplaced = str1.replace(\"l\", \"d\");\n        System.out.println(charReplaced);\n        //Reemplazar subcadenas\n        String subStrReplaced = str1.replace(\"ell\", \"all\");\n        System.out.println(subStrReplaced);\n\n        //Convertir a mayusculas\n        String upper = str1.toUpperCase();\n        System.out.println(upper);\n        //Convertir a minusculas\n        String lower = str1.toLowerCase();\n        System.out.println(lower);\n\n        //Eliminar espacios en blanco al inicio y al final\n        String trimmed = str1.trim();\n        System.out.println(trimmed);\n\n        //Convertir a otros tipos de cadena\n        String fromInt = str1.valueOf(123);\n        System.out.println(fromInt);\n        String fromChar = str1.valueOf('a');\n        System.out.println(fromChar);\n\n        //Si una cadena esta dentro de otra\n        boolean contains = str1.contains(\"ell\");\n        System.out.println(contains);\n        //Verificar si comienza con una subcadena\n        boolean startsWith = str1.startsWith(\" Hel\");\n        System.out.println(startsWith);\n        //Verificar si termina con una subcadena\n        boolean endsWith = str1.endsWith(\"llo \");\n        System.out.println(endsWith);\n\n        //Buscar posicion de una caracter o subcadena\n        int index = str1.indexOf('l');\n        System.out.println(index);\n        int lastIndex = str1.lastIndexOf(\"l\");\n        System.out.println(lastIndex);\n        int subIndex = str1.indexOf(\"ell\");\n        System.out.println(subIndex);\n\n        //Verificar si una cadena esta vacia\n        boolean isEmpty = str1.isEmpty();\n        System.out.println(isEmpty);\n\n        //Si una cadena es nula\n        boolean isBlank = str1 == null;\n        System.out.println(isBlank);\n\n        //Recorrer cada caracter de la cadena\n        for(int i = 0; i < str1.length(); i++){\n            System.out.println(str1.charAt(i));\n        }\n\n        //Invertir una cadena\n        String reversed = \"\";\n        for(int i = str1.length() - 1; i >= 0; i--){\n            reversed += str1.charAt(i);   \n        }\n        System.out.println(str1);\n        System.out.println(reversed);\n\n        ingresarPalabras();\n    }\n\n    //******************************** Ejercicio adicional ********************************/\n\n    public static void ingresarPalabras(){\n        Scanner scanner = new Scanner(System.in);\n        String word1 = \" \";\n        String word2 = \" \"; \n        System.out.println(\"Ingrese la primer palabra: \");\n        word1 = scanner.next();\n        System.out.println(\"Ingrese la segunda palabra: \");\n        word2 = scanner.next();\n        palindromo(word1, word2);\n        anagrama(word1, word2);\n        isograma(word1, word2);\n        scanner.close();\n    }\n\n    public static void anagrama(String word1, String word2) {\n        String difOrderWord1 = ordenarPalabra(word1);\n        String difOrderWord2 = ordenarPalabra(word2);\n\n        if ( difOrderWord1.equals(difOrderWord2)){\n            System.out.println(\"Las palabras son anagramas\");\n        }else{\n            System.out.println(\"Las palabras no son anagramas\");\n        }\n    }\n\n    public static void isograma(String word1, String word2){\n        boolean wordIsogram = verificarDuplicados(word1);\n        boolean wordIsogram2 = verificarDuplicados(word2);\n        if(wordIsogram){\n            System.out.println(\"La palabra es isograma\");\n        }else{\n            System.out.println(\"La palabra no es isograma\");\n        }\n\n        if(wordIsogram2){\n            System.out.println(\"La palabra es isograma\");\n        }else{\n            System.out.println(\"La palabra no es isograma\");\n        }\n    }\n\n    public static void palindromo(String word1, String word2){\n        String reverseWord1 = InvertirPalabra(word1);\n        String reverseWord2 = InvertirPalabra(word2);\n\n        if(word1.equals(reverseWord1)){\n            System.out.println(\"Es palindromo\");\n        }else{\n            System.out.println(\"No es palindromo\");\n        }\n        if(word2.equals(reverseWord2)){\n            System.out.println(\"Es palindromo\");\n        }else{\n            System.out.println(\"No es palindromo\");\n        }\n    }\n\n    public static String InvertirPalabra(String word){\n        String reverseWord = \"\";\n        for (int i = word.length() - 1; i >= 0; i--){\n            reverseWord += word.charAt(i);\n        }\n        return reverseWord;\n    }\n\n    public static String ordenarPalabra(String word){\n        char [] sortWork = word.toCharArray();\n        Arrays.sort(sortWork);\n\n        String newWork = new String(sortWork);\n        return newWork;\n    }\n\n    public static boolean verificarDuplicados(String word){\n        Set characthers = new HashSet<>();\n        for (int i = 0; i < word.length(); i++){\n            char c = word.charAt(i);\n            if(characthers.contains(c)){\n                return false;\n            }\n            characthers.add(c);\n        }\n        return true;\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/1Nonamed.js",
    "content": "// Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres en tu lenguaje.\n\n// STRINGS METHODS\nlet myName = \"Pablo\";\nconsole.log(myName.length);\n\n// ---- Acceder a las posiciones -- Búsqueda\nconsole.log(myName[0], myName[1]);\nconsole.log(myName.at(0), myName.at(1));\n\nlet myStr = \"This is a very very very Short Sentence.\";\nlet searchTerm = \"very\";\nconsole.log(\"IndexOf:\", myStr.indexOf(searchTerm));\nconsole.log(\"LastIndexOf:\", myStr.lastIndexOf(searchTerm));\n\n// ---- Contactenación\nconsole.log(myName.concat(\" is my name\"));\nconsole.log(`${myName} is my name`);\n\n// ---- Upper & Lowercase\nconsole.log(myName.toLowerCase());\nconsole.log(myName.toUpperCase());\n\n// ---- Recorrido\nconsole.log(myName.endsWith(\"lo\"));\nconsole.log(myName.startsWith(\"Pa\"));\nconsole.log(myName.includes(\"ab\"));\nconsole.log(myName.includes(\"ca\"));\n\n// ---- Extracción\nconst regexUpper = /[A-Z]/g; // Todas las mayús en un string\nconst regexSpecialCharacters = /[^\\w\\s']/g;\n\nconsole.log(myStr.match(regexUpper)); // Extraer mayús usando regex\n\nconsole.log(myStr.search(regexSpecialCharacters)); // Trae el index del caracter especial\nconsole.log(myStr[myStr.search(regexSpecialCharacters)]); // Accediendo a la posición: \".\"\n\nlet myNewString = \"Today will be an amazing day\";\nconsole.log(myNewString.slice(6, 10));\nconsole.log(myNewString.slice(-3)); // Para empezar desde atrás\n\n// ---- Divisón\nconsole.log(myNewString.split(\" \")); // Separa por espacios vacíos\n\n// ---- Substring\nconsole.log(myNewString.substring(2, 12)); // Extrae parte del string usando los indices\n\n// ---- Reemplazo\nconsole.log(myName.replace(\"b\", \"c\"), myName);\nconsole.log(myStr.replaceAll(\"very\", \"tiny\"));\n\n// ---- Transformación\nlet myNumb = 2344;\nconsole.log(myNumb.toString());\nconsole.log(String(myNumb)); // Recommended\n\n// Trim\nlet mySpacedString = \"      Hi!!    \";\nconsole.log(mySpacedString.trim())\nconsole.log(mySpacedString.trimEnd()) // Remueve espacios al final\nconsole.log(mySpacedString.trimStart()) // Remueve espacios al inicio\n\n\n// -------------- EXTRA CHALLENGE --------------\n\n// Crea un programa que analice dos palabras diferentes y realice comprobaciones para descubrir si son:\n//  * Palíndromos: Se lee igual de izq a derecha \n//  * Anagramas: \n//  * - Isogramas"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/7R0N1X.js",
    "content": "let sentence = \"Esto es una prueba\";\n\nconsole.log(sentence.at(1)); // Retorna el caracter en la posición 1, permite valores negativos para contar desde el final de la cadena\nconsole.log(sentence.at(-1));\n\nconsole.log(sentence.charAt(1)); // Retorna el caracter en la posición 1, no permite valores negativos\n\nconsole.log(sentence.charCodeAt(1)); // Retorna el código unicode del caracter en la posición 1\nconsole.log(sentence.codePointAt(1));\n\nlet str1 = 'Hola'\nlet str2 = 'Mundo'\nconsole.log(str1.concat(' ', str2)) // Concatena dos cadenas\n\nconsole.log(sentence.endsWith('prueba')); // Comprueba si la cadena termina con el texto especificado\n\nconsole.log(sentence.startsWith('Esto')); // Comprueba si la cadena comienza con el texto especificado\n\nconsole.log(sentence.includes('es')); // Comprueba si la cadena contiene el texto especificado\n\nconsole.log(sentence.indexOf('es')); // Devuelve la posición de la primera aparición del texto especificado en la cadena. No soporta expresiones regulares\n\nconsole.log(sentence.isWellFormed()); // Comprueba si la cadena es un mensaje válido\n\nconsole.log(sentence.lastIndexOf('a')); // Devuelve la posición de la última aparición del texto especificado en la cadena\n\nlet str3 = 'reservé'\nlet str4 = 'RESERVE'\nconsole.log(str3.localeCompare(str4)); // Compara dos cadenas en base al idioma local\n\nconst paragraph = 'The quick brown fox jumps over the lazy dog. It barked.';\nconst regex = /[A-Z]/g;\nconsole.log(paragraph.match(regex)) // Devuelve una lista de todas las coincidencias de la expresión regular\n\nconsole.log(sentence.padEnd(25, '*')); // Agrega asteriscos al final de la cadena hasta alcanzar la longitud especificada\n\nconsole.log(sentence.padStart(25)); // Agrega espacios al principio de la cadena hasta alcanzar la longitud especificada\n\nconsole.log(str1.repeat(3)); // Repetir la cadena 3 veces\n\nconsole.log(sentence.replace('es', 'is')); // Reemplaza el texto especificado por otro texto\n\nconsole.log(sentence.replaceAll('es', 'is')); // Reemplaza todos los ocurrencias del texto especificado por otro texto\n\nconsole.log(sentence.search('es')); // Devuelve la posición de la primera aparición del texto especificado en la cadena. Soporta expresiones regulares\n\nconsole.log(sentence.slice(1, 3)); // Devuelve una nueva cadena que contiene las letras del texto original desde la posición especificada hasta la posición especificada - 1\n\nconsole.log(sentence.split('es')); // Divide la cadena en una lista de cadenas, separando cada una por el texto especificado\n\nconsole.log(sentence.substring(1, 3)); // Devuelve una nueva cadena que contiene las letras del texto original desde la posición especificada hasta la posición especificada\n\nconsole.log(sentence.toLocaleLowerCase()); // Convierte la cadena a minúsculas en base al idioma local\n\nconsole.log(sentence.toLocaleUpperCase()); // Convierte la cadena a mayúsculas en base al idioma local\n\nconsole.log(sentence.toLowerCase()); // Convierte la cadena a minúsculas\n\nconsole.log(sentence.toUpperCase()); // Convierte la cadena a mayúsculas\n\nlet str5 = new String('Hola Mundo');\nconsole.log(str5.toString()); // Convierte la cadena a una cadena de caracteres\n\nconsole.log(str5.valueOf()); // Convierte la cadena a una cadena de caracteres\n\nlet str6 = '    Hola Mundo    '\nconsole.log(str6.trim()); // Elimina espacios en blanco al principio y final de la cadena\n\nconsole.log(str6.trimEnd()); // Elimina espacios en blanco al final de la cadena\n\nconsole.log(str6.trimStart()); // Elimina espacios en blanco al principio de la cadena\n\nconsole.log(sentence.length); // Devuelve la longitud de la cadena\n\n\n// Dificultad Extra\nlet str7 = 'radar'\nlet str8 = 'amor'\nlet str9 = 'roma'\nlet str10 = 'murcielago'\n\nfunction polindromo(str) {\n  return str.toLowerCase().split('').reverse().join('') === str.toLowerCase() ? true : false\n}\n\nfunction anagrama(str1, str2) {\n  return str1.toLowerCase().sort === str2.toLowerCase().sort ? true : false\n}\n\nfunction isograma(str) {\n  let mySet = new Set(str)\n  return str.length === mySet.size ? true : false\n}\n\nconsole.log(`¿La palabra ${str7} es políndroma?: ${polindromo(str7)}`)\nconsole.log(`¿Las palabras ${str8} y ${str9} son anagramas?: ${anagrama(str8, str9)} `)\nconsole.log(`¿La palabra ${str10} es un isograma?: ${isograma(str10)}`)\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/AChapeton.js",
    "content": "//at, charAt - Recibe un numero y devuelve el caracter en esa posicion\nconst sentence = 'Mouredev by Brais Moure';\nconsole.log('at', sentence.at(10));\nconsole.log('charAt', sentence.charAt(3));\n\n//concat - Conecta dos strings y devuelve una nueva\nconst str1 = 'Hola';\nconst str2 = 'Mundo';\nconsole.log('concat con espacio', str1.concat(' ', str2));\nconsole.log('concat con caracter', str1.concat('-', str2));\n\n//startsWith & endsWith - Evalua si el string inicia/termina con los caracteres del string del argumento y devuelve un booleano\nconsole.log('startsWith 1', sentence.endsWith('Mouredeb'));\nconsole.log('startsWith 2', sentence.endsWith('by'));\nconsole.log('endsWith 1', sentence.endsWith('Moure'));\nconsole.log('endsWith 2', sentence.endsWith('dev'));\n\n//fromCharCode - Devuelve un string creada por una secuencia de unidades de UTF-16\nconsole.log('fromCharCode', String.fromCharCode(12, 24, 15, 9));\n\n//includes - Evalua si un substring se encuentra dentro de un string. Devuelve un booleano. Se diferencia entre mayusculas y minusculas\nconst word1 = 'by';\nconst word2 = 'By';\nconsole.log('includes 1', sentence.includes(word1));\nconsole.log('includes 2', sentence.includes(word2));\n\n//indexOf - Devuelve la posicion en la que un substring inicia dentro de un string. En caso que la substring se repita, devuelve la posicion de la primera encontrada.\n//lastIndexOf - Devuelve la posicion en la que un substring inicia dentro de un string. En caso que la substring se repita, devuelve la posicion de la ultima encontrada.\nconst newSentence = 'Hola mundo. Bienvenidos al stream! Adios mundo.';\nconst word3 = 'mundo';\nconsole.log('indexOf', newSentence.indexOf(word3));\nconsole.log('lastIndexOf', newSentence.lastIndexOf(word3));\n\n//match - Devuelve los valores que coincidan con el regex\nconst regex = /[A-Z]/g; //Evalua solo mayusculas\nconsole.log('match', sentence.match(regex));\n\n//padStart & padEnd - Agregan un caracter al inicio o al final de la string, segun tantos espacios falten entre el ancho del string, y el ancho del argumento.\nconsole.log('padStart', sentence.padStart(106, '-'));\nconsole.log('padStart', sentence.padStart(102, '.'));\nconsole.log('padEnd', sentence.padEnd(40, '^'));\nconsole.log('padEnd', sentence.padEnd(80, '*'));\n\n\n//raw - Metodo que funciona con template literals para crear un string, en base a otra que tenga caracteres especiales que no se quieren perder o interpretar de forma inadecuada.\nconst __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {\n  if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\n  return cooked;\n};\n\nconst filePath = String.raw(__makeTemplateObject([\"C:Developmentprofileaboutme.html\"], [\"C:\\\\Development\\\\profile\\\\aboutme.html\"]));\nconsole.log('raw', \"Ruta de acceso: \".concat(filePath));\n\n//repeat - Devuelve una nueva string que contiene el numero de copias del string del argumento, concatenadas\nconst strSinSpacio = 'Mundo!';\nconst strConSpacio = 'Mundo! ';\nconsole.log('repeat 1', \"Hola \".concat(strSinSpacio.repeat(3)));\nconsole.log('repeat 2', \"Hola \".concat(strConSpacio.repeat(5)));\n\n//replace - Sustituye uno, constios, o toda un string, con otra string del segundo argumento del metodo.\nconst ownRegex = /Brais Moure/i;\nconsole.log('replace 1', sentence.replace('Brais', 'AChapeton'));\nconsole.log('replace 2', sentence.replace(ownRegex, 'Andres'));\n\n//search - Ejecuta una busqueda en base a un regex para buscar una similitud en un string, y devolver el index de esa primera similitud\nconst regex2 = /[^\\w\\s']/g; //Este regex evalua todo lo que NO sea una palabra, espacios en blanco, o comillas\nconsole.log('search', newSentence.search(regex2));\n\n//slice - Extrae una seccion del string y retorna una nueva, si modificar la original\nconsole.log('slice', sentence.slice(7));\n\n//split - Divide el string en base a un patron, y crea un array con las substrings resultantes\nconsole.log('split', sentence.split(' '));\n\n//toLowerCase & toUpperCase - Devuelve un string transformado todo a minusculas/mayusculas\nconsole.log('toLowerCase', sentence.toLowerCase());\nconsole.log('toUpperCase', sentence.toUpperCase());\n\n//trim - Elimina todos los espacios vacios que se encuentren al inicio o al final de un string\n//trimStart - Elimina solo los espacios vacion que se encuentra al inicio\n//trimEnd - Elimina solo los espacios vacion que se encuentra al final\nconst whiteSpaces = '    Hello World!     ';\nconsole.log('trim 1', whiteSpaces);\nconsole.log('trim 2', whiteSpaces.trim());\nconsole.log('trimStart', whiteSpaces.trimStart());\nconsole.log('trimEnd', whiteSpaces.trimEnd());\n\n// EJERCICIO EXTRA\nconst esPalindromo = function (my_string) {\n  const reverseStr = my_string.toLowerCase().split('').reverse().join('');\n  if (my_string.toLowerCase() === reverseStr) {\n      console.log('Es palindroma');\n  }\n  else {\n      console.log('No es palindroma');\n  }\n};\n\nesPalindromo('reconocer');\nesPalindromo('mundo');\n\nconst esAnagrama = function (str1, str2) {\n  const reverseStr2 = str2.toLowerCase().split('').reverse().join('');\n  if (str1.toLowerCase() === reverseStr2) {\n      console.log(\"La palabra \".concat(str1, \" es un anagrama\"));\n  }\n  else {\n      console.log(\"\".concat(str1, \" no es un anagrama\"));\n  }\n};\nesAnagrama('amor', 'roma');\n\nconst esIsograma = function (my_string) {\n  const letrasArray = my_string.toLowerCase().split('');\n  const letrasSet = new Set(letrasArray);\n  if (letrasArray.length === letrasSet.size) {\n      console.log(\"La palabra \".concat(my_string, \" es un isograma\"));\n  }\n  else {\n      console.log(\"\".concat(my_string, \" no es un isograma\"));\n  }\n};\n\nesIsograma('murcielago');\nesIsograma('ambiente');\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/AiresEsteban.js",
    "content": "let cadena = \"Hola Javascript\"\n\n//- Acceso a caracteres específicos\nconsole.log(cadena[0])\n\n//- Subcadenas\nconsole.log(cadena.substring(0,4))\nconsole.log(cadena.slice(5))\n\n//- Longitud\nconsole.log(cadena.length)\n\n//- Concatenación\nlet cadena2 = \"Comencemos!\"\nconsole.log(cadena + cadena2)\n\n//- Repetición\nconsole.log(cadena.repeat(2))\n\n//- Recorrido\nfor (let char of cadena){\n    console.log(char)\n}\n\n//- Conversión a mayúsculas y minúsculas\nconsole.log(cadena.toUpperCase())\nconsole.log(cadena.toLowerCase())\n\n//- Reemplazo\nconsole.log(cadena.replace(\"Javascript\", \"Python\"))\n\n//- División\nlet palabras = cadena.split(\" \")\nconsole.log(palabras)\n\n//- Unión\nconsole.log(palabras.join(\", \"))\n\n//- Interpolación\nlet profesion = \"Desarrollador\"\nconsole.log(`Hola, ${profesion}`)\n\n//- Verificación\nconsole.log(cadena.includes(\"Javascript\"))\nconsole.log(cadena.startsWith(\"Hola\"))\nconsole.log(cadena.endsWith(\"Javascript\"))\n\n//- Trim\n\nlet mySpacedString = \"     Hola    \"\nconsole.log(mySpacedString.trim())\nconsole.log(mySpacedString.trimEnd())\nconsole.log(mySpacedString.trimStart())\n\n\n// Dificulta extra\n\nfunction esPalindromo(palabra){\n    let invertida = palabra.split(\"\").reverse().join(\"\")\n    return palabra === invertida\n}\n\nfunction esAnagrama(palabra2,palabra3){\n    let sorted1 = palabra2.split(\"\").sort().join(\"\")\n    let sorted2 = palabra3.split(\"\").sort().join(\"\")\n    return sorted1 === sorted2\n}\n\nfunction esIsograma(palabra){\n    let letras = new Set(palabra)\n    return letras.size === palabra.length\n}\n\nlet palabra1 = \"anana\"\nlet palabra2 = \"roma\"\nlet palabra3 = \"amor\"\n\nconsole.log(`\"${palabra1}\" es un palíndromo? ${esPalindromo(palabra1)}`)\nconsole.log(`¿\"${palabra2}\" es un palíndromo? ${esPalindromo(palabra2)}`)\nconsole.log(`\"${palabra2}\" y \"${palabra3}\" son anagramas?${esAnagrama(palabra2,palabra3)}`)\nconsole.log(`¿\"${palabra1}\" es un isograma? ${esIsograma(palabra1)}`);\nconsole.log(`¿\"${palabra2}\" es un isograma? ${esIsograma(palabra2)}`);"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/Alvaro-Neyra.js",
    "content": "// Acesso a caracteres\nlet string = 'Hello, World!';\nlet charW = string[7];\nconsole.log(`Accediendo a un caracter en especifico del string usando []: ${charW}`);\n\n// Subcadenas\nlet subCadena = string.substring(0,5);\nconsole.log(`Conseguiendo una subcadena de la cadena principal usando el metodo .substring(): ${subCadena}`);\n\n// Longitud\nlet cadenaEjemplo = \"Hola, Hermoso mundo!\";\nlet longitudDeLaCadena = cadenaEjemplo.length;\nconsole.log(`Conseguiendo la longitud o la cantidad de caracteres de la cadena usando .length: ${longitudDeLaCadena}`);\n\n// Repeticion\nlet otraCadenaEjemplo = \"Querido, Mundo...\";\nlet repetirCadena = otraCadenaEjemplo.repeat(4);\nconsole.log(`Hemos usado el metodo .repeat(4) para repetir la cadena 4 veces: ${repetirCadena}`);\n\n// Recorrido:\nlet cadenaAIterar = \"Mi nombre es ...\";\nconsole.log(`Iterando la cadena....`);\nfor (let i = 0; i < cadenaAIterar.length; i++) {\n    console.log(`${cadenaAIterar[i]}`)\n}\n\n// Conversion a Mayusculas:\nlet importante = \"esto es importante\"\nlet importanteDeVerdad = importante.toUpperCase();\nconsole.log(`Con el metodo toUpperCase() transformamos la cadena a mayusculas: ${importanteDeVerdad}`);\n\n// Conversion a Minusculas:\nlet noImportante = \"ESTO NO DEBERIA SER IMPORTANTE\";\nlet noImportanteDeVerdad = noImportante.toLowerCase();\nconsole.log(`Con el metodo .toLowerCase() transformamos la cadena a mayusculas: ${noImportanteDeVerdad}`);\n\n// Reemplazo\nlet sentence = \"Esta maquina esta malograda!\";\nlet reemplazo = sentence.replace(\"malograda\", \"en buen estado\");\nconsole.log(`Hemos usado el metodo .replace() para reemplazar una subcadena existente: ${reemplazo}`);\n\n// Division\nlet cadenaALista = \"Esta va a ser una cadena que se separara por espacios\";\nlet divisionDeCadena = cadenaALista.split(\" \");\nconsole.log(`Hemos usado el metodo .split() para separar la cadena en subcadenas y conviertiendo cada subcadena en elementos de una lista: ${divisionDeCadena}`);\n\n// Union\nlet listaDeSubCadenas = [\"Hola\", \"Mundo\", \"Te\", \"Amo\"];\nlet cadenaUnida = listaDeSubCadenas.join(\", \");\nconsole.log(`Hemos usado el metodo .join() en una lista de elementos para separar esos elementos y luego convertirlos en un solo string: ${listaDeSubCadenas}`);\n\n// Interpolacion\nlet nombre = \"Alvaro\";\nlet saludo = `Hola, ${nombre}!`;\nconsole.log(`Usando la interpolacion para usar los valores de las variables existentes dentro un string: ${saludo}`);\n\n// Verificacion\nlet cadenaNoVerificada = \"Mi lindo perro se llama Luke!\";\nlet incluyeMiPerro = cadenaNoVerificada.includes(\"Luke\");\nconsole.log(`Usando el metodo .includes() para verificar si una subcadena existe dentro de la cadena principal, si existe devuelve true: ${incluyeMiPerro}`);\n\n// Ejercicio Opcional:\nfunction anagrama(string1, string2) {\n    let normalizar = (str) => str.toLowerCase().split('').sort().join('');\n    return normalizar(string1) === normalizar(string2);\n}\n\nfunction palindroma(string1) {\n    return string1 === string1.split('').reverse().join('');\n}\n\nfunction isograma(string1) {\n    let letras = string1.toLowerCase().split('').sort();\n    for (let i = 1; i < letras.length; i++){\n        if (letras[i] === letras[i - 1]) {\n            return false;\n        }\n    }\n    return true;\n}\n\nlet palabra1 = \"iman\";\nlet palabra2 = \"mani\";\n\nconsole.log(`Es ${palabra1} un palindrome?:`, palindroma(palabra1));\nconsole.log(`Es ${palabra2} un palindrome?:`, palindroma(palabra2));\n\nconsole.log(`Son ${palabra1} y ${palabra2} anagramas?`, anagrama(palabra1, palabra2));\n\nconsole.log(`Es ${palabra1} un isograma?:`, isograma(palabra1));\nconsole.log(`Es ${palabra2} un isograma?:`, isograma(palabra2));"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/AndresMCardenas.js",
    "content": "/*\n  * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n  * en tu lenguaje.Algunas de esas operaciones podrían ser(busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n * conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA(opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n  * para descubrir si son:\n * - Palíndromos\n  * - Anagramas\n  * - Isogramas\n*/\n\n// Acceso a caracteres específicos\nlet cadena = \"Hola Mundo\";\nconsole.log(cadena[0]); // Himprime H por que es el primer caracter de la cadena\n\n// Subcadenas\nconsole.log(cadena.substring(0, 4)); // Imprime Hola por que es la subcadena que va desde el caracter 0 hasta el 4\n\n// Longitud\nconsole.log(cadena.length); // Imprime 10 por que es la longitud de la cadena\n\n// Concatenación\nlet cadena2 = \" desde JavaScript\";  \nconsole.log(cadena + cadena2); // Imprime Hola Mundo desde JavaScript\n\n// Repetición\nconsole.log(cadena.repeat(3)); // Imprime Hola MundoHola MundoHola Mundo\n\n// Recorrido\nfor (let i = 0; i < cadena.length; i++) {\n  console.log(cadena[i]); // Imprime cada caracter de la cadena en una linea\n}\n\n// Conversión a mayúsculas y minúsculas\nconsole.log(cadena.toUpperCase()); // Imprime HOLA MUNDO  \nconsole.log(cadena.toLowerCase()); // Imprime hola mundo\n\n// Reemplazo\nconsole.log(cadena.replace(\"Hola\", \"Adios\")); // Imprime Adios Mundo\n\n// División\nconsole.log(cadena.split(\" \")); // Imprime [\"Hola\", \"Mundo\"]\n\n// Unión\nconsole.log(cadena.split(\" \").join(\"\")); // Imprime HolaMundo\n\n// Interpolación\nconsole.log(`${cadena} desde JavaScript`); // Imprime Hola Mundo desde JavaScript\n\n// Verificación\nconsole.log(cadena.includes(\"Hola\")); // Imprime true\n\n// Palíndromos\nlet palabra = \"oso\";\nlet palabraInvertida = palabra.split(\"\").reverse().join(\"\");\n\nif (palabra === palabraInvertida) {\n  console.log(\"Es palíndromo\");\n} else {\n  console.log(\"No es palíndromo\");\n}\n\n// Anagramas\nlet palabra1 = \"roma\";\nlet palabra2 = \"amor\";\n\nif (palabra1.split(\"\").sort().join(\"\") === palabra2.split(\"\").sort().join(\"\")) {\n  console.log(\"Es anagrama\");\n} else {\n  console.log(\"No es anagrama\");\n}\n\n// Isogramas\nlet palabra3 = \"murcielago\";\nlet isograma = true;\n\nfor (let i = 0; i < palabra3.length; i++) {\n  for (let j = i + 1; j < palabra3.length; j++) {\n    if (palabra3[i] === palabra3[j]) {\n      isograma = false;\n      console.log(\"No es isograma\");\n      break;\n    }\n  }  \n}\n\nif (isograma) {\n  console.log(\"Es isograma\");\n}\n\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/ArticKun.js",
    "content": "\n//* CADENAS DE CARACTERES\n\n/*\n\nEn JavaScript, una cadena de caracteres (también conocida como \"string\") \nes una secuencia de caracteres Unicode. Puedes crear cadenas utilizando \ncomillas simples (''), comillas dobles (\"\") o la sintaxis de comillas \ninvertidas (``).\n\n*/\n\n\n//* OPERACIONES\n\n//Acceso a caracteres específicos:\nlet cadena = \"JavaScript\";\nlet tercerCaracter = cadena[2];\nconsole.log(tercerCaracter); // Salida: v\n\n\n//Subcadenas:\nlet cadena2 = \"JavaScript\";\nlet subcadena = cadena2.substring(0, 4);\nconsole.log(subcadena); // Salida: Java\n\n\n//Longitud de una cadena:\nlet cadena3 = \"Hola, mundo!\";\nlet longitud = cadena3.length;\nconsole.log(longitud); // Salida: 12\n\n\n//Concatenación:\nlet str1 = \"Hola\";\nlet str2 = \"Mundo\";\nlet resultado = str1.concat(\" \", str2);\nconsole.log(resultado);          // Salida: Hola Mundo\nconsole.log(str1 + \" \" + str2 ); // Salida: Hola Mundo\n\n\n//Repeticion\nlet cadena4 = \"Hola \";\nlet repetida = cadena4.repeat(4);\nconsole.log(repetida); // Salida: Hola Hola Hola Hola\n\n\n//Recorrido\nlet cadena5 = \"JavaScript\";\nfor (let i = 0; i < cadena5.length; i++) {\n  console.log( cadena5[i] );\n};\n//Salida:\n/*\n\n\"J\"\n\"a\"\n\"v\"\n\"a\"\n\"S\"\n\"c\"\n\"r\"\n\"i\"\n\"p\"\n\"t\"\n\n*/\n\n\n//Conversión a mayúsculas y minúsculas:\nlet cadena6 = \"JavaScript\";\nlet mayusculas = cadena6.toUpperCase();\nlet minusculas = cadena6.toLowerCase();\nconsole.log(mayusculas); // Salida: JAVASCRIPT\nconsole.log(minusculas); // Salida: javascript\n\n\n//Reemplazo\nlet frase = \"La programación es divertida\";\nlet buscar = \"divertida\";\nlet reemplazarCon = \"increíble\";\nlet nuevaFrase = frase.replace(buscar, reemplazarCon);\nconsole.log(nuevaFrase); // Salida: La programación es increíble\n\n\n//División\nlet cadena7 = \"Manzana,Naranja,Uva\";\nlet frutas = cadena7.split(\",\");\nconsole.log(frutas); // Salida: [\"Manzana\", \"Naranja\", \"Uva\"]\n\n\n//Unión\nlet frutas2 = [\"Manzana\", \"Naranja\", \"Uva\"];\nlet cadena8 = frutas2.join(\" - \");\nconsole.log(cadena); // Salida: Manzana - Naranja - Uva\n\n\n//Interpolación de Cadenas\nlet nombre = \"Artic\";\nlet edad = 34;\nlet mensaje = `Hola, soy ${nombre} y tengo ${edad} años.`;\nconsole.log(mensaje); // Salida: Hola, soy Artic y tengo 34 años.\n\n\n//Verificación de presencia\nlet cadena9 = \"JavaScript\";\nlet contieneJava = cadena9.includes(\"Java\");\nconsole.log(contieneJava); // Salida: true\n\n\n//Busqueda de subcadena\nvar cadena10 = \"Hola mundo\";\nvar subcadena2 = \"mundo\";\nvar indice = cadena10.indexOf(subcadena2); // indice será 5\n\n\n//Comparación de Cadenas\nvar cadenaA = \"Hola\";\nvar cadenaB = \"Hola\";\nvar comparacion = cadenaA === cadenaB; // comparacion será true\n\n\n\n//* DIFICULTAD EXTRA:\n/*\n\nCrea un programa que analice dos palabras diferentes y realice comprobaciones\npara descubrir si son:\n\n    Palíndromos\n    Anagramas\n    Isogramas\n\n*/\n\n/*\n\nPolindromos\nson aquellas que se leen igual de izquierda a derecha que de derecha a izquierda.\n\"oso\", \"reconocer\", \"radar\" y \"salas\". \n\nAnagramas\nLas palabras anagramas son aquellas que se forman mediante la reorganización de \nlas letras de otra palabra, utilizando todas las letras originales exactamente \nuna vez. \n\"amor\" y \"roma\" son anagramas, ya que comparten las mismas letras pero están \ndispuestas de manera diferente.\n\nIsogramas\nLas palabras isogramas son aquellas que no tienen letras repetidas. En un isograma, \ncada letra aparece una sola vez.\n\"murciélago\", \"estufa\" y \"celular\".\n\n*/\n\n\nlet analyzeWord = () => {\n\n//Palabras que se pueden cambiar para testear\n    let word1 = 'murciélago';\n    let word2 = 'oso';\n\n    console.log('---------- PALINDROMO ----------');\n    let palindromo = (w) => {\n        let minus = w.toLowerCase();\n        let rev = minus.split('').reverse().join('');\n        if( minus === rev ){\n            console.log(`${w} Es Palíndromo`);\n        }else{\n            console.log(`${w} No es Palíndromo`);\n        }\n    };\n    palindromo( word1 );\n    palindromo( word2 );\n    console.log('---------- ANAGRAMA ----------');\n    let anagrama = ( w1,w2 ) =>{\n        let str1 = w1.toLowerCase();\n        let str2 = w2.toLowerCase();\n        const arr1 = str1.split('').sort().join('');\n        const arr2 = str2.split('').sort().join('');\n        return arr1 === arr2;\n    };\n    if( anagrama(word1, word2) ){\n        console.log(`${word1} y ${word2} Son Anagramas.`);\n    }else{\n        console.log(`${word1} y ${word2} No son Anagramas.`);\n    }\n    console.log('---------- ISOGRAMA ----------');\n    let isograma = (w) =>{\n        let minus = w.toLowerCase();\n        let letras = new Set();\n        for (let letra of minus) {\n            // Si la letra ya está en el conjunto, no es un isograma\n            if ( letras.has(letra) ) {\n              console.log(`${w} No es un Isograma`);\n              return;\n            }else{\n                letras.add(letra);\n            }\n          }\n        //no se encontraron letras repetidas, es un isograma\n        console.log(`${w} Es un Isograma`);;\n    }\n    isograma( word1 );\n    isograma( word2 );\n};\n\n\nanalyzeWord();\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/CaveroBrandon.js",
    "content": "/*\nEJERCICIO:\nMuestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\nen tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n- Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\nconversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n*/\nconst operationString = 'Hello world';\nconst supportString = 'Javascript!';\n\nconsole.log('Original string: ' + operationString);\nconsole.log('Access to second character: ' + operationString[1]);               // Accesing an specific character\nconsole.log('Verifying the existence of a substring: ', operationString.includes('world'))  // Finding a substring\nconsole.log('Getting the substring index: ', operationString.indexOf('world')); // Finding the index of a substring\nconsole.log('Extracting a substring: ', operationString.slice(-5));             // Extracting a substring\nconsole.log('String lenght is: ' + operationString.length);                     // Length of a string\nconsole.log('Concatenated string: ' + `${operationString} - ${supportString}`); // Concatenating strings\nconsole.log('Repeat a string: ', supportString.repeat(2));                      // Repeating a string\nconsole.log('Convert to upper case: ', supportString.toUpperCase());            // Converting to upper cas\nconsole.log('Convert to lower case: ', supportString.toLowerCase());            // Converting to lower case\nconsole.log('Replacing a substring: ', operationString.replace('world', supportString));    // Replacing a substring with other substring\nconsole.log('Spliting a string: ', operationString.split(' '));                 // Spliting a string\nconsole.log(`Interpolating a string in ${supportString}`);                      // Interpolating a string\nconsole.log('Using scape characters:\\n', operationString);                      // Scape characters\n// Iterating a string\nfor (i in supportString) {\n    console.log(supportString[i]);\n}\n\n/*\nDIFICULTAD EXTRA (opcional):\nCrea un programa que analice dos palabras diferentes y realice comprobaciones\npara descubrir si son:\n- Palíndromos\n- Anagramas\n- Isogramas\n*/\n\nfunction preProcess(userText) {\n    let lowerCaseString = userText.toLowerCase();\n    let originalString = lowerCaseString.split(' ').join('');\n    return originalString.split('');\n}\n\nfunction isPalindrome(userText) {\n    let lowerCaseString = userText.toLowerCase();\n    let originalString = lowerCaseString.split(' ').join('');\n    let splitArray = originalString.split('');\n    let reversedString = splitArray.reverse().join('');\n    \n    if (reversedString == originalString) {\n        console.log(`The text \"${userText}\" is palindrome`);\n        return true;\n    }\n    else {\n        console.log(`The text \"${userText}\" is not a palindrome`);\n        return false;\n    }\n}\n\nfunction isAnagram(firstText, secondText) {\n    let firstTextArray = preProcess(firstText);\n    let secondTextArray = preProcess(secondText);\n\n    if (firstTextArray.sort().join('') === secondTextArray.sort().join('')) {\n        console.log(`The texts \"${firstText}\" and \"${secondText}\" are anagrams`);\n        return true;\n    }\n    else {\n        console.log(`The texts \"${firstText}\" and \"${secondText}\" are not anagrams`);\n        return false;\n    }\n\n}\n\nfunction isIsogram(userText) {\n    let userTextArray = preProcess(userText);\n    \n    let evaluationSet = new Set();\n    userTextArray.forEach(element => {\n        evaluationSet.add(element);\n    });\n    evaluationArray = Array.from(evaluationSet);\n    if (userTextArray.join('') === evaluationArray.join('')) {\n        console.log(`The text \"${userText}\" is an isogram`);\n        return true;\n    }\n    else {\n        console.log(`The text \"${userText}\" is not an isogram`);\n        return false;\n    }\n\n}\n\nconsole.log('----- Palindrome -----')\nisPalindrome('Hello Javascript');\nisPalindrome('Nurses run');\nconsole.log('----- Anagrams -----');\nisAnagram('Javascript', 'Cinema');\nisAnagram('iceman', 'Cinema');\nconsole.log('----- Isogram -----');\nisIsogram('Javascript');\nisIsogram('Lumberjacks');\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/CesarCarmona30.js",
    "content": "// EJERCICIO \n\n// Concatenación de cadenas\nlet name = \"César\";\nlet surname = \"Carmona\";\n\nlet fullname = name + \" \" + surname;\nconsole.log(\"Nombre: \", fullname);\n\n// Interpolación\nconsole.log(`Soy ${name} ${surname}`);\n\n// Acceso a caracteres específicos\nlet language = \"JavaScript\";\nconsole.log(\"El lenguaje en que estás programando es: \", language[0], language[4]);\nconsole.log(\"Primer caracter: \", language.charAt(0));\n\n// Subcadena\nlet substring = language.substring(0, 3);\nconsole.log(\"Subcadena:\", substring);\n\n// Longitud de cadena\nconsole.log(\"Longitud de la cadena:\", language.length);\n\n\n// Repetición\nlet languageRepeat = language.repeat(3);\nconsole.log(\"Cadena repetida:\", languageRepeat);\n\n// Recorrido \nfor (let i = 0; i < language.length; i++) {\n    console.log(\"Carácter en posición\", i, \":\", language[i]);\n}\n\n// Conversión a mayúsculas y minúsculas\nconsole.log(\"Mayúsculas:\", language.toUpperCase());\nconsole.log(\"Minúsculas:\", language.toLowerCase());\n\n// Reemplazo\nlet newlanguage = language.replace(\"Java\", \"Python\");\nconsole.log(\"Reemplazo:\", newlanguage);\n\n// División\nlet string = \"¡Hola Mundo!\"\nlet words = string.split(\" \");\nconsole.log(\"División por espacio:\", words);\n\n// Unión\nlet newString = words.join(\"-\");\nconsole.log(\"Unión con guiones:\", newString);\n\n// Verificación\nlet contains = string.includes(\"Hola\");\nconsole.log(\"Contiene 'Hola': \", contains);\n\n// Dificultad extra\n\nfunction check(cadena1, cadena2) {\n    function palindrome(cadena1, cadena2) {\n        return cadena1.toLowerCase() === cadena2.split(\"\").reverse().join(\"\").toLowerCase();\n    }\n    console.log(\"Es palíndromo:\", palindrome(cadena1, cadena2));\n\n    function anagram(cadena1, cadena2) {\n        return cadena1.toLowerCase().split(\"\").sort().join(\"\") === cadena2.toLowerCase().split(\"\").sort().join(\"\")\n    }\n    console.log(\"Es anagrama:\", anagram(cadena1, cadena2));\n\n    function isogram(cadena1, cadena2) {\n        let caracteres = {};\n\n        for (let i = 0; i < cadena1.length; i++) {\n            if (caracteres[cadena1[i].toLowerCase()]) {\n                return false;\n            }\n            caracteres[cadena1[i]] = true;\n        }\n\n        for (let i = 0; i < cadena2.length; i++) {\n            if (caracteres[cadena2[i].toLowerCase()]) {\n                return false;\n            }\n            caracteres[cadena2[i]] = true;\n        }\n\n        return true;\n    }\n    console.log(\"Es isograma:\", isogram(cadena1, cadena2));\n}\n\n\ncheck(\"radar\", \"pythonpythonpythonpythonpython\");\ncheck(\"amor\", \"roma\");"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/DAVstudy.js",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\nlet myString = \"Hola! JavaScript\";\n\n// Acceso\nconsole.log(myString[0]);\nconsole.log(myString[1]);\nconsole.log(myString[2]);\n\n// at() retorna el caracter del indice indicado\nconsole.log(myString.at(-1));\n\n// Subcadenas\nconsole.log(myString.substring(0, 8));\n\n// Longitud\nconsole.log(myString.length);\n\n// Concatenacion\n\nlet name = \"Diego\";\nlet lastname = \"Arenas\";\nlet fullname = name.concat(\" \", lastname);\n\nconsole.log(fullname);\n\n// Repeticion\nconsole.log(name.repeat(10));\n\n// Recorrer un string\nfor (let i = 0; i < myString.length; i++) {\n  console.log(myString[i]);\n}\n\n// Conversion mayus y minus\nconsole.log(myString.toUpperCase());\nconsole.log(myString.toLowerCase());\n\n// Reemplazar\nconsole.log(myString.replace(\"javascript\", \"JavaScript\")); // Reemplaza la primera palabra que coincida con lo indicado pero solo esa\nconsole.log(myString.replaceAll(\"a\", \"!\")); // Reemplaza todos los caracteres que coinciden\n\n// Split\nconst words = myString.split(\" \"); // devolvera un array, separarando elementos dado el string que se indicque\nconsole.log(words);\n\n// Splice\nlet newString = myString.slice(3, -3); // El método slice() extrae una sección de una cadena y devuelve una cadena nueva.\nconsole.log(newString);\n\n// template literal\nconsole.log(`Mi nombre es ${name}`);\n\n// Verificacion\n\n// Busqueda\n\n// search\nconsole.log(myString.search(/[aeiouáéíóú]/)); // sirve para buscar expresiones regulares si encuentra una coincidencia retorna el indice, si no -1\n\n// includes\nconsole.log(myString.includes(\"la\")); // Retorna true si incluye y false en caso contrario\n\n// indexOf\nconsole.log(myString.indexOf(\"Java\")); // Retorna el indice de una subcadena literal\n\n// lastIndexOf\nconsole.log(myString.lastIndexOf(\"Java\")); // Retorna el indice de una subcadena literal buscando desde el final hacia el inicio\n\n// match\nconst regex = /[A-Z]/g;\nconst found = myString.match(regex); // devolvera un arrai con todas las expreciones regulares indicadas, en este caso todas las mayusculas\nconsole.log(found);\n\n// matchAll\n// El método matchAll() retorna un iterador de todos los resultados de ocurrencia en una cadena de texto contra una expresión regular, incluyendo grupos de captura.\nconst regexp = /t(e)(st(\\d?))/g;\nconst str = \"test1test2\";\n\nconst array = [...str.matchAll(regexp)];\n\nconsole.log(array[0]);\n// Expected output: Array [\"test1\", \"e\", \"st1\", \"1\"]\n\nconsole.log(array[1]);\n// Expected output: Array [\"test2\", \"e\", \"st2\", \"2\"]\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\n\nconst AnalizeWords = {\n  reverseString: (str) => str.split(\"\").reverse().join(\"\"),\n  sortString: (str) => str.split(\"\").sort().join(\"\"),\n  isIsogram: function (str) {\n    const listChars = str.split(\"\").sort();\n    const Counts = {};\n    let result = true;\n    for (const element of listChars) {\n      if (Object.hasOwn(Counts, element)) {\n        Counts[element] += 1;\n        result = false;\n      } else {\n        Counts[element] = 1;\n      }\n    }\n    return result ? `${str} es un Isograma` : `${str} no es un Isograma`;\n  },\n  isAnagram: function (word1, word2) {\n    return this.sortString(word1) === this.sortString(word2)\n      ? `${word1} y ${word2} son un anagrama`\n      : `${word1} y ${word2} no son un anagrama`;\n  },\n  isPalindrome: function (word) {\n    return word === this.reverseString(word)\n      ? `${word} es un palindromo`\n      : `${word} no es un palindromo`;\n  },\n  verify : function (word1, word2) {\n    console.log(AnalizeWords.isPalindrome(word1));\n    console.log(AnalizeWords.isPalindrome(word2));\n\n    console.log(AnalizeWords.isAnagram(word1, word2));\n\n    console.log(AnalizeWords.isIsogram(word1));\n    console.log(AnalizeWords.isIsogram(word1));\n  }\n};\n\nconsole.log(AnalizeWords.verify(\"arroz\", \"zorra\"));\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/Dan-Corbo.js",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\n\n/* Soluciones */\n\n\n// Acceso a caracteres específicos\n\nlet palabra = \"Hola\";\nconsole.log(palabra[0]);  // Imprime \"H\"\nconsole.log(palabra.charAt(2));  // Imprime \"l\"\n\n\n//Subcadenas\n\nlet frase = \"JavaScript es poderoso\";\nlet subcadena = frase.substring(0, 10);\nlet subcadena2 = frase.indexOf(\"poderoso\");\nconsole.log(subcadena);  // Imprime \"JavaScript\"\nconsole.log(subcadena2); // Imprime la posicion de la primera letra de la subcadena mencionada \"14\"\n\n\n// Longitud de una cadena\n\nlet texto = \"Ejemplo\";\nconsole.log(texto.length);  // Imprime 7\n\n\n// Concatenación\n\nlet cadena1 = \"Hola\";\nlet cadena2 = \" Mundo\";\nlet resultado = cadena1 + cadena2;\nconsole.log(resultado);  // Imprime \"Hola Mundo\"\n\n// Repetición\n\nlet palabra1 = \" Hola\";\nlet repetida = palabra1.repeat(3);\nconsole.log(repetida);  // Imprime \" Hola Hola Hola\"\n\n\n// Recorrido\n\nlet palabra2 = \"JavaScript\";\nfor (let i = 0; i < palabra2.length; i++) {\n    console.log(palabra2[i]);\n}\n// Imprime cada letra de \"JavaScript\" en líneas separadas\n\n\n// Conversión a mayúsculas y minúsculas\n\nlet minusculas = \"javascript\";\nlet mayusculas = minusculas.toUpperCase();\nconsole.log(mayusculas);  // Imprime \"JAVASCRIPT\"\n\n\n// Reemplazo\n\nlet frase2 = \"JavaScript es divertido\";\nlet nuevaFrase2 = frase2.replace(\"divertido\", \"poderoso\");\nconsole.log(nuevaFrase2);  // Imprime \"JavaScript es poderoso\"\n\n\n// División\n\nlet lista = \"manzana,banana,cereza\";\nlet arrayFrutas = lista.split(\",\");\nconsole.log(arrayFrutas);  // Imprime [\"manzana\", \"banana\", \"cereza\"]\n\n\n// Unión\n\nlet arrayColores = [\"rojo\", \"verde\", \"azul\"];\nlet cadenaColores = arrayColores.join(\", \");\nconsole.log(cadenaColores);  // Imprime \"rojo, verde, azul\"\n\n\n// Interpolación\n\nlet nombre = \"Juan\";\nlet edad = 25;\nlet mensaje = `Hola, me llamo ${nombre} y tengo ${edad} años.`;\nconsole.log(mensaje);\n// Imprime \"Hola, me llamo Juan y tengo 25 años.\"\n\n\n// Verificación\n\nlet correo = \"usuario@dominio.com\";\nlet esCorreoValido = correo.includes(\"@\");\nconsole.log(esCorreoValido);  // Imprime true\n\n\n// Extra - Opcional\n\n\n// Funcion para verificar si una palabra es palíndroma\nfunction esPalindromo(palabra) {\n    const palabraReversa = palabra.split('').reverse().join('');\n    return palabraReversa === palabra;\n}\n\n// Funcion para verificar si una palabra es un anagrama\nfunction esAnagrama(palabra) {\n    const ordenada = palabra.split('').sort().join('');\n    return ordenada === palabra;\n}\n\n// Funcion para verificar si una palabra es un isograma\nfunction esIsograma(palabra) {\n    const letras = {};\n    for (let letra of palabra) {\n        if (letras[letra]) {\n            return false;\n        }\n        letras[letra] = true;\n    }\n    return true;\n}\n\n\n// Funcion que dependiendo el resultado de si una o mas palabras son palíndromos, anagramas o isogramas, devuelve un resultado\nfunction palabras(palabra1, palabra2) {\n    let resultado = \"\";\n\n    if (esPalindromo(palabra1) && esPalindromo(palabra2)) {\n        resultado += `\"${palabra1}\" y \"${palabra2}\" son Palíndromos.\\n`;\n    } else if (esPalindromo(palabra1)) {\n        resultado += `\"${palabra1}\" es un Palíndromo y \"${palabra2}\" no lo es.\\n`;\n    } else if (esPalindromo(palabra2)) {\n        resultado += `\"${palabra2}\" es un Palíndromo y \"${palabra1}\" no lo es.\\n`;\n    } else {\n        resultado += `Ninguna es un Palíndromo.\\n`;\n    }\n\n    if (esAnagrama(palabra1) && esAnagrama(palabra2)) {\n        resultado += `\"${palabra1}\" y \"${palabra2}\" son Anagramas.\\n`;\n    } else if (esAnagrama(palabra1)) {\n        resultado += `\"${palabra1}\" es un Anagrama y \"${palabra2}\" no lo es.\\n`;\n    } else if (esAnagrama(palabra2)) {\n        resultado += `\"${palabra2}\" es un Anagrama y \"${palabra1}\" no lo es.\\n`;\n    } else {\n        resultado += `Ninguna es un Anagrama.\\n`;\n    }\n\n    if (esIsograma(palabra1) && esIsograma(palabra2)) {\n        resultado += `\"${palabra1}\" y \"${palabra2}\" son Isogramas.\\n`;\n    } else if (esIsograma(palabra1)) {\n        resultado += `\"${palabra1}\" es un Isograma y \"${palabra2}\" no lo es.\\n`;\n    } else if (esIsograma(palabra2)) {\n        resultado += `\"${palabra2}\" es un Isograma y \"${palabra1}\" no lo es.\\n`;\n    } else {\n        resultado += `Ninguna es un Isograma.\\n`;\n    }\n\n    return resultado.trim(); // Elimina posibles espacios en blanco al final\n}\n\n// Ejemplo de uso\nconsole.log(palabras(\"Uruguay\", \"Amor\"));\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/DanielBustos342.js",
    "content": "//! Operaciones con cadenas\n\n//* Concatenacion de cadenas\nlet str1 = \"Hola\";\nlet str2 = \"Mundo\";\nlet result = str1 + \" \" + str2; // \"Hola Mundo\"\n\n//* Acceso a caracteres\nlet str = \"JavaScript\";\nlet char = str[0]; // \"J\"\nlet charAt = str.charAt(0); // \"J\"\n\n//* Longitud de una cadena\nlet string = \"Hola Mundo\";\nlet length = string.length; // 10\n\n//* Cambio de mayusculas a minusculas\nlet str3 = \"Hola Mundo\";\nlet upperCase = str3.toUpperCase(); // \"HOLA MUNDO\"\nlet lowerCase = str3.toLowerCase(); // \"hola mundo\"\n\n//* Extraccion de subcadenas\nlet str4 = \"Hola Mundo\";\nlet substring = str4.substring(0, 4); // \"Hola\"\nlet slice = str4.slice(5); // \"Mundo\"\n\n//* Division de una cadena\nlet str5 = \"Hola Mundo\";\nlet split = str5.split(\" \"); // [\"Hola\", \"Mundo\"]\n\n//* Reemplazo de texto\nlet str6 = \"Hola Mundo\";\nlet replaced = str6.replace(\"Mundo\", \"JavaScript\"); // \"Hola JavaScript\"\n\n//* Busqueda de texto\nlet str7 = \"Hola Mundo\";\nlet indexOf = str7.indexOf(\"Mundo\"); // 5\nlet includes = str7.includes(\"Mundo\"); // true\n\n//* Eliminar espacios en blanco\nlet str8 = \"   Hola Mundo   \";\nlet trimmed = str8.trim(); // \"Hola Mundo\"\n\n//* Repetir cadenas\nlet str9 = \"Hola\";\nlet repeated = str9.repeat(3); // \"HolaHolaHola\"\n\n//* Conversion de una cadena en un arreglo de caracteres\nlet str10 = \"Hola\";\nlet array = Array.from(str10); // [\"H\", \"o\", \"l\", \"a\"]\n\n//* Verificacion de inicio y final de una cadena\nlet str11 = \"Hola Mundo\";\nlet startsWith = str11.startsWith(\"Hola\"); // true\nlet endsWith = str11.endsWith(\"Mundo\"); // true\n\n//* Interpolacion de cadenas (template literals)\nlet nombre = \"Juan\";\nlet saludo = `Hola, ${nombre}`; // \"Hola, Juan\"\n\n//* Obtener codigo de caracter\nlet str12 = \"A\";\nlet charCode = str12.charCodeAt(0); // 65\n\n//* Recorrido\nlet str13 = \"JavaScript\";\nfor (let i = 0; i < str13.length; i++) {\n  console.log(str13[i]);\n}\n// J\n// a\n// v\n// a\n// S\n// c\n// r\n// i\n// p\n// t\n\n//* Union\nlet arr = [\"Hola\", \"Mundo\"];\nlet joined = arr.join(\" \"); // \"Hola Mundo\"\n\n//! Ejercicio Extra\n// Polindromo: es una palabra, numero o frace que se lee igual de izquierda a derea que de derecha a izquierda\nfunction isPalindromo(stringA) {\n  let palindromo = Array.from(stringA);\n  let revercedPolindromo = [];\n  for (let i = stringA.length - 1; i >= 0; i--) {\n    revercedPolindromo.push(stringA[i]);\n  }\n  let isPalindromo = true;\n  for (let j = 0; j < palindromo.length; j++) {\n    if (palindromo[j].toLowerCase() !== revercedPolindromo[j].toLowerCase()) {\n      isPalindromo = false;\n      break;\n    }\n  }\n  if (isPalindromo) {\n    return `${stringA} es palindromo`;\n  } else {\n    return `${stringA} no es palindromo`;\n  }\n}\n// Anagrama: es una palabra o frace que se forma reordenando las letras de otra palabra o frace original, utilizando exactamente las mismas letras con la misma frecuencia.\nfunction cleanSort(string) {\n  return string\n    .toLowerCase()\n    .replace(/[^a-z0-9]/g, \"\")\n    .split(\"\")\n    .sort()\n    .join(\"\");\n}\nfunction isAnagrama(stringA, stringB) {\n  let string1 = cleanSort(stringA);\n  let string2 = cleanSort(stringB);\n\n  if (string1 === string2) {\n    return `${stringA} y ${stringB} son Anagramas`;\n  } else {\n    return `${stringA} y ${stringB} no son Anagramas`;\n  }\n}\n// Isograma: es una palabra o frace en la que ninguna letra se repita\nfunction isIsograma(string) {\n  let newString = string.toLowerCase().replace(/[^a-z]/g, \"\");\n  let letters = new Set();\n\n  for (const letter of newString) {\n    if (letters.has(letter)) {\n      return `${string} no es un Isograma`;\n    }\n    letters.add(letter);\n  }\n  return `${string} es un Isograma`;\n}\n\nconsole.log(isPalindromo(\"radar\"));\nconsole.log(isAnagrama(\"amors\", \"roma\"));\nconsole.log(isIsograma(\"isogramas\"));\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/DannyMarperOne.js",
    "content": "//#04 CADENAS DE CARACTERES\n\n/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\n//CONSTRUCTOR\n\n// ************** string() y new String() *******************\n\n//String() convierte un valor a cadena de texto y lo retorna como un valor primitivo.\nlet numbers = 1234;\nlet cadenaString = String(numbers); // \"1234\"\nconsole.log(typeof cadenaString); //string\n\n//new String() crea un objeto de tipo string, se utiliza como contructor, y devulve un objeto string\nlet numb = 9874;\nlet stringObj = new String(numb); //[String: '9874']\nconsole.log(typeof stringObj); // object\n\n\n\n\n\n// MÉTODOS ESTATICOS\n\n// ******************** String.raw **************************\n\n//Devuleve cadenas en crudo, sin procesar\n\nlet name1 = \"Daniel\";\nlet full = String.raw`Hola\\n${name1}\\\\ como estás \\\"`;\n/* No procesa secuencias de escape (barras invertidas), no da saltos de linea, \nni agrega comillas, todo lo pasa literal. */\nconsole.log(full); //Salida: Hola\\nDaniel\\\\ como estás \\\"\n\n\n\n\n\n//PROPIEDADES\n\n//*************  Longitud = Length  *****************\n\n//Devuelve la longitud de una cadena\n\nlet player = \"Cristiano Ronaldo\"\nlet cr7 = player.length;\n\nconsole.log(cr7) //Salida: 17\nconsole.log('The name ' + player + ' has ' + player.length + ' characters'); //Salida: The name Cristiano Ronaldo has 17 characters\n\n\n\n\n\n//MÉTODOS\n\n//**************  charAt = Acceder a un solo caracter  ****************\n\n//Devuelve el valor de index al que se desea acceder\n\nlet escuderia = \"Ferrari\";\n//Acceder a la posición del caracter\nconsole.log(escuderia.charAt(3)); //Salida: r\n//Acceder al último caracter del string\nconsole.log(escuderia.charAt(escuderia.length - 1)); //Salida: i\n//Si se busca una posición que supere el tamaño del string, devulve cadena vacia.\n\n\n\n//************** concat() ****************\n\n//Ayuda a concatenar o unir variables, cadenas, etc.\n\nlet hello = \"Hello, \";\nconsole.log(hello.concat(\"Kevin\", \". Have a nice day.\")); //Salida: Hello, Kevin. Have a nice day.\n\nlet greetList = [\"Hello\", \" \", \"Venkat\", \"!\"];\nconsole.log(\"\".concat(...greetList)); //Salida: \"Hello Venkat!\"\n\n\"\".concat({}); // [object Object]\n\"\".concat([]); // \"\"\n\"\".concat(null); // \"null\"\n\"\".concat(true); // \"true\"\n\"\".concat(4, 5); // \"45\"\n\n\n\n//************** includes() *************\n\n//Determina si una cadena de texto se encuentra dentro de otra cadena de texto, devolviendo true o false\n\nlet frase = \"El campeon Max Verstappen vs el 7 veces campeon Lewis Hamilton\"\nlet piloto = \"Max\";\n\nconsole.log(`La palabra ${piloto} ${frase.includes(piloto) ? 'si' : 'no'} está dentro de la frase principal!`); //Devuelve si o no\nconsole.log(`La palabra ${piloto} ${frase.includes(piloto)} está dentro de la frase principal!`); //Devulve true o false\nconsole.log(`La palabra ${piloto} ${frase.includes(piloto, 12)} está dentro de la frase principal!`); //Busca apartir de la posición 12 de la cadena (False)\n\n\n\n//*************** startsWith() ************* */\n\n//Determina si una cadena de texto inicia con los caracteres de una cadena indicada, devolviendo true o false\n\nlet fraseFour = \"Arriba el futbol de Monterrey\"\nconsole.log(`La primera palabra de la frase es Monterrey? ${fraseFour.startsWith('Arriba') ? 'SI' : 'NO'}`);\nconsole.log(`La última palabra de la frase es Monterrey? ${fraseFour.startsWith('Arriba', 3) ? 'SI' : 'NO'}`);\n\n//Ejemplo\nlet palabraStarsWith = \"Tengo frio ahorita mismo. Mañana no creo.\";\nlet iniciaCon = palabraStarsWith.startsWith(\"Ten\");\nlet inciciaCon2 = palabraStarsWith.startsWith(\"Ten\", 1);\nconsole.log(iniciaCon);\nconsole.log(inciciaCon2);\n//Toma en cuenta los puntos finales\nlet puntoFinal = palabraStarsWith.startsWith(\"Ma\", 26);\nconsole.log(puntoFinal);\n\n\n\n//*************** endsWhith() ************* */\n\n//Determina si una cadena de texto termina con los caracteres de una cadena indicada, devolviendo true o false\n\nlet fraseTwo = \"Arriba el futbol de Monterrey\"\nconsole.log(`La última palabra de la frase es Monterrey? ${fraseTwo.endsWith('Monterrey') ? 'SI' : 'NO'}`); //Determina la última palabra del string\nconsole.log(`La última palabra de la frase es Monterrey? ${fraseTwo.endsWith('Monterrey', 3) ? 'SI' : 'NO'}`); //La posición de busqueda va de cualquier posición hacia atras\n\n\n\n//*************** indexOf() y lastIndexOf() ************* */\n\n//indexOf() Encuentra la primera ocurrencia de una subcadena (o carácter) dentro de una cadena. Va de izquierda a derecha.\n\n//lastIndexOf() Encuentra la última ocurrencia de una subcadena (o carácter) dentro de una cadena o la primera ocurrencia llendo de derecha a izquierda.\n\nlet cadena = \"MasterClassEnds\";\n\nconsole.log(cadena.indexOf(\"m\")); //Salida: -1 (no encontrará la posición de 'm' porque indexOf es sencible a Mayusculas)\nconsole.log(cadena.indexOf(\"M\")); //Salida: 0\nconsole.log(cadena.indexOf(\"r\")); //Salida: 5 (indexOf busca el primer caracter de izquierda a derecha)\nconsole.log(cadena.lastIndexOf(\"a\")); //Salida: 8 (lasIndexOf busca el primer caracter pero de derecha a izquierda)\n\n//Ejemplo\nlet cuenta = 0;\nlet posicion = cadena.indexOf(\"s\"); //2\nwhile (posicion != -1) {\n    cuenta++;//1,2,3,4\n    posicion = cadena.indexOf(\"s\", posicion + 1); // 9(3), 10(10), 14(11) -1(15)\n}\nconsole.log(cuenta); //Salida: 4 (En si porque solo existen 4 's' dentro del string entonces la iteración fue de 4)\nconsole.log(posicion); //Salida: -1 (Cuando ya no encontra más posiciones en el string retorna -1)\n\n\n\n// ********************* localeCompare() *******************\n\n//Sirve para hacer comparaciones entre cadenas de texto dependiento el alfabeto\n\nlet palabra1 = \"manzana\";\nlet palabra2 = \"banana\";\n\nlet resultado = palabra2.localeCompare(palabra1);\nconsole.log(resultado); //Salida: -1\nlet resultado2 = palabra1.localeCompare(palabra2);\nconsole.log(resultado2); //Salida: 1\n/* Nota: entiendo que la cadena que está antes del localCompare es el dato a comparar, \ny este manda si el resultado es -1,1 o 0 (Si va antes de lo que está entre parentesis o después) */\n\n//Ejemplo\nlet nombres = [\"Pedro\", \"Ana\", \"Juan\"];\nnombres.sort((a, b) => a.localeCompare(b)); //Ocupamos sort para ordenar un arreglo y con localCompare le decimos que lo ordene alfabeticamente.\nconsole.log(nombres);\n\n//Se puede especificar el idioma en el que se requiere hacer la comparación\nconsole.log(\"ä\".localeCompare(\"z\", \"de\")); // un valor negativo: en alemán, ä se ordena antes que z\nconsole.log(\"ä\".localeCompare(\"z\", \"sv\")); // un valor positivo: en sueco, ä se ordena después que z\n\n\n\n// ************************ Secuencias de escape o Notación de escape ****************************\n\n/*\nEstas notaciones permiten incluir caracteres que de otro modo serían difíciles de escribir o \nque podrían causar problemas en la interpretación del código. \nLas notaciones de escape comienzan con una barra invertida (\\), seguida de un carácter que indica el tipo de escape. \n */\n\nlet saludar = \"Hola \\n Daniel como estás \\'Amigo\\' \\nMi nombre es \\\\ Gloria \\\\ \\\"Cabeza de Bolo\\\" Jejejej \\r y tu? \\v tabulacion vertical \\t jejjeej \\f ijijjiji \\ud83d\";\nconsole.log(saludar);\n\n// Cadenas literales largas\nlet adios = \"Adios amigo \\\nme tengo que ir \\\nmañana debo de trabajar\"; //Adios amigo me tengo que ir mañana debo de trabajar\n\nlet bye = \"Adios amigo\" +\n    \"me tengo que ir\" +\n    \"mañana debo de trabajar\"; //Adios amigo me tengo que ir mañana debo de trabajar\n\n\n\n// ******************** String.fromCharCode() ********************************\n\n// Devuelve una cadena creada de valores Unicode.\n\nconsole.log(String.fromCharCode(65, 69, 67)); //Salida: AEC\n\n\n\n// **************** .match() ***************\n\n//Devuelve un array que contiene todas las coincidencias encontradas dentro de un string apartir de una Expresion Regula\n\nlet fraseThree = \"Hola mi nombre es Optimus Prime, comandante de los 'Autobots'\"\nconst expresionReg = /[A-Z]/g;\nlet resultMatch = fraseThree.match(expresionReg); //devuelve todas (/g) las mayusculas de la A-Z \nconsole.log(resultMatch);\n\nconst expresionReg2 = /[A-Z]/;\nlet resultMatch2 = fraseThree.match(expresionReg2); //devuelve la primer mayuscula entre la A-Z, su index, el input y el grupo\nconsole.log(resultMatch2)\n\n\n\n// ***************** padEnd() ****************\n\n//Este metodo rellena un string con el string que nosotros proporciones colocando el index en el maxlenght que deseemos\n\nlet phraseEnd = \"Esta frase termina con * apartir de aqui \";\nlet padExample = phraseEnd.padEnd(55, \"*\");\nconsole.log(padExample);\n//Si el maxLength es menor o igual al string, devolverá el string tal cual fue declarado.\nconsole.log(phraseEnd.padEnd(10, \"Repeat\"));\n// Si solo se coloca el maxLength sin el fillString como resultado por defecto es rellenar las posiciones con \" \".\nconsole.log(phraseEnd.padEnd(60));\nconsole.log(phraseEnd.padEnd(60, \"Repeat\"));\n\n\n\n// ***************** padStart() ****************\n\n//Este metodo rellena un string con el string que nosotros proporciones colocando el index en el maxlenght que deseemos\n//pero rellenará desde el principio del string original\n\n//las condiciones de uso son las mismas que las de padEnd()\nlet phraseStart = \"Esta frase empieza con *.\";\nconsole.log(phraseStart.padStart(40, \"*\"));\n\n\n\n// ***************** repeat() ****************\n\n//Repite un string la cantidad de veces necesarias (Solo numeros enteros)\n\nconsole.log(\"hola\".repeat(10)); //holaholaholaholaholaholaholaholaholahola\nconsole.log(\"hola\".repeat(10)); // RangeError\nconsole.log(\"abc\".repeat(0)); // ''\n\n\n\n// ***************** replace() ****************\n\n//Cualquier cosa que no sea un texto o un regex, este lo convierte en string\n\n// Reemplaza un string completo, buscando una coincidencia y cambiandola por otro string\nconsole.log(\"viva mexico cabrones\".replace(\"cabrones\", \"******\"));\n//Se pueden utilizar expresiones regulares\nlet expRegReplace = /comer/i;\nconsole.log(\"Es hora de ir a comer\".replace(expRegReplace, \"Dormir\"));\n\n// Ejemplo\nconst re = /apples/gi;\nconst str = \"Apples are round, and apples are juicy.\";\nconst newstr = str.replace(re, \"oranges\");\nconsole.log(newstr); // orange are round, and oranges are juicy.\n\n// Ejemplo\nconst ree = /(\\w+)\\s(\\w+)/;\nconst stre = \"Maria Cruz\";\nconst newstre = stre.replace(ree, \"$2, $1\");\nconsole.log(newstre); // Cruz, Maria\n\n//Ejemplo: Uso de parametros match, p1, offset, string\nfunction replacer(match, p1, offset, string) {\n    console.log(`match: ${match}`); // La coincidencia completa\n    console.log(`p1: ${p1}`); // El primer grupo de captura\n    console.log(`offset: ${offset}`); // La posición en la cadena donde se encuentra la coincidencia\n    console.log(`string: ${string}`); // La cadena original completa\n    return p1.toUpperCase(); // Ejemplo de transformación\n}\nconst regex = /(\\w+)\\s/;\nconst strr = \"Hello world!\";\nconst newStr = strr.replace(regex, replacer);\nconsole.log(newStr);\n\n//Ejemplo: Remplace con RegEx\nfunction f2c(x) {\n    function convert(str, p1, offset, s) {\n        return `${((p1 - 32) * 5) / 9}C`;\n    }\n    const s = String(x);\n    const test = /(-?\\d+(?:\\.\\d*)?)F\\b/ig;\n    return s.replace(test, convert);\n}\nconsole.log(f2c(\"En mexico estamos a 100F y en alaska estan a -3f\"));\n\n//Ejemplo\nconsole.log(\"bc abcd abcssssss sas\".replace(/(bc)/, (match, p1, offset) => `${match} (${offset}) -`));\n\n//Ejemplo Dificil\nfunction addOffset(match, ...args) {\n    const hasNamedGroups = typeof args.at(-1) === \"object\";\n    const offset = hasNamedGroups ? args.at(-3) : args.at(-2);\n    return `${match} (${offset}) `;\n}\nconsole.log(\"abcd\".replace(/(bc)/, addOffset)); // \"abc (1) d\"\n\n\n\n// ***************** replaceAll() ****************\n\n//Basicamente hace lo mismo que remplace() pero en lugar de remplazar un solo valor, este remplaza todas las ocurrencias.\n//Cuando se utliza con RegEx es necesario que este último lleve el valor global (g) ya que de lo contrario marcará error.\n\n\n\n// ***************** search() ****************\n\n//Busca una ocurrencia respecto a una expresión regular. (Solo funciona con expreciones regulares)\n\nfunction testinput(re, str) {\n    var midstring;\n    if (str.search(re) != -1) {\n        midstring = \" contains \";\n    } else {\n        midstring = \" does not contain \";\n    }\n    console.log(str + midstring + re);\n}\n/* let exp = /\\hola/g;\nlet text = \"hola a todos, hola.\";\ntestinput(exp, text); */\n\ntestinput(/\\hola/g, \"hola a todos, hola.\");\n\n\n\n// ***************** slice() ****************\n\n//Extrae un trozo de una cadena, eligiendo desde que indice de inicio hasta el indice final, y crea una nueva cadena.\n//desde el inicio se cuenta desde el indice 0 y el final desde el indice -1\n\nvar cadena1 = \"La mañana se nos echa encima.\";\nvar cadena2 = cadena1.slice(3, -4);\nconsole.log(cadena2); // retorna 'mañana se nos echa enc'\n\nvar cad = \"La mañana se nos echa encima.\";\ncad.slice(-3); // retorna 'ma.'\ncad.slice(-3, -1); // retorna 'ma'\ncad.slice(0, -1); // retorna 'La mañana se nos echa encima'\n\n/* \nslice(startIndex, endIndex): Extrae desde startIndex hasta endIndex, pero sin incluir endIndex.\nslice(startIndex): Extrae desde startIndex hasta el final de la cadena.\nÍndices negativos: Los índices negativos cuentan desde el final de la cadena hacia atrás. \n*/\n\n\n\n// ***************** split() ****************\n\n//Delvuelve un arreglo apartir de una cadena. Donde encuentre el separador, ahí delimita un elemento del arreglo.\n\n//Ejemplo\nfunction dividirCadena(cadenaADividir, separador) {\n    var arrayDeCadenas = cadenaADividir.split(separador);\n    console.log('<p>La cadena original es: \"' + cadenaADividir + '\"');\n    console.log('<br>El separador es: \"' + separador + '\"');\n    console.log(\"<br>El array tiene \" + arrayDeCadenas.length + \" elementos: \",);\n\n    for (var i = 0; i < arrayDeCadenas.length; i++) {\n        console.log(arrayDeCadenas[i] + \" / \");\n    }\n}\n\nvar cadenaVerso = \"Oh brave new world that has such people in it.\";\nvar cadenaMeses = \"Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec\";\n\nvar espacio = \" \"; //donde encuentre espacio separa\nvar coma = \",\"; //donde encuentre una coma separa\n\ndividirCadena(cadenaVerso, espacio);\ndividirCadena(cadenaVerso);\ndividirCadena(cadenaMeses, coma);\n\n/*\nLa cadena original es: \"Oh brave new world that has such people in it.\"\nEl separador es: \" \"\nEl array tiene 10 elementos: Oh / brave / new / world / that / has / such / people / in / it. /\n\nLa cadena original es: \"Oh brave new world that has such people in it.\"\nEl separador es: \"undefined\"\nEl array tiene 1 elementos: Oh brave new world that has such people in it. /\n\nLa cadena original es: \"Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec\"\nEl separador es: \",\"\nEl array tiene 12 elementos: Jan / Feb / Mar / Apr / May / Jun / Jul / Aug / Sep / Oct / Nov / Dec /\n*/\n\n//Ejemplo\nfunction slplitCadena(cadenita, separadores) {\n    let pruebaSplit = cadenita.split(separadores);\n    console.log(pruebaSplit);\n    console.log(pruebaSplit.length);\n}\n\nlet cadenaSp = \"Hola, muchas gracias, por estar aqui, bye.\"\nlet sepa = \",\";\n\nslplitCadena(cadenaSp, sepa);\n\n//Ejemplo\nvar strt = \"asdfghjkl\"; // Original string\nvar strReverse = strt.split(\"\") // Step 1: Split into characters\n    .reverse() // Step 2: Reverse the array\n    .join(\"\"); // Step 3: Join the characters into a string\n\nconsole.log(strReverse); // Output: \"lkjhgfdsa\"\n\n\n\n// ***************** substring() ****************\n\n//Devuleve un subconjunto de cadena apartir de el indice de inicio e indice fin.\n//Si el indice final es mayor al indice inicial, substring lo invierte (el indice menor siempre lo toma como indice a)\n\nvar cualquierCadena = \"Mozilla\";\n\n// Muestra \"Moz\"\nconsole.log(cualquierCadena.substring(0, 3));\nconsole.log(cualquierCadena.substring(3, 0));\n// Muestra \"lla\"\nconsole.log(cualquierCadena.substring(4, 7));\nconsole.log(cualquierCadena.substring(7, 4));\n// Muestra \"Mozill\"\nconsole.log(cualquierCadena.substring(0, 6));\nconsole.log(cualquierCadena.substring(6, 0));\n//Devuelve cadena vacia porque el indiceA es igual al indiceB\nconsole.log(cualquierCadena.substring(1, 1));\n//Devuelve desde el indiceA hasta el length de la cadena. Ya queno se asigna indiceB\nconsole.log(cualquierCadena.substring(1));\n\n//Ejemplo\nfunction reemplazarCadena(cadenaVieja, cadenaNueva, cadenaCompleta) {\n    // Reemplaza cadenaVieja por cadenaNueva en cadenaCompleta\n\n    for (var i = 0; i < cadenaCompleta.length; i++) {\n        if (cadenaCompleta.substring(i, i + cadenaVieja.length) == cadenaVieja) {\n            cadenaCompleta =\n                cadenaCompleta.substring(0, i) +\n                cadenaNueva +\n                cadenaCompleta.substring(i + cadenaVieja.length, cadenaCompleta.length); //retorna cadena vacia\n        }\n    }\n    console.log(cadenaCompleta)\n    return cadenaCompleta;\n}\nreemplazarCadena(\"Mundo\", \"Web\", \"Bravo Nuevo Mundo\");\n\n\n\n// ***************** toLowerCase() ****************\n\n//Si una cadena contiene caracteres en mayusculas, este método lo devulve en minusculas\n\nlet ejemploLowerUpperCase = \"HOLA A TODOS mi nombre es Daniel\";\nconsole.log(ejemploLowerUpperCase.toLowerCase()); //hola a todos mi nombre es daniel\n\n\n\n// ***************** toUpperCase() ****************\n\n//Si una cadena contiene caracteres en minusculas, este método lo devulve en mayusculas\n\nconsole.log(ejemploLowerUpperCase.toUpperCase());\n\n\n\n// ***************** toString() ****************\n\n// Es utilizado para convertir un objeto a su representación en forma de cadena de texto.\n\nlet tex = \"Hola\"\nconsole.log(tex.toString); //\"Hola\"\nlet num = 123;\nconsole.log(num.toString); //\"123\"\nlet arr = [1, 2, 3, 4, 5];\nconsole.log(arr.toString()); // \"1,2,3,4,5\"\nlet obj = { a: 1, b: 2 };\nconsole.log(obj.toString()); // \"[object Object]\"\n\n//Ejemplo\nfunction Perro(nombre, criadero, color, sexo) {\n    this.nombre = nombre;\n    this.criadero = criadero;\n    this.color = color;\n    this.sexo = sexo;\n}\n\nlet elPerro = new Perro(\"Gabby\", \"Laboratorio\", \"chocolate\", \"femenino\");\nPerro.prototype.toString = function perroToString() {\n    var retorno = `El perro ${this.nombre} es del sexo ${this.sexo}, tiene un color ${this.color} y fue criado en un ${this.criadero}`;\n    return console.log(retorno);\n};\n\nconsole.log(elPerro.toString());\n// El perro Gabby es del sexo femenino, tiene un color chocolate y fue criado en un Laboratorio          undefined\n\n\n\n// ***************** trim() ****************\n\n//Elimina los espacios de ambos extremos de una cadena\nlet ejemploTrim = \"       Cadena de ejemplo con trim       \"\nconsole.log(ejemploTrim.trim());\n\n//Ejemplo\nlet jaja = `Elimina los espacios de ejemlo trim, ${ejemploTrim.trim()}, al final tambien lo elimina.`;\nconsole.log(jaja);\n\n\n\n// ***************** trimStart() ****************\n\n//Elimina los espacios que estén solo al inicio de una cadena\nconsole.log(ejemploTrim.trimStart());\n\n\n\n// ***************** trimEnd() ****************\n\n//Elimina los espacios que estén solo al final de una cadena\nconsole.log(ejemploTrim.trimEnd());\n\n\n\n// ***************** valueOf() ****************\n\n//Delvuelve el valor primitivo de un objeto string\n\ncadena = new String(\"Hello world\");\nconsole.log(cadena.valueOf()); // Displays \"Hello world\"\n\n//Practicamente con las cadenas de texto es lo mismo que colocar\nconsole.log(cadena.toString());\n\n\n\n// ******************* [Symbol.iterator](); *******************\n\n/* \nLa propiedad [Symbol.iterator] permite definir el comportamiento de iteración de un objeto. \nCuando un objeto tiene una propiedad [Symbol.iterator], puede ser utilizado en contextos que esperan un iterable, \ncomo en los bucles for...of, el operador de propagación (...), y métodos como Array.from.\n*/\n\nconst strg = \"The quick red fox jumped over the lazy dog's back.\";\n\nconst iterator = strg[Symbol.iterator]();\nlet theChar = iterator.next();\n\nwhile (!theChar.done && theChar.value !== '') {\n    console.log(theChar.value);\n    theChar = iterator.next();\n    // Expected output: \"T\"\n    //                  \"h\"\n    //                  \"e\"\n}\n\n//Ejemplo Manual\nconst strig = \"Daniel Martinez\";\nconst strIter = strig[Symbol.iterator]();\n\nconsole.log(strIter.next().value); // \"D\"\nconsole.log(strIter.next().value); // \"a\"\nconsole.log(strIter.next().value); // \"n\"\n\n\n/* \nDIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas \n * */\n\n// Palindromos\nfunction palindromo(firstWord) {\n    let deleteSpace = firstWord.toLowerCase().split(' ').join('');\n    let arrayWord = Array.from(deleteSpace).toReversed().join('');\n    let result = arrayWord === deleteSpace ? `${firstWord} es un palindromo` : `${firstWord} no es un palindromo`;\n    console.log(result);\n}\npalindromo(\"ANITA LAVA LA TINA\");\n\n// Anagramas\nfunction anagrama(secondWord, thirdWord) {\n    let arraySecondWord = secondWord.split('').sort((a, b) => a.localeCompare(b));\n    arraySecondWord = arraySecondWord.join('').toLowerCase();\n    let arrayThirWord = thirdWord.split('').sort((a, b) => a.localeCompare(b));\n    arrayThirWord = arrayThirWord.join('').toLowerCase();\n    let result = arraySecondWord === arrayThirWord\n        ? `La palabras ${secondWord} y ${thirdWord}, son anagramas`\n        : `La palabras ${secondWord} y ${thirdWord}, no son anagramas`;\n    console.log(result);\n}\nanagrama(\"Daniel\", \"DANIEL\");\n\n// Isogramas\nfunction isograma(fourthWord) {\n    let arrayIsograma = fourthWord.toLowerCase().split('').join('');\n    let textSet = new Set(arrayIsograma);\n\n    const array = [];\n    textSet.forEach(v => array.push(v));\n    let emptyArray = array.join('');\n    if (arrayIsograma === emptyArray) {\n        console.log(`${fourthWord} es un Isograma`);\n    } else {\n        console.log(`${fourthWord} no es un Isograma`);\n    }\n}\nisograma(\"Murcielago\");\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/DavidMoralesDeveloper.js",
    "content": "// 1 Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n//  * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n\nconsole.log(\"cadena basica\");\n//concatenaión\nconst string = \"JavaScript\";\nconst string2 = \"ola k ace\";\nconsole.log(string + \" espacio \" + string2);\n//interpolación\nconsole.log(\n  `ESC6 una manera moderna de concatenar ${string} junto a ${string2}`\n);\n\n// Propiedades de string pagina oficial: https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/String/replace\n\n// Repetir\nconsole.log(string.repeat(3));\n\n// Indexación\nconsole.log(string[1] + string2[0]);\n\n//Longitud\nconsole.log(string.length);\n\n// Slice (porcion o rebanada)\nconst frase = \"soy una frase muy corta\";\nconsole.log(frase.slice(3, 10));\n\n//Busqueda\nconsole.log(string2.includes(\"k\"));\nconsole.log(\n  `el meme ola k ace incluye la palabra: ace =  ${\n    string2.includes(\"ace\") ? \", si lo inclue\" : \", no lo incluye\"\n  } `\n);\nconsole.log(\n  `el meme ola k ace incluye la palabra: hace = ${\n    string2.includes(\"hace\") ? \", si lo inclue\" : \", no lo incluye\"\n  } `\n);\n\n// #remplazo\nconsole.log(string2.replace(\"ace\", \"hace\"));\n\n// Division\nlet separadorArr = string.split(\"S\");\nconsole.log(separadorArr + \" split JavaScript\"); //[ 'Java', 'cript' ]\n\n//Union\n\nconsole.log(separadorArr.join(\"S\") + \" join propiedad\"); //JavaScript join propiedad\n\n//Mayusculas y minusculas\nconsole.log(string.toLocaleLowerCase());\nconsole.log(string.toLocaleUpperCase());\nconsole.log(string.toLowerCase());\nconsole.log(string.toUpperCase());\n//Primera Mayus\nconsole.log(string.charAt(0).toUpperCase() + string.slice(1));\nconsole.log(string[0].toUpperCase() + string.slice(1));\n\n//eliminación de espacios\nconsole.log(string2.trim()); // no funciona pero que investigar\nlet unido = string2.split(\" \");\nconsole.log(unido);\nconsole.log(unido.join(\"-\"));\n\n//Budqueda  al principio y final\n// inicio\nconsole.log(string.startsWith(\"Ja\")); //true\nconsole.log(string.startsWith(\"Scr\")); //false\n//final\nconsole.log(string.endsWith(\"ipt\")); //true\nconsole.log(string.endsWith(\"Jav\")); //false\n\n//Busqueda de pisición\nconsole.log(string2.search(\"ace\")); //6\n\n// de string a un array\nlet lista1 = string2.split(\"\");\nconsole.log(lista1); // ['o', 'l', 'a', ' ', 'k', ' ', 'a', 'c', 'e']\nconsole.log(lista1.join(\"\")); // ola k ace\n\n//trasfomacion numerico\n\nlet numeros = \"123456\";\nlet numerosDecimal = \"123.456\";\nconsole.log(typeof numeros); //string\nconsole.log(typeof parseInt(numeros)); //number\nconsole.log(parseFloat(numerosDecimal)); //numeros decimales\nconsole.log(parseInt(numeros)); //numeros enteros\n\n//Extra ------------------------------------------------\n\n// Crea un programa que analice dos palabras diferentes y realice comprobaciones\n//  * para descubrir si son:\n//  * - Palíndromos\n//  * - Anagramas\n//  * - Isogramas\n\n//funcion la cual analiza dos palabras\n\nfunction analitic(word1, word2) {\n  // el primer analicis seria si se lee al derecho y al reves y es estrictamente igual\n\n  //   Palíndromos\n  word1.split(\"\").reverse().join(\"\") === word1\n    ? console.log(`${word1} :es un palindromo`)\n    : console.log(`${word1} :no es un palindromo `);\n  word2.split(\"\").reverse().join(\"\") === word2\n    ? console.log(`${word2} :es un palindromo`)\n    : console.log(`${word2} :no es un palindromo `);\n\n  //   Anagrama\n  word1.split(\"\").sort().join() == word2.split(\"\").sort().join()\n    ? console.log(` ${word1} es anagrama de ${word2}  `)\n    : console.log(` ${word1} no es anagrama de ${word2} `);\n\n  //   Isograma\n  //isograma de primer orden se repiten todas las palabras una sala vez\n\n  //creo funcion de isograma\n  function isograma (word){\n    const wordArray = word.split(\"\");\n    const wordSet = new Set(wordArray);\n    if (wordArray.length === wordSet.size) {\n        // console.log(wordArray)\n        // console.log(wordSet)\n        // console.log(true)\n       return true\n    } else {\n        // console.log(wordArray)\n        // console.log(wordSet)\n        // console.log(false)\n       return false\n    }\n  }\n //EJECUTO FUNCION de isograma\n  isograma(word1) ? console.log(` ${word1} es un isograma de primer orde`) : console.log(` ${word1} no es un isograma de primer orde`)\n  isograma(word2) ? console.log(` ${word2} es un isograma de primer orde`) : console.log(` ${word2} no es un isograma de primer orde`)\n\n//   isograma de multinivel queda pendiendiente , espero resolverlo pronto\n\n\n\n} //final de funcion analitic\n\nanalitic(\"ana\", \"ala\");\nanalitic(\"roma\", \"amor\");\nanalitic('murcielago', 'ambiente')\n\n\n\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/Deyvid-10.js",
    "content": "// operaciones que se pueden realizar con cadenas de caracteres\n\nlet string = \"La vida es un viaje de autodescubrimiento, atrévete a explorar.\"\n\nconsole.log(string.charAt(3)); //Acceso a caracteres específicos\nconsole.log(string[3]); // Acceso a caracteres específicos\nconsole.log(string.substring(3, 9)); // Subcadena que imprime una parte de la cadena\nconsole.log(string.substring(3)); // Subcadena que imprime desde el indice indicado en adelante\nconsole.log(string.slice(-9, -1)); // Subcadena que imprime una parte de la cadena, permite valores negativos para acceder a los caracteres del final del string\nconsole.log(string.slice(-9)); // Subcadena que imprime desde el indice indicado en adelante, permite valores negativos para acceder a los caracteres del final del string\nconsole.log(string.length); // Conocer la longitud\nconsole.log(string + \" Anaïs Nin\"); // Concatenación\nconsole.log(string, \" Anaïs Nin\"); // Concatenación\nconsole.log(`${string} Anaïs Nin`); // Concatenación\nconsole.log(string.concat(\" \", \"Anaïs Nin\")); // Concatenación\nconsole.log(string.repeat(3)); //Repetición\nconsole.log(string.toUpperCase()); // Conversión a mayúscula\nconsole.log(string.toLowerCase()); // conversión a minúsculas\nconsole.log(string.replace(\"autodescubrimiento\", \"descubrimiento\")); // Reemplazo\nlet division = string.split(\" \") // División\nconsole.log(division); \nconsole.log(division.join(\" \")); // Union\nconsole.log(string.includes(\"vida\")); // Buscar cadenas\nconsole.log(string.search(\"vida\")); // Buscar en que indice esta la palabra\nconsole.log(string.indexOf(\"v\")); // Buscar indice de un caracter\nconsole.log(string.startsWith(\"La\")); // Buscar el inicio de una cadena\nconsole.log(string.endsWith(\"explorar.\")); // Buscar el final de una cadena\nconsole.log(string.endsWith(\"explorar.\")); // Buscar el final de una cadena\nconsole.log(typeof(string)); // Saber el tipo de dato\n\n\n// DIFICULTAD EXTRA\nfunction palindromos(palindromo)\n{\n    let arraypalindromo = palindromo.split(\"\")\n    let arrayReverso = arraypalindromo.reverse()\n    let palindromoReverso = arrayReverso.join(\"\")\n    if(palindromoReverso.toLocaleLowerCase() == palindromo.toLocaleLowerCase())\n    {\n        console.log(\"Esta palabra es un palíndromo\");\n    }\n    else\n    {\n        console.log(\"Esta palabra no es un palíndromo\");\n    }\n}\npalindromos(\"radar\")\n\nfunction anagramas(palabra1, palabra2)\n{\n    console.log(palabra1.toLowerCase().split(\"\").sort().join(\"\"));\n    console.log(palabra2.toLowerCase().split(\"\").sort().join(\"\"));\n    if(palabra1.toLowerCase().split(\"\").sort().join(\"\") == palabra2.toLowerCase().split(\"\").sort().join(\"\"))\n    {\n        console.log(\"Esto es un anagrama\");\n    }\n    else\n    {\n        console.log(\"Esto no es un anagrama\");\n    }\n}\nanagramas(\"amor\", \"roma\")\n\nfunction isogramas(isograma)\n{\n    let noIsograma = true\n    let conteoPalabra = {}\n\n    for (let i of isograma.toLowerCase()) {\n    \n        if(!(Object.keys(conteoPalabra).includes(i)))\n        {\n            conteoPalabra[i] = 0\n        }\n\n        conteoPalabra[i] += 1\n    }\n\n    let claves = Object.keys(conteoPalabra)\n \n    for(let c in conteoPalabra)\n    {\n        if(conteoPalabra[claves[0]] != conteoPalabra[c])\n        {\n            noIsograma = false\n        }\n    }\n\n    return noIsograma\n}\n\nconsole.log(isogramas(\"palopalopalo\") ? \"Es un isograma\" : \"No es un isograma\");"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/DjSurgeon.js",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\n *   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\n *   interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\n// Operaciones con cadenas\nlet string = \"Hola mundo!\";\n\n// Encontrar la longitud de una cadena *.length\n\nconsole.log(string.length); // Devuelve 11 incluye espacios y simbolos.\n\n// Extraer un caracter de la cadena. Para ello utilizaremos la notación del punto *.[n]\n\nconsole.log(string[0]); // Devuelve \"H\"\nconsole.log(string[string.length - 1]); // Devuelve \"!\"\n\n// Encontrar una subcadena dentro de una cadena y extraerla *.indexOf()\n// Como parametro utilizaremos la cadena a buscar y el resultado sera -1 si no se encuentra la cadena, y si se encuentra el numero n a partir de donde empieza la cadena.\n\nconsole.log(string.indexOf(\"mundo\")); // Devuelve 5\nconsole.log(string[5]); // Devuelve \"m\"\nconsole.log(string.indexOf(\"world\")); // Devuelve -1\n\n// Si sabes donde comienza una subcadena dentro de una cadena y sabes hasta cuál caracter deseas que termina puede usarse *.slice().\n// Recibe dos parametrosel primero es la posicion en la que comienza a extraer el caracter y el segundo la posicion del caracter posterior al ultimo a ser extraido.\n\nconsole.log(string.slice(5, 10)); // Devuelve \"mundo\"\nconsole.log(string.slice(8, string.length)); // Devuelve \"do!\"\n// El segundo parametro es opcional, si no se añade el corte termina al final de la cadena original\nconsole.log(string.slice(5)); // Devuelve \"mundo!\"\nconsole.log(string.slice(2)); // Devuelve \"la mundo!\"\n\n// Cambiar todo a mayuscula o todo a minuscula *.toLowerCase() y *.toUpperCase()\n\nconsole.log(string.toLowerCase()); // Devuelve \"hola mundo!\"\nconsole.log(string.toUpperCase()); // Devuelve \"HOLA MUNDO!\"\n\n// Actualizar partes de una cadena *.replace()\n\nconsole.log(string.replace(\"Hola\", \"Hello\")); // Devuelve \"Hello mundo!\"\n\n// Combinar cadenas *.concat()\n\nconsole.log(string.concat(\", \", \"Hello\")); // Devuelve \"Hola mundo!, Hello\"\n\n// Dividir cadenas *.split()\n// El paremetro es el elemento separador de la cadena\n\nconsole.log(string.split(\" \")); // Devuelve [ 'Hola', 'mundo!' ]\nconsole.log(string.split(\"\")); // Devuelve [  'H', 'o', 'l', 'a',' ', 'm', 'u', 'n','d', 'o', '!']\nconsole.log(string.split(\"-\")); // Devuelve [ 'Hola mundo!' ]\n\n//Buscar un valor dentro de la cadena *.includes()\n\nconsole.log(string.includes(\"mundo\")); // Devuelve true\nconsole.log(string.includes(\"world\")); // Devuelve false\n\n// Eliminar los espacios en blanco al principio y final de una cadena\n\nlet string2 = \"        Hello  World!    \";\nconsole.log(string2.trim()); // Devuelve \"Hello  World!\"\n\n// Extra =======\n/* Un palíndromo es un término o una expresión que puede leerse tanto de izquierda a derecha como de derecha a izquierda (es decir, expresa lo mismo al ser leído de manera tradicional o al revés).\n */\n\nconst isPalindromo = (string) => {\n  let element1 = string.toLowerCase().trim().split(\" \").join(\"\"); // almacenamos en la variable la cadena en minuscula y sin huecos a los lados y eliminamos los huecos entremedia y lo volvemos a juntar\n  let element2 = element1.split(\"\").slice().reverse().join(\"\"); // Hacemos una copia de la string y le damos la vuelta\n\n  if (element1 === element2) {\n    console.log(`${string} es palindromo.`);\n  } else {\n    console.log(`${string} no es palindromo.`);\n  }\n};\n\nisPalindromo(\"as$sa\");\nisPalindromo(\"12jeja85\");\n\n/* \nUn anagrama es una palabra que resulta de la transposición de todas las letras de otra palabra. Dicho de otra forma, una palabra es anagrama de otra si las dos tienen las mismas letras, con el mismo número de apariciones, pero en un orden diferente. Esto se aplica también a grupos de palabras o frases.\n*/\n\nconst isAnagrama = (string1, string2) => {\n  let element1 = string1.toLowerCase().trim();\n  let element2 = string2.toLowerCase().trim();\n  if (element1.length === element2.length) {\n    element3 = element1.split(\"\").sort().join(\"\");\n    element4 = element2.split(\"\").sort().join(\"\");\n    if (element3 === element4) {\n      console.log(`${element1} y ${element2} son anagramas.`);\n    } else {\n      console.log(`${element1} y ${element2} no son anagramas.`);\n    }\n  } else {\n    console.log(`${element1} y ${element2} no son anagramas.`);\n  }\n};\n\nisAnagrama(\"Nacionalista\", \"Altisonancia\");\nisAnagrama(\"Seudo\", \"Sesudo\");\n\n/* \nEn morfología y juego verbal , un isograma es una palabra sin letras repetidas (como ambidestro ) o, más ampliamente, una palabra en la que las letras aparecen el mismo número de veces.\n*/\n\nconst isIsograma = (string) => {\n\n  let element1 = string.toLowerCase().trim();\n  let set1 = new Set()\n\n  for(let letra of element1) {\n    if(set1.has(letra)) {\n      return console.log(`${string}, no es un isograma.`)\n    }\n    else {\n      set1.add(letra);\n    }\n  }\nreturn console.log(`${string} es un isograma.`)\n\n}\n\nisIsograma(\"bilabial\");\nisIsograma(\"ambidestro\");\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/DobleDJ.js",
    "content": "/**\n * Reto de programación #04 - javaScript\n * Autor: Yoandy Doble Herrera\n * Fecha: 15/12/2024\n */\n\n/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\nlet cadenaTexto = \"Esta es una cadena de texto. \"\nlet otraCadena = `Esta es una cadena de texto literal. By codebydoble`\n\n/* Búsqueda */\nconst mensajeTry = \"Utilizaré este ejemplo para el Roadmap.\"\n\nconsole.log(\"Buscar con includes en la cadena return un boolean: \", mensajeTry.includes(\"este\")) // true\nconsole.log(\"Buscar con indexOF en la cadena return un boolean: \", mensajeTry.indexOf(\"ejemplo\")) // 15\nconsole.log(\"Buscar con indexOF en la cadena return un boolean: \", mensajeTry.indexOf(\"javascript\")) // -1\nconsole.log(\"Buscar con endWith en la cadena return un boolean: \", otraCadena.endsWith(\"doble\"))\nconsole.log(\"Buscar con starWith en la cadena return un boolean: \", cadenaTexto.startsWith(\"doble\"))\nconsole.log(\"Buscar con includes en la cadena return un boolean: \", cadenaTexto.includes(\"una\"))\n\n/* Interpolación  */\nlet nombre = \"Yoandy\"\nlet oracion = `Este reto de programacion es realizado por: ${nombre} \\n`\n\n/* Acceso a elementos */\nconsole.log(\"Acceso a elemento por index -chartAt-: \", otraCadena.charAt(3), \"\\n\")\nconsole.log(\"Acceso a elemento por index: \", cadenaTexto[1], \"\\n\")\nconsole.log(\"Acceso a elemento por index devuelve Code: \", cadenaTexto.charCodeAt(5), \"\\n\")\n\n/* Subcadena */\nlet subcadenaTexto = cadenaTexto.split(\" \")\nconsole.log(\"Subcadenas de texto: \", subcadenaTexto, \"\\n\")\n\nlet sliceText = cadenaTexto.slice(3, 10)\nconsole.log(\"Slice texto: \", sliceText, \"\\n\")\n\nlet tinyText = cadenaTexto.match(\"es una\")\nconsole.log(\"Subcadenas de texto: \", tinyText, \"\\n\")\n\n/* Longitud */\nconsole.log(\"Longitud de la cadena: \", otraCadena.length, \"\\n\")\n\n/* Concatenación */\nlet paragraph = cadenaTexto.concat(otraCadena)\nconsole.log(\"Concatenación de string -concat-: \", paragraph, \"\\n\")\n\n/* Unión */\nlet otraConcatenacion = cadenaTexto + otraCadena\nconsole.log(\"Concatenación de string: \", otraConcatenacion, \"\\n\")\n\nlet unJoin = \"\"\nunJoin += cadenaTexto\nunJoin += otraCadena\nconsole.log(\"Join de string: \", unJoin, \"\\n\")\n\n/* repetición */\nlet textoRepetido = cadenaTexto.repeat(2)\nconsole.log(\"Cadena repetida 2 veces: \", textoRepetido, \"\\n\")\n\n/* conversión a mayúsculas y minúsculas */\nconsole.log(\"Conversión a mayúsculas: \", cadenaTexto.toUpperCase(), \"\\n\")\n\nconsole.log(\"Conversión a minúsculas: \", cadenaTexto.toLowerCase(), \"\\n\")\n\n/* Reemplazo */\nlet textoSimple = \"javaScript es un lenguaje de programación. Retos de programación by mouredev\"\nlet replaceText = textoSimple.replace(\"by\", \"por\")\nlet replaceTextAll = textoSimple.replaceAll(\"a\", \"@\")\n\nconsole.log(\"Texto original: \", textoSimple, \"\\n\")\n\nconsole.log(\"Texto de reemplazo: \", replaceText, \"\\n\")\n\nconsole.log(\"Texto de reemplazo todos los resultados: \", replaceTextAll, \"\\n\")\n\n/* recorrido */\nlet message = \"Este es un mensaje en un string\"\n\nfor (let index = 0; index < message.length; index++) {\n  console.log(message[index])\n}\n\n/* DIFICULTAD EXTRA (opcional):\n Crea un programa que analice dos palabras diferentes y realice comprobaciones para descubrir si son:\n - [] Palíndromos\n - [] Anagramas\n - [] Isogramas\n*/\n\n/**\n * Reverse a string\n * @param {string} word Any string word with symbols, spaces and string\n * @returns Returns reversed string word\n */\nconst reverseManual = (word) => word.split(\"\").reverse().join(\"\")\n\n/**\n * Extrae las palabras únicas de un string\n * @param {string} word Any string word\n */\nconst palabrasUnicas = (word) => {\n  //TODO al string realizar .split agregarlo a un Set retornarlo a string y si es igual no tiene palabras repetidas\n  return Array.from(new Set(word.split(\"\"))).join(\"\")\n}\n\n/**\n * Determine if two words are palindromes\n * @param {string} firstWord Any string word\n * @param {string} secondWord Any string word\n * @returns Returns a boolean response true or false\n */\nconst palindromeTester = (firstWord, secondWord) => {\n  //TODO reversed secondWord check firstWord\n  return firstWord.toLowerCase() === reverseManual(secondWord).toLowerCase()\n}\n\n/**\n * Determine if a word is an isogram\n * @param {string} word Any string word\n * @returns {boolean} Returns true if the word is an isogram, false otherwise\n */\nconst esIsograma = (word) => {\n  return word === palabrasUnicas(word)\n}\n\n/**\n * Determine if two words are isograms\n * @param {string} firstWord Any string word\n * @param {string} secondWord Any string word\n * @returns {boolean} Returns true if both words are isograms, false otherwise\n */\nconst isogramaTester = (firstWord, secondWord) => {\n  const firstIsIsogram = esIsograma(firstWord)\n  const secondIsIsogram = esIsograma(secondWord)\n\n  console.log(`La palabra ${firstWord} ${firstIsIsogram ? \"es\" : \"no es\"} un isograma`)\n  console.log(`La palabra ${secondWord} ${secondIsIsogram ? \"es\" : \"no es\"} un isograma`)\n\n  return firstIsIsogram && secondIsIsogram\n}\n\n/**\n * Determine if two words are anagrams\n * @param {string} firstWord Any string word\n * @param {string} secondWord Any string word\n * @returns {boolean} Returns true if both words are anagrams, false otherwise\n */\nconst anagramaTester = (firstWord, secondWord) => {\n  const normalize = (word) => word.toLowerCase().replace(/\\s+/g, \"\").split(\"\").sort().join(\"\")\n  return normalize(firstWord) === normalize(secondWord)\n}\n\nfunction textAnalizer(firstWord, secondWord) {\n  const firstIsIsogram = esIsograma(firstWord)\n  const secondIsIsogram = esIsograma(secondWord)\n\n  if (palindromeTester(firstWord, secondWord)) {\n    console.log(\"Las palabras son palíndromes\")\n  } else {\n    console.log(\"Las palabras no son palíndromes\")\n  }\n\n  if (anagramaTester(firstWord, secondWord)) {\n    console.log(\"Las palabras son anagramas\")\n  } else {\n    console.log(\"Las palabras no son anagramas\")\n  }\n  console.log(`La palabra ${firstWord} ${firstIsIsogram ? \"es\" : \"no es\"} un isograma`)\n  console.log(`La palabra ${secondWord} ${secondIsIsogram ? \"es\" : \"no es\"} un isograma`)\n}\n\ntextAnalizer(\"Listen\", \"silent\")\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/DouglasDiazR.js",
    "content": "/*STRING */\n\nconst string = \"Hola soy un string\";\nconst string2 = \"También soy un string\";\nconst string3 = `   Ésto tambien\" es 'una cadena'       `;\n\nconsole.log(string3.length); // Devuelve la longitud del string\n\nconst text = \"Hola Mundo\";\nconsole.log(text.charAt(1)); //Devuelve el caracter específicado con el índice de su posición\nconsole.log(text.at(0)); //Devuelve el caracter específicado con el índice de su posición\n\nconsole.log(text[5]); // Acceso a un caracter específico\n\nconsole.log(string3.slice(1, 13)); // extrae una parte de una cadena y devuelve una nueva.\nconsole.log(string3.substring(6, 13));\n\nconsole.log(string.toUpperCase()); //convierte la cadena a mayúsculas\nconsole.log(string.toLowerCase()); //convierte la cadena a minúsculas\n\nconsole.log(string3.trim()); // elimina los espacios en blanco al principio y final de la cadena\nconsole.log(string3.trimStart()); // elimina los espacios en blanco al principio de la cadena\nconsole.log(string3.trimEnd()); // elimina los espacios en blanco al final de la cadena\n\nconsole.log(string.includes(\"string\")); //devuelve true si una cadena contiene un valor especificado\n\nconsole.log(string3.indexOf(\"a\")); //devuelve el indice del primer caracter que coincida con el indicado. Devuelve -1 si no encuenta coincidencia\nconsole.log(string3.lastIndexOf(\"a\")); //devuelve el indice del último caracter que coincida con el indicado\n\nconsole.log(string.repeat(4)); // repite el string\n\nconsole.log(string.replace(\"Hola\", \"Chao\")); // método reemplaza un valor especificado con otro valor en una cadena\nconsole.log(string.replace(/n/g, \"x\"));\n\nconsole.log(string.split(\" \")); //Convierte un string en un array\n\nconsole.log(string3.match(\"en\")); //devuelve un array con los resultados de hacer coincidir una cadena con otra cadena\n\nconsole.log(string2.startsWith(\"Tam\")); //retorna true si una cadena comienza con un valor especificado.\nconsole.log(string.endsWith(\"g\")); //retorna true si una cadena termina con un valor especificado.\n\n/*PALÍNDROMOS*/\n\nconst isPalindromo = (palabra) => {\n  const palabra2 = palabra.toLowerCase().split(\"\").reverse();\n  palabra.toLowerCase() === palabra2.join(\"\")\n    ? console.log(\"Es Palíndromo\")\n    : console.log(\"No es Palíndromo\");\n};\n\nisPalindromo(\"arepera\");\n\nconst isAnagrama = (palabra1, palabra2) => {\n  if (\n    palabra1.toLowerCase().split(\"\").sort().join(\"\") ===\n    palabra2.toLowerCase().split(\"\").sort().join(\"\")\n  )\n    console.log(\"Son anagramas\");\n  else console.log(\"No son Anagramas\");\n};\nisAnagrama(\"Aroma\", \"amaro\");\n\nconst isIsograma = (palabra) => {\n  const palabraArray = palabra.toLowerCase().split(\"\");\n  const palabraset = new Set(palabra.toLowerCase());\n  palabraArray.length === palabraset.size\n    ? console.log(\"Es Isograma\")\n    : console.log(\"No es Isograma\");\n};\n\nisIsograma(\"murcielago\");\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/FabianRpv.js",
    "content": "// Cadena de Caracteres\n\nlet cadena = \"Hola Mundo \";\nconsole.log(cadena);\n\n// Acceso a caracteres especificos\n\nconsole.log(cadena[0]); // H\n\n// Subcadenas\n\nconsole.log(cadena.substring(0, 5)); // Hola\nconsole.log(cadena.slice(-5)); // Mundo\n\n// Longitud\n\nconsole.log(cadena.length); // 10\n\n// Concatenación\n\nlet cadena2 = \"desde JavaScript\";\nconsole.log(cadena + cadena2); // Hola Mundo desde JavaScript\n\n// Repetición\n\nconsole.log(cadena.repeat(3)); // Hola Mundo Hola Mundo Hola Mundo\n\n// Recorrido\n\nfor (let i = 0; i < cadena.length; i++) {\n  console.log(cadena[i]);\n}\n\n// Conversion a mayusculas y minusculas\n\nconsole.log(cadena.toUpperCase()); // HOLA MUNDO\nconsole.log(cadena.toLowerCase()); // hola mundo\n\n// Reemplazo\n\nconsole.log(cadena.replace(\"Mundo\", \"Fabian\")); // Hola Fabian\n\n// Division \n\nconsole.log(cadena.split(\" \")); // [\"Hola\", \"Mundo\"]\n\n// Union \n\nconsole.log(cadena.split(\" \").join(\" \")); // Hola Mundo\n\n// Interpolación\n\nconsole.log(`Hola ${cadena2}`); // Hola desde JavaScript\n\n// Verificacion \n\nconsole.log(cadena.includes(\"Hola\")); // true\nconsole.log(cadena.startsWith(\"Hola\")); // true\nconsole.log(cadena.endsWith(\"Mundo \")); // true\n\n// Eliminacion de espacios en blanco\n\nconsole.log(cadena.trim()); // Hola Mundo\n\n// Busqueda de indice\n\nconsole.log(cadena.indexOf(\"Mundo\")); // 5\nconsole.log(cadena.lastIndexOf(\"o\")); // 9\n\n/*\nCrea un programa que analice dos palabras diferentes y realice comprobaciones para descubrir si son:\n- Palíndromos\n- Anagramas\n- Isogramas\n*/\n\nlet palabra1 = \"Amor\";\nlet palabra2 = \"Roma\";\n\n// Palindromo\n\nconst palindromo = palabra => {\n    let palabraInvertida = palabra.toLowerCase().split(\"\").reverse().join(\"\");\n    return palabra.toLowerCase() === palabraInvertida;\n}\n\nconsole.log(`Es palindromo: ${palindromo(palabra1)}`);\nconsole.log(`Es palindromo: ${palindromo(palabra2)}`);\n\n// Anagrama\n\nconst anagrama = (palabra1, palabra2) => {\n    return palabra1.toLowerCase().split('').sort().join('') === palabra2.toLowerCase().split('').sort().join('');\n}\n\nconsole.log(`Es anagrama: ${anagrama(palabra1, palabra2)}`);\n\n// Isograma\n\nconst isograma = palabra => {\n    let palabraArray = palabra.toLowerCase().split(\"\");\n    let palabraSet = new Set(palabraArray);\n    return palabraArray.length === palabraSet.size;\n}\n\nconsole.log(`Es isograma: ${isograma(palabra1)}`);\nconsole.log(`Es isograma: ${isograma(palabra2)}`);"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/Facundo-Muoio.js",
    "content": "//operacines con cadenas de caracteres\n//concatenar cadenas\nconsole.log(\"hola\" + \" mundo!\");\nconsole.log(\"Hola \".concat(\"mundo!\"));\n\n// ver el lenght de las cadeans de caracteristicas\nlet str = \"soy un string\";\nconsole.log(str.length);\n\n// acceder a un caracter específico del  string\nconsole.log(str[0]);\n\n// acceder a una porción del string\nconsole.log(str.slice(0, 6));\nconsole.log(str.substring(0, 6));\n\n// formatear todo el string a uppercase.\nconsole.log(str.toUpperCase());\n\n// formatear todo el string a lowercase\nlet upper = \"UPPERCASE\";\nconsole.log(upper.toLowerCase());\n\n// separa los caracteres segun un separador que pasamos como argumento y te devulte un arreglo con los caracteres de los subtrings producidos.\nconsole.log(str.split(\"\"));\n\n// reemplaza el string o expresion regular que pasamos por el string que pasamos por segundo argumento\nconsole.log(str.replace(\"s\", \"f\"));\n\n// elimina todos los caracteres de espacios en blanco iniciales y finales dentro de un string\nstr = \" Mauricio    Perez  \";\nconsole.log(str.trim());\n\n// devuelve true si el string que pasamos esta includi en la cadean de texto en la cual aplicamos el método\nconsole.log(str.includes(\"Mauricio\"));\n\n// devuelve el caracter en la posicion que indicamos como argumento del método\nconsole.log(str.charAt(0));\n\n// devulve el indice del primer caracter que coicide con el caracter que pasamos en el método.\nconsole.log(str.indexOf(\"i\"));\n\n// devuelve todas las coicidencias de una expresión regular dentro de un arreglo.\nconsole.log(str.match(/[A-Z]/));\n\n// devuelve un booleano chequeando si la cadena de texto comienza con los caracteres que pasamos como argumento\nconsole.log(str.startsWith(\" Maur\"));\n\n// devuelve un nuevo string con el mismo repetido el número de veces que pasamos por agumento\nconsole.log(\"hola\".repeat(2));\n\n// Actividad Extra :\nfunction chekcString(str1, str2) {\n\tstr1 = str1.toLowerCase();\n\tstr2 = str2.toLowerCase();\n\n\tlet palindromo = [];\n\tlet anagrama;\n\tlet isogram = [];\n\n\t// vemos si la palabra es un palíndromo\n\tstr1.split(\"\").reverse().join(\"\") === str1\n\t\t? (palindromo[0] = true)\n\t\t: (palindromo[0] = false);\n\tstr2.split(\"\").reverse().join(\"\") === str2\n\t\t? (palindromo[1] = true)\n\t\t: (palindromo[1] = false);\n\n\t// vemos si la palabra es un anagrama\n\tstr1.split(\"\").sort().join() === str2.split(\"\").sort().join()\n\t\t? (anagrama = true)\n\t\t: (anagrama = false);\n\n\t//vemos si una palabra es un isograma\n\n\tfunction verifyIsogram(str) {\n\t\tlet obj = {};\n\t\tlet isogram = true;\n\n\t\tfor (let letter of str.toLowerCase()) {\n\t\t\tobj[letter] ? obj[letter]++ : (obj[letter] = 1);\n\t\t}\n\n\t\tconst arr = Object.values(obj);\n\t\tarr.forEach(e => {\n\t\t\te != arr[0] ? (isogram = false) : \"\";\n\t\t});\n\n\t\treturn isogram;\n\t}\n\n\tisogram[0] = verifyIsogram(str1);\n\tisogram[1] = verifyIsogram(str2);\n\n\treturn { palindromo, anagrama, isogram };\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/Glitzypanic.js",
    "content": "// CADENA DE CARACTERES\nvar cadena = \"Hola Mundo\"; // Comillas simples\nvar cadena2 = \"Hola Mundo\"; // Comillas dobles\n\nvar nombre = \"Jose\";\nvar cadena = `Hola ${nombre}`; // Comillas invertidas\n\nvar nombre = \"Jose\";\nvar apellido = \"Perez\";\n\nvar cadena1 = nombre + \" \" + apellido;\nconsole.log(cadena1); // Jose Perez\n\n// Metodos de las cadenas\nvar cadena = \"Hola Mundo\";\nconsole.log(cadena.length); // 10\nconsole.log(cadena.repeat(3)); // Hola MundoHola MundoHola Mundo\nconsole.log(cadena.replace(\"Hola\", \"Hello\")); // Hello Mundo\nconsole.log(cadena.charAt[2]); // l\n\nfor (var i = 0; i < cadena.length; i++) {\n  console.log(cadena[i]);\n}\n\n// Convertir a mayusculas y minusculas\nconsole.log(cadena.toUpperCase()); // HOLA MUNDO\nconsole.log(cadena.toLowerCase()); // hola mundo\n\nconsole.log(cadena.indexOf(\"Mundo\")); // 5\nconsole.log(cadena.lastIndexOf(\"o\")); // 7\nconsole.log(cadena.includes(\"Mundo\")); // true\nconsole.log(cadena.substring(0, 4)); // Hola\nconsole.log(cadena.slice(0, 4)); // Hola\n\nvar suma = 1 + 2;\nconsole.log(`El resultado de la suma es ${suma}`); // El resultado de la suma es 3\n\n// EJERCICIO\nfunction comprobarPalabra1(word1, word2) {\n  // Comprobamos si la palabra es un palindromo\n  console.log(\n    word1 +\n      \" es un palíndromo?: \" +\n      (word1 === word1.split(\"\").reverse().join(\"\"))\n  );\n  console.log(\n    word2 +\n      \" es un palindromo?: \" +\n      (word2 === word2.split(\"\").reverse().join(\"\"))\n  );\n\n  // Comprobamos si las palabras son anagramas\n  console.log(\n    word1 +\n      \" y \" +\n      word2 +\n      \" son anagramas?: \" +\n      (word1.split(\"\").sort().join(\"\") === word2.split(\"\").sort().join(\"\"))\n  );\n\n  // Comprohbar si las palabras son isogramas\n  console.log(\n    word1 +\n      \" es un isograma?: \" +\n      (new Set(word1.split(\"\")).size === word1.length)\n  );\n  console.log(\n    word2 +\n      \" es un isograma?: \" +\n      (new Set(word2.split(\"\")).size === word2.length)\n  );\n}\n\ncomprobarPalabra1(\"amor\", \"radar\");\ncomprobarPalabra1(\"roma\", \"amor\");\ncomprobarPalabra1(\"murcielago\", \"repetir\");\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #04 - JavaScript ->Jesus Antonio Escamilla */\n/**\n * Este son los ejemplos de cadenas de caracteres\n */\n\n//---STRING---\nvar cadena = \"Hola, mundo\";\n\nvar primeraCarácter = cadena[0];\nvar segundoCarácter = cadena[cadena.length - 1];\n\nconsole.log(primeraCarácter); // H\nconsole.log(segundoCarácter); // o\n\n\n//---SUB-CADENA---\nvar subcadena = cadena.substring(2,8);\n\nconsole.log(subcadena); // la, mu\n\n\n//---LONGITUD---\nvar longitud = cadena.length;\n\nconsole.log(longitud); // 11\n\n\n//---CONCATENACIÓN---\nvar cadena1 = \"Hola mundo,\";\nvar cadena2 = \" Jesus Antonio\";\n\nconsole.log(cadena1 + cadena2); // Hola mundo, Jesus Antonio\n\n\n//---REPETICIÓN---\nvar repetido = cadena.repeat(4);\n\nconsole.log(repetido); // Hola, mundoHola, mundo,Hola mundoHola, mundo\n\n\n//---MAYÚSCULAS & MINÚSCULAS---\nvar mayusculas = cadena.toLocaleUpperCase();\nvar misnusculas = cadena.toLocaleLowerCase();\n\nconsole.log(mayusculas); //HOLA, MUNDO\nconsole.log(misnusculas); //hola, mundo\n\n\n//---REMPLAZO---\nvar nuevaCadena = cadena.replace(\"mundo\", \"Mexico\");\n\nconsole.log(nuevaCadena); // Hola, Mexico\n\n\n//---DIVISION---\nvar palabra = cadena.split(\", \");\n\nconsole.log(palabra); // ['Hola', 'mundo']\n\n\n//---UNION---\nvar listaPalabras = [\"Hola\", \"mundo\"];\nvar nuevaCadena1 = listaPalabras.join(', ');\n\nconsole.log(nuevaCadena1); // Hola, mundo\n\n\n//---INTERPOLACIÓN---\nvar nombre = \"Jesus Antonio\";\nvar edad = 24;\nvar saludos = `Hola, me llamo ${nombre} y tengo ${edad} años.`;\n\nconsole.log(saludos); // Hola, me llamo Jesus Antonio y tengo 24 años.\n\n\n//---VERIFICACIÓN---\nif (cadena.includes(\"Hola\")) {\n    console.log(\"La cadena contiene 'Hola'\"); // La cadena contiene 'Hola'\n}\n\n\n\n/**-----DIFICULTAD EXTRA-----*/\nconsole.log(\"----------Palindromo----------\");\n\nfunction palindromo(palabra1) {\n    const palabraInvectiva = palabra1.split('').reverse().join('');\n    if(palabraInvectiva === palabra1){\n        console.log(`La palabra ${palabra1}, si es un palindromo y es ${palabraInvectiva}`);\n    }else{\n        console.log(`La palabra ${palabra1}, no es un palindromo`);\n    }\n}\npalindromo(\"reconocer\");\npalindromo(\"mundo\");\n\n\nconsole.log(\"----------Anagrama----------\");\n\nfunction anagrama(palabra2, palabra3) {;\n\n    const palabraProcesada = palabra2.split('').sort().join('');\n    const palabraProcesada1 = palabra3.split('').sort().join('');\n\n    if (palabraProcesada === palabraProcesada1) {\n        console.log(`La palabra ${palabra2}, si es un anagrama y su anagrama es ${palabra3}`);\n    } else {\n        console.log(`La palabra ${palabra2} y la palabra ${palabra3},  no son anagramas`);\n    }\n}\n\nanagrama(\"amar\", \"rama\");\nanagrama(\"lápiz\", \"goma\");\n\n\nconsole.log(\"----------Isograma----------\");\n\nfunction isograma(palabra4) {\n    const letrasEncontradas = {};\n    for (const letra of palabra4) {\n        if (letrasEncontradas[letra]) {\n            console.log(`La palabra ${palabra4}, no es un isograma`);\n            return false;\n        }else{\n            letrasEncontradas[letra] = true;\n        }\n    }\n    console.log(`La palabra ${palabra4}, si es un isograma`);\n    return true;\n}\n\nisograma(\"murciélago\");\nisograma(\"programador\");\n/**-----DIFICULTAD EXTRA-----*/\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/Joanfv-git.js",
    "content": "//Operaciones de cadenas de caracteres\n//Concatenar\nlet cadena1 = \"Hola\";\nlet cadena2 = \"Mundo\";\nlet concatenacion = cadena1 + \" \" + cadena2;\nconsole.log(concatenacion);\n//Longitud\nconsole.log(concatenacion.length);\n//Mayusculas\nconsole.log(concatenacion.toUpperCase());\n//Minusculas\nconsole.log(concatenacion.toLowerCase());\n//Extraer una parte de la cadena\nconsole.log(concatenacion.substring(0, 4));\n//Dividir una cadena en un array\nconsole.log(concatenacion.split(\" \"));\n//Reemplazar parte de una cadena\nconsole.log(concatenacion.replace(\"Mundo\", \"World\"));\n//Buscar una cadena en otra\nconsole.log(concatenacion.includes(\"Hola\"));\n//Comparar cadenas\nlet cadena3 = \"Hola Mundo\";\nconsole.log(concatenacion === cadena3);\n//Extraer un caracter\nconsole.log(concatenacion.charAt(0));\n//Buscar la posición de un caracter\nconsole.log(concatenacion.indexOf(\"M\"));\n//Comparar cadenas sin importar mayúsculas o minúsculas\nconsole.log(concatenacion.toUpperCase() === cadena3.toUpperCase());\n//Eliminar espacios en blanco al principio y al final\nlet cadena4 = \" Hola Mundo \";\nconsole.log(cadena4.trim());\n//Extraer una parte de la cadena\nconsole.log(concatenacion.slice(0, 4));\n//Extraer una parte de la cadena y reemplazarla\nconsole.log(concatenacion.slice(0, 4).replace(\"H\", \"J\"));\n\n//Ejercicio extra\nlet primeraPalabra = prompt(\"Introduce una palabra\");\nlet segundaPalabra = prompt(\"Introduce una palabra\");\n\n//Comprobar si son palindromas\nif (primeraPalabra === segundaPalabra.split(\"\").reverse().join(\"\")) {\n  console.log(\"Las palabras son palindromas\");\n} else {\n  console.log(\"Las palabras no son palindromas\");\n}\n//Comprobar si son anagramas\nif (\n  primeraPalabra.split(\"\").sort().join(\"\") ===\n  segundaPalabra.split(\"\").sort().join(\"\")\n) {\n  console.log(\"Las palabras son anagramas\");\n} else {\n  console.log(\"Las palabras no son anagramas\");\n}\n\n//Comprobar si son isogramas\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/JoseAndresGC.js",
    "content": "// cadenas de texto\n// metodos de cadenas de texto\n\nlet str = \"Banana\";\nlet my_name = \"Andrés\";\nconsole.log(my_name);\n\n// Acceso a caracteres específicos\n\nconsole.log(my_name.charAt(0)); // \"A\"\nconsole.log(my_name.charAt(100)); // \"\" si está fuera de rango devuelve una cadena vacía\n\nconsole.log(my_name.at(0), my_name.at(1), my_name.at(2));  // [\"A\", \"n\", \"d\"]\nconsole.log(my_name.at(200)); // undefined ... si está fuera de rango devuelve undefined\nconsole.log(my_name.at(-1)); // s ... acepta valores negativos. En indices negativos se representa -1 como la ultima letra o posicion de la cadena\n\n// subcadenas\n\nconsole.log(my_name.substring()) // Andrés .substring(inicio, fin) Si no se especifica el fin devuelve toda la cadena\nconsole.log(my_name.substring(1, 4)) // \"ndr\"\n\nconsole.log(my_name.slice(-5, -1)); // \"ndré\" .slice(inicio, fin) Funciona parecido a substring, pero acepta valores negativos.\nconsole.log(my_name.slice(500)); // \"\"\nconsole.log(my_name.slice(0)); // \"Andrés\"\n\n// longitud\n\nconsole.log(my_name.length); // 6\n\n// búsqueda\n\nconsole.log(str.match(/a/g)); // busca de manera global por la cadena y separa en un array todas las coindidencias [\"a\",\"a\",\"a\"]\nconsole.log(str.match(/[an]/g)); // para buscar más de una letra usar [] [\"a\", \"n\", \"a\", \"n\", \"a\"]\n\nconsole.log(my_name.search(\"A\")); // 0 devuelve la posición de la primera coincidencia\nconsole.log(my_name.search(\"z\")); // -1 si no encuentra la letra devuelve -1\n\nconsole.log(my_name.indexOf(\"A\")); // 0 devuelve la posición de la primera coincidencia\nconsole.log(my_name.indexOf(\"z\")); // -1 si no encuentra la letra devuelve -1\n\n// concatenación\n\nconsole.log(my_name + ' ' + str); // \"Andrés Banana\" con operador +\n\nconsole.log(my_name.concat(' ', str)); // \"Andrés Banana\" .concat(str1, str2,  ...)\n\nconsole.log(`José ${my_name} ${str} con backticks`); // \"José Andrés Banana\" con el metodo de los backstick. Se pueden concatenar variables y variables directamente en la cadena de texto\n\n// repetición\n\nconsole.log(my_name.repeat(3)); // \"AndrésAndrésAndrés\" .repeat(n) repite la cadena n veces\n\n// recorrido\n\nconsole.log(my_name.endsWith(\"s\")); // true ...verifica si la cadena termina con el caracter especificado\nconsole.log(my_name.startsWith(\"A\")); // true ...verifica si la cadena comienza con el caracter especificado \nconsole.log(my_name.includes(\"n\")); // true ...verifica si la cadena contiene el caracter especificado \n\n// conversion a mayusculas y minusculas\n\nconsole.log(my_name.toUpperCase()); // \"ANDRÉS\" convierte la cadena de texto a mayúsculas\nconsole.log(my_name.toLowerCase()); // \"andrés\" convierte la cadena de texto en minúsculas\n\n// reemplazo\n\nconsole.log(my_name.replace(\"A\", \"a\")); // \"andrés\" reemplaza la primera coincidencia\nconsole.log(my_name.replace(/A/g, \"a\")); // \"andrés\" reemplaza todas las coincidencias\n\nlet str2 = \"Hola, Hola mundo, Hola a todos\";\nconsole.log(str2.replaceAll(\"Hola\", \"Chao\")); // \n\n// división\n\nconsole.log(my_name.split(\"\")); // [\"A\", \"n\", \"d\", \"r\", \"é\", \"s\"] Divide la cadena de texto en un array de caracteres equivalente a la cadena original\n\n// interpolación\n\nconsole.log(`\n    Hola! Mi nombre es ${my_name}\n    Y esto es un ejemplo de interpolación de cadenas de texto`);\n\n// DIFICULTAD EXTRA:\n\nlet word1 = \"Zorra\";\nlet word2 = \"Arroz\";\nlet word3 = \"Background\";\nlet word4 = \"Mary\";\nlet word5 = \"Army\";\n\nfunction isPalindrom() { // palabras que se leen igual de izquierda a derecha que de derecha a izquierda\n    let _word1 = word1.toLowerCase().split(\"\").reverse().join(\"\");\n    let _word2 = word2.toLowerCase();\n    \n    return _word1 === _word2 ? true : false;\n    \n}\n\nfunction isAnagram() { // palabras que tienen las mismas letras pero en diferente orden\n    let _word4 = word4.toLowerCase().split(\"\").sort().join(\"\");\n    return _word4 === word5.toLowerCase().split(\"\").sort().join(\"\") ? true : false;\n}\n\nfunction isIsogram() { // palabras que o frases que no tienen letras repetidas\n\n    let _word3 = word3.toLowerCase().split(\"\").sort().join(\"\");\n    let _word3Set = new Set(_word3);\n\n    return _word3.length === _word3Set.size ? true : false;\n}\n\nconsole.log(`Las palabras ${word1} y ${word2} son Palíndromos? : ${isPalindrom()}`);\n\nconsole.log(`Las palabras ${word4} y ${word5} son Anagramas? : ${isAnagram()}`);\n\nconsole.log(`La palabra ${word3} es un Isograma? : ${isIsogram()}`);"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/JuSeRDev.js",
    "content": "let saludo = \"Hola!\"\nlet lenguaje = \"JavaScript\"\n\nlet saludar = saludo + \" \"+ lenguaje\nconsole.log(saludar);\n\nconsole.log(saludar.length)\n\nconsole.log(saludar[0])\nconsole.log(saludar[1])\nconsole.log(saludar[2])\nconsole.log(saludar[3])\nconsole.log(saludar[4])\nconsole.log(saludar[5])\nconsole.log(saludar[6])\nconsole.log(saludar[7])\nconsole.log(saludar[8])\nconsole.log(saludar[9])\nconsole.log(saludar[10])\nconsole.log(saludar[11])\nconsole.log(saludar[12])\nconsole.log(saludar[13])\nconsole.log(saludar[14])\nconsole.log(saludar[15])\n\n\nlet extraccion = saludar.substring(0,10)\nconsole.log(extraccion)\n\nlet extraccion2 = saludar.slice(-16,-5)\nconsole.log(extraccion2);\n\n\n\n\n\n// const confirmacion = (palabra, palabra2)=>{\n//     let invertido = \"\"\n//     let invertido2 = \"\"\n//     for (let i =  palabra.length -1; i >= 0 ; i--) {\n//         invertido += palabra[i]\n//     }\n//     for (let i =  palabra2.length -1; i >= 0 ; i--) {\n//         invertido2 += palabra2[i]\n//     }\n//     if (invertido === palabra) {\n//         console.log(`la palabra: ${palabra} es un Palindromo`)\n//     } else {\n//         console.log(`la palabra: ${palabra} no es un Palindromo`)\n//     }\n//     if (invertido2 === palabra2) {\n//         console.log(`la palabra: ${palabra2} es un Palindromo`)\n//     } else {\n//         console.log(`la palabra: ${palabra2} no es un Palindromo`)\n//     }\n// }\n\n// confirmacion(\"casa\", \"lateleletal\")\n\n// const confirmacion = (palabra1, palabra2)=>{\n//      //seprala la palabra en caracteres convirtiendolo en un array, luego lo pone alrevez y luego lo vuelve a unir en una cadena de texto\n//     let invertido1 = palabra1.split(\"\").reverse().join(\"\")\n//     let invertido2 = palabra2.split(\"\").reverse().join(\"\")\n//     if (palabra1 === invertido1) {\n//         console.log(`la plabra ${palabra1} es un Palindromo`)\n//     } else {\n//         console.log(`La palabra ${palabra1} no es un Palindromo`)\n//     }\n//     if (palabra2 === invertido2) {\n//         console.log(`la plabra ${palabra2} es un Palindromo`)\n//     } else {\n//         console.log(`La palabra ${palabra2} no es un Palindromo`)\n//     }\n    \n// }\n// confirmacion(\"casa\", \"oso\")\n\n\n\nconst invertirPalabra = (palabra)=> palabra.split(\"\").reverse().join(\"\")\nconst esPalindromo = (palabra) =>{\n    const invertida = invertirPalabra(palabra)\n    if (invertida === palabra) {\n        return `la palabra: \"${palabra}\" es un palindromo`\n    } else{\n        return `la palabra \"${palabra}\" no es un palindromo`\n    }\n}\n\nconst esAnagrama = (opcion1, opcion2)=>{\n    let separacion1 = opcion1.split(\"\").sort()\n    let separacion2 = opcion2.split(\"\").sort()\n    console.log(separacion1)\n    console.log(separacion2)\n    if (separacion1.length === separacion2.length && separacion1.join(\"\") === separacion2.join(\"\")) {\n        return `la palabras 1: ${opcion1} y 2: ${opcion2} son un anagrama`\n    } else{\n        return `la palabras 1: \"${opcion1}\" y 2: \"${opcion2}\" no son un anagrama`\n    }\n}\n\nconst esIsograma = (palabra1, palabra2)=>{\n    let isograma = new Set();\n    (palabra1 + palabra2).split(\"\").forEach(letra => isograma.add(letra))\n    if (isograma.size === (palabra1.length + palabra2.length)) {\n        console.log(\"si\");\n        return `Las palabras \"${palabra1}\" y \"${palabra2}\" son isogramas`\n    } else {\n        console.log(\"no\");\n        \n        return `Las palabras \"${palabra1}\" y \"${palabra2}\" no son isogramas`\n    }\n}\n\nconst confirmacion = (palabra1, palabra2)=>{\n    let resultado = []\n    \n    resultado.push(esPalindromo(palabra1))\n    resultado.push(esPalindromo(palabra2))\n    resultado.push(esAnagrama(palabra1, palabra2))\n    resultado.push(esIsograma(palabra1, palabra2))\n    \n    console.log(esPalindromo(palabra1));\n    console.log(esPalindromo(palabra2));\n    console.log(esAnagrama(palabra1, palabra2))\n    console.log(esIsograma(palabra1, palabra2))\n//<<<<<<< main\n    \n=======\n\n//>>>>>>> main\n    return resultado.join(\"\\n\")\n    \n}\n\nconsole.log(confirmacion(\"casa\", \"oso\"))\n\n//<<<<<<< main\n//=======\nconsole.log(confirmacion(\"perro\", \"lateleletal\"))\n//>>>>>>> main\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/JuanCaicedo1024.js",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\n *   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\n *   interpolación, verificación...\n */\n\n//acceso a caracteres\nvar str = \"Hola mundo\";\n\nstr.charAt(0); // retorna H\nstr[0]; //retorna H\n\n//Subcadenas\n\nstr.slice([0, 2]); // Hol\nstr.substring(0, 4); //Hola\n\n// Longitud de la cadena\nstr.length; //10\n\n//concatenacion\nlet saludo = \"Hola\";\nlet destino = \"mundo\";\n\nconsole.log(saludo + \" \" + destino); //Hola mundo\nconsole.log(`${saludo} ${destino}`); // Hola mundo\n\n//repeticion\n\"JS\".repeat(5); // JS JS JS JS JS\n\n//Recorrido de una cadena\nfor (let i of str) {\n  console.log(i);\n} // H O L A M U N D O\n\n//Conversión a mayúsculas y minúsculas\nstr.toUpperCase; // MAYUSCULAS\nstr.toLowerCase; // minuscula\n\n// Reemplazo de texto\n\nstr.replace(\"mundo\", \"JavaScript\"); // Hola JavaScript\n\n//División de una cadena en un array\n\nlet palabras = str.split(\" \", 1); //Hola\n\n// Unión de un array en una cadena\nconsole.log(str.split(\"\").join(\"-\")); //el split convierte la string en un array pars que la funcion join les inserte \"-\"\n\n//Verificación de contenido\n\nstr.includes(\"Hola\"); // la variable str incluye Hola? dara como resultado un true\nstr.startsWith(\"Mundo\"); // la varaibale str no empieza con la palabra Mundo tonces resultado sera false\nstr.endsWith(\"Mundo\"); // la varaibe str si finaliza con la palabra mundo tonces resultara true\n\n//  Eliminación de espacios en blanco\nlet strConEspacios = \"   Espacios   \";\nconsole.log(strConEspacios.trim()); // \"Espacios\"\nconsole.log(strConEspacios.trimStart()); // \"Espacios   \"\nconsole.log(strConEspacios.trimEnd()); // \"   Espacios\"\n\n//De numero a string\nlet num1 = 10;\nlet cadena = num1.toString();\n\n//Conversión de cadena a número\nlet str = \"123\";\nconsole.log(parseInt(cadenaNumero)); // 123 entero\nconsole.log(parseFloat(\"123.45\")); // 123.45 decimal\n\n//comparacion\n\nconsole.log(\"a\" === \"A\"); //devolvera false\n\n//Reversión de una cadena\n\nconsole.log(str.split(\"\").reverse().join(\"\")); //o d n u m   a l o H\n\n/* DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\nlet palabra1 = \"xdssd\"\nlet palabra2 = \"xdddd\"\n\n\nfunction palindromos(){\n    let reversa1 = palabra1.toLowerCase().split(\"\").reverse().join(\"\")\n    let reversa2 = palabra2.toLowerCase().split(\"\").reverse().join(\"\")\n    \n    if (reversa1 === palabra1.toLowerCase()){\n        console.log(`las palabras ${palabra1} si es palindromos`)\n    } \n    \n    if(reversa2 === palabra2.toLowerCase()){\n        console.log(`la palabra ${palabra2} si es palindromos` )\n    }\n        else {\n        console.log(\"no es palindromo\")\n    }\n    \n    \n}\n\npalindromos()\n\n\nfunction Anagramas (){\n    let Anagramas1 = palabra1.toLowerCase().split(\"\").sort().join(\"\")\n    let Anagramas2 = palabra2.toLowerCase().split(\"\").sort().join(\"\")\n\n    if (Anagramas1 === Anagramas2){\n        console.log(`las palabras ${palabra1, palabra2} son anagramas`)\n    } else {\n        console.log(\"No son anagramas\")\n    }\n}\n\nAnagramas()\n\nfunction Isogramas() {\n    let Isograma1 = palabra1.toLowerCase().split(\"\");\n    let letras = new Set();\n\n    for (let letra of Isograma1) {\n        if (letras.has(letra)) { \n            return \"No es un isograma\";\n        }\n        letras.add(letra); \n    }\n\n    return \"Es un isograma\"; \n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/LauraCastrillonMp.js",
    "content": "// Acceso a caracteres específicos\nlet string = 'Hello World!';\nlet char = string[1]; // 'e'\n\n// Subcadenas\nlet substring = string.substring(0, 5); // 'Hello'\n\n// Longitud\nlet length = string.length; // 12\n\n// Concatenación\nlet concatenated = string + ' How are you?'; // 'Hello World! How are you?'\n\n// Repetición\nlet repeated = string.repeat(3); // 'Hello World!Hello World!Hello World!'\n\n// Recorrido\nfor (let i = 0; i < string.length; i++) {\n    console.log(string[i]);\n}\n\n// Conversión a mayúsculas\nlet upper = string.toUpperCase(); // 'HELLO WORLD!'\n\n// Conversión a minúsculas\nlet lower = string.toLowerCase(); // 'hello world!'\n\n// Reemplazo\nlet replaced = string.replace('World', 'Everyone'); // 'Hello Everyone!'\n\n// División\nlet split = string.split(' '); // ['Hello', 'World!']\n\n// Unión\nlet joined = split.join(', '); // 'Hello, World!'\n\n// Interpolación\nlet name = 'Alice';\nlet interpolated = `Hello, ${name}!`; // 'Hello, Alice!'\n\n// Verificación (includes)\nlet contains = string.includes('World'); // true\n\n\n\n// Ejercicio:\nfunction isPalindrome(word) {\n    return word === word.split('').reverse().join('');\n}\n\nfunction isAnagram(word1, word2) {\n    let normalize = (str) => str.toLowerCase().split('').sort().join('');\n    return normalize(word1) === normalize(word2);\n}\n\nfunction isIsogram(word) {\n    let letters = word.toLowerCase().split('').sort();\n    for (let i = 1; i < letters.length; i++) {\n        if (letters[i] === letters[i - 1]) {\n            return false;\n        }\n    }\n    return true;\n}\n\n// Use the functions\nlet word1 = 'listen';\nlet word2 = 'silent';\n\nconsole.log(`Is \"${word1}\" a palindrome?`, isPalindrome(word1));\nconsole.log(`Is \"${word2}\" a palindrome?`, isPalindrome(word2));\nconsole.log(`Are \"${word1}\" and \"${word2}\" anagrams?`, isAnagram(word1, word2));\nconsole.log(`Is \"${word1}\" an isogram?`, isIsogram(word1));\nconsole.log(`Is \"${word2}\" an isogram?`, isIsogram(word2));"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/MatiTC.js",
    "content": "//Ejemplos de operaciones de cadenas\n\n//1.Acceso a caracteres específicos:\nlet cadena = 'Hola, Mundo!';\nconsole.log(cadena[0]); // Muestra 'H'\n//2.Subcadenas\nlet subcadena = cadena.substring(0, 4);\nconsole.log(subcadena); // Muestra 'Hola'\n//3.Longitud\nconsole.log(cadena.length); // Muestra 12\n//4.Concatenación\nlet otraCadena = 'Adios, Mundo';\nlet concatenada = cadena + ' ' + otraCadena;\nconsole.log(concatenada); // Muestra 'Hola, Mundo! ¡Qué tal!'\n//5.Repetición\nlet repetida = cadena.repeat(2);\nconsole.log(repetida); // Muestra 'Hola, Mundo! Hola, Mundo!'\n//6.Recorrido\nfor (let i = 0; i < cadena.length; i++) {\n  console.log(cadena[i]);\n}\n//7.Conversión a mayúsculas y minúsculas:\nconsole.log(cadena.toUpperCase()); // Muestra 'HOLA, MUNDO!'\nconsole.log(cadena.toLowerCase()); // Muestra 'hola, mundo!'\n//8.Reemplazo\nlet nuevaCadena = cadena.replace('Mundo', 'Universo'); //Remplaza Mundo pór Universo\nconsole.log(nuevaCadena); // Muestra 'Hola, Universo!'\n//9.División\nlet palabras = cadena.split(', '); //Separa palabras\nconsole.log(palabras); // Muestra ['Hola', 'Mundo!']\n//10.Unión\nlet arregloPalabras = ['Hola', 'Mundo!'];\nlet nuevaCadenaUnion = arregloPalabras.join(', ');\nconsole.log(nuevaCadena); // Muestra 'Hola, Mundo!'\n//11.Interpolación\nlet nombre = 'Juan';\nlet saludo = `Hola, ${nombre}!`;\nconsole.log(saludo); // Muestra 'Hola, Juan!'\n//12.Verificación\nlet contieneMundo = cadena.includes('Mundo'); //Muy  utilizada\nconsole.log(contieneMundo); // Muestra true\n//13.Invertir\nlet cadenaInvertida = cadena.split('').reverse().join('');\nconsole.log(cadenaInvertida);\n// DIFICULTAD EXTRA (opcional):\n\n//Palíndromos\nfunction Palindromo(cadena) {\n  let cadenaInvertida = cadena.split('').reverse().join('');\n  if (cadena === cadenaInvertida) {\n    return console.log('Es palindromo');\n  }\n  return console.log('No es palindromo');\n}\n\nPalindromo('oso');\n\n//Anagramas\nfunction Anagramas(palabraUno, palabrasDos) {\n  // Eliminar espacios y convertir a minúsculas para ignorar diferencias de caso y espacios\n  let palabra1Normalizada = palabraUno.toLowerCase().replace(/\\s/g, '');\n  let palabra2Normalizada = palabrasDos.toLowerCase().replace(/\\s/g, '');\n  // Verificar si ambas cadenas tienen la misma longitud\n  if (palabra1Normalizada.length !== palabra2Normalizada.length) {\n    return false;\n  }\n  // Convertir las cadenas a arrays, ordenar los arrays y compararlos\n  let array1 = palabra1Normalizada.split('').sort();\n  let array2 = palabra2Normalizada.split('').sort();\n  if (array1.join('') === array2.join('')) {\n    return console.log('Es anagrama');\n  }\n  return console.log('No es anagrama');\n}\n\nAnagramas('roma', 'amor');\n\n//Isogramas\nfunction Isograma(cadena) {\n  // Eliminar espacios y convertir a minúsculas para ignorar diferencias de caso y espacios\n  let cadenaNormalizada = cadena.toLowerCase().replace(/\\s/g, '');\n\n  // Crear un conjunto para almacenar las letras únicas\n  let letrasUnicas = new Set();\n\n  // Iterar sobre cada letra de la cadena\n  for (let letra of cadenaNormalizada) {\n    // Verificar si la letra ya está en el conjunto\n    if (letrasUnicas.has(letra)) {\n      return console.log('No es isograma'); // La letra se repite, no es un isograma\n    } else {\n      letrasUnicas.add(letra); // Agregar la letra al conjunto\n    }\n  }\n\n  return console.log('El isograma');\n}\n\nIsograma('murciélago');\nIsograma('Hoy es un buen día');\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/MeLlamoOmar.js",
    "content": "const esPalindromo = (t) => {\n  return t.split('').reverse().join('') === t\n    ? `${t} es un palindromo`\n    : `${t} no es un palindromo`;\n};\n\nconst esAnagrama = (t1, t2) => {\n  let esAnagrama;\n  const letrasDeT1 = t1.lenght;\n  const letrasDeT2 = t2.lenght;\n\n  if (letrasDeT1 === letrasDeT2) {\n    esAnagrama = t1.split('').sort().join('') == t2.split('').sort().join('');\n  }\n\n  return esAnagrama\n    ? `${t1} es un anagrama de ${t2}`\n    : `${t1} no es un anagrama de ${t2}`;\n};\n\nconst esIsograma = (t) => {\n  const letras = t.split('').sort();\n  const contador = [];\n  let esIsograma = true;\n  let cap;\n\n  letras.forEach((letra) => {\n    if (contador[letra]) {\n      contador[letra].count++;\n    } else {\n      contador[letra] = {\n        value: letra,\n        count: 1,\n      };\n    }\n  });\n\n  Object.values(contador).forEach((letra, i) => {\n    if (i === 0) {\n      cap = letra.count;\n    }\n\n    if (letra.count != cap) {\n      esIsograma = false;\n    }\n  });\n\n  return esIsograma ? `${t} es un Isograma` : `${t} no es un Isograma`;\n};\n\nconst analisisPalabras = (t1, t2) => {\n  const t1Palindromo = esPalindromo(t1);\n  const t2Palindromo = esPalindromo(t2);\n\n  console.log(t1Palindromo, t2Palindromo);\n\n  const anagrama = esAnagrama(t1, t2);\n\n  console.log(anagrama);\n\n  console.log(esIsograma(t1));\n  console.log(esIsograma(t2));\n};\n\nanalisisPalabras('Holaa', 'Halo');\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/MiguelAngelMTZ000414.js",
    "content": "console.warn(\"----------(◉◉∖____/◉◉)---------- Cadena de Caracteres ----------(OO∖____/OO)----------\")\n\nlet v1_string = \"Lamborghini\" // Cadena de caracteres \"String\", comillas dobles\nlet v2_string = 'Gallardo LP' // Cadena de caracteres \"String\", comillas simples\nlet v3_string = `560-4` // Cadena de caracteres \"String\", comillas invertidas\nconsole.log(typeof v1_string) // Tipo de dato \"String\"\nconsole.log(typeof v2_string) // Tipo de dato \"String\"\nconsole.log(typeof v3_string) // Tipo de dato \"String\"\nconsole.log(v1_string.length) // Longitud String\nconsole.log(v2_string.length) // Longitud String\nconsole.log(v3_string.length) // Longitud String\nconsole.log(v1_string) // Imprimiendo por consola \nconsole.log(v2_string) // Imprimiendo por consola \nconsole.log(v3_string) // Imprimiendo por consola\n\nconsole.warn(\"------------------------------- Concatenación -------------------------------\")\nconsole.log(v1_string + v2_string + v3_string)\nconsole.log(v1_string, v2_string, v3_string)\nlet concatenacion = v1_string.concat(\" \", v2_string, \" \", v3_string) // Usando la funtion concat()\nconsole.log(concatenacion)\nconsole.log(typeof concatenacion)\nconsole.log(concatenacion.length)\n\nconsole.warn(\"------------------------------- Interpolación -------------------------------\")\nconsole.log(`Interpolación de cadenas: ${v1_string} ${v2_string} ${v3_string}}`)\n\nconsole.warn(\"------------------------------- Mayusculas toLocaleUpperCase() -------------------------------\")\nconsole.log(`${v1_string.toLocaleUpperCase()} ${v2_string.toLocaleUpperCase()} ${v3_string.toLocaleLowerCase()}`) // Funcion toLocaleLowerCase() \n\nlet convertir_1_letraMayuscalas = \"miguel\"\nconsole.log(convertir_1_letraMayuscalas)\nlet obtenerEl_1_Valor = convertir_1_letraMayuscalas.charAt(0).toUpperCase()\nconsole.log(obtenerEl_1_Valor + convertir_1_letraMayuscalas.slice(1))\n\nconsole.warn(\"------------------------------- Minusculas toLocaleLowerCase() -------------------------------\")\nconsole.log(`${v1_string.toLocaleLowerCase()} ${v2_string.toLocaleLowerCase()} ${v3_string.toLocaleLowerCase()}`) // Funcion toLocaleLowerCase() \n\nconsole.warn(\"------------------------------- Acceso a caracteres específicos chartAt() -------------------------------\")\nconsole.log(v1_string)\nconsole.log(v1_string.charAt(0)) // Funtion charAt()\nconsole.log(v1_string.charAt(1)) // Funtion charAt()\nconsole.log(v1_string.charAt(2)) // Funtion charAt()\nconsole.log(v1_string.charAt(3)) // Funtion charAt()\nconsole.log(v1_string.charAt(4)) // Funtion charAt()\nconsole.log(v1_string.charAt(5)) // Funtion charAt()\nconsole.log(v1_string.charAt(6)) // Funtion charAt()\nconsole.log(v1_string.charAt(7)) // Funtion charAt()\nconsole.log(v1_string.charAt(8)) // Funtion charAt()\nconsole.log(v1_string.charAt(9)) // Funtion charAt()\nconsole.log(v1_string.charAt(10)) // Funtion charAt()\n\nconsole.warn(\"------------------------------- verificar primer caracter startsWith() -------------------------------\")\nlet v17_string = \"BMW 3.0 CSL HOMMAGE\"\nconsole.log(v17_string)\nconsole.log(`\"B\" empieza al principio: ${v17_string.startsWith(\"B\")}`)\nconsole.log(`\"b\" empieza al principio: ${v17_string.startsWith(\"b\")}`)\nconsole.log(`\"bmw\" empieza al principio: ${v17_string.startsWith(\"bmw\")}`)\nconsole.log(`\"BMW\" empieza al principio: ${v17_string.startsWith(\"BMW\")}`)\nconsole.log(`\"3.0\" empieza al principio: ${v17_string.startsWith(\"3.0\")}`)\n\nconsole.warn(\"------------------------------- verificar ultimo caracter endsWith() -------------------------------\")\nlet v4_string = \"Porsche 918 Spyder\"\nconsole.log(v4_string)\nconsole.log(`\"Spyder\" se encuentra al final de la cadena: ${v4_string.endsWith(\"Spyder\")}`) // Ultimo caracter true\nconsole.log(`\"918\" se encuentra al final de la cadena: ${v4_string.endsWith(\"918\")}`) //false\nconsole.log(`\"r\" se encuentra al final de la cadena: ${v4_string.endsWith(\"r\")}`) //false\n\nconsole.warn(\"------------------------------- verificar si existen caracteres en la cadena includes() -------------------------------\")\nlet v5_string = \"When Love Takes Over\"\nconsole.log(v5_string)\nconsole.log(`\"Love\" se encuentra en la cadena: ${v5_string.includes(\"Love\")}`)\nconsole.log(`\"Loves\" se encuentra en la cadena: ${v5_string.includes(\"Loves\")}`)\nconsole.log(`\"Two\" se encuentra en la cadena: ${v5_string.includes(\"Two\")}`)\n\nconsole.warn(\"------------------------------- Busca cadena y devuelve el indice indexOf() -------------------------------\")\nconsole.log(v5_string)\n// Devuelve la posición de la primera aparición de una subcadena.\n// indexOf(searchString: string, position?: number)\n// parametro = (searchString): la subcadena que se buscará en la cadena\n// parametro (position): el índice en el que se comenzará a buscar el objeto String. Si se omite, la búsqueda comienza al principio de la cadena.\nconsole.log(`Su posición de \"L\" es: ${v5_string.indexOf(\"L\")}`) // Funtion indexOf(),  \nconsole.log(`Su posición de \"o\" es: ${v5_string.indexOf(\"o\", 7)}`) // Funtion indexOf(),  \nconsole.log(`Su posición de \"v\" es: ${v5_string.indexOf(\"v\")}`) // Funtion indexOf(),  \nconsole.log(`Su posición de \"e\" es: ${v5_string.indexOf(\"e\", 7)}`) // Funtion indexOf(),  \nconsole.log(`Su posición de \"Over\" es: ${v5_string.indexOf(\"Over\")}`) // Funtion indexOf(),\nconsole.log(`Su posición de \"z\" es: ${v5_string.indexOf(\"z\")}`) // Funtion indexOf(),\n\nconsole.warn(\"------------------------------- Extrae caracteres si coincide en la cadena match() -------------------------------\")\n// Busca una cadena o un objeto que admita la búsqueda y devuelve una matriz que contiene los resultados de esa búsqueda o null si no se encuentran coincidencias.\nlet v6_string = \"Ive Been Thinking About You\"\nconst regex1 = /[A-Z]/g // Expresión Regular\nconst regex2 = /[a-z]/g // Expresión Regular\nconst regex3 = /[A-E]/gi // Expresión Regular\nconsole.log(v6_string)\nconsole.log(v6_string.match(regex1))\nconsole.log(v6_string.match(regex2))\nconsole.log(v6_string.match(regex3))\n\nconsole.warn(\"------------------------------- Rellenando una cadena al final y al principio padStart() y padEnd() -------------------------------\")\nlet v7_string = \"123\"\nlet v8_string = \"CFMOTO 450MT\"\nconsole.log(v7_string)\nconsole.log(v7_string.length)\nconsole.log(v7_string.padEnd(6, \".\"))\nconsole.log(v7_string.padStart(6, \".\"))\n\nconsole.log(`${v8_string}, longitud de la cadena: ${v8_string.length}`) // Interpolacion ``\nconsole.log(v8_string.padEnd(17, \"⭐\"))\nconsole.log(v8_string.padStart(17, \"⭐\"))\n\nlet v9_string = '2034399002125581'\nconsole.log(v9_string)\nlet Splitt = v9_string.slice(-4)\nconsole.log(Splitt.padStart(v9_string.length, \"*\"))\n\nconsole.warn(\"------------------------------- Repetir una cadena repeat() -------------------------------\")\nlet v10_string = \"GO! \"\nconsole.log(v10_string)\nconsole.log(v10_string.repeat(3))\n\nconsole.warn(\"------------------------------- Remplazando caracteres de una cadena replace() y replaceAll() -------------------------------\")\nlet v11_string = \"Asphalt Legends 9\"\nconsole.log(v11_string)\nconsole.log(v11_string.replace(\"9\", \"Unite\"))\n\nlet v12_string = \"H_O_L_A_H_O_L_A\"\nconsole.log(v12_string)\nconsole.log(v12_string.replaceAll(\"_\", \"-\"))\n\nconsole.warn(\"------------------------------- Extraer una sección de una cadena slice() -------------------------------\")\nlet v13_string = \"King of the Rodeo\"\nconsole.log(v13_string)\nconsole.log(v13_string.slice(0,4))\nconsole.log(v13_string.slice(8))\nconsole.log(v13_string.slice(-5))\n\nconsole.warn(\"------------------------------- Eliminiar los espacios de ambos extremos de un cadena trim() -------------------------------\")\nlet v14_string = \" Esto es una cadena con espacios \"\nconsole.log(v14_string)\nconsole.log(v14_string.trim())\n\nconsole.warn(\"------------------------------- Convertir a cadenas de caracteres (String) toString() -------------------------------\")\nlet v15_string = 12345678910\nconsole.log(`${v15_string}, es de tipo ${typeof v15_string}`)\nconst conversion = v15_string.toString()\nconsole.log(`${conversion}, es de tipo ${typeof conversion}`)\n// Convertimos a un Array (matriz/lista) usando la funsion split()\nconst conversionArray = conversion.split(\"\")\nconsole.log(conversionArray)\n\nlet v16_string = [\"Uno\", \"Dos\", \"Tres\"]\nconsole.log(typeof v16_string)\nconsole.log(v16_string)\nconst Array_String = v16_string.toString()\nconsole.log(typeof Array_String)\nconsole.log(Array_String)\n\nconsole.warn(\"------------------------------- Ejercicio Extra -------------------------------\")\n// Palíndromos: palabras o frase que se lee igual de izquierda a derecha que de derecha a izquierda. Somos o no somos, Son robos o sobornos\n\n// Anagramas: una palabra es anagrama de otra si las dos tienen las mismas letras, con el mismo numero de apariciones, pero en un orden diferente. Raza-Zara, Amor-Roma, Frase-Fresa\n\n// Isogramas: palabra o frase en la que cada letra aparece el mismo número de veces\n\nlet ejemplo = \"El Tiempo Que Tenemos\"\n// console.log(ejemplo.split(\"\", 10))\nlet ejemplo2 = ejemplo.trim().replace(/ /g, \"\")\n// let ejemplo3 = ejemplo2.replace(/ /g, \"\")\nconsole.log(ejemplo2)\n\nlet string = \"ElTiempoQueTenemos\"\nlet string2 = string.split(\"\")\nconsole.log(string2)\nlet string3 = string2.reverse()\nconsole.log(string3)\nlet string4 = string3.join(\"\")\nconsole.log(string4)\n\nconsole.log(`${ejemplo2} y ${string4}`)\nconsole.log(ejemplo2 == string4)\nconsole.log(`${string2} y ${string3}`)\nconsole.log(string2 === string3)\n\nconsole.warn(\"------------------------------- Palabras Palíndromos -------------------------------\")\nfunction Palindromos(palabra1, palabra2) {\n    // Convertimos las cadenas de caracteres a minisculas usando la funcion toLocaleLowerCase()\n    // Para eliminar los espacios usaremos la función replace(), la parte \"/\" significa que es una exprecion regultar que busca espacios, y la \"/g\" significa que es global, es decir busca todos los espacios en la variable. \n    let palabraPalindromo1 = palabra1.toLocaleLowerCase().replace(/ /g, \"\")\n    let palabraPalindromo2 = palabra2.toLocaleLowerCase().replace(/ /g, \"\")\n\n    // Con la función split(\"\") convertiremos la cadena a una arreglo \"Array\" de subcadenas\n    // Con la funcion reverse() invertiremos el orden de los elementos del Array\n    // Con la funcion join(\"\") concarenaremos todos los elementos de Array, devolviendo una nueva cadena\n    reverse_cadena = palabraPalindromo2.split(\"\").reverse().join(\"\")\n    if (palabraPalindromo1 === reverse_cadena) {\n        console.log(`La palabra = ${palabra1} es Palindromo`)\n        console.log(`La palabra = ${palabra2} es Palindromo`)\n    } else {\n        console.log(\"Las palabras no son Palindromos\")\n    }\n}\nPalindromos(\"Adan y Raza\", \"Azar y Nada\")\n\nconsole.warn(\"------------------------------- Palabras Anagramas -------------------------------\")\nfunction Anagramas(anagrama1, anagrama2) {\n    // Convertimos la cadena en minuscúlas con la función toLocaleLowerCase() y en arreglo de caracteres con la función split(\"\")\n    let cambio1 = anagrama1.toLocaleLowerCase().split(\"\")\n    let cambio2 = anagrama2.toLocaleLowerCase().split(\"\")\n    console.log(cambio1)\n    console.log(cambio2)\n    // (a, b) => a.localeCompare(b, undefined, { sensitivity: 'accent' }) (Checar el funcionamiento) ?\n    // Ordenar el arreglo con la función sort()\n    // Convertimos de nuevo el arreglo a una cadena de caracteres con la función join(\"\")\n    let ordenar1 = cambio1.sort().join(\"\")\n    let ordenar2 = cambio2.sort().join(\"\")\n    console.log(ordenar1)\n    console.log(ordenar2)\n    // Usamos la condición IF para comparar si las cadenas de caracteres son exactamente iguales \n    if (ordenar1 === ordenar2) {\n        console.log(`La palabra \"${anagrama1}\" y la palabra \"${anagrama2}\" son palabras Anagramas`)\n    } else {\n        console.log(\"Estas palabras no son Anagramas\")\n    }\n}\n// Anagramas(\"Amor\", \"Roma\")\nAnagramas(\"Lastre\", \"Letras\")\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/N1sek.js",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n */\n\nconst palabra = \"Javascript\"\n\n//Acceder a un caracter.\nconsole.log(palabra.charAt(0))\nconsole.log(palabra[0]) //Opcion mas moderna, pero no soportada en IE7\nconsole.log(\"---------------------------\")\n\n\n//Comparar caracteres\nlet a = \"a\"\nlet b = \"b\"\n\nif(a < b){\n    console.log(a + \" es menor que \" + b) //Se imprime esto porque el valor ASCII de la letra a es menor que la letra b\n} else if(a > b){\n    console.log(a + \" es mayor que \" + b)\n} else{\n    console.log(\"Son iguales\")\n}\nconsole.log(\"---------------------------\")\n\n//Substring\nconsole.log(palabra.substring(1,3)) //Primera letra se incluye y la utlima NO se incluye\nconsole.log(palabra.substring(2)) //Se imprime a partir de la letra seleccionada hasta el final\nconsole.log(\"---------------------------\")\n\n//Longitud\nconst emoji = \"😄\" \nconsole.log(palabra.length)\nconsole.log(palabra.length - 1) //Tambien se le puede restar a la longitud\n\nconsole.log(emoji.length) //Devuelve 2 debido a que Javascript usar utf-16 para representar caracteres\nconsole.log([...emoji].length) //De esta manera devuelve el numero de caracteres\n\nconsole.log(\"---------------------------\")\n\n//Concatenacion\nlet nombre = \"Denis\"\nlet frase = \"Hola, me llamo\"\n\nconsole.log(\"Hola, me llamo \" + nombre) //Usando el operador +\nconsole.log(`Hola, me llamo ${nombre}`) //Usando plantillas literales. No soportado en IE7\nconsole.log(frase.concat(\" \", nombre)) //Usando concat()\n\nconsole.log(\"---------------------------\")\n\n//Repeticion\nconsole.log(palabra.repeat(3))\n\nconsole.log(\"---------------------------\")\n\n// Recorrido\nfor (let i = 0; i < palabra.length; i++) {\n    console.log(palabra[i]);\n}\n\nconsole.log(\"---------------------------\")\n\n//Conversion Mayusculas <-> Minusculas\nconsole.log(palabra.toLowerCase())\nconsole.log(palabra.toUpperCase())\n\nconsole.log(\"---------------------------\")\n\n//Reemplazo\nlet frase2 = \"Hola Hola mundo\"\nconsole.log(frase.replace(\"Hola\", \"Adios\")) //Solo reemplaza la primera coincidencia\nconsole.log(frase.replaceAll(\"Hola\", \"Adios\")) //Reemplaza todas las coincidencias\n\nconsole.log(\"---------------------------\")\n\n//Division\nlet frase3 = \"Hola mundo estoy aprendiendo Javascript\"\nlet split = frase3.split(\" \")\nconsole.log(split)\nconsole.log(\"---------------------------\")\n\n//Union\nlet joined = split.join(\" \") \nconsole.log(joined)\nconsole.log(\"---------------------------\")\n\n//Interpolacion (mismo ejemplo que en el apartado concatenacion)\nconsole.log(`Hola, me llamo ${nombre}`)\nconsole.log(\"---------------------------\")\n\n//Verificacion\nconsole.log(frase3.includes(\"mundo\")) // True\nconsole.log(frase3.includes(\"Mundo\")) //False\nconsole.log(\"---------------------------\")\n\n//Trim\nlet frase4 = \"    Hola mundo    \"\nconsole.log(frase4)\nconsole.log(frase4.trim()) //Quita los espacios en blanco al principio y al final del string.\nconsole.log(frase4.trimEnd()) //Quita los espacios en blanco al final del string.\nconsole.log(frase4.trimStart()) //Quita los espacios en blanco al principio del string.\nconsole.log(\"---------------------------\")\n\n//Reverse\nconsole.log(split.reverse().join(\" \"))\nconsole.log(\"---------------------------\")\n\n\n\n/*\n* DIFICULTAD EXTRA (opcional):\n* Crea un programa que analice dos palabras diferentes y realice comprobaciones\n* para descubrir si son:\n* - Palíndromos\n* - Anagramas\n* - Isogramas\n*/\n\n//Palindromo\nfunction esPalindromo(palabra1){\n    return palabra1 === palabra1.split(\"\").reverse().join(\"\")\n\n}\nconsole.log(esPalindromo(\"somos\"))\n\n//Anagrama\nfunction esAnagrama(palabra1, palabra2){\n    return palabra1.split(\"\").reverse().join(\"\") === palabra2\n}\nconsole.log(esAnagrama(\"roma\", \"amor\"))\n\n//Isograma\nfunction esIsograma(palabra1){\n    let letras = palabra1.split(\"\")\n    for (let i = 0; i < letras.length; i++) {\n        for (let j = i+1; j < letras.length; j++) {\n            if(letras[i] === letras[j]){\n                return false\n            }\n        }\n    }\n    return true\n}\nconsole.log(esIsograma(\"murcielago\"))"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/Nightblockchain30.js",
    "content": "//at, charAt - Recibe un numero y devuelve el caracter en esa posicion\nconst sentence = 'Mouredev by Brais Moure';\nconsole.log('at', sentence.at(10));\nconsole.log('charAt', sentence.charAt(3));\nconst sentence2 = \"Nightblockchain 30\";\nconsole.log(\"ar\",sentence2.charAt(5),\"ol\");\n\n//concat - Conecta dos strings y devuelve una nueva\nconst str1 = 'Hola';\nconst str2 = 'Mundo';\nconsole.log('concat con espacio', str1.concat(' ', str2));\nconsole.log('concat con caracter', str1.concat('-', str2));\n\n//startsWith & endsWith - Evalua si el string inicia/termina con los caracteres del string del argumento y devuelve un booleano\nconsole.log('startsWith 1', sentence.endsWith('Mouredeb'));\nconsole.log('startsWith 2', sentence.endsWith('by'));\nconsole.log('endsWith 1', sentence.endsWith('Moure'));\nconsole.log('endsWith 2', sentence.endsWith('dev'));\n\n//fromCharCode - Devuelve un string creada por una secuencia de unidades de UTF-16\nconsole.log('fromCharCode', String.fromCharCode(12, 24, 15, 9));\n\n\n//includes - Evalua si un substring se encuentra dentro de un string. Devuelve un booleano. Se diferencia entre mayusculas y minusculas\nconst word1 = 'by';\nconst word2 = 'By';\nconsole.log('includes 1', sentence.includes(word1));\nconsole.log('includes 2', sentence.includes(word2));\n\n//indexOf - Devuelve la posicion en la que un substring inicia dentro de un string. En caso que la substring se repita, devuelve la posicion de la primera encontrada.\n//lastIndexOf - Devuelve la posicion en la que un substring inicia dentro de un string. En caso que la substring se repita, devuelve la posicion de la ultima encontrada.\nconst newSentence = 'Hola mundo. Bienvenidos al stream! Adios mundo.';\nconst word3 = 'mundo';\nconsole.log('indexOf', newSentence.indexOf(word3));\nconsole.log('lastIndexOf', newSentence.lastIndexOf(word3));\n\n//match - Devuelve los valores que coincidan con el regex\nconst regex = /[A-Z]/g; //Evalua solo mayusculas\nconsole.log('match', sentence.match(regex));\n\n//padStart & padEnd - Agregan un caracter al inicio o al final de la string, segun tantos espacios falten entre el ancho del string, y el ancho del argumento.\nconsole.log('padStart', sentence.padStart(106, '-'));\nconsole.log('padStart', sentence.padStart(102, '.'));\nconsole.log('padEnd', sentence.padEnd(40, '^'));\nconsole.log('padEnd', sentence.padEnd(80, '*'));\n\n\n//raw - Metodo que funciona con template literals para crear un string, en base a otra que tenga caracteres especiales que no se quieren perder o interpretar de forma inadecuada.\nconst __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {\n  if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\n  return cooked;\n};\n\nconst filePath = String.raw(__makeTemplateObject([\"C:Developmentprofileaboutme.html\"], [\"C:\\\\Development\\\\profile\\\\aboutme.html\"]));\nconsole.log('raw', \"Ruta de acceso: \".concat(filePath));\n\n//repeat - Devuelve una nueva string que contiene el numero de copias del string del argumento, concatenadas\nconst strSinSpacio = 'Mundo!';\nconst strConSpacio = 'Mundo! ';\nconsole.log('repeat 1', \"Hola \".concat(strSinSpacio.repeat(3)));\nconsole.log('repeat 2', \"Hola \".concat(strConSpacio.repeat(5)));\n\n//replace - Sustituye uno, constios, o toda un string, con otra string del segundo argumento del metodo.\nconst ownRegex = /Brais Moure/i;\nconsole.log('replace 1', sentence.replace('Brais', 'AChapeton'));\nconsole.log('replace 2', sentence.replace(ownRegex, 'Andres'));\n\n//search - Ejecuta una busqueda en base a un regex para buscar una similitud en un string, y devolver el index de esa primera similitud\nconst regex2 = /[^\\w\\s']/g; //Este regex evalua todo lo que NO sea una palabra, espacios en blanco, o comillas\nconsole.log('search', newSentence.search(regex2));\n\n//slice - Extrae una seccion del string y retorna una nueva, si modificar la original\nconsole.log('slice', sentence.slice(7));\n\n//split - Divide el string en base a un patron, y crea un array con las substrings resultantes\nconsole.log('split', sentence.split(' '));\n\n//toLowerCase & toUpperCase - Devuelve un string transformado todo a minusculas/mayusculas\nconsole.log('toLowerCase', sentence.toLowerCase());\nconsole.log('toUpperCase', sentence.toUpperCase());\n\n//trim - Elimina todos los espacios vacios que se encuentren al inicio o al final de un string\n//trimStart - Elimina solo los espacios vacion que se encuentra al inicio\n//trimEnd - Elimina solo los espacios vacion que se encuentra al final\nconst whiteSpaces = '    Hello World!     ';\nconsole.log('trim 1', whiteSpaces);\nconsole.log('trim 2', whiteSpaces.trim());\nconsole.log('trimStart', whiteSpaces.trimStart());\nconsole.log('trimEnd', whiteSpaces.trimEnd());\n\n// EJERCICIO EXTRA\nconst esPalindromo = function (my_string) {\n  const reverseStr = my_string.toLowerCase().split('').reverse().join('');\n  if (my_string.toLowerCase() === reverseStr) {\n      console.log('Es palindroma');\n  }\n  else {\n      console.log('No es palindroma');\n  }\n};\n\nesPalindromo('reconocer');\nesPalindromo('mundo');\n\nconst esAnagrama = function (str1, str2) {\n  const reverseStr2 = str2.toLowerCase().split('').reverse().join('');\n  if (str1.toLowerCase() === reverseStr2) {\n      console.log(\"La palabra \".concat(str1, \" es un anagrama\"));\n  }\n  else {\n      console.log(\"\".concat(str1, \" no es un anagrama\"));\n  }\n};\nesAnagrama('amor', 'roma');\n\nconst esIsograma = function (my_string) {\n  const letrasArray = my_string.toLowerCase().split('');\n  const letrasSet = new Set(letrasArray);\n  if (letrasArray.length === letrasSet.size) {\n      console.log(\"La palabra \".concat(my_string, \" es un isograma\"));\n  }\n  else {\n      console.log(\"\".concat(my_string, \" no es un isograma\"));\n  }\n};\n\nesIsograma('murcielago');\nesIsograma('ambiente');\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/OmarLand.js",
    "content": "/*\n    * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n    * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n    * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\n    *   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\n    *   interpolación, verificación...\n*/\n\n// Inicializo una cadena de caracteres:\nlet firstString = \"Saludos desde Javascript\"\nconsole.log(`Esta es una cadena: ${firstString}`);\n\n// Ver la longitud de una cadena:\nconsole.log(`Usamos la funcion .length en la variable firstString: ${firstString.length} es su longitud`);\n\n//Accediendo a un valor especifico de la cadena:\nconsole.log(`Usamos nombre de la variable con corchetes ej. var[i] para acceder a un valor concreto: ${firstString[2]}`);\n\n//Obtener el ultimo valor de una cadena:\nconsole.log( `EL ultimo valor de la cadena usamos .length - 1: ${firstString[firstString.length - 1]}` );\n\n// Concateniación de dos cadenas:\nlet str1 = \"Hola saludos\"\nlet str2 = \"soy javascript, dos cadenas concatenadas\"\nconsole.log( 'Concatenamos dos cadenas así: ', str1 +' '+ str2 ); \n\n//Repetición de cadena:\nlet repeatible = \"I feel good!!!\";\nconsole.log( repeatible.repeat(3) );\n\n// Recorrido de una cadena:\nfor(let i = 1; i <= firstString.length; i++){\n    let caracter = firstString[i - 1];\n    console.log(`Position: ${i} >>> `, caracter);\n}\n\n// Convertir de mayusculas a minisculas y minusculas a mayusculas:\nconsole.log('A Mayusculas: >>>', firstString.toUpperCase() );\nconsole.log('A Minusculas: >>>', firstString.toLowerCase() );\n\n// Uso del replace:\nlet str3 = 'I love the Streetfood for a lifetime';\nlet replaced = str3.replace('Streetfood', 'programming');\nconsole.log('Original: >>>', str3);\nconsole.log('Reemplazado: >>>', replaced);\n\nlet replacedAllChar = str3.replaceAll('o', '4')\nconsole.log('>>> ', replacedAllChar);\n\n// Dividiendo / Uso del SPLIT\nconst splited = firstString.split(' ');\nconsole.log('Dividido split: >>>', splited );\n\n// Union\nconst joined = splited.join(' ');\nconsole.log(\"Joined by ' ' >>>: \", joined);\n\n//Interpolación:\nconsole.log(`Esta es una cadena interpolada: ${str1 + ' ' + str2}  `);\n\n// Verificación de una cadena:\nconst verificando = firstString.includes('Javascript');\nconsole.log(\"Contiene Javascript: >>>\", verificando);\n\n\n/*\n    * DIFICULTAD EXTRA (opcional):\n    * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n    * para descubrir si son:\n    * - ✔️ Palíndromos\n    * - ✔️ Anagramas\n    * - Isogramas\n*/\n\n// Compruebo si dos palabras son Palíndromos:\nlet str4 = 'Reconocer';\nlet check0 = str4.toLowerCase().split('').join();\nlet check1 = str4.toLowerCase().split('').reverse().join();\n\nif( check0 === check1 ){\n    console.log('>>> Se trata de un Palíndromo...');\n} else {\n    console.log('>>> No se trata de un Palíndromo...');\n}\n\n// Compruebo si la palabra es un anagrama:\nconst isAnagrama = (palabra, posibleAnagrama) => {\n    let check = palabra.toLowerCase().split(\"\").sort().join();\n    let check1 = posibleAnagrama.toLowerCase().split(\"\").sort().join();\n  \n    if (check === check1) {\n      console.log(\">>> Se trata de un Anagrama...\");\n    } else {\n      console.log(\">>> No se trata de un anagrama\");\n    }\n    return \"Proceso completado.\";\n  };\n  \n  console.log(isAnagrama(\"Omar\", \"roma\"));\n  \n// Compruebo si una palabra es Isograma:\nconsole.log(\"\\n##### Comprobando si un String es Isograma #####\");\nconst isIsograma = (string) => {\n  \n  const word = string.toLowerCase();\n\n  const wordArray = word.split(\"\");\n  const wordSet = new Set(wordArray);\n  if (wordArray.length === wordSet.size){\n    console.log(\">>> Se trata de un Isograma...\");\n  } else {\n    console.log(\">>> No se trata de un Isograma...\");\n  }\n\n  return \"Proceso completado.\";;\n\n};\n\nconsole.log( isIsograma(\"Hola\") );\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/Pancratzia.js",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\n/***********OPERACIONES CON CADENAS - PARTE 1*************/\n\n/******* IMPORTANTE\n *\n * Todos los metodos retornan una nueva cadena, no modifican la cadena original a menos que se indique lo contrario\n *\n ********/\n\nconst stringExample = \"Hello, Javascript!\";\n\n//LARGO DE LA CADENA\n\nconsole.log(\n  `La cadena \"${stringExample}\" tiene ${stringExample.length} caracteres.`\n);\n\n//EXTRACCIÓN DE CARACTERES DE UN STRING\n\nconsole.log(\n  `at(n) - ${stringExample}.at(1) es la letra \"${stringExample.at(1)}\".`\n);\nconsole.log(\n  `charAt(n) - ${stringExample}.charAt(1) es la letra \"${stringExample.charAt(\n    1\n  )}\".`\n);\n\n//La diferencia entre at() y charAt() es que at() permite usar indexes negativos\n\nconsole.log(\n  `charCodeAt(n) - ${stringExample}.charCodeAt(1) es la letra \"${stringExample.charCodeAt(\n    1\n  )}\".`\n); //Devuelve el valor ASCII del caracter\n\nconsole.log(`También se puede acceder a un caracter como si fuese un array`);\nconsole.log(\n  `string[n] - ${stringExample}[1] es la letra \"${stringExample[1]}\".`\n);\n\n//EXTRAYENDO PARTES DE UN STRING\n\nconsole.log(\n  `slice(n,m) - ${stringExample}.slice(0,5) es la cadena \"${stringExample.slice(\n    0,\n    5\n  )}\".`\n); //Si no se coloca el segundo argumento, toma hasta el final de la cadena\nconsole.log(\n  `substring() - ${stringExample}.substring(0,5) es la cadena \"${stringExample.substring(\n    0,\n    5\n  )}\".`\n); //Si no se coloca el segundo argumento, toma hasta el final de la cadena\n\n//La diferencia entre slice() y substring() es que slice() puede tomar negativos\n\nconsole.log(\n  `substr(n,m) - ${stringExample}.substr(0,5) es la cadena \"${stringExample.substr(\n    0,\n    5\n  )}\".`\n); //Si no se coloca el segundo argumento, toma hasta el final de la cadena\n\n//Está deprecado. Se recomienda usar substring() o substr(). El segundo argumento indica la longitud de la subcadena.\n\n//CONVERSION A MAYÚSCULAS Y MINÚSCULAS\n\nconsole.log(\n  `toUpperCase() - ${stringExample}.toUpperCase() es la cadena \"${stringExample.toUpperCase()}\".`\n);\nconsole.log(\n  `toLowerCase() - ${stringExample}.toLowerCase() es la cadena \"${stringExample.toLowerCase()}\".`\n);\n\n//CONCATENACION\n\nconst string1 = \"Fizz\";\nconst string2 = \"Buzz\";\n\nconsole.log(\n  `concat() - ${string1}.concat(${string2}) es la cadena \"${string1.concat(\n    string2\n  )}\".`\n);\nconsole.log(`+ - ${string1}+${string2} es la cadena \"${string1 + string2}\".`);\n\n//TRIM - Elimina espacios al principio y al final de una cadena\n\nconst trimStringExample = \"          Hello, Javascript!          \";\n\nconsole.log(\n  `trim() - ${trimStringExample}.trim() es la cadena \"${trimStringExample.trim()}\".`\n);\nconsole.log(\n  `trimStart() - ${trimStringExample}.trimStart() es la cadena \"${trimStringExample.trimStart()}\".`\n);\nconsole.log(\n  `trimEnd() - ${trimStringExample}.trimEnd() es la cadena \"${trimStringExample.trimEnd()}\".`\n);\n\n//PADDING - Rellena una cadena con un caracter\n\nlet text = \"5\";\nlet padded = text.padStart(3, \"x\");\n\nconsole.log(`padStart() - ${text}.padStart(4,\"x\") es la cadena \"${padded}\".`);\nconsole.log(\n  `padEnd() - ${text}.padEnd(4,\"x\") es la cadena \"${text.padEnd(4, \"x\")}\".`\n);\n\n//REPETICION\n\nconsole.log(\n  `repeat() - ${stringExample}.repeat(3) es la cadena \"${stringExample.repeat(\n    3\n  )}\".`\n);\n\n//REEMPLAZO\n\nconsole.log(\n  `replace() - ${stringExample}.replace(\"Javascript\",\"JS\") es la cadena \"${stringExample.replace(\n    \"Javascript\",\n    \"JS\"\n  )}\".`\n);\nconsole.log(\n  `replaceAll() - ${stringExample}.replaceAll(\"Javascript\",\"JS\") es la cadena \"${stringExample.replaceAll(\n    \"Javascript\",\n    \"JS\"\n  )}\".`\n);\n\n//La diferencia entre replace() y replaceAll() es que replace() reemplaza la primera coincidencia, mientras que replaceAll() reemplaza todas las coincidencias.\n\n//CONVERSION A ARRAY\n\nconst textToSplit = new String(\"Hello|,|Javascript!\");\n\nconsole.log(\n  `split() - ${textToSplit}.split(\"|\") es el array \"${textToSplit.split(\"|\")}\".`\n);\n\n//El split() separa la cadena en un array de caracteres dado un separador\n\n/***********OPERACIONES CON CADENAS - EXTRA***************/\n\nlet word1 = \"Anna\";\nlet word2 = \"nana\";\n\nword1 = word1.toLowerCase();\nword2 = word2.toLowerCase();\n\nfunction isPalindrome(word) {\n  const newWord = word.split(\"\").reverse().join(\"\");\n  if (word === newWord) return true;\n\n  return false;\n}\n\nfunction isAnagram(word1, word2) {\n    const newWord1 = word1.split(\"\").sort().join(\"\");\n    const newWord2 = word2.split(\"\").sort().join(\"\");\n\n    if (newWord1 === newWord2) return true;\n\n    return false;\n}\n\nfunction isIsogram(word) { //Para que sea isograma, las letras no pueden repetirse\n    let letters = word.toLowerCase().split('').sort();\n    for (let i = 1; i < letters.length; i++) {\n        if (letters[i] === letters[i - 1]) {\n            return false;\n        }\n    }\n    return true;\n}\n\n\nconsole.log(`La palabra \"${word1}\" es un palíndromo?`, isPalindrome(word1));\nconsole.log(`La palabra \"${word2}\" es un palíndromo?`, isPalindrome(word2));\n\nconsole.log(`La palabra \"${word1}\" y \"${word2}\" son anagramas?`, isAnagram(word1, word2));\n\nconsole.log(`La palabra \"${word1}\" es un isograma?`, isIsogram(word1));\nconsole.log(`La palabra \"${word2}\" es un isograma?`, isIsogram(word2));\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/RaulDoezon.js",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n*/\n\nvar cadena = \"Parangaricutirimícuaro\";\nvar arreglo = [\"See\", \"you\", \"next\", \"mission\"];\n\nconsole.log(\"El rey de \" + cadena + \", es la concatenación de dos cadenas de texto.\");\nconsole.log(\"La longitud de \" + cadena + \" es: \" + cadena.length);\nconsole.log(\"El tercer caracter de \" + cadena + \" es: \" + cadena[2]);\nconsole.log(\"El último caracter de \" + cadena + \" es: \" + cadena[cadena.length - 1]);\nconsole.log(\"Una subcadena de \" + cadena + \": \" + cadena.substring(9, 15));\nconsole.log(cadena.toUpperCase() + \" en MAYÚSCULAS.\");\nconsole.log(cadena.toLowerCase() + \" en minúsculas.\");\nconsole.log(\"Parte de la cadena se reemplaza: \" + cadena.replace(\"cutirimícuaro\", \"fláutica\"));\nconsole.log(\"La cadena se repite tres veces: \" + cadena.repeat(3));\nconsole.log(\"La cadena se divide: \" + cadena.split(\"\"));\nconsole.log(\"El arreglo [\" + arreglo + \"] se une para formar una cadena: \" + arreglo.join(\" \"));\nconsole.log(`Estoy interpolando a ${cadena} en esta cadena de texto.`);\nconsole.log(`¿La cadena ${cadena} incluye el texto Paranga? ${cadena.includes(\"Paranga\") === true ? \"Así es.\" : \"No lo contiene.\"}`);\nconsole.log(\"Esta es la iteración de la cadena:\");\n\nfor (caracter of cadena) {\n  console.log(caracter);\n}\n\n// +++++++++ DIFICULTAD EXTRA +++++++++\nvar firstWord = \"Samus\".toUpperCase();\nvar secondWord = \"Sumas\".toUpperCase();\n\nfunction isPalindrome() {\n  var secondPalindrome = secondWord.toUpperCase().split(\"\").reverse().join(\"\");\n\n  if (firstWord === secondPalindrome) {\n    return \"son palíndromos.\";\n  } else {\n    return \"no son palíndromos.\"\n  }\n}\n\nfunction isAnagram() {\n  var firstAnagram = firstWord.split(\"\").sort().join(\"\");\n  var secondAnagram = secondWord.split(\"\").sort().join(\"\");\n\n  if (firstAnagram === secondAnagram) {\n    return \"son Anagramas.\";\n  } else {\n    return \"no son Anagramas.\";\n  }\n}\n\nfunction isIsogram(theString) {\n  for (var index = 0; index < theString.length; index++) {\n\n    if (theString.indexOf(theString[index]) !== index) {\n      return `${theString} no es Isograma.`;\n    }\n  }\n\n  return `${theString} es Isograma.`;\n}\n\nconsole.log(\"------------------------------\");\nconsole.log(`${firstWord} y ${secondWord} ${isPalindrome()}`);\nconsole.log(\" \");\nconsole.log(`${firstWord} y ${secondWord} ${isAnagram()}`);\nconsole.log(\" \");\nconsole.log(isIsogram(firstWord));\nconsole.log(isIsogram(secondWord));\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/RicJDev.js",
    "content": "//EJERCICIO\n//-Concatenacion-\nlet miString1 = 'Hola';\nlet miString2 = 'JavaScript';\nconsole.log(miString1 + ' ' + miString2);\nconsole.log(miString1, miString2);\nconsole.log(miString1.concat(' ', miString2));\n\n//-Repeticion-\nlet miNombre = 'Ric ';\nconsole.log(miNombre.repeat(5));\n\n//-Indexacion-\nlet alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';\nconsole.log(alphabet[17] + alphabet[8] + alphabet[2]);\n\n//-Busqueda por posicion-\nconst miNombreChart1 = alphabet.charAt(17);\nconst miNombreChart2 = alphabet.charAt(8);\nconst miNombreChart3 = alphabet.charAt(2);\nconsole.log(miNombreChart1, miNombreChart2, miNombreChart3);\nconsole.log(alphabet.at(17), alphabet.at(8), alphabet.at(2));\n\n//-Busqueda de posicion-\nconst h = alphabet.indexOf('H');\nconsole.log(`La letra H es la  numero ${h + 1} de nuestro alfabeto`);\n\n//-Longitud-\nlet miString3 = 'Papas fritas';\nconsole.log(miString3.length);\n\n//-Slicing (porcion)-\nlet fritas = miString3.slice(6);\nconsole.log(fritas);\n\nlet miString4 = 'Batman le gana a Superman';\nlet BatmanStr = miString4.substring(0, 6);\nlet SupermanStr = miString4.substring(17, miString4.length);\nconsole.log(BatmanStr);\nconsole.log(SupermanStr);\n\n//-Iteracion-\nfor (let i = 0; i < BatmanStr.length; i++) {\n\tconsole.log(BatmanStr[i]);\n}\n\n//-Busqueda-\nlet companies = 'Google, Telegram, Facebook, YouTube';\nconsole.log(companies.includes('Google'));\nconsole.log(companies.includes('Microsoft'));\n\n//-Reemplazo-\nlet messageMusicPlayer =\n\t'Music Player says: \\n Now playing \"The Pretender - Foo Fighters\"';\nconsole.log(messageMusicPlayer);\nlet latestSong = '\"The Pretender - Foo Fighters\"';\nlet currentSong = '\"Monster - Skillet\"';\nconsole.log(messageMusicPlayer.replace(latestSong, currentSong));\n\n//-Division-\nlet companiesArray = companies.split(', ');\nconsole.log(companiesArray);\nlet colores = 'amarillo, rojo, verde, marron';\nconsole.log(colores.split('r'));\n\n//-Union-\nlet companiesNuevaStr = companiesArray.join(', ');\nconsole.log(companiesNuevaStr);\n\n//-Mayusculas, minusculas y letras en mayusculas-\nlet miString5 = 'CamellOs y cabAlloS';\nlet minusculas = miString5.toLowerCase();\nlet mayusculas = miString5.toUpperCase();\nconsole.log(minusculas);\nconsole.log(mayusculas);\n\n//-Eliminación de espacios al principio y al final-\nlet miString6 = ' Frase con espacios antes y despues ';\nconsole.log('***' + miString6 + '***');\nconsole.log('***' + miString6.trim() + '***');\nconsole.log('***' + miString6.trimStart() + '***');\nconsole.log('***' + miString6.trimEnd() + '***');\n\n//-Inerpolacion-\nlet num1 = 23;\nlet num2 = 12;\nconsole.log(`${num1} y ${num2} suman ${num1 + num2}`);\n\n//EJERCICIO\nconst analizaEstasPalabras = (a = 'Roma', b = 'Amor') => {\n\tconsole.log('------PALINDROMA------');\n\tfunction palindromo(palabra) {\n\t\tlet palabraInvertida = palabra.toLowerCase().split('').reverse().join('');\n\t\tif (palabra.toLowerCase() === palabraInvertida) {\n\t\t\tconsole.log(`${palabra} es palindroma`);\n\t\t} else {\n\t\t\tconsole.log(`${palabra} no es palindorma`);\n\t\t}\n\t}\n\tpalindromo(a);\n\tpalindromo(b);\n\n\tconsole.log('------ANAGRAMA------');\n\tfunction anagrama(palabra1, palabra2) {\n\t\tconst arr1 = palabra1.toLowerCase().split('').sort().join('');\n\t\tconst arr2 = palabra2.toLowerCase().split('').sort().join('');\n\t\tif (arr1 === arr2) {\n\t\t\tconsole.log(`${palabra1} es un anagrama de ${palabra2}`);\n\t\t} else {\n\t\t\tconsole.log(`${palabra1} no es un anagrama de ${palabra2}`);\n\t\t}\n\t}\n\n\tanagrama(a, b);\n\n\tconsole.log('------ISOGRAMA------');\n\tfunction isograma(palabra) {\n\t\tconst array = palabra.toLowerCase().split('');\n\t\tconst set = new Set(array);\n\t\tif (array.length === set.size) {\n\t\t\tconsole.log(`${palabra} es un isograma`);\n\t\t} else {\n\t\t\tconsole.log(`${palabra} no es un isograma`);\n\t\t}\n\t}\n\n\tisograma(a);\n\tisograma(b);\n};\n\nanalizaEstasPalabras();\nanalizaEstasPalabras('Radar', 'Paloma');\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/Sac-Corts.js",
    "content": "// Ejercicio //\n\n// Accessing specific characters\nlet str = \"Hello World\";\nconsole.log(str[0]);\nconsole.log(str.charAt(6));\n\n// Substrings\nconsole.log(str.substring(0, 5));\nconsole.log(str.slice(6));\nconsole.log(str.slice(-5));\n\n// Length\nconsole.log(str.length);\n\n// Concatenation\nlet str1 = \"Hello\";\nlet str2 = \"World\"; \nconsole.log(str1 + \" \" + str2);\nconsole.log(str1.concat(\" \", + str2));\n\n// Repetition\nconsole.log(str.repeat(3));\n\n// Iteration\nfor (let char of str) {\n    console.log(char);\n}\n\n// Conversion to uppercase and lowercase\nconsole.log(str.toUpperCase());\nconsole.log(str.toLowerCase());\n\n// Replacement\nconsole.log(str.replace(\"World\", \"Everyone\"));\n\n// Splitting\nlet words = str.split(\" \");\nconsole.log(words);\n\n// Joining\nlet joinedStr = words.join(\" \");\nconsole.log(joinedStr);\n\n// Interpolation\nlet _name = \"Isaac\";\nlet greeting = `Hello ${_name}!`;\nconsole.log(greeting);\n\n// Checking substrings\nconsole.log(str.includes(\"World\"));\nconsole.log(str.startsWith(\"Hello\"));\nconsole.log(str.endsWith(\"World\"));\n\n// Trimming\nlet paddedStr = \"   Hello World     \";\nconsole.log(paddedStr.trim());\nconsole.log(paddedStr.trimStart());\nconsole.log(paddedStr.trimEnd());\n\n// Converting to array of characters\nconsole.log(Array.from(str));\n\n// Finding character of substring position\nconsole.log(str.indexOf(\"o\"));\nconsole.log(str.lastIndexOf(\"o\"));\n\n// Extra Exercise //\n\nfunction checkPalindrome(word) {\n    let inverted = word.split('').reverse().join('');\n    return word === inverted;\n}\n\nfunction checkAnagram(word1, word2) {\n    let ordered1 = word1.split('').sort().join('');\n    let ordered2 = word2.split('').sort().join('');\n    return ordered1 === ordered2;\n}\n\nfunction checkIsogram(word) {\n    let letters = new Set([]);\n    for (char of word) {\n        if (letters.has(char)) {\n            return false;\n        } \n        letters.add(char);\n    }\n    return true;\n}\n\nfunction checkWords(word1, word2) {\n    return {\n        word1ItsPalindrome: checkPalindrome(word1),\n        word2ItsPalindrome: checkPalindrome(word2),\n        theyAreAnagrams: checkAnagram(word1, word2),\n        word1ItsIsogram: checkIsogram(word1),\n        word2ItsIsogram: checkIsogram(word2),\n    };\n}\n\nlet word1 = \"civic\";\nlet word2 = \"radar\";\n\nconsole.log(checkWords(word1, word2));\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/SalazarProgrammer.js",
    "content": "/*\n * 04 CADENAS DE CARACTERES\n * Dificultad: Media | Publicación: 22/01/24 | Corrección: 29/01/24\n */\n\n/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones con cadenas de caracteres\n */\n\nconsole.log('=== OPERACIONES CON CADENAS EN JAVASCRIPT ===');\n\n// 1. CREACIÓN DE CADENAS\nconsole.log('\\n1. CREACIÓN DE CADENAS:');\nlet cadena1 = 'Hola Mundo';\nlet cadena2 = 'JavaScript es genial';\nlet cadena3 = `Plantillas literales`;\nlet cadena4 = String(123); // Conversión a string\nconsole.log('cadena1:', cadena1);\nconsole.log('cadena2:', cadena2);\nconsole.log('cadena3:', cadena3);\nconsole.log('cadena4:', cadena4);\n\n// 2. LONGITUD DE CADENA\nconsole.log('\\n2. LONGITUD:');\nconsole.log(\"Longitud de '\" + cadena1 + \"':\", cadena1.length);\n\n// 3. ACCESO A CARACTERES\nconsole.log('\\n3. ACCESO A CARACTERES:');\nconsole.log('Primer carácter:', cadena1[0]);\nconsole.log('Último carácter:', cadena1[cadena1.length - 1]);\nconsole.log('charAt(5):', cadena1.charAt(5));\nconsole.log('charCodeAt(0):', cadena1.charCodeAt(0)); // Código Unicode\n\n// 4. SUBCADENAS\nconsole.log('\\n4. SUBCADENAS:');\nconsole.log('slice(0, 4):', cadena1.slice(0, 4)); // \"Hola\"\nconsole.log('substring(5, 10):', cadena1.substring(5, 10)); // \"Mundo\"\nconsole.log('substr(2, 3):', cadena1.substr(2, 3)); // \"la \" (deprecado)\n\n// 5. CONCATENACIÓN\nconsole.log('\\n5. CONCATENACIÓN:');\nlet concatenacion = cadena1 + ' ' + cadena2;\nconsole.log('Concatenación con +:', concatenacion);\nconsole.log('concat():', cadena1.concat(' - ', cadena2));\n\n// 6. REPETICIÓN\nconsole.log('\\n6. REPETICIÓN:');\nconsole.log('repeat(3):', 'Hola '.repeat(3));\n\n// 7. RECORRIDO\nconsole.log('\\n7. RECORRIDO:');\nconsole.log('For...of:');\nfor (let char of cadena1) {\n\tconsole.log('  ' + char);\n}\n\nconsole.log('split() y forEach():');\ncadena1.split('').forEach((char, index) => {\n\tconsole.log(`  ${index}: ${char}`);\n});\n\n// 8. CONVERSIÓN MAYÚSCULAS/MINÚSCULAS\nconsole.log('\\n8. CONVERSIÓN DE CASES:');\nconsole.log('toUpperCase():', cadena1.toUpperCase());\nconsole.log('toLowerCase():', cadena1.toLowerCase());\n\n// 9. BÚSQUEDA\nconsole.log('\\n9. BÚSQUEDA:');\nconsole.log(\"indexOf('Mundo'):\", cadena1.indexOf('Mundo'));\nconsole.log(\"lastIndexOf('o'):\", cadena1.lastIndexOf('o'));\nconsole.log(\"includes('Hola'):\", cadena1.includes('Hola'));\nconsole.log(\"startsWith('Hola'):\", cadena1.startsWith('Hola'));\nconsole.log(\"endsWith('Mundo'):\", cadena1.endsWith('Mundo'));\nconsole.log('match(/[aeiou]/g):', cadena1.match(/[aeiou]/g));\n\n// 10. REEMPLAZO\nconsole.log('\\n10. REEMPLAZO:');\nconsole.log(\n\t\"replace('Mundo', 'JavaScript'):\",\n\tcadena1.replace('Mundo', 'JavaScript')\n);\nconsole.log(\"replaceAll('o', '0'):\", cadena1.replaceAll('o', '0'));\nconsole.log('replace con regex:', cadena1.replace(/[aeiou]/g, '-'));\n\n// 11. DIVISIÓN Y UNIÓN\nconsole.log('\\n11. DIVISIÓN Y UNIÓN:');\nlet palabras = cadena1.split(' ');\nconsole.log(\"split(' '):\", palabras);\nconsole.log(\"join('-'):\", palabras.join('-'));\n\n// 12. ELIMINACIÓN DE ESPACIOS\nconsole.log('\\n12. ELIMINACIÓN DE ESPACIOS:');\nlet conEspacios = '   Hola Mundo   ';\nconsole.log('trim():', `\"${conEspacios.trim()}\"`);\nconsole.log('trimStart():', `\"${conEspacios.trimStart()}\"`);\nconsole.log('trimEnd():', `\"${conEspacios.trimEnd()}\"`);\n\n// 13. VERIFICACIÓN\nconsole.log('\\n13. VERIFICACIÓN:');\nconsole.log(\"includes('Hola'):\", cadena1.includes('Hola'));\nconsole.log(\"startsWith('H'):\", cadena1.startsWith('H'));\nconsole.log(\"endsWith('o'):\", cadena1.endsWith('o'));\n\n// 14. INTERPOLACIÓN (TEMPLATE LITERALS)\nconsole.log('\\n14. INTERPOLACIÓN:');\nlet nombre = 'Juan';\nlet edad = 30;\nconsole.log(`Mi nombre es ${nombre} y tengo ${edad} años.`);\n\n// 15. COMPARACIÓN\nconsole.log('\\n15. COMPARACIÓN:');\nconsole.log(\"'a' < 'b':\", 'a' < 'b');\nconsole.log(\"'a' === 'A':\", 'a' === 'A');\nconsole.log('localeCompare:', 'ñ'.localeCompare('n'));\n\n// 16. MÉTODOS ADICIONALES\nconsole.log('\\n16. MÉTODOS ADICIONALES:');\nconsole.log(\"padStart(15, '-'):\", cadena1.padStart(15, '-'));\nconsole.log(\"padEnd(15, '-'):\", cadena1.padEnd(15, '-'));\nconsole.log('codePointAt(0):', cadena1.codePointAt(0));\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Analizar dos palabras para ver si son palíndromos, anagramas o isogramas\n */\n\nconsole.log('\\n=== DIFICULTAD EXTRA ===');\n\nfunction analizarPalabras(palabra1, palabra2) {\n\tconsole.log(`Analizando: \"${palabra1}\" y \"${palabra2}\"`);\n\n\t// 1. PALÍNDROMOS (se leen igual al derecho y al revés)\n\tfunction esPalindromo(palabra) {\n\t\tconst limpia = palabra.toLowerCase().replace(/[^a-záéíóúüñ]/g, '');\n\t\treturn limpia === limpia.split('').reverse().join('');\n\t}\n\n\tconsole.log(`¿\"${palabra1}\" es palíndromo?`, esPalindromo(palabra1));\n\tconsole.log(`¿\"${palabra2}\" es palíndromo?`, esPalindromo(palabra2));\n\n\t// 2. ANAGRAMAS (mismas letras en diferente orden)\n\tfunction sonAnagramas(p1, p2) {\n\t\tconst limpiar = (str) => str.toLowerCase().replace(/[^a-záéíóúüñ]/g, '');\n\t\tconst p1Limpia = limpiar(p1);\n\t\tconst p2Limpia = limpiar(p2);\n\n\t\tif (p1Limpia.length !== p2Limpia.length) return false;\n\n\t\treturn (\n\t\t\tp1Limpia.split('').sort().join('') === p2Limpia.split('').sort().join('')\n\t\t);\n\t}\n\n\tconsole.log(`¿Son anagramas?`, sonAnagramas(palabra1, palabra2));\n\n\t// 3. ISOGRAMAS (ninguna letra se repite)\n\tfunction esIsograma(palabra) {\n\t\tconst limpia = palabra.toLowerCase().replace(/[^a-záéíóúüñ]/g, '');\n\t\tconst letrasUnicas = new Set(limpia.split(''));\n\t\treturn limpia.length === letrasUnicas.size;\n\t}\n\n\tconsole.log(`¿\"${palabra1}\" es isograma?`, esIsograma(palabra1));\n\tconsole.log(`¿\"${palabra2}\" es isograma?`, esIsograma(palabra2));\n}\n\n// Ejemplos de prueba\nanalizarPalabras('reconocer', 'cerco negro');\nconsole.log('\\n' + '='.repeat(40));\nanalizarPalabras('amor', 'roma');\nconsole.log('\\n' + '='.repeat(40));\nanalizarPalabras('murciélago', 'programación');\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/TofeDev.js",
    "content": "const string1 = \"El cielo está soleado\"\nconst string2 = \"puede que hoy llueva\"\n\n//Concatenación\nconsole.log(string1 + \" pero \" + string2)\nconsole.log(`${string1} pero ${string2}`)\n\n//Index de un caracter en específico\nconsole.log(string1[5]) //e\n\n//Subcadena\nconsole.log(string1.slice(9,21)) //está soleado\n\n//Longitud\nconsole.log(string1.length); //21\n\n//División\nconst listaColores = \"rojo, amarillo, azul, morado\"\nlet separar = string1.split(\",\");\nconsole.log(separar); //(4) [\"rojo\", \"amarillo\", \"azul\", \"morado\"]\n\n//Conversión mayúsculas\nconsole.log(string2.toUpperCase()); //PUEDE QUE HOY LLUEVA\n\n//Conversión minúsculas\nconsole.log(string1.toLowerCase()); //el cielo está soleado\n\n//Reemplazo\nconsole.log(string1.replace(\"soleado\", \"nublado\")) //\"El cielo está nublado\"\n\n//Verificación\nconsole.log(string1.includes(\"llueva\")); //true\n\n// Repetir\nconsole.log(string2.repeat(3)); //\n\n//Busqueda de posición\nconsole.log(string1.search(\"elo\")); //5\n\n   /* DIFICULTAD EXTRA (opcional):\n    * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n    * para descubrir si son:\n    * - Palíndromos\n    * - Anagramas\n    * - Isogramas\n    */ \n\n//Palíndromo\nfunction palindromo(palabra) {\npalabraInvertida = \"\";\n    for (i = palabra.length - 1; i >= 0; i--) {\n        palabraInvertida += palabra[i];\n    }\n    if (palabra===palabraInvertida) {\n        console.log(\"Es palíndromo\");\n    } else {\n        console.log(\"No es palíndromo\");\n    }\n}\n\n//Anagrama\nfunction anagrama(palabra1, palabra2) {\n    const arr1 = palabra1.toLowerCase().split('').sort().join('');\n    const arr2 = palabra2.toLowerCase().split('').sort().join('');\n    if (arr1 === arr2) {\n        console.log(\"Es un anagrama\");\n    } else {\n        console.log(\"No es un anagrama\");\n    }\n}\n\n//Isograma\nfunction isograma(palabra) {\n    const array = palabra.toLowerCase().split('');\n    const set = new Set(array);\n    if (array.length === set.size) {\n        console.log(\"Es un isograma\");\n    } else {\n        console.log(\"No es un isograma\");\n    }\n}\n\nconst palabra1 = \"reconocer\";\nconst palabra2 = \"ballena\";\nconst palabra3 = \"llenaba\";\nconst palabra4 = \"cuervo\";\n\n\npalindromo(palabra1); //True\npalindromo(palabra4); //False\n\nanagrama(palabra2, palabra3); //True\nanagrama(palabra3, palabra4); //False\n\nisograma(palabra4); //True\nisograma(palabra1); //False"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/UserMatthew.js",
    "content": "\n/* #04 CADENAS DE CARACTERES\n   ## Ejercicio\n */\n// ---- Crear Cadenas ----\nlet nombre = \"Andres\"\nlet apellido = \"Machuca\"\n\n// ---- Concatenar Cadenas ----\nlet nombreCompleto = nombre + \" \" + apellido\nconsole.log(nombreCompleto)\nlet nombreCompleto2 = `${nombre} ${apellido}`\nconsole.log(nombreCompleto2)\n\n// ---- Longitud de cadena ----\nconsole.log(nombreCompleto.length)\n\n// ---- Acceder a un caracter especifico ----\nconsole.log(nombreCompleto[0])\nconsole.log(nombreCompleto.charAt(7))\n\n// ---- Convertir en mayuscula o miniscula todo ----\nconsole.log(nombreCompleto.toUpperCase())\nconsole.log(nombreCompleto.toLowerCase())\n\n// ---- Extraer parte de una cadena ----\nconsole.log(nombreCompleto.slice(0, 6))\nconsole.log(nombreCompleto.substring(7, 14))\n\n// ---- Reemplazar parte de una cadena ----\nconsole.log(nombreCompleto.replace(\"Machuca\", \"Machado\"))\n\n// ---- Buscar dentro de una cadena ----\nconsole.log(nombreCompleto.indexOf(\"Machuca\"))   // Devuelve el inicio de la posicion en la cadena\nconsole.log(nombreCompleto.indexOf(\"Fernando\"))  // Devuelve -1 si no se encuentra el valor\nconsole.log(nombreCompleto.includes(\"Fernando\")) //Devuelve un Booleano\nconsole.log(nombreCompleto.endsWith(\"Machado\"))  // Devuelve un Booleano\n\n// ---- Buscar dentro de una cadena ----\nconsole.log(nombreCompleto.repeat(3))\n\n// ---- Dividir una cadena ----\nlet lista = \"manzana,pera,banana\";\nconsole.log(lista.split(\",\"))\n\n// ---- Eliminar espacios en blanco ----\nlet saludo = \"     Hola gente           \"\nconsole.log(saludo)\nconsole.log(saludo.trim())\n\n// ---- Convertir valores numericos a cadena ----\nlet numero = 123;\nconsole.log(numero.toString());\n// ---- Sustituir caracteres usando expresiones regulares ----\nlet textoRegExp = \"Hola 1234\";\nconsole.log(textoRegExp.replace(/\\d/g, \"*\"))\n\n// ---- Invertir una cadena ----\nconsole.log(nombreCompleto.split(\"\").reverse().join(\"\"))\n\n// ---- Contar la cantidad de veces que se repite una letra ----\nconsole.log(nombreCompleto.split(\"a\").length - 1)\n\n\n\nfunction analizarPalabras(Primera, segunda) {\n   anagramas(Primera, segunda)\n   sonPalindromos(Primera, segunda)\n   Isogramas(Primera, segunda)\n}\n\nfunction anagramas(Primera, segunda) {\n   let palabraInertida = Primera.toLowerCase().split(\"\").reverse().join(\"\");\n   if (palabraInertida === segunda.toLowerCase()) {\n      console.log(`Las palabras ${Primera} y ${segunda} son anagramas`);\n   } else {\n      console.log(`Las palabras ${Primera} y ${segunda} no son anagramas`);\n   }\n}\n\nfunction palindromo(palabra) {\n   let normal = palabra.toLowerCase();\n   let invertida = normal.split(\"\").reverse().join(\"\");\n   return invertida === normal\n}\n\nfunction sonPalindromos(palabra1, palabra2) {\n   if (palindromo(palabra1) && palindromo(palabra2)) {\n      console.log(`Las palabras ${palabra1} y ${palabra2} son palíndromos`);\n   } else{\n      console.log(`Las palabras ${palabra1} y ${palabra2} no son palíndromos`);\n   }\n}\n\n\nfunction esIsograma(palabra){\n   let letras = new Set();\n    let normalizada = palabra.toLowerCase(); \n    \n    for (let letra of normalizada) {\n        if (letras.has(letra)) {\n            return false; \n        }\n        letras.add(letra);\n    }\n    return true;\n}\n\nfunction Isogramas(primera, segunda) {\n   if (esIsograma(primera) && esIsograma(segunda)) {\n      console.log(`Las palabras ${primera} y ${segunda} son Isogramas`);\n   }\n   else {\n      console.log(`Las palabras ${primera} y ${segunda} no son Isogramas`);\n   }\n}\n  \nanalizarPalabras(\"murcielago\" , \"hola\")\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/Vixito.js",
    "content": "let str = \"zzz\";\n\n// INSTRUCCIONES EN EL OUTPUT\nconsole.log(\"Acceso al carácter específico\\n\" + str[0]);\nconsole.log(str.charAt(1));\nconsole.log(\"\\nSubcadena: \" + str.substring(0, 2));\nconsole.log(\"\\nLongitud: \" + str.length);\nconsole.log(\"\\nConcatenación: \" + str.concat(\" sadasd\"));\nconsole.log(\"\\nRepetición: \" + str.repeat(4));\nconsole.log(\"\\nRecorrido: \");\nfor (let char of str){console.log(char);}\nconsole.log(\"\\nConversión a mayúsculas: \" + str.toUpperCase());\nconsole.log(\"\\nConversión a minúsculas: \" + str.toLowerCase());\nconsole.log(\"\\nReemplazo\\n\" + str.replace(\"zz\", \"xd\"));\nconsole.log(str.replaceAll(\"xd\", \"zzz\"));\nconsole.log(\"\\nDivisión: \" + str.split(\"\"));\nconsole.log(\"\\nUnión: \" + str.split(\"\").join(\"-\"));\nconsole.log(`\\nInterpolación:\\nEl string ${str} tiene ${str.length} carácteres`);\nconsole.log(\"\\nVerificación con\\nincludes: \" + str.includes(\"z\"));\nconsole.log(\"startsWith: \" + str.startsWith(\"xd\"));\nconsole.log(\"endsWith: \" + str.endsWith(\"z\"));\nconsole.log(\"\\nElimina los espacios en blanco...\\n\" + str.trim());\nconsole.log(\"al comienzo del string: \" + str.trimStart());\nconsole.log(\"al final del string: \" + str.trimEnd());\nconsole.log(\"\\nExtrae parte del string y lo retorna como nuevo string: \" + str.slice(1, 3));\nconsole.log(\"\\nBusca una coincidencia entre una expresión regular y el string: \" + str.search(\"xd\"));\nconsole.log(\"\\nRetorna índice donde se indica un carácter\\nprimer índice: \" + str.indexOf(\"z\"));\nconsole.log(\"último índice: \" + str.lastIndexOf(\"z\") + \"\\n\");\n\n\n\n// DIFICULTAD EXTRA\n\n/* PALÍNDROMOS */\n\nfunction Palindromo(str){\n    // Convertir a string (en lo demás es sensible)\n    str = String(str);\n    return str === str.split('').reverse().join('');\n}\n\nconsole.log(Palindromo(\"zzz\")); // true\n\n/* Anagrama */\n\nfunction Anagrama(str1, str2) {\n    // Eliminar espacios y convertir a minúsculas\n    str1 = str1.replace(/\\s+/g, '').toLowerCase();\n    str2 = str2.replace(/\\s+/g, '').toLowerCase();\n\n    // Convertir a arrays, ordenar y convertir de nuevo a cadenas\n    let arr1 = str1.split('').sort().join('');\n    let arr2 = str2.split('').sort().join('');\n\n    return arr1 === arr2;\n}\n\nconsole.log(Anagrama(\"listen\", \"silent\")); // true\n\n/* Isograma */\n\nfunction Isograma(str) {\n    // Eliminar espacios y convertir a minúsculas\n    str = str.replace(/\\s+/g, '').toLowerCase();\n\n    let letras = new Set();\n\n    for (let char of str) {\n        if (letras.has(char)) {\n            return false; // Si la letra ya está en el conjunto, no es un isograma\n        }\n        letras.add(char);\n    }\n    return true; // Si no se repite ninguna letra, es un isograma\n}\n\nconsole.log(Isograma(\"lumberjacks\")); // true\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/VolumiDev.js",
    "content": "var cadenaTexto = 'Este es el ejemplo para trabajar con cadenas de texto'\n// Mostramos la longitud de la cadena de texto\nconsole.log('La longitud de la cadena de texto es de',cadenaTexto.length, 'caracteres')\n\n// Metodos para acceder a cada uno de los caracteres de la cadena de texto\nconsole.log('Accedemos con el at() al caracter deseado ->', cadenaTexto.at(3))  // Podemos acceder con el at() directamte\nconsole.log('Accedemos con el charAt al caracter deseado ->', cadenaTexto.charAt(3)) \nconsole.log('Accedemos con el charCodeAt(), que nos retorna el codigo UTF-16 ->', cadenaTexto.charCodeAt(3))\nconsole.log('Accedemos como si fuera un array con los [] ->', cadenaTexto[3])\n\n// Metodos para extraer partes de la cadena de texto\nconsole.log('Utilizamos el metodo Slice() ->', cadenaTexto.slice(8,15))\nconsole.log('Utilizamos el metodo Substring() ->', cadenaTexto.substring(8,15))\nconsole.log('Utilizamos el metodo Substr() ->', cadenaTexto.substr(8,15))\n\n// Transformar con lower upper case\nconsole.log('Utilizamos el toLowerCase() para pasarlo a miniscula ->', cadenaTexto.toLowerCase())\nconsole.log('Utilizamos el toLowerCase() para pasarlo a miniscula ->', cadenaTexto.toUpperCase())\n\n// Concatenar varias cadenas de texto.\nvar text1 = 'texto 1'\nvar text2 = 'texto 2'\nconsole.log('Concatenamos las dos cadenas ->', text1.concat(' - ', text2))\n\n// Eliminar los espacios de la cadena de texto\nvar cadenaEspacio = '     contenido de la cadena       '\nconsole.log('Esta es la variable sin modificar ->', cadenaEspacio)\nconsole.log('Eliminamos los espacio del principio y del final de la cadena de texto ->', cadenaEspacio.trim())\nconsole.log('Eliminamos los espacio del principio  de la cadena de texto ->', cadenaEspacio.trimStart())\nconsole.log('Eliminamos los espacio del del final de la cadena de texto ->', cadenaEspacio.trimEnd())\n\n// Añadimos cadena al principio o al final de la variable una determinada cantidad de veces que le pasemos.\nvar numero = '5'\nconsole.log('Le añadimos al principio de la cadena de texto tantos 0 como le indiquemos ->', numero.padStart(3,'0'))\nconsole.log('Le añadimos al fianl de la cadena de texto tantos 0 como le indiquemos ->', numero.padEnd(3,'0'))\n\n// Repetimos un cadena de texto tantas veces como le pasasmos por parametro\nvar rep = 'repetir '\nconsole.log('Vamos a repetir la cadena 4 veces ->', rep.repeat(4))\n\n// Reemplazmos la cadena que le pasamos como parametro por la del siguiente parametro\nvar txt = 'Hola Diego, Diego'\nconsole.log('Reemplazamos \"Diego\" por \"Juan\" ->', txt, '->', txt.replace('Diego','Juan'))\nconsole.log('Reemplazamos \"Diego\" por \"Juan\" ->', txt, '->', txt.replace(/DIEGO/i,'Juan'))\nconsole.log('Reemplazamos \"Diego\" por \"Juan\" ->', txt, '->', txt.replace(/DIEGO/gi,'Juan'))\nvar txt = 'Tenemos un perro que se llama Otto. Es un perro de raza Golden'\nconsole.log('Vamos a cambiar todos los \"perro\" por \"gato\" ->', txt.replaceAll('perro', 'gato'))\n\n// Convertir una cadena de texto en un array\nconsole.log('Vamos a usar el \" \" como caracter de spliteo ->', txt.split(' '))\n\n// Comprobar si una cadena contiene una cadena que le pasamos por parametro.\nconsole.log('Vamos a ver si contiene la \"a\" ->', txt.includes('a'))\nconsole.log('Vamos a ver si contiene la \"w\" ->', txt.includes('w'))\n\n// Dificultad extra\nconst readline = require(\"readline\")\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout\n})\n\nfunction palindromo(p1){\n  let palflag = true\n  let arrayP1 = p1.split('')\n  let array_sin_espacios = [];\n  for(let i=0 ; i < arrayP1.length ; i++){\n    if(arrayP1[i] != ' '){\n      array_sin_espacios.push(arrayP1[i])\n    }\n  }\n\n  for (let i = 0; i < arrayP1.length && palflag == true; i++) {\n    if(array_sin_espacios[i] != array_sin_espacios.reverse()[i]){\n      palflag = false\n    }\n  }\n  if(palflag == true){\n    console.log(`${p1}\\ Es palindromo`)\n  }else{\n    console.log(`${p1}\\ No es palindromo`)\n  }\n}\n\nfunction anagrama(p1 ,p2){\n  let ana_p1 = p1.replace(/\\s+/g,'').toLowerCase()\n  let ana_p2 = p2.replace(/\\s+/g,'').toLowerCase()\n  ana_p1 = ana_p1.split('').sort()\n  ana_p2 = ana_p2.split('').sort()\n  if(ana_p1.length != ana_p2.length){\n    console.log('No son anagrama')\n  }else{\n    ana_p1 = ana_p1.join('')\n    ana_p2 = ana_p2.join('')\n    if(ana_p1 === ana_p2){\n      console.log('Son anagrama')\n    }\n  }\n}\n\nfunction isograma(p1){\n  let iso_flag = true\n  let isoP1 = p1.replace(/\\s+/g,'').toLowerCase()\n  isoP1 = isoP1.split('').sort()\n  for(let i=1 ; i<isoP1.length && iso_flag == true; i++){\n    if(isoP1[i] == isoP1[i-1]){\n      iso_flag = false\n    }\n  }\n  if(iso_flag){\n    console.log(`${p1} es un isograma`)\n  }else{\n    console.log(`${p1} no es un isograma`)\n  }\n}\n\n\nfunction inicio(){\n  rl.question('Introduce una cadena de caracteres\\n', (p1) => {\n    rl.question('Introduce la segunda cadena\\n', (p2) => {\n      p1 = p1.toLowerCase()\n      p2 = p2.toLowerCase()\n      if (p1 == p2){\n        console.log('Ambas palabras tiene que se distintas')\n        inicio()\n      }else{\n        console.log('Palabra 1 =', p1)\n        console.log('Palabra 2 =', p2)\n        palindromo(p1)\n        palindromo(p2)\n        anagrama(p1, p2)\n        isograma(p1)\n        isograma(p2)\n\n        rl.question('Desea cerrar el programa? S/N\\n', (resp) => {\n          resp = resp.toUpperCase()\n          if(resp == 'S'){\n            console.log('Saliendo....')\n            process.exit(0)\n          }else{\n            inicio()\n          }\n        })\n      }\n    })\n  })\n  \n}\n\n  inicio()\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/YgriegaSB.js",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos: un palíndromo se lee igual de izquierda a derecha\n * - Anagramas: dos palabras son anagramas si tienen las mismas letras \n * - Isogramas: palabra en la que no hay letras repetidas\n */\n\n// check Palindromo\nconsole.log('------------------------------------- PALINDROMO -----------------------------------------');\nconst checkPalindromo = (palabra1, palabra2) => {\n    const palabraInvertida = palabra1.split('').reverse().join('');\n    return console.log((palabra2 === palabraInvertida) ? \n        `${palabra1} y ${palabra2} son palíndromos.` : `${palabra1} y ${palabra2} no son palíndromos.`);\n}\n\ncheckPalindromo(\"amor\", \"roma\");\ncheckPalindromo('Ana', 'Ana');\ncheckPalindromo('cama', 'ssdad');\ncheckPalindromo('rapar', 'romparaa');\n\nconsole.log('------------------------------------- ANAGRAMA -----------------------------------------');\n// check Anagram\nconst checkAnagrama = (palabra1, palabra2) => {\n    let isAnagrama = false;\n    for (let i = 0; i < palabra1.length ; i++) {\n        for (let j = 0; j < palabra2.length; j++) {\n            const checkIso = (palabra1, palabra2) => {\n                (palabra1[i] === palabra2[j]) ? isAnagrama = true : isAnagrama = false;\n            }\n            checkIso(palabra1, palabra2);\n        }\n    }\n    return console.log((isAnagrama === true) ? `${palabra1} y ${palabra2} son anagramas` : 'No son anagramas');\n}\n\ncheckAnagrama('llenaba', 'ballena');\ncheckAnagrama('salame', 'melase');\n\nconsole.log('--------------------------------------- ISOGRAMAS --------------------------------------------');\n// check Isogramas\nconst checkIsograma = (palabra1, palabra2) => {\n    const checkLetters = (palabra) => {\n        let letrasVistas = {};\n        for (let i = 0; i < palabra.length; i++) {\n            const letra = palabra[i];\n            if (letrasVistas[letra]) {\n                return false;\n            }\n            letrasVistas[letra] = true;\n        }\n        return true; \n    };\n\n    console.log(checkLetters(palabra1) ? `${palabra1} es un isograma` : `${palabra1} no es un isograma`);\n    console.log(checkLetters(palabra2) ? `${palabra2} es un isograma` : `${palabra2} no es un isograma`);\n};\n\ncheckIsograma('Nicolas', 'Nicole');\ncheckIsograma('Andres', 'Caca');\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/Zunigaj1101.js",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\n *   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\n *   interpolación, verificación...\n */\n\n// Concatenacion\nlet myName = 'Jose'\nconsole.log ('Hola ' + myName  + ' Buenas noches')\n\n// Acceso a Caracteres especificos\nconsole.log (myName.indexOf('e')) // para indentificar en indice del caracter\nconsole.log (myName[3]) // para mostrar el caracter\nconsole.log (myName.charAt(3)) // para mostrar el caracter\n\n// Subcadenas\nconsole.log (myName.includes('se')) // para saber si incluye la subcadena\nconsole.log (myName.indexOf('se')) // en que indice empieza\nconsole.log(myName.slice(2,4)) // se indica donde empieza, y donde termnina\nconsole.log(myName.substring(2,4)) // se indica donde empieza, y donde termnina\n\n// Longitud\nconsole.log (myName.length) // para saber la longitud de la cadena\n\n// Repeticion\nconsole.log (myName.repeat(2)) // indica cuantas veces se repite\n\n// Recorrido\nfor (i = 0; i < myName.length; i++) {\n    console.log (myName.charAt(i))\n}\n\n// Conversión a mayúsculas y minúsculas\nconsole.log(myName.toUpperCase()) // Covierte en mayusculas\nconsole.log(myName.toLowerCase()) // Convierte en minisculas\n\n// Reemplazo\nconsole.log (myName.replace('se', '  si lo reemplaza')) // reemplaza una cadena por otra\n\n// División\nlet phrase = \"Hola Jose Buenas noches\"\nlet words = phrase.split(' ') // divide la cadena en un array de palabras y devuelve un array\nconsole.log(words)\n\n// Unión\nlet joinedPhrase = words.join(' ') // une el array de palabras en una cadena\nconsole.log(joinedPhrase)\n\n// Interpolación\nlet greeting = `Hola ${myName}, ¿cómo estás?` // usa template literals para interpolar variables\nconsole.log(greeting)\n\n// Verificación\nconsole.log(myName.startsWith('Jo')) // verifica si la cadena empieza con 'Jo'\nconsole.log(myName.endsWith('se')) // verifica si la cadena termina con 'se'\nconsole.log(myName.includes('os')) // verifica si la cadena incluye 'os'\n\n// * DIFICULTAD EXTRA (opcional):\n// * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n// * para descubrir si son:\n// * - Palíndromos\n// * - Anagramas\n// * - Isogramas\n\nlet word = 'amor22'\nlet word2 = 'roma'\n\nfunction checkPalindromo(word1, word2) {\n    const reverseWord = word1.split ('').reverse().join('')\n    let result = reverseWord === word2 ? 'Son un palindromo': 'No son un palidromo'\n    console.log (`${word1} y ${word2} ${result}`)\n};\ncheckPalindromo (word, word2);\n\nconst checkAnagrama = (word1, word2) => {\n    const check = (str) => {\n        return str.split('').sort().join(\"\");\n    }\n    let result = check (word1) === check (word2) ? 'Son un anagrama': 'No son un anagrama'\n    console.log (`${word1} y ${word2} ${result}`)\n}\n\ncheckAnagrama (word,word2);\n\nconst checkIsogramas = (word1, word2) => {\n    const check = (str) => {\n        let setWord = new Set (str)\n        return new Array (...setWord).join('')\n    } \n    let result = check (word1) === word1 ? 'Es un Isograma': 'No es un Isograma'\n    return console.log (`${word1} ${result}`)\n}\n\ncheckIsogramas (word, word2);"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/aarxnmendez.js",
    "content": "// Ejemplos de operaciones con cadenas de caracteres en JavaScript\r\n\r\nlet cadena = \"Hola Mundo\";\r\n\r\n// Acceso a caracteres específicos\r\nconsole.log(cadena[0]); // H\r\nconsole.log(cadena.charAt(1)); // o\r\n\r\n// Subcadenas\r\nconsole.log(cadena.substring(0, 4)); // Hola\r\nconsole.log(cadena.slice(5)); // Mundo\r\n\r\n// Longitud\r\nconsole.log(cadena.length); // 10\r\n\r\n// Concatenación\r\nlet cadena2 = \" ¡Bienvenidos!\";\r\nconsole.log(cadena + cadena2); // Hola Mundo ¡Bienvenidos!\r\n\r\n// Repetición\r\nconsole.log(cadena.repeat(2)); // Hola MundoHola Mundo\r\n\r\n// Recorrido\r\nfor (let char of cadena) {\r\n    console.log(char);\r\n}\r\n\r\n// Conversión a mayúsculas y minúsculas\r\nconsole.log(cadena.toUpperCase()); // HOLA MUNDO\r\nconsole.log(cadena.toLowerCase()); // hola mundo\r\n\r\n// Reemplazo\r\nconsole.log(cadena.replace(\"Mundo\", \"JavaScript\")); // Hola JavaScript\r\n\r\n// División\r\nlet palabras = cadena.split(\" \");\r\nconsole.log(palabras); // [\"Hola\", \"Mundo\"]\r\n\r\n// Unión\r\nconsole.log(palabras.join(\", \")); // Hola, Mundo\r\n\r\n// Interpolación\r\nlet nombre = \"Juan\";\r\nconsole.log(`Hola, ${nombre}`); // Hola, Juan\r\n\r\n// Verificación\r\nconsole.log(cadena.includes(\"Mundo\")); // true\r\nconsole.log(cadena.startsWith(\"Hola\")); // true\r\nconsole.log(cadena.endsWith(\"Mundo\")); // true\r\n\r\n// Dificultad extra: Programa para analizar dos palabras\r\n\r\nfunction esPalindromo(palabra) {\r\n    let invertida = palabra.split('').reverse().join('');\r\n    return palabra === invertida;\r\n}\r\n\r\nfunction sonAnagramas(palabra1, palabra2) {\r\n    let sorted1 = palabra1.split('').sort().join('');\r\n    let sorted2 = palabra2.split('').sort().join('');\r\n    return sorted1 === sorted2;\r\n}\r\n\r\nfunction esIsograma(palabra) {\r\n    let letras = new Set(palabra);\r\n    return letras.size === palabra.length;\r\n}\r\n\r\nlet palabra1 = \"amor\";\r\nlet palabra2 = \"roma\";\r\n\r\nconsole.log(`¿\"${palabra1}\" es un palíndromo? ${esPalindromo(palabra1)}`);\r\nconsole.log(`¿\"${palabra2}\" es un palíndromo? ${esPalindromo(palabra2)}`);\r\nconsole.log(`¿\"${palabra1}\" y \"${palabra2}\" son anagramas? ${sonAnagramas(palabra1, palabra2)}`);\r\nconsole.log(`¿\"${palabra1}\" es un isograma? ${esIsograma(palabra1)}`);\r\nconsole.log(`¿\"${palabra2}\" es un isograma? ${esIsograma(palabra2)}`);"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/adrs1166ma.js",
    "content": "/*\nEJERCICIO:\nMuestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\nen tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n- Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n  conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n*\nDIFICULTAD EXTRA (opcional):\nCrea un programa que analice dos palabras diferentes y realice comprobaciones\npara descubrir si son:\n- Palíndromos\n- Anagramas\n- Isogramas\n*/\n\n// 🔥 Acceso a caracteres específicos\nconst texto = \"JavaScript\";\nconsole.log(\"Primer carácter:\", texto[0]); // J\nconsole.log(\"Último carácter:\", texto[texto.length - 1]); // t\n\n// 🔥 Subcadenas\nconsole.log(\"Subcadena (índice 0 a 4):\", texto.slice(0, 4)); // Java\nconsole.log(\"Subcadena desde índice 4:\", texto.substring(4)); // Script\n\n// 🔥 Longitud\nconsole.log(\"Longitud de la cadena:\", texto.length); // 10\n\n// 🔥 Concatenación\nconst saludo = \"Hola\";\nconst lenguaje = \"Mundo\";\nconsole.log(\"Concatenación:\", saludo + \" \" + lenguaje); // Hola Mundo\nconsole.log(\"Concatenación con template string:\", `${saludo} ${lenguaje}`); // Hola Mundo  - con Backtick \n\n// 🔥 Repetición\nconsole.log(\"Repetición:\", \"JS \".repeat(3)); // JS JS JS \n\n// 🔥 Recorrido\nfor (let char of texto) {\n    console.log(char); // Imprime cada carácter de \"JavaScript\"\n}\n\n// 🔥 Conversión a mayúsculas y minúsculas\nconsole.log(\"Mayúsculas:\", texto.toUpperCase()); // JAVASCRIPT\nconsole.log(\"Minúsculas:\", texto.toLowerCase()); // javascript\n\n// 🔥 Reemplazo\nconsole.log(\"Reemplazo:\", texto.replace(\"Script\", \"Code\")); // JavaCode\n\n// 🔥 División\nconsole.log(\"División:\", texto.split(\"a\")); // [\"J\", \"v\", \"Script\"]\n\n// 🔥 Unión\nconst palabras = [\"Hola\", \"Mundo\"];\nconsole.log(\"Unión:\", palabras.join(\" \")); // Hola Mundo\n\n// 🔥 Interpolación\nconst nombre = \"Alice\";\nconsole.log(`Hola, me llamo ${nombre}`); // Hola, me llamo Alice\n\n// 🔥 Verificación\nconsole.log(\"Incluye 'Java':\", texto.includes(\"Java\")); // true\nconsole.log(\"Empieza con 'Java':\", texto.startsWith(\"Java\")); // true\nconsole.log(\"Termina con 'Script':\", texto.endsWith(\"Script\")); // true\n\n// 🔥 Eliminación de espacios en blanco\nconst frase = \"   Espacios alrededor   \";\nconsole.log(\"Trim:\", frase.trim()); // \"Espacios alrededor\"\n\n// 🔥 Búsqueda de posición\nconsole.log(\"Índice de 'S':\", texto.indexOf(\"S\")); // 4\nconsole.log(\"Última aparición de 'a':\", texto.lastIndexOf(\"a\")); // 3\n\n// 🔥 Extra \nfunction analizarPalabras(palabra1, palabra2) {\n    /*\n    Palíndromos : Una palabra es igual cuando se lee de izquierda a derecha y viceversa.\n    Anagramas : Dos palabras contienen exactamente las mismas letras, pero en diferente orden.\n    Isogramas : Una palabra no tiene letras repetidas.\n    */\n\n    const normalizar = (str) => str.replace(/\\s+/g, \"\").toLowerCase();\n\n    // Si una palabra es palíndromo\n    const esPalindromo = (palabra) => {\n        const normalizada = normalizar(palabra);\n        return normalizada === normalizada.split(\"\").reverse().join(\"\");\n    };\n\n    // Si dos palabras son anagramas\n    const sonAnagramas = (palabra1, palabra2) => {\n        const normalizada1 = normalizar(palabra1).split(\"\").sort().join(\"\");\n        const normalizada2 = normalizar(palabra2).split(\"\").sort().join(\"\");\n        return normalizada1 === normalizada2;\n    };\n\n    // Si una palabra es isograma\n    const esIsograma = (palabra) => {\n        const letras = normalizar(palabra).split(\"\");\n        return new Set(letras).size === letras.length;\n    };\n\n    console.log(`${palabra1} es palíndromo:`, esPalindromo(palabra1));\n    console.log(`${palabra2} es palíndromo:`, esPalindromo(palabra2));\n    console.log(`${palabra1} y ${palabra2} son anagramas:`, sonAnagramas(palabra1, palabra2));\n    console.log(`${palabra1} es isograma:`, esIsograma(palabra1));\n    console.log(`${palabra2} es isograma:`, esIsograma(palabra2));\n}\n\nanalizarPalabras(\"radar\", \"anagram\");"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/agusrosero.js",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\nlet miCadena = \"Hola Mundo!\";\n\n// Acceso a caracteres\nlet accederCadena = miCadena[1];\nconsole.log(accederCadena);\n\n// Longitud\nlet longitud = miCadena.length;\nconsole.log(longitud);\n\n// Concatenación\nlet concatenacion = miCadena + \" Javascript\";\nconsole.log(concatenacion);\n\n// Repetición\nlet repeticion = miCadena.repeat(5);\nconsole.log(repeticion);\n\n// Recorrido\nfor (let i = 0; i < miCadena.length; i++) {\n  console.log(miCadena[i]);\n}\n\n// Mayúscula\nlet mayuscula = miCadena.toUpperCase();\nconsole.log(mayuscula);\n\n// Minúscula\nlet minuscula = miCadena.toLowerCase();\nconsole.log(minuscula);\n\n// Reemplazo\nlet reemplazo = miCadena.replace(\"Mundo\", \"Javascript\");\nconsole.log(reemplazo);\n\n// División\nlet division = miCadena.split(\"\");\nconsole.log(division);\n\n// Unión\nlet caracteres = [\"a\", \"b\", \"c\", \"d\"];\nlet union = caracteres.join(\"\");\nconsole.log(union);\n\n// Interpolación\nlet nombre = \"Hernan\";\nconsole.log(`Mi nombre es ${nombre}`);\n\n// Verificación\nlet verificacion = miCadena.includes(\"Hola\");\nconsole.log(verificacion);\n\n// DIFICULTAD EXTRA:\nfunction esPalindromo(str1) {\n  return str1 === str1.split(\"\").reverse().join(\"\");\n}\n\nconsole.log(esPalindromo(\"radar\"));\n\nfunction esAnagrama(str1, str2) {\n  let cadena1 = str1.toLowerCase();\n  let cadena2 = str2.toLowerCase();\n\n  if (cadena1.length !== cadena2.length) {\n    return false;\n  }\n\n  let ordenada1 = cadena1.split(\"\").sort().join(\"\");\n  let ordenada2 = cadena2.split(\"\").sort().join(\"\");\n\n  return ordenada1 === ordenada2;\n}\n\nconsole.log(esAnagrama(\"amor\", \"roma\"));\n\nfunction esIsograma(str1) {\n  let letras = str1.toLowerCase().split(\"\").sort();\n  for (let i = 1; i < letras.length; i++) {\n    if (letras[i] === letras[i - 1]) {\n      return false;\n    }\n  }\n  return true;\n}\n\nconsole.log(esIsograma(\"murcielago\"));\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/alexdevrep.js",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\n *   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\n *   interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\n// Creamos una cadena de texto\nlet mi_cadena = \"Soy una cadena de texto\"\nconsole.log(mi_cadena)\n\n//Acceso a caracteres específicos\nlet caracterY =console.log(mi_cadena[2])\n\n//Longitud de una cadena de texto\nlet longitud = console.log(mi_cadena.length)\n\n// Contatenación de cadenas de texto\nlet cadenaNueva= \"y estoy creada por alexdevrep\"\nlet cadenaConcatenada = console.log(mi_cadena+\" \"+cadenaNueva)\n\n//Repetición de una cadena de texto\nlet cadenaRepetida = console.log(mi_cadena.repeat(3))\n\n//Recorrido de una cadena de texto\nfor (i=0;i<mi_cadena.length;i++){\n    console.log(mi_cadena[i])\n\n}\n\n//Conversión a minúsculas\nlet cadena_minus = console.log(mi_cadena.toLowerCase())\n\n//Conversión a mayúsculas\nlet cadena_mayus = console.log(mi_cadena.toUpperCase())\n\n//Reemplazo de caracteres\nmi_cadena = mi_cadena.replace (\"Soy\",\"I´m\")\nconsole.log(mi_cadena)\n\n//División de una cadena de texto\nmi_cadena = mi_cadena.slice(8)\nconsole.log(mi_cadena)\n\n//Unión de cadenas de texto\nlet cadenasDivididas = [\"a\",\"b\",\"c\"]\nlet cadenaUnida = console.log(cadenasDivididas.join(\"-\"))\n\n//Interpolación de cadenas de texto\nsuma = 1+2\nconsole.log(`El resultado de la suma es ${suma}`)\n\n//Verificación de las cadenas de texto\nlet contiene = console.log(mi_cadena.includes(\"texto\"))\n\n\n//Dificultad extra\n\n/*\n* DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isograma\n\n*/\n\n\nfunction palabra3invertida(palabra3){\n    palabra3reverse = palabra3.split(\"\").reverse().join(\"\")\n    return palabra3reverse\n}\n\n\nfunction palabra4invertida(palabra4){\n    palabra4reverse = palabra4.split(\"\").reverse().join(\"\")\n    return palabra4reverse\n}\n\n\n\nfunction palindromo(inversion3,inversion4){\n   \n    if (inversion3 === palabra3){\n        console.log(\"Esta palabra es un palíndromo\")\n    }\n    else{\n        console.log (\"Esta palabra no es un palíndromo\")\n    }\n    if (inversion4 === palabra4){\n        console.log(\"Esta palabra es un palíndromo\")\n    }\n    else{\n        console.log (\"Esta palabra no es un palíndromo\")\n    }\n}\n\nfunction Anagrama (palabra3, palabra4){\n    let array3 = palabra3.split(\"\").sort().join(\"\")\n    let array4 = palabra4.split(\"\").sort().join(\"\")\n    \n    if (array3 === array4){\n        console.log(\"Estas palabras son anagramas\")\n    }\n    else{\n        console.log(\"Estas palabras no son un anagrama\")\n    }\n\n}\n\nfunction Isograma(palabra3,palabra4){\n    let palabra3set = palabra3.split(\"\")\n    let palabra4set = palabra4.split(\"\")\n    let set3 = [...new Set (palabra3)]\n    let set4 = [...new Set (palabra4)]\n    console.log(set3)\n    console.log(palabra3set)\n    console.log(set4)\n    console.log(palabra4set)\n    \n    if (set3.length == palabra3set.length){\n        console.log(\"Esta palabra es un isograma\")\n    }\n    else{\n        console.log(\"Esta palabra no es un isograma\")\n    }\n    if (set4.length == palabra4set.length){\n        console.log(\"Esta palabra es un isograma\")\n    }\n    else{\n        console.log(\"Esta palabra no es un isograma\")\n    }\n        \n\n}\n\n\nconst prompt = require('prompt-sync')()\nlet palabra3 = prompt(\"Introduce la primera palabra al sistema: \")\nlet palabra4 = prompt(\"Introduce la segunda palabra al sistema: \")\ninversion3 = palabra3invertida(palabra3)\ninversion4 = palabra4invertida(palabra4)\npalindromo(inversion3,inversion4,palabra3,palabra4)\nAnagrama(palabra3,palabra4)\nIsograma(palabra3,palabra4)\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/andresgcastillo.js",
    "content": "// Crear una cadena de caracteres\nlet cadena = \"Hola Mundo\";\n\n// Acceso a caracteres específicos\nlet primerCaracter = cadena[0]; // \"H\"\n\n// Subcadenas\nlet subcadena = cadena.substring(0, 4); // \"Hola\"\n\n// Longitud\nlet longitud = cadena.length; // 10\n\n// Concatenación\nlet cadenaConcatenada = cadena + \", ¿Cómo estás?\"; // \"Hola Mundo, ¿Cómo estás?\"\n\n// Repetición\nlet cadenaRepetida = cadena.repeat(2); // \"Hola MundoHola Mundo\"\n\n// Recorrido\nfor (let i = 0; i < cadena.length; i++) {\n  console.log(cadena[i]);\n}\n\n// Conversión a mayúsculas\nlet mayusculas = cadena.toUpperCase(); // \"HOLA MUNDO\"\n\n// Conversión a minúsculas\nlet minusculas = cadena.toLowerCase(); // \"hola mundo\"\n\n// Reemplazo\nlet cadenaReemplazada = cadena.replace(\"Mundo\", \"Andres\"); // \"Hola Andres\"\n\n// División\nlet cadenaDividida = cadena.split(\" \"); // [\"Hola\", \"Mundo\"]\n\n// Unión\nlet cadenaUnida = cadenaDividida.join(\"-\"); // \"Hola-Mundo\"\n\n// Interpolación\nlet nombre = \"Andres\";\nlet cadenaInterpolada = `Hola ${nombre}`; // \"Hola Andres\"\n\n// Verificación\nlet contiene = cadena.includes(\"Mundo\"); // true\n\n//Dificultad Extra\n\nfunction esPalindromo(palabra) {\n  let palabraReversa = palabra.split(\"\").reverse().join(\"\");\n  return palabra === palabraReversa;\n}\n\nfunction esAnagrama(palabra1, palabra2) {\n  let ordenarPalabra = (palabra) => palabra.toLowerCase().split(\"\").sort().join(\"\");\n  return ordenarPalabra(palabra1) === ordenarPalabra(palabra2);\n}\n\nfunction esIsograma(palabra) {\n  let letras = palabra.toLowerCase().split(\"\");\n  let unicas = [...new Set(letras)];\n  return letras.length === unicas.length;\n}\n\nlet palabra1 = \"anagram\";\nlet palabra2 = \"nagaram\";\n\nconsole.log(`Las palabras son ${palabra1} y ${palabra2}`);\n\nconsole.log(`¿Son palíndromos?`);\nconsole.log(`Palabra 1: ${esPalindromo(palabra1)}`);\nconsole.log(`Palabra 2: ${esPalindromo(palabra2)}`);\n\nconsole.log(`¿Son anagramas? ${esAnagrama(palabra1, palabra2)}`);\n\nconsole.log(`¿Son isogramas?`);\nconsole.log(`Palabra 1: ${esIsograma(palabra1)}`);\nconsole.log(`Palabra 2: ${esIsograma(palabra2)}`);\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/bernatcs.js",
    "content": "// ** EJERCICIO\n\n// Acceso a caracteres específicos\nlet str = \"Hola\"\nstr.charAt(1) // \"o\"\nstr[1] // \"o\"\n\n// Longitud\nstr.length // 4\n\n// Subcadenas\nstr.substring(1, 3) // \"ol\"\nstr.slice(1, 3) // \"ol\"\n\n// Concatenación\nlet str2 = \" Mundo\"\nstr + str2 // \"Hola Mundo\"\nstr.concat(str2); // \"Hola Mundo\"\n`Hola,${str2}` // \"Hola, Mundo\"\n\n// Repetición\nstr.repeat(2) // \"HolaHola\"\n\n// Recorrido\nfor (let char of str) {\n  (char); // 'H', 'o', 'l', 'a'\n}\n\n// Conversión a mayúsculas y minúsculas\nstr.toUpperCase() // \"HOLA\"\nstr.toLowerCase() // \"hola\"\n\n// Reemplazo\nstr.replace(\"a\", \"o\") // \"Holo\"\n\"banana\".replace(\"a\", \"o\") // \"bonana\"\n\"banana\".replaceAll(\"a\", \"o\") // \"bonono\"\n\n// Separación\nstr.split(\"\") // [\"H\", \"o\", \"l\", \"a\"]\nstr.split(\"\", 2) // [\"H\", \"o\"]\n\n// Unión\nlet arr = [\"H\", \"o\", \"l\", \"a\"];\narr.join(\"\") // \"Hola\"\n\n// Verificación\nstr.includes(\"ol\") // true\nstr.startsWith(\"Ho\") // true\nstr.endsWith(\"la\") // true\n\n// Búsqueda\nstr.indexOf(\"o\") // 1\nstr.lastIndexOf(\"o\") // 1\nstr.search(/o/) // 1\n\n// Eliminación de espacios\nlet strWithSpaces = \"  Hola  \";\nstrWithSpaces.trim() // \"Hola\"\nstrWithSpaces.trimStart() // \"Hola  \"\nstrWithSpaces.trimEnd() // \"  Hola\"\n\n// Conversión\nlet num = 123;\nString(num) // \"123\"\nnum.toString() // \"123\"\n\n// Comparación\n\"a\".localeCompare(\"a\") // 0\n\"a\".localeCompare(\"b\") // -1\n\"a\".localeCompare(\"1\") // 1\n\n// Extracción de códigos Unicode\nstr.charCodeAt(1) // 111\n\n// Otros\nstr.padStart(6, \"0\") // \"00Hola\"\nstr.padEnd(6, \"0\") // \"Hola00\"\nString.fromCharCode(72, 111, 108, 97) // \"Hola\"\n\n// ** EXTRA ** ----------------------------------------------------------------------------------------------------------------------------------------------------------\n\nfunction palindromo(palabra1, palabra2) {\n\n    palabra1 = palabra1.toLowerCase().trim()\n    palabra2 = palabra2.toLowerCase().trim()\n\n    if (palabra1.split(\"\").reverse().join(\"\") == palabra2) {\n        console.log(`Las palabra ${palabra1} y ${palabra2} son palíndromo`)\n    } else {\n        console.log(`La palabra ${palabra1} y ${palabra2} NO son palíndromo`)\n    }\n}\n\nfunction analgamas(palabra1, palabra2) {\n\n    palabra1 = palabra1.toLowerCase().trim()\n    palabra2 = palabra2.toLowerCase().trim()\n\n    if (palabra1.split(\"\").sort().join(\"\") == palabra2.split(\"\").sort().join(\"\")) {\n        console.log(`Las palabras ${palabra1} y ${palabra2} son anagramas`)\n    } else {\n        console.log(`Las palabras ${palabra1} y ${palabra2} NO son anagramas`)\n    }\n}\n\nfunction isograma(palabra) {\n    palabra = palabra.toLowerCase().trim()\n    let set = new Set(palabra.split(\"\"))\n    if (palabra.split(\"\").length == set.size) {\n        console.log(`La palabra ${palabra} es un isograma, no contiene letras repetidas`)\n    } else {\n        console.log(`La palabra ${palabra} NO es un isograma, contiene letras repetidas`)\n    }\n}\n\nconst readline = require('readline').createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nfunction comprobacionPalabras(){\n    readline.question('Este programa va a comparar dos palabras. Introduce la primera palabra: ', (palabra1) => {\n        readline.question('Introduce la segunda palabra: ', (palabra2) => {\n            readline.question('¿Cómo las quieres comparar?\\n[Palíndromos] - [Anagramas] - [Isogramas] ', (respuesta) => {\n                switch (respuesta.toLowerCase()) {\n                    case 'palíndromos':\n                        palindromo(palabra1, palabra2)\n                        comprobacionPalabras();\n                        break;\n                    case 'anagramas':\n                        analgamas(palabra1, palabra2)\n                        comprobacionPalabras();\n                        break;\n                    case 'isogramas':\n                        isograma(palabra1)\n                        isograma(palabra2)\n                        comprobacionPalabras();\n                        break;\n                    default:\n                        console.error(`No reconocí \"${respuesta}\".`);\n                        comprobacionPalabras();\n                }\n            });\n        });\n    });\n}\n\ncomprobacionPalabras()\n\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/caterinarodriguezdev.js",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\n *   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\n *   interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\nconst miStr = 'Loki es mi mi perro ';\nconsole.log(miStr.replace('mi', 'nuestro'));\nconsole.log(miStr.replaceAll('mi', 'nuestro'));\n\nconsole.log(miStr.split(' '));\n\nconst trimmed = miStr.trim().length;\n\nconsole.log(`trimmed tiene length ${trimmed}, sin trimmed ${miStr.length}`);\n\nconsole.log(miStr.includes('Loki'));\n\nconsole.log(miStr.concat('inteligente'));\n\nconsole.log(miStr.toUpperCase());\n\nconsole.log(miStr.toLocaleLowerCase());\n\nconsole.log(miStr.startsWith('oki', 1));\n\nconsole.log(miStr.slice(1, 3));\n\nconsole.log(miStr.search('/d'));\n\nconsole.log(miStr.repeat(2));\n\nconsole.log(miStr.padStart(30, 'relleno'));\n\nconst isPalindroma = (word) => {\n\n    const wordArr = word.split('');\n    const wordArrReverse = word.split('').reverse();\n\n    for (let i = 0; i < wordArr.length; i++) {\n        if (wordArr[i] !== wordArrReverse[i]) {\n            console.log('no es palindroma');\n            return;\n        }\n    }\n    console.log('es palindroma');\n}\n\nisPalindroma('oso')\n\nconst isAnagrama = (word1, word2) => {\n\n    const word1Arr = word1.split('').sort();\n    const word2Arr = word2.split('').sort();\n\n    for (let i = 0; i < word1Arr.length; i++) {\n        if (word1Arr[i] !== word2Arr[i]) {\n            console.log('no es un anagrama');\n            return;\n        }\n    }\n\n    console.log('es un anagrama');\n}\n\n\nisAnagrama('roma', 'amor');\n\nconst isIsograma = (word) => {\n\n    const set = new Set();\n\n    for (letter in word) {\n        if (set.has(letter)) {\n            console.log('no es un isograma');\n            return;\n        } else {\n            set.add(letter);\n        }\n    }\n\n    console.log('es un isograma');\n}\n\nisIsograma('murcielago');\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/ceciliarava1.js",
    "content": "// ********* Array *********\nlet array = [1, 2, 3, 4]\n\narray.push(5) // Add\narray.pop() // Delete\narray = [5, 6, 2, 8] // Update\narray.sort() // Sort\n\n\n// ********* Set *********\nlet mySet = new Set([1, 2, 3, 4])\n\nmySet.add('Hellooo') // Add\nmySet.delete(1) // Delete\nmySet = [2, 8, 7] // Update\nmySet.sort() // Sort\n\n\n// ********* Map *********\nlet myMap = new Map([\n    ['name', 'Lia'],\n    ['color', 'blue']\n])\n\nmyMap.set('alias', 'li') // Add\nmyMap.delete('alias') // Delete\nmyMap.set('name', 'Mirko') // Update\n\n\n// ********* Object *********\nlet person = {\n    name: 'Matias',\n    age: 10,\n    walk: function () {\n        console.log('Walking')\n    }\n}\n\nperson.color = 'red' // Add\ndelete person.color // Delete\nperson.name = 'Brais' // Update\n\n\n//  DIFICULTAD EXTRA (opcional):\n//  Crea una agenda de contactos por terminal.\n//  - Debes implementar funcionalidades de búsqueda, inserción, actualización y eliminación de contactos.\n//  - Cada contacto debe tener un nombre y un número de teléfono.\n//  - El programa solicita en primer lugar cuál es la operación que se quiere realizar, y a continuación\n//    los datos necesarios para llevarla a cabo.\n//  - El programa no puede dejar introducir números de teléfono no numéricos y con más de 11 dígitos.\n//    (o el número de dígitos que quieras)\n//  - También se debe proponer una operación de finalización del programa.\n// \n\nconst readline = require('readline')\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n})\n\n\nclass Agenda {\n\n    constructor() {\n        this.contacts = []\n    }\n\n    createContact(name, phoneNumber) {\n        console.log('I can create a contact')\n\n        let validation = correctPhoneNumber(phoneNumber)\n        if (validation !== 'Valid phone number') {\n            console.log(validation)\n            return\n        }\n\n        let contactFound = this.contacts.find(contact => contact.name === name) ||\n            this.contacts.find(contact => contact.phoneNumber === phoneNumber)\n\n        if (contactFound) {\n            console.log('Contact already exists')\n        } else {\n            let contact = new Contact(name, phoneNumber)\n            this.contacts.push(contact)\n        }\n    }\n\n    searchContact(name) {\n        console.log('I can search contact', name)\n        let contactFound = this.contacts.find(contact => contact.name === name)\n        if (contactFound) {\n            console.log(`Name: ${contactFound.name}, Phone number: ${contactFound.phoneNumber}`)\n        } else {\n            console.log('Contact not found')\n        }\n    }\n\n    updateContact(name, phoneNumber) {\n        console.log('I can update contact')\n        const index = this.contacts.findIndex(contact => contact.name === name);\n        this.contacts.splice(index, 1, {name}, {phoneNumber})\n    }\n\n    deleteContact(name) {\n        console.log('I can delete contact')\n        const index = this.contacts.findIndex(contact => contact.name === name);\n        if (index !== -1) {\n            this.contacts.splice(index, 1)\n            console.log('Contact deleted')\n        }\n        else {\n            console.log('Contact does not exist')\n        }\n    }\n\n    showContactList() {\n        console.log(this.contacts)\n\n    }\n\n}\n\nclass Contact {\n\n    constructor(name, phoneNumber) {\n        this.name = name\n        this.phoneNumber = phoneNumber\n    }\n\n    showContactData(name) {\n        console.log(`Name: ${this.name}`)\n        console.log(`Phone number: ${this.phoneNumber}`)\n    }\n}\n\nfunction correctPhoneNumber(phoneNumber) {\n    phoneNumber = phoneNumber.toString();\n    let validDigits = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];\n\n    if (phoneNumber.length !== 13) {\n        return 'Invalid number. It must contain 13 digits';\n    }\n\n    for (let i = 0; i < phoneNumber.length; i++) {\n        if (!validDigits.includes(phoneNumber[i])) {\n            return 'Contains non-numeric values';\n        }\n    }\n\n    return 'Valid phone number';\n}\n\n\nfunction showMenu(agenda) {\n\n    console.log('-----------------------')\n    console.log('1. Search contact')\n    console.log('2. Create contact')\n    console.log('3. Update contact')\n    console.log('4. Delete contact')\n    console.log('5. Show contact list')\n    console.log('6. Exit')\n\n\n    rl.question('Choose an option: ', (option) => {\n        console.log('-----------------------')\n\n        switch (option) {\n\n            case '1':\n                rl.question('Name of contact to search: ', (name) => {\n                    agenda.searchContact(name)\n                    showMenu(agenda)\n                })\n                break\n\n            case '2':\n                rl.question('Name of contact to create: ', (name) => {\n                    rl.question(`Phone of ${name} `, (phoneNumber) => {\n                        agenda.createContact(name, phoneNumber)\n                        showMenu(agenda)\n                    })\n                })\n                break\n\n            case '3':\n                rl.question('Name of contact to update: ', (name) => {\n                    rl.question(`New phone of ${name} `, (phoneNumber) => {\n                        agenda.updateContact(name, phoneNumber)\n                        showMenu(agenda)\n                    })\n                })\n                break\n\n            case '4':\n                rl.question('Name of contact to delete: ', (name) => {\n                    agenda.deleteContact(name)\n                    showMenu(agenda)\n                })\n                break\n\n            case '5':\n                agenda.showContactList()\n                showMenu(agenda)\n                break\n\n            case '6':\n                console.log('Bye!')\n                rl.close()\n                break\n\n            default:\n                console.log('Value is not correct')\n                showMenu(agenda)\n        }\n    })\n\n}\n\nfunction main() {\n    let agenda = new Agenda()\n    showMenu(agenda)\n}\n\nmain()\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/cesar-ch.js",
    "content": "// #04 CADENAS DE CARACTERES\n\n// Ejercicio \n\n// Acceso a caracteres específicos\n\nlet cadena = \"Hola, mundo!\";\n\nconsole.log(\"Primer caracter:\", cadena[0]);\nconsole.log(\"Primer caracter:\", cadena.charAt(0));\n\n// Subcadena\n\nlet subcadena = cadena.substring(6, 11);\nconsole.log(\"Subcadena:\", subcadena);\n\n// Longitud de cadena\n\nconsole.log(\"Longitud de la cadena:\", cadena.length);\n\n// Concatenación de cadenas\n\nlet cadena1 = \"Hola\";\nlet cadena2 = \"mundo!\";\n\nlet cadenaConcatenada = cadena1 + \" \" + cadena2;\nconsole.log(\"Cadena concatenada:\", cadenaConcatenada);\n\nlet cadenaConcatenada2 = cadena1.concat(\" \", cadena2);\nconsole.log(\"Cadena concatenada:\", cadenaConcatenada2);\n\n// Repetición\n\nlet cadenaRepetida = cadena.repeat(3);\nconsole.log(\"Cadena repetida:\", cadenaRepetida);\n\n// Recorrido \n\nfor (let i = 0; i < cadena.length; i++) {\n    console.log(\"Carácter en posición\", i, \":\", cadena[i]);\n}\n\n// Conversión a mayúsculas y minúsculas\nconsole.log(\"Mayúsculas:\", cadena.toUpperCase());\nconsole.log(\"Minúsculas:\", cadena.toLowerCase());\n\n// Reemplazo\nlet cadenaReemplazada = cadena.replace(\"mundo\", \"javascript\");\nconsole.log(\"Reemplazo:\", cadenaReemplazada);\n\n// División\nlet palabras = cadena.split(\" \");\nconsole.log(\"División por espacio:\", palabras);\n\n// Unión\nlet nuevaCadenaUnida = palabras.join(\":) \");\nconsole.log(\"Unión con guiones:\", nuevaCadenaUnida);\n\n// Interpolación\n\nlet lenguaje = \"JavaScript\";\nconsole.log(`El lenguaje es ${lenguaje}`);\n\n// Verificación\n\nlet contieneHola = cadena.includes(\"Hola\");\nconsole.log(\"Contiene 'Hola':\", contieneHola);\n\n// Dificultad extra\n\nfunction programa(cadena1, cadena2) {\n    function esPalindromo(cadena1, cadena2) {\n        return cadena1.toLowerCase() === cadena2.split(\"\").reverse().join(\"\").toLowerCase();\n    }\n    console.log(\"Es palíndromo:\", esPalindromo(cadena1, cadena2));\n\n    function esAnagrama(cadena1, cadena2) {\n        return cadena1.toLowerCase().split(\"\").sort().join(\"\") === cadena2.toLowerCase().split(\"\").sort().join(\"\")\n    }\n    console.log(\"Es anagrama:\", esAnagrama(cadena1, cadena2));\n\n    function esIsograma(cadena1, cadena2) {\n        let caracteres = {};\n\n        for (let i = 0; i < cadena1.length; i++) {\n            if (caracteres[cadena1[i].toLowerCase()]) {\n                return false;\n            }\n            caracteres[cadena1[i]] = true;\n        }\n\n        for (let i = 0; i < cadena2.length; i++) {\n            if (caracteres[cadena2[i].toLowerCase()]) {\n                return false;\n            }\n            caracteres[cadena2[i]] = true;\n        }\n\n        return true;\n    }\n    console.log(\"Es isograma:\", esIsograma(cadena1, cadena2));\n}\n\n\nprograma(\"Hola\", \"aloh\");\nprograma(\"Dart\", \"Go\");"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/christian-jfr.js",
    "content": "// #04 CADENAS DE CARACTERES\n\n/**\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n */\nconst hello = 'Hello';\nconst world = 'World';\nconst javascript = ', JavaScript!';\nlet hola = 'Hola';\nconst five = 5;\nconsole.log(five.toString()); // -> '5'\n// .length: Longitud de la cadena\nconsole.log(hello.length); // -> 5\nconsole.log(world.length); // -> 5\nconsole.log(hola.length); // -> 4\n// concatenacion(+)(.concat) e interpolacion(Template Literals ` `)\nconst concat = 'Hello' + ',' + ' ' + 'World!';\nconst interp = `${hello}, ${world}!`;\nconsole.log((hola += javascript)); // -> 'Hola, JavaScript!'\nconsole.log(concat); // -> 'Hello, World!'\nconsole.log(hello, world); // -> 'Hello World'\nconsole.log(hello.concat(javascript)); // -> 'Hello, JavaScript!'\nconsole.log(interp); // -> 'Hello, World!'\nconsole.log(concat.length); // -> 13\nconsole.log(interp.length); // -> 13\nconsole.log(hola.length); // -> 17\n// acceder a un caracter\nconsole.log('Hello'.charAt(0)); // -> 'H'\nconsole.log('Hello'[-1]); // -> undefined\nconsole.log('Hello'[1]); // -> 'e'\nconsole.log('Hello'.charAt(4)); // -> 'o'\nconsole.log('Hello'.charAt(5)); // -> ''\n// verificar y busqueda\nconsole.log('Hello'.startsWith('H')); // -> true\nconsole.log('Hello'.startsWith('h')); // -> false\nconsole.log('Hello'.endsWith('o')); // -> true\nconsole.log('Hello'.endsWith('O')); // -> false\n\nconsole.log('Javascript'.includes('s')); // -> true\nconsole.log('Javascript'.includes('S')); // -> false\n\nconsole.log('welcome'.indexOf('e')); // -> 1\nconsole.log('welcome'.lastIndexOf('e')); // -> 6\n// repetir\nconsole.log('Hello'.repeat(3)); // -> 'HelloHelloHello'\nconsole.log('Hello'.repeat(0)); // -> ''\n// reemplazar\nconsole.log('Hekko'.replace('k', 'l')); // -> 'Helko'\nconsole.log('Hekko'.replaceAll('k', 'l')); // -> 'Hello'\n// Mayúsculas y minúsculas\nconsole.log('Hello'.toUpperCase()); // -> 'HELLO'\nconsole.log('Hello'.toLowerCase()); // -> 'hello'\n// Division y subcadenas\nconsole.log('Dos mil veinticuatro'.split(' ')); // -> ['Dos', 'mil', 'veinticuatro']\nconsole.log('DOS'.split('')); // -> ['D', 'O', 'S']\nconsole.log('DOS'.split('', 1)); // -> ['D']\nconsole.log('Dos mil veinticuatro'.slice(0, 3)); // -> 'Dos'\nconsole.log('Dos mil veinticuatro'.slice(-12)); // -> 'veinticuatro'\nconsole.log('Dos mil veinticuatro'.substring(0, 3)); // -> 'Dos'\n// Mayusculas y minusculas\nconsole.log('Hello'.toUpperCase()); // -> 'HELLO'\nconsole.log('HELLO'.toLowerCase()); // -> 'hello'\n// trim eliminación de espacios (inicio y final)\nconsole.log('    Hello World!     '.trim()); // -> 'Hello World!'\nconsole.log('    Hello World!     '.trimStart()); // -> 'Hello World!     '\nconsole.log('    Hello World!     '.trimEnd()); // -> '    Hello World!'\n// rellenar\nconsole.log('Hello'.padStart(10, '*')); // -> '****Hello'\nconsole.log('Hello'.padEnd(10, '*')); // -> 'Hello****'\n\n/**\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\nfunction main(firstWord, secondWord) {\n\tif (\n\t\ttypeof firstWord !== 'string' ||\n\t\ttypeof secondWord !== 'string' ||\n\t\tfirstWord === '' ||\n\t\tsecondWord === ''\n\t) {\n\t\treturn console.log('Please enter a valid word');\n\t}\n\tpalindrome(firstWord, secondWord);\n\n\tanagram(firstWord, secondWord);\n\n\tisogram(firstWord, secondWord);\n}\n\nfunction palindrome(firstWord, secondWord) {\n\tconst first = firstWord.toLowerCase();\n\tconst second = secondWord.toLowerCase();\n\tfirst === first.split('').reverse().join('')\n\t\t? console.log(`${firstWord} is Palindrome`)\n\t\t: console.log(`${firstWord} is not Palindrome`);\n\n\tsecond === second.split('').reverse().join('')\n\t\t? console.log(`${secondWord} is Palindrome`)\n\t\t: console.log(`${secondWord} is not Palindrome`);\n}\n\nfunction anagram(firstWord, secondWord) {\n\tconst first = firstWord.toLowerCase();\n\tconst second = secondWord.toLowerCase();\n\tconst firstSorted = first.split('').sort().join('');\n\tconst secondSorted = second.split('').sort().join('');\n\tfirstSorted === secondSorted\n\t\t? console.log(`The words ${firstWord} and ${secondWord} are anagrams`)\n\t\t: console.log(`The words ${firstWord} and ${secondWord} are not anagrams`);\n}\n\nfunction isogram(firstWord, secondWord) {\n\tconst first = firstWord.toLowerCase();\n\tconst second = secondWord.toLowerCase();\n\tconst firstSet = new Set(first);\n\tconst secondSet = new Set(second);\n\n\tfirstSet.size === first.length\n\t\t? console.log(`The word ${firstWord} is a First-order Isogram`)\n\t\t: console.log(`The word ${firstWord} is not a First-order Isogram`);\n\n\tsecondSet.size === second.length\n\t\t? console.log(`The word ${secondWord} is a First-order Isogram`)\n\t\t: console.log(`The word ${secondWord} is not a First-order Isogram`);\n}\n\nmain('string', 'number');\nmain('evil', 'live');\nmain('level', 'noon');\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/cmejiajulian.js",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n */\n\n// CREACION DE CADENAS \n\nlet cadena1 = 'Hola Mundo';// Usando comillas simples\nlet cadena2 = \"Hola Mundo\";// Usando comillas dobles \nlet cadena3 = `Hola Mundo`;// Usando comillas invertidas \n\n\n//Concatenacion \n\nconsole.log(cadena1 +' '+ cadena2 +' '+ cadena3);\n\n\n//Propiedades de las cadenas de caracteres \n\n//lenght - devuelve la longitud de la cadena\n\nlet usuario = 'Julian';\nconsole.log(usuario.length) //6\n\n// toUpperCase() - Convierte la cadena a mayusculas \n\nlet videoJuego = ' Assassins creed valhalla '\nconsole.log(videoJuego.toUpperCase());//MODERN WARE\n\n\n//toLowerCase() convierte la cadena a minusculas \n\nlet videoJuego2 = 'CALL OF DUTY '\nconsole.log(videoJuego2.toLowerCase());// call of duty \n\n//charAt(index) - devuelve el caracter en la posicion especificada\n\nlet saludo= 'Hola';\nconsole.log(saludo.charAt(0));//H\n\n/*indexOf(subcadena) - devuelve el índice de la primera aparición \n de la subcadena especificada, o -1 si no se encuentra.*/\n\nlet music = 'Metal Rock Pop';\nconsole.log ( music.indexOf('Rock'));\n\n//substring(inicio,fin) devuelve la palabra segun la posicion indicada\n\nlet mago = 'reconocer';\nconsole.log(mago.substring(9,0));\n\n//split - divide la cadena en un array de subcadenas usando el seperador especificado\n\nlet deporte = 'Natacion Ciclismo Futbol';\nconsole.log(deporte.split());//[Natacion Ciclismo Futbol]\n\n/*replace(buscar, reemplazar)  - reemplaza la primera aparicion de la \nsubcadena especificada*/\n\nlet diosDeLaGuerra = 'Tanos'\nconsole.log(diosDeLaGuerra.replace('Tanos','DIOS'));//DIOS\n\n//trim - elimina los espacios en blanco de la cadena \n\nlet cidadPrincipal = ' New York  '\nconsole.log(cidadPrincipal.trim());\n\n /* Temple Strings (Plantillas de Cadenas de Texto)\nlas comillas invertidas``permiten interpolar variables y expreciones\ndentro de las cadenas asi \n*/\n\nlet firstName = 'Julian';\nlet lastName = 'Batista';\nlet fullName = `Nombre completo: ${firstName} ${lastName}!`\n \nconsole.log(fullName);\n\n\n/*  \n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\nconst readline = require('readline');\n\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout\n});\n\nrl.question('Por favor ingrese la primera palabra: ', (primeraPalabra) => {\n    rl.question('Por favor ingrese la segunda palabra: ', (segundaPalabra) => {\n\n        // Palíndroma\n        const palabrainvertida = (palabra) => {\n            return palabra.split('').reverse().join('');\n        };\n\n        // Anagrama\n        const anagrama = (palabra) => {\n            return palabra.toLowerCase().split('').sort().join('');\n        };\n\n        const esAnagrama = (palabra1, palabra2) => {\n            return anagrama(palabra1) === anagrama(palabra2);\n        };\n\n        // Isograma\n        const palabraUnica = (palabra) => {\n            palabra = palabra.toLowerCase();\n            const letrasUni = new Set();\n\n            for (const letra of palabra) {\n                if (letrasUni.has(letra)) {\n                    return false;\n                }\n                letrasUni.add(letra);\n            }\n            return true;\n        };\n\n        // Comparaciones\n        if (primeraPalabra.toLowerCase() === palabrainvertida(segundaPalabra.toLowerCase())) {\n            console.log('Es palíndroma');\n        } else if (esAnagrama(primeraPalabra, segundaPalabra)) {\n            console.log('Es anagrama');\n        } else if (palabraUnica(primeraPalabra)) {\n            console.log('Es isograma');\n        } else {\n            console.log('No es ninguna');\n        }\n\n        rl.close();\n    });\n});\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/d4-n1.js",
    "content": "// Comparación de caracteres\n///////////////////////////////\nconst a = \"a\"\nconst b = \"B\"\nconsole.log(a < b)\n// Las minúsculas son \"mayores\" que las mayúsculas\nconsole.log(a > b)\n\n// Cambio de case\n///////////////////////////////\nconsole.log(a.toUpperCase())\nconsole.log(b.toLowerCase())\n\n// Longitud\n///////////////////////////////\nconst str = \"Hola mundo\"\nconsole.log(str.length)\n\n// Acceso a caracteres\n///////////////////////////////\nconsole.log(str.charAt(0))\nconsole.log(str[0])\nconsole.log(str.at(0))\n// Valores negativos cuentan desde el final\nconsole.log(str.at(-2))\n\n// Concatenación de strings\n///////////////////////////////\nconsole.log(str.concat(\" \", str))\n\n// Palabras contenidas, inicios y finales\n///////////////////////////////\nconsole.log(str.includes(\"mundo\"))\nconsole.log(str.endsWith(\"mundo\"))\nconsole.log(str.endsWith(\"o\"))\nconsole.log(str.startsWith(\"Hola\"))\nconsole.log(str.startsWith(\"H\"))\n\n// Index de un carácter o palabra\n///////////////////////////////\nconst sentence = \"Mi perro es mayor que tu perro\"\nconsole.log(sentence.indexOf(\"perro\"))\nconsole.log(sentence.indexOf(\"gato\"))\n\n// Último index de un carácter o palabra\n///////////////////////////////\nconsole.log(sentence.lastIndexOf(\"perro\"))\nconsole.log(sentence.lastIndexOf(\"gato\"))\n\n// Pads\n///////////////////////////////\nconsole.log(str.padEnd(20, \".\"))\nconsole.log(str.padStart(15, \">\"))\n\n// Repetición\n///////////////////////////////\nconsole.log(a.repeat(10))\n\n// Reemplazo\n///////////////////////////////\nconsole.log(sentence.replace(\"perro\", \"gato\"))\nconsole.log(sentence.replaceAll(\"perro\", \"gato\"))\n\n// Búsqueda\n///////////////////////////////\nconsole.log(sentence.search(\"perro\"))\nconsole.log(sentence[sentence.search(\"perro\")])\n\n// Slice\n///////////////////////////////\nconsole.log(sentence.slice(25))\nconsole.log(sentence.slice(20, 30))\nconsole.log(sentence.slice(-8))\n\n// Split\n///////////////////////////////\nconsole.log(sentence.split(\" \"))\n\n// Trim\n///////////////////////////////\nconst str2 = \"   Hola   \"\nconsole.log(str2.trim())\nconsole.log(str2.trimEnd())\nconsole.log(str2.trimStart())\n\n// Convertir a string\n///////////////////////////////\nconst number = 92\nconsole.log(typeof number.toString())\n\n///////////////////////////////\n// Dificultad extra\n///////////////////////////////\n\nconst isPalindrome = (word) => {\n  let validation\n\n  for(let i = 0; i < (word.length / 2) - 1; i++) {\n    if(word[i] !== word[word.length - 1 - i]) { return false }\n    else { return true }\n  }\n\n  return validation\n}\n\n\nconst isAnagram = (word1, word2) => {\n  let arr1 = word1.normalize(\"NFD\").replace(/[\\u0300-\\u036f]/g, \"\").split(\"\").sort()\n  let arr2 = word2.normalize(\"NFD\").replace(/[\\u0300-\\u036f]/g, \"\").split(\"\").sort()\n\n  if(arr1.length !== arr2.length) {\n    return false\n  } else {\n    if(arr1.length !== arr2.length) {\n      return false\n    } else {\n      return true\n    }\n  }\n}\n\nconst isIsogram = (word) => {\n  let arr = word.normalize(\"NFD\").replace(/[\\u0300-\\u036f]/g, \"\").split(\"\").sort()\n\n  for (let i = 0; i <= arr.length; i++) {\n    if (arr[i] == arr[i + 1]) {\n      return false\n    } else {\n      return true\n    }\n  }\n}\n\nconsole.log(isPalindrome(\"arenera\"))\nconsole.log(isPalindrome(\"hola\"))\nconsole.log(isAnagram(\"álvaro\", \"valora\"))\nconsole.log(isAnagram(\"hola\", \"mundo\"))\nconsole.log(isIsogram(\"murciélago\"))\nconsole.log(isIsogram(\"arena\"))\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/darkhouselab08.js",
    "content": "/*\n * EJERCICIO #04: CADENAS DE CARACTERES\n * darkhouselab08 (Jorge Franco)\n */\n\n// 1. Definición y longitud de cadenas de texto. \nlet usuario = \"darkhouselab08\";\nlet nombreReal = \"Jorge Franco\";\n\nconsole.log(`Usuario: ${usuario} - Longitud: ${usuario.length}`); \n\n// 2. Acceso a caracteres (lo que practicamos hoy)\nconsole.log(\"Primera letra del usuario:\", usuario[0]); \nconsole.log(\"Última letra del nombre:\", nombreReal.at(-1));\n\n// 3. Transformaciones (Limpieza y Mayúsculas)\nlet entradaSucia = \"   jorge franco   \";\nlet nombreLimpio = entradaSucia.trim().toUpperCase();\nconsole.log(`Nombre normalizado: \"${nombreLimpio}\"`);\n\n// 4. Reemplazo e Interpolación\nlet saludo = \"Hola, bienvenido al reto 03\";\nlet saludoCorregido = saludo.replace(\"03\", \"04\"); // Corregimos el número del reto\nconsole.log(`${saludoCorregido}, ${nombreReal}!`);\n\n// 5. División y Unión (El puente)\nlet habilidades = \"JavaScript, Git, Terminal, Warp\";\nlet arrayHabilidades = habilidades.split(\", \");\nconsole.log(\"Mis herramientas:\", arrayHabilidades);\nconsole.log(\"Lista unida con guiones:\", arrayHabilidades.join(\" - \"));\n\n/* * DIFICULTAD EXTRA: EL ANALIZADOR DE JORGE\n */\n\nfunction analizadorDePalabras(palabra1, palabra2) {\n    \n    // Normalización: quitamos espacios y pasamos a minúsculas\n    const limpiar = (str) => str.toLowerCase().trim();\n    \n    let p1 = limpiar(palabra1);\n    let p2 = limpiar(palabra2);\n\n    // --- 1. PALÍNDROMO ---\n    const esPalindromo = (palabra) => {\n        return palabra === palabra.split(\"\").reverse().join(\"\");\n    };\n\n    // --- 2. ANAGRAMA ---\n    const esAnagrama = (str1, str2) => {\n        if (str1 === str2) return false;\n        return str1.split(\"\").sort().join(\"\") === str2.split(\"\").sort().join(\"\");\n    };\n\n    // --- 3. ISOGRAMA ---\n    const esIsograma = (palabra) => {\n        // Usamos Set para ver si hay letras repetidas\n        return new Set(palabra).size === palabra.length;\n    };\n\n    console.log(`\\n--- RESULTADOS PARA: \"${palabra1}\" y \"${palabra2}\" ---`);\n    console.log(`¿\"${palabra1}\" es Palíndromo?: ${esPalindromo(p1)}`);\n    console.log(`¿Son Anagramas?: ${esAnagrama(p1, p2)}`);\n    console.log(`¿\"${palabra1}\" es Isograma?: ${esIsograma(p1)}`);\n}\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/duendeintemporal.js",
    "content": "/* I use *Professional JavaScript for Web Developers* by Matt Frisbie as a reference to generate accurate comment descriptions and to understand JavaScript's capabilities in string manipulation. I also use GPT to correct some translations, syntax, and grammar.\n*/\n\n//short for console.log\nlet log = console.log.bind(console);\n\n//STRING TYPE\n//The String type is the object representation of strings and is created using the String constructor as follows:\nlet stringObject = new String(\"hello girl\");\n//The methods of a String object are available for all string primitives.\n\n/*Every time a primitive value is read, an object of the corresponding primitive wrapper type is created behind the scenes, allowing access to various methods for manipulating the data. */ \n\nlet q = 'Did you know Internet start as a Pentagon project named ARPANET(Advanced Research Projects Agency Network)?'\nlet q2 = q.substring(12);\nlog(q2); // Internet start as a Pentagon project named ARPANET(Advanced Research Projects Agency Network)?\n\n//The JavaScript Character\n//JavaScript strings consist of 16-bit code units. For most characters, each 16-bit code unit corresponds to a single character. The length property indicates how many 16-bit code units are present in the string\nlet message = \"Sometimes you make me smile...\";\nlog(message.length); // 30\nlog(message.charAt(10)); // y\nlog(message.charCodeAt(10)); // 121\nlog(message.indexOf('m')); // 2\nlog(message.lastIndexOf('m')); // 23\nlet chart = message.lastIndexOf('s');\nlet chart2 = message.indexOf('.');\nlog(message.substring(chart, chart2)); // smile\nlog(message.substring(-8)); // Sometimes you make me smile..\nlog(message.substr(-8)); // smile... (I believe this method may be deprecated)\n\nlog(message.substring(message.length - 8))// smile...\nlet arr = message.substring(0, 8).split('');\nlog(arr)// Array(8) [ \"S\", \"o\", \"m\", \"e\", \"t\", \"i\", \"m\", \"e\" ]  ( no inclusive the last index )\nlog(arr.join('-')); // S-o-m-e-t-i-m-e    \nlog(arr[arr.length - 1].replace('e', 'e-s')); // e-s\nlog(arr.join('-').replaceAll('-', '') + 's'); // Sometimes \n\n//Note: It is important to know that some emojis are composed of two 16-bit code units, so you have to take this into consideration when evaluating or using the length property.\n\nlet fragment = '   at this point in my life...  ';\nlog(fragment.trim()); // Logs: at this point in my life... (without spaces at the begining or at the end)\n\n//Note: you can also use trimStart() or trimEnd()\n\nlet name = 'anna';\nlog(name.toUpperCase()); // ANNA\nlet othername = 'Luna';\nlog(othername.toLowerCase()); // luna\n\n//we can also use String.fromCharCode() method\n\nlog(String.fromCharCode(193, 48, 587, 482, 102, 107)); // Á0ɋǢfk\nlog(String.fromCharCode(0x68fa)); // 棺\n\n//Note: using fromCharCode() may have performance implications, especially if called frequently or with a large number of characters. \n \n/* The normalize() Method. Some Unicode characters can be encoded in more than one way. Sometimes, a character can be represented by either a single BMP character or a surrogate pair. For example, consider the following: */\n\n// U+00C5: Latin capital letter A with ring above\nlog(String.fromCharCode(0x00C5)); // Å\n// U+212B: Angstrom sign\nlog(String.fromCharCode(0x212B)); // Å\n// U+0041: Latin captal letter A\n// U+030A: Combining ring above\nlog(String.fromCharCode(0x0041, 0x030A)); // Å\n\nlet unnormalized_text = String.fromCharCode(0x0041, 0x030A, 0x212B, 0x00C5);\nlog(unnormalized_text.charCodeAt(1), unnormalized_text.charCodeAt(3)); // 778 197\nlet normalized_text = unnormalized_text.normalize();\nlog(normalized_text.charCodeAt(1), normalized_text.charCodeAt(3)); // 197 NaN  (Because the first character is converted from a surrogate pair to a single BMP character, there is no character at charCodeAt(3). After normalization, there are only three characters, all with the same code: 197.)\n\n//Unicode addresses this by providing four normalization forms that allow characters, such as this one, to be normalized into a consistent format, regardless of their character code derivation.\n\n//we can concatenate strings by using the concat() method or the + unary operator\nlet firstName = 'Patty';\nlet lastName = ' Smith';\nlet longName = firstName.concat(lastName);\nlog(longName)// Patty Smith\n//same as\nlog(firstName + lastName); // Patty Smith\n\n//or make use of the previus methods to f.e capitalize a word\nfunction capitalize(str) {\n    return str.charAt(0).toUpperCase() + str.slice(1);\n}\n\nlog(capitalize(name)); // Anna\n\n//There are two methods for locating substrings within another string: indexOf() and lastIndexOf(). Both methods search a string for a given substring and return the position (or –1 if the substring isn’t found).\n\nlet fragment2 = 'the fire is burned, the tables are turned...';\nlog(fragment2.indexOf('is')); // 9 \nlog(fragment2.indexOf('house')); // -1\nlog(fragment2.lastIndexOf('t')); // 35\n\n//String Inclusion Methods\nlog(fragment2.startsWith(\"the\")); // true\nlog(fragment2.endsWith(\"fire\")); // false\n\nlet say = 'oh';\nlog(say.repeat(2) + '!'); // ohoh!\n\n//I think padStart() and padEnd() are deprecated, but we can create our own function to achieve the same result. For example, let's try to emulate the padStart() method.\n\nfunction  addPad(str, width, pad = 0){\n    let result = String(str); \n    while (result.length < width) {\n         result = `${pad}` + result;\n    }\n     return result;\n }\n \n \n log(addPad(4, 3, '#')); // ##4\n log(addPad(56, 3, '$')); // $56\n log(addPad(7, 3)); // 007\n log(addPad('something', 3, '-')); // ---something\n\n const greeting = \"tururuuu\";\n const paddedString = addPad.call(greeting, greeting, 11, \"&\");\n log(paddedString); //  &&&tururuuu\n\n//we can use match() and RegExp() (or regular expression patterns) to evaluate regular expressions in a string, f.e.\n\nfunction toCamelCase(input) {\n    return (\n        input\n            // Replace kebab-case, snake_case, and spaces with a space\n            .replace(/[-_\\s]+(.)?/g, (_, char) => (char ? char.toUpperCase() : ''))\n            // Handle PascalCase\n            .replace(/^[A-Z]/, (char) => char.toLowerCase())\n    );\n}\n\nlog(toCamelCase('PascalCase')); // pascalCase\nlog(toCamelCase('kebab-case-string')); // kebabCaseString\nlog(toCamelCase('snake_case_string')); // snakeCaseString\nlog(toCamelCase('string with spaces')); // stringWithSpaces\n\n\nwindow.addEventListener('load', function(){\n    const body = document.querySelector('body');\n    const title = document.createElement('h1');\n    \n    body.style.setProperty('background', '#000');\n    body.style.setProperty('text-align', 'center');\n    \n    title.textContent = 'Retosparaprogramadores #4.';\n    title.style.setProperty('font-size', '3.5vmax');\n    title.style.setProperty('color', '#fff');\n    title.style.setProperty('line-height', '100vh');\n    \n    body.appendChild(title);\n    \n    this.setTimeout(()=>{\n    alert('Retosparaprogramadores #4. Please open the Browser Developer Tools.');\n    }, 2000);\n    log( 'Retosparaprogramadores #4'); // this will be logged at the end cause the nature of window event\n});\n\n\n/*ADDITIONAL DIFFICULTY (optional):\nCreate a program that analyzes two different words and performs checks\nto determine if they are:  Palindromes   Anagrams   Isograms */\n\n\n//Palindrome: A palindrome is a word, phrase, number, or other sequence of characters that reads the same forward and backward.\n\nconst isPolidrome = (w1, w2)=>{\n    if(w1.length != w2.length) return false\n  let fw = w1.split('')\n  let sw = w2.split('')\n    for(let i = 0, k = w1.length;i < w1.length; i++, k--){\n      if(fw[i] != sw[k-1]) return false;       \n    }  \n    return true;\n}\n\nlog('is isPolidrome: ', isPolidrome('roma', 'amor'))//Logs: true\n\n//Anagram: An anagram is a word or phrase formed by rearranging the letters of another word or phrase, using all the original letters exactly once. \n\nconst isAnagram = (w1, w2)=>{\n\n    if(w1.length != w2.length) return false;\n  \n    let result = w1.split('').some(l =>\n        w2.split('').some(v => v == l)\n    )\n   return result;\t\n}\n\nlog('is anagram: ', isAnagram('nick','kinc')); //Logs: true\n\n//Isogram: An isogram is a word or phrase in which no letter occurs more than once. For example, \"lumberjack\" and \"background\" are isograms because none of the letters are repeated.\n\nconst isIsogram = (str)=>{\n  let countLetters = [];\nstr.split('').forEach((l,index)=>{\n    countLetters[index] = str.split('').filter(char => l == char).length\n});\n//console.log('countLetters: ', countLetters);  \n  for(let num of countLetters){\n  if(num > 1) return false;\n}\nreturn true;\n}\n\nlog('is isogram: ', isIsogram('background')); //Logs: true\n\n//the function check when two strings are polidromes, anagrams or isograms\nconst checkState = (str1, str2)=>{\n    let r_poli = isPolidrome(str1, str2);\n    let r_anag = isAnagram(str1, str2);\n    let f_iso = isIsogram(str1);\n    let s_iso = isIsogram(str2);\n    let result = '';\n    let bool = false;\n\nif(r_poli && r_anag && f_iso && s_iso){\n    result = `The words: \"${str1}\" and \"${str2}\" are polidromes, anagrams and also isograms.`\n    bool = true;\n}else if(r_poli){\n    result = `The words: \"${str1}\" and \"${str2}\" are polidromes and anagrams but they aren't isograms. `\n}else if(r_anag && f_iso && s_iso){\n    result = `The words: \"${str1}\" and \"${str2}\" are anagrams and also isograms.`\n    bool = true;\n}else if(r_anag){\n    result = `The words: \"${str1}\" and \"${str2}\" are anagrams. `\n}\n\n  if(!bool){  \n      if(f_iso && s_iso){\n          result = `The words: \"${str1}\" and \"${str2}\" are isograms. `\n      }else if(f_iso){\n          result += `The first word: \"${str1}\" is an isogram`\n      }else if(s_iso){\n          result += `The second word: \"${str2}\" is an isogram`\n      }else if(!r_poli&&!r_anag){\n       result = `The words: \"${str1}\" and \"${str2}\" aren't polidromes, anagrams or isograms.`\n      }\n  }  \n\n log(result)\n\n}\n\ncheckState('amor','mora'); /* Logs: The words: \"amor\" and \"mora\" are anagrams and also isograms */\ncheckState('amor','roma'); /* logs: The words: \"amor\" and \"roma\" are polidromes, anagrams and also isograms.*/\ncheckState('zeitgest','kaguabumga'); /* Logs: The words: \"zeitgest\" and \"kaguabumga\" aren't polidromes, anagrams or isograms.*/\ncheckState('pizza', 'background'); /* Logs: The second word: \"background\" is an isogram  */\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/emedevelopa.js",
    "content": "// CADENAS DE CARACTERES\n\n// Concatenación\nlet str1 = \"Hola\";\nlet str2 = \"qué tal estás?\";\nlet resultado = str1 + \" \" + str2;\nconsole.log(resultado);\n\n// Longitud de cadena\nlet frase = \"Hola me llamo Antoñita\";\nlet longitud = frase.length;\nconsole.log(longitud);\n\n// Acceso a caracteres individuales\nlet palabra = \"Machete\";\nlet caract = palabra[0];\nconsole.log(caract);\n\n// Búsqueda y comparación\nlet frase1 = \"Dale a tu cuerpo alegría macarena\";\nconsole.log(frase1.indexOf(\"cuerpo\")); //10\nconsole.log(frase1.lastIndexOf(\"tu\")); //7\nconsole.log(frase1.startsWith(\"Hola\")); //flase\nconsole.log(frase1.endsWith(\"macarena\")); //true\nconsole.log(frase1.includes(\"culo\")); //false\n\n// Extracción de subcadenas\nlet oracion = \"El mundo es mío y de nadie más\";\nconsole.log(oracion.substring(2, 7));\nconsole.log(oracion.slice(5));\n\n// Transformación de texto\nlet word = \"Me gusta la lasaña\";\nconsole.log(word.toUpperCase());\n\n// Reemplazar\nconsole.log(word.replace (\"lasaña\", \"sopa\"));\n\n// Acceder a un caracter\nlet sofa = \"sofa\";\n//console.log(sofa.charAt(2)); //f\nconsole.log(sofa[2]); //f\n\n// Repetición\nlet piano = \"piano\";\nconsole.log(piano.repeat(3)); //pianopianopiano\n\n// Recorrido\nlet bucle = \"Esto es un bucle\";\nfor(let i = 0; i < bucle.length; i++) {\n    console.log(bucle[i]);\n}\n\n// Dividir\nlet str3 = \"azul, verde, naranja, negro\";\n//let strdiv = str3.split(' ');//Por espacios\n//let strdiv = str3.split(''); //por caracter\n//let strdiv = str3.split(','); //por comas\nlet strdiv = str3.split(',', 3); //por limite\nconsole.log(strdiv);\n\n// Eliminar espacios en blanco\nlet str4 = \" Me duele un pie \";\nconsole.log(str4.trim());\n\n// Revertir cadena\nlet str5 = \"No quiero trabajar\";\nconsole.log(str5.split('').reverse().join(''));\n\n//Interpolación\nlet msg1 = \"mañana\";\nlet msg2 = \"frío\";\nlet msg3 = \"lloviendo\";\nlet finalmsg = `Esta ${msg1} hacía ${msg2} y estaba ${msg3}`\nconsole.log(finalmsg);\n\n//EXTRA\n\nfunction esPalindromo (palabra) {\n    const palabraReversa = palabra.split('').reverse().join('');\n    return palabraReversa === palabra;\n}\n\nfunction esAnagrama(palabra) {\n    const ordenada = palabra.split('').sort().join('');\n    return ordenada === palabra;\n}\n\nfunction esIsograma(palabra) {\n    const letras = {};\n    for (let letra of palabra) {\n        if (letras[letra]) {\n            return false;\n        }\n        letras[letra] = true;\n    }\n    return true;\n}\n\nfunction palabras (palabra1, palabra2) {\n    let resultado = \"\";\n    \n    if (esPalindromo(palabra1) && esPalindromo(palabra2)) {\n        resultado += `\"${palabra1}\" y \"${palabra2}\" son Palíndromos.`;\n    } else if (esPalindromo (palabra1)) {\n        resultado += `\"${palabra1}\" es un Palíndromo y \"${palabra2}\" no lo es.`;\n    } else if (esPalindromo (palabra2)) {\n        resultado += `\"${palabra2}\" es un Palíndromo y \"${palabra1}\" no lo es.`;\n    } else {\n        resultado += `Ninguna es un palíndromo`;\n    }\n\n    if (esAnagrama(palabra1) && (palabra2)) {\n        resultado += `\"${palabra1}\" y \"${palabra2}\" son Anagramas.`;\n    } else if (esAnagrama (palabra1)) {\n        resultado += `\"${palabra1}\" es Anagrama y \"${palabra2}\" no lo es.`;\n    } else if (esAnagrama (palabra2)) {\n        resultado += `\"${palabra2}\" es Anagrama y \"${palabra1}\" no lo es`;\n    } else {\n        resultado += `Ninguna es una anagrama`;\n    }\n\n    if (esIsograma(palabra1) && (palabra2)) {\n        resultado += `\"${palabra1}\" y \"${palabra2}\" son Isogramas.`;\n    } else if (esIsograma(palabra1)) {\n        resultado += `\"${palabra1}\" es Isograma y \"${palabra2}\" no lo es.`\n    } else if (esIsograma(palabra2)) {\n        resultado += `\"${palabra2}\" es Isograma y \"${palabra1}\" no lo es.`\n    } else {\n        resultado += `Ninguna es un isograma`;\n    }\n    return resultado.trim();\n}\n\nconsole.log(palabras(\"amor\", \"reconocer\"));\n\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/eulogioep.js",
    "content": "// Operaciones con cadenas en JavaScript\n\n// Declaración de una cadena\nconst texto = \"Hola, mundo!\";\n\nconsole.log(\"Texto original:\", texto);\n\n// 1. Acceso a caracteres específicos\nconsole.log(\"1. Primer carácter:\", texto[0]);\n\n// 2. Subcadenas\nconsole.log(\"2. Subcadena:\", texto.substring(0, 4));\n\n// 3. Longitud\nconsole.log(\"3. Longitud:\", texto.length);\n\n// 4. Concatenación\nconst otraCadena = \" Bienvenidos\";\nconsole.log(\"4. Concatenación:\", texto + otraCadena);\n\n// 5. Repetición\nconsole.log(\"5. Repetición:\", texto.repeat(3));\n\n// 6. Recorrido\nconsole.log(\"6. Recorrido:\");\nfor (let char of texto) {\n    console.log(char);\n}\n\n// 7. Conversión a mayúsculas y minúsculas\nconsole.log(\"7. Mayúsculas:\", texto.toUpperCase());\nconsole.log(\"   Minúsculas:\", texto.toLowerCase());\n\n// 8. Reemplazo\nconsole.log(\"8. Reemplazo:\", texto.replace(\"mundo\", \"JavaScript\"));\n\n// 9. División\nconsole.log(\"9. División:\", texto.split(\", \"));\n\n// 10. Unión\nconst arrayPalabras = [\"JavaScript\", \"es\", \"genial\"];\nconsole.log(\"10. Unión:\", arrayPalabras.join(\" \"));\n\n// 11. Interpolación (template literals en JavaScript)\nconst nombre = \"Alice\";\nconst edad = 30;\nconsole.log(`11. Interpolación: Me llamo ${nombre} y tengo ${edad} años.`);\n\n// 12. Verificación\nconsole.log(\"12. Empieza con 'Hola':\", texto.startsWith(\"Hola\"));\nconsole.log(\"    Termina con '!':\", texto.endsWith(\"!\"));\nconsole.log(\"    Contiene 'mundo':\", texto.includes(\"mundo\"));\n\n// 13. Recorte de espacios\nconst textoConEspacios = \"  Hola Mundo  \";\nconsole.log(\"13. Recorte de espacios:\", textoConEspacios.trim());\n\n// 14. Extracción de subcadenas\nconsole.log(\"14. Extracción (slice):\", texto.slice(0, 4));\n\n// 15. Búsqueda de índice\nconsole.log(\"15. Índice de 'mundo':\", texto.indexOf(\"mundo\"));\n\n// DIFICULTAD EXTRA\nconsole.log(\"\\nDIFICULTAD EXTRA:\");\n\nconst palabra1 = \"amor\";\nconst palabra2 = \"roma\";\n\nconsole.log(\"Palabra 1:\", palabra1);\nconsole.log(\"Palabra 2:\", palabra2);\n\n// Función para verificar si una palabra es un palíndromo\nfunction esPalindromo(palabra) {\n    return palabra === palabra.split('').reverse().join('');\n}\n\n// Función para verificar si dos palabras son anagramas\nfunction sonAnagramas(palabra1, palabra2) {\n    return palabra1.toLowerCase().split('').sort().join('') === \n           palabra2.toLowerCase().split('').sort().join('');\n}\n\n// Función para verificar si una palabra es un isograma\nfunction esIsograma(palabra) {\n    return new Set(palabra.toLowerCase()).size === palabra.length;\n}\n\nconsole.log(\"¿Son palíndromos?\", \n    esPalindromo(palabra1), esPalindromo(palabra2));\nconsole.log(\"¿Son anagramas?\", sonAnagramas(palabra1, palabra2));\nconsole.log(\"¿Son isogramas?\", esIsograma(palabra1), esIsograma(palabra2));"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/fdcorreadev.js",
    "content": "console.log(\"Cadena de caracteres\")\n\nconsole.log(\"-----------------------------------------------------------start--------------------------------------------------\")\nconsole.log(\"1. Formas de declara cadenas de caracteres\")\nconst text1 = \"Una cadena primitiva\"\nconst text2 = 'Otra cadena primitiva'\nconst text3 = `Otra cadena primitiva`\nconst text4 = new String(\"Un bojeto String\")\n\n\nconsole.log(\"2. formas de obtener numeros caracteres\")\n\nconsole.log(\"cat\".charAt(1))\nconsole.log(\"cat\"[1])\nconsole.log(\"cat\"[0])\n\nconsole.log(\"3. manejo de string mayucula, minuscula\")\nconsole.log(\"hola\".toUpperCase())\nconsole.log(\"HOLA\".toLowerCase())\n\n\nconsole.log(\"4. concatenacion y separacion de caracteres\")\nconst concat = 4\nconsole.log(`con estas comillas podemos concatenar el valor ${concat}`)\n\n\nconst splitText = text1.split(' ')\nconsole.log(splitText)\nconsole.log(splitText[0] + \" \" + splitText[1] + \" \" + splitText[2])\nconsole.log(splitText.join(\" \"))\n\n\nconsole.log(\"5. verificacion de tipos para recorrerlos\")\nlet s_prim = \"foo\";\nlet s_obj = new String(s_prim);\n\nconsole.log(typeof s_prim); // Registra \"string\"\nconsole.log(typeof s_obj); // Registra \"object\"\n\n// tener cuidado con eval para operaciones\n\nlet s1 = \"2 + 2\"; // crea una string primitiva\nlet s2 = new String(\"2 + 2\"); // crea un objeto String\nconsole.log(eval(s1)); // devuelve el número 4\nconsole.log(eval(s2)); // devuelve la cadena \"2 + 2 es un Object se trata diferentre\n// para que devuelva el mismo resultado debemos utilizar valueOF\n\nconsole.log(eval(s2.valueOf()))\n\nconsole.log(\"6. propiedade de las cadenas de caracteres\")\n\nconsole.log(\"hola\".length)\nconsole.log(\"Hola\".replace(\"H\", \"h\"))\nconsole.log(\"hola\".substring(1, 3))\nconsole.log(\"hola\".includes(\"o\"))\n//esta propiedad de indexOf si encuentra genera la posicion empezando del 0 pero si no encuentra lanza -1\nconsole.log(\"hola\".indexOf(\"f\"))\nconsole.log(\"hola\".indexOf(\"l\"))\nconsole.log(\"hola\".slice(1, 3))\n\n\nconsole.log(\"-----------------------------------------------------------------------end-----------------------------------------------------------\")\n\nconsole.log(\"-----------------------------------------------------------------Dificultad extra------------------------------------------------------\")\n\nfunction verifyPalindromeWord(text){\n    const textReverse = text.split('').reverse().join('')\n    let isPalindrome = text === textReverse ? true : false\n    let response\n    \n    if(isPalindrome){\n        response = `La palabra ${text} es palindromo`\n    } else {\n        response = `La palabra ${text} no es palindromo`\n    }\n\n    return response\n}\n\nconsole.log(\"-------------------------------Palindromo--------------------------------------------------\")\nlet word = \"ana\"\nconst res = verifyPalindromeWord(word)\nconsole.log(res)\n\n\nfunction verifyAnagramsWords(word, compareWord){\n    const cleanWord = word.toLowerCase().replace(/[^a-z0-9]/g, '');\n    const cleanCompareWord = compareWord.toLowerCase().replace(/[^a-z0-9]/g, '');\n    let result\n\n    if(cleanWord.length !== cleanCompareWord.length){\n        result = 'No es Anagrama'\n    }\n\n    const ordenWord =  cleanWord.split('').sort().join('')\n    const ordenCompareWord =  cleanCompareWord.split('').sort().join('')\n\n    result = ordenWord === ordenCompareWord ? 'Es un Anagrama' : 'No es anagrame'\n\n    return result\n}\n\nconsole.log(\"-------------------------------Anagramas--------------------------------------------------\")\nconst resultAnagrams = verifyAnagramsWords(\"Debit card\", \"Bad credit\")\nconsole.log(resultAnagrams)\n\nfunction verifyIsogramasWord(word){\n    const splitWord = word.split('')\n    const apariciones  = splitWord.filter(function (caracterActual,  indice, arreglo){\n        const primerIndice = arreglo.indexOf(caracterActual)\n        const esRepeticion = primerIndice !== indice\n        return esRepeticion\n    })\n    let result\n    if(!apariciones.length > 0){\n        result = 'Es un isograma'\n    } else {\n        result = 'No es isograma'\n    }\n    \n    return result\n}\nconsole.log(\"-------------------------------isograma--------------------------------------------------\")\nconst resultIsogramas = verifyIsogramasWord('murcielago')\nconsole.log(resultIsogramas)"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/garos01.js",
    "content": "// Acceso a caracteres específicos\nlet cadena = \"Hola, mundo!\";\nconsole.log(cadena[0]);\n\n// Subcadenas\nlet subcadena = cadena.substring(1, 5);\nconsole.log(subcadena);\n\n// Longitud de la cadena\nlet longitud = cadena.length;\nconsole.log(longitud);\n\n// Concatenación\nlet otraCadena = \"¡Cómo estás?\";\nlet concatenacion = cadena + \" \" + otraCadena;\nconsole.log(concatenacion);\n\n// Repetición\nlet repetida = cadena.repeat(3);\nconsole.log(repetida);\n\n// Recorrido\nfor (let letra of cadena) {\n  console.log(letra);\n}\n\n// Conversión a mayúsculas y minúsculas\nlet mayusculas = cadena.toUpperCase();\nlet minusculas = cadena.toLowerCase();\nconsole.log(mayusculas);\nconsole.log(minusculas);\n\n// Reemplazo\nlet nuevaCadena = cadena.replace(\"mundo\", \"amigo\");\nconsole.log(nuevaCadena);\n\n// División\nlet palabras = cadena.split(\" \");\nconsole.log(palabras);\n\n// Unión\nlet union = palabras.join(\" \");\nconsole.log(union);\n\n// Interpolación\nlet nombre = \"Juan\";\nlet saludoPersonalizado = `Hola, ${nombre}!`;\nconsole.log(saludoPersonalizado);\n\n// Verificación\nlet contieneHola = cadena.includes(\"Hola\");\nconsole.log(contieneHola);\n\n// Ejercicio extra\nfunction esPalindromo(palabra) {\n  palabra = palabra.toLowerCase().replace(/\\s/g, \"\");\n  return palabra === palabra.split(\"\").reverse().join(\"\");\n}\n\nfunction esAnagrama(palabra1, palabra2) {\n  palabra1 = palabra1.toLowerCase().replace(/\\s/g, \"\");\n  palabra2 = palabra2.toLowerCase().replace(/\\s/g, \"\");\n  return (\n    palabra1.split(\"\").sort().join(\"\") === palabra2.split(\"\").sort().join(\"\")\n  );\n}\n\nfunction esIsograma(palabra) {\n  palabra = palabra.toLowerCase().replace(/\\s/g, \"\");\n  return new Set(palabra).size === palabra.length;\n}\n\nfunction analizarPalabras(palabra1, palabra2) {\n  if (esPalindromo(palabra1)) {\n    console.log(`${palabra1} es un palíndromo.`);\n  } else {\n    console.log(`${palabra1} no es un palíndromo.`);\n  }\n\n  if (esAnagrama(palabra1, palabra2)) {\n    console.log(`${palabra1} y ${palabra2} son anagramas.`);\n  } else {\n    console.log(`${palabra1} y ${palabra2} no son anagramas.`);\n  }\n\n  if (esIsograma(palabra1)) {\n    console.log(`${palabra1} es un isograma.`);\n  } else {\n    console.log(`${palabra1} no es un isograma.`);\n  }\n\n  if (esPalindromo(palabra2)) {\n    console.log(`${palabra2} es un palíndromo.`);\n  } else {\n    console.log(`${palabra2} no es un palíndromo.`);\n  }\n\n  if (esAnagrama(palabra1, palabra2)) {\n    console.log(`${palabra1} y ${palabra2} son anagramas.`);\n  } else {\n    console.log(`${palabra1} y ${palabra2} no son anagramas.`);\n  }\n\n  if (esIsograma(palabra2)) {\n    console.log(`${palabra2} es un isograma.`);\n  } else {\n    console.log(`${palabra2} no es un isograma.`);\n  }\n}\n\nconst palabra1 = \"amor\";\nconst palabra2 = \"roma\";\n\nanalizarPalabras(palabra1, palabra2);\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/gianbordon.js",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\n//\n// STRINGS\n//\n\n// Declaracion\n\nlet myStr = \"Soy un strig con comillas dobles\"\nlet myStrr = 'Soy un string con comillas simple'\nlet myStrrr = `Soy un string con backsticks`\n\nconsole.log(myStr)\nconsole.log(myStrr)\nconsole.log(myStrrr)\n\n//\n// METODOS \n//\n\n// charAt()\nconst ejemploCharAt = \"Hola mundo\"; // Devuelve el caracter en la posicion indicada\nconsole.log('Caracter buscado mediante la posicion: ',ejemploCharAt.charAt(2)); \nconsole.log('Caracter buscado mediante la posicion: ',ejemploCharAt.charAt(7)); \n\n//charCodeAt()\nconst ejemploCharCodeAt = \"Hola\"; // Devuelve el valor UTF-16 del carácter en la posición indicada.\nconsole.log(ejemploCharCodeAt.charCodeAt(0)); \n\n// codePointAt()\nconst ejemploCodePointAt = \"A\"; // Devuelve el valor Unicode del punto de código en la posición dada.\nconsole.log(ejemploCodePointAt.codePointAt(0)); \n\n// concat()\nconst ejemploConcat = \"Hola, \".concat(\"Gianfranco\", \"!\"); // Concatena (une) una o más cadenas.\nconsole.log(ejemploConcat); \n\n// includes()\nconst ejemploIncludes = \"JavaScript es genial\"; // Verifica si la cadena contiene la subcadena especificada.\nconsole.log(ejemploIncludes.includes(\"genial\")); \n\n// endsWith()\nconst ejemploEndsWith = \"Hola mundo\"; // Verifica si la cadena termina con la subcadena especificada.\nconsole.log(ejemploEndsWith.endsWith(\"mundo\")); \n\n// indexOf()\nconst ejemploIndexOf = \"banana\"; // Devuelve la posición de la primera ocurrencia del valor indicado.\nconsole.log(ejemploIndexOf.indexOf(\"a\")); \n\n// lastIndexOf()\nconst ejemploLastIndexOf = \"banana\"; // Devuelve la posición de la última ocurrencia del valor indicado.\nconsole.log(ejemploLastIndexOf.lastIndexOf(\"a\")); \n\n// localCompare()\nconst ejemploLocaleCompare = \"café\"; // Compara dos cadenas según la configuración regional.\nconsole.log(ejemploLocaleCompare.localeCompare(\"cafe\")); \n\n// match()\nconst ejemploMatch = \"Hoy es 17 de abril\"; // Devuelve las coincidencias de una expresión regular.\nconsole.log(ejemploMatch.match(/\\d+/)); \n\n// matchAll()\nconst ejemploMatchAll = \"uno, dos, tres\"; // Devuelve un iterador con todas las coincidencias de una expresión regular.\nconst matches = [...ejemploMatchAll.matchAll(/\\w+/g)]; \nconsole.log(matches.map(m => m[0])); \n\n// normalize()\nconst ejemploNormalize = \"\\u004e\\u006f\\u0072\\u006d\\u0061\\u006c\\u0065\"; // Normaliza una cadena en su forma Unicode.\nconsole.log(ejemploNormalize.normalize()); \n\n// padEnd()\nconst ejemploPadEnd = \"123\"; // Agrega caracteres al final de la cadena hasta llegar a la longitud deseada.\nconsole.log(ejemploPadEnd.padEnd(6, \"0\")); \n\n// padStart()\nconst ejemploPadStart = \"45\"; // Agrega caracteres al inicio de la cadena hasta llegar a la longitud deseada.\nconsole.log(ejemploPadStart.padStart(5, \"0\")); \n\n// repeat()\nconst ejemploRepeat = \"ha\"; // Repite la cadena la cantidad de veces indicada.\nconsole.log(ejemploRepeat.repeat(3)); \n\n// replace()\nconst ejemploReplace = \"Me gusta el pan\"; // Reemplaza la primera aparición de una subcadena.\nconsole.log(ejemploReplace.replace(\"pan\", \"queso\")); \n\n// replaceAll()\nconst ejemploReplaceAll = \"Hola mundo mundo mundo\"; // Reemplaza todas las apariciones de una subcadena.\nconsole.log(ejemploReplaceAll.replaceAll(\"mundo\", \"universo\")); \n\n// search()\nconst ejemploSearch = \"El número 42 es especial\"; // Devuelve el índice de la primera coincidencia con una expresión regular.\nconsole.log(ejemploSearch.search(/\\d+/)); \n\n// slice()\nconst ejemploSlice = \"JavaScript\"; // Devuelve una porción de la cadena desde beginIndex hasta endIndex (sin incluirlo).\nconsole.log(ejemploSlice.slice(4, 10)); \n\n// split()\nconst ejemploSplit = \"manzana,banana,pera\"; // Divide la cadena en un array usando un separador.\nconsole.log(ejemploSplit.split(\",\"));\n\n// startsWith()\nconst ejemploStartsWith = \"Buenos días\"; // Verifica si la cadena comienza con la subcadena indicada.\nconsole.log(ejemploStartsWith.startsWith(\"Buenos\")); \n\n// substring()\nconst ejemploSubstring = \"JavaScript\"; // Devuelve los caracteres entre dos índices (sin incluir indexEnd).\nconsole.log(ejemploSubstring.substring(4, 10)); \n\n// toLowerCase()\nconst ejemploToLowerCase = \"HOLA MUNDO\"; // Convierte toda la cadena a minúsculas.\nconsole.log(ejemploToLowerCase.toLowerCase()); \n\n// toString()\nconst ejemploToString = 12345; // Devuelve una representación en forma de cadena del objeto.\nconsole.log(ejemploToString.toString()); \n\n// toUpperCase()\nconst ejemploToUpperCase = \"hola mundo\"; // Convierte toda la cadena a mayúsculas.\nconsole.log(ejemploToUpperCase.toUpperCase()); \n\n// trim()\nconst ejemploTrim = \"   espacio   \"; // Elimina espacios en blanco al inicio y al final de la cadena.\nconsole.log(ejemploTrim.trim()); \n\n// trimStart()\nconst ejemploTrimStart = \"   inicio\"; // Elimina espacios al comienzo de la cadena.\nconsole.log(ejemploTrimStart.trimStart()); \n\n// trimEnd()\nconst ejemploTrimEnd = \"fin   \"; // Elimina los espacios en blanco al final de la cadena.\nconsole.log(ejemploTrimEnd.trimEnd()); \n\n// valueOf()\nconst ejemploValueOf = new String(\"valor primitivo\"); // Devuelve el valor primitivo de un objeto String.\nconsole.log(ejemploValueOf.valueOf()); \n\n// @@iterador()\nconst ejemploIterator = \"hola\"; // Permite recorrer los caracteres de una cadena con un iterador.\nfor (const letra of ejemploIterator[Symbol.iterator]()) {\n    console.log(letra);\n}\n\n// \n// Metodos que funcionan como propiedades internas o funciones\n//\n\n// Acceder al carácter con notación de corchete (similar a charAt)\nconst ejemploBracket = \"cadena\";\nconsole.log(ejemploBracket[2]); \n\n// Comparación de cadenas con ===\nconst str1 = \"abc\";\nconst str2 = \"abc\";\nconsole.log(str1 === str2); \n\n// .length\nconst ejemploLength = \"longitud\"; // Longitud de una cadena.\nconsole.log(ejemploLength.length);  \n\n//\n// EXTRA\n//\n\nfunction compareString(str1, str2) {\n    const a = str1.toLowerCase();\n    const b = str2.toLowerCase();\n\n    console.log('🔄 Palabras comparadas:', a, '-', b);\n\n    console.log('* ¿Es Palíndroma? *');\n    if (isPalindromo(a)) {\n        console.log(`✅ La palabra \"${a}\" es palíndroma.`);\n    } else {\n        console.log(`❌ La palabra \"${a}\" no es palíndroma.`);\n    }\n    if (isPalindromo(b)) {\n        console.log(`✅ La palabra \"${b}\" es palíndroma.`);\n    } else {\n        console.log(`❌ La palabra \"${b}\" no es palíndroma.`);\n    }\n\n    console.log('* ¿Son Anagramas entre sí? *');\n    if (isAnagrama(a, b)) {\n        console.log(`✅ Las palabras \"${a}\" y \"${b}\" son anagramas entre sí.`);\n    } else {\n        console.log(`❌ Las palabras \"${a}\" y \"${b}\" no son anagramas entre sí.`);\n    }\n\n    console.log('* ¿Es Isograma? *');\n    if (isIsograma(a)) {\n        console.log(`✅ La palabra \"${a}\" es un isograma.`);\n    } else {\n        console.log(`❌ La palabra \"${a}\" no es un isograma.`);\n    }\n    if (isIsograma(b)) {\n        console.log(`✅ La palabra \"${b}\" es un isograma.`);\n    } else {\n        console.log(`❌ La palabra \"${b}\" no es un isograma.`);\n    }\n\n    console.log('------------------------------');\n}\n\nfunction isPalindromo(str) {\n    return str === str.split(\"\").reverse().join(\"\")\n}\nfunction isAnagrama(str1,str2){\n    return str1.split('').sort().join('') === str2.split('').sort().join('');\n}\nfunction isIsograma(str){\n    for (let i = 0; i < str.length; i++) {\n    for (let j = i + 1; j < str.length; j++) {\n        if (str[i] === str[j]) {\n        return false;\n        }}}\n    return true;\n}\n\n// 🧪 Casos de prueba\ncompareString(\"reconocer\", \"reconocer\"); \ncompareString(\"anita\", \"atina\");         \ncompareString(\"murcielago\", \"pantheon\"); \ncompareString(\"abc\", \"cab\");             \ncompareString(\"banana\", \"perro\");       \ncompareString(\"radar\", \"luz\");           \ncompareString(\"gato\", \"gaga\");           \ncompareString(\"amor\", \"roma\");           \n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/giovanyosorio.js",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\n//Operaciones Cadenas\n\n\n\n// charAt()\n// devuelve en un nuevo String el carácter UTF-16 de una cadena.\nvar cualquierCadena = \"Brave new world\";\n\nconsole.log(\n  \"El carácter en el índice 0 es '\" + cualquierCadena.charAt(0) + \"'\",\n);\n//El carácter en el índice 0 es 'B'\n\n\n//concat()\n// combina dos o más cadenas de texto y devuelve una cadena de texto nueva.\nconst str1 = 'Hello';\nconst str2 = 'World';\n\nconsole.log(str1.concat(' ', str2));\n// Expected output: \"Hello World\"\n\n\n//indexOf()\n// devuelve el índice, dentro del objeto String que realiza la llamada\n\"Blue Whale\".indexOf(\"Blue\"); // returns 0\n\"Blue Whale\".indexOf(\"Blute\"); // returns -1\n\n\n//match()\n//devuelve todas las ocurrencias de una expresión regular dentro de una cadena.\nconst paragraph = 'The quick brown fox jumps over the lazy dog. It barked.';\nconst regex = /[A-Z]/g;\nconst found = paragraph.match(regex);\n\nconsole.log(found);\n// Expected output: Array [\"T\", \"I\"]\n\n//padStart()\n//rellena la cadena actual con una cadena dada (repetida eventualmente) de modo que la cadena resultante alcance una longitud dada.\n\"abc\".padStart(10); // \"       abc\"\n\"abc\".padStart(10, \"foo\"); // \"foofoofabc\"\n\"abc\".padStart(6, \"123465\"); // \"123abc\"\n\n\n//repeat()\n//construye y devuelve una nueva cadena que contiene el número especificado de copias de la cadena en la cual fue llamada, concatenados.\n\"abc\".repeat(1); // 'abc'\n\"abc\".repeat(2); // 'abcabc'\n\"abc\".repeat(3.5); // 'abcabcabc' (count will be converted to integer)\n\"abc\".repeat(1 / 0); // RangeError\n\n\n//replace()\n//devuelve una nueva cadena con una, algunas, o todas las coincidencias de un patrón\nconst paragraph2 = \"I think Ruth's dog is cuter than your dog!\";\n\nconsole.log(paragraph2.replace(\"Ruth's\", 'my'));\n// Expected output: \"I think my dog is cuter than your dog!\"\n\n//search()\n// ejecuta una búsqueda que encaje entre una expresión regular y el objeto String desde el que se llama.\nfunction testinput(re, str) {\n    var midstring;\n    if (str.search(re) != -1) {\n      midstring = \" contains \";\n    } else {\n      midstring = \" does not contain \";\n    }\n    console.log(str + midstring + re);\n  }\n  \n\n//slice()\n//El método slice() extrae una sección de una cadena y devuelve una cadena nueva.\nvar cadena1 = \"La mañana se nos echa encima.\";\nvar cadena2 = cadena1.slice(3, -2);\nconsole.log(cadena2);\n// mañana se nos echa encim\n\n//split()\n//divide un objeto de tipo String en un array (vector) de cadenas mediante la separación de la cadena en subcadenas.\nvar miCadena = \"Hola Mundo. Cómo estás hoy?\";\nvar divisiones=miCadena.split(\" \")\nconsole.log(divisiones)\n//[ 'Hola', 'Mundo.', 'Cómo', 'estás', 'hoy?' ]\n\n// to string()\n// El toString() método devuelve una cadena que representa al objeto especificado.\ncadena = new String(\"Hello world\");\nalert(cadena.toString()); // Displays \"Hello world\"\n\n\n//toLowerCase()\n//devuelve el valor en minúsculas de la cadena que realiza la llamada.\nvar textoMayusculas = \"ALFABETO\";\ndocument.write(textoMayusculas.toLowerCase());\n\n//toUpperCase()\n//método devuelve el valor convertido en mayúsculas de la cadena que realiza la llamada.\nconsole.log(\"alphabet\".toUpperCase()); // \"ALPHABET\"\n\n// valueOf()\n//The valueOf() método devuelve el valor primitivo de un objeto String.\ncadena = new String(\"Hello world\");\nalert(cadena.valueOf()); // Displays \"Hello world\"\n\n//trim()\n//El método trim( ) elimina los espacios en blanco en ambos extremos del string\n\nvar orig = \"   foo  \";\nconsole.log(orig.trim()); // 'foo'\n\n\n// palindromos\n\nfunction isPalindrome(texto){\n    return texto== texto.split('').reverse().join('')\n  }\n  isPalindrome(\"reconocer\")\n\n  //Anagramas\n  function isAnagrama(palabra, posibleAnagrama){\n    return palabra.toLowerCase().split(\"\").sort().join(\"\") === posibleAnagrama.toLowerCase().split(\"\").sort().join(\"\");\n  }\n  isAnagrama(\"roma\",\"amor\")\n\n  //Isogramas\n  function isIsograma(palabra){\n    palabra = palabra.toLowerCase().replace(/A-Z/gi);\n      const letras = new Set(palabra);\n    return letras.size === palabra.length;\n\n\n}\nisIsograma(\"murcielago\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/gonzadev28.js",
    "content": "//Operaciones con cadenas de caracteres\n\nlet texto = 'Aprendo javascript';\n\n//Acceso a caracter en especifico\nconsole.log(texto[0]); //Accede al caracter en la posicion [0] = 'A' de 'Aprendo'\n\n//Acceso a subcadena \nconsole.log(texto.substring(8)); //Accede a los caracteres desde la posicion [8] en adelante\nconsole.log(texto.substring(8, 12));//Accede a los caracteres desde la posicion [8] hasta [12]\n\n//Acceso a la longitud de la cadena\nconsole.log(texto.length); //Imprime el numero total de caracteres del string incluyendo el espacio\n\n//Concatenacion\nlet texto2 = 'Retos de programacion';\nconsole.log(texto, 'con ' + texto2); //Concatenacion de variable 'texto' + 'texto2'\n\n//Repeticion\nlet textoRepetido = ('Texto en repeticion ');\nconsole.log(textoRepetido.repeat(5)); //Cadena se repite 5 veces \n\n//Recorrido\nfor(let i = 0; i < texto.length; i++){\n    console.log(texto[i]);//Recorre la cadena de caracteres \n}\n\n//Coversion a MAYUSCULAS\nconsole.log(texto.toUpperCase());//Convierte la cadena de caracteres en solo mayusculas \n\n//Conversion a minusculas\nconsole.log(texto.toLowerCase());//Convierte la cadena de caracteres en solo minusculas\n\n//Remplazo de caracteres\nconsole.log(texto.replace('javascript', 'leguajes de programacion'));\n//Remplaza string 'javascript' por string 'leguajes de programacion' \n\n//Division\nconsole.log(texto.split('')); //Divide cada cadena de caracteres en un solo caracter\nconsole.log(texto.split(' '));//Divide cada cadena de caracteres donde haya un espacio\n\n//Union\nlet textoSeparado = ['Esto', 'es', 'un', 'texto'];\nconsole.log(textoSeparado);//Imprime el texto separado\nconsole.log(textoSeparado.join(' '));//Une el texto en una sola frase\n\n//Interpolacion\nlet nombre = 'Gonzalo';\nlet lenguaje = 'Javascript';\nconsole.log(`Hola mi nombre es ${nombre} e intento aprender ${lenguaje}`);\n\n//Verificacion\nlet textoVerificado = 'Soy un texto que utilizare para verificar si se encuentra cierta palabra';\nconsole.log(textoVerificado.includes('verificar'));\n//Devuelve true porque 'verificar' si se encuentra en la variable 'textoVerificado'\nconsole.log(textoVerificado.includes('verificando'));\n//Devuelve false porque 'verificando' no se encuentra en la variable 'textoVerificado'\n\n// DIFICULTAD EXTRA (opcional):\n//  * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n//  * para descubrir si son:\n//  * - Palíndromos\n//  * - Anagramas\n//  * - Isogramas\n\n//Palindromo\nconsole.log('==========Palindromos==========');\nfunction palindromo(palabra1){\n    let palabraInvertida = palabra1.toLowerCase().split('').reverse().join('');\n    if(palabra1 === palabraInvertida){\n        console.log('Es un palindromo');\n    }else{\n        console.log('No es palindromo');\n    }\n}\npalindromo('radar');\npalindromo('gato');\n\n//Anagrama\nconsole.log('==========Anagramas=========='); \nfunction anagrama(palabra1, palabra2){\n    let ordenPalabra1 = palabra1.toLowerCase().split('').sort().join('');\n    let ordenPalabra2 = palabra2.toLowerCase().split('').sort().join('');\n    if(ordenPalabra1 === ordenPalabra2){\n        console.log('Es un anagrama');\n    }else{\n        console.log('No es un anagrama');\n    }\n}\nanagrama('botines', 'bisonte');\nanagrama('perro', 'gato');\n\n//Isograma\nconsole.log('==========Isogramas=========='); \nfunction isograma(palabra1){\n    let letras = palabra1.toLowerCase().split('');\n    let letrasSet = new Set(letras);\n    if(letras.length === letrasSet.size){\n        console.log('Es un isograma');\n    }else{\n        console.log('No es un isograma');\n    }\n}\nisograma('murcielago');\nisograma('programador');"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/h4ckxel.js",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\n *   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\n *   interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\n// Creamos una cadena de texto\nlet mi_cadena = \"Soy una cadena de texto\"\nconsole.log(mi_cadena)\n\n//Acceso a caracteres específicos\nlet caracterY =console.log(mi_cadena[2])\n\n//Longitud de una cadena de texto\nlet longitud = console.log(mi_cadena.length)\n\n// Contatenación de cadenas de texto\nlet cadenaNueva= \"y estoy creada por alexdevrep\"\nlet cadenaConcatenada = console.log(mi_cadena+\" \"+cadenaNueva)\n\n//Repetición de una cadena de texto\nlet cadenaRepetida = console.log(mi_cadena.repeat(3))\n\n//Recorrido de una cadena de texto\nfor (i=0;i<mi_cadena.length;i++){\n    console.log(mi_cadena[i])\n\n}\n\n//Conversión a minúsculas\nlet cadena_minus = console.log(mi_cadena.toLowerCase())\n\n//Conversión a mayúsculas\nlet cadena_mayus = console.log(mi_cadena.toUpperCase())\n\n//Reemplazo de caracteres\nmi_cadena = mi_cadena.replace (\"Soy\",\"I´m\")\nconsole.log(mi_cadena)\n\n//División de una cadena de texto\nmi_cadena = mi_cadena.slice(8)\nconsole.log(mi_cadena)\n\n//Unión de cadenas de texto\nlet cadenasDivididas = [\"a\",\"b\",\"c\"]\nlet cadenaUnida = console.log(cadenasDivididas.join(\"-\"))\n\n//Interpolación de cadenas de texto\nsuma = 1+2\nconsole.log(`El resultado de la suma es ${suma}`)\n\n//Verificación de las cadenas de texto\nlet contiene = console.log(mi_cadena.includes(\"texto\"))\n\n\n//Dificultad extra\n\n/*\n* DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isograma\n\n*/\n\n\nfunction palabra3invertida(palabra3){\n    palabra3reverse = palabra3.split(\"\").reverse().join(\"\")\n    return palabra3reverse\n}\n\n\nfunction palabra4invertida(palabra4){\n    palabra4reverse = palabra4.split(\"\").reverse().join(\"\")\n    return palabra4reverse\n}\n\n\n\nfunction palindromo(inversion3,inversion4){\n   \n    if (inversion3 === palabra3){\n        console.log(\"Esta palabra es un palíndromo\")\n    }\n    else{\n        console.log (\"Esta palabra no es un palíndromo\")\n    }\n    if (inversion4 === palabra4){\n        console.log(\"Esta palabra es un palíndromo\")\n    }\n    else{\n        console.log (\"Esta palabra no es un palíndromo\")\n    }\n}\n\nfunction Anagrama (palabra3, palabra4){\n    let array3 = palabra3.split(\"\").sort().join(\"\")\n    let array4 = palabra4.split(\"\").sort().join(\"\")\n    \n    if (array3 === array4){\n        console.log(\"Estas palabras son anagramas\")\n    }\n    else{\n        console.log(\"Estas palabras no son un anagrama\")\n    }\n\n}\n\nfunction Isograma(palabra3,palabra4){\n    let palabra3set = palabra3.split(\"\")\n    let palabra4set = palabra4.split(\"\")\n    let set3 = [...new Set (palabra3)]\n    let set4 = [...new Set (palabra4)]\n    console.log(set3)\n    console.log(palabra3set)\n    console.log(set4)\n    console.log(palabra4set)\n    \n    if (set3.length == palabra3set.length){\n        console.log(\"Esta palabra es un isograma\")\n    }\n    else{\n        console.log(\"Esta palabra no es un isograma\")\n    }\n    if (set4.length == palabra4set.length){\n        console.log(\"Esta palabra es un isograma\")\n    }\n    else{\n        console.log(\"Esta palabra no es un isograma\")\n    }\n        \n\n}\n\n\nconst prompt = require('prompt-sync')()\nlet palabra3 = prompt(\"Introduce la primera palabra al sistema: \")\nlet palabra4 = prompt(\"Introduce la segunda palabra al sistema: \")\ninversion3 = palabra3invertida(palabra3)\ninversion4 = palabra4invertida(palabra4)\npalindromo(inversion3,inversion4,palabra3,palabra4)\nAnagrama(palabra3,palabra4)\nIsograma(palabra3,palabra4)\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/hectorio23.js",
    "content": "\"use strict\";\n\nconst { NOMEM } = require('dns');\nconst readline = require('readline');\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\n/*\nEJERCICIO:\nMuestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\nen tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n- Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n  conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n\nDIFICULTAD EXTRA (opcional):\nCrea un programa que analice dos palabras diferentes y realice comprobaciones\npara descubrir si son:\n- Palíndromos\n- Anagramas\n- Isogramas\n*/\n\n\nfunction discoverType(value1, value2) {\n    // Se guarda una variable local la cual sera modificada\n    // para posteriormente ser comparada con la segunda palabra.\n    // Se puede observar que se ordena de manera contraria\n    let valueReverse = value1.split('').reverse().join('');\n\n    if (valueReverse === value2) {\n        return \"\\nLas palabras anteriormente insertadas forman en realidad un palíndromo\\n\\n\";\n    } else if (isograma(value1) && isograma(value2)) {\n        return \"\\nAmbas palabras son isogramas\\n\\n\";\n    } else if (isograma(value1) || isograma(value2)) {\n        return \"\\nUna de las palabras es un isograma\\n\\n\";\n    } else if (anagrama(value1, value2)) {\n        return \"\\nEs un anagrama\\n\\n\";\n    }\n\n    return \"\\nLas palabras proporcionadas no cumplen con las condiciones para ser un palíndromo, isograma o anagrama\\n\";\n}\n\nfunction isograma(palabra) {\n    let _tmp_ = \"\";\n\n    for (let item of palabra) {\n        if (_tmp_.includes(item)) {\n            return false;\n        }\n        _tmp_ += item;\n    }\n    return true;\n}\n\nfunction anagrama(palabra1, palabra2) {\n    let palabra1_sorted = palabra1.split('').sort().join('');\n    let palabra2_sorted = palabra2.split('').sort().join('');\n\n    if (palabra1.length !== palabra2.length || palabra1_sorted !== palabra2_sorted) {\n        return false;\n    }\n    return true;\n}\n\nfunction main() {\n    // Las siguientes variables almacenan las palabras\n    // insertadas por el usuario\n    let value1;\n    let value2;\n    rl.question(\"Inserta la primera palabra: \", (nombre) => { value1 = nombre;})    \n    rl.question(\"Ahora inserta la segunda palabra: \", (nombre) => { value2 = nombre;})    \n\n    let cadena1 = \"Hola\";\n    let cadena2 = \"Mundo\";\n\n    // Modifican la variable original transformando sus caracteres en minúsculas\n    value1 = value1.toLowerCase();\n    value2 = value2.toLowerCase();\n\n    // Se llama a la función discoverType, la cual devuelve una cadena dependiendo de\n    // si las palabras ingresadas por el usuario forman parte de un palíndromo, anagrama o isograma.\n    // Para lograr esto, se invocan otras funciones cuyo único propósito es verificar\n    // si las palabras cumplen con las especificaciones dadas.\n    console.log(discoverType(value1, value2));\n\n    // Concatenación de dos cadenas\n    let concatenacion = cadena1 + \" \" + cadena2;\n    console.log(\"Concatenación: \" + concatenacion);\n\n    // Se elimina cualquier espacio de la cadena de caracteres\n    let cadenaPrueba = concatenacion.replace(/\\s/g, \"\");\n    console.log(\"Cadena sin espacios en blanco: \" + cadenaPrueba);\n\n    // Obtención de la longitud de dos cadenas\n    console.log(\"Longitud de la cadena 1: \" + cadena1.length);\n    console.log(\"Longitud de la cadena 2: \" + cadena2.length);\n\n    // Acceso a caracteres individuales\n    console.log(\"Primer caracter de la cadena 1: \" + cadena1[0]);\n    console.log(\"Último caracter de la cadena 2: \" + cadena2[cadena2.length - 1]);\n\n    // Comparación\n    if (cadena1 === cadena2) {\n        console.log(\"Las cadenas son iguales\");\n    } else {\n        console.log(\"Las cadenas son diferentes\");\n    }\n\n    // Subcadena\n    let subcadena = concatenacion.substring(5, 10); // Extrae \"Mundo\"\n    console.log(\"Subcadena: \" + subcadena);\n\n    // Búsqueda\n    let buscar = \"Mundo\";\n    let posicion = concatenacion.indexOf(buscar);\n    if (posicion !== -1) {\n        console.log(\"La cadena '\" + buscar + \"' fue encontrada en la posición \" + posicion);\n    } else {\n        console.log(\"La cadena '\" + buscar + \"' no fue encontrada\");\n    }\n\n    // Modificación\n    concatenacion = concatenacion.replace(\"Mundo\", \"Universo\");\n    console.log(\"Después de reemplazar 'Mundo' por 'Universo': \" + concatenacion);\n}\n\nmain();\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/jaxi86.js",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\nlet cadena = 'hola a todos los que puedan leer esto';\nconsole.log(cadena);\n\nconsole.log(' ');\n\n\nconsole.log('acceso');\nconsole.log(cadena[10]);//se accede como si fuera un array\nconsole.log(cadena.charAt(3));// conel metodo charAt\n\nconsole.log(' ');\n\nconsole.log('subcadenas');\nconsole.log(cadena.substring(13, 16));\n\nconsole.log(' ');\n\nconsole.log('longitud');\nconsole.log(cadena.length);\n\nconsole.log(' ');\n\nconsole.log('concatenacion');\nconsole.log(cadena + \" \" + \"hoy\");\nlet strn1 = 'hola';\nlet strn2 = 'mundo';\nconsole.log(strn1.concat(' ',strn2));//con el metodo concat()\n\nconsole.log(' ');\n\nconsole.log('repeticion');\nlet saludo = 'hola';\nconsole.log(saludo.repeat(5));\n\nconsole.log(' ');\n\nconsole.log('recorrido');\nlet reco = 'josue';\nfor (let i = 0; i < reco.length; i++){\n    console.log(reco[i]);\n}\n\nconsole.log(' ');\n\nconsole.log('conversion a mayusculas');\nconsole.log(cadena.toLocaleUpperCase());\n\nconsole.log(' ');\n\nconsole.log('conversion a minusculas');\nlet cadenaMay = 'JESUS ES TREMENDA PERRA';\nconsole.log(cadenaMay.toLocaleLowerCase());\n\nconsole.log(' ');\n\nconsole.log('reemplazo');\nconsole.log(cadena.replace('leer', 'ver'));\n\n\nconsole.log(' ');\n\nconsole.log('division');\nlet compras = \"harina, huevos, salsa\";\nconsole.log(compras.split(','));\n\n\nconsole.log(' ');\n\nconsole.log('union');\nlet compras2 = [\"harina, huevos, salsa\"];\nconsole.log(compras2.join(','));\n\nconsole.log(' ');\n\nconsole.log('interpolacion');\nlet marcaMoto = 'empire';\nlet marcaCauchos = 'firestone';\nlet oracion = `tengo una moto ${marcaMoto} y con los cauchos de ${marcaCauchos}`;\nconsole.log(oracion);\n\nconsole.log(' '); \n\nconsole.log('verificacion');\nlet veri = cadena.includes(\"a\");\nconsole.log(veri);\n\nconsole.log(' ');\n\n\nconsole.log('dificultad extra');\n\n// function principal () {\n//     let plb1 = prompt ('escribe la primera palabra para validar');\n//     let plb2 = prompt ('escribe la segunda palabra para validar');\n//     if (palindromo(plb1, plb2)===true){\n//         console.log(`${plb1} y ${[plb2]} son palindromos`);\n//     }\n    \n//     palindromo()\n// }\n// principal();\n\n// function palindromo (plbr1, plbr2) {\n//     let palabraRever = plbr1.split('').reverse().join('');\n//     if (palabraRever === plbr2){\n//         return true;\n//     }\n// }\n\n// function Anagrama (plbr1, plbr2) {\n//     let check = plbr1.toLowerCase().split(\"\").sort().join();\n//     let check1 = plbr2.toLowerCase().split(\"\").sort().join();\n//     if (check === check1) {\n//         return true;\n//     }\n// }\n\n// function isograma (plbr1, plbr2) {\n//     let check1 = plbr1.toLowerCase().split(\"\")\n//     let check2 = plbr2.toLowerCase().split(\"\")\n//     let i = 0;\n//     for (letra1 of check1){\n//         for (letra2 of check2){\n//             if (letra1 == letra2){\n//                 return true;\n//             }\n//         }\n//     }\n// }\n\n/* aqui tengo que confesar que todo el bloque de codigo anterior llevaba 3 dias intentando hacer que funcionara pero no lo logre \nasi que en el codigo que sigue use gemini para que lo corrigera y este fue el resultado, claro el codigo que me dio gemini tenia\nalgunos errores de funcionamiento pero le retoque algunas lineas (eso si fue por mi propio merito) y asi quedo*/\n\n\nfunction principal() {\n    let plb1 = prompt('escribe la primera palabra para validar');\n    let plb2 = prompt('escribe la segunda palabra para validar');\n\n    if (palindromo(plb1, plb2)) {\n        console.log(`${plb1} y ${plb2} son palíndromos`);\n    }else {console.log('no es un palindromo');\n    }\n\n    if (anagrama(plb1, plb2)) {\n        console.log(`${plb1} y ${plb2} son anagramas`);\n    }else {console.log('no es un anagrama');\n    }\n\n    if (isograma(plb1, plb2)) {\n        console.log(`${plb1} y ${plb2} comparten al menos una letra`);\n    } else {\n        console.log(`${plb1} y ${plb2} no comparten ninguna letra`);\n    }\n}\n\nprincipal();\n\nfunction palindromo(palabra, palabra2) {\n    return palabra.split('').reverse().join('') === palabra2.split('').join('');\n}\n\nfunction anagrama(palabra1, palabra2) {\n    return palabra1.toLowerCase().split(\"\").sort().join(\"\") === palabra2.toLowerCase().split(\"\").sort().join(\"\");\n    \n}\n\nfunction isograma(palabra1, palabra2) {\n    let letras1 = palabra1.toLowerCase().split(\"\");\n    let letras2 = palabra2.toLowerCase().split(\"\");\n\n    for (let letra of letras1) {\n        if (letras2.includes(letra)) {\n        return true;\n        }\n    }\n    return false;\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/jeronimocardu.js",
    "content": "let ejemplo1 = 'Hola mundo';\nlet ejemplo2 = 'Soy jeronimo';\n// Acceso a un caracter especifico\nconsole.log('Acceso a un caracter en especifico: ', ejemplo1[0]);\n\n// Subcadenas\nconsole.log('Subcadena de un string', ejemplo1.substring(0, 5));\n\n// Longitud\nconsole.log('Longitud del string: ', ejemplo1.length);\n\n// Concatenacion\nlet concatenacion = ejemplo1 + ', ' + ejemplo2;\nconsole.log('Concatenacion: ', concatenacion);\n\n// Repeticion\nlet cadenaRepetida = ejemplo1.repeat(5);\nconsole.log('Cadena repetida: ', cadenaRepetida);\n\n// Recorrido\nfor(let i of ejemplo1){\n    console.log(i);\n}\n\n// Conversion a Mayus y Minus\nconsole.log('String en Minusculas: ', ejemplo1.toLowerCase());\nconsole.log('String en Mayusculas: ', ejemplo1.toUpperCase());\n\n// Reemplazo\nconsole.log('String remplazado: ', ejemplo1.replace('Hola', 'Chau'));\n\n// Division\nlet cadenaWords = ejemplo1.split(' ');\nconsole.log('Division de string: ', cadenaWords);\n\n// Union\nconsole.log('Union del string: ', cadenaWords.join(' '));\n\n// Interpolacion\nconsole.log(`Esto es interpolacion: '${ejemplo1}' usando $ {}`);\n\n// Verificacion\nlet contiene = ejemplo1.includes('Hola');\nconsole.log('Contiene \"Hola\":', contiene);\n\n////////////////////////////////////////////////////////\n//              EXTRA\n\nfunction comparaciones(str1, str2){\n    // Políndromos\n    if(str1.toLowerCase() === str1.toLowerCase().split('').reverse().join('')){\n        console.log(`'${str1}' es Polídromos`);\n    }\n    if(str2.toLowerCase() === str2.toLowerCase().split('').reverse().join('')){\n        console.log(`'${str2}' es Polídromos`);\n    }\n\n    // Anagramas\n    if(str1.toLowerCase().split('').sort().join('') === str2.toLowerCase().split('').sort().join('')){\n        console.log(`${str1} y ${str2} Son Anagramas`);\n    }\n\n    // Isogramas\n    let isIsogram = true;\n    for(let i of str1.toLowerCase()){\n        if(str2.toLowerCase().includes(i)){\n            isIsogram = false;\n        }\n    }\n    if(isIsogram) console.log(`${str1} y ${str2} son Isogramas`);\n}\n\ncomparaciones('hola', 'efe')"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/jhoshmc.js",
    "content": "//! operaciones con cadenas\nfunction mayuscula_minusculas(text) {\n  //? transformar toda la cadena a mayuscula, toUpperCase()\n  console.log(\"\\n texto en mayusculas toUpperCase() \\n\");\n  console.log(\n    `texto normal: ${text} \\ntexto en mayusculas: `,\n    text.toUpperCase()\n  );\n\n  //? transformar toda la cadena en minuscula, toLowerCase()\n  console.log(\"\\n texto en minusculas toLowerCase() \\n\");\n  console.log(\n    `texto normal: ${text} \\ntexto en mayusculas: `,\n    text.toLowerCase()\n  );\n}\n\nfunction f_charAt(text) {\n  //? devolver un caracter de la cadena, con la posicion, con charAt()\n  console.log(\"\\n caracer de una cadena , charAt() \\n\");\n  let c = 0;\n  console.log(`el caracter ${c} es : ${text.charAt(c)}`);\n  console.log(`el caracter ${c + 1} es : ${text.charAt(c + 1)}`);\n}\n\nfunction f_indexOf(text) {\n  //? idexOf()\n  //* El método indexOf() retorna el primer índice en el que se puede encontrar un elemento\n  //* dado en el array, ó retorna - 1 si el elemento no esta presente.\n  //* devuelve la paosicion donde se encuentre el primer incice\n  console.log(\"\\n indexOf \\n\");\n  console.log(text);\n  console.log(`indexOf: l es:  ${text.indexOf(\"l\")}`);\n  console.log(`indexOf: todos : ${text.indexOf(\"todos\")}`);\n  //* se puede indicar desde que posicion comenzar a buscar\n  //* en ejemplo para imprimir los nombres de las personas que empiecen por la letra A\n  let personas = [\"Ana\", \"Juan\", \"Marcos\", \"Armando\", \"Miguel\", \"Amelia\"];\n  for (let iterador in personas) {\n    if (personas[iterador].indexOf(\"A\") == 0) {\n      console.log(personas[iterador]);\n    }\n  }\n}\n\nfunction f_lastIndexOf(text) {\n  console.log(\"\\n ultima coicidencia lastIndexOf()\\n\");\n  //? lastIndexOf(), es igual a indexOf, solo que este, en vez de enviar la posicion de la primira coincidencia\n  //* devuelve la posicionde la última coincidenta, si no la encontró devuelve -1\n  console.log(text);\n  console.log(\n    `devolver el indice de la ultima coincidencia: ${text.lastIndexOf(\"o\")}`\n  );\n}\n\nfunction f_replace(text) {\n  console.log(\"\\n replace()\\n\");\n  //? replace(),\n  //* devuelve una nueva cadena con los cambios realizados\n  console.log(text);\n  console.log(text.replace(\"todos\", \"muchos\"));\n}\nfunction opereacionesConCadenas() {\n  let text = \"Hola a todos\";\n\n  mayuscula_minusculas(text);\n  f_charAt(text);\n  f_indexOf(text);\n  f_lastIndexOf(text);\n  f_replace(text);\n  console.log(`\\n ----------------tamaño de el espacio----------\\n`);\n  console.log(`tamaño: ${text.length}`);\n  console.log(\"\\n ------ conectar cadenas de caracteres-----------\\n\");\n  console.log(`cadena unida: ${text + \" mucho gusto\"}`);\n  console.log(\"\\n ----- extraer cadnas ---------------\");\n  //* subsctring(), extrae subcadenas, develve la cadenas extraidas desde los indices firstIn y lastOut-1\n  console.log(\n    `extrayedo desde la poisicon 2 hasta la 5: ${text.substring(2, 5)}`\n  );\n  console.log(`esxtrayendo todo desde la posicion 7: ${text.substring(7)}`);\n}\n\nopereacionesConCadenas();\n\n//! Ejercicio extra\n\nconst redline = require(\"readline\");\nconst rl = redline.createInterface({\n  input: process.stdin,\n  output: process.stdout,\n});\n\nconst ask = (texto) => {\n  return new Promise((resolve) => rl.question(texto, resolve));\n};\nconst palindromo = (palabra) => {\n  let copia = palabra.split(\"\").reverse().join(\"\");\n  return palabra === copia;\n};\n\nconst anagrama = (palabra1, palabra2) => {\n  if (palabra1.length !== palabra2.length) {\n    return false;\n  }\n  palabra1 = palabra1.split(\"\").sort().join(\"\");\n  palabra2 = palabra2.split(\"\").sort().join(\"\");\n\n  return palabra1 == palabra2;\n};\n\nconst isograma = (palabra) => {\n  for (let i = 0; i < palabra.length - 1; i++) {\n    for (let j = i + 1; j < palabra.length; j++) {\n      if (palabra[i] == palabra[j]) {\n        return false;\n      }\n    }\n  }\n  return true;\n};\nasync function ejercicioExtra() {\n  const rejex = /\\s+/g;\n  let respuesta1, respuesta2, respuesta3;\n  let palabra1 = await ask(\"ingresa la primera palabra: \");\n  let palabra2 = await ask(\"ingresa la segunda palabar: \");\n  let comprimido1 = palabra1.replace(rejex, \"\").toLowerCase();\n  let comprimido2 = palabra2.replace(rejex, \"\").toLowerCase();\n  respuesta1 = palindromo(comprimido1);\n  respuesta2 = palindromo(comprimido2);\n  console.log(\"\\n\");\n  if (respuesta1) {\n    console.log(`la palabra: ${palabra1} es un palindromo`);\n  } else {\n    respuesta1 = isograma(comprimido1);\n    if (respuesta1) {\n      console.log(`la palabra: ${palabra1} es un isograma`);\n    }\n  }\n\n  if (respuesta2) {\n    console.log(`la palabra: ${palabra2} es un palindromo`);\n  } else {\n    respuesta2 = isograma(comprimido2);\n    if (respuesta2) {\n      console.log(`la palabra: ${palabra2} es un isograma`);\n    }\n  }\n  respuesta3 = anagrama(comprimido1, comprimido2);\n  if (respuesta3) {\n    console.log(\"\\n\");\n    console.log(\n      `las palabras: ${palabra1} y ${palabra2} conforman un anagrama`\n    );\n  }\n\n  rl.close();\n}\n\nejercicioExtra();\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/joapalobael.js",
    "content": "\nlet my_quote = \"Maybe I don't really want to know how your garden grows, 'Cause I just want to fly.\"\n//Cantidad de caracteres (incluye espacios)\nconsole.log(\"-------- Length→ Cantidad de caracteres --------\");\nconsole.log(my_quote.length - 1);\n// Un caracter individual\nconsole.log(\"-------- charAt→ Posición de un caracter en particular --------\");\nconsole.log(my_quote.charAt(71));\n// Subcadena dentro de cadena\nconsole.log(\"-------- indexOf→ Encuentra una subcadena dentro de una cadena --------\");\nlet a = \"know\";\nif (my_quote.toLocaleLowerCase().indexOf(a) !== -1) {\n    console.log(`Si, encontré la palabra: ${a}`)\n} else {\n    console.log('no se encuentra la palabra');\n}\nconsole.log(\"-------- Slice→ Extrae una subcadena dentro de una cadena, conociendo el inicio --------\");\n// Extraer una subcadena dentro de una cadena, conociendo el inicio\nconsole.log(my_quote.slice(71, 75));\n// Actualizar parte de una cadena\nconsole.log(\"-------- Replace→ Actualiza parte de una cadena --------\");\nconsole.log(my_quote.replace(\"fly\", \"swim\"));\n//Concatenación\nconsole.log(\"-------- Concatenación→ Suma cadena de textos --------\");\nlet part1 = \"Latlely, did you ever feel the pain?\"\nlet part2 = \"in the morning rain, as it soaks you to the bone.\"\nconsole.log(part1 + \" \" + part2);\nconsole.log(part1.concat(\" \", part2));\nconsole.log(\"-------- Interpolación→ template literals --------\");\nconsole.log(`${part1} ${part2}`)\n//Busqueda de ocurrencias\nconsole.log(\"-------- split+reduce → Busqueda de ocurrencias --------\");\nlet part1ToArray = part1.split('');\nlet counter = part1ToArray.reduce((objetoAcumulador, letra) => {\n    // console.log(`Acumulador: ${JSON.stringify(objetoAcumulador)}`);\n    // console.log(`Elemento Actual: ${letra}`);\n    objetoAcumulador[letra] = (objetoAcumulador[letra] || 0) + 1;\n    return objetoAcumulador;\n\n}, {});\nconsole.log(`El resultado final es: ${JSON.stringify(counter)}`);\n\n// Join\nconsole.log(\"-------- Join → Metodo para concatenar elementos de un array --------\");\nconsole.log(part1ToArray.join(\"\"));\n\nconsole.log(\"-------- Transformaciones numericas --------\");\nconst num1 = \"100793\"\nconsole.log(parseInt(num1));\nconst num2 = \"21.09\"\nconsole.log(parseFloat(num2));\n\nconsole.log(\"-------- Validar si es alpha o alphanumerico --------\");\n// En JS no existe las funciones como en phyton, pero se pueden crear con arrow functions\n\nconst isAlpha = (str) => /^[A-Za-z\\s.,?!]+$/.test(str);\nconst isAlnum = (str) => /^[A-Za-z0-9\\s.,?!]+$/.test(str);\n\nconsole.log(isAlnum(part2));\nconsole.log(isAlpha(num2));\n\n/*---- Ejercicio Extra ----*/\n//instale npm install prompt-sync\nconst prompt = require(\"prompt-sync\")({ sigint: true });\n\n// Palindromo\nfunction palindromoCheck() {\n    let esPalindromo = prompt('Ingrese una palabra para chequear si es Palindromo:');\n    // Cualquier caracter que NO sea A-Z o a-z o un espacio, se reemplazara con ''. /g significa global, no solo la primer coincidencia. \n    let palindromoNormalizado = esPalindromo.replace(/[^A-Za-z]/g, '').toLocaleLowerCase();\n    let palindromoInvertido = palindromoNormalizado.split('').reverse().join('');\n    if (palindromoNormalizado === palindromoInvertido) {\n        console.log(`Efectivamente, ${palindromoNormalizado} es un palíndromo`)\n    } else {\n        console.log(`No, ${palindromoNormalizado} no es un palindromo. El inverso es ${palindromoInvertido}`);\n    }\n}\npalindromoCheck();\n\n//Anagrama\nfunction anagramaCheck() {\n    let esAnagrama1 = prompt('Vamos a chequear si dos palabras son anagramas entre sí. Ingrese la primer palabra: ');\n    let esAnagrama2 = prompt('Ingrese la segunda palabra palabra: ');\n\n    let anagramaNormalizado1 = esAnagrama1.replace(/[^A-Za-z]/g, '').toLocaleLowerCase().split('').sort().join('');\n    let anagramaNormalizado2 = esAnagrama2.replace(/[^A-Za-z]/g, '').toLocaleLowerCase().split('').sort().join('');\n\n    if (anagramaNormalizado1 === anagramaNormalizado2) {\n        console.log(`Efectivamente, ${esAnagrama1} es un anagrama de ${esAnagrama2} porque utilizan las mismas letras: ${anagramaNormalizado1}`);\n    } else {\n        console.log(`No, ${esAnagrama1} no es un anagrama de ${esAnagrama2}`);\n    }\n\n}\nanagramaCheck();\n\n//Isograma\nfunction isogramaCheck() {\n    let esIsograma = prompt('Ingrese una palabra para validar si es un isograma: ');\n    let isogramaToArray = esIsograma.replace(/[^A-Za-z]/g, '').toLocaleLowerCase().split('');\n    let isoCounter = isogramaToArray.reduce((objetoAcumulador, letra) => {\n        // console.log(`Acumulador: ${JSON.stringify(objetoAcumulador)}`);\n        // console.log(`Elemento Actual: ${letra}`);\n        objetoAcumulador[letra] = (objetoAcumulador[letra] || 0) + 1;\n        return objetoAcumulador;\n\n    }, {});\n    let check = true;\n    for (const letra in isoCounter) {\n        if (isoCounter[letra] > 1) {\n            check = false;\n            break;\n        }\n    }\n\n    if (check) {\n        console.log(`¡Buenísimo! ${esIsograma} es un isograma.`);\n    } else {\n        console.log(`${esIsograma} no es un isograma. Se repiten algunas letras.`);\n    }\n}\nisogramaCheck();"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/juperdev.js",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n*/\n\n// Concatenation\n// Used + or concat()\nlet string = 'Hello,';\nlet string2 = ' world!';\nconsole.log(string + string2); // Hello, world!\nconsole.log(string.concat(string2)); // Hello, world!\n\n// String length\nlet stringLength = 'Good Morning!';\nconsole.log(stringLength.length); // 13\n\n// Slice String\n// slice assign number for start 0 (include) and number for the finish (exclude)\nlet sliceExample = 'Do you go to the park?'\nconsole.log(sliceExample.slice(0, 7)); // Do you\n\n// Index Of\n// Index of give you index where start the word.\nlet indexOfExample = 'My mom went shopping at Wallmart';\nconsole.log(indexOfExample.indexOf('went')); // 7\n\n// Split\n// Split process the string and return a array with de words separated for an any character that you choose.\nlet splitExample = 'Hi,how,are,you';\nconsole.log(splitExample.split(',')); // [ 'Hi', 'how', 'are', 'you' ]\n\n// Replace\n// Replace, search in the string the word that you give and replace for another one you give.\nlet replaceExample = 'on my way';\nconsole.log(replaceExample.replace('way', 'table')); // on my table\n\n// toUpperCase() / toLowerCase()\nlet exampleUpperLowerCase = 'She is a big woman.'\nconsole.log(exampleUpperLowerCase.toLowerCase()); // she is a big woman.\nconsole.log(exampleUpperLowerCase.toUpperCase()); // SHE IS A BIG WOMAN.\n\n// charAt: Return index from a string\n// this method init on 0\nlet exampleCharAt = 'Hello';\nconsole.log(exampleCharAt.charAt(0)); // H\n\n// Trim\n// This method erase blanks on the start and finish from a string.\nlet exampleTrim = '     Hellow     ';\nconsole.log(exampleTrim.trim()); // 'Hellow'\n\n// Repeat\n// This method repeats the text on a string any many times as you indicate.\nconsole.log(exampleCharAt.repeat(5)); // HelloHelloHelloHelloHello\n\n\n// endsWith/ startsWith\nconsole.log(exampleCharAt.startsWith('H')); // True\nconsole.log(exampleCharAt.endsWith('a')); // False\n\n// includes\n// This method verify if the string contain the word thar you indicate.\n// is case sensitive\nconsole.log(exampleCharAt.includes('Hello')); // True\n\n/*\n* DIFICULTAD EXTRA (opcional):\n* Crea un programa que analice dos palabras diferentes y realice comprobaciones\n* para descubrir si son:\n* - Palíndromos\n* - Anagramas\n* - Isogramas\n*/\n\n// Importamos elmódulo 'readline' de Node.js para poder recuperar los datos de terminal\nconst readline = require('readline');\n\n// Interfaz de lectura\n    const rl = readline.createInterface({\n        input: process.stdin,\n        output: process.stdout\n    });\n\nfunction readTerminal(){\n    rl.question('Elije la opción deseada:\\n1: Verificar si es palindromo\\n2: Verificar si es un anagrama\\n3: Verificar si es un isograma\\n0: Salir\\n ', (opcion) => {\n        if(opcion === '0'){\n            console.log('Se ha terminado la ejecución!')\n            rl.close();\n            process.exit(0);\n        } else if(opcion > 0 && opcion < 4){\n            opciones(opcion);\n        } else {\n\n        }\n    })\n}\n\n// Options\nfunction opciones(option){\n        switch (option) {\n        case '1':\n            console.log('opcion 1!!!!');\n            palindromo();\n            break;\n        case '2':\n            anagrama();\n            break;\n        case '3':\n            isograma();\n            break;\n    }\n}\n\n\n// Funcion Palíndromo\nfunction palindromo(){\n    rl.question('Ingrese la palabra a evaluar: ', palabra => {\n        let reverseWord = [];\n        let palabraArray = palabra.split('')\n        for(let i = 0; i < palabraArray.length; i++){\n            reverseWord.unshift(palabraArray[i]);\n\n        }\n        let str = reverseWord.join('');\n        (str === palabra) ? console.log('- - - - - - - - - - -\\nEs palindromo!\\n- - - - - - - - - -') : console.log('- - - - - - - - - - -\\nNo es palindromo!\\n- - - - - - - - - -');\n        readTerminal();\n    })\n}\n\nfunction anagrama(){\n    rl.question('Ingrese la primera palabra a comparar: ', palabra1 => {\n        rl.question('Ingrese la segunda palabra a comparar: ', palabra2 => {\n            let str = palabra1.split('').sort().join();\n            let str2 = palabra2.split('').sort().join();\n                if(str === str2){\n                    console.log('- - - - - - - - \\n Es un anagrama!\\n- - - - - - -'); \n                } else {\n                    console.log('- - - - - - - - \\n No es anagrama!\\n- - - - - - -');\n                    readTerminal();\n                }\n            readTerminal();         \n        })\n})};\n\nfunction isograma(){\n    let isIso = true;\n    rl.question('Ingrese la palabra para verificar si es un isograma: ', palabra => {\n        let str = palabra.split('').sort();\n        for(let i = 1; i <= str.length; i++){\n            if(str[i-1] === str[i]){\n                console.log('- - - - - - - - - - -\\nNo es un isograma!\\n- - - - - - - - - - -')\n                isIso = false;\n                break;\n            }\n        }\n        if(isIso){\n        console.log('- - - - - - - - - - -\\nEs un isograma :D!\\n- - - - - - - - - - -');\n        }\n        readTerminal();\n    })\n}\n\nreadTerminal();"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/kaesar84.js",
    "content": "/*\n# #04 CADENAS DE CARACTERES\n> #### Dificultad: Media | Publicación: 22/01/24 | Corrección: 29/01/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n\n\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n*/\n\n// Strings\n\n// Concatenación\nlet myName = \"John Wick\"\nlet greeting = \"Hello \" + myName\nconsole.log(greeting)\n\n// Longitud\nconsole.log(myName.length)\n\n// Acceso a un caracter\nconsole.log(myName[0])\n\n// Métodos comunes\nconsole.log(myName.toUpperCase())\nconsole.log(myName.toLowerCase())\nconsole.log(myName.indexOf(\"Wick\")) // donde encuentra la primera coincidencia -1 si no encuentra\nconsole.log(myName.includes(\"Wick\")) // true si la cadena contiene la cadena\nconsole.log(myName.slice(0, 6)) // extrae una parte de la cadena\nconsole.log(myName.replace(\"Wick\", \"Reaves\")) // reemplaza una cadena por otra\n\n// Templates literales\nlet despedida = \"Adiós\"\nlet message = `Hello ${myName} y estoy\nhaciendo cosas.\nHace los saltos de\nlínea.\n${despedida}.`\nconsole.log(message)\n\n// * DIFICULTAD EXTRA (opcional):\n//  * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n//  * para descubrir si son:\n//  * - Palíndromos\n//  * - Anagramas\n//  * - Isogramas\n\nfunction isPalindrome(string1, string2) {\n  let string1Lower = string1.toLowerCase()\n  let string2Lower = string2.toLowerCase()\n\n  if (string1Lower == string2Lower.split(\"\").reverse().join(\"\")) {\n    return `*** SON PALINDROMOS`\n  } else {\n    return `!!! NO SON PALINDROMOS`\n  }\n}\n\nfunction isAnagrame(string1, string2) {\n  let string1Lower = string1.toLowerCase()\n  let string2Lower = string2.toLowerCase()\n\n  if (string1Lower.length == string2Lower.length) {\n    let stringOrdenada1 = string1Lower.split(\"\").sort().join(\"\")\n    let stringOrdenada2 = string2Lower.split(\"\").sort().join(\"\")\n    if (stringOrdenada1 === stringOrdenada2) {\n      return `*** SON ANAGRAMAS`\n    } else {\n      return `!!! NO SON ANAGRAMAS`\n    }\n  } else {\n    return `!!! NO SON ANAGRAMAS`\n  }\n}\n\nfunction isIsoagrame(string1, string2) {\n  let string1Lower = string1.toLowerCase()\n  let string2Lower = string2.toLowerCase()\n  let charChecked = new Set()\n\n  for (let i = 0; i < string1Lower.length; i++) {\n    charChecked.add(string1Lower[i])\n  } // console.log(charChecked)\n\n  for (let i = 0; i < string2Lower.length; i++) {\n    if (charChecked.has(string2Lower[i])) {\n      return `!!! NO SON ISOGRAMAS.\\nCarácteres compartidos >> ${Array.from(\n        charChecked\n      )}  ***`\n    } else {\n      charChecked.add(string2Lower[i])\n      return `*** SON ISOGRAMAS,\\nNo comparten ningún carácter. ***`\n    } //console.log(charChecked)\n  }\n}\n\nfunction checkWord(string1, string2) {\n  console.log(\"\\n===========================\")\n  console.log(`>> PALABRA 1: ${string1}`)\n  console.log(`>> PALABRA 2: ${string2}`)\n  console.log(\"===========================\")\n  console.log(isPalindrome(string1, string2))\n  console.log(isAnagrame(string1, string2))\n  console.log(isIsoagrame(string1, string2))\n  console.log(\"===========================\")\n}\nlet wordOne = \"Amor\"\nlet wordTwo = \"Roma\"\n\ncheckWord(wordOne, wordTwo)\n\nwordOne = \"Spawn\"\nwordTwo = \"Rio\"\n\ncheckWord(wordOne, wordTwo)\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n_______________________________________\n#04 CADENAS DE CARACTERES\n---------------------------------------\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\n *   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\n *   interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n*/\n\n// ________________________________________________________\n// Declaraciones de cadenas\nconst str1 = \"Esto es una cadena\"; // Comillas dobles\nconst str2 = 'Esto es una cadena'; // Comillas simples\nconsole.log(typeof str2); // \"string\"\n\n// Salto de línea: \\n\nconst str4 = \"Primer linea\\nSegunda linea\";\nconsole.log(str4);\n\n// ASCII y Unicode\nconsole.log(\"\\u00F1\"); // Unicode para 'ñ'\n\n// Texto multilínea\nconsole.log(`Primer linea\nSegunda linea\nTercer linea`);\n\n// Longitud de la cadena\nconst s = \"abcdef\";\nconsole.log(s.length); // 6\n\n// Acceso a caracteres individuales\nconsole.log(s[1]); // \"b\"\n\n// Obtener porciones específicas de una cadena\nconsole.log(s.slice(1, 4)); // \"bcd\"\nconsole.log(s.slice(3)); // \"def\"\n\n// Revertir una cadena\nconsole.log(\"abcd\".split('').reverse().join(''));\n\n// ________________________________________________________\n// Formateo de cadenas:\n\n// Concatenación\nconst s1 = \"hola\";\nconst s2 = \"javascript\";\nconsole.log(`${s1}, ${s2}`);\n\n// Interpolación\nconst a = 5, b = 10;\nconsole.log(`Los números son ${a} y ${b}`);\n\n// Replicación o repetición de cadenas\nconst greeting = \"Hola \";\nconsole.log(greeting.repeat(3));\n\n// Valor numérico que representa un carácter y viceversa\nconsole.log(String.fromCharCode(241)); // \"ñ\"\nconsole.log(\"ñ\".charCodeAt(0)); // 241\n\n// Ordenar caracteres de una cadena\nconsole.log(\"cdba\".split('').sort().join(''));\n\n// ________________________________________________________\n// Métodos:\n\nconst txt = \"Hello, javascript!\";\nconsole.log(txt.includes(\"javascript\")); // true\nconsole.log(txt.indexOf(\"javascript\")); // 7\nconsole.log(txt.replace(\"javascript\", \"world\"));\nconsole.log(\"mi cadena\".charAt(0).toUpperCase() + \"mi cadena\".slice(1));\nconsole.log(\"MI CADENA\".toLowerCase());\nconsole.log(\"mI cAdEnA\".split('').map(c => c === c.toUpperCase() ? c.toLowerCase() : c.toUpperCase()).join(''));\nconsole.log(\"mi cadena\".toUpperCase());\nconsole.log(\"mi cadena\".split(' ').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' '));\n\nconst txt2 = \"Cantando y llorando.\";\nconsole.log((txt2.match(/ando/g) || []).length); // 2\nconsole.log(\"aeiou1234\".match(/^[a-z0-9]+$/i) !== null); // true\nconsole.log(\"abcdefg\".match(/^[a-z]+$/i) !== null); // true\nconsole.log(\"12345\".match(/^[0-9]+$/) !== null); // true\nconsole.log(\"abc\".toLowerCase() === \"abc\"); // true\nconsole.log(\"ABC\".toUpperCase() === \"ABC\"); // true\nconsole.log(/^\\s+$/.test(\"   \")); // true\nconsole.log(\"  abc  \".trim()); // \"abc\"\nconsole.log(\"123\".padStart(5, '0')); // \"00123\"\nconsole.log([\"1\", \"2\", \"3\"].join(\" y \")); // \"1 y 2 y 3\"\nconsole.log(\"a,b,c\".split(\",\")); // [\"a\", \"b\", \"c\"]\n\n// ________________________________________________________\n// DIFICULTAD EXTRA\n\nfunction analyze(str1, str2) {\n    const esPalindromo = str => str === str.split('').reverse().join('');\n    const esAnagrama = (str1, str2) => str1.split('').sort().join('') === str2.split('').sort().join('');\n    const esIsograma = str => new Set(str).size === str.length;\n\n    console.log(`\\n    \"${str1}\" es un palíndromo?: ${esPalindromo(str1)}\n    \"${str2}\" es un palíndromo?: ${esPalindromo(str2)}\n\n    \"${str1}\" es un anagrama de \"${str2}\"?: ${esAnagrama(str1, str2)}\n\n    \"${str1}\" es un isograma?: ${esIsograma(str1)}\n    \"${str2}\" es un isograma?: ${esIsograma(str2)}\\n`);\n}\n\nanalyze(\"reconocer\", \"vida\");\nanalyze(\"notas\", \"santo\");\nanalyze(\"héroe\", \"radar\");\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/kodenook.js",
    "content": "\nlet txt = 'hello, javascript!'\n\nconsole.log(txt.charAt(4))\nconsole.log(txt.toUpperCase())\nconsole.log(txt.toLowerCase())\nconsole.log(txt.trim())\nconsole.log(txt.repeat(2))\nconsole.log(txt.replace('h', 'j'))\nconsole.log(txt.split(' '))\nconsole.log(txt.endsWith('script!'))\nconsole.log(txt.startsWith('hello'))\n\n/**\n * The function checks if a word is a palindrome, an anagram, or an isogram.\n * @param word - The first parameter \"word\" is a string that you want to check if it is a palindrome,\n * an anagram, or an isogram.\n * @param word2 - The parameter `word2` is a second word that will be compared to the first word for\n * anagram check.\n */\nfunction typeWord(word, word2) {\n\n    if (word === word.split('').reverse().join('')) {\n        console.log('is palindrome')\n    }\n\n    if (word.split('').sort().join('') == word2.split('').sort().join('')) {\n        console.log('is an anagram')\n    }\n\n    if (word.length === new Set(word).size) {\n        console.log('is isogram')\n    }\n}\n\ntypeWord('roma', 'amor')"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/marcode24.js",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\n// Operaciones comunes con cadenas de caracteres\n\n// Acceso a caracteres específicos\nconst cadena = 'Hola, mundo!';\nconsole.log('Carácter en la posición 0:', cadena[0]);\n\n// Subcadenas\nconst subcadena = cadena.substring(2, 6);\nconsole.log('Subcadena:', subcadena);\n\n// Longitud de la cadena\nconsole.log('Longitud de la cadena:', cadena.length);\n\n// Concatenación\nconst otraCadena = ' Qué tal?';\nconst cadenaConcatenada = cadena + otraCadena;\nconsole.log('Cadena concatenada:', cadenaConcatenada);\n\n// Repetición\nconst cadenaRepetida = cadena.repeat(3);\nconsole.log('Cadena repetida 3 veces:', cadenaRepetida);\n\n// Recorrido\nfor (let i = 0; i < cadena.length; i++) {\n  console.log('Carácter en posición', i, ':', cadena[i]);\n}\n\n// Conversión a mayúsculas y minúsculas\nconst mayusculas = cadena.toUpperCase();\nconst minusculas = cadena.toLowerCase();\nconsole.log('Mayúsculas:', mayusculas);\nconsole.log('Minúsculas:', minusculas);\n\n// Reemplazo\nconst nuevaCadena = cadena.replace('mundo', 'amigo');\nconsole.log('Cadena con reemplazo:', nuevaCadena);\n\n// División\nconst palabras = cadena.split(' ');\nconsole.log('Palabras divididas:', palabras);\n\n// Unión\nconst union = palabras.join('-');\nconsole.log('Palabras unidas con guiones:', union);\n\n// Interpolación\nconst nombre = 'Juan';\nconst edad = 30;\nconst mensaje = `Hola, me llamo ${nombre} y tengo ${edad} años.`;\nconsole.log('Mensaje interpolado:', mensaje);\n\n// Verificación\nconst contieneHola = cadena.includes('Hola');\nconsole.log(\"¿La cadena contiene 'Hola'?\", contieneHola);\n\n// Programa que verifica palíndromos, anagramas e isogramas\n\nfunction esPalindromo(palabra) {\n  const palabraInvertida = palabra.split('').reverse().join('');\n  return palabra === palabraInvertida;\n}\n\nfunction esAnagrama(palabra1, palabra2) {\n  const ordenPalabra1 = palabra1.split('').sort().join('');\n  const ordenPalabra2 = palabra2.split('').sort().join('');\n  return ordenPalabra1 === ordenPalabra2;\n}\n\nfunction esIsograma(palabra) {\n  const caracteresUnicos = new Set(palabra);\n  return palabra.length === caracteresUnicos.size;\n}\n\n// Ejemplos\nconst palabra1 = 'oso';\nconst palabra2 = 'soso';\nconsole.log(`\"${palabra1}\" es palíndromo:`, esPalindromo(palabra1));\nconsole.log(\n  `\"${palabra1}\" es anagrama de \"${palabra2}\":`,\n  esAnagrama(palabra1, palabra2),\n);\nconsole.log(`\"${palabra1}\" es isograma:`, esIsograma(palabra1));\n\n// Visita mi repo en GitHub para ver y correr los tests de este código --> https://github.com/marcode24/weekly-challenges\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/maximiliano1997.js",
    "content": "\r\n/*\r\n * EJERCICIO:\r\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\r\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\r\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\r\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\r\n *\r\n * DIFICULTAD EXTRA (opcional):\r\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\r\n * para descubrir si son:\r\n * - Palíndromos\r\n * - Anagramas\r\n * - Isogramas\r\n */\r\n\r\n\r\n\r\n\r\n// SOLUCION:\r\n\r\n\r\n\r\n/////////////////////////////// Metodos de Cadena (String Methods) ///////////////////////////\r\n\r\n// Cadenas de Caracteres:\r\nlet cadena1 = 'Gracias, MoureDev'\r\nlet cadena2 = 'Gracias por todo'\r\nlet cadena3 = 'Adios a todos'\r\n\r\n// Longitud String: .length\r\nconst longitud = cadena1.length\r\nconsole.log(longitud)\r\n\r\n\r\n// Acceso a caracteres especificos:   [], .charAt(), .at()\r\n//                                      Acceso por Indice con corchetes\r\nconsole.log(cadena2[0])\r\nconsole.log(cadena2[-1])\r\n\r\n//                                      Acceso con metodo .charAt(index)\r\nconsole.log(cadena2.charAt(0))\r\nconsole.log(cadena2.charAt(-1))\r\n\r\n//                                      Acceso con metodo .at(index)\r\nconsole.log(cadena2.at(0))\r\nconsole.log(cadena2.at(-1))\r\n\r\n\r\n// SUBCADENAS:      .slice(), .substring()\r\n//\r\nconsole.log(cadena3.substring('0, 4'))\r\nconsole.log(cadena3.slice(5))\r\nconsole.log(cadena3.slice(-2))\r\n\r\n\r\n// CONCATENACION:   +, .concat()\r\n\r\nconsole.log(cadena1 + \" \" + cadena2)\r\nconsole.log(cadena1.concat(\" \", cadena2))\r\n\r\n\r\n//  REPETICION:  .repeat()\r\nconsole.log('JS'.repeat(6))\r\n\r\n// RECORRIDO DE CARACTERES: for...of\r\nfor (let x of cadena1) {\r\n    console.log(x)\r\n}\r\n\r\n\r\nconsole.warn('\\n-------- CONVERSION MAYUSCULAS Y MINUSCULAS .toUpperCase(), .toLowerCase() --------\\n')\r\n\r\n// CONVERSION A MAYISCULAS Y MINUSCULAS:    .toUpperCase(), .toLowerCase()\r\nconsole.log(cadena1.toUpperCase())\r\nconsole.log(cadena1.toLowerCase())\r\n\r\nconsole.warn('\\n---------------------------- REEMPLAZO ---------------------\\n')\r\n\r\n// REEMPLAZO:   .replace(), .replaceAll()\r\nconsole.log(cadena3.replace('Adios', 'Gracias'))\r\nconsole.log(cadena3.replaceAll('o', '0'))\r\nconsole.log(cadena3.replace(/o/g, 'Y'))\r\n\r\nconsole.warn('\\n----------------------- DIVISION EN PARTES .split(), .join() ---------------------\\n')\r\n// DIVISION EN PARTES: .split(), .join()\r\nconsole.warn('\\n   \\n')\r\n\r\nconsole.log(cadena1.split(\" \"))\r\nconsole.log('1,2,3'.split(','))\r\n\r\nconsole.warn('\\n---------------------------- UNION ---------------------\\n')\r\n// UNION:\r\nlet arrCadenas = [cadena1, cadena2]\r\nconsole.log(arrCadenas.join(' '))\r\n\r\nconsole.warn('\\n---------------------------- INTERPOLACION ---------------------\\n')\r\n// INTERPOLACION: `${var}`\r\nlet nombre = 'Imanol'\r\nconsole.log(`Hola, mi nombre es ${nombre} y solo quiero decir... ${cadena1} `)\r\n\r\nconsole.warn('\\n---------------------------- VERIFICACION ---------------------\\n')\r\n// VERIFICACION:    .includes(), .startsWith(), .endsWith()\r\ncadena1.includes('MoureDev')\r\ncadena1.startsWith('a')\r\ncadena1.endsWith('v')\r\ncadena1.indexOf('Gracias')\r\ncadena1.lastIndexOf('o')\r\n\r\n\r\nconsole.warn('\\n---------------------------- ELIMINACION DE ESPACIOS ---------------------\\n')\r\n// ELIMINACION DE ESPACIOS: .trim(), .trimStart(), .trimEnd()\r\nlet cadenaConEspacios = '   Benvenidos  '\r\nconsole.log(cadenaConEspacios.trim())\r\nconsole.log(cadenaConEspacios.trimStart())\r\nconsole.log(cadenaConEspacios.trimEnd())\r\n\r\n\r\nconsole.warn('\\n---------------------------- COMPARACION DE CADENAS ---------------------\\n')\r\n// COMPARACION DE CADENAS:  ===, <, >\r\nconsole.log('1' === 1)\r\nconsole.log(2 < 5)\r\n\r\n\r\nconsole.warn('\\n---------------------------- REEMPLAZO ---------------------\\n')\r\n// REEMPLAZO:\r\nlet texto = 'Imanol Aguer'\r\nlet nuevoTexto = texto.slice(0, 5) + 'Maximiliano'\r\nconsole.log(`Texto ORIGINAL: ${texto}        Texto Nuevo: ${nuevoTexto}`)\r\n\r\nconsole.warn('\\n---------------------------- CONVERTIR ---------------------\\n')\r\n// CONVERTIR:\r\nlet cadena4 = '1'\r\nlet cadena5 = 5\r\nconsole.log(Number(cadena4))\r\nconsole.log(String(cadena5))\r\nconsole.log((157).toString())\r\n\r\nconsole.warn('\\n---------------------------- REPETICION ---------------------\\n')\r\n// REPETICION:\r\nconsole.log('Imanol '.padStart(3, 'Aguer'))\r\nconsole.log('Imanol '.padEnd(3, 'I'))\r\n\r\nconsole.warn('\\n---------------------------- REGULAR EXPRESSIONS ---------------------\\n')\r\n// EXPRESIONES REGULARES:\r\nconsole.log('ima123'.match('/\\d+/'))\r\nconsole.log('ima123'.replace('/\\d+/', ''))\r\n\r\n\r\nconsole.warn('\\n---------------------------- INVERTIR UNA CADENA ---------------------\\n')\r\n// INVERTIR UNA CADENA:\r\nconsole.log(cadena1.split('').reverse().join(''))\r\n\r\n\r\n\r\n\r\n//  DIFICULTAD EXTRA(opcional):\r\n//  * Crea un programa que analice dos palabras diferentes y realice comprobaciones\r\n//     * para descubrir si son:\r\n//     * - Palíndromos\r\n//     * - Anagramas\r\n//     * - Isogramas\r\n\r\n\r\nconst readline = require('readline')\r\nconst { stdin: input, stdout: output } = require('node:process')\r\n\r\nconst rl = readline.createInterface({ input, output })\r\n\r\n\r\nfunction programa() {\r\n    console.warn('\\n\\n\\n---------------------------- BIENVENIDO A TU PROGRAMA ---------------------\\n')\r\n    console.log(`\r\n        Bienvenido al Programa: \r\n        (0) - Verificacion Total\r\n        (1) - Verificacin de Palindromos\r\n        (2) - Verificacin de Anagramas\r\n        (3) - Verificacin de Isogramas\r\n        `)\r\n\r\n\r\n    var todo = 1\r\n    const returnToMenu = () => {\r\n        const clear = () => console.clear()\r\n        if (todo == 1 || todo == 2 || todo == 3) {\r\n            rl.question('Desea continuar con el programa o cerrarlo: (y/n):  ', (respuesta) => {\r\n                if (respuesta === 'y') {\r\n                    clear()\r\n                    programa()\r\n                } else {\r\n                    clear()\r\n                    rl.close()\r\n                }\r\n            })\r\n        } else {\r\n            rl.close()\r\n        }\r\n    }\r\n\r\n    rl.question('Eliga un (numero) para avanxar: ', (optionMethod) => {\r\n        switch (optionMethod) {\r\n            case '1':\r\n                todo = 1\r\n                rl.question('Ingrese la Plabra 1: ', (palabraUno) => {\r\n                    rl.question('Ingrese la Palabra 2: ', (palabraDos) => {\r\n                        checkForPalindromo(palabraUno, palabraDos)\r\n                    })\r\n                })\r\n                break\r\n            case '2':\r\n                todo = 2\r\n                rl.question('Ingrese la Plabra 1: ', (palabraUno) => {\r\n                    rl.question('Ingrese la Palabra 2: ', (palabraDos) => {\r\n                        checkForAnagrama(palabraUno, palabraDos)\r\n                    })\r\n                })\r\n                break\r\n            case '3':\r\n                todo = 3\r\n                rl.question('Ingrese la Plabra 1: ', (palabraUno) => {\r\n                    rl.question('Ingrese la Palabra 2: ', (palabraDos) => {\r\n                        checkForIsograma(palabraUno, palabraDos)\r\n                    })\r\n                })\r\n                break\r\n            case '0':\r\n                rl.question('Ingrese la Plabra 1: ', (palabraUno) => {\r\n                    rl.question('Ingrese la Palabra 2: ', (palabraDos) => {\r\n                        checkForPalindromo(palabraUno, palabraDos)\r\n                        checkForAnagrama(palabraUno, palabraDos)\r\n                        checkForIsograma(palabraUno, palabraDos)\r\n                        todo = 1\r\n                    })\r\n                })\r\n                break;\r\n        }\r\n    })\r\n\r\n\r\n\r\n    const checkForPalindromo = (palabraUno, palabraDos) => {\r\n        console.log('\\n\\n ----- Resultado Palindromo -----')\r\n\r\n        const palabra1 = palabraUno.toLowerCase().split('').reverse().join('')\r\n        const palabra2 = palabraDos.toLowerCase().split('').reverse().join('')\r\n        console.log('Palabra numero 1 a testear --> ', palabra1)\r\n        console.log('Palabra numero 2 a testear --> ', palabra2)\r\n\r\n        let db = [palabra1, palabra2]\r\n\r\n\r\n        for (let i = 0; i < db.length; i++) {\r\n            if (db[i] === palabraUno || db[i] === palabraDos) {\r\n                console.log(`${db[i]} es un Palindromo Completamente`)\r\n            } else {\r\n                console.log(`${db[i]} no es un Palindromo`)\r\n            }\r\n        }\r\n\r\n        returnToMenu()\r\n    }\r\n\r\n\r\n    const checkForAnagrama = (palabraUno, palabraDos) => {\r\n        console.log('\\n\\n ----- Resultado Anagrama -----')\r\n\r\n        const palabra1 = palabraUno.split('').sort().join(0)\r\n        const palabra2 = palabraDos.split('').sort().join(0)\r\n\r\n\r\n        if (palabra1 === palabra2) {\r\n            console.log(` SI ${palabraUno} y ${palabraDos} son Anagramas.`)\r\n        } else {\r\n            console.log(`NO ${palabraUno} y ${palabraDos} no son Anagramas.`)\r\n        }\r\n\r\n        returnToMenu()\r\n    }\r\n\r\n    const checkForIsograma = (palabraUno, palabraDos) => {\r\n        console.log('\\n\\n ----- Resultado Isograma -----')\r\n        console.log('Not available at the Moment!')\r\n        returnToMenu()\r\n    }\r\n\r\n}\r\n\r\nprograma()\r\n\r\n\r\n\r\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/miguelex.js",
    "content": "// Operaciones básicas sobre cadenas de texto\nconst texto = \"Hola, mundo!\";\n\n// Interpolación de cadenas (uso de plantillas de cadena)\nconst nombre = \"Migue\";\nconst lenguaje = \"PHP\";\nconst mensaje = `Hola, me llamo ${nombre} y trabajo con ${lenguaje} años.`;\nconsole.log(mensaje);\n\n// Longitud de la cadena\nconst longitud = texto.length;\nconsole.log(`La longitud de la cadena ${texto} es ${longitud} caracteres`);\n\n// Obtener el carácter en una posición específica\nconst primerCaracter = texto[0];\nconsole.log(`El primer carácter de ${texto} es ${primerCaracter}`);\n\n// Concatenar dos cadenas\nconst nuevaCadena = texto + \" TypeScript\";\nconsole.log(`La nueva cadena de unir ${texto} con TypeScript es ${nuevaCadena}`);\n\n// Convertir la cadena a minúsculas\nconst minusculas = texto.toLowerCase();\nconsole.log(`${texto} en minúsculas es ${minusculas}`);\n\n// Convertir la cadena a mayúsculas\nconst mayusculas = texto.toUpperCase();\nconsole.log(`${texto} en mayúsculas es ${mayusculas}`);\n\n// Obtener una subcadena\nconst subcadena = texto.substring(0, 4);\nconsole.log(`La subcadena de ${texto} entre las posiciones 0 y 4 es ${subcadena}`);\n\n// Reemplazar parte de la cadena\nconst reemplazada = texto.replace(\"Hola\", \"Saludos\");\nconsole.log(`Vamos a reemplazar Hola por Saludos: ${reemplazada}`);\n\n// Operaciones adicionales sobre cadenas de texto\nconst textoConEspacios = \"   Hola,      mundo!   \";\n\n// Eliminar espacios en blanco al principio y al final\nconst sinEspaciosExtremos = textoConEspacios.trim();\nconsole.log(`Cadena sin espacios al principio y al final: ${sinEspaciosExtremos}`);\n\n// Eliminar todos los espacios en blanco\nconst sinEspacios = textoConEspacios.replace(/\\s/g, \"\");\nconsole.log(`Cadena sin espacios: ${sinEspacios}`);\n\n// Unión de dos cadenas\nconst cadena1 = \"Moure\";\nconst cadena2 = \"Dev\";\nconst unionCadenas = cadena1.concat(\" \", cadena2);\nconsole.log(`La unión de las cadenas ${cadena1} y ${cadena2} es ${unionCadenas}`);\n\n// Intersección de dos cadenas (caracteres comunes)\nconst interseccionCadenas = [...new Set(cadena1)].filter(char => cadena2.includes(char)).join(\"\");\nconsole.log(`Intersección de las cadenas ${cadena1} y ${cadena2} es ${interseccionCadenas}`);\n\n// Acceso a caracteres específicos (por posición)\nconst tercerCaracter = texto.charAt(2);\nconsole.log(`El tercer carácter de ${texto} es ${tercerCaracter}`);\n\n// Repetición de una cadena\nconst cadenaRepetida = \"Hola \".repeat(3);\nconsole.log(`Cadena Hola repetida 3 veces queda ${cadenaRepetida}`);\n\n// Recorrido de una cadena (usando un bucle)\nfor (let i = 0; i < texto.length; i++) {\n  console.log(`Carácter en posición ${i}: ${texto[i]}`);\n}\n\n// Conversión a título (primera letra en mayúscula)\nconst titulo = texto.toLowerCase().replace(/\\b\\w/g, (char) => char.toUpperCase());\nconsole.log(`La cadena ${texto} como título ${titulo}`);\n\n// División de una cadena en un array de substrings\nconst palabras = texto.split(\" \");\nconsole.log(`Palabras en la cadena ${texto} son ${palabras}`);\n\n// Verificación de si una cadena comienza o termina con ciertos caracteres\nconst comienzaCon = texto.startsWith(\"Hola\");\nconsole.log(`¿La cadena ${texto} comienza con \"Hola\"? ${comienzaCon}`);\n\nconst terminaCon = texto.endsWith(\"mundo!\");\nconsole.log(`¿La cadena ${texto}termina con \"mundo!\"? ${terminaCon}`);\n\n// Verificar si una cadena es palíndromo\nfunction esPalindromo(cadena) {\n  const sinEspacios = cadena.replace(/\\s/g, \"\").toLowerCase();\n  const invertida = sinEspacios.split(\"\").reverse().join(\"\");\n  return sinEspacios === invertida;\n}\n\n// Verificar si una cadena es un anagrama\nfunction esAnagrama(cadena1, cadena2) {\n  const limpiarCadena = (cadena) => cadena.replace(/\\s/g, \"\").toLowerCase();\n  const limpiaCadena1 = limpiarCadena(cadena1);\n  const limpiaCadena2 = limpiarCadena(cadena2);\n\n  const ordenada1 = limpiaCadena1.split(\"\").sort().join(\"\");\n  const ordenada2 = limpiaCadena2.split(\"\").sort().join(\"\");\n\n  return ordenada1 === ordenada2;\n}\n\n// Verificar si una cadena es un isograma\nfunction esIsograma(cadena) {\n  const caracteres = new Set();\n\n  for (const char of cadena) {\n    const caracter = char.toLowerCase();\n    if (caracteres.has(caracter)) {\n      return false;\n    }\n    caracteres.add(caracter);\n  }\n\n  return true;\n}\n\n// Ejemplos de uso de las funciones adicionales\nconsole.log(`¿Es \"${texto}\" un palíndromo? ${esPalindromo(texto)}`);\nconsole.log(`¿Es Ana un palíndromo? ${esPalindromo(\"Ana\")}`);\nconsole.log(`¿Es \"listen\" un anagrama de \"silent\"? ${esAnagrama(\"listen\", \"silent\")}`);\nconsole.log(`¿Es \"programming\" un isograma? ${esIsograma(\"programming\")}`);\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/natalyjoanna.js",
    "content": "\n\nlet cadena = \"Hola soy una Cadena primitiva!\"\nlet cadena_obj = new String(cadena) // Objeto String\nconsole.log(typeof cadena)\nconsole.log(typeof cadena_obj) //\n\nlet animal = \"cat\"\nlet pet = \"DOG\"\n\n// Acceder a un caracter especifico\nconsole.log(animal.charAt(1))\nconsole.log(animal[2])\n\n// Comparar cadenas\nlet a = \"a\"\nlet b = \"b\"\nif (a<b) {\n  console.log(`${a} es menor que ${b}`)\n} else if (a>b) {\n  console.log(`${a} es mayor que ${b}`)\n} else {\n  console.log(`${a} y ${b} son iguales`)\n}\n\n// Concatenacion\nconsole.log(a + \", \" + b)\nconsole.log(animal.concat(' ', pet))\n\n// Cadenas literales largas\n\nlet cadenaLarga = \n\"Lorem Ipsum is simply dummy text of the printing and typesetting industry.\\\nLorem Ipsum is simply dummy text of the printing and typesetting industry.\\\n It has survived not only five centuries, but also the leap into electronic typesetting,\"\nconsole.log(cadenaLarga)\n\n// Longitud\nconsole.log(cadenaLarga.length)\n\n// Repeticion\nconsole.log(animal.repeat(3))\n\n// Porcion\nconsole.log(cadena.slice(0,4))\nconsole.log(cadena.substring(15,19))\n\n// Busqueda\nconst regex = /[^\\w\\s']/g\nconsole.log(cadena.search(regex))\nconsole.log(cadena[cadena.search(regex)])\nconsole.log(cadena.indexOf(\"primitiva\"))\nconsole.log(cadena.match(/[A-Z]/g)) // Busca caracteres que coincidan\n \n// Busqueda | Termina en...\nconsole.log(cadena.endsWith(\"!\"))\nconsole.log(cadena.endsWith(\"?\"))\n\n// Busqueda | Empieza en...\nconsole.log(cadena.startsWith(\"Hola\"))\nconsole.log(cadena.startsWith(\"Adios\"))\n\n// Busqueda | buscar palabra en cadena\nconst word = \"primitiva\"\nconsole.log( `La palabra \"${word}\" ${\n  cadena.includes(word) ? \"esta\" : \"no esta\"\n} en la oracion` )\n\n// Dividir y buscar palabras\nconst palabra = cadena.split(' ')\nconsole.log(palabra[3])\n\n// Reemplazar\nconsole.log(cadena.replace(\"una\", \"la\"))\nlet cadena2 = \"Un perro y otro perro\"\nconsole.log(cadena2.replaceAll('perro', 'caballo'))\n\n// mayusculas y minusculas\nconsole.log(animal.toUpperCase())\nconsole.log(pet.toLowerCase())\n\n\nconsole.log(String.fromCodePoint(9731, 9733, 9842, 0x2f804));\n\n// Aumentar el largo al final de la cadena\nconsole.log(cadena.padEnd(35, '.'))\n\n// Aumentar el largo al principio de la cadena\nlet num = '5'\nconsole.log(num.padStart(2, '0'))\nlet longnum = '0000000000114'\nconst cutNum = longnum.slice(-3)\nconsole.log(cutNum.padStart(longnum.length, \"*\"))\n\n// Iteracion\nconst iterator = cadena[Symbol.iterator]()\nlet char = iterator.next()\nwhile (!char.done && char.value !==' ') {\n  console.log(char.value)\n  char = iterator.next()\n}\n\n// Eliminacion de espacios principio y final\nconsole.log(\"    Hello    \".trimStart())\nconsole.log(\"    Hello    \".trimEnd())\nconsole.log(\"    Hello    \".trim())\n\n// Retornar un valor string\nconsole.log(cadena_obj)\nconsole.log(cadena_obj.valueOf())\n\n// DIFICULTAD EXTRA\n\nconst readLine = require('readline');\nconst rl = readLine.createInterface({\n  input: process.stdin,\n  output: process.stdout\n})\n\nfunction menuPalabras() {\n  rl.question('Introduce una palabra: ', (palabra1) => {\n    rl.question('Introduce otra palabra: ', (palabra2) => {\n      if (palabra1 && palabra2) {\n        menu(String(palabra1), String(palabra2))\n      } else {\n        console.log('Debes introducir las dos palabras');\n        menuPalabras();\n      }\n    })\n  })\n}\n\nfunction menu(p1, p2) {\n  p1 = p1.toLowerCase();\n  p2 = p2.toLowerCase();\n\n  let palabra1 = p1.split('')\n  let palabra2 = p2.split('')\n\n  console.log('\\n1. Son palindromos?')\n  console.log('2. Son anagramas?')\n  console.log('3. Son isogramas?')\n  console.log('4. Volver a introducir las palabras')\n  console.log('5. Salir')\n\n  rl.question('\\nElige una opcion: ', (opcion) => {\n    switch (opcion) {\n      case '1':\n        if(isPalindromo(palabra1, palabra2)) {\n          console.log('Son palindromos')\n          menu(p1, p2)\n        } else {\n          console.log('No son palindromos')\n          menu(p1, p2)\n        }\n        break;\n      case '2':\n        if(isAnagrama(palabra1, palabra2)) {\n          console.log('Son anagramas')\n        } else {\n          console.log('No son anagramas')\n        }\n        menu(p1, p2)\n        break;\n      case '3':\n        if(isIsograma(palabra1) && isIsograma(palabra2)) {\n          console.log('Son isogramas')\n        } else if (isIsograma(palabra1)) {\n          console.log(`La palabra ${palabra1} es isograma pero la ${palabra2} no lo es`)\n        } else if (isIsograma(palabra2)) {\n          console.log(`La palabra ${palabra2} es isograma pero la ${palabra1} no lo es`)\n        } else {\n          console.log('No son isogramas')\n        }\n        menu(p1, p2)\n        break;\n      case '4':\n        menuPalabras()\n        break;\n      case '5':\n        console.log('Saliendo...')\n        rl.close()\n        break;\n      default:\n        console.log('elige una de las opciones')\n        menu(p1, p2)\n    }\n  })\n}\n\nfunction isPalindromo(palabra1, palabra2) {\n  let i = 0\n  let j = palabra2.length-1\n  while (i <= palabra1.length-1 && j>=0) {\n    if(palabra1[i] !== palabra2[j]) return false\n    i++\n    j--\n  }\n  return true\n}\n\nfunction isAnagrama(palabra1, palabra2) {\n\n  let i=0\n\n  while (i<=palabra1.length-1) {\n    let j=0\n    while(j<=palabra2.length-1) {\n      if(palabra1[i] === palabra2[j]){\n        palabra2.splice(j,1)\n        console.log(palabra2)\n        j--\n      }\n      j++ \n    }\n    i++\n  }\n\n  if(palabra2.length === 0) {\n    return true\n  } else {\n    return false\n  }\n}\n\nfunction isIsograma(palabra) {\n  let i=0\n\n  while(i<=palabra.length-1) {\n    let j= i+1\n    while(j<=palabra.length-1) {\n      if(palabra[i]===palabra[j]) {\n        return false\n      } else {\n        j++\n      }\n    }\n    i++\n  }\n  return true\n}\n\nmenuPalabras()"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/nlarrea.js",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\n// CREATE A STRING\n\nconst myString = 'Hello world!';\n\n// ACCESS CHARACTERS\n\nconsole.log(myString[6]);  // w\nconst firstWord = myString.slice(0, 5);\nconsole.log(firstWord);  // Hello\n\n// Separate the string in each space and take the second item from the list\nconst secondWord = myString.split(' ')[1]\nconsole.log(secondWord);  // world!\n\n// LENGTH\n\nconsole.log(myString.length);  // 12\nconsole.log(firstWord.length);  // 5\nconsole.log(secondWord.length);  // 6\n\n// INTERPOLATION AND CONCATENATION\n\nlet sentence = `${firstWord} ${secondWord}`;\nconsole.log(sentence);  // Hello world!\n\nsentence = firstWord + ' ' + secondWord;\nconsole.log(sentence);  // Hello world!\n\nsentence = firstWord.concat(secondWord);\nconsole.log(sentence);  // Helloworld!\n\n// REPETITION\n\nconsole.log(firstWord.repeat(2));  // HelloHello\n\n// CHECK\n\nconsole.log(myString.includes('h'));  // false\nconsole.log(myString.includes('H'));  // true\nconsole.log(myString.includes('world'));  // true\nconsole.log(myString.startsWith('Hell'));  // true\nconsole.log(myString.endsWith('!'));  // true\n\n// REPLACE\n\nconsole.log(myString.replace('!', '.'));  // Hello world.\n\n// DIVISION\n\nconsole.log(myString.split(' '));  // [ 'Hello', 'world!' ]\n\n// UPPER AND LOWER CASES\n\nconsole.log(myString.toUpperCase());  // HELLO WORLD\nconsole.log(myString.toLowerCase());  // hello world\n\n// REMOVE EMPTY SPACES FROM BEGINNING AND END\n\nconst myOtherString = '    Hello there!   '\n\nconsole.log(myOtherString.length);  // 19\nconsole.log(myOtherString.trim().length);  // 12\nconsole.log(myOtherString.trimEnd().length);    // 16\nconsole.log(myOtherString.trimStart().length);  // 15\n\n// FIND\n\nconst longString = 'the quick brown fox jumped over the lazy dog'\n\nconsole.log(longString.search('quick'));  // 4 -> index of the start of the word\nconsole.log(longString.search('QUICK'));  // -1 -> doesn't exist\n\n// FROM NUMERIC STRING TO NUMBER\n\nconst stringNumber = '1234';\nconst intNumber = +stringNumber;\nconst intNumber2 = parseInt(stringNumber);\nconsole.log(typeof stringNumber);   // string\nconsole.log(typeof intNumber);      // number\nconsole.log(typeof intNumber2);     // number\n\nconst stringNumber2 = '1234.56';\nconst floatNumber = +stringNumber2;\nconst floatNumber2 = parseFloat(stringNumber2);\nconsole.log(typeof stringNumber2);  // string\nconsole.log(typeof floatNumber);    // number\nconsole.log(typeof floatNumber2);   // number\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\n\nconst checkIsPalindrome = word => {\n    let reversedWord = [...word].reverse().join('');\n\n    return word === reversedWord;\n};\n\n\nconst checkIsAnagram = (wordOne, wordTwo) => {\n    return [...wordOne].sort().join('') === [...wordTwo].sort().join('');\n};\n\n\nconst checkIsIsogram = word => {\n    // Store how many times appears each character\n    const charsObj = {};\n    for (let char of word) {\n        charsObj[char] = charsObj[char] + 1 || 1;\n    }\n    \n    let isIsogram = true;\n    const charsValues = Object.values(charsObj);\n    const firstChQty = charsValues[0];\n    for (let charQty of charsValues) {\n        if (charQty !== firstChQty) {\n            isIsogram = false;\n            break;\n        }\n    }\n\n    return isIsogram;\n};\n\n\nfunction checkWords (wordOne, wordTwo) {\n    // Check if they are palindromes\n    console.log(`\\nIs ${wordOne} a palindrome? ${checkIsPalindrome(wordOne)}`);\n    console.log(`Is ${wordTwo} a palindrome? ${checkIsPalindrome(wordTwo)}`);\n\n    // Check if they are anagrams\n    console.log(`\\nIs ${wordOne} ${wordTwo}'s anagram? ${checkIsAnagram(wordOne, wordTwo)}`);\n\n    // Check if they are isograms\n    console.log(`\\nIs ${wordOne} an isogram? ${checkIsIsogram(wordOne)}`);\n    console.log(`Is ${wordTwo} an isogram? ${checkIsIsogram(wordTwo)}\\n`);\n}\n\n\ncheckWords('rotor', 'anna');\ncheckWords('amor', 'roma');"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/ocram1304.js",
    "content": "//Operacines con cadenas de carcteres\n//Contatenación\nconst parte1 = \"hola \";\nconst parte2 = \"una cadena\";\nconst partesUnidas = parte1+parte2;\nconsole.log(partesUnidas);\n//Template iteral es una alternativa a la contatenación normal, además de que permite incluir expresione\nconsole.log(`suma de 4+2 es igual a: ${4+2}`);\nconst cadena = \"CadenaDecaracter\";\n//conversión entre strings y numeros\nconst num = \"123456\";\n//De string a número\nNumber(num);\n//De número a string\nnum.toString();\n//Tamaño del string, la pripiedad length permite conocer el numero de caracteres que conformán el string\nconst long =  cadena.length;\n//Buscando substrings, el método includes permite verificar la existancia de un substring dentro de otro \n//más grande, si lo encuentra regresa true.\nif(cadena.includes(\"Cadena\")){\n    console.log(\"Cadena encontrada\");\n} \nelse{\n    console.log(\"Cadena no encontrada\");\n\n}\n//Encontrar la posición de un substring. IndexOf() permite encontrar el indice en donde se encuantra un substring\n//Si lo encuentra devuelve el indice, de lo contrario devuelve -1.\nconst encontrada = cadena.indexOf(\"caracter\");\n//Mayúsculas y minúsculas los métodos toUpperCase() y toLowerCase() permiten convertir a mayúsculas y minúsculas\n//respectivamente, los caracteres de una cadena.\nconst MayMin = \"cambiodeletra\";\nconsole.log(MayMin.toUpperCase());\nconsole.log(MayMin.toLowerCase);\n//Actualizar partes de un string, se puden cambiar partes especificas de un estring por medio del método replace()\n//Este y otros métodos devuelven un nuevo string, no modifican al string como tal. Para poder modificar el string\n//se tiene que declarar como variable \"let\" y no como constante \"const\"\nconst actual = \"niña\";\nconst actualizada = actual.replace(\"ni\",\"pi\");\nconsole.log(actualizada);\n//Si se tiene un string en donde varios substring se repiten y se desea actualizar cada uno de esos substrings\n//se puede hacer por medio del método replaceAll()\nlet cita =  \"ser o no ser\";\ncita = cita.replaceAll(\"ser\",\"programar\");\nconsole.log(cita);\n//Los espacios en blanco se pueden remover con el método trim()\ncita = cita.trim();\nconsole.log(cita);\n//Se pueden obtener partes especificas de un string, para ello existe el método slice(), utiliza dos parametros\n//El primero es para indicar desde donde comienza la substracción; mientras que el segundo indica la posición en\n//donde acaba (en realidad la substracción acaba un valor antes del valor especificado en el segundo parametro)\nconst extraido = \"Batman\";\nconsole.log(extraido.slice(0,3));\n//De string a arreglo y de arreglo a sting\n//Las cadenas (strings) son muy similares a los arreglos, de hecho se les pude considerar como un arreglo\n//De carcteres, por eso se puede convertir a un arreglo en un string y viceversa.\n//De string a arreglo. El método spit() permite convertir un string a un arreglo tomando un parametro como referencia\n//Para dividir en string\nconst datos = \"usuario,password,correo,telefono\";\nconst datosArray = datos.split(\",\");\nconsole.log(datosArray);\n//De  arreglo a string. Si lo que se pretende es pasar de un arreglo, entonces es método join() es el indicado\n//Funciona de la misma manera que split(), solo que el parametro se utiliza para unir el string en lugar de \n//separarlo\nconst ndatos = datosArray.join(\",\");\nconsole.log(ndatos);\n\n//Dificultad extra \n\n//Verificar si una palabra es un palindromo\nfunction IsPalindromo(palindromo){\n    //En mi caso no conicía el método reverse() que permite cambiar el orden, de manera inversa, de los elementos\n    //De un arreglo. Si la cadena se apoya de ese método en combinación de split() y join() se tiene algo como\n    //Esto palindromo.split(\"\").reverse().join(\"\"); la lógica es la misma, pero de está manera la cadena se convierte\n    //En arreglo para aprovechar sus métodos y después vuelve a ser cadena  para realizar la comparación.\n  \n\n    let aux = \"\";\n    for(let i = palindromo.length-1; i>=0; i--){\n        aux += palindromo[i];\n\n    }\n    if(aux===palindromo){\n        return \"Es palindromo\"\n    }\n    else{\n        return \"No es palindromo\"\n        \n    }\n    \n}\n//Verificar si es un isograma\nfunction isIsograma(isograma) {\n\n    function apariciones(cadena, letra) {\n        const arregloCadena = cadena.split(\"\"); \n        const cadenaFiltrada = arregloCadena.filter(car => car === letra);\n        return cadenaFiltrada.length;\n    }\n\n    for (let i = 0; i < isograma.length; i++) {\n        const aux = apariciones(isograma, isograma[i]);\n        if (aux > 1) {\n            return \"No es un isograma\";\n        }\n    }\n    return \"Es un isograma\";\n}\n//Verificar si es un anagrama\n//Para este función me vase en el trabajo de YgriegaSB.js pero me apoye en chatgpt para acomodarla \n//de una manera que considero más apropiada. \nfunction isAnagrama(palabra1, palabra2){\n    //Contar las frecuancia de las letras en una palabra\n    const contarLetras = palabra =>{\n        const contador = {}\n         for(let letra of palabra){\n            //Se accede a la propiedad letra del objeto contador\n            //está parte de la lina es muy importante (contador[letra]||0)+1\n            //Se utiliza un operador de corto circuito si contador[letra] es undefined (la letra no se ha encontrado)\n            //se evalua como 0, por lo que la cuenta de la letra está en 0. En cambio si contador[letra] tiene un valor\n            //diferente a undefined, entonces se utiliza ese valor (pues se encontro la letra anteriormente).\n            //deespues se le agrega uno para incrementar la cuenta de la letra\n            contador[letra] = (contador[letra]||0)+1\n\n\n         }\n         //Al final se devuelve un objeto en donde las claves corresponden a cada una de las letras de la palabra\n         //y el valor es el la cantidad de operaciones de dicha palabra.\n         return contador;\n    };\n    //Se verifican la frecuanccia de las palbras\n\n    const freqPalabra1 = contarLetras(palabra1);\n    const freqPalabra2 = contarLetras(palabra2);\n\n    //Se utiliza el Object.keys par tener un array de la claves del objeto con la frecuenia de las palabras\n    //El objetivo es verificar que posan el mismo numero de letras (que su longitud sea igual)\n    //Y por medio del método  every() se verfica que cada una de las claves(las letras) tenga el mismo\n    //numero en ambas palabras.\n    const sonAnagramas = (Object.keys(freqPalabra1).length === Object.keys(freqPalabra2).length) &&\n    Object.keys(freqPalabra1).every(letra => freqPalabra1[letra] === freqPalabra2[letra]);\n    return console.log(sonAnagramas ? `${palabra1} y ${palabra2} son anagramas` : 'No son anagramas');\n}\nfunction analizaPalabra(pal1, pal2){\n    pal1.toLowerCase();\n    pal2.toLowerCase();\n    isAnagrama(pal1);\n    isAnagrama(pal2);\n    isIsograma(pal1)\n    isIsograma(pa2)\n    isAnagrama(pal1,pal2);\n    \n}\nanalizaPalabra(amor,roma);\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/oleojake.js",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\n// Acceso a caracteres específicos\nlet string = 'Oleojake dev';\nconsole.log(string[6]); // k\n\n// Subcadenas\nconsole.log(string.substring(0, 8)); // Oleojake\n\n// Longitud\nconsole.log(string.length); // 12\n\n// Concatenación\nlet concatenated = string + ' 1993'; \nconsole.log(concatenated); // Oleojake dev 1993\n\n// Repetición\nlet repeated = string.repeat(2);\nconsole.log(repeated); // Oleojake devOleojake dev\n\n// Recorrido\nfor (let i = 0; i < string.length; i++) {\n    console.log(string[i]);\n}\n\n// Conversión a mayúsculas\nconsole.log(string.toUpperCase()); // OLEOJAKE DEV\n\n// Conversión a minúsculas\nconsole.log(string.toLowerCase()); // oleojake dev\n\n// Reemplazo\nlet replaced = string.replace('dev', 'DEVELOPER');\nconsole.log(replaced); // Oleojake DEVELOPER\n\n// División\nlet split = string.split(' ');\nconsole.log(split);\n\n// Unión\nlet joined = split.join(', ');\nconsole.log(joined);\n\n// Interpolación\nlet name = 'Oleojake';\nlet interpolated = `Hola, ${name}`;\nconsole.log(interpolated);\n\n// Verificación (includes)\nconsole.log(string.includes('dev')); // true\n\n// Reverse\nconsole.log(string.toLowerCase().split('').reverse().join(''));\n\n\n// EJERCICIO EXTRA\n\nfunction checkPalindromo (word){\n    \n    return word.toLowerCase() === word.toLowerCase().split('').reverse().join('');\n\n    /* RESOLUCIÓN CON RECORRIDO\n    let len = Math.floor(word.length / 2);\n    for(let i=0;i<len;i++){\n        if(word[i] != word[word.length-i-1]){\n            return false;\n        }\n    }\n    return true;\n    */\n\n}\n\nfunction checkAnagrama (word1, word2){\n    \n    return word1.toLowerCase().split('').sort().join('') === word2.toLowerCase().split('').sort().join('')\n\n}\n\nfunction checkIsograma (word){\n    \n    let myMap = new Map;\n\n    for(let i = 0; i < word.length; i++){\n        if(myMap.has(word[i])){\n            myMap.set(word[i], myMap.get(word[i]) + 1);\n        }\n        else{\n            myMap.set(word[i], 1); \n        }\n    }\n\n    let compare = myMap.get(word[0]);\n    for (let amount of myMap.values()) {\n        if(compare != amount){\n            return false;\n        }\n    }\n\n    return true;\n\n}\n\nfunction check (word1,word2){\n\n    // Palíndromo\n    console.log(\"¿La palabra \" + word1 + \" es palíndromo?: \" + checkPalindromo(word1));\n    console.log(\"¿La palabra \" + word2 + \" es palíndromo?: \" + checkPalindromo(word2));\n\n    // Anagramas\n    console.log(\"Las palabras \" + word1 + \" y \" + word2 + \" son Anagramas?: \" + checkAnagrama(word1,word2));\n\n    // Isograma\n    console.log(\"¿La palabra \" + word1 + \" es un Isograma?: \" + checkIsograma(word1));\n    console.log(\"¿La palabra \" + word2 + \" es un Isograma?: \" + checkIsograma(word2));\n\n}\n\ncheck(\"radrad\", \"radar\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/othamae.js",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\nlet string = 'Hello from JavaScript!'\nconsole.log(`This is the string: ${string}`)\n\n// Character access \nconst char = string[4]\nconst char2 = string.charAt(4)\nconsole.log(`Character on index 4 using string[4]: ${char}`)\nconsole.log(`Character on index 4 using string.charAt(4): ${char2}`)\n\n// Length\nconst stringLength = string.length\nconsole.log(`String length: ${stringLength}`)\n\n// Substring\nconst substring = string.substring(11, 21)\nconsole.log(`Substring from index 11 to 20: ${substring}`)\n\nconst slice = string.slice(11, 21)\nconsole.log(`Slice from index 11 to 20: ${slice}`)\n\n// Concatenation\nconst contat = string + ' and Node.js!'\nconsole.log(`Concatenation: ${contat}`)\n\n// Repetition\nconst repetition = string.repeat(3)\nconsole.log(`Repetition x3: ${repetition}`)\n\n// Traversal\nconsole.log('Traversal:')\nfor (const char of string) {\n  console.log(char)\n}\n\n// Conversion\nconst upper = string.toUpperCase()\nconst lower = string.toLowerCase()\nconsole.log(`Uppercase: ${upper}`)\nconsole.log(`Lowercase: ${lower}`)\n\n// Replacement\nconst replaced = string.replace('JavaScript', 'TypeScript')\nconsole.log(`Replaced: ${replaced}`)\n\nconst replaceAll = string.replaceAll('o', 'u')\nconsole.log(`Replaced all: ${replaceAll}`)\n\n// Division\nconst divided = string.split(' ')\nconsole.log(`Divided by ' ': ${divided}`)\n\n// Union\nconst joined = divided.join(' ')\nconsole.log(`Joined by ' ': ${joined}`)\n\n// Interpolation\nconst interpolation = `Interpolation: ${string}`\nconsole.log(interpolation)\n\n// Verification\nconst contains = string.includes('JavaScript')\nconsole.log(`Contains 'JavaScript': ${contains}`)\n\n\n// EXTRA TASK:\n\nfunction isPalindrome(string) {\n    return string === string.split('').reverse().join('')\n}\n\nfunction isAnagram(string1, string2) {\n    const sorted1 = string1.toLowerCase().split('').sort().join('')\n    const sorted2 = string2.toLowerCase().split('').sort().join('')\n    return sorted1 === sorted2\n}\n\nfunction isIsogram(string) {\n    const letters = string.toLowerCase().split('')\n    const dic = {}\n    for (const letter of letters) {       \n        if (dic[letter]) dic[letter]++ \n        else dic[letter] = 1\n    }\n    const frecuencies = Object.values(dic)\n    return frecuencies.every(frec => frec === frecuencies[0]);\n}\n\nconst word1 = 'reconocer'\nconst word2 = 'debit card' \nconst word3 = 'bad credit'\nconst word4 = 'redder'\n\nconsole.log(`Is the word '${word1}' Palindrome? ${isPalindrome(word1)}`)\nconsole.log(`Are the words '${word2}' and '${word3}' Anagrams? ${isAnagram(word2, word3)}`)\nconsole.log(`Is the word '${word4}' Isogram? ${isIsogram(word4)}`)\n\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/parababire.js",
    "content": "//Cadenas literales\n\nconst miNombre = \"Ángel Nárvaez\";\nconsole.log(miNombre);\n\n//Cadena objeto\n\nconst thirdRockFromTheSun = new String(\"Tierra\");\nconsole.log(thirdRockFromTheSun);\n\n//Acceso a un caracter específico\n\nconsole.log(miNombre.charAt(6));\nconsole.log(thirdRockFromTheSun[2]);\n\n//Subcadenas\n\nconsole.log(miNombre.substring(0, 6));\n\n//Longitud de cadenas\n\nconsole.log(miNombre.length);\n\n//Concatenar\n\nlet saludo = \"Hola \";\nconsole.log(saludo + miNombre);\n\n//Repetición\n\nconsole.log(saludo.repeat(3) + thirdRockFromTheSun);\n\n//Conversión a mayusculas\n\nconsole.log(miNombre.toUpperCase());\n\n//Conversión a minusculas\n\nconsole.log(thirdRockFromTheSun.toLowerCase());\n\n//Recorrido\n\nlet miNombreMinu = miNombre.toLocaleLowerCase();\nfor (let i = 0; i < miNombreMinu.length; i++) {\n  console.log(miNombreMinu[i]);\n}\n\n//Reemplazo\n\nconsole.log(miNombre.replace(\"Ángel\", \"Lcdo.\"));\n\n//Dividir cadenas\n\nlet str = \"Hola programadores de la ruta de programación 2024.\";\n\nlet palabrasStr = str.split(\" \");\nconsole.log(palabrasStr);\n\n//Unir cadenas\n\nlet unionDeStr = str.concat(\" Mi nombre es \", miNombre);\nconsole.log(unionDeStr);\n\n//Interpolación\n\nlet saludo_interpolado = `${str} Bienvenidos, esta es mi solución al reto #04. Mi nombre es ${miNombre}`;\nconsole.log(saludo_interpolado);\n\n//Verificación\n\nconsole.log(saludo_interpolado.includes(miNombre));//El método includes() es case sensible.\n\n//Dificultad extra\n\nfunction check(word1, word2) {\n\n  //Palindromo\n  console.log(`Es ${word1} un palindromo?: ${word1 === word1.split(\"\").reverse().join(\"\")}`);\n  console.log(`Es ${word2} un palindromo?: ${word2 === word2.split(\"\").reverse().join(\"\")}`);\n  \n  //Anagrama\n  console.log(`Es ${word2} un anagrama de ${word1}?: ${word1.split(\"\").sort().join(\"\") === word2.split(\"\").sort().join(\"\")}`);\n\n  //isograma\n  function isograma(word) {\n    let textoSinNumerosNiSignos = word.replace(/\\d+\\D/, \"\").toLowerCase();\n    let textoSinAcento = textoSinNumerosNiSignos.normalize(\"NFD\").replace(/[\\u0300-\\u036f]/g, \"\");\n    let objLetras = {};\n    for (const letras in textoSinAcento) {\n      objLetras[textoSinAcento[letras]] = (objLetras[textoSinAcento[letras]] || 0) + 1;\n    }\n    let isograma = true;\n    let values = Object.values(objLetras);\n    let isogramaLen = values[0];\n    for (let wordCount of values) {\n      if (wordCount !== isogramaLen) {\n        isograma = false;\n      }\n    }\n    return isograma;\n  }\n  console.log(`Es ${word1} un isograma?: ${isograma(word1)}`);\n  console.log(`Es ${word2} un isograma?: ${isograma(word2)}`);\n}\n\ncheck(\"caso\", \"saco\");"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/pedamoci.js",
    "content": "let lorem = new String('Lorem ipsum, dolor sit amet consectetur adipisicing elit. Earum, eum! Ipsam odit repellendus dolorem dolor ut sequi beatae, odio earum dignissimos aut consequuntur quibusdam, ad voluptas unde atque, sapiente inventore!')\nlet hello = 'Hello'\nlet world = 'world'\n\n// ----------------------- OPERACIONES DE CADENAS -----------------------\n  // at() --> busca un caracter o elemento por posición empenzando desde el 0, con números negativos va de atras hacia delante empezando por -1\n    console.log(lorem.at(25)) // --> devuelve la 'e' de amet\n    console.log(lorem.at(-32)) // --> devuelve ' ' el espacio entre voluptas y unde\n\n  // charAt() --> busca un caracter por posición empenzando desde el 0, no acepta números negativos y no devuelve espacios, saltos de linea, etc.\n    console.log(lorem.charAt(45)) // --> devuelve la 's' de adipisicing\n    console.log(lorem.charAt(64)) // --> devuelve la '' ya que es el espacio entre Earum y eum\n\n  // charCodeAt() --> devuelve el codigo (valor del 0 al 65523 del codigo UTF-16) de un caracter o elemento buscado por posición empenzando desde el 0, no acepta números negativos y si el caracter es un emoji, símbolo matemático o caracter de un idoma raro el valor devuelto es incorrecto\n    console.log(lorem.charCodeAt(45)) // --> devuelve 115 del codigo en UTF-16 de la 's' de adipisicing\n    console.log(lorem.charCodeAt(64)) // --> devuelve 32 del codigo en UTF-16 ya que es el espacio entre Earum y eum\n\n  // charCodeAt() --> devuelve el codigo (valor del 0 al 65523 que puede contener letras del codigo UTF-16) de cualquier caracter buscado por posición empenzando desde el 0, no acepta números negativos\n    console.log(lorem.codePointAt(45)) // --> devuelve 115 del codigo en UTF-16 de la 's' de adipisicing\n    console.log(lorem.codePointAt(64)) // --> devuelve 32 del codigo en UTF-16 ya que es el espacio entre Earum y eum\n\n  // concant() --> concatena \n    console.log(hello.concat(' ', world, ', mensaje número ', 1)); // --> devuelve 'Hello world, mensaje número 1'\n\n  // endsWith() --> devuelve true | false comparando el string ingresado con el final de la cadena\n    console.log(lorem.endsWith('!')); // --> true\n    console.log(lorem.endsWith('inventore!')); // --> true\n    console.log(lorem.endsWith('Lore', 4)); // --> true ya que compara el string con como termina la cadena hasta (sin incluir el caracter) la posición indicada \n    console.log(lorem.endsWith('Lorem', 4)); // --> false \n\n  // includes() --> devuelve true | false revisando si el string ingresado esta en la cadena, es case sensitive (distingue entre mayúsculas y minúsculas)\n    console.log(lorem.includes('!')); // --> true\n    console.log(lorem.includes('inventore!')); // --> true\n    console.log(lorem.endsWith('lorem')); // --> true ya que dentro de la palabra dolorem se encuaantra 'lorem'\n    console.log(lorem.endsWith('Amet')); // --> false \n\n  // indexOf() --> busca una coincidencia en la cadena con el string ingresado y devuelve la posicion del primer caracter de la primera coincidencia\n    console.log(lorem.indexOf('dolor')); // --> devuelve 13 (ignora la posición 93 y 101 que también lo cumplen)\n    console.log(lorem.indexOf(' ')); // --> devuelve 5\n\n  // isWellFormed() --> devuelve true | false si el string tiene un codigo UTF-16 completo\n    const correctUTF16 = \"\\uD83D\\uDE00\"; // el '😄' al ser una simbolo complejo esta formado por dos partes \n    const incorrectUTF16 = \"\\uD83D\"; // Una parte del codigo UTF-16 de '😄'\n    console.log(correctUTF16.isWellFormed()); // --> devuelve true\n    console.log(incorrectUTF16.isWellFormed()); // --> devuelve false\n\n  // lastIndexOf() --> busca una coincidencia en la cadena con el string ingresado y devuelve la posicion del primer caracter de la última coincidencia\n    console.log(lorem.indexOf('dolor')); // --> devuelve 101 (ignora la posición 13 y 93 que también lo cumplen)\n    console.log(lorem.indexOf(' ')); // --> devuelve 207\n\n  // localCompare() --> compara la cadena de la derecha con la de la izquerda, si la de la deracha va antes en orden alfabetico devuelve -1, si va despues 1 y 0 si son iguales según llas reglas de comparación \n    console.log(\"manzana\".localeCompare(\"banana\")); // --> 1 \n    console.log(\"banana\".localeCompare(\"manzana\")); // --> -1\n    console.log(\"pera\".localeCompare(\"pera\")); // --> 0 \n    console.log(\"réservé\".localeCompare(\"RESERVE\", 'es', { sensitivity: \"base\"})) // --> 0 ya que ignora el acento y las mayúsculas\n    console.log(\"ä\".localeCompare(\"z\", \"es\")); // --> -1 ya que 'ä' en el español se la considera como una variante de 'a'\n    console.log(\"ä\".localeCompare(\"z\", \"sv\")); // --> 1 ya que 'ä' es parte del alfabeto sueco y va despues de la 'z'\n\n  // match() --> busca a través de una expreción regular (https://regex101.com) los caracteres o las cadenas que coincidan\n    console.log(lorem.match(/[A-Z]/g)); // --> L, E, I ya que devuelve las letras mayúsculas desde la 'A' a la 'Z'\n    console.log(lorem.match(/\\b\\w*um\\w*\\b/g)); // --> ipsum, Earum, eum, earum ya que devuelve las palabras que contengan 'um'\n\n  // matchAll() --> busca a través de una expreción regular (https://regex101.com) los caracteres o las cadenas que coincidan y la devuelve incluyendo los grupos capturables\n    const array = [...lorem.matchAll(/s(a)\\w*(ie)\\w*(e)/g)]\n    console.log(array[0]) // --> sapiente, a, ie, e primero devuelve sapiente ya que busca una palabra 's'-'a'-cualquier caracter-'ie'-cualquier caracter-'e' y despues devuelve cada grupo 'a', 'ie', 'e' \n\n  // normalize() --> transforma el código dado a uno normalizado\n    const name1 = \"\\u0041\\u006d\\u00e9\\u006c\\u0069\\u0065\" // --> Amélie, el codigo de 'é' esta dado por \\u00e9\n    const name2 = \"\\u0041\\u006d\\u0065\\u0301\\u006c\\u0069\\u0065\" // --> Amélie, el codigo de 'é' esta dado por \\u0065\\u0301 el primero correspode a 'e' y el segundo al acento\n    console.log(name1 === name2) // --> False\n    console.log(name1.normalize('NFC') === name2.normalize('NFC')); // --> True\n\n  // padEnd() --> agrega el caracter/string que quieras al final de un string hasta llegar a la longitud ingresada, empieza desde 1 (siempre devuelve como mínimo el string original)\n    console.log(hello.padEnd(6, ',').padEnd(7, ' ') + world) // --> Hello, world\n\n  // padStart() --> agrega el caracter/string que quieras al inicio de un string hasta llegar a la longitud ingresada, empieza desde 1 (siempre devuelve como mínimo el string original)\n    console.log('9725'.padStart(10, '*')) // --> ******9725\n\n  // repeat() --> repite el string la cantidad de veces ingresadas\n    console.log(`I feel ${'Happy! '.repeat(3)}`) // --> I feel Happy! Happy! Happy!\n\n  // replace() --> remplaza la primer coincidencia de lo indicado a través de una expreción regular o por un string por el string ingresado\n    console.log(lorem.replace('dolor', 'DOLOR')) // --> remplaza el primer string 'dolor' (indice 13) por 'DOLOR', ignorando los de indice 93 y 101\n\n  // replaceAll() --> remplaza todas las coincidencia de lo indicado a través de una expreción regular o por un string por el string ingresado\n    console.log(lorem.replaceAll('dolor', 'DOLOR')) // --> remplaza todos los string 'dolor' (indice 13, 93, 101) por 'DOLOR'\n\n  // search() --> busca la primer coincidencia de lo indicado a través de una expreción regular o por un string\n    console.log(lorem.search('Ipsam')) // --> 70 ya que es el indice donde empieza el strin 'Ipsam'\n\n  // slice() --> devuelve la parte indicada de un string, acepta números negativos\n    console.log(lorem.slice(-99,-63)) // --> tae, odio earum dignissimos aut cons\n    console.log(lorem.slice(151)) // --> consequuntur quibusdam, ad voluptas unde atque, sapiente inventore!\n\n  // split() --> divede la cadena de texto por el string o la expreción regular ingresada\n    console.log(lorem.split(' ')) // --> divide el texto en palabras\n    console.log(lorem.split('')) // --> divide el texto en caracteres\n\n  // startWith() --> verifica si en una posición hay un string que empiece como el string ingresado (NO acepta expresiones regelures)\n    console.log(lorem.startsWith('Lor')) // --> True el texto comienza com Lorem...\n    console.log(lorem.startsWith('lor', 15)) // --> True en el indice 15 inicia un string 'lor' (palabra original 'dolor' indice 13)\n\n  // substring() --> devuelve la parte indicada -1 de un string, los números negativos los interpreta como 0 y no importa el orden en el que ingreses los datos\n    console.log(lorem.substring(99,55)) // --> t. Earum, eum! Ipsam odit repellendus dolore ya que invierte los valores al ser el de la izquierda mas grande y el caracter de indice 99 no lo devuelve\n\n  // toLocalLowerCase() --> devuelve el string ingresado en la minúscula del idioma ingresado\n    console.log(\"İstanbul\".toLocaleLowerCase(\"en-US\") === \"İstanbul\".toLocaleLowerCase(\"tr\")) // --> False ya que la 'İ' en minúscula en \"en-US\" es ditinta a la de \"tr\"\n\n  // toLocalUpperCase() --> devuelve el string ingresado en la minúscula del idioma ingresado\n    console.log(\"istanbul\".toLocaleUpperCase(\"en-US\") === \"istanbul\".toLocaleUpperCase(\"tr\")) // --> False ya que la 'i' en minúscula en \"en-US\" es ditinta a la de \"tr\"\n\n  // toLowerCase() --> devuelve el string en minúscula\n    console.log(\"İstanbul\".toLowerCase(\"en-US\") === \"İstanbul\".toLowerCase(\"tr\")) // --> True ya que vuelve el string insensible a la configuración regional\n\n  // toString() --> devuelve un string de lo ingresado\n    const num = 123\n    console.log(num.toString());\n\n  // toUpperCase() --> devuelve el string en mayúcula\n    console.log(\"istanbul\".toUpperCase(\"en-US\") === \"istanbul\".toUpperCase(\"tr\")) // --> True ya que vuelve el string insensible a la configuración regional\n\n  // toWellFormed() --> transforma el codigo UTF-16 a un caracter legible\n    console.log('ab\\uD83D\\uDE04c'.toWellFormed()) // --> ab😄c transformo '\\uD83D\\uDE04' en 😄\n\n  // trim() --> quita los espacios en blanco del comienzo y final de un string (NO quita los saltos de linea)\n    console.log(`                  ${hello}, ${world}!                      `.trim()) // --> 'Hello, world!'\n\n  // trimEnd() --> quita los espacios en blanco del final de un string (NO quita los saltos de linea)\n  console.log(`                  ${hello}, ${world}!                      `.trimEnd()) // --> '                  Hello, world!'\n\n  // trimStart() --> quita los espacios en blanco del comienzo de un string (NO quita los saltos de linea)\n  console.log(`                  ${hello}, ${world}!                      `.trimStart()) // --> 'Hello, world!                      '\n\n  // valueOf() --> devuelve el valor de un objeto string\n    const stringObj = new String(\"foo\")\n    console.log(stringObj) // --> [String: 'foo']\n    console.log(stringObj.valueOf()) // --> 'foo'\n    console.log('Hello, world!'.valueOf()) // --> 'Hello, world!'\n\n  // [Symbol.iterator]() --> devuelde cada simbolo de un string (se usa si tenes codigo UTF-16 para separar por caracter)\n    const str = \"A\\uD835\\uDC68B\\uD835\\uDC69C\\uD835\\uDC6A\";\n    const strIter = str[Symbol.iterator]();\n    console.log(strIter.next().value)\n    console.log(strIter.next().value)\n    console.log(strIter.next().value)\n    console.log(strIter.next().value)\n    console.log(strIter.next().value)\n    console.log(strIter.next().value)\n\n  // length --> devuelve la cantidad de caracteres que tiene un string\n  console.log(lorem.length) // --> 218\n\n// -------------------------- DIFICULTAD EXTRA --------------------------\nfunction palindromos(word) {\n  let i = 0\n  let j = word.length - 1\n  while (i <= word.length/2) {\n    // recorre la palabra hasta la mitad ya que más seria redundate debido\n    // a que va comparando los caracteres del inicio con los del final \n    if (word[i].toLowerCase !== word[j].toLowerCase) {\n      return false\n    } else if (i === j) {\n      return true\n    }\n    i++\n    j--\n  }\n}\n\nfunction anagramas(word1, word2) {\n  let i = 0\n  while (word2.includes(word1[i]) && word1.length === word2.length) {\n    // recorre la primer palabra verificando que la segunda contenga el caracter y remplaza a este por un guion \n    // para matener la igual de length y evitar que verifique con el mismo caracter dos veces\n    if (i === word1.length - 1) return true\n    word2 = word2.replace(word1[i], '-')\n    i++\n  } return false\n}\n\nfunction isogramas(word) {\n  let i = 0\n  do {\n    // recorre la palabra guardando letra por letra y cuando quita una,\n    //  la remplaza por un guion y verifica que no esta repetida\n    if (i === word.length - 1) return true\n    letter = word[i]\n    word = word.replace(word[i], '-')\n    i++\n  } while (!word.includes(letter));\n  return false\n}\n\nfunction startProgram() {\n  // ingresa la/s palabra/s a la función pertinente, esta devuelve true | false y tiene una frase especifica para cada valor\n  let operation = prompt('Que deseas verificar si es/son palindromos, anagramas o isogramas?')\n  let word = 'y'\n  if (operation.toLowerCase() === 'palindromos' || operation.toLowerCase() === 'palindromo') {\n    while (word.toLowerCase() !== 'n') {\n      if (word.toLowerCase() === 'y'|| word.toLowerCase() === 's') {\n        word = prompt('Ingrese la palabra')\n        word = prompt(`La palabra ${word} ${palindromos(word) ? 'es un palíndromo' : 'no es un palíndromo'}` + \"\\n\".repeat(2) + \n                    `Desea comprobar si otra palabra es un palíndromo? Y/N`)\n      } else {\n        word = prompt('Desea comprobar si otra palabra es un palíndromo? Y/N')\n      }\n    }\n  } else if (operation.toLowerCase() === 'anagramas' || operation.toLowerCase() === 'anagrama') {\n    while (word.toLowerCase() !== 'n') {\n      if (word.toLowerCase() === 'y'|| word.toLowerCase() === 's') {\n        word = prompt('Ingrese la primer palabra')\n        let word2 = prompt('Ingrese la segunda palabra')\n        word = prompt(`Las palabras ${word} y ${word2} ${anagramas(word, word2) ? 'son anagramas' : 'no son anagramas'}` + \"\\n\".repeat(2) + \n                      `Desea comprobar si otras palabras son anagramas? Y/N`)\n      } else {\n        word = prompt('Desea comprobar si otras palabras son anagramas? Y/N')\n      }\n    }\n  } else if (operation.toLowerCase() === 'isogramas' || operation.toLowerCase() === 'isograma') {\n    while (word.toLowerCase() !== 'n') {\n      if (word.toLowerCase() === 'y'|| word.toLowerCase() === 's') {\n        word = prompt('Ingrese la palabra')\n        word = prompt(`La palabra ${word} ${isogramas(word) ? 'es un isograma' : 'no es un isograma'}` + \"\\n\".repeat(2) + \n                      `Desea comprobar si otra palabra es un isograma? Y/N`)\n      } else {\n        word = prompt('Desea comprobar si otra palabra es un isograma? Y/N')\n      }\n    }\n  }\n  do {\n    // bucle para saber si el usuario quiere hacer otra operacion (si no ingresa 's', 'y' o 'n') se repite hasta que ingrese un valor aceptado\n    operation = prompt('Deseas hacer otra operación? Y/N')\n    if (operation.toLowerCase() === 'y'|| operation.toLowerCase() === 's') startProgram()\n  } while (operation.toLowerCase() !== 'n')\n}\nstartProgram()"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/popmaquin.js",
    "content": "//-------------------------\n//  Cadena de caracteres\n//-------------------------\n\nlet string1 = \"Ciudad \";\nlet string2 = \"Guatemala\";\nlet string3 = \"Bienvenido a Guatemala\"\n\nconsole.log(typeof(string1)); //string\n\n\n// ---Longitud string2\nconsole.log(string2.length); // 9\n\n\n// ---Concatenación\nconsole.log(string1 + string2); // Por el operador '+'\nconsole.log(string1.concat(string2));//-metodo 'concat()'\nconsole.log(`${string1}${string2}`); // -Con plantillas literales\n\n\n// ---Acceso\nconsole.log(string1[0]); // C  -por su indice\nconsole.log(string1.charAt(1)); // i -Con el metodo charAt\n\n// ---Interpolación\nconsole.log(`Bienvendio a la  ${string1} de ${string2}`); // 'Bienvenido a la Ciudad de Guatemala'\n\n// ---Repetición\nconsole.log(string1.repeat(5));\n\n// ---Devuelve código UTF-16\n\nconsole.log(string1.charCodeAt(0)); // 67 = C\nconsole.log(string1.codePointAt(1)); // 105 = i\n\n// ---Elimnacion de espacio a los extremos\nconsole.log(string1.trim().length); // 6\n\n\n// ---Busqueda de palabra\nconsole.log(string3.includes(\"Bienvenido\")); // True\n\n// ---Busqueda por posicion\nconsole.log(\"Guatemala\".indexOf(\"a\")); // 2\n// ---Busqueda de la ultima posicion posicion\nconsole.log(\"Bienvenido\".lastIndexOf(\"i\")); // 2\n\n\n// ---Determinar la ulitma palabra o caracter\nconsole.log(\"Bienvenido a Guatemala\".endsWith(\"ala\")); // true\nconsole.log(\"Bienvenido a Guatemala\".endsWith(\"Guatemala\")); //true\n\n\n// ---Comparación\nconsole.log(\"Guatemala\".localeCompare(string2)); // 0 = true\nconsole.log(\"2\".localeCompare(\"10\"));\n\n\n// ---Remplazar\nconsole.log(string3.replace(\"Guatemala\", \"Coban\")); //Bienvenido a Coban\n //El Coban se representa en la modena de un Coban\nconsole.log(\"El quetzal se representa en la modena de un quetzal\".replaceAll(\"quetzal\", \"Coban\"));\n\n\n// ---Extraer parte\nconsole.log(string2.slice(0,5)); // Guate\nconsole.log(string2.substring(0,5)); // Guate\nconsole.log(string2.substring(5,0)); // Guate\n\n\n// ---Dividir => Array\nlet arr = string2.split(\"\", 9); //['G', 'u', 'a', 't', 'e', 'm', 'a', 'l', 'a']\nconsole.log(arr);\nconsole.log(arr[0]); //G\n\n// ---Conversion a minuscula y mayuscula\nconsole.log(string1.toLowerCase()); // ciudad\nconsole.log(string1.toLocaleLowerCase()); // ciudad\n\nconsole.log(string1.toUpperCase()); // CIUDAD\nconsole.log(string1.toLocaleUpperCase()); // CIUDAD\n\n//-------------------------\n//  Dificultad extra\n//-------------------------\n\n//funcion para invertir la cadena de caracteres\nfunction invertir(cadena){\n    let reverso=\"\";\n    for(let i=cadena.length-1; i>=0; i--){\n        reverso= reverso.concat(cadena[i]);\n    }\n    return reverso;\n}\n//funcion palindromo\nfunction juegoDePalabras(cad1, cad2){\n   \n    //Palindromo\n    if(invertir(cad1).toLowerCase()==cad1.toLowerCase()){\n        console.log(`La palabra \"${cad1}\" es palindromo`);\n    }else{\n       console.log(cad1 + \" no es palindromo\");\n    }\n    if(invertir(cad2).toLowerCase()==cad2.toLowerCase()){\n        console.log(`La palabra \"${cad2}\" es palindromo`);\n    }else{\n       console.log(cad2 + \" no es palindromo\");\n    }\n   \n    //Anagrama\n    if(cad1.split(\"\").sort().join()==cad2.split(\"\").sort().join()){\n      console.log(`La palabra \"${cad2}\" es anagrama de \"${cad1}\" `);\n    }else{\n      console.log(`\"${cad2}\" no es anagrama de \"${cad1}\"`);\n    }\n    //Isograma\n    if(cad1.length==new Set(cad1).size){\n        console.log(`la palabra \"${cad1}\" es isograma`);\n    }else{\n         console.log(`la palabra \"${cad1}\" no es isograma`);\n    }\n    if(cad2.length==new Set(cad2).size){\n        console.log(`la palabra \"${cad2}\" es isograma`);\n    }else{\n         console.log(`la palabra \"${cad2}\" no es isograma`);\n    }\n \n}\n   \n//juegoDePalabras(\"murcielago\",\"lago\");\njuegoDePalabras(\"ramo\",\"mora\");"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/qwik-zgheib.js",
    "content": "/* -- exercise */\nlet str = \"Hello\";\nconsole.log(str[0]);\n\nstr = \"Hello World\";\nconsole.log(str.substring(0, 5));\nconsole.log(str.slice(-5));\n\nstr = \"JavaScript\";\nconsole.log(str.length);\n\nlet str1 = \"Hello\";\nlet str2 = \"World\";\nconsole.log(str1 + \" \" + str2);\nstr = \"abc\";\nconsole.log(str.repeat(3));\n\nstr = \"JavaScript\";\nfor (let char of str) {\n  console.log(char);\n}\n\nstr = \"Hello\";\nconsole.log(str.toUpperCase());\nconsole.log(str.toLowerCase());\n\nstr = \"Hello World\";\nconsole.log(str.replace(\"World\", \"JavaScript\"));\n\nstr = \"Apple, Banana, Cherry\";\nconsole.log(str.split(\", \"));\nlet arr = [\"Apple\", \"Banana\", \"Cherry\"];\nconsole.log(arr.join(\", \"));\n\nlet name = \"Alice\";\nconsole.log(`Hello, ${name}!`);\n\nstr = \"JavaScript is awesome\";\nconsole.log(str.includes(\"Java\"));\nconsole.log(str.startsWith(\"Java\"));\nconsole.log(str.endsWith(\"awesome\"));\n\n/* -- extra challenge */\nconst isPalindrome = (word) => {\n  let reversed = word.split(\"\").reverse().join(\"\");\n  return word.toLowerCase() === reversed.toLowerCase();\n};\n\nconst isAnagram = (word1, word2) => {\n  let sorted1 = word1.toLowerCase().split(\"\").sort().join(\"\");\n  let sorted2 = word2.toLowerCase().split(\"\").sort().join(\"\");\n  return sorted1 === sorted2;\n};\n\nconst isIsogram = (word) => {\n  let charMap = {};\n  for (let char of word.toLowerCase()) {\n    if (charMap[char]) return false;\n\n    charMap[char] = true;\n  }\n  return true;\n};\n\nlet word1 = \"Madam\";\nlet word2 = \"Adam\";\n\nconsole.log(`\"${word1}\" is a palindrome:`, isPalindrome(word1));\nconsole.log(`\"${word2}\" is an anagram of \"${word1}\":`, isAnagram(word1, word2));\nconsole.log(`\"${word1}\" is an isogram:`, isIsogram(word1));\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/ralphmcralph.js",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n */\n\n\n// Acceso a caracteres específicos\nlet cadena = \"Hola mundo\";\n\nconsole.log(cadena[0]); // H\n\n// Subcadenas\n\nconsole.log(cadena.substring(0, 4)); // Hola\n\n// Longitud\n\nconsole.log(cadena.length); // 10\n\n// Concatenación\n\nlet cadena2 = \" desde JavaScript\";\n\nconsole.log(cadena + cadena2); // Hola mundo desde JavaScript\n\n// Repetición\n\nconsole.log(cadena.repeat(3)); // Hola mundoHola mundoHola mundo\n\n// Recorrido\n\nfor (let i = 0; i < cadena.length; i++) {\n    console.log(cadena[i]);\n}\n\n// Conversión a mayúsculas y minúsculas\n\nconsole.log(cadena.toUpperCase()); // HOLA MUNDO\n\nconsole.log(cadena.toLowerCase()); // hola mundo\n\n// Reemplazo\n\nconsole.log(cadena.replace(\"mundo\", \"amigos\")); // Hola amigos\n\n// División\n\nconsole.log(cadena.split(\" \")); // [\"Hola\", \"mundo\"]\n\n// Unión\n\nconsole.log([\"Hola\", \"mundo\"].join(\" \")); // Hola mundo\n\n// Interpolación\n\nlet nombre = \"Ralph\";\n\nconsole.log(`Hola ${nombre}`); // Hola Ralph\n\n// Verificación\n\nconsole.log(cadena.includes(\"mundo\")); // true\n\nconsole.log(cadena.startsWith(\"Hola\")); // true\n\nconsole.log(cadena.endsWith(\"mundo\")); // true\n\nconsole.log(cadena.indexOf(\"mundo\")); // 5\n\nconsole.log(cadena.lastIndexOf(\"o\")); // 7\n\nconsole.log(cadena.search(\"mundo\")); // 5\n\nconsole.log(cadena.match(/o/g)); // [\"o\", \"o\", \"o\"]\n\nconsole.log(cadena.match(/o/g).length); // 3\n\n/* DIFICULTAD EXTRA(opcional):\n* Crea un programa que analice dos palabras diferentes y realice comprobaciones\n* para descubrir si son:\n*   - Palíndromos\n*   - Anagramas\n*   - Isogramas\n*/\n\nlet palabra1 = \"Yuxtaponer\"\nlet palabra2 = \"Radar\"\n\nfunction isPalindrome(word) {\n\n    word = word.toLowerCase();\n\n    return word === word.split(\"\").reverse().join(\"\");\n\n}\n\nfunction printResult(word) {\n    console.log(isPalindrome(word) ? `La palabra ${word.toLowerCase()} es un palíndromo` : `La palabra ${word.toLowerCase()} no es un palíndromo`);\n}\n\n\nprintResult(palabra1);\nprintResult(palabra2);\n\n// Anagrama\n\nfunction isAnagram(word1, word2) {\n\n    return word1.toLowerCase().split(\"\").sort().join(\"\") === word2.toLowerCase().split(\"\").sort().join(\"\");\n\n}\n\nconsole.log(isAnagram(palabra1, palabra2) ? `${palabra1} es un anagrama de ${palabra2.toLowerCase()}` : `${palabra1} no es un anagrama de ${palabra2.toLowerCase()}`);\n\n// Isograma\n\nfunction isIsogram(word) {\n\n    letterCounter = new Map();\n\n    word.toLowerCase().split(\"\").forEach(letter => {\n        if (letterCounter.get(letter)) {\n\n            letterCounter.set(letter, letterCounter.get(letter) + 1)\n\n        } else {\n            letterCounter.set(letter, 1);\n        }\n    }\n    );\n\n    const uniqueValues = new Set(letterCounter.values());\n\n    return uniqueValues.size === 1;\n\n}\n\nconsole.log(isIsogram(palabra1) ? `La palabra ${palabra1.toLowerCase()} es un isograma` : `La palabra ${palabra1.toLowerCase()} no es un isograma`);\n\nconsole.log(isIsogram(palabra2) ? `La palabra ${palabra2.toLowerCase()} es un isograma` : `La palabra ${palabra2.toLowerCase()} no es un isograma`);\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/rlores-edison.js",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos (se leen igual de izquierda a derecha y de derecha a izquierda)\n * - Anagramas (Las letras de una palabra, si se escriben en orden diferente, forman otra)\n * - Isogramas (Las letras se repiten el mismo número de veces)\n */\n\n// String length\nlet text = \"ABCDEFGHIJKLLLMNOPQRSTUVWXYZ\";\nlet length = text.length;\nconsole.log(\"Length of the text: \" + length);\n\n\n// Accessing characters\nconsole.log(\"Accessing characters\");\nconsole.log(\"First character: \" + text[0]);\nconsole.log(\"Last character: \" + text[length - 1]);\nconsole.log(\"Character at index 2: \" + text[2]);\nconsole.log(\"Character at index 10: \" + text[10]);\nconsole.log(\"Character at index -1: \" + text[length + 1]);\n\n// Accessing substrings\nconsole.log(\"Accessing substrings\");\nlet substring = text.substring(2, 5);\nconsole.log(\"Substring from index 2 to index 5: \" + substring);\nsubstring = text.substring(2);\nconsole.log(\"Substring from index 2 to the end: \" + substring);\nsubstring = text.substring(0, length);\nconsole.log(\"Substring from the beginning to the end: \" + substring);\n\n// Concatenation\nconsole.log(\"Concatenation\");\nlet concatenatedText = text + \"123456789\";\nconsole.log(\"Concatenated text: \" + concatenatedText);\n\n// Repetition\nconsole.log(\"Repetition\");\nlet repeatedText = text + text;\nconsole.log(\"Repeated text: \" + repeatedText);\n\n// Iterating over characters\nconsole.log(\"Iterating over characters\");\nfor (let i = 0; i < length; i++) {\n  console.log(\"Character at index \" + i + \": \" + text[i]);\n}\n\n// Iterating over substrings\nconsole.log(\"Iterating over substrings\");\nfor (let i = 0; i < length; i++) {\n  let substring = text.substring(i, i + 3);\n  console.log(\"Substring from index \" + i + \" to index \" + (i + 3) + \": \" + substring);\n}\n\n// Converting to uppercase\nconsole.log(\"Converting to uppercase\");\nlet uppercaseText = text.toUpperCase();\nconsole.log(\"Uppercase text: \" + uppercaseText);\n\n// Converting to lowercase\nconsole.log(\"Converting to lowercase\");\nlet lowercaseText = text.toLowerCase();\nconsole.log(\"Lowercase text: \" + lowercaseText);\n\n// Replacing characters\nconsole.log(\"Replacing characters\");\nlet replacedText = text.replace(\"A\", \"X\");\nconsole.log(\"Replaced text: \" + replacedText);\n\n// Splitting a string\nconsole.log(\"Splitting a string\");\nlet splitText = text.split(\"\");\nconsole.log(\"Split text: \" + splitText);\n\n//String Interpolation method: Interpolate variables and expressions into strings\nconsole.log(\"Interpolate between M and N the string: INTERPOLATED_TEXT\");\nlet interpolateText = `${text.slice(0, text.indexOf('N'))} INTERPOLATED_TEXT ${text.slice(text.indexOf('N'))}`;\nconsole.log(\"Interpolate text: \" + interpolateText);\n\n// Checking if a string is empty\nconsole.log(\"Checking if a string is empty\");\nif (text.length === 0) {\n  console.log(\"The text is empty\");\n} else {\n  console.log(\"The text is not empty\");\n}\n\n// Checking if a string contains a substring\nconsole.log(\"Checking if a string contains a substring\");\nif (text.includes(\"A\")) {\n  console.log(\"The text contains the substring 'A'\");\n} else {\n  console.log(\"The text does not contain the substring 'A'\");\n}\n\n// Checking if a string starts with a substring\nconsole.log(\"Checking if a string starts with a substring\");\nif (text.startsWith(\"A\")) {\n  console.log(\"The text starts with the substring 'A'\");\n} else {\n  console.log(\"The text does not start with the substring 'A'\");\n}\n\n// Checking if a string ends with a substring\nconsole.log(\"Checking if a string ends with a substring\");\nif (text.endsWith(\"A\")) {\n  console.log(\"The text ends with the substring 'A'\");\n} else {\n  console.log(\"The text does not end with the substring 'A'\");\n}\n\n//  Checking if a string contains a sequence of characters\nconsole.log(\"Checking if a string includes a sequence of characters\");\nif (text.includes(\"ABCDE\")) {\n  console.log(\"true\");\n} else {\n  console.log(\"false\");\n}\n\nconsole.log(\"Dificultad EXTRA\");\n/*DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos (se leen igual de izquierda a derecha y de derecha a izquierda)\n * - Anagramas (Las letras de una palabra, si se escriben en orden diferente, forman otra)\n * - Isogramas (Las letras se repiten el mismo número de veces)\n */\n\n \nconsole.log(\"Reverse a string & check if it is a palindrome, anagram or isogram\")\nlet word1 = \"oso\";\nlet word2 = \"nana\";\n\nlet reversedWord = word1.split(\"\").reverse().join(\"\");\nconsole.log(`\"${word1}\" is a palindrome:`, word1 === reversedWord); // you can read the word in reverse\nconsole.log(`\"${word2}\" is an anagram of \"${word1}\":`, word2 === reversedWord);// the letters of a word can form another word\nconsole.log(`\"${word1}\" is an isogram:`, word1.length === new Set(word1).size); // it has no repeated characters\n\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/robmxz.js",
    "content": "/* RETO #04 */\n/*\nvar string = \" Just a normal string \";\n\n// string.at -> Retorna el caracter al cual le estas pasando el índice - Soporta índices negativos\n\nconsole.log(`${string} el indice -5 retorna ${string.at(-5)}`); // r\n\n// string.charAt -> Retorna el caracter al cual le estas pasando el índice - no soporta índices negativos\n\nconsole.log(`${string} el indice 4 retorna ${string.at(4)}`); // t\n\n// string.charCodeAt -> Retorna el valor unicode del caracter al cual le estas pasando el índice - no soporta índices negativos\n\nconsole.log(`${string} el indice 4 retorna ${string.charCodeAt(4)}`); // 116\n\n// string.concat -> Concatena dos o más strings\n\nvar string2 = \"and another string\";\n\nconsole.log(string.concat(string2)); // Just a normal string and another string\n\n// string.endsWith -> Retorna un valor booleano verificando si la cadena termina o no con el valor que le pasas\n\nconsole.log(string.endsWith(\"string\")); // false\n\n// string.includes -> Retorna un valor booleano verificando si la cadena incluye o no el valor que le pasas\n\nconsole.log(string.includes(\"string\")); // true\n\n// string.indexOf -> Retorna el índice de la primera ocurrencia del valor que le pasas\n\nconsole.log(string.indexOf(\"string\")); // 15\n\n// string.lastIndexOf -> Retorna el índice de la última ocurrencia del valor que le pasas\n\nconsole.log(string.lastIndexOf(\"t\")); // 16\n\n// string.length -> Retorna la longitud de la cadena\n\nconsole.log(string.length); // 22\n\n// string.match -> Busca una cadena por una expresión regular y retorna un array con los resultados\n\nvar regex = /[A-Z]/g;\n\nconsole.log(string.match(regex)); // ['J']\n\n// string.padEnd -> Completa la cadena con el valor que le pasas hasta la longitud que le indiques\n\nconsole.log(string.padEnd(30, \".\")); // Just a normal string ........\n\n// string.padStart -> Completa la cadena con el valor que le pasas hasta la longitud que le indiques\n\nconsole.log(string.padStart(30, \"*\")); // ******** Just a normal string\n\n// string.repeat -> Repite la cadena el número de veces que le indiques\n\nconsole.log(\"IDK \".repeat(5)); // IDK IDK IDK IDK IDK\n\n// string.replace -> Reemplaza un valor por otro\n\nvar replaceable = \"The day over the days\";\n\nconsole.log(replaceable.replace(\"day\", \"night\")); // The night over the days\n\n// string.replaceAll -> Reemplaza todas las ocurrencias de un valor por otro\n\nconsole.log(replaceable.replaceAll(\"day\", \"night\")); // The night over the nights\n\n// string.slice -> Extrae una sección de la cadena y la retorna como una nueva cadena\n\nconsole.log(replaceable.slice(4, 7)); // day\n\n// string.split -> Divide la cadena en un array de subcadenas\n\nconsole.log(string.split(\" \")); // [ '', 'Just', 'a', 'normal', 'string', '' ]\n\n// string.startsWith -> Verifica si la cadena comienza con el valor que le pasas\n\nconsole.log(string.startsWith(\"Just\")); // false\n\n// string.substring -> Extrae los caracteres entre dos índices especificados\n\nconsole.log(replaceable.substring(4, 7)); // day\n\n// string.toLowerCase -> Convierte la cadena a minúsculas\n\nconsole.log(string.toLowerCase()); // just a normal string\n\n// string.toUpperCase -> Convierte la cadena a mayúsculas\n\nconsole.log(string.toUpperCase()); // JUST A NORMAL STRING\n\n// string.trim -> Elimina los espacios en blanco al inicio y al final de la cadena\n\nconsole.log(string.trim()); // Just a normal string\n\n// string.trimEnd -> Elimina los espacios en blanco al final de la cadena\n\nconsole.log(string.trimEnd()); // Just a normal string\n\n// string.trimStart -> Elimina los espacios en blanco al inicio de la cadena\n\nconsole.log(string.trimStart()); // Just a normal string\n*/\nfunction identifier(str1, str2) {\n  palindromo(str1);\n  palindromo(str2);\n  anagrama(str1, str2);\n  isograma(str1);\n  isograma(str2);\n}\n\nfunction palindromo(str) {\n  var regex = /[a-z]/g;\n\n  str = str.toLowerCase().match(regex).join(\"\");\n\n  return str === str.split(\"\").reverse().join(\"\")\n    ? console.log(str, \"es palindromo\")\n    : console.log(str, \"no es palindromo\");\n}\n//palindromo(\"A man, a plan, a canal, Panama\");\n\nfunction palindrome(str) {\n  var regex = /[a-z]/g;\n\n  str = str.toLowerCase().match(regex).join(\"\");\n\n  return str === str.split(\"\").reverse().join(\"\");\n}\n\nvar anagramaTest1 = \"Clint Eastwood\";\nvar anamgramaTest2 = \"Old West action\";\n\nfunction anagrama(str1, str2) {\n  regex = /[a-z]/g;\n\n  str1 = str1.toLowerCase().match(regex).join(\"\");\n  str2 = str2.toLowerCase().match(regex).join(\"\");\n\n  return str1.split(\"\").sort().join(\"\") === str2.split(\"\").sort().join(\"\")\n    ? console.log(str1, \"y\", str2, \"son anagramas\")\n    : console.log(str1, \"y\", str2, \"no son anagramas\");\n}\n\n//anagrama(anagramaTest1, anamgramaTest2);\n\nfunction isograma(str) {\n  var regex = /[a-z]/g;\n  str = str.toLowerCase().match(regex);\n  for (let i = 0; i < str.length; i++) {\n    if (str.indexOf(str[i]) !== str.lastIndexOf(str[i])) {\n      return console.log(str.join(\"\"), \"no es isograma\");\n    }\n  }\n  console.log(str.join(\"\"), \"es isograma\");\n}\n\n//isograma(\"Hormiga\");\n\nidentifier(\"Anita lava la tina\", \"Oso\");\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/saicobys.js",
    "content": "/* Operaciones basicas con string */\n\nlet saludo = \"Hola, mundo!\";\n\n// Acceso a caracteres especificos\nconsole.log(saludo[0]);\nconsole.log(saludo.charAt(4));\n\n// Subcadenas\nconsole.log(saludo.slice(0, 4));\nconsole.log(saludo.substring(5, 11));\n\n// Longitud\nconsole.log(saludo.length);\n\n// Concatenacion\nlet nombre = \"Juan\";\nconsole.log(saludo + \" \" + nombre);\n\n// Repeticion\nconsole.log(\"ja\".repeat(3));\n\n// Recorrido\nfor (let letra of saludo) {\n  console.log(letra);\n}\n\n// Conversion a mayusculas y minusculas\nconsole.log(saludo.toLocaleUpperCase());\nconsole.log(saludo.toLowerCase());\n\n// Reemplazo\nconsole.log(saludo.replace(\"mundo\", \"JavaScript\"));\n\n// Division\nlet palabras = saludo.split(\" \");\nconsole.log(palabras);\n\n// Union\nconsole.log(palabras.join(\"-\"));\n\n// Interpolacion\nlet edad = 30;\nconsole.log(`Hola, ${nombre}! Tienes ${edad} años.`);\n\n// Verificación\nconsole.log(saludo.startsWith(\"Hola\"));\nconsole.log(saludo.endsWith(\"!\"));\nconsole.log(saludo.includes(\"mundo\"));\n\n/* Desafío Extra */\n\nfunction analizarPalabras(palabra1, palabra2) {\n  palabra1 = palabra1.toLowerCase().replace(/[^a-z]/g, \"\");\n  palabra2 = palabra2.toLowerCase().replace(/[^a-z]/g, \"\");\n\n  // Palíndromo\n  const esPalindromo = palabra1 === palabra1.split(\"\").reverse().join(\"\");\n\n  // Anagrama\n  const esAnagrama =\n    palabra1.split(\"\").sort().join(\"\") === palabra2.split(\"\").sort().join(\"\");\n\n  // Isograma (cada letra aparece solo una vez)\n  const esIsograma = new Set(palabra1).size === palabra1.length;\n\n  console.log(`Palíndromo: ${esPalindromo}`);\n  console.log(`Anagrama: ${esAnagrama}`);\n  console.log(`Isograma: ${esIsograma}`);\n}\n\nanalizarPalabras(\"Amor\", \"Roma\"); // Palíndromo y Anagrama\nanalizarPalabras(\"Ojo\", \"ojo\"); // Palíndromo e Isograma\nanalizarPalabras(\"Hola\", \"Chau\"); // Ninguna\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/seandsun.js",
    "content": "// Concatenación o interpolación por medio de los templates string: ` ${} `\nlet apellido = \"Henao\"\nlet nombreApellido = `Marisol ${apellido}` // Marisol Henao\n\n// Extraer o cortar una cadena pasando índice de inicio y fin\n//  H  A  R  R  Y     P  O  T  T   E   R\n//  0  1  2  3  4  5  6  7  8  9  10  11\nlet pelicula = \"Harry Potter\"\nlet extraer = pelicula.slice(0, 7) // Harry P\n\n// Buscar el dato que se pasa como argumento en una cadena\nlet incluir = pelicula.includes(\"Potter\") // true\n\n// Concatenar dos o más cadenas\nlet descripcion = \" es mi saga favorita\"\nlet guardianes = ' y guardianes de la galaxia'\nlet concatenarCadenas = pelicula.concat( descripcion, guardianes) // Harry Potter es mi saga favorita y guardianes de la galaxia\nconcatenarCadenas = pelicula.concat(\" es\").concat(\" maravilloso\") // Harry Potter es maravilloso\n\n// eliminar espacios iniciales y finales de una cadena\nlet eliminarEspacios = descripcion.trim() // es mi saga favorita\n\n// Fragmentar el texto cada que encuetre el dato que se pasa como agurmento \nlet fragmentar = pelicula.split(\"\") // [ 'H', 'a', 'r', 'r','y', ' ', 'P', 'o','t', 't', 'e', 'r' ]\n\n// Reemplazar un caracter o cadena por otro\nlet reemplazar = pelicula.replace(\"r\",\"p\") // Hapry Potter\n\n// Reemplazar un caracter más de una vez. g: global, capturar todo; i: ignorar mayúsculas y minúsculas\nreemplazar = pelicula.replace(/r/gi,\"p\") // Happy Pottep\n\n// Encontrar índice de un caracter (el primero) en una cadena, devuleve -1 si no lo encuentra \nlet primerCaracter = pelicula.indexOf(\"t\") // 8\n\n// Encontrar indice de un caracter (el último) en una cadena desde el index 8 hacia atrás\nlet ultimoCaracter = pelicula.lastIndexOf(\"r\", 8) // 3\n\n// Encontrar la longitud de una cadena\nlet longitud = pelicula.length-1 // 11\n\n// Convertir una cadena a mayúsculas\nlet mayusculas = pelicula.toUpperCase() // HARRY POTTER\n\n// Convertir una cadena a minúsculas\nlet minusculas = pelicula.toLowerCase() // harry potter\n\n// Acceder a un caracter pasanso su índice\nlet accederCaracter = pelicula.charAt(0) // H\naccederCaracter = pelicula[0] // H\n\n// Unir un los elementos de un arreglo en una sola cadena\nlet array = [\"estoy\", \"aprendiendo a\", \"programar en js\"]\nlet unir = array.join(\" \") // estoy aprendiendo a programar en js\n\n// Saber si una cadena inicia con una subcadena específica. Distingue entre mayúscaulas y minúsculas\nlet comienzaCon = unir.startsWith(\"estoy\") // true\n\n// Saber si una cadena termina con una subcadena específica. Distingue entre mayúscaulas y minúsculas\nlet terminaCon = unir.endsWith(\"en js\") // true\n\n// Operaciones combinadas\nlet operacionesCombinadas = pelicula.toUpperCase().slice(0, 5).split(\"\") // [ 'H', 'A', 'R', 'R', 'Y' ]\n\n// ----------> Ejercicio: palíndromos <----------\n\nlet palabra1 = \"AniMal\"\nlet palabra2 = \"lamINa\"\nlet longitudPal2 = palabra2.length-1\n\nfunction palindromo (palabra1, palabra2) {\n    palabra1 = palabra1.toLowerCase()\n        \n    let arr = []\n    for(let j=longitudPal2; j>=0; j--) {\n        arr.push(palabra2[j])\n    }\n    let unionPalabra2 = arr.join(\"\").toLowerCase()\n    \n    if (palabra1 === unionPalabra2) {\n        return `Es un palíndromo: ${palabra1} = ${unionPalabra2}`\n    } \n}\nlet resultado = palindromo(palabra1, palabra2)\nconsole.log(resultado)"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/shevotool.js",
    "content": "// #04 CADENAS DE CARACTERES\n\n/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n */\n\n// length\nconst lenguaje = \"javaScript\";\nconst longitudCadena = lenguaje.length;\nconsole.log(longitudCadena);\n\n//concatenar\nconst nombre = \"Erick\";\nconst apellido = \"Alphonse\";\nconsole.log(nombre + \" \" + apellido);\n\n//indexOf()\nconst secondIndex = apellido.indexOf(\"l\", 0);\nconsole.log(secondIndex);\n\n//substring()\nconst textoRandom =\n  \"Vive la vida y no que la vida te viva es lo que dice mi jefe\";\nconst extraerFrase = textoRandom.substring(0, 37);\nconsole.log(extraerFrase);\n\n// cadenas primitivas\nconst string1 = \"Houston tenemos un problema\";\nconsole.log(string1);\n\nconst string2 = `Confirmado, cambio`;\nconsole.log(string2);\n\nconst string3 = new String(\"Hasta la vista baby\");\nconsole.log(string3);\n\n// interpolación\nconst cualidad = \"inteligente\";\nconsole.log(`Mi perro lulu es muy ${cualidad}!`);\n\n// Acceder a un caracter, existen dos formas\n\n// charAt()\nconst gato = \"cat\";\nconsole.log(gato.charAt(1));\n\n//  tratar a la cadena como un objeto similar a un arreglo\nconsole.log(gato[1]);\n\n// Comparar cadenas con los operadores menor que y mayor que:\nconst numero1 = 20;\nconst numero2 = 10;\n\nif (numero1 > numero2) {\n  console.log(`${numero1} es mayor que ${numero2}`);\n} else if (numero1 < numero2) {\n  console.log(`${numero2} es mayor que ${numero1}`);\n} else {\n  console.log(`${numero1} y ${numero2} son iguales`);\n}\n\n// localeCompare()\nconsole.log(\"a\".localeCompare(\"c\"));\nconsole.log(\"check\".localeCompare(\"against\"));\nconsole.log(\"look\".localeCompare(\"foward\"));\nconsole.log(\"2\".localeCompare(\"10\"));\n\n//Ordenar un arreglo con localeCompare()\nlet items = [\"réservé\", \"Premier\", \"Cliché\", \"communiqué\", \"café\", \"Adieu\"];\nitems.sort((a, b) => a.localeCompare(b, \"fr\", { ignorePunctuation: true }));\nconsole.log(items);\n\n// comparar\nfunction isEqual(a, b) {\n  return a.toUpperCase() === b.toUpperCase();\n}\nconsole.log(isEqual(\"PerRo\", \"perro\"));\n\n// JavaScript automáticamente convierte las primitivas en objetos String\nlet s_prim = \"foo\";\nlet s_obj = new String(s_prim);\nconsole.log(typeof s_prim);\nconsole.log(typeof s_obj);\n\n// eval()\nlet s1 = \"2 + 2\";\nlet s2 = new String(\"2 + 2\");\nconsole.log(eval(s1));\nconsole.log(eval(s2));\n\n// valueOf()\nconsole.log(s1.valueOf());\nconsole.log(s2.valueOf());\n\n// agregar varias cadenas juntas\nlet longString =\n  \"Lorem ipsum dolor sit amet, consectetur adipiscing elit.\" +\n  \" Ut enim ad minim veniam, quis nostrud exercitation.\" +\n  \" Duis aute irure dolor in reprehenderit in voluptate.\";\nconsole.log(longString);\n\nlet longString2 =\n  \"Lorem ipsum dolor sit amet, consectetur adipiscing elit.\\\n   Ut enim ad minim veniam, quis nostrud exercitation.Duis\\\n    aute irure dolor in reprehenderit in voluptate.\";\nconsole.log(longString2);\n\n// String() constructor\n\n//String constructor and String function\n//String function and String constructor produce different results:\n\nconst a = new String(\"Hello world\"); // a === \"Hello world\" is false\nconst b = String(\"Hello world\"); // b === \"Hello world\" is true\nconsole.log(a instanceof String);\nconsole.log(b instanceof String);\nconsole.log(typeof a);\nconsole.log(typeof b);\n\n// Métodos estáticos\n\n// String.fromCharCode()\nconsole.log(String.fromCharCode(65, 66, 67, 68));\n\n// String.fromCodePoint()\nconsole.log(String.fromCodePoint(42));\n//console.log(String.fromCodePoint(NaN));\n\n// String.raw()\nconsole.log(\"с:\\u005c.js\");\nconsole.log(String.raw`с:\\u.js`);\n\n// Propiedades de la instancia\n\n//String.length;\nlet lenguaje2 = \"Python\";\nconsole.log(lenguaje2.length);\n\n// charAt()\nconst lenguaje3 = \"Rust\";\nconsole.log(lenguaje3.charAt(3));\n\n// charCodeAt()\nconst lenguaje4 = \"Java\";\nconsole.log(lenguaje4.charCodeAt(1));\n\n// codePointAt()\nconst lenguaje5 = \"Kobol\";\nconsole.log(lenguaje4.codePointAt(1));\n\n// concat();\nconst saludar = \"Hola \";\nconst individuo = \"forastero\";\nconsole.log(saludar.concat(individuo));\n\n// endsWith()\nconst texto2 = \"vive la vida loca\";\nconsole.log(texto2.endsWith(\"loca\"));\n\n// includes()\nconst texto3 = \"vive la vida loca\";\nconsole.log(texto3.includes(\"la\"));\n\n// indexOf()\nconsole.log(\"Blue Whale\".indexOf(\"Whale\", 5));\n\n// lastIndexOf()\nconst parrafo = \"I think Ruth's dog is cuter than your dog!\";\nconst mascota = \"dog\";\n\nconsole.log(`Index of the last ${mascota} is ${parrafo.lastIndexOf(mascota)}`);\n\n// localeCompare()\nconst a1 = \"réservé\";\nconst b2 = \"RESERVE\";\nconsole.log(a1.localeCompare(b2));\n\n// match()\nconst parrafo2 = \"The quick brown fox jumps over the lazy dog. It barked.\";\nconst regex = /[A-Z]/g;\nconst encontrado = parrafo2.match(regex);\nconsole.log(encontrado);\n\n// matchAll();\nconst regexexp = /t(e)(st(\\d?))/g;\nconst str = \"test1test2\";\nconst array = [...str.matchAll(regexexp)];\nconsole.log(array[0]);\nconsole.log(array[1]);\n\n// padEnd()\nconst str3 = \"Hola\";\nconsole.log(str3.padEnd(25, \".\"));\n\n// padStart()\nconst str4 = \"Hola\";\nconsole.log(str4.padStart(25, \".\"));\n\n// repeat()\nconst saludo = \"Hola! \";\nconsole.log(saludo.repeat(3));\n\n// replace();\nconst parrafo1 =\n  \"¡Creo que el perro de Ruth es más bonito que el perro de Jose!\";\nconsole.log(parrafo1.replace(/Ruth/gi, \"Pedro\"));\n\n// replaceAll();\nconst parrafo3 =\n  \"¡Creo que el perro de Ruth es más bonito que el perro de Jose!\";\nconsole.log(parrafo3.replaceAll(/perro/gi, \"conejo\"));\n\n// search();\nconst parrafo4 =\n  \"¡Creo que el perro de Ruth es más bonito que el perro de Jose!\";\nconst regex3 = /[^\\w\\s']/g;\nconsole.log(parrafo4.search(regex3));\nconsole.log(parrafo4[parrafo4.search(regex)]);\n\n// slice();\nconst str5 = \"El rápido zorro marrón salta sobre el perro perezoso.\";\nconsole.log(str5.slice(44));\nconsole.log(str5.slice(10, 22));\n\n// split();\nconst str6 = \"El rápido zorro marrón salta sobre el perro perezoso.\";\nconst palabras = str6.split(\" \");\nconsole.log(palabras[2]);\n\n// startsWith();\nconst str7 = \"Planes de sabado por la noche\";\nconsole.log(str7.startsWith(\"Pla\"));\n\n// substring()\nconst str8 = \"Mozilla\";\nconsole.log(str8.substring(2, 7));\n\n// toLowerCase()\nconst str9 = \"Planes de sabado por la noche con Dios\";\nconsole.log(str9.toLowerCase());\n\n// toString()\nconst strObj = new String(\"foo\");\nconsole.log(typeof strObj);\nconsole.log(strObj.toString());\n\n// toUpperCase()\nconst str10 = \"Planes de sabado por la noche con Dios\";\nconsole.log(str10.toUpperCase());\n\n// trim()\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\nconst palabra1 = \"Pensar\";\nconst palabra2 = \"Correr\";\nconst palabra3 = \"radar\";\nconst palabra4 = \"amor\";\nconst palabra5 = \"Roma\";\n\nfunction palindromo(palabra1, palabra2) {\n  return (\n    palabra1.toLowerCase().split(\"\").reverse().join(\"\") ===\n    palabra2.toLowerCase()\n  );\n}\n\nconsole.log(palindromo(palabra3, palabra3));\nconsole.log(palindromo(palabra1, palabra2));\n\nfunction anagrama(palabra1, palabra2) {\n  return (\n    palabra1.toLowerCase().split(\"\").sort().join(\"\") ===\n    palabra2.toLowerCase().split(\"\").sort().join(\"\")\n  );\n}\n\nconsole.log(anagrama(palabra4, palabra5));\n\nfunction isogramas(palabra1) {\n  let palabra = [];\n  for (let i = 0; i < palabra1.length; i++) {\n    if (palabra.includes(palabra1[i])) {\n      return true;\n    } else {\n      palabra.push(palabra1[i]);\n    }\n  }\n  return false;\n}\n\nconsole.log(isogramas(palabra1));\nconsole.log(isogramas(palabra2));\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/ssanjua.js",
    "content": "const contatenacion = 'hola' + ' mundo';          // hola mundo\nconst longitud = 'hola'.length;                   // 4\nconst caractereseEsp = 'hola'.charAt(0);          // h\nconst subcadenas = 'hola'.substring(0, 2);        // ho\nconst mayus = 'hola'.toUpperCase();               // HOLA\nconst minus = 'Hola'.toLowerCase();               // hola\nconst repetir = 'hola'.repeat(3);                 // holaholahola\nconst trim = ' hola '.trim();                     // hola\nconst includes = 'hola'.includes('o');            // true\nconst indexOf = 'hola'.indexOf('o');              // 1\nconst lastIndexOf = 'holaho'.lastIndexOf('o');    // 5\nconst replace = 'hola'.replace('o', 'a');         // hala\nconst slice = 'hola'.slice(0, 2);                 // ho\nconst split = 'hola'.split('');                   // ['h', 'o', 'l', 'a']\nconst terminaCon = 'hola'.endsWith('a');          // true\nconst empiezaCon = 'hola'.startsWith('h');        // true\nconst comparacion = 'hola'.localeCompare('hola'); // 0\n\n\nconsole.log(contatenacion, longitud, caractereseEsp, subcadenas, mayus, minus, repetir, trim, includes, indexOf, lastIndexOf, replace, slice, split, terminaCon, empiezaCon, comparacion);\n\n\n/* EXTRA\n  * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n  * para descubrir si son:\n  * - Palíndromos\n  * - Anagramas\n  * - Isogramas\n*/\n\nfunction palindromo(palabra) {\n  const palabraInvertida = palabra.split('').reverse().join('');\n  return palabra === palabraInvertida;\n}\n\nfunction anagrama(palabra1, palabra2) {\n  return palabra1.split('').sort().join('') === palabra2.split('').sort().join('');\n}\n\nfunction isograma(palabra) {\n  const letras = palabra.split('');\n  return letras.length === new Set(letras).size;\n}\n\nconsole.log(palindromo('oso'));         // true\nconsole.log(anagrama('roma', 'amor'));  // true\nconsole.log(isograma('murcielago'));    // true\nconsole.log(isograma('oso'));           // false\nconsole.log(palindromo('hola'));        // false\nconsole.log(anagrama('rama', 'amor'));  // false"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/victor-Casta.js",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\n//acceder a un caracter \nconsole.log(\"Hola\".charAt(1)); //Imprime \"o\"\nconsole.log(\"JavaScript\"[1]); //Imprime \"a\"\n\n//Subcadenas\n//Método substring(startIndex, endIndex)\nlet originalString = \"Hola JavaScript\";\nlet subcadena = originalString.substring(5, 15);\nconsole.log(subcadena);\n\n//Propiedad slice(startIndex, endIndex)\nlet sliceSubcadena = originalString.slice(0, 4)\nconsole.log(sliceSubcadena);\n\n//Método substring(index)\nlet substringString = originalString.substring(5);\nconsole.log(substringString);\n\n\n//Longitud\nlet myString = 'JavaScript';\nconsole.log(myString.length);\n\n//Concatenación\nlet stringOne = 'hola';\nlet stringTwo = 'mundo';\nconsole.log(stringOne + ' ' + stringTwo);\nconsole.log(`${stringOne} ${stringTwo}`);\n\n//repeticion\nlet repeatTimes = 3;\nlet repeatedString = `${stringOne.repeat(repeatTimes)}`\nconsole.log(repeatedString);\n\n//recorrido\nlet myString2 = () => {\n  for (let i=0 ; i < myString.length ; i++) {\n    console.log(myString[i]);\n  }\n}\n\nmyString2();\n\n//conversión a mayúsculas y minúsculas\nconsole.log(\"alphabet\".toUpperCase());\nconsole.log(\"alphabet\".toLowerCase());\n\n//reemplazo\nlet replacedString = \"Hello World\".replace(\"World\", \"JavaScript\");\nconsole.log(replacedString);\n\n//interpolación\nconst a = 'Hello';\nconst b = 'JavaScript'\n\nconsole.log(`${a} ${b} welcome to roadmap!`);\n\n//verificación\nlet string  = \"Hello World\";\nconsole.log(typeof(string));\n\n\n//Programa\n\nlet myProgram = (word1, word2) => {\n  const formatWord1 = word1.replace(/\\s/g, '').toLowerCase();\n  const formatWord2 = word2.replace(/\\s/g, '').toLowerCase();\n\n  const palindromo1 = formatWord1.split('').reverse().join('');\n  const palindromo2 = formatWord2.split('').reverse().join('');\n\n  const anagrama1 = formatWord1.split('').sort().join('');\n  const anagrama2 = formatWord2.split('').sort().join('');\n\n  const isIsogram = (word) => {\n    const charCount = {};\n    for (let char of word) {\n      if (charCount[char]) {\n        return false;\n      }\n      charCount[char] = 1;\n    }\n    return true;\n  };\n\n  if (word1 === palindromo1 && word2 === palindromo2) {\n    console.log(`La palabra ${word1} y ${word2} son palíndromos.`);\n  } else if (anagrama1 === anagrama2) {\n    console.log(`La palabra ${word1} y ${word2} son anagramas.`);\n  } else if (isIsogram(formatWord1) && isIsogram(formatWord2)) {\n    console.log(`La palabra ${word1} y ${word2} son isogramas.`);\n  } else {\n    console.log('No son ni palíndromos ni anagramas ni isogramas.');\n  }\n};\n\nmyProgram('roma', 'amor');\n\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/wapastorv.js",
    "content": "/* EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en JavaScript. Todas las operaciones que se podrian hacer:\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación, etc...\n*/\n\n// Acceso a caracteres específicos\nlet cadena = \"Hola mundo\";\nconsole.log(cadena[0]); // H\nconsole.log(cadena.charAt(0)); // H\nconsole.log(cadena.charCodeAt(0)); // 72\n\n// Subcadenas\nconsole.log(cadena.substring(0, 4)); // Hola\nconsole.log(cadena.substr(0, 4)); // Hola\nconsole.log(cadena.slice(0, 4)); // Hola\nconsole.log(cadena.slice(-5)); // mundo\n\n// Longitud\nconsole.log(cadena.length); // 10\n\n// Concatenación\nlet cadena2 = \" desde JavaScript\";\nconsole.log(cadena + cadena2); // Hola mundo desde JavaScript\nconsole.log(cadena.concat(cadena2)); // Hola mundo desde JavaScript\n//console.log(cadena.concat(\" desde JavaScript\")); // Hola mundo desde JavaScript\n\n// Repetición\nconsole.log(cadena.repeat(3)); // Hola mundoHola mundoHola mundo\n\n//Recorrido o Iteración\nfor (let i = 0; i < cadena.length; i++) {\n    console.log(cadena[i]);// H o l a   m u n d o\n}\nfor(let i in cadena){\n    console.log(cadena[i]); // H o l a   m u n d o\n}\n\n// Conversión a mayúsculas y minúsculas\nconsole.log(cadena.toUpperCase()); // HOLA MUNDO\nconsole.log(cadena.toLowerCase()); // hola mundo\n\n// Reemplazo\nconsole.log(cadena.replace(\"mundo\", \"amigos\")); // Hola amigos\nconsole.log(cadena.replace(/o/g, \"0\")); // H0la mund0\n\n// División\nconsole.log(cadena.split(\" \")); // [\"Hola\", \"mundo\"]\n\n// Unión\nconsole.log([\"Hola\", \"mundo\"].join(\" \")); // Hola mundo\n\n// Interpolación\nlet nombre = \"Juan\";\nlet edad = 25;\nconsole.log(`Me llamo ${nombre} y tengo ${edad} años.`); // Me llamo Juan y tengo 25 años.\n\n// Verificación\nconsole.log(cadena.startsWith(\"Hola\")); // true\nconsole.log(cadena.endsWith(\"mundo\")); // true\nconsole.log(cadena.includes(\"mundo\")); // true\n\nconsole.log(cadena.match(/o/g)); // [\"o\", \"o\"] \nconsole.log(cadena.match(/o/g).length); // 2\nconsole.log(cadena.match(/o/g).join(\"\")); // oo\nconsole.log(cadena.match(/o/g).toString()); // o,o\nconsole.log(cadena.match(/o/g).reverse().join(\"\")); // o,o (no funciona) porque reverse() no es una función de un array de strings sino de un array de objetos (en este caso, de un array de strings)\n\n//Eliminar Espacios en Blanco (Trim)\nlet cadena3 = \"    Hola mundo    \";\nconsole.log(cadena3.trim()); // Hola mundo (elimina los espacios en blanco al principio y al final de la cadena)\nconsole.log(cadena3.trimStart()); // Hola mundo    (elimina los espacios en blanco al principio de la cadena)\nconsole.log(cadena3.trimEnd()); //     Hola mundo (elimina los espacios en blanco al final de la cadena)\n\n// Buscar indice de un caracter o subcadena\nconsole.log(cadena.indexOf(\"mundo\")); // 5\nconsole.log(cadena.lastIndexOf(\"o\")); // 7\nconsole.log(cadena.search(\"mundo\")); // 5\n\n// Comparación de Cadenas\nlet cadena4 = \"Hola\";\nlet cadena5 = \"Hola\";\nconsole.log(cadena4 === cadena5); // true (compara el valor y el tipo de dato) \nconsole.log(cadena4 == cadena5); // true (compara el valor)\nconsole.log(cadena4 > cadena5); // false (compara el valor en Unicode)\nconsole.log(cadena4 < cadena5); // false (compara el valor en Unicode)\nconsole.log(cadena4 >= cadena5); // true (compara el valor en Unicode)\nconsole.log(cadena4 <= cadena5); // true (compara el valor en Unicode)\n\n//Convertir Cadena a Array de Caracteres\nlet cadena6 = \"Hola\";\nconsole.log(cadena6.split(\"\")); // [\"H\", \"o\", \"l\", \"a\"]\nlet chars = [...cadena6];\nconsole.log(chars); // [\"H\", \"o\", \"l\", \"a\"]\n\n//Remplazo Complejo Usando Expresiones Regulares\nlet cadena7 = \"Hola mundo\";\nconsole.log(cadena7.replace(/(mundo)/, \"amigos\")); // Hola amigos\n\nlet frase = \"Ella es ella, pero ella no es él.\";\nconsole.log(frase.replace(/ella/g, \"él\")); // Él es él, pero él no es él.\n\n//Convertir a Código ASCII\nlet cadena8 = \"Hola\";\nlet ascii = \"\";\nfor (let i = 0; i < cadena8.length; i++) {\n    ascii += cadena8.charCodeAt(i) + \" \";\n}\nconsole.log(ascii); // 72 111 108 97\n\n//Convertir a Código ASCII con Expresiones Regulares\nlet cadena9 = \"Hola\";\nlet ascii2 = \"\";\nlet asciiArray = cadena9.split(\"\").map(c => c.charCodeAt(0));\nascii2 = asciiArray.join(\" \");\nconsole.log(ascii2); // 72 111 108 97\n\n//convertir a Código ASCII con Expresiones Regulares\nconst texto = \"Hola\";\nlet ascii3 = texto.replace(/./g, c => c.charCodeAt(0) + \" \");\nconsole.log(ascii3); // 72 111 108 97\n\n//Convertir a Código ASCII con Expresiones Regulares y Eliminar Espacios en Blanco\nconst texto2 = \"Hola\"; \nlet ascii4 = texto2.replace(/./g, c => c.charCodeAt(0) + \" \").trim();\nconsole.log(ascii4); // 72 111 108 97\n\n//Convertir a Código ASCII con Expresiones Regulares y Eliminar Espacios en Blanco con Expresiones Regulares\nconst texto3 = \"Hola\";\nlet ascii5 = texto3.replace(/./g, c => c.charCodeAt(0) + \" \").replace(/\\s/g, \"\");\nconsole.log(ascii5); // 7211110897\n\n//Convertir a Código ASCII con Expresiones Regulares y Eliminar Espacios en Blanco con Expresiones Regulares y Convertir a Array\nconst texto4 = \"Hola\";\nlet ascii6 = texto4.replace(/./g, c => c.charCodeAt(0) + \" \").replace(/\\s/g, \"\").split(\"\");\nconsole.log(ascii6); // [\"7\", \"2\", \"1\", \"1\", \"1\", \"0\", \"8\", \"9\", \"7\"]\n\n//Convertir a Código ASCII con Expresiones Regulares y Eliminar Espacios en Blanco con Expresiones Regulares y Convertir a Array de Números\nconst texto5 = \"Hola\";\nlet ascii7 = texto5.replace(/./g, c => c.charCodeAt(0) + \" \").replace(/\\s/g, \"\").split(\"\").map(Number);\nconsole.log(ascii7); // [7, 2, 1, 1, 1, 0, 8, 9, 7]\n\n\n// Ejercio Practico\nfunction esPalindromo(texto) {\n    // Convertimos el texto a minúsculas, eliminamos todos los caracteres no alfanuméricos\n    // y normalizamos para eliminar tildes\n    const textoLimpio = texto\n        .normalize('NFD')         // Descompone caracteres acentuados\n        .replace(/[\\u0300-\\u036f]/g, '') // Elimina los diacríticos (tildes)\n        .toLowerCase()            // Convertimos todo a minúsculas\n        .replace(/[^a-z0-9]/g, ''); // Eliminamos caracteres no alfanuméricos\n\n    // Comparamos el texto limpio con su versión invertida\n    const esPalindromo = textoLimpio === textoLimpio.split('').reverse().join('');\n\n    // Retornamos un mensaje en forma de string indicando si es palíndromo o no\n    return esPalindromo ? `\"${texto}\" es un palíndromo` : `\"${texto}\" no es un palíndromo`;\n}\n\nconst frase1= \"Somos o no somos\"\nconst frase2 = \"Amó la paloma\"\nconst frase3 = \"palabra\"\nconst frase4 = \"No es palíndromo\"\n\nconsole.log(esPalindromo(frase1)); // \"Somos o no somos\" es un palíndromo\nconsole.log(esPalindromo(frase2)); // \"Amó la paloma\" es un palíndromo\nconsole.log(esPalindromo(frase3)); // \"palabra\" no es un palíndromo\nconsole.log(esPalindromo(frase4)); // \"No es palíndromo\" no es un palíndromo\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/wolffcode.js",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\nconst cadena = \"anita lava la tina\"\n\n    //at\nlet index = 5 //at toma un valor numérico y hace la bsuqueda\nconsole.log(`el index número: ${index} regresara el carácter: \"${cadena.at(index)}\" de la cadena de texto`) //buscara en la cadena el carácter que este en la posición que especificamos\nlet negativeíndex = -3\nconsole.log(`el index número: ${negativeíndex} regresara el carácter: \"${cadena.at(negativeíndex)}\" de la cadena de texto`) //si usamos un index negativo, la búsqueda del carácter comenzara desde el final de la cadena\n\n    // charAt\nlet charnum = 6\nconsole.log(`el index número: ${charnum} regresara el carácter: \"${cadena.charAt(charnum)}\" de la cadena de texto`) //buscara en la cadena el carácter que este en la posición que especificamos\nlet charnegative = -3\nconsole.log(`el index número: ${charnegative} regresara el carácter: \"${cadena.charAt(charnegative)}\" de la cadena de texto`) //charAt no funciona con indices negativos\n\n    // concat\nconst cadena2 = \"no lavo nada anita\"\nconsole.log(cadena.concat(cadena2)) //concatenara ambas cadenas\nconsole.log(cadena.concat(\", \",cadena2)) //nos permite agregar una cadena intermedia para agregar espacios o comas\n\n    // endsWith\nconsole.log(cadena.endsWith('tina')) //regresa true o false si la cadena termina con los caracteres que hemos dado como parámetros\nconsole.log(cadena.endsWith('tina', 20)) //no entiendo esta parte todavía\n\n    // indexOf\nconst searchTerm = \"lava\"\nconsole.log(`el index de la palabra \"${searchTerm}\" es: \"${cadena.indexOf(searchTerm)}\"`) //regresa el index del primer carácter que componga el parámetro especificado\n\n    // repeat\nconst palabra = \"Feliz \"\nconsole.log(`hoy me encuentro muy ${palabra.repeat(3)}!`)\n\n    //include\nconsole.log(`la la palabra tina se encuentra en la cadena ? ${cadena.includes('tina') ? 'verdadero': 'falso'}`) //regresa true o false si el parámetro especificado se encuentra en la cadena\n\n\n    // replace\nconst mascota= \"A mi me gustan mas los perros que los gatos porque son mas juguetones los perros que los gatos\"\nconsole.log(mascota.replace(\"mi me\", 'mi amiga le')) //remplaza un pedazo de la cena con el parámetro especificado\n\n    //replaceAll\nconst mascotas= \"A mi me gustan mas los perros que los gatos porque son mas juguetones los perros que los gatos\"\nconsole.log(mascotas.replaceAll('perros', 'mapaches'))\n\n    //slice\nconsole.log(cadena.slice(6,12))\n\n    // split\nconsole.log(cadena.split('a'))\nconsole.log(cadena.split('a')[2])\nconsole.log(cadena.split(' '))\nconsole.log(cadena.split('n'))\n\n    // startsWith\nconsole.log(cadena.startsWith('ani'))\n\n    //substring\nconsole.log(cadena.substring(3, 14))\n\n    // toLocaleLowerCase\nconst minus = \"miNUScuLas\"\nconsole.log(minus.toLocaleLowerCase('en-US'))\n                                                        // estas funcionan similar a toLowerCase o toUpperCase pero agregando como parámetro un locale-specific case mapping\n    //toLocalUpperCase\nconst mayus = \"MayuscuLas\"\nconsole.log(mayus.toLocaleUpperCase('en-US'))\n\n    // trim\nconst saludo = \"      Hola   mundo!           \"\nconsole.log(saludo.trim())\nconsole.log(saludo.trimEnd())\nconsole.log(saludo.trimStart())\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/xmunder.js",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n*/\n\n// Acceso a caracteres específicos\nlet cadena = \"Hola, mundo!\";\nconsole.log(cadena[0]); // Muestra \"H\"\nconsole.log(cadena.charAt(7)); // Muestra \"m\"\n\n// Subcadenas\nlet subcadena = cadena.substring(6, 11);\nconsole.log(subcadena); // Muestra \"mundo\"\n\n// Longitud de la cadena\nconsole.log(cadena.length); // Muestra 12\n\n// Concatenación\nlet otraCadena = \" Qué tal?\";\nlet resultadoConcatenacion = cadena + otraCadena;\nconsole.log(resultadoConcatenacion); // Muestra \"Hola, mundo! Qué tal?\"\n\n// Repetición\nlet cadenaRepetida = cadena.repeat(3);\nconsole.log(cadenaRepetida); // Muestra \"Hola, mundo!Hola, mundo!Hola, mundo!\"\n\n// Recorrido\nfor (let i = 0; i < cadena.length; i++) {\n  console.log(cadena[i]);\n}\n\n// Conversión a mayúsculas y minúsculas\nconsole.log(cadena.toUpperCase()); // Muestra \"HOLA, MUNDO!\"\nconsole.log(cadena.toLowerCase()); // Muestra \"hola, mundo!\"\n\n// Reemplazo\nlet nuevaCadena = cadena.replace(\"mundo\", \"amigo\");\nconsole.log(nuevaCadena); // Muestra \"Hola, amigo!\"\n\n// División\nlet palabras = cadena.split(\", \");\nconsole.log(palabras); // Muestra [\"Hola\", \"mundo!\"]\n\n// Unión\nlet nuevaCadenaUnida = palabras.join(\" \");\nconsole.log(nuevaCadenaUnida); // Muestra \"Hola mundo!\"\n\n// Interpolación\nlet nombre = \"Cristian\";\nlet edad = 21;\nconsole.log(`Mi nombre es ${nombre} y tengo ${edad} años.`);\n\n// Verificación\nconsole.log(cadena.includes(\"mundo\")); // Devuelve true\nconsole.log(cadena.startsWith(\"Hola\")); // Devuelve true\nconsole.log(cadena.endsWith(\"!\")); // Devuelve true\n\n// Dificultad extra\n\nconst transformString = (myString) => {\n  return myString.replace(/\\s/g, \"\").toLowerCase();\n};\n\nconst isPalindrome = (myString) => {\n  const myWord = transformString(myString);\n  myWord === Array.from(myWord).reverse().join(\"\")\n    ? console.log(`${myString} es un Palíndromo`)\n    : console.log(`${myString} no es un Palíndromo`);\n};\n\nconst isAnagram = (myString1, myString2) => {\n  const myWord1 = transformString(myString1);\n  const myWord2 = transformString(myString2);\n  if (myWord1.length === myWord2.length) {\n    const isAnagram = Array.from(myWord1).every((char) =>\n      myWord2.includes(char)\n    );\n    isAnagram\n      ? console.log(`${myString1} y ${myString2} son Anagramas`)\n      : console.log(`${myString1} y ${myString2} no son Anagramas`);\n  }\n};\n\nconst isIsogram = (myString) => {\n  const myWord = transformString(myString);\n  const letter = myWord.split(\"\").sort();\n  for (let index = 0; index < letter.length; index++) {\n    if (letter[index] === letter[index + 1]) {\n      return console.log(`${myString} no es un Isograma`);\n    }\n  }\n  return console.log(`${myString} es un Isograma`);\n};\n\nisPalindrome(\"Oso\");\nisPalindrome(\"Casa\");\nisAnagram(\"Roma\", \"Amor\");\nisAnagram(\"Rojo\", \"Verde\");\nisIsogram(\"Cristian\");\nisIsogram(\"Hamburguesa\");\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/javascript/yesidL12.js",
    "content": "// <------- Cadena de carácteres ---------->\n let nombre = 'Juan Perez';\n let nombre1 = \"Juan Perez\";\n let nombre2 = `Juan Perez`;\n\n console.log(typeof(nombre)); // Cadena\n console.log(typeof(nombre1));//Cadena\n console.log(typeof(nombre2)); // Cadena\n\n //<------- Concatenación de cadenas --------->\n\n let nombre4 = 'Juan';\n let apellido = 'Perez';\n let nombreCompleto = nombre + ' ' + apellido;\n console.log(nombreCompleto); // Juan Perez\n\n\nlet nombre5 = 'Juan';\nlet apellido1 = 'Perez';\nlet nombreCompleto1 = nombre5.concat(' ', apellido1);\nconsole.log(nombreCompleto1); // Juan Perez\n\n\n// Concatenación con plantillas literales\n\nlet nombre6 = 'Juan';\nlet apellido2 = 'Perez';\nlet nombreCompleto2 = `${nombre6} ${apellido2}`;\nconsole.log(nombreCompleto2); // Juan Perez\n\n\n//<-------- Convertir de mayusculas a minisculas y viceversa ----------->\n\nlet mensaje = 'Bienvenidos';\nlet mensajaeMayusculas = mensaje.toUpperCase();\nlet mensajeMinusculas = mensaje.toLocaleLowerCase();\n\nconsole.log(mensajaeMayusculas); // BIENVENIDOS\nconsole.log(mensajeMinusculas); // bienvenidos\n\n//<------- Métodos del string ---------->\n\n// Para encontrar el tamaño de un string\n\nlet browserType = 'mozilla';\nbrowserType.length(); // 7\n\n// Recuperar una cáracter especifico del string\nbrowserType[1]; // o\n\nbrowserType[browserType.length - 1]; //Forma recomendada para recuperar el último cáracter.\n\n\n//Probar si una cadena tiene una subcadena\n\nlet buscador = 'mozilla';\n\nif (buscador.includes('zilla')) {\n    console.log('Encontré zilla!');\n} else {\n    console.log('No hay zilla aqui');\n}\n\n// Para saber si tiene una subcadena al incio\n\nlet buscador1 = 'mozilla';\nif (buscador.startsWith('zilla')) {\n    console.log('Encontré \"zilla\"!');\n} else {\n    console.log('No hay \"zilla\" aqui');\n}\n\n// Para saber si tiene una subcadena al final\n\nlet buscador2 = 'mozilla';\nif(buscador2.endsWith('zilla')) {\n    console.log('Encontré \"zilla\"!');\n} else {\n    console.log('No hay \"zilla\" aqui');\n}\n\n// Para encontrar la posición de una subcadena\n\nlet tagline = 'MDN - REsourcer for developers, by developers';\nconsole.log(tagline.indexOf('developers')); // 20\n// indexOF, devuelve el indice de la primera aparición de la subcadena.\n\n//Para encontrar las subcadenas posteriores a la primera aparición\n\nlet firstOcurrence = tagline.indexOf('developers');\nlet secondOcurrence = tagline.indexOf('developers', firstOcurrence + 1);\n\nconsole.log(firstOcurrence); // 20\nconsole.log(secondOcurrence); // 35\n\n// Para extraer una subacdena de una cadena\n\nlet buscador3 = 'mozilla';\nconsole.log(buscador3.slice(1,4)); // 'azi\n\n// Para actualizar partes de una cadena\n\nlet buscador4 = 'mozilla';\nlet update = buscador4.replace('moz', 'van');\n\nconsole.log(update); // vanilla\nconsole.log(buscador4);// mozilla\n\n// <--------- Dificultad extra -------->\n\n// Palindromo\n\nconst palindromo = (palabra1, palabra2) => {\n    const palabraInvertida = palabra1.split('').reverse().join('');\n   if ( palabra2 === palabraInvertida){\n       console.log(`${palabra1} y ${palabra2} son palíndromos`);\n   } else {\n    console.log(`${palabra1} y ${palabra2} no son palíndromos`);\n   }\n}\n\npalindromo('amor' , 'roma');\npalindromo('Ana', 'Ana');\n\n// anagrama\n\nconst anagrama = (palabra1, palabra2) =>{\n    let esAnagrama = false;\n    for (let i = 0; i < palabra1.length; i++) {\n        for(let j = 0; j < palabra2.length; j++) {\n            const check = (palabra1, palabra2) => {\n                (palabra1[i] === palabra2[j]) ? esAnagrama = true : esAnagrama = false;\n            }\n            check(palabra1, palabra2);\n        }\n    }\n    if(esAnagrama === true) {\n        console.log(`${palabra1} y ${palabra2} son anagramas`)\n    } else {\n        console.log(`${palabra1} y ${palabra2} no son anagramas`);\n    }\n}\n\nanagrama('llenaba', 'ballena');\nanagrama('salame', 'melase');\n\n//Isogramas\n\nconst isograma = (palabra1, palabra2) => {\n    const checkLetters = (palabra) => {\n        let letrasVistas = {};\n        for (let i = 0; i < palabra.length; i++){\n            const letra = palabra[i];\n            if(letrasVistas[letra]) {\n                return false;\n            }\n            letrasVistas[letra] = true;\n        }\n        return true;\n    }\n    console.log(checkLetters(palabra1) ? `${palabra1} es un isograma` : `${palabra1} no es un isograma`);\n    console.log(checkLetters(palabra2) ? `${palabra2} es un isograma` : `${palabra2} no es un isograma`);\n}\n\nisograma('Nicolas', 'Nicole');\nisograma('Andres', 'caca');"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/kotlin/AnCarlu.kt",
    "content": "fun cadenas() {\n//Operaciones con cadenas\n\n    val name = \"Adrian\"\n    //Concatenación\n    println(\"Hola mi nombre es $name\")\n\n    //Acceso a caracteres especificos\n    val firstCaracter = name[0]\n    println(\"La primera letra de mi nombre es $firstCaracter\")\n\n    //Longitud de cadenas\n    val lenghtName = name.length\n    println(\"Ni nombre tiene $lenghtName caracteres\")\n\n    //Subcadenas\n    val chain = \"Las subcadenas muestran un conjunto de caracteres acotados\"\n    println(chain)\n    println(\"Por ejemplo ${chain.substring(15, 35)}\")\n\n    //Comparacion de cadenas\n    println(\"Comparación de cadenas:\")\n    println(\"Introduce un nombre\")\n    val newName = readln()\n    if (name == newName) {\n        println(\"Te llamas igual que yo :), ¡Hola tocayo!!\")\n    } else {\n        println(\"Bonito nombre!!\")\n    }\n\n    //Formateo de cadenas\n    val newChain = \"Ejemplo de Formateo de cadenas\"\n    println(newChain)\n    println(\"Se puede modificar todo en mayusculas ${newChain.uppercase()}\")\n    println(\"Y tambien todo en minusculas ${newChain.lowercase()}\")\n    val trimChain = \" Trim sirve para quitar los espacios en blanco tanto al principio como al final \"\n    println(trimChain.trim())\n\n    //Remplazo de cadenas\n    val replaceChain = \"Hola a todos\"\n    println(replaceChain.replace(\"todos\", \"Kotlin\"))\n\n    //Division de cadenas\n    val words = \"Programar es pensar en soluciones\"\n    println(words.split(\" \"))\n\n    //Verificacion\n    println(\"¿Empieza con Hola?\" + words.startsWith(\"Hola\"))\n    println(\"¿Termina en s?\" + words.endsWith(\"s\"))\n    println(\"¿Contiene pensar? ${\"pensar\" in words}\")\n}\n\nfun extraExercise() {\n    println(\"Ahora comprobaremos si 2 palabras son palindromos, anagramas o isogramas\")\n    println(\"Añade la primera palabra\")\n    val word1 = readln()\n    println(\"Añade la segunda palabra\")\n    val word2 = readln()\n    palindromo(word1, word2)\n    anagrama(word1,word2)\n    isograma(word1)\n\n}\n\nfun palindromo(word1: String, word2: String) {\n    //Comparo si la primera palabra es igual a la segunda al reves\n    if (word1.lowercase() == word2.lowercase().reversed()) {\n        println(\"Tus dos palabras son un palindromo\")\n    } else {\n        println(\"Estas palabras no son un palindromo\")\n    }\n}\n\nfun anagrama(word1: String, word2: String): Boolean{\n    //Primero compruebo si tiene la misma cantidad de letras\n    if (word1.length!=word2.length){\n        println(\"Tus palabras no pueden ser un anagrama porque no son de la misma longitud\")\n        return false\n    }\n    //Comparo si todas las letras de las dos palabras son iguales\n    if ( word1.lowercase().toList().sorted()==word2.lowercase().toList().sorted()){\n        println(\"Tus palabras añadidas podrian ser un anagrama\")\n        return true\n    }else{\n        println(\"No es posible que estas palabras sean un anagrama\")\n        return false\n    }\n}\n\nfun isograma(word:String): Boolean{\n    //Compruebo letra a letra la palabra\n    val filterWord = word.lowercase().filter { it.isLetter() }\n    //Si la longitud es la misma significa que no hay ninguna letra repetida, por lo tanto es un isograma\n    if ( filterWord.toSet().size==filterWord.length){\n        println(\"En la primera palabra no se repite ninguna letra\" +\n                \"\\nes un isograma\")\n        return true\n    }else{\n        println(\"Se repite alguna letra\")\n        return false\n    }\n}\n\nfun main() {\n    cadenas()\n    extraExercise()\n}"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/kotlin/Luis-VB.kt",
    "content": "\nimport java.io.File\nimport kotlin.text.lowercase\nimport kotlin.text.uppercase\n\n/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\nopen class LuisRetos {\n\n    fun myStrings() {\n        // String\n        val myString = \"Hola: soy una cadena de texto\"\n        println(myString)\n\n        // Access to specific characters\n        println(\"First character: ${myString[0]}\")\n        println(\"Last character: ${myString[myString.length - 1]}\")\n        println(\"Third character: ${myString.get(2)}\")\n        println(\"Substring from index 5 to 10: ${myString.subSequence(5, 10)}\")\n        println(\"Length of the string: ${myString.length}\")\n\n        // Concatenation\n        val string1 = \"Hello\"\n        val string2 = \"World\"\n        val concatenatedString = string1 + \" \" + string2\n        println(\"Concatenated string: $concatenatedString\")\n\n        // Repetition\n        val repeatedString = \"abc\".repeat(3)\n        println(\"Repeated string: $repeatedString\")\n\n        // Conversion to uppercase and lowercase\n        val uppercaseString = myString.uppercase()\n        val lowercaseString = myString.lowercase()\n        println(\"Uppercase string: $uppercaseString\")\n        println(\"Lowercase string: $lowercaseString\")\n\n        // Replacement\n        val replacedString = myString.replace(\"cadena\", \"frase\")\n        println(\"Replaced string: $replacedString\")\n\n        // Splitting\n        val splitString = myString.split(\":\")\n        println(\"Split string: $splitString\")\n\n        // Joining\n        val joinedString = splitString.joinToString(\"-\")\n        println(\"Joined string: $joinedString\")\n\n        // Interpolation\n        val name = \"Luis\"\n        val age = 30\n        val interpolatedString = \"My name is $name and I am $age years old.\"\n        println(\"Interpolated string: $interpolatedString\")\n\n        // Verification\n        val containsHola = myString.contains(\"Hola\")\n        println(\"Contains 'Hola': $containsHola\")\n        println()\n    }\n\n    fun checkWords(word1: String, word2: String) {\n\n        val reversedWord1 = word1.reversed()\n        val reversedWord2 = word2.reversed()\n        val isPalindrome1 = word1 == reversedWord1\n        val isPalindrome2 = word2 == reversedWord2\n        println(\"Is \\\"$word1\\\" a palindrome? $isPalindrome1\")\n        println(\"Is \\\"$word2\\\" a palindrome? $isPalindrome2\")\n        println()\n\n        val sortedWord1 = word1.toCharArray().sorted().joinToString(\"\")\n        val sortedWord2 = word2.toCharArray().sorted().joinToString(\"\")\n        val isAnagram = sortedWord1 == sortedWord2\n        println(\"Are \\\"$word1\\\" and \\\"$word2\\\" anagrams? $isAnagram\")\n        println()\n        val isIsogram1 = word1.length == word1.toSet().size\n        val isIsogram2 = word2.length == word2.toSet().size\n        println(\"Is \\\"$word1\\\" an isogram? $isIsogram1\")\n        println(\"Is \\\"$word2\\\" an isogram? $isIsogram2\")\n\n    }\n}\n\nfun main() {\n    val retos = LuisRetos()\n    retos.myStrings()\n    retos.checkWords(\"hola\", \"aloh\")\n    retos.checkWords(\"hola\", \"Taco cat\")\n    retos.checkWords(\"eye\", \"madam\")\n    retos.checkWords(\"radar\", \"level\")\n}"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/kotlin/OcandoDev.kt",
    "content": "fun main() {\n\n    var developer = \"Alejandro\"\n    developer += \" Ocando\"\n\n    println(developer)\n\n    //Subcadena\n    val substringDev = developer.substring(10,16)\n    println(substringDev)\n\n    //Busqueda y remplazo\n    val modifiedString = developer.replace(\"Ocando\", \"Enrique\")\n    println(modifiedString)\n\n    //Recorriendo una cadena\n    println(developer[4])\n    println(developer.get(4))\n\n    for(char in developer)\n        print(char)\n\n    println()\n\n    for(index in developer.indices)\n        print(\"${developer[index]} \")\n\n    println()\n\n    println(developer.length)\n\n    println()\n\n    //Formas de concatenacion\n    val repoOwner = \"Brais \" + \"Moure\"\n    println(repoOwner)\n    val mixedDataType = \"Emocion: \" + 100\n    println(mixedDataType)\n    val operation = \"Resultado: \" + (4 + 4)\n    println(operation)\n\n    println()\n\n    val multiLineString = \"\"\"\n        This is\n        a simple\n        way to\n        create\n        a super\n        string\n    \"\"\".trimIndent()\n\n    println(multiLineString)\n\n\n    println()\n\n    //Comparacion de cadenas\n    val isEqual = \"Kotlin\" == \"kotlin\"\n    println(isEqual)\n    val isEqualIgnoreCase = \"Kotlin\".equals(\"kotlin\", ignoreCase = true)\n    println(isEqualIgnoreCase)\n\n    //Trimming una cadena\n    val trimmedString = \"   Kotlin  \"\n    println(trimmedString.trim())\n\n    //Split de cadenas\n    val splittedText = \"Programar es lo mejor!\".split(\" \")\n    println(splittedText)\n\n    //Upper y LowerCase\n    val upper = \"estoy en mayusculas\"\n    println(upper.uppercase())\n\n    val lower = \"ESTOY EN MINUSCULAS\"\n    println(lower.lowercase())\n\n    //Contains\n    println(lower.contains(\"a\"))\n\n    //Parseo de cadenas\n    val favoriteNumber = \"26\"\n    favoriteNumber.toInt()\n    println(favoriteNumber)\n\n    val chars = arrayOf('h','o','l','a')\n    val charsString = String(chars.toCharArray())\n    println(charsString)\n\n    println()\n    //Ejercicios\n\n    val anagramWord1 = \"Secure\"\n    val anagramWord2 = \"Rescue\"\n    println(\"Es $anagramWord1 anagrama de $anagramWord2?: ${isAnagram(anagramWord1, anagramWord2)}\")\n\n    println()\n\n    val palindrome = \"Arepera\"\n    println(\"Es $palindrome un palindromo?: ${isPalindrome(palindrome)}\")\n\n    println()\n\n    val isogram = \"uncopyrightable\"\n    println(\"Es $isogram un isograma?: ${isIsogram(isogram)}\")\n\n}\n\nfun isAnagram(word1: String, word2: String): Boolean{\n    val ordenedWord1 = word1.lowercase().trim().toCharArray().sorted()\n    val ordenedWord2 = word2.lowercase().trim().toCharArray().sorted()\n\n    return ordenedWord1 == ordenedWord2\n}\n\nfun isPalindrome(original: String): Boolean{\n    original.lowercase()\n    var reversed = \"\"\n\n    for(letter in original.trim()){\n        reversed += letter\n    }\n\n    return original == reversed.trim()\n}\n\nfun isIsogram(original: String): Boolean{\n    val manipulatedString = original.lowercase().trim()\n\n    for(i in manipulatedString.indices){\n        for(j in i + 1..<manipulatedString.length){\n            if(manipulatedString[i] == manipulatedString[j]) return false\n        }\n    }\n    return true\n}"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/kotlin/VincentRodriguezR.kt",
    "content": "class strings {\n    fun cadenas(){\n\n        //Ejemplos de operaciones con cadenas de texto\n        val cadena: String = \"Este es un string y exploraremos diferentes operaciones con el, y sus posibilidades\"\n\n        //Operaciones con cadenas\n\n        //Acceso a un caracter en especifico\n        val caracter =  cadena[2]\n        println(\"En este caso tare la letra $caracter ya que es la segunda letra de toda la cadena\")\n\n        //Subcadenas\n        val subCadena = cadena.substring(0,3)\n        println(\"En este caso tare unicamente la cadena $subCadena ya que le indicamos que traiga desde la primera letra que es 0 hasta la cuarta que es 3\")\n\n        //Longitud de la cadena\n        val longitud = cadena.length\n        println(\"La longitud de la cadena es $longitud\")\n\n        //Concatenacion\n        val concatenacion = cadena + \"En este caso se concateno un texto adicional\"\n        println(concatenacion)\n\n        //Repeticion\n        val repeticion = cadena.repeat(3)\n        println(\"En este caso la cadena se repite el numero de veces que le indiquemos, como en este caso fueron 3 veces -> $repeticion\")\n\n        //recorrido de caracteres\n        cadena.forEach{println(\"En este casi se imprimira caracter por caracter de la cadena -> $it\")}\n\n        //Conversion de mayusculas y minusculas\n        val minus = cadena.toLowerCase()\n        val mayus = cadena.toUpperCase()\n        println(\"En este caso se convirtieron a mayusculas y minusculas -> Minus: $minus Mayus: $mayus\")\n\n        //Reemplazo\n        val reemplazo = cadena.replace(\"string\", \"cadena de texto\")\n        println(\"Pra reemplazar primero se debe poner la palabra a reemplazar y luego la nueva -> $reemplazo\")\n\n        //Division en partes\n        val division = cadena.split(\",\")\n        division.forEach{println(\"En este caso la cedena se divide basado en un delimitador, ene ste caso una coma -> $it\")}\n\n        //Union de cadenas\n        val union = division.joinToString(separator = \",\")\n        println(\"Aca unimos nuevamente la cadena que separamos anteriormenet y la unimos con la coma que antes era el delimitador\")\n\n        //Interpolacion\n        println(\"Durante todo el ejercicio hemos aplicado la inetrpolacion, para hacerlo mas explicito aca interpolaremos la cadena inicial colocando el signo $ y el nombre de la variable -> $cadena\")\n\n        //verificacion de contenido\n        val contiene = cadena.contains(\"string\")\n        val empiezaCon = cadena.startsWith(\"Este\")\n        val terminaCon = cadena.endsWith(\"posibilidades\")\n        println(\"En este caso se usan las funciones, contains, startsWith y endsWith, las cuales devuelven un valor booleano\")\n\n        //Eliminar espacios\n        val noEspacios = cadena.trim()\n        println(\"En este caso se eliminan los espacios de la cadena -> $noEspacios\")\n\n        //Punto Extra -> comprobador de cadenas\n\n        //Begin\n        println(\"Digita la primera palabra que vas a evaluar\")\n        val word1: String? = readLine()\n        println(\"Digita la segunda palabra que vas a evaluar\")\n        val word2 = readLine()\n\n        //Palindrome validation\n        fun palindrome(word: String?){\n            var counter: Int = 0\n            var reverseWord: Int = 1\n            for(i in word!!){\n                for(j in word.length -reverseWord downTo 0){\n                    val value = word[j]\n                    if(i == value){\n                        counter++\n                        reverseWord++\n                    }\n                    break\n                }\n            }\n            if(counter == word.length){\n                println(\"La palabra $word es un palindromo\")\n            }else{\n                println(\"La palabra $word no es un palindromo\")\n            }\n        }\n\n        //Anagram validation\n        fun anagram(word1: String?, word2: String?){\n            var counter: Int = 0\n            if(word1!!.length == word2!!.length){\n                val word1List = word1!!.toList()\n                val word2List = word2!!.toList()\n                for(i in word1.indices){\n                    if(word1List.sorted()[i] == word2List.sorted()[i])\n                        counter++\n                }\n                if(counter == word1.length){\n                    println(\"Las palabras $word1 y $word2 forman un anagrama\")\n                }else{\n                    println(\"Las palabras $word1 y $word2 no forman un anagrama\")\n                }\n            }else{\n                println(\"Las palabras no conforman un anagrama\")\n            }\n\n        }\n\n        //Isogram validation\n        fun isogram(word: String?){\n            var sum = 0\n            var index = 0\n            var unique = word!!.toList().distinct().joinToString(\"\")\n            var counter: MutableMap<Char, Int> = mutableMapOf()\n            var iterator: Int = 0\n            for(i in unique!!){\n                counter.put(i, 0)\n            }\n            for(i in counter.keys){\n                for(j in word){\n                    if(i == j){\n                        index++\n                    }\n                    counter[i] = index\n                }\n                index = 0\n            }\n            val values: List<Int> = counter.values.toList().distinct()\n            if(values.size > 1){\n                println(\"la palabra $word no es un isograma\")\n            }else{\n                println(\"la palabra $word es un isograma\")\n            }\n        }\n\n        //Executions\n        palindrome(word1)\n        palindrome(word2)\n        anagram(word1,  word2)\n        isogram(word1)\n        isogram(word2)\n\n    }\n    companion object {\n        @JvmStatic\n        fun main(args: Array<String>) {\n            val obj = strings()\n            obj.cadenas()\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/kotlin/adridoce.kt",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\n fun main() {\n    strings()\n }\n\n fun strings() {\n    val cadena: String = \"Hola Kotlin!\"\n    val cadena2: String = \"Hola Python!\"\n    \n/* --- Propiedades --- */\n\n    // longitud: Se llama a length sin usar () porque es una propiedad de la cadena y no un metodo.\n    println(\"La longitud de la cadena es: ${cadena.lenght}\")\n\n\n/* --- Functions --- */\n\n    // compareTo(): Devuelve 0 si las dos cadenas son iguales, <0 si es menor que la cadena recibida y >0 si es mayor \n    println(cadena.compareTo(cadena2))\n    println(cadena2.compareTo(cadena))\n\n    // equals(): Compara si dos objetos son iguales, devuelve booleano\n    if (cadena.equals(cadena2)) println(\"Las cadenas coinciden\") else println(\"Las cadenas no coinciden\")\n\n    // get(): Devuelve el caracter en la posicion indicado\n    println(cadena.get(5))\n\n    // hashCode(): Devuelve el hashCode del objeto\n    println(cadena.hashCode())\n\n    // plus(): Devuelve un string resultado de la concatenacion de ambos objetos\n    println(cadena.plus(cadena2))\n\n    // SubSequence(): devuelve una secuencia de caracteres más genérica\n    println(cadena.subSequence(0,4))\n\n    /* --- Propiedades de extensión --- */\n    // indices: Devuelve el rango de índices de caracteres válidos para esta secuencia de caracteres.\n    println(cadena2.indices)\n\n    // lastIndex: Devuelve el índice del último carácter de la secuencia de caracteres o -1 si está vacío.\n    println(cadena2.lastIndex)\n\n\n/* --- Funciones de extension --- */\n\n    // substring() devuelve una nueva cadena específica \n    println(cadena.substring(0,4))\n    println(cadena.substring(5, 11))\n\n    // contains(): Devuelve true si la secuencia de caracteres contiene la  secuencia de caracteres especificada como subcadena.\n    if (cadena.contains(\"Kot\")) println(\"Subcadena encontrada\") else println(\"Subcadena no encontrada\")\n    if (cadena.contains(\"aaa\")) println(\"Subcadena encontrada\") else println(\"Subcadena no encontrada\")\n\n    // count(): Devuelve la longitud de la secuencia de caracteres.\n    println(cadena2.count())\n\n    // drop(): Devuelve un string con los primeros n caracteres eliminados\n    println(cadena.drop(5))\n\n    // dropLast(): Devuelve un string con los ultimos n caracteres eliminados\n    println(cadena.dropLast(5))\n\n    // filter(): Devuelve una cadena que contiene sólo aquellos caracteres de la cadena original que coinciden con el predicado dado.\n    val palabras = listOf(\"Hola\", \"Adiós\", \"Gato\", \"Perro\", \"Ratón\")\n    val palabrasConA = palabras.filter { palabra -> 'a' in palabra.toLowerCase() }\n\n    println(\"Palabras originales: $palabras\")\n    println(\"Palabras que contienen 'a': $palabrasConA\")\n\n    // format()\n    val integerNumber = String.format(\"%07d\", 31416)\n\tprintln(integerNumber)\n\n\tval floatNumber = String.format(\"%+.4f\", 3.141592)\n\tprintln(floatNumber)\n\n\tval helloString = String.format(\"%S %S\", \"hello\", \"world\")\n\tprintln(helloString)\n\n    //split()\n    println(cadena.split(\"\"))\n\n    // Conversion a mayusculas y minusculas\n    println(cadena.uppercase())\n    println(cadena.lowercase())\n\n    esPalindromo(\"anilina\")\n    esPalindromo(\"El perro de san roque no tiene rabo\")\n    esAnagrama(\"roma\", \"amor\")\n    esAnagrama(\"palabra\", \"arbol\")\n    esIsograma(\"murcielago\")\n    esIsograma(\"escritura\")\n }\n\n fun esPalindromo(texto: String) {\n    /* \n        Palabra o frase cuyas letras están dispuestas de tal manera que resulta \n        la misma leída de izquierda a derecha que de derecha a izquierda\n    */\n\n    val textoSinEspacios = texto.replace(\"\\\\s\".toRegex(), \"\")\n    val longitud = textoSinEspacios.length\n\n    for (i in 0 .. longitud / 2) {\n        if (textoSinEspacios[i] != textoSinEspacios[longitud - 1 - i]) {\n            println(\"La cadena NO es un Palindromo\")\n            return\n        }\n    }\n\n    println(\"La cadena SI es un Palindromo\")\n }\n\n fun esAnagrama(texto1: String, texto2: String) {\n    /*  \n        una palabra es anagrama de otra si las dos tienen las mismas letras, \n        con el mismo número de apariciones, pero en un orden diferente.   \n    */\n\n    val texto1Array = texto1.toCharArray().sortedArray()\n    val texto2Array = texto2.toCharArray().sortedArray()\n\n    if (texto1Array.contentEquals(texto2Array)) {\n        println(\"La cadena SI es un Anagrama\")\n    }\n    else {\n        println(\"La cadena NO es un Anagrama\")\n    }\n }\n\n fun esIsograma(texto: String) {\n    /*\n        Un isograma es una palabra o frase en la cual no hay letras o caracteres repetidos. \n        En otras palabras, cada letra o caracter en un isograma aparece exactamente una vez. \n    */\n    val textoEnMinusculas = texto.lowercase()\n    val conjuntoDeCaracteres = textoEnMinusculas.toCharArray().toSet()\n\n    if (conjuntoDeCaracteres.size == textoEnMinusculas.length) {\n        println(\"La cadena SI es un Isograma\")\n    }\n    else {\n        println(\"La cadena NO es un Isograma\")\n    }\n    \n }"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/kotlin/blackriper.kt",
    "content": "\r\nfun operationsWithStrings(){\r\n val villain=\"freezer\"\r\n\r\n  // substring\r\n  println(villain.substring(0,3))\r\n  // length\r\n  println(villain.length)\r\n  // uppercase\r\n  println(villain.uppercase())\r\n  // lowercase\r\n  println(villain.lowercase())\r\n  // repeat\r\n  println(villain.repeat(3))\r\n  // trim\r\n  println(villain.trim())\r\n  //replace\r\n  println(villain.replace(\"free\",\"\"))\r\n  // interpolation\r\n  println(\"$villain use kienzan technique\")\r\n // union\r\n val example=\"$villain use kienzan technique\"\r\n println(example +\"and Goku use kamehameha\")\r\n // verify\r\n println(villain.startsWith(\"free\"))\r\n println(villain.endsWith(\"zer\"))\r\n // split\r\n println(villain.split(\"e\"))\r\n // compare\r\n println(villain.compareTo(\"cell\"))\r\n// reversed\r\n println(villain.reversed())\r\n\r\n}\r\n\r\nfun isAnagram(str1: String, str2: String): Boolean {\r\n    val array1=str1.uppercase().toCharArray()\r\n    val array2=str2.uppercase().toCharArray()\r\n    array1.sort()\r\n    array2.sort()\r\n    return array1.contentEquals(array2)\r\n}\r\n\r\nfun isIsogram(word: String): Boolean {\r\n    if (word.length == 1) return true // las letras individuales son un isogram\r\n\r\n    val charCounts = IntArray(26) // Crear un arrgle de 26 enteros\r\n\r\n    // hacer un ciclo para contar los caracteres\r\n    for (char in word) {\r\n        charCounts[char - 'a']++ // Increment the count for that character\r\n       }\r\n\r\n    // checar si los cacteres contados son mas de uno\r\n    for (count in charCounts) {\r\n        if (count > 1) return false // si count es mayor que 1, no es un isogram\r\n    }\r\n\r\n    return true //  si todos los caracteres contados son 1 o cero, es un isogram\r\n}\r\n\r\n\r\nfun analyzingWord(word:String,word2:String=\"\"){\r\n    when {\r\n      word.uppercase().reversed() == word2.uppercase() -> println(\"palindrome\")\r\n      isAnagram(word,word2) -> println(\"anagram\")\r\n      isIsogram(word) -> println(\"isogram\")\r\n      else-> println(\"not category\")\r\n    }\r\n}\r\n\r\n\r\nfun main() {\r\n    operationsWithStrings()\r\n    analyzingWord(\"Anna\",\"anna\")\r\n    analyzingWord(\"Nacionalista\",\"Altisonancia\")\r\n    analyzingWord(\"murcielago\")\r\n}"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/kotlin/deivitdev.kt",
    "content": "fun main() {\n    // String operations\n    val str = \"Hello, World!\"\n    println(\"Access specific character: ${str[1]}\") // Access specific character\n    println(\"Substring: ${str.substring(0, 5)}\") // Substring\n    println(\"Length: ${str.length}\") // Length\n    println(\"Concatenation: ${str + \" How are you?\"}\") // Concatenation\n    println(\"Repetition: ${str.repeat(2)}\") // Repetition\n    println(\"Uppercase: ${str.uppercase()}\") // Uppercase\n    println(\"Lowercase: ${str.lowercase()}\") // Lowercase\n    println(\"Replace: ${str.replace(\"World\", \"Kotlin\")}\") // Replace\n    println(\"Split: ${str.split(\", \")}\") // Split\n    println(\"Join: ${listOf(\"Hello\", \"World\").joinToString(\", \")}\") // Join\n    println(\"Interpolation: ${\"The length of the string is ${str.length}\"}\") // Interpolation\n    println(\"Contains: ${str.contains(\"World\")}\") // Contains\n\n    // Check if two words are palindromes, anagrams, or isograms\n    val word1 = \"roma\"\n    val word2 = \"amor\"\n    println(\"Is '$word1' a palindrome? ${isPalindrome(word1)}\")\n    println(\"Are '$word1' and '$word2' anagrams? ${areAnagrams(word1, word2)}\")\n    println(\"Is '$word1' an isogram? ${isIsogram(word1)}\")\n}\n\nfun isPalindrome(word: String): Boolean = word == word.reversed()\n\nfun areAnagrams(word1: String, word2: String): Boolean = word1.toCharArray().sorted() == word2.toCharArray().sorted()\n\nfun isIsogram(word: String): Boolean = word.length == word.toSet().size"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/kotlin/didacdev.kt",
    "content": "fun main() {\n\n    // Concatenación\n    var hello = \"hello\"\n    var world = \" world\"\n\n    println(hello + world)\n\n    // Iterar\n    val animals = \"🐶🐵🐻\"\n\n    for (animal in animals) {\n        print(\"$animal\")\n    }\n\n    // Construcción a partir de caracteres\n    val characters = arrayOf('H', 'e', 'l', 'l', 'o')\n    val string = String(characters.toCharArray())\n    println(\"\\n$string\")\n\n    // Interpolación\n    val name = \"Diego\"\n    val message = \"Su nombre es $name\"\n    println(message)\n\n    // Unicode\n    val character = \"\\u1F425\"\n    println(character)\n\n    // Tamaño de la cadena\n    val word = \"esternocleidomastoideo\"\n    println(word.length)\n\n    // Obtener un caracter\n    val saludo = \"hello world\"\n    println(saludo[2])\n\n    // Insertar\n    hello = hello.substring(0, 5) + \"!\"\n    println(hello)\n\n    // Eliminar\n    hello = hello.replace(\"!\", \"\")\n    println(hello)\n\n    // Subcadenas\n    hello = saludo.substring(0, 5)\n    println(hello)\n\n    // Comparar\n    val sameHello = \"hello\"\n\n    if (hello == sameHello) {\n        println(\"$hello y $sameHello son iguales\")\n    }\n\n    // Repetición\n    val doubleHello = hello.repeat(2)\n    println(doubleHello)\n\n    // Conversión mayúsculas\n    val mayusHello = hello.toUpperCase()\n    println(mayusHello)\n\n    // Conversión minúsculas\n    val minusHello = mayusHello.toLowerCase()\n    println(minusHello)\n\n    // Reemplazar caracter\n    val helloDos = hello.replace('h', 'H')\n    println(helloDos)\n\n    // División\n    val sentence = \"hello world\"\n    val words = sentence.split(\" \")\n    println(words)\n\n    // Verificación\n    if (helloDos.contains('H')) {\n        println(\"Contiene H\")\n    }\n\n    checkWords(\"lacteo\", \"coleta\")\n}\n\n// --------------- Ejercicio -----------------\n\nfun checkWords(word1: String, word2: String) {\n    if (isPalindromo(word1, word2)) {\n        println(\"$word1 y $word2 son palíndromos\")\n    } else {\n        println(\"$word1 y $word2 no son palíndromos\")\n    }\n\n    if (isAnagrama(word1, word2)) {\n        println(\"$word1 y $word2 son anagramas\")\n    } else {\n        println(\"$word1 y $word2 no son anagramas\")\n    }\n\n    if (isIsograma(word1)) {\n        println(\"$word1 es un isograma\")\n    } else {\n        println(\"$word1 no es un isograma\")\n    }\n\n    if (isIsograma(word2)) {\n        println(\"$word2 es un isograma\")\n    } else {\n        println(\"$word2 no es un isograma\")\n    }\n}\n\nfun isPalindromo(word1: String, word2: String): Boolean {\n    val reversedWord2 = word2.reversed()\n\n    if (word1.length == word2.length) {\n\n        for (i in word1.indices) {\n            val character1 = word1[i]\n            val character2 = reversedWord2[i]\n\n            if (character1 != character2) {\n                return false\n            }\n        }\n\n        return true\n    }\n\n    return false\n}\n\nfun isAnagrama(word1: String, word2: String): Boolean {\n    var word1Array = word1.toCharArray()\n    var word2Array = word2.toCharArray()\n\n    word1Array.sort()\n    word2Array.sort()\n\n    return word1Array.contentEquals(word2Array)\n}\n\nfun isIsograma(word: String): Boolean {\n    var characters = mutableMapOf<String, Int>()\n    var i = 0   \n\n    for (character in word) {\n\n        characters[character.toString()] = if (characters[character.toString()] != null) characters.getOrDefault(character.toString(), 0) + 1 else 1\n    }\n\n    for ((key, value) in characters) {\n\n        if (i == 0) {\n            i = value\n        } else {\n            if (i != value) {\n                return false\n            }\n        }\n    }\n\n    return true\n}\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/kotlin/eulogioep.kt",
    "content": "fun main() {\n    // Ejemplos de operaciones con cadenas\n    val cadena = \"Hola, Mundo!\"\n    \n    // Acceso a caracteres específicos\n    println(\"Primer carácter: ${cadena[0]}\")\n    println(\"Último carácter: ${cadena[cadena.length - 1]}\")\n\n    // Subcadenas\n    println(\"Subcadena (3, 7): ${cadena.substring(3, 7)}\")\n\n    // Longitud\n    println(\"Longitud: ${cadena.length}\")\n\n    // Concatenación\n    val otraCadena = \" Bienvenido\"\n    println(\"Concatenación: ${cadena + otraCadena}\")\n\n    // Repetición\n    println(\"Repetición: ${\"Hola\".repeat(3)}\")\n\n    // Recorrido\n    print(\"Recorrido: \")\n    for (char in cadena) {\n        print(\"$char \")\n    }\n    println()\n\n    // Conversión a mayúsculas y minúsculas\n    println(\"Mayúsculas: ${cadena.uppercase()}\")\n    println(\"Minúsculas: ${cadena.lowercase()}\")\n\n    // Reemplazo\n    println(\"Reemplazo: ${cadena.replace(\"Mundo\", \"Kotlin\")}\")\n\n    // División\n    val palabras = cadena.split(\", \")\n    println(\"División: $palabras\")\n\n    // Unión\n    println(\"Unión: ${palabras.joinToString(\" - \")}\")\n\n    // Interpolación\n    val nombre = \"Alice\"\n    println(\"Interpolación: Hola, $nombre!\")\n\n    // Verificación\n    println(\"¿Empieza con 'Hola'?: ${cadena.startsWith(\"Hola\")}\")\n    println(\"¿Termina con '!'?: ${cadena.endsWith(\"!\")}\")\n    println(\"¿Contiene 'Mundo'?: ${\"Mundo\" in cadena}\")\n\n    // DIFICULTAD EXTRA\n    println(\"\\nDIFICULTAD EXTRA:\")\n    val palabra1 = \"reconocer\"\n    val palabra2 = \"ceronorec\"\n    \n    println(\"'$palabra1' es palíndromo: ${esPalindromo(palabra1)}\")\n    println(\"'$palabra2' es palíndromo: ${esPalindromo(palabra2)}\")\n    println(\"'$palabra1' y '$palabra2' son anagramas: ${sonAnagramas(palabra1, palabra2)}\")\n    println(\"'$palabra1' es isograma: ${esIsograma(palabra1)}\")\n    println(\"'$palabra2' es isograma: ${esIsograma(palabra2)}\")\n}\n\nfun esPalindromo(palabra: String): Boolean {\n    val palabraLimpia = palabra.lowercase().filter { it.isLetter() }\n    return palabraLimpia == palabraLimpia.reversed()\n}\n\nfun sonAnagramas(palabra1: String, palabra2: String): Boolean {\n    if (palabra1.length != palabra2.length) return false\n    return palabra1.lowercase().toList().sorted() == palabra2.lowercase().toList().sorted()\n}\n\nfun esIsograma(palabra: String): Boolean {\n    val letrasUnicas = mutableSetOf<Char>()\n    for (letra in palabra.lowercase()) {\n        if (letra in letrasUnicas) return false\n        letrasUnicas.add(letra)\n    }\n    return true\n}"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/kotlin/isaacus98.kt",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\n *   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\n *   interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\nfun main() {\n    var str1: String = \"Hola\"\n    var str2: String = \"Mundo\"\n\n    // Acceso a un caracter especifico\n    println(str1[1])\n    println(str1.get(1))\n\n    // Substring\n    str1 = \"Esto es una string\"\n    println(str1.substring(12))\n    println(str1.substring(0, 4))\n\n    // Longitud de la string\n    println(str1.length)\n\n    // Concatenación\n    str1 = \"Hola \"\n    println(str1.plus(str2))\n\n    // Repeticion\n    str1 = \"a\"\n    println(str1.repeat(5))\n\n    // Añadir valor tanto al inicio o al final si no cumple una longitud minina.\n    str1 = \"Hola\"\n    println(str1.padEnd(8,'!'))\n    println(str1.padStart(8,'!'))\n\n    // Mayusculas, minusculas\n    println(str1)\n    println(str1.uppercase())\n    println(str1.lowercase())\n\n    // Reemplazo\n    str1 = \"hola mundo\"\n    println(str1.replace('o', '?'))\n\n    // División\n    val palabras: List<String> = str1.split(' ')\n    println(palabras.toString())\n\n    // Verificación\n    println(str1.contains(\"hola\"))\n\n    // Trim\n    str1 = \"    hola    \"\n    println(str1.trim())\n\n    // recorrido\n    str1 = \"abcdefg\"\n    for (i in str1){\n        println(i)\n    }\n\n    // Interpolación\n    str1 = \"interpolación\"\n    println(\"Esto es una prueba de $str1\")\n\n    // Reto extra\n    println(analizarPalabra(\"rayar\", \"rayar\"))\n    println(analizarPalabra(\"cava\", \"vaca\"))\n    println(analizarPalabra(\"prueba\", \"\"))\n}\n\nfun analizarPalabra(str1: String, str2: String): String {\n    if (esPalindromo(str1, str2))\n        return \"$str1 es un palindromo\"\n\n    if (esAnagrama(str1, str2))\n        return \"$str2 es un anagrama de $str1\"\n\n    if (esIsograma(str1))\n        return  \"$str1 es un isograma\"\n\n    return \"$str1 no es ni un palindromo, anagrama o isograma\"\n}\n\nfun esPalindromo(str1: String, str2: String): Boolean {\n    return when (str1){\n        str2.reversed() -> true\n        else -> false\n    }\n}\n\nfun esAnagrama(str1: String, str2: String): Boolean {\n\n    if (str1.length != str2.length)\n        return false\n\n    var palabra1: CharArray = str1.toCharArray()\n    var palabra2: CharArray = str2.toCharArray()\n\n    palabra1.sort()\n    palabra2.sort()\n\n    for (i in palabra1.indices){\n        if (palabra1[i] != palabra2[i]){\n            return false\n        }\n    }\n\n    return true\n}\n\nfun esIsograma(str1: String): Boolean{\n    var palabra = str1.toCharArray()\n    palabra.sort()\n\n    var letras: String = \"\"\n\n    for (i in palabra.indices){\n        if (letras.contains(palabra[i])){\n            return false\n        } else {\n            letras += palabra[i]\n        }\n    }\n\n    return true\n}"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/kotlin/juanppdev.kt",
    "content": "fun main() {\n    // Definir una cadena de caracteres\n    val cadena = \"Hola, mundo!\"\n\n    // Acceso a caracteres específicos\n    val primerCaracter = cadena[0]\n    val ultimoCaracter = cadena[cadena.length - 1]\n\n    println(\"Acceso a caracteres:\")\n    println(\"Primer caracter: $primerCaracter\")\n    println(\"Último caracter: $ultimoCaracter\")\n\n    // Subcadenas\n    val subcadena = cadena.substring(0, 4)\n    println(\"\\nSubcadena:\")\n    println(\"Subcadena de los primeros 4 caracteres: $subcadena\")\n\n    // Longitud de la cadena\n    val longitud = cadena.length\n    println(\"\\nLongitud de la cadena:\")\n    println(\"Longitud de la cadena: $longitud\")\n\n    // Concatenación\n    val otraCadena = \" ¡Kotlin es genial!\"\n    val cadenaConcatenada = cadena + otraCadena\n    println(\"\\nConcatenación:\")\n    println(\"Cadena concatenada: $cadenaConcatenada\")\n\n    // Repetición\n    val cadenaRepetida = cadena.repeat(3)\n    println(\"\\nRepetición:\")\n    println(\"Cadena repetida 3 veces: $cadenaRepetida\")\n\n    // Recorrido\n    println(\"\\nRecorrido:\")\n    for (caracter in cadena) {\n        print(\"$caracter \")\n    }\n\n    // Conversión a mayúsculas y minúsculas\n    println(\"\\n\\nConversión a mayúsculas y minúsculas:\")\n    val mayusculas = cadena.toUpperCase()\n    val minusculas = cadena.toLowerCase()\n    println(\"Mayúsculas: $mayusculas\")\n    println(\"Minúsculas: $minusculas\")\n\n    // Reemplazo\n    val cadenaReemplazada = cadena.replace(\"mundo\", \"Kotlin\")\n    println(\"\\nReemplazo:\")\n    println(\"Cadena con reemplazo: $cadenaReemplazada\")\n\n    // División\n    val palabras = cadena.split(\",\")\n    println(\"\\nDivisión:\")\n    println(\"Cadena dividida por coma: $palabras\")\n\n    // Unión\n    val nuevaCadena = palabras.joinToString(\"-\")\n    println(\"\\nUnión:\")\n    println(\"Palabras unidas por guión: $nuevaCadena\")\n\n    // Interpolación\n    val nombre = \"Juan\"\n    val edad = 25\n    val mensaje = \"Hola, me llamo $nombre y tengo $edad años.\"\n    println(\"\\nInterpolación:\")\n    println(\"Mensaje interpolado: $mensaje\")\n\n    // Verificación\n    val esDigito = cadena.all { it.isDigit() }\n    println(\"\\nVerificación:\")\n    println(\"¿La cadena contiene solo dígitos?: $esDigito\")\n}\n\n// Ejercicio Extra\nfun main() {\n    // Ingresa las dos palabras que deseas analizar\n    print(\"Ingresa la primera palabra: \")\n    val palabra1 = readLine()!!.toLowerCase()\n\n    print(\"Ingresa la segunda palabra: \")\n    val palabra2 = readLine()!!.toLowerCase()\n\n    // Comprobación de palíndromo\n    val esPalindromo1 = esPalindromo(palabra1)\n    val esPalindromo2 = esPalindromo(palabra2)\n\n    // Comprobación de anagrama\n    val esAnagrama = esAnagrama(palabra1, palabra2)\n\n    // Comprobación de isograma\n    val esIsograma1 = esIsograma(palabra1)\n    val esIsograma2 = esIsograma(palabra2)\n\n    // Mostrar resultados\n    println(\"\\nResultados:\")\n    println(\"Palabra 1 es palíndromo: $esPalindromo1\")\n    println(\"Palabra 2 es palíndromo: $esPalindromo2\")\n    println(\"Son anagramas: $esAnagrama\")\n    println(\"Palabra 1 es isograma: $esIsograma1\")\n    println(\"Palabra 2 es isograma: $esIsograma2\")\n}\n\nfun esPalindromo(palabra: String): Boolean {\n    val reversa = palabra.reversed()\n    return palabra == reversa\n}\n\nfun esAnagrama(palabra1: String, palabra2: String): Boolean {\n    return palabra1.toCharArray().sorted() == palabra2.toCharArray().sorted()\n}\n\nfun esIsograma(palabra: String): Boolean {\n    val setDeCaracteres = HashSet<Char>()\n    for (caracter in palabra) {\n        if (!setDeCaracteres.add(caracter)) {\n            return false // Si se encuentra un carácter repetido, no es un isograma\n        }\n    }\n    return true\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/kotlin/miguelex.kt",
    "content": "fun isPalindromo(cadena: String): Boolean {\n    var cadenaLimpia = cadena.replace(\" \", \"\").toLowerCase()\n    var cadenaInvertida = cadenaLimpia.reversed()\n    return cadenaLimpia == cadenaInvertida\n}\n\nfun isAnagrama(cadena1: String, cadena2: String): Boolean {\n    var cadena1Limpia = cadena1.replace(\" \", \"\").toLowerCase()\n    var cadena2Limpia = cadena2.replace(\" \", \"\").toLowerCase()\n    return cadena1Limpia.toCharArray().sorted() == cadena2Limpia.toCharArray().sorted()\n}\n\nfun isIsograma(cadena: String): Boolean {\n    var cadenaLimpia = cadena.replace(\" \", \"\").toLowerCase()\n    return cadenaLimpia.toCharArray().distinct().size == cadenaLimpia.length\n}\n\nfun main() {\n    var cadena = \"Hola Mundo\"\n\n    println(cadena);\n\n    // Concatenar\n\n    var nombre = \"Miguel\"\n\n    println(\"Hola \" + nombre)\n\n    // Interpolación de cadenas\n\n    println(\"Hola $nombre\")\n\n    // Mayuscula\n\n    println(nombre.toUpperCase())\n\n    // Minuscula\n\n    println(nombre.toLowerCase())\n\n    // Longitud\n\n    println(nombre.length)\n\n    // Comparar cadenas\n\n    var nombre2 = \"Miguel\"\n\n    println(nombre == nombre2)\n\n    // Subcadena\n\n    println(nombre.substring(0, 3))\n\n    // Reemplazar\n\n    println(nombre.replace(\"M\", \"L\"))\n\n    // Buscar\n\n    println(nombre.indexOf(\"g\"))\n\n    // Recorrer cadena\n\n    for (letra in nombre) {\n        println(letra)\n    }\n\n    // trim\n\n    var nombre3 = \" Miguel \"\n    println(nombre3.trim())\n\n    println(\"Ana es palindromo: \" + isPalindromo(\"Ana\"))\n    println(\"Miguel es palindromo: \" + isPalindromo(\"Miguel\"))\n\n    println(\"Amor y Roma son anagramas: \" + isAnagrama(\"Amor\", \"Roma\"))\n    println(\"Hola y Adios son anagramas: \" + isAnagrama(\"Hola\", \"Adios\"))\n\n    println(\"Murcielago es isograma: \" + isIsograma(\"Murcielago\"))\n    println(\"Miguelex es isograma: \" + isIsograma(\"Miguelex\"))\n}"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/kotlin/pedroomar23.kt",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\n // Cadena de Caracteres \n val myString = \"Hola Mundo\"\n\n // Longitud \n println(myString.length)\n\n // Concatenacion\n println(\"My Name\" + myString)\n\n // Interpolacion \n println(\"Kotlin usa $myString\")\n\n // Mayuscula \n println(myString.toUpperCase())\n\n // Minuscula \n println(myString.toLowerCase())\n\n // SubCadenas \n println(myString.substring(0, 2))\n\n // Reemplazar\n println(myString.remplace(\"H\", \"M\"))\n\n // Recorrido \n for (i in myString) {\n    print(i)\n }\n\n \n\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/kotlin/rikmij.kt",
    "content": "fun ejercicioExtra(){\n    print(\"Escoge la primera palabra para comprobar: \")\n    val word1 = readln()\n    print(\"Escoge la segunda palabra para comprobar: \")\n    val word2 = readln()\n\n    fun isPalindromo(word: String): String {\n        //palíndromo: se lee igual al derecho que al revés\n        return if (word == word.reversed()){\n            (\"Es un palíndromo\")\n        }else{\n            (\"No es un palíndromo\")\n        }\n    }\n\n    fun isAnagrama(word1: String, word2: String): String {\n        //anagrama: cambian de orden las letras de una palabra para formar otra\n        val list1 = mutableListOf<Char>()\n        val list2 = mutableListOf<Char>()\n\n        for (letter in word1.lowercase()){\n            list1.add(letter)\n            list1.sort()\n        }\n        for (letter2 in word2.lowercase()){\n            list2.add(letter2)\n            list2.sort()\n        }\n        return if (list1 == list2){\n            \"Estas 2 palabras son anagramas\"\n        }else{\n            \"Estas 2 palabras no son anagramas\"\n        }\n    }\n\n    fun isIsograma(word: String): String {\n        //isograma: palabra o frase que cada letra aparece el mismo número de veces\n        val letters = mutableMapOf<Char, Int>()\n\n        for (letter in word){\n            if (letter in letters){\n                letters[letter] = letters[letter]!! + 1\n            }else{\n                letters[letter] = 1\n            }\n        }\n\n        val setCounter = letters.values.toSet()\n\n        if (setCounter.size == 1){\n            return \"Es un isograma\"\n        }else{\n            val repeatedChars = mutableListOf<Char>()\n\n            for ((key, value) in letters){\n                if (value >= 2){\n                    repeatedChars.add(key)\n                }\n            }\n            return \"No es un isograma. Se repiten las letras: $repeatedChars\"\n        }\n    }\n\n    println(\"Palabra 1: \" + isPalindromo(word1))\n    println(\"Palabra 2: \" + isPalindromo(word2))\n    println(\"Las palabras elegidas \" + isAnagrama(word1, word2))\n    println(\"Palabra 1: \" + isIsograma(word1))\n    println(\"Palabra 2: \" + isIsograma(word2))\n}\n\n\nfun main() {\n    val stringEjemplo = \"Este es el string de ejemplo\"\n    println(stringEjemplo)\n\n    println(\"\\n\\t-> Acceso a caracteres específicos:\")\n    println(\"En la posición ${stringEjemplo.indexOf(\"s el\")} se encuentra el caracter ${stringEjemplo[6]}\")\n\n    println(\"\\n\\t-> Subcadenas\")\n    print(\"Acceso a una subcadena: \")\n    println(\"\\t\" + stringEjemplo.substring(3,13))\n    print(\"Está \\\"X\\\" en una cadena: \")\n    println(\"\\t ejemplo\" in stringEjemplo)\n\n    println(\"\\n\\t-> Longitud:\")\n    println(\"${stringEjemplo.length} caracteres\")\n\n    println(\"\\n\\t-> Concatenación\")\n    println(stringEjemplo + \"y este es un añadido\")\n    val string2 = \", soy el string 2 añadido\"\n    println(stringEjemplo + string2)\n\n    println(\"\\n\\t-> Repetición\")\n    println(stringEjemplo.repeat(2))\n\n    println(\"\\n\\t-> Recorrido\")\n    for (elem in stringEjemplo){\n        println(elem)\n    }\n    for (elem in stringEjemplo.split(\" \")){\n        println(elem)\n    }\n\n    println(\"\\n\\t-> Mayúsculas y minúsculas\")\n    println(stringEjemplo.uppercase())\n    println(stringEjemplo.replaceFirstChar { it.uppercaseChar() })\n            //también serviría .capitalize(), pero parece estar 'deprecated' y aparece tachado aunque funcione\n    println(stringEjemplo.lowercase())\n\n    println(\"\\n\\t-> Reemplazo\")\n    val wordsEjemplo = stringEjemplo.split(\" \").toMutableList()\n    wordsEjemplo[1] = \"no es\"\n    val wordsUnit = wordsEjemplo.joinToString(\" \")\n    println(wordsUnit)\n\n    println(\"\\n\\t-> División\")\n    println(stringEjemplo.split(\" \"))\n\n    println(\"\\n\\t-> Interpolación\")\n    println(\"Recordemos que la cadena principal es: $stringEjemplo\")\n\n    println(\"\\n\\t-> Verificación\")\n    if (stringEjemplo is String){\n        println(\"Es un string\")\n    }else{\n        println(\"No es un string\")\n    }\n\n    println(\"\\n\\t-> Pertenencia\")\n    println(\"ejemplo\" in stringEjemplo)\n    println(\"mondongo\" in stringEjemplo)\n\n\n    println(\"\\n\" + \"~\".repeat(9) + \" EJERCICIO EXTRA \" + \"~\".repeat(9))\n    ejercicioExtra()\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/kotlin/traver79.kt",
    "content": "fun main() {\n\n    /*\n    EJERCICIO:\n    * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n    * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n    * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n    *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n    *\n    */\n\n    var miCadena: String = \"Hola esto es una cadena\"\n    var miCadena2: String = \"Esto es otra cadena\"\n\n    // Acceso a caracteres específicos\n    println(\"ACCEDER a caracteries especificos\")\n    val Caracter = miCadena[2]\n    println(\"El segundo caracter empezando por 0 de '$miCadena' es $Caracter\")\n\n    // Subcadenas\n    println(\"CREAR SUBCADENAS:\")\n    val subcadena = miCadena2.slice(0..3)\n    println(subcadena)\n\n    val subcadena1 = miCadena2.substring(0, 7)\n    println(subcadena1)\n\n    // Longitud\n    println(\"INDICAR LA LONGITUD TOTAL DE LAS CADENA:\")\n    println(\"La longitud de '$miCadena' es ${miCadena.length} caracteres\")\n    println(\"La longiutud de '$miCadena2' es ${miCadena2.length} caracteres\")\n\n    // Concatenar\n\n    println(\"Aqui la CONCATENACIÓN \" + miCadena2 + miCadena)\n    println(\"$miCadena se une $miCadena2\") // String templates\n\n    // Repetición\n    println(\"LA REPETICIÓN:\")\n    //val repeticion:String = miCadena*3\n    //println (repeticion)\n\n    val repeticion1 = miCadena.repeat(3)\n    println(repeticion1)\n\n    // Recorrido\n    println(\"RECORRIDO\")\n    for (char in miCadena) {\n            println(char)\n    }\n    // conversión a mayúsculas y minúsculas\n    println(\"CONVERSION A MAYUSCULAS Y MINUSCULAS:\")\n    println(miCadena.uppercase())\n    println(miCadena.lowercase())\n\n    // reemplazo,\n    println(\"REEMPLAZO\")\n    val nuevaCadena = miCadena.replace(\"cadena\", \"nueva cadena\")\n    println(nuevaCadena)\n\n    // división,\n    // . Dividir en palabras con el metodo split. Crea una lista.\n    println(\"DIVISION\")\n    val palabras = nuevaCadena.split(\" \")\n    println(palabras)\n\n\n    // unión,\n    val cadenaUnida = palabras.joinToString(\"-\")\n    println(cadenaUnida)\n\n    // empieza con, termina con\n\n    val email = \"usuario@example.com\"\n\n    // Verificar si la cadena comienza con \"usuario\"\n\n    val comienzaConUsuario = email.startsWith(\"usuario\")\n    println(\"Comienza con 'usuario': $comienzaConUsuario\")\n\n    // Verificar si la cadena termina con \".com\"\n    val terminaConCom = email.endsWith(\".com\")\n    println(\"Termina con '.com': $terminaConCom\")\n\n    // verificación\n\n    println(cadenaUnida.contains(\"-\"))\n\n    //dar la vuela a una cadena\n    println(\"DAR LA VUELTA A UNA PALABRA:\")\n    var cadena3: String = \"cadena\"\n    var delreves: String = cadena3.reversed()\n    println(\"La palabra '$cadena3' puesta al reves es '$delreves'\")\n\n    //ordenar los caracteres\n    println(\"ORDENAR LAS LETRAS\")\n    var palabra: String = \"roma\"\n    var nuevapalabra = palabra.toSortedSet()\n    println(nuevapalabra)\n// Extra:\n\n\n    /* Crea un programa que analice dos palabras diferentes y realice comprobaciones\n             * para descubrir si son:\n             * - Palíndromos\n             * - Anagramas\n             * - Isogramas\n\n            Palíndromos: Secuencias de caracteres que se leen igual de izquierda a derecha que de derecha a izquierda, como \"oso\" o \"reconocer\".\n\n            Anagramas: Palabras o frases formadas reorganizando las letras de otra palabra o frase, manteniendo todas las letras originales. Ejemplo: \"amor\" y \"Roma\".\n\n            Isogramas: Palabras en las que no se repite ninguna letra. Cada letra aparece solo una vez. Ejemplo: \"murciélago\".\n             */\n\n    println(\"INTRODUCE DOS PALABRAS\")\n    print(\"Primera palabra:\")\n    var palabra1: String= readln()\n    print(\"Segunda palabra:\")\n    var palabra2: String= readln()\n    println(\"La palabra 1 es '$palabra1' y la segunda es '$palabra2'\")\n    println(\" \")\n    println(\"Análisis de las palabras:\")\n    if (esPalindromo(palabra1)) {println (\"La palabra $palabra1 es un palindromo\")}\n    if (esPalindromo(palabra2)) {println (\"La palabra $palabra2 es un palindromo\")}\n    if(esAnagrama(palabra1,palabra2)) {println(\"La palabra $palabra1 y la palabra $palabra2 forman un anagrama\")}\n    if (esIsograma(palabra1)) {println (\"La palabra $palabra1 es un isograma\")}\n    if (esIsograma(palabra2)) {println (\"La palabra $palabra2 es un isograma\")}\n\n}\n\nfun esPalindromo(palabra: String):Boolean{\n    var reversa:String=palabra.reversed()\n    return (palabra==reversa)\n}\n\nfun esAnagrama (palabra1:String, palabra2:String):Boolean{\n    var ordenada1=palabra1.toCharArray().sorted()\n    var ordenada2=palabra2.toCharArray().sorted()\n    return (ordenada1==ordenada2)\n}\n\nfun esIsograma(palabra: String): Boolean {\n    for (i in 0 until palabra.length - 1) {\n            val subDivide = palabra.slice(i + 1 until palabra.length)\n            if (subDivide.contains(palabra[i])) {\n                    return false\n            }\n    }\n    return true\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/kotlin/westwbn.kt",
    "content": "//     Isograma: palabra o frase en la que cada letra aparece el mismo número de veces.\n//     Palíndromo: Palabra o frase que se lee igual de derecha a izquierda, que de izquierda a derecha\n//     Anagrama: si las dos tienen las mismas letras, con el mismo número de apariciones, pero en un orden diferente\nfun differentWord(firstWord: String, secondWord: String): Boolean {\n    return firstWord != secondWord\n}\n\nfun anagram(firstWord: String, secondWord: String): Boolean {\n    val firstWordMap = firstWord.groupingBy { it }.eachCount()\n    val secondWordMap = secondWord.groupingBy { it }.eachCount()\n\n    return if (differentWord(firstWord, secondWord) && firstWord.length == secondWord.length) {\n        firstWordMap == secondWordMap\n    } else {\n        false\n    }\n}\n\nfun palindrome(firstWord: String, secondWord: String): Boolean {\n    val textOne = firstWord.reversed()\n    val textTwo = secondWord.reversed()\n\n    return if (differentWord(firstWord, secondWord)) {\n        firstWord == textOne && secondWord == textTwo\n    } else {\n        false\n    }\n}\n\nfun isogram(firstWord: String, secondWord: String): Boolean {\n    val textOne = firstWord.groupingBy { it }.eachCount()\n    val textTwo = secondWord.groupingBy { it }.eachCount()\n\n    return if (differentWord(firstWord, secondWord)) {\n        firstWord.length == textOne.size && secondWord.length == textTwo.size\n    } else {\n        false\n    }\n}\n\n\nfun checkWords(firstWord: String, secondWord: String): String {\n    return when {\n        anagram(firstWord, secondWord) -> \"$firstWord y $secondWord forman un: anagrama.\"\n        palindrome(firstWord, secondWord) -> \"$firstWord y $secondWord forman un: palindromo\"\n        isogram(firstWord, secondWord) -> \"$firstWord y $secondWord forman un: isograma\"\n        else -> \"$firstWord y $secondWord no forman lo requerido\"\n    }\n}\n\n\nfun main() {\n    val wordOne = \"I love\"\n    val wordTwo = \"Kotlin\"\n    val text = \"Ejemplo de cadena\"\n    val parts = text.split(\" \")\n\n//  Acceso a caracteres específicos\n    println(\"La tercera letra de la palabra \\\"$wordOne\\\" es: ${wordOne[3]}\")\n    println(\"La primera letra es: ${wordOne.first()}\")\n    println(\"La última letra es: ${wordOne.last()}\")\n\n//    Subcadena\n    println(\"Subcadena a partir del índice 11 de la palabra \\\"$text\\\" : ${text.substring(11)}\")\n\n//    Longitud\n    println(\"Longitud de la cadena ${text.length}\")\n//    Convertir en minúsculas\n    println(wordOne.lowercase())\n\n//    Convertir a mayúsculas\n    println(wordTwo.uppercase())\n\n//    Concatenar\n    println(\"Cadena concatenada: $text en $wordTwo\")\n\n//    Repetición\n    println(\"Repetición de cadena:\")\n    repeat(3) {\n        println(\"$wordOne $wordTwo\")\n    }\n\n//    Recorrido\n    println(\"Recorriendo la cadena:\")\n    for (letter in text) {\n        println(letter)\n    }\n\n//    Reemplazo\n    println(\"Letra \\\"e\\\" reemplazada por \\\"X\\\": ${text.replace('e', 'X')}\")\n\n//    División\n    println(\"Cadena separada por comas: $parts\")\n\n//    Verificación\n    println(\"¿La cadena contiene la palabra \\\"Ejemplo\\\": ${text.contains(\"Ejemplo\")}\")\n\n//    Comparación de cadenas\n    println(\"¿La cadena 1 es igual a la cadena 2?: ${wordOne == wordTwo}\")\n\n//    Eliminación de espacios en blanco\n    val whiteSpace = \"             hola              \"\n    println(\"Eliminando espacios blancos al inicio: ${whiteSpace.trimStart()}\")\n    println(\"Eliminando espacios en blanco al final: ${whiteSpace.trimEnd()}\")\n    println(\"Eliminando todos los espacios en blanco: ${whiteSpace.trim()}\")\n\n//    Extracción de partes específicas\n    val learning = \"Roadmap de retos de programación\"\n    /*Puedes utilizar funciones como substringBefore, substringAfter, take, drop, takeLast, dropLast para extraer partes específicas de una cadena.*/\n    println(\"Extrayendo el texto de la cadena $learning antes de la palabra \\\"de\\\": ${learning.substringBefore(\"de\")}\")\n    println(\"Extrayendo el texto después de la palabra \\\"de\\\": ${learning.substringAfter(\"de\")}\")\n    println(\"Extrayendo el texto a través del índice 10: ${learning.take(10)}\")\n\n//    Búsqueda de cadenas\n    /*Puedes buscar subcadenas dentro de una cadena utilizando funciones como indexOf, lastIndexOf, contains, startsWith, endsWith.*/\n    println(\"Índice de la palabra \\\"Roadmap\\\": ${learning.indexOf(\"Roadmap\")}\")\n    println(\"El texto comienza con \\\"Z\\\"? : ${learning.startsWith(\"Z\")}\")\n\n//    Expresiones regulares\n    val age = \"La edad es 30\"\n    val regexAge = Regex(\"[0-9]+\")\n    println(regexAge.find(age)?.value)\n\n//    Ejercicio extra\n    println(\"RESULTADO DEL EJERCICIO EXTRA:\")\n    println(checkWords(\"adan\", \"nada\"))\n    println(checkWords(\"reconocer\", \"anilina\"))\n    println(checkWords(\"animal\", \"lamina\"))\n    println(checkWords(\"sometemos\", \"sacas\"))\n    println(checkWords(\"huevo\", \"murciélago\"))\n    println(checkWords(\"cazador\", \"reappear\"))\n    println(checkWords(\"anagrama\", \"nagarama\"))\n    println(checkWords(\"caso\", \"saco\"))\n    println(checkWords(\"túnel\", \"tiburón\"))\n}"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/lua/Bert008.lua",
    "content": "--[[\n```\n/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n```\n]]\n\n-- strings\nlocal cadena = \"Hola Mundo\"\nprint(cadena)\nprint(string.len(cadena))\nprint(#cadena)\n\n-- concatenacion\nlocal palabra1 = \"Hola\"\nlocal palabra2 = \"Mundo\"\nprint(palabra1 .. \", \" .. palabra2)\n\n-- repeticion\nlocal repeticion = string.rep(palabra1 ..\" \", 5)\nprint(repeticion)\n\n-- acceso a caracteres especificos\nlocal cadena = \"Mundo\"\nprint(cadena:sub(2, 3))\n\n-- subcadenas\nlocal cadena = \"Hola Mundo\"\nprint(cadena:sub(1, 4))\n\nlocal cadena = \"Hola Mundo\"\nlocal encuentra = string.find(cadena, \"Mundo\")\nprint(encuentra) -- esto nos dice la posicion\n\n-- conversion de mayusculas a minusculas\nlocal cadena = \"Hola Mundo\"\nprint(string.upper(cadena))\nprint(string.lower(cadena))\n\n-- remplazo (string.gsub)\nlocal cadena = \"Hola Mundo\"\nprint(cadena:gsub(\"Mundo\", \"Lua\"))\n\n-- cadena\nlocal cadena = \"Hola, Mundo\"\nfor i in cadena:gmatch(\"[^,]+\") do\n    print(i)\nend\n\n-- union\nlocal cadena = {\"Hola\", \"mundo\", \"Hola\", \"amigo\"}\nprint(table.concat(cadena, \" \"))\n\nlocal cadena = \"Hola Mundo\"\nprint(cadena:match(\"^Hola\"))\nprint(cadena:match(\"Mundo$\"))\n\n-- interpolacion\nlocal palabra1, palabra2 = \"Hola\", \"mundo\"\nprint(string.format(\"La palabra 1 es: %s, y la segunda palabra seria: %s\", palabra1, palabra2))\n\n-- extra\nfunction analizarPalabra(palabra)\n    return palabra:lower():gsub(\"%s+\", \"\")\nend\n\nlocal function palindromo(palabra)\n    palabra = analizarPalabra(palabra) \n    local longitud = #palabra\n\n    for i = 1, math.floor(longitud / 2) do \n        if palabra:sub(i, i) ~= palabra:sub(longitud - i + 1, longitud - i + 1) then\n            return false\n        end\n    end\n    return true \nend\n\nlocal function anagrama(palabra1, palabra2)\n    palabra1 = analizarPalabra(palabra1)\n    palabra2 = analizarPalabra(palabra2)\n\n    if #palabra1 ~= #palabra2 then\n        return false\n    end\n\n    local function contar_letras(palabra)\n        local conteo = {}\n        for letra in palabra:gmatch(\".\") do\n            conteo[letra] = (conteo[letra] or 0) + 1\n        end\n        return conteo\n    end\n\n    local conteo1 = contar_letras(palabra1)\n    local conteo2 = contar_letras(palabra2)\n\n    for letra, cantidad in pairs(conteo1) do\n        if conteo2[letra] ~= cantidad then\n            return false\n        end\n    end\n\n    return true\nend\n\nlocal function isograma(palabra)\n    palabra = analizarPalabra(palabra)\n    local letras_vistas = {}\n\n    for letra in palabra:gmatch(\".\") do\n        if letras_vistas[letra] then\n            return false \n        end\n        letras_vistas[letra] = true\n    end\n    return true\nend\n\n-- Pruebas\nlocal word1 = \"oso\"\nlocal word2 = \"aibofobia\"\nprint(\"¿La palabra '\"..word1..\"' es un palíndromo?: \", palindromo(word1))\nprint(\"¿La palabra '\"..word2..\"' es un palíndromo?: \", palindromo(word2))\n\nprint(\"\\nPruebas de anagramas:\")\nprint(\"roma - amor:\", anagrama(\"roma\", \"amor\"))     -- true\nprint(\"hola - aloh:\", anagrama(\"hola\", \"aloh\"))    -- true\nprint(\"lobo - bolo:\", anagrama(\"lobo\", \"bolo\"))    -- true\nprint(\"perro - pera:\", anagrama(\"perro\", \"pera\"))  -- false\n\nprint(\"\\nPruebas de isogramas:\")\nprint(\"murciélago:\", isograma(\"murcielago\"))  -- true\nprint(\"repetir:\", isograma(\"repetir\"))"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/lua/ansuzgs.lua",
    "content": "-- Strings\n\n--[[\n-- OPERACIONES\n-- ]]\n\n-- To byte\nprint(\"string.byte('abc', 1, 3): \" .. string.byte(\"abc\", 1, 3)) -- 97 98 99\n\n-- From byte\nprint(\"string.char(97, 98, 99): \" .. string.char(97, 98, 99)) -- abc\n\n-- Concatenar\nprint(\"'abc' .. 'def': \" .. \"abc\" .. \"def\") -- abcdef\n\n-- Formatear\nprint(\"string.format('%.2f', 3.1416): \" .. string.format(\"%.2f\", 3.1416)) -- 3.14\n\n-- Buscar\nprint(\"string.find('abc', 'b'): \" .. string.find(\"abc\", \"b\")) -- 2\n\n-- Reemplazar\nprint(\"string.gsub('abc', 'b', 'B'): \" .. string.gsub(\"abc\", \"b\", \"B\")) -- aBc\n\n-- dump\nprint(\"string.dump(function() print('hola') end): \" .. string.dump(function()\n  print(\"hola\")\nend)) -- function() print(\"hola\") end\n\n-- gmacth\nfor word in string.gmatch(\"hola mundo\", \"%a+\") do\n  print(word)\nend\n\n-- match\nprint(\"string.match('hola mundo', '%a+'): \" .. string.match(\"hola mundo\", \"%a+\")) -- hola\n\n-- gsub\nprint(\"string.gsub('hola mundo', '%a+', 'X'): \" .. string.gsub(\"hola mundo\", \"%a+\", \"X\")) -- X X\n\n-- len\nprint(\"string.len('hola mundo'): \" .. string.len(\"hola mundo\")) -- 10\n\n-- lowercase\nprint(\"string.lower('HOLA MUNDO'): \" .. string.lower(\"HOLA MUNDO\")) -- hola mundo\n\n-- pack\n-- print(\"string.pack('i4i4', 3, 4): \" .. string.pack(\"i4i4\", 3, 4)) -- 3 0 0 0 4 0 0 0\n\n-- packsize\n-- print(\"string.packsize('i4i4'): \" .. string.packsize(\"i4i4\")) -- 8\n\n-- rep\nprint(\"string.rep('hola', 3): \" .. string.rep(\"hola\", 3)) -- holaholahola\n\n-- reverse\nprint(\"string.reverse('hola mundo'): \" .. string.reverse(\"hola mundo\")) -- odnum aloh\n\n-- sub\nprint(\"string.sub('hola mundo', 1, 4): \" .. string.sub(\"hola mundo\", 1, 4)) -- hola\n\n-- unpack\n-- print(\"string.unpack('i4i4', '3 0 0 0 4 0 0 0'): \" .. string.unpack(\"i4i4\", \"3 0 0 0 4 0 0 0\")) -- 3 4\n\n-- uppercase\nprint(\"string.upper('hola mundo'): \" .. string.upper(\"hola mundo\")) -- HOLA MUNDO\n\n--[[\n-- EXTRA\n-- ]]\n\nlocal function palindrome(word)\n  -- Check si es palindromo\n  if word == string.reverse(word) then\n    return true\n  else\n    return false\n  end\nend\n\nlocal function sort_word(word)\n  -- Ordenar las palabras\n  word = string.gsub(word, \"%s+\", \"\")\n  word = string.lower(word)\n  local tabla = {}\n  for c in string.gmatch(word, \"%a\") do\n    table.insert(tabla, c)\n  end\n  table.sort(tabla)\n  return tabla\nend\n\nlocal function isogramas(word)\n  word = string.gsub(word, \"%s+\", \"\")\n  word = string.lower(word)\n  local tabla = {}\n  for c in string.gmatch(word, \"%a\") do\n    if tabla[c] == nil then\n      tabla[c] = 0\n    end\n    tabla[c] = tabla[c] + 1\n  end\n  -- comprobar que todas las letras aparezcan el mismo numero de veces\n  -- si es asi, es un isograma\n  local initial_char = string.sub(word, 1, 1)\n  local isogram_length = tabla[initial_char]\n  for c in string.gmatch(word, \"%a\", 2) do\n    if isogram_length ~= tabla[c] then\n      return false\n    end\n  end\n  return true\nend\n\nlocal function check(word1, word2)\n  -- Check si son palindromos\n  if palindrome(word1) then\n    print(word1 .. \" es palindromo\")\n  else\n    print(word1 .. \" no es palindromo\")\n  end\n\n  if palindrome(word2) then\n    print(word2 .. \" es palindromo\")\n  else\n    print(word2 .. \" no es palindromo\")\n  end\n\n  -- Check si son anagramas\n  local word1_table = sort_word(word1)\n  local word2_table = sort_word(word2)\n  local anagrama = true\n  for i = 1, #word1_table do\n    if word1_table[i] ~= word2_table[i] then\n      print(word1 .. \" y \" .. word2 .. \" no son anagramas\")\n      anagrama = false\n      break\n    end\n  end\n  if anagrama then\n    print(word1 .. \" y \" .. word2 .. \" son anagramas\")\n  end\n\n  -- Check si son isogramas\n  if isogramas(word1) then\n    print(word1 .. \" es isograma\")\n  else\n    print(word1 .. \" no es isograma\")\n  end\n\n  if isogramas(word2) then\n    print(word2 .. \" es isograma\")\n  else\n    print(word2 .. \" no es isograma\")\n  end\nend\n\ncheck(\"oso\", \"oso\")\ncheck(\"radar\", \"lualualua\")\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/lua/santyjl.lua",
    "content": "-- 04 CADENAS DE CARACTERES\n-- Dificultad: Media | Publicación: 22/01/24 | Corrección: 29/01/24\n\n-- Ejercicio\n\n--[[\n/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n]]\n\nlocal cadena_de_texto = \"hola mundo\"\nlocal cadena_de_texto2 = \"hola npc\"\n\n-- 1. Longitud de la cadena\nprint(\"Longitud de cadena_de_texto:\" .. string.len(cadena_de_texto))\n\n-- 2. Concatenación de cadenas\nprint(\"Concatenacion:\", cadena_de_texto .. \"--\" .. cadena_de_texto2)\n\n-- 3. Acceso a un carácter específico\n-- En Lua, no puedes acceder directamente por índice, pero puedes usar string.sub\nprint(\"Primer caracter:\" .. string.sub(cadena_de_texto, 1, 1))\n\n-- 4. Subcadenas\nprint(\"Subcadena:\" .. string.sub(cadena_de_texto, 6, 10)) -- Extrae \"mundo\"\n\n-- 5. Repetición de la cadena\nprint(\"Repeticion:\" .. string.rep(cadena_de_texto, 2)) -- Repite \"hola mundo\" dos veces\n\n-- 6. Conversión a mayúsculas y minúsculas\nprint(\"Mayusculas:\" .. string.upper(cadena_de_texto))\nprint(\"Minusculas:\" .. string.lower(cadena_de_texto2))\n\n-- 7. Reemplazo de subcadenas\nprint(\"Reemplazo de 'mundo' por 'npc':\" .. string.gsub(cadena_de_texto, \"mundo\", \"npc\"))\n\n-- 8. División de cadenas (No hay una función directa en Lua, pero puedes usar patrones)\nlocal palabras = {}\nfor palabra in string.gmatch(cadena_de_texto, \"%w+\") do\n    table.insert(palabras, palabra)\nend\nprint(\"Division:\" .. table.concat(palabras, \", \"))\n\n-- 9. Verificación de la existencia de una subcadena\nprint(\"Contiene 'mundo':\", string.find(cadena_de_texto, \"mundo\") ~= nil)\n\n-- 10. Interpolación (usando concatenación o string.format)\nlocal nombre = \"Santiago\"\nprint(string.format(\"Hola, %s!\" , nombre))\n\n-- extra\n\nlocal function palindromo (texto)\n    local texto_volteado = string.reverse(texto)\n    if texto == texto_volteado then\n        return true\n\n    else\n        return false\n    end\nend\n\n\nlocal function Isogramas (texto)\n    local letras = {}\n\n    for i=1 , #texto do  --esto es un bucle for lo que hace es recorrer cada elemento del texto\n        local letra = string.sub(texto , i , i)\n\n        if letras[letra] then\n            return false\n        else\n            letras[letra] = letra\n        end\n    end\n\n    return true\nend\n\nprint(\"============================\")\n\nprint(\"\\npalindromos : \")\nprint(\"hola mundo : \" , palindromo(\"hola mundo\"))\nprint(\"sol : \" , palindromo(\"sol\"))\nprint(\"oso : \" , palindromo(\"oso\"))\n\nprint(\"\\nIsogramas : \")\nprint(\"amateur : \" , Isogramas(\"amateur\"))\nprint(\"jose : \" , Isogramas(\"jose\"))\nprint(\"papa : \" , Isogramas(\"papa\"))\nprint(\"brais moure : \" , Isogramas(\"brais moure\"))"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/nasm/evanz2608.s",
    "content": "; https://nasm.us/\n\n; ====================================================================\n; Ejercicio 04 - Cadenas de texto\n; ====================================================================\n;\n; En ensamblador, existen sólo 5 instrucciones para el manejo de cadena de caracteres (strings)\n; que son: MOVS, LODS, STOS, CMPS y SCAS.\n; Cada una de las cuales tiene distintas variantes. Explico que hace cada una con un ejemplo.\n;\n; MOVS viene de MOV String. Sus variantes son MOVSB, MOVSW, MOVSD, MOVSQ, donde B viene de BYTE, W de WORD, D de DOUBLE WORD y Q de QUAD WORD.\n; (recordemos que BYTE son 8 bits, WORD 16 bit, DOUBLEWORD 32 y QUADWORD 64).\n; Esta instrucción mueve datos de una parte de la memoria a otra, y dependiendo de que variante se usa mueve los datos de 8 en 8 bits, de 16 en 16 etc...\n; Esta misma lógica aplica para CMPS, con sus variantes CMPSB, CMPSW, CMPSD, CMPSQ\n; CMPS viene de CMP Strings. Compara dos valores residentes en memoria, modificando RFLAGS acorde al resultado.\n; LODS viene de LOAD String. Esta instrucción carga en el registro RAX desde la memoria. Se puede usar de dos maneras, sin operandos: usa como puntero a memoria\n; al registro RSI. Si se usa alguna de sus variantes, entonces siempre se usa el registro RSI.\n; STOS Viene de STORE String. Al contrario de LODS, esta instrucción guarda en memoria el valor de RAX. Si se usa STOSB entonces el valor almacenado es el registro AL,\n; si se usa STOSW, se usa AX, etc...\n; SCAS es igual a CMPS sólo que compara un valor en memoria con el registro RAX. Igual que las demas instrucciones, dependiendo de la variante, compara contra AL, AX, EAX, RAX.\n; El resto, deberemos implementarlo por nuestra cuenta.\n;\n; Debo mencionar que NASM tiene 2 macros que se pueden usar para \"manipular\" cadenas de caracteres, aunque no me parecen muy útiles y sólo las voy a mencionar por completitud:\n; %strlen <etiqueta> <string literal> crea una etiqueta con el largo en bytes de la cadena <string literal>. Aunque no se puede usar para calcular el largo de cadenas\n; que tengamos guardadas en memoria, por lo que no la veo muy util.\n; %substr <etiqueta> <string_literal> <index> crea una etiqueta con el valor del <string_literal> en la posicion <index>\n; un ejemplo sería %substr mi_caracter \"xyz\" 1. En este caso se crea una etiqueta \"mi_caracter\" con el valor \"x\". Si en lugar de 1 usamos el 2, \"mi_caracter\" valdría \"y\".\n; de nuevo, esta macro sólo funciona con cadenas de texto literales y no le podemos pasar cadenas que tengamos almacenadas en memoria.\n;\n; NOTA: tanto RDI como RSI son los registros que usan estas instrucciones usan para operar.\n; el registro RDI es el registro de indice de destino, de ahí viene el DI: Destination Index. La R es la nomenclatura que se usa en x64. Existe tambien EDI, de 32 bits y DI de 16 bits\n; al igual, el registor RSI es el registro de indice de fuente: SI de Source Index.\n; De manera que siempre se usa RSI como el puntero a la memoria de la que vamos a leer, y RDI donde vamos a escribir.\n\n\n\n\n\n\n\n\nSYS_write: equ 1  ; syscall para escribir.\nSYS_exit: equ 60  ; syscall para terminar la ejecucion.\n\nSTDIN:  equ 0      ; entrada estandar, en este caso la consola.\nSTDOUT: equ 1     ; salida estandar, en este caso la consola.\nSTDERR: equ 2     ; salida de errores, en este caso también se muestra por consola.\n\nglobal _start\nextern printf\nsection .text\n\n; Vamos a crear una función que nos devuelva el largo de un string.\n; Le pasamos en RDI el puntero al string y nos devuelve en RAX el largo.\n; Recordemos que todos los strings los vamos a terminar con un byte nulo.\nstrlen:\n  xor rax, rax\n.loop:\n  cmp byte [rdi + rax], 0\n  je .done\n  inc rax\n  jmp .loop\n.done:\n  ret\n\n\n\n; Funcion que limpia el buffer apuntado por RDI.\n; El largo se recibe en RSI\nmemset:\n  test rsi, rsi\n  jz .done\n  mov rax, 0\n  mov rcx, rsi\n  cld\n.next:\n  stosb\n  loop .next\n.done:\n  ret\n\n; Función que invierte un string\n; Recibe en RDI el puntero a la memoria donde se va a guardar el string invertido\n; en RSI el string a invertir y en RCX la cantidad de bytes a invertir.\n; La vamos a usar para computar los palindromos.\nreverse:\n  test rcx, rcx\n  jz .done\n  add rdi, rcx\n  dec rdi\n.next:\n  cld\n  lodsb\n  std\n  stosb\n  loop .next \n.done:\n  ret\n\n; El entry point de nuestro programa\n_start:\n  ; Primero vamos a ver ejemplos de las instrucciónes antes mencionadas y sus variantes.\n  ; para comparar, vamos siempre a imprimir por pantalla ambos strings.\n\n.movs_rep:\n  ; Empecemos con MOVS, vamos a copiar word1 en buffer1.\n  ; RDI es el puntero a la memoria destino, y RSI es el puntero a la cadena fuente.\n  lea rdi, [buffer1]\n  lea rsi, [word1]\n  movsb\n  ; En este caso sólo copiamos 1 byte, con lo cual buffer1 contiene solamente \"r\".\n  lea rdi, [printf_mask]\n  lea rsi, [word1]\n  lea rdx, [buffer1]\n  call printf\n\n  ; Existe un modificador que nos facilita el copiar múltiples bytes sin tener que crear un loop.\n  ; REP va a repetir la última instrucción, y se tiene que cargar en RCX el número de repeticiones que queremos realizar.\n  ; MOVS luego de copiar el byte, incrementa o decrementa tanto RDI como RSI 1 byte si usamos MOVSB, 2 bytes si usamos MOVSW, 4 con MOVSD y 8 con MOVSQ.\n  ; El incremento o decremento depende de RFLAGS, en específico el Flag de Direccion (DF). Si esta en 1 decrementa, si está a 0 incrementa.\n  ; Ahora vamos a copiar word1 completo a buffer1 usando REP y limpiando, (poniendo a 0) el flag de dirección para incrementar los punteros.\n\n  lea rdi, [word1]\n  call strlen\n  mov rcx, rax\n  lea rdi, [buffer1]\n  lea rsi, [word1]\n  cld\n  rep movsb\n  ; Ahora buffer1 contiene \"radar\", igual que word1. y rcx en este punto vale 0\n  lea rdi, [printf_mask]\n  lea rsi, [word1]\n  lea rdx, [buffer1]\n  call printf\n\n  ; Ahora que tanto word1 como buffer1 contienen el mismo string, vamos a probar CMPS, para ver si son iguales.\n  ; Del mismo modo que, REP MOVSB repite la operación de copia, podemos usar REP CMPSB para repetir la comprobación en todos los bytes del string.\n  ; Existen 2 variantes de REP que nos son útiles en este caso. REPE y REPNE. También existen REPZ y REPNZ que son equivalentes a las 2 anteriores.\n  ; REPE significa (REPeat while Equal) y, obviamente, REPNE es (REPeat while Not Equal).\n  ; REPE va a repetir la instrucción hasta que la comparación no sea igual, ó hasta que RCX llegue a 0, por lo que es fácil comprobar strings.\n  ; Un detalle a tener en cuenta, es que CMPSB modifica el flag zero (ZF) en cada iteración, con lo cual, podemos comprobar el flag\n  ; luego de que termina la instrucción, en este caso JE viene de Jump Equal, que salta a .equal en caso de estar ZF en 1.\n\n.cmps_rep:\n  lea rdi, [word1]\n  call strlen\n  mov rcx, rax\n  lea rdi, [word1]\n  lea rsi, [buffer1]\n  repe cmpsb\n  je .equal     ; si la comparación falla, la ejecución continua en la siguiente instrucción, si no falla, entonces saltamos a .equal.\n  lea rdi, [not_equal_mask]\n  lea rsi, [buffer1]\n  lea rdx, [word1]\n  call printf\n  jmp .lods_stos\n.equal:\n  lea rdi, [equal_mask]\n  lea rsi, [buffer1]\n  lea rdx, [word1]\n  call printf\n  jmp .lods_stos\n\n.lods_stos:\n  ; Vamos ahora con LODS. Esta instrucción carga en RAX, un valor en la memoria apuntada por RSI.\n  ; Usada en conjunto con STOS sirven para iterar en un string y manipular cada caracter uno por vez.\n  ; Un ejemplo sería convertir minúsculas a mayúsculas.\n\n  ; primero voy a copiar word1 en buffer1 para no destruir el valor en word1.\n  lea rdi, [word1]\n  call strlen\n  mov rcx, rax\n  lea rdi, [buffer1]\n  lea rsi, [word1]\n  cld\n  rep movsb\n\n  ; Para pasar un caracter en minuscula a mayuscula, vamos a setear el bit 6 del byte a 0. Esto porque entre un caracter en minuscula y el mismo en mayuscula solo es\n  ; este bit.\n  ; Un ejemplo: el valor del caracter ascii \"A\" es 0x41, en binario: 0b01000001 y el valor de \"a\" es 0x61, en binario 0b01100001\n\n  ; Ahora que tengo el string copiado en buffer1, vamos a iterar cada byte, cambiar este bit cuando sea necesario, y guardarlo de nuevo en buffer1.\n  lea rdi, [buffer1]\n  call strlen\n  mov rcx, rax\n  lea rsi, [buffer1]\n  mov rdi, rsi\n  cld\n%define BIT_MASK 0b11011111\n.next:\n  lodsb             ; Cargo en al, el siguiente byte, (LODSB incrementa RSI al igual que MOVSB).\n  and al, BIT_MASK  ; Si el bit 6 es 0, lo dejo en 0, si es uno, lo cambio a 0.\n  stosb             ; y guardo el byte en la posicion de memoria apuntada por RDI. (STOS incrementa RDI al igual que MOVSB)\n  loop .next        ; Repito hasta que rcx sea 0. (antes del loop, cargamos en rcx el largo de buffer1).\n\n  ; Una vez terminamos, imprimo. Ahora buffer1 debería contener \"RADAR\" y word1 \"radar\".\n  lea rdi, [printf_mask]\n  lea rsi, [word1]\n  lea rdx, [buffer1]\n  call printf\n\n\n; ============================================================================\n; Ejercicio extra\n; ============================================================================\n\n; Para el ejercicio extra voy a crear unas funciones mas abajo.\n\n  lea rdi, [buffer1]\n  mov rsi, 0\n  mov rdx, BUFFER_LEN\n  call memset\n  lea rdi, [word1]\n  call strlen\n  mov rcx, rax\n  lea rdi, [buffer1]\n  lea rsi, [word1]\n  mov rdx, rcx\n  call palindromos\n\n  lea rdi, [buffer2]\n  mov rsi, 0\n  mov rdx, BUFFER_LEN\n  call memset\n  lea rdi, [word2]\n  call strlen\n  mov rcx, rax\n  lea rdi, [buffer2]\n  lea rsi, [word2]\n  mov rdx, rcx\n  call palindromos\n\n  lea rdi, [word1]\n  lea rsi, [word2]\n  call anagramas\n\n  lea rdi, [word2]\n  call isogramas\n  lea rsi, [word2]\n  jz .is_isogram\n  jmp .is_not_isogram\n\n.is_isogram:\n  lea rdi, [is_isogram_mask]\n  call printf\n  jmp _exit\n\n.is_not_isogram:\n  lea rdi, [is_not_isogram_mask]\n  call printf\n\n; Terminamos la ejecución.\n_exit:\n  mov rax, SYS_exit\n  xor rdi, rdi\n  syscall\n\n\n; ============================================================================\n; Funciones para el ejercicio extra\n; ============================================================================\n\n; RDI: puntero destino\n; RSI: puntero fuente\ncopy:\n  enter 16, 0\n  mov [rbp - 8], rdi\n  mov [rbp - 16], rsi\n\n  mov rdi, rsi\n  call strlen\n  mov rcx, rax\n\n  mov rdi, [rbp - 8]\n  mov rsi, [rbp - 16]\n  cld\n  rep movsb\n  leave\n  ret\n  \npalindromos:\n  enter 32, 0\n  mov rcx, rdx\n  mov [rbp - 0], rdi\n  mov [rbp - 8], rsi\n  mov [rbp - 16], rcx\n  call reverse\n  mov rdi, [rbp - 0]\n  mov rsi, [rbp - 8]\n  mov rcx, [rbp - 16]\n  cld\n  repe cmpsb\n  je .is_palim\n  mov rdx, [rbp - 0]\n  mov rsi, [rbp - 8]\n  lea rdi, [is_not_palim_mask]\n  call printf\n  jmp .done\n.is_palim:\n  mov rdx, [rbp - 0]\n  mov rsi, [rbp - 8]\n  lea rdi, [is_palim_mask]\n  call printf\n.done:\n  leave\n  ret\n\n; Una forma fácil de saber si dos palabras son anagramas, es ordenar sus letras, y comparar ambas cadenas ordenadas.\n; Si son iguales, entonces ambas palabras son anagramas, de lo contrario, no lo son.\n; Puesto que en un anagrama, no importa si las letras son mayusculas o minusculas, pero a la hora de ordenarlas si,\n; primero vamos a convertir todas las letras a minusculas, y luego recién ordenamos y comparamos.\n; Recibe en RDI y RSI los punteros a los strings a comparar.\nanagramas:\n  enter 32, 0\n  mov [rbp - 8], rdi\n  mov [rbp - 16], rsi\n  lea rdi, [buffer1]\n  mov rsi, BUFFER_LEN\n  call memset\n  lea rdi, [buffer2]\n  mov rsi, BUFFER_LEN\n  call memset\n  mov rdi, [rbp - 8]\n  call lowercase\n  mov rdi, [rbp - 16]\n  call lowercase\n  lea rdi, [buffer1]\n  mov rsi, [rbp - 8]\n  call copy\n  lea rdi, [buffer1]\n  call sort\n  lea rdi, [buffer2]\n  mov rsi, [rbp - 16]\n  call copy\n  lea rdi, [buffer2]\n  call sort\n  lea rdi, [buffer1]\n  lea rsi, [buffer2]\n  mov rcx, BUFFER_LEN\n  cld\n  repe cmpsb\n  je .is_anagram\n  lea rdi, [is_not_anagram_mask]\n  mov rsi, [rbp - 8]\n  mov rdx, [rbp - 16]\n  call printf\n  jmp .done\n.is_anagram:\n  lea rdi, [is_anagram_mask]\n  mov rsi, [rbp - 8]\n  mov rdx, [rbp - 16]\n  call printf\n.done:\n  leave\n  ret\n\n; Para saber si una palabra es un isograma, podemos contar cuantas veces aparece cada letra, y luego comparar cada resultado\n; Inicializamos un array de 25 bytes a 0, convertimos la palabra a minusculas y luego, cargamos cada letra en RAX, le restamos 0x61\n; y usamos el resultado como indice para incrementar el array en esa posicion.\n; NOTA: Los caracteres en minuscula en ascii empiezan con \"a\" = 0x61, \"b\" = 0x62 ... \"z\" = 0x7A. Al restarle 0x61, tenemos que \"a\" - 0x61 = 0\n; \"b\" - 0x61 = 1 ... \"z\" - 0x61 = 25. Luego usamos este resultado como indice. Esta es la razon por la que vamos a convertir en minusculas primero.\n; Por ultimo, compararemos el array con el primer valor distinto de 0 que encontremos. Si todos los demás valores del array son 0 ó igual al primer valor hallado,\n; entonces tenemos un isograma.\n; Pongo un ejemplo de cómo se vería el array con un isograma.\n;\n; Palabra: \"diez\"\n;             a b c d e f g h i j k l m n o p q r s t u v w x y z\n; Alphabet:   0 0 0 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1\n\n; Como vemos, en este caso, todas las letras de la palabra solo aparecen una vez, y el resto está a 0.\n; Comprobamos ahora desde el primer valor, si es cero seguimos, si es distinto de cero, lo almacenamos y seguimos comprobando\n; ahora con el valor 1 (el primero distinto de cero que encontramos). Si no hay otro valor distinto de 0 que sea distinto de 1, entonces tenemos un isograma\n; Si encontráramos cualquier otro valor distinto, entonces ya no sería un isograma. \n; Como ejemplo pongamos:\n;\n\n; Palabra: \"jueves\"\n;             a b c d e f g h i j k l m n o p q r s t u v w x y z\n; Alphabet:   0 0 0 0 2 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0\n;\n; Vemos como \"e\" aparece dos veces, y el resto sólo 1 vez.\n\n; RDI = puntero al string a comprobar\nisogramas:\n  mov r12, rdi\n  call lowercase\n  mov rdi, r12\n  mov rsi, r12\n  call strlen\n  mov rcx, rax\n  xor r12, r12\n  xor rax, rax\n.count_loop:\n  lodsb\n  sub al, 0x61\n  inc byte [alphabet + rax]\n  cmp r12b, byte [alphabet + rax]\n  jae .count_continue\n  inc r12\n.count_continue:\n  dec rcx\n  test rcx, rcx\n  jnz .count_loop\n  xor rcx, rcx\n.compare_loop:\n  movzx rbx, byte [alphabet + rcx]\n  inc rcx\n  cmp rbx, 0\n  je .compare_loop\n  cmp rbx, r12\n  jne .compare_fail\n  cmp rcx, 25\n  jae .compare_done\n  jmp .compare_loop\n.compare_fail:\n  mov rax, 1\n  jmp .done\n.compare_done:\n  mov rax, 0\n.done:\n  ret\n\n\n; Función que ordena un array de bytes de menor a mayor.\n; Recibe en RDI el puntero al array a ordenar y en RSI el puntero donde almacenar\n; el array ordenado. La vamos a usar para computar los anagramas.\nsort:\n  enter 16, 0\n  call strlen\n  mov rcx, rax\n.outer_loop:\n  dec rcx\n  test rcx, rcx\n  jz .end_sort\n  mov rsi, rdi\n  mov r12, rcx\n.inner_loop:\n  mov al, byte [rsi]\n  mov bl, byte [rsi + 1]\n  cmp al, bl\n  jbe .no_swap\n  mov byte [rsi], bl\n  mov byte [rsi + 1], al\n.no_swap:\n  inc rsi\n  dec r12\n  jnz .inner_loop\n  jmp .outer_loop\n.end_sort:\n  leave\n  ret\n\n\n; Función que convierte todos los caracteres de un string a minusculas.\n; Recibe en RDI un puntero al string.\nlowercase:\n%define MIN_MASK 0b00100000\n  enter 16, 0\n  mov [rbp - 8], rdi\n  call strlen\n  mov rcx, rax\n  mov rsi, [rbp - 8]\n  mov rdi, rsi\n  cld\n.loop:\n  lodsb\n  or al, MIN_MASK\n  stosb\n  loop .loop\n  leave\n  ret\n  \n\nsection .rodata\n  BUFFER_LEN: equ 20\n  \nsection .data\n  word1: db \"Radar\", 0x00\n  word2: db \"Ensamblador\", 0x00\n\n\n  printf_mask: db \"word1: %s\", 0x0A, \"word2: %s\", 0x0A, 0x00\n  equal_mask: db \"word1 es igual a word2\", 0x0A, \"  word1: %s\", 0x0A, \"  word2: %s\", 0x0A, 0x00\n  not_equal_mask: db \"word1 es distinta a word2\", 0x0A, \"  word1: %s\", 0x0A, \"  word2: %s\", 0x0A, 0x00\n  is_palim_mask: db \"%s es palindromo. Su inverso es: %s\", 0x0A, 0x00\n  is_not_palim_mask: db \"%s no es palindromo. Su inverso es: %s\", 0x0A, 0x00\n  is_anagram_mask: db \"%s es anagrama de %s\", 0x0A, 0x00\n  is_not_anagram_mask: db \"%s no es anagrama de %s\", 0x0A, 0x00\n  is_isogram_mask: db \"%s es isograma.\", 0x0A, 0x00\n  is_not_isogram_mask: db \"%s no es isograma.\", 0x0A, 0x00\n\nsection .bss\n  buffer1: resb BUFFER_LEN\n  buffer2: resb BUFFER_LEN\n  alphabet: resb 25\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/ocaml/luishendrix92.ml",
    "content": "open String\nopen Printf;;\n\n(* The [Stdlib]'s [String] module (ignoring the [Str] library and [Core])\n   contains the following relevant operations:\n\n   {[\n     val length : string -> int\n   ]}\n   [length s] is the length (number of bytes/characters) of [s].\n\n   {[\n     val get : string -> int -> char\n   ]}\n   [get s i] is the character at index i in s. Same as writing [s.[i].]\n\n   {[\n     val concat : string -> string list -> string\n   ]}\n   [concat sep ss] concatenates the list of strings [ss], inserting the\n   separator string [sep] between each.\n\n   {[\n     val cat : string -> string -> string\n   ]}\n   [cat s1 s2] concatenates [s1] and [s2] [(s1 ^ s2)].\n\n   {[\n     val compare : t -> t -> int\n   ]}\n   [compare s0 s1] sorts [s0] and [s1] in lexicographical order. [compare]\n   behaves like [compare] on strings but may be more efficient.\n\n   {[\n     val starts_with : prefix:string -> string -> bool\n   ]}\n   [starts_with ~prefix s] is [true] if and only if [s] starts with [prefix].\n\n   {[\n     val ends_with : suffix:string -> string -> bool\n   ]}\n   [ends_with ~suffix s] is [true] if and only if [s] ends with [suffix].\n\n   {[\n     val contains : string -> char -> bool\n   ]}\n   [contains s c] is [String.contains_from s 0 c].\n\n   {[\n     val sub : string -> int -> int -> string\n   ]}\n   [sub s pos len] is a string of length [len], containing the substring\n   of [s] that starts at position [pos] and has length [len].\n\n   {[\n     val split_on_char : char -> string -> string list\n   ]}\n   [split_on_char sep s] is the list of all (possibly empty) substrings\n   of [s] that are delimited by the character [sep].\n\n   {[\n     val map : (char -> char) -> string -> string\n   ]}\n   [map f s] is the string resulting from applying [f] to all the\n   characters of [s] in increasing order.\n\n   {[\n     val mapi : (int -> char -> char) -> string -> string\n   ]}\n   [mapi f s] is like [String.map] but the index of the character\n   is also passed to [f].\n\n   {[\n     val fold_left : ('acc -> char -> 'acc) -> 'acc -> string -> 'acc\n   ]}\n   [fold_left f x s] computes [f (... (f (f x s.[0]) s.[1]) ...) s.[n-1]],\n   where [n] is the length of the string [s].\n\n   {[\n     val for_all : (char -> bool) -> string -> bool\n   ]}\n   [for_all p s] checks if all characters in [s] satisfy the predicate [p].\n\n   {[\n     val exists : (char -> bool) -> string -> bool\n   ]}\n   [exists p s] checks if at least one character of [s] satisfies [p].\n\n   {[\n     val trim : string -> string\n   ]}\n   [trim s] is [s] without leading and trailing whitespace.\n\n   {[\n     val escaped : string -> string\n   ]}\n   [escaped s] is [s] with special characters represented by escape sequences.\n\n   {[\n     val uppercase_ascii : string -> string\n   ]}\n   [uppercase_ascii s] is [s] with all lowercase letters uppercased.\n\n   {[\n     val lowercase_ascii : string -> string\n   ]}\n   [lowercase_ascii s] is [s] with all uppercase letters lowercased.\n\n   {[\n     val capitalize_ascii : string -> string\n   ]}\n   [capitalize_ascii s] is [s] with the first character set to uppercase.\n\n   {[\n     val uncapitalize_ascii : string -> string\n   ]}\n   [uncapitalize_ascii s] is [s] with the first character set to lowercase.\n\n   {[\n     val iter : (char -> unit) -> string -> unit\n   ]}\n   [iter f s] applies function [f] in turn to all the characters of [s].\n   It is equivalent to [f s.[0]; f s.[1]; ...; f s.[length s - 1]; ()].\n\n   {[\n     val iteri : (int -> char -> unit) -> string -> unit\n   ]}\n   [iteri] is like [String.iter], but the function is also given\n   the corresponding character index.\n\n   {[\n     val index : string -> char -> int\n   ]}\n   [index s c] is [String.index_from s 0 c].\n\n   {[\n     val index_opt : string -> char -> int option\n   ]}\n   [index_opt s c] is [String.index_from_opt s 0 c].\n\n   {[\n     val to_seq : t -> char Seq.t\n   ]}\n   [to_seq s] is a sequence made of the string's characters in order.\n\n   {[\n     val to_seqi : t -> (int * char) Seq.t\n   ]}\n   [to_seqi s] is like [String.to_seq] but also tuples the index.\n\n   {[\n     val of_seq : char Seq.t -> t\n   ]}\n   [of_seq s] is a [string] made of the sequence's characters. *)\n\n(* Concatenation and length. *)\nlet str = cat (\"Hello, \" ^ \"world\") \"!!!\" in\nprintf \"%s has length %d.\\n\" str (length str)\n;;\n\n(* Index access. *)\nbegin\n  printf \"Second letter of 'LCD': %c.\\n\" (get \"LCD\" 1);\n  printf \"First letter of 'what': %c.\\n\" \"what\".[0]\nend\n\n(* Predicates and comparisons. *)\nlet print_comparison a b =\n  let veredict =\n    match compare a b with\n    | -1 -> '<'\n    | 0 -> '='\n    | 1 -> '>'\n    | _ -> '?'\n  in\n  printf \"Lexicographical comparison: '%s' %c '%s'.\\n\" a veredict b\n;;\n\nbegin\n  printf \"Are '%s' and '%s' equal? %b.\\n\" \"one\" \"one\" (equal \"one\" \"one\");\n  printf \"Are '%s' and '%s' equal? %b.\\n\" \"two\" \"ten\" (equal \"two\" \"ten\");\n  print_comparison \"aaa\" \"baa\";\n  print_comparison \"az1\" \"ax2\";\n  print_comparison \"333\" \"333\";\n  printf \"Does 'Luis' start with 'Lu'? %b.\\n\" (starts_with ~prefix:\"Lu\" \"Luis\");\n  printf \"Does 'Dora' start with 'do'? %b.\\n\" (starts_with ~prefix:\"do\" \"Dora\");\n  printf \"Does 'abc' end with 'bc'? %b.\\n\" (ends_with ~suffix:\"bc\" \"abc\");\n  printf \"Does 'xyz' end with 'zy'? %b.\\n\" (ends_with ~suffix:\"zy\" \"xyz\");\n  printf \"Is '_' contained in 'snake_case'? %b.\\n\" (contains \"snake_case\" '_');\n  printf \"Is 'a' contained in 'HOA'? %b.\\n\" (contains \"HOA\" 'a')\nend\n\n(* Extracting substrings. *)\nlet show_str_list = function\n  | h :: tl -> \"[\" ^ List.fold_left (fun acc s -> acc ^ \"; \" ^ s) h tl ^ \"]\"\n  | _ -> \"[]\"\n;;\n\nbegin\n  printf \"Slicing 'AEIOU' with pos=1 and len=3: '%s'.\\n\" (sub \"AEIOU\" 1 3);\n  printf\n    \"Splitting '1,23,4,5' at every ',': %s.\\n\"\n    (split_on_char ',' \"1,23,4,5\" |> show_str_list)\nend\n\n(* Transforming. *)\nlet is_digit = function\n  | '0' .. '9' -> true\n  | _ -> false\n;;\n\nbegin\n  printf\n    \"Increasing every char code in 'abc' by 1: '%s'.\\n\"\n    (map (fun c -> Char.code c |> Int.succ |> Char.chr) \"abc\");\n  printf\n    \"Replacing chars with their index in 'WoW': '%s'.\\n\"\n    (mapi (fun i _ -> (string_of_int i).[0]) \"WoW\");\n  printf\n    \"Sum of all char codes in 'dog': %d.\\n\"\n    (fold_left (fun sum ch -> Char.code ch + sum) 0 \"dog\");\n  printf \"Is '1234' made of only digits? %b.\\n\" (for_all is_digit \"1234\");\n  printf \"Is there any digit in 'abc'? %b.\\n\" (exists is_digit \"abc\");\n  printf\n    \"Trimming whitespace off '\\t  this\\r\\n  ' on both sides: '%s'.\\n\"\n    (trim \"\\t  this\\r\\n  \");\n  printf \"Uppercase of 'sOmEtHiNg': '%s'.\\n\" (uppercase_ascii \"sOmEtHiNg\");\n  printf \"Lowercase of 'QUIET!': '%s'.\\n\" (lowercase_ascii \"QUIET!\");\n  printf\n    \"Capitalization of 'my awesome title': '%s'.\\n\"\n    (capitalize_ascii \"my awesome title\")\nend\n;;\n\n(* Traversing. *)\nbegin\n  print_endline \"Spelling out 'pony' char by char:\";\n  \"pony\" |> iter (fun c -> printf \"- %c\\n\" c);\n  print_endline \"Spelling out 'my hands' with indices:\";\n  \"my hands\" |> iteri (fun i c -> printf \"- [%d] %c\\n\" i c)\nend\n;;\n\n(* Searching. *)\nbegin\n  printf\n    \"Index of '!' in '?!¿' (scan from left to right): %s\\n\"\n    (try string_of_int (index \"?!¿\" '!') with\n     | Not_found -> \"not found!\");\n  printf\n    \"Index of 'z' in 'xyy' (scan from left to right): %s\\n\"\n    (index_opt \"xyy\" 'z'\n     |> Option.map string_of_int\n     |> Option.value ~default:\"not found!\");\n  printf\n    \"Index of '1' in '1113' (scan from right to left): %s\\n\"\n    (try string_of_int (rindex \"1113\" '1') with\n     | Not_found -> \"-1\");\n  printf\n    \"Index of '5' in 'aa33' (scan from right to left): %s\\n\"\n    (rindex_opt \"aa33\" '5'\n     |> Option.map string_of_int\n     |> Option.value ~default:\"-1\")\nend\n\n(*--------------------------------------------------------------------*\n * DIFICULTAD EXTRA (opcional):                                       *\n *                                                                    *\n * Crea un programa que analice dos palabras y realice comprobaciones *\n * para descubrir si son:                                             *\n * - Palíndromos                                                      *\n * - Anagramas                                                        *\n * - Isogramas                                                        *\n ---------------------------------------------------------------------*)\n\n(** [rev_str s] reverses a string [s]. *)\nlet rev_str s =\n  String.to_seq s |> List.of_seq |> List.rev |> List.to_seq |> String.of_seq\n;;\n\n(** [is_alpha ch] returns [true] if the character [ch] is a lowercase\n    or uppercase letter of the alphabet ([a-z] or [A-Z]). *)\nlet is_alpha ch =\n  match ch with\n  | 'a' .. 'z' | 'A' .. 'Z' -> true\n  | _ -> false\n;;\n\n(** [is_palindrome s] returns [true] when a string [s] is equal to its reversed\n    version. Case-insensitive, considers non-alphanumeric characters. *)\nlet is_palindrom s = lowercase_ascii s = (rev_str s |> lowercase_ascii)\n\n(** [is_anagram s1 s2] returns [true] when [s2] and [s1] form an anagram,\n    meaning, all the letters (including repeated ones) from [s1] are present in\n    [s2] and viceversa. Case-insensitive, ignores non-alphabetical chars. *)\nlet is_anagram s1 s2 =\n  let clean_and_sorted s =\n    String.lowercase_ascii s\n    |> String.to_seq\n    |> List.of_seq\n    |> List.filter is_alpha\n    |> List.stable_sort Char.compare\n    |> List.to_seq\n    |> String.of_seq\n  in\n  clean_and_sorted s1 = clean_and_sorted s2\n;;\n\nmodule CharMap = Map.Make (Char)\n\n(** [frequencies s] counts each character in [s] and returns an associative\n    list (a list of tuples) where the key is a character and the value is\n    the number of times it appears in the string. *)\nlet frequencies s =\n  let inc_count = function\n    | Some count -> Some (count + 1)\n    | None -> Some 1\n  in\n  String.to_seq s\n  |> Seq.fold_left\n       (fun freqs ch -> CharMap.update ch inc_count freqs)\n       CharMap.empty\n  |> CharMap.to_list\n;;\n\n(** [isogram s] returns [Some n] where the number [n] represents the order of\n    the isogram [s]. If [s] is not a true isogram, then [None] is returned\n    instead. [s] is an {b isogram} if all its characters appear the {e same\n    number of times}. An isogram of order [1] is an {b heterogram}, this means\n    each character appears only once (no repeats). *)\nlet isogram s =\n  match length s with\n  | len when len < 2 -> Some len\n  | _ ->\n    let freqs = frequencies s in\n    let _, expected_count = List.hd freqs in\n    let is_true_isogram =\n      List.for_all (fun (_, count) -> count = expected_count) freqs\n    in\n    if is_true_isogram then Some expected_count else None\n;;\n\n(** [prompt msg] prints a string [msg] and asks the user for input. Returns\n    the line that was inputted (anything before hitting [ENTER]). If [ENTER]\n    was pressed before any other characters, [\"\"] is returned instead. *)\nlet prompt_str msg =\n  begin\n    print_string msg;\n    flush Out_channel.stdout;\n    In_channel.input_line In_channel.stdin |> Option.value ~default:\"\"\n  end\n;;\n\nlet () =\n  let str_of_bool b = if b then \"is\" else \"is not\" in\n  let print_isogram s =\n    match isogram s with\n    | Some 1 -> printf \"'%s' is an heterogram.\\n\" s\n    | Some n -> printf \"'%s' is a perfect isogram of order %d.\\n\" s n\n    | None -> printf \"'%s' is NOT an isogram!\\n\" s\n  in\n  begin\n    print_endline \"\\nOptional Challenge\";\n    print_endline \"__________________\";\n    let word1 = prompt_str \"Enter the first word: \" in\n    let word2 = prompt_str \"Enter the second word: \" in\n    printf\n      \"\\n'%s' %s a palindrom, and '%s' %s a palindrom.\\n\"\n      word1\n      (is_palindrom word1 |> str_of_bool)\n      word2\n      (is_palindrom word2 |> str_of_bool);\n    printf\n      \"'%s' %s an anagram of '%s'.\\n\"\n      word1\n      (is_anagram word1 word2 |> str_of_bool)\n      word2;\n    print_isogram word1;\n    print_isogram word2\n  end\n;;\n\n(* Output of running [ocaml luishendrix92.ml]:\n\n   Hello, world!!! has length 15.\n   Second letter of 'LCD': C.\n   First letter of 'what': w.\n   Are 'one' and 'one' equal? true.\n   Are 'two' and 'ten' equal? false.\n   Lexicographical comparison: 'aaa' < 'baa'.\n   Lexicographical comparison: 'az1' > 'ax2'.\n   Lexicographical comparison: '333' = '333'.\n   Does 'Luis' start with 'Lu'? true.\n   Does 'Dora' start with 'do'? false.\n   Does 'abc' end with 'bc'? true.\n   Does 'xyz' end with 'zy'? false.\n   Is '_' contained in 'snake_case'? true.\n   Is 'a' contained in 'HOA'? false.\n   Slicing 'AEIOU' with pos=1 and len=3: 'EIO'.\n   Splitting '1,23,4,5' at every ',': [1; 23; 4; 5].\n   Increasing every char code in 'abc' by 1: 'bcd'.\n   Replacing chars with their index in 'WoW': '012'.\n   Sum of all char codes in 'dog': 314.\n   Is '1234' made of only digits? true.\n   Is there any digit in 'abc'? false.\n   Trimming whitespace off '\t  this\n   ' on both sides: 'this'.\n   Uppercase of 'sOmEtHiNg': 'SOMETHING'.\n   Lowercase of 'QUIET!': 'quiet!'.\n   Capitalization of 'my awesome title': 'My awesome title'.\n   Spelling out 'pony' char by char:\n   - p\n   - o\n   - n\n   - y\n     Spelling out 'my hands' with indices:\n   - [0] m\n   - [1] y\n   - [2]\n   - [3] h\n   - [4] a\n   - [5] n\n   - [6] d\n   - [7] s\n     Index of '!' in '?!¿' (scan from left to right): 1\n     Index of 'z' in 'xyy' (scan from left to right): not found!\n     Index of '1' in '1113' (scan from right to left): 2\n     Index of '5' in 'aa33' (scan from right to left): -1\n\n   Optional Challenge\n   __________________\n   Enter the first word: raceecar\n   Enter the second word: caer reac\n   'raceecar' is a palindrom, and 'caer reac' is a palindrom.\n   'raceecar' is an anagram of 'caer reac'.\n   'raceecar' is a perfect isogram of order 2.\n   'caer reac' is NOT an isogram!\n*)\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/pascal/miguelex.pas",
    "content": "program miguelex;\n\nvar\n  cadena1, cadena2: string;\n  longitud, position: integer;\n  \n{ Funcion que verifica si una cadena es un palindromo }\nfunction esPalindromo(cadena: string): boolean;\nvar\n  i: integer;\nbegin\n    esPalindromo := true;\n    { Pasamos la cadena a minusculas }\n    cadena := lowercase(cadena);\n    for i := 1 to length(cadena) do\n        if cadena[i] <> cadena[length(cadena) - i + 1] then\n            esPalindromo := false;\nend;\n\n{ Funcion que verifica si una cadena es anagrama }\nfunction esAnagrama(cadena1, cadena2: string): boolean;\nvar\n  i, j: integer;\n  encontrado: boolean;\nbegin\n    esAnagrama := true;\n    { Pasamos las cadenas a minusculas }\n    cadena1 := lowercase(cadena1);\n    cadena2 := lowercase(cadena2);\n    for i := 1 to length(cadena1) do\n    begin\n        encontrado := false;\n        for j := 1 to length(cadena2) do\n            if cadena1[i] = cadena2[j] then\n                encontrado := true;\n        if not encontrado then\n            esAnagrama := false;\n    end;\nend;\n\n{ Funcion que verifica de una cadena es Isogramas }\nfunction esIsograma(cadena: string): boolean;\nvar\n  i, j: integer;\nbegin\n    esIsograma := true;\n    { Pasamos la cadena a minusculas }\n    cadena := lowercase(cadena);\n    for i := 1 to length(cadena) do\n        for j := i + 1 to length(cadena) do\n            if cadena[i] = cadena[j] then\n                esIsograma := false;\nend;\n\nbegin\n\n    writeln('Introduzca la primera cadena');\n    readln(cadena1);\n    \n    writeln('Vamos a hacer las pruebas sobre la cadena ', cadena1);\n    writeln();\n\n    { Longitud de la cadena }\n    longitud := length(cadena1);\n    writeln('La longitud de la cadena es --> ', longitud);\n    writeln();\n    \n    { Concatenar cadenas }\n    writeln('Introduzca la segunda cadena');\n    readln(cadena2);\n    writeln('Vamos a concatenar la cadena ', cadena1, ' con la cadena ', cadena2);\n    writeln('El resultado es --> ', cadena1 + ' ' + cadena2);\n    writeln();\n\n    { Comparar cadenas }\n    writeln('Vamos a comparar la cadena ', cadena1, ' con la cadena ', cadena2);\n    if cadena1 = cadena2 then\n        writeln('Las cadenas son iguales')\n    else\n        writeln('Las cadenas son distintas');\n    writeln();\n    \n    { Copiar cadenas }\n    writeln('Vamos a copiar la cadena ', cadena1, ' en la cadena ', cadena2);\n    cadena2 := cadena1;\n    writeln('El resultado es -->  ', cadena2);\n    writeln();\n\n    { Extraer una subcadena }\n    writeln('Vamos a extraer una subcadena de la cadena ', cadena1);\n    writeln('Introduzca la posicion inicial');\n    readln(position);\n    writeln('Introduzca la longitud');\n    readln(longitud);\n    cadena2 := copy(cadena1, position, longitud);\n    writeln('El resultado es --> ', cadena2);\n    writeln();\n\n    { Insertar una subcadena }\n    writeln('Vamos a insertar una subcadena en la cadena ', cadena1);\n    writeln('Introduzca la posicion inicial');\n    readln(position);\n    writeln('Introduzca la subcadena');\n    readln(cadena2);\n    insert(cadena2, cadena1, position);\n    writeln('El resultado es --> ', cadena1);\n    writeln();\n\n    { Eliminar una subcadena }\n    writeln('Vamos a eliminar una subcadena en la cadena ', cadena1);\n    writeln('Introduzca la posicion inicial');\n    readln(position);\n    writeln('Introduzca la longitud');\n    readln(longitud);\n    delete(cadena1, position, longitud);\n    writeln('El resultado es --> ', cadena1);\n    writeln();\n\n    { Buscar una subcadena }\n    writeln('Vamos a buscar una subcadena en la cadena ', cadena1);\n    writeln('Introduzca la subcadena');\n    readln(cadena2);\n    position := pos(cadena2, cadena1);\n    if position <> 0 then\n        writeln('La subcadena se encuentra en la posicion ', position)\n    else\n        writeln('La subcadena no se encuentra en la cadena');\n    writeln();\n\n    { Convertir a mayusculas }\n    writeln('Vamos a convertir la cadena ', cadena1, ' a mayusculas');\n    cadena2 := upcase(cadena1);\n    writeln('El resultado es --> ', cadena2);\n    writeln();\n\n    { Convertir a minusculas }\n    writeln('Vamos a convertir la cadena ', cadena1, ' a minusculas');\n    cadena2 := lowercase(cadena1);\n    writeln('El resultado es --> ', cadena2);\n    writeln();\n\n    { Invertir cadena }\n    writeln('Vamos a invertir la cadena ', cadena1);\n    cadena2 := '';\n    for position := length(cadena1) downto 1 do\n        cadena2 := cadena2 + cadena1[position];\n    writeln('El resultado es --> ', cadena2);\n    writeln();\n\n    { Eliminar espacios en blanco }\n    writeln('Vamos a eliminar los espacios en blanco de la cadena ', cadena1);\n    cadena2 := '';\n    for position := 1 to length(cadena1) do\n        if cadena1[position] <> ' ' then\n            cadena2 := cadena2 + cadena1[position];\n    writeln('El resultado es --> ', cadena2);\n    writeln();\n\n    { Eliminar caracteres no alfabeticos }\n    writeln('Vamos a eliminar los caracteres no alfabeticos de la cadena ', cadena1);\n    cadena2 := '';\n    for position := 1 to length(cadena1) do\n        if cadena1[position] in ['a'..'z', 'A'..'Z'] then\n            cadena2 := cadena2 + cadena1[position];\n    writeln('El resultado es --> ', cadena2);\n    writeln();\n\n    { Eliminar vocales }\n    writeln('Vamos a eliminar las vocales de la cadena ', cadena1);\n    cadena2 := '';\n    for position := 1 to length(cadena1) do\n        if cadena1[position] in ['a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'] then\n            cadena2 := cadena2 + cadena1[position];\n    writeln('El resultado es --> ', cadena2);\n    writeln();\n\n    { Extra }\n\n    WriteLn(esPalindromo('Ana'));\n    WriteLn(esPalindromo('Esto no es un palindromo'));\n    WriteLn(esPalindromo('Ana lava lana'));\n\n    WriteLn(esAnagrama('amor', 'roma'));\n    WriteLn(esAnagrama('monja', 'jamon'));\n    WriteLn(esAnagrama('monja', 'jamoncito'));\n\n    WriteLn(esIsograma('murcielago'));\n    WriteLn(esIsograma('murcielagoo'));\n\nend.    "
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/php/CeciliaPorras01.php",
    "content": "<?php\n/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\n\n//Concatenación\n\n$nombre = \"Cecilia\";\n$saludo = \"Hola\";\n\necho $saludo . \", \" . $nombre . \"!\\n\";\n\n//Repetición\nprint str_repeat(\"Hola\\n\", 3);\n\n//Indexación\nprint $nombre[0] . $nombre[1] . $nombre[2] . $nombre[3] . $nombre[4] . $nombre[5] . $nombre[6] .\"\\n\";\n\n//Longitud\nprint strlen($nombre);\n\n//Slycing\nprint substr($nombre, 2, 3) . \"\\n\";\n\n//Busqueda\nprint strpos($nombre, \"c\") . \"\\n\";\nprint strpos($nombre, \"e\") . \"\\n\";\n\n//Reemplazo\nprint str_replace(\"C\", \"o\", $nombre) . \"\\n\";\n\n//División\n$nombre = \"CeciliaPorras01\";\n$partes = str_split($nombre);\n\nprint_r($partes);\n\n//Mayúsculas , minúsculas y primera letra en mayúscula\n\nprint strtoupper($nombre) . \"\\n\";\nprint strtolower($nombre) . \"\\n\";\nprint ucfirst($nombre) . \"\\n\";\n\n//Eliminación de espacios en blanco al inicio y al final\n$nombre = \" Cecilia \";\nprint trim($nombre) . \"\\n\";\n\n//Busqueda al inicio y al final\nprint str_starts_with($nombre, \"C\") . \"\\n\";\nprint str_ends_with($nombre, \"o\") . \"\\n\";\n\n\n//Busqueda de posición\n$nombre = \"Cecilia Porras01\";\nprint strpos($nombre, \"P\") . \"\\n\";\n\n\n//Busqueda de ocurrencias\nprint substr_count($nombre, \"1\") . \"\\n\";\n\n\n//Formateo\n\n$nombre = \"Cecilia\";\n$edad = 25;\n\n$cadenaFormateada = sprintf(\"Hola, %s. Tienes %d años.\", $nombre, $edad);\necho $cadenaFormateada;\n\n//Interpolación\necho \"Hola, $nombre. Tienes $edad años.\\n\";\n\n//Transformación en lista de caracteres\n$nombreArray = str_split($nombre);\nprint_r($nombreArray);\n\n//Transformación de lista en cadena\n$nombreArray = str_split($nombre);\n$nombre = implode('-', $nombreArray);\necho $nombre;\n\n\n//Extra\n\nfunction validText($text1, $text2) {\n    print \"\\n\";\n\n    // Palíndromos\n    if ($text1 == strrev($text1)) {\n        print \"$text1 es palíndromo\\n\";\n    } else {\n        print \"$text1 no es palíndromo\\n\";\n    }\n\n    if ($text2 == strrev($text2)) {\n        print \"$text2 es palíndromo\\n\";\n    } else {\n        print \"$text2 no es palíndromo\\n\";\n    }\n\n    // Anagramas\n    $text1Normalized = strtolower($text1);\n    $text2Normalized = strtolower($text2);\n\n    if (count_chars($text1Normalized, 1) == count_chars($text2Normalized, 1)) {\n        print \"$text1 y $text2 son anagramas\\n\";\n    } else {\n        print \"$text1 y $text2 no son anagramas\\n\";\n    }\n\n    // Isogramas\n    $textIso1 = strtolower($text1);\n    $textIso2 = strtolower($text2);\n\n    if (count(str_split($textIso1)) == count(array_unique(str_split($textIso1))) &&\n        count(str_split($textIso2)) == count(array_unique(str_split($textIso2)))) {\n        print \"$text1 y $text2 son isogramas\\n\";\n    } else {\n        print \"$text1 y $text2 no son isogramas\\n\";\n    }\n\n}\n\n// Prueba de ejemplo\nvalidText(\"amor\", \"roma\");  // Debería decir que son anagramas\nvalidText(\"murcielago\", \"jamon\");  // \"murcielago\" es isograma, \"jamon\" también\nvalidText(\"oso\", \"radar\");  // Ambos son palíndromos\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/php/Jeyker-Dev.php",
    "content": "<?php\n\n/*\n* EJERCICIO:\n* Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n* en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n* - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n*   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n*\n* DIFICULTAD EXTRA (opcional):\n* Crea un programa que analice dos palabras diferentes y realice comprobaciones\n* para descubrir si son:\n* - Palíndromos\n* - Anagramas\n* - Isogramas\n*/\n\n$string = \"String\";\n$string_2 = \"    String 2\";\n$string_3 = \"Another\";\n\n// Returns the length of the string\necho \"The length of string is \".strlen($string).\".\\n\";\n\n// Makes a string to lowercase\necho strtolower($string).\".\\n\";\n\n// Makes a string to uppercase\necho strtoupper($string).\".\\n\";\n\n// Return a part of the string\necho substr($string,0,3).\".\\n\";\n\n// Replace all occurrences of the search string with the replacement string\necho str_replace(\"String\", \"Hola\", $string).\".\\n\";\n\n// Returns a string with the first character of str lowercase if that character is alphabetic.\necho lcfirst($string).\"\\n\";\n\n// Removes whitespace (or other characters) from the beginning of a string.\necho trim($string_2).\"\\n\";\n\n// Returns the reversed string\necho strrev($string).\"\\n\";\n\nclass Funcionality\n{\n    public function palindromes(string $word_1, string $word_2): string\n    {\n        $word_1 = trim($word_1);\n        $word_2 = trim($word_2);\n\n        $convert_word = $this->toLowerAndReversed($word_1);\n        $convert_word_2 = $this->toLowerAndReversed($word_2);\n\n        if($convert_word === $word_1) {\n            echo \"The First Word is a Palindrome.\\n\";\n        }\n\n        if($convert_word_2 === $word_2) {\n            echo \"The Second Word is a Palindrome.\\n\";\n        }\n\n        return \"The words ain't palindromes.\\n\";\n    }\n\n    public function anagrams(string $word_1, string $word_2): string\n    {\n        $word_1 = strtolower(trim($word_1));\n        $word_2 = strtolower(trim($word_2));\n\n        $sorted_word_1 = $this->sortString($word_1);\n        $sorted_word_2 = $this->sortString($word_2);\n\n        if ($sorted_word_1 === $sorted_word_2) {\n            return \"The words are anagrams.\\n\";\n        } else {\n            return \"The words are not anagrams.\\n\";\n        }\n    }\n\n    public function isograms(string $word_1, string $word_2)\n    {\n        $word_1 = strtolower(trim($word_1));\n        $word_2 = strtolower(trim($word_2));\n\n        $letters = str_split($word_1);\n        $letters_2 = str_split($word_2);\n\n        $is_isogram = $this->hasRepeatingLetters($letters);\n        $is_isogram_2 = $this->hasRepeatingLetters($letters);\n\n        if($is_isogram === true) {\n            echo \"The First Word is a Isogram.\\n\";\n        }\n\n        if($is_isogram_2 === true) {\n            echo \"The Second Word is a Isogram.\\n\";\n        }\n    }\n\n    public function hasRepeatingLetters(array $letters): bool\n    {\n        foreach ($letters as $letter => $count) {\n            if ($count > 1) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    private function sortString(string $word): string\n    {\n        $letters = str_split($word);\n        sort($letters);\n        return implode('', $letters);\n    }\n\n    public function toLowerAndReversed(string $word): string\n    {\n        $lower_word = strtolower($word);\n        return $reversed_word =  strrev($lower_word);\n    }\n}\n\n$instance = new Funcionality();\n\n$instance->isograms($string,$string_3);\n\necho \"This is a program where you write two words and then it will analyze if the words are palindromes, anagrams or isograms.\\n\";\n\necho \"Write the first word: \";\n$word_1 = fgets(STDIN);\n\necho \"Write the second word: \";\n$word_2 = fgets(STDIN);\n\n\n\n$instance->palindromes($word_1, $word_2);\n$instance->anagrams($word_1, $word_2);\n$instance->isograms($word_1, $word_2);\n\n\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/php/adrs1166ma.php",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\n <?php\n\n/* \n * OPERACIONES\n */\n\n// 1. Declaración de una cadena\n$cadena = \"Hola Mundo\";\n\n// 2. Acceso a caracteres específicos\necho \"2. Acceso a caracteres:<br>\";\necho \"   El primer carácter es: \" . $cadena[0] . \"<br>\";    // 'H'\necho \"   El cuarto carácter es: \" . $cadena[3] . \"<br>\";    // 'a'\necho '<br>';\n\n// 3. Subcadenas (substr)\necho \"3. Subcadenas:<br>\";\necho \"   Subcadena desde el índice 5: \" . substr($cadena, 5) . \"<br>\";      // \"Mundo\"\necho \"   Subcadena de longitud 3 desde el índice 5: \" . substr($cadena, 5, 3) . \"<br>\"; // \"Mun\"\necho '<br>';\n\n// 4. Longitud de la cadena (strlen)\necho \"4. Longitud:<br>\";\necho \"   La longitud de '$cadena' es: \" . strlen($cadena) . \"<br>\";\necho '<br>';\n\n// 5. Concatenación (operador .)\necho \"5. Concatenación:<br>\";\n$otraCadena = \" desde PHP\";\n$concatenada = $cadena . $otraCadena;\necho \"   Cadena concatenada: $concatenada<br>\";\necho '<br>';\n\n// 6. Repetición de cadenas (str_repeat)\necho \"6. Repetición:<br>\";\n$repetida = str_repeat($cadena, 2);\necho \"   Repetir '$cadena' 2 veces: $repetida<br>\";\necho '<br>';\n\n// 7. Recorrer cada carácter (str_split + bucle)\necho \"7. Recorrido de la cadena carácter a carácter:<br>\";\n$arrayCaracteres = str_split($cadena);\nforeach ($arrayCaracteres as $char) {\n    echo \"   $char<br>\";\n}\necho '<br>';\n\n// 8. Conversión a mayúsculas y minúsculas (strtoupper, strtolower)\necho \"8. Cambios de mayúsculas/minúsculas:<br>\";\necho \"   En mayúsculas: \" . strtoupper($cadena) . \"<br>\"; // \"HOLA MUNDO\"\necho \"   En minúsculas: \" . strtolower($cadena) . \"<br>\"; // \"hola mundo\"\necho '<br>';\n\n// 9. Reemplazo de subcadenas (str_replace)\necho \"9. Reemplazo:<br>\";\n$reemplazada = str_replace(\"Mundo\", \"ChatGPT\", $cadena);\necho \"   Reemplazar 'Mundo' por 'ChatGPT': $reemplazada<br>\";\necho '<br>';\n\n// 10. División de cadenas (explode)\necho \"10. División (explode):<br>\";\n$partes = explode(\" \", $cadena); // [\"Hola\", \"Mundo\"]\necho \"   Después de explode(' ', '$cadena'): <br>\";\nprint_r($partes);\necho '<br>';\n\n// 11. Unión de elementos de un array en una cadena (implode)\necho \"11. Unión (implode):<br>\";\n$unida = implode(\"-\", $partes); // \"Hola-Mundo\"\necho \"   Unir con '-': $unida<br>\";\necho '<br>';\n\n// 12. Interpolación de variables\necho \"12. Interpolación:<br>\";\n$nombre = \"Carlos\";\necho \"   Usando comillas dobles, se puede interpolar: \\\"Hola, $nombre\\\"<br>\";\necho '<br>';\n\n// 13. Verificación de la existencia de subcadena (strpos o str_contains en PHP8+)\necho \"13. Verificación de subcadena:<br>\";\nif (strpos($cadena, \"Mundo\") !== false) {\n    echo \"   'Mundo' se encuentra dentro de '$cadena'.<br>\";\n} else {\n    echo \"   'Mundo' NO se encuentra dentro de '$cadena'.<br>\";\n}\necho '<br>';\n\n/*\n *  🔥 PROGRAMA PARA PALÍNDROMOS, ANAGRAMAS E ISOGRAMAS\n * \n * Este programa analiza dos palabras y realiza comprobaciones \n * para descubrir si son:\n *   - Palíndromos\n *   - Anagramas\n *   - Isogramas\n */\n\n// Puedes cambiar estas dos palabras para hacer pruebas.\n$palabra1 = \"Murcielago\";\n$palabra2 = \"Guacamole\";\n\n/**\n * isPalindrome\n * Comprueba si una palabra es palíndroma (se lee igual al derecho y al revés).\n */\nfunction isPalindrome($word) {\n    // Convertimos a minúsculas y quitamos espacios en blanco\n    $procesada = strtolower(preg_replace(\"/\\s+/\", \"\", $word));\n    // Comparamos con su inversa\n    return $procesada === strrev($procesada);\n}\n\n/**\n * isAnagram\n * Comprueba si dos palabras son anagramas (contienen las mismas letras en distinto orden).\n */\nfunction isAnagram($word1, $word2) {\n    // Convertimos a minúsculas y quitamos espacios\n    $procesada1 = strtolower(preg_replace(\"/\\s+/\", \"\", $word1));\n    $procesada2 = strtolower(preg_replace(\"/\\s+/\", \"\", $word2));\n\n    // Creamos arrays de caracteres y los ordenamos\n    $array1 = str_split($procesada1);\n    sort($array1);\n    $array2 = str_split($procesada2);\n    sort($array2);\n\n    // Comparamos el resultado\n    return implode(\"\", $array1) === implode(\"\", $array2);\n}\n\n/**\n * isIsogram\n * Comprueba si una palabra es isograma (no repite ninguna letra).\n */\nfunction isIsogram($word) {\n    // Convertimos a minúsculas y quitamos espacios\n    $procesada = strtolower(preg_replace(\"/\\s+/\", \"\", $word));\n    // Dividimos en caracteres\n    $letras = str_split($procesada);\n    // Si el número de letras es el mismo que el número de letras únicas, es isograma\n    return count($letras) === count(array_unique($letras));\n}\n\necho \"-------------------------------------<br>\";\necho \"   COMPROBACIONES ESPECIALES<br>\";\necho \"<br>\";\necho \"Palabra 1: $palabra1<br>\";\necho \"Palabra 2: $palabra2<br><br>\";\n\n// Palíndromos\necho \"¿Palabra 1 es palíndromo? \" . (isPalindrome($palabra1) ? \"Sí<br>\" : \"No<br>\");\necho \"¿Palabra 2 es palíndromo? \" . (isPalindrome($palabra2) ? \"Sí<br>\" : \"No<br>\");\n\n// Anagramas\necho \"¿Son anagramas? \" . (isAnagram($palabra1, $palabra2) ? \"Sí<br>\" : \"No<br>\");\n\n// Isogramas\necho \"¿Palabra 1 es isograma? \" . (isIsogram($palabra1) ? \"Sí<br>\" : \"No<br>\");\necho \"¿Palabra 2 es isograma? \" . (isIsogram($palabra2) ? \"Sí<br>\" : \"No<br>\");\n\n?>\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/php/eulogioep.php",
    "content": "<?php\n// Operaciones con cadenas en PHP\n\n// Declaración de una cadena\n$texto = \"Hola, mundo!\";\n\necho \"Texto original: $texto\\n\";\n\n// 1. Acceso a caracteres específicos\necho \"1. Primer carácter: \" . $texto[0] . \"\\n\";\n\n// 2. Subcadenas\necho \"2. Subcadena: \" . substr($texto, 0, 4) . \"\\n\";\n\n// 3. Longitud\necho \"3. Longitud: \" . strlen($texto) . \"\\n\";\n\n// 4. Concatenación\n$otraCadena = \" Bienvenidos\";\necho \"4. Concatenación: \" . $texto . $otraCadena . \"\\n\";\n\n// 5. Repetición\necho \"5. Repetición: \" . str_repeat($texto, 3) . \"\\n\";\n\n// 6. Recorrido\necho \"6. Recorrido:\\n\";\nfor ($i = 0; $i < strlen($texto); $i++) {\n    echo $texto[$i] . \"\\n\";\n}\n\n// 7. Conversión a mayúsculas y minúsculas\necho \"7. Mayúsculas: \" . strtoupper($texto) . \"\\n\";\necho \"   Minúsculas: \" . strtolower($texto) . \"\\n\";\n\n// 8. Reemplazo\necho \"8. Reemplazo: \" . str_replace(\"mundo\", \"PHP\", $texto) . \"\\n\";\n\n// 9. División\n$palabras = explode(\", \", $texto);\necho \"9. División: \" . print_r($palabras, true) . \"\\n\";\n\n// 10. Unión\n$arrayPalabras = [\"PHP\", \"es\", \"genial\"];\necho \"10. Unión: \" . implode(\" \", $arrayPalabras) . \"\\n\";\n\n// 11. Interpolación (PHP usa comillas dobles para interpolación)\n$nombre = \"Alice\";\n$edad = 30;\necho \"11. Interpolación: Me llamo $nombre y tengo $edad años.\\n\";\n\n// 12. Verificación\necho \"12. Empieza con 'Hola': \" . (strpos($texto, \"Hola\") === 0 ? \"true\" : \"false\") . \"\\n\";\necho \"    Termina con '!': \" . (substr($texto, -1) === \"!\" ? \"true\" : \"false\") . \"\\n\";\necho \"    Contiene 'mundo': \" . (strpos($texto, \"mundo\") !== false ? \"true\" : \"false\") . \"\\n\";\n\n// 13. Recorte de espacios\n$textoConEspacios = \"  Hola Mundo  \";\necho \"13. Recorte de espacios: '\" . trim($textoConEspacios) . \"'\\n\";\n\n// 14. Extracción de subcadenas\necho \"14. Extracción (substring): \" . substr($texto, 0, 4) . \"\\n\";\n\n// 15. Búsqueda de posición\necho \"15. Posición de 'mundo': \" . strpos($texto, \"mundo\") . \"\\n\";\n\n// DIFICULTAD EXTRA\necho \"\\nDIFICULTAD EXTRA:\\n\";\n\n$palabra1 = \"amor\";\n$palabra2 = \"roma\";\n\necho \"Palabra 1: $palabra1\\n\";\necho \"Palabra 2: $palabra2\\n\";\n\n// Función para verificar si una palabra es un palíndromo\nfunction esPalindromo($palabra) {\n    return $palabra === strrev($palabra);\n}\n\n// Función para verificar si dos palabras son anagramas\nfunction sonAnagramas($palabra1, $palabra2) {\n    $palabra1 = strtolower($palabra1);\n    $palabra2 = strtolower($palabra2);\n    return count_chars($palabra1, 1) === count_chars($palabra2, 1);\n}\n\n// Función para verificar si una palabra es un isograma\nfunction esIsograma($palabra) {\n    return strlen($palabra) === count(array_unique(str_split(strtolower($palabra))));\n}\n\necho \"¿Son palíndromos? \" . \n     (esPalindromo($palabra1) ? \"true\" : \"false\") . \", \" . \n     (esPalindromo($palabra2) ? \"true\" : \"false\") . \"\\n\";\necho \"¿Son anagramas? \" . (sonAnagramas($palabra1, $palabra2) ? \"true\" : \"false\") . \"\\n\";\necho \"¿Son isogramas? \" . \n     (esIsograma($palabra1) ? \"true\" : \"false\") . \", \" . \n     (esIsograma($palabra2) ? \"true\" : \"false\") . \"\\n\";\n\n?>"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/php/gabrielmoris.php",
    "content": "<?php\n/* EXERCISE:\n* Show examples of all the operations you can perform with strings in your language. Some of these operations could include (search for as many as you can):\n* - Accessing specific characters\n* - Substrings\n* - Length\n* - Concatenation\n* - Repetition\n* - Iteration\n* - Conversion to uppercase and lowercase\n* - Replacement\n* - Division\n* - Joining\n* - Interpolation\n* - Verification\n*/\n$string = \"Hello, World!\";\n$string2 = \"\";\n$third_char = $string[2]; // Access Char\n$substring = substr($string, 5, 7); // Extract part of the string\n$length = strlen($string); // check lenght\n$dramatice = $string . \"!!!!!\"; // Concatenate\n$stars = str_repeat(\"*\", 5); // Generates *****\nfor ($i = 0; $i < strlen($string); $i++) { // Iteration\n    $string2 .= $string[$i]; // Prints each character\n}\n$uppercase = strtoupper($string2); // uppercase\n$lowercase = strtolower($string2); // lowercase\n$replacement = str_replace(\"World\", \"Gabriel\", $string2); // replace\n$array = explode(\",\", $replacement); // create an array using the regex as a separatore\n$join = implode(\"\", $array); // joins an array\n$interpolate = \"$join. I hope you had a nice day!\";\n$verification = strpos($interpolate, \"Gabriel\"); // gives the index back or false if it is not in the string\n$reverse = strrev($interpolate);\n\n/* EXTRA CHALLENGE (optional):\n* Create a program that analyzes two different words and checks if they are:\n* - Palindromes\n* - Anagrams\n* - Isograms\n*/\n\nfunction sort_string($string)\n{\n    $arr = str_Split($string);\n    sort($arr); // It sorts in the original variable. Doesn't return.\n    $string_worked = implode($arr);\n    return $string_worked;\n}\n\nfunction is_isogram($string)\n{\n    $sorted_str = sort_string($string);\n\n    for ($i = 0; $i < strlen($sorted_str) - 1; $i++) {\n        if ($sorted_str[$i] == $sorted_str[$i + 1]) {\n            return false;\n        }\n    }\n    return true;\n}\n\nfunction str_check($str1, $str2)\n{\n    if (strrev($str1) == $str1) {\n        echo \"$str1 is a Palindrome.\\n\";\n    }\n    if (strrev($str2) == $str2) {\n        echo \"$str2 is a Palindrome.\\n\";\n    }\n\n    if (sort_string($str1) == sort_string($str2)) {\n        echo \"$str1 and $str2 are Anagrams.\\n\";\n    }\n\n    if (is_isogram($str1)) {\n        echo \"$str1 is a Isogram.\\n\";\n    }\n\n    if (is_isogram($str2)) {\n        echo \"$str1 is a Isogram.\\n\";\n    }\n}\n\nstr_check(\"manam\", \"maman\");\nstr_check(\"abcde\", \"aba\");\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/php/kodenook.php",
    "content": "<?php\n\ndeclare(strict_types = 1);\n\n$txt = 'hello, php!';\n\necho strlen($txt), PHP_EOL;\necho str_word_count($txt), PHP_EOL;\necho strpos($txt, ', p'), PHP_EOL;\necho strtoupper($txt), PHP_EOL;\necho strtolower($txt), PHP_EOL;\necho str_replace('hello', 'dolly', $txt), PHP_EOL;\necho strrev($txt), PHP_EOL;\necho trim($txt), PHP_EOL;\necho substr($txt, 4, 8), PHP_EOL;\necho var_dump(count_chars($txt, 1)), PHP_EOL;\n\n/**\n * The function checks if a word is a palindrome, an anagram of another word, or an isogram.\n *\n * @param string word The \"word\" parameter is a string that represents a word.\n * @param string word2 The parameter `word2` is a string that represents the second word that will be\n * compared with `word` to check if they are anagrams.\n */\nfunction wordType(string $word, string $word2): void {\n\n    if ($word === strrev($word)) {\n        echo 'is palindrome', PHP_EOL;\n    }\n\n    if (count_chars($word, 3) === count_chars($word2, 3)) {\n        echo 'is an anagram', PHP_EOL;\n    }\n\n    if (strlen($word) === strlen(count_chars($word, 3))) {\n        echo 'is isogram', PHP_EOL;\n    }\n}\n\nwordType('reconocer', 'roma');"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/php/marcode24.php",
    "content": "<?php\n/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\n// Operaciones comunes con cadenas de caracteres\n\n// Acceso a caracteres específicos\n$cadena = 'Hola, mundo!';\necho 'Carácter en la posición 0: ' . $cadena[0] . PHP_EOL;\n\n// Subcadenas\n$subcadena = substr($cadena, 2, 4);\necho 'Subcadena: ' . $subcadena . PHP_EOL;\n\n// Longitud de la cadena\necho 'Longitud de la cadena: ' . strlen($cadena) . PHP_EOL;\n\n// Concatenación\n$otraCadena = ' Qué tal?';\n$cadenaConcatenada = $cadena . $otraCadena;\necho 'Cadena concatenada: ' . $cadenaConcatenada . PHP_EOL;\n\n// Repetición\n$cadenaRepetida = str_repeat($cadena, 3);\necho 'Cadena repetida 3 veces: ' . $cadenaRepetida . PHP_EOL;\n\n// Recorrido\nfor ($i = 0; $i < strlen($cadena); $i++) {\n  echo 'Carácter en posición ' . $i . ': ' . $cadena[$i] . PHP_EOL;\n}\n\n// Conversión a mayúsculas y minúsculas\n$mayusculas = strtoupper($cadena);\n$minusculas = strtolower($cadena);\necho 'Mayúsculas: ' . $mayusculas . PHP_EOL;\necho 'Minúsculas: ' . $minusculas . PHP_EOL;\n\n// Reemplazo\n$nuevaCadena = str_replace('mundo', 'amigo', $cadena);\necho 'Cadena con reemplazo: ' . $nuevaCadena . PHP_EOL;\n\n// División\n$palabras = explode(' ', $cadena);\necho 'Palabras divididas: ' . implode(', ', $palabras) . PHP_EOL;\n\n// Unión\n$union = implode('-', $palabras);\necho 'Palabras unidas con guiones: ' . $union . PHP_EOL;\n\n// Interpolación\n$nombre = 'Juan';\n$edad = 30;\n$mensaje = \"Hola, me llamo $nombre y tengo $edad años.\";\necho 'Mensaje interpolado: ' . $mensaje . PHP_EOL;\n\n// Verificación\n$contieneHola = strpos($cadena, 'Hola') !== false;\necho \"¿La cadena contiene 'Hola'? \" . ($contieneHola ? 'Sí' : 'No') . PHP_EOL;\n\n// Programa que verifica palíndromos, anagramas e isogramas\n\nfunction esPalindromo($palabra) {\n  $palabraInvertida = strrev($palabra);\n  return $palabra === $palabraInvertida;\n}\n\nfunction esAnagrama($palabra1, $palabra2) {\n  $ordenPalabra1 = str_split($palabra1);\n  $ordenPalabra2 = str_split($palabra2);\n  sort($ordenPalabra1);\n  sort($ordenPalabra2);\n  return $ordenPalabra1 === $ordenPalabra2;\n}\n\nfunction esIsograma($palabra) {\n  $caracteresUnicos = array_unique(str_split($palabra));\n  return count(str_split($palabra)) === count($caracteresUnicos);\n}\n\n// Ejemplos\n$palabra1 = 'oso';\n$palabra2 = 'soso';\necho \"\\\"$palabra1\\\" es palíndromo: \" . (esPalindromo($palabra1) ? 'Sí' : 'No') . PHP_EOL;\necho \"\\\"$palabra1\\\" es anagrama de \\\"$palabra2\\\": \" . (esAnagrama($palabra1, $palabra2) ? 'Sí' : 'No') . PHP_EOL;\necho \"\\\"$palabra1\\\" es isograma: \" . (esIsograma($palabra1) ? 'Sí' : 'No') . PHP_EOL;\n\n// Visita mi repo en GitHub para ver y correr los tests de este código --> https://github.com/marcode24/weekly-challenges\n\n?>\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/php/miguelex.php",
    "content": "<?php\n\n// Vamos a hacer un script que muestre todas las operacioens sobre cadenas que existen en php\n\n// 1. Concatenar cadenas\n$cadena1 = \"Hola\";\n$cadena2 = \"Mundo\";\n$cadena3 = $cadena1 . \" \" . $cadena2;\necho $cadena3 . \"\\n\";\n\n// 2. Longitud de una cadena\necho strlen($cadena3) . \"\\n\";\n\n// 3. Mostrar o no mostrar caracteres\necho substr($cadena3, 0, 5) . \"\\n\";\necho substr($cadena3, 5, 5) . \"\\n\";\n\n// 4. Buscar una cadena dentro de otra\necho strpos($cadena3, \"Mundo\") . \"\\n\";\necho strpos($cadena3, \"mundo\") . \"\\n\";\n\n// 5. Reemplazar una cadena por otra\necho str_replace(\"Mundo\", \"Universo\", $cadena3) . \"\\n\";\n\n// 6. Convertir a mayúsculas y minúsculas\necho strtoupper($cadena3) . \"\\n\";\necho strtolower($cadena3) . \"\\n\";\n// 7. Dividir una cadena en array\n$cadena4 = \"Hola Mundo\";\n$cadena5 = explode(\" \", $cadena4);\necho $cadena5[0] . \"\\n\";\necho $cadena5[1] . \"\\n\";\n\n// 8. Convertir un array en una cadena\n$cadena6 = implode(\" \", $cadena5);\necho $cadena6 . \"\\n\";\n\n// 9. Eliminar espacios en blanco\n$cadena7 = \" Hola Mundo \";\necho trim($cadena7) . \"\\n\";\n\n// 10. Eliminar etiquetas HTML\n$cadena8 = \"<h1>Hola Mundo</h1>\";\necho strip_tags($cadena8) . \"\\n\";\n\n// 11. Convertir caracteres especiales en entidades HTML\n$cadena9 = \"Hola Mundo\";\necho htmlentities($cadena9) . \"\\n\";\n\n// 12. Convertir entidades HTML en caracteres especiales\n$cadena10 = \"Hola Mundo\";\necho html_entity_decode($cadena10) . \"\\n\";\n\n// Funcion para comprobar si una cadena es palindroma\nfunction esPalindroma($cadena) {\n    $cadena = strtolower($cadena);\n    $cadena = str_replace(\" \", \"\", $cadena);\n    $cadenaInvertida = strrev($cadena);\n    if ($cadena == $cadenaInvertida) {\n        return true;\n    } else {\n        return false;\n    }\n}\n\n$resultado = esPalindroma(\"Dabale arroz a la zorra el abad\") ? \"Verdad\" : \"Falso\";\necho \"¿Es palindroma la cadena 'Dabale arroz a la zorra el abad'? ? $resultado\\n\";\n$resultado = esPalindroma(\"Esto deberia devolver falso\") ? \"Verdad\" : \"Falso\";\necho \"¿Esto deberia devolver falso'? ? $resultado\\n\";\n\n// Funcion para comprobar si es anagrama\nfunction esAnagrama($cadena1, $cadena2) {\n    $cadena1 = strtolower($cadena1);\n    $cadena2 = strtolower($cadena2);\n    $cadena1 = str_replace(\" \", \"\", $cadena1);\n    $cadena2 = str_replace(\" \", \"\", $cadena2);\n    $cadena1 = str_split($cadena1);\n    $cadena2 = str_split($cadena2);\n    sort($cadena1);\n    sort($cadena2);\n    $cadena1 = implode(\"\", $cadena1);\n    $cadena2 = implode(\"\", $cadena2);\n    if ($cadena1 == $cadena2) {\n        return true;\n    } else {\n        return false;\n    }\n}\n\n$resultado = esAnagrama(\"roma\", \"amor\") ? \"Verdad\" : \"Falso\";\necho \"¿Es anagrama la cadena 'roma' y 'amor'? ? $resultado\\n\";\n$resultado = esAnagrama(\"Paco\", \"capa\") ? \"Verdad\" : \"Falso\";\necho \"¿Es anagrama la cadena 'Paco' y 'capa'? ? $resultado\\n\";\n\n// Funcion para comproabr si una cadena es isograma\nfunction esIsograma($cadena) {\n    $cadena = strtolower($cadena);\n    $cadena = str_replace(\" \", \"\", $cadena);\n    $cadena = str_split($cadena);\n    $cadena = array_count_values($cadena);\n    foreach ($cadena as $valor) {\n        if ($valor > 1) {\n            return false;\n        }\n    }\n    return true;\n}\n\n$resultado = esIsograma(\"murcielago\") ? \"Verdad\" : \"Falso\";\necho \"¿Es isograma la cadena 'murcielago'? $resultado\\n\";\n$resultado = esIsograma(\"murcielagoo\") ? \"Verdad\" : \"Falso\";\necho \"¿Es isograma la cadena 'murcielagoo'? $resultado\\n\";\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/php/qv1ko.php",
    "content": "<?php\n\n    program(\"incapable\", \"display\");\n\n    function program($word1, $word2) {\n\n        echo isPalindrome($word1) ? \"The word $word1 is a palindrome\\n\" : \"The word $word1 is not a palindrome\\n\";\n        echo isPalindrome($word2) ? \"The word $word2 is a palindrome\\n\" : \"The word $word2 is not a palindrome\\n\";\n\n        echo areAnagrams($word1, $word2) ? \"The words $word1 and $word2 are anagrams\\n\" : \"The words $word1 and $word2 are not anagrams\\n\";\n\n        echo isIsogram($word1) ? \"The word $word1 is an isogram\\n\" : \"The word $word1 is not an isogram\\n\";\n        echo isIsogram($word2) ? \"The word $word2 is an isogram\\n\" : \"The word $word2 is not an isogram\\n\";\n\n    }\n\n    function isPalindrome($word) {\n\n        $len = strlen($word);\n\n        for ($i = 0; $i < $len / 2; $i++) {\n            if ($word[$i] != $word[$len - $i - 1]) {\n                return false;\n            }\n        }\n\n        return true;\n\n    }\n\n    function areAnagrams($word1, $word2) {\n\n        if (strlen($word1) != strlen($word2)) {\n            return false;\n        }\n\n        $lettersWord1 = str_split($word1);\n        $lettersWord2 = str_split($word2);\n\n        sort($lettersWord1);\n        sort($lettersWord2);\n\n        return $lettersWord1 == $lettersWord2;\n\n    }\n\n    function isIsogram($word) {\n\n        $letters = [];\n\n        foreach (str_split($word) as $letter) {\n            if (in_array($letter, $letters)) {\n                return false;\n            }\n            $letters[] = $letter;\n        }\n\n        return true;\n\n    }\n\n?>\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/59822.py",
    "content": "''' 04 CADENAS DE CARACTERES'''\n\n### OPERACIONES CON CADENAS DE CARACTERES\n\n\n'''Strings'''\nstring = \"Hola mundo\"\ndouble_string = \"hola mundo\\nAdios para siempre\"\n\nprint(double_string)\n\n# 1. Concatenación de cadenas\nuno = \"holaa\"\ndos = \"mundo\"\nprint(uno + \" \" + dos)\n\n# 2. Repetición de cadenas\nprint((uno + \" \")* 3)\n\n# 3. Longitud de una cadena\nprint(len(uno))\n\n# 4. Acceso a un caracter\nprint(uno[0])\n\n# 5. Acceso a un rango de caracteres\n## SLICING\nprint(uno[:3])\nprint(uno[1:2])\nprint(uno[0:])\n\n# 6. Búsqueda de un caracter\nprint(\"a\" in uno)\nprint(\"w\" not in uno)\n\n# 7. Reemplazo de caracteres\nprint(uno.replace(\"h\", \"p\"))\n\n# 8. División\nprint(uno.split(\"a\"))\n\n# 9. Mayúsculas y minúsculas, y capilalización\nprint(uno.upper())\nprint(uno.lower())\nprint(\"hola pepe\".title()) # Primera letra en mayúscula\nprint(\"hola pepe\".capitalize()) # Primera letra en mayúscula de la oración\n\n# 10. Eliminación de espacios al principio y al final\nprint(\" hola pepe    \".strip())\n\n#11. Búsqueda al principio y al final\n## Devuelve True o False\nprint(uno.startswith(\"ho\"))\nprint(uno.endswith(\"aa\"))\n\n# 12. Búsqueda de posición\nprint(uno.find(\"a\"))\n\n# 13. Búsqueda de ocurrencias \n## Contar cuantas veces aparece un caracter\n\nprint(uno.count(\"a\"))\n\n# 14. Leer al reves\nprint(uno[::-1])\n\n\n''' Para printear '''\n\n# 1. Formateo de cadenas\nprint(\"Saludos desde {}, {}!\".format(\"latinoamerica\", \"Colombia\"))\n\n# 2. Formateo de cadenas con f-strings\nprint(f\"Saludos desde {uno}\")\n\n# 3. Pasar a lista\nprint(list(\"hola\"))\n\n# 4. Pasar a cadena la lista\nlista = [\"ok\",\"dlsad\", uno, \"jeje\"]\nprint(\" \".join(lista))\n\n'''Para diferentes tipos de datos'''\nhola = 9382195238945\nhola = int(hola)\nprint(hola)\n\n# Comprobacion \nnumbers = \"123456\"\nprint(uno.isalnum()) #Significa que son alfabeticos y/o numericos\nprint(uno.isalpha()) #Significa que son alfabeticos\nprint(numbers.isalpha()) #Significa que son alfabetico\nprint(numbers.isnumeric()) #Significa que no tiene números\n\n''' DIFICULTAD EXTRA\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n'''\n\ndef palabras(palabra1, palabra2):\n    igual = lambda x, y: x == y\n    if igual(palabra1, palabra2):\n        if palabra1 == palabra1[::-1]:\n            print(f\"{palabra1} es un palíndromo.\")\n        if sorted(palabra1) == sorted(palabra2):\n            print(f\"{palabra1} y {palabra2} son anagramas.\")\n    else: \n        print(f\"{palabra1} y {palabra2} no son iguales.\")\n    print(\"Finalización de programa\")\n\ndef isograma(palabra1):\n    lista = list(palabra1)\n    conjunto = set(lista)\n    \n    if len(conjunto) == len(lista):\n        print(f\"{palabra1} es un isograma.\")\n    else:\n        print(f\"{palabra1} no es un isograma.\")\n        \n            \npalabras(\"level\", \"leveeel\")\nisograma(\"level\")     \n        \n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/AChapeton.py",
    "content": "# Declarar strings\nmyString = 'Este es un string'\nmultipleString = 'Este es un string \\n de multiples \\n lineas'\nemptyString = ''\n\nprint(myString)\nprint(multipleString)\nprint(emptyString)\n\n# Metodos\n\n# capitalize() - Convierte la primera letra en mayuscula\nmyString.capitalize()\nprint(myString)\n\n# lower() - Convierte todos los caracteres en minusculas\nmyString.lower()\nprint(myString)\n\n# swapcase() - Conviertes todos los caracteres de mayusculas a minusculas y viceversa\nmultipleString.swapcase()\nprint(multipleString)\n\n# upper() - Convierte todos los caracteres a mayusculas\nmultipleString.upper()\nprint(multipleString)\n\n# isalmun - Devuelve True si todos los caracteres son alfanumericos\nprint(myString.isalnum())\n\n# isalpha() - Devuelve True si todos los caracteres son alfabeticos\nprint(myString.isalpha())\n\n# strip() - Elimina espacios en blanco\nwhiteSpace = '    mucho espacio        '\nprint(whiteSpace.strip())\n\n# join() - Devuelve una cadena unida por el elemento del primer parametro\nnumbers = [\"1\", \"2\", \"3\"]\nnewNumbers = \" - \".join(numbers)\nprint(newNumbers)\n\n# split() - Divide una cadena en subcadenas y las devuelve en una lista. Se dividen segun el elemento del primer parametro\nnames = \"Python,JavaScript,C\"\nnewNames = names.split(\",\")\nprint(newNames)\n\n\n# DIFICULTAD EXTRA\n\ndef esPalindroma(string1):\n  if(string1 == string1[::-1]):\n    print('Es palindroma')\n  else:\n    print('No es palindroma')\n\nesPalindroma('level')\n\ndef esAnagrama(string1, string2):\n  if(string1 == string2[::-1]):\n    print('{string1} es anagrama de {string2}')\n  else:\n    print('No son anagramas')\n\ndef esIsograma(string1):\n  letrasArray = string1.split()\n  letrasSet = set(letrasArray)\n  if(len(letrasArray) == len(letrasSet)):\n    print(\"Es anagrama\")\n  else:\n    print(\"No es anagrama\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/AbelPerezCollado.py",
    "content": "# Concatenar\ncadena = 'Hola' + ' ' + 'mundo'\n\n# Multiplicar\nceros = '0' * 10\n\n# Añadir\ncadena = 'Hola'\ncadena += ' '\ncadena += 'mundo'\n\n# Acceso a caracteres\ncadena = 'Me encanta programar'\nultimo_caracter = cadena [-1]\n\n# Subcadenas\nsubcadena = cadena[0:10]\nlongitud = len(cadena)\n\n\n#Dividir cadena\ndivision = cadena.split()\n\n# Unión\nunion = ' '.join(division)\n\n# Mayusculas minusculas\nmayusculas = cadena.upper()\nminusculas = cadena.lower()\n\n#Reemplazo\nreemplazo = cadena.replace('e','3').replace('a','4')\n\n# Interpolar o formatear\nlenguaje = 'Python'\ncadena = f'Mi lenguaje preferido de programación es {lenguaje}'\n\n# Verificacion\ncadena = '123456'\nprint(cadena.isdigit())\nprint('a' in cadena)\n\n# DIFICULTAD EXTRA\n\ndef es_palindromo(palabra : str):\n    p = palabra.lower()\n    if p == p[::-1]:\n        return True\n    else:\n        return False\n\ndef es_anagrama(p1: str, p2:str):\n    p1 = p1.lower()\n    p2 = p2.lower()\n    if not len(p1) == len(p2):\n        return False\n    else:\n        anagrama = True\n        for c in p1:\n            if c not in p2:\n                anagrama = False\n    return anagrama\n\ndef es_isograma(palabra: str,):\n    palabras_vistas = []\n    for p in palabra.lower():\n        if p not in palabras_vistas:\n            palabras_vistas.append(p)\n        else:\n            return False\n    return True\n\np1 = input('Introduce la primera palabra: ')\n\nprint(f'{p1} es un palindromo? -> {es_palindromo(p1)}')\nprint(f'{p1} es un isograma -> {es_isograma(p1)}')\np2 = input(\"Introduce la segunda palabra: \")\nprint(f'{p1} y {p2} son anagramas? -> {es_anagrama(p1,p2)}')\n    "
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/AgustinDamonte17.py",
    "content": "# ============================================\n# OPERACIONES CON CADENAS DE CARACTERES\n# ============================================\n\nprint(\"====== OPERACIONES CON CADENAS EN PYTHON ======\")\n\ntexto = \"Python es poderoso\"\n\n# Acceso a caracteres específicos\nprint(\"Primer carácter:\", texto[0])\nprint(\"Último carácter:\", texto[-1])\n\n# Subcadenas (slicing)\nprint(\"Subcadena [0:6]:\", texto[0:6])\nprint(\"Subcadena desde el 7:\", texto[7:])\nprint(\"Cada segundo carácter:\", texto[::2])\n\n# Longitud\nprint(\"Longitud:\", len(texto))\n\n# Concatenación\nsaludo = \"Hola \" + \"mundo\"\nprint(\"Concatenación:\", saludo)\n\n# Repetición\nrepetido = \"ja\" * 3\nprint(\"Repetición:\", repetido)\n\n# Recorrido\nprint(\"Recorrido por caracteres:\")\nfor letra in \"Hola\":\n    print(letra, end=\" \")\nprint()\n\n# Mayúsculas y minúsculas\nprint(\"Mayúsculas:\", texto.upper())\nprint(\"Minúsculas:\", texto.lower())\nprint(\"Capitalizado:\", texto.capitalize())\nprint(\"Título:\", texto.title())\nprint(\"Swapcase:\", texto.swapcase())\n\n# Reemplazo\nprint(\"Reemplazo:\", texto.replace(\"poderoso\", \"genial\"))\n\n# División y unión\npalabras = texto.split()\nprint(\"Split (división en lista):\", palabras)\nunido = \"-\".join(palabras)\nprint(\"Join (lista a cadena):\", unido)\n\n# Interpolación\nlenguaje = \"Python\"\nprint(f\"Interpolación con f-string: {lenguaje} es increíble\")\nprint(\"Interpolación con format: {} es genial\".format(lenguaje))\n\n# Verificación\nprint(\"¿Empieza con 'Python'?\", texto.startswith(\"Python\"))\nprint(\"¿Termina con 'poderoso'?\", texto.endswith(\"poderoso\"))\nprint(\"¿Contiene 'es'?\", \"es\" in texto)\nprint(\"¿Es alfanumérico?\", \"abc123\".isalnum())\nprint(\"¿Es alfabético?\", \"abc\".isalpha())\nprint(\"¿Está en minúsculas?\", \"python\".islower())\nprint(\"¿Está en mayúsculas?\", \"PYTHON\".isupper())\nprint(\"¿Es espacio?\", \"   \".isspace())\nprint(\"¿Es título?\", \"Hola Mundo\".istitle())\nprint()\n\n\n# ============================================\n# ANALIZADOR DE PALABRAS (DIFICULTAD EXTRA)\n# ============================================\n\ndef es_palindromo(palabra):\n    palabra = palabra.lower().replace(\" \", \"\")\n    return palabra == palabra[::-1]\n\ndef es_anagrama(p1, p2):\n    return sorted(p1.lower().replace(\" \", \"\")) == sorted(p2.lower().replace(\" \", \"\"))\n\ndef es_isograma(palabra):\n    letras = palabra.lower().replace(\" \", \"\")\n    return len(set(letras)) == len(letras)\n\nprint(\"====== ANALIZADOR DE PALABRAS ======\")\npalabra1 = input(\"Introduce la primera palabra: \").strip()\npalabra2 = input(\"Introduce la segunda palabra: \").strip()\n\n# Palíndromos\nprint(f\"¿'{palabra1}' es palíndromo?\", es_palindromo(palabra1))\nprint(f\"¿'{palabra2}' es palíndromo?\", es_palindromo(palabra2))\n\n# Anagramas\nprint(f\"¿'{palabra1}' y '{palabra2}' son anagramas?\", es_anagrama(palabra1, palabra2))\n\n# Isogramas\nprint(f\"¿'{palabra1}' es isograma?\", es_isograma(palabra1))\nprint(f\"¿'{palabra2}' es isograma?\", es_isograma(palabra2))\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/AlainMartz.py",
    "content": "#04 CADENAS DE CARACTERES\n\n\"\"\"\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n\"\"\"\n\n# Manipulación de casos y formato\n\nstring = \"ergO prOxy\"\nprint(f\"Este es la cadena original: {string}\")                   # String original\nprint(f\"Ahora se capitaliza la primera letra: {string.capitalize()}\")      # Convierte la primera letra a mayúscula\nprint(f\"Todas las letras en mayús: {string.upper()}\")           # Convierte la cadena a mayúsculas\nprint(f\"Todas las letras en minús: {string.lower()}\")           # Convierte la cadena a minúsculas            \nprint(f\"Invirtiendo minús y mayús: {string.swapcase()}\")        # Invierte mayús y minús\nprint(f\"Ahora, en formato título: {string.title()}\")           # Convierte la cadena a formato título\nprint(f\"Normalizado a minús: {string.casefold()}\")        # Normaliza a minús el texto de forma más agresiva que lower()\n\n# Alineación y relleno          \npalin = \"Jelenovi pivo nelej\"   \n\nprint(f\"Centrado de la frase con *: {palin.center(25,'*')}\")     # Centra el texto a un ancho determinado con caracteres determinados\nprint(f\"Centrado de la frase con -: {palin.center(25,'-')}\")     \nprint(f\"Centrado de la frase con \\\" \\\": {palin.center(25,' ')}\")     \nprint(f\"Ajuste por la izquierda: {palin.ljust(25,'*')}\")      # Ajusta el texto por la izquierda, rellenando con caracteres\nprint(f\"Ajuste por la derecha: {palin.rjust(25,'*')}\")      # Ajusta el texto por la derecha, rellenando con caracteres\nprint(f\"Agrega 0 al comienzo: {palin.zfill(25)}\")          # Añade 0 al comienzo de la cadena hasta rellenar un ancho determinado\n\n# Comprabaciones y validaciones \ns = \"123 por mi\"                \nprint(f\"¿Es {s} alfanumérico? {s.isalnum()}\")              # Comprueba si es alfanumérico\nprint(f\"¿Es {s} solo letras? {string.isalpha()}\")         # Comprueba si son letras\nprint(f\"¿Es {s} ASCII? {string.isascii()}\")         # Comprueba si es ASCII\ns2 = \"123\"                       \nprint(f\"¿Es {s2} decimal? {s.isdecimal()}\")            # Comprueba si es decimal\nprint(f\"¿Es {s2} un digito? {s.isdigit()}\")              # Comprueba si son digitos\nprint(f\"¿Es {s2} un id váldio? {string.isidentifier()}\")    # Comprueba si es un identificador válido / Un identificador es el nombre de la variable, puede ser Aa_09\nprint(f\"¿Está {s} en minús? {string.islower()}\")         # Devuelve True si todos los caracteres están en minús\nprint(f\"¿Es {s2}? {s.isnumeric()}\")            # Devuelve True si todos los caracteres son numéricos\nprint(f\"¿Es {s} imprimible? {string.isprintable()}\")     # Devuelve True si todos los caracteres son printables o si la cadena está vacía.\nprint(f\"¿Todo es \\\" \\\" en {s}? {string.isspace()}\")         # Devuelve True si todos los caracteres son espacios en blanco\nprint(f\"¿Está {s} en forma de título? {string.istitle()}\")         # Devuelve True si todas las palabras están en forma de título\nprint(f\"¿Está {s} en mayús? {string.isupper()}\")         # Devuelve True si todos los caracteres están en mayús\n\n# Búsqueda y conteo             \nx = \"Parangaricutirimicuaro\"             \nprint(f\"Cuantas veces aparece \\\"ar\\\": {x.count('ar')}\")            # Cuenta la ocurrencia de una subcadena\nprint(f\"El índice de la primera ocurrencia \\\"ga\\\" es: {x.find('ga')}\")             # Encuentra el índice de la primera ocurrencia de la subcadena\nprint(f\"El índice de la primera ocurrencia \\\"cua\\\" es: {x.index('cua')}\")           # Encuentra el índice de la primera ocurrencia, si no, lanza una excepción\nprint(f\"El índice de la última ocurrencia \\\"o\\\" es: {x.rfind('o')}\")             # Encuentra el índice de la última ocurrencia de la subcadena      \nprint(f\"El índice de la última ocurrencia \\\"a\\\" es: {x.rindex('a')}\")            # Última ocurrencia de la subcadena o lanza una excepción\nprint(f\"Comienza con \\\"Pa\\\": {x.startswith('Pa')}\")       # Comprueba si una cadena comienza con un prefijo\nprint(f\"Termina con \\\"ro\\\": {x.endswith('ro')}\")       # Comprueba si la cadena termina con un sufijo\nprint(f\"La extensión de {x} es: {len(x)}\")                   # Devuelve la extensión de la cadena\n\n# Transformaciones y reemplazos\n\ny = \"Charlotte\"\nprint(f\"Remplazando 't' por 'x' en {y}: {y.replace('t','x')}\")       # Reemplaza la ocurrencia de la subcadena\ntable = y.maketrans('aeiou','12345')    # Realiza una tabla de referencia para translate\nprint(f\"Reemplazando 'aeiou' por '12345': {y.translate(table)}\")       # Traduce según la tabla\n\n# División y unión\nz = \"Cantaba la noche con susurros de tristeza, en la mesa, el mate se enfriaba\"\nprint(z.split(sep=','))         # Divide la cadena en una lista de subcadenas. El parámetro sep indica un separador, el parámetro maxsplit indica un maximo de divisiones que puedan realizarse\nprint(z.rsplit('a'))            # Divide la cadena en subcadenas desde el final\nz = \"Cantaba la noche \\ncon susurros de tristeza\\n en la mesa\\n el mate se enfriaba\"\nprint(z.splitlines(keepends=False)) # Divide la cadena en una lista de líneas (salto de lineas, tabulaciones, etc...)\nz = \"Cantaba la noche con susurros de tristeza, en la mesa, el mate se enfriaba\"\nprint(z.partition(','))         # Divide la cadena en tres partes usando el separador\nprint(z.rpartition(','))        # Divide la cadena en tres partes usando el separador, comienza desde el final\nu = '-'\nprint(u.join(['Edipo','Rey']))  # Une un iterable de cadena con la cadena como delimitador\nprint(z[8:41])                  # Realiza un slice de la cadena, creando una subcadena\nprint('Edipo' + ' Rey')         # Concatenación de cadena con el operador +\nprint(u*3)                      # Multiplica la cadena con el operador *\nprint(f\"{y} y su inversión es: {y[::-1]}\") # El slicing [::-1] invierte el orden de la cadena\n\n\n# Eliminación de espacios y caracteres\nd = \"***oso***\"\nprint(d.strip('*'))             # Elimina los caracteres\nprint(d.lstrip('*'))            # Elimina los caracteres de la izquierda\nprint(d.rstrip('*'))            # Elimina los caracteres de la derecha\n\n# Codificación y expansión\ne = \"Der mishk kalen\"\nprint(e.encode(                 # Retorna la cadena codificada a bytes. Defecto = utf_8, posibles: ascii, utf_32....\n    encoding='utf-8',\n    errors='strict'\n))               \ne = \"Der\\t mishk\\t kalen\"\nprint(e.expandtabs(tabsize=15)) # Retorna una copia de la cadena, con los caracteres tipo tab \\t reemplazados por espacios.\n\n## Formato\n\n# Format\nprint(\"Since we're feeling {}\".format(\"so anesthetized\"))           # Formato posicional. Se utilizan los {} para formatear\nprint(\"In our comfort {name}\".format(name=\"zone\"))                  # Formato nombrado. Ademas de los {}, se llama una variable con el contenido del formato\nprint(\"Reminds {} the second {lt}\".format(\"me of\",lt=\"time\"))       # Mixto, posicional y nombrado\nprint(\"That I f{0}llow{1}d you h{0}m{1}\".format(\"o\",\"e\"))           # Con índices. En orden creciente, desde 0, se indican los parámetros \n\nprint(\"Binario: {0:b}, Hex: {0:x}, Octal: {0:o}\".format(42))        # Formato numérico \"Binary: 101010, Hex: 2a, Octal: 52\"\nprint(\"Número formateado: {:.3f}\".format(3.14159))                  # Formato numérico con decimales. 3f siginifica 3 float, o 3 decimales\n\n# format_map\nletra = {\"4f\":\"We're running out of alibis\", \"5f\":\"On the second of may\"}\nprint(\"{4f}\\n{5f}\".format_map(letra))                               # Usa las keys en los {} y devuielve los valores de las keys    \n\n# f-string\nletra =  \"of the summertime\"\nprint(f\"Reminds me {letra}\")                                        # Pasando una variable entre los {}\na = \"winters\"\nb = \" day\"\nprint(f\"On this {a + b}\")                                           # Utilizando expresiones dentro del formateo\npi = 3.14159\nprint(f\"Pi es: {pi:2f}\")                                            # Formato numérico con dos decimales\n\n# Operador %\nletra = \"See you at the bitter end\"\ncaracteres = 25\ndivision = 25/106\nprint(\"%s es una frase que contiene %d caracteres que corresponden al %.2f de este mensaje\" %(letra,caracteres,division))\n\n\n## Desafio extra ##\n\"\"\"\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos    anna > Palabra que se espeja, por ejemplo, an|na\n * - Anagramas      nana > Palabra con la que puede formarse otra anna -> nana | odio -> oido\n * - Isogramas      abcd > Palabra en la que no se repite ni una letra, o, en la que se repiten todas las letras el mismo número de veces\n\"\"\"\n\nfrom collections import Counter\n\ndef anagrama(w1,w2):\n    w1 = \"\".join(c.lower() for c in w1 if c.isalpha())\n    w2 = \"\".join(c.lower() for c in w2 if c.isalpha())    \n    # Quitar caracteres no alfanumericos \n    # w1 = w1.lower().replace(\" \",\"\").replace(\"-\",\"\").replace(\"/\",\"\")\n    # w2 = w2.lower().replace(\" \",\"\").replace(\"-\",\"\").replace(\"/\",\"\")\n    \n    if len(w1) != len(w2):\n        return (\"Las palabras no son anagrama\")\n    \n    counterw1 = Counter(w1)\n    counterw2 = Counter(w2)\n\n    # Contar palabras sin Counter\n    # for l1,L2 in zip(w1,w2):\n    #     if l1 in counterw1:\n    #         counterw1[l1] += 1\n    #     else:\n    #         counterw1[l1] = 1  \n    #     if l2 in counterw2:\n    #         counterw2[l2] += 1\n    #     else:\n    #         counterw2[l2] = 1\n\n    if counterw1 == counterw2:   \n        return print(\"Las palabras son anagrama\")\n    \n    return print(\"Las palabras no son anagrama\")\n\nanagrama(\"an/na\",\"nana-\")\nanagrama(\"odio\",\"oido\")\nanagrama(\"pajaro\",\"jarron\")\n\nimport re\n\ndef palindromo(word):\n    word = re.sub(r'[^a-zA-Z]','',word.lower())  # re.sub(rule, replace, string)\n# Otras formas de quitar los caracteres\n#   word = \"\".join(c.lower() for c in word if c.isalpha())\n#   word = word.lower().replace(\" \",\"\").replace(\"-\",\"\").replace(\"/\",\"\").replace(\",\",\"\").replace(\";\",\"\").replace(\":\",\"\")\n    revword = word[::-1]\n\n    if len(word) == 0:\n        return print (f\"La palabra \\\"{word}\\\" está vacía o no contiene caracteres alfanuméricos\")\n\n    if word == revword:\n        return print (f\"La palabra \\\"{word}\\\" es palíndromo\")\n    \n    return print (f\"La palabra no es palíndromo: \\\"{word}\\\" != \\\"{revword}\\\"\")\n\n\npalindromo(\"anna\")\npalindromo(\"As I pee sir, I see Pisa\")\npalindromo(\"oceano\")\npalindromo(\"---   \")\n\n\ndef isograma(word):\n    word = re.sub(r'[^a-zA-Z]','',word.lower())  # re.sub(rule, replace, string)\n    cword = Counter(word)\n    repword = []\n\n    if len(set(list(cword.values()))) == 1:\n        return print (f\"La palabra \\\"{word}\\\" es isograma\")\n    \n    repword = [l for l,f in cword.items() if f > 1]\n\n    repword_count = {l: cword[l] for l in repword}\n\n    return print (f\"La palabra \\\"{word}\\\" no es isograma, se repite: {repword_count}\")\n\nisograma(\"murcielago\")\nisograma(\"gaga\")\nisograma(\"programming\")\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/Aldroide.py",
    "content": "\"\"\"\nMuestra ejemplos de las operaciones con cadenas de caracteres\nAcceso a caracteres especificos, subcadenas, longitud, concatenación\nrepetición, recorrido\nConversión a mayusculas y minusculas, reemplazo división, union, interpolación\nverificación etc\n\"\"\"\n\n# Concatenación\ncad_1 = \"Hola\"\ncad_2 = \" mundo\"\nconcatena = cad_1+cad_2\nprint(concatena)\n\n# Replica de una cadena\ncadena = \"Hola \"\nresultado = cadena * 3\nprint(resultado)\n\n# Longitud de una cadena\ncadena = \"Hola Python\"\nlongitud = len(cadena)\nprint(longitud)\n\n# Acceso a caracteres\ncadena = \"Hola Python\"\nprimer_caracter = cadena[0]\nsexto_caracter = cadena[5]\nprint(primer_caracter, sexto_caracter)\n\n# Acceso a caracteres\nultimo_caracter = cadena[-1]\nanteultimo_caracter = cadena[-2]\nprint(ultimo_caracter, anteultimo_caracter)\n\n# subcadena\ncadena = \"Python hello\"\nsubcadena = cadena[4:9]\nprint(subcadena)\n\n\ncadena = \"Hola, Mundo!\"\nPalabras = [\"hola\", \"mundo\", \"python\"]\n\n# Poner en mayúsculas toda la cadena\nmayusculas = cadena.upper()\nprint(mayusculas)\n\n# Poner en minúsculas toda la cadena\nminusculas = cadena.lower()\nprint(minusculas)\n\n# Quitar los espacios a la cadena\nsin_espacios = cadena.strip()\nprint(sin_espacios)\n\n# Reeplazar la cadena o parte de la cadena\nreemplazar = cadena.replace(\"Hola\", \"Saludos\")\nprint(reemplazar)\n\n# Separar en cadenas\nsepara = cadena.split(\" \")\nprint(separa)\n\n# Unir varias cadenas de texto\nunir = \" \".join(Palabras)\nprint(unir)\n\n# interpolación de varaibles\nnombre = \"Aldroide\"\nedad = 40\ninterpolar = f\"Soy {nombre} y tengo {edad} años\"\nprint(interpolar)\n\n# Revisar si es numero o digito\nmi_numero = \"123435\"\nprint(mi_numero.isdigit())\nprint(mi_numero.isnumeric())\n\ncadena = \"Aldroide\"\nprint(cadena.isalpha())\nprint(cadena.isalnum())\nprint(cadena.startswith(\"R\"))\nprint(cadena.endswith(\"f\"))\nprint(cadena.islower())\nprint(cadena.isupper())\nprint(cadena.isspace())\n\ncadena = \"esta cadena inicia en minúscula\"\nprint(cadena.capitalize())\n\n\n\"\"\"\nEjercicio extra \nCrear un programa que analice dos palabras diferentes\ny realice comprobaciones para descubrir si son:\n * Palindromos\n * Anagramas\n * Isogramas\n\"\"\"\n\n\ndef palindromo(palabra):\n    palabra = palabra.lower().replace(\" \", \"\")\n    return palabra == palabra[::-1]\n\n\ndef anagrama(palabra1, palabra2):\n    palabra1 = palabra1.lower().replace(\" \", \"\")\n    palabra2 = palabra2.lower().replace(\" \", \"\")\n    return sorted(palabra1) == sorted(palabra2)\n\n\ndef isograma(palabra):\n    palabra = palabra.lower().replace(\" \", \"\")\n    return len(set(palabra)) == len(palabra)\n\n\npalabra1 = input(\"Introduce la primera palabra: \")\npalabra2 = input(\"Introduce la segunda palabra: \")\n\nprint(\n    f\"La palabra {palabra1} ¿Es anagrama de {palabra2}?: {anagrama(palabra1, palabra2)}\")\nprint(f\"La palabra {palabra1} ¿Es palindromo?: {palindromo(palabra1)}\")\nprint(f\"La palabra {palabra2} ¿Es palindromo?: {palindromo(palabra2)}\")\nprint(f\"La palabra {palabra1} ¿Es isograma?: {isograma(palabra1)}\")\nprint(f\"La palabra {palabra2} ¿Es isograma?: {isograma(palabra2)}\")\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/Aleran07.py",
    "content": "# 04\n'''\nOperaciones con cadenas de caracteres\n'''\n\n# Creacion y concatenacion\na = \"Hola\"\nb = \"Mundo\"\nc = a + \" \" + b        # Concatenación → 'Hola Mundo'\nd = a * 3              # Repetición → 'HolaHolaHola'\n\n\n# Indexación y segmentación (slicing)\ntexto = \"Python\"\ntexto[0]      # 'P' → primer carácter\ntexto[-1]     # 'n' → último carácter\ntexto[0:3]    # 'Pyt' → desde 0 hasta antes del 3\ntexto[2:]     # 'thon' → desde 2 hasta el final\ntexto[:4]     # 'Pyth' → desde el inicio hasta antes del 4\ntexto[::-1]   # 'nohtyP' → invertir cadena\n\n\n#Búsqueda y verificación\ntexto = \"programar en python\"\n\n\"python\" in texto       # True → verifica si existe\n\"java\" not in texto     # True → verifica si no existe\ntexto.find(\"python\")    # 13 → índice donde empieza\ntexto.rfind(\"n\")        # última aparición de 'n'\ntexto.startswith(\"pro\") # True\ntexto.endswith(\"on\")    # True\n\n# Modificación de contenido\ntexto = \"hola mundo\"\n\ntexto.upper()        # 'HOLA MUNDO'\ntexto.lower()        # 'hola mundo'\ntexto.title()        # 'Hola Mundo'\ntexto.capitalize()   # 'Hola mundo'\nprint(texto.swapcase())     # 'HOLA MUNDO' → 'hola mundo'\ntexto.replace(\"mundo\", \"Python\")  # 'hola Python'\n\n# Eliminación de espacios o caracteres\ntexto = \"  hola mundo  \"\n\ntexto.strip()        # 'hola mundo' → elimina espacios a ambos lados\ntexto.lstrip()       # 'hola mundo  ' → elimina solo a la izquierda\ntexto.rstrip()       # '  hola mundo' → elimina solo a la derecha\ntexto.strip(\"o\")     # elimina las 'o' de los extremos → '  hola mund'\n\n\n#División y unión\ntexto = \"uno,dos,tres\"\n\ntexto.split(\",\")     # ['uno', 'dos', 'tres'] → divide por comas\ntexto.split()        # divide por espacios\n\"-\".join([\"uno\", \"dos\", \"tres\"])  # 'uno-dos-tres' → une con '-'\n\n# Información de la cadena\ntexto = \"Python\"\n\nlen(texto)           # 6 → longitud\ntexto.count(\"t\")     # 1 → cuántas veces aparece\n\n# Comprobaciones de tipo\n\"abc\".isalpha()      # True → solo letras\n\"123\".isdigit()      # True → solo dígitos\n\"abc123\".isalnum()   # True → letras y números\n\"hola mundo\".isspace()  # False → solo espacios\n\"HOLA\".isupper()     # True\n\"hola\".islower()     # True\n\"Hola Mundo\".istitle() # True\n\n# Alineación y formato\ntexto = \"Python\"\n\ntexto.center(10, \"-\")  # '--Python--'\ntexto.ljust(10, \".\")   # 'Python....'\ntexto.rjust(10, \".\")   # '....Python'\n\n# Formato de cadenas (interpolación)\nnombre = \"Brian\"\nedad = 24\n\n# Forma moderna (f-string)\nf\"Hola {nombre}, tienes {edad} años\"\n\n# Método format\n\"Hola {}, tienes {} años\".format(nombre, edad)\n\n# Índices\n\"Hola {0}, tienes {1} años\".format(nombre, edad)\n\n# Diccionario\n\"Hola {n}, tienes {e} años\".format(n=nombre, e=edad)\n\n# Métodos útiles adicionales\ntexto = \"Hola mundo\"\n\ntexto.encode()         # convierte a bytes\ntexto.expandtabs()     # reemplaza tabulaciones con espacios\ntexto.partition(\" \")   # ('Hola', ' ', 'mundo') → divide en 3 partes\ntexto.rpartition(\" \")  # divide desde el final\ntexto.zfill(10)        # '000Hola mundo' → rellena con ceros\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/AllanYSalazarG.py",
    "content": "\"\"\" #04 CADENAS DE CARACTERES \"\"\"\n\n\n# Cadenas Base\nstring = \"hola allan\"\nanotherString = \"hola python\"\nstringStrip = \"  hola allan  \"\n\n# Acceso a caracteres según indices\nprint(\"-- Acceso a caracteres según indices --\")\nprint(f\"{string}[0] = {string[0]}\")  # h\nprint(f\"{string}[:] = {string[:]}\")  # hola allan\nprint(f\"{string}[2:] = {string[2:]}\")  # la allan\nprint(f\"{string}[:5] = \\\"{string[:5]}\\\"\")  # \"hola \"\nprint(f\"{string}[-1] = {string[-1]}\")  # n\nprint(f\"{string}[::-1] = {string[::-1]}\")  # nalla aloh\n\n# Longitud\n\nprint(\"-- Longitud -- \")\nprint(f\"{string} tiene {len(string)} caracteres\")\n\n# Reccorrido con for\n\nprint(\"-- Recorrido con for --\")\nfor char in string:  # Orden normal del string\n    print(char, end=\", \")\n\nprint(\"\")\n\nfor char in string[::-1]:  # Orden inverso del string\n    print(char, end=\", \")\n\n# Concatenación\n\nprint(\"\\n-- Concatenación --\")\nprint(string + anotherString)  # Signo + con cadenas, concatena\nprint(f\"{string} - {anotherString}\")  # f string tambien concatena, da formato\n# Con join, lo que está entre comillas dobles es el separador\nstringList = list(string)\nprint(\"\".join(stringList))\n\n# Operaciones que regresan una copia de la cadena\nprint(\"-- Operaciones que regresan una copia de la cadena --\")\n# Regresa una copia de la cadena con el 1er caracter en Mayusculas\nprint(f\"{string}.capitalize() = {string.capitalize()}\")  # Hola allan\n# Regresa una copia de la cadena con el 1er caracter de cada palabra en Mayusculas\nprint(f\"{string}.title() = {string.title()}\")  # Hola Allan\n# Regresa una copia de la cadena con todos las caracteres en mayusculas\nprint(f\"{string}.upper() = {string.upper()}\")\n# Regresa una copia de la cadena con todos los caracteres en minusculas\nprint(f\"{string}.lower() = {string.lower()}\")\n# Regresa una copia de la cadena sin espacios a la izquierda\n# \"   hola allan   \" regresa \"holla allan   \"\nprint(f\"{stringStrip}.lstrip() = \\\"{stringStrip.lstrip()}\\\"\")\n# Regresa una copia de la cadena sin espacios a la derecha\n# \"   hola allan   \" regresa \"   holla allan\"\nprint(f\"{stringStrip}.rstrip() = \\\"{stringStrip.rstrip()}\\\"\")\n# Regresa una copia de la cadena sin espacios a la izquierda y derecha\n# \"   hola allan   \" regresa \"holla allan\"\nprint(f\"{stringStrip}.strip() = \\\"{stringStrip.strip()}\\\"\")\n# Regresa una copia de la cadena con el valor de la derecha reemplazando al de la izquierda\nprint(f\"{string}.replace(\\\"allan\\\",\\\"mundo\\\") = {\n      string.replace(\"allan\", \"mundo\")}\")\n\n# Operaciones que devuelven otra cosa como indices, booleanos o estructuras de datos\n\n# Regresa el indice menor donde se encuentra la cadena dentro de parentesis,\n# devuelve -1 si no encuentra una coincidencia\nprint(string.find(\"ho\"))  # 0\n# Igual que find, solo que si no encuentra coincidencia, devuelve un error\nprint(string.index(\"la\"))  # 2\n# Devuelve True si todos los caracteres son letras\nprint(string.isalpha())  # False (Porque tiene un espacio)\n# Regresa una tupla con 3 cadenas: anterior a ocurrencia, ocurrencia o separador, despues a ocurrencia\nprint(string.partition(\"a a\"))  # ('hol','a a','llan')\n# Regresa una lista con las palabras encontradas como cada valor\n# Recibe un separador cualquiera, si no se agrega, toma el espacio como separador\nprint(string.split())  # ['hola', 'allan']\n\n\n# ------------ EJERCIO ------------\n\nprint(\"\\n---------- EJERCICIO ----------\\n\")\n\n# Palabra/Frase sin espacios\n\n\ndef sentenceWithoutSpace(word):\n    return word.lower().replace(\" \", \"\")\n\n# Palíndromo\n\n\n\"\"\" Un palindromo es una palabra que se escribe igual al derecho y al reves\nPor ejemplo: reconocer\n\nEn la función, comparamos la misma cadena, una en su forma original y otra en su forma inversa \"\"\"\n\n\ndef palindrome(word):\n    word = sentenceWithoutSpace(word)\n    return word == word[::-1]\n\n\n# Anagrama\n\n\"\"\" Un anagrama es una palabra que con mover sus letras, puede crear otra distinta\nPor ejemplo: Amor y Roma\n\nEn la función, ordenamos las letras de dos palabras y comparamos si tienen las mismas letras\nvalidando que ambas palabras son anagramas \"\"\"\n\n\ndef anagram(firstWord, secondWord):\n    firstWord = sentenceWithoutSpace(firstWord)\n    secondWord = sentenceWithoutSpace(secondWord)\n    return sorted(firstWord) == sorted(secondWord)\n\n\n# Isograma\n\n\"\"\" Un isograma es una palabra cuyos caracteres son únicos.\nPor ejemplo: Murcielago\n\nEn la función, regresamos True o False\nComparamos el numero de caracteres la palabra\nLa primera toma el numero de caracteres de la palabra real\nla segunda toma el numero de caracteres del conjunto de la palabra real\n\nRecuerda que un conjunto almacena entre llaves los caracteres sin ordenar y sin repetir \"\"\"\n\n\ndef isogram(word):\n    word = sentenceWithoutSpace(word)\n    return len(word) == len(set(word))\n\n\n# Principal\n\n\ndef main():\n    firstWord = str(input(\"Ingresa la primer palabra: \"))\n    secondWord = str(input(\"Ingresa la segunda palabra: \"))\n    # Mensaje según el resultado de palindrome()\n    message = \"es Palindromo\" if palindrome(firstWord) else \"no es Palindromo\"\n    print(f\"{firstWord} {message}\")\n    # Mensaje segun el resultado de anagram()\n    message = \"son Anagramas\" if anagram(\n        firstWord, secondWord) else \"no son Anagramas\"\n    print(f\"{firstWord} y {secondWord} {message}\")\n    # Mensaje segun el resultado de isogram()\n    message = \"es Isograma\" if isogram(firstWord) else \"no es Isograma\"\n    print(f\"{firstWord} {message}\")\n\n\nmain()\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/Alvaro-Neyra.py",
    "content": "from unicodedata import normalize\n\n#Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\n# *   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\n# *   interpolación, verificación...\n\n## Acceso a caracteres especificos:\ncadena = \"Hola, Mundo!\"\nletra_a = cadena[3]\nprint(f\"Este es un caracter perteneciente a la cadena 'Hola, Mundo!': {letra_a}\")\n\n## Subcadenas\n### Se usa la tecnica llamada slicing:\notra_cadena = \"Esta es una cadena que es tratada como ejemplo\"\nque_es = otra_cadena[:19]\nprint(f\"Esta es una subcadena y pertenece a la cadena 'otra_cadena': {que_es}\")\n\n## logitud\nlongitud_otra_cadena = len(otra_cadena)\nprint(f\"Esta es la cantidad de caracteres de 'otra_cadena', usamos la funcion integrada `len()`: {longitud_otra_cadena}\")\n\n## concatenacion\ncadena_ejemplo1 = \"Esta es la cadena 1\"\ncadena_ejemplo2 = \"Esta es la cadena 2\"\ncadena_concatenada = cadena_ejemplo1 + \" \" + \"y\" + \"\" + cadena_ejemplo2\nprint(f\"Usamos el operador de suma (+) para concatenar strings 'para unirlos': {cadena_concatenada}\")\n\n## repeticion\ncadena_a_ser_repetida = \"hola \"\nmuchos_holas = cadena_a_ser_repetida * 8\nprint(f\"Esta es una cadena repetida usando el operador (*) de multiplicacion: {muchos_holas}\")\n\n## recorrido\ncadena_larga = \"Esta es una cadena larga que sera recorrida, te quiero MoureDev ❤️\"\nfor caracter in cadena_larga:\n    print(caracter)\n\n## conversion\nmi_cadena = \"Esta es una LinDa cadena\"\n### Convertir a uppercase\nmi_cadena_upper = mi_cadena.upper()\nprint(f\"Esta es la cadena declarada en su forma a uppercase: {mi_cadena_upper}\")\n### Convertir a lowercase\nmi_cadena_lower = mi_cadena.lower()\nprint(f\"Esta es la cadena declarada en su forma a lowercase: {mi_cadena_lower}\")\n### Convertir a capitalize\nmi_cadena_capitalize = mi_cadena.capitalize()\nprint(f\"Esta es la cadena declarada en su forma a capitalize: {mi_cadena_capitalize}\")\n\n## reemplazo\n### Reemplazar una subcadena de la cadena principal por otra:\ncadena_normal = \"Esta es una cadena normal que se usa para un ejemplo\"\ncadena_cambiada = cadena_normal.replace(\"normal\", \"RARA\")\nprint(f\"Esta es una cadena que reemplaza una subcadena de la cadena principal: {cadena_cambiada}\")\n\n## division\n### Dividir los caracteres o subcadenas de la cadena principal usando .split():\ncadena_a_dividir = \"Hola esta es una cadena que sera dividida.\"\ncadena_dividida = cadena_a_dividir.split(\" \")\nprint(f\"Esta es una lista con todos las subcadenas que fueron divididas usando .split(): {cadena_dividida}\")\n\n## union\n### Unir cadenas de una lista usando el metodo .join(): Cada caracter o elemento de la lista se concatenara junto a la cadena especificada\n### como objeto que usa el metodo.\nlista_de_cadenas = [\"Python\", \"es\", \"un\", \"lenguaje\", \"de\", \"programacion\"]\ncadena_unida = \" \".join(lista_de_cadenas)\nprint(f\"Esta es la cadena unida usando el metodo .join(): {cadena_unida}\")\n\n## Interpolacion\n### Haciendo iterpolacion de cadenas usando el metodo .format()\nnombre = \"Alvaro\"\nedad = 19\ncadena_interpolada = \"Hola mi nombre es {1} y tengo {0}\".format(edad, nombre)\nprint(f\"Esta es la cadena iterpolada resultante usando el metodo .format(): {cadena_interpolada}\")\n\n## Verificacion\ncadena_numerica = \"21948190248102931\"\nes_numerica = cadena_numerica.isnumeric()\nprint(f\"Usando el metodo .isnumeric() podemos verificar si todos los elementos de la cadena son numeros. Devuelve un valor booleano: {es_numerica}\")\ncadena_con_digitos = \"123131439\"\ntiene_digitos = cadena_con_digitos.isdigit()\nprint(f\"Usando el metodo .isdigit() podemos verificar si todos los elementos de la cadena son digitos. Devuelve un valor booleano: {tiene_digitos}\")\ncadena_de_letras = \"HOLA ESTA ES UNA CADENA UPPERCASE\"\nes_alfabetico = cadena_de_letras.isalpha()\nprint(f\"Verifica si todos los caracteres de la cadena son alfabeticos, devuelve valor booleano: {es_alfabetico}\")\nes_alfanumerico = cadena_de_letras.isalnum()\nprint(f\"Verifica si todos los caracteres de la cadena son alfanumericos, devuelve valor booleano: {es_alfanumerico}\")\nempieza_con_H = cadena_de_letras.startswith(\"H\")\nprint(f\"Verifica si la cadena termina con 'H', devuelve valor booleano: {empieza_con_H}\")\ntermina_con_E = cadena_de_letras.endswith(\"E\")\nprint(f\"Verifica si la cadena termina con 'E', devuelve valor booleano: {termina_con_E}\")\nes_uppercase = cadena_de_letras.isupper()\nprint(f\"Verifica si la cadena es uppercase: {es_uppercase}\")\nes_lowercase = cadena_de_letras.islower()\nprint(f\"Verifica si la cadena es lowercase: {es_lowercase}\")\ntiene_espacios = cadena_de_letras.isspace()\nprint(f\"Verifica si la cadena contiene solo espacios en blanco, devuelve valor booleano: {tiene_espacios}\")\n\n## Busqueda:\nmy_string = \"Mi cadena de caracteres de Python\"\nencontrar_cadena = my_string.find(\"cadena\")\nprint(f\"Devuelve el primer numero de indice que coincide con la cadena pasada al metodo .find(): {encontrar_cadena}\")\ndame_index = my_string.rfind(\"caracteres\")\nprint(f\"Devuelve la primera posicion de la coincidencia pasada: {dame_index}\")\nmi_indice = my_string.index(\"c\")\nprint(f\"Devuelve el indice de la primera coincidencia encontrada: {mi_indice}\")\ncontar_letras_e = my_string.count(\"e\")\nprint(f\"Contar las coincidencias encontradas en la cadena: {contar_letras_e}\")\n\n# DIFICULTAD EXTRA (opcional):\ndef anagrama(string1: str, string2 : str):\n    anagrama1 = string1.replace(\" \", \"\").lower()\n    anagrama2 = string2.replace(\" \", \"\").lower()\n    return sorted(anagrama1) == sorted(anagrama2)\n\ndef palindroma(string1 : str):\n    trans_tab = dict.fromkeys(map(ord, u'\\u0301\\u0308'), None)\n    string1 = normalize('NFKC', normalize('NFKD', string1).translate(trans_tab))\n    palindroma1 = string1.replace(\" \", \"\").lower()\n    return palindroma1 == palindroma1[::-1]\n\ndef isograma(string1 : str, string2 : str):\n    for char in string1:\n        if string1.count(char) == 1:\n            pass\n        else:\n            return False\n    for char in string2:\n        if string2.count(char) == 1:\n            pass\n        else:\n            return False\n    return True\n\ndef verificar_palabras():\n    string1 = input(\"Primera palabra a verificar: \")\n    string2 = input(\"Segunda palabra a verificar: \")\n\n    while True:\n        comprobacion = input(\"Que quieres comprobar con estas palabras? Si son: (anagramas, palindromas o isogramas) o escribe 'cancelar' si deseas cerrar la ejecucion, escribe: \")\n        if comprobacion.lower() == 'cancelar':\n            break\n        elif comprobacion.lower() == 'anagramas':\n            resultado = anagrama(string1, string2)\n            if resultado:\n                print(f\"Las dos palabras que me proporcionaste son anagramas\")\n            else:\n                print(\"No son anagramas\")\n        elif comprobacion.lower() == 'palindromas':\n            resultado1 = palindroma(string1)\n            resultado2 = palindroma(string2)\n            if resultado1:\n                print(f\"La primera palabra es palindroma\")\n            else:\n                print(f\"La primera palabra no es palindroma\")\n            if resultado2:\n                print(f\"La segunda palabra es palindroma\")\n            else:\n                print(f\"La segunda palabra no es palindroma\")\n        elif comprobacion.lower() == 'isogramas':\n            resultado = isograma(string1, string2)\n            if resultado:\n                print(f\"Las dos palabras son isogramas\")\n            else:\n                print(f\"No son isogramas\")\n\nverificar_palabras()"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/AndresMCardenas.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n\"\"\"\n\n# Acceso a caracteres específicos\ncadena = \"Hola Mundo\"\nprint(cadena[0]) # Imprime H ya que es el caracter de la cadena ubicado en la posicion 0\n\n# Subcadenas\ncadena = \"Hola Mundo\"\nprint(cadena[0:4]) # Imprime Hola ya que es la subcadena de la cadena ubicada en la posicion 0 a la 4\n\n# Longitud\ncadena = \"Hola Mundo\"\nprint(len(cadena)) # Imprime 10 ya que es la longitud de la cadena\n\n# Concatenación \ncadena = \"Hola\"\ncadena2 = \" Mundo\"\nprint(cadena + cadena2) # Imprime Hola Mundo ya que es la concatenacion de las dos cadenas\n\n# Repetición\ncadena = \"Hola\"\nprint(cadena * 3) # Imprime HolaHolaHola ya que es la cadena repetida 3 veces\n\n# Recorrido\ncadena = \"Hola\"\nfor i in cadena:\n    print(i) # Imprime Hola ya que recorre la cadena y la imprime caracter por caracter\n\n# Conversión a mayúsculas y minúsculas\ncadena = \"Hola Mundo\"\nprint(cadena.upper()) # Imprime HOLA MUNDO ya que convierte la cadena a mayusculas\nprint(cadena.lower()) # Imprime hola mundo ya que convierte la cadena a minusculas \n\n# Reemplazo\ncadena = \"Hola Mundo\"\nprint(cadena.replace(\"Hola\", \"Hello\")) # Imprime Hello Mundo ya que reemplaza la palabra Hola por Hello\n\n# División\ncadena = \"Hola Mundo\"\nprint(cadena.split(\" \")) # Imprime ['Hola', 'Mundo'] ya que divide la cadena en una lista de dos elementos\n\n# Unión\ncadena = \"Hola Mundo\"\nprint(\" \".join(cadena)) # Imprime H o l a   M u n d o ya que une la cadena con un espacio entre cada caracter\n\n# Interpolación\ncadena = \"Hola Mundo\"\nprint(f\"La cadena es: {cadena}\") # Imprime La cadena es: Hola Mundo ya que interpola la cadena en el texto\n\n# Verificación\ncadena = \"Hola Mundo\"\nprint(cadena.isalpha()) # Imprime False ya que verifica si la cadena es alfanumerica\n\n# Palíndromos\ncadena = \"ana\"\nif cadena == cadena[::-1]:\n    print(\"Es palindromo\") # Imprime Es palindromo ya que verifica si la cadena es palindromo\n\n# Anagramas\ncadena = \"roma\"\ncadena2 = \"amor\"\nif sorted(cadena) == sorted(cadena2):\n    print(\"Es anagrama\") # Imprime Es anagrama ya que verifica si la cadena es anagrama\n\n# Isogramas\ncadena = \"murcielago\"\nif len(cadena) == len(set(cadena)):\n    print(\"Es isograma\") # Imprime Es isograma ya que verifica si la cadena es isograma\n\n# DIFICULTAD EXTRA (opcional):\n# Crea un programa que analice dos palabras diferentes y realice comprobaciones\n\ncadena1 = input(\"Ingrese la primera palabra: \")\ncadena2 = input(\"Ingrese la segunda palabra: \")\n\ndef palindromo(cadena1, cadena2):\n  if cadena1 == cadena1[::-1] and cadena2 == cadena2[::-1]:\n    print(\"Las dos palabras son palindromos\") # Imprime Las dos palabras son palindromos ya que verifica si las dos cadenas son palindromos\n  elif cadena1 == cadena1[::-1]:\n    print(\"La primera palabra es palindromo\")\n  elif cadena2 == cadena2[::-1]:\n    print(\"La segunda palabra es palindromo\")\n  else:\n    print(\"Ninguna de las dos palabras es palindromo\")  \n\ndef anagramas(cadena1, cadena2):\n  if sorted(cadena1) == sorted(cadena2):\n    print(\"Las dos palabras son anagramas\") # Imprime Las dos palabras son anagramas ya que verifica si las dos cadenas son anagramas\n  elif sorted(cadena1) == sorted(cadena2):\n    print(\"La primera palabra es anagrama\")\n  elif sorted(cadena2) == sorted(cadena1):\n    print(\"La segunda palabra es anagrama\")\n  else:\n    print(\"Ninguna de las dos palabras es anagrama\")\n\ndef isogramas(cadena1, cadena2):\n  if len(cadena1) == len(set(cadena1)) and len(cadena2) == len(set(cadena2)):\n    print(\"Las dos palabras son isogramas\") # Imprime Las dos palabras son isogramas ya que verifica si las dos cadenas son isogramas\n  elif len(cadena1) == len(set(cadena1)):\n    print(\"La primera palabra es isograma\")\n  elif len(cadena2) == len(set(cadena2)):\n    print(\"La segunda palabra es isograma\")\n  else:\n    print(\"Ninguna de las dos palabras es isograma\")\n\n\nif (type(cadena1)) != str or (type(cadena2)) != str:\n  print(\"No ingreso palabras o cadena de texto\") # Imprime No son palabras ya que verifica si las cadenas son palabras \nelse:\n  palindromo(cadena1, cadena2)\n  anagramas(cadena1, cadena2)\n  isogramas(cadena1, cadena2)"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/Aquiles735.py",
    "content": "\n\n#  EJERCICIO:\n#  * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n#  * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n#  * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n#  *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n#  * para descubrir si son:\n#  * - Palíndromos\n#  * - Anagramas\n#  * - Isogramas\n#  */\n\n\n\n\n   # aplicacion de \" + \" y print\n\n# saludos= \"Hola\"\n# nombre=\"pedrito por acá\"\n# saludo_completo=saludos + \",\" + nombre \n# print(saludo_completo)  #Hola,pedrito por acá\n\n\n#    # uso de \" * \"\n\n# repetir= saludos*4\n# print(repetir)  #HolaHolaHolaHola\n\n\n#    # imprimir un carcter  específico \n# palabra= \"carpintero\"\n# eliminar_caracter=palabra[4]\n# print(eliminar_caracter)   #limina el caracter de la posicion 4 >>> \"i\"\n\n\n#    #subcadena\n# texto=\"programacion\"\n# limitado=texto[0:6]\n# print(limitado)    #imprime \"progra\"\n\n\n#    #numero de caracteres\n# palabron=\"contadores publicos\"\n# contador=len(palabron)\n# print(contador)   #imprime el numero de caracteres >> 19\n\n\n#    #immrpimir mayusculas \"upper\"o minusculas \"lower\" \n# saludito = \"Saludos Totales en Proceo\"\n# mayusculas = saludito.upper()\n# minusculas = saludito.lower()\n# print(mayusculas)  # Salida: SALUDOS TOTALES EN PROCEO\n# print(minusculas)  # Salida: saludos totales en proceo\n\n\n#     #reemplazar \" texto en cadena\"  .replace( \" a \"  \" b \"  \" c \")\n# escrito = \"aqui vamos, en proceso continuo\"\n# nuevo_ = escrito.replace(\"aqui\", \"desde\" \"cero\" \"de\" \"nuevo\")\n# print(nuevo_)  \n# print(escrito)  # Salida: aqui vamos, en proceso continuo\n\n\n    # encontrar \" posicion \" (numero de carcateres antes de la palabra) de una plabra en una cadena de texo con .find(\"  \")\n# cadena1= \"aqui vamos, en proceso continuo\"\n# posicion = cadena1.find(\"proceso\")\n# print(posicion)  # Salida: 15 (son los caracteres antes de inciciar \"proceso\")\n\n\n# #  dividir una cadena en subcadena (lista con elementos separados por ,)\n# cadena2 = \"aqui vamos, en proceso continuo, por ahora\"\n# subcadena = cadena2.split(\", \")\n# print(subcadena)  # Salida:['aqui vamos', 'en proceso continuo', 'por ahora']\n\n\n      #Quitar espacios en blanco al inicio y al final de la cadena con .strip()\n# cadena3 = \"   aqui vamos, en proceso continuo, por ahora   \"\n# subcad = cadena3.strip()\n# print(subcad)  # imprime:aqui vamos, en proceso continuo, por ahora\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/Bert008.py",
    "content": "'''\n/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n'''\n\ncadena1 = \"hola\"\ncadena2 = \"mundo\"\n\n# longitud de las cadenas\nprint(len(cadena1)) # 4\nprint(len(cadena2)) # 5\n\n# acceso a caracteres especificos\nprint(cadena1[3:]) # a\nprint(cadena2[0:1]) # m\ncadena_nueva = cadena1 + \" \" + cadena2\ncadena_con_o = [x for x in cadena_nueva.split() if \"o\" in x]\nprint(cadena_con_o)\ncadena_con_o = [x for x in cadena_nueva.split() if \"la\" in x]\nprint(cadena_con_o)\n\n# subcadenas\ncadena = \"Hola mundo, hola Python.\"\nsubcadena = cadena[:10]\nprint(subcadena)\nsubcadena = cadena[11: ]\nprint(subcadena)\nprint(subcadena.strip())\ncadena1, cadena2 = cadena.split(\",\")\nprint(\"Cadena 1 = \",cadena1)\nprint(\"Cadena 2 = \",cadena2.strip())\n\n# concatenacion\ncadena1 = \"Hola\"\ncadena2 = \"mundo\"\ncadena3 = \"python\"\ncadena4 = cadena1 + \" \" + cadena2\ncadena5 = cadena1 + \" \" + cadena3\nprint(cadena4)\nprint(cadena5)\n\n# repeticion\nprint(cadena1 * 3)\nprint(\"*\" * 3)\n\n# recorrido\nfor i in cadena1:\n    print(i, end = \" \")\nprint(\" \")\n\n# conversion de mayusculas y minusculas\nprint(cadena1.upper())\nprint(cadena1.lower())\nprint(cadena1.capitalize())\nprint(cadena.title())\n\n# remplazo\nprint(cadena.replace(\"Python\", \"amigo\"))\n\n# division\ndivision = cadena.split(\" \")\nprint(division)\n\n# union\nprint(\", \".join(cadena1))\n\n# interpolacion\nprint(f\"{cadena1} a todos y {cadena1} al {cadena2}\")\n\n# Verificacion\nprint(cadena1 in cadena) # Hola en Hola mundo, hola python.\nprint(cadena2 in cadena) # mundo en Hola mundo, hola python.\nprint(\"abc1234\".isalnum())\nprint(\"HOLA\".isupper())\nprint(\" \".isspace())\nprint(\"abc\".isalpha())\nprint(\"123\".isdigit())\n\n# Extra\n\ndef palindromos(word1, word2):\n    # palindromos\n    word1 = word1.lower()\n    word2 = word2.lower()\n    palindromo1 = word1 == word1[::-1]\n    palindromo2 = word2 == word2[::-1]\n    \n    \n    if palindromo1 and palindromo2:\n        print(\"Ambos son palindromos\")\n    elif palindromo1 == True and palindromo1 == False:\n        print(\"palabra 2 es un palindromo\")\n    elif palindromo1 == True and palindromo2 == False:\n        print(\"palabra 1 es palindromo\")\n    \ndef anagramaIsagrama(word1, word2):\n    word1 = word1.lower()\n    word2 = word2.lower()\n    if word1 == word2[::-1]:\n        print(\"Palabra 2 es un anagrama de 1\")\n    elif word2 == word1[::-1]:\n        print(\"Palabra 1 es un anagrama de 2\")\n    else:\n        print(\"Ambas palabras son isogramas\")\n\nwhile True:\n    print(\"Para salir escriba salir en ambas entradas\")\n    word1 = input(\"Palabra 1: \")\n    word2 = input(\"Palabra 2: \")\n\n    if word1 == word1[::-1] or word2 == word2[::-1]:\n        palindromos(word1, word2)\n    elif word1 == \"salir\" and word2 == \"salir\":\n        break\n    else:\n        anagramaIsagrama(word1, word2)\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/BrianSilvero.py",
    "content": "\"\"\"\nOperaciones\n\"\"\"\ns1 = \"Hola\"\ns2 = \"Python\"\ns3 = \"Brian Silvero @briandavid\"\n\n# Concatenación \nprint(s1 + \",\" + s2 + \"!\" )\n\n# Repetición\nprint(s1 * 3)\n\n# Indexación\nprint(s1[0] + s1[1] + s1[2] + s1[3])\n\n# Longitud\nprint(len(s2))\n\n# Slicing (porción)\nprint(s2[2:6])\nprint(s2[2:])\nprint(s2[0:2])\nprint(s2[:2])\n\n# Busqueda\nprint(\"a\" in s1)\nprint(\"i\" in s1)\n\n# Reemplazo\nprint(s1.replace(\"o\", \"a\"))\n\n# Division\nprint(s2.split(\"t\"))\n\n\n# Mayúscula, minúscula y letras en mayúscula\nprint(s1.upper())\nprint(s1.lower())\nprint(\"brian silvero\".title())\nprint(\"brian silvero\".capitalize())\n\n# Eliminación de espacios al principio y al final \nprint(\" brian silvero \".strip())\n\n# Busqueda al principio y al final\nprint(s1.startswith(\"Ho\"))\nprint(s1.startswith(\"Py\")) \nprint(s1.endswith(\"la\"))\nprint(s1.endswith(\"ton\"))\n\n# Busquedad de posicion\nprint(s3.find(\"brian\"))\nprint(s3.find(\"Brian\"))\nprint(s3.find(\"B\"))\nprint(s3.lower().find(\"b\"))\n\n# Busqueda de ocurrencia\nprint(s3.lower().count(\"brian\"))\n\n# Formateo\nprint(\"Saludo: {}, Lenguaje: {}!\".format(s1,s2))\n\n# Interpolación\nprint(f\"Saludo: {s1}, Lenguaje: {s2}!\")\n\n# Transformación en lista de caracteres\nprint(list(s3))\n\n# Transformación de lista en cadena \nl1 = [s1,\",\", s2,\"!\"]\nprint(\" \".join(l1))\n\n# Transformaciones numéricas \ns4 = \"123456\"\ns4 = int(s4)\n\nprint(s4)\n\ns5 = \"123456.123\"\ns5 = float(s5)\n\nprint(s5)\n\n# Comprobaciones varias\ns4 = \"123456\"\nprint(s1.isalnum())\nprint(s1.isalpha())\nprint(s4.isalpha())\nprint(s4.isnumeric())\n\n\n\"\"\"\nExtra\n\"\"\"\n\ndef check(word1:str , word2:str):\n    # Palindromo\n    print(f\"La palabra {word1} es un palidromo?: {word1== word1[::-1]}\")\n    print(f\"La palabra {word2} es un palidromo?: {word2 == word2[::-1]}\")\n    \n    # Anagramas\n    print(f\"La palabra {word1} es anagrama de {word2}? {sorted(word1) == sorted(word2)}\")\n    \n    \n    # Isograma\n    \n    def isograma(word: str) -> bool:\n        \n        word_dict = dict()\n        for character in word:\n            word_dict[character] = word_dict.get(character, 0) + 1\n            \n        isograma = True\n        \n        values = list(word_dict.values())\n        isogram_len = values [0]\n        for word_count in values:\n            if word_count != isogram_len:\n                isograma = False\t\n                break\n        return isograma\n\n    print(f\"{word1} es un isograma?: {isograma(word1)}\")\n    print(f\"{word2} es un isograma?: {isograma(word2)}\")\n\ncheck(\"radar\",\"pythonpythonpython\")\n\ncheck(\"amor\",\"roma\")\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/C-Gabs.py",
    "content": "#Reto 04\n\n'''EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\n *   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\n *   interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas'''\n\nstring = \"Hola mundo\"\nstring_2 = \" Hola python\"\nstring_3 = \"\"\n\n#Concatenación\nstring_3 = string + string_2\nprint(string_3)\nstring_3 = \"hola\" + \" Pandas\"\nprint(string_3)\n\n#indexacion\nprint(string[3])\n\nprint(string_3.join([\"Hola\",\"Mundo\",\" Hola \", \"python\"]))\n\n#Repetición\nprint(string*3)\n\n#Conversión a mayusculas o minusculas\nstring = string.upper()\nprint(string)\nstring = string.lower()\nprint(string)\nstring = string.capitalize()\nprint(string)\nprint(string.swapcase())\nprint(string.title())\n\n#busqueda \nprint(string.find(\"o\"))\nprint(string.rfind(\"o\",2,5)) #Devuelve -1 si no hay coincidencias\nprint(string.index(\"o\",1,3))\n#print(string.rindex(\"o\",2,5)) genera un ValueError si no hay coincidencias\nprint(\"l\" in string)\nprint(string.startswith(\"Hola\"))\nprint(string.endswith(\"on\"))\n#conteo de coincidencias\nstring = \"   hola python, hola swift, hola numpy  \"\nprint(string.count(\"hola\"))\nprint(string.count(\"py\"))\n\n#longitud\nprint(len(string))\n\n#Recorrido\nfor char in string:\n    print(char)\n\n#Reemplazo\n\nprint(string.replace(\" \", \"#\"))\nprint(string.rstrip()) #Remueve los espacios al final del texto\nprint(string.strip()) #Remueve los espacios al inicio del texto\nstring = string.removeprefix(\"   \")\nprint(string) \nstring = string.removesuffix(\"  \")\nprint(string)\nstring = string.replace(\",\", \"\")\n\n#División\nprint(string.split(\" \"))\n\n#interpolación\nprint(f\"string 1: {string} string 2: {string_2} estring 3: {string_3}\")\n\n#formateo\nprint(\"Hola {}, hola {}\".format(\"brais\",\"mundo\"))\n\n#rodajas\nprint(string[2:7])\nprint(string[::-1])\n\n#conversion lista cadena y cadena a lista\nprint(list(string))\nprint(\"\".join([\"hola\",\" \",\"mundo\"]))\n\n#conversion a enteros\nprint(type(int(\"123\")))\n\n#comprobaciones\nprint(string.isalpha())\nprint(\"12w31j2d3h55rt42\".isalnum())\nprint(\"1234565436\".isdigit())\nprint(\"1234565436\".isnumeric())\nprint(\"juan\".islower())\nprint(\"JUAN\".isupper())\nprint(\"Juan\".istitle())\nprint(\"  \".isspace())\nprint(string.isascii())\n\n\n# Reto Extra\n\ndef palindromo(string_1, string_2):\n    if string_1.lower().replace(\" \",\"\") == string_1[::-1].lower().replace(\" \",\"\"):\n        print(f\"{string_1} Es palindromo\")\n    else:\n        print(f\"{string_1} No es palindromo\")\n    if string_1.lower().replace(\" \",\"\") == string_1[::-1].lower().replace(\" \",\"\"):\n        print(f\"{string_2} Es palindromo\")\n    else:\n        print(f\"{string_2} No es palindromo\")\n     \npalindromo(\"dabale arroz a la zorra el abad\",\"dabale arroz a la zorra el abad\")\n\n\ndef anagrama(string_1,string_2):\n    es_anagrama = \"No es un anagrama\"\n    \n    if string_1.lower() == string_2.lower():\n        es_anagrama = \"No es un anagrama\"\n    \n    if sorted(string_1.lower().replace(\" \",\"\")) == sorted(string_2.lower().replace(\" \",\"\")):\n        es_anagrama = \"Es un anagrama\"\n\n    return es_anagrama \n\nprint(anagrama(\"animales\",\"milanesa\"))\n\n\ndef isograma(string_1):\n    string_dict = dict()\n    for char in string_1:\n        if char not in string_dict.keys():\n            string_dict[char] = string_1.count(char)\n    values = list(string_dict.values())\n    repeticiones = values[0]\n    for value in values:\n        if repeticiones != values[value]:\n            return \"No es un isograma\"\n    return \"Es un isograma\"\nprint(isograma(\"hola\"))\n\n\n#otra forma de resolver el anagrama\n\ndef anagrama_2(string_1,string_2):\n    sumaord_1 = 0\n    sumaord_2 = 0\n    for char in string_1.lower().replace(\" \",\"\"):\n        sumaord_1 += ord(char)\n    for char in string_2.lower().replace(\" \",\"\"):\n        sumaord_2 += ord(char)\n    if sumaord_1 == sumaord_2:\n        return True\n    else:\n        return False\nprint(anagrama_2(\"ani MAles\",\"mila nesa\"))\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/CaveroBrandon.py",
    "content": "\"\"\"\nMuestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres en tu lenguaje.\nAlgunas de esas operaciones podrían ser (busca todas las que puedas):\n- Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\nconversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación\n\"\"\"\n\n\ndef string_exercise(first_string='First string', second_string='Second string'):\n    string_concatenated = first_string + '-' + second_string  # Concatenation of strings\n    print('Concatenated string:', string_concatenated)\n\n    string_multiplication = first_string * 3  # Multiplication of a string or repetition\n    print('Repetition of a string:', string_multiplication)\n\n    first_char = first_string[0]  # Accessing a specific character\n    print('First character of a string:', first_char)\n\n    sliced_string = first_string[0:5]  # Slicing an string\n    print('Sliced string:', sliced_string)\n\n    split_string = first_string.split()  # Splitting a string\n    print('Split string:', split_string)\n\n    lower_case_string = first_string.lower()  # Transforming any string to lower case\n    print('The lower case version of the string is:', lower_case_string)\n\n    upper_case_string = first_string.upper()  # Transforming any string to upper case\n    print('The upper case version of the string is:', upper_case_string)\n\n    replace_text = second_string.replace('string', 'text')  # Replacing a string\n    print('Replacing the text \"string\" to \"text\":', replace_text)\n\n    find_string = first_string.find('string')  # Find a word in a string\n    print('The word \"string\" is in the position:', find_string)\n\n    first_string_length = len(first_string)  # Getting the length of a string\n    print('The length of the string is:', first_string_length)\n\n    for i in first_string:  # Navigate a string using a for\n        print(i)\n\n    print(f'String interpolation using the {first_string} and the {second_string}')  # String interpolation\n\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\nCrea un programa que analice dos palabras diferentes y realice comprobaciones para descubrir si son:\n- Palíndromos\n- Anagramas\n- Isogramas\n\"\"\"\n\n\ndef is_palindrome(text):\n    testing_text = text.lower()\n    testing_text = testing_text.replace(' ', '')\n\n    inverted_text = text[::-1]\n    inverted_text = inverted_text.lower()\n    inverted_text = inverted_text.replace(' ', '')\n\n    if testing_text == inverted_text:\n        print(f'The text \"{text}\" is a palindrome')\n    else:\n        print(f'The text \"{text}\" is not a palindrome')\n\n\ndef is_isogram(text):\n    test_text = text.replace(' ', '')\n    for letter in test_text:\n        if test_text.count(letter) != 1:\n            print(f'The text \"{text}\" is not an isogram')\n            return\n    print(f'The text \"{text}\" is an isogram')\n\n\ndef is_anagram(text1, text2):\n    test_text1 = text1.replace(' ', '')\n    test_text1 = test_text1.lower()\n    test_text1 = sorted(test_text1)\n\n    test_text2 = text2.replace(' ', '')\n    test_text2 = test_text2.lower()\n    test_text2 = sorted(test_text2)\n\n    if test_text1 == test_text2:\n        print(f'The text {text1} and {text2} are anagram')\n    else:\n        print(f'The text {text1} and {text2} are not anagram')\n\n\nstring_exercise()\n\nprint(' \\n **** DIFICULTAD EXTRA ****')\ntext = input('Input a text to verify if is palindrome and isogram:')\nis_palindrome(text)\nis_isogram(text)\nanagram1 = input('Input a text the first text to verify if is an anagram:')\nanagram2 = input('Input a text the first text to verify if is an anagram:')\nis_anagram(anagram1, anagram2)\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/CesarCarmona30.py",
    "content": "'''\n  EJERCICIO:  Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de \n  caracteres en tu lenguaje.\n'''\n\n# Concatenación de caracteres\n\nname = 'César'\nlastname = 'Carmona'\nfull_name = name + ' ' + lastname\nprint(full_name)\nprint('Hola %s %s' % (name, lastname))\nprint('{1} {0}, ¿Cómo estás?'.format(lastname, name))\nprint(f'Adiós {name} {lastname}')\nnumbers = ['16', '62', '35']\nprint(' '.join(numbers))\n\n# repetición\nprint(name * 4)\n\n# Indexación\nprint(name[0] + name[1] + name[2] + name[3])\n\n# Longitud\nprint(len(lastname))\n\n# Slicing (porción)\nprint(lastname[2:6])\nprint(lastname[2:])\nprint(lastname[0:2])\nprint(lastname[:2])\n\n# Busqueda\nprint(\"a\" in lastname)\nprint(\"i\" in name)\n\n# Reemplazo\nprint(lastname.replace(\"a\", \"x\"))\n\n# División\nprint(lastname.split(\"m\"))\n\n# Mayúsculas, minúsculas y letras en mayúsculas\nprint(lastname.upper())\nprint(name.lower())\nprint(\"hello world\".title())\nprint(\"mexico city\".capitalize())\n\n# Eliminación de espacios al principio y al final\nprint(\" cesar leroy \".strip())\n\n# Búsqueda al principio y al final\nprint(lastname.startswith(\"ca\"))\nprint(name.startswith(\"er\"))\nprint(lastname.endswith(\"na\"))\nprint(name.endswith(\"sar\"))\n\n\n# Comprobaciones varias\nmy_string = \"123456\"\nprint(my_string.isalnum())\nprint(my_string.isalpha())\nprint(my_string.isalpha())\nprint(my_string.isnumeric())\n\n\"\"\"\nExtra\n\"\"\"\n\n\ndef check(word1: str, word2: str):\n\n    # Palíndromos\n    print(f\"¿{word1} es un palíndromo?: {word1 == word1[::-1]}\")\n    print(f\"¿{word2} es un palíndromo?: {word2 == word2[::-1]}\")\n\n    # Anagramas\n    print(f\"¿{word1} es anagrama de {word2}?: {sorted(word1) == sorted(word2)}\")\n\n    # Isogramas\n\n    def isogram(word: str) -> bool:\n\n        word_dict = dict()\n        for character in word:\n            word_dict[character] = word_dict.get(character, 0) + 1\n\n        isogram = True\n        values = list(word_dict.values())\n        isogram_len = values[0]\n        for word_count in values:\n            if word_count != isogram_len:\n                isogram = False\n                break\n\n        return isogram\n\n    print(f\"¿{word1} es un isograma?: {isogram(word1)}\")\n    print(f\"¿{word2} es un isograma?: {isogram(word2)}\")\n\n\ncheck(\"radar\", \"pythonpythonpythonpython\")\ncheck(\"amor\", \"roma\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/Chrisdev00.py",
    "content": "\"\"\"\n* EJERCICIO:\n* Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n* en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n* - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n*   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n*\n* DIFICULTAD EXTRA (opcional):\n* Crea un programa que analice dos palabras diferentes y realice comprobaciones\n* para descubrir si son:\n* - Palíndromos\n* - Anagramas\n* - Isogramas\n\"\"\"\n\n# Creando una cadena\n\ntext = \"P\"\nprint(text)\n\nmultiline_string = \"\"\" \nEste es un ejemplo de una cadena\nen varias lineas usando comillas dobles, tambien se puede\nusar comillas simples.\n\"\"\"\nprint(multiline_string)\n\n# Concatenacion de cadenas\n\nfirst_name = \"Pepito\"\nlast_name = \"Perez\"\nspace = \" \"\n\nfull_name = first_name + space +  last_name\nprint(full_name)\n\n\n# Secuencia de escape en cadenas\n\n\"\"\"\nEn Python y otros lenguajes de programación, \\ seguido de un carácter es una secuencia de escape. \nVeamos los caracteres de escape más comunes:\n\n\\n: nueva línea\n\\t: Tabulador significa (8 espacios)\n\\\\: barra invertida\n\\': Una frase (')\n\\\": comillas dobles (\")\n\"\"\"\n\nprint('Este es un ejemplo de como usar una secuencia de escape.\\nUsando barra invertida') # nueva linea\nprint('Dias\\tTemas\\tEjercicios')                                                # añadiendo tabulacion o 4 espacios \nprint('Dia 4\\t4\\t4')\nprint('Dia 5\\t5\\t101')\nprint('Simbolo de barra invertida (\\\\)')                                        # Para escribir barra invertida\nprint('Usando comillas simples y comillas dobles \\\"Hola, Mundo!\\\"')\n\n\n# Formateo de cadenas\n\na = 2\nb = 6\n\nprint(f\"{a} + {b} = {a+b}\")\nprint(f'{a} / {b} = {a / b:.2f}')  #  formatea un número decimal(float) para que tenga dos lugares decimales después del punto decimal.\n\n\n# Desempaquetando caracteres de una cadena\n\nlenguaje = \"Python\"\na,b,c,d,e,f = lenguaje             # desempaquetando en secuencia los caracteres en las variables\nprint(a)            \nprint(b)            \nprint(c)            \nprint(d)            \nprint(e)            \nprint(f)    \n\n# Accediendo a caracteres en cadenas por indice\n\nlenguaje = \"Python\"\nfirst_letter = lenguaje[0]\nprint(first_letter)\nsecond_letter = lenguaje[1]\nprint(second_letter) \nlast_index = len(lenguaje) - 1\nlast_letter = lenguaje[last_index]\nprint(last_letter)\n\nlast_letter = lenguaje[-1]           # Comenzando desde la derecha ultimo indice\nprint(last_letter)\nsecond_last = lenguaje[-2]           # Comenzando desde la derecha penultimo indice\nprint(second_last)\n\n\n# Separar o Cortar Cadenas en python\n\nlenguaje = \"JavaScript\"\nfirts_three_char = lenguaje[0:3]     # Comienza en el indice 0 hasta el numero 3 pero sin incluir el numero 3\nprint(firts_three_char)\nother_three = lenguaje[3:6]\nprint(other_three)\nlast_four = lenguaje[-4:]            # last_four = lenguaje[6:]  print(last_four)  Otra forma de escribir\nprint(last_four)\n\n\n# Invertir una cadena \n\nmy_string = \"Hola mundo!\"\nprint(my_string[::-1])\n\n# Saltar caracteres mientras se corta   // slicing [start:end:step]\n\nlenguaje = \"Kotlin\"\nkti = lenguaje[0:6:2]\nprint(kti)\n\n\n# Convertir caracteres de una cadena a mayusculas\n\nmy_string = \"hola mundo\"\nprint(my_string.capitalize())              # Convierte solo el primer caracter a mayuscula\nprint(my_string.upper())                   # Convierte todos los caracteres a mayusculas\n\n# Convertir caracteres de una cadena a minusculas\n\nmy_other_string = \"PYTHON\"\nprint(my_other_string[0].lower() + my_other_string[1:])   # Convierte solo el primer caracter a minuscula\nprint(my_other_string.lower())                           # Convierte todos los caracteres a minusculas\n\nvariable = \"Hola Mundo\"\nprint(variable.swapcase())   # convierte todos los caracteres en mayúsculas a minúsculas y todos los caracteres en minúsculas a mayúsculas.     \n\n# Contar cuantas veces aparece un caracter en una cadena   count(substring, start=..., end=...)\n\nmy_string = \"Retos de programacion\"\nprint(my_string.count(\"o\"))              # 3\nprint(my_string.count(\"o\",4, 15))        # 1\nprint(my_string.count(\"ro\",4, 15))       # 1\n\n\n\n# Comprobar si una cadena termina con un caracter especifico\n\ntext = \"road map de programacion\"\nprint(text.endswith(\"ion\"))          # True\nprint(text.endswith(\"ción\"))         # False, por el acento\n\n\n\n# Reemplazar el carácter de tabulación con espacios, el tamaño de tabulación predeterminado es 8. \n\nmy_string = \"retos\\tde\\tprogramacion\"\nprint(my_string)\nprint(my_string.expandtabs(10))\nprint(my_string.expandtabs(12))\n\n\n\n# Buscar el índice de la primera y ultima aparición de un caracter, si no se encuentra devuelve -1\n\nmy_var = \"Cadenas de caracteres\"\nprint(my_var.find(\"e\"))\nprint(my_var.find(\"de\"))\nprint(my_var.find(\"f\"))\n\nprint(my_var.rfind(\"e\"))         # Imprime el indice de la ultima aparicion de un caracter\nprint(my_var.rfind(\"te\"))        # Imprime el indice de la ultima aparicion de un caracter\nprint(my_var.rfind(\"f\"))         # Sino lo encuentra retorna -1\n\n\n\n# Devuelve el índice más bajo de una subcadena, los argumentos adicionales indican el índice inicial y final \n# los argumentos adicionales indican el índice inicial y final\n# si no encuentra el valor da valueError \n\nmy_other_string = \"ejercicios de programacion\"\nsub_string = \"de\"\nprint(my_other_string.index(sub_string))          # 11\nprint(my_other_string.index(sub_string, 2, 13))       # error\n\nprint(my_other_string.rindex(sub_string))           # Devuelve el indice mas alto\nprint(my_other_string.rindex(sub_string, 2, 17))   \n\n\n# Comprobar caracteres alfanumericos\n\nmy_text = \"retosdeprogramacion2024\"\nprint(my_text.isalnum())                        # True\nmy_text_two = \"retos de programacion\"\nprint(my_text_two.isalnum())                    # False,  los espacion no son caracteres alfanumericos\n\n\n# Comprobar si los elementos de una cadena son caracteres alfabeticos\n\nnumeros = \"123\"\nprint(numeros.isalpha())                        # False\n\nletters = \"LogicaDeProgramacion\"\nprint(letters.isalpha())                        # True\n\ncadena = \"Logica de Programacion\"\nprint(cadena.isalpha())                         # False\n\n\n# comprueba si todos los caracteres de una cadena son decimales (0-9)\n\nmy_string = \"reto numero 4\"\nprint(my_string.isdecimal())                    # False\n\nnum = \"6574\"\nprint(num.isdecimal())                          # True\n\n\n# Devolver una cadena concatenada\n\nlenguajes = ['HTML', 'CSS', 'JavaScript', 'React']\nresult = ' '.join(lenguajes)\nprint(result)\n\n# Reemplazar la subcadena con una cadena determinada\n\nphrase = \"road retos de programacion\"\nprint(phrase.replace(\"retos\", \"ejercicios\"))\n\n\n#################      EXTRA      #############################\n\n\ndef is_Palindromo (text, text2):\n\n    var_1 = text[::-1].lower().replace(\" \", \"\")\n    var_2 = text2[::-1].lower().replace(\" \", \"\")\n    if var_1 == text.replace(\" \", \"\") and var_2 == text2.replace(\" \", \"\"):\n        print(f\"Las palabras '{text}' y '{text2}' son palindromos\")\n    else:\n        print(f\"Las palabras '{text}' y '{text2}' no son palindromos\")\n\n\ndef is_Anagrama (text , text2):\n\n    var_1 = sorted(text.lower().replace(\" \", \"\"))\n    var_2 = sorted(text2.lower().replace(\" \", \"\"))\n    if var_1 == var_2:\n        print(f\"Las palabras '{text}' y '{text2}' son anagramas\")\n    else:\n        print(f\"Las palabras '{text}' y '{text2}' no son anagramas\")\n\n\ndef is_Isograma (word):\n\n    palabra = word.lower()\n    caracteres_filtrados = []  \n    \n    for caracter in palabra:        \n        if caracter.isalpha():            \n            caracteres_filtrados.append(caracter)\n    \n    palabra = ''.join(caracteres_filtrados)\n    return len(palabra) == len(set(palabra))\n\ndef comprobar_Isograma (text, text2):\n\n    if is_Isograma(text) and is_Isograma(text2):\n        print(f\"Las palabras '{text}' y '{text2}' son Isogramas.\")\n    else:\n        print(f\"Las palabras '{text}' y '{text2}' no son isogramas.\")\n\n\nis_Palindromo(\"anita lava la tina\", \"reconocer\")\nis_Anagrama(\"anagrama\", \"amar gana\")\ncomprobar_Isograma (\"murcielago\", \"puerta\")\n\nis_Palindromo(\"zorra\", \"arroz\")\nis_Anagrama(\"Enrique\", \"quieren\")\ncomprobar_Isograma (\"python\", \"java\")\n\n\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/Complex303.py",
    "content": "\"\"\"\nCADENAS DE CARACTERES\"\"\"\n\ntx1 = 'Hola'\ntx2 = 'Python'\ntx3 = 'Esto es una variable'\n\n#Concatenacion\nprint(tx1+ ' ' + tx2+ '!!')\n\n#Repeticion\nprint(tx1 * 5)\n\n#indexacion\nprint(tx1[0] + tx1[1] + tx1[2]+ tx1 [3])\n\n#Longitud\nprint(len(tx2))\n\n#slicing (porcion)\nprint(tx2[0:3]) #el ultimo indice no se incluye\nprint(tx2[3:])\n\n#busqueda\nprint('th' in tx2);\n\n#remplazo\nprint(tx1.replace('o', 'a'))\n\n\n#division\nprint(tx2.split('t'))\n\n\n#mayuscula, minuscula y primera letra mayuscula\nprint(tx2.upper())\nprint(tx2.lower())\nprint('carro rojo'.title()) #primera letra de cada palabra mayuscula\nprint('carro rojo'.capitalize()) #solo la primera letra mayuscula\n\n\n#Eliminacion de espacio al principio y al final\nprint(' carro rojo '.strip())\n\n\n#Busqueda al principio y al final\nprint(tx1.startswith('Ho'))\nprint(tx2.startswith('a'))\nprint(tx1.endswith('lo'))\nprint(tx2.endswith('n'))\n\n#Busqueda de posicion\nprint('Este es un ejemplo'.find('es')) #5\nprint('Este es un ejemplo'.lower().find('es')) #0\n\n#busquda de ocuerrencia\nprint('Este es un ejemplo'.lower().count('es')) #2\n\n\n#Formateo\nprint('Saludo: {}, Lenguaje {}!'.format(tx1,tx2))\n\n#Interpolacion\nprint(f'Saludo: {tx1}, Lenguaje {tx2}!')\n\n\n#Transformacion en lista de caracteres\nprint(list(tx3))\n\n#Transformacion de lista en cadena\nl1 = [tx1, ', ', tx2, '!' ]\nprint(''.join(l1)) #join: concatenar resultados de una lista\n\n\n#Transformaciones numericas\ntxt4 = '124312.821'\ntxt4 = float(txt4)\nprint(txt4)\n\n\n#comprobaciones varias\ntxt4 = '124312.821'\nprint(tx2.isalnum()) #True\nprint(tx2.isnumeric()) #False\nprint(txt4.isnumeric())\n\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\"\"\"\n\n\ndef comprobar_palabra(palabra : str, palabra2 : str):\n\n    #Palindromos: Se lee igual al derecho y al revés.\n    print(f\"La palabra {palabra} Es un palindromo?  {palabra == palabra[::-1]}\")\n    print(f\"La palabra {palabra2} Es un palindromo?  {palabra2 == palabra2[::-1]}\")\n\n    #Anagrama: Palabra formada al reorganizar las letras de otra.\n    print(f\"La palabra {palabra} Es un analagrama de la palabra {palabra2}? {sorted(palabra) == sorted(palabra2)}\")\n\n    ##Isograma: Ninguna letra se repite.\n    ##print(f\"La palabra {palabra} es un Isograma? {len(palabra) == len(set(palabra))} \")\n    ##print(f\"La palabra {palabra2} es un Isograma? {len(palabra2) == len(set(palabra2))} \")\n\n    #isograma: si todas las letras aparecen la misma cantidad de veces.\n    def isograma(word: str) -> bool:\n\n        palabra_dict = dict()\n        for caracter in word:\n            palabra_dict[caracter] = palabra_dict.get(caracter, 0) + 1\n\n        isograma = True\n        values = list(palabra_dict.values())\n        isograma_len = values[0]\n        for palabra_contada in values:\n            if palabra_contada != isograma_len:\n                isograma = False\n                break\n        return isograma\n\n    print(f'{palabra} es un isograma?: {isograma(palabra)}')\n    print(f'{palabra2} es un isograma?: {isograma(palabra2)}')\n\n\n\ncomprobar_palabra('reconocer', 'radar' )\ncomprobar_palabra('amor', 'roma')\n\ncomprobar_palabra('ropa', 'pythonpython')"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/D3rk1us.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n \"\"\"\n\nnombre_cadena = 'Alfabeto'\ncadena = \"abcd-efg-hijk\"\n\n # Acceso a caracteres específicos\n\nprint(cadena[1])\n\n # Subcadenas\n\nprint(cadena[5:8])\n\n # Longitud\n\nprint(len(cadena))\n\n # Concatenación\n\nprint(nombre_cadena + \":\" + cadena)\nprint(nombre_cadena, \":\", cadena)\nprint(f\"{nombre_cadena}: {cadena}\")\n\n # Repetición \n\nprint(cadena * 4)\n\n # Recorrido\n\nfor c in cadena:\n    print(c)\n\n # Conversión a mayúsculas y minúsculas\n\nprint(cadena.upper())\nprint(nombre_cadena.lower())\n\n # Reemplazo\n\nprint(cadena.replace('a', 'z'))\n\n # División y Unión\n\ncadena = cadena.split('-')\nprint(cadena)\n\ncadena = ' '.join(cadena)\nprint(cadena)\n\n # Interpolación\n\nprint(f\"Este es el {nombre_cadena.lower()}, que comienza con: {cadena}\")\n\n # Verificación\n\nprint(isinstance(cadena, str))\nprint(type(nombre_cadena))\n\n\"\"\"\n/////////////////////////////////////////////////  DIFICULTAD EXTRA  /////////////////////////////////////////////////\n\"\"\"\n\npalabra1 = \"adan\"\npalabra2 = \"nada\"\n\n# Funciones que comprueban si son palíndromos, anagramas y/o isogramas\n\ndef palindromo(palabra1, palabra2):\n    list_palabra1 = [*palabra1] # Divide cada caracter en un elemento de un listado.\n    list_palabra2 = [*palabra2]\n\n    list_palabra2.reverse()\n\n    if list_palabra1 == list_palabra2:\n        return \"Palíndromos.\"\n    else:\n        return \"No son palíndromos.\"\n\ndef anagrama(palabra1, palabra2):\n    list_palabra1 = [*palabra1] # Divide cada caracter en un elemento de un listado.\n    list_palabra2 = [*palabra2]\n\n    list_palabra1.sort()\n    list_palabra2.sort()\n\n    if list_palabra1 == list_palabra2:\n        return \"Anagramas.\"\n    else:\n        return \"No son anagramas.\"\n\ndef isograma(palabra):\n    count = 0 # Cuenta cuánto se repite una letra.\n\n    for a in range(len(palabra)):\n        for k in palabra:\n\n            if palabra[a] == k:\n                count += 1\n                if count == 2:  #En el momento que una letra se repite dos veces, deja de ser Isograma.\n                    return \"No es Isograma.\"\n        \n        count = 0\n    \n    return \"Es Isograma.\"\n\nprint(palindromo(palabra1, palabra2))\nprint(anagrama(palabra1, palabra2))\nprint(isograma(palabra2))"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/DAVstudy.py",
    "content": "\n# Operaciones con Strings tipo str\n\nmy_string = \"Hola soy DevsDav \"\nprint(my_string)\n\n# Acceso a caracteres\nprint(my_string[0])  # Acceder al primer caracter\nprint(my_string[2:6])  # Acceder a un rango\nprint('')\n\n# Recorrer un String\nfor caracter in my_string:\n    print(caracter)\n\n# Confirmar si existe uno o mas caracters en el String\nprint(\"DevsDav\" in my_string)  # Si existe\nprint(\"DevDav\" not in my_string)  # Si no existe\n\n# Longitud de un String\nprint(f'La longitud del string es: {len(my_string)}')\n\n# Conectar o Unir dos o mas Strings\nprint('Uniremos el mensaje \", soy ingeniero electrónico\" al string anterior')\nprint(my_string + \", soy ingeniero electrónico\")\n\n# Convertir en mayúsculas todas las letras del String\nprint(my_string.upper())\n\n# Convertir en minúsculas todas las letras del String\nprint(my_string.lower())\n\n\n\"\"\"Podemos validar si todos los caracteres estan\nen mayúsculas o minúscolas con isupper() o islower\nRetornara True si es correcto.\"\"\"\n\nmy_string = my_string.lower()\n\nprint(my_string.isupper())  # Verifica que este todo en mayúsculas\nprint(my_string.islower())  # Verifica que este todo en minúsculas\n\n# Verificaciones\n\nmy_other_string = \"123456789D\"\nprint(my_other_string.isnumeric())  # Verifica si es númerico\nprint(my_other_string.isalnum())  # Verifica si es alfanúmerico\nprint(my_other_string.isalpha())  # Verifica si es alfabetico\n\n\n\"\"\"strip() Retornar el string eliminando los espacios\nen blanco iniciales y finales\"\"\"\n\nprint(my_string.strip())\n\n\n\"\"\"string.split(a): retorna una lista con los elementos\ndel string que están separados por el string a. Si se\nomite a, asume que el separador es uno o más espacios\nen blanco o el salto de línea.\"\"\"\n\nprint(my_string.split())\n\n\n\"\"\"p.join(lista): suponiendo que p es un string, retor-\nna un nuevo string conteniendo los elementos de la\nlista \"unidos\" por el string p.\n\"\"\"\n\nprint(my_string.join(['a', 'b', 'c']))\n\n\n# replace(): Reemplazar un caracter en la cadena\n\nprint(my_string.replace(\"h\", \"H\"))\n\n# Repetición de un String\nprint(my_string * 3)\n\n\n# count(a): Cuenta cuantas veces 'a' esta en la cadena\nprint(my_string.count(\"a\"))\n\n\n\"\"\"Extra\nCrea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n\"\"\"\n\n\ndef is_anagram(word1: str, word2: str):\n\n    if sorted(word1.lower()) == sorted(word2.lower()):\n        return True\n    return False\n\n\ndef is_palindrome(word1: str):\n\n    bool_word1 = False\n    if word1.lower() == word1.lower()[::-1]:\n        bool_word1 = True\n\n    return bool_word1\n\n\ndef is_isogram(word1: str):\n\n    bool_word1 = True\n\n    for caracter in word1:\n        if word1.lower().count(caracter.lower()) < 2:\n            bool_word1 = False\n\n    return bool_word1\n\n\nword_1 = input(\"Ingrese la palabra 1:\")\nword_2 = input(\"Ingrese la palabra 2:\")\n\nprint(f\"Las palabras son '{word_1}' y '{word_2}'\")\nprint(f\"¿{word_1} es un palindromo? {is_palindrome(word_1)}\")\nprint(f\"¿{word_2} es un palindromo? {is_palindrome(word_2)}\")\nprint(f\"¿{word_1} es un anagrama de '{word_2}'? {is_anagram(word_1, word_2)}\")\nprint(f\"¿{word_1} es un isograma? {is_isogram(word_1)}\")\nprint(f\"¿{word_2} es un isograma? {is_isogram(word_2)}\")\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/DGrex.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n   en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\n   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\n   interpolación, verificación...\n\"\"\"\n\nstrings_one = \"Soy\"\nstrings_two= \"DGrex\"\n\n# concatenacion\nconcatenacion = \"(Hola, \" + strings_one + \" \" + strings_two + \")\"\nprint(concatenacion)\n\n# Repeticion\nprint(concatenacion * 3)\n\n# Indexación\nprint(concatenacion[1]+strings_one[1]+concatenacion[3]+concatenacion[4])\n\n# Longitud\nprint(len(concatenacion))\n\n# Slicing o Porción\nprint(concatenacion[7:])\nprint(concatenacion[7:16])\nprint(concatenacion[:17])\nprint(concatenacion[1:5])\n\n# Busqueda\nprint(\"oy\" in strings_one)\nprint(\"rex\" in strings_one)\n\n# Reemplazo\nprint(strings_two.replace(\"e\", \"i\"))\n\n# División\n#La función split() se utiliza para dividir una cadena en una lista de subcadenas\nLenguajes = \"Python Java C++\"\n\nprint(strings_two.split(\"G\")) \nprint(Lenguajes.split()) # Cuando hay parametro tomara los espacios como referencia\n\n# Mayúsculas, minúsculas\nprint(strings_two.lower())\nprint(strings_two.upper())\nprint(\"soy dgrex\".title()) # Primera letra de cada palabra en mayuscula\nprint(\"soy dgrex\".capitalize()) # Primera letra en mayuscula\n\n# Eliminación de espacios al principio y al final de una cadena\nprint(\" Soy DGrex      \".strip())\n\n# Búsqueda al principio y al final\nprint(strings_two.startswith(\"DG\"))\nprint(strings_two.startswith(\"re\"))\nprint(strings_two.endswith(\"ex\"))\n\n# Búsqueda de posición\nstring_thre = \"Soy DGrex @DGrex__\"\n\nprint(string_thre.find(\"DGrex\"))\nprint(string_thre.find(\"dgrex\")) # -1 es subcadena no encontrada\nprint(string_thre.lower().find(\"dgrex\"))\n\n# Búsqueda de ocurrencias\nprint(string_thre.upper().count(\"E\"))\n\n# Formateo\nprint(\"Hola {} {}.\".format(strings_one, strings_two))\n\n# Interpolación\nprint(f\"Hola {strings_one} {strings_two}.\")\n\n# Tranformación en lista de caracteres\nprint(list(string_thre))\n\n# Transformación de lista en cadena\nmy_name = [\"D\",\"G\",\"r\",\"e\",\"x\"]\nprint(\"\".join(my_name))\n\n# Transformaciones numéricas\nnumber = \"123456\"\nnumber = int(number)\nprint(f\"{number} it's from the  {type(number)}\")\n\nnumber = \"123456.123\"\nnumber = float(number)\nprint(f\"{number} it's from the  {type(number)}\")\n\n# Comprobaciones varias\nstrings_two= \"DGrex\"\nnumber = \"123456\"\nprint(strings_two.isalnum()) # Es numerico, es alfa, es alfanumerico, si esta vacío da False \nprint(strings_two.isalpha()) #Es alfa\nprint(number.isalpha()) #Es alfa\nprint(number.isnumeric()) # Es numerico\nprint(number.isdecimal())\n\nprint(isinstance(number, float)) # Compara el tipo de dato de una variable\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n   para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n\n\"\"\"\ndef palindromos_anagramas_isogramas(word_one, word_two):\n  print\n\n  # Palíndromos\n\n  if word_one.lower() == word_one[::-1].lower():\n    print(f\"La palabra {word_one} es un palindromo.\")\n  else:\n    print(f\"La palabra {word_one} no es un palindromo.\")\n\n  if word_two.lower() == word_two[::-1].lower():\n    print(f\"La palabra {word_two} es un palindromo.\")\n  else:\n    print(f\"La palabra {word_two} no es un palindromo.\") \n\n  # Anagramas\n \n  if \"\".join(sorted(word_one.lower())) == \"\".join(sorted(word_two.lower())):\n    print(f\"{word_one} y {word_two} si son anagramas.\")\n  else:\n    print(f\"{word_one} y {word_two} no son anagramas.\")\n\n# Isogramas\n\n  if len(word_one.lower()) == len(set(word_one.lower())):\n    print(f\"La palabra {word_one} es un isograma.\")\n  else:\n    print(f\"La palabra {word_one} no es un isograma.\")\n\n  if len(word_two.lower()) == len(set(word_two.lower())):\n    print(f\"La palabra {word_two} es un isograma.\")\n  else:\n    print(f\"La palabra {word_two} no es un isograma.\")\n\npalindromos_anagramas_isogramas(\"ROMA\",\"amor\")\n#palindromos_anagramas_isogramas(\"Radar\",\"teclado\")\n\n\"\"\"\nLa funcion set crear un conjunto.\nUn conjunto es una colección de elementos únicos y desordenados.\nLos conjuntos eliminan los duplicados.\n\"\"\"\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/DaniQB99.py",
    "content": "\"\"\"\nEJERCICIO:\n  Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n  en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n  - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n    conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n \"\"\"\n \n# OPERACIONES CON CADENAS DE CARACTERES\n\ns1 = \"Hola\"\ns2 = \"Daniel\"\n\n# Concatenacion\nprint(s1 + ', ' + s2)\n\n# Repeticion\nprint(s1 * 5)\n\n# Indexacion\nprint(s1[0])\nprint(s1[1])\nprint(s1[2])\nprint(s1[3])\n\n# Longitud\nprint(len(s2))\n\n# Slicing \nprint(s1[0:3])\nprint(s1[3:])\nprint(s2[:2])\n\n# Busqueda\nprint(s1.find('a')) # Busqueda de 'a' en la cadena\nprint('a' in s1) # Verificacion de si hay una 'a' en la cadena\n\n# Reemplazo\ns3 = s1.replace('a', 'e')\nprint(s3)\n\n# Division\nprint(s2.split('i'))\n\n# Mayusculas y minusculas, capitalizacion\ns4 = s2.upper()\nprint(s4)\n\ns5 = s2.lower()\nprint(s5)\n\ns6 = s2.title()\nprint(s6)\n\n# VERIFICACION DE CADENAS\n# Verificacion de caracteres\nprint(s1.isalpha())\nprint(s1.isalnum())\n\n# Verificacion de numeros\nprint(s2.isdecimal())\nprint(s2.isdigit())\n\n# Verificacion de espacios\nprint(s1.isspace())\n\n# Verificacion de capitalizacion\nprint(s2.istitle())\n\n# Verificacion de capitalizacion\nprint(s2.islower())\n\n# Eliminacion de espacios\nprint(' Hello Python '.strip())\n\n# Formateo de cadenas\nname = 'Daniel'\nlast_name = 'Quiros'\nlanguage = 'pythton'\nprint('Me llamo {} {}. Y aprendo {}'.format(name, last_name, language))\n\n# Interpolacion de cadenas   \nname = 'Daniel'\nage = 25   \nprint('My name is {} and I am {} years old.'.format(name, age))\nprint(f'My name is {name} and I am {age} years old.')\n\n#Transformacion de cadenas\ns1 = 'Hello Python'\ns2 = list(s1)\nprint(s2)\n\n# Transformacion de listas a cadena\nl1 = ['H', 'e', 'l', 'l', 'o', ' ', 'P', 'y', 't', 'h', 'o', 'n']\ns3 = ''.join(l1)\nprint(s3)\n\n# Transformacion numerica\nn1 = \"123456789\"\nn2 = int(n1)\nprint(n2)\n\nn3 = '123.456'\nn4 = float(n3)\nprint(n4)\n   \n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n  Crea un programa que analice dos palabras diferentes y realice comprobaciones\n  para descubrir si son:\n  - Palíndromos\n  - Anagramas\n  - Isogramas \n \"\"\"\n\nprint('\\n--- EJERCICIO EXTRA ---\\n')\n\ndef extra():\n    palabra1 = input('Ingrese la primera palabra: ')\n    palabra2 = input('Ingrese la segunda palabra: ')\n    \n    # Palindromo\n    '''\n    Un palindromo es una palabra que se lee igual en ambos sentidos.\n    Por ejemplo: \n        - madam\n        - racecar\n        - aba\n        - radar\n    '''\n    print(f'¿{palabra1} es un palindromo?: {palabra1 == palabra1[::-1]}')\n    print(f'¿{palabra2} es un palindromo?: {palabra2 == palabra2[::-1]}')\n\n    # Anagrama\n    '''\n    Una palabra es un anagrama de otra si ambas palabras ordenadas alfabéticamente son iguales.\n    Por ejemplo:\n        - amor -> roma\n        - cosa -> asco\n        - teresa -> aretes\n        - madam -> damma\n    '''\n    print(f'¿{palabra1} es un anagrama de {palabra2}?: {sorted(palabra1) == sorted(palabra2)}')\n   \n    # Isograma\n    '''\n    Una palabra es un isograma si cada letra aparece una sola vez.\n    Por ejemplo:\n        - amor\n        - cosa\n        - python\n    '''\n    print(f'¿{palabra1} es un isograma?: {len(palabra1) == len(set(palabra1))}')\n    print(f'¿{palabra2} es un isograma?: {len(palabra2) == len(set(palabra2))}')\n\n\nextra()"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/Daparradom.py",
    "content": "### 04_Cadenas de Caracteres ###\n\n#creating string\nmy_string = \"Hello Python\"\nprint(my_string)\n\nmultiline_string=\"\"\"Hello Python Im mr David\nHello Python Im mr David\nHello Python Im mr David\n\"\"\"\nprint(multiline_string)\n\n#String Concatenation\n\nname = \"David\"\nlast_name = \"Parrado\"\nspace = \" \"\nfull_name = name + space + last_name\nprint(full_name)\n\n#separating strings \n\nprint(\"Python es un buen lenguaje.\\nNo crees?\")\nprint(\"Python es un buen lenguaje.\\tNo crees?\")\n\n#Strin formatting \n# strings and numbers\noperation = \"area\"\nradius = 10\npi = 3.14\narea = pi * radius ** 2\n#formated_string = 'The %s of circle with a radius %d is %.2f.' %(operation,radius, area)\n#print(formated_string)\n\n# f-strings\n\nformated_fstring = f'The {operation} of circle with a radius {radius} is {area:.2f}.'\nprint(formated_fstring)\n\n#python Strings as sequences of characters\n\nlenguaje = \"Python\"\na,b,c,d,e,f = lenguaje\nprint(a)\nprint(b)\nprint(c)\nprint(d)\nprint(e)\nprint(f,\"\\n\")\n\n#accesing for index\n\nfirst_letter = lenguaje[0]\nprint(first_letter)\nsecond_letter = lenguaje[1]\nprint(second_letter)\nlast_index = len(lenguaje) - 1\nlast_letter = lenguaje[last_index]\nprint(last_letter,\"\\n\")\n\n#slicing python strings\n\nfirst_three = lenguaje[0:3] #Del caracter en el indice 0 hasta el 3 pero no incluye este.\nprint(first_three)\nlast_three = lenguaje[3:6]\n#print(last_three)\n\n#otra forma\nlast_three = lenguaje[3:]\nprint(last_three,\"\\n\")\n\n#Reversing a string \n\nprint(my_string[::-1],\"\\n\")\n\n#Skipping Characters While Slicing\n\nch = lenguaje[0:6:2]\nprint(ch,\"\\n\")\n\n#String Methods\n\nother_string = \"aprendiendo\\tpython\"\nprint(other_string.capitalize()) #coloca en mayuscula la primera letra del string\nprint(other_string.count(\"e\")) #cuenta las veces que aparace la letra \nprint(other_string.endswith(\"ion\")) #verifica si el string finaliza con la cadena o letra especificada\nprint(other_string.expandtabs(10)) #reemplaza tabs por espacios\nprint(my_string.find(\"n\")) # retorna el indice de la primera ocurrencia de una letra o cadena, retorna -1 si no hay ocurrencias\nprint(my_string.rfind(\"o\")) # retorna el indice de la ultima ocurrencia de una letra o cadena, retorna -1 si no hay ocurrencias\n\nprint(other_string.isalnum()) #revisa si es un caracter alphanumerico\nprint(other_string.isalpha()) #revisa si es un caracter alfabetico (a-z A-Z)\nprint(other_string.isdecimal()) #revisa si es un caracter decimal (0-9)\nprint(other_string.islower()) #revisa si la cadena esta en minusculas\nprint(other_string.isupper()) #revisa si la cadena esta en mayusculas\n\nlanguages = [\"Html\" , \"CSS\" , \"JS\", \"React\"]\nres =\" \".join(languages) #Retorna una cadena concatenada\nprint(res)\n\nprint(my_string.strip(\"He\")) # elimina todos los caracteres especificados de la cadena\n\nprint(my_string.replace(\"Python\",\"World\")) #Reemplaza subcadenas por cadenas especificadas\n\nprint(multiline_string.split()) # Divide la cadena, separada por caracteres dados o por espacios\n\nprint(other_string.title())\n\nprint(other_string.swapcase()) #pone mayusculas en minusculas y visceversa\n\n\nprint(other_string.startswith(\"ap\")) #valida si la cadena comienza con una letra o subcadena especificada\n\n# EXTRA #\n\ndef my_string (cadena_1 :str, cadena_2:str):\n    \n    #Comprobacion Palindromo\n    if  cadena_1.lower() == cadena_1.lower()[::-1] and cadena_2.lower() == cadena_2.lower()[::-1]  :\n        print(f\"la palabras {cadena_1} y {cadena_2} son palindromos\")\n    elif cadena_1.lower() ==  cadena_1.lower()[::-1] and cadena_2.lower() != cadena_2.lower()[::-1] :\n        print(f\"la palabra {cadena_1} es un palindromo pero {cadena_2} no lo es\")\n    elif cadena_1.lower() != cadena_1.lower()[::-1] and cadena_2.lower() == cadena_2.lower()[::-1]:\n        print(f\" la palabra {cadena_2} es un palindromo pero {cadena_1} no lo es\")\n    else:\n        print(f\" las palbras {cadena_1} y {cadena_2} no son palindromos\" )\n\n    #comprobacion anagrama\n    if sorted(cadena_1.lower()) == sorted(cadena_2.lower()) and cadena_1.lower() != cadena_2.lower():\n        print(f\"Las palabras {cadena_1} y {cadena_2} son anagramas entre si\")\n    else:\n        print(f\"Las palabras {cadena_1} y {cadena_2}  no son anagramas entre si\")\n    \n    #comprobacion isograma\n    def isogram(word: str) -> bool:\n        word_dict = dict()\n        for ch in word:\n            word_dict[ch] = word_dict.get(ch, 0) + 1\n        \n        isogram = True\n        values = list(word_dict.values())\n        isogram_len = values[0]\n        for word_count in values :\n            if word_count != isogram_len:\n                isogram = False\n                break\n        return isogram\n    print(f\"La palabra {cadena_1} es un isograma?: {isogram(cadena_1)}\")\n    print(f\"La palabra {cadena_2} es un isograma?: {isogram(cadena_2)}\")\n\nmy_string(\"iman\" , \"mani\")\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/DataCiriano.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\"\"\"\n \n#Operaciones con cadenas de texto.\n\n#Definición de una cadena\n \nmi_cadena = \"Hola mundo, estoy haciendo el roadmap de \"\nmi_cadena2 = \"Python\"\nmi_cadena3 =  \"2024\"\n\n\n#Desempaquetado cadena\n\na,b,c,d,e,f = mi_cadena2\nprint(a)\nprint(b)\nprint(c)\nprint(d)\nprint(e)\nprint(f)\n\n#Concatenación de cadenas\n\ncadena_unida = mi_cadena + mi_cadena2\nprint(cadena_unida)\n\n#Formateo de una cadena (deferentes formas)\nnombre = \"Pepito\"\nsaludo = f\"Hola, bienvenido a este roadmap {nombre}\"\nprint(saludo)\n\nsaludo2 = \"Hola, bienvenido a este roadmap {}\".format(nombre)\nprint(saludo2)\n\naño = 2020\nlenguaje_programacion = \"Python\"\n\nmensaje = \"Comencé a aprender %s en el año %i\" %(lenguaje_programacion, año)\nprint(mensaje)\n\n#Acceso a cararacteres de una cadena\n\nprint(mi_cadena2[0]) #Devueve el primer caracter de la cadena\nprint(mi_cadena2[-1]) #Devuelve el último caracter de la cadena\n\n#Slicing de una cadena\n \nprint(mi_cadena[12:]) #Devuele desde el caracter 3n al posiión 12 hasta el final de la cadena\nprint(mi_cadena[:-3]) #Devuelve desde el principio de la cadena hasta el 4 caracter empezando por el final\nprint(mi_cadena[18:26]) #Devuelve solo la palabra 'haciendo'\nprint(mi_cadena[::3]) #Devuelve un caracter de cada 3\n\n#Invertir una cadena\n\nprint(mi_cadena[::-1])\n\n#Métodos de las cadenas de carateres\n\nprint(mi_cadena.upper()) #Convertir a mayúsculas\nprint(mi_cadena.lower()) #Convertir a minúculas\nprint(mi_cadena.capitalize()) #Poner la primera letra de la cadena en mayúsculas\nprint(mi_cadena.title()) #Poner la primera letra de cada palabra en mayúculas \nprint(mi_cadena2.swapcase()) #Invertir mayúsculas y minúculas de una cadena\n\nprint(mi_cadena.endswith(\"python\")) #Devuelve True si la cadena acaba por 'python' si no devuelve False\nprint(mi_cadena.startswith(\"Hola \")) #Devuelve True si la cadena empeza por 'Hola ' sei no devuelve False\n\nprint(mi_cadena.count(\"o\")) #Devuelve el número total de 'o' en la cadena\n\nprint(mi_cadena.index(\"e\")) #Devuelve el índice de la priemra 'e' de la cadena\nprint(mi_cadena.rindex(\"e\")) #Devuelve el índice máxio del caracter buscado\n\nprint(mi_cadena.find(\"estoy\")) #Devuelve el índice de los caracteres buscados en la cadena\nprint(mi_cadena.rfind(\"e\")) #Devuelve el índice de la última ocurrencia del caracter buscado\n\nprint(mi_cadena.replace(\"Hola\", \"Buenos días\")) #Reemplazo de caracteres de una cadena\n \nprint(mi_cadena.isalnum()) #Devuelve True si todos lso caracters de la cadena son alfanuméricos, si no False\nprint(mi_cadena.isalpha()) #Devuelve True si todos las caracteres de la cadena son (a-z and A-Z), si no False (el espacio no cuenta)\nprint(mi_cadena3.isdecimal()) #Devuelve True si todos las caracteres de la cadena son (0-9), si no False\nprint(mi_cadena3.isdigit()) #Devuelve True si todos las caracteres de la cadena son (0-9), si no False\nprint(mi_cadena3.isnumeric()) #Igua que .isdigit() pero se aceptan más caracters numérico (por ejemplo ½)\nprint(mi_cadena.isidentifier()) #Devuelve True si la cadena es un nombre valido para una varaible, si no False\nprint(mi_cadena.islower()) #Devuelve True si todos los caracteres están en minúsculas, si no False\nprint(mi_cadena.isupper()) #Devuelve True si todos los caracteres están en mayúsculas, si no False \n\n#Convertir una lista en una cadena de caracteres separad por espacios\n\nlista_lenguajes = [\"Python\", \"JavaScript\", \"Java\", \"HTML\", \"R\"]\nlenguajes = \" \".join(lista_lenguajes)\nprint(lenguajes)\n\n#Separa una cadena de caracteres en una lista por un delimitador\n\nlista_palabras = mi_cadena.split(\" \")\nprint(lista_palabras)\n\n\n#---EXTRA---\n\ndef analizar_palabras(word1: str, word2: str): \n    \n    #Palíndromo\n    print(f\"¿La palabra {word1} es palíndromo? {word1 == word1[::-1]}\")\n    print(f\"¿La palabra {word2} es palíndromo? {word2 == word2[::-1]}\")\n    \n    #Anagrama\n    print(f\"¿La palabra {word1} es anagrama de {word2}? {sorted(word1) == sorted(word2)}\")\n    \n    #Isograma\n    print(f\"¿Es la palabra {word1} un isograma? {len(word1) == len(set(word1))}\")\n    print(f\"¿Es la palabra {word2} un isograma? {len(word2) == len(set(word2))}\")\n    \n    \nanalizar_palabras(\"reconocer\", \"perro\")\nanalizar_palabras(\"amor\", \"roma\")\nanalizar_palabras(\"radar\", \"murcielago\")\n\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/DevKnn.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\n *   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\n *   interpolación, verificación...\n\"\"\"\npalabra = \"pera\"\nnumero = 9\nprint(len(palabra))\nprint(palabra.find(\"o\") ) # encuentra solo donde aparezca el primer caraacter en la app\nprint(palabra.count(\"a\") ) # encuentra todo los caracteres dentro de la app \nprint(palabra.replace(\"a\", \"e\") ) #remprazamos los caracteres \nprint(palabra.islower() ) # comprobamos si la palabra es minuscuka\nprint(palabra.isdigit()) # comprobamos si la palabra es un digito\nprint(palabra + \" \" +\"nueva\") #concardenacion de palabras\nprint(palabra.lower()) # colocamos la palabra en minuscula\nprint(palabra.split()) # convertimos la palabra en lista\nprint(palabra.upper()) # colocamos la palabra en mayuscula\nprint(palabra[::-1]) #reverso de unaa cadena \nprint(palabra[3:6]) #cortando cadena\nprint(\"hola %s %d\" % (palabra,numero)) #interpolacion\nprint(f\"mi palabra es {palabra} mi numero es {numero}\")\nprint(\"Mi palabrra es {} y mi numero es {}\".format(palabra,numero)) #interpolacion\n\n\n\n\n\n\n\n\n\n \n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\"\"\"\n \ndef palidromo():\n    palabra = input(\"Ingrese la palabra para comprobar si es un anagrama: \").lower()\n    palabra2 = palabra[::-1]\n    if (palabra == palabra2):\n        return f\"La palabra {palabra}\\nEs un palidromo.\"\n    else:\n        return f\"La palabra {palabra}/nNo es un palidromo.\"   \n#print(palidromo())\n\ndef anagrama():\n    tx1 = input(\"Ingrese la primera palabra: \").lower()\n    txt2 = input(\"Ingrese la segunda palabra: \").lower()\n\n    if len(sorted(tx1)) == len(sorted(txt2)):\n        return f\"La palabra {tx1}y la palabra {txt2}:\\nSon un anagrama.\"\n    else:\n        return f\"La palabra {tx1} y la palabra {txt2}:\\nNo son anagrama.\" \n#print(anagrama())\n\ndef isograma():\n    palabra = \"repeticion\"\n    nuevaPalabra = set(palabra.lower())\n    \n    if (len(nuevaPalabra) == len(nuevaPalabra)):\n        return \"La palabra {} \\nEs un Isograma\".format(palabra)\n\nprint(isograma())\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/DiegoIBB.py",
    "content": "'''\n* EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n '''\n\n#-------------------------------------------------\n#-------------- OPERACIONES BASICAS --------------\n#-------------------------------------------------\n\n\n#CONCATENAZIÓN ---> Unir 2 cadenas de diferentes variables\nstring_1 = \"La hora es \"\nstring_2 = \"21:30\"\nconcatenacion = string_1 + string_2\nprint(concatenacion)\n\n#INDEXACIÓN ---> Acceder a un caracter especifico de una cadena por medio de su indice\nstring_3 = \"Programacion\"\ncaracter = string_3[5]\nprint(caracter)\n\n\n\n\n#-------------------------------------------------\n#-------------- METODOS CON CADENAS --------------\n#-------------------------------------------------\n\n\n#------ CAPITALIZE ---> Transforma la primera letra de una cadena en mayuscula\ncadena_1 = \"hola\"\nc1 = cadena_1.capitalize()\nprint(c1)\n\n#------ CASEFOLD ---> Convierte una cadena a minusculas\ncadena_2 = \"HaY MuchAs MayusCuLas\"\nc2 = cadena_2.casefold()\nprint(c2)\n\n#------ COUNT ---> Cuenta la cantidad de veces que se repite un elemento de las string\ncadena_3 = \"pelar manzanas, cocer manzanas, servir manzanas\"\nc3 = cadena_3.count(\"manzanas\")\nprint(c3)\n\n#------ FIND ---> Devuelve la cantidad de elementos que coincidan con un caracter a indicar\ncadena_4 = \"Bienvenido\"\nc4 = cadena_4.find(\"i\")\nprint(c4)\n\n#------ JOIN ---> Une todos los elementos de un grupo de elementos con un caracter de conexión\nlista_1 = [\"Esta\", \"es\", \"una\", \"cadena\", \"de\", \"una\", \"lista\"]\nc5 = \" \".join(lista_1)\nprint(c5)\n\n#------ PARTITION ---> Divide una cadena en 3 partes y devuelve una tupla\ncadena_5 = \"las cadenas pueden dividirse con el método partition\"\nc6 = cadena_5.partition(\"dividirse\")\nprint(c6)\n\n#------ RSTRIP ---> Nos permite eliminar los espacios vacios al final de una cadena\ncadena_6 = \"nombre        \"\nc7 = cadena_6.rstrip()\nprint(\"Mi\", c7, \"es Ignacio\")\n\n\n#------ SPLIT ---> Divide una cadena en sus diferentes palabras y las guarda en una lista\ncadena_7 = \"las cadenas pueden dividirse usando split\"\nc8 = cadena_7.split()\nprint(c8)\n\n#------ RSPLIT ---> Crea una lista a partir de una cadena usando un separador especial\ncadena_8 = \"Mercedez Benz, Audi, Porsche, BMW, Volkswagen\"\nc9 = cadena_8.rsplit(\", \")\nprint(c9)\nprint(c9[3])\n\n#------ TITLE ---> Convierte el primer caracter de cada palabra de una string en mayusculas\ncadena_9 = \"diego, pablo, felipe, jose, maria, miguel\"\nc10 = cadena_9.title()\nprint(c10)\n\n#------ SWAPCASE ---> Convierte mayusculas en minusculas y viceversa\ncadena_10 = \"Las Jerarquia Se Invierte\"\nc11 = cadena_10.swapcase()\nprint(c11)\n\n\n#------ UPPER ---> Convierte todas las letras a myusculas\ncadena_11 = \"estoy gritando\"\nc12 = cadena_11.upper()\nprint(c12)\n\n#------ REPLACE ---> Reemplaza todos los caracteres que conicidan con uno definido \ncadena_12 = \"coincidencia\"\nc13 = cadena_12.replace(\"i\", \"a\")\nprint(c13)\n\n\n'''\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n '''\n\n\n#PALINDROMO: Palabra o frase cuyas letras están dispuestas de tal manera que resulta la misma leída de izquierda a derecha que de derecha a izquierda\n\ncadena_original = input(\"Palindromo ?: \")\nlista_letras = []\nlista_2 = [] #Para obtener la cadena original sin espacios\ncounter = 0\n\ncadena_Reversa = \"\"\ncadena_notReversa = \"\"\ncadena_aux = \"\"\n\n#Transformar la cadena a lista\nfor l in cadena_original:\n    #print(l)\n    lista_letras.append(l)\n\n#Quitar espacios a la cadena original e invertirla\nfor c in range(0, len(lista_letras)):\n    cadena_aux = lista_letras[c]\n    if cadena_aux == \" \":\n        continue\n    elif cadena_aux != \" \":\n        cadena_Reversa = cadena_aux + cadena_Reversa\n\n#Reconstruir la cadena original a partir de la cadena invertida sin espacios\nfor f in cadena_Reversa:\n    lista_2.append(f)\n    cadena_notReversa = lista_2[counter] + cadena_notReversa\n    counter += 1\n\nprint(lista_2) #Lista\nprint(cadena_notReversa) #Cadena reconstruida sin espacios\n\n\nprint(\"Cadena Original: \" + cadena_notReversa)\nprint(\"Cadena Reversa: \" + cadena_Reversa)\n\nif cadena_notReversa == cadena_Reversa:\n    print(\"La cadena es un palindromo\")\nelse:\n    print(\"La cadena no es un palindromo\")\n\n\n#ANAGRAMA:\n\nstring_org_An = input(\"Cadena Original: \")\nstring_comp = input(\"Anagrama?: \")\ncounter = 0\ncharCounter = 0\nlist_strOrg = []\nlist_comp = []\n\nfor i in string_org_An:\n    char1 = i.lower()\n    list_strOrg.append(char1)\n\nfor h in string_comp:\n    char2 = h.lower()\n    list_comp.append(char2)\n\nlen_cadOrg = len(list_strOrg)\nlen_cadCom = len(list_comp)\n\nif len_cadOrg == len_cadCom:\n    print (len_cadOrg , \"=\", len_cadCom ) #Evaluamos si el largo de caracteres coincide\n    for c in list_strOrg:\n        charCounter = 0 #Char counter se actualiza aquí por cada vez que ingresa una nueva letra para ser coparada con las de la segunda cadena\n        for d in list_comp:\n            if (c == d):\n                charCounter+=1\n                counter+=1\n                if charCounter == 2:\n                    counter -= 1\n                else:\n                    print(c, \" is in \", string_comp)\n            else:\n                continue\n\n    if counter == len_cadOrg:\n        print(\"Strings are anagramas\")\n    else:\n        print(\"String are not anagramas\")\n        print(counter, \" = \", len_cadOrg)\nelse:\n    print(\"la cadena no es un anagrama\") \n\n\n#ISOGRAMA: Palabra o frase donde cada letra aparece el mismo número de veces\n\nisograma = input(\"Isograma: \")\nisogramaToLower = isograma.lower()\nlista_iso = []\nletra = 0\ncontador = 0\ncaracterIsograma = {}\n\nprint(isogramaToLower)\n\nfor c in isogramaToLower:\n    lista_iso.append(c)\n\nfor i in lista_iso:\n    caracterIsograma[i] = 1\n    # letra = i\n    # lista_iso.remove(i)\n    # for l in lista_iso:\n    #     if letra == l:\n    #         contador += 1\n    #     else:\n    #         continue\n    # print(f\"{letra}, {contador}\")\n\n    #caracterIsograma[i] = 1\n\nprint(caracterIsograma)\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/Dkp-Dev.py",
    "content": "\"\"\"\nEJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\n *   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\n *   interpolación, verificación...\n\"\"\"\n\n# Operaciones\n\nx1 = \"Perro\"\nx2 = \"Conejo\"\nx3 = \"tortuga nadando\"\n\nprint(x1 + x2)      # Concatenacion (pegar dos o mas cadenas de texto)\n\nprint(x1 * 3)       # Repeticion\n\nprint(x1[4] + x1[3] + x1[2] + x1[1] + x1[0])    # Indexacion (indicar un solo caracter de la cadena)\n\nprint(len(x2))      # Longitud\n\nprint(x2[2:6])      # Slicing (porcionar la cadena de texto)\nprint(x2[2:])\nprint(x2[:4])\n\nprint(\"e\" in x1)    # Busqueda (comprobar si el/los caracteres se encuentran en una cadena de texto)\nprint(\"jo\" in x2)\n\nprint(x2.replace(\"o\",\"a\"))  # Remplazo\n\nprint(x2.split(\"e\"))        # Division de una cadena que da como resultado una lista\n\nprint(x3.upper())   # Convertir a Mayusculas\n\nprint(x1.lower())   # Convertir a minusculas\n\nprint(x3.title())   # Primera letra a mayuscula de cada palabra\n\nprint(x3.capitalize())  # Primera letra a mayuscula de toda la cadena de texto\n\nprint(\" Dkp Dev \")\nprint(\" Dkp Dev \".strip())  # Elimincacion de espacios al comienzo y al final de la cadena\n\nprint(x3.startswith(\"Tor\")) # Comprueba si la cadena inicia con los caracteres que se especifiquen\nprint(x3.startswith(\"tor\"))\n\nprint(x3.find(\"ando\"))  # Busqueda por posicion del caracter\n\nprint(x3.count(\"a\"))    # Busqueda de ocurrencias (cuantas veces aparece el caracter)\n\nprint(\"{}, {} y {}\".format(x1,x2,x3))   # Formateo de una cadena eligiendo donde insertare mis cadenas de texto\n\nprint(f\"{x2}, {x1} y {x3}\")     # Interpolacion\n\nprint(list(x1))         # Transforma una cadena en lista\n\nl1 = [x1, x2, \"y\", x3]\nprint(\" \".join(l1))     # Transforma una lista a cadena de texto\n\nx4 = \"357\"          # Transformar una cadena numerica en un 'int'\nx4 = int(x4)\nprint(x4)\n\nx5 = \"35.7\"         # Transformar una cadena numerica en un 'float'\nx5 = float(x5)\nprint(x5)\n\nx1 = \"Perro\"            # Comprobaciones\nx6 = \"123123\"\nprint(x1.isalpha())     # Si la cadena es alfabetica (solo contiene letras)\nprint(x6.isalpha())\n\nprint(x1.isnumeric())   # Si la cadena es numerica (solo contiene numeros)\nprint(x6.isnumeric())\n\nprint(x1.isalnum())     # Si la cadena es alfanumerica (contiene letras y/o numeros)\nprint(x6.isalnum())\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos (palabras que se leen igual aunque se posiciones en orden inverso como radar o salas)\n * - Anagramas (palabras que contiene las mismas letras pero en diferente orden)\n * - Isogramas (palabras que no tienen mas de una letra repetida)\n\n\"\"\"\n\ndef check(cadena1: str,cadena2: str):\n\n    # Palindromo\n    print(f\"Es {cadena1} un palindromo?: {cadena1 == cadena1[::-1]}\")   # Mediante el slicing comprobamos si la cadena se lee igual en reversa\n    print(f\"Es {cadena2} un palindromo?: {cadena2 == cadena2[::-1]}\")\n\n    # Anagramas\n    print(f\"Es {cadena1} un anagrama de {cadena2}?: {sorted(cadena1) == sorted(cadena2)}\")      # Se ordenan las cadenas y se comprueban los characteres\n\n    # Isograma\n\n    def isograma(cadena:str) -> bool:       # Funcion que recibe una cadena y arroja un booleano\n\n        cadena_dict = dict()        # Primero un dict de la cadena\n        for letras in cadena:\n            cadena_dict[letras] = cadena_dict.get(letras, 0) + 1\n\n        isograma = True\n        valor = list(cadena_dict.values())      # Lista de values\n        isograma_len = valor[0]\n        for cadena_count in valor:              # Se cuentan los values\n            if cadena_count != isograma_len:    # Se comprueban ambas listas\n                isograma = False\n                break\n\n        return isograma\n\n    print(f\"Es {cadena1} un isograma? {isograma(cadena1)}\")\n    print(f\"Es {cadena2} un isograma? {isograma(cadena2)}\")\n\n\n   \n\ncheck(\"radar\",\"quesoqueso\")\ncheck(\"amor\",\"roma\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/EliasBonnin.py",
    "content": "# Ejercicio 04\n# En el siguiente URL https:/python.org Tenemos la documentacion de phyton.\n# Los retos se encuentran en https://retosdeprogramacion.com\n\n# Variables\n\nv_cadena = \"Hola\"\nv_cadena2 = \"Python\"\nv_cadena3 = \"elias bonnin\"\nv_cadena4 = \"elias bonnin @hotmail\"\nv_cadena5 = \"123456\"\nlist_c = [v_cadena, \", \", v_cadena2, \"! \"]\n\n# Concatenacion\n\nprint(v_cadena + \", \" + v_cadena2 + \"!\")  # Concatenamos cadenas sumandolas, podemos agregar espacios en el medio\n\n# Repeticion\n\nprint(v_cadena * 3)  # Repetimos la cantidad de veces de 3 en este caso\n\n# Indexacion\n\nprint(v_cadena[0] + v_cadena[1] + v_cadena[2])\n\n# Longitud\n\nprint(len(v_cadena2))\n\n# Slicing (Particionar)\n\nprint(v_cadena2[2:6])  # Si queremos un slice Concetro\n\nprint(v_cadena2[2:])  # Imprime hasta el final si necesidad de decirlo\n\nprint(v_cadena2[:2])  # Imprime desde el inicio hasta el indice 2 si necesidad de aclararlo\n\n# Busqueda\n\nprint(\"a\" in v_cadena)  # Buscamos si una cadena de caracteres \"a\" esta contenida en otra cadena \"v_cadena\"\n\n# Remplazo\n\nprint(v_cadena.replace(\"o\", \"a\"))  # Remplazamos donde estaria la existencia de cadena \"o\" por una \"a\"\n\n# Division\n\nprint(v_cadena2.split(\"t\"))  # Dividimos en el lugar que eligamos\"t\" y eliminamos en el proceso el punto elegido\n\n# Conversion Mayusculas y Minusculas y Primera letra Mayuscula\n\nprint(v_cadena.upper())  # Pone todo en Mayuscula\nprint(v_cadena.lower())  # Pone todo en Minuscula\nprint(v_cadena3.title())  # Pone todos los primeros caracteres en Mayuscula\nprint(v_cadena3.capitalize())  # Pone solo el PRIMER caracter en Mayuscula\n\n# Eliminacion de espacios al principio y final\n\nv_cadena3 = \" elias bonnin \"\nprint(v_cadena3.strip() + \"Eliasdev\")\n\n# Busqueda a principio y al final\n\nprint(v_cadena.startswith(\"Ho\"))  # Podemos ver si la cadena empieza por un determinado texto\nprint(v_cadena.startswith(\"Py\"))\n\nprint(v_cadena.endswith(\"la\"))  # Podemos ver si la cadena termina por un determinado texto\n\n# Busqueda de posicion\n\nprint(v_cadena4.find(\"bonnin\"))  # Nos dice la Posicion donde esta empezando esa cadena buscada\nprint(v_cadena4.lower().find(\"b\"))  # Se queda con la primera ocurrencia de match\n\n# Busqueda de ocurrencias\n\nprint(v_cadena4.lower().count(\"n\"))  # Me dice cuantas \"n\" hay en una cadena\n\n# Formatear\n\nprint(\"Saludo: {} , Lenguaje: {} !\".format(v_cadena, v_cadena2))\n\n# Interpolacion FSTRING\n\nprint(f\"Saludo: {v_cadena} , Lenguaje: {v_cadena2} !\")\n\n# Transformacion en lista de caracteres\n\nprint(list(v_cadena3))\n\n# Transformacion de lista en cadena\n\nprint(\"\".join(list_c))  # Une o concatena una lista de caracteres por un criterio\n\n# Transformaciones numericas\n\nprint(v_cadena5)\nv_cadena5 = int(v_cadena5)\nprint(v_cadena5)\nv_cadena5 = float(v_cadena5)\nprint(v_cadena5)\n\n# Comprobaciones\n\nprint(v_cadena4.isalnum())  # alfanumero\nprint(v_cadena.isalpha())  # Solo alfabetico\nprint(v_cadena.isnumeric())  # Es numerico\n\n# Extra\n\n# Funcion\n\n\ndef Check(Palabra1, Palabra2: str):\n\n    # Palindromo\n\n    print(f\"{Palabra1} es un palindromo? {Palabra1 == Palabra1[::-1]}\")  # Con el slider el inverso de la palabra\n    print(f\"{Palabra2} es un palindromo? {Palabra2 == Palabra2[::-1]}\")\n\n    # Anagrama\n\n    print(f\"{Palabra1} es un anagrama? {sorted(Palabra1) == sorted(Palabra2)}\")\n\n    # Isograma\n\n    def isograma(Palabra: str) -> bool:\n\n        dic_palabras = dict()\n        for Palabra in Palabra2:\n            dic_palabras[Palabra] = dic_palabras.get(Palabra, 0) + 1\n\n        isograma = True\n        Valores_dic = list(dic_palabras.values())\n        len_isograma = Valores_dic[0]\n        for Palabra_count in Valores_dic:\n            if Palabra_count != len_isograma:\n                isograma = False\n                break\n\n        return isograma\n\n    print(f\"{Palabra1} es un isograma? {isograma(Palabra1)}\")\n    print(f\"{Palabra2} es un isograma? {isograma(Palabra2)}\")\n\n\nCheck(\"radar\", \"phytonphytonphytonphyton\")\nCheck(\"amor\", \"roma\")\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/EmmanuelMMontesinos.py",
    "content": "\"\"\"\r\n/*\r\n * EJERCICIO:\r\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\r\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\r\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\r\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\r\n */\r\n\"\"\"\r\n\r\n# Operaciones con strings\r\ntexto = \"En python es muy fácil programar\"\r\nprint(f\"Texto original: {texto}\\n\")\r\n\r\n\"\"\"Acceso a caracteres específicos\"\"\"\r\nprint(f\"Primera letra: {texto[0]}\")\r\nprint(f\"Última letra: {texto[-1]}\\n\")\r\n\r\n\"\"\"Subcadenas\"\"\"\r\nsubcadena_python = texto[3:9]\r\nprint(f\"Subcadena '3:9': {subcadena_python}\\n\")\r\n\r\n\"\"\"Longitud\"\"\"\r\nlongitud_texto = len(texto)\r\nprint(f\"El texto mide: {longitud_texto} caracteres\\n\")\r\n\r\n\"\"\"Concanetación\"\"\"\r\ntexto_concatenado = texto + \" gracias a la comunidad\"\r\nprint(f\"Texto concatenado: {texto_concatenado}\\n\")\r\n\r\n\"\"\"Repetición\"\"\"\r\ntexto_repetido = (texto + \"\\n\") * 2\r\nprint(f\"Texto repetido:\\n{texto_repetido}\")\r\n\r\n\"\"\"Recorrido\"\"\"\r\nletras = []\r\nfor letra in texto:\r\n    letras.append(letra)\r\nprint(f\"Recorrido: {letras}\\n\")\r\n\r\n\"\"\"Conversión a mayúsculas y minúsculas\"\"\"\r\ntexto_mayus = texto.upper()\r\nprint(f\"Texto en Mayúsculas: {texto_mayus}\")\r\ntexto_minus = texto.lower()\r\nprint(f\"Texto en Minúsculas: {texto_minus}\\n\")\r\n\r\n\"\"\"Reemplazo\"\"\"\r\ntexto_reemplazado = texto.replace(\"python\", \"bash\")\r\nprint(f\"Texto Reemplazado: {texto_reemplazado}\\n\")\r\n\r\n\"\"\"División\"\"\"\r\ntexto_dividido = texto.split()\r\nprint(f\"Texto Dividido: {texto_dividido}\\n\")\r\n\r\n\"\"\"Unión\"\"\"\r\ntexto_unido = \"$\".join(texto)\r\nprint(f\"Texto Unido: {texto_unido}\\n\")\r\n\r\n\"\"\"Interpolación\"\"\"\r\ntexto_interpolado = f\"Y entonces el ordenador dijo: '{texto}'\"\r\nprint(f\"Texto Interpolado:\\n{texto_interpolado}\\n\")\r\n\r\n\"\"\"Verificación\"\"\"\r\nes_str = \"programar\" in texto\r\nprint(f\"Texto Verificado:\\n¿Está 'programar' en texto?: {es_str}\")\r\n\r\n\r\n\"\"\"\r\n * DIFICULTAD EXTRA (opcional):\r\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\r\n * para descubrir si son:\r\n * - Palíndromos\r\n * - Anagramas\r\n * - Isogramas\r\n\"\"\"\r\n\r\n\r\ndef filtro(str_1: str, str_2: str):\r\n    palindromo(str_1)\r\n    palindromo(str_2)\r\n    anagrama(str_1, str_2)\r\n    isograma(str_1)\r\n    isograma(str_2)\r\n\r\n\r\ndef palindromo(str_: str):\r\n    letras = []\r\n    ciclo = -1\r\n    for let in str_:\r\n        if let == str_[ciclo]:\r\n            ciclo -= 1\r\n        else:\r\n            return print(f\"{str_} NO es palíndromo\")\r\n    return print(f\"{str_} es palíndromo\")\r\n\r\n\r\ndef generar_dic(str_) -> dict[str:int]:\r\n    list_str = {}\r\n    for let in str_:\r\n        if let not in list_str:\r\n            list_str[let] = 1\r\n        elif let in list_str:\r\n            list_str[let] += 1\r\n    return list_str\r\n\r\n\r\ndef anagrama(str_1: str, str_2: str):\r\n    if len(str_1) == len(str_2):\r\n\r\n        list_str_1: dict = generar_dic(str_1)\r\n        list_str_2: dict = generar_dic(str_2)\r\n        if list_str_1 == list_str_2:\r\n            print(f\"{str_1} y {str_2} son anagramas\")\r\n        else:\r\n            print(f\"{str_1} y {str_2} NO son anagramas\")\r\n    else:\r\n        print(f\"{str_1} y {str_2} NO son anagramas\")\r\n\r\n\r\ndef isograma(str_: str):\r\n    lista = generar_dic(str_)\r\n    for value in lista.values():\r\n        if value > 1:\r\n            return print(f\"{str_} No es un isograma\")\r\n    return print(f\"{str_} es un isograma\")\r\n\r\n\r\nfiltro(\"amar\", \"rama\")\r\nfiltro(\"noon\", \"salsa\")\r\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/EricJoel-code.py",
    "content": "# Cadenas de caracteres son secuencias de caracteres que se utilizan para representar texto en Python.\n\n## Operaciones \n\ncadena1 = \"Hola\"\ncadena2 = \"Mundo\"\n\n# Concatenación\nprint(cadena1 + \", \" + cadena2) \n\n# Repetición\nprint(cadena1 * 3)\n\n#Indexación\nprint(cadena1[0])\n\n#Longitud\nprint(len(cadena1))\nprint(len(cadena2))\n\n#Slicing\nprint(cadena1[1:3]) # no incluye el índice final\nprint(cadena2[:3])  # desde el inicio hasta el índice 3 (no incluido)\nprint(cadena2[3:])  # desde el índice 3 hasta el final\nprint(cadena2[-1])  # último carácter\nprint(cadena2[-3:]) # últimos tres caracteres\n\n#Busqueda\nprint(cadena1.find(\"o\")) # índice de la primera ocurrencia de \"o\"\nprint(cadena2.find(\"x\")) # devuelve -1 si no se encuentra\n\nprint(\"a\" in cadena1) # True\nprint(\"x\" in cadena2) # False\n\n#Reemplazo\nprint(cadena1.replace(\"o\", \"a\")) \nprint(cadena2.replace(\"Mundo\", \"Python\"))\nprint(cadena2) # la cadena original no cambia\n\n#Division\nprint(cadena2.split(\"n\")) # divide en una lista\n\n#Conversion a mayusculas y minusculas\nprint(cadena1.upper())\nprint(cadena2.lower())\n\nprint(\"eric joel\".title()) # Convierte a mayúscula la primera letra de cada palabra\nprint(\"eric joel\".capitalize()) # Convierte a mayúscula la primera letra de la cadena\n\n#Eliminacion de espacios al inicio y al final\nprint(\"  Hola Mundo  \".strip())\nprint(\"  Hola Mundo  \".strip() + \"!!!\") # Concatenación después de eliminar espacios para mostrar el efecto \nprint(\"  Hola Mundo  \".lstrip() + \"!!!\") # Elimina espacios solo al inicio\nprint(\"  Hola Mundo  \".rstrip() + \"!!!\") # Elimina espacios solo al final\n\n#Busqueda al principio y al final\nprint(cadena1.startswith(\"H\"))\nprint(cadena1.startswith(\"o\"))\nprint(cadena2.endswith(\"do\"))\nprint(cadena2.endswith(\"x\"))\n\n#Busqueda de posiciones\nprint(cadena1.index(\"l\")) # index encuentra la primera l de izquierda a derecha\nprint(cadena1.rindex(\"l\")) # rindex encuentra la última l de derecha a izquierda \n#En este caso ambas devuelven 2 porque la primera l y la última l están en la misma posición\n\nprint(\"Eric Joel @ericcode\".find(\"joel\")) # find no distingue entre mayúsculas y minúsculas devuelve -1 \nprint(\"Eric Joel @ericcode\".find(\"Joel\"))\n\n#Búsqueda de ocurrencias\nprint(\"Hola Hola Hola\".count(\"Hola\")) # cuenta cuántas veces aparece \"Hola\"\nprint(\"Hola Hola Hola\".count(\"o\"))    # cuenta cuántas veces aparece \"o\"\n\n#Formateo de cadenas\nnombre = \"Eric\"\nedad = 30\nprint(\"Mi nombre es {} y tengo {} años\".format(nombre, edad))\n\n#Interpolacion\nprint(f\"Mi nombre es {nombre} y tengo {edad} años\")\n\n#Transformacion en lista de caracteres\nprint(list(cadena1))\n\n#Transformacion en cadena a partir de lista de caracteres\nprint(''.join(['H', 'o', 'l', 'a']))\nlista = [cadena1, \",\", cadena2, \"!\"]\nprint(''.join(lista))\n\n#Transformaciones numericas\nstr_num = \"12345\"\nstr_num = int(str_num)\nprint(str_num)\n\nstr_num2 = \"123.45\"\nstr_num2 = float(str_num2)\nprint(str_num2)\n\n#Combinaciones varias\nstr_num = \"12345\"\nprint(cadena1.isalpha()) # True si todos los caracteres son letras\nprint(cadena2.isdigit())  # True si todos los caracteres son dígitos\nprint(cadena1.isalnum())  # True si todos los caracteres son letras o dígitos\nprint(\"   \".isspace())    # True si todos los caracteres son espacios en blanco \nprint(str_num.isnumeric()) # True si todos los caracteres son numéricos\nprint(cadena2.isidentifier()) # True si es un identificador válido en Python\nprint(str_num.isupper()) # True si todos los caracteres son mayúsculas como es numérico devuelve False\nprint(cadena1.islower()) # True si todos los caracteres son minúsculas\nprint(cadena1.istitle()) # True si cada palabra comienza con mayúscula y el resto son minúsculas\n\n\n#Cadenas multilínea\ncadena_multilinea = \"\"\"Esta es una cadena\nmultilinea que ocupa varias lineas.\n\"\"\"\nprint(cadena_multilinea)\n\n\n#Extra\n\"\"\"Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\"\"\"\n\ndef palindormo():\n    \n    print(\"Verificador de palindromos\")\n    \n    palabra = input(\"Ingrese una palabra o frase para verificar si es un palindromo: \")\n    \n    palabra = palabra.replace(\" \", \"\").lower() # Elimina espacios y convierte a minúsculas  \n    \n    if palabra == palabra[::-1]: # Compara la palabra con su reverso\n        print(f\"{palabra} es un palindromo\")\n    else:\n        print(f\"{palabra} no es un palindromo\")\n\n\n\n\ndef anagrama():\n    \n    print(\"Verificador de anagramas\")\n    \n    palabra1 = input(\"Ingrese la primera palabra: \")\n    palabra2 = input(\"Ingrese la segunda palabra: \")\n    \n    palabra1 = palabra1.replace(\" \", \"\").lower()\n    palabra2 = palabra2.replace(\" \", \"\").lower()\n    \n    if sorted(palabra1) == sorted(palabra2): # Compara las palabras ordenadas alfabéticamente\n        print(f\"{palabra1} y {palabra2} son anagramas\")\n    else:\n        print(f\"{palabra1} y {palabra2} no son anagramas\")\n        \n\n\n\ndef isograma():\n    \n    print(\"Verificador de isogramas\")\n    \n    palabra = input(\"Ingrese una palabra para verificar si es un isograma: \")\n    palabra = palabra.replace(\" \", \"\").lower()\n    \n    if len(palabra) == len(set(palabra)): # Compara la longitud de la palabra con la longitud del conjunto de caracteres únicos\n        print(f\"{palabra} es un isograma\")\n    else:\n        print(f\"{palabra} no es un isograma\")\n\n\n\ndef menu():\n    print(\"1. Palindromo\")\n    print(\"2. Anagrama\")\n    print(\"3. Isograma\")\n    print(\"4. Salir\")\n    while True:\n        opcion = input(\"Seleccione una opción (1-4): \")\n        if opcion == \"1\":\n            palindormo()\n        elif opcion == \"2\":\n            anagrama()\n        elif opcion == \"3\":\n            isograma()\n        elif opcion == \"4\":\n            print(\"Saliendo del programa...\")\n            break\n        else:\n            print(\"Opción no válida. Intente de nuevo.\")\n            \nmenu()"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/FabianRpv.py",
    "content": "# Operaciones con Cadena de Caracteres\n\nstr1 = \"Hola\"\nstr2 = \"Mundo\"\n\nconcatenacion = str1 + \" \" + str2  # Concatenar Strings\nprint(concatenacion)\n\nrepeticion = str1*3\nprint(repeticion)  # Repetir Strings\n\nlongitud = len(str1)  # Ver la longitud de un String\nprint(longitud)\n\nindexacion = str1[0]  # Acceder a una posicion del String\nprint(indexacion)\n\nbusqueda = \"H\" in str1  # Verificar si existe un valor en el String\nprint(busqueda)\n\ninicio = str1.startswith(\"Hol\")  # Verificar si inicia el String con...\nfin = str1.endswith(\"la\")  # Verificar si finaliza el String con...\nprint(inicio)\nprint(fin)\n\nposicion = str1.index(\"o\")  # Devuelve la posicion si el valor existe en el String\nprint(posicion)\n\nminusculas = concatenacion.lower()  # Convierte el String a Minusculas\nprint(minusculas)\n\nmayusculas = concatenacion.upper()  # Convierte el String a Mayusculas\nprint(mayusculas)\n\ntitle = concatenacion.title()  # Convierte la primera letra de cada palabra en Mayuscula\nprint(title)\n\ncapitalize = concatenacion.capitalize()  # Convierte la primera letra de la oracion en Mayuscula\nprint(capitalize)\n\nordenar =  sorted(str1)  # Ordena la lista segun su valor unicode\nprint(ordenar)\n\nprint(\"  hola  \".strip())   # Elimina espacios\nprint(\"  hola  \".lstrip())  # Elimina espacios al principio\nprint(\"  hola  \".rstrip())  # Elimina espacios al final\n\nremplazo = concatenacion.replace(\"Mundo\", \"Python\")  # Reemplaza valores en los Strings\nprint(remplazo)\n\nunion = \", \".join([\"a\", \"b\", \"c\"]) # Une datos en un String\nprint(union)\n\ndivision = union.split(\",\")  # Dividir caracteres de un String en una lista\nprint(division)\n\nformateo = \"Python\"  # Formatear datos en un String\nprint(f\"Hola {formateo}\" ) \n\nalphanumerico = str1.isalnum()  # Valida si la cadena es Alfanumerica\nprint(alphanumerico)\n\nletras = str1.isalpha()  # Verifica si la cadena solo contiene letras\nprint(letras)\n\nnumeros = str1.isdigit()  # Verifica si la cadena solo contiene numeros\nprint(numeros)\n\nminuscula = str1.islower()  # Verifica si la cadena solo contiene minusculas\nprint(minuscula)\n\nmayuscula = str1.isupper()  # Verifica si la cadena solo contiene mayusuculas\nprint(mayuscula)\n\nespacios = str1.isspace()  # Verifica si la cadena solo contiene espacios\nprint(espacios)\n\ncodificacion = \"año\"\nbytes = codificacion.encode('utf8')  # Codifica los caracteres\ncodificacion = bytes.decode('utf8')  # Descodifica los caracteres\nprint(bytes)\nprint(codificacion)\n\ninvertir = str1[::-1]  # Invertir cadena\nprint(invertir) \n\n\n\n\n# Ejercicio: \n\npalabra1 = \"mora\"\npalabra2 = \"amora\"\n\ndef es_palindromo(palabra):\n    \n    if palabra == palabra[::-1]:\n        print(f\"La palabra {palabra} es un palindromo\")\n    \n    else:\n        print(f\"La palabra {palabra} no es un palindromo\")\n        \n   \ndef es_anagrama(palabra1, palabra2):\n       \n    if sorted(palabra1) == sorted(palabra2):\n        \n        print(f\"Las palabras {palabra1} y {palabra2} son anagramas\")\n    \n    else: \n        \n        print(f\"Las palabras {palabra1} y {palabra2} no son anagramas\")\n                \n\ndef es_isograma(palabra):\n    \n    if len(palabra) == len(set(palabra)):\n        \n        print(f\"La palabra {palabra} es un isograma\")\n        \n    else:\n            \n        print(f\"La palabra {palabra} no es un isograma\")\n\nes_palindromo(palabra1)\nes_palindromo(palabra2)\nes_anagrama(palabra1, palabra2)\nes_isograma(palabra1)\nes_isograma(palabra2)"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/Franz-Arzapalo.py",
    "content": "\"\"\"\nEJERCICIO: #04 CADENAS DE CARACTERES\n- Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n  en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n- Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n  conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n\n  DIFICULTAD EXTRA (opcional):\n- Crea un programa que analice dos palabras diferentes y realice comprobaciones\n  para descubrir si son:\n- Palíndromos\n- Anagramas\n- Isogramas\n\"\"\"\n\n# 1. Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n#    en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n\n# Definición:\n\"\"\"\nLas cadenas como se vio en los tipos de datos primitivos sabemos que se pueden definir con comillas dobles \" \no comillas simples '.\n\"\"\"\n\nc1 = \"ejemplo\"\nc2 = 'otro ejemplo'\n\nprint(c1, c2) # ejemplo otro ejemplo\n\nc3 = ' '\n\n# Tambien se puede definir una cadena con espacio vacios.\n\n# Concatenación:\n\"\"\"\nExisten varias formas de concatenar cadenas de texto, concatenar se puede definir como la accion de unir mas de una\ncadena de texto en cualquier aspecto ya sea para definir una variable, o para imprimir el resultado de una función.\n\"\"\"\n\n# Uso de + para concatenar:\n\nc4 = c1 + ',' + c3 + c2 \nprint(c4) # ejemplo, otro ejemplo  \n\n# Repeticion:\n\nprint(c1*3) # ejemploejemploejemplo   \n\n# Pertenencia o busqueda:\n\nprint('e' in  c1) # True\nprint('1' in c1) # False\n\n# Secuencia de escape:\n\"\"\"\nSe puede tener problemas si se intante usar las comillas dobles o las comillas simples porque los tomara como cierre de la cadena\npara ello podemos usar un ruta de escape con la digonal inversa pero tambien sirve para hacer otra cosa:\n\"\"\"\n\n# \\\" o \\'\n\nprint(\"ejemplo \\\" ejemplo2 \\' \") # ejemplo \" ejemplo2 ' \n\n# Como vemos la diañonal invertida no se ve en la impresion y en este caso le quita sus propiedades a las comillas.\n\n# \\n\n\nprint(\" Linea 1 \\n linea 2 \\n linea 3\")\n# Linea 1\n# linea 2\n# linea 3\n\n# \\n siver para hacer un salto de linea.\n\n# Tambien sirve para escribir asi con el unicode.\n# https://www.freecodecamp.org/news/everything-you-need-to-know-about-encoding/ (Pagina de referencia.)(Columna Oct)\n\nprint(\"\\105\\152\\145\\155\\160\\154\\157\") # Ejemplo\n\n# ord() seia la funcion inversa porque so le damos un caracter nos devuelve el unicode pero de html no de Oct.\n\nprint(ord('E')) # 69\n\n# Solo se puede usar con un caracter y de forma inversa seria chr().\n\n# Asi como letras se pueden imprimir otro tipo de caracteres especiales.\n\n# Formateo de cadenas con %:\n\nx = 'cadena'\nx1 = \"Ejemplo de formateo %s\" % x\nprint(x1)\n\n# %d es para numeros y %s es para cadenas el formato es el mismo y se puede hacer con mas variables y las pones dentro de un parentesis\n# y las separamos con comas.\n\n# Indexar:\n\"\"\"\nAl igual que con las listas y tipos de datos parecidos con las cadenas se pueden indexar sus caracterres y se hace de la\nmisma forma.\n\"\"\"\nx = 'cadena'\nprint(x[0]) # c\nprint(x[0:2]) # ca\nprint(x[2:]) # dena\n\n# Como se ve se pueden indexar rangos de caracteres de la cadena.\n# si no ponemos ningun rango por defecto estara hasta el minimo y/o maximo.\n\n# Saltos o zancadas:\n\nprint(x[::2]) # cdn\n\n# Al utilizar esta forma de indexar se puede usar un tercer parametro que por defecto esta en 1\n# Esto es un salto en las cadena por eso el resultado es cdn.\n\n# invertir:\n\nprint(x[::-1]) # anedac\n\n# Como se ve se puede invertir una cadena poniendo -1 en el tercer parametro.\n# Si variamos el numero como -2 se invertira la cadena y comenzara a realizar los saltos desde el nuevo inicio.\n\n# Métodos:\n\n# capitalize():\n\nprint(x.capitalize()) # Cadena\n\n# Esto convierte el primer caracter de la cadena ingresada en mayuscula si ya lo esta entoces no hace nada.\n\n# lower():\n\ny = 'CADENA'\nprint(y.lower()) # cadena\n\n# Esto convierte todas los caracteres de una cadena en minuscula y si ya lo estaban entonces no pasa nada.\n\n# upper():\n\nprint(x.upper()) # CADENA\n\n# Esto convierte todos los caracteres de una cadena a mayusculas y si ya lo estaban no pasa nada.\n\n# swapcase():\n\nz = 'CaDeNa'\nprint(z.swapcase()) # cAdEnA\n\n# Esto convierte los caracteres mayusculas de una cadena en minusculas y biseversa.\n\n# count():\n\nprint(x.count('a')) # 2\n\n# Esto cuenta la cantidad de veces que se repite una cadena de texto dentro de otras.\n\n# isalnum():\n\nx2 = 'Jose1234'\nprint(x2.isalnum()) # True\n\n# Esta devuelve true si todos los caracteres de una cadena seleccionala son alphanumericos osea numeros o letras.\n# Tambien decir que si en la cadena solo hay careacteres alphanumericos y espacios en blanco devolvera false por los espacios.\n\n# isalpha():\n\nprint(x2.isalpha()) # # False\n\n# Esta devuelve true si todos los caracteres de una cadena son letras solo letras si hay espacio o numeros devolvera false.\n\n# strip():\n\nx3 = 'hola mundo'\nprint(x3.strip('h')) # ola mundo\n\n# Esto compara el caracter de cada extremo con el parametro y si lo encuentra lo elimina sino no hace nada.\n\n# zfill():\n\nx4 = 'nada'\nprint(x4.zfill(5)) # 0nada\n\n# Esto rellena la cadena con 0 a la izquierda hasta que la cadena tenga la longitud pasada como parametro.\n\n# join():\n\nx5 = ' y '.join(['1','2','3','4','5'])\nprint(x5) # 1 y 2 y 3 y 4 y 5\n\n# Aqui vemos que tenemos que poner la cadena que separar los datos de la lista antes del elemento .join()\n# dentro del parametro tiene que ir una lista que ojo tiene que ser de datos tipo string.\n\n# split():\n\nx6 = '1y3y4y5y6y7'\nprint(x6.split('y')) # ['1', '3', '4', '5', '6', '7']\n\n# Esto utiliza como parametro un caracter del cual usara para saber cuando separar un dato de otro y ponerlo en una lista.\n\n# replace:\n\nprint(x6.replace('y', ' ')) # 1 3 4 5 6 7\n\n# Esto intercambia la cadena que se pasa como primer parametro por la cadena que se pasa como segundo parametro de la cadena original.\n\n# sorted:\n\nprint(sorted('cadena'))\n\n# La funcion sorted tiene muchas utilidades una de ellas es convertir y ordenar cadenas dentro de una lista(hipotesis: los ordena por \n# orden alfabetico) y al ser una lista si hay mas de una misma letra no se juntan o eliminan solo se almacenan.\n\n\"\"\"\n  DIFICULTAD EXTRA (opcional):\n- Crea un programa que analice dos palabras diferentes y realice comprobaciones\n  para descubrir si son:\n- Palíndromos\n- Anagramas\n- Isogramas\n\"\"\"\n\ndef vpai ():\n    X = input('Ingrese la primer palabra: ')\n    Y = input('Ingrese la segunda palabra: ')\n    x = X.lower()\n    y = Y.lower()\n    # Palíndromos\n    print(f\"{X} es un palindromo.\" if x == x[::-1] else f\"{X} no es un palindromo.\")\n    print(f\"{Y} es un palindromo.\" if y == y[::-1] else f\"{Y} no es un palindromo.\")\n    # Anagramas\n    print(f\"{X} y {Y} son anagramas.\" if sorted(x) == sorted(y) else f\"{X} y {Y} no son anagramas.\")\n    # Isogramas\n    def isograma(w):\n        wd = {}\n        for c in w:\n            wd[c] = wd.get(c,0)+1\n        wdn = list(wd.values())\n        r = ''\n        for l in wd:\n            if wd[l] != wdn[0]:\n                r = 'no '\n                break\n        return r\n    print(f\"{X} {isograma(x)}es un isograma.\")\n    print(f\"{Y} {isograma(y)}es un isograma.\")    \nvpai()\t\n\n# Fin."
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/GaboDev23.py",
    "content": "'''\nEJERCICIO:\nMuestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n- Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n'''\n# Cadenas de carácteres\ns1 = 'Hola'\ns2 = 'Python'\ns3 = 'Brais Moure @mouredev'\ns4 = '1234'\n\nl1 = [s1, ', ', s2, '!']\n\n# Concatenación e interpolación\nprint(s1+ ' ' +s2) # Resultado - Hola Python\nprint(f'{s1} {s2}') # Resultado - Hola Python\n\n# Repetición\nprint((f'{s1} {s2}\\n') * 3) \n'''\nResultado - \nHola Python\nHola Python\nHola Python\n'''\n\n# Indexación\nprint(f'{s1[0]}{s1[1]}{s1[2]}{s1[3]}') # Resultado - Hola\n\n# Longitud\nprint(len(s2)) # Resultado - 6\n\n# Slicing (Porción)\nprint(s2[2:6]) # Resultado - thon\nprint(s2[2:]) # Resultado - thon\nprint(s2[:2]) # Resultado - Py\nprint(f'{s2[:2]}{s2[2:]}') # Resultado - Python\n\n# Busqueda\nprint('a' in s1) # Resultado - True\nprint('Ho' in s1) # Resultado - True\nprint('i' in s1) # Resultado - False\n\n# Reemplazo\nprint(s1.replace('o', 'a')) # Resultado - Hala\n\n# División\nprint(s2.split('t')) # Resultado - ['Py', 'hon']\n\n# Mayúsculas y minúsculas\nprint(s1.upper()) # Resultado - HOLA\nprint(s1.lower()) # Resultado - hola\nprint('Gabriel herling'.title()) # Resultado - Gabriel Herling\nprint('gabriel herling'.capitalize()) # Resultado - Gabriel herling\n\n# Eliminación de espacios al principio y al final\nprint(' Gabriel Herling ') # Resultado - ' Gabriel Herling '\nprint(' Gabriel Herling '.strip()) # Resultado - 'Gabriel Herling'\n\n# Busqueda al principio y al final\nprint(s1.startswith('Ho')) # Resultado - True\nprint(s2.startswith('Pyt')) # Resultado - True\nprint(s1.endswith('a')) # Resultado - True\nprint(s1.endswith('thon')) # Resultado - False\n\n# Búsqueda de posición\nprint(s3.find('m')) # Resultado - 13\nprint(s3.lower().find('m')) # Resultado - 6\n\n# Búsqueda de ocurrencias\nprint(s3.lower().count('m')) # Resultado - 2\nprint(s3.lower().count('x')) # Resultado - 0\n\n# Formateo\nprint('Saludo: {}, Lenguaje: {}'.format(s1, s2)) # Resultado - Saludo: Hola, Lenguaje Python\n\n# Transformación en lista de carácteres\nprint(list(s3)) # Resultado - ['B', 'r', 'a', 'i', 's', ' ', 'M', 'o', 'u', 'r', 'e', ' ', '@', 'm', 'o', 'u', 'r', 'e', 'd', 'e', 'v']\n\n# Transformación de lista a cadena\nprint(\"\".join(l1)) # Resultado - Hola, Python!\nprint(\"-\".join(l1)) # Resultado - Hola-, -Python-!\nprint(\" \".join(l1)) # Resultado - Hola ,  Python !\n\n# Transformaciones numéricas\nprint(s4.isnumeric()) # Resultado - True\nprint(s1.isnumeric()) # Resultado - False\nprint(s4) # Resultado - 1234\n# print(s4 + 5) # Resultado - Error\nprint(int(s4) + 5) # Resultado - 1239\n\n# Comprobaciones varias\nprint(s1.isalnum()) # Resultado - True\nprint(s1.isalpha()) # Resultado - True\nprint(s4.isalpha()) # Resultado - False\n\nprint('------------------------------------------------------')\n\n'''\nDIFICULTAD EXTRA (opcional):\nCrea un programa que analice dos palabras diferentes y realice comprobaciones para descubrir si son:\n- Palíndromos\n- Anagramas\n- Isogramas\n'''\np1 = input('Introduce una palabra: ').strip().lower()\np2 = input('Introduce otra palabra: ').strip().lower()\ni1 = ''\ni2 = ''\n\n# Sólo toma la primera palabra de cada cadena en caso de que halla espacios\ndef eliminar_espacio(p):\n    if ' ' in p:\n        p = p[:p.find(' ')]\n    \n    return p\n\np1 = eliminar_espacio(p1)\np2 = eliminar_espacio(p2)\n\n# Verifica si una palabra es palíndromo\ndef es_palindromo(p):\n    i = p[::-1]\n    \n    if p == i:\n        print(f'La palabra \"{p}\" es palíndromo')\n    else:\n        print(f'La palabra \"{p}\" no es palíndromo')\n        \n# Verifica si 2 palabras son anagramas\ndef son_anagramas(p1, p2):\n    if sorted(p1) == sorted(p2):\n        return 'Ambas palabras son anagramas'\n    else:\n        return 'Las palabras no son anagramas'\n\n# Verifica si una palabra es isograma\ndef esisograma (p):\n    l = list(p)\n    cont = 0\n    \n    for i in range(len(l)):\n        for j in range(len(l)):\n            if i != j:\n                if l[i] == l[j]:\n                    cont =+ 1\n    \n    if cont == 0:\n        return f'La palabra {p} es un isograma'\n    else:\n        return f'La palabra {p} no es un isograma'\n\n# Palíndromos\nes_palindromo(p1)\nes_palindromo(p2)\n    \nprint('------------------------------------------------------')\n\n# Anagramas\nprint(son_anagramas(p1, p2))\n\nprint('------------------------------------------------------')\n\n# Isogramas\nprint(esisograma(p1))\nprint(esisograma(p2))"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/Gallitofast.py",
    "content": "#04 CADENAS DE CARACTERES\n\"\"\"\n-Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\nen tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n-Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\nrecorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\ninterpolación, verificación...\n\"\"\"\n#CREACION DE CADENAS\nprimeracadena = \"hola compañeros\"\nsegundacadena = \"python es genial\"\ncadena_multilinea = \"\"\"Escribir un texto muy grande en una cadena es mas facil con las cadenas multilineas, mira todo\nel texto que cabe en esta cadena wooow\"\"\"\n\n#ACCESO A CARACTERES ESPECIFICOS\nacceso_cadena = \"pyhton\"\nprint(acceso_cadena[0])\nprint(acceso_cadena[-1])\nprint(acceso_cadena[2])\n\n#SUBCADENAS (SLICING)\ncadena_subcadenas = \"Hola_mi_nombre_es jose_muchisimo gusto\"\nprint(cadena_subcadenas[3:7])\nprint(cadena_subcadenas[:8])\nprint(cadena_subcadenas[8:])\nprint(cadena_subcadenas[::2])\nprint(cadena_subcadenas[::-1])\n\n#LONGITUD DE UNA CADENA\ncadena_longitud = \"parangaricutirimicuaro\"\nprint(len(cadena_longitud))\n\nprint(cadena_longitud)\n#CONCATENACION\nconcatenadora_1 = \"Hola\"\nconcatenadora_2 = \" y adios\"\nprint(concatenadora_1+concatenadora_2)\n\n#REPETICION\ncadena_repeticion = \"osito gominola\\n\"\nprint(cadena_repeticion*7)\n\n#RECORRIDO DE CADENAS\ncadena_recorridos = \"Python\"\nfor caracter in cadena_recorridos:\n    print(caracter)\n\n#CONVERSION A MAYUSCULAS Y MINUSCULAS\nmayus_minus = \"mayusculas_minusculas\"\nprint(mayus_minus.upper())\nprint(mayus_minus.lower())\nprint(mayus_minus)\nprint(mayus_minus.capitalize())\nprint(\"hola mundo\".title())  \n\n#REEMPLAZO\ncadena_reemplazo = \"Me gusta la pizza hawaiana\"\nprint(cadena_reemplazo.replace(\"hawaiana\",\"con peperoni\"))\n\n#DIVISION\ncadena_division = \"Jose,Michel,Enrique,Monica,Monroy\"\nprint(\"\\n\".join(cadena_division.split(\",\")))   #Lo del join viene a continuacion jejeje\n\n#UNION O JOIN\nlista = [\"Python\", \"Java\", \"C++\"]\nprint(\", \".join(lista))   \n\n#INTERPOLACION (F-STRINGS)\nnombre = \"Jose\"\nedad = \"23\"\nprint(f\"Mi nombre es {nombre} y tengo {edad} años\")\n\n#VERIFICACION\nverificadena = \"Gallolobo123\"\nprint(verificadena.isalpha())  \nprint(verificadena.isdigit())\nprint(verificadena.isalnum())\nprint(verificadena.startswith(\"Gallo\"))\nprint(verificadena.endswith(\"123\"))\nprint(\"GALLO\" in verificadena.upper())\n\n#ELIMINACION DE ESPACIOS\nespacio_cadena =\"   Gallo   \"\nprint(espacio_cadena.strip())\nprint(espacio_cadena.rstrip())\nprint(espacio_cadena.lstrip())\n\n#BUSQUEDA\nbuscadena = \"Programación en python\"\nprint(buscadena.find(\"python\"))\nprint(buscadena.find(\"Java\"))   \nprint(buscadena.index(\"en\"))   #INDEX SI NO ENCUENTRA LANZA ERROR  \nprint(buscadena.count(\"a\"))     \nprint(buscadena.count(\"z\"))     \n\n#FORMATEO\nnombre = \"Carlos\"\nedad = 30\nprint(\"Nombre: {}, Edad: {}\".format(nombre, edad))  # Formato tradicional\nprint(\"Nombre: {1}, Edad: {0}\".format(edad, nombre))  # Con índices\n\n#COMPROBACIONES\ncomprobacion_cadena = \"python\"\nprint(comprobacion_cadena.islower())  # False\nprint(comprobacion_cadena.isupper())  # False\nprint(\"123\".isnumeric())  # True\nprint(\"   \".isspace())   # True\n\n#CODIFICACION Y DECODIFICACION\ncadena = \"Año\"\nbytes = cadena.encode('utf-8')  # b'A\\xc3\\xb1o'\nprint(bytes.decode('utf-8'))   # 'Año'\n\n\n\"\"\"\n            Dificultad extra\n\"\"\"\nprint(\"Este es el programa de dificultad extra, necesitaras ingresar dos palabras\")\nPrimera_palabra = input(\"Ingresa la primera palabra: \")\nSegunda_palabra = input(\"Ingresa la Segunda palabra: \")\n\n# PALINDROMO CHEQUEO \nif Primera_palabra == Primera_palabra[::-1]:\n    print(\"La primera palabra es un palindromo\")\nelse:\n    print(\"La primera palabra no es un palindromo\")\nif Segunda_palabra == Segunda_palabra[::-1]:\n    print(\"La segunda palabra es un palindromo\")\nelse:\n    print(\"La segunda palabra no es un palindromo\")\n    \n# ISOGRAMA CHEQUEO\npalabra_limpia_1 = Primera_palabra.replace(\" \", \"\").lower()\npalabra_limpia_2 = Segunda_palabra.replace(\" \", \"\").lower()\n\nif len(palabra_limpia_1) == len(set(palabra_limpia_1)):\n    print(\"La primera palabra es un isograma\")\nelse: \n    print(\"La primera palabra no es un isograma\")\nif len(palabra_limpia_2) == len(set(palabra_limpia_2)):\n    print(\"La segunda palabra es un isograma\")\nelse:\n    print(\"La segunda palabra no es un isograma\")\n\n# ANAGRAMA CHEQUEO\nif sorted(palabra_limpia_1) == sorted(palabra_limpia_2):\n    print(\"Las palabras son un anagrama\")\nelse: \n    print(\"Las palabras no son un anagrama\") \n    "
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/Gordo-Master.py",
    "content": "\"\"\"\nCadena de caracteres\n\"\"\"\n\n\n\nmy_string = \"¡Hola Comunidad!\"\n\n# Metodos comunes de una secuencia\n\nprint(my_string[1]) # Acceso\n\nfor x in my_string: # Recorriendo el str(es una secuencia inmutable)\n    print(x)\n\nprint(\"m\" in my_string) # Presencia\nprint(\"m\" not in my_string)\n\nprint(my_string + \" 2 veces\") # Concatenación\n\nprint(my_string * 3)    # Multiplicación/Repetición\n\nprint(my_string[2:6])   # Slice (porción)\nprint(my_string[:5])   # Slice desde el principio\nprint(my_string[5:])   # Slice hasta el final\nprint(my_string[2:15:2]) # Slice con salto\nprint(my_string[::-1]) # Slice revirtiendo\n\nprint(len(my_string))   # Longitud\n\nprint(min(my_string))   # Minimo. Segun valor unicode\nprint(max(my_string))   # Maximo. Segun valor unicode\n\nprint(my_string.index(\"l\")) # Buscar la posicion de la primera ocurrencia\nprint(my_string.count(\"o\")) # Contar las ocurrencias\n\n\n# Metodos propios de string\nmy_string = \"hola Comunidad de Retos de Programación\"\n\nprint(my_string.upper()) # Convertir a mayuscula\nprint(my_string.lower()) # Convertir a minuscula\nprint(my_string.strip(\"dH!¡\")) # Recortar el inicio y el final de caracteres\nprint(my_string.replace(\"u\",\"O\"))   # Reemplazar valores\nprint(my_string.split(\" \",2)) # Separar en una lista, hasta \"2\" ocurrencias\n\nprint(my_string.capitalize()) # Mayuscula primera palabra\nprint(my_string.casefold()) # Vuelve todo minuscula, pero con busqueda con esteroides\nprint(my_string.center(72,\"-\")) # Centra el texto\nprint(my_string.count(\"o\")) #  Cuenta las ocurrencias\nprint(my_string.encode()) # Codifica el texto, por defecto en utf-8\nprint(my_string.endswith(\"ión\")) # boolean: final de string\nprint(\"H\\to\\tl\\ta\".expandtabs(3)) # Cambia los tab por espacios\nprint(my_string.find(\"ad\")) # Busca la posición de la expersión\nprint(my_string.index(\"ad\")) # Busca la posición de la expersión, error = no found\nprint(my_string.isalnum()) # Es alfanumerico\nprint(my_string.isalpha()) # Es alfabetico \nprint(\"Hola\".isascii()) # Es ascii\nprint(\"45\".isdecimal()) # Es decimal (0-9)\nprint(my_string.isdigit()) # Es un digito (decimal y mas)\nprint(\"my_string\".isidentifier()) # Es un identificador\nprint(my_string.islower()) # Es minuscula\nprint(\"\\u2155\".isnumeric()) # Es un numero (digito y mas)\nprint(\"\\u2155\") \nprint(my_string.isprintable()) # Es imprimible\nprint(my_string.isspace())  # Es todo espacio\nprint(\"Hola Mundo\".istitle())  # Es tipo titulo (mayuscula en palabras)\nprint(\"Hola Mundo\".isupper()) # Es todo mayuscula\nprint(\"@\".join([\"tomas\",\"cain\",\"abel\"]))  # Une iterables en str\nprint(my_string.ljust(72,\"*\")) # Justificado izquierdo\nprint(my_string.lstrip(\"ho\"))    # Elimina los caracteres dados del comienzo\nprint(my_string.partition(\" \"))    #  Da una tupla de 3, de acuerdo al sep.\nprint(my_string.removeprefix(\"hola\")) # Quita el prefijo (coincidencia exacta)\nprint(my_string.removesuffix(\"ción\")) # Quita el sufijo (coincidencia exacta)\nprint(my_string.replace(\"hola\",\"Hi\"))  # Reemplaza los str dados \nprint(my_string.rfind(\"ma\")) # Un find que comienza desde la derecha\nprint(my_string.rindex(\"ma\"))   # Un indes desde la derecha \nprint(my_string.rjust(72,\"*\"))    # Justificación a la derecha\nprint(my_string.rpartition(\" \"))   # Partición desde la derecha \nprint(my_string.rsplit(\" \"))   # Separa el str y da una lista, no devuelve el separador\nprint(my_string.rstrip(\"nó\")) # Quita los caracteres dados desde el final\nprint(my_string.split(\" \",maxsplit=2)) # Separa el string y da una lista, no devuelve el sep\nprint(\"String\\ncon\\nvarias\\nlineas\".splitlines()) # Retorna una lista de varias lineas de str, con separadores\nprint(my_string.startswith(\"hol\")) # Si comienza con el caracter dado\nprint(my_string.strip(\"hol\")) # el str no puede comenzar ni terminar con ninguno de los caracteres dados \nprint(my_string.swapcase()) # Cambia mayuscula por minuscula y viceversa\nprint(my_string.title())    # Todas la palabras empiezan en mayuscula, resto minuscula \nprint(my_string.zfill(72))  # Rellena de 0 hacia la izquierda, hasta tenes la longitud especificada\nx = str.maketrans(\"hr\",\"ei\")    #(static) Hace un dict para usar en str.translate\nprint(x) \nprint(my_string.translate(x)) # Transforma caracter por caracter segun el dict dado\n\n\n# Formateo\nprint(\"Texto de {} formatado de {} maneras\".format(\"Python\",5*5))\n\nmapa: dict ={\n    \"Nombre\":\"Python\",\n    \"cantidad\":\"muchas\"\n}\nprint(\"Texto de {Nombre} formatado de {cantidad} maneras\".format_map(mapa))\n\n\n\n\"\"\"\nEjercicio extra\n\"\"\"\n\n# Palíndromos (se lee de igual comenzando desde la izquierda o la derecha)\ndef is_pal(text_1:str):\n    if text_1 == text_1[::-1]:\n        return f\"La palabra '{text_1}' es un palindromo\"\n    return f\"La palabra \\\"{text_1}\\\" NO es un palindromo\"\n\n# Anagramas (Se permutan sus letras para conseguir esas palabras)\ndef is_anag(text_1:str, text_2:str):\n    x1 = sorted(text_1)\n    x2 = sorted(text_2)\n    if x1 == x2:\n        return f\"La palabra \\\"{text_1}\\\" y \\\"{text_2}\\\" son anagramas\"\n    return f\"La palabra \\\"{text_1}\\\" y \\\"{text_2}\\\" NO son anagramas\"\n\n# Isogramas (cuando ni una letra se repite, al ser dos me imagino que una no contiene a otra)\ndef is_iso(text_1:str):\n    contador = text_1.count(text_1[0])\n    for i in text_1:\n        if text_1.count(i)!=contador:\n            return f\"La palabra \\\"{text_1}\\\" NO es un isograma\"\n    return f\"La palabra \\\"{text_1}\\\" es un isograma\"\n\nprint(is_pal(\"radar\"))\nprint(is_pal(\"pera\"))\nprint(is_anag(\"sentido\",\"destino\"))\nprint(is_anag(\"intuición\",\"logica\"))\nprint(is_iso(\"murcielago\"))\nprint(is_iso(\"jirafa\"))"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/Hyromy.py",
    "content": "print(\"hola buenas\".capitalize()) #convertir a letra capital\nprint(\"MINUSCULAS\".casefold()) #convertir agresivamente a minusculas (util para comparaciones)\nprint(\"centrado\".center(20)) #centar un texto con un ancho especifico\nprint(\"esternocleidomastoideo\".count(\"e\")) #contar cuantas veces aparece el string especificado\nprint(\"Hyromy\".endswith(\"my\")) #comprueba que el string termine con otro string\nprint(\"hola buenas tardes\".find(\"buenas\")) #encontrar el indice de la primera aparicion de un substring\nprint(\"Hyromy\".index(\"m\")) #devuelve el indice de la primera aparicion de un substring especificado\nprint(\"04Python\".isalnum()) #comprueba si el string posee caracteres alphanumericos (solo numeros y letras)\nprint(\"Alpha\".isalpha()) #comprueba que todo el string sean letras alfabeticas\nprint(\"Codigo Ascii\".isascii()) #comprueba si el string posee caracteres ascii\nprint(\"55\".isdecimal()) #comprueba si el string es un numero (no admite punto decimal)\nprint(\"minusculas\".islower()) #comprueba si esta escrito en minusculas\nprint(\"Hola\\nbuenas\".isprintable()) #comrprueba es imprimible (no posee caracteres de instruccion)\nprint(\"\\n\\t  \".isspace()) #comrpueba que el string sean espacios en blanco, saltos de linea o tabulados\nprint(\"Nuevo Titulo\".istitle()) #comprueba que cada palabra del string empiece por mayuscula\nprint(\"MAYUSCULAS\".isupper()) #comprueba que el string este en mayusculas\nprint(\" - \".join([\"Hyromy\", \"Luis\", \"Paco\"])) #usa el string original como separador y concatena el resto de elementos que reciba\nprint(\"Hola\".ljust(8, \"-\")) #posiciona el string a la izquierda y rellena con un caracter hasta lograr un largo especificado\nprint(\"MAYUS\".lower()) #convierte a minusculas\nprint(\"     _buenas_\".lstrip()) #elimina los espacios en blanco a la izquierda del string\nprint(\"Hola, mundo\".partition(\",\")) #divide el string en 3 partes, inicial, central y final deacuerdo a un substring\nprint(\"!ping\".removeprefix(\"!\")) #remueve el prefijo de un string\nprint(\"hola...\".removesuffix(\"...\")) #remueve un sufijo de un string\nprint(\"Hola buenas tardes\".replace(\"a\", \"4\")) #reemplaza todas las apariciones de un substring por otro\nprint(\"hola buenas tardes\".rfind(\"a\")) #devuelve el indice de la ultima aparicion del substring\nprint(\"Hola\".rjust(8, \"-\")) #acomoda el string a la derecha rellenando con un substring a un largo especificado\nprint(\"Hola buenas tardes\".split(\" \")) #divide el string apartir de un substring especificado\nprint(\"hola ¿como estas?\".startswith(\"hola\")) #comrpueba que el string comience con otro substring\nprint(\"    hola    \".strip()) #elimina los espacios en blanco al inicio y al final\nprint(\"DiFiCiL dE lEeR\".swapcase()) #invierte el case del string\nprint(\"sistema digestivo\".title()) #convierte a un titulo\nprint(\"mayusculas\".upper()) #convierte a mayusculas\n\n# ---- DIFICULTAD EXTRA ----\n\n#la palabra debe de leerse igual al derecho y al reves\ndef palindromo(string:str):\n    string = string.casefold()\n    original, copy = \"\", \"\"\n\n    for i in string:\n        if i != \" \":\n            original += i\n            copy = i + copy\n    \n    for o, c in zip(original, copy): #agrupar 2 iterables diferentes (deben tener la misma longitud)\n        if o != c:\n            return False\n    else:\n        return True\n\n\n#ambas palabras deben contener las mismas letras\ndef anagrama(string:str, compare:str):\n    string = string.casefold()\n    compare = compare.casefold()\n\n    alpha = []\n    for i in range(26): #a-z (97-122)\n        alpha.append([chr(i + 97), 0])\n\n    for s in string:\n        for a in alpha:\n            if s == a[0]:\n                a[1] += 1\n                break\n\n    for c in compare:\n        for a in alpha:\n            if c == a[0]:\n                a[1] -= 1\n                break\n    \n    for i in alpha:\n        if i[1] != 0:\n            return False\n    else:\n        return True\n\n\n#la palabra no debe de tener letras repetidas\ndef isograma(string:str):\n    string = string.casefold()\n\n    alpha = []\n    for i in range(26):\n        alpha.append([chr(i + 97), 0])\n\n    for s in string:\n        for a in alpha:\n            if s == a[0]:\n                a[1] += 1\n                break\n\n    for i in alpha:\n        if i[1] > 1:\n            return False\n    else:\n        return True\n\npalabra_1 = input(\"Dime una palabra => \")\npalabra_2 = input(\"Dime otra palabra => \")\nprint()\n\nif palindromo(palabra_1):\n    print(f\"{palabra_1} Es un palindromo\")\nelse:\n    print(f\"{palabra_1} NO es un palindromo\")\nif palindromo(palabra_2):\n    print(f\"{palabra_2} Es un palindromo\")\nelse:\n    print(f\"{palabra_2} NO es un palindromo\")\nprint()\n\nif anagrama(palabra_1, palabra_2):\n    print(f\"{palabra_1} y {palabra_2} Son anagramas\")\nelse:\n    print(f\"{palabra_1} y {palabra_2} NO son anagramas\")\nprint()\n\nif isograma(palabra_1):\n    print(f\"{palabra_1} Es un isograma\")\nelse:\n    print(f\"{palabra_1} NO es un isograma\")\nif isograma(palabra_2):\n    print(f\"{palabra_2} Es un isograma\")\nelse:\n    print(f\"{palabra_1} NO es un isograma\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/Irenetitor.py",
    "content": "#STRINGS\n\"Hi, everyone\"\n'Python'\n\"\"\" This is also a String \"\"\"\n\ns1 = \"Hello\"\ns2 = \"World\"\n\n\n# #Concatenate\n# print(s1 + ', ' + s2 + '!' )  #Hello, World !\n\n# #Repetition\n# Eco = \"ha\" * 3\n# print(Eco)\n\n# #Length\n# print(len(Eco))    #6\n\n# #Indentation\n# print(s1[0] + s1[1] + s1[2] + s1[3] + s1[4])   #Hello\n# print(s1[1])    #he\n\n# #Slicing\n# t = \"If you can dream it\"\n# print(t[2:6])     #from position 2 to position 6 (not included)  - you\n# print(t[:6])      #from the start to position 6 (not included)  -If you\n# print(t[2:])      #from position 2 to all the way to the end   -you can dream it\n# print(t[-7:-2])   #start counting from the end (from r to ' ' before it.)  -ream\n\n# #Character search\n# print(\"o\" in s1)  #True\n# print(\"i\" in s1)  #False\n\n# #Replace\n# y = \"Hi, ocean\"\n# print(y.replace(\"H\", \"J\"))    #Ji, ocean\n\n# #Split\n# y = \"Hi, ocean\"\n# print(y.split(\",\"))      #['Hi', ' ocean']\n\n# # Uppercase, lowercase, and title case\n# print(s1.upper())    #HELLO\n# print(s1.lower())    #hello\n# print(\"better together\".title())       #Better Together\n# print(\"better together\".capitalize())    #Better together\n\n# # Removing spaces at the beginning and end\n# print(\" sparkling water \".strip())           #sparkling water\n\n# #Search at the beginning and end\n# print(s1.startswith(\"He\"))  #True\n# print(s1.startswith(\"Pi\"))  #False\n# print(s1.endswith(\"lo\"))    #True\n# print(s1.endswith(\"\"))      #True\n\ns3 = \"Blood is thicker than water\"\n\n# Position search\nprint(s3.find(\"thicker\"))  #9\nprint(s3.find(\"Than\"))  #-1\nprint(s3.find(\"B\"))  #0\nprint(s3.lower().find(\"w\"))  #22\n\n# Counting occurrences\nprint(s3.lower().count(\"a\"))  #2\n\n# Formatting\nprint(\"Greeting: {}, language: {}!\".format(s1, s2))  #Greeting: Hello, language: World!\n\n# Interpolation (f-strings)\nprint(f\"Greeting: {s1}, language: {s2}!\")  #Greeting: Hello, language: World!\n\n# Transform string into a list of characters\nprint(list(s3))  #['B', 'l', 'o', 'o', 'd', ' ', 'i', 's', ' ', 't', 'h', 'i', 'c', 'k', 'e', 'r', ' ', 't', 'h', 'a', 'n', ' ', 'w', 'a', 't', 'e', 'r']\n\n# Transform list into a string\nl1 = [s1, \", \", s2, \"!\"]\nprint(\"\".join(l1))  #Hello, World!\n\n# Numeric transformations\ns4 = \"123456\"\ns4 = int(s4)\nprint(s4)   #123456\n\ns5 = \"123456.123\"\ns5 = float(s5)\nprint(s5)   #123456.123\n\n# Various checks\ns4 = \"123456\"\nprint(s1.isalnum())   #True\nprint(s1.isalpha())   #True\nprint(s4.isalpha())   #False\nprint(s4.isnumeric())   #True\n\n#Extra exercise\n\ndef checking_word(word1: str, word2: str):\n    # Palindrome checks\n    print(f\"Is '{word1}' a palindrome? {word1.lower() == word1[::-1].lower()}\")\n    print(f\"Is '{word2}' a palindrome? {word2.lower() == word2[::-1].lower()}\")\n\n    # Anagram check\n    if sorted(word1.lower()) == sorted(word2.lower()):\n        print(f\"'{word1}' and '{word2}' are anagrams\")\n    else:\n        print(f\"'{word1}' and '{word2}' are not anagrams\")\n\n    # Isogram checks\n    print(f\"Is '{word1}' an isogram? {len(word1.lower()) == len(set(word1.lower()))}\")\n    print(f\"Is '{word2}' an isogram? {len(word2.lower()) == len(set(word2.lower()))}\")\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/JacMac45.py",
    "content": "# Cadenas de caracteres\n# 1. Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n\n# operaciones con cadenas de caracteres\ncadena_01 = \"hola\"\ncadena_02 = \"mundo\"\n\n# concatenacion\nconcatenacion = cadena_01 + \" \" + cadena_02\nprint()\nprint(concatenacion)\n\n# repeticion\nrepeticion = cadena_01 * 3\nprint(repeticion)\n\n# indexacion\nindexacion = cadena_01[0] + cadena_01[1] + cadena_01[2] + cadena_01[3]\nprint(indexacion)\nindexacion = cadena_01[0] + cadena_01[3] + cadena_01[0] + cadena_01[3] +cadena_01[0]+ cadena_01[3]\nprint(indexacion)\n\n# longitud\nlongitud = len(cadena_01)\nprint(longitud)\n\n# slicing\nslicing = cadena_02[2:6]\nprint(slicing)\nslicing = cadena_02[2:]\nprint(slicing)\nslicing = cadena_02[:4]\nprint(slicing)\n\n# busqueda\nbusqueda = \"o\" in cadena_01\nprint(busqueda)\nbusqueda = \"i\" in cadena_01\nprint(busqueda)\n\n# remplazo\nremplazo = cadena_01.replace(\"o\", \"a\") \nprint(remplazo)\nremplazo = cadena_02.replace(\"o\", \"i\")\nprint(remplazo)\n\n# division\ndivision = cadena_02.split(\"n\")\nprint(division)\n\n# mayusculas y minusculas\ncadena_03 = \"hola caracola\"\nmayusculas = cadena_01.upper()\nprint(mayusculas)\nminusculas = cadena_01.lower()\nprint(minusculas)\ntitulo = cadena_03.title()\nprint(titulo)\nprimera_letra_mayuscula = cadena_03.capitalize()\nprint(primera_letra_mayuscula)\n\n# Eliminar espacios en blanco\ncadena_03 = \"   hola caracola   \"\ncadena_03 = cadena_03.strip() # elimina espacios al principio y al final\nprint(cadena_03)\n\n# Interpolación\nnombre = \"JacMac45\"\nedad = 20\nprint(f\"Mi nombre es {nombre} y tengo {edad} años\")\n\n# Buqueda al principio y al final\nprint(cadena_03.startswith(\"hola\"))\nprint(cadena_03.endswith(\"ola\"))\nprint(cadena_03.endswith(\"no\"))\n\n# Busqueda de posicion\nprint(cadena_03.find(\"hola\"))\nprint(cadena_02.find(\"n\"))\nprint(cadena_03.lower().find(\"ola\"))\n\n# Busqueda de ocurrencias\ncadena_04 = \"Es la hora de la fiesta\"\nprint(cadena_04.count(\"a\"))\n\n# Transformación en lista de caracteres\nlista_caracteres = list(cadena_03)\nprint(lista_caracteres)\n\n# Transformación de lista en cadena\nlista_caracteres = [\"h\", \"o\", \"l\", \"a\", \" \", \"c\", \"a\", \"r\", \"a\", \"c\", \"o\", \"l\", \"a\"]\ncadena_03 = \"\".join(lista_caracteres)\nprint(cadena_03)\n\n# Casting de cadenas en números\nnum1 = \"123456\"\nprint(type(num1))\nnu = int(num1) # A entero\nprint(type(nu))\nprint(nu)\nnum2 = \"123456.75\"\nprint(type(num2))\nnu2 = float(num2) # A decimal\nprint(type(nu2))\nprint(nu2)\n\n# Formateo\nprint(\"cadena1 tiene {} y cadena2 tiene {}\".format(cadena_01, cadena_02)) # Con format()\nprint(f\"cadena1 tiene {cadena_01} y cadena2 tiene {cadena_02}\") # Con f-string \n\n# Extra\nPalabra1 = input(\"Dime una palabra => \")\nPalabra2 = input(\"Dime otra palabra => \")\nprint()\n# El palindromo se comprueba comparando la palabra con su inversa\nprint(f\"{Palabra1} Es un palindromo\") if Palabra1 == Palabra1[::-1] else print(f\"{Palabra1} NO es un palindromo\")\nprint(f\"{Palabra2} Es un palindromo\") if Palabra2 == Palabra2[::-1] else print(f\"{Palabra2} NO es un palindromo\")\nprint()\n\nprint(f\"{Palabra1} y {Palabra2} Son anagramas\") if sorted(Palabra1) == sorted(Palabra2) else print(f\"{Palabra1} y {Palabra2} NO son anagramas\")\nprint()\n\nprint(f\"{Palabra1} Es un isograma\") if len(Palabra1) == len(set(Palabra1)) else print(f\"{Palabra1} NO es un isograma\")\nprint(f\"{Palabra2} Es un isograma\") if len(Palabra2) == len(set(Palabra2)) else print(f\"{Palabra2} NO es un isograma\")\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/Jav-mol.py",
    "content": "# --- Cadena de Caracteres ---\n# Javier Molina\n\n# Concatenacion \nvar1 = 'Javi'\nvar2 = 'Molina'\n\nprint(var1 + var2)\nprint(var1 +' '+var2)\n\n# Indexacion\nprint(var1[0:2])\nprint(var1[::-1])\n\n# Longitud\nprint(len(var1))\n\n# Verificar in string\nprint('a' in var1 and 'o' in var2)\n\n# Reemplazo\nprint(var1.replace('J', 'j'))\n\n# Division\nprint(var1.split('v'))\n\n# Mayusculas - Minusculas\nprint(var1.upper())\nprint(var1.lower())\nprint(var2.upper())\nprint(var2.lower())\n\n# Eliminación de espacios al principio y al final\nprint(\" Javier Molina \".strip())\n\n# Metodo title() pone la primera letra de cada palabra en Mayusculas\nprint('javier molina'.title())\n\n# Invertir el metodo title() con swapcase() \nprint('javier molina'.title().swapcase())\n\n# Metodo capitalize() pone la primera letra en mayusculas solo de la primera palabra\nprint('javier molina'.capitalize())\n\n# endswith() Veridica el final del string con el argumento pasado\nprint(var1.endswith('i'))\n\n# Buscar\nprint(var1.find('i'))\n\n# Corrobora si contiene numeros\nprint(var2.isalnum())\nprint('Javi2'.isalnum())\n\n# Corrobora si solo tiene letras del alfabeto\nprint(var2.isalpha())\nprint('abc1'.isalpha())\n\n# Corrobora si solo contiene numeros\nprint('abc1'.isnumeric())\nprint('321'.isnumeric())\n\n# Corrobora si todos los caracteres son imprimibles\nprint('Javier Molina'.isprintable())\nprint('Javier\\nMolina'.isprintable())\nprint('Javier \\tMolina'.isprintable())\n\n# Retorna el indice del parametro a buscar, caso contrario retorna -1\nprint(var1.rfind('f'))\n\n# Rellena con ceros el principio de la cadena\nprint(\"54\".zfill(4))\n\n\n\"\"\" --- Ejercicio Extra --- \"\"\"\n\npalindromo = lambda palab_1, palab_2: palab_1.replace(' ','') == palab_2.replace(' ','')[::-1]\n\n\ndef ejercicio(palab_1: str, palab_2: str):\n    palab_1 = palab_1.lower()\n    palab_2 = palab_2.lower()\n        \n    ispalindromo = palindromo(palab_1, palab_2)\n    \n    if ispalindromo:\n        print(f'{palab_1} - {palab_2} Son palindromos')\n    \n    anagrama = [letra in palab_2 for letra in palab_1]\n    if anagrama.count(True) == len(palab_1):\n        print(f'\"{palab_1}\" es un anagrama de: {palab_2}')\n    \n    anagrama2 = [letra in palab_1 for letra in palab_2]\n    if anagrama2.count(True) == len(palab_2):\n        print(f'\"{palab_2}\" es un anagrama de: {palab_1}')\n        \n    isograma = [letra for letra in palab_1 if palab_1.count(letra) == 1]\n    if len(isograma) == len(palab_1):\n        print(f'Es un isograma: {palab_1}')\n\n    isograma2 = [letra for letra in palab_2 if palab_2.count(letra) == 1]\n    if len(isograma2) == len(palab_2):\n        print(f'Es un isograma: {palab_2}')\n\n    print(\"-\"*30)\n\nejercicio('Oracion', 'Caroino')\nejercicio(' Amor', 'Roma')\nejercicio('Mial', 'Lima')\nejercicio('perro', 'romper')\nejercicio('a mama roma', 'amor a mama')\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/JesusAntonioEEscamilla.py",
    "content": "# #04 - Python -> Jesus Antonio Escamilla\n\n\"\"\"\nEJERCIÓ\n\"\"\"\n#---STRING---\ns1 = 'Hola Mundo'\nprint(f'String -> {s1}')\n\n#---SUB-CADENA---\nsub_s1 = s1[5:10]\nprint(f'Sub-Cadena -> {sub_s1}')\n\n#---LONGITUD---\nlength = len(s1)\nprint(f'Longitud -> {length}')\n\n#---CONCATENACIÓN---\ns11 = 'Hola'\ns12 = 'Mundo'\nresult = s11 + s12\nprint(f'Concatenación -> {result}')\n\n#---REPETICIÓN---\nrepeated = s1 * 3\nprint(f'Repetición -> {repeated}')\n\n#---MAYÚSCULAS Y MINÚSCULAS---\nupper = s1.upper()\nlower = s1.lower()\nprint(f'Mayúsculas -> {upper}')\nprint(f'Minúsculas -> {lower}')\n\n#---REEMPLAZO---\nreplaced = s1.replace(\"Mundo\", \"Python\")\nprint(f'Reemplazo -> {replaced}')\n\n#---DIVISION---\ns1_ = \"Hola,Mundo,Python\"\nparts = s1_.split(\",\")\nprint(f'Division -> {parts}')\n\n#---UNION---\nwords = [\"Hola\", \"Mundo\", \"Python\"]\njoined = \" \".join(words)\nprint(f'Union -> {joined}')\n\n#---INTERPOLACIÓN---\nnombre = \"Antonio\"\ns1__ = \"Hola {}\".format(nombre)\nprint(f'Interpolación -> {s1__}')\n\n#---VERIFICACIÓN---\n# --IGUALDAD--\ns3 = \"Hola Mundo\"\nis_equal = s1 == s3\nprint(f'Verificación-Igualdad (Hola Mundo == Hola Mundo) -> {is_equal}')\n\n# --EMPIEZA--\nstarts_with = s1.startswith(\"Hola\")\nprint(f'Verificación-Empieza (Hola Mundo == Hola) -> {starts_with}')\n\n# --TERMINA--\nends_with = s1.endswith(\"Mundo\")\nprint(f'Verificación-Termina (Hola Mundo == Mundo) -> {ends_with}')\n\n# --CONTIENE--\ncontains = \"Mundo\" in s1\nprint(f'Verificación-Contiene (Hola Mundo == Mundo) -> {contains}')\n\n\n\n\"\"\"\nEXTRA\n\"\"\"\ndef es_palíndromo(word):\n    word = word.lower()\n    return word == word[::-1]\n\ndef son_anagramas(word1, word2):\n    word1 = word1.lower()\n    word2 = word2.lower()\n    return sorted(word1) == sorted(word2)\n\ndef es_isograma(word):\n    word = word.lower()\n    return len(set(word)) == len(word)\n\ndef EXTRA(palabra1: str, palabra2: str):\n    #Palíndromo\n    print(f'{palabra1} es un Palíndromo: {es_palíndromo(palabra1)}')\n    print(f'{palabra2} es un Palíndromo: {es_palíndromo(palabra2)}')\n    \n    #Anagrama\n    print(f'{palabra1} es Anagrama de {palabra2}: {son_anagramas(palabra1, palabra2)}')\n    \n    #Isograma\n    print(f'{palabra1} es un Isograma: {es_isograma(palabra1)}')\n    print(f'{palabra2} es un Isograma: {es_isograma(palabra2)}')\n\nEXTRA('radar', 'roma')"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/JheisonQuiroga.py",
    "content": "\"\"\" Cadenas de carácteres \"\"\"\n# Las cadenas de caracteres conocidas como strings, son inmutables\n\n# Operaciones\n\ntext = \"Duban\"\nprint(text[0]) # Accediendo al primer valor\nprint(text[-1]) # Accediendo al último valor\n\n#Definiendo mas textos de varias formas\ntext = 'Hola, mi nombre es \"Duban\"'\nprint(text)\ntext = \"Hola, mi nombre es 'Duban'\"\nprint(text)\ntext = \"Hola, mi nombre es \\\"Duban\\\"\" # Utilizando formateo de carácteres\nprint(text)\nlarge_text = \"\"\"Esta es un texto de varias líneas. \nPrimero se declara la variable, luego se utilizan las\n'triple comillas dobles'\"\"\"\nprint(large_text)\nlarge_text = (\"Este es otro ejemplo de un texto de varias líneas,\"\n\"para ello se utiliza separando las comillas por medio de la coma (,)\") # Texto unido por literales de cadena\nprint(large_text)\n\n#Subcadenas o indices(slices), cortes o rebanadas\n\ntext = \"Duban Quiroga\"\n# Los slices mantienen la siguiente estructura\nprint(text[:5] + text[5:])\nfirst_name = text[0:5]\nlastname = text[6:]\nprint(first_name, lastname)\n#Saltos de carácteres\nhello = \"Hello World\"\nprint(hello[::2]) # HloWrd\n#Invertir una cadena\nprint(hello[::-1]) # dlroW olleH\n\n# Longitud de una cadena\n\nprint(len(text)) # 13 😏 Tu número fav\n\n# Concatenación de cadenas\nfirst_name = \"Duban\"\nlastname = \"Quiroga\"\n\ncomplete_name = first_name + \" \" + lastname\nprint(complete_name) # Duban Quiroga\nprint(complete_name * 3) # Podemos multiplicar las cadenas, a esto se le llama Repetición\n\n# Recorrido de una cadena\n\nfor letter in complete_name:\n    print(letter) # Imprime cada letra de la cadena\n\nfor letter in complete_name:\n    print(letter, end=\"\")\nprint()\n\n# Conversión a mayus y minus\n\nprint(complete_name.upper())\nprint(complete_name.lower())\n\n#Reemplazo\nprint(complete_name.replace(complete_name, \"Brais Moure\"))\n\n# División\n\nfirst_name, lastname = complete_name.split(\" \") # Separa cuando encuentra el espacio\nprint(first_name)\nprint(lastname)\n\n# Unión\n# Siguiendo la siguiente lógica de concatenación de listas\nname = [\"Duban\"]\nl_name = [\"Quiroga\"]\nfull_name = name + l_name\nprint(full_name)\nprint(\", \".join([first_name] + [lastname])) # Duban, Quiroga\n\n# Formateo de cadenas\n\nprint(f\"{first_name} {lastname}\") # Utilizando f-String\nprint(\"%s %s\"%(first_name, lastname))\n\n# Verificación\n\ndoes_d_in_duban = \"D\" in first_name\nprint(does_d_in_duban) # True\n\n\n\"\"\" Dificultad Extra \"\"\"\n\n\"\"\"\nCrea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n\"\"\"\ndef main(word1, word2):\n\n    def is_palindrome(word1, word2):\n        word2 = word2[::-1]\n        return word1 == word2 # Retorna True o False\n\n    def is_anagrama(word1:str, word2:str) -> bool:\n        word1 = sorted(word1.replace(\" \", \"\").lower())\n        word2 = sorted(word2.replace(\" \", \"\").lower())\n        return word1 == word2\n\n\n    def is_isograma(word:str):\n        word = word.lower().replace(\" \", \"\")\n\n        return len(word) == len(set(word))\n        \n    \n    if is_palindrome(word1, word2):\n        print(f\"{word1} y {word2} Son palindromos\")\n    else:\n        print(f\"{word1}, {word2} No son palindromos\")\n    \n\n    if is_anagrama(word1, word2):\n        print(f\"{word1}, {word2} Son anagramas\")\n    else:\n        print(f\"{word1}, {word2} No son anagramas\")\n    \n\n    if is_isograma(word1):\n        print(f\"La palabra: {word1} es Isograma\")\n    else:\n        print(f\"La palabra: {word1} no es isograma\")\n\n    if is_isograma(word2):\n        print(f\"La palabra: {word2} es Isograma\")\n    else:\n        print(f\"La palabra: {word2} no es Isograma\")\n\n    return f\"{is_palindrome(word1, word2)}, {is_anagrama(word1, word2)}, {is_isograma(word1)}, {is_isograma(word2)}\" \n\n\nprint(main(\"Toledo\", \"el todo\"))\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/Jose-Luis-Lanza.py",
    "content": "# EJERCICIO:\n# Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n# en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n# - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n#   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n\n# Asignacion de una string a una variable\ngreeting = \"Hello, World!\"\nprint(greeting)\n\n# Los Strings son Arrays\n\"\"\"\nComo muchos otros lenguajes de programación populares, las cadenas en Python son matrices de bytes que representan caracteres unicode.\nSin embargo, Python no tiene un tipo de datos carácter, un carácter es simplemente una cadena con una longitud de 1.\nSe pueden utilizar corchetes para acceder a los elementos de la cadena.\n\"\"\"\n# Acceso a caracteres específicos\ngreeting = \"Hello, World!\"\nprint(greeting[1])\n\n# Recorrer una cadena en Bucle\nfor c in \"banana\":\n    print(c)\n\n# Longitud de cadena\ngreeting = \"Hello, World!\"\nprint(len(greeting))\n\n# Para comprobar si una frase o un caracter esta dentro de una cadena, utilizamos \"in\"\ntxt = \"The best things in life are free!\"\nprint(\"free\" in txt)\n\n# Tambien se puede utilizar en una condicional if:\ntxt = \"The best things in life are free!\"\nif \"free\" in txt:\n    print(\"Yes, 'free' is present.\")\n\n# Para comprobar si una frase o un caracter no esta dentro de una cadena, utilizamos \"not in\"\ntxt = \"The best things in life are free!\"\nprint(\"expensive\" not in txt)\n\n# Tambien se puede utilizar en una condicional if:\ntxt = \"The best things in life are free!\"\nif \"expensive\" not in txt:\n    print(\"No, 'expensive' is NOT present.\")\n\n# Slicing (rebanar)\n# Consigue los caracteres de la posición 2 a la posición 5 (no incluidas):\nb = \"Hello, World!\"\nprint(b[2:5])\n\n# Rebanar desde el principio hasta la posicion 5(no incluida)\nb = \"Hello, World!\"\nprint(b[:5])\n\n# Rebanar hasta el final\n# Obtener los caracteres desde la posicion 2 hasta el final\nb = \"Hello, World!\"\nprint(b[2:])\n\n# Indexación Negativa\n# Se utilizan los indices negativos para empezar el corte desde el final de la cadena de texto:\n# Obtener los caracteres:\n# Desde: \"o\" en \"World!\" (posicion -5)\n# hasta pero no incluido el caracter \"d\" en \"World\" (posicion -2)\nb = \"Hello, World!\"\nprint(b[-5:-2])\n\n# Python - string methods\n# Mayusculas - upper()\na = \"Hello, World!\"\nprint(a.upper())\n\n# Minusculas - lower()\na = \"Hello, World!\"\nprint(a.lower())\n\n# Eliminar espacios en blanco que se encuentren al inicio o al final de la cadena de texto - strip()\na = \" Hello, World! \"\nprint(a.strip()) # returns \"Hello, World!\"\n\n# Sustituir Cadena - replace()\na = \"Hello, World!\"\nprint(a.replace(\"H\", \"J\"))\n\n# Dividir Cadena - split()\n# El método split() devuelve una lista en la que el texto entre el\n# separador especificado se convierte en los elementos de la lista.\na = \"Hello, World!\"\nprint(a.split(\",\")) # returns ['Hello', ' World!']\n\n# Concatenacion de cadenas\na = \"Hello\"\nb = \"World\"\nc = a + b\nprint(c)\n\n# Para agregar espacio entre ambas cadenas:\na = \"Hello\"\nb = \"World\"\nc = a + \" \" + b\nprint(c)\n\n# Para concatenar una lista de strings con \"join\"\ncadenas = [\"Hola\", \"Jose Luis\", \",\", \"¿cómo\", \"estás?\"]\nprint(\" \".join(cadenas))\n\n# DIFICULTAD EXTRA (opcional):\n# Crea un programa que analice dos palabras diferentes y realice comprobaciones\n# para descubrir si son:\n# - Palíndromos\n# - Anagramas\n# - Isogramas\n\ndef main():\n    string_1 = input(\"Type the first word: \").lower().strip()\n    string_2 = input(\"Type the second word: \").lower().strip()\n    palindrome(string_1, string_2)\n    anagram(string_1, string_2)\n    isogram(string_1, string_2)\n\n# Function Palindrome\ndef palindrome(word_1, word_2):\n    words = [word_1, word_2]\n\n    for word in words:\n        list_1 = []\n        list_2 = []\n        for char in word:\n            list_1.append(char)\n\n        for char in reversed(list_1):\n            list_2.append(char)\n\n        if list_1 == list_2:\n            print(f\"The word {word} is a palindrome.\")\n        else:\n            print(f\"The word {word} isn't a palindrome.\")\n\n# Function anagram\ndef anagram(word_1, word_2):\n\n    if sorted(word_1) == sorted(word_2):\n        print(f\"The words {word_1} and {word_2} are anagrams.\")\n    else:\n        print(f\"The words {word_1} and {word_2} aren't anagrams.\")\n\n# Function isogram\ndef isogram(word_1, word_2):\n    words = [word_1, word_2]\n\n    for word in words:\n        my_dict = dict()\n        for char in word:\n            if char in my_dict:\n                my_dict[char] += 1\n            else:\n                my_dict[char] = 1\n\n        first_value = list(my_dict.values())[0]\n\n        if all(value == first_value for value in my_dict.values()):\n            print(f\"The word {word} is an isogram.\")\n        else:\n            print(f\"The word {word} isn't an isogram.\")\n\nmain()\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/JoseAlberto13.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n\"\"\"\nmi_string = \"Hola Python\"\nmi_string2 = \"Hola GitHub!\"\nnombre = \"José\"\nedad = 26\n\n\n# Acceso a caracter específico\nprint(mi_string[5])\nprint(mi_string[6])\nprint(mi_string[7])\nprint(mi_string[8])\nprint(mi_string[9])\nprint(mi_string[10])\n\"\"\"Python\"\"\"\n\n\n# Subcadenas\nprint(mi_string[2:7])\n\"\"\"slicing = la Py\"\"\"\n\nprint(mi_string[-6:])\n\"\"\"slicing = Python (Ultimos caracteres)\"\"\"\n\nprint(mi_string[::-1])\n\"\"\"slicing reversa\"\"\"\n\nprint(mi_string[::2])\n\"\"\"slicing salto de caracteres \"\"\"\n\ncadena_string = \"@JoseAlberto13 programando en python desde el 2024\"\nprint(cadena_string.split()) # Este método crea una lista de subcadenas\n\nreversa = reversed(nombre) #reversa una palabra, es necesario transformarla en una lista para su impresion \nprint(list(reversa)) #transformamso la variable string en lista para su impresion\n\n\n# Subcadenas \"Búsqueda\"\notraString = \"Git\"\n\nprint(otraString in mi_string2) # retorna un boleano si encuentra o no la palabra dentro \"in\" de la cadena de texto\n\nprint(mi_string2.find(otraString)) # Este metodo retorna la posicion donde encuentra el primer caracter de la palabra buscada \"find\"\n\nprint(mi_string.startswith(\"Hola\")) # Este método retorna un valor booleano si encuentra o no la palabra al inicio de la cadena de texto\n\nprint(mi_string.endswith(\"thon\")) # Este método retorna un valor booleano si encuentra o no la palabra al final de la cadena de texto\n\nprint(cadena_string.count(\"de\")) # Este método cuenta las veces que aparece la palabra \"de\" dentro cadena de texto\n\n\n# Longitud\nprint(mi_string,\" tiene \" , len(mi_string) , \" caracteres\" )\n\n\n# Concatenación\nprint(mi_string + mi_string2)\n\nprint(mi_string + \" \" + mi_string2)\n\nprint(\"Mi nombre es {} y tengo {} años\".format(nombre, edad))\n\nprint(f\"{mi_string}, mi nombre es {nombre} y tengo {edad} años\")\n\n\n# Alineado \nprint('{:<15}''{:<7}''{:<4}'.format(mi_string,nombre,edad)) # Alineado a la derecha\n\nprint('{:>15}''{:>7}''{:>4}'.format(mi_string,nombre,edad)) # Alineado a la izquierda\n\nprint('{:^15}''{:^7}''{:^4}'.format(mi_string,nombre,edad)) # Alineado al centro\n\nprint('{:*^15}''{:*^7}''{:*^4}'.format(mi_string,nombre,edad)) # usa '*' para rellenar y ver el sentido de la alineación\n\nprint('{:*>15}''{:*>7}''{:*>4}'.format(mi_string,nombre,edad)) # usa '*' para rellenar y ver el sentido de la alineación\n\n\n# Repetición\nprint(mi_string2, mi_string2, mi_string2)\n\nprint(mi_string2 * 3)\n\n\n# Recorrido\nfor i in mi_string:\n    print(i)\nprint(\"\")\ni = 0\nwhile i < len(mi_string):\n    i+=1\n    print(mi_string[i *-1])\n\n\n# Conversión a Mayúsculas y Minúsculas\nprint(cadena_string.upper())\n\nprint(cadena_string.lower())\n\nprint(\"jose\".capitalize()) # Convierte en mayúscula la primera letra\n\nprint(cadena_string.title()) # Formatea el texto, colocando al inicio de cada palabra en mayúscula\n\nprint(mi_string.swapcase()) # Alterna las mayúsculas por minúsculas y viceversa\n\n\n# Reemplazo\nprint(\"Jose\".replace(\"e\",\"é\"))\n\nprint(cadena_string.replace(\" \",\"\")) # Quitamos los espacios con replace\n\nprint(cadena_string.replace(\"o\",\"oooo\")) \n\nprint(\"Jos@ Alb@rto Figu@roa Luc@na\".replace(\"@\", \"e\"))\n\nprint(\"José Alberto @JoseAlberto13\".replace(\"e\", \"E\", 1)) # El número indica la cantidad de caracteres reemplazará\n\nprint(\"   Esto es un texto con espacios al inicio y al final  \".strip()) # Quita los espacios al inicio y al final del texto\n\n# Reemplazo por medio de indiciese \"Mejor usar el método anterior xd\"\nnombre = \"Alverto\"\nprint(nombre)\nnombre = nombre[:2] + \"b\" + nombre[3:] # Dividimos la cadena en 2, y en la intersección agregamos el caracter que deseemos cambiar [inicio:fin] + \"caracter\" + [inicio:fin]\nprint(nombre)\n\nnumero = \"27287281\"\nprint(type(numero), numero)\nnumero = int(numero)\nprint(type(numero), numero)\nnumero = str(numero)\n\n# División\nprint(cadena_string.split(\"en\")) #divide la cadena de texto en la palabra o caracter indicado y si este no es definido, lo divide en cada espacio en blanco\n\nprint(cadena_string.split(\"e\",2)) # donde estaba la \"e\" es dividido las veces que se le es indicado, si no se le indica la veces que hara la division, esta sera ilimitada\nprint(type(cadena_string.split(\"e\",2))) # lo transforma en una lista\n\ncolores = \"amarillo,azul,rojo,blanco\"\nprint(colores)\ncolores = colores.split(\",\") # Divideremos los colores por las comas\nprint(colores)\n\n# División con indices\nprint(cadena_string[:15] + \" / \" + cadena_string[22:])\n\n\n# Unión\nprint(\" \".join(colores))\n\n# Verificación // Comprobación\nprint(\"HOLA\".isupper()) # Comprueba si un texto esta en mayúsculas\nprint(\"Hola\".islower()) # Comprueba si un texto esta en minúsculas\nprint(cadena_string.isnumeric()) \nprint(cadena_string.isalnum())\nprint(cadena_string.isprintable())\nprint(cadena_string.isascii())\nprint(numero.isdigit())\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n\"\"\"\n\ndef palindromo(text1:str, text2:str):\n    text1min = text1.lower()\n    text2min = text2.lower()\n    print(f\"'{text1}' es palindromo: {text1min == text1min[::-1]}\")\n    print(f\"'{text2}' es palindromo: {text2min == text2min[::-1]}\")\n\ndef anagrama(text1:str, text2:str):\n    text1min = text1.lower()\n    text2min = text2.lower()\n    print(f\"'{text1} y {text2}' son anagramas: {sorted(text2min)==sorted(text1min)}\")\n\ndef isograma(text1:str, text2:str):\n    text1min = text1.lower()\n    text2min = text2.lower()\n    print(f\"'{text1}' es un isograma: {len(text1min) == len(set(text1min[::-1]))}\")\n    print(f\"'{text2}' es un isograma: {len(text2min) == len(set(text2min[::-1]))}\")\n\npalindromo(\"Anna\",\"Roncar\")\n\nanagrama(\"Gato\", \"Toga\")\n\nisograma(\"Rancho\",\"Roncando\")\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/JuanDAW37.py",
    "content": "\"\"\"\n* EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\n *   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\n *   interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n\"\"\"\ncadena = \"Esto es una cadena de caracteres\" # Asignación\ncadena2 = \" para hacer pruebas en Python\"\n\nprint(cadena + cadena2) # Concatenación\n\nprint(cadena * 3) # Repetición\n\nprint(cadena[9]) # Acceso a caracteres específicos\n\nprint(len(cadena)) # Longitud de la cadena\n\n# Porciones de cadena\nprint(cadena[2:6])\nprint(cadena[:6])\nprint(cadena[2:])\n\nprint('e' in cadena) # Búsqueda\nprint(cadena.startswith('H')) # Búsqueda al principio\nprint(cadena.endswith('H')) # Búsqueda al final\nprint(cadena.find('J')) # Búsqueda de posición\n\nprint(cadena.replace('e', 'j')) # Reemplazo\n\nprint(cadena.capitalize()) # Convertir la primera letre a mayúsculas\n\nprint(cadena.upper()) # Convertir a mayúsculas\n\nprint(cadena.lower()) # Convertir a minúsculas\n\nprint(cadena.title()) # Cada palabra con letra capital\n\nprint(cadena.split('t')) # Eliminar el carácter indicado\n\nprint(cadena.join('ta')) # Pone la t al comienzo de la cadena y la a como última letra\n\nprint(cadena2.strip()) # Quita espacios al principio y al final\n\nprint(cadena.count('e')) # Conteo de caracteres\n\n# Formateo\nprint('cadena tiene {} y cadena2 tiene {}'.format(cadena, cadena2)) # Con format()\nprint(f'cadena tiene {cadena} y cadena2 tiene {cadena2}') # Con f-string\n\nprint(list(cadena)) # Transformación en una lista\n\n# Casting de cadenas en números\nnum1 = \"123456\"\nprint(type(num1))\nnu = int(num1) # A entero\nprint(type(nu))\nnum2 = \"123456.75\"\nprint(type(num2))\nnu2 = float(num2) # A decimal\nprint(type(nu2))\n\nprint(cadena.isalpha()) # Comprobar si sólo tiene letras\n\nprint(cadena.isnumeric()) # Comprobar si es número\n\nprint(cadena.endswith('r')) # Finaliza con un carácter o un conjunto de caracteres\n\nprint(cadena.startswith('r')) # Comienza con un carácter o un conjunto de caracteres\n\nprint(cadena.isalnum())\n\n# * DIFICULTAD EXTRA (opcional):\ndef palindromo(palabra1:str, palabra2:str):\n    print(f'¿{palabra1} se lee igual?: {palabra1 == palabra1[::-1]}')# Se recorre la palabra de principio a fin, y con -1 desde atrás haca adelante\n    print(f'¿{palabra2} se lee igual?: {palabra2 == palabra2[::-1]}')\n        \npalindromo('hola', 'radar')\n\ndef anagrama(palabra1:str, palabra2:str):\n    print(f'¿{palabra1} es ANAGRAMA de {palabra2}?: {sorted(palabra1) == sorted(palabra2)}') # Si al ordenar alfabéticamente palabra1 y palabra2, son iguales, es que son ANAGRAMAS\n\nanagrama('amor', 'roma')\n\ndef isograma(palabra1:str, palabra2:str):\n    print(len(palabra1)) # Longitud de la palabra\n    print(len(set(palabra1))) # Número de letras no repetidas en la palabra, ya que los sets no permiten repeticiones\n    print(len(palabra2))\n    print(len(set(palabra2)))\n    print(f'¿{palabra1} es un isograma?: {len(palabra1) == len(set(palabra1))}')\n    print(f'¿{palabra2} es un isograma?: {len(palabra2) == len(set(palabra2))}')\n    \n    # Comprobar que tipo de isograma es\n    diccionario:dict = dict()\n    \n    for l in palabra1:\n        diccionario[l] = diccionario.get(l,0) + 1 # En diccionario guardo l (letra), de existir ya en diccionario, le suma 1, en caso contrario, la da de alta y le asigna 0+1=1\n    print(diccionario)\n    \nisograma('hola', 'radar')"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/Juanma0416.py",
    "content": "\"\"\"\nOperaciones\n\"\"\"\n\ns1 = \"Hola\"\ns2 = \"Python\"\n\n# Concatenación\nprint(s1 + \", \" + s2 + \"!\")\n\n# Repetición\nprint(s1 * 3)\n\n# Indexación\nprint(s1[0] + s1[1] + s1[2] + s1[3])\n\n# Longitud\nprint(len(s2))\n\n# Slicing (porción)\nprint(s2[2:6])\nprint(s2[2:])\nprint(s2[0:2])\nprint(s2[:2])\n\n# Busqueda\nprint(\"a\" in s1)\nprint(\"i\" in s1)\n\n# Reemplazo\nprint(s1.replace(\"o\", \"a\"))\n\n# División\nprint(s2.split(\"t\"))\n\n# Mayúsculas, minúsculas y letras en mayúsculas\nprint(s1.upper())\nprint(s1.lower())\nprint(\"juancho\".title())\nprint(\"juancho\".capitalize())\n\n# Eliminación de espacios al principio y al final\nprint(\" juancho \".strip())\n\n# Búsqueda al principio y al final\nprint(s1.startswith(\"Ho\"))\nprint(s1.startswith(\"Py\"))\nprint(s1.endswith(\"la\"))\nprint(s1.endswith(\"thon\"))\n\ns3 = \"Juancho Mancho @juancho\"\n\n# Búsqueda de posición\nprint(s3.find(\"juancho\"))\nprint(s3.find(\"Juancho\"))\nprint(s3.find(\"J\"))\nprint(s3.lower().find(\"j\"))\n\n# Búsqueda de ocurrencias\nprint(s3.lower().count(\"j\"))\n\n# Formateo\nprint(\"Saludo: {}, lenguje: {}!\".format(s1, s2))\n\n# Interpolación\nprint(f\"Saludo: {s1}, lenguje: {s2}!\")\n\n# Tranformación en lista de caracteres\nprint(list(s3))\n\n# Transformación de lista en cadena\nl1 = [s1, \", \", s2, \"!\"]\nprint(\"\".join(l1))\n\n# Transformaciones numéricas\ns4 = \"123456\"\ns4 = int(s4)\nprint(s4)\n\ns5 = \"123456.123\"\ns5 = float(s5)\nprint(s5)\n\n# Comprobaciones varias\ns4 = \"123456\"\nprint(s1.isalnum())\nprint(s1.isalpha())\nprint(s4.isalpha())\nprint(s4.isnumeric())\n\n\"\"\"\nExtra\n\"\"\"\n\n\ndef check(word1: str, word2: str):\n\n    # Palíndromos\n    print(f\"¿{word1} es un palíndromo?: {word1 == word1[::-1]}\")\n    print(f\"¿{word2} es un palíndromo?: {word2 == word2[::-1]}\")\n\n    # Anagramas\n    print(f\"¿{word1} es anagrama de {word2}?: {sorted(word1) == sorted(word2)}\")\n\n    # Isogramas\n\n    def isogram(word: str) -> bool:\n\n        word_dict = dict()\n        for character in word:\n            word_dict[character] = word_dict.get(character, 0) + 1\n\n        isogram = True\n        values = list(word_dict.values())\n        isogram_len = values[0]\n        for word_count in values:\n            if word_count != isogram_len:\n                isogram = False\n                break\n\n        return isogram\n\n    print(f\"¿{word1} es un isograma?: {isogram(word1)}\")\n    print(f\"¿{word2} es un isograma?: {isogram(word2)}\")\n\n\ncheck(\"radar\", \"pythonpythonpythonpython\")\n# check(\"amor\", \"roma\")\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/KevinED11.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n \"\"\"\nfrom abc import ABC, abstractmethod\n\n\ndef string_operations(text: str) -> None:\n    first_char = text[0]\n    substring = text[1:]\n    length = len(text)\n    concatenation = text + text\n    repeated = text * 2\n\n    for char in text:\n        print(char)\n\n    text_to_upper = text.upper()\n    text_to_lower = text.lower()\n    replace_last_char_in_text = text[:-1] + first_char\n    other_replace = text.replace(text[0], \"\")\n    interpolation = f\"{text} {text}\"\n    verification = text == text[::-1]\n    verification2 = \"h\" in text\n    division_for_words = text.split()\n    division_for_chars = list(text)\n    division_for_chars2 = [char for char in text]\n\n    print(\"first_char:\", first_char)\n    print(\"substring:\", substring)\n    print(\"length:\", length)\n    print(\"concatenation:\", concatenation)\n    print(\"repeated:\", repeated)\n    print(\"text_to_upper:\", text_to_upper)\n    print(\"text_to_lower:\", text_to_lower)\n    print(\"replace_last_char_in_text:\", replace_last_char_in_text)\n    print(\"other_replace:\", other_replace)\n    print(\"interpolation:\", interpolation)\n    print(\"verification:\", verification)\n    print(\"verification2:\", verification2)\n    print(\"division_for_words:\", division_for_words)\n    print(\"division_for_chars:\", division_for_chars)\n    print(\"division_for_chars2:\", division_for_chars2)\n\n\nclass Comprobator(ABC):\n    @abstractmethod\n    def is_palindrome(self) -> bool:\n        pass\n\n    @abstractmethod\n    def is_anagram(self) -> bool:\n        pass\n\n    @abstractmethod\n    def is_isogram(self) -> bool:\n        pass\n\n\nclass Program(Comprobator):\n    def __init__(self, text1: str, text2: str) -> None:\n        self.text1 = text1.lower()\n        self.text2 = text2.lower()\n\n    def is_palindrome(self) -> bool:\n        return self.text1 == self.text2[::-1]\n\n    def is_anagram(self) -> bool:\n        return len(self.text1) == len(self.text2) and all(\n            char in self.text2 for char in self.text1\n        )\n\n    def is_isogram(self) -> bool:\n        word1_is_isogram = len(set(self.text1)) == len(self.text1)\n        word2_is_isogram = len(set(self.text2)) == len(self.text2)\n        print(\"text1 is isogram:\", word1_is_isogram)\n        print(\"text2 is isogram:\", word2_is_isogram)\n\n        return word1_is_isogram and word2_is_isogram\n\n\ndef main() -> None:\n    string_operations(text=\"hello\")\n\n    program = Program(text1=\"hola\", text2=\"aloh\")\n    print(program.is_palindrome())\n    print(program.is_anagram())\n    print(program.is_isogram())\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/Lazar171717ech.py",
    "content": "## 1. STRINGS ##\n\nstring_uno = \"Hola\" # Esto es una cadena de caracteres, también conocidas como strings o str\n# También podemos definir un string con la triple comilla, ponré un ejemplo más tarde.\nprint(string_uno)\nprint(f\"string_uno + ', soy Juan' = {string_uno + ', soy Juan'}\") # Podemos concatenarlos con el simbolo +\nprint(f\"'Hola' ', soy Juan' = {'Hola' ', soy Juan'}\") # Podemos concatenar dos str poniendolos juntos (no funciona con variables)\nprint(f\"string_uno * 5 = {string_uno * 5}\") # Podemos hacer que se repita con el simbolo * y el numero de repeticiones\nstring_uno += \", soy Juan\"\nprint(string_uno) # También se le aplican los operadores de reasignación\nprint(f\" len(string_uno) = {len(string_uno)}\") # Con la función len podemos saber la longitud de un string\nprint(f\"string_uno.lower() = {string_uno.lower()}\") # Con el método lower se cambiarán las mayúsculas por minúsculas\nprint(f\"string_uno.upper() = {string_uno.upper()}\") # Con el método upper se cambiarán las minúsculas por mayúsculas\nprint(f\"string_uno.replace('Juan', 'Ernesto') = {string_uno.replace('Juan', 'Ernesto')}\") # con el método replace sustituimos un string dentro del principal por otro\n# A cada caracter del string se le asigna un valor numérico de izquierda a derecha empezando por el 0. \nprint(f\"string_uno.find('Juan') = {string_uno.find('Juan')}\") # Con el método find podemos saber en que posición se encuentra un string dentro de otro,\n# En caso de haber varios se debuelve el primero por la izquierda y en caso de no encontrar debuelve -1\nprint(f\"string_uno.count('a') = {string_uno.count('a')}\") # Al igual que en listas podemos usar el método count para saber cuantas veces está us string en otro.\n# Esto lo explico porque lo usaré en el ejercicio extra.\nprint(f\"string_uno[4] = {string_uno[4]}\") # Podemos mostrar el caracter en una posicion con la sintaxix: variable_str[posición]\nprint(f\"string_uno[1:7] = {string_uno[1:7]}\") # Podemos mostrar una parte del string con la sintaxis: variable_str[posición para empezar:posición para finalizar]\n# Podemos quitar las posiciones si queremos que empieze por el principio o termine por el final.\nprint(f\"string_uno[1:-3] = {string_uno[1:-3]}\") # Si ponemos un número negativo simplemente nos referimos a la posición comenzando por la derecha comenzando por -1.\nprint(f\"string_uno[-4] = {string_uno[-4]}\") # También funciona para mostrar los caracteres\nprint(f\"string_uno[::-1] = {string_uno[::-1]}\") # Si usamos el [::-1] estaríamos invirtiendo el string\nprint(f\"\\n{string_uno}\") # Usando \\n en un string sería como insertar un salto de línea\nprint(f\"\\t{string_uno}\") # Usando \\t en un string sería como insertar una tabulación\nstring_en_lineas = \"\"\"Hola, soy Juan \nHola, soy Ernesto\"\"\" #Como ya he dicho se puede definir un str en varias líneas con la triple comilla\nstring_en_lineas2 = \"Hola, soy Juan\\nHola, soy Ernesto\"\nprint(f\"Es igual usar n que triple comilla? = {string_en_lineas == string_en_lineas2}\") # Sí\n#Se puede usar un bucle for para recorrer un string:\nfor index in string_uno:\n    print(index)\nprint(f\"'Juan' in string_uno = {'Juan' in string_uno}\") # Se puede saber si un string está en otro string usando in:\n#Llevo usandolo todo el rato pero se pueden usar tanto comillas simples como comillas dobles. Esto es para poder usar un tipo de comillas en un string\nprint(f\"Él dijo: '{string_uno}'.\")\nprint(f\"Él dijo: \\\"{string_uno}\\\"\") #También se puede usar el mismo tipo si ponemos \\ + las comillas\nprint(r\"\\n <-- No se está leyendo como un salto de línea\") # usando r delante podemos hacer que lea \\ como el caracter\nprint(fr\"\\n {string_uno}\") # Podemos unsar el formateo (f) y el raw (r) al mismo tiempo\n#Por supuesto el formateo se usa poniendo f delante y lo que haya entre {} dentro del string se leerá como codigo a imprimir\nstring_dos = \"\\n \\t\\nHola Juan\\n\\t \\t\"\nprint(f\"string_dos.strip() = {string_dos.strip()}\") # Con el método strip eliminamos los espacios, saltos de línea y tabulaciones innecesarios al principio y al final\n# Si solo los queremos quitar de uno de los lados podemos usar rstrip o lstrip\nprint(f\"string_dos.rstrip() = {string_dos.rstrip()}\")\nprint(f\"string_dos.lstrip() = {string_dos.lstrip()}\")\nprint(f\"string_dos.split() = {string_dos.split()}\") # Con el método split convertimos el split en una lista con todos los strings separados por \" \", \\n o \\t\nprint(f\"string_dos.split(' ') = {string_dos.split(' ')}\") # Si le pasamos un argumento serán los strings separados por el argumento dado\n \n## 2. Dificultad Extra ##\n\ndef anagrama(wrd1, wrd2):\n    wrd1,wrd2 = wrd1.lower(),wrd2.lower()\n    for i in wrd1:\n        if i in wrd2 and wrd1.count(i) == wrd2.count(i): pass\n        else: return(False)\n    return(True)\n\ndef isograma(wrd1, wrd2):\n    wrd1,wrd2 = wrd1.lower(),wrd2.lower()\n    for i in wrd1:\n        if wrd1.count(i) == 1: pass\n        else: return(False)\n    for i in wrd2:\n        if wrd2.count(i) == 1: pass\n        else: return(False)\n    return(True)\n\ndef palindromo(wrd1, wrd2):\n    wrd1,wrd2 = wrd1.lower(),wrd2.lower()\n    if wrd1 != wrd1[::-1]: return False\n    if wrd2 != wrd2[::-1]: return False\n    else: return True\n\ndef queson(string1, string2):\n    if palindromo:\n        print(\"Ambos son palíndromos\")\n    elif anagrama(string1, string2):\n        print(\"Son anagramas\")\n    elif isograma(string1, string2):\n        print(\"Ambos son isogramas\")\n    else: print(\"No son ninguno\")\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/Lio7master.py",
    "content": "\n#  * EJERCICIO:\n#  * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n#  * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n#  * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n#  *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n#  * para descubrir si son:\n#  * - Palíndromos\n#  * - Anagramas\n#  * - Isogramas\n\n#Operaciones\n\ns1 = \"hola\"\ns2 = \"PYTHON\"\n\nprint(s1 + \" \" + s2)\n\n\n#replicacion\nprint(s1 * 3)\n\n#indexacion\nprint(s1[0]+s2[4]+s1[2]+s1[3])\n\n#longitud\nprint(\"longitud cadena Python: \" + str(len(s2)))\n\n#slicing\n\nprint(\"slicing [2:5]= \" + s2[2:5])\nprint(\"slicing [2:]: \" + s2[2:])\nprint(\"slicing [0:2]: \" + s2[0:2])\nprint(\"slicing [:2]: \" + s2[:2])\n\n#busqueda\n\nprint(\"a\" in s1)\nprint(\"ho\" in s1)\nprint(\"y\" in s1)\n\n#remplazo\nprint(s1.replace(\"o\", \"a\"))\n\n#division\nprint(s2.split(\"t\"))\ns3 = \"pythonthon\"\nprint(s3.split(\"t\"))\n\n#Mayusculas y minusculas\nprint(s1.upper())\nprint(s2.lower())\nprint(\"lio 7 master\".title())\nprint(\"lio 7 master\".capitalize())\n\n#eliminacion de espacios al principio y fin\n\nprint(\" leo limon \".strip() + \"@dominio.com\")\n\n#busqueda al principio y al final\nprint(s1.startswith(\"py\"))\nprint(s1.startswith(\"ho\"))\nprint(s1.endswith(\"la\"))\nprint(s1.endswith(\"hon\"))\n\n#busqueda de posición\n\nprint(\"Leonardo Limon @lio7master\".find(\"li\"))\nprint(\"Leonardo Limon @lio7master\".find(\"lim\"))\nprint(\"Leonardo Limon @lio7master\".find(\"Lim\"))\nprint(\"Leonardo Limon @lio7master\".find(\"L\"))\nprint(\"Leonardo Limon @lio7master\".find(\"l\"))\n\n#busqueda de ocurrencia\nprint(s3.lower().count(\"h\"))\n\n#formato\nprint(\"Saludos: {}, lenguaje: {}\".format(s1, s2))\n\n#interpolacion\nprint(f\"Saludos: {s1}, lenguaje: {s2}\")\n\n#Transformacion de lista de caracteres\n\nprint(list(s3))\n\n#trsnformacion de lista en cadena\n\nl1 = [s1, \"\", \"\", s2, \"!\"]\n\nprint(\" \".join(l1))\n\n#transformacion numerica\ns4 = \"1234567\"\ns4 = int(s4)\nprint(s4)\n\n\ns5 = \"1234567.89\"\ns5 = float (s5)\nprint(s5)\n\n#comprobacion varias\ns4 = \"1234567\"\nprint(s1.isalnum())\nprint(s1.isalpha())\nprint(s4.isalpha())\nprint(s4.isnumeric())\n\n\n#EXTRA\n\n\ndef check(word1: str, word2: str):\n\n    #palindromos -> Palabras/fraces que se leen igual de derecha a izquierda como izquierda a derecha.\n    print(word1)\n    print(word2[::-1]) #Esta sentencia invierte la posicion del strinf pero se pueden usar otras funciones\n\n    print(f\"{word1} es un palindromo?: {word1 == word1[::-1]}\")\n    print(f\"{word2} es un palindromo?: {word2 == word2[::-1]}\")\n\n    #anagrama -> es una  palabra que resulta de reordenar todas las letras de otra palabra\n    print(f\"{word1} es un anagrama de {word2}?: {sorted(word1)== sorted(word2)}\")\n\n    #heterograma -> es una palabra o frase que no contiene ninguna letra repetida.\n    #isograma -> en una palabra aparecen el mismo numero de veces cada letra, o en una frase cada palabra palabra.\n    print(len(word1)) #la longitud total de la palabra \n    print(len(set(word1)))#el set por su concepto mismo no permite el guardar valores duplicados, por lo que nos permite contar las letras diferentes para este caso\n    print(f\"¿La palabra {word1} es un isograma? {len(word1)==len(set(word1))}\")\n    print(f\"¿La palabra {word2} es un isograma? {len(word2)==len(set(word2))}\")\n\n    def isograma(word: str) -> bool:\n        word_dict = dict()\n        for charater in word:\n            word_dict[charater] = word_dict .get(charater, 0) + 1\n\n        isograma = True\n        values =  list(word_dict.values())\n        isograma_len = values[0]\n        for word_count in word_dict.keys():\n            if len(word_count) != isograma_len:\n                isograma = False\n                break\n        return isograma\n   \n    print(f\"¿La palabra {word1} es un isograma? (fun) {isograma(word1)}\")\n    print(f\"¿La palabra {word2} es un isograma?(fun){isograma(word2)}\")\n\ncheck(\"radar\", \"python\")\ncheck(\"amor\", \"roma\")\ncheck(\"radar\", \"python\")\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/Lioomx.py",
    "content": "''' \nOperaciones con cadenas de caracteres\n'''\n\n# Concatenación de cadenas\n\nc1 = \"Hola\"\nc2 = \"Mundo\"\nresultado = c1 + \" \" + c2\nprint(resultado)\n\n# Repetición de cadenas\n\ncadena = \"Python\"\nprint(cadena * 3)\n\n# Longitud de una cadena\n\ncadena = \"Curso de Python\"\nprint(len(cadena))\n\n# Acceso a caracteres\n\ncadena = \"Python\"\nprint(cadena[0])\nprint(cadena[-1])\n\n# Rebanado (slicing)\n\ncadena = \"Curso de Python\"\nprint(cadena[0:8]) # Salida: Curso de\nprint(cadena[:8]) # Salida: Curso de (inicio implicito)\nprint(cadena[9:]) # Salida: Python (final implicito)\nprint(cadena[::-1]) # Salida: nohtyP ed osruC (Cadena invertida)\n\n# Mayúsculas y minúsculas\n\ncadena = \"Python\"\nprint(cadena.upper()) # PYTHON\nprint(cadena.lower()) # python\n\n# Eliminar espacios\n\ncadena = \"  Hola Mundo  \"\nprint(cadena.strip()) # Salida: Hola Mundo\nprint(cadena.lstrip()) # Salida: \"Hola Mundo  \"\nprint(cadena.rstrip()) # Salida: \"  Hola Mundo\"\n\n# Buscar y reemplazar\n\ncadena = \"Aprender Python es divertido\"\nprint(cadena.find(\"Python\")) # Salida: 9 (posición)\nprint(cadena.replace(\"divertido\", \"facil\")) # Salida: Aprender Python es facil\n\n# Dividir y unir cadenas\n\ncadena = \"uno, dos, tres\"\nlista = cadena.split(\", \")\nprint(lista) # Salida: ['uno', 'dos', 'tres']\n\nnueva_cadena = \" - \".join(lista)\nprint(nueva_cadena) # Salida: uno - dos - tres\n\n# Verificar contenido\n\ncadena = \"Python3\"\nprint(cadena.startswith(\"Py\")) # Salida: True\nprint(cadena.endswith(\"3\")) # Salida: True\nprint(cadena.isalpha()) # Salida: False (tiene números)\nprint(\"12345\".isdigit()) # Salida: True\n\n\n\"\"\" EXTRA \"\"\"\n\ndef palindromo(palabra):\n    palabra = palabra.lower().replace(\" \", \"\") # Ignora mayúsculas y espacios\n    return palabra == palabra[::-1]\n\ndef anagrama(palabra1, palabra2):\n    palabra1 = palabra1.lower().replace(\" \", \"\")\n    palabra2 = palabra2.lower().replace(\" \", \"\")\n    return sorted(palabra1) == sorted(palabra2)\n\ndef isograma(palabra):\n    palabra = palabra.lower().replace(\" \", \"\")\n    return len(palabra) == len(set(palabra))\n\nprint(\"Analizador de palabras\")\npalabra1 = input(\"Ingresa la primera palabra: \")\npalabra2 = input(\"Ingresa la segunda palabra: \")\n\nif palindromo(palabra1): \n    print(f\"- '{palabra1}' es un palindromo.\")\nelse: \n    print(f\"- '{palabra1}' no es un palindromo.\")\n\nif anagrama(palabra1, palabra2):\n    print(f\"- '{palabra1}' y '{palabra2}' son anagramas.\")\nelse:\n    print(f\"- '{palabra1}' y {palabra2}' no son anagramas.\")\n\nif isograma(palabra1):\n    print(f\"- '{palabra1}' es un isograma.\")\nelse: \n    print(f\"- '{palabra2}' no es un isograma.\")\n\n    "
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/LittleMabbit.py",
    "content": "'''\nOperaciones en Python\n'''\n\nt1 = 'Hola'\nt2 = 'Python'\nt3 = 'Py thon'\n\n# Concatenación\nprint(t1 + t2)\n\n# Repetición\nprint(t1 * 3)\n\n# Indexing\nprint(t1[1])\n\n# Slicing\nprint(t2[2:])\n\n# Longitud\nprint(len(t1))\n\n# Busqueda\nprint(t1.find('o'))\nprint('H' in t1)\n\n# Reemplazo\nprint(t1.replace('H', 'Hh'))\n\n# Division\nprint(t2.split('t'))\nprint(t3.split(' '))\n\n# Mayusculas ó minúsculas\nprint(t2.lower())\nprint(t2.upper())\n\n# Eliminar espacios al principio y al final de un string.\nprint(' Cinnamon Rat '.strip())\n\n# Busqueda al principio y al final de un string.\nprint(t1.startswith('H'))\nprint(t1.endswith('a'))\n\n# Busqueda de posición\nprint('Cinnamon Rat Rabbiting'.find('Ra'))\nprint('Cinnamon Rat Rabbiting'.find('Rab'))\nprint('Cinnamon Rat Rabbiting'.find('R', 11))\n\n# Busqueda de coincidencias\nprint('Cinnamon Rat Rabbiting'.count('a'))\n\n# Interpolacion\nprint(f'{t1}, estas viendo {t2}. O bueno, jeje, también {t3}')\n\n# Formateo\nprint('{}, estás viendo {}, bienvenido!'.format(t1, t2))\n\n# De caracteres a listas.\nprint(list(t3))\n\n# De string a integer\nnum = '12345'\nnum_ = int(num)\nprint(type(num_))\n\n# De string a float\ndnum = '1234.56'\ndnum_ = float(dnum)\nprint(type(dnum_))\n\n# Comprobaciones\nprint(t1.isalnum())\nprint(t1.isalpha())\nprint(t1.islower())\nprint(t1.isdecimal())\n\n'''\nCrea un programa que analice dos palabras diferentes y realice comprobaciones para verificar si son palíndromos, anagramas ó isogramas.\n'''\n\ndef check(w1: str, w2: str):\n  print(f\"Verifiquemos si {w1} es palíndromo. {w1 == w1[::-1]}\") # Con el slicing [::-1] damos vuelta la palabra.\n  print(f\"Verifiquemos si {w2} es palíndromo. {w2 == w2[::-1]}\") # La lógica es que si la palabra equivale a su misma palabra a la inversa, entonces es palíndroma.\n\n  print(f\"¿ Es {w1} anagrama de {w2}?: {sorted(w1) == sorted(w2)}\")\n\n  def isogram(word: str) -> bool:\n\n        word_dict = dict() # Establecemos un diccionario vacío.\n        for character in word: # Loopeamos entre los carácteres dentro de word.\n            word_dict[character] = word_dict.get(character, 0) + 1 # Accedemos a cada valor.\n        isogram = True # Valor inicial a 'isogram' seteado.\n        values = list(word_dict.values()) # La lista de los word.dict.\n        isogram_len = values[0] \n        \n        for word_count in values: # Por cada valor dentro de values:\n            if word_count != isogram_len: # Si el word_count NO es igual al valor de isogram_len, entonces es falso.\n                isogram = False\n                break\n\n        return isogram\n\n  print(f\"¿Es {w1} un isograma?: {isogram(w1)}\")\n  print(f\"¿Es {w2} un isograma?: {isogram(w2)}\")\n\ncheck('salas', 'subcampeon')\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/LucasRebuffo.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\n *   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\n *   interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */ \"\"\"\n\n\"\"\" Operaciones con Strings \"\"\"\n\nimport re\nfrom xmlrpc.client import Boolean\n\n\nmy_string_1 = \"Hola\"\nmy_string_2 = \"Lucas\"\n\n# Concatenacion\nprint(my_string_1 + \" \" + my_string_2)\n\n# Repeticion\nprint(my_string_2 * 5)\n\n# Indexacion\nprint(my_string_1[0] + my_string_2[1])\n\n# Longitud\nprint(len(my_string_1))\n# Slicing (partir la cadena de texto)\nprint(my_string_1[1:3])\nprint(my_string_2[1:])\nprint(my_string_1[:-1])\nprint(my_string_2[0:3])\nprint(my_string_1[:2])\n\n# Reemplazo\nprint(my_string_1.replace(\"a\", \"x\"))\n\n# Busqueda\nprint(\"h\" in my_string_1)\nprint(\"x\" in my_string_2)\n\n# Division\nprint(my_string_2.split(\"c\"))\n\n# Mayusculas y minusculas\nprint(my_string_1.upper())\nprint(my_string_1.lower())\nprint(my_string_1.capitalize())\nprint(my_string_1.title())\n\n\n# Eliminacion de espacios (strip)\nprint(\"Lucas Rebuffo\".strip())\n\n# Busqueda al principio y al final\nprint(my_string_1.startswith(\"Ho\"))\nprint(my_string_2.endswith(\"as\"))\n\n# Busqueda de posicion\nprint(\"lucasrebu@outlook.com\".find(\"@\"))\nprint(\"lucasrebu@outlook.com\".find(\"@\"))\nprint(\"lucasrebu@outlook.com\".find(\"u@\"))\n\n# Busqueda de ocurrencias\nprint(\"Lucas Rebuffo\".count(\"f\"))\n\n# Formateo\nprint(\"{} {} !\".format(my_string_1, my_string_2))\n\n# Interpolacion\nprint(f\"{my_string_1} {my_string_2} !\")\n\n# Transferencia de lista de caracteres\nlista_char = list(my_string_1)\nprint(lista_char)\nprint(\"-\".join(lista_char))\n\n# Transformacion numerica\nprint(int(\"452\"))\nprint(float(\"452.2\"))\n\n# Comprobaciones\nprint(\"151\".isdecimal())\nprint(\"151a\".isalnum())\nprint(\"a\".isascii())\nprint(\"def\".isidentifier())\n\n\n\"\"\"  * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */ \"\"\"\n\n\ndef is_palindrome(cadena: str):\n    return cadena[::-1].strip().lower() == cadena.strip().lower()\n\n\ndef is_anagram(cadena1: str, cadena2: str):\n    return sorted(cadena1.lower()) == sorted(cadena2.lower())\n\n\ndef is_isogram(cadena: str):\n    set_caracteres = set(cadena)\n    lista = list(map(lambda char: cadena.count(char), set_caracteres))\n    r = set(lista)\n    return len(r) == 1\n\n\ndef chequear_palabras(cadena1: str, cadena2: str):\n\n    print(\"Chequeo de palindromo: \")\n    if is_palindrome(cadena1):\n        print(f\"{cadena1} es palindromo\")\n    else:\n        print(f\"{cadena1} NO es palindromo\")\n    if is_palindrome(cadena2):\n        print(f\"{cadena2} es palindromo\")\n    else:\n        print(f\"{cadena2} NO es palindromo\")\n\n    print(\"----------------------------------------\")\n\n    print(\"Chequeo de anagrama: \")\n    if is_anagram(cadena1, cadena2):\n        print(f\"{cadena1} y {cadena2} son anagramas\")\n    else:\n        print(f\"{cadena1} y {cadena2} NO son anagramas\")\n\n    print(\"----------------------------------------\")\n\n    print(\"Chequeo de isograma: \")\n    if is_isogram(cadena1):\n        print(f\"{cadena1} es isograma\")\n    else:\n        print(f\"{cadena1} NO es isograma\")\n    if is_isogram(cadena2):\n        print(f\"{cadena2} es isograma\")\n    else:\n        print(f\"{cadena2} NO es isograma\")\n\n    print(\"----------------------------------------\")\n    print(\"----------------------------------------\")\n\n\nchequear_palabras(\"amor\", \"roma\")\nchequear_palabras(\"neuquen\", \"quenneu\")\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/Lumanet.py",
    "content": "mi_cadena = \"Esto sería una cadena de caracteres\"\notra_cadena = \"Y esto es otra cadena de caracteres\"\n\nprint(mi_cadena + \" - \" + otra_cadena) # Concatenación -> Esto sería una cadena de caracteres - Y esto sería otra cadena de caracteres\n\nprint(mi_cadena*2) # Repetición -> Esto sería una cadena de caracteresEsto sería una cadena de caracteres\nprint(len(mi_cadena)) # Longitud -> 35\nprint(mi_cadena[0]) # Muestra el primer caracter -> E\nprint(mi_cadena[0:5]) # Muestra desde la posición 0 hasta la 5 -> Esto\nprint(mi_cadena[5:]) # Muestra desde la posición 5 hasta el final -> sería una cadena de caracteres\nprint(\"sería\" in mi_cadena) # Verificar si una cadena contiene sería -> True\nprint(\"uno\" in mi_cadena) # Verificar si una cadena contiene uno -> False\nprint(mi_cadena.replace(\"sería\", \"es\")) # Reemplazo de sería por es -> Esto es una cadena de caracteres\nprint(mi_cadena.split(\" \")) # División de cadena en lista -> ['Esto', 'sería', 'una', 'cadena', 'de', 'caracteres']\nprint(mi_cadena.upper()) # Mayúsculas -> ESTO SERÍA UNA CADENA DE CARACTERES\nprint(mi_cadena.lower()) # Minúsculas -> esto sería una cadena de caracteres\nprint(mi_cadena.title()) # Letras en mayúsculas -> Esto Sería Una Cadena De Caracteres\nprint(mi_cadena.capitalize()) # Capitalize -> Esto sería una cadena de caracteres\nprint(mi_cadena.strip()) # Eliminación de espacios al principio y al final\nprint(mi_cadena.startswith(\"Es\")) # Búsqueda al principio -> True\nprint(mi_cadena.endswith(\"res\")) # Búsqueda al final -> True\nprint(mi_cadena.find(\"sería\")) # Búsqueda de posición -> 5\nprint(mi_cadena.find(\"Sería\")) # Búsqueda de posición -> -1 (No encontrado)\nprint(mi_cadena.find(\"esto\")) # Búsqueda de posición -> -1 (No encontrado)\nprint(mi_cadena.lower().find(\"esto\")) # Búsqueda de posición -> 0\nprint(mi_cadena.count(\"e\")) # Búsqueda de ocurrencias -> 5\nprint(mi_cadena.count(\"s\")) # Búsqueda de ocurrencias -> 3\nprint(mi_cadena.isalnum()) # Verificar si la cadena es alfanumérica -> False\n\nnombre = \"Marcos\"\ndeporte = \"pádel\"\n\nprint(nombre.center(50)) # Centrado ->                      Marcos\n\n\nfor letra in nombre: # Iteración de la cadena nombre\n    print(letra) # Muestra cada letra en una línea\nfor letra in nombre: # Iteración de la cadena nombre\n    print(letra, end=\"\") # Muestra cada letra en la misma línea\nprint()\nfor letra in nombre: # Iteración de la cadena nombre\n    print(letra, end=\".\") # Muestra cada letra en la misma línea separada por un punto \nprint()\n\nprint(\"Hola {}, deporte: {}\".format(nombre, deporte)) # Formateo -> Hola Marcos, deporte: pádel\nprint(\"Hola {nombre}, deporte: {deporte}\".format(nombre=\"Juan\", deporte=\"fútbol\")) # Formateo -> Hola Juan, deporte: fútbol\nprint(f\"Hola {nombre}, deporte: {deporte}\") # Interpolación -> Hola Marcos, deporte: pádel  \nprint(list(nombre)) # Transformación en lista de caracteres -> ['M', 'a', 'r', 'c', 'o', 's']\nmi_join =[nombre, \" \", deporte, \"!\", \"!\", \"!\", \"!\", \"!\"]\nprint(\"\".join(mi_join)) # Transformación de lista en cadena -> Marcos pádel!!!!!\nmi_otro_join = \" - \"\nprint(mi_otro_join.join([\"1\",\"2\",\"3\"]))\n\n\"\"\"\nCrea un programa que analice dos palabras diferentes y realice comprobaciones\npara descubrir si son:\n- Palíndromos \n- Anagramas\n- Isogramas\n\"\"\"\ndef comprobar(palabra1: str, palabra2: str):\n\n    # PALÍNDROMOS (se lee igual de izquierda a derecha que de derecha a izquierda)\n    print(f\"¿{palabra1} es un palíndromo?: {palabra1 == palabra1[::-1]}\")\n    print(f\"¿{palabra2} es un palíndromo?: {palabra2 == palabra2[::-1]}\")\n\n    # ANAGRAMAS (palabras que tienen las mismas letras pero en distinto orden)\n    print(f\"¿{palabra1} es anagrama de {palabra2}?: {sorted(palabra1) == sorted(palabra2)}\")\n\n    # ISOGRAMAS (palabras que no tienen letras repetidas)\n    def isograma(palabra):\n\n        palabras_dict = dict() # Diccionario para almacenar las letras de la palabra\n        for caracter in palabra: # Iteración de la palabra\n            palabras_dict[caracter] = palabras_dict.get(caracter, 0) + 1 # Almacenamiento de las letras\n\n        isograma = True # Inicialización de la variable isograma\n        values = list(palabras_dict.values()) # Obtención de los valores del diccionario\n        isograma_len = values[0] # Obtención del primer valor\n        for word_count in values: # Iteración de los valores\n            if word_count != isograma_len: # Comparación de los valores\n                isograma = False\n                break\n\n        return isograma\n\n    print(f\"¿{palabra1} es un isograma?: {isograma(palabra1)}\")\n    print(f\"¿{palabra2} es un isograma?: {isograma(palabra2)}\")\n\n\ncomprobar(\"oso\", \"casa\")\ncomprobar(\"oso\", \"oso\")\ncomprobar(\"oso\", \"abcdefghijklmnopqrstuvwxyz\")\ncomprobar(\"radar\", \"roma\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/Maanghel.py",
    "content": "\"\"\"\nEJERCICIO:\nMuestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\nen tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n    - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n    conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n\nDIFICULTAD EXTRA (opcional):\nCrea un programa que analice dos palabras diferentes y realice comprobaciones\npara descubrir si son:\n    - Palíndromos\n    - Anagramas\n    - Isogramas\n\"\"\"\n\ntext1 = \"Github\"\ntext2 = \"Maanghel\"\ntexts = [\"Hola\", \"Python\"]\ntext3 = \"124123\"\ntext4 = \"Mañana sera un gran dia\"\n\n# Acceso a caracteres específicos\nprint(\"Acceso a caracteres específicos:\")\nprint(text1[0])\n\n# Acceso a subcadenas\nprint(\"\\nAcceso a subcadenas:\")\nprint(text1[0:3])\n\n# Longitud de la cadena\nprint(\"\\nLongitud de la cadena:\")\nprint(len(text1))\n\n# Concatenacion de cadenas\nprint(\"\\nConcatenacion de cadenas:\")\nprint(text1 + \" \" + text2)\n\n# Repeticion de cadenas\nprint(\"\\nRepetición de cadenas:\")\nprint(text2 * 5)\n\n# Recorrido de cadenas\nprint(\"\\nRecorrido de cadenas:\")\nfor letra in text2:\n    print(letra, end=\"\")\n\n# Conversion a mayúsculas\nprint(\"\\n\\nConversión a mayúsculas:\")\nprint(text1.upper())\n\n# Conversión a minúsculas\nprint(\"\\nConversión a minúsculas:\")\nprint(text2.lower())\n\n# Reemplazo de caracteres en python\nprint(\"\\nReemplazo de caracteres:\")\nprint(text2.replace(\"a\", \"A\"))\n\n# División de cadenas\nprint(\"\\nDivisión de cadenas:\")\nprint(text1.split(\"t\"))\n\n# Union de cadenas\nprint(\"\\nUnión de cadenas:\")\nprint(\" \".join(texts))\n\n# Interpolación de cadenas\nprint(\"\\nInterpolación de cadenas:\")\nprint(f\"Mi {text1} es {text2}\")\n\n# Verificación\nprint(\"\\nVerificacion en cadenas:\")\nprint(\"a\" in text2)\n\n# Comprobaciones\nprint(\"\\nComprobaciones varias:\")\nprint(text3.isalnum())\nprint(text1.isalpha())\nprint(text3.isalpha())\n\n# Eliminacion de espacios al inicio y final\nprint(\"\\nEliminación de espacios al inicio y al final:\")\nprint(text1.strip())\n\n# Convertir la cadena en una lista\nprint(\"\\nConvertir la cadena en una lista:\")\nprint(text4.split(\" \"))\n\n# EXTRA\n\ndef verificar_palindromo(palabra1: str, palabra2: str) -> bool:\n    \"\"\"Verifica si las dos palabras son palindromas\"\"\"\n    return palabra1[::-1].lower() == palabra2.lower()\n\ndef verificar_anagrama(palabra1: str, palabra2: str) -> bool:\n    \"\"\"Verifica si las dos palabras son anagramas\"\"\"\n    return sorted(palabra1.lower()) == sorted(palabra2.lower())\n\ndef verificar_isograma(palabra: str) -> bool:\n    \"\"\"Verifica si la palabra es un isograma\"\"\"\n    return len(set(palabra.lower())) == len(palabra.lower())\n\nprint(verificar_palindromo(\"Ana\", \"ana\"))\nprint(verificar_palindromo(\"Roberto\", \"Ana\"))\n\nprint(verificar_anagrama(\"Amor\", \"Roma\"))\nprint(verificar_anagrama(\"Hola\", \"Python\"))\n\nprint(verificar_isograma(\"Hola\"))\nprint(verificar_isograma(\"mañana\"))\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/MarcosE-FerretoE.py",
    "content": "\"\"\"EJERCICIO\"\"\"\n\n# Acceso a caracteres específicos\ncadena = \"Hola Python\"\nprint(cadena[0])\nprint(cadena[-1])\n\n\n# Sub cadenas\ncadena = \"Hola Java\"\nprint(cadena[0:4])\nprint(cadena[5:])\n\n\n# Longitud\ncadena = \"Hola C\"\nprint(len(cadena))\n\n\n# Concatenación\ncadena1 = \"Hola\"\ncadena2 = \"Mundo\"\nconcatenada = cadena1 + \" \" + cadena2\nprint(concatenada)\n\n\n# Repetición\ncadena = \"Hola\"\nrepetida = cadena * 3\nprint(repetida)\n\n\n# Recorrido\ncadena = \"Hola Kotlin\"\nfor caracter in cadena:\n    print(caracter)\n\n\n# Conversión a mayúsculas y minúsculas\ncadena = \"Hola Dart\"\nmayusculas = cadena.upper()\nminusculas = cadena.lower()\nprint(mayusculas)\nprint(minusculas)\nprint(\"hola python\".title())\nprint(\"hola python\".capitalize())\n\n\n# Reemplazo\ncadena = \"Hola JavaScript\"\nreemplazo = cadena.replace(\"JavaScript\", \"TypeScript\")\nprint(reemplazo)\n\n\n# División (split)\ncadena = \"Hola,Python,Java,C\"\ndivision = cadena.split(\",\")\nprint(division)\n\n\n# Unión (join)\nunion = \",\".join(division)\nprint(union)\n\n\n# Interpolación\nnombre = \"Marcos\"\nedad = 17\nprint(f\"Hola, me llamo {nombre} y tengo {edad} años.\")\n\n\n# Verificación\ncadena = \"Hola Python\"\nif \"Hola\" in cadena:\n    print(\"¡Hola está en la cadena!\")\n\n\n\"\"\"\nDIFICULTAD EXTRA\n\"\"\"\n\nprint(\"\\n\")\n\n\ndef palindromos(palabra1: str, palabra2: str):\n    palabra1 = palabra1.lower()\n    palabra2 = palabra2.lower()\n    print(f\"{palabra1} es un palíndromo?: {palabra1 == palabra1[::-1]}\")\n    print(f\"{palabra2} es un palíndromo?: {palabra2 == palabra2[::-1]}\")\n\n\ndef anagramas(palabra1: str, palabra2: str):\n    palabra1 = palabra1.lower()\n    palabra2 = palabra2.lower()\n    print(\n        f\"{palabra1} es anagrama de {palabra2}? {sorted(palabra1) == sorted(palabra2)}\"\n    )\n\n\ndef isogramas(palabra1: str, palabra2: str):\n    palabra1 = palabra1.lower()\n    palabra2 = palabra2.lower()\n    print(f\"{palabra1} es isograma?: {len(palabra1) == len(set(palabra1))}\")\n    print(f\"{palabra2} es isograma?: {len(palabra2) == len(set(palabra2))}\")\n\n\ndef main():\n    palabra1 = input(\"Ingrese la primer palabra: \")\n    palabra2 = input(\"Ingrese la segundas palabra:\")\n    palindromos(palabra1, palabra2)\n    anagramas(palabra1, palabra2)\n    isogramas(palabra1, palabra2)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/MiguelAngelEc.py",
    "content": "### OPERACIONES\n\nfrom ast import If, IfExp\nfrom socket import if_indextoname\nimport string\n\n\nt1 = \"Hola\"\nt2 = \"Miguel Angel\"\nt3 = \"Python\"\nt4 = \"1234\"\n\n#Concatenación\nsaludo = t1 + \", \" + t2\nprint(saludo)\n\n#Repetición\nprint(saludo * 3)\n\n#Indexación\nprint(saludo[1])\n\n#Longitud\nprint(len(saludo))\n\n#Slicing\nprint(t2[0:5])\nprint(t2[0:])\nprint(t2[:-1])\n\n#Busqueda\nprint(\"a\" in saludo)\nprint(\"i\" in saludo)\n\n#Reemplazo\nprint(saludo.replace(\"l\", \"\"))\n\n#Division\nsplit1 = saludo.split(\" \")\nfor i in range(len(split1)):\n    print(split1[i])\n\n#Mayuscuals y Minisculas\nprint(saludo.upper())\nprint(saludo.lower())\nprint(\"miguel angel castillo enriquez\".title())\nprint(\"miguel angel castillo enriquez\".capitalize())\n\n#Eliminacion de espacios\nprint(\" Miguel Angel \".strip())\nprint(\" Miguel Angel \".lstrip())\nprint(\" Miguel Angel \".rstrip())\n\n#Busqueda al inicio y al final\nprint(saludo.startswith(\"Hola\"))\nprint(saludo.endswith(\"Miguel\"))\n\n#Busqueda de posicion\nprint(saludo.find(\"Miguel\"))\nprint(saludo.find(\"Angel\"))\nprint(saludo.find(\"Hola\"))\n\n#Busqueda de ocurrencia\nprint(saludo.count(\"l\"))\n\n#Formateo\nprint(\"Saludo: {}, Lenguaje: {}!\".format(saludo, t3))\n\n#Interpolación\nprint(f\"Saludo: {saludo}, Lenguaje: {t3}!\")\n\n#Transformación en lista de caracteres\nprint(list(t1))\n\n#Transformación de lista en cadena\nprint(\"\".join(list(saludo)))\n\n#Transformaciones numéricas\nprint(t4.isnumeric())\nprint(t1.isnumeric())\nprint(int(t4))\nprint(float(t4))\n\n# Comprobaciones\nprint(t1.isalnum())\nprint(t1.isalpha())\nprint(t1.islower())\nprint(t1.isdecimal())\n\n\n\"\"\"\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n*/\n\"\"\"\n\ndef check(word1: string, word2: string):\n   #Palindormos\n   if word1 == word1[::-1]:\n      print(f\"La palabra {word1} es un palíndromo\")\n   else:\n      print(f\"La palabra {word1} no es un palíndromo\")\n\n   #Anagramas\n   if sorted(word1) == sorted(word2):\n      print(f\"La palabra {word1} es un anagrama de {word2}\")\n   else:\n      print(f\"La palabra {word1} no es un anagrama de {word2}\")\n\n   #Isogramas\n   if len(word1) == len(set(word1)):\n      print(f\"La palabra {word1} es un isograma\")\n   else:\n      print(f\"La palabra {word1} no es un isograma\")\n\ncheck(\"radar\", \"python\")\ncheck(\"amor\", \"roma\")\ncheck(\"python\", \"python\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/MirandaYuber.py",
    "content": "from builtins import list\n\nprint('#####  CADENAS DE CARACTERES #####')\n\nstring = 'Programa en python'\nprint(str(reversed(string)))\n\nprint(f\"Concatenación: {'Hola ' + string}\")\n\nprint(f'Multiplicación: {3 * string}')\n\nprint(f\"Indexación: {string[0] + string[1] + string[2]}\")\n\nprint(f'Longitud de un string: {len(string)}')\n\nprint(f'Subcadena con los 3 primeros caracteres de la cadena \"{string}\": {string[0:3:1]}')  # [Inicio: Fin: paso]\nprint(f'Subcadena del 2do caracter al ultimo de la cadena \"{string}\": {string[1:]}')  # [Inicio: Fin: paso]\n\nprint(f\"Buscador: {'Python' in string}\")\n\nprint(f\"Reemplaza la 'e' de la cadena '{string}' por la 'E': {string.replace('e', 'E')}\")\n\nprint(f\"Dividir cadena: {string.split(' ')}\")\n\nprint(f'Pasamos a mayusculas la cadena \"{string}\": {string.upper()}')\n\nprint(f'Pasamos a minusculas la cadena \"{string}\": {string.lower()}')\n\nprint(f'Pasamos a notación de titulo la cadena \"{string}\": {string.title()}')\n\nprint(f\"Capitalizar la cadena 'yuber Miranda': {'yuber Miranda'.capitalize()}\")\n\nnew_string = '      Hola Python      '\n\nprint(f'Elimina los espacios vacios al inicio de la cadena \"{new_string}\": {new_string.lstrip()}')\n\nprint(f'Elimina los espacios vacios al final de la cadena \"{new_string}\": {new_string.rstrip()}')\n\nprint(f'Elimina todos los espacios vacios de la cadena \"{new_string}\": {new_string.strip()}')\n\nprint(f'Recorrer caracteres de la cadena \"{string}\":')\nfor caracter in string:\n    print(caracter)\n\nprint(f\"Buscar al principio de la cadena: {string.startswith('Pro')} || {string.startswith('Py')}\")\n\nprint(f\"Buscar al final de la cadena: {string.endswith('thon')} || {string.endswith('ma')}\")\n\nprint(f\"Buscar posición: {string.find('en')} || {string.lower().find('En')}\")  # -1 es cuando no es encontrado\n\nprint(f\"Buscar concurrencias: {string.lower().count('o')}\")\n\nprint(\"Formateo: String1 = {}, string2 = {}\".format(string, new_string))\n\nprint(f\"Interpolación: String1 = {string}, string2 = {new_string}\")\n\nlist_characters = list(string)\nprint(f\"Transforma string en lista: {list_characters}\")\n\nprint(f\"Transforma lista en string: {''.join(list_characters)}\")\n\nprint(f\"Transforma string a enteros: {type(int('12345'))}\")\n\nprint(f\"Transforma string a decimales: {type(float('12.4'))}\")\n\nprint(f\"Comprueba si es un número: {string.isalnum()}\")\nprint(f\"Comprueba si es un string: {string.isalpha()}\")\nprint(f\"Comprueba si es númerico: {string.isnumeric()}\")\n\naccess_first_character = string[0]\nprint(f'Acceder al primer caracter del string: {access_first_character}')\n\naccess_last_character = string[-1]\nprint(f'Acceder al ultimo caracter de la string: {access_last_character}')\n\n\nprint('#####  EXTRA  #####')\n\nprint(\"Programa para analizar dos palabras diferentes y comprobar si son palindromas, anagramas o isogramas.\")\nfirst_string = str(input('Digite la primera palabra: '))\nsecond_string = str(input('Digite la segunda palabra: '))\n\nwhile first_string == second_string:\n    print('Las palabras deben ser diferentes.')\n    first_string = str(input('Digite la primera palabra: '))\n    second_string = str(input('Digite la segunda palabra: '))\n\n\ndef check(word1: str, word2: str):\n    # Palindromos\n    print(f\"¿La palabra {word1} es palindroma?: {word1 == word1[::-1]}\")\n\n    print(f\"¿La palabra {word2} es palindroma?: {word2 == word2[::-1]}\")\n\n    # Anagramas\n    print(f\"¿La palabra {word1} es anagrama de la palabra {word2}?: {sorted(word1) == sorted(word2)}\")\n\n    # Isogramas\n    def isogram(word: str) -> bool:\n\n        word_dict = dict()\n        for character in word:\n            word_dict[character] = word_dict.get(character, 0) + 1\n\n        isogram = True\n        values = list(word_dict.values())\n        print(f\"prueba: {values}\")\n        isogram_len = values[0]\n        for word_count in values:\n            if word_count != isogram_len:\n                isogram = False\n                break\n\n        return isogram\n\n    print(f\"¿{word1} es un isograma?: {isogram(word1)}\")\n    print(f\"¿{word2} es un isograma?: {isogram(word2)}\")\n\n\ncheck(first_string, second_string)\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/NeosV.py",
    "content": "Ej_1 = [\"Thirty\",\"Days\",\"Of\",\"Python\"]\njoin_1 = \" \".join(Ej_1)\nprint(join_1)\n\nEj_2 = [\"Coding\",\"For\",\"All\"]\njoin_2 = \" \".join(Ej_2)\nprint (join_2)\n\ncompany = \"Coding For All\"\nprint (company)\nprint (len(company))\nprint (company.upper())\nprint (company.lower())\nprint (company.capitalize())\nprint (company.title())\nprint (company.swapcase())\nprint (company[6:])\nprint (company.find(\"Coding\"))\nprint (company.replace ('Coding', 'Python'))\nprint (company.split())\n\nvariable = \"Facebook, Google, Microsoft, Apple, IBM, Oracle, Amazon\"\n\nprint (variable.splitlines())\n\nprint (company[0])\nprint (company[-1])\nprint (company[10])\n\na, b ,c = company [0], company[7], company[11]\nprint (a,b,c) \n\ncompany_2 = \"Python For All\"\n\nd, e ,f = company_2 [0], company_2[7], company_2[11]\nprint( d, e ,f)\n\nprint (company.find('C'))\nprint (company.find('f'))\n\ncompany_3 = \"Coding For All People\"\n\nprint (company_3.rfind('p'))\n\ncompany_4 = \"You cannot end a sentence with because because because is a conjunction\"\n\nprint (company_4.find('because'))\nprint (company_4.rfind('because'))\nprint (company_4 [31:54])\n\nprint (company.startswith('Coding'))\nprint (company.endswith('coding'))\n\nvariable_a = \"30DaysOfPython\"\nvariable_b = \"thirty_days_of_python\"\n\nprint (variable_a.isidentifier())\nprint (variable_b.isidentifier())\n\nprint('I am enjoying this challenge.\\nI just wonder what is next. ?')\n\nprint( \"Name\\tAge\\tCountry\\t        City \")\nprint( \"Andres\\t22\\tColombia\\tBogota\")\n\nprint (\"radius = 10 \\narea = 3.14 * radius ** 2 \\nThe area of a circle with radius 10 is 314 meters square\")\n\nprint (\"8 + 6 = 14 \\n8 - 6 = 2 \\n8 * 6 = 48 \\n8 / 6 = 1.33 \\n8 % 6 = 2 \\n8 // 6 = 1 \\n8 ** 6 = 262144\")\n\n    \n\n\n# Ejercicio Extra\n\ndef comprobador(palabra_1:str , palabra_2 : str):\n   \n   \n   print (f\"la palabra {palabra_1} es un palindromo? {palabra_1 == palabra_1[::-1]}\")\n   print (f\"la palabra {palabra_2} es un palindromo? {palabra_2 == palabra_2[::-1]}\")\n\n   print (f\"las palabras {palabra_1} y {palabra_2} son anagramas?: {sorted(palabra_2) == sorted(palabra_2)}\")\n\n   dictio = dict()\n   for i in palabra_1:\n      dictio [i] = dictio.get(i, 0)+1\n\n      isograma = True\n      valores = list(dictio.values())\n      Isograma_len = valores[0]\n      for i in valores:\n         if i != Isograma_len:\n            isograma = False\n            break\n   print (f\"{palabra_2} es un Isograma? {len(palabra_2) == len(set(palabra_2))}\") \n\n \n\n\n\n\n   \ncomprobador(\"amor\" , \"rada\")\n\n\n      \n        "
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/NicoHeguaburu.py",
    "content": "\"\"\"\nOperaciones\n\"\"\"\n\nstring1 = \"Hola\"\nstring2 = \"Python\"\n\n\n#Concatenacion\nprint(string1 + \" \" + string2 + \"!\")\n\n#Repeticion \nprint(string1 * 3)\n\n#Indexacion\nprint(string1[0] + string1[1] + string1[2] + string1[3])\n\n#longitud\nprint(len(string1))\n\n#slicing (porcion)\nprint(string2[2:6])\nprint(string2[2:])\n\n#Busqueda\nprint(\"Ho\" in string1)\n\n#Remplazo\nprint(string1.replace(\"o\",\"a\"))\n\n#Division\nprint(string2.split(\"t\"))\n\n#Mayusculas y minusculas\nprint(string1.upper())\nprint(string1.lower())\nprint(\"hola a todos\".title())\nprint(\"hola a todos\".capitalize())\n\n#Eliminacion de espacios\nprint(\"   Hola python    \".strip())\n\n#Busqueda al principio y al final\nprint(string1.startswith(\"Ho\"))\nprint(string1.startswith(\"Py\"))\nprint(string1.endswith(\"Ho\"))\nprint(string1.endswith(\"Ho\"))\n\n#Busqueda de posicion\nprint(\"Hola como estan todos?\".find(\"estan\"))\n\n#Busqueda de ocurrencias\nprint(string1.lower().count(\"o\"))\n\n#Formateo de cadena\nprint(\"Saludo: {}, lenguaje: {}!\".format(string1, string2))\n\n#Interpolacion\nprint(f\"Saludo: {string1}, lenguaje: {string2}!\")\n\n#Transformacion en lista\nprint(list(string1))\n\n#Transformacion en string\nlista1 = [\"h\",\"o\",\"l\",\"a\"]\nprint(\"\".join(lista1))\n\n#transformaciones numericas\nstring3 = 123456789\nstring3 = int(string3)  #ENTERO\nprint(type(string3))  \nstring3 = float(string3)  #DECIMAL\nprint(type(string3)) \n\n#Comprobaciones varias\nprint(string1.isalnum())\nprint(string1.isalpha())\nprint(string1.isnumeric())\n\n\n\n#DIFICULTAD EXTRA\n\n\ndef texto_palindromo():\n\n    print(\"elija su palabra a comprobar\")\n    texto = input(\"\")\n\n    texto_dividio_1 = []\n    texto_dividio_2 = []\n\n    if len(texto) % 2 == 0:\n        for i in range(len(texto) // 2):\n            letra = texto[i]\n            texto_dividio_1.append(letra)\n\n        for i in range(len(texto) -1, len(texto) // 2 -1, -1):\n            letra = texto[i]\n            texto_dividio_2.append(letra)\n            \n    else:\n        for i in range(len(texto) // 2):\n            letra = texto[i]\n            texto_dividio_1.append(letra)\n\n        for i in range(len(texto) -1, len(texto) // 2 , -1):\n            letra = texto[i]\n            texto_dividio_2.append(letra)\n            \n    if  texto_dividio_1 == texto_dividio_2:\n        print(\"su texto es palindromo\")\n    else:\n        print(\"su texto no es palindromo\")\n\n\n\ndef texto_anagrama():\n    print(\"elije tu palabra numero 1\")\n    palabra1 = input()\n    lista_palabra1 = list(palabra1)\n    lista_palabra1.sort()\n    \n    print(\"elije tu palabra numero 2\")\n    palabra2 = input()\n    lista_palabra2 = list(palabra2)\n    lista_palabra2.sort()\n    \n    if lista_palabra1 == lista_palabra2:\n        print(\"TU PALABRA ES UN ANAGRAMAA!!!!\")\n    else:\n        print(\"TU PALABRA NO ES UN ANAGRAMA :(\")\n\n\n\n\n\n\ndef texto_isograma():\n    print(\"elije tu palabra para ver si es un isograma\")\n    palabra = input()\n    conteo = {}\n\n    for letra in palabra:\n        if letra in conteo:\n            conteo[letra] += 1\n        else:\n            conteo[letra] = 1\n\n    apariciones_iniciales = next(iter(conteo.values()))\n    valores = list(conteo.values())\n    \n    def fun():\n        for i in valores:\n            if apariciones_iniciales != i:\n                return False\n        return True\n    \n    fun()\n    resultado = fun()\n    \n\n    if resultado == True:\n        print(\"es un isograma\")\n    else:\n        print(\"no es un isograma\")\n    \ndef menu():\n    print(\"1----------palindromos\")\n    print(\"2----------anagrama\")\n    print(\"3----------isograma\")\n    print(\"4----------salir\")\n\n\n    opcion = input()\n    \n\n    if opcion == \"1\":\n        texto_palindromo()\n        menu()\n    elif opcion == \"2\":\n        texto_anagrama()\n        menu()\n    elif opcion == \"3\":\n        texto_isograma()\n        menu()\n    elif opcion == \"4\":\n        exit()        \n    else:\n        menu()\n\n\n\nmenu()\n\n\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/Nicojsuarez2.py",
    "content": "'''\n# #04 CADENAS DE CARACTERES\n> #### Dificultad: Media | Publicación: 22/01/24 | Corrección: 29/01/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n'''"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/NightAlchemist.py",
    "content": "#Operations on strings\n\nstring1 = \"This is my year!\"\nstring2 = \"I will make it count!\"\n\n#Concatenation\n\nstring3 = string1 + \" \" + string2\nprint(string3)  #This is my year! I will make it count!\n\n#Repetition\n\nstring4 = string1 * 3\nprint(string4)  #This is my year!This is my year!This is my year!\n\n#Indexing\n\nprint(string1[0])  #T\nprint(string1[5])  #i\nprint(string1[-3]) #a\n\n#Slicing\n\nprint(string1[0:4])  #This\nprint(string1[5:])   #is my year!\nprint(string1[:4])   #This\nprint(string1[:])    #This is my year!\nprint(string1[0:10:2])  #Ti sm\n\n#Membership\n\nprint(\"year\" in string1)  #True\nprint(\"year\" not in string1)  #False\n\n#Built-in functions\n\nprint(len(string1))  #15\nprint(min(string1))  \nprint(max(string1))\nprint(string1.index(\"i\"))  #2\nprint(string1.count(\"i\"))  #2\n\n#String methods\n\nprint(string1.lower())  #this is my year!\nprint(string1.upper())  #THIS IS MY YEAR!\nprint(string1.title())  #This Is My Year!\nprint(string1.capitalize())  #This is my year!\nprint(string1.swapcase())  #tHIS IS MY YEAR!\nprint(string1.center(30))  #   This is my year!\nprint(string1.find(\"is\"))  #2\nprint(string1.replace(\"is\", \"was\"))  #Thwas was my year!\nprint(string1.split())  #['This', 'is', 'my', 'year!']\nprint(string1.split(\"i\"))  #['Th', 's ', 's my year!']\nprint(string1.strip())  #This is my year!\nprint(string1.lstrip())  #This is my year!\nprint(string1.rstrip())  #This is my year!\nprint(string1.startswith(\"This\"))  #True\nprint(string1.endswith(\"year!\"))  #True\nprint(string1.isalnum())  #False\nprint(string1.isalpha())  #False\nprint(string1.isdigit())  #False\nprint(string1.islower())  #False\nprint(string1.isupper())  #False\nprint(string1.istitle())  #False\n\n#String formatting\n\nname = \"John\"\nage = 25\n\nprint(\"My name is %s and I am %d years old.\" % (name, age))  #My name is John and I am 25 years old.\nprint(\"My name is {} and I am {} years old.\".format(name, age))  #My name is John and I am 25 years old.    \nprint(f\"My name is {name} and I am {age} years old.\")  #My name is John and I am 25 years old.\n\n#Escape characters\n\nprint(\"This is a backslash: \\\\\")  #This is a backslash: \\\nprint(\"This is a tab: \\t\")  #This is a tab:\nprint(\"This is a newline: \\n\")  #This is a newline:\n\n#Raw strings\n\nprint(r\"This is a raw string: \\n\")  #This is a raw string: \\n\nprint(\"This is a raw string: \\\\n\")  #This is a raw string: \\n\n\n\n#Extra\n\nfirst_word = input(\"Give me a word: \").strip()\nprint(f\"Your first word is {first_word}\")\nsecond_word = input(\"Give me another word: \").strip()\nprint(f\"Your second word is {second_word}\")\n\ndef analize(word1, word2): #palindrome, anagram or isogram?\n    #palindromes\n    reversed_word1 = word1[::-1]\n    reversed_word2 = word2[::-1]\n    \n    if word1 == reversed_word1:\n        print(\"The first word is a palindrome\")\n    else:\n        print(\"The first word is not a palindrome\")\n    \n    if word2 == reversed_word2:\n        print(\"The second word is a palindrome\")\n    else:\n        print(\"The second word is not a palindrome\")\n        \n    #anagrams\n    \n    if len(word1) == len(word2) and sorted(word1) == sorted(word2):\n        print(\"These words are anagrams\")\n    else:\n        print(\"These words are not anagrams\")\n    \n    #isograms\n    def isogram(word):\n        used_characters = set()\n        for character in (word):\n            if character in used_characters:\n                return False\n            else:\n                used_characters.add(character)\n        \n        return True\n\n    if isogram(word1):\n        print(\"The first word is an Isogram\")\n    else:\n        print(\"The first word is not an Isogram\")\n        \n    if isogram(word2):\n        print(\"The second word is an Isogram\")\n    else:\n        print(\"The second word is not an Isogram\")\n\nanalize(first_word, second_word)"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/Nightblockchain30.py",
    "content": "'''\nEJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n'''\n\nmy_string = \"  I wanna be a full stack developer  \"\n\n# Acceso al caracter en el indice 2:\nprint(my_string[2])\n# Subcadena\nsub_string = my_string[2:9]\nprint(sub_string)\n# Longitud\nprint(len(my_string))\n# Concatenación\nstring_result = my_string + sub_string\nprint(string_result)\n# Búsqueda de ocurrencias\n## Dime cuantas veces se repite el caracter \"a\" dentro del string sin usar ningún método\ncharacter = \"a\"\nnum = 0\nfor i in my_string:\n    if character == i:\n        num += 1\nprint(f\"En nuestro string [{character}] aparece un total de: {num} veces\")\n\n## Ahora puedes usar métodos\nprint(my_string.count(\"a\"))\n# Conversión\nstring_upper = my_string.upper()\nprint(string_upper)\n# Reemplazo\nprint(my_string.replace(\"a\",\"A\"))\n# Multiplicación de caracteres\nprint(my_string[2].upper() * 3)\n#División\nprint(my_string.split())\n# Eliminación de espacios al principio y al final\nprint(my_string.strip())\n# Búsqueda al principio y al final\nprint(my_string.startswith(\"  I\"))\nprint(my_string.endswith(\"  \"))\n# Búsqueda de posición\nprint(my_string.find(\"w\"))\n# Formateo \nprint(\"{} --> era mi string inicial. {} \\n --> es mi string concatenado\".format(my_string.strip(),string_result.strip()))\n# Interpolación\nprint(f\"En nuestro string [{character}] aparece un total de: {num} veces\")\n# Cambio de dato a lista\nmy_list = list(my_string)\nprint(my_list)\n# Comprobaciones varias\ns4 = \"123456\"\nprint(s4.isalnum())\nprint(s4.isalpha())\nprint(s4.isnumeric())\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n\"\"\"\n\ndef son_palindromos(str1:str,str2:str)->bool:\n    print(f\"¿Es {str1} palindroma con ella misma? {str1 == str1[::-1]}\")\n    print(f\"¿Es {str2} palindroma con ella misma? {str2 == str2[::-1]}\")\n    return\n\n\ndef son_anagramas(str1:str,str2:str)->bool:\n    print(f\"Es {str1} anagrama de {str2}: {sorted(str1) == sorted(str2)}\")\n\n\ndef son_isogramas(str1:str,str2:str):\n        \n    def isogram(word:str)->bool:\n        # Creo un diccionario vacío para ir agregando el número de veces que se repite cada letra de la palabra\n        world_dict= dict() \n        # Recorro cada letra de la palabra\n        for letra in word:\n            # Agrego al diccionario el total de repeticiones teniendo por defect el valor igual a 0\n            world_dict[letra] = world_dict.get(letra,0) + 1\n        \n        isIsogram = True\n        list_values = list(world_dict.values()) # Para trabajar con los indices me quedo con una lista SOLO con los valores del diccionario\n        longitud_de_isogram = list_values[0]    # Calculo la longitud de cualquiera de los valores\n                                                # Sabemos que para ser isograma todas las letras se tienen que repetir el mismo número de veces\n        # Ahora voy a recorrer la lista de el número de repeticiones\n        for count_word in list_values:\n            if count_word != longitud_de_isogram:\n                isIsogram = False\n                break\n        return isIsogram\n    \n\n    print(f\"Es {str1} un isograma?: {isogram(str1)}\")\n    print(f\"Es {str2} un isograma?: {isogram(str2)}\")\n\n\n# Ejemplos! \nson_palindromos(\"pera\",\"radar\")\nson_anagramas(\"roma\",\"amor\")\nson_isogramas(\"pera\",\"radarmou\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/NoMeLlamoDante.py",
    "content": "\"\"\"\n#! EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n\"\"\"\ntexto = \"hola, me dicen Dante\"\ntexto_completo = \"hola, me dicen Dante\\ty soy un programador\"\nnumeros = \"1234567890\"\nprint(texto)\n\n#! Convierte caracteres\nprint(texto.capitalize()) #Primero mayuscula, resto minusculas\nprint(texto.casefold()) #Convierte a minusculas\nprint(texto.lower()) #Convierte a minusculas\nprint(texto.swapcase()) #Invierte mayusculas y minusculas\nprint(texto.title()) #Convierte a titulo (primera letra de cada palabra en mayuscula)\nprint(texto.upper()) #Convierte a mayusculas\n\n#! Elimina los espacios en blanco \nprint(texto.lstrip()) #A la izquierda\nprint(texto.strip()) #A ambos lados\nprint(texto.rstrip()) #Elimina los espacios en blanco a la derecha\n\n#! Verifica si todos los caracteres coinciden con un criterio\nprint(texto.isalnum()) #Alfanumerico\nprint(texto.isalpha()) #Alfabetico\nprint(texto.isascii()) #ASCII\n\nprint(numeros.isdecimal()) #Decimal\nprint(numeros.isdigit()) #Digito\nprint(numeros.isnumeric()) #Numerico\n\nprint(texto.islower()) #Minusculas\nprint(texto.isupper()) #mayusculas\n\nprint(texto.isidentifier()) #Identificador\nprint(texto.isprintable()) #Imprimible\nprint(texto.isspace()) #Espacios\nprint(texto.istitle()) #Titulo (Primera letra de cada palabra en mayuscula)\n\n#! Justifica Caracteres de acuerdo a un ancho especificado\nprint(texto.ljust(50)) #Justificado a la izquierda\nprint(texto.center(50)) #Al centro\nprint(texto.rjust(50)) #Justificado a la derecha\n\n#! Buscar dentro de la cadena\n#Cuenta cuantas veces aparece una subcadena, con un origen dado\nprint(texto.count(\" \", 8)) \n#Verifica si la cadena termina con una subcadena\nprint(texto_completo.endswith(\"programador\")) \n#Verifica si la cadena comienza con una subcadena\nprint(texto_completo.startswith(\"hola\"))\n#Devuelve la posicion de la primera ocurrencia de una subcadena\nprint(texto_completo.find(\"pr\"))\n#Devuelve la posicion de la ultima ocurrencia de una subcadena\nprint(texto_completo.rfind(\"pr\")) \n#Devuelve la posicion de la primera ocurrencia de una subcadena\nprint(texto.index(\"Dante\")) \n#Devuelve la posicion de la ultima ocurrencia de una subcadena\nprint(texto_completo.rindex(\"Dante\")) \n\n#! Cambia el valor de las tabulaciones por el numero especificado de espacios\nprint(texto_completo.expandtabs(2))\n\n#! Formatea la cadena con los valores especificados\ntexto2 = \"Estoy practicando {lenguaje} con los ejercicios prácticos de {autor}\"\nprint(texto2.format(lenguaje=\"Python\", autor=\"Mouredev\"))\n\nprint(f\"el texto de ejemplo es: \\\" {texto} \\\"\")\n\nprint(texto2.format_map({\n            \"lenguaje\":\"Python\",\n            \"autor\":\"Mouredev\"\n        })\n    )\n\nprint(texto.zfill(50)) #Rellena con ceros a la izquierda\n\n#! Cadenas y subcadenas\n#Une una lista de cadenas con un separador\nprint(\"-\".join([\"hola\", \"mundo\", \"python\"])) \n#Divide la cadena en una tupla con tres elementos con el separador especificado\nprint(texto_completo.partition(\"Dante\")) \n#Divide la cadena en una tupla con tres elementos con el separador especificado\nprint(texto_completo.rpartition(\"Dante\")) \n#Reemplaza una subcadena dentro del texto\nprint(texto.replace(\"Dante\", \"Mouredev\"))\n#Divide la cadena en una lista de subcadenas con el separador especificado\nprint(texto.split(\" \")) \n#Divide la cadena en una lista de subcadenas con el separador especificado\nprint(texto.rsplit(\" \")) \n#Divide la cadena en una lista de subcadenas con el separador especificado\nprint(texto.split(\" \")) \n#Divide la cadena en una lista de subcadenas con el separador de salto de linea\nprint(texto.splitlines()) \n\n#! Permite tablas de reemplazo de caracteres\ntexto_ejemplo = \"tata\"\ntabla_conversion = str.maketrans(\"t\", \"p\")\nprint(texto_ejemplo.translate(tabla_conversion))\n\n\"\"\"\n#! DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n\"\"\"\n#Todo Palíndromos\ndef es_palindromo(text, ignore_spaces = True):\n    text = text.lower()\n    if ignore_spaces:\n        text = text.replace(\" \", \"\")\n    return text == reverse(text)\n\ndef reverse(text):\n    return text[::-1]\n\n\nprint(es_palindromo(\"lavanderia\"))\nprint(es_palindromo(\"eva usaba rimel y le miraba suave\"))\n\n#Todo Anagramas\ndef es_anagrama(text1, text2):\n    list1 = list(text1.lower())\n    list1.sort()\n    list2 = list(text2.lower())\n    list2.sort()\n    return list1 == list2\n\nprint(es_anagrama(\"rosa\", \"arroz\"))\nprint(es_anagrama(\"roma\", \"amor\"))\n\n#Todo Isogramas (Todas las letras se repiten el mismo numero de veces)\ndef contador_caracteres(text:str):\n    text = text.lower()\n    if text.isalpha():\n        caracteres = {}\n        for char in text:\n            if char in caracteres.keys():\n                caracteres[char] += 1\n            else:\n                caracteres[char] = 1\n        return caracteres\n    return False\n\ndef es_isograma(text:str):\n    caracteres = contador_caracteres(text)\n    num_caracteres = list(caracteres.values())\n    return num_caracteres.count(num_caracteres[0]) == len(num_caracteres)\n    \nprint(es_isograma(\"intestines\"))\nprint(es_isograma(\"Vivienne\"))\nprint(es_isograma(\"alondra\"))"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/Paprikaistkrieg.py",
    "content": "\n#Cadenas de caracteres\n\n #operaciones\n\n\n\n\n\ncadena1 = \"hello\"\ncadena2 = \"world\"\ncadena4 = \"   H e l l o  \"\n\nfrom operator import gt\nfrom optparse import Values\nimport re\nfrom test.dis_module import f\nfrom test.test_operator import PyCOperatorPickleTestCase\n\n# Concatenación / Concatenation\n\ncadena3 = cadena1 + \" \" + cadena2 #los \"\" son importantes para mantener el espacio en esta concatenación\nprint(cadena3)\n\n\"\"\"\na una cadena de texto sumarle otra, sin mas xd\nJoins two strings into one.\n\"\"\"\n\n# Repetición / Repetition\n\nprint(cadena1 * 3)\n\n\"\"\"\nRepite la cadena un número determinado de veces con *.\nRepeats the string a specified number of times.\n\"\"\"\n\n# Acceso a caracteres / Indexación / Indexing\n\n\nprint(cadena1[0] + cadena1[1] + cadena1[2] + cadena1[3] + cadena1[4])\n\n\"\"\"Acceso a cada carácter de la cadena al índice correspondiente solo usando indexación [] \"\"\"\n\n# Acceso a caracteres inverso / Reverse Indexing\nultimo_caracter = cadena1[-1]\nprint(ultimo_caracter)\n\n\"\"\"Acceso al último carácter de la cadena\"\"\"\n\n\n# Longitud / Length\n\nprint(len(cadena1))\n\n\"\"\"len mide la longitud de la cadena\"\"\"\n\n\n# Slicing (porciones)\n\nslicing = cadena1[0:5]\nprint(slicing)\n\n\"\"\"\nSlicing básico / Basic Slicing\nExtrae una parte de la cadena.\ntambien conlleva un concepto de inicio, fin y paso.\ndonde  \n#Índice o inicio\nEs donde comienza el corte (incluido). Se refiere a que incluye el carácter en esa posición, si se omite se asume que es 0.\n\nFin Índice donde termina el corte (excluido). Se refiere a que no incluye el carácter en esa posición, si se omite se asume que es el final de la cadena.\n\npaso Índice que determina el salto entre cada elemento, si se omite se asume que es 1. si usas paso negativo, recorres la secuencia en orden inverso. \n(se refiere a que el último carácter tiene índice -1)\n\nExtracts a part of the string.\nIt also involves a concept of start, end, and step.\nIndex where slicing starts (inclusive).\nEnd index where slicing ends (exclusive).\nStep index that determines the jump between each element.\n\n\"\"\"\n\n\n\n#busqueda de caracteres / Character Search\n\n\"\"\"se puede buscar si un carácter o subcadena está presente en la cadena solo con la palabra clave in (seguida de la variable o iterable)- \nDetalles importantes\n\n- Sensibilidad a mayúsculas/minúsculas: \"A\" no es igual a \"a\".\n- No da posición: Si necesitas saber dónde está el carácter, debes usar .find() o expresiones regulares.\n- Funciona con cualquier iterable: También puedes usarlo en listas, tuplas, sets, etc.\n\"\"\"\nprint(\"H\" in cadena1) #Devuelve false, ya que el carácter o subcadena no está presente en la cadena.\nprint(\"h\" in cadena1) #Devuelve true, ya que el carácter o subcadena está presente en la cadena.\nprint(\"hell\" in cadena1) #Devuelve true, ya que el carácter o subcadena está presente en la cadena.\n\n\n\"\"\"Busca una subcadena dentro de otra cadena y devuelve el número de posición (índice) donde aparece por primera vez.\nReturns the index of the first occurrence of a substring within another string.\n\"\"\"\n\n#remplazo / Replacement\nprint(cadena1.replace(\"h\", \"J\")) #Sustituye una subcadena por otra (Replace a substring with another)\nprint(cadena1.replace(\"l\", \"m\"))  #aqui la reemplazo en todas las apariciones ( Reemplazar múltiples veces / Replace multiple occurrences)\nprint(cadena1.replace(\"l\", \"m\", 1)) # Solo reemplaza las primeras n veces (Reemplazo limitado / Limited replacement)\nprint(cadena1.replace(\"hello\", \"see u\") + \" \" + cadena2.replace(\"world\", \"round\")) #Reemplazo encadenado / Chained replacement Puedes encadenar .replace() varias veces.\nif \"hello\" in cadena1 or \"world\" in cadena2: \n    print(cadena1.replace(\"hello\", \"see u\") + \" \" + cadena2.replace(\"world\", \"round\")) #Reemplazo condicional  (con lógica) / Conditional replacement Solo reemplaza si se cumple una condición.\n\nGt = \"Paprikaistkrieg\"\nsaludo = cadena1 + \" \" + cadena2\nsaludo = saludo.replace(cadena2, Gt)\nprint(saludo) # Reemplazo con variables / Replacement using variables Puedes usar variables para personalizar el reemplazo.\n\nlista = [\"toby\", \"wilson\", \"mango\"]\nlista1 = [michis.replace(\"toby\", \"benito\") for michis in lista]\nprint(lista1) # Reemplazo en listas / Replacement in lists Puedes usar listas y comprensión de listas para reemplazar en múltiples cadenas.\n\n#division\n\n\"\"\"\nLa división de cadenas se puede realizar utilizando el método .split() que separa una cadena en una lista de subcadenas.\n\"\"\"\nprint(cadena1.split(\"l\")) # Divide la cadena en una lista usando \"l's\" como separador. (desecha ese criterio, aunque este depende del lenguaje)\nprint(cadena1.split(\"e\")) # Divide la cadena en una lista usando \"e\" como separador. (desecha ese criterio, aunque este depende del lenguaje)\n\n#Conversion a mayusculas / Conversion to uppercase /convesion a minusculas y letras mayusculas \n\nprint(cadena1.upper()) # Convierte toda la cadena a mayúsculas. (all string)\nprint(cadena1.lower()) # Convierte toda la cadena a minúsculas. (all string)\nprint(cadena1.capitalize()) # Capitaliza la primera letra de la cadena.  (solo la primera letra de la cadena)\nprint(cadena3.title()) # Capitaliza la primera letra de cada palabra en la cadena. (la primera letra de cada una de las palabras)\nprint(cadena1.swapcase()) # Invierte las mayúsculas y minúsculas en la cadena. (invierte las mayusculas y minusculas)\n\n# Eliminación de espacios en blanco / Whitespace Removal (al principio y al final)\n\nprint(\"@Paprikaistkrieg\" + cadena4.strip()) # Elimina los espacios en blanco al principio y al final de la cadena.\nprint(cadena4.lstrip()) # Elimina los espacios en blanco al principio de la cadena.\nprint(cadena4.rstrip() + \"@Paprikaistkrieg\") # Elimina los espacios en blanco al final de la cadena.\n\n#busqueda al principio y al final\n\nprint(cadena1.startswith(\"h\")) # Devuelve True si la cadena comienza con \"h\".\nprint(cadena1.endswith(\"o\")) # Devuelve True si la cadena termina con \"o\".\nprint(cadena1.startswith(\"H\")) # Devuelve false \nprint(cadena1.endswith(\"O\")) # Devuelve false \n\n#busqueda de posicion\n\n\nprint(cadena1.find(\"H\")) # Devuelve -1 si no se encuentra\nprint(cadena1.find(\"l\")) # Devuelve 2 (debido a la posicion en la que se encuentra)\nprint(Gt.find(\"r\")) # Devuelve 4 (debido a la posicion en la que se encuentra)\nprint(Gt.lower().find(\"i\"))# Devuelve -1 (debido a la posicion en la que se encuentra, pero este devuelve la primer ocurrencia que coincide con el criterio de busqueda)\n\n\n\nprint(cadena1.find(\"H\")) # Devuelve -1 (debido a la posicion en la que se encuentra)\nprint(cadena1.find(\"l\")) # Devuelve 2 (debido a la posicion en la que se encuentra)\nprint(cadena1.find(\"o\")) # Devuelve 4 (debido a la posicion en la que se encuentra)\nprint(cadena1.find(\"h\")) # Devuelve 0 (debido a la posicion en la que se encuentra)\n\n\n#busqueda de todas las ocurrencias\nprint(Gt.lower().count(\"a\"))# Devuelve 2 (debido a las ocurrencias de \"a\" en la cadena)\n\n#Formateo de cadenas / String formatting\n\"\"\"\nEs el proceso de insertar valores dentro de una cadena sin tener que concatenar manualmente. En lugar de hacer esto:\n\"\"\"\nnombre = \"Paprikaistkrieg\"\nedad = 26\nprint(f\"Hola, soy {nombre} y tengo {edad} años.\") # Formateo con f-strings (se interpreta que todo lo que este dentro de llaves es una variable)\nprint(\"Hola, soy {} y tengo {} años.\".format(nombre, edad)) # Formateo con .format()\n\n\n#para evitar\nprint(\"Hola, soy \" + nombre + \" y tengo \" + str(edad) + \" años.\") # concatenación de cadenas\n\n#interpolación de cadenas (f strings)\nprint(f\"Hola, soy {nombre} y tengo {edad} años.\") # Formateo con f-strings (se interpreta que todo lo que este dentro de llaves es una variable)\nprint(f\"{cadena1} {cadena2}\")\nprint(f\"{nombre} has {edad}.\")\nprint(\"{nombre} has {edad}.\") #aqui no lo imprime con las variables debido a que no esta interpolado\n\n#transformación en lista de caracteres\n\nprint(list(cadena1)) # Convierte la cadena en una lista de caracteres.\n\n#transformación de lista en cadena\ncadena5 = [cadena1, cadena2, \"iam\", Gt]\nprint(\" \".join(cadena5)) # Une/concatena los elementos de la lista en una cadena, separados por un criterio (\" \"  el espacio en este caso es el criterio de separación).\n\n#transformaciones numericas\ncadena6 = \"12345\"\ncadena6 = int(cadena6)\nprint(cadena6)\nprint(type(cadena6))\n\ncadena7 = \"12345.123\"\ncadena7 = float(cadena7)\nprint(cadena7)\nprint(type(cadena7))\n\n#Comprobaciones\n\ncadena8 = \"12345\"\ncadena8 = (cadena8)\n\ncadena9 = \"12345.123\"\ncadena9 = str(cadena9)\nprint(cadena1.isalnum()) # Devuelve True si la cadena es alfanumérica (si tiene letras o numeros)\nprint(cadena1.isalpha()) # Devuelve True si la cadena solo contiene letras (si son solo letras)\nprint((cadena8.isdigit())) # Devuelve True si la cadena solo contiene dígitos (si son solo dígitos)\nprint((cadena8.isdecimal())) # Devuelve True si la cadena es decimal (si son solo números decimales, osea del 0 al 9)\nprint((cadena8.isnumeric())) # Devuelve True si la cadena es numérica (si son solo números)\n\n\n#Xtra\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos (una palabra que se lee igual al derecho que al revés)\n * - Anagramas (dos palabras que tienen las mismas letras en diferente orden)\n * - Isogramas (Cada letra aparece el mismo número de veces. Ej: todas una vez, dos veces, etc.\nHeterograma: Cada letra aparece una sola vez. Es un isograma de primer orden.\nIsograma de segundo orden: Cada letra aparece dos veces, etc.\nIsograma de tercer orden: Cada letra aparece tres veces, etc.\n\"\"\"\ndef check(palabra1: str, palabra2: str):\n    # palíndromo\n    print(f\"¿'{palabra1}' es palíndromo?\", palabra1 == palabra1[::-1])\n    print(f\"¿'{palabra2}' es palíndromo?\", palabra2 == palabra2[::-1])\n\n    # anagrama\n    print(f\"¿'{palabra1}' es anagrama de '{palabra2}'?\", sorted(palabra1) == sorted(palabra2))\n\n    # isograma\n\n    print(f\"¿'{palabra1}' es heterograma?\", len(palabra1) == len(set(palabra1)))\n    print(f\"¿'{palabra2}' es heterograma?\", len(palabra2) == len(set(palabra2))) # Heterograma ya que no se repite ninguna letra\n\n    def isograma(palabra: str):\n        word_dict = dict()\n        for letra in palabra:\n            word_dict[letra] = word_dict.get(letra, 0) + 1\n\n        Values = list(word_dict.values())\n        isogram = True\n        for letra in Values:\n            if letra != Values[0]:\n                isogram = False\n                break\n        return isogram, word_dict\n\n    isograma_result, word_dict = isograma(palabra2)\n    print(f\"¿'{palabra2}' es isograma?\", isograma_result)\n    print(f\"¿'{palabra1}' es isograma?\", isograma_result)\n\ncheck(\"python\", \"pythonpythonpython\")\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/Paula2409.py",
    "content": "\"\"\" \n/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n \"\"\"\n \ndef characters():\n    first_word = input('Ingrese una palabra para analizar: ')\n    second_word = input('Ingrese otra palabra para analizar: ')\n    print(f'La primer palabra tiene un largo de {len(first_word)}')\n    print(f'La primer letra de la primer palabra es la {first_word[0]} y la ultima letra de la segunda es la {second_word[-1]}')\n    print(f'La inversa de la primer palabra es {first_word[::-1]}')\n    print(f'Dos veces la segunda palabra es {2*second_word}')\n    print(f'La concatenacion se realiza sumando la primer palabra {first_word + \" y la segunda palabra \" + second_word}')\n    print(f'Podemos separar los caracteres de la primer palabra en una lista con el metodo split: {first_word.split()}')\n    my_list = []\n    for char in second_word:\n        my_list.append(char)\n    print(f'Tambien se puede realizar lo mismo recorriendo la segunda palabra con un for: {my_list}')\n    print(f'Primer palabra en mayusculas: {first_word.upper()}')\n    print(f'Segunda palabra en minuscula: {second_word.lower()}')\n    print(f'Indicamos la primer letra de la primer palabra como mayuscula: {first_word.capitalize()}')\n    sentence = 'hola mundo python'\n    print(f'Ejemplo de indicar formato titulo en una oracion {sentence}: {sentence.title()}')\n    # Las cadenas de caracteres son tipos de datos inmutables, por lo que no pueden ser modificadas, sino que cualquier cambio debe guardarse dentro de otra referencia de variable:\n    first_word = first_word.replace(first_word[0],\"1\")\n    second_word = second_word.replace(second_word[0],\"2\")\n    print(f'Podemos reemplazar un caracter: {first_word}')\n    print(f'Podemos reemplazar un caracter: {second_word}')\n    print(f'Chequeamos caracteres, si es alfabetico: {first_word.isalpha()}')\n    print(f'Chequeamos caracteres, si es alfanumerico: {first_word.isalnum()}')\n    print(f'Chequeamos caracteres, si es numerico: {first_word.isdigit()}')\n    print(f'\"1\" existe en la primer palabra: {\"1\" in first_word}')\n    print(f'\"2\" existe en la segunda palabra: {\"2\" in second_word}')\n\n#characters()\n    \ndef analyze_word():\n    word_first = input('Ingrese una palabra: ')\n    word_second = input('Ingrese otra palabra: ')\n    \n    def is_palindrom(word_first,word_second):\n        # Palindrom\n        word_first = word_first.lower()\n        word_second = word_second.lower()\n        \n        if word_first == word_first[::-1]:\n            print(f'La palabra {word_first} es palindromo')\n        else:\n            print(f'La palabra {word_first} no es palindromo')\n        if word_second == word_second[::-1]:\n            print(f'La palabra {word_second} es palindromo')\n        else:\n            print(f'La palabra {word_second} no es palindromo')\n    \n    def is_anagram(word_first,word_second):   \n        # Anagram. Using dict\n        first_anagram = {}\n        second_anagram = {}\n        \n        for char in word_first:\n            if char in first_anagram:\n                first_anagram[char] +=1\n            else:\n                first_anagram[char] = 1\n        \n        for char in word_second:\n            if char in second_anagram:\n                second_anagram[char] +=1\n            else:\n                second_anagram[char] = 1\n        \n        if first_anagram == second_anagram:\n            print(f'La palabra {word_first} es un anagrama de {word_second}')\n        else:\n            print('No son anagramas')\n            \n        # Anagram with sort\n        if sorted(word_first) == sorted(word_second):\n            print(f'Metodo sorted: La palabra {word_first} es anagrama de {word_second}')\n        else:\n            print('Metodo sorted: No son anagramas')  \n    \n    def is_isogram(word):    \n        # Isogram\n        word_dict = {}\n        \n        for char in word:\n            if char in word_dict:\n                word_dict[char] += 1\n            else:\n                word_dict[char] = 1\n        analyze_value = word_dict.get(word[0]) \n        for value in word_dict.values():\n            if value != analyze_value:\n                return f\"La palabra {word} no es isograma\"\n        return f\"La palabra {word} es un isograma\"   \n      \n    is_palindrom(word_first,word_second)\n    is_anagram(word_first,word_second) \n    print(is_isogram(word_first))\n    print(is_isogram(word_second))\n             \nanalyze_word()\n    "
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/Pipe281.py",
    "content": "#Ejercicio\n#Acceso a caracter específico\ncadena = \"Python\"\nprimer_caracter = cadena[0]\nultimo_caracter = cadena[-1]\nprint(primer_caracter, ultimo_caracter)\n\n#Subcadena\ncadena = \"Python\"\nposicion = cadena.find(\"y\")\nprint(posicion)\n\n#Longitud\ncadena = \"Python\"\nlongitud = len(cadena)\nprint(longitud)\n\n#Concatenación\ncadena1 = \"Hola\"\ncadena2 = \"Mundo\"\nresultado = cadena1 + \" \" + cadena2\nprint(resultado)\n\n#Repetición\ncadena = \"Python \"\nresultado = cadena * 3\nprint(resultado)\n\n#Recorrido\ncadena = \"Python\"\nfor caracter in cadena:\n    print(caracter)\n\n\n#Conversión Minusculas y Mayusculas\ncadena = \"Python\"\nmayusculas = cadena.upper()\nminusculas = cadena.lower()\nprint(mayusculas, minusculas)\n\n#Reemplazo\ncadena = \"Hola Mundo\"\nnueva_cadena = cadena.replace(\"Mundo\", \"Python\")\nprint(nueva_cadena)\n\n#División\ncadena = \"Python es genial\"\nsubcadenas = cadena.split(\" \")  # Dividir por espacio en blanco\nprint(subcadenas)\n\ncadena = \"Python es genial\"\ntrozo1 = cadena[:6]  \ntrozo2 = cadena[7:9]  \ntrozo3 = cadena[10:]  \n\nprint(trozo1, trozo2, trozo3)\n\n#Unión\ncadenas = [\"Hola\", \"Python\"]\nunion = \" xx \".join(cadenas)\nprint(union)\n\n#Interpolación con f-strings y método format \nnombre = \"Felipe\"\nedad = 33\nmensaje = f\"Hola, mi nombre es {nombre} y tengo {edad} años.\"\nprint(mensaje)\n\nmensaje = \"Hola, mi nombre es {} y tengo {} años.\".format(nombre, edad)\nprint(mensaje)\n\n#Verificación con Dígito, Letra, Alfanumérico, Mayúscula, Minúscula y espacio en blanco\ncaracter = '5'\nif caracter.isdigit():\n    print(f\"{caracter} es un dígito.\")\nelse:\n    print(f\"{caracter} no es un dígito.\")\n\ncaracter = 'A'\nif caracter.isalpha():\n    print(f\"{caracter} es una letra.\")\nelse:\n    print(f\"{caracter} no es una letra.\")\n\ncaracter = 'X'\nif caracter.isalnum():\n    print(f\"{caracter} es alfanumérico.\")\nelse:\n    print(f\"{caracter} no es alfanumérico.\")\n\ncaracter = 'Z'\nif caracter.isupper():\n    print(f\"{caracter} está en mayúsculas.\")\nelse:\n    print(f\"{caracter} no está en mayúsculas.\")\n\ncaracter = 'z'\nif caracter.islower():\n    print(f\"{caracter} está en minúsculas.\")\nelse:\n    print(f\"{caracter} no está en minúsculas.\")\n\ncaracter = ' '\nif caracter.isspace():\n    print(f\"{caracter} es un espacio en blanco.\")\nelse:\n    print(f\"{caracter} no es un espacio en blanco.\")\n\n#Ejercicio\n#Palindromo\ndef es_palindromo(palabra):\n    palabra = palabra.lower().replace(\" \", \"\")  # Convertir a minúsculas y eliminar espacios\n    return palabra == palabra[::-1]\n\ndef verificar_palindromos(palabra1, palabra2):\n    if es_palindromo(palabra1) and es_palindromo(palabra2):\n        print(f\"Ambas palabras, '{palabra1}' y '{palabra2}', son palíndromos.\")\n    elif es_palindromo(palabra1):\n        print(f\"La palabra '{palabra1}' es un palíndromo, pero '{palabra2}' no lo es.\")\n    elif es_palindromo(palabra2):\n        print(f\"La palabra '{palabra2}' es un palíndromo, pero '{palabra1}' no lo es.\")\n    else:\n        print(f\"Ni '{palabra1}' ni '{palabra2}' son palíndromos.\")\n\n# Ejemplo de uso\npalabra1 = input(\"Ingrese la primera palabra: \")\npalabra2 = input(\"Ingrese la segunda palabra: \")\n\nverificar_palindromos(palabra1, palabra2)\n\n#Anagrama\ndef son_anagramas(palabra1, palabra2):\n    palabra1 = palabra1.lower().replace(\" \", \"\")  # Convertir a minúsculas y eliminar espacios\n    palabra2 = palabra2.lower().replace(\" \", \"\")\n\n    # Verificar si las palabras tienen la misma cantidad de letras\n    if len(palabra1) != len(palabra2):\n        return False\n\n    # Verificar si ambas palabras contienen las mismas letras\n    return sorted(palabra1) == sorted(palabra2)\n\n# Ejemplo de uso\npalabra1 = input(\"Ingrese la primera palabra: \")\npalabra2 = input(\"Ingrese la segunda palabra: \")\n\nif son_anagramas(palabra1, palabra2):\n    print(f\"'{palabra1}' y '{palabra2}' son anagramas.\")\nelse:\n    print(f\"'{palabra1}' y '{palabra2}' no son anagramas.\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/PyTorDev.py",
    "content": " # EJERCICIO:\n # Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n # en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n # - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\n #   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\n #   interpolación, verificación...\n\n # Operaciones con strings en Python\n\nmy_str = \"Hola python\"\nsec_str = \"Soy Aitor López\"\nname, surname, job, age = \"Aitor\", \"López\", \"Software Developer\", 27\n\n# Devolver numero de caracteres\nprint(len(my_str))\n\n# Concatenar strings\nprint(my_str + \". \" + sec_str)\n\n# Formateo de un string. Diferentes metodos ordenados de mas recomendado a menos recomendado\nprint(f\"Hola, soy {name} {surname}, soy un {job} junior, y tengo {age} años\") # Forma mas moderna y legible\nprint(\"Hola, soy {} {}, soy un {} junior, y tengo {} años\".format(name, surname, job, age)) # Forma algo mas antigua, pero aun legible\nprint(\"Hola, soy %s %s, soy un %s junior, y tengo %d años\" % (name, surname, job, age)) # Esta forma es hereadada de versiones antiguas de Python\nprint(\"Hola, soy \" + name + \" \" + surname + \", soy un \" + job + \" junior, y tengo \" + str(age) + \" años\") # Totalmente desaconsejable, pero legibilidad y propenso a errore\n\n# Desempaquetado de caracteres\na, b, c, d, e = name\nprint(a)\nprint(b)\n\n# Division (slice)\nname_slice = name[1:3]\nprint(name_slice)\n\nname_slice = name[1:]\nprint(name_slice)\n\nname_slice = name[-2]\nprint(name_slice)\n\nname_slice = name[0:3:2]\nprint(name_slice)\n\n# Revertir string\nname_slice = name[::-1] #Lee de principio a fin pero en intervalos de -1\nprint(name_slice)\n\n# Funciones del sistema para strings\nprint(surname.capitalize()) # Pone la primera letra en mayuscula\nprint(surname.upper()) # Pone todas las letras en mayusculas\nprint(surname.lower()) # Pone todas las letras en minusculas\nprint(surname.isupper()) # Comprueba si todas las letras son mayusculas\nprint(surname.count(\"ó\")) # Cuenta cuantas veces aparece un caracter\nprint(surname.isnumeric()) # Comprueba si el string es numerico (es decir, si se podria pasar a un int)\nprint(surname.startswith(\"Ló\")) # Comprueba si un string comienza con cierto prefijo\nprint(surname == name) # Compara dos strings\n\n # DIFICULTAD EXTRA (opcional):\n # Crea un programa que analice dos palabras diferentes y realice comprobaciones\n # para descubrir si son:\n # - Palíndromos\n # - Anagramas\n # - Isogramas\n\ndef str_analycer(str1, str2):\n  clean1 = str1.replace(\" \", \"\").lower()\n  reverse1 = clean1[::-1]\n  caracters1 = set()\n  clean2 = str2.replace(\" \", \"\").lower()\n  reverse2 = clean2[::-1]\n  caracters2 = set()\n  result = []\n  \n  # Comprovar Palíndormos \n  result.append(\"si\" if clean1 == reverse1 else \"no\") # result[0]\n  result.append(\"si\" if clean2 == reverse2 else \"no\") # result[1]\n\n  # Comprobar anagramas \n  result.append(\"si\" if sorted(clean1) == sorted(clean2) else \"no\") #result[2]\n\n  #Comprobar isogramas\n  # result[3]\n  for letra in clean1:\n    if letra in caracters1:\n      result.append(\"no\")\n      break\n    else:\n      caracters1.add(letra)\n  else:\n    result.append(\"si\")\n\n  # result[4]\n  for letra in clean2:\n    if letra in caracters2:\n      result.append(\"no\")\n      break\n    else:\n      caracters2.add(letra)\n  else:\n    result.append(\"si\")\n\n  #Imprimir el resultado\n  print(\"-----------------------------------------------------\")\n  print(f\"La palabra {str1} {result[0]} es un palindormo.\\nLa palabra {str2} {result[1]} es un palindormo. \\nLas palabras {str1} y {str2}, {result[2]} son un anagrama. \\nLa palabra {str1} {result[3]} es un isograma. \\nLa palabra {str2} {result[4]} es un isograma.\")\n  print(\"-----------------------------------------------------\")\n\nstr_analycer(\"Reconocer\", \"Anilina\") # Palindromos, no isogramas, no anagramas\nstr_analycer(\"Amor\", \"Roma\") #Anagramas, no palindormos, si isogramas\nstr_analycer(\"Murcielago\", \"Centavo\") # Isogramas, no palindormos ni anagramas\nstr_analycer(\"Oso\", \"oso\") #Palindromos, anagramas, no isogramas\nstr_analycer(\"Luz\", \"zul\") # Anagramas, isogramas, no palindromos\nstr_analycer(\"Hola\", \"Adios\") # Todo no\nstr_analycer(\"carro\", \"rocar\") # anagramas, no isogramas, no palindormos\nstr_analycer(\"dabale arroz a la zorra el abad\", \"la zorra el abad dabale arroz\") # palindromos y anagramas\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/Ramirofordev.py",
    "content": "# Cadenas de caracteres\n\nstring = \"Hola Python\"\nstring2 = \"Como estan?\"\n\n# Concatenacion \nprint(string + \", \" + string2)\n\n# Repeticion\nprint(string * 3)\n\n# Acceso a caracteres especificos\nprint(string[2])\n\n# Slicing\nprint(string[:5])\n\n# Longitud\nprint(len(string2))\n\n# Busqueda \nprint('a' in string)\nprint('h' in string2)\n\n# Conversion a mayusculas, minusculas y primera letra en mayusculas\nprint(string.upper())\nprint(string.lower())\nprint(string2.title())\nprint(\"me llamo nacho\".capitalize())\n\n# Remplazo\nprint(string.replace(\"a\", \"5\"))\n\n# Division\nprint(string2.split(\"o\"))\n\n# Eliminacion de espacios al principio y al final\nprint(\"    hola mi nombre es nacho     \".strip())\n\n# Encontrar \nprint(string.find(\"P\"))\n\n# Busqueda al principio y al final\nprint(string.startswith(\"h\"))\nprint(string.endswith(\"n\"))\n\n\n# Busqueda de ocurrencias\nprint(string.count(\"o\"))\n\n# Formateo\nprint(\"AAAA {} texto sin sentido. {}\".format(string, string2))\n\n# Interpolacion\nprint(f\"Viva molotov, {string2}\")\n\n# Transformacion en lista de caracteres\ncaracters = list(string)\n\n# Transformaciones numericas\ns1 = \"12131341\"\ns1 = int(s1)\n\ns2 = \"1.5\"\ns2 = float(s2)\n\n# Transformacion de lista en cadena\nlista = [\"Hola\", \"Python\", \"Weyes\"]\nprint(\" \".join(lista))\n\n# Comprobaciones\nprint(string.isalnum())\nprint(string.isalpha())\nprint(string.isascii())\nprint(string.isdecimal())\nprint(string.isdigit())\nprint(string.islower())\n# Etc..\n\n# Ejercicio extra\n\ndef check(word1: str, word2: str):\n\n    # Palindromos\n    print(f\"{word1} es un palindromo?: {word1 == word1[::-1]}\")\n    print(f\"{word2} es un palindromo?: {word2 == word2[::-1]}\")\n\n    # Anagramas\n    print(f\"{word1} es un anagrama de {word2}: {sorted(word1) == sorted(word2)}\")\n        \n    # Isograma\n    def isogram(word: str) -> bool:\n        \n        word_dict = {}\n        for character in word:\n            word_dict[character] = word_dict.get(character, 0) + 1\n\n        isograma = True\n        values = list(word_dict.values())\n        isagram_len = values[0]\n        for word_count in values:\n            if word_count != isagram_len:\n                isograma = False\n                break\n        return isograma\n\n    print(f\"{word2} es un isograma? {isogram(word2)}\")\n    print(f\"{word2} es un isograma? {isogram(word2)}\")\n\n\ncheck(\"radar\", \"Python\")\ncheck(\"amor\", \"roma\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/RicardiJulio.py",
    "content": "#  * EJERCICIO:\n#  * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n#  * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n#  * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n#  *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n#  * para descubrir si son:\n#  * - Palíndromos\n#  * - Anagramas\n#  * - Isogramas\n\n# Creacion y acceso:\n\ns = 'Hola mundo' # Creacion de la cadena\ns[5]             # Acceder a un caracter en concreto\ns[2:6]           # Acceder a un tramo de la cadena [a:b]\nlen(s)           # funcion que cuenta el numero de caracteres de la cadena\n\n# Comparaciones y busquedas:\n\n# s1 == s2, s1 != s2, s1 > s2, etc.   ---> Comparaciones\n'mundo' in s                         #---> Verifica si contiene una subcadena\ns.find('mundo')                      #---> Indica la primera aparicion del texto\ns.index('mundo')                     #---> Igual que la anterior pero imprime error si no existe\ns.startswith('Hola')                 #---> Indica si el texto inicia con ('texto')\ns.endswith('Mundo')                  #---> Indica si el texto termina con ('texto')\ns.count('o')                         #---> Cuenta las ocurrencias de un caracter\n\n# Modificacion y transformacion:\n\ns.lower()                           #---> Transforma el texto a minusculas\ns.upper()                           #---> Transforma el texto a mayusculas\ns.title()                           #---> Transforma el texto a altas y bajas\ns.capitalize()                      #---> Transforma en mayuscula la pirmera letra\ns.swapcase()                        #---> Intercambia mayusculas y minusculas\ns.replace('a','e')                  #---> Intercambia subcadenas\ns.strip()                           #---> Elimina espacios al principio (o caracteres) o al final\ns.rstrip(), s.lstrip()              #---> Elimina espacios a la derecha o a la izquierda respectivamente\ns.zfill(5)                          #---> Rellena con ceros los caracteres indicaciones\ns.center(10), \ns.ljust(10),                        #---> Alineación\ns.rjust(10) \n\n# Union y separacion\n\n# ' '.join(lista)                   #---> Une elementos con un separador\ns.split()                           #---> Separa cadenas de texto por los espacios ( )\ns.split(',')                        #---> Separa cadenas de texto por un caracter especifico (',')\ns.partition('x')                    #---> Divide en 3 partes (antes, separador, después)\ns.rsplit()                          #---> Separa cadenas de texto desde la derecha\n\n# Verificacion (booleanas):\n\ns.isalpha()                         # ---> Verifica si en la cadena hay solo letras\ns.isdigit()                         # ---> Verifica si en la cadena hay solo numeros\ns.isalnum()                         # ---> Verifica si hay letras y numeros\ns.islower()                         # ---> Verifica si son todo minusculas\ns.isupper()                         # ---> Verifica si son todo mayusculas\ns.isspace()                         # ---> Verifica si son espacios \ns.istitle()                         # ---> Verifica si esta en altas y bajas (o titulo)\n\n# Formateo de cadenas:\n\n# nombre = 'juan'\n\n# f\"Hola {nombre}\" # f-strings\n# \"Hola {}\".format(nombre) # Método format\n# \"Hola %s\" % nombre # Formato tipo C\n# s.format_map(diccionario) # Formato con diccionarios\n\n# Otros Útiles\n\n# import re\n# re.sub(), re.search()               # Expresiones regulares\n# ord('a'), chr(97)                   # Unicode <-> caracter\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n#  * para descubrir si son:\n#  * - Palíndromos\n#  * - Anagramas\n#  * - Isograma\n\n# Palindromo:\n# Un palíndromo es una palabra, frase o número que se lee igual de izquierda a derecha\n# que de derecha a izquierda, como \"anana\" o \"12321\"\n\n# Anagrama:\n# Un anagrama es una palabra o frase nueva que se obtiene al cambiar el orden de las \n# letras de otra palabra o frase. Por ejemplo, \"Pedro\" se puede transformar en \"poder\". \n\n# Isograma:\n\n# Un isograma, es una palabra o frase en la que cada letra aparece el mismo número de veces. \n# Si cada letra aparece solo una vez será un heterograma, si aparece dos, un isogroma de \n# segundo orden y así sucesivamente. \n\ndef descomponer(palabra):\n    descomposicion = []\n    for i in palabra:\n        descomposicion.append(i)\n    return descomposicion\n\ndef es_pali(lista):\n    tupla_i = lista[::-1]\n    if tupla_i == lista:\n        return True\n    else:\n        return False\n    \ndef es_ana(palabra1,palabra2):\n    tf = []\n    a = len(palabra1)\n    b = len(palabra2)\n    palabra1.sort()\n    palabra2.sort()\n    for i in range(len(palabra1)) and range(len(palabra2)):\n        if palabra1[i] == palabra2[i]:\n            tf.append(True)\n        else:\n            break\n    \n    if a == b and a == len(tf):\n        return True\n    else:\n        return False\n    \n    \ndef es_iso(palabra):\n    for i in palabra:\n        if palabra.count(i) == 1:\n            continue\n        elif palabra.count(i) >= 2:\n            return True\n    return False\n\n\npalabra1 = input(str('Introduzca la primera palabra:\\n'))\npalabra2 = input(str('Introduzca la segunda palabra:\\n'))\n\na = descomponer(palabra1)\nb = descomponer(palabra2)\n\nif es_pali(a) == True:\n    print(f'La palabra {palabra1} es un palindromo.')\n    \nelif es_ana(a,b) == True:\n    print (f'Las palabras {palabra1} y {palabra2} son un anagrama.')\n    \nelif es_iso(palabra1) == True:\n    print(f'La palabra {palabra1} es un Isograma.')\n    \nif es_pali(b) == True:\n    print(f'La palabra {palabra2} es un palindromo.')\n    \nelif es_iso(palabra2) == True:\n    print(f'La palabra {palabra2} es un Isograma.')\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/RoniPG.py",
    "content": "# @RoniPG\n\n# Crear una cadena de caracteres\n\nejemplo=\"hola Mundo\"\nejemplo2:str # --> Crear la cadena vacia\nprint(\"Contenido de la cadena de caracteres: \"+ejemplo)\nprint(\"Ejemplo despues del capitlaze: \"+str(ejemplo.capitalize())) # --> Se utiliza para convertir la cadena con su primer carácter convertido a mayúscula\nprint(\"Contenido de la cadena de caracteres: \"+ejemplo)\nprint(\"Ejemplo despues del casefold: \"+str(ejemplo.casefold()) ) # --> Se utiliza para convertir la cadena a minúsculas durante su ejecucion\nprint(\"Contenido de la cadena de caracteres: \"+ejemplo)\nprint(f\"Ejemplo despues del center: {ejemplo.center(25,\"*\")}\") # --> Se utiliza para centrar una cadena dentro de un ancho específico durante su ejecucion\nprint(\"Contenido de la cadena de caracteres: \"+ejemplo)\nprint(f\"Ejemplo despues del count: {ejemplo.count(\"o\")}\") # --> Se utiliza para contar cuántas veces aparece una subcadena específica dentro de una cadena más grande\nprint(\"Contenido de la cadena de caracteres: \"+ejemplo)\nprint(f\"Ejemplo despues del endswith: {ejemplo.endswith(\"a\")}\") # --> Se utiliza para verificar si una cadena termina con una subcadena específica\nprint(\"Contenido de la cadena de caracteres: \"+ejemplo)\nprint(f\"Ejemplo despues del encode: {ejemplo.encode()}\") # --> Se utiliza para convertir una cadena de caracteres en su representación en bytes utilizando una codificación específica\nejemplo=\"hola\\tMundo\\t\"\nprint(\"Contenido de la cadena de caracteres: hola\\\\tMundo\\\\t\")\nprint(f\"Ejemplo despues del expandtabs:{ejemplo.expandtabs(12)}\") # --> Se utiliza para expandir los tabuladores '\\t' \nejemplo=\"hola Mundo\"\nprint(f\"Contenido de la cadena de caracteres: {ejemplo}\")\nprint(f\"Ejemplo despues del find:{ejemplo.find(\"o\")}\") # --> Se utiliza para encontrar la primera ocurrencia de una subcadena dentro de otra cadena\nejemplo=\"hola Mundo {} {}\"\nprint(\"Contenido de la cadena de caracteres: \"+ejemplo)\nprint(f\"Ejemplo despues del format: {ejemplo.format(\"Python\",2)}\") # --> Se utiliza para formatear cadenas de texto con valores específicos\nejemplo=\"hola Mundo {Lenguaje} {Version}\"\nprint(\"Contenido de la cadena de caracteres: \"+ejemplo)\nprint(f\"Ejemplo despues del format: {ejemplo.format_map({\"Lenguaje\":\"Python\",\"Version\":2})}\") # --> Se utiliza para formatear cadenas de texto con valores específicos\nejemplo=\"hola Mundo\"\nprint(\"Contenido de la cadena de caracteres: \"+ejemplo)\nprint(f\"Ejemplo despues del index: {ejemplo.index(\"la\")}\") # --> Se utiliza para encontrar el índice de la primera ocurrencia de una subcadena dentro de otra cadena\nprint(\"Contenido de la cadena de caracteres: \"+ejemplo)\nprint(f\"Ejemplo despues del isalnum: {ejemplo.isalnum()}\") # --> Se utiliza para verificar si una cadena contiene únicamente caracteres alfanuméricos (letras y números) y no está vacía o contiene espacios\nprint(\"Contenido de la cadena de caracteres: \"+ejemplo)\nprint(f\"Ejemplo despues del isalpha: {ejemplo.isalpha()}\") # --> Se utiliza para verificar si una cadena contiene únicamente caracteres alfabéticos (letras) y no está vacía o contiene espacios.\nprint(\"Contenido de la cadena de caracteres: \"+ejemplo)\nprint(f\"Ejemplo despues del isascii: {ejemplo.isascii()}\") # --> Se utiliza para verificar si todos los caracteres de una cadena son caracteres ASCII y no está vacía.\nprint(\"Contenido de la cadena de caracteres: \"+ejemplo)\nprint(f\"Ejemplo despues del isdecimal: {ejemplo.isdecimal()}\") # --> Se utiliza para verificar si todos los caracteres de una cadena son dígitos decimales(0-9) y no está vacía o contiene espacios.\nprint(\"Contenido de la cadena de caracteres: \"+ejemplo)\nprint(f\"Ejemplo despues del isdigit: {ejemplo.isdigit()}\") # --> Se utiliza para verificar si todos los caracteres de una cadena son dígitos y no está vacía o contiene espacios.\nprint(\"Contenido de la cadena de caracteres: \"+ejemplo)\nprint(f\"Ejemplo despues del isidentifier: {ejemplo.isidentifier()}\") # --> Se utiliza para verificar si una cadena es un identificador válido de Python\nprint(\"Contenido de la cadena de caracteres: \"+ejemplo)\nprint(f\"Ejemplo despues del isnumeric: {ejemplo.isnumeric()}\") # --> Se utiliza para verificar si todos los caracteres de una cadena son caracteres numéricos y no está vacía o contiene espacios.\nprint(\"Contenido de la cadena de caracteres: \"+ejemplo)\nprint(f\"Ejemplo despues del islower: {ejemplo.islower()}\") # --> Se utiliza para verificar si todos los caracteres de una cadena están en minúsculas y no está vacía.\nprint(\"Contenido de la cadena de caracteres: \"+ejemplo)\nprint(f\"Ejemplo despues del isprintable: {ejemplo.isprintable()}\") # --> Se utiliza para verificar si todos los caracteres de una cadena son caracteres imprimibles y no está vacía\nprint(\"Contenido de la cadena de caracteres: \"+ejemplo)\nprint(f\"Ejemplo despues del isspace: {ejemplo.isspace()}\") # --> Se utiliza para verificar si todos los caracteres de una cadena son caracteres de espacio en blanco y no está vacía.\nprint(\"Contenido de la cadena de caracteres: \"+ejemplo)\nprint(f\"Ejemplo despues del istitle: {ejemplo.istitle()}\") # --> Se utiliza para verificar si una cadena sigue el formato de título y no está vacía.\nprint(\"Contenido de la cadena de caracteres: \"+ejemplo)\nprint(f\"Ejemplo despues del isupper: {ejemplo.isupper()}\") # --> Se utiliza para verificar si todos los caracteres de una cadena están en mayúsculas y no está vacía.\nprint(\"Contenido de la cadena de caracteres: \"+ejemplo)\ncadena=[\"hola\",\"Mundo\"]\nprint(f\"Lista de cadenas despues del join: {\" \".join(cadena)}\") # --> Se utiliza para concatenar una lista de cadenas en una sola cadena, utilizando otra cadena como separador entre cada elemento de la lista.\nprint(\"Contenido de la cadena de caracteres: \"+ejemplo)\nprint(f\"Ejemplo despues del ljust: {ejemplo.ljust(20,\"*\")}\") # --> Se utiliza para justificar a la izquierda (left justify) una cadena\nprint(\"Contenido de la cadena de caracteres: \"+ejemplo)\nprint(f\"Ejemplo despues del lower: {ejemplo.lower()}\") # --> Se utiliza para convertir todos los caracteres de una cadena a minúsculas\nejemplo=\"****hola Mundo****\"\nprint(\"Contenido de la cadena de caracteres: \"+ejemplo)\nprint(f\"Ejemplo despues del lstrip: {ejemplo.lstrip(\"*\")}\") # --> Se utiliza para eliminar los caracteres en blanco (o cualquier otro carácter especificado) del lado izquierdo (o principio) de una cadena.\nejemplo=\"hola Mundo\"\nprint(\"Contenido de la cadena de caracteres: \"+ejemplo)\ntabla=str.maketrans({\"a\":\"1\",\"o\":\"4\",\"u\":\"5\"}) # --> Se utiliza para crear una tabla de traducción que puede ser utilizada por los métodos translate() o str.translate() para realizar traducciones de caracteres.\nprint(f\"La tabla despues del maketrans contiene:\\n{tabla}\")\nprint(f\"Ejemplo despues del translate: {ejemplo.translate(tabla)}\") # -->  Se utiliza para realizar traducciones de caracteres en una cadena utilizando una tabla de traducción creada con el método maketrans().\nprint(\"Contenido de la cadena de caracteres: \"+ejemplo)\nprint(f\"Ejemplo despues del partition: {ejemplo.partition(\" \")}\") # -->Se utiliza para dividir una cadena en tres partes, utilizando un separador especificado\nprint(\"Contenido de la cadena de caracteres: \"+ejemplo)\nprint(f\"Ejemplo despues del removeprefix: {ejemplo.removeprefix(\"ho\")}\") # --> Se utiliza para eliminar un prefijo especificado de una cadena, si la cadena comienza con ese prefijo\nprint(\"Contenido de la cadena de caracteres: \"+ejemplo)\nprint(f\"Ejemplo despues del removesuffix: {ejemplo.removesuffix(\"do\")}\") # --> Se utiliza para eliminar un sufijo especificado de una cadena, si la cadena termina con ese sufijo\nprint(\"Contenido de la cadena de caracteres: \"+ejemplo)\nprint(f\"Ejemplo despues del replace: {ejemplo.replace(\"o\",\"a\")}\") # --> Se utiliza para reemplazar todas las ocurrencias de una subcadena en una cadena con otra subcadena especificada\nprint(\"Contenido de la cadena de caracteres: \"+ejemplo)\nprint(f\"Ejemplo despues del rpartition: {ejemplo.rpartition(\" \")}\") # --> A diferencia del método partition(), rpartition() comienza la búsqueda desde el final de la cadena en lugar de desde el principio.\nprint(\"Contenido de la cadena de caracteres: \"+ejemplo)\nprint(f\"Ejemplo despues del rfind:{ejemplo.rfind(\"o\")}\") # --> Se utiliza para encontrar la última ocurrencia de una subcadena dentro de una cadena\nprint(\"Contenido de la cadena de caracteres: \"+ejemplo)\nprint(f\"Ejemplo despues del rindex: {ejemplo.rindex(\"la\")}\") # --> Se utiliza para encontrar el índice de la ultima ocurrencia de una subcadena dentro de otra cadena\nprint(\"Contenido de la cadena de caracteres: \"+ejemplo)\nprint(f\"Ejemplo despues del rjust: {ejemplo.rjust(20,\"*\")}\") # --> Se utiliza para justificar a la derecha una cadena, añadiendo espacios o caracteres especificados en el lado izquierdo de la cadena hasta alcanzar una longitud total especificada.\nprint(\"Contenido de la cadena de caracteres: \"+ejemplo)\nprint(f\"Ejemplo despues del rsplit: {ejemplo.rsplit(\"o\")}\") # --> Se utiliza para dividir una cadena en una lista de subcadenas, utilizando un separador especificado, comenzando desde el final de la cadena.\nprint(\"Contenido de la cadena de caracteres: \"+ejemplo)\nprint(f\"Ejemplo despues del rstrip: {ejemplo.rstrip(\"o\")}\") # --> Se utiliza para eliminar los caracteres de espacio en blanco y/o los caracteres especificados en la parte derecha (final) de una cadena\nprint(\"Contenido de la cadena de caracteres: \"+ejemplo)\nprint(f\"Ejemplo despues del split: {ejemplo.split(\"o\")}\") # --> Se utiliza para dividir una cadena en una lista de subcadenas, utilizando un separador especificado.\nprint(\"Contenido de la cadena de caracteres: hola\\\\nMundo\\\\n\")\nejemplo=\"hola\\nMundo\\n\"\nprint(f\"Ejemplo despues del splitlines: {ejemplo.splitlines()}\") # --> Se utiliza para dividir una cadena en una lista de líneas.Utiliza los caracteres(\\n),(\\r),(\\r\\n)\nejemplo=\"hola Mundo\"\nprint(\"Contenido de la cadena de caracteres: \"+ejemplo)\nprint(f\"Ejemplo despues del startswith: {ejemplo.startswith(\"ho\")}\") # --> Se utiliza para verificar si una cadena comienza con un prefijo especificado\nprint(\"Contenido de la cadena de caracteres: \"+ejemplo)\nprint(f\"Ejemplo despues del strip: {ejemplo.strip(\"o\")}\") # --> Se utiliza para eliminar los caracteres de espacio en blanco y/o los caracteres especificados al principio y al final de una cadena\nprint(\"Contenido de la cadena de caracteres: \"+ejemplo)\nprint(f\"Ejemplo despues del swapcase: {ejemplo.swapcase()}\") # --> Se utiliza para intercambiar entre mayúsculas y minúsculas en una cadena\nprint(\"Contenido de la cadena de caracteres: \"+ejemplo)\nprint(f\"Ejemplo despues del title: {ejemplo.title()}\") # --> Se utiliza para convertir la primera letra de cada palabra en una cadena a mayúscula y las demás letras a minúscula.\nprint(\"Contenido de la cadena de caracteres: \"+ejemplo)\nprint(f\"Ejemplo despues del upper: {ejemplo.upper()}\") # --> Se utiliza para convertir todos los caracteres de una cadena a mayúsculas.\nprint(\"Contenido de la cadena de caracteres: \"+ejemplo)\nprint(f\"Ejemplo despues del zfill: {ejemplo.zfill(15)}\") # --> Se utiliza para rellenar una cadena con ceros ('0') a la izquierda para alcanzar una longitud específica\nprint(\"\\nDIFICULTAD EXTRA (opcional):\")\n\"\"\"\nDIFICULTAD EXTRA (opcional):\nCrea un programa que analice dos palabras diferentes y realice comprobaciones\npara descubrir si son:\nPalíndromos\nAnagramas\nIsogramas\n\"\"\"\ndef Palindromo(a:str):\n    \"\"\"\n    Palíndromo:\n    Palabra o frase cuyas letras están dispuestas de tal manera que resulta la misma leí­da de izquierda a derecha que de derecha a izquierda.\n    Por ejemplo: anilina\n    \"\"\"\n    a1=a.lower()\n    aux=\"\"\n    for letra in reversed(a1):\n        aux+=letra\n    if(aux.__eq__(a1)):\n        print(f\"La palabra {a} es palindromo\")\n    else:\n        print(f\"La palabra {a} NO es palindromo\")\n\ndef Anagrama(a:str, b:str):\n    \"\"\"\n    Anagrama:\n    Cambio en el orden de las letras de una palabra o frase que da lugar a otra palabra o frase distinta.\n    Por ejemplo: Amor --> Roma\n    \"\"\"\n    a1=a.lower()\n    b1=b.lower()\n\n    a1=sorted(a1)\n    b1=sorted(b1)\n\n    if(a1.__eq__(b1)):\n        print(f\"La palabra {a} es anagrama de la palabra {b}\")\n    else:\n        print(f\"La palabra {a} NO es anagrama de la palabra {b}\")    \ndef Isograma(a:str):\n    \"\"\"\n    Un isograma es una palabra o frase en la que cada letra aparece el mismo número de veces.\n    Si cada letra aparece solo una vez será un heterograma, si aparece dos, un isogroma de segundo orden y así­ sucesivamente.\n    Por ejemplo:\n    Heterogramas: yuxtaponer, centrifugado, luteranismo.\n    Isogramas con una repetición o de segundo orden: acondicionar, escritura, intestinos.\n    \"\"\"\n    flag=False\n    count=0\n    a1=set()\n    for letra_a in a:\n        a1.add(letra_a)\n    for letra_a1 in a1:\n        for letra_a in a:\n            if (letra_a1.__eq__(letra_a)):\n                count +=1\n        print(f\"La letra: \\\"{letra_a1}\\\" esta repetida: {count} veces\")\n        if count>1:\n            flag=True\n        count=0\n    if flag:\n        print(\"Es un isograma\")\n    else:\n        print(\"Es un heterograma\")\n    \nAnagrama(\"Roma\",\"Amor\")\nPalindromo(\"Anilina\")\nIsograma(\"acondicionar\")\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/RuhlMirko.py",
    "content": "print(\"Acceso a caracteres especificos:\")\ncadena_ejemplo = \"Hola mundo \"\nprint(cadena_ejemplo[0])\nprint(cadena_ejemplo[5])\n\nprint(\"\\nSubcadenas\")\nprint(cadena_ejemplo[2:5])\nprint(cadena_ejemplo[:5])\nprint(cadena_ejemplo[4:])\n\nprint(\"\\nLongitud\")\nlongitud_cadena = str(len(cadena_ejemplo))\nprint(\"Longitud de la cadena: \" + longitud_cadena)\nprint(\"Cantidad de letras 'o' encontradas: \" + str(cadena_ejemplo.count('o')))\n\nprint(\"\\nConcatenacion\")\ncadena_nueva = \"y hola a todos\"\ncadena_ejemplo = cadena_ejemplo + cadena_nueva\nprint(cadena_ejemplo)\n\nprint(\"\\nRepeticion\")\nprint(cadena_ejemplo * 3)\n\nprint(\"\\nRecorrido\")\nfor char in cadena_ejemplo:\n    print(char)\n\nprint(\"\\nConversion a Mayuscula y Minuscula\")\nprint(cadena_ejemplo.lower())\nprint(cadena_ejemplo.upper())\nprint(cadena_ejemplo.capitalize())\nprint(cadena_ejemplo.title())\n\nprint(\"\\nReemplazo\")\ncadena_ejemplo = cadena_ejemplo.strip(' ')  # Elimina los espacios en blanco\ncadena_ejemplo = cadena_ejemplo.replace('mundo', 'Python')  # Reemplaza una palabra con otra\nprint(cadena_ejemplo)\n\nprint(\"\\nDivision\")\nlista_cadena = cadena_ejemplo.split(' ')\nprint(lista_cadena)\n\nprint(\"\\nUnion\")\nprint(\"\".join(lista_cadena))\n\nprint(\"\\nVerificacion\")\nnumero_ejemplo = \"12\"\nprint(f\"<{cadena_ejemplo}> es una variable alfa-numerica? {cadena_ejemplo.isalnum()}\")\nprint(f\"<{numero_ejemplo}> es un numero? {numero_ejemplo.isnumeric()}\")\n\nprint(\"\\nBusqueda\")\nprint(f\"<{cadena_ejemplo}> contiene un hola? {'Hola' in cadena_ejemplo}\")\nprint(f\"<{cadena_ejemplo}> contiene python? Indice {cadena_ejemplo.find('Python')}\")\nprint(f\"<{cadena_ejemplo}> Empieza con un hola? {cadena_ejemplo.startswith('Hola')}\")\nprint(f\"<{cadena_ejemplo}> Empieza con un hola? {cadena_ejemplo.endswith('Hola')}\")\n\nprint(\"\\nDificlutad Extra: \")\n\nfirst_word = input(\"Ingrese una palabra: \").lower()\nsecond_word = input(\"Ingrese otra palabra: \").lower()\n\n\ndef palindromos(a_str, b_str):\n    if a_str == a_str[::-1]:\n        print(f\"{a_str} es una Palabra palindroma\")\n    if b_str == b_str[::-1]:\n        print(f\"{b_str} es una Palabra palindroma\")\n\n\ndef anagramas(a_str, b_str):\n    result = sorted(a_str) == sorted(b_str)\n    if result:\n        print(f\"{a_str} y {b_str} es un Anagrama\")\n\n\ndef isogramas(a_str, b_str):\n    def revisar_palabra(palabra_a_revisar):\n        dict_palabra = dict()\n        for character in palabra_a_revisar:\n            dict_palabra[character] = dict_palabra.get(character, 0) + 1\n\n        isograma = True\n        valores = list(dict_palabra.values())\n        isograma_longitud = valores[0]\n        for word_count in valores:\n            if word_count != isograma_longitud:\n                isograma = False\n                break\n\n        return isograma\n\n    if revisar_palabra(a_str):\n        print(a_str + \" es un Isograma\")\n    if revisar_palabra(b_str):\n        print(b_str + \" es un Isograma\")\n\n\npalindromos(first_word, second_word)\nanagramas(first_word, second_word)\nisogramas(first_word, second_word)\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/Rusanov16.py",
    "content": "\"\"\"\n/*\nEJERCICIO:\nMuestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\nen tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n- Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n  conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n\nDIFICULTAD EXTRA (opcional):\nCrea un programa que analice dos palabras diferentes y realice comprobaciones\npara descubrir si son:\n- Palíndromos\n- Anagramas\n- Isogramas\n\n \"\"\"\n \n#*-------------------------------------------------------------------------------------------------------------#\nprint(\"-----------------------------------------------------------------------------------------------------\")\n\n#ACCESO A CARACTERES\nprint(\"Acceso a los caracteres: \")\npalabra = \"Python\"\nprint(f\"El primer caracter de {palabra} es {palabra[0]}\")\nprint(f\"El quinto caracter de {palabra} es {palabra[4]}\")\nprint(\"-----------------------------------------------------------------------------------------------------\")\n\n#SUBCADENAS\nprint(\"Subcadenas: \")\nprint(f\"Una subcadena de {palabra} en la que se selecciona los primeros cuatro elementos será: {palabra[0:4]}\")\nprint(f\"Una subcadena de {palabra} en la que selecciona los primeros tres elementos pero escogerá los elementos de dos en dos será: {palabra[0:4:2]}\")\nprint(\"-----------------------------------------------------------------------------------------------------\")\n\n#LONGITUD\nprint(\"Longitud: \")\nprint(f\"La longitud de {palabra} es {len(palabra)}\")\nprint(\"-----------------------------------------------------------------------------------------------------\")\n\n#CONCATENACION\nprint(\"Concatenación: \")\nprint(f\"{palabra + \" es el lenguaje utilizado para este reto\"}\")\nprint(\"-----------------------------------------------------------------------------------------------------\")\n\n\n#CONCATENACION\nprint(\"Concatenación: \")\nprint(f\"{palabra + \" es el lenguaje utilizado para este reto\"}\")\nprint(\"-----------------------------------------------------------------------------------------------------\")\n\n#REPETICIÓN\nprint(\"Repetición: \")\nshoo = \"shoo \"\nbee = \"bee \"\nprint(f\"Kendrick - Euphoria: Part II Intro: {shoo * 6 , bee * 6} \")\nprint(\"-----------------------------------------------------------------------------------------------------\")\n\n#RECORRIDO\nprint(\"Recorrido: \")\nfor i in palabra:\n    print(i)\nprint(\"-----------------------------------------------------------------------------------------------------\")\n\n#CONVERSIÓN A MAYÚSCULAS Y MINÚSCULAS\nprint(\"Conversión a Mayúsculas y Minúsculas: \")\nprint(f\"{palabra} en mayúsculas: {palabra.upper()} \")\nprint(f\"{palabra} en minúsculas: {palabra.lower()} \")\n\nprint(\"-----------------------------------------------------------------------------------------------------\")\n\n#REEMPLAZO\nprint(\"Reemplazo: \")\nprint(f\"{palabra} va a ser reemplaza por: {palabra.replace(\"Python\", \"Cobol\")} \")\nprint(\"-----------------------------------------------------------------------------------------------------\")\n\n#DIVISIÓN\nprint(\"División: \")\npalabra_dos = \"Tyler the Creator: Chromakopia\"\nprint(f\"{palabra_dos} va a ser divida en: {palabra_dos.split(\" \")} \")\nprint(\"-----------------------------------------------------------------------------------------------------\")\n\n#UNIÓN\nprint(\"Unión: \")\nsplit_palabra_dos = palabra_dos.split(\" \")\nprint(f\"{split_palabra_dos} va a ser unida en: {\"\".join(split_palabra_dos)} \")\nprint(\"-----------------------------------------------------------------------------------------------------\")\n\n#INTERPOLACIÓN\nprint(\"Interpolación: \")\nnumero = 3673\nprint(f\"El lenguaje {palabra} es el más usado y tiene más de {numero} scripts.\")\nprint(\"-----------------------------------------------------------------------------------------------------\")\n\n#Verificación\nprint(\"Verificación: \")\n\nif \"Tyler\" in palabra_dos:\n    print(f\"Tyler se encuentra en la cadena: {palabra_dos}\")\nprint(\"-----------------------------------------------------------------------------------------------------\")\n\n#*-------------------------------------------------------------------------------------------------------------#\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\nCrea un programa que analice dos palabras diferentes y realice comprobaciones\npara descubrir si son:\n- Palíndromos\n- Anagramas\n- Isogramas\n\"\"\" \ndef palabras():\n\n    def palindromo(palabra):\n        return palabra == palabra[::-1]\n\n    def anagrama(palabra1, palabra2):\n        return sorted(palabra1) == sorted(palabra2)\n\n    def isograma(palabra):\n        return len(palabra) == len(set(palabra))\n\n    def input_palabra(mensaje):\n        while True:\n            palabra = input(mensaje)\n            if isinstance(palabra, str) and palabra.isalpha():\n                return palabra\n            else:\n                print(\"Por favor, introduzca solo letras (sin números ni caracteres especiales).\")\n    \n    primera_palabra = input_palabra(\"Introduzca la primera palabra: \")\n    segunda_palabra = input_palabra(\"Introduzca la segunda palabra: \")\n    print(\"****************************************************************************\")\n    print(\"Palindromo: \")\n    print(f\" La palabra {primera_palabra} es un palíndromo? {palindromo(primera_palabra)}\")\n    print(f\" La palabra {segunda_palabra} es un palíndromo? {palindromo(segunda_palabra)}\")\n    print(\"****************************************************************************\")\n    print(\"Anagrama: \")\n    print(f\" Las palabras {primera_palabra} y {segunda_palabra} son anagramas? {anagrama(primera_palabra, segunda_palabra)}\")\n    print(\"****************************************************************************\")\n    print(\"Isograma: \")\n    print(f\" La palabra {primera_palabra} es un isograma? {isograma(primera_palabra)}\")\n    print(f\" La palabra {segunda_palabra} es un isograma? {isograma(segunda_palabra)}\")\n    print(\"****************************************************************************\")\npalabras()\n\n#*-------------------------------------------------------------------------------------------------------------#"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/Sac-Corts.py",
    "content": "s1 = \"Hola\"\ns2 = \"Python\"\n\n# Concatenación\nprint(s1 + \", \" + s2 + \"!\")\n\n# Repetición\nprint(s1 * 3)\n\n# Indexación\nprint(s1[0] + s1[1] + s1[2] + s1[3])\n\n# Longitud\nprint(len(s2))\n\n# Slicing (porción)\nprint(s2[2:6])\nprint(s2[2:])\nprint(s2[0:2])\nprint(s2[:2])\n\n# Busqueda\nprint(\"a\" in s1)\nprint(\"i\" in s1)\n\n# Reemplazo\nprint(s1.replace(\"o\", \"a\"))\n\n# División\nprint(s2.split(\"t\"))\n\n# Mayúsculas, minúsculas y letras en mayúsculas\nprint(s1.upper())\nprint(s1.lower())\nprint(\"brais moure\".title())\nprint(\"brais moure\".capitalize())\n\n# Eliminación de espacios al principio y al final\nprint(\" brais moure \".strip())\n\n# Búsqueda al principio y al final\nprint(s1.startswith(\"Ho\"))\nprint(s1.startswith(\"Py\"))\nprint(s1.endswith(\"la\"))\nprint(s1.endswith(\"thon\"))\n\ns3 = \"Brais Moure @mouredev\"\n\n# Búsqueda de posición\nprint(s3.find(\"moure\"))\nprint(s3.find(\"Moure\"))\nprint(s3.find(\"M\"))\nprint(s3.lower().find(\"m\"))\n\n# Búsqueda de ocurrencias\nprint(s3.lower().count(\"m\"))\n\n# Formateo\nprint(\"Saludo: {}, lenguje: {}!\".format(s1, s2))\n\n# Interpolación\nprint(f\"Saludo: {s1}, lenguje: {s2}!\")\n\n# Tranformación en lista de caracteres\nprint(list(s3))\n\n# Transformación de lista en cadena\nl1 = [s1, \", \", s2, \"!\"]\nprint(\"\".join(l1))\n\n# Transformaciones numéricas\ns4 = \"123456\"\ns4 = int(s4)\nprint(s4)\n\ns5 = \"123456.123\"\ns5 = float(s5)\nprint(s5)\n\n# Comprobaciones varias\ns4 = \"123456\"\nprint(s1.isalnum())\nprint(s1.isalpha())\nprint(s4.isalpha())\nprint(s4.isnumeric())\n\n\"\"\"\n  DIFICULTAD EXTRA\n\"\"\"\n\n# Un palíndromo es una palabra que se lee igual hacia adelante y hacia atrás.\n# Un anagrama es una palabra formada reordenando las letras de otra palabra, utilizando todas las letras originales exactamente una vez.\n# Un isograma es una palabra en la que ninguna letra se repite.\n\n# Entradas\ndef solicitar_cadena_1():\n    while True:\n        cadena = input(\"Por favor, ingresa la primera palabra: \")\n        # Verifica que la cadena solo contenga caracteres alfabéticos\n        if cadena.isalpha():\n            # Convierte la cadena en minúsculas\n            cadena_minusculas = cadena.lower()\n            return cadena_minusculas\n        else:\n            print(\"Entrada inválida. Por favor, ingresa una palabra que no contenga números, espacios o caracteres especiales.\")\n\n\ndef solicitar_cadena_2():\n    while True:\n        cadena = input(\"Por favor, ingresa la segunda palabra: \")\n        if cadena.isalpha():\n            cadena_minusculas = cadena.lower()\n            return cadena_minusculas\n        else:\n            print(\"Entrada inválida. Por favor, ingresa una palabra que no contenga números, espacios o caracteres especiales.\")\n\n# Comprobaciones\n\n# Función para validar si es un palíndromo\ndef es_palindromo(string):\n    cadena_invertida = \"\".join(reversed(string))\n    if string == cadena_invertida:    \n        print(f\"'{string}'. Es un palíndromo.\") \n    else: \n        print(f\"'{string}'. No un es palíndromo.\")\n\n# Función para validar si son anagramas\ndef es_anagrama(string_1, string_2):\n    palabra_ordenada_1 = sorted(string_1)\n    palabra_ordenada_2 = sorted(string_2)\n    if palabra_ordenada_1 == palabra_ordenada_2:\n        print(f\"'{string_1}' y '{string_2}'. Son anagramas.\")\n    else:\n        print(f\"'{string_1}' y '{string_2}'. No son anagramas.\")\n\n\n# Función para validar si es un isograma\ndef es_isograma(string):\n    palabra_unica = set()\n    for char in string:\n        if char in palabra_unica:\n            return False    \n        else:\n            palabra_unica.add(char) \n    return True\n\n\n# Llamada de funciones\ncadena_1 = solicitar_cadena_1()\ncadena_2 = solicitar_cadena_2()\n\nes_palindromo(cadena_1)\n\nes_anagrama(cadena_1, cadena_2)\n\nif es_isograma(cadena_1):\n    print(f\"'{cadena_1}'. Es un isograma.\")\nelse:\n    print(f\"'{cadena_1}'. No es un isograma.\")\n "
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/SaezMD.py",
    "content": "#04 CADENAS DE CARACTERES\n\n\"\"\"\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\n *   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\n *   interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\"\"\"\n\nprint(\"Hello\") #String between \"\" or ''\n\ntext =  \"\"\" \nmultiple\nlines\nand not limit\n\"\"\"\nprint(text)\n\n#access:\nprint(text[2])\nprint(text[2:6])\n\nfor x in \"fruits\":\n  print(x)\n\nstr01 = \"Hello my friends\"\nstr02 = \"Hello my friend\"\nstr03 = \"Hello my friends\"\n\n#compare strings:\nprint(str01 == str02)\nprint(str02 == str03)\n\n#Join:\nstr05 = \"hello \"\nstr06 = \"my friends\"\nstrUnion = str05+str06\n\nprint(strUnion)\n\n#Lenght:\nprint(len(str01))\n\n#Membership \nprint( \"a\" in \"home\")\nprint( \"h\" in \"home\")\n\n#methods:\nprint(\"baLls\".upper()) #converts the string to uppercase\nprint(\"baLls\".lower()) #converts the string to lowercase\nprint(\"baLls\".swapcase()) #converts all uppercase characters to lowercase and vice versa of the given string and returns it.\nprint(\"balls and sticks\".partition(\"and\")) #The partition method returns a 3-tuple containing:\nsomeText = \"Here you can find the dragons.\"\nprint(someText)\nreplaced = someText.replace(\"dragons\",\">>puppets\") #replaces substring inside\nprint(replaced)\nprint(replaced.find(\"you\")) #returns the index of first occurrence of substring\nanotherText=\"Help me please.    \"\nprint(anotherText.rstrip()) #returns a copy of the string with trailing characters removed (based on the string argument passed).\nprint(replaced.split()) #breaks down a string into a list of substrings using a chosen separator.\nprint(replaced.startswith(\"H\")) #\tchecks if string starts with the specified string\nprint(\"126\".isnumeric()) #checks numeric characters\nprint(\"126aa\".isalnum()) #checks numeric and alphabet characters\nprint(replaced.index(\"n\")) #returns the index of a substring inside the string (if found). If the substring is not found, it raises an exception.\n\n#Escape Sequences\nspecialText = \"Mariló can \\\"play\\\" guitar\" # use the character: \\ to skip special characters\n\n# f-Strings\nname = \"Camela\"\nsurname = \"Analisais\"\nprint(f'{name} is from {surname}') #Python f-Strings make it really easy to print values and variables.\ndel name # delete whole string\n\n# format\nString1 = \"{} {} {}\".format('Help', 'Me', 'Baby') \nprint(String1) \n\n# Formatting of Integers\nnumber = 16\nString1 = \"{0:b}\".format(number) \nprint(f\"\\nBinary representation of {number} is: {String1}\") \n  \n# Formatting of Floats \nString1 = \"{0:e}\".format(165.6458) \nprint(f\"\\nExponent representation of 165.6458 is: {String1}\") \n  \n# Rounding off Integers \nString1 = \"{0:.2f}\".format(1/6) \nprint(f\"\\nOne-sixth is : {String1}\")\n\n#sort strings:\nsurname = \"Analisais\"\nsorted = sorted(surname)\nprint(sorted)\n\n#Count currents\nprint(surname.lower().count(\"a\"))\n\n\nprint()\nprint()\n\ndef cleanWords(word: str)-> str:\n    \"\"\"clean special characters and transform to lowercase\"\"\"\n    from unidecode import unidecode\n    # Remove special characteres, spaces and punctuation\n    cleanStr = ''.join(filter(str.isalpha, word))\n    cleanStr = unidecode(cleanStr)\n    # Convert to lowercase\n    lowerStr = cleanStr.lower()\n\n    return lowerStr\n\n\ndef checkPalindromes(word1: str, word2: str) -> bool:\n  \"\"\"function to detect if 2 words are palindromes ( is a word, number, phrase, or other sequence of symbols that reads the same backwards as forwards, such as madam or racecar)\"\"\"\n  #Check palindrome\n  if cleanWords(word1) != cleanWords(word2)[::-1]:\n    return False\n  else:\n    return True\n\ndef checkAnagrams(word1: str, word2: str) -> bool:\n  \"\"\"function to detect if 2 words are anagrams (An anagram is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.)\"\"\"\n  #sort the letters in the string\n  list1 = list(cleanWords(word1))\n  list1.sort()\n\n  list2 = list(cleanWords(word2))\n  list2.sort()\n\n  if list1 != list2:\n    return False\n  else:\n    return True\n  \ndef checkIsograms(word: str) -> bool:\n  \"\"\"function to detect if 2 words are isograms (A word or phrase in which each letter occurs the same number of times.)\"\"\"\n  listOfWord = list(cleanWords(word))\n  listOfWord.sort()\n  \n  for i in range(0,len(listOfWord)-1):\n    if listOfWord[i] == listOfWord[i+1]:\n      return False\n    else:\n      return True\n\ndef checkIsogramsMoure(word: str) -> bool:\n  \"\"\"function to detect if 2 words are isograms (A word or phrase in which each letter occurs the same number of times.)\"\"\"\n  listOfWord = cleanWords(word)\n  \n  wordDict = dict()\n  for character in listOfWord:\n    wordDict[character] = wordDict.get(character,0) + 1\n\n  isogram = True\n  values = list(wordDict.values())\n  isogramLen = values[0]\n  for wordCount in values:\n    if wordCount != isogramLen:\n      isogram = False\n      break\n  \n  return isogram\n\n\ndef checkWords(word1: str, word2: str) -> str:\n  \"\"\"check 2 words if they are: palindromes, anagrams or/and isograms\"\"\"\n  print(f\"{word1} and {word2} Palindormes: \", checkPalindromes(word1, word2))\n  print(f\"{word1} and {word2} Anagrams: \", checkAnagrams(word1,word2))\n  print(f\"Isograms: {word1}: {checkIsograms(word1)}, {word2}: {checkIsograms(word2)}\") \n\ncheckWords(\"ratoN\", \"notar\")\ncheckWords(\"camAc\", \"cAmÁc\")\ncheckWords(\"diálogo\", \"cÄmero\")\ncheckWords(\"Diálogo\", \"caMero\")\n\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/SergioGI99.py",
    "content": "\"\"\"\n--------------------\nCADENA DE CARACTERES\n--------------------\nEJERCICIO:\nMuestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\nen tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n- Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\n  recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\n  interpolación, verificación...\n\nDIFICULTAD EXTRA (opcional):\nCrea un programa que analice dos palabras diferentes y realice comprobaciones\npara descubrir si son:\n- Palíndromos\n- Anagramas\n- Isogramas\n\"\"\"\n\n# Ejercicio\n\nmy_string: str = \"Esto es un string de prueba \"\nmy_otherString: str = \"Esto es otro string de prueba\"\n\n# Acceso a caracteres específicos\nprint(my_string.find(\"es\"))\n\n# Subcadenas\nmy_subString: str = my_string[11:17]\nprint(my_subString)\n\nmy_other_subString: str = \"es\"\nprint(my_other_subString in my_string) # Devuelve un bool\n\n# Longitud\nprint(len(my_string)) # my_string tiene 27 caracteres\n\n# Concatenación\nprint(my_string + my_otherString)\n\n# Repetición\nprint(my_string * 2)\n\n# Mayusculas\nprint(my_string.upper())\n\n# Reemplazo\nmy_new_string: str = my_string.replace(\"un string\", \"una cadena de texto\")\nprint(my_new_string)\n\n# División\ndivided_string: str = my_string[11:17]\nprint(divided_string)\n\n# Interpolación\nprint(f\"Esto es un {divided_string.upper()} interpolado\")\n\n# Verificación\nprint(my_string.isalpha()) # Devuelve False porque los espacios no son alfabeticos\nmy_last_string = \"Hola\"\nprint(my_last_string.isalpha()) # Devuelve True\n\n\n# EJERCICIO EXTRA\n\nprint(\"Vamos a comprovar si dos palabras son Palíndromos, Anagramas o Isogramas\")\nword_one: str = (input(\"Primera palabra: \")).lower()\nword_two: str = (input(\"Segunda palabra: \")).lower()\n\ndef invertir_cadena(cadena):\n    cadena_invertida = \"\"\n    for letra in cadena:\n        cadena_invertida = letra + cadena_invertida\n    return cadena_invertida\n\ndef esAnagrama(cad1, cad2):\n    return sorted(cad1) == sorted(cad2)\n\ndef esIsograma(word: str) -> bool:\n    leter_dict = {}\n    for leter in word:\n        if leter in leter_dict:\n            leter_dict[leter] += 1\n        else:\n            leter_dict[leter] = 1\n\n    values = list(leter_dict.values())\n    isogram_len = values[0]\n    for leter_count in values:\n        if leter_count != isogram_len:\n            return False\n    return True\n\nif invertir_cadena(word_one) == word_two:\n    print(f\"{word_one} y {word_two} son palíndromos\")\nelse:\n    print(f\"{word_one} y {word_two} no son palíndromos\")\n\nif esAnagrama(word_one, word_two):\n    print(f\"{word_one} y {word_two} son anagramas\")\nelse:\n    print(f\"{word_one} y {word_two} no son anagramas\")\n\nif esIsograma(word_one):\n    print(f\"{word_one} es un Isograma\")\nelse:\n    print(f\"{word_one} no es un Isograma\")\n\nif esIsograma(word_two):\n    print(f\"{word_two} es un isograma\")\nelse:\n    print(f\"{word_two} no es un isograma\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/SooHav.py",
    "content": "#04 CADENAS DE CARACTERES\n\n#Operaciones con cadenas de caracteres\ntexto = \"¡Hola Mundo!\"\nprint(texto) # ¡Hola Mundo!\nprint(type(texto)) # <class 'str'>\n\n# Operador de suma y concatenación\ntexto1 = \"¡Hola\"\ntexto2 = \"Mundo!\"\nsaludo = texto1 + \" \" + texto2\nprint(saludo) # ¡Hola Mundo!\n\nlista_texto = ['Python', 'saluda', 'con', '¡Hola', 'Mundo!']\nseparador = \" \"\nmensaje = separador.join(lista_texto)\nprint(mensaje) # Python saluda con ¡Hola Mundo!\n\ntexto1 = \"¡Hola\"\ntexto2 = \" Mundo!\"\ntexto1 += texto2\nprint(texto1)\n\n# Operador de multiplicación\ntexto  = \"¡Hola!\"\neco = texto * 3\nprint(eco) # ¡Hola! ¡Hola! ¡Hola!\n\n# Operador len (longitud)\ntexto = \"¡Hola Mundo!\"\nlongitud = len(texto)\nprint(longitud) # 12\n\n#Operdaores para subcadenas y caracteres epecíficos\ntexto = \"¡Hola Mundo!\"\nprint(texto[0:6:2]) # ¡oa\n\ntexto = \"En el lenguaje de Python, el primer paso es siempre decir ¡Hola Mundo! y comenzar la magia.\"\nsubcadena = texto[58:70]\nprint(subcadena) # ¡Hola Mundo!\n\ntexto = \"¡Hola Mundo!\"\nprint(texto[0])  #¡\nprint(texto[-1]) #!\n\n#Encontrar caracteres específicos\ntexto = \"¡Hola mundo!\"\nprint(texto.find(\"o\")) # 2\nprint(texto.find(\"¡\")) # 0\nprint(texto.rfind(\"o\")) # 10\nprint(texto.index(\"mun\")) # 6\n#print(texto.index(\"x\")) # ValueError: substring not found\n\n#Conversión a mayúsculas y minúsculas\ntexto = \"Python saluda con ¡Hola Mundo!\"\nprint(texto.capitalize()) # Python saluda con ¡hola mundo!\nprint(texto.upper()) # PYTHON SALUDA CON ¡HOLA MUNDO!\nprint(texto.lower()) # python saluda con ¡hola mundo!\n\n#Contar la repeticion de un caracter o una subcadena\ntexto = \"¡Hola Mundo!\"\nprint(texto.count(\"o\")) # 2\n\n#Division de un texto\ntexto = \"Python saluda con ¡Hola Mundo!\"\nlista_del_texto = texto.split(\" \")\nprint(lista_del_texto) # ['Python', 'saluda', 'con', '¡Hola', 'Mundo!']\n\n#Reemplazo de una cadena o parte de una cadena\ntexto = \"Python saluda con ¡Hola Mundo!\"\ntexto = texto.replace(\"saluda con ¡Hola Mundo!\", \"es uno de los lenguajes más usados.\")\nprint(texto) # Python es uno de los lenguajes más usados.\n\n#Verificación\ntexto = \"Python saluda con ¡Hola Mundo!\"\nprint(\"saluda\" in texto) #True\nprint(texto.startswith(\"Python\")) # True\nprint(texto.endswith(\"do!\")) # True\nprint(texto.isalpha())  # True\n\n#Interpolacion de un string\nlenguaje = \"Python\"\nranking = 3\nanio = 2023\n\ntexto = f\"{lenguaje} estuvo en el puesto {ranking} en el ranking de los lenguajes de programación durante {anio}.\" # con f-strings\nprint(texto)\n\ntexto = \"{} estuvo en el puesto {} en el ranking de los lenguajes de programación durante {}.\".format(lenguaje, ranking,anio) #con format()\nprint(texto)\n\ntexto = \"%s estuvo en el puesto %d en el ranking de los lenguajes de programación durante %d.\" % (lenguaje, ranking, anio) # con formatting()\nprint(texto)\n\n#Recorrido\ntexto = \"¡Hola Mundo!\"\n\n# Recorrido utilizando un bucle for\nfor caracter in texto: #bucle for\n    print(caracter)\n\nfor indice, caracter in enumerate(texto):  #con índices\n    print(f\"Índice: {indice}, Carácter: {caracter}\")\n\n#Otras\ntexto = \"  ¡Hola Mundo!  \"\nprint(texto.strip()) #elimina espacios en blanco start y end\n\ntexto = \"abc\"\nprint(texto.zfill(5)) #00abc agrega ceros adelante\n\ntexto = \"calcuta\"\nmi_set = set(texto)\nprint(mi_set)\n\n\"\"\"\nPalíndromo: Un palíndromo es una palabra, frase, número u otra secuencia de caracteres que se lee igual hacia \nadelante que hacia atrás. Los palindromos pueden llegar a ser anagramas si se cumple la condicion.\nEjemplo: \"reconocer\", \"anilina\".\n\nAnagrama: Un anagrama es una palabra o frase que resulta de la transposición de letras de otra palabra o frase. \nEs decir, que usa todas las letras originales exactamente una vez.\nEjemplo: \"amor\" y \"roma\" y \"mora\" y \"ramo\", \"monja\" y \"jamon\", \"lamina\" y \"animal\", \"esponja\" y \"japones\"\n\nIsograma: Un isograma es una palabra o frase en la que no hay letras repetidas; cada letra aparece una sola vez.\nLos isogramas pueden llegar a ser anagramas si se cumple la condicion.\nEjemplo: \"murciélago\".\n\"\"\"\n\ndef comparacion_palabras(palabra_1, palabra_2):\n    palabra_1_invertida = palabra_1[::-1].lower()\n    palabra_2_invertida = palabra_2[::-1].lower()\n    resultados = []\n\n    if palabra_1 != palabra_2:\n        if palabra_1_invertida == palabra_1:\n            resultados.append(f\"La palabra {palabra_1_invertida} es palíndromo.\")\n\n        if palabra_2_invertida == palabra_2:\n            resultados.append(f\"La palabra {palabra_2_invertida} es palíndromo.\")\n\n        if len(set(palabra_1)) == len(palabra_1):\n            resultados.append(f\"La palabra {palabra_1} es isograma.\")\n\n        if len(set(palabra_2)) == len(palabra_2):\n            resultados.append(f\"La palabra {palabra_2} es isograma.\")\n\n        if sorted(palabra_1) == sorted(palabra_2):\n            resultados.append(f\"Las palabras {palabra_1} y {palabra_2} son anagramas.\")\n\n        if len(resultados) == 0:\n            resultados.append(f\"Las palabras {palabra_1} y {palabra_2} no cumplen con ninguna condición.\")\n    else:\n        print(f\"Las palabras {palabra_1} y {palabra_2} son identicas.\")\n\n    return resultados\n\nresultados = comparacion_palabras(\"murciélago\", \"anilina\")\n\nfor resultado in resultados:\n    print(resultado)\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/ThePhobos01.py",
    "content": "#Diferentes opciones que tenemos con cadenas de caracteres (String) en Pyuthon\n\n#Imprimir una cadena\nprint('Hola mundo!')\n\n#Concatenar\nprint('Hola ' + 'Mundo')\n\n#Multiplicar\nprint('Hola ' * 3 + 'Mundo')\n\n#Longitud\n\nprint(len('Hola mundo!'))\n\n#Encontrar\n\nsaludo = 'Hola Mundo!'\n\nsaludo = saludo.find('Mundo!')\n\nprint(saludo)\n\n#Poner en minusculas\nprint('Hola mundo!'.lower())\n\n#Poner en mayusculas\nprint('Hola Mundo!'.upper())\n\n#Reemplazar\nprint('Hola Mundo!'.replace('Mundo!', 'Python!'))\n\n#Cortar\nprint('Hola Mundo!'[1:8])\n\n\n#Dificultad extra\n\ndef es_palindromo(palabra):\n    palabra = palabra.replace(\" \", \"\").lower()\n    return palabra == palabra[::-1]\n\ndef es_anagrama(palabra1, palabra2):\n    palabra1 = palabra1.replace(\" \", \"\").lower()\n    palabra2 = palabra2.replace(\" \", \"\").lower()\n    return sorted(palabra1) == sorted(palabra2)\n\ndef es_isograma(palabra):\n    palabra = palabra.replace(\" \", \"\").lower()\n    return len(palabra) == len(set(palabra))\n\ndef analizar_palabras(palabra1, palabra2):\n    print(f\"Analizando las palabras: '{palabra1}' y '{palabra2}'\")\n    \n    if es_palindromo(palabra1):\n        print(f\"'{palabra1}' es un palíndromo.\")\n    if es_palindromo(palabra2):\n        print(f\"'{palabra2}' es un palíndromo.\")\n    \n    if es_anagrama(palabra1, palabra2):\n        print(f\"'{palabra1}' y '{palabra2}' son anagramas.\")\n    else:\n        print(f\"'{palabra1}' y '{palabra2}' no son anagramas.\")\n    \n    if es_isograma(palabra1):\n        print(f\"'{palabra1}' es un isograma.\")\n    else:\n        print(f\"'{palabra1}' no es un isograma.\")\n    if es_isograma(palabra2):\n        print(f\"'{palabra2}' es un isograma.\")\n    else:\n        print(f\"'{palabra2}' no es un isograma.\")\n\nanalizar_palabras(\"reconocer\", \"roma\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/TheReDNooB.py",
    "content": "#concatenacion\nhello = \"Hello World\" + \"!\"\nprint(hello)\n\n#slicing\ncountries = \"Venezuela, Colombia, Brasil, Argentina, Chile, Paraguay, Uruguay, Bolivia\"\nprint(countries[0:5])\nprint(countries[10:18])\nprint(countries[19:27])\n\n#upercase\nfruit = \"apple\"\nprint(fruit.upper())\n\n#lowercase\nfruit = \"APPLE\"\nprint(fruit.lower())\n\n#remove space\nfruit = \" apple \"\nprint(fruit.strip())\n\n#split\nfruits = \"apple,banana,orange\"\nprint(fruits)\nprint(fruits.split(\",\"))\n\n#concatenar\nnumber = \"noventa\"\nprint(number + \" y ocho\")\n\n# String methods\n\n#capitalize\ntxt = [\"hello\",\"and\", \"welcome\",\"to\",\"my\",\"world\"]\nfor i in txt:\n    print(i.capitalize())\n\n#casefold\ntxt = [\"Hello\",\"And\", \"Welcome\",\"TO\",\"My\",\"World\"]\nfor i in txt:\n    print(i.casefold())\n\n#center\ntxt = \"banana\"\nprint(txt.center(20,\"*\"))\n\n#count\ntxt = \"I love the chocolate and the apples, the chocolate is my favorite\"\nprint(txt.count(\"chocolate\"))\n\n#encode\ntxt = \"My name is Ståle\"\nprint(txt.encode(encoding=\"ascii\",errors=\"backslashreplace\"))\n\n#endwith\ntxt = \"Hello, welcome to my world.\"\ny = txt.endswith(\"red\")\nx = txt.endswith(\".\")\nprint(x,y)\n\n#expand tabs\ntxt = \"H\\te\\tl\\tl\\to\"\n\nprint(txt)\nprint(txt.expandtabs())\nprint(txt.expandtabs(2))\nprint(txt.expandtabs(4))\nprint(txt.expandtabs(10))\n\n#find\ntxt = \"Hello, welcome to my world.\"\nprint(txt.find(\"welcome\",2,20))\nprint(txt.find(\"world\",2,20))\n\n#format\ntxt = \"the price is {} dollars\\n\".format(500)\ntxt2 = \"My name is {0}, I'm {1}\".format(\"John\",36)\nprint(txt,txt2)\n\n#index\ntxt = \"Hello, welcome to my world.\"\nprint(txt.index(\"welcome\"))\nprint(txt.index(\"world\",2))\n\n#extra\n\ndef check_word(msg1, msg2:str):\n    #polindromo\n    print(f\"¿{msg1} es un polindromo? {msg1 == msg1[::-1]}\")\n    print(f\"¿{msg2} es un polindromo? {msg2 == msg2[::-1]}\")\n\n    #anagramas\n    print(f\"¿{msg1} y {msg2} son anagramas? {sorted(msg1) == sorted(msg2)}\")\n\n    #isogramas\n    def isogram(word:str) -> bool:\n        word_dict = dict()\n        for character in word:\n            word_dict[character] = word_dict.get(character, 0) + 1\n        \n        isogram = True\n        values = list(word_dict.values())\n        isogram_len = values[0]\n        for word_count in values:\n            if word_count != isogram_len:\n                isogram = False\n                break\n        return isogram\n    print(f\"¿{msg1} es un isograma? {isogram(msg1)}\")\n    print(f\"¿{msg2} es un isograma? {isogram(msg2)}\")\n\ncheck_word(\"oso\",\"hola\")\ncheck_word(\"amor\",\"roma\")\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/Tomu98.py",
    "content": "\"\"\" Reto 04: Cadena de Caracteres \"\"\"\n\n\"\"\" Operaciones \"\"\"\n\ns1 = \"Hola\"\ns2 = \"Python\"\ns3 = \"Abel Tomás @Tomu98\"\n\n# Concatenación\nprint(s1 + \" \" + s2 + \"!\")\n\n# Repetición\nprint(s1 * 3)\n\n# Indexación\nprint(s1[0] + s1[1] + s1[2] + s1[3])\n\n# Longitud\nprint(len(s2))\n\n# Slicing (porción)\nprint(s2[2:6])\nprint(s2[2:])\nprint(s2[0:2])\nprint(s2[:2])\n\n# Búsqueda\nprint(\"a\" in s1)\nprint(\"i\" in s1)\n\n# Reemplazo\nprint(s1.replace(\"o\", \"a\"))\n\n# División\nprint(s2.split(\"t\"))\n\n# Mayúsculas, minúsculas y primera letra en mayúsculas\nprint(s1.upper())\nprint(s1.lower())\nprint(\"abel tomás\".title())\nprint(\"abel tomás\".capitalize())\n\n# Eliminación de espacios al principio y al final\nprint(\" Abel Tomás \".strip())\n\n# Búsqueda al principio y al final\nprint(s1.startswith(\"Ho\"))\nprint(s1.startswith(\"Py\"))\nprint(s1.endswith(\"la\"))\nprint(s1.endswith(\"thon\"))\n\n# Búsquda de posición\nprint(s3.find(\"Tomu\"))\nprint(s3.find(\"Abel\"))\nprint(s3.find(\"T\"))\nprint(s3.lower().find(\"u\"))\n\n# Búsqueda de ocurrencias\nprint(s3.lower().count(\"m\"))\n\n# Formateo\nprint(\"Saludo: {}, lenguaje: {}!\".format(s1, s2))\n\n# Interpolación\nprint(f\"Saludo: {s1}, lenguaje: {s2}!\")\n\n# Transformación en lista de caracteres\nprint(list(s3))\n\n# Transformación de lista en cadena\nl1 = [s1, \", \", s2, \"!\"]\nprint(\"\".join(l1))\n\n# Transformaciónes númericas\ns4 = \"123456\"\ns4 = int(s4)\nprint(s4)\n\ns5 = \"123456.12\"\ns5 = float(s5)\nprint(s5)\n\n# Comprobaciones varias\ns4 = \"123456\"\n#print(s1.isalnum())\n#print(s1.isalpha())\n#print(s4.isalpha())\n#print(s4.isnumeric())\n\n\n\n\"\"\" Reto extra \"\"\"\n\ndef analize_string(word1: str, word2: str):\n    # Palíndromo\n    print(f\"¿{word1} es un palíndromo?: {word1.lower() == word1[::-1].lower()}\")\n    print(f\"¿{word2} es un palíndromo?: {word2.lower() == word2[::-1].lower()}\")\n\n    # Anagrama\n    print(f\"¿{word1} es anagrama de {word2}?: {sorted(word1.lower()) == sorted(word2[::-1].lower())}\")\n\n    # Isograma\n    def isogram(word: str) -> bool:\n        word_dict = dict()\n        for char in word:\n            word_dict[char] = word_dict.get(char, 0) + 1\n\n        isogram = True\n        values = list(word_dict.values())\n        isogram_len = values[0]\n        for word_count in values:\n            if word_count != isogram_len:\n                isogram = False\n                break\n\n        return isogram\n\n    print(f\"¿{word1} es un isograma?: {isogram(word1)}\")\n    print(f\"¿{word2} es un isograma?: {isogram(word2)}\")\n\nanalize_string(\"Tommu\", \"Python\")\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/TroyNebula.py",
    "content": "'''\r\nEJERCICIO:\r\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\r\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\r\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\r\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\r\n'''\r\n# Cadena vacía\r\ncadena_vacía=\"\"\r\n\r\n# Cadenas simples\r\nprint(\"Cadena de texto\")\r\nprint('Cadena de texto')\r\nprint(\"Cadena de 'texto'\")\r\n\r\n# Cadenas multilínea, tiene en cuenta el vacío tras las tres comillas mostrando una línea en blanco.\r\npoema_Poe = \"\"\"\r\nY el Cuervo nunca emprendió el vuelo.\r\nAún sigue posado, aún sigue posado\r\nen el pálido busto de Palas.\r\nen el dintel de la puerta de mi cuarto.\r\n\"\"\"\r\nprint(poema_Poe)\r\n\r\n# Encontrar la primera ocurrencia de alguna subcadena\r\nprint(poema_Poe.find(\"el\"))\r\nprint(poema_Poe.index(\"el\"))\r\n\r\n# Contabilizar el número de veces que aparece una subcadena\r\nprint(poema_Poe.count(\"el\"))\r\n\r\n# Reemplazar elementos\r\nprint(poema_Poe.replace('posado', 'volando'))\r\n\r\n# Separar textos por saltos de línea \\n\r\nprint(\"Este texto sale en una línea \\ny este en la segunda línea.\")\r\nprint(\"Esto no pinta\\nnada\")\r\n\r\n# Formato de cadena de texto sin procesar (raw string)\r\nprint(r\"Esto no pinta\\nada\")\r\n\r\n# Tabulador\r\nprint('Valor = \\t40')\r\n\r\n# Otra manera de mostrar comilla simple\r\nprint('Necesitamos \\'escapar\\' la comilla simple')\r\n\r\n# Barra invertida\r\nprint ('Capítulo \\\\ Sección \\\\ Encabezado')\r\n\r\n# Conversión\r\nprint(str(True))\r\nprint(str(10))\r\n\r\n# Separadores a la hora de imprimir textos\r\nmsg1 = '¿Estás ahí?'\r\nmsg2 = 'No estoy.'\r\nprint(msg1, msg2) # por defecto la coma  hace un espacio\r\nprint(msg1, msg2, sep='|')\r\nprint(msg2, end='!!')\r\n\r\n# Concatenación Unir cadenas de textos\r\nproverb1 = 'Cuando el río suena'\r\nproverb2 = 'agua lleva'\r\nprint(proverb1 + proverb2) #los une sin espacio\r\nprint(proverb1 + ', ' + proverb2)  # incluimos una coma\r\n\r\n# May y min\r\nprint(proverb2.capitalize())  # La primera palabra comienza con mayúsculas\r\nprint(proverb2.title()) # Todas las palabras cominezan con mayúsculas\r\nprint(proverb2.upper()) # Todas las palabras con mayúsculas\r\nprint(proverb1.lower()) # Todas las palabras con minúsculas\r\n\r\n# Repetir cadenas\r\nreaction = 'Wow'\r\nprint(reaction * 4)\r\n\r\n# Obtener un carácter\r\nsaludo = 'Hola, Mundo'\r\nprint(saludo[0]) # muestra un índice concreto\r\nprint(saludo[:]) # muestra todo\r\nprint(saludo[5:]) # muestra desde la posición 5, incluida\r\nprint(saludo[:6]) # muestra hasta la posición 6, incluida\r\nprint(saludo[0:3]) # muestra desde la 0 a la 3 incluidas\r\nprint(saludo[1:8:3]) # muestra [start:end:step] incluye el 1, excluye el 8 y salta de 3 en 3\r\n\r\n# Longitud de la cadena\r\nprint(len(saludo))\r\nprint(len(cadena_vacía))\r\n\r\n# Comprobar que una determinada subcadena se encuentra en una cadena de texto\r\nprint(\"Hola\" in saludo)\r\nprint(\"Hola\" not in saludo)\r\n\r\n# Limpiar cadenas\r\ntexto_a_limpiar = \"   -Hola mundo-   \"\r\nprint (texto_a_limpiar)  \r\nprint(texto_a_limpiar.strip()) # solo limpia espacios, si empieza con algún símbolo o letra no los borra\r\nprint(texto_a_limpiar.lstrip()) #left\r\nprint(texto_a_limpiar.rstrip()) #right\r\nprint(texto_a_limpiar.strip(\"-\"))  #funciona si está al principo o final\r\ntexto_a_limpiar2 = \"-   Hola mundo   -\"\r\nprint(texto_a_limpiar2.strip(\"-\"))  #funciona si está al principo o final\r\n\r\n# Empieza o termina por alguna subcadena\r\nprint(msg2.startswith(\"N\"))\r\nprint(msg2.endswith(\".\"))\r\n\r\n# Identificando caracteres\r\nprint('R2D2'.isalnum()) # Detectar si todos los caracteres son letras o números\r\nprint('C3-PO'.isalnum())\r\nprint('314'.isnumeric()) # Detectar si todos los caracteres son números\r\nprint('3.14'.isnumeric())\r\nprint('abc'.isalpha()) # Detectar si todos los caracteres son letras\r\nprint('BIG'.isupper()) # Detectar mayúsculas/minúsculas\r\nprint('BIG'.islower()) \r\nprint('Primera Instancia'.istitle())\r\n\r\n# Formato\r\nx = 10\r\nprint(f'La variable x es = {x}')\r\nprint(\"La variable x es =\", x)\r\nprint('La variable x es = {}'.format(x))\r\n\r\n# Caracteres Unicode\r\n# Fuente: https://symbl.cc/en/unicode/blocks/\r\nrocket_code = 0x1F680\r\nrocket = chr(rocket_code) # La función chr() permite representar un carácter a partir de su código\r\nprint (rocket) # cohete\r\n\r\nrocket_code = hex(ord(rocket))\r\nprint(rocket_code) # La función ord() permite obtener el código (decimal) de un carácter a partir de su representación\r\n\r\nprint('\\N{ROCKET}') #El modificador \\N permite representar un carácter a partir de su nombre\r\nprint('\\N{SNAKE}')\r\n\r\n\r\n'''\r\n * DIFICULTAD EXTRA (opcional):\r\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\r\n * para descubrir si son:\r\n * - Palíndromos\r\n * - Anagramas\r\n * - Isogramas\r\n '''\r\n\r\npalabra_a_comprobar= \"\"\r\npalabras_a_comprobar= \"\"\r\npalabras_a_comprobar2= \"\"\r\n\r\n# Palíndromo, misma palabra que se lee igual al derecho que al revés\r\ndef palindromo (palabra_a_comprobar):\r\n    inverso= palabra_a_comprobar[::-1] # Invierto un str\r\n    inverso2 = ''.join(reversed(palabra_a_comprobar)) # Otra forma\r\n    #print(palabra_a_comprobar, inverso, inverso2)\r\n    if palabra_a_comprobar.lower() == inverso.lower():\r\n        print(palabra_a_comprobar, \" es un palíndromo.\")\r\n        menu()\r\n    else:\r\n        print(\"Prueba con otra cosa, no lo es.\")\r\n        menu()\r\n\r\n# Anagrama, dos palabras que se leen igual al derecho que al revés\r\ndef anagrama (palabras_a_comprobar, palabras_a_comprobar2):\r\n    ordenado2=sorted(palabras_a_comprobar.lower())  # Devuelve una lista de caracteres ordenados alfabéticamente\r\n    ordenado3=sorted(palabras_a_comprobar2.lower())\r\n    if ordenado2 == ordenado3:  \r\n        print(f\"Las palabras {palabras_a_comprobar} y {palabras_a_comprobar2}, son un anagrama.\")\r\n        menu()\r\n    else:\r\n        print(\"Prueba con otra cosa, no lo son.\")\r\n        menu()\r\n\r\n# Isograma, una palabra o frase en la que no hay letras repetidas\r\ndef isograma (palabra_a_comprobar):\r\n    if len(set(palabra_a_comprobar.lower())) == len(palabra_a_comprobar.lower()):  \r\n        # al convertirlo en set elimina lo duplicado y si el largo sigue siendo el mismo, lo es\r\n        print(palabra_a_comprobar, \" es un palíndromo.\")\r\n        menu()\r\n    else:\r\n        print(\"Prueba con otra cosa, no lo es.\")\r\n        menu()\r\n\r\ndef menu():\r\n    opcion = input (\"1. Comprobar palíndromo\\n2. Comprobar Anagrama\\n3. Comprobar isograma\\n4. Salir\\nElige una opción:\")\r\n\r\n    if opcion == \"1\":\r\n        palabra_a_comprobar= input(\"Introduce una palabra para comprobar:\")\r\n        print (\"Has introducido:\", palabra_a_comprobar)\r\n        palindromo(palabra_a_comprobar)\r\n    elif opcion == \"2\":\r\n        palabras_a_comprobar= input(\"Introduce una palabra para comprobar:\")\r\n        palabras_a_comprobar2= input(\"Introduce otra palabra para comprobar:\")\r\n        print (\"Has introducido:\", palabras_a_comprobar,\"y\", palabras_a_comprobar2)\r\n        anagrama (palabras_a_comprobar, palabras_a_comprobar2)\r\n    elif opcion == \"3\":\r\n        palabra_a_comprobar= input(\"Introduce una palabra para comprobar:\")\r\n        print (\"Has introducido:\", palabra_a_comprobar)\r\n        isograma(palabra_a_comprobar)\r\n    else:\r\n        print (\"¡Hasta luego cocodrilo!\")\r\n        quit()\r\n\r\nmenu()\r\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/VictorRivero1204.py",
    "content": "\"\"\"\nOperaciones\n\"\"\"\n\ns1 = \"Hola\"\ns2 = \"Python\"\n\n# Concatenacion\nprint(s1 + \", \" + s2 + \"!\")\n\n# Repeticion\nprint(s1 * 3)\n\n# Indexacion\nprint(s1[0] + s1[1] + s1[2] + s1[3])\n\n# Longitud\nprint(len(s2))\n\n# Slicing (porcion)\nprint(s2[2:6])\nprint(s2[2:])\nprint(s2[0:2])\nprint(s2[:2])\n\n# Busqueda\nprint (\"a\" in s1)\nprint (\"i\" in s1)\n\n# Reemplazo\nprint(s1.replace(\"o\", \"a\"))\n\n# Division\nprint(s2.split(\"t\"))\n\n# Mayusculas, minusculas y letras en mayusculas\nprint(s1.upper())\nprint(s1.lower())\nprint(\"victor rivero\".title())\nprint(\"victor rivero\".capitalize())\n\n# Eliminacion de espacios al inicio y al final\nprint(\" victor rivero \".strip())\n\n# Busqueda al principio y al final \nprint(s1.startswith(\"Ho\"))\nprint(s1.startswith(\"Py\"))\nprint(s1.endswith(\"la\"))\nprint(s1.endswith(\"thon\"))\n\ns3 = \"Victor rivero @VictorRivero\"\n\n# Busqueda de posicion \nprint(s3.find(\"rivero\"))\nprint(s3.find(\"Rivero\"))\nprint(s3.find(\"r\"))\nprint(s3.lower().find(\"ri\"))\n\n# Busqueda de ocurrencias\nprint(s3.lower().count(\"victor\"))\n\n# Formateo\nprint(\"Saludo: {}, lenguaje: {}!\".format(s1, s2))\n\n# Interpolacion \nprint(f\"Saludo: {s1}, lenguaje: {s2}!\")\n\n# Transformacion en lista de caracteres\nprint(list(s3))\n\n# Transformacion de lista en cadena\nl1 = [s1, \", \", s2, \"!\"]\nprint(\"\".join(l1))\n\n# Transformaciones numericas\ns4 = \"123456\"\ns4 = int(s4)\nprint(s4)\n\ns5 = \"123.456\"\ns5 = float(s5)\nprint(s5)\n\n# Comprobaciones varias\ns4 = \"123456\"\nprint(s1.isalnum())\nprint(s1.isalpha())\nprint(s4.isalpha())\nprint(s4.isnumeric()) \n\n\"\"\"\n Extra\n\"\"\"\n\ndef check(word1: str, word2: str):\n\n    #Palindromos\n    print(f\"¿{word1}es un palindromo?: {word1 == word1[::-1]}\") \n    print(f\"¿{word2}es un palindromo?: {word2 == word2[::-1]}\") \n\n    #Anagramas\n    print(f\"¿{word1} es anagrama de {word2}?: {sorted(word1) == sorted(word2)}\")\n\n    #isogramas\n\n    def isogram(word: str) -> bool:\n\n        word_dict = dict()\n        for character in word:\n            word_dict[character] = word_dict.get(character, 0) + 1\n\n        isogram = True\n        values = list(word_dict.values())\n        isogram_len = values[0]\n        for word_count in values:\n            if word_count != isogram_len:\n                isogram = False\n                break\n\n        return isogram\n\n    print(f\"¿{word1} es un isograma?: {isogram(word1)}\")\n    print(f\"¿{word2} es un isograma?: {isogram(word2)}\")\n\n\ncheck(\"radar\", \"pythonpython\")\ncheck(\"amor\", \"roma\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/Yani-Git.py",
    "content": "#Cadenas de caracteres \n\n\"\"\"\nOperaciones \n\"\"\"\n\ns1 = \"Hola\"\n\nS2 = \"Python\"\n\n#Operaciones de concatenación\n\nprint (s1 + \",\" + S2 + \"!\") \n\n#Repetición \n\nprint (s1 * 3)\n\n#Indexación \n\nprint ( s1 [0]  )\n\nprint ( s1 [0] + s1 [1] + s1 [2]  +s1 [3])\n\n#Longitud\n\nprint (len(S2))\n\n#Slicing (porción)\n\nprint (S2 [2:5])\nprint (S2 [2:6])\nprint (S2 [2:])  #le indico que llegue hasta el final de la cadena de texto\nprint (S2 [0:2])\nprint (S2 [:2])  #le indico que vaya del 0 hasta el 2\n\n\n#Busqueda: intento buscar si de verdad  una letra o caracter existe en una cadena de texto\n\nprint ( \"a\" in s1)\nprint ( \"i\" in s1)\n\n#Reemplazo: Tengo una cadena de texto y la puedo reemplazar y decir que donde aparezca una letra tengamos otra\n\nprint (s1.replace(\"a\", \"o\"))\nprint (s1.replace(\"o\", \"a\"))\n\n#División de cadena de caracteres\n\nprint (S2.split(\"t\"))\n\n#Mayúsculas y Minúsculas\n\nprint (s1.upper())\nprint (s1.lower())\n\n#Mayúsculas, minúsculas y primera letra en mayúsculas\n\nprint (\"yanines barr\".title()) #imprime Yanines Barr\n\nprint (\"yanines barr\".capitalize())  #imprime Yanines barr la primera letra de la primera palabra en mayúscula\n\n#Eliminación de espacios al principio y al final\n\nprint (\"    Yanines Barr     \".strip) # imprime sin espacios \nprint (\"    Yanines Barr     \".strip () + \"@yanines\")  #imprime Yanines Barr@yanines\n\n#Búsqueda al principio y al final: pregunta devuelve booleano\n\nprint (s1.startswith(\"Ho\"))  #devuelve True\nprint (s1.startswith(\"Py\"))  ##evuelve False\nprint (s1.endswith(\"la\"))  #final devuelve True\nprint (s1.endswith(\"thon\"))  #final devuelve false\n\n\ns3 = \"Yanines yanines2025@\"\n\n#Búsqueda de posición\n\nprint (\"Yanines yanines2025@gmail.com\".find (\"yanines\"))\nprint (\"Yanines yanines2025@gmail.com\".find (\"Yanines\"))\nprint (\"Yanines yanines2025@gmail.com\".find (\"Y\"))\nprint (\"Yanines yanines2025@gmail.com\".lower ().find(\"y\")) # se queda con la primera ocurrencia que conincide con el criterio de busqueda sea mayúsla o minúscula\n\n#Búsquedas de ocurrencias\n\nprint (s3.lower().find (\"y\"))\nprint (s3.lower().find (\"I\"))\nprint (s3.lower().find (\"A\"))\n\nprint (s3.lower().count(\"a\"))\n\n#Formateo de una cadena de texto\n\nprint (\"Saludo: {}, lenguaje: {}\".format(s1, S2))\n\n\n#Interpolación\n\nprint (f\"Saludo: {s1}, lenguaje: {S2}\") #resultado igual que el item anterior \n\n#Tranformación en lista de caracteres: crea una lista con todos los caracteres que hay en la cadena de texto\n\nprint (list(s3))\n\n#Tranformación de lista en cadena\n\nl1 = [s1, \",\", S2, \"!\"] #array\nprint (\"\".join(l1)) #operación que sirve para concatenar resultados de una lista\nprint (\"-\".join(l1))\n\n\n#Transformaciones numéricas \n\ns4 = \"123456\"\nS4 = int(s4)\nprint (s4)\n\n\nS5 = \"123.23\"\nS5 = float (S5)\nprint (S5)\n\n#Comprobaciones varias \ns4 = \"123456\"\nprint (s1.isalnum())  #devuelve booleano\nprint (s1.isalpha())\nprint (s4.isalpha())\nprint (s4.isnumeric())\n\n\"\"\"\nExtra\n\n\"\"\"\n\ndef check(word1: str, word2: str):\n\n    #Palíndromos: son las palabras capicúas, pueden leerse igual al derecho y al revés ej: Menem\n    print (f\"¿{word1} es un palíndromo?: {word1 ==word1 [::1]}\")\n    print (f\"¿{word2} es un palíndromo?: {word2 ==word2 [::1]}\")\n\n    #Anagramas\n    print (f\"¿{word1} es anagrama de {word2}?: {sorted(word1) == sorted(word2)}\")\n   \n   #Isograma\n    #print (len   (word1))\n\n    #print (f\"¿{word1} es un isograma  de {word2}?: {sorted(word1) == sorted(word2)}\")\n    #print (f\"¿{word2} es un isograma?: {len (word2) == len (set(word2))}\")\n    #print (f\"¿{word1} es un isograma  de {word1}?: {sorted(word1) == sorted(word1)}\")\n    \n    #print (len (word1) == len (set(word1)))\n\n    def isogram (word: str) ->bool:    # funciones dentro de funciones \n\n        word_dict = dict ()\n        for word in word: \n            #print (word)\n            word_dict[word] = word_dict.get (word, 0) + 1\n        \n        isogram = True\n        values = list(word_dict.values())\n        #print (values)\n        isogram_len = values [0]\n        #isogram_len = word_dict [0]\n        for word_count in values: \n            if word_count != isogram_len:\n                isogram = False\n                break\n        return isogram\n        \n    #print (isogram)\n\n    #print (word_dict)\n\n    print (f\"¿{word1} es un isograma?: {isogram(word1)}\")\n    print (f\"¿{word2} es un isograma?: {isogram(word2)}\")\n\n\ncheck (\"radar\", \"pythonpythonpythonpython\")\n#check (\"amor\", \"roma\")\n\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/YgriegaSB.py",
    "content": "# Concatenacion\ncadena1 = \"Hola\"\ncadena2 = \"Mundo\"\nconcatenacion = cadena1 + \" \" + cadena2\nprint(concatenacion)  # Output: Hola Mundo\n\n# Caracteres por indice\ncadena = \"Python\"\nprimer_caracter = cadena[0]\nprint(primer_caracter)  # Output: P\n\n# longitud \ncadena = \"Python\"\nlongitud = len(cadena)\nprint(longitud)  # Output: 6\n\n# Subcadenas\ncadena = \"Python\"\nsubcadena = cadena[2:5]\nprint(subcadena)  # Output: thon\n\n# Busqueda de subcadenas\ncadena = \"Python es un lenguaje de programación\"\nsubcadena = \"lenguaje\"\nif subcadena in cadena:\n    print(\"La subcadena está presente en la cadena\")\nelse:\n    print(\"La subcadena no está presente en la cadena\")\n\n# Conversion mayus y minus\ncadena = \"Python\"\nmayusculas = cadena.upper()\nminusculas = cadena.lower()\nprint(mayusculas)  # Output: PYTHON\nprint(minusculas)  # Output: python\n\n# Reemplazo de subcadenas\ncadena = \"Python es genial\"\nnueva_cadena = cadena.replace(\"genial\", \"increíble\")\nprint(nueva_cadena)  # Output: Python es increíble\n\n# separacion de cadenas en listas\ncadena = \"Python es genial\"\npalabras = cadena.split()\nprint(palabras)  # Output: ['Python', 'es', 'genial']\n\n# Operaciones con cadenas de caracteres en Python\n\n# Formateo de cadenas\nnombre = \"Juan\"\nedad = 30\ncadena_formateada = \"Mi nombre es {} y tengo {} años\".format(nombre, edad)\nprint(cadena_formateada)  # Output: Mi nombre es Juan y tengo 30 años\n\n# Concatenación de cadenas con la función join()\nlista_palabras = [\"Hola\", \"Mundo\"]\ncadena_concatenada = \" \".join(lista_palabras)\nprint(cadena_concatenada)  # Output: Hola Mundo\n\n# Eliminación de espacios en blanco\ncadena_espacios = \"    Python    \"\ncadena_sin_espacios = cadena_espacios.strip()\nprint(cadena_sin_espacios)  # Output: Python\n\n# Conteo de ocurrencias de subcadenas\ncadena = \"Python es genial y Python es divertido\"\nconteo = cadena.count(\"Python\")\nprint(conteo)  # Output: 2\n\n# Verificación de si una cadena comienza o termina con una subcadena\ncadena = \"Python es genial\"\nprint(cadena.startswith(\"Python\"))  # Output: True\nprint(cadena.endswith(\"genial\"))    # Output: True\n\n# Reversión de una cadena\ncadena = \"Python\"\ncadena_reversa = cadena[::-1]\nprint(cadena_reversa)  # Output: nohtyP\n\n# División de una cadena en subcadenas de longitud fija\ncadena = \"Python es genial\"\nsubcadenas = [cadena[i:i+3] for i in range(0, len(cadena), 3)]\nprint(subcadenas)  # Output: ['Pyt', 'hon', ' es', ' ge', 'nia', 'l']\n\n# Verificación de si una cadena contiene solo dígitos\ncadena = \"12345\"\nprint(cadena.isdigit())  # Output: True\n\n# Verificación de si una cadena contiene solo caracteres alfabéticos\ncadena = \"Python\"\nprint(cadena.isalpha())  # Output: True\n\n# Formateo de cadenas con f-strings (Python 3.6+)\nnombre = \"Juan\"\nedad = 30\ncadena_formateada = f\"Mi nombre es {nombre} y tengo {edad} años\"\nprint(cadena_formateada)  # Output: Mi nombre es Juan y tengo 30 años\n\n# Concatenación de cadenas con %\nnombre = \"Juan\"\nedad = 30\ncadena_concatenada = \"Mi nombre es %s y tengo %d años\" % (nombre, edad)\nprint(cadena_concatenada)  # Output: Mi nombre es Juan y tengo 30 años\n\n# Inversión de palabras en una cadena\ncadena = \"Hola Mundo\"\npalabras_invertidas = \" \".join(reversed(cadena.split()))\nprint(palabras_invertidas)  # Output: Mundo Hola\n\n# Relleno de cadenas con ceros a la izquierda\nnumero = 42\ncadena_rellena = str(numero).zfill(5)\nprint(cadena_rellena)  # Output: 00042\n\n# Búsqueda y reemplazo utilizando expresiones regulares\nimport re\ncadena = \"El número de teléfono es 123-456-7890\"\nnueva_cadena = re.sub(r'\\b(\\d{3})-(\\d{3})-(\\d{4})\\b', r'(\\1) \\2-\\3', cadena)\nprint(nueva_cadena)  # Output: El número de teléfono es (123) 456-7890\n\n\"\"\" \nEJERCICIO\n * - Palíndromos: se lee igual hacia adelante que hacia atrás.\n * - Anagramas: se forman mediante la reorganización de las letras de otra palabra\n * - Isogramas: todas las letras en la palabra aparecen una sola vez\n\"\"\"\n\nprint(\"\\n --------------------------------------------------------- \\n\")\n\n# check palindromo\ndef are_palindromos(word1, word2):\n    reversed_word2 = word2[::-1]\n    return reversed_word2 == word1\n\n# check Anagramas\ndef are_anagramas(word1, word2):\n    return sorted(word1) == sorted(word2)\n\n# check Isogramas\ndef are_isogramas(word1, word2):\n    for i in range(len(word1)):\n        for j in range(i + 1, len(word1)):\n            if word1[i] == word1[j]:\n                return False\n    for i in range(len(word2)):\n        for j in range(i + 1, len(word2)):\n            if word2[i] == word2[j]:\n                return False\n    return True\n\n\ndef check_words(word1, word2):\n    if(are_palindromos(word1, word2) == True):\n        print(f\"Son Palindromos {word1} y {word2}\")\n    else:\n        print(f\"No son Palindromos {word1} y {word2}\")\n    if(are_anagramas(word1, word2) == True):\n        print(f\"Son Anagramas {word1} y {word2}\")\n    else:\n        print(f\"No son Palindromos {word1} y {word2}\")\n    if(are_isogramas(word1, word2) == True):\n        print(f\"Son Isogramas {word1} y {word2}\")\n    else:\n        print(f\"No son Palindromos {word1} y {word2}\")\n\ncheck_words(\"amor\", \"roma\")\ncheck_words(\"barco\", \"arco\")\ncheck_words(\"loma\", \"malo\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/Yisusocanto.py",
    "content": "#Cadena de caracteres\n\ncadena1 = \"Hola\"\ncadena2 = \"Amigo\"\ncadena3 = \"Adios\\namigo\"\ncadena4 = \"Como estas hoy?\"\n\nprint(f\"esta es la cadena1:\", cadena1)\nprint(f\"esta es la cadena multilinea:\", cadena3)\nprint(f\"caracter del indice 1:\", cadena1[1]) #Acceso a un caracter mediante su indice\nprint(f\"indice del caracter o:\", cadena1.index(\"o\")) #Acceso al indice de un caracter\nprint(f\"indice del caracter o:\", cadena1.find(\"o\")) #Acceso al indice de un caracter\nprint(f\"rebanado de la cadena1:\", cadena1[2:5]) #rebanado\nprint(cadena1 * 3)           #repeticion\nprint(\"longitud de la cadena1:\", len(cadena1)) #longitud\nprint(f\"cuenta ocurrencias de a:\", cadena1.count(\"a\"))\nprint(f\"verifica el inicio:\", cadena1.startswith(\"Ho\"))\nprint(f\"verifica el final:\", cadena1.endswith(\"la\"))\nprint(f\"cadena1 en mayusculas:\", cadena1.upper()) #convierte todos los caracteres en mayusculas\nprint(f\"cadena1 en minusculas:\", cadena1.lower()) #convierte todos los caracteres en minusculas\nprint(f\"union de caracteres de la cadena1 y la cadena2:\", cadena1 + \" \" + cadena2)\nprint(\"Ho\" in cadena1)          #verificacion o buscar\nprint(f\"reemplazar cadena de caracteres: \", cadena1.replace(\"Hola\", \"Hello\")) #reemplazar cadena de caracteres\ncadena4.strip()\nprint(cadena4)\n\n#extra\n\ndef check():\n\t#palindromo\n\tpalabra1 = \"ana\"\n\tpalabra2 = \"hola\"\n\n\tprint(f\"{palabra1} es un palindromo?, {palabra1 == palabra1[::-1]}\")\n\tprint(f\"{palabra2} es un palindromo?, {palabra2 == palabra2[::-1]}\")\n\n\t#anagrama\n\tprint(f\"{palabra1} y {palabra2} son anagramas?\", sorted(palabra1) == sorted(palabra2))\n\ncheck()\t\t\t"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/ZAKKDRTE.py",
    "content": "'''\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\n *   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\n *   interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n'''\n\n## CONCATENATION ##\n\nstring:str = \"[+] Hello\" + \" \" + \"World!\"   # Use the + operator to join two or morw strings\n\nprint (string)\n\n\n## REPETITION ##\n\nstring = \"Hello World\\t\" * 3 # Use the * operator to repeat a string a specified number of times\n\nprint (string)\n\n\n## INDEXES AND SLICES ##\n\nstring = \"Hello Python\"\n\nprint(string[0], string[-1])    # Indexes: You can access a character using its index\nprint(string[0:3])  # Slicing: To extract parts of a string\n\n\n## LENGTH ##\n\nlen_str = len(string)   # Get the length of the strings: With the len() function\n\nprint(len_str)  \n\n## TRANSFORMATIONS METHODS ##\n\nupper_str = string.upper()  # HELLO PYTHON\nprint(upper_str)\n\nlower_str = string.lower()  # hello python\nprint(lower_str)\n\ncap_str = string.capitalize()   # Hello python\nprint(cap_str)\n\ntitle_str = string.title()  # Hello Python\nprint(title_str)\n\ntitle_swap = string.swapcase()  # hELLO pYTHON\nprint(title_swap)\n\n## SEARCH AND REPLACE ##\n\nprint(string.find('Python'))    # 6  Returns the index of the first occurrence of a substring, or -1 if not found.\n\nprint(string.index('Python'))   # 6  the same that find but raises an error if the substring is not found.\n\nprint(string.replace(\"Python\",\"Hello\")) # replace all the ocurrences of a substring with another.\n\nprint(string.count(\"Hello\"))    # 2 Counts how many times a substring appears in the string.\n\n## COMPARISON ##\n\n\nprint(\"a\" < \"b\")    # Strings can be compared using comparison operators.\n\nprint(\"HELLO\" == \"HELLO\")\n\n## VALIDATION METHODS ##\n\nprint(string.startswith(\"Hello\"))   # Checks if the string starts with a substring.\n\nprint(string.endswith(\"Python\"))    # Checks if the string ends with a substring. \n\nprint(string.isalpha())     # Checks if all characters are letters. \n\nprint(string.isdigit())     # Checks if all characters are digits.\n\nprint(string.isspace())     # Checks if the string contains only whitespace.\n\nprint(string.isalnum())     # Checks if the string is alphanumeric ( contains letters and/or digits ).\n\n## SPLIT AND JOIN ##\n\nprint(string.split())       # Splits the string into a list of  substrings based on a delimeter ( by default, spaces ).\n\nprint(string.join(\" !!!!\")) # Joins the elements of a list into a string, using a separator.\n\n## TRIM WHITESPACE ##\n\nprint('   string '.strip())     # Removes leading and trailing whitespace.\n\nprint('    string'.lstrip())    # Removes leading whitespace.\n\nprint('string    '.rstrip())    # Removes trailing whitespace.\n\n## STRING FORMATTING ##\n\nprint(\"[+] {}\".format(string))  # Used to format a string with values.\n\nprint(f\"[+] {string}\")          # f-strigns: A simplified syntax for string formatting.\n\n## REVERSING ##\n\nprint(string[::-1])     # There isn't a direct method to reverse a string, but you can use slicing.\n\n\n\n## EXTRA ##\n\n\ntext1 = input(\"\\n[+] Write the first word without accents, character specials:\\t\")\ntext2 = input(\"\\n[+] Write the second word without accents, character specials:\\t\")\n\ndef get_text(text1, text2) -> str:\n\n\n    if (sorted(set(text1)) == sorted(set(text2))):\n        print(\"\\n[+] Son anagramas\\n\")\n    elif (text1.strip() == (text1.strip()[::-1]) and text2.strip() == (text2.strip()[::-1])):\n        print(\"\\n[+] Son Palindromos\\n\")\n    elif (sorted(set(text1)) == sorted(text1) and sorted(set(text2)) == sorted(text2)):\n\n        for i in text1:\n            if i in text2:\n                break\n            else:\n                print(\"\\n[+] Son Isogramas\\n\")\n                break\n    else:\n        print(\"\\n[!] Hubo algun error\\n\")\n\n\nget_text(text1, text2)\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/a-mayans.py",
    "content": "# Cadena de caracteres\ncadena_caracteres = 'Bienvenido a Python'\n\n# Acceso a caracteres específicos\nprint(cadena_caracteres[13]) # devuelve la letra que hay en la posicion indicada\n\n# subcadenas\nsubcadena = cadena_caracteres[13:19]\nprint(subcadena) # indicando dos posiciones, desde donde (13) hasta donde (19 - 1)\n\n# longitud\nlongitud = len(cadena_caracteres) # len calcula cuantos caracteres contiene la cadena, incluyendo los espacios\nprint(longitud)\n\n# concatenación\nnombre = 'Alex'\nconcatenado = cadena_caracteres + ' ' + nombre\nprint(concatenado)\n\n# repetición\nnickname = 'Mayi13 '\nrepeticion = nickname * 3 # la cadena se repite por las veces que se ha multiplicado\nprint(repeticion)\n\n# recorrido\nfor caracter in cadena_caracteres: # recorre cada uno de los caracteres de la cadena\n    print(caracter) # imprime caracter por caracter\n\n# conversión a mayúsculas\nconversion_mayusculas = cadena_caracteres.upper() # con upper devuelve la cadena entera en mayusculas\nprint(conversion_mayusculas)\n\n# conversión a minúsculas\nconversion_minusculas = cadena_caracteres.lower() # con lower devuelve la cadena entera en minusculas\nprint(conversion_minusculas)\n\n# reemplazo\nreemplazo = cadena_caracteres.replace('Bienvenido a', 'Aprendiendo') # indicando primero que queremos cambiar y por que lo queremos cambiar\nprint(reemplazo)\n\n# división\ncadena_dividida = cadena_caracteres.split(' ') # con split e indicando por donde queremos dividir la cadena, devuelve una lista de elementos\nprint(cadena_dividida)\n\n# unión\ncadena_unida = ' '.join(cadena_dividida) # unimos la lista de elementos en una cadena de nuevo separandolos con el espacio indicado ( ' ' )\nprint(cadena_unida)\n\n# interpolación\ninterpolado = f'Hola, {cadena_caracteres.lower()}, {nombre}' # lo hacemos poniendo f antes de abrir comillas, y utilizando los {} para las variables\nprint(interpolado)\n\n# verificación (retornará True o False)\nprint(cadena_caracteres.isalnum()) # retorna True si todos los caracteres de la cadena son alfanuméricos. Si esta vacio o no son alfanumericos retorna False\nprint(cadena_caracteres.isalpha()) # retorna True si todos los caracteres de la cadena son alfabéticos y si como mínimo hay uno.Si la cadena contiene espacios retorna False\nprint(cadena_caracteres.isascii()) # retorna True si la cadena de caracteres está vacía, o si todos los caracteres de la cadena son ASCII, en caso contrario, retorna False\nprint(cadena_caracteres.isdecimal()) # retorna True si todos los caracteres de la cadena son caracteres decimales y hay, al menos, un carácter, en caso contrario, retorna False\nprint(cadena_caracteres.isdigit()) # retorna True si todos los caracteres de la cadena son dígitos y hay, al menos, un carácter, en caso contrario, retorna False\nprint(cadena_caracteres.islower()) # retorna True si todos los caracteres son en minusuclas\nprint(cadena_caracteres.isupper()) # retorna True si todos los caracteres son en mayusculas\nprint(cadena_caracteres.isprintable()) # retorna True si todos los caracteres de la cadena son imprimibles o si la cadena esta vacia. De lo contrario retorna False\nprint(cadena_caracteres.isspace()) # retorna True si verifica que todos los caracteres en la cadena son caracteres de espacio en blanco\nprint(cadena_caracteres.istitle()) # retorna True si las palabras en la cadena tienen forma de título, de lo contrario retorna False\nprint(cadena_caracteres.startswith('Bien')) # retorna True si la cadena empieza por lo indicado. Es case sensitive (distingue entre mayusuclas y minusculas)\nprint(cadena_caracteres.endswith('n')) # retorna True si la cadena termina por lo indicado. Es case sensitive (distingue entre mayusuclas y minusculas)\n\n\n# -------------------------------------------------------------------------------------------------------------------------------------------------------#\n\n'''\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n'''\n\ndef palindromo(palabra):\n    palabra = palabra.lower().replace(\" \", \"\")\n    return palabra == palabra[::-1]\n\ndef anagrama(palabra1, palabra2):\n    palabra1 = palabra1.lower().replace(\" \", \"\")\n    palabra2 = palabra2.lower().replace(\" \", \"\")\n    return sorted(palabra1) == sorted(palabra2)\n\ndef isograma(palabra):\n    palabra = palabra.lower().replace(\" \", \"\")\n    return len(set(palabra)) == len(palabra)\n\ndef palabras():\n    palabra1 = input(\"Ingresa la primera palabra: \")\n    palabra2 = input(\"Ingresa la segunda palabra: \")\n\n    if palindromo(palabra1):\n        print(f\"{palabra1} es un palíndromo.\")\n    else:\n        print(f\"{palabra1} no es un palíndromo.\")\n    \n    if palindromo(palabra2):\n        print(f\"{palabra2} es un palíndromo.\")\n    else:\n        print(f\"{palabra2} no es un palíndromo.\")\n\n    if anagrama(palabra1, palabra2):\n        print(f\"{palabra1} y {palabra2} son anagramas.\")\n    else:\n        print(f\"{palabra1} y {palabra2} no son anagramas.\")\n\n    if isograma(palabra1):\n        print(f\"{palabra1} es un isograma.\")\n    else:\n        print(f\"{palabra1} no es un isograma.\")\n\n    if isograma(palabra2):\n        print(f\"{palabra2} es un isograma.\")\n    else:\n        print(f\"{palabra2} no es un isograma.\")\n\npalabras()"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/abascal92.py",
    "content": "'''\n/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n '''\n\n# Operaciones con cadenas de caracteres\ncadena = \"Hola Mundo\"\ncadena2 = \"Alejandro\"\ncadena3 = \"\"\nprint(cadena[0]) # Acceso a un caracter específico\nprint(cadena[0:4]) # Subcadena\nprint(len(cadena)) # Longitud\nprint(f\"{cadena} {cadena2}\") # Concatenación\nprint(cadena * 2) # Repetición\nfor char in cadena: # Recorrido\n    print(char)\nprint(cadena.upper()) # Conversión a mayúsculas\nprint(cadena.lower()) # Conversión a minúsculas\nprint(cadena2.replace(\"Alejandro\", \"Alex\")) # Reemplazo\nprint(cadena.split(\" \")) # División\nprint(cadena3.join([cadena, cadena2])) # Unión\nprint(f\"{cadena} {cadena2}\") # Interpolación\nprint(f\"{cadena.isalnum()} {cadena.isalpha()} {cadena.isdecimal()} {cadena.isdigit()} {cadena.isidentifier()} {cadena.islower()} {cadena.isupper()} {cadena.isspace()} {cadena.istitle()} {cadena.isnumeric()} {cadena.isprintable()}\") # Verificación\n\n# DIFICULTADO EXTRA\n#region Palíndromos\n# 1\ndef is_palindrome(word): # Verifica si una palabra es palíndromo\n    return word == word[::-1] # Compara la palabra con su inversa\nprint(is_palindrome(\"ana\")) # True\n# 2\nprint(\"Vamos a verificar si una palabra es palíndromo\")\ncadena = input(\"Introduce una palabra: \").lower()\nlist_cadena = list(cadena)\nlist_cadena_reverse = list(cadena)\nlist_cadena_reverse.reverse()\nwhile \"\" in list_cadena:\n    list_cadena.remove(\" \")\nwhile \"\" in list_cadena_reverse:\n    list_cadena_reverse.remove(\" \")\nif list_cadena == list_cadena_reverse:\n    print(f\"La palabra {cadena} es un palíndrono\")\nelse:\n    print(f\"La palabra {cadena} NO es un palíndrono\")\n#endregion\n#region Anagramas\ndef is_anagrama(palabra1, palabra2): \n    return sorted(palabra1) == sorted(palabra2) # Compara si las palabras ordenadas son iguales\nprint(\"Vamos a verificar si dos palabras son anagramas\")\npalabra1 = input(\"Introduzca la primera l¡palabra: \").lower()\npalabra2 = input(\"Introduzca la segunda palabra: \").lower()\nprint(f\"¿Las palabras '{palabra1}' y '{palabra2}' son anagramas?\\n{is_anagrama(palabra1, palabra2)}\")\n#endregion\n#region Isogramas\ndef is_isograma(plaabra):\n    return len(plaabra) == len(set(plaabra)) # Compara la longitud de la palabra con la longitud de la palabra sin caracteres repetidos (si son iguales, no hay caracteres repetidos)\nprint(\"Vamos a verificar si una palabra es un isograma\")\npalabra = input(\"Introduzca una palabra \").lower()\nprint(f\"¿Es la palabra '{palabra}' un isograma?\\n{is_isograma(palabra)}\")\n#endregion\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/adolfolozaa.py",
    "content": "### Cadena de Caracteres\r\n\r\n'''\r\nEJERCICIO:\r\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\r\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\r\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\r\n *   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\r\n *   interpolación, verificación...\r\n *\r\n * DIFICULTAD EXTRA (opcional):\r\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\r\n * para descubrir si son:\r\n * - Palíndromos\r\n * - Anagramas\r\n * - Isogramas\r\n '''\r\n'''\r\nOperaciones\r\n'''\r\n# Concatenacion\r\ns1 = 'Hola '\r\ns2 = 'Python'\r\nprint(s1 + ' ' + s2 +'!')\r\n\r\n# Repeticion\r\nprint(s1 * 3)\r\n\r\n# Indexacion\r\nprint(s1[0] + s1[1] + s1[2] + s1[3])\r\n\r\n# Longitud\r\nprint(len(s2))\r\n\r\n# Slicing\r\nprint(s2[2:6])\r\nprint(s2[2:])\r\nprint(s2[0:2])\r\nprint(s2[:2])\r\n\r\n# Busqueda\r\nprint('a' in s1)\r\n\r\n# Reemplazo\r\nprint(s1.replace('o', 'a'))\r\n\r\n# Division\r\nprint(s2.split('t'))\r\n\r\n# Mayusculas y minusculas\r\nprint(s1.upper())\r\nprint(s1.lower())\r\nprint('adolfo loza'.title())\r\nprint('adolfo loza'.capitalize())\r\n\r\n# Eliminacion de espacios al principio y al final\r\ns3 = ' Adolfo Loza '\r\nprint(s3.strip() + '@adolfolozaa')\r\n\r\n# Busqueda al principio y al final\r\nprint(s1.startswith('Ho'))\r\nprint(s1.startswith('Py'))\r\nprint(s1.endswith('la '))\r\nprint(s2.endswith('n'))\r\n\r\n# Busqueda de Posicion\r\nprint('Adolfo Loza @adolfolozaa'.find('folo')) #empieza en 0\r\nprint('Adolfo Loza @adolfolozaa'.find('Loza'))\r\nprint('Adolfo Loza @adolfolozaa'.find('L'))\r\nprint('Adolfo Loza @adolfolozaa'.find('o'))\r\n\r\n# Busqueda de ocurrencias\r\nprint('Adolfo Loza @adolfolozaa'.count('o'))\r\nprint('Adolfo Loza @adolfolozaa'.count('lo'))\r\n\r\n# Formateo\r\nprint('Saludo: {} Lenguaje: {}'.format('Adolfo', 'Python'))\r\n\r\n# Interpolar\r\nprint(f'Saludo: {s1} Lenguaje: {s2}')\r\n\r\n# Transformacion cadena en lista de caracteres\r\nprint(list(s3))\r\n\r\n# Transformacion de lista en cadena \r\nl1 = [s1, ', ', s2, '!']\r\nprint(l1)\r\nprint(''.join(l1))\r\nprint('-'.join(l1))\r\n\r\n# Transformaciones numericas\r\ns4 = '1234'\r\ns5 = int(s4)\r\nprint(type(s5))\r\ns6 = '1234.56'\r\ns7 = float(s6)\r\nprint(type(s7))\r\n\r\ns8 = 5\r\n# Comprobaciones varias\r\nprint(s1.isalnum()) \r\nprint(s3.isalpha())\r\nprint(s4.isnumeric()) #solo aplica a str\r\n\r\n'''\r\nDIFICULTAD EXTRA (opcional):\r\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\r\n * para descubrir si son:\r\n * - Palíndromos\r\n * - Anagramas\r\n * - Isogramas\r\n '''\r\nprint( 'Analisis de Palabras')\r\nprint('--------------------')\r\n\r\n# Ingreso de palabras\r\ndef enter_words():\r\n    print('Por favor ingrese dos palabras ')\r\n    global w1, w2\r\n    w1 = input('Palabra nupero 1: ')\r\n    w2 = input('Palabra numero 2: ')\r\n    print(f'Las palabras ingresadas son: {w1} y {w2}')\r\n    global w1_1\r\n    w1_1 = w1.lower()\r\n    global w2_1\r\n    w2_1 = w2.lower()\r\n    print(w1_1 + ' '+ w2_1)\r\n    w2_1\r\n\r\nenter_words()\r\n\r\n# Palindromos\r\ndef palin():\r\n    print('\\n\\nanalisis de polindromos')\r\n    print('--------------------')\r\n    reversed_w2_1 = w2_1[::-1]  # de inicio a fin a la inversa\r\n    #print(reversed_w2_1)\r\n    if w1_1 == reversed_w2_1:\r\n        print(f'Las palabras {w1} y {w2} --SI-- son palindromos')\r\n    else:\r\n        print(f'Las palabras {w1} y {w2}  --NO-- palindromos')\r\n\r\npalin()\r\n\r\n# Anagramas\r\ndef ana():\r\n    print('\\n\\nanalisis de anagramas')\r\n    print('--------------------')\r\n    if len(w1_1) != len(w2_1):\r\n        print(f'Las palabras {w1_1} y {w2_1} --NO-- son Anagramas')\r\n        bandera = 0\r\n    else:\r\n        bandera = 1\r\n    counter =0\r\n    for letra in w1_1:\r\n        if letra not in w2_1:\r\n            break\r\n        else:\r\n            counter +=1\r\n    if counter == len(w2_1):\r\n\r\n        print(f'Las palabras {w1_1} y {w2_1} --SI-- son Anagramas')\r\n    else:\r\n        if bandera == 1:\r\n            print(f'Las palabras {w1_1} y {w2_1} --NO-- son Anagramas')\r\nana()\r\n\r\n# Isogramas\r\n\r\ndef check(w1_1 : str, w2_1 : str ):\r\n    print('\\n\\nanalisis de isogramas')\r\n    print('--------------------')\r\n    def isogram(word: str) -> bool:\r\n        word_dict = dict()\r\n        for character in word:\r\n            word_dict[character] = word_dict.get(character, 0) + 1\r\n        isogram = True\r\n        values = list(word_dict.values())\r\n        print(values)\r\n        isogram_len = values[0]\r\n        for word_count in values:\r\n            if word_count != isogram_len:\r\n                isogram = False\r\n                break\r\n        return isogram\r\n    \r\n    print(f\"{w1_1} es un isograma?: {isogram(w1_1)}\")\r\n    print(f\"{w2_1} es un isograma?: {isogram(w2_1)}\")\r\n\r\ncheck(w1_1, w2_1)\r\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/adra-dev.py",
    "content": "\"\"\"\nEJERCICIO:\n- Muestra ejemplos de creación de todas las operaciones que puedes \nrealizar con cadenas de caracteres.\n- Acceso a caracteres específicos, subcadenas, longitud, \nconcatenación, repetición, recorrido, conversión a mayúsculas y \nminúsculas, reemplazo, división, unión, interpolación, \nverificación...\n\nDIFICULTAD EXTRA (opcional):\n- Crea un programa que analice dos palabras diferentes y realice \ncomprobaciones para descubrir si son:\n- Palíndromos\n- Anagramas\n- Isogramas\n\nby adra-dev.\n\"\"\"\n\n\"\"\"\nCadenas:\n    Una cadena de texto es una secuencia inmutable de caracteres que \n    en Python se representa con el tipo de dato str.Esta secuencia \n    se puede delimitar con comillas simples('') o con comillas dobles\n    (\"\").Aunque se pueden utilizar ambos tipos de comillas, las \n    cadenas se deben cerrar con el mismo tipo de comillas usado en la\n    apertura.\n\"\"\"\n\n# Creacion\ncadena_comillas_dobles = \"Cadena de texto\"\nprint(cadena_comillas_dobles)\ncadena_comillas_simples = 'Cadena de texto'\nprint(cadena_comillas_simples)\n\n\"\"\"\nAcceso a los elementos de una cadena:\n    Las cadenas de texto son un tipo de dato compuesto, es decir, \n    estan formadas por elementos mas pequenos que tienen significado,\n    los caracters. Al tratarse de un tipo de dato compuesto podemos \n    acceder a la cadena como un todo o a las partes que la componen.\n\"\"\"\nserie = 'Juego de tronos'\nprint(serie)\n\nprint(serie[0])\n\nprint(serie[1])\n\nprint(serie[-1])\n\nprint(serie[-2])\n\nprint(serie[-3])\n\n\"\"\"\nAcceso a una subcadena:\n    Para acceder a una procion de una cadena, es decir, a una \n    subcadena, hay que indicar la posicion de inicio y la posicion \n    limite separadas por dos puntos [posicion_inicio:posicion_limite]\n    . Al escribir la posicion limite debemos tener cuidado, puesto \n    que el operador [posicion_inicio:posicion_limite] devuelve la \n    subcadena que va desde el caracter que ocupa la <<posicion_inicio>> \n    hasta el caracter que ocupa la <<posicion limite>>, sin incluirlo.\n\"\"\"\n\nprint(serie[0:5])\n\nprint(serie[0:4])\n\nprint(serie[0:20])\n\nprint(serie[:5])\n\nprint(serie[9:])\n\nprint(serie[:])\n\n\"\"\"\nOperadores especiales:\n    Existen 4 operadores que nos permiten operar con cadenas de texto:\n    el operador de suma(+), el operador de asignacion de suma(+=), el\n    operador de multipliacion(*) y el operador modulo(%).\n\"\"\"\n\n# (+) permite concatenar cadenas de caracteres, no incluye los espacios.\n\nnum_temp = 8\n\nfecha_estreno = \"22 de abril\"\n\nmensaje = \"La temporada \" + str(num_temp) + \" de \" + serie + \" se estreno el \" + fecha_estreno + \" de 2019.\"\n\nprint(mensaje)\n\n# (*) permite concatenar una cadena varias veces.\n\ntexto_a = \"Hace \" + 3 * \"mucho \" + \"tiempo. . .\"\nprint(texto_a)\n\ntexto_b = \"Hace \" + \"mucho \" * 3 + \"tiempo. . .\"\nprint(texto_b)\n\n# (+=) permite agregar cadenas al final de una cadena de caracteres.\n\npersonajes = [\"Daenerys Targaryen\", \"John Snow\", \"Ayra Stark\", \"Cersei Lannister\"]\n\npersonajes_principales = \"\"\n\nfor nombre in personajes:\n    personajes_principales += nombre + \", \"\n    \nprint(personajes_principales)\n\n# (%) permite interpolar variables dentro de una cadena.\n\n\"\"\"\nMetodos para la manipulacion de cadenas.\n\"\"\"\n\n# len devuelve la longitud de la cadena\nprint(len(serie))\n\n# count devuelve el numero de veces que se repite la subcadena\ncadena = \"Hace mucho mucho mucho tiempo...\"\nprint(cadena.count(\"mucho\"))\n\n# find devuelve la posicion de la primera ocurriencia de la subcadena\nfrase = \"Erase una vez una princesa llamada Jasmine.\"\nprint(frase.find(\"una\"))\n\n# index realiza lo misma funcion que el metodo find(), pero genera un error si no encuentra la subcadena.\nprint(frase.index(\"una\"))\n\n# rfind realiza la busqueda desde el final de la cadena\nprint(frase.rfind(\"una\"))\n\n# rindex realiza la busqueda desde el final de la cadena\nprint(frase.rindex(\"una\"))\n\n# capitalize devuelve una copia de la cadena convirtiendo el primer caracter a mayuscula y el resto a minuscula.\ncadena = \"pyTHon\"\nprint(cadena.capitalize())\n\n# lower devuelve una copia de la cadena convirtiendo todos los caracteres a minuscula\nprint(cadena.lower())\n\n# upper devuelve una copia de la cadena convirtiendo todos los caracteres a mayuscula\nprint(cadena.upper())\n\n# swapcase devuelve una copia de la cadena invirtiendo los caracters\nprint(cadena.swapcase())\n\n# strip devuelve uan copia de la cadena tras eliminar los caracteres iniciales y finales\ncadena = \"\\t Estoy aprendiendo mucho sobre Python. \\n\"\nprint(cadena.strip())\n\n# lstrip elimina solamente los caracteres iniciales que corresponden \nprint(cadena.lstrip())\n\n# rstrip elimana solamente los caracteres finalesen lugar de los iniciales\nprint(cadena.rstrip())\n\n# replace devuelve una copia de cadena tras reemplazar las ocurrencias de la subcadena\ncadena = \"Soy un excelente programador de Java.\"\nprint(cadena.replace(\"Java\", \"Python\"))\n\n# split divide la cadena utilizando un caracter separador indicado\ncadena = \"Grupo A\\tGrupo B\\tGrupo C\"\nprint(cadena.split(\"\\t\"))\n\n# join Devuelve una cadena resultante de unir las cadenas del iterable indicado como argumento\nprint(\" - \".join(personajes))\n\n\"\"\"\nFormateo de una cadena\n\"\"\"\n\n# Operador % permite interpolar variables dentro de una cadena de caracteres\n\nnombre = \"Maria\"\nprint(\"%s domina lenguajes como Java y C++ \" %nombre)\n\nnuevo_lenguaje= \"Python\"\nprint(\"%s domina lenguajes como Java y C++ y quiere aprender a programar %s\" %(nombre, nuevo_lenguaje))\n\n\n# Funcion str.format() permite realizar un formateo de la cadena desde la que se realiza la llamada.\nprint(\"{0} domina lenguajes como Java y C++ y quiere aprender a programar {1}\".format(nombre, nuevo_lenguaje))\n\nprint(\"{nom} domina lenguajes como Java y C++ y quiere aprender a programar {nl}\".format(nom =nombre, nl =nuevo_lenguaje))\n\n\n# F-strings se representan con una f al principio y contienen llaves con las variables cuyos valores se insertan en la cadena\nprint(f\"{nombre} domina lenguajes como Java y C++ y quiere aprender a programar {nuevo_lenguaje} \\n\")\n\nprint(\"---------\")\n\n\n\"\"\"\nExtra\n\"\"\"\n\ndef check(word1: str, word2: str):\n\n    # Palíndromos\n    print(f\"¿{word1} es un palíndromo?: {word1 == word1[::-1]}\")\n    print(f\"¿{word2} es un palíndromo?: {word2 == word2[::-1]}\")\n\n    # Anagramas\n    print(f\"¿{word1} es anagrama de {word2}?: {sorted(word1) == sorted(word2)}\")\n\n    # Isogramas\n\n    def isogram(word: str) -> bool:\n\n        word_dict = dict()\n        for character in word:\n            word_dict[character] = word_dict.get(character, 0) + 1\n\n        isogram = True\n        values = list(word_dict.values())\n        isogram_len = values[0]\n        for word_count in values:\n            if word_count != isogram_len:\n                isogram = False\n                break\n\n        return isogram\n\n    print(f\"¿{word1} es un isograma?: {isogram(word1)}\")\n    print(f\"¿{word2} es un isograma?: {isogram(word2)}\")\n\n\ncheck(\"radar\", \"pythonpythonpythonpython\")\n# check(\"amor\", \"roma\")\n            \n            \ncheck(\"rallar\", \"seder\")\ncheck(\"caucasus\", \"seder\")\ncheck(\"caucasus\", \"ambidiestramente\")\ncheck(\"PUBVEXINGFJORD-SCHMALTZY\", \"hola\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/agusrosero.py",
    "content": "mi_cadena = 'Hernan'\n\n# Acceso a caracteres específicos\nprint(mi_cadena[0])\n\n# Longitud\nprint(len(mi_cadena))\n\n# Subcadenas\nsubcadena = 'code'\nprint(mi_cadena.find(subcadena))\n\n# Concatenacion\nsaludo = 'Hola'\nprint(saludo + ' ' + mi_cadena)\n\n# Repeticion\nprint(mi_cadena * 5)\n\n# Recorrido\nfor i in mi_cadena:\n    print(i)\n\n# Conversion\nprint(mi_cadena.upper())\nprint(mi_cadena.lower())\nprint(mi_cadena.capitalize())\nprint(mi_cadena.title())\nprint(mi_cadena.center(10, '*'))\n\n# Reemplazo\nnueva_cadena = 'Python'\nprint(mi_cadena.replace('Hernan', 'Python'))\n\n# Division\nnueva_cadena2 = 'Esta es una division de cadena'\nprint(nueva_cadena2.split(' '))\n\n# Union\nnueva_cadena3 = ['Esta', 'es', 'una', 'union', 'de', 'cadenas']\nprint(' '.join(nueva_cadena3))\n\n# Interpolacion\ncadena = 'Python'\nprint(f'Hola, {cadena}!')\n\n# Verificacion\nverificacion = '777'\nprint(verificacion.isdecimal())\nprint(verificacion.isdigit())\nprint(verificacion.isalnum())\nprint(verificacion.isalpha())\nprint(verificacion.isascii())\nprint(verificacion.isidentifier())\nprint(verificacion.islower())\nprint(verificacion.isnumeric())\n\n##### DIFICULTAD EXTRA\ndef es_palindromo(cadena):\n    return cadena == cadena[::-1]\n\nes_palindromo('radar')\n\ndef es_anagrama(p1, p2):\n    p1 = p1.lower()\n    p2 = p2.lower()\n    \n    p1_arreglo = list(p1)\n    p2_arreglo = list(p2)\n\n    p1_arreglo.sort()\n    p2_arreglo.sort()\n\n    p1_ordenada = ''.join(p1_arreglo)\n    p2_ordenada = ''.join(p2_arreglo)\n    \n    return p1_ordenada == p2_ordenada\n\nstring1 = 'Nacionalista'\nstring2 = 'Altisonancia'\nprint(es_anagrama(string1, string2))\n\ndef es_isograma(cadena):\n    cadena_minuscula = cadena.lower()\n    unique_letters = set(cadena_minuscula)\n    return len(unique_letters) == len(cadena)\n\nstring3 = 'acondicionar'\nprint(es_isograma(string3))\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/ainaragmt.py",
    "content": "s1 = \"Hello \"\ns2 = \"Python\"\n\n# Concatenación\nprint(\"\\nConcatenación\")\nprint(s1 + \" \" + s2)\n      \n# Repetición\nprint(\"\\nRepetición\")\nprint(s1*3)\n\n# Indexación\nprint(\"\\nIndexación\")\nprint(s1[0])\n\n# Longitud\nprint(\"\\nLongitud\")\nprint(len(s1))\n\n# Slicing\nprint(\"\\nSlicing\")\nprint(s2[2:5]) # del 2 al 5 excluyendo el 5\nprint(s2[2:]) # del 2 al final\n\n# Búsqueda\nprint(\"\\nBúsqueda\")\nprint(\"a\" in s1)\nprint(\"e\" in s1)\n\n# Reemplazo\nprint(\"\\nReemplazo\")\nprint(s1.replace(\"e\", \"a\"))\n\n# División\nprint(\"\\nDivisión\")\nprint(s1.split('l')) # corta por las dos 'l'\n\n# Conversión a mayúsculas\nprint(\"\\nConversión a mayúsculas y minúsculas\")\nprint(s1.upper())\nprint(s1.lower())\n\nnombre = \"Ainara gmt\"\nprint(nombre.title())\nprint(nombre.capitalize())\n\n# Eliminación de espacios al principio y al final\nprint(\"\\nEliminación de espacios al principio y al final\")\nprint(s1.strip() + s2)\n\n# Búsqueda al principio y al final\nprint(\"\\nBúsqueda al principio y al final\")\nprint(s1.startswith(\"He\"))\nprint(s1.endswith(\"He\"))\n\n# Búsqueda de posición\nprint(\"\\nBúsqueda de posición\")\nprint(s1.find(\"o\"))\n\n# Búsqueda de ocurrencias\nprint(\"\\nBúsqueda de ocurrencias\")\nprint(s1.count(\"l\"))\n\n# Interpolación\nprint(\"\\nInterpolación\")\nprint(f\"Saludo {s1}, lenguaje {s2}\")\n\n# Formateo\nprint(\"\\nFormateo\")\nprint(\"Saludo {}, lenguaje {}\".format(s1,s2))\n\n# Transformación en lista de caracteres\nprint(\"\\nTransformación en lista de caracteres\")\nprint(list(s1))\n\n# Transformación en lista en cadena\nprint(\"\\nTransformación en lista en cadena\")\nl1 = [s1, \", \", s2]\nprint(\"\".join(l1))\nprint(\"-\".join(l1))\n\n# Transformaciones numéricas\nprint(\"\\nTransformaciones numéricas\")\ns3 = 1234\nprint(int(s3))\n\n# Comprobaciones varias\nprint(\"\\nComprobaciones varias\")\n# Devuelve False por el espacio \"Hello \"\nprint(s1.isalnum()) # letras y números\nprint(s1.isalpha()) # letras\nprint(s1.isnumeric()) # números\n\nprint(s2.isalnum()) # letras y números\nprint(s2.isalpha()) # letras\nprint(s2.isnumeric()) # números\n\n'''\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n'''\nprint(\"\\nEjercicio de dificultad extra\\n\")\n\ndef programa():\n    def palindromo(s1):\n        s1 = s1.lower().strip().replace(\" \", \"\")\n        for i in range (len(s1)):\n            if s1[i] != s1[(len(s1) - 1 - i)]:\n                return \"No\"\n        return \"Sí\"\n    \n    # Corrección palíndromos\n    # Podríamos haber invertido la palabra con s1[::-1]\n    # print(f\"¿{s1} es un palíndromo?: {s1 == s1[::-1]}\")\n    \n    def anagrama(s1, s2):\n        def orden (s1):\n            s1 = s1.lower().strip().replace(\" \", \"\")\n            lista_ordenada1 = sorted(s1)\n            palabra_ordenada1 = \"\".join(lista_ordenada1)\n            return palabra_ordenada1\n        s1 = orden (s1)\n        s2 = orden (s2)\n        if len(s1) != len(s2):\n            return \"No\"\n        for i in range (len(s1)):\n            if s1[i] != s2[i]:\n                return \"No\"\n        return \"Sí\"\n    \n    # Corrección anagrama\n    # print(f\"¿{s1} es anagrama de {s2}?: {sorted(s1) == sorted(s2)}\")\n\n    def isograma(s1):\n        s1 = s1.lower().strip().replace(\" \", \"\")\n        for i in range (len(s1)):\n            for j in range (len(s1)):\n                if s1[i] == s1[j] and i != j:\n                    return \"No\"\n        return \"Sí\"\n    \n    # Corrección isograma\n    # Comprueba si la longitud de la palabra es igual a\n    # la longitud del conjunto de sus letras\n    # print(f\"¿{s1} es un isograma?: {len(s1) == len(set(s1))}\")\n\n    palabra1 = input(\"Escribe la primera palabra: \")\n    palabra2 = input(\"Escribe la segunda palabra: \")\n\n    pal1 = palindromo(palabra1)\n    print(\"\\n¿Es la primera palabra un palíndromo? \" + pal1)\n    pal2 = palindromo(palabra2)\n    print(\"\\n¿Es la segunda palabra un palíndromo? \" + pal2)\n\n    ana = anagrama(palabra1, palabra2)\n    print(\"\\n¿Son anagramas? \" + ana)\n\n    iso1 = isograma(palabra1)\n    print(\"\\n¿Es la primera palabra un isograma? \" + iso1)\n    iso2 = isograma(palabra2)\n    print(\"\\n¿Es la segunda palabra un isograma? \" + iso2)\n    \nprograma()"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/alanshakir.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n \"\"\"\nmy_string = \"esto es un string\"\nprint(len(my_string)) #retorna el numero de caracteres\nprint(my_string[5]) #retorna el caracter en la posicion 5\nprint(my_string[2:9]) #retorna una subcadena\nprint(my_string * 3) #repite la cadena 3 veces\nprint(\"e\" in my_string) #busca el caracter en el string\nfor element in my_string: #recorre una cadena\n    print(element)\nmy_other_string = \" esto es otro string\"\nprint(my_string + \" \"+ my_other_string) #concatena dos cadenas\nprint(my_string.upper()) #retorna el string en mayusculas\nprint(my_string.lower()) #retorna el string en minuscula\nprint(my_string.title()) #devuelve una copia usando el titulo como referencia\nprint(my_string.replace(\"o\",\"O\")) # reemplaza la primera ocurrencia indicada\nprint(my_other_string.lstrip()) #elimina espacios en blanco al principio\nprint(my_other_string.rstrip()) #elimina espacios en blanco al final\nprint(my_other_string.split(\"o\")) # devuelve una lsita separada por el parametro indicado\nprint(my_string.startswith(\"es\")) #busca al principio la primera ocurrencia\nprint(my_string.endswith(\"es\")) #busca al final la primera ocurrencia\nprint(\"Cadena1:  {}, cadena2: {}\".format(my_string,my_other_string) )\n\n#DIFICULTAD EXTRA\ndef comprobar(word1, word2):\n    #palindromo\n    reverse_word1= word1[::-1]\n    reverse_word2= word2[::-1]\n    print(f\"la palabra {word1} es palindromo?: {word1==reverse_word1}\")\n    print(f\"la palabra {word2} es palindromo?: {word2==reverse_word2}\")\n\n    #anagrama\n    print(f\"las palabras {word1} y {word2} son anagrama?: {sorted(word1)==sorted(word2)}\")\n\n    #isograma\n    print(f\"{word1} es isograma?: {len(word1) == len(set(word1))}\") #funciona si el string no se repite\n    print(f\"{word2} es isograma?: {len(word2) == len(set(word2))}\")\n\n    def is_isogram(word):\n        word_dict = dict()\n        for element in word:\n            word_dict[element] = word_dict.get(element, 0) + 1\n        isogram = True\n        values = list(word_dict.values())\n        len_isogram = values[0]\n        for word_count in values:\n            if word_count != len_isogram:\n                isogram = False\n                break\n        return isogram\n    print(f\"{word1} es isograma?: {is_isogram(word1)}\")\n    print(f\"{word2} es isograma?: {is_isogram(word2)}\")\n\ncomprobar(\"retos\", \"programacion\")\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/alberba.py",
    "content": "\n# Comprobar si empieza por una secuancia de caracteres\nstring = \"Hola mundo\"\n\nbooleano = string.startswith(\"hola\")\n\nprint(booleano)\n\n# Convierte en mayúsculas\nprint(string.capitalize())\n\n# Reemplaza caracteres\nprint(string.replace(\"mundo\", \"España!!\"))\n\n# Centraliza el texto a partir de un ancho acordado\nprint(string.center(20))\n\n# Cuanta el número de veces que aparece la secuencia de caracteres\nprint(string.count(\"o\"))\n\n# Devuelve el indice menor donde se encuentra esta secuencia\nprint(string.find(\"mun\"))\n\n# Convierte en minúsculas\nprint(string.lower())\n\n# Separa la cadena en dos si encuentra la cadena proporcionada\nprint(string.split(\" \"))\n\n# Devuelve la longitud de la cadena\nprint(len(string))\n\n# Cambia las mayúsculas por minúsculas y viceversa\nprint(string.swapcase())"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/albertomorilla.py",
    "content": "# #04 CADENAS DE CARACTERES\n\n\"\"\"\nEJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n  - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n\"\"\"\n# Ejemplo de acceso a caracteres específicos\ncadena = \"I am Alberto\"\nprint(cadena [4]) #Imprime A (INDEXACION)\n\nindice = cadena.find(\"H\") #Encuentra un caracter \nif indice != -1:\n    print(f\"La letra H se encuentra en la posición {indice}\")\nelse:\n    print(\"La letra H no se encuentra en la cadena\")\n\n# Subcadenas\nprint(cadena[0:4]) #Imprime I am (SLICING)\n\n# Longitud\nprint(len(cadena)) #Imprime 9\nprint(cadena.count(\"a\")) #Imprime 1\n\n# Concatenación\ncadena2 = \"My city is Sevilla\"\nprint(cadena + \" \" + cadena2) #Imprime I am Alberto My city is Sevilla\n\n# Repeticion\nprint(cadena * 2) #Imprime I am AlbertoI am Alberto\nprint(cadena + cadena) #Imprime I am AlbertoI am Alberto\n\n# Recorrido\nfor caracter in cadena:\n    print(caracter) #Imprime cada caracter de la cadena\n\nfor i in range(len(cadena)):\n    print(cadena[i]) #Imprime cada caracter de la cadena\n    \n# Conversion Mayúsculas y Minúsculas\nprint(cadena.upper()) #Imprime I AM ALBERTO\nprint(cadena.lower()) #Imprime i am alberto\nprint(cadena.capitalize()) #Imprime I am alberto\nprint(cadena.title()) #Imprime I Am Alberto\nprint(cadena.swapcase()) #Imprime i AM aLBERTO\nprint(cadena.casefold()) #Imprime i am alberto\n\n# Reemplazo\nprint(cadena.replace(\"Alberto\", \"Juan\")) #Imprime I am Juan\n\n# División\nprint(cadena.split(\" \")) #Imprime ['I', 'am', 'Alberto']\n\n# Unión\ncadena3 = [\"Hello\", \"Alberto \", \"Morilla\"]\ncadena_unida = \" \".join(cadena3)\nprint(cadena_unida) #Imprime Hello Alberto Morilla\n\n# Interpolación\nname = \"Alberto\"\nage = 36\ncadena2_unida = \"Hello, my name is {} and I am {} years old\".format(name, age)\nprint(cadena2_unida) #Imprime Hello, my name is Alberto and I am 36 years old.\n\ncadena3_unida = f\"Hello, my name is {name} and I am {age} years old.\"\nprint(cadena3_unida) #Imprime Hello, my name is Alberto and I am 36 years old.\n\n# Verificación\nprint(cadena.startswith(\"I\")) #Imprime True\nprint(cadena.endswith(\"o\")) #Imprime True\nprint(cadena.isdigit()) #Imprime False si no es int\nprint(cadena.isalpha()) #Imprime False si no es string\nprint(cadena.isalnum()) #Imprime False si no es string o int\nprint(cadena.islower()) #Imprime True si es todo minusculas\nprint(cadena.isupper()) #Imprime False si no es todo mayusculas\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n  para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n\"\"\"\n\ndef check(word1: str, word2: str):\n\n    # Palíndromos\n    print (f\"¿{word1} es un palíndromo?: {word1 == word1[::-1]}\")  \n    print (f\"¿{word2} es un palíndromo?: {word2 == word2[::-1]}\")\n\n    # Anagrama\n    print(f\"¿{word1} es anagrama de {word2}?: {sorted(word1) == sorted(word2)}\")\n\n    # Isograma\n    print(f\"¿{word1} es un isograma?: {len(word1) == len(set(word1))}\")\n    print(f\"¿{word2} es un isograma?: {len(word2) == len(set(word2))}\")\n\n    def isogram(word: str) -> bool:\n        word_dict = dict()\n        for character in word:\n            word_dict[character] = word_dict.get(character, 0) +1\n\n        isogram = True\n        values = list(word_dict.values())\n        isogram_len = values[0]\n        for word_count in word_dict:\n            if len(word_count) != isogram_len:\n                isogram = False\n                break\n            \n        return isogram\n    \n    print(f\"¿{word1} es un isograma?: {len(word1) == len(set(word1))}\")\n    print(f\"¿{word2} es un isograma?: {len(word2) == len(set(word2))}\")\n\n\ncheck(\"radar\", \"pythonpythonpython\")\n#check(\"amor\", \"roma\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/alcaan16.py",
    "content": "\"\"\"/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\n *   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\n *   interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n    *Palabra o frase cuyas letras están dispuestas de tal manera \n    que resulta la misma leída de izquierda a derecha que de derecha a izquierda\n * - Anagramas\n    * - Un Anagrama consiste en formar una palabra reordenando TODAS\n    *   las letras de otra palabra inicial.\n    * - NO hace falta comprobar que ambas palabras existan.\n    * - Dos palabras exactamente iguales no son anagrama.\n * - Isogramas\n    *palabra o frase en la que cada letra aparece el mismo número de veces.\n    *el orden indica el numero de veces\n */\"\"\"\n\ndef anagrama (var_1, var_2):\n    if var_1.lower() == var_2.lower():\n        #print (\"las palabras son iguales\")\n        return False\n    return sorted(var_1.lower()) == sorted (var_2.lower())\n\ndef isograma (var_1):\n    contador={}\n    for char in var_1:\n        if char in contador.keys():\n            contador[char] +=1\n        else:\n            contador[char] =1\n    print (contador)\n    orden=0\n    for i in contador.values():\n        if orden == 0:\n            orden = i\n        if orden != i:\n            return print (f\"{var_1} NO es una palabra isograma\\n\")\n    return print (f\"{var_1} es una palabra isograma de orden {orden}\\n\")\n            \n\n\nprint (\"\\nlas palabras son anagramas?\")\nprint (anagrama(\"Caso\", \"saco\"))\n\nprint (\"\\nes una palabra isograma?\")\nisograma(\"Casoo\")\nisograma(\"saco\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/alejo-digital.py",
    "content": "# 04 CADENA DE CARACTERES\n\n\"\"\"\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\n *   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\n *   interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n\"\"\"\n\n# Operaciones con cadenas de caracteres en Python\n\nmy_string = \"Hola, Mundo!\"\nprint(\"Cadena original:\", my_string)\n# Acceso a caracteres específicos\nprint(\"Primer carácter:\", my_string[0])  # H\nprint(\"Último carácter:\", my_string[-1])  # !\n\n# Subcadenas\nsub_string = my_string[0:4]  # Hola\nprint(\"Subcadena:\", sub_string)\n\n# Longitud\nlength = len(my_string)\nprint(\"Longitud de la cadena:\", length)  # 13\n\n# Concatenación\nanother_string = \" soy Python.\"\nconcatenated_string = my_string + another_string\nprint(\"Cadena concatenada:\", concatenated_string)  # Hola, Mundo! soy Python\n\n# Repetición\nrepeated_string = my_string * 2\nprint(\"Cadena repetida:\", repeated_string)  # Hola, Mundo!Hola, Mundo\n\n# Recorrido\ndef recorrido(a_string):\n    contador_v = 0\n    contador_c = 0\n    for char in a_string:\n        if char in (\"a\", \"e\", \"i\", \"o\", \"u\"):\n            contador_v += 1\n            print(f\"vocal: {char}\")\n        elif char.isalpha():\n            print(f\"consonante: {char}\")\n            contador_c += 1\n        else:\n            print(f\"{char} no es una letra\")\n    print(f\"Total de vocales: {contador_v}\")\n    print(f\"Total de consonantes: {contador_c}\")\n\nrecorrido(concatenated_string)\n\n# Conversión a mayúsculas y minúsculas\n\nupper_string = my_string.upper()\nprint(\"Cadena en mayúsculas:\", upper_string)  # HOLA, MUNDO\nlower_string = upper_string.lower()\nprint(\"Cadena en minúsculas:\", lower_string)  # hola, mundo!\n\n# Reemplazo\nreplaced_string = my_string.replace(\"Mundo\", \"Python\")\nprint(\"Cadena con reemplazo:\", replaced_string)  # Hola, Python!\n\n# División\nsplit_string = my_string.split(\", \")\nprint(\"Cadena dividida:\", split_string)  # ['Hola', 'Mundo!']\n\n# Unión\njoined_string = \" - \".join(split_string)\nprint(\"Cadena unida:\", joined_string)  # Hola - Mundo!\n\n# Interpolación\nname = \"Python\"\ninterpolated_string = f\"Hola, {name}!\"\nprint(\"Cadena interpolada:\", interpolated_string)  # Hola, Python!\n\n# Verificación\nis_alpha = my_string.isalpha()  # False, porque contiene espacios y puntuación\nprint(\"¿La cadena es alfabética?\", is_alpha)\nis_digit = my_string.isdigit()  # False, porque no es numérica\nprint(\"¿La cadena es numérica?\", is_digit)\nis_lower = my_string.islower()  # False, porque contiene mayúsculas\nprint(\"¿La cadena está en minúsculas?\", is_lower)\nis_upper = my_string.isupper()  # False, porque contiene minúsculas\nprint(\"¿La cadena está en mayúsculas?\", is_upper)\n\n\n# DIFICULTAD EXTRA: Análisis de palabras\n\ndef es_palindromo(palabra):\n    palabra = palabra.replace(\" \", \"\").lower()\n    return palabra == palabra[::-1]\n\ndef son_anagramas(palabra1, palabra2):\n    palabra1 = palabra1.replace(\" \", \"\").lower()\n    palabra2 = palabra2.replace(\" \", \"\").lower()\n    return sorted(palabra1) == sorted(palabra2)\n\ndef es_isograma(palabra):\n    palabra = palabra.replace(\" \", \"\").lower()\n    return len(palabra) == len(set(palabra))\n\ndef analizar_palabras(palabra1, palabra2):\n    print(f\"Análisis de las palabras: '{palabra1}' y '{palabra2}'\")\n    \n    if es_palindromo(palabra1):\n        print(f\"'{palabra1}' es un palíndromo.\")\n    else:\n        print(f\"'{palabra1}' no es un palíndromo.\")\n    \n    if es_palindromo(palabra2):\n        print(f\"'{palabra2}' es un palíndromo.\")\n    else:\n        print(f\"'{palabra2}' no es un palíndromo.\")\n    \n    if son_anagramas(palabra1, palabra2):\n        print(f\"'{palabra1}' y '{palabra2}' son anagramas.\")\n    else:\n        print(f\"'{palabra1}' y '{palabra2}' no son anagramas.\")\n    \n    if es_isograma(palabra1):\n        print(f\"'{palabra1}' es un isograma.\")\n    else:\n        print(f\"'{palabra1}' no es un isograma.\")\n\n    if es_isograma(palabra2):\n        print(f\"'{palabra2}' es un isograma.\")\n    else:\n        print(f\"'{palabra2}' no es un isograma.\")\n\n# Ejemplo de uso\npalabra1 = \"Anita lava la tina\"\npalabra2 = \"Ala tita\"\nanalizar_palabras(palabra1, palabra2)"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/alexdevrep.py",
    "content": "'''\n/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\n *   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\n *   interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n'''\n\n# Creamos una cadena de caracteres (String)\n\nmi_string = \"Soy una cadena de caracteres\"\nprint(mi_string)\n\n# Operaciones con cadenas de caracteres \n\n# Acceso a caracteres\nprint(mi_string[5])\n\n#Creación de subcadenas\nprint(mi_string[0:15])\n\n# Longitud de una cadena de caracteres y interpolación de caracteres\nprint(f'Mi cadena tiene {len(mi_string)} caracteres')\n\n# Concatenación de una cadena de caracteres\nmi_string3 = mi_string + \" \" + \"y estoy descubriendo que puedo hacer en python!\"\nprint(mi_string3)\n\n#Repetición de la cadena de caracteres\nmi_string4 = \"Hola python!  \" * 3\nprint(mi_string4)\n\n# Conversión de la cadena a mayúsculas\nmi_string1 = mi_string.upper()\nprint(mi_string1)\n\n# Conversión de la cadena a minúsculas\nmi_string2 = mi_string.lower()\nprint(mi_string2)\n\n#Repetición de la cadena de caracteres\nmi_string4 = \"Hola python!  \" * 3\nprint(mi_string4)\n\n#División de una cadena de caracteres\nmi_string5 = mi_string3.split('estoy')\nprint(mi_string5)\n\n#Reemplazo de caracteres\nmi_string = mi_string.replace('c', 'k')\nprint(mi_string)\n\n#Recorriendo una cadena de caracteres\nnum = 0\nwhile num < len(mi_string):\n    print (mi_string[num])\n    num =num + 1\n\n#Unión de cadenas \ncadena= (\"soy\",\"una\",\"cadena\",\"de\",\"caracteres\")\nmi_string = \"/\".join(cadena)\nprint(mi_string)\n\n#Verficacion de un elemento en una cadena de caracteres\n\nmi_string = \"soy una cadena de caracteres\"\nprint(mi_string.isdecimal())\nprint(mi_string.isdigit())\nprint(mi_string.isalnum())\nprint(mi_string.isalpha())\nprint(mi_string.isascii())\nprint(mi_string.isidentifier())\nprint(mi_string.islower())\nprint(mi_string.isnumeric())\n\n\n#Dificultad extra\n'''\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n'''\npalabra4 = input(\"Introduce la primera palabra a al sistema: \")\npalabra5 = input(\"Introduce la segunda palabra al sistema: \")\npalabra4invertida = palabra4[::-1].lower\npalabra5invertida = palabra5[::-1].lower\ndef palindromo(palabra4invertida , palabra5invertida): # Un palíndromo es una palabra que puede leerse de la misma forma de izquierda a derecha que de derecha a izquierda\n       \n       if palabra4invertida == palabra4:\n         print(f'La palabra {palabra4} es un palíndromo')\n       else :\n         print (f'La palabra {palabra4} no es un palíndromo')\n\n       if palabra5invertida == palabra5:\n         print(f'La palabra {palabra5} es un palíndromo')\n       else :\n         print (f'La palabra {palabra5} no es un palíndromo')\n        \n\ndef Anagrama(palabra4,palabra5): #Es una palabra que si se ordena de otra manera da lugar a otra palabra distinta roma//amor \n\n    if sorted(palabra4) == sorted(palabra5):\n         print (\"Estas palabras son un anagrama\")\n    else :\n         print (\"Estas palabras no son un anagrama\")\n\n\ndef Isograma (palabra4,palabra5): # Un isograma es una palabra que no tiene letras repetidas\n   \n   if len(set(palabra4)) == len(palabra4):\n        print (\"Esta palabra es un isograma\")\n   else:\n    print(\"Esta palabra no es un isograma\")\n\n   if len(set(palabra5)) == len(palabra5):\n        print (\"Esta palabra es un isograma\")\n   else:\n        print(\"Esta palabra no es un isograma\")\n   \n\npalindromo(palabra4invertida,palabra5invertida)\nAnagrama(palabra4,palabra5)\nIsograma(palabra4,palabra5)\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/andres54-coder.py",
    "content": "'''\nopereaciones con cadenas de caracteres\n'''\n\nname = \"Andres\"\nlastname = \"Rapster21\"\n\n#concatenar\nprint(name + \" \" + lastname)\n\n#repetir\nprint(f\"{name} \" * 3)\n\n#indexacion\nprint(name[0], name[1], name[2], name[3], name[4], name[5])\n\n#slicing\nprint(name[0:3])\n\n#buscar\nprint(\"d\" in name)\n\n#longitud\nprint(len(name))\n\n#mayusculas\nprint(name.upper())\n\n#minusculas\nprint(name.lower())\n\n#capitalizar\nprint(name.capitalize())\n\n#reemplazar\nprint(name.replace(\"A\", \"X\"))\n\n#buscar\nprint(name.find(\"d\"))\n\n#contar\nprint(name.count(\"e\"))\n\n#eliminar espacios\nprint(\"   Andres  Rapster21  \".strip())\n\n#comparar\nprint(name == \"Andres\")\n\n#saber si empieza con\nprint(name.startswith(\"A\"))\n\n#saber si termina con\nprint(name.endswith(\"s\"))\n\n#separar\nprint(name.split(\"n\"))\n\n#unir\nprint(\" \".join(name))\n\n#interpolacion\nprint(f\"{name} {lastname}\")\n\n#formatear\nprint(\"{} {}\".format(name, lastname))\n\n#formatear\nprint(\"{1} {0}\".format(name, lastname))\n\n#formatear\nprint(\"{lastname} {name}\".format(name=name, lastname=lastname))\n\n#formatear\nprint(\"{lastname} {name}\".format_map({\"name\": name, \"lastname\": lastname}))\n\ns3 = \"Andres Rapster21 @gmail\"\n\n#transformacion en lista de caracteres\nprint(list(s3))\n\n#comprobacion de caracteres\nprint(s3.isalnum())\nprint(s3.isalpha())\nprint(s3.isascii())\nprint(s3.isdecimal())\nprint(s3.isdigit())\nprint(s3.isidentifier())\nprint(s3.islower())\nprint(s3.isnumeric())\nprint(s3.isprintable())\nprint(s3.isspace())\nprint(s3.istitle())\nprint(s3.isupper())\n\n'''\nExtra\n'''\n\ndef check(word1: str, word2: str) -> bool:\n    \n    def is_isogram() -> bool:\n        word_dict = dict()\n        for word in word2:\n            word_dict[word] = word_dict.get(word, 0) + 1\n            \n        isogram = True\n        values = list(word_dict.values())\n        isogramlen = values[0]\n        for wordcount in values:\n            if isogramlen != wordcount:\n                isogram = False\n                break\n        return isogram\n    #palindromo\n    print(f\"¿{word1} es palindromo?: {word1 == word1[::-1]}\") \n    print(f\"¿{word2} es palindromo?: {word2 == word2[::-1]}\") \n    #anagrama\n    if sorted(word1) == sorted(word2):\n        print(f\"La palabra {word1} es anagrama de {word2}\")\n    #isograma\n    print(f\"¿{word2} es isograma?: {is_isogram()}\")\n    \n    \ncheck(\"amor\", \"romaroma\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/andresgcastillo.py",
    "content": "# Crear una cadena de caracteres\ncadena = \"Hola Mundo\"\n\n# Acceso a caracteres específicos\nprint(cadena[0])  # H\n\n# Subcadenas\nprint(cadena[0:4])  # Hola\n\n# Longitud\nprint(len(cadena))  # 10\n\n# Concatenación\ncadena2 = \" Python\"\nprint(cadena + cadena2)  # Hola Mundo Python\n\n# Repetición\nprint(cadena * 2)  # Hola MundoHola Mundo\n\n# Recorrido\nfor caracter in cadena:\n    print(caracter)\n\n# Conversión a mayúsculas\nprint(cadena.upper())  # HOLA MUNDO\n\n# Conversión a minúsculas\nprint(cadena.lower())  # hola mundo\n\n# Reemplazo\nprint(cadena.replace(\"Mundo\", \"Python\"))  # Hola Python\n\n# División\nprint(cadena.split(\" \"))  # ['Hola', 'Mundo']\n\n# Unión\nlista = ['Hola', 'Mundo']\nprint(\" \".join(lista))  # Hola Mundo\n\n# Interpolación\nnombre = \"Python\"\nprint(f\"Hola {nombre}\")  # Hola Python\n\n# Verificación\nprint(\"Mundo\" in cadena)  # True\n\n#Dificultad Extra\n\ndef es_palindromo(palabra):\n    return palabra == palabra[::-1]\n\ndef es_anagrama(palabra1, palabra2):\n    return sorted(palabra1) == sorted(palabra2)\n\ndef es_isograma(palabra):\n    return len(palabra) == len(set(palabra))\n\n# Prueba\npalabra1 = \"anagram\"\npalabra2 = \"nagaram\"\n\nprint(f\"¿'{palabra1}' es un palíndromo? {es_palindromo(palabra1)}\")\nprint(f\"¿'{palabra1}' y '{palabra2}' son anagramas? {es_anagrama(palabra1, palabra2)}\")\nprint(f\"¿'{palabra1}' es un isograma? {es_isograma(palabra1)}\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/annerssv.py",
    "content": "#CADENAS\n\nmi_cadena = \"Hola soy una cadena de caracteres\"\nmi_cadena_vacia = ''\n\nprint(type(mi_cadena))\nprint(len(mi_cadena))  #Longitud de caracteres de una cadena\nprint(mi_cadena_vacia)\n\n#SECUENCIAS DE ESCAPE\n\nsec_esc = \"Esta es una cadena con comillas simples dentro \\\"HOLA\\\" \"\nprint(sec_esc)\n\n#SALTO DE LINEA\n\nsalt_linea = \"Esta es una cadena\\n con saltos de linea\"\nprint(salt_linea)\n\n#FORMATEO DE CADENAS E INTERPOLACIÓN\n\nnumero_a_cadena = 12345\nprint(\"El numero es \" + str(numero_a_cadena))\n\n#ESTILO PRINTF\n\nn1 = 5\nresultado_formateo = \"El numero formateado es %d\" % n1\nprint(resultado_formateo)\n\nresultado_formateo = \"Los numeros formateados son {} y {}\".format(4, 3)\nprint(resultado_formateo)\n\n#INTERPOLACION O F-STRINGS\n\nn1 = 20\nn2 = 30\nsuma = n1 + n2\nsuma_formateada = str(n1) + str(n2)  #FORMATEO A CADENAS\n\nprint(f'La suma de {n1} + {n2} = {suma}')\nprint(f'La suma formateada de {n1} + {n2} = {suma_formateada}'\n      )  #NO SE REALIZA LA SUMA, SE CONCATENAN LOS VALORES FORMATEADOS\n\n#SUMA DE CADENAS\n\ncadena_1 = \"Hola soy la primera parte...\"\ncadena_2 = \"y yo soy la segunda parte!\"\n\nprint(cadena_1 + \" \" + cadena_2)\n\n#REPETIR UNA CADENA n VECES\n\ncadena_repetida = \"Hola soy una cadena repetida \\n\"\nprint(cadena_repetida * 5)\n\n#SABER SI UNA CADENA ESTA CONTENIDA EN OTRA\n\ncadena = \"Python es clave\"\n\nprint(\"thon\" in cadena)  #True\n\n#ACCEDER A LOS VALORES DE UNA CADENA COMO EN UNA LISTA\n\nmi_cadena = \"Hola\"\nprint(mi_cadena[0])  #ACCEDER AL PRIMER CARACTER\n\n#CORTAR CADENAS O SLICING\n\nprint(mi_cadena[0:2])  #EMPIEZA DESDE EL INDICE 0 AL 2\nprint(mi_cadena[2:])  #EMPIEZA DEL INDICE 2 HASTA EL FINAL\nprint(mi_cadena[0::2])  #CORTA LA CADENA DE 2 en 2\nprint(mi_cadena[::-1])  #INVIERTE LA CADENA\n\n#METODOS DE CADENA\n\ncadena = \"hola soy una cadena que sera modificada\"\nprint(\n    cadena.capitalize())  #PONE LA PRIMERA LETRA DE TODA LA CADENA EN MAYUSCULA\nprint(cadena.upper())  #CONVIERTE A MAYUSCULA TODA LA CADENA\nprint(cadena.lower())  #CONVIERTE A MINUSCULA TODA LA CADENA\nprint(cadena.swapcase())  #VARIACION ENTRE MAYUSCULAS Y MINUSCULAS\nprint(cadena.title())  #CONVIERTE LA PRIMERA LETRA DE CADA PALABRA EN MAYUSCULA\nprint(\n    cadena.count(\"ca\")\n)  #EVALUA CUANTAS VECES SE REPITE SE REPITE UN FRAGMENTO DE CADENA EN OTRA\nprint(cadena.replace(\"hola\", \"Hey\"))\n\nmi_cadena = \"correo@gmail.com\"\nprint(mi_cadena.isalnum())  #EVALUA SI LA CADENA ESTA FORMADA POR CARACTERES ALFANUMERICOS\nmi_cadena = \"soy una cadena normal\"\nprint(mi_cadena.isalpha())  #EVALUA SI LA CADENA ESTA FORMADA POR CARACTERES ALFABETICOS\n\ncadena = \" Hola soy una cadena que tenia espacios al inicio y al final \"\nprint(cadena.strip())  #ELIMINA ESPACIOS AL INICIO Y FINAL DE LA CADENA\n\nnumero = 345\nprint(str(numero).zfill(\n    7))  #RELLENA CON 0 HASTA LLEGAR AL NUMERO PASADO COMO PARAMETRO\n\ncadena = \" y \".join([\"1\", \"2\", \"3\", \"4\", \"5\"])  #UNIR UNA CADENA A UNA LISTA\nprint(cadena)\n\ncadena_a_lista = \"Python, Java, C++, Typescritp\"\nprint(\n    cadena_a_lista.split(\",\")\n)  #DIVIDE Y CONVIERTE LA CADENA EN UN ARRAY DEPENDIENDO EL PARAMETRO PASADO\n\n#RECORRER UNA CADENA\nfor cadena in mi_cadena:\n    print(cadena)\n\n#EJERCICIO ---------------------------------------------------------------------\n\nsalir = False\n\n#FUNCIONES PARA EVALUAR LAS PALABRAS\n\n\ndef esPalindromo():\n    palabra = input('Ingresa la palabra a evaluar: ')\n\n    palabra_invertida = palabra[::-1]\n\n    if palabra.lower() == palabra_invertida.lower():\n        print(f'La palabra {palabra} es palindroma')\n    else:\n        print(f'La palabra {palabra} no es palindroma')\n\n\ndef esAnagrama():\n    palabra_1 = input(\"Ingrese palabra 1: \")\n    palabra_2 = input(\"Ingrese palabra 2: \")\n\n    if sorted(palabra_1) == sorted(palabra_2):\n        print(\"Las palabras ingresadas son anagramas\")\n    else:\n        print(\"Las palabras ingresadas no son anagramas\")\n\n\ndef esIsograma(palabra):\n    letras = set()\n    palabra = palabra.lower()\n\n    for letra in palabra:\n        if letra.isalpha():\n            if letra in letras:\n                return False\n            letras.add(letra)\n    return True\n\n\ndef evaluarIsograma():\n\n    palabra_1 = input(\"Ingrese palabra 1: \").strip()\n    palabra_2 = input(\"Ingrese palabra 2: \").strip()\n\n    isograma_1 = esIsograma(palabra_1)\n    isograma_2 = esIsograma(palabra_2)\n\n    if isograma_1 and isograma_2:\n        print(f\"Ambas palabras '{palabra_1}' y '{palabra_2}' son isogramas.\")\n    elif isograma_1 and not isograma_2:\n        print(\n            f\"La palabra '{palabra_1}' es un isograma, pero '{palabra_2}' no lo es.\"\n        )\n    elif not isograma_1 and isograma_2:\n        print(\n            f\"La palabra '{palabra_2}' es un isograma, pero '{palabra_1}' no lo es.\"\n        )\n    else:\n        print(\n            f\"Ninguna de las dos palabras ('{palabra_1}' y '{palabra_2}') es un isograma.\"\n        )\n\n\nwhile not salir:\n\n    #MENU INTERACTIVO\n\n    print('''---BIENVENIDO AL EVALUADOR DE PALABRAS---\\n\n            1. Evaluar palindromos\n            2. Evaluar Anagramas\n            3. Evaluar Isogramas\n            4. Salir''')\n\n    opcion = input('Ingresa una opción: ').strip()\n\n    match opcion:\n        case '1':\n            esPalindromo()\n        case '2':\n            esAnagrama()\n        case '3':\n            evaluarIsograma()\n        case '4':\n            print('Saliendo del programa...')\n            salir = True\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/any7dev.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */ \"\"\"\n\ncadena1 = \"mi cadena\"\ncadena2 = \"Mi Cadena\"\ncadena3 = \"micadena\"\ncadena4 = \" micadena \"\ncadena0 = \"otra cadena\"\ncadena7 = \"mi cadena\"\ncadena8 = \"012345\"\nnumeros = 123\n\n# Formateo de cadena, interpolación\nprint(f\"Esta es {cadena1}, {cadena0} y una cadena de números {cadena8}\")\nprint(\"Esta es %s, %s y una cadena de números %s\" %(cadena1, cadena0, cadena8))\nprint(\"Esta es {0}, {1} y una cadena de números {2}\".format(cadena1, cadena0, cadena8))\nprint(f\"Esta es {cadena1} y estos unos números {numeros}\")\nprint(\"Esta es %s y estos unos números %d\" %(cadena1, numeros))\nprint(\"Esta es {0} y estos unos números {1}\" .format(cadena1, numeros))\n\n# Concatenar cadenas\nprint(cadena1 + \" \" + cadena0)\ncadena7 += cadena0\nprint(cadena7)\n\n# Multiplicar cadena, repetición\nprint(cadena1*5)\n\n# Invertir cadena\nprint(cadena1[::-1])\n\n# Saber si una cadena está en otra cadena\nprint(cadena1 in cadena0)\nprint(\"mi\" in cadena1)\n\n# Contar las veces que aparece una cadena en otra\nprint(cadena1.count(\"ca\"))\n\n# Devolver la posición en la que se encuentra\nprint(cadena1.find(\"de\"))\n\n# Accede al caracter que te interesa\nprint(cadena1[3])\nprint(cadena1[-1])\n\n# Se puede mostrar la subcadena que quieras, división\nprint(cadena1[0:5])\nprint(cadena1[2:5])\nprint(cadena1[2:])\nprint(cadena1[0:5:2])\nprint(cadena1[0::2])\n\n# Pone la primera letra en mayúsculas\nprint(cadena1.capitalize())\n\n# Todo en mayúsculas\nprint(cadena1.upper())\n\n# Todo en minúsculas\nprint(cadena1.lower())\n\n# Te dice si la cadena está en minúsculas\nprint(cadena1.islower())\n\n# Te dice si la cadena está en mayúsculas\nprint(cadena1.isupper())\n\n# Cambia las mayúsculas por minúsculas y viceversa\nprint(cadena2.swapcase())\n\n# Reemplazar\nprint(cadena1.replace(\"a\", \"4\"))\n\n# Te dice si la cadena es alfanumérica\nprint(cadena1.isalnum())\n\n# Te dice si todos los caracteres son alfabéticos\nprint(cadena3.isalpha())\n\n# Te dice si es una cadena numérica\nprint(cadena8.isnumeric())\n\n# Te dice si son dígitos\nprint(cadena8.isdigit())\n\n# Te dice la longitud de la cadena\nprint(len(cadena1))\n\n# Elimina los espacios que tenga la cadena a la izquierda y/o derecha\nprint(cadena4.strip())\n\n#Divide cadena en subcadenas en forma de lista\nprint(cadena1.split(\" \"))\n\n# De una lista devuelve una cadena\ncadena5 = \" \".join([\"Esto\", \"es\", \"otra\", \"cadena\"])\nprint(cadena5)\n\n\n#DIFICULTAD EXTRA (Me he ceñido a lo que pone tal cuál, no me he querido complicar con tema acentos y mayúsculas)\n\ndef extra(pal1, pal2):\n    if pal1 == pal1[::-1]:\n        print(f\"{pal1} es un palíndromo\")\n    else:\n        print(f\"{pal1} no es un palíndromo\")\n    if pal2 == pal2[::-1]:\n        print(f\"{pal2} es un palíndromo\")\n    else:\n        print(f\"{pal2} no es un palíndromo\")\n\n    print(\"-------------\")\n\n    if pal1 == pal2[::-1]:\n        print(f\"{pal1} y {pal2} son anagramas\")\n    else:\n        print(f\"{pal1} y {pal2} no son anagramas\")\n\n    print(\"-------------\")\n\n    contador = 0\n    for caracter in pal1:\n        if pal1.count(caracter) == 1:\n            contador += 1\n            continue\n        else:\n            print(f\"{pal1} no es isograma\") \n            break\n    if contador == len(pal1):\n        print(f\"{pal1} es isograma\")\n    contador = 0\n    for caracter in pal2:\n        if pal2.count(caracter) == 1:\n            contador += 1\n            continue\n        else:\n            print(f\"{pal2} no es isograma\") \n            break\n    if contador == len(pal2):\n        print(f\"{pal2} es isograma\")               \n\n    print(\"-------------\")    \n\nif __name__ == '__main__':\n    extra(\"radar\", \"oyo\")\n    extra(\"amor\", \"roma\")\n    extra(\"aba\", \"dermatoglyphics\")\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/augustdev2003.py",
    "content": "\"\"\"\nCadenas de caractéres\n\"\"\"\n\nmsg1 = '¿Sabes de qué trabajo?'\nmsg2 = 'De programador'\n\n# Curiosidades sobre print()\nprint(msg1, msg2) # Concatenación\nprint(msg1, msg2, sep=\"|\")\nprint(msg1, msg2, end=\"!!\")\n\nprint(\"\")\n\n\"\"\"Conversión a mayúsculas y minúsculas\"\"\"\n\nmy_string = \"esta es una CAdena de caracteres\"\n\nprint(my_string.capitalize()) # Cambia el primer caracter de la cadena por mayúscula.\nprint(my_string.upper()) # Cambia todos los caracteres por mayúsculas.\nprint(my_string.lower()) # Cambia todos los caracteres por minúsculas.\nprint(my_string.title()) # El primer caracter de cada palabra será convertido en mayúscula.\nprint(my_string.swapcase()) # Convierte las minúsculas en mayúsculas, y viceversa.\n\n\"\"\"Longitud\"\"\"\n\nprint(len(my_string)) # Longitud de la cadena de caracteres.\n\n\"\"\"Repetición\"\"\"\n\nprint(my_string * 4) # Repetir cadenas.\n\n\"\"\"Obtención de caracteres\"\"\"\n\nprint(my_string[1]) # Obtener un caracter.\nprint(my_string[-1])\n\n\"\"\"Subcadenas\"\"\"\n\nprint(my_string[4:]) # Obtener sub-cadenas.\nprint(my_string[:20]) # Todos los caracteres hasta el índice 20.\nprint(my_string[0:15]) # Caracteres desde el indice 0 hasta el 15.\nprint(my_string[5:11:2]) # Caracteres desde el índice 5 hasta el 11 haciendo saltos de 2.\n\n\"\"\"Pertenencia\"\"\"\n\nprint(\"esta\" in my_string)\nprint(\"no\" is not my_string)\nprint(\"hola\" in my_string)\n\nnumber = \"\\n\\t     18234612\\n\\n\\n   \\n\\t\"\n\n# Eliminar caracteres\nprint(number.strip()) # Elimina todos los caracteres al principio y final de la cadena.\nprint(number.rstrip()) # Elimina todos los caracteres que estén a la derecha de la cadena.\nprint(number.lstrip()) # ELimina todos los caracteres que estén a la izquierda de la cadena.\n\n\"\"\"Búsquedas\"\"\"\n\nlarge_text = \"\"\"Python es un lenguaje de programación\nque se utiliza para Backend, Automatización\nCiencia de datos, Análisis de datos, etc.\n\"\"\"\n\nprint(large_text.startswith(\"Python\")) # Comprueba si empieza con la subcadena dada.\nprint(large_text.endswith(\"programación\")) # Comprueba si termina con la subcadena dada.\n\nprint(large_text.find('Backend')) # Devuelve el índice donde se encuentra la subcadena, si no la encuentra, devuelve -1.\nprint(large_text.index('Análisis')) # Devuelve el índice donde se encuentra la subcadena, si no la encuentra, devuelve un error.\n\nprint(large_text.count('de')) # Contabiliza el número de veces que aparece una subcadena\n\n\"\"\"Reemplazo\"\"\"\n\ntext = \"Quien mal anda mal acaba\"\n\nprint(text.replace('mal', 'bien')) # El primer argumento es la subcadena a reemplazar, el segundo es la subcadena de reemplazo.\nprint(text.replace('mal', 'bien', 1)) # Podemos indicar las veces que queremos reemplazar una subcadena.\n\n\"\"\"Identificación\"\"\"\n\nprint('rd29'.isalnum()) # Detecta si los caracteres de una cadena son letras o numeros.\nprint('asj-29'.isalnum())\n\nprint('183'.isnumeric()) # Detecta si los caracteres de una cadena son numeros.\nprint('3.14'.isnumeric())\n\nprint('abcdef'.isalpha()) # Detecta si los caracteres de una cadena son letras.\nprint('a-b-c-d'.isalpha())\n\nprint('UPPER'.isupper()) # Detecta si los caracteres de una cadena son mayúsculas.\nprint('lower'.islower()) # Detecta si los caracteres de una cadena son minúsculas.\nprint('Hola Python'.istitle()) # Detecta si las palabras de una cadena empiezan con mayúscula.\n\n\"\"\"Interpolación\"\"\"\n\nname = 'Augusto'\nage = 20\nbirthday = '28-08'\n\nf_string = f'Me llamo {name}, tengo {age} años y mi cumpleaños es el {birthday}'\nprint(f_string)\n\n# Formato a valores enteros\n\ncurrent_year = 2024\n\nprint(f'{current_year:10d}') # d viene de 'entero decimal'\nprint(f'{current_year:010d}')\n\n# Formato a valores flotantes\n\nPI = 3.14159265\n\nprint(f'{PI:f}') # Por defecto son 6 decimales\nprint(f'{PI:3f}') # f viene de 'flotante'\n\n# Formato a cadenas de texto\n\nmy_text1 = \"how\"\nmy_text2 = \"are\"\nmy_text3 = \"you\"\n\nprint(f'{my_text1:<7s}|{my_text2:^11s}|{my_text3:>7s}')\nprint(f'{my_text1:-<7s}|{my_text2:.^11s}|{my_text3:->7s}')\n\n\"\"\"Recorrido\"\"\"\n\nlanguage = 'Español'\n\nfor x in language:\n    print(x)\n\n\"\"\"División\"\"\"\n\nprograming_languages = \"Python, Java, PHP, JavaScript, Dart\"\nprint(programing_languages.split(',')) # Divide la cadena en una lista. En este caso lo separamos según las comas.\n\n\"\"\"Unión\"\"\"\n\nmy_list = programing_languages.split(',')\nprint(\" -\".join(my_list)) # Une los valores de la lista en un string. En este caso separamos los elementos con \" -\"\n\n\"\"\"\nDificultad EXTRA\n\"\"\"\n\ndef analyze_words(word1, word2):\n\n    print(f'¿{word1} y {word2} son anagramas? -> {sorted(word1) == sorted(word2)}')\n\n    def no_space(text):\n        nuevo_texto = \"\"\n        for char in text:\n            if char != \" \":\n                nuevo_texto += char\n        return nuevo_texto\n    \n    def es_palindromo(text):\n        text = no_space(text)\n        result = ''\n        for char in text:\n            result += char\n        if result[::-1].capitalize() == text:\n            return True\n        else:\n            return False\n    \n    return (f'¿{word1} y {word2} son palíndromos? -> {es_palindromo(word1)}, {es_palindromo(word2)}')\n        \nprint(analyze_words('Amo la paloma', 'Oso'))\nprint(analyze_words('Abba', 'Reconocer'))\nprint(analyze_words('Hola Mundo', 'Somos o no somos'))\nprint(analyze_words('lacteo', 'coleta'))"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/avcenal.py",
    "content": "\"\"\"\nCADENAS DE CARACTERES\n\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\n *   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\n *   interpolación, verificación...\n\"\"\"\n\nmy_string = \"Mi nombre es Alex\"\n# Acceso a caracteres específicos\nprint(\"Acceso a caracteres específicos\")\nprint(f\"Podemos acceder a caracteres específicos por medio del índice del string, por ejemplo, en \\\"{my_string}\\\", para acceder al caracter en la posición 4 my_string[4] --> {my_string[4]}\")\nprint(f\"O en la posición 7 my_string[7] --> {my_string[7]}\")\nprint(f\"O desde el final contando con que el último caracter tendría el índice -1 y hacia el primer caracter sería incremental, por ejemplo my_string[-12]: {my_string[-12]}\")\n# Longitud\nprint(\"\\n\")\nprint(\"Longitud\")\nprint(f\"Podemos obtener la longitud con len(my_string): {len(my_string)}\")\n# Subcadenas\nprint(\"\\n\")\nprint(\"Subcadenas\")\nprint(f\"Podemos crear subcadenas especificando dos índices, uno inicial y otro final, por ejemplo my_string[3:12]: {my_string[3:12]}\")\nprint(f\"Solo el índice inicial y nos mostrará desde ese índice hasta el final, my_string[5:]: {my_string[5:]}\")\nprint(f\"O únicamente el índice del final que nos mostrará desde el inicio hasta ese caracter, my_string[:9]: {my_string[:9]}\")\nprint(f\"O subcadenas con índices negativos, my_string[:-3]: {my_string[:-3]}, o my_string[-11:-5]: {my_string[-11:-5]} o my_string[-14:]: {my_string[-14:]}\")\n# Cadenas y Subcadenas inversas\nprint(\"\\n\")\nprint(\"Cadenas y Subcadenas inversas\")\nprint(f\"También podemos crear cadenas invertidas con my_string[::-1]: {my_string[::-1]}, que devolvería la cadena inversa completa\")\nprint(f\"o si usamos un índice -2 por ejemplo my_string[::-2], nos de vuelve la cadena inversa menos los caractéres en los múltiplos de 2: {my_string[::-2]}\")\n# Mayúsuclas y minúsculas\nprint(\"\\n\")\nprint(\"Mayúsuclas y minúsculas\")\nprint(f\"podemos pasar a mayúsuclas todo con upper(): {my_string.upper()}\")\nprint(f\"O a minúsuclas con lower():{my_string.lower()}\")\nprint(f\"O también poner las primeras letras de cada palabra en mayúsculas con title(): {my_string.title()}\")\nprint(f\"O con capitalize(), solo la primera palabra con mayúscula: {my_string.capitalize()}\")\n# Repetición\nprint(\"\\n\")\nprint(\"Repetición\")\nprint(f\"Podemos contar las ocurrencias de una serie de caractéres dentro de la cadena con count, por ejemplo my_string.count(\\\"e\\\"): La letra \\\"e\\\" aparece {my_string.count(\"e\")} veces\")\n# Recorrido\nprint(\"\\n\")\nprint(\"Recorrido\")\nprint(\"Podemos recorrer el string con un bucle del tipo \\\"for char in my_string:\\\" e ir imrimiendo cada caracter\")\nfor char in my_string:\n    print(char)\n\nprint(\"\\n\")\nprint(\"O usando un índice + un rango del tipo \\\"for index in range(0,len(my_string))\\\". También podría hacerse con un While\")\nfor index in range(0,len(my_string)):\n    print(my_string[index])\n#Reemplazo\nprint(\"\\n\")\nprint(\"Reemplazo\")\nprint(f\"También podemos reemplazar un caracter o una subcadena con replace() {my_string.replace(\"e\",\"a\")}\")\n# División\nprint(\"\\n\")\nprint(\"División\")\nprint(f\"Podemos crear una lista a partir de split(), dándole como argumento lo que \\\"separará\\\" cada elemento de esa lista: {my_string.split(\" \")}\")\n# Concatenación\nprint(\"\\n\")\nprint(\"Concatenación\")\nprint(f\"Lo más sencillo para unir o concatenar dos strings es con el operador \\\"+\\\": {my_string + \" y me gusta Python\"}\")\nprint(f\"Aunque también se pueden usar \\\"*\\\" para repetir un texto y que quede concatenado: {\"Hola \"* 5}\")\n# Búsqueda\nprint(\"\\n\")\nprint(\"Búsqueda\")\nprint(f\"podemos utilizar find() para obtener el índice de la primera ocurrencia de un caracter o una subcadena: {my_string.find(\"Alex\")}\")\nprint(f\"Obtendremos el mismo resultado con index(): {my_string.index(\"Alex\")}, aunque funciona es un método que se usa en listas\")\n# Formatos\nprint(\"\\n\")\nprint(\"Formatos\")\nprint(f\"Podemos aplicar un formato al texto, tipo tabulación con métodos como center(): {my_string.center(55,\"*\")}\")\n#Verificación inicio/fin\nprint(\"\\n\")\nprint(\"Verificación inicio/fin\")\nprint(f\"Se puede comprobar si una cadena comienza por un caracter o subcadena con startswith(): {my_string.startswith(\"Mi\")}\")\nprint(f\"O si finaliza con otro: {my_string.endswith(\"Alex\")}\")\n#Verificación\nprint(\"\\n\")\nprint(\"Verificación\")\nprint(f\"Podemos comprobar si una cadena solo contiene números con isnumeric(): {\"1234\".isnumeric()} o con isdigit(): {\"1234\".isnumeric()}\")\nprint(f\"Si es alfanumérica con isalnum(): {\"AlexS117\".isalnum()}\")\nprint(f\"Si contiene solo caracteres del alfabeto con isalpha(): {\"Alejandro\".isalpha()}\")\nprint(f\"Si todas las letras son minúsculas con islower(): {\"hola que tal\".islower()}, o mayúsculas con isupper(): {\"HOLA QUE TAL\".isupper()}\")\n\nprint(\"\\n\")\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n\"\"\"\ndef normalize_string(one_text):\n    special_chars={\n            \"á\":\"a\",\n            \"é\":\"e\",\n            \"í\":\"i\",\n            \"ó\":\"o\",\n            \"ú\":\"u\",\n            \"ü\":\"u\"\n    }\n    one_text = one_text.lower()\n    for key in special_chars:\n        one_text = one_text.replace(key,special_chars[key])\n    return one_text\n\ndef is_palindrome (string_one, string_two):\n    if len(string_one) != len(string_two):\n        return False\n    else:\n        string_one = normalize_string(string_one)\n        string_two = normalize_string(string_two)\n        inverted_string = string_one[::-1]\n        for index in range (0,len(string_two)):\n            if string_two[index] != inverted_string[index]:\n                return False    \n        return True\n\ndef is_anagram(string_one,string_two):\n    if len(string_one) != len(string_two):\n        return False\n    else:\n        string_one = normalize_string(string_one)\n        string_two = normalize_string(string_two)\n        set_string_one = set()\n        for char in string_one:\n            set_string_one.add(char)\n        for char in string_two:\n            if char not in set_string_one:\n                return False\n        return True\n    \ndef is_isogram(string_one,string_two):\n    new_string = string_one + string_two\n    string_one = normalize_string(string_one)\n    string_two = normalize_string(string_two)\n    limit = new_string.count(new_string[0])\n    for char in new_string:\n        if new_string.count(char)!= limit:\n            return False\n        \n    return True\n\n    \nprint(is_palindrome(\"AniMaL\",\"lÁMina\"))\n\nprint(is_anagram(\"Frase\",\"freSA\"))\n\nprint(is_isogram(\"aaabbb\",\"cccddd\"))\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/blancowilson.py",
    "content": "string1 = \"Hi \"\nstring2 = \"Python\"\n\nstring_result = string1 + string2\n\nprint(string_result)\n\nprint(string1*3)\n\nfor leter in string1:\n    print(leter)\n\nprint(len(string_result))\n\n# dividir\nprint(string_result[2:6])\nprint(string_result[2:])\n\nprint ('t' in string_result)\nprint (string_result.replace('Hi', 'Hello'))\n\nprint(string_result.split('P'))\n\nprint(string_result.upper())\nprint(string_result.lower())\nprint(string_result.capitalize())\nprint(string_result.title())\n\nstring_list = [string1,', ', string2]\nprint(string_list)\n\ndef verify_string(word1: str, word2:str ):\n    print(f\"{word1}  {'Is' if word1 == word1[::-1] else 'is Not'} a Palindromo\")\n    print(f\"{word2}  {'Is' if word2 == word2[::-1] else 'is Not'} a Palindromo\")\n\n    print(f\"{word1}  {'Is' if sorted(word1) == sorted(word2) else 'is Not'} Anagrama of {word2}\")\n\nverify_string('amor','roma')"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/c3sarmx.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\n *   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\n *   interpolación, verificación...\n */\n\"\"\"\n\n# Indices\ntexto = \"Python\"\nprint(texto[0])   # P\nprint(texto[3])   # h\nprint(texto[-1])  # n (último)\n\n# Subcadenas (slicing)\ntexto = \"Python\"\nprint(texto[0:3])   # Pyt \nprint(texto[2:])    # thon\nprint(texto[:4])    # Pyth\n#* Regla -> inicio : fin (fin no incluido)\n\n# Longitud\ntexto = \"Python\"\nprint(len(texto))  # 6\n\n# Concatenación\nnombre = \"Lio\"\nlenguaje = \"Python\"\n\nprint(nombre + \" aprende \" + lenguaje)\n\n# Repetición\nprint(\"🔥\" * 3)\nprint(\"Hola \" * 2)\n\n# Recorrer un string\nfor letra in \"Python\":\n    print(letra)\n\n# Mayusculas y minusculas\ntexto = \"PyThOn\"\n\nprint(texto.upper())\nprint(texto.lower())\nprint(texto.capitalize())\n\n# Reemplazo \ntexto = \"Hola mundo\"\nprint(texto.replace(\"mundo\", \"Python\"))\n\n# División (split)\nfrase = \"Python es brutal\"\npalabras = frase.split(\" \")\nprint(palabras)\n\n# Union (join)\npalabras = [\"Python\", \"es\", \"brutal\"]\nfrase = \" \".join(palabras)\nprint(frase)\n\n# Interpolación (f strings)\nnombre = \"Lio\"\nedad = 26\n\nprint(f\"{nombre} tiene {edad} años\")\n\n# Verificación\ntexto = \"Python123\"\n\nprint(texto.isalpha())   # False #* ¿Solo letras?\nprint(texto.isdigit())   # False #* ¿Solo números?\nprint(texto.isalnum())   # True #* ¿Letras y/o números?\nprint(\"Python\" in texto) # True #* ¿Solo espacios?\n\n# Busqueda\nprint(\"P\" in texto)\n\n# Mayusculas y minusculas\nstring = \"Hola Python\"\nprint(string.upper()) # Mayusculas\nprint(string.lower()) # Minusculas\nprint(string.title()) # Primer letra de cada palabra en Mayusculas\n\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n* Crea un programa que analice dos palabras diferentes y realice comprobaciones\n* para descubrir si son:\n* - Palíndromos\n* - Anagramas\n* - Isogramas\n\"\"\"\n\npalabra1 = input(\"Ingresa una palabra: \").strip().lower()\npalabra2 = input(\"Ingresa otra palabara: \").strip().lower()\n\n# Función que verifica si una palabra es un palíndromo\n# Un palíndromo se lee igual de izquierda a derecha y viceversa\ndef palindromo(palabra):\n    # palabra[::-1] invierte el string\n    return palabra == palabra[::-1]\n\n# Función que verifica si dos palabras son anagramas\n# Dos palabras son anagramas si contienen las mismas letras en distinto orden\ndef anagrama(p1, p2):\n    # sorted() ordena las letras de cada palabra y devuelve una lista\n    # Si ambas listas son iguales, las palabras son anagramas\n    return sorted(p1) == sorted(p2)\n\n# Función que verifica si una palabra es un isograma\n# Un isograma no repite letras\ndef isograma(palabra):\n    # set(palabra) elimina letras duplicadas\n    # Si la longitud del set es igual a la del string original, significa que no había letras repetidas\n    return len(palabra) == len(set(palabra))\n\nprint(\"\\nRESULTADOS\")\n\nprint(f\"¿'{palabra1}' es palindromo?: {palindromo(palabra1)}\")\nprint(f\"¿'{palabra2}' es palindromo?: {palindromo(palabra2)}\")\n\nprint(f\"¿Son anagramas?: {anagrama(palabra1, palabra2)}\")\n\nprint(f\"¿'{palabra1}' es isograma?: {isograma(palabra1)}\")\nprint(f\"¿'{palabra2}' es isograma?: {isograma(palabra2)}\")\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/cbuenrostrovalverde.py",
    "content": "'''\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n '''\n\n# Acceso a caracteres específicos:\ncadena = 'Hola Mundo'\nprint(cadena[0])\n\n# Subcadenas(Indexación)\nprint(cadena[:7])\n\n# Longitud\nprint(len(cadena))\n\n# Concatenación\ncadena1 = 'Hola'\ncadena2 = 'Mundo'\n\nprint(cadena1 + cadena2)\nprint(cadena1 + ' ' + cadena2 + '!')\n\n# Repetición\nprint(cadena1 + cadena1 + cadena1)\nprint(cadena1 * 3)\n\n# Slicing (porción)\nprint(cadena2[2:5])\nprint(cadena2[2:]) # Que empiece desde donde quiero hasta el final\nprint(cadena2[0:2])\nprint(cadena2[:2])\n\n# Búsqueda\nprint(\"H\" in cadena1)\nprint(\"M\" in cadena1)\n\n# Reemplazo\nprint(cadena1.replace(\"o\", \"a\"))\n\n# División\nprint(cadena1.split(\"l\"))\n\n# Mayúsculas y minúsculas\nprint(cadena1.upper())\nprint(cadena2.lower())\nprint('carlos buenrostro'.title())\nprint('carlos buenrostro'.capitalize())\n\n# Eliminación de espacions al principio y al final\nprint('carlos buenrostro valverde'.strip() + ' ' + '@carlosbuenrostrovalverde')\n\n# Búsqueda al principio y al final\nprint(cadena1.startswith('H'))\nprint(cadena1.startswith('M'))\n\n# Búsqueda de posición\nprint('Carlos Buenrostro Valverde @cbuenrostrovalverde'.find('@'))\nprint('Carlos Buenrostro Valverde @cbuenrostrovalverde'.find('l'))\nprint('Carlos Buenrostro Valverde @cbuenrostrovalverde'.lower().find('v'))\n\ncadena3 = 'Carlos Buenrostro Valverde @cbuenrostrovalverde'\n\n# Búsqueda de ocurrencias\nprint(cadena3.lower().find('n'))\n\n# Formateo\nprint('Saludo: {}, Dirigido: {}'.format(cadena1, cadena2) )\n\n# Interpolación\nprint(f'Saludo: {cadena1}, lenguaje: {cadena2}!')\n\n# Transformación en lista de caracteres:\nprint(list(cadena3))\n\n# Transformación de lista en cadena:\ncadena4 = [cadena1, ' ', cadena2, '!']\n\nprint(''.join(cadena4))\n\n# Transformaciones numéricas:\n\ncadena5 = '123456789'\ncadena5 = int(cadena5)\nprint(cadena5)\n\n# Comprobaciones varias:\n\nprint(cadena1.isalnum())\nprint(cadena1.isalpha())\n\n'''\nExtra\n'''\n\n'''Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n '''\n\ndef check(word1: str, word2: str):\n    # Palíndromos: Si inviertes el orden, obtendríamos la misma palabra (radar, asa, etc...)\n    print(f'¿{word1} es una palabra palíndroma?: {word1 == word1[::-1]}')\n    print(f'¿{word2} es una palabra palíndroma?: {word2 == word2[::-1]}')\n\n    # Anagramas: Palabra que resulta de la transposiciónde todas las letras de una palabra. Cambio de orden de las letras.\n    print(f'¿{word1} es una anagrama de {word2}?: {sorted(word1) == sorted(word2)}')\n\n    # Isograma\n    print(f'¿{word1} es una isograma?: {len(word1) == len(set(word1))}')\n    print(f'¿{word2} es una isograma?: {len(word2) == len(set(word2))}')\n\n    word_dict = dict()\n    for word in word1:\n        word_dict[word] = word_dict.get(word, 0) + 1\n\n    isogram = True\n    isogram_len = word_dict.values\n    for word_count in word_dict:\n        if len(word_count) != isogram_len:\n            isogram = False\n            break\n\n# check('roma', 'amor')\ncheck('radar', 'python')\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/cesar-ch.py",
    "content": "# #04 CADENAS DE CARACTERES\n\n# Ejercicio\n\n# Acceso a caracteres específicos\ncadena = \"Hola, mundo!\"\nprint(\"Primer caracter: \", cadena[0])\nprint(\"Último caracter: \", cadena[-1])\n\n# Subcadenas\nsubcadena = cadena[0:4]\nprint(\"Subcadena: \", subcadena)\n\n# Longitud de la cadena\nlongitud = len(cadena)\nprint(\"Longitud: \", longitud)\n\n# Concatenación\ncadena1 = \"Hola\"\ncadena2 = \"Mundo\"\nconcatenacion = cadena1 + \" \" + cadena2\nprint(\"Concatenación: \", concatenacion)\n\n# Repetición\nrepetida = cadena1 * 3\nprint(\"Repetición: \", repetida)\n\n# Recorrido\nfor caracter in cadena:\n    print(caracter)\n\n# Conversión a mayúsculas y minúsculas\nmayusculas = cadena.upper()\nminusculas = cadena.lower()\nprint(\"Mayúsculas: \", mayusculas)\nprint(\"Minúsculas: \", minusculas)\n\n# Reemplazo\nreemplazo = cadena.replace(\"mundo\", \"Python\")\nprint(\"Reemplazo: \", reemplazo)\n\n# División\ndivision = cadena.split(\",\")\nprint(\"División: \", division)\n\n# Unión\nunion = \"-\".join([\"Hola\", \"Python\"])\nprint(\"Unión: \", union)\n\n# Interpolación\nlenguaje = \"Python\"\ninterpolacion = f\"El lenguaje es {lenguaje}.\"\nprint(\"Interpolación: \", interpolacion)\n\n# Verificación\ncontieneHola = \"Hola\" in cadena\ncontieneHola2 = cadena.find(\"Hola\") != -1\nprint(\"Contiene Hola: \", contieneHola)\nprint(\"Contiene Hola: \", contieneHola2)\n\n\n# Dificultad extra\ndef comprobar_palabra(palabra1, palabra2):\n    def es_palindromo(palabra1, palabra2):\n        if len(palabra1) != len(palabra2):\n            return False\n        return palabra1.lower() == palabra2.lower()[::-1]\n\n    print(\"Es palindromo: \", es_palindromo(palabra1, palabra2))\n\n    def es_anagrama(palabra1, palabra2):\n        if len(palabra1) != len(palabra2):\n            return False\n\n        return sorted(palabra1.lower()) == sorted(palabra2.lower())\n\n    print(\"Es anagrama: \", es_anagrama(palabra1, palabra2))\n\n    def es_isogama(palabra1, palabra2):\n        if len(palabra1) != len(palabra2):\n            return False\n\n        char_counter = {}\n        for char in palabra1:\n            if char in char_counter:\n                char_counter[char.lower()] += 1\n            else:\n                char_counter[char.lower()] = 1\n\n        for char in palabra2:\n            if char in char_counter:\n                char_counter[char.lower()] -= 1\n            else:\n                return False\n\n        return all(value == 0 for value in char_counter.values())\n\n    print(\"Es isogama: \", es_isogama(palabra1, palabra2))\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/clmiranda.py",
    "content": "# CADENAS DE CARACTERES\n\n# Acceso a caracteres específicos\ncadena = \"Hola Mundo\"\nprint(cadena[0], cadena[5], cadena[-1])\n\n# Subcadenas\nprint(cadena[:10])\nprint(cadena[::2])\n\n# Verificación\nsubcadena = \"Mundo\"\nprint(subcadena in cadena)\nprint(\"valor\" in cadena)\n\n\n# Longitud\nprint(f\"La cantidad de caracteres de la cadena es: {len(cadena)}\")\n\n# Concatenación\nconcatenar = \" y mas!\"\nprint(cadena + concatenar)\n\n# Interpolación #1\nnombre = \"Cliver\"\nprint(f\"{cadena}, mi nombre es {nombre}\")\n\n# Interpolación #2\nlenguaje, experiencia = \"Python\", 2\nprint(\"Soy desarrollador {lng} con {exp} años de experiencia\".format(lng=lenguaje, exp=experiencia))\n\n# Unión\ncaracter = \"-\"\nprint(caracter.join(\"cadena unida\"))\n\n# Repetición\nprint(\"bugs \" * 3)\n\n# Recorrido\nprint([i for i in cadena])\n\n# Conversión a Mayúsculas\nprint(cadena.upper())\n\n# Conversión a Minúsculas\nprint(cadena.lower())\n\n# Conversión a Capitalizada\ncapitalizada = \"lunes en la mañana\"\nprint(capitalizada.capitalize())\n\n# Reemplazo\nprint(cadena.replace(\"Hola\", \"Adios\"))\n\n# División\ncad2 = \"cadena separada por espacios\"\nprint(cad2.split(\" \"))\n\n\n\n# EJERCICIO - DIFICULTAD EXTRA\n\ndef palindrome(word) -> bool:\n    return True if word[::-1] == word else False\n\ndef anagram(word1, word2) -> bool:\n    counter, aux_word = 0, word2\n    for i in word1:\n        if i in word2:\n            counter += 1\n            word2.replace(i, \"\")\n    return True if counter == len(aux_word) else False\n\ndef isogram(word) -> bool:\n    return True if len(word) == len(set(word)) else False\n\n\nprint(f\"'reconocer' es palíndromo: {palindrome(\"reconocer\")}\")\nprint(f\"'materialismo' y 'memorialista' son anagramas: {anagram(\"materialismo\", \"memorialista\")}\")\nprint(f\"'centrifugado' es isograma: {isogram(\"centrifugado\")}\")\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/cristianfloyd.py",
    "content": "\"\"\"/*\n* EJERCICIO:\n* Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n* en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n* - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\n*   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\n*   interpolación, verificación...\n*/\"\"\"\n\ncadena1 = \"Hola\"\ncadena2 = \"Python\"\n\n# Concatenación\nprint(cadena1 + \", \" + cadena2 + \"!\")\n\n# Repetición\nprint(cadena1 * 3)\n\n# Acceso a caracteres específicos (indexación)\nprint(cadena1[0] + cadena1[1] + cadena1[2] + cadena1[3])\n\n# longitud\nprint(f\"Longitud de cadena2: {len(cadena2)}\")\n\n# subcadenas (slicing)\nprint(cadena1[1:4])\nprint(cadena2[2:6])\nprint(cadena2[2:])\n\n# busqueda\nprint(\"a\" in cadena1)\nprint(\"y\" in cadena2)\n\nprint(f\"Busqueda al principio: {cadena1.startswith('Ho')}\")\nprint(f\"Busqueda al final: {cadena2.endswith('on')}\")\n\ncadena3 = \"Cristian Floyd @cristianfloyd\"\nprint(f\"Posicion de floyd: {cadena3.find('floyd')}\")\n\n# recorrido (conteo de ocurrencias)\nprint(f\"Número de ocurrencias de 'c': {cadena3.lower().count('c')}\")\n\n\n# reemplazo\ncadena1_reemplazada = cadena1.replace(\"o\", \"a\")\nprint(cadena1_reemplazada)\n\n# division\nprint(cadena1.split(\"l\"))\n\n# conversión a mayúsculas y minúsculas\nprint(cadena1.lower())\nprint(cadena1.upper())\nprint(\"cristian floyd\".title())\nprint(\"cristian floyd\".capitalize())\n\n# eliminación de espacios al principio y al final\ncadena_con_espacios = \"  cristian floyd  \"\nprint(cadena_con_espacios.strip())\n\n# trasnformación a lista de caracteres\nlista_caracteres = list(cadena3)\nprint(f\"De cadena a lista: {lista_caracteres}\")\n\n# transformacion de lista a cadena\nprint(f\"De lista a cadena str: {''.join(lista_caracteres)}\")\n\ncadena4 = \"123456\"\nprint(f\"Conversion de cadena a entero: {int(cadena4) + 10}\")\nprint(f\"Conversion de cadena a float: {float(cadena4 + '.5')}\")\n\nprint(f\"Es alfanumerico?: {cadena4.isalnum()}\")\nprint(f\"Es alfabetico?: {cadena4.isalpha()}\")\nprint(f\"Es digito?: {cadena4.isdigit()}\")\nprint(f\"Es minuscula?: {cadena4.islower()}\")\nprint(f\"Es mayuscula?: {cadena4.isupper()}\")\nprint(f\"Es numerico?: {cadena4.isnumeric()}\")\nprint(f\"Es espacio?: {'   '.isspace()}\")\nprint(f\"Es titulo?: {'Cristian Floyd'.istitle()}\")\nprint(f\"Es ascii?: {cadena4.isascii()}\")\n\n\n\"\"\"/*\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */ \"\"\"\n\n\ndef es_palindromo(palabra: str) -> bool:\n    \"\"\"Verifica si una palabra es un palíndromo.\n    def: palabra o frase que se lee igual de izquierda a derecha que de derecha a izquierda\n    \"\"\"\n    palabra = palabra.replace(\" \", \"\").lower()\n    return palabra == palabra[::-1]\n\n\ndef es_anagrama(palabra1: str, palabra2: str) -> bool:\n    \"\"\"Verifica si dos palabras son anagramas.\n\n    def: palabra o frase que se crea reorganizando las letras de otra palabra o frase, \n         de manera que todas las letras originales se usan exactamente una vez\n    \"\"\"\n    return sorted(palabra1.replace(\" \", \"\").lower()) == sorted(\n        palabra2.replace(\" \", \"\").lower()\n    )\n\n\ndef es_isograma(palabra: str) -> bool:\n    \"\"\"Verifica si una palabra es un isograma.\n    def: palabra que no tiene letras repetidas\n    \"\"\"\n    palabra = palabra.replace(\" \", \"\").lower()\n    return len(set(palabra)) == len(palabra)\n\n\ndef check(palabra1: str, palabra2: str):\n    print(f\"{palabra1} es un palíndromo\") if es_palindromo(palabra1) else None\n    print(f\"{palabra2} es un palíndromo\") if es_palindromo(palabra2) else None\n\n    print(f\"{palabra1} es un anagrama de {palabra2}\") if es_anagrama(\n        palabra1, palabra2\n    ) else None\n\n    print(f\"{palabra1} es un isograma\") if es_isograma(palabra1) else None\n\n    print(f\"{palabra2} es un isograma\") if es_isograma(palabra2) else None\n\n\n# check(\"radar\", \"pythonpythonpythonpython\")\ncheck(\"amor\", \"roma\")\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/d0ubt0.py",
    "content": "#Concatenacion\nstr1 = \"Hola\"\nstr2 = \" mundo\"\nstr1+str2\nprint(str1+str2)\n\n#Repetiocion\ncadena = \"Hola \"\nprint(cadena * 3)\n\n#Longitud\ncadena = \"Hola Python\"\nprint(len(cadena))\n\n#Slicing\nsubcadena = cadena[4:]\nprint(subcadena)\n\n\n#EXTRA\n#Palindromo\ndef es_palindromo(str1: str):\n    return True if str1[::-1] == str1 else False\n\n#Anagrama\ndef es_anagrama(str1:str,str2:str):\n    return True if sorted(str1) == sorted(str2) else False\n\n#Isograma\ndef es_isograma(str1:str):\n    contador = str1.count(str1[0])\n    for i in str1:\n        if str1.count(i) != contador:\n            return False\n    return True\nprint(es_palindromo('awa')) \nprint(es_palindromo('abc'))    \n\nprint(es_anagrama('hola','aloh'))\nprint(es_anagrama('xd','uwu'))\n\nprint(es_isograma('abcabcabcddd'))"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/daniel-sanabria0419.py",
    "content": "#los string en pyhton o cadenas de texto es una estrucutura de terxto mas en la que se guardan caracteres\n#por ende esta cadena de texto se puede iterar y se pueden hacer operacion con esta\n\n\"\"\"OPERACIONES BASICAS CON STRINGS\"\"\"\n#concatenacion de cadenas de texto \n\ntext_1 = \"hola \"\ntext_2 = \"python\"\n\nprint(text_1+\" \"+text_2)\n\n#repeticion de cadenas de texto\n\ntext_1 = \"hola \"\ntext_2 = \"python \"\n\nprint(text_1*3 +\" \"+text_2*2)\n\n#acceder a caracteres de una cadena por medio de la indexacion \n\ntext = \"esto es una cadena de text\"\n\nprint(text[0])\n\n\n#slicing en cadenas de texto, al ser un tipo de estructura de dato tambien se puede hacer slicin\n\ntext = \"python es mejor que java\"\n\nprint(text[0:17])\n\n#saber la longitud de un string con len()\n\ntext = \"python\"\nprint(f\"python tiene una longitud de {len(text)}\")\n\n#verificar si una cadena tiene un caracter n [\"n\" in \"str\"]\n\ntext = (\"a,b,c,d,e,f,h,i,j,k\")\n\nprint(\"a\" in text)\n\n#comparar si una cadena es igual a otra cadena\n\nprint(\"hola\" == \"hola\")\n\n\"\"\"METODOS DE ANALISIS Y BUSQUEDA CON STRINGS\"\"\"\n\n# .find(substring) busca el primer conjunto de caracteres en la cadena de texto si no \n# lo encuentra devuelve -1 si lo encuentra devuelve el indice\n\ntext = \"mi sueño es viajar mucho\"\n\nprint(text.find(\"z\"))\nprint(text.find(\"sueño \"))\n\n# .index(substring) busca el indice de donde comienza el str a encontrar pero si no \n# lo encontra lanza error\ntext = \"mi sueño es viajar mucho\"\n\nprint(text.index(\"z\"))\nprint(text.index(\"sueño \"))\n\n# .count(substring) return the times of the substring find in the string\ntext = \"sueño sueño sueño hola sueño otra vez sueñoooo\"\n\nprint(text.count(\"sueño \"))\n\n# .startwhith(substring) compare the substring with the string start\n\ntexto =  \"pythonn es el mejor\"\n\nprint(texto.startswith(\"python\"))\n\n\n\"\"\"DIVISION Y UNION DE CADENDAS DE TEXTO\"\"\"\n\n# .split(\"division\") retorna una lista con las palabras de la cadena de texto\n# palabra = grupo de caracteres sin separador\n\ntext = \"esto es una cadena de letras , y va a seperar todo esto.\"\n\nprint(text.split(\"z\"))\n\n\n# .rsplit(\"division\") retorna una lista con palabras de la cadena de texto pero recorre de derecha a izquierda\n# palabra = grupo de caracteres sin separador\n\ntext = \"esto es una cadena de letras , y va a seperar todo esto.\"\n\nprint(text.rsplit(\" \", 2))\n\n\n# .partition() devuelve una tupla con 3 elementos, [str antes del separador,separador ,str despues del separador]\n\ntext = \"esto es :una cadena de letras : y va a seperar todo :esto.\"\n\nprint(text.partition(\":\"))\n\n\n# .join(lista) convierte una lista en un str separando los elementos por el str que llamo el metodo\n\nlist_name = [\"hola\",\"me\",\"llamo\", \"daniel\"]\nprint(\" \".join(list_name))\n\n\"\"\"ALINIACION Y FORMATO\"\"\"\n\n# .center(n) centra una cadena de texto en un ancho de n caracteres\n\ntexto = \"texto centrado\"\n\nprint(texto.center(100))\n\n# .ljust(n) alinea a la izquierda una cadena de texto en un ancho de n caracteres\n\ntexto = \"texto alineado a la izquierda\"\n\nprint(texto.ljust(100))\n\n\n# .rjust(n) alinea a la derecha una cadena de texto en un ancho de n caracteres\n\ntexto = \"texto alineado a la izquierda\"\n\nprint(texto.rjust(100))\n\n# .zfill(n) \n\ntexto = \"relleno con 0\"\n\nprint(texto.zfill(100))\n\n\n\n\n#Ejercicio Extra\n\n\n\ndef word_type(word_one :str, word_tow:str) -> str:\n    \"\"\"Retorna una str con el tipo de las palabras:\n    Palindromo, Anagramas, Isogramas\"\"\"\n    word_one, word_tow = word_one.lower(), word_tow.lower()\n    \n    def is_polindromo(word)->bool:\n        if word == word[::-1]:\n            return True\n        return False\n    \n    def is_isograma(word)->bool:\n        views = []\n        for key, char in enumerate(word):\n            if word[key] in views:\n                return False\n            views.append(char)\n        return True\n    def is_anagrama(word_one: str, word_tow: str)->bool:\n        word_one = sorted(word_one)\n        word_tow = sorted(word_tow)\n        if word_one == word_tow:\n            return True\n        else:\n            return False\n\n    print(f\"la palabra {word_one} es un polindromo?: {is_polindromo(word_one)}\")\n    print(f\"la palabra {word_tow} es un polindromo?: {is_polindromo(word_tow)}\")\n\n    print(f\"la palabra {word_one} es un isograma?: {is_isograma(word_one)}\")\n    print(f\"la palabra {word_tow} es un isograma?: {is_isograma(word_tow)}\")\n    \n    print(f\"la palabra {word_one} es un anagrama de la palabra {word_tow}?: {is_anagrama(word_one,word_tow)}\")\n\n\n\nword_type(\"murciélago\",\"oso\")\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/danielhdzr.py",
    "content": "# #04CADENAS DE CARACTERES\n#### Dificultad: Media | Publicación: 22/01/24 | Corrección: 29/01/24\n\n# Ejercicio\n\n\"\"\"\n* EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas \n \"\"\"\n \ndef main():\n    # Creamos una cadena de texto (string) (str)\n    cadena_de_texto = \"hola\"\n    cadena_de_texto2 = \"python\"\n    espacio = \" \"\n    # Concatenamos stings\n    cadena_completa = cadena_de_texto + espacio + cadena_de_texto2\n    print(f\"{cadena_completa}\")\n    # Primer caracter se vuelve mayuscula\n    print(f\"{cadena_completa.capitalize()}\")\n    # cadena_de_texto.casefold()\n    # Contar el numero de veces que aparece un caracter dado: count(arg1, arg2, arg3) arg2 y 3 son opcionales\n    print(cadena_completa.count(\"o\", 0, 9))\n    # cadena_de_texto.encode()\n    # Regresa True o False si el string termina con el argumento dado\n    print(cadena_completa.endswith(\"hon\"))\n    # Remplaza el caracter tab (\\t) con espacios tabulados(8 espacios por defecto)\n    cadena_con_barras = 'Hola\\tpython'\n    print(cadena_con_barras.expandtabs())\n    # Regresa el index de la primera aparicion del substring dado: find(arg1, args2, arg3) arg2 y tres son opcionales\n    print(cadena_completa.find(\"ol\"))\n    # Regresa el index de la ultima apareicion del substring dado\n    print(cadena_completa.rfind(\"o\"))\n    # Da formato al string \n    name = \"Daniel\"\n    last_name = \"Hernandez\"\n    language = \"pyhton\"\n    print(\"Me llamo {} {}. Y aprendo {}\".format(name, last_name, language))\n    # Se utiliza para formatear cadenas utilizando un diccionario\n    data = {'name': 'Daniel', 'age': 33}\n    text = \"My name is {name} and I am {age} years old.\".format_map(data)\n    print(text)\n    # Regresa el index mas bajo del substring dado, arg2 y arg3 indican start y end, default es 0\n    print(last_name.index(\"e\"))\n    # Regresa el index mas alto del substring dado\n    print(last_name.rindex(\"e\"))\n    # Regresa True o False si el string es alfanumerico (los espacios no lo son)\n    print(last_name.isalnum())\n    # Regresa True o False si elementos en string pertenecen al alfabeto (a-z A-Z)\n    print(last_name.isalpha())\n    # Revisa si los caracteres en string son decimales (0-9)\n    print(last_name.isdecimal())\n    # Revisa si los caracteres en string son numeros (0-9 y algun otro caracter unicode para numeros)\n    print(last_name.isdigit())\n    # Revisa si los caracteres son numeros o se relacionan a numeros (acepta simbolos como ½)\n    print(last_name.isnumeric())\n    # Revisa si el string tiene una nombre valido de variable (False si empieza con numero)\n    print(last_name.isidentifier())\n    # Revisa si los caracteres alfabeticos estan en minusculas\n    print(last_name.islower())\n    # Revisa si los caracteres alfabeticos estan en mayusculas\n    print(last_name.isupper())\n    # Regresa un string concatenado\n    web_tech = ['HTML', 'CSS', 'JavaScript', 'React']\n    print(\"# \".join(web_tech))\n    # Remueve todos los espacios en blanco al principio y al final del string\n    str_with_spaces = \" Hola me llamo Daniel \"\n    print(str_with_spaces.strip())\n    # Remueve los espacios al final del string\n    print(str_with_spaces.rstrip()) \n    # Remueve los espacios al inicio del string\n    print(str_with_spaces.lstrip()) \n    # Reemplaza un cararcter por el otro \n    print(str_with_spaces.replace(\"D\", \"d\"))\n    # Remueve el prefijo indicado\n    print(str_with_spaces.removeprefix(\" H\")) \n    # Remueve el sufijo indicado\n    print(str_with_spaces.removesuffix(\"l \"))\n   \n    str_withno_spaces = \"Hola me llamo Daniel\"\n    # Parte el string en una lista comenzando desde el inicio usando un caracter dado como separador, esa el espacio como separador por defecto\n    print(str_withno_spaces.split(\" \",2))\n    # Parte el string en una lista comenzando desde el final usando un caracter dado como separador, esa el espacio como separador por defecto\n    print(str_withno_spaces.rsplit(\" \",2))\n    # Convierte cada primer caracter en mayuscula\n    print(str_with_spaces.title())\n    # Cambia mayusculas por minusculas y viceversa\n    full_name = \"Daniel Hernandez\"\n    print(full_name.swapcase())\n    # Revisa si el string comienza con el string dado. Regresa True o False\n    print(full_name.startswith(\"Dan\"))\n    # Convierte todo a mayusculas\n    print(full_name.upper())\n    # Convierte todo a minusculas\n    print(full_name.lower())\n\n \nif __name__==\"__main__\":\n    main()\n\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/davidrguez98.py",
    "content": "\"\"\" # #04 CADENAS DE CARACTERES\n> #### Dificultad: Media | Publicación: 22/01/24 | Corrección: 29/01/24\n\n## Ejercicio\n\n\n/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\nRecuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**. \"\"\"\n\n#Concatenación\n\nc1 = \"hola\"\nc2 = \"mundo\"\nc3 = \"David Rodríguez @davidrguez98\"\n\nprint(c1 + \" \" + c2)\n\n#Repetición\n\nprint(c1 * 3)\n\n#Indexación\n\nprint(c1[1])\n\n#Longitud\n\nprint(len(c2))\n\n#Slicing (porción)\n\nprint(c2[2:4])\nprint(c2[2:])\nprint(c2[0:2])\nprint(c2[:2])\n\n#Búsqueda\n\nprint(\"a\" in c1)\n\n#Reemplazo\n\nprint(c1.replace(\"o\", \"a\"))\n\n#División\n\nprint(c1.split(\"l\"))\n\n#Conversión a mayúsculas, minúsculas y primera en mayúsculas\n\nprint(c1.upper())\nprint(c1.lower())\nprint(\"David Rodríguez\".title()) \nprint(\"David Rodríguez\".capitalize()) #Solo la primera en mayúscula\n\n#Eliminación de espacios al principio y al final\n\nprint(\" David Rodríguez \".strip())\n\n#Búsqueda al principio y al final\n\nprint(c1.startswith(\"ho\"))\nprint(c1.endswith(\"la\"))\n\n#Búsqueda de posición\n\nprint(c3.find(\"david\"))\nprint(c3.lower().find(\"david\"))\n\n#Búsqueda de ocurrencias\n\nprint(c3.lower().count(\"d\"))\n\n#Formateo\n\nprint(\"Saludo: {}, lenguaje: {}!\".format(c1, c2))\n\n#Interpolación\n\nprint(f\"Saludo: {c1}, lenguaje: {c2}!\")\n\n# Transformación en lista de caracteres\n\nprint(list(c3))\n\n#Transformación de lista en cadena\n\nc4 = [c1, \", \", c2, \"!\"]\nprint(\"\".join(c4))\n\nc4 = [c1, \", \", c2, \"!\"]\nprint(\"-\".join(c4))\n\n#Transformaciones numéricas\n\nc5 = \"123456\"\nc5 = int(c5)\nprint(c5)\n\nc6 = \"123456.2344\"\nc6 = float(c6)\nprint(c6) \n\n#Comprobaciones varias\n\nprint(c1.isalnum())\nprint(c1.isalpha())\nprint(c1.isnumeric())\n\n\n#DIFICULTAD EXTRA\n\n\"\"\" \n/*\n\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */ \"\"\"\n\nfrom collections import Counter\n\ndef comparador():\n\n    def palindropo():\n        invertir = word_2[::-1].lower()\n\n        if word_1.lower() == invertir:\n            print(\"\\nEs un palíndrono\")\n        else:\n            print(\"\\nNo es un palíndrono\")\n\n    def anagrama():\n        counter1 = Counter(word1.lower())\n        counter2 = Counter(word2.lower())\n\n        if counter1 == counter2:\n            print(f\"\\nLas palabra {word1} y {word2} son anagramas\")\n        else:\n            print(f\"\\nLas palabra {word1} y {word2} no son anagramas\")\n\n    while True:\n\n        print(\"\")\n        print(\"1. Comprobar si es un palíndromo.\")\n        print(\"2. Comprobar si es un anagrama\")\n        print(\"3. Comprobar si es un isograma\")\n        print(\"4. Salir de la comprobación.\")\n        option = input(\"\\nElige una de las anteriores opciones: \")\n\n        match option:\n\n            case(\"1\"): \n                word_1 = input(\"Palabra 1: \")\n                word_2 = input(\"Palabra 2: \")\n                palindropo()\n            \n            case(\"2\"):\n                \n                word1 = input(\"Primera palabra: \")\n                word2 = input(\"Segunda palabra: \")\n                anagrama()\n\n            case(\"3\"):\n                def isograma(word_3):\n                    \n                    word_3 = word_3.lower()\n                    letras = set(word_3)\n                    return len(letras) == len(word_3)\n\n                word_3 = input(\"Escribe la palabra: \")\n                if isograma(word_3):\n                    print(f\"\\n{word_3} es un isograma\")\n                else:\n                    print(f\"\\n{word_3} no es un isograma\")\n\n            case(\"4\"):\n                break\n\ncomparador()"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/dimasb69.py",
    "content": "\"\"\"\n* EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\n *   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\n *   interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n\"\"\"\n\n# Concatenación\ncadena1 = \"Hola!\"\ncadena2 = \" Mundo\"\ncadenaP = 'Hannah'\n\n\n# Repetición\ncadena4 = \"Hola\" * 3\nprint(cadena4)\n\n# Acceso a caracteres específicos\nprint(cadena1[0])\n\n# Subcadenas\nprint(cadena1[0:2])\n\n# Longitud de la cadena\nlongitud = len(cadena1)\nprint(longitud)\n\n# Concatenación\nconcatenacion = cadena1 + \" \" + cadena2\nprint(concatenacion)\n\n#interpolación con f-strings\nnombre = \"Dimas\"\nsaludo_f = f\"{cadena1}, {nombre}\"\nprint(saludo_f)\n\n# Recorrido\nfor caracter in cadena1:\n    print(caracter)\n\n# Conversión a mayúsculas\nprint(cadena1.upper())\n\n# Conversión a minúsculas\nprint(cadena1.lower())\n\n# Reemplazo\nreemplazada = cadena1.replace(\"o\", \"a\")\nprint(reemplazada)\n\n# División\ndividida = cadena1.split(\",\")\nprint(dividida)\n\n# Unión\nunida = '-'.join(dividida)\nprint(unida)\n\n# Verificación\ninicio_con_hola = cadena1.startswith(\"Hola\")\ntermina_con_exclamacion = cadena1.endswith(\"!\")\n\nprint(f\"Inicia con 'Hola': {inicio_con_hola}\")\nprint(f\"Termina con '!': {termina_con_exclamacion}\")\n\ndef es_palindromo(cadena):\n    print('un palíndromo es una palabra que se lee igual de izquierda a derecha que de derecha a izquierda\\n')\n    palabra1 = input('Ingrese una palabra: ')\n    palindromo = palabra1.lower() == palabra1.lower()[::-1]\n    if palindromo:\n        print(f\"Palabra {palabra1} es palíndromo\\n\\n\")\n    else:\n        print(f\"Palabra {palabra1} no es palíndromo\\n\\n\")\n\ndef es_anagrama():\n    print('un anagrama es una palabra que se forman con las letras de otra palabra\\n')\n    palabra1 = input('Ingrese una palabra1: ')\n    palabra2 = input('Ingrese una palabra2: ')\n    anagrama = sorted(palabra1.lower()) == sorted(palabra2.lower())\n    if anagrama:\n        print(f\"Palabra {palabra1} y {palabra2} son anagramas\\n\\n\")\n    else:\n        print(f\"Palabra {palabra1} y {palabra2} no son anagramas\\n\\n\")\n\ndef es_isograma():\n    print('un isograma es una palabra que no tiene letras repetidas\\n')\n    palabra1 = input('Ingrese una palabra: ')\n    isograma = len(set(palabra1)) == len(palabra1)\n    if isograma:\n        print(f\"Palabra {palabra1} es un isograma\\n\\n\")\n    else:\n        print(f\"Palabra {palabra1} no es un isograma\\n\\n\")\n\nprint('\\n\\n\\n')\n\nwhile True:\n    print('1. Palíndromo')\n    print('2. Anagrama')\n    print('3. Isograma')\n    print('4. Salir')\n    opcion = int(input('Ingrese una opció: '))\n\n    if opcion == 1:\n        es_palindromo(cadena1)\n    elif opcion == 2:\n        es_anagrama()\n    elif opcion == 3:\n        es_isograma()\n    elif opcion == 4:\n        print('Adios\\n')\n        break\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/duendeintemporal.py",
    "content": "#4 { Retos para Programadores } CADENAS DE CARACTERES\n# Short for log\nlog = print  # Using print as a logging function\n\n# STRING TYPE\n# The str type is the object representation of strings in Python.\nstring_object = str(\"hello girl\")  # Creating a string object\n\n# In Python, strings are immutable, but we can still access various methods for manipulating the data.\n\nq = 'Did you know Internet start as a Pentagon project named ARPANET (Advanced Research Projects Agency Network)?'\nq2 = q[12:]  # Slicing the string from index 12 to the end\nlog(q2)  # Logs: Internet start as a Pentagon project named ARPANET (Advanced Research Projects Agency Network)?\n\n# The Python Character\n# Python strings are sequences of Unicode characters. The len() function returns the number of characters in the string.\nmessage = \"Sometimes you make me smile...\"\n\n# Length of the message\nlog(len(message))  # Output: 30\n\n# Character at index 10\nlog(message[10])  # Output: y\n\n# Unicode code point of character at index 10\nlog(ord(message[10]))  # Output: 121\n\n# First occurrence of 'm'\nlog(message.index('m'))  # Output: 2\n\n# Last occurrence of 'm'\nlog(message.rindex('m'))  # Output: 23\n\n# Last index of 's'\nchart = message.rindex('s')  # Should be 22\nlog(chart)  # Log the value of chart (last index of 's')\n\n# First index of '.'\nchart2 = message.index('.')  # Should be 27\nlog(chart2)  # Log the value of chart2 (first index of '.')\n\n# Substring from last index of 's' to the first index of '.'\nlog(message[chart:chart2])  # Output: smile (substring from index 27 to 29)\n\n# Slicing from the end\nlog(message[-8:])  # Output: smile...\n\narr = list(message[:8])  # Convert the first 8 characters to a list\nlog(arr)  # ['S', 'o', 'm', 'e', 't', 'i', 'm', 'e'] (not inclusive of the last index)\nlog('-'.join(arr))  # S-o-m-e-t-i-m-e\nlog(arr[-1].replace('e', 'e-s'))  # e-s\nlog('-'.join(arr).replace('-', '') + 's')  # Sometimes\n\n# Note: Some emojis may be represented by multiple code points, so consider this when evaluating lengths.\n\nfragment = '   at this point in my life...  '\nlog(fragment.strip())  # Logs: at this point in my life... (without spaces at the beginning or end)\n\n# Note: You can also use lstrip() or rstrip() for trimming.\n\nname = 'anna'\nlog(name.upper())  # ANNA\nothername = 'Luna'\nlog(othername.lower())  # luna\n\n# We can also use the chr() function to get characters from Unicode code points.\nlog(''.join(chr(i) for i in [193, 48, 587, 482, 102, 107]))  # Á0ɋǢfk\nlog(chr(0x68fa))  # 棺\n\n# Note: Using chr() may have performance implications if called frequently or with many characters.\n\n# The normalize() method is not directly available in Python, but we can use the unicodedata module for normalization.\nimport unicodedata\n\n# U+00C5: Latin capital letter A with ring above\nlog(chr(0x00C5))  # Å\n# U+212B: Angstrom sign\nlog(chr(0x212B))  # Å\n# U+0041: Latin capital letter A\n# U+030A: Combining ring above\nlog(chr(0x0041) + chr(0x030A))  # Å\n\nunnormalized_text = chr(0x0041) + chr(0x030A) + chr(0x212B) + chr(0x00C5)\nlog(ord(unnormalized_text[1]), ord(unnormalized_text[3]))  # 778 197\n# Normalize the text and check its length before accessing indices\nnormalized_text = unicodedata.normalize('NFC', unnormalized_text)\n\n# Check the length of normalized_text before accessing its indices\nif len(normalized_text) > 3:\n    log(ord(normalized_text[1]), ord(normalized_text[3]))  # Access safely\nelse:\n    log(\"Normalized text is too short:\", normalized_text)\n\n# We can concatenate strings using the + operator or the join() method.\nfirst_name = 'Patty'\nlast_name = ' Smith'\nlong_name = first_name + last_name  # Concatenation using +\nlog(long_name)  # Patty Smith\n# Same as\nlog(first_name + last_name)  # Patty Smith\n\n# Function to capitalize the first letter of a string\ndef capitalize(s):\n    return s[0].upper() + s[1:]\n\nlog(capitalize(name))  # Anna\n\n# Methods for locating substrings within another string: find() and rfind().\nfragment2 = 'the fire is burned, the tables are turned...'\nlog(fragment2.find('is'))  # 9\n# Searching for a substring that does not exist returns -1\nlog(fragment2.find('house'))  # -1\nlog(fragment2.rfind('t'))  # 35 (last occurrence of 't')\n\n# String Inclusion Methods\nlog(fragment2.startswith(\"the\"))  # True\nlog(fragment2.endswith(\"fire\"))  # False\n\n# Repeat a string using the * operator\nsay = 'oh'\nlog(say * 2 + '!')  # ohoh!\n\n# Implementing a custom padStart function\ndef add_pad(s, width, pad='0'):\n    result = str(s)  # Convert to string\n    while len(result) < width:  # While the length is less than the desired width\n        result = f\"{pad}{result}\"  # Prepend the padding character\n    return result\n\nlog(add_pad(4, 3, '#'))  # ##4\nlog(add_pad(56, 3, '$'))  # $56\nlog(add_pad(7, 3))  # 007\nlog(add_pad('something', 3, '-'))  # ---something\n\n# Function to add padding to a string\ndef add_pad(s, width, pad='0'):\n    result = str(s)  # Convert to string\n    while len(result) < width:  # While the length is less than the desired width\n        result = f\"{pad}{result}\"  # Prepend the padding character\n    return result\n\ngreeting = \"tururuuu\"\npadded_string = add_pad(greeting, 11, \"&\")  # Padding the greeting string to a width of 11 with '&'\nlog(padded_string)  # Logs: &&&tururuuu\n\nimport re\n\n# Function to convert various string formats to camelCase\ndef to_camel_case(input_str):\n    # Replace kebab-case, snake_case, and spaces with a space\n    # Handle PascalCase\n    return (\n        ''.join(\n            part.capitalize() if i > 0 else part.lower()\n            for i, part in enumerate(re.split(r'[-_\\s]+', input_str))\n        )\n    )\n\nlog(to_camel_case('PascalCase'))  # pascalCase\nlog(to_camel_case('kebab-case-string'))  # kebabCaseString\nlog(to_camel_case('snake_case_string'))  # snakeCaseString\nlog(to_camel_case('string with spaces'))  # stringWithSpaces\n\n# Simulating a window load event in a console environment\ndef on_load():\n    body_style = {\n        'background': '#000',\n        'text-align': 'center'\n    }\n    \n    title = 'Retosparaprogramadores #4.'\n    title_style = {\n        'font-size': '3.5vmax',\n        'color': '#fff',\n        'line-height': '100vh'\n    }\n    \n    # Simulating setting styles (not applicable in console)\n    log(f\"Body styles: {body_style}\")\n    log(f\"Title: {title} with styles: {title_style}\")\n    \n    # Simulating a delay before showing an alert\n    import time\n    time.sleep(2)  # Wait for 2 seconds\n    log('Retosparaprogramadores #4.')\n\non_load()  # Call the function to simulate the load event\n\n# ADDITIONAL DIFFICULTY (optional):\n# Create a program that analyzes two different words and performs checks\n# to determine if they are: Palindromes, Anagrams, Isograms\n\n# Palindrome: A palindrome is a word, phrase, number, or other sequence of characters that reads the same forward and backward.\ndef is_palindrome(w1, w2):\n    if len(w1) != len(w2):\n        return False\n    return w1 == w2[::-1]  # Check if w1 is equal to w2 reversed\n\nlog('is palindrome: ', is_palindrome('roma', 'amor'))  # Logs: true\n\n# Anagram: An anagram is a word or phrase formed by rearranging the letters of another word or phrase.\ndef is_anagram(w1, w2):\n    if len(w1) != len(w2):\n        return False\n    return sorted(w1) == sorted(w2)  # Check if sorted characters of both words are equal\n\nlog('is anagram: ', is_anagram('nick', 'kinc'))  # Logs: True\n\n# Isogram: An isogram is a word or phrase in which no letter occurs more than once.\ndef is_isogram(s):\n    # Create a list to count occurrences of each letter\n    count_letters = []\n    for l in s:\n        count_letters.append(s.count(l))  # Count occurrences of each letter in the string\n\n    # Check if any letter occurs more than once\n    for num in count_letters:\n        if num > 1:\n            return False\n    return True\n\nlog('is isogram: ', is_isogram('background'))  # Logs: true\n\n# Function to check if two strings are palindromes, anagrams, or isograms\ndef check_state(str1, str2):\n    r_poli = is_palindrome(str1, str2)  # Check if they are palindromes\n    r_anag = is_anagram(str1, str2)      # Check if they are anagrams\n    f_iso = is_isogram(str1)              # Check if the first string is an isogram\n    s_iso = is_isogram(str2)              # Check if the second string is an isogram\n    result = ''\n    bool_result = False\n\n    if r_poli and r_anag and f_iso and s_iso:\n        result = f'The words: \"{str1}\" and \"{str2}\" are palindromes, anagrams, and also isograms.'\n        bool_result = True\n    elif r_poli:\n        result = f'The words: \"{str1}\" and \"{str2}\" are palindromes and anagrams but they aren\\'t isograms.'\n    elif r_anag and f_iso and s_iso:\n        result = f'The words: \"{str1}\" and \"{str2}\" are anagrams and also isograms.'\n        bool_result = True\n    elif r_anag:\n        result = f'The words: \"{str1}\" and \"{str2}\" are anagrams.'\n\n    if not bool_result:\n        if f_iso and s_iso:\n            result = f'The words: \"{str1}\" and \"{str2}\" are isograms.'\n        elif f_iso:\n            result += f'The first word: \"{str1}\" is an isogram.'\n        elif s_iso:\n            result += f'The second word: \"{str2}\" is an isogram.'\n        elif not r_poli and not r_anag:\n            result = f'The words: \"{str1}\" and \"{str2}\" aren\\'t palindromes, anagrams, or isograms.'\n\n    log(result)\n\n# Test cases\ncheck_state('amor', 'mora')  # Logs: The words: \"amor\" and \"mora\" are anagrams and also isograms.\ncheck_state('amor', 'roma')  # Logs: The words: \"amor\" and \"roma\" are palindromes, anagrams, and also isograms.\ncheck_state('zeitgest', 'kaguabumga')  # Logs: The words: \"zeitgest\" and \"kaguabumga\" aren't palindromes, anagrams, or isograms.\ncheck_state('pizza', 'background')  # Logs: The second word: \"background\" is an isogram.\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/eamartin96.py",
    "content": "# #04 CADENAS DE CARACTERES\n'''\nMuestra ejemplos de todas las operacines que puedes realizar con cadenas de caracteres:\nAcceso a caracteres especificos, subcadenas, longitud, concatenacion, repeticion, recorrido,\nconversion a mayusculas y minusculas, reemplazo, division, union, interpolacion, verificacion.\n'''\n\ncadena = \"HolaMundo\"\nprint(f\"String: {cadena}\")\n\n# Acceso a caracteres especificos\nprint(\"Access to specyfic characters\")\nprint(f\"First character: {cadena[0]}\")\nprint(f\"Sixth character: {cadena[5]}\")\nprint(f\"Last character: {cadena[-1]}\")\n\n# Subcadenas\nprint()\n\n# Longitud\nprint(\"\\nString Lenght\")\nprint(f\"String lenght is: {len(cadena)}\")\n\n# Concatenacion\nprint(\"\\nString Concatenation\")\ncadena2 = \"HolaPython!\"\nprint(cadena + cadena2)\n\n# Repeticion\nprint(\"\\nString Lenght\")\nprint(cadena * 3)\n\n# Mayusculas\nprint(\"\\nConvert to uppercase\")\nprint(cadena.upper())\n\n# Minusculas\nprint(\"\\nConvert to lowercase\")\nprint(cadena.lower())\n\n# Union\nprint(\"\\nConvert to lowercase\")\nlist_cadena = [\"Hola\", \"mundo\", \"python\"]\njoin_cadena = \" - \".join(cadena)\nprint(f\"Joint String: {cadena}\")\n\n# Verificacion\nprint(f\"String is alphanumberic?: {cadena.isalpha()}\")\n\n# DIFICULTAD EXTRA\nprint(\"\\n----------------------------------------------------\")\nprint(\"EXTRA DIFFICULT\")\n'''\nCrea un programa que analice dos palabras diferentes y realice comprobaciones\npara descubrir si son:\n- Palindromos\n- Anagramas\n- Isogramas\n'''\ndef check(string1, string2):\n    # Palindromo\n    print(f\"{string1} is a palyndrome\" if string1 == string1[::-1] else f\"{string1} is not a palyndrome\")\n    print(f\"{string2} is a palyndrome\" if string2 == string2[::-1] else f\"{string2} is not a palyndrome\")\n\n    # Anagram\n    print(f\"{string1} is anagram of {string2}\" if sorted(string1) == sorted(string2) else f\"{string1} is not anagram of {string2}\")\n\n    # Isogram\n    print(f\"{string1} is an isogram\" if len(string1) == len(set(string1)) else f\"{string1} is not an isogram\")\n    print(f\"{string2} is an isogram\" if len(string2) == len(set(string2)) else f\"{string2} is not an isogram\")\n\n    print()\n\ndef main():\n    check(\"radar\", \"ana\")\n    check(\"amor\", \"roma\")\n    check(\"roma\", \"python\")\n\nif __name__ == \"__main__\":\n    main()\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/eberstr.py",
    "content": "# Definición de cadena\ncadena = \"Hola, mundo!\"\n\n# 1. Acceso a caracteres específicos\nprint(\"Primer carácter:\", cadena[0])        # H\nprint(\"Último carácter:\", cadena[-1])       # !\n\n# 2. Subcadenas\nprint(\"Subcadena (posición 1 a 4):\", cadena[1:5])   # ola,\n\n# 3. Longitud de la cadena\nprint(\"Longitud de la cadena:\", len(cadena))        # 12\n\n# 4. Concatenación\nsaludo = \"Hola\" + \" \" + \"mundo!\"\nprint(\"Concatenación:\", saludo)                     # Hola mundo!\n\n# 5. Repetición de cadenas\nprint(\"Repetición:\", \"Hola! \" * 3)                  # Hola! Hola! Hola!\n\n# 6. Recorrido de caracteres (iteración)\nfor caracter in cadena:\n    print(caracter, end=\" \")                        # H o l a ,   m u n d o !\n\n# 7. Conversión a mayúsculas y minúsculas\nprint(\"\\nMayúsculas:\", cadena.upper())              # HOLA, MUNDO!\nprint(\"Minúsculas:\", cadena.lower())                # hola, mundo!\n\n# 8. Reemplazo\nprint(\"Reemplazo:\", cadena.replace(\"mundo\", \"Python\"))  # Hola, Python!\n\n# 9. División (split)\npalabras = cadena.split(\", \")\nprint(\"División por ', ':\", palabras)               # ['Hola', 'mundo!']\n\n# 10. Unión (join)\nunidas = \" \".join(palabras)\nprint(\"Unión de lista en cadena:\", unidas)          # Hola mundo!\n\n# 11. Interpolación (f-strings)\nnombre = \"Eber\"\nprint(f\"Hola, {nombre}!\")                           # Hola, Eber!\n\n# 12. Verificación de prefijo y sufijo\nprint(\"Empieza con 'Hola':\", cadena.startswith(\"Hola\"))  # True\nprint(\"Termina con '!':\", cadena.endswith(\"!\"))          # True\n\n# 13. Buscar posición de subcadena\nprint(\"Posición de 'mundo':\", cadena.find(\"mundo\"))      # 6\n\n# 14. Contar ocurrencias\nprint(\"Ocurrencias de 'o':\", cadena.count(\"o\"))          # 2\n\n# 15. Comprobar si es numérica o alfabética\nprint(\"Es numérica:\", cadena.isdigit())                  # False\nprint(\"Es alfabética:\", cadena.isalpha())                # False (hay espacios y signos)\n\n# 16. Eliminar espacios en blanco (trim)\ncadena_espacios = \"   Hola, mundo!   \"\nprint(\"Sin espacios:\", cadena_espacios.strip())          # \"Hola, mundo!\"\n\n# 17. Capitalización (primera letra en mayúscula)\nprint(\"Capitalización:\", cadena.capitalize())            # \"Hola, mundo!\"\n\n# 18. Título (Primera letra de cada palabra en mayúscula)\nprint(\"Título:\", cadena.title())                         # \"Hola, Mundo!\"\n\n\n# Extra\n\ndef palindromo(palabra):\n    word =\"\"\n    for letra in palabra:\n        i -= 1\n        if letra != palabra[i]:\n            break\n        else:\n            word += letra\n    if word == palabra:\n        print(f\"La palabra {palabra} es un palindromo\")\n    else:\n        print(f\"La palabra {palabra} NO es un palindromo\")\n\ndef anagrama(palabra1, palabra2):\n    if palabra1.sorted() == palabra2.sorted()\n        print(\"Anagrama\")\n    else:\n        print(\"No anagrama\")\n\ndef isograma(palabra):\n    letras  = []\n    for letra in palabra:\n        if letra not in letras:\n            letras.append(letra)\n    if letras == list(palabra):\n        print(f\"La palabra {palabra} es un isograma\")\n    else:\n        print(f\"La palabra {palabra} NO es un isograma\")\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/eduhumanes91.py",
    "content": "'''\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n'''\n\n# Concatenación\ncadena1 = \"Hola\"\ncadena2 = \" Mundo\"\ncadena3 = cadena1 + cadena2\nprint(cadena3)\n\n# Repetición\ncadena4 = \"Hola\" * 3\nprint(cadena4)\n\n# Acceso a caracteres específicos\nprint(cadena1[0])\n\n# Subcadenas\nprint(cadena1[0:2])\n\n# Longitud\nprint(len(cadena1))\n\n# Recorrido\nfor letra in cadena1:\n    print(letra)\n\n# Conversión a mayúsculas y minúsculas\nprint(cadena1.upper())\nprint(cadena1.lower())\n\n# Reemplazo\nprint(cadena1.replace(\"o\", \"a\"))\n\n# División\nprint(cadena1.split(\"o\"))\n\n# Unión\nprint(\"o\".join(cadena1))\n\n# Interpolación\nprint(f\"{cadena1} Mundo\")\n\n# Verificación\nprint(\"Hola\" in cadena1)\nprint(\"Hola\" not in cadena1)\n\n#Extra\n# Palíndromos, Anagramas e Isogramas\n\n    #Isogramas\n    \ndef check(word1: str, word2: str):\n\n    # Palíndromos\n    print(f\"¿{word1} es un palíndromo?: {word1 == word1[::-1]}\")\n    print(f\"¿{word2} es un palíndromo?: {word2 == word2[::-1]}\")\n\n    # Anagramas\n    print(f\"¿{word1} es anagrama de {word2}?: {sorted(word1) == sorted(word2)}\")\n\n    # Isogramas\n\n    def isogram(word: str) -> bool:\n\n        word_dict = dict()\n        for character in word:\n            word_dict[character] = word_dict.get(character, 0) + 1\n\n        isogram = True\n        values = list(word_dict.values())\n        isogram_len = values[0]\n        for word_count in values:\n            if word_count != isogram_len:\n                isogram = False\n                break\n\n        return isogram\n\n    print(f\"¿{word1} es un isograma?: {isogram(word1)}\")\n    print(f\"¿{word2} es un isograma?: {isogram(word2)}\")\n\n\ncheck(\"radar\", \"pythonpythonpythonpython\")\ncheck(\"amor\", \"roma\")\n    \n    \n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/evilpotato04.py",
    "content": "\n#/*\n# * EJERCICIO:\n# * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n# * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n# * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n# *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n\ncitacion = \"Hello\"\n\ncitacion += \" world!\" # concatenación - manera 01\nprint(citacion)\n\nnombre = input(\"Tu nombre: \")\ncitacion = \"Tu nombre es {a}\".format(a=nombre) # concatenación - manera 02\nprint(citacion)\n\nedad = int(input(\"Tu edad: \"))\ncitacion = \"Tu tuenes %d años de edad\" % (edad) # concatenación - manera 03 (solo numeros)\nprint(citacion)\n\npasatiempo = input(\"Tu pasatiempo: \")\ncitacion = f\"Tu pasatiempo es {pasatiempo}\" # concatenación - manera 04 (interpolación)\nprint(citacion)\n\n# ------\ncitacion = \"Beetlejuice! \" # repetición\nprint(citacion*3)\n\nprint(len(citacion)) # longitud\n\nprint(citacion[4]) # accesando el caracter específico L en \"Beetlejuice\"\n\nprint(citacion[:6]) # subcadena \"Beetle\"\nprint(citacion[6:]) # subcadena \"juice!\"\nprint(citacion[4:8]) # subcadena \"leju\"\n\nfor x in citacion:\n    print(x) # recorrido\n\nprint(citacion.upper()) # conversión a mayúsculas\nprint(citacion.lower()) # conversión a minúsculas\n\nprint(\"Beetle\" in citacion)     # verificación (resulta en True)\nprint(\"juice\" not in citacion)  # verificación (resulta en False)\n\ncitacion = \" \".join([\"My\", \"Instagram\", \"is\", \"@samy_witch\"]) # unión\nprint(citacion)\n\ncitacion = \"Feel free to add me\" # división\nprint(citacion.split(\" \"))\n\n# *\n# * DIFICULTAD EXTRA (opcional):\n# * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n# * para descubrir si son:\n# * - Palíndromos\n# * - Anagramas\n# * - Isogramas\n# */\n\ndef analisis_palindromo(palabra_1, palabra_2):\n    letras_palabra_2 = []\n    palabra_2_invertida = \"\"\n\n    for letra in palabra_2:\n        letras_palabra_2.append(letra)\n    \n    letras_palabra_2.reverse()\n\n    for letra in letras_palabra_2:\n        palabra_2_invertida += letra\n\n    return True if palabra_1 == palabra_2_invertida else False\n\ndef analisis_anagrama(palabra_1, palabra_2):\n    es_anagrama = True\n    \n    for letra in palabra_2:\n        if letra not in palabra_1:\n            es_anagrama = False\n    \n    if palabra_1 == palabra_2:\n        es_anagrama = False\n    \n    return es_anagrama\n\ndef analisis_isograma(palabra):\n    lista_de_letras = []\n\n    for letra in palabra:\n        if letra not in lista_de_letras:\n            lista_de_letras.append(letra)\n\n    return True if len(palabra) == len(lista_de_letras) else False\n\ndef analisis_de_palabras():\n    palabra_1 = input(\"palabra 1: \")\n    palabra_2 = input(\"palabra 2: \")\n    es_palindromo = False\n    es_anagrama = False\n    es_isograma = False\n    \n    # * - Palíndromos\n    es_palindromo = analisis_palindromo(palabra_1, palabra_2)\n    print(\"Son Palíndromos\") if es_palindromo == True else print(\"No son Palíndromos\")\n    \n    # * - Anagramas\n    es_anagrama = analisis_anagrama(palabra_1, palabra_2)\n    print(\"Son Anagramas\") if es_anagrama == True else print(\"No son Anagramas\")\n    \n    # * - Isogramas\n    es_isograma = analisis_isograma(palabra_1)\n    print(f\"{palabra_1} es Isograma\") if es_isograma == True else print(f\"{palabra_1} no es Isograma\")\n\n    es_isograma = analisis_isograma(palabra_2)\n    print(f\"{palabra_2} es Isograma\") if es_isograma == True else print(f\"{palabra_2} no es Isograma\")\n\nanalisis_de_palabras()\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/fborjalv.py",
    "content": "# OPERACIONES CON CADENAS DE TEXTO EN PYTHON\n# ACCESO A CARACTERES ESPECIFICOS \n\ncadena = \"Esta es una cadena de ejemplo\"\ncadena_2 = \"Soy la Cadena 2\"\n\nprint(f\"acceso a un caracter concreto: {cadena[10]}\")\nprint(f\"acceso a los primeros n caracteres: {cadena[:10]}\")\nprint(f\"acceso a los últimos n caracteres: {cadena[10:]}\")\nprint(f\"acceso a los caracteres de las posición n hasta la posición m: {cadena[10:15]}\")\n\n# LONGITUD\n\nprint(f\"La longitud de la cadena es de {len(cadena)} caracteres\")\n\n# CONCATENACIÓN \n\nprint(f\"Contenando la cadena 1 y la cadena 2 = {cadena + ' ' + cadena_2}\")\n\n# REPETICIÓN\n\nprint(cadena_2 * 4)\n\n# CONVERSIÓN A MAYÚSCULAS Y MINÚSCULAS, \n\nprint(f\"Convertimos todo a mayúsculas: {cadena.upper()}\")\nprint(f\"Convertimos todoo a minúsculas: {cadena.lower()} \")\nprint(f\"Establecemos primera letra en mayúsculas: {cadena.capitalize()}\")\nprint(f\"Usamos la función titulo: {cadena.title()}\")\n\n\n# REEMPLAZO\n\nprint(f'Función de reemplazo: {cadena.replace(\"ejemplo\", \"ejercicio\")}')\n\n# DIVISIÓN\n\nprint(cadena.split(\"cadena\")) # devuelve un array con los partes restantes \nprint(cadena.strip())\n\n# UNIÓN\n\ncadena_3 = cadena.join(cadena_2)\nprint(f\"cadena 3 es una unión de cadena y cadena_2: {cadena_3}\")\n\n\n# BUSQUEDA POSICIÓN\nprint(f\"Busca dentro de una cadena: {cadena.find('ejemplo')}\")\n\n# CREA UN PROGRAMA QUE ANALICE DOS PALABRAS DIFERENTES Y REALIZE LAS COMPROBACIONES PARA DESCUBRIR SI SON: \n\nprint(cadena_2.count(\"a\"))\n\n\ndef word_analysis (word_1, word_2):\n\n    # ANAGRAGAMA \n    print(f\"¿Son anagramas las palabras {word_1} y {word_2}?: {sorted(word_1) == sorted(word_2)}\")\n\n    # Palíndromo\n    print(f\"¿Es palíndroma la palabra {word_1}? {word_1[::1] == word_1[::-1]}\")\n    print(f\"¿Es palíndroma la palabra {word_2}? {word_2[::1] == word_2[::-1]}\")\n\n    # Isogramas\n    def is_isogram (word):\n        isograma = True\n        for elemento in word: \n            if word.count(elemento) > 1: \n                isograma = False\n                return isograma\n            else: \n                pass\n        isograma = True\n        return isograma\n\n    print(f\"{word_1}  es un isograma?: {is_isogram(word_1)} \" )\n    print(f\"{word_2}  es un isograma?:{is_isogram(word_2)} \")\n\n#word_analysis(\"radar\", \"anilina\")\n#word_analysis(\"amor\", \"roma\")\nword_analysis(\"pythonpythonpythonpython\",\"roma\")\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/fishellVvv.py",
    "content": "# operaciones\nstr1 = \"Queso\"\nstr2 = \"supercalifragilistoespialidoso\"\n\n# concatenación\nprint(str1 + \" y \" + str2)\n\n# repetición\nprint(str1 * 3)\n\n# indexación\nprint(str1[0])\n\n# longitud\nprint(len(str2))\n\n# slicing\nprint(str1[:3], str1[2:4], str1[2:5] + \"? \" + str1[2:5], str1[2:4], str1)\nprint(str2[:3], str2[3:9], str2[26:], str2[1:10:2])\n\n# busqueda\nprint(\"super\" in str2)\nprint(str2.startswith(\"sup\"))\nprint(str2.endswith(\"eso\"))\n\n# reemplazo\nprint(str2.replace(\"i\", \".\"))\n\n# división\nprint(str2.split(\"l\"))\n\n# mayúsculas y minúsculas\nprint(str1.upper())\nprint(str1.lower())\nprint(str2.capitalize())\nprint(\"victor vigil\".title())\n\n# eliminación de espacios iniciales y finales\nprint(\" hola mundo  \".strip())\n\n# busqueda de posición\nprint(str2.find(\"fragil\"))\n\n# busqueda de ocurrencias\nprint(str2.count(\"i\"))\n\n# formateo\nprint(\"El {} estaba {}!\".format(str1.lower(), str2[:5]))\n\n# interpolación\nprint(f\"El {str1.lower()} estaba {str2[:5]}!\")\n\n# trasformación en lista de caracteres\nprint(list(str1))\n\n# transformación de lista a cadena\nlist1 = [\"El\", str1, \"estaba\", str2[:5], \"!\"]\nprint(\"-\".join(list1))\n\n# transformaciones numéricas\nstr3 = \"42\"\nstr3 = int(str3)\nprint(str3)\n\n# comprobaciones\nprint(str1.isalnum())\nprint(str1.isalpha())\nprint(str3.is_integer())\n\n# EXTRA\ndef check(word1: str, word2: str):\n\n    print(\"\\nPalíndromos:\")\n    if word1 == word1[::-1]:\n        print(f\"{word1} es palíndromo.\")\n    else:\n        print(f\"{word1} no es palíndromo.\")\n    if word2 == word2[::-1]:\n        print(f\"{word2} es palíndromo.\")\n    else:\n        print(f\"{word2} no es palíndromo.\")\n\n    print(\"\\nAnagrama:\")\n    if sorted(word1.lower().replace(\" \", \"\")) == sorted(word2.lower().replace(\" \", \"\")):\n        print(f\"{word2} es un anagram de {word1}.\")\n    else:\n        print(f\"{word2} no es un anagram de {word1}.\")\n\n    print(\"\\nIsograma:\")\n    def isograma(word: str) -> bool:\n        word_dict = dict()\n\n        for character in word:\n            word_dict[character] = word_dict.get(character, 0) +1\n\n        return len(set(word_dict.values())) == 1\n    \n    if isograma(word1):\n        print(f\"{word1} es un isograma.\")\n    else:\n        print(f\"{word1} no es un isograma.\")\n    if isograma(word2):\n        print(f\"{word2} es un isograma.\")\n    else:\n        print(f\"{word2} no es un isograma.\")\n\ncheck(\"elle\", \"lele\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/franvozzi.py",
    "content": "mensaje = 'Hola Mundo' # Declaración de variables\n\n# Concatenación de caracteres\nmensaje1 = 'Hola' + ' ' + 'Mundo'\nprint(mensaje1)\n\n# Multiplicación de caracteres\nmensaje2A = 'Hola ' * 3\nmensaje2B = 'Mundo'\nprint(mensaje2A + mensaje2B)\n\n# Añadir caracteres (desde aquí 'String Methods')\nmensaje3 = 'Hola'\nmensaje3 += ' '\nmensaje3 += 'Mundo'\nprint(mensaje3)\n\n# Extensión de caracteres\nmensaje4 = 'hola' + ' ' + 'mundo'\nprint(len(mensaje4))\n\n# Encontrar caracteres\nmensaje5 = \"Hola Mundo\"\nmensaje5A = mensaje5.find(\"Mundo\")\nprint(mensaje5A)\n\n# Minúsculas\nmensaje6 = \"HOLA MUNDO\"\nmensaje6A = mensaje6.lower()\nprint(mensaje6A)\n\n# Reemplazo\nmensaje7 = \"Hola mundo\"\nmensaje7A = mensaje7.replace(\"L\", \"pizza\")\nprint(mensaje7A)\n\n\"\"\"\nExtra\n\"\"\"\ndef check(word1: str, word2: str):\n    # Palíndromos\n    print(f\"¿{word1} es un palíndromo?  {word1 == word1[::-1]}\")\n    print(f\"¿{word2} es un palíndromo?  {word2 == word2[::-1]}\")\n    \n    # Anagrama\n    print(f\"¿{word1} es un anagrama de {word2}?  {sorted(word1) == sorted(word2)}\")\n\n    # Isogramas\n    \n    def isogram(word: str) -> bool:\n        wordDict = dict()\n        for word in word1:\n            wordDict[word] = wordDict.get(word, 0) + 1\n    \n        isogram = True\n        values = list(wordDict.values())\n        print(values)\n        isogramLen = values[0]\n        for wordCount in values:\n            if wordCount != isogramLen:\n                isogram = False\n                break\n        \n        return isogram\n            \n    \n    print(f\"¿{word1} es un isograma?  {isogram(word1)}\")\n    print(f\"¿{word2} es un isograma?  {isogram(word2)}\")\n\n    \n    print(isogram)\n    \ncheck(\"radar\", \"reconocer\")\ncheck(\"amor\", \"roma\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/franxiscodev.py",
    "content": "'''\nCadenas de caracteres\n'''\n\n# concatenación\nprint(\"Hola \" + \"Franxisco\")  # Hola Franxisco\nprint(\"Hola \" \"Franxisco\")  # Hola Franxisco    # no recomendado\n# Hola Franxisco  # recomendado   # f-string  # python 3.6\nprint(f\"Hola Franxisco\")\n# Hola Franxisco  # recomendado   # python 3.6\nprint(\"Hola {}\".format(\"Franxisco\"))\nprint(\"Hola %s\" % \"Franxisco\")  # Hola Franxisco  # recomendado   # python 2.7\nprint(\"Hola \" * 3)  # Hola Hola Hola    # repetición\n\nstr1 = \"Hola\"\nstr2 = \"Python\"\nprint(str1 + str2)  # HolaPython\nprint(str1 + \" \" + str2)  # Hola Python   # concatenación   # recomendado\nprint(str1, str2)  # Hola Python    # concatenación   # recomendado\nprint(str1, str2, sep=\" \")  # Hola Python    # concatenación   # recomendado\nprint(str1 * 3)  # HolaHolaHola    # repetición  # recomendado\nprint(f\"{str1} {str2}\")  # Hola Python    # f-string   # recomendado\nprint(\" \".join([str1, str2]))  # Hola Python    # concatenación   # recomendado\nprint(\"Hola\", \"Python\")  # Hola Python    # concatenación   # recomendado\n# Hola Python    # concatenación   # recomendado\nprint(\"Hola\", \"Python\", sep=\" \")\n\n# indexación strings\nmy_str = \"Hola Franxisco\"\nprint(my_str[0])  # H   # primer caracter\nprint(my_str[-1])  # o   # último caracter\nprint(my_str[0:4])  # Hola   # rango de caracteres  # [start:stop]\n# Franxisco   # rango de caracteres  # [start:]  # hasta el final\nprint(my_str[5:])\n# Hola   # rango de caracteres  # [:stop]  # desde el principio  # hasta stop\nprint(my_str[:4])\n# Fra   # rango de caracteres  # [start:stop]   # desde start  # hasta stop\nprint(my_str[5:8])\n# Hl rns o   # rango de caracteres  # [start:stop:step]  # desde start  # hasta stop  # con paso step   # recomendado\nprint(my_str[::2])\n# ocsixnarF aloH   # rango de caracteres  # [::-1]  # invertir cadena   # recomendado\nprint(my_str[::-1])\n# nix   # rango de caracteres  # [start:stop:step]  # desde start  # hasta stop  # con paso step  # recomendado  # invertido\nprint(my_str[8:5:-1])\n# rango de caracteres  # [start:stop]  # desde start  # hasta stop  # recomendado   # no hay caracteres\nprint(my_str[8:5])\n# Fra   # rango de caracteres  # [start:stop:step]  # desde start  # hasta stop  # con paso step  # recomendado\nprint(my_str[5:8:1])\n# longitud string\nprint(len(my_str))  # 14\n\n# slicing strings\nmy_str = \"Hola Franxisco\"   # 14\nprint(my_str[0:4])  # Hola\n\n# busqueda en strings\nmy_str = \"Hola Franxisco\"\n# True   # buscar si una cadena está en otra cadena\nprint(\"Franxisco\" in my_str)    # True\n# False   # buscar si una cadena no está en otra cadena  # recomendado  # más legible\nprint(\"Franxisco\" not in my_str)    # False\n\n# reemplazo en strings\nmy_str = \"Hola Franxisco Franxisco\"\n# Hola Python   # reemplazar una cadena por otra cadena\nprint(my_str.replace(\"Franxisco\", \"Python\"))  # Hola Python\n# Hola Python   # reemplazar una cadena por otra cadena  # recomendado\n# Hola Python  # 1 reemplazo\nprint(my_str.replace(\"Franxisco\", \"reemplaza solo el primero q encontro\", 1))\n# Hola Python   # reemplazar una cadena por otra cadena  # recomendado  # case sensitive\n# Hola Franxisco  # no hay reemplazo\nprint(my_str.replace(\"franxisco\", \"Python\"))\n# Hola Franxisco   # reemplazar una cadena por otra cadena  # recomendado  # case sensitive # no hay reemplazo  # más legible\n# Hola Franxisco  # 1 reemplazo    # más legible   # recomendado   # case sensitive    # no hay reemplazo\nprint(my_str.replace(\"franxisco\", \"Python\", 1))\n\n# split strings\nmy_str = \"Hola Franxisco\"\n# ['Hola', 'Franxisco']   # separar una cadena por un caracter\nprint(my_str.split(\" \"))\n# ['Hola', 'Franxisco']   # separar una cadena por un caracter  # recomendado   # más legible\n# ['Hola', 'Franxisco']  # 1 separación  # recomendado\nprint(my_str.split(\" \", 1))\n# ['Hola', 'Franxisco']   # separar una cadena por un caracter  # recomendado   # más legible   # case sensitive\n# ['Hola', 'Franxisco']  # 1 separación  # recomendado  # case sensitive\nprint(my_str.split(\" \", 1))\n# ['Hola', 'Franxisco']   # separar una cadena por un caracter  # recomendado   # más legible   # case sensitive    # no hay separación\n# ['Hola', 'Franxisco']  # 2 separaciones  # recomendado  # case sensitive  # no hay separación\nprint(my_str.split(\" \", 2))\n# ['Hola', 'Franxisco']   # separar una cadena por un caracter  # recomendado   # más legible   # case sensitive    # no hay separación # más legible   # recomendado\n# ['Hola', 'Franxisco']  # 2 separaciones  # recomendado  # case sensitive  # no hay\nprint(my_str.split(\" \", 2))\n# ['Hola', 'Franxisco']   # separar una cadena por un caracter  # recomendado   # más legible   # case sensitive    # no hay separación # más legible   # recomendado                                       # case sensitive\n\n# minusculas y mayusculas - capitalización - títulos\nmy_str = \"Hola Franxisco\"\n# hola franxisco   # convertir a minúsculas\nprint(my_str.lower())\n# HOLA FRANXISCO   # convertir a mayúsculas\nprint(my_str.upper())\n# Hola Franxisco   # convertir a capitalización\nprint(my_str.capitalize())\n# Hola franxisco   # convertir a capitalización\nprint(my_str.title())\n# Hola franxisco   # convertir a capitalización  # recomendado\n\n# espacios en blanco\nmy_str = \" Hola Franxisco \"\n# Hola Franxisco   # eliminar espacios en blanco al principio y al final\nprint(my_str.strip())\n# Hola Franxisco   # eliminar espacios en blanco al principio y al final  # recomendado\nprint(my_str.strip())\n# Hola Franxisco   # eliminar espacios en blanco al principio\nprint(my_str.lstrip())\n# Hola Franxisco   # eliminar espacios en blanco al principio  # recomendado\nprint(my_str.lstrip())\n# Hola Franxisco   # eliminar espacios en blanco al final\nprint(my_str.rstrip())\n# Hola Franxisco   # eliminar espacios en blanco al final  # recomendado\nprint(my_str.rstrip())\n\n# encontrar  la posicion de una cadena\nmy_str = \"Hola Franxisco @franxiscodev\"\n# 5   # encontrar la posición de una cadena en otra cadena\nprint(my_str.find(\"Franxisco\"))  # 5\n# -1   # encontrar la posición de una cadena en otra cadena  # recomendado\nprint(my_str.find(\"Python\"))    # -1    # no encontrado     # recomendado\nprint(my_str.find(\"f\"))    # 16    # @franxiscodev\nprint(my_str.lower().find(\"f\"))    # 5    # Franxisco -> franxisco x el lower\nprint(my_str.lower().count(\"f\"))    # 2 veces\nprint(my_str.count(\"f\"))    # 1 vez la otra es MAY\n\n# interpolación de strings\nmy_str = \"Franxisco\"\n# Hola Franxisco   # interpolación de strings   # recomendado\nprint(f\"Hola {my_str}\")  # Hola Franxisco    # recomendado\n# Hola Franxisco   # interpolación de strings\n\n# transformar strings en listas\nmy_str = \"Hola Franxisco\"\n# ['H', 'o', 'l', 'a', ' ', 'F', 'r', 'a', 'n', 'x', 'i', 's', 'c', 'o']   # transformar una cadena en una lista\nprint(list(my_str))\n\n# transformar lista en string\nmy_list = [\"H\", \"o\", \"l\", \"a\", \" \", \"F\",\n           \"r\", \"a\", \"n\", \"x\", \"i\", \"s\", \"c\", \"o\"]\n# Hola Franxisco   # transformar una lista en una cadena\nprint(\"\".join(my_list))\n\n'''\nExtra\n'''\n\n\ndef check_palindrome(word: str) -> bool:\n    return word == word[::-1]   # invertir cadena\n\n\ndef check_anagram(word_1: str, word_2: str) -> bool:\n    return sorted(word_1) == sorted(word_2)   # ordenar cadena\n\n\ndef check_isogram(word: str) -> bool:\n    return len(word) == len(set(word))   # no repetir caracteres\n\n\n# isogramas\ndef check_isograms(word: str) -> str:\n    word_dict = {}  # diccionario\n    for char in word:\n        word_dict[char] = word_dict.get(char, 0) + 1\n\n    is_isogram = True\n    # tomar el len de la primera pos y todas deben ser del mismo valor\n    values_word_dict = list(word_dict.values())\n    isogram_len = values_word_dict[0]   # tomar el len de la primera pos\n    for char_count in values_word_dict:\n        if char_count != isogram_len:\n            is_isogram = False\n            break   # salir del ciclo\n\n    return is_isogram\n\n\nprint(\"--------- Isogramas ---------\")\npalabra = \"murcielago\"\n# True\nprint(f\"la palabra {palabra} es un isograma {check_isograms(palabra)}\")\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/gabrielramos02.py",
    "content": "# #04 CADENAS DE CARACTERES\n\n# Acceso a caracteres\nejemplo = \"ejemplo\"\nprint(ejemplo[1])  # Accede al elemtento en la segunda posicion del string\n\n#  Repeticion\nprint(\n    ejemplo.count(\"e\")\n)  # count.() devuelve la cantidad de caracteres que son iguales al pasado por parametros\n\n# Longitud\nprint(\n    len(ejemplo)\n)  # len() devuelve la cantidad de elementos que tenga el objeto pasado por parametros\n\n# Concatenacion\nprint(ejemplo + \" concatenacion\")\n\n# Recorrido\nfor i in ejemplo:  # Recorre cada uno de los elementos del string\n    print(i)\n\n# Conversion a mayuscula\nprint(ejemplo.capitalize())  # solo la inicial\nprint(ejemplo.upper())  # todas las letras\nejemplo = ejemplo.upper()  # convertimos todas a mayusculas para los siguientes ejemplos\nprint(ejemplo.lower())  # todas son minusculas\n\n# Remplazo\nreemplazado = ejemplo.replace(\"EJEMPLO\", \"ejemplo de reemplazo\")\nprint(reemplazado)\n\n# Division\nprint(ejemplo.split(\",\"))\n\n\n# Dificultado extra\n\ndef verificar(palabra1: str, palabra2: str):\n    if palabra1.lower() == palabra2.lower():\n        print(\"Las palabras son iguales\")\n    palabra1 = palabra1.lower()\n    palabra2 = palabra2.lower()\n    def es_palindromo():\n        if len(palabra1) == len(palabra2):\n            return palabra1.lower() == palabra2.lower()[::-1]\n        else: return False\n    print(\"Palindromo: \",es_palindromo())\n          \n    def es_anagrama(): \n        list_palabra1 = list()\n        list_palabra2 = list()\n        for index in palabra1:\n            list_palabra1.append(index)\n        for index in palabra2:\n            list_palabra2.append(index)\n        list_palabra1.sort()\n        list_palabra2.sort()\n        #print(list_palabra1)\n        #print(list_palabra2)\n\n        return list_palabra1 == list_palabra2\n    \n    print(\"Anagrama: \",es_anagrama())\n\n\nverificar(\"roma\",\"amor\")\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/garos01.py",
    "content": "# Acceso a caracteres específicos\ncadena = \"Hola, mundo!\"\nprint(cadena[0])\n\n# Subcadenas\nsubcadena = cadena[1:5]\nprint(subcadena)\n\n# Longitud de la cadena\nlongitud = len(cadena)\nprint(longitud)\n\n# Concatenación\notra_cadena = \"¡Cómo estás?\"\nconcatenacion = cadena + \" \" + otra_cadena\nprint(concatenacion)\n\n# Repetición\nrepetida = cadena * 3\nprint(repetida)\n\n# Recorrido\nfor letra in cadena:\n    print(letra)\n\n# Conversión a mayúsculas y minúsculas\nmayusculas = cadena.upper()\nminusculas = cadena.lower()\nprint(mayusculas)\nprint(minusculas)\n\n# Reemplazo\nnueva_cadena = cadena.replace(\"mundo\", \"amigo\")\nprint(nueva_cadena)\n\n# División\npalabras = cadena.split()\nprint(palabras)\n\n# Unión\nunion = \" \".join(palabras)\nprint(union)\n\n# Interpolación\nnombre = \"Juan\"\nsaludo_personalizado = f\"Hola, {nombre}!\"\nprint(saludo_personalizado)\n\n# Verificación\ncontiene_hola = \"Hola\" in cadena\nprint(contiene_hola)\n\n\n# Ejercicio extra\n\n\ndef es_palindromo(palabra):\n    palabra = palabra.lower().replace(\" \", \"\")\n    return palabra == palabra[::-1]\n\n\ndef es_anagrama(palabra1, palabra2):\n    palabra1 = palabra1.lower().replace(\" \", \"\")\n    palabra2 = palabra2.lower().replace(\" \", \"\")\n    return sorted(palabra1) == sorted(palabra2)\n\n\ndef es_isograma(palabra):\n    palabra = palabra.lower().replace(\" \", \"\")\n    return len(palabra) == len(set(palabra))\n\n\ndef analizar_palabras(palabra1, palabra2):\n    if es_palindromo(palabra1):\n        print(f\"{palabra1} es un palíndromo.\")\n    else:\n        print(f\"{palabra1} no es un palíndromo.\")\n\n    if es_anagrama(palabra1, palabra2):\n        print(f\"{palabra1} y {palabra2} son anagramas.\")\n    else:\n        print(f\"{palabra1} y {palabra2} no son anagramas.\")\n\n    if es_isograma(palabra1):\n        print(f\"{palabra1} es un isograma.\")\n    else:\n        print(f\"{palabra1} no es un isograma.\")\n\n    if es_palindromo(palabra2):\n        print(f\"{palabra2} es un palíndromo.\")\n    else:\n        print(f\"{palabra2} no es un palíndromo.\")\n\n    if es_anagrama(palabra1, palabra2):\n        print(f\"{palabra1} y {palabra2} son anagramas.\")\n    else:\n        print(f\"{palabra1} y {palabra2} no son anagramas.\")\n\n    if es_isograma(palabra2):\n        print(f\"{palabra2} es un isograma.\")\n    else:\n        print(f\"{palabra2} no es un isograma.\")\n\n\npalabra1 = input(\"Ingresa la primera palabra: \")\npalabra2 = input(\"Ingresa la segunda palabra: \")\n\nanalizar_palabras(palabra1, palabra2)\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/ggilperez.py",
    "content": "# Problem #04 Strings\n\nmy_string = \"hello world\"\n\n# Access first char / index\nprint(f\"{my_string[0] = }\")\n\n# Substring\nprint(f\"{'hello' in my_string = }\")\n\n# Length\nprint(f\"{len(my_string) = }\")\n\n# Concat\nprint(f\"{my_string + ' Python' = }\")\n\n# Repeat\nprint(f\"{my_string * 3 = }\")\n\n# Loop\nprint(\"Start loop\")\nfor char in my_string:\n    print(char)\nprint(\"End loop\")\n\n# Upper case\nprint(f\"{my_string.upper() = }\")\n\n# Lower case\nprint(f\"{my_string.lower() = }\")\n\n# Title\nprint(f\"{my_string.title() = }\")\n\n# Capitalize\nprint(f\"{my_string.capitalize() = }\")\n\n\n# Replace...\n# Strings are immutable but can return new object with replaced string\nprint(f\"{my_string.replace('world', 'Python') = }\")\n\n# Split\nprint(f\"{my_string.split((' ')) = }\")\n\n# Slicing\nprint(f\"{my_string[2:5] = }\")\n\n# Trimm / Strip\nmy_string = \" \" + my_string + \" \"\nprint('\"' + my_string + '\"')\nprint(f\"{my_string.strip() = }\")\n\n\nmy_string = \"hello world\"\n\n# Search\nprint(f\"{my_string.startswith('hello') = }\")\nprint(f\"{my_string.endswith('world') = }\")\nprint(f\"{my_string.find('w') = }\")\n\n# Count\nprint(f\"{my_string.count('l') = }\")\n\n# Format\nmy_string = \"Hello {0}\"\nprint('\"' + my_string + '\"')\nprint(f\"{my_string.format('Python') = }\")\n\n# Cast\nmy_string = \"hello world\"\n\n# To list\nprint(f\"{list(my_string) = }\")\n\n# From list\nprint(f\"{''.join(['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd']) = }\")\n\n# To int\nprint(f\"{int('1234') = }\")\n\n# From int\nprint(f\"{str(1234) = }\")\n\n# To float\nprint(f\"{float('12.34') = }\")\n\n# From float\nprint(f\"{str(12.34) = }\")\n\n# Checks\nprint(f\"{my_string.isdigit() = }\")\nprint(f\"{my_string.isalpha() = }\")\nprint(f\"{my_string.isalnum() = }\")\nprint(f\"{my_string.isnumeric() = }\")\nprint(f\"{my_string.isascii() = }\")\nprint(f\"{my_string.isdecimal() = }\")\nprint(f\"{my_string.isidentifier() = }\")\nprint(f\"{my_string.islower() = }\")\nprint(f\"{my_string.isprintable() = }\")\nprint(f\"{my_string.isspace() = }\")\nprint(f\"{my_string.istitle() = }\")\nprint(f\"{my_string.isupper() = }\")\n\n# Extra\n\ndef is_palindrome(word) -> bool:\n    return word[::-1] == word\n\ndef is_anagram(word_1: str, word_2: str) -> bool:\n    return sorted(word_1) == sorted(word_2)\n\ndef is_isogram(word: str) -> bool:\n    \"\"\"\n    An isogram must have the same count on each letter/char\n    \"\"\"\n    innit_count = word.count(word[0])\n    for letter in word:\n        if word.count(letter) != innit_count:\n            return False\n    return True\n\ndef do_checks(word_1: str, word_2: str):\n    print(f\"is palindrome {word_1} {is_palindrome(word_1)}\")\n    print(f\"is palindrome {word_2} {is_palindrome(word_2)}\")\n\n    print(f\"is anagram {word_1} / {word_2} {is_anagram(word_1, word_2)}\")\n\n    print(f\"is isogram {word_1} {is_isogram(word_1)}\")\n    print(f\"is isogram {word_2} {is_isogram(word_2)}\")\n\ndo_checks(\"hello\", \"world\")\ndo_checks(\"badab\", \"dabab\")\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/gjbecerrae.py",
    "content": "#Cadenas de caracteres\nmyCadena = 'esta ES mi CAdena'\nprint(myCadena[0]) # Acceder a caracteres, como si fuera una lista\nprint(myCadena.capitalize()) # Primer caracter en mayuscula\nprint(myCadena.upper()) #Todos los caracteres en mayuscula\nprint(myCadena.casefold()) #Todos los caracteres en minuscula\nprint(myCadena.count('e')) #Todas las ocurrencuas de 'e' (2 para este ejemplo)\nprint(myCadena.find('E')) # Index de la primera ocuurencia de 'E'\nprint(myCadena.find('q'))\ntry:\n    print(myCadena.index('q'))\nexcept ValueError:\n    print('Item not found')\nprint(myCadena.isascii()) #True si todos los caracteres son ascii\nprint(myCadena.isalpha()) #True si todos los caracteres son letras, en este caso hay espacios entonces False\n\nmyCadenaLista=['esta','era','una','lista']\nmyCadenaString = ' '.join(myCadenaLista) # list to string\nprint(myCadenaString, type(myCadenaString))\nprint('La longitud de myCadenaString es '+ str(len(myCadenaString)))\n\ncadenaA = 'Cadena A'\ncadenaB = 'Cadena B'\nprint(cadenaA + ' ' + cadenaB) #Concatenacion\n\ncadenaC = 'Esta es la cadena C'\nprint(cadenaC)\nprint('Cadena C convertida en lista ->')\nprint(cadenaC.split())\n\n####### Dificultad Extra\ndef isPalindrom(wordA, wordB):\n    if wordA == wordB[::-1]:\n        print('Las palabras son palindromas')\n    else:\n        print('Las palabras no son palindromas')\n\ndef isAnagram(wordA, wordB):\n    listA = list(wordA)\n    listB = list(wordB)\n    if sorted(listA) == sorted(listB):\n        print('Las palabras son anagramas')\n    else:\n        print('Las palabras no son anagrams')\n\ndef isIsogram(wordA):\n    count = 0\n    for i in range (len(wordA)//2):                \n        if wordA.count(wordA[i]) > 1:            \n            count += 1\n    if count >  2:\n        print('Is isogram')\n\nisPalindrom('anilina','anilina')\nisAnagram('peinar','pierna')\nisIsogram('acondicionar')\n\n\n\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/gmbarrios.py",
    "content": "\"\"\"\nMuestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres en tu lenguaje. Algunas de estas operaciones podrían ser (busca todas las que puedas): acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido, conversion a mayúsculas y minúsculas, reemplazo, division, union, interpolación, verificación...\n\"\"\"\n\ncadena = \"Esto es una cadena de texto.\"\n\n# Acceso a caracteres\nprint(cadena[5])\nprint(cadena[-2])\n\n# Subcadenas\nsubcadena = \"Texto\"\nprint(cadena.find(subcadena))\n\n# Longitud\nprint(len(cadena))\n\n# Concatenación\npregunta = \"¿Que es esto?\"\nprint(f\"{pregunta} \\n{cadena}\")\n\n# Repetición\nprint(cadena * 3)\n\n# Recorrido\nfor i in cadena:\n    print(i)\n\n# Conversion a mayúsculas y minúsculas.\nprint(cadena.upper())\nprint(cadena.lower())\n\n# Reemplazo\nprint(cadena.replace(\"texto\", \"hierro\"))\n\n# Division\nprint(cadena.split(' '))\n\n# Union\nprint(\" \".join(cadena))\n\n# Interpolación\nprint(f\"CADENA - {cadena} - INTERPOLADA.\")\n\n# Verificación\nverificar = \"666\"\nprint(verificar.isalnum())\nprint(verificar.isalpha())\nprint(verificar.isdecimal())\nprint(verificar.isdigit())\nprint(verificar.isascii())\nprint(verificar.isupper())\nprint(verificar.islower())\nprint(verificar.isnumeric())\nprint(verificar.isprintable())\nprint(verificar.isspace())\nprint(verificar.istitle())\nprint(verificar.startswith(\"9\"))\nprint(verificar.endswith(\"6\"))\n\n\n\"\"\"\nDificultad extra\nCrea un programa que analice dos palabras diferentes y realice comprobaciones para descubrir si son:\n- Palíndromos\n- Anagramas\n- Isogramas\n\"\"\"\n# Palindromo: palabra o frase cuyas letras están dispuestas de tal manera que resulta la misma leída de izquierda a derecha que de derecha a izquierda.\n\ndef palindrome(word):\n    word = word.lower().replace(\" \", \"\")\n    return word == word[::-1]\n\n\nprint(palindrome(\"tomate\"))\nprint(palindrome(\"arepera\"))\n\n\n# Anagrama: cambio en el orden de las letras de una palabra o frase que da lugar a otra palabra o frase distinta.\n\ndef anagram(word1, word2):\n    if word1.lower() == word2.lower():\n        return False\n    return sorted(word1.lower()) == sorted(word2.lower())\n\n\nprint(anagram(\"ramo\", \"amor\"))\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/gonzadev28.py",
    "content": "\"\"\" EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\"\"\"\n\ncadena_texto = \"Aprendiendo Python con Mouredev\"\n\nprint(cadena_texto[12]) #Acceso a un caracterter en especifico en la posicion[12] = \"P\"\nprint(cadena_texto.find(\"Mouredev\")) #Acceso a posicion de subcadena \"Mouredev\" = [23]\nprint(len(cadena_texto)) #Acceso a la longitud de cadena de texto (31)\n\ncadena_texto2 = \"en Github y Youtube\"\n\nprint(cadena_texto + \", \" + cadena_texto2) #Concatenacion de 2 cadenas de texto\nprint(cadena_texto * 5) #Repeticion de cadena de texto\n\nfor i in cadena_texto: #Reccorido por caracter de la cadena de texto\n    print(i)\n\nprint(cadena_texto.upper()) #Convierte la cadena de texto a mayusculas\nprint(cadena_texto.lower()) #Convierte la cadena de texto a minusculas \nprint(cadena_texto.replace(\"Python\", \"Java\")) #Reemplaza cadena de texto \"Python\" a \"Java\"\nprint(cadena_texto.split(\" \")) #Separa cadena de texto donde haya \" \" (espacio)\n\n#Union\ntexto_separado = [\"Esto\", \"es\", \"texto\", \"separado\"]\nprint(\" \".join(texto_separado)) #Une diferentes cadenas de texto en uno solo\n\n#Interpolacion \nprint(f\"Esta es la primera cadena de texto: {cadena_texto} y esta la segunda: {cadena_texto2}\")\n\n#Verificacion\ncadena_texto3 = \"Python\"\nprint(\"h\" in(cadena_texto3)) #Verifica si caracter \"h\" se encuentra en cadena de texto\nprint(cadena_texto3.isalpha()) #Verfica si cadena de texto es alfabetica\nprint(cadena_texto3.isalnum()) #Verfifica si cadena de texto es alfanumerica\nprint(cadena_texto3.isdigit()) #Verifica si cadena de texto es numerica \nprint(cadena_texto3.istitle()) #Verifica si cadena de texto tiene formato de titulo \n\n\"\"\" DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas \"\"\"\n\n#Palindromo\n\ndef palindromo(palabra1):\n    if(palabra1 == palabra1[::-1]):\n        print(f\"La palabra {palabra1} es palindromo\")\n    else:\n        print(f\"La palabra {palabra1} no es palindromo\")\n\npalindromo(\"radar\")\npalindromo(\"perro\")\n\n#Anagrama\n\ndef anagrama(palabra1, palabra2):\n    if(sorted(palabra1) == sorted(palabra2)):\n        print(f\"La palabra {palabra1} es anagrama de {palabra2}\")\n    else:\n        print(\"No son anagramas\")\n\nanagrama(\"sentido\", \"destino\")\nanagrama(\"programador\", \"estudiante\")\n\n#Isograma\n\ndef isograma(palabra1):\n    if(len(palabra1) == len(set(palabra1))):\n        print(f\"La palabra {palabra1} es un isograma\")\n    else:\n        print(f\"La palabra {palabra1} no es isograma\")\n\nisograma(\"murcielago\")\nisograma(\"isograma\")\n\n\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/gringoam.py",
    "content": "\"\"\"\nOperaciones\n\"\"\"\n\ns1 = \"Hola\"\ns2 = \"Python\"\n\n# Concatenación\nprint(s1 + \", \" + s2 + \"!\")\n\n# Repetición\nprint(s1 * 3)\n\n# Indexación\nprint(s1[0] + s1[1] + s1[2] + s1[3])\n\n# Longitud\nprint(len(s2))\n\n# Slicing (porción)\nprint(s2[2:6])\nprint(s2[2:])\nprint(s2[0:2])\nprint(s2[:2])\n\n# Busqueda\nprint(\"a\" in s1)\nprint(\"i\" in s1)\n\n# Reemplazo\nprint(s1.replace(\"o\", \"a\"))\n\n# División\nprint(s2.split(\"t\"))\n\n# Mayúsculas, minúsculas y letras en mayúsculas\nprint(s1.upper())\nprint(s1.lower())\nprint(\"brais moure\".title())\nprint(\"brais moure\".capitalize())\n\n# Eliminación de espacios al principio y al final\nprint(\" brais moure \".strip())\n\n# Búsqueda al principio y al final\nprint(s1.startswith(\"Ho\"))\nprint(s1.startswith(\"Py\"))\nprint(s1.endswith(\"la\"))\nprint(s1.endswith(\"thon\"))\n\ns3 = \"Brais Moure @mouredev\"\n\n# Búsqueda de posición\nprint(s3.find(\"moure\"))\nprint(s3.find(\"Moure\"))\nprint(s3.find(\"M\"))\nprint(s3.lower().find(\"m\"))\n\n# Búsqueda de ocurrencias\nprint(s3.lower().count(\"m\"))\n\n# Formateo\nprint(\"Saludo: {}, lenguje: {}!\".format(s1, s2))\n\n# Interpolación\nprint(f\"Saludo: {s1}, lenguje: {s2}!\")\n\n# Tranformación en lista de caracteres\nprint(list(s3))\n\n# Transformación de lista en cadena\nl1 = [s1, \", \", s2, \"!\"]\nprint(\"\".join(l1))\n\n# Transformaciones numéricas\ns4 = \"123456\"\ns4 = int(s4)\nprint(s4)\n\ns5 = \"123456.123\"\ns5 = float(s5)\nprint(s5)\n\n# Comprobaciones varias\ns4 = \"123456\"\nprint(s1.isalnum())\nprint(s1.isalpha())\nprint(s4.isalpha())\nprint(s4.isnumeric())\n\n\"\"\"Extra\"\"\"\n\n\n\ndef check(palabra1:str, palabra2:str):\n    #Polindroma\n    print(f\"{palabra1} es una palabra polindroma: {palabra1== palabra1[::-1]}\")\n    print(f\"{palabra2} es una palabra polindroma: {palabra2== palabra2[::-1]}\")\n\n    #Anagramas\n    print(f\"{palabra1} y {palabra2} son anagrama?: {palabra1== palabra1[::-1]}\")\n\n    #\n\n\ncheck(\"radar\", \"ardar\")\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/h4ckxel.py",
    "content": "\"\"\"\nauthor: h4ckxel\n\"\"\"\nmy_string = \"Esto es un string\"\nprint(len(my_string)) # Retorna el numero de caracteres\nprint(my_string[5]) # Retorna el caracter en la posicion 5\nprint(my_string[2:9]) # Retorna una subcadena\nprint(my_string * 3) # Repite la cadena 3 veces\nprint(\"e\" in my_string) # Busca el caracter en el string\n\nfor element in my_string: # Recorre una cadena\n    print(element)\n    \nmy_other_string = \" esto es otro string\"\nprint(my_string + \" \"+ my_other_string) #concatena dos cadenas\nprint(my_string.upper()) #retorna el string en mayusculas\nprint(my_string.lower()) #retorna el string en minuscula\nprint(my_string.title()) #devuelve una copia usando el titulo como referencia\nprint(my_string.replace(\"o\",\"O\")) # reemplaza la primera ocurrencia indicada\nprint(my_other_string.lstrip()) #elimina espacios en blanco al principio\nprint(my_other_string.rstrip()) #elimina espacios en blanco al final\nprint(my_other_string.split(\"o\")) # devuelve una lsita separada por el parametro indicado\nprint(my_string.startswith(\"es\")) #busca al principio la primera ocurrencia\nprint(my_string.endswith(\"es\")) #busca al final la primera ocurrencia\nprint(\"Cadena1:  {}, cadena2: {}\".format(my_string,my_other_string) )\n\n\n\n# DIFICULTAD EXTRA\ndef comprobar(word1, word2):\n    #palindromo\n    reverse_word1= word1[::-1]\n    reverse_word2= word2[::-1]\n    print(f\"la palabra {word1} es palindromo?: {word1==reverse_word1}\")\n    print(f\"la palabra {word2} es palindromo?: {word2==reverse_word2}\")\n\n    #anagrama\n    print(f\"las palabras {word1} y {word2} son anagrama?: {sorted(word1)==sorted(word2)}\")\n\n    #isograma\n    print(f\"{word1} es isograma?: {len(word1) == len(set(word1))}\") #funciona si el string no se repite\n    print(f\"{word2} es isograma?: {len(word2) == len(set(word2))}\")\n\n    def is_isogram(word):\n        word_dict = dict()\n        for element in word:\n            word_dict[element] = word_dict.get(element, 0) + 1\n        isogram = True\n        values = list(word_dict.values())\n        len_isogram = values[0]\n        for word_count in values:\n            if word_count != len_isogram:\n                isogram = False\n                break\n        return isogram\n    print(f\"{word1} es isograma?: {is_isogram(word1)}\")\n    print(f\"{word2} es isograma?: {is_isogram(word2)}\")\n\ncomprobar(\"retos\", \"programacion\")\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/haroldAlb.py",
    "content": "cadena_01= \"Hola\"\ncadena_02= \"Mundo\"\ncadena_03= \"Que ase?\"\ncadena_04= \"HAROLD\"\ncadena_05= \"5.33,12,200.633,001,3,0.009\"\ncadena_06= [\"Hola\", \"Harolito\", \"que\", \"ases?\"]\ncadena_07= \"123456\"\ncadena_08= \"3.1416\"\n### Acceso a caracteres específicos ###\nprint(cadena_01[2]) # Imprime el caracter en el índice 2 \n\n### subcadenas ###\n\n\n### longitud ###\nprint(len(cadena_01)) # retorna el número total de caracteres que tenga el string\n\n### concatenación ###\nprint(cadena_01 + \" \" + cadena_02)\n\n### repetición ###\nprint(\"#\" * 10)\n\n### recorrido ###\nfor c in cadena_03:\n    print(c)\n\n### conversión a mayúsculas ###\nprint(cadena_01.upper())\n\n### conversión a minúsculas ###\nprint(cadena_04.lower())\n\n### reemplazo ###\nprint(\"Harold que ases\".replace(\"Harold\", cadena_01))\n\n### división ###\nprint(cadena_05.split(\",\")) # Divide la cadena en una lista de subcadenas separadas por el separador especificado\n\n### unión ###\nprint(\" \".join(cadena_06)) # Une lo elementos de una lista, en una sola cadena. El separador se indica al principio\n\n### interpolación ###\n\n\n### verificación ###\n\n\n### slicing ###\nprint(cadena_04[3:])\nprint(cadena_04[-1:-len(cadena_04)-1:-1])\n\n### busqueda ###\nprint(\"u\" in cadena_02)\nprint(\"a \" in cadena_02)\n\n### busqueda al principio y al final ###\nprint(cadena_01.startswith(\"H\"))\nprint(cadena_01.startswith(\"K\"))\nprint(cadena_01.endswith(\"a\"))\nprint(cadena_01.endswith(\"i\"))\n\n### busqueda de posición ###\nprint(cadena_03.lower().find(\"q\")) # pasa las mayusculas a minusculas y busca la posición de la 'q'\n\n### conversión a Integer ###\nprint(type(int(cadena_07)))\nprint(type(float(cadena_08)))\n\n### EXTRA ###\n\"\"\"\nUn palíndromo es una palabra o frase que se lee igual en un sentido que en otro.\nUn anagrama es cojer una palabra o frase, reordenarla y obtenes otra palabra o otra frase.\nUn isograma es una palabra donde ninguna letra se repite, como \"murciélago\".\n\"\"\" \ndef comprobacion(palabra_1: str, palabra_2: str):\n    # Palíndromo\n    def palindromo(palabra):\n        palabra_reb= palabra[::-1]\n\n        if palabra == palabra_reb:\n            print(f\"{palabra} si es un palíndromo\")\n        else:\n            print(f\"{palabra} no es un palíndromo\")\n\n    # Anagrama\n    def anagrama(palabra_1, palabra_2):\n        count= 0\n        aux= \"\"\n        if len(palabra_1) == len(palabra_2):\n            for p1 in palabra_1:\n                for p2 in palabra_2:\n                    if p1 == p2 and p2 not in aux:\n                        count += 1\n                aux= aux + p1\n            if count == len(palabra_2):\n                print(f\"{palabra_1} y {palabra_2} SI son Anagrama\")\n            else:\n                print(f\"{palabra_1} y {palabra_2} no son Anagrama\")\n        else:\n            print(f\"{palabra_1} y {palabra_2} NO son Anagrama\")\n\n    # Solución Anagrama de Brais #\n\n    def anagramaBrais(palabra_1, palabra_2):\n        if sorted(palabra_1) == sorted(palabra_2): # Ordena las letras de cada string y las compara entre si. Si tienen las mismas letras es que son Anagramas.\n            print(f\"{palabra_1} SI es anagrama de {palabra_2}\")\n        else:\n            print(f\"{palabra_1} NO es anagrama de {palabra_2}\")\n    \n    # Isograma\n    def isograma(palabra):\n        aux=\"\"\n\n        for p in palabra:\n            if p not in aux:\n                aux= aux + p\n            else:\n                break\n        \n        if palabra == aux:\n            print(f\"{palabra} SI es un isograma\")\n        else:\n            print(f\"{palabra} NO es un isograma\")\n\n    palindromo(palabra_1)\n    palindromo(palabra_2)\n    anagrama(palabra_1, palabra_2)\n    anagramaBrais(palabra_1, palabra_2)\n    isograma(palabra_1)\n    isograma(palabra_2)\n\n\n\nif __name__ == \"__main__\":\n    word_1= input(\"Introduce la primera palabra: \")\n    word_2= input(\"Introduce la segunda palabra: \")\n\n    comprobacion(word_1, word_2)"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/hectordbh.py",
    "content": "\"\"\" OPERACIONES CON CADENAS DE CARACTERES \"\"\"\n\n# Concatenación y repetición\nS1 = \"Había una vez, \"\nS2 = \"un barquito chiquitito \"\nS3 = \"que no podía, \"\nS4 = \"que no podía navegar.\"\nprint((S1 + S2) * 2 + (S3 * 2) + S4)\n\n# Función str()\nNOMBRE = \"María\"\nEDAD = 22\nprint(\"Mi hermana se llama \" + NOMBRE + \" y su edad es \" + str(EDAD))\n\n# Método .format()\nNOMBRE2 = \"Ricardo\"\nNUMERO_GATOS = 3\nprint(f\"Mi abuelo se llama {NOMBRE2} y tiene {NUMERO_GATOS} gatos\")\n\n# Acceso a caracteres específicos, o a varios caracteres\nS = \"Soy fan de los videojuegos\"\nprint(S[3])\nprint(S[-1]) # Último elemento\nprint(S[4:7]) # Del quinto al séptimo\nprint(S[-10:]) # Diez últimos caracteres\n\n# Cambio a minúsculas, mayúsculas, capitalizar y titular cada palabra\nS5 = \"Me ENCANTAN el chocolate y las galletas\"\nprint(S5.lower())\nprint(S5.upper())\nprint(S5.capitalize())\nprint(S5.title())\n\n# Cambios de mayúsculas a minúsculas y viceversa\nprint(S5.swapcase())\n\n# Método .count()\nprint(S5.count(\"s\"))\n\n# Método replace\nprint(S5.replace(\"galletas\", \"pastas\"))\n\n# Método split\nprint(S5.split(\"e\"))\n\n# Método .strip(), .rstrip() y lstrip()\nS6 = \"       El elefante tiene las orejas muy grandes        \"\nprint(S6.strip())\nprint(S6.rstrip())\nprint(S6.lstrip())\n\n# Método .find(), .index() y .rindex()\nprint(S6.find(\"e\", 7))\nprint(S6.index(\"e\", 3))\nprint(S6.rindex(\"e\"))\n\n# Función len()\nprint(len(S6))\n\n# Recorrer un string\nfor c in S6.strip():\n    print(c, end=\"#\")\n\n# Verificación\nS7 = \"verificacion\"\nN = 0\nLETTER = \"c\"\nprint(\"\\nLa letra '{}' {} está en la palabra\".format(LETTER, \"sí\" if LETTER in S7 else \"no\"))\n\n\n# DIFICULTAD EXTRA\n\nclass WordAnalisys():\n    \"\"\"\n    Clase para analizar las palabras pasadas, unas con otras e\n    individualmente\n    \"\"\"\n    def __init__(self, w1, w2):\n        self.w1 = w1.lower()\n        self.w2 = w2.lower()\n        self.reverse_w = str()\n        self.reverse_w2 = str()\n        self.dicc_w1 = {}\n        self.dicc_w2 = {}\n        self.dicc_result = {}\n\n    def are_palindrome(self):\n        \"\"\"\n        Método que determina si dos palabras son palíndromas,\n        se leen igual en ambos sentidos\n        \"\"\"\n        for character in self.w2:\n            self.reverse_w2 = character + self.reverse_w2\n\n        if self.w1 == self.reverse_w2:\n            return True\n        return None\n\n    def is_palindrome(self, w):\n        \"\"\"\n        Método para determinar si una palabra es palíndroma,\n        se lee igual en ambos sentidos\n        \"\"\"\n        for character in w:\n            self.reverse_w = character + self.reverse_w\n\n        if w == self.reverse_w:\n            return True\n        return None\n\n    def are_anagram(self):\n        \"\"\"\n        Método que determina si dos palabras son anagramas,\n        usan las mismas letras para formar palabras distintas\n        \"\"\"\n        for character in self.w1:\n            self.dicc_w1.setdefault(character, self.w1.count(c))\n\n        for letter in self.w2:\n            self.dicc_w2.setdefault(letter, self.w1.count(letter))\n\n        if dict(sorted(self.dicc_w1.items())) == dict(sorted(self.dicc_w2.items())):\n            return True\n        return None\n\n    def are_isogram(self):\n        \"\"\"\n        Método que determina si dos palabras son isogramas,\n        tienen repetidas el mismo número de veces las letras\n        \"\"\"\n        self.are_anagram()\n        first_value_dicc_w1 = self.dicc_w1.get(list(self.dicc_w1.keys())[0])\n        first_value_dicc_w2 = self.dicc_w2.get(list(self.dicc_w2.keys())[0])\n        if (self.is_isogram(self.w1) is True and self.is_isogram(self.w2) is True and\n            first_value_dicc_w1 == first_value_dicc_w2):\n            return True\n        return None\n\n    def is_isogram(self, s):\n        \"\"\"\n        Función para determinar si un texto tiene las letras repetidas\n        el mismo número de veces\n        \"\"\"\n        iso = False\n        new_s = s.replace(\" \", \"\").lower()\n        letters = []\n        for letter in new_s:\n            letters.append(letter) if letter not in letters else None\n        for item in letters:\n            if new_s.count(item) == new_s.count(letters[0]):\n                iso = True\n            else:\n                iso = False\n                break\n\n        return iso\n\n    def result(self):\n        \"\"\"\n        Método que devuelve el resultado del análisis realizado\n        \"\"\"\n        self.dicc_result = {\"ANÁLISIS COMPARANDO LAS PALABRAS\": \"\",\n        \"¿Son palíndromos la una de la otra?\": \"Si\"if self.are_palindrome() is True else \"No\",\n        \"¿Son anagramas la una de la otra?\": \"Si\" if self.are_anagram() is True else \"No\",\n        \"¿Son isogramas la una de la otra?\":\"Si\" if self.are_isogram() is True else \"No\",\n        \"\\nANÁLISIS INDIVIDUAL DE LAS PALABRAS\": \"\",\n        f\"¿{self.w1.capitalize()} es palíndromo?\":\n        \"Si\" if self.is_palindrome(self.w1) is True else \"No\",\n        f\"¿{self.w2.capitalize()} es palíndromo?\":\n        \"Si\" if self.is_palindrome(self.w2) is True else \"No\",\n        f\"¿{self.w1.capitalize()} es isograma?\": \"Si\" if self.is_isogram(self.w1) is True else \"No\",\n        f\"¿{self.w2.capitalize()} es isograma?\": \"Si\" if self.is_isogram(self.w2) is True else \"No\"}\n\n        print(f\"Las palabras a analizar son '{self.w1.capitalize()}' y '{self.w2.capitalize()}'\\n\")\n        for key, value in self.dicc_result.items():\n            print(key, value)\n\n# EJEMPLO\n\nanalisys = WordAnalisys(\"Abalaba\", \"Marta\")\nanalisys.result()\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/hectorio23.py",
    "content": "# Autor: Héctor Adàn\n# GitHub: https://github.com/hectorio23\n\n'''\nEJERCICIO:\nMuestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\nen tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n- Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n  conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n\nDIFICULTAD EXTRA (opcional):\nCrea un programa que analice dos palabras diferentes y realice comprobaciones\npara descubrir si son:\n- Palíndromos\n- Anagramas\n- Isogramas\n'''\n\ndef discover_type(value1, value2):\n    # Se guarda una variable local la cual sera modificada\n    # para posteriormente ser comparada con la segunda palabra.\n    # Se puede observar que se ordena de manera contraria\n    value_reverse = value1[::-1]\n\n    if value_reverse == value2:\n        return \"\\nLas palabras anteriormente insertadas forman en realidad un palíndromo\\n\\n\"\n    elif isograma(value1) and isograma(value2):\n        return \"\\nAmbas palabras son isogramas\\n\\n\"\n    elif isograma(value1) or isograma(value2):\n        return \"\\nUna de las palabras es un isograma\\n\\n\"\n    elif anagrama(value1, value2):\n        return \"\\nEs un anagrama\\n\\n\"\n\n    return \"\\nLas palabras proporcionadas no cumplen con las condiciones para ser un palíndromo, isograma o anagrama\\n\"\n\ndef isograma(palabra):\n    _tmp_ = \"\"\n    for item in palabra:\n        if item in _tmp_:\n            return False\n        _tmp_ += item\n    return True\n\ndef anagrama(palabra1, palabra2):\n    palabra1_sorted = sorted(palabra1)\n    palabra2_sorted = sorted(palabra2)\n\n    if len(palabra1) != len(palabra2) or palabra1_sorted != palabra2_sorted:\n        return False\n    return True\n\ndef main():\n    # Las siguientes variables almacenan las palabras\n    # insertadas por el usuario\n    value1 = input(\"Inserta la primera palabra: \")\n    value2 = input(\"Ahora inserta la segunda palabra: \")\n\n    cadena1 = \"Hola\"\n    cadena2 = \"Mundo\"\n\n    # Modifican la variable original transformando sus caracteres en minúsculas\n    value1 = value1.lower()\n    value2 = value2.lower()\n\n    # Se llama a la función discoverType, la cual devuelve una cadena dependiendo de\n    # si las palabras ingresadas por el usuario forman parte de un palíndromo, anagrama o isograma.\n    # Para lograr esto, se invocan otras funciones cuyo único propósito es verificar\n    # si las palabras cumplen con las especificaciones dadas.\n    print(discover_type(value1, value2))\n\n    # Concatenación de dos cadenas\n    concatenacion = cadena1 + \" \" + cadena2\n    print(f\"Concatenación: {concatenacion}\")\n\n    # Se elimina cualquier espacio de la cadena de caracteres\n    cadena_prueba = concatenacion.replace(\" \", \"\")\n    print(f\"Cadena sin espacios en blanco: {cadena_prueba}\")\n\n    # Obtención de la longitud de dos cadenas\n    print(f\"Longitud de la cadena 1: {len(cadena1)}\")\n    print(f\"Longitud de la cadena 2: {len(cadena2)}\")\n\n    # Acceso a caracteres individuales\n    print(f\"Primer caracter de la cadena 1: {cadena1[0]}\")\n    print(f\"Último caracter de la cadena 2: {cadena2[-1]}\")\n\n    # Comparación\n    if cadena1 == cadena2:\n        print(\"Las cadenas son iguales\")\n    else:\n        print(\"Las cadenas son diferentes\")\n\n    # Subcadena\n    subcadena = concatenacion[5:10]  # Extrae \"Mundo\"\n    print(f\"Subcadena: {subcadena}\")\n\n    # Búsqueda\n    buscar = \"Mundo\"\n    posicion = concatenacion.find(buscar)\n    if posicion != -1:\n        print(f\"La cadena '{buscar}' fue encontrada en la posición {posicion}\")\n    else:\n        print(f\"La cadena '{buscar}' no fue encontrada\")\n\n    # Modificación\n    concatenacion = concatenacion.replace(\"Mundo\", \"Universo\")\n    print(f\"Después de reemplazar 'Mundo' por 'Universo': {concatenacion}\")\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/hozlucas28.py",
    "content": "import re\n\n\"\"\"\n    String operations...\n\"\"\"\n\n# Get length of a string\nLENGTHSTR = len(\"Hello World!\")\nprint(\"Get length of a string: len(<STRING NAME>)\")\nprint(f'len(\"Hello World!\") --> {LENGTHSTR}')\n\n# Get char of a string\nCHAR = \"Hello World!\"[3]\nprint(\"\\nGet char of a string: <STRING NAME>[<INDEX OF THE CHAR>]\")\nprint(f'\"Hello World!\"[3] --> \"{CHAR}\"')\n\n# Get substring of a string\nSUBSTRING = \"Hello World!\"[3:8]\nprint(\"\\nGet substring of a string: <STRING NAME>[<START + 1>, <END>]\")\nprint(f'\"Hello World!\"[3:9] --> \"{SUBSTRING}\"')\n\n# String to uppercase\nUPPERCASESTR = \"Buenos Aires\".upper()\nprint(\"\\nString to uppercase: <STRING NAME>.uppercase()\")\nprint(f'\"Buenos Aires\".upper() --> \"{UPPERCASESTR}\"')\n\n# String to lowercase\nLOWERCASESTR = \"USA\".lower()\nprint(\"\\nString to lowercase: <STRING NAME>.lower()\")\nprint(f'\"USA\".lower() --> \"{LOWERCASESTR}\"')\n\n# Repeat a string\nREPEATEDSTR = \"Juana\" * 2\nprint(\"\\nRepeat a string: <STRING NAME> * <NUMBER OF REPEATS>\")\nprint(f'\"Juana\" * 2 --> \"{REPEATEDSTR}\"')\n\n# Concat two strings (first option)\nCONCATEDSTROPT01 = \"Lucas \" + \"Hoz\"\nprint(\n    \"\\nConcat two strings (first option): <FIRST STRING NAME> + <SECOND STRING NAME> + <'N' STRING NAME...>\"\n)\nprint(f'\"Lucas \" + \"Hoz\" --> \"{CONCATEDSTROPT01}\"')\n\n# Concat two strings (second option)\nCONCATEDSTROPT02 = \" \".join([\"Lucas\", \"Hoz\", \"-\", \"Argentina\"])\nprint(\n    \"\\nConcat two strings (second option): <SEPARATOR>.join([<FIRST STRING NAME>, <'N' STRING NAME...>])\"\n)\nprint(f'\" \".join([\"Lucas\", \"Hoz\", \"-\", \"Argentina\"]) --> \"{CONCATEDSTROPT02}\"')\n\n# Replace substring of a string\nREPLACEDSTR = \"Hello Python!\".replace(\"Python\", \"TypeScript\")\nprint(\n    \"\\nReplace substring of a string: <STRING NAME>.replace(<SUBSTRING TO SEARCH>, <NEW SUBSTRING>)\"\n)\nprint(f'\"Hello Python!\".replace(\"Python\", \"TypeScript\") --> \"{REPLACEDSTR}\"')\n\n# Compare start of a string\nCOMPARESTART = \"Lucas\".startswith(\"ho\")\nprint(\"\\nCompare start of a string: <STRING NAME>.startswith(<SUBSTRING TO FIND>)\")\nprint(f'\"Lucas\".startswith(\"ho\") --> {COMPARESTART}')\n\n# Compare end of a string\nCOMPAREEND = \"Lucas\".endswith(\"as\")\nprint(\"\\nCompare end of a string: <STRING NAME>.endswith(<SUBSTRING TO FIND>)\")\nprint(f'\"Lucas\".endswith(\"as\") --> {COMPAREEND}')\n\n# Check if a string includes a substring\nINCLUDES = \"Lucas\".find(\"c\")\nprint(\"\\nCheck if a string find a substring: <STRING NAME>.find(<SUBSTRING TO FIND>)\")\nprint(f'\"Lucas\".find(\"c\") --> {INCLUDES}')\n\n# Check if a string matches a regex\nREGEXSTR = re.match(r\"/[uca]/\", \"Lucas\")\nprint(\"\\nCheck if a string matches a regex: re.match(r<REGEX>, <STRING NAME>)\")\nprint(f're.match(r\"/[uca]/\", \"Lucas\") --> [{REGEXSTR}]')\n\n# Check if a string is equal to another string\nCOMMONCOMPARISON = \"Lucas\" == \"LuCaS\"\nprint(\n    \"\\nCheck if a string is equal to another string: <FIRST STRING NAME> == <SECOND STRING NAME>\"\n)\nprint(f'\"Lucas\" == \"LuCaS\" --> {COMMONCOMPARISON}')\n\n\nprint(\n    \"\\n# ---------------------------------------------------------------------------------- #\"\n)\n\n\"\"\"\n    Additional challenge... \n\"\"\"\n\n\ndef get_palindrome_words(words: list[str]) -> list[str]:\n    \"\"\"Get palindrome words\"\"\"\n    palindromes: list[str] = []\n\n    for word in words:\n        reversed_word: str = word[::-1]\n        if word == reversed_word:\n            palindromes.append(word)\n\n    return palindromes\n\n\ndef get_anagram_words(pair_of_words: list[list[str]]) -> list[list[str]]:\n    \"\"\"Get anagram words\"\"\"\n    anagrams: list[list[str]] = []\n\n    for words in pair_of_words:\n        [word_01, word_02] = words\n        longest_word: str = word_01 if (len(word_01) > len(word_02)) else word_02\n\n        are_anagrams: bool = True\n        unique_chars: set[str] = set(list(longest_word))\n\n        for char in longest_word:\n            if char in unique_chars:\n                continue\n            are_anagrams = False\n            break\n\n        if are_anagrams:\n            anagrams.append(words)\n\n    return anagrams\n\n\ndef get_isogram_words(words: list[str]) -> list[str]:\n    \"\"\"Get isogram words\"\"\"\n    isograms: list[str] = []\n\n    for word in words:\n        word_formatted = word.replace(\" \", \"\")\n        unique_chars = set(list(word_formatted))\n        if len(word_formatted) == len(unique_chars):\n            isograms.append(word)\n\n    return isograms\n\n\nARR01 = [\n    \"level\",\n    \"hello\",\n    \"racecar\",\n    \"world\",\n    \"madam\",\n    \"programming\",\n    \"deed\",\n    \"javascript\",\n]\nPALINDROMEWORDS = get_palindrome_words(ARR01)\nprint(f\"\\nPalindrome words of {ARR01} --> {PALINDROMEWORDS}\")\n\nARR02 = [\n    [\"listen\", \"silent\"],\n    [\"hello\", \"world\"],\n    [\"good\", \"dog\"],\n]\nANAGRAM_WORDS = get_anagram_words(ARR02)\nprint(f\"\\nAnagram words of {ARR02} --> {ANAGRAM_WORDS}\")\n\nARR03 = [\"hello\", \"world\", \"isogram\", \"javascript\", \"python\", \"algorithm\"]\nISOGRAM_WORDS = get_isogram_words(ARR03)\nprint(f\"\\nIsogram words of {ARR03} --> {ISOGRAM_WORDS}\")\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/iban99.py",
    "content": "#Suma\na = 'Miriam'\nb = 'Iban'\nc = \"Señor4\"\n\nprint(a + \" \" + b) #Concatenación\nprint(a*3) #Repetición\nprint(len(a)) #Len\nprint(a.upper()) #Mayúscula\nprint(a.lower()) #Minúscula\nprint(a.title()) #Las primeras letras todas en mayúscula\nprint(a.capitalize()) #Primera letra en mayúscula\nprint(a[1]) #Acceder a una posición - Indexación\nprint(a[1:3]) #Subcadena - Slicing - Porción\nprint(a.find(\"r\")) #Buscar posición\nprint(\"r\" in a) #True si está dentro de la cadena\nprint(a.count(\"i\")) #Contar letras/subcadenas\nprint(a.isalnum()) #True si son todos caracteres alfanuméricos\nprint(c.isalpha())#True si todos los cracteres son alfabéticos\nprint(c.isnumeric())#True si todos los cracteres son números\nprint(a.strip()) #Elimina el caracter que se le introduce \nprint(a.join([\"Hola \",b])) #Une caracteres\nl1=[a, \",\", b, \"Gil\"]\nprint(\" \".join(l1)) #Transformación de lista en cadena\nprint(\"Python,Java,C\".split(\",\")) #Separa por el caracter que se introduce\nprint(a.startswith(\"Mi\")) #Empieza por\nprint(a.endswith(\"im\")) #Termina por\nprint(a.split(\"r\")) #División\nprint(a.replace(\"i\", \"I\")) #Reemplazo\nprint(\"Nombre: {}, apellido: {}!\". format(a,b)) #Formateo\nprint(f\"Nombre: {a}, apellido: {b}!\") #Interpolación\nprint(list(a)) #Crear lista\n\n\nfor letra in a:\n    print(letra) #Recorrer\n    \nprint(a[1])\n\n\n#Extra\ndef palabras(palabra1, palabra2):\n    \n    #Palíndromas\n    print(f\"La palabra {palabra1} es palíndroma? {palabra1.lower() == palabra1[::-1].lower()}\")\n    print(f\"La palabra {palabra2} es palíndroma? {palabra2.lower() == palabra2[::-1].lower()}\")\n    \n    #Anagramas\n    print(f\"¿{palabra1} es anagrama de {palabra2}? : {sorted(palabra1) == sorted(palabra2)}\")\n    \n    #Isograma\n    print(f\"¿{palabra1} es un isograma? : {len(palabra1) == len(set(palabra1))}\")\n    print(f\"¿{palabra2} es un isograma? : {len(palabra2) == len(set(palabra2))}\")\n    \n    def isogram(word_string) -> bool:\n    \n        word_dict = dict()\n        for word in palabra2:\n            word_dict[word] = word_dict.get(word, 0) + 1\n        \n        isograma = True   \n        values = list(word_dict.values())\n        isogram_len = values[0]\n        for word_count in values:\n            if word_count != isogram_len:\n                isogram = False\n                break\n        return isograma\n        \n    print(f\"¿{palabra1} es un isograma? : {isogram(palabra1)}\")\n    print(f\"¿{palabra2} es un isograma? : {isogram(palabra2)}\")\n    \n    \npalabras(\"radar\", \"pythonpythonpythonpython\")\n#palabras(\"amor\", \"roma\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/idiegorojas.py",
    "content": "# Cadenas de Caracteres\n\n# Concatenacion\n# Unir dos o mas cadenas\ncadena_1 = 'Hola'\ncadena_2 = 'Mundo'\nresultado = cadena_1 + ' ' + cadena_2\nprint(resultado)\n\n# Repeticion\n# Repetir una cadena varias veces\ncadena = 'Python'\nresultado = cadena * 3\nprint(resultado)\n\n# Acceso a caracteres\n# Acceder a un caracter de la cadena mediante su indice\ncadena = 'Python'\nprint(cadena[0])\nprint(cadena[-1])\n\n# Subcadenas (slicing)\ncadena = 'Python'\nresultado = cadena[1:4]\nprint(resultado)\n\n# Longitud\ncadena = 'Python'\nlongitud = len(cadena)\nprint(longitud)\n\n# Busqueda se subcadenas\ncadena = 'Python es genial.'\nposicion = cadena.find('es')\nprint(posicion)\n\n# Reemplazar\ncadena = 'Python es genial.'\nnueva_Cadena = cadena.replace('genial', 'increible')\nprint(nueva_Cadena)\n\n# Division\ncadena = 'Python es genial.'\nlista = cadena.split(\" \")\nprint(lista)\n\n# Union\nlista = ['Python', 'es', 'genial.']\nunion = \" \".join(lista)\nprint(union)\n\n# Mayusculas y minusculas\ncadena = 'Python'\nmayuscula = cadena.upper()\nminuscula = cadena.lower()\nprint(mayuscula)\nprint(minuscula)\n\n# Eliminacion de espacios\n# Elimina espacios en blanco al inicio y al final de una cadena\ncadena = ' Python '\nlimpia = cadena.strip()\nprint(limpia)\n\n# Formateo de cadenas\nnombre = 'Python'\nversion = 3.12\nmensaje = f'{nombre} version {version}'\nprint(mensaje)\n\nmensaje = '{} version {}'.format(nombre, version)\nprint(mensaje)\n\n# comprobacion de prefijos y sufijos.\ncadena = 'Python es genial.'\nprint(cadena.startswith('Python'))\nprint(cadena.endswith('genial.'))\n\n# Conversion a lista de caracteres\ncadena = 'Python'\nlista = list(cadena)\nprint(lista)\n\n# Inversion de una cadena\ncadena = 'Python'\ninvertida = cadena[::-1]\nprint(invertida)\n\n# Comprobar contenido\ncadena = 'Python 3.12'\nprint(cadena.isalpha()) # False por que contiene numeros\nprint(cadena.isdigit()) # False por que contiene letras\nprint(cadena.isalnum()) # True por que contiene letras y numeros\n\n# Capitalizacion\ncadena = 'python es genial.'\ncapitalizar = cadena.capitalize()\nprint(capitalizar)\n\n# Conteo de subcadenas\ncadena = 'Python es genial, Python esta en la version 3.12'\nconteo = cadena.count('Python')\nprint(conteo)\n\n# Verificacion de espacios\ncadena = \" \"\nprint(cadena.isspace())\n\n# Interpolacion de cadenas\nnombre = 'Python'\nversion = 3.12\nmensaje = 'Lenguaje: %s, Version: %.1f'%(nombre, version)\nprint(mensaje)\n\n\n# Extra\ndef programa_palabras():\n    \n    palabra_1 = input('Por favor ingrese la primera palabra: ')\n    palabra_2 = input('Por favor ingrese la segunda palabra: ')\n\n    def limpiar_palabra(palabra):\n        return palabra.replace(\" \", \"\").lower()\n\n    palabra_1_limpia = limpiar_palabra(palabra_1)\n    palabra_2_limpia = limpiar_palabra(palabra_2)\n\n    def palindromo():\n        return palabra_1_limpia == palabra_2_limpia[::-1]\n\n    def anagrama():\n        return sorted(palabra_1_limpia) == sorted(palabra_2_limpia)\n\n    def isograma(palabra):\n        return len(palabra) == len(set(palabra))\n\n    if palindromo():\n        print(f'Las palabras \"{palabra_1}\" y \"{palabra_2}\" son palíndromos.')\n    else:\n        print(f'Las palabras \"{palabra_1}\" y \"{palabra_2}\" no son palíndromos.')\n\n    if anagrama():\n        print(f'Las palabras \"{palabra_1}\" y \"{palabra_2}\" son anagramas.')\n    else:\n        print(f'Las palabras \"{palabra_1}\" y \"{palabra_2}\" no son anagramas.')\n\n    if isograma(palabra_1_limpia) and isograma(palabra_2_limpia):\n        print(f'Las palabras \"{palabra_1}\" y \"{palabra_2}\" son isogramas.')\n    else:\n        print(f'Las palabras \"{palabra_1}\" y \"{palabra_2}\" no son isogramas.')\n\nprograma_palabras()"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/ignaciovihe.py",
    "content": "\"\"\"\nMuestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\nen tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n- Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n  conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n\"\"\"\n\n\"\"\"\nOperaciones de Cadenas de caracteres\n\"\"\"\n\n#Creación\n\nmy_string = 'Permite incluir comillas \"dobles\"'\nmy_other_string =\"Permite incluircomillas 'simples'\"\n#con comillas triple se incluyen todos los espacion y saltos de linea pudiendo formatear el texto.\nmy_new_string = \"\"\"\nOpciones:\n    1. Jugar\n    2. Opciones\n    3. Salir\n\"\"\"\n\nprint(my_new_string)\n\nprint(my_new_string[15]) #Acceso a un caracter especifico\nprint(my_new_string[15:23]) # Slicing de subcadenas\nprint(len(my_new_string)) # Longitud de cadena\n\nprint(my_new_string + my_string) # Concatenación de cadenas\nprint(my_string * 3) #Repeticion de cadenas\n\nfor char in my_new_string: #Recorrido de cadenas.\n    print(char)\n\nmy_string =\"mi Cadena en minusculas\"\nprint(my_string.upper()) #Convierte todo a mayusculas\nprint(my_string.capitalize()) # Convierte solo el primer caracter a mayusculas. Cuidado espacios al inicio.\nprint(my_string.lower()) #Conbierte todo a minusculas.\nprint(my_string.title()) # Convierte la primera letra de cada palabra en mayus.\n\ntexto1 = \"Straße\"  # \"Straße\" es \"calle\" en alemán\ntexto2 = \"STRASSE\"\nprint(texto1.lower())   # \"straße\"\nprint(texto1.casefold()) # \"strasse\" Convierte todo a minusculas de forma mas agresiva. ß --> ss\n\nmy_string= \" Texto con espacios inicial y final \" \nprint(my_string.strip()) # Elimina espacios al principio y al final.\n\nmy_new_string = \"\"\"\nOpciones:\n    1. Jugar\n    2. Opciones\n    3. Salir\n\"\"\"\n#Se reemplaza el primer parametro con el segundo. Crea una nueva cadena.\nmy_string = my_new_string.replace(\"Salir\", \"Cerrar\") \nprint(my_string)\n\nwords = my_new_string.split(\"\\n\") #División de cadenas\nprint(words)\n\npalabras = [\"Python\", \"es\", \"genial\"]\nresultado = \" \".join(palabras) # Union de cadenas con join\nprint(resultado)\n\nprint(resultado.find(\"es\")) #devuelve el indice de la primera aparicion de la cadena pasada dentro de otra\n\n#Interpolación\n\nname = \"Ignacio\"\nedad = 40\nprint(f\"Me llamo {name} y tengo {edad} años\") # con f-strings\nprint(\"Me llamo {} y tengo {} años\".format(name, edad)) # Con format.\n\n# Verificación\n\ntexto = \"Python es increíble\"\nprint(\"Python\" in texto)   #Verificacion de existencia\nprint(\"Java\" in texto) \nprint(\"Java\" not in texto) #Verificacion de no existencia.\n\narchivo = \"documento.pdf\"\nprint(archivo.startswith(\"doc\")) #Verificacion de prefijo\nprint(archivo.endswith(\".pdf\")) # Verificacion de sufijo\nprint(archivo.endswith(\".doc\"))\n\ncadena1 = \"12345\"\ncadena2 = \"Python\"\ncadena3 = \"Python123\"\ncadena4 = \" \"\ncadena5 = \"3.14\"\nprint(cadena1.isdigit())   # True (solo números)\nprint(cadena2.isalpha())   # True (solo letras)\nprint(cadena3.isalnum())   # True (letras y números)\nprint(cadena4.isspace())   # True (solo espacios)\nprint(cadena5.isnumeric()) # False porque tiene un punto\n\ntexto = \"HOLA\"\nprint(texto.isupper())  #Verificacion de mayusculas \ntexto = \"hola\"\nprint(texto.islower())  #Verificación de minusculas\n\n# Operaciones adicionales\n\ncadena = \"Python, Java , Python, c#\"\nprint(cadena.count(\"Python\")) #Cuenta las ocurrencias de una cadena dentro de otra.\nprint(cadena.find(\"Java\")) # Devuelve el index de la primera ocurrencia de la cadena pasada en otra. -1 si no esta.\nprint(cadena.ljust(50, \"-\"))\nprint(cadena.rjust(50, \"-\"))\nnew_str = cadena.center(50,\"_\") #centrado de cadenas\nprint(new_str)\n\n\nprint(f\"2 == 2.0: {2 == 2.0}\")\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\"\"\"\n\ndef check(word_1: str, word_2: str):\n\n\n    def is_isogramm(word: str) -> bool:\n        counter_dict = {letter: word.count(letter) for letter in word}\n        if len(set(counter_dict.values())) != 1:\n            return False\n        return True\n    \n\n    #Palindromo\n    print(f\"{word_1} es un palíndromo?: {word_1 == word_1[::-1]}\")\n    print(f\"{word_2} es un palíndromo?: {word_2 == word_2[::-1]}\")\n\n\n    #Anagrama\n    print(f\"{word_1} y {word_2} son anagramas?: {sorted(word_1) == sorted(word_2)}\")\n\n\n    #Isograma\n    print(f\"{word_1} es un isograma?: {is_isogramm(word_1)}\")\n    print(f\"{word_2} es un isograma?: {is_isogramm(word_2)}\")\n\ncheck(\"radar\", \"murcielagomurcielago\")\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/inmortalnight.py",
    "content": "# 04 - Cadenas de caracteres \n\n# Cadenas de caracteres y operaciones\n\ncadena = \"Hola Mundo\"\nprint(\"Mi cadena: \" + cadena)\nprint(\"Primer caracter: \" + cadena[0] + \" - Ultimo caracter: \" + cadena[-1])\nprint(\"Subcadena: \" + cadena[0:4])\nprint(\"Longitud de la cadena: \" + str(len(cadena)))\nprint(\"Concatenación: \" + cadena + \" desde Python\")\nprint(\"Repetición: \" + (cadena + \" \")* 3)\nprint(\"Recorrido:\")\nfor caracter in cadena:\n    print(caracter)\nprint(\"Mayúsculas: \" + cadena.upper())\nprint(\"Minúsculas: \" + cadena.lower())\nprint(\"Reemplazo: \" + cadena.replace(\"Mundo\", \"Universo\"))\nprint(\"División: \" + str(cadena.split(\" \")))\nprint(\"Unión: \" + \" \".join([\"Hola\", \"Mundo\"]))\ncadena1 = \"casa!\"\nprint(\"Interpolación: \" + f\"{cadena} desde {cadena1}\")\nprint(\"Verificación: \" + str(cadena.startswith(\"Hola\")))\nprint(\"Verificación: \" + str(cadena.endswith(\"Mundo\")))\nprint(\"Busqueda: \" + str(cadena.find(\"Mundo\")))\nprint(\"Comparación: \" + str(cadena == \"Hola Mundo\"))\n\n\n# EXTRA: Análisis de palabras\n\n# Palíndromo: Palabra o frase que se lee igual de izquierda a derecha que de derecha a izquierda.\ndef es_palindromo(palabra):\n    return palabra == palabra[::-1]\n\n# Anagrama: Palabra o frase que resulta de la transposición de letras de otra palabra o frase.\ndef es_anagrama(palabra1, palabra2):\n    return sorted(palabra1) == sorted(palabra2)\n\n# Isograma: Palabra que no tiene letras repetidas.\ndef es_isograma(palabra):\n    return len(palabra) == len(set(palabra))\n\nprint(\"\\n-----Análisis de palabras-----\")\nprint(\"Nota: las comparaciones dan prioridad a la primera palabra.\")\npalabra1 = input(\"Ingrese una palabra: \")\npalabra2 = input(\"Ingrese otra palabra: \")\nprint(f\"¿Es palíndromo?: {es_palindromo(palabra1)}\")\nprint(f\"¿Es anagrama?: {es_anagrama(palabra1, palabra2)}\")\nprint(f\"¿Es isograma?: {es_isograma(palabra1)}\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/ipfabio.py",
    "content": "\"\"\"\nOperaciones\n\"\"\"\ns1 = \"Hola\"\ns2 = \"mundo\"\n\n# Concatenación\nprint(s1 + \", \" + s2 + \"!\")\n\n# Repetición\nprint(s1 * 3)\n\n# Indexación\nprint(s1[0] + s1[1] + s1[2] + s1[3])\n\n# Longitud\nprint(len(s2))\n\n# Slicing (porción)\nprint(s2[2:6])\nprint(s2[2:]) # Hasta el fin\nprint(s2[:2]) # Desde el principio\nprint(s2[0:2]) # Desde el principio\n\n# Busqueda\nprint(\"a\" in s1)\nprint(\"i\" in s1)\n\n# Reemplazo\nprint(s1.replace(\"o\", \"a\"))\n\n# División\nprint(s2.split(\"n\"))\n\n# Mayúsculas y minúsculas y primera letra en mayúsculas\nprint(s1.upper())\nprint(s1.lower())\nprint(\"atila eluno\".title())\nprint(\"atila eluno\".capitalize())\n\n# Eliminación de espacios al principio y al final\nprint(\" atila eluno \".strip())\n\n# Búsqueda al principio y al final\nprint(s1.startswith(\"Ho\"))\nprint(s1.startswith(\"Py\"))\nprint(s1.endswith(\"la\"))\nprint(s1.endswith(\"thon\"))\n\n# Búsqueda de posición\ns3 = \"Atila Eluno @atieluno\"\nprint(s3.find(\"ati\"))\nprint(s3.find(\"Elu\"))\nprint(s3.find(\"E\"))\nprint(s3.lower().find(\"a\"))\n\n# Búsqueda de ocurrencias\nprint(s3.lower().count(\"a\"))\n\n# Formateo\nprint(\"Saludo: {}, lenguaje: {}\".format(s1, s2))\n\n# Interpolación\nprint(f\"Saludo: {s1}, lenguaje: {s2}\")\n\n# Transformación en lista de caracteres\nprint(list(s3))\n\n# Tranformación de lista en cadena\nl1 = [s1, \", \", s2, \"!\"]\nprint(\"\".join(l1))\n\n# Tranformaciónes númericas\ns4 = \"123456\"\ns4 = int(s4)\nprint(s4)\n\ns4 = \"123456.123\"\ns4 = float(s4)\nprint(s4)\n\n# Comprobaciónes varias\ns4 = \"123456\"\nprint(s1.isalnum())\nprint(s1.isalpha())\nprint(s4.isalpha())\nprint(s4.isnumeric())\n\n\"\"\"\nExtra\n\"\"\"\nprint(\"-- Extra --\\n\")\ndef imprimir_resultado(titulo: str, function, *args):\n    print(\"\")\n    print(titulo)\n    function(*args)\n\ndef palindromo(*words: str):\n    for word in words:\n        palindromo = word == word[::1]\n        print(f\"¿{word} es palindromo?: {palindromo}\")\n\ndef anagrama(w1, w2):\n    anagrama = sorted(w1) == sorted(w2)\n    print(f\"¿{w1} y {w2} son anagramas?: {anagrama}\")\n\ndef isograma(*words: str):\n    for word in words:\n        word_dict = dict()\n    \n        for w in word:\n            word_dict[w] = word_dict.get(w, 0) + 1\n\n        isogram = True\n        for w_count in word_dict.values():\n            if w_count > 1:\n                isogram = False\n                break\n        print(f\"¿{word} es un isograma?: {isogram}\")\n\n\n\ndef check(word1: str, word2: str):\n    imprimir_resultado(\"Verificando Palíndromo:\", palindromo, word1, word2)\n    imprimir_resultado(\"Verificando Anagrama:\", anagrama, word1, word2)\n    imprimir_resultado(\"Verificando Isograma:\", isograma, word1, word2)\n    \n\nif __name__ == \"__main__\":\n    word1 = input(\"Ingresa la palabra a verificar: \")\n    word2 = input(\"Ingresa la palabra a verificar: \")\n    \n    check(word1, word2)\n    \n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/isilanes.py",
    "content": "import re\n\n\ndef main():\n    string = \"This is a String\"\n    other = \"Another String\"\n\n    print(f\"s == '{string}'\")\n\n    print(\"\\nAcceso al caracter enésimo:\")\n    print(f\"s[3] == '{string[3]}'\")\n\n    print(\"\\nAcceso al último caracter:\")\n    print(f\"s[-1] == '{string[-1]}'\")\n\n    print(\"\\nAcceso a subcadena:\")\n    print(f\"s[5:7] == '{string[5:7]}'\")\n\n    print(\"\\nCálculo de longitud:\")\n    print(f\"len(s) == {len(string)}\")\n\n    print(\"\\nConcatenación de dos cadenas:\")\n    print(f\"o == '{other}'\")\n    print(f\"s + ':' + o == '{string+':'+other}' <- inefficient, don't use\")\n    print(f\"':'.join([s, o]) == '{':'.join([string, other])}' <- proper way\")\n    print(f\"f'{{s}}:{{o}}' == '{string}:{other}' <- also good way\")\n\n    print(\"\\nRepetición de cadena:\")\n    print(f\"s*3 == '{string*3}'\")\n    print(f\"':'.join([s]*3) == '{':'.join([string]*3)}'\")\n\n    print(\"\\nRecorremos los 3 primeros caracteres:\")\n    print(\"for c in s[:3]:\\n    print(c)\")\n    for c in string[:3]:\n        print(c)\n\n    print(\"\\nConversión a mayúsculas:\")\n    print(f\"s.upper() == '{string.upper()}'\")\n\n    print(\"\\nConversión a minúsculas:\")\n    print(f\"s.lower() == '{string.lower()}'\")\n\n    print(\"\\nReemplazar partes de una cadena es imposible, puesto que en Python las cadenas son inmutables.\")\n    print(\"Para lograr una modificación, tendremos que crear otra cadena, que equivalga a la primera modificada.\")\n    print(f\"s.replace('s', 'J') == {string.replace('s', 'J')}\")\n\n    print(\"\\nDivisión de una cadena:\")\n    print(f\"s.split('is') == {string.split('is')}\")\n\n    print(\"\\nLa interpolación de cadenas puede hacerse de varias maneras. La mejor son los f-strings:\")\n    print(\"Nótese que coerce variables de tipo no cadena, a cadena (p.e. el entero 666 a continuación)\")\n    print(\"nombre = 'Iñaki'\")\n    print(\"edad = 666\")\n    name, age_years = \"Iñaki\", 666\n    print('f\"Me llamo {nombre}, y mi edad es {edad} años\" ==', f\"'Me llamo {name} y mi edad es {age_years} años'\")\n\n    print(\"\\nA una cadena se le pueden hacer muchas verificaciones.\")\n    print(\"Supongamos que queremos verificar que una cadena contiene un código ISO de nación, seguido\")\n    print(\"de cuatro cifras (ni más ni menos), separados ambos grupos por un guión:\")\n    print(\"patt = re.compile(r'^[A-Z]{2}-\\d{4}$')\")\n    patt = re.compile(r'^[A-Z]{2}-\\d{4}$')\n    print(\"patt.match('ES-1234') ==\", patt.match(\"ES-1234\"))\n    print(\"patt.match('es-1234') ==\", patt.match(\"es-1234\"))\n    print(\"patt.match('ES-123') ==\", patt.match(\"ES-123\"))\n    print(\"patt.match('ES-12345') ==\", patt.match(\"ES-12345\"))\n    print(\"patt.match('ES 1234') ==\", patt.match(\"ES 1234\"))\n\n\ndef extra():\n\n    print(\"\\nDificultad extra:\")\n\n    def is_word(word: str) -> bool:\n        \"\"\"\n        Returns True if 'word' is a word (only contains letters). False, otherwise.\n        Only strings of len > 0 will be considered.\n\n        Args:\n            word (str):\n                String that we want to check.\n\n        Returns:\n            Boolean. Whether input is a word or not.\n        \"\"\"\n        if not isinstance(word, str):\n            return False\n\n        patt = re.compile(r\"^[a-z]+$\", re.IGNORECASE)\n\n        return patt.match(word) is not None\n\n    def is_palindrome(word: str) -> bool:\n        \"\"\"\n        Returns True if 'word' is a word, and it is a palindrome.\n\n        Args:\n            word (str):\n                Word to check whether it is a palindrome.\n\n        Returns:\n            True if input word is a palindrome, False otherwise.\n        \"\"\"\n        if not is_word(word):\n            return False\n\n        word = word.lower()  # just in case, ignore capitalization\n\n        return word == word[::-1]\n\n    def are_anagrams(word_a: str, word_b: str) -> bool:\n        \"\"\"\n        Returns True if 'word_a' and 'word_b' are words, and an anagram\n        of each other.\n\n        Args:\n            word_a (str):\n                First word of pair to check.\n            word_b (str):\n                Second word of pair to check.\n\n        Returns:\n            True if both input words are anagrams of each other, False otherwise.\n        \"\"\"\n        if not is_word(word_a) or not is_word(word_b):\n            return False\n\n        word_a = word_a.lower()  # just in case, ignore capitalization\n        word_b = word_b.lower()\n\n        return sorted(word_a) == sorted(word_b)\n\n    def order_of_isogram(word: str) -> int | None:\n        \"\"\"\n        Return the order of isogram 'word' constitutes. If 'word' is not an isogram,\n        then return None.\n\n        An isogram is defined as a word where each distinct letter appears the same amount\n        of times. The amount of repetitions of each letter is the order. For example 'intestinos'\n        is an isogram of order 2.\n\n        Args:\n            word (str):\n                Word for which we want to calculate the isogram order.\n\n        Returns:\n            An integer representing the isogram order of the input word. If the input word\n            is not an isogram, return None.\n        \"\"\"\n        if not is_word(word):\n            return None\n\n        count = {}\n        for letter in word:\n            count[letter] = count.get(letter, 0) + 1\n\n        orders = set(count.values())\n\n        return None if len(orders) > 1 else list(orders)[0]\n\n    print(\"is_word('abc') ==\", is_word(\"abc\"))\n    print(\"is_word('a bc') ==\", is_word(\"a bc\"))\n    print(\"is_word('aCbc') ==\", is_word(\"aCbc\"))\n    print(\"is_word('aC1c') ==\", is_word(\"aC1c\"))\n    print(\"is_word('aC,c') ==\", is_word(\"aC,c\"))\n    print(\"is_palindrome('abc') ==\", is_palindrome(\"abc\"))\n    print(\"is_palindrome('abba') ==\", is_palindrome(\"abba\"))\n    print(\"are_anagrams('abba', 'baba') ==\", are_anagrams(\"abba\", \"baba\"))\n    print(\"are_anagrams('perro', 'gato') ==\", are_anagrams(\"perro\", \"gato\"))\n    print(\"are_anagrams('Tokyo', 'Kyoto') ==\", are_anagrams(\"Tokyo\", \"Kyoto\"))\n    for word in (\n        \"perro\",\n        \"intestinos\",\n        \"gato\",\n        \"papelera\",\n        \"baba\",\n        \"cuscus\",\n    ):\n        order = order_of_isogram(word)\n        if order is None:\n            print(f\"La palabra '{word}' no es un isograma.\")\n        else:\n            print(f\"La palabra '{word}' es un isograma de orden {order}.\")\n\n\nif __name__ == \"__main__\":\n    main()\n    extra()\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/ivangdev.py",
    "content": "# ---------------- Cadenas de caracteres ---------------------\n# Acesso a caracteres\ntexto = \"Hola Ivan\"\nprint(texto[0])\nprint(texto[-1])\n\n# Subcadenas\nprint(texto[0:4])  # Desde el indice 0 hasta el 3\nprint(texto[5:])  # Desde el indice 5 hasta el final\nprint(texto[:4])  # Desde el inicio 0 hasta el 3\nprint(texto[::2])  # Uno si, uno no\n\n# Longuitud\nprint(len(texto))\n\n# Concatenacion\nnombre = \"Ivan\"\napellido = \"Guerrero\"\nprint(nombre + \" \" + apellido)\n\n# Repeticion\nprint(\"ivan\" * 4)\n\n# Recorrido\nfor letra in texto:\n    print(letra)\n\n# Mayuscula\nprint(texto.upper())\nprint(texto.lower())\nprint(texto.title())\nprint(texto.capitalize())\n\n# Reemplazo\nprint(texto.replace(\"Ivan\", \"Mundo\"))\n\n# Division y union\nprint(texto.split(\" \"))  # Division\nprint(\"-\".join(texto))  # Union\n\n# Interpolacion\nedad = 25\nprint(f\"Me llamo {nombre} y tengo {edad}\")  # f-string\nprint(\"Me llamo {} y tengo {}\".format(nombre, edad))  # format\n\n# Verificacion\nprint(\"123\".isdigit())  # True -> solo numeros\nprint(\"abc\".isalpha())  # True -> solo letras\nprint(\"abc123\".isalnum())  # True -> solo letras y numeros\nprint(\"       \".isspace())  # True -> solo espacios\nprint(\"hola\".startswith(\"ho\"))  # True\nprint(\"Hola\".endswith(\"la\"))  # True\n\n# Eliminar espacios\nespacios = \"          prueba            \"\nprint(espacios.strip())  # 'prueba'\nprint(espacios.lstrip())  # 'prueba    '\nprint(espacios.rstrip())  # '      prueba'\n\n# Buscar\nprint(texto.find(\"Ivan\"))  # 5 -> posicion\nprint(texto.find(\"Raul\"))  # -1 -> no encontrado\nprint(\"Mundo\" in texto)  # False\nprint(\"Python\" not in texto)  # True\n\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n#  * para descubrir si son:\n#  * - Palíndromos\n#  * - Anagramas\n#  * - Isogramas\n\n\ndef analizarPalabra(palabra1, palabra2):\n    if palabra1 == palabra1[::-1]:\n        print(f\"{palabra1}: Es palindromo\")\n    else:\n        print(f\"{palabra1}: No es palindromo\")\n\n    if palabra2 == palabra2[::-1]:\n        print(f\"{palabra2}: Es palindromo\")\n    else:\n        print(f\"{palabra2}: No es palindromo\")\n\n    # palabra_1 = list(palabra1)\n    # palabra_2 = list(palabra2)\n\n    if len(palabra1) != len(palabra2):\n        print(\"No son anagramas\")\n\n    anagrama = {}\n    for letra in palabra1:\n        if letra in anagrama:\n            anagrama[letra] += 1\n        else:\n            anagrama[letra] = 1\n\n    anagrama2 = {}\n    for letra in palabra2:\n        if letra in anagrama2:\n            anagrama2[letra] += 1\n        else:\n            anagrama2[letra] = 1\n\n    if anagrama == anagrama2:\n        print(f\"Las palabras {palabra1} y {palabra2}: son anagrama\")\n    else:\n        print(f\"Las palabras {palabra1} y {palabra2}: no son anagrama\")\n\n    cantidadLetras = {}\n    for letra in palabra1:\n        if letra in cantidadLetras:\n            cantidadLetras[letra] += 1\n        else:\n            cantidadLetras[letra] = 1\n    cantidad = list(cantidadLetras.values())\n\n    cantidadLetras2 = {}\n    for letra in palabra2:\n        if letra in cantidadLetras2:\n            cantidadLetras2[letra] += 1\n        else:\n            cantidadLetras2[letra] = 1\n    cantidad2 = list(cantidadLetras2.values())\n\n    if min(cantidad) == max(cantidad) and min(cantidad2) == max(cantidad2):\n        print(\n            f\"Las palabras {palabra1} y {palabra2}: Es isograma {cantidad} {cantidad2}\"\n        )\n    else:\n        print(f\"Las palabras {palabra1} y {palabra2}: no son isograma\")\n\n\nanalizarPalabra(\"mama\", \"abab\")\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/javierfiestasbotella.py",
    "content": "'''\nEJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas'''\n\n def multi(w1,w2):\n    valor=0\n    if w1==w2[::-1]:\n        print(w2[::-1],w1)\n        print('son palindromas.')\n    w1_1=sorted(w1)\n    w2_2=sorted(w2)\n    if w1_1==w2_2:\n        print('son anagramas')\n    for i in range(1,len(w1)):\n      print(w1[i],w1[:i])\n      if w1[i] in w1[:i]:\n        valor+=1\n    if valor ==0:\n      print(f'{w1} es un isograma')"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/javierjoyera.py",
    "content": "#Acceso a carácteres específicos de una cadena, se hace mediante la posición del carácter en la cadena, empezando por 0.\nmy_string = \"Mi cadena de caracteres\"\nprint(my_string[5])\n\n'''\nAcceso a un rango de carácteres de una cadena, \nse hace mediante la posición del primer carácter del rango y la posición del último carácter del rango, \nseparados por dos puntos. '''\nmy_substring = my_string[3:10] #Desde la posición 3 hasta la 10, sin incluir la 10.\nprint(my_substring) \n\n#Longitud de una cadena\nmy_len = len(my_string)\nprint(my_len)\n\n#Concatenación de cadenas\nmy_string_1 = \"Soy\"\nmy_string_2 = \" una cadena\"\nmy_string_3 = \" de caracteres\"\nmy_string_4 = \" concatenada\"\n\nmy_concatenated_string = my_string_1 + my_string_2 + my_string_3 + my_string_4\nprint(my_concatenated_string)\n\n#Repetición de cadenas\nmy_repeated_string = my_string_1 * 3\nprint(my_repeated_string)\n\n#Recorrer una cadena con un bucle for\nmy_for_string = \"Recorriendo una cadena con un bucle for\"\nfor character in my_for_string:\n    print(character)\n\n#Convertir una cadena a mayusculas\nmy_upper_string = my_string.upper()\nprint(my_upper_string)\n\n#Convertir una cadena a minusculas\nmy_lower_string = my_string.lower()\nprint(my_lower_string)\n\n#Convertir una cadena a mayusculas la primera letra de cada palabra\nmy_title_string = my_string.title()\nprint(my_title_string)\n\n#Reemplazar una cadena por otra\nmy_replaced_string = my_string.replace(\"cadena\", \"frase\")\nprint(my_replaced_string)\n\n#Dividir una cadena en una lista de subcadenas con un delimitador \nmy_split_string = my_string.split(\" \")\nprint(my_split_string)\n\n#Union de una lista de subcadenas en una cadena con un delimitador\nmy_words = [\"Mi\", \"cadena\", \"de\", \"caracteres\"]\nmy_joined_string = \" \".join(my_words)\nprint(my_joined_string)\n\n#Interpolación de variables en una cadena\nmy_name = \"Javier\"\nmy_age = 27\nmy_interpolated_string = f\"Me llamo {my_name} y tengo {my_age} años.\"\nprint(my_interpolated_string)\n\n#Interpolación de variables en una cadena con formato\nmy_name = \"Javier\"\nmy_age = 27\nmy_interpolated_string = \"Me llamo {} y tengo {} años.\".format(my_name, my_age)\n\n#Interpolación de variables en una cadena con formato y posición\nmy_name = \"Javier\"\nmy_age = 27\nmy_interpolated_string = \"Me llamo {1} y tengo {0} años.\".format(my_age, my_name)\n\n#Interpolación de variables en una cadena con formato y nombre [Preferible para mi]\nmy_name = \"Javier\"\nmy_age = 27\nmy_interpolated_string = \"Me llamo {name} y tengo {age} años.\".format(age=my_age, name=my_name)\n\n#Verificación de cadenas\nmy_number = \"192304\"\nprint(my_number.isnumeric()) \nprint(my_number.isdigit()) \n\nmy_string = \"Iphone\"\nprint(my_string.isalpha())\nprint(my_string.isalnum()) \nprint(my_string.startswith(\"Z\")) \nprint(my_string.endswith(\"e\")) \nprint(my_string.islower()) \nprint(my_string.isupper()) \nprint(my_string.isspace()) #Comprueba si la cadena contiene solo espacios en blanco\n\n#Busqueda de subcadenas\nmy_string = \"Mi cadena de caracteres de python\"\nprint(my_string.find(\"de\")) #Devuelve la posición de la primera coincidencia en la cadena\nprint(my_string.rfind(\"de\")) #Devuelve la posición de la última coincidencia en la cadena\nprint(my_string.count(\"e\")) #Devuelve el número de veces que se repite el valor buscado\n\n#modificacion de cadena eliminando espacios\nmy_string = \"   Mi cadena de caracteres de python   \"\nprint(my_string.strip()) #Elimina los espacios al principio y al final de la cadena\nprint(my_string.rstrip()) #Elimina los espacios al final de la cadena\nprint(my_string.lstrip()) #Elimina los espacios al principio de la cadena\n\nmy_new_string = \"esta cadena empieza en minúscula\"\nprint(my_new_string.capitalize()) #Pone la primera letra en mayúscula\n\nprint(\"--------------------\")\nprint(\"Ejercicio Opcional\")\nprint(\"--------------------\")\n\n#Ejercicio opcional\n'''\nPalindromo: Es una palabra o frase que se lee igual de izquierda a derecha que de derecha a izquierda.\nAnagrama: Es una palabra o frase que tiene las mismas letras que otra, pero en diferente orden.\nIsograma: Es una palabra o frase que no tiene letras repetidas.\n\n\nProcedimiento:\n- Crear las funciones para cada uno de los tres tipos\n- Pedirle al usuario una cadena de caracteres\n- Llamar a las tres funciones con la cadena de caracteres\n- Mostrar por pantalla el resultado de cada función\n'''\n\ndef es_palindromo(palabra):\n    palabra = palabra.lower().replace(\" \", \"\")\n    return palabra == palabra[::-1] #Compara la palabra con la palabra invertida\n\ndef es_anagrama(palabra1, palabra2):\n    palabra1 = palabra1.lower().replace(\" \", \"\")\n    palabra2 = palabra2.lower().replace(\" \", \"\")\n    return sorted(palabra1) == sorted(palabra2) #Compara las dos palabras ordenadas\n\ndef es_isograma(palabra):\n    palabra = palabra.lower().replace(\" \", \"\")\n    return len(set(palabra)) == len(palabra) #Compara la longitud de la palabra con la longitud de la palabra sin caracteres repetidos\n\n#Pedimos al usuario la entrada de las palabras\npalabra1 = input(\"Introduce la primera palabra: \")\npalabra2 = input(\"Introduce la segunda palabra: \")\n\n#Llamamos a las funciones y mostramos el resultado\nprint(\"La palabra %s ¿Es palindromo?: %s\" % (palabra1, es_palindromo(palabra1)))\nprint(\"La palabra %s ¿Es palindromo?: %s\" % (palabra2, es_palindromo(palabra2)))\nprint(\"La palabra %s ¿Es anagrama de %s?: %s\" % (palabra1, palabra2, es_anagrama(palabra1, palabra2)))\nprint(\"La palabra %s ¿Es isograma?: %s\" % (palabra1, es_isograma(palabra1)))\nprint(\"La palabra %s ¿Es isograma?: %s\" % (palabra2, es_isograma(palabra2)))\n\n\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/javitron100.py",
    "content": "# 04 - CADENAS DE CARACTERES\r\n\r\nmi_cadena = \"Hola mi nombre es Javier, estoy aprendiendo Python con retos de programación\"\r\n\r\nprint(mi_cadena[3])\r\nprint(mi_cadena[0:4])\r\nprint(\"Longitud de la cadena: \" + str(len(mi_cadena)))\r\nprint(mi_cadena * 3)\r\n\r\nfor caracter in mi_cadena:\r\n    print(caracter)\r\n\r\nprint(mi_cadena.upper())\r\nprint(mi_cadena.lower())\r\nprint(mi_cadena.capitalize())\r\n\r\nprint(mi_cadena.replace(\"javier\", \"Javier\"))\r\n\r\nmi_lista = mi_cadena.split(\" \")\r\nprint(mi_lista)\r\nprint(type(mi_lista))\r\ntexto=\"\"\r\nfor i in mi_lista:\r\n     texto = texto + i + \" \"\r\nprint(texto)\r\n\r\nlenguaje = \"Python\"\r\nprint(f\"Hola {lenguaje}!\")\r\n\r\nif lenguaje == \"Python\":\r\n     print(\"El lenguaje es Python\")\r\n\r\nmi_cadena = \"AAAAAaaaaa\"\r\nif mi_cadena.isalpha():\r\n     print(\"Cadena contiene sólo caracteres\")\r\n\r\nmi_cadena = \"12345\"\r\nif mi_cadena.isnumeric():\r\n     print(\"Cadena contiene sólo números\")\r\n    \r\n\r\n\"\"\"\r\nDIFICULTAD EXTRA (opcional):\r\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\r\n * para descubrir si son:\r\n * - Palíndromos\r\n * - Anagramas\r\n * - Isogramas\r\n\"\"\"\r\nprimera_palabra = \"\"\r\nsegunda_palabra = \"\"\r\n\r\nwhile primera_palabra == segunda_palabra:\r\n    print(\"Introduce dos palabras, tienen que ser distintas\")\r\n    primera_palabra = input(\"Primera palabra: \")\r\n    segunda_palabra = input(\"Segunda palabra: \")\r\n\r\n\r\nif primera_palabra == segunda_palabra[::-1]:\r\n     print(\"Palindromos\")\r\n\r\nif ''.join(sorted(primera_palabra)) == ''.join(sorted(segunda_palabra)):\r\n     print(\"Anagramas\")\r\n\r\nisograma = True\r\nfor letra in primera_palabra:\r\n     if primera_palabra.count(letra) > 1:\r\n          isograma = False\r\n\r\nif isograma: print(\"La primera palabra es un isograma\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/jcdm60.py",
    "content": "# #04 CADENAS DE CARACTERES\n#### Dificultad: Media | Publicación: 22/01/24 | Corrección: 29/01/24\n\n## Ejercicio\n\n\n# EJERCICIO:\n# Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n# en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n# - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n#   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n#\n# DIFICULTAD EXTRA (opcional):\n# Crea un programa que analice dos palabras diferentes y realice comprobaciones\n# para descubrir si son:\n# - Palíndromos\n# - Anagramas\n# - Isogramas\n#\n\n# Acceso a caracteres específicos\ncadena = \"Hola, mundo!\"\nprimer_caracter = cadena[0]\nultimo_caracter = cadena[-1]\n\nprint(f\"Primer caracter: {primer_caracter}\")\nprint(f\"Último caracter: {ultimo_caracter}\")\n\n# Subcadenas\nsubcadena = cadena[6:11]  # Extrae desde el índice 6 hasta el 10 (sin incluir el 11)\nprint(f\"Subcadena: {subcadena}\")\n\n# Longitud de una cadena\nlongitud = len(cadena)\nprint(f\"Longitud de la cadena: {longitud}\")\n\n# Concatenación\notra_cadena = \" ¡Bienvenido!\"\nconcatenada = cadena + otra_cadena\nprint(f\"Concatenación: {concatenada}\")\n\n# Repetición\nrepetida = cadena * 3\nprint(f\"Repetición: {repetida}\")\n\n# Recorrido de caracteres\nfor caracter in cadena:\n    print(caracter, end=' ')\n\n# Conversión a mayúsculas y minúsculas\nmayusculas = cadena.upper()\nminusculas = cadena.lower()\nprint(f\"\\nMayúsculas: {mayusculas}\")\nprint(f\"Minúsculas: {minusculas}\")\n\n# Reemplazo\nreemplazada = cadena.replace(\"mundo\", \"Python\")\nprint(f\"Reemplazo: {reemplazada}\")\n\n# División\ndividida = cadena.split(\",\")  # Divide la cadena en una lista usando la coma como separador\nprint(f\"División: {dividida}\")\n\n# Unión\nunida = '-'.join(dividida)  # Une los elementos de la lista con '-' como separador\nprint(f\"Unión: {unida}\")\n\n# Interpolación de cadenas (formato de f-strings)\nnombre = \"Juan\"\nedad = 63\nmensaje = f\"Hola, me llamo {nombre} y tengo {edad} años.\"\nprint(mensaje)\n\n# Verificación\ninicio_con_hola = cadena.startswith(\"Hola\")\ntermina_con_exclamacion = cadena.endswith(\"!\")\n\nprint(f\"Inicia con 'Hola': {inicio_con_hola}\")\nprint(f\"Termina con '!': {termina_con_exclamacion}\")\n\n\n# DIFICULTAD EXTRA\ndef es_palindromo(palabra):\n    palabra = palabra.lower()\n    return palabra == palabra[::-1]\n\ndef es_anagrama(palabra1, palabra2):\n    palabra1 = palabra1.lower()\n    palabra2 = palabra2.lower()\n    return sorted(palabra1) == sorted(palabra2)\n\ndef es_isograma(palabra):\n    palabra = palabra.lower()\n    return len(set(palabra)) == len(palabra)\n\ndef main():\n    palabra_palindromo = input(\"Ingrese una palabra para verificar si es un palíndromo: \")\n    if es_palindromo(palabra_palindromo):\n        print(f\"{palabra_palindromo} es un palíndromo.\")\n    else:\n        print(f\"{palabra_palindromo} no es un palíndromo.\")\n\n    palabra_anagrama1 = input(\"Ingrese la primera palabra para verificar si es un anagrama: \")\n    palabra_anagrama2 = input(\"Ingrese la segunda palabra para verificar si es un anagrama: \")\n    if es_anagrama(palabra_anagrama1, palabra_anagrama2):\n        print(f\"{palabra_anagrama1} y {palabra_anagrama2} son anagramas.\")\n    else:\n        print(f\"{palabra_anagrama1} y {palabra_anagrama2} no son anagramas.\")\n\n    palabra_isograma = input(\"Ingrese una palabra para verificar si es un isograma: \")\n    if es_isograma(palabra_isograma):\n        print(f\"{palabra_isograma} es un isograma.\")\n    else:\n        print(f\"{palabra_isograma} no es un isograma.\")\n\nif __name__ == \"__main__\":\n    main()\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/jesusgdev.py",
    "content": "\"\"\"\n#04\nCADENAS DE CARACTERES\n/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\n *   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\n *   interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\"\"\"\n\n'''\nOperaciones con Strings\n'''\n\nmessage = \"Esto es una cadena de texto\"\nname = \"Jesus\"\nage = 30\n\n# 1. Acceso a una ubicacion o indice especifico dentro de una cadena de texto (indices)\n# Devuelve el caracter indicado dentro de una cadena de texto especifica.\n\nprint(message[0])   # E (Primer caracter ubicado en el indice 0)\nprint(message[8])   # u (Octavo caracter unbicado en el indice 8)\nprint(message[-1])  # o (Ultimo caracter de la cadena ya que el los indices negativos reccoren la cadena a la inversa)\n\n\n# 2 Subcadenas (slicing)\n# Extrae una parte de una cadena usando rangos.\n\nprint(message[0:7])    # Esto es (desde el indice 0 hasta el indice 7, sin incluir el 7)\nprint(message[8:])    # una cadena de texto (desde el indice 8 hasta el final)\nprint(message[:11])    # Esto es una (desde el inicio hasta el indice 11, sin incluir el indice 11)\n\n# 3. Longitud de cadena (len)\n# Devuelve el tamaño o numero de caracteres de la cadena.\n\nprint(len(message))    # 27\n\n# 4. Concatenacion de cadenas (+)\n# Une dos cadenas de texto\n\ngreet = \"Hello\" + name\nprint(greet)    # Hello Jesus\n\n# 5. Repeticion de cadenas\n# Devuelve la cadena varias veces\n\nprint(\"Hello \" * 4)    # Hello Hello Hello Hello\n\n# 6. Recorrido de una cadena (con bucles)\n# Recorre cada caracter de la cadena de texto con un ciclo for y lo imprime\n\nfor char in name:\n    print(char)\n\n# 7. Mayusculas y minusculas\n# Cambia el formato del texto\n\nprint(name.upper())    # JESUS (todo en mayusculas)\nprint(name.lower())    # jesus (todo en minusculas)\nprint(name.capitalize())    # Jesus (primera en mayusculas)\n\n# 8. Reemplazo de texto\n# Cambia una parte del texto por otra\n\nprint(greet.replace(\"Jesus\", \"Python\"))    # Hola Python\n\n# 9. Division (split)\n# Dividir un texto por palabras o separadores.\n# Ideal para convertir textos en listas.\n\nprint(message.split(\" \"))    # ['Esto', 'es', 'una', 'cadena', 'de', 'texto']\n\n# 10. Transformacion en lista de caracteres\n# Separa cada caracter dentro de la cadena y los devuelve en una lista\nprint(list(name))    # ['J', 'e', 's', 'u', 's']\n\n# 11. Union (join)\n# Unir elementos de una lista en una sola cadena.\n\nList = ['Esta', 'es', 'una', 'lista']\nprint(\" \".join(List))    # Esta es una lista\n\n# 12. Interpolacion (Insercion de variables de texto)\n# Dos formas modernas de insertar variables en cadenas:\n\n# a. Usando f-strings:\nprint(f\"Me llamo {name} y tengo {age} años\")    # Me llamo Jesus y tengo 30 años\n\n# b. Usando format():\nprint(\"Me llamo {} y tengo {} años\".format(name, age))    # Me llamo Jesus y tengo 30 años\n\n# 13. Verificacion o busqueda\n\n# a. Devuelve True si una cadena contiene una palabra especifica\nprint(\"cadena\" in message)    # True\n\n# b. Devuelve True si una cadena empieza con una palabra especifica\nprint(message.startswith(\"Esta\"))    # True\n\n# c. Devuelve True si una cadena termina con una palabra especifica\nprint(message.endswith(\"texto\"))    # True\n\n# d. Devuelve True si la cadena es alfanumerica \nprint(\"Hi5\".isalnum())    # True (Debe ser una cadena continua sin espacios)\n\n# e. Devuelve True si contiene solo numeros\nprint(\"2025\".isdigit())    # True (Debe ser una cadena continua sin espacios)\n\n# f. Devuelve True si contiene solo letras\nprint(\"Texto\".isalpha())    # True (Debe ser una cadena continua sin espacios)\n\n# 14. Eliminar espacios\nwith_spaces = \" Cadena con espacios \"\n\n# a. Elimina los espacios al principio y al final de la cadena\nprint(with_spaces.strip())    # \"Cadena con espacios\"\n\n# b. Elimina los espacios al inicio\nprint(with_spaces.lstrip())    # \"Cadena con espacios \"\n\n# c. Elimina los espacios al final\nprint(with_spaces.rstrip())    # \" Cadena con espacios\"\n\n# 15. Contar apariciones\nfruit = \"banana\"\n\nprint(fruit.count(\"a\"))    # 3 (Devuelve la cantidad de apariciones de un caracter especifico dentro de una cadena de texto)\n\n# 16. Encontrar posicion de algo\nprint(\"Python\".find(\"h\"))    # 3 (Devuelve el indice de la posicion del caracter indicado en la busqueda)\nprint(\"Python\".find(\"r\"))    # -1 (Devuelve -1 si no hay ninguna coincidencia)\n\n# 17. Transformaciones o casting\nprint(type(age))    # <class 'int'>\nage_str = str(age)\nprint(type(age_str))    # <class 'str'>\n\n'''\nExtra\n'''\n\ndef word_comparator():\n\n    while True:\n\n        print(\"\")\n        print(\"COMPARADOR DE PALABRAS\")\n        print(\"1. Palindromo\")\n        print(\"2. Anagrama\")\n        print(\"3. Isograma\")\n        print(\"4. Salir\")\n\n        option = input(\"\\nSelecciona una opcion: \")\n\n        match option:\n            case \"1\":\n                word = input(\"Introduzca una palabra: \")\n\n                if word == word[::-1]:\n                    print(f\"\\nLa palabra {word} es un palindromo!\")\n                else:\n                    print(f\"\\nLa palabra {word} no es un palindromo!\")\n\n                \n            case \"2\":\n                word1 = input(\"Introduzca la primera palabra: \")\n                word2 = input(\"Introduzca la segunda palabra: \")\n                word3 = word2\n\n                for char in word1:\n                    word3 = word3.replace(char, \"\")\n\n                if len(word3) == 0:\n                    print(f\"\\nLa palabra {word1} es un Anagrama de {word2}!\")\n                    \n                else:\n                    print(f\"\\nLa palabra {word1} no es un Anagrama de {word2}!\")\n                    \n            \n            case \"3\":\n                word = input(\"Introduzca una palabra: \")\n                char_count = []\n\n                for char in word:\n                    char_count.append(word.count(char))\n\n                if len(set(char_count)) == 1:\n                    print(f\"\\nLa palabra {word} es un Isograma!\")\n                    \n                else:\n                    print(f\"\\nLa palabra {word} no es un Isograma!\")\n            \n            case \"4\":\n                print(\"Gracias por usar el comparador de palabras!\")\n                break\n\n            case _:\n                print(\"\\n Opcion invalida. Intenta de nuevo\")\n\nword_comparator()           "
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/jesusway69.py",
    "content": "import os\nos.system('cls')\nfrom itertools import permutations\nimport re\nfrom unicodedata import normalize\n\"\"\"\n* EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\n *   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\n *   interpolación, verificación...\"\"\"\n\nprint(\"MÉTODOS Y MANIPULACIONES BÁSICAS CON STRINGS\")\nmy_string = \"Hola PYTHON\"\nprint (\"\\\"Hola Python\\\"\")\n#Para imprimir con comillas o caracteres reservados se usa backslash antes del caracter\n\nprint(r\"c:\\users\\usuario\\carpeta\\archivo.txt\")\n#Si queremos imprimir un string que incluya backslash formateamos con una r (raw string)\n\nprint(\"Ho\" + \"la Py\" + \"thon\") \n#Concatenación de varios strings\n\nprint (\"Ding! \" * 5)\n #Python admite multiplicaciones de strings\n\nprint (str(len(\"123456789\")) + \" caracteres\")\n #La función len() devuelve medida en int, str castea a string y + concatena\n\nprint(len(\"123456789\") * 9)\n# La función len() devuelve cantidad de caracteres y se puede operar con el número resultante\n\nprint(my_string.find(\"THON\"))\n# .find devuelve el índice donde comienza la subcadena especificada\n\nprint(my_string.replace(\"PYTHON\",\"JAVASCRIPT\"))\n# .replace sustituye la parte del string especificada por otra especificada\n\nprint(my_string.capitalize())\n# .capitalize devuelve el string con el primer caracter en mayúsculas y el resto en minúsculas\n\nprint(my_string.upper())\n# .upper devuelve todo el string en mayúsculas\n\nprint(my_string.lower())\n# .lower devuelve todo el string en minúsculas\n\nprint(my_string.swapcase())\n# .swapcase cambia los caracteres en minúsculas por mayúsculas y viceversa\n\nprint(my_string[2:8])\n#Deja sólo los caraceteres dentro del rango, el resto los borra(en este caso borra los 0,1,9,10 y 11)\n\nprint(my_string[:8])\n#En caso de omitir el primer valor equevale a 0 y solo borra a partir del valor especificado\n\nlista_caracteres_ascii = [72,111,108,97,32,80,121,116,104,111,110]\n#lista con los códigos ascii de \"Hola Python\"\n\n[print(chr(i) , end='') for i in lista_caracteres_ascii]\n#Con la función chr() obtenemos el caracter asociado a su código ascii\n\nprint('')\n[print(my_string[i] , end='') for i in range(len(my_string))]\n#Se pueden recorrer los caracteres de un string con un bucle for por índice \n\n\nprint('')\n[print(my_string[i] , end='') for i, char in enumerate(my_string)]\n#Tambien con un bucle for por índice usando la función enumerate()\n\nprint('')\n[print(char , end='') for char in my_string]\n#Se pueden recorrer los caracteres de un string con un bucle foreach sin índice\n\nprint('')\nprint(\"abracadabra\".count(\"bra\"))\n#El método .count devuelve la cantidad de veces que se repite un substring\n\nprint(\"  Hola Python  \".strip())\n#El método .strip elimina los espacios que haya al principio y al final de un string\n\nprint(\"1001\".zfill(8))\n#Con .zfill rellenamos con ceros a la izqda el string pasándole el nº total de caracteres\n\nprint(my_string.split(\"HO\"))\n# .split devuelve una lista con las subcadenas divididas por el caracter especificado (que se elimina)\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos clean_words diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagrams\n * - Isograms\"\"\"\n\ndef remove_diacritic (string)->str:\n  string = str(string)\n  string = re.sub(\n        r\"([^n\\u0300-\\u036f]|n(?!\\u0303(?![\\u0300-\\u036f])))[\\u0300-\\u036f]+\", r\"\\1\", \n        normalize( \"NFD\", string), 0, re.I\n    )\n  string = normalize( 'NFC', string)\n#Borra los símbolos diacríticos excepto la ñ y la diéresis\n  return string.lower().replace(' ', '')\n\n\n\n\n\n\ndef anagram (word1,word2):\n    clean_word1, clean_word2 = remove_diacritic(word1), remove_diacritic(word2)\n    list1, list2 = list(clean_word1), list(clean_word2)  \n    list1.sort()\n    list2.sort()\n    sorted1, sorted2 = \"\".join(list1), \"\".join(list2)\n    if sorted1 == sorted2:\n        print(f\"Las palabras {word1} y {word2} son anagramas\")\n    else:\n      print(f\"Las palabras {word1} y {word2} no son anagramas\")\n\nanagram(\"Fotolitografía\", \"Litofotografía\")\n\n\n\n\ndef isogram (word1,word2):\n char_dict = {}\n clean_word = remove_diacritic(word1)+remove_diacritic(word2)\n for char in clean_word:\n   if char in char_dict:     \n      char_dict[char] +=1\n   else:\n      char_dict[char] =1\n \n char_set = set(char_dict.values())\n if len(char_set) > 1:\n   print(f\"Las palabras {word1} y {word2} concatenadas no son un isograma\")\n else:\n   print(f\"Las palabras {word1} y {word2} concatenadas son un isograma\")\n print(\"nº de veces que se repite cada letra:\") \n [print(\"\\n\",char, count , end = ' : ') for char, count in char_dict.items()] \n\nisogram (\"paz\" , \"porrazo\")\n\n\ndef palindrome (string1, string2):\n  string = remove_diacritic(str((string1+string2)))\n  reverse = string[::-1]\n  if string == reverse:\n    print (f\"La frase formada por \\\" {string1}\\\" y \\\"{string2}\\\" forman un palíndromo\")\n  else:\n    print (f\"La frase formada por \\\" {string1}\\\" y \\\"{string2}\\\"  no forman un palíndromo\")\n\npalindrome(\"Arriba\" , \"la birra\")\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/jgutierrez9891.py",
    "content": "# Operadores de cadenas\n\n\"\"\"\nConcatenar\n\"\"\"\n\nnombre = \"John \"\napellido = \"Gutierrez\"\n\nprint (f\"Mi nombre completo es: {nombre + apellido}\")\n\n\"\"\"\nRepetición\n\"\"\"\n\nperros = \"perro\"\ngatos = \"gato\"\npajaros = \"pajaro\"\n\nprint(f\"{perros*3} {gatos*2} {pajaros*4}\")\n\n\n\"\"\"\nAñadir\n\"\"\"\n\nmensaje = \"Hola\"\nmensaje += \" \"\nmensaje += \"\\nBuenos días\"\n\nprint(mensaje)\n\n\n# Métodos para cadenas\n\nmensaje = \"Este texto contiene un mensaje oculto\"\nprint(mensaje[1] + mensaje[3] + mensaje[13] + mensaje[15] + mensaje[20] + mensaje[21])\n\notorrino = str(len(\"otorrinolaringólogo\"))\nprint(f\"El animal más dificil de pronunciar tiene {otorrino} letras\")    # Longitud\n\nmensaje = \"Ayúdame a encontrar a Javier\"\nprint(f\"Javier se encuentra en la posición {mensaje.find('Javier')}\")    # Encontrar\n\nmensaje = \"EsTe eS uN mEnSaJe eN mInÚsCuLa\"                              # Minúscula\nprint(mensaje.lower())\n\nmensaje = \"EsTe eS uN mEnSaJe eN mAyÚsCuLa\"                              # Mayúscula\nprint(mensaje.upper())\n\nmensaje = \"El animal más fuerte es el león\"\nprint (mensaje.replace('león','tigre'))                                  # Reemplazar\n\nmensaje = \"Esto contiene un perromensaje escondido\"                      # Cortar\nprint(mensaje[17:22])\n\nmensaje = \"hola\"                                                         # Primera letra de la cadena en mayúscula\nprint(mensaje.capitalize())\n\nmensaje = \"EsTe eS uN nUeVo mEnSaJe\"                                     # Invierta mayúsculas y minúsculas\nprint(mensaje.swapcase())\n\nmensaje = \"El hombre de camisa cafe le ofreció un cafe a la mujer de ojos color cafe\"\nprint(f\"La frase tiene {mensaje.count('cafe')} veces la palabra cafe\")   # Contar las veces que existe una cadena dentro de otra\n\nmensaje = \"Mas información al correo prueba@mailinator.com\"\nprint (f\"Esta cadena contiene solo caracteres alfanuméricos? {mensaje.isalnum()}\")\n\nmensaje = \"ABCDEfghijk\"\nprint (f\"Esta cadena contiene solo caracteres alfabéticos? {mensaje.isalpha()}\")\n\nmensaje = \"aEliminar los caracteres indeseadosv \"\nprint(mensaje.strip(\"av \"))                                               # Elimina los caracteres introducidos al comienzo y final\n\nmensaje = \"27340374\"\nprint(mensaje.zfill(10))                                                 # Completa con ceros a la izquierda hasta la cantidad indicada\n\n\n\"\"\"\nExtra\n\"\"\"\n\ndef sonAnagramas(palabra1, palabra2):\n    print (sorted(palabra1))\n    if sorted(palabra1.lower()) == sorted(palabra2.lower()):\n        return True\n    else:\n        return False\n    \ndef esIsograma(palabra):\n    contador = palabra.count(palabra[0])\n    for i in range(0, int(len(palabra))):\n        letra = palabra[i]\n        if palabra.count(letra) != contador:\n            return False\n    return True\n\ndef revisarPalabras(palabra1, palabra2):\n\n    print(f\"La palabra {palabra1} es palíndroma? {palabra1 == palabra1[::-1]}\")\n    print(f\"La palabra {palabra2} es palíndroma? {palabra2 == palabra2[::-1]}\")\n\n    print(f\"Las palabras {palabra1} y {palabra2} son anagramas? {sonAnagramas(palabra1, palabra2)}\")\n\n    isograma = esIsograma(palabra1)\n    print(f\"La palabra {palabra1} es un isograma? {isograma}\")\n    isograma = esIsograma(palabra2)\n    print(f\"La palabra {palabra2} es un isograma? {isograma}\")\n\nrevisarPalabras(\"amorr\", \"romaroma\")\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/jhoshmc.py",
    "content": "\n#! operaciones con cadenas \n\n\ndef operaciones_con_cadenas():\n  print(\"--- concatenar cadenas de caractes ------\")\n  texto1= \"hola\"\n  texto2=\" como esta?\"\n  print(f\"concatenados: {texto1+texto2}\")\n  print(\"---- reemplazar cadenas con otra --------------\")\n  \"\"\"\n  * el metodo es replace(), su sintaxis es: replace(old, new, coutn )\n  * old: es la cadena sub cadena que se va a reemplazar\n  * new: es la subcadena con la que se va a reemplazar\n  * coutn: (opcional), el el número de ocurrencias de la subcadena old  se desee reemplazar\n  \"\"\"\n  mensaje= \"hola mundo, me gusta programar en javascript, porque javascript es un buen lenguaje\"\n  mensaje_python= mensaje.replace(\"javascript\",\"python\",1)\n  #* solo reemplazara el primer javascript\n  print(mensaje_python)\n  #* reemplazara todas las ocurrencias\n  mensaje_python= mensaje.replace(\"javascript\",\"python\")\n  print(mensaje_python)\n  #? ordenar cadednas de caracteres\n  print(\"--------- ordenar las cadenas -------------\")\n  raw = \"hola\"\n  ordenada = \"\".join(sorted(raw)) # sorted, es como sort en c++, javascript\n  print(ordenada)\n\n  print(\"----- minucula lower()--------------\")\n  texto3= \"MAMA MIA\"\n  print(f\"original: {texto3} , en minuscula: {texto3.lower()}\")\n\n  print(\"------- texto en mayuscula upper()-------------\")\n  texto4=\"awesome!\"\n  print(f\"original: {texto4} , en mayuscula: {texto4.upper()}\")\n\n  print(\"----------- eliminar espacios en blanco usando .join y split()\")\n  texto5= \"h o l a\"\n  print(f\"texto original: {texto5}, sin espacios: {\"\".join(texto5.split())}\")\n\n  print(\"---- voltear un string ------------------\")\n  #* notacion de rebanado (string) con un paso negativo\n  cadena = \"Hola\"\n  cadena_volteada = cadena[::-1]\n  print(cadena_volteada)\n  #* utilizando la funcion reversed(), devuelve un iterador inverso de la cadena, \n  #* luego uniendolo con join()\n  cadena_volteada = \"\".join(reversed(cadena))\n  print(cadena_volteada)\n\n\noperaciones_con_cadenas()\n\n#! ejercicio extra\n\ndef palindromo(palabra)->bool:\n  reverso= palabra[::-1]\n  return reverso == palabra\n\ndef isograma(palabra)->bool:\n  \n  for i in range(len(palabra)-1):\n    for j in range(i+1,len(palabra)):\n      if palabra[i] == palabra[j]:\n        return False\n  return True        \n\ndef anagrama(palabra1,palabra2)->bool:\n  if len(palabra1) != len(palabra2):\n    return False\n  palabra1=\"\".join(sorted(palabra1))\n  palabra2=\"\".join(sorted(palabra2))\n  if palabra1 == palabra2:\n    return True\n  \n  \ndef ejercicio_exta():\n  palabra1= input(\"ingrese el la primera palabra: \")\n  palabra2= input(\"ingrese la segunda palabra: \")\n  compacto1= \"\".join(palabra1.split())\n  compacto2=\"\".join(palabra2.split())\n  respuesta1=palindromo(compacto1)\n  respuesta2=palindromo(compacto2)\n\n  if respuesta1:\n    print(f\"la palabra {palabra1} es un palindromo\")\n  else:\n    respuesta1= isograma(compacto1)\n    if respuesta1:\n      print(f\"la palabra {palabra1} es un isograma\")\n\n  if respuesta2:\n    print(f\"la palabra {palabra2} es un palindromo\")\n  else:\n    respuesta2= isograma(compacto2)\n    if respuesta2:\n      print(f\"la palabra: {palabra2} es un isograma\")\n  respuesta3=anagrama(compacto1,compacto2)\n  if respuesta3:\n    print(f\"la palabra: {palabra1} y la plabra: {palabra2}, conforman un anagrama\")    \n    \n\nejercicio_exta()\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/jorgeadamowicz.py",
    "content": "### cadena de caracteres ###\n\n#operaciones:\nmy_string = \"hola, \"\nmy_other_string = \"Python!\"\n\n#concatenación:\n\nmy_add_string = my_string + my_other_string\nprint(my_add_string)\n#tambien se pueden concatenar variables con caracteres, espacios, etc. \nprint(my_string + \" \" + my_other_string + \"!\" )\n\n# repetición o multiplicación:\n\nprint(my_add_string * 2)\n\n#indexación o desempaquetado\n\nmy_string = \"Python\"\nprint(my_string[1])\n\n###Funciones del sistema###\n\n#longitud de la cadena de texto\n\nmy_length = len(my_string) \nprint(my_length)\n\n#Slicing (porción)\n\nprint(my_add_string[6:-1])# la opción sin colocar nada en el segundo indice tambien es válido \nprint(my_add_string[6:])\nprint(my_add_string[::-1]) # invierte la palabra al imprimirla desde el final al principio. \n\n#busqueda\n\nprint(\"Py\" in my_add_string)\n\n#Metodo\n#reemplazo: \n\nprint(my_string.replace(\"o\", \"a\"))\n\n#division: \nprint(my_add_string.split(\" \"))\n\n# mayusculas y minusculas\n\nprint(my_add_string.capitalize())#convierte a mayuscula la primer letra de la cadena de texto a mayusculas\nprint(my_add_string.title())#convierte la primera letra de cada palabra de la cadena de texto a mayusculas\nprint(my_string.upper())#convierte todas las letras a mayusculas\nprint(my_string.lower())#convierte todas las letras a minusculas\n\n#eliminacion de espacios al principio y final de la cadena de texto\n\nprint(my_add_string.strip())\n\n#busqueda al principio o final\nprint(my_string.startswith(\"ho\"))\nprint(my_string.endswith(\"a\"))\n\n#busqueda de posición\n\nprint(my_add_string.find(\"thon\"))\n\n#busqueda de ocurrencia o conteo\n\nprint(my_add_string.count(\"o\"))\n\n#formateo\n\nprint(\"Saludo: {},  lenguaje: {}\".format(my_string, my_other_string))\n\n#interpolación: f string (interpretará que todo lo que esta entre{} hace referencia a una variable)\n\nprint(f\"saludo: {my_string} lenguaje: {my_other_string}\")\n\n#tranformacion en lista de caracteres:\nprint(list(my_add_string))\n\n#transformación metodo join\nprint(\" \".join(my_add_string))\n\n\n\n###Extra###\n\n#quitar espacios y pasar a minusculas: ok\ndef limpiar_palabra (word:str)-> str:\n    return word.replace(\" \", \"\").lower()\n    \n#función palindromo: \ndef check_palindromo(word:str)-> bool:\n    clean_word = limpiar_palabra(word)\n    invert_word = clean_word[::-1] # invierte la palabra utilizando slicing:    \n    return clean_word == invert_word #comprobación\n        \n#función anagrama: con retorno \ndef check_anagrama(word_1:str, word_2:str)-> bool:\n    clean_word_1 = limpiar_palabra(word_1)\n    clean_word_2 = limpiar_palabra(word_2)\n   \n    #comprobación:\n    return sorted(clean_word_1) == sorted(clean_word_2)\n\n        \n#funcion isograma:con conteo\ndef check_isograma(word):\n    for i in word:\n        conteo = word.count(i)\n        if conteo != 1:\n            return False\n    return True \n      \n          \n\n### main:###\nword_1 = input(\"ingrese una palabra\\n\")\nword_2 = input(\"ingrese otra palabra\\n\")\n\n#comprobación palindromo:\nres_pal = check_palindromo(word_1)\nprint(f\"la palabra {word_1} {'es ' if res_pal else 'no es '} palindromo \")\nres_pal = check_palindromo(word_2)\nprint(f\"la palabra {word_2} {'es ' if res_pal else 'no es '} palindromo \")\n\n#comprobación anagrama:\nres_ana = check_anagrama(word_1, word_2)\nprint(f\"la palabra {word_1} y {word_2} {'son' if res_ana else 'no son '} anagramas.\")\n\n#comprobación isograma:\nres_isograma= check_isograma(word_1)\nprint(f\"la palabra {word_1} {'es ' if res_isograma else 'no es '} isograma \") \nres_isograma= check_isograma(word_2)\nprint(f\"la palabra {word_2} {'es ' if res_isograma else 'no es '} isograma \") \n\n\n\n\"\"\"\n#Notas de lo aprendido:\n1) se debe llamar a la función por cada palabra a ser analizada\n2) para retotno booleano no es necesario utilizar comprobación if/else\n3) operadores ternario if/else se pueden utilizar en un f-string para decidir qué texto incluir basado en una condición.\n4) iograma: otra forma es convertir los elementos de la \"palabra\" ingresada en un set y comparar la longitud (cantidad de elementos)\nentre \"palabra\" original y  set(palabra). len(palabra)==len(set(palabra))    \n5) un set guarda sólo los elementos únicos (sin repeticiones) eje: set(palabra)-> len(p,l,a,b,r) -> 5 elementos\nmientras que len(palabra) -> 7 elemntos\n\"\"\""
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/jose-larss.py",
    "content": "\"\"\"\nCadena de Caracteres\n\"\"\"\ncadena1 = \"Esto es una cadena de caracteres o string\"\ncadena2 = \"cadena 2\"\n\n# Acceso a caracteres específicos\nif 'e' in cadena1:\n    print(\"hay e\")\nprint('o' in cadena1)\n# Subcadenas\n\n# Longitud\nprint(f\"La longitud de la cadene es: {len(cadena1)}\")\n\n# Concatenación\ncadena3 = cadena1 + cadena2\nprint(f\"La concatenación de la cadena 1 mas la cadena2 es: {cadena3}\")\n\n# Repetición\nprint(f\"La repeticion es {cadena1 * 3}\")\n\n# Indexación\nprint(cadena1[0] + cadena1[5] + cadena2[0] + cadena2[5])\n\n# Slicing (Porción)\nprint(cadena1[2:6])\n\n# Recorrido\nfor letra in cadena1:\n    print(letra)\n\n# Conversión a mayúsculas y Minúsculas\nprint(cadena1.upper()) # mayúsculas\nprint(cadena1.lower()) # minúsculas\nprint(cadena1.capitalize())\nprint(cadena1.title())\n\n# Reemplazo\nprint(cadena1.replace('o', 'a'))\n\n# División\nprint(cadena1.split(\" \"))\n\n# Eliminación de espacios al principio y al final\nprint(\" brais moure \".strip())\n\n# Búsqueda al principio y al final\nprint(cadena1.startswith(\"Ho\"))\nprint(cadena1.startswith(\"Py\"))\nprint(cadena1.endswith(\"la\"))\nprint(cadena1.endswith(\"thon\"))\n\ns3 = \"Brais Moure @mouredev\"\n\n# Búsqueda de posición\nprint(s3.find(\"moure\"))\nprint(s3.find(\"Moure\"))\nprint(s3.find(\"M\"))\nprint(s3.lower().find(\"m\"))\n\n# Interpolación\nprint(f\"Saludo: {cadena1}, lenguje: {cadena2}!\")\n\n# Formateo\nprint(\"Saludo: {}, lenguaje: {}!\".format(cadena1, cadena2))\n\n# Verificación\n\n# Tranformación en lista de caracteres\nprint(list(cadena2))\n\n# Transformación de lista en cadena\nl1 = [cadena1, \", \", cadena2, \"!\"]\nprint(\"\".join(l1))\n\n# Transformaciones numéricas\ns4 = \"123456\"\ns4 = int(s4)\nprint(s4)\n\ns5 = \"123456.123\"\ns5 = float(s5)\nprint(s5)\n\n# Comprobaciones varias\ns4 = \"123456\"\nprint(cadena1.isalnum())\nprint(cadena2.isalpha())\nprint(s4.isalpha())\nprint(s4.isnumeric())\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\"\"\"\ndef check(word1: str, word2: str):\n    print(word1)\n    print(word1[::-1])\n    print(sorted(word1))\n    print(sorted(word2))\n    # Palíndromos\n    print(f\"¿{word1} es un palíndromo?: {word1 == word1[::-1]}\")\n    print(f\"¿{word2} es un palíndromo?: {word2 == word2[::-1]}\")\n\n    # Anagramas\n    print(f\"¿{word1} es anagrama de {word2}?: {sorted(word1) == sorted(word2)}\")\n\n    # Isogramas\n\n    def isogram(word: str) -> bool:\n\n        word_dict = dict()\n        for character in word:\n            if character in word_dict:\n                word_dict[character] += 1\n                word_dict.get()\n            else:\n                word_dict[character] = 1\n            #word_dict[character] = word_dict.get(character, 0) + 1\n        print(word_dict)\n        isogram = True\n        values = list(word_dict.values())\n        isogram_len = values[0]\n        for word_count in values:\n            if word_count != isogram_len:\n                isogram = False\n                break\n\n        return isogram\n    \n    print(f\"¿{word1} es un isograma?: {isogram(word1)}\")\n    print(f\"¿{word2} es un isograma?: {isogram(word2)}\")\n\n\ncheck(\"radar\", \"pythonpythonpythonpython\")\n#check(\"amor\", \"roma\")\n#check(\"cara\", \"arca\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/josecox13.py",
    "content": "x = 8\nx = str(x) #conversión a string\n\nx = 'Pedro es desarrollador'\nprint(x[6]) #acceso al 7º valor, se empieza a numerar en 0\nprint(x[-2]) #acceso al 2º carácter empezando por el final\nname = x[0:5] #creación de subcadena de 5 carácteres\nlongitud = len(x) #longitud de la cadena\n\n\nx = 'La luna '\ny = 'sale durante las noches'\nfrase = x + y   #concatenación\nprint(frase)\nprint('luna' in frase) #pertenencia de un elemento\n\nrepeticion = frase * 3 #repeticion\nprint(repeticion)\n\n# Recorrido\ncontador = 0\nfor caracter in frase:\n    if caracter in {'a','e','i','o','u'}:\n        contador += 1\nprint(contador)\n\nfrase_may = frase.upper() #Mayúsculas\nprint (frase_may)\nfrase_min = frase.lower() #Minúsculas\nprint(frase_min)\nfrase_cambio = frase.swapcase() #Cambio de mayúsculas a minúsculas y viceversa\nprint(frase_cambio)\nfrase_frase = frase.capitalize() #Convierte la primera letra en mayúscula\nprint(frase_frase)\nfrase_titulo = frase.title() #Convierte la primera letra de cada palabra en mayúscula\nprint(frase_titulo)\n\n\n#Dividir una cadena\npalabras = frase.split(' ') #entre parénthesis se pone el separador\nprint(palabras) #devolverá una lista con las palabras separadas\n\ntexto = '3 + 4'\nseparacion = texto.partition('+') #devolverá una tupla con la cadena separada en 3 partes\nprint(separacion)\n\n#Limpiar cadenas\nserial_number = '\\n\\t    \\n 48374983274832 \\n \\n\\t \\n\\t'\n#La función strip() elimina los espacios en blanco al principio y al final de la cadena\ncadena_limpia = serial_number.strip()\nprint(cadena_limpia)\n#También se puede especificar el carácter a eliminar\ncadena_limpia = serial_number.strip('\\n')\nprint(cadena_limpia)\n\n#Reemplazar\ncadena = 'Hola, soy Juan'\ncadena = cadena.replace('Juan','Pedro')\nprint(cadena)\n\n#Unión\nseparador = ','\nlista = ['a','b','c']\ncadena = separador.join(lista)\nprint(cadena)\n\n#Separación\nseparada = list(cadena)\nprint(separada)\n\n#Conversión a número\nnum_str  = '123'\nnum = int(num_str)\nprint(num)\nnum_float = '123.45'\nnum = float(num_float)\nprint(num)\n\n#Interpolación\nnombre = 'Juan'\nedad = 25\ncadena = f'Hola, me llamo {nombre} y tengo {edad} años'\n\n\n\n#Verificación\ncadena = '12345'\nprint(cadena.isnumeric()) #devuelve True si todos los caracteres son numéricos\nprint(cadena.isalpha()) #devuelve True si todos los caracteres son alfabéticos\nprint(cadena.isalnum()) #devuelve True si todos los caracteres son alfanuméricos\n\n#Realizar búsquedas\ncadena = 'Hola, soy Juan'\nprint(cadena.find('Juan')) #devuelve la posición de la primera ocurrencia\nprint(cadena.rfind('Juan')) #devuelve la posición de la última ocurrencia\nprint(cadena.index('Juan')) #devuelve la posición de la primera ocurrencia\nprint(cadena.rindex('Juan')) #devuelve la posición de la última ocurrencia\n\n#Contar las veces que aparece una subcadena\nprint(cadena.count('o'))\n\n#Si la subcadena buscada no existe find devuelva -1, mientras que index lanza una excepción\ntry:\n    print(cadena.index('Fran'))\nexcept:\n    print('No se ha encontrado la subcadena')\n\n#Empieza o termina por\nprint(cadena.startswith('Ho'))\nprint(cadena.endswith('no'))\n\n\n#Centrado\ncadena = 'Hola'\ncadena = cadena.center(20,'-') #centra la cadena en un espacio de 20 caracteres\nprint(cadena)\n\n#caracteres unicode\nrocket_code = 0x1F680\nrocket = chr(rocket_code)\nprint(rocket)\n\n# Ejercio extra\n\nprint('-----Ejercicio extra-----')\nprint(('***Palíndromo***')) #palabras que se escriben al revés que al derecho\ndef palindromo (w1:str) -> bool:\n    w1 = w1.lower() #convertimos todo a minúscula\n    w1 = w1.replace(' ','') #eliminamos los espacios\n    #se eliminan las tildes y la diéresis\n    w1 = w1.replace('á','a')\n    w1 = w1.replace('é','e')\n    w1 = w1.replace('í','i')\n    w1 = w1.replace('ó','o')\n    w1 = w1.replace('ú','u')\n    w1 = w1.replace('ü','u')    \n    long = len(w1)\n    for i in range(long):\n        if w1[i]==w1[-i-1]:\n            pass\n        else:\n            return False\n    return True\n\nprint(f'¿Anilina es un palíndromo? {palindromo(\"anilina\")}')\nprint(f'¿Casa es un palíndromo? {palindromo(\"casa\")}')\nprint(f'¿Dábale arroz a la zorra el abad? {palindromo(\"Dábale arroz a la zorra el abad\")}')\n\ndef isograma(w1):\n    w1 = w1.lower() #convertimos todo a minúscula\n    w1 = w1.replace(' ','') #eliminamos los espacios\n    #se eliminan las tildes y la diéresis\n    w1 = w1.replace('á','a')\n    w1 = w1.replace('é','e')\n    w1 = w1.replace('í','i')\n    w1 = w1.replace('ó','o')\n    w1 = w1.replace('ú','u')\n    w1 = w1.replace('ü','u')\n    for i in w1:\n        if w1.count(i) > 1:\n            return False\n    return True\n\nprint(f'Murciélago es un palíndromo? {isograma(\"Murciélago\")}')\nprint(f'¿Casa es un isograma? {isograma(\"casa\")}')\n\ndef anagrama(w1,w2):\n    w1 = w1.lower() #convertimos todo a minúscula\n    w1 = w1.replace(' ','') #eliminamos los espacios\n    #se eliminan las tildes y la diéresis\n    w1 = w1.replace('á','a')\n    w1 = w1.replace('é','e')\n    w1 = w1.replace('í','i')\n    w1 = w1.replace('ó','o')\n    w1 = w1.replace('ú','u')\n    w1 = w1.replace('ü','u')\n    w1 = w1.lower() #convertimos todo a minúscula\n    w1 = w1.replace(' ','') #eliminamos los espacios\n    #se eliminan las tildes y la diéresis\n    w2 = w2.lower()\n    w2 = w2.replace(' ','')\n    w2 = w2.replace('á','a')\n    w2 = w2.replace('é','e')\n    w2 = w2.replace('í','i')\n    w2 = w2.replace('ó','o')\n    w2 = w2.replace('ú','u')\n    w2 = w2.replace('ü','u')\n    set_w1 = set(w1)\n    for i in w2:\n        if i not in set_w1:\n            return False\n    return True\n\nprint(anagrama('roma','amor'))\nprint(anagrama('Paco', 'Pepe'))\nprint(anagrama('Roma','amor'))\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/joshu725.py",
    "content": "# Operaciones con caracteres #\n\nx = \"Hola\"\ny = \"mundo\"\n\nprint(x + \" \" + y)  # Concatenación\nprint(x * 5)  # Repetición\nprint(x[0])  # Indexación\nprint(len(y))  # Longitud\nprint(y[2:4] + \" \" + y[3:] + \" \" + y[:3])  # Slicing\nprint(\"o\" in y)  # Busqueda\nprint(x.replace(\"a\", \"o\"))  # Reemplazo\nprint(y.split(\"n\"))  # División\nprint(y.upper())  # Mayuscula\nprint(x.lower())  # Minuscula\nprint(\"string test\".title())  # Titulo\nprint(\"string test\".capitalize())  # Capitalizar\nprint(x.startswith(\"H\"))  # Busqueda al principio\nprint(x.endswith(\"F\"))  # Busqueda al final\nprint(x.find(\"o\"))  # Busqueda\nprint(\"spring test\".count(\"t\"))  # Busqueda de ocurrencias\nprint(list(x))  # Transformación en lista de caracteres\nl = [x, \" \", y]\nprint(\"\".join(l)) # Transformación de lista en cadena de caracteres\n# Comprobaciones\nprint(\"46735\".isalnum())\nprint(\"Hola\".isalpha())\nprint(\"Hola\".isdigit())\n\n# Extra #\ndef check(w1 : str, w2 : str):\n    # Palindromos\n    print(f\"¿\\\"{w1}\\\" es palindromo?: {w1 == w1[::-1]}\")\n    print(f\"¿\\\"{w2}\\\" es palindromo?: {w2 == w2[::-1]}\")\n\n    # Anagramas\n    print(f\"¿\\\"{w1}\\\" es anagrama de \\\"{w2}\\\"?: {sorted(w1) == sorted(w2)}\")\n\ncheck(\"seres\", \"hola\")\ncheck(\"iman\", \"mani\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/jptxaya.py",
    "content": "#String\n\nmy_str1 = \"Hola Mundo\"\nmy_str2 = \"hEllo wOrld\"\nmy_str3 = \"hha bb sh hha ss\"\n\n#Longitud\nprint(\"*Longitud\")\nprint(len(my_str1))\n\n#Index del primer caracter encontrado\nprint(\"*Index del primer caracter encontrado\")\nprint(my_str1.index(\"o\"))\n\n#Busqueda\nprint(\"*Busqueda\")\nprint(my_str1.find(\"Mu\"))\n\n#Repeticiones\nprint(\"*Repeticiones\")\nprint(my_str1.count(\"o\"))\nprint(my_str3.count(\"ha\"))\nprint(my_str3.count(\"ha\",5))\n\n#Subtring\nprint(\"*Subtring\")\nprint(my_str1[2])\nprint(my_str1[1:3])\nprint(my_str1[-1])\nprint(my_str1[-2])\n\n\n#rstrip y lstrip, ljust,rjust, center\nprint(\"*rstrip y lstrip, ljust,rjust, center\")\nmy_str1 = \"   Hola Mundo   \"\nprint(my_str1)\nprint(my_str1.lstrip())\nprint(my_str1.rstrip())\nmy_str1 = \"---Hola Mundo---\"\nprint(my_str1)\nprint(my_str1.lstrip(\"-\"))\nprint(my_str1.rstrip(\"-\"))\n\nprint(my_str1.ljust(30,\"*\"))\nprint(my_str1.rjust(30))\n\nprint(my_str1.center(50,\"_\"))\n\n#Uppercase, lowercase, capitalize,swapcase, tittle\nprint(\"*Uppercase, lowercase, capitalize,swapcase, tittle\")\nprint(my_str2.upper())\nprint(my_str2.lower())\nprint(my_str2.capitalize())\nprint(my_str2.swapcase())\nprint(my_str2.title())\n\n#Concatenacion\nprint(\"*Concatenacion\")\nmy_oper = my_str1 + \" \" + my_str2\nprint(my_oper)\nprint(my_str2.join([\"aa\",\"bb\"]))\nprint(\"-\".join([\"aa\",\"bb\",\"cc\",\"dd\"]))\n\n#Replace\nprint(\"*Replace\")\nprint(my_str1.replace(\"ola\",\"ello\"))\n\n#Separar\nprint(\"*Separar\")\nprint(my_str1.split(\" \"))\nprint(my_str1.partition(\"l\"))\n\nmy_str_lines = \"Hola mundo \\n\" + \"testing splitlines \\n\" + \"final test\"\nprint(my_str_lines)\nprint(my_str_lines.splitlines())\n\n#Verificaciones\nprint(\"*Verificaciones\")\n\nmy_str_numeric = \"11\"\nprint(my_str_numeric)\nprint(f\"Aphanumeric: {my_str_numeric.isalnum()}\")\nprint(f\"Alphabetic: {my_str_numeric.isalpha()}\")\nprint(f\"Decimal:{my_str_numeric.isdecimal()}\")\nprint(f\"Digito:{my_str_numeric.isdigit()}\")\nprint(f\"Numeric:{my_str_numeric.isnumeric()}\")\n\nprint(my_str1)\nprint(f\"Aphanumeric: {my_str1.isalnum()}\")\nprint(f\"Alphabetic: {my_str1.isalpha()}\")\nprint(f\"Decimal:{my_str1.isdecimal()}\")\nprint(f\"Digito:{my_str1.isdigit()}\")\nprint(f\"Numeric:{my_str1.isnumeric()}\")\n\n#Iteraciones\nprint(\"*Iteraciones\")\nmy_str1 = \"Hola\"\nfor elem in my_str1:\n    print(f\"for character:{elem}\")\n\ni = 0\nwhile i < len(my_str1):\n    print(f\"while character:{my_str1[i]}\")\n    i += 1\n\n\n#Dificultad extra\nprint(\"***Dificultad extra\")\n\ndef is_palindromo(my_str1):\n    #Veridicamos si cada palabra es palindroma, se lee igual de izq a der que de der a izq\n    palindromos = True\n    i = 0\n    while i < len(my_str1) // 2:\n        if my_str1[i] == my_str1[0 - 1 - i]:\n                i += 1\n        else:\n            palindromos = False\n            break\n    print(f\"Palindromo palabra {my_str1}:{palindromos}\")\n\ndef get_dict_word(my_str):\n    my_dict1 = {}\n    for elem in list(my_str):\n        my_dict1[elem] = my_dict1.get(elem,0) + 1\n    return my_dict1\n\ndef is_isograma(my_dict):\n     for elem in my_dict.values():\n          if elem > 1:\n               return False\n     return True\n          \ndef is_anagrama(dict1,dict2):\n     my_list1 = list(dict1.keys())\n     my_list1.sort()\n     my_list2 = list(dict2.keys())\n     my_list2.sort()\n     anagrama = False\n     if len(my_list1) == len(my_list2):\n          i = 0\n          anagrama = True\n          while i < len(my_list1):\n               if my_list1[i] != my_list2[i] or my_dict1[my_list1[i]] != my_dict2[my_list2[i]]:\n                    anagrama = False\n                    break\n               i += 1\n     return anagrama\n\n\nmy_str1 = input(\"Insertar palabra_1 para verificar:\")\nmy_str2 = input(\"Insertar palabra_2 para verificar:\")\n#Verificacion palindromo\nis_palindromo(my_str1)\nis_palindromo(my_str2)\n#Verificacion isograma\nmy_dict1 = get_dict_word(my_str1)\nmy_dict2 = get_dict_word(my_str2)\nprint(f\"Isograma palabra {my_str1}:{is_isograma(my_dict1)}\")\nprint(f\"Isograma palabra {my_str2}:{is_isograma(my_dict2)}\")\n#Verificacion de anagrama de las dos palabras\nprint(f\"Son anagramas {my_str1} y {my_str2}: {is_anagrama(my_dict1,my_dict2)}\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/jtrujilloalcocer.py",
    "content": "# #04 CADENAS DE CARACTERES\n## Ejercicio\n\n'''\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n '''\n \n #CADENAS DE CARACTERES\ncadena = \"Hola Mundo\"\n\n#Funciones de cadena\nprint(cadena[0]) #H\nprint(cadena[1:4]) #ola\nprint(len(cadena)) #10\nprint(cadena + \" \" + \"Cruel\") #Hola Mundo Cruel\nprint(cadena * 3) #Hola MundoHola MundoHola Mundo\nprint(cadena.lower()) #hola mundo\nprint(cadena.upper()) #HOLA MUNDO\nprint(cadena.replace(\"Hola\", \"Adios\")) #Adios Mundo\nprint(cadena.split(\" \")) #['Hola', 'Mundo'] \nprint(\" \".join(cadena)) #H o l a   M u n d o\nprint(cadena.find(\"Mundo\")) #5\nprint(cadena.count(\"o\")) #2\n\n#Programa que analiza dos palabras diferentes y realice comprobaciones\ndef menu():\n    print(\"Introduce la primera palabra:\")\n    palabra1 = input()\n    print(\"Introduce la segunda palabra:\")\n    palabra2 = input()\n    return palabra1, palabra2\n\n#Funcion Palindromo que significa que se lee igual de izquierda a derecha que de derecha a izquierda\ndef palindromo(palabra1, palabra2):\n    if palabra1 == palabra1[::-1]: #[::-1] invierte la cadena y comprueba si es palindromo\n        print(\"La palabra\", palabra1, \"es un palindromo\") \n    else:\n        print(\"La palabra\", palabra1, \"no es un palindromo\")\n    if palabra2 == palabra2[::-1]:\n        print(\"La palabra\", palabra2, \"es un palindromo\")\n    else:\n        print(\"La palabra\", palabra2, \"no es un palindromo\")\n        \n#Funcion Anagrama que significa que las letras de una palabra se pueden reordenar para formar otra palabra\ndef anagrama(palabra1, palabra2): \n    if sorted(palabra1) == sorted(palabra2):#sorted ordena la cadena y comprueba si es un anagrama\n        print(\"La palabra\", palabra1, \"es un anagrama de\", palabra2)\n    else:\n        print(\"La palabra\", palabra1, \"no es un anagrama de\", palabra2)\n\n#Funcion Isograma que significa que no tiene letras repetidas\ndef isograma(palabra1, palabra2):\n    if len(palabra1) == len(set(palabra1)) and len(palabra2) == len(set(palabra2)):#set elimina los elementos duplicados\n        print(\"La palabra\", palabra1, \"es un isograma\")\n    else:\n        print(\"La palabra\", palabra1, \"no es un isograma\")\n    if len(palabra2) == len(set(palabra2)):\n        print(\"La palabra\", palabra2, \"es un isograma\")\n    else:\n        print(\"La palabra\", palabra2, \"no es un isograma\")\n\ndef main():\n    palabra1, palabra2 = menu()\n    palindromo(palabra1, palabra2)\n    anagrama(palabra1, palabra2)\n    isograma(palabra1, palabra2)\n    \nmain()#Llamada a la funcion main  \n    \n     \n "
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/juanRCoder.py",
    "content": "\nstring1 = 'juanrcoder'\nstring2 = 'pythonRoadMap'\n\nprint(string1[1])                               #Acceso a carateres especificos\nprint(len(string1))                             #Longitud de carateres de un string.\nprint(string1 + string2)                        #Concatenacion de string.\nprint(string1*3)                                #Repeticion del string.\nprint([i for i in string1])                     #Recorrido en el string.\nprint(string1.upper())                          #Convertir el string a mayuscula.\nprint(string2.lower())                          #Convertir el string a minuscula.\nprint(string1.replace('rcoder','cito'))         #Reemplazar pedazos del string.\nprint(string1[1])                               #Acceso a carateres especificos.\nprint('-'.join(string1))                        #Union con - de cada caracter.\nprint(f\"{string1} aprende en el {string2}\")     #Interpolacion de string.\nprint(string2.isdigit())                        #Verifica si tiene digitos.\nprint(string1[1:5])                             #Subcadena de string1.\nprint(string2.split('o'))                       #Division de la cadena por cada 'o'.\n\n\n#  * DIFICULTAD EXTRA (opcional):\ndef isPalindromo(str):\n    str = str.lower().replace(\" \", \"\")\n    return str == str[::-1]\n\nprint(isPalindromo('reconocer'))\n\n\ndef isAnagramas(str, str2):\n    str, str2 = list(set(str.lower())), list(set(str2.lower()))\n    str.sort()\n    str2.sort()\n    str , str2 = ''.join(str), ''.join(str2)\n    return str == str2\n\nprint(isAnagramas('pedro','drope'))\n\n\ndef isIsograma(str):\n    str = str.lower()\n    obj = {}\n    for i in str:\n        if i in obj:\n            obj[i] += 1\n        else:\n            obj[i] = 1\n            \n    for _, v in obj.items():\n        if v > 1:\n            return False\n    return True\n\nprint(isIsograma('murcielago'))\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/juanchernandezdev.py",
    "content": "### Python Strings ###\n\nmy_first_str = 'Hello world, I\\'m learning python'\nmy_second_str = 'My other string'\n\n#! Multiline String\nmy_multi_str = '''Hello, this\nis a multiline\nstring'''\nprint(my_multi_str)\n\n#! Accessing a Character\nprint(my_first_str[6]) # Shows character at index 6\n\n#! String Concatenation\nprint(my_first_str + ', ' + my_second_str)\nprint(f'{my_first_str}, {my_second_str}')\n\n#! Substrings\n#* Slicing\nprint(my_first_str[0:11])\nprint(my_first_str[-6:])\n\n#! Length\nprint(len(my_first_str))\n\n#! Repetition\nprint(my_first_str * 4)\n\n#! Formatting\nyear = 2024\nmonth = 'jun'\ntemp = 23.5\n\n# f-string\nprint(f'The current year is {year}, the current month is {month}, and today temperature is {temp}celsius.')\n\n# format() method\nprint('The current year is {}, the current month is {}, and today temperature is {}celsius.'.format(year, month, temp))\n\n# % Operator\nprint('The current year is %s, the current month is %s, and today temperature is %.1fcelsius.' %(year, month, temp))\n\n#! String Iteration\nfor char in my_first_str:\n  print(char)\n  \n# Iteration with char index\nfor i, char in enumerate(my_first_str):\n  print(i, char)\n\n#! Methods\n#* Uppercase\nprint(my_first_str.upper())\n\n#* Lowercase\nprint(my_first_str.lower())\n\n#* Title\nprint(my_first_str.title())\n\n#* Capitalize\nprint(my_first_str.capitalize())\n\n#* Replace\nprint(my_first_str.replace('Hello', 'Good bye'))\n\n#* Find\nprint(my_first_str.find('python'))\n\n#* Split\nprint(my_first_str.split(' '))\n\n#* Join\nprint(''.join(my_first_str))\n\n#! Escape Characters\n#* Line Break\nprint('Jumping a\\nline.')\n\n#* Tab\nprint('first word\\tsecond word')\n\n#* Quote\nprint('The author said, \\'Author quote here!\\'')\n\n#* Backslash\nprint('Hi, I\\'m a backslash -> \\\\')\n\n#! Verification\nupper_str = 'UPPER WORDS'\ndigits_str = '123456'\nempty_str = ''\n\n# isupper\nprint(upper_str.isupper())\n\n# islower\nprint(upper_str.islower())\n\n# isdigits\nprint(upper_str.isdigit())\nprint(digits_str.isdigit())\n\n# isalpha\nprint(upper_str.isalpha()) # Returns false because of the space\nprint(digits_str.isalpha())\n\n# isalnum\nprint(upper_str.isalnum())\nprint(digits_str.isalnum())\n\n# startswith\nprint(upper_str.startswith('Hello'))\nprint(digits_str.startswith('1'))\n\n# endswith\nprint(upper_str.endswith('WORDS'))\nprint(digits_str.endswith('6'))\n\n# check if the string is empty\nif len(empty_str) == 0: print('the string is empty') \n\n#! Optional Challenge\nprint('---Optional Challenge---')\n\ndef word_checker(first_txt, second_txt):\n  normalized_first_txt = first_txt.lower().replace(' ', '')\n  normalized_second_txt = second_txt.lower().replace(' ', '')\n  sorted_first = ''.join(sorted(normalized_first_txt)) \n  sorted_second = ''.join(sorted(normalized_second_txt))\n  \n  \n  if normalized_first_txt == normalized_first_txt[::-1]:\n    print(f'{first_txt.capitalize()} is a palindrome!!.')\n    \n  if normalized_second_txt == normalized_second_txt[::-1]:\n    print(f'{second_txt.capitalize()} is a palindrome!!.')\n    \n  if sorted_first == sorted_second :\n    print(f'The second word {second_txt} is an anagram of {first_txt}!!.') \n  \n  my_first_set = set()\n    \n  for char in normalized_first_txt:\n      counter = normalized_first_txt.count(char)\n      my_first_set.add(counter)\n      \n  my_second_set = set()\n    \n  for char in normalized_second_txt:\n      counter = normalized_second_txt.count(char)\n      my_second_set.add(counter)\n\n  if len(my_first_set) == 1:\n    print(f'Your word {first_txt} is a isogram!!')\n    \n  if len(my_second_set) == 1:\n    print(f'Your word {second_txt} is a isogram!!')\n      \n#* Palindrome    \nword_checker('madam', 'kayak')\nword_checker('car', 'Rotator')  \n    \n#* Aanagram\nword_checker('angel', 'Glean')\nword_checker('cried', 'cider')\nword_checker('cat', 'act')\n\n#* Isogram\nword_checker('Caucasus', 'intestines')\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/juandaherrera.py",
    "content": "\"\"\"\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n *\n\"\"\"\nfrom collections import Counter\nfrom typing import Callable, Optional\n\nREPLACEMENTS = ((\"á\", \"a\"), (\"é\", \"e\"), (\"í\", \"i\"), (\"ó\", \"o\"), (\"ú\", \"u\"), (\" \", \"\"))\n\n\ndef replace_special_characters(input: str) -> str:\n    \"\"\"Reemplaza caracteres especiales en una cadena con sus equivalentes sin tilde.\n\n    Args:\n        input_str (str): La cadena de entrada que puede contener caracteres especiales.\n\n    Returns:\n        str: La cadena resultante con los caracteres especiales reemplazados.\n    \"\"\"\n    for a, b in REPLACEMENTS:\n        input = input.replace(a, b)\n    return input\n\n\ndef string_to_list(input: str) -> list:\n    \"\"\"Convierte una cadena en una lista de caracteres.\n\n    Args:\n        input_str (str): La cadena de entrada.\n\n    Returns:\n        list: Lista de caracteres individuales de la cadena de entrada.\n    \"\"\"\n    return [letter for letter in input]\n\n\ndef is_palindrome(input: str) -> bool:\n    \"\"\"Verifica si una cadena es un palíndromo.\n\n    Args:\n        input_str (str): La cadena de entrada.\n\n    Returns:\n        bool: True si la cadena es un palíndromo, False en caso contrario.\n    \"\"\"\n    modified_input = replace_special_characters(input.lower())\n    return modified_input == modified_input[::-1]\n\n\ndef is_anagram(input_1: str, input_2: str) -> bool:\n    \"\"\"Verifica si dos cadenas son anagramas entre sí.\n\n    Args:\n        input_1 (str): La primera cadena.\n        input_2 (str): La segunda cadena.\n\n    Returns:\n        bool: True si las cadenas son anagramas, False en caso contrario.\n    \"\"\"\n    if len(input_1) != len(input_2):\n        return False\n    new_input_1, new_input_2 = replace_special_characters(input_1.lower()), replace_special_characters(input_2.lower())\n    new_input_1, new_input_2 = sorted(string_to_list(new_input_1)), sorted(string_to_list(new_input_2))\n\n    return new_input_1 == new_input_2\n\n\ndef is_isogram(input: str) -> bool:\n    \"\"\"Verifica si una cadena es un isograma (no repite ninguna letra).\n\n    Args:\n        input_str (str): La cadena de entrada.\n\n    Returns:\n        bool: True si la cadena es un isograma, False en caso contrario.\n    \"\"\"\n    input = replace_special_characters(input)\n    counter = Counter(sorted(string_to_list(input)))\n    return max(counter.values()) == 1\n\n\ndef request_input(prompt: str, validation: Optional[Callable[[str], bool]] = None) -> str:\n    \"\"\"Solicita entrada al usuario hasta que cumpla con la validación.\n\n    Args:\n        prompt (str): El mensaje a mostrar al usuario.\n        validation (Optional[Callable[[str], bool]]): La función de validación que debe pasar la entrada.\n\n    Returns:\n        str: La entrada del usuario que pasó la validación.\n    \"\"\"\n    while True:\n        user_input = input(prompt)\n        if not validation or validation(user_input):\n            return user_input\n\n\ndef main():\n    while True:\n        print(\"-------------------------------------------------\")\n        print(\"1. Validar si una palabra es palíndroma.\")\n        print(\"2. Validar dos palabras son anagramas.\")\n        print(\"3. Validar si una palabra es isograma.\")\n        print(\"4. Salir del programa.\")\n        option = input(\"Ingrese su opción: \")\n        match option:\n            case \"1\":\n                word = request_input(\"Ingresa la palabra: \")\n                response = (\n                    f\"La palabra {word} es palíndroma\" if is_palindrome(word) else f\"La palabra {word} NO es palíndroma\"\n                )\n                print(response)\n            case \"2\":\n                word_1 = request_input(\"Ingresa la primera palabra: \")\n                word_2 = request_input(\"Ingresa la segunda palabra: \")\n                response = (\n                    f\"{word_1} y {word_2} son anagramas\"\n                    if is_anagram(word_1, word_2)\n                    else f\"{word_1} y {word_2} NO son anagramas\"\n                )\n                print(response)\n            case \"3\":\n                word = request_input(\"Ingresa la palabra: \")\n                response = f\"La palabra {word} es isograma\" if is_isogram(word) else f\"La palabra {word} NO es isograma\"\n                print(response)\n            case \"4\":\n                print(\"Saliendo del programa...\")\n                break\n            case _:\n                print(\"Ingresa una opción válida.\")\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/juanmax2.py",
    "content": "\"\"\"\nOperaciones con cadenas\n\"\"\"\n\n# Concatenar\nc1 = \"Hola\"\nc2 = \"python\"\n\nc3 = c1 + \" \" + c2 # Podemos concatenar con strings fuera de variables\nprint(c3)\n\n# Repetición\nprint(c3 * 3)\n\n# Index\nprint(c3[1]) # Desde el indice 1\n\n# Longitud\nprint(len(c3))\n\n# Slicing\nprint(c3[3:7]) # Recorre del 3 al 6\nprint(c3[3:]) # Recorre del 3 al final\nprint(c3[:4]) # Recorre del principio hasta el 3\n\n# Busqueda\nprint(\"a\" in c3) # True\nprint(\"w\" in c3) # False\n\n# Remplazo\nprint(c1.replace(\"o\", \"a\"))\n\n# División\nprint(c3.split(\" \")) # Dividimos por espacio (\" \")\n\n# Conversión\n# Mayusculas\nprint(c3.upper())\n\n# Minusculas\nprint(c3.lower())\n\n# Primera letra mayusculas de cada palabra\nprint(c3.title())\n\n# Solo primera letra de la primera palabra\nprint(c3.capitalize())\n\n# Eliminación de espacio al principio y al final\nprint(\" juanma gonzalez \". strip())\n\n# Busqueda al principio y final\nprint(c3.startswith(\"H\"))\nprint(c3.endswith(\"on\"))\n\n# Busqueda de posición\n# Muestra el indice donde comienza la palabra\nprint(\"Hola Juanma como estas hoy?\".find(\"estas\"))\n\n# Busqueda de ocurrencia\nprint(c3.count(\"o\")) # Cuantas veces aparece el caracter o palabra\n\n# Formateo\nprint(\"Saludo: {}, lenguaje: {}!\".format(c1, c2))\n\n# f string(Python), interpolación (lenguajes) \nprint(f\"Saludo: {c1}, lenguaje: {c2}\")\n\n# Transformacion en lista de caracteres\nprint(list(c3))\n\nc4 = list(c3)\n\n# Transformación de lista en cadena\nprint(c4)\nprint(\"\".join(c4))\n\n# Transformaciones númericas\nc4 = \"12345\" # Texto\nprint(c4)\nprint(type(c4))\nc4 = int(c4) # Integer\nprint(c4)\nprint(type(c4))\nc4 = float(c4) # Float\nprint(c4)\nprint(type(c4))\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n\"\"\"\n\n\ndef check_palabra(palabra1, palabra2) -> str:\n    # Palindromos\n    palindromo(palabra1)\n    palindromo(palabra2)\n    \n    # Anagramas\n    anagrama(palabra1, palabra2)\n\n    # heterograma\n    heterograma(palabra1)\n    heterograma(palabra2)\n    \n    # Isograma\n    isograma(palabra1)\n    isograma(palabra2)\n\n        \ndef palindromo(palabra):\n    \"\"\"Esta función se encarga de mirar si la palabra y la palabra ordenada al\n    revés son iguales\"\"\"\n    if palabra == palabra[::-1]:\n        print(f\"La palabra {palabra} es un palíndromo\")\n\n    else:\n        print(f\"La palabra {palabra} no es un palíndromo\")\n\ndef anagrama(palabra1, palabra2):\n    \"\"\"Esta función se encarga de mirar si las palabras ordenandolas por orden\n    alfabetico son iguales\"\"\"\n    if sorted(palabra1) == sorted(palabra2):\n        print(f\"La palabra {palabra1} y la palabra {palabra2} son anagramas\")\n    else:\n        print(f\"La palabra {palabra1} y la palabra {palabra2} no son anagramas\")\n\ndef heterograma(palabra):\n    \"\"\"Esta funcón compara la longitud de la palabra con la longitud del set\n    de esa palabra, el set elimina los caracteres repetidos asi que si las \n    longitudes son iguales no hay caracteres repetidos\"\"\"\n    if len(palabra) == len(set(palabra)):\n        print(f\"La palabra {palabra} es un heterograma\")\n    else:\n        print(f\"La palabra {palabra} no es un heterograma\")\n\ndef isograma(palabra):\n    \"\"\"Esta función almacena el numero de veces que sale cada letra en una\n    palabra para ver si es exactamente el mismo siempre que sean 2 o mas\"\"\"\n    dict_palabra = dict()\n    for letra in palabra:\n        dict_palabra[letra] = dict_palabra.get(letra, 0) + 1\n    isograma = True\n    values = list(dict_palabra.values())\n    isograma_len = values[0]\n    if isograma_len <= 1: \n        isograma = False\n        print(f\"La palabra {palabra} es un isograma? {isograma}\")\n    else: \n        for contador_letra in values:\n            if (contador_letra != isograma_len):\n                isograma = False\n                print(f\"La palabra {palabra} es un isograma? {isograma}\")\n        \n        print(f\"La palabra {palabra} es un isograma? {isograma}\")\n            \n# Caso de uso             \ncheck_palabra(\"radar\", \"python\")\ncheck_palabra(\"amor\", \"roma\")\ncheck_palabra(\"radar\", \"pythonpython\")\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/juanppdev.py",
    "content": "# Definir una cadena de caracteres\ncadena = \"Hola, mundo!\"\n\n# Acceso a caracteres específicos\nprimer_caracter = cadena[0]\nultimo_caracter = cadena[-1]\n\nprint(\"Acceso a caracteres:\")\nprint(\"Primer caracter:\", primer_caracter)\nprint(\"Último caracter:\", ultimo_caracter)\n\n# Subcadenas\nsubcadena = cadena[0:4]\nprint(\"\\nSubcadena:\")\nprint(\"Subcadena de los primeros 4 caracteres:\", subcadena)\n\n# Longitud de la cadena\nlongitud = len(cadena)\nprint(\"\\nLongitud de la cadena:\")\nprint(\"Longitud de la cadena:\", longitud)\n\n# Concatenación\notra_cadena = \" ¡Python es genial!\"\ncadena_concatenada = cadena + otra_cadena\nprint(\"\\nConcatenación:\")\nprint(\"Cadena concatenada:\", cadena_concatenada)\n\n# Repetición\ncadena_repetida = cadena * 3\nprint(\"\\nRepetición:\")\nprint(\"Cadena repetida 3 veces:\", cadena_repetida)\n\n# Recorrido\nprint(\"\\nRecorrido:\")\nfor caracter in cadena:\n    print(caracter, end=\" \")\n\n# Conversión a mayúsculas y minúsculas\nprint(\"\\n\\nConversión a mayúsculas y minúsculas:\")\nmayusculas = cadena.upper()\nminusculas = cadena.lower()\nprint(\"Mayúsculas:\", mayusculas)\nprint(\"Minúsculas:\", minusculas)\n\n# Reemplazo\ncadena_reemplazada = cadena.replace(\"mundo\", \"Python\")\nprint(\"\\nReemplazo:\")\nprint(\"Cadena con reemplazo:\", cadena_reemplazada)\n\n# División\npalabras = cadena.split(\",\")\nprint(\"\\nDivisión:\")\nprint(\"Cadena dividida por coma:\", palabras)\n\n# Unión\nnueva_cadena = \"-\".join(palabras)\nprint(\"\\nUnión:\")\nprint(\"Palabras unidas por guión:\", nueva_cadena)\n\n# Interpolación\nnombre = \"Juan\"\nedad = 25\nmensaje = f\"Hola, me llamo {nombre} y tengo {edad} años.\"\nprint(\"\\nInterpolación:\")\nprint(\"Mensaje interpolado:\", mensaje)\n\n# Verificación\nes_digito = cadena.isdigit()\nprint(\"\\nVerificación:\")\nprint(\"¿La cadena contiene solo dígitos?:\", es_digito)\n\n## Ejercicio Extra\ndef es_palindromo(palabra):\n    reversa = palabra[::-1]\n    return palabra == reversa\n\ndef es_anagrama(palabra1, palabra2):\n    return sorted(palabra1) == sorted(palabra2)\n\ndef es_isograma(palabra):\n    set_de_caracteres = set()\n    for caracter in palabra:\n        if caracter in set_de_caracteres:\n            return False  # Si se encuentra un carácter repetido, no es un isograma\n        set_de_caracteres.add(caracter)\n    return True\n\n# Ingresa las dos palabras que deseas analizar\npalabra1 = input(\"Ingresa la primera palabra: \").lower()\npalabra2 = input(\"Ingresa la segunda palabra: \").lower()\n\n# Comprobación de palíndromo\nes_palindromo_1 = es_palindromo(palabra1)\nes_palindromo_2 = es_palindromo(palabra2)\n\n# Comprobación de anagrama\nes_anagrama_resultado = es_anagrama(palabra1, palabra2)\n\n# Comprobación de isograma\nes_isograma_1 = es_isograma(palabra1)\nes_isograma_2 = es_isograma(palabra2)\n\n# Mostrar resultados\nprint(\"\\nResultados:\")\nprint(f\"Palabra 1 es palíndromo: {es_palindromo_1}\")\nprint(f\"Palabra 2 es palíndromo: {es_palindromo_2}\")\nprint(f\"Son anagramas: {es_anagrama_resultado}\")\nprint(f\"Palabra 1 es isograma: {es_isograma_1}\")\nprint(f\"Palabra 2 es isograma: {es_isograma_2}\")\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/julianbuitragocharry-dev.py",
    "content": "my_string = 'Hello'\nmy_second_string = 'World!'\n\n# Concatenation\nprint(my_string + ', ' + my_second_string)\n\n# String as List --> You can slicing and using list methods \nfor i in range(len(my_string)):\n    print(my_string[i])\n\nprint(my_string[::-1])\n\n# Search\nprint('W' in my_string)\nprint('W' in my_second_string)\n\n# Some Methods \nmy_new_string = my_string\n\nmy_new_string.capitalize()\nprint(my_new_string)\n\nmy_new_string.lower()\nprint(my_new_string)\n\nmy_new_string.replace('e', 'o')\nprint(my_new_string)\n\ndef is_palindromo(first_string: str, second_string: str):\n    return (first_string == second_string[::-1])\n\ndef is_anagrama(first_string: str, second_string: str):\n    return (first_string.sort() == second_string.sort())\n\ndef is_isograma(string):\n    word_dict = dict()\n    for character in string:\n        word_dict[character] = word_dict.get(character, 0) + 1\n    isogram = True\n    values = list(word_dict.values())\n    isogram_len = values[0]\n    for word_count in values:\n        if word_count != isogram_len:\n            isogram = False\n            break\n    return isogram"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/juserdev.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */ \"\"\"\n\nsaludo = \"hola\"\nlenguaje = \"python\"\n\n#subcadena\nprint(saludo[0:3])\nprint(saludo[1:3])\n\n#acceso caracteres especificos\nprint(saludo[0])\n\n# logitud\nprint(len(saludo))\n\n#concatenacion\nprint(saludo + \" \" + lenguaje)\n\n#multiplicacion\nprint(saludo * 3)\n\n#reccorido\nfor letra in saludo:\n  print(letra)\n\nfor letra in lenguaje:\n  print(letra)\n\n\n#conversion a mayusculas\nsaludar = saludo + \" \" + lenguaje\nsaludar_mayusculas = saludar.upper()\nprint(saludar_mayusculas)\n\n#convertir a minusculas\nsaludar_minusculas = saludar_mayusculas.lower()\nprint(saludar_minusculas)\n\n#inicial mayuscula\nprint(saludar.capitalize())\nprint(saludar.title(), \"este es ima ´riena de totñe()\") # convierte la primera letra de cada palabra en mayuscula\n\n# reemplazo\nreemplazo = saludo.replace(\"h\", \"J\")\nprint(reemplazo)\n\n# divisio\ndivision = saludar.split(\" \")\nprint(division)\n\n# union\n# -> es una manera un poco burda de unir palabras pero funciona\noracion = \" \".join(division)\nprint(oracion)\n\n# Interporacion\nSaludo_interpolado = f\"{saludo} {lenguaje}\"\nprint(Saludo_interpolado)\n\n# verificacion\nprint(\"a\" in lenguaje)\nprint(\"y\" in lenguaje)\n\n# busqueda\nprint(saludar.find(\"python\"))\n\n# transformacion en lista de caracteres\nprint(list(saludar))\n\n# verificacion\n\nprint(saludar.isnumeric())\nprint(saludar.isalnum())\nprint(saludar.isalpha())\n\n### dificulatad extra\n\ndef analisis(palabra1: str, palabra2: str):\n  #palindromo\n  print(f\"{palabra1} es un palindromo --> {palabra1 == palabra1[::-1]}\")\n  print(f\"{palabra2} es un palindromo --> {palabra2 == palabra2[::-1]}\")\n\n  #anagrama\n  print(f\"{palabra1} es un anagrama de {palabra2}? {sorted(palabra1) == sorted(palabra2)}\")\n  \n  #isograma\n\n  def isograma(palabra: str) -> bool:\n    palabra_dic = dict()\n\n    for letra in palabra:\n      palabra_dic[letra] = palabra_dic.get(letra, 0) + 1\n\n    isograma = True\n    values = list(palabra_dic.values())\n    isograma_len = values[0]\n\n    for contar_palabras in values:\n      if contar_palabras != isograma_len:\n        isograma = False\n        break\n    return isograma\n\n  print(f\"{palabra1} es un isograma= -> {isograma(palabra1)}\")\n  print(f\"{palabra1} es un isograma= -> {isograma(palabra2)}\")\n  \n  isograma(palabra1)\n  isograma(palabra2)\n  \nanalisis(\"radar\", \"anilina\")\nanalisis(\"cara\", \"arca\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/k-90.py",
    "content": "### Cadena de caracteres\n\nname = \"Enrique\"\nsurname = \"Castro\"\n\n### Concatenación\nname_complete = name + \" \" + surname\nprint(name_complete)\n\n### Repetición \n\nprint(name * 3)\n\n### Longitud\n \nprint(len(name))\n\n### Indexación\n\nprint(surname[0]+surname[1]+surname[2]+surname[3]+ surname[4]+ surname[5])\n\n### Busqueda\n\nprint(\"e\" in name)\nprint(\"a\" in surname)\n\n### Division\n\nprint(name.split(\"r\"))\n\n### Slicing\n\nprint(name[2:4])\nprint(name[::2])\nprint(name[2:])\n\n### Reemplazo\n\nprint(surname.replace(\"s\",\"r\" ))\n\n### Mayusculas\n\nprint(name.upper())\nprint(surname.capitalize())\nprint(surname.title())\nprint(name.lower())\n\n### Strip --> Elimina espacios al principio al final de un string\n\nr1 = \"Mi Lenguaje favorito es Python\"\nprint(r1.strip())\n\n### Busqueda en principio y final\n\nprint(r1.startswith(\"Mi\"))\nprint(r1.startswith(\"El\"))\nprint(r1.endswith(\"Python\"))\nprint(r1.endswith(\"python\"))\n\n### Busqueda de ocurrencias\n\nprint(r1.lower().count(\"e\"))\n\n### Transformación en lista\n\nprint(list(r1))\n\n### Interpolación\n\nprint(f\"Hola {name}, ¿Cuál es tu apellido?. Es {surname}\")\n\n### Busqueda de posición\n\nprint(r1.find(\"Python\"))\nprint(r1.find(\"len\"))\n\n### Formateo\n\nprint(\"Nombre: {} Apellido: {}\".format(name,surname))\n\n### Transformaciones númericas\n\nn1 = \"1234567\"\nn1 = int(n1)\nprint(n1)\n\n### Transformación de lista en cadena\n\ns1 = [name, \" \", surname]\nprint(\"\".join(s1))\n\n### Extra\n\ndef find_out(word1:str, word2:str):\n    ### Anagrama\n    print(f\"{word1} es anagrama de {word2}? {sorted(word1) == sorted(word2)}\")\n    \n    ### Palíndromo \n\n    print(f\"{word1} es palindromo?{word1 == word1[::-1]}\")\n    print(f\"{word2} es palindromo?{word2 == word2[::-1]}\")\n\n    ### Isograma\n\n    def isIsogram(word:str) -> bool:\n        word_dict = dict()\n        for char in word:\n            word_dict[char] = word_dict.get(char, 0) + 1\n        \n        isograma = True\n        values = list(word_dict.values())\n        isogram_len = values[0]\n        for word_count in values:\n            if word_count != isogram_len:\n                isograma = False\n                break\n        return isograma\n    \n    print(f\"{word1} es isograma?: {isIsogram(word1)}\")\n    print(f\"{word2} es isograma?: {isIsogram(word2)}\")\n    \n        \nfind_out(\"amor\", \"radar\")\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/keltoi-dev.py",
    "content": "\"\"\"\n* EJERCICIO:\n* Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n* en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n* - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n*   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n*\n* DIFICULTAD EXTRA (opcional):\n* Crea un programa que analice dos palabras diferentes y realice comprobaciones\n* para descubrir si son:\n* - Palíndromos\n* - Anagramas\n* - Isogramas\n\"\"\"\n\n# Asignacion de cadena\ncadena = \"Hola Python!!\"\nprint(type(cadena))\n\nnumero = 10\ntexto = str(numero)\nprint(type(texto))\n\n# Acceso a caracteres\nprint(cadena[2])  # Muestra el caracter en la posicion 2\nprint(cadena[-1])  # Muestra el ultimo caracter\nprint(cadena[0:4])  # Muestra los caracteres desde el 0 al 4 exclusive\nprint(cadena[5:])  # Muestra los caracteres desde la posicion 5 hasta el final\nprint(cadena[0:7:2])  # Muestra los caracteres desde el 0 al 7 de dos en dos\nprint(cadena[0::2])  # Muestra todos los caracteres de la cadena de dos en dos\n\n# Buscar una subcadena en una cadena\nsub = \"Python\"\nprint(sub in cadena)\n\n# Longitud de cadena\nprint(\"Longitud: \", len(cadena))\n\n# concatenacion\nprint(cadena + texto)\nprint(cadena, \"Hola mundo!\")\n\n# Repeticion\nprint(\"-\" * 30)\n\n# Recorrido\nfor letra in cadena:\n    print(letra)\n\n# Conversion de letras\ntexto = \"HOLA MUNDO!\"\nprint(cadena.upper())  # Todo a mayusculas\nprint(texto.lower())  # Todo a minusculas\nprint(texto.capitalize())  # La primer letra de la oracion en mayuscula\nprint(texto.swapcase())  # Alterna mayuscula y minuscula\n\n# Division en subcadenas\ntexto = \"Juan-Jose-Pedro\"\ncadena = texto.split(\"-\")\nprint(cadena)\n\n# Union de cadenas\nprint(\" - \".join(cadena))\n\n# Verificacion\nprint(texto.isalnum())\nprint(texto.isalpha())\n\nimport re\n\n\n# Dificultad extra\ndef insert_word():\n    word = input(\"Ingrese una palabra: \")\n    word = word.lower()\n    if re.match(\"^[a-zñ]*$\", word):\n        return word\n    else:\n        print(\"Error, ingrese solo letras sin acentos\")\n        insert_word()\n\n\ndef palindromos(word):\n    word_aux = word[::-1]\n    if word_aux == word:\n        return \"es un palindromo\"\n    else:\n        return \"no es un palindromo\"\n\n\ndef isogramas(word):\n    word_aux = set(word)\n    if len(word) == len(word_aux):\n        return \"es un isograma\"\n    else:\n        return \"no es un isograma\"\n\n\nword_1 = insert_word()\nword_2 = insert_word()\n\nif word_1 != word_2:\n    # Verifica si son palindromos\n    print(f\"\\nLa palabra {word_1} {palindromos(word_1)}\")\n    print(f\"La palabra {word_2} {palindromos(word_2)}\")\n\n    # Verifica si son anagramas entre si\n    if set(word_1) == set(word_2):\n        print(f\"\\nLa palabra {word_1} es un anagrama de la palabra {word_2}\")\n    else:\n        print(f\"La palabra {word_1} no es un anagrama de la palabra {word_2}\")\n\n    # Verifica si son isogramas\n    print(f\"\\nLa palabra {word_1} {isogramas(word_1)}\")\n    print(f\"La palabra {word_2} {isogramas(word_2)}\")\nelse:\n    print(\"\\nLas palabras son iguales\")\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/kenysdev.py",
    "content": "# ╔══════════════════════════════════════╗\n# ║ Autor:  Kenys Alvarado               ║\n# ║ GitHub: https://github.com/Kenysdev  ║\n# ║ 2024 -  Python                       ║\n# ╚══════════════════════════════════════╝\n# ************************\n# 1. cadenas de caracteres.\n# ************************\n# Las cadenas en Python, son de tipo inmutable, lo que\n# implica que al realizar operaciones con ellas se accede\n# a una copia y no al valor original.\nstr1 = \"Esto es una cadena\" # commilas dobles.\nstr2 = 'Esto es una cadena' # comillas simples.\nprint(type(str2)) #<class 'str'>\n\n# comillas dentro de una cadena\nstr3 = \"comilla doble \\\" - comilla simple \\'\"\n\n# Salto de linea: \\n\nstr4 = \"Primer linea\\nSegunda linea\"\nprint(str3)\n\n# ASCI y Unicode\nprint(\"\\361\") # octal-Unicode de la 'ñ'.\n\n# raw strings: tratar una cadena como literal.\nprint(r\"\\361\") # \\361\n\n# para textos muy largo.\nprint(\"\"\"Primer linea\nSegunda linea\nTercer linea\"\"\")\n\n# Longitud de la cadena.\ns = \"abcdef\"\nprint(len(s)) # 6\n\n# Acceso a caracteres individuales:\nprint(s[1]) # b\n\n# Obtener porciones específicas de una cadena.\nprint(s[1:4]) # bcd\nprint(s[3:])  # def\n\n# para revertir una cadena\nprint(\"abcd\"[::-1])\n\n# ------------------------\n# Formateo de cadenas:\n# ------------------------\n# concatenación\ns1 = \"hola\"\ns2 = \"python\"\nprint(s1 + \", \" + s2) #Parte 1 Parte 2\n\n# Interpolación (inserción de valores en la cadena)\na = 5; b = 10\ns = f\"Los números son {a} y {b}\"\nprint(s) \n\ns = \"Los números son %d y %d.\" % (5, 10)\nprint(s)\n\ns = \"Los números son {a} y {b}\".format(a=5, b=10)\nprint(s)\n\n# replicación o repetición de cadenas:\ns = \"Hola \"\nprint(s*3) #Hola Hola Hola\n\n# valor numérico que lo representa y viceversa.\nprint(chr(241)) # ñ\nprint(ord(\"ñ\")) # 241\n\n# ordenar\nprint(sorted(\"cdba\")) # abcd\n\n# ------------------------\n# Metodos:\n# ------------------------\n# búsqueda de subcadenas (in, find, index)\ns = \"Hello, python!\"\nprint(\"pyth\" in s)  # True\nprint(s.find(\"python\"))  # 7\n\n# Reemplazo de subcadenas \nprint(s.replace(\"python\", \"Ben\"))\n\n# devuelve una cadena con su primera letra en mayúscula.\nprint(\"mi cadena\".capitalize()) #Mi cadena\n\n# convierte en minúscula.\nprint(\"MI CADENA\".lower()) #mi cadena\n\n#  intercambia el caso de cada letra en una cadena.\nprint(\"mI cAdEnA\".swapcase()) # Mi CaDeNa\n\n# convierte en mayúsculas.\nprint(\"mi cadena\".upper())\n\n# Letras del inicio.\nprint(\"mi cadena\".title()) # Mi Cadena\n\n# conteo de repetición de una cadena en otra.\ns = \"Cantando y llorando.\"\nprint(s.count(\"ando\")) #2\n\n# si son alfanuméricos.\nprint(\"aeiou1234\".isalnum()) # True\n\n# si son alfabéticos.\nprint(\"abcdefg\".isalpha()) # True\n\n# son numéricos.\nprint(\"12345\".isdigit())  # True\n\n# considera una gama más amplia de dígitos\nprint(\"²346½\".isnumeric())  # True\n\n# si están en minúsculas.\nprint(\"abc\".islower())  # True\n\n# si están en mayúsculas.\nprint(\"ABC\".isupper())  # True\n\n# si son espacios en blanco.\nprint(\"   \".isspace())  # True\n\n# espacios o caracteres específicos al principio y al final.\nprint(\"  abc  \".strip()) # abc\n\n# rellena la cadena con ceros a la izquierda.\nprint(\"123\".zfill(5)) #00123\n\n# devuelve la primera cadena unida a cada uno de los elementos\ns = \" y \".join([\"1\", \"2\", \"3\"])\nprint(s) #1 y 2 y 3\n\n# División de cadenas.\nlista_ = \"a,b,c\".split(\",\")  # ['a', 'b', 'c']\nprint(lista_)\n\n# ************************\n# 1. EJERCICIO:\n# ************************\n'''\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n'''\n\ndef analizar(str1, str2):\n    print(f\"\"\"\n    \"{str1}\" es un palíndromo?: {str1 == str1[::-1]}\n    \"{str2}\" es un palíndromo?: {str2 == str2[::-1]}\n \n    \"{str1}\" es un anagrama de \"{str2}\"?: {sorted(str1) == sorted(str2)}\n\n    \"{str1}\" es un isograma?: {len(str1) == len(set(str1))}\n    \"{str2}\" es un isograma?: {len(str2) == len(set(str2))}\n    \"\"\")\n\nanalizar(\"reconocer\",\"vida\")\nanalizar(\"notas\",\"santo\")\nanalizar(\"héroe\",\"radar\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/kodenook.py",
    "content": "\ntxt = 'hello, python!'\n\nprint(len(txt))\nprint(txt.upper())\nprint(txt.lower())\nprint(txt.strip())\nprint(txt.replace('h', 'j'))\nprint(txt.split(','))\nprint(txt.capitalize())\n\ndef word_type(word: str, word2: str) -> None:\n\n    if word == word[::-1]:\n        print('is palindrome')\n\n    if sorted(word) == sorted(word2):\n        print('is an anagram')\n\n    if len(word) == len(set((word))):\n        print('is isogram')\n\nword_type('amor', 'roma')"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/kuroz00.py",
    "content": "#Imprimir una cadena de caracteres por pantalla\nvarEjemplo = 'Hola a todos! '\nvarEjemplo2 = 'Que tal estan?'\nprint(varEjemplo) #hola a todos\n\n#Buscar un caracter en especifico\nif '!' in varEjemplo:\n    print('\" ! \" si existe dentro de varEjemplo')\n\n#FIND Retornara la pocision en la que se encuentra el caracter o cadena señalada como parametro\nprint(varEjemplo.find('!'))\n\n#Eliminar espacios en blanco a los costados de la cadena de caracteres\nvarEjemplo.strip()\n\n#Concatenar 2 o mas cadenas de caracteres \nvarEjemplo += varEjemplo2\nprint(varEjemplo) \n\n#Buscar una palabra en particular\nif 'todos' in varEjemplo:\n    print('\"todos\" si existe dentro de varEjemplo')\n\n#Averiguar la longitud\nprint('La longitud de varEjemplo es: ', len(varEjemplo))\n\n  #Ahora sin los espacios en blanco entre medio\nif \" \" in varEjemplo:\n    varEjemplo = varEjemplo.replace(\" \", \"\")\nprint('La longitud de varEjemplo sin espacios es: ', len(varEjemplo))\n\n#subcadenas \n  #slicing \nprint(varEjemplo[:4]) # hola\nprint(varEjemplo[4:11]) # a todos!\nprint(varEjemplo[11:]) # que tal estna?\n\n\n#Recorrer la cadena de caracteres (comentado para no saturarme la terminal)\n#for x in range(len(varEjemplo)):\n   # print(varEjemplo[x]) #impresion de todos sus caracteres uno por uno\n\n#Conversion \nvarEjemplo = 'HOla a toDos, ESTO es una CADENA De caraCTereS'\n\n    #Mayus\nprint('Conversion a mayusculas  ->' ,varEjemplo.upper())\n    #Minus\nprint('Conversion a minusculas  ->' ,varEjemplo.lower())\n    #convertir en una lista y de paso ordenarla (tambien se puede en tuple y set)\nprint(sorted(varEjemplo))\n\n#Reemplazar palabras al interior\nvarEjemplo = 'Hola mundo!'\nif 'Hola' in varEjemplo:\n    varEjemplo = varEjemplo.replace('Hola', 'Adios') #Adios mundo! (suena re sad)\n    print(varEjemplo)\n\n#Dividir SPLIT\nvarEjemplo = 'Esto es una cadena de varias palabras '\nvarEjemplo = varEjemplo.split()\nprint(varEjemplo) #Dividi todas las palabras las cuales quedaron en una lista\n\n#Unir JOIN\nvarEjemplo = \" \".join(varEjemplo)\nprint(varEjemplo)\n\n#Interpolacion\nnumero = 500\nsaludo1 = 'Hola'\nsaludo2 = ' a todos'\nPI = 3.14\n\nprint('%i + 500 = 1000' %(numero))\nprint('%.2f es el valor de PI!' %(PI))\nprint('%s %s' %(saludo1,saludo2))\n\n# * DIFICULTAD EXTRA (opcional):\n\n'''   Funciones   '''\ndef palinfromo(palabra):\n    palabra = palabra.lower().replace(' ', '')\n    return palabra == palabra[::-1]\n\n\ndef anagrama(palabra1, palabra2):\n    palabra1 = palabra1.lower().replace(' ', '')\n    palabra2 = palabra2.lower().replace(' ', '')       \n    return sorted(palabra1) == sorted(palabra2)       \n\ndef isograma(palabra1, palabra2):\n    palabra1 = palabra1.lower().replace(' ', '')\n    palabra2 = palabra2.lower().replace(' ', '')\n    return len(set(palabra1)) == len(set(palabra2))\n\n\nprint('palindromo: ', palinfromo('radar'))\nprint('anagrama: ', anagrama('radar', 'rada'))\nprint('isograma: ',isograma('rueda', 'ruedo'))\n\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/linerlander.py",
    "content": "\"\"\"\nOperaciones\n\"\"\"\ns1 = \"Hola\"\ns2 = \"Python\"\n\n# Concatenación\nprint(s1 +\" \"+ s2 + \"!\")\n\n# Repetición\nprint(s1 * 3)\n\n# Indexación\nprint(s1[0] + s1[1] + s1[2] + s1[3])\n\n# Longitud\nprint(len(s2))\n\n# Slicing\nprint(s2[2:6])\nprint(s2[2:])\nprint(s2[0:2])\nprint(s2[:2])\n\n# Búsqueda\nprint(\"Ho\" in s1)\nprint(\"i\" in s1)\n\n# Remplazo\nprint(s1.replace(\"o\",\"a\"))\n\n# División\nprint(s2.split(\"t\"))\n\n# Mayúsculas y Minúsculas\nprint(s1.upper())\nprint(s1.lower())\nprint(\"liner lander\".title())\nprint(\"liner lander\".capitalize())\n\n# Eliminación de espacios al principio y al final\nprint(\" Liner Lander \".strip() + \"@landerdev\")\n\n# Búsqueda al principio y al final\nprint(s1.startswith(\"Hol\"))\nprint(s1.startswith(\"Py\"))\nprint(s1.endswith(\"la\"))\nprint(s1.endswith(\"thon\"))\n\ns3 = \"Liner Lander @landerdev\"\n\n# Búsqueda de posición\nprint(s3.find(\"lander\"))\nprint(s3.find(\"Lander\"))\nprint(s3.find(\"L\"))\nprint(s3.lower().find(\"l\"))\n\n# Búsqueda de ocurrencias\nprint(s3.count(\"L\"))\n\n# Formateo\nprint(\"Saludo:{}, lenguaje:{}!\".format(s1, s2))\n\n# Interpolar\nprint(f\"Saludo:{s1}, lenguaje:{s2}!\")\n\n# Transformación en lista de carácteres\nprint(list(s3))\n\n#Transformación de lista en cadena\nl1 = [s1, \",\",s2,\"!\"]\nprint(\" \".join(l1))\n\n#Transformaciónes numéricas\ns4 = \"123456\"\ns4 = int(s4)\nprint(s4)\n\ns5 = \"123456.123\"\ns5 = float(s5)\nprint(s5)\n\n# Comprobaciones varias\ns4 = \"123456\"\nprint(s1.isalnum())\nprint(s1.isalpha())\nprint(s4.isalpha())\nprint(s4.isnumeric())\n\n\"\"\"\nExtra\n\"\"\"\n\ndef check(word1: str, word2: str):\n\n    # Palíndromos\n    print(f\"¿{word1} es un palíndromo?: {word1 == word1[::-1]}\")\n    print(f\"¿{word2} es un palíndromo?: {word2 == word2[::-1]}\")\n\n    # Anagramas\n    print(f\"¿{word1} es anagrama de {word2}?: {sorted(word1) == sorted(word2)}\")\n\n    # Isogramas\n\n    def isogram(word: str) -> bool:\n\n        word_dict = dict()\n        for character in word:\n            word_dict[character] = word_dict.get(character, 0) + 1\n\n        isogram = True\n        values = list(word_dict.values())\n        isogram_len = values[0]\n        for word_count in values:\n            if word_count != isogram_len:\n                isogram = False\n                break\n\n        return isogram\n\n    print(f\"¿{word1} es un isograma?: {isogram(word1)}\")\n    print(f\"¿{word2} es un isograma?: {isogram(word2)}\")\n\n\ncheck(\"radar\", \"linerlinerliner\")\n# check(\"amor\", \"roma\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/m1l0j05.py",
    "content": "# Operaciones con cadenas en Python\n\n# Acceso a caracteres específicos\ns = \"Hola, mundo!\"\nprint(f\"Carácter en la posición 0: {s[0]}\")\nprint(f\"Último carácter: {s[-1]}\")\n\n# Subcadenas\nsubstring = s[6:11]\nprint(f\"Subcadena desde la posición 6 hasta 10: {substring}\")\n\n# Longitud de la cadena\nlength = len(s)\nprint(f\"Longitud de la cadena: {length}\")\n\n# Concatenación\ns1 = \"Hola\"\ns2 = \"mundo\"\nconcatenated = s1 + \", \" + s2 + \"!\"\nprint(f\"Concatenación de cadenas: {concatenated}\")\n\n# Repetición\nrepeated = s1 * 3\nprint(f\"Repetición de cadena 'Hola' tres veces: {repeated}\")\n\n# Recorrido\nfor char in s:\n    print(char, end=' ')\nprint()  # Salto de línea después del recorrido\n\n# Conversión a mayúsculas y minúsculas\nuppercase = s.upper()\nlowercase = s.lower()\nprint(f\"Mayúsculas: {uppercase}\")\nprint(f\"Minúsculas: {lowercase}\")\n\n# Reemplazo\nreplaced = s.replace(\"mundo\", \"Python\")\nprint(f\"Reemplazo de 'mundo' por 'Python': {replaced}\")\n\n# División\nwords = s.split(\", \")\nprint(f\"División de la cadena por ', ': {words}\")\n\n# Unión\njoined = \"-\".join(words)\nprint(f\"Unión de palabras con '-': {joined}\")\n\n# Interpolación de cadenas (format y f-string)\nname = \"Juan\"\nage = 30\nformatted = \"Mi nombre es {} y tengo {} años.\".format(name, age)\nf_string = f\"Mi nombre es {name} y tengo {age} años.\"\nprint(formatted)\nprint(f_string)\n\n# Verificación\ncontains_hola = \"Hola\" in s\nprint(f\"La cadena contiene 'Hola': {contains_hola}\")\n\n# Conteo de ocurrencias\ncount_e = s.count('e')\nprint(f\"Número de veces que 'e' aparece en la cadena: {count_e}\")\n\n# Búsqueda de subcadena\nindex_mundo = s.find('mundo')\nprint(f\"Índice de la primera aparición de 'mundo': {index_mundo}\")\n\n# Verificación de mayúsculas/minúsculas\nis_upper = s.isupper()\nis_lower = s.islower()\nprint(f\"¿Toda la cadena está en mayúsculas?: {is_upper}\")\nprint(f\"¿Toda la cadena está en minúsculas?: {is_lower}\")\n\n# Espacios en blanco\nwhitespace_string = \"   Hola   \"\nstripped = whitespace_string.strip()\nprint(f\"Cadena con espacios en blanco alrededor: '{whitespace_string}'\")\nprint(f\"Cadena sin espacios en blanco alrededor: '{stripped}'\")\n\n# Comprobación de tipo de caracteres\nis_alpha_numeric = s.isalnum()\nis_alpha = s.isalpha()\nis_digit = s.isdigit()\nprint(f\"¿La cadena es alfanumérica?: {is_alpha_numeric}\")\nprint(f\"¿La cadena contiene solo letras?: {is_alpha}\")\nprint(f\"¿La cadena contiene solo dígitos?: {is_digit}\")\n\n\n# Métodos de cadenas en Python\n\n# Métodos de acceso y búsqueda\nprint(s.capitalize())  # Devuelve una copia de la cadena con el primer carácter en mayúscula.\nprint(s.casefold())    # Devuelve una versión de la cadena con todas las letras en minúsculas, adecuada para comparaciones sin distinción entre mayúsculas y minúsculas.\nwidth = 20\nprint(s.center(width))  # Devuelve una cadena centrada en un ancho especificado, con relleno opcional.\nsub = 'mundo'\nprint(s.count(sub))      # Cuenta el número de ocurrencias de una subcadena en la cadena.\nencoding = 'utf-8'\nprint(s.encode(encoding))  # Codifica la cadena en bytes utilizando el formato especificado.\nsuffix = '!'\nprint(s.endswith(suffix))  # Devuelve True si la cadena termina con el sufijo dado, False de lo contrario.\ntabsize = 8\nprint(s.expandtabs(tabsize))  # Expande las tabulaciones en la cadena utilizando espacios.\nsub = 'mundo'\nprint(s.find(sub))       # Devuelve el índice de la primera ocurrencia de la subcadena, -1 si no se encuentra.\n\n# Métodos de formato e información\nprint(s.format())        # Formatea la cadena con valores especificados.\nmapping = {'name': 'Juan', 'age': 30}\nprint(s.format_map(mapping))  # Similar a format, pero utiliza un diccionario para proporcionar los valores.\nsub = 'mundo'\nprint(s.index(sub))       # Devuelve el índice de la primera ocurrencia de la subcadena, genera una excepción si no se encuentra.\nprint(s.isalnum())        # Devuelve True si todos los caracteres de la cadena son alfanuméricos, False de lo contrario.\nprint(s.isalpha())        # Devuelve True si todos los caracteres de la cadena son alfabéticos, False de lo contrario.\nprint(s.isascii())        # Devuelve True si todos los caracteres de la cadena son ASCII, False de lo contrario.\nprint(s.isdecimal())      # Devuelve True si todos los caracteres de la cadena son decimales, False de lo contrario.\nprint(s.isdigit())        # Devuelve True si todos los caracteres de la cadena son dígitos, False de lo contrario.\nprint(s.isidentifier())   # Devuelve True si la cadena es un identificador válido, False de lo contrario.\nprint(s.islower())        # Devuelve True si todos los caracteres de la cadena están en minúsculas, False de lo contrario.\nprint(s.isnumeric())      # Devuelve True si todos los caracteres de la cadena son numéricos, False de lo contrario.\nprint(s.isprintable())    # Devuelve True si todos los caracteres de la cadena son imprimibles, False de lo contrario.\nprint(s.isspace())        # Devuelve True si todos los caracteres de la cadena son espacios en blanco, False de lo contrario.\nprint(s.istitle())        # Devuelve True si la cadena sigue el formato de título, False de lo contrario.\nprint(s.isupper())        # Devuelve True si todos los caracteres de la cadena están en mayúsculas, False de lo contrario.\n\n# Métodos de manipulación y transformación\niterable = ['Hola', 'mundo']\nprint(s.join(iterable))   # Une los elementos de un iterable con la cadena como separador.\nwidth = 20\nprint(s.ljust(width))     # Devuelve una cadena justificada a la izquierda en un ancho especificado.\nprint(s.lower())          # Devuelve una copia de la cadena con todos los caracteres en minúsculas.\nprint(s.lstrip())         # Devuelve una copia de la cadena con los espacios en blanco iniciales eliminados.\nx = 'aeiou'\ny = '12345'\nz = '.,!'\ntranslation_table = str.maketrans(x, y, z)\nprint(s.translate(translation_table))  # Aplica una tabla de traducción creada por maketrans.\nsep = ','\nprint(s.partition(sep))   # Divide la cadena en una tupla (pre-sep, sep, post-sep).\nold = 'mundo'\nnew = 'Python'\ncount = 1\nprint(s.replace(old, new, count))  # Reemplaza las ocurrencias de una subcadena con otra.\nsub = 'mundo'\nprint(s.rfind(sub))       # Devuelve el índice de la última ocurrencia de la subcadena, -1 si no se encuentra.\nprint(s.rindex(sub))      # Devuelve el índice de la última ocurrencia de la subcadena, genera una excepción si no se encuentra.\nwidth = 20\nprint(s.rjust(width))     # Devuelve una cadena justificada a la derecha en un ancho especificado.\nsep = ','\nmaxsplit = 1\nprint(s.rsplit(sep, maxsplit))  # Divide la cadena en una lista de subcadenas, comenzando desde la derecha.\nprint(s.rstrip())         # Devuelve una copia de la cadena con los espacios en blanco finales eliminados.\nsep = ','\nmaxsplit = 1\nprint(s.split(sep, maxsplit))   # Divide la cadena en una lista de subcadenas.\nkeepends = True\nprint(s.splitlines(keepends))   # Divide la cadena en una lista de líneas.\nprefix = 'Hola'\nstart = 0\nend = len(s)\nprint(s.startswith(prefix, start, end))  # Devuelve True si la cadena comienza con el prefijo dado, False de lo contrario.\nchars = ' \\t'\nprint(s.strip(chars))     # Devuelve una copia de la cadena con los caracteres iniciales y finales eliminados.\nprint(s.swapcase())       # Devuelve una copia de la cadena con las mayúsculas convertidas en minúsculas y viceversa.\nprint(s.title())          # Devuelve una versión de la cadena con cada palabra capitalizada.\nprint(s.translate(translation_table))  # Aplica una tabla de traducción creada por maketrans.\nprint(s.upper())          # Devuelve una copia de la cadena con todos los caracteres en mayúsculas.\nwidth = 20\nprint(s.zfill(width))     # Rellena la cadena con ceros a la izquierda hasta alcanzar la longitud especificada.\n\n\n\n# Ejercicio Extra\n\n# * DIFICULTAD EXTRA (opcional):\n# * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n# * para descubrir si son:\n# * - Palíndromos\n# * - Anagramas\n# * - Isogramas\n\n\"\"\"\nDefinicion:\n    Palíndromo: \n    - Una palabra, frase o secuencia que se lee igual en ambos sentidos.\n    Ejemplos: \"reconocer, radar, oso, salas, anilina\".\n    Anagrama: \n    - Una palabra o frase formada reorganizando las letras de otra palabra o frase.\n    Ejemplos: \"amor/Roma, Avisar/Varias, Posta/Pasto\", \n    Isograma: \n    - Una palabra en la que no hay letras repetidas (cada letra aparece una sola vez).\n    Ejemplo: \"murciélago, ligero, cumbre, farsante, ajedrez\".\n\n\"\"\"\n\nimport os\nimport signal\nimport sys\nimport time\n\n## utilidades\n# Colores y estilos\nCOLOR_RED = '91'\nCOLOR_BLUE = '34'\nCOLOR_CYAN = '96'\nCOLOR_GREEN = '32'\nCOLOR_YELLOW = '33'\nCOLOR_GRAY = '90'\nCOLOR_PURPLE = '95'\nCOLOR_BLACK = '30'\nCOLOR_WHITE = '37'\n\n# Funcion generica para imprimir en color\ndef color_text(text, color_code, bold=False):\n    bold_code = '1;' if bold else ''    \n    return f\"\\033[{bold_code}{color_code}m{text}\\033[0m\"\n\n# Funciones de impresión\ndef error(text, bold=False): print(color_text(text, COLOR_RED, bold=bold))       ###--- ROJO ---###\ndef info(text, bold=False): print(color_text(text, COLOR_BLUE, bold=bold))       ###--- AZUL ---###\ndef info_2(text, bold=False): print(color_text(text, COLOR_CYAN, bold=bold))       ###--- CYAN ---###\ndef success(text, bold=False): print(color_text(text, COLOR_GREEN, bold=bold))    ###--- VERDE ---###\ndef warning(text, bold=False): print(color_text(text, COLOR_YELLOW, bold=bold))  ###--- AMARILLO ---###\ndef debug(text, bold=False): print(color_text(text, COLOR_PURPLE, bold=bold))    ###--- PURPURA ---###\ndef debug_2(text, bold=False): print(color_text(text, COLOR_GRAY, bold=bold))      ###--- GRIS ---###\ndef others(text, bold=False): print(color_text(text, COLOR_BLACK, bold=bold))    ###--- NEGRO ---###\ndef standard(text, bold=False): print(color_text(text, COLOR_WHITE, bold=bold))  ###--- BLANCO ---###\n\n# Función de captura de Ctrl+C\ndef sig_handler(sig, frame):\n    warning('\\n\\n[!] Ejecucion cancelada por el usuario ...\\n')\n    sys.exit(1)\n\nsignal.signal(signal.SIGINT, sig_handler)\n\n# Función para limpiar la terminal\ndef clean_terminal():\n    os.system('clear' if os.name == 'posix' else 'cls')\n\ndef welcome():\n    info('\\n\\n[+] Bienvenido al comprobador de palabras'.upper())\n    info_2('\\n[i] Introduzca una palabra para comprobar si es: Palindromo, Isograma, Anagrama')\n    info_2('[i] Para salir escriba pulse \"ctrl + C\"')\n\ndef user_input():\n    prompt_1 = '\\n[+] Escriba la primera palabra:'\n    prompt_2 = '\\n[+] Escriba la segunda palabra:'\n    \n    while True:\n        word_1 = input(''.format(info(prompt_1))).lower().strip()\n        word_2 = input(''.format(info(prompt_2))).lower().strip()\n        \n        # Comprobar que solo sean letras\n        if not word_1.isalpha() or not word_2.isalpha():\n            warning('[!] Solo se permiten palabras, evite números, símbolos y espacios.')\n        else:\n            return (word_1.lower(), word_2.lower())\n        \n# Comprabar si text_ y word_2 son un palindromo\ndef is_palindrome(word_1: str, word_2: str):\n    if word_1 == word_2[::-1]:\n        success(\"[+] Las palabras forman un palíndromo.\")\n    else:\n        error(\"[-] Las palabras no forman un palíndromo.\")\n\n# Comprobar si son isogramas\ndef is_isogram(word_1: str, word_2: str):\n    success(\"[+] La primera palabra es un isograma.\") if len(word_1) == len(set(word_1)) else error(\"[-] La primera palabra no es un isograma.\")\n    success(\"[+] La segunda palabra es un isograma.\") if len(word_2) == len(set(word_2)) else error(\"[-] La segunda palabra no es un isograma.\")\n    \n    word_3 = word_1 + word_2\n    success(\"[+] El conjunto de las dos palabras forman un isograma.\") if len(word_3) == len(set(word_3)) else error(\"[-] El conjunto de las dos palabras no forman un isograma.\")\n\n# Comprobar si es anagrama\ndef is_anagram(word_1: str, word_2: str):\n    success(\"[+] Las palabras son un anagrama.\") if sorted(list(word_1)) == sorted(list(word_2)) else error(\"[-] Las palabras no son un anagrama.\")\n\n\n# Entrada del programa\nif __name__ == '__main__':\n\n    clean_terminal()\n    welcome()\n    texts = user_input()\n    info_2('\\n[-]- SUS RESULTADOS -[-]\\n')\n    # Palindromo\n    is_palindrome(word_1=texts[0], word_2=texts[1])\n    # Isograma\n    is_isogram(word_1=texts[0], word_2=texts[1])\n    # Anagrama\n    is_anagram(word_1=texts[0], word_2=texts[1])\n    info_2('\\n[-]- FINAL -[-]\\n\\n')\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/majinka10.py",
    "content": "cadena = 'Hola Python!.'\n\nprint(f\"Acceso a un caracter: {cadena[0]}\")\nprint(f\"Subcadena: {cadena[0:5]}, resto de la cadena: {cadena[5:]}\")\nprint(f\"Longitud de la cadena: {len(cadena)}\")\nprint(f\"Concatenación a la cadena: {cadena + ' ' + 'Me gustas.'}\")\nprint(f\"Repetición de la cadena {cadena*2}\")\nprint(\"Recorrido de la cadena:\")\nfor char in cadena:\n    print(char)\nprint(f\"Toda la cadena en mayúsculas: {cadena.upper()}\")\nprint(f\"Toda la cadena en minúsculas: {cadena.lower()}\")\nprint(f\"Reemplazando en la cadena: {cadena.replace('Python', 'Guillermo')}\")\ncadena_dividida = cadena.split(' ')\nprint(f\"División de la cadena: {cadena_dividida[0]}, resto de la cadena: {cadena_dividida[1]}\")\ncadena_dos = 'I love Python.'\ntupla = (cadena, cadena_dos)\nprint(f\"Unión de cadenas: {' '.join(tupla)}\")\nprint(f\"Interpolación de cadenas. (lo he estado haciendo desde el inicio sin darme cuenta) {cadena} {cadena_dos}\")\nprint(\"Verificación.\")\npalabra = 'Queso'\nif palabra in cadena:\n    print(f'La palabra: {palabra}, está en la cadena.')\nelse:\n    print(f\"La palabra: {palabra}, no está en la cadena.\")\nprint(\"Búsqueda de subcadenas.\")\npalabra_dos = 'Python'\nif cadena.find(palabra_dos) > 0:\n    print(f\"La palabra: {palabra_dos}, está en el índice {cadena.find(palabra_dos)}\")\nelse:\n    print(f\"La palabra: {palabra_dos}, no está en la cadena.\")\ncadena_tres = '          Soy una cadena mala.    '\nprint(f\"Eliminación de espacios (inicio y final): {cadena_tres.strip()}\")\nprint(f\"Mayúsculas a minúsculas y visceversa: {cadena.swapcase()}\")\nprint(f\"Invertir cadena: {cadena[::-1]}\")\n\n# Ejercicio EXTRA\nprint(\"Ejercico EXTRA\")\ndef test_words(palabra1: str, palabra2: str):\n    palabra1 = palabra1.lower()\n    palabra2 = palabra2.lower()\n\n    # Palíndromos\n    def es_palindromo(palabra: str) -> bool:\n        if palabra == palabra[::-1]:\n            return True\n        else:\n            return False\n    print(f\"¿{palabra1.capitalize()} es palíndromo?: {es_palindromo(palabra1)}\")\n    print(f\"¿{palabra2.capitalize()} es palíndromo?: {es_palindromo(palabra2)}\")\n\n    # Anagramas\n    def son_anagramas(palabra1: str, palabra2: str) -> bool:\n        if sorted(palabra1) == sorted(palabra2):\n            return True\n        return False   \n    print(f\"¿Son {palabra1.capitalize()} y {palabra2.capitalize()} anagramas?: {son_anagramas(palabra1, palabra2)}\")\n\n    # Isogramas\n    def es_isograma(palabra: str) -> bool:\n        veces = palabra.count(palabra[0])\n        for char in palabra:\n            if palabra.count(char) != veces:\n                return False\n        return True\n    print(f\"¿{palabra1.capitalize()} es isograma?: {es_isograma(palabra1)}\")\n    print(f\"¿{palabra2.capitalize()} es isograma?: {es_isograma(palabra2)}\")\n    \ntest_words('Nacionalista', 'Altisonancia')\nprint()\ntest_words('murcielago', 'reconocer')\nprint()\ntest_words(\"radar\", \"pythonpythonpythonpython\")\nprint()"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/manjaitan.py",
    "content": "'''\n\n# #04 CADENAS DE CARACTERES\n> #### Dificultad: Media | Publicación: 22/01/24 | Corrección: 29/01/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n\n\n'''\n\n# Conversión a Mayúscula.\ncadena = \"Esto Es Una Cadena De Caracteres Mi Telefono es 777888999\"\nmayuscula = cadena.upper()\nprint (\"\")\nprint (mayuscula)\n\n# Conversión a Minuscula.\ncadena2 = \"Esto Es Una Cadena De Caracteres\"\ncadena2 = cadena2.lower()\nprint (\"\")\nprint (cadena2)\n\n# Conteo de digitos de la cadena\ncadena3 = \"Esto Es Una Cadena De Caracteres\"\ncadena3 = len(cadena3)\nprint (\"\")\nprint (cadena3)\n\n# Conteo de digitos de la cadena\ncadena4 = \"Esto Es Una Cadena De Caracteres\"\ncadena4 = len(cadena4)\nprint (\"\")\nprint (cadena4)\n\n# Conteo de digitos de la cadena\ncadena5 = \"Esto Es Una Cadena De Caracteres \"\ncadena6 = \"concatenamos otra cadena más\"\nconcatenado = cadena5 + cadena6\nprint (\"\")\nprint (concatenado)\n\n# Subcadenas.\ncadena7 = \"Esto es una cadena para tratar los substrigs\"\npos1 = 1\npos2 = 3\nsubcadena = cadena7[pos1:pos2]\nprint (\"\")  \nprint (subcadena)\n\n# Repeticion de cadenas.\ncadena8 = \"Esta es la cadena para el ejemplo de repeticion de cadenas - \"\nprint (\"\")\ncadena9 = cadena8 * 4\nprint (cadena9)\n\n# Recorridos de variables strings.\ncadena10 = \"Recorrido de variables\"\nprint (\"\")\nfor x in cadena10:\n    print (x)\n\n# Reemplazo.\ncadena11 = \"Reemplazo en variables , Reemplazo\"\nnuevacadena = cadena11.replace(\"Reemplazo\",\"Texto nuevo que reemplaza al texto Reemplazo - \")\nprint (nuevacadena)\n\n# Division en cadenas string.\ncadenaDivision = \"Esta cadena la vamos a dividir\"\ndividida = cadenaDivision.split()\nprint (\"\")\nprint (dividida)\n\n# Unión de cadenas string.\ncadenaUnir = \"Esta cadena la vamos a unir\"\ncadenadiv = cadenaUnir.split()\nprint (\"\")\nresultado = \",\".join(cadenadiv)\nprint (resultado)\n\n# interpolacion de strings.\na = 2000\nb = \"hola\"\nc = \"Clipper\"\nd = False\ne = 1900\n\nprint (\"\")\nprint (\"%d + 1200 = 3000\" % (a))\nprint (\"%s es un saludo incial para empezar una conversación, en Español es %s\" % (\"Hellow\", b ))\n\n# Verificación de palabras en strings.\nprint (\"\")\ncadenaVerif = \"Esta cadena es para verificar la existencia en strings\"\nencontrada = cadenaVerif.find(\"cadena\")\nprint (encontrada) # Nos indica con un número en que posición ha encontrado la cadena, en este caso la posición 5.\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/marcelosanchez166.py",
    "content": "#  EJERCICIO:\n#  Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n#  en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n#  - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n#    conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n\n#  DIFICULTAD EXTRA (opcional):\n#  Crea un programa que analice dos palabras diferentes y realice comprobaciones\n#  para descubrir si son:\n#  - Palíndromos\n#  - Anagramas\n#  - Isogramas\n\ncadena = \"Hola Mundo\"\nprint(\"Cadena original:\", cadena)\n\n# Acceso a caracteres específicos\nprint(\"Primer carácter:\", cadena[0])\nprint(\"Último carácter:\", cadena[-1])\n\n# Subcadenas\nprint(\"Subcadena (del 0 al 3 caracter sin incluir el 3 ):\", cadena[0:3])\nprint(\"Subcadena (del 5 al ultimo caracter ):\", cadena[5:])\n\n# Longitud\nprint(\"Longitud de la cadena:\", len(cadena))\n\n# Concatenación\ncadena2 = \" Python\"\ncadena_concatenada = cadena + cadena2\nprint(\"Cadena concatenada:\", cadena_concatenada)\n\n# Repetición\ncadena_repetida = cadena * 2\nprint(\"Cadena repetida:\", cadena_repetida)\n\n# Recorrido\nfor caracter in cadena:\n    print(caracter, end=' ')\nprint(\"\\nRecorrido completo de la cadena con un ciclo for:\", cadena)\n\n# Conversión a mayúsculas y minúsculas\nprint(\"Cadena en mayúsculas:\", cadena.upper())\nprint(\"Cadena en minúsculas:\", cadena.lower())\nprint(\"Cadena capitalizada:\", cadena.capitalize())\nprint(\"Cadena con título:\", cadena.title())\n\n# Conversión a lista de caracteres\nlista_caracteres = list(cadena)\nprint(\"Lista de caracteres, convirtiendo una cadena de caracteres a una lista:\", lista_caracteres)\n\n# Reemplazo\ncadena_reemplazada = cadena.replace(\"Mundo\", \"Python\")\nprint(\"Cadena reemplazada:\", cadena_reemplazada)\n\n# División\ncadena_dividida = cadena.split(\" \")\nprint(\"Cadena dividida con split :\", cadena_dividida)\nprint(type(cadena_dividida))  # Verifica el tipo de dato\n\n# Unión\ncadena_unida = \" \".join(cadena_dividida)\nprint(\"Cadena unida:\", cadena_unida)\nprint(type(cadena_unida))  # Verifica el tipo de dato\n\n# Interpolación (f-strings)\nnombre = \"Juan\"\nedad = 30\nprint(f\"Hola, mi nombre es {nombre} y tengo {edad} años.\")\n\n# Verificación\nprint(\"¿La cadena contiene 'Mundo'?\", \"Mundo\" in cadena)\nprint(\"¿La cadena empieza con 'Hola'?\", cadena.startswith(\"Hola\"))\n\n\n# un palíndromo es una palabra que se lee igual de izquierda a derecha que de derecha a izquierda\ndef es_palindromo(palabra):\n    # Eliminar espacios y convertir a minúsculas para la comparación\n    palabra = palabra.replace(\" \", \"\").lower()\n    return palabra == palabra[::-1]\n\n\ndef es_anagrama(palabra1, palabra2):  # un anagrama es una palabra formada por las letras de otra palabra\n    palabra1 = palabra1.replace(\" \", \"\").lower()  # remover espacios y convertir a minúsculas\n    palabra2 = palabra2.replace(\" \", \"\").lower()  # remover espacios y convertir a minúsculas\n    return sorted(palabra1) == sorted(palabra2)  # comparar las letras ordenadas de ambas palabras\n\n\ndef es_isograma(palabra):  # un isograma es una palabra en la que no se repite ninguna letra\n    palabra = palabra.replace(\" \", \"\").lower()\n    return len(palabra) == len(set(palabra))\n\n\ndef main():\n    palabra = \"Anita lava la tina\"\n    print(f\"¿'{palabra}' es un palíndromo?\", es_palindromo(palabra))\n\n    palabra1 = \"amor\"\n    palabra2 = \"roma\"\n    print(f\"¿'{palabra1}' y '{palabra2}' son anagramas?\", es_anagrama(palabra1, palabra2))\n\n    palabra3 = \"murcielago\"\n    print(f\"¿'{palabra3}' es un isograma?\", es_isograma(palabra3))\n\n\nif __name__ == \"__main__\":\n    main()\n\n\nfor i in range(1, 101):\n    if i % 3 == 0 and i % 5 == 0:\n        print(\"FizzBuzz\")\n    elif i % 3 == 0:\n        print(\"Fizz\")\n    elif i % 5 == 0:\n        print(\"Buzz\")\n    else:\n        print(i)\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/mariovelascodev.py",
    "content": "#String\n\nmy_string = \"Esto es una cadena de caracteres\"\nprint(my_string)\n\n#Formateo de cadenas\nnumber = 5\nstring_format = \"El número es: \" + str(number)\nprint(string_format)\n\nstring_format_1 = \"Los números son {} y {}\".format(5, 10)\nprint(string_format_1)\n\nstring_format_2 = \"Los números son {n1} y {n2}\".format(n1=15, n2=10)\nprint(string_format_2)\n\nn1 = 30\nn2 = 12\nstring_format_3 = f\"El resultado de sumar {n1} + {n2} = {n1+n2}\"\nprint(string_format_3)\n\n#Concatenar cadenas\nstring1 = \"Hola\"\nstring2 = \"Mundo\"\nprint(string1+\" \"+ string2)\n\n#Multiplicar string por un int\nprint(string1*3)\n\n#Saber si una cadena contiene otra cadena\nprint(\"mola\" in \"Python mola\")\n\n#Longitud de una cadena\nprint(len(my_string))\n\n#Acceder a una posición de la cadena\nprint(my_string[6])\nprint(my_string[-1]) #accede a la última posición\nprint(my_string[0:10])#accede desde la posición 0 a la 12 \nprint(my_string[10:])#accede desde la posición indicada hasta el final\n\n#Métodos\n#capitalize() Pone la primera letra en mayúscula\nprint(my_string.capitalize())\n\n#lower() Convierte la cadena a minúsculas\nstring3 = \"Hola MUNDO\"\nprint(string3.lower())\n\n#swapcase() Convierte los caracteres alfabéticos con mayúsculas en minúsculas y viceversa\nprint(string3.swapcase())\n\n#upper Convierte la cadena a mayúsculas\nprint(string3.upper())\n\n#count Cuenta las veces que la cadena indicada aparece en una cadena\nprint(my_string.count(\"ca\"))\n\n#isalnum() Devuelve True si la cadena esta formada únicamente por caracteres alfanuméricos y False al contrario\nprint(my_string.isalnum())\n\n#strip() Elimina los espacios en blanco de izquierda y derecha\nstring4 = \"           Aquí no hay espacios   \"\nprint(string4)\nprint(string4.strip())\n\n#join devuelve la primera cadena unida a cada uno de los elementos de la lista que se le pasa como parámetro\nstring5 = \" y \"\nprint(string5.join([\"1\",\"2\",\"3\"]))\n\n#split() Divide una cadena en subcadenas y las devuelve almacenadas en una lista\nlanguages = \"Python, Java, C\"\nprint(languages.split(\",\"))\n\nprint(\"\\n----------------------------\")\nprint(\"EXTRA\")\n\n#EXTRA\ndef validate_word(word1, word2):\n    word1_lower = word1.lower()\n    word2_lower = word2.lower()\n\n    #Palíndromo\n    #Se ordena la palabra a la inversa\n    word1_reverse = word1_lower[::-1]\n    word2_reverse = word2_lower[::-1]\n    \n    #Comparamos si las palabras original y la inversa para ver si son iguales\n    if word1_lower == word1_reverse and word2_lower == word2_reverse:\n        print(f\"Las palabras {word1} y {word2} son palíndromos\\n\")\n    elif word1_lower == word1_reverse and word2_lower != word2_reverse:\n        print(f\"La palabra {word1} es un palíndromo\\n\")\n    elif word1_lower != word1_reverse and word2_lower == word2_reverse:\n        print(f\"La palabra {word2} es un palíndromo\\n\")\n    else:\n        print(f\"Las palabras {word1} y {word2} no son un palíndromo\\n\")\n    \n    #Anagrama\n    #Con el método sorted() convertimos el string en una lista y la ordenamos, se comparan ambas lista para ver si son iguales\n    if sorted(word1_lower) == sorted(word2_lower):\n        print(f\"La palabra {word1_lower} es un anagrama de la palabra {word2_lower}\\n\")\n    else:\n        print(f\"La palabra {word1_lower} no es un anagrama de la palabra {word2_lower}\\n\")  \n        \n    #Isograma\n    if len(word1_lower) == len(set(word1_lower)) and len(word2_lower) == len(set(word2_lower)):\n        print(f\"{word1_lower} y {word2_lower} son isogramas\\n\")\n    elif len(word1_lower) == len(set(word1_lower)) and len(word2_lower) != len(set(word2_lower)):\n        print(f\"{word1_lower} es un isograma\\n\")\n    elif len(word1_lower) != len(set(word1_lower)) and len(word2_lower) == len(set(word2_lower)):\n        print(f\"{word2_lower} es un isograma\\n\")\n    else:\n        print(print(f\"{word1_lower} y {word2_lower}  no son isogramas\\n\"))\n\nvalidate_word(\"Ana\", \"camion\")\nvalidate_word(\"frase\", \"fresa\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/maxiRica.py",
    "content": "\"\"\"\nVamos con las cadenas de carácteres\n- Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\nconversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n \"\"\"\n\nimport os #importamos la libreria del sistema para poder hacer uso del bash\nimport textwrap\ndef limpiar(): #creamos la función para limpiar la pantalla para poder aplicarla las veces que necesitemos sin repetir código\n    while True:\n\n        pregunta=input(\"quieres que limpie la pantalla? (si - no): \")\n        if pregunta==\"si\":\n        \n            if os.name==\"posix\":\n                os.system(\"clear\")\n                break\n            else:\n                os.system(\"cls\")\n                break\n        elif pregunta==\"no\":\n            break\n    \n#Pregunto si limpio la consola\n\nlimpiar()\n\n\n#CREO LA VARIABLE CON LA CADENA DE TEXTO\n\ncadena_texto=\"Acceso a caracteres específicos, subcadenas, longitud, concatenación,\"\\\n     \"repetición, recorrido, conversión a mayúsculas y minúsculas, reemplazo, división,\"\\\n     \"unión, interpolación, verificación...\\n\"\n\nprint(cadena_texto)\n\n# 1. Longitud de la Cadena\n\nprint(\"#1. LONGITUD DE LA CADENA\")\nprint(len(cadena_texto))\nprint(\"\\n\")\n\n# 2. Acceso a caracteres específicos\n\nprint(\"#2. ACCESO A UN CARÁCTER\\n\")\nprint(\"Vamos acceder a un punto concreto del indice de la cadena. Vamos a pedir que posición quiere el usuario\\n\")\nwhile True:\n    try:\n        pregunta=int(input(\"dame el número del indice en la cadena anterior para mostrar el carácter: \"))\n        if pregunta<0 or pregunta>= len(cadena_texto):\n            raise IndexError\n        break\n    except ValueError:\n        print(\"\\n\")\n        print(\"ERROR. Ingresa un valor entero\")\n    except IndexError:\n        print(\"ERROR. Has puesto un valor fuera del rango de la cadena\")\n\nprint(f\"el carácter es el: {cadena_texto[pregunta]}\\n\")\n\n# 3. Acceso a subcadenas (slicing)\n\nprint(\"#3. ACCESO A SUBCADENAS (SLICING)\\n\")\nwhile True:\n    try:\n        inicio=int(input(\"ingresa el número de inicio del indice la cadena: \\n\"))\n        final=int(input(\"ingresa el final del indice de la cadena: \\n\"))\n        if inicio>final:\n            print(\"el primer valor a de ser inferior al segundo\\n\")\n            continue\n        break\n    except ValueError:\n        print(\"\\n\")\n        print(\"ERROR. Ingresa un valor entero\")\n    \n\nprint(f\"la cadena resultante es: {cadena_texto[inicio:final]}\\n\")\n\n# 4. Concatenación\n\nprint(\"#4. CONCATENACIÓN\")\n\nwhile True:\n    try:\n        print(\"Vamos a concatenar dos candenas\\n\")\n        print(\"antes decide que tipo de concatenació:\\n\")\n        print(\"1- enganchar dos palabras como una compuesta\\n\")\n        print(\"2- concatenar dos palabras individuales con espacio entre ellas\\n\")\n        opcion=int(input(\"Que opción quieres: \\n\"))\n    except ValueError:\n        print(\"\\n\")\n        print(\"ERROR. Ingresa un valor entero\")\n    if opcion==1:\n        print(\"has escogido la opción 1\\n\")\n        primera_cadena=input(\"escribe la primera cadena :\")\n        segunda_cadena=input(\"escribe la segunda cadena: \")\n        print(\"la concatenación es: \")\n        print(primera_cadena + segunda_cadena)\n        break\n    elif opcion==2:\n        print(\"has escogido la opción 2\")\n        primera_cadena=input(\"escribe la primera cadena :\")\n        segunda_cadena=input(\"escribe la segunda cadena: \")\n        print(\"la concatenación es: \")\n        print(primera_cadena + \" \" + segunda_cadena)\n        break\n    elif opcion<0 and opcion>1:\n        print(\"ERROR. Introduce 1 o 2\\n\")\n\n# 5. Repetición de Cadenas. Se trata de repetir la cadena las veces que le indiques\n\nprint(\"\\n#5. REPETICIÓN DE CADENAS\\n\")\nprint(\"Vamos a realizar una repetición de la misma cadena, tantas veces le indiques\\n\")\nwhile True:\n    frase=input(\"dime la cadena a repetir: \\n\")\n    try:\n        repeticion=int(input(\"indica las veces que se ha de repetir la cadena: \"))\n        cadena=frase*repeticion\n        print(cadena+\"\\n\")\n        break\n    except ValueError:\n        print(\"ERROR. Ingresa un valor entero\")\n        \n# 6. Conversión a Mayúsculas y Minúsculas\n\nprint(\"\\n#6. CONVERSIÓN A MAYÚSCULAS Y MINÚSCULAS\\n\")\nprint(\"Empezamos con la conversión de minúsculas a mayúsculas\\n\")\nfrase=input(\"dime la frase: \")\nfrase2=frase.upper()\nprint(\"\\n\"+frase2+\"\\n\")\n\nprint(\"Empezamos con la conversión de mayúsculsa a minúsculas\\n\")\nfrase=input(\"dime la frase: \")\nfrase2=frase.lower()\nprint(\"\\n\"+frase2)\n\n# 7. Recorrido por la cadena\nprint(\"\\n#7. RECORRIDO POR LA CADENA\\n\")\nprint(f\"cogeremos la frase inicial: {cadena_texto}\\n\")\nprint(\"vamos a imprimir carácter a carácter separado cada uno del otro, haciendo una iteración por toda la cadena\\n\")\nprint(\"para eso, luego vamos a usar la función print(cadena, end=\\\" \\\"). Con el parámetro end añadimos despues del string un carácter o espacio\")\nfor i in cadena_texto:\n    print(i,end=\" \")\nprint(\"\\n\")\n\n# 8. Reemplazo de Subcadenas\nprint(\"#8. REEMPLAZO DE SUBCADENAS\\n\")\ncadena=input(\"que cadena es la muestra donde vamos a realizar el cambio: \")\nantigua=input(\"\\nindicame la cadena que quieres substituir: \")\nnueva=input(\"\\nindicame la cadena nueva: \")\ncadena=cadena.replace(antigua,nueva)\nprint(f\"\\nLa cadena ha quedado así: {cadena}\\n\")\n\n# 9. División de Cadenas\nprint(\"\\n#9. División de Cadenas\\n\")\nprint(\"Vamos a proceder a realizar una división de una cadena. Lo realizaremos con la función .split()\")\ncadena=input(\"pasame la cadena para después dividirla: \")\nlista_cadenas=cadena.split()\nprint(\"\\nHemos creado una lista con las cadenas divididas por un espacio (frases).\\\n       Si quieres separar por un indicador se ha de proceder indicandolo\\n\")\nprint(f\"la lista es: {lista_cadenas}\")\nprint(\"\\nAhora vamos a indicar también cual será el separador\\n\")\nseparador=input(\"dame el separador: \")\nlista_cadenas2=cadena.split(separador)\nprint(f\"La lista es: {lista_cadenas2}\")\n\n# 10. Unión de cadenas\nprint(\"# 10. UNIÓN DE CADENAS\\n\")\nprint(\"Esta función (.join()) hace la función inversa a la .splint()\\n\")\nprint(f\"Vamos a usar la lista anterior que hemos creado: {lista_cadenas}\\n\")\ncadena_nueva=\" \".join(lista_cadenas)\nprint(cadena_nueva)\n\n# 11. Interpolación de cadenas\nprint(\"\\n# 11. INTERPOLACIÓN DE CADENAS\\n\")\nprint(\"Tenemos diferentes sistemas de interpolación, el más habitual es el F-strings:\\n\")\nprint(\"1. F-strings: print(f\\\"cadena {variable})\\n\")\nprint(\"2. Str.format()\\n\")\nprint(\"inciamos con la F-str\")\nfrase1=input(\"dame la primera frase: \\n\")\nfrase2=input(\"dame la segunda frase: \\n\")\nprint(f\"vamos a añadir al print la primera frase: ({frase1}) y la segunda frase: ({frase2})\\n\") #usamos la F-Str para introducir cadenas\nprint(\"vamos a usar el .format(). Requiere que introduzca los datos según lo siguiente:\\n\") \nprint(\"variable=\\\"estoy en {cadena1\\} y quiero ir a {cadena2\\}.format(cadena1=\\\"STR\\\",cadena2=\\\"STR\\\")\\n\")\nprint(\"luego imprimimos con un print la variable\")\ncadena1=input(\"dame la primera cadena que ha de ser el nombre de una ciudad: \\n\")\ncadena2=input(\"dame la segunda cadena que ha de ser el nombre de otra ciudad: \\n\")\nmensaje=\"estoy en {frase1} y quiero ir a {frase2}\".format(frase1=cadena1,frase2=cadena2) # usamos la función .format\nprint(mensaje+\"\\n\")\n\n# 12. VERIFICACIÓN DE PROPIEDADES DE CADENAS\nprint(\"# 12. VERIFICACIÓN DE PROPIEDADES DE CADENAS\\n\")\nprint(\"Tipos de verificación: \\n\")\n\n#Verifico si la cadena es de caracter alfabéticos\nprint(\"1. Verifica si los carácteres son letras con la función .isalpha()\\n\")\ncadena=input(\"introduce una palabra (no una frase o dará error) para verificar si son letras: \") \nverifica=cadena.isalpha()       #compruebo si los carácteres son alfabeto, y si es cierto devuelvo True\nif verifica==True:\n    print(\"son carácteres alfabéticos\\n\")\nelse:\n    print(\"no es una cadena de carácteres alfabéticos\\n\")\n\n#si es una frase genero una lista separando las palabras con un .split() y luego lo proceso\nprint(\"puedo comprobar si se usa una frase, palabra a palabra. Para eso usaré un bucle y la función all()\\n\")\ncadena=input(\"introduce una frase para verificar si son letras: \")\nfrase=cadena.split()\nalphabet=all(caracter.isalpha() for caracter in frase)\nif alphabet:\n    print(\"son caracteres alfabéticos\\n\")\nelse:\n    print(\"no todos son carácteres alfabéticos\\n\")\n\n#Verifico si la cadena es alfanumérica\nprint(\"2. Verifica si los carácteres son alfanuméricos con la función .isalnum()\\n\")\nfrase=input(\"introduce la cadena: \\n\")\nverifica=frase.isalnum()        #realizo la compovación de si los carácteres son alfanumérico\nif verifica:\n    print(\"son alfanuméricos\\n\")\nelse:\n    print(\"no son alfanuméricos\\n\")\n\n#vuelvo a separar en una lista mediante un .split()\nfrase=input(\"escribe la frase alfanumérica a identificar: \\n\")\nlista=frase.split()\nnumeros=all(num.isalnum() for num in lista)\nif numeros:\n    print(\"todos son alfanúmericos\\n\")\nelse:\n    print(\"no todos son alfanúmericos\")\n\n#Verifico si la cadena es numérica\nprint(\"3. Verifica si los carácteres son numéricos con la función .isdigit()\\n\")\nfrase=input(\"introduce la cadena: \\n\")\nverifica=frase.isdigit()        #realizo la compovación de si los carácteres son numéricos\nif verifica:\n    print(\"son numéricos\\n\")\nelse:\n    print(\"no son numéricos\\n\")\n\n#vuelvo a separar en una lista mediante un .split()\nfrase=input(\"introduce la cadena separada por espacios\\n\")\nlista=frase.split()\nnumeros=all(num.isdigit() for num in lista)\nif numeros:\n    print(\"todos son números\\n\")\nelse:\n    print(\"no todos son números\")\n\n#Verifico si la cadena es un espacio en blanco\nprint(\"4. Verifica si la cadena es un espacio en blanco con la función .isspace()\\n\")\nfrase=input(\"introduce la cadena: \\n\")\nverifica=frase.isspace()        #realizo la compovación de si es un espacio en blanco\nif verifica:\n    print(\"es un espacio en blanco\\n\")\nelse:\n    print(\"no es un espacio en blanco\\n\")\n\n# EJERCICIOS DIFICULTAD EXTRA\n\n#Palíndromos\nlimpiar() #Iniciamos limpiando la pantalla si el usuario nos lo indica\nprint(\"#######################\")\nprint(\"#                     #\")\nprint(\"#     PALÍNDROMOS     #\")\nprint(\"#                     #\")\nprint(\"#######################\")\ntexto=(\n    \"Un palíndromo es una palabra, frase, número o cualquier otra secuencia de caracteres\"\n    \"que se lee igual de izquierda a derecha que de derecha a izquierda, ignorando los espacios,\"\n    \"la puntuación y la acentuación. Es decir, su orden se mantiene al revés, lo cual hace que se\" \n    \"pueda leer de forma idéntica en ambas direcciones.\"\n)\nparagrafo=textwrap.fill(texto,80)\nprint(\"\\n\"+paragrafo+\"\\n\")\nfrase=input(\"introduce el palíndromo: \")\nfrase=frase.replace(\" \",\"\").lower() #ponemos todos los carácteres en minúsculas y quitamos posibles espacios\npalindromo=frase\nfrase=list(frase)\npalindromo=list(palindromo)\npalindromo.reverse()\npalCert=True\nfor i in range(len(frase)):\n    if frase[i] != palindromo[i]: \n        palCert=False\n        break\nif palCert:\n    print(\"\\nES UN PALÍNDROMO\\n\")\nelse:\n    print(\"\\nNO ES UN PALÍNDROMO\\n\")\n\n# ANAGRAMA\n\nlimpiar()\n\nprint(\"#################\")\nprint(\"#               #\")\nprint(\"#   ANAGRAMA    #\")\nprint(\"#               #\")\nprint(\"#################\")\n\ntexto=(\n    \"Un anagrama es una palabra o frase formada al reorganizar\"\n     \"las letras de otra palabra o frase, usando todas las letras\" \n     \"una sola vez. Por ejemplo, \\\"amor\\\" es un anagrama de \\\"Roma\\\"\"\n)\nparagrafo=textwrap.fill(texto,80)\nprint(\"\\n\"+paragrafo+\"\\n\")\nprint(\"\\nVamos a introducir dos frases y comprobar si la segunda es un anagrama de la segunda\\n\")\nprint(textwrap.fill(\"No se verificará si la frase tiene coherencia o sentido lingüístico, únicamente se evaluará si las letras se reorganizan correctamente en un anagrama\",80))\n\n# iniciamos la petición de las frases\nwhile True:    \n    primera_frase=input(\"\\nintroduce la primera frase: \")\n    anagrama=input(\"\\nintroduce la segunda frase. El anagrama: \")\n\n    primera_frase=primera_frase.replace(\" \",\"\").lower() #ponemos en minúsculas los carácteres y quitamos los espacios\n    anagrama=anagrama.replace(\" \",\"\").lower() #ponemos en minúsculas los carácteres y quitamos los espacios\n\n    # comprobamos que la longitud de las dos cadenas sean iguales\n    if len(primera_frase)==len(anagrama):\n        break\n    else:\n        print(\"\\nERROR. Introduce frases del mismo tamaño\\n\")\n\n#ordenamos las cadenas convirtiendolas en listas ordenadas\nprimera_frase=sorted(primera_frase)\nanagrama=sorted(anagrama)\n\nif primera_frase==anagrama:\n    print(\"\\nEs un anagrama\\n\")\nelse:\n    print(\"\\nNo es un anagrama\\n\")\n\n# ISOGRAMA\n\n# ANAGRAMA\n\nlimpiar()\n\nprint(\"#################\")\nprint(\"#               #\")\nprint(\"#    ISOGRAMA   #\")\nprint(\"#               #\")\nprint(\"#################\")\n\ntexto=(\n    \"Un isograma es una palabra o frase en la que ninguna letra se repite.\" \n    \"Cada letra aparece solo una vez, sin importar si son mayúsculas o minúsculas.\" \n    \"Un ejemplo de isograma es la palabra \\\"murciélago\\\", ya que todas sus letras son diferentes.\"\n)\n\nprint(textwrap.fill(texto,80))\n\n# Iniciamos con la introducción de la frase\nfrase=input(\"introduce la frase a analizar: \\n\")\nfrase=frase.replace(\" \",\"\").lower()  # quito espacios y lo paso todo a minúsculas para evitar errores en la comparación\nisograma=set()\nlista=list(frase)\n\n# Iniciamos unta iteración por la lista creada de la frase introducida y añadimos los carácteres en el set()\nfor car in lista:\n    isograma.add(car)\nif len(lista)==len(isograma):\n    print(\"\\nEs un ISOGRAMA\\n\")\nelse:\n    print(\"\\nNo es un ISOGRAMA\\n\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/mensius87.py",
    "content": "\"\"\"04 CADENAS DE CARACTERES\nDificultad: Media | Publicación: 22/01/24 | Corrección: 29/01/24\n\nEjercicio\n\n/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n   en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n   para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\"\"\"\n\n\ntexto_1 = \"    la casa es roja y dentro está la caja\"\ntexto_2 = \"el coche tiene cuatro ruedas\"\ntexto_3 = \"2342\"\n\nprint(\":::::::::::::::::::: MÉTODOS CON CADENAS ::::::::::::::::::::\")\nprint()\nprint(f\"Texto original 1: {texto_1.capitalize()}\")\nprint(f\"Texto original 2: {texto_2.capitalize()}\")\nprint()\n\n# Capitalize: pone la primera letra del string en mayúscula\nprint(f\"Método capitalize: {texto_1.capitalize()}\")\n\n# Center: centra el texto con dejando un espacio en los laterales con el número de caracteres indicado o un caracter\n#         en caso de poner un segundo parámetro\nprint(f\"Método center: [{texto_1.center(30)}] \")\nprint(f\"Método center: [{texto_1.center(30, '*')}] \")\n\n# Endswith: devuelve true o false si la cadena termina con el argumento especificado\nprint(f\"Método endswith: la frase acaba en ja --> {texto_1.endswith(\"ja\")}\")\nprint(f\"Método endswith: la frase acaba en on --> {texto_1.endswith(\"on\")}\")\n\n\n# Startswith: devuelve true o false si la cadena termina con el argumento especificado\nprint(f\"Método startswith: la frase empieza con un espacio --> {texto_1.startswith(\" \")}\")\nprint(f\"Método startswith: la frase empieza por 'on' --> {texto_1.startswith(\"on\")}\")\n\n\n# Find: devuelve la primera ocurrencia en una cadena de la subcadena indicada en el parámetro. Con un segundo parámetro,\n#       se especifica en qué posición empieza a buscar\nprint(f\"Método find: posición {texto_1.find(\"ro\")}\")\nprint(f\"Método find: posición {texto_1.find(\"ro\", 12)}\")\n\n\n# Isalnum: cualquier elemento de cadena que no sea un dígito o una letra hace que el método regrese False.\n#          Los espacios en blanco no cuentan como letra ni número, por tanto, de haberlos resultará False.\nif texto_1.isalnum():\n    print(f\"Método Isalnum: '{texto_1}' solo contiene letras y/números\")\nelse:\n    print(f\"Método Isalnum: '{texto_1}' no contiene letras ni números\")\n\n\n# Isalpha: comprueba que todos los caracteres de la cadena sean letras. De ser así, dará True. El espacio no cuenta como\n#          letra, por tanto, de haberlo dará False.\nif texto_1.isalpha():\n    print(f\"Método isalpha: el texto solamente contiene letras\")\nelse:\n    print(f\"Método isalpha: el texto contiene algo que no son letras\")\n\n\n# Isdigit: comprueba que todos los caracteres de la cadena sean dígitos. De ser así, dará True. El espacio no cuenta\n#          como dígito, por tanto, de haberlo dará False.\nif texto_3.isdigit():\n    print(f\"Método isdigit: el texto solamente contiene dígitos\")\nelse:\n    print(f\"Método isdigit: el texto contiene algo que no son dígitos\")\n\n\n# Islower: comprueba que solo haya minúsculas. Los espacios no se tienen en cuenta.\nif texto_1.islower():\n    print(f\"Método islower: el texto solamente contiene minúsculas\")\nelse:\n    print(f\"Método islower: el texto contiene algo que no son minúsculas\")\n\n\n# Isupper: comprueba que solo haya mayúsculas. Los espacios no se tienen en cuenta.\nif texto_1.isupper():\n    print(f\"Método isupper: el texto solamente contiene mayúsculas\")\nelse:\n    print(f\"Método isupper: el texto contiene algo que no son mayúsculas\")\n\n\n# isspace: comprueba si sólamente hay espacios en blanco (si hay algún otro caracter, da false)\nif texto_1.isspace():\n    print(f\"Método isspace: el string solamente contiene espacios\")\nelse:\n    print(f\"Método isspace: el string no contiene solamente espacios\")\n\n\n# Lstrip: elimina todos los espacios en blanco de una cadena. Si tiene un argumento, eliminar todos los carateres\n#          iniciales que estén en dicho argumento\nprint(f\"Método lstrip: {texto_1.lstrip()}\")\nprint(f\"Método lstrip con argumento: {texto_1.lstrip(\" la\")}\")\n\n\n# Rstrip: lo mismo que lstrip pero empezando por el final de string\nprint(f\"Método rstrip: {texto_1.rstrip()}\")\nprint(f\"Método rstrip con argumento: {texto_1.rstrip(\" la\")}\")\n\n\n# Replace: con dos parámetros devuelve una copia de la cadena original en la que todas las apariciones del primer\n#          argumento han sido reemplazadas por el segundo argumento.\nprint(f\"Método replace: {texto_1.replace(\" \", \"*\")}\")\n\n\n# Split: El método split() divide la cadena y crea una lista de todas las subcadenas detectadas. El método asume que\n#        las subcadenas están delimitadas por espacios en blanco, los espacios no participan en la operación y no se\n#        copian en la lista resultante.\nprint(f\"Método split: {texto_1.split()} \")\n\n\n# Strip: combina los efectos causados por rstrip() y lstrip(), crea una nueva cadena que carece de todos los espacios\n#        en blanco iniciales y finales.\nprint(f\"Método strip: {texto_1.strip()}\")\n\n\n# Swapcase: crea una nueva cadena intercambiando todas las letras por mayúsculas o minúsculas dentro de la cadena\n#           original: los caracteres en mayúscula se convierten en minúsculas y viceversa.\nprint(f\"Método swapcase{texto_1.swapcase()}\")\n\n\n# Upper: hace una copia de la cadena de origen, reemplaza todas las letras minúsculas con sus equivalentes en\n#        mayúsculas, y devuelve la cadena como resultado.\nprint(f\"Método upper: {texto_1.upper()}\")\n\n# Lower: hace una copia de la cadena de origen, reemplaza todas las letras mayúsculas con sus equivalentes en\n#        minúsculas, y devuelve la cadena como resultado.\nprint(f\"Método lower: {texto_1.lower()}\")\n\n\nprint()\nprint(\"::::::::::::::::::::::::::::::::::::: EXTRA :::::::::::::::::::::::::::::::::::::\")\nprint()\n\n# Palíndromo:\ndef palindromo(texto):\n\n    texto_sin_espacios = texto.replace(\" \", \"\")\n    texto_invertido_sin_espacios = texto[::-1].replace(\" \", \"\")\n\n    if texto_sin_espacios == texto_invertido_sin_espacios:\n        print(f\"'{texto}' es palíndromo.\\n\")\n    else:\n        print(f\"'{texto}' no es palíndromo.\\n\")\n\n\n# Anagrama:\ndef anagrama(palabra_1, palabra_2):\n    palabra_1_minusculas = palabra_1\n    palabra_2_minusculas = palabra_2\n\n    if sorted(palabra_1_minusculas) == sorted(palabra_2_minusculas):\n        print(f\"las plabras '{palabra_1_minusculas}' y '{palabra_2_minusculas}' son anagramas.\\n\")\n    else:\n        print(f\"las plabras '{palabra_1_minusculas}' y '{palabra_2_minusculas}' no son anagramas.\\n\")\n\n\n# Isograma:\ndef isograma(palabra):\n\n    lista_letras = []\n    isograma = False\n\n    for letra in palabra:\n\n        if letra not in lista_letras:\n            lista_letras.append(letra)\n            isograma = True\n        else:\n            isograma = False\n            print(f\"No es un isograma, hay letras repetidas en la palabra '{palabra}'.\")\n            break\n\n    if isograma:\n        print(f\"La palabra '{palabra}' es un isograma: no tiene letras repatidas.\")\n\n\n\nopcion_elegida = 0\n\nwhile opcion_elegida != 4:\n\n    # Creación del menú y bucle\n    print(\n\n        \"\"\"¿Qué deseas hacer?:\n\n              [1] - Comprobar palíndromo\n              [2] - Comprobar anagramas\n              [3] - Comprobar isograma\n              [4] - Salir\"\"\"\n    )\n\n    opcion_elegida = int(input())\n\n    match opcion_elegida:\n        case 1:\n            texto = input(\"Introduce palabra o frase para comprobar si es un palíndromo: \")\n            palindromo(texto)\n        case 2:\n            palabra_1 = input(\"Introduce la primera palabra para comprobar si es un anagrama de la segunda: \")\n            palabra_2 = input(\"Introduce la primera palabra para comprobar si es un anagrama de la primera: \")\n            anagrama(palabra_1, palabra_2)\n        case 3:\n            palabra = input(\"Introduce palabra o frase para comprobar si es un isograma: \")\n            isograma(palabra)\n        case 4:\n            print(\"Gracias por utilizar el comprobador de cadenas. ¡Hasta pronto!\")\n            opcion_elegida = 4\n            pass"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/mhayhem.py",
    "content": "# Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n# en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n# - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n#   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n\nmy_string = \"hola python\"\n\n# acceso por índice\nprint(my_string[3]) # \"a\"\n\n# convertir string en minusculas\nprint(my_string.casefold()) # hola python a diferencia de lower actua con caracteres especiales de algunos idiomas\nprint(my_string.lower()) # hola python\n\n# convertir string a mayusculas\nprint(my_string.upper()) # HOLA PYTHON  transforma todos los caracteres a mayúsculas\nprint(my_string.capitalize()) # Hola Python solo transforma la primera letra del string\nprint(my_string.title()) # Hola Python transforma las primera letra despues de un espacio\n\n# reemplazar caracteres\nprint(my_string.swapcase()) # HOLA PYTHON invierte las mayúsculas y minúsculas\nprint(my_string.replace(\"a\", \"4\")) # hol4 python reemplaza un carácter por otro\n\n# comprobación\nprint(my_string.isalnum()) # False comprueba si es un número\nprint(my_string.isalpha()) # False comprueba si todos los caracteres son letras, si hay números, espacios, simbolos o signos de puntuación devuelve devuelve False\nprint(my_string.isascii()) # True comprueba que todos los caracteres sean caracteres dentro de ASCII\nprint(my_string.startswith(\"h\")) # True comprueba que el string empiece por un caracter específico\nprint(my_string.endswith(\"n\")) # True comprueba que la string finalice con un csracter específico \n\n# operaciones varias\nprint(\" \".join([\"hola\", \"mundo\"])) # hola mundo  une elementos interables(lista, tupla) con lo que haya en la cadena\nprint(my_string.encode()) # b'hola python' transforma la string en una secuencia de bytes\nprint(my_string.count(\"o\")) # 2 cuenta el numero de veces que aparece el carárater indicado\nprint(my_string.find(\"s\")) # -1 busca el caracter indicado y devuelve su índice, si no encontrase el carácter devuelve -1\nprint(my_string.split(\" \")) # [\"hola\", \"python\"] devuelve una lista las subcadenas que se crean ha partir del carácter indicado\nprint(\"esto es un {}\".format(my_string)) # esto es un hola python inserta una variable en una string, actualmente se usa mas f\"str {var}\"\n\n\n# DIFICULTAD EXTRA (opcional):\n# Crea un programa que analice dos palabras diferentes y realice comprobaciones\n# para descubrir si son:\n# - Palíndromos\n# - Anagramas\n# - Isogramas\n\n\ndef checking_words(text_1, text_2):\n    print(f\"¿Las palabras {text_1} y {text_2} son isogramas? {set(text_1.lower()) != set(text_2.lower())}\")\n    print(f\"¿Las palabras {text_1} y {text_2} son anagramas? {sorted(text_1.lower()) == sorted(text_2.lower())}\")\n    print(f\"¿Las palabras {text_1} y {text_2} son palíndromas entre sí? {text_1.lower() == text_2.lower()[::-1]}\")\n    print(f\"¿La palabra {text_1} es palíndroma? {text_1.lower() == text_1.lower()[::-1]}\")\n    print(f\"¿La palabra {text_2} es palíndroma? {text_2.lower() == text_2.lower()[::-1]}\")\n    \nchecking_words(\"Dany\", \"Ynad\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/miguelex.py",
    "content": "# Operaciones básicas sobre cadenas de texto\ntexto = \"Hola, mundo!\"\n\n# Interpolación de cadenas (uso de plantillas de cadena)\nnombre = \"Migue\"\nlenguaje = \"PHP\"\nmensaje = f\"Hola, me llamo {nombre} y trabajo con {lenguaje} años.\"\nprint(mensaje)\n\n# Longitud de la cadena\nlongitud = len(texto)\nprint(f\"La longitud de la cadena {texto} es {longitud} caracteres\")\n\n# Obtener el carácter en una posición específica\nprimerCaracter = texto[0]\nprint(f\"El primer carácter de {texto} es {primerCaracter}\")\n\n# Concatenar dos cadenas\nnuevaCadena = texto + \" Python\"\nprint(f\"La nueva cadena de unir {texto} con Python es {nuevaCadena}\")\n\n# Convertir la cadena a minúsculas\nminusculas = texto.lower()\nprint(f\"{texto} en minúsculas es {minusculas}\")\n\n# Convertir la cadena a mayúsculas\nmayusculas = texto.upper()\nprint(f\"{texto} en mayúsculas es {mayusculas}\")\n\n# Obtener una subcadena\nsubcadena = texto[0:4]\nprint(f\"La subcadena de {texto} entre las posiciones 0 y 4 es {subcadena}\")\n\n# Reemplazar parte de la cadena\nreemplazada = texto.replace(\"Hola\", \"Saludos\")\nprint(f\"Vamos a reemplazar Hola por Saludos: {reemplazada}\")\n\n# Operaciones adicionales sobre cadenas de texto\ntextoConEspacios = \"   Hola,      mundo!   \"\n\n# Eliminar espacios en blanco al principio y al final\nsinEspaciosExtremos = textoConEspacios.strip()\nprint(f\"Cadena sin espacios al principio y al final: {sinEspaciosExtremos}\")\n\n# Eliminar todos los espacios en blanco\nsinEspacios = textoConEspacios.replace(\" \", \"\")\nprint(f\"Cadena sin espacios: {sinEspacios}\")\n\n# Unión de dos cadenas\ncadena1 = \"Moure\"\ncadena2 = \"Dev\"\nunionCadenas = f\"{cadena1} {cadena2}\"\nprint(f\"La unión de las cadenas {cadena1} y {cadena2} es {unionCadenas}\")\n\n# Intersección de dos cadenas (caracteres comunes)\ninterseccionCadenas = ''.join(set(cadena1) & set(cadena2))\nprint(f\"Intersección de las cadenas {cadena1} y {cadena2} es {interseccionCadenas}\")\n\n# Acceso a caracteres específicos (por posición)\ntercerCaracter = texto[2]\nprint(f\"El tercer carácter de {texto} es {tercerCaracter}\")\n\n# Repetición de una cadena\ncadenaRepetida = \"Hola \" * 3\nprint(f\"Cadena Hola repetida 3 veces queda {cadenaRepetida}\")\n\n# Recorrido de una cadena (usando un bucle)\nfor i in range(len(texto)):\n    print(f\"Carácter en posición {i}: {texto[i]}\")\n\n# Conversión a título (primera letra en mayúscula)\ntitulo = texto.lower().title()\nprint(f\"La cadena {texto} como título {titulo}\")\n\n# División de una cadena en un array de substrings\npalabras = texto.split(\" \")\nprint(f\"Palabras en la cadena {texto} son {palabras}\")\n\n# Verificación de si una cadena comienza o termina con ciertos caracteres\ncomienzaCon = texto.startswith(\"Hola\")\nprint(f\"¿La cadena {texto} comienza con 'Hola'? {comienzaCon}\")\n\nterminaCon = texto.endswith(\"mundo!\")\nprint(f\"¿La cadena {texto} termina con 'mundo!'? {terminaCon}\")\n\n# Verificar si una cadena es palíndromo\ndef esPalindromo(cadena):\n    sinEspacios = ''.join(cadena.split()).lower()\n    invertida = sinEspacios[::-1]\n    return sinEspacios == invertida\n\n# Verificar si una cadena es un anagrama\ndef esAnagrama(cadena1, cadena2):\n    limpiaCadena = lambda cadena: ''.join(cadena.split()).lower()\n    limpiaCadena1 = limpiaCadena(cadena1)\n    limpiaCadena2 = limpiaCadena(cadena2)\n    return sorted(limpiaCadena1) == sorted(limpiaCadena2)\n\n# Verificar si una cadena es un isograma\ndef esIsograma(cadena):\n    caracteres = set()\n\n    for char in cadena:\n        caracter = char.lower()\n        if caracter in caracteres:\n            return False\n        caracteres.add(caracter)\n\n    return True\n\n# Ejemplos de uso de las funciones adicionales\nprint(f\"¿Es '{texto}' un palíndromo? {esPalindromo(texto)}\")\nprint(f\"¿Es 'Ana' un palíndromo? {esPalindromo('Ana')}\")\nprint(f\"¿Es 'listen' un anagrama de 'silent'? {esAnagrama('listen', 'silent')}\")\nprint(f\"¿Es 'programming' un isograma? {esIsograma('programming')}\")\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/mikelm2020.py",
    "content": "# Acceso a caracteres especificos\n# con indices\nphrase = \"esta es una cadena de caracteres\"\n# Acceso al primer caracter\nprint(\"Acceso al primer caracter\")\nprint(phrase[0])\n\n#con slices\n# Acceso a los caracteres de las posiciones pares\nprint(f\"Acceso a los caracteres de las posiciones pares de la frase {phrase}\")\nprint(phrase[::2])\n\n#Subcadenas\n# Encontrar la posición de una subcadena en una cadena\nprint(\"Encontrar la posición de una subcadena en una cadena\")\nprint(f\"Encontrar la posición de la subcadena cadena en la phrase {phrase}\" )\nprint(phrase.find(\"cadena\"))\n\n# Contar subcadenas\n# Contar los espacios en blanco en la phrase\nprint(f\"Contar los espacios en blanco en la phrase {phrase}\")\nprint(phrase.count(\" \"))\n\n# Longitud\nprint(f\"La longitud de la cadena {phrase} es: {len(phrase)}\")\n\n# Concatenación\ncomplement = \"Mucho más grande\"\nprint(f\"Concatenar la frase {phrase} con {complement}\")\nprint(phrase + \" \" + complement)\n\n# Repetición\n# Repetir el compplemento\nprint(f\"Repetir el complemento {complement} 4 veces\")\nprint(complement * 4)\n\n# Recorrido\n# Recorer cada letra de la frase\nprint(f\"Recorer cada letra de la frase {phrase}\")\nfor letter in phrase:\n    print(letter)\n\n# Conversión a mayusculas\nprint(f\"Convertir a mayuculas la frase {phrase}\")\nprint(phrase.upper())\n\n# Conversión a minusculas\nprint(f\"Convertir a minusculas la frase {phrase}\")\nprint(phrase.lower())\n\n# Convertir a mayuscula la primer letra de la frase\nprint(f\"Convertir a mayuculas la primer letra de la frase {phrase}\")\nprint(phrase.capitalize())\n\n# Convertir a mayusculas la primer letra de cada palabra de la frase\nprint(f\"Convertir a mayusculas la primer letra de cada palabra de la frase {phrase}\")\nprint(phrase.title())\n\nother = \"Agustin Rojas Moreno\"\n# Intercambiar mayusculas y minusculas en la frase\nprint(f\"Intercambiar mayusculas y minusculas en la frase {other}\")\nprint(other.swapcase())\n\n# Reemplazo\n# Remplazar Rojas por Ramirez en la frase\nprint(f\"Remplazar Rojas por Ramirez en la frase {other}\")\nprint(other.replace(\"Rojas\", \"Ramirez\"))\n\n# Eliminar espacios en blanco a principio y al final\nsecond_phrase = \" \" + phrase + \" \"\nprint(f\"Eliminar espacios en blanco de la frase:{second_phrase}\")\nprint(phrase.strip())\n\n# División\n# Dividir en subacadenas la frase\nprint(f\"Dividir en subacadenas la frase {phrase}\")\nprint(phrase.split())\n\n# Unión\n# Unir con  coma cada letra de la frase\nprint(\",\".join(phrase))\n\n# Interpolación\n# La interpolación es con f string\nprint(f\"Esta es la interpolacion de la frase {phrase} con other {other}\")\n\n# Verificación\n# Verificar si es alfanumerica\nprint(f\"Verifica si es alfanumerica la frase {phrase}\")\nprint(phrase.isalpha())\n\n# Otrasverificaciones\nprint(f\"Otras verificaciones para la frase {phrase}\")\nprint(f\"Es ascii?: {phrase.isascii()}\")\nprint(f\"Es decimal?: {phrase.isdecimal()}\")\nprint(f\"Es minusculas?: {phrase.islower()}\")\nprint(f\"Es digito?: {phrase.isdigit()}\")\n\n# Extra\ndef analysys_of_words(first_word, second_word):\n    \n    def is_isogram(word):\n        for letter in word:\n            if word.count(letter) > 1:\n                return False\n            \n        return True\n\n\n    print(f\"Es palindromo {first_word}? {first_word == first_word[::-1]}\")\n    print(f\"Es palindromo {second_word}? {second_word == second_word[::-1]}\")\n    \n    print(f\"Es anagrama {first_word}  de {second_word}? {sorted(first_word) == sorted(second_word)}\")\n\n    print(f\"Es isograma {first_word}? {is_isogram(first_word)}\")\n    print(f\"Es isograma {second_word}? {is_isogram(second_word)}\")\n\nif __name__ == \"__main__\":\n    analysys_of_words(\"oro\", \"ana\")\n    analysys_of_words(\"cara\", \"arca\")\n    analysys_of_words(\"nido\", \"nodo\")\n    \n\n    \n\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/monicavaquerano.py",
    "content": "# 04 CADENAS DE CARACTERES\n# Mónica Vaquerano\n# https://monicavaquerano.dev\n\n\"\"\"\nEJERCICIO:\nMuestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\nen tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n\n- Acceso:\n            # a caracteres específicos,\n            # subcadenas, \n            # longitud, \n            # concatenación, \n            # recorrido,\n            # conversión a mayúsculas y minúsculas, \n            # reemplazo, \n            # verificación\n            # repetición, \n            # división, \n            # unión, \n            # interpolación, \n            ...\n\n\"\"\"\nprint(\"\\nCADENA DE CARACTERES O STRINGS\\n\")\n\n# Asignar a una variable (Assign String to a Variable)\nstring = \"hello, world!\"\nprint(f\"* String o cadena de caracteres:\\t{string}\")\n\n# Cadenas de caracteres multilínea (Multiline Strings)\na = \"\"\"Lorem ipsum dolor sit amet,\nconsectetur adipiscing elit,\nsed do eiusmod tempor incididunt\nut labore et dolore magna aliqua.\"\"\"\nprint(f\"\\n* Un multiline string puede usar comillas simples(') o dobles(\\\"):\\n{a}\")\n\n# Acceso a un caracter específico (Access to specific elements of a string)\nprint(\n    f\"\\n* Acceso a un caracter específico:\\tstring[1] -> {string[1]}, string[5] -> {string[5]}\"\n)\n\n# Recorriendo una string (Looping Through a String)\nprint(\"* Recorrinedo una string:\\t\", end=\"\")\nfor char in string:\n    print(char, end=\" \")\nprint()\n\n# Longitud de una string (String Length)\nprint(f\"* Longitud de una cadena:\\tlen(string) -> {len(string)}\")\n\n# Verificación de string (Check String)\nprint(\n    f\"* Verificación de string:\\t'hello' in string -> {'hello' in string}\\n\\t\\t\\t\\t'hello' not in string -> {'hello' not in string}\"\n)\n\n# Subcadenas (Access to specific elements of a string)\nprint(\n    f\"\\n* Acceso a subcadenas:\\t\\tstring[0:5] -> {string[0:5]}\\n\\t\\t\\t\\tstring[7:-1] -> {string[7:-1]}\"\n)\nprint(f\"  (Index negativos y pasos):\\tstring[-1::-1] -> {string[-1::-1]}\\n\")\n\n# Concatenación y repeticion de strings (Concatenate Strings)\na, b = \"Hello\", \"World\"\nc = a + b\nprint(f\"* Concatenación de strings (a, b = 'Hello', 'World'):\\ta + b -> {c}\")\nprint(f\"* Repetición de strings (a = 'Hello'):\\t(a * 3) -> {a * 3}\")\n\n# Format Strings\nprint(\"\\n* Formateo de strings:\")\nprint(\n    \"\"\"string.format():\nUse the string.format() method to insert numbers into strings:\n    age = 36\n    txt = \"My name is John, and I am {}\"\n    print(txt.format(age)) -> My name is John, and I am 36\n\nf-string format:\n    age = 36\n    txt = f\"My name is John, and I am {age}\"\n    print(text) -> My name is John, and I am 36\n    \"\"\"\n)\n\n# Modificación de strings (Modify Strings)\nprint(f\"* Modificación de strings:\\tUpper Case: string.upper() -> {string.upper()}\")\nprint(f\"\\t\\t\\t\\tLower Case: string.lower() -> {string.lower()}\")\nprint(f\"\\t\\t\\t\\tTitle Case: string.title() -> {string.title()}\")\nprint(f\"\\t\\t\\t\\tSwap Case: string.swapcase() -> {string.title().swapcase()}\")\nprint(f\"\\t\\t\\t\\tCapitalize Case: string.capitalize() -> {string.capitalize()}\")\nprint(\n    f\"\\t\\t\\t\\tRemove Whitespace: lstrip(), rstrip(), strip(): string.strip() -> {string.strip()}\"\n)\nprint(f\"\\t\\t\\t\\tReplace String: string.replace('e','a') -> {string.replace('e', 'a')}\")\nprint(f\"\\t\\t\\t\\tSplit String: string.split(', ') -> {string.split(', ')}\")\n\n# Metodos de strings (String Methods)\nprint(\n    f\"* Otros métodos de strings:\\tCase Fold: Converts string into lower case too): string.casefold() -> {string.casefold()}\"\n)\nprint(f\"\\t\\t\\t\\tCenter: string.center(50) -> {string.center(50)}\")\nprint(f\"\\t\\t\\t\\tCount: string.count('l') -> {string.count('l')}\")\nprint(f\"\\t\\t\\t\\tEnds with: string.endswith('world!') -> {string.endswith('world!')}\")\nprint(\n    f\"\\t\\t\\t\\tStarts with: string.startswith('world!') -> {string.startswith('world!')}\"\n)\nprint(\n    f\"\\t\\t\\t\\tFind and Index: string.find('w') or string.index('w') -> {string.find('w')}\"\n)\nprint(\n    f\"\\t\\t\\t\\tIs Alphanumeric: checks if the text is alphanumeric: string.isalnum() -> {string.isalnum()}\"\n)\nprint(\n    f\"\\t\\t\\t\\tIs Alpha: checks if the text is all text: string.isalpha() -> {string.isalpha()}\"\n)\nprint(\n    f\"\\t\\t\\t\\tIs Numeric: checks if the text is all numeric: string.isnumeric() -> {string.isnumeric()}\"\n)\nprint(\n    f\"\\t\\t\\t\\tMake translation and translate: Create a mapping table, and use it in the translate() method to replace any character:\",\n)\nprint(\n    f'\\t\\t\\t\\t\\t\\t  txt = \"Hello Sam!\" ->  mytable = str.maketrans(\"S\", \"P\") -> print(txt.translate(mytable)) -> \"Hello Pam\"'\n)\nprint(\n    f\"\\t\\t\\t\\tPartition(Rpartition too): Returns a tuple where the string is parted into three parts: string.partition('world!') -> {string.partition('world')}\"\n)\nprint(\n    f\"\\t\\t\\t\\tRfind and rindex: Searches the string for a specified value and returns the last position of where it was found:\\n\\t\\t\\t\\t\\t\\t  string.rfind('l') or string.rindex('l') -> {string.rfind('l')}\"\n)\nprint(\n    f\"\\t\\t\\t\\tZfill: Fills the string with a specified number of 0 values at the beginning:\\n\\t\\t\\t\\t\\t\\t  '50'.zfill(10) -> {'50'.zfill(10)}\"\n)\n\nmyTuple = (\"John\", \"Peter\", \"Vicky\")\nx = \"#\".join(myTuple)\nprint(\n    f\"\\t\\t\\t\\tJoin: join all items in an iterable into a string, using a hash character as separator:\\n\\t\\t\\t\\t\\t\\t  myTuple = ('John', 'Peter'', 'Vicky') -> x = '#'.join(myTuple) = {x}\"\n)\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\nCrea un programa que analice dos palabras diferentes y realice comprobaciones\npara descubrir si son:\n    - Palíndromos:  Palabra o frase cuyas letras están dispuestas de tal manera que resulta la misma leída de izquierda a derecha que de derecha a izquierda.\n    - Anagramas: Cambio en el orden de las letras de una palabra o frase que da lugar a otra palabra o frase distinta.\n    - Isogramas: Un isograma (del griego isos, 'igual' y gramma, 'letra') es una palabra o frase en la que cada letra aparece el mismo número de veces.\n        Ejemplos:\n        Heterogramas: yuxtaponer (10), centrifugado (12), luteranismo (11), adulterinos (11), hiperblanduzcos (15)...\n        Isogramas con una repetición o de segundo orden: acondicionar (11), escritura (9), intestinos (10), papelera (8)...\n\"\"\"\nprint(\"\\nDIFICULTAD EXTRA (opcional):\\n\")\n\n\ndef palindrome(word: str):\n    reversed_word = word[::-1]\n    print(\n        f\"-> Is '{word}' a palindrome?: {word.strip().lower() == reversed_word.strip().lower()}\"\n    )\n\n\ndef anagram(word1: str, word2: str):\n    listChar1, listChar2 = sorted(word1.strip().lower()), sorted(word2.strip().lower())\n    print(f\"-> Are '{word1}' and '{word2}' anagrams?: {listChar1 == listChar2}\")\n\n\ndef isogram(word: str):\n    isogram = True\n    charDict = {}\n    for char in word:\n        charDict[char] = charDict.get(char, 0) + 1\n\n    values = list(charDict.values())\n    value_count = values[0]\n    for char_count in values:\n        if char_count != value_count:\n            isogram = False\n            break\n\n    print(f\"-> Is '{word}' an isogram?: {isogram}\")\n\n\ndef compare_strings(word1: str, word2: str):\n    print(\"Comparing two strings:\")\n    palindrome(word1)\n    palindrome(word2)\n    anagram(word1, word2)\n    isogram(word1)\n    isogram(word2)\n\n\ncompare_strings(\"Saco\", \"radar\")\ncompare_strings(\"Roma\", \"yuxtaponer\")\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/mordevspt.py",
    "content": "\"\"\"\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n\"\"\"\n# Cadena - String\nmi_cadena = \"En un lugar de la mancha\"\nprint(f\"Cadena a recorrer: {mi_cadena}\")\n\n# INDEXACIÓN - Acceso a caracteres específicos\nprint(\"\\nINDEXACIÓN\\n\")\nprint(f\"Posición 10 (mi_cadena[10]): {mi_cadena[10]}\")\n\n# Subcadenas\nprint(\"\\nSUBCADENAS\\n\")\nprint(f\"Posiciones 6 a 10 (mi_cadena[6:10]): {mi_cadena[6:10]}\")\nprint(f\"Primeros 10 catracteres (mi_cadena[:10]): {mi_cadena[:10]}\")\nprint(f\"Últimos 10 catracteres mi_cadena[10:]: {mi_cadena[10:]}\")\nprint(f\"Último caracter de la cadena (mi_cadena[-1]): {mi_cadena[-1]}\")\n\n# Saber si una subcadena está en otra cadena\nprint(\"\\nSaber si una subcadena está en otra cadena\\n\")\nmi_subcadena1 = \"mancha\"\nmi_subcadena2 = \"coche\"\nprint(f\"Subcadenas: \\n\\n- mi_subcadena1: {mi_subcadena1}\\n- mi_subcadena2: {mi_subcadena2}\")\n\n# Búsqueda de posición\nprint(\"\\nBÚSQUEDA DE POSICIÓN\\n\")\n\n# Método In devuelve True o False\nprint(\"\\nMÉTODO IN\\n\")\nprint(f\"In (mi_subcadena1 in mi_cadena): {mi_subcadena1 in mi_cadena}\")\nprint(f\"In (mi_subcadena2 in mi_cadena): {mi_subcadena2 in mi_cadena}\")\n\n# Método Find - Devuelve el índice donde empieza la subcadena dentro de la cadena o -1 si no la encuentra\n# Devuelve la primera ocurriencia\nprint(\"\\nMETODO FIND\\n\")\nprint(f\"Find (mi_cadena.find(mi_subcadena1)): {mi_cadena.find(mi_subcadena1)}\")\nprint(f\"Find (mi_cadena.find(mi_subcadena2)): {mi_cadena.find(mi_subcadena2)}\")\n\n# Búsqueda de ocurrencias\nprint(\"\\nBUSCAR OCURRENCIAS\\n\")\nprint(f\"Cuantas veces aparece una subcadena (mi_cadena.count('a')): {mi_cadena.count(\"a\")}\")\n\n# Buscar por el principio o el final\nprint(\"\\nBUSCAR PRINCIPIO / FINAL\\n\")\nprint(f\"Principio (mi_cadena.startswith('mancha')): {mi_cadena.startswith(\"mancha\")}\")\nprint(f\"Principio (mi_cadena.startswith('En')): {mi_cadena.startswith(\"En\")}\")\nprint(f\"Final (mi_cadena.endswith('mancha')): {mi_cadena.endswith(\"mancha\")}\")\nprint(f\"Final (mi_cadena.endswith('En')): {mi_cadena.endswith(\"En\")}\")\n\n# Longitud\nprint(\"\\nLONGITUD\\n\")\nprint(f\"Longitud total (len(mi_cadena)): {len(mi_cadena)}\")\n\n# División\nprint(\"\\nDIVISIÓN\\n\")\nprint(f\"División (mi_cadena.split()): {mi_cadena.split()}\")\nprint(f\"División por alguna de las letras (mi_cadena.split('a')): {mi_cadena.split(\"a\")}\")\n\n# Concatenación\nprint(\"\\nCONCATENACIÓN\\n\")\nprint(f\"Concatenamos las subcadenas (mi_subcadena1+mi_subcadena2): {mi_subcadena1+mi_subcadena2}\")\n\n# Repetición\nprint(\"\\nREPETICIÓN\\n\")\nrepetirCadena= 5\nprint(f\"Repetición de la cadena por una cantidad: {mi_cadena*repetirCadena}\")\n\n# Recorrido\nprint(\"\\nRECORRIDO\\n\")\nprint(f\"Recorrer de principo a fin (mi_cadena[0::]): {mi_cadena[0::]}\")\nprint(f\"Recorrer en saltos de 3 (mi_cadena[::3]): {mi_cadena[::3]}\")\nprint(f\"Invertir cadena (mi_cadena[::-1]): {mi_cadena[::-1]}\")\nprint(f\"Saltos de dos en dos (mi_cadena[::2]): {mi_cadena[::2]}\")\n\n# Conversión a mayúsculas y minúsculas\nprint(\"\\nCONVERSIÓN A MAYÚSCULAS Y MINÚSCULAS\\n\")\nprint(f\"Minúsculas (mi_cadena.lower()): {mi_cadena.lower()}\")\nprint(f\"Mayúsculas (mi_cadena.upper()): {mi_cadena.upper()}\")\nprint(f\"Cambiar mayúsculas a minúsculas y viceversa (mi_cadena.swapcase()): {mi_cadena.swapcase()}\")\nprint(f\"Letra capital (mi_cadena.capitalize()): {mi_cadena.capitalize()}\")\nprint(f\"Título (mi_cadena.title()): {mi_cadena.title()}\")\n\n# Reemplazo \nprint(\"\\nREEMPLAZO\\n\")\nprint(f\"mi_cadena.replace('mancha','llanura'): {mi_cadena.replace(\"mancha\",\"llanura\")}\")\n\n# Unión\nprint(\"\\nUNIÓN\\n\")\nprint(f\"Unión de las subcadenas mi_subcadena1 + ' ' + mi_subcadena2: {mi_subcadena1 + \" \" + mi_subcadena2}\")\n\n# Eliminar espacios al principio y al final\nprint(\"\\nELIMINAR ESPACIOS\\n\")\nmi_cadenaConEspacios = \" empiezo con espacios y termino con espacios \"\nprint(f\"'{mi_cadenaConEspacios}'\")\nprint(f\"Eliminar espacios (mi_cadenaConEspacios.strip()): '{mi_cadenaConEspacios.strip()}'\")\n\n# Interpolación \nprint(\"\\nINTERPOLACION\")\n\n# Variables\na = 2001\nb = \"Hola\"\nc = \"Python\"\nd = True\ne = 3.14\n\n# Módulos %\nprint(\"\\nMODULOS\\n\")\n# %d = Integer\n# %f = Float\n# %s = String\n# %x = Hexadecimal\n# %o = Octal\n\nprint(\"%d + 1000 = 3001\" % (a))\nprint(\"%s es una web desarrollada en %s\" % (\"Reflex\", c))\nprint(\"[%d, %s, %s, %s, %f]\" % (a, b, c, d, e))\nprint(\"¡%s! Mi lenguaje de programación favorito es %s\" % (b, c))\nprint(\"El valor de PI o π: %f\" % (e))\n\nprint(\"\\nFORMAT\\n\")\nprint(\"{} + 1000 = 3001\".format(a))\nprint(\"{} es una web desarrollada en {}\".format(\"Reflex\", c))\nprint(\"[{}, {}, {}, {}, {}]\".format(a, b, c, d, e))\nprint(\"¡{}! Mi lenguaje de programación favorito es {}\".format(b, c))\nprint(\"El valor de PI o π: {}\".format(e))\n\nprint(\"\\nF\\n\")\nprint(f\"{a} + 1000 = 3001\")\nprint(f\"Reflex es una web desarrollada en {c}\")\nprint(f\"[{a}, {b}, {c}, {d}, {e}]\")\nprint(f\"¡{b}! Mi lenguaje de programación favorito es {c}\")\nprint(f\"El valor de PI o π: {e}\")\n\n# Transformación de String a lista - Todos los caracteres son parte de una lista\nprint(\"\\nTRANSFORMACIÓN STRING A LISTA\\n\")\nprint(f\"Transformación a lista list(mi_cadena): {list(mi_cadena)}\")\n\n# Transformación de List a String - UNa lista pasa a ser un String\nprint(\"\\nTRANSFORMACIÓN LISTA A STRING\\n\")\nmi_lista = [mi_subcadena1,\" y \",mi_subcadena2, \".\"]\nprint(mi_lista)\nprint(f\"Pasar de lista a String (''.join(mi_lista)): {\"\".join(mi_lista)}\")\n\n# Transformación numérica\nprint(\"\\nTRANSFORMACIÓN NUMÉRICA\\n\")\n\nprint(\"Como string\")\nmi_telefono = \"987456321\"\nmi_pi = \"3.14\"\nprint(mi_telefono)\nprint(mi_pi)\nprint(type(mi_telefono))\nprint(type(mi_pi))\n\nprint(\"\\nComo números\")\nprint(\"Usamos int(<variable>) y float(<variable>)\")\nmi_telefono = int(mi_telefono)\nmi_pi = float(mi_pi)\nprint(mi_telefono)\nprint(mi_pi)\nprint(type(mi_telefono))\nprint(type(mi_pi))\n\n# Comprobaciones de tipo de dato\nprint(\"\\nCOMPROBAR TIPO DE DATO\\n\")\nprint(f\"Es caracter (mi_cadena.isalpha): {mi_cadena.isalpha}\")\nprint(f\"Es entero (mi_telefono.is_integer): {mi_telefono.is_integer}\")\nprint(f\"Es float (mi_pi.is_integer): {mi_pi.is_integer}\")\n\n# Verificación\nprint(\"\\nVERIFICACIÓN\\n\")\nprint(f\"Tipo de objeto (type(mi_cadena)): {type(mi_cadena)}\")\nif type(mi_cadena) == str:\n    print(\"True\")\nelse:\n    print(\"False\")\nprint(f\"Es una instancia (isinstance(mi_cadena,str)): {isinstance(mi_cadena,str)}\")\nif isinstance(mi_cadena, str):\n    print(\"True\")\nelse:\n    print(\"False\")\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n\"\"\"\n\n\"\"\"\nPalíndromos\n\nHabitualmente se entiende por palíndromo aquel que toma por unidad la letra, es decir, \ncuya última letra es la misma que la primera, la penúltima es la misma que la segunda, etc. \nEs el caso de palabras tales como reconocer o anilina.\n\nEjemplos\n1. aba, 2. Ababa, 3. Abalaba, 4. acá, 5. acurruca, 6. ada, 7. Ada, 8. aérea, 9. agá\n\"\"\"\n\n\"\"\"\nAnagramas\n\nUn anagrama es una palabra que resulta de la transposición de todas las letras de otra palabra. \nDicho de otra forma, una palabra es anagrama de otra si las dos tienen las mismas letras, \ncon el mismo número de apariciones, pero en un orden diferente.\n\nEjemplos\n1. Esqueleto / es el toque, 2. Amor / mora, 3. Necesario / escenario, 4. Alfabeto / aabeflot, 5. Roma / Omar\n\"\"\"\n\n\"\"\"\nIsogramas\n\nUn isograma es una palabra, frase o secuencia en la que no se repite ninguna letra. \nEs un conjunto de caracteres en el que cada letra aparece solo una vez. \n\nEjemplos\n1. \"Amor\" es un isograma, ya que ninguna de sus letras se repite.\n2. \"Casa\" no es un isograma, porque la letra \"a\" aparece dos veces.\n\"\"\"\n\nprint(\"\\nEJERCICIO\\n\")\n\ndef preguntaFrases():\n    primeraPalabra = input(\"Dame la Primera palabra: \")\n    segundaPalabra = input(\"Dame la Segunda palabra: \")\n    \n    # Comprobamos que las palabras se nos han pasado\n    if len(primeraPalabra) > 0 and len(segundaPalabra) > 0:\n        # Revisamos si son Palíndromos\n        esPalindromoPrimeraPalabra = esPalindromo(primeraPalabra.lower())\n        esPalindromoSegundaPalabra = esPalindromo(segundaPalabra.lower())\n        # Imprimimos el resultado\n        if esPalindromoPrimeraPalabra and esPalindromoSegundaPalabra:\n            print(f\"Las palabras {primeraPalabra} y {segundaPalabra} son Palindromos.\")\n        # Resto de resultados\n        else:\n            # Solo Primera Palabra\n            if esPalindromoPrimeraPalabra:\n                print(f\"La palabra {primeraPalabra} es un Palíndromo.\")\n            else:\n                print(f\"La palabra {primeraPalabra} NO es un Palíndromo.\")\n            # Solo Segunda Palabra\n            if esPalindromoSegundaPalabra:\n                print(f\"La palabra {segundaPalabra} es un Palíndromo.\")\n            else:\n                print(f\"La palabra {primeraPalabra} NO es un Palíndromo.\")\n        \n        # Comprobamos si es un Anagrama\n        resultado = esAnagrama(primeraPalabra.lower(),segundaPalabra.lower())\n        if resultado:\n            print(f\"Las palabras {primeraPalabra} y {segundaPalabra} son Anagramas.\")\n        else: \n            print(f\"Las palabras {primeraPalabra} y {segundaPalabra} NO son Anagramas.\")\n            \n        \"\"\"\n        En el ejecrició correguido sería:\n        print(f\"¿Las palabras {primeraPalabra} y {segundaPalabra} son Anagramas?: {sorted(primeraPalabra) == sorted(segundaPalabra)}\")\n        \"\"\"    \n        print(f\"¿Las palabras {primeraPalabra} y {segundaPalabra} son Anagramas?: {sorted(primeraPalabra) == sorted(segundaPalabra)}\")\n            \n        # Comprobamos si es un Isograma - Hererograma\n        comprobarPrimeraPalabra = esIsogramaPrimerOrden(primeraPalabra.lower())\n        comprobarSegundaPalabra = esIsogramaPrimerOrden(segundaPalabra.lower())\n        if comprobarPrimeraPalabra and comprobarSegundaPalabra:\n            print(f\"Las palabras {primeraPalabra} y {segundaPalabra} son Isogramas de primer orden.\")\n        # Resto de resultados\n        else:\n            # Solo Primera Palabra\n            if comprobarPrimeraPalabra:\n                print(f\"La palabra {primeraPalabra} es un Isogramas de primer orden.\")\n            else:\n                print(f\"La palabra {primeraPalabra} NO es un Isogramas de primer orden.\")\n            # Solo Segunda Palabra\n            if comprobarSegundaPalabra:\n                print(f\"La palabra {segundaPalabra} es un Isogramas de primer orden.\")\n            else:\n                print(f\"La palabra {segundaPalabra} NO es un Isogramas de primer orden.\")\n\n        # Comprobamos si es un Isograma de segundo orden\n        comprobarPrimeraPalabra = esIsogramaSegundoOrden(primeraPalabra.lower())\n        comprobarSegundaPalabra = esIsogramaSegundoOrden(segundaPalabra.lower())\n        if comprobarPrimeraPalabra and comprobarSegundaPalabra:\n            print(f\"Las palabras {primeraPalabra} y {segundaPalabra} son Isogramas de segundo orden.\")\n        # Resto de resultados\n        else:\n            # Solo Primera Palabra\n            if comprobarPrimeraPalabra:\n                print(f\"La palabra {primeraPalabra} es un Isogramas de segundo orden.\")\n            else:\n                print(f\"La palabra {primeraPalabra} NO es un Isogramas de segundo orden.\")\n            # Solo Segunda Palabra\n            if comprobarSegundaPalabra:\n                print(f\"La palabra {segundaPalabra} es un Isogramas de segundo orden.\")\n            else:\n                print(f\"La palabra {segundaPalabra} NO es un Isogramas de segundo orden.\")   \n            \n        # Comprobamos si es un Isograma - Basado en la corrección del ejercicio\n        comprobarPrimeraPalabra = esIsogramaContarLetras(primeraPalabra.lower())\n        comprobarSegundaPalabra = esIsogramaContarLetras(segundaPalabra.lower())\n        if comprobarPrimeraPalabra and comprobarSegundaPalabra:\n            print(f\"Las palabras {primeraPalabra} y {segundaPalabra} son Isogramas.\")\n        # Resto de resultados\n        else:\n            # Solo Primera Palabra\n            if comprobarPrimeraPalabra:\n                print(f\"La palabra {primeraPalabra} es un Isogramas.\")\n            else:\n                print(f\"La palabra {primeraPalabra} NO es un Isogramas.\")\n            # Solo Segunda Palabra\n            if comprobarSegundaPalabra:\n                print(f\"La palabra {segundaPalabra} es un Isogramas.\")\n            else:\n                print(f\"La palabra {segundaPalabra} NO es un Isogramas.\") \n        \n    else:\n        print(\"Palabras no facilitadas para su comprobación\")\n        \n# PALINDROMO             \ndef esPalindromo(palabra):\n    # Recorremos una de las palabras (la segunda) al revés y la comparamos\n    if palabra == palabra[::-1]:\n        return True\n    else:\n        return False\n\n# ANAGRAMA\ndef esAnagrama(primeraPalabra,segundaPalabra):\n    letraNoEncontrada = False\n    # Recorremos la primera palabra y buscamos si alguna de sus letras no están en la segunda palabra\n    for i in range(len(primeraPalabra)):\n        if segundaPalabra.count(primeraPalabra[i]) == 0:\n            letraNoEncontrada = True\n            break\n    # Recorremos la segunda palabra y buscamos si alguna de sus letras no están en la primera palabra\n    for i in range(len(segundaPalabra)):\n        if primeraPalabra.count(segundaPalabra[i]) == 0:\n            letraNoEncontrada = True\n            break\n    # Si hay repetidas no es un Isograma\n    if letraNoEncontrada:\n        return False\n    else:\n        return True\n\n# ISOGRAMA - HETEROGRAMA (Isograma de primer orden)\ndef esIsogramaPrimerOrden(palabra):\n    letraRepetida = True\n    # Recorremos las diferentes partes de la palabra y comprobamos si esta tiene alguna letra repetida\n    for i in range(len(palabra)):\n        if palabra.count(palabra[i]) > 1:\n            letraRepetida = False\n            break\n    # Si hay repetidas no es un Isograma\n    if letraRepetida:\n        return True\n    else:\n        return False\n    \ndef esIsogramaSegundoOrden(palabra):\n    letraRepetida = True\n    # Recorremos las diferentes letras y comprobamos si se repiten\n    for i in range(len(palabra)):\n        if palabra.count(palabra[i]) < 2:\n            letraRepetida = False\n            break\n    # Si hay repetidas no es un Isograma\n    if letraRepetida:\n        return True\n    else:\n        return False\n    \ndef esIsogramaContarLetras(palabra):\n    # Inicimos un diccionario para almacenar las letras y el número de repeticiones de las mismas\n    numeroLetras = {} \n    # Recorremos el string\n    for letra in palabra:\n        # Por cada letra que recorremos, asignamos en el diccionario la letra como clave y la cantidad como valor\n        numeroLetras[letra] = numeroLetras.get(letra,0) + 1\n    \n    # Comprobamos la recurriencia de cada una de las letras\n    esUnIsograma = True\n    # Nos quedamos con el valor del primer elemento para comparar\n    listaValores = list(numeroLetras.values())\n    longitudIsograma = listaValores[0]\n    \n    # Recorremos el string\n    for cantidad_letra in listaValores:\n        if cantidad_letra != longitudIsograma:\n            esUnIsograma = False\n            break\n    # Si hay repetidas no es un Isograma\n    if esUnIsograma:\n        return True\n    else:\n        return False\n    \n# Ejecutamos el programa\npreguntaFrases()"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/mouredev.py",
    "content": "\"\"\"\nOperaciones\n\"\"\"\n\ns1 = \"Hola\"\ns2 = \"Python\"\n\n# Concatenación\nprint(s1 + \", \" + s2 + \"!\")\n\n# Repetición\nprint(s1 * 3)\n\n# Indexación\nprint(s1[0] + s1[1] + s1[2] + s1[3])\n\n# Longitud\nprint(len(s2))\n\n# Slicing (porción)\nprint(s2[2:6])\nprint(s2[2:])\nprint(s2[0:2])\nprint(s2[:2])\n\n# Busqueda\nprint(\"a\" in s1)\nprint(\"i\" in s1)\n\n# Reemplazo\nprint(s1.replace(\"o\", \"a\"))\n\n# División\nprint(s2.split(\"t\"))\n\n# Mayúsculas, minúsculas y letras en mayúsculas\nprint(s1.upper())\nprint(s1.lower())\nprint(\"brais moure\".title())\nprint(\"brais moure\".capitalize())\n\n# Eliminación de espacios al principio y al final\nprint(\" brais moure \".strip())\n\n# Búsqueda al principio y al final\nprint(s1.startswith(\"Ho\"))\nprint(s1.startswith(\"Py\"))\nprint(s1.endswith(\"la\"))\nprint(s1.endswith(\"thon\"))\n\ns3 = \"Brais Moure @mouredev\"\n\n# Búsqueda de posición\nprint(s3.find(\"moure\"))\nprint(s3.find(\"Moure\"))\nprint(s3.find(\"M\"))\nprint(s3.lower().find(\"m\"))\n\n# Búsqueda de ocurrencias\nprint(s3.lower().count(\"m\"))\n\n# Formateo\nprint(\"Saludo: {}, lenguje: {}!\".format(s1, s2))\n\n# Interpolación\nprint(f\"Saludo: {s1}, lenguje: {s2}!\")\n\n# Tranformación en lista de caracteres\nprint(list(s3))\n\n# Transformación de lista en cadena\nl1 = [s1, \", \", s2, \"!\"]\nprint(\"\".join(l1))\n\n# Transformaciones numéricas\ns4 = \"123456\"\ns4 = int(s4)\nprint(s4)\n\ns5 = \"123456.123\"\ns5 = float(s5)\nprint(s5)\n\n# Comprobaciones varias\ns4 = \"123456\"\nprint(s1.isalnum())\nprint(s1.isalpha())\nprint(s4.isalpha())\nprint(s4.isnumeric())\n\n\"\"\"\nExtra\n\"\"\"\n\n\ndef check(word1: str, word2: str):\n\n    # Palíndromos\n    print(f\"¿{word1} es un palíndromo?: {word1 == word1[::-1]}\")\n    print(f\"¿{word2} es un palíndromo?: {word2 == word2[::-1]}\")\n\n    # Anagramas\n    print(f\"¿{word1} es anagrama de {word2}?: {sorted(word1) == sorted(word2)}\")\n\n    # Isogramas\n\n    def isogram(word: str) -> bool:\n\n        word_dict = dict()\n        for character in word:\n            word_dict[character] = word_dict.get(character, 0) + 1\n\n        isogram = True\n        values = list(word_dict.values())\n        isogram_len = values[0]\n        for word_count in values:\n            if word_count != isogram_len:\n                isogram = False\n                break\n\n        return isogram\n\n    print(f\"¿{word1} es un isograma?: {isogram(word1)}\")\n    print(f\"¿{word2} es un isograma?: {isogram(word2)}\")\n\n\ncheck(\"radar\", \"pythonpythonpythonpython\")\n# check(\"amor\", \"roma\")\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/mrodara.py",
    "content": "######## CADENAS DE CARACTERES (Tipo de dato inmutable) #######################\n\ncadena = \"Hola que tal\"\n\nprint('Concatenación: ' + cadena + cadena)\n\nprint('Repetición: ' + cadena*3)\n\nprint('Indexación: ' + cadena[0] + cadena[1])\n\nprint('Longitud de la cadena (len): ' + str(len(cadena)))\n\n# Las cadenas se pueden recorrer\n\ncadena = 'informática'\n\nfor caracter in cadena:\n  print(caracter, \" \" ,  end=\"\")\n  \n'''\nOperadores de pertenencia: Se puede comprobar si un elemento (subcadena) pertenece o no \na una cadena de caracteres con los operadores in y not in.\n'''\nprint('á' in cadena)\n\nprint('p' in cadena)\n\nprint('p' not in cadena)\n\n\"\"\"\nSlice (rebanada): Puedo obtener una subcadena de la cadena de caracteres. \nSe indica el carácter inicial, y el carácter final, además podemos indicar opcionalmente un salto. \nSi no se indica el carácter inicial se supone que es desde el primero, sino se indica el carácter final \nse supone que es hasta el final. \nPor último podemos usar salto negativo para empezar a contar desde el final.\n\"\"\"\n\ncadena = \"inteligencia artifical\"\n\nprint(cadena[2:5]) # Desde el tercer carácter hasta el quinto\n\nprint(cadena[2:7:2]) # Desde el tercer carácter hasta el séptimo con salto de 2\n\nprint(cadena[:5]) # Desde el primer carácter hasta el quinto\n\nprint(cadena[5:]) # Desde el quinto carácter hasta el final\n\nprint(cadena[-1:-3]) # Desde el último carácter hasta el penúltimo\n\nprint(cadena[::-1]) # Invertir la cadena\n\nprint(cadena[::-2]) # Invertir la cadena con salto de 2\n\n# Podemos convertir cualquier número en una cadena de caracteres utilizando la función str()\nnum = str(123)\n\nprint(type(num))\n\n# Conversión a mayúsculas y minúsculas\nprint(cadena.upper())\nprint(cadena.lower())\n\n# Title: Convierte la primera letra de cada palabra en mayúscula\nprint(cadena.title())\n\n# Capitalize: Convierte la primera letra de la cadena en mayúscula\nprint(cadena.capitalize())\n\n# Reemplazar elementos dentro de una cadena\nprint(cadena.replace(\"i\", \"@\"))\n\n# Eliminar espacios en blanco\ncadena = \"    Hola que tal    \"\ncadena_sin_espacios = cadena.strip()\nprint(cadena_sin_espacios)\n\n# Podemos separar una cadena de caracteres y el resultado se almacena en una lista.\nwords = cadena_sin_espacios.split(\" \")\nprint(words)\nprint(type(words))\n\n######## FIN CADENAS DE CARACTERES (Tipo de dato inmutable) #######################\n\n######## EXTRA #######################\n\nword1 = input(\"Introduce la palabra 1: \")\nword2 = input(\"Introduce la palabra 2: \")\n\nwhile word1 == \"\" or word2 == \"\":\n  print(\"Debes introducir palabras\")\n  word1 = input(\"Introduce la palabra 1: \") if word1 == \"\" else word1\n  word2 = input(\"Introduce la palabra 2: \") if word2 == \"\" else word2\n\n# Comprobar si las palabras son iguales\nif word1.lower() == word2.lower():\n  print(\"Las palabras son iguales\")\nelse:\n    print(\"Las palabras son diferentes\")\n\n# Comprobar si las palabras son anagramas\nif sorted(word1.lower()) == sorted(word2.lower()):\n  print(\"Las palabras son anagramas\")\nelse:\n    print(\"Las palabras no son anagramas\")\n\n# Comprobar si las palabras son palíndromas\nprint('La palabra 1 es palíndroma') if word1.lower() == word1[::-1].lower() else print('La palabra 1 no es palíndroma')\nprint('La palabra 2 es palíndroma') if word2.lower() == word2[::-1].lower() else print('La palabra 2 no es palíndroma')\n\n# Comprobar si las palabras son Isogramas\nisograma = True\nfor char in word1.lower():\n    if word1.lower().count(char) > 1:\n        isograma = False\n        break\nif isograma:    \n    print(f'{word1} es un Isograma porque cada caracter aparece una sola vez en la palabra')\nelse:\n    print(f'{word1} no es un Isograma porque {char} se repite más veces en la palabra')    \n\nisograma = True\n\nfor char in word2.lower():\n    if word2.lower().count(char) > 1:\n        isograma = False\n        break\nif isograma:    \n    print(f'{word2} es un Isograma porque cada caracter aparece una sola vez en la palabra')\nelse:\n    print(f'{word2} no es un Isograma porque {char} se repite más veces en la palabra')\n    \n######## FIN EXTRA #######################"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/mvidalb.py",
    "content": "\n'''\nOperaciones\n'''\n\ns1 = \"Hola\"\ns2 = \"Python\"\n\n# Concatenación\nprint(s1 + \", \" + s2 + \"!\") \n\n# Repetición\nprint(s1 * 3)\n\n# Indexación\nprint(s1[0] + s1[1] + s1[2] + s1[3])\n\n# Longitud\nprint(len(s1))\n\n# Slicing (porción)\nprint(s2[2:5])\nprint(s2[2:])\nprint(s2[0:])\n\n# Búsqueda\nprint(\"a\" in s1)\nprint(\"i\" in s1)\n\n# Reemplazo\nprint(s1.replace(\"o\", \"a\"))\n\n# División\nprint(s2.split(\"t\"))\n\n# Mayúsculas y minúsculas\nprint(s1.upper())\nprint(s1.lower())\nprint(\"pedro garcía\".title())\nprint(\"pedro garcía\".capitalize())\n\n# Eliminación de espacios al principio y al final\nprint(\"  pedro garcía  \". strip())\n\n# Búsqueda al principio y final\nprint(s1.startswith(\"Ho\"))\nprint(s1.endswith(\"la\"))\n\ns3 = \"Brais Moure @mouredev\"\n\n# Búsqueda de posición\nprint(s3.find(\"m\"))\n\n# Búsqueda de ocurrencias\nprint(s3.lower().count(\"m\"))\n\n# Formateo\nprint(\"Saludo: {}, lenguaje: {}!\".format(s1, s2))\n\n# Interpolación\nprint(f\"Saludo: {s1}, lenguaje: {s2}!\")\n\n# Transformación en lista\nprint(list(s3))\n\n# Transformación de lista en cadena\nl1 = [s1, \", \", s2, \"!\"]\nprint(\"\".join(l1))\n\n# Transformaciones numéricas\ns4 = \"123456\"\nprint(int(s4))\ns4 = \"123456.17\"\nprint(float(s4))\n\n# Comprobaciones varias\nprint(s1.isalnum())     #Alphaanumérico (texto + números)\nprint(s1.isalpha())     #Alpha (solo texto)\nprint(s1.isnumeric())   #Numérico\n\n\n'''\nEjercicio extra\n'''\ndef analyze_strings(str1, str2):\n    # Palíndromo\n    if str1 == str2[::-1]:\n        print(f\"{str1} y {str2} son palíndromos!\")\n    # Anagrama\n    if sorted(str1) == sorted(str2):\n        print(f\"{str1} es un anagrama de {str2}!\")\n    # Isograma\n    if isograma(str1):\n        print(f\"{str1} es un isograma!\")\n    if isograma(str2):\n        print(f\"{str2} es un isograma!\")\n\ndef isograma(str) -> bool:\n    word_dict = dict()\n    for letter in str:\n        word_dict[letter] = word_dict.get(letter, 0) + 1\n    \n    values = list(word_dict.values())\n    isogram_len = values[0]\n    for letter in values:\n        if letter != isogram_len:\n            return False\n    return True\n\nanalyze_strings(\"pedro\", \"ordep\")\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/neslarra.py",
    "content": "\"\"\"\n EJERCICIO:\n Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n\n DIFICULTAD EXTRA (opcional):\n Crea un programa que analice dos palabras diferentes y realice comprobaciones\n para descubrir si son:\n - Palíndromos\n - Anagramas\n - Isogramas\n\"\"\"\nprint(\"Con dir(cadena) podemos ver los atributos y métodos de una variable de clase 'str'.\")\nprint(dir(\"Hola mundo\"))\nprint(f\"Clase de la cadena: 'Hola mundo'.__class__.__name__ = {'Hola mundo'.__class__.__name__}\")\nprint(f\"Largo de la cadena: 'Hola mundo'.__len__() = {'Hola mundo'.__len__()}\")\nprint(f\"Cambiar a minúscula: 'Hola mundo'.lower() = {'Hola mundo'.lower()} \")\nprint(f\"Cambiar a mayúscula: 'Hola mundo'.lower() = {'Hola mundo'.upper()} \")\nprint(f\"Inicio de palabras en mayúscula: 'Hola mundo'.title() = {'hola mundo'.title()}'\")\nprint(f\"Inicio de frase en mayúscula: 'hola mundo'.capitalize() = {'hola mundo'.capitalize()}'\")\nprint(f\"Dividir frase en palabras: 'Hola mundo'.split() = {'Hola mundo'.split()}\")\nprint(f\"Buscar un caracter en particular: 'Hola mundo'.index('n') = {'Hola mundo'.index('n')}\")\nprint(f\"Mostrar el caracter de la posición 7: 'Hola mundo'[7] = {'Hola mundo'[7]}\")\nprint(f\"Mostrar una subcadena: 'Hola mundo'[1:4] = {'Hola mundo'[1:4]}\")\nprint(f\"Mostrar desde el final de la cadena: 'Hola mundo'[3:0:-1] = {'Hola mundo'[3:0:-1]}\")\nprint(f\"Invertir el orden: 'Hola mundo'[1:4][::-1] = {'Hola mundo'[1:4][::-1]}\")\nprint(f\"Concatenar cadenas: ' '.join(['Hola mundo'[1:4][::-1], 'monde']) = {' '.join(['Hola mundo'[1:4][::-1], 'monde'])}\")\nprint(\"Una cadena se comporta como una lista de caracteres: cantidad de consonantes => \", end=\"\")\nprint(f\"[x for x in 'Hola mundo' if x.lower() not in ' aeiou'].__len__() = {[x for x in 'Hola mundo' if x.lower() not in ' aeiou'].__len__()}\")\nprint(\"Se puede formatear usando distintas cadenas y los métodos de ajuste:\")\nprint(\"\"\"    vertical = '\\\\u2502'\n    up_left = '\\\\u250c'\n    flat = '\\\\u2500'\n    up_right = '\\\\u2510'\n    down_left = '\\\\u2514'\n    down_right = '\\\\u2518'\n    under = \"*\"\n    print(f'{up_left + flat * 25 + up_right}')\n    print(f'{vertical.ljust(3, \" \")}{\"Saludito\".center(20, \" \")}{vertical.rjust(4, \" \")}')\n    mus = under * \"Saludito\".__len__()\n    print(f'{vertical.ljust(3, \" \")}{mus.center(20, \" \")}{vertical.rjust(4, \" \")}')\n    for j, item in enumerate('Hola mundo'.split()):\n        print(\n            f'{vertical.ljust(3, \" \")}{str(j).ljust(2, \" \")}{item.ljust(20, \" \")}{vertical.rjust(2, \" \")}')\n    print(f'{down_left + flat * 25 + down_right}')\n\"\"\")\nvertical = \"\\u2502\"\nup_left = \"\\u250c\"\nflat = \"\\u2500\"\nup_right = \"\\u2510\"\ndown_left = \"\\u2514\"\ndown_right = \"\\u2518\"\nunder = \"*\"   # \"\\u23ba\"\nprint(f'{up_left + flat * 25 + up_right}')\nprint(f'{vertical.ljust(3, \" \")}{\"Saludito\".center(20, \" \")}{vertical.rjust(4, \" \")}')\nmus = under * \"Saludito\".__len__()\nprint(f'{vertical.ljust(3, \" \")}{mus.center(20, \" \")}{vertical.rjust(4, \" \")}')\nfor j, item in enumerate('Hola mundo'.split()):\n    print(\n        f'{vertical.ljust(3, \" \")}{str(j).ljust(2, \" \")}{item.ljust(20, \" \")}{vertical.rjust(2, \" \")}')\nprint(f'{down_left + flat * 25 + down_right}')\n\n# Complejidad extra\n\n\ndef normalizar(cadena: str) -> str:\n    \"\"\"\n    Suprime caracteres no alfanumericos <= hay librerías que hacen esto => va de ejemplo nomás\n    \"\"\"\n    translate_chars = \"\".maketrans(\"áàéèíìóòúùüñÁÀÉÈÍÌÓÒÚÙÜÑ\", \"aaeeiioouuunAAEEIIOOUUUN\")\n    replace_chars = \"_-.,;:'¿?¡!·@#\"\n    for i in replace_chars:\n        cadena = cadena.replace(i, \" \")\n    normalizada = cadena.translate(translate_chars)\n    return normalizada\n\n\ndef es_anagrama(cadena1: str, cadena2: str) -> bool:\n    return sorted(normalizar(cadena1.lower()).replace(\" \", \"\")) == sorted(normalizar(cadena2.lower()).replace(\" \", \"\"))\n\n\ndef es_isograma(cadena1: str, cadena2: str) -> bool:\n    normalizada1 = sorted(normalizar(cadena1.lower()).replace(\" \", \"\"))\n    normalizada2 = sorted(normalizar(cadena2.lower()).replace(\" \", \"\"))\n    for lista_de_letras in (normalizada1, normalizada2):\n        if any(x for x in lista_de_letras if lista_de_letras.count(x) > 1):\n            return False\n    letras1 = set(normalizada1)\n    letras2 = set(normalizada2)\n    return not letras1.intersection(letras2)\n\n\ndef es_palindromo(cadena: str) -> bool:\n    normalizada = normalizar(cadena).replace(\" \", \"\").lower()\n    return normalizada == normalizada[::-1]\n\n\ndef main():\n    while True:\n        resultado = \"Las cadenas NO entran en ninguna categoría.\"\n        cadena1 = input(\"Ingrese una palabra o frase (X para salir): \")\n        if cadena1 == \"X\":\n            break\n        if not cadena1:\n            continue\n        cadena2 = input(\"Ingrese OTRA cadena o frase (Enter para ignorar: \")\n\n        if es_palindromo(cadena1):\n            resultado = f\"La cadena {cadena1} es un palíndromo.\"\n        if cadena2:\n            if es_anagrama(cadena1, cadena2):\n                resultado = f\"Ambas cadenas son anagramas.\"\n            else:\n                if es_isograma(cadena1, cadena2):\n                    resultado = f\"Ambas cadenas son isogramas.\"\n\n        print(resultado)\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/njaimev.py",
    "content": "# 1. Concatenación de caracteres\n\npalabra_1 = \"Gato\"\npalabra_2 = \"Perro\"\n\nunion = palabra_1 + \" \" + palabra_2\n\nprint(union)\n\n# 2. Repetición de caracteres\n\nrepeticion = palabra_1 * 4\n\nprint(repeticion)\n\n# la función join agrega un espacio al inicio de cada palabra\n\nresultado_2 = \" \".join([palabra_1] * 4)\n\nprint(resultado_2)\n\n# 3. Acceso e indexación: acceder a un caracter específico con el índice.\n\nprint(palabra_1[3]) \nprint(palabra_1[0])\nprint(palabra_1[-2])   #cuenta desde el último caracter\n\n# 4. Slicing: extrae una porción de la cadena de caracteres\n\nfrase = \"Hoy no tomé desayuno\"\n\nprint(frase[0:3])   #se excluye el ultimo indice\nprint(frase[12:])   #si no se indica el fin este llega al final de la cadena\n\n# 5. Longitud: nos entrega la longitud de la cadena de caracteres\n\nprint(len(frase))\n\n# 6. Búsqueda de caracteres o subcadenas\n\nprint(\"D\" in frase)\nprint(\"d\" in frase)\nprint(frase.find(\"desayuno\"))\nprint(frase.index(\"desayuno\"))\n\n# 7. Reemplazo de subcadenas\n\nnueva_frase = frase.replace(\"no\", \"si\")\n\nprint(nueva_frase)\n\n# Cuando se repite una palabra la va a cambiar, para evitarlo se especifica cuantas veces se quiere cambiar\n\nnueva_frase2 = frase.replace(\"no\", \"si\", 1)\n\nprint(nueva_frase2)\n\n# 8. Conversión a mayúsculas y minúsculas\n\nprint(frase.upper())\nprint(frase.lower())\n\n# 9. Capitalización y formato de título\n\npalabra = \"hola gato\"\n\nprint(palabra.capitalize())   # Solo pone mayuscula la primera letra\nprint(palabra.title())        # Pone mayuscula en cada palabra\n\n# 10. Eliminar espacios en blanco\n\ncadena = \"       Hola Mundo Gatos       \"\n\nprint(cadena.strip())\nprint(cadena.lstrip())   # Solo a la izquierda\nprint(cadena.rstrip())   # Solo a la derecha\n\n# 11. Dividir y unir: se divide con split y se une con join\n\npartes = cadena.split()   # Divide por espacios\nprint(palabra_1.split(\"t\"))\n\nprint(partes)\n\nunir = \" \".join(partes)\n\nprint(unir)\n\n# 12. Verificación de tipo de caracteres\n\nprint(palabra_1.isdigit())   #Falso, son letras\nprint(palabra_1.isalpha())   #True, son todas letras\n\npalabraConNumeros = \"abcd1234\"\n\nprint(palabraConNumeros.isalnum())  #True, son letras y numeros\n\n# 14. Formato de cadenas\n\nnombre = \"Juan\"\nedad = 45\n\nprint(f\"Nombre: {nombre}, Edad: {edad}\")\nprint(\"Nombre: {}, Edad: {}\".format(nombre, edad))\nprint(\"Nombre: %s, Edad: %d\" %(nombre, edad))\n\n# 15. Transformación numérica\n\nnum = \"012345\"\nnum = int(num)\nprint(int(num))\nprint(type(num))\n\n# 16. Transformacion decimales\n\ndec = \"1234.123\"\ndec = float(dec)\nprint(float(dec))\nprint(type(dec))\n\n\n#* DIFICULTAD EXTRA (opcional):\n# * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n# * para descubrir si son:\n# * - Palíndromos\n# * - Anagramas\n# * - Isogramas\n\npalabra1 = \"arenera\"\npalabra2 = \"amor\"\n\ndef palindromos(palabra1):\n    return palabra1 == palabra1[::-1]  # [inicio:fin:paso]\n\nprint(palindromos(palabra1)) \n\n# lo que hace [::-1] es dar vuelta la palabra\n# == va a devolver un booleano porque compara los valores\n\ndef anagramas(palabra1, palabra2):\n    return sorted(palabra1) == sorted(palabra2)\n\nprint(anagramas(palabra1, palabra2)) \n\n# Isograma: palabra donde ninguna letra se repite.\n\npal1 = \"Murcielago\"\n\n# primero separamos la palabra por sus caracteres con set, donde no se muestran repetidos\n# se mide el largo de la palabra con len() y se compara con len() del set() de la palabra\n# si es distinto significa que alguna letra se repite, por lo que no es isograma\n# si son iguales, la palabra no tiene caracteres que se repiten, siendo isograma\n\nif len(pal1) == len(set(pal1)):\n    print(f\"{pal1}, si es isograma\")\n\nelse:\n    print(f\"{pal1}, no es isograma\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/nlarrea.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n\"\"\"\n\n# CREATE A STRING\n\nmy_str = \"Hello world!\"\n# Simple '' can be used too\n\n# ACCESS CHARACTERS\n\nprint(my_str[6])  # w\nfirst_word = my_str[:5]\nprint(first_word)  # Hello\nprint(my_str[::-1])  # !dlrow olleH\n\n# Separate string in each space and take the second item from the list\nsecond_word = my_str.split(\" \")[1]\nprint(second_word)  # world!\n\n# LENGTH\n\nprint(len(my_str))  # 12\nprint(len(first_word))  # 5\nprint(len(second_word))  # 6\n\n# INTERPOLATION, CONCATENATION AND FORMAT\n\n# Using string templates\nsentence_1 = f\"{first_word} {second_word}\"\nprint(sentence_1)  # Hello world!\n\n# Using join\nsentence_2 = \" \".join([first_word, second_word])\nprint(sentence_2)  # Hello world!\n\n# Using math +\nsentence_3 = first_word + \" \" + second_word\nprint(sentence_3)  # Hello world!\n\n# Using format\nsentence_4 = \"{} {}\".format(first_word, second_word)\nprint(sentence_4)  # Hello world!\n\n# REPETITION\n\nprint(first_word * 2)  # HelloHello\n\n# CHECK\n\nprint(\"h\" in my_str)  # False\nprint(\"H\" in my_str)  # True\nprint(\"world\" in my_str)  # True\nprint(my_str.startswith(\"Hell\"))  # True\nprint(my_str.endswith(\"!\"))  # True\n\n# REPLACE\n\nprint(my_str.replace(\"!\", \".\"))  # Hello world.\n\n# DIVISION\n\nprint(my_str.split(\" \"))  # ['Hello', 'world!']\n\n# UPPER AND LOWER CASES\n\nprint(my_str.upper())  # HELLO WORLD! -> all words in upper case\nprint(my_str.lower())  # hello world! -> all words in lower case\nprint(\n    my_str.capitalize()\n)  # Hello world! -> only first char in upper and the rest in lower case\nprint(\n    my_str.title()\n)  # Hello World! -> first char of each word in upper and the rest in lower case\n\n# REMOVE EMPTY SPACES FROM BEGINNING AND END\n\nmy_other_str = \"    Hello there!   \"\nprint(len(my_other_str))  # 19\nprint(\n    len(my_other_str.strip())\n)  # 12 -> .strip() removes spaces at the beginning and the end of the str\nprint(len(my_other_str.rstrip()))  # 16 -> remove empty spaces from the right\nprint(len(my_other_str.lstrip()))  # 15 -> remove empty spaces from the left\n\n# FIND AND COUNT\n\nlong_str = \"the quick brown fox jumped over the lazy dog\"\n\nprint(long_str.find(\"quick\"))  # 4 -> where the word starts\nprint(long_str.find(\"QUICK\"))  # -1 -> doesn't exist in the sentence\nprint(long_str.count(\"o\"))  # 4\nprint(long_str.count(\"q\"))  # 1\n\n# FROM NUMERIC STRING TO NUMBER\n\nstr_num = \"1234\"\nint_num = int(str_num)\nprint(type(str_num))  # <class 'str'>\nprint(type(int_num))  # <class 'int'>\n\nstr_num_2 = \"1234.56\"\nfloat_num = float(str_num_2)\nprint(type(str_num_2))  # <class 'str'>\nprint(type(float_num))  # <class 'float'>\n\nprint(str_num.isalnum())  # True\nprint(str_num.isalpha())  # False\nprint(str_num.isalpha())  # False\nprint(str_num.isnumeric())  # True\n\nprint(str_num_2.isalnum())  # False\nprint(str_num_2.isalpha())  # False\nprint(str_num_2.isalpha())  # False\nprint(str_num_2.isnumeric())  # False\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n\"\"\"\n\n\ndef check_is_palindrome(word: str) -> bool:\n    reversed_word = word[::-1]\n\n    return word == reversed_word\n\n\ndef check_is_anagram(word_one: str, word_two: str) -> bool:\n    return sorted(word_one) == sorted(word_two)\n\n\ndef check_is_isogram(word: str) -> bool:\n    # Store how many times appears each character\n    chars_dict = dict()\n    for char in word:\n        chars_dict[char] = chars_dict.get(char, 0) + 1\n\n    # Check if all the characters appear equal times\n    is_isogram = True\n    chars_values = list(chars_dict.values())\n    first_ch_qty = chars_values[0]\n    for char_qty in chars_values:\n        if char_qty != first_ch_qty:\n            is_isogram = False\n            break\n\n    return is_isogram\n\n\ndef check_words(word_one: str, word_two: str) -> None:\n    # Check if words are palindromes\n    print(f\"\\nIs {word_one} a palindrome? {check_is_palindrome(word_one)}\")\n    print(f\"Is {word_two} a palindrome? {check_is_palindrome(word_two)}\")\n\n    # Check if words are anagrams\n    print(\n        f\"\\nIs {word_one} {word_two}'s anagram? {check_is_anagram(word_one, word_two)}\"\n    )\n\n    # Check if words are isograms\n    print(f\"\\nIs {word_one} an isogram? {check_is_isogram(word_one)}\")\n    print(f\"Is {word_two} an isogram? {check_is_isogram(word_two)}\\n\")\n\n\ncheck_words(\"rotor\", \"anna\")\ncheck_words(\"amor\", \"roma\")\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/oniricoh.py",
    "content": "#operaciones con strings\n\nstring1 = \"Hola mi nombre es,\"\nstring2 = \"Daniel\"\n\nconcatenacion = string1+string2\nprint(concatenacion)\n\nrepeticion = string2*10\nprint(repeticion)\n\nacceso_a_caracter = string1[0]\nprint(f\"La primera letra de la palabra {string2} es: {acceso_a_caracter}\")\n\nacceso_a_palabra = string1[:4]\nprint(acceso_a_palabra)\n\nlongitud = len(string2)\nprint(f\"La longitud de la cadena es: {longitud}\")\n\nfor letra in string2:\n    if letra in \"aeiou\":\n        print(f\"La letra {letra} es una vocal\")\n    else:\n        print(f\"La letra {letra} es una consonante\")\n\nconversion_a_mayuscula = string2.upper()\nprint(string2, conversion_a_mayuscula)\n\nconversion_a_minuscula = conversion_a_mayuscula.lower()\nprint(conversion_a_minuscula)\n\nprint(string1)\nreemplazo = string1.replace(\"Hola\", \"Buenos dias\")\nprint(reemplazo)\n\ndivision = string1.split(\" \")\nprint(division)\n\n# Unión (join)\npalabras = ['Hola', 'cómo estás', 'amigo']\nnueva_frase = \" \".join(palabras)\nprint(nueva_frase)\n\ninterpolacion = f\"{string1}, David\"\nprint(interpolacion)\n\nverificacion = string2.isalpha()\nprint(f\"¿{string1} es alpha? {verificacion}\")\n\n\n\n#DIFICULTAD EXTRA\n\ndef is_palindrome(palabra):\n    return palabra == palabra[::-1]\n\ndef anagrams(palabra1, palabra2):\n    return sorted(palabra1) == sorted(palabra2)\n\ndef isograms(palabra):\n    letras=list()\n    verificacion = True\n    for letra in palabra:\n        if letra in letras:\n            verificacion = False\n            break\n        else:\n            letras.append(letra)\n    return verificacion\n \ndef analizar_palabra(palabra, palabra2):\n    if is_palindrome(palabra):\n        print(f\"La palabra {palabra}: es un palindromo\")\n    if isograms(palabra):\n        print(f\"La palabra {palabra} es un isograma\")\n        \n    if is_palindrome(palabra2):\n        print(f\"La palabra {palabra2}: es un palindromo\")\n    if isograms(palabra2):\n        print(f\"La palabra {palabra2} es un isograma\")\n        \n    if anagrams(palabra, palabra2):\n        print(\"Las dos palabras son anagramas\")\n\n        \npalabra1 = input(\"Escribe la primera palabra: \") \npalabra2 = input(\"Escribe la segunda palabra: \") \nanalizar_palabra(palabra1, palabra2)         \n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/oriaj3.py",
    "content": "\n\"\"\"\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\"\"\"\n\n### OPERACIONES CON CADENAS DE CARACTERES ###\n\n# Acceso a caracteres específicos\ncadena = \"Hola mundo\"\nprint(cadena[0]) # H\n\n# Subcadenas\nprint(cadena[0:4]) # Hola\n\n# Longitud\nprint(len(cadena)) # 10\n\n# Concatenación\ncadena2 = \"Adios mundo\"\nprint(cadena + \" \" + cadena2) # Hola mundo Adios mundo\n\n# Repetición\nprint(cadena * 3) # Hola mundoHola mundoHola mundo\n\n# Recorrido\nfor i in cadena:\n    print(i) # H o l a   m u n d o\n    \n# Conversión a mayúsculas y minúsculas\nprint(cadena.upper()) # HOLA MUNDO\nprint(cadena.lower()) # hola mundo\n\n# Reemplazo\nprint(cadena.replace(\"Hola\", \"Adios\")) # Adios mundo\n\n# División\nprint(cadena.split(\" \")) # ['Hola', 'mundo']\n\n# Unión\nprint(\" \".join(cadena.split(\" \"))) # Hola mundo\n\n# Interpolación\nprint(\"Hola %s\" % \"mundo\") # Hola mundo\n\n# Verificación\nprint(\"Hola\" in cadena) # True\nprint(\"Hola\" not in cadena) # False\n\n\n## Sirven con cadenas de carácteres y con palabras ##\n# Buscar posición de un caracter\nprint(cadena.find(\"o\")) # 1\n\n# Buscar posición de un caracter desde el final\nprint(cadena.rfind(\"o\")) # 7\n\n# Conteo de caracteres\nprint(cadena.count(\"o\")) # 2\n\n# Comprobar si una cadena empieza por un caracter\nprint(cadena.startswith(\"H\")) # True\n\n# Comprobar si una cadena termina por un caracter\nprint(cadena.endswith(\"o\")) # True\n\n# Eliminar espacios en blanco al principio y al final\ncadena3 = \"  Hola mundo  \"\nprint(cadena3.strip()) # Hola mundo\n\n# f-strings\nnombre = \"Jota\"\nedad = 23\nprint(f\"Hola {nombre}, tienes {edad} años\") # Hola Jota, tienes 23 años\n\n# Format\nprint(\"Hola {}, tienes {} años\".format(nombre, edad)) # Hola Jota, tienes 23 años\n\n# Comprobar si una cadena es alfanumérica\nprint(cadena.isalnum()) # False\n\n# Comprobar si una cadena es alfabética\nprint(cadena.isalpha()) # False\n\n# Comprobar si una cadena es numérica\nprint(cadena.isnumeric()) # False\n\n# Comprobar si una cadena es decimal\nprint(cadena.isdecimal()) # False\n\n# Comprobar si una cadena es un dígito\nprint(cadena.isdigit()) # False\n\n# Comprobar si una cadena es un identificador válido\nprint(cadena.isidentifier()) # False\n\n# Comprobar si una cadena es imprimible\nprint(cadena.isprintable()) # True\n\n# Comprobar si una cadena es un espacio\nprint(cadena.isspace()) # False\n\n# Capitalización de la primera letra de cada palabra\nprint(cadena.title()) # Hola Mundo\n\n# Cambiar de mayúsculas a minúsculas y viceversa\nprint(cadena.swapcase()) # hOLA MUNDO\nprint(cadena.swapcase().swapcase()) # Hola mundo\n\n\n\n\n\n\n\n### PALÍNDROMOS, ANAGRAMAS E ISOGRAMAS ###\n\n## PALÍNDROMOS\n# Los palíndronos son palabras que se leen igual de izquierda a derecha que de derecha a izquierda\n\n# Función óptimizada\ndef isPalindromo(cadena):\n    cadena = cadena.lower()\n    return cadena == cadena[::-1]\n\n# Función no óptimizada\ndef isPalindromo2(cadena):\n    tamano = len(cadena)\n    cadena = cadena.lower()\n    if tamano/2 == 0:\n        for i in range(0, tamano/2): # Si el tamaño es par\n            if cadena[i] != cadena[tamano - i]:\n                return False\n    else:\n        tamano = tamano - 1 # la palabra tiene 3 letras, y los indices van de 0 a 2. \n        for i in range(0, tamano//2): # Si el tamaño es impar, tamano//2 redondea hacia abajo\n            if cadena[i] != cadena[tamano - i]:\n                return False\n    return True\n\n## ANAGRAMAS \n# Los anagramas son palabras que tienen las mismas letras pero en diferente orden\n\n# Función óptimizada\ndef isAnagrama(cadena1, cadena2):\n    cadena1 = sorted(cadena1.lower())\n    cadena2 = sorted(cadena2.lower())\n    print(f\"cadena1: {cadena1} cadena2: {cadena2}\")\n    return cadena1 == cadena2\n\n# Función no óptimizada (fallo, cuando una letra se repite en la primera palabra y en la segunda se repite una letra diferente)\n# Ejemplo: retener y enteere, da positivo al tener el mismo tamaño y las mismas palabras únicas, pero la e se repite 3 y 4 veces. \ndef isAnagrama2(cadena1, cadena2):\n    cadena1 = cadena1.lower()\n    cadena2 = cadena2.lower()\n    letras1 = {}\n    letras2 = {}\n    for letra in cadena1:\n        letras1[letra] = letras1.get(letra, 0) + 1\n                           \n    for letra in cadena2:\n        letras2[letra] = letras2.get(letra, 0) + 1\n\n    return letras1 == letras2    \n\n# Prueba palíndromos\nprint(\"*** PALÍNDROMOS ***\")\npalabra = \"Anabel\"\npalabra2 = \"Holaaloh\"\n\nprint(isPalindromo(palabra)) # True\nprint(isPalindromo(palabra2)) # False\n\nprint(isPalindromo2(palabra)) # True\nprint(isPalindromo2(palabra2)) # False\n\n# Prueba anagramas\nprint(\"*** ANAGRAMAS FALSE***\")\npalabra3 = \"retener\"\npalabra4 = \"entere\"\n\nprint(isAnagrama(palabra3, palabra4)) # False\nprint(isAnagrama2(palabra3, palabra4)) # False\n\nprint(\"*** ANAGRAMAS TRUE***\")\npalabra3 = \"retener\"\npalabra4 = \"enterre\"\n\nprint(isAnagrama(palabra3, palabra4)) # True\nprint(isAnagrama2(palabra3, palabra4)) # True\n\n## ISOGRAMAS de primer orden\n# Los isogramas son palabras que no tienen letras repetidas y todas ellas se repiten el mismo número de veces\n\n# Función óptimizada\ndef isIsograma(cadena):\n    cadena = cadena.lower()\n    return len(cadena) == len(set(cadena))\n\n# Función sin optimizar\ndef isIsograma2(cadena):\n    letras = {}\n    for letra in cadena:\n        letras[letra] = letras.get(letra, 0) + 1\n        if letras[letra] > 1:\n            return False\n    return True\n\n# Prueba isogramas\nprint(\"*** ISOGRAMAS ***\")\npalabra5 = \"murcielago\"\npalabra6 = \"murcielagoos\"\n\nprint(isIsograma(palabra5)) # True\nprint(isIsograma(palabra6)) # False\n\nprint(isIsograma2(palabra5)) # True\nprint(isIsograma2(palabra6)) # False\n\n## Isogramas de orden N \n\ndef isogramasN(cadena):\n    cadena = cadena.lower()\n    letras = {}\n    for letra in cadena:\n        letras[letra] = letras.get(letra, 0) + 1\n    #Compruebo que todas las letras tengan el mismo número de repeticiones\n    repeticiones = letras.get(cadena[0])\n    for letra in letras:\n        if letras[letra] != repeticiones:\n            return False\n    return repeticiones\n\n# Prueba isogramas de orden N\n\nprint(\"*** ISOGRAMAS DE ORDEN N ***\")\npalabra = \"murcielago\"\nprint(f\"La palabra {palabra} es un isograma de orden {isogramasN(palabra)}\") # 1\n\npalabra = \"murcielagomurcielago\"\nprint(f\"La palabra {palabra} es un isograma de orden {isogramasN(palabra)}\") # 2\n\npalabra = \"murcielagomurcielagomurcielago\"\nprint(f\"La palabra {palabra} es un isograma de orden {isogramasN(palabra)}\") # 3\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/pabloche73.py",
    "content": "# Operaciones con cadenas\n\nmi_cadena = \"Hola Mundo!\"\nprint(mi_cadena * 3) # Repetición\nprint(mi_cadena.title()) # Título, transforma la primera en mayúscula\nprint(mi_cadena.lower()) # Minúsculas\n\n# Transformamos el texto en una lista y asignamos cada letra a una variable\na, b, c, d, e, f, g, h, i, j, k = list(mi_cadena) \nprint (a)\nprint (b)\nprint (c)\nprint (d)\nprint (e)\nprint (f)\nprint (g)\nprint (h)\nprint (i)\nprint (j)\nprint (k)\n\n\nprint(mi_cadena.replace(\"!\",\"!!!\")) # Reemplazo\nprint(mi_cadena + \",que tal?\") # Concatenación\n\nprint(mi_cadena[-2]) # Accedemos por indice a un caracter específico\nprint(mi_cadena[0])\n\nmi_lista = mi_cadena.split() # Crea una lista a partir del texto\nprint(mi_lista)\nnueva_cadena = \"*\".join(mi_lista) # Creacion y unión de una cadena a partir de una lista\nprint(nueva_cadena)\n\nprint(mi_cadena.count(\"u\")) # Busca en la cadena y devuelve la cantidad de ocurrencias\nprint(mi_cadena.find(\"o\")) # Busca en la cadena y devuelve el valor d ela primer ubicacion\n\nprint(mi_cadena[0:3])  # Slicing o rebanado\nprint(mi_cadena[::2])  \n\ncadena_ordenada = sorted(mi_cadena.lower()) # Ordena la cadena\nprint (cadena_ordenada)\n\n# Extra!!\n\ndef anagram (word1, word2):\n    if sorted(word1.lower()) != sorted(word2.lower()):\n        print (f\"{word1} no es anagrama de {word2} o viceversa\")\n    else: \n        print (f\"{word1} y {word2} son anagramas\")\n\ndef palindromo (word1, word2):\n    inversa = word1.lower()[::-1]\n    if inversa == word2.lower():\n        print (f\"{word1} y {word2} son palíndromos\")\n    else:\n        print (f\"{word1} y {word2} no son palíndromos\")\n\ndef isograma (word1, word2):\n    \"\"\"\n    A continuacion comparamos el len del Set word1/word2 y el len de word1/word2\n    Como el set no admite repetidos si hay letras repetidas en la palabra\n    el set va a tener un len menor y devolver True\n    \"\"\"\n    repeticion1 = len(set(word1)) < len(word1)\n    repeticion2 = len(set(word2)) < len(word2)\n    if repeticion1:\n        print(f\"{word1} no es un isograma\")\n    else:\n        print(f\"{word1} es un isograma\")\n    if repeticion2:\n        print(f\"{word2} no es un isograma\")\n    else:\n        print(f\"{word2} es un isograma\")\n\ncorrecta=True\nwhile correcta:    \n    palabra1=input(\"Palabra 1: \")\n    palabra2=input(\"Palabra 2: \")\n    if palabra1.lower() != palabra2.lower():\n        anagram (palabra1, palabra2)\n        palindromo(palabra1, palabra2)\n        isograma(palabra1, palabra2)\n        correcta = False\n    else:\n        print(\"Las palabras no pueden ser iguales\")\n\n\n\n\n    "
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/pakiuh.py",
    "content": "'''\r\n   EJERCICIO:\r\n   Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\r\n   en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\r\n   - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\r\n     conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\r\n'''\r\n\r\n\r\n\r\n#Acceso a caracteres específicos\r\ncadena1 = \"Gandalf fue el que manejó el destino de Frodo y de los hobits sin saberlo.\"\r\nbuscamos_o = cadena1.find(\"o\")\r\ncuantas_o = cadena1.count(\"o\")\r\nprint(f'el texto \"{cadena1}\" tiene un total de caracter \"o\": {cuantas_o} veces y la primera \"o\" está en la posición {buscamos_o}. de un texto que tiene un total de {len(cadena1)} caracteres')\r\ncadena2 =  'Y Aragorn también fue guiado opr Gandalf'\r\nprint(cadena1 + \" \" + cadena2) #concatencación\r\n\r\n#subcadena\r\nsubcadena1 = cadena1[0:7]\r\nprint(subcadena1)\r\n\r\n#repetición\r\nrepetir_gandalf = subcadena1 * 5\r\nprint(repetir_gandalf)\r\n\r\nfor letra in subcadena1: #recorrido\r\n    print(letra)\r\n\r\ncadena1_mayusculas = cadena1.upper() #mayusculas\r\nprint(cadena1_mayusculas)\r\n\r\ncadena1_minusculas = cadena1.lower() #minusculas\r\nprint(cadena1_minusculas)\r\n\r\ncadena1_reemplazada = cadena1.replace(\"Gandalf\", \"Saruman\")\r\nprint(cadena1_reemplazada)\r\n\r\ncadena1_primera_parte = cadena1[0:int(len(cadena1)/2)]\r\ncadena2_segunda_parte = cadena1[int((len(cadena1)/2)):len(cadena1)]\r\nprint(cadena1_primera_parte)\r\nprint(cadena2_segunda_parte)\r\n\r\n#interpolacion\r\nfor letra in \"Gandalf\":\r\n    print(f\"*{letra}\",end='')\r\nprint(\"*\")\r\n\r\n'''\r\n   DIFICULTAD EXTRA (opcional):\r\n   Crea un programa que analice dos palabras diferentes y realice comprobaciones\r\n   para descubrir si son:\r\n   - Palíndromos #Una palabra o frase que se lee igual hacia adelante que hacia atrás.\r\n   - Anagramas #Dos palabras o frases que tienen las mismas letras en distinta posición.\r\n   - Isogramas #Una palabra o frase donde no se repite ninguna letra.\r\n'''\r\ndef palindromo(palabra):#Una palabra o frase que se lee igual hacia adelante que hacia atrás.\r\n    palabra_reversed =\"\"\r\n    for letra in reversed(palabra):\r\n        palabra_reversed = palabra_reversed+letra\r\n    if palabra_reversed == palabra:\r\n        print(f\"La palabra {palabra} es un palíndromo\")\r\n    else:\r\n        print(f\"La palabra {palabra} no es un palíndromo porque al revés es {palabra_reversed}\")\r\npalindromo(\"Pitufina\")\r\n\r\ndef anagrama(palabra1, palabra2):\r\n    if sorted(palabra1) == sorted(palabra2):\r\n        print(f\"Las 2 palabras {palabra1} y {palabra2} son palindromos\")\r\n    else:\r\n        print(f\"L2as 2 palabras {palabra1} y {palabra2} NO son palindromos\")\r\n\r\nanagrama(\"roma\", \"amor\")\r\n\r\ndef isogramas(frase1):#Una palabra o frase donde no se repite ninguna letra.\r\n    set_frase1 = set(frase1)\r\n    if len(frase1) == len(set_frase1):\r\n        print(f\"La frase'{frase1}' es un isograma\")\r\n    else:\r\n        print(f\"La frase '{frase1}' NO es un isograma\")\r\n\r\nisogramas(\"centavo\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/pguillo02.py",
    "content": "#Strings en python\n\npalabra = \"Esto es una string\"\n\npalabra2 = \" Esto es otra string\"\n\n#Longitud de una string\nprint(len(palabra))\n\n#Concatenar\nprint(palabra + palabra2)\n\n#Repetir palabra \nprint(palabra *3)\n\n#Acceder a una string\nprint(palabra[0])\n\n#Convertir a mayúsculas, minísculas y capitalizar la primera\nprint(palabra.upper())\nprint(palabra.capitalize())\nprint(palabra.lower())\n\n#Substrings\nprint(palabra.count(\"Esto\"))\n\n#Reemplazar\nprint(palabra.replace(\"Esto\", \"Hola\"))\n\n#Separar \nprint(palabra.strip(\" \"))\n\n#Juntar\nprint(palabra.split())\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/pipngpop.py",
    "content": "\"\"\"\nCADENAS DE CARÁCTERES\n\"\"\"\n#cadenas de texto que vamos a usar\ns1= \"Hola\"\ns2 = \"Python\"\n\n\n#Concatenación\nprint(s1 + \" \" + s2)\n\n#Repetición\nprint(s1 * 3)\n\n#Indexación -> para acceder a un caracter concreto de una cadena de texto\nprint(s1[0] + s1[1] + s1[0])\n\n#Longitud\nprint(len(s1))\n\n#Porción\nprint(s2[2:6]) #siempre poner uno de más pork sino el último no se tiene en cuenta\nprint(s2[2:]) #si no ponemos nada va hasta el final\nprint(s2[:2])\n\n#Busqueda -> para ver si un caracter existe en una cadena de texto\nprint(\"a\" in s1)\nprint(\"i\" in s1)\n\n#Remplazo\nprint(s1.replace(\"o\",\"a\")) #para cambiar una letra por otra nueva\n\n#División\nprint(s2.split(\"t\")) #si tuvieramos dos t en la palabra, cortaría por ambas\n\n#Conversión a mayúsculas, minúsculas y priméra letra en mayúsculas\nprint(s1.upper())\nprint(s1.lower())\nprint(\"hosi eloso\".title()) #pone las primeras letras en mayus\nprint(\"hosi eloso\".capitalize()) #pone solo la primera letra en mayus\n\n#Eliminación de espacios al principio y al final\nprint(\"  hosi eloso    \".strip())\n\n#Búsqueda al principio y al final\nprint(s1.startswith(\"Ho\"))\nprint(s1.startswith(\"Py\"))\nprint(s1.endswith(\"la\"))\nprint(s1.endswith(\"on\"))\n\ns3 = \"Hosi Eloso hosi@gmail.com\"\n\n#Búsqueda de posición\nprint(s3.find(\"Eloso\"))\nprint(s3.find(\"o\")) #te da la posición de la primera coincidencia\n\n#Búsqueda de ocurrencias\nprint(s3.lower().count(\"o\")) #cuenta las o de la cadena\n\n#Formato\nprint(\"Saludo: {}, lenguaje: {}!\".format(s1,s2))\nprint(f\"Saludo: {s1}, lenguaje: {s2}!\")\n\n#Transformación de cadena en lista\nprint(list(s3))\n\n#Transformación de lista en cadena\nl1 = [s1, \", \", s2, \"!\"]\nprint(\"\".join(l1))\n\n#Transformaciones numéricas\ns4 = \"123456\"\ns4 = int(s4) #número entero\nprint(s4)\n\ns5 =\"123.456\"\ns5 = float(s5) #número decimal\nprint(s5)\n\n#Comprobaciones varias\nprint(s1.isalnum())\nprint(s1.isalpha())\nprint(s4.is_integer())\nprint(s1.isnumeric())\n\n\"\"\"\nEXTRA\n\"\"\"\n'''\n* Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n'''\n\n    \n\ndef analizador():\n\n    def palindromo():\n        l=len(b)-1\n        i=0\n        b=b.lower()\n        while i!=l:\n            if b[i]==b[l]:\n                if l-i==1:\n                    l=i\n                else:\n                    i+=1\n                    l-=1\n            else:\n                break\n        if i==l:\n            print(f\"{p} es un palíndromo\")\n        else:\n            print(f\"{p} no es un palíndromo\")\n\n    def anagrama():\n        i=0\n        if len(l1)==len(l2):\n            while i<=len(l1)-1:\n                if l1[i]==l2[i]:\n                    i+=1\n                else:\n                    print(\"Las palabras no son anagramas\")\n                    break\n        if i==len(l1):\n            print(\"Las palabras son anagramas\")\n        else:\n            print(\"Las palabras no son anagramas\")\n\n    def isograma():\n        i=1\n        while i<len(l):\n            if l.count(l[i-1])==l.count(l[i]):\n                i+=1\n            else:\n                print(f\"{p} no es un isograma\")\n                break\n        if i==len(l):\n            print(f\"{p} es un isograma\")\n\n             \n\n    while True:\n\n        p1 = input(\"\\nIntroduce la primera palabra: \").strip()\n        p2 = input(\"\\nIntroduce la segunda palabra: \").strip()\n        b1 = p1.replace(\" \",\"\")\n        b2 = p2.replace(\" \",\"\")\n        if not b1.isalpha() or not b2.isalpha():\n            print(\"\\nIntroduce palabras o frases válidas.\")\n        else:\n            break\n   \n    print(\"\\n¿Son palíndromos?\")\n    p=p1\n    b=b1\n    palindromo()\n    p=p2\n    b=b2\n    palindromo()\n\n    l1=list(p1)\n    l2=list(p2)\n    l1.sort()\n    l2.sort()\n\n    print(\"\\n¿Son anagramas?\")\n    anagrama()\n\n    print(\"\\n¿Son isogramas?\")\n    l=l1\n    p=p1\n    isograma()\n    l=l2\n    p=p2\n    isograma()\n    \n\nanalizador()\nprint(\"\")\n\n\n\"\"\"\nSU SOLUCIÓN:\n\ndef check(word1: str, word2: str):\n\n    # Palíndromos\n    print(f\"¿{word1} es un palíndromo?: {word1 == word1[::-1]}\")\n    print(f\"¿{word2} es un palíndromo?: {word2 == word2[::-1]}\")\n\n    # Anagramas\n    print(f\"¿{word1} es anagrama de {word2}?: {sorted(word1) == sorted(word2)}\")\n\n    # Isogramas\n\n    def isogram(word: str) -> bool:\n\n        word_dict = dict()\n        for character in word:\n            word_dict[character] = word_dict.get(character, 0) + 1\n\n        isogram = True\n        values = list(word_dict.values())\n        isogram_len = values[0]\n        for word_count in values:\n            if word_count != isogram_len:\n                isogram = False\n                break\n\n        return isogram\n\n    print(f\"¿{word1} es un isograma?: {isogram(word1)}\")\n    print(f\"¿{word2} es un isograma?: {isogram(word2)}\")\n\n\ncheck(\"radar\", \"pythonpythonpythonpython\")\n# check(\"amor\", \"roma\")\n\n\"\"\""
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/pirrin22.py",
    "content": "my_string = 'Hola mundo'\nmy_other_string = 'soy Cristian'\nmy_long_string = 'Hola soy Cristian y soy Developer'\n# Acceso a caracteres especificos\n\nprint(my_string[1])\n\n# Subcadenas\n\nrango = slice(1,6)\n\nsubcadena1 = my_string[rango]\nprint(subcadena1)\n\nprint(my_other_string[1:6])\n\n# Longitud\n\nprint(len(my_long_string))\n\n# Concatenacion\n\nSubcadena2 = my_string + ' ' + my_other_string\n\nprint(Subcadena2)\n\n# Busqueda\n\nprint('Cristian' in my_long_string)\n\n# Repeticion\n\nprint(my_string * 3)\n\n# Recorido\n\nfor a in my_string:\n    print(a)\n\n# Conversion a Mayúsculas y minúsculas y letras en mayusculas\n\nprint(my_other_string.upper())\nprint(my_long_string.lower())\nprint(my_long_string.capitalize())\nprint(my_long_string.title())\n\n# Remplazo\n\nprint(my_long_string.replace('Cristian', 'Juan'))\n\n# Division\n\nprint(my_long_string.split(' ', 3))\n\n# Interpolacion\n\nprint(f'Hola mundo {my_other_string}')\n\n# Verificacion\n\nprint(my_long_string.count('a'))\nprint(my_long_string.find('C'))\n\n\n# Ejercicio extra\n\ndef verificaciones():\n \n\n        def palindormo(palabra1):\n            palabra1 = palabra1.lower()\n            if palabra1 == palabra1[::-1]:\n                return 'Es un palindromo'\n            else:\n                return 'No es un palindromo'\n            \n\n        def anagrama(palabra1, palabra2):\n            palabra1 = palabra1.lower()\n            palabra2 = palabra2.lower()\n            comprovacion = sorted(palabra1) == sorted(palabra2)\n            if comprovacion == False:\n                return 'No es un anagrama'\n            else:\n                return 'Es un anagrama'\n\n        def isograma(palabra1):\n            palabra1 = palabra1.lower()\n            for letra in palabra1:\n                if palabra1.count(letra) > 1:\n                    return 'No es un isogrma'\n            return 'Es un isograma'\n    \n        palabra1 = input('Ingrese una palabra: ')\n        palabra2 = input('Ingrese una palabra: ')\n        print(palindormo(palabra1))\n        print(anagrama(palabra1, palabra2))\n        print(isograma(palabra1))\n\nverificaciones()\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/pwrxman.py",
    "content": "\n\n\"\"\"\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\n *   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\n *   interpolación, verificación...\n \"\"\"\n\n# Creating a string\nletter=\"P\"\nstring=\"My string\"\nhello=\"Hello World!!\"\nprint(letter)\nprint(string)\nprint(hello)\n\n\nmultiline_string=\"\"\"this is an example of a string divided in several lines.\nThe power of you is coming from inside of you.\nThe life is great, enjoy it!!\"\"\"\nprint(multiline_string)\n\n\n# To get the length of a string, use the len() function.\n\na = \"Hello, World!\"\nprint(len(a))\n\n\n# To check if a certain phrase or character is present in a string, we can use the keyword in.\n# Check if \"free\" is present in the following text:\ntxt = \"The best things in life are free!\"\nprint(\"free\" in txt)\n\n# string concatenation\nname=\"Andrei\"\nlast_name=(\"Med\")\nfull_name=name+\" \"+last_name\n\n# Strings only\nfirst_name = 'Asabeneh'\nlast_name = 'Yetayeh'\nlanguage = 'Python'\nformated_string = 'I am %s %s. I teach %s' %(first_name, last_name, language)\nprint(formated_string)\n\n# string interpolation\na = 4\nb = 3\nprint(f'{a} + {b} = {a +b}')\nprint(f'{a} - {b} = {a - b}')\nprint(f'{a} * {b} = {a * b}')\n\n# Sequence of characters\nlanguage = 'Python'\na,b,c,d,e,f = language # unpacking sequence characters into variables\nprint(a) # P\nprint(b) # y\nprint(c) # t\nprint(d) # h\nprint(e) # o\nprint(f) # n\n\n# String index normal from 0 to the end\nlanguage = 'Python'\nfirst_letter = language[0]\nprint(first_letter) # P\nsecond_letter = language[1]\nprint(second_letter) # y\nlast_index = len(language) - 1\nlast_letter = language[last_index]\nprint(last_letter)\n\n# String index inverse order the end to -len\nlanguage = 'Python'\nlast_letter = language[-1]\nprint(f\"\\n{last_letter}\") # n\nsecond_last = language[-2]\nprint(second_last) # o\nprint(language[-len(language)])\n\n# Reversing a String\nhello = 'Hello, World!'\nprint(\"\\nreversing the string  --> \", hello[::-1]) \n\n# substrings\nlanguage = 'Python'\npto = language[0:6:2] #\nprint(pto) # Pto\n\n# Methods\nphrase=\"the world is ours, enjoy it!\"\n\n# Convert first character Upper\nprint(phrase.capitalize(), \"\\n\")\n\n# count(substring, start=.., end=..). \n# Returns the number of times a specified value occurs in a string. \n# The start is a starting indexing for counting and end is the last index to count.\n# return 0 if not found\nprint(\"COUNT\")\nprint(phrase.count('w')) \nprint(phrase.count('o')) \nprint(phrase.count('ld', 7, 14)) \nprint(phrase.count('x'))\n\n# find(): Returns the index of the first occurrence of a substring, if not found returns -1\nprint(\"FIND\")\nprint(\"\\n\", phrase.find('ours'))\nprint(phrase.find('the'))\nprint(phrase.find('xx'))\n\n# format(): formats string into a nicer output\nprint(\"FORMAT\")\nradius = 10\npi = 3.14\narea = pi * radius ** 2\nresult = 'The area of a circle with radius {} is {}'.format(str(radius), str(area))\nprint(\"\\n\", result) # The area of a circle with radius 10 is 314\n\n# isalnum()\tReturns True if all characters in the string are alphanumeric\nprint(\"ISALNUM\")\nphrase=\"No pain no gain\"\nprint(\"\\n\", phrase.isalnum())\nphrase=\"Pele won 5 futbol wold championships\"\nprint(\"\\n\", phrase.isalnum())\n\n# isalpha()\tReturns True if all characters in the string are in the alphabet\nprint(\"ISALPHA\")\n\nphrase = 'Las clases de Moure'\nprint(phrase.isalpha()) # False, space is excluded\nphrase = 'LasclasesdeMoure'\nprint(phrase.isalpha()) \nnum = '85478'\nprint(num.isalpha()) \n\n# isdecimal()\tReturns True if all characters in the string are decimals '0123456789'\nprint(\"DECIMAL\")\n\nphrase = 'thirty'\nprint(phrase.isdecimal())\nphrase = '69587'\nprint(phrase.isdecimal()) \nphrase = '3.1416'\nprint(phrase.isdecimal())\n\n# isdigit()\tReturns True if all characters in the string are digits 0123456789 other unicode characters for numbers) \nprint(\"ISDIGIT\")\n\nphrase = 'Thirty'\nprint(phrase.isdigit())\nphrase = '53489'\nprint(phrase.isdigit())\nphrase = '\\u00B2'\nprint(phrase.isdigit())\n\n# islower()\tReturns True if all characters in the string are lower case\nprint(\"ISLOWER\")\n\nphrase = 'Los cursos de Moure'\nprint(phrase.islower()) \nphrase = 'las clases de python'\nprint(phrase.islower())\n\n# isupper()\tReturns True if all characters in the string are upper case\nprint(\"ISUPPER\")\n\nphrase = 'Los cursos de Moure'\nprint(phrase.isupper()) \nphrase = 'THE COURSE OF PYTHON'\nprint(phrase.isupper()) \n\n\n# strip()\tReturns a trimmed version of the string\nprint(\"STRIP\")\n\nphrase = 'thirty days of vacationnn'\nprint(\"\\n\", phrase.strip('nothdv')) \n\n\n# upper()\tConverts a string into upper case\nprint(\"UPPER\")\n\nprint(phrase.upper())\n\nprint(\"\\n\\n< < < < < < < < < < < < < < < < <   INICIA LA DIFICULTAD EXTRA   > > > > > > > > > > > > > > > > >\\n\\n\")\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos    Palabra o frase que se lee identicamente en ambos sentidos\n                    Ejemplos:  \"Dábale arroz a la zorra el abad\", \"reconocer\", \"radar\", \"sanas\", \"amor a roma\",\n                    \"Somos o no somos\", \"Isaac no ronca así\", \"Sé verlas al revés\", \"Amó la paloma\", \n                    \"Anita lava la tina\", \"Luz azul\", \"Yo hago yoga hoy\", \"Ana lava lana\"\n\n * - Anagramas      Palabra o frase con las mismas letras pero con distinto significado. Ejemplos:\n                    \"Sergio – riesgo\", \"ramo – armo\", \"delira – lidera\", \"anagrama – amar gana\",\n                    \"Istmo de Panama – Tío Sam me da pan\", \"Valiente – Ni te vale\", \"Llave sorda > El Salvador.\",\n                    \"Llenaba > Ballena\", \"Botines > Bisonte\", \"Cara - arca\"                    \n                    \"Lácteo - coleta\", \"Retener - enterré\", \"Castor - castro\", \"Seto - esto\",\n                    \"Nido - Odín\", \"Lobo - bolo\", \"Toledo - El todo\"\n\n * - Isogramas      Palabra o frase en la que ninguna letra del alfabeto aparece más de una vez,\n                    es decir, no tiene letras repetidas. ​ \n                    Si cada letra aparece solo una vez será un isograma, Ejemplos:\n                    \"lumberjacks\", \"background\", \"downstream\", \"six-year-old\", \"yuxtaponer\",\n                    \"centrifugado\", \"luteranismo\", \"adulteros\", \"hiperblandos\"\n \"\"\"\n\ndef is_palindromo():\n    str1 = input(\"Ingrese la palabra a Analizar: \")\n    str11 = str1\n    rts1 = str1[::-1]\n    lstrts1 = rts1.split()\n    lststr1 = str1.split()\n    str1 = \"\"  \n    rts1 = \"\"\n    for x in lststr1:\n        str1 = str1 + x\n    \n    for x in lstrts1:\n        rts1 = rts1 + x\n\n    if str1 == rts1:\n        print(f\"<{str11}>  es un Palindromo! \")\n    else:\n        print(f\"{str11} NO es un Palindromo\")\n      \n    print(f\"str1 despues del split {lststr1}\\nrts1 ya invertida y sin blanco {lstrts1}\")\n    \n    return\n\n\ndef is_anagram():\n    str1 = input(\"Ingrese la palabra 1 a Analizar: \")\n    str2 = input(\"Ingrese la palabra 2 a Analizar: \")\n    \n    for x in str1:\n        if str2.find(x) < 0:\n            return print(f\"{str1} NO es anagrama de {str2}\")\n            \n    return print(f\"{str1} SI es anagrama de {str2}\")\n\ndef is_isograma():\n    str1 = input(\"Ingrese la palabra a Analizar: \")\n    str2=\"\"\n    esisogram=True\n    for i in range(len(str1)):\n        if str2.find(str1[i]) < 0:\n            str2=str2 + str1[i]\n        else:\n            esisogram=False\n    siono = \"SI\" if esisogram else \"NO\"\n    return print(f\"la palabra o frase {str1} -> {siono} es Isograma\")\n\nwhile True:\n    action = input(\"Ingrese el Análisis a Realizar: \\n(P) Pal´ndromo\\n(A) Anagrama\\n(i) Isograma\\n(q) Terminar : \")\n\n    match action:\n        case \"p\":\n            is_palindromo()\n\n        case \"a\":\n            is_anagram()\n\n        case \"i\":\n            is_isograma()\n\n        case \"q\":\n            break\n\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/pyramsd.py",
    "content": "'''\nMuestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres en tu lenguaje.\n'''\nstring = 'Programando con python'\n\n# acceso directo a un caracter\nprint(string[5])\n\n# subcadenas\nprint(string[16:22])\n\n# longitud\nprint(len(string))\n\n# concatenacion\nprint(string + ' y c++')\nprint(string, 'y javascript')\n\n# repeticion\nstring_2 = 'hola'\nprint(string_2 * 3)\n\n# recorrido\nfor i in string:\n    print(i)\n\n# conversion a mayuscula\nprint(string.upper())\n\n# conversion a minuscula\nprint(string.lower())\n\n# remplazo\nprint(string.replace(string[16:22], 'C#'))\n\n# division de string\nprint(string.split())\n\n# union\nstring_dividido = string.split()\nprint(''.join(string_dividido))\n\n# interpolacion\notro_lenguaje = 'java'\nprint(f'{string} y con {otro_lenguaje}')\n\n# verificaiones\nprint(string.isalnum()) # alfanuméricos\nprint(string.isalpha()) # alfanuméricos\nprint(string.isascii()) # si son ascii\nprint(string.isdecimal()) # si son caracteres decimal\nprint(string.isdigit()) # si son digitos\nprint(string.islower()) # si son minusculas\nprint(string.isupper()) # si son mayusculas\nprint(string.isprintable()) # si es imprimible\nprint(string.isspace()) # si son caracteres en blanco\nprint(string.istitle()) # si es de forma de titulo\nprint(string.startswith('P')) # si empieza con...\nprint(string.endswith('n')) # si termina en...\n\n# EXTRA\n'''\nDIFICULTAD EXTRA (opcional):\nCrea un programa que analice dos palabras diferentes y realice comprobaciones para descubrir si son:\n- Palíndromos\n- Anagramas\n- Isogramas\n'''\ndef palAnaIso(txt: str, txt2=''):\n    def palindromo(tx: str):\n        tx = tx.lower()\n        return tx == tx[::-1]\n    \n    def anagrama(tx:str, tx2:str):\n        tx = tx.lower()\n        tx2 = tx2.lower()\n        return sorted(tx) == sorted(tx2)\n    \n    def isograma(tx: str):\n        tx = tx.lower()\n        return len(set(tx)) == len(tx)\n\n    if txt2:\n        return f'Palindormo({txt}): {palindromo(txt)}, Anagrama{txt, txt2}: {anagrama(txt, txt2)}, Isograma({txt}): {isograma(txt)}'\n    else:\n        return f'Palindormo({txt}): {palindromo(txt)}, Isograma({txt}): {isograma(txt)}'\n\nprint(palAnaIso('Ana'))\nprint(palAnaIso('anal', 'lana'))\nprint(palAnaIso('amor'))\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/qv1ko.py",
    "content": "def program(word1, word2):\n    print(f\"The word {word1} is a palindrome\" if is_palindrome(word1) else f\"The word {word1} is not a palindrome\")\n    print(f\"The word {word2} is a palindrome\" if is_palindrome(word2) else f\"The word {word2} is not a palindrome\")\n    print(f\"The words {word1} and {word2} are anagrams\" if are_anagrams(word1, word2) else f\"The words {word1} and {word2} are not anagrams\")\n    print(f\"The word {word1} is an isogram\" if is_isogram(word1) else f\"The word {word1} is not an isogram\")\n    print(f\"The word {word2} is an isogram\" if is_isogram(word2) else f\"The word {word2} is not an isogram\")\n\ndef is_palindrome(word):\n    length = len(word)\n    for i in range(length // 2):\n        if word[i] != word[length - i - 1]:\n            return False\n    return True\n\ndef are_anagrams(word1, word2):\n    if len(word1) != len(word2):\n        return False\n    letters_word1 = sorted(word1)\n    letters_word2 = sorted(word2)\n    return letters_word1 == letters_word2\n\ndef is_isogram(word):\n    letters = []\n    for letter in word:\n        if letter in letters:\n            return False\n        letters.append(letter)\n    return True\n\nprogram(\"solution\", \"loose\")\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/qwik-zgheib.py",
    "content": "# -- exercise --\nstring: str = \"Hello, World!\"\n\n# access to specific characters\nprint(string[0])\nprint(string[-1])\n\n# sub strings\nprint(string[1:5])\nprint(string[:4])\nprint(string[7:])\n\n# long\nprint(len(string))\n\n# concatenation\nprint(string + \" How are you?\")\n\n# repetition\nprint(string * 2)\n\n# route\nfor char in string:\n    print(char)\n\n# uppercase - lowercase\nprint(string.upper())\nprint(string.lower())\n\n# replacement\nprint(string.replace(\"Hello\", \"Bye\"))\n\n# division\nprint(string.split(\" \"))\n\n# union\nlist_i: list[str] = [\"Hello\", \"World\"]\nprint(\" \".join(list_i))\n\n# interpolation\nname: str = \"World\"\nprint(f\"Hello, {name}!\")\n\n# verification\nprint(string.startswith(\"Hello\"))\nprint(string.endswith(\"!\"))\nprint(\"World\" in string)\nprint(string.isalpha())\nprint(\"Hello\".isalpha())\n\n\nprint(\"\\n----- extra challenge -----\")\n\n\n# -- extra challenge --\nclass WordAnalyzer:\n    def __init__(self, word1: str, word2: str):\n        self.word1 = word1\n        self.word2 = word2\n\n    def is_palindrome(self, word: str) -> bool:\n        return word == word[::-1]\n\n    def is_anagram(self, word1: str, word2: str) -> bool:\n        return sorted(word1) == sorted(word2)\n\n    def is_isogram(self, word: str) -> bool:\n        return len(word) == len(set(word))\n\n    def analyze(self):\n        results = {\n            \"word1_is_palindrome\": self.is_palindrome(self.word1),\n            \"word2_is_palindrome\": self.is_palindrome(self.word2),\n            \"are_anagrams\": self.is_anagram(self.word1, self.word2),\n            \"word1_is_isogram\": self.is_isogram(self.word1),\n            \"word2_is_isogram\": self.is_isogram(self.word2),\n        }\n        return results\n\n\ndef display_results(results):\n    print(f\"fist word is palindrome: {results['word1_is_palindrome']}\")\n    print(f\"second word is palindromw: {results['word2_is_palindrome']}\")\n    print(f\"the words are anagrams: {results['are_anagrams']}\")\n    print(f\"first word is isogram: {results['word1_is_isogram']}\")\n    print(f\"second word is isogram: {results['word2_is_isogram']}\")\n\n\ndef main():\n    word1 = input(\"enter the first word: \")\n    word2 = input(\"enter the second word: \")\n\n    analyzer = WordAnalyzer(word1, word2)\n    results = analyzer.analyze()\n\n    display_results(results)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/rantamhack.py",
    "content": "\n\nprint(\"\\n\\n===============================OPERACIONES CON STRINGS===============================\\n\\n\")\n\n# Concatenacion\na = \"Hello\"\nb = \" World\"\nprint(a + b)\n\n# Multiplicar cadenas\na = \"Hello World\\n\" * 3\nprint(a)\n\n# Añadir texto al final de una cadena\na = \"Hello World \"\na += \"Estamos aprendiendo python\"\nprint(a)\n\n# Acceso a caracteres especificos\na = \"Hello World\"\nprint(a[0])\nprint(a[7])\n\n# Recorrido\na = \"Hello World\"\nfor character in a:\n    print(character)\n    \n# Conversion a mayusculas y minusculas\na = \"Hello World\"\nprint(a.upper())\nprint(a.lower())\nprint(a.capitalize())\n\n# Reemplazar\na = \"Hello World\"\nprint(a.replace(\"World\", \"Python\" ))\n\n# Buscar la longitud de la cadena\nstring = \"¡Es cierto! Siempre he sido nervioso, muy nervioso, terriblemente nervioso.\"\nprint(len(string))\n\n# Eliminar espacios en blanco\nstring = \"¡Es cierto! Siempre he sido nervioso, muy nervioso, terriblemente nervioso.\"\nprint(string.replace(\" \",\"\"))\n\n# Buscar\nprint(string.find(\"r\"))\n\n# Contar\nprint(f\"El numero de r que hay  en la frase son: {string.count('r')}\")\n\n# Subcadenas\nprint(string[12:36] )\n\n# Division \nprint(string.split())\nprint(string.split(\",\", 1)) # El segundo parametro indica las veces que quieres dividir con el separador \",\"\n\n# Interpolacion\nstring = \"¡Es cierto! Siempre he sido nervioso, muy nervioso, terriblemente nervioso.\"\nauthor = \"Edgar Allan Poe\"\nprint(f\"El texto: {string} es el comienzo de una novela de {author}\")\n\n# verificacion\nprint(type(string))\n\nprint(\"\\n\\n===============================DIFICULTAD EXTRA===============================\\n\\n\")\n\ndef palindromo(texto):\n    if texto.lower().replace(\" \",\"\") == texto[::-1].lower().replace(\" \",\"\"):\n        return True\n    else:\n        return False\n\nprint(palindromo(\"Luz azul\"))\n\n\ndef anagrama(word1, word2):\n    word1 = word1.lower()\n    word2 = word2.lower()\n    array1 = list(word1)\n    array2 = list(word2)\n    array1.sort()\n    array2.sort()\n    if array1 == array2:\n        print(f\"Las palabras {word1.capitalize()} y {word2.capitalize()} son un anagrama\")\n    else:\n        print(f\"Las palabras {word1} y {word2} no son un anagrama\")\n    \nanagrama(\"Enfriamiento\", \"Refinamiento\")\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/raulG91.py",
    "content": "\nstring = \"This is a string with multiple characters\"\n\n#Access to element\n\nprint(\"Element at position 2 is: \", string[1])\n\n#Sub string\n\nprint(\"Substring: \", string[0:15])\n\n#Length\n\nprint(\"Length of the string is: \", len(string))\n\n#Concatenate \n\nstring1 = \"This is a string\"\nstring2 = \" and another string\"\n\nprint(\"Concatenate: \", string1+string2)\n\n#Repeat string\n\nprint(\"Repeat string: \", 2*string1)\n\n#Loop over string\n\nfor character in string1:\n    print(character)\n\n# Uppercase\n\nprint(\"Uppercase: \", string1.upper())  \n\n#Lowercase\n\nprint(\"Lowercase: \",string1.lower())  \n\n#Replace\n\nstring_new = string1.replace(' ','_')\nprint(\"Replace: \", string_new)\n\n#Split\n\nlist = string1.split(\" \")\nprint(\"Split: \", list)\n\n#Join\n\nlist2 = [\"Join\", \"string\"]\n\nprint(\"Join: \", \" \".join(list2))\n\n#Verification\n\nstring_numeric = \"12\"\nprint(\"Is numeric: \", string_numeric.isdigit())\n\n#Extra exercise\n\ndef isPalindrome(input:str)-> bool:\n    reverse = input.lower()\n    return input == reverse[::-1]\n\n#Palindorme\n\nstring_palindrome = \"ana\"\n\nprint(\"Is palindrome:\", isPalindrome(string_palindrome))\n\n#Anagram\n\ndef is_anagram(value1:str,value2:str):\n    return sorted(value1) == sorted(value2)\n\n\nstring3 = \"roca\"\nstring4 = \"caro\"\n\nprint(\"Anagram: \",is_anagram(string3,string4))\n\n#Isogram\n\ndef is_isogram(input:str)->bool:\n    letter_set = set(input.lower())\n    return len(letter_set) == len(input)\n\nstring5=\"pan\"\nprint(\"Is isogram: \", is_isogram(string5))"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/raulallue.py",
    "content": "'''\n/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n '''\n# Declaracion cadena\nmy_string = \"esto es una cadena\"\nmy_string = 'esto es una cadena'\n\n#Acceso a caracteres especificos\nprint(my_string[3])\n\n#Subcadenas\nprint(my_string[12:])\nprint(my_string[:4])\n\n#Longitud de una cadena\nprint(len(my_string))\n\n#Concatenación\nmy_second_string = my_string + \" y esto es otra cadena\"\nprint(my_second_string)\n\n#Repetición\nprint(my_second_string * 5)\n#Recorrido\nfor letter in my_second_string:\n    print(letter)\n    \n#Convertir a mayusculas\nprint(my_second_string.upper())\n\n#Convertir primera letra en mayúscula\nprint(my_second_string.capitalize())\n\n\n#Convertir primera letra de cada palabra en mayúscula\nprint(my_second_string.title())\n\n#Convertir en minúsculas\nmy_second_string_upper = \"ESTO ES OTRA CADENA MAS\"\nprint(my_second_string_upper.lower())\n\n#Dividir cadenas\nmy_third_string = \"División de cadenas\"\n\nprint(my_third_string.split(\" \"))\n\n#Unión de cadenas\nmy_third_string = ['División', 'de', 'cadenas']\n\nprint(\" \".join(my_third_string))\n\n#Busqueda\nmy_string = \"Hola, Python\"\nposicion = my_string.find(\"Python\")\nprint(posicion)\n\n#Reemplazo\nmy_string = \"Hola, Java\"\nnew_string = my_string.replace(\"Java\", \"Python\")\nprint(new_string)\n\n#Interpolación de cadenas\nmy_other_string = \"muchas cadenas\"\nprint(f\"Aqui hay {my_other_string}\")\n\n#Verificación de cadenas\nmy_verify_string = \"Esto es una cadena para verificar\"\n\nprint(my_verify_string.isalnum()) #Devuelve True si la cadena es alfanumérica, de lo contrario False.\nmy_verify_string = \"Esto\"\nprint(my_verify_string.isalpha()) #Devuelve True si la cadena es alfabética, de lo contrario False.\nmy_verify_string = \"777\"\nprint(my_verify_string.isdigit()) #Devuelve True si la cadena es numérica, de lo contrario False.\nmy_verify_string = \"Hola\"\nprint(my_verify_string.islower()) #Devuelve True si la cadena contiene solamente minúsculas, de lo contrario False.\nmy_verify_string = \"HOLA\"\nprint(my_verify_string.isupper()) #Develve True si la cadena contiene solamente mayúsculas, de lo contrario False.\nmy_verify_string = \" \"\nprint(my_verify_string.isspace()) #Devuelve True si la cadena contiene solamente espacios en blanco, de lo contrario False.\n\n#DIFICULTAD EXTRA\n\n#PALINDROMO\n\ndef words(first_word, second_word):\n    if (first_word == second_word[::-1]):\n        print(f\"{first_word} y {second_word}, son palíndromos\")\n    else:\n        print(f\"{first_word} y {second_word}, no son palíndromos\")\n        \n        \nwords(\"hola\",\"aloh\")\n\n\n#ANAGRAMA\n\ndef words(first_word, second_word):\n    \n    first_temp = first_word.lower()\n    second_temp = second_word.lower()\n    \n    first_temp = list(first_temp)\n    second_temp = list(second_temp)\n    \n    first_temp.sort()\n    second_temp.sort()\n    \n    first_temp = \"\".join(first_temp)\n    second_temp = \"\".join(second_temp)\n\n    if(first_temp == second_temp):\n        print(f\"{first_word} y {second_word} son anagramas\")\n    else:\n        print(f\"{first_word} y {second_word} no son anagramas\")\n    \nwords(\"monja\",\"jamon\")\n\n#ISOGRAMA\ndef contar_letras(text):\n    letras = dict()\n    for letra in text:\n        if letra in letras.keys():\n            letras[letra] += 1\n        else:\n            letras[letra] = 1\n    return letras\n        \ndef isograma(text):\n    counter = 0\n    for repeat in contar_letras(text).values():\n        if counter == 0:\n            counter = repeat\n        if counter != repeat:\n            return False\n    return True\n\nprint(isograma(\"pepe\"))\n            \n        "
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/rayn1er.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n#  * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n#  * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\n#  *   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\n#  *   interpolación, verificación...\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n#  * para descubrir si son:\n#  * - Palíndromos\n#  * - Anagramas\n#  * - Isogramas\n#  */\n\nstring = 'Hola'\nstring_2 = 'Mundo'\n\nprint(string + ' ' + string_2) # Podemos utilizar el operador + para concatenar 2 o mas cadenas de texto\nprint(string * 3) # podemos utilizar * para multiplicar la cadena de texto\nstring_2 += ' de Python' # += para agregar texto\nprint(string_2)\nstring_3 = string + string_2\nprint(len(string_3)) # len para calcular obtener el numero de caracteres\nprint(string_3.find(\"Mundo\")) #find para encontrar el indice de inicio de la subcadena\nprint(string.find(\"naruto\")) # find devolvera -1 si no se encuentra la subcadena\nprint(string_3.lower()) # lower para convertir todas las letras a minusculas\nprint(string_3.upper()) #upper para convertir todas las letras a mayusculas\nprint(string_3.replace('Python','Java')) # replace para reemplazar un valor por otro\nprint(string_3[2:6]) # se puede crear subcadena utilizando corchetes con los indices desde el comienzo hasta el final\nstring_4 = 'Hola con \\\"Secuencia de escape\"' # permite representar caracteres no imprimibles\nprint(string_4)\nstring_5 = 'Hola\\t mundo' #se puede usar \\t para una tabulacion\nprint(string_5)\nstring_6 = \"Hola\\nmundo\" # y \\n para un salto de linea\nprint(string_6)\nprint(string_6.startswith('H')) #Para saber si empieza con una letra \nprint(string_6.endswith(\"O\")) # para saber si termina con una letra\n\n#Ejercicio\n\ndef palindromo(string: str): \n    \n    if string == string[::-1]: \n        return f'{string} es palindromo'\n    else:\n        return f'{string} No es palindromo'\n\nprint(palindromo(\"alomomola\"))\nprint(palindromo(\"ratatta\"))\n\ndef anagrama(string: str, string2 : str):\n    \n    if sorted(string) == sorted(string2):\n        return f'{string} es anagrama de {string2}'\n    else:\n        return f'{string} no es anagrama de {string2}'\n\nprint(anagrama(\"japones\", 'esponja'))\nprint(anagrama(\"amada\", 'mirada'))\n\ndef isograma(string):\n    check = {}\n    isograma = True\n    for i in string:\n        check[i] = string.count(i)\n\n    max_value = max(check.values())\n    \n    for i in check.values():\n        if i != max_value:\n            isograma = False\n   \n    \n    if isograma:\n        return f\"{string} es un isograma\"\n    else:\n        return f\"{string} no es un isograma\"\n\n    return max_value\n    \n    \nprint(isograma(\"pythonpythonpython\"))"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/raynerpv2022.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n \"\"\"\n \n\nnombre = \"ejemplo para reto 04 sobre cadenas string suncadenas y todo lo que desees\"\nprint(nombre)\n\n# acceso a caracter especifico\nprint(nombre[5])\n\n# subcadena\nprint(nombre[3:8])\nprint(nombre[:8])\nprint(nombre[10:])\nprint(nombre[2:10:2])\nprint(nombre.split())\n\n# buscar subcadenas\nprint(nombre.find(\"ca\"))\n\nprint(\"04\" in nombre )\n\n# concatenar cadenas\nmoneda = \"BITCOIN\"\nvalor = \"60000\"\nfiat = \"EURO\"\noperacion = \"=\"\nespacio = \" \"\ntexto = moneda + espacio + operacion + espacio + valor + espacio + fiat\nprint(texto)\ntexto += \" !!!\"\nprint(texto)\nmonedas = [\"BITCOIN\", \"USDT\",\"CRONOS\", \"ETHERIUM\"]\ntexto = \" \".join(monedas)\nprint(texto)\nprint(\"{} {} {} {}\".format(moneda,operacion,valor,fiat))\nprint(f\"La moneda diital del futuro {moneda}, hoy vale aproximadamente {valor} {fiat} \")\n\n#longitud\nprint(len(nombre))\n\n#repeticion\nprint((\"-*-\" + moneda)*10)\n\n#recorrer cadaena\nfor i in texto:\n    if i not in (\"A\",\"E\",\"I\",\"O\",\"U\"):\n       print(i)  \nprint(texto.lower())\nprint(texto.upper())\n\n#reemplazo\nprint(texto.replace(\"USDT\", \"CUBACoin\"))\n\n\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n \"\"\"\n\n# palindromo\ndef palindromo_for(palabra: str ):\n    new_p = \"\"\n    palabra = palabra.lower().replace(\" \",\"\")\n    for i in palabra:\n        new_p =  i + new_p \n    print(new_p) \n    print(palabra)\n\n    if new_p == palabra:\n        print(\"palindromo\")\n    else:\n        print(\"NO palindromo\")\n\n        \n\ndef palindromo_slicing(palabra :str):\n     \n    palabra = palabra.lower().replace(\" \",\"\")\n     \n    if palabra == palabra[::-1] :\n        print(\"palindromo\")\n    else:\n        print(\"NO palindromo\")\n\ndef anagrama(cad1:str, cad2 :str):\n    if len(cad1) == len(cad2):\n        cad1 = cad1.lower()\n        cad2 = cad2.lower()\n\n        cad2_invert = cad2[::-1]\n        \n        if cad1 == cad2_invert:\n            print(f\"{cad1} {cad2} anagrama\")\n        else:\n            print(f\"{cad1} {cad2} NOT anagrama\")\n    else:\n        print(f\"{cad1} {cad2} NOT anagrama\")\n\n\ndef isograma(cad : str):\n    cad = cad.lower()\n    letras = {}\n    for i in cad:\n        letras[i] = cad.count(i)\n    print(letras)\n    ocurrencia = list(letras.values())[0]\n    print(\"o\",ocurrencia)\n    for i in letras:\n        if letras[i] != ocurrencia:\n            print(f\"{cad} NOT isograma\")\n            return\n    print(letras)\n    print(f\"{cad} Isograma\")   \n\n\n\npalindromo_for(\"A mama Roma le aviva el amor a mama\")\npalindromo_slicing(\"A mama Roma le aviva el amor a mama \")\nanagrama(\"zorra\",\"arroz\")\nanagrama(\"Roma\",\"amor\")\nanagrama(\"RAdAr\",\"arroz\")\nisograma(\"cabezon\")\nisograma(\"cabezoncabezoncabezoncabezoncabezon\")\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/restevean.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n\"\"\"\n\n# String creation\ns = \"Hello World!\"\n\n# Access specific character\nprint(f\"Accessing to 67th char: {s[6]}\")  # Output: W\n\n# Substring\nprint(f\"Extracting substring: {s[0:5]}\")  # Output: Hello\n\n# Length\nprint(f\"Length: {len(s)}\")  # Output: 13\n\n# Concatenation\ns2 = \" How are you?\"\nprint(f\"Concatenation: {s + s2}\")  # Output: Hello, World! How are you?\n\n# Repetition\nprint(f\"Repetition: {s * 2}\")  # Output: Hello, World!Hello, World!\n\n# Iteration\nprint(\"Iteration:\")  # Output: Iteration:\nfor char in s:\n    print(char)\n\n# Conversion to uppercase\nprint(f\"Uppercase: {s.upper()}\")  # Output: HELLO WORLD!\n\n# Conversion to lowercase\nprint(f\"Lowercase: {s.lower()}\")  # Output: hello world!\n\n# Replacement\nprint(f\"Replacement: {s.replace(\"World\", \"Python\")}\")  # Output: Hello Python!\n\n# Splitting\nprint(f\"Splitting: {s.split(\",\")}\")  # Output: ['Hello', ' World!']\n\n# Joining\nwords = ['Hello', 'World!']\nprint(f\"Joining: {' '.join(words)}\")  # Output: Hello World!\n\n# Interpolation\nname = \"Python\"\nprint(f\"Interpolation: Hello, {name}!\")  # Output: Hello, Python!\n\n# Checking if string starts with a substring\nprint(f\"String starts with 'Hello': {s.startswith(\"Hello\")}\")  # Output: True\n\n# Checking if string ends with a substring\nprint(f\"String ends with '!': {s.endswith(\"!\")}\")  # Output: True\n\n# Checking if string contains a substring\nprint(f\"String contains 'World'; {\"World\" in s}\")  # Output: True\n\n\n# EXTRA\nclass WordAnalyzer:\n    def __init__(self, word1, word2):\n        self.word1 = word1.lower()\n        self.word2 = word2.lower()\n\n    def is_palindrome(self, word):\n        return word == word[::-1]\n\n    def is_anagram(self):\n        return sorted(self.word1) == sorted(self.word2)\n\n    def is_isogram(self, word):\n        return len(word) == len(set(word))\n\n\ndef main():\n    word1 = input(\"Enter first word: \")\n    word2 = input(\"Enter second word: \")\n\n    analyzer = WordAnalyzer(word1, word2)\n\n    print(f\"{word1} is a palindrome: {analyzer.is_palindrome(word1)}\")\n    print(f\"{word2} is a palindrome: {analyzer.is_palindrome(word2)}\")\n\n    print(f\"{word1} and {word2} are anagrams: {analyzer.is_anagram()}\")\n\n    print(f\"{word1} is an isogram: {analyzer.is_isogram(word1)}\")\n    print(f\"{word2} is an isogram: {analyzer.is_isogram(word2)}\")\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/rianojnicolas.py",
    "content": "# OPERACIONES CON CADENAS DE CARACTERES\n\n# 1. Asignacion\nsaludo = \"Hola, \"\nnombre = \"Nico\"\n\n# 2. Concatenacion\nsal = saludo + nombre\nprint(f'{sal}\\n')\n\n# 3. Operaciones \"aritmeticas\"\nsaludoTotal = saludo*3\nprint(f'{saludoTotal}\\n')\n\n# 4. Operaciones de partcion (Subcadena)\nsecuencia = \"123456789\"\nprimerCorte = secuencia[0:2:1] # Se toma -> 12\nsegundoCorte = secuencia[::2] # Se toma -> 13579\ntercerCorte = secuencia[::3] # Se toma -> 147 \ncuartoCorte = secuencia[::] #Se toma toda la cadena\nprint(primerCorte)\nprint(segundoCorte)\nprint(tercerCorte)\nprint(f'{cuartoCorte}\\n')\n\n# 5. Acceso a caracteres\ncaracter1 = sal[0]\ncaracter2 = sal[4]\nprint(caracter1)\nprint(f'{caracter2}\\n')\n\n# 6. Longitud\nlongitudString = len(sal)\nprint(f'La longitud de la cadena \"{sal}\" es de {longitudString}\\n') # Interpolacion utilizando f-string y {}\n\n# 7. Recorrido\nfor i in range(longitudString):\n    print(sal[i])\n\n# 8. Mayusculas y Minusculas\nsalMayus = sal.upper()\nprint(f'\\n{salMayus}')\nsalMinus = sal.lower()\nprint(f'{salMinus}\\n')\n\n# 9. Reemplazo\nsalReplace = sal\nprint(f'Palabra Original -> {salReplace}') # Interpolacion utilizando f-string y {}\nsalReplace = salReplace.replace(\"o\", \"2\") # Reemplaza todas las \"o\" por un \"2\"\nprint(f'Primer reemplazo de letra \"0\" por un \"2\" -> {salReplace}') # Interpolacion utilizando f-string y {}\nsalReplace = salReplace.replace(\"2\", \"o\", 1) # Reemplaza el primer \"2\" por una \"o\"\nprint(f'Segundo reemplazo, primer \"2\" por una \"o\" -> {salReplace}\\n') # Interpolacion utilizando f-string y {}\n\n# 10. Divison o Separacion\nsalDiv = sal\nprint(f'Palabra Original -> {salDiv}') # Interpolacion utilizando f-string y {}\nsalDiv = salDiv.split(\",\") # Separa la cadena por el caracter \",\" y los deja en una lista\nprint(f'Separacion = {salDiv}') # Interpolacion utilizando f-string y {}\nsalDiv = sal + \" Me llamo Johan, soy ingeneriero electronico, me gusta el futbol, la programacion y la f1\"\nprint(f'Otra separacion de la siguiente cadena -> {salDiv}') # Interpolacion utilizando f-string y {}\nsalDiv = salDiv.split(\",\", 2) # Separa por comas solo las dos primeras comas\nprint(f'Separacion = {salDiv}\\n') # Interpolacion utilizando f-string y {}\n\n# 11. Union\nmyStringList = [\"uno\", \"dos\", \"tres\", \"cuatro\"]\nprint(f'Lista -> {myStringList}') # Interpolacion utilizando f-string y {}\nmyString = \", \".join(myStringList)\nprint(f'Lista unida en un string -> {myString}\\n') # Interpolacion utilizando f-string y {}\n\n# 12. Verificacion\nletra = \"a\"\nprint(f\"String Base -> {sal}\")\nif letra in sal:\n    print(f\"La letra {letra} si esta en {sal}\\n\")\nelse:\n    print(f\"La letra {letra} no esta en {sal}\\n\")\n\n\n# DIFICULTAD EXTRA\ndef palindromo(palabra):\n    palabra = palabra.replace(' ', '')\n    palabra = palabra.lower()\n\n    numeros = [\"0\",\"1\",\"2\",\"3\",\"4\",\"5\",\"6\",\"7\",\"8\",\"9\"]\n\n    try:\n        for index in numeros:\n            if index in palabra:\n                raise ValueError(\"Por favor ingresa una palabra, por lo menos hay un numero dentro de ella\") \n        return palabra == palabra[::-1]\n    \n    except ValueError as ve:\n        print(ve)\n        return False\n    \n\ndef anagrama(palabra1, palabra2):\n    palabra1 = palabra1.replace(' ', '')\n    palabra1 = palabra1.lower()\n    palabra2 = palabra2.replace(' ', '')\n    palabra2 = palabra2.lower()\n\n    palabra1 = sorted(palabra1)\n    palabra2 = sorted(palabra2)\n\n    return palabra1 == palabra2\n\n\ndef isograma(palabra):\n    palabra = palabra.replace(' ', '')\n    palabra = palabra.lower()\n    setLetras = set()\n\n    for letra in palabra:\n        if letra in setLetras:\n            print(f'Se repite la letra {letra}')\n            return False\n        else:\n            setLetras.add(letra)\n\n    return True\n\n\ndef run():\n    palabra1 = input('Ingresa la primer palabra: ')\n    palabra2 = input('Ingresa la segunda palabra: ')\n    # Seccion Palindromo\n    es_palindromo1 = palindromo(palabra1)\n    es_palindromo2 = palindromo(palabra2)\n\n    if es_palindromo1:\n        print(f'{palabra1}, es palindroma')\n    else:\n        print(f'{palabra1}, NO es palindroma')\n    \n    if es_palindromo2:\n        print(f'{palabra2}, es palindroma')\n    else:\n        print(f'{palabra2}, NO es palindroma')\n\n    # Seccion Anagrama\n    es_anagrama = anagrama(palabra1, palabra2)\n    if es_anagrama:\n        print(f'{palabra1} y {palabra2} son anagramas')\n    else:\n        print(f'{palabra1} y {palabra2} NO son anagramas')\n\n    # Seccion Isograma\n    es_isograma1 = isograma(palabra1)\n    es_isograma2 = isograma(palabra2)\n\n    if es_isograma1:\n        print(f'{palabra1}, si es isograma')\n    else:\n        print(f'{palabra1}, NO es isograma')\n    \n    if es_isograma2:\n        print(f'{palabra2}, es isograma')\n    else:\n        print(f'{palabra2}, NO es isograma')\n\n\nif __name__ == \"__main__\":\n    run()"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/rigo93acosta.py",
    "content": "#04 CADENAS DE CARACTERES\n'''\nEJERCICIO:\nMuestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\nen tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n- Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n  conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n\nDIFICULTAD EXTRA (opcional):\nCrea un programa que analice dos palabras diferentes y realice comprobaciones\npara descubrir si son:\n- Palíndromos\n- Anagramas\n- Isogramas\n'''\n\nif __name__ == '__main__':\n\n    '''\n    Operaciones\n    '''\n\n    s1 = \"Hola\"\n    s2 = \"Python\"\n\n    # Concatenación\n    print(s1 + \", \" + s2 + \"!\")\n\n    # Repetición\n    print(s1 * 3)\n\n    # Indexación\n    print(s1[0])\n\n    # Longitud\n    print(len(s2))\n\n    # Slicing\n    print(s2[2:])\n\n    # Search\n    print('a' in s1)\n    print('i' in s1)\n\n    # Reemplazo\n    print(s1.replace(\"o\", \"a\"))\n\n    # Division\n    print(s2.split(\"t\"))\n\n    # Mayúscula y minúsculas\n    print(s1.upper())\n    print(s1.lower())\n    print(\"rigo acosta\".title())\n    print(\"rigo acosta\".capitalize())\n\n    # Eliminación al principio y al final espacio\n    # en blanco\n    print(\" rigo acosta \".strip())\n\n    # Búsqueda al principio y al final\n    print(s1.startswith('H'))\n    print(s1.endswith('o'))\n\n    s3 = \"Rigo Acosta @rigo93acosta\"\n    # Search position\n    print(\"Rigo Acosta @rigo93acosta\".find(\"Acosta\"))\n    print(\"Rigo Acosta @rigo93acosta\".find(\"r\"))\n\n    # Search ocurrencia\n    print(s3.lower().count(\"r\"))\n\n    # Formateo\n    print(\"Saludo: {}, lenguaje: {}!\".format(s1, s2))\n\n    # Interpolación\n    print(f\"Saludo: {s1}, lenguaje: {s2}!\")\n\n    # Transformación en lista\n    print(list(s3))\n\n    # Transformación en str\n    l1 = [s1, ', ', s2, '!']\n    print(\"\".join(l1))\n    \n    # Transformaciones numéricas\n    s4 = \"123456\"\n    s4 = int(s4)\n    print(s4)\n\n    s5 = \"123456.123\"\n    s5 = float(s5)\n    print(s5)\n\n    # Comprobaciones varias\n    s4 = \"123456\"\n    print(s1.isalnum())\n    print(s1.isalpha())\n    print(s4.isalpha())\n    print(s4.isnumeric())\n\n    '''\n    EXTRA\n    '''\n\n    def isogram(word_test: str) -> bool:\n            \n        word_dict = {}\n        for word in word_test:\n            word_dict[word] = word_dict.get(word, 0) + 1\n        \n        isogram = True\n        values = list(word_dict.values())\n        isogram_len = values[0]\n        for word_count in values:\n            if word_count != isogram_len:\n                isogram = False\n                break\n        return isogram\n    \n    def check_words(word_1: str, word_2: str):\n\n        # Palíndromos\n        print(f\"¿{word_1} es un palíndromo?: {word_1 == word_1[::-1]}\")\n        print(f\"¿{word_2} es un palíndromo?: {word_2 == word_2[::-1]}\")\n\n        # Anagramas entre dos palabras\n        print(f\"¿{word_1} es anagrama de {word_2}?: {sorted(word_1) == sorted(word_2)}\")\n\n        # Isogramas\n        print(f\"¿{word_1} es un isograma?: {isogram(word_1)}\")\n        print(f\"¿{word_2} es un isograma?: {isogram(word_2)}\")\n\n\n    check_words(\"pythonpython\", \"radar\")\n    check_words(\"roma\", \"amor\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/rikmij.py",
    "content": "string_ejemplo = \"Esta es la cadena de caracteres de ejemplo\"\nprint(string_ejemplo)\n\nprint(\"\\n\\t-> Acceso a caracteres específicos:\")\nprint(f\"-> En la posición {string_ejemplo.index('a')} se encuentra la letra {string_ejemplo[3]}\")\n\nprint(\"\\n\\t-> Subcadenas\")\nprint(\"~ Acceso a una subcadena:\")\nprint(string_ejemplo[3:13])\nprint(\"~ Está 'X' subcadena e una cadena:\")\nprint(\"cadena\" in string_ejemplo)\nprint(\"mondongo\" in string_ejemplo)\n\nprint(\"\\n\\t-> Longitud\")\nprint(f\"{len(string_ejemplo)} caracteres\")\n\nprint(\"\\n\\t-> Concatenación\")\nstring2 = \"y me uno a la cadena 1\"\nprint(string_ejemplo + ' ' + string2)\nprint(string_ejemplo + \" soy un añadido\")\n\nprint(\"\\n\\t-> Repetición\")\nprint(\"~ Repetimos una cadena:\")\nprint((string_ejemplo + ' ')*2)\n\nprint(\"\\n\\t-> Recorrido\")\nfor elem in string_ejemplo:\n    print(elem) #imprime cada letra\n\nfor elem in string_ejemplo.split():\n    print(elem) #imprime cada palabra\n\nprint(\"\\n\\t-> Conversión a mayúsculas y minúsculas\")\nprint(\"~ A mayúsculas\")\nprint(string_ejemplo.upper())\nprint(\"~ La primera en mayúsculas\")\nprint(string_ejemplo.capitalize())\nprint(\"~ A minúsculas\")\nprint(string_ejemplo.lower())\n\nprint(\"\\n\\t-> Reemplazo\")\nword = string_ejemplo.split()\nword[1] = \"no es\"\nprint(\" \".join(word))\n\nprint(\"\\n\\t-> División\")\nprint(string_ejemplo.split())\n\nprint(\"\\n\\t-> Interpolación\")\nprint(f\"La cadena principal era: \\\"{string_ejemplo}\\\", como recuerdo\")\n\nprint(\"\\n\\t-> Verificación\")\nif type(string_ejemplo) == str:\n    print(\"Es un string\")\nelse:\n    print(\"Pues no es un string\")\n\nprint(\"\\n\\t-> Pertenencia\")\nprint(\"ejemplo\" in string_ejemplo)\nprint(\"mondongo\" in string_ejemplo)\n\n\nprint('\\n','~'*5, ' EJERCICIO EXTRA ', '~'*5)\n# palíndromo = se lee igual al derecho que al revés\n# anagrama = cambian de orden las letras para formar otra\n# isograma = palabra o frase que cada letra aparece el mismo número de veces\n\ndef palindrome(word):\n    if word == word[::-1]:\n        return \"Es un palíndromo\"\n    else:\n        return \"No es un palíndromo\"\n\n\ndef anagrama(word1, word2):\n    letters1 = []\n    letters2 = []\n\n    for l in word1.lower():\n        letters1.append(l)\n    \n    for l2 in word2.lower():\n        letters2.append(l2)\n    \n    letters1.sort()\n    letters2.sort()\n\n    if letters1 == letters2:\n        return \"Son anagramas\"\n    else:\n        return \"No son anagramas\"\n\n\ndef isograma(word):\n    count_letters = {}\n\n    for letter in word:\n        if letter in count_letters:\n            count_letters[letter] += 1\n        else:\n            count_letters[letter] = 1\n\n    set_compr = set(count_letters.values())\n\n    if len(set_compr) == 1:\n        return \"Es un isograma\"\n    else:\n        reps = []\n        for key, value in count_letters.items():\n            if value >= 2:\n                reps.append(key)\n        return f\"No es un isograma, se repiten: {reps}\"\n\n\ndef verification_words():\n    w1 = input(\"Palabra 1 que quieres comprobar: \")\n    w2 = input(\"Palabra 2 que quieres comprobar: \")\n\n    print(\"Palabra 1: \", palindrome(w1))\n    print(\"Palabra 2: \", palindrome(w2))\n    print(\"Estas 2 palabras: \", anagrama(w1, w2))\n    print(\"Palabra 1: \", isograma(w1))\n    print(\"Palabra 2: \", isograma(w2))\n\nverification_words()\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/saicobys.py",
    "content": "# Cadenas de ejemplo\ntexto1 = \"Hola, mundo!\"\ntexto2 = \"Python es genial\"\n\n# Acceso a caracteres y subcadenas\nprint(texto1[0])      # H (Primer carácter)\nprint(texto1[7:12])   # mundo (Subcadena desde el índice 7 hasta el 11)\nprint(texto1[-1])     # ! (Último carácter)\n\n# Longitud\nprint(len(texto1))    # 12 (Número de caracteres en la cadena)\n\n# Concatenación (unir cadenas)\ntexto_combinado = texto1 + \" \" + texto2\nprint(texto_combinado)  # Hola, mundo! Python es genial\n\n# Repetición\ntexto_repetido = texto1 * 3\nprint(texto_repetido)  # Hola, mundo!Hola, mundo!Hola, mundo!\n\n# Recorrido (iterar sobre caracteres)\nfor caracter in texto2:\n    print(caracter)    # Imprime cada carácter en una línea nueva\n\n# Conversión a mayúsculas y minúsculas\nprint(texto1.upper())  # HOLA, MUNDO!\nprint(texto2.lower())  # python es genial\n\n# Reemplazo\nnuevo_texto = texto2.replace(\"genial\", \"fantástico\")\nprint(nuevo_texto)     # Python es fantástico\n\n# División (split)\npalabras = texto2.split(\" \")\nprint(palabras)        # ['Python', 'es', 'genial']\n\n# Unión (join)\nnueva_cadena = \"-\".join(palabras)\nprint(nueva_cadena)    # Python-es-genial\n\n# Verificación (contiene, comienza, termina)\nprint(\"mundo\" in texto1)          # True\nprint(texto1.startswith(\"Hola\"))  # True\nprint(texto2.endswith(\"!\"))       # False\n\n# Interpolación (formateo de cadenas)\nnombre = \"Carlos\"\nedad = 30\nmensaje = f\"Hola, me llamo {nombre} y tengo {edad} años.\"\nprint(mensaje)        # Hola, me llamo Carlos y tengo 30 años.\n\n# Analizador de Palabras\n\ndef es_palindromo(palabra):\n    \"\"\"Verifica si una palabra es un palíndromo (se lee igual de derecha a izquierda).\"\"\"\n    palabra = palabra.lower().replace(\" \", \"\")  # Normalización\n    return palabra == palabra[::-1]  # Compara la palabra con su reverso\n\ndef es_anagrama(palabra1, palabra2):\n    \"\"\"Verifica si dos palabras son anagramas (tienen las mismas letras en diferente orden).\"\"\"\n    palabra1 = palabra1.lower().replace(\" \", \"\")\n    palabra2 = palabra2.lower().replace(\" \", \"\")\n    return sorted(palabra1) == sorted(palabra2)  # Compara las palabras ordenadas\n\ndef es_isograma(palabra):\n    \"\"\"Verifica si una palabra es un isograma (no tiene letras repetidas).\"\"\"\n    palabra = palabra.lower().replace(\" \", \"\")\n    return len(palabra) == len(set(palabra))  # Compara la longitud original con la del conjunto (sin duplicados)\n\n# Ejemplo de uso\npalabra1 = \"Anita lava la tina\"\npalabra2 = \"Amor a Roma\"\npalabra3 = \"Python\"\n\nprint(f\"'{palabra1}' es palíndromo: {es_palindromo(palabra1)}\")\nprint(f\"'{palabra1}' y '{palabra2}' son anagramas: {es_anagrama(palabra1, palabra2)}\")\nprint(f\"'{palabra3}' es isograma: {es_isograma(palabra3)}\")\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/santiago434c.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\"\"\"\n\ntexto = \"Hola, python\"\ntexto_2 = \"2024\"\ntexto_3 = \"JUAN ROMAN \"\ntexto_4 = \"JRR, JRR, JRR, NJ\"\n\n#Acceso a caracter por posiscion - letra l\nprint(texto[2])\n\n#Longitud de caracteres\nprint(len(texto))\n\n#Concatenacion\nprint(texto + \" \" + texto_2)\n\n#Subcadena\nsubcadena = texto[6:12]\nprint(subcadena)\n\n#Mayusculas\nprint(texto.upper())\n\n#Minusculas\nprint(texto_3.lower())\n\n#Remplazo\ntexto_remplazo = texto.replace(\"Hola\", \"Adios\")\nprint(texto_remplazo)\n\n#Division - Split\ntexto_dividido = texto.split()\nprint(texto_dividido)\n\n#Comprobar si es numero el string\nprint(texto.isdigit())\nprint(texto_2.isdigit())\n\n#Recorrido de string\nfor letra in texto:\n    print(letra)\n\n#Repeticion\nprint(3 * texto_3)\n\n#Verificacion - Las mayusculas importan\ncontiene = \"JUAN\" in texto_3\nprint(contiene)\n\ncontiene = \"juan\" in texto_3\nprint(contiene)\n\n#Contar subcadenas\ncuantas_veces_JRR = texto_4.count(\"JRR\")\nprint(cuantas_veces_JRR)\n\n#Interpolacion\nmensaje = \"Hola, soy {} y estamos en el {}.\".format(texto_3, texto_2)\nprint(mensaje)\n\n#f-string\nprint(f\"{texto} es la primera frase que imprimi en {texto_2}\")\n\n#Join\n\n#RETO -> Recibe 2 palabras str\n\n#PALINDROMO - Se lee igual de izquierda a derecha que de dercha a izquierda - OK\n\n#ANAGRAMA - 2 Palabras que contiene las mismas letras pero en diferente orden\n#Eg. Amor - Roma\n\n#ISOGRAMAS - Palabra en la cual no se repiten letras\n#Eg. Murcielago\n    \ndef comprobacion_palabras(txt_1, txt_2):\n    txt_1 = txt_1.lower()\n    txt_2 = txt_2.lower()\n    #Verificar Palindromo\n    def palindromo(txt_palindromo):\n        vacio = \"\" #String vacio para reordenar\n        for letra in txt_palindromo: #Bucle for que recorre todas las letras de la palabra que se quiere verificar\n            vacio = letra + vacio #Asignacion de la letra al string\n        if vacio == txt_palindromo: #En casos que la palabra invertida y la normal sean igual se confirma que es un palindromo\n            print(f\"La palabra {txt_palindromo} es un palindromo\")\n        else: #En caso de no coincidir se sabe que no es un palindromo \n            print(f\"La palabra {txt_palindromo} NO es un palindromo\")\n    #Aplicar revision a las dos palabras\n    palindromo(txt_1)\n    palindromo(txt_2)\n    #Verificar Anagrama\n    longitud_palabra_1 = len(txt_1) #Obetener la longitud de la palabra #1\n    longitud_palabra_2 = len(txt_2) #Obetener la longitud de la palabra #2\n    cuenta_de_true = 0 #Cuenta para verifica la cantidad de True\n    if longitud_palabra_1 == longitud_palabra_2: #Los anagramas deben tener el mismo numero de palabras - Primea verificacion\n        for letra in txt_1: #Bucle for para revisar que cada letra de la palabra 1 sea reccorida\n            verificacion = letra in txt_2 #Busqueda de la letra perteneciente a la palabra 1 en la palabra 2 \n            if verificacion == False: #En caso de que exita un false se sabe que ya no es un anagrama, se rompe el bucle e imprime - Segunda verificacion\n                print(f\"Las palabras {txt_1} y {txt_2} no son un Anagrama.\")\n                break\n            else:\n                cuenta_de_true = cuenta_de_true +1 #Caso de que sea True se suma a la variable global para llevar la cuenta y comparar luego\n    else:\n        print(f\"Las palabras {txt_1} y {txt_2} no son un Anagrama.\") #Si no son iguales ya se sabe que no es un anagrama\n    if cuenta_de_true == longitud_palabra_1: #Si la cantidad de true es igual a la longitud de las palabras se sabe que es un anagrama - Tercera verificacion\n        print(f\"las palabras {txt_1} y {txt_2} son un Anagrama.\")\n    #Verificar Isograma\n    def isograma(palabra_isograma):\n        isograma_medidor = 0 #Cuenta para verifica cuando acabe el bucle for y poder comprobar que todas las letras este solo una vez \n        longitud_palabra_isograma = len(palabra_isograma) #longitud de la palabra\n        for letra in palabra_isograma: #Bucle for para revisar que cada letra de la palabra sea reccorida\n            conteo = palabra_isograma.count(letra) #Contar cuantas veces está la palabra\n            if conteo != 1: #condicion que determina que no es un isogrma ya que 'x' letra está mas de una vez\n                print(f\"la palabra {palabra_isograma} no es un isograma.\")\n                break #Romper el bucle for\n            else:\n                isograma_medidor = isograma_medidor + 1 #Ir aumentado el contador cada vez que 'x' letra este solo una vez\n        if isograma_medidor == longitud_palabra_isograma:\n            print(f\"la palabra {palabra_isograma} es un isograma.\") #ultima verificacion para imprimir que es un isograma\n                \n    isograma(txt_1)\n    isograma(txt_2)\n\ncomprobacion_palabras(\"aMor\", \"Roma\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/santiagobailleres.py",
    "content": "# Operaciones con cadenas de caracteres\nstr1 = \"Hola\"\nstr2 = \"Mundo\"\nprint(str1[0]) # Acceso a caracteres específicos: H\nprint(str1[1:3]) # Subcadenas: Hola -> ol (slicing)\nprint(len(str1)) # Longitud: 4\nprint(str1 +', ' + str2) # Concatenación: Hola, Mundo\nprint(str1 * 3) # Repetición: HolaHolaHola\nfor i in str1: # Recorrido: Hola\n    print(i)\nprint(str1.upper()) # Conversión a mayúsculas: HOLA\nprint(str1.lower()) # Conversión a minúsculas: hola\nprint('hola mundo'.capitalize()) # Capitalización: Hola mundo\nprint('hola mundo'.title()) # Capitalización de palabras: Hola Mundo\nprint('hola Mundo'.swapcase()) # Inversión de capitalización: HOLA mUNDO\nprint('  hola mundo  '.strip()) # Eliminación de espacios en blanco: hola mundo\nprint(str1.replace('o','a')) # Reemplazo: Hala\nprint(str1.split('o')) # División: ['H', 'la']\nprint(''.join([str1,str2])) # Unión: HolaMundo\nprint(f'{str1} {str2}') # Interpolación: Hola Mundo\nprint(str1.isalpha()) # Verificación: True. esta función verifica si la cadena contiene solo letras\nprint(str1.isalnum()) # Verificación: True. esta función verifica si la cadena contiene solo letras y números\nprint(str1.isdigit()) # Verificación: False. esta función verifica si la cadena contiene solo números\nprint(str1[0]+str1[1]+str1[2]+str1[3]) # Indexación: Hola\nprint(str1[::-1]) # Inversión: aloH\nprint(str1 == str1[::-1]) # Palíndromos: False (Hola != aloH)\nprint(sorted(str1) == sorted(str2)) # Anagramas: False (Hola != Mundo). anagrama es una palabra o frase que resulta de la transposición de letras de otra palabra o frase\nprint(\"a\" in str1) #Búsqueda: True. verifica si la letra a está en la cadena\nprint('Saludo: {}, lenguaje: {}'.format(str1,str2)) #Formateo: Saludo: Hola, lenguaje, Mundo\nprint(list(str1)) # Transformacion de cadena a lista: ['H', 'o', 'l', 'a']\n\n# EXTRA\n'''Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos: palabras que se leen igual de izquierda a derecha que de derecha a izquierda\n * - Anagramas: palabras que tienen las mismas letras pero en diferente orden\n * - Isogramas: palabras que no tienen letras repetidas'''\n\n# quiero un programa que haga todas las comprobaciones en la misma funcion\ndef check(word1:str,word2:str):\n    print(f'La palabra {word1} es un palíndromo?: {word1==word1[::-1]}')\n    print(f'La palabra {word2} es un palíndromo?: {word2==word2[::-1]}')\n    print(f'{word1} es un anagrama de {word2}?: {sorted(word1) == sorted(word2)}')\n    print(f'{word1} es un isograma?: {len(set(word1)) == len(word1)}')\n    print(f'{word2} es un isograma?: {len(set(word2)) == len(word2)}')\n\nword1 = \"reconocer\"\nword2 = \"carrera\"\nword3 = \"murcielago\"\nword4 = \"anagrama\"\nword5 = 'amor'\nword6 = 'roma'\ncheck(word1,word2) \ncheck(word3,word4)\ncheck(word5,word6)"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/santyjL.py",
    "content": "# 04 CADENAS DE CARACTERES\n\n\"\"\"\n/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\"\"\"\n\nString = \"HOLA MUNDO\"\nString2 = \"ESTO ES PYTHON\"\n# Acceso a un caracter\nprint(\"Acceso a un caracter:\")\nprint(String[2])\n\n# Subcadena\nprint(\"\\nSubcadena:\")\nprint(String[0:4])\nprint(String[-3:-1])\n\n# Longitud\nprint(\"\\nLongitud:\")\nprint(\"Cantidad de caracteres en el string:\", len(String))\n\n# Concatenación\nprint(\"\\nConcatenación:\")\nString3 = String + String2\nprint(\"Cadena concatenada:\", String3)\n\n# Repetición\nprint(\"\\nRepetición:\")\nprint(String3 * 2)\n\n# Recorrido\nprint(\"\\nRecorrido:\")\nfor caracter in String3:\n    print(caracter, end=\".\")\n\n# Conversiones\nprint(\"\\n\\nConversiones:\")\n\n# Minúsculas\nprint(\"Minúsculas:\", String3.lower())\n\n# Mayúsculas\nprint(\"Mayúsculas:\", String3.upper())\n\n# Reemplazo\nprint(\"Reemplazo:\", String3.replace(\"O\", \"0\"))\n\n# Separación\nprint(\"Separación:\", String3.split(\" \"))\n\n# Unión\nprint(\"Unión:\", \"\".join(String3))\n\n# Interpolación\nprint(f\"\\nInterpolación:\\nEl texto original es: {String}, y ahora es {String3}\")\n\n# Verificación\nprint(\"\\nVerificación:\")\nif \"HOLA\" in String3:\n    print(f\"HOLA está en: {String3}\")\n\n# Métodos extras\nprint(\"\\nMétodos extras:\")\nprint(\"Es alfabético:\", String3.isalpha())\nprint(\"Capitalizado:\", String3.capitalize())\nprint(String3.count(\"O\"))\n\n\n###DIFICULTAD EXTRA\n\ndef palidromo (texto):\n    \"el palidromo son las paralabras que se leen igual de al reverso\"\n\n    if texto != texto[::-1]: #le da vuelta al texto\n        return \"NO ES UN PALIDROMO \"\n\n    else:\n        return f\"{texto} es un palidromo\"\n\n\ndef Anagramas(texto1 , texto2):\n    \"un anagrama son 2 palabras que contienen las misma letras\"\n\n    if len(texto1) != len(texto2):\n        return \"no es un anagrama\"\n\n\n    for caracter  in texto1 :\n        if caracter not in texto2:\n            return \"no es un anagrama\"\n\n    return \"si es un anagrama\"\n\n\ndef Isogramas(texto : str):\n    \"un isograma es una palabra o frase donde no hay caracteres repetidos\"\n\n    textocopy=texto\n    texto.split()\n    texto = set(texto)\n    texto = \"\".join(texto)\n\n    if len(texto) != len(textocopy):\n        return \"no es un isograma\"\n\n    return \"si es un isograma\"\n\n\nprint(palidromo(\"reconocer\"))\nprint(Anagramas(\"amor\" , \"romaa\"))\nprint(Isogramas(\"maximo\"))"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/sarismejiasanchez.py",
    "content": "# #04 CADENAS DE CARACTERES\n\"\"\"\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, \nverificación...\n *\n\"\"\"\n# Creando un string\nprint(\"Creando un string\".upper())\n\nletter = \"S\"                        # Un string puede ser un caracter o múltiples cadenas de texto\nprint(letter)                       # S\nprint(type(letter))                 # <class 'str'>\n\nname = \"Sara Mejia\"                 # Se pueden definir con comillas dobles \" \"\nprint(name)                         # Sara\nprint(type(name))                   # <class 'str'>\nalias = 'srismejiasanchez'          # Se pueden definir con comillas simples ' '\nprint(type(alias))                  # <class 'str'>\n\nmultiline_string = \"\"\"\\nEste es un string\ncon multiples\nlineas\\n\"\"\"\nprint(multiline_string)             # String multilinea con caracter de escape para salto de linea\n\nmultiline_string = '''Este también\nes un string\ncon multiples\nlineas'''\nprint(multiline_string)\n\n# Acceso a caracteres específicos\nprint(\"\\nAcceso a caracteres específicos\".upper())\n\nlanguage = \"Python\"\n# En programación los índices comienzan en cero\nprint(language[0])              # P\nprint(language[2])              # t\nprint(f\"Último carácter: {language[-1]}\")   # El recorrido inverso comienza en -1\n\n# Subcadenas\nprint(\"\\nSubcadenas\".upper())\ntext = \"Roadmap Retos de Programacion\"\ntext_slice = text[7::]  # Retos de Programacion\nprint(f\"Texto original: {text}\")\nprint(f\"Slicing: {text_slice}\")\n\n# Longitud\nprint(\"\\nLongitud\".upper())\ntext = \"Thirty Days Of Python\"\nprint(f\"La longitud de la cadena {text} es {len(text)} caracteres.\")\n\n# Concatenación\nprint(\"\\nConcatenación\".upper())\nname = \"Sara\"\nsurname = \"Mejia\"\nage = 31\n\nfull_name = name, surname\nprint(\"Mi nombre es:\", name , surname)      # Mi nombre es: Sara Mejia\n\ninformation = \"Nombre: \" + name + \", Apellido: \" + surname + \", Edad: \" + str(age)\nprint(information)      # Nombre: Sara, Apellido: Mejia, Edad: 31\n\ninformation = f\"Mi nombre es {name} {surname}, y tengo {age} años.\"\nprint(information)      # Mi nombre es Sara Mejia, y tengo 31 años.\n\nprint(\"\\n --Secuencias de Escape--\".upper())\nprint(\"(\\\\n) Salto de línea: \\nHola!\")   # Salto de línea\nprint(\"(\\\\t) Esto es un \\t tabulador.\")   # Tabulación (4 espacios)\nprint('(\\\\) Símbolo backslash (\\\\)') # Simbolo backslash\nprint('Asi se incluye un texto entre comillas: \"Hello, World!\\\"') # Comillas dobles dentro de comillas simples\n\n# Repetición\nprint(\"\\nRepetición\".upper())\ntext = \"Hello, Python! \"\nprint(text * 4)     # Hello, Python! Hello, Python! Hello, Python! Hello, Python!\n\n# Recorrido\nprint(\"\\nRecorrido\".upper())\nlanguage = \"Python\"\n\n# Recorrido de izquierda a derecha\nfor letter in language:\n    print(letter)\n\n# Recorrido inverso y paso a mayúscula\nfor letter in language[::-1]:\n    print(letter.upper())\n\n\n# Conversión a mayúsculas y minúsculas\nprint(\"\\nConversión a mayúsculas y minúsculas.. y métodos adicionales\".upper())\ncourse = \"Roadmap Retos Programación\"\nprint(f\"Mayúscula: {course.upper()}\")\nprint(f\"Minúscula: {course.lower()}\")\n# Convierte el primer caracter del string a letra capital\nprint(f\"Letra Capital: {course.capitalize()}\")  # Roadmap retos programacion\ntext = \"texto para titulo\"\n# Convierte a mayúscula inicial cada letra inicial del texto\nprint(f\"Titulo: {text.title()}\")    # Texto Para Titulo\n\n\n# Reemplazo\nprint(\"\\nReemplazo\".upper())\n# Replace the word coding in the string 'Coding For All' to Python.\ntext = \"Coding For All\"\nprint(text.replace(\"Coding\", \"Python\"))\n\n# División\nprint(\"\\nDivisión\".upper())\ntext = \"Roadmap Retos Programacion\"\nprint(text.split(\" \"))  # Separa la cadena por espacios en blanco\ntext = \"Manzana,Naranja,Platano\"\nprint(text.split(\",\"))  # Separa la cadena por comas\n\n# Tambien podríamos convertir el string a lista\ntext = list(text)\nprint(f\"String a lista: \\n{text}\")\n\n# Unión\nprint(\"\\nUnión\".upper())\n\nlanguages = ['Python', 'JavaScript', 'Java', 'C#']\nresult = ', '.join(languages)\nprint(f\"Lenguajes: {languages}\")\nprint(f\"Unión: {result}\")\n\n# Interpolación\nprint(\"\\nInterpolación\".upper())\n\n# f-strings\nname = \"Sara\"\nsurname = \"Mejia\"\nsaludo = f\"Hola {name} {surname}! ¿Cómo estás?\"\nprint(result)   # Hola Sara Mejia! ¿Cómo estás?\n\n# format\nsaludo = \"Hola {} {}! ¿Cómo estás?\".format(name, surname)\nprint(saludo)\n\n# %\nsaludo = \"Hola %s %s. ¿Cómo estás?\" % (name, surname) # %s strings\nprint(saludo)   # Hola Sara Mejia. ¿Cómo estás?\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n* Crea un programa que analice dos palabras diferentes y realice comprobaciones\n* para descubrir si son:\n* - Palíndromos\n* - Anagramas\n* - Isogramas\n\"\"\"\nprint(\"\\nDIFICULTAD EXTRA\")\nfrom collections import Counter\n\ndef check_words(word_1, word_2):\n    # Convertimos las palabras a minúsculas para evitar diferencias entre mayúsculas y minúsculas\n    word_1, word_2 = word_1.lower(), word_2.lower()\n    \n    # Palíndromos\n    # Palabras que se leen igual de izquierda a derecha y viceversa.\n    print(f\"¿{word_1} es Palindromo?: {word_1 == word_1[::-1]}\")\n    print(f\"¿{word_2} es Palindromo?: {word_2 == word_2[::-1]}\")\n\n    # Anagramas\n    # Ambas palabras tienen las mismas letras, solo en diferente orden.\n    \"\"\"\n    Counter crea un diccionario donde las claves son los caracteres y los valores son las frecuencias de esos caracteres.\n    \"\"\"\n    print(f\"¿{word_1} y {word_2} son Anagramas?: {Counter(word_1) == Counter(word_2)}\")\n\n    # Isogramas\n    # Palabras en las que ninguna letra se repite.\n    print(f\"¿{word_1} es Isograma?: {len(word_1) == len(set(word_1))}\")\n    print(f\"¿{word_2} es Isograma?: {len(word_2) == len(set(word_2))}\")\n\n    \ncheck_words(\"oso\", \"reconocer\")\ncheck_words(\"acto\", \"taco\")\ncheck_words(\"cielo\", \"mundo\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/sorubadguy.py",
    "content": "\"\"\"\nCadenas de caracteres\n\"\"\"\ncadena = \"Hola Soy una cadena de caracteres\"\ncadena2 = '  yo tambien lo soy    '\ncadena3 = \"\"\"--soy una\ncadena escrita en\nvarias lineas--\n\"\"\"\ncadena4 = \"soy\"\n\nprint(cadena)\nprint(cadena2)\nprint(cadena3)\nprint(cadena[3])\nprint(len(cadena)) #tamaño de la cadena\nprint(\"una\" in cadena) #compruebo si una cadena esta en la cadena\nprint(\"sde\" in cadena)\nprint(cadena4 in cadena)\nprint(cadena[3:13]) #Selecciono un rango de caracteres dentro de la cadena\nprint(cadena[:13]) #muestro desde el inicio hasta el caracter indicado\nprint(cadena[13:]) #mustro desde el caracter indicado hasta el final de la cadena\nprint(cadena[-8:]) #Al utilizar numeros negativos como indice, empieza a contar posiciones desde el final\nprint(cadena.upper()) #Todos los caracterse pasan a ser mayusculas\nprint(cadena.lower()) #Todos los caracteres pasan a ser minusculas\nprint(cadena2.strip()) #quita los espacion en blanco del principio de la cadena\nprint(cadena.replace(\"a\", \"t\")) #reemplaza todas las coincidencias con el primer parametro con el segundo\nprint(cadena.split(\" \")) #devuleve una lista de substrings separadas por el caracter dado\nprint(cadena.split(\"a\"))\n\ncadena5 = cadena2 + cadena3\nprint(cadena5)\n\ncosto = 34\nprint(f\"el costo del producto es de {costo:.3f}\") #puedo indicar en cuantos decimales puedo mostrar de un numero\nprint(\"puedo usar el simbolo \\\\ para evadir la \\\"funcionalidad\\\" de un caracter en especifico\")\n\n#Metodos\nprint(\"\\n\\n\")\nprint(\"convierte la primer letra de la cadena en mayuscula\".capitalize()) #convierte la primer letra de la cadena en mayuscula\nprint(\"CONVIERTE TODO EL TEXTO EN MINUSCULA\".casefold())\ncentrar = \"centra el contenido \\\"X\\\" caracteres\"\nprint(centrar.center(50))\nprint(centrar.center(50, \"_\"))\nprint(\"Muestra la cantidad de ocurrencias en un string de un valor especifico\".count(\"un\"))\nprint(\"codifica caracteres especiales: Ståle\".encode())\nprint(\"devuelve True si termina con el valor especificado\".endswith(\"cado\"))\nprint(\"devuelve True si termina con el valor especificado\".endswith(\"valor\"))\nprint(\"Especifica el valor de las t\\ta\\tb\\tu\\tl\\ta\\tc\\ti\\to\\tn\\te\\ts\".expandtabs(5))\nprint(\"busca un valor especifico y devuleve en que posicion se encontro\".find(\"valor\")) #En caso de no encotrar ocurrencias devuelve -1\nprint(\"da formato a un texto {costo:.2f}\".format(costo = 50))\nprint(\"busca un valor especifico y devuleve en que posicion se encontro\".index(\"valor\")) #En caso de no encontrar ocurrencias devuelve un error\nprint(\"TrueS1T0d0sLosCaracteresSonAlfanumericos\".isalnum())\nprint(\"TrueSiTodosLosCaracteresPertenecenAlAlfabeto\".isalpha())\nprint(\"True si todos l0s c4ract3res corresponden con los valores ascii\".isascii())\nprint(\"345\".isdecimal()) #solo permite numeros decimales, es decir del 0 al 9\nprint(\"3\\u00B2 \",\"\\u00B2\".isdigit()) #Permite decimales, aunque estos sean por ejemplo decimales\nprint(\"True_si_es_un_identificado_valido\".isidentifier()) #Se considera identificador si solo posee caracteres alfanumericos, es decir, (0-9) (a-z) o \"_\"\nprint(\"true si todos los carecteres estan en minusculas\".islower())\nprint(\"2234567\".isnumeric()) #devuelve true si todos sus caracteres son numeros\nprint(\"true si la cadena es imprimible\".isprintable())\nprint(\"              \".isspace()) #True si todos los caracteres de la cadena son \" \" espacios\nprint(\"True Si Corresponde Con La Norma De Titulos\".istitle()) #todas las palabras deben comenzar con una mayuscula y seguir con minusculas\nprint(\"TRUE SI TODAS LAS LETRAS DE LA CADENA SON MAYUSCULAS\".isupper())\nlista_nombres = (\"lucas\", \"pedro\", \"gaston\")\nprint(\"#\".join(lista_nombres)) #concatena con el caracter indicado un elemento iterable\nprint(\"ljust()\".ljust(30), \"devuelve una version justificada hacia la izquiera\")\nprint(\"CONVIERTE TODO EN MINUSCULAS\".lower())\nprint(\"quita los espacios\",\"            que se encuentren              \".lstrip(), \"a la izquierda\")\ncentrar = \"Me van cambiar las letras \\\"a\\\" por letras \\\"T\\\"\"\nmapa = str.maketrans(\"a\", \"t\") #genera un mapa de caracteres\nprint(centrar.translate(mapa)) #translate intercambia la primera letra del mapa de caracteres por la segunda\nprint(\"Retorna una tupla con 3 resultados:lo que esta antes de la cadena indicada, la cadena, y lo que esta despues\".partition(\"indicada\"))\nprint(\"Reemplaza un caracter especifico por otro\".replace(\"e\",\"j\"))\nprint(\"devuelve la ultima posicion en la que se encontro el string dado\".rfind(\"s\"))\nprint(\"devuelve la ultima posicion en la que se encontro el string dado\".rindex(\"s\")) #da error en caso de no encontrarlo\nprint(\"justifica hacia la derecha\".rjust(40))\nprint(\"Realiza lo mismo que particion, salvo que usa la ultima ocurrencia en el string\".rpartition(\"l\"))\nprint(cadena.rsplit(\" \", 2))\nprint(\"quita los espacio\", \"                  de               \".rstrip(), \"la derecha\")\nprint(cadena3.splitlines()) #genera una lista a partir de las lineas de un strin\nprint(\"True si el estring comienza con la cadena dada\".startswith(\"Tr\"))\nprint(\"InViErTe MaYuScUlAs Y mInUsCuLaS\".swapcase())\nprint(\"convierte todas las primeras letras en mayusculas\".title())\nprint(\"rellena los strigns con 0 hasta que\\n\".zfill(10), \"llegan a\\n\".zfill(10), \" \\\"X\\\" caracteres\".zfill(25))\n\n\"\"\"\nExtra\n\"\"\"\ndef palindromo(palabra1: str, palabra2: str):\n    \n    if(palabra1[:] == palabra2[::-1]):\n        print(f\"{palabra1} y {palabra2} son palindromos entre si\")\n    else:\n        print(f\"{palabra1} y {palabra2} no son palindromos entre si\")\n\n        if(palabra1[:] == palabra1[::-1]):\n            print(f\"{palabra1} es palindromo\")\n\n        if(palabra2[:] == palabra2[::-1]):\n            print(f\"{palabra2} es palindromo\")\n\ndef anagrama(palabra1: str, palabra2: str):\n\n    palabra1 = palabra1.replace(\" \", \"\")\n    palabra2 = palabra2.replace(\" \", \"\")\n\n    if(len(palabra1) == len(palabra2)):\n        palabra1_ordenada = []\n        palabra2_ordenada = []\n        palabra1_ordenada = list(palabra1)\n        palabra2_ordenada = list(palabra2)\n        palabra1_ordenada.sort()\n        palabra2_ordenada.sort()\n\n        if(palabra1_ordenada == palabra2_ordenada):\n            print(f\"{palabra1} y {palabra2} son anagramas\")\n        else:\n            print(f\"{palabra1} y {palabra2} no son anagramas\")\n    else:\n        print(f\"{palabra1} y {palabra2} no son anagramas\")\n\ndef isograma(palabra1: str, palabra2: str):\n    contador1 = {}\n    contador2 = {}\n    iso = False\n    for i in range(0,len(palabra1)):\n        if(palabra1[i] not in contador1):\n            contador1[palabra1[i]] = palabra1.count(palabra1[i])\n\n    for i in range(0,len(palabra2)):\n        if(palabra2[i] not in contador2):\n            contador2[palabra2[i]] = palabra2.count(palabra2[i])\n\n    if(len(contador1) == len(contador2)):\n        for i in contador1:\n            if(i in contador2 and contador1[i] == contador2[i]):\n                iso = True\n            else:\n                iso = False\n                break;\n    \n    if iso:\n        print(f\"{palabra1} y {palabra2} son isogramas\")\n    else:\n        print(f\"{palabra1} y {palabra2} no son isogramas\")\n\ndef palabras(palabra1: str, palabra2: str):\n    isograma(palabra1, palabra2)\n    anagrama(palabra1, palabra2)\n    palindromo(palabra1, palabra2)\n\npalabras(\"cara\", \"arca\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/switchdays.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\n *   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\n *   interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n \"\"\"\n\n\n# Los palíndromos son palabras que se leen igual para alante que para atrás. Ejemplo: oso\ndef palindromo(palabra):\n    lista = list(palabra)\n    lista_reverse = lista.copy()\n    lista_reverse.reverse()\n    return lista == lista_reverse\n\n# Dos palagbras son anagramas si contienen las mismas letras. Ejemplo: roma y amor\ndef anagrama(palabra_1, palabra_2):\n    lista_1 = list(palabra_1)\n    lista_2 = list(palabra_2)\n    lista_1.sort()\n    lista_2.sort()\n    return lista_1 == lista_2\n\n# Un isograma es una palabra en la que todas sus letras son diferentes. Ejemplo: murciélago\ndef isograma(palabra):\n    lista = list(palabra)\n    conjunto_letras = set()\n    for letra in lista:\n        if letra in conjunto_letras:\n            return False\n        else:\n            conjunto_letras.add(letra)\n    return True\n\npalabra_1 = input(\"Introduce la primera palabra: \")\npalabra_2 = input(\"Introduce la segunda palabra: \")\n\nif palindromo(palabra_1):\n    print(palabra_1, \"Es un palíndromo.\")\nelse:\n    print(palabra_1, \"No es un palíndromo\")\n\nif palindromo(palabra_2):\n    print(palabra_2, \"Es un palíndromo\")\nelse:\n    print(palabra_2, \"No es un palíndromo\")\n\nif anagrama(palabra_1, palabra_2):\n    print(palabra_1, \"y \", palabra_2, \"son anagramas.\")\nelse:\n    print(palabra_1, \"y \", palabra_2, \"no son anagramas.\")\n\nif isograma(palabra_1):\n    print(palabra_1, \"Es un isograma.\")\nelse:\n    print(palabra_1, \"No es un isograma\")\n\nif isograma(palabra_2):\n    print(palabra_2, \"Es un isograma\")\nelse:\n    print(palabra_2, \"No es un isograma\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/thezhizn.py",
    "content": "''' Ejemplos de operacones con \nCadenas de caracteres / strings \n'''\na = \"Esto es una cadena de caracteres / str. \"\nprint(a)\n#esto es lo que seria una cadena de caracteres, string o str\nb = \"\"\"        Esto es string \n        que ocupa \n        varias lineas. \"\"\" # string en varias lineas\nprint(b)\n#para imprimir un string en varias lineas lo escribimos en tres comillas\nc = \"\"\"Este esta STR \\\n        ocupa \\\n        varias lineas \"\"\"\nprint(c)\n#podemos poner '\\' para que no aparezcan las tres linea y solo aparezcan con tres espacios en una sola linea\n\n\"unión\"\nd = \"hola\" + \"mundo\" \nprint(d)\n#Así podemos unir dos strings pero cuando se imprima salda 'holamundo' todo junto\n#para evitar eso escribe \"hola\" + \" mundo\" dejando un espacio ya sea en el \"hola \" o en \" mundo\"\n\n\"acceder a un caracter\"\ne = \"soy thezhizn\"\nprint(e[0])\nprint(e[3])\nprint(e[6]) #\nprint(e[10])\n#De esta forma podemos acceder a un caracter especifico\n#El primer caracter siempre vale 0 como podemos ver \"(e[0])\" es el caracter s\n#como podemos por con el \"(e[3])\" los espacios tambien cuentan como caracteres\n\n\"subcadenas\"\nprint(e[:3])\nprint(e[2:7])\nprint(e[-5:])\n#Subcadenas comienzan de izquierda a derecha comenzando desde el caracter 1\n#En el medio vamos de izquierda a derecha poniendo el par ordenado en la izquierda donde queremos iniciar y en la derecha donde quiere terminar\n#Para el final lo hacemos de derecha a izquierda comenzando desde el -1\n\n\"longitud\"\nf = \"¿cuanto mide este STR?\"\nprint(len(f))\n#Usamos la funcion \"len\" \"f\" mide 22 caracteres, recordando que los espacios tambien se cuentan\n\n\"concatenacion\"\nname = \"Migue Santiago\"\nsurname = \" Garbanzo Hernan\"\nprint(name + surname)\n#Para concatenar Strings es mas comun usar el + \n#los datos podemos sacarlos de variables con inputs\n#Recuerda poner espacios en los strings para que no aparecan pegados\n\n\"repeticion\"\ng = \"repeticion \" \nprint(g *2)\nh = \"hola \" *2 \nprint(h)\n#Esta es una forma de repetir funciones de una forma muy simple\n#Python no tiene formas mas complejas, de querer hacer cosas mas complejas tienes que hacer tu propia logica en una funcion\n\n\"recorrido\"\ni = \"python\"\nfor i in i:\n    print(i)\n#Para recorrer un String utilizamos el \"for\" que tambien usamos para el famoso fizz buzz\n\n\"conversion\"\nj = \"hola mundo\"\nprint(j.capitalize)\n#Este metodo vuelve la primera letra mayuscula\nprint(j.upper())\n#Para convertir de minusculas a mayusculas usamos el metodo .upper\nprint(j.lower())\n#Para convertir de mayusculas a minusculas usamos el metodo .lower\nprint(j.capitalize())\n#Para convertir solo la primera letra en mayuscula usamos el metodo .capitalize\nk = \"Soy Un Titulo\"\nprint(k.swapcase())\n#Este metodo cambia las mayusculas en minusculas y viceversa \nprint(k.lower())\nprint(k.title())\n#El metodo .title funciona de de tal forma que crea mayusculas en cada palabra de forma que sea un Titulo\n#La funcion hace eso apesar de que usamos en metodo .lower antes\n\n\"reemplazar\"\nl = \"yo soy yhechizn\"\nprint(l)\nprint(l.replace(\"yhechizn\",\"thezhizn\"))\n#De esta forma podemos reemplazar un texto especifico en nuesto STR\nm = \"aaaaaa\"\nprint(m)\nprint(m.replace(\"a\", \"b\",3))\n#de esta forma podemos reemplazar un numero de veces que queramos \n\n\"dividir\"\nn = \"Maria,Ana,Roger,Sandy,Michael\"\nprint(n.split(\",\"))\n#El metodo .split nos dividira nuestro String y nos devolvera una lista con los parametros\n#El metodo divide en base en lo que pongamos en medio de las comillas del .split, en este caso una \",\"\n\n\"union\"\nunion_1 = \"thezhizn\"\nunion_2 = \"zhizn98\"\nthe_union = set(union_1).union(union_2)\nprint(\"la union es \" + str(the_union))\n#esto nos mandara un conjunto/set con las letras que aparecen en los str\n\n\"interpolar\"\n\n'%d = Integer'\n'%f = Float'\n'%s = String'\n'%x = Hexadecimal'\n'%o = Octal'\n#cada uno representa que se usara para interpolar cada tipo de dato\no = 16\np = 3.14\nq = \"thezhizn\"\nprint(\"La edad de Jose es de %d \" % (o))\nprint(\"El valor de π creo que es %f\" % (p))\nprint(\"Mi nombre es %s\" % (q))\n#De esta forma es la que podemos usar las sintaxis\no = \"Maria\"\np = 6.5\nq = 2000 \nr = 5500\nprint(\"Ayer vi a {} pasear por el parque\" .format(o)) \nprint(\"{} es el resultado de dividor 13 entre 2\" .format(p))\nprint(\"La suma de {} + 3500 da resultado {}\" .format(q,r))\n#Tambien podemos interpolar usando el metodo .format \n#En este caso usamos {} para marcar la posicion a interpolar en lugas de los \"%d, %s...etc\"\nprint(f\"Ayer {o} salio a la tienda\")\nprint(f\"la divición de 13 entre 2 es igual a {p}\")\nprint(F\"Sumar {q} + 3500 resulta en {r}\")\n#Este metodo es exclusivo de Python y se le conoce como cadenas formateadas o cadenas f\n#al agregar f al principio crea un str interactivo en donde podemos poner variables o logica en la cadena de texto\nfrom string import Template\nexample_1 = Template(\"$a + 12 = 18\")\nexample_2 = Template(\"Hola $name que tal te fue ayer en $city\")\nprint(example_1.substitute({\"a\" : 6}))\nprint(example_2.substitute({\"name\" : \"thezhizn\", \"city\" : \"Cartago\" }))\n#Esta forma es la Clase Platilla en donde en el Template usamos \"$\" para crear una variable\n#en el .substitute vamos a crear un diccionario con el nombre de la variable en el template y un valor para la variable\n\n\"verificación\"\ns = \"holaa\"\nt = \"holaa\"\nu = \"Holaa\"\nprint(s == t)\nprint(t == u)\n#Asi podemos verificar si dos str son iguales (se toman en cuenta las mayusculas y los espacios)\nv = \"hola\"\nw = \"hola34\"\nprint(v.isalpha())\nprint(w.isalpha())\n#usando el metodo .isalpha podemos verificar con un true y false si los caracteres en el str son solo letras o no\nprint(k.islower())\n#El metodo .islower sirve para saber si todo el texto es todo minisculas y devolvera falso o cierto\nprint(k.isupper())\n#El metodo .islower sirve para saber si todo el texto es todo mayusculas y devolvera falso o cierto\nprint(w.isdigit())\n#sirve para saber si es solo digitos\n#hay muchos mas pero son demaciados. solo pon .is al lado de la variable en Python\n\n\"DIFICULTAD EXTRA\"\ndef my_extra():\n    print(\"\\nBienvenido al programa\")\n    \n    while True:\n\n        print(\"\\n1. palindromos\")\n        print(\"2. anagramas\")\n        print(\"3. isogramas\")\n        print(\"4. salir del programa\")\n        print(\"\")\n\n        opciones = input(\"\\nseleccione una opcion porfavor \")\n\n        match opciones:\n            case \"1\":\n                palabra_1 = input(\"Bienvenido a Palidromos.\\nPor favor ingresa una palabra. \").lower()\n                palabra_2 = palabra_1[::-1]\n                if palabra_1.isalpha() and palabra_1 == palabra_2:\n                    print(f\"La palabra {palabra_1} es un Palindromo\".upper())\n                else:\n                    print(f\"La palabra {palabra_1} no es un palindromo\".upper())\n            case \"2\":\n                print(\"Bienvenido a anagramas.\\nPorfavor incerte las palabras que quieras comparar. \")\n                palabra_1 = input(\"Palabra 1. \")\n                palabra_2 = input(\"Palabra 2. \")\n                if (sorted(palabra_1) == sorted(palabra_2)):\n                    print(f\"Las palabras {palabra_1} y {palabra_2} son anagramas\")\n                else:\n                    print(f\"Las palabras {palabra_1} y {palabra_2} no son anagramas\")\n            case \"3\":\n                palabra_1 = input(\"Bienvenido a isogramas.\\nInserta la palabra que quieres probar. \")\n                lista = list(palabra_1)\n                conjunto = set(lista)\n                if len(lista) == len(conjunto):\n                    print(f\"La palabra {palabra_1} es un isogramo\")\n                else:\n                    print(f\"La palabra {palabra_1} no es un isogramo\")\n            case \"4\":\n                print(\"Saliendo del sistema\")\n                break\n            case _:\n                print(\"por favor seleciona una opcion valida\")\nmy_extra()    \n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/thonys07.py",
    "content": "\"\"\" \n\n* EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n \n \"\"\"\ncadena:str=\"\" # cadena vacía\nprint(cadena)\ncadena = \"Estoy creando cadenas\" #cadena con comillas dobles\nprint(cadena)\ncadena = 'Estoy creando cadenas' #cadena con comillas simples\nprint(cadena)\ncadena=\"las cadenas no tienen limite de tamaño solamente el espacio en memoria que abarquen en el ordenador\"\nprint(cadena)\ncadena=\" Esto es una comilla doble \\\" de ejemplo dentro de una cadena\"\nprint(cadena)\ncadena =\"se puede incluir salto de linea utilizando el caracter \\n llevando el textro a otra linea (\\ n sin espacios)\"\nprint(cadena)\ncadena=\"al escribir la barra invertida \\ seguida de un numero se imprime el caracter correspondiente ejemple \\110 (\\ 110 sin espacios) es la 'H'\"\nprint(cadena)\ncadena = \"\"\" tambien se pueden\nescribir cadenas\nde varias lineas\nutilizando las triples comillas\n\"\"\"\nprint(cadena)\n\n#formateo de cadenas\na=\"Python \"\nb=\"es \"\nc=\"un lenguaje de programación de: \"\nd=10\ne=a+b+c+str(d) \nprint(e)\nf=\"Python es un lenguaje de programacion de: %a\" %d\nprint(f)\ns = \"Los números son %d y %d.\" % (5, 10)\nprint(s) #Los números son 5 y 10.\ns = \"Los números son {} y {}\".format(5, 10)\nprint(s) #Los números son {} y {}\".format(5, 10)\ns = \"Los números son {a} y {b}\".format(a=5, b=10)\nprint(s) #Los números son 5 y 10\na = 5; b = 10\ns = f\"Los números son {a} y {b}\"\nprint(s) #Los números son 5 y 10\na = 5; b = 10\ns = f\"a + b = {a+b}\"\nprint(s) #a + b = 15\ndef funcion():\n    return 20\ns = f\"El resultado de la función es {funcion()}\"\nprint(s) #El resultado de la funcion es 20\n\n#multiplicar string por un int\ns = \"Hola \" * 3\nprint(s) #HolaHolaHola\n#verificar si exite una string dentro de otra con in\nprint(\"mola\" in \"Python mola\") #True\nprint(\"Hola\" in \"Python mola\") #False\n\n#longitud\ncadena = \" esta es una cadena de texto con cierta longitud y muchos espacios, de manera que podamos ver su longitud de caracteres y buscar en valores altos o bajos\"\nlongitud=len(cadena)\nprint(longitud)\n\n#indexado de cadenas\nprint(cadena[0],cadena[-5])\n\n#Porcionando cadenas\nprint(cadena[:10])\nprint(cadena[::2])\nprint(cadena[1:2])\nprint(cadena[0:30:3])\n\n#capitalize\nprint(cadena.capitalize())\n\n#lower\nprint(cadena.lower())\n\n#Swapcase\ncadena= \"HolA ComO EsTaS\"\nprint(cadena.swapcase())\n\n#upper\nprint(cadena.upper())\n\n#contar fragmentos de cadenas\ncadena = \" esta es una cadena de texto con cierta longitud y muchos espacios, de manera que podamos ver su longitud de caracteres y buscar en valores altos o bajos\"\nprint(cadena.count(\"al\"))\n\n#Reconocer caracteres alfanumericos, alfabeticos\nstring=\"abcdefghijklmnopqrstuvwxyz\"\nprint(string.isalpha())\nstring=(\"1231456789abcdefghijklmnopqrstuvwxyz\")\nprint(string.isalnum())\n\n#Reconocer espacios\nprint(cadena.isspace())\n\nprint(\"EXTRA\\n\\n\\n\")\n\"\"\"\nEXTRA\n\"\"\"\ndef es_isograma(palabra):\n    return len(set(palabra)) == len(palabra)\n\ndef evaluador_de_palabras():\n    palabra1=input(\"Escribe la primera palabra: \").lower()\n    palabra2=input(\"Escribe la segunda palabra: \").lower()\n    inverted1=palabra1[::-1]\n    inverted2=palabra2[::-1]\n    sorted1=sorted(palabra1)\n    sorted2=sorted(palabra2)\n\n    if palabra1==inverted1:\n        print(f\"La palabra {palabra1} es un palindromo\")\n    else :\n        print(f\"La palabra {palabra1} no es un palindromo\")\n    if palabra2==inverted2:\n        print(f\"La palabra {palabra2} es un palindromo\")\n    else :\n        print(f\"La palabra {palabra1} no es un palindromo\")\n    if sorted1==sorted2:\n        print(f\"Las palabras {palabra1} y {palabra2} son anagramas\")\n    else :\n        print(f\"Las palabras {palabra1} y {palabra2} no son anagramas\")\n    if es_isograma(palabra1):\n        print(f\"{palabra1} es un isograma.\")\n    else:\n        print(f\"{palabra1} no es un isograma.\")\n\n    if es_isograma(palabra2):\n        print(f\"{palabra2} es un isograma.\")\n    else:\n        print(f\"{palabra2} no es un isograma.\")\n\nevaluador_de_palabras()\n    \n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/tito-delpino.py",
    "content": "#  * EJERCICIO:\n#  * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n#  * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n#  * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n#  *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n\ncadena = 'Esto es una cadena'\ncadena2 = ' Esto es otra cadena '\n\ncaracter = cadena[10] # accedemos al caracter en indice 10\nprint(caracter)\nsubcadena = cadena[5:15] # accede a una subcadena entre los indices indicados\nprint(subcadena)\nlongitud = len(cadena) # damos valor a la variable con la longitud de cadena\nprint(longitud)\nconcatenacion = cadena + ' ' + cadena2 # concatenamos cadenas\nprint(concatenacion)\nmayus = cadena.upper() # converion a mayusculas\nprint(mayus)\nminus = cadena.lower() # conversion a minusculas\nprint(minus)\nprimera_mayus = cadena.title() # primera letra de cada palabra en mayus\nprint(primera_mayus)\nsolo_inicio_mayus = cadena.capitalize() # solo primera letra del string en mayus\nprint(solo_inicio_mayus)\nprint(cadena * 3) # repeticion\nprint('a' in cadena) # a existe en cadena, printeara True\nremplazo = cadena.replace('a', 'e') # remplazamos las 'a' por 'e' dentro de la cadena\nprint(remplazo)\ndivision = cadena.split('t') # corta en elementos en el valor indicado,crea lista con las partes\nprint(division)\neliminacion_espacios = cadena2.strip() # elimina los espacios al inicio y fin de la cadena\nprint(eliminacion_espacios)\ncantidad = cadena.count('a') # cuenta las veces que esta lo indicado en el string\nprint(cantidad)\nformateo = 'String1:{}, string2:{}'.format(cadena, cadena2) # da formato al la salida\nprint(formateo)\ninterpolacion = f'String1:{cadena}, string2:{cadena2}' # da formato al la salida interpolando tipos de datos\nprint(interpolacion)\nlista = [cadena, ',', cadena2, '!']\nprint(\" \".join(lista)) # unifica en un mismo string los varoles de una lista separados por el valor indicado\n\ncadena = 'sdfsdf'\nprint(cadena.isalpha()) # cheque si el string es alfanumerico\nprint(cadena.isalnum()) # chequea si el strin es numerico\n\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n#  * para descubrir si son:\n#  * - Palíndromos\n#  * - Anagramas\n#  * - Isogramas\n\n\ndef check_palabras(palabra1, palabra2):\n    # Palindromo\n    print(f'La palabra \"{palabra1}\" es palindromo? {palabra1 == palabra1[::-1]}')\n    print(f'La palabra \"{palabra2}\" es palindromo? {palabra2 == palabra2[::-1]}')\n    \n    # Anagramas\n    print(f'\"{palabra1}\" es anagrama de \"{palabra2}\"? {sorted(palabra1) == sorted(palabra2)}')\n\n    # Isogramas\n    def isograma(palabra):\n        carac_palabra = dict()\n        for carac in palabra:\n            # el caracter se agregara al diccionario con valor 0 si no existe o sumara 1 al valor si existe\n            carac_palabra[carac] = carac_palabra.get(carac, 0) +1\n        isograma = True\n        # creamos una lista con los valores obtenidos del diccionario\n        valores = list(carac_palabra.values())\n        # checkeamos de que tipo es el isograma\n        long_isograma = valores[0]\n        # Revisamos que todos los caracteres tengan el mismo conteo\n        for conteo_carac in valores:\n            if conteo_carac != long_isograma:\n                # si algun caracter tiene conteo distinto, no es isograma\n                isograma = False\n                break\n        return isograma\n\n\n    print(f'\"{palabra1}\" es un isograma? {isograma(palabra1)}')\n    print(f'\"{palabra2}\" es un isograma? {isograma(palabra2)}')\n\n\n\n\ncheck_palabras('amor', 'ramo')\ncheck_palabras('murcielago', 'reconocer')"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/toral24.py",
    "content": "'''\nEJERCICIO:\nMuestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n- Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n'''\n\ncadena = 'Hola mundo'\n\nprint(len(cadena)) #Ver la longitud de una cadena\n\nprint(cadena[3]) # Ver una letra de la cadena\n\nprint(cadena[2:6]) # Ver una subcadena\n\nprint(cadena.upper()) # Convertir la cadena en mayusculas\n\nprint(cadena.lower()) # Convertir la cadena en minusculas\n\nfor i in cadena:\n    print(i) # Recorrer una cadena\n\nprint('La frase más utilizada en la programación es: '+ cadena) # Concatenación\n\nprint(cadena*3) # Repetición de una cadena\n\nprint(cadena.replace('a','@')) # Reemplazo de letras\n\nprint(cadena[:4].isalpha()) # Verificar que se trata de una cadena (se ha puesto solo las 4 primeras letras porque al tener un espacio devolveria False)\n\ncadena = cadena.split(' ') # Divide la cadena en una lista en función del parametro que se le pasa como separador\n\nprint(cadena) \n\ncadena = ' '.join(cadena) # Une una lista en una cadena (deshace la operación anterior)\n\nprint(cadena)\n\nn = 22\n\nprint(\"%d esto es una cadena con interpolación %s\" %(n,cadena)) # Interpolación, se utiliza % + n,d,f,x o o en función del tipo de dato\n\n'''\nDIFICULTAD EXTRA (opcional):\nCrea un programa que analice dos palabras diferentes y realice comprobaciones para descubrir si son:\n    - Palíndromos\n    - Anagramas \n    - Isogramas\n'''\n\npalabra1 = input('Introduce la primera palabra')\n\npalabra2 = input('Introduce la segunda palabra')\n\ndef ver_palindromo(a,b):\n    cont1 = 0\n    cont2 = len(a) -1\n    while cont1 < cont2:\n        if a[cont1] != b[cont2]:\n            return False\n        cont1 += 1\n        cont2 -= 1\n    return True\n\ndef ver_anagrama(a,b):\n    return sorted(a)==sorted(b)\n\nif ver_palindromo(palabra1,palabra2):\n    print(f'la palabra {palabra1} es el palindromo de la {palabra2}')\nelse:\n    print('las palabras introducidas no son palindromos')\n\nif ver_anagrama(palabra1,palabra2):\n    print(f'la palabra {palabra1} es anagrama de la {palabra2}')\nelse:\n    print('las palabras introducidas no son palindromos')"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/victorfer69.py",
    "content": "#OPERACIONES\n\ns1 = \"Hola\"\ns2 = \"Python\"\n\n#Concatenacion\nprint(s1 + \", \" + s2 + \"!\")\n\n#Repetición\nprint(s1 * 3)\n\n#Indexación\nprint(s1[1] + s1[3] + s2[4])\n\n#Longitud\nprint(len(s1))\n\n#Slicing (porción)\nprint(s2[2:4])\nprint(s2[2:])\nprint(s2[:2])\n\n#Búsqueda\nprint(\"a\" in s1)\nprint(\"on\" in s1)\n\n#Reemplazo\nprint(s1.replace(\"o\",\"a\"))\n\n#División\nprint(s1.split(\"l\"))\n\n#Mayusculas y minúsculas\nprint(s1.upper())\nprint(s2.lower())\nprint(\"victor fer\".title())\nprint(\"victor fer\".capitalize())\n\n#Eliminacion de espacios al principio y al final\nprint(\"   victor fer    \")\nprint(\"   victor fer    \".strip())\n\n#Búsqueda al principio y al final\nprint(s1.startswith(\"Ho\"))\nprint(s1.startswith(\"la\"))\nprint(s1.endswith(\"Ho\"))\nprint(s1.endswith(\"la\"))\n\n#Búsqueda de posición\nprint(\"qwerty victor fer asdf\".find(\"victor\"))\nprint(\"qwerty victor fer asdf\".find(\"v\"))\n\n#Búsqueda de ocurrencia\nprint(\"qwerty victor fer asdf\".lower().count(\"e\"))\n\n#Formateo\nprint(\"Saludos, {} lenguaje {}!\".format(s1.lower(), s2))\n\n#Interpolacion\nprint(f\"Saludos, {s1.lower()} lenguaje {s2}!\")\n\n#Transformación de lista de caracteres\nprint(list(\"qwert asdf zxcv\"))\n\n#Transformación de lista en cadena\nli = [s1, \", \", s2, \"!\"]\nprint(\"\".join(li))\n\n#Transformaciones numéricas\ns4 = \"12345.123\"\ns5 = float(s4)\nprint(s5)\n\n\n#EJERCICIO EXTRA\n\ndef isPalindromo(palabra):\n    i = 0\n    cont = len(palabra) - 1\n    for i in palabra:\n        if i != palabra[cont]:\n            return False\n        cont -= 1\n    return True\n    \n\ndef isAnagrama(palabra1, palabra2):\n    if sorted(palabra1) == sorted(palabra2):\n        return True\n    else:\n        return False\n\n\ndef isIsograma(palabra):\n    tmp = dict()\n    for c in palabra:\n        tmp[c] = tmp.get(c, 0) + 1\n\n    values = list(tmp.values())\n    isogram_len = values[0]\n    for word_count in values:\n        if word_count != isogram_len:\n            return False\n\n    return True\n\n\ndef comprobaciones(palabra1: str, palabra2: str):\n\n    if isPalindromo(palabra1):\n        print(f\"Las palabras {palabra1} es palíndromo\")\n\n    if isPalindromo(palabra2):\n        print(f\"Las palabras {palabra2} es palíndromo\")\n\n    if isAnagrama(palabra1, palabra2):\n        print(f\"Las palabras {palabra1} y {palabra2} son anagramas\")\n\n    if isIsograma(palabra1):\n        print(f\"Las palabras {palabra1} es isogrma\")\n\n    if isIsograma(palabra2):\n        print(f\"Las palabras {palabra2} es isograma\")\n\ncomprobaciones(\"amor\", \"roma\")\ncomprobaciones(\"radar\", \"barco\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/warclimb.py",
    "content": "'''\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\n *   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\n *   interpolación, verificación...\n *\n'''\n\nfrom collections import Counter # necesario para contar letras en el ejercicio extra\n\n# el clásico string:\nhola = \"El veloz murcielago hindú comía feliz cardillo y kiwi.\"\nprint(hola)\n\n# subcadena, acceso a caracteres específicos\nsubcadena = hola[0:4]\nprint(subcadena)\n\n# longitud de la cadena\nprint(f\"La cadena {hola} tiene {len(hola)} caracteres\")\n\n# concatenación\ntest_concatenar = \"murcielago\" + \" \" + \"hipopotamo\" + \"(concatenado)\"\nprint(test_concatenar)\n\n# Aprovechamos la repeción para crear un separador\ndef separador():\n    print(\"-\" * 25)\n\nseparador()\n\n# recorrido\nfor i in hola:\n    print(i)\n\n# conversión a mayúsculas, minúsculas, capitalizar, titulo e invertir\ndef transformacion(s):\n    return s.upper(), s.lower(), s.capitalize(), s.title(), s.swapcase()\n\nprint(transformacion(hola))\n\n# reemplazo\nprint(f\"Transformacion: {hola.join(transformacion(hola))}\")\n\n# división\nseparacion = hola.split(\" \")\nprint(separacion)\nprint(separacion[-1]) # accedemos a la ultima palabra\n\n# unión, volvemos a unir la cadena con algun extra\ncontinua = \"con su amigo el hipopotamo.\"\ncontinua2 = continua.split(\" \")\n\n\ndel separacion[6:] # borramos parte de la lista\n\n# Ahora si, unimos las dos listas en un string\nunion = separacion + continua2\nunion = \" \".join(union)\nprint(union)\n\n# interpolación\n# Print con f-strings\nprint(f\"\"\"La frase inicial era:\n      \\n - '{hola}'\n      \\ny ahora es:\n      \\n - '{union}'\"\"\")\n\n# Print con format\nprint(\"\"\"La frase inicial era:\n      \\n - '{}'\n      \\ny ahora es:\n      \\n - '{}'\"\"\".format(hola, union))\n\n# verificación del string\nhola_num = \"1234\"\ntext = \"hola mundo, esto es una prueba 1 2 3\"\nprint(hola_num.isalnum()) # comprobamos si es alfanumerico en una variable de solo numeros\nprint(text.isalpha()) # comprobamos si es alfabetico\nprint(hola_num.isdigit()) # comprobamos si es numerico\nprint(text.islower()) # comprobamos si esta en minusculas\nprint(text.isupper()) # comprobamos si esta en mayusculas\nprint(text.isspace()) # comprobamos si esta en espacios\nprint(text.istitle()) # comprobamos si esta en titulo\nprint(text == \"\") # comprobamos si esta vacio\n\n\n'''\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n'''\n\n# Palindromo: que se lea igual de izquierda a derecha o al revés\ndef palindromo(*palabras):\n    for palabra in palabras:\n        palabra = palabra.lower()\n        if palabra == palabra[::-1]:\n            print(f\"{palabra} es un palíndromo\")\n        else:\n            print(f\"{palabra} no es un palíndromo\")\n  \n\n# Anagrama, comprobamos si cambiando el orden puede formar otra palabra\ndef anagrama(palabra1, palabra2):\n    orden_palabra1 = sorted(list(palabra1.lower()))\n    orden_palabra2 = sorted(list(palabra2.lower()))\n\n    if orden_palabra1 == orden_palabra2:\n        print(f\"{palabra1} y {palabra2} son anagramas\")\n    else:\n        print(f\"{palabra1} y {palabra2} no son anagramas\")\n\n# Isograma, cada letra aparece el mismo número de veces\ndef isograma(*palabras):\n    # convertimos la palabra a minusculas y contamos las letras\n    for palabra in palabras:\n        contador = Counter(palabra.lower())\n        # contamos cada letra y comprobamos si la longitud del set es 1, eso significa que todos los contadores de letras son iguales\n        if len(set(contador.values())) == 1:\n            print(f\"{palabra} es un isograma\")\n        else:\n            print(f\"{palabra} no es un isograma\")\n\n# Heterograma, que no tiene ninguna letra repetida\ndef heterograma(*palabras):\n    for palabra in palabras:\n        # convertir la palabra a minusculas\n        letras = set(palabra.lower())\n        # si tras meterlo en el set, tenemos el mismo numero de letras es que es un isograma\n        if len(letras) == len(palabra):\n            print(f\"{palabra} es un heterograma\")\n        else:\n            print(f\"{palabra} no es un heterograma\")\n\n# Empieza la fiesta\nseparador()\nprint(\"EJERCICIO EXTRA:\")\nseparador()\n\n# Comprobamos si son palindromos\npalindromo(\"sometemos\", \"cabeza\")\n\nseparador()\n\n# Comprobamos si dos palabras son anagramas\nanagrama(\"Lacteo\", \"Coleta\")\n\nseparador()\n\n# Comprobamos si es un isograma\nisograma(\"abba\", \"calabaza\")\n\nseparador()\n\n# comprobamos si es un heterograma\nheterograma(\"esternocleidomastoideo\", \"centrifugado\")\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/willianl731.py",
    "content": "# Día 4: Cadenas de Caracteres\n\n# --- String base para los ejemplos ---\ncadena = \"Hola, Mundo! Este es mi string de prueba.\"\nprint(f\"String original: '{cadena}'\\n\" + \"=\"*40)\n\n# --- Acceso y Subcadenas (Slicing) ---\nprint(\"\\n## 1. Acceso y Subcadenas ##\")\n# Acceso a un carácter específico (índice 0 es el primero)\nprimer_caracter = cadena[0]\nprint(f\"El primer carácter (índice 0) es: '{primer_caracter}'\")\n\n# Acceso al último carácter\nultimo_caracter = cadena[-1]\nprint(f\"El último carácter (índice -1) es: '{ultimo_caracter}'\")\n\n# Acceso a una subcadena (slicing)\nsubcadena = cadena[6:11] # Desde el índice 6 hasta el 10\nprint(f\"Subcadena de [6:11]: '{subcadena}'\")\n\n# --- Longitud ---\nprint(\"\\n## 2. Longitud de la Cadena ##\")\nlongitud = len(cadena)\nprint(f\"La longitud de la cadena es: {longitud} caracteres\")\n\n# --- Concatenación ---\nprint(\"\\n## 3. Concatenación ##\")\nsaludo = \"Mi nombre es Willian\"\nfrase_completa = cadena + \" \" + saludo\nprint(f\"Frase concatenada: '{frase_completa}'\")\n\n# --- Repetición ---\nprint(\"\\n## 4. Repetición ##\")\nrisa = \"Ja\"\nrisa_repetida = risa * 5\nprint(f\"String repetido: '{risa_repetida}'\")\n\n# --- Recorrido (Iteración) ---\nprint(\"\\n## 5. Recorrido de la Cadena ##\")\nprint(\"Imprimiendo cada carácter de la palabra 'Mundo':\")\nfor caracter in \"Mundo\":\n    print(f\"- {caracter}\")\n\n# --- Conversión a Mayúsculas y Minúsculas ---\nprint(\"\\n## 6. Mayúsculas y Minúsculas ##\")\nprint(f\"En mayúsculas: '{cadena.upper()}'\")\nprint(f\"En minúsculas: '{cadena.lower()}'\")\nprint(f\"Con primera letra en mayúscula: '{cadena.capitalize()}'\")\nprint(f\"Con cada palabra capitalizada: '{cadena.title()}'\")\n\n# --- Reemplazo ---\nprint(\"\\n## 7. Reemplazo de Caracteres ##\")\ncadena_reemplazada = cadena.replace(\"Mundo\", \"Python\")\nprint(f\"Reemplazando 'Mundo' por 'Python': '{cadena_reemplazada}'\")\n\n# --- División (Split) ---\nprint(\"\\n## 8. División en una Lista ##\")\npalabras = cadena.split() # Por defecto, divide por los espacios\nprint(f\"La cadena dividida en palabras: {palabras}\")\n\n# --- Unión (Join) ---\nprint(\"\\n## 9. Unión de Elementos ##\")\nlista_palabras = [\"Python\", \"es\", \"genial\"]\nfrase_unida = \" \".join(lista_palabras)\nprint(f\"Uniendo una lista con espacios: '{frase_unida}'\")\n\n# --- Interpolación (f-strings) ---\nprint(\"\\n## 10. Interpolación ##\")\nnombre = \"Willian\"\nedad = 51\nprint(f\"Interpolación: Me llamo {nombre} y tengo {edad} años.\")\n\n# --- Verificación (startswith, endswith, is...) ---\nprint(\"\\n## 11. Verificación de Contenido ##\")\nprint(f\"¿La cadena empieza con 'Hola'?: {cadena.startswith('Hola')}\")\nprint(f\"¿La cadena termina con 'prueba.'?: {cadena.endswith('prueba.')}\")\nprint(f\"¿La cadena '123' contiene solo dígitos?: {'123'.isdigit()}\")\nprint(f\"¿La cadena 'abc' contiene solo letras?: {'abc'.isalpha()}\")\n\n# Reto #04 - Analizador de Palabras\nprint(\"ANALIZADOR DE PALABRAS\")\nprint(\"=\" * 40)\n\n# Entrada de datos\npalabra1 = input(\" Ingresa la primera palabra: \")\npalabra2 = input(\"Ingresa la segunda palabra: \")\n\n# Limpiar palabras (minúsculas y sin espacios)\ndef limpiar_palabra(palabra):\n    return palabra.lower().replace(\" \", \"\").replace(\"á\", \"a\").replace(\"é\", \"e\").replace(\"í\", \"i\").replace(\"ó\", \"o\").replace(\"ú\", \"u\")\n\np1 = limpiar_palabra(palabra1)\np2 = limpiar_palabra(palabra2)\n\n# 1. Verificar Palíndromos\ndef es_palindromo(palabra):\n    return palabra == palabra[::-1]\n\npal1_palindromo = es_palindromo(p1)\npal2_palindromo = es_palindromo(p2)\n\n# 2. Verificar Anagramas\ndef son_anagramas(pal1, pal2):\n    return sorted(pal1) == sorted(pal2)\n\nanagramas = son_anagramas(p1, p2)\n\n# 3. Verificar Isogramas\ndef es_isograma(palabra):\n    return len(palabra) == len(set(palabra))\n\npal1_isograma = es_isograma(p1)\npal2_isograma = es_isograma(p2)\n\n# Mostrar resultados\nprint(\"\\nRESULTADOS DEL ANÁLISIS:\")\nprint(\"=\" * 40)\n\nprint(f\"Palabra 1: '{palabra1}' → '{p1}'\")\nprint(f\"Palabra 2: '{palabra2}' → '{p2}'\")\nprint(\"-\" * 40)\n\nprint(f\" ¿'{palabra1}' es palíndromo? {' Sí' if pal1_palindromo else '❌ No'}\")\nprint(f\" ¿'{palabra2}' es palíndromo? {' Sí' if pal2_palindromo else '❌ No'}\")\nprint(f\" ¿Son anagramas? {' Sí' if anagramas else '❌ No'}\")\nprint(f\" ¿'{palabra1}' es isograma? {' Sí' if pal1_isograma else '❌ No'}\")\nprint(f\" ¿'{palabra2}' es isograma? {' Sí' if pal2_isograma else '❌ No'}\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/willypaz243.py",
    "content": "\"\"\"Todo lo que se puede hacer con strings en python\"\"\"\nimport sys\nfrom typing import Any\n\nfrom colorama import Fore, Style\n\n\ndef print_colored(name: str, value: Any, description: str, *args: list[str]):\n    \"\"\"Print colored\"\"\"\n    string = Style.RESET_ALL + name + \" \"\n    string += Fore.RED + str(value) + \" \"\n    string += Fore.GREEN + description\n    string += \" \".join([str(arg) for arg in args])\n    print(string.strip())\n\n\ndef string_functions(string: str) -> None:\n    \"\"\"Todas las funciones que contiene el obejeto string\"\"\"\n    print(f\"Original String: {string}\\n\")\n\n    print_colored(\n        \"1. capitalize():\",\n        string.capitalize(),\n        \"Retorna el string con el primer caracter en Mayuscula\",\n    )\n    print_colored(\n        \"2. casefold():\",\n        string.casefold(),\n        \"Retorna el string con todos los caracteres en minusculas\",\n    )\n    print_colored(\n        \"3. center(20, '*'):\",\n        string.center(20, \"*\"),\n        \"Retorna un string del tamaño n=20 con el string original en el centro\",\n    )\n    print_colored(\n        \"4. count('l'):\",\n        string.count(\"l\"),\n        \"Cuenta las veces que aparece el sub-string 'l' en el string\",\n    )\n    print_colored(\n        \"5. encode():\",\n        string.encode(),\n        \"Convierte el string a bytes\",\n    )\n    print_colored(\n        \"6. endswith('world'):\",\n        string.endswith(\"world\"),\n        \"Comprueba si el string termina en 'world'\",\n    )\n    print_colored(\n        \"7. find('l'):\",\n        string.find(\"l\"),\n        \"Retorna el indice inicial de la primera vez que aparece el sub-string 'l'\",\n    )\n    print_colored(\n        \"8. format('John'):\",\n        string.format(\"John\"),\n        \"Reemplaza \\{\\} con 'John'\",\n    )\n    try:\n        print_colored(\n            \"9. index('l'):\",\n            string.index(\"l\"),\n            \"Hace exactamente lo mismo que 'find('l')'\",\n        )\n    except ValueError as error:\n        print_colored(\n            \"9. index('l'):\",\n            error,\n            \"Hace lo mismo que 'find('l')' pero lanza ValueError si no encuentra el subtring\",\n        )\n    print_colored(\n        \"10. isalnum():\",\n        string.isalnum(),\n        \"Verifica si el string es numerico o alfabético\",\n    )\n    print_colored(\n        \"11. isalpha():\",\n        string.isalpha(),\n        \"Verifica si el string es solamente alfabético\",\n    )\n    print_colored(\n        \"12. isdecimal():\",\n        string.isdecimal(),\n        \"Verifica si todos los caracteres en el string son decimales\",\n    )\n    print_colored(\n        \"13. isdigit():\",\n        string.isdigit(),\n        \"Verifica si todos los caracteres en el string son dígitos\",\n    )\n    print_colored(\n        \"14. islower():\",\n        string.islower(),\n        \"Verifica si todos los caracteres en el string están en minúsculas\",\n    )\n    print_colored(\n        \"15. isnumeric():\",\n        string.isnumeric(),\n        \"Verifica si todos los caracteres en el string son numéricos\",\n    )\n    print_colored(\n        \"16. isspace():\",\n        string.isspace(),\n        \"Verifica si todos los caracteres en el string son espacios en blanco\",\n    )\n    print_colored(\n        \"17. istitle():\",\n        string.istitle(),\n        \"Verifica si el string está en formato de título (cada palabra comienza con mayúscula)\",\n    )\n    print_colored(\n        \"18. isupper():\",\n        string.isupper(),\n        \"Verifica si todos los caracteres en el string están en mayúsculas\",\n    )\n    print_colored(\n        \"19. join(['a', 'b', 'c']):\",\n        \"-\".join([\"a\", \"b\", \"c\"]),\n        \"Une elementos de un iterable (por ejemplo, una lista) en un string utilizando el string como separador\",\n    )\n    print_colored(\n        \"20. ljust(20, '*'):\",\n        string.ljust(20, \"*\"),\n        \"Retorna un string justificada a la izquierda en un ancho dado, con caracteres de relleno opcionales\",\n    )\n    print_colored(\n        \"21. lower():\", string.lower(), \"Retorna una copia de el string en minúsculas\"\n    )\n    print_colored(\n        \"22. lstrip():\",\n        string.lstrip(),\n        \"Elimina los espacios en blanco a la izquierda de el string\",\n    )\n    print_colored(\n        \"23. partition('l'):\",\n        string.partition(\"l\"),\n        \"Divide el string en tres partes usando un separador y devuelve una tupla\",\n    )\n    print_colored(\n        \"24. replace('l', 'x'):\",\n        string.replace(\"l\", \"x\"),\n        \"Reemplaza todas las ocurrencias de un sub-string con otra\",\n    )\n    print_colored(\n        \"25. rfind('l'):\",\n        string.rfind(\"l\"),\n        \"Similar a find(), pero busca desde el final de el string\",\n    )\n    try:\n        print_colored(\n            \"26. rindex('l'):\",\n            string.rindex(\"l\"),\n            \"Similar a index(), pero busca desde el final de el string\",\n        )\n    except ValueError as error:\n        print_colored(\n            \"26. rindex('l'):\",\n            error,\n            \"Similar a index(), pero busca desde el final de el string\",\n        )\n    print_colored(\n        \"27. rjust(20, '*'):\",\n        string.rjust(20, \"*\"),\n        \"Devuelve un string justificada a la derecha en un ancho dado, con caracteres de relleno opcionales\",\n    )\n    print_colored(\n        \"28. rpartition('l'):\",\n        string.rpartition(\"l\"),\n        \"Divide el string en tres partes usando un separador, comenzando desde el final\",\n    )\n    print_colored(\n        \"29. rsplit(' ', 1):\",\n        string.rsplit(\" \", 1),\n        \"Divide el string en sub-strings utilizando un separador desde la derecha\",\n    )\n    print_colored(\n        \"30. rstrip():\",\n        string.rstrip(),\n        \"Elimina los espacios en blanco a la derecha de el string\",\n    )\n    print_colored(\n        \"31. split(' '):\",\n        string.split(\" \"),\n        \"Divide el string en sub-strings utilizando un separador\",\n    )\n    print_colored(\n        \"32. splitlines():\",\n        string.splitlines(),\n        \"Divide el string en líneas y devuelve una lista de líneas\",\n    )\n    print_colored(\n        \"33. startswith('Hello'):\",\n        string.startswith(\"Hello\"),\n        \"Verifica si el string comienza con el prefijo especificado\",\n    )\n    print_colored(\n        \"34. strip():\",\n        string.strip(),\n        \"Elimina los espacios en blanco al principio y al final de el string\",\n    )\n    print_colored(\n        \"35. swapcase():\",\n        string.swapcase(),\n        \"Intercambia mayúsculas y minúsculas en el string\",\n    )\n    print_colored(\n        \"36. title():\",\n        string.title(),\n        \"Devuelve una versión de el string con cada palabra en mayúsculas\",\n    )\n    print_colored(\n        \"37. upper():\", string.upper(), \"Devuelve una copia de el string en mayúsculas\"\n    )\n    print_colored(\n        \"38. zfill(20):\",\n        string.zfill(20),\n        \"Rellena el string con ceros a la izquierda hasta alcanzar la longitud especificada\",\n    )\n\n\ndef string_operations_example(string_1: str, string_2: str):\n    \"\"\"Operaciones que se pueden realizar a uno o varios strings\"\"\"\n    result_concat = string_1 + \", \" + string_2\n\n    print(\"Strings originales: \", string_1, string_2)\n\n    print_colored(\n        \"1. Concatenación: 'str1' + 'str2'\",\n        result_concat,\n        \"Combina dos o más strings en una sola string más larga\",\n    )\n\n    result_repeat = string_1 * 3\n    print_colored(\n        \"2. Repetición: str * 3\",\n        result_repeat,\n        \"Repite un string un número especificado de veces\",\n    )\n\n    result_format = \"La primera string es '{}' y la segunda es '{}'.\".format(\n        string_1, string_2\n    )\n    print_colored(\n        \"3. 'Formateo de \\{string\\}'.format('string'):\",\n        result_format,\n        \"Incorpora valores en un string usando marcadores de posición\",\n    )\n\n    len_str1 = len(string_1)\n    print_colored(\n        \"4. Longitud de el string len(str):\",\n        len_str1,\n        \"Obtiene la cantidad de caracteres en un string\",\n    )\n\n    first_char = string_1[0]\n    last_char = string_1[-1]\n    print_colored(\n        \"5. Acceso a caracteres por índice: str[0], str[-1]\",\n        f\"Primer caracter: {first_char}, Último caracter: {last_char}\",\n        \"Obtiene caracteres individuales de un string utilizando su posición\",\n    )\n\n    slice_str1 = string_1[1:4]\n    print_colored(\n        \"6. Slice de string (índices 1 a 3): str[1:4]\",\n        slice_str1,\n        \"Extrae una porción específica de un string\",\n    )\n\n    reverse_string = string_1[::-1]\n    print_colored(\n        \"7. invertir string: str[::-1]\",\n        reverse_string,\n        \"Invierte los caracteres del string\",\n    )\n\n\ndef is_palindrome(string: str):\n    return string[::-1] == string\n\n\ndef are_anagrams(string_1: str, string_2: str):\n    return sorted(string_1) == sorted(string_2)\n\n\ndef are_isograms(string_1: str, string_2: str):\n    return len(set(string_1)) == len(string_1) and len(set(string_2)) == len(string_2)\n\n\ndef main():\n    \"\"\"The Main Function\"\"\"\n\n    if not len(sys.argv) > 1:\n        raise Exception(\"Debe proporcionar algun argumento de string para la función.\")\n    string_functions(sys.argv[1])\n    if not len(sys.argv) > 2:\n        print(\"Pase 2 string como argumentos para mostrar las demas operaciones\")\n        return\n    string_operations_example(sys.argv[1], sys.argv[2])\n    print_colored(\n        \"Son Palindromos\",\n        f\"string 1: {is_palindrome(sys.argv[1])}, string 2: {is_palindrome(sys.argv[2])}\",\n        \"Verifica si el primer string es un palindromo del segundo string y biceversa\",\n    )\n    print_colored(\n        \"Son Anagramas\",\n        are_anagrams(sys.argv[1], sys.argv[2]),\n        \"Verifica si un string es un anagrama del otro string\",\n    )\n    print_colored(\n        \"Son Isogramas\",\n        are_isograms(sys.argv[1], sys.argv[2]),\n        \"Verifica si los strings son isogramas\",\n    )\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/worlion.py",
    "content": "\"\"\"\nCrea un programa que analice dos palabras diferentes y realice comprobaciones\npara descubrir si son:\n- Palíndromos\n- Anagramas\n- Isogramas\n\"\"\"\n\n#  --- Manejo de cadenas  --- \n\nmy_string = \"mi amigo Worlion es UN BRASAS\"\n\n# Operaciones contempladas en el enunciado\nprint(f\"Acceso a caracteres específicos: {my_string[3]}\") # ACCESO A CARACTERES ESPECIFICOS\nprint(f\"Acceso a subcadenas: {my_string[3:10]}\") # ACCESO A SUBCADENAS\nprint(f\"Longitud: {len(my_string)}\") # LONGITUD\nprint(f\"Concatenación: {my_string + ' y un pesado'}\") # CONCATENACIÓN\nprint(f\"Repetición: {my_string * 3}\") # REPETICIÓN\n\n# RECORRIDO\nprint(\"Recorrido:\")\nfor char in my_string:\n    if(char == \" \"): \n        print(\"\\t- Espacio!\")\n\nprint(f\"Conversión a mayúsculas: {my_string.upper()}\") # CONVERSIÓN A MAYÚSCULAS\nprint(f\"Conversión a minúsculas: {my_string.lower()}\") # CONVERSIÓN A MINÚSCULAS\nprint(f\"Reemplazo: {my_string.replace('mi', 'tu')}\") # REEMPLAZO\nprint(f\"División: {my_string.split(' ')}\") # DIVISIÓN\nprint(f\"Unión: {' '.join(my_string.split(' '))}\") # UNIÓN\nprint(f\"Interpolación: {my_string} y {my_string}\") # INTERPOLACIÓN\nprint(f\"Verificación: {'mi' in my_string}\") # VERIFICACIÓN\n\n# Otros\nprint(f\"capitalize: {my_string.capitalize()}\") # CAPITALIZADO\nprint(f\"casefold: {my_string.casefold()}\") # CASEFOLD\nprint(f\"center: {my_string.center(50, '-')}\") # CENTER\nprint(f\"count ('mi'): {my_string.count('mi')}\") # COUNT\nprint(f\"encode: {my_string.encode(encoding='utf-8', errors='strict')}\") # ENCODE\nprint(f\"endswith('AS'): {my_string.endswith('AS')}\") # ENDSWITH\nprint(f\"expandtabs: {my_string.expandtabs(tabsize=8)}\") # EXPANDTABS \nprint(f\"find('CARCAMUSA'): {my_string.endswith('CARCAMUSA')}\") # FIND\nprint(f\"isalpha: {my_string.isalpha()}\") # ISALPHA\n\n\"\"\"\nDIFICULTAD EXTRA (opcional): PALÍNDROMOS, ANAGRAMAS E ISOGRAMAS\n\"\"\"\n\ndef is_palindrome(word):\n    print(f\"Es palindromo si {word} == {word[::-1]}\")\n    return word == word[::-1]\n\ndef is_anagram(word1, word2):\n    print(f\"Son anagramas si {sorted(word1)} == {sorted(word2)}\")\n    return sorted(word1) == sorted(word2)\n\ndef is_isogram(word):\n    print(f\"{word} es palindromo si cada letra se repite el mismo número de veces!\")\n    my_dict = {}\n\n    for char in word:\n        if char in my_dict:\n            my_dict[char] += 1\n        else:\n            my_dict[char] = 1\n    \n    num : int = 0\n    \n    for i in my_dict.values():\n        if(num == 0):\n            num = i\n        elif(i != num):\n            return False\n        \n    return True\n    \n\ndef analyze_words(word1, word2):\n    print(f\"Las palabras {word1} y {word2} son:\")\n    print(f\"Palíndromos: {is_palindrome(word1)} and {is_palindrome(word2)}\")\n    print(f\"Anagramas: {is_anagram(word1, word2)}\")\n    print(f\"Isogramas: {is_isogram(word1)} and {is_isogram(word2)}\")\n\nanalyze_words(\"oso\", \"soso\")\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/xemita007.py",
    "content": "@ -1,99 +0,0 @@\n\n\n### Ejercicio\n\ncadena = \"mi cadena de texto 1\"\ncadena2= \"cadena de texto 2\"\n\n\n# Concatenación \nprint(cadena,cadena2)\nprint(cadena+\" \"+cadena2)\n\n# Repetición\ncadena = \"mi cdena de texto 1 con salto\\n\" # con salto de linea\nprint(cadena*3)\ncadena = \"mi cadena de texto 1 con tabulación\\t\" # con tabulación\nprint(cadena*3)\ncadena = \"mi cadena de texto 1 con barra\\\\\" # para representar barra invertida\nprint(cadena*3)\n\n# Cuenta en la cadena caracteres que cumplen con el requisito\nprint(cadena.count(\"mi\"))\n\n\n# Indexación\nprint(cadena[3] + cadena2[7] )\n\n# Por proporciones\nprint(cadena[1:5])\n\n# Longitud \nprint(len(cadena2))\nprint(len(cadena))\n\n#Minusculas, Mayusculas, Titulo\nprint(cadena.lower())\nprint(cadena.upper())\nprint(cadena.title())\ncadena = \"    mi cAdena de texto 1 con barra     \"\n# Sin Espacios principio y final\nprint(cadena.strip())\n\n#Busqueda\n\nprint(\"a\" in cadena)\nprint(\"Dentro de la cadena se encuentra de en: \",cadena.find(\"de\"))\n\n#Reemplazar\n\nprint(cadena.replace(\"a\",\"x\"))\n\n## Divide por donde esta el caracter asignado omitiendolo\nprint(cadena.split(\"a\")) \n\n#Unión\ncadena3=\"/\".join(cadena2)\n\nprint(cadena3)\n\n#Formateo\ncadena4=\" HUECOS \"\nprint(f\"yo puedo poner en los huecos {cadena4} lo que yo quiera {cadena4}\")\nprint(\"yo puedo poner en los huecos {} lo que yo quiera {}\".format(cadena4,cadena4))\n\n\n#Transformación de cadena a lista y viceversa\ncadena_list=list(cadena)\nprint(cadena_list)\n\nprint(\"\".join(cadena_list))\n\n# Comprobaciones\ncadena=\"11asdf\"\nprint(cadena.isalnum())\ncadena=\"asdf\"\nprint(cadena.isalpha())\ncadena=\"2\"\nprint(cadena.isdigit())\ncadena=\"1\"\nprint(cadena.isnumeric())\n\ndef comprueba(palabra: str, palabra2: str):\n    print(palabra[::-1])\n    print(f\"la palabra {palabra} es Palíndromos: \", palabra[::-1]==palabra)\n    print(f\"la palabra {palabra2} es Palíndromos: \", palabra2[::-1]==palabra2)\n\n\n    print(f\"la palabra {palabra2} es Anagramas de {palabra}: \", sorted(palabra)==sorted(palabra2))\n    palabra.lower()\ncomprueba(\"roma\",\"amor\")\n\n\n\ndef son_isogramas(word1: str):\n    set1 = set(word1)\n\n    print(f\"¿{word1} son isogramas?: {len(set1)==len(word1)}\")\n\nson_isogramas(\"python\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/yah1r404.py",
    "content": "\"\"\"\nOPERACIONES\n\"\"\"\n\ntext1 = \"Hola\"\ntext2 = \"Python\"\n\n# CONCATENACIÓN\n\nprint(text1 + \", \" + text2 + \"!\")\n\n# REPETICIÓN\n\nprint(text1 * 5)\n\n# INDEXACIÓN\n\nprint(text1[0] + text1[1] + text1[2] + text1[3])\n\n# LONGITUD\n\nprint(len(text2))\n\n# SLICING (PORCIÓN)\n\nprint(text2[2:6])\nprint(text2[2:])\nprint(text2[0:2])\nprint(text2[:2])\n\n# BÚSQUEDA\n\nprint(\"a\" in text1)\nprint(\"m\" in text1)\n\n# REEMPLAZO\n\nprint(text1.replace(\"o\", \"a\"))\n\n# DIVISIÓN\n\nprint(text2.split(\"t\"))\n\n# MAYÚSCULAS Y MINÚSCULAS\n\nprint(text1.upper())\nprint(text2.lower())\nprint(\"yahir sulu\".title())\nprint(\"yahir sulu\".capitalize())\n\n# QUITAR ESPACIOS\n\nprint(\" yahir sulu \".strip())\n\n# BÚSQUEDA AL PRINCIPIO Y AL FINAL\n\nprint(text1.startswith(\"Ho\"))\nprint(text1.startswith(\"Py\"))\nprint(text1.endswith(\"la\"))\nprint(text1.endswith(\"thon\"))\n\nname = \"Yahir sulu @yahir404.\"\n\n# BÚSQUEDA DE POSICIÓN\n\nprint(name.find(\"yahir\"))\nprint(name.find(\"Yahir\"))\nprint(name.find(\"y\"))\nprint(name.lower().find(\"y\"))\n\n# BÚSQUEDA DE OCURRENCIAS\n\nprint(name.lower().count(\"u\"))\n\n# FORMATEO\n\nprint(\"Saludo: {}, Lenguaje: {}!\".format(text1, text2))\n\n# INTERPOLACIÓN\n\nprint(f\"Saludo: {text1}, Lenguaje: {text2}!\")\n\n# TRANSFORMACIÓN EN LISTA DE CARÁCTERES\n\nprint(list(name))\n\n# TRANSFORMACIÓN DE LISTA EN CADENA\n\nlista1 = [text1, \", \", text2, \"!\"]\nprint(\"-\".join(lista1))\n\n# TRANSFORMACIÓN NUMÉRICA\n\nnum = \"12345\"\nnum = int(num)\nprint(num)\n\nnum1 = \"12345.54321\"\nnum1 = float(num1)\nprint(num1)\n\n\n# COMPROBACIONES VARIAS\n\nprint(text1.isalnum())\nprint(text1.isalpha())\nprint(text1.isnumeric())\n\n\"\"\"\nEXTRA TASK\n\"\"\"\n\ndef analizar_palabras(palabra1, palabra2):\n\n    # Palíndromo: se lee igual al derecho y al revés\n    print(f\"{palabra1} es palíndromo:\", palabra1 == palabra1[::-1])\n    print(f\"{palabra2} es palíndromo:\", palabra2 == palabra2[::-1])\n\n    # Anagrama: tienen las mismas letras, orden diferente\n    print(\"Son anagramas:\", sorted(palabra1) == sorted(palabra2))\n\n    def isogram(word: str) -> bool:\n    # Creamos un diccionario para contar las apariciones de cada letra\n        word_dict = dict()\n\n        for character in word:\n            word_dict[character] = word_dict.get(character, 0) + 1\n\n    # Obtenemos la lista de cuántas veces aparece cada letra\n        values = list(word_dict.values())\n    \n    # Tomamos el valor de repetición de la primera letra\n        isogram_len = values[0]\n        isogram = True\n\n    # Comparamos todas las repeticiones con la primera\n        for word_count in values:\n            if word_count != isogram_len:\n                isogram = False\n                break\n\n        return isogram\n# Ejemplos:\n    print(\"¿'aabbcc' es isograma?\", isogram(\"aabbcc\"))  # True\n    print(\"¿'aabc' es isograma?\", isogram(\"aabc\"))      # False\n    print(\"¿'abab' es isograma?\", isogram(\"abab\"))      # True\n\nanalizar_palabras(\"amor\", \"roma\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/ycanas.py",
    "content": "# --------- Strings\n\nmy_string: str = \"Soy un String\"\n\n# I. Acceso\nprint(\"Acceso:\", my_string[5])\n\n# II. Subcadenas\nmy_sub_string = my_string[0:10]\nprint(\"Subcadenas:\", my_sub_string)\n\n# III. Longitud\nprint(\"Longitud:\", len(my_string))\n\n# IV. Concatenación\nmy_string = my_string + \" :)\"\nprint(\"Concatenación:\", my_string)\n\n# V. Repetición\nprint(\"Repetición:\", my_string * 2)\n\n# VI. Recorridio\nprint(\"Recorrido (for each): \", end='')\nfor letter in my_string:\n  print(letter, end='')\nprint()\n\n\nprint(\"Recorrido (while): \", end='')\ncounter = 0\nwhile counter != len(my_string):\n  print(my_string[counter], end='')\n  counter = counter + 1\nprint()\n\n# VII. Mayusculas\nprint(\"Conversión a mayusculas:\", my_string.upper())\n\n# VIII. Minisculas\nprint(\"Conversión a minusculas:\", my_string.lower())\n\n# IX. Reemplazo\nmy_string = my_string.replace(\"un String\", \"una Cadena\")\nprint(\"Reemplazo:\", my_string)\n\n# X. División\nmy_split_string = my_string.split()\nprint(\"División:\", my_split_string)\n\n# XI. Union\nmy_join_string = \" \".join(my_split_string)\nprint(\"Union:\", my_join_string)\n\n# XII. Interpolación\nprint(f\"Interpolación: {my_string}\")\n\n# XIII. Verificación\nprint(\"Verificación:\")\nprint(\"String\" in my_string)\nprint(my_string.isdigit())\nprint(my_string.islower())\nprint(my_string.startswith(\"Soy\"))\nprint(not my_string.isalpha())\n\n\n# --------- Extra\nimport re\n\n\ndef only_letters(string):\n  return re.sub(r\"[^a-z]\", '', string.lower())\n\n\ndef is_palindrome(string):\n  return only_letters(string) == string[::-1]\n\n\ndef is_anagram(string_1, string_2):\n  return sorted(only_letters(string_1)) == sorted(only_letters(string_2))\n\n\ndef is_isogram(string):\n  stack: dict = {}\n\n  for letter in only_letters(string):\n        if letter in stack:\n            stack[letter] += 1\n\n        else:\n            stack[letter] = 1\n\n  return len(set(stack.values())) == 1\n\n\nprint(is_palindrome(\"radar\"))\nprint(is_palindrome(\"coco\"))\n\nprint(is_anagram(\"cola\", \"loca\"))\nprint(is_anagram(\"nona\", \"nono\"))\n\nprint(is_isogram(\"carbon\"))\nprint(is_isogram(\"carbonara\"))\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/yenneralayon142.py",
    "content": "\"\"\"\nOperaciones\n\"\"\"\nc1 = \"Yenner\"\nc2 = \"Alayon\"\n#Concatenacion\nprint(c1 + \" \" +  c2)\n#Repetición\nprint(c1 * 3)\n#Indexación\nprint(c1[0] + c1[1])\n#Longitud\nprint(len(c1))\n#Slicing\nprint(c1[2:4])\n#Busqueda\nprint(\"a\" in c1)\nprint(\"b\"in c2)\n#Reemplazo\nprint(c1.replace(\"Y\" , \"J\"))\n#Division\nprint(c1.split(\"Y\"))\n#Busqueda al principio y al final\nprint(c1.startswith(\"Ye\"))\nprint(c1.startswith(\"Je\"))\nprint(c1.endswith(\"er\"))\n#Busqueda de Ocurrencias\nprint(c1.lower().count(\"y\"))\n#Formateo\nprint(\"Saludo:{} lenguaje:{}!\".format(c1,c2))\n#Interpolación\nprint(f\"Saludo {c1} , lenguaje{c2}\")\n#Transformar una cadena a lista\nprint(list(c1))\n#Transformar una lsta a cadena\nl1 = [c1,\", \",c2,\"!\"]\nprint(\"\".join(l1))\n#Transformaciones númericas\ns1 = \"12345\"\ns1 = int(s1)\nprint(type(s1))\n#Comprobaciones Varias\nprint(c1.isalnum())\nprint(c1.isalpha())\n\"\"\"\nEXTRA\n\"\"\"\ndef comprobaciones(word1:str, word2:str):\n    #Palindromos\n    print(f\"¿{word1} es un palindromo?: {word1 == word1[::-1]}\")\n    print(f\"¿{word2} es un palíndromo?: {word2 == word2[::-1]}\")\n    #Anagramas \n    print(f\"¿{word1} es Anagrama de {word2}?: {sorted(word1) == sorted(word2)}\")\n    #Isogramas\n    def isogram(word:str ) -> bool:\n        word_dict = dict()\n        for character in word:\n            word_dict[character] = word_dict.get(character,0) + 1\n        isogram = True\n        values = list(word_dict.values())\n        isogram_len = values[0]\n        for word_count in values:\n            if word_count != isogram_len:\n                isogram = False\n                break\n        return isogram\n    print(f\"¿{word1} es un isograma?: {isogram(word1)}\")\n    print(f\"¿{word2} es un isograma?:{isogram(word2)}\")\ncomprobaciones(\"radar\",\"pythonpythonpythonnnnn\")\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/yharyarias.py",
    "content": "\"\"\"\n* EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\n *   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\n *   interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n\"\"\"\n\n# Acceso a carácteres específicos\n\ncadena = 'Reto cuatro'\nprint(cadena[0])\nprint(cadena[-1])\n\n# Subacadenas\n\nprint(cadena[2:6])\nprint(cadena[:4])\nprint(cadena[5:])\n\n# Longitud\n\nprint(len(cadena))\n\n# Concatenación\n\ncadena2 = ' de programación'\nconcatenar = cadena + cadena2\nprint(concatenar)\n\nprint(f'* {cadena}')\n\n# Repetición\npalabra_repetir = cadena * 2\nprint(palabra_repetir)\n\n# Recorrido\n\nfor caracrer in cadena:\n    print(caracrer)\n\n# Conversión a mayúsculas y minúsculas\n\nprint(concatenar.upper())\nprint(concatenar.lower())\n\n# Reemplazar\n\nnueva_cadena = cadena.replace('Hola', 'Hi')\n\n# División\n\nsub_cadena = cadena.split(' ')\nprint(sub_cadena)\n\n# Unión\n\nsub_cadena = ['Hola', 'Hi']\ncadena_nueva = ' '.join(sub_cadena)\nprint(cadena_nueva)\n\n# Interpolación\n\nnombre = 'Yhary'\nedad = 28\nprint(f'Mi nombre es {nombre} y tengo {edad}')\n\n# Verificación\n\nprint('cuatro' in cadena)\n\n# DIFICULTAD EXTRA (opcional):\n\n\ndef palindromos(palabra: str) -> bool:\n    '''\n        Palabra o frase que son iguales leidas de izquierda a \n        derecha que de derecha a izquierda.\n    '''\n    return palabra == palabra[::-1]\n\n\ndef anagrama(palabra1: str, palabra2) -> bool:\n    '''\n        Cambio en el orden de las letras de una palabra o frase \n        que da lugar a otra palabra o frase distinta.\n    '''\n    return sorted(palabra1) == sorted(palabra2)\n\ndef isograma(palabra: str) -> bool:\n    '''\n        Es una palabra o frase en la que cada letra aparece el \n        mismo número de veces\n    '''\n    return len(palabra) == len(set(palabra))\n\ndef main():\n    palabra1 = input('Ingresa la primera palabra\\n')\n    palabra2 = input('Ingresa la segunda palabra\\n')\n\n    palabra1 = palabra1.lower().replace(\" \", \"\")\n    palabra2 = palabra2.lower().replace(\" \", \"\")\n\n    if palindromos(palabra1):\n        print(f'La palabra \"{palabra1}\" es palíndromo')\n    else:\n        print(f'La palabra \"{palabra1}\" no es palíndromo')\n    \n    if palindromos(palabra2):\n        print(f'La palabra \"{palabra2}\" es palíndromo')\n    else:\n        print(f'La palabra \"{palabra2}\" no es palíndromo')\n    \n    if anagrama(palabra1, palabra2):\n        print(f'Las palabra \"{palabra1}\" y \"{palabra2}\" crean un anagrama')\n    else:\n        print(f'Las palabra \"{palabra1}\" y \"{palabra2}\" no crean un anagrama')\n    \n    if isograma(palabra1):\n        print(f'Las palabra \"{palabra1}\" es un isograma')\n    else:\n        print(f'Las palabra \"{palabra1}\" no es un isograma')\n\n    if isograma(palabra2):\n        print(f'Las palabra \"{palabra2}\" es un isograma')\n    else:\n        print(f'Las palabra \"{palabra2}\" no es un isograma')\n    \n\n\nif __name__ == '__main__':\n    main()\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/yoezequiel.py",
    "content": "cadena = \"Hola Mundo\"\nprint(\"Acceso a caracteres específicos:\")\nprint(\"Primer caracter:\", cadena[0])\nprint(\"Último caracter:\", cadena[-1])\n\nprint(\"\\nSubcadenas:\")\nprint(\"Subcadena desde el segundo caracter hasta el final:\", cadena[1:])\nprint(\"Subcadena desde el segundo al quinto caracter:\", cadena[1:6])\n\nprint(\"\\nLongitud de la cadena:\", len(cadena))\n\ncadena2 = \" de Python\"\nconcatenada = cadena + cadena2\nprint(\"\\nConcatenación:\", concatenada)\n\nprint(\"\\nRepetición:\")\nrepetida = cadena * 3\nprint(repetida)\n\nprint(\"\\nRecorrido:\")\nfor letra in cadena:\n    print(letra)\n\nprint(\"\\nConversión a mayúsculas y minúsculas:\")\nprint(\"Mayúsculas:\", cadena.upper())\nprint(\"Minúsculas:\", cadena.lower())\n\nprint(\"\\nReemplazo:\")\nnueva_cadena = cadena.replace(\"Mundo\", \"Python\")\nprint(nueva_cadena)\n\nprint(\"\\nDivisión:\")\ndividida = cadena.split(\" \")\nprint(dividida)\n\nprint(\"\\nUnión:\")\nunida = \"-\".join(dividida)\nprint(unida)\n\nprint(\"\\nInterpolación:\")\nnombre = \"Alice\"\nedad = 30\nprint(f\"Mi nombre es {nombre} y tengo {edad} años.\")\n\nprint(\"\\nVerificación:\")\nprint(\"¿La cadena contiene solo letras?\", cadena.isalpha())\nprint(\"¿La cadena contiene solo números?\", cadena.isdigit())\nprint(\"¿La cadena contiene solo letras o números?\", cadena.isalnum())\nprint(\"¿La cadena está en minúsculas?\", cadena.islower())\nprint(\"¿La cadena está en mayúsculas?\", cadena.isupper())\nprint(\"¿La cadena comienza con 'H'?\", cadena.startswith(\"H\"))\nprint(\"¿La cadena termina con 'o'?\", cadena.endswith(\"o\"))\n\n\n# EXTRA\ndef es_palindromo(palabra):\n    return palabra == palabra[::-1]\n\n\ndef es_anagrama(palabra1, palabra2):\n    return sorted(palabra1.lower()) == sorted(palabra2.lower())\n\n\ndef es_isograma(palabra):\n    return len(set(palabra.lower())) == len(palabra)\n\n\ndef analizar_palabras(palabra1, palabra2):\n    if es_palindromo(palabra1):\n        print(f\"{palabra1} es un palíndromo.\")\n    else:\n        print(f\"{palabra1} no es un palíndromo.\")\n\n    if es_palindromo(palabra2):\n        print(f\"{palabra2} es un palíndromo.\")\n    else:\n        print(f\"{palabra2} no es un palíndromo.\")\n\n    if es_anagrama(palabra1, palabra2):\n        print(f\"{palabra1} y {palabra2} son anagramas.\")\n    else:\n        print(f\"{palabra1} y {palabra2} no son anagramas.\")\n\n    if es_isograma(palabra1):\n        print(f\"{palabra1} es un isograma.\")\n    else:\n        print(f\"{palabra1} no es un isograma.\")\n\n    if es_isograma(palabra2):\n        print(f\"{palabra2} es un isograma.\")\n    else:\n        print(f\"{palabra2} no es un isograma.\")\n\n\npalabra1 = \"oso\"\npalabra2 = \"soso\"\nanalizar_palabras(palabra1, palabra2)\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/python/zetared92.py",
    "content": "# CADENAS DE CARACTERES\n\nstr1 = \"Euler\"\nstr2 = \"Number\"\n\n# Concatenación\nprint(str1 + \"'s\" + \" \" + str2)\n\n# Longitud\nprint(len(str1))\n\n# Indexación\nprint(str1[0] + str1[1] + str2[2] + str2[3])\n\n# Búsqueda\nprint(\"l\" in str1)\nprint(\"b\" in str1)\n\n# División\nprint(str1.split(\"e\"))\n\n# Slicing\nprint(str1[1:5])\nprint(str1[1:])\nprint(str1[0:4])\nprint(str1[:4])\n\n# Repetición\nprint(str1 * 4)\n\n# Reemplazo\nprint(str1.replace(\"E\", \"O\"))\n\n# Mayúsculas\nprint(str1.upper())\n# Minúsculas\nprint(str1.lower())\n# Letras Mayúsculas\nprint(\"euler's number\".title())\nprint(\"euler's number\".capitalize())\n\n# Eliminación de espacios iniciales y finales\nprint(\" euler's number \".strip())\n\n# Búsqueda al inicio y al final\nprint(str1.startswith(\"Eu\"))\nprint(str1.startswith(\"Num\"))\nprint(str1.endswith(\"ler\"))\nprint(str1.endswith(\"ber\"))\n\nstr3 = \"Euler's number is a constant\"\n\n# Búsqueda de posición\nprint(str3.find(\"constant\"))\nprint(str3.find(\"Euler\"))\nprint(str3.find(\"n\"))\nprint(str3.lower().find(\"n\"))\n\n# Búsqueda de ocurrencias\nprint(str3.lower().count(\"n\"))\n\n# Formateo\nprint(\"Mathematical: {}, type: {}\".format(str1, str2))\n\n# Interpolación\nprint(f\"Mathematical: {str1}, type: {str2}\")\n\n# Transformación de una lista en una cadena\nlist1 = [str1, \"'s\", str2]\nprint(\"\".join(list1))\n\n# Transformaciones numéricas\nstr4 = \"271828\"\nstr4 = int(str4)\nprint(str4)\n\nstr5 = \"2.71828\"\nstr5 = float(str5)\nprint(str5)\n\n# Comprobaciones\nstr5 = \"2,71828\"\nprint(str1.isalnum())\nprint(str1.isalpha())\nprint(str5.isalpha())\nprint(str5.isnumeric())\n\n\n\n# Extra\n\nprint(\"🧩 DIFICULTAD EXTRA 🧩\")\n\ndef check(w1: str, w2: str):\n    # Palindromes\n    print(f\"Is {w1} a palindrome?: {w1 == w1[::-1]}\")\n    print(f\"Is {w2} a palindrome?: {w2 == w2[::-1]}\")\n\n    # Anagrams\n    print(f\"Is {w1} an anagram of {w2}?: {sorted(w1) == sorted(w2)}\")\n\n    # Isograms\n    def isogram(word: str) -> bool:\n        word_dict = dict()\n        for char in word:\n            word_dict[char] = word_dict.get(char, 0) + 1\n        \n        isogram = True\n        values = list(word_dict.values())\n        isogram_len = values[0]\n        for word_count in values:\n            if word_count != isogram_len:\n                isogram = False\n                break\n        return isogram\n    \n    print(f\"Is {w1} an isogram?: {isogram(w1)}\")\n    print(f\"Is {w2} an isogram?: {isogram(w2)}\")\n\ncheck(\"radar\", \"bebe\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/r/Micromantic.R",
    "content": "#\n  # EJERCICIO:\n# Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n# en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n# - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n#   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n#\n\n## Operaciones con cadenas de caracteres\n\n# Concatenación\n\ncat(\"Hola,\", \"R\")\n\n# Repeticion\n\nstrrep(\"Hola, R.\", 3)\n\n# Longitud de una cadena de caracteres\n\nnchar(\"Murcielago\")\n\n# Subcadenas\n\nsubstr(\"Murcielago\", start = 4, stop = 8)\nsubstr(\"Murcielago\", 4, 7)\n\n# Cambio de mayúsculas/minúsculas\n\ntoupper(\"Murcielago\")\ntolower(\"MURCIELAGO\")\ntools::toTitleCase(\"murcielago\")\n\n# Eliminación de espacios al principio y al final\n\ntrimws(\" Murcielago en el ático.        \")\n\n# Reemplazo de patrones\n# gsub cambia el patrón en todas las ocasiones, mientras que sub solamente la primera vez\n\nsub(x = \"Murcielago en el lago\", pattern = \"la\", replacement = \"ga\")\n\ngsub(x = \"Murcielago en el lago\", pattern = \"la\", replacement = \"ga\")\n\n# Dividir cadenas\n\nstrsplit(x = c(\"1,2,3,4,5\"), split = \",\")\n\nstrsplit(x = c(\"Murcielago en el lago\"), split = \" \")\n\n# Buscar patrones\n\n# grep devuelve la posición donde se cumple el patrón de la regex\ngrep(\"[a-z]\", c(\"123\", \"b\"))\n\ngrep(\"[a-z]\", c(\"12d3\", \"b\"))\n\n# grepl devuelve si el patrón se cumple o no\n\ngrepl(\"[a-z]\", c(\"123\", \"b\"))\n\ngrepl(\"[a-z]\", c(\"12d3\", \"b\"))\n\n# Coincidencias de patrones\n\n# regexpr indica la posición del patrón en la primera aparición\nregexpr(c(\"Murcielago en el lago\"), pattern = \"el\")\n\n# gregexpr indica la posición del patrón en todas las repeticiones \ngregexpr(c(\"Murcielago en el lago\"), pattern = \"el\")\n\n# Formateo de texto\n\ns1 <- \"Hola\"\ns2 <- \"R\"\n\nsprintf(\"Saludo: %s, lenguaje: %s!\", s1, s2)\n\n\n\n# DIFICULTAD EXTRA (opcional):\n# Crea un programa que analice dos palabras diferentes y realice comprobaciones\n# para descubrir si son:\n# - Palíndromos\n# - Anagramas\n# - Isogramas\n#\n\nanalizar_palabras <- function(x, y) {\n  \n  x_lower <- tolower(x)\n  y_lower <- tolower(y)\n  \n  x_letras <- unlist(strsplit(x_lower, split = \"\"))\n  y_letras <- unlist(strsplit(y_lower, split = \"\"))\n  \n  x_inversa <- rev(x_letras)\n  y_inversa <- rev(y_letras)\n  \n  x_sorted <- sort(x_letras)\n  y_sorted <- sort(y_letras)\n  \n  x_unique <- unique(x_sorted)\n  y_unique <- unique(y_sorted)\n  \n  verificar_palindromo <- function(palabra, letras, letras_inv) {\n    \n    if (all(letras == letras_inv)) {\n    cat(\"La palabra\", palabra, \"es un palíndromo.\\n\")\n    } else cat(\"La palabra\", palabra, \"no es un palíndromo.\\n\")\n  }\n  \n  verificar_palindromo(x, x_letras, x_inversa)\n  verificar_palindromo(y, y_letras, y_inversa)\n  \n  if (length(x_sorted) == length(y_sorted) && all(x_sorted == y_sorted)) {\n    cat(\"Las palabras\", x, \"y\", y, \"son anagramas.\\n\")\n    } else cat(\"Las palabras\", x, \"y\", y, \"no son anagramas.\\n\")\n  \n  verificar_isograma <- function(palabra, letras_ord, letras_uniq) {\n    \n    if (length(letras_ord) == length(letras_uniq)) {\n      cat(\"La palabra\", palabra, \"es un isograma.\\n\")\n      } else if (sum(table(letras_ord)) / length(table(letras_ord)) == table(letras_ord)[[1]]) {\n        cat(\"La palabra\", palabra, \"es un isograma.\\n\")\n        } else cat(\"La palabra\", palabra, \"no es un isograma.\\n\")\n  }\n  \n  verificar_isograma(x, x_sorted, x_unique)\n  verificar_isograma(y, y_sorted, y_unique)\n}\n\nanalizar_palabras(\"Roma\", \"Amor\")\nanalizar_palabras(\"arepera\", \"salas\")\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/ruby/kodenook.rb",
    "content": "\ntxt = 'hello, ruby!'\n\nputs txt.size\nputs txt.reverse\nputs txt.upcase\nputs txt.downcase\nputs txt.capitalize\nputs txt.strip\nputs txt.split\nputs txt.gsub('h', 'j')\nputs txt.chars\n\n##\n# The function checks if a word is a palindrome, an anagram of another word, or an isogram.\n#\n# Args:\n#   word: The parameter \"word\" is a string that represents a word.\n#   word2: The parameter \"word2\" is used to compare with the first word to check if they are anagrams.\ndef word_type(word, word2) :nil\n    if word == word.reverse\n        puts 'is palindrome'\n    end\n\n    if word.split('').sort == word2.split('').sort\n        puts 'is an anagram'\n    end\n\n    if word.size == word.split('').uniq.size\n        puts 'is isogram'\n    end\nend\n\nword_type('amor', 'roma')"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/rust/brockar.rs",
    "content": "use std::collections::HashMap;\nuse std::io;\n\n/*\n Ejercicio 04 - CADENAS DE CARACTERES\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\n *   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\n *   interpolación, verificación...\n*/\nfn main() {\n    let mut s = String::new();\n\n    // Concat\n    s.push_str(\"Hello \");\n    s.push_str(\"Rust!\");\n    println!(\"s: {}\", s);\n\n    // Length\n    println!(\"Longitud: {}\", s.len());\n\n    // Contains\n    let c = s.contains('R');\n    println!(\"s contiene R?: {}\", c);\n\n    // Position\n    println!(\"Posicion de e: {:?}\", s.find('e'));\n\n    // Replace\n    let s2 = s.replace(\"Rust\", \"Rust 2023\");\n    println!(\"s2: {}\", s2);\n\n    // Iterate\n    println!(\"s2 iteration: \");\n    for c in s2.chars() {\n        print!(\"{}\", c);\n    }\n    println!();\n\n    // To uppercase\n    println!(\"s2 uppercase: {}\", s2.to_uppercase());\n\n    // To lowercase\n    println!(\"s2 lowercase: {}\", s2.to_lowercase());\n\n    // Slice\n    let s3 = &s2[0..5];\n    println!(\"s3 = s2[0..5]: {}\", s3);\n\n    // Splite (Vector, not a String)\n    println!(\"s2: {}\", s2);\n    let s4: Vec<_> = s2.split(' ').collect();\n    println!(\"s4 : {:?}\", s4);\n\n    // Join\n    println!(\"s4 join: {:?}\", s4.join(\"-\"));\n\n    // Trim (remove \" \")\n    let s5 = \"  Hello  \";\n    println!(\"s5 trim: {}.\", s5.trim());\n\n    // format\n    let formatted = format!(\"Mi nombre es {}! Estoy aprendiendo {}.\", \"Martin\", \"Rust\");\n    println!(\"{}\", formatted);\n\n    // Repetir\n    println!(\"s3 ({}) * 3: {}\", s3, s3.repeat(3));\n\n    /*\n     * DIFICULTAD EXTRA (opcional):\n     * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n     * para descubrir si son:\n     * - Palíndromos\n     * - Anagramas\n     * - Isogramas\n     */\n    println!(\"EXTRA EXTRA:\\n\");\n\n    println!(\"Ingrese la primer palabra:\");\n    let mut palabra1 = String::new();\n    match io::stdin().read_line(&mut palabra1) {\n        Ok(_) => {}\n        Err(error) => {\n            println!(\"Ha ocurrido un error: {}\", error)\n        }\n    };\n    println!(\"Ingrese la segunda palabra:\");\n    let mut palabra2 = String::new();\n    match io::stdin().read_line(&mut palabra2) {\n        Ok(_) => {}\n        Err(error) => {\n            println!(\"Ha ocurrido un error: {}\", error)\n        }\n    };\n    palabra1 = palabra1.trim().to_string();\n    palabra2 = palabra2.trim().to_string();\n    extra(palabra1, palabra2);\n}\n\nfn extra(palabra1: String, palabra2: String) {\n    if son_palindromos(palabra1.clone(), palabra2.clone()) {\n        println!(\"Las dos palabras son palindromos\");\n    } else {\n        println!(\"Las dos palabras no son palindromos\\n\")\n    }\n\n    if son_anagrama(palabra1.clone(), palabra2.clone()) {\n        println!(\"Las dos palabras son anagramas\");\n    } else {\n        println!(\"Las dos palabras no son anagramas\\n\")\n    }\n\n    if son_isograma(palabra1.clone(), palabra2.clone()) {\n        println!(\"Ambas palabras son isogramas\");\n    } else {\n        println!(\"Ambas palabras no son isogramas\")\n    }\n}\n\nfn son_palindromos(palabra1: String, palabra2: String) -> bool {\n    let mut a = false;\n    let mut b = false;\n    if es_palindromo(palabra1.clone()) {\n        println!(\"La palabra {} es palindromo\", palabra1);\n        a = true;\n    }\n\n    if es_palindromo(palabra2.clone()) {\n        println!(\"La palabra {} es palindromo\", palabra2);\n        b = true;\n    }\n\n    if a && b {\n        return true;\n    }\n    false\n}\n\nfn es_palindromo(palabra: String) -> bool {\n    let mut palabra_r: Vec<char> = palabra.chars().collect();\n    palabra_r.reverse();\n    let palabra_r: String = palabra_r.iter().collect();\n    if palabra == palabra_r {\n        return true;\n    }\n    false\n}\n\nfn son_anagrama(palabra1: String, palabra2: String) -> bool {\n    let mut palabra1_v: Vec<char> = palabra1.chars().collect();\n    let mut palabra2_v: Vec<char> = palabra2.chars().collect();\n    palabra1_v.sort();\n    palabra2_v.sort();\n    let palabra1_v: String = palabra1_v.iter().collect();\n    let palabra2_v: String = palabra2_v.iter().collect();\n    if palabra1_v == palabra2_v {\n        return true;\n    }\n    false\n}\n\nfn son_isograma(palabra1: String, palabra2: String) -> bool {\n    let mut a = false;\n    let mut b = false;\n    if es_isograma(palabra1.clone()) {\n        println!(\"La palabra {} es un isograma\", palabra1);\n        a = true;\n    }\n    if es_isograma(palabra2.clone()) {\n        println!(\"La palabra {} es un isograma\", palabra2);\n        b = true;\n    }\n\n    if a && b {\n        return true;\n    }\n    false\n}\n\nfn es_isograma(palabra: String) -> bool {\n    let palabra_v = palabra.chars();\n    let mut caracteres: HashMap<char, u8> = HashMap::new();\n    for c in palabra_v {\n        *caracteres.entry(c).or_insert(0) += 1;\n    }\n\n    let values_equal = caracteres\n        .values()\n        .all(|&v| v == *caracteres.values().next().unwrap());\n\n    values_equal\n}"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/rust/gabrielmoris.rs",
    "content": "/*\n * EXERCISE:\n * Show examples of all the operations you can perform with strings in your language.\n * Some of these operations might include (search for as many as you can):\n * - Accessing specific characters, substrings, length, concatenation, repetition,\n *   traversal, converting to uppercase and lowercase, replacement, splitting, joining,\n *   interpolation, verification...\n *\n */\n\nfn main() {\n    // The two most used string types in Rust are String and &str.\n    // A String is stored as a vector of bytes (Vec<u8>), but guaranteed to always be a valid UTF-8 sequence.\n    // String is heap allocated, growable and not null terminated.\n    // &str is a slice (&[u8]) that always points to a valid UTF-8 sequence,\n    // and can be used to view into a String, just like &[T] is a view into Vec<T>.\n\n    // CREATION\n    let mut reversed: String = String::new();\n    let str: &str = \"Hello\";\n    let mut str_to_reverse: String = String::new();\n\n    // ACCESS\n    let third_character = str.chars().nth(2);\n    assert_eq!(third_character, Some('l'));\n\n    // PUSH\n    str_to_reverse.push_str(\"World!!\");\n\n    // POP\n    str_to_reverse.pop();\n\n    // INSERT\n\n    str_to_reverse.insert_str(5, \"!!\");\n\n    // SPLIT\n    let chars: Vec<_> = str_to_reverse.split(\"\").collect();\n\n    // ITERATION\n    for word in chars.iter().rev() {\n        reversed.push_str(word);\n    }\n\n    // CONCATENATION\n\n    let weird = format!(\"{} {}\", str, reversed);\n    println!(\"Concatenated: {weird}\");\n\n    // SLICE\n    let sliced = &weird[0..5];\n    println!(\"Sliced: {sliced}\");\n\n    // REPLACING\n    let say = String::from(\"I like dogs\");\n    let replace = say.replace(\"dog\", \"cat\");\n    println!(\"He says: {}\", replace);\n\n    // TRIMMING\n    let string = String::from(\"   Hello, world!   \");\n    let chars_to_trim: &[char] = &[' ', ','];\n    let trimmed_str: &str = string.trim_matches(chars_to_trim);\n    println!(\"Trimmed: {}\", trimmed_str);\n    let string2 = String::from(\"         WHAT!!?      \");\n    let trimmed = string2.trim();\n    println!(\"Trimmed: {}\", trimmed);\n\n    // VIWEW INTO A STRING: The &str type allows you to view into a String without copying data\n    let pangram: &'static str = \"the quick brown fox jumps over the lazy dog\";\n    for word in pangram.split_whitespace() {\n        println!(\"Word: {}\", word);\n    }\n\n    challenge(\"a\".to_owned(), \"almendro\".to_owned());\n    challenge(\"manam\".to_owned(), \"maman\".to_owned());\n}\n\n/*\n * EXTRA CHALLENGE (optional):\n * Create a program that analyzes two different words and checks whether they are:\n * - Palindromes\n * - Anagrams\n * - Isograms\n */\n\nfn reverse_string(input: String) -> String {\n    let mut input1_reversed = String::new();\n    let chars: Vec<_> = input.split(\"\").collect();\n    for word in chars.iter().rev() {\n        input1_reversed.push_str(word);\n    }\n    return input1_reversed;\n}\n\nfn sort_string(input: String) -> String {\n    let sliced_str = &input[..];\n    let mut chars: Vec<char> = sliced_str.chars().collect();\n    chars.sort_by(|a, b| b.cmp(a));\n\n    return String::from_iter(chars);\n}\n\nfn is_isogram(s: &str) -> bool {\n    let mut sorted_chars: Vec<char> = s.chars().collect();\n    sorted_chars.sort_by(|a, b| a.to_ascii_lowercase().cmp(&b.to_ascii_lowercase()));\n\n    for i in 0..sorted_chars.len() - 1 {\n        if sorted_chars[i] == sorted_chars[i + 1] {\n            return false;\n        }\n    }\n\n    true\n}\n\nfn challenge(input1: String, input2: String) {\n    let cloned_input1 = input1.clone();\n    let cloned_input2 = input2.clone();\n    let reversed_input1 = reverse_string(input1);\n    let reversed_input2 = reverse_string(input2);\n\n    if reversed_input1 == cloned_input1 {\n        println!(\"{cloned_input1} is a Palindrome.\");\n    }\n    if reversed_input2 == cloned_input2 {\n        println!(\"{cloned_input2} is a Palindrome.\");\n    }\n\n    let recloned_input1 = cloned_input1.clone();\n    let recloned_input2 = cloned_input2.clone();\n    let sorted_str1 = sort_string(cloned_input1);\n    let sorted_str2 = sort_string(cloned_input2);\n\n    if sorted_str1 == sorted_str2 {\n        println!(\"{recloned_input1} and {recloned_input2} are Anagrams\");\n    }\n\n    let is_str1_isogram = is_isogram(&recloned_input1);\n    let is_str2_isogram = is_isogram(&recloned_input2);\n\n    if is_str1_isogram {\n        println!(\"{recloned_input1} is a Isogram\");\n    }\n    if is_str2_isogram {\n        println!(\"{recloned_input2} is a Isogram\")\n    }\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/rust/kenysdev.rs",
    "content": "// no advertencia\n#![allow(unused_variables)]\n#![allow(unused_assignments)]\n#![allow(unused_mut)]\nuse std::collections::HashSet;\nuse std::borrow::Cow;\n/*\n╔═══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado                ║\n║ GitHub: https://github.com/Kenysdev   ║\n║ 2024 -  Rust                          ║\n╚═══════════════════════════════════════╝\n-----------------------------------------\n* CADENAS DE CARACTERES\n-----------------------------------------\n- Hay dos tipos principales: String y &str.\n- son una colección de caracteres Unicode que pueden representar una\n  amplia gama de idiomas y símbolos.\n*/\nfn main() {\n    /*__________________________________\n     * (&str)\n     - Es una referencia a un segmento de memoria.\n     - Son inmutables por naturaleza.\n     - Representa una “sección” de una cadena de caracteres.\n     - Pueden ser asociados con el tiempo de vida de otras referencias.\n    */\n    let name: &str = \"Ken!\"; // Su contenido sera estatico.\n    \n    // Concatenación\n    let hello: &str = \"¡Hola, \";\n    let combined: String = hello.to_owned() + name; // o .to_string()\n    println!(\"{combined}\"); // ¡Hola, Ken!\n\n    // Extracción de subcadenas (slicing)\n    let sub: &str = &combined[0..6];\n    println!(\"slicing: {sub}\"); // ¡Hola\n\n    // longitud\n    println!(\"Longitud de 'name': '{}'\", name.len());\n\n    // Búsqueda de subcadenas\n    if hello.contains(\"Ho\") {\n        println!(\"Si contiene 'Ho'\");\n    }\n\n    // División en tokens\n    let combined: &str = &combined; // tomar referencia de (combined: String).\n    let tokens: Vec<&str> = combined.split(',').collect();\n    println!(\"{:?}\", tokens); // [\"¡Hola\", \"Ken!\"]\n\n    // Conversión a otros tipo\n    let num_str: &str = \"12\";\n    let num: i8 = num_str.parse().unwrap();\n    println!(\"Conversión a int: {num}\");\n\n    // Remoción de espacios en blanco\n    let padded: &str = \"   ¡Hola, mundo!   \";\n    let trimmed: &str = padded.trim();\n    println!(\"Remoción de espacios: '{trimmed}'\");\n\n    // Transformaciones de mayúsculas y minúsculas\n    let upper: String = trimmed.to_uppercase();\n    let lower: String = trimmed.to_lowercase();\n    println!(\"upper: {upper}\"); // ¡HOLA, MUNDO!\n    println!(\"lower: {lower}\"); // ¡hola, mundo! \n\n    // Iteración sobre caracteres\n    for c in hello.chars() {\n        println!(\"{c}\");\n    }\n\n    /*__________________________________\n     * (String)\n     - Cadena de caracteres de propiedad (owned).\n     - Son mutables por naturaleza.\n     - Alojados en la memoria dinámica (Heap).\n     - Están sujetas a las reglas de propiedad y vida útil de Rust.\n    */\n    let mut hi: String = String::from(\"¡Hola, \"); // mutable\n    let name: String = String::from(\"Ken!\");      // inmutable\n\n    // - Diferentes asignaciones\n    let mut hello: String = hi;    // La propiedad de 'hi' se mueve a 'hello'\n    // En este punto, 'hi' ya no es válido y no puede ser usado.\n\n    let my_name: &String = &name; // Se crea una referencia inmutable de 'name'\n    \n    // Crear una referencia mutable\n    let mut name2 = String::from(\"Ben\");\n    let mut my_name2: &mut String = &mut name2; \n    my_name2.push_str(\" y Zoe\");\n    println!(\"{name2}\"); // Veremos el cambio en la variable original.\n\n    // - Formas de concatenar\n    let mut result: String = String::new(); // declarar vacia\n    result = format!(\"{}{}\", hello, my_name);\n\n    result.push_str(&hello); // Agregar texto\n    result.push_str(&my_name);\n    result.push('!'); // Agregar un caracter\n\n    result = hello + &my_name; // hello ya no es utilizable.\n\n    // Transformaciones de mayúsculas y minúsculas\n    let upper: String = result.to_uppercase();\n    let lower: String = result.to_lowercase();\n    println!(\"upper: {upper}\"); // ¡HOLA, KEN!\n    println!(\"lower: {lower}\"); // ¡hola, ken! \n\n    // - Reemplazo de subcadenas:\n    result = result.replace(\"Ken\", \"Rust\");\n    println!(\"Reemplazo: {result}\"); // ¡hola, Rust!\n\n    // Búsqueda de subcadenas:\n    if let Some(index) = result.find(\"Rust\") {\n        println!(\"Indice: {index}\");\n    }\n    \n    // Eliminación de espacios en blanco:\n    let hi = String::from(\"   ¡Hola, mundo!   \");\n    let trimed = hi.trim();\n    println!(\"{trimed}\");\n\n    // Comprobación de vacío:\n    let s = String::from(\"\");\n    if s.is_empty() {\n        println!(\"La cadena está vacía\");\n    }\n\n    /*__________________________________\n     * Cow (Clone On Write)\n     - 'Cow<'a, B>' es una estructura de datos que representa una cadena de caracteres y se \n       utiliza para evitar copias innecesarias de datos al trabajar con cadenas. \n     - Puede contener tanto una referencia prestada (&T) como datos de propiedad propia (T).\n     - Si se necesita modificar los datos compartidos, se realiza una copia solo en ese momento. \n    */\n    \n    // Cuando se necesita una copia de la cadena, y esta se clona.\n    let owned: Cow<str> = Cow::Owned(String::from(\"Hola\"));\n    //  Cuando se quiere trabajar con una referencia prestada.\n    let borrowed: Cow<str> = Cow::Borrowed(\"Hello\");\n\n    // Ejemplo de uso\n    fn add_greeting(mut s: Cow<str>) -> Cow<str> {\n        match s {\n            // Verificamos si la cadena es propia (String) o prestada (&str)\n            Cow::Owned(ref mut owned_string) => {\n                // Si es propia, podemos modificarla directamente\n                owned_string.push_str(\", mundo!\");\n                return s\n            }\n            Cow::Borrowed(_) => {\n                // Si es prestada, necesitamos hacer una copia antes de modificarla\n                s.to_mut().push_str(\", mundo!\");\n                return s\n            }\n        }\n    }\n\n    // Ejemplo con una cadena propia (String)\n    let mut owned_string: Cow<str> = Cow::Owned(String::from(\"Hola\"));\n    let result_owned = add_greeting(owned_string.clone());\n    println!(\"Cadena modificada (own): {}\", result_owned);\n\n    // Ejemplo con una cadena prestada (&str)\n    let borrowed_string: Cow<str> = Cow::Borrowed(\"Hola\");\n    let result_borrowed  = add_greeting(borrowed_string.clone());\n    println!(\"Cadena modificada (borrowed): {}\", result_borrowed);\n\n    /*__________________________________\n     * EJERCICIO:\n     * Crea un programa que analice dos palabras diferentes y \n     * realice comprobaciones para descubrir si son:\n     * - Palíndromos\n     * - Anagramas\n     * - Isogramas\n    */\n    println!(\"EJERCICIO:\");\n    analyze(\"reconocer\", \"vida\");\n    analyze(\"notas\", \"santo\");\n    analyze(\"héroe\", \"radar\");\n}\n\nfn analyze(s1: &str, s2: &str) {\n    let s1_is_palindrome: bool = s1.chars().eq(s1.chars().rev());\n    let s2_is_palindrome: bool = s2.chars().eq(s2.chars().rev());\n\n    let mut s1_chars: Vec<char> = s1.chars().collect();\n    let mut s2_chars: Vec<char> = s2.chars().collect();\n    s1_chars.sort();\n    s2_chars.sort();   \n    let is_anagram: bool =  s1_chars == s2_chars;\n\n    let s1_set: HashSet<_> = s1.chars().collect();\n    let s2_set: HashSet<_> = s2.chars().collect();\n    let s1_is_isogram: bool = s1.len() == s1_set.len();\n    let s2_is_isogram: bool = s2.len() == s2_set.len();\n\n    println!(\"\n__________________________________________\n- {s1} es un palíndromo?: {s1_is_palindrome}\n- {s2} es un palíndromo?: {s2_is_palindrome}\n\n- {s1} es un anagrama de {s2}?: {is_anagram}\n\n- {s1} es un isograma?: {s1_is_isogram}\n- {s2} es un isograma?: {s2_is_isogram}\n__________________________________________\");\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/rust/raulfauli.rs",
    "content": "/// #04 CADENAS DE CARACTERES\n///\n/// Para compilar y ejecutar este código, ejecuta el siguiente comando desde el directorio principal:\n///\n/// `rustc ./Roadmap/04\\ -\\ CADENAS\\ DE\\ CARACTERES/rust/raulfauli.rs && ./raulfauli && rm raulfauli`\n///\nfn main() {\n  let mut string = String::from(\"Hola\");\n\n  // Concatenar\n  string.push_str(\" Rust\");\n  println!(\"{}\", string);\n\n  // Longitud\n  let length = string.len();\n  println!(\"Longitud: {}\", length);\n\n  // Contiene\n  let contains = string.contains(\"Rust\");\n  println!(\"Contiene 'Rust'? {}\", contains);\n\n  // Posición\n  let position = string.find(\"Rust\").unwrap();\n  println!(\"Posición de 'Rust': {}\", position);\n\n  // Reemplazar\n  let new_string = string.replace(\"Rust\", \"Mundo\");\n  println!(\"{}\", new_string);\n\n  // Iterar\n  for c in string.chars() {\n      println!(\"{}\", c);\n  }\n\n  let chars: Vec<char> = string.chars().collect();\n  println!(\"{}\", chars[1]);\n\n  // Convertir a mayúsculas\n  println!(\"Mayúsculas: {}\", string.to_uppercase());\n  println!(\"Minúsculas: {}\", string.to_lowercase());\n\n  // Subcadenas\n  let sub = &string[0..4];\n  println!(\"{}\", sub);\n\n  // Split\n  let split: Vec<&str> = string.split(\" \").collect();\n  println!(\"{:?}\", split);\n\n  // Join\n  let join = split.join(\"-\");\n  println!(\"{}\", join);\n\n  // Trim\n  let trimmed = \"   Hola   \".trim();\n  println!(\"{}\", trimmed);\n\n  // Convertir a número\n  let number = \"10\".parse::<i32>().unwrap();\n  println!(\"{}\", number);\n\n  // Formatear\n  let formatted = format!(\"Mi nombre es {}! Ingeniero desde hace {} años\", \"Raúl\", 12);\n  println!(\"{}\", formatted);\n\n  // Multiplicar\n  let multiplied = \"Hola\".repeat(3);\n  println!(\"{}\", multiplied);\n\n  // Vaciar\n  string.clear();\n  println!(\"Está vacía? {}\", string.is_empty());\n\n  // EXTRA\n  let palindrome = \"anitalavalatina\";\n  println!(\"Es palíndromo '{}'? {}\", palindrome, is_palindrome(palindrome));\n\n  let not_palindrome = \"Rust\";\n  println!(\"Es palíndromo '{}'? {}\", not_palindrome, is_palindrome(not_palindrome));\n\n  let anagram1 = \"roma\";\n  let anagram2 = \"amor\";\n  println!(\"Es anagrama '{}' y '{}'? {}\", anagram1, anagram2, is_anagram(anagram1, anagram2));\n\n  let not_anagram1 = \"rust\";\n  let not_anagram2 = \"dart\";\n  println!(\"Es anagrama '{}' y '{}'? {}\", not_anagram1, not_anagram2, is_anagram(not_anagram1, not_anagram2));\n\n  let isogram = \"murcielago\";\n  println!(\"Es isograma '{}'? {}\", isogram, is_isogram(isogram));\n\n  let not_isogram = \"murcielagoo\";\n  println!(\"Es isograma '{}'? {}\", not_isogram, is_isogram(not_isogram));\n}\n\nfn is_palindrome(word: &str) -> bool {\n  word.chars().eq(word.chars().rev())\n}\n\nfn is_anagram(word1: &str, word2: &str) -> bool {\n  let mut chars1: Vec<char> = word1.chars().collect();\n  chars1.sort_by(|a, b| b.cmp(a));\n\n  let mut chars2: Vec<char> = word2.chars().collect();\n  chars2.sort_by(|a, b| b.cmp(a));\n\n  chars1 == chars2\n}\n\nfn is_isogram(word: &str) -> bool {\n  let mut chars: Vec<char> = word.chars().collect();\n  chars.sort_by(|a, b| b.cmp(a));\n\n  let mut isogram = true;\n  for i in 0..chars.len() - 1 {\n      if chars[i] == chars[i + 1] {\n          isogram = false;\n          break;\n      }\n  }\n\n  isogram\n}\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/rust/troleomotor10.rs",
    "content": "use std::collections::HashSet;\n\n/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n*/\n\nfn checkwords(word1: String, word2: String) {\n    // Saber si una palabra es palindroma -> Palabras que se leen igual de izquierda a derecha que de derecha a izquierda\n    let invertedword1: String = word1.chars().rev().collect::<String>();\n    let invertedword2: String = word1.chars().rev().collect::<String>();\n    println!(\"La palabra {} es una palindroma? {}\", word1, word1 == invertedword1);\n    println!(\"La palabra {} es una palindroma? {}\", word2, word2 == invertedword2);\n\n    // Saber si una palabra en un anagrama -> Palabras que si cambiamos el orden de las letras, son palabras diferentes (Zara = Raza)\n    let mut string1: Vec<char> = word1.chars().collect();\n    let mut string2: Vec<char> = word2.chars().collect();\n    string1.sort();\n    string2.sort();\n    println!(\"Son anagramas? {:?}\", string1 == string2);\n\n    // Saber si es un isograma -> Palabras que tienen letras repetidas\n    let mut string1_set: HashSet<char> = HashSet::new();\n    for c in word1.chars() {\n        string1_set.insert(c);\n    }\n    let string1_fi: String = string1_set.into_iter().collect();\n\n    let mut string2_set: HashSet<char> = HashSet::new();\n    for c in word2.chars() {\n        string2_set.insert(c);\n    }\n    let string2_fi: String = string2_set.into_iter().collect();\n\n    println!(\"La palabra {} es un isograma? {}\",word1 ,string1_fi.len() < word1.len());\n    println!(\"La palabra {} es un isograma? {}\", word2, string2_fi.len() < word2.len());\n}\n\nfn main(){\n    let string1: String = String::from(\"hello\");\n    let string2: String = String::from(\"rust\");\n    let string3: String = String::from(\"  github    \");\n    let string4: String = String::from(\"Mouredev esta en directo en twitch\");\n    let palabras: Vec<&str> = vec![\"Juan\", \"se\", \"fue\", \"a\", \"comprar\", \"el\", \"pan\"];\n\n    // Formateo\n    let saludo = format!(\"{string1}, {string2}\");\n    println!(\"{saludo}\");\n\n    // Convertir String a int\n    let numero: String = String::from(\"34\");\n    println!(\"Pasamos una string un valor numerico: {:?}\", numero.parse::<i32>().unwrap());\n    \n    // Ver si una cadena esta vacía\n    println!(\"La cadena2 esta vacía? {}\", string2.is_empty());\n\n    // Obtener una referencia a los bytes que componen la cadena.\n    println!(\"La cadena 2 representada en caracteres ASCII es: {:?}\", string2.as_bytes());\n    \n    // Obtener posición\n    let string2_vector: Vec<char> = string2.chars().collect();\n    println!(\"La posición 2 de la cadena 2 es: {:?}\", string2_vector[2]);\n    \n    // Concatenación\n    let mut result: String = String::new();\n    result.push_str(&string1);\n    result.push_str(&string2);\n\n    println!(\"Si concatenamos la string1 y la string2 sale: {}\", result);\n\n    // Repetición\n    println!(\"String2 repetida 3 veces: {}\", &string2.repeat(3));\n\n    // Longitud\n    println!(\"La longitud de la string 1 es de {} caracteres\", string1.len());\n\n    // Busqueda\n    let incluye: bool = string2.contains(\"us\");\n    println!(\"La string 2 contiene 'us'? {incluye}\");\n\n    // Reemplazo\n    println!(\"En la string 1, si remplazamos las 'l' por 'a' quedaria asi: {}\", string1.replace(\"l\", \"a\"));\n\n    // Recorrido\n    for character in string2.chars() {\n        println!(\"{character}\")\n    }\n    \n    // División\n    let text: Vec<&str> = string4.split(\"en\").collect();\n    println!(\"La string 4 dividida por 'en' es: {:?}\", text);\n\n    // Mayúsculas y minúsculas\n    println!(\"String 2 toda en mayúsculas: {}\", string2.to_uppercase());\n    println!(\"String 2 toda en minúsculas: {}\", string2.to_lowercase());\n\n    // Eliminar espacio principio y final\n    println!(\"La string sin espacios es: {}\", string3.trim());\n\n    // Búsqueda al principio y al final\n    println!(\"La string 2 comienza por ru? {}\", string2.starts_with(\"ru\"));\n    println!(\"La string 2 comienza por he? {}\", string2.starts_with(\"he\"));\n    println!(\"La string 2 acabas por llo? {}\", string2.ends_with(\"llo\"));\n    println!(\"La string 2 acabas por st? {}\", string2.ends_with(\"st\"));\n\n    // Búsqueda de la primera posición\n    println!(\"La primera letra 't' esta en la posición: {:?}\", string4.find(\"t\"));\n\n    // Búsqueda de la ultima posición\n    println!(\"La ultima letra 't' se encuentra en la posición: {:?}\", string4.rfind(\"t\"));\n\n    // Búsqueda de ocurrencias\n    println!(\"La string 4 tiene: {} caracteres\", string4.chars().count());\n\n    // Unión de vector\n    println!(\"El vector unido mediante espacios es: {}\", palabras.join(\" \"));\n    \n    checkwords(String::from(\"radar\"), String::from(\"zara\"));\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/scala/edalmava.scala",
    "content": "private def countWithCount(string: String, char: Char): Int = string.count(_ == char)\n\n@main def hello(): Unit =\n  println(\"Interpolación de cadenas.  Uso de variables dentro de las cadenas\")\n  // Dadas estas dos variables inmutables\n  val nombre : String = \"Edwin\"\n  val apellido : String = \"Martinez\"\n  // Se pueden combinar en una cadena \n  println(s\"Nombre Completo: $nombre $apellido\")\n  /* Se precede la cadena con la letra s y se antepone el símbolo $ antes de cada nombre de variable\n     Dentro de la cadena. \n     Scala provee tres métodos de interpolación de cadenas s, f y raw\n     Estos métodos están explicados en https://docs.scala-lang.org/scala3/book/string-interpolation.html   \n  */\n  // Uso del interpolador f\n  val altura: Float = 1.7\n  println(f\"$nombre%s es de $altura%2.2f metros de altura\")\n  // Uso del interpolador raw\n  println(raw\"a\\nb\")\n  // Para embeber expresiones dentro de una cadena, se encierran entre llaves {}\n  println(s\"La suma de (2 + 2) es ${2 + 2}\")\n  println(\"\")\n\n  println(\"Cadenas Multilínea.  Son creadas incluyendo dentro de la cadena tres comillas dobles o comillas inglesas\")\n  val mensaje : String = \"\"\"Este es un mensaje de múltiples\n  líneas como ejemplo en Scala\"\"\"\n  println(mensaje)\n  // Cadenas multilinea con interpolación\n  val edad: Int = 40\n  println(s\"\"\"Nombre: \"$nombre\",\n             |Edad: $edad\"\"\".stripMargin)\n\n  /* En Scala las cadenas no son secuencias directas pero se pueden convertir en ellas, y también \n     admiten todas las operaciones de secuencias */\n  println(\"\")\n  println(\"Operaciones con cadena\")\n  val original = \"anita lava la tinA\"\n  println(s\"Cadena Original: $original\")\n  println(s\"Cadena Invertida: ${original.reverse}\")\n  println(s\"Longitud de la cadena: ${original.length()}\")\n  println(s\"Cadena en mayúscula: ${original.toUpperCase()}\")\n  println(s\"Cadena en minúscula: ${original.toLowerCase()}\")\n  println(s\"Cadena Capitalizada: ${original.capitalize}\")\n  val otraCadena = \"Todos los días\"\n  println(\"Concatenando cadenas\")\n  println(original + \" \" + otraCadena.toLowerCase())\n  println(original ++ \" \" ++ otraCadena.toLowerCase())\n  println(\"Repetición de Cadenas\")\n  println(\"Hola\"*(5))\n\n  /* Las cadenas tienen una longitud y sus elementos tienen índices \n     de posición fija que comienzan en 0*/\n  println(\"\")\n  println(s\"Cadena Original: $original\")\n  println(s\"Caracter en la posición 3: ${original.apply(3)}\")\n  println(s\"La cadena contiene el caracter 'x': ${if original.contains('x') then \"Verdadero\" else \"Falso\"}\")\n  println(s\"La cadena contiene el caracter 't': ${if original.contains('t') then \"Verdadero\" else \"Falso\"}\")\n  println(s\"La cadena tiene ${countWithCount(original.toLowerCase(),'a')} 'a' o 'A'\")\n  println(s\"Caracteres distintos usados en la cadena: ${original.distinct}\")\n  println(s\"Primer Caracter: ${original.head}\")\n  println(s\"Último Caracter: ${original.last}\")\n  println(s\"Rellenar la cadena con *: ${original.padTo(25, '*')}\")\n  println(s\"Obtener una parte de la cadena: ${original.slice(6, 10)}\")\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/scala/rianojnicolas.scala",
    "content": "object Source {\n    def main(args: Array[String]): Unit = {\n        // OPERACIONES CON CADENAS DE CARACTERES\n\n        // 1. Asignacion\n        val saludo = \"Hola, \"\n        val nombre = \"Mr X\"\n\n        // 2. Concatenacion\n        val final_saludo_1 = saludo + nombre\n        println(s\"${final_saludo_1}\\n\")\n        val final_saludo_2 = saludo.concat(nombre)\n        println(s\"${final_saludo_2}\\n\")\n\n        // 3. Operaciones \"Aritmeticas\"\n        val saludoTotal = saludo*3\n        println(s\"${saludoTotal}\\n\")\n\n        // 4. Subcadenas\n        val secuencia = \"123456789\"\n        val primerSub = secuencia.substring(0, 5)\n        val secondSub = secuencia.substring(3)\n        val thirdSub =  secuencia.substring(2,6)\n        println(s\"Primera subcadena $primerSub\") // Se toma 12345\n        println(s\"Segunda subcadena $secondSub\") // Se toma 456789\n        println(s\"Tercera subcadena $thirdSub \\n\") // Se toma 3456\n\n        // 5. Indexacion\n        val char1 = final_saludo_1(1)\n        val char2 = final_saludo_1(2)\n        val char3 = final_saludo_1(3)\n        println(s\"caracter de saludo 1 = $char1\")\n        println(s\"caracter de saludo 2 = $char2\")\n        println(s\"caracter de saludo 3 = $char3 \\n\")\n\n        // 6. Longitud\n        val lenghtStr = final_saludo_1.length()\n        println(s\"Longitud del saludo es $lenghtStr \\n\")\n\n        // 7. Recorrido\n        println(\"Recorrido de Str - Forma 1: Ciclo for\")\n        for (caracter <- final_saludo_1) {\n            println(s\"Recorriendo el String $final_saludo_1 -> $caracter\")\n        }\n        println(\"\\nRecorrido de Str - Forma 2: Metodo foreach\")\n        final_saludo_1.foreach {\n            caracter => println(s\"Caracter: $caracter\")\n        }\n\n        // 8. Mayusculas y Minusculas\n        val salMayus = final_saludo_1.toUpperCase()\n        val salMinus = salMayus.toLowerCase()\n        println(s\"\\nSaludo en Mayuscula -> $salMayus\")\n        println(s\"Saludo en Minuscula -> $salMinus \\n\")\n\n        // 9. Reemplazo\n        val newName = final_saludo_1.replace(\"X\", \"Z\")\n        println(s\"Nuevo saludo = $newName\")\n        val newName2 = final_saludo_1.replaceAll(\"Mr X\", \"Señor X\")\n        println(s\"Nuevo saludo = $newName2 \\n\")\n\n        // 10. Division o Separacion\n        println(s\"Frase Inicial -> $final_saludo_1\")\n        val divSal = final_saludo_1.split(\",\")\n        println(s\"Resultado de dividir -> ${divSal.toList} \\n\")\n        \n        // 11. Union\n        val myStringList = List(\"uno\", \"dos\", \"tres\", \"cuatro\")\n        println(s\"Lista de Strings -> $myStringList.toString()\")\n        val myString = myStringList.mkString(\", \")\n        println(s\"Strings unidos -> $myString \\n\")\n\n        // 12. Verificacion/Contiene \n        val word = \"scala\"\n        val subChar = \"al\"\n        println(s\"String Base -> ${word}\")\n        if (word.contains(subChar)) {\n            println(s\"la palabra '${word}' posee la cadena '${subChar}'\\n\")\n        }\n        else{\n            println(s\"la palabra '${word}' NO posee la cadena '${subChar}'\\n\")\n        }\n\n        // 13. Eliminar espacios en Blanco\n        val saludoNoTrim = \"     Hola, Mr X....         \"\n        println(s\"Sin trimeo -> '${saludoNoTrim}'\")\n        val saludoTrim = saludoNoTrim.trim\n        println(s\"Con trimeo -> '${saludoTrim}'\\n\")\n\n        // DIFICULTAD EXTRA\n        def palindromo(palabra: String): Boolean = {\n            var palabra_inver = palabra.trim.toLowerCase().reverse\n            val numeros = Seq(\"0\", \"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\")\n\n            try {\n                for (index <- numeros) {\n                    if (palabra.contains(index)) {\n                        throw new IllegalArgumentException(\"Por favor ingresa una palabra, por lo menos hay un número dentro de ella\")\n                    }\n                }\n                return palabra_inver == palabra\n            }\n            catch {\n                case e: IllegalArgumentException => println(s\"Error: ${e.getMessage}\")\n                return false\n            }\n        }\n\n        def anagrama(palabra1: String, palabra2: String): Boolean = {\n            val palabra1_clean = palabra1.trim.toLowerCase()\n            val palabra2_clean = palabra2.trim.toLowerCase()\n            // organizo en orden alfabetico los caracteres del String en otro String\n            val palabra1_sorted = palabra1_clean.toCharArray.sorted.mkString(\"\")\n            val palabra2_sorted = palabra2_clean.toCharArray.sorted.mkString(\"\")\n            return palabra1_sorted == palabra2_sorted\n        }\n\n        def isograma(palabra: String): Boolean = {\n            val palabra_clean = palabra.trim.toLowerCase()\n            // Crear un set vacio\n            var set_letters = Set[Char]()\n            for (letter <- palabra_clean) {\n                if (set_letters.contains(letter)) {\n                    println(s\"Se repite la letra ${letter}\")\n                    return false\n                }\n                else {\n                    set_letters + letter\n                }\n            }\n            return true\n        }\n\n        def run(): Unit = {\n            println(\"Ingresa la primer palabra: \")\n            val palabra1 = scala.io.StdIn.readLine()\n            \n            println(\"Ingresa la segunda palabra: \")\n            val palabra2 = scala.io.StdIn.readLine()\n\n            // Seccion Palindromo\n            val es_palindromo1 = palindromo(palabra1)\n            val es_palindromo2 = palindromo(palabra2)\n\n            if (es_palindromo1) {\n                println(s\"${palabra1}, es palindroma\")\n            }\n            else {\n                println(s\"${palabra1}, NO es palindroma\")\n            }\n    \n            if (es_palindromo2) {\n                println(s\"${palabra2}, es palindroma\")\n            }\n            else {\n                println(s\"${palabra2}, NO es palindroma\")\n            }\n\n            // Seccion Anagrama\n            val es_anagrama = anagrama(palabra1, palabra2)\n            if (es_anagrama) {\n                println(s\"${palabra1} y ${palabra2} son anagramas\")\n            }\n            else {\n                println(s\"${palabra1} y ${palabra2} NO son anagramas\")\n            }\n\n            // Seccion Isograma\n            val es_isograma1 = isograma(palabra1)\n            val es_isograma2 = isograma(palabra2)\n\n            if (es_isograma1) {\n                println(s\"${palabra1}, si es isograma\")\n            }\n            else {\n                println(s\"${palabra1}, NO es isograma\")\n            }\n            \n            if (es_isograma2) {\n                println(s\"${palabra2}, si es isograma\")\n            }\n            else{\n                println(s\"${palabra2}, NO es isograma\")\n            }\n        }\n        \n        run()\n    }\n}"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/sql/Nicojsuarez2.sql",
    "content": "# #04 CADENAS DE CARACTERES\n> #### Dificultad: Media | Publicación: 22/01/24 | Corrección: 29/01/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/sql/eulogioep.sql",
    "content": "-- Operaciones con cadenas en SQL\n\n-- Creamos una tabla temporal para nuestros ejemplos\nCREATE TEMPORARY TABLE IF NOT EXISTS ejemplos (\n    id INT AUTO_INCREMENT PRIMARY KEY,\n    texto VARCHAR(100)\n);\n\n-- Insertamos algunos datos de ejemplo\nINSERT INTO ejemplos (texto) VALUES \n('Hola, mundo!'),\n('TypeScript'),\n('amor'),\n('roma');\n\n-- 1. Longitud de la cadena\nSELECT texto, LENGTH(texto) AS longitud\nFROM ejemplos;\n\n-- 2. Conversión a mayúsculas y minúsculas\nSELECT texto, \n       UPPER(texto) AS mayusculas, \n       LOWER(texto) AS minusculas\nFROM ejemplos;\n\n-- 3. Subcadenas\nSELECT texto, \n       SUBSTRING(texto, 1, 4) AS subcadena\nFROM ejemplos;\n\n-- 4. Reemplazo\nSELECT texto, \n       REPLACE(texto, 'mundo', 'SQL') AS reemplazo\nFROM ejemplos\nWHERE texto LIKE '%mundo%';\n\n-- 5. Concatenación\nSELECT CONCAT(e1.texto, ' ', e2.texto) AS concatenacion\nFROM ejemplos e1, ejemplos e2\nWHERE e1.id = 1 AND e2.id = 2;\n\n-- 6. Recorte de espacios\nSELECT TRIM('  Hola Mundo  ') AS recorte_espacios;\n\n-- 7. Verificación\nSELECT texto,\n       texto LIKE 'Hola%' AS empieza_con_hola,\n       texto LIKE '%!' AS termina_con_exclamacion,\n       texto LIKE '%mundo%' AS contiene_mundo\nFROM ejemplos;\n\n-- DIFICULTAD EXTRA\n\n-- Función para verificar si una palabra es un palíndromo\nDELIMITER //\nCREATE FUNCTION esPalindromo(palabra VARCHAR(100)) \nRETURNS BOOLEAN\nDETERMINISTIC\nBEGIN\n    RETURN palabra = REVERSE(palabra);\nEND //\nDELIMITER ;\n\n-- Función para verificar si dos palabras son anagramas\nDELIMITER //\nCREATE FUNCTION sonAnagramas(palabra1 VARCHAR(100), palabra2 VARCHAR(100)) \nRETURNS BOOLEAN\nDETERMINISTIC\nBEGIN\n    RETURN LOWER(palabra1) REGEXP CONCAT('^[', LOWER(palabra2), ']+$')\n           AND LENGTH(palabra1) = LENGTH(palabra2);\nEND //\nDELIMITER ;\n\n-- Función para verificar si una palabra es un isograma\nDELIMITER //\nCREATE FUNCTION esIsograma(palabra VARCHAR(100)) \nRETURNS BOOLEAN\nDETERMINISTIC\nBEGIN\n    RETURN LENGTH(palabra) = LENGTH(DISTINCT palabra);\nEND //\nDELIMITER ;\n\n-- Probamos las funciones\nSELECT texto,\n       esPalindromo(texto) AS es_palindromo,\n       sonAnagramas(texto, 'roma') AS es_anagrama_de_roma,\n       esIsograma(texto) AS es_isograma\nFROM ejemplos\nWHERE texto IN ('amor', 'roma', 'TypeScript');"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/swift/18miguelgalarza.swift",
    "content": "\n/*\n * 18miguelgalarza.swift Release #04 - swift\n * EJERCICIO: #04 CADENAS DE CARACTERES\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\nimport Foundation\n\n//Concatenacion\n\nlet firstName = \"John\"\nlet lastName = \"Doe\"\nlet fullName = firstName + \" \" + lastName\nprint(fullName) // Salida: \"John Doe\"\n\n\n//Intepolación\n\nlet age = 36\nlet message = \"Tengo \\(age) años de edad.\"\nprint(message) // Salida: \"Tengo 30 años de edad.\"\n\n\n\n//Longitud\n\nlet cadena = \"Hello, playground!\"\nlet length = cadena.count\nprint(length) // Salida: 13\n\n\n//Acceso a caracteres individuales\n\nlet cadena1 = \"world\"\nlet firstChar = cadena1.first // Accede al primer carácter (opcional)\nlet lastChar = cadena1.last // Accede al último carácter (opcional)\nprint(firstChar as Any) // Salida: Optional(\"H\")\nprint(lastChar as Any) // Salida: Optional(\"o\")\n\n\n//Comparacion\n\nlet c1 = \"apple\"\nlet c2 = \"Apple\"\nif c1 == c2 {\n    print(\"Las cadenas son iguales.\")\n} else {\n    print(\"Las cadenas son diferentes.\")\n}\n\n\n//Conversion a minúscula y mayúscula\n\nlet conversion = \"Hello, World!\"\nlet uppercaseStr = conversion.uppercased()\nlet lowercaseStr = conversion.lowercased()\nprint(uppercaseStr) // Salida: \"HELLO, WORLD!\"\nprint(lowercaseStr) // Salida: \"hello, world!\"\n\n//Subcadenas\n\nlet sc = \"Hello, World!\"\nlet substring = sc.prefix(5) // Obtiene los primeros 5 caracteres\nprint(substring) // Salida: \"Hello\"\n\n\n//Bûsqueda de subcadenas\n\nlet bs = \"Hello, World!\"\nif bs.contains(\"World\") {\n    print(\"La subcadena 'World' está presente.\")\n} else {\n    print(\"La subcadena 'World' no está presente.\")\n}\n\n\n\n\n\n/*\n* DIFICULTAD EXTRA (opcional):\n* Crea un programa que analice dos palabras diferentes y realice comprobaciones\n* para descubrir si son:\n* - Palíndromos\n* - Anagramas\n* - Isogramas\n*/\n\n\n\nfunc validaDosPalabrasPalindromo(_ word01:String, _ word02:String) -> Bool{\n    return word01.lowercased().caseInsensitiveCompare(String(word02.lowercased().reversed())) == .orderedSame\n}\n\nfunc esPalindromo(_ word:String) -> Bool{\n    return word.lowercased().caseInsensitiveCompare(String(word.lowercased().reversed())) == .orderedSame\n}\n\nfunc sonAnagramas(_ palabra1: String, _ palabra2: String) -> Bool {\n    // Convertir las palabras a arrays de caracteres y ordenarlos alfabéticamente\n    let array1 = palabra1.lowercased().sorted()\n    let array2 = palabra2.lowercased().sorted()\n    \n    // Comparar los arrays resultantes\n    return array1 == array2\n}\n\n\nfunc esIsograma(_ palabra: String) -> Bool {\n    var letrasVistas = Set<Character>()\n    \n    for letra in palabra {\n        if letrasVistas.contains(letra) {\n            return false\n        }\n        letrasVistas.insert(letra)\n    }\n    \n    return true\n}\n\n\n/*\nprint(validaDosPalabrasPalindromo(\"amor\",\"roma\") ? \"Las palabras son palíndromos\" : \"No son Palíndromos\")\nprint(esPalindromo(\"ama\") ? \"La palabra es palíndromo\" : \"No no es Palíndromo\")\nprint(sonAnagramas(\"ama\",\"ama\") ? \"Las palabras son Anagramas\" : \"No son Anagramas\")\nprint(esIsograma(\"Marzo\") ? \"La palabra es Isograma\" : \"No no es Isograma\")\n*/\n\n//programa\n\nfunc analizadorDePalabras(_ p1:String, _ p2:String){\n    print(\"\\n\\n\")\n\n    print(validaDosPalabrasPalindromo(p1,p2) ? \"Las palabras son palíndromos\" : \"No son Palíndromos\")\n    print(esPalindromo(p1) ? \"La palabra \\(p1) es palíndromo\" : \"\\(p1) no es Palíndromo\")\n    print(esPalindromo(p2) ? \"La palabra \\(p2) es palíndromo\" : \"\\(p2) no es Palíndromo\")\n    print(sonAnagramas(p1,p2) ? \"Las palabras son Anagramas\" : \"No son Anagramas\")\n    print(esIsograma(p1) ? \"La palabra \\(p1)  es Isograma\" : \"\\(p1)  no es Isograma\")\n    print(esIsograma(p2) ? \"La palabra \\(p2)  es Isograma\" : \"\\(p2)  no es Isograma\")\n}\n\nanalizadorDePalabras(\"ana\", \"marzo\")\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/swift/PineroDev.swift",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\nimport Foundation\n\n// Creación de cadena de caracteres\nlet Saludo: String = \"Hola!\"\nprint(Saludo)\n\n// Concatenación de cadena de caracteres\nlet palabra1: String = \"Bienvenido\"\nlet palabra2: String = \" al curso de Swift!\"\nlet mensaje: String = palabra1 + palabra2\nprint(mensaje)\n\nvar mutableSaludo: String = \"Mundo!\"\nmutableSaludo.append(\" ¿Cómo estás?\")\nprint(mutableSaludo)\n\n//interopolación de cadena de caracteres\nlet nombre: String = \"Arturo\"\nlet edad: Int = 25\nlet saludoPersonalizado: String = \"Hola, mi nombre es \\(nombre) y tengo \\(edad) años.\"\nprint(saludoPersonalizado)\n\n// Longitud de cadena de caracteres\nlet texto: String = \"Soy una cadena de caracteres\"\nprint(texto.count)\n\n// Acceso a caracteres\nlet palabra3: String = \"Swift\"\nlet indice = palabra3.index(palabra3.startIndex, offsetBy: 1)\nprint (palabra3[indice])\n\n// Recorrer cadena de caracteres\nlet palabra4: String = \"Pirineos\"\nfor caracter in palabra4 {\n    print(caracter)\n}\n\n// Convertir a mayusculas o minusculas\nlet palabra5 : String = \"Mandarina\"\nprint(palabra5.uppercased())\nprint(palabra5.lowercased())\n\n// Buscar palabra en una cadena\nlet palabra6: String = \"El almendro florece al principio de la primavera\"\nprint(palabra6.contains(\"primavera\"))\n\n//Obtener el indice de una palabra\nif let rango = palabra6.range(of: \"primavera\") {\n    print(\"Encontrado en la posición \\(palabra6.distance(from: palabra6.startIndex, to: rango.lowerBound))\")\n}\n\n// Remplazar texto en cadena\nlet palabra7: String = \"Swift es un lenguaje de programación\"\nlet nuevaFrase: String = palabra7.replacingOccurrences(of: \"Swift\", with: \"Kotlin\")\nprint(nuevaFrase)\n\n//Extraer subcadenas de carateres\nlet palabra8: String = \"La Jirafa tiene un largo cuello\"\nlet inicio = palabra8.index(palabra8.startIndex, offsetBy: 25)\nlet subcadena = palabra8[inicio...]\nprint(subcadena)\n\n//Dividir una cadena de caracteres\nlet lista: String = \"camarón, langosta, langostino\"\nlet mariscos = lista.split(separator: \",\")\nprint (mariscos)\nprint(mariscos[1])\n\n//Convertir entre String y Int\nlet numeroYTexto: String = \"123\"\nif let numero: Int = Int(numeroYTexto) {\n    print(numero)\n}\n\n// Eliminar espacios en blanco\nlet textoConEspacios: String = \" Texto con espacios \"\nprint(textoConEspacios)\nprint(textoConEspacios.trimmingCharacters(in: .whitespaces))\n\n//Compararar cadena de caracteres\nlet a: String = \"Swift\"\nlet b: String = \"swift\"\nprint (a == b)\nprint(a.lowercased() == b.lowercased())\n \nfunc menu(){\n    \n    print(\" ------------------------------------------ \")\n    print(\"| Bienvenido al comparador de palabras!    |\")\n    print(\"|   Ingresa palabras para comprobar si     |\")\n    print(\"| son palíndromos,anagramas o isogramas:   |\")\n    print(\"|         Elige una opcion:                |\")\n    print(\"|          1 - Palindromos                 |\")\n    print(\"|          2 - Anagramas                   |\")\n    print(\"|          3 - Isogramas                   |\")\n    print(\"|          4 - Salir                       |\")\n    print(\" ------------------------------------------ \")\n    \n    if let opcionUsuario = readLine(){\n        switch opcionUsuario {\n        case \"1\":\n            palindromo()\n        case \"2\":\n            anagrama()\n        case \"3\":\n            isograma()\n        case \"4\":\n            print(\"Gracias por usar el programa!\")\n            break\n        default:\n            print(\"Opcion no valida\")\n            \n        }\n    }\n}\n\nfunc palindromo(){\n    print(\"Ingresa una palabra:\")\n    if let primeraPalabra = readLine(){\n        if primeraPalabra == String(primeraPalabra.reversed()) {\n            print(\"Es un palindromo\")\n            sleep(3)\n            menu()\n        } else {\n            print(\"No es un palindromo\")\n            sleep(3)\n            menu()\n        }\n    }\n}\n\nfunc anagrama(){\n    print(\"Ingresa la primera palabra\")\n    if let primeraPalabra = readLine(){\n        print(\"Ingresa la segunda palabra\")\n        if let segundaPalabra = readLine(){\n            let primeraConvert = primeraPalabra.lowercased()\n            let segundaConvert = segundaPalabra.lowercased()\n            if String(primeraConvert.reversed( )) == segundaConvert {\n                print( \"Son anagramas\" )\n                sleep(3)\n                menu()\n            }else {\n                print( \"No son anagramas\" )\n                sleep(3)\n                menu()\n            }\n        }\n    }\n    \n}\n\nfunc isograma(){\n    print(\"Ingresa una palabra\")\n    if let primeraPalabra = readLine(){\n        let caracteres = primeraPalabra.lowercased()\n        let SetCaracteres = Set(caracteres)\n        if SetCaracteres.count == caracteres.count {\n            print(\"Es un isograma\")\n            sleep(3)\n            menu()\n        } else {\n            print(\"No es un isograma\")\n            sleep(3)\n            menu()\n        }\n        \n    }\n}\n\nmenu()\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/swift/allbertoMD.swift",
    "content": "import Foundation\n\n\n\n// Cadena de caracteres\nprint(\"\\nCADENA DE CARACTERES\\n\")\n\nvar string: String = \"Hello, World\"\nprint(string)\n\n\n// Acceso a caracteres especificos\nprint(\"\\nACCESO A CARACTERES ESPECIFICOS\")\n\nprint(\"\\nAcceso al Primer Caracter Del String\")\n\n// Accedar al primer caracter del string\nlet firstCharacter = string[string.startIndex]\nprint(firstCharacter)\n\n// Acceder al primer caracter del string\nif let firstCharacter: Character = string.first {\n    print(firstCharacter)\n} else {\n    print(\"El string esta vacio\")\n}\n\nprint(\"\\nAcceso al Ultimo Caracter Del Sting\")\n\n// Acceder al ultimo caracter del string\nlet lastCharacter: Character = string[string.index(before: string.endIndex)]\nprint(lastCharacter)\n\n// Acceder al ultimo caracter del string\nif let lastCharacter: Character = string.last {\n    print(lastCharacter)\n} else {\n    print(\"El string esta vacio\")\n}\n\nprint(\"\\nAcceso al Caracter en la Posicioón 3 Del String\")\n\n// Acceder al caracter en la posición 3 del string\nlet thirdCharacter: Character = string[string.index(string.startIndex, offsetBy: 2)]\nprint(thirdCharacter)\n\nprint(\"\\nAcceso al Caracter en la Posición 2 Del String\")\n\n// Acceder al caracter en la posición 2 del string\nlet seconCharacter: Character = string[string.index(after: string.startIndex)]\nprint(seconCharacter)\n\nprint(\"\\nAcceso al Caracter en la Posición 5 Del String\")\n\n// Acceder al caracter en la posición 5 del string\nlet fifthIndex: String.Index = string.index(string.startIndex, offsetBy: 4)\nlet fifthCharacte: Character = string[fifthIndex]\nprint(fifthCharacte)\n\n\n\n// Recorrer\nprint(\"\\nRECORRER\")\n\nprint(\"\\nRecorrer Todos Los Caracteres Del String\")\n\n// Recorrer todol los caracteres del string\nfor character in string {\n    print(character)\n}\n\n\n\n// SubCadenas\nprint(\"\\nSUBCADENAS\")\n\nprint(\"\\nSubstring Con Los 3 Primeros Caraxteres Del String\")\n\n// Substring con los tres primeros caracteres del string\nlet firstThreeCharacters = string.prefix(3)\nprint(firstThreeCharacters)\n\nprint(\"\\nSubstring Con Los 5 Ultimos Caracteres Del String\")\n\n// Substring con los 5 ultimos caracteres del string\nlet lastFiveCharacters = string.suffix(4)\nprint(lastFiveCharacters)\n\nprint(\"\\nSubstring Desde el Primer Caracter al 4\")\n\n// Substring desde el primer caracter al 4\nlet prefixTo = string.prefix(upTo: string.index(string.startIndex, offsetBy: 4))\nprint(prefixTo)\n\nprint(\"\\nSubstring Desde el Caracter 4 Hasta el Final\")\n\n// Substring desde el caracter 4 hasta el final\nlet suffixFrom = string.suffix(from: string.index(string.startIndex, offsetBy: 4))\nprint(suffixFrom)\n\nprint(\"\\nSubstring Desde el Primer Caracter Hasta Que Aparecca la Letra \\\"r\")\n\n// Substring Desde el primer caracter hasta que aparacca la letra \"r\"\nlet prefixWhile = string.prefix(while: { $0 != \"r\" })\nprint(prefixWhile)\n\nprint(\"\\nSubstring Con Los Caracteres Del String Excluyendo Los 2 Primeros\")\n\n// Substring con los caracteres del string excluyendo los 2 primeros\nlet dropTwoFirstCharacters = string.dropFirst(2)\nprint(dropTwoFirstCharacters)\n\nprint(\"\\nSubstring Con Los Caracteres Del String Excluyendo Los 4 Ultimos\")\n\n// Substring con los caracteres del string expluyendo los 4 ultimos\nlet dropFourLastCharacter = string.dropLast(4)\nprint(dropFourLastCharacter)\n\nprint(\"\\nRango Para Obtener Substring Con Los 5 Primeros Caracteres\")\n\n// Rango para obtener substring con los 5 primeros caracteres\nlet startIndex = string.index(string.startIndex, offsetBy: 0)\nlet endIndex: String.Index = string.index(string.startIndex, offsetBy: 5)\nlet hello = string[startIndex..<endIndex]\nprint(hello)\n\nprint(\"\\nRango Para Obtener Substring Con Los Caracteres Del 7 al 12\")\n\n// Rango para obtener substring con los caracteres del 7 al 12\nlet indexRange = string.index(string.startIndex, offsetBy: 7)..<string.index(string.startIndex, offsetBy: 12)\nlet world = string[indexRange]\nprint(world)\n\nprint(\"\\nRango de Las Letras \\\"rld\\\" Del String\")\n\n// Rango de las letras \"rld\" del estring\nif let range = string.range(of: \"rld\") {\n    print(string[range])\n}\n\n\n\n// División\nprint(\"\\nDIVISIÓN\")\n\nprint(\"\\nDivision en un Array Separados Por el Delimitador \\\",\\\"\")\n\n// Division en un arrray separados por el delimitador \",\"\nlet splitByComa = string.split(separator: \",\")\nprint(splitByComa)\n\nprint(\"\\nDivision en un Array de un Maximo de 3 Elementos Omitiendo los Substrings Vacios y separados pr el delimitador \\\"o\\\"\")\n\n// Division en un array de un maximo de 3 subcastring, omitiendo los subcadenas vacias y separados por el delimitador \"0\"\nlet splitWhere = string.split(maxSplits: 3, omittingEmptySubsequences: true, whereSeparator: { $0 == \"o\"})\nprint(splitWhere)\n\nprint(\"\\nDivision en un Array Separados Por el Delimitador \\\", \\\"\")\n\n// Division en un array separados por el dilimitador \", \"\nlet componentsByComaAndSpace = string.components(separatedBy: \", \")\nprint(componentsByComaAndSpace)\n\n\n\n// Longitud\nprint(\"\\nLONGITUD\")\n\nprint(\"\\nLongitud Del String\")\n\n// Longitud del string\nlet countString = string.count\nprint(countString)\n\n\n\n// Concatenación\nprint(\"\\nCONCATENACIÓN\")\n\nprint(\"\\nConcatenación de \\\"!\\\" al String\")\n\n// Concatena \"!\" sl string \nstring += \"!\"\nprint(string)\n\nprint(\"\\nConcatenación de \\\"!!!\\\" al String\")\n\n// Concate \"!!!\" al string\nlet concatenation1 = string + \"!!\"\nprint(concatenation1)\n\nprint(\"\\nConcatenación de \\\"Hello, World\\\" al String\")\n\n// Concatena \"Hello, World\" al string\nlet concatenation2 = String(\"Hello\" + \",\" + \" \" + \"World!\")\nprint(concatenation2)\n\n\n\n// Interpolación\nprint(\"INTERPOLACIÓN\")\n\nprint(\"\\nInterpolación de \\\"I'm Swift\\\" al String\")\n\n// Interpola \"I'm Seift\" al string\nlet interpolation1 = \"\\(string) I'm Swift\"\nprint(interpolation1)\n\n\n\n// Union\nprint(\"\\nUNIÓN\")\n\nprint(\"\\nConcatenación de \\\"Are You Ready to Code?\\\" al String\")\n\n// Concatena \"Are you Ready to Code?\" al string\nlet concatenation3 = string.appending(\" Are You Readi to Code?\")\nprint(concatenation3)\n\n\n\n// Repetición\nprint(\"\\nREPETICIÓN\")\n\nprint(\"\\nRepetición de 10 Veces el Caracter \\\"a\\\" en un string\")\n\n// Repite el caracter \"a\" 10 veces en un string\nlet repeatingCharacters = String(repeating: \"a\", count: 10)\nprint(repeatingCharacters)\n\nprint(\"\\nRepetición de 10 Veces el String \\\"Swift\\\" en un String\")\n\n// Repite el string \"Swift\" 10 veces en un string\nlet repeatingString = String(repeating: \"Swift\", count: 10)\nprint(repeatingString)\n\n\n\n// Mayusculas\nprint(\"\\nMAYUSCULAS\")\n\nprint(\"\\nTransformar el String a Mayusculas\")\n\n// Transforma el string a mayusculas\nlet upperCasedSting = string.uppercased()\nprint(upperCasedSting)\n\nprint(\"\\nTransformas el String a Mayusculas Teniendo en Cuenta la Localizacion y Reglas linguisticas Del Dispositivo\")\n\n// Transforma a mayusculas teniendo en cuenta la localización, y las reglas linguisticas del dispositivo\nlet upperCasedByLocation: String = string.uppercased(with: Locale.current)\nprint(upperCasedByLocation)\n\nprint(\"\\nTranformar el String a Mayusculas Uno a Uno Con un Bucle\")\n\n// Transforma el string a mayusculas uno a uno con un bucle\nvar upperCasedLoop = \"\"\nfor character in string {\n    upperCasedLoop += String(character).uppercased()\n}\nprint(upperCasedLoop)\n\nprint(\"\\nTransformar Cade Caracter Del String a Mayusculas y metiendolos en un arry\")\n\n// Transforma el string a mayusculas y metie cada caracter en un array\nlet upperCasedMap = string.map( { String($0.uppercased()) } )\nprint(upperCasedMap)\n\n\n\n// Minusculas\nprint(\"\\nMINUSCULAS\")\n\nprint(\"\\nTransformar el String a Minusculas\")\n\n// Transforma el string a minusculas\nlet lowerCasedString = string.lowercased()\nprint(lowerCasedString)\n\nprint(\"\\nTransformas el String a Minusculas Teniendo en Cuenta la Localizacion y Reglas linguisticas Del Dispositivo\")\n\n// Transforma a minusculas teniendo en cuenta la localización, y las reglas linguisticas del dispositivo\nlet lowerCasedByLocation = string.lowercased(with: Locale.current)\nprint(lowerCasedByLocation)\n\nprint(\"\\nTransformar el String Uno a Uno Usando un Bucle\")\n\n// Transforma el string a minusculas uno a uno usando un bucle\nvar lowerCasedLoop = \"\"\nfor character in string {\n    lowerCasedLoop += String(character).lowercased()\n}\nprint(lowerCasedLoop)\n\nprint(\"\\nTransforma el String a Minusculas y Mete Cada Caracter en un Array\")\n\n// Transforma el string a minusculas y metie cada caracter en un array\nlet lowerCasedMap = string.map( { String($0.lowercased()) } )\nprint(lowerCasedMap)\n\n\n\n// Reemplazo\nprint(\"\\nREEMPLAZO\")\n\nprint(\"\\nReemplaza el caracter \\\"r\\\" por \\\"R\\\"\")\n\n// Reemplaza el caracter \"r\" por \"R\" \nlet remplacingOcurrencesString = string.replacingOccurrences(of: \"r\", with: \"R\")\nprint(remplacingOcurrencesString)\n\nprint(\"\\nReemplaza los Caracteres \\\"l\\\" Por \\\"L\\\"\")\n\n// Reemplaza los caracteres ¨l\" por \"L\"\nlet remplacingWhitMap = String(string.map({ $0 == \"l\" ? \"L\" : $0 }))\nprint(remplacingWhitMap)\n\n\n\n// Verificación\nprint(\"\\nVERIFICACIÓN\")\n\nprint(\"\\nVerificación si el String Contiene el Caracter \\\"W\\\"\")\n\n// Verifica si el string contiene el caracter \"W\"\nlet containsCharacter = string.contains(\"W\")\nprint(containsCharacter)\n\nprint(\"\\nVerificación si el String Contiene la Cadena \\\"Hello\\\"\")\n\n// Verifica si el string contiene la cadena \"Hello\"\nlet containsString = string.contains(\"Hello\")\nprint(containsString)\n\nprint(\"\\nVerificación si el String Contienen el Substring \\\"o,\\\"\")\n\n// Verifica si el string contiene el substring \"o,\"\nlet containsSubString = string.contains(\"o,\")\nprint(containsSubString)\n\nprint(\"\\nVerificación si el String Cumple con la Condición Del Parameter where\")\n\n// Verifica si el string cumple con la condición del parametro where\nlet containsWhere = string.contains(where: { $0 == \"r\" })\nprint(containsWhere)\n\n\n\n// Eliminar\nprint(\"\\nELIMINAR\")\n\nprint(\"\\nEliminar el Primer Caracter Del String\")\n\n// Elimina el primer caracter del string\nstring.removeFirst()\nprint(string)\n\nprint(\"\\nEliminar Los Dos Primeros Caracterres Del String\")\n\n// Elimina los 2 primeros caracteres del string\nstring.removeFirst(2)\nprint(string)\n\nprint(\"\\nEliminar el Ultimo Caracter Del String\")\n\n// Elimina el ultimo caracter del string\nstring.removeLast()\nprint(string)\n\nprint(\"\\nElimina Los Dos Ultimos Caracteres Del String\")\n\n// Elimina los dos ultimos caracteres del string\nstring.removeLast(2)\n\nprint(\"\\nElimina el Cuerto Elemento Del String\")\n\n// Elimina el cuarto elemento del string\nstring.remove(at: string.index(string.startIndex, offsetBy: 3))\nprint(string)\n\nprint(\"\\nEliminar el Rango de Caracteres Del Tercer Elemento al Quinto Del String\")\n\n// Elimina el rango de caracteres del tercer al quinto del string\nstring.removeSubrange(string.index(string.startIndex, offsetBy: 2)...string.index(string.startIndex, offsetBy: 4))\nprint(string)\n\nprint(\"\\nElimina Todos Los Caracteres Del String\")\n\n// Wlimina todos los caracteres del string\nstring.removeAll()\nprint(string)\n\n\n\n// Dificultad Extra\nprint(\"\\nDIFICULTAD EXTRA\")\n\nfunc isPalindromeAnagramOrIsogram(str1: String, str2: String) {\n    // palindromo\n    var wordOfStr1: String = \"\"\n    var wordReversedOfStr1: String = \"\"\n    var wordOfStr2 = \"\"\n    var wordReversedOfStr2: String = \"\"\n\n    wordOfStr1 = str1\n    wordOfStr2 = str2\n    \n    for c in str1.reversed() {\n        wordReversedOfStr1.append(c)\n    }\n\n    if wordOfStr1 == wordReversedOfStr1 {\n        print(\"\\(str1) es un palindromo\")\n    } else {\n        print(\"\\(str1) no es un palindromo\")\n    }\n\n    for c in str2.reversed() {\n        wordReversedOfStr2.append(c)\n    }\n\n    if wordOfStr2 == wordReversedOfStr2 {\n        print(\"\\(str2) es un palindromo\")\n    } else {\n        print(\"\\(str2) no es un palindromo\")\n    }\n\n\n    // Anagrama\n    let sortedArrayOfStr1 = str1.lowercased().sorted()\n    let sortedArrayOfStr2 = str2.lowercased().sorted()\n\n    if sortedArrayOfStr1 == sortedArrayOfStr2 {\n        print(\"\\(str1) y \\(str2) son anagrama\")\n    } else {\n        print(\"\\(str1) y \\(str2) no son anangramas\")\n    }\n\n\n    // Isograma\n    var repeatedCharacterOfStr1 = false\n    var characterArrayOfStr1 = [Character]()\n    var repeatedCharacterOfStr2 = false\n    var characterArrayOfStr2 = [Character]()\n\n    for character in wordOfStr1 {\n        if characterArrayOfStr1.contains(character) {\n            repeatedCharacterOfStr1 = true\n            break\n        } else {\n            characterArrayOfStr1.append(character)\n        }\n    }\n\n    if repeatedCharacterOfStr1 {\n        print(\"\\(str1) no es un isograma\")\n    } else {\n        print(\"\\(str1) es un isograma\")\n    }\n\n    for character in wordOfStr2 {\n        if characterArrayOfStr2.contains(character) {\n            repeatedCharacterOfStr2 = true\n            break\n        } else {\n            characterArrayOfStr2.append(character)\n        }\n    }\n\n    if repeatedCharacterOfStr2 {\n        print(\"\\(str2) no es un isograma\")\n    } else {\n        print(\"\\(str2) es un isograma\")\n    }\n    \n}\nisPalindromeAnagramOrIsogram(str1: \"amor\", str2: \"roma\")\n\n\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/swift/blackriper.swift",
    "content": "\nvar hokage=\"Naruto\"\n\nprint(hokage.contains(\"N\"))\n\nhokage.append(\" Uzumaki\")\nprint(hokage)\n\nlet upper=hokage.uppercased()\nprint(upper)\n\nlet lower=hokage.lowercased()\nprint(lower)\n\nlet rev=hokage.reversed()\nprint(String(rev))\n\nlet sp=hokage.split(separator: Character(\"-\"))\nprint(sp)\n\nlet count=hokage.count\nprint(count)\n\nhokage.remove(at: hokage.startIndex)\nprint(hokage)\n\nprint(hokage.hasPrefix(\"Naruto\"))\nprint(hokage.hasSuffix(\"Uzumaki\"))\n\nprint(hokage.isEmpty)\n\nprint(\"\\(hokage) is the seventh hokage!!\")\n\n\n// ejercicio extra \n\ntypealias Word=String\n\nfunc isAnagram(text1:Word,text2:Word)->Bool{\n    if text1.uppercased().sorted() == text2.uppercased().sorted(){\n       return true\n    }\n    return false \n}\n\nfunc isIsogram(_ word: Word) -> Bool {\n  let lowercasedWord = word.lowercased()\n  let characterSet = Set(lowercasedWord)\n\n  // Devolver verdadero si el número de caracteres en la palabra es igual al número de caracteres en el conjunto.\n  return characterSet.count == lowercasedWord.count\n}\n\n\nfunc analazingWord(text1:Word,text2:Word=\"\"){\n    \n    if String(text1.uppercased().reversed()) == text2.uppercased(){\n      print(\"\\(text1) and \\(text2) are palidrome\")\n\n    }else if isAnagram(text1: text1, text2: text2)==true{\n       print(\"\\(text1) and \\(text2) are anagrams\")\n    }else if isIsogram(text1){\n        print(\"\\(text1) are isograms\")\n    }\n\n}\n\nanalazingWord(text1: \"Anna\", text2: \"anna\")\nanalazingWord(text1: \"Nacionalista\", text2:\"Altisonancia\")\nanalazingWord(text1: \"Taco\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/swift/didacdev.swift",
    "content": "import Foundation\n\n// Concatenación\n\nvar hello = \"hello\"\nvar world = \" world\"\n\nprint(hello + world)\n\n// Iterar\nvar animals = \"🐶🐵🐻\"\n\nfor animal in animals {\n    print(animal)\n}\n\n// Construcción a partir de caracteres\nlet characters:[Character] = [\"h\", \"e\", \"l\", \"l\", \"o\"]\nlet string = String(characters)\nprint(string)\n\n// Interpolación\nlet name = \"Diego\"\nlet message = \"Su nombre es \\(name)\"\nprint(message)\n\n// Unicode\nlet character = \"\\u{1F425}\"\nprint(character)\n\n// Combinar caracteres\nlet combine = \"\\u{65}\\u{301}\" // é\nprint(combine)\n\n// Tamaño de la cadena\nlet word = \"esternocleidomastoideo\"\nprint(word.count)\n\n// Obtener un caracter\nlet saludo = \"hello world\"\n\nprint(saludo[saludo.startIndex]) // primero\nprint(saludo[saludo.index(before: saludo.endIndex)]) // último\nprint(saludo[saludo.index(after: saludo.startIndex)]) // segundo\nprint(saludo[saludo.index(saludo.startIndex, offsetBy: 6)]) // cualquier posición\n\nfor index in saludo.indices {\n    print(\"\\(saludo[index])\")\n}\n\n// Insertar\nhello.insert(contentsOf: \"\\(world)!\", at: hello.endIndex)\nprint(hello)\n\n// Eliminar\nhello.remove(at: hello.index(before: hello.endIndex))\nprint(hello)\n\n// Subcadenas\nlet index = hello.firstIndex(of: \" \") ?? hello.endIndex\nlet beggining = hello[..<index]\n\nhello = String(beggining)\n\nprint(hello)\n\n// Comparación\nlet sameHello = \"hello\"\n\nif hello == sameHello {\n    print(\"\\(hello) y \\(sameHello) Son iguales\")\n}\n\n// Repetición\nlet doubleHello = String(repeating: hello, count: 2)\nprint(doubleHello)\n\n// Conversión mayúsculas\nlet mayusHello = hello.uppercased()\n\nprint(mayusHello)\n\n// Conversión a minúsculas\nlet minusHello = mayusHello.lowercased()\nprint(minusHello)\n\n// Reemplazar caracter\nlet newHello = String(hello).replacingOccurrences(of: \"h\", with: \"H\")\nprint(newHello)\n\n// División\nlet sentence = \"hello world\"\nlet words = sentence.split(separator: \" \")\nprint(words)\n\n// Verificación\nif newHello.contains(\"H\") {\n    print(\"Contiene H\")\n}\n\n// -------------------- Ejercicio ------------------------\n\nfunc checkWords(word1: String, word2: String) {\n    if isPalindromo(word1: word1, word2: word2) {\n        print(\"\\(word1) y \\(word2) son palíndromos\")\n    } else {\n        print(\"\\(word1) y \\(word2) no son palíndromos\")\n    }\n    \n    if isAnagrama(word1: word1, word2: word2) {\n        print(\"\\(word1) y \\(word2) son anagramas\")\n    } else {\n        print(\"\\(word1) y \\(word2) no son anagramas\")\n    }\n\n    if isIsograma(word: word1) {\n        print(\"\\(word1) es un isograma\")\n    } else {\n        print(\"\\(word1) no es un isograma\")\n    }\n\n    if isIsograma(word: word2) {\n        print(\"\\(word2) es un isograma\")\n    } else {\n        print(\"\\(word2) no es un isograma\")\n    }\n}\n\nfunc isPalindromo(word1: String, word2: String) -> Bool{\n\n    let reversedWord2 = String(word2.reversed())\n    if word1.count == word2.count {\n\n        for i in 0..<word1.count {\n            let character1 = word1[word1.index(word1.startIndex, offsetBy: i)]\n            let character2 = reversedWord2[reversedWord2.index(reversedWord2.startIndex, offsetBy: i)]\n\n            if character1 != character2 {\n                return false\n            }\n        }\n\n        return true\n    } \n\n    return false\n}\n\nfunc isAnagrama(word1: String, word2: String) -> Bool {\n    var checkingWord = word2 \n\n    for character in word1 {\n        if checkingWord.contains(character) {\n            \n            if let index = checkingWord.firstIndex(of: character) {\n                checkingWord.remove(at: index)\n            }\n        } else {\n            return false\n        }\n    }\n\n    return true\n}\n\nfunc isIsograma(word: String) -> Bool{\n    var characters: [String: Int] = [:]\n\n    for character in word {\n        characters[String(character)] = characters[String(character)] != nil ? characters[String(character)]! + 1 : 1\n    }\n\n    var i = 0\n    for (key, value) in characters {\n        \n        if i == 0 {\n            i = value\n        } else {\n            if i != value {\n                return false\n            }\n        }\n    }\n\n    return true\n}\n\ncheckWords(word1: \"lacteo\", word2: \"coleta\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/swift/karys4.swift",
    "content": "import Foundation\n\n//Concatenating two strings\n var firstString = \"All we hear is radio ga ga\"\n var secondString = \"Radio goo goo\"\n var chorus = firstString + \" \" + secondString\n\n\n //String interpolation\n var radioSong = \"You had your time, you had the power, you've yet to have your finest hour Radio (radio) \\(chorus).\"\n\n\n //Counting characters\n var songCharacters = radioSong.count\n\n\n //Insert a character\n radioSong.insert(\"!\", at: radioSong.endIndex)\n\n//Insert a word\nradioSong.insert(contentsOf: \"hello\", at: radioSong.index(before: radioSong.endIndex))\n\n//Remove a single character (the last character)\nradioSong.remove(at: radioSong.index(before: radioSong.endIndex))\n\n//Remove a substring\nlet range = radioSong.index(radioSong.endIndex, offsetBy: -25)..<radioSong.endIndex\nradioSong.removeSubrange(range)\n\n//Substring\nvar bohemianSong = \"\"\"\nIs this the real life? Is this just fantasy?\nCaught in a landslide, no escape from reality\nOpen your eyes, look up to the skies and see\nI'm just a poor boy, I need no sympathy\n\"\"\"\n\n//append() method\nbohemianSong.append(radioSong)\n\n//elementsEqual() method\nvar compare = radioSong.elementsEqual(bohemianSong)\n\n//replacingOcurrences() method\nvar championsSong = \"\"\"\n I've paid my dues\nTime after time\nI've done my sentence\nBut committed no crime\nAnd bad mistakes\nI've made a few\n\"\"\"\n\nchampionsSong.replacingOccurrences(of: \"my\", with: \"your\")\n\n//trimmingCharacters() method removes whitespace from both ends of a string.\nvar underPressureSong = \" Under pressure that burns a building down Splits A FAMILY in two \"\nvar songWithOutSpaces = underPressureSong.trimmingCharacters(in: .whitespaces)\n\n//dropFirst() method removes the first character of the string.\nsongWithOutSpaces.dropFirst()\n\n//dropLast() method removes the last character of the string.\nsongWithOutSpaces.dropLast()\n\n//lowercased() method converts all uppercase characters in a string into lowercase characters.\nsongWithOutSpaces.lowercased()\n\n//uppercased() method converts all lowercase characters in a string into lowercase characters.\nsongWithOutSpaces.uppercased()\n\n//hasPrefix() method checks whether the string begins with the specified string or not.\nsongWithOutSpaces.hasPrefix(\"Und\")\n\n//hasSuffix() method checks whether the string ends with the specified string or not (is case-sensitive).\nsongWithOutSpaces.hasSuffix(\"xyz\")\n\n//contains() method checks whether the specified string (sequence of characters) is present in the string or not.\nchampionsSong.contains(\"time\")\n\n//joined() method returns a new string with the given elements joined with the specified delimiter.\nvar str = [\"I\",\"Love\",\"Swift\"]\nstr.joined(separator: \" \")\n\n//split() method breaks up a string at the specified separator and returns an array of strings.\nchampionsSong.split(separator: \" \")\n\n//reversed() method reverses the given string.\nString(championsSong.reversed())\n\n\n/*\n DIFICULTAD EXTRA (opcional):\n  * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n  * para descubrir si son:\n  * - Palíndromos\n  * - Anagramas\n  * - Isogramas (palabra que no contiene valores repetidos)\n*/\n\nfunc comparingWords(word1:String, word2: String) {\n    if word1 == String(word1.reversed()) && word2 == String(word2.reversed()) {\n        print(\"Both words are Palindrome.\")\n    } else if word1.sorted() == word2.sorted() {\n    print(\"Both words are anagram\")\n    } else {\n        print(\"I still don't know how to validate an isogram, pending to complete this in the future.\")\n    }\n}\n\ncomparingWords(word1: \"narran\", word2: \"seres\") //Palindrome\ncomparingWords(word1: \"ecuador\", word2: \"acuerdo\") //Anagram\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/swift/kontroldev.swift",
    "content": "import Foundation\n\n/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\n\n// Operaciones con cadenas de caracteres\n\n// Acceso a caracteres específicos\nlet palabra = \"Swift\"\nlet primerCaracter = palabra[palabra.startIndex] // Accede al primer caracter (\"S\")\n\n// Subcadenas\nlet subcadena = palabra[1..<3] // Crea una subcadena con los caracteres en las posiciones 1 y 2 (\"wi\")\n\n// Longitud\nlet longitud = palabra.count // Obtiene la longitud de la cadena (5)\n\n// Concatenación\nlet otraPalabra = \" es genial\"\nlet concatenacion = palabra + otraPalabra // Concatena dos cadenas (\"Swift es genial\")\n\n// Repetición\nlet repetida = String(repeating: palabra, count: 2) // Repite la cadena dos veces (\"SwiftSwift\")\n\n// Recorrido\nfor caracter in palabra {\n    print(caracter) // Itera sobre cada caracter e imprime (\"S\", \"w\", \"i\", \"f\", \"t\")\n}\n\n// Conversión a mayúsculas y minúsculas\nlet mayusculas = palabra.uppercased() // Convierte a mayúsculas (\"SWIFT\")\nlet minusculas = palabra.lowercased() // Convierte a minúsculas (\"swift\")\n\n// Reemplazo\nlet reemplazada = palabra.replacingOccurrences(of: \"i\", with: \"o\") // Reemplaza \"i\" con \"o\" (\"Swott\")\n\n// División\nlet palabrasSeparadas = \"Hola, mundo\".components(separatedBy: \",\") // Divide la cadena por coma ([\"Hola\", \" mundo\"])\n\n// Unión\nlet palabrasUnidas = palabrasSeparadas.joined(separator: \" \") // Une las palabras con un espacio (\"Hola mundo\")\n\n// Interpolación\nlet edad = 25\nlet mensaje = \"Tengo \\(edad) años\" // Crea una cadena interpolada (\"Tengo 25 años\")\n\n// Verificación\nlet contieneLetra = palabra.contains(\"w\") // Verifica si la cadena contiene la letra \"w\" (true)\n\n\n// Programa para comprobar palíndromos, anagramas e isogramas\n\nfunc esPalindromo(_ palabra: String) -> Bool {\n    let palabraInvertida = String(palabra.reversed())\n    return palabra == palabraInvertida\n}\n\nfunc sonAnagramas(_ palabra1: String, _ palabra2: String) -> Bool {\n    return palabra1.sorted() == palabra2.sorted()\n}\n\nfunc esIsograma(_ palabra: String) -> Bool {\n    let caracteresSinRepetir = Set(palabra)\n    return palabra.count == caracteresSinRepetir.count\n}\n\n// Ejemplos de uso\n\nlet palabra1 = \"oso\"\nlet palabra2 = \"oso\"\nlet palabra3 = \"amor\"\n\nprint(\"Es palíndromo: \\(esPalindromo(palabra1))\") // true\nprint(\"Son anagramas: \\(sonAnagramas(palabra1, palabra2))\") // true\nprint(\"Es isograma: \\(esIsograma(palabra3))\") // true\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/swift/miguelex.swift",
    "content": "import Foundation\n\nlet cadena = \"Esta va a ser nuestra cadena de ejemplo\"\n\nprint(cadena)\n\n// acceder al priemr caracter\n\nprint(\"El primer caracter es: \\(cadena[cadena.startIndex])\")\n\n// acceder al ultimo caracter\n\nprint(\"El ultimo caracter es: \\(cadena[cadena.index(before: cadena.endIndex)])\")\n\n// acceder a un caracter en una posicion concreta\n\nprint(\"Caracter en la posición 5 es: \\(cadena[adena.index(cadena.startIndex, offsetBy: 5)])\")\n\n// subcadena\n\nprint(\"Subcadena: \\(cadena[cadena.index(cadena.startIndex, offsetBy: 5)..<cadena.index(cadena.startIndex, offsetBy: 10)])\")\n\n// longitud\n\nprint(\"Longitud: \\(cadena.count)\")\n\n// concatenación\n\nlet otraCadena = \" y esta es otra cadena\"\n\nprint(\"Concatenación: \\(cadena + otraCadena)\")\n\n// repetición\n\nprint(\"Repetición: \\(String(repeating: cadena, count: 2))\")\n\n// recorrido\n\nfor caracter in cadena {\n    print(caracter)\n}\n\n// conversión a mayúsculas y minúsculas\n\nprint(\"Mayúsculas: \\(cadena.uppercased())\")\n\nprint(\"Minúsculas: \\(cadena.lowercased())\")\n\n// reemplazo\n\nprint(\"Reemplazo: \\(cadena.replacingOccurrences(of: \"a\", with: \"o\"))\")\n\n// busqueda de substring    \nif let index = cadena.firstIndex(of: \"a\"){\n    print(\"Substring: \\(cadena[index...])\")\n}\n\n// división\n\nprint(\"División: \\(cadena.components(separatedBy: \" \"))\")\n\n// unión\n\nprint(\"Unión: \\(cadena.components(separatedBy: \" \").joined(separator: \"-\"))\")\n\n// interpolación\n\nlet name = \"Migue\"\n\nprint(\"Interpolación: Me llamo \\(name)\")\n\n// verificación\n\nprint(\"Contiene la letra 'a': \\(cadena.contains(\"a\"))\")\n\n// Extra\n\nfunc esPalindromo(_ palabra: String) -> Bool {\n    let palabraInvertida = String(palabra.reversed())\n    return palabra.lowercased() == palabraInvertida.lowercased()\n}\n\nfunc sonAnagramas(_ palabra1: String, _ palabra2: String) -> Bool {\n    return palabra1.sorted() == palabra2.sorted()\n}\n\nfunc esIsograma(_ palabra: String) -> Bool {\n    let caracteresSinRepetir = Set(palabra)\n    return palabra.count == caracteresSinRepetir.count\n}\n\nprint (\"Ana es palíndromo: \\(esPalindromo(\"Ana\"))\")\nprint (\"roma y amor son anagramas: \\(sonAnagramas(\"roma\", \"amor\"))\")\nprint (\"Murcielago es isograma: \\(esIsograma(\"Murcielago\"))\")\nprint (\"Pavor es palíndromo: \\(esPalindromo(\"Pavor\"))\")\nprint (\"hola y ola Son anagramas: \\(sonAnagramas(\"hola\", \"ola\"))\")\nprint (\"colegiala es isograma: \\(esIsograma(\"colegiala\"))\")\n\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/swift/pedroomar23.swift",
    "content": "import Foundation \n\n/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\n// Operadores con cadena de caracteres \n\n// Caracteres especificos \nlet nombre = \"Pedro\"\nlet fisrtCharacter = nombre[nombre.startIndex] // Verificar el primir caracter de la cadena P\n\nprint(fisrtCharacter) // Imprimir en la consola firstChracter \n\n// Interpolacion\nlet nombre = \"Pedro\"\nlet interpolacion = \"El nombre es \\(nombre)\" // Interpolacion de la cadena de texto mediante \\()\n\nprint(interpolacion)\n\n// Concatenacion \nlet nombre1 = \"Pedro\"\nlet nombre2 = \"Juan\"\nlet concatenacion = nombre1 + nombre2 // Se le suma una constante a la otra a traves de la concatenacion\n\nprint(concatenacion) // Imprimir en la consola concatenacion \n\n// Repeticion\nlet nombre = \"Pedro\"\nlet repeticion = String(repeating: \"Pedro\", count: 2) // La cadena de texto \"Pedro\" se repite 2 veces \n\nprint(repeticion)\n\n// Verificacion\nlet nombre = \"Pedro\"\nlet verificacion = nombre.contains(\"P\") // Verificar si el caracter \"P\" se encuentra dentro de la cadena \n\nprint(verificacion) // Imprimir en la consola verificacion \n\n// Longitud\nlet nombre = \"Pedro\"\nlet longitud = nombre.count // Verificar la longitud de la cadena de texto \n\nprint(longitud) // Imprimir en la consola longitud\n\n// Recorrido\nlet nombres = \"Pedro\"\n\nfor character in nombres { // Se recorre la cadena de texto \"Pedro\" 5 veces \n    print(nombres)\n}\n\n// Division \nlet nombre = \"Hola Mundo\"\nlet division = \"Hola, Mundo\".components(separatedBy: \",\") // Separa la cadena de texto \"Hola Mundo\" con la , \n\nprint(division)\n\n// Union\nlet division = \"Hola, Mundo\".joined(separated: \" \") // La cadena de texto \"Hola Mundo\" se unen \n\n// Conversion a Mayuscula\nlet nombre = \"pedro\"\nlet conversion = nombre.uppercased() // La cadena de texto \"pedro\" cambia a mayuscula \"PEDRO\"\n\n// Conversion a Minuscula \nlet nombre = \"PEDRO\"\nlet conversion = nombre.lowercased() // La cadena de texto \"PEDRO\" cambia muniscula \"pedro\"\n\n// Subcadenas \nlet nombre = \"Pedro\"\nlet subcadena = nombre[1...<4] // Se crea una subcadena de la cadena de texto \"Pedro\" entre las posiciones 1, 2, 3\n\n\n\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/swift/zetared92.swift",
    "content": "import Foundation\n// RETO #04 CADENA DE CARACTERES\n\n// Acceso a caracteres específicos\nlet my_str = \"Rubik\"\n// Accede al primer caracter, en este caso \"R\"\nlet firstCharacter = my_str[my_str.startIndex]\nprint(firstCharacter)\n\n// Accede al último caracter\nlet lastCharacter = my_str[my_str.index(before: my_str.endIndex)]\nprint(lastCharacter)\n\n// Acceder a un caracter en posición X (En este caso la U)\nlet xPositionChar: Character = my_str[my_str.index(my_str.startIndex, offsetBy: 1)]\nprint(xPositionChar)\n\n// Eliminar\n// Eliminar el primer caracter\nmy_str.removeFirst()\nprint(my_str)\n//Eliminar el último caracter\nmy_str.removeLast()\nprint(my_str)\n// Eliminar todo\nmy_str.removeAll()\nprint(my_str)\n\n// Concatenación\nlet my_str2 = \"'s Cube\"\nlet concatenation = my_str + my_str2\nprint(concatenacion)\n\n// División\nlet div = \"Cubik's Rubik\".components(separatedBy: \"'s\")\nprint(div)\n\n// Interpolación\nlet year = 1974\nlet text = \"The Rubik's Cube was invented in \\(year)\"\nprint(text)\n\n// Longitud\nlet length = my_str.count\nprint(length)\n\n// Recorrer los caracteres que contiene el String\nfor character in my_str {\n    print(character)\n}\n\n// Reemplazo\nlet replancing = my_str.replacingOccurrences(of: \"u\", with: \"o\")\nprint(replancing)\n\n// Repetición\nlet rep = String(repeating: my_str, count: 3)\nprint(rep)\n\n// Subcadenas\nlet subStr = my_str[1..<4]\n\n// Verificación\nlet verification = my_str.contains(\"k\")\nprint(verification)\n\n\n// 🧩 DIFICULTAD EXTRA 🧩\n\nfunc palindromo(_ str1: String) -> Bool {\n    let invertedStr = String(str1.reversed())\n    return str1 == invertedStr\n\n} \n\nfunc anagrama(_ str2: String, _ str3: String) -> Bool {\n    return str2.sorted() == str3.sorted()\n}\n\nfunc isograma(_ str4: String) -> Bool {\n    let nonRepeatedChar = Set(str4)\n    return str4.count == nonRepeatedChar.count\n}\n\nlet str1 = \"radar\"\nlet str2 = \"electromagnético\"\nlet str3 = \"magnetoeléctrico\"\nlet str4 = \"bebe\"\n\nprint(\"Radar es palíndromo: \\(palindromo(str1))\")\nprint(\"Electromagnético y Magnetoeléctrico son anagramas: \\(anagrama(str2, str3))\")\nprint(\"Bebé es un isograma: \\(isograma(str4))\")"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/typescript/AChapeton.ts",
    "content": "//at, charAt - Recibe un numero y devuelve el caracter en esa posicion\nconst sentence: string = 'Mouredev by Brais Moure'\nconsole.log('at', sentence.at(10))\nconsole.log('charAt', sentence.charAt(3))\n\n\n//concat - Conecta dos strings y devuelve una nueva\nconst str1: string = 'Hola'\nconst str2: string = 'Mundo'\nconsole.log('concat con espacio', str1.concat(' ', str2))\nconsole.log('concat con caracter', str1.concat('-', str2))\n\n//startsWith & endsWith - Evalua si el string inicia/termina con los caracteres del string del argumento y devuelve un booleano\nconsole.log('startsWith 1', sentence.endsWith('Mouredeb'))\nconsole.log('startsWith 2', sentence.endsWith('by'))\nconsole.log('endsWith 1', sentence.endsWith('Moure'))\nconsole.log('endsWith 2', sentence.endsWith('dev'))\n\n//fromCharCode - Devuelve un string creada por una secuencia de unidades de UTF-16\nconsole.log('fromCharCode', String.fromCharCode(12, 24, 15, 9))\n\n//includes - Evalua si un substring se encuentra dentro de un string. Devuelve un booleano. Se diferencia entre mayusculas y minusculas\nconst word1: string = 'by'\nconst word2: string = 'By'\nconsole.log('includes 1', sentence.includes(word1))\nconsole.log('includes 2', sentence.includes(word2))\n\n//indexOf - Devuelve la posicion en la que un substring inicia dentro de un string. En caso que la substring se repita, devuelve la posicion de la primera encontrada.\n//lastIndexOf - Devuelve la posicion en la que un substring inicia dentro de un string. En caso que la substring se repita, devuelve la posicion de la ultima encontrada.\nconst newSentence: string = 'Hola mundo. Bienvenidos al stream! Adios mundo.'\nconst word3: string = 'mundo'\nconsole.log('indexOf', newSentence.indexOf(word3))\nconsole.log('lastIndexOf', newSentence.lastIndexOf(word3))\n\n//match - Devuelve los valores que coincidan con el regex\nconst regex = /[A-Z]/g //Evalua solo mayusculas\nconsole.log('match', sentence.match(regex))\n\n//padStart & padEnd - Agregan un caracter al inicio o al final de la string, segun tantos espacios falten entre el ancho del string, y el ancho del argumento.\nconsole.log('padStart', sentence.padStart(106, '-'))\nconsole.log('padStart', sentence.padStart(102, '.'))\nconsole.log('padEnd', sentence.padEnd(40, '^'))\nconsole.log('padEnd', sentence.padEnd(80, '*'))\n\n//raw - Metodo que funciona con template literals para crear un string, en base a otra que tenga caracteres especiales que no se quieren perder o interpretar de forma inadecuada.\nconst filePath = String.raw`C:\\Development\\profile\\aboutme.html`\nconsole.log('raw', `Ruta de acceso: ${filePath}`)\n\n//repeat - Devuelve una nueva string que contiene el numero de copias del string del argumento, concatenadas\nconst strSinSpacio: string = 'Mundo!'\nconst strConSpacio: string = 'Mundo! '\nconsole.log('repeat 1', `Hola ${strSinSpacio.repeat(3)}`)\nconsole.log('repeat 2', `Hola ${strConSpacio.repeat(5)}`)\n\n//replace - Sustituye uno, varios, o toda un string, con otra string del segundo argumento del metodo.\nconst ownRegex = /Brais Moure/i\nconsole.log('replace 1', sentence.replace('Brais', 'AChapeton'))\nconsole.log('replace 2', sentence.replace(ownRegex, 'Andres'))\n\n//search - Ejecuta una busqueda en base a un regex para buscar una similitud en un string, y devolver el index de esa primera similitud\nconst regex2 = /[^\\w\\s']/g; //Este regex evalua todo lo que NO sea una palabra, espacios en blanco, o comillas\nconsole.log('search', newSentence.search(regex2))\n\n//slice - Extrae una seccion del string y retorna una nueva, si modificar la original\nconsole.log('slice', sentence.slice(7))\n\n//split - Divide el string en base a un patron, y crea un array con las substrings resultantes\nconsole.log('split', sentence.split(' '))\n\n//toLowerCase & toUpperCase - Devuelve un string transformado todo a minusculas/mayusculas\nconsole.log('toLowerCase', sentence.toLowerCase())\nconsole.log('toUpperCase', sentence.toUpperCase())\n\n//trim - Elimina todos los espacios vacios que se encuentren al inicio o al final de un string\n//trimStart - Elimina solo los espacios vacion que se encuentra al inicio\n//trimEnd - Elimina solo los espacios vacion que se encuentra al final\nconst whiteSpaces: string = '    Hello World!     '\nconsole.log('trim 1', whiteSpaces)\nconsole.log('trim 2', whiteSpaces.trim())\nconsole.log('trimStart', whiteSpaces.trimStart())\nconsole.log('trimEnd', whiteSpaces.trimEnd())\n\n\nconst esPalindromo = (my_string: string): void => {\n  const reverseStr: string = my_string.toLowerCase().split('').reverse().join('')\n  if(my_string.toLowerCase() === reverseStr){\n    console.log('Es palindroma')\n  }else{\n    console.log('No es palindroma')\n  }\n}\n\nesPalindromo('reconocer')\nesPalindromo('mundo')\n\nconst esAnagrama = (str1: string, str2: string): void => {\n  const reverseStr2: string = str2.toLowerCase().split('').reverse().join('')\n  if(str1.toLowerCase() === reverseStr2){\n    console.log(`La palabra ${str1} es un anagrama`)\n  }else{\n    console.log(`${str1} no es un anagrama`)\n  }\n}\n\nesAnagrama('amor', 'roma')\n\nconst esIsograma = (my_string: string): void => {\n  const letrasArray: String[] = my_string.toLowerCase().split('')\n  const letrasSet = new Set(letrasArray)\n  if(letrasArray.length === letrasSet.size){\n    console.log(`La palabra ${my_string} es un isograma`)\n  }else{\n    console.log(`${my_string} no es un isograma`)\n  }\n}\n\nesIsograma('murcielago')\nesIsograma('ambiente')\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/typescript/EdiedRamos.ts",
    "content": "// Autor: EdiedRamos\n\n// Ejercicio base\nfunction stringFunctions() {\n  const username: string = \"Edied Ramos\";\n  const dirtyUsername: string = \"    Edied Ramos     \";\n\n  console.log(\"Longitud de la cadena:\", username.length);\n  console.log(\"Carácter en la primer posición:\", username.charAt(0));\n  console.log(\n    \"Carácter en la primer posición pero en código UTF-16:\",\n    username.charCodeAt(0)\n  );\n\n  console.log(\"Carácter en la última posición:\", username.at(-1));\n  console.log(\"Últimos 5 carácteres:\", username.slice(-5));\n  console.log(\"Primeros 5 carácteres:\", username.substring(0, 5));\n  // El método \"substr\" está deprecado, pero es útil para compatibilidad\n  console.log(\n    \"4 carácteres a partír de la segunda posición:\",\n    username.substr(1, 4)\n  );\n\n  console.log(\"Nombre de usuario en mayúscula:\", username.toUpperCase());\n  console.log(\"Nombre de usuario en minuscula:\", username.toLowerCase());\n\n  console.log(\n    \"Saludo concatenado con el nombre de usuario:\",\n    \"Hola \".concat(username)\n  );\n\n  console.log(\n    \"Nombre de usuario sin espacios al inicio ni al final:\",\n    dirtyUsername.trim()\n  );\n  console.log(\n    \"Nombre de usuario sin espacios al inicio:\",\n    dirtyUsername.trimStart()\n  );\n  console.log(\n    \"Nombre de usuario sin espacios al final:\",\n    dirtyUsername.trimEnd()\n  );\n\n  console.log(\" con 15 carácteres:\", username.padStart(15, \"_\"));\n  console.log(\"Nombre de usuario con 15 carácteres:\", username.padEnd(15, \"_\"));\n\n  console.log(\"2 veces el nombre de usuario:\", username.repeat(2));\n\n  console.log(\"Reemplaza la primer d por D:\", username.replace(\"d\", \"D\"));\n  console.log(\"Reemplaza todas las d por D:\", username.replaceAll(\"d\", \"D\"));\n\n  console.log(\"Palabras en el nombre de usuario: \", username.split(\" \"));\n}\n\n// Ejercicio extra\nfunction createMessage(\n  value: string,\n  status: boolean,\n  context: string,\n  isPlural?: boolean\n) {\n  return `${value}: ${\n    status ? (isPlural ? \"Son\" : \"Es\") : isPlural ? \"No son \" : \"No es\"\n  } ${context}`;\n}\n\nfunction palindromeCase() {\n  const isPalindrome = (str: string): boolean => {\n    for (let i = 0; i < str.length / 2; i++) {\n      if (str[i] !== str[str.length - i - 1]) return false;\n    }\n    return true;\n  };\n  const firstWord = \"abcba\",\n    secondWord = \"ediedramos\";\n\n  console.log(createMessage(firstWord, isPalindrome(firstWord), \"palindromo\"));\n  console.log(\n    createMessage(secondWord, isPalindrome(secondWord), \"palindromo\")\n  );\n}\n\nfunction anagramCase() {\n  const areAnagram = (wordA: string, wordB: string): boolean => {\n    const wordASorted = [...wordA].sort().join(\"\");\n    const wordBSorted = [...wordB].sort().join(\"\");\n    return wordASorted === wordBSorted;\n  };\n  const firstWord = \"ramosedied\",\n    secondWord = \"ediedramos\";\n\n  console.log(\n    createMessage(\n      `${firstWord} y ${secondWord}`,\n      areAnagram(firstWord, secondWord),\n      \"anagramas\",\n      true\n    )\n  );\n}\n\nfunction isogramCase() {\n  const isIsogram = (str: string): boolean => {\n    const frecuency: Record<number, number> = {};\n    for (const char of str) {\n      const isALetter = /[a-z]/i.test(char);\n      if (isALetter) {\n        if (!frecuency[char]) frecuency[char] = 0;\n        frecuency[char]++;\n      }\n    }\n    const unique = new Set();\n    for (const key of Object.keys(frecuency)) unique.add(frecuency[key]);\n    return unique.size === 1;\n  };\n  const firstWord = \"edied\",\n    secondWord = \"ramos\";\n\n  console.log(createMessage(firstWord, isIsogram(firstWord), \"isograma\"));\n  console.log(createMessage(secondWord, isIsogram(secondWord), \"isograma\"));\n}\n\nfunction extraExercise() {\n  palindromeCase();\n  anagramCase();\n  isogramCase();\n}\n\n(() => {\n  stringFunctions();\n  extraExercise();\n})();\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/typescript/Guillemduno.ts",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición,\n *   recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión,\n *   interpolación, verificación...\n */\n\nconsole.log(\"Dentro consola!\");\n\nconst miFrase: string = \"Hay una casa verde.\";\n\n/**\n *  charAt() - Devuelve la letra de la posicion indicada.\n */\nconst posicionA = miFrase.charAt(1);\nconsole.log(`charAt: ${posicionA}`); // a\n\n/**\n * charCodeAt() - Devuelve el valor en format Unicode.\n *\n * Unicode provides a unique number for every character,\n * no matter what the platform,\n * no matter what the program,\n * no matter what the language.\n */\nconst posicionB = miFrase.charCodeAt(1);\nconsole.log(`charCodeAt: ${posicionB}`); // 97\n\n/**\n * codePointAt() -\n */\n\nconst posicionC = miFrase.codePointAt(1);\nconsole.log(`codePointAt: ${posicionC}`); // 97\n\n/**\n * concat() - concatena dos cadenas.\n */\n\nconst posicionD = miFrase.concat(miFrase, \" El sol se pone.\");\nconsole.log(`concat: ${posicionD}`);\n\n/**\n * endsWith() - Devuelve true si la cadena termina con la misma cadena que se le\n * passa en el argumento, sino coincide devuelve false.\n */\n\nconst posicionE = miFrase.endsWith(\"verde.\");\nconsole.log(`endsWith: ${posicionE}`); // true\n\nconst posicionF = miFrase.endsWith(\"verdes.\");\nconsole.log(`endsWith: ${posicionF}`); // false\n\n/**\n * include () - Devuelve true o false si se encuentra la cadena que se passa como\n * argumento.\n */\n\nconst posicionG = miFrase.includes(\"casa\");\nconsole.log(`include: ${posicionG}`); // true\n\nconst posicionH = miFrase.includes(\"casita\");\nconsole.log(`include: ${posicionH}`); // false\n\n/**\n * indexOf() - Devuelve la posicion de la primera letra de la cadena que se le\n * passa como argumento.\n */\n\nconst posicionI = miFrase.indexOf(\"casa\");\nconsole.log(`indexOf: ${posicionI}`); // 8\n\n/**\n * lastIndexOf() - Devuelve la posicion de la última ocurrencia de la cadena que\n * se pasa como argumento.\n */\n\nconst posicionJ = miFrase.lastIndexOf(\"e\");\nconsole.log(`lastIndexOf: ${posicionJ}`); // 17\n\n/**\n * length - Devuelve el total de caracteres que contiene la cadena.\n */\n\nconst posicionK = miFrase.length;\nconsole.log(`length: ${posicionK}`); // 19\n\n/**\n * localeCompare() - ?\n */\n\nconst posicionL = miFrase.localeCompare(\"La casa roja.\");\nconsole.log(`localeCompare: ${posicionL}`); // -1\n\nconst posicionM = miFrase.localeCompare(\"Hay una casa verde.\");\nconsole.log(`localeCompare: ${posicionM}`); // 0\n\n/**\n * match() - Devuelve un objeto con los caracteres encontrados mediante la\n * expresión regular.\n */\n\nconst posicionN = miFrase.match(/[a-z]/g);\nconsole.log(`match: ${posicionN}`); //  a,y,u,n,a,c,a,s,a,v,e,r,d,e\n\n/**\n * normalize() - ?\n */\n\nconst posicionO = miFrase.normalize();\nconsole.log(`normalize: ${posicionO}`);\n\n/**\n * repeat() - Repite la cadena tantas veces como se indica numericamente en el\n * argumento.\n */\n\nconst posicionP = miFrase.repeat(4);\nconsole.log(`repeat: ${posicionP}`);\n\n/**\n * replace() - Sustituye un caracter por otro.\n */\n\nconst posicionQ = miFrase.replace(\"a\", \"A\");\nconsole.log(`replace: ${posicionQ}`);\n\n/**\n * search() - Devuelve la posicion de la primera palabra encontrada.\n * si no encuentra nada devuelve -1.\n *\n * Se le puede passar como argumento una expresion regular /ver/i\n */\n\nconst posicionR = miFrase.search(\"verde\");\nconsole.log(`replace: ${posicionR}`); // 13\nconst posicionRR = miFrase.search(\"verdes\");\nconsole.log(`replace: ${posicionRR}`); // -1\nconst posicionRRR = miFrase.search(/ver/i);\nconsole.log(`replace: ${posicionRRR}`); // 13\n\n/**\n * slice() - Devuelve un trozo de la cadena.\n */\n\nconst posicionS = miFrase.slice(0, 3);\nconsole.log(`slice: ${posicionS}`); // Hay\n\n/**\n * split() - Devuelve un array con los trozos de la cadena separados.\n */\n\nconst posicionT = miFrase.split(\" \");\nconsole.log(`split: ${posicionT}`);\nconsole.log(posicionT[2]); // casa\n\n/**\n *  startsWith() - Devuelve true o false si la cadena empieza o no con la\n * misma cadena que se le pasa por argumento.\n */\nconst posicionSs = miFrase.startsWith(\"Hay\");\nconsole.log(`startsWith: ${posicionSs}`); // true\nconst posicionSss = miFrase.startsWith(\"Tay\");\nconsole.log(`startsWith: ${posicionSss}`); // false\n\n/**\n * substring() - Devuelve una cadena con el trozo de string seleccionado.\n */\nconst posicionU = miFrase.substring(8, 12);\nconsole.log(`substring: ${posicionU}`); // casa\n\n/**\n * toLocateLowerCase() -\n */\n\nconst posicionUu = miFrase.toLocaleLowerCase();\nconsole.log(`toLocateLowerCase: ${posicionUu}`);\n\n/**\n * toLocaleUpperCase() -\n */\n\nconst posicionUuu = miFrase.toLocaleUpperCase();\nconsole.log(`toLocaleUpperCase: ${posicionUuu}`);\n\n/**\n * toLowerCase() -\n */\n\nconst posicionUuuu = miFrase.toLowerCase();\nconsole.log(`toLowerCase: ${posicionUuuu}`);\n\n/**\n * toString() - Devuelve una cadena.\n */\n\nconst posicionV1 = miFrase.toString();\nconsole.log(`toString: ${posicionV1}`);\n\n/**\n * toUpperCase() -\n */\n\nconst posicionV = miFrase.toUpperCase();\nconsole.log(`toUpperCase: ${posicionV}`);\n\n/**\n * trim() - Elimina los espacios en blanco de inici i fin.\n */\n\nconst posicionV2 = miFrase.trim();\nconsole.log(`trim: ${posicionV2}`);\n\n/**\n * valueOf() - Devuelve el valor primitivo del objeto especificado.\n */\n\nconst posicionV3 = miFrase.valueOf();\nconsole.log(`valueOf: ${posicionV3}`);\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n *\n * - Palíndromos: es una palabra o frase que se lee igual en un sentido que en\n *                otro (por ejemplo; Ana, Anna, Otto). Si se trata de números en\n *                lugar de letras, se llama capicúa.\n *\n * - Anagramas: Un anagrama es una palabra que resulta de la transposición de\n *              todas las letras de otra palabra. Dicho de otra forma, una palabra\n *              es anagrama de otra si las dos tienen las mismas letras, con el\n *              mismo número de apariciones, pero en un orden diferente. Esto se\n *              aplica también a grupos de palabras o frases.\n *\n * - Isogramas: Un isograma (del griego isos, 'igual' y gramma, 'letra') es\n *              una palabra o frase en la que cada letra aparece el mismo número\n *              de veces.3​ Si cada letra aparece solo una vez será un heterograma,\n *              si aparece dos, un isogroma de segundo orden y así sucesivamente.\n */\n\nfunction analizaPalabras(palabra1: string, palabra2: string): void {\n  console.log(\"===========================================================================================\");\n  console.log(`================ ANALIZADOR DE LAS PALABRAS (${palabra1}) y (${palabra2}) =================`);\n  console.log(\"===========================================================================================\");\n  // Comprueba si son iguales\n  if (palabra1 === palabra2) {\n    // validar si és palindromo\n    esPalabraPalindromo(palabra2);\n    esPalabraAnagrama(palabra1, palabra2);\n    esPalabraIsograma(palabra2);\n\n    // Comprueba si tienen la misma longitud\n  } else if (palabra1.length === palabra2.length) {\n    esPalabraPalindromo(palabra2);\n    esPalabraAnagrama(palabra1, palabra2);\n    esPalabraIsograma(palabra2);\n  } else {\n    console.log(`Las palabra '${palabra2}' no tiene la misma longitud que la palabra '${palabra1}'.`);\n  }\n}\n\n// Comprueba si una palabra és palindromo o no.\nfunction esPalabraPalindromo(palabra: string): boolean {\n  for (let index = 0; index < palabra.length; index++) {\n    let indexNegativo = palabra.length - 1 - index;\n    let letraInicial = palabra[index];\n    let letraFinal = palabra[indexNegativo];\n\n    if (letraInicial !== letraFinal) {\n      console.log(`${palabra} no és palindromo...`);\n      return false;\n    }\n  }\n  console.log(`${palabra} no és un super palindromo!`);\n  return true;\n}\n\n// Comprueba si una palabra és anagrama.\nfunction esPalabraAnagrama(palabra1: string, palabra2: string): boolean {\n  if (palabra1 === palabra2) {\n    console.log(`${palabra2} no és una anagrama!`);\n    return false;\n  }\n  // Recorre la primera palabra para ver si la segunda palabra contiene las mismas letras.\n  for (let index = 0; index < palabra1.length; index++) {\n    let letra = palabra1[index];\n    if (!palabra2.includes(letra)) {\n      console.log(`${palabra2} no és una anagrama!`);\n      return false;\n    }\n  }\n  console.log(`${palabra2} és un super anagrama!`);\n  return true;\n}\n\nfunction esPalabraIsograma(palabra: string): boolean {\n  for (let index = 0; index < palabra.length; index++) {\n    const letra = palabra[index];\n    const palabraMenosletra = palabra.replace(letra, \"\");\n    if (palabraMenosletra.includes(letra)) {\n      console.log(`${palabra} NO és un isograma...`);\n      return false;\n    }\n  }\n  console.log(`${palabra} és un isograma!`);\n  return true;\n}\n\n// Guarda las dos palabras que introduce el usuario.\nconst palabra1 = prompt(\"Escribe una palabra o frase\");\nconst palabra2 = prompt(\"Escribe otra palabra o frase\");\n\n// Si los campos estan llenos ejecutamos el programa para analizar palabras.\nif (palabra1 && palabra2) {\n  analizaPalabras(palabra1, palabra2);\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/typescript/IgleDev.ts",
    "content": "// 1º Ejemplos de todas las operaciones que puedes realizar con cadenas.\n    let mensaje : string = 'Ola Mundo';\n    let mensaje2 : string = 'Soy Igledev';\n\n    // -- charAt\n    console.log('charAt' + mensaje.charAt(10)); // Recive un numero y devuelve su caracter.\n\n    // -- Concat\n    console.log('concat' + mensaje.concat(' ' + mensaje2)); // Se le puede pasar carárteres como '-' , '/' , '_' , etc...\n\n    // -- startsWith\n    console.log('Starswith: ' + mensaje.startsWith('Ola')); // Evalua si el string inicia con lo que le pasamos en el argumento y nos devuelve un boolean.\n\n    // -- endsWith\n    console.log('Endswith: ' + mensaje2.endsWith('Igledev')); // Evalua si el string acaba con lo que le pasamos en el argumento y nos devuelve un boolean.\n\n    // -- includes\n    let texto : string = 'Mundo';\n    console.log('includes: ' + mensaje.includes(texto)); // Comprueba si el substring que le pasamos como argumento está en el string, nos devuelve un booleano.\n\n    // -- indexOf\n    console.log('indexOf: ' + mensaje.indexOf(texto)); // Devuelve la posicion en la que un substring inicia dentro de un string, en caso de que se repita devuelve la primera posición encontrada.\n\n    // -- lastIndexof\n    console.log('lastIndexOf' + mensaje.lastIndexOf(texto)); // Devuelve la posicion en la que un substring acaba dentro de un string. En caso que la substring se repita, devuelve la posicion de la última encontrada.\n\n    // -- match\n    let regex = /[A-Z]/g; //Evalua solo mayusculas.\n    console.log('match' + mensaje.match(regex));\n\n    // -- replace\n    const ownRegex = /Brais Moure/i\n    console.log('replace 1' + mensaje.replace(texto, 'Ola')); // Sustituye uno, varios, o toda un string, con otra string del segundo argumento del metodo.\n\n    // -- slice\n    console.log('slice' + mensaje.slice(4)); // Extrae una seccion del string y retorna una nueva, sin modificar la original.\n\n    // -- split\n    console.log('split' + mensaje.split(' ')); // Divide y crea un array con los substrings resultantes.\n\n    // -- toLowerCase\n    console.log('toLowerCase' + mensaje.toLowerCase()); // Devuelve un string transformado todo a minusculas.\n\n    // -- toUpperCase\n    console.log('toUpperCase' + mensaje.toUpperCase()); // Devuelve un string transformado todo a mayuscula.\n\n    // -- trim\n    console.log('trim: ' + mensaje.trim()); // Elimina todos los espacios vacios que se encuentren al inicio o al final de un string.\n\n    // -- trimStart\n    console.log('trimStart: ' + mensaje.trimStart()); // Elimina solo los espacios vacion que se encuentra al inicio.\n\n    // -- trimEnd\n    console.log('trimEnd: ' + mensaje.trimEnd()); // Elimina solo los espacios vacion que se encuentra al final.\n\n// Ejercicio Extra\n\n    // Palíndromo\n    let palindromo = (cadena: string) : boolean => {\n        let reverse : string = cadena.toLowerCase().split('').reverse().join('')\n        if(cadena.toLowerCase() === reverse){\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    console.log('La palabra es palíndroma? ' + palindromo('reconocer'));\n\n    // Anagrama\n    let anagrama = (cadena1 : string , cadena2 : string) : boolean => {\n        let reverse : string = cadena2.toLowerCase().split('').reverse().join('');\n        if(cadena1.toLowerCase() === reverse){\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    console.log('La palabra es anagrama? ' + anagrama('amor' , 'roma'));\n\n    // Isograma\n    let isograma = (cadena1: string): boolean => {\n        let letrasArray: String[] = cadena1.toLowerCase().split('');\n        let letras = new Set(letrasArray);\n        if(letrasArray.length === letras.size){\n          return true;\n        }else{\n          return false;\n        }\n    }\n\n    console.log('La palabra es un isograma? ' + isograma('murcielago'));"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/typescript/RicJDev.ts",
    "content": "//EJERCICIO\n//Acceso a caracteres específicos\nconst myAlphabet: string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'\n\nconsole.log(myAlphabet[17] + myAlphabet[8] + myAlphabet[2])\n\nconst nameChart1: string = myAlphabet.charAt(17)\nconst nameChart2: string = myAlphabet.charAt(8)\nconst nameChart3: string = myAlphabet.charAt(2)\n\nconsole.log(nameChart1, nameChart2, nameChart3)\n\nconst rPosition: number = myAlphabet.indexOf('R')\n\nconsole.log(`La letra R es la número ${rPosition + 1} de nuestro alfabeto`)\n\n//Longitud\nconst phrase: string = 'Me encantan las papas fritas'\n\nconsole.log(`\\\"${phrase}\\\" tiene ${phrase.length} caracteres`)\n\n//Subcadenas\nconst phraseSlice: string = phrase.slice(16)\n\nconsole.log(phraseSlice)\n\nconst heroes: string = 'Batman le gana a Superman'\nconst Batman: string = heroes.substring(0, 6)\nconst Superman: string = heroes.substring(17)\n\nconsole.log(Batman)\nconsole.log(Superman)\n\n//Concatenación\nlet action: string = ' está peleando con '\n\nconsole.log(Batman.concat(action, Superman))\nconsole.log(Batman + action + Superman)\n\n//Repetición\nlet ric: string = 'Ric '\n\nconsole.log(ric.repeat(3))\n\n//Recorrido\nfor (let i = 0; i < myAlphabet.length; i++) {\n\tconsole.log(myAlphabet[i])\n}\n\n//Conversión a mayúsculas y minúsculas\nconst fruits: string[] = ['fresa', 'PARCHITA', 'LiMÓn', 'Mango']\n\nfruits.forEach((fruit) => {\n\tconsole.log(fruit.toUpperCase())\n})\n\nfruits.forEach((fruit) => {\n\tconsole.log(fruit.toLowerCase())\n})\n\n//Reemplazo\nlet musicPlayer = 'Music Player current song: The Pretender - Foo Fighters'\nconsole.log(musicPlayer)\n\nmusicPlayer = musicPlayer.replace('The Pretender - Foo Fighters', 'Monster - Skillet')\nconsole.log(musicPlayer)\n\n//División\nconst companiesString: string = 'Google, Apple, Telegram, Facebook'\nconst companiesArr = companiesString.split(', ')\n\nconsole.log(companiesArr)\n\n//Unión\nconst colorsArray = ['blue', 'red', 'yellow', 'white']\nconst colorsString = colorsArray.join(', ')\n\nconsole.log(colorsString)\n\n//Interpolación\nconsole.log(`\\n\\\"TypeScript es JavaScript premium\\\" \\n\\n\\t\\t\\t${ric.toUpperCase()}\\n`)\n\n//Verificación\nconst fiveInSpanish: string = 'Cinco'\nconst fiveCharsRegex = /\\b[A-Za-z]{5}\\b/g\n\nconsole.log('Tiene cinco caracteres la palabra \"cinco\"?', fiveCharsRegex.test(fiveInSpanish))\n\n//Otros\nconst randomPhrase = 'Pedro estaba bebiendo un jugo de manzana'\nconst jRegex = /\\b[Jj]{1}[A-Za-z]{3}\\b/g\n\nlet result = randomPhrase.match(jRegex)\n\nconsole.log(result)\n\n//EXTRA\nfunction analyzeTheseWords(word1: string, word2: string) {\n\tfunction palindrome(word: string) {\n\t\tconst reversedWord = word.toLowerCase().split('').reverse().join('')\n\n\t\tif (word.toLowerCase() === reversedWord) {\n\t\t\tconsole.log(`${word} es un palíndromo`)\n\t\t} else {\n\t\t\tconsole.log(`${word} no es un palíndromo`)\n\t\t}\n\t}\n\n\tfunction anagram(word1: string, word2: string) {\n\t\tconst arr1 = word1.toLowerCase().split('').sort().join('')\n\t\tconst arr2 = word2.toLowerCase().split('').sort().join('')\n\n\t\tif (arr1 === arr2) {\n\t\t\tconsole.log(`${word1} es un anagrama de ${word2}`)\n\t\t} else {\n\t\t\tconsole.log(`${word1} no es un anagrama de ${word2}`)\n\t\t}\n\t}\n\n\tfunction isogram(word: string) {\n\t\tconst array = word.toLowerCase().split('')\n\t\tconst set = new Set(array)\n\n\t\tif (array.length === set.size) {\n\t\t\tconsole.log(`${word} es un isograma`)\n\t\t} else {\n\t\t\tconsole.log(`${word} no es un isograma`)\n\t\t}\n\t}\n\n\tpalindrome(word1)\n\tpalindrome(word2)\n\n\tanagram(word1, word2)\n\n\tisogram(word1)\n\tisogram(word2)\n}\n\nanalyzeTheseWords('Roma', 'Amor')\nanalyzeTheseWords('Radar', 'Paloma')\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/typescript/RobertoAmaroHub.ts",
    "content": "\nlet comillasDobles: string = \"texto entre comillas dobles\";\nconsole.log(comillasDobles);\nlet comillasSimples: string = 'texto entre comillas simples';\nconsole.log(comillasSimples);\nlet bt_test:string = \"prueba dentro\";\nlet backTicks: string =`texto entre backTicks: ${bt_test}`;//interpolación\nconsole.log(backTicks);\n//concadenación\nconsole.log(backTicks+comillasDobles);\n//iteración\nlet vocales: string=\"aeiou\";\nfor(let vocal of vocales){\n    console.log(vocal+\" \")\n}\n//minúsculas\nconsole.log(\"minúsculas: \"+comillasDobles.toLowerCase());\n//mayúsculas\nconsole.log(\"mayúsculas: \"+comillasDobles.toUpperCase());\n//longitud\nconsole.log(\"longitud: \"+comillasDobles.length);\n//eliminar espacios al inicio y final del texto\nlet textoEspacios:string=\"   texto     \";\nconsole.log(textoEspacios.trim());\n//posición de un carácter\nconsole.log(comillasDobles[4]);\nconsole.log(comillasDobles.charAt(4));\n//validar comienzo de un texto\nconsole.log(comillasDobles.startsWith(\"texto\"));\n//validar final de un texto\nconsole.log(comillasSimples.endsWith(\"simples\"));\n//buscar el indexof dentro de una cadena\nconsole.log(\"indexOf: \"+comillasDobles.indexOf(\"dobles\"));\n//Cuando indexOf NO encuentra la subcadena devuelve -1\nconsole.log(\"indexOf NO encontrado: \"+comillasDobles.indexOf(\"simples\"));\n//includes, Valida si encuentra o no una subcadena\nconsole.log(`¿la palabra \"entre\" fue encontrada? ${comillasDobles.includes(\"entre\")}`);\nconsole.log(`¿la palabra \"dado\" fue encontrada? ${comillasDobles.includes(\"dado\")}`);\n//slice divide el texto en el índice de inicio y final que nosotros especifiquemos\nconsole.log(\"slice: \"+comillasDobles.slice(2,7));\n//replace reemplaza el texto especificado por algún otro\nconsole.log(\"replace: \"+comillasDobles.replace(\"texto\",\"frase\"));\n//split divide el texto en subtextos dependiendo de el separador que especifiquemos devolviendo un arreglo\nconsole.log(\"split: \"+comillasDobles.split(\" \"));\n\n/* DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\nvar prompt = require(\"prompt-sync\")();\nimport * as readline from 'readline';\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\nfunction cerrarApp(){\n    console.log(\"Finalizando aplicación\")\n    rl.close();\n}\n\nconsole.log(\"\\n******Analizando palabras*******\")\nlet palabra1:string=\"\";\nlet palabra2:string=\"\";\n\nfunction ingresandoPalabras(){\n    palabra1=prompt(\"Ingresa la primera palabra: \")\n    palabra2=prompt(\"Ingresa la segunda palabra: \")\n}\nfunction validandoPalabras(): boolean{\n    let isCorrect:boolean=false;\n    for(let char of palabra1){\n        if(!isNaN(+char)){\n            console.log(\"Las palabras no pueden contener números, inténtalo de nuevo\");\n            break;\n        }\n        if(palabra1.includes(\" \") || palabra2.includes(\" \")){\n            console.log(\"Las palabras no pueden contener espacios, inténtalo de nuevo\");\n            break;\n        }\n    }\n    for(let char of palabra2){\n        if(!isNaN(+char)){\n            console.log(\"Las palabras no pueden contener números, inténtalo de nuevo\");\n            break;\n        }\n    }\n    if(palabra1.trim().toLowerCase()==palabra2.trim().toLowerCase()){\n        console.log(\"Las palabras no pueden ser iguales, inténtalo de nuevo\");\n    } else if(palabra1.trim().length<1 || palabra2.trim().length<1){\n        console.log(\"Las palabras no pueden estar vacías, inténtalo de nuevo\");\n    } else{\n        isCorrect=true;\n    }\n    return isCorrect;\n}\n\nfunction isPalindromo(palabra:string){\n    if(palabra.split(\"\").toString()===palabra.split(\"\").reverse().toString()){\n        console.log(`la palabra ${palabra} es un palíndromo`)\n    }else{\n        console.log(`la palabra ${palabra} NO es un palíndromo`)\n    }\n}\n\nfunction sonAnagramas(){\n    let _pal1:string[]=palabra1.split(\"\");\n    let _pal2:string[]=palabra2.split(\"\");\n    if(_pal1.sort().toString()==_pal2.sort().toString()){\n        console.log(`${palabra1} y ${palabra2} son anagramas`)\n    } else {\n        console.log(`${palabra1} y ${palabra2} NO son anagramas`)\n    }\n}\n\nfunction esIsograma(palabra:string){\n    let tempArray:string[]=[];\n    for(let char of palabra){\n        tempArray.push(char);\n        if(tempArray.filter((valor)=>valor==char).length>1){\n            console.log(`la ${palabra} NO es isograma`)\n            return;\n        }\n    }\n    console.log(`la ${palabra} es isograma`)\n}\n\nfunction analizandoPalabras(){\n    ingresandoPalabras();\n    if(!validandoPalabras()){\n        analizandoPalabras()\n    }\n    console.log(\"\\n\")\n    isPalindromo(palabra1);\n    isPalindromo(palabra2);\n    console.log(\"\\n\")\n    sonAnagramas();\n    console.log(\"\\n\")\n    esIsograma(palabra1)\n    esIsograma(palabra2)\n    cerrarApp();\n}\n\nanalizandoPalabras();\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/typescript/Sac-Corts.ts",
    "content": "// Define a character string\nlet text: string = \"TypeScript is a typed language\";\n\n// 1. Access to specific characters\nlet firstCharacter: string = text[0];\nlet lastCharacter: string = text[text.length - 1];\n\n// 2. String length\nlet _length: number = text.length; \n\n// 3. Substrings\nlet substring: string = text.substring(0, 10);\nlet substringSlice: string = text.slice(11, 13);\n\n// 4. String concatenation\nlet additionalText: string = \" with type support\";\nlet concatenated: string = text.concat(additionalText);\nlet concatenationWithOperator: string = text + additionalText;\n\n// 5. Repetition\nlet repeat: string = \"Hi! \".repeat(3);\n\n// 6. Iterate a string\nfor (let char of text) {\n    console.log(char);\n}\n\n// 7. Conversion to upper and lower case\nlet uppercase: string = text.toUpperCase();\nlet lowercase: string = text.toLowerCase();\n\n// 8. Character or substring replacement\nlet replacement: string = text.replace(\"typed\", \"modern\");\n\n// 9. Divison of strings in array\nlet _words: string[] = text.split(\" \");\n\n// 10. Union of an array of strings\nlet united: string = _words.join(\"-\");\n\n// 11. String interpolation\nlet version: number = 4;\nlet interpolation: string = `The current version of TypeScript is ${version}`;\n\n// 12. Checking if one string contains another\nlet contains: boolean = text.includes(\"language\");\nlet startsWith: boolean = text.startsWith(\"Type\");\nlet endsWith: boolean = text.endsWith(\"language\");\n\n// 13. Substring or character indexes\nlet indexWord: number = text.indexOf(\"typed\");\nlet lastIndexLetter: number = text.lastIndexOf(\"e\");\n\n// 14. Remove whitespace\nlet textWithSpace: string = \"   TypeScript   \";\nlet noSpace: string = textWithSpace.trim();\nlet noStartSpace: string = textWithSpace.trimStart();\nlet noEndSpace: string = textWithSpace.trimEnd();\n\n// 15. Compare strings\nlet isEqual: boolean = text === \"TypeScript is a typed language\";\nlet isEqualIgnoreCase: boolean = text.toLowerCase() === \"typescript is a typed language\";\n\n// 16. Type conversions to string\nlet number: number = 42;\nlet numberAsString: string = number.toString();\n\n// 17. Find a pattern with regular expressions\nlet regex: RegExp = /typed/i;\nlet coincidence: boolean = regex.test(text);\n\n// 18. Get matches of a regular expression\nlet coincidences: RegExpMatchArray | null = text.match(/e/g);\n\n// *** Extra Exercise *** //\nfunction checkPalindromeTypeScript(word: string): boolean {\n    let inverted: string = word.split('').reverse().join('').toLowerCase();\n    return word === inverted;\n}\n\nfunction checkAnagramTypeScript(word1: string, word2: string): boolean {\n    let ordered1: string = word1.toLowerCase().split('').sort().join('');\n    let ordered2: string = word2.toLowerCase().split('').sort().join('');\n    return ordered1 === ordered2;\n}\n\nfunction checkIsogramTypeScript(word: string): boolean {\n    let isogram = new Set<string>();\n    for (let char of word) {\n        if (isogram.has(char)) {\n            return false;\n        }\n        isogram.add(char);\n    }\n    return true;\n}\n\nfunction checkWordsTypeScript(word1: string, word2: string) {\n    return {\n        word1ItsPalindrome: checkPalindromeTypeScript(word1),\n        word2ItsPalindrome: checkPalindromeTypeScript(word2), \n        theyAreAnagram: checkAnagramTypeScript(word1, word2),\n        word1ItsIsogram: checkIsogramTypeScript(word1),\n        word2ItsIsogram: checkIsogramTypeScript(word2)\n    };\n}\n\nlet _word1: string = \"Roma\";\nlet _word2: string = \"Amor\";\n\nconsole.log(checkWordsTypeScript(_word1, _word2));"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/typescript/Sharah07.ts",
    "content": "// Operaciones con cadenas de caracteres\n\nlet myString:string = 'Hola ' + 'mundo'; //Concatenar.\nlet saludo=`Sharah: ${myString}!`; // Interpolación.\n\nconsole.log(saludo.length); //Longitud (número de caracteres incluyendo espacios, símbolos, etc.).\n\nconsole.log(saludo.toUpperCase); //Conversión a mayúsculas.\nconsole.log(saludo.toLowerCase); //Conversión a minúsculas.\n\nconsole.log(saludo.charAt(2)); //Acceder a caracteres específicos.\nconsole.log(saludo[1]); //Acceder con [].\n\n//subcadenas\nconsole.log(saludo.slice(8, 11)); // Extraer partes de una cadena con slice(start, end)/ desde 'start' hasta el caracter antes de 'end'.\nconsole.log(saludo.slice(-6,-1)); //slice con negativos\nconsole.log(saludo.substring(0,6)); //Extraer con substring(start, end): similar a slice, pero este no permite índices negativos.\n\nconsole.log(saludo.indexOf('mundo')); //Obetener la primera posición de una subcadena. \nconsole.log(saludo.lastIndexOf('a')); // Obtiene la última posición de una subcadena.\n\n//verificación.\nconsole.log(saludo.includes('Hola')); // Validar si la subcadena existe.\nconsole.log(saludo.startsWith('Sharah')); // Validar si la cadena empieza con la subcadena.\nconsole.log(saludo.endsWith('mundo.')); // Validar si la cadena termina con la subcadena.\n\nconsole.log(saludo.replace('Hola mundo', 'Hello World')); // Reemplazar la primera cadena que coincida.\nsaludo = 'Hola mundo desde javascript. Es divertido aprender javascript.'\nsaludo = saludo.replaceAll('javascript', 'typescript'); //Reemplazar todas las apariciones en la cadena de la primera subcadena dada con la segunda.\n\n//División de cadenas: se divide una cadena según el separador establecido (' ' | ',' | '.') convirtiendola en un array.\nconsole.log(saludo.split(' ')); // ['Hola', 'mundo', 'desde', 'typescript.', 'Es', 'divertido', 'aprender', 'typescript.']\n\n//Unión de cadenas: permite unir un array de cadenas en una sola.\nlet holaMundo = ['Hola', 'mundo', 'desde', 'typescript'];\nconsole.log(holaMundo.join(' '));\n\nlet numeros = ['10', '20', '30', '40'];\nconsole.log(numeros.join('-'));\n\nnumeros.reverse();\nconsole.log(numeros); //reverse\n\nsaludo = 'Hola mundo!';\nconsole.log(saludo.repeat(3)); //repetición\n\n// Recorrido\nlet palabra = 'palabra'; \n\nfor(let i=0; i<palabra.length; i++){\n    console.log(`Índice: ${i}, letra: ${palabra[i]}`);\n}\n\nfor(let letra of palabra){\n    console.log(letra);\n}\n\n\nlet eliminarEspacios = '   eliminar espacios en una cadena      ';\nconsole.log(eliminarEspacios.trim()); //Eliminar espacios al inicio y final\nconsole.log(eliminarEspacios.trimStart()); //Eliminar espacios al inicio\nconsole.log(eliminarEspacios.trimEnd()); //Eliminar espacios al final\n\n\nlet numeros2 = '1234.4566';\nconsole.log(parseInt(numeros2)); //Convertir en número entero. \nconsole.log(parseFloat(numeros2)); //Convertir en número decimal.\nconsole.log(Number(numeros2)); // Convertir en su tipo numérico correspondiente.\n\n//Extra \nconst readline = require(\"readline\");\n    \nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nfunction compararPalabras(){\n    rl.question('Ingrese la primera palabra: ', (laPalabra1)=>{\n        rl.question('Ingrese la segunda palabra: ',(laPalabra2)=>{\n            let palabra1 = laPalabra1.toLowerCase().normalize(\"NFD\").replace(/[\\u0300-\\u036f]/g, \"\");\n            let palabra2 = laPalabra2.toLowerCase().normalize(\"NFD\").replace(/[\\u0300-\\u036f]/g, \"\");\n            \n            //palíndromos\n            if(palabra1 == palabra1.split('').reverse().join('')){\n                console.log(`\"${laPalabra1}\" es un palíndromo.`);\n            }else{console.log(`\"${laPalabra1}\" no es un palíndromo.`);}\n\n            if(palabra2 == palabra2.split('').reverse().join('')){\n                console.log(`\"${laPalabra2}\" es un palíndromo.`);\n            }else{console.log(`\"${laPalabra2}\" no es un palíndromo.`);}\n\n            //Anagramas\n            let newPalabra1 = palabra1.split('').sort().join('');\n            let newPalabra2 = palabra2.split('').sort().join('');\n            \n            if(newPalabra1 == newPalabra2){\n                console.log(`\"${laPalabra1}\" es anagrama de \"${laPalabra2}\"`);\n            }else{console.log(`\"${laPalabra1}\" no es anagrama de \"${laPalabra2}\"`);}\n\n            //Isogramas\n            let setPalabra1 = new Set(palabra1.split(''));\n            let arrayPalabra1 = [... setPalabra1];\n\n            if(arrayPalabra1.join('').length == palabra1.length){\n                console.log(`\"${laPalabra1}\" es isograma.`);\n            }else{console.log(`\"${laPalabra1}\" no es isograma.`)}\n\n            let setPalabra2 = new Set(palabra2.split(''));\n            let arrayPalabra2 = [... setPalabra2];\n            \n            if(arrayPalabra2.join('').length == palabra2.length){\n                console.log(`\"${laPalabra2}\" es isograma.`);\n            }else{console.log(`\"${laPalabra2}\" no es isograma.`);}\n\n            rl.close();\n        });\n    });\n}\ncompararPalabras();"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/typescript/david-git-dev.ts",
    "content": "//EJERCICIO\nlet cadena = 'soy una cadena'\n// Constructor\n// String() constructor\nconst construct:{} = new String()//The String() constructor creates String objects.\nconst constructFunction:string = String()//When called as a function, it returns primitive values of type String.\n// Static methods\n// String.fromCharCode()\nString.fromCharCode(104, 111, 108, 97)// returns a string created from the specified sequence of UTF-16 code units. --> this example return hola\n// String.fromCodePoint()\nString.fromCodePoint(104, 111, 108, 97)//returns a string created from the specified sequence of code points. --> the main diferences is that use unicode points and dont return  'suplement chars' like fromCharCode and required use surrogate pair to return a suplement chars\n// String.raw()\nconst filePath = String.raw`C:\\Development\\profile\\aboutme.html`;\nconsole.log(`The file was uploaded from: ${filePath}`);\n// Expected output: \"The file was uploaded from: C:\\Development\\profile\\aboutme.html\"\n// Instance methods\n// String.prototype.at()\ncadena.at(-1)//The at() method of String values takes an integer value and returns a new String consisting of the single UTF-16 code unit located at the specified offset.  this ex return --> a to 'soy una cadena'\n// String.prototype.charAt()\ncadena.charAt(3)//return character of specific index --> '' white space after 'soy'\n// String.prototype.charCodeAt()\ncadena.charCodeAt(3)//return unicode of specific location --> 32\n// String.prototype.codePointAt()\ncadena.codePointAt(3)//return unicode code point of location index --> 32\n// String.prototype.concat()\ncadena.concat(' yo tambien') //return string concatenate the first and second string --> return 'soy una cadena yo tambien'\n// String.prototype.endsWith()\ncadena.endsWith(cadena) // return boolean if string ends with a sequence of string also specific index end point endsWith(string,endIndex)\n// String.prototype.includes()\ncadena.includes('soy') // return boolean and case-sensitive: search to determine whether a given string may be found within this string\n// String.prototype.indexOf()\ncadena.indexOf('ca')//Returns the position of the first occurrence of a substring.\n// String.prototype.isWellFormed()\ncadena.isWellFormed()// returns a boolean indicating whether this string contains any lone surrogates. -->true\n// String.prototype.lastIndexOf()\ncadena.lastIndexOf('a')//Returns the last occurrence of a substring in the string. --> 13\n// String.prototype.localeCompare()\ncadena.localeCompare('SOY UNA CADENA')//Returns an integer indicating whether the referenceStr comes before, after or is equivalent to the compareString. --> -1\n// String.prototype.match()\ncadena.match(/[a-z]/g)//The match() method of String values retrieves the result of matching this string against a regular expression. --> return the same 'soy una cadena' but in array separate by chars\n// String.prototype.matchAll()\ncadena.matchAll(/[a-z]/g)//The matchAll() method of String values returns an iterator of all results matching this string against a regular expression, including capturing groups.\n// String.prototype.normalize()\ncadena.normalize()//Returns the String value result of normalizing the string into the normalization form named by form as specified in Unicode Standard Annex #15, Unicode Normalization Forms.\n// String.prototype.padEnd()\ncadena.padEnd(20,'-')//The padEnd() method of String values pads this string with a given string (repeated, if needed) so that the resulting string reaches a given length. The padding is applied from the end of this string. --> return 'soy una cadena------' but THE LENGTH OF THE RESULTING STRING ONCE THE CURRENT STRING HAS BEEN PADDED. IF THIS PARAMETER IS SMALLER THAN THE CURRENT STRING'S LENGTH, THE CURRENT STRING WILL BE RETURNED AS IT IS.\n// String.prototype.padStart()\ncadena.padStart(20,'+')//Pads the current string with a given string (possibly repeated) so that the resulting string reaches a given length. The padding is applied from the start (left) of the current string.\n// String.prototype.repeat()\ncadena.repeat(3)// Returns a String value that is made from count copies appended together. If count is 0, the empty string is returned. -->'soy una cadenasoy una cadenasoy una cadena'\n// String.prototype.replace()\ncadena.replace('a','@')//Replaces text in a string, using a regular expression or search string.--> 'no soy un@ cadena'\n// String.prototype.replaceAll()\ncadena.replaceAll('a','@')//Replace all instances of a substring in a string, using a regular expression or search string. --> 'no soy un@ c@den@'\n// String.prototype.search()\ncadena.search('una')//Finds the first substring match in a regular expression search. -->return 4\n// String.prototype.slice()\ncadena.slice(0,5)//Returns a section of a string. return --> 'soy u'\n// String.prototype.split()\ncadena.split('')//Split a string into substrings using the specified separator and return them as an array. return -->[ 's', 'o', 'y', ' ', 'u', 'n', 'a', ' ', 'c', 'a', 'd', 'e', 'n', 'a' ]\n\n// String.prototype.startsWith()\ncadena.startsWith('a')//Returns true if the sequence of elements of searchString converted to a String is the same as the corresponding elements of this object (converted to a String) starting at position. Otherwise returns false. return --> 'false'\n// String.prototype.substring()\ncadena.substring(5,10)//Returns the substring at the specified location within a String object. return -->'na ca'\n// String.prototype[Symbol.iterator]()\nconst iterator = cadena[Symbol.iterator]();\nlet theChar = iterator.next();\n/*\nThe [Symbol.iterator]() method of String values implements the iterable protocol and allows strings to be consumed by most syntaxes expecting iterables, such as the spread syntax and for...of loops. It returns a string iterator object that yields the Unicode code points of the string value as individual strings.\n*/\nwhile (!theChar.done && theChar.value !== ' ') {\n  console.log(theChar.value);\n  theChar = iterator.next();\n  // Expected output: \"s\"\n  //                  \"o\"\n  //                  \"y\"\n}\n// String.prototype.toLocaleLowerCase()\ncadena.toLocaleLowerCase()//Converts all alphabetic characters to lowercase, taking into account the host environment's current locale. return --> 'soy una cadena'\n// String.prototype.toLocaleUpperCase()\ncadena.toLocaleUpperCase()//Returns a string where all alphabetic characters have been converted to uppercase, taking into account the host environment's current locale.return --> 'SOY UNA CADENA'\n// String.prototype.toLowerCase()\ncadena.toLowerCase()//Converts all the alphabetic characters in a string to lowercase. return --> 'soy una cadena'\n// String.prototype.toString()\ncadena.toString()//Returns a string representation of a string.\n// String.prototype.toUpperCase() return --> 'soy una cadena'\ncadena.toUpperCase()//Converts all the alphabetic characters in a string to uppercase. return --> 'SOY UNA CADENA'\n// String.prototype.toWellFormed()\ncadena.toWellFormed()//Returns a string where all lone or out-of-order surrogates have been replaced by the Unicode replacement character (U+FFFD). return -->'SOY UNA CADENA'\n// String.prototype.trim()\n\"  SOY UNA CADENA  \".trim()//Removes the leading and trailing white space and line terminator characters from a string. return --> \"SOY UNA CADENA\"\n// String.prototype.trimEnd()\n\"  SOY UNA CADENA  \".trimEnd()//Removes the trailing white space and line terminator characters from a string. return -->\"SOY UNA CADENA  \"\n// String.prototype.trimStart()\n\"  SOY UNA CADENA  \".trimStart()//Removes the leading white space and line terminator characters from a string. return --> \"  SOY UNA CADENA\"\n// String.prototype.valueOf()\ncadena.valueOf()//Returns the primitive value of the specified object.\nconst str = new String('soy una cadena');\nconsole.log(str);\n// Expected output: String { \"soy una cadena\" }\nconsole.log(str.valueOf());\n// Expected output: \"soy una cadena\"\n//DIFICULTAD EXTRA\n//DIFICULTAD EXTRA\nconsole.log('Hola, soy un programa para analizar tus textos!..dime:¿que quieres hacer hoy?')\nconsole.log(`\n  1.-Palindromos\n  2.-Anagramas\n  3.-Isogramas\n  *-Salir de la aplicacion\n  `)\n  let option :string | null\n  do{\noption = prompt(`Que quieres hacer?\n    1.-Palindromos\n  2.-Anagramas\n  3.-Isogramas\n  *-Salir de la aplicacion escribe cualquier cosa diferente a los numero de las opciones...\n    `);\n\nlet word;\nlet response;\nswitch (option) {\n  case '1':\n    do{\n word = prompt('Dime la palabra?...')\n    }while(!word)\n     response = palindromeChecker(word)? (`${word} es un palindromo!`) : (`Ohh...lo siento ${word} no es un palindromo`);\n    alert(response)\n    break;\n  case '2':\n    let firstWord\n let secondWord\n    do{\n  firstWord = prompt('Dime la primera palabra?...')\n  secondWord = prompt('Dime la segunda palabra?...')\n    }while(!firstWord && !secondWord)\n     response = anagramChecker(firstWord!,secondWord!)? (`${firstWord} es un anagrama de ${secondWord}!`) : (`Ohh...lo siento ${firstWord} no es un anagrama de ${secondWord}`);\n    alert(response)\n    break;\n  case '3':\n\n    do{\n        word = prompt('Dime la palabra?...')\n    }while(!word)\n    response = isogramChecker(word) ?  (`${word} es un isograma!`) : (`Ohh...lo siento ${word} no es un isograma`)\n    alert(response)\n    break;\n  default:\n    option ? alert('Saliendo del programa....'):'';\n    break;\n}\n}while(['1','2','3'].some(select=> select===option) || !option)\n\n  function palindromeChecker(word:string):boolean{\n    const isPalindrome = word.split(\"\").every((letter, position, word) => {\n      return letter == word[word.length - position - 1]; //check if the character Position is the same that Inverse character Position in every letter if every letter is equal then is Palindrome\n    });\n    return isPalindrome\n  }\n  function isogramChecker(word:string):boolean{\n    const letterCounts = word\n    .split(\"\")\n    .reduce((letterMap: { [key: string]: number }, position) => {\n      if (!letterMap[position]) {\n        letterMap[position] = 1;\n      } else {\n        letterMap[position] += 1;\n      }\n      return letterMap;//this create a map that contain letter and many times appear in the word: {a:1 , b:2 ,c:3}\n    }, {});\n\n  const isIsogram = Object.values(letterCounts).every(\n    (count) => count === letterCounts[word[0]] //if de first count value is the same that every count then is Isogram by definition\n  );\n  return isIsogram;\n  }\n  function anagramChecker(wordOne: string, wordTwo: string): boolean {\n    return (\n      wordOne.split(\"\").toSorted().join(\"\") == wordTwo.split(\"\").toSorted().join(\"\") // sort alpabhetical letters in every word and compare IF the word one order is the same that the word two order then is Anagram by definition\n    );\n  }"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/typescript/duendeintemporal.ts",
    "content": "//#04 { retosparaprogramadores } CADENAS DE CARACTERES\n/* I use *Professional JavaScript for Web Developers* by Matt Frisbie as a \nreference to generate accurate comment descriptions and to understand JavaScript's capabilities in string manipulation. I also use GPT and Deepseek to correct some translations, syntax, and grammar.\n*/\n\n//short for console.log\nlet log = console.log;\n\n//STRING TYPE\n//The String type is the object representation of strings and is created using the String constructor as follows:\nlet stringObject = new String(\"hello girl\"); // it will throw an ts(2322) error if we attend to set string type to stringObject so it is preferible to avoid using new String() in TypeScript. Use primitive strings (let str: string = \"hello\") instead. The primitive string type automatically gives access to all string methods.\nlog(stringObject) // [String: 'hello girl']\n\n//The methods of a String object are available for all string primitives.\n\n/*Every time a primitive value is read, an object of the corresponding primitive wrapper type is created behind the scenes, allowing access to various methods for manipulating the data. */ \n\nlet q: string = 'Did you know Internet start as a Pentagon project named ARPANET(Advanced Research Projects Agency Network)?'\nlet q2: string = q.substring(12); // Extracts the substring starting from index 12\nlog(q2); // Internet start as a Pentagon project named ARPANET(Advanced Research Projects Agency Network)?\n\n//The JavaScript Character\n//JavaScript strings consist of 16-bit code units. For most characters, each 16-bit code unit corresponds to a single character. The length property indicates how many 16-bit code units are present in the string\nlet message: string = \"Sometimes you make me smile...\";\nlog(message.length); // 30\nlog(message.charAt(10)); // y\nlog(message.charCodeAt(10)); // 121 (charCodeAt returns the UTF-16 code unit for the character at the given index)\nlog(message.indexOf('m')); // 2\nlog(message.lastIndexOf('m')); // 23\nlet chart: number = message.lastIndexOf('s');\nlet chart2: number = message.indexOf('.');\nlog(message.substring(chart, chart2)); // smile\nlog(message.substring(-8)); // Sometimes you make me smile..\nlog(message.substr(-8)); // smile... (I believe this method may be deprecated)\n\nlog(message.substring(message.length - 8))// smile...\nlet arr: any = message.substring(0, 8).split('');\nlog(arr)// Array(8) [ \"S\", \"o\", \"m\", \"e\", \"t\", \"i\", \"m\", \"e\" ]  ( no inclusive the last index )\nlog(arr.join('-')); // S-o-m-e-t-i-m-e    \nlog(arr[arr.length - 1].replace('e', 'e-s')); // e-s\nlog(arr.join('-').replaceAll('-', '') + 's'); // Sometimes \n\n//Note: It is important to know that some emojis are composed of two 16-bit code units, so you have to take this into consideration when evaluating or using the length property.\n\nlet fragment = '   at this point in my life...  ';\nlog(fragment.trim()); // Logs: at this point in my life... (without spaces at the begining or at the end)\n\n//Note: you can also use trimStart() or trimEnd()\n\nlet userName: string = 'anna';\nlog(userName.toUpperCase()); // ANNA\nlet othername: string = 'Luna';\nlog(othername.toLowerCase()); // luna\n\n//we can also use String.fromCharCode() method\n\nlog(String.fromCharCode(193, 48, 587, 482, 102, 107)); // Á0ɋǢfk\nlog(String.fromCharCode(0x68fa)); // 棺\n\n//Note: using fromCharCode() may have performance implications, especially if called frequently or with a large number of characters. \n \n/* The normalize() Method. Some Unicode characters can be encoded in more than one way. Sometimes, a character can be represented by either a single BMP character or a surrogate pair. For example, consider the following: */\n\n// U+00C5: Latin capital letter A with ring above\nlog(String.fromCharCode(0x00C5)); // Å\n// U+212B: Angstrom sign\nlog(String.fromCharCode(0x212B)); // Å\n// U+0041: Latin captal letter A\n// U+030A: Combining ring above\nlog(String.fromCharCode(0x0041, 0x030A)); // Å\n\nlet unnormalized_text = String.fromCharCode(0x0041, 0x030A, 0x212B, 0x00C5);\nlog(unnormalized_text.charCodeAt(1), unnormalized_text.charCodeAt(3)); // 778 197\nlet normalized_text: string = unnormalized_text.normalize();\nlog(normalized_text.charCodeAt(1), normalized_text.charCodeAt(3)); // 197 NaN  (Because the first character is converted from a surrogate pair to a single BMP character, there is no character at charCodeAt(3). After normalization, there are only three characters, all with the same code: 197.)\n\n//Unicode addresses this by providing four normalization forms that allow characters, such as this one, to be normalized into a consistent format, regardless of their character code derivation.\n\n//we can concatenate strings by using the concat() method or the + unary operator\nlet firstName: string = 'Patty';\nlet lastName: string = ' Smith';\nlet longName: string = firstName.concat(lastName);\nlog(longName)// Patty Smith\n//same as\nlog(firstName + lastName); // Patty Smith\n// a better way\nlog(`${firstName}${lastName}`); // Patty Smith\n\n//or make use of the previus methods to f.e capitalize a word\nfunction capitalize(str: string): string {\n    if (!str) return str;\n    return str.charAt(0).toUpperCase() + str.slice(1);\n}\n\nlog(capitalize(userName)); // Anna\n\n//There are two methods for locating substrings within another string: indexOf() and lastIndexOf(). Both methods search a string for a given substring and return the position (or –1 if the substring isn’t found).\n\nlet fragment2: string = 'the fire is burned, the tables are turned...';\nlog(fragment2.indexOf('is')); // 9 \nlog(fragment2.indexOf('house')); // -1\nlog(fragment2.lastIndexOf('t')); // 35\n\n//String Inclusion Methods\nlog(fragment2.startsWith(\"the\")); // true\nlog(fragment2.endsWith(\"fire\")); // false\n\nlet say: string = 'oh';\nlog(say.repeat(2) + '!'); // ohoh!\n\n//I think padStart() and padEnd() are deprecated, but we can create our own function to achieve the same result. For example, let's try to emulate the padStart() method.\n\nfunction  addPad(str: any, width: number, pad: any = 0): string {\n    let result = String(str); \n    while (result.length < width) {\n         result = `${pad}` + result;\n    }\n     return result;\n }\n \n \n log(addPad(4, 3, '#')); // ##4\n log(addPad(56, 3, '$')); // $56\n log(addPad(7, 3)); // 007\n log(addPad('something', 3, '-')); // something  (cause something length is bigger than 3)\n\n const greeting: string = \"tururuuu\";\n const paddedString: string = addPad.call(greeting, greeting, 11, \"&\");\n log(paddedString); //  &&&tururuuu\n\n//we can use match() and RegExp() (or regular expression patterns) to evaluate regular expressions in a string, f.e.\n\nfunction toCamelCase(input: string): string {\n    return (\n        input // Replace kebab-case, snake_case, and spaces with a space\n            .replace(/[-_\\s]+(.)?/g, (_, char) => (char ? char.toUpperCase() : ''))\n            .replace(/^[A-Z]/, (char) => char.toLowerCase()) // Handle PascalCase\n    );\n}\n\nlog(toCamelCase('PascalCase')); // pascalCase\nlog(toCamelCase('kebab-case-string')); // kebabCaseString\nlog(toCamelCase('snake_case_string')); // snakeCaseString\nlog(toCamelCase('string with spaces')); // stringWithSpaces\n\n\n    log( 'Retosparaprogramadores #4'); // Retosparaprogramadores #4 \n\n\n\n/*ADDITIONAL DIFFICULTY (optional):\nCreate a program that analyzes two different words and performs checks\nto determine if they are:  Palindromes   Anagrams   Isograms */\n\n\n//Palindrome: A palindrome is a word, phrase, number, or other sequence of characters that reads the same forward and backward.\n\nconst isPolidrome = (w1: string, w2: string): boolean => {\n    if (w1.length !== w2.length) return false;\n    return w1 === w2.split('').reverse().join('');\n};\n\nlog('is isPolidrome: ', isPolidrome('roma', 'amor'))//Logs: true\n\n//Anagram: An anagram is a word or phrase formed by rearranging the letters of another word or phrase, using all the original letters exactly once. \n\nconst isAnagram = (w1: string, w2: string): boolean => {\n    if (w1.length !== w2.length) return false;\n    return w1.split('').sort().join('') === w2.split('').sort().join('');\n};\n\nlog('is anagram: ', isAnagram('nick','kinc')); //Logs: true\n\n//Isogram: An isogram is a word or phrase in which no letter occurs more than once. For example, \"lumberjack\" and \"background\" are isograms because none of the letters are repeated.\n\nconst isIsogram = (str: string): boolean => {\n    const charSet = new Set(str);\n    return charSet.size === str.length;\n};\n\nlog('is isogram: ', isIsogram('background')); //Logs: true\n\n//the function check when two strings are polidromes, anagrams or isograms\nconst checkState = (str1: string, str2: string): void => {\n    const isPoli = isPolidrome(str1, str2);\n    const isAna = isAnagram(str1, str2);\n    const isIso1 = isIsogram(str1);\n    const isIso2 = isIsogram(str2);\n\n    let result = '';\n    if (isPoli && isAna && isIso1 && isIso2) {\n        result = `The words: \"${str1}\" and \"${str2}\" are palindromes, anagrams, and isograms.`;\n    } else if (isPoli) {\n        result = `The words: \"${str1}\" and \"${str2}\" are palindromes.`;\n    } else if (isAna && isIso1 && isIso2) {\n        result = `The words: \"${str1}\" and \"${str2}\" are anagrams and isograms.`;\n    } else if (isAna) {\n        result = `The words: \"${str1}\" and \"${str2}\" are anagrams.`;\n    } else if (isIso1 && isIso2) {\n        result = `The words: \"${str1}\" and \"${str2}\" are isograms.`;\n    } else if (isIso1) {\n        result = `The first word: \"${str1}\" is an isogram.`;\n    } else if (isIso2) {\n        result = `The second word: \"${str2}\" is an isogram.`;\n    } else {\n        result = `The words: \"${str1}\" and \"${str2}\" are not palindromes, anagrams, or isograms.`;\n    }\n\n    log(result);\n};\n\ncheckState('amor','mora'); /* Logs: The words: \"amor\" and \"mora\" are anagrams and also isograms */\ncheckState('amor','roma'); /* logs: The words: \"amor\" and \"roma\" are polidromes, anagrams and also isograms.*/\ncheckState('zeitgest','kaguabumga'); /* Logs: The words: \"zeitgest\" and \"kaguabumga\" aren't polidromes, anagrams or isograms.*/\ncheckState('pizza', 'background'); /* Logs: The second word: \"background\" is an isogram  */\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/typescript/eulogioep.ts",
    "content": "// Operaciones con cadenas en TypeScript\n\n// Declaración de una cadena\nconst texto: string = \"Hola, mundo!\";\n\nconsole.log(\"Texto original:\", texto);\n\n// 1. Acceso a caracteres específicos\nconsole.log(\"1. Primer carácter:\", texto[0]);\n\n// 2. Subcadenas\nconsole.log(\"2. Subcadena:\", texto.substring(0, 4));\n\n// 3. Longitud\nconsole.log(\"3. Longitud:\", texto.length);\n\n// 4. Concatenación\nconst otraCadena: string = \" Bienvenidos\";\nconsole.log(\"4. Concatenación:\", texto.concat(otraCadena));\n\n// 5. Repetición\nconsole.log(\"5. Repetición:\", texto.repeat(3));\n\n// 6. Recorrido\nconsole.log(\"6. Recorrido:\");\nfor (let char of texto) {\n    console.log(char);\n}\n\n// 7. Conversión a mayúsculas y minúsculas\nconsole.log(\"7. Mayúsculas:\", texto.toUpperCase());\nconsole.log(\"   Minúsculas:\", texto.toLowerCase());\n\n// 8. Reemplazo\nconsole.log(\"8. Reemplazo:\", texto.replace(\"mundo\", \"TypeScript\"));\n\n// 9. División\nconsole.log(\"9. División:\", texto.split(\", \"));\n\n// 10. Unión\nconst arrayPalabras: string[] = [\"TypeScript\", \"es\", \"genial\"];\nconsole.log(\"10. Unión:\", arrayPalabras.join(\" \"));\n\n// 11. Interpolación (template literals en TypeScript)\nconst nombre: string = \"Alice\";\nconst edad: number = 30;\nconsole.log(`11. Interpolación: Me llamo ${nombre} y tengo ${edad} años.`);\n\n// 12. Verificación\nconsole.log(\"12. Empieza con 'Hola':\", texto.startsWith(\"Hola\"));\nconsole.log(\"    Termina con '!':\", texto.endsWith(\"!\"));\nconsole.log(\"    Contiene 'mundo':\", texto.includes(\"mundo\"));\n\n// 13. Recorte de espacios\nconst textoConEspacios: string = \"  Hola Mundo  \";\nconsole.log(\"13. Recorte de espacios:\", textoConEspacios.trim());\n\n// 14. Extracción de subcadenas\nconsole.log(\"14. Extracción (slice):\", texto.slice(0, 4));\n\n// 15. Búsqueda de índice\nconsole.log(\"15. Índice de 'mundo':\", texto.indexOf(\"mundo\"));\n\n// DIFICULTAD EXTRA\nconsole.log(\"\\nDIFICULTAD EXTRA:\");\n\nconst palabra1: string = \"amor\";\nconst palabra2: string = \"roma\";\n\nconsole.log(\"Palabra 1:\", palabra1);\nconsole.log(\"Palabra 2:\", palabra2);\n\n// Función para verificar si una palabra es un palíndromo\nfunction esPalindromo(palabra: string): boolean {\n    return palabra === palabra.split('').reverse().join('');\n}\n\n// Función para verificar si dos palabras son anagramas\nfunction sonAnagramas(palabra1: string, palabra2: string): boolean {\n    return palabra1.toLowerCase().split('').sort().join('') === \n           palabra2.toLowerCase().split('').sort().join('');\n}\n\n// Función para verificar si una palabra es un isograma\nfunction esIsograma(palabra: string): boolean {\n    return new Set(palabra.toLowerCase()).size === palabra.length;\n}\n\nconsole.log(\"¿Son palíndromos?\", \n    esPalindromo(palabra1), esPalindromo(palabra2));\nconsole.log(\"¿Son anagramas?\", sonAnagramas(palabra1, palabra2));\nconsole.log(\"¿Son isogramas?\", esIsograma(palabra1), esIsograma(palabra2));"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/typescript/hozlucas28.ts",
    "content": "/*\n    String operations...\n*/\n\n// Get length of a string\nconst strLength = 'Hello World!'.length\nconsole.log('Get length of a string: const <VARIABLE NAME> = <STRING NAME>.length')\nconsole.log(`'Hello World!'.length --> ${strLength}`)\n\n// Get char of a string\nconst char = 'Hello World!'[1]\nconsole.log('\\nGet char of a string: const <VARIABLE NAME> = <STRING NAME>[<INDEX OF THE CHAR>]')\nconsole.log(`'Hello World!'[1] --> '${char}'`)\n\n// Get substring of a string\nconst substring = 'Hello World!'.substring(2, 9)\nconsole.log('\\nGet substring of a string: const <VARIABLE NAME> = <STRING NAME>.substring(<START - 1>, <END>)')\nconsole.log(`'Hello World!'.substring(2, 9) --> '${substring}'`)\n\n// String to uppercase\nconst uppercaseStr = 'Buenos Aires'.toUpperCase()\nconsole.log('\\nString to uppercase: const <VARIABLE NAME> = <STRING NAME>.toUpperCase()')\nconsole.log(`\"Buenos Aires\".toUpperCase() --> '${uppercaseStr}'`)\n\n// String to lowercase\nconst lowercaseStr = 'USA'.toLowerCase()\nconsole.log('\\nString to lowercase: const <VARIABLE NAME> = <STRING NAME>.toLowerCase()')\nconsole.log(`\"USA\".toLowerCase() --> '${lowercaseStr}'`)\n\n// Repeat a string\nconst repeatedStr = 'Juana'.repeat(2)\nconsole.log('\\nRepeat a string: const <VARIABLE NAME> = <STRING NAME>.repeat(<NUMBER OF REPEATS>)')\nconsole.log(`\"Juana\".repeat(2) --> '${repeatedStr}'`)\n\n// Concat two strings (first option)\nconst concatedStrOpt01 = 'Lucas ' + 'Hoz'\nconsole.log(\n\t\"\\nConcat two strings (first option): const <VARIABLE NAME> = <FIRST STRING NAME> + <SECOND STRING NAME> + <'N' STRING NAME...>\"\n)\nconsole.log(`\"Lucas \" + \"Hoz\" --> '${concatedStrOpt01}'`)\n\n// Concat two strings (second option)\nconst concatedStrOpt02 = 'Lucas'.concat(' ', 'Hoz', ' - ', 'Argentina')\nconsole.log(\"\\nConcat two strings (second option): const <VARIABLE NAME> = <FIRST STRING NAME>.concat(<'N' STRING NAME...>)\")\nconsole.log(`'Lucas'.concat(' ', 'Hoz', ' - ', 'Argentina') --> '${concatedStrOpt02}'`)\n\n// Replace substring of a string\nconst replacedStr = 'Hello Python!'.replace('Python', 'TypeScript')\nconsole.log(\n\t'\\nReplace substring of a string: const <VARIABLE NAME> = <STRING NAME>.replace(<SUBSTRING TO SEARCH>, <NEW SUBSTRING>)'\n)\nconsole.log(`'Hello Python!'.replace('Python', 'TypeScript') --> '${replacedStr}'`)\n\n// Compare start of a string\nconst compareStart = 'Lucas'.startsWith('ho')\nconsole.log('\\nCompare start of a string: <STRING NAME>.startsWith(<SUBSTRING TO FIND>)')\nconsole.log(`'Lucas'.startsWith('ho') --> ${compareStart}`)\n\n// Compare end of a string\nconst compareEnd = 'Lucas'.endsWith('as')\nconsole.log('\\nCompare end of a string: <STRING NAME>.endsWith(<SUBSTRING TO FIND>)')\nconsole.log(`'Lucas'.endsWith('as') --> ${compareEnd}`)\n\n// Check if a string includes a substring\nconst includes = 'Lucas'.includes('c')\nconsole.log('\\nCheck if a string includes a substring: <STRING NAME>.includes(<SUBSTRING TO FIND>)')\nconsole.log(`'Lucas'.includes('c') --> ${includes}`)\n\n// Check if a string matches a regex\nconst regexStr = 'Lucas'.match(/[uca]/g)\nconsole.log('\\nCheck if a string matches a regex: <STRING NAME>.match(<REGEX>)')\nconsole.log(`'Lucas'.match(/[uca]/g) --> [${regexStr}]`)\n\n// Check if a string is equal to another string\n// @ts-expect-error\nconst commonComparison = 'Lucas' === 'LuCaS'\nconsole.log('\\nCheck if a string is equal to another string: <FIRST STRING NAME> === <SECOND STRING NAME>')\nconsole.log(`'Lucas' === 'LuCaS' --> ${commonComparison}`)\n\nconsole.log('\\n# ---------------------------------------------------------------------------------- #')\n\n/*\n    Additional challenge...\n*/\n\nfunction getPalindromeWords(words: string[]): string[] {\n\tconst palindromes: string[] = []\n\n\tfor (const word of words) {\n\t\tconst reversedWord = [...word].toReversed().join('')\n\t\tif (word === reversedWord) palindromes.push(word)\n\t}\n\n\treturn palindromes\n}\n\nfunction getAnagramWords(pairOfWords: string[][]): string[][] {\n\tconst anagrams: string[][] = []\n\n\tfor (const words of pairOfWords) {\n\t\tconst [word01, word02] = words\n\t\tconst longestWord = word01.length > word02.length ? word01 : word02\n\n\t\tlet areAnagrams = true\n\t\tconst uniqueChars = new Set([...longestWord])\n\n\t\tfor (const char of longestWord) {\n\t\t\tif (uniqueChars.has(char)) continue\n\t\t\tareAnagrams = false\n\t\t\tbreak\n\t\t}\n\n\t\tif (areAnagrams) anagrams.push(words)\n\t}\n\n\treturn anagrams\n}\n\nfunction getIsogramWords(words: string[]): string[] {\n\tconst isograms: string[] = []\n\n\tfor (const word of words) {\n\t\tconst wordFmt = word.replace(' ', '')\n\t\tconst uniqueChars = new Set([...wordFmt])\n\t\tif (uniqueChars.size === wordFmt.length) isograms.push(word)\n\t}\n\n\treturn isograms\n}\n\nconst arr01 = ['level', 'hello', 'racecar', 'world', 'madam', 'programming', 'deed', 'javascript']\nconst palindromeWords = getPalindromeWords(arr01)\nconsole.log(`\\nPalindrome words of [${arr01}] --> [${palindromeWords}]`)\n\nconst arr02 = [\n\t['listen', 'silent'],\n\t['hello', 'world'],\n\t['good', 'dog'],\n]\nconst anagramWords = getAnagramWords(arr02)\nconsole.log(`\\nAnagram words of [${arr02}] --> [${anagramWords}]`)\n\nconst arr03 = ['hello', 'world', 'isogram', 'javascript', 'python', 'algorithm']\nconst isogramWords = getIsogramWords(arr03)\nconsole.log(`\\nIsogram words of [${arr03}] --> [${isogramWords}]`)\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/typescript/ialmontedr0.ts",
    "content": "/**\r\n * Operaciones con cadenas de caracteres en TypeScript\r\n */\r\n\r\n// Creacion de cadena de caracteres\r\nlet cadena: string = \"Nueva cadena de caracteres\";\r\nconsole.log(cadena);\r\n\r\n// Templates literales\r\nlet numero: number = 12;\r\nlet cadenaConVariables: string = `El numero es: ${numero}`;\r\nconsole.log(cadenaConVariables);\r\n\r\n// Concatenacion\r\nlet stringConcatenado: string = \"Hola \" + \"Mundo!\";\r\nconsole.log(stringConcatenado);\r\n\r\n// Acceso a caracter especifico\r\n//Indice => Los indices en TypeScript comienzan desde 0\r\nlet accesoACaracter: string = stringConcatenado[1];\r\nconsole.log(accesoACaracter);\r\n\r\n// Propiedades y metodos de cadena\r\n// length => Devuelve la longitud de la cadena\r\nlet cadenaLongitud: number = cadena.length;\r\nconsole.log(cadenaLongitud);\r\n\r\n// toUppercase() => Convierte la cadena a mayúsculas\r\nlet cadenaAMayusculas: string = cadena.toUpperCase();\r\nconsole.log(cadenaAMayusculas);\r\n\r\n// toLowerCase() => Convierte la cadena a minúsculas\r\nlet cadenAMinusculas: string = cadena.toLowerCase();\r\nconsole.log(cadenAMinusculas);\r\n\r\n// indexOf() => Devuelve el índice de la primera aparición de una subcadena en la cadena\r\nlet indice: number = cadena.indexOf(\"cadena\");\r\nconsole.log(indice); // devuelve -1 si no lo encuentra, si lo enc\r\n\r\n// lastIndexOf() => Devuelve el índice de la última aparición de una subcadena en la cadena\r\nlet ultimoIndice: number = cadena.lastIndexOf(\"cadena\"); // devuelve -1 si no lo encuentra, si lo encuentra devuelve el último índice\r\nconsole.log(ultimoIndice);\r\n\r\n// slice() => Devuelve una subcadena de la cadena\r\nlet subcadena: string = cadena.slice(0, 5); // devuelve \"Nueva\"\r\nconsole.log(subcadena);\r\n\r\n// charAt() => Devuelve el carácter en la posición especificada\r\nlet caracterEnPosicion: string = cadena.charAt(5); // devuelve \"c\"\r\nconsole.log(caracterEnPosicion);\r\n\r\n/**\r\n * Programa con dificultad extra: Analisis de palabras\r\n */\r\n\r\nlet palindroma: string = \"radar\";\r\nlet anagrama: string = \"adram\";\r\nlet isograma: string = \"estrla\";\r\n\r\n// Verificando si una palabra es palindroma\r\nfunction esPalindroma(palabra: string): boolean {\r\n    let sinEspacios: string = palabra.replace(/\\s/g, \"\").toLowerCase(); // Convertimos a minusculas y quitamos los espacios\r\n    return sinEspacios === sinEspacios.split(\"\").reverse().join(\"\"); // Comparamos con la versión invertida, si son iguales devuelve true\r\n}\r\n\r\nfunction esAnagrama(palabra: string, otraPalabra: string): boolean {\r\n    let sinEspacios: string = palabra.replace(/\\s/g, \"\").toLowerCase(); // Convertimos a minusculas y quitamos los espacios\r\n    let otraSinEspacios: string = otraPalabra.replace(/\\s/g, \"\").toLowerCase(); // Convertimos a minusculas y quitamos los espacios\r\n    return sinEspacios.split(\"\").sort().join(\"\") === otraSinEspacios.split(\"\").sort().join(\"\"); // Comparamos los arrays ordenados, si son iguales devuelve true\r\n}\r\n\r\nfunction esIsograma(palabra: string): boolean {\r\n    let sinEspacios: string = palabra.replace(/\\s/g, \"\").toLowerCase(); // Convertimos a minusculas y quitamos los espacios\r\n    return new Set(sinEspacios).size === sinEspacios.length; // Comparamos el tamaño del Set con la longitud de la cadena, si son iguales devuelve true\r\n}\r\n\r\nconsole.log(`Palindroma: ${esPalindroma(palindroma)}`); // true\r\nconsole.log(`Anagrama: ${esAnagrama(anagrama, palindroma)}`); // false\r\nconsole.log(`Isograma: ${esIsograma(isograma)}`); // true (porque no contiene caracteres repetidos)"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/typescript/jesusEs1312.ts",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\nlet text: string = \"hola\";\nlet text2: string = \"mundo\";\nlet text3: string = \"Java,Typescript,Python,Javascript,C\";\nlet text4: string = \"    Hola    \";\nlet text5: string = \"Jesus|25|Peter|36|James|85\";\nconst numberRegexp = /^[A-Z a-zs]+$/;\n\n//--- Acceso especifico a un caracter de una cadena\nconsole.log(text[0]);\nconsole.log(text2[1]);\n\n//--- Concatenando 2 cadenas de texto (concat)\nconsole.log(text.concat(\" \").concat(text2));\n\n//--- Tomando 2 caracteres de una cadena de texto (substring o slice)\nconsole.log(text.substring(2, 4));\nconsole.log(text2.slice(3,6));\n\n//--- Dividiendo un cadena de texto (split), esto retorna un array de cadenas\nconsole.log(text3.split(\",\"));\n\n//--- Numero de caracteres que contiene un cadena (length)\nconsole.log(text.length);\n\n//--- Remplazando caracteres por otros en una cadena (replace)\nconsole.log(text3.replace(\",\", \"|\"));\n\n//--- Repitiendo la misma cadena (repeat)\nconsole.log(text.repeat(3));\n\n//--- Cadena en mayusculas (toUpperCase)\nconsole.log(text.toUpperCase());\n\n//--- Cadena en minusculas (toLowerCase)\nconsole.log(text.toLowerCase());\n\n//--- Buscar un caracter dentro de una cadena (search)\nconsole.log(text3.search(\"P\"));\n\n//--- Buscar una cadena dentro de una cadena de texto (includes)\nconsole.log(text3.includes(\"Python\"));\n\n//--- Quitar espacios en una cadena de texto (trim)\nconsole.log(text4.trim());\n\n//--- Quitar el primer espacio en blanco de una cadena (trimStart)\nconsole.log(text4.trimStart());\n\n//--- Quitar el ultimo espacio en blanco de una cadena (trimEnd)\nconsole.log(text4.trimEnd());\n\n//--- Crear un array mediante la coincidencia de una expresion regular dentro de una cadena de texto (match)\nconsole.log(text5.match(numberRegexp));\n\n//--- Ejercicio Extra\nfunction analizedString(text1: string, text2: string): void{\n    //--- Palindromos\n    let text1Reverse: string = text1.split(\"\").reverse().join(\"\").toLowerCase();\n    let text2Reverse: string = text2.split(\"\").reverse().join(\"\").toLowerCase();\n    let result: string = \"\";\n\n    result = text1 == text1Reverse\n        ? `La palabra ${text1} es Palindroma`\n        : `La palabra ${text1} NO es Palindroma`;\n    console.log(result);\n\n    result = text2 == text2Reverse\n        ? `La palabra ${text2} es Palindroma`\n        : `La palabra ${text2} NO es Palindroma`;\n    console.log(result);\n\n    //--- Anagramas\n    let text1Sorted = text1.split(\"\").sort((a, b) => a.localeCompare(b)).join(\"\");\n    let text2Sorted = text2.split(\"\").sort((a, b) => a.localeCompare(b)).join(\"\");\n\n    result = text1Sorted == text2Sorted\n        ? `Las palabras ${text1} y ${text2} son Anagramas`\n        : `Las palabras ${text1} y ${text2} NO son Anagramas`\n\n    //--- Isogramas\n    let textSet1: Set<string> = new Set<string>(text1);\n    let textSet2: Set<string> = new Set<string>(text2);\n    result = text1.length == textSet1.size\n        ? `La palabra ${text1} es Isograma`\n        : `La palabra ${text1} NO es Isograma`;\n    console.log(result);\n\n    result = text2.length == textSet2.size\n        ? `La palabra ${text2} es Isograma`\n        : `La palabra ${text2} NO es Isograma`;\n    console.log(result);\n}\n\nanalizedString(\"roma\", \"amor\");\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/typescript/juserdev.ts",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\nconst texto: string = \"hello typeScript\"\nconsole.log(texto[0]) //obtiene el caracter en la posicion indicada, en este caso en la posicion 0\nconsole.log(texto.charAt(6)) //hace lo mismo que el anterior\nconsole.log(texto.length) // obtiene la logitud del string\n\n//concatenaciones\n\nconst saludar: string = \"hola \"\nconst lenguaje: string = \"typescript\"\n\nconsole.log(saludar + lenguaje)\nconsole.log(saludar.concat(lenguaje))\n\n// repeticion\n\nconsole.log(texto.repeat(2)) //repite la cadena de texto n numero de veces\n\n// conversion a mayusculas y minusculas\n\nconsole.log(texto.toUpperCase())\nconsole.log(texto.toLowerCase())\n\nconsole.log(texto.replace(\"hello\" , \"hi\"))\nconsole.log(texto.replace(\"t\" , \"T\"))\n\n// division\nconst palabras: string[] = texto.split(\" \")\nconsole.log(palabras)\n\n//union\n\nconsole.log(palabras.join(\", \"))\n\n//interpolacion\nconsole.log(`Hola ${lenguaje}`)\n\n//verificacion\n\nconsole.log(texto.startsWith(\"hello\"))\nconsole.log(texto.endsWith(\"typeScript\"))\nconsole.log(texto.includes(\"type\"))\n\n//recorrido\n\nfor (const char of texto) {\n    console.log(char)\n}\n\n//Extra\n\ninterface returnFunction { //esto es el retorno de la funcion\n    anagrama: string,\n    isograma: string,\n    palindromo: string\n}\n\nconst comprobaciones = (a: string, b: string): returnFunction =>{\n    let ar = a.split(\"\").reverse().join(\"\")\n    let br = b.split(\"\").reverse().join(\"\")\n    \n    let aa = a.split(\"\").sort().join(\"\")\n    let ba = b.split(\"\").sort().join(\"\")\n    \n    let ai = a.split(\"\").sort().join(\"\")\n    let aiSet = [...new Set(ai)].join(\"\")\n    let bi = b.split(\"\").sort().join(\"\")\n    let biSet = [...new Set(bi)].join(\"\")\n\n    let isograma: string\n    \n    if (ai === aiSet && bi === biSet) {\n        isograma = `Tanto \"${a}\" como \"${b}\" son isogramas`\n    } else if (ai === aiSet && bi !== biSet) {\n        isograma = `\"${a}\" es un isograma y \"${b}\" no lo es`\n    } else if (ai !== aiSet && bi === biSet) {\n        isograma = `\"${b}\" es un isograma y \"${a}\" no lo es`\n    } else {\n        isograma = `Ni \"${a}\" es un isograma y \"${b}\" tampoco`\n    }\n\n    let anagrama: string \n    anagrama = aa === ba ? `Las palabras \"${a}\" y \"${b}\" son anagramas` : `Las palabras \"${a}\" y \"${b}\" no son anagramas`\n\n    let palindromo: string\n\n    if (a === ar && b === br) {\n        palindromo = `Tanto \"${a}\" como \"${b}\" son palindromas`\n    } else if (a === ar && b !== br) {\n        palindromo = `\"${a}\" es palindroma y \"${b}\" no lo es`\n    } else if (a!==ar && b === br) {\n        palindromo =` \"${a}\" no es palindroma pero \"${b}\" si lo es`\n    } else{\n        palindromo = `Ninguna de las palabras es palindroma`\n    }\n\n    return {anagrama, palindromo, isograma}\n}\n\nconsole.log(comprobaciones(\"carne\", \"ana\"))\nconsole.log(comprobaciones(\"radar\", \"ana\"))\nconsole.log(comprobaciones(\"radar\", \"carlos\"))\nconsole.log(comprobaciones(\"carlos\", \"ana\"))\nconsole.log(comprobaciones(\"juan\", \"carlos\"))"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/typescript/kodenook.ts",
    "content": "\nlet txt: string = 'hello, javascript!'\n\nconsole.log(txt.charAt(4))\nconsole.log(txt.toUpperCase())\nconsole.log(txt.toLowerCase())\nconsole.log(txt.trim())\nconsole.log(txt.repeat(2))\nconsole.log(txt.replace('h', 'j'))\nconsole.log(txt.split(' '))\nconsole.log(txt.endsWith('script!'))\nconsole.log(txt.startsWith('hello'))\n\n/**\n * The function checks if a word is a palindrome, an anagram of another word, or an isogram.\n * @param {string} word - The `word` parameter is a string that represents a word.\n * @param {string} word2 - The parameter `word2` is a string that represents another word that will be\n * compared to `word` to check if they are anagrams.\n */\nfunction typeWord(word: string, word2: string): void {\n\n    if (word === word.split('').reverse().join('')) {\n        console.log('is palindrome')\n    }\n\n    if (word.split('').sort().join('') == word2.split('').sort().join('')) {\n        console.log('is an anagram')\n    }\n\n    if (word.length === new Set(word).size) {\n        console.log('is isogram')\n    }\n}\n\ntypeWord('roma', 'amor')"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/typescript/marcode24.ts",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\n// Operaciones comunes con cadenas de caracteres\n\n// Acceso a caracteres específicos\nconst cadena: string = \"Hola, mundo!\";\nconsole.log(\"Carácter en la posición 0:\", cadena[0]);\n\n// Subcadenas\nconst subcadena: string = cadena.substring(2, 6);\nconsole.log(\"Subcadena:\", subcadena);\n\n// Longitud de la cadena\nconsole.log(\"Longitud de la cadena:\", cadena.length);\n\n// Concatenación\nconst otraCadena: string = \" Qué tal?\";\nconst cadenaConcatenada: string = cadena + otraCadena;\nconsole.log(\"Cadena concatenada:\", cadenaConcatenada);\n\n// Repetición\nconst cadenaRepetida: string = cadena.repeat(3);\nconsole.log(\"Cadena repetida 3 veces:\", cadenaRepetida);\n\n// Recorrido\nfor (let i: number = 0; i < cadena.length; i++) {\n  console.log(\"Carácter en posición\", i, \":\", cadena[i]);\n}\n\n// Conversión a mayúsculas y minúsculas\nconst mayusculas: string = cadena.toUpperCase();\nconst minusculas: string = cadena.toLowerCase();\nconsole.log(\"Mayúsculas:\", mayusculas);\nconsole.log(\"Minúsculas:\", minusculas);\n\n// Reemplazo\nconst nuevaCadena: string = cadena.replace(\"mundo\", \"amigo\");\nconsole.log(\"Cadena con reemplazo:\", nuevaCadena);\n\n// División\nconst palabras: string[] = cadena.split(\" \");\nconsole.log(\"Palabras divididas:\", palabras);\n\n// Unión\nconst union: string = palabras.join(\"-\");\nconsole.log(\"Palabras unidas con guiones:\", union);\n\n// Interpolación\nconst nombre: string = \"Juan\";\nconst edad: number = 30;\nconst mensaje: string = `Hola, me llamo ${nombre} y tengo ${edad} años.`;\nconsole.log(\"Mensaje interpolado:\", mensaje);\n\n// Verificación\nconst contieneHola: boolean = cadena.includes(\"Hola\");\nconsole.log(\"¿La cadena contiene 'Hola'?\", contieneHola);\n\n// Programa que verifica palíndromos, anagramas e isogramas\n\nfunction esPalindromo(palabra: string): boolean {\n  const palabraInvertida: string = palabra.split(\"\").reverse().join(\"\");\n  return palabra === palabraInvertida;\n}\n\nfunction esAnagrama(palabra1: string, palabra2: string): boolean {\n  const ordenPalabra1: string = palabra1.split(\"\").sort().join(\"\");\n  const ordenPalabra2: string = palabra2.split(\"\").sort().join(\"\");\n  return ordenPalabra1 === ordenPalabra2;\n}\n\nfunction esIsograma(palabra: string): boolean {\n  const caracteresUnicos: Set<string> = new Set(palabra);\n  return palabra.length === caracteresUnicos.size;\n}\n\n// Ejemplos\nconst palabra1: string = \"oso\";\nconst palabra2: string = \"soso\";\nconsole.log(`\"${palabra1}\" es palíndromo:`, esPalindromo(palabra1));\nconsole.log(`\"${palabra1}\" es anagrama de \"${palabra2}\":`, esAnagrama(palabra1, palabra2));\nconsole.log(`\"${palabra1}\" es isograma:`, esIsograma(palabra1));\n\n// Visita mi repo en GitHub para ver y correr los tests de este código --> https://github.com/marcode24/weekly-challenges\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/typescript/markc1234.ts",
    "content": "(() => {\n    //Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n    // - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido, conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n\n    // concantencacion\n    const cadena1 = \"nombre\"\n    const cadena2 = \"apellido\"\n    const cadena3 = cadena1 + cadena2\n    const cadena4 = cadena2.concat(cadena1)\n\n    // longitud de la cadena\n    const cadena5 = cadena4.length\n\n    // acceso a un caracter\n    const char = cadena3.charAt(0)\n\n    // convertir a mayuscula y minuscula\n    const cadena6 = char.toUpperCase()\n    const cadena7 = cadena6.toLowerCase()\n\n    // buscar posicion de una subcadena dentro de una cadena\n    const cadena8 = cadena2.indexOf(\"lli\")\n    // subcadena de una cadena\n    const cadena9 = cadena1.substring(0,3)\n\n    // repeticion\n    const cadena10 = cadena9.repeat(3); \n    // recorrer\n    for (let char of cadena10) {\n        console.log(char);\n    }\n\n    // remplazar \n    const cadena11 = cadena10.replace(\"nom\", \"nombre\");\n    \n    // dividir cadena\n    const cadena12 = cadena2.split(\"ll\");\n\n    // union \n    const palabras = [\"Hola\", \"Adios\"];\n    console.log(palabras.join(\" \"));\n\n\n    // interpolacion\n    const cadena13 = \"Mundo\";\n    console.log(`Hola ${cadena13}`);\n\n    // verificar cadena\n    console.log(cadena11.includes(\"nombre\"));\n    console.log(cadena11.startsWith(\"n\"));\n    console.log(cadena11.endsWith(\"e\"));\n\n\n\n    // DIFICULTAD EXTRA (opcional):\n    // Crea un programa que analice dos palabras diferentes y realice comprobaciones para descubrir si son:\n    // - Palíndromos\n    // - Anagramas\n    // - Isogramas\n\n    function reseverseString(str:string):string {\n        let result:string = \"\"\n        for (let i = str.length-1; i >= 0; i--) {\n            const element = str[i];\n            result += element   \n        }\n\n        return result\n    }\n\n    function palindrome(str1:string, str2:string):boolean {\n        // const reverseStr = reseverseString(str1)\n        const str1ToLower = str1.toLowerCase()\n        const str2ToLower = str2.toLowerCase()\n\n        for (let i = 0; i < str1ToLower.length; i++) {\n            const element = str1ToLower[i];\n            if(element !== str2ToLower[i]) {\n                return false\n            }\n        }\n        return true\n    }\n\n    function anagram(str1:string, str2:string):boolean {\n        const str1ToLower = str1.toLowerCase()\n        const str2ToLower = str2.toLowerCase()\n\n        if(str1ToLower.length !== str2ToLower.length) {\n            return false\n        }\n\n        for (let i = 0; i < str1ToLower.length; i++) {\n            const element = str1ToLower[i];\n            \n            if(!str2ToLower.includes(element)) {\n                return false\n            }\n            \n        }\n\n        return true\n    }\n\n    function isogram(str: string): boolean {\n        const strToLower = str.toLowerCase();\n        let letrasVistas = new Set<string>();\n    \n        for (let letra of strToLower) {\n            if (letrasVistas.has(letra)) {\n                return false;\n            }\n            letrasVistas.add(letra);\n        }\n        return true;\n    }\n\n    function bothAreIsogram(str1: string, str2: string): boolean { \n        return isogram(str1) && isogram(str2)\n    } \n\n})()"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/typescript/miguelex.ts",
    "content": "// Operaciones básicas sobre cadenas de texto\nconst texto: string = \"Hola, mundo!\";\n\n// Interpolación de cadenas (uso de plantillas de cadena)\nconst nombre: string = \"Migue\";\nconst lenguaje: string = \"PHP\";\nconst mensaje: string = `Hola, me llamo ${nombre} y trabajo con ${lenguaje} años.`;\nconsole.log(mensaje);\n\n// Longitud de la cadena\nconst longitud: number = texto.length;\nconsole.log(`La longitud de la cadena ${texto} es ${longitud} caracteres`);\n\n// Obtener el carácter en una posición específica\nconst primerCaracter: string = texto[0];\nconsole.log(`El primer carácter de ${texto} es ${primerCaracter}`);\n\n// Concatenar dos cadenas\nconst nuevaCadena: string = texto + \" TypeScript\";\nconsole.log(`La nueva cadena de unir ${texto} con TypeScript es ${nuevaCadena}`);\n\n// Convertir la cadena a minúsculas\nconst minusculas: string = texto.toLowerCase();\nconsole.log(`${texto} en minúsculas es ${minusculas}`);\n\n// Convertir la cadena a mayúsculas\nconst mayusculas: string = texto.toUpperCase();\nconsole.log(`${texto} en mayúsculas es ${mayusculas}`);\n\n// Obtener una subcadena\nconst subcadena: string = texto.substring(0, 4);\nconsole.log(`La subcadena de ${texto} entre las posiciones 0 y 4 es ${subcadena}`);\n\n// Reemplazar parte de la cadena\nconst reemplazada: string = texto.replace(\"Hola\", \"Saludos\");\nconsole.log(`Vamos a reemplazar Hola por Saludos: ${reemplazada}`);\n\n// Operaciones adicionales sobre cadenas de texto\nconst textoConEspacios = \"   Hola,      mundo!   \";\n\n// Eliminar espacios en blanco al principio y al final\nconst sinEspaciosExtremos = textoConEspacios.trim();\nconsole.log(`Cadena sin espacios al principio y al final: ${sinEspaciosExtremos}`);\n\n// Eliminar todos los espacios en blanco\nconst sinEspacios = textoConEspacios.replace(/\\s/g, \"\");\nconsole.log(`Cadena sin espacios: ${sinEspacios}`);\n\n// Unión de dos cadenas\nconst cadena1: string = \"Moure\";\nconst cadena2: string = \"Dev\";\nconst unionCadenas = cadena1.concat(\" \", cadena2);\nconsole.log(`La unión de las cadenas ${cadena1} y ${cadena2} es ${unionCadenas}`);\n\n// Intersección de dos cadenas (caracteres comunes)\nconst interseccionCadenas: string = [...new Set(cadena1)].filter(char => cadena2.includes(char)).join(\"\");\nconsole.log(`Intersección de las cadenas ${cadena1} y ${cadena2} es ${interseccionCadenas}`);\n\n// Acceso a caracteres específicos (por posición)\nconst tercerCaracter: string = texto.charAt(2);\nconsole.log(`El tercer carácter de ${texto} es ${tercerCaracter}`);\n\n// Repetición de una cadena\nconst cadenaRepetida: string = \"Hola \".repeat(3);\nconsole.log(`Cadena Hola repetida 3 veces queda ${cadenaRepetida}`);\n\n// Recorrido de una cadena (usando un bucle)\nfor (let i = 0; i < texto.length; i++) {\n  console.log(`Carácter en posición ${i}: ${texto[i]}`);\n}\n\n// Conversión a título (primera letra en mayúscula)\nconst titulo: string = texto.toLowerCase().replace(/\\b\\w/g, (char) => char.toUpperCase());\nconsole.log(`La cadena ${texto} como título ${titulo}`);\n\n// División de una cadena en un array de substrings\nconst palabras: string[]= texto.split(\" \");\nconsole.log(`Palabras en la cadena ${texto} son ${palabras}`);\n\n// Verificación de si una cadena comienza o termina con ciertos caracteres\nconst comienzaCon: boolean = texto.startsWith(\"Hola\");\nconsole.log(`¿La cadena ${texto} comienza con \"Hola\"? ${comienzaCon}`);\n\nconst terminaCon: boolean = texto.endsWith(\"mundo!\");\nconsole.log(`¿La cadena ${texto}termina con \"mundo!\"? ${terminaCon}`);\n\n// Verificar si una cadena es palíndromo\nfunction esPalindromo(cadena: string): boolean {\n  const sinEspacios = cadena.replace(/\\s/g, \"\").toLowerCase();\n  const invertida = sinEspacios.split(\"\").reverse().join(\"\");\n  return sinEspacios === invertida;\n}\n\n// Verificar si una cadena es un anagrama\nfunction esAnagrama(cadena1: string, cadena2: string): boolean {\n  const limpiarCadena = (cadena: string) => cadena.replace(/\\s/g, \"\").toLowerCase();\n  const limpiaCadena1 = limpiarCadena(cadena1);\n  const limpiaCadena2 = limpiarCadena(cadena2);\n\n  const ordenada1 = limpiaCadena1.split(\"\").sort().join(\"\");\n  const ordenada2 = limpiaCadena2.split(\"\").sort().join(\"\");\n\n  return ordenada1 === ordenada2;\n}\n\n// Verificar si una cadena es un isograma\nfunction esIsograma(cadena: string): boolean {\n  const caracteres = new Set();\n\n  for (const char of cadena) {\n    const caracter = char.toLowerCase();\n    if (caracteres.has(caracter)) {\n      return false;\n    }\n    caracteres.add(caracter);\n  }\n\n  return true;\n}\n\n// Ejemplos de uso de las funciones adicionales\nconsole.log(`¿Es \"${texto}\" un palíndromo? ${esPalindromo(texto)}`);\nconsole.log(`¿Es Ana un palíndromo? ${esPalindromo(\"Ana\")}`);\nconsole.log(`¿Es \"listen\" un anagrama de \"silent\"? ${esAnagrama(\"listen\", \"silent\")}`);\nconsole.log(`¿Es \"programming\" un isograma? ${esIsograma(\"programming\")}`);\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/typescript/mikelroset.ts",
    "content": "/* ------------------------ CONCATENACIÓN DE CADENAS ------------------------ */\n\n// Usando el operador +\nlet a: string = \"Hello\";\nlet b: string = \"World\";\nlet c: string = a + b; // HelloWorld\n\n// Usando el operador +=\nlet d: string = \"Hello\";\nd += \"World\"; // HelloWorld\n\n// Usando template literals\nlet e: string = `Hello ${\"World\"}`; // Hello World\n\n\n/* --------------------------- LONGITUD DE CADENA --------------------------- */\n\n// Usando el .length\nlet f: string = \"Hello\";\nlet g: number = f.length; // 5\n\n\n/* -------------------------- ACCEDER A CARACTERES -------------------------- */\n\n// Usando el []\nlet h: string = \"Hello\";\nlet i: string = h[0]; // H\nlet j: string = h[4]; // o\n\n// Usando el .charAt()\nlet k: string = \"Hello\";\nlet l: string = k.charAt(0); // H\nlet m: string = k.charAt(4); // o\n\n// Usando el .charCodeAt()\nlet n: string = \"Hello\";\nlet o: number = n.charCodeAt(0); // 72\nlet p: number = n.charCodeAt(4); // 111\n\n\n/* -------------------------- MANIPULACIÓN DE CADENAS ----------------------- */\n\n// Usando el .toUpperCase()\nlet q: string = \"Hello\";\nlet r: string = q.toUpperCase(); // HELLO\n\n// Usando el .toLowerCase()\nlet s: string = \"Hello\";\nlet t: string = s.toLowerCase(); // hello\n\n// Usando el .toLocaleLowerCase()\nlet v: string = \"Hello\";\nlet w: string = v.toLocaleLowerCase(); // hello\n\n// Usando el .toLocaleUpperCase()\nlet x: string = \"Hello\";\nlet y: string = x.toLocaleUpperCase(); // HELLO\n\n// Usando el .replace()\nlet z: string = \"Hello\";\nlet a2: string = z.replace(\"H\", \"h\"); // hell\nlet b2: string = z.replace(\"o\", \"0\"); // HeLl\n\n// Usando el .split()\nlet c2: string = \"Hello, World\"; // Hello, World\nlet d2: string[] = c2.split(\", \"); // [\"Hello\", \"World\"]\n\n// Usando el .substring()\nlet e2: string = \"Hello\";\nlet f2: string = e2.substring(0, 5); // Hello\nlet g2: string = e2.substring(6); // World\n\n// Usando el .slice()\nlet h2: string = \"Hello\";\nlet i2: string = h2.slice(0, 5); // Hello\nlet j2: string = h2.slice(6); // World\n\n// Usando el .indexOf()\nlet k2: string = \"Hello\";\nlet gl: number = k2.indexOf(\"l\"); // 2\nlet m2: number = k2.indexOf(\"o\"); // 4\n\n// Usando el .lastIndexOf()\nlet n2: string = \"Hello\";\nlet o2: number = n2.lastIndexOf(\"l\"); // 5\nlet p2: number = n2.lastIndexOf(\"o\"); // 4\n\n// Usando el .includes()\nlet q2: string = \"Hello\";\nlet s2: boolean = q2.includes(\"l\"); // true\nlet t2: boolean = q2.includes(\"o\"); // true\n\n// Usando el .trim()\nlet u2: string = \"   Hello   \";\nlet w2: string = u2.trim(); // Hello\n\n// Usando el .trimStart()\nlet x2: string = \"   Hello   \";\nlet y2: string = x2.trimStart(); // Hello   \n\n// Usando el .trimEnd()\nlet z2: string = \"   Hello   \";\nlet a3: string = z2.trimEnd(); //    Hello\n\n// Usando el .replaceAll()\nlet b3: string = \"Hello\";\nlet c3: string = b3.replaceAll(\"l\", \"x\"); // Hexxo\n\n\n/* ----------------------- OTROS MÉTODOS MENOS COMUNES ---------------------- */\n\n// Usando el .padStart()\nlet d3: string = \"Hello\";\nlet e3: string = d3.padStart(10, \"0\"); // 00000Hello\n\n// Usando el .padEnd()\nlet f3: string = \"Hello\";\nlet g3: string = f3.padEnd(10, \"0\"); // Hello00000\n\n// Usando el .repeat()\nlet h3: string = \"Hello\";\nlet i3: string = h3.repeat(3); // HelloHelloHello\n\n// Usando el .localeCompare()\nlet j3: string = \"apple\";\nlet k3: number = j3.localeCompare(\"banana\"); // -1 (apple es menor que banana)\n\n\n// -------------------------- BONUS EJERCICIO ------------------------------- //\n\n// Palíndromos con strings\nfunction isPalindrome(str: string): boolean {\n    let reversed: string = str.split(\"\").reverse().join(\"\");\n    return str === reversed;\n}\n\nisPalindrome(\"Isaac no ronca así\"); // true\nisPalindrome(\"tanto monta monta tanto\"); // false\n\n\nfunction isAnagram(str1: string, str2: string): boolean {\n    let reversed1: string = str1.split(\"\").reverse().join(\"\");\n    let reversed2: string = str2.split(\"\").reverse().join(\"\");\n    return reversed1 === reversed2;\n}\n\nisAnagram(\"Isaac no ronca así\", \"Isaac no ronca así\"); // true\nisAnagram(\"Isaac no ronca así\", \"Isaac no ronca así tanto\"); // false\n\nfunction isIsogram(str: string): boolean {\n    let letters: string[] = str.toLocaleLowerCase().split(\"\");\n\n    return letters.length === new Set(letters).size;\n}\n\nisIsogram(\"coco\"); // true 2 c, 2 o\nisIsogram(\"otra prueba\"); // false 1 o, 1 t, 2 r, 2 a,, 1 p, 1 u, 1 e, 1 b"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/typescript/misterdan100.ts",
    "content": "/**\n * palindromo = 'oso' 'ana'\n * anagrama = 'amor' 'roma'\n * isograma = \"brújula\", \"examen\", \"zebra\"\n */\n\nconst word1 = 'brujula'\nconst word2 = 'zebra'\n\nconst checkWords = (word1: string, word2: string) => {\n    type TResult = {\n        word1: string\n        word2: string\n        areAnagrama: boolean\n        areIsograma: boolean\n    }\n    const result: TResult = {\n        word1: '',\n        word2: '',\n        areAnagrama: false,\n        areIsograma: false,\n    }\n\n    const isPalindromo = (word) => {\n        const reverseWord = word.split('').reverse().join('').replaceAll(' ', '')\n        return !!(word.replaceAll(' ', '') === reverseWord)\n    }\n\n    const areAnagrama = (word1, word2) => {\n        const arrWord1 = word1.replaceAll(' ', '').split('')\n        const arrWord2 = word2.replaceAll(' ', '').split('')\n\n        if(arrWord1.length !== arrWord2.length) return false\n        for( let i of arrWord1) {\n            if(!arrWord2.includes(i)) return false\n        }\n        return true\n    }\n\n    const areIsograma = (word1, word2) => {\n        const arrWord1 = word1.replaceAll(' ', '').split('')\n        const arrWord2 = word2.replaceAll(' ', '').split('')\n\n        for( let i of arrWord1) {\n            if(arrWord2.includes(i)) return false\n        }\n        return true\n\n    }\n\n    result.word1 = `Palindromo ${isPalindromo(word1)}`\n    result.word2 = `Palindromo ${isPalindromo(word2)}`\n    result.areAnagrama = areAnagrama(word1, word2)\n    result.areIsograma = areIsograma(word1, word2)\n\n    return result\n}\n\nconsole.log(checkWords(word1, word2))\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/typescript/mxtrar23.ts",
    "content": "\n//Strings\n(()=>{\n//Comillas aceptadas\nconsole.log('Comillas sencillas')\nconsole.log(\"Comillas dobles\")\nconsole.log(`Comillas invertidas`)\n\nconst texto = 'Hola, Typescript'\nconsole.log(texto.length); //lonigtud\n\n\n// obtener caracter individual\nconsole.log(texto.charAt(6));\nconsole.log(texto[0]);\n\n// concatenar \nconsole.log(texto.concat(' bienvenido.'));\nconsole.log(texto+' bienvenido.');\nconsole.log(`${texto} bienvenido.`);\n\n// busca en contenido\nconsole.log(texto.includes('script')); // contiene el texto\nconsole.log(texto.startsWith('T')); // caracter inicial \nconsole.log(texto.endsWith('.')); // caracter final \nconsole.log(texto.indexOf(',')); // y devuelve indice de la 1er coincidencia\nconsole.log(texto.match(/\\w+,\\s\\w+/)); //coincidencia con expresion regular\nconsole.log(texto.search(/\\s/)); //devuelve indice decoinicencia expresion regular\n\n//motificaciones\nconsole.log(texto.toUpperCase); //mayusulas\nconsole.log(texto.toLowerCase); //minusculas\nconsole.log(texto.repeat(3)); //repite cadena n veces\nconsole.log(texto.replace('Hola','Bienvenido')); //remplaza \nconsole.log(texto.replace(/^\\w+,/,'Bienvenido,')); //remplaza con expreison regular\n\nconsole.log(texto.split(' ')); // separa por el caracter especifico\nconsole.log(texto.split(', ').join('___')); // une con caracter especifico\nconsole.log(texto.split(', ').reverse().join(' ')); // separa por el caracter especifico, invierte las coincidencias y une\n\n\n//Dificultad Extra\n\nconst validarPalabras= (palabra1:string,palabra2:string) => {\n\n  //palindromos\n  [palabra1,palabra2].forEach((texto)=>{\n    if (texto.toLowerCase().replace(' ','') == texto.toLowerCase().replace(' ','').split('').reverse().join('') ) {\n      console.log(`+ \"${texto}\" Es palindromo`);\n    } else {\n      console.log(`- \"${texto}\" NO es palindromo`);\n    }\n  })\n\n  //anagrama\n  let texto1 = palabra1.toLowerCase().replace(' ','').trim().split('')\n  let texto2 = palabra2.toLowerCase().replace(' ','').trim().split('')\n  let encontradas = 0;\n\n  if(texto1.length == texto2.length){\n    texto1.forEach((letra)=>{\n      if (texto2.includes(letra)) {\n        let pos = texto2.indexOf(letra)\n        texto2.splice(pos,1)\n        encontradas++\n      }\n    })\n\n    if(encontradas == texto1.length){\n      console.log(`+ \"${palabra1}\"-\"${palabra2}\" Son un anagrama`);\n    }else{\n      console.log(`- \"${palabra1}\"-\"${palabra2}\" NO son un anagrama`);\n    }\n  }else {\n    console.log(`- \"${palabra1}\"-\"${palabra2}\" NO son un anagrama`);\n  }\n\n  //isograma\n\n  [palabra1,palabra2].forEach((texto)=>{\n    let parsed = texto.toLowerCase().trim().replace(' ','')\n    let myset = new Set(parsed)\n\n    if(myset.size == parsed.length){\n      console.log(`+ \"${texto}\" Es isograma`);\n    }else{\n      console.log(`- \"${texto}\" NO es isograma`);\n    }\n\n  })\n\n}\n\nconsole.log('---');\nvalidarPalabras('radar','isogram')\nconsole.log('---');\nvalidarPalabras('cuaderno','educaron')\nconsole.log('---');\n\n\n\n\n\n\n\n\n\n\n\n})();\n\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/typescript/nlarrea.ts",
    "content": "/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\n// CREATE A STRING\n\nconst myString: string = 'Hello world!';\n\n// ACCESS CHARACTERS\n\nconsole.log(myString[6]);  // w\nconst firstWord: string = myString.slice(0, 5);\nconsole.log(firstWord);  // Hello\n\n// Separate the string in each space and take the second item from the list\nconst secondWord: string = myString.split(' ')[1]\nconsole.log(secondWord);  // world!\n\n// LENGTH\n\nconsole.log(myString.length);  // 12\nconsole.log(firstWord.length);  // 5\nconsole.log(secondWord.length);  // 6\n\n// INTERPOLATION AND CONCATENATION\n\nlet sentence: string = `${firstWord} ${secondWord}`;\nconsole.log(sentence);  // Hello world!\n\nsentence = firstWord + ' ' + secondWord;\nconsole.log(sentence);  // Hello world!\n\nsentence = firstWord.concat(secondWord);\nconsole.log(sentence);  // Helloworld!\n\n// REPETITION\n\nconsole.log(firstWord.repeat(2));  // HelloHello\n\n// CHECK\n\nconsole.log(myString.includes('h'));  // false\nconsole.log(myString.includes('H'));  // true\nconsole.log(myString.includes('world'));  // true\nconsole.log(myString.startsWith('Hell'));  // true\nconsole.log(myString.endsWith('!'));  // true\n\n// REPLACE\n\nconsole.log(myString.replace('!', '.'));  // Hello world.\n\n// DIVISION\n\nconsole.log(myString.split(' '));  // [ 'Hello', 'world!' ]\n\n// UPPER AND LOWER CASES\n\nconsole.log(myString.toUpperCase());  // HELLO WORLD\nconsole.log(myString.toLowerCase());  // hello world\n\n// REMOVE EMPTY SPACES FROM BEGINNING AND END\n\nconst myOtherString: string = '    Hello there!   '\n\nconsole.log(myOtherString.length);  // 19\nconsole.log(myOtherString.trim().length);  // 12\nconsole.log(myOtherString.trimEnd().length);    // 16\nconsole.log(myOtherString.trimStart().length);  // 15\n\n// FIND\n\nconst longString: string = 'the quick brown fox jumped over the lazy dog'\n\nconsole.log(longString.search('quick'));  // 4 -> index of the start of the word\nconsole.log(longString.search('QUICK'));  // -1 -> doesn't exist\n\n// FROM NUMERIC STRING TO NUMBER\n\nconst stringNumber: string = '1234';\nconst intNumber: number = +stringNumber;\nconst intNumber2: number = parseInt(stringNumber);\nconsole.log(typeof stringNumber);   // string\nconsole.log(typeof intNumber);      // number\nconsole.log(typeof intNumber2);     // number\n\nconst stringNumber2: string = '1234.56';\nconst floatNumber: number = +stringNumber2;\nconst floatNumber2: number = parseFloat(stringNumber2);\nconsole.log(typeof stringNumber2);  // string\nconsole.log(typeof floatNumber);    // number\nconsole.log(typeof floatNumber2);   // number\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\n\nfunction checkIsPalindrome(word: string): boolean {\n    const reversedWord: string = [...word].reverse().join('');\n    return word === reversedWord;\n}\n\n\nfunction checkIsAnagram(wordOne: string, wordTwo: string): boolean {\n    return [...wordOne].sort().join('') === [...wordTwo].sort().join('');\n}\n\n\nfunction checkIsIsogram(word: string): boolean {\n    // Store how many times appears each character\n    const charsObj = {};\n    for (const char of word) {\n        charsObj[char] = charsObj[char] + 1 || 1;\n    }\n\n    // Check if all the characters repeat the same amount of times\n    const charsValues: number[] = Object.values(charsObj);\n    const firstCharQty: number = charsValues[0];\n    for (const charQty of charsValues) {\n        if (charQty !== firstCharQty) {\n            return false;\n        }\n    }\n\n    return true;\n}\n\n\nfunction checkWords (wordOne: string, wordTwo: string): void {\n    // Check if they are palindromes\n    console.log(`\\nIs ${wordOne} a palindrome? ${checkIsPalindrome(wordOne)}`);\n    console.log(`Is ${wordTwo} a palindrome? ${checkIsPalindrome(wordTwo)}`);\n\n    // Check if they are anagrams\n    console.log(`\\nIs ${wordOne} ${wordTwo}'s anagram? ${checkIsAnagram(wordOne, wordTwo)}`);\n\n    // Check if they are isograms\n    console.log(`\\nIs ${wordOne} an isogram? ${checkIsIsogram(wordOne)}`);\n    console.log(`Is ${wordTwo} an isogram? ${checkIsIsogram(wordTwo)}\\n`);\n}\n\n\ncheckWords('rotor', 'anna');\ncheckWords('amor', 'roma');"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/typescript/pcosin.ts",
    "content": "// Operaciones a realizar con cadena de caracteres\n\n// Concatenación:\n\nconst str1: string = \"Hola\";\nconst str2: string = \"mundo\";\n\nconst concatenado: string = str1 + \" \" + str2;\n\nconst cantenadoConcat: string = str1.concat(\" \", str2);\n\nconsole.log(concatenado, cantenadoConcat);\n\n// Longitud de la cadena\n\nconst lengthStr: number = str1.length;\n\nconsole.log(lengthStr);\n\n// Acceso a la cadena con corchetes\n\nconst primerCaracter: string = str1[0];\n\nconsole.log(primerCaracter);\n\n// Subcadenas\n\nconst subCadena: string = str1.substring(0, 2);\n\nconsole.log(subCadena);\n\n// Búsqueda de subcadenas con indexOf e includes\n\nconst indexCadena: number = str2.indexOf(\"m\");\nconst includesInCadena: boolean = str2.includes(\"l\");\n\nconsole.log(indexCadena, includesInCadena);\n\n// Recorta una parte del string\n\nconst parte = str2.slice(-1);\n\nconsole.log(parte)\n\n//Mayúsculas y minúsculas\n\nconst mayusculas = str1.toUpperCase();\nconst minusculas = str2.toLowerCase();\n\nconsole.log(mayusculas, minusculas);\n\n// Reemplazo\n\nconst reemplazo: string = str1.replace(\"H\", \"P\");\n\nconsole.log(reemplazo);\n\n// Dividir una cadena\n\nconst cadenas: string = \"Holas mundos\";\n\nconst dividirCadena: string[] = cadenas.split(\" \");\n\nconsole.log(dividirCadena);\n\n//Unir cadenas\n\nconst unir: string = dividirCadena.join(\" \");\n\nconsole.log(unir);\n\n// Fin y principio de cadena\n\nconst terminaCon: boolean = str1.endsWith(\"K\");\nconst empiezaCon: boolean = str1.startsWith(\"H\");\n\nconsole.log(terminaCon);\nconsole.log(empiezaCon);\n\n\n\n// Extra\n\nimport * as readlineSync from \"readline-sync\";\n\nfunction esUnPalindromo(): void {\n  const str: string = readlineSync.question(\n    \"Ingrese la palabra a comprobar si es un palíndromo: \"\n  );\n\n  const comprobacion: string = str.split(\"\").reverse().join(\"\");\n\n  str === comprobacion\n    ? console.log(`La palabra ${str} es un palíndromo`)\n    : console.log(`La palabra ${str} no es un palíndromo`);\n}\n\nfunction esUnAnagrama(): void {\n  const str1: string = readlineSync.question(\n    \"Ingrese la primera palabra a comprobar si es un anagrama: \"\n  );\n\n  const str2: string = readlineSync.question(\n    \"Ingrese la segunda palabra a comprobar si es un anagrama: \"\n  );\n\n  const str1Comprobacion: string = str1.split(\"\").sort().join(\"\");\n  const str2Comprobacion: string = str2.split(\"\").sort().join(\"\");\n\n  str1Comprobacion === str2Comprobacion\n    ? console.log(`Las palabras ${str1} y ${str2} son anagramas`)\n    : console.log(`Las palabras ${str1} y ${str2} NO son anagramas`);\n}\n\nfunction esUnIsograma(): void {\n  const str: string = readlineSync.question(\n    \"Ingrese la palabra a comprobar si es un isograma: \"\n  );\n\n  let comprobacion: string = \"\";\n  let count: number = 0;\n  for (let i = 0; i < str.length; i++) {\n    if (!comprobacion.includes(str[i])) {\n      comprobacion += str[i];\n    } else {\n      count++;\n    }\n  }\n\n  count > 0\n    ? console.log(`La palabra ${str} no es un isograma`)\n    : console.log(`La palabra ${str} es un isograma`);\n}\n\nfunction main(): void {\n  let bucle: boolean = true;\n  while (bucle) {\n    console.log(\"\\n== Menú ==\");\n    console.log(\"1. ¿Es un palíndromo?\");\n    console.log(\"2. ¿Es una anagrama?\");\n    console.log(\"3. ¿Es un isograma?\");\n    console.log(\"4. Salir\");\n\n    const opcion = readlineSync.questionInt(\"Seleccione una opción: \");\n\n    switch (opcion) {\n      case 1:\n        esUnPalindromo();\n        break;\n      case 2:\n        esUnAnagrama();\n        break;\n      case 3:\n        esUnIsograma();\n        break;\n      case 4:\n        console.log(\"Saliendo de la aplicación. ¡Hasta luego!\");\n        bucle = false;\n        break;\n      default:\n        console.log(\"Opción no válida. Inténtelo de nuevo.\");\n    }\n  }\n}\n\nmain();\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/typescript/qv1ko.ts",
    "content": "program(\"facility\", \"disk\");\n\nfunction program(word1: string, word2: string): void {\n\n    console.log(isPalindrome(word1) ? `The word ${word1} is a palindrome` : `The word ${word1} is not a palindrome`);\n    console.log(isPalindrome(word2) ? `The word ${word2} is a palindrome` : `The word ${word2} is not a palindrome`);\n\n    console.log(areAnagrams(word1, word2) ? `The words ${word1} and ${word2} are anagrams` : `The words ${word1} and ${word2} are not anagrams`);\n\n    console.log(isIsogram(word1) ? `The word ${word1} is an isogram` : `The word ${word1} is not an isogram`);\n    console.log(isIsogram(word2) ? `The word ${word2} is an isogram` : `The word ${word2} is not an isogram`);\n\n}\n\nfunction isPalindrome(word: string): boolean {\n\n    const len = word.length;\n\n    for (let i = 0; i < len / 2; i++) {\n        if (word[i] !== word[len - i - 1]) {\n            return false;\n        }\n    }\n\n    return true;\n\n}\n\nfunction areAnagrams(word1: string, word2: string): boolean {\n\n    if (word1.length !== word2.length) {\n        return false;\n    }\n\n    const lettersWord1 = word1.split('').sort();\n    const lettersWord2 = word2.split('').sort();\n\n    return lettersWord1.join('') === lettersWord2.join('');\n\n}\n\nfunction isIsogram(word: string): boolean {\n\n    const letters: string[] = [];\n\n    for (const letter of word) {\n        if (letters.includes(letter)) {\n            return false;\n        }\n        letters.push(letter);\n    }\n\n    return true;\n\n}\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/typescript/qwik-zgheib.ts",
    "content": "/* -- exercise */\nlet str: string = \"Hello\";\nconsole.log(str[0]);\n\nstr = \"Hello World\";\nconsole.log(str.substring(0, 5));\nconsole.log(str.slice(-5));\n\nstr = \"JavaScript\";\nconsole.log(str.length);\n\nlet str1: string = \"Hello\";\nlet str2: string = \"World\";\nconsole.log(str1 + \" \" + str2);\nstr = \"abc\";\nconsole.log(str.repeat(3));\n\nstr = \"JavaScript\";\nfor (let char of str) {\n  console.log(char);\n}\n\nstr = \"Hello\";\nconsole.log(str.toUpperCase());\nconsole.log(str.toLowerCase());\n\nstr = \"Hello World\";\nconsole.log(str.replace(\"World\", \"JavaScript\"));\n\nstr = \"Apple, Banana, Cherry\";\nconsole.log(str.split(\", \"));\nlet arr: string[] = [\"Apple\", \"Banana\", \"Cherry\"];\nconsole.log(arr.join(\", \"));\n\nlet nameA: string = \"Alice\";\nconsole.log(`Hello, ${nameA}!`);\n\nstr = \"JavaScript is awesome\";\nconsole.log(str.includes(\"Java\"));\nconsole.log(str.startsWith(\"Java\"));\nconsole.log(str.endsWith(\"awesome\"));\n\n/* -- extra challenge */\nconst isPalindrome = (word: string): boolean => {\n  let reversed: string = word.split(\"\").reverse().join(\"\");\n  return word.toLowerCase() === reversed.toLowerCase();\n};\n\nconst isAnagram = (word1: string, word2: string): boolean => {\n  let sorted1: string = word1.toLowerCase().split(\"\").sort().join(\"\");\n  let sorted2: string = word2.toLowerCase().split(\"\").sort().join(\"\");\n  return sorted1 === sorted2;\n};\n\nconst isIsogram = (word: string): boolean => {\n  let charMap: { [key: string]: boolean } = {};\n  for (let char of word.toLowerCase()) {\n    if (charMap[char]) return false;\n    charMap[char] = true;\n  }\n  return true;\n};\n\nlet word1: string = \"Madam\";\nlet word2: string = \"Adam\";\n\nconsole.log(`\"${word1}\" is a palindrome:`, isPalindrome(word1));\nconsole.log(`\"${word2}\" is an anagram of \"${word1}\":`, isAnagram(word1, word2));\nconsole.log(`\"${word1}\" is an isogram:`, isIsogram(word1));\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/typescript/rubenplazavi.ts",
    "content": "\n/*\n * EJERCICIO:\n * Muestra ejemplos de todas las operaciones que puedes realizar con cadenas de caracteres\n * en tu lenguaje. Algunas de esas operaciones podrían ser (busca todas las que puedas):\n * - Acceso a caracteres específicos, subcadenas, longitud, concatenación, repetición, recorrido,\n *   conversión a mayúsculas y minúsculas, reemplazo, división, unión, interpolación, verificación...\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa que analice dos palabras diferentes y realice comprobaciones\n * para descubrir si son:\n * - Palíndromos\n * - Anagramas\n * - Isogramas\n */\n\n/*\n\nLos palíndromos son palabras o frases que al leerse de izquierda a derecha y viceversa dicen lo mismo\n\nUn anagrama es una palabra que resulta de la transposición de todas las letras de otra palabra12. Puede aplicarse también a grupos de palabras o frases1. Existen dos tipos de anagramas:\n\nIsogramas\n*/\n\nconst cadenaAmigo: string = \"amigo\"; \nconst cadenaUn = \"Un\";\nconst cadenaEres = \"eres\";\n\n//! concatenar strings\nconst cadenaConcatenadaConSeparador: string = cadenaEres.concat(\"-\",cadenaUn,\"-\").concat(cadenaAmigo);\nconsole.log(cadenaConcatenadaConSeparador);\n\n//Otra forma\nconst cadenaConcatenada2: string = `${cadenaEres}${cadenaUn}${cadenaAmigo}`;\nconsole.log(cadenaConcatenada2);\n\n// otra forma\nconst cadenaConcatenada3: string = cadenaEres + cadenaUn + cadenaAmigo;\nconsole.log(cadenaConcatenada3);\n\n//! Cortar Strings - //!división\n//slice\nconst cadenaCortada: string = cadenaAmigo.slice(0, 4);\nconsole.log(cadenaCortada);\n\n//split\nconst cadenaSplit: string[] = cadenaAmigo.split(\"\");\nconsole.log(\"split(''): \", cadenaSplit);\n\nconst cadenaSplit2: string[] = cadenaConcatenadaConSeparador.split(\"-\");\nconsole.log(cadenaSplit2);\n\n//! recoger length of a string\nconst lengthCadenaAmigo: number = cadenaAmigo.length;\nconsole.log(\"longitud cadenaAmigo: \",lengthCadenaAmigo);\n\n//! recoger caracter de un string\nconst caracterPosicion4: string = cadenaAmigo.charAt(3);\nconsole.log(caracterPosicion4);\n\n//! Pillar una subcadena de carácteres dentro de la cadena\nconst subcadena: string = cadenaConcatenada2.substring(4,2);\nconsole.log(\"subcadena un: \",subcadena);\n\n//! Comparar cadenas\nconst cadenaIgualValorQueAmigo: string = \"amigo\";\n\nconsole.log(`comparacion: ${cadenaIgualValorQueAmigo} === ${cadenaAmigo}`);\ncadenaIgualValorQueAmigo.match(cadenaAmigo) \n    ? console.log(\"son iguales\") \n    : console.log(\"no son iguales\");\n\nconsole.log(`comparacion: ${cadenaIgualValorQueAmigo} === ${cadenaConcatenadaConSeparador}`);\ncadenaIgualValorQueAmigo === cadenaConcatenadaConSeparador\n    ? console.log(\"son iguales\")\n    : console.log(\"no son iguales\");\n\n//! comparar si existe una subcadena dentro de un string\nconst substringExists: boolean = cadenaConcatenadaConSeparador.search(cadenaAmigo) !== -1;\n\n//! Recorrer cadenas\nconst CadenaMayusculas: string = cadenaAmigo.toLocaleLowerCase()\nconsole.log(\"cadenaAmigo en minusculas: \",CadenaMayusculas);\ncadenaAmigo.toLocaleUpperCase()\nconsole.log(\"cadenaAmigo en minusculas: \",cadenaAmigo.toUpperCase());\n\n//! Repetir string\nconsole.log(cadenaAmigo.repeat(5)); //cadenaAmigo.repeat(5);ç\n\nconst monjaRepetida = \"monja\".repeat(5);\nconsole.log(monjaRepetida);\n\n//!reemplazo\nconst cadenaRemplazada: string = cadenaConcatenadaConSeparador.replace(\"-\",'.');\nconsole.log(`cadena antes: ${cadenaConcatenadaConSeparador}, cadenaRemplazada: ${cadenaRemplazada}`);\n\n\nconst palabraDividida: string = cadenaConcatenadaConSeparador.slice(0,4);\nconsole.log(\"Palabra dividida\", palabraDividida);\n\n//! interpolación\nconst nombre: string = \"Carlos\";\nconst apellido: string = \"Augusto\";   \nconst edad: number = 30;\n\nconst mensaje: string = `Mi nombre es ${nombre}, mi apellido es ${apellido} y tengo ${edad} años.`;\nconsole.log(mensaje);\n\n//! verificación\nconsole.log(\"cadenaAmigo.startsWith('am') --> \",cadenaAmigo.startsWith(\"am\"));\nconsole.log(\"cadenaAmigo.endsWith('rot') --> \",cadenaAmigo.endsWith(\"rot\"));\n\n//! Comprobar si pasa un regex\nconsole.log(\"cadenaAmigo.match(/amig/) --> \",cadenaAmigo.match(/amig/)!=null);\n//! Comprobar si pasa un regex\nconsole.log(\"cadenaAmigo.match(/amig/) Respuesta real --> \",cadenaAmigo.match(/amig/));\n//! comprobar si contiene un substring\nconsole.log(\"cadenaAmigo.includes('amig') --> \",cadenaAmigo.includes(\"amig\"));\n\n//! recorrido\nfor(let i=0; i<cadenaAmigo.length; i++){\n    console.log(`posicion: ${i+1} - caracter: ${cadenaAmigo[i]}`); // cadenaAmigo.charAt(i) \n}\n\n\n/**\n * ------------------ Reto Extra ------------------\n * Palindromos\n * Anagramas\n * Isogramas\n */\n\n//! Palindromos\n\nconst palindromo: string = \"anilina\";\nconst noPalindromo: string = \"amigo\";\n\n// Una forma de hacerlo\n\nlet palindromoInvertido: string = \"\";\nconst ultimoIndex: number = palindromo.length -1;\n\nfor (let i = 0; i < palindromo.length; i++) {\n    palindromoInvertido += palindromo[ultimoIndex - i];\n}\nconsole.log(\"palindromoInvertido\", palindromoInvertido);\npalindromoInvertido == palindromo\n    ? console.log(`${palindromo} es una palabra palíndroma`)\n    : console.log(`${palindromo} no es una palabra palíndroma`);\n\n\n// Otra forma más directa\n\n    palindromo.toLowerCase() === palindromo.toLowerCase().split(\"\").reverse().join(\"\")\n    ? console.log(`${palindromo} es una palabra palíndroma`)\n    : console.log(`${palindromo} no es una palabra palíndroma`);\n\n\n//! Anagramas\n\nconst inglaterra: string = \"inglaterra\";\nconst integrarla: string = \"integrarla\";\nlet dobleIntegrarla = integrarla;\n\nconst inglaterraArray: Array<string> = inglaterra.split(\"\"); //convierte el string en un array\nlet contador: number = 0;\nif(inglaterra.length === integrarla.length){\n    const length: number = inglaterraArray.length;\n    for (let i = 0; i < length; i++) {\n        const caracterAComparar = inglaterraArray[i];\n        if(dobleIntegrarla.includes(caracterAComparar)){\n            contador++;\n            const index = dobleIntegrarla.indexOf(caracterAComparar);\n            if(index !== -1){\n                dobleIntegrarla = integrarla.slice(0, index) + integrarla.slice(index + 1);\n            }\n        }\n    }\n}\nif(contador === inglaterra.length){   \n    console.log(`${integrarla} es un anagrama de ${inglaterra}`);\n}else{\n    console.log(`${integrarla} no es un anagrama de ${inglaterra}`);\n}\n\n\n// Ejemplo refactorizado y optimizado:\nfunction areAnagrams(word1: string, word2: string): boolean {\n    if (word1.length !== word2.length) return false;\n    const sortedWord1 = word1.toLowerCase().split(\"\").sort().join(\"\");\n    const sortedWord2 = word2.toLowerCase().split(\"\").sort().join(\"\");\n    return sortedWord1 === sortedWord2;\n}\n\nif (areAnagrams(inglaterra, integrarla)) {\n    console.log(`${integrarla} es un anagrama de ${inglaterra}`);\n} else {\n    console.log(`${integrarla} no es un anagrama de ${inglaterra}`);\n}\n\n\n//! Isogramas"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/typescript/victor-Casta.ts",
    "content": "// Acceso a caracteres específicos\nconst myCharacter: string = 'TypeScript';\nconsole.log(myCharacter.charAt(0));\n\n// Subcadenas\nconst myString1: string = 'Hello TypeScript';\nconsole.log(myString.substring(0, 5));\nconsole.log(myString.slice(6));\n\n// Longitud\nconst Username: string = 'Victor';\nconsole.log(`the username length is the: ${Username.length} characters`);\n\n// Concatenación\nconst productTitle: string = 'Product 1';\nconsole.log(`Product: ${productTitle}`);\n\n// Repetición\nconsole.log('-'.repeat(10));\n\n// Recorrido\nconst programLanguage: string = 'TypeScript';\nfor (let char of programLanguage) {\n  console.log(char);\n}\n\n// Conversión a mayúsculas y minúsculas\nconst myProgramLanguage: string = 'typescript';\nconst uppercaseProgram: string = myProgramLanguage.toUpperCase();\nconst lowercaseProgram: string = myProgramLanguage.toLowerCase();\nconsole.log(`Uppercase program: ${uppercaseProgram}`);\nconsole.log(`Lowercase program: ${lowercaseProgram}`);\n\n// Reemplazo\nlet replacedString1: string = \"Hello TypeScript\".replace(\"TypeScript\", \"JavaScript\");\nconsole.log(replacedString);\n\n// División\nconst myDivideString: string = \"Hello,TypeScript,in,the,roadmap\";\nconst parts: string[] = myDivideString.split(',');\nconsole.log(parts);\n\n// Unión\nconsole.log(parts.join(' '));\nconst greeting: string = 'Hello';\nconst greeting2: string = 'Mundo';\nconsole.log(`${greeting}, ${greeting2}`);\n\n// Interpolación\nlet language: string = 'TypeScript';\nconsole.log(`Welcome to ${language}`);\n\n// Verificación\nconsole.log(typeof language);\n\n// \"Extra\"\nconst myProgram1 = (word1: string, word2: string) => {\n  const formatWord1: string = word1.replace(/\\s/g, '').toLowerCase();\n  const formatWord2: string = word2.replace(/\\s/g, '').toLowerCase();\n\n  const isPalindrome = (word: string): boolean => {\n    const reversedWord = word.split('').reverse().join('');\n    return word === reversedWord;\n  };\n\n  const isAnagram = (word1: string, word2: string): boolean => {\n    const sortedWord1 = word1.split('').sort().join('');\n    const sortedWord2 = word2.split('').sort().join('');\n    return sortedWord1 === sortedWord2;\n  };\n\n  const isIsogram = (word: string): boolean => {\n    const charSet = new Set<string>(word);\n    return charSet.size === word.length;\n  };\n\n  if (isPalindrome(formatWord1) && isPalindrome(formatWord2)) {\n    console.log(`La palabra ${word1} y ${word2} son palíndromos.`);\n  } else if (isAnagram(formatWord1, formatWord2)) {\n    console.log(`La palabra ${word1} y ${word2} son anagramas.`);\n  } else if (isIsogram(formatWord1) && isIsogram(formatWord2)) {\n    console.log(`La palabra ${word1} y ${word2} son isogramas.`);\n  } else {\n    console.log('No son ni palíndromos ni anagramas ni isogramas.');\n  }\n};\n\nmyProgram('roma', 'amor');\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/typescript/victoriaparraf.ts",
    "content": "//Acceso a caracteres especificos\nlet cadena: string = \"Hola, mundo\";\nconsole.log(cadena[0]); // \"H\"\nconsole.log(cadena.charAt(1)); // \"o\"\n\n//Longitud\nlet longitud: number = cadena.length;\nconsole.log(longitud); // 11\n\n//Concatenacion\nlet cadena1: string = \"Hola, \";\nlet cadena2: string = \"mundo\";\nlet concatenado: string = cadena1 + cadena2;\nconsole.log(concatenado); // \"Hola, mundo\"\n\nlet concatenado2: string = cadena1.concat(cadena2);\nconsole.log(concatenado2); // \"Hola, mundo\"\n\n//Subcadenas\nlet subcadena1: string = cadena.slice(0, 4);\nconsole.log(subcadena1); // \"Hola\"\n\nlet subcadena2: string = cadena.substring(5, 10);\nconsole.log(subcadena2); // \"mundo\"\n\nlet subcadena3: string = cadena.substr(5, 5);\nconsole.log(subcadena3); // \"mundo\"\n\n//Repeticion\nlet repetida: string = \"abc\".repeat(3);\nconsole.log(repetida); // \"abcabcabc\"\n\n//Conversión a Mayúsculas y Minúsculas\nlet mayusculas: string = cadena.toUpperCase();\nconsole.log(mayusculas); // \"HOLA, MUNDO\"\n\nlet minusculas: string = cadena.toLowerCase();\nconsole.log(minusculas); // \"hola, mundo\"\n\n//Reemplazo\nlet reemplazada: string = cadena.replace(\"mundo\", \"TypeScript\");\nconsole.log(reemplazada); // \"Hola, TypeScript\"\n\n//Division\nlet partes: string[] = cadena.split(\", \");\nconsole.log(partes); // [\"Hola\", \"mundo\"]\n\n//Union\nlet unidas: string = partes.join(\" - \");\nconsole.log(unidas); // \"Hola - mundo\"\n\n//Interpolacion\nlet nombre: string = \"Victoria\";\nlet edad: number = 23;\nlet saludo: string = `Hola, mi nombre es ${nombre} y tengo ${edad} años`;\nconsole.log(saludo);\n\n//Verificacion de subcadena\nlet contiene: boolean = cadena.includes(\"mundo\");\nconsole.log(contiene); // true\n\nlet empieza: boolean = cadena.startsWith(\"Hola\");\nconsole.log(empieza); // true\n\nlet termina: boolean = cadena.endsWith(\"mundo\");\nconsole.log(termina); // true\n\n\n/***********************************************/\n/*EXTRA */\n\n//Funcion para saber si es palindromo\nfunction esPalindromo(palabra: string): boolean {\n    let palabraInvertida = palabra.split('').reverse().join('');\n    return palabra === palabraInvertida;\n}\n//Funcion para saber si es una anagrama\nfunction sonAnagramas(palabra1: string, palabra2: string): boolean {\n    let ordenarPalabra = (palabra: string) => palabra.toLowerCase().split('').sort().join('');\n    return ordenarPalabra(palabra1) === ordenarPalabra(palabra2);\n}\n//Funcion para comprobar si es isograma\nfunction esIsograma(palabra: string): boolean {\n    let letras = new Set();\n    for (let letra of palabra.toLowerCase()) {\n        if (letras.has(letra)) {\n            return false;\n        }\n        letras.add(letra);\n    }\n    return true;\n}\n//Funcion principal\n\nfunction analizarPalabras(palabra1: string, palabra2: string): void {\n    console.log(`Palabra 1: ${palabra1}`);\n    console.log(`Palabra 2: ${palabra2}`);\n    \n    console.log(`\"${palabra1}\" es palíndromo: ${esPalindromo(palabra1)}`);\n    console.log(`\"${palabra2}\" es palíndromo: ${esPalindromo(palabra2)}`);\n    \n    console.log(`\"${palabra1}\" y \"${palabra2}\" son anagramas: ${sonAnagramas(palabra1, palabra2)}`);\n    \n    console.log(`\"${palabra1}\" es isograma: ${esIsograma(palabra1)}`);\n    console.log(`\"${palabra2}\" es isograma: ${esIsograma(palabra2)}`);\n}\n\n// Ejemplo de uso\nlet palabra1 = \"amor\";\nlet palabra2 = \"roma\";\nanalizarPalabras(palabra1, palabra2);\n\n"
  },
  {
    "path": "Roadmap/04 - CADENAS DE CARACTERES/vb.net/kenysdev.vb",
    "content": "' ╔══════════════════════════════════════╗\n' ║ Autor:  Kenys Alvarado               ║\n' ║ GitHub: https://github.com/Kenysdev  ║\n' ║ 2024 -  VB.NET                       ║\n' ╚══════════════════════════════════════╝\n\n' Cadenas de Caracteres\n' ---------------------\nImports System.Text\n\nModule Program\n\n    Sub Main(args As String())\n        ' ________________________________________\n        ' Declaración e inicialización\n        Dim msg As String\n        Dim msg1 As String = \"\"\n        ' Tabulación horizontal.\n        Dim columns As String = \"Column 1\" & vbTab & \"Column 2\"\n        ' Salto de línea.\n        Dim rows As String = \"Row 1\" & vbCrLf & \"Row 2\"\n        Console.WriteLine(columns)\n        Console.WriteLine(rows)\n\n        ' ________________________________________\n        ' Longitud\n        Dim str1 As String = \"abcd\"\n        Dim length As Integer = str1.Length\n        Console.WriteLine(\"longitud: \" & length)\n\n        ' ________________________________________\n        ' Método Trim \n        Dim str2 As String = \"   str   \"\n        ' Eliminar los caracteres en blanco al inicio y al final.\n        Dim trim_str As String = str2.Trim()\n        Console.WriteLine(trim_str)\n        ' Eliminar al inicio.\n        Dim trim_start As String = str2.TrimStart()\n        Console.WriteLine(trim_start)\n        ' Eliminar al final.\n        Dim trim_end As String = str2.TrimEnd()\n        Console.WriteLine(trim_end)\n\n        ' ________________________________________\n        ' Extraer una parte de la cadena.\n        Dim str3 As String = \"Hello, world!\"\n        Dim newStr3 As String = str3.Substring(7, 5)\n        Console.WriteLine(newStr3) ' World\n\n        ' Eliminar una parte de la cadena.\n        Dim sb As New Text.StringBuilder(str3)\n        sb.Remove(7, 5)\n        Console.WriteLine(sb.ToString()) ' Hello, !\n\n        ' ________________________________________\n        ' Reemplazar un carácter por otro\n        Dim str4 As String = \"abc def\"\n        Dim newStr4 As String = str4.Replace(\"c\", \"C\")\n        Console.WriteLine(newStr4) ' abC def\n        newStr4 = str4.Replace(\"def\", \"DEF\")\n        Console.WriteLine(newStr4) ' abc DEF\n\n        ' ________________________________________\n        ' Mayúsculas\n        Dim str5 As String = \"abc\"\n        Dim newStr5 As String = str5.ToUpper()\n        Console.WriteLine(newStr5) ' ABC\n\n        ' ________________________________________\n        ' Minúsculas\n        Dim str6 As String = \"ABC\"\n        Dim newStr6 As String = str6.ToLower()\n        Console.WriteLine(newStr6) ' abc\n\n        ' ________________________________________\n        ' Concatenación\n        Dim str_a As String = \"a\"\n        Dim str_b As String = \"b\"\n        Dim int_r As Integer = 7\n        Dim combined_str As String\n        combined_str = str_a & \"-\" & str_b & \"=\" & int_r.ToString()\n        Console.WriteLine(combined_str) ' a-b=7\n\n        ' ________________________________________\n        ' Interpolación\n        Dim name As String = \"Ben\"\n        Dim age As Integer = 21\n        Console.WriteLine($\"Soy {name} y tengo {age} años.\")\n\n        ' ________________________________________\n        ' Acceso\n        Dim str7 As String = \"abcd\"\n        Dim endChar As Char = str7(3)\n        Console.WriteLine(endChar) ' d\n\n        ' verificación\n        Console.WriteLine(str7.Contains(\"bc\")) ' True\n\n        ' ________________________________________\n        ' Iterar\n        For Each c As Char In str7\n            Console.WriteLine(c)\n        Next\n\n        ' ________________________________________\n        ' Ejercicio:\n        ' Crea un programa que analice dos palabras diferentes y realice comprobaciones\n        ' para descubrir si son:\n        ' - Palíndromos (Igual ambas direcciones)\n        ' - Anagramas   (Reordenamiento de las letras de otra palabra)\n        ' - Isogramas   (No hay letras repetidas)\n\n        exs(\"reconocer\", \"vida\")\n        exs(\"notas\", \"santo\")\n        exs(\"héroe\", \"radar\")\n    End Sub\n\n    Sub exs(str1 As String, str2 As String)\n        Dim isAnagram As Boolean\n        isAnagram = str1.OrderBy(Function(c) c).SequenceEqual(str2.OrderBy(Function(c) c))\n\n        Console.WriteLine($\"\n    ________________________________________\n    \"\"{str1}\"\" es un palíndromo?: {str1 = New String(str1.Reverse().ToArray())}\n    \"\"{str2}\"\" es un palíndromo?: {str2 = New String(str2.Reverse().ToArray())}\n\n    \"\"{str1}\"\" es un anagrama de \"\"{str2}\"\"?: {isAnagram}\n\n    \"\"{str1}\"\" es un isograma?: {str1.Length = str1.Distinct().Count()}\n    \"\"{str2}\"\" es un isograma?: {str2.Length = str2.Distinct().Count()}\n    \")\n    End Sub\nEnd Module\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/arduino/santyjL.ino",
    "content": "/*\n#05 VALOR Y REFERENCIA\n\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n*/\nint a = 30;  // Variable por valor, contiene directamente el valor 30\nint b = a + 10;   \n\nint array_x[] = {1, 2, 3, 4, 5};  // Array por asignación, se guarda en memoria\nint array_y[6];  \n\nvoid copiarArray(int destino[], int fuente[], int longitud) {\n  for (int i = 0; i < longitud; i++) {\n    destino[i] = fuente[i];\n  }\n}\n\nint modificacion_valor(int valor) {\n  return valor + 10;\n}\n\nvoid modificacion_asignacion(int lista[]) {\n  // Se crea una nueva lista para evitar modificar la original fuera de la función\n  lista[5] = 7;\n}\n\nvoid verificacion(int x, int y) {\n  Serial.print(\"Verificación: \");\n  if (x == y) {\n    Serial.println(\"x es igual a y\");\n  } else {\n    Serial.println(\"x no es igual a y\");\n  }\n}\n\nvoid intercambio_valor(int a, int b, int& resultado_a, int& resultado_b) {\n  int a_temporal = a;\n  resultado_a = b;\n  resultado_b = a_temporal;\n}\n\nvoid intercambio_asignacion(int array_orig[], int array_dest[], int longitud) {\n  // Copiar el contenido de 'array_orig' a 'array_dest'\n  for (int i = 0; i < longitud; i++) {\n    array_dest[i] = array_orig[i];\n  }\n}\n\nvoid setup() {\n  Serial.begin(9600);\n\n  // Copiar el contenido de 'array_x' a 'array_y'\n  copiarArray(array_y, array_x, 5);\n\n  // Agregar un elemento a 'array_y'\n  array_y[5] = 6;\n\n  // Imprimir los valores originales y modificados\n  Serial.println(\"Original array_x:\");\n  for (int i = 0; i < 5; i++) {\n    Serial.print(array_x[i]);\n    Serial.print(\" \");\n  }\n  Serial.println();\n\n  Serial.println(\"Modificacion array_y:\");\n  for (int i = 0; i < 6; i++) {\n    Serial.print(array_y[i]);\n    Serial.print(\" \");\n  }\n  Serial.println();\n\n  // Modificar valor por valor\n  int resultado_mod_valor = modificacion_valor(a);\n  Serial.print(\"Resultado de modificacion_valor: \");\n  Serial.println(resultado_mod_valor);\n\n  // Modificar asignación\n  int resultado_mod_asignacion[7];\n  copiarArray(resultado_mod_asignacion, array_x, 5);\n  modificacion_asignacion(resultado_mod_asignacion);\n\n  Serial.print(\"Resultado de modificacion_asignacion: \");\n  for (int i = 0; i < 7; i++) {\n    Serial.print(resultado_mod_asignacion[i]);\n    Serial.print(\" \");\n  }\n  Serial.println();\n\n  // Verificación\n  verificacion(a, b);\n\n  // Intercambio de valores por valor\n  int resultado_intercambio_a, resultado_intercambio_b;\n  intercambio_valor(a, b, resultado_intercambio_a, resultado_intercambio_b);\n\n  Serial.println(\"Valores después de intercambio por valor:\");\n  Serial.print(\"a: \");\n  Serial.println(resultado_intercambio_a);\n  Serial.print(\"b: \");\n  Serial.println(resultado_intercambio_b);\n\n  // Intercambio de valores por asignación\n  int resultado_intercambio_asignacion[5];\n  intercambio_asignacion(array_x, resultado_intercambio_asignacion, 5);\n\n  Serial.println(\"Valores después de intercambio por asignación:\");\n  for (int i = 0; i < 5; i++) {\n    Serial.print(resultado_intercambio_asignacion[i]);\n    Serial.print(\" \");\n  }\n  Serial.println();\n}\n\nvoid loop() {\n\n}\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/c/N0HagoNada.c",
    "content": "#include <stdio.h>\n\n// Función para demostrar el paso de argumentos por valor\nvoid incrementarPorValor(int x)\n{\n    x++;\n    printf(\"Dentro de incrementarPorValor: %d\\n\", x); // Valor incrementado localmente\n}\n\n// Función para demostrar el paso de argumentos por referencia\nvoid incrementarPorReferencia(int *x)\n{\n    (*x)++;                                                 // deference\n    printf(\"Dentro de incrementarPorReferencia: %d\\n\", *x); // Valor incrementado en la variable original\n}\n// Función para intercambiar dos valores por referencia\nvoid intercambioPorReferencia(int *a, int *b)\n{\n    int temp = *a;\n    *a = *b;\n    *b = temp;\n}\n\nint main()\n{\n    // Asignación por valor\n    int a = 10;\n    int b = a;                                             // b ahora tiene una copia del valor de a\n    b = 20;                                                // Modificar b no afecta a a\n    printf(\"Asignación por valor - a: %d, b: %d\\n\", a, b); // a: 10, b: 20\n\n    // Asignación por referencia\n    int c = 30;\n    int *p = &c;                                                  // p apunta a la dirección de memoria de c\n    *p = 40;                                                      // Modificar el valor de *p cambia el valor de c\n    printf(\"Asignación por referencia - c: %d, *p: %d\\n\", c, *p); // c: 40, *p: 40\n\n    // Paso de argumentos a funciones por valor\n    int valor = 10;\n    printf(\"Antes de incrementarPorValor: %d\\n\", valor);\n    incrementarPorValor(valor);\n    printf(\"Después de incrementarPorValor: %d\\n\", valor); // El valor original no cambia\n\n    // Paso de argumentos a funciones por referencia\n    int referencia = 10;\n    printf(\"Antes de incrementarPorReferencia: %d\\n\", referencia);\n    incrementarPorReferencia(&referencia);\n    printf(\"Después de incrementarPorReferencia: %d\\n\", referencia); // El valor original cambia\n\n    /****************************************************RETO******************************************/\n    int x = 1, y = 2;\n    int nuevoX, nuevoY;\n\n    // Intercambio por referencia\n    nuevoX = x;\n    nuevoY = y;\n    intercambioPorReferencia(&nuevoX, &nuevoY);\n\n    printf(\"Original: x = %d, y = %d\\n\", x, y);\n    printf(\"Intercambio por referencia: nuevoX = %d, nuevoY = %d\\n\", nuevoX, nuevoY);\n\n    return 0;\n}"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/c/d1d4cum.c",
    "content": "#include <stdio.h>\n\n/*\n// Variables por valor\nint age1 = 28;\nprintf(\"Edad 1: %d\\n\", age1);\n\nint age2 = age1;\nprintf(\"Edad 2: %d\\n\", age1);\nage2 = 30;\nprintf(\"Edad 1: %d\\n\", age1);\nprintf(\"Edad 2: %d\\n\", age2);\n\n// Variables por referencia usando punteros\nint* age3 = &age1;\nprintf(\"Edad 1: %d\\n\", age1);\n*age3 = 45;\nprintf(\"Edad 1: %d\\n\", age1);\n*/\n\nint valor1 = 1;\nint valor2 = 2;\nint newValor1;\nint newValor2;\n\nvoid valor(int valor1, int valor2) {\n    int old1 = valor1;\n    int old2 = valor2;\n\n    valor2 = old1;\n    valor1 = old2;\n\n    newValor1 = valor1;\n    newValor2 = valor2;\n}\n\nvoid reference(int *valor1, int *valor2) {\n    int old1 = *valor1;\n    int old2 = *valor2;\n\n    *valor1 = old2;\n    *valor2 = old1;\n\n    newValor1 = *valor1;\n    newValor2 = *valor2;\n}\n\nint main() {\n    printf(\"**Paso por valor**\\n\");\n    valor(valor1, valor2);\n    printf(\"Valor 1 original: %d\\n\", valor1);\n    printf(\"Valor 2 original: %d\\n\", valor2);\n    printf(\"Valor 1 nuevo: %d\\n\", newValor1);\n    printf(\"Valor 2 nuevo: %d\\n\", newValor2);\n\n    printf(\"**Paso por referencia**\\n\");\n    reference(&valor1, &valor2);\n    printf(\"Valor 1 original: %d\\n\", valor1);\n    printf(\"Valor 2 original: %d\\n\", valor2);\n    printf(\"Valor 1 nuevo: %d\\n\", newValor1);\n    printf(\"Valor 2 nuevo: %d\\n\", newValor2);\n\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/c/jchavescaceres.c",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\n#include <stdio.h>\n\n/*\nExample of function with input parameter as value\n*/\nvoid functionAsValue (int inValue) {\n\n\tprintf (\"\tfunctionAsValue parametro entrada %d, \", inValue);\n\n\tinValue *= 2;\n\n\tprintf (\"parametro modificado %d\\n\", inValue);\n};\n\n/*\nExample of function with input parameter as reference.\nAcutally this concept doesn't exist in (C) as it does in C++ or ADA,\nbut it can be emulated using pointers\n*/\nvoid functionAsReference (int* inValue) {\n\n\tprintf (\"\tfunctionAsReference parametro entrada %d, \", *inValue);\n\n\t*inValue *= 2;\n\n\tprintf (\"parametro modificado %d\\n\", *inValue);\n};\n\ntypedef struct {\n\tint value1;\n\tint value2;\n} t_values;\n\n\nt_values swapAsValue (int value1, int value2) {\n\tt_values res = {0, 0};\n\tint aux = value2;\n\tvalue2 = value1;\n\tvalue1 = aux;\n\n\tres.value1 = value1;\n\tres.value2 = value2;\n\treturn res;\n}\n\nt_values swapAsReference (int* value1, int* value2) {\n\tt_values res = {0, 0};\n\tint aux = *value2;\n\t*value2 = *value1;\n\t*value1 = aux;\n\t\n\tres.value1 = *value1;\n\tres.value2 = *value2;\n\treturn res;\n\n}\n\n /*\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\nvoid extra() {\n\tint initValueAsValue1 = 1;\n\tint initValueAsValue2 = 2;\n\tt_values resValuesAsValue;\n\tint endtValueAsValue1 = initValueAsValue1;\n\tint endtValueAsValue2 = initValueAsValue2;\n\tint initValueAsReference1 = 3;\n\tint initValueAsReference2 = 4;\n\tt_values resValuesAsReference;\n\n\tprintf (\"Intercambio por valor: \\n\");\n\tprintf (\"\\tinitValue1 %d, initValue2 %d antes de llamar a función\\n\", initValueAsValue1, initValueAsValue2);\n\tresValuesAsValue = swapAsValue (initValueAsValue1, initValueAsValue2);\n\tprintf (\"\\tresValue1 %d, resValue2 %d despues de llamar a función\\n\", resValuesAsValue.value1, resValuesAsValue.value2);\n\tprintf (\"\\tinitValue1 %d, initValue2 %d despues de llamar a función\\n\", initValueAsValue1, initValueAsValue2);\n\n\tprintf (\"Intercambio por referencia: \\n\");\n\tprintf (\"\\tinitValue1 %d, initValue2 %d antes de llamar a función\\n\", initValueAsReference1, initValueAsReference2);\n\tresValuesAsReference = swapAsReference (&initValueAsReference1, &initValueAsReference2);\n\tprintf (\"\\tresValue1 %d, resValue2 %d despues de llamar a función\\n\", resValuesAsReference.value1, resValuesAsReference.value2);\n\tprintf (\"\\tinitValue1 %d, initValue2 %d despues de llamar a función\\n\", initValueAsReference1, initValueAsReference2);\n\n\n\n\n};\n\n\nvoid main () {\n\t\n\tint value = 2;\n\n\tprintf (\"Valor inicial : %d, llamamos a funcion pasando valor\\n\", value);\n\tfunctionAsValue (value);\n\tprintf (\"Valor nuevo : %d\\n\", value);\n\n\tprintf (\"Valor inicial : %d, llamamos a funcion pasando referncia\\n\", value);\n\tfunctionAsReference (&value);\n\tprintf (\"Valor nuevo : %d\\n\", value);\n\n\textra();\n\n};\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/c/srvariable.c",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y\n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\n#include <stdio.h>\n\nvoid unmodifier(int num);\nvoid modifier(int *num);\nint *swap_value(int num1, int num2);\nint *swap_reference(int *num1, int *num2);\n\nint main(void)\n{\n    /* === 1 === */\n    // Asignación por valor\n    // num es igual a 200 y another_num a\n    int num = 200;\n    int another_num = 20123;\n\n    // Asignación por referencia\n    // Puntero que apunta a una dirección de memoria\n    int *ptr_num = &num;\n\n    // Asignación por valor\n    // Puntero que\n    int *ptr_ptr = ptr_num;\n\n    /* === EXTRA === */\n    // Modificando num y another_num usando punteros\n    // que apuntan a sus referencias\n    printf(\"                        num    another_num    ptr_num    ptr_ptr\\n\");\n    printf(\"Original %18d %14d %10d %10d\\n\", num, another_num, *ptr_num, *ptr_ptr);\n    // Modifico num a 3\n    num = 3;\n    printf(\"Modifico num %14d %14d %10d %10d\\n\", num, another_num, *ptr_num, *ptr_ptr);\n    // Dereferencio ptr_num y le asigno 6\n    *ptr_num = 6;\n    printf(\"Modifico ptr_num %10d %14d %10d %10d\\n\", num, another_num, *ptr_num, *ptr_ptr);\n    // Dereferencio ptr_ptr y le asigno 27\n    *ptr_ptr = 27;\n    printf(\"Modifico ptr_ptr %10d %14d %10d %10d\\n\", num, another_num, *ptr_num, *ptr_ptr);\n    // Reasigno ptr_num a la dirección de memoria de another_num\n    ptr_num = &another_num;\n    printf(\"Reasigno ptr_num %10d %14d %10d %10d\\n\", num, another_num, *ptr_num, *ptr_ptr);\n    // Dereferencio ptr_num y le asigno 0\n    *ptr_num = 0;\n    printf(\"Modifico ptr_num %10d %14d %10d %10d\\n\", num, another_num, *ptr_num, *ptr_ptr);\n    *ptr_ptr = 89213;\n    printf(\"Modifico ptr_ptr %10d %14d %10d %10d\\n\", num, another_num, *ptr_num, *ptr_ptr);\n    // Reasigno ptr_num a la dirección de memoria de another_num\n    ptr_num = ptr_ptr;\n    printf(\"Reasigno ptr_num %10d %14d %10d %10d\\n\", num, another_num, *ptr_num, *ptr_ptr);\n    printf(\"\\n\\n\\n\");\n\n    /* === 2 === */\n    printf(\"Pre unmodifier: %d\\n\", num);\n    unmodifier(num);\n    printf(\"Post unmodifier: %d\\n\\n\", num);\n    printf(\"Pre modifier: %d\\n\", num);\n    modifier(&num);\n    printf(\"Post modifier: %d\\n\", num);\n    printf(\"\\n\\n\\n\");\n\n    /* === DIFICULTAD EXTRA === */\n    int num1 = 9;\n    int num2 = 6;\n    int *temp = NULL;\n    printf(\"                        num1    num2    temp[0]    temp[1]\\n\");\n    printf(\"Pre swap_value %13d %7d          ?          ?\\n\", num1, num2);\n    temp = swap_value(num1, num2);\n    printf(\"Post swap_value %12d %7d %10d %10d\\n\", num1, num2, temp[0], temp[1]);\n    printf(\"Pre swap_reference %9d %7d          ?          ?\\n\", num1, num2);\n    temp = swap_reference(&num1, &num2);\n    printf(\"Post swap_reference %8d %7d %10d %10d\\n\", num1, num2, temp[0], temp[1]);\n    return (0);\n}\n\nvoid modifier(int *num)\n{\n    printf(\"***Dentro de la función modifier\\n\");\n    printf(\"Valor de num: %d\\n\", *num);\n    *num = 123;\n    printf(\"***Modificando num...\\n\");\n    printf(\"Valor de num: %d\\n\", *num);\n    printf(\"***Saliendo de la función modifier\\n\");\n}\n\nvoid unmodifier(int num)\n{\n    printf(\"***Dentro de la función unmodifier\\n\");\n    printf(\"Valor de num: %d\\n\", num);\n    num = 123;\n    printf(\"***Modificando num...\\n\");\n    printf(\"Valor de num: %d\\n\", num);\n    printf(\"***Saliendo de la función unmodifier\\n\");\n}\n\nint *swap_value(int num1, int num2)\n{\n    int temp = num1;\n    num1 = num2;\n    num2 = temp;\n    int res[2] = {num1, num2};\n    int *ptr_res = res;\n    return (ptr_res);\n}\n\nint *swap_reference(int *num1, int *num2)\n{\n    int temp = *num1;\n    *num1 = *num2;\n    *num2 = temp;\n    int res[2] = {*num1, *num2};\n    int *ptr_res = res;\n    return (ptr_res);\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/c#/Andreavzqz.cs",
    "content": "using System:\n\nclass Program \n{\n    static void Main(string[] args)\n    {\n\n        //Asignacion por valor\n        int valor1 = 10;\n        int valor2 = valor1;\n        valor2 = 20;\n        console.WriteLine($\"Asignacion por: valor1 = {valor1}, valor2 = {valor2}   \")\n    \n\n        //Asignacion por referencia\n        int[] array1 = { 1, 2, 3 };\n        int[] array2 = array\n        array2 [0] = 10;\n        Console.WriteLine($\"Asignacion por referencia: array1[0] = {array1[0]}, array2[0] = {array2[0]}\")\n\n        //Funcion con parametro por valor\n        int numero = 5;\n        ModificarPorValor(numero);\n        Console.WriteLine($\"Despues de ModificarPorValor: numero = {numero}\");\n\n        // Función con parámetro por referencia\n        int numeroRef = 5;\n        ModificarPorReferencia(ref numeroRef);\n        Console.WriteLine($\"Después de ModificarPorReferencia: numeroRef = {numeroRef}\");\n\n        //Funcion con parametro de salida\n        int numeroOut;\n        Console.WriteLine($\"Despues de modificarPorSalida: numeroOut = {numeroOut}\");\n    }\n\n    static void ModificarPorValor(int num)\n    {\n        num = 10;\n        Console.WriteLine($\"Dentro de modificarPorValor: num = {num}\");\n    }\n\n    static void ModificarPorReferencia(ref int num)\n    {\n        num = 10;\n        Console.WriteLine($\"Dentro de modificarPorReferencia: num = {num}\");\n    }\n\n    static void modificarPorSalida(out int num)\n    {\n        num = 10;\n        Console.WriteLine($\"Dentro de ModificarPorSalida: num = {num}\");\n    }\n\n/*\n-Explicación\n\nAsignación por valor:\nSe crea una copia del valor y se asigna a la nueva variable. Modificar la nueva variable no afecta a la original.\n\nAsignación por referencia:\nSe asigna una referencia al mismo objeto en memoria. Modificar la nueva variable también afecta a la original.\n\nFunción con parámetro por valor:\nSe pasa una copia del valor a la función. Modificaciones dentro de la función no afectan a la variable original.\n\nFunción con parámetro por referencia:\nSe pasa una referencia a la variable original. Modificaciones dentro de la función afectan a la variable original.\n\nFunción con parámetro de salida:\nSimilar a la referencia, pero obliga a la función a asignar un valor antes de salir.\n\n-Ejecución del Código\n\nAsignación por valor:\nvalor1 y valor2 son independientes. Modificar valor2 no afecta a valor1.\n\nAsignación por referencia:\narray1 y array2 apuntan al mismo arreglo. Modificar array2[0] afecta a array1[0].\n\nFunciones:\nModificarPorValor modifica una copia, no afecta a numero.\nModificarPorReferencia modifica la variable original numeroRef.\nModificarPorSalida asigna un valor a numeroOut.\n*/\n\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/c#/Arkmiguel379.cs",
    "content": "﻿// ======= ASIGNACION POR VALOR =======\n\nConsole.WriteLine(\"=== ASIGNACION POR VALOR === \\n\");\n\nint x = 5;\nint y = x;\n\nConsole.WriteLine(x); // Salida: 5 (Valor de la variable original)\nConsole.WriteLine(y); // Salida: 5 (Es la copia de la variable original)\n\ny = 10;\n\nConsole.WriteLine(x); // Salida: 5 (La variable original no cambia)\nConsole.WriteLine(y); // Salida: 10 (El valor de la copia de la variable cambia sin afectar el valor de la variable original)\n\nConsole.WriteLine();\n\n// ==================================\n\nstring cadena = \"C Sharp\";\nstring cadena2 = cadena;\n\nConsole.WriteLine(cadena); // Salida: C Sharp (Valor de la variable original)\nConsole.WriteLine(cadena2); // Salida: C Sharp (Es la copia de la variable original)\n\nConsole.WriteLine();\n\ncadena2 = \"Python\";\n\nConsole.WriteLine(cadena); // Salida: C Sharp (La variable original no cambia)\nConsole.WriteLine(cadena2); // Salida: Python (El valor de la copia de la variable cambia sin afectar el valor de la variable original)\n\nConsole.WriteLine();\n\n\n// ======= ASIGNACION POR REFERENCIA =======\n\nConsole.WriteLine(\"=== ASIGNACION POR REFERENCIA === \\n\");\n\nint[] array1 = {1,2,3,4,5};\n\nint[] array2 = array1;\n\nforeach (var i in array1)\n{\n    Console.WriteLine(i); // Salida: 1 2 3 4 5 (Valores del arreglo original)\n}\n\nConsole.WriteLine();\n\nforeach (var i in array2) // Salida: 1 2 3 4 5 (Valores de la copia del arreglo original)\n{\n    Console.WriteLine(i);\n}\n\nConsole.WriteLine();\n\narray2[0] = 33; // Se cambia el valor del indice 0 de la copia del arreglo original\n\nforeach (var i in array1)\n{\n    Console.WriteLine(i); // Salida: 33 2 3 4 5 (El valor del indice 0 del arreglo original ha sido modificado\n}                         // a causa de la modificacion hecha en la copia)\n\nConsole.WriteLine();\n\nforeach (var i in array2)\n{\n    Console.WriteLine(i); // Salida: 33 2 3 4 5 (Valores del arreglo que se modificó directamente)\n}\n\nConsole.WriteLine();\n\n// =======================\n\nList<string> list = new List<string> {\"Lobo\", \"Koala\", \"Leopardo\", \"Caballo\"};\n\nConsole.WriteLine(\"Valores de la lista original \\n\");\n\nforeach (var i in list)  // Valores de la lista original\n{\n    Console.WriteLine(i);\n}\n\nConsole.WriteLine();\n\nList<string> list2 = list;\n\nConsole.WriteLine(\"Valores de la segunda lista, una copia de la primera \\n\");\n\nforeach (var i in list2) // Valores de la segunda lista, siendo esta una copia de la primera\n{\n    Console.WriteLine(i);\n}\n\nConsole.WriteLine();\n\nlist2[0] = \"Tiburon\";  // Se modifica el indice 0 de la segunda lista\n\nConsole.WriteLine(\"Valores de la segunda lista, modificando el indice 0 \\n\");\n\nforeach (var i in list2) // Valores de la segunda lista, con el indice 0 modificado directamente\n{\n    Console.WriteLine(i);\n}\n\nConsole.WriteLine();\n\nConsole.WriteLine(\"Valores de la lista original pero con el indice 0 modificado mediante la segunda lista \\n\");\n\nforeach (var i in list) // El indice 0 de la primera lista es afectado por la modificacion hecha a la segunda lista\n{\n    Console.WriteLine(i);\n}\n\nConsole.WriteLine();\n\n\n// ======= FUNCIONES CON PARAMETROS POR VALOR =======\n\nConsole.WriteLine(\"=== FUNCIONES CON PARAMETROS POR VALOR === \\n\");\n\nint z = 3;\n\nConsole.WriteLine($\"El valor de Z es: {z}\"); // Valor de la variable original\n\nValorIntModificado(z); // Funcion que modifica el valor de la variable e imprime su nuevo valor\n\nConsole.WriteLine($\"El valor de Z despues de la llamada de la funcion es: {z}\"); // Valor de la variable original despues de que la funcion\n                                                                                 // haya \"modificado su valor\"\n\nConsole.WriteLine();\n\n// =====================\n\nstring c = \"Hola mundo\"; \n\nConsole.WriteLine($\"El valor de C es: {c}\"); // Valor de la variable original\n\nValorStrModificado(c); // Funcion que modifica el valor de la variable e imprime su nuevo valor\n\nConsole.WriteLine($\"El valor de C despues de la llamada de la funcion es: {c}\"); // Valor de la variable original despues de que la funcion\n                                                                                 // haya \"modificado su valor\"\n\nConsole.WriteLine();\n\n\n// ======= FUNCIONES CON PARAMETROS POR REFERENCIA =======\n\nConsole.WriteLine(\"=== FUNCIONES CON PARAMETROS POR REFERENCIA === \\n\");\n\nList<int> ints = new List<int> {5, 6, 7, 8, 9};\n\nConsole.WriteLine(\"Los valores de la lista ints son: \\n\");\n\nforeach (int i in ints) // Valores de la lista original\n{\n    Console.WriteLine(i);\n}\n\nConsole.WriteLine();\n\nReferenciaIntModificada(ints, 0, 333); // Funcion que modifica el valor del indice indicado e imprime su nuevo valor\n\nConsole.WriteLine();\n\nforeach (int i in ints) // Valores de la lista original despues de la llamada de la funcion\n{\n    Console.WriteLine(i);\n}\n\nConsole.WriteLine();\n\n\n// ====== METODOS ======\nvoid ValorStrModificado(string parS)\n{\n    parS = \"Cadena Modificada\";\n    Console.WriteLine($\"El valor modificado del parametro es {parS}\");\n}\nvoid ValorIntModificado(int parI)\n{\n    parI = 9;\n    Console.WriteLine($\"El valor modificado del parametro es: {parI}\");\n};\n\nvoid ReferenciaIntModificada(List<int> parI, int indice, int newValue)\n{\n    parI[indice] = newValue;\n    Console.WriteLine($\"El nuevo valor del indice {indice} es: {parI[indice]}\");\n}\n\n\n// ===== EXTRA =====\n\n// Programa de parametros por valor\n\nint var1 = 3;\nint var2 = 9;\n\nvar retorno = ProgramValue(var1, var2);\n\nint varD1 = retorno.Item1;\nint varD2 = retorno.Item2;\n\nConsole.WriteLine($\"El valor de var1 es: {var1}\");\nConsole.WriteLine($\"El valor de var2 es: {var2}\");\nConsole.WriteLine();\nConsole.WriteLine($\"El valor de varD1 es: {varD1}\");\nConsole.WriteLine($\"El valor de varD2 es: {varD2}\");\n\nConsole.WriteLine();\n\n// Programa de parametros por referencia\n\nList<string> lista1 = new List<string> {\"Bicicleta\", \"Moto\", \"Carro\",\"Avion\"};\n\nList<string> lista2 = new List<string> { \"Gato\", \"Perro\", \"Leopardo\", \"Aguila\" };\n\nvar returnStr = ProgramParameter(lista1[0], lista2[3]);\n\nstring strD1 = returnStr.Item1;\nstring strD2 = returnStr.Item2;\n\nConsole.WriteLine($\"El valor del indice lista1[0] que antes era {lista1[0]} ahora es {strD1}\");\nConsole.WriteLine($\"El valor del indice lista2[3] que antes era {lista2[3]} ahora es {strD2}\");\n\n// =====================================\n\n\n(int, int) ProgramValue(int parameter1, int parameter2)\n{\n    int store = parameter1;\n    parameter1 = parameter2;\n    parameter2 = store;\n\n    return (parameter1, parameter2);\n}\n\n(string, string) ProgramParameter(string parameter1, string parameter2)\n{\n    string store = parameter1;\n    parameter1 = parameter2;\n    parameter2 = store;\n\n    return (parameter1, parameter2);\n}"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/c#/Isj-code.cs",
    "content": "﻿// En los tipo de datos primitivos la asignacion es por valor\n\nint a = 10;\nint a1 = a;\na1 = 11;\n\nConsole.WriteLine($\"El valor de a es: {a}, el valor de a1 es: {a1}\");\n\nstring palabraUno = \"Uno\";\nstring palabraDos = palabraUno;\npalabraDos += \", dos\";\n\nConsole.WriteLine($\"La palabra uno es {palabraUno} y la palabra 2 es  {palabraDos}\");\n\n// En los tipos compuestos es por referencia\n\nint[] numeros = {1,2,3,4,5};\nint[] numeros2 = numeros;\n\nConsole.Write(\"El array numeros es: \");\nforeach (var item in numeros)\n{\n    Console.Write($\"{item} \");\n}\n\nConsole.WriteLine(\"\");\nConsole.WriteLine(\"Asignamos numeros2 = numeros1 y cambiamos la posicion 0 por el numero 0\");\nnumeros2[0] = 0;\n\nConsole.Write(\"Ahora el array numeros es: \");\nforeach (var item in numeros)\n{\n    Console.Write($\"{item} \");\n}\n\n// Funciones con parametro por Valor\n\nvoid FuncionPorValor(int numA)\n{\n    numA++;\n    Console.WriteLine($\"la variable global dentro a vale {numA}\");\n}\n\nFuncionPorValor(a);\nConsole.WriteLine($\"Despues de pasar por la funcion a vale {a}\");\n\n// Funcion con parametro por referencia\n\nList<int> listaNumeros = [1,2,3,4,5];\nConsole.WriteLine(\"Lista de numero original\");\nforeach (var item in listaNumeros)\n{\n    Console.Write($\"{item} \");\n}\n\nvoid FuncionPorReferencia(List<int> lista)\n{\n    for (int i = 0; i < lista.Count; i++)\n    {\n        lista[i] = lista[i] * 5;\n    }\n}\n\nFuncionPorReferencia(listaNumeros);\n// Transformamos la lista\n\nConsole.WriteLine(\"\");\nConsole.WriteLine(\"Despues de multiplicar x 5\");\nforeach (var item in listaNumeros)\n{\n    Console.Write($\"{item} \");\n}\n\n// ## Dificultad Extra\nConsole.WriteLine(\"\");\nint datoA = 5;\nint datoB = 10;\n\nConsole.WriteLine($\"Dato A original: {datoA}\");\nConsole.WriteLine($\"Dato B original: {datoB}\");\n\nint[] FuncionParaValor(int a1, int b1)\n{\n    int x = b1;\n    b1 = a1;\n    a1 = x;\n\n    return [a1, b1];\n}\n\nint[] resp = FuncionParaValor(datoA, datoB);\n\nConsole.WriteLine($\"Dato A devuelto por la funcion: {resp[0]}\");\nConsole.WriteLine($\"Dato B devuelto por la funcion: {resp[1]}\");\nConsole.WriteLine($\"Dato A original: {datoA}\");\nConsole.WriteLine($\"Dato B original: {datoB}\");\n\nint[] numerosA = [1,2];\nint[] numerosB = [3,4];\n\nConsole.WriteLine($\"La primera dupla original es {numerosA[0]} y {numerosA[1]}\");\nConsole.WriteLine($\"La segunda dupla original es {numerosB[0]} y {numerosB[1]}\");\n\nint[][] FuncionParaReferencia(int[] a1, int[] b1)\n{\n    int[] x = b1;\n    b1 = a1;\n    a1 = x;\n\n    return [a1, b1];\n}\n\nint[][] numerosDevueltos = FuncionParaReferencia(numerosA, numerosB);\nConsole.WriteLine($\"Los numeros devueltos en la primera dupla son {numerosDevueltos[0][0]} y {numerosDevueltos[0][1]}\"); \nConsole.WriteLine($\"Los numeros devueltos en la segunda dupla son {numerosDevueltos[1][0]} y {numerosDevueltos[1][1]}\");\n\nConsole.WriteLine($\"La primera dupla original es {numerosA[0]} y {numerosA[1]}\");\nConsole.WriteLine($\"La segunda dupla original es {numerosB[0]} y {numerosB[1]}\");"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/c#/JoseEsmil04.cs",
    "content": "\n\nnamespace _05_Valor_Referencia\n{\n\tclass Program\n\t{\n\t\tstatic void Main(string[] args)\n\t\t{\n\t\t\t// Asignacion de Variables por valor\n\t\t\tint a = 10;\n\t\t\tint b = a;\n\t\t\tb = 50;\n\n\t\t\tConsole.WriteLine($\"a sigue siendo {a} y b ahora es {b}\");\n\n\t\t\tstring nombre = \"JoseEsmil\";\n\t\t\tstring nombre2 = nombre;\n\t\t\tnombre2 = \"Jose\";\n\n\t\t\tConsole.WriteLine($\"nombre: {nombre} | nombre2: {nombre2}\");\n\n\t\t\t// Asignacion de Variables por referencia\n\t\t\tVehiculo honda1 = new() { Marca = \"Honda\", Modelo = \"Civic\" };\n\t\t\tVehiculo honda2 = honda1;\n\t\t\thonda2.Modelo = \"Accord\";\n\n\t\t\tConsole.WriteLine($\"honda1.Modelo: { honda1.Modelo } | honda2.Modelo: {honda2.Modelo}\");\n\n\t\t\tint[] numeros = { 1, 2, 3, 4, 5, 6, 7 };\n\t\t\tint[] numeros2 = numeros;\n\t\t\tnumeros2[0] = 545;\n\n\t\t\tConsole.WriteLine($\"Se modifico el numeros[0] por referencia {string.Join(',', numeros)}\");\n\n\n\t\t\t// Funcion por Valor\n\t\t\tint num1 = 50;\n\t\t\tFuncionPorValor(num1);\n\n\t\t\tConsole.WriteLine($\"El valor de la variable num1 sigue igual {num1}\");\n\n\t\t\t// Funcion Por referencia\n\t\t\tint num2 = 45;\n\t\t\tFuncionPorReferencia(ref num2);\n\n\t\t\tConsole.WriteLine($\"El valor de num2 ahora cambia a {num2}\");\n\n\n\t\t\t/***** Ejercicios Extra ***/\n\n\t\t\t// Intercambio por valor\n\t\t\tint num3 = 5, num4 = 10;\n\t\t\tIntercambios.PorValor(num3, num4, out int nuevoNum3, out int nuevoNum4); // (out) para crear nuevas Variables\n\n\t\t\tConsole.WriteLine($\"Originales: num3 = {a}, num4 = {num4}\"); // Originales: a = 5, b = 10\"\n\t\t\tConsole.WriteLine($\"Nuevos: nuevoNum3 = {nuevoNum3}, nuevoNum4 = {nuevoNum4}\"); // Se crean dos variables con los valores intercambiados\n\n\n\t\t\t// Intercambio por referencia\n\t\t\tint num5 = 12, num6 = 6;\n\t\t\tIntercambios.PorReferencia(ref num5, ref num6); // (ref) para cambiar valores por referencia\n\n\t\t\tConsole.WriteLine($\"Originales: num5: {num5}, num6: {num6}\"); // Originales: num5 ahora es 12 y num6 es 6\n\t\t\tConsole.WriteLine($\"Intercambiados: num5: {num5}, num6: {num6}\"); // Intercambiados: Igual por la referencia\n\t\t}\n\n\t\tclass Vehiculo\n\t\t{\n\t\t\tpublic string Marca { get; set; }\n\t\t\tpublic string Modelo { get; set; }\n\t\t}\n\n\t\tstatic void FuncionPorValor(int num1)\n\t\t{\n\t\t\tnum1 += 50;\n\t\t}\n\n\t\tstatic void FuncionPorReferencia(ref int num2)\n\t\t{\n\t\t\tnum2 += 45;\n\t\t}\n\n\n\t\tclass Intercambios\n\t\t{\n\t\t\tpublic static void PorValor(int num3, int num4, out int nuevoNum3, out int nuevoNum4)\n\t\t\t{\n\t\t\t\tint temporal = num3;\n\t\t\t\tnum3 = num4;\n\t\t\t\tnum4 = temporal;\n\t\t\t\tnuevoNum3 = num3;\n\t\t\t\tnuevoNum4 = num4;\n\t\t\t}\n\n\t\t\tpublic static void PorReferencia(ref int num5, ref int num6)\n\t\t\t{\n\t\t\t\tint temporal = num5;\n\t\t\t\tnum5 = num6;\n\t\t\t\tnum6 = temporal;\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/c#/RXVLC.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace R05___2024\n{\n    internal class Program\n    {\n        //Dificultad adicional:\n        //Para el valor lo realizo con tupla, podría hacerlo con listas también.\n        static (int, int) IntercambiarValoresPorValor(int a, int b)\n        {\n            return (b, a);\n        }\n\n        static void IntercambiarValoresPorReferencia(ref int a, ref int b)\n        {\n            int temp = a;\n            a = b;\n            b = temp;\n        }\n        //Fin de dificultad adicional.\n\n        static void ModificarValorReferencia(ref int valor)\n        {\n            valor = 0; // Modifica el valor proporcionado a 0\n        }\n\n        static int ModificarValorValor(int  valor)\n        {\n            return valor = valor + 1;\n        }\n\n        static void Main(string[] args)\n        {\n            //Por valor:\n            int a = 10;\n            int b = a; // Asignación por valor\n\n            Console.WriteLine($\"\\nOriginal: a = {a}, b = {b}\");\n\n            b = 20; // Modificando b no afecta a\n            Console.WriteLine($\"\\nDespués de modificar b: a = {a}, b = {b}\");\n\n            int x = 10;\n\n            Console.WriteLine($\"\\nAntes de llamar a ModificarValorReferencia: a = {x}\");\n            ModificarValorReferencia(ref x);\n            Console.WriteLine($\"\\nDespués de llamar a ModificarValorReferencia: a = {x}\");\n\n            int v = 10;\n            Console.WriteLine($\"\\nAntes de llamar a ModificarValorValor: v = {v}\");\n            v = ModificarValorValor(v);\n            Console.WriteLine($\"\\nDespués de llamar a ModificarValorValor: v = {v}\");\n\n            //Dificultad Adicional:\n\n\n            Console.WriteLine(\"\\nPor valor: \");\n\n            // Por valor:\n            int originalA = 10;\n            int originalB = 20;\n\n            Console.WriteLine($\"\\nValores originales: originalA = {originalA}, originalB = {originalB}\");\n\n            (int nuevoAValor, int nuevoBValor) = IntercambiarValoresPorValor(originalA, originalB);\n\n            Console.WriteLine($\"\\nDespués de intercambiar por valor: originalA = {originalA}, originalB = {originalB}\");\n            Console.WriteLine($\"\\nNuevos valores: nuevoA = {nuevoAValor}, nuevoB = {nuevoBValor}\");\n\n            Console.WriteLine(\"\\nPor Referencia: \");\n\n            // Por referencia:\n            int originalARef = 10;\n            int originalBRef = 20;\n            int antiguaOriginalARef = originalARef;\n            int antiguaOriginalBRef = originalBRef;\n\n            Console.WriteLine($\"\\nValores originales: originalA = {originalARef}, originalB = {originalBRef}\");\n\n            IntercambiarValoresPorReferencia(ref originalARef, ref originalBRef);\n\n            Console.WriteLine($\"\\nDespués de intercambiar por referencia: originalA = {originalARef}, originalB = {originalBRef}\");\n            Console.WriteLine($\"\\nVariables antiguas: originalAAntigua = {antiguaOriginalARef}, originalBAntigua = {antiguaOriginalBRef}\");\n\n\n            Console.ReadKey();\n        }\n    }\n    }\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/c#/XPERIARGLUNA.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nclass Persona\n{\n    public string Nombre;\n}\n\nclass Program\n{\n    // -------- FUNCIONES PARA COMPROBAR PASO POR VALOR Y REFERENCIA --------\n\n    static void CambiarValor(int x)\n    {\n        x = 999;\n        Console.WriteLine($\"Dentro de CambiarValor: x = {x}\");\n    }\n\n    static void CambiarPorReferencia(ref int x)\n    {\n        x = 888;\n        Console.WriteLine($\"Dentro de CambiarPorReferencia: x = {x}\");\n    }\n\n    static void CambiarNombrePersona(Persona p)\n    {\n        p.Nombre = \"Juan\";\n        Console.WriteLine($\"Dentro de CambiarNombrePersona: p.Nombre = {p.Nombre}\");\n    }\n\n    // -------- FUNCIONES PARA INTERCAMBIAR VALORES --------\n\n    static (int, int) IntercambiarPorValor(int a, int b)\n    {\n        int temp = a;\n        a = b;\n        b = temp;\n        return (a, b);\n    }\n\n    static void IntercambiarPorReferencia(ref int a, ref int b)\n    {\n        int temp = a;\n        a = b;\n        b = temp;\n    }\n\n    // -------- MAIN --------\n\n    static void Main(string[] args)\n    {\n        // -------- ASIGNACIÓN POR VALOR --------\n        int a = 10;\n        int b = a;\n        b = 20;\n        Console.WriteLine(\"== Asignación por VALOR ==\");\n        Console.WriteLine($\"a = {a}, b = {b}\\n\");\n\n        // -------- ASIGNACIÓN POR REFERENCIA --------\n        int[] array1 = { 1, 2, 3 };\n        int[] array2 = array1;\n        array2[0] = 99;\n        Console.WriteLine(\"== Asignación por REFERENCIA ==\");\n        Console.WriteLine($\"array1[0] = {array1[0]}, array2[0] = {array2[0]}\\n\");\n\n        // -------- FUNCIONES: PASO POR VALOR --------\n        int valor = 100;\n        CambiarValor(valor);\n        Console.WriteLine($\"Después de CambiarValor: valor = {valor}\\n\");\n\n        // -------- FUNCIONES: PASO POR REFERENCIA --------\n        int refValor = 100;\n        CambiarPorReferencia(ref refValor);\n        Console.WriteLine($\"Después de CambiarPorReferencia: refValor = {refValor}\\n\");\n\n        // -------- FUNCIONES: OBJETOS PASADOS POR VALOR (REFERENCIA INTERNA) --------\n        Persona persona = new Persona();\n        persona.Nombre = \"Ana\";\n        CambiarNombrePersona(persona);\n        Console.WriteLine($\"Después de CambiarNombrePersona: persona.Nombre = {persona.Nombre}\\n\");\n\n        // -------- INTERCAMBIO POR VALOR --------\n        int a1 = 5;\n        int b1 = 10;\n        var (nuevoA1, nuevoB1) = IntercambiarPorValor(a1, b1);\n\n        Console.WriteLine(\"== Intercambio por VALOR ==\");\n        Console.WriteLine($\"Originales: a1 = {a1}, b1 = {b1}\");\n        Console.WriteLine($\"Nuevas: nuevoA1 = {nuevoA1}, nuevoB1 = {nuevoB1}\\n\");\n\n        // -------- INTERCAMBIO POR REFERENCIA --------\n        int a2 = 15;\n        int b2 = 30;\n        int copiaA2 = a2;\n        int copiaB2 = b2;\n\n        IntercambiarPorReferencia(ref a2, ref b2);\n        int nuevoA2 = a2;\n        int nuevoB2 = b2;\n\n        Console.WriteLine(\"== Intercambio por REFERENCIA ==\");\n        Console.WriteLine($\"Originales antes: copiaA2 = {copiaA2}, copiaB2 = {copiaB2}\");\n        Console.WriteLine($\"Nuevas (modificadas): nuevoA2 = {nuevoA2}, nuevoB2 = {nuevoB2}\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/c#/abrahamraies.cs",
    "content": "// Author: Abraham Raies https://github.com/abrahamraies\n\n/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\nusing System;\nusing System.Collections.Generic;\n\nclass Program {\n    static void Main(string[] args){\n        Console.WriteLine(\"=== ASIGNACION POR VALOR === \\n\");\n\n        int a = 10;\n        int b = a;\n\n        b += 5;\n        Console.WriteLine(a);\n        Console.WriteLine(b); // El valor de a no se ve afectado por la modificacion de a.\n\n        Console.WriteLine(\"=== ASIGNACION POR REFERENCIA === \\n\");\n\n        int[] array1 = {1,2,3};\n        int[] array2 = array1;\n\n        array2[0] = 10;\n\n        Console.WriteLine(array1[0]); // Salida: 10 (El valor del arreglo original se ve afectado por la modificacion de la copia del arreglo original)\n        Console.WriteLine(array2[0]); // Salida: 10 (El valor de la copia del arreglo original se ve afectado por la modificacion de la copia del arreglo original)\n\n        Console.WriteLine(\"=== FUNCIONES CON PARAMETROS POR VALOR === \\n\");\n\n        int y = 10;\n        FuncionPorValor(y);\n        Console.WriteLine(y); // Salida: 10 (El valor de y no se ve afectado por la modificacion de y)\n\n        Console.WriteLine(\"=== FUNCIONES CON PARAMETROS POR REFERENCIA === \\n\");\n\n        List<int> lista = new List<int> {1,2,3};\n        AgregarElemento(lista);\n        Console.WriteLine(lista[3]); // Salida: 4 (El valor de la lista se ve afectado por la modificacion de la lista)\n\n        int x = 10;\n        FuncionPorReferencia(ref x);\n        Console.WriteLine(x); // Salida: 15 (El valor de x se ve afectado por la modificacion de x)\n\n        ObtenerValores(out int valor1, out int valor2); // Out: se usa para indicar que el valor de la variable se va a modificar dentro de la funcion.\n        Console.WriteLine(valor1); // Salida: 10\n        Console.WriteLine(valor2); // Salida: 20\n\n        Console.WriteLine(\"=== EJERCICIO EXTRA === \\n\");\n\n\n        Console.WriteLine(\"=== FUNCION CON PARAMETROS POR VALOR === \\n\");\n        int var1 = 10;\n        int var2 = 20;\n\n        int nuevo1,nuevo2;\n\n        IntercambiarPorValor(var1, var2, out nuevo1, out nuevo2);\n        Console.WriteLine(\"Originales: a = {0}, b = {1}\", var1, var2);\n        Console.WriteLine(\"Intercambiados: nuevo1 = {0}, nuevo2 = {1}\", nuevo1, nuevo2);\n\n        Console.WriteLine(\"=== FUNCION CON PARAMETROS POR REFERENCIA === \\n\");\n        int var3 = 5;\n        int var4 = 10;\n\n        int original3 = var3;\n        int original4 = var4;\n\n        IntercambiarPorReferencia(ref var3, ref var4);\n        Console.WriteLine(\"Originales: original3 = {0}, original4 = {1}\", original3, original4);\n        Console.WriteLine(\"Intercambiados: var3 = {0}, var4 = {1}\", var3, var4);\n        \n    }\n\n    static void FuncionPorValor(int a){\n        a += 5;\n    }\n\n    static void FuncionPorReferencia(ref int a){\n        a += 5;\n    }\n\n    static void ObtenerValores(out int a, out int b){\n        a = 10;\n        b = 20;\n    }\n\n    static void AgregarElemento(List<int> lista){\n        lista.Add(4);\n    }\n\n    // Función que intercambia dos valores pasados por valor\n    static void IntercambiarPorValor(int x, int y, out int nuevoX, out int nuevoY)\n    {\n        nuevoX = y;\n        nuevoY = x;\n    }\n\n    // Función que intercambia dos valores pasados por referencia\n    static void IntercambiarPorReferencia(ref int x, ref int y)\n    {\n        int temp = x;\n        x = y;\n        y = temp;\n    }\n\n}"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/c#/charlerodriguez3.cs",
    "content": "//*EJERCICIO:\n// *-Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n// *   su tipo de dato.\n// * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n// *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n// * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n\n\n/*\n*DIFICULTAD EXTRA(opcional):\n *Crea dos programas que reciban dos parámetros (cada uno) definidos como\n * variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime\n *   el valor de las variables originales y las nuevas, comprobando que se ha invertido\n *   su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\n//ejemplo Asignaciones por valor // solo cambia su valor en el contexto actual\n\n//tipos como int, float, double, entre otros. Son tipos de variable x valor\n\nint num1 = 3;\nfloat num2 = 20.5f;\nConsole.WriteLine($\"Valores actuales antes del metodo:  Numero {num1} y Flotante: {num2}\\n\");\n\n(int numNuevo, float floatNuevo) = CambiarParametrosPorValor(num1, num2);\n\nConsole.WriteLine($\"Valores despues del metodo:  Numero {numNuevo} y FlotanteNuevo: {floatNuevo}\\n\");\n\n\n\n//ejemplo Asignacion por referencia, cambia su valor a pesar de modificarse en otro metodo o contexto\n\n// tipos como arrays, objects, list, string(Array char), entre otros.Son tipos de variable x referencia\nstring palabra = \"hola\";\nint[] numeros = new int[]{ 1, 2, 3, 4, 5 };\nConsole.WriteLine($\"Valores actuales antes del metodo:  Palabra {palabra} y Arreglo:\\n\");\nforeach(int num in numeros)\n{\n    Console.Write(\" \"+num);\n}\n\nConsole.WriteLine(\"\");\n//ALERT! :\n//Aqui se esta utilizando variables de referencia pero no se estan pasando por referencia\n(string palabraNueva, int[] arregloInvertido) = CambiarParametrosPorReferencia(palabra, numeros); \n\n\nConsole.WriteLine($\"Valores despues del metodo:  Palabra {palabraNueva} y Arreglo:\\n\");\nforeach (int num in arregloInvertido)\n{\n    Console.Write(\" \" + num);\n}\nConsole.WriteLine(\"\");\n\n\n(string palabraNueva2, int[] arregloInvertido2) = CambiarParametrosPorReferencia2(ref palabra,ref numeros);\n\nConsole.WriteLine($\"Valores despues del metodo POR REFERENCIA LAS VARAIBLES:  Palabra {palabraNueva2} y Arreglo:\\n\");\nforeach (int num in arregloInvertido2)\n{\n    Console.Write(\" \" + num);\n}\nConsole.WriteLine(\"\");\n\n\nstatic (int, float) CambiarParametrosPorValor(int valor1, float valor2)\n{\n    valor1 += 100;\n    valor2 /= 4;\n\n    return (valor1,valor2);\n}\nstatic (string, int[]) CambiarParametrosPorReferencia(string valor1 , int[] valor2)//Al ser por referencia solo se modifican en su contexto del metodo y no en el global\n{\n    valor1.Reverse();//Invertir la palabra\n    valor2.Reverse();//Invertir la secuencia de numeros en el array\n\n\n    return (valor1, valor2);\n}\n\nstatic (string, int[]) CambiarParametrosPorReferencia2(ref string valor1 , ref int[] valor2)//Al utilizar la palabra reservada out o ref, estos tipos de variables por referencia\n{//al modificarlos en un contexto menor como un metodo, tambien modifican su valor en el global\n    valor1 = new string(valor1.Reverse().ToArray());//Invertir la palabra\n    Array.Reverse(valor2);//Invertir la secuencia de numeros en el array\n    return (valor1, valor2);\n}"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/c#/devcherry1.cs",
    "content": "/*\n * *** #05 - C# VALOR Y REFERENCIA  ***\n * \n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n */\n\nusing System;\n\nclass Program\n{\n    static void Main()\n    {\n        string ejem1 = \"esta es una variable por valor\";\n        ejem1 = caps(ejem1);\n        Console.WriteLine(ejem1);\n        string ejem2 = \"esta es una variable por referencia\";\n        toCaps(ref ejem2);\n        Console.WriteLine(ejem2);\n\n        //***Extra***\n        string chicaUno = \"Rachel\";\n        string chicaDos = \"Phoebe\";\n        (string chicaIntercambiada1, string chicaIntercambiada2) = Extra.Chicas(chicaUno,chicaDos);\n        Console.WriteLine($\"Nombres originales: {chicaUno} {chicaDos}\" +\n                          $\"\\nNombres intercambiados: {chicaIntercambiada1} {chicaIntercambiada2}\");\n        \n        string chicoUno = \"Ross\";\n        string chicoDos = \"Joey\";\n        (string chicoIntercambiado1, string chicoIntercambiado2) = Extra.Chicos(ref chicoUno, ref chicoDos);\n        Console.WriteLine($\"Nombres originales: {chicoUno} {chicoDos}\" +\n                          $\"\\nNombres intercambiados: {chicoIntercambiado1} {chicoIntercambiado2}\");\n    }\n    static string caps(string cadena)\n    {\n        string cadenaCaps = cadena.ToUpper();\n        return cadenaCaps;\n    }\n    static void toCaps(ref string cadena)\n    {\n        cadena = cadena.ToUpper();\n    }\n}\n /* DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como\n * variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime\n *   el valor de las variables originales y las nuevas, comprobando que se ha invertido\n *   su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\nclass Extra\n{\n    public static (string, string) Chicas(string persona1, string persona2)\n    {\n        return (persona2, persona1);\n    }\n    public static (string, string) Chicos(ref string persona1, ref string persona2)\n    {\n        return (persona2, persona1);\n    }\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/c#/estuardodev.cs",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\nusing System.Runtime.CompilerServices;\nusing System;\n\nnamespace estuardodev\n{\n    class Program\n    {\n        private static void Main(string[] args)\n        {\n            int valor1 = 3;\n            int valor2 = valor1;\n\n            valor2 += 2;\n\n            Console.WriteLine(\"Valor 1: \" + valor1);\n            Console.WriteLine(\"Valor 2: \" + valor2);\n\n            List<string> strings = new List<string>{\n                \"Python\",\n                \"C#\",\n                \"Java\"\n            };\n\n            List<string> strings2 = strings;\n\n            strings2.Add(\"C++\");\n\n            foreach(String i in strings)\n            {\n                Console.WriteLine(\"Valores de Strings 1: \" + i);\n            }\n\n            foreach (String i in strings2)\n            {\n                Console.WriteLine(\"Valores de Strings 2: \" + i);\n            }\n\n            Valor(5, 10);\n\n            List<string> lista1 = new List<string>{\n                \"C#\"\n            };\n            List<string> lista2 = new List<string>{\n                \"Python\"\n            };\n            Referencia(lista1, lista2);\n\n        }\n\n        private static void Valor(int val1, int val2)\n        {\n            int valor = val1;\n            val1 = val2;\n            val2 = valor;\n\n            Console.WriteLine(\"Valor del parámetro 1: \" + val1);\n            Console.WriteLine(\"Valor del parámetro 2: \" + val2);\n        }\n\n        private static void Referencia(List<string> lista1, List<string> lista2)\n        {\n            List<string> refuerzo = lista1;\n            lista1 = lista2;\n            lista2 = refuerzo;\n            lista1.Add(\"Lista 1\");\n            lista2.Add(\"Lista 2\");\n\n            foreach(string s in lista1)\n            {\n                Console.WriteLine(\"Valor lista 1: \" + s);\n            }\n            foreach (string s in lista2)\n            {\n                Console.WriteLine(\"Valor lista 2: \" + s);\n            }\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/c#/isaacus98.cs",
    "content": "﻿/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\nnamespace RetosProgramacion2024\n{\n    internal class Reto5\n    {\n        static void Main(string[] args)\n        {\n            // Variable por valor\n            int numero = 1;\n            Console.WriteLine(numero);\n\n            FuncionPorValor(numero);\n            Console.WriteLine(numero);\n\n            // Variable por referencia\n            int numero2 = 2;\n            // La variable numeroRef hace referencia a la variable numero2.\n            // Si se añade un valor a la variable de referencia se canviara el valor en la variable referenciada\n            ref int numeroRef = ref numero2;\n            Console.WriteLine(numeroRef);\n            numeroRef = 4;\n            Console.WriteLine(numeroRef);\n            numero2 = 5;\n            Console.WriteLine(numeroRef);\n\n            FuncionPorReferencia(ref numero2);\n            Console.WriteLine(numero2);\n\n            // Reto extra\n            Console.WriteLine(\"\\nReto Extra\\n\");\n\n            string str1 = \"str1\";\n            Console.WriteLine($\"Valor original de str1 {str1}\");\n            string str2 = \"str2\";\n            Console.WriteLine($\"Valor original de str2 {str2}\");\n            string respStr1;\n            string respStr2;\n            string[] str1Array = IntercambiarValores(str1, str2);\n            respStr1 = str1Array[0];\n            respStr2 = str1Array[1];\n            Console.WriteLine($\"Valor de la nueva variable respStr1 {respStr1}\");\n            Console.WriteLine($\"Valor de la nueva variable respStr2 {respStr2}\");\n            Console.WriteLine($\"Valor de str1 despues de llamar la función {str1}\");\n            Console.WriteLine($\"Valor de str2 despues de llamar la función {str2}\");\n\n\n            Console.WriteLine();\n            Console.WriteLine();\n\n\n            string str3 = \"str3\";\n            Console.WriteLine($\"Valor original de str3 {str3}\");\n            string str4 = \"str4\";\n            Console.WriteLine($\"Valor original de str4 {str4}\");\n            string respStr3;\n            string respStr4;\n            string[] str2Array = IntercambiarValores(ref str3, ref str4);\n            respStr3 = str2Array[0];\n            respStr4 = str2Array[1];\n            Console.WriteLine($\"Valor de la nueva variable respStr3 {respStr3}\");\n            Console.WriteLine($\"Valor de la nueva variable respStr4 {respStr4}\");\n            Console.WriteLine($\"Valor de str3 despues de llamar la función {str3}\");\n            Console.WriteLine($\"Valor de str4 despues de llamar la función {str4}\");\n        }\n\n        // La función que recibe un parametro por valor, lo que recibe es una copia del valor de la variable que se le ha pasado como parametro.\n        private static void FuncionPorValor(int numero)\n        {\n            numero++;\n        }\n\n        // La función que recibe un parametro por referencia lo que recibe es la referencia de la variable que le pasamos.\n        // Si se modifica el valor de la variable dentro de la función, tambien se modificara en la variable que esta fuera de la función que se le haya pasado como parametro\n        private static void FuncionPorReferencia(ref int numero)\n        {\n            numero++;\n        }\n\n        // Reto extra\n        private static string[] IntercambiarValores(string str1, string str2)\n        {\n            string temp;\n            temp = str1;\n            str1 = str2;\n            str2 = temp;\n            return new string[] { str1, str2};\n        }\n\n        private static string[] IntercambiarValores(ref string str1, ref string str2)\n        {\n            string temp;\n            temp = str1;\n            str1 = str2;\n            str2 = temp;\n            return new string[] { str1, str2 };\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/c#/jamerrq.cs",
    "content": "using System;\nclass ValueAndReferences\n{\n    // Ejemplo de asignación de variables por valor y por referencia\n    static void VarsByValueAndReference()\n    {\n        // Asignación por valor\n        int a = 5;\n        int b = a;\n        b = 10;\n        Console.WriteLine(\"int a = 5; int b = a; b = 10;\");\n        Console.WriteLine(a); // 5\n        Console.WriteLine(b); // 10\n\n        // Asignación por referencia\n        int[] c = { 5 };\n        int[] d = c;\n        d[0] = 10;\n        Console.WriteLine(\"int[] c = { 5 }; int[] d = c; d[0] = 10;\");\n        Console.WriteLine(c[0]); // 10\n        Console.WriteLine(d[0]); // 10\n    }\n\n    // Ejemplo de función con variables que se les pasan por valor y por referencia\n    static void FuncByValue(int value1, int value2)\n    {\n        int tmp = value1;\n        value1 = value2;\n        value2 = tmp;\n        Console.WriteLine(\"FuncByValue(5, 10);\");\n        Console.WriteLine(value1); // 10\n        Console.WriteLine(value2); // 5\n    }\n\n    static void FuncByReference(ref int value1, ref int value2)\n    {\n        int tmp = value1;\n        value1 = value2;\n        value2 = tmp;\n        Console.WriteLine(\"FuncByReference(ref 5, ref 10);\");\n        Console.WriteLine(value1); // 10\n        Console.WriteLine(value2); // 5\n    }\n\n    static void Extra()\n    {\n        int a = 5;\n        int b = 10;\n        int c = a;\n        int d = b;\n        FuncByValue(c, d);\n        Console.WriteLine(a); // 5\n        Console.WriteLine(b); // 10\n        FuncByReference(ref c, ref d);\n        Console.WriteLine(a); // 10\n        Console.WriteLine(b); // 5\n    }\n\n    static void Main()\n    {\n        Console.WriteLine(\"========================================\");\n        Console.WriteLine(\"==== VARIABLES POR VALOR Y REFERENCIA ==\");\n        Console.WriteLine(\"========================================\\n\");\n        VarsByValueAndReference();\n        Console.WriteLine(\"\\n========================================\\n\");\n        Console.WriteLine(\"==== FUNCIONES POR VALOR Y REFERENCIA ===\");\n        Console.WriteLine(\"========================================\\n\");\n        FuncByValue(5, 10);\n        int x = 5;\n        int y = 10;\n        FuncByReference(ref x, ref y);\n        Console.WriteLine(\"\\n========================================\\n\");\n        Console.WriteLine(\"============ EJERCICIO EXTRA ===========\");\n        Console.WriteLine(\"========================================\\n\");\n        Extra();\n    }\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/c#/kenysdev.cs",
    "content": "/* ╔══════════════════════════════════════╗\n   ║ Autor:  Kenys Alvarado               ║\n   ║ GitHub: https://github.com/Kenysdev  ║\n   ║ 2024 -  C#                           ║\n   ╚══════════════════════════════════════╝\n   ----------------------------------------\n   # VALOR Y REFERENCIA\n   ----------------------------------------\n// Asignación de variables \"por valor\"\n   - se asigna el valor real de la variable a otra variable.\n   - los cambios en una variable no afectarán a la otra. */\n\nConsole.WriteLine(\"Por valor\");\nint int1 = 111;\nbool bool1 = false;\nstring str1 = \"Ben\";\n\n// Asignación\nint int2 = int1;\nbool bool2 = bool1;\nstring str2 = str1;\n\n// Cambio\nint1 = 777;\nbool1 = true;\nstr1 = \"zoe\";\n\n// Las variables no fueron afectadas.\nConsole.WriteLine($\"{int2} - {bool2} - {str2}\");\n\n// ejemplo con una función:\nvoid fun_v(int int3, bool bool3, string str3)\n{\n    int3 = 333;\n    bool3 = false;\n    str3 = \"Zoe\";\n}\n// paso por valor\nfun_v(int1, bool1, str1);\n// no afectadas por los cambios en la función.\nConsole.WriteLine($\"{int2} - {bool2} - {str2}\");\n\n/* _________________________________________\n   Asignación de variables \"por referencia\"\n   - se asigna la referencia o dirección de memoria\n     de la variable a otra variable.\n   - Los cambios en una variable pueden afectar a la otra. */\nConsole.WriteLine(\"Por referencia\");\nvar list1 = new List<string> {\"Bob\", \"Zoe\", \"Dan\"};\nvar dic1 = new Dictionary<string, string> {{\"name\", \"Dan\"}};\n\n// Asignación\nvar list2 = list1;\nvar dic2 = dic1;\n\n// Cambio\nlist1[0] = \"Tom\";\ndic1[\"name\"] = \"Zoe\";\n\n// Las variables fueron afectadas por el cambio.\nstring rList = string.Join(\", \", list2);\nConsole.WriteLine($\"{rList}) - {dic2[\"name\"]}\");\n\n// Ejemplo en una función\nvoid fun_r(List<string> list, Dictionary<string, string> dic)\n{\n    list[0] = \"Bob\";\n    dic[\"name\"] = \"Dan\";\n}\n// Paso por referencia\nfun_r(list2, dic2);\n\n// Fueron afectadas por los cambios en la función.\nstring rList2 = string.Join(\", \", list2);\nConsole.WriteLine($\"{rList2}) - {dic2[\"name\"]}\");\n\n/* _________________________________________\nEjercicio:\n* Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n* - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n*   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n*   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n*   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n*   Comprueba también que se ha conservado el valor original en las primeras. */\nConsole.WriteLine(\"Ejercicio:\");\nstring s1 = \"Ben\";\nstring s2 = \"Zoe\";\nvar l1 = new List<object> {12, 21};\nvar l2 = new List<object> {\"Ben\", \"Zoe\"};\n\nstring rL1 = string.Join(\", \", l1);\nstring rL2 = string.Join(\", \", l2);\nConsole.WriteLine($\"Pre-Intercambio:\\r\\n{s1} - {s2}\\r\\n{rL1} - {rL2}\");\n\nstatic(string, string) by_value(string str1, string str2)\n{\n    (str1, str2) = (str2, str1);\n    return (str1, str2);\n}\n\nstatic(List<object>, List<object>)by_reference(List<object>list1, List<object> list2)\n{\n    (list1, list2) = (list2, list1);\n    return (list1, list2);\n}\n\nvar (new_s1, new_s2) = by_value(s1, s2);\nvar (new_l1, new_l2) = by_reference(l1, l2);\n\nrL1 = string.Join(\", \", l1);\nrL2 = string.Join(\", \", l2);\nConsole.WriteLine($\"Originales:\\r\\n{s1} - {s2}\\r\\n{rL1} - {rL2}\");\n\nrL1 = string.Join(\", \", new_l1);\nrL2 = string.Join(\", \", new_l2);\nConsole.WriteLine($\"Nuevas:\\r\\n{new_s1} - {new_s2}\\r\\n{rL1} - {rL2}\");\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/c#/victormugo.cs",
    "content": "﻿using System.Drawing;\nusing System.Security.Cryptography.X509Certificates;\n\nnamespace _05_valoryreferencia\n{\n    internal class Program\n    {\n        static void Main(string[] args)\n        {\n            /*\n             * EJERCICIO:\n             * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n             *   su tipo de dato.\n             * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n             *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n             * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n             *\n             * DIFICULTAD EXTRA (opcional):\n             * Crea dos programas que reciban dos parámetros (cada uno) definidos como\n             * variables anteriormente.\n             * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n             *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n             *   se asigna a dos variables diferentes a las originales. A continuación, imprime\n             *   el valor de las variables originales y las nuevas, comprobando que se ha invertido\n             *   su valor en las segundas.\n             *   Comprueba también que se ha conservado el valor original en las primeras.\n             */\n\n\n            // Ejemplo de asignación de varialbe por valor\n            int a = 5;\n            int b = a;\n            a = 7;\n\n            // a tiene el valor 7 y b tiene el valor 5\n            Console.WriteLine($\"a: {a}\");\n            Console.WriteLine($\"b: {b}\");\n\n\n            // -------------------------------------------------------------------------------\n            // -------------------------------------------------------------------------------\n\n\n            // Ejemplo de asignación de variables por referencia\n            int c = 10;\n            Console.WriteLine($\"c: {c}\"); // c = 10\n            _MetodoReferencia(ref c);\n\n            Console.WriteLine($\"c: {c}\"); // c = 20\n\n\n            // -------------------------------------------------------------------------------\n            // -------------------------------------------------------------------------------\n\n\n            // Ejemplos de funciones con variables que se les pasan por valor y por referencia\n\n            // Pasar una variable por valor es que se hace una copia de la variable original y al salir del método, la copia se destruye\n            int x = 5;\n            _FuncionPorValor(x);\n            Console.WriteLine($\"x al final por valor: {x}\");\n\n\n            // Pasar una variable por referencia es que se conserva el valor de la variable original al salir del método\n            // Usar ref cuando se deseen devolver dos o más valores en una función\n            int y = 5;\n            _FuncionPorReferencia(ref y);\n            Console.WriteLine($\"y al final por referencia: {y}\");\n\n\n            // -------------------------------------------------------------------------------\n            // -------------------------------------------------------------------------------\n\n\n            // Crea dos programas que reciban dos parámetros(cada uno) definidos como variables anteriormente.\n            //      Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n            //      Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno se asigna a dos variables diferentes a las originales.\n            //      A continuación, imprime el valor de las variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n            //      Comprueba también que se ha conservado el valor original en las primeras.\n\n\n            int variable1 = 5;\n            int variable2 = 10;\n\n            Console.WriteLine($\"variable1: {variable1}\");\n            Console.WriteLine($\"variable2: {variable2}\");\n\n            int[] ints = _MetodoValor(variable1, variable2);\n\n            int variable3 = ints[0];\n            int variable4 = ints[1];\n\n            Console.WriteLine($\"variable3: {variable3}\");\n            Console.WriteLine($\"variable4: {variable4}\");\n\n            Console.WriteLine($\"variable1: {variable1}\");\n            Console.WriteLine($\"variable2: {variable2}\");\n\n\n            // -------------------------------------------------------------------------------\n\n            int variable5 = 15;\n            int variable6 = 30;\n\n            Console.WriteLine($\"Valores antes del intercambio: variable5 = {variable5}, variable6 = {variable6}\");\n\n            _MetodoReferencia(ref variable5, ref variable6);\n\n            Console.WriteLine($\"Valores después del intercambio: variable5 = {variable5}, variable6 = {variable6}\");\n        }\n\n        private static int[] _MetodoValor(int x, int y)\n        {\n            // x = 5\n            // y = 10\n\n            int aux = x;\n            x = y;\n            y = aux;\n\n            // x = 10\n            // y = 5\n\n            return [x, y];\n\n        }\n\n        private static void _MetodoReferencia(ref int x, ref int y)\n        {\n            // x = 15;\n            // y = 30;\n\n            int temp = x;\n            x = y;\n            y = temp;\n\n            // x = 30;\n            // y = 15;\n        }\n\n        private static void _MetodoReferencia(ref int numero)\n        {\n            numero = 20;\n        }\n\n        private static void _FuncionPorValor(int x)\n        {\n            x *= 2;\n            Console.WriteLine($\"x dentro de la función: {x}\");\n        }\n\n        private static void _FuncionPorReferencia(ref int y)\n        {\n            y *= 2;\n            Console.WriteLine($\"x dentro de la función: {y}\");\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/c#/vixxtory.cs",
    "content": "﻿using static System.Runtime.InteropServices.JavaScript.JSType;\n\nnamespace RetosProgramacion {\n    class Program\n    {\n        static void Main(string[] args)\n        {\n            //Tipos de variables POR VALOR: el operando de la izquierda recibe el valor del de la derecha.\n            //Se almacenan en el tipo de memoria Stack\n            //Son los struct, los tipos primitivos y enum.\n            int var1 = 15;\n            int var2 = var1;\n            var1 = 10; //aunque se modifique el valor de var1, var2 mantiene su valor.\n            Console.WriteLine(var1);\n            Console.WriteLine(var2);\n\n            Empleado empleado1 = new Empleado(1500, \"Sebastian\"); //se crea una copia de struct empleado en Stack\n            empleado1.incrementarSalario(1000);\n            Console.WriteLine(empleado1);\n            Empleado empleado2 = empleado1;\n            empleado2.incrementarSalario(3000); //al modificar empleado2 no se modifica empleado1.\n            Console.WriteLine(empleado2);\n            Console.WriteLine(empleado1);\n\n            //Tipos de variables POR REFERENCIA: la asignación copia la referencia al objeto.\n            //Los objetos se guardan en la memoria Heap y su referencia en el Stack.\n            //Los tipos de variable por valor son las clases, los records, los string, las matrices,\n            //los delegados, las interfaces, los tipos dinamicos.\n            Auto auto1 = new Auto(\"Nissan\", 0);\n            Auto auto2 = new Auto(\"Peugueot\", 15000);\n            auto2 = auto1;\n            Console.WriteLine(\"Auto 2: \" + auto2); //auto2 apunta a la direccion de memoria de auto1\n            auto2.sumarKms(150);\n            Console.WriteLine(\"Auto 1: \" + auto1);\n            Console.WriteLine(\"Auto 2: \" + auto2);\n\n            //Funciones con paso de parametros por valor\n            int numero = 5;\n            Console.WriteLine($\"Antes de PasarPorValor: {numero}\");\n            PasarPorValor(numero);\n            Console.WriteLine($\"Después de PasarPorValor: {numero}\");\n\n            //Funciones con paso de parametros por referencia\n\n            int[] numeros = { 1, 2, 3, 4, 5 };\n            Console.WriteLine(\"Array antes de modificar:\");\n            ImprimirArray(numeros);\n            ModificarArray(numeros);\n            Console.WriteLine(\"Array después de modificar:\");\n            ImprimirArray(numeros);\n\n            // EXTRA -------------------------------------\n            int valor1 = 10;\n            int valor2 = 50;\n            var retornoValor = intercambiarValor(valor1, valor2);\n\n            Console.WriteLine($\"Variables originales: {valor1} {valor2}\");\n            Console.WriteLine($\"Variables nuevas: {retornoValor.Item1} {retornoValor.Item2}\");\n\n\n            Auto auto3 = new Auto(\"BMW\", 100);\n            Auto auto4 = new Auto(\"Fiat\", 2000);\n            var retornoReferencia = intercambiarReferencia(auto3, auto4);\n\n            Console.WriteLine($\"Variables originales: \\n {auto3} \\n {auto4}\");\n            Console.WriteLine($\"Variables nuevas: \\n {retornoReferencia.Item1} \\n {retornoReferencia.Item2}\");\n\n        }\n\n        static void PasarPorValor(int x)\n        {\n            x = 10; // Esto no afecta la variable original\n            Console.WriteLine($\"Dentro de PasarPorValor: {x}\");\n        }\n        static void ModificarArray(int[] arr)\n        {\n            for (int i = 0; i < arr.Length; i++)\n            {\n                arr[i] *= 2;\n            }\n        }\n\n        static void ImprimirArray(int[] arr)\n        {\n            foreach (int num in arr)\n            {\n                Console.Write(num + \" \");\n            }\n            Console.WriteLine();\n        }\n\n        //EXTRA\n        static (int, int) intercambiarValor(int x, int y)\n        {\n            int intermediario = x;\n            x = y;\n            y = intermediario;\n            return (x, y);\n        }\n        static (Auto, Auto) intercambiarReferencia(Auto auto1, Auto auto2)\n        {\n            Auto autoIntermedio = auto1;\n            auto1 = auto2;\n            auto2 = autoIntermedio;\n\n            return (auto1, auto2);\n        }\n    }\n    public struct Empleado //se crea un struct inmutable en la memoria Stack\n        {\n            public double salario { get; set; }\n            public string nombre { get; set; }\n            public Empleado(double salario, string nombre)\n            {\n                this.salario = salario;\n                this.nombre = nombre;\n            }\n\n            public override string ToString() => $\"El salario del empleado {nombre} es {salario}\";\n            public void incrementarSalario(double incremento)\n            {\n            this.salario += incremento;\n            }\n        }\n    public class Auto //hasta que no se instancia una clase no se crea el objeto en la memoria head\n    {\n        string marca { get; set; }\n        double kms { get; set; }\n        public Auto(string marca, double kms)\n        {\n            this.marca = marca;\n            this.kms = kms;\n        }\n        public void sumarKms(double incrementoDeKms)\n        {\n            this.kms += incrementoDeKms;\n        }\n        public override string ToString()\n        {\n            return $\"El auto marca {marca} tiene recorridos {kms} kilometros\";\n        }\n               \n    } \n}\n\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/c++/Fravelz.cpp",
    "content": "#include <iostream>\n#include <vector>\n\nusing namespace std;\n\n// *************** *************** 05# - Valor y Referencia *************** *************** //\n\n// ? Funciones\n\nint funcion_por_valor(int x) {\n    ++x; return x*x;\n}\n\nint funcion_por_referencia(int& x) {\n    ++x; return x*x;\n}\n\nvector<int> programa1(int a, int b);\nvector<int> programa2(int& a, int& b);\n\nint main() {\n    int numero = 10;\n\n    cout << funcion_por_valor(numero) << '\\n'; // 121\n    cout << numero << '\\n';                    // 10\n\n    cout << funcion_por_referencia(numero) << '\\n'; // 121\n    cout << numero << '\\n';                         // 11\n   \n    // ? Copia de una Variable\n    string saludo = \"> Hola Mundo!\";\n   \n    string saludo2 = saludo;\n    saludo2 = \"Hola :v\"; // Modifico la copia 2\n    \n    cout << saludo << \" != \" << saludo2 << '\\n'; // Copia 2 es diferente a original\n\n    string *saludo3 = &saludo;\n    *saludo3 = \"Hello :)\"; // Modifico la copia 3\n    \n    cout << saludo << \" == \" << *saludo3 << '\\n'; // Copia 3 es igual a original\n\n    // *********************** Ejercicio DIFICULTAD EXTRA *********************** //\n    \n    int nueva_1, nueva_2, original_1 = 1, original_2 = 2;\n\n    vector<int> result = programa1(original_1, original_2);\n\n    nueva_1 = result[0];\n    nueva_2 = result[1];\n\n    cout << original_1 << \", \" << original_2 << \"\\n\";\n    cout << nueva_1 << \", \" <<  nueva_2 << \"\\n\";\n\n    nueva_1, nueva_2, original_1 = 1, original_2 = 2;\n\n    cout << '\\n' << \"por Referencia :)\" << '\\n';\n\n    result = programa2(original_1, original_2);\n\n    nueva_1 = result[0];\n    nueva_2 = result[1];\n\n    cout << original_1 << \", \" << original_2 << \"\\n\";\n    cout << nueva_1 << \", \" <<  nueva_2 << \"\\n\";\n\n    return 0;\n}\n\nvector<int> programa1(int a, int b) {\n    swap(a, b);\n    return {a, b};\n};\n\nvector<int> programa2(int& a, int& b) {\n    swap(a, b);\n    return {a, b};\n};\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/c++/RoniPG.cpp",
    "content": "// @Roni\n\n#include<iostream>\n#include<tuple>\n\nvoid porValor(int a, int b);\nvoid porReferencia(int& a, int& b);\nstd::tuple<int,int> intercambioPorValor(int a, int b);\nstd::tuple<int,int> intercambioPorReferencia(int& a, int& b);\nint main(){\n\n\t//Asignación de variables por valor\n\n\tint original=5;\n\tint copia=original;\n\tstd::cout<<\"El valor de original: \"<<original<<std::endl;\n\tstd::cout<<\"El valor de la copia: \"<<copia<<std::endl;\n\tcopia=10;\n\tstd::cout<<\"El valor de original al modificar la copia: \"<<original<<std::endl;\n\tstd::cout<<\"El nuevo valor de la copia: \"<<copia<<std::endl;\n\n\t//Asignación de variables por referencia\n\n\tint x=5;\n\tint &ref=x;\n\tstd::cout<<\"El valor de x: \"<<x<<std::endl;\n\tstd::cout<<\"El valor de la referencia: \"<<ref<<std::endl;\n\tref=10;\n\tstd::cout<<\"El valor de x al modificar la referencia: \"<<x<<std::endl;\n\tstd::cout<<\"El nuevo valor de la referencia: \"<<ref<<std::endl;\n\n\t//Llamadas a funciones\n\tint a=5; int b=10;\n\tstd::cout<<\"Valores antes de llamar a la funcion porValor\\n\"\n\t\t\t\"a: \"<<a<<\".\\tb: \"<<b<<std::endl;\n\tporValor(a, b);\n\tstd::cout<<\"Valores despues de llamar a la funcion porValor\\n\"\n\t\t\t\t\"a: \"<<a<<\"\\tb: \"<<b<<std::endl;\n\tstd::cout<<\"Valores antes de llamar a la funcion porReferencia\\n\"\n\t\t\t\"a: \"<<a<<\".\\tb: \"<<b<<std::endl;\n\tporReferencia(a, b);\n\tstd::cout<<\"Valores despues de llamar a la funcion porReferencia\\n\"\n\t\t\t\t\"a: \"<<a<<\"\\tb: \"<<b<<std::endl;\n\n   /* DIFICULTAD EXTRA (opcional):\n\t* Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n\t* - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n\t*   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n\t*   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n\t*   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n\t*   Comprueba también que se ha conservado el valor original en las primeras.\n\t*/\n\n\tint numA=5;\t\tint numB=10;\n\tstd::cout<<\"\\nValor de numA: \"<<numA<<\".\\tValor de numB: \"<<numB<<std::endl;\n\tint numC;\t\tint numD;\n\tstd::tie(numC,numD)=intercambioPorValor(numA, numB);\n\tstd::cout<<\"Valor de numA: \"<<numA<<\".\\tValor de numB: \"<<numB<<std::endl;\n\tstd::cout<<\"Valor de numC: \"<<numC<<\".\\tValor de numD: \"<<numD<<\"\\n\"<<std::endl;\n\n\tint&refA=numA;\t\tint&refB=numB;\n\tstd::cout<<\"\\nValor de refA: \"<<refA<<\".\\tValor de refB: \"<<refB<<std::endl;\n\tint valorC;int&refC=valorC;\t\tint valorD;int&refD=valorD;\n\tstd::tie(refC,refD)=intercambioPorReferencia(refA, refB);\n\tstd::cout<<\"Valor de refA: \"<<refA<<\".\\tValor de refB: \"<<refB<<std::endl;\n\tstd::cout<<\"Valor de refC: \"<<refC<<\".\\tValor de refD: \"<<refD<<\"\\n\"<<std::endl;\n\n\treturn 0;\n}\n//Funciones con variables por valor\nvoid porValor(int a, int b){\n\tstd::cout<<\"\\nEntramos en la funcion porValor\"<<std::endl;\n\ta=45;\tb=95;\n\tstd::cout<<\"Valor de la variable a: \"<<a<<\"\\nnValor de la variable b: \"<<b<<std::endl;\n\tstd::cout<<\"Salimos de la funcino porValor\\n\"<<std::endl;\n}\n//Funciones con variables por referencia\nvoid porReferencia(int& a, int& b){\n\tstd::cout<<\"\\nEntramos en la funcion porReferencia\"<<std::endl;\n\ta=45;\tb=95;\n\tstd::cout<<\"Valor de la variable a: \"<<a<<\"\\nnValor de la variable b: \"<<b<<std::endl;\n\tstd::cout<<\"Salimos de la funcino porReferencia\\n\"<<std::endl;\n}\nstd::tuple<int,int> intercambioPorValor(int a, int b){\n\tstd::cout<<\"Entramos en la funcion intercambioPorValor\"<<std::endl;\n\tint temp=a;\n\ta=b;\n\tb=temp;\n\tstd::cout<<\"Salimos de la funcion intercambioPorValor\"<<std::endl;\n\treturn std::make_tuple(a, b);\n}\nstd::tuple<int,int> intercambioPorReferencia(int& a, int& b){\n\t/*Al pasarle los parametros por Referencia hay que tener en cuenta que\n\t *cualquier modificación realizada dentro de la funcion cambiara el valor\n\t *de la posicion de memoria que le pasemos\n\t */\n\tstd::cout<<\"Entramos en la funcion intercambioPorReferencia\"<<std::endl;\n\t/*Creamos dos variables temporales para poder intercambiar los valores sin\n\t *modificar sus valores originales\n\t */\n\tint tempA=a;\n\tint tempB=b;\n\tstd::cout<<\"Salimos de la funcion intercambioPorReferencia\"<<std::endl;\n\treturn std::make_tuple(tempB, tempA);\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/c++/Vid92.cpp",
    "content": "#include <iostream>\n#include <vector>\n\nusing namespace std;\n\n\nvoid funcionValor(int dato){\n    int nuevo = 35;\n    dato = nuevo;\n}\n\nvoid funcionReferencia(int &dato){\n    int nuevo = 20;\n    dato = nuevo;\n}\n\nvector<int> cambioValor(int a, int b){\n    int tmp = a;\n    a = b;\n    b = tmp;\n    \n    vector <int> temporal = { a, b };\n    \n    return temporal;\n}\n\n\nvector<int> cambioReferencia(int &a,int &b){ \n    int tmp = a;\n    a = b;\n    b = tmp;\n    \n    vector <int> temporal = { a, b };\n    \n    return temporal;\n}\n\n\nint main()\n{\n    cout<<\"--------------------Variables por Valor-----------------\"<<endl;\n    int x = 5;\n    int y = x;\n    \n    cout<<\"Valor de x = \"<<x<<endl;\n    cout<<\"Valor de y = \"<<y<<endl;\n    cout<<\"Suma de (x + y) = \"<<(x+y)<<endl;\n    \n    y = 10;\n    cout<<\"Valor de x al modificar y = \"<<x<<endl;\n    cout<<\"Nuevo valor de y = \"<<y<<endl;\n    cout<<\"Suma de (x + y) = \"<<(x+y)<<endl;\n    \n    cout<<endl<<\"-------------Variables por Referencia------------\"<<endl;\n    int i = 5;\n\tint &j = i;\n\tcout<<\"El valor de i: \"<<i<<endl;\n\tcout<<\"El valor de j: \"<<j<<endl;\n\tcout<<\"Suma de (i + j) = \"<<(i+j)<<endl;\n\t\n\tj = 10;\n\tcout<<\"El valor de i al modificar j: \"<<i<<endl;\n\tcout<<\"El nuevo valor de j: \"<<j<<endl;\n\tcout<<\"Suma de (i + j) = \"<<(i+j)<<endl;\n    \n    cout<<endl<<\"-------------Funciones por Valor----------------\"<<endl<<endl;\n    int value = 15;\n    cout<<\"Valor de value antes de funcionValor: \"<<value<<endl;\n    funcionValor(value);\n    cout<<\"Valor de value despues de funcionValor: \"<<value<<endl;\n    \n    \n    \n    cout<<endl<<\"-----------Funciones por Referencia--------------\"<<endl<<endl;\n    int num = 10;\n    cout<<\"Valor de num antes de funcionReferencia: \"<<num<<endl;\n    funcionReferencia(num);\n    cout<<\"Valor num despues de funcionReferencia: \"<<num<<endl;\n    \n    \n    //Ejercicio extra\n    int a = 10;\n    int b = 20;\n    \n    \n    vector<int> resultadoValor = cambioValor(a,b);\n    int c = resultadoValor[0];\n    int d = resultadoValor[1];\n    \n    cout<<endl<<\"---------------------Valor-------------------\"<<endl;\n    cout<<\"Valor de A: \"<<a<<endl;\n    cout<<\"Valor de B: \"<<b<<endl;\n    cout<<\"Valor de C: \"<<c<<endl;\n    cout<<\"Valor de D: \"<<d<<endl;\n    \n    \n    \n    vector<int> resultadoReferencia = cambioReferencia(a, b);\n    int &e = resultadoReferencia[0];\n    int &f = resultadoReferencia[1];\n  \n    cout<<endl<<\"---------------------Referencia-----------------\"<<endl;\n    cout<<\"Valor de A: \"<<a<<endl;\n    cout<<\"Valor de B: \"<<b<<endl;\n    cout<<\"Valor de E: \"<<e<<endl;\n    cout<<\"Valor de F: \"<<f<<endl;\n    \n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/c++/h4ckxel.cpp",
    "content": "#include <iostream>\n\n/*Cuando utilizamos una función que recibe los parmámetros por valor, estos valores se utilizan dentro de la función\npueden variar, pero al finalizar la función y volver al programa principal volveran a tener su valor original.\nSi en cambio los parámetros los recibe por referencia, al variar dentro de la función también están cambiando\nsu valor de retorno al finalizar la función (no necesariamente tienen que retornarse estos valores).    */\n\nstruct Numeros\n{\n    int numA;\n    int numB;\n};\n\nNumeros PorValor(Numeros num)\n{\n    int aux = num.numA;\n    num.numA = num.numB;\n    num.numB = aux;\n\n    return num;\n}\n\nNumeros PorReferencia(Numeros &num)\n{\n    int aux = num.numA;\n    num.numA = num.numB;\n    num.numB = aux;\n\n    return num;\n}\n\nint main()\n{\n    Numeros num = {24, 7};\n    printf(\"Valores originales:\\nNumero A: %d, Numero B: %d\\n\\n\", num.numA, num.numB);\n\n    PorValor(num);\n    printf(\"Parametros por valor:\\nNumero A: %d, Numero B: %d\\n\\n\", num.numA, num.numB);\n\n    PorReferencia(num);\n    printf(\"Parametros por referencia:\\nNumero A: %d, Numero B: %d\\n\\n\", num.numA, num.numB);\n\n    return 0;\n}"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/c++/hectorio23.cpp",
    "content": "#include <iostream>\n#include <vector>\n\n/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\n //#############################################################\n /**************** DEFINICION DE FUNCIONES ********************/\n //#############################################################\n\n int sumaReferencia(int&, int&);\n int sumaCopia(int, int);\n\n std::vector<int> intercambioValoresReferencia(int&, int&);\n std::vector<int> intercambioCopia(int, int);\n\n //#############################################################\n /******************* PROGRAMA PRINCIPAL **********************/\n //#############################################################\n\nint main() {\n\n    // Variables las cuales de van a usar como conejillos de indias\n    int numero = 94, numero2 = 6;\n\n\n    // En esta sección de imprimirán la dirección en memoria de las variables\n    // tiempo después de ser definidas, para comprobar cual ha sido la dirección\n    // asignada por el compilador.\n    std::cout << \"*** Estos son las direcciones en memoria de las variables previamente definidas***\\n\";\n    std::cout << \"Ubicación en memoria de value1: \" << &numero << \"\\n\";\n    std::cout << \"Ubicación en memoria de value2: \" << &numero2 << \"\\n\";\n\n    sumaReferencia(numero, numero2);\n    sumaCopia(numero, numero2);\n\n\n    std::cout << \"\\n******************\\n\";\n\n    std::cout << \"Valor de las variables originales \\n\";\n    std::cout << \"a -> \" << numero << \"\\n\";\n    std::cout << \"b -> \" << numero2 << \"\\n\";\n\n    // Después de hacer el cambio de variables mediante una funcion\n    // que recibe los parámetros por copia \n    std::vector<int> resutadoCopia = intercambioCopia(numero, numero2);\n    int copia1 = resutadoCopia[0], copia2 = resutadoCopia[1];\n    \n    std::cout << \"\\nValor de las variables después de hacer un intarcambio de valores (copia) \\n\";\n    std::cout << \"Variables originales \\n\";\n    std::cout << \"a -> \" << numero << \"\\n\";\n    std::cout << \"b -> \" << numero2 << \"\\n\";   \n    std::cout << \"Variables retornadas \\n\";\n    std::cout << \"copia a -> \" << copia1 << \"\\n\";\n    std::cout << \"copia b -> \" << copia2 << \"\\n\";\n\n    // Después de hacer el cambio de variables mediante una funcion\n    // que recibe los parámetros por referencia\n    std::vector<int> resutadoReferencia = intercambioValoresReferencia(numero, numero2);\n    int referencia1 = resutadoReferencia[0], referencia2 = resutadoReferencia[1];\n\n    std::cout << \"\\nValor de las variables después de hacer un intarcambio de valores (referencia) \\n\";\n    std::cout << \"Variables originales \\n\";\n    std::cout << \"a -> \" << numero << \"\\n\";\n    std::cout << \"b -> \" << numero2 << \"\\n\";   \n    std::cout << \"Variables retornadas \\n\";\n    std::cout << \"copia a -> \" << referencia1 << \"\\n\";\n    std::cout << \"copia b -> \" << referencia2 << \"\\n\";\n\n    return 0;\n}\n\n//#############################################################\n/************************ FUNCIONES **************************/\n//#############################################################\n\n// La siguiente función recibe como referencia dos variables\n// de tipo <<int>> y retorna la suma de estos\nint sumaReferencia(int& iValue1, int& iValue2) {\n    // Imprime a su vez la variable y su dirección de memoria\n    // de la siguiente manera\n    // variable   memory address\n    //    &a   -> 0x7ffcfd2f2460    Note que va de 4 en 4, es porque <<int>> tiene una longitud de 4 bytes\n    //    &b   -> 0x7ffcfd2f2464    \n    std::cout << \"***Dentro de la funcion que recibe valores por referencia*** \\n\";\n    std::cout << \"var     memory address\\n\";\n    std::cout << \"&a  ->   \" << &iValue1 << \"\\n\";\n    std::cout << \"&b  ->   \" << &iValue2 << \"\\n\";\n    return iValue1 + iValue2;\n}\n\n// La siguiente función recibe dos variables creando una copia\n// de tipo <<int>> y retorna la suma de estos\nint sumaCopia(int value1, int value2) {\n    // Imprime a su vez la variable y su dirección de memoria\n    // de la siguiente manera\n    // variable   memory address\n    //    a    -> 0x7ffcfd2f244c    Note que va de 4 en 4, es porque <<int>> tiene una longitud de 4 bytes\n    //    b    -> 0x7ffcfd2f2448    \n    std::cout << \"\\n***Dentro de la funcion que recibe valores por copia*** \\n\";\n    std::cout << \"a   ->   \" << &value1 << \"\\n\";\n    std::cout << \"b   ->   \" << &value2 << \"\\n\";\n    return value1 + value2;\n}\n\n// intercambia los valores de los parámetros pasados como referencia\n// lo que significa que los parámetros que se le pases serán afectados\n// dentro y fuera del scope de la función\nstd::vector<int> intercambioValoresReferencia(int& numero1, int& numero2) {\n    int value1 = numero1;\n\n    numero1 = numero2;\n    numero2 = value1;\n\n    // se retornan los parámetros de la forma <<number1, number2>>\n    std::vector <int> temporal = { numero1, numero2 };\n    return temporal;\n}\n\n// intercambia los valores de los parámetros pasados como copia\n// lo que significa que los parámetros que se le pases NO serán afectados\n// fuera del scope, pero si dentro de él\nstd::vector<int> intercambioCopia(int numero1, int numero2) {\n\n    int value1 = numero1;\n\n    numero1 = numero2;\n    numero2 = value1;\n\n    // se retornan los parámetros de la forma <<number1, number2>>\n    std::vector <int> temporal = { numero1, numero2 };\n    return temporal;\n}\n\n /*\n- En C++, al igual que en todos los lenguajes de programación, cuando se declaran variables de cualquier tipo, \n- incluso si se inicializan con un valor nulo, el compilador o el intérprete les asigna una dirección de memoria \n- en función de su tipo. A continuación, se presenta la longitud típica de cada tipo de datos en C++:\n    ------------------------\n    | char      |  1 byte  |\n    | int(x32)  |  4 bytes | \n    | int(x64)  |  8 bytes |\n    | float     |  4 bytes |\n    | double    |  8 bytes |\n    | long(x32) |  4 bytes | \n    | long(x64) |  8 bytes |\n    | long long |  8 bytes |  \n    | short     |  2 bytes | \n    | bool      |  1 byte  |\n    ------------------------\n- Las variables por referencia en realidad se le asigna la dirección de la variable pasada a la variable \n- definida dentro de un scope, es decir, a -> 0xFFFF.., b -> a, es igual a b -> 0xFFFF...\n- Lo anterior tiene consecuencias como en caso de modificar b, también se modifica a, por el contrario, \n- cuando las variables se crean como copia, esto no sucede. \n */"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/c++/jhoshmc.cpp",
    "content": "/*\n ! EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n*/\n\n#include <iostream>\n#include <tuple> \n\n\nvoid f_valor(int);\nvoid f_referencia(int &);\n//*------------ extra-------------\nstd::tuple<int,int> intercambiar_valor(int, int);\nstd::tuple<int,int> intercambiar_referencia(int&, int&);\nvoid extra();\n\nusing namespace std;\n\n\nint main(){\n  \n  // int numero = 2;\n  // cout << \"numero original: \" << numero << endl;\n  // f_valor(numero);\n  // cout << \"\\n variable numero original: \" << numero << endl;\n  // f_referencia(numero);\n  // cout << \"\\n variable texto original: \" << numero << endl;\n  // cout << \"\\n\";\n\n  \n  extra();\n  return 0;\n}\n\n\n\nvoid f_valor(int numero){\n  /*\n  * cuando se pasa una variable por valor, se pasa una copia del valor de esa variable\n  * en este caso se pasa un string, dicho, se podria modificar, pero los cambios solo\n  * se arian a la copia pasada, la variable original, segira tal y como fue declarada\n  * en su scope\n  */\n  cout << \"\\nnumero pasado por valor: \" << numero << endl;\n  numero = 5;\n  cout << \"numero cambiado (por valor): \" << numero << endl;\n}\n\nvoid f_referencia(int& numero){\n  /*\n  *cuando se pasa una variable por referencia, se está pasando la direccion de memoria \n  * donde está guardada esa variable, si se modifica , se estaria cambiando el valor \n  * de la variable original\n  */\n  cout << \"\\nnumero pasado por referencia: \" << numero << endl;\n  numero = 10;\n  cout << \"numero cambiado (por referencia): \" << numero << endl;\n}\n\n/*\n ! DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n*/\nvoid extra(){\n  int p_1 = 2;\n  int P_2 = 4;\n  cout << \"valor original de p_1: \" << p_1 << endl;\n  cout << \"valor original de p_2: \" << P_2 << endl;\n  cout << \"\\n pasando valores por valor: \" << endl;\n  auto [copia_p_1, copia_p_2] = intercambiar_valor(p_1, P_2);\n  cout << \"el valor de la copia p_1: \" << copia_p_1 << endl;\n  cout << \"el valor de la copia p_2: \" << copia_p_2 << endl;\n  cout << \"\\n pasando valores por referencia: \" << endl;\n  auto [ref_p1, ref_p2] = intercambiar_referencia(p_1, P_2);\n  cout << \" el valor por referencia de ref_1: \" << ref_p1 << endl;\n  cout << \"el valor por referencia de ref_2: \" << ref_p2 << endl;\n  cout << \"\\n los valores de las variables originales: \" << endl;\n  cout << \"valor de p_1: \" << p_1 << endl;\n  cout << \"valor de p_2: \" << P_2 << endl;\n}\n\nstd::tuple<int,int>intercambiar_valor(int p_1,int p_2){\n\n  int aux = p_1;\n  p_1 = p_2;\n  p_2 = aux;\n  return std::make_tuple(p_1,p_2);\n}\n\nstd::tuple<int,int> intercambiar_referencia(int& p_1, int& p_2){\n  \n  int aux = p_1;\n  p_1 = p_2;\n  p_2 = aux;\n  return {p_1, p_2};\n}"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/c++/m-doce.cpp",
    "content": "#include <iostream>\r\n\r\n/*Cuando utilizamos una función que recibe los parmámetros por valor, estos valores se utilizan dentro de la función\r\npueden variar, pero al finalizar la función y volver al programa principal volveran a tener su valor original.\r\nSi en cambio los parámetros los recibe por referencia, al variar dentro de la función también están cambiando\r\nsu valor de retorno al finalizar la función (no necesariamente tienen que retornarse estos valores).    */\r\n\r\nstruct Numeros\r\n{\r\n    int numA;\r\n    int numB;\r\n};\r\n\r\nNumeros PorValor(Numeros num)\r\n{\r\n    int aux = num.numA;\r\n    num.numA = num.numB;\r\n    num.numB = aux;\r\n\r\n    return num;\r\n}\r\n\r\nNumeros PorReferencia(Numeros &num)\r\n{\r\n    int aux = num.numA;\r\n    num.numA = num.numB;\r\n    num.numB = aux;\r\n\r\n    return num;\r\n}\r\n\r\nint main()\r\n{\r\n    Numeros num = {24, 7};\r\n    printf(\"Valores originales:\\nNumero A: %d, Numero B: %d\\n\\n\", num.numA, num.numB);\r\n\r\n    PorValor(num);\r\n    printf(\"Parametros por valor:\\nNumero A: %d, Numero B: %d\\n\\n\", num.numA, num.numB);\r\n\r\n    PorReferencia(num);\r\n    printf(\"Parametros por referencia:\\nNumero A: %d, Numero B: %d\\n\\n\", num.numA, num.numB);\r\n\r\n    return 0;\r\n}"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/dart/D3rk1us.dart",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n */\n\nvoid main() {\n\n    int number = 23;\n    int aNumber = number;\n\n    aNumber = 12;\n\n    print('number: $number');\n    print('aNumber: $aNumber');\n\n\n    ejemploFuncion(number);\n    print('number fuera de la función: $number');\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\n    String variable1 = 'Hola';\n    String variable2 = 'Mundo';\n\n    List<String> iPrograma1 = programa1(variable1, variable2);\n\n    String variable1Nueva = iPrograma1[0];\n    String variable2Nueva = iPrograma1[1];\n\n\n    print('Primer valor antes del cambio: $variable1 \\nSegundo valor antes del cambio: $variable2');\n    print('Primer valor después del cambio: $variable1Nueva \\nSegundo valor después del cambio: $variable2Nueva');\n\n    print('-------------------------------------------------');\n\n    List<dynamic> variableList1 = [45];\n    List<dynamic> variableList2 = [80];\n\n    List<dynamic> iPrograma2 = programa2(variableList1, variableList2);\n\n    dynamic lista1Nueva = iPrograma2[0];\n    dynamic lista2Nueva = iPrograma2[1];\n\n    print('Primer valor antes del cambio: $variableList1 \\nSegundo valor antes del cambio: $variableList2');\n    print('Primer valor después del cambio: $lista1Nueva \\nSegundo valor después del cambio: $lista2Nueva');\n\n}\n\n\n// Funciones\n\nvoid ejemploFuncion(int valor) {\n    valor = 10;\n    print('El valor de number dentro de la funcion es: $valor');\n}\n\nList<String> programa1(String variable1, String variable2) {\n    String valor_cambio = variable1;\n    variable1 = variable2;\n    variable2 = valor_cambio;\n\n    return [variable1, variable2];\n    \n}\n\nList<dynamic> programa2(List<dynamic> variable1, List<dynamic> variable2) {\n    dynamic valor_cambio = variable1[0];\n    variable1[0] = variable2[0];\n    variable2[0] = valor_cambio;\n\n    return [variable1[0], variable2[0]];\n}"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/dart/bluefeatherdev.dart",
    "content": "/*\n* EJERCICIO:\n* - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n*   su tipo de dato.\n* - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n*   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n* (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n*\n* DIFICULTAD EXTRA (opcional):\n* Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n* - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n*   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n*   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n*   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n*   Comprueba también que se ha conservado el valor original en las primeras.\n*/\n\nvoid main() {\n  /// [Asignaciones por valor]:\n  /// int, bool, String y enum\n  int a = 10;\n  int b = a;  // Copia el valor\n\n  b = 20;\n  print('a: $a'); // 10\n  print('b: $b'); // 20\n\n  double c = 3.14159265;\n  double d = c;  // Copia el valor\n\n  d = 1.61803399;\n  print('c: $c'); // 3.14159265\n  print('d: $d'); // 1.61803399\n\n  String e = 'Hello';\n  String f = e;  // Copia el valor\n\n  f = 'Dart!';\n  print('e: $e'); // Hello\n  print('f: $f'); // Dart\n\n  EnumColor color1 = EnumColor.blue;\n  EnumColor color2 = color1;  // Copia el valor\n\n  color2 = EnumColor.green;\n  print('color1: ${color1.name}'); // blue\n  print('color2: ${color2.name}'); // green\n\n  /// [Asignaciones por referencia]:\n  /// List, Set, Map y clases personalizadas\n  List<String> list1 = ['A', 'B', 'C'];\n  List<String> list2 = list1; // Copia la referencia\n\n  list2.add('D');\n  print('list1: $list1'); // [A, B, C, D]\n  print('list2: $list2'); // [A, B, C, D]\n\n  Set<int> set1 = {1, 2, 3};\n  Set<int> set2 = set1; // Copia la referencia\n\n  set2.add(4);\n  print('set1: $set1'); // {1, 2, 3, 4}\n  print('set2: $set2'); // {1, 2, 3, 4}\n\n  Map<int, bool> map1 = {0:true, 1:false, 2:true};\n  Map<int, bool> map2 = map1; // Copia la referencia\n\n  map2[3] = false;\n  print('map1: $map1'); // {0: true, 1: false, 2: true, 3: false}\n  print('map2: $map2'); // {0: true, 1: false, 2: true, 3: false}\n\n  Person p1 = Person('Ana');\n  Person p2 = p1; // Copia la referencia\n\n  p2.name = 'Elie';\n  print('p1: ${p1.name}');  // Elie\n  print('p2: ${p2.name}');  // Elie\n\n  /// [Función con parámetros por valor]:\n  void addTwo(int x) {\n    x = x + 2;  /// `x` copia valor de `myInt`\n    print(x);   /// cambiar `x` no altera a `myInt`\n  }\n\n  int myInt = 23;\n  addTwo(myInt);  // 25\n  print(myInt);   // 23\n\n  /// [Función con parámetros por referencia]:\n  void newKey(Map map) {\n    map['c'] = 3; /// cambiar `map` altera `myMap`\n\n    Map otherMap = map; /// `otherMap` copia referencia de `map`\n    otherMap['d'] = 4; /// cambiar `otherMap` altera `map`\n\n    print(map);\n  }\n\n  Map myMap = {\n    'a': 1,\n    'b': 2,\n  };\n  newKey(myMap);  // {a: 1, b: 2, c: 3, d: 4}\n  print(myMap);   // {a: 1, b: 2, c: 3, d: 4}\n\n  /// [DIFICULTAD EXTRA]:\n  int int1 = 15;\n  int int2 = 23;\n  int int3;\n  int int4;\n  (int3, int4) = byValue(int1, int2); /// por [valor]\n  print('int1: $int1, int2: $int2');  // 15, 23\n  print('int3: $int3, int4: $int4');  // 23, 15\n\n  Set mySet1 = {1, 2, 3};\n  Set mySet2 = {4, 5, 6};\n  Set mySet3;\n  Set mySet4;\n  (mySet3, mySet4) = byReference(mySet1, mySet2); /// por [referencia]\n  print('mySet1: $mySet1, mySet2: $mySet2');  // {1, 2, 3}, {4, 5, 6}\n  print('mySet3: $mySet3, mySet4: $mySet4');  // {4, 5, 6}, {1, 2, 3}\n}\n\n/// [Asignaciones por valor]:\n/// Ejemplo de enums\nenum EnumColor { red, green, blue }\n\n/// [Asignaciones por referencia]:\n/// Ejemplo de clases personalizadas\nclass Person {\n  String name;\n  Person(this.name);\n}\n\n/// [DIFICULTAD EXTRA]:\n(int, int) byValue(int var1, int var2) {\n  int temp = var1;\n  var1 = var2;\n  var2 = temp;\n  return (var1, var2);\n}\n\n(Set, Set) byReference(Set var1, Set var2) {\n  Set temp = var1;\n  var1 = var2;\n  var2 = temp;\n  return (var1, var2);\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/dart/marinaortells.dart",
    "content": "/// URL del sitio web oficial: https://dart.dev/\n\nimport 'dart:io';\n\nvoid main() {\n  /// El paso por valor consiste en que se pasa una copia del valor original al parámetro de la función.\n  /// Cualquier modificación no afecta a la variable original\n  int valor = 304;\n  modificarNumero(valor);\n  print(valor);\n  \n  //// El paso por referencia conciste en que cuando se le pasa un objeto a una función, en este caso\n  /// lo que se le pasa es la referencia al objeto original\n  /// Si se modifica el contenido del objeto dentro de la función, esos cambios se reflejan\n  /// fuera de la función ya que ambas referencias apuntan al mismo objeto\n\n  List<int> lista = [2, 4, 5];\n  modificarLista(lista);\n  print(lista);\n\n  /// Dificultad extra\n  \n  var resultadoPaso = pasoParametros(palabra1, palabra2);\n  String palabraMod1 = resultadoPaso[0];\n  String palabraMod2 = resultadoPaso[1];\n\n  print(\"$palabra1, $palabra2, $palabraMod1, $palabraMod2\");\n\n  var resultadoRef = pasoReferencia(lista1, lista2);\n  List<String> listaMod1 = resultadoRef[0];\n  List<String> listaMod2 = resultadoRef[1];\n\n  print(\"$lista1, $lista2, $listaMod1, $listaMod2\");\n\n}\n\nvoid modificarNumero(int valor) {\n  valor = 244;\n}\n\nvoid modificarLista(List<int> valores) {\n  valores[2] = 7;\n}\n\n/// Dificultad extra\n  String palabra1 = \"dart\";\n  String palabra2 = \"reto\";\n\npasoParametros(palabraPaso1, palabraPaso2) {\n  String auxValor;\n  auxValor = palabraPaso1;\n  palabraPaso1 = palabraPaso2;\n  palabraPaso2 = auxValor;\n  return [palabra1, palabra2];\n}\n\nList<String> lista1 = [\"python\", \"java\", \"typescript\"];\nList<String> lista2 = [\"c++\", \"dart\", \"haskell\"];\n\npasoReferencia(List<String> listaRef1, List<String> listaRef2) {\n  List<String> auxRef;\n  auxRef = listaRef1;\n  listaRef1 = listaRef2;\n  listaRef2 = auxRef;\n  return [lista1, lista2];\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/dart/raulfauli.dart",
    "content": "/// #05 VALOR Y REFERENCIA\n\nvoid main() {\n  // Los datos primitivos se pasan por valor\n  var primitiveVar = 123;\n  var other = primitiveVar;\n  other = 456;\n  print(primitiveVar); // 123\n  print(other); // 456\n\n  // Las listas/objetos se pasan por referencia\n  var lista = [2, 4, 5];\n  var otraLista = lista;\n  otraLista.add(7);\n  print(lista); // [2, 4, 5, 7]\n  print(otraLista); // [2, 4, 5, 7]\n\n  // Para evitar esto, se puede usar el operador spread\n  var lista2 = [2, 4, 5];\n  var otraLista2 = [...lista2];\n  otraLista2.add(7);\n  print(lista2); // [2, 4, 5]\n  print(otraLista2); // [2, 4, 5, 7]\n\n  // Otra forma de evitar esto es usar el método toList()\n  var lista3 = [2, 4, 5];\n  var otraLista3 = lista3.toList();\n  otraLista3.add(7);\n  print(lista3); // [2, 4, 5]\n  print(otraLista3); // [2, 4, 5, 7]\n\n  // Los mapas se pasan por referencia\n  var persona = {'nombre': 'Raúl', 'edad': 25};\n  var otraPersona = persona;\n  otraPersona['edad'] = 26;\n  print(persona); // {nombre: Raúl, edad: 26}\n  print(otraPersona); // {nombre: Raúl, edad: 26}\n\n  // Para evitar esto, se puede usar el operador spread\n  var persona2 = {'nombre': 'Raúl', 'edad': 25};\n  var otraPersona2 = {...persona2};\n  otraPersona2['edad'] = 26;\n  print(persona2); // {nombre: Raúl, edad: 25}\n  print(otraPersona2); // {nombre: Raúl, edad: 26}\n\n  // Otra forma de evitar esto es usar el método Map.from()\n  var persona3 = {'nombre': 'Raúl', 'edad': 25};\n  var otraPersona3 = Map.from(persona3);\n  otraPersona3['edad'] = 26;\n  print(persona3); // {nombre: Raúl, edad: 25}\n  print(otraPersona3); // {nombre: Raúl, edad: 26}\n\n  // En dart 3.0 se añaden los Records que es como una tupla y se pasan por valor\n  var tupla = ('Raúl', 25);\n  var otraTupla = tupla;\n  otraTupla = ('Faulí', 26);\n  print(tupla); // (Raúl, 25)\n  print(otraTupla); // (Faulí, 26)\n\n  // Otro ejemplo de paso por valor mediante un Objeto\n  var fecha = DateTime.now();\n  var otraFecha = fecha;\n  otraFecha.add(Duration(days: 78));\n  print(fecha); // 2021-10-14 20:00:00.000\n  print(otraFecha); // 2021-12-31 00:00:00.000\n\n  // Para evitar esto, se puede clonear la fecha con copyWith\n  var fecha2 = DateTime.now();\n  var otraFecha2 = fecha2.copyWith();\n  otraFecha2 = otraFecha2.add(Duration(days: 78));\n  print(fecha2); // 2021-10-14 20:00:00.000\n  print(otraFecha2); // 2021-12-31 20:00:00.000\n\n  // En funciones pasa lo mismo, depende del tipo de dato y la forma de pasar el dato\n  var valor = 123;\n  modifyValue(valor);\n  print(valor); // 123\n\n  var lista4 = [2, 4, 5];\n  modifyList(lista4);\n  print(lista4); // [2, 4, 5, 777]\n\n  var lista5 = [2, 4, 5];\n  var otraLista5 = modifyListImmutable(lista5);\n  print(lista5); // [2, 4, 5]\n\n  // En caso de haber definido como constante el valor, no se podrá modificar bajo ninguna circunstancia\n  const immutableList = [2, 4, 5];\n  // immutableList.add(777); // Error\n  // modifyList(immutableList); // Error\n  final newList = modifyListImmutable(immutableList);\n  print(immutableList); // [2, 4, 5]\n  print(newList); // [2, 4, 5, 777]\n\n  // Dificultad extra\n  var pareja = [1, 2];\n  var nuevaPareja = pasoPorValor(pareja);\n  print(nuevaPareja); // [2, 1]\n  print(pareja); // [1, 2]\n\n  pasoPorReferencia(pareja);\n  print(pareja); // [2, 1]\n}\n\nvoid modifyValue(int valor) {\n  valor = 777;\n}\n\nvoid modifyList(List<int> lista) {\n  lista.add(777);\n}\n\nList<int> modifyListImmutable(List<int> lista) {\n  return [...lista, 777];\n}\n\nList<int> pasoPorValor(List<int> lista) {\n  return [lista[1], lista[0]];\n}\n\n// convert list to reverse\npasoPorReferencia(List<int> lista) {\n  lista.add(lista[1]);\n  lista.add(lista[0]);\n  lista.removeRange(0, 2);\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/delphi/fduron.dpr",
    "content": "(*\n * EJERCICIO:\n * - Muestra ejemplos de asignacin de variables \"por valor\" y \"por referencia\", segn\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y\n *   \"por referencia\", y cmo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayora de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parmetros (cada uno) definidos como\n * variables anteriormente.\n * - Cada programa recibe, en un caso, dos parmetros por valor, y en otro caso, por referencia.\n *   Estos parmetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuacin, imprime\n *   el valor de las variables originales y las nuevas, comprobando que se ha invertido\n *   su valor en las segundas.\n *   Comprueba tambin que se ha conservado el valor original en las primeras.\n *)\nprogram fduron;\n\n{$APPTYPE CONSOLE}\n\n{$R *.res}\n\nuses\n  System.SysUtils;\n\nprocedure SumarPorReferencia(ValorBase: Integer; var Valor1: Integer; var Valor2: Integer);\nbegin\n  { Los parmetros por referencia son modificados dentro del contexto del\n    procedimiento o funcin que los manda llamar }\n  Valor1 := ValorBase + Valor1;\n  Valor2 := ValorBase + Valor2;\nend;\n\nprocedure ConcatenarPorReferencia(var Cadena1: String; Cadena2: String);\nbegin\n  { El resultado de la concatenacin se almacena en la variable Cadena1, que es\n    un parmetro por referencia }\n  Cadena1 := Cadena1 + '+' + Cadena2;\nend;\n\nfunction ConcatenarPorValor(Cadena1, Cadena2: String): String;\nbegin\n  { El resultado de la concatenacin se regresa en el resultado de la funcin\n    ya que ambos parmetros son por valor }\n\n  // Los parmetros pueden cambiar su valor en el contexto de esta funcin\n  Cadena1 := Cadena1+ '+';\n  Result := Cadena1 + Cadena2;\nend;\n\nprocedure SumarPorValor(ValorBase, Valor1, Valor2: Integer);\nbegin\n  Valor1 := ValorBase + Valor1;\n  Valor2 := ValorBase + Valor2;\n  WriteLn('\"SumaPorValor\"');\n  WriteLn('Valor1: ', Valor1);\n  WriteLn('Valor2: ', Valor2);\nend;\n\nprocedure DificultadExtraPorValor(ParametroUno, ParametroDos: String);\nvar\n  VariableTemporal: String;\nbegin\n  VariableTemporal := ParametroUno;\n  ParametroUno := ParametroDos;\n  ParametroDos := VariableTemporal;\nend;\n\nprocedure DificultadExtraPorReferencia(var ParametroUno, ParametroDos: String);\nvar\n  VariableTemporal: String;\nbegin\n  VariableTemporal := ParametroUno;\n  ParametroUno := ParametroDos;\n  ParametroDos := VariableTemporal;\nend;\n\nVar\n  VarEjemplo1, VarEjemplo2: Integer;\n  CadenaUno, CadenaDos: String;\n  OriginalUno, OriginalDos, NuevaUno, NuevaDos: String;\n\nbegin\n  VarEjemplo1 := 15;\n  VarEjemplo2 := 23;\n  CadenaUno := 'quince';\n  CadenaDos := 'veintitrs';\n\n  SumarPorReferencia(10, VarEjemplo1, VarEjemplo2);\n  WriteLn('los valores + 10 son: ', VarEjemplo1, ' ', VarEjemplo2);\n\n  CadenaUno := 'quince';\n  CadenaDos := 'veintitrs';\n  ConcatenarPorReferencia(CadenaUno, CadenaDos);\n  WriteLn('Concatenar texto usando un procedimiento con parmetros por referencia: ',\n    CadenaUno);\n\n  CadenaUno := 'quince';\n  CadenaDos := 'veintitrs';\n  WriteLn('Concatenar texto usando una funcin con parmetros por valor: ',\n    ConcatenarPorValor(CadenaUno, CadenaDos) );\n\n  SumarPorValor(10, 27, 16);\n\n  WriteLn;\n  WriteLn('************************************************');\n  WriteLn(' DIFICULTAD EXTRA');\n  WriteLn('************************************************');\n  WriteLn;\n\n  OriginalUno := '*Texto nmero uno*';\n  OriginalDos := '-TEXTO NMERO DOS-';\n  NuevaUno := OriginalUno;\n  NuevaDos := OriginalDos;\n\n  DificultadExtraPorValor(NuevaUno, NuevaDos);\n  WriteLn('Ejemplo \"Por valor\"');\n  WriteLn('Varialbes originales: ', OriginalUno, ' ', OriginalDos);\n  WriteLn('Varialbes nuevas: ', NuevaUno, ' ', NuevaDos);\n  WriteLn;\n\n  OriginalUno := '*Texto nmero uno*';\n  OriginalDos := '-TEXTO NMERO DOS-';\n  NuevaUno := OriginalUno;\n  NuevaDos := OriginalDos;\n  DificultadExtraPorReferencia(NuevaUno, NuevaDos);\n  WriteLn('Ejemplo \"Por referencia\"');\n  WriteLn('Varialbes originales: ', OriginalUno, ' ', OriginalDos);\n  WriteLn('Varialbes nuevas: ', NuevaUno, ' ', NuevaDos);\n  ReadLn;\nend.\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/ejercicio.md",
    "content": "# #05 VALOR Y REFERENCIA\n> #### Dificultad: Fácil | Publicación: 29/01/24 | Corrección: 05/02/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/fortran/LeandroCFD.f90",
    "content": "program VALOR_REFERENCIA\n    implicit none\n\n    integer :: a,aa,b,bb\n\n    !En Fortran las variables se asignan por defecto por \"referencia\" no hay asignación por \"valor\", sin embargo en las funciones\n    !si es posible pasar argumentos por valor.\n\n    a=5\n    aa=10\n\n    call ejemplo_x_referencia(a,aa) !Se llama a la función ejemplo_x_referencia\n\n    print*,\"Los valores de a y aa se modificaron en la función: a=\",a,\"y aa=\",aa\n\n    call ejemplo_x_valor (a,aa) !Se llama a la función ejemplo_x_valor\n\n    print*,\"Los valores de a y aa no se modificaron en la función: a=\",a,\"y aa=\",aa\n\n    !DIFICULTAD EXTRA\n    print*,\"************************************************\"\n    print*,\"SUBRUTINAS CON ARGUMENTOS POR VALOR Y REFERENCIA\"\n    print*,\"************************************************\"\n    print*,\"\"\n    b=10\n    bb=20\n    a=30\n    aa=40\n    print*,\"Inicialmente el valor de a es:\",a\n    print*,\"Inicialmente el valor de aa es:\",aa\n    print*,\"Inicialmente el valor de b es:\",b\n    print*,\"Inicialmente el valor de bb es:\",bb\n    print*,\"\"\n\n    call extra_x_referencia(a,aa) !Se llama a la función ejemplo_x_referencia\n\n    print*,\"Los valores de a y aa se intercambiaron en la subrutina: a=\",a,\"y aa=\",aa\n\n    call extra_x_valor (b,bb) !Se llama a la función ejemplo_x_valor\n\n    print*,\"Los valores de b y bb no se intercambiaron en la subrutina: b=\",b,\"y bb=\",bb\n\n    contains\n    subroutine ejemplo_x_referencia(x1,x2)\n        integer , intent(inout) :: x1,x2\n        integer :: x3\n        x3=5\n        x1=x3*5\n        x2=x3*10        \n    end subroutine ejemplo_x_referencia\n\n    subroutine ejemplo_x_valor(x4,x5)\n        integer, value :: x4,x5 !Se agrega la sentencia value para simular la asignación de las variables por \"valor\"\n        integer :: x6\n        x6=5\n        x4=x6*50\n        x5=x6*100        \n    end subroutine ejemplo_x_valor\n\n    subroutine extra_x_referencia(x7,x8)\n        integer , intent(inout) :: x7,x8\n        integer :: x9\n        x9=x7\n        x7=x8\n        x8=x9        \n    end subroutine extra_x_referencia\n\n    subroutine extra_x_valor(x10,x11)\n        integer, value :: x10,x11 !Se agrega la sentencia value para simular la asignación de las variables por \"valor\"\n        integer :: x12\n        x12=x10\n        x10=x11\n        x11=x12        \n    end subroutine extra_x_valor\n    \nend program VALOR_REFERENCIA"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/go/AmadorQuispe.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc main() {\n\t//variableAssignment()\n\tvar x int = 45\n\tfnByValue(x)\n\tfmt.Println(\"Valor de 'x' luego pasar por la función fnByValue\", x)\n\tfnByReference(&x)\n\tfmt.Println(\"Valor de 'x' luego pasar por la función fnByReference\", x)\n\tvar slice []int = []int{1, 2, 3}\n\tmodifySlice(slice)\n\tfmt.Println(\"Slice luego de pasar por la función 'modifySlice'\", slice)\n\n\t//Paso por valor\n\tfmt.Println(\"---------------------------------------\")\n\ta, b := 5, 6\n\ta1, b1 := swapByValue(a, b)\n\tfmt.Printf(\"Valor original a=%d y b=%d\\n\", a, b)\n\tfmt.Printf(\"Valor intercambiado a1=%d y b1=%d\\n\", a1, b1)\n\t//Paso por referencia\n\tfmt.Println(\"---------------------------------------\")\n\ty, z := 10, 20\n\ty1, z1 := swapByRef(&y, &z)\n\tfmt.Printf(\"Valor original y=%d y z=%d\\n\", y, z)\n\tfmt.Printf(\"Valor intercambiado y1=%d y z1=%d\\n\", y1, z1)\n\n}\n\nfunc fnByValue(x int) {\n\tx += 100 //Esto no modifica a 'x' ya que recibe por valor\n}\nfunc fnByReference(x *int) {\n\t*x += 100 //Esto modifica a 'x' ya que recibe por referencia (apunta a la misma dirección de memoria)\n}\nfunc modifySlice(slice []int) {\n\t//Los slice por defecto se pasan por referencia\n\tfor i, v := range slice {\n\t\tslice[i] = v * 2\n\t}\n}\nfunc swapByValue(a, b int) (int, int) {\n\ta, b = b, a\n\treturn a, b\n}\n\nfunc swapByRef(a, b *int) (int, int) {\n\t*a, *b = *b, *a\n\treturn *a, *b\n}\n\nfunc VariableAssignment() {\n\t//POR VALOR\n\t//Todo los tipos básicos se asignan  por valor\n\tvar varInt int = 35\n\tvar varInt1 int = varInt\n\tvarInt1 = 50\n\tfmt.Printf(\"'varInt'= %d, 'varInt1=' %d \\n\", varInt, varInt1)\n\n\tvar varUint uint = 1500000\n\tvar varUint1 uint = varUint\n\tvarUint1 = 1500\n\tfmt.Printf(\"'varUint'= %d, 'varUint1'= %d \\n\", varUint, varUint1)\n\n\tvar varFloat32 float32 = 2500.5\n\tvar varFloat32_1 float32 = varFloat32\n\tvarFloat32_1 = 1500.23\n\tfmt.Printf(\"'varFloat32'= %f, 'varFloat32_1'= %f \\n\", varFloat32, varFloat32_1)\n\n\tvar varString string = \"Hola dev\"\n\tvar varString1 string = varString\n\tvarString1 = \"amsoft.dev\"\n\tfmt.Printf(\"'varString'= %s, 'varString_1'= %s \\n\", varString, varString1)\n\n\tvar varComplex64 complex64 = 2i\n\tvar varComplex64_1 complex64 = varComplex64\n\tvarComplex64_1 = 5i\n\tfmt.Printf(\"'varComplex64'= %v, 'varComplex64_1'= %v \\n\", varComplex64, varComplex64_1)\n\n\tvar varRune rune = 'A'\n\tvar varRune1 rune = varRune\n\tvarRune1 = 'B'\n\tfmt.Printf(\"'varRune'= %v, 'varRune_1'= %v \\n\", varRune, varRune1)\n\n\tvar array [3]int = [3]int{1, 2, 3}\n\tvar array1 [3]int = array\n\tarray1[0] = 20\n\tfmt.Println(array)\n\tfmt.Println(array1)\n\n\t//POR REFERENCIA, tipos de datos por referencia\n\t//slices\n\tfmt.Println(\"TIPOS POR REFERENCIA\")\n\tfmt.Println(\"--------------------\")\n\tvar slice []int = []int{1, 2, 3}\n\tvar slice1 []int = slice\n\tslice1[0] = 20\n\tfmt.Println(slice)\n\tfmt.Println(slice)\n\n\t//mapas\n\tvar varMap map[string]string = map[string]string{\"clave1\": \"valor1\", \"clave2\": \"valor2\"}\n\tvar varMap1 map[string]string = varMap\n\tvarMap1[\"clave1\"] = \"valor 1 modificado\"\n\tfmt.Println(varMap)\n\tfmt.Println(varMap1)\n\n\t//Punteros\n\tvar var1 uint = 3\n\tvar var2 *uint = &var1\n\t*var2 = 15\n\tprintln(var1, *var2) //var1 y var2 apuntan a la misma dirección de memoria\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/go/FreyFonseca117.go",
    "content": "// # #05 VALOR Y REFERENCIA\n// > #### Dificultad: Fácil | Publicación: 29/01/24 | Corrección: 05/02/24\n\n// ## Ejercicio\n\n// ```\n// /*\n//  * EJERCICIO:\n//  * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n//  *   su tipo de dato.\n//  * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y\n//  *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n//  * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n//  *\n//  * DIFICULTAD EXTRA (opcional):\n//  * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n//  * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n//  *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n//  *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n//  *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n//  *   Comprueba también que se ha conservado el valor original en las primeras.\n//  */\n// ```\n// #### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\n// Sigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n// > Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n\npackage main\n\nimport \"fmt\"\n\n// Función con parámetro por valor\nfunc duplicarValor(num int) {\n\tnum *= 2\n\tfmt.Println(\"Dentro de duplicarValor:\", num)\n}\n\n// Función con parámetro por referencia (usando puntero)\nfunc duplicarReferencia(num *int) {\n\t*num *= 2\n\tfmt.Println(\"Dentro de duplicarReferencia:\", *num)\n}\n\n// Intercambio por valor (no afecta a las variables originales)\nfunc intercambioPorValor(a, b int) (int, int) {\n\treturn b, a\n}\n\n// Intercambio por referencia (afecta a las variables originales)\nfunc intercambioReferencia(a, b *int) {\n\t*a, *b = *b, *a\n}\n\nfunc main() {\n\t// Asignación por valor (tipos primitivos)\n\ta := 10\n\tb := a // b recibe una COPIA del valor de a\n\tb = 20\n\tfmt.Println(\"Por valor - a:\", a, \"b:\", b) // a sigue siendo 10\n\n\t// Asignación por referencia (slices, maps, channels, pointers)\n\tslice1 := []int{1, 2, 3}\n\tslice2 := slice1 // slice2 apunta al MISMO slice subyacente\n\tslice2[0] = 99\n\tfmt.Println(\"Por referencia - slice1:\", slice1, \"slice2:\", slice2) // ambos muestran [99 2 3]\n\n\t// Usando punteros para referencia explícita\n\tptrVal := 5\n\tptr := &ptrVal // ptr es un puntero a ptrVal\n\t*ptr = 15\n\tfmt.Println(\"Con punteros - ptrVal:\", ptrVal, \"*ptr:\", *ptr) // ambos son 15\n\n\t// Pruebas de paso por valor y por referencia\n\tnumero := 10\n\n\t// Paso por valor\n\tduplicarValor(numero)\n\tfmt.Println(\"Después de duplicarValor:\", numero) // sigue siendo 10\n\n\t// Paso por referencia\n\tduplicarReferencia(&numero)\n\tfmt.Println(\"Después de duplicarReferencia:\", numero) // ahora es 20\n\n\t// Variables originales para intercambio\n\toriginal1, original2 := 5, 10\n\tfmt.Println(\"\\nOriginales para intercambio - original1:\", original1, \"original2:\", original2)\n\n\t// Intercambio por valor\n\tnuevo1, nuevo2 := intercambioPorValor(original1, original2)\n\tfmt.Println(\"Intercambio por valor:\")\n\tfmt.Println(\"Originales - original1:\", original1, \"original2:\", original2) // no han cambiado\n\tfmt.Println(\"Nuevas - nuevo1:\", nuevo1, \"nuevo2:\", nuevo2)                 // valores intercambiados\n\n\t// Intercambio por referencia\n\tintercambioReferencia(&original1, &original2)\n\tfmt.Println(\"Intercambio por referencia:\")\n\tfmt.Println(\"Originales modificadas - original1:\", original1, \"original2:\", original2) // ahora están intercambiadas\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/go/MiguelP-Dev.go",
    "content": "package main\n\nimport \"fmt\"\n\n// Variable Global\nvar number = 10\n\n// valArray Arreglo de enteros.\nvar valArray = [5]int{1, 2, 3, 4, 5}\n\nfunc main() {\n\n\t// Asignación por valor\n\tvar numberByValue = number\n\tnumberByValue = 45\n\tfmt.Printf(\"Variable Copia: %d Tipo: %T Direccion en Memoria: %v\\n\", numberByValue, numberByValue, &numberByValue)\n\tnumber = 1234\n\tfmt.Printf(\"imprimimos la variable original: %v Dirección en Memoria: %v\\n\", number, &number)\n\n\t// Asignación por Referencia (En Golang esto se hace con punteros, map's y slices que son en golang un puntero a un array subyacente.)\n\tvar numberByReference = &number\n\tfmt.Printf(\"Valor por Referencia: %v  Direccion en Memoria: %v Tipo: %T\\n\", *numberByReference, numberByReference, numberByReference)\n\n\t// Operando en un arreglo accediendo y modificando su valor\n\tfmt.Println(\"Arreglo principal: \", valArray)\n\tvalArray[0] = 10\n\tfmt.Println(\"Arreglo Modificado: \", valArray)\n\n\t// Slice sobre el Arraglo de enteros(Asignación por Referencia)\n\tvar valSlice []int\n\tvalSlice = valArray[0:2]\n\tfmt.Println(\"Slice :\", valSlice)\n\tvalSlice = append(valSlice[:], 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)\n\tfmt.Println(\"Slice :\", valSlice)\n\n\t// Función con asignación por valor\n\tbyVal(number)\n\tfmt.Println(\"Variable Original: \", number)\n\n\tbyRef(&number)\n\tfmt.Println(\"Variable Original: \", number)\n\n\tchangeByValue(value, value2)\n\tchangeByReference(&value, &value2)\n\n}\n\nfunc byVal(x int) {\n\tx = 1000\n\tfmt.Printf(\"Funcion con declaración por Valor: %v\\n\", x)\n}\n\nfunc byRef(x *int) {\n\t*x = 5000\n\tfmt.Printf(\"Función con asignación por referencia: %d Tipo: %T\\n\", *x, x)\n}\n\nvar value = 123\nvar value2 = 22\n\nfunc changeByValue(param, param2 int) {\n\tfmt.Println(\"Valores originales :\", param, param2)\n\tparam, param2 = param2, param\n\tfmt.Println(\"Valores intercambiados: \", param, param2)\n}\n\nfunc changeByReference(param, param2 *int) {\n\tfmt.Printf(\"Valores originales: %v %v\\n\", *param, *param2)\n\tparam, param2 = param2, param\n\tfmt.Printf(\"Valores intercambiados: %v %v\\n\", *param, *param2)\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/go/N0HagoNada.go",
    "content": "package main\n\nimport \"fmt\"\n\ntype Persona struct {\n\tNombre string\n}\n\nfunc main() {\n\t// Tipos Básicos (Por Valor)\n\tx := 5\n\ty := x\n\tfmt.Println(y)\n\t// Por referencia\n\ta := []int{1, 2, 3}\n\tb := a // b y a apuntan al mismo slice\n\tfmt.Println(a, b)\n\t// Estructuras (Por Valor)\n\tp1 := Persona{Nombre: \"Alice\"}\n\tp2 := p1 // Copia los valores de p1 en p2\n\tfmt.Println(p2)\n\t// punteros (por Referencia)\n\tpy := &x // y apunta a la dirección de memoria de x\n\tfmt.Println(py)\n\n\t// Probar la función por Valor\n\tvar pValor1 float32 = 3.1821\n\tvar pValor2 float32 = -1121.1\n\tpValor3, pValor4 := porValor(pValor1, pValor2)\n\tfmt.Printf(\"Variables originales: %f y %f \\n\", pValor1, pValor2)\n\tfmt.Printf(\"Variables nuevas %f, y %f \\n\", pValor3, pValor4)\n\t// Probar pasar por referencia\n\tporRef1 := float32(5.5)\n\tporRef2 := float32(10.1)\n\n\t// Intercambiar valores por referencia\n\tporReferencia(&porRef1, &porRef2)\n\n\t// Imprimir valores modificados\n\t// Nota: En este caso, x e y ya han sido modificados directamente.\n\tfmt.Printf(\"Modificados: x = %f, y = %f\\n\", porRef1, porRef2)\n}\n\nfunc porValor(param1, param2 float32) (result1, result2 float32) {\n\tvar tmpValue float32\n\ttmpValue = param1\n\tparam1 = param2\n\tparam2 = tmpValue\n\treturn param1, param2\n}\nfunc porReferencia(a, b *float32) {\n\t*a, *b = *b, *a\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/go/hozlucas28.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc main() {\n\t/*\n\t   Variable assignment by value...\n\t*/\n\n\tfmt.Println(\"\\nVariable assignment by value...\")\n\n\tvar a int8 = 8\n\tvar b int8 = a\n\n\tfmt.Println(\"\\nvar a int8 = 8\\nvar b int8 = a\")\n\tfmt.Printf(\"\\nValue of 'a' = %d\\nValue of 'b' = %d\\n\", a, b)\n\n\ta = a * 4\n\n\tfmt.Println(\"\\na = a * 4\")\n\tfmt.Printf(\"\\nValue of 'a' = %d\\nValue of 'b' = %d\\n\", a, b)\n\n\tfmt.Println(\"\\n# ---------------------------------------------------------------------------------- #\")\n\n\t/*\n\t   Variable assignment by reference...\n\t*/\n\n\tfmt.Println(\"\\nVariable assignment by reference...\")\n\n\tc := []int{1, 2, 3, 4}\n\td := &c\n\n\tfmt.Println(\"\\nc := []int{1, 2, 3, 4}\\nd := &c\")\n\tfmt.Printf(\"\\nValue of 'c' = %d\\nValue of 'd' = %d\\n\", c, *d)\n\n\tc = append(c, 5)\n\n\tfmt.Println(\"\\nc = append(c, 5)\")\n\tfmt.Printf(\"\\nValue of 'c' = %d\\nValue of 'd' = %d\\n\", c, *d)\n\n\tfmt.Println(\"\\n# ---------------------------------------------------------------------------------- #\")\n\n\t/*\n\t   Function with an argument passed by value...\n\t*/\n\n\tfmt.Println(\"\\nFunction with an argument passed by value...\")\n\n\tconst value int8 = 2\n\tfnWithParamenterByValue := func(x int8) {\n\t\tx += 3\n\t}\n\n\tfmt.Println(\"\\nconst value int8 = 2\")\n\tfmt.Println(\"fnWithParamenterByValue := func(x int8) { x += 3 }\")\n\n\tfnWithParamenterByValue(value)\n\tfmt.Println(\"\\nfnWithParamenterByValue(value)\")\n\n\tfmt.Printf(\"\\nValue of 'value' = %d\\n\", value)\n\n\t/*\n\t\tFunction with an argument passed by reference...\n\t*/\n\n\tfmt.Println(\"\\nFunction with an argument passed by reference...\")\n\n\treference := []int{12}\n\tfnWithParamenterByReference := func(x *[]int) {\n\t\t*x = append(*x, (*x)[0]/2)\n\t}\n\n\tfmt.Println(\"\\nreference := []int{12}\")\n\tfmt.Println(\"fnWithParamenterByReference := func(x *[]int) { *x = append(*x, (*x)[0]/2) }\")\n\n\tfnWithParamenterByReference(&reference)\n\tfmt.Println(\"\\nfnWithParamenterByReference(&reference)\")\n\n\tfmt.Printf(\"\\nValue of 'reference' = %d\\n\", reference)\n\n\tfmt.Println(\"\\n# ---------------------------------------------------------------------------------- #\")\n\n\t/*\n\t   Additional challenge...\n\t*/\n\n\tfirstProgram := func(a int8, b int8) (int8, int8) {\n\t\tvar aux int8 = a\n\t\ta = b\n\t\tb = aux\n\n\t\treturn a, b\n\t}\n\n\tsecondProgram := func(a **[]int8, b **[]int8) (**[]int8, **[]int8) {\n\t\taux := *a\n\t\t*a = *b\n\t\t*b = aux\n\n\t\treturn a, b\n\t}\n\n\tconst arg01 int8 = 12\n\tconst arg02 int8 = 34\n\targ03 := []int8{1, 2, 3, 4, 5}\n\targ04 := []int8{6, 7, 8, 9, 10}\n\targ03Pointer := &arg03\n\targ04Pointer := &arg04\n\n\tnewArg01, newArg02 := firstProgram(arg01, arg02)\n\tnewArg03, newArg04 := secondProgram(&arg03Pointer, &arg04Pointer)\n\n\tfmt.Printf(\"\\nOriginal:\\n\targ01 = %d\\n\targ02 = %d\", arg01, arg02)\n\tfmt.Printf(\"\\nNew:\\n\tnewArg01 = %d\\n\tnewArg02 = %d\", newArg01, newArg02)\n\n\tfmt.Printf(\"\\n\\nOriginal:\\n\targ03 = %d\\n\targ04 = %d\", *arg03Pointer, *arg04Pointer)\n\tfmt.Printf(\"\\nNew:\\n\tnewArg03 = %d\\n\tnewArg04 = %d\", **newArg03, **newArg04)\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/go/kodenook.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc main() {\n\n\t/*\n\t\tAssignment by value\n\t*/\n\n\tvar var1 uint = 3\n\tvar var2 uint = var1\n\n\tvar1 = 4\n\n\tfmt.Println(var1)\n\tfmt.Println(var2)\n\n\t/*\n\t\tAssignment by reference\n\t*/\n\n\tvar var3 uint = 3\n\tvar var4 *uint = &var3\n\n\tvar3 = 5\n\n\tfmt.Println(var3)\n\tfmt.Println(*var4)\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/go/miguelex.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc pasoPorValor(x int) int {\n\tx = 0\n\treturn x\n}\n\nfunc pasoPorReferencia(x *int) int {\n\t*x = 0\n\treturn *x\n}\n\nfunc intercambioPorvalor(x int, y int) (int, int) {\n\treturn y, x\n}\n\nfunc intercambioPorReferencia(x *int, y *int) {\n\t*x, *y = *y, *x\n}\n\nfunc main() {\n\t// Declaracion de variable por valor\n\n\tfmt.Println(\"\\nDeclaracion de variable por valor\")\n\n\tvar num1 = 10\n\tvar num2 = num1\n\n\tfmt.Printf(\"\\nvar num1 %d \\nvar num2 %d \", num1, num2)\n\n\tnum1 = 20\n\n\tfmt.Printf(\"\\nvar num1 %d \\nvar num2 %d \", num1, num2)\n\n\t// Declaracion de variable por referencia\n\n\tfmt.Println(\"\\nDeclaracion de variable por referencia\")\n\n\tvar num3 = []int{1, 2, 3, 4}\n\tvar num4 = &num3\n\n\tfmt.Printf(\"\\nvar num3 %d \\nvar num4 %d \", num3, *num4)\n\n\tnum3[1] = 56789\n\n\tfmt.Printf(\"\\nvar num3 %d \\nvar num4 %d \", num3, *num4)\n\n\t// Paso por valor\n\n\tnum1 = 5\n\tfmt.Printf(\"\\nValor de var num1 = %d  antes de llamar a la funcion\", num1)\n\tnum2 = pasoPorValor(num1)\n\tfmt.Printf(\"\\nPaso por valor: var num1 =  %d \\nvar num2 = %d \", num1, num2)\n\t// Paso por Referencia\n\n\tnum1 = 5\n\n\tfmt.Printf(\"\\nValor de var num1 = %d  antes de llamar a la funcion\", num1)\n\tnum2 = pasoPorReferencia(&num1)\n\n\tfmt.Printf(\"\\nPaso por referencia: var num1 = %d \\nvar num2 = %d \", num1, num2)\n\n\tnum1 = 1\n\tnum2 = 2\n\n\tfmt.Printf(\"\\nValor de var num1 = %d \\nValor de var num2 = %d  antes de llamar a la funcion\", num1, num2)\n\n\tnum1, num2 = intercambioPorvalor(num1, num2)\n\n\tfmt.Printf(\"\\nIntercambio por valor: var num1 = %d \\nvar num2 = %d \\nvar num3 = %d \\nvar num4 = %d \", num1, num2, num3, num4)\n\n\tnum1 = 1\n\tnum2 = 2\n\n\tfmt.Printf(\"\\nValor de var num1 = %d \\nValor de var num2 = %d  antes de llamar a la funcion\", num1, num2)\n\n\tintercambioPorReferencia(&num1, &num2)\n\n\tfmt.Printf(\"\\nIntercambio por referencia: var num1 = %d \\nvar num2 = %d \", num1, num2, num3, num4)\n\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/go/qwik-zgheib.go",
    "content": "package main\n\nimport \"fmt\"\n\ntype Person struct {\n\tName string\n\tAge  int\n}\n\nfunc swapByValue(x, y int) {\n\tx, y = y, x\n}\n\nfunc swapByReference(a, b *int) {\n\t*a, *b = *b, *a\n}\n\nfunc incrementByValue(num int) {\n\tnum += 10\n}\n\nfunc changeNameByReference(p *Person) {\n\tp.Name = \"qwik\"\n}\n\nfunc main() {\n\tx := 10\n\ty := x\n\ty = 20\n\n\tfmt.Println(\"variables by value:\")\n\tfmt.Println(\"x:\", x)\n\tfmt.Println(\"y:\", y)\n\n\tslice1 := []int{1, 2, 3}\n\tslice2 := slice1\n\n\tslice2[0] = 100\n\n\tfmt.Println(\"\\nvariables by reference:\")\n\tfmt.Println(\"slice1:\", slice1)\n\tfmt.Println(\"slice2:\", slice2)\n\n\tnum := 5\n\tincrementByValue(num)\n\tfmt.Println(\"\\nafter calling incrementByValue:\", num)\n\n\t/* Extra exercise */\n\tperson := Person{Name: \"Abdul\", Age: 30}\n\tchangeNameByReference(&person)\n\tfmt.Println(\"\\nafter calling changeNameByReference:\", person)\n\tp, q := 10, 20\n\tswapByValue(p, q)\n\tfmt.Println(\"exchange for value:\")\n\tfmt.Println(\"p:\", p)\n\tfmt.Println(\"q:\", q)\n\n\ta, b := 30, 40\n\tswapByReference(&a, &b)\n\tfmt.Println(\"\\nexchange by reference:\")\n\tfmt.Println(\"a:\", a)\n\tfmt.Println(\"b:\", b)\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/go/thegera4.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc main() {\n\t// Asignación por valor: es cuando se asigna un valor directamente a una variable\n\n\ta := 5 // a es una variable que almacena el valor 5\n\tb := a // b es una variable que almacena el valor de a, pero no es una referencia a la dirección de memoria de a\n\tfmt.Println(a) // 5\n\tfmt.Println(\"b antes de cambiar su valor\", b) // 5\n\tb = 10 // b es una variable que almacena el valor 10, pero no es una referencia a la dirección de memoria de a\n\tfmt.Println(\"b después de cambiar su valor\", b) // 10\n\n\t// Asignación por referencia: es cuando se asigna una dirección de memoria a una variable, \n\t// la cual apunta a otra variable ya existente y que puede ser modificada\n\n\tc := &a // c es un puntero a la dirección de memoria de a\n\tfmt.Println(c) // 0xc0000b6010 (dirección de memoria de a)\n\td := c // d es un puntero a la dirección de memoria de a (por medio de c)\n\tfmt.Println(d) // 0xc0000b6010 (dirección de memoria de a porque c es un puntero a la dirección de memoria de a)\n\t*d = 10 // d es un puntero a la dirección de memoria de a, por lo que al modificar *d, se modifica el valor de a y lo relacionado\n\tfmt.Println(a) // 10\n\tfmt.Println(*c) // 10\n\tfmt.Println(*d) // 10\n\n\tx, y := 5, 10\n\n\t// Ejemplo de funcion con parámetros por valor \n\n\tfmt.Println(\"x antes de sumByValue\", x) // 5\n\tfmt.Println(\"y antes de sumByValue\", y) // 10\n\tresultByValue := sumByValue(x, y)\n\tfmt.Println(\"Resultado de sumByValue\", resultByValue) // 30\n\tfmt.Println(\"x después de sumByValue\", x) // 5\n\tfmt.Println(\"y después de sumByValue\", y) // 10\n\n\t// Ejemplo de funcion con parámetros por referencia\n\n\tfmt.Println(\"x antes de sumByRef\", x) // 5\n\tfmt.Println(\"y antes de sumByRef\", y) // 10\n\tresultByRef := sumByRef(&x, y)\n\tfmt.Println(\"Resultado de sumByRef\", resultByRef) // 30\n\tfmt.Println(\"x después de sumByRef\", x) // 20\n\tfmt.Println(\"y después de sumByRef\", y) // 10\n\n\t// Dificultad extra\n\n\tp1V1, p1V2 := 5, 10\n\n\tfmt.Println(\"p1V1 antes de intercambiar swapByValue\", p1V1) // 5\n\tfmt.Println(\"p1V2 antes de intercambiar swapByValue\", p1V2) // 10\n\tp1V1, p1V2 = swapByValue(p1V1, p1V2)\n\tfmt.Println(\"p1V1 después de intercambiar swapByValue\", p1V1) // 10\n\tfmt.Println(\"p1V2 después de intercambiar swapByValue\", p1V2) // 5\n\tfmt.Println(\"p1V1 antes de intercambiar swapByRef\", p1V1) // 10\n\tfmt.Println(\"p1V2 antes de intercambiar swapByRef\", p1V2) // 5\n\tp1V1, p1V2 = swapByRef(&p1V1, p1V2)\n\tfmt.Println(\"p1V1 después de intercambiar swapByRef\", p1V1) // 5\n\tfmt.Println(\"p1V2 después de intercambiar swapByRef\", p1V2) // 10\n\n}\n\nfunc sumByValue(a, b int) int {\n\ta = 20 //modificamos el valor de x, pero no afecta a la variable original si no que se crea una copia de x\n\treturn a + b\n}\n\nfunc sumByRef(a *int, b int) int {\n\t*a = 20 //modificamos el valor de x, y afecta a la variable original al ser un puntero a la dirección de memoria de x\n\treturn *a + b\n}\n\nfunc swapByValue(a, b int) (int, int) {\n\treturn b, a\n}\n\nfunc swapByRef(a *int, b int) (int, int) {\n\treturn b, *a\n}"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/java/AbelADE.java",
    "content": "public class Main {\n\n    public static void value(int number) {\n        System.out.println(\"El valor del número recibido es: \" + number);\n        number += 5;\n        System.out.println(\"Sumado a 5 es igual a \" + (number));\n    }\n\n    public static void value(User user) {\n        System.out.println(\"El usuario recibido es: \" + user);\n        user.setName(\"Marcos\");\n        System.out.println(\"El nuevo nombre del usuario es: \" + user);\n    }\n\n    public static void main(String[] args) {\n\n        /*\n         * Paso de variables por valor: pasan 'una copia' de su valor a un parámetro, sin ser ella misma modificada.\n         */\n        int variable = 15;\n        value(variable);\n        System.out.println(\"El valor de la variable enviada cómo parámetro es: \" + variable + \"\\n\");\n\n        /*\n         * Paso de variables por referencia: en Java no existe el paso por referencia, aunque algo muy similar ocurre\n         * con los objetos, ya que se guardan cómo una dirección de memoria y al pasarla cómo parámetro, se envía la\n         * dirección de memoria y se trabaja sobre esos datos (lo que significa que cambiamos el objeto al cambiar los\n         * datos asociados con una dirección de memoria concreta).\n         */\n\n        User user = new User(\"Abel\",29);\n        value(user);\n        System.out.println(\"El valor del objeto enviado cómo parámetro es: \" + user + \"\\n\");\n\n    }\n}\n\nclass User {\n    //Atributos\n    String name;\n    int age;\n\n    //Métodos de acceso\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public int getAge() {\n        return age;\n    }\n\n    public void setAge(int age) {\n        this.age = age;\n    }\n\n    //Constructor\n    public User(String name, int age) {\n        this.name = name;\n        this.age = age;\n    }\n\n    //Método que se invoca de forma automática al querer mostrar el objeto por consola.\n    @Override\n    public String toString() {\n        return name;\n    }\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/java/Alextc35.java",
    "content": "/*                                                                                                                \n * EJERCICIO:                                                                                                     \n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según                            \n *   su tipo de dato.                                                                                             \n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y                                   \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.                         \n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)                                    \n *                                                                                                                \n * DIFICULTAD EXTRA (opcional):                                                                                   \n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.               \n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.                  \n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno                       \n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las               \n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.                 \n *   Comprueba también que se ha conservado el valor original en las primeras.                                    \n */\n\npublic class Alextc35 {\n    public static void main(String[] args) {\n        // Asignación de variables \"por valor\"\n        System.out.println(\"\\n--- Asignación de variables por valor ---\");\n        int x = 10;\n        System.out.println(\"- Antes de llamar a la función: x = \" + x);\n        modificarPrimitivo(x);\n        System.out.println(\"\\n- Después de llamar a la función: x = \" + x);\n        System.out.println(\"-----------------------------------------\");\n\n        // Asignación de variables \"por referencia\"\n        System.out.println(\"\\n------- Asignación por referencia -------\");\n        Persona persona = new Persona(\"Alejandro\");\n        System.out.println(\"- Antes de llamar a la función:\\npersona.nombre = \"\n                + persona.nombre);\n        modificarObjeto(persona);\n        System.out.println(\"\\n- Después de llamar a la función:\\npersona.nombre = \"\n                + persona.nombre);\n        System.out.println(\"-----------------------------------------\");\n\n        // Modificación de Referencia de Objeto\n        System.out.println(\"\\n------- Modificación de Referencia -------\");\n        Persona persona2 = new Persona(\"Barry Allen\");\n        System.out.println(\"- Antes de llamar a la función:\\npersona2.nombre = \" + persona2.nombre);\n        cambiarReferencia(persona2);\n        System.out.println(\"\\n- Después de llamar a la función:\\npersona2.nombre = \" + persona2.nombre);\n        System.out.println(\"-----------------------------------------\");\n\n        // Opcional\n        // Intercambio por valor\n        System.out.println(\"\\n--- Intercambio de valores por valor ---\");\n        int a = 5;\n        int b = 10;\n        System.out.println(\"\\n- Antes de llamar a la función:\\na = \" + a + \"\\nb = \" + b);\n        // Llamada al método para intercambiar valores\n        int[] resPorValor = swapPorValor(a, b);\n        // Resultados después de la llamada\n        int nuevoA = resPorValor[0];\n        int nuevoB = resPorValor[1];\n        System.out.println(\"\\n- Después de intercambiar por valor:\\na = \" + a\n                + \"\\nb = \" + b + \"\\nnuevoA = \" + nuevoA + \"\\nnuevoB = \" + nuevoB);\n        System.out.println(\"-----------------------------------------\");\n\n        // Intercambio por referencia\n        System.out.println(\"\\n- Intercambio de valores por referencia -\");\n        Par par1 = new Par(5);\n        Par par2 = new Par(10);\n        System.out.println(\"\\n- Antes de llamar a la función:\\npar1.valor = \" + par1.valor\n                + \"\\npar2.valor = \" + par2.valor);\n        // Llamada al método para intercambiar valores\n        Par[] resPorReferencia = swapPorReferencia(par1, par2);\n        // Resultados después de la llamada\n        Par nuevoPar1 = resPorReferencia[0];\n        Par nuevoPar2 = resPorReferencia[1];\n        System.out.println(\"\\n- Después de intercambiar por referencia:\\npar1.valor = \" + par1.valor\n                + \"\\npar2.valor = \" + par2.valor + \"\\nnuevoPar1.valor = \" + nuevoPar1.valor\n                + \"\\nnuevoPar2.valor = \" + nuevoPar2.valor);\n    }\n\n    // Opcional MÉTODO 1\n    public static int[] swapPorValor(int x, int y) {\n        int temp = x;\n        x = y;\n        y = temp;\n        return new int[] { x, y };\n    }\n\n    // Opcional MÉTODO 2\n    public static Par[] swapPorReferencia(Par p1, Par p2) {\n        int temp = p1.valor;\n        p1.valor = p2.valor;\n        p2.valor = temp;\n        return new Par[] { p1, p2 };\n    }\n\n    // Asignación de variables \"por valor\"\n    public static void modificarPrimitivo(int a) {\n        a = 20; // Modifica la copia local, no afecta a la variable original\n    }\n\n    // Asignación de variables \"por referencia\"\n    public static void modificarObjeto(Persona p) {\n        p.nombre = \"Alex\"; // Modifica el objeto al que p apunta\n    }\n\n    // Modificación de Referencia de Objeto\n    public static void cambiarReferencia(Persona p) {\n        p = new Persona(\"The Flash\"); // Cambia la referencia local, no afecta a la variable original\n    }\n}\n\n// Clase Persona\nclass Persona {\n    String nombre;\n\n    Persona(String nombre) {\n        this.nombre = nombre;\n    }\n}\n\n// Opcional\n// Clase que representa un par de valores\nclass Par {\n    int valor;\n\n    Par(int valor) {\n        this.valor = valor;\n    }\n}"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/java/AmadorQuispe.java",
    "content": "public class AmadorQuispe {\n    public static void main(String[] args) {\n        /*\n         * Todos los tipos primitivos se pasan por valor\n         */\n        int age;\n        age = 35;\n        System.out.println(age);\n        changeAge(age); // pasamos a una función que asigna otro valor\n        System.out.println(age); // observamos que no cambia por se pasa copia (valor)\n\n        /*\n         * Todos los arreglos y objetos se pasan por referencia\n         */\n        // Ejemplo con arreglo\n        double[] prices = { 10.23, 34.00, 12.00 };\n        System.out.println(\"Precios\");\n        for (double price : prices) {\n            System.out.println(price);\n        }\n        changeArray(prices); // Se pasa a una función donde se cambia\n        System.out.println(\"Precios despues de cambio\");\n        for (double price : prices) {\n            System.out.println(price);\n        }\n        // Ejemplo con objeto\n        Person person = new Person();\n        person.setName(\"Amador\");\n        person.setAge(29);\n\n        System.out.println(person);\n        changePerson(person);\n\n        /*\n         * las clases Wrappers(String, Integer, Double...) son inmutables, quiere decir\n         * que una vezasignado no su valor no se puede cambiar\n         */\n        Double d = 89.00;\n        System.out.println(d);\n        changeAge(d);\n        System.out.println(\"post\" + d);\n    }\n\n    static void changeAge(int age) {\n        age = 40;\n    }\n\n    static void changeArray(double[] prices) {\n        for (int i = 0; i < prices.length; i++) {\n            prices[i] = prices[i] + 10;\n        }\n    }\n\n    static void changePerson(Person person) {\n        System.out.println(person);\n    }\n\n    static void changeAge(Double d) {\n        d = 23.00;\n    }\n}\n\nclass Person {\n    private String name;\n    private int age;\n\n    public Person() {\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public int getAge() {\n        return age;\n    }\n\n    public void setAge(int age) {\n        this.age = age;\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/java/AnaLauDB.java",
    "content": "public class AnaLauraDB {\n    public static void main(String[] args) {\n        System.out.println(\"AnaLauraDB está lista para usarse.\\n\");\n\n        // Ejemplo de asignación por valor (tipos primitivos)\n        int a = 5;\n        int b = a; // b recibe el valor de a\n        b = 10; // modificar b no afecta a\n        System.out.println(\"Por valor:\");\n        System.out.println(\"a = \" + a); // 5\n        System.out.println(\"b = \" + b); // 10\n\n        System.out.println();\n\n        // Ejemplo de asignación por referencia (objetos)\n        int[] arr1 = { 1, 2, 3 };\n        int[] arr2 = arr1; // arr2 referencia el mismo arreglo que arr1\n        arr2[0] = 99; // modificar arr2 afecta a arr1\n        System.out.println(\"Por referencia:\");\n        System.out.print(\"arr1 = \");\n        imprimirArreglo(arr1); // 99, 2, 3\n        System.out.print(\"arr2 = \");\n        imprimirArreglo(arr2); // 99, 2, 3\n\n        System.out.println();\n\n        // Función con variable por valor\n        int x = 20;\n        modificarPorValor(x);\n        System.out.println(\"Después de modificarPorValor(x): x = \" + x); // sigue siendo 20\n\n        System.out.println();\n\n        // Función con variable por referencia\n        int[] valores = { 7, 8, 9 };\n        modificarPorReferencia(valores);\n        System.out.print(\"Después de modificarPorReferencia(valores): valores = \");\n        imprimirArreglo(valores); // primer elemento cambiado a 100\n\n        // EXTRA:\n\n        System.out.println(\"\\nEXTRA: Intercambio de valores\");\n        // Intercambio por valor (tipos primitivos)\n        int val1 = 100;\n        int val2 = 200;\n        int[] nuevosValores = intercambiarPorValor(val1, val2);\n        System.out.println(\"\\nIntercambio por valor:\");\n        System.out.println(\"Originales: val1 = \" + val1 + \", val2 = \" + val2);\n        System.out.println(\"Nuevos:     val1 = \" + nuevosValores[0] + \", val2 = \" + nuevosValores[1]);\n\n        // Intercambio por referencia (arreglos)\n        int[] ref1 = { 1, 2, 3 };\n        int[] ref2 = { 4, 5, 6 };\n        int[][] nuevosRefs = intercambiarPorReferencia(ref1, ref2);\n        System.out.println(\"\\nIntercambio por referencia:\");\n        System.out.print(\"Originales: ref1 = \");\n        imprimirArreglo(ref1);\n        System.out.print(\"            ref2 = \");\n        imprimirArreglo(ref2);\n        System.out.print(\"Nuevos:     ref1 = \");\n        imprimirArreglo(nuevosRefs[0]);\n        System.out.print(\"            ref2 = \");\n        imprimirArreglo(nuevosRefs[1]);\n    }\n\n    // Función que recibe un int (por valor)\n    public static void modificarPorValor(int n) {\n        n = 50;\n    }\n\n    // Función que recibe un arreglo (por referencia)\n    public static void modificarPorReferencia(int[] arr) {\n        arr[0] = 100;\n    }\n\n    // Utilidad para imprimir arreglos\n    public static void imprimirArreglo(int[] arr) {\n        for (int i = 0; i < arr.length; i++) {\n            System.out.print(arr[i]);\n            if (i < arr.length - 1)\n                System.out.print(\", \");\n        }\n        System.out.println();\n\n    }\n\n    // Intercambio por valor\n    public static int[] intercambiarPorValor(int a, int b) {\n        int temp = a;\n        a = b;\n        b = temp;\n        return new int[] { a, b };\n    }\n\n    // Intercambio por referencia\n    public static int[][] intercambiarPorReferencia(int[] arr1, int[] arr2) {\n        int[] temp = arr1.clone();\n        arr1 = arr2.clone();\n        arr2 = temp;\n        return new int[][] { arr1, arr2 };\n    }\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/java/AndrewCodev.java",
    "content": "import java.util.ArrayList;\n\npublic class AndrewCodev {\n\t\n\tint numeroRef;\n\tint numeroRef2;\n\t\n\tpublic static void main(String[] args) {\n\t\tAndrewCodev andrewCodev = new AndrewCodev();\n\t\t//Asignación de Variable por valor\t\t\n\t\t//EJEMPLO ASIGNACIÓN DE VARIBALE POR VALOR\n\t\t/*En Java, los tipos de datos primitivos se asignan por valor. \n\t\t *Esto significa que cuando asignas una variable a otra, se copia el valor \n\t\t * y no la referencia.\n\t\t */\n\t\t//Asignación de Variable por valor\n\t\tint numeroVal = 5;\n\t\tint numeroVal2 = numeroVal; // b obtiene el valor 5\n\t\tnumeroVal2 = 10; // cambiar b no afecta a\n\n\t\tSystem.out.println(\"a: \" + numeroVal); // a sigue siendo 5\n\t\tSystem.out.println(\"b: \" + numeroVal2); // b es 10\n\t\t\n\t\t//EJEMPLO ASIGNACIÓN DE VARIBALE POR REFERENCIA\n\t\tArrayList<String> list1 = new ArrayList<>();\n\t\tlist1.add(\"Elemento 1\");\n\n\t\tArrayList<String> list2 = list1; // list2 se refiere al mismo objeto que list1\n\n\t\tlist2.add(\"Elemento 2\"); // agregar un elemento a list2 afecta a list1\n\n\t\tSystem.out.println(\"list1: \" + list1); // list1 contiene [\"Elemento 1\", \"Elemento 2\"]\n\t\tSystem.out.println(\"list2: \" + list2); // list2 contiene [\"Elemento 1\", \"Elemento 2\"]\n\t\t\n\t\t\n\t\t//EJERCICIO DE ASIGNACIÓN DE VALOR Y REFERENCIA\n\t\tSystem.out.println(\"\\n\\nEJERCICIO DE ASIGNACIÓN DE VALOR\");\n\t\tint num1 = 3;\n\t\tint num2 = 6;\n\t\tSystem.out.println(\"num1 = \"+num1);\n\t\tSystem.out.println(\"num2 = \"+num2);\n\t\tint[] intercambio = pasarValor(num1, num2);\n\t\tSystem.out.println(\"Se intercambian los numeros a través del método pasarValor(num1, num2) \");\n\t\tint num3 = intercambio[0];\n\t\tint num4 = intercambio[1];\n\t\tSystem.out.println(\"num3 = num1 con el valor de num2: \"+num3);\n\t\tSystem.out.println(\"num4 = num2 con el valor de num1: \"+num4);\n\t\tSystem.out.println(\"num1 = \"+num1);\n\t\tSystem.out.println(\"num2 = \"+num2);\n\t\t\n\t\t/*En Java, los objetos y arreglos se asignan por referencia.\n\t\t *Esto significa que cuando asignas una variable a otra, ambas variables \n\t\t *se refieren al mismo objeto en la memoria.*/\n\t\t\n\t\tSystem.out.println(\"\\n\\nEJERCICIO DE ASIGNACIÓN DE REFERENCIA\");\n\t\tandrewCodev.numeroRef = 5;\n\t\tandrewCodev.numeroRef2 = 10;\n\t\tSystem.out.println(\"numeroRef = \"+andrewCodev.numeroRef);\n\t\tSystem.out.println(\"numeroRef2 = \"+andrewCodev.numeroRef2);\n\t\tint[] intercambioR = andrewCodev.pasarPorReferencia(andrewCodev);\n\t\tSystem.out.println(\"\\nSe intercambian los numeros a través del método \"\n\t\t\t\t+ \"\\nandrewCodev.pasarPorReferencia(andrewCodev) \"\n\t\t\t\t+ \"\\nrecibiendo como parámetro el objeto andrewCodev\");\n\t\tint numeroRef3 = intercambioR[0];\n\t\tint numeroRef4 = intercambioR[1];\n\t\tSystem.out.println(\"numeroRef3 = numeroRef con el valor de numeroRef2: \"+numeroRef3);\n\t\tSystem.out.println(\"numeroRef4 = numeroRef2 con el valor de numeroRef: \"+numeroRef4);\n\t\tSystem.out.println(\"numeroRef = \"+andrewCodev.numeroRef);\n\t\tSystem.out.println(\"numeroRef2 = \"+andrewCodev.numeroRef2);\n\t}\n\t\n\tpublic static int[] pasarValor(int numeroVal, int numeroVal2) {\n\t\tnumeroVal = numeroVal2;\n\t\tnumeroVal2 = numeroVal;\n\t\t\n\t\tint[] arrEnteros = {numeroVal, numeroVal2};\n\t\treturn arrEnteros;\n\t}\n\t\n\tpublic int[] pasarPorReferencia(AndrewCodev andrewCodev) {\n\t\tandrewCodev.numeroRef = andrewCodev.numeroRef2;\n\t\tandrewCodev.numeroRef2 = andrewCodev.numeroRef;\n\t\t\n\t\tint[] arrEnteros = {andrewCodev.numeroRef, andrewCodev.numeroRef2};\n\t\treturn arrEnteros;\n\t}\n}"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/java/DiegoIBB.java",
    "content": "package Valor_y_Referencia_05;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.HashMap;\n\n/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n*/\n\n// CONTINUAR CON DIFICULTAD EXTRA METODOS CON DIFERENTES TIPOS DE DATOS\t\n\n//-------- REFERENCIAS --------\t\n// https://javarush.com/es/groups/posts/es.2642.tipos-de-datos-de-referencia-en-java\n// https://somoshackersdelaprogramacion.es/paso-por-valor-y-paso-por-referencia-de-variables-en-java\n\n\n//Ejemplo: Objeto como referencia\nclass Car{ \n\tString brand;\n\tfloat milage;\n\tint cost;\n}\n\npublic class Valor_Referencia_05 {\n\t\n\t/*Tipos primitivos (int, char, short, long, double, float, boolean, byte) siempre se pasan por VALOR en los métodos (mutables)\n\t *las variables de tipos primitivos crean copias de dichas variables para que los métodos operen sobre las copias (valor) en lugar de\n\t *las variables orignales, son elementos mutables.\n\t*/\n\t\n\t/*Los objetos o instancias de una clase siempre se pasan por REFERENCIA a los métodos (inmutables)\n\tlos objetos pasan por referencia a un método, lo que quiere decir que al momento en que una instancia de un objeto entra a un método\n\tse cambia el valor original del objeto, no se crean copias.\n\t*/\n\t\n\tpublic static void main(String[]args) {\n\t\t\n\t\t//--------- PARAMETROS POR VALOR ---------\n\t\t\n\t\t/*Un parámetro por valor pasa una copia de la variable a un método y\n\t\t * opera sobre ella, sin modificar la variable original, ya que trabajamos\n\t\t * sobre direcciones de memoria diferentes*/\n\t\t\n\t\tint a = 45;\n\t\tint b = 34;\n\t\t\n\t\tSystem.out.println(\"Variable a sin modificar: \" + a);\n\t\tSystem.out.println(\"Variable b sin modificar: \" + b);\n\t\tSystem.out.println(\"Suma de elementos: \" + suma(a, b));\n\t\tSystem.out.println(\"Copia de b al doble: \" + doubl(b));\n\t\tSystem.out.println(\"Variable a: \" + a);\n\t\tSystem.out.println(\"Variable b: \" + b);\n\t\t\n\t\t//--------- PARAMETROS POR REFERENCIA ---------\n\t\t\n\t\t/* Los parámetros por referencia son aquellos parámetros que pasan la\n\t\t * dirección de la variable orginal a un método y este actua sobre ella,\n\t\t * modificando el valor interno de la variable referenciada*/\n\t\t\n\t\tString Estado = \"Pensilvania\";\n\t\tString Ciudad = \"Filadelfia\";\n\t\t\n\t\tSystem.out.println(Estado); // Cadena sin modificar\n\t\tSystem.out.println(Ciudad); // Cadena sin modificar\n\t\tSystem.out.println(upper(Estado)); // Cadena modificada, pasamos una copia de la variable State a la función\n\t\tSystem.out.println(Ciudad + \"del estado de\" + Estado);\n\t\t\n\n\t\t\n\t\t// Los datos usados como valor o referencia varían según el tipo de datos del que se trate\n\t\t\n\t\t//--------------------------------------------------------------------------------------\n\t\t//----------- DATOS PRIMITIVOS (INT, CHAR, BOOLEAN, FLOAT, DOUBLE) Mutables ------------\n\t\t//--------------------------------------------------------------------------------------\n\t\t// Estos datos son pasados por valor\n\t\t\n\t\tint entero = 12;\n\t\tchar caracter = 'S';\n\t\tboolean booleano_1 = true;\n\t\tfloat flotante_1 = 34.5f;\n\t\tfloat flotante_2 = 14.8f;\n\t\tdouble Double = 45.6;\n\t\t\n\t\t// EJEMPLO CON DATO FLOTANTE (parámetro por valor)\n\t\tSystem.out.println(\"Resultado de la resta: \" +(resta(flotante_1, flotante_2))); // El valor obtenido es gracias a las copias que entraron a la función\n\t\tSystem.out.println(\"Flotante 1 original: \" + flotante_1); // La variable original no cambia\n\t\tSystem.out.println(\"Flotante 2 original: \" + flotante_2); // La variable original no cambia\n\t\t\t\t\n\t\t// EJEMPLO CON DATO BOOLEANO (parámetro por valor)\n\t\tSystem.out.println(booleano_1);\n\t\t//boolean booleano_2 = bool(booleano_1); Si guardaramos el resultado de la función en otra variable lo estamos alojando en otro espacio de memoria\n\t\tSystem.out.println(bool(booleano_1));// El valor de la COPIA de booleano_1 pasado como parámetro cambia a false dentro del método\n\t\tSystem.out.println(booleano_1); //El valor original de booleano_1 permanece igual\n\t\t\n\t\t\n\t\t//--------------------------------------------------------------------------------------\n\t\t//----- DATOS DE REFERENCIA (hacen referencia a un objeto) (STRING) Inmutables ---------\n\t\t//--------------------------------------------------------------------------------------\n\t\t// Estos datos son pasados por referencia\n\t\t\n\t\t/*String no es un tipo de dato sino que es una clase, podemos crear objetos de tipo string*/\n\t\t\n\t\tString objeto_string = new String();\n\t\tobjeto_string = \"Este es un objeto\";\n\t\tString variable_String = \"Este tambien es un objeto\";\n\t\tSystem.out.println(variable_String);\n\n\t\tvariable_String = objeto_string;\n\t\t\n\t\t//Asignamos al objeto variable_string una copia de la dirección del objeto objeto_string\n\t\t//al hacer esto el objeto variable_String quedo sin variable que haga referencia a él (no podemos acceder a él)\n\t\tSystem.out.println(variable_String); // --> La variable original variable_String pese a que usa memoria  no tiene mayor utilidad\n\t\tSystem.out.println(objeto_string);\n\t\t\n\t\t\n\t\t/* IMPORTANTE:\n\t\t * Los Arrays son un tipo de dato intermedio entre primitivos y objetos,\n\t\t * y su paso siempre se realiza por referencia \n\t\t * */\n\t\t\n\t\t\n\t\t//-------------------------------------------\n\t\t//--------- OBJETOS COMO REFERENCIA ---------\n\t\t//-------------------------------------------\n\t\t\n\t\t/* Los objetos siempre son pasados por referencia dentro de una función, salvo los objetos inmutables \n\t\t * (aquel objeto en el que cada vez que se realiza una modificación sobre el mismo se crea una copia \n\t\t * automáticamente del mismo), un ejemplo clásico es el objeto String\n\t\t * \n\t\t */\n\n\t\tCar auto_1 = new Car(); //Creamos una instancia u objeto de la clase Car llamado auto_1 y seteamos sus valores\n\t\tauto_1.brand = \"Porsche\";\n\t\tauto_1.milage = 24.5f;\n\t\tauto_1.cost = 150000;\n\t\t\n\t\tSystem.out.println(auto_1.brand);\n\t\tSystem.out.println(auto_1.milage);\n\t\tSystem.out.println(auto_1.cost);\n\t\t\n\t\t/* Creamos una referencia, no es un objeto, para que fuera un objeto debería tener la estructura\n\t\t * \"Car auto_2 = new Car();\", esta podría considerarse como una clase vacia\n\t\t * */\n\t\tCar auto_2;\n\t\t\n\t\t/* Le asignamos la referencia del objeto a la que declaramos anteriormente, ahora\n\t\t * ambas tienen la misma dirección en la memoria\n\t\t * */\n\t\tauto_2 = auto_1;\n\t\t\n\t\t//Vemos que al imprimir la referencia obtenemos los mismos valores de la referencia auto_1, al compartir la misma dirección sus valores son los mismos\n\t\tSystem.out.println(auto_2.brand);\n\t\tSystem.out.println(auto_2.milage);\n\t\tSystem.out.println(auto_2.cost);\n\t\t\n\t\t//Le asginamos nuevos valores a la referencia auto_2\n\t\tauto_2.brand = \"BMW\";\n\t\tauto_2.milage = 15.5f;\n\t\tauto_2.cost = 100000;\n\t\t\n\t\t//Imprimimos los valores que le dimos a la referencia y vemos que cambian, luego imprimimos los de la referencia auto_1\n\t\tSystem.out.println(auto_2.brand);\n\t\tSystem.out.println(auto_2.milage);\n\t\tSystem.out.println(auto_2.cost);\n\t\t\n\t\t//Vemos que al imprimir la referencia auto-1 sus valores cambian a los que le asignamos a la referencia auto_2\n\t\tSystem.out.println(auto_1.brand);\n\t\tSystem.out.println(auto_1.milage);\n\t\tSystem.out.println(auto_1.cost);\n\t\t\n\t\t/*Estos cambios se producen porque las referencias son las mismas debido a que comparten la misma locación en la \n\t\t * memoría, si una de las 2 sufre algún cambio dicho cambio afectará a la otra*/\n\t\t\n\t\tCar auto_3 = new Car(); //Creamos un objeto auto_3\n\t\tauto_3 = auto_1; // Le asignamos los mismos valores que auto_1\n\n\t\t// Al imprimir auto_3 vemos que conserva los mismos valores que auto_1\n\t\tSystem.out.println(auto_3.brand);\n\t\tSystem.out.println(auto_3.milage);\n\t\tSystem.out.println(auto_3.cost);\n\t\t\n\t\t// Si cambiamos sus valores al imprimirlos vemos que cambian\n\t\tauto_3.brand = \"Audi\";\n\t\tauto_3.milage = 20.8f;\n\t\tauto_3.cost = 90000;\n\t\t\n\t\tSystem.out.println(auto_3.brand);\n\t\tSystem.out.println(auto_3.milage);\n\t\tSystem.out.println(auto_3.cost);\n\t\t\n\t\t//Sinembargo al pasar la referencia del objeto auto_1 vemos que estos tambien cambiaron, ya que ambos comparten la misma dirección\n\t\tSystem.out.println(auto_1.brand);\n\t\tSystem.out.println(auto_1.milage);\n\t\tSystem.out.println(auto_1.cost);\n\t\t\n\t\t/*Conclusión: En JAVA los objetos creado por nosotros dentro del programa tienen paso por referencia\n\t\t*/\n\t\t\t\t\n\t\t/*\n\t\t * DIFICULTAD EXTRA (opcional):\n\t\t * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n\t\t * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n\t\t *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n\t\t *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n\t\t *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n\t\t *   Comprueba también que se ha conservado el valor original en las primeras.\n\t\t*/\n\t\t\n\t\t// Programa_1: Pasa valores por referencia\n\t\t\n\t\tSystem.out.println(\"------ DIFICULTAD EXTRA ------\");\n\t\tSystem.out.println(\"------- Parámetros por Referencia -------\");\n\t\tString byRef1 = \"Cadena referencia 1\";\n\t\tString byRef2 = \"Cadena referencia 2\";\n\t\t\n\t\tSystem.out.println(\"Valor byRef1 original: \" + byRef1);\n\t\tSystem.out.println(\"Valor byRef2 original: \" + byRef2);\n\t\tString[]result_ref = byReference(byRef1, byRef2);\n\t\tSystem.out.println(\"Valor byRef1 modificado: \" + result_ref[0]);\n\t\tSystem.out.println(\"Valor byRef2 modificado: \" + result_ref[1]);\n\t\tSystem.out.println(\"Valor byRef1 original: \" + byRef1);\n\t\tSystem.out.println(\"Valor byRef2 original: \" + byRef2);\n\t\t\n\t\tSystem.out.println(\"------- Parámetros por Valor -------\");\n\t\tint byVal1 = 435;\n\t\tint byVal2 = 211;\n\t\t//Valores originales\n\t\tSystem.out.println(\"Valor byVal1 original: \" + byVal1);\n\t\tSystem.out.println(\"Valor byVal1 original: \" + byVal2);\n\t\tint []result_val = byValue(byVal1, byVal2);\n\t\t//Valores invertidos\n\t\tSystem.out.println(\"Valor modificado byVal1: \" + result_val[0]);\n\t\tSystem.out.println(\"Valor modificado byVal1: \" + result_val[1]);\n\t\t//Valores originales conservados\n\t\tSystem.out.println(\"Valor byVal1 original: \" + byVal1);\n\t\tSystem.out.println(\"Valor byVal1 original: \" + byVal2);\n\n\t}\n\t\n\t//METODOS DE EJEMPLO\n\t\n\tstatic int suma(int x, int y) {\n\t\tint sum;\n\t\tsum = x + y;\n\t\treturn sum;\n\t}\n\t\n\tstatic float resta(float e, float f) {\n\t\tfloat res;\n\t\tres = e - f;\n\t\treturn res;\n\t}\n\t\n\tpublic static int doubl(int d) {\n\t\tint doub;\n\t\tdoub = d * 2;\n\t\treturn doub;\n\t}\n\tpublic static String upper(String x){\n\t\tString s;\n\t\ts = x.toUpperCase();\n\t\treturn s;\n\t}\n\tpublic static boolean bool(boolean b) {\n\t\tboolean b_change = !b; // Negamos el valor de boolean b con el operador de negación \"!\", si es true pasa a false y viceversa \n\t\treturn b_change;\n\t}\n\t\n\t//DIFICULTAD EXTRA\n\t\n//\tstatic Map<String, Integer>[] programa_1 (String cadena, int entero) {\n//\t\tString var_aux = cadena;\n//\t\tint copiaCadena = entero;\n//\t\tString copiaEntero = var_aux;\n//\t\t\n//\t\treturn Map[]{copiaEntero, copiaCadena};\n//\t}\n\t\n\tstatic int [] byValue(int i1, int i2){\n\t\tint iAux = i1;\n\t\tint int1 = i2;\n\t\tint int2 = iAux;\n\t\t\n\t\tint [] resultVal = {int1, int2};\n\t\treturn resultVal;\n\t}\n\t\n\t//Investigar setter y getter para obtener valores por referencia en la función\n\t\n\tstatic String [] byReference(String s1, String s2) {\n\t\tString sAux = s1;\n\t\tString string_1 = s2;\n\t\tString string_2 = sAux;\n\t\t\n\t\tString [] resultRef = {string_1, string_2};\n\t\treturn resultRef;\n\t\t\n\t}\n\n}\n\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/java/FranDev200.java",
    "content": "\npublic class FranDev200 {\n\n    /*\n     * EJERCICIO:\n     * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n     *   su tipo de dato.\n     * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y\n     *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n     * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n     *\n     * DIFICULTAD EXTRA (opcional):\n     * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n     * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n     *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n     *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n     *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n     *   Comprueba también que se ha conservado el valor original en las primeras.\n     */\n\n    static void main() {\n\n        System.out.println(\"Asignacion por valor\");\n        System.out.println(\"====================\");\n        int x = 10;\n        System.out.println(\"Antes de modificar el valor de x=\" + x);\n        modificarPorValor(x);\n        System.out.println(\"Después de modificar el valor de x=\" + x);\n        System.out.println(\"=====================================\");\n        System.out.println(\"Asignacion por referencia\");\n        System.out.println(\"=========================\");\n        Animal animal = new Animal(\"Rubi\");\n        System.out.println(\"Antes de modificar el nombre: \" + animal.name);\n        modificarPorReferencia(animal);\n        System.out.println(\"Después de modificar el nombre: \" + animal.name);\n        System.out.println(\"====================================\");\n\n        System.out.println(\"\\nEJERCICIO EXTRA\");\n        System.out.println(\"===============\");\n        System.out.println(\"Intercambios por valor\");\n        int a = 20;\n        int b = 10;\n        System.out.println(\"======================\");\n        System.out.println(\"Antes de intercambiarlos\");\n        System.out.println(\"------------------------\");\n        System.out.println(\"a = \" + a);\n        System.out.println(\"b = \" + b);\n        System.out.println(\"========================\");\n        int[] changeNumbers = intercambiarPorValor(a, b);\n        int c = changeNumbers[0];\n        int d = changeNumbers[1];\n        System.out.println(\"Después de intercambiarlos\");\n        System.out.println(\"--------------------------\");\n        System.out.println(\"a = \" + c);\n        System.out.println(\"b = \" + d);\n        System.out.println(\"==========================\");\n        System.out.println(\"Intercambios por referencia\");\n        Animal animal1 = new Animal(\"Perro\");\n        Animal animal2 = new Animal(\"Gato\");\n        System.out.println(\"======================\");\n        System.out.println(\"Antes de intercambiarlos\");\n        System.out.println(\"------------------------\");\n        System.out.println(\"Nombre animal1 = \" + animal1.name);\n        System.out.println(\"Nombre animal2 = \" + animal2.name);\n        System.out.println(\"========================\");\n        Animal[] animals = intercambiarPorReferencia(animal1, animal2);\n        System.out.println(\"Después de intercambiarlos\");\n        System.out.println(\"--------------------------\");\n        System.out.println(\"Nombre animal1 = \" + animal1.name);\n        System.out.println(\"Nombre animal2 = \" + animal2.name);\n        System.out.println(\"==========================\");\n    }\n\n    public static void modificarPorValor(int x){\n        x = 20; // x vale 20 solamente en la funcion, fuera de ella vale otra cosa\n    }\n\n    public static void modificarPorReferencia(Animal animal){\n        animal.name = \"Indi\";\n    }\n\n    public static int[] intercambiarPorValor(int a, int b){\n        int c = a;\n        a = b;\n        b = c;\n        int[] result = {a, b};\n        return result;\n    }\n\n    public static Animal[] intercambiarPorReferencia(Animal a, Animal b){\n        Animal animal = new Animal(a.name);\n        a.name = b.name;\n        b.name = animal.name;\n        Animal[] result = {a, b};\n        return result;\n    }\n\n    static class Animal{\n        String name;\n\n        public Animal(String name){\n            this.name = name;\n        }\n    }\n\n}\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/java/Gerthai08.java",
    "content": "import com.sun.security.jgss.GSSUtil;\n\nimport java.util.Arrays;\nimport java.util.LinkedList;\n\npublic class Gerthai08 {\n    public static void main(String[] args) {\n\n        int value = 10;\n        LinkedList<String> reference = new LinkedList<String>();\n\n        //Asignación de variables por \"VALOR\"\n        System.out.println(\"=====Asignación de variables por \\\"VALOR\\\"=====\\n\");\n        System.out.println(\"Antes de llamar al método \\\"updateValue\\\": \" + value);\n        updateValue(value);\n        System.out.println(\"Después de llamar al método \\\"updateValue\\\": \" + value);\n\n        //Asignación de variables por \"REFERENCIA\"\n        System.out.println(\"\\n=====Asignación de variables por \\\"REFERENCIA\\\"=====\\n\");\n        reference.add(\"Juan\");\n        reference.add(\"Pedro\");\n        reference.add(\"Esteban\");\n        reference.add(\"Carlos\");\n\n        System.out.println(\"Recorriendo arrayList:\");\n        displayNames(reference);\n\n        System.out.println(\"\\nRecorriendo la lista antes de llamar al método \\\"displayNamesWithModification\\\"\");\n        displayNamesWithModification(reference);\n        System.out.println(\" \");\n        //Los cambios se mantienen porque el método recibe una referencia al mismo objeto en memoria.\n        displayNames(reference);\n        }\n\n    //Método para \"asignación de variables\"\n    private static void updateValue(int value) {\n        System.out.println(\"Valor recibido en \\\"updateValue\\\": \" + value);\n        value = 20;\n        System.out.println(\"Valor después de la modificación en \\\"updateValue\\\": \" + value);\n    }\n\n    //Métodos para \"asignación por referencias\"\n    //Recorriendo la lista \"reference\"\n    private static void displayNames(LinkedList<String> reference) {\n        for(String name : reference){\n            System.out.println(name);\n        }\n    }\n\n    private static void displayNamesWithModification(LinkedList<String> reference) {\n        System.out.println(\"\\nVisualizando nombres dentro del método:\");\n        for(String name : reference){\n            System.out.println(name);\n        }\n\n        //Modificando un elemento de la arrayList\n        reference.set(0,\"German\");\n        System.out.println(\"\\nNombres después de la modificación:\");\n        for(String name : reference){\n            System.out.println(name);\n        }\n\n        //Ejercicio extra\n        System.out.println(\"\\n=====Asignación de variables por valor=====\");\n        int value1 = 10;\n        int value2 = 20;\n        System.out.println(investedValue(value1,value2));\n        System.out.println(\"valores llamados después del método valor1: \" + value1 + \" valor2: \" + value2);\n\n        System.out.println(\"\\n=====Asignación de variables por referencia=====\");\n        String[] array1 = {\"Juan\",\"Pedro\",\"Samuel\"};\n        String[] array2 = {\"German\",\"Sofia\",\"Estaban\"};\n        System.out.println(investedReference(array1,array2));\n        System.out.println(\"valores llamados despues del método: \" + Arrays.toString(array1) + \" array2: \" + Arrays.toString(array2));\n    }\n\n    private static String investedReference(String[] array1, String[] array2){\n        String previousReference = \"valores antes del método array1: \" + Arrays.toString(array1) + \" array2: \" + Arrays.toString(array2);\n        //invirtiendo arrays\n        for (int i = 0; i < array1.length; i++) {\n            String temp = array1[i];\n            array1[i] = array2[i];\n            array2[i] = temp;\n        }\n        String afterReference = \"\\nvalores modificados en el método array1: \" + Arrays.toString(array1) + \" array2: \" + Arrays.toString(array2);\n        return previousReference + afterReference;\n    }\n\n    private static String investedValue(int value1, int value2){\n        String previousValue = \"valores antes del método valor1: \" + value1 + \" valor2: \" + value2;\n        //Invirtiendo variables\n        value1 = 20;\n        value2 = 10;\n        String updateValue = \"\\nvalores modificados en el método valor1: \" + value1 + \" valor2: \" + value2;\n        return previousValue + updateValue ;\n    }\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/java/GlossyPath.java",
    "content": "/**\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como\n * variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime\n *   el valor de las variables originales y las nuevas, comprobando que se ha invertido\n *   su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n * \n * @version v1.0\n * \n * @since 01/07/2024\n * \n * @author GlossyPath\n */\n\npublic class GlossyPath {\n    \n    /*\n     * Descripción: mètodo para cambiar notas por referencia.\n     */\n    public static void nuevaNotaReferencia(double[] notas){\n\n        notas[0] = 8.5d;\n    }\n    /*\n     * Descripción: método para cambiar nota por valor.\n     */\n    public static void nuevaNota(double nota){\n\n        nota = 9d;\n        System.out.println(String.format(\"Nota dentro del método = %s\",nota));\n\n    }\n\n\n    public static void main(String[] args) {\n        \n        System.out.println(\"\\n----------Por valor------------\");\n        //los tipos primitivos se pasan por valor (copia del dato)\n        double nota = 7.5d;\n        System.out.println(String.format(\"Nota antes de pasar por valor = %s \",nota));\n\n        nuevaNota(nota);\n\n        System.out.println(String.format(\"Nota después de pasar por el método por valor = %s\", nota));\n\n        //los arreglos y objetos se pasan por referencia.\n\n        System.out.println(\"\\n----------Por referencia------------\");\n        double[] notaReferencia = {5.5};\n\n        for(double notaRef: notaReferencia){\n            System.out.println( \"Antes de pasar por referencia = \" + notaRef);\n        }\n\n        nuevaNotaReferencia(notaReferencia);\n\n        for(double notaRef: notaReferencia){\n            System.out.println(\"Despues de pasar al método por referencia = \" +notaRef);\n        }\n\n\n        System.out.println(\"\\n------DIFICULTAD EXTRA------\");\n\n        Programa p1 = new Programa(\"Sheila\", \"Laura\");  \n        Programa p2 = new Programa(\"Carlos\", \"Lorenzo\");\n\n        System.out.println(\"CAMBIO POR VALOR\");\n        p1.cambioPorValor(p1.getParametro1(), p1.getParametro2(), p2.getParametro1(), p2.getParametro2());\n        System.out.println(p1.toString(\"p1\"));\n        System.out.println(p2.toString(\"p2\"));\n\n        System.out.println(\"CAMBIO POR REFERENCIA\");\n        p1.cambioPorReferencia(p1, p2);\n        System.out.println(p1.toString(\"p1\"));\n        System.out.println(p2.toString(\"p2\"));\n\n        }\n    }\n\n    class Programa {\n\n        private String parametro1;\n        private String parametro2;\n\n        public Programa(String parametro1, String parametro2){\n\n            this.parametro1 = parametro1;\n            this.parametro2 = parametro2;\n        }\n\n        public String getParametro1() {\n            return parametro1;\n        }\n\n        public void setParametro1(String parametro1) {\n            this.parametro1 = parametro1;\n        }\n\n        public String getParametro2() {\n            return parametro2;\n        }\n\n        public void setParametro2(String parametro2) {\n            this.parametro2 = parametro2;\n        }\n\n        public void cambioPorValor(String s1, String s2, String s3, String s4){\n\n            String aux = s1;\n            s1 = s3;\n            s3 = aux;\n            aux = s2;\n            s2 = s4;\n            s4 = aux;\n\n            System.out.println(s1);\n        }\n\n        public void cambioPorReferencia(Programa p1,  Programa p2){\n\n            String aux = p1.getParametro1();\n            p1.setParametro1(p2.getParametro1());\n            p2.setParametro1(aux);\n            aux = p1.getParametro2();\n            p1.setParametro2(p2.getParametro2());\n            p2.setParametro2(aux);\n\n        }\n\n        public String toString(String programa){\n\n            return (\"Programa: \" + programa +\n            \"\\nparametro1: \" + parametro1 +\n            \"\\nparametro2: \" + parametro2\n            );\n        }\n    }\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/java/Guillermo-Munoz.java",
    "content": "/**\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * @version 1.0\n * @since 05/03/2026\n * @author Guillermo-Munoz\n */\npublic class GuillermoMunoz {\n\n    // Funcion que modifica el objeto pasado com parámetro\n    public static void valor(int a){\n        System.out.println(\"Funcion Valor (Suma 10 a la variable pasada)\");\n        System.out.println(\"Valor recibido: \" + a);\n        a = a + 10;\n        System.out.println(\"Suma 10 al valor a: \" + a);\n        System.out.println(\"Fin de la función Valor\");\n    }\n    // Funcion paso por referencia\n    public static void referencia(int[] b){ \n        System.out.println(\"Funcion Valor (Suma 10 a la variable pasada)\");\n        System.out.println(\"Valor recibido: \" + b[0]);\n        b[0] = b[0] + 10;\n        System.out.println(\"Suma 10 al valor a: \" + b[0]);\n        System.out.println(\"Fin de la función Valor\");\n    }\n\n    public static void main(String[] args) {\n        \n        //============================================\n        // Asignación variable por valor\n        //============================================\n\n        int a = 5;\n        valor(a);\n        System.out.println(\"Valor de la variable pasada no se modica: \" + a );\n\n        //============================================\n        // Asignación variable por referencia\n        //============================================\n\n            // En Java no existen los punteros explicitos como en (C, C++...) pero en su lugar utiliza referencias a objetos, \n            // los cuales actuan como \"punteros seguros\".\n            // Los objetos se guardan como una dirección de memoria, los cuales al pasar como parametro se envia esa dirección de memoria, \n            // de manera que al trabajar con esos datos se modifican los datos asocidos a esa direccion de memoria\n\n       int[] b = {10};\n       referencia(b);\n       System.out.println(\"Valor de la variable pasada por referencia: \" + b[0]);\n\n       //=============================================\n       // Ejercicio Extra\n       //=============================================\n\n            /* DIFICULTAD EXTRA (opcional):\n            *   Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n            *   Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n            *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n            *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n            *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n            *   Comprueba también que se ha conservado el valor original en las primeras.\n            */\n\n           //Por valor\n\n       int valorA = 10;\n       int valorB = 20;\n       intercambioPorValor(valorA, valorB);\n       System.out.printf(\"valores fuera de función: %n valorA: %d, valorB: %d %n\", valorA, valorB);\n\n           //Por referencia\n        int[] ReferenciaA = {10};   \n        int[] FerefenciaB = {20};\n        intercambioPorReferencia(ReferenciaA, FerefenciaB);\n        System.out.printf(\"valores fuera de función: %n referenciaA: %d, referenciaB: %d %n\", ReferenciaA[0], FerefenciaB[0]);\n\n    }\n       \n\n            //Función intercambio valor de dos variables pasado por valor\n        \n        public static void intercambioPorValor(int a, int b){\n            System.out.println(\"Funcion intercambio por valor\");\n            System.out.printf(\"valorA vale: %d, valorB vale: %d %n\", a, b);\n            int temp = a;\n            a = b;\n            b = temp;\n            System.out.println(\"Intercambio de valor\");\n            System.out.printf(\"valorA vale %d, valorB vale: %d %n\", a , b);\n        }\n\n            //Función intercambio valor de dos variables pasado por referencia\n        public static void intercambioPorReferencia(int[] a, int[] b){\n            System.out.println(\"Funcion intercambio por referencia\");\n            System.out.printf(\"referenciaA vale: %d, referenciaB vale: %d %n\", a[0], b[0]);\n            int temp = a[0];\n            a[0] = b[0];\n            b[0] = temp;\n            System.out.println(\"Intercambio de valor\");\n            System.out.printf(\"referenciaA vale %d, referenciaB vale: %d %n\", a[0] , b[0]);\n        }\n\n\n\n\n\n\n\n        \n    \n    \n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/java/GustavoGomez19.java",
    "content": "public class GustavoGomez19 {\n\n   /*\n    * Asignación de varialbles por valor: La asignación de una variable por valor\n    * es el proceso de copiar el valor\n    * de una variable original a una nueva ubicación en memoria, cualquier\n    * modificación en la variable copiada\n    * no afectará la variable original. En Java los tipos de datos primitivos se\n    * asignan por valor\n    */\n\n   /*\n    * Asignación de valor por referencia: En Java las variables de tipo objeto se\n    * asignan por referencia, lo que quiere\n    * decir que cuando se asigna un objeto a una variable, se asigna una referencia\n    * al objeto en lugar del objeto mismo.\n    * La referencia es esencialmente una dirección en memoria donde se encuentra\n    * almacenado el objeto.\n    * Cuando se pasa una variable de objeto por parámetro a un método, también se\n    * pasa la referencia al objeto, no el objeto\n    * en si mismo, cualquier modificación del objeto dentro del método se reflejará\n    * en el objeto original.\n    */\n\n   // Ejemplo de asignación por valor\n   static int original = 10;\n   static int copia = original;\n\n   // Ejemplo paso por referencia\n   static class Persona {\n      String nombre;\n\n      public Persona(String nombre) {\n         this.nombre = nombre;\n      }\n   }\n\n   public static void main(String[] args) {\n      // Impresión de los valores de las variables asignadas por valor\n      System.out.println(\"Valor de la variable original: \" + original);\n      System.out.println(\"Valor de la variable copia: \" + copia);\n\n      cmabioValorCopia(copia);\n\n      System.out.println(\"El valor dela variable original se mantiene sin modificaciones. \" + original);\n\n      // Creación de los objetos de la clase \"Persona\"\n      Persona persona1 = new Persona(\"Gustavo\"); // Se asigna el valor al objeto persona1\n      Persona persona2 = persona1; // Se asigna por referencia al objeto persona2 el objeto persona1\n\n      // Impresión por terminal de los objetos\n      System.out.println(\"Nombre persona 1: \" + persona1.nombre);\n      System.out.println(\"Nombre persona 2: \" + persona2.nombre);\n\n      // Modificación del nombre de persona2\n      persona2.nombre = \"Katerine\";\n      System.out.println(\"Nombre persona 1 modidifado : \" + persona1.nombre);\n      System.out.println(\"Nombre persona 2 modidifado : \" + persona2.nombre);\n\n      persona1.nombre = cambioDeValorPorReferencia(\"María José\");\n      System.out.println(\"Nombre persona 1 modidifado por método: \" + persona1.nombre);\n      System.out.println(\"Nombre persona 2 modidifado por método: \" + persona2.nombre);\n\n      // Por valor\n      int num1 = 10;\n      int num2 = 7;\n      System.out.println(\"Valores originales: \");\n      System.out.println(\"num1: \" + num1 + \", num2: \" + num2);\n      int[] cambio = cambioPorValor(num1, num2);\n      System.out.println(\"Variables intercambiadas: \");\n      System.out.println(\"num1: \" + cambio[0] + \" - num2: \" + cambio[1]);\n\n      // Por referencia\n      int[] c = {17};\n      int[] d = {19};\n      System.out.println(\"Variables originales\");\n      System.out.println(\"c[0] \" + c[0] + \" | \" + \"d[0] \" + d[0]);\n      int[] e = cambioPorReferencia(c, d);\n      System.out.println(\"Variables intercambiadas\");\n      System.out.println(\"c[0] \" + e[0] + \" | \" + \"d[0] \" + e[0]);\n\n   }\n\n   // Método para cambiar el valor de la variable copia\n   public static void cmabioValorCopia(int copia) {\n      copia = 20;\n      System.out.println(\"Nuevo valor de la variable copia: \" + copia);\n   }\n\n   // Método para cambiar el valor por referencia\n   public static String cambioDeValorPorReferencia(String nombre) {\n      return nombre;\n   }\n\n   /* Desafio dificultad extra: Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n    * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n        Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n        se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n        variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n        Comprueba también que se ha conservado el valor original en las primeras.\n    */\n\n    // Por valor\n    \n\n    public static int[] cambioPorValor(int num1, int num2){\n      int aux = num1;\n      num1 = num2;\n      num2 = aux;\n      return new int[] {num1, num2};\n    }\n\n    // Por referencia\n    public static int[] cambioPorReferencia(int[]a, int[]b){\n      int aux = a[0];\n      a[0] = b[0];\n      b[0] = aux;\n      return new int[] {a[0], b[0]};\n    }\n\n}"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/java/Jeigar2.java",
    "content": "public class Jeigar2 {\n    /*\n     * EJERCICIO:\n     * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n     *   su tipo de dato.\n     * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y\n     *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n     * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n     *\n     * DIFICULTAD EXTRA (opcional):\n     * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n     * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n     *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n     *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n     *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n     *   Comprueba también que se ha conservado el valor original en las primeras.\n     */\n\n    private String nombre;\n    private int edad;\n\n    public Jeigar2(String nombre, int edad) {\n        this.nombre = nombre;\n        this.edad = edad;\n    }\n\n    public static void cambiarEdadValor(int edad) {\n        edad = cambiarEdadValorRetorno(edad);\n    }\n\n    public static int cambiarEdadValorRetorno(int edad) {\n        edad = edad * 2 + 1;\n        return edad;\n    }\n\n    public static void cambiarNombreValor(String nombre) {\n        nombre = cambiarNombreValorRetorno(nombre);\n    }\n\n    public static String cambiarNombreValorRetorno(String nombre) {\n        nombre = \"_\" + nombre.toUpperCase() + \"_\";\n        return nombre;\n    }\n\n    public static void cambiarEdadReferencia(Jeigar2 jeigar2) {\n        cambiarEdadReferenciaRetorno(jeigar2);\n    }\n\n    public static int cambiarEdadReferenciaRetorno(Jeigar2 jeigar2) {\n        jeigar2.setEdad(cambiarEdadValorRetorno(jeigar2.getEdad()));\n        return jeigar2.getEdad();\n    }\n\n    public static void cambiarNombreReferencia(Jeigar2 jeigar2) {\n        cambiarNombreReferenciaRetorno(jeigar2);\n    }\n\n    public static String cambiarNombreReferenciaRetorno(Jeigar2 jeigar2) {\n        jeigar2.setNombre(cambiarNombreValorRetorno(jeigar2.getNombre()));\n        return jeigar2.getNombre();\n    }\n\n    public static void main(String[] args) {\n        Jeigar2 jeigar2 = new Jeigar2(\"Jesús\", 33);\n\n        System.out.println(String.format(\"# Antes: %s, %d\", jeigar2.getNombre(), jeigar2.getEdad()));\n\n        // Por valor no se modifica\n        System.out.println(\"POR VALOR No cambia\");\n        cambiarEdadValor(jeigar2.getEdad());\n        cambiarNombreValor(jeigar2.getNombre());\n        System.out.println(String.format(\"- Después Valor 1: %s, %d\", jeigar2.getNombre(), jeigar2.getEdad()));\n        int edadCambio = cambiarEdadValorRetorno(jeigar2.getEdad());\n        String nombreCambio = cambiarNombreValorRetorno(jeigar2.getNombre());\n        System.out.println(String.format(\"- Después Valor 2: %s, %d\", jeigar2.getNombre(), jeigar2.getEdad()));\n        System.out.println(String.format(\"+ Después Retorno 2.1: %s, %d\", nombreCambio, edadCambio));\n\n        // Por referencia si se modifica\n        System.out.println(\"POR REFERENCIA Sí cambia\");\n        cambiarEdadReferencia(jeigar2);\n        cambiarNombreReferencia(jeigar2);\n        System.out.println(String.format(\"+ Después Referencia 3 : %s, %d\", jeigar2.getNombre(), jeigar2.getEdad()));\n        cambiarEdadReferencia(jeigar2);\n        edadCambio = cambiarEdadReferenciaRetorno(jeigar2);\n        nombreCambio = cambiarNombreReferenciaRetorno(jeigar2);\n        System.out.println(String.format(\"+ Después Referencia 4: %s, %d\", jeigar2.getNombre(), jeigar2.getEdad()));\n        System.out.println(String.format(\"+ Después Retorno 4.1: %s, %d\", nombreCambio, edadCambio));\n\n        System.out.println(\"\\n ---- EXTRA ---- \\n\");\n\n        Programa programa1 = new Programa(\"p1 Olivo\", \"p1 Palma\");\n        Programa programa2 = new Programa(\"p2 Getsemani\", \"p2 Tabor\");\n        System.out.println(\"# Antes \" + programa1.toString(\"p1\"));\n        System.out.println(\"# Antes \" + programa2.toString(\"p2\"));\n\n        System.out.println(\"POR VALOR No cambia\");\n        programa1.cambioValor(programa1.getParam1(), programa1.getParam2(), programa2.getParam1(), programa2.getParam2());\n        System.out.println(\"- Después valor \" + programa1.toString(\"p1\"));\n        System.out.println(\"- Después valor \" + programa2.toString(\"p2\"));\n\n        System.out.println(\"POR REFERENCIA Sí cambia\");\n        programa1.cambioReferencia(programa1, programa2);\n        System.out.println(\"+ Después referencia \" + programa1.toString(\"p1\"));\n        System.out.println(\"+ Después referencia \" + programa2.toString(\"p2\"));\n    }\n\n    public String getNombre() {\n        return nombre;\n    }\n\n    public void setNombre(String nombre) {\n        this.nombre = nombre;\n    }\n\n    public int getEdad() {\n        return edad;\n    }\n\n    public void setEdad(int edad) {\n        this.edad = edad;\n    }\n}\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\nclass Programa {\n    private String param1;\n    private String param2;\n\n    public Programa(String param1, String param2) {\n        this.param1 = param1;\n        this.param2 = param2;\n    }\n\n    public String getParam2() {\n        return param2;\n    }\n\n    public void setParam2(String param2) {\n        this.param2 = param2;\n    }\n\n    public String getParam1() {\n        return param1;\n    }\n\n    public void setParam1(String param1) {\n        this.param1 = param1;\n    }\n\n    public void cambioValor(String p11, String p12, String p21, String p22) {\n        String aux = p11;\n        p11 = p21;\n        p21 = aux;\n        aux = p12;\n        p12 = p22;\n        p22 = aux;\n    }\n\n    public void cambioReferencia(Programa p1, Programa p2) {\n        String aux = p1.getParam1();\n        p1.setParam1(p2.getParam1());\n        p2.setParam1(aux);\n        aux = p1.getParam2();\n        p1.setParam2(p2.getParam2());\n        p2.setParam2(aux);\n    }\n\n    public String toString(String sufijo) {\n        return \"Programa (\" + sufijo + \"){\" +\n                \"param1='\" + param1 + '\\'' +\n                \", param2='\" + param2 + '\\'' +\n                '}';\n    }\n}\n\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/java/JesusAntonioEEscamilla.java",
    "content": "import java.util.Arrays;\n\n/** #05 - Java -> Jesus Antonio Escamilla */\n\npublic class JesusAntonioEEscamilla {\n    public static void main(String[] args) {\n    //---EJERCIÓ---\n        System.out.println(\"Asignación de Variable\");\n        System.out.println(\"Por Valor\");\n        variablePorValor();\n        System.out.println(\"Por Referencia\");\n        variablePorReferencia();\n        System.out.println(\"Variable a Función\");\n        System.out.println(\"Por Valor\");\n        funciónPorValor();\n        System.out.println(\"Por Referencia\");\n        funciónPorReferencia();\n\n    //---EXTRA---\n        System.out.println(\"Extra por Valor\");\n        extraValor();\n        System.out.println(\"Extra por Referencia\");\n        extraReferencia();\n    }\n\n    //---EJERCIÓ---\n    \n    //--Asignación de Variables--\n    // VALOR\n    public static void variablePorValor(){\n        int a = 5;\n        int b = a;\n\n        System.out.println(\"a: \" + a);\n        System.out.println(\"b: \" + b);\n\n        b = 10;\n        System.out.println(\"a: \" + a);\n        System.out.println(\"b: \" + b);\n    }\n\n    // REFERENCIA\n    public static void variablePorReferencia(){\n        int[] array1 = {1, 2, 3};\n        int[] array2 = array1;\n\n        System.out.println(java.util.Arrays.toString(array1));\n        System.out.println(java.util.Arrays.toString(array2));\n\n        array2[0] = 10;\n        System.out.println(java.util.Arrays.toString(array1));\n        System.out.println(java.util.Arrays.toString(array2));\n    }\n\n\n    //--Variables a Funciones--\n    // VALOR\n    public static void modificarValor(int x) {\n        x = 10;\n    }\n\n    public static void funciónPorValor(){\n        int a = 5;\n        modificarValor(a);\n        System.out.println(a);\n    }\n\n    // REFERENCIA\n    public static void modificarReferencial(int[] array){\n        array[0] = 10;\n    }\n\n    public static void funciónPorReferencia(){\n        int[] array1 = {1, 2, 3};\n        modificarReferencial(array1);\n        System.out.println(java.util.Arrays.toString(array1));\n    }\n\n    /**-----DIFICULTAD EXTRA-----*/\n\n    // Por VALOR\n    // Función para intercambiar valores de tipo primitivo\n    public static int[] intercambioValores(int a, int b){\n        int temp = a;\n        a = b;\n        b = temp;\n        return new int[]{a, b};\n    }\n\n    public static void extraValor(){\n        // Variables originales\n        int x = 5;\n        int y = 10;\n\n        // Llamada la nuevas variables en funciones\n        int[] resultados = intercambioValores(x, y);\n        int nuevoX = resultados[0];\n        int nuevoY = resultados[1];\n\n        // Los mostramos el resultado en la consola\n        System.out.println(\"Originales: x = \" + x + \", y = \" + y);\n        System.out.println(\"Nuevas: nuevoX = \" + nuevoX + \", nuevoY = \" + nuevoY);\n    }\n\n\n    // Por REFERENCIA\n    // Clase contenedor para las lista de referencia\n    public static class ListaContenedor {\n        int[] lista1;\n        int[] lista2;\n\n        public ListaContenedor(int[] lista1, int[] lista2){\n            this.lista1 = lista1;\n            this.lista2 = lista2;\n        }\n    }\n\n    // Función para intercambiar las referencia de las lista\n    public static ListaContenedor intercambiarLista(ListaContenedor contenedor){\n        int[] temp = contenedor.lista1;\n        contenedor.lista1 = contenedor.lista2;\n        contenedor.lista2 = temp;\n        return contenedor;\n    }\n\n    public static void extraReferencia(){\n        // Variables Originales\n        int[] listaA = {1, 2, 3};\n        int[] listaB = {4, 5, 6};\n\n        // Crear copias de las listas\n        int[] listAOriginal = Arrays.copyOf(listaA, listaA.length);\n        int[] listBOriginal = Arrays.copyOf(listaB, listaB.length);\n\n        // Crear contenedores y llamar a la función\n        ListaContenedor contenedor = new ListaContenedor(listaA, listaB);\n        ListaContenedor nuevasLista = intercambiarLista(contenedor);\n\n        // Los mostramos el resultado en la consola\n        System.out.println(\"Originales: listaA: \" + Arrays.toString(listAOriginal) + \", listaB: \" + Arrays.toString(listBOriginal));\n        System.out.println(\"Nuevas: listaA: \" + Arrays.toString(nuevasLista.lista1) + \", listaB: \" + Arrays.toString(contenedor.lista2));\n    }\n\n    /**-----DIFICULTAD EXTRA-----*/\n}"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/java/JesusEs1312.java",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\npublic class JesusEs1312 {\n    public static void main(String[] args) {\n        // Asignación de variables por valor\n        int a = 5;\n        int b = a;\n        b = 10;\n        System.out.println(\"a: \" + a + \", b: \" + b); // a: 5, b: 10\n\n        // Asignación de variables por referencia\n        int[] c = {5};\n        int[] d = c;\n        d[0] = 10;\n        System.out.println(\"c[0]: \" + c[0] + \", d[0]: \" + d[0]); // c[0]: 10, d[0]: 10\n\n        // Funciones con variables por valor\n        int f = 20;\n        porValor(f);\n        System.out.println(\"f fuera de la función: \" + f); // f: 20\n\n        // Funciones con variables por referencia\n        int[] g = {10};\n        porReferencia(g);\n        System.out.println(\"g[0] fuera de la función: \" + g[0]); // g[0]: 10\n\n        // Ejercicio Extra\n        int i = 5;\n        int j = 10;\n        System.out.println(\"Variables originales - i: \" + i + \", j: \" + j); // i: 5, j: 10\n        int[] h = intercambioPorValor(i, j);\n        System.out.println(\"Variables retornadas - i: \" + h[0] + \", j: \" + h[1]); // h[0]: 10, h[1]: 5\n\n        int[] k = {5};\n        int[] l = {10};\n        System.out.println(\"Variables originales - k[0]: \" + k[0] + \", l[0]: \" + l[0]); // k[0]: 5, l[0]: 10\n        int[] m = intercambioPorReferencia(k, l);\n        System.out.println(\"Variables retornadas - k[0]: \" + m[0] + \", l[0]: \" + m[1]); // m[0]: 10, m[1]: 5\n    }\n    \n    // Funciones con variables por valor\n    public static void porValor(int f) {\n        f = 10;\n        System.out.println(\"f dentro de la función: \" + f); // f: 10\n    }\n\n    // Funciones con variables por referencia\n    public static void porReferencia(int[] g) {\n        int h[] = g;\n        h[0] = 10;\n        h[1] = 20;\n        System.out.println(\"g[0] dentro la función: \" + g[0]); // g[0]: 10\n    }\n\n    // Funciones de Ejercicio Extra\n    public static int[] intercambioPorValor(int a, int b) {\n        int temp = a;\n        a = b;\n        b = temp;\n        return new int[] {a, b};\n    }\n\n    public static int[] intercambioPorReferencia(int[] a, int[] b) {\n        int temp = a[0];\n        a[0] = b[0];\n        b[0] = temp;\n        return new int[] {a[0], b[0]};\n    }\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/java/JimsimroDev.java",
    "content": "\n/* VALOR Y REFERENCIA\n\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como\n * variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime\n *   el valor de las variables originales y las nuevas, comprobando que se ha invertido\n *   su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class JimsimroDev {\n  static final String DIV_LINE = \":::::::::::::\";\n\n  // Funcion o metodo para imprimir tipos de datos por valor\n  public static void print(String str, int result) {\n    System.out.println(str + \" \" + result);\n  }\n\n  // Funcion o metodo con datos por valor\n  public static void intFuncion(int number) {\n    number = 30;\n    print(\"number = \", number);\n  }\n\n  // Funcion con datos por referencia\n  public static void funcionDeLista(List<Integer> miLista) {\n    miLista.add(30);\n\n    List<Integer> miLista1 = new ArrayList<>();\n    miLista1 = miLista;\n    miLista1.add(40);// Esta opción es la mas comun para inciar la lista con valores o asignar\n                     // valores\n    System.out.println(miLista);\n  }\n\n  // Funcion o metodo para intercambiar datos por valor\n  public static int[] cambiarValor(int d, int e) {\n    int temp = d;\n    d = e;\n    e = temp;\n    return new int[] { d, e };\n  }\n\n  // Funcion para intercambiar datos por referencia\n  public static List<Integer>[] referencia(List<Integer> cambiarRefD, List<Integer> cambiarRefE) {\n    List<Integer> temp = cambiarRefD;\n    cambiarRefD = cambiarRefE;\n    cambiarRefE = temp;\n    return new List[] { cambiarRefD, cambiarRefE };\n  }\n\n  public static void main(String[] args) {\n    // Los daos primitivos en java se manejava por valor\n    // quier decir que cuanod le asignas una variable a otra se copia\n    // el valor de esta.\n\n    // Tipos de datos por valor\n    System.out.println(DIV_LINE);\n    int a = 3;\n    print(\"a=\", a);\n    System.out.println(DIV_LINE);\n    int b = a; // resultado -> 3\n    print(\"b=\", b);// Imprime 3\n    System.out.println(DIV_LINE);\n    b = 10; // resultado -> 10\n    print(\"b=\", b);// Imprime 10\n\n    // Funciones con tipos de datos por valor\n    System.out.println(DIV_LINE);\n    int c = 15;\n    intFuncion(c);\n    System.out.println(DIV_LINE);\n    print(\"c = \", c);\n\n    // Tipos de datos por referencia\n    System.out.println(DIV_LINE);\n    List<Integer> miLista = new ArrayList<>() {\n      {\n        add(10);\n        add(20);// esta es otra manera de inciar valors mutables a la lista\n      }\n    };\n    funcionDeLista(miLista);\n    System.out.println(DIV_LINE);\n    miLista.set(2, 60);// reemplaza el valor que esta en posición 2\n    System.out.println(miLista);\n\n    // EXTRA\n    // Por valor\n    System.out.println(DIV_LINE);\n    int d = 80;\n    int e = 90;\n    System.out.printf(\"d = %d e = %d\\n\", d, e);\n    System.out.println(\"d = \" + cambiarValor(d, e)[0] + \" e = \" + cambiarValor(d, e)[1]);\n\n    // Por referencia\n    System.out.println(DIV_LINE);\n    List<Integer> listaD = new ArrayList<>() {\n      {\n        add(20);\n        add(30);\n      }\n    };\n    List<Integer> listaE = new ArrayList<>();\n    listaE.add(40);\n    listaE.add(50);\n    System.out.println(\"listaD = \" + listaD);\n    System.out.println(\"listaE = \" + listaE);\n    System.out.println(\"listaE = \" + referencia(listaD, listaE)[0] + \" listaD = \" + referencia(listaD, listaE)[1]);\n  }\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/java/Josegs95.java",
    "content": "import java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\n\npublic class Josegs95 {\n    public static void main(String[] args) {\n        //Asignación por valor. Propio de las variables de tipo primitivo\n        int a = 18;\n        int b = 5;\n        System.out.println(\"a: \" + a); //Out: 'a: 18'\n        System.out.println(\"b: \" + b); //Out: 'b: 5'\n        b = a;\n        a += 3;\n        System.out.println(\"a: \" + a); //Out: 'a: 21'\n        System.out.println(\"b: \" + b); //Out: 'b: 18'\n\n        //Asignación por referencia. Propio de los objetos\n        List<String> listA = new ArrayList<>();\n        listA.add(\"Paloma\");\n        listA.add(\"Loro\");\n        listA.add(\"Águila\");\n        List<String> listB = listA;\n        System.out.println(\"listA: \" + listA); //Out: [Paloma, Loro, Águila]\n        System.out.println(\"listB: \" + listB); //Out: [Paloma, Loro, Águila]\n        listA.add(\"Gorrión\");\n        listB.add(\"Cuervo\");\n        System.out.println(\"listA: \" + listA); //Out: [Paloma, Loro, Águila, Gorrión, Cuervo]\n        System.out.println(\"listB: \" + listB); //Out: [Paloma, Loro, Águila, Gorrión, Cuervo]\n\n        //Métodos de ejemplo\n        int c = 15;\n        System.out.println(\"c before: \" + c); //Out: 'c: 15'\n        modifyInteger(c); //Out: 'n: 25'\n        System.out.println(\"c after: \" + c); //Out: 'c: 15'\n\n        int[] array = new int[5];\n        array[0] = 2;\n        array[1] = 6;\n        array[2] = 3;\n        array[3] = 8;\n        System.out.println(\"array before: \" + Arrays.toString(array)); // Out: [2, 6, 3, 8, 0]\n        modifyArray(array); // Out: [0, 6, 3, 8, 0]\n        System.out.println(\"array after: \" + Arrays.toString(array)); // Out: [0, 6, 3, 8, 0]\n\n        //Reto\n        System.out.println(\"\\n\");\n        retoFinal();\n    }\n\n    public static void modifyInteger(int n){\n        n += 10;\n        System.out.println(\"n: \" + n);\n    }\n\n    public static void modifyArray(int[] array){\n        array[0] = 0;\n        System.out.println(\"array modified: \" + Arrays.toString(array));\n    }\n\n    public static void retoFinal(){\n        int n1 = 8;\n        int n2 = 12;\n        int[] result = exchangeValues(n1, n2);\n        int n3 = result[0];\n        int n4 = result[1];\n        System.out.println(\"n1: \" + n1 + \" - n2: \" + n2);\n        System.out.println(\"n3: \" + n3 + \" - n4: \" + n4);\n\n        List<Integer> l1 = new ArrayList<>(); //Out: 'n1: 8 - n2: 12'\n        List<Integer> l2 = new ArrayList<>(); //Out: 'n3: 12 - n4: 8'\n        l1.add(8);\n        l1.add(6);\n        l1.add(2);\n        l2.add(3);\n        l2.add(5);\n        Object[] resultArray = exchangeValuesRef(l1, l2);\n        List<Integer> l3 = (ArrayList) resultArray[0];\n        List<Integer> l4 = (ArrayList) resultArray[1];\n        System.out.println(\"l1: \" + l1 + \" - l2: \" + l2); //Out: 'l1: [8, 6, 2] - l2: [3, 5]'\n        System.out.println(\"l3: \" + l3 + \" - l4: \" + l4); //Out: 'l3: [3, 5] - l4: [8, 6, 2]'\n    }\n\n    private static int[] exchangeValues(int a, int b){\n        int c = b;\n        b = a;\n        a = c;\n        int[] array = {a, b};\n        return array;\n    }\n\n    private static Object[] exchangeValuesRef(List list1, List list2){\n        List list3 = list1;\n        list1 = list2;\n        list2 = list3;\n        Object[] array = {list1, list2};\n\n        return array;\n    }\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/java/RodrigoGit87.java",
    "content": "\nimport java.util.*;\n\npublic class RodrigoGit87 {\n    public static void main(String[] args) {\n        /*\n         *\n         * DIFICULTAD EXTRA (opcional):\n         * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n         * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n         *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n         *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n         *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n         *   Comprueba también que se ha conservado el valor original en las primeras.\n         */\n\n        //tipos de variables POR VALOR (son los primitivos y la 'copia' no afecta ala variable original ya q son independientes (cada una se almacena en una ubicacion diferente en\n        // memoria 'Stack')\n        float producto = 100;\n        float descuento = (15 * 100 / 100); // <- 15 %\n        float productoCon15Descuento = producto - descuento; // <- 85\n        IO.println(\"\\nproducto con descuento: \" + productoCon15Descuento);\n        IO.println(\" pero producto sigue teniendo el valor original asignado : \" + producto);\n\n        // variables POR REFERENCIA ( Clases, Objetos, Strings, ARRays.. ) Lo q se 'copia' es la 'referencia en memoria', por tanto, ambas variables 'apuntan' al mismo sitio en memoria 'Heap'. Y cambiar algo\n        //en el 'mismo sitio', altera el valor de lo que hay en el sitio, y como ambas variables apuntan al 'mismo sitio' ambas se modifican.\n\n        int[] myArray = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};\n        IO.println(Arrays.toString(myArray));\n\n        int[] anotherArray = myArray; // <- anotherArray 'apunta' al mismo sitio en memoria que myArray.\n        IO.println(Arrays.toString(anotherArray));\n\n        anotherArray[9] = 69; // <- Cambiar una posicion en este array, tambien modificará la misma posicion en el array original, ya que ambos apuntan al mismo 'Heap'\n        IO.println(\"\\nmyArray: \");\n        IO.print(Arrays.toString(myArray));\n\n        IO.println(\"\\nanotherArray: \");\n        IO.print(Arrays.toString(anotherArray));\n\n        IO.println(\"\");\n\n        //llamada metodo de funcion por valor\n        int numA = 10;\n        modificarInt(numA); // el metodo siempre imprimirá 30 por que -> ver metodo modificarInt\n        IO.println(\" comprobamos q numA sigue valiendo 10, numA = \"+numA+\" después de usarlo como parametro del metodo\");\n\n        //llamada metodo de funcion por referencia\n        var lista1 = new ArrayList<Integer>();\n        for (int i=1; i<= 10; i++) lista1.add(i); // añado numeros a la lista con ciclo for\n\n        funcionReferencia(lista1); // lista1 y listaParametro 'apuntan' al mismo sitio en memoria (Heap)\n        IO.println(\"comprobamos q lista1 ( el original )  ha cambiado tras usar el metodo: \" + lista1); // si fuese por valor, (imposible si no es primitivo), hubiese impreso el valor original (del 1 al 10)\n\n        // -----\n        // EXTRA\n        // -----\n        int d = 10;\n        int e = 20;\n\n        int[] retornoFuncion = changeValue(d,e);\n\n        IO.println(d);\n        IO.println(e);\n        IO.println(\" valores  invertidos : \" + Arrays.toString(retornoFuncion));\n\n    }\n\n        //Funcion con datos por Valor\n        public static void modificarInt (int num){  //el valor q usemos en la llamada, se asignará a la nueva variable creada 'num'\n        IO.println(num); // <-- Imprimirá 10, q es el valor de numA  ( num es una copia de numA )\n        num= 30;  // <- Ahora la copia tiene asignado el valor 30\n        IO.println(num);  // <-  Imprime 30\n        }\n\n\n        //Funcion por Referencia\n        public static void funcionReferencia (ArrayList<Integer> listaParametro){\n            listaParametro.add(55);\n            IO.println(\"lista parametro: \" + listaParametro );\n        }\n        // -----\n        // EXTRA\n        // -----\n        public static int[] changeValue(int valueA, int valueB) { // a= 10 b = 20\n            int temp = valueA; // temp 10\n            valueA = valueB; // a = 20\n            valueB = temp; // b = 10\n            return new int[] {valueA,valueB};\n        }\n\n\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/java/RoniPG.java",
    "content": "// @Roni\n\npublic class VALOR_Y_REFERENCIA_05 {\n\n\tpublic static void main(String[] args) {\n\t\t\n\t\t// Asignación de variables por valor\n\t\t/*\n\t\t * Las variables por valor son las que no comparten la misma posicion en memoria.\n\t\t * Los datos primitivos en la asginacion de datos o al pasarle otro dato primitivo crea una copia, del valor\n\t\t * en otra posicion de memoria(no comparte el puntero a su posicion en memoria)\n\t\t * Una excepion dentro de los datos primitivos es el String, que es un dato de tipo objeto pero actua como un\n\t\t * dato primitivo al asignarle otro valor/dato.\n\t\t */\n\t\tint a=5; \t\t\tint b=10;\n\t\tString a1=\"Hola\";\tString b1=\"Adios\";\n\t\tSystem.out.println(\"Numero a: \"+a+\".\\t\\tNumero b: \"+b+\"\\nCadena a1: \"+a1+\".\\tCadena b1: \"+b1);\n\t\ta=b;\t\t\t\tb=5;\t\t// --> Intercambiamos los valores numericos\n\t\ta1=b1;\t\t\t\tb1=\"Hola\";  // --> Intercambiamos los valores en la cadena\n\t\tSystem.out.println(\"Numero a: \"+a+\".\\t\\tNumero b: \"+b+\"\\nCadena a1: \"+a1+\".\\tCadena b1: \"+b1);\n\t\t\n\t\t// Asignación de variables por referencia\n\t\t/*\n\t\t * Java no permite la modificación de la referencia en sí misma.\n\t\t * No puedes hacer que una referencia apunte a otro objeto dentro de un método y esperar que esa modificación se refleje fuera del método\n\t\t */\n\t\t\n\t\tint numsA [] = {5,10};\tint numsB [] = {15,20};\n\t\tnumsA=numsB;\t\t\t\tnumsB[0]=5;numsB[1]=10;\n\t\t// Comprobamos que al asignarle numsB a numsA pasan a compartir el mismo espacio de memoria.\n\t\t// Todo lo que se modifique en una variable modificara automaticamente la otra. \n\t\tfor(int numero : numsA) {System.out.print(numero+\"\\t\");\t}\n\t\tfor(int numero : numsB) {System.out.print(numero+\"\\t\");\t}\n\t\t\n\t\ta=5; b=10;\n\t\tporValor(a, b);\n\t\tSystem.out.println(\"Valor de la variable a: \"+a+\"\\nValor de la variable b: \"+b);\n\t\tint [] arrayA= {5,10};\n\t\tint [] arrayB= {15,20};\n\t\tporReferencia(arrayA, arrayB);\n\t\tSystem.out.println(\"Valor del arrayA: \"+arrayA[0]+\", \"+arrayA[1]+\"\\nValor del arrayB: \"+arrayB[0]+\", \"+arrayB[1]);\n\t\t\n\t\t/* DIFICULTAD EXTRA (opcional):\n\t\t * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n\t\t * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n\t\t *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n\t\t *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n\t\t *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n\t\t *   Comprueba también que se ha conservado el valor original en las primeras.\n\t\t */\n\t\tSystem.out.println();\n\t\tint numA=5;\tint numB=10;\n\t\tSystem.out.println(\"\\nValor de numA: \"+numA+\".\\tValor de numB: \"+numB);\n\t\tint result[]=intercambioPorValor(numA, numB);\n\t\tint numC=result[0];\tint numD=result[1];\n\t\tSystem.out.println(\"Valor de numA: \"+numA+\".\\tValor de numB: \"+numB);\n\t\tSystem.out.println(\"Valor de numC: \"+numC+\".\\tValor de numD: \"+numD+\"\\n\");\n\t\t\n\t\tint [] numArray1= {5,10};\tint [] numArray2= {15,20};\n\t\tSystem.out.println(\"\\nValor del array numArray1: \"+numArray1[0]+\",\"+numArray1[1]+\".\\tValor de numArray2: \"+numArray2[0]+\",\"+numArray2[1]);\n\t\tint res[][]=intercambioPorReferencia(numArray1, numArray2);\n\t\tint [] numArray3=new int[res[0].length]; int [] numArray4=new int[res[1].length];\n\t\tfor(int i=0; i<numArray3.length;i++) {numArray3[i]=res[0][i];}\n\t\tfor(int i=0; i<numArray4.length;i++) {numArray4[i]=res[1][i];}\n\t\tSystem.out.println(\"Valor del array numArray1: \"+numArray1[0]+\",\"+numArray1[1]+\".\\tValor de numArray2: \"+numArray2[0]+\",\"+numArray2[1]);\n\t\tSystem.out.println(\"Valor del array numArray3: \"+numArray3[0]+\",\"+numArray3[1]+\".\\tValor de numArray4: \"+numArray4[0]+\",\"+numArray4[1]+\"\\n\");\n\t}\n\tpublic static int[] intercambioPorValor(int a, int b) {\n\t\tSystem.out.println(\"Entramos en la funcion intercambioPorValor\");\n\t\tint aux = a ;\n\t\ta = b;\n\t\tb = aux;\n\t\tint result[]={a,b}; //--> Lo devolvemos como un array para luego asignar los valores deseados\n\t\tSystem.out.println(\"Salimos de la funcion porValor\");\n\t\treturn result;\n\t}\n\tpublic static int [][] intercambioPorReferencia(int [] a, int [] b) {\n\t\tSystem.out.println(\"Entramos en la funcion intercambioPorReferencia\");\n\t\tint [] auxA=new int[a.length];\n\t\tint [] auxB=new int[b.length];\n\t\tfor(int i=0; i<auxA.length;i++) {auxA[i]=a[i];}\n\t\tfor(int i=0; i<auxB.length;i++) {auxB[i]=b[i];}\n\t\t\n\t\tSystem.out.println(\"Salimos de la funcion porValor\");\n\t\treturn new int [][] {auxB,auxA};\n\t}\n\t\t//Funciones con variables por valor\n\t\n\tpublic static void porValor(int a, int b) {\n\t\tSystem.out.println(\"\\nEntramos en la funcion porValor\");\n\t\ta=45; b=95;\n\t\tSystem.out.println(\"Valor de la variable a: \"+a+\"\\nValor de la variable b: \"+b);\n\t\tSystem.out.println(\"Salimos de la funcion porValor\\n\");\n\t}\n\t//Funciones con variables por valor\n\tpublic static void porReferencia(int [] arrayA, int [] arrayB) {\n\t\tSystem.out.println(\"\\nEntramos en la funcion porReferencia\");\n\t\tarrayA[0]=25; arrayA[1]=30;\n\t\tarrayB[0]=35; arrayB[1]=40;\n\t\tSystem.out.println(\"Valor del arrayA: \"+arrayA[0]+\", \"+arrayA[1]+\"\\nValor del arrayB: \"+arrayB[0]+\", \"+arrayB[1]);\n\t\tSystem.out.println(\"Salimos de la funcion porReferencia\\n\");\n\t}\n\t\t\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/java/SDM29GH.java",
    "content": "import java.util.ArrayList;\n\npublic class SDM29GH {\n    public static void main(String[] args) {\n        \n        System.out.println(\"***** Valor y Referencia *****\");\n\n        // Asignación de variables por valor\n        System.out.println(\"Asignación de variables por Valor\");\n        int a = 5;\n        int b = a;\n        a = 10;\n        System.out.println(b);\n        \n        // Asignación de variables por referencia\n        System.out.println(\"Asignación de variables por Referencia\");\n        ArrayList<Integer> lista1 = new ArrayList<>();\n        lista1.add(100);\n        ArrayList<Integer> lista2 = lista1;\n        lista1.add(200);\n        System.out.println(lista2);\n    }\n}"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/java/TofeDev.java",
    "content": "public class TofeDev {\n    public static void main(String[] args) {\n\n        int valor = 20;\n        String str = \"String inmutable\";\n        Objeto obj1 = new Objeto();\n        obj1.setNombre(\"Primero\");\n\n\n        //Asignación por valor\n        int valorCopia = valor;\n        valor = 25;\n\n        //Asignaciones por referencia\n        modificarObjeto(obj1);\n\n        //Los Strings son inmutables\n        moficicarString(str);\n\n        System.out.println(\"Int modificado: \" + valor); // 25\n        System.out.println(\"Int sin modificar: \" + valorCopia); // 20\n        System.out.println(\"Objeto modificado por referencia: \" + obj1.getNombre()); // \"Segundo\"\n        System.out.println(\"String 'Modificado': \" + str); // \"String inmutable\"\n        \n        /* DIFICULTAD EXTRA (opcional):\n        * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n        * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n        *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n        *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n        *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n        *   Comprueba también que se ha conservado el valor original en las primeras.\n        */\n\n        //Modificación por valor\n        int a = 5;\n        int b = 10;\n        System.out.println(\"a = \" + a + \" ; b = \" + b);\n\n        int[] modificacionValor = modificarPorValor(a, b);\n        System.out.println(\"a = \" + a + \" ; b = \" + b);\n        System.out.println(\"a = \" + modificacionValor[0] + \" ; b = \" + modificacionValor[1]);\n\n        //Modificación por referencia\n        Objeto objetoA = new Objeto();\n        objetoA.setNombre(\"Caja Amarilla\");\n        objetoA.setNumero(12);\n\n        Objeto objetoB = new Objeto();\n        objetoB.setNombre(\"Caja Roja\");\n        objetoB.setNumero(26);\n\n        System.out.println(\"Objeto A: \" + objetoA.getNombre() + \", \" + objetoA.getNumero() + \" Objeto B: \" + objetoB.getNombre() + \", \" + objetoB.getNumero());\n\n\n        modificarPorReferencia(objetoA, objetoB);\n\n        System.out.println(\"Objeto A: \" + objetoA.getNombre() + \", \" + objetoA.getNumero() + \" Objeto B: \" + objetoB.getNombre() + \", \" + objetoB.getNumero());\n    }\n\n    public static void moficicarString(String frase) {\n        frase = \"String modificada\";\n    }\n\n    public static void modificarObjeto(Objeto mod) {\n        mod.setNombre(\"Segundo\");\n    }\n\n    public static int[] modificarPorValor(int uno, int dos) {\n        int temp = uno;\n        uno = dos;\n        dos = temp;\n        return new int[]{uno, dos};\n    }\n\n    public static void modificarPorReferencia(Objeto ref1, Objeto ref2) {\n        Objeto hold = new Objeto();\n        hold.setNombre(\"\");\n        hold.setNumero(0);\n\n        hold.setNombre(ref1.getNombre());\n        hold.setNumero(ref1.getNumero());\n\n        ref1.setNombre(ref2.getNombre());\n        ref1.setNumero(ref2.getNumero());\n\n        ref2.setNombre(hold.getNombre());\n        ref2.setNumero(hold.getNumero());\n    }\n}\n\nclass Objeto {\n    private String nombre;\n    private int numero;\n\n    public String getNombre() {\n        return nombre;\n    }\n\n    public void setNombre(String nombre) {\n        this.nombre = nombre;\n    }\n\n    public int getNumero() {\n        return numero;\n    }\n\n    public void setNumero(int numero) {\n        this.numero = numero;\n    }\n}"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/java/Vecinacoo.java",
    "content": "public class P05 {\n\n\tpublic static void main(String[] args) {\n\n\t\t// EXPLICACION VALOR Y REFERENCIA\n\t\texplicacion();\n\n\t\t// OPCIONAL\n\n\t\tint numeroPequegno = 1;\n\t\tint numeromayor = 10;\n\n\t\tSystem.out.println(\"numero Pequegno:\" + numeroPequegno + \" Numero mayor: \" + numeromayor);\n\n\t\tint[] cambio = cambioPorValor(numeroPequegno, numeromayor);\n\n\t\tSystem.out.println(\"numero Pequegno:\" + cambio[0] + \" Numero mayor: \" + cambio[1]);\n\n\t}\n\n\tpublic static int[] cambioPorValor(int num1, int num2) {\n\t\tint aux = num1;\n\t\tnum1 = num2;\n\t\tnum2 = aux;\n\t\treturn new int[] { num1, num2 };\n\t}\n\n\tprivate static void explicacion() {\n\t\t// Asignacion de variable por valor\n\n\t\tint numero = 5;\n\t\t// Vamos ha cambiar valor de la variable mediante una funcion.\n\t\tcambiarValorInt(numero);\n\t\t// Esto deberia imprimir 10, pero NO, Imprime 5 ja que se le pasa una copia de\n\t\t// la variable\n\t\t// y no se agrega el 10 a la variable original si no a la copia.\n\t\tSystem.out.println(numero);\n\n\t\t// Asignacion de variable por referencia\n\t\tint[] miArray = new int[3];\n\n\t\tmiArray[0] = 10;\n\t\tmiArray[1] = 20;\n\t\tmiArray[2] = 30;\n\n\t\t// Modificamos el array.\n\t\tmodificarArray(miArray);\n\n\t\t// Imprimimos el contenido de nuestro Array\n\t\t// Habra cambiado? SI, ya que el array funciona por referencia, cuando llamamos\n\t\t// a la funcion\n\t\t// modificaArray le pasamos el array original no una copia.\n\n\t\tfor (int n : miArray) {\n\t\t\tSystem.out.println(n);\n\t\t}\n\n\t\t// Como funciona en objetos?\n\t\t// Vamos a probarlo.\n\n\t\tPersona p1 = new Persona(\"Angel\", 18);\n\n\t\tSystem.out.println(p1.getNombre() + \" \" + p1.getEdad());\n\n\t\tp1.setNombre(\"PEPE\");\n\t\tp1.setEdad(20);\n\n\t\t// Que imprimira?\n\t\tSystem.out.println(p1.getNombre() + \" \" + p1.getEdad());\n\t\t// Imprime a PEPE y a 20, ya que se pasa como referencia\n\t}\n\n\tprivate static void modificarArray(int[] miArray) {\n\n\t\tmiArray[0] = 5;\n\t\tmiArray[1] = 5;\n\t\tmiArray[2] = 5;\n\n\t}\n\n\tprivate static void cambiarValorInt(int numero) {\n\t\tnumero = 10;\n\n\t}\n\n\tpublic static class Persona {\n\n\t\tprotected String nombre;\n\t\tprotected int edad;\n\n\t\tpublic Persona(String nombe, int edad) {\n\t\t\tthis.nombre = nombe;\n\t\t\tthis.edad = edad;\n\t\t}\n\n\t\tpublic String getNombre() {\n\t\t\treturn nombre;\n\t\t}\n\n\t\tpublic void setNombre(String nombre) {\n\t\t\tthis.nombre = nombre;\n\t\t}\n\n\t\tpublic int getEdad() {\n\t\t\treturn edad;\n\t\t}\n\n\t\tpublic void setEdad(int edad) {\n\t\t\tthis.edad = edad;\n\t\t}\n\n\t}\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/java/Worlion.java",
    "content": "/*\n * EJERCICIO: Valor y Referencia\n */\n\npublic class Worlion {\n\n    public static void main(String[] args) {\n        new Worlion().run();\n    }\n\n    public void run() {\n        valueOrReference();\n        extra();\n    }\n\n\n    private void valueOrReference() {\n    \n        System.out.println(\"\\nValor y referencia:\");\n        // En java los tipos primitivos se pasan por valor: Son dos objetos diferentes\n        int a = 1;\n        int b = a;\n        System.out.println(\"\\na: \" + a + \" - b: \" + b);\n        System.out.println(\"Direccion de memoria de a: \" + System.identityHashCode(a));\n        System.out.println(\"Direccion de memoria de b: \" + System.identityHashCode(b));\n\n        a=20;\n        System.err.println(\"Modificamos a\");\n        System.out.println(\"a: \" + a + \" - b: \" + b);\n        System.out.println(\"Direccion de memoria de a: \" + System.identityHashCode(a));\n        System.out.println(\"Direccion de memoria de b: \" + System.identityHashCode(b));\n\n        // En java los objetos se pasan por referencia: Son dos punteros apuntando al mismo objeto!\n        Chorizo c = new Chorizo(\"Sarta\", 2);\n        Chorizo d = c;\n        System.out.println(\"\\nc: \" + c + \" - d: \" + d);\n        System.out.println(\"Direccion de memoria de c: \" + System.identityHashCode(c));\n        System.out.println(\"Direccion de memoria de d: \" + System.identityHashCode(d));\n\n        c.setPicantez(4);\n        System.err.println(\"Modificamos c\");\n        System.out.println(\"c: \" + c + \" - d: \" + d);\n        System.out.println(\"Direccion de memoria de c: \" + System.identityHashCode(c));\n        System.out.println(\"Direccion de memoria de d: \" + System.identityHashCode(d));\n\n        // Funciones:\n\n        // En java los tipos primitivos se pasan por valor: Se crea una copia de la variable\n        System.out.println(\"\\n\\nFunciones:\");\n        int _a = 5;\n        System.out.println(\"a: \" + _a);\n        cuadrado(_a);\n        System.out.println(\"a: \" + _a +\" (no se ha modificado)\");\n\n        // En java los objetos se pasan por referencia: Se pasa la referencia al objeto\n        Chorizo _c = new Chorizo(\"Sarta\", 2);\n        System.out.println(\"c: \" + _c);\n        picante(_c);\n        System.out.println(\"c: \" + _c + \" (se ha modificado)\");\n    }\n    \n    class Chorizo {\n        private String nombre;\n        private int picantez;\n\n        public Chorizo(String nombre, int picantez) {\n            this.nombre = nombre;\n            this.picantez = picantez;\n        }\n\n        public String getNombre() {\n            return nombre;\n        }\n\n        public void setNombre(String nombre) {\n            this.nombre = nombre;\n        }\n\n        public int getPicantez() {\n            return picantez;\n        }\n\n        public void setPicantez(int picantez) {\n            this.picantez = picantez;\n        }\n\n        public String toString() {\n            return \"Chorizo: \" + nombre + \" - Picantez: \" + picantez;\n        }\n    }\n\n    private void cuadrado(int x) {\n        x =  x * x;\n    }\n\n    private void picante(Chorizo c) {\n        c.setPicantez(c.getPicantez() * 2);\n    }\n\n    /*\n    * DIFICULTAD EXTRA (opcional):\n    */\n\n    private void intercambioPorValor(int a, int b) {\n        int temp = a;\n        a = b;\n        b = temp;\n    }\n\n    private void intercambioPorReferencia(Chorizo c, Chorizo d) {\n        Chorizo temp = c;\n        c = d;\n        d = temp;\n    }\n\n    private void extra() {\n\n        // En java los tipos primitivos se pasan por valor: Se crea una copia de la variable\n        System.out.println(\" \\n ---- 🌩 DIFICULTAD EXTRA 🌩 ----\\n\");\n        int a = 5;\n        int b = 10;\n        System.out.println(\"a: \" + a + \" - b: \" + b);\n        intercambioPorValor(a, b);\n        System.out.println(\"a: \" + a + \" - b: \" + b + \" (no se ha modificado)\");\n\n        // En java los objetos se pasan por referencia: Se pasa la referencia al objeto\n        // PERO java crea una copia de la referencia, por lo que no se modifica el objeto original\n\n        Chorizo c = new Chorizo(\"Sarta\", 2);\n        Chorizo d = new Chorizo(\"Txistorra\", 3);\n        System.out.println(\"c: \" + c + \" - d: \" + d);\n        intercambioPorReferencia(c, d);\n        System.out.println(\"c: \" + c + \" - d: \" + d + \" (no se ha modificado)\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/java/alexdevrep.java",
    "content": "package _05_Valor_y_Referencia;\n\nimport java.util.ArrayList;\n\npublic class _05_Valor_y_Referencia {\n    /*\n     * EJERCICIO:\n     * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n     *   su tipo de dato.\n     * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y\n     *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n     * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n     *\n     * DIFICULTAD EXTRA (opcional):\n     * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n     * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n     *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n     *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n     *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n     *   Comprueba también que se ha conservado el valor original en las primeras.\n     */\n\n    //Asignación de variables por valor\n    static int valor1 = 10;\n    static int valor2 = valor1;\n\n    //Asignación de variables por referencia\n    static ArrayList<Integer> numeros = new ArrayList<>();\n    static ArrayList<Integer> numerosNew = numeros;\n    //Dificultad extra\n    //Programa asignación por valor\n    public static void programa1(int numero1, int numero2){\n         numero1 = 5;\n         numero2 = 3;\n         System.out.println(\"El valor del numero1 ahora es: \"+numero1);\n         System.out.println(\"El valor del numero2 ahora es: \"+numero2);\n\n    }\n    //Programa asignación por referencia\n    public static ArrayList<String> programa2 (ArrayList lista){\n        ArrayList<String> listaNueva = lista;\n        listaNueva.remove(\"Alexdevrep\");\n        System.out.println(\"Los elementos en la lista nueva son:\"+ lista);\n        return  listaNueva;\n\n\n    }\n\n\n\n\n\n    public static void main(String[] args){\n        //Asignación de variables por valor\n        valor1 = 20;\n        System.out.println(valor1);\n        System.out.println(valor2);\n\n        //Asignación de variables por referencia\n        //Creamos un Array\n        numeros.add(1);\n        numeros.add(2);\n        numeros.add(3);\n        numeros.add(4);\n        numerosNew.remove(2);\n        System.out.println(numeros);\n        /*\n        * Como podemos comprobar aunque hayamos quitado el número 3\n        * en el arrayList numerosNew el array original numeros tambien\n        * se ve afectado por esta modificacion.\n        */\n\n        //Dificultad Extra\n        //Programa asignación por valor\n        int numero1 =3;\n        int numero2 =5;\n        System.out.println(\"El valor original del numero1 es:\"+numero1);\n        System.out.println(\"El valor original del numero2 es:\"+numero2);\n\n        programa1 (numero1,numero2);\n\n        //Programa asignación por referencia\n        ArrayList<String> lista = new ArrayList<>();\n        lista.add(\"Hola\");\n        lista.add(\"Alexdevrep\");\n        lista.add(\"Java\");\n        System.out.println(\"Los elementos en la lista original son:\"+ lista);\n\n        programa2(lista);\n\n        /*\n        Los valores originales no cambian despues de llamar a las funciones de intercambios\n        ya que en Java los parámetros se pasan por valor incluso cuando se tratan de objetos\n         */\n\n\n\n\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/java/asjordi.java",
    "content": "public class Main {\n\n    /**\n     * Java utiliza el mecanismo de \"paso por valor\".\n     * Esto significa que cuando pasas una variable a un método,\n     * se pasa una copia del valor de la variable, no la variable en sí.\n     * Esto es cierto tanto para tipos primitivos como para referencias a objetos.\n     * Para los tipos primitivos, el valor que se pasa es el contenido de la variable.\n     * Para las referencias a objetos, el valor que se pasa es la referencia al objeto, no el objeto en sí.\n     * Por lo tanto, puedes modificar el objeto al que apunta la referencia,\n     * pero no puedes cambiar la referencia en sí para que apunte a un objeto diferente.\n     * @param args\n     */\n\n    public static void main(String[] args) {\n\n        // Asignación de valores a las variables\n        int numero = 5; // Asignación por valor\n        double decimal = 5.0; // Asignación por valor\n        boolean bool = true; // Asignación por valor\n\n        int[] numeros = {1, 2, 3}; // Asignación por referencia\n        int[] numeros2 = numeros; // Asignación por referencia\n        int[] numeros3 = {1, 2, 3}; // Asignación por referencia\n\n        System.out.println(numeros == numeros2); // true\n        System.out.println(numeros == numeros3); // false\n\n        // Funciones por valor\n        /**\n         * Cuando se pasa un parámetro por valor a un método,\n         * se crea una copia del valor pasado a ese método.\n         * Esto significa que cualquier cambio realizado en el parámetro dentro del método\n         * no afectará a la variable original fuera del mismo.\n         */\n        int a = 5;\n        duplicar(a);\n        System.out.println(\"El valor de a después de llamar al método duplicar es: \" + a);\n\n        // Funciones por referencia\n        /**\n         * En Java, los parámetros por referencia se utilizan para transmitir información a un método de referencia.\n         * Cuando se pasa un parámetro de referencia a un método, se pasa la dirección de memoria del objeto o la referencia al objeto en sí mismo.\n         * Esto permite que el método pueda acceder y modificar el estado del objeto original.\n         */\n\n        String[] personas = {\"Juan\", \"Pedro\", \"Luis\"};\n        System.out.println(\"El nombre de la persona en la posición 1 es: \" + personas[1]);\n        cambiarNombre(personas, 1, \"Carlos\");\n        System.out.println(\"El nombre de la persona en la posición 1 después de llamar al método cambiarNombre es: \" + personas[1]);\n\n        System.out.println(\"-\".repeat(50));\n\n        int o1 = 7;\n        int o2 = 3;\n\n        int n1 = intercambiarPorValor(o1, o2);\n        int n2 = intercambiarPorValor(o2, o1);\n\n        StringBuilder o3 = new StringBuilder(\"Hola\");\n        StringBuilder o4 = new StringBuilder(\"Adiós\");\n\n        StringBuilder n3 = intercambiarPorReferencia(o3, o4);\n        StringBuilder n4 = intercambiarPorReferencia(o4, o3);\n\n        System.out.println(\"El valor de o1 es: \" + o1);\n        System.out.println(\"El valor de o2 es: \" + o2);\n        System.out.println(\"El valor de n1 es: \" + n1);\n        System.out.println(\"El valor de n2 es: \" + n2);\n\n        System.out.println(\"El valor de o3 es: \" + o3);\n        System.out.println(\"El valor de o4 es: \" + o4);\n        System.out.println(\"El valor de n3 es: \" + n3);\n        System.out.println(\"El valor de n4 es: \" + n4);\n\n\n\n    }\n\n    public static void duplicar(int a) {\n        a = a * 2;\n        System.out.println(\"El valor de a dentro del método duplicar es: \" + a);\n    }\n\n    public static void cambiarNombre(String[] nombres, int pos, String nuevoNombre) {\n        nombres[pos] = nuevoNombre;\n    }\n\n    /**\n     * DIFICULTAD EXTRA (opcional):\n     * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n     * Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n     * Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n     * se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n     * variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n     * Comprueba también que se ha conservado el valor original en las primeras.\n     */\n\n    public static int intercambiarPorValor(int original, int intercambio) {\n        original = intercambio;\n        return original;\n    }\n\n    public static StringBuilder intercambiarPorReferencia(StringBuilder original, StringBuilder intercambio) {\n        original = intercambio;\n        return original;\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/java/cesar-ch.java",
    "content": "import java.util.HashMap;\nimport java.util.Map;\n\npublic class Main {\n    public static void main(String[] args) {\n        // Asignación de variables por valor\n        int a = 10;\n        int b = a;\n\n        a = 5;\n\n        System.out.println(a); // 5\n        System.out.println(b); // 10\n\n        // Asignación de variables por referencia\n        Map<String, Integer> x = new HashMap<>();\n        x.put(\"a\", 10);\n        x.put(\"b\", 20);\n        Map<String, Integer> y = x;\n\n        x.put(\"a\", 12);\n        x.put(\"b\", 24);\n        \n        System.out.println(x); // [12, 24]\n        System.out.println(y); // [12, 24]\n\n        // Función con parámetro por valor\n        int numero = 5;\n        cambiarValor(numero);\n\n        System.out.println(numero); // 5\n\n        // Función con parámetro por referencia\n        Map<String, Integer> objeto = new HashMap<>();\n        objeto.put(\"a\", 5);\n        cambiarReferencia(objeto);\n\n        System.out.println(objeto); // {a=100}\n\n        // Ejemplo que intercambia los valores de dos variables por valor\n        int c = 10;\n        int d = 5;\n\n        int[] newValues = intercambiarValores(c, d);\n        System.out.println(\"Valores iniciales: \" + c + \", \" + d); // 10, 5\n        System.out.println(\"Valores por valor: \" + newValues[0] + \", \" + newValues[1]); // 5, 10\n\n        // Ejemplo que intercambia los valores de dos variables por referencia\n        Map<String, Integer> objA = new HashMap<>();\n        objA.put(\"a\", 10);\n        Map<String, Integer> objB = new HashMap<>();\n        objB.put(\"a\", 5);\n\n        Map<String, Integer>[] newObjects = intercambiarReferencias(objA, objB);\n        System.out.println(\"Valores iniciales: \" + objA + \", \" + objB); // {a=10}, {a=5}\n        System.out.println(\n                \"Valores por referencia: \" + newObjects[0] + \", \" + newObjects[1]); // {a=5}, {a=10}\n    }\n\n    static void cambiarValor(int numero) {\n        numero = 100;\n        System.out.println(numero); // 100\n    }\n\n    static void cambiarReferencia(Map<String, Integer> objeto) {\n        objeto.put(\"a\", 100);\n        System.out.println(objeto); // {a=100}\n\n    }\n\n    static int[] intercambiarValores(int c, int d) {\n        int temp = c;\n        c = d;\n        d = temp;\n\n        return new int[] { c, d };\n    }\n\n    static Map<String, Integer>[] intercambiarReferencias(Map<String, Integer> obj1, Map<String, Integer> obj2) {\n        Map<String, Integer> temp1 = new HashMap<>(obj1);\n        Map<String, Integer> temp2 = new HashMap<>(obj2);\n        Map<String, Integer> temp = new HashMap<>(obj1);\n        temp1.clear();\n        temp1.putAll(temp2);\n        temp2.clear();\n        temp2.putAll(temp);\n\n        return new Map[] { temp1, temp2 };\n    }\n}"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/java/chartypes.java",
    "content": "\nimport java.util.HashMap;\nimport java.util.Map;\n\nclass chartypes {\n    public static void main(String[] args) {\n        // Value\n        int myNumber = 5;\n        System.out.println(\"myNumber = \" + myNumber);\n        valueProof(5);\n        System.out.println(\"myNumber after the function was called = \" + myNumber);\n        System.out.println(\" How you can see...this is assigning variables by value\");\n\n        // Reference\n        Map<String, Integer> dict = new HashMap<>();\n        dict.put(\"cinco\", 5);\n        System.out.println(\"Before call the method: \" + dict);\n        referenceProof(dict);\n        System.out.println(\"After called the method: \" + dict);\n        System.out.println(\" How you can see...this is assigning variables by reference\");\n\n        // Exercise\n\n        // Value\n        int two = 2;\n        int five = 5;\n        int[] numbers = exerciseValueProof(two, five);\n        int num1 = numbers[0];\n        int num2 = numbers[1];\n        System.out.println(\"variable named 'two' = \" + two);\n        System.out.println(\"variable named 'five' = \" + five);\n\n        System.out.println(\"new variable named 'num1' = \" + num1);\n        System.out.println(\"new variable named 'num2' = \" + num2);\n\n        // Reference\n        Map<String, Integer> map1 = new HashMap<>();\n        Map<String, Integer> map2 = new HashMap<>();\n        map1.put(\"ten\", 10);\n        map2.put(\"eleven\", 11);\n\n        System.out.println(\" my numbers at the begining: \");\n        System.out.println(\" first Map: \" + map1);\n        System.out.println(\" second Map \" + map2);\n        exerciseReferenceProof(map1, map2);\n        System.out.println(\" my numbers after called teh method : \");\n        System.out.println(\" first Map: \" + map1);\n        System.out.println(\" second Map \" + map2);\n\n    }\n\n    static void valueProof(int number) {\n        System.out.println(\"number = \" + number);\n        number = 8;\n        System.out.println(\"number has been reasigned to: \" + number);\n\n    }\n\n    static void referenceProof(Map<String, Integer> map) {\n        map.put(\"cinco\", 7);\n    }\n\n    static int[] exerciseValueProof(int value1, int value2) {\n        int mediator = value1;\n        value1 = value2;\n        value2 = mediator;\n        int[] response = { value1, value2 };\n\n        return response;\n\n    }\n\n    static void exerciseReferenceProof(Map<String, Integer> referValue1, Map<String, Integer> referValue2) {\n        referValue1.put(\"ten\", 20);\n        referValue2.put(\"eleven\", 123);\n\n    }\n}"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/java/danhingar.java",
    "content": "import java.util.*;\n\npublic class danhingar {\n\n    public static void main(String[] args) {\n        //Tipos de dato por valor\n        int number= 1;\n        int number2 = number;\n        number =2;\n        System.out.println(number);\n        System.out.println(number2);\n\n        String name1 = \"Pepe\";\n        String name2 = name1;\n        name1 = \"José\";\n        System.out.println(name1);\n        System.out.println(name2);\n\n        boolean condition1 = true;\n        boolean condition2 = condition1;\n        condition1 = false;\n        System.out.println(condition1);\n        System.out.println(condition2);\n\n        //Tipos de datos por referencia -> objetos\n        List<Integer> numberList1 = new ArrayList<>(Arrays.asList(1,2,3,4));\n        List<Integer> numberList2 = numberList1;\n        numberList2.add(5);\n        System.out.println(numberList1);\n        System.out.println(numberList2);\n\n        int c = 10;\n        changeValue(c);\n        System.out.println(c);\n\n        List<Integer> numberList3 = new ArrayList<>(Arrays.asList(10,20));\n        changeReference(numberList3);\n        System.out.println(numberList3);\n\n        String a = \"Pepe\";\n        String b = \"Juan\";\n        String[] result =method1Value(a, b);\n        System.out.println(a);\n        System.out.println(b);\n        System.out.println(result[0]);\n        System.out.println(result[1]);\n\n        List<String> nameList = new ArrayList<>(Arrays.asList(\"Marcos\",\"Jose\"));\n        List<String> nameList2 = new ArrayList<>(Arrays.asList(\"Alfonso\",\"Luis\"));\n        List<List<String>> result2 =method2Reference(nameList, nameList2);\n        System.out.println(nameList);\n        System.out.println(nameList2);\n        System.out.println(result2.get(0));\n        System.out.println(result2.get(1));\n    }\n\n    //Funcion con datos por valor\n    private static void changeValue(int number){\n        number = 20;\n        System.out.println(number);\n    }\n\n    //Funcion con datos por referencia\n    private static void changeReference(List<Integer> numbers){\n        numbers.add(30);\n\n        List<Integer> numberList4 = numbers;\n        numberList4.add(40);\n        System.out.println(numbers);\n        System.out.println(numberList4);\n\n        //Romper la referencia\n        List<Integer> numberList5 = new ArrayList<>(numbers);\n        numberList5.add(50);\n        System.out.println(numberList5);\n    }\n\n\n    //EJERCICIO EXTRA\n    private static String[] method1Value(String name1,String name2){\n        String temp = name1;\n        name1 = name2;\n        name2 = temp;\n        return new String[] {name1, name2};\n    }\n\n    private static List<List<String>> method2Reference(List<String> name1,List<String> name2){\n        List<String> temp = name1;\n        name1 = name2;\n        name2 = temp;\n        return  List.of(name1,name2);\n    }\n    \n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/java/davidSorroche.java",
    "content": "import java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\n\n/**\n *\n * @author David Sorroche\n */\n\npublic class FuncionesValorReferencia {\n    // Ejercicio\n    public void funcionPorValor(double numParam) {\n        numParam = 4.50;\n        System.out.println(\"Modificación valor pasado por parámetro: \" + numParam);\n    }\n    \n    public void funcionPorReferencia(List<String> listadoRefParam) {\n        listadoRefParam.add(\"nuevo Registro.\");\n        System.out.println(\"Modificación referencia pasada por parámetro: \" + Arrays.toString(listadoRefParam.toArray()));\n        \n        List<String> nuevoListadoRef = listadoRefParam;\n        nuevoListadoRef.add(\"nuevo registro a un nuevo dato List\");\n        System.out.println(\"Impresión del nuevo listado creado en la función: \" + Arrays.toString(nuevoListadoRef.toArray()));\n    }\n    \n    // Dificultad Extra\n    public double[] funcionPorValor(double num1, double num2) {\n        double numAux = num1;\n        num1 = num2;\n        num2 = numAux;\n        \n        return new double[]{num1, num2};\n    }\n    \n    public List[] funcionPorReferencia(List<String> listadoRef1, List<String>  listadoRef2) {\n        List<String> refAux = listadoRef1;\n        listadoRef1 = listadoRef2;\n        listadoRef2 = refAux;\n        \n       return new List[]{listadoRef1, listadoRef2};\n    }\n}\n\n/*\n     * EJERCICIO:\n     * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n     *   su tipo de dato.\n     * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n     *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n     * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n     *\n     * DIFICULTAD EXTRA (opcional):\n     * Crea dos programas que reciban dos parámetros (cada uno) definidos como\n     * variables anteriormente.\n     * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n     *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n     *   se asigna a dos variables diferentes a las originales. A continuación, imprime\n     *   el valor de las variables originales y las nuevas, comprobando que se ha invertido\n     *   su valor en las segundas.\n     *   Comprueba también que se ha conservado el valor original en las primeras.\n*/\n\npublic class ValorYReferencia {\n    public static void main(String[] args) {\n        // Para el ejercicio creamos una variable primitiva de tipo double (num) y una estrructura de datos (listadoRef).\n        double num = 9.00;\n        List<String> listadoRef = new ArrayList<>();\n        listadoRef.add(\"Practicando ejercicios\");\n        listadoRef.add(\"Retos de programación\");\n        listadoRef.add(\"Mouredev\");\n        listadoRef.add(\"en Java, usando Maven.\");\n        \n        // Mostramos los valores originales de las dos variables (double y estructura de datos List<String>\n        System.out.println(\"Valor original: \" + num);\n        System.out.println(\"Referencia original: \" + Arrays.toString(listadoRef.toArray()));\n        \n        // Creamos un objeto FuncionesValorReferencia (f) y llamamos a cada uno de los métodos (funcionPorValor y funcionPorReferencia.\n        FuncionesValorReferencia f = new FuncionesValorReferencia();\n        f.funcionPorValor(num);\n        f.funcionPorReferencia(listadoRef);\n        \n        // Comprobamos si las funciones han modificado el valor de las dos variables originales.\n        System.out.println(\"\\nValor actualizado: \" + num);\n        System.out.println(\"Referencia actualizada: \" + Arrays.toString(listadoRef.toArray()));\n        \n        // Añadimos la dificultad extra.\n        double num1 = 4.00;\n        double num2 = 47.75;\n        \n        List<String> listadoRef1 = new ArrayList<>();\n        List<String> listadoRef2 = new ArrayList<>();\n        \n        listadoRef1.add(\"Hola\");\n        listadoRef1.add(\"Y\");\n        listadoRef1.add(\"Adiós\");\n        \n        listadoRef2.add(\"Probando\");\n        listadoRef2.add(\"Intencamibo de datos de referencia\");\n        \n        System.out.println(\"\\n\" + num1 +\", \" + num2);\n        double[] valores = f.funcionPorValor(num1, num2);\n        double num3 = valores[0];\n        double num4 = valores[1];\n        System.out.println(\"\\n\" + num1 + \", \" + num2);\n        System.out.println(num3 + \", \" + num4);\n        \n        System.out.println(Arrays.toString(listadoRef1.toArray()) + \"\\t\" + Arrays.toString(listadoRef2.toArray()));\n        List[] referencias = f.funcionPorReferencia(listadoRef1, listadoRef2);\n        List<String> listadoRef3 = referencias[0];\n        List<String> listadoRef4 = referencias[1];\n        System.out.println(\"\\n\" + Arrays.toString(listadoRef1.toArray()) + \"\\t\" + Arrays.toString(listadoRef2.toArray()));\n        System.out.println(Arrays.toString(listadoRef3.toArray()) + \"\\t\" + Arrays.toString(listadoRef4.toArray()));\n    }\n}\n\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/java/deathwing696.java",
    "content": "/*\n * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license\n * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Main.java to edit this template\n */\n\n/*\n * EJERCICIO:\n * - Muestra ejemplos de asignacin de variables \"por valor\" y \"por referencia\", segn\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cmo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayora de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parmetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parmetros por valor, y en otro caso, por referencia.\n *   Estos parmetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuacin, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba tambin que se ha conservado el valor original en las primeras.\n */\n\n/**\n *\n * @author death\n */\npublic class deathwing696 {\n\n    public static void main(String[] args) \n    {\n        int variable1 = 1, variable2 = 5;\n        IntegerWrapper variable3 = new IntegerWrapper(1);\n        IntegerWrapper variable4 = new IntegerWrapper(5);\n        \n        funcion_por_valor(variable1, variable2);\n        \n        System.out.println(\"Despus de la ejecucin del paso por valor los valores son variable1:\" + variable1 + \" y variable2:\" + variable2);\n        \n        funcion_por_referencia(variable3, variable4);\n        \n        System.out.println(\"Despus de la ejecucin del paso por referencia los valores son variable3:\" + variable3.getValue() + \" y variable4:\" + variable4.getValue());\n    }\n    \n    static private void funcion_por_valor(int var1, int var2)\n    {\n        int aux = var1;\n        \n        var1 = var2;\n        var2 = aux;\n    }\n    \n    static private void funcion_por_referencia(IntegerWrapper var1, IntegerWrapper var2)\n    {\n        IntegerWrapper aux = new IntegerWrapper(var1.getValue());\n        \n        var1.setValue(var2.getValue());\n        var2.setValue(aux.getValue());\n    }\n    \n}\n\n/*Java SIEMPRE pasa los parmetros de los tipos primitivos por valor, si quieres que lo pase por referencia tienes que \n* \"inventarte\" una especia de wrapper\n*/\nclass IntegerWrapper\n{\n    private int value;\n    \n    public IntegerWrapper(int value)\n    {\n        this.value = value;\n    }\n    \n    public int getValue()\n    {\n        return value;\n    }\n    \n    public void setValue(int value)\n    {\n        this.value = value;\n    }\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/java/estuardodev.java",
    "content": "import java.util.ArrayList;\nimport java.util.List;\n\npublic class estuardodev {\n    public static void main(String[] args) {\n        int valor1 = 3;\n        int valor2 = valor1;\n\n        valor2 += 2;\n\n        System.out.println(\"Valor 1: \" + valor1);\n        System.out.println(\"Valor 2: \" + valor2);\n\n        List<String> strings = new ArrayList<>();\n        strings.add(\"Python\");\n        strings.add(\"C#\");\n        strings.add(\"Java\");\n\n        List<String> strings2 = new ArrayList<>(strings);\n        strings2.add(\"C++\");\n\n        for (String i : strings) {\n            System.out.println(\"Valores de Strings 1: \" + i);\n        }\n\n        for (String i : strings2) {\n            System.out.println(\"Valores de Strings 2: \" + i);\n        }\n\n        valor(5, 10);\n\n        List<String> lista1 = new ArrayList<>();\n        lista1.add(\"C#\");\n        List<String> lista2 = new ArrayList<>();\n        lista2.add(\"Python\");\n        referencia(lista1, lista2);\n\n    }\n\n    private static void valor(int val1, int val2) {\n        int valor = val1;\n        val1 = val2;\n        val2 = valor;\n\n        System.out.println(\"Valor del parámetro 1: \" + val1);\n        System.out.println(\"Valor del parámetro 2: \" + val2);\n    }\n\n    private static void referencia(List<String> lista1, List<String> lista2) {\n        List<String> refuerzo = new ArrayList<>(lista1);\n        lista1.clear();\n        lista1.addAll(lista2);\n        lista2.clear();\n        lista2.addAll(refuerzo);\n        lista1.add(\"Lista 1\");\n        lista2.add(\"Lista 2\");\n\n        for (String s : lista1) {\n            System.out.println(\"Valor lista 1: \" + s);\n        }\n        for (String s : lista2) {\n            System.out.println(\"Valor lista 2: \" + s);\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/java/eulogioep.java",
    "content": "public class eulogioep {\n    public static void main(String[] args) {\n        // Ejemplos de asignación por valor (tipos primitivos)\n        int a = 5;\n        int b = a; // b es una copia del valor de a\n        b = 10; // Cambiar b no afecta a a\n        System.out.println(\"a: \" + a + \", b: \" + b); // a: 5, b: 10\n\n        // Ejemplos de asignación por referencia (objetos)\n        int[] arr1 = {1, 2, 3};\n        int[] arr2 = arr1; // arr2 apunta al mismo array que arr1\n        arr2[0] = 100; // Cambiar arr2 afecta a arr1\n        System.out.println(\"arr1[0]: \" + arr1[0] + \", arr2[0]: \" + arr2[0]); // arr1[0]: 100, arr2[0]: 100\n\n        // Ejemplo de función con parámetro por valor\n        int x = 5;\n        modificarValor(x);\n        System.out.println(\"x después de modificarValor: \" + x); // x no cambia\n\n        // Ejemplo de función con parámetro por referencia\n        int[] array = {1, 2, 3};\n        modificarReferencia(array);\n        System.out.println(\"array[0] después de modificarReferencia: \" + array[0]); // array[0] cambia\n\n        // DIFICULTAD EXTRA\n        // Programa 1: Intercambio por valor\n        int num1 = 10, num2 = 20;\n        System.out.println(\"Antes del intercambio por valor: num1 = \" + num1 + \", num2 = \" + num2);\n        int[] resultadoValor = intercambioPorValor(num1, num2);\n        int nuevoNum1 = resultadoValor[0], nuevoNum2 = resultadoValor[1];\n        System.out.println(\"Después del intercambio por valor:\");\n        System.out.println(\"Variables originales: num1 = \" + num1 + \", num2 = \" + num2);\n        System.out.println(\"Nuevas variables: nuevoNum1 = \" + nuevoNum1 + \", nuevoNum2 = \" + nuevoNum2);\n\n        // Programa 2: Intercambio por referencia\n        Integer ref1 = 30, ref2 = 40;\n        System.out.println(\"\\nAntes del intercambio por referencia: ref1 = \" + ref1 + \", ref2 = \" + ref2);\n        Integer[] resultadoReferencia = intercambioPorReferencia(ref1, ref2);\n        Integer nuevoRef1 = resultadoReferencia[0], nuevoRef2 = resultadoReferencia[1];\n        System.out.println(\"Después del intercambio por referencia:\");\n        System.out.println(\"Variables originales: ref1 = \" + ref1 + \", ref2 = \" + ref2);\n        System.out.println(\"Nuevas variables: nuevoRef1 = \" + nuevoRef1 + \", nuevoRef2 = \" + nuevoRef2);\n    }\n\n    // Función que recibe un parámetro por valor\n    public static void modificarValor(int n) {\n        n = 100; // Este cambio no afecta a la variable original\n    }\n\n    // Función que recibe un parámetro por referencia\n    public static void modificarReferencia(int[] arr) {\n        arr[0] = 100; // Este cambio afecta al array original\n    }\n\n    // Función para intercambio por valor\n    public static int[] intercambioPorValor(int a, int b) {\n        int temp = a;\n        a = b;\n        b = temp;\n        return new int[]{a, b};\n    }\n\n    // Función para intercambio por referencia\n    public static Integer[] intercambioPorReferencia(Integer a, Integer b) {\n        Integer temp = new Integer(a);\n        a = new Integer(b);\n        b = new Integer(temp);\n        return new Integer[]{a, b};\n    }\n}"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/java/frangarmez21.java",
    "content": "import java.util.List;\n\npublic class frangarmez21 {\n\n    public static void main(String[] args) {\n\n        System.out.println(\"##Ejercicio valor/referencia##\");\n        /*\n         * EJERCICIO:\n         * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n         *   su tipo de dato.\n         *\n         * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y\n         *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n         * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n         */\n\n        System.out.println();\n        System.out.println(\"##Asignación por valor##\");\n        System.out.println();\n        //Cualquier variable de tipo primitivo y de la clase String como caso excepcional se les realiza una asignacion por valor.\n        System.out.println(\"Creamos una variable de tipo entero y le damos un valor\");\n        int miNumero = 5;\n        System.out.println(miNumero);\n        System.out.println(\"LLamamos a una función que modifica el valor de la variable\");\n        modificarNumero(miNumero);\n        System.out.println(\"Imprimimos el valor de la variable inicial\");\n        System.out.println(miNumero);\n\n        System.out.println(\"Creamos una variable de tipo String y le damos un valor\");\n        String miCadena = \"Hola Mundo\";\n        System.out.println(miCadena);\n\n        System.out.println(\"LLamamos a una función que modifica el valor de la variable\");\n        modificarCadena(miCadena);\n\n        System.out.println(\"Imprimimos el valor de la variable inicial\");\n        System.out.println(miCadena);\n\n\n        System.out.println(\"##Asignación por referencia##\");\n        /*Cualquier variable de tipo Array y la mayoría de los objetos se les realiza una asignación por valor, es decir,\n        se les asigna una dirección de memoria por lo que cualquier cambio sobre estos afecta a esa dirección de memoria\n        y por lo tanto verá modificado su valor inicial.*/\n        System.out.println(\"Creamos un Array de enteros de 3 posiciones\");\n        int[] misNumeros = new int[3];\n\n        System.out.println(\"Asignamos valores a nuestro Array\");\n        misNumeros[0] = 10;\n        misNumeros[1] = 20;\n        misNumeros[2] = 30;\n\n        System.out.println(\"Imprimimos el contenido de nuestro Array\");\n        for (int numero : misNumeros) {\n            System.out.println(numero);\n        }\n\n        System.out.println(\"Modificamos en valor de nuestro Array en la función\");\n        modificarArray(misNumeros);\n\n        System.out.println(\"Imprimimos el contenido de nuestro Array\");\n        for (int numero : misNumeros) {\n            System.out.println(numero);\n        }\n\n        System.out.println();\n        System.out.println(\"##Dificultad Extra##\");\n        System.out.println();\n\n        /* DIFICULTAD EXTRA (opcional):\n         * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n         * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n         *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n         *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n         *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n         *   Comprueba también que se ha conservado el valor original en las primeras.\n         */\n\n        System.out.println(\"Programa 1: parámetros por valor\");\n        System.out.println();\n\n        int numberOne = 1;\n        System.out.println(\"Variable inicial 1: \" + numberOne);\n        int numberTwo = 2;\n        System.out.println(\"Variable inicial 2: \" + numberTwo);\n        System.out.println(\"Llamamos a la funcion de intercambio de valor\");\n        List<Integer> resulList = changeVariableByValue(numberOne, numberTwo);\n        int contador = 1;\n        for (int numero : resulList) {\n            System.out.println(\"Variable \" + contador + \": \" + numero);\n            contador++;\n        }\n        System.out.println(\"Variable inicial 1: \" + numberOne);\n        System.out.println(\"Variable inicial 2: \" + numberTwo);\n\n        System.out.println();\n        System.out.println(\"Programa 2: parámetros por referencia\");\n        System.out.println();\n\n        Integer integerOne = 1;\n        System.out.println(\"Variable inicial 1: \" + numberOne);\n        Integer integerTwo = 2;\n        System.out.println(\"Variable inicial 2: \" + numberTwo);\n        System.out.println(\"Llamamos a la funcion de intercambio de valor\");\n        List<Integer> resultList = changeVariableByReference(numberOne, numberTwo);\n        contador = 1;\n        for (Integer numero : resultList) {\n            System.out.println(\"Variable \" + contador + \": \" + numero);\n            contador++;\n        }\n        System.out.println(\"Variable inicial 1: \" + numberOne);\n        System.out.println(\"Variable inicial 2: \" + numberTwo);\n\n    }\n\n    private static List<Integer> changeVariableByReference(Integer number1, Integer number2) {\n        System.out.println(\"Dentro de la funcion:\");\n        System.out.println(\"Cambiamos el valor de variable 1\");\n        Integer numberOne = number2;\n        System.out.println(\"Cambiamos el valor de variable 2\");\n        Integer numberTwo = number1;\n        System.out.println(\"Salimos de la función\");\n        return List.of(numberOne, numberTwo);\n    }\n\n    private static List<Integer> changeVariableByValue(int number1, int number2) {\n        System.out.println(\"Dentro de la funcion:\");\n        System.out.println(\"Cambiamos el valor de variable 1\");\n        int numberOne = number2;\n        System.out.println(\"Cambiamos el valor de variable 2\");\n        int numberTwo = number1;\n        System.out.println(\"Salimos de la función\");\n        return List.of(numberOne, numberTwo);\n    }\n\n    private static void modificarNumero(int miNumero) {\n        //Modificamos el valor de la variable a 2\n        miNumero = 2;\n        System.out.println(\"valor dentro de la funcion: \" + miNumero);\n    }\n\n    private static void modificarCadena(String miCadena) {\n        miCadena = \"Esto es un String cuya referencia se hace por valor\";\n        System.out.println(\"valor dentro de la funcion: \" + miCadena);\n    }\n\n    private static void modificarArray(int[] miArray) {\n        miArray[0] = 1;\n        miArray[1] = 2;\n        miArray[2] = 3;\n    }\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/java/hernanR.java",
    "content": "public class hernanR {\n    public static void main(String[] args) {\n        // Por valor: tipos primitivos\n        int a = 10;\n        int b = a;\n        b = 20;\n        System.out.println(\"Por valor - a: \" + a);\n        System.out.println(\"Por valor - b: \" + b);\n\n        // Por referencia: objetos\n        int[] c = { 1, 2, 3 };\n        int[] d = c;\n        d[0] = 10;\n        System.out.println(\"Por referencia - c[0]: \" + c[0]);\n        System.out.println(\"Por referencia - d[0]: \" + d[0]);\n\n        // DIFICULTAD EXTRA (opcional):\n        int[] valores = { 10, 20 };\n        intercambiarPorReferencia(valores);\n        int nuevoX = valores[0];\n        int nuevoY = valores[1];\n        System.out.println(\"Intercambio por referencia - nuevoX: \" + nuevoX);\n        System.out.println(\"Intercambio por referencia - nuevoY: \" + nuevoY);\n    }\n\n    // Por valor\n    public static void porValor(int a, int b) {\n        a = 20;\n        b = 30;\n    }\n\n    // Por referencia\n    public static void porReferencia(int[] c, int[] d) {\n        c[0] = 10;\n        d[0] = 20;\n    }\n\n    public static void intercambiarPorReferencia(int[] arr) {\n        int temp = arr[0];\n        arr[0] = arr[1];\n        arr[1] = temp;\n    }\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/java/inmortalnight.java",
    "content": "// 05 - VALOR Y REFERENCIA\n\npublic class inmortalnight {\n    public static void main(String[] args) {\n        //Variables por valor, tipos primitivos\n        int a = 5;\n        int b = a;\n        b = 10;\n        System.out.println(a + \" \" + b); \n        //Variables por referencia, tipos compuestos\n        int[] c = {5};\n        int[] d = c;\n        d[0] = 10;\n        System.out.println(c[0] + \" \" + d[0]);\n\n\n        //EXTRA\n        //Por valor\n        int valor1 = 10;\n        int valor2 = 20;\n        int valor3 = (intercambiaValor(valor1, valor2))[0];\n        int valor4 = ((intercambiaValor(valor1, valor2))[1]);\n        System.out.println(\"original: \" + valor1 + \" \" + valor2);\n        System.out.println(\"después: \" + valor3 + \" \" + valor4);\n        \n        //Por referencia\n        int[] valor1_1 = {10, 20};\n        int[] valor2_2 = {30, 40};\n        int[] valor3_3 = (intercambiaReferencia(valor1_1, valor2_2))[0];\n        int[] valor4_4 = (intercambiaReferencia(valor1_1, valor2_2))[1];\n        System.out.println(\"original: \" );\n        printArray(valor1_1);\n        printArray(valor2_2);\n        System.out.println(\"después: \" );\n        printArray(valor3_3);\n        printArray(valor4_4);\n    }\n    public static int[] intercambiaValor(int a, int b){\n        int temp = a;\n        a = b;\n        b = temp;\n        int[] n = {a, b};\n        return n;\n    } \n    public static int[][] intercambiaReferencia(int[] a, int[] b){\n        int[] temp = a;\n        a = b;\n        b = temp;\n        int[][] n = {a, b};\n        return n;\n    }\n    \n    public static void printArray(int[] array) {\n        for (int i : array) {\n            System.out.print(i + \" \");\n        }\n        System.out.println();\n    }\n}"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/java/julian98789.java",
    "content": "\npublic class reto_5 {\n    public static void main(String[] args) {\n        // Ejemplo de asignación por valor (datos primitivos)\n        int a = 5;\n        int b = a; // 'b' obtiene una copia del valor de 'a'\n        b = 10; // Cambiamos 'b', pero 'a' permanece igual\n\n        System.out.println(\"Asignación por valor:\");\n        System.out.println(\"a: \" + a); // Imprime 5\n        System.out.println(\"b: \" + b); // Imprime 10\n\n        // Ejemplo de asignación por referencia (objetos)\n        Persona persona1 = new Persona(\"Juan\");\n        Persona persona2 = persona1; // 'persona2' obtiene la referencia de 'persona1'\n        persona2.nombre1 = \"Pedro\"; // Cambiamos el nombre usando 'persona2'\n\n        System.out.println(\"\\nAsignación por referencia:\");\n        System.out.println(\"persona1.nombre: \" + persona1.nombre1); // Imprime \"Pedro\"\n        System.out.println(\"persona2.nombre: \" + persona2.nombre1); // Imprime \"Pedro\"\n\n        // Ejemplo de paso de parámetros por valor (datos primitivos)\n        int numero = 5;\n        cambiarValor(numero);\n        System.out.println(\"\\nPaso por valor:\");\n        System.out.println(\"numero: \" + numero); // Imprime 5, porque se pasa una copia\n\n        // Ejemplo de paso de parámetros por referencia (objetos)\n        Persona persona = new Persona(\"Juan\");\n        cambiarNombre(persona);\n        System.out.println(\"\\nPaso por referencia:\");\n        System.out.println(\"persona.nombre: \" + persona.nombre1); // Imprime \"Pedro\"\n\n        // **********reto****************\n        System.out.println(\"\\nReto:\");\n        int numeroOriginal1 = 5;\n        int numeroOriginal2 = 10;\n        Persona personaOriginal1 = new Persona(\"Juan\");\n        Persona personaOriginal2 = new Persona(\"andres\");\n\n        System.out.println(\"Nombre 1: \" + personaOriginal1.nombre1 + \" nombre 2 \" + personaOriginal2.nombre1);\n\n        System.out.println(\"Antes de cambiar:\");\n        System.out.println(\"numeroOriginal1: \" + numeroOriginal1); \n        System.out.println(\"numeroOriginal2: \" + numeroOriginal2); \n        System.out.println(\"personaOriginal1.nombre: \" + personaOriginal1.nombre1);\n        System.out.println(\"personaOriginal2.nombre: \" + personaOriginal2.nombre1); \n\n        System.out.println(\"Después de cambiar:\");\n\n        cambiarValor(numeroOriginal1,numeroOriginal2);\n        cambiarNombre(personaOriginal1,personaOriginal2);\n\n        \n    }\n\n    public static void cambiarValor(int numeroOriginal1, int numeroOriginal2 ) {\n        int aux = numeroOriginal1;\n        numeroOriginal1 = numeroOriginal2;\n        numeroOriginal2 = aux;\n\n        System.out.println(\"valores cambiados numero 1: \"+ numeroOriginal1 + \" numero 2: \" +numeroOriginal2 );\n\n    }\n\n    public static void cambiarNombre(Persona p1, Persona p2) {\n        String aux = p1.nombre1;\n        p1.nombre1 = p2.nombre1 ;\n        p2.nombre2 = aux;\n\n        System.out.println(\"valores cambiados p1.nombre1: \"+ p1.nombre1 + \" p2.nombre2: \" +p2.nombre2 );\n    }\n\n    public static void cambiarValor(int n) {\n        n = 10;\n    }\n\n    public static void cambiarNombre(Persona p1) {\n        p1.nombre1 = \"Pedro\";\n    }\n\n    static class Persona {\n        String nombre1;\n        String nombre2;\n\n        Persona(String nombre) {\n            this.nombre1 = nombre;\n        }\n\n       \n\n    }\n}\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/java/kleyner098.java",
    "content": "import java.util.Arrays;\n\npublic class kleyner098 {\n    /*\n     * EJERCICIO:\n     * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\",\n     * según su tipo de dato.\n     * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y\n     * \"por referencia\", y cómo se comportan en cada caso en el momento de ser\n     * modificadas.\n     * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n     */\n\n    public static void main(String[] args) {\n\n        // Los tipos primitivos en Java simpre toman su valor por copia\n        int num1 = 1; // Creamos una variable primitiva con un valor\n        int num2 = num1; // Se copia el mismo valor de num1 en num2\n        num1++; // Se modifica num1 y no afecta a num2\n        System.out.println(\"Valor de variable num1:\" + num1);\n        System.out.println(\"Valor de variable num2:\" + num2);\n        // Las dos varaibles tienen espacio de memoria diferentes\n        // Función\n        cambiar(num2);\n        // No se ha modificado el valor de num2\n        System.out.println(\"Valor de variable num2, después de pasarla como argumento de una función:\" + num2); \n\n        // Los demás tipos de variable tomarán el valor por referencia\n        // Los arrays se concideran un tipo de dato entre primitivo y objeto\n        int[] array1 = { 1, 2, 3, 4 }; // Creamos un array de tipo int\n        int[] array2 = array1; // Copiamos la array1 en la array dos\n        // Modificamos la array1\n        for (int i = 0; i < array1.length; i++) {\n            array1[i] = array1.length - i;\n        }\n        // Se ha realizado las modificaciones en las dos arrays\n        System.out.println(\"Array1: \" + Arrays.toString(array1));\n        System.out.println(\"Array2: \" + Arrays.toString(array2));\n\n        // Lo que en realidad ocurre es que lo que copiamos en la array2 es la\n        // referencia en memoria de la array1, por lo que en realidad las dos variables\n        // apunta a la misma arrays, es decir, al mismo espacio de memoria.\n        // En Java, en realidad todas las asignaciones son por copia, pero en el caso de\n        // los objetos, lo que se copia es la referencia de memoria y no los valores que\n        // contiene\n        System.out.println(\"Dirección de memoria de array1 \" + array1);\n        System.out.println(\"Dirección de memoria de array2 \" + array2);\n\n        // Función\n        cambiarArrays(array2);\n        System.out.println(\"Arrays2 después de pasarla como argumento de una función:\" + Arrays.toString(array2));\n\n        // Existen casos especiales de objetos, llamado objetos inmutables cuyo estado\n        // no puede ser modificado, es decir, una vez asignado un valor a un objeto este\n        // no se puede realizar cambios en sus atributos. El ejemplo más típico en Java\n        // son las clase String o la mayoría de las clases Wrappers(Integer, Double...)\n\n        String cadena1 = \"Hola mundo\"; // Creamos un objeto string\n        String cadena2 = cadena1; // Copiamos el valor del objeto cadena1 en cadena2 (Referencia al mismo objeto)\n        cadena1 = \"Adios Java\"; // Se crea otro objeto con el nuevo valor y se le asiga la referencia de cadena1\n        System.out.println(cadena1);\n        System.out.println(cadena2);\n\n        // Al principio, ambas cadena1 y cadena2 apuntan al objeto \"Hola mundo\".\n        // Después cadena1 apunta a un nuevo objeto \"Adios Java\" pareciendo que se ha\n        // modificado, pero en realidad crea un nuevo objeto con la referencia cadena1\n        // y cadena2 sigue apuntando al objeto original \"Hola mundo\".\n        // No se crea un nuevo objeto para cadena2 en este caso.\n        // Java utiliza un mecanismo llamado \"pool de cadenas\" o \"String pool\" para\n        // optimizar el uso de memoria y permitir que variables String con el mismo\n        // contenido referencien los mismos literales de cadena.\n\n        // Ejercicio extra\n\n        int numero1 = 5;\n        int numero2 = 7;\n        int[] arrryNum = cambiarOrden(numero1, numero2);\n        System.out.println(\"Valores originales: \" + numero1 + \" | \" + numero2);\n        System.out.println(\"Valores intercambiados: \" + arrryNum[0] +\" | \" + arrryNum[1]);\n        int[] tabla1 = {1,2,3};\n        int[] tabla2 = {4,3,2,1};\n        int[][] resultado = cambiarOrdenArray(tabla1, tabla2);\n        System.out.println(\"Valores originales: \" + Arrays.toString(tabla1) + \" | \" + Arrays.toString(tabla2));\n        System.out.println(\"Valores intercambiados: \" + Arrays.toString(resultado[0]) + \" | \" + Arrays.toString(resultado[1]));\n    }\n\n    // La función toma el valor por copia, lo que significa que se crea un espacion\n    // nuevo en memoria y copia el valor pasado en el argumento\n    static void cambiar(int a) {\n        a++;\n    }\n\n    // La función copia el valor de referencia de la array pasada en el argumento,\n    // por lo que hace referencia a la misma array\n    static void cambiarArrays(int[] array) {\n        for (int i = 0; i < array.length; i++) {\n            array[i] = -i;\n        }\n    }\n\n    /*\n     * DIFICULTAD EXTRA (opcional):\n     * Crea dos programas que reciban dos parámetros (cada uno) definidos como\n     * variables anteriormente.\n     * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso,\n     * por referencia.\n     * Estos parámetros los intercambia entre ellos en su interior, los retorna, y\n     * su retorno se asigna a dos variables diferentes a las originales. A\n     * continuación, imprime el valor de las variables originales y las nuevas,\n     * comprobando que se ha invertido su valor en las segundas.\n     * Comprueba también que se ha conservado el valor original en las primeras.\n     */\n\n     static int[] cambiarOrden(int num1, int num2){\n        int[] arrayNum = {num2, num1};\n        return arrayNum;\n     }\n\n     static int[][] cambiarOrdenArray(int[] array1, int[] array2){\n        int[][] arrayResult = new int[2][];\n        arrayResult[0] = new int[array2.length];\n        arrayResult[1] = new int[array1.length];\n        for (int i = 0; i < arrayResult[0].length; i++) {\n            arrayResult[0][i] = array2[i];\n        }\n        for (int i = 0; i < arrayResult[1].length; i++) {\n            arrayResult[1][i] = array1[i];\n        }\n        return arrayResult;\n     }\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/java/lautarorisso.java",
    "content": "public class LogicaJava05 {\n    \n    public static void main(String[] args) {\n        // 1.\n        // Por valor\n        int a = 10;\n        int b = a;\n\n        b = 20;\n\n        System.out.println(a); // 10\n        System.out.println(b); // 20\n        \n        // Por \"referencia\"\n        Persona p1 = new Persona();\n        p1.nombre = \"Alberto\";\n\n        Persona p2 = p1; // se copia la REFERENCIA, no el objeto\n\n        p2.nombre = \"Pedro\";\n\n        System.out.println(p1.nombre); // Pedro\n        System.out.println(p2.nombre); // Pedro\n\n        // 2.\n        // Por valor\n        int n = 5;\n        cambiarNumero(n);\n        System.out.println(n); // 5 porque se pasó una copia, se modifica la copia\n        \n        // Por \"referencia\"\n        Persona persona = new Persona();\n        persona.nombre = \"Ana\";\n\n        cambiarNombre(persona);\n\n        System.out.println(persona.nombre); // Carlos\n    }\n    // 2.\n    // Por valor\n    public static void cambiarNumero(int x) {\n        x = 100;\n    }\n    \n    // Por \"referencia\"\n    public static void cambiarNombre(Persona p) {\n    p.nombre = \"Carlos\";\n    }\n}\nclass Persona {\n    String nombre;\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/java/mariovelascodev.java",
    "content": "import java.util.ArrayList;\nimport java.util.HashSet;\n\npublic class mariovelascodev {\n    public static void main(String[] args) {\n        //Paso por valor\n        int number1 = 5;\n        int number2 = number1;\n        System.out.println(\"La variable number2 vale: \"+number2);\n        number2 = 2;\n        System.out.println(\"La variable number2 vale: \"+number2);\n        System.out.println(\"La variable number1 vale: \"+number1);\n\n        modificarValor(number1);\n        System.out.println(\"La variable number1 vale: \"+number1);\n\n        modificarValor(number2);\n        System.out.println(\"La variable number2 vale: \"+number2);\n\n        //Paso por referencia\n        int [] numbers = {10, 20,30};\n        int []  numbers2 = numbers;\n\n        System.out.println(\"Números del array numbers\");\n        for(int i=0; i<numbers.length;i++){\n            System.out.println(numbers[i]);\n        }\n\n        System.out.println(\"\\nNumeros del array numbers2\");\n        for(int i=0; i<numbers2.length;i++){\n            System.out.println(numbers2[i]);\n        }\n\n        //Modificamos el array numbers2\n        numbers2[0] = 11;\n\n        System.out.println(\"\\nNúmeros del array numbers\");\n        for(int i=0; i<numbers.length;i++){\n            System.out.println(numbers[i]);\n        }\n        System.out.println(\"\\nNumeros del array numbers2\");\n        for(int i=0; i<numbers2.length;i++){\n            System.out.println(numbers2[i]);\n        }\n\n        System.out.println(\"\\nNumeros de los arrays tras llamar a la función\");\n        modificarArray(numbers2);\n\n        System.out.println(\"\\nNúmeros del array numbers\");\n        for(int i=0; i<numbers.length;i++){\n            System.out.println(numbers[i]);\n        }\n        System.out.println(\"\\nNumeros del array numbers2\");\n        for(int i=0; i<numbers2.length;i++){\n            System.out.println(numbers2[i]);\n        }\n\n\n        System.out.println(\"\\n-------------EXTRA--------------\\n\");\n\n        String name = \"mario\";\n        String height = \"1.80\";\n\n        HashSet<String> lista = new HashSet<>();\n        HashSet<String> language = new HashSet<>();\n\n        lista.add(\"10\");\n        lista.add(\"20\");\n        lista.add(\"30\");\n        lista.add(\"40\");\n\n        language.add(\"Inglés\");\n        language.add(\"Frances\");\n        language.add(\"Español\");\n\n        System.out.println(\"Name: \"+name);\n        System.out.println(\"Altura: \"+height);\n        cambioPorValor(name, height);\n        System.out.println(\"Name: \"+name);\n        System.out.println(\"Altura: \"+height);\n\n        System.out.println(\"HashSet Lista:\"+ lista);\n        System.out.println(\"HashSet Language\"+language);\n        cambioPorReferencia(lista,language);\n    }\n\n\n    //Función paso por valor\n    public static void modificarValor(int number){\n        number = 23;\n        System.out.println(\"En la función la variable vale: \"+number);\n    }\n\n    //Función paso por referencia\n    public static void modificarArray(int[] array){\n        array[0] = 1;\n    }\n\n    //EXTRA\n    public static void cambioPorValor(String name, String height){\n        name = height;\n        height = name;\n        System.out.println(\"El valor de la variable name: \"+name);\n        System.out.println(\"El valor de la variable height: \"+height);\n    }\n\n    public static void cambioPorReferencia(HashSet<String> lista, HashSet<String> language){\n         lista = language;\n         System.out.println(\"El valor de lista: \"+lista);\n         System.out.println(\"El valor de language: \"+language);\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/java/martinbohorquez.java",
    "content": "/**\n * #05 VALOR Y REFERENCIA\n *\n * @author martinbohorquez\n */\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\n\npublic class martinbohorquez {\n\n    private static int num1;\n    private static int num2;\n    private static int[] array1;\n    private static int[] array2;\n    private static List<Integer> list1;\n    private static List<Integer> list2;\n\n    private static int num3;\n    private static int num4;\n    private static int[] array3;\n    private static int[] array4;\n    private static List<Integer> list3;\n    private static List<Integer> list4;\n    private static List<Integer> list5;\n    private static List<Integer> list6;\n\n    private static int numA;\n    private static int numB;\n    private static int[] arrayC;\n    private static int[] arrayD;\n    private static int[] arrayE;\n    private static int[] arrayF;\n    private static List<Integer> listG;\n    private static List<Integer> listH;\n    private static List listI;\n    private static List listJ;\n\n    public static void main(String[] args) {\n        /*\n         * Asignación de variable \"por valor\"\n         */\n        num1 = 10;\n        num2 = num1;\n        num2 = 20;\n        System.out.printf(\"num1: %d y num2: %d%n\", num1, num2);\n\n        /*\n         * Asignación de variable \"por referencia\"\n         */\n        //Array\n        array1 = new int[]{10, 20};\n        array2 = array1;\n        array2[0] = 30;\n        array2[1] = 40;\n        System.out.printf(\"array1: %s y array2: %s%n\",\n                Arrays.toString(array1), Arrays.toString(array2));\n\n        //List\n        list1 = new ArrayList<>(Arrays.asList(10, 20));\n        list2 = list1;\n        list2.add(30);\n        System.out.printf(\"list1: %s y list2: %s%n\",\n                list1.toString(), list2.toString());\n\n        /*\n         * Funciones con asignación de variable \"por valor\"\n         */\n        num3 = 100;\n        getValue(num3);\n        System.out.printf(\"num3: %d%n\", num3);\n\n        /*\n         * Funciones con asignación de variable \"por referencia\"\n         */\n        array3 = new int[]{100, 200};\n        getValue(array3);\n        System.out.printf(\"array3: %s%n\", Arrays.toString(array3));\n\n        list3 = new ArrayList<>(Arrays.asList(100, 200));\n        getReference(list3);\n        System.out.printf(\"list3: %s%n\", list3.toString());\n\n        list5 = new ArrayList<>(Arrays.asList(100, 200));\n        getValue(list5);\n        System.out.printf(\"list5: %s%n\", list5.toString());\n\n        /**\n         * DIFICULTAD EXTRA\n         * Crea dos programas que reciban dos parámetros (cada uno)\n         * definidos como variables anteriormente.\n         */\n        // valor\n        arrayC = new int[]{1000, 2000};\n        arrayD = reverseValue(arrayC);\n        System.out.printf(\"arrayC: %s%n\", Arrays.toString(arrayC));\n        System.out.printf(\"arrayD: %s%n\", Arrays.toString(arrayD));\n\n        arrayE = new int[]{3000, 4000};\n        arrayF = reverseValue(arrayE.clone()); //crea una nueva instancia\n        System.out.printf(\"arrayE: %s%n\", Arrays.toString(arrayE));\n        System.out.printf(\"arrayF: %s%n\", Arrays.toString(arrayF));\n\n        listG = new ArrayList<>(Arrays.asList(5000, 6000));\n        listH = new ArrayList<>(Arrays.asList(7000, 8000));\n        List[] listas = reverseReference(listG, listH); //\n        listI = listas[0];\n        listJ = listas[1];\n        System.out.printf(\"listG: %s, listH: %s%n\", listG.toString(), listH.toString());\n        System.out.printf(\"listI: %s, listJ: %s%n\", listI.toString(), listJ.toString());\n\n    }\n\n    private static void getValue(int num) {\n        num = 200;\n        System.out.printf(\"num: %d%n\", num);\n    }\n\n    private static void getValue(int[] array) {\n        array = new int[]{300, 400}; //crea un nuevo objeto\n        System.out.printf(\"array: %s%n\", Arrays.toString(array));\n    }\n\n    private static void getReference(List<Integer> list) {\n        list.add(300); //usando la misma referencia (objeto en memoria)\n        list4 = list;\n        list4.add(400);\n        System.out.printf(\"list: %s%n\", list.toString());\n        System.out.printf(\"list4: %s%n\", list4.toString());\n    }\n\n    private static void getValue(List<Integer> list) {\n        list.add(300); //usando la misma referencia (objeto en memoria)\n        list6 = new ArrayList<>(list); //se crea un nuevo objeto\n        list6.add(400);\n        System.out.printf(\"list: %s%n\", list.toString());\n        System.out.printf(\"list6: %s%n\", list6.toString());\n    }\n\n    private static int[] reverseValue(int[] array) {\n        int temp = array[0];\n        array[0] = array[1];\n        array[1] = temp;\n        return array;\n    }\n\n    private static List[] reverseReference(List list1, List list2) {\n        List temp = list1;\n        list1 = list2;\n        list2 = temp;\n        return new List[]{list1, list2};\n    }\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/java/mensius87.java",
    "content": "import java.util.*;\n\npublic class mensius87 {\n\n    // Asignación de variables por valor\n    static int numero1 = 23;\n    static double numero2 = 3.14;\n    static String color = \"rojo\";\n    static Object[] agenda = {1, \"hola\", numero2};\n\n    // Asignación de variables por referencia\n    static List<String> colores = Arrays.asList(\"rojo\", \"verde\", \"azul\");\n    static Map<String, String> inglesEspanol = new HashMap<>();\n    static {\n        inglesEspanol.put(\"hello\", \"hola\");\n        inglesEspanol.put(\"red\", \"rojo\");\n        inglesEspanol.put(\"green\", \"verde\");\n        inglesEspanol.put(\"blue\", \"azul\");\n    }\n    static Set<Integer> miSet = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5));\n\n    // Ejemplos de funciones con variables de paso por valor\n    static void suma(double num1, double num2) {\n        double resultado = num1 + num2;\n        System.out.println(\"El valor de 'numero1' es \" + num1 + \"+\" + num2 + \" es \" + resultado);\n    }\n\n    static void datosAgenda(Object[] datos) {\n        System.out.println(Arrays.toString(datos));\n    }\n\n    // Ejemplos de funciones con variables de paso por referencia\n    static void imprimirVocabulario(Map<String, String> vocabulario) {\n        for (Map.Entry<String, String> entry : vocabulario.entrySet()) {\n            System.out.println(entry.getKey() + \": \" + entry.getValue());\n        }\n    }\n\n    // Programa principal\n    public static void main(String[] args) {\n        // Ejemplos de funciones con variables de paso por valor\n        suma(numero1, numero2);\n        System.out.println();\n\n        // Ejemplos de funciones con variables de paso por referencia\n        datosAgenda(agenda);\n        System.out.println();\n\n        imprimirVocabulario(inglesEspanol);\n    }\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/java/miguelex.java",
    "content": "public class miguelex {\n\n    static class Persona {\n        private String nombre;\n        private int edad;\n\n        public String getNombre() {\n            return nombre;\n        }\n\n        public void setNombre(String nombre) {\n            this.nombre = nombre;\n        }\n\n        public int getEdad() {\n            return edad;\n        }\n\n        public void setEdad(int edad) {\n            this.edad = edad;\n        }\n    }\n\n    public static int[] intercambioporValor(int a, int b) {\n        int temp = a;\n        a = b;\n        b = temp;\n        return new int[]{a, b};\n    }\n\n    public static void intercambioporReferencia(Persona a, Persona b) {\n        Persona temp = a;\n        a = b;\n        b = temp;\n    }\n\n    public static void main(String[] args) {\n        \n        int a = 10;\n        int b = a;\n\n        System.out.println(\"Variables por valor\");\n        System.out.println(\"a original = \" + a);\n        System.out.println(\"b copia = \" + b);\n        //Cambiamos el valor de una variable y verificamos que no afect\n        a = 20;\n        System.out.println(\"variable a modificada = \" + a);\n        System.out.println(\"variable b = \" + b);\n\n        System.out.println(\"\\n\\nVariables por referencia\");\n        Persona personaOriginal = new Persona();\n        personaOriginal.setNombre(\"Miguel\");\n        personaOriginal.setEdad(48);\n\n        Persona personaCopia = personaOriginal;\n\n        System.out.println(\"persona original = \" + personaOriginal.getNombre() + \" \" + personaOriginal.getEdad());\n        System.out.println(\"persona copia = \" + personaCopia.getNombre() + \" \" + personaCopia.getEdad());\n\n        personaOriginal.setNombre(\"Miguel Angel\");\n        personaOriginal.setEdad(49);\n\n        System.out.println(\"persona original modificada = \" + personaOriginal.getNombre() + \" \" + personaOriginal.getEdad());\n        System.out.println(\"persona copia = \" + personaCopia.getNombre() + \" \" + personaCopia.getEdad());\n\n        System.out.println(\"\\n\\nExtra\");\n\n        a = 5;\n        b = 10;\n\n        System.out.println(\"a = \" + a);\n        System.out.println(\"b = \" + b);\n\n        int[] valores = intercambioporValor(a, b);\n        System.out.println(\"a = \" + a);\n        System.out.println(\"b = \" + b);\n        System.out.println(\"a intercambiada = \" + valores[0]);\n        System.out.println(\"b intercambiada = \" + valores[1]);\n\n        Persona personaA = new Persona();\n        personaA.setNombre(\"Juan\");\n        personaA.setEdad(30);\n\n        Persona personaB = new Persona();\n        personaB.setNombre(\"Pedro\");\n        personaB.setEdad(40);\n    \n        System.out.println(\"personaA = \" + personaA.getNombre() + \" \" + personaA.getEdad());\n        System.out.println(\"personaB = \" + personaB.getNombre() + \" \" + personaB.getEdad());\n\n        intercambioporReferencia(personaA, personaB);\n\n        System.out.println(\"personaA = \" + personaA.getNombre() + \" \" + personaA.getEdad());\n        System.out.println(\"personaB = \" + personaB.getNombre() + \" \" + personaB.getEdad());\n    }\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/java/mtirador.java",
    "content": "import java.util.Arrays;\n\npublic class mtirador {\n    public static void main(String[] args) {\n        \n\n /*ASIGNACIÓN POR VALOR */\n\n    int a= 3;\n    int b=a; //se copia el valor de a en b\n    b=10; //se cambia el valor de b\n    System.out.println(\"a ---> \"+a); //a sigue siendo 3\n    System.out.println(\"b ---> \"+ b);\n\n    /*ASIGNACIÓN POR REFERENCIA */\n    //cuando trabajamos con arreglos  int[] arr2= arr1; lo que hacemos es apuntar a la misma ubicación de memoria,entonces cualquier cambio en arr2 se refleja en arr1\n\n    int[] arr1= {3,6,1};\n    int[] arr2= arr1;\n    System.out.println(\"arr1--> \"+ Arrays.toString(arr1));\n    System.out.println(\"arr2---> \"+ Arrays.toString(arr2));\n    arr2[0] =7;\n    System.out.println(\"arr1--> \"+ Arrays.toString(arr1));\n    System.out.println(\"arr2---> \"+ Arrays.toString(arr2));\n\n\n\n/*Ejercicio extra */\n\n // Intercambio por valor\n    int z = 3;\n    int x = 7;\n\n    int[] nuevosValores = cambioVariables(z, x);\n    int newZ = nuevosValores[0];\n    int newX= nuevosValores[1];\n\n    System.out.println(\"Valores originales: z = \" + z + \", x = \" + x);\n    System.out.println(\"Nuevos valores después del intercambio: nuevo Z = \" + newZ + \", nuevo X = \" + newX);\n\n\n// Intercambio por referencia\n    int[] num1 = {5};\n    int[] num2 = {10};\n    System.out.println(\"Valores originales : num1[0] = \" + num1[0] + \", num2[0] = \" + num2[0]);  \n \n    intercambiarPorReferencia(num1, num2);\n    int newNum1 = num1[0];\n    int newNum2 = num2[0];\n            \n \n    System.out.println(\"Nuevos valores después del intercambio: newNum1 = \" + newNum1 + \", newNum2 = \" + newNum2);\n\n    }//fin main\n\n    static int[] cambioVariables(int a, int b) {\n    int temp = a;\n    a = b;\n    b = temp;\n    return new int[] {a, b};\n    }\n\n \n   static void intercambiarPorReferencia(int[] array1, int[] array2) {\n     int temp = array1[0];\n     array1[0] = array2[0];\n     array2[0] = temp;\n   }\n\n    \n        \n       \n    \n    \n   \n    \n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/java/qv1ko.java",
    "content": "public class Qv1ko {\n\n    public static void main(String[] args) {\n        \n        int a = 3, b = 4;\n        Reference x = new Reference(5), y = new Reference(6);\n\n        int newA = program1(a, b);\n        Reference newX = program2(x, y);\n\n        System.out.println(\"A value: \" + a);\n        System.out.println(\"X value: \" + x.getNum());\n        System.out.println(\"New A value: \" + newA);\n        System.out.println(\"New X value: \" + newX.getNum());\n\n    }\n\n    private static int program1(int a, int b) {\n\n        int temp = a;\n\n        a = b;\n        b = temp;\n\n        return a;\n\n    }\n\n    private static Reference program2(Reference x, Reference y) {\n\n        Reference temp = x;\n\n        x = y;\n        y = temp;\n\n        return x;\n\n    }\n\n}\n\nclass Reference {\n\n    int num;\n\n    Reference(int num) {\n        this.num = num;\n    }\n\n    public int getNum() {\n        return num;\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/java/simonguzman.java",
    "content": "public class simonguzman {\n    public static void main(String[] args) {\n\n        int a = 5;\n        int b = a;\n        int[] array1 = {1, 2, 3};\n        int[] array2 = array1;\n        Coche c = new Coche(5, \"Opel\", \"Astra\", 85, 1200, 14000 );\n        String miCadena = \"Hola: Ejercicio #05\";\n\n        //Asignacion por valor\n        b=10;\n        System.out.println(a);\n        System.out.println(b);\n        modificarNumero(a);\n        System.out.println(a);\n\n        //Asignacion por referencia\n        array2[0] = 10;\n        for (int i = 0; i < array1.length; i++) {\n            System.out.println(array1[i]);\n        }\n        for (int i = 0; i < array2.length; i++) {\n            System.out.println(array2[i]);\n        }\n\n        System.out.println(array1[0]);\n        System.out.println(array2[0]);\n\n        modificarArray(array1);\n        for (int i = 0; i < array1.length; i++) {\n            System.out.println(array1[i]);\n        }\n        for (int i = 0; i < array2.length; i++) {\n            System.out.println(array2[i]);\n        }\n\n        //Objeto por referencia\n\n        System.out.println(c.getNumPuertas());\n        System.out.println(c.getMarca());\n        System.out.println(c.getModelo());\n        System.out.println(c.getNumCaballos());\n        System.out.println(c.getCilindrada());\n        System.out.println(c.getPrecio());\n\n        modificarCoche(c);\n\n        System.out.println(c.getNumPuertas());\n        System.out.println(c.getMarca());\n        System.out.println(c.getModelo());\n        System.out.println(c.getNumCaballos());\n        System.out.println(c.getCilindrada());\n        System.out.println(c.getPrecio());\n\n\n        //Objeto inmutable\n        System.out.println(miCadena);\n        modificarCadena(miCadena);\n        System.out.println(miCadena);\n\n        //Ejercicio adicional\n        //Intercambio por valor\n        int num1 = 0;\n        int num2 = 1;\n        int []arreglo1 = {1,2,3};\n        int []arreglo2 = {4,5,6};\n\n        System.out.println(num1);\n        System.out.println(num2);\n        int[] intercambio = intercambioXValor(num1, num2);\n        for(int i = 0; i < intercambio.length; i++){\n            System.out.println(intercambio[i]);\n        }\n\n        //Intercambio por referencia\n        for (int i = 0; i < arreglo1.length; i++){\n            System.out.print(arreglo1[i]);\n        }\n        for (int i = 0; i < arreglo2.length; i++){\n            System.out.print(arreglo2[i]);\n        }\n        System.out.println();\n        intercambioXReferencia(arreglo1, arreglo2);\n        for (int i = 0; i < arreglo1.length; i++){\n            System.out.print(arreglo1[i]);\n        }\n        for (int i = 0; i < arreglo2.length; i++){\n            System.out.print(arreglo2[i]);\n        }\n    }\n\n        public static int[] intercambioXValor(int num1, int num2){\n            int aux = 0;\n            aux = num1;\n            num1 = num2;\n            num2 = aux;\n            return new int[] {num1,num2};\n        }\n\n    public static void intercambioXReferencia(int[] arreglo1, int[] arreglo2){\n        for (int i = 0; i < arreglo1.length; i++) {\n            int temp = arreglo1[i];\n            arreglo1[i] = arreglo2[i];\n            arreglo2[i] = temp;\n        }\n    }\n    private static void modificarCadena(String miCadena){\n        miCadena = \"Modificacion de un string\";\n    }\n\n    public static void modificarNumero(int num){\n        num = 4;\n    }\n\n    public static void modificarArray(int[] array){\n        array[0] = 0;\n        array[1] = 1;\n        array[2] = 2;\n    }\n\n    public static void modificarCoche(Coche c){\n        c.setNumPuertas(3);\n        c.setMarca(\"Citroen\");\n        c.setModelo(\"C3\");\n        c.setNumCaballos(92);\n        c.setCilindrada(1400);\n        c.setPrecio(17000);\n    }\n\n}\n\n\nclass Coche{\n    private int numPuertas;\n    private String marca;\n    private String modelo;\n    private int numCaballos;\n    private int cilindrada;\n    private double precio;\n\n    public Coche(){\n\n    }\n\n    public Coche(int numPuertas, String marca, String modelo, int numCaballos, int cilindrada, double precio){\n        this.numPuertas = numPuertas;\n        this.marca = marca;\n        this.modelo = modelo;\n        this.numCaballos = numCaballos;\n        this.cilindrada = cilindrada;\n        this.precio = precio;\n    }\n\n    public int getNumPuertas() {\n        return numPuertas;\n    }\n\n    public void setNumPuertas(int numPuertas) {\n        this.numPuertas = numPuertas;\n    }       \n\n    public String getMarca() {\n        return marca;\n    }\n\n    public void setMarca(String marca) {\n        this.marca = marca;\n    }\n\n    public String getModelo() {\n        return modelo;\n    }\n\n    public void setModelo(String modelo) {\n        this.modelo = modelo;\n    }\n\n    public int getNumCaballos() {\n        return numCaballos;\n    }\n    \n    public void setNumCaballos(int numCaballos) {\n        this.numCaballos = numCaballos;\n    }\n\n    public int getCilindrada() {\n        return cilindrada;\n    }\n\n    public void setCilindrada(int cilindrada) {\n        this.cilindrada = cilindrada;\n    }\n\n    public double getPrecio() {\n        return precio;\n    }\n\n    public void setPrecio(double precio) {\n        this.precio = precio;\n    }\n}"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/7R0N1X.js",
    "content": "// Tipos de datos por valor\nlet a = 1\nlet b = 2\nlet c = b\n\n// console.log(a)\n// console.log(b)\n// console.log(c)\n\n\n// Tipos de datos por referencia\nlet d = [1, 2, 3]\nlet e = d\ne.push(4)\n\n// console.log(d)\n// console.log(e)\n\n// Funciones por valor\nfunction f(a) {\n  a = 5\n  console.log(a)\n}\n\n// f(a)\n// console.log(a)\n\n// Funciones por referencia\nfunction g(d) {\n  d.push(20)\n  console.log(d)\n}\n\n// g(d)\n// console.log(d)\n\n\n// Dificultad extra\n\n// Funcion que intercambia dos variables por valor\nfunction myFunc1(a, b) {\n  let aux = a\n  a = b\n  b = aux\n  return { a, b }\n}\n\nlet myVar1 = 1\nlet myVar2 = 2\n\nconsole.log(`Valores originales -> myVar1: ${myVar1}, myVar2: ${myVar2}`)\n\nlet { a: myVar3, b: myVar4 } = myFunc1(myVar1, myVar2)\nconsole.log(`Valores Intercambiados -> myVar3: ${myVar3}, myVar4: ${myVar4}`)\n\n// Funcion que intercambia valores por referencia\nfunction myFunc2(a, b) {\n  let aux = a\n  a = b\n  b = aux\n  return { a, b }\n}\n\nlet myArray1 = [1, 2, 3]\nlet myArray2 = [4, 5, 6]\n\nconsole.log(`Valores originales -> myArray1: ${myArray1}, myArray2: ${myArray2}`)\n\nlet { a: myArray3, b: myArray4 } = myFunc2(myArray1, myArray2)\nconsole.log(`Valores Intercambiados -> myArray3: ${myArray3}, myArray4: ${myArray4}`)\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/AChapeton.js",
    "content": "//Variables por Valor\nvar a = 'Hola Mundo';\nvar b = a; //El valor de \"a\" se asigna a \"b\"\na += '!'; //Se modifica el valor de \"a\"\nconsole.log(\"a\", a);\nconsole.log(\"b\", b);\n\n//Variables por Referencia\n//Con estructuras, no se crea un nuevo valor, sino que ambas variables apuntan a un mismo espacio en memoria\nvar c = [1, 2, 3];\nvar d = c;\nc.push(4);\nconsole.log('c', c);\nconsole.log('d', d);\n\n//Funciones utilizando Variables por Valor\nvar firstFunction = function (str) {\n    str = 'nuevo valor dentro de la funcion';\n    return str;\n};\nvar strOriginal = 'Fuera de la funcion';\nconsole.log('Por valor - Dentro de la funcion: ', firstFunction(strOriginal));\nconsole.log('Por valor - Fuera de la funcion: ', strOriginal);\n\n//Funciones utilizando Varibles por Referencia\nvar secondFunction = function (arr) {\n    arr.push('Moure');\n    return arr;\n};\nvar arrOriginal = ['Andres', 'Brais', 'Chape'];\nconsole.log('Por referencia - Dentro de la funcion: ', secondFunction(arrOriginal));\nconsole.log('Por referencia - Fuera de la funcion: ', arrOriginal);\n\n// EJERCICIO EXTRA\n//Funcion para intercarbiar variables por valor\nvar intercambiarValor = function (num1, num2) {\n    var temp = num1;\n    num1 = num2;\n    num2 = temp;\n    return [num1, num2];\n};\nvar primerValor = 10;\nvar segundoValor = 5;\n\nconsole.group('Valores antes del intercambio');\nconsole.log('primerValor: ', primerValor);\nconsole.log('segundoValor: ', segundoValor);\nconsole.groupEnd();\n\nvar _a = intercambiarValor(primerValor, segundoValor), nuevoPrimerValor = _a[0], nuevoSegundoValor = _a[1];\n\nconsole.group('Valores despues del intercambio');\nconsole.log('primerValor: ', primerValor);\nconsole.log('segundoValor: ', segundoValor);\nconsole.groupEnd();\n\nconsole.group('Nuevos valores intercambiados');\nconsole.log('nuevoPrimerValor: ', nuevoPrimerValor);\nconsole.log('nuevoSegundoValor: ', nuevoSegundoValor);\nconsole.groupEnd();\n\n//Funcion para intercarbiar variables por referencia\nvar intercambiarReferencias = function (user) {\n    var temp = user.mainEmail;\n    user.mainEmail = user.secondEmail;\n    user.secondEmail = temp;\n    return user;\n};\n\nvar usuarioOriginal = {\n    name: 'Andres',\n    mainEmail: 'andres@new.com',\n    secondEmail: 'andres@test.com',\n};\n\nconsole.group('Referencias antes del intercambio');\nconsole.log('usuarioOriginal: ', usuarioOriginal);\nconsole.groupEnd();\n\nvar nuevoUsuario = intercambiarReferencias(usuarioOriginal);\n\nconsole.group('Referencias despues del intercambio');\nconsole.log('usuarioOriginal: ', usuarioOriginal);\nconsole.groupEnd();\n\nconsole.group('Nuevas Referencias intercambiadas');\nconsole.log('nuevoUsuario: ', nuevoUsuario);\nconsole.groupEnd();\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/AndresMCardenas.js",
    "content": "/*\n* EJERCICIO:\n* - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n*   su tipo de dato.\n* - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n*   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n* (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n*\n* DIFICULTAD EXTRA (opcional):\n* Crea dos programas que reciban dos parámetros (cada uno) definidos como\n* variables anteriormente.\n* - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n*   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n*   se asigna a dos variables diferentes a las originales. A continuación, imprime\n*   el valor de las variables originales y las nuevas, comprobando que se ha invertido\n*   su valor en las segundas.\n*   Comprueba también que se ha conservado el valor original en las primeras.\n*/\n\n// Asignación de variables por valor y por referencia\n\nlet a = 5;\nlet b = a; // Asignación por valor\nconsole.log(b); // imprime 5\na = 10;\nconsole.log(a); // imprime 10\nconsole.log(b); // imprime 5\n\nlet c = { nombre: \"Andrés\" };\nlet d = c; // Asignación por referencia (en este caso, se copia la dirección de memoria) y si se modifica c, también se modifica d\nconsole.log(d.nombre); // imprime \"Andrés\"\nc.nombre = \"Juan\";\nconsole.log(c.nombre); // imprime \"Juan\"\nconsole.log(d.nombre); // imprime \"Juan\"\n\n// Funciones con parámetros por valor y por referencia\n\nfunction cambiarValor(a) {\n  a = 20;\n  console.log(a); // imprime 20\n\n}\n\nlet e = 10;\ncambiarValor(e);\nconsole.log(e); // imprime 10 por que se pasó por valor no la referencia\n\nfunction cambiarValorObjeto(c) {\n  c.nombre = \"Pedro\";\n  console.log(c.nombre); // imprime \"Pedro\"\n}\n\nlet f = { nombre: \"Andrés\" };\ncambiarValorObjeto(f);\nconsole.log(f.nombre); // imprime \"Pedro\" por que se pasó por referencia\n\n// DIFICULTAD EXTRA (opcional)\n\nfunction intercambiarValoresPorValor(a, b) {\n  let aux = a;\n  a = b;\n  b = aux;\n  return [a, b];\n}\n\nlet g = 5;\nlet h = 10;\nlet resultado = intercambiarValoresPorValor(g, h);\nconsole.log(g); // imprime 5\nconsole.log(h); // imprime 10\nconsole.log(resultado[0]); // imprime 10\nconsole.log(resultado[1]); // imprime 5\n\nfunction intercambiarValoresPorReferencia(c, d) {\n  let aux = c.nombre;\n  c.nombre = d.nombre;\n  d.nombre = aux;\n  return [c, d];\n}\n\nlet i = { nombre: \"Andrés\" };\nlet j = { nombre: \"Juan\" };\nlet resultado2 = intercambiarValoresPorReferencia(i, j);\nconsole.log(i.nombre); // imprime \"Juan\"\nconsole.log(j.nombre); // imprime \"Andrés\"\nconsole.log(resultado2[0].nombre); // imprime \"Juan\"\nconsole.log(resultado2[1].nombre); // imprime \"Andrés\"\n\n\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/ArticKun.js",
    "content": "\n//* VALOR Y REFERENCIA\n\n/*\n\nVALOR (Value):\n\nCuando asignas un valor primitivo a una variable \n(como un número, una cadena o un booleano), estás manipulando el valor real.\nLa asignación de un valor a otra variable crea una copia independiente de ese valor. \nCambiar la copia no afectará al valor original.\n\n*/\n\nlet a = 5;\nlet b = a;\nb = 10;\n\nconsole.log(a); // Output: 5\nconsole.log(b); // Output: 10\n\n\n/*\n\nREFERENCIA (Reference):\n\nCuando asignas un objeto (incluidos arreglos y funciones) a una variable, \nestás manipulando una referencia al objeto en la memoria, no el objeto en sí mismo.\nAsignar la referencia a otra variable significa que ambas variables apuntan al mismo \nobjeto en la memoria.\n\n*/\n\nlet array1 = [1, 2, 3];\nlet array2 = array1;\narray2.push(4);\n\nconsole.log(array1); // Output: [1, 2, 3, 4]\nconsole.log(array2); // Output: [1, 2, 3, 4]\n\n/*\n\nEn este caso, modificar array2 afecta a array1 porque ambas comparten la misma \nreferencia al objeto en la memoria.\n\n*/\n\n//* TIPOS DE DATOS POR VALOR\n\n//Number\nlet num1 = 10;\nlet num2 = num1;\nnum2 = 20;\n\nconsole.log(num1); // Output: 10\nconsole.log(num2); // Output: 20\n\n//String\nlet str1 = \"Hola\";\nlet str2 = str1;\nstr2 = \"Adiós\";\n\nconsole.log(str1); // Output: Hola\nconsole.log(str2); // Output: Adiós\n\n//Boolean\nlet bool1 = true;\nlet bool2 = bool1;\nbool2 = false;\n\nconsole.log(bool1); // Output: true\nconsole.log(bool2); // Output: false\n\n//Undefined\nlet undefinedValue = undefined;\nlet anotherUndefined = undefinedValue;\n\nconsole.log(undefinedValue);   // Output: undefined\nconsole.log(anotherUndefined); // Output: undefined\n\n//Null\nlet nullValue = null;\nlet anotherNull = nullValue;\n\nconsole.log(nullValue);   // Output: null\nconsole.log(anotherNull); // Output: null\n\n\n//* TIPOS DE DATOS POR REFERENCIA\n\n//Objeto\nlet obj1 = { key: 'value' };\nlet obj2 = obj1;\nobj2.key = 'new value';\n\nconsole.log(obj1.key); // Output: new value\nconsole.log(obj2.key); // Output: new value\n\n//Array\nlet arr1 = [1, 2, 3];\nlet arr2 = arr1;\narr2.push(4);\n\nconsole.log(arr1); // Output: [1, 2, 3, 4]\nconsole.log(arr2); // Output: [1, 2, 3, 4]\n\n//Funciones\nfunction greet(name) {\n    return `Hello, ${name}!`;\n}\n\nlet greetFunction1 = greet;\nlet greetFunction2 = greetFunction1;\n\nconsole.log(greetFunction1('Alice')); // Output: Hello, Alice!\nconsole.log(greetFunction2('Bob'));   // Output: Hello, Bob!\n\n\n//* EJEMPLOS DE FUNCIONES POR VALOR\n\n//Numero\nfunction modifyNumber(value) {\n    console.log( value = 20 );\n}\n\nlet num = 10;\n\nmodifyNumber(num);  // Output: 20\n\nconsole.log( num ); // Output: 10\n\n/*\nEn este ejemplo, el valor de num no cambia aun después de llamar \na la función modifyNumber, ya que los números se pasan \"por valor\".\nosea se creo una copia de num\n*/\n\n//String\nfunction modifyString(value) {\n    console.log( value = \"Adiós\" );;\n}\n\nlet str = \"Hola\";\n\nmodifyString(str);// Output: Adiós\n\nconsole.log(str); // Output: Hola\n\n/*\nSimilar al caso anterior, el valor de str no se modifica después de llamar \na la función modifyString.\n*/\n\n//*EJEMPLOS DE FUNCIONES POR REFERENCIA\n\n//Objeto\nfunction modifyObject(obj) {\n    obj.key = 'new value';\n}\n\nlet obj = { key: 'value' };\n\nconsole.log( obj.key ); // Output: value\n\nmodifyObject(obj);\n\nconsole.log( obj.key ); // Output: new value\n\n/*\nEn este caso, la función modifyObject modifica directamente la propiedad \ndel objeto, y este cambio se refleja fuera de la función.\n*/\n\n\n//Array\nfunction modifyArray(arr) {\n    arr.push(4);\n}\n\nlet arr = [1, 2, 3];\n\nconsole.log( arr ); // Output: [1, 2, 3]\n\nmodifyArray(arr);\n\nconsole.log( arr ); // Output: [1, 2, 3, 4]\n\n/*\nAl igual que con el objeto, la función modifyArray modifica el arreglo \ndirectamente, y este cambio afecta al arreglo fuera de la función.\n*/\n\n//*  DIFICULTAD EXTRA (opcional):\n/*\nCrea dos programas que reciban dos parámetros (cada uno) definidos como \nvariables anteriormente.\n\nCada programa recibe, en un caso, dos parámetros por valor, \ny en otro caso, por referencia.\n\nEstos parámetros los intercambia entre ellos en su interior, \nlos retorna, y su retorno se asigna a dos variables diferentes a las originales. \n\nA continuación, imprime el valor de las variables originales y las nuevas, \ncomprobando que se ha invertido su valor en las segundas.\n\nComprueba también que se ha conservado el valor original en las primeras.\n\n*/\n\n// PROGRAMA 1 con Strings ( por referencia )\nlet value1 = 'Hola';\nlet value2 = 'Mundo';\n\nlet programa1 = ( param1,param2 ) => {\n    let invert1 = param2;\n    let invert2 = param1;\n    return [invert1, invert2 ='Soy ArticKun'];\n};\n\n// Obtener los nuevos valores y asignarlos a variables diferentes\nlet [newValue1, newValue2] = programa1(value1, value2);\n\nconsole.log(\"Originales:\", value1, value2);   // 'Hola Mundo\nconsole.log(\"Nuevos:\", newValue1, newValue2); // Mundo soy ArticKun\n\n\n// PROGRAMA 2 con Arrays( por referencia )\nlet arreglo1 = ['Iron Man','Hulk','Thor'];\nlet arreglo2 = ['Spidey','Cap','Ant Man'];\n\nlet programa2 = ( param1,param2 ) =>{\n    let invert1 = param2;\n    let invert2 = param1;\n    return[invert1, invert2];\n};\n\nlet [newArr1, newArr2] = programa2(arreglo1, arreglo2);\n\nconsole.log(\"Originales:\", arreglo1, arreglo2);\nconsole.log(\"Nuevos:\", newArr1, newArr2);\n\n\n// PROGRAMA 2 con objetos ( por referencia )\nlet objeto1 = { nombre: 'Iron Man', poder: 'Tecnología avanzada' };\nlet objeto2 = { nombre: 'Hulk', poder: 'Fuerza sobrehumana' };\n\nlet programa2Objetos = (param1, param2) => {\n    [param1.nombre, param2.nombre] = [param2.nombre, param1.nombre];\n    [param1.poder, param2.poder] = [param2.poder, param1.poder];\n};\n\nconsole.log(\"Originales:\", objeto1, objeto2);\nprograma2Objetos(objeto1, objeto2);\nconsole.log(\"Nuevos:\", objeto1, objeto2);\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/CaveroBrandon.js",
    "content": "/*\n EJERCICIO:\n- Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\nsu tipo de dato.\n- Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n\"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n(Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n*/\n\n// Assigning a value by value\nlet currentYear = 2025;\nconsole.log('Assigned by value: ' + currentYear);\n\n// Assigning a value by reference\nlet animals = ['lion', 'fish', 'dog'];\nconsole.log('Assigned by value: ' + animals);\nlet animalsArrayCopy = animals;\nconsole.log('Assigned by reference: ' + animalsArrayCopy);\n\n// Changing the first array assigned by value\nanimals.push('cat');\nconsole.log('Assigned by value after change: ' + animals);\n// The array assigned by reference is also updated\nconsole.log('Assigned by reference after change: ' + animalsArrayCopy);\n\n\n/*\n* DIFICULTAD EXTRA (opcional):\nCrea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n- Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\nEstos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\nse asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\nvariables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\nComprueba también que se ha conservado el valor original en las primeras.\n*/\n\n// Receives two values and assign them by value\nfunction firstProgram(first, second) {\n    let aux = first;\n    first = second;\n    second = aux;\n    return [first, second];\n}\nfunction secondProgram(first, second) {\n    first = vegetables;\n    second = fruits;\n    return [first, second];\n}\n\nconsole.log('---------------------------------');\nconst a = 1;\nconst b = 2;\nconsole.log('Variables before executing first method');\nconsole.log('firstVariable = ' + a + ', secondVariable = ' + b);\nconsole.log('Variables after executing first method');\nlet [firstValue, secondValue] = firstProgram(a, b);\nconsole.log('firstVariable = ' + firstValue + ', secondVariable = ' + secondValue);\n\nconsole.log('---------------------------------');\nlet fruits = ['apple', 'banana', 'grape'];\nlet vegetables = ['tomato', 'carrot', 'radish'];\nconsole.log('Variables before executing second method');\nconsole.log('firstVariable = ' + fruits + ', secondVariable = ' + vegetables);\nconsole.log('Variables before executing second method');\nlet [firstArray, secondArray] = secondProgram(fruits, vegetables);\nconsole.log('firstVariable = ' + firstArray + ', secondVariable = ' + secondArray);\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/CesarCarmona30.js",
    "content": "/**\n * EJERCICIO\n */\n\n// Datos por valor\nlet valueX = 5;\nlet valueY = valueX;\nvalueY += 15;\n\nconsole.log(valueX);\nconsole.log(valueY);\n\n// Datos por referencia\nlet objectA = {\n  valueX: 8,\n  valueY: 2\n}\n\nlet objectB = objectA;\n\nobjectA.valueX = 20;\nobjectA.valueY = 15;\n\nconsole.table(objectA);\nconsole.table(objectB);\n\n// Función con dato por valor\nfunction modifyValue(valueA) {\n  valueA = 'Valor modificado';\n  console.log(valueA);\n}\n\nlet valueB = 'Valor inicial';\nconsole.log(valueB);\nmodifyValue(valueB);\nconsole.log(valueB);\n\n// Función con dato por referencia\nfunction modifyReference(objectA) {\n  objectA.dato = 'dato modificado';\n  console.log(objectA);\n}\n\nlet objectX = {\n  dato: 'dato inicial',\n}\n\nconsole.log(objectX);\nmodifyReference(objectX);\nconsole.log(objectX);\n\n/**\n * EXTRA\n */\n\n// Valor\n\nfunction replaceValue(valueX, valueY) {\n  let aux = valueX;\n  valueX = valueY;\n  valueY = aux;\n  return [valueX, valueY]\n}\n\nlet name = \"César\";\nlet surname = \"Carmona\";\nlet [nameRep, surnameRep] = replaceValue(name, surname);\n\nconsole.log(`Nombre: ${name}, Apellido: ${surname}`);\nconsole.log(`Nombre reemplazado: ${nameRep}, Apellido reemplazado: ${surnameRep}`);\n\n// Referencia\n\nfunction replaceReference(referenceX, referenceY) {\n  let aux = referenceX;\n  referenceX = referenceY;\n  referenceY = aux;\n  return [referenceX, referenceY];\n}\n\nlet fruits = ['apple', 'orange', 'banana', 'grape'];\nlet vegetables = ['tomato', 'carrot', 'onion', 'radish'];\n\nlet [fruitsRep, vegetablesRep] = replaceReference(fruits, vegetables);\nconsole.log(`Vegetales: ${vegetables}`);\nconsole.log(`Frutas: ${fruits}`);\nconsole.log(`Vegetales reemplazados: ${vegetablesRep}`);\nconsole.log(`Frutas reemplazados: ${fruitsRep}`);"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/Dan-Corbo.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\n\n/* Soluciones */\n\n\n// Primitivos\nlet numero1 = 10;\nlet numero2 = numero1; // Se copia el valor de numero1 a numero2\n\nnumero1 = 20; // Modificar numero1 no afecta a numero2\n\nconsole.log(numero1); // 20\nconsole.log(numero2); // 10\n\n// String\nlet nombre1 = \"Ana\";\nlet nombre2 = nombre1; // Se copia el valor de nombre1 a nombre2\n\nnombre1 = \"María\"; // Modificar nombre1 no afecta a nombre2\n\nconsole.log(nombre1); // María\nconsole.log(nombre2); // Ana\n\n\n// Objetos\nlet persona1 = { nombre: \"Ana\", edad: 30 };\nlet persona2 = persona1; // Se asigna la referencia al mismo objeto\n\npersona1.nombre = \"María\"; // Modificar persona1 afecta a persona2\n\nconsole.log(persona1); // { nombre: \"María\", edad: 30 }\nconsole.log(persona2); // { nombre: \"María\", edad: 30 }\n\n// Arrays\nlet numeros1 = [1, 2, 3];\nlet numeros2 = numeros1; // Se asigna la referencia al mismo array\n\nnumeros1[0] = 4; // Modificar numeros1 afecta a numeros2\n\nconsole.log(numeros1); // [4, 2, 3]\nconsole.log(numeros2); // [4, 2, 3]\n\n\n/* Extra - Opcional */\n\n\nlet apellido = \"Benzatto\";\n\nlet apellido1 = \"Corbo\";\n\n\nfunction intercambio1(param1, param2) {\n    let apellido3 = param1;\n    let apellido2 = param2;\n\n    return { apellido2, apellido3 };\n}\n\nlet resultado = intercambio1(apellido, apellido1);\n\nlet { apellido2, apellido3 } = resultado;\n\n    // Las variables originales no se modifican\n    console.log(apellido); // Valor original\n    console.log(apellido1); // Valor original\n    console.log(apellido2); // \"Corbo\"\n    console.log(apellido3); // \"Benzatto\"\n\n\n    let fruta1 = { nombre: \"Manzana\", color: \"Rojo\" };\n\n    let fruta2 = { nombre: \"Pera\", color: \"Amarillo\" };\n\n\nfunction intercambio2(param1, param2) {\n    let fruta3 = param2;\n    let fruta4 = param1;\n    \n    return { fruta3, fruta4 };\n}\n\nlet resultado1 = intercambio2(fruta1, fruta2);\n\nlet { fruta3, fruta4 } = resultado1;\n\n    // Las variables originales no se modifican\n    console.log(fruta1); // Valor original\n    console.log(fruta2); // Valor original\n    console.log(fruta3); // \"Pera\"\n    console.log(fruta4); // \"Manzana\""
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/DannyMarperOne.js",
    "content": "/* Dificultad: Fácil | Publicación: 29/01/24 | Corrección: 05/02/24\nEjercicio */\n\n/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y\n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\n\n\n// ASIGNACIÓN VARIABLES \"POR VALOR\"\n\n/* \nEsto aplica con tipos de datos primitivos: String, Number, Null, Boolean, Undefined (Revisar: BigInt y Symbol)\n\nEste tipo de asignación basicamente cuando se crea una variable \"a\" y se le asigna valor x, depués se crea una \nvariable \"b\" y se le asigna la variable \"a\", practicamente se está haciendo una copia de la variable \"a\", \npara asignarsela a \"b\".\n\nLa variable \"a\" está en un espacio de memoria y la variable \"b\" está en otro espacio de memoria, por ello es que aunque \ndespués se cambie el valor de la variable \"a\" por z, el valor que está en la variable \"b\" seguirá siendo el mismo que ya \ntenia asignado una copia (x). \n*/\n\n//POR VALOR\nlet var1 = \"México\";\nlet var2 = \"España\";\nconsole.log(var1); // México\nconsole.log(var2); // España\n\nlet var3 = var1; //var3 ahora se le asignó una \"copia\" del valor de la var1 entonces var3 = \"México\"\n\nconsole.log(var3 == var1)\n/* Resultado true, porque a pesar de que están en distintos espacios de memoria, tienen el mismo valor con el mismo \ntipo de dato. Ya que los datos primitivos se asignan \"por valor\".\n*/\nvar3 = \"Francia\"; //var3 ahora se le asignó un nuevo valor, ahora var3 = \"Francia\"\nconsole.log(var3);\nconsole.log(var1); //var1 sigue valiendo \"México\".\n\n\n\n//ASIGNACIÓN DE VARIABLES \"POR REFERENCIA\"\n\n/* \nEsto aplica con tipos de datos compuestos: Object (Objects, Functions, Arrays, Set, Etc...)\n\nBasicamente cuando se crea un arreglo o un objeto con ciertos valores como nombre: Daniel y edad: 27 y se asigna a \nuna variable.\n\nPor ejemplo obj1, como tal obj1 no tiene asignados lo valores nombre y edad, lo que tienen asignado literalmente es la\ndirección en memoria donde se encuentran esos datos.\nAhora si se crea otra variable como obj2, a la cual se le asigna la variable obj1 (let obj2 = obj1), entonces en este caso \nno se hace una copia de los valores dentro del objeto, se hace una copia de la dirección en memoria donde se encuentran\nlos valores. Así que en dado caso en el que se cambie algun valor del objeto obj1, este tambien se verá reflejado en obj2.\n\nEsto es porque no se copia directamente el valor sino la dirección en memoria donde se encuentran los valores.\n*/\n\n//EJEMPLO\nlet arr = [\"Daniel\", \"Gustavo\", \"Jannet\"];\nlet arr2 = arr;\n\narr2.push(\"Daneri\");\n\nconsole.log(arr);\nconsole.log(arr2);\n\nlet arr3 = arr2;\narr3.push(\"Zulema\")\n\nconsole.log(\"arr3\");\nconsole.log(arr3);\n\nconsole.log(\"arr\");\nconsole.log(arr);\n\nconsole.log(\"arr2\");\nconsole.log(arr2);\n\n//EJEMPLO\nlet obj1 = {\n    nombre: \"Daniel\",\n    edad: 27\n}\nconsole.log(obj1);\n\nlet obj3 = obj1;\nconsole.log(obj3);\n\nobj3.nombre = \"Alejandra\";\nconsole.log(obj3);\nconsole.log(obj1);\nconsole.log(obj1 == obj3);\n//Resultado true, porque las dos variables apuntan a la misma dirección en memoria (espacio en memoria).\n\n\nlet obj2 = {\n    nombre: \"Daniel\",\n    edad: 27\n}\nconsole.log(obj2 == obj1);\n/* Resultado false, porque a pesar de tener los mismos valores, estos están en distintas direcciones en memoria \n(espacios de memoria).\n\nLos objetos compuestos se asignan \"por referencia\", unicamente son iguales cuando se encuentran en el mismo \nespacio de memoria ya que comparten los mismo valores\n*/\n\n\n\n\n//FUNCIONES CON ASIGNACIÓN POR VALOR Y POR REFERENCIA.\n\n//FUNCION POR VALOR\n\n/* \nCuando pasamos valores primitivos a una función, ésta copia los valores en sus parámetros. \nEs efectivamente lo mismo que usar =\n\nTodas las operaciones que se realizan dentro de la función con las copias de los valores de esas variables\nno afecta en nada los valores que se encuentran fuera de la función.\n*/\n\nlet num1 = 50, num2 = 34;\n\nfunction sumar(x, y) {\n    console.log(\"Suma de los parametros antes de cambiar su valor dentro de la función \" + (x + y)); //84\n    x = 20;\n    y = 30;\n    return x + y;\n}\nconsole.log(`Suma de los parametros dentro de la función ${sumar(num1, num2)}`); //50\nconsole.log(`Suma de variable fuera de la función ${num1 + num2}`); //84\n\n/* Como se ve en el ejemplo, la variables fuera de la función no se ven afectadas ya que x & y hacen una copia de los valores\nque tienen num1 y num2. */\n\n\n\n// FUNCION REFERENCIA\n\n/* \nCuando pasamos valores compuestos a una función, de la misma forma solo se hace una copia de la dirección en memoria de\ndonde se encuentran los valores reales.\n\nTodas las operaciones que se realizan dentro de la función con las variables o parametros que contengan \nlas copias de la dirección de referencia, se veran afectadas dentro y fuera de la función. \n\nEsto se puede evitar realizando cierta operación para evitar que los objetos modificados dentro de la función\nno afecten a los objetos fuera de esta. Y esto se logra haciendo una copia legitima del objeto en cuestion.\n*/\n\n//FUNCION REFERENCIA NORMAL\nlet array = [\"Daniel\", \"Gustavo\", \"Jannet\"];\nfunction reff() {\n    let array2 = array;\n    array2.push(\"Rosalí\");\n    return array2;\n}\nconsole.log(reff()); //[ 'Daniel', 'Gustavo', 'Jannet', 'Rosalí' ]\nconsole.log(array); //[ 'Daniel', 'Gustavo', 'Jannet', 'Rosalí' ]\n\n\n//Ejemplo por referencia\nfunction cambiaLaEdadYLaReferencia(persona) {\n    persona.edad = 25;\n    persona = {\n        nombre: 'John',\n        edad: 50\n    };\n    return persona;\n}\nlet persona1 = {\n    nombre: 'Claudia',\n    edad: 31\n};\nlet persona2 = cambiaLaEdadYLaReferencia(persona1);\nconsole.log(persona1); // -> ?  \nconsole.log(persona2); // -> ?\n\n\n//Ejemplo copia de objeto:\nlet arreglo = [\"HTML\", \"CSS\", \"JAVASCRIPT\"];\nfunction lenguaje(dev) {\n    //Convertimos el objeto en cadena y despues en objeto nuevamente para hacer una copia del objeto completo\n    let nuevaPersona = JSON.parse(JSON.stringify(dev));\n    nuevaPersona.push(\"PHP\");\n    console.log(nuevaPersona);\n    //De esta forma cuando se modifica el nuevo objeto dentro de la función, no afecta al objeto fuera de la misma\n}\nlenguaje(arreglo); //[ 'HTML', 'CSS', 'JAVASCRIPT', 'PHP' ]\nconsole.log(arreglo);//[ 'HTML', 'CSS', 'JAVASCRIPT'\n\n/* \n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   \n * \n * Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\nlet nombre = \"Daniel\";\nlet apellido = \"Martínez\";\n\nfunction progValor(nombre, apellido) {\n    let extra = nombre\n    nombre = apellido\n    apellido = extra\n    return nombre + \" \" + apellido;\n}\nconsole.log(progValor(nombre, apellido));\nconsole.log(nombre, apellido);\n\n/* \nNOTA: El concepto de paso por referencia en JavaScript es consistente tanto dentro como fuera de las funciones. \nSiempre se manejan referencias a objetos, no copias de los objetos en sí. Las asignaciones dentro de una \nfunción solo afectan a las variables locales a menos que se modifiquen directamente los objetos referenciados \n(como agregar elementos a un array, por ejemplo).\n*/\n\n\nlet listaNombre = [\"Jim\", \"Pam\", \"Dwigth\"];\nlet listName = [\"Manuel\", \"Fidencio\", \"Jose\"];\n\nfunction progReferencia(listaNombre, listaName) {\n    let extra = listaNombre;\n    listaNombre = listName;\n    listaName = extra;\n    return [listaNombre, listaName];\n}\nconsole.log(progReferencia(listaNombre, listName));\nconsole.log(listaNombre, listName);\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/DavidMoralesDeveloper.js",
    "content": "\n\n\n//valor\n let persona1 = 'Jose'\n let persona2 = persona1\n persona1 = 'Pedro'\n//  console.log(persona2) // => Jose\n//  console.log(persona1)  // => Pedro\n\n //referencia\n\n  let personas1 = ['Pedro','Jose','Teresa']\n  let personas2 = personas1\n personas1.push('Diego')\n//  console.log(personas1) // ['Pedro','Jose','Teresa','Diego']\n//  console.log(personas2) // ['Pedro','Jose','Teresa','Diego']\n\n //funciones \n\nlet variablePorValor = 10\n\n function myfunctionValor ( variable) {\n\n    variable =20\n    // return console.log(variable)\n\n }\n\n myfunctionValor(variablePorValor)\n//  console.log(variablePorValor)\n\n //funciones por referencia\n\n let valorPorReferencia = [1, 2, 3]\n\n function myFunctionReferencia ( referencia ) {\n\n    referencia.push(6)\n    // console.log( referencia)\n\n    let valorPorRef2= referencia\n    valorPorRef2.push(9)\n    // console.log(valorPorRef2)\n\n }\n\n myFunctionReferencia(valorPorReferencia)\n//  console.log(valorPorReferencia)\n\n\n //extra \n\n//  Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n//  * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n//  *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n//  *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n//  *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n//  *   Comprueba también que se ha conservado el valor original en las primeras.\n\nlet valor1 = 10\nlet valor2 = 20\n\n// programa1\nfunction programa1 (parametro1, parametro2) {\n    let axu =parametro1\n    parametro1 = parametro2\n    parametro2 = axu\n    return [parametro1, parametro2]\n\n}\n//desestructuracion de un array\nlet [nuevoValo1, nuevoValo2] = programa1(valor1, valor2)\n\nconsole.log(valor1+ 'valor orginal ', + valor2 + 'valor original')\n// 10 - 20\nconsole.log(nuevoValo1 + 'valor invertido ' + nuevoValo2 + 'valor invertido' ) \n// 20 - 10\n\n\n\nlet referencia1 = [1, 2, 3]\nlet referencia2 = [11, 12, 30]\n\n// programa2\nfunction programa2 (parametro11, parametro22) {\n\n    parametro11 = referencia2\n    parametro22 = referencia1\n\n    return [parametro11, parametro22]\n}\n\nlet [nuevaReferencia1, nuevaReferencia2] = programa2(referencia1, referencia2)\n\nconsole.log(`${referencia1} valor origina - ${referencia2} valor original `)\n// 1,2,3 valor origina - 11,12,30 valor original\nconsole.log(`${nuevaReferencia1} valor invertido - ${nuevaReferencia2} valor ivertido `)\n// 11,12,30 valor invertido - 1,2,3 valor ibertido"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/Deyvid-10.js",
    "content": "//  Ejemplos de asignación de variables \"por valor\" y \"por referencia\"\n\n// Por valor\nlet numero = 1\nlet numero2 = numero\nlet cadena = \"texto\"\nlet cadena2 = cadena\n\nnumero2 = 2\ncadena2 = \"palabra\"\n\nconsole.log(numero);\nconsole.log(numero2);\nconsole.log(cadena);\nconsole.log(cadena2);\n\n// Por referencia\nlet array = [1, 2, 3]\nlet array2 = array\nlet objeto = {a: 1, b:2, c:3}\nlet objeto2 = objeto\n\narray2.push(4)\nobjeto2[\"d\"] = 4\n\nconsole.log(array);\nconsole.log(array2);\nconsole.log(objeto);\nconsole.log(objeto2);\n\n// Funcion por valor \nlet numero3 = 3\n\nfunction porValor()\n{\n    let numero4 = numero3\n    numero4 = 4\n    console.log(numero4);\n}\n\nporValor()\nconsole.log(numero3);\n\n// Funcion por referencia\nlet array3 = [1, 2, 3]\nfunction porReferencia()\n{\n    let array4 = array3\n    array4.push(4)\n    console.log(array4);\n}\n\nporReferencia()\nconsole.log(array3);\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/DjSurgeon.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como\n * variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime\n *   el valor de las variables originales y las nuevas, comprobando que se ha invertido\n *   su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\n/* \nCuando hablamos de pasar una variable por valor y por referencia en JavaScript nos referimos a pasar una variable usando un valor primitivo o un valor no primitivo. Entonces, pasar una variable por valor se refiere a asignarle uno de los siete elementos con valores primitivos de JavaScript. Por su parte, pasar una variable por referencia quiere decir que estamos asignándole un elemento con un valor no primitivo, sea un objeto, un array o una función.\nLa diferencia entre pasar una variable por valor y por referencia en JavaScript es su relación con lo que sucede dentro y fuera de la función. Cuando pasamos una reference variable javascript, lo que «ocurre» dentro de la función «repercute» fuera de ella. Mientras tanto, cuando pasamos una variable por valor, lo que «ocurre» dentro de la función, «se queda» en la función, sin alterar el resto del código.\n*/\n\n// Pasamos por valor, con valores primitivos\n\nlet num1 = 15;\nlet arr1 = [1,2,3,4];\n\nfunction pasoValor(num) {\n  console.log(`Dentro de la función ${num} es ${num * 2}`);\n}\n\npasoValor(num1);\nconsole.log(`Fuera de la función es: ${num1} el valor original no se modifica.`);\n\nfunction pasoReferencia(arr) {\n  arr.push(5);\n  console.log(`Dentro de la función ${arr}`);\n}\n\nconsole.log(`Antes de pasarlo ${arr1} por la función.`)\npasoReferencia(arr1);\nconsole.log(`Fuera de la función ${arr1} el valor original se ha modificado.`);\n\n// Extra =================\n\nlet num2 = 10;\nlet num3 = 20;\n\nlet arr2 = [0,1,2];\nlet arr3 = [\"Sergio\", \"Vero\"];\n\nfunction pasoPorValor(num1, num2){\n  let numA = num1;\n  num2 = num1;\n  num2 = numA;\n  return[num1, num2];\n\n}\nconsole.log(\"Valores despues de la función por valor\");\nconsole.log(pasoPorValor(num2, num3));\nconsole.log(\"Valores originales:\")\nconsole.log(num2, num3);\n\nfunction pasoPorReferencia(arr1, arr2){\n  let arrA = arr1;\n  arr2 = arr1;\n  arr2 = arrA;\n  return arrA;\n}\n\nconsole.log(\"Valores despues de la función por referencia\");\nconsole.log(pasoPorReferencia(arr2, arr3));\nconsole.log(\"Valores originales:\")\nconsole.log(arr2, arr3);\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/DobleDJ.js",
    "content": "/** #05 - javaScript VALOR Y REFERENCIA\n * Date: 03/01/2025\n * Author: Yoandy Doble Herrera\n */\n\n/*\nEJERCICIO:\n- Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\" según su tipo de dato.\n- Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas. (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n\nDIFICULTAD EXTRA (opcional):\nCrea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n- Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\nEstos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\nComprueba también que se ha conservado el valor original en las primeras.\n*/\n\n/* Asignación por valor */\nlet usuario = \"codebydoble\"\nconst distancia = 10000\nlet userCopy = \"@\" + usuario\n\nconsole.log(usuario)\nconsole.log(distancia)\nconsole.log(userCopy)\n\n/* Asignación de variables por referencia */\n\nconst librosTech = [\"De 0 a Experto\", \"Github ++\", \"100 Horas de código\", \"Javascript Eloquent\"]\nconst personalBook = librosTech\n\nlibrosTech.push(\"Mouredev la guía definitiva\") // se actualiza en ambos array\nconsole.log(librosTech)\nconsole.log(personalBook)\n\n/* Funciones con valores primitivos */\n\n/**\n * Simula un juego\n * @param {number} participantes Númeto total de participantes en el juego\n * @returns Retorna la cantidad de participantes\n */\nconst game = (participantes) => {\n  participantes = 100\n  return `El juego cuenta con: ${participantes} atletas`\n}\n\nlet atletas = 200\nconsole.log(game(atletas)) //Le juego cuenta con 100 atletas\nconsole.log(atletas) //200\n\n/* Funciones con valores no primitivos */\n\n/**\n * Lista de series de TV\n * @param {Array} arr Array lista de series de TV\n * @returns Retorna la lista de series televisivas\n */\nconst seriesTV = (arr) => {\n  const arrCopy = [...arr]\n  const results = []\n  for (let index = 0; index < arrCopy.length; index++) {\n    results.push(arrCopy.shift())\n  }\n  return results\n}\nconst misSeries = [\"X Files\", \"24 Hours\", \"La que se avecina\", \"Bleach\", \"Big Bang Theory\"]\nseriesTV(misSeries)\nconsole.log(misSeries) // [\"X Files\", \"24 Hours\", \"La que se avecina\", \"Bleach\", \"Big Bang Theory\"]\n\n/* DIFICULTAD EXTRA */\n/**\n * DIFICULTAD EXTRA (opcional):\nCrea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n- Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\nEstos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\nComprueba también que se ha conservado el valor original en las primeras.\n*/\n\n// Función con dos parámetros por valor\n/**\n * Intercambia dos valores\n * @param {number} paramOne Any number\n * @param {number} paramTwo Any number\n * @returns Retorna un array con los valores intercambiados\n */\nfunction programOne(paramOne, paramTwo) {\n  let temp = paramOne\n  paramOne = paramTwo\n  paramTwo = temp\n  return [paramOne, paramTwo]\n}\n\nlet paramOne = 10\nlet paramTwo = 20\n\nlet switchOne\nlet switchTwo\n;[switchOne, switchTwo] = programOne(paramOne, paramTwo)\n\nconsole.log(`Parámetros iniciales: Primer valor ${paramOne}, Segundo Valor ${paramTwo}`)\n\nconsole.log(`Parámetros intercambiados: Primer valor ${switchOne}, Segundo Valor ${switchTwo}`)\n\n// Función con dos parámetros por referencia\nfunction programTwo(arrOne, arrTwo) {\n  const temp = arrOne\n  arrOne = arrTwo\n  arrTwo = temp\n  return { arrOne, arrTwo }\n}\n\nconst laptop = [\"Apple\", \"Dell\", \"HP\", \"Lenovo\", \"Asus\"]\nconst phone = [\"Samsung\", \"Apple\", \"Xiaomi\", \"OnePlus\", \"Huawei\"]\n\nlet { arrOne: firstArr, arrTwo: secondArr } = programTwo(laptop, phone)\nconsole.log(`Parámetros iniciales -> uno: ${laptop}, dos: ${phone}`)\nconsole.log(`Parámetros Intercambiados -> uno: ${firstArr}, dos: ${secondArr}`)\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/FabianRpv.js",
    "content": "// Valor y Referencia\n\n// Asignación por valor\n\nlet a = 10;\nlet b = a;\n\nb = 30;\n\nconsole.log({ a, b }); // No se modifica el valor de a\n\n\n// Funcion que recibe un variable por valor\n\nconst cambiarValor = a => {\n    a = 20;\n    console.log({ a });\n}\n\nlet c = 10;\ncambiarValor(c);\n\nconsole.log({ c }); // No se modifica el valor de c\n\n\n\n\n// Asignación por referencia\n\nlet persona = { nombre: 'Fabian' };\nlet persona2 = persona;\n\npersona2.nombre = 'Juan';\n\nconsole.log({ persona, persona2 }); // Se modifica el valor de persona\n\n\n// Funcion que recibe una variable por referencia\n\nconst cambiarValorObjeto = (objeto) => {\n    objeto.nombre = 'Juan';\n    console.log({ objeto });\n}\n\nlet personaa = { nombre: 'Fabian' };\ncambiarValorObjeto(personaa);\n\nconsole.log({ personaa }); // Se modifica el valor de persona"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/Facundo-Muoio.js",
    "content": "// Ejemplos de asignación por valor, todos los valores primitivos se pasan por valor\nlet number = 1;\nlet str = \"Hola Mundo!\";\nlet boolean = true;\nlet undf = undefined;\nlet nullish = null;\nlet bigInt = BigInt(13);\nlet symbol = Symbol(\"symbol\");\n\n// Ejemplos de asignación por referencia, todos los valores que no son primitivos se pasan por referencia\nlet arr = [1, 2, 3, 4];\nlet obj = { nombre: \"Facundo\", apellid: \"Muoio\" };\nlet sum = function (a, b) {\n\treturn a + b;\n};\n\n// Ejemplo de una funcion con variables pasados por valor y referencia\n// En el primer caso tomamos number que se pasa como valor por lo cual esta funcion es pura y no moficia ninguna variables del ambito externo u global. Como se visualiza en el console.log tendremos numXTwo = 2 y number continuara siendo 1 por mas que lo copiemos en la varable numXTWO\n\nfunction multiply() {\n\tnumXTwo = number;\n\treturn (numXTwo *= 2);\n}\n\nconsole.log(multiply(), number);\n\n// En este segundo caso modificaremos el arr que hemso declaro y notaremos que al pasarse por referencia cuando hagamos una copia del array\n// dentro de la función y la modifiquemos los cambios seran visibles tanto en el array original como en la copia, ya que referencian al mismo\n//objeto\n\nfunction changeArray() {\n\tconst arrayCopy = arr;\n\tarrayCopy.push(\"5\");\n\tarrayCopy.shift();\n\treturn arrayCopy;\n}\n\nconsole.log(arr, changeArray());\n\n//Ejercicio extra\nlet variableUno = \"uno\";\nlet variableDos = \"dos\";\n\nfunction forValue(par1, par2) {\n\tpar1 = par2;\n\tpar2 = variableUno;\n\treturn [par1, par2];\n}\n\nlet retornoVariableUno = forValue(variableUno, variableDos)[0];\nlet retornoVariableDos = forValue(variableUno, variableDos)[1];\n\nconsole.log({\n\tvariableUno,\n\tvariableDos,\n\tretornoVariableUno,\n\tretornoVariableDos,\n});\n\nlet array = [1, 2, 3];\nlet arrayDos = [\"Uno\", \"Dos\", \"Tres\"];\n\nfunction forReference(arr1, arr2) {\n\tarr1 = arr2;\n\tarr2 = array;\n\treturn [arr1, arr2];\n}\n\nconsole.log(array, arrayDos, arr1, arr2);\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/Glitzypanic.js",
    "content": "// DATOS POR VALOR Y REFERENCIA\nvar a = 10;\nvar b = a;\na = 20;\n\nconsole.log(b); // 10\nconsole.log(a); // 20\n\nvar c = [10, 20];\nvar d = c;\nd.push(30);\n\nconsole.log(d);\nconsole.log(c);\n\n// FUNCIONES CON DATOS POR VALOR\n\nvar h = 10;\n\nfunction my_valor(my_va) {\n  my_va = 20;\n  console.log(my_va);\n}\n\nmy_valor(h); // 20\nconsole.log(h); // 10\n\n// FUNCIONES CON DATOS POR REFERENCIA\n\n// var j = [10, 20];\n\n// function my_referencia(my_re) {\n//   my_re.push(30);\n//   console.log(my_re);\n// }\n\n// my_referencia(j);\n// console.log(j);\n\n// EJERCICIO DE VALOR\nfunction intercambioPorValor(a, b) {\n  let temp = a;\n  a = b;\n  b = temp;\n  return [a, b];\n}\n\n// Definimos variables originales\nlet valor1 = 10;\nlet valor2 = 20;\n\n// Llamamos a la función para intercambiar los valores\nlet nuevosValores = intercambioPorValor(valor1, valor2);\n\n// Imprimimos los valores originales y los nuevos\nconsole.log(valor1, valor2);\nconsole.log(nuevosValores[0], nuevosValores[1]);\n\n// EJERCICIO DE REFERENCIA\nfunction interPorRef(c, d) {\n  let temp = c;\n  c = d;\n  d = temp;\n  d.push(50);\n\n  return [c, d];\n}\n\nvar valor3 = [10, 20];\nvar valor4 = [30, 40];\n\nlet nuevoValor2 = interPorRef(valor3, valor4);\nconsole.log(valor3, valor4);\nconsole.log(nuevoValor2[0], nuevoValor2[1]);\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #05 - JavaScript ->Jesus Antonio Escamilla */\n/**\n * Los tipos de datos primitivos en JavaScript,\n    como números, cadenas, booleanos, null y undefined, se manejan por valor.\n * Cuando asignas un valor a una variable, se copia directamente ese valor en la variable. \n * Modificar la variable no afecta a la variable original.\n * Excepto los valores nulls o undefined esos siempre serán vacíos.\n */\n\n//-----NÚMEROS-----\nvar num1 = 10;\nvar num2 = num1;\nnum2 = 20;\n\nconsole.log(num1); // Se imprime 10 ya que no se a modificado\nconsole.log(num2); // Se imprime 20 aquí si se cambio el valor que se asigno inicialmente\n\n\n//-----CADENAS DE TEXTO-----\nvar str1 = \"Hola\";\nvar str2 = str1;\nstr2 = \"Hola Mundo\";\n\nconsole.log(str1); // Se imprime \"Hola\" ya que no se a modificado\nconsole.log(str2); // Se imprime \"Hola Mundo\" aquí si se cambio el valor que se asigno inicialmente\n\n\n//-----BOOLEANOS-----\nvar bool1 = true;\nvar bool2 = bool1;\nbool2 = false;\n\nconsole.log(bool1); // Se imprime TRUE ya que no se a modificado\nconsole.log(bool2); // Se imprime FALSE aquí si se cambio el valor que se asigno inicialmente\n\n\n\n/**\n * Los objetos y arreglos en JavaScript se manejan por referencia.\n * Cuando asignas un objeto o un arreglo a una variable, en realidad\n    estás asignando una referencia a la ubicación en memoria donde se almacena ese objeto o arreglo.\n * Modificar el objeto o arreglo a través de una variable\n    también afectará a otras variables que hagan referencia al mismo objeto o arreglo.\n */\n\n//-----OBJETOS-----\nvar obj1 = {\n    nombre: \"Jesus Antonio\",\n    edad: 25\n};\nvar obj2 = obj1;\nobj2.edad = 30;\n\nconsole.log(obj1.edad); // Se imprime 30 ya que el objeto esta ocupando la misma memoria de objeto\n\n\n//-----ARREGLOS-----\nvar arr1 = [1, 2, 3];\nvar arr2 = arr1;\narr2.push(4);\n\nconsole.log(arr1); // Se imprime [1, 2, 3, 4] ya se ocupan el misma memoria los arreglos\n\n\n\n/**\n * Ahora lo haremos con funciones de valor y referencia.\n */\n\n//-----POR VALOR-----\n\nfunction duplicarNumero(numero) {\n    numero = numero * 2;\n    return numero;\n}\n\nvar miNumero = 5;\nvar resultado = duplicarNumero(miNumero);\n\nconsole.log(miNumero); // Imprime 5 por que es el valor original\nconsole.log(resultado); // Imprime el valor 10 ya que es el valor duplicado\n\n\n\nfunction agregarPrefijo(texto) {\n    texto = \"Prefijo \" + texto;\n    return texto;\n}\n\nvar miTexto = \"Palabra\";\nvar nuevoTexto = agregarPrefijo(miTexto);\n\nconsole.log(miTexto); // Imprime 'Palabra' por que es el valor original\nconsole.log(nuevoTexto); // Imprime el valor 'Prefijo Palabra' ya que es el valor modificado\n\n\n//-----POR REFERENCIA-----\n\nfunction modificarObjeto(obj) {\n    obj.propiedad = \"Nueva propiedad\";\n}\n\nvar miObjeto = {propiedad: \"Valor original\"};\nmodificarObjeto(miObjeto);\n\nconsole.log(miObjeto.propiedad); // Imprime 'Nueva propiedad' y es el valor nuevo ya que es por referencia\n\n\n\nfunction modificarArreglo(arr) {\n    arr.push(5);\n}\n\nvar miArreglo = [1, 2, 3, 4];\nmodificarArreglo(miArreglo);\n\nconsole.log(miArreglo); // Imprime todos los valores incluyendo el 5 ya que el es por referencia\n\n\n/**-----DIFICULTAD EXTRA-----*/\n\n// Por Valor\nfunction swapByValue(x, y) {\n    let temp = x;\n    x = y;\n    y = temp;\n    return [x, y];\n}\n\nlet a = 5;\nlet b = 10;\n\nlet [newA, newB] = swapByValue(a, b);\n\nconsole.log(\"Valores originales: a =\", a, \", b =\", b); // a = 5, b = 10\nconsole.log(\"Valores intercambiados: newA =\", newA, \", newB =\", newB); // newA = 10, newB = 5\n\n\n// Por Referencia\nfunction swapByReference(arr1, arr2) {\n    let temp = arr1[0];\n    arr1[0] = arr2[0];\n    arr2[0] = temp;\n    return [arr1, arr2];\n}\n\nlet array1 = [5];\nlet array2 = [10];\n\nlet [newArray1, newArray2] = swapByReference(array1, array2);\n\nconsole.log(\"Valores originales: array1 =\", array1[0], \", array2 =\", array2[0]); // array1 = 10, array2 = 5\nconsole.log(\"Valores intercambiados: newArray1 =\", newArray1[0], \", newArray2 =\", newArray2[0]); // newArray1 = 10, newArray2 = 5\n\n\n/**-----DIFICULTAD EXTRA-----*/"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/JoseAndresGC.js",
    "content": "// Tipos de datos por valor\n\nlet a = 100;\nlet b = 200;\nlet c = b;\n\n// Tipos de datos por referencia\n\nlet array1 = [1, 2, 3];\nlet array2 = array1;\narray2.push(4);\nlet perro = {nombre: \"Felipe\", raza: \"Pitbull\"};\n\n// ejemplo por valor\n\nlet numero = 10;\n\nfunction duplicar(valor) {\n    valor = 20;    \n}\n\nduplicar(numero); // numero sigue siendo 10\nconsole.log(numero); // 10\n\n\n// ejemplo por referencia\n\nlet persona = {nombre : \"María\"};\n\nfunction cambiarNombre(persona) {\n    persona.nombre = \"José\";\n}\n\ncambiarNombre(persona); // Ahora el nombre es \"José\"\nconsole.log(persona.nombre); // \"José\"\n\n// DIFICULTAD EXTRA:\n\nlet param1 = 10;\nlet param2 = 20;\n\n// intercambio de valores por valor\nfunction programa1(param1, param2) {\n    let aux = param1;\n    param1 = param2;\n    param2 = aux;\n    console.log(param1, param2);\n    \n}\nprograma1(param1, param2);\nconsole.log(param1, param2); // [10, 20]\n\n// intercambio de valores por referencia\n\nlet param3 = [1, 2, 3];\nlet param4 = [10, 20, 30];\n\nfunction programa2(param3, param4) {\n    let aux = param3;\n    param3 = param4;\n    param4 = aux;\n    console.log(param3, param4);\n}\nprograma2(param3, param4);\nconsole.log(param3, param4); // [30, 40]"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/JuanCaicedo1024.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n */\n\n\n\n//Por valor \nlet string = \"Hola \"\nlet Number = 12345\nlet boolean = true\nlet Noexite = null\n\n\n// Asignación \"Por Referencia\"\nlet obj1 = { nombre: \"Juan\" };\nlet obj2 = obj1; // Se copia la referencia en memoria\n\nobj2.nombre = \"Pedro\"; // Modificamos obj2, pero también cambia obj1\n\nconsole.log(obj1.nombre); // \"Pedro\"\nconsole.log(obj2.nombre); // \"Pedro\"\n\n\n// funciones por valor \n\nfunction Iva (precio) {\n    precioIva = precio * 0.25\n    final = precioIva + precio\n    console.log (`este es el precio original ${precio}`);\n    console.log (`este es el precio con Iva ${final}`);\n}\n\n//funcion por referencia \n\nlet stock = [\n    {nombre: \"cafe\", precio: 1000, stock: 5},\n    {nombre: \"agua\", precio: 1800, stock: 7},\n    {nombre: \"Bombilla\", precio: 80, stock: 2}\n]\n\nfunction actualizaStock(producto,cantidad) {\n    stockProductos[producto].stock=cantidad;\n    console.log(`El nuevo stock de ${stockProductos[producto].nombre} es: ${cantidad}`);\n}\n\nactualizaStock(1,9);\n\n\n/* DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como\n * variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime\n *   el valor de las variables originales y las nuevas, comprobando que se ha invertido\n *   su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\n\nlet A = 1024\nlet B = 1001\n\n\nfunction InversosPorValor (A , B) {\n    let Aguardado = A\n    A = B\n    B = Aguardado\n\n    return (\n        console.log(`Los valores invertidos de A = ${A} y los valores inciales de B = ${B}`)\n    )\n}\nconsole.log(`Los valores inciales de A = ${A} y los valores inciales de B = ${B}`)\nInversosPorValor(A,B)\n\nlet arrayUno = [\n    1,2,3,4\n    ]\n    let arrayDos = [\n        0,1,1,1,1\n    ]\n    function InversosPorReferencia (arrayUno, arrayDos){\n        let ArryaUnoGuardada = arrayUno\n        arrayUno = [...arrayDos]\n        arrayDos = [...ArryaUnoGuardada]\n        \n        return (console.log(`array uno es = ${arrayUno} y arrayDos es = ${arrayDos}`))\n    \n    }\n    InversosPorReferencia(arrayUno, arrayDos)\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/MiguelAngelEc.js",
    "content": "// Tipo de datos por valor\n\nlet a = 10\nlet b = a\nconsole.log(b)\nb = 20\n\nconsole.log(a)\nconsole.log(b)\n\n//Tipo de datos por referencia\n\nlet persona = { nombre: 'Juan' }\nlet persona2 = persona\npersona2.nombre = 'Pedro'\nconsole.log(persona)\nconsole.log(persona2)\n\n//Funciones con dato por valor\n\nfunction cambiarValor(a) {\n    a = 20\n    console.log(a)\n}\n\nlet c = 10\nconsole.log(c)\ncambiarValor(c)\nconsole.log(c)\n\n// Funciones por datos de referencias\n\nfunction cambiarValorObjeto(objeto) {\n    objeto.nombre = 'Pedro'\n    console.log(objeto)\n}\n\nlet personaFunc = { nombre: 'Juan' }\nconsole.log(personaFunc)\ncambiarValorObjeto(personaFunc)\nconsole.log(personaFunc)\n\n//Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n//Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n//Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n//se asigna a dos variables diferentes a las originales. A continuación, imprime\n//el valor de las variables originales y las nuevas, comprobando que se ha invertido\n//su valor en las segundas.\n//Comprueba también que se ha conservado el valor original en las primeras.\n\nlet valor1 = 10\nlet valor2 = 20\n\nfunction intercambiarValoresPorValor (valor1, valor2) {\n    let aux = valor1\n    valor1 = valor2\n    valor2 = aux\n    return [valor1, valor2]\n}\n\nlet [valor1Nuevo, valor2Nuevo] = intercambiarValoresPorValor(valor1, valor2)\nconsole.log(valor1)\nconsole.log(valor2)\nconsole.log(valor1Nuevo)\nconsole.log(valor2Nuevo)\n\nlet persona1 = {nombre: \"Miguel\"}\nlet persona2 = {nombre: \"Angle\"}\n\nfunction intercambiarValoresPorReferencia (persona1, persona2) {\n    let aux = persona1\n    persona1 = persona2\n    persona2 = aux\n    return [persona1, persona2]\n}\n\n\nlet [persona1Nuevo, persona2Nuevo] = intercambiarValoresPorReferencia(persona1, persona2)\nconsole.log(persona1)\nconsole.log(persona2)\nconsole.log(persona1Nuevo)\nconsole.log(persona2Nuevo)\n\n\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/MiguelAngelMTZ000414.js",
    "content": "console.warn(\"----------(◉◉∖____/◉◉)---------- Tipo por valor ----------(OO∖____/OO)----------\")\n\n// Hay 5 tipos de datos que son pasados por valor_Number: Boolean, Null, Undefined, String y Number los cuales son de tipo valor_Numberes primitivos\n\nlet valor_Number1 = 918\nlet valor_Number2 = 40\nlet valor_String1 = \"Porsche\"\nlet valor_String2 = \"Spyder\"\nlet valor_String5 = \"2414\"\nlet valor_Null1 = null\nlet valor_Undefined1 = undefined\nlet valor_boolean1 = true\n\nvalor_Number5 = valor_Number1 // valor_Number5 toma el valor de valor_Number1: undefined = 918\nvalor_Number3 = valor_Number1 // valor_Number3 toma el valor de valor_Number1: undefined = 918\nvalor_Number1 = valor_Number2 // valor_Number1 toma el valor de valor_Number2: 918 = 40\nvalor_Number2 = valor_Number1 // valor_Number2 toma el valor de valor_Number1: 20 = 40\nvalor_Number3 = valor_Number1 // valor_Number3 toma el valor de valor_Number1: 918 = 40\nvalor_Number4 = valor_Number3 // valor_Number4 toma el valor de valor_Number3: undefined = 40\nvalor_Number6 = valor_Number5 // valor_Number6 toma el valor de valor_Number5: undefined = 918\nvalor_Number7 = valor_String1.concat(\" \", valor_Number6, \" \", valor_String2) // valor_Number7 toma el valor de valor_String1: undefined = Porsche concatenando 918 y Spyder\n// valor_String1.concat(\" \", valor_String2)\nvalor_String3 = valor_String1 // valor_String3 toma el valor de valor_String1: undefined = Porsche\nvalor_String4 = valor_Number5.toString() // valor_String4 toma el valor de valor_Number5 convirtiendolo en String: undefined = 918\nvalor_Number8 = parseInt(valor_String5) // valor_Number8 toma el valor de valor_String5 convertiendolo en Number: undefined = 2414\nvalor_Number1 = valor_Null1 // valor_Number1 toma el valor de valor_Null1: 40 = null\nvalor_Null2 = valor_Undefined1 // valor_Null2 toma el valor de valor_Undefined: undefined = undefined\n\nconsole.log(\"valor por tipo: \" + typeof valor_Number5 + \" = \" + valor_Number5)\nconsole.log(\"valor por tipo: \" + typeof valor_Number1 + \" = \" + valor_Number1)\nconsole.log(\"valor por tipo: \" + typeof valor_Number2 + \" = \" + valor_Number2)\nconsole.log(\"valor por tipo: \" + typeof valor_Number3 + \" = \" + valor_Number3)\nconsole.log(\"valor por tipo: \" + typeof valor_Number4 + \" = \" + valor_Number4)\nconsole.log(\"valor por tipo: \" + typeof valor_Number6 + \" = \" + valor_Number6)\nconsole.log(\"valor por tipo: \" + typeof valor_Number7 + \" = \" + valor_Number7)\nconsole.log(\"valor por tipo: \" + typeof valor_String3 + \" = \" + valor_String3)\nconsole.log(\"valor por tipo: \" + typeof valor_String1 + \" = \" + valor_String1)\nconsole.log(\"valor por tipo: \" + typeof valor_String4 + \" = \" + valor_String4)\nconsole.log(\"valor por tipo: \" + typeof valor_Number8 + \" = \" + valor_Number8)\nconsole.log(\"valor por tipo: \" + typeof valor_Number1 + \" = \" + valor_Number1)\nconsole.log(\"valor por tipo: \" + typeof valor_Null2 + \" = \" + valor_Null2)\n\nconsole.warn(\"----------(◉◉∖____/◉◉)---------- Tipo por Referencia ----------(OO∖____/OO)----------\")\nlet referencia_Arreglo0 = [1, 2, 3, 4, 5, 6, 7, 8] // Definimos un arreglo de tipo Number\nlet referencia_Arreglo1 = [10, 20, 30, 40] // Definimos un arreglo de tipo Number\nlet referencia_Arreglo2 = [60, 70, 80, 90] // Definimos un arreglo de tipo Number\n\nreferencia_Arreglo5 = [...referencia_Arreglo1] // Creamos una copia a partir del arreglo[...referencia_Arreglo1], usando el operador de propagación, ahora es un arreglo independiente\nreferencia_Arreglo3 = referencia_Arreglo1 // El arreglo \"referencia_Arraglo1\" es asignado como arreglo [referencia_Arreglo3]\nreferencia_Arreglo3.push(50) // Agregamos un nuevo valor al final del arreglo con la función push\nreferencia_Arreglo3.unshift(9) // Agregamos un nuevo valor al principio del arreglo con la función unshift\nreferencia_Arreglo4 = referencia_Arreglo3 // El arreglo [referencia_Arreglo4] toma la referencia del arreglo [referencia_Arreglo3] \nreferencia_Arreglo6 = [...referencia_Arreglo1] // Creamos una copia a partir del arreglo [referencia_Arreglo1], ahora es un arreglo \nreferencia_Arreglo7 = referencia_Arreglo6 // El arreglo [referencia_Arreglo7] toma la referencia del arreglo [referencia_Arreglo6]\nreferencia_Arreglo7.push(60) // Agregamos un nuevo valor al final del arreglo con la funcion push\nreferencia_Arreglo8 = [...referencia_Arreglo7] // Creamos una copia a partir del arreglo [referencia_Arreglo7], ahora es un arreglo \nreferencia_Arreglo8.push(70) // Agregamos un nuevo valor al final del arreglo con la funcion push \nreferencia_Arreglo9 = [...referencia_Arreglo4] // Creamos una copias a partir del arreglo [referencia_Arreglo4], ahora es un arreglo \nreferencia_Arreglo10 = referencia_Arreglo9.concat(referencia_Arreglo2) // Con la funcion concat fucionaremos los arreglos [referencia_Arreglo9] y [referencia_Arreglo2] creando un nuevo arreglo con los valores existentes.\nreferencia_Arreglo10.push(100) // Agregaremos dos valores al final del arreglo con la funcion push \nreferencia_Arreglo10.push(110) // Agregaremos dos valores al final del arreglo con la funcion push \nreferencia_Arreglo11 = [].concat(referencia_Arreglo0, referencia_Arreglo10) // Con la funcion concat fucionaremos dos arreglos\nreferencia_Arreglo10.push(120) // Agregamos un valor al final del arreglo con la funcion push\nreferencia_Arreglo11.unshift(0) // Agregamos un valor al principio del arreglo con la funcion unshift\nreferencia_Arreglo11.push(110) // Agregamos un valor al final del arreglo con la funcion push\n\n\nconsole.log(`Valor por referencia:`, referencia_Arreglo1)\nconsole.log(`Valor por referencia:`, referencia_Arreglo2)\nconsole.log(`Valor por referencia:`, referencia_Arreglo3)\nconsole.log(`Valor por referencia:`, referencia_Arreglo4)\nconsole.log(`Valor por referencia copia:`, referencia_Arreglo5)\nconsole.log(`Valor por referencia copia:`, referencia_Arreglo6)\nconsole.log(`Valor por referencia:`, referencia_Arreglo7)\nconsole.log(`Valor por referencia copia:`, referencia_Arreglo8)\nconsole.log(`Valor por referencia copia:`, referencia_Arreglo9)\nconsole.log(`Valor por referencia, unión:`, referencia_Arreglo10)\nconsole.log(`Valor por referencia, unión:`, referencia_Arreglo11)\n\nconsole.warn(\"----------(◉◉∖____/◉◉)---------- Extra ----------(OO∖____/OO)----------\")\nconsole.log(\"---------- Valor ----------\")\nlet valor1 = 10 // Declaramos dos valores\nlet valor2 = 20 // Declaramos dos valores\nfunction Valor(valor_1, valor_2) {\n    valor_original_1 = valor_1 // valor_original_1 tomara el valor de valor_1: undefined = 10\n    valor_original_2 = valor_2 // valor_original_2 tomara el valor de valor_2: undefined = 20\n    valor1 = valor_1 // valor1 tomara el valor de valor_1: undefined = 10\n    valor_1 = valor_2 // valor_1 tomara el valor de valor_2: 10 = 20\n    valor_2 = valor1 // valor_2 tomara el valor1: 20 = 10\n    console.log(`${valor_original_1}, ${valor_original_2}`) // Salida: 10, 20\n    console.log(`${valor_1}, ${valor_2}`) // Salida: 20, 10\n}\nValor(valor1, valor2)\n\nconsole.log(\"---------- Referencia ----------\")\nlet referencia1 = [1, 2, 3, 4, 5] // Definimos dos arreglos\nlet referencia2 = [6, 7, 8, 9, 10] // Definimos dos arreglos\n\n// Definimos una funcion que recibira dos parametros/argumentos\nfunction Referencia(referencia_1, referencia_2) {\n    referencia_copia1 = referencia_1 // referencia_copia1 tomara el valor de referencia_1: undefined = referencia1\n    referencia_copia2 = referencia_2 // referencia_copia2 tomara el valor de referencia_2: undefined = referencia2\n    referencia_copia1.unshift(0) // Agregamos un valor al principio del arreglo con la funcion unshift [referencia_copia1]\n    referencia_1 = referencia_copia2 // referencia_1 tomar el valor de referencia_copia2: \n    referencia_1.push(11) // Agregamos un valor al final del arreglo con la funcion push [referencia_1]\n    referencia_2 = referencia_copia1 // referencia_2 toma el valor de referencia_copia1\n    referencia_2.unshift(-3, -2, -1) // Agregamos varios valores al principio del arreglo [referencia_2]\n    console.log(`${referencia_copia1}, ${referencia_copia2}`)\n    console.log(`${referencia_1}, ${referencia_2}`)\n}\nReferencia(referencia1, referencia2)\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/Nightblockchain30.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\n//Refiere a cómo se manejan los valores y las direcciones de memoria cuando se asignan variables en un programa\n\n//Asignación por valor\n/*\nEn la asignación por valor, se copia el contenido de la variable original en la nueva variable.\nLas dos variables son independientes y ocupan ubicaciones de memoria diferentes.\n */\nlet variableoriginal= 10\nlet variablecopia= variableoriginal //Asignación por valor\nvariableoriginal=20 \n\nconsole.log(`La variable original ahora vale ${variableoriginal} mientras que la variable copia \nguarda el primer valor de la original en este caso ${variablecopia}`)\n\n//Asignación por referencia\n/*\nEn la asignación por referencia, la nueva variable hace referencia a la misma ubicación de memoria que la variable original.\n En este caso, cualquier cambio en una variable afectará a la otra, ya que comparten la misma ubicación de memoria.\n*/\n\nlet arrayoriginal = [\"Hola\",\"Alexdevrep\",\"Mundo\"]\nlet arraycopia = arrayoriginal\n\narraycopia[2] = \"JavaScript\" \n\nconsole.log (arrayoriginal)\n/*Como podemos obsevar aunque hayamos modificado el array copia tambien se modifica el original\nya que ambos apuntan a la misma ubicación de memoria */\n\n//Funciones con variables por valor\n\nfunction saludar(saludo){\n     let mi_saludo = `Hola, ${saludo}`\n    return mi_saludo\n}\n\nlet holamundo = \"JavaScript\"\nlet resultado = saludar(holamundo)\nconsole.log(holamundo) //La variable original no se modifica\nconsole.log(resultado)\n\n//Funciones con variables por referencia\n\nfunction agregarelemento(array,elemento){\n    array.push(elemento)\n\n}\n//Vamos a usar el arrayoriginal creado anteriormente\nagregarelemento(arrayoriginal,\"Mundo\")\nconsole.log(arraycopia)//Imprimimos el arraycopia para comprobar que efectivamente ambos array apuntan a la misma ubicación de la memoria\n\n\n//DIFICUALTAD EXTRA\n/* DIFICULTAD EXTRA (opcional):\n* Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n* - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n*   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n*   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n*   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n*   Comprueba también que se ha conservado el valor original en las primeras.\n*/\n\nlet valor1 = 3\nlet valor2 = 5\nlet objetoOriginal= { valor1: \"Hola\", valor2:\"JavaScript\"}\nlet objetoNuevo = programa2(objetoOriginal)\n\nfunction programa1 (valor1,valor2){\n    valor1 = 5\n    valor2 = 3\n    return [valor1, valor2]\n\n}\n\nfunction programa2 (objeto){\n    let intercambio =objeto.valor1\n    objeto.valor1=objeto.valor2\n    objeto.valor2 = intercambio\n    return objeto\n   \n}\n\nconsole.log (\"Resultado del programa 1: \")\nconsole.log (`El valor de la variables originales es ${valor1} para la variable valor1 y ${valor2} para la variable valor2`)\nlet [valor1nuevo, valor2nuevo] = programa1(valor1,valor2)\nconsole.log(\"El valor1 ahora será:\" + valor1nuevo)\nconsole.log(\"El valor2 ahora será:\"+valor2nuevo)\nconsole.log(\"-------------------------------------\")\nconsole.log (\"Resultado del programa 2: \")\n\nconsole.log (\"Valores originales:\", objetoOriginal.valor1,objetoOriginal.valor2)\nconsole.log (\"Valores nuevos:\", objetoNuevo.valor1,objetoNuevo.valor2)\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/OmarLand.js",
    "content": "/*\n    * EJERCICIO:\n    * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n    *   su tipo de dato.\n    * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n    *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n    * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n    *\n*/\n\n// Asignación de variables \"por valor\" y \"por referencia\", según su tipo de dato.\n\nlet numA = 10;\nconsole.log(\"Variable por su valor: \", numA);\nlet numB = numA;\nconsole.log(\"Variable por referencia: \", numB);\nnumB = 20;\nconsole.log(\"Variable por referencia: \", numB);\n\nlet stringA = \"Hola\";\nconsole.log(\"Variable por su valor: String\", stringA);\nlet stringB = stringA;\nconsole.log(\"Variable por su valor: String\", stringB);\nstringB = \"Adios\";\nconsole.log(\"Variable por su valor: String\", stringB);\n\n/* \n  Muestra ejemplos de funciones con variables que se les pasan \"por valor\"   y \"por referencia\", y cómo se comportan en cada caso en el momento de      ser modificadas.\n*/\n\nconst saludar = () =>{\n  let saludo = \"Hola saludo por valor!!! xD\"\n  return saludo;\n}\nconsole.log(\">>>\", saludar() )\n\nconst saludoPorReferencia = (saludo) => {\n  let saludando = saludo;\n  return saludando;\n}\n\nconsole.log(saludoPorReferencia(\">>> Hola saludo por referencia!!! xD\"))\n\n\n/*\n    * DIFICULTAD EXTRA (opcional):\n    * Crea dos programas que reciban dos parámetros (cada uno) definidos como\n    * variables anteriormente.\n    * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n    *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n    *   se asigna a dos variables diferentes a las originales. A continuación, imprime\n    *   el valor de las variables originales y las nuevas, comprobando que se ha invertido\n    *   su valor en las segundas.\n    *   Comprueba también que se ha conservado el valor original en las primeras.\n*/\n \n// Función que intercambia dos variables por su valor:\nconst interChangeValues = () => {\n    let valueA = \"Perro\"\n    let valueB = \"Gato\"\n    let temp   = \"\";\n\n    console.log(`Valor original de ValueA es: ${valueA}`);\n    console.log(`Valor original de ValueB es: ${valueA}`);\n\n    temp = valueA;\n    valueA = valueB;\n    valueB = temp;\n\n    console.log(`Ahora el valor de valueA es: ${valueA}`);\n    console.log(`Ahora el valor de valueB es: ${valueB}`);\n\n}\n\nconsole.log( \">>> \", interChangeValues() );\n\n// Función que intercambia dos variables por parametro:\nconst interChangeValuesByParam = ( valA, valB ) => {\n\n    console.log(\"Valor original de valA: \", valA);\n    console.log(\"Valor original de valB: \", valB);\n\n    let aux = valA;\n    valA = valB;\n    valB = aux;\n\n    console.log(\">>> Ha cambiado el valor de valA y es: \", valA);\n    console.log(\">>> Ha cambiado el valor de valB y es: \", valB);\n\n}\n\ninterChangeValues(\"JavasCript\", \"TypeScript\");"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/Pancratzia.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y\n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\n/***************************************************************/\n/***************************************************************/\n/***************************************************************/\n/************************ PRIMERA PARTE ************************/\n/***************************************************************/\n/***************************************************************/\n/***************************************************************/\n\n/* ASIGNACION POR VALOR PARA TIPOS PRIMITIVOS - Siempre se copia el valor, debido a que cada variable tiene su propio espacio de memoria */\n\nlet a = 500;\nlet b = a; // Asignación por valor\n\nconsole.log(a); // Salida: 10 (valor original no cambia)\nconsole.log(b); // Salida: 10\n\na = 501;\n\nconsole.log(a); // Salida: 20\nconsole.log(b); // Salida: 10\n\n/* ASIGNACION POR REFERENCIA PARA OBJETOS - Siempre se copia la referencia al espacio de memoria, así que si se cambia el valor de una variable, el valor de la otra variable cambia también, pues hacen referencia al mismo espacio de memoria */\n\nlet personaA = { nombre: \"Laura\" };\nlet personaB = personaA; // Asignación por referencia\n\nconsole.log(personaA); // Salida: { nombre: 'Laura' }\nconsole.log(personaB); // Salida: { nombre: 'Laura' }\n\npersonaA.nombre = \"Arthuro\";\n\nconsole.log(personaA); // Salida: { nombre: 'Arthuro' }\nconsole.log(personaB); // Salida: { nombre: 'Arthuro' }\n\npersonaB.nombre = \"Laura\"; //No importa la variable que se cambie. La referencia al mismo espacio de memoria se va a cambiar\n\nconsole.log(personaA); // Salida: { nombre: 'Laura' }\nconsole.log(personaB); // Salida: { nombre: 'Laura' }\n\n/* FUNCION CON VARIABLES POR VALOR */\n\nfunction dividir(num) {\n  num /= 2;\n  return num;\n}\n\nfunction multiplicar(num) {\n  num *= 2;\n  console.log(num);\n}\n\nlet original = 10;\nlet resultado = dividir(original);\n\nconsole.log(original); // Salida: 10 (el valor original no cambia)\nconsole.log(resultado); // Salida: 5\n\noriginal = 20;\nresultado = multiplicar(original);\n\nmultiplicar(original); // El valor de la variable original no cambia. Cambia el valor de la variable dentro de la función\nconsole.log(original); // Salida: 20 (el valor original no cambia)\n\n/* FUNCION CON VARIABLES POR REFERENCIA */\n\nfunction marcarComoLeido(libro) {\n  libro.leido = true;\n}\n\nlet libroOriginal = {\n  autor: \"J.K. Rowling\",\n  titulo: \"Harry Potter y la Piedra Filosofal\",\n  leido: false,\n};\n\nconsole.log(libroOriginal.leido);\nmarcarComoLeido(libroOriginal);\nconsole.log(libroOriginal.leido); //El valor de la variable original cambia\n\nlet arrayOriginal = [1, 2, 3];\nlet arrayCopia = arrayOriginal;\n\nconsole.log(arrayOriginal);\nconsole.log(arrayCopia);\n\narrayOriginal.push(4);\n\nconsole.log(arrayOriginal);\nconsole.log(arrayCopia); //Los arrays se comportan como si fueran objetos, es decir, se pasan por referencia\n\n/***************************************************************/\n/***************************************************************/\n/***************************************************************/\n/************************ SEGUNDA PARTE ************************/\n/***************************************************************/\n/***************************************************************/\n/***************************************************************/\n\n//Invertir Valores con Variables por Valor\n\nfunction invertirPorValor(a, b) {\n  let temp = a;\n  a = b;\n  b = temp;\n  return [a, b];\n}\n\nlet porValor1 = 'a';\nlet porValor2 = 'b';\n\nlet porValorInvertido = invertirPorValor(porValor1, porValor2);\n\n//Los valores solo cambian en la función debido a que no se pasan por referencia\n\nconsole.log(porValor1);\nconsole.log(porValor2);\n\n//Sin embargo, podemos asignar los nuevos valores a las variables originales de la siguiente manera:\n\nporValor1 = porValorInvertido[0];\nporValor2 = porValorInvertido[1];\n\nconsole.log(porValor1);\nconsole.log(porValor2);\n\n//Invertir Valores con Variables por Referencia\n\nfunction invertirPorReferencia(obj1, obj2) {\n  let aux = obj1.nombre;\n  obj1.nombre = obj2.nombre;\n  obj2.nombre = aux;\n  return [obj1, obj2];\n}\n\nlet objeto1 = {\n  nombre: \"Pelota\"\n}\n\nlet objeto2 = {\n  nombre: \"Bate\"\n}\n\nlet nuevosObjetos = invertirPorReferencia(objeto1, objeto2);\n\nconsole.log(objeto1);\nconsole.log(objeto2); //Al pasarse por referencia, los objetos cambian de valor debido a que lo que se pasa por referencia es el espacio de memoria, no el valor\n\n//Si asignamos los nuevos valores a nuevas variables de la siguiente manera:\n\nlet obj1copia = nuevosObjetos[0];\nlet obj2copia = nuevosObjetos[1];\n\nconsole.log(obj1copia);\nconsole.log(obj2copia);\n\n //Ahora, si cambio el valor del objeto 1\n objeto1.nombre = \"Guante\";\n \nconsole.log(objeto1);\nconsole.log(obj1copia); //El valor del objeto 1 cambia, así que la copia también cambia, debido a que, de nuevo, hacen referencia al mismo espacio de memoria.\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/RaulDoezon.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n*/\n\n/* +++++++++ ASIGNACIONES POR VALOR Y POR REFERENCIA +++++++++ */\nconsole.log(\"+++++++++ ASIGNACIÓN POR VALOR +++++++++\");\n\nvar a = 10;\nvar b = \"JavaScript\";\nvar x = a;\nvar y = b;\nx = 15;\ny = \"ECMAScript\";\n\nconsole.log(`El valor de a es: ${a}`);\nconsole.log(`El valor de b es: ${b}`);\nconsole.log(`El valor de x es: ${x}`);\nconsole.log(`El valor de y es: ${y}`);\n\nconsole.log(\"+++++++++ ASIGNACIÓN POR REFERENCIA +++++++++\");\n\nvar x = {\n  a: 33,\n  b: \"Asignación por valor\"\n}\n\ny = x;\n\nx.a = 16;\nx.b = \"Asignación por referencia\";\n\nconsole.log(\"Valor de x:\");\nconsole.log(x);\nconsole.log(\"Valor de y:\");\nconsole.log(y);\n\nconsole.log(\"+++++++++ FUNCIÓN: ASIGNACIÓN POR VALOR +++++++++\");\n\nfunction asignacionPorValor(reassignObject) {\n  reassignObject.age = 40;\n}\n\nvar person = {\n  name: \"Peter\",\n  age: 34,\n}\n\nasignacionPorValor(person);\nconsole.log(person);\n\nconsole.log(\"+++++++++ ASIGNACIÓN POR REFERENCIA +++++++++\");\n\nfunction asignacionPorReferencia(reassignBountyHunter) {\n  reassignBountyHunter.name = \"Sylux\";\n\n  reassignBountyHunter = {\n    name: \"Samus Aran\",\n    specie: \"Human\",\n  }\n\n  return reassignBountyHunter;\n}\n\nvar bountyHunter = {\n  name: \"Unknow\",\n  specie: \"Unknow\",\n}\n\nvar bestBountyHunter = asignacionPorReferencia(bountyHunter);\n\nconsole.log(bountyHunter);\nconsole.log(bestBountyHunter);\n\n/* +++++++++ DIFICULTAD EXTRA +++++++++ */\nconsole.log(\"+++++++++ EJERCICIO +++++++++\");\n\nvar a = 19;\nvar b = \"Raúl\";\nvar x = [1, 2, 3, 4];\nvar y = [\"a\", \"b\", \"c\", \"d\"];\n\nfunction invertirPorValor(valor1, valor2) {\n  valorIntercambiado1 = valor2;\n  valorIntercambiado2 = valor1;\n\n  return [valorIntercambiado1, valorIntercambiado2];\n}\n\nvar [bToA, aToB] = invertirPorValor(a, b);\n\nconsole.log(`Valor de a: ${a}. Valor de b: ${b}`);\nconsole.log(`Valor intercambiado de a: ${bToA}. Valor intercambiado de b: ${aToB}`);\n\nfunction invertirPorReferencia(referencia1, referencia2) {\n  var referenciaIntercambiada1 = referencia2;\n  var referenciaIntercambiada2 = referencia1;\n\n  return [referenciaIntercambiada1, referenciaIntercambiada2];\n}\n\nvar [xToY, yToX] = invertirPorReferencia(x, y);\n\nconsole.log(`Referencia de x: ${x}. Referencia de y: ${y}`);\nconsole.log(`Referencia invertida de x: ${xToY}. Referencia invertida de y: ${yToX} `);\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/RicJDev.js",
    "content": "//EJERCICIO\n//-Tipos de datos por valor-\nlet miNumA = 20;\nlet miNumB = miNumA;\nconsole.log(miNumB); //---> 20\nmiNumA = 40; //actualizar el valor de miNumbA no afecta al de miNumB\nconsole.log(miNumA); //---> 40\nconsole.log(miNumB); //---> 20\n\n//-Tipos de datos por referencia-\nlet arr1 = [1, 2, 3];\nlet arr2 = arr1;\nconsole.log(arr1); //---> [1, 2, 3]\nconsole.log(arr2); //---> [1, 2, 3]\narr2.push(4); //operar arr2 si afecta a arr1\nconsole.log(arr1); //---> [1, 2, 3, 4]\nconsole.log(arr2); //---> [1, 2, 3, 4]\n\n//-Funciones con datos por valor-\nlet miNumC = 5;\n\nfunction suma40(num) {\n\treturn num + 40;\n}\n\nconsole.log(miNumC);\n\nsuma40(miNumC);\nconsole.log(miNumC);\n\n//-Funciones con datos por referencia-\nconst arr3 = [12, 34, 53];\n\nconst agrega40ALaLista = (arr) => {\n\treturn arr.push(40);\n};\n\nconsole.log(arr3);\n\nagrega40ALaLista(arr3);\nconsole.log(arr3);\n\n//EXTRA\n//-Por valor-\nfunction intercambiaLosValores(a, b) {\n\tlet temp = a;\n\ta = b;\n\tb = temp;\n\treturn [a, b];\n}\n\nlet miNumD = 45;\nlet miNumF = 63;\n\nlet [nuevoNumD, nuevoNumF] = intercambiaLosValores(miNumD, miNumF);\n\nconsole.log(`\\nValores originales: ${miNumD}, ${miNumF}`);\nconsole.log(`\\nValores luego de cambiarlos con la función: ${nuevoNumD}, ${nuevoNumF}`);\n\n//-Por referencia-\n//Funciona de la misma manera con los arrays\nlet miArr1 = [10, 45, 20, 78];\nlet miArr2 = [100, 200, 432, 590];\n\nlet [nuevoArr1, nuevoArr2] = intercambiaLosValores(miArr1, miArr2);\n\nconsole.log('\\nArrays originales:');\nconsole.log(miArr1, miArr2);\n\nconsole.log('\\nArrays luego de pasarlos por la función:');\nconsole.log(nuevoArr1, nuevoArr2);\n\nlet miObj1 = {\n\ta: 12,\n\tb: 24,\n};\n\nlet miObj2 = {\n\tc: 45,\n\td: 68,\n};\n\nconsole.log('\\nFunciona igual para los objetos:');\n\nconsole.log(miObj1, miObj2);\nlet [nuevoObj1, nuevoObj2] = intercambiaLosValores(miObj1, miObj2);\nconsole.log(nuevoObj1, nuevoObj2);\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/Sac-Corts.js",
    "content": "// Exercise //\n\n// Variable Assignment \n// By value\nlet a = 10;\nlet b = a;\nb = 20;\n\nconsole.log(a);\nconsole.log(b);\n\n// By reference\nlet obj1 = { value: 10 };\nlet obj2 = obj1;\nobj2.value = 20;\n\nconsole.log(obj1.value);\nconsole.log(obj2.value);\n\n// Passing from Parameters to Functions\n// By value\nfunction changeValue(x) {\n    x = 30;\n    return x;\n}\n\nlet num = 10;\nconsole.log(changeValue(num));\nconsole.log(num);\n\n// By reference\nfunction changeObj(obj) {\n    obj.value = 60;\n    return obj;\n}\n\nlet myObj = { value: 50 };\nconsole.log(changeObj(myObj));\nconsole.log(myObj);\n\n// Extra Exercise //\nlet str1 = \"Hello\";\nlet str2 = \"World\";\n\n// By value\nfunction swapByValue(x, y) {\n    let temp = x;\n    x = y;\n    y = temp;\n    return [x, y];\n}\n\n// By reference\nfunction swapByReference(ref) {\n    let temp = ref.str1;\n    ref.str1 = ref.str2;\n    ref.str2 = temp;\n}   \n\nlet [newStr1, newStr2] = swapByValue(str1, str2);\nconsole.log(\"Swap by value:\");\nconsole.log(\"Original values: str1 = \", str1, \" str2 = \", str2);\nconsole.log(\"New values: nweStr1 = \", newStr1, \" newStr2 = \", newStr2);\n\nlet ref = {str1: str1, str2: str2};\nswapByReference(ref);\nconsole.log(\"Swap by reference\");\nconsole.log(\"Original values: str1 = \", str1, \" str2 = \", str2);\nconsole.log(\"New values: ref.str1 = \", ref.str1, \" ref.str2 = \", ref.str2);"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/UserMatthew.js",
    "content": "/*#05 VALOR Y REFERENCIA\n  ## Ejercicio\n */\n/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n*/\n\n/* \n * En Javascript la asignacion de variales \"por valor\" se le asigna a los datos de tipo primitivo\n  Number, String, Boolean, Undefined, Null, Symbol, y BitInt... Y no modifica la variable original\n*/\n\nlet a = 10 // Variable original\nlet b = a  // Se le asigna el valor de la original, se vuelve una copia\nb = 30    // Se cambia la copia \n\nconsole.log('a:', a) //Sigue siendo la original\nconsole.log('b:', b) // Cambio el valor de la copia \n\n/* \n * En Javascript la asignacion de variales \"por referencia\" se le asigna a los datos de tipo\n  Object, array , funtion, y modifica la variable original \n*/\nlet persona = {Nombre: \"Juan\"}\nlet persona2 = persona \n\npersona2.nombre = \"Michael\"\nconsole.log(persona.nombre)\nconsole.log(persona2.nombre)\n\n/*\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n * \n */\n\n// Funcion variable asignada por valor \n\nlet numero = 5\nfunction incrementar(numero) {\n  numero *= 5\n  console.log(`El valor dentro de la funcion de la copia es ${numero}`)\n}\nincrementar(numero)\nconsole.log(`El valor fuera de la funcion de la original es ${numero}`)\n\n// Funcion variable asignada por referencia \nlet usuario = { nombre: \"Juan\" };\nfunction cambiarNombre(persona) {\n  persona.nombre = \"Pedro\"; // \n}\ncambiarNombre(usuario);\nconsole.log(usuario.nombre); \n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\n\nlet valor1 = 20\nlet valor2 = 100\nfunction parametrosPorValor(parametro1, parametro2) {\nlet temporal = parametro1\n    parametro1 = parametro2\n    parametro2 = temporal\n  return   {parametro1 , parametro2}\n}\nconsole.log(parametrosPorValor(valor1, valor2))  \nconst resultados = parametrosPorValor(valor1,  valor2)\nconst resultado1 = resultados.parametro1\nconst resultado2 = resultados.parametro2\n\nconsole.log(`Parametro 1 Original: ${valor1}, Nuevo: ${resultado1}`);\nconsole.log(`Parametro 2 Original: ${valor2}, Nuevo: ${resultado2}`);\n\nlet list1 = [10, 20];\nlet list2 = [30, 40];\nfunction parametrosPorReferencias(referencia1, referencia2) { \n    let temp = referencia1;\n    referencia1 = referencia2;\n    referencia2 = temp;\n    return [  referencia1, referencia2 ];\n  }\n  \n  const resultados2 = parametrosPorReferencias(list1, list2);\n  \n  const resultadoList1 = resultados2[0]\n  const resultadoList2 = resultados2[1]\n  \n  console.log(`Parametro 1 Original: ${list1}, Nuevo: ${resultadoList1}`);\n  console.log(`Parametro 2 Original: ${list2}, Nuevo: ${resultadoList2}`);"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/YgriegaSB.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\n// Definimos una función que intercambia los valores de dos parámetros por valor\nfunction intercambiarValoresPorValor(a, b) {\n    let temp = a;\n    a = b;\n    b = temp;\n    return [a, b];\n}\n  \n// Definimos dos variables\nlet x = 5;\nlet y = 10;\n\n// Llamamos a la función y asignamos los nuevos valores a dos variables diferentes\nlet [xNuevo, yNuevo] = intercambiarValoresPorValor(x, y);\n\n// Imprimimos los valores originales y los nuevos\nconsole.log(\"Valores originales:\", x, y);\nconsole.log(\"Nuevos valores:\", xNuevo, yNuevo);\n\n\n// Definimos una función que intercambia los valores de dos parámetros por referencia\nfunction intercambiarValoresPorReferencia(objeto) {\n    let temp = objeto.a;\n    objeto.a = objeto.b;\n    objeto.b = temp;\n    return objeto;\n  }\n  \n  // Definimos un objeto con dos propiedades\n  let objeto = { a: 5, b: 10 };\n  \n  // Llamamos a la función y asignamos los nuevos valores a un nuevo objeto\n  let objetoNuevo = intercambiarValoresPorReferencia(objeto);\n  \n  // Imprimimos los valores originales y los nuevos\n  console.log(\"Valores originales:\", objeto.a, objeto.b);\n  console.log(\"Nuevos valores:\", objetoNuevo.a, objetoNuevo.b);\n  "
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/Zunigaj1101.js",
    "content": "// Ejemplo de asignación \"por valor\"\nlet a = 10;\nlet b = a; // Se copia el valor de 'a' en 'b'\nb = 20; // Cambiar 'b' no afecta a 'a'\n\nconsole.log(\"Por valor:\");\nconsole.log(\"a:\", a); // 10\nconsole.log(\"b:\", b); // 20\n\n// Ejemplo de asignación \"por referencia\"\nlet obj1 = { value: 10 };\nlet obj2 = obj1; // Se copia la referencia de 'obj1' en 'obj2'\nobj2.value = 20; // Cambiar 'obj2.value' afecta a 'obj1.value'\n\nconsole.log(\"\\nPor referencia:\");\nconsole.log(\"obj1:\", obj1); // { value: 20 }\nconsole.log(\"obj2:\", obj2); // { value: 20 }\n\n\n// Función con parámetros pasados \"por valor\"\nfunction modifyValue(x) {\n  x = x * 2; // Esto no afecta a la variable original\n  console.log(\"Dentro de modifyValue:\", x);\n}\n\nlet num = 5;\nmodifyValue(num);\nconsole.log(\"Después de modifyValue:\", num); // 5\n\n// Función con parámetros pasados \"por referencia\"\nfunction modifyReference(obj) {\n  obj.value = obj.value * 2; // Esto modifica el objeto original\n  console.log(\"Dentro de modifyReference:\", obj);\n}\n\nlet myObj = { value: 5 };\nmodifyReference(myObj);\nconsole.log(\"Después de modifyReference:\", myObj); // { value: 10 }\n\n/// Dificultad extra\nfunction swapByValues (a,b) {\n return [b, a]\n}\n\nfunction swapByreference (a, b) {\n    let temp = a.value\n    a.value = b.value\n    b.value = temp\n}\n\nlet value1 = 5; let value2 = 10\n\nlet [newValue1, newValue2] = swapByValues(value1, value2)\nconsole.log (`\\nVariables por valor:`)\nconsole.log (`valores orginales: ${value1}, ${value2}`)\nconsole.log (`Nuevos valores: ${newValue1}, ${newValue2}`)\n\nlet myObj1 = {value: 5}; let myObj2 = {value: 10}\nconsole.log (`\\nVariables por referencia:`)\nconsole.log (`referencias originales: ${myObj1.value}, ${myObj2.value}`)\nswapByreference (myObj1, myObj2)\nconsole.log (`referencias cambiadas: ${myObj1.value}, ${myObj2.value}`)\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/aarxnmendez.js",
    "content": "// Ejemplo de asignación por valor\r\nlet numeroA = 10;\r\nlet numeroB = numeroA; // numeroB es una copia del valor de numeroA\r\nnumeroB = 20;\r\nconsole.log(numeroA); // 10\r\nconsole.log(numeroB); // 20\r\n\r\n// Ejemplo de asignación por referencia\r\nlet objeto1 = { nombre: \"Alicia\" };\r\nlet objeto2 = objeto1; // objeto2 es una referencia a objeto1\r\nobjeto2.nombre = \"Roberto\";\r\nconsole.log(objeto1.nombre); // \"Roberto\"\r\nconsole.log(objeto2.nombre); // \"Roberto\"\r\n\r\n// Función con parámetro por valor\r\nfunction modificarValor(x) {\r\n    x = 20;\r\n    console.log(\"Dentro de la función:\", x); // 20\r\n}\r\n\r\nlet numero = 10;\r\nmodificarValor(numero);\r\nconsole.log(\"Fuera de la función:\", numero); // 10\r\n\r\n// Función con parámetro por referencia\r\nfunction modificarObjeto(obj) {\r\n    obj.nombre = \"Carlos\";\r\n    console.log(\"Dentro de la función:\", obj.nombre); // \"Carlos\"\r\n}\r\n\r\nlet persona = { nombre: \"Alicia\" };\r\nmodificarObjeto(persona);\r\nconsole.log(\"Fuera de la función:\", persona.nombre); // \"Carlos\"\r\n\r\n// Ejercicio Extra: Intercambio por valor\r\nfunction intercambiarPorValor(x, y) {\r\n    let temp = x;\r\n    x = y;\r\n    y = temp;\r\n    return [x, y];\r\n}\r\n\r\nlet valor1 = 1;\r\nlet valor2 = 2;\r\nlet [nuevoValor1, nuevoValor2] = intercambiarPorValor(valor1, valor2);\r\nconsole.log(\"Valores originales:\", valor1, valor2); // 1, 2\r\nconsole.log(\"Valores intercambiados:\", nuevoValor1, nuevoValor2); // 2, 1\r\n\r\n// Ejercicio Extra: Intercambio por referencia\r\nfunction intercambiarPorReferencia(obj1, obj2) {\r\n    let temp = obj1.valor;\r\n    obj1.valor = obj2.valor;\r\n    obj2.valor = temp;\r\n}\r\n\r\nlet referencia1 = { valor: 1 };\r\nlet referencia2 = { valor: 2 };\r\nintercambiarPorReferencia(referencia1, referencia2);\r\nconsole.log(\"Valores originales:\", referencia1.valor, referencia2.valor); // 2, 1"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/adrs1166ma.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\n// 🔥 Asignación por valor (tipos primitivos)\nlet numero1 = 5;\nlet numero2 = numero1; // Copia el valor de numero1\nnumero2 = 10;\n\nconsole.log(\"Número 1:\", numero1); // 5\nconsole.log(\"Número 2:\", numero2); // 10\n\n// 🔥 Asignación por referencia (tipos compuestos)\nlet array1 = [1, 2, 3];\nlet array2 = array1; // Ambas variables apuntan al mismo objeto en memoria\narray2.push(4);\n\nconsole.log(\"Array 1:\", array1); // [1, 2, 3, 4]\nconsole.log(\"Array 2:\", array2); // [1, 2, 3, 4]\n\n\n// 🔥 Función con parámetro por valor\nfunction modificarValor(valor) {\n    valor = 100;\n}\n\nlet num = 5;\nmodificarValor(num);\nconsole.log(\"Número después de la función:\", num); // 5 (no cambia)\n\n// 🔥 Función con parámetro por referencia\nfunction modificarReferencia(objeto) {\n    objeto.propiedad = \"Modificado\";\n}\n\nlet miObjeto = { propiedad: \"Original\" };\nmodificarReferencia(miObjeto);\nconsole.log(\"Objeto después de la función:\", miObjeto); // { propiedad: \"Modificado\" }\n\n// 🔥 Programa 1: Intercambio \"por valor\"\n// Intercambio de valores por valor\nfunction intercambiarPorValor(valor1, valor2) {\n    let temp = valor1;\n    valor1 = valor2;\n    valor2 = temp;\n    return [valor1, valor2]; // Retornamos los valores intercambiados\n}\n\n// Variables originales\nlet original1 = 5;\nlet original2 = 10;\n\n// Llamada a la función\nlet [nuevo1, nuevo2] = intercambiarPorValor(original1, original2);\n\n// Resultados\nconsole.log(\"Originales:\", original1, original2); // 5, 10\nconsole.log(\"Nuevos:\", nuevo1, nuevo2); // 10, 5\n\n\n// 🔥  Programa 2: Intercambio \"por referencia\"\n// Intercambio de valores por referencia\nfunction intercambiarPorReferencia(objeto1, objeto2) {\n    let temp = objeto1.valor;\n    objeto1.valor = objeto2.valor;\n    objeto2.valor = temp;\n    return [objeto1, objeto2]; // Retornamos los objetos modificados\n}\n\n// Variables originales\nlet objetoA = { valor: \"A\" };\nlet objetoB = { valor: \"B\" };\n\n// Llamada a la función\nlet [nuevoObjetoA, nuevoObjetoB] = intercambiarPorReferencia(objetoA, objetoB);\n\n// Resultados\nconsole.log(\"Originales:\", objetoA.valor, objetoB.valor); // B, A (modificados)\nconsole.log(\"Nuevos:\", nuevoObjetoA.valor, nuevoObjetoB.valor); // B, A"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/agusrosero.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y\n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\n// Asignación de variables por valor\nlet a = \"Javascript\";\nlet b = a;\nb += \"!\";\nconsole.log(a);\nconsole.log(b);\n\n// Asignación de variable por referencia\n// Objetos\nlet person_1 = {\n  name: \"Hernan\",\n  age: 23,\n};\nlet person_2 = person_1;\nperson_2.name = \"Agustin\";\nperson_2.age = 24;\nconsole.log(\"person 1\", person_1);\nconsole.log(\"person 2\", person_2);\n\n// Array\nlet miArray = [1];\nlet miArray2 = miArray;\nconsole.log(miArray);\nconsole.log(miArray2);\n\n// Funcion por valor\nfunction funcionPorValor(str) {\n  str = \"Mi valor\";\n  return str;\n}\n\nlet valor = \"Fuera de la funcion\";\nconsole.log(funcionPorValor(valor));\n\n// Funcion por referencia\nfunction funcionPorReferencia(objeto) {\n  objeto.propiedad = \"Modificado\";\n  console.log(\"Dentro de la funcion\", objeto);\n}\n\nlet objeto = { propiedad: \"Original\" };\nconsole.log(\"Antes de la funcion:\", objeto);\nfuncionPorReferencia(objeto);\nconsole.log(\"Despues de la funcion:\", objeto);\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/airesEsteban.js",
    "content": "// Ejemplo de asignación por valor\n\nlet numA = 10\nlet numB = numA // numB es una copia en este momento de numA\nnumB = 20\n\nconsole.log(numA) // 10\nconsole.log(numB)// 20\n\n// Ejemplo de asignación por referencia\nlet obj1 = {nombre: \"Esteban\"}\nlet obj2 = obj1 // obj 2 es referencia a obj1, toma la referencia de memoria de obj1\nobj2.nombre = \"Carlos\"\nconsole.log(obj1.nombre)//\"Carlos\"\nconsole.log(obj2.nombre)//\"Carlos\"\n\n// Función con parámetro por valor\nfunction modificarValor(x){\n    x = 20\n    console.log(\"dentro de la funcion\", x)// 20\n}\n\nlet num = 10\nmodificarValor(num)\nconsole.log(\"fuera de la funcion\", num )//10\n\n// Función con parámetro por referencia\nfunction modificarObjeto(obj){\n    obj.nombre = \"Carlos\"\n    console.log(obj.nombre)//Carlos\n}\n\nlet persona = { nombre: \"Esteban\"}\nmodificarObjeto(persona)\nconsole.log(persona.nombre)//Carlos\n\n\n// Ejercicio Extra: Intercambio por valor\n\nfunction intercambioValor(x,y){\n    let valor = x\n    x = y\n    y = valor\n    console.log(x,y)\n    return [x,y]\n}\n\nlet valor1 = 1\nlet valor2 = 2\nlet [nuevoValor1, nuevoValor2] = intercambioValor(valor1,valor2)\nconsole.log(\"Valores originales\", valor1,valor2)\nconsole.log(\"Valores intercambiados\", nuevoValor1,nuevoValor2)\n\n// Ejercicio Extra: Intercambio por referencia\nfunction intercambioReferencia(obj1, obj2) {\n    let ref = obj1.valor\n    obj1.valor = obj2.valor\n    obj2.valor = ref\n}\n\nlet ref1 = { valor:1 }\nlet ref2 = { valor:2 }\nintercambioReferencia(ref1, ref2)\nconsole.log(\"Valores originales\", ref1.valor,ref2.valor)\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/alexdevrep.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\n//Refiere a cómo se manejan los valores y las direcciones de memoria cuando se asignan variables en un programa\n\n//Asignación por valor\n/*\nEn la asignación por valor, se copia el contenido de la variable original en la nueva variable.\nLas dos variables son independientes y ocupan ubicaciones de memoria diferentes.\n */\nlet variableoriginal= 10\nlet variablecopia= variableoriginal //Asignación por valor\nvariableoriginal=20\n\nconsole.log(`La variable original ahora vale ${variableoriginal} mientras que la variable copia \nguarda el primer valor de la original en este caso ${variablecopia}`)\n\n//Asignación por referencia\n/*\nEn la asignación por referencia, la nueva variable hace referencia a la misma ubicación de memoria que la variable original.\n En este caso, cualquier cambio en una variable afectará a la otra, ya que comparten la misma ubicación de memoria.\n*/\n\nlet arrayoriginal = [\"Hola\",\"Alexdevrep\",\"Mundo\"]\nlet arraycopia = arrayoriginal\n\narraycopia[2] = \"JavaScript\" \n\nconsole.log (arrayoriginal)\n/*Como podemos obsevar aunque hayamos modificado el array copia tambien se modifica el original\nya que ambos apuntan a la misma ubicación de memoria */\n\n//Funciones con variables por valor\n\nfunction saludar(saludo){\n     let mi_saludo = `Hola, ${saludo}`\n    return mi_saludo\n}\n\nlet holamundo = \"JavaScript\"\nlet resultado = saludar(holamundo)\nconsole.log(holamundo) //La variable original no se modifica\nconsole.log(resultado)\n\n//Funciones con variables por referencia\n\nfunction agregarelemento(array,elemento){\n    array.push(elemento)\n\n}\n//Vamos a usar el arrayoriginal creado anteriormente\nagregarelemento(arrayoriginal,\"Mundo\")\nconsole.log(arraycopia)//Imprimimos el arraycopia para comprobar que efectivamente ambos array apuntan a la misma ubicación de la memoria\n\n\n//DIFICUALTAD EXTRA\n/* DIFICULTAD EXTRA (opcional):\n* Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n* - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n*   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n*   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n*   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n*   Comprueba también que se ha conservado el valor original en las primeras.\n*/\n\nlet valor1 = 3\nlet valor2 = 5\nlet objetoOriginal= { valor1: \"Hola\", valor2:\"JavaScript\"}\nlet objetoNuevo = programa2(objetoOriginal)\n\nfunction programa1 (valor1,valor2){\n    valor1 = 5\n    valor2 = 3\n    return [valor1, valor2]\n\n}\n\nfunction programa2 (objeto){\n    let intercambio =objeto.valor1\n    objeto.valor1=objeto.valor2\n    objeto.valor2 = intercambio\n    return objeto\n   \n}\n\nconsole.log (\"Resultado del programa 1: \")\nconsole.log (`El valor de la variables originales es ${valor1} para la variable valor1 y ${valor2} para la variable valor2`)\nlet [valor1nuevo, valor2nuevo] = programa1(valor1,valor2)\nconsole.log(\"El valor1 ahora será:\" + valor1nuevo)\nconsole.log(\"El valor2 ahora será:\"+valor2nuevo)\nconsole.log(\"-------------------------------------\")\nconsole.log (\"Resultado del programa 2: \")\n\nconsole.log (\"Valores originales:\", objetoOriginal.valor1,objetoOriginal.valor2)\nconsole.log (\"Valores nuevos:\", objetoNuevo.valor1,objetoNuevo.valor2)\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/andresgcastillo.js",
    "content": "// Asignación por valor\nlet var1 = 5;\nlet var2 = var1;\nvar2 = 10;\nconsole.log(var1); // Output: 5\nconsole.log(var2); // Output: 10\n\n// Asignación por referencia (objetos)\nlet obj1 = {name: \"John\"};\nlet obj2 = obj1;\nobj2.name = \"Jane\";\nconsole.log(obj1.name); // Output: Jane\nconsole.log(obj2.name); // Output: Jane\n\n// Asignación por referencia (arrays)\nlet arr1 = [1, 2, 3];\nlet arr2 = arr1;\narr2.push(4);\nconsole.log(arr1); // Output: [1, 2, 3, 4]\nconsole.log(arr2); // Output: [1, 2, 3, 4]\n\n// Funciones con paso por valor\nfunction increment(num) {\n  num++;\n  return num;\n}\n\nlet x = 5;\nlet y = increment(x);\nconsole.log(x); // Output: 5\nconsole.log(y); // Output: 6\n\n// Funciones con paso por referencia\nfunction changeName(obj) {\n  obj.name = \"Alice\";\n}\n\nlet person = {name: \"Bob\"};\nchangeName(person);\nconsole.log(person.name); // Output: Alice\n\n/*Dificultad Extra\nEn JavaScript, todos los parámetros se pasan por valor. Sin embargo, si pasas un objeto (incluyendo arrays y funciones), lo que se pasa es la referencia al objeto. Esto significa que si modificas las propiedades del objeto dentro de la función, esos cambios se reflejarán fuera de la función:\n*/\n\n// Programa 1: Pasando parámetros primitivos (por valor)\nfunction swapValues(val1, val2) {\n  let temp = val1;\n  val1 = val2;\n  val2 = temp;\n  return [val1, val2];\n}\n\nlet a = 5;\nlet b = 10;\nconsole.log(`Original a: ${a}, b: ${b}`); // Original a: 5, b: 10\n\nlet [newA, newB] = swapValues(a, b);\nconsole.log(`Swapped a: ${newA}, b: ${newB}`); // Swapped a: 10, b: 5\nconsole.log(`After swap a: ${a}, b: ${b}`); // After swap a: 5, b: 10\n\n// Programa 2: Pasando objetos (por referencia)\nfunction swapObjectValues(obj) {\n  let temp = obj.val1;\n  obj.val1 = obj.val2;\n  obj.val2 = temp;\n  return {val1: obj.val1, val2: obj.val2};\n}\n\nlet obj = {val1: 5, val2: 10};\nconsole.log(`Original obj.val1: ${obj.val1}, obj.val2: ${obj.val2}`); // Original obj.val1: 5, obj.val2: 10\n\nlet newObj = swapObjectValues(obj);\nconsole.log(`Swapped obj.val1: ${newObj.val1}, obj.val2: ${newObj.val2}`); // Swapped obj.val1: 10, obj.val2: 5\nconsole.log(`After swap obj.val1: ${obj.val1}, obj.val2: ${obj.val2}`); // After swap obj.val1: 10, obj.val2: 5\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/bernatcs.js",
    "content": "// ** EJERCICIO\n\n// Por valor\n\nlet m = 10;\nlet n = m; // b es una copia del valor de a\n\nm // 10\nn // 10\n\nn = 20;\nm // 10 (a no cambia)\nn // 20 (b cambia)\n\nfunction modifyValue(x) {\n    x = 20;\n    x // 20\n}\n\nlet y = 10;\nmodifyValue(y);\ny // 10 (y no cambia)\n\n// Por referencia\n\nlet o1 = {name: \"Alice\"};\nlet o2 = o1; // o2 es una referencia a o1\n\no1.name // Alice\no2.name // Alice\n\no2.name = \"Bob\";\no1.name // Bob (o1 cambia porque o2 es una referencia a o1)\no2.name // Bob\n\nfunction modifyObject(obj) {\n    obj.name = \"Charlie\";\n    obj.name // Charlie\n}\n\nlet person = {name: \"Alice\"};\nmodifyObject(person);\nperson.name // Charlie (person cambia)\n\n// ** DIFICULTAD EXTRA ** -----------------------------------------------------------------------------------------------------------------------------------------------\n\n// Intercambio por valor\nfunction intercambioPorValor(val1, val2) {\n    let temp = val1;\n    val1 = val2;\n    val2 = temp;\n    return [val1, val2];\n}\n\n// Intercambio por referencia\nfunction intercambioPorReferencia(ref1, ref2) {\n    let temp = {...ref1}; // Clonamos el objeto para evitar modificar los originales\n    ref1.name = ref2.name;\n    ref2.name = temp.name;\n    return [ref1, ref2];\n}\n\n// Variables primitivas (por valor)\nlet a = 5;\nlet b = 10;\n\nlet [newA, newB] = intercambioPorValor(a, b);\nconsole.log(newA, newB); // 10, 5 (intercambiadas)\nconsole.log(a, b); // 5, 10 (se mantienen iguales)\n\n// Objetos (por referencia)\nlet obj1 = { name: \"Alice\" };\nlet obj2 = { name: \"Bob\" };\nconsole.log(obj1.name, obj2.name); // Alice, Bob\n\nlet [newObj1, newObj2] = intercambioPorReferencia({ ...obj1 }, { ...obj2 });\nconsole.log(newObj1.name, newObj2.name); // Bob, Alice\nconsole.log(obj1.name, obj2.name); // Alice, Bob (se mantienen iguales)"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/carlosmares.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\n//Asignacion de variables\n\n// Asignacion de variables por valor\n\n/**\n * La Asignacion por valor sucede cuando a una variable le asignamos el valor de otra cuyo valor es un dato primitivo\n*/\n\nlet variablePorValor = 10;\nlet variableTemporal = variablePorValor;\nvariablePorValor = 20;\n\nconsole.log(variablePorValor);\nconsole.log(variableTemporal);\n\n//Asignacion de Variables por referencia\n\n/**\n * La asignacion por referencia sucede cuando a una variable le asignamos el valor de otra cuyo valor es un dato complejo \n*/\n\nlet x = {\n    a: 10,\n    b: 5\n};\n\nlet y = x;\n\nx.a = 20;\nx.b - 50;\n\nconsole.log(x);\n\n//Funciones que se pasen variables por valor y por referencia\n\n//Funcion que se le pasa una variable por valor\n\n/**\n * La diferencia entre pasar una variable por valor y por referencia es su relacion con lo que sucede dentro y fuera de la funcion\n * Cuando pasamos una variable por referencia lo que ocurre dentro de la funcion repercute fuera de ella\n * Mientas tanto cuando pasamos una variable por valor lo que ocurre dentro de la funcion se queda en la funcion, sin alterar el resto del codigo\n */\n\n//paso por valor\n\nlet valor = 18;\nconst funcionValor = (value) =>{\n    value = value * 10;\n    console.log('Dentro de la funcion, value es: ', value);\n}\nfuncionValor(valor);\nconsole.log('Fuera de la funcion, valor es: ', valor);\n\n//paso por referencia\nlet valor2 = 10;\nconst funcionValor2 = (value) =>{\n    valor2 = valor2 * 10;\n}\nconsole.log('Valor de la variable valor2 antes de ejecutar la funcion es: ', valor2);\nfuncionValor2(30);\nconsole.log('Valor de la variable valor2 despues de ejecutar la funcion es: ', valor2);"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/caterinarodriguezdev.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como\n * variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime\n *   el valor de las variables originales y las nuevas, comprobando que se ha invertido\n *   su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\n\nconst a = 10;\n\nconst modificandoCopia = (a) => a = 30;\n\n\nmodificandoCopia(a);\n\nconsole.log(a);\n\nconst p = {\n    nombre: 'Teseo'\n}\n\nconst modificandoReferencia = (p) => p.nombre = 'Egeo';\n\nmodificandoReferencia(p);\n\nconsole.log(p);\n\n\nconst edad = 25;\nconst nombre = 'Caterina';\n\nconst intercambioValores = (a, b) => {\n    let valorA = a;\n\n    a = b;\n    b = valorA;\n\n    return {a, b}\n}\n\nconst {a: edad2, b: nombre2} = intercambioValores(edad, nombre);\n\nconsole.log('antes:', edad, nombre);\nconsole.log('después:', edad2, nombre2);\n\nconst obj1 = { nombre: 'John B.'} \nconst obj2 = { nombre: 'Ada Lovelace'}\nconst intercambioReferencias = (obj1, obj2) => {\n\n    let temp = obj1;\n    obj1 = obj2;\n    obj2 = temp;\n\n    return {obj1, obj2}\n}\n\nconst {obj1: obj1Interchanged, obj2: obj2Interchanged} = intercambioReferencias(obj1, obj2);\n\nconsole.log('originales');\nconsole.log(obj1);\nconsole.log(obj2);\nconsole.log('intercambiados');\nconsole.log(obj1Interchanged);\nconsole.log(obj2Interchanged);"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/ceciliarava1.js",
    "content": "// Value assignment\nlet value = 'Hello'\n\n\nlet number = 1\n\nfunction valueFunction (number) {\n    number = 2\n    return number\n}\n\n// console.log(valueFunction(number))\n\n\n// Reference Assignment\nlet letter = 'a'\n\n\nlet array = ['a', 'e']\n\nfunction referenceFunction (array) {\n    array.push('hello')\n    return array\n}\n\n// console.log(referenceFunction(array))\n\n\n/* - Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n   - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n\n   - Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n          se asigna a dos variables diferentes a las originales. \n   - Imprime el valor de las variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n   - Comprueba también que se ha conservado el valor original en las primeras.\n*/\n\nlet aux = ''\n\nfunction valueProgram (value, number) {\n    aux = value\n    value = number\n    number = aux\n    return[`New value: ${value}, New number: ${number}`]\n}\n\nfunction referenceProgram (letter, array) {\n    aux = letter\n    letter = array\n    array = aux\n    return [`New letter: ${letter}, New array: ${array}`]\n}\n\nconsole.log(valueProgram(value, number))\nconsole.log(`Original value: ${value}`)\nconsole.log(`Original number: ${number}`)\n\nconsole.log(referenceProgram(letter, array))\nconsole.log(`Original letter: ${letter}`)\nconsole.log(`Original array: ${array}`)\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/cesar-ch.js",
    "content": "// #05 VALOR Y REFERENCIA\n\n// Asignación de variables por valor\nlet a = 10;\nlet b = a;\n\na = 5;\n\nconsole.log(a); // 5\nconsole.log(b); // 10\n\n// Asignación de variables por referencia\nlet x = { a: 10, b: 5 };\nlet y = x;\n\nx.a = 12;\nx.b = 24;\n\nconsole.log(x); // { a: 12, b: 24 }\nconsole.log(y); // { a: 12, b: 24 }\n\n// Función con parámetro por valor\nfunction cambiarValor(numero) {\n    numero = 100;\n    console.log(numero); // 100\n}\n\nlet numero = 5;\ncambiarValor(numero);\n\nconsole.log(numero); // 5\n\n// Función con parámetro por referencia\nfunction cambiarReferencia(objeto) {\n    objeto.a = 100;\n    console.log(objeto); // { a: 100 }\n}\n\nlet objeto = { a: 5 };\ncambiarReferencia(objeto);\n\nconsole.log(objeto); // { a: 100 }\n\n// Ejemplo que intercambia los valores de dos variables por valor\nfunction intercambiarValores(c, d) {\n    let temp = c;\n    c = d;\n    d = temp;\n\n    return [c, d];\n}\n\n// Ejemplo que intercambia los valores de dos variables por referencia\nfunction intercambiarReferencias(obj1, obj2) {\n    let temp = { ...obj1 };\n    let temp2 = { ...obj2 }\n    let temp3 = temp.value\n    temp.value = temp2.value\n    temp2.value = temp3\n    return [temp, temp2];\n}\n\n\nlet c = 10;\nlet d = 5;\nlet e = 10;\nlet objA = { value: 10 };\nlet objB = { value: 5 };\n\nlet [newc, newd] = intercambiarValores(c, d);\nconsole.log(\"Valores iniciales:\", c, d) // 10 5\nconsole.log(\"Valores por valor:\", newc, newd); // 5 10\n\n\nlet [newObjA, newObjB] = intercambiarReferencias(objA, objB);\nconsole.log(\"Valores iniciales:\", objA, objB) // { value: 10 } { value: 5 }\nconsole.log(\"Valores por referencia:\", newObjA, newObjB); // { value: 5 } { value: 10 }\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/christian-jfr.js",
    "content": "// #05 VALOR Y REFERENCIA\n\n/**\n * Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n * su tipo de dato.\n */\n\n// por valor: la variable se copia, no la referencia (con valores primitivos)\nlet numberOne = 10;\nlet numberTwo = numberOne;\n\nnumberOne += 2;\n\nconsole.log(numberOne, numberTwo); // -> 12, 10\n\nlet stringOne = 'Hello';\nlet stringTwo = stringOne;\n\nstringOne += ' JavaScript!';\n\nconsole.log(stringOne, stringTwo); // -> 'Hello JavaScript!', 'Hello'\n\nlet booleanOne = true;\nlet booleanTwo = booleanOne;\n\nbooleanOne = false;\n\nconsole.log(booleanOne, booleanTwo); // -> false, true\n\n// por referencia: el valor no se copia, lo que se asigna es la referencia (con objetos, arrays)\nlet personOne = {\n\tname: 'John',\n\tage: 37,\n};\nlet personTwo = personOne;\n\npersonOne.age = 38;\n\nconsole.log(personOne, personTwo); // -> { name: 'John', age: 38 }, { name: 'John', age: 38 }\n\nlet arrayOne = [10, 20, 30];\nlet arrayTwo = arrayOne;\n\narrayTwo.push(40);\n\nconsole.log(arrayOne, arrayTwo); // -> [10, 20, 30, 40], [10, 20, 30, 40]\n\nlet func1 = () => console.log('1');\nlet func2 = func1;\n\nfunc2 = () => console.log('2');\n\nconsole.log(func1(), func2()); // -> 1, 2\n\n/*\n *  Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y\n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n */\n\n// pasando valores primitivos en una funcion...\n// el valor que recibimos dentro de la función es siempre una “copia”,\n// lo que implica que cualquier mutación o re-asignación de los parámetros\n// dentro de una función no afecta al valor en el contexto de invocación.\n// Primitivos\nconst returnNumber = (num) => {\n\tnum = 0;\n\treturn num;\n};\n\nconst aNumber = 10;\n\nconsole.log(returnNumber(aNumber)); // -> 0\nconsole.log(aNumber); // -> 10\n\n// No Primitivos\nconst addSix = (arr) => {\n\tconst results = [];\n\tfor (let num of arr) {\n\t\tlet add6;\n\t\tadd6 = num + 6;\n\t\tresults.push(add6);\n\t}\n\treturn results;\n};\nconst arr = [1, 2, 3, 4];\n\nconsole.log(double(arr)); // -> [2, 4, 6, 8]\nconsole.log(arr); // -> [1, 2, 3, 4]\n\n/** referencia circular:\n * En estos ejemplos, la propiedad self del objeto user hace referencia a sí mismo.\n * Esto crea un ciclo infinito en el que el objeto user apunta a sí mismo y viceversa.\n *\n * Y el array students El método push(students) intenta agregar el mismo array students\n * como un nuevo elemento al final de sí mismo.\n * Esto crea una situación en la que el último elemento del array students apunta de nuevo\n * al propio array, formando un bucle cerrado o referencia circular.\n * */\nlet user = {\n\tname: 'Juan',\n\tage: 25,\n\tself: 'user',\n};\n\nuser.self = user;\nconsole.log(user); // -> { name: 'Juan', age: 25, self: [Circular *1] }\n\nlet students = ['John', 'Mark', 'Jane'];\nstudents.push(students);\n\nconsole.log(students); // -> ['John', 'Mark', 'Jane', [Circular *1]]\n\n/**\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\nlet valueOne = 'ONE';\nlet valueTwo = 'TWO';\nlet referenceOne = [1, 2, 3];\nlet referenceTwo = [4, 5, 6];\n\nfunction byValue(pam1, pam2) {\n\tlet pam1Temporal = pam1;\n\tpam1 = pam2;\n\tpam2 = pam1Temporal;\n\treturn [pam1, pam2];\n}\n\nlet changedValueOne = byValue(valueOne, valueTwo)[0];\nlet changedValueTwo = byValue(valueOne, valueTwo)[1];\n\nconsole.log(\n\t`Value One: ${valueOne} \n  \\nValue Two: ${valueTwo}\n  \\nChanged Value One: ${changedValueOne}\n  \\nChanged Value Two: ${changedValueTwo}`\n);\n// -> Value One: ONE\n// -> Value Two: TWO\n// -> Changed Value One: TWO\n// -> Changed Value Two: ONE\n\nfunction byReference(pam1, pam2) {\n\tlet pam1Temporal = pam1;\n\tpam1 = pam2;\n\tpam2 = pam1Temporal;\n\treturn [pam1, pam2];\n}\n\nlet changedReferenceOne = byReference(referenceOne, referenceTwo)[0];\nlet changedReferenceTwo = byReference(referenceOne, referenceTwo)[1];\n\nconsole.log(referenceOne); // -> [1, 2, 3]\nconsole.log(referenceTwo); // -> [4, 5, 6]\nconsole.log(changedReferenceOne); // -> [4, 5, 6]\nconsole.log(changedReferenceTwo); // -> [1, 2, 3]\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/cmejiajulian.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n */\n\n//tipos de datos por valor \n\n//Number\n\nlet = 10;\nlet = 209.1;\n\n//string \n\nlet magoDeOz = 'El Lago';\nlet aerosmith = 'Jaded ';\n\n//Bolean\n\nlet isIntelligent = true;\nlet isBoring = false;\n\n//null --> Representa la ausencia intencional de un valor.\n\nlet valorReal = null;\n\n//undefined --> Indica que una variable ha sido declarada pero no se le ha asignado un valor \n\nlet notAssigned;\n\n//Symbol --> Representa un valor unico y anonimo \n\nlet sym1 = Symbol('Suma');\nlet sym2 = Symbol('another description');\n\n// BigInt \n\nlet numValue = 2921129241294129439493949394n;\n\n//EJEMPLO DE COMPORTAMIENTO POR VALOR \n\n\nlet x = 10; \nlet y = x;\n\ny = 20; \n\nconsole.log(x);\nconsole.log(y);\n\n\n//tipos de datos por referencia \n\n//objecto \n\nlet cars =  {\n    name:'Mercedes',\n    model: 98,\n    kilometraje:1000\n\n}\n\nlet anotherCar = cars\n\nanotherCar.model = 2000\n\nconsole.log(cars.model);\nconsole.log(anotherCar.model);\n\n\n//array \n\nlet numbers = [1,2,3,4,5,6]\nlet numbersDiferent = numbers;\n\nnumbersDiferent.push(12);\n\nconsole.log(numbers);\nconsole.log(numbersDiferent);\n\n\n//function \n\nlet time =()=>{\n    console.log('Sunday');\n}\n\nlet othertime = time \n\nothertime()\n\n\n\n/* DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\n\n// Importa el módulo readline\nconst readline = require('readline');\n\n// Configura readline para que lea desde la terminal\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout\n});\n\n// PRIMER PROGRAMA Pregunta al usuario por el elemento \nrl.question('¿ingresa el elemento numero 1 por valor ? ', (valor1) => {\n    rl.question('¿ingresa el elemento numero 2 por valor ? ', (valor2) => {\n\n\n      var intercambioDeValor = (valor1,valor2) => {\n\n          if(!isNaN(parseFloat(valor1)) && !isNaN(parseFloat(valor2))) { \n             let inter = parseFloat(valor1);\n             (valor1) = parseFloat(valor2);\n             (valor2)= inter;\n             return[valor1,valor2];\n\n          } else {\n               let inter = valor1;\n               valor1 = valor2;\n               valor2 = inter;\n               return[valor1,valor2];\n              \n            }\n      }\n      let x = valor1;\n      let y = valor2;\n       \n\n      let [nuevoValor1,nuevoValor2] = intercambioDeValor(x,y);\nx\n\n   \n\n      console.log(`Valor Original 1 : ${x}, Valor Original 2: ${y}`);\n      console.log(`Nuevo Valor Original 1: ${nuevoValor1}, Nuevo Valor Original 2: ${nuevoValor2}`);\n      \n\n    \n   \n    // Cierra la interfaz de readline\n   \n// SEGUNDO PROGRAMA  Pregunta al usuario por el valor por referencia \n\n\n    rl.question('¿Ingresa el elemento número 1 por Referencia: ', (referencia1) => {\n        rl.question('Ingresa el elemento número 2 por Referencia',(referencia2 )=>{\n            \n          let intercambioPorReferencia = (ref) => {\n            let inter = ref[0];\n            ref[0] = ref[1];\n            ref[1] = inter;\n        }\n\n        let variableR = [referencia1, referencia2];\n        let variableRO = [...variableR]; // Crea una copia de variableR\n\n        intercambioPorReferencia(variableRO);\n\n        console.log(`Variable original 1: ${variableR[0]}, Variable original 2: ${variableR[1]}`);\n        console.log(`Nuevo valor 1: ${variableRO[0]}, Nuevo valor 2: ${variableRO[1]}`);\n      // Cierra la interfaz de readline\n      rl.close();\n      })\n    });\n  });\n});\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/duendeintemporal.js",
    "content": "//Exercice #5 Valor y Referencia\n// I use GPT for translation. generate comments an also as a reference.\n\nlet log = console.log.bind(console);\n\n//Variables by Value\n\n/*Primitive data types in JavaScript (such as number, string, boolean, null, undefined, and symbol) are assigned by value. This means that when you assign a primitive value to a variable, a copy of that value is made.*/\n\nlet a = 44; // a is a number (primitive type)\nlet b = a;  // b is assigned the value of a\n\nlog(a); //  44\nlog(b); //  44\n\nb += 20; // Changing b does not affect a\nlog(a); //  44\nlog(b); //  64\n\n//Variables by Reference\n\n/*Reference data types in JavaScript (such as object, array, and function) are assigned by reference. This means that when you assign an object to a variable, you are actually assigning a reference to that object, not a copy of it.*/\n\n\nlet obj1 = { name: \"Julia\" }; // obj1 is an object (reference type)\nlet obj2 = obj1; // obj2 is assigned the reference of obj1\n\nlog(obj1.name); //  Julia\nlog(obj2.name); //  Julia\n\nobj2.name = \"Karla\"; // Changing obj2 affects obj1 because they reference the same object\nlog(obj1.name); //  Karla\nlog(obj2.name); //  Karla\n\nobj2.age = 32;\nlog(obj2.age)// 32\nlog(obj1.age)// 32\n\n//Arrays (Reference Type) in JavaScript are also reference types.\n\nlet arr1 = [7, 4, 90]; // arr1 is an array (reference type)\nlet arr2 = arr1; // arr2 is assigned the reference of arr1\n\nlog(arr1); //  [7, 4, 90]\nlog(arr2); //  [7, 4, 90]\n\narr2.push(42); // Modifying arr2 affects arr1\nlog(arr1); //  [7, 4, 90, 42]\nlog(arr2); //  [7, 4, 90, 42]\n\n/*    By Value: Primitive types (e.g., number, string) are copied when assigned to a new variable.\n    By Reference: Reference types (e.g., object, array) are assigned by reference, meaning changes to one variable affect the other if they reference the same object. */\n\n  /*  In JavaScript, functions are also treated as first-class objects, which means they can be assigned to variables, passed as arguments, and returned from other functions. When you assign a function to a variable, you are assigning a reference to that function, not a copy of it. Here are some examples to illustrate how functions work with reference: */\n    \n    //Functions Assigned by Reference\n    \n    //When you assign a function to a new variable, both variables point to the same function in memory.\n        \n    function greet() {\n        log(\"Hello everybody! is time for coding...\");\n    }\n    \n    let greetCopy = greet; // greetCopy is assigned the reference of greet\n    \n    greet();      // Hello everybody! is time for coding...\n    greetCopy();  // Hello everybody! is time for coding...\n    \n    // Changing the function reference\n    greetCopy = function() {\n        log(\"This world is turning into a weird scenario with all those AIs, M2M (technology), and there are cyber attacks that can explode beepers, cell phones, and a big media that shows only a tiny fragment of reality. \");\n    };\n    \n    greet();      // Hello everybody! is time for coding...\n    greetCopy();  //This world is turning into a weird scenario with all those AIs, M2M (technology), and there are cyber attacks that can explode beepers, cell phones, and big media that shows only a tiny fragment of reality.\n    \n    // Passing Functions as Arguments\n    \n    //You can pass functions as arguments to other functions. This demonstrates that functions are treated as reference types.\n    \n       \n    function callFunct(fn) {\n        fn();\n    }\n    \n    function sayByeLady() {\n        log(\"See you later, lady!\");\n    }\n    \n    callFunct(sayByeLady); // See you later, lady\n    \n    //Returning Functions from Functions\n    \n    //You can also return functions from other functions, which shows that functions can be created dynamically and assigned by reference.\n    \n        \n    function saySomethingTo(greeting) {\n        return function(name) {\n            log(`${greeting}, ${name}!`);\n        };\n    }\n    \n    let say = saySomethingTo(\"Wellcome to coding lab\");\n    let say2 = saySomethingTo(\"Is a long way home\");\n    \n    say(\"Nicky\"); // Wellcome to coding lab, Nicky\n    say2(\"Jhon\");      // Is a long way home, Jhon\n    \n    //  Modifying Functions\n    \n    //Since functions are reference types, if you modify a function that is referenced by multiple variables, it will affect all references.\n    \n    function hiMiss() {\n        log(\"Hello, miss. Have a beautiful day\");\n    }\n    \n    let funcRef = hiMiss; // funcRef points to hiMiss\n    \n    funcRef(); //  Hello, miss, have a beautiful day\n    \n    // Modifying the original function\n    hiMiss = function() {\n        log(\"Sometimes I feel jealous of the wind that caresses your hair, sometimes the rain....\");\n    };\n    \n    funcRef(); //  Hello, miss, have a beautiful day (still points to the original function)\n\n    //but if we fro example...\n    funcRef = ()=>{\n     return hiMiss;\n    }\n\n    funcRef()()// Sometimes I feel jealous of the wind that caresses your hair, sometimes the rain.... (now every change in hiMiss will be reflexted)\n    \n\n/*  In JavaScript, when you pass arguments to a function, the behavior depends on whether the argument is a primitive type (passed by value) or a reference type (passed by reference). Here’s an example that demonstrates both concepts:  */\n      \n\n// Function that takes a primitive type (passed by value)\nfunction doSomething(value) {\n    value = 20; // This change does not affect the original variable\n    log(\"Value Inside doSomething:\", value); // Value Inside doSomething: 20\n}\n\n// Function that takes an object (passed by reference)\nfunction setUserName(obj, name) {\n    obj.name = name; // This change affects the original object\n    log(\"Value Inside setUserName:\", obj.name); \n}\n\n// Testing the functions\nlet num = 'something';\nlog(\"Value Before doSomething:\", num); // Value Before doSomething: something\ndoSomething(num);\nlog(\"After doSomething:\", num); // After doSomething: something (remains unchanged)\n\nlet user = { name: \"Luna\", age: 32 };\nlog(\"Before setUserName:\", user.name); // Before setUserName: Luna\nsetUserName(user, 'Kia'); // Value Inside setUserName: Kia\nlog(\"After setUserName:\", user.name); // After setUserName: Kia (changed)\n\n//Note: the same apply to arrays that are reference values.\n\nwindow.addEventListener('load', ()=>{\n    const body = document.querySelector('body');\n    const title = document.createElement('h1');\n    \n    body.style.setProperty('background', '#000');\n    body.style.setProperty('text-align', 'center');\n    \n    title.textContent = 'Retosparaprogramadores #5.';\n    title.style.setProperty('font-size', '3.5vmax');\n    title.style.setProperty('color', '#fff');\n    title.style.setProperty('line-height', '100vh');\n    \n    body.appendChild(title);\n    \n    setTimeout(()=>{\n    alert('Retosparaprogramadores #5. Please open the Browser Developer Tools.');\n    }, 2000);\n    log( 'Retosparaprogramadores #5'); // this will be logged at the end cause the nature of window event\n});\n\n\n/* EXTRA DIFFICULTY (optional):\n\n    Create two programs that receive two parameters (each) defined as variables previously.\n    One program receives, in one case, two parameters by value, and in another case, by reference.\n    These parameters are swapped between each other internally, returned, and their return values are assigned to two variables different from the originals. Then, print the value of the original variables and the new ones, checking that their values have been inverted in the second set.\n    Also verify that the original values have been preserved in the first set.\n */\n\nlet user1 = {\n    name: 'Kasperle',\n    age: 12\n}\n\nlet user2 = {\n    name: 'Snoopy',\n    age: void(0)\n}\n\nlog('user1: ', user1);// user1: Object { name: \"Kasperle\", age: 12 }\nlog('user2: ', user2);// user2: Object { name: \"Snoopy\", age: undefined }\n\nfunction changeUser(obj1, obj2) {\n   const provisional = {};\n    Object.assign(provisional, obj1);// Object.assign allow a deep copy\n    Object.assign(obj1, obj2);\n    Object.assign(obj2, provisional);\n   // return [obj1, obj2] \n   // We can return the objects in an array, but it becomes unnecessary because objects are treated as reference values. \n   // Therefore, the function will affect the original objects directly.\n}\n\nchangeUser(user1, user2)\n\nlog('user1: ', user1);// user1: Object { name: \"Snoopy\", age: undefined }\nlog('user2: ', user2);// user2: Object { name: \"Kasperle\", age: 12 }\n\nfunction swapValues(a, b) {\n    return { a: b, b: a };    // using destructuring to return the swapped values as an object\n}\n\n//You can call the function and use destructuring to assign the returned values to new variables:\n\nlet x = 85;\nlet y = 17;\n\nlog(\"Before swap: \", x, y);// Before swap: 85 17\n\n// Call the function and destructure the returned object\n({ a: d, b: e } = swapValues(x, y));\n\nlog(\"After swap: \", x, y);// After swap:  85 17\nlog('new variables with values swapped: ', d, e)// new variables with values swapped: 17 85\n\n//Note: destructuring allow us to achive the effect of reference values with primitive values. Say using destructuring we can achive both effects. Conserving the originals values or swapping the values.\nlog(\"Before swap: \", x, y);// Before swap:  85 17\n({ a: x, b: y } = swapValues(x, y));\n\nlog(\"After swap: \", x, y);// After swap: 17 85\n\n\n//Note: using destructuring we can achive both effects. Conserving the originals values or swapping the values\n\n//Note2: have in mind that when you use destructuring you make a shallow copy, it means that if are object nested inside, the nested ones don't be copied"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/emedevelopa.js",
    "content": "// Valor y referencia\n\n//Primitivos\n\nlet nombre = \"León\";\nlet nombre1 = nombre;\nnombre += \" Pérez\";\nconsole.log(nombre);\nconsole.log(nombre1);\n\nlet edad = 13;\nlet edad1 = edad;\nedad += \" años\";\nconsole.log(edad);\nconsole.log(edad1);\n\n//Objetos y Arrays\n\nlet myArray = [1, 2, 3];\nlet myArray2 = myArray;\n\nmyArray.push(4);\nconsole.log(myArray);\nconsole.log(myArray2);\n\nlet myObject = {nombre: \"Marea\", edad: 9};\nlet myObject1 = myObject;\n\nmyObject.edad = 12;\nconsole.log(myObject);\nconsole.log(myObject1);\n\n//EXTRA\n\n//Por valor\nlet comida = \"Macarrones\";\nlet comida1 = \"Lentejas\";\n\nfunction cambio (param1, param2) {\n    let temp = param1;\n    param1 = param2;\n    param2 = temp;\n\n    return {param1, param2};\n}\n\nlet resultado = cambio (comida, comida1);\nlet {param1: nuevoValor1, param2: nuevoValor2} = resultado;\n\nconsole.log(comida);\nconsole.log(comida1);\nconsole.log(nuevoValor1);\nconsole.log(nuevoValor2);\n\n//Por referencia\nlet niña1 = { nombre: \"Ana\", color: \"rosa\" };\nlet niña2 = { nombre: \"Lucia\", color: \"Verde\" };\n\n\nfunction intercambio2(param1, param2) {\n    let temp1 = param1;\n    param1 = param2;\n    param2 = temp1;\n    \n    return { param1, param2 };\n}\n\nlet resultado1 = intercambio2(niña1, niña2);\n\nlet { param1: nuevoValor3, param2: nuevoValor4 } = resultado1;\n\n    console.log(niña1); \n    console.log(niña2); \n    console.log(nuevoValor3); \n    console.log(nuevoValor4); "
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/eulogioep.js",
    "content": "// Ejemplos de Valor y Referencia en JavaScript\n\n// Función para imprimir resultados\nfunction print(message) {\n    console.log(message);\n}\n\n// Ejemplos de asignación por valor (tipos primitivos)\nlet a = 5;\nlet b = a; // b es una copia del valor de a\nb = 10; // Cambiar b no afecta a a\nprint(`Asignación por valor: a: ${a}, b: ${b}`); // a: 5, b: 10\n\n// Ejemplos de asignación por referencia (objetos y arrays)\nlet arr1 = [1, 2, 3];\nlet arr2 = arr1; // arr2 apunta al mismo array que arr1\narr2[0] = 100; // Cambiar arr2 afecta a arr1\nprint(`Asignación por referencia: arr1[0]: ${arr1[0]}, arr2[0]: ${arr2[0]}`); // arr1[0]: 100, arr2[0]: 100\n\n// Función con parámetro por valor\nfunction modificarValor(n) {\n    n = 100; // Este cambio no afecta a la variable original\n}\n\nlet x = 5;\nmodificarValor(x);\nprint(`x después de modificarValor: ${x}`); // x no cambia\n\n// Función con parámetro por referencia\nfunction modificarReferencia(arr) {\n    arr[0] = 100; // Este cambio afecta al array original\n}\n\nlet array = [1, 2, 3];\nmodificarReferencia(array);\nprint(`array[0] después de modificarReferencia: ${array[0]}`); // array[0] cambia\n\n// DIFICULTAD EXTRA\n// Función para intercambio por valor\nfunction intercambioPorValor(a, b) {\n    let temp = a;\n    a = b;\n    b = temp;\n    return [a, b];\n}\n\n// Función para intercambio por referencia\nfunction intercambioPorReferencia(obj) {\n    let temp = obj.a;\n    obj.a = obj.b;\n    obj.b = temp;\n    return { a: obj.a, b: obj.b };\n}\n\n// Programa 1: Intercambio por valor\nlet num1 = 10, num2 = 20;\nprint(`Antes del intercambio por valor: num1 = ${num1}, num2 = ${num2}`);\nlet [nuevoNum1, nuevoNum2] = intercambioPorValor(num1, num2);\nprint(\"Después del intercambio por valor:\");\nprint(`Variables originales: num1 = ${num1}, num2 = ${num2}`);\nprint(`Nuevas variables: nuevoNum1 = ${nuevoNum1}, nuevoNum2 = ${nuevoNum2}`);\n\n// Programa 2: Intercambio por referencia\nlet obj = { a: 30, b: 40 };\nprint(`\\nAntes del intercambio por referencia: obj.a = ${obj.a}, obj.b = ${obj.b}`);\nlet nuevoObj = intercambioPorReferencia(obj);\nprint(\"Después del intercambio por referencia:\");\nprint(`Objeto original: obj.a = ${obj.a}, obj.b = ${obj.b}`);\nprint(`Nuevo objeto: nuevoObj.a = ${nuevoObj.a}, nuevoObj.b = ${nuevoObj.b}`);"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/garos01.js",
    "content": "// Ejemplo por valor\nlet num1 = 10;\nlet num2 = num1;\n\nconsole.log(num1);\nconsole.log(num2);\n\nnum2 = 20;\n\nconsole.log(num1);\nconsole.log(num2);\n\n// Ejemplo por referencia\nlet array1 = [1, 2, 3];\nlet array2 = array1;\n\nconsole.log(array1);\nconsole.log(array2);\n\narray2.push(4);\n\nconsole.log(array1);\nconsole.log(array2);\n\n// Ejemplo funciones por valor\nfunction incrementar(numero) {\n  numero++;\n}\n\nlet a = 5;\nincrementar(a);\n\nconsole.log(a);\n\n// Ejemplo funciones por referencia\nfunction agregarElemento(array) {\n  array.push(4);\n}\n\nlet b = [1, 2, 3];\nagregarElemento(b);\n\nconsole.log(b);\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/gianbordon.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\n//\n// Asignar por valor\n//\n\nlet a = 8\nlet b = 10\n\nconsole.log(a)\nconsole.log(b)\n\n//\n// Por Referencia \n//\n\nb = 20\nlet obj1 = { name: \"Gian\", age: 20}\nlet obj2 = obj1\n\nobj2.name = \"David\"\n\nconsole.log(b)\nconsole.log(obj1)\nconsole.log(obj2)\n\n//\n// Cambiar valor por medio de una Funcion \n//\n\nfunction changeValor(num){\n    return num + 4\n}\n\nconsole.log(changeValor(4))\n\n//\n// Cambiar un valor por referencia por medio de una funcion \n//\n\nfunction changeName(obj,name){\n    obj.name = name\n    return obj \n}\n\nconsole.log(changeName(obj2,\"Jean\"))\n\n//\n// EXTRA\n//\n\nlet num1 = 4\nlet num2 = 8\n\nfunction invertPos (num1, num2){\n    tem1 = num2\n    tem2 = num1\n    return [tem1,tem2]\n}\n\nlet [num3, num4] = invertPos(num1,num2)\n\nconsole.log(`Originales: num1 = ${num1}, num2 = ${num2}`);\nconsole.log(`Nuevos: num3 = ${num3}, num4 = ${num4}`);\n\nlet per1 = { name: \"Juan\", age: 26 };\nlet per2 = { name: \"Fran\", age: 26 };\n\nfunction invertName(obj1, obj2) {\n    let temObj1 = { ...obj1 };\n    let temObj2 = { ...obj2 };\n\n    let tem = temObj1.name;\n    temObj1.name = temObj2.name;\n    temObj2.name = tem;\n\n    return [temObj1, temObj2];\n}\n\nlet [per3, per4] = invertName(per1, per2);\n\nconsole.log(`Originales: per1 = ${per1.name}, per2 = ${per2.name}`);\nconsole.log(`Nuevos: per3 = ${per3.name}, per4 = ${per4.name}`);"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/giovanyosorio.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\n\n// Asignación de variables por valor y por referencia\nvar a = 1;\nvar b = a; // Asignación por valor\na = 2;\nconsole.log(b); // 1\n\nvar c = { value: 1 };\nvar d = c; // Asignación por referencia\nc.value = 2;\nconsole.log(d.value); // 2\n\n// Funciones con variables por valor y por referencia\nfunction changeValue(val) {\n    val = 2;\n}\nvar e = 1;\nchangeValue(e);\nconsole.log(e); // 1\n\nfunction changeObjectValue(obj) {\n    obj.value = 2;\n}\nvar f = { value: 1 };\nchangeObjectValue(f);\nconsole.log(f.value); // 2\n\n// DIFICULTAD EXTRA\nfunction swapValuesByValue(a, b) {\n    var temp = a;\n    a = b;\n    b = temp;\n    return [a, b];\n}\nvar g = 1;\nvar h = 2;\nvar swappedValues = swapValuesByValue(g, h);\nconsole.log(g); // 1\nconsole.log(h); // 2\nconsole.log(swappedValues[0]); // 2\nconsole.log(swappedValues[1]); // 1\n\nfunction swapValuesByReference(a, b) {\n    var temp = a.value;\n    a.value = b.value;\n    b.value = temp;\n    return [a, b];\n}\nvar i = { value: 1 };\nvar j = { value: 2 };\nvar swappedObjects = swapValuesByReference(i, j);\nconsole.log(i.value); // 2\nconsole.log(j.value); // 1\nconsole.log(swappedObjects[0].value); // 2\nconsole.log(swappedObjects[1].value); // 1\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/gonzadev28.js",
    "content": "//Asignacion por valor\n//*Esto sucede en variables de tipo primitivos (string, number, boolean, etc)\n\nlet deporte = 'running';\nlet deporte2 = deporte;\n\ndeporte = 'ciclismo';\n\nconsole.log(deporte);//Se cambia el valor de la variable de 'running' a 'ciclismo'\nconsole.log(deporte2);//Sigue mostrando 'running' porque es el primer valor con el que fue declarado\n\n//Asignacion por referencia \n//*Esto sucede en tipos de datos objetos (objeto, array, funcion)\n\nlet zapatilla = {\n    marca: 'Adidas'\n}\nlet modelo = zapatilla;\n\n// console.log(zapatilla); *Se imprimen ambas variables con los mismos valores*\n// console.log(modelo);\n\nzapatilla.marca = 'Nike';//Se cambia el valor de marca\n\nconsole.log(zapatilla);//Ambos pasan a cambiar su valor en marca\nconsole.log(modelo);\n\n//Funcion con asignacion por valor\n\n function xValor(n1){\n    n1 = 12345;\n    console.log(n1);\n }\n xValor();\n\nn1 = 54321;\nxValor(); //No se modifica el valor de n1.\n\nconsole.log(n1); //Se imprime el nuevo valor de n1.\n\n//Funcion con asignacion por referencia.\n\nfunction xReferencia(lista){\n    lista.push(4);\n}\nlet miArray = [1, 2, 3];\nxReferencia(miArray);\nconsole.log(miArray);\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/hectorio23.js",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\n\"use strict\";\n\n// #############################################################\n// #################### DEFINICIÓN DE FUNCIONES ################\n// #############################################################\n\nfunction sumaReferencia(value1, value2) {\n    // Imprime a su vez la variable y su dirección de memoria\n    console.log(\"*** Dentro de la funcion que recibe valores por referencia ***\");\n    console.log(`&a  ->   ${value1}`);\n    console.log(`&b  ->   ${value2}`);\n    return value1 + value2;\n}\n\nfunction sumaCopia(value1, value2) {\n    // Imprime a su vez la variable y su dirección de memoria\n    console.log(\"\\n*** Dentro de la funcion que recibe valores por copia ***\");\n    console.log(`a   ->   ${value1}`);\n    console.log(`b   ->   ${value2}`);\n    return value1 + value2;\n}\n\nfunction intercambioValoresReferencia(value1, value2) {\n    return [value2, value1];\n}\n\nfunction intercambioCopia(value1, value2) {\n    return [value2, value1];\n}\n\n// #############################################################\n// ################## PROGRAMA PRINCIPAL #######################\n// #############################################################\n\n// Variables las cuales se van a usar como conejillos de indias\nlet numero = 94;\nlet numero2 = 6;\n\n// En esta sección se imprimirán la dirección en memoria de las variables\nconsole.log(\"*** Estos son las direcciones en memoria de las variables previamente definidas***\");\nconsole.log(`Ubicación en memoria de numero: ${numero}`);\nconsole.log(`Ubicación en memoria de numero2: ${numero2}`);\n\nsumaReferencia(numero, numero2);\nsumaCopia(numero, numero2);\n\nconsole.log(\"\\n******************\\n\");\n\nconsole.log(\"Valor de las variables originales\");\nconsole.log(`a -> ${numero}`);\nconsole.log(`b -> ${numero2}`);\n\n// Después de hacer el cambio de variables mediante una función que recibe los parámetros por copia\nlet resultadoCopia = intercambioCopia(numero, numero2);\nlet copia1 = resultadoCopia[0];\nlet copia2 = resultadoCopia[1];\n\nconsole.log(\"\\nValor de las variables después de hacer un intercambio de valores (copia)\");\nconsole.log(\"Variables originales\");\nconsole.log(`a -> ${numero}`);\nconsole.log(`b -> ${numero2}`);\nconsole.log(\"Variables retornadas\");\nconsole.log(`copia a -> ${copia1}`);\nconsole.log(`copia b -> ${copia2}`);\n\n// Después de hacer el cambio de variables mediante una función que recibe los parámetros por referencia\nlet resultadoReferencia = intercambioValoresReferencia(numero, numero2);\nlet referencia1 = resultadoReferencia[0];\nlet referencia2 = resultadoReferencia[1];\n\nconsole.log(\"\\nValor de las variables después de hacer un intercambio de valores (referencia)\");\nconsole.log(\"Variables originales\");\nconsole.log(`a -> ${numero}`);\nconsole.log(`b -> ${numero2}`);\nconsole.log(\"Variables retornadas\");\nconsole.log(`copia a -> ${referencia1}`);\nconsole.log(`copia b -> ${referencia2}`);\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/jaxi86.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\nconsole.log(\"asignacion por valor\");\nlet numero1 = 66;\nlet numero2 = numero1;\nconsole.log(numero1);\nconsole.log(numero2);\n\nconsole.log(\" \");\n\nconsole.log(\"asinacion por referencia\");\nlet usuario1 = {\n    nombre: \"jaxi\",\n    edad :33,\n    correo : \"jaxijax86@gmail.com\",\n}\nlet usuario2 = usuario1;\nconsole.log(usuario1);\nconsole.log(usuario2);\n\nconsole.log(\" \");\n\nconsole.log(\"funciones con variables que se les pasan por valor y por referencia\");\nlet valor = 11;\nlet referencia = {\n    nombre:\"george\",\n    edad : 21,\n}\nconsole.log(valor);\nconsole.log(referencia);\n\nfunction funVariable (numero, persona) {\n    numero *=2;\n    console.log(numero);//aqui se imprime el valor de numero que ahora es 11 x 2 = 22\n    console.log(valor);//aqui imprime valor que como ya sabemos sigue siendo 11 porque el unico que cambio de valor es numero y la variable valor se queda como estaba\n    persona.nombre = \"jhon\";//por en cambio aqui le cambio el valor a una propiedad de referencia que tambien se llama persona y se cambia el valor de esa propiedad en persona y referencia (porque los objetos al igual que los array son datos de tipo de referencia o compuesto) como se ve a continuacion \n    console.log(persona);\n    console.log(referencia);\n\n}\nfunVariable(valor, referencia)\n\nconsole.log(\" \");\n\nconsole.log(\"DIFICULTAD EXTRA\");\nlet color1 = \"rojo\";\nlet color2 = \"azul\";\nfunction intervalor (param1, param2) {\n    param1 = color2;\n    param2 = color1;\n    let color3 = param1;\n    let color4 = param2;\n    return {color3, color4};\n}\nlet resultado = intervalor(color1, color2);\nconsole.log(resultado, color1, color2);//aqui se imprime las nuevas variables y las originales\n\nlet persona = {nombre: 'jaxi', edad : 25,};\nlet compras = ['leche', 'pollo', 'queso'];\nfunction inter_refe (param1, param2) {\n    param1 = compras;\n    param2 = persona;\n    let erapersona = param1;\n    let eracompras = param2;\n    return {erapersona, eracompras};\n}\nlet resultado2 = inter_refe(persona, compras);\nconsole.log(resultado2);//aqui imprimo las variables nuevas\nconsole.log(persona, compras);//aqui imprimo las variavles originales\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/jeronimocardu.js",
    "content": "// Variables de asignacion por valor - PRIMITIVOS\n// Se crea una copia del valor original\nlet numero1 = 1;\nlet letra1 = 'A';\nlet verdad1 = true;\nlet indefinido1 = undefined;\nlet nulo1 = null;\n\nlet numero2 = numero1;\nlet letra2 = letra1;\nlet verdad2 = verdad1;\nlet indefinido2 = indefinido1;\nlet nulo2 = nulo1;\n\n// Variables de asignacion por referencia\n// Ambas variables apuntan al mismo espacio en la memoria\nlet arreglo1 = [1, 2, 3];\nlet objecto = {nombre: 'Jeronimo'};\nlet esFuncion = function funcion(){}\n\nlet arreglo2 = arreglo1;    // arreglo2 = [1, 2, 3]\narreglo2.pop();             // Se modifica el lugar en la memoria\nconsole.log(arreglo1)       // [1, 2]\nconsole.log(arreglo2)       // [1, 2]\n\n////////////////////////////////////////////////////\n//                  EXTRA\n\nfunction porValor(value1, value2){\n    let temp = value1;\n    value1 = value2\n    value2 = temp;\n    return [value1, value2];\n}\nfunction porReferencia(ref1, ref2){\n    let temp = ref1;\n    ref1 = ref2;\n    ref2 = temp;\n    return [ref1, ref2]\n}\n\n\nlet primerV = 'Hola';\nlet segV = 2;\nlet primerRef = [1, 2, 3];\nlet segRef = [4, 5, 6];\n\nlet newFirstValor = porValor(primerV, segV)[0];\nlet newSecondValor = porValor(primerV, segV)[1];\nlet newFirtsRef = porValor(primerRef, segRef)[0];\nlet newSecondRef = porValor(primerRef, segRef)[1];\n\nconsole.log(`\n    POR VALOR \n    original = ${primerV}, ahora es ${newFirstValor};\n    original = ${segV}, ahora es ${newSecondValor};\n    \n    POR REFERENCIA\n    original = ${primerRef}, ahora es ${newFirtsRef};\n    original = ${segRef}, ahora es ${newSecondRef};\n    `)\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/jhoshmc.js",
    "content": "function ejercicio() {\n  let val = \"hola\";\n  console.log(`texto original: ${val}`);\n  f_valor(val);\n  console.log(`texto en variable original: ${val}`);\n  console.log(`\\n asignacion de  valores por referencia`);\n  f_referencia();\n}\n\nfunction f_valor(val) {\n  /**\n   ** cuando se pasa una variable por valor, se pasa una copia de esta, si se modifica,\n   ** esto solo afectaria a la copia, mas a la variable original no\n   */\n  console.log(`\\ntexto pasado: ${val}`);\n  val = \"adios\";\n  console.log(`texto modificado: ${val}`);\n}\n\nfunction f_referencia() {\n  /**\n   ** cuando se pasa un valor por referencia, se pasa la ubicacion de donde está guardado esa\n   ** variable en la memoria, si se modifica algo, si afectaria a la variable\n   ** en javascript , los objetos y arreglos se manejan por referencias\n   **Cuando asignas un objeto o un arreglo a una variable, en realidad\n   ** estás asignando una referencia a la ubicación en memoria donde se almacena ese objeto o arreglo.\n   * *Modificar el objeto o arreglo a través de una variable\n   ** también afectará a otras variables que hagan referencia al mismo objeto o arreglo.\n   */\n  let obj1 = {\n    nombre: \"juan\",\n    edad: 15,\n  };\n  console.log(`obj1 :`);\n  console.log(obj1);\n  //* como le estoy pasando la direccion de memoria de obj1 a obj2, estan compartiendo o mejor dicho\n  //* tinene el mismo espacio en la memoria, asi que si modificamos obj2, tambian se modificará obj1\n  let obj2 = obj1;\n  obj2.nombre = \"andres\";\n  console.log(`obj1 modificado:`);\n  console.log(obj2);\n  //* lo mismo se puede hacer en un array\n  let arr = [1, 2, 3, 4, 5];\n  console.log(\"arr: \");\n  console.log(arr);\n  let arr_2 = arr;\n  arr_2.pop();\n  console.log(\"arr modificado: \");\n  console.log(arr);\n\n  //* pasando valores por referencia\n\n  function modificarObjeto(obj) {\n    obj.propiedad = \"nuevo valor\";\n  }\n\n  let obj = {\n    propiedad: \"valor original\",\n  };\n  console.log(\"obj original: \");\n  console.log(obj);\n  modificarObjeto(obj);\n  console.log(\"obj modificado: \");\n  console.log(obj);\n}\n\n// ejercicio();\n\nfunction extra() {\n  let v1 = 1;\n  let v2 = 2;\n  console.log(`valor original 1: ${v1}`);\n  console.log(`valor original 2: ${v2}`);\n  let [c1, c2] = cambio_valor(v1, v2);\n  console.log(\"\\n\");\n  console.log(`copia valor 1: ${c1}`);\n  console.log(`copia valor 2: ${c2}`);\n  console.log(\"\\n\");\n  let r1 = [1];\n  let r2 = [2];\n  console.log(`valor original de r1: ${r1[0]}`);\n  console.log(`valor original de r2: ${r2[0]}`);\n  console.log(\"\\n\");\n  let [cr1, cr2] = cambio_referencia(r1, r2);\n  console.log(`el valor de cr1 es: ${cr1[0]}`);\n  console.log(`el valor de cr2 es: ${cr2[0]}`);\n  console.log(\"\\n\");\n  console.log(`el valor de r1: ${r1[0]}`);\n  console.log(`el valor de r2: ${r2[0]}`);\n}\n\nfunction cambio_valor(v1, v2) {\n  let aux = v1;\n  v1 = v2;\n  v2 = aux;\n  return [v1, v2];\n}\n\nfunction cambio_referencia(r1, r2) {\n  let aux = r1[0];\n  r1[0] = r2[0];\n  r2[0] = aux;\n  return [r1, r2];\n}\n\nextra();\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/joapalobael.js",
    "content": "// Asignacion de variables por valor\nlet valor1 = 25;\nconsole.log(`Asignación de variable por valor → valor1 = ${valor1}.`)\n\n//Asignación de variables por referencia\n\nlet objeto1 = {nombre: \"Johanna\", edad: 30, signo: \"Cancer\"};\nobjetoReferencia = objeto1;\nobjetoReferencia.edad = 36;\nconsole.log(`Asignación de variable por referencia → objetoReferencia = ${JSON.stringify(objeto1)}.`);\n\n//Funciones con variables por valor\nfunction descuento10(fullPrize) {\n    fullPrize = fullPrize-fullPrize*0.10;\n    return fullPrize;\n}\n\nlet precioOriginal = 1480;\nlet precioConDescuento = descuento10(precioOriginal);\n\nconsole.log(`El precio original fuera de la función sigue siendo: ${precioOriginal}`);\nconsole.log(`El precio con descuento fuera de la función es: ${precioConDescuento}`);\n\n// Funcion con variable por referencia\n\nlet stockProductos = [\n    {nombre: \"Mate\", precio: 1000, stock: 5},\n    {nombre: \"Termo\", precio: 1800, stock: 7},\n    {nombre: \"Bombilla\", precio: 80, stock: 2}\n]\n\nfunction actualizaStock(producto,cantidad) {\n    stockProductos[producto].stock=cantidad;\n    console.log(`El nuevo stock de ${stockProductos[producto].nombre} es: ${cantidad}`);\n}\n\nactualizaStock(1,9);\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\n//Programa 1\nlet a =  \"Abierto\"\nlet b = \"Cerrado\"\n\nfunction intercambiaPorValor(a,b) {\n    let guardaA = a; //Guardas el primer valor\n    a = b; // le asignas al primer valor, el segundo\n    b = guardaA; //Le asignas al segundo valor, el primero\n    return[a,b]\n}\nlet resultado = intercambiaPorValor(a, b);\n// Muestra los valores intercambiados\nconsole.log(`Los valores intercambiados son: ${resultado}`); \n//comprobar valores originales\nconsole.log(`Los valores originales son: ${a}, ${b}`); \n\n// Programa2\nlet programa2 = [\n    {nombre: \"Gary\" , tipo: \"Caracol\"},\n    {nombre: \"Bob\", tipo: \"Esponja\"},\n    {nombre: \"Patricio\", tipo: \"Estrella\"},\n\n]\n\nfunction intercambiaPorReferencia (objeto,index1, index2){\n    let guardaA = objeto[index1]; //Guardas el primer valor\n    objeto[index1] = objeto[index2]; //Asignas el primer valor, al segundo\n    objeto[index2] = guardaA; //Asignas al segundo valor, el primero que guardaste\n\n    console.log(programa2);\n}\n\nintercambiaPorReferencia(programa2,0,2);\n\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/juandaherrera.js",
    "content": "// Por valor (inmutables)\nlet number = 42;\nlet string = \"Hola mundo!\";\nlet boolean = true;\n\n// Por referencia (mutables)\nlet myList = [1, 2, 3];\nlet myDict = { Nombre: \"Juan\", Apellido: \"Herrera\" };\n\n// Función con parámetros \"por valor\"\nfunction elevateValue(value, n) {\n    value **= n;\n    console.log(value);\n}\n\nconsole.log(number);\nelevateValue(number, 2);\nconsole.log(number);\n\n// Función con parámetros \"por referencia\"\nfunction elevateValues(container, n) {\n    for (let index = 0; index < container.length; index++) {\n        container[index] = container[index] ** n;\n    }\n    console.log(container);\n}\n\nconsole.log(myList);\nelevateValues(myList, 2);\nconsole.log(myList);\n\nconsole.log(\"-----------------------------------------\");\n\n/*\n * DIFICULTAD EXTRA (opcional):\n */\n\nfunction areValuesEqual(original1, original2, new1, new2) {\n    return original1 === new1 && original2 === new2;\n}\n\nfunction swapByValue(param1, param2) {\n    let temp = param1;\n    param1 = param2;\n    param2 = temp;\n    return [param1, param2];\n}\n\nlet value1 = \"Juan\";\nlet value2 = \"David\";\n\nconsole.log(value1, value2);\nlet [value3, value4] = swapByValue(value1, value2);\nconsole.log(value1, value2);\nconsole.log(value3, value4);\nconsole.log(\n    \"El valor de las variables originales fue invertido:\",\n    areValuesEqual(value1, value2, value3, value4)\n);\nconsole.log(\"---------------------------\");\n\nfunction swapByReference(param1, param2) {\n    if (param1.length === param2.length) {\n        for (let index = 0; index < param1.length; index++) {\n            let temp = param1[index];\n            param1[index] = param2[index];\n            param2[index] = temp;\n        }\n    }\n    return [param1, param2];\n}\n\nvalue5 = [\"Juan\", \"David\"];\nvalue6 = [\"Herrera\", \"Parra\"];\n\nconsole.log(value5, value6);\nlet [value7, value8] = swapByReference(value5, value6);\nconsole.log(value5, value6);\nconsole.log(value7, value8);\nconsole.log(\n    \"El valor de las variables originales fue invertido:\",\n    areValuesEqual(value5, value6, value7, value8)\n);"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/juperdev.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n*/\n\n/*\n\n- - - - - - Solución - - - - - -\n\n*/\n\n\n// por value\n\n// Por valor es para los tipos de datos primitivos ya que estos contienen el dato en si\nlet a = 10;\nlet b = a;\n// Por referencia es cuando se almacena dentro de un espacio de memoria destinado para eso.\nconst persona = {\n    name: \"Fabian\",\n    age: 18\n};\n\n// Por ejemplo si yo le entrego mi variable con dato primitivo a una funcion esta no sera modificada ya que se esta creando una copia para trabajar\nfunction suma(a, b){\n    // ahora a la variable 'a' le cambiare el valor dentro de la función\n    a = 5;\n    // pero como a y b no tienen ninguna relación entre si b no cambiara su valor que es de 10\n    console.log(`el valor de a es: ${a}`);\n    console.log(`el valor de b es: ${b}`);\n    let resultado = a + b;\n    console.log(resultado);\n}\n\nsuma(a, b);\nconsole.log(`Entonces la variable a: ${a} nunca fue modificada, como es tipo de dato primitivo esta solo crea una copia para trabajar con ella`);\n\n// por Referencia\n\n// Cuando por ejemplo se almacena un objeto este se guarda en un espacio en memoria y se le asigna una localizacion por referencia\n// Ejemplo el objeto fabian se le asigno el espacio en memoria AFR123\n// Por mas que nosotros utilicemos el nombre de la variable con la que fue creado el objeto este apuntara al espacio de memoria asignado y trabajara sobre el\n// Es como si dijecemos function procesarDatos(AFR123){}\n// se modificara en todos los lugares donde estemos haciendo la referencia.\n\nconst persona2 = persona;\n\nfunction procesarDatos(persona){\n    persona.name = 'Arnold';\n}\nconsole.log(`Objeto persona antes de ser procesado ${persona.name}`);\nprocesarDatos(persona);\nconsole.log(`Objeto persona luego de ser procesado ${persona.name}`);\nconsole.log(`Copia persona2 -> ${persona2.name}`); // También fue modificado.\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n*/\n\nconst num = 1;\nconst string = 'Juan';\n\nlet auto = {\n    marca: 'honda'\n}\nlet moto = {\n    marca: 'suzuki'\n}\n\nfunction porValor(param1, param2){\n    let temp = param1;\n    param1 = param2;\n    param2 = temp;\n    \n    return [param1, param2];\n}\n\nfunction porReferencia(param1, param2){\n    let auxiliar = param1;\n    param1 = param2;\n    param2 = auxiliar;\n    return [param1, param2]\n}\nconsole.log(`valor de num: ${num} valor de string: ${string}`);\nlet resultado = porValor(num, string);\nconsole.log(`Luego de aplicar la función y invertir las variables num: ${resultado[0]} y string: ${resultado[1]}`)\nconsole.log(`22222 valor de num: ${num} valor de string: ${string}`);\n\nconsole.log(`valor antes de invertir auto: ${auto.marca} y valor de moto: ${moto.marca}`);\nlet refResultados = porReferencia(auto, moto);\nconsole.log(`Luego de invertir auto: ${refResultados[0].marca} y moto: ${refResultados[1].marca}`);\nconsole.log(`22222 valor antes de invertir auto: ${auto.marca} y valor de moto: ${moto.marca}`);"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/kaesar84.js",
    "content": "/*\n\n# #05 VALOR Y REFERENCIA\n> #### Dificultad: Fácil | Publicación: 29/01/24 | Corrección: 05/02/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n */\n\n// Por valor\nlet value = 25\nlet valueTwo = value\n\nfunction add(a, b) {\n  return a + b\n}\n\nconsole.log(add(value, 25))\n\n// Por referencia\nlet array = [1, 2, 3]\nlet array2 = array\nlet objeto = { a: 1, b: 2, c: 3 }\nlet objeto2 = objeto\n\nconsole.log(array)\nconsole.log(objeto)\narray2.push(99)\nobjeto2[\"z\"] = 99\n\nconsole.log(array2)\n\nconsole.log(objeto2)\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n *\n * */\n// 1️⃣ Intercambio de valores POR VALOR (Primitivos)\nfunction intercambiarPorValor(a, b) {\n    let temp = a\n    a = b\n    b = temp\n    return [a, b] // Retornamos los valores intercambiados\n  }\n  \n  // Definimos variables primitivas\n  let num1 = 10,\n    num2 = 20\n  \n  // Llamamos a la función y guardamos el resultado en nuevas variables\n  let [nuevoNum1, nuevoNum2] = intercambiarPorValor(num1, num2)\n  \n  // Imprimimos los valores antes y después del intercambio\n  console.log(\"🔹 Intercambio por VALOR:\")\n  console.log(`Originales: num1 = ${num1}, num2 = ${num2}`)\n  console.log(`Nuevos: nuevoNum1 = ${nuevoNum1}, nuevoNum2 = ${nuevoNum2}`)\n  \n  // 2️⃣ Intercambio de valores POR REFERENCIA (Objetos)\n  function intercambiarPorReferencia(obj) {\n    let temp = obj.valor1\n    obj.valor1 = obj.valor2\n    obj.valor2 = temp\n  }\n  \n  // Definimos un objeto con propiedades para almacenar valores\n  let objValores = { valor1: \"Hola\", valor2: \"Mundo\" }\n  \n  // Clonamos el objeto para demostrar la diferencia entre original y referencia\n  let objClonado = { ...objValores }\n  \n  // Llamamos a la función que intercambia los valores dentro del objeto\n  intercambiarPorReferencia(objClonado)\n  \n  // Imprimimos los valores antes y después del intercambio\n  console.log(\"\\n🔹 Intercambio por REFERENCIA:\")\n  console.log(\n    `Originales: valor1 = ${objValores.valor1}, valor2 = ${objValores.valor2}`\n  )\n  console.log(\n    `Nuevos: valor1 = ${objClonado.valor1}, valor2 = ${objClonado.valor2}`\n  )\n  "
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n_______________________________________\n#05 VALOR Y REFERENCIA\n---------------------------------------\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n*/\n\n// ________________________________________________________\n// 1. Asignación de variables \"por valor\":\n\n// Inicialización:\nlet int1 = 111;\nlet boo1 = false;\nlet str1 = \"Ben\";\n\n// Asignación:\nlet int2 = int1;\nlet boo2 = boo1;\nlet str2 = str1;\n\n// Cambio:\nint1 = 777;\nboo1 = true;\nstr1 = \"Bob\";\n\n// Las segundas variables no fueron afectadas.\nconsole.log(int2, boo2, str2); // 111 false \"Ben\"\n\n// Ejemplo en una función:\nfunction fun_v(en_int, en_boo, en_str) {\n    // Cambio:\n    en_int = 333;\n    en_boo = false;\n    en_str = \"Ken\";\n}\n\n// Paso por valor\nfun_v(int1, boo1, str1);\n\n// No afectadas por los cambios en la función.\nconsole.log(int1, boo1, str1); // 777 true \"Bob\"\n\n// ________________________________________________________\n// 2. Asignación de variables \"por referencia\":\n\n// Inicialización:\nlet lis1 = [444, true, \"Dan\"];\nlet set1 = new Set([444, true, \"Dan\"]);\nlet dic1 = { name: \"Dan\" };\n\n// Asignación:\nlet lis2 = lis1;\nlet set2 = set1;\nlet dic2 = dic1;\n\n// Cambio:\nlis1.splice(0, 3, 888, false, \"Zoe\");\nset1.delete(444);\nset1.delete(\"Dan\");\ndic1.name = \"Zoe\";\n\n// Las variables fueron afectadas por el cambio.\nconsole.log(lis2);\nconsole.log([...set2]);\nconsole.log(dic2);\n\n// Ejemplo en una función:\nfunction fun_r(en_lis, en_set, en_dic) {\n    // Cambio:\n    en_lis.splice(0, 3, 333, true, \"Jay\");\n    en_set.add(333);\n    en_set.add(\"Jay\");\n    en_dic.name = \"Jay\";\n}\n\n// Paso por referencia\nfun_r(lis2, set2, dic2);\n\n// Fueron afectadas por los cambios en la función.\nconsole.log(lis2);\nconsole.log([...set2]);\nconsole.log(dic2);\n\n// ________________________________________________________\n// 3. DIFICULTAD EXTRA\n\nlet s1 = \"Ben\";\nlet s2 = \"Zoe\";\nlet l1 = [12, 21];\nlet l2 = [\"Ben\", \"Zoe\"];\n\nconsole.log(`Pre-Intercambio:\\n${s1} - ${s2}\\n${l1} - ${l2}`);\n\nfunction by_value(str1, str2) {\n    let temp = str1;\n    str1 = str2;\n    str2 = temp;\n    return [str1, str2];\n}\n\nfunction by_reference(list1, list2) {\n    return [list2.slice(), list1.slice()];\n}\n\nconst [new_s1, new_s2] = by_value(s1, s2);\nconst [new_l1, new_l2] = by_reference(l1, l2);\n\nconsole.log(`Originales:\\n${s1} - ${s2}\\n${l1} - ${l2}`);\nconsole.log(`Nuevas:\\n${new_s1} - ${new_s2}\\n${new_l1} - ${new_l2}`);\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/kodenook.js",
    "content": "/*\n    Assignment By Value\n*/\n\nlet var1 = 3;\nlet var2 = var1;\n\nvar1 = 4;\n\nconsole.log(var1)\nconsole.log(var2)\n\n/*\n    Assignment By Reference\n*/\n\nlet var3 = [10, 20]\nlet var4 = var3\n\nvar3.push(30)\n\nconsole.log(var3)\nconsole.log(var4)\n\n/*\n    Exercise\n*/\n\nfunction ByValue(a, b) {\n    let c = b\n    let d = a\n\n    return [c, d]\n}\n\nlet original1 = 20\nlet original2 = 30\nlet values = ByValue(original1, original2)\n\nconsole.log('By Values')\nconsole.log('Original Values')\nconsole.log(original1)\nconsole.log(original2)\nconsole.log('After Function Values')\nconsole.log(values[0])\nconsole.log(values[1])\n\nfunction ByReference(a, b) {\n    let c = b\n    let d = a\n\n    return [c, d]\n}\n\nlet original3 = 20\nlet original4 = 30\nlet values2 = ByReference(original3, original4)\n\nconsole.log('By Reference')\nconsole.log('Original Values')\nconsole.log(original3)\nconsole.log(original4)\nconsole.log('After Function Values')\nconsole.log(values2[0])\nconsole.log(values2[1])"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/marcode24.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\n// Ejemplo de asignación por valor para tipos primitivos\nconst num1 = 10;\nlet num2 = num1; // Asignación por valor\nnum2 = 20;\n\nconsole.log(num1); // Salida: 10 (valor original no cambia)\nconsole.log(num2); // Salida: 20\n\n// Ejemplo de asignación por referencia para objetos\nconst obj1 = { nombre: 'Juan' };\nconst obj2 = obj1; // Asignación por referencia\nobj2.nombre = 'Carlos';\n\nconsole.log(obj1.nombre); // Salida: Carlos (el valor original cambia)\nconsole.log(obj2.nombre); // Salida: Carlos\n\n// Ejemplo de función que recibe parámetros por valor\nfunction duplicar(numero) {\n  numero *= 2;\n  return numero;\n}\n\nconst original = 5;\nconst resultado = duplicar(original);\n\nconsole.log(original); // Salida: 5 (el valor original no cambia)\nconsole.log(resultado); // Salida: 10\n\n// Ejemplo de función que recibe parámetros por referencia (objeto)\nfunction cambiarNombre(persona) {\n  persona.nombre = 'Pedro';\n}\n\nconst personaOriginal = { nombre: 'Juan' };\ncambiarNombre(personaOriginal);\n\nconsole.log(personaOriginal.nombre); // Salida: Pedro (el valor original cambia)\n\nconsole.log(`${'\\n'}${'*'.repeat(50)}${'\\n'}`);\n\n// Función que intercambia valores por valor\nfunction intercambiarValoresPorValor(a, b) {\n  const temp = a;\n  a = b;\n  b = temp;\n  return [a, b];\n}\n\n// Función que intercambia valores por referencia\nfunction intercambiarValoresPorReferencia(obj) {\n  const copia = { ...obj }; // Crear una copia del objeto original\n  const temp = copia.valor1;\n  copia.valor1 = copia.valor2;\n  copia.valor2 = temp;\n  return copia; // Devolver la copia del objeto modificado\n}\n\n// Ejemplos\nconst valorA = 3;\nconst valorB = 7;\n\nconst [nuevoValorA, nuevoValorB] = intercambiarValoresPorValor(valorA, valorB);\nconsole.log(valorA, valorB); // Salida: 3 7\nconsole.log(nuevoValorA, nuevoValorB); // Salida: 7 3\n\nconst valores = { valor1: 10, valor2: 5 };\n\nconst nuevosValores = intercambiarValoresPorReferencia(valores);\nconsole.log(valores.valor1, valores.valor2); // Salida: 10 5\nconsole.log(nuevosValores.valor1, nuevosValores.valor2); // Salida: 5 10\n\n// Visita mi repo en GitHub para ver y correr los tests de este código --> https://github.com/marcode24/weekly-challenges\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/maximiliano1997.js",
    "content": "\r\n/*\r\n * EJERCICIO:\r\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\r\n *   su tipo de dato.\r\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \r\n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\r\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\r\n *\r\n */\r\n\r\n\r\n// SOLUCION:\r\n\r\nconsole.log(`//////////////////////      Asignacion por valor:     ////////////////////`)\r\n\r\n// Copiamos el valor de la variable y si modificamos la copia la original no cambia\r\n// Aplica para tipos primitivos como .... numeros, strings, booleanos, etc\r\n\r\nlet a = 28\r\nlet b = a\r\nb = 30\r\nconsole.log('a: ', a)\r\nconsole.log('b: ', b)\r\n//En este caso a y b estan en distintas posiciones de memoria, por eso cambiar b no afecta a la variable a.\r\n\r\n\r\nconsole.log(`//////////////////////      Asignacion por Referencia:     ////////////////////`)\r\n\r\n// Copiamos la referencia (direccion en memoria). Si modificamos una copia, la original tambien cambia en este caso.\r\n// Esto aplica para tipo no primitivos como objetos, arrays, funciones, etc\r\n\r\nlet vehiculo1 = { nombre: 'Tesla', año: 2010 }\r\nlet vehiculo2 = vehiculo1\r\nvehiculo2.año = 2000\r\nconsole.log('vehiculo1: ', vehiculo1)\r\nconsole.log('vehiculo2: ', vehiculo2)\r\n// En este caso ambas variables (persona1 y persona2) apuntan al mismo objeto en memoria, por ende cambiar cualquiera de las 2 tambien afectara a la otra.\r\n\r\n\r\nconsole.log(`//////////////////////      Funcion \"por Valor\":     ////////////////////`)\r\n\r\nfunction cambiarEdad(edad) { // <-- aqui el parametro edad recibe una copia del valor de numero. (Justamente por eso el cambio dentro de la funcion no efecto a la variable original)\r\n    edad = edad + 1\r\n    console.log('Dentro de la funcoin: ', edad)\r\n}\r\n\r\nlet numero = 28\r\ncambiarEdad(numero)\r\n\r\nconsole.log('Fuera de la funcion: ', numero)\r\n\r\n\r\nconsole.log(`//////////////////////      Funcion \"por Referencia\":     ////////////////////`)\r\n\r\nfunction cambiarEdad(x) { // <--- El parametro x recibe una referencia al mismo objeto que num, por eso al modificar p modificas tambien el objeto original.\r\n    x.edad = 29\r\n    console.log('Dentro de la funcion: ', x)\r\n}\r\n\r\nlet num = { edad: 50 }\r\ncambiarEdad(num)\r\n\r\nconsole.log('Fuera de la funcion: ', num)\r\n\r\n\r\n////////////////////////////////////////////////// PARA EVITAR CAMBIAR EL ORIGINAL: podemos copiar un objeto o un array para romper la referencia\r\n\r\nlet mascotaA = { nombre: 'Sally', edad: 10 }\r\nlet mascotaB = { ...mascotaA } // una copia usando spread operator\r\n\r\nmascotaB.nombre = 'Camilo'\r\n\r\nconsole.log(mascotaA)\r\nconsole.log(mascotaB)\r\n\r\n\r\n\r\n/*\r\n* DIFICULTAD EXTRA (opcional):\r\n* Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\r\n* - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\r\n*   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\r\n*   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\r\n*   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\r\n*   Comprueba también que se ha conservado el valor original en las primeras.\r\n*/\r\n\r\nconsole.log(`//////////////////////      DIFICULTAD EXTRA:     ////////////////////`)\r\n\r\n\r\n//FUNCION POR VALOR:\r\nfunction programaValor(val1, val2) {\r\n    let valor = val1\r\n    val1 = val2\r\n    val2 = valor\r\n\r\n    return [val2, val1]\r\n}\r\n\r\nlet arrVal1 = 10\r\nlet arrVal2 = 20\r\n\r\nlet [newArrVal2, newArrVal1] = programaValor(arrVal1, arrVal2)\r\n\r\nconsole.log(arrVal1)\r\nconsole.log(arrVal2)\r\nconsole.log(newArrVal1)\r\nconsole.log(newArrVal2)\r\n\r\n\r\n\r\n//FUNCION POR REFERENCIA:\r\nfunction programaReferencia(param1, param2) {\r\n    let nuevo = param1.nombre\r\n    param1.nombre = param2.nombre\r\n    param2.nombre = nuevo\r\n    return [param2, param1]\r\n}\r\n\r\nlet arg1 = { nombre: 'Imanol' }\r\nlet arg2 = { nombre: 'Maximiliano' }\r\n\r\nlet [newArg2, newArg1] = programaReferencia(arg1, arg2)\r\n\r\nconsole.log(arg1)\r\nconsole.log(arg2)\r\nconsole.log(newArg1)\r\nconsole.log(newArg2)\r\n\r\n\r\n\r\n\r\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/miguelex.js",
    "content": "var _a;\nvar myNumber = 25;\nvar myString = \"Hola Mundo\";\nconsole.log(myNumber);\nconsole.log(myString);\n// Declaramos dos nuevas variables por valor \nvar myNumber2 = myNumber;\nvar myString2 = myString;\nconsole.log(myNumber2);\nconsole.log(myString2);\n// Cambiamos el valor de las variables originales\nmyNumber = 50;\nmyString = \"Adios Mundo\";\nconsole.log(\"El valor de variable numérica original es: \" + myNumber + \" y el valor de la variable numérica nueva es: \" + myNumber2);\nconsole.log(\"El valor de variable string original es: \" + myString + \" y el valor de la variable string nueva es: \" + myString2);\n// Ejemplo por referencia\nvar obj1 = {\n    name: \"Miguel\",\n    age: 25\n};\nconsole.log(obj1);\n// Declaramos un nuevo objeto y le asignamos el valor del objeto original\nvar obj2 = obj1;\n// Imprimimos el valor del nuevo objeto\nconsole.log(obj2);\n// Cambiamos el valor de una propiedad del objeto original\nobj1.name = \"Miguelex\";\nconsole.log(\"El valor de la propiedad name del objeto original es: \" + obj1.name + \" y el valor de la propiedad name del objeto nuevo es: \" + obj2.name);\n// Ejemplo de funcion con paso por valor\nfunction changeValue(a) {\n    a = 50;\n}\nvar num = 25;\nchangeValue(num);\nconsole.log(num);\n// Ejemplo de funcion con paso por referencia\nfunction changeValueObj(obj) {\n    obj.name = \"Miguelex\";\n}\nvar obj = {\n    name: \"Miguel\",\n    age: 25\n};\nchangeValueObj(obj);\nconsole.log(obj.name);\n// Extra\nfunction byValor(a, b) {\n    var aux = a;\n    a = b;\n    b = aux;\n    return [a, b];\n}\nfunction byReference(obj1, obj2) {\n    var aux = obj1;\n    obj1 = obj2;\n    obj2 = aux;\n    return [obj1, obj2];\n}\nvar a = 5;\nvar b = 10;\nvar user1 = {\n    name: \"Miguel\",\n    age: 25\n};\nvar user2 = {\n    name: \"Juan\",\n    age: 30\n};\nconsole.log(\"Antes de llamar a la función --> El valor de a es: \" + a + \" y el valor de b es: \" + b);\n_a = byValor(a, b), a = _a[0], b = _a[1];\nconsole.log(\"Después de llamar a la función --> El valor de a es: \" + a + \" y el valor de b es: \" + b);\nconsole.log(\"Antes de llamar a la función --> El valor de user1 es: \" + JSON.stringify(user1) + \" y el valor de user2 es: \" + JSON.stringify(user2));\nvar _b = byReference(user1, user2), newUser1 = _b[0], newUser2 = _b[1];\nconsole.log(\"Despues de llamar a la función --> El valor de user1 es: \" + JSON.stringify(newUser1) + \" y el valor de user2 es: \" + JSON.stringify(newUser2));\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/natalyjoanna.js",
    "content": "\n// Asignar valores primitivos (por valor)\nlet a = 'hola';\nlet b = a;\na += '!';\nconsole.log(a) // el valor de a cambia despues de la modificacion\nconsole.log(b) // b imprime el valor original de a que se le asigno\n\n// Asignar valores complejos (por referencia)\nconst c = [1,2,3];\nconst d = c; // en este caso se asigna una refenrecia\nd.push(4);\nconsole.log(c) // Se modifica el valor original\nconsole.log(d)\n\n// Pasar valores primitivos (por valor) a una funcion\nconst greet1 = 'Hello'\nconst greetings = (greet) => {\n  greet = 'Hola javascript';\n  return greet;\n};\nconsole.log(greetings(greet1)) \nconsole.log(greet1) // El valor de greet1 no se modifica ni se reasigna fuera de la funcion\n\n// Pasar valores complejos a una funcion\nlet arreglo = [1,2,3]\nfunction referencia(arr) {\n  arr.push(4);\n  console.log('Dentro de la funcion ', arr) \n}\n\nreferencia(arreglo)\nconsole.log('Fuera de la funcion: ', arreglo) // Se modifica el valor original\n\n// Pasar valores complejos a una funcion y que no se modifiquen\nlet arreglo2 = [1,2,3]\nfunction copia(arr) {\n  const copy = arr.slice(0) // copia del arreglo original\n  copy.push(4);\n  console.log('Dentro de la funcion ', copy) \n}\n\ncopia(arreglo2)\nconsole.log('Fuera de la funcion: ', arreglo2) \n\n// DIFICULTAD EXTRA\nlet num1 = 10\nlet num2 = 20\n\nfunction porValor(n1, n2) {\n  let temp = n1\n  n1=n2\n  n2=temp\n  return [n1, n2]\n}\n\nlet [num1_f, num2_f] = porValor(num1, num2)\nconsole.log(`Valores que la funcion retorna: ${num1_f} , ${num2_f}`)\nconsole.log(`Valores originales: ${num1} , ${num2}`)\n\nlet valores1 = [1,2,3]\nlet valores2 = [10, 20, 30]\n\nfunction porReferencia(v1, v2) {\n  let temp = v1\n  v1=v2\n  v2=temp\n  return [v1, v2]\n}\n\nlet [valores1_f, valores2_f] = porReferencia(valores1, valores2)\nconsole.log(`Valores que la funcion retorna: ${valores1_f} y ${valores2_f}`)\nconsole.log(`Valores originales: ${valores1} y ${valores2}`)"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/nlarrea.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\n\n// Asignación por valor\n\nlet numberA = 11;\nlet numberB = numberA;\nconsole.log('numberA:', numberA);  // numberA: 11\nconsole.log('numberB:', numberB);  // numberB: 11\nnumberB = 7;\nconsole.log('numberA:', numberA);  // numberA: 11\nconsole.log('numberB:', numberB);  // numberB: 7\n\n// Asignación por referencia\n\nlet arrayA = [1, 2, 3, 4];\nlet arrayB = arrayA;\nconsole.log('arrayA:', arrayA);  // [1, 2, 3, 4]\nconsole.log('arrayB:', arrayB);  // [1, 2, 3, 4]\narrayB.push(5);\nconsole.log('arrayA:', arrayA);  // [1, 2, 3, 4, 5]\nconsole.log('arrayB:', arrayB);  // [1, 2, 3, 4, 5]\n\n// Funciones por valor\n\nfunction printDouble(number) {\n    number *= 2;\n    console.log(number);\n}\n\nlet myNumber = 2;\nprintDouble(myNumber);  // 4\nconsole.log(myNumber);  // 2\n\n// Funciones por referencia\n\nfunction printAppendNumber(arr, num) {\n    arr.push(num);\n    console.log(arr);\n}\n\nlet myArr = [1, 2, 3, 4]\nprintAppendNumber(myArr, 5);  // [1, 2, 3, 4, 5]\nconsole.log(myArr);  // [1, 2, 3, 4, 5]\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\n\nfunction exchangeByValue(valOne, valTwo) {\n    [valOne, valTwo] = [valTwo, valOne]\n    return [valOne, valTwo];\n}\n\nlet firstValue = 11\nlet secondValue = 7\nlet [val1, val2] = exchangeByValue(firstValue, secondValue);\nconsole.log(`1.1 Before function: ${firstValue}, After function: ${val1}`);\n// 1.1 Before function: 11, After function: 7\nconsole.log(`1.2 Before function: ${secondValue}, After function: ${val2}`);\n// 1.2 Before function: 7, After function: 11\n\n\nfunction exchangeByReference(arrOne, arrTwo) {\n    [arrOne, arrTwo] = [[...arrTwo], [...arrOne]];\n    return [arrOne, arrTwo]\n}\n\nlet firstArray = [1, 2, 3, 4]\nlet secondArray = [9, 8, 7, 6]\nlet [arr1, arr2] = exchangeByReference(firstArray, secondArray);\nconsole.log(`2.1 Before function: ${firstArray}, After function: ${arr1}`);\n// 2.1 Before function: 1,2,3,4, After function: 9,8,7,6\nconsole.log(`2.2 Before function: ${secondArray}, After function: ${arr2}`);\n// 2.2 Before function: 9,8,7,6, After function: 1,2,3,4"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/ocram1304.js",
    "content": "/*Los  tipo valor son aquellas en las que se copia directamenete el valor dentro de su propia asignacipon \nde memoria, los tipo de datos primitivo como number (int, float) string, boolean, null, undenined y symbol, se pueden\nutilizar como tipo de  datos por valor.\nLos tipo refenrncia en cambio guardan una referenica a donde se encuentran sus datos. Los datos compuestos como arreglos\ny objetos son de tipo referencia.\nEstrictamente hablando JS no ofrece la opción de pasar por referencia cuando pasamos la varible como parametro de una\nfunción. Lo interesante es que cuando se trata de un objeto o arreglo el \"valor\" de estos es la referencia.\n*/\n\n\n//NOTA para este ejercisio utilice la información proviniente de está página https://medium.com/laboratoria-developers/por-valor-vs-por-referencia-en-javascript-de3daf53a8b9\n//El author origina es Lupo Montero, publicado en  Laboratoria Devs.\n//Ejemplo de asignación por valor\n//Cundo se asignan valores por valor como en este ejemplo al cambiar el valor de a, b se mantiene independiate\n//Cada varible mantien su propio valor.\nlet a = \"12\";\nlet b = a;\na+=\"5\";\nconsole.log(a);//salida esperada [17]\nconsole.log(b);//salida esperada [12]\n\n//Ejemplo de asignación por referencia\n//Como se puede observar si se modifica el valor del parametro, se está modificando el mismo valor al que hace\n//referencia la variable, por ello para evitar eefectos colaterales se obta por no mutar directamente los argumentos\n//pasados a una función\n\nconst modi = (arreglo)=>{\n    const results= [];\n    while(arreglo.length){\n        results.push(doSomethingWithArrayItem(arr.shift()))//Se vacia el arreglo/parametro \n    }\n    return results;\n}\nconst arreglo = [1,2,3,4];\nmodi(arreglo);\nconsole.log(arreglo);//salida esperada []\n//Como evitar efectos colaterales \nconst modi2 = (arreglo)=>{\n    const copia = arreglo.slice(0); //Se hace una copia del arreglo\n    const results= [];\n    while(copia.length){\n        results.push(doSomethingWithArrayItem(copia.shift()))//Se vacia la copia del  arreglo/parametro \n    }\n    return results;\n}\nconst arreglo2 = [1,2,3,4];\nmodi(arreglo2);//salida esperada [1,2,3,4];\n\n//Una caracteristica importante a resaltar de los tipo referemcia, es que se pude utilizar en la recursión\n//En algo que se llama referencia circulares por ejemplo\n\nconst a2 = [1, 2, 3];\na2.push(a2);\nconsole.log(a2);\n//El cuarto elemento que se agrega es una referencia hacia el mismo arreglo. Se tiene que tener cuidado con esto\n//Pues se pueden producir bucles infinitos.\n\n//Dificultad extra\n\n//Tipo valor\nlet tValor1 = \"valor1\";\nlet tValor2 = \"valor2\";\n\nfunction tipoValor(v1,v2){\n\n    let aux =v1;\n    v1= v2;\n    v2 = aux;\n    return [v1,v2]\n}\nlet valoresIntercambiados = tipoValor(tValor1, tValor2);\nconsole.log(valoresIntercambiados); // Debería imprimir [\"valor2\", \"valor1\"]\nconsole.log(tValor1); // Debería imprimir \"valor1\"\nconsole.log(tValor2); // Debería imprimir \"valor2\"\n\n//Tipo referenia\nconst  tipoRefe1 = {\n  a: 1,\n  b: 2,\n  c: 3\n}\nconst tipoRefe2 = {\n    a: 4,\n    b: 5,\n    c: 6\n  }\n\nfunction tipoRefencia (ref1, ref2){\n    //Se cran copias de los objetos originales\n    //Object.assign  crea copias superficiales de los objetos originales. Los valores promitivos se copian directamente\n    //mientras que las referencias  a otros objetos se mantienen, pero apuntan a los mismos objetos.\n    let aux1 = Object.assign({}, ref1);\n    let aux2 = Object.assign({}, ref2);\n    let mix = aux1;\n    aux1= aux2;\n    aux2 = mix;\n    return [aux1,aux2];\n\n\n}\nlet intercambio = tipoRefencia(tipoRefe1,tipoRefe2);\n//Valorse intercambiados\nconsole.log(intercambio[0]);\nconsole.log(intercambio[1]);\n//Valores originales \nconsole.log(tipoRefe1);\nconsole.log(tipoRefe2);\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/oleojake.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n */\n\n// Asignación por Valor en tipos PRIMITIVOS\nlet nombre = \"Pablo\";\nlet nombre1 = nombre;\nnombre += \" Marzal\";\nconsole.log(nombre); // Pablo Marzal\nconsole.log(nombre1); // Pablo\n\nlet edad = 25;\nlet edad1 = edad;\nedad = edad + 5;\nconsole.log(edad); // 30\nconsole.log(edad1); // 25\n\n// Asignación por Referencia en Arrays y Objetos. Hacen referencia al mismo espacio de memoria\n\nlet myArray = [1, 2];\nlet myArray2 = myArray;\n\nmyArray.push(3);\nconsole.log(myArray); // [1, 2, 3]\nconsole.log(myArray2); // [1, 2, 3]\n\nlet myObject = {\n    nombre: \"Pablo\",\n    edad: 25\n};\nlet myObject1 = myObject;\n\nmyObject.edad = 30;\nconsole.log(myObject); // {nombre: 'Pablo', edad: 30 }\nconsole.log(myObject1); // {nombre: 'Pablo', edad: 30 }\n\n// Función variable por VALOR\n\nfunction multiplicar(number) {\n    number = number * 2;\n    return number;\n}\n\nlet original = 10;\nlet resultado = multiplicar(original);\n\nconsole.log(original); // --> 10 El valor original no cambia\nconsole.log(resultado); // 20\n\n// Función variable por REFERENCIA\n\n// Los arrays se comportan como objetos\n\nlet myPerson = {\n    nombre: \"Pablo\",\n    edad: 25\n};\n\nfunction cumpleaños (persona){\n    persona.edad = persona.edad + 1;\n}\nconsole.log(myPerson.edad); // Inicialmente es 25\ncumpleaños(myPerson); // Llamamos a la funcion pasando un objeto (por referencia)\nconsole.log(myPerson.edad); // --> 26 cambia la edad en el objeto original, fuera de la función aunque no la hayamos mencionado\n\n/* DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como\n * variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime\n *   el valor de las variables originales y las nuevas, comprobando que se ha invertido\n *   su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\n\n\n//EXTRA\n// Por Valor\nlet fruta1 = \"Melocotón\";\nlet fruta2 = \"Uva\";\n\nfunction cambioValor (param1, param2){\n    let temp = param1;\n    param1 = param2;\n    param2 = temp;\n    return [param1, param2];\n}\n\nlet newFruta1 = cambioValor(fruta1, fruta2)[0];\nlet newFruta2 = cambioValor(fruta1, fruta2)[1];\n\nconsole.log(fruta1); // Melocotón. El original no ha cambiado\nconsole.log(fruta2); // Uva. El original no ha cambiado\nconsole.log(newFruta1); // Uva. Aquí sí que se han invertido porque es una nueva variable\nconsole.log(newFruta2); // Melocotón. Aquí también\n\n// Por Referencia\n\nlet fruta1Object = {\n    nombre: 'Melocotón',\n}\n\nlet fruta2Object= {\n    nombre: 'Uva',\n}\n\nfunction cambioReferencia (obj1, obj2){\n    let aux = obj1.nombre ;\n    obj1.nombre = obj2.nombre;\n    obj2.nombre = aux;\n    return [obj1, obj2];\n}\n\nconsole.log(fruta1Object);\nconsole.log(fruta2Object);\nlet newFrutas = cambioReferencia (fruta1Object, fruta2Object);\nconsole.log(newFrutas[0]);\nconsole.log(newFrutas[1]);\n// Los originales cambian de orden también porque se modifica el espacio en memoria no el valor\nconsole.log(fruta1Object);\nconsole.log(fruta2Object);"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/othamae.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\n\n// Pass by Value\nlet num1 = 20\nlet num2 = num1 // Assigning the value of 'num1' to 'num2', creating a new copy of the value\nnum2 = 40 // Modifying the value of 'num2', does not affect 'num1' as they are independent variables\n\nconsole.log(`Value of num1: ${num1}`) // 'num1' retains its original value of 20\nconsole.log(`Value of num2: ${num2}`) // 'num2' has been modified to 40\n\n// Pass by Reference \n    // Objects:\nconst obj1 = {x: 20, y: 30}\nconst obj2 = obj1 // Assigning the reference of 'obj1' to 'obj2', so both now point to the same object in memory\nobj2.x = 40 // Modifying the 'x' property of 'obj2', which also affects 'obj1' since they share the same reference\n\nconsole.log(`Value of obj1:`)\nconsole.log(obj1) // Both 'obj1' and 'obj2' now have an 'x' value of 40\nconsole.log(`Value of obj2:`)\nconsole.log(obj2) // 'obj2' reflects the change made to 'obj1'\n\n    // Arrays:\nconst arr1 = [1, 2, 3]\nconst arr2 = arr1 // Assigning the reference of 'arr1' to 'arr2', so both now point to the same array in memory\narr2[0] = 4 // Modifying the first element of 'arr2', which also affects 'arr1' since they share the same reference\n\nconsole.log(`Value of arr1:`)\nconsole.log(arr1) // Both 'arr1' and 'arr2' now have an index0 value of 4\nconsole.log(`Value of arr2:`)\nconsole.log(arr2) // 'arr2' reflects the change made to 'arr1'\n\n// Functions with Pass by Value\nfunction increment(num) {\n  num++;\n  return num;\n}\n\nconst num = 5;\nconst numIncremented = increment(num);\nconsole.log(`num: ${num}`) // num retains its original value of 5\nconsole.log(`numIncremented: ${numIncremented}`) // numIncremented has the value of 6\n\n// Functions with Pass by Reference\nfunction changeValue(obj){\n    obj.x= 50\n    return obj\n}\nconst object1 = {x: 10, y: 20}\nconst objChanged = changeValue(object1)\n\nconsole.log(`object1: `)\nconsole.log(object1) // object1 has changed its original value to {x: 50, y: 20}\nconsole.log(`objChanged: `)\nconsole.log(objChanged) // objChanged has the value of {x: 50, y: 20}\n\n\n// EXTRA TASK:\nfunction swapValues(value1, value2) {\n    let temp1 = value1\n    value1 = value2\n    value2 = temp1\n    return [value1, value2]\n}\n\nfunction swapObjectValues(obj) {\n    let copy = {...obj}\n    let temp1 = copy.val1\n    copy.val1 = copy.val2\n    copy.val2 = temp1\n    return copy\n}\n\nconst value1 = 10\nconst value2 = 50\nconst [newValue1, newValue2] = swapValues(value1, value2)\nconsole.log(`Value1: ${value1}, Value2: ${value2}`)\nconsole.log(`NewValue1: ${newValue1}, NewValue2: ${newValue2}`)\n\nconst obj = {val1: 10, val2: 50}\nconst newObj = swapObjectValues(obj)\nconsole.log(`Obj: `)\nconsole.log(obj)\nconsole.log(`NewObj: `)\nconsole.log(newObj)\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/parababire.js",
    "content": "//Asignación de variables.\n\n/*Asignar valor:\nCuando un valor primitivo (number, boolean, string...) es asignado a \nuna variable, este puede ser copiado a otra variable por medio de lo \nque conocemos como asignación por valor.*/\n\nlet fruta = \"banana\";\nlet fruta2 = fruta;//A la variable fruta2 se le asigna una copia del valor contenido en la variable fruta.\nfruta = \"mandarina\";\nconsole.log(`La ${fruta} es el nuevo valor de la variable fruta. Ésta al contener un valor primitivo, \nla copia de su valor en fruta2, no es alterado y sigue siendo ${fruta2}.`);//\n\n/*Asignar referencia:\nDe datos tipo Array, Object y Function*/\n\n//Al asignar un objeto a una variable, este es guardado en un espacio de memoria libre (referencia).\nlet carro = {\n  color: \"azul\",\n  puertas: 2,\n  ruedas: 4,\n}\nlet carro1 = carro;//El motor de javascript busca la referencia asignada a la variable carro y la copia a carro1.\ncarro.puertas = 4;//Se modifica la propiedad puertas del objeto guardado en la variable carro.\nconsole.log(`\\nComo ambas variables tienen la misma referencia los cambios al objeto se pueden acceder desde sus copias ejem: carro1.puertas = ${carro1.puertas}.`);\n\n//Parámetros asignados por valor.\n\nfunction sumar(suma) {\n  return suma = suma + 1;\n}\n\nlet suma = 1;\nconsole.log(sumar(suma));\nconsole.log(suma);\n\n//Parámetros asignados por referencia.\n\nfunction comer(fruto) {\n  return fruto.cantidad = fruto.cantidad -1;\n}\n\nlet fruto = {\n  nombre: 'banana',\n  cantidad: 4\n}\n\nconsole.log(comer(fruto));\nconsole.log(fruto.cantidad);\n\n//Extra\n\nlet bike1 = \"azul\";\nlet bike2 = \"rojo\";\n\n//Función de asignación por valor\n\n/*Cabe aclarar que las funciones solo retornan un valor, pero con el uso de arrays u objetos\npodemos simular el retorno de más de un valor.*/\nfunction intercambio(bike1, bike2) {\n  let temp = bike1;\n  bike1 = bike2;\n  bike2 = temp;\n  return [bike1, bike2];\n}\n\n//El uso de desestructuración permite asignar el resultado de una función a un conjunto de variables.\nlet [bike3, bike4] = intercambio(bike1, bike2);\nconsole.log(bike1);\nconsole.log(bike2);\nconsole.log(bike3);\nconsole.log(bike4);\n\n//Función de asignación por referencia.\n\nlet persona1 = {\n  cabello: true,\n  nombre: 'angel'\n}\n\nlet persona2 = {\n  cabello: false,\n  nombre: 'luis'\n}\n\nfunction asignarPorRefencia(persona1, persona2) {\n  let temp = persona1.nombre;\n  persona1.nombre = persona2.nombre;\n  persona2.nombre = temp;\n  return [persona1, persona2];\n}\n\nconst [persona3, persona4] = asignarPorRefencia(persona1, persona2);\nconsole.log(persona1);\nconsole.log(persona2);\nconsole.log(persona3);\nconsole.log(persona4);"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/pedamoci.js",
    "content": "// ------------------------- ASIGNACION DE VARIABLES -------------------------\n  /* --> variables con valores primitivos <-- */\n    let varValorNumber = 123\n    let varValorStrig = 'string'\n    let varValorBoolean = true\n    let varValorUndefined = undefined\n    let varValorNull = null\n\n  // POR VALOR --> se copia el valor de una variable (tiene que contener un dato primitivo) a otra\n    let asignacionValorNumber = varValorNumber\n    let asignacionValorString = varValorStrig\n    let asignacionValorBoolean = varValorBoolean\n    let asignacionValorUndefined = varValorUndefined\n    let asignacionValorNull = varValorNull \n    // cada variable 'asignacion' contiene copia del valor que contiene la variable original\n\n  /* --> variables con valores tipo objeto<--*/\n    let varTOArray = [12, 'messi', true, 98567]\n    let varTOObjeto = {'messi': 'futbolista', 'Del Potro': 'tenista', 'Hamilton': 'Piloto'}\n    let varTOFuncion = function saludar() {\n      console.log('Hola')\n    }\n\n  // POR REFERENCIA --> se copia la referencia a un valor almacenado en memoria\n    let asignacionReferenciaArray = varTOArray\n    let asignacionReferenciaObjeto = varTOObjeto\n    let asignacionReferenciaFuncion = varTOFuncion\n\n// ------------------------- EJEMPLOS DE FUNCIONES CON VARIABLES -------------------------\n  // POR VALOR\n  function modificarVarXValor(valorNum) {\n    valorNum = 852\n    console.log('valor de la variable dentro de la función: ' + valorNum)\n  }\n  console.log('valor de la variable antes de ingresar a la función: ' + asignacionValorNumber)\n  modificarVarXValor(asignacionValorNumber)\n  console.log('valor de la variable despues de ingresar a la función: ' + asignacionValorNumber)\n\n  // POR REFERENCIA\n  function modificarVarXReferencia(valorArr) {\n    valorArr.push('dato ingresado dentro de la funcion')\n    console.log('valor de la variable dentro de la función: ' + valorArr)\n  }\n  console.log('valor de la variable antes de ingresar a la función: ' + asignacionReferenciaArray)\n  modificarVarXReferencia(asignacionReferenciaArray)\n  console.log('valor de la variable despues de ingresar a la función: ' + asignacionReferenciaArray)\n  // la variable se modifica fuera de la funcion ya que al ingresar como dato un array en verdad lo que hace es ingresar la ubicacion en memoria del array original y ese es el   que modifica el push que esta adentro de la funcion\n\n// ----------------------------------- DIFICULTAD EXTRA -----------------------------------\n// INTERCAMBIO DE PARAMETROS POR VALOR\nlet parametroValor1 = 5\nlet parametroValor2 = 8\nfunction intercambiarXValor(v1, v2) {\n  return [v2, v1]\n}\nlet [intercambiadoValor1, intercambiadoValor2] = intercambiarXValor(parametroValor1, parametroValor2)\nconsole.log(`El valor original 1 es: ${parametroValor1} y el 2 es: ${parametroValor2}` + \"\\n\" + `El valor intercambiado del 1 es: ${intercambiadoValor1} y del 2 es: ${intercambiadoValor2}`)\n\n\n// INTERCAMBIO DE PARAMETROS POR REFERENCIA\nlet parametroReferencia1 = [5, 6454, 324, 2, 878]\nlet parametroReferencia2 = ['jaime', 'pepe', 'juan', 'jesus', 'hector']\nfunction intercambiarXReferencia(v1, v2) {\n  let valorIntercambiador = [...v1]\n  v1 = [...v2]\n  v2 = [...valorIntercambiador]\n  return [v1, v2]\n}\nlet [intercambiadoReferencia1, intercambiadoReferencia2] = intercambiarXReferencia(parametroReferencia1, parametroReferencia2)\nconsole.log(`El valor original 1 es: ${parametroReferencia1} y el 2 es: ${parametroReferencia2}` + \"\\n\" + `El valor intercambiado del 1 es: ${intercambiadoReferencia1} y del 2 es: ${intercambiadoReferencia2}`)"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/popmaquin.js",
    "content": "/*---Por valor y referencia---*/\n\n//---Por referencia a datos primitivos\nconsole.log(\"---Por valor\");\nlet a= \"hola\";\nlet b= a;\n\na+=\"!\";\nconsole.log(a);\nconsole.log(b);\n\n//---Por referencia a datos complejos\nconsole.log(\"---Por referencia\");\nlet arr= [\"hola\",\"Juan\",\"Bienvenido\"];\nlet ref= arr;\n\narr.push(\"Guatemala\");\nconsole.log(arr);\nconsole.log(ref);\n\n//---Funcion por valor datos primitivos\nconsole.log(\"---Funcion por valor\");\nfunction xvalor(a){\n    let b=a;\n    a=\"4\"\n    return [b, a];\n}\n\nlet a_ =\"hola\";\n\nconsole.log(xvalor(a_));\nconsole.log(a_);\n\n\n//---Funcion por referencia a datos complejos\nconsole.log(\"---Funcion por referencia\");\nfunction xrefencia(arr2){\n    let ref2=arr2;\n    arr2.set(34)\n    return [ref2,arr2];\n}\nlet mymap2= new Map([[10],[24]]);\n\nconsole.log(xrefencia(mymap2));\nconsole.log(mymap2);\n\n//---Dificultad extra---\nconsole.log(\"---Dificultad Extra---\");\nconsole.log(\"---x valor\");\nfunction parametro_x_valor(num1,num2){\n    let temp=num1;\n        num1=num2;\n        num2=temp;\n    return {num1,num2}  \n}\nlet num3 = 5;\nlet num4 = 2;\nlet result = parametro_x_valor(num3,num4);\n\nconsole.log(result);\nconsole.log(`num3: ${num3} num4: ${num4}`);\n\n\nconsole.log(\"---x refrencia\");\nfunction parametro_x_ref(matriz1,matriz2){\n    let temp=matriz1;\n        matriz1=matriz2;\n        matriz2=temp;\n    return {matriz1, matriz2}\n}\nlet arr1 = [1,2,3];\nlet arr2 = [4,5,6];\nlet arr_result = parametro_x_ref(arr1,arr2);\n\nconsole.log(arr_result);\nconsole.log(`arr1: ${arr1} arr2: ${arr2}`);"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/qwik-zgheib.js",
    "content": "/* -- exercise */\n// -- by value\nlet a = 5;\nlet b = a;\n\nb = 10;\nconsole.log(a);\nconsole.log(b);\n\n// by reference\nlet obj1 = { name: \"Alice\" };\nlet obj2 = obj1;\n\nobj2.name = \"Bob\";\nconsole.log(obj1.name);\nconsole.log(obj2.name);\n\n// Passing Variables to Functions\n// by value\nfunction changeValue(x) {\n  x = 10;\n}\n\nlet valueA = 5;\nchangeValue(valueA);\nconsole.log(valueA);\n\n// by reference\nfunction changeObject(obj) {\n  obj.name = \"Charlie\";\n}\n\nlet object1 = { name: \"Alice\" };\nchangeObject(object1);\nconsole.log(object1.name);\n\n/* -- extra challenge */\nfunction swapByValue(x, y) {\n  let temp = x;\n  x = y;\n  y = temp;\n  return [x, y];\n}\n\nlet value1 = 10;\nlet value2 = 20;\n\nlet [new1, new2] = swapByValue(value1, value2);\n\nconsole.log(\"Original values: value1 =\", value1, \", valueB =\", value2);\nconsole.log(\"Swapped values: newA =\", new1, \", newB =\", new2);\n\nfunction swapByReference(obj1, obj2) {\n  let temp = obj1.value;\n  obj1.value = obj2.value;\n  obj2.value = temp;\n  return [obj1, obj2];\n}\n\nlet objectA = { value: \"Hello\" };\nlet objectB = { value: \"World\" };\n\nlet [newObjectA, newObjectB] = swapByReference(objectA, objectB);\n\nconsole.log(\"Original values: objectA.value =\", objectA.value, \", objectB.value =\", objectB.value);\nconsole.log(\"Swapped values: newObjectA.value =\", newObjectA.value, \", newObjectB.value =\", newObjectB.value);\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/ralphmcralph.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n */\n\n// Tipos de dato por valor (primitivos)\n\nlet a = 5;\n\nconsole.log(a); // 5\n\nlet b = a;\n\nconsole.log(b); // 5\n\nb = 10;\n\nconsole.log(a); // 5\n\nconsole.log(b); // 10\n\n// Tipos de dato por referencia (objetos)\n\nlet objeto1 = {\n    nombre: \"Ralph\"\n};\n\nconsole.log(objeto1); // { nombre: \"Ralph\" }\n\nlet objeto2 = objeto1;\n\nconsole.log(objeto2); // { nombre: \"Ralph\" }\n\nobjeto2.nombre = \"Ralph McRalph\";\n\nconsole.log(objeto1); // { nombre: \"Ralph McRalph\" }\n\nconsole.log(objeto2); // { nombre: \"Ralph McRalph\" }\n\n// Funciones con parámetros por valor\n\nfunction duplicar(numero) {\n    return numero *= 2;\n}\n\nlet numero = 5;\n\nconsole.log(duplicar(numero));\n\nconsole.log(numero); // 5\n\n// Funciones con parámetros por referencia\n\nfunction cambiarNombre(objeto) {\n    objeto.nombre = \"Ralph McRalph\";\n}\n\nlet persona = {\n    nombre: \"Ralph\"\n};\n\nconsole.log(persona);\n\ncambiarNombre(persona);\n\nconsole.log(persona); // { nombre: \"Ralph McRalph\" }\n\nlet my_list_a = [1, 2, 3];\nlet my_list_b = my_list_a;\n\nmy_list_b.push(4);\n\nconsole.log(my_list_a); // [1, 2, 3, 4]\n\n\n\n/* DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\n// Por valor\n\nlet my_int_a = 10;\nlet my_int_b = 20;\n\nfunction intercambioValor(int1, int2) {\n\n    var my_temp = int1;\n\n    int1 = int2;\n\n    int2 = my_temp\n\n    return [int1, int2]\n\n}\n\n[my_new_int_a, my_new_int_b] = intercambioValor(my_int_a, my_int_b);\n\nconsole.log(my_int_a + \",\" + my_int_b);\n\nconsole.log(my_new_int_a + \",\" + my_new_int_b);\n\n// Por referencia\n\nlet persona_a = {\n    nombre: \"Ralph\"\n}\n\nlet persona_b = {\n    nombre: \"McRalph\"\n}\n\nfunction intercambiarReferencia(persona1, persona2) {\n\n    var persona_temp = persona1;\n\n    persona1 = persona2;\n\n    persona2 = persona_temp;\n\n    return [persona1, persona2]\n\n}\n\n\n[new_persona_a, new_persona_b] = intercambioValor(persona_a, persona_b);\n\nconsole.log(persona_a.nombre + \",\" + persona_b.nombre);\n\nconsole.log(new_persona_a.nombre + \",\" + new_persona_b.nombre);\n\n\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/saicobys.js",
    "content": "/* Paso de variables por valor y por referencia */\n\n// Paso por valor (tipos primitivos)\nlet num1 = 5;\nlet num2 = 10;\n\nfunction sumarPorValor(a, b) {\n  a += 5; // Modifica la copia local de 'a'\n  b += 5; // Modifica la copia local de 'b'\n  console.log(a, b);\n}\n\nsumarPorValor(num1, num2);\nconsole.log(num1, num2);\n\n// Paso por referencia (objetos)\nlet obj1 = { x: 1, y: 2 };\nlet obj2 = { z: 3 };\n\nfunction modificarPorReferencia(objeto) {\n  objeto.x = 10; // Modifica la propiedad 'x' del objeto original\n}\n\nmodificarPorReferencia(obj1);\nconsole.log(obj1); // { x: 10, y: 2 } (el objeto original se modificó)\n\n/* Funciones con paso por valor y por referencia */\n\nfunction sumarPorValor(a, b) {\n  return a + b; // Retorna la suma de los valores (copias)\n}\n\nfunction modificarArrayPorReferencia(arr) {\n  arr.push(5); // Modifica el array original\n}\n\nlet numeros = [1, 2, 3];\nmodificarArrayPorReferencia(numeros);\nconsole.log(numeros);\n\n/* Desafio */\n\n// Intercambio por valor\nfunction intercambiarPorValor(a, b) {\n  let temp = a;\n  a = b;\n  b = temp;\n  return [a, b];\n}\n\nlet x = 5;\nlet y = 10;\n[x, y] = intercambiarPorValor(x, y);\nconsole.log(x, y);\n\n// Intercambio por referencia\nfunction intercambiarPorReferencia(obj) {\n  let temp = obj.a;\n  obj.a = obj.b;\n  obj.b = temp;\n}\n\nlet obj = { a: 5, b: 10 };\nintercambiarPorReferencia(obj);\nconsole.log(obj);\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/seandsun.js",
    "content": "/** \n<-------------- Variable por valor -------------->\nCuando se le asignan valores primitivos (boolean, number, string, undefined, null, BigInt, symbol) el valor asignado se va a pasar como \nuna copia del valor original.\n*/\n\nlet a = 'hola'\nlet b = a // Se asigna el valor de \"a\" a \"b\"\na += 'Mundo' // Se cambia el valor de \"a\" añadiendo \"Mundo\" al final\nconsole.log(a) // holaMundo\nconsole.log(b) // hola\n\n// En el ejemplo anterior, se puede observar como cada variable guarda su propio valor, o sea que se mantienen independientes.\n\n/** \n<-------------- Variable por referencia -------------->\nCuando se le asignan valores NO primitivos (objetos, arrays y funciones) el valor asignado no se va a pasar como tal, en realidad lo que se\npasa es una referencia a la variable que contiene el valor original, es como si la variable fuera una \"casa\" y lo que se pasa no es la casa\ncomo tal, sino que lo que se pasa es su \"dirección\" para poder ubicarla.\n*/\n\nlet x = [1, 2, 3]\nlet y = x\nx.push(4)\nconsole.log(x) // [ 1, 2, 3, 4 ]\nconsole.log(y) // [ 1, 2, 3, 4 ]\n\n/**\nEn el ejemplo anterior, se puede observar que a la variable \"x\" se le está agregando un nuevo valor, sin embargo, tanto el valor de \"x\" como\nde \"y\" es exactamente el mismo. Esto se debe a que las variables tienen diferente nombre, pero el valor que estamos modificando es el mismo.\n*/\n\n/**\n<-------------- Variable por valor y referencia en funciones -------------->\nLa diferencia entre pasar una variable por referencia o por valor es con respecto a lo que pasa dentro y fuera de la función.\n\n<-------------- Variable por valor en funciones -------------->\nCuando pasamos una variable por valor, las acciones que ocurren dentro de esta NO repercuten fuera de ella, o sea que dichas acciones solo viven\ndentro de la función y NO alteran el código fuera de la función. Recordemos que el valor que recibe la función es una \"copia\" del valor original.\n*/\n\nlet animalPorValor = \"perro\" // Valor original\n\nfunction mascotaPorValor(animal) {\n\tanimal = \"gato\" // Re-asignación\n\tconsole.log(`Dentro de la función el animal es: ${animal}`) // Dentro de la función el animal es: gato\n}\n\nmascotaPorValor(animalPorValor) \nconsole.log(`Fuera de la función el animal es: ${animalPorValor}`) // Fuera de la función el animal es: perro\n\n/**\n<-------------- Variable por referencia en funciones -------------->\nCuando pasamos una variable por referencia, las acciones que ocurren dentro de esta SÍ repercuten fuera de ella, o sea que dichas acciones viven\ntanto dentro como fuera de la función, por ende alteran todo el código. Recordemos que el valor que recibe la función es una referencia o \ndirección que apunta hacia el valor original.\n*/\n\nlet arrayDeMascotas = [\"conejo\"] // Valor original\n\nfunction mascotaPorReferencia(animales) {\n\tanimales[1] = \"gato\" // Agregar un nuevo elemento\n\tconsole.log(`Dentro de función el array tiene: ${animales}`) // Dentro de la función el array tiene: conejo,gato\n}\n\nmascotaPorReferencia(arrayDeMascotas)\nconsole.log(`Fuera de la función el array tiene: ${arrayDeMascotas}`) // Fuera de la función el array tiene: conejo,gato"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/shevotool.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n */\n\n// por valor (valores primitivos)\nlet ejercicio = \"caminar\";\nlet copia = ejercicio;\n\nejercicio = \"pesas\";\nconsole.log(ejercicio);\nconsole.log(copia);\n\n// por referencia (valores complejos)\nconst array = [1, 2, 3];\nconst array2 = array;\narray.push(4);\n\nconsole.log(array);\nconsole.log(array2);\n\n/*   - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n    \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n  (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes) */\n\n// funciones por valor (valores primitivos)\n\nlet numeroRandom = 0;\n\nfunction modificarNumero(numeroRandom) {\n  return (numeroRandom = 4);\n}\n\nconsole.log(numeroRandom);\nconsole.log(modificarNumero(2));\n\n// funciones por referencia (valores complejos)\n\nlet tareas = [\"trabajar\", \"estudiar\", \"entrenar\"];\n\nfunction agregarTarea(tareas) {\n  return tareas.push(\"dormir\");\n}\n\nconsole.log(agregarTarea(tareas));\nconsole.log(tareas);\n\n/*  * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\n// funcion por valor (valores primitivos)\n\nlet numero1 = 10;\nlet numero2 = 20;\n\nfunction cambiarValorEnNumeros(numero1, numero2) {\n  numero1 = 20;\n  numero2 = 10;\n  return [numero1, numero2];\n}\n\nconst [copia1, copia2] = cambiarValorEnNumeros(numero1, numero2);\n\nconsole.log(copia1);\nconsole.log(copia2);\n\nconsole.log(numero1);\nconsole.log(numero2);\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/victor-Casta.js",
    "content": "/*\n  * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n  *   su tipo de dato.\n*/\n\n//Asignación por valor\nlet number1 = 10;\nlet number2 = number1;\nconsole.log(number1);\nconsole.log(number2);\n\n//asignacion por referencia\nlet myArray1 = [10, 20];\nlet myArray2 = myArray1;\n\nmyArray2.push(30);\n\nconsole.log(myArray1);\nconsole.log(myArray2);\n\n/*\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y\n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n*/\n\nconst porValor = (x) => {\n  let y = x;\n  console.log(\"Dentro de porValor:\");\n  console.log(\"Original:\", x);\n  console.log(\"Copia:\", y);\n  y = 20;\n  console.log(\"Después de modificar la copia en porValor:\");\n  console.log(\"Original:\", x);\n  console.log(\"Copia:\", y);\n}\n\nconst porReferencia = (arr) => {\n  let copiaArr = arr;\n  console.log(\"Dentro de porReferencia:\");\n  console.log(\"Original:\", arr);\n  console.log(\"Copia:\", copiaArr);\n  copiaArr.push(4);\n  console.log(\"Después de modificar la copia en porReferencia:\");\n  console.log(\"Original:\", arr);\n  console.log(\"Copia:\", copiaArr);\n}\n\nporValor(10);\n\nconst originalArray = [1, 2, 3];\nporReferencia(originalArray);\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n*/\n\n//por Valor\n\nlet number3 = 10;\nlet number4 = 20;\n\nconst program1 = (param1, param2) => {\n  let temp = param1;\n  param1 = param2;\n  param2 = temp;\n  return { param1, param2 };\n}\n\nconst resultados = program1(number3, number4);\n\nconst rtaParam1 = resultados.param1;\nconst rtaParam2 = resultados.param2;\n\nconsole.log(`Parametro 1 Original: ${number3}, Nuevo: ${rtaParam1}`);\nconsole.log(`Parametro 2 Original: ${number4}, Nuevo: ${rtaParam2}`);\n\n\n//por referencia\n\nlet list1 = [10, 20];\nlet list2 = [30, 40];\n\nconst program2 = (param1, param2) => {\n  let temp = param1;\n  param1 = param2;\n  param2 = temp;\n  return [  param1, param2 ];\n}\n\nconst resultados2 = program2(list1, list2);\n\nconst rtaList1 = resultados2[0]\nconst rtaList2 = resultados2[1]\n\nconsole.log(`Parametro 1 Original: ${JSON.stringify(list1)}, Nuevo: ${JSON.stringify(rtaList1)}`);\nconsole.log(`Parametro 2 Original: ${JSON.stringify(list2)}, Nuevo: ${JSON.stringify(rtaList2)}`);\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/wapastorv.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\n// Por valor\nvar a = 1;\nvar b = a;\nb = 2;\nconsole.log(a); // 1\nconsole.log(b); // 2\n\n// Por referencia\nvar obj1 = { name: 'John' };\nvar obj2 = obj1;\nobj2.name = 'Jane';\nconsole.log(obj1.name); // Jane\nconsole.log(obj2.name); // Jane\n\n// Por valor\nfunction addOne(num) {\n  num++;\n}\nvar num = 1;\naddOne(num); // num es pasado por valor\nconsole.log(num); // 1\n\n// Por referencia\nfunction changeName(obj) {\n  obj.name = 'Jane';\n}\nvar obj = { name: 'John' };\nchangeName(obj); // obj es pasado por referencia\nconsole.log(obj.name); // Jane\n\n// DIFICULTAD EXTRA\nfunction swapByValue(a, b) {\n  var temp = a;\n  a = b;\n  b = temp;\n  return [a, b];\n}\n\nfunction swapByReference(obj1, obj2) {\n  var temp = obj1.name;\n  obj1.name = obj2.name;\n  obj2.name = temp;\n  return [obj1, obj2];\n}\n\nvar a = 1;\nvar b = 2;\nvar obj1 = { name: 'John' };\nvar obj2 = { name: 'Jane' };\n\nvar swappedValues = swapByValue(a, b);\nvar swappedReferences = swapByReference(obj1, obj2);\n\nconsole.log(a); // 1\nconsole.log(b); // 2\nconsole.log(swappedValues[0]); // 2\nconsole.log(swappedValues[1]); // 1\n\nconsole.log(obj1.name); // Jane\nconsole.log(obj2.name); // John\nconsole.log(swappedReferences[0].name); // John\nconsole.log(swappedReferences[1].name); // Jane\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/wolffcode.js",
    "content": "/*\n* EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n*/\n\n        // asignación por valor\nlet color = 'naranja'\nlet fruta = color\n\ncolor = 'amarillo'\nconsole.log(color)\nconsole.log(fruta)\n\n        // asignación por referencia\nconst arr = [1,2,3,4,5]\nconst arr2 = arr\n\narr.push(10)\nconsole.log(arr)\nconsole.log(arr2)\n\n        // funciones por valores\nfunction valor(numero){\n    numero --\n    console.log(numero)\n}\nlet numero = 5\nvalor(numero)\nconsole.log(numero)\n\n        // funciones por referencia\nfunction referencia(fruta){\n    fruta.cantidad = 3\n    console.log(`la cantidad de ${frutaObj.nombre} es: ${frutaObj.cantidad} dentro de la función`)\n}\nconst frutaObj = {\n    nombre: 'banana',\n    cantidad: 4\n}\nreferencia(frutaObj)\nconsole.log(`la cantidad de ${frutaObj.nombre} es: ${frutaObj.cantidad} fuera de la función`)\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/javascript/xmunder.js",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y\n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\n// Ejemplo de asignación por valor para tipos primitivos\nlet a = 10;\nlet b = a; // Asignación por valor\nb = 20; // Modificar 'b' no afecta 'a'\nconsole.log(a); // Resultado: 10\n\n// Ejemplo de asignación por referencia para objetos\nlet array1 = [1, 2, 3];\nlet array2 = array1; // Ambas variables apuntan al mismo objeto en la memoria\n\narray2.push(4); // Modificar 'array2' afecta a 'array1'\nconsole.log(array1); // Resultado: [1, 2, 3, 4]\n\n// Ejemplo de función que recibe parámetros por valor\nfunction modificarNumero(num) {\n  num = 100; // Modificar el parámetro 'num' no afecta el valor original\n}\n\nlet x = 5;\nmodificarNumero(x);\nconsole.log(x); // Resultado: 5\n\n// Ejemplo de función que recibe parámetros por referencia (objeto)\nfunction modificarArray(arr) {\n  arr.push(4); // Modificar el parámetro 'arr' afecta al array original\n}\n\nlet miArray = [1, 2, 3];\nmodificarArray(miArray);\nconsole.log(miArray); // Resultado: [1, 2, 3, 4]\n\nfunction intercambiarPorValor(a, b) {\n  let temp = a;\n  a = b;\n  b = temp;\n  return [a, b];\n}\n\n//DIFICULTAD EXTRA\n// Definir variables\nlet valor1 = 10;\nlet valor2 = 20;\n\n// Llamar a la función y asignar los resultados a nuevas variables\nlet nuevosValores = intercambiarPorValor(valor1, valor2);\nlet nuevoValor1 = nuevosValores[0];\nlet nuevoValor2 = nuevosValores[1];\n\n// Imprimir resultados\nconsole.log(\"Original (por valor):\", valor1, valor2); // Original (por valor): 10 20\nconsole.log(\"Nuevos (por valor):\", nuevoValor1, nuevoValor2); // Nuevos (por valor): 20 10\nconsole.log(\"Comprobación:\", valor1, valor2); // Comprobación: 10 20\n\nfunction intercambiarPorReferencia(obj) {\n  let temp = obj.prop1;\n  obj.prop1 = obj.prop2;\n  obj.prop2 = temp;\n  return obj;\n}\n\n// Definir objeto\nlet objeto = { prop1: \"hola\", prop2: \"mundo\" };\n\n// Llamar a la función y asignar los resultados a un nuevo objeto\nlet nuevoObjeto = intercambiarPorReferencia(objeto);\n\n// Imprimir resultados\nconsole.log(\"Original (por referencia):\", objeto.prop1, objeto.prop2); // Original (por referencia): hola mundo\nconsole.log(\"Nuevo (por referencia):\", nuevoObjeto.prop1, nuevoObjeto.prop2); // Nuevo (por referencia): mundo hola\nconsole.log(\"Comprobación:\", objeto.prop1, objeto.prop2); // Comprobación: mundo hola\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/kotlin/AnCarlu.kt",
    "content": "fun main() {\n    //Asignacion de variables por valor\n\n    var a = 10\n    var b = a //Aqui se copia el valor\n    a = 20\n\n    println(\n        \"Asignación de variable por valor:\" +\n                \"\\na=$a, b=$b\"\n    )\n\n    //Asignacion de variables por referencia\n    data class Refer(var value: Int)\n\n    var x = Refer(5)\n    var y = x //Aqui ambas apuntan al mismo objeto, lo que se copia es la referencia, no el valor\n    y.value = 10\n    println(\n        \"Asignacion de variable por referencia:\" +\n                \"\\nAmbas variables apuntan al mismo objeto, \" +\n                \"\\npor lo que al cambiar el valor en una de las dos variables\" +\n                \"\\nambas se cambian:\" +\n                \"\\nx=${x.value}, y=${y.value}\"\n    )\n\n    //Funciones con paremetros por valor\n    fun modiferValue(number: Int): Int {\n        return number + 5\n    }\n\n    var numero = 10\n    println(\"El numero antes de cambiarlo $numero\")\n    numero = modiferValue(numero)\n    println(\"Despues de cambiarlo $numero\")\n\n    //Funcion con parametro por referencia\n    fun modifierRefer(refer: Refer) {\n        refer.value = 100\n    }\n\n    var newNumber = Refer(50)\n    println(\"Antes de cambiar la referencia ${newNumber.value}\")\n    modifierRefer(newNumber)\n    println(\"Despues de cambiar la referencia ${newNumber.value}\")\n\n\n    //Extra\n\n    var number1 = 10\n    var number2 = 20\n    //Programa para intercambiar las variables por valor\n    println(\"Programa para intercambiar variables por valor:\")\n    fun extraValor(x: Int, y: Int): Pair<Int, Int> {\n        /*\n        Los parametros en kotlin son inmutables, por lo que no se pueden reasignar,\n        para ello primero hay que crear nuevas variables\n         */\n        var number1 = x\n        var number2 = y\n        number1 += 5\n        number2 += 8\n        return Pair(number1, number2)\n    }\n\n    println(\"Valores antes de cambiar $number1 y $number2\")\n    var changeNumber = extraValor(number1, number2)\n    number1 = changeNumber.first\n    number2 = changeNumber.second\n    println(\"Valores despues de cambiar $number1 y $number2\")\n\n    //Programa para intercambiar los parametros por referencia\n    println(\"Programa para intercambiar parametros por referencia:\")\n    data class Persona(var nombre: String)\n\n    var myName = Persona(\"Adrian\")\n    var yourName = Persona(\"Jorge\")\n    fun extraReferencia(a: Persona, b: Persona): Pair<Persona, Persona> {\n        a.nombre = \"Pepe\"\n        b.nombre = \"Jose\"\n        var extraName1 = a.nombre\n        var extraName2 = b.nombre\n\n        return Pair(Persona(extraName1), Persona(extraName2))\n    }\n\n    println(\"Nombres antes de cambiar ${myName.nombre} y ${yourName.nombre}\")\n    extraReferencia(myName, yourName)\n    println(\"Nombres despues de cambiar ${myName.nombre} y ${yourName.nombre}\")\n}"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/kotlin/Luis-VB.kt",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y\n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n */\n\n//kotlinc Luis-VB.kt -include-runtime -d Luis-VB.jar\n//java -jar Luis-VB.jar\n\nopen class LuisRetos {\n\n    fun byValue(a: Int, b: Int) {\n        println(\"Valor de a: $a\")\n        println(\"Valor de b: $b\")\n    }\n\n    fun byReference(listOne: MutableList<Int>, listTwo: MutableList<Int>) {\n        listTwo.add(4)\n        println(\"Valor de listOne: $listOne\")\n    }\n}\n\nfun main() {\n    val retos = LuisRetos()\n    retos.byValue(10, 20)\n    val listOne = mutableListOf(1, 2, 3)\n    val listTwo = listOne\n    retos.byReference(listOne, listTwo)\n\n    var x = 10\n    var y = 20\n    y += 5\n\n    println(\"\\nPasar por valor:\")\n    println(\"x: $x\")\n    println(\"y: $y\")\n\n    var lista1 = mutableListOf(1, 2, 3)\n    var lista2 = lista1\n    lista2.add(4)\n    println(\"\\nPasar por referencia:\")\n    println(\"lista1: $lista1\")\n    println(\"lista2: $lista2\")\n\n    fun porValor(a: Int) {\n        var b = a\n        b += 5\n        println(\"Valor de a: $a\")\n    }\n    println(\"\\nFuncion con variables por valor:\")\n    porValor(34546)\n\n    fun porReferencia(lista: MutableList<Int>) {\n        lista.add(4)\n        lista.add(5)\n        println(\"Valor de lista: $lista\")\n        lista.remove(5)\n        println(\"Valor de lista: $lista\")\n    }\n    println(\"\\nFuncion con variables por referencia:\")\n    porReferencia(mutableListOf(1, 2, 3))\n\n    /* DIFICULTAD EXTRA (opcional):\n    * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n    * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n    *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n    *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n    *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n    *   Comprueba también que se ha conservado el valor original en las primeras.\n    */\n\n    fun programaPorValor(x: Int, y: Int): Pair<Int, Int> {\n        return Pair(y, x)\n    }\n\n    fun programaPorReferencia(lista1: MutableList<Int>, lista2: MutableList<Int>): Pair<MutableList<Int>, MutableList<Int>> {\n        return Pair(lista2, lista1)\n    }\n\n    val swappedValues = programaPorValor(x, y)\n    println(\"\\nOriginal values x and y: $x, $y\")\n    println(\"Returned values x and y: ${swappedValues.first}, ${swappedValues.second}\")\n\n    val lista3 = mutableListOf(10, 20, 30)\n    val lista4 = mutableListOf(40, 50, 60)\n    val swappedReferences = programaPorReferencia(lista3, lista4)\n    println(\"\\nOriginal references: $lista3, $lista4\")\n    println(\"Returned references: ${swappedReferences.first}, ${swappedReferences.second}\")\n}"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/kotlin/OcandoDev.kt",
    "content": "data class Person(var name: String)\ndata class Number(var value: Int)\n\nfun main() {\n\n    // Asignacion por valor: Crea una copia y la modifica sin afectar al valor original\n\n    val number1 = 5\n    var number2 = number1\n\n    number2 += 10\n    println(\"a: $number1 ; b: $number2\\n\")\n\n    // Asignacion por referencia: Afecta el valor original de la variable\n\n    val person1 = Person(\"Moure\")\n    val person2 = person1\n\n    person2.name = \"Alejandro\"\n\n    println(\"Person1: ${person1.name} ; Person2: ${person2.name}\\n\")\n\n    var value = 5\n    incrementarPorValor(value)\n    println(\"Fuera de la función: $value\\n\")  // No cambia el valor original, pero cambia el valor de la copia\n\n    val person3 = Person(\"AntiguoNombre\")\n    cambiarNombrePorReferencia(person3)\n    println(\"Nuevo nombre: ${person3.name}\\n\")  // La funcion afecta al valor original\n\n    //Extra//\n\n    println(\"Extra!!\")\n\n    val originalA = 10\n    val originalB = 20\n    val intercambio1 = intercambiarPorValor(originalA, originalB)\n    println(\"\"\"\n        \n        Valores originales: A = ${originalA} ; B = ${originalB}\n        Valores intercambiados: A = ${intercambio1.first} ; B = ${intercambio1.second}\n        \n    \"\"\".trimIndent())\n\n    val originalC = Number(20)\n    val originalD = Number(40)\n    val intercambio2 = intercambiarPorReferencia(originalC, originalD)\n    println(\"\"\"\n        \n        Valores originales: C = ${originalC.value} ; D = ${originalD.value}\n        Valores intercambiados: C = ${intercambio2.first.value} ; D = ${intercambio2.second.value}\n        \n    \"\"\".trimIndent())\n\n}\n\nfun incrementarPorValor(number: Int) {\n    println(\"Dentro de la función: ${number + 1}\\n\") // No afecta a la variable fuera de la funcion\n}\n\nfun cambiarNombrePorReferencia(person: Person) {\n    person.name = \"NuevoNombre\"\n}\n\nfun intercambiarPorValor(a: Int, b: Int): Pair<Int, Int>{\n    val temporal = a\n    val newA = b\n    val newB = temporal\n\n    return Pair(newA, newB)\n}\n\nfun intercambiarPorReferencia(a: Number, b: Number): Pair<Number,Number>{\n    val temporal = a.value\n    a.value = b.value\n    b.value = temporal\n\n    return Pair(a, b)\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/kotlin/VincentRodriguezR.kt",
    "content": "class valueReference{\n\n    fun main(){\n\n        //Asigancion por valores\n        var value1 = \"Las asignaciones por valores cambian el valor de la variable de forma independiente, en este caso value2 toma la forma de value1\"\n        var value2 = value1\n        println(value1)\n        println(value2)\n        value2 = \"En este caso si cambiamos el valor de value2 solo se cambiara para esta variable dejando value1 como se deifnio en el inicio, se comportan como variables independientes\"\n        println(value1)\n        println(value2)\n        val value3 = \"estas asignaciones funcionan de esta manera para los tipos de datos primitivos incluyendo los arrays creados con arrayOf\"\n\n        //Asignacion por referencia\n        var reference1 = mutableListOf(1, 2, 3)\n        var reference2 = reference1\n        println(\"En este caso reference2 toma la forma de reference1 pero no son valores independientes, ambas variables apuntan al mismo espacio en memoria\")\n        println(\"reference1: $reference1, reference2:$reference2\")\n        reference2.add(4)\n        println(\"En este caso al agregar un valor a reference2 este valor extra lo veremos reflejado en reference1 ya que independientemente de que no lo agregamos en el original reference2 interactua como un puntero hacia reference1 \")\n        println(\"reference1: $reference1, reference2: $reference2\")\n\n        //Funciones con asignacion por valores y referencias\n        var number = 10\n        fun value(num: Int){\n            var innerNumber = 5\n            println(\"En este caso si ceramos una variable en la funcion la podremos reasignar dentro de la misma, pero no podemos reasignar el parametro de entrada de la funcion\")\n            println(\"Numero original $innerNumber\")\n            innerNumber = 15\n            println(\"Numero reasignado $innerNumber\")\n            //La siguente instruccion intenta reasignar el parametro num recibido por la funcion, esta con comentario ya que genera un error ya que esto no es permitido en Kotlin\n            //num = 20\n        }\n        value(number)\n\n        //Funciones por referencia\n        fun reference(list: MutableList<Int>){\n            println(\"En este caso al igual que las asignaciones por valor no se puede reasignar la variable, pero con las referencias si podemos añadir datos a los objetos desde las funciones\")\n            println(\"Lista Original: $list\")\n            list.add(4)\n            println(\"Lista alterada: $list\")\n        }\n\n        var list = mutableListOf(1, 2, 3)\n        println(\"Aca comprobamos que la lista original tiene la siguiente forma antes de la adicion realizada en la funcion: $list\")\n        reference(list)\n        println(\"Por ultimo ya que se ha realizado la adicion en la funcion queda de la siguiente forma la lista: $list\")\n\n        //Punto Extra\n        //Por valor\n        var newValue1 = 10\n        var newValue2 = 20\n        fun valueExchange(value1: Int, value2: Int): Pair<Int, Int>{\n            //En kotlin los parametros de entrada son inmutables, por lo que para reasignarlos y cambiarlos debemos crear una variable nueva\n            var newValue1 = value1\n            var newValue2 = value2\n            var temporalValue = value1\n            newValue2 = newValue1\n            newValue1 = temporalValue\n\n            return Pair(newValue1, newValue2)\n        }\n\n        println(\"Primer valor inicial: $newValue1, Segundo valor inicial: $newValue2\")\n        var assignedPair = valueExchange(newValue1, newValue2)\n        newValue1 = assignedPair.first\n        newValue2 = assignedPair.second\n        println(\"Primer valor final: $newValue1, Segundo valor final: $newValue2\")\n\n        //Por referencia\n        var newList1 = mutableListOf(1, 2, 3)\n        var newList2 = mutableListOf(4, 5, 6, 7)\n        fun referenceExchange(list1: MutableList<Int>, list2: MutableList<Int>): Pair<MutableList<Int>, MutableList<Int>>{\n            var newList1 = list1\n            var newList2 = list2\n            var temporalReference = list1\n            newList1 = list2\n            newList2 = temporalReference\n\n            return Pair(newList1, newList2)\n        }\n        println(\"Primera Lista inicial: $newList1, Segunda Lista Inicial: $newList2\")\n        var assignedReference = referenceExchange(newList1, newList2)\n        newList1 = assignedReference.first\n        newList2 = assignedReference.second\n        println(\"Primera Lista Final: $newList1, Segunda Lista Final: $newList2\")\n    }\n\n\n    companion object {\n        @JvmStatic\n        fun main(args: Array<String>) {\n            val obj = valueReference()\n            obj.main()\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/kotlin/blackriper.kt",
    "content": "/*\r\n   En Kotlin no se pueden usar referencias o punteros a memoria , se utiliza la referencia de objeto para representar una ubicación de memoria.\r\n   Las referencias de objeto son seguras por defecto, ya que no es posible que apunten a una\r\n   ubicación de memoria que ya no contenga datos. Esto se debe a que Kotlin utiliza el sistema\r\n   de recolección de basura para gestionar la memoria. Cuando un objeto ya no se utiliza, se\r\n   elimina de la memoria y las referencias a ese objeto se vuelven nulas.\r\n*/\r\n\r\n// en kotlin tenemos dos referencias de objetos val y var\r\nval a=1\r\nvar b=1\r\n\r\nfun test() {\r\n   // a=2 marca error porque a es val y no se puede reasignar\r\n    b=2\r\n}\r\n\r\n// extra\r\nfun changeParams( p1:Int) {\r\n    //a=p1 marca error porque a es val y no se puede reasignar\r\n    b=a\r\n    b=p1\r\n}\r\n\r\n\r\nfun main() {\r\n    val c=b\r\n    test()\r\n    println(b)\r\n    changeParams(5)\r\n    // a siempre sera inmutable mientras b cambia de acuerdo a su referencia de objeto perdiendo el valor original a menos que se conserve en otra variable\r\n    println(b)\r\n    println(a)\r\n    println(c)\r\n}\r\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/kotlin/deivitdev.kt",
    "content": "fun main() {\n    // Asignación por valor\n    val a = 1\n    var b = a\n    b = 2\n    println(\"a = $a\")\n    println(\"b = $b\")\n\n    // Asignación por referencia\n    val c = mutableListOf(1, 2, 3)\n    val d = c\n    d.add(4)\n    println(\"c = $c\")\n    println(\"d = $d\")\n\n    // llamada a función con parámetros por valor\n    println(\"a after function call = ${functionWithParametersByValue(a)}\")\n\n    // llamada a función con parámetros por referencia\n    println(\"c after function call = ${functionWithParametersByReference(c)}\")\n\n    // ---------- Reto ----------\n\n    // Intercambio de valores por valor\n    println(\"Swap by value: ${swapByValue(a, b)}\")\n\n    // Intercambio de valores por referencia\n    println(\"Swap by reference: ${\n        swapByReference(mutableListOf(1, 2, 3), mutableListOf(4, 5, 6))\n    }\")\n}\n\n// función con parámetros por valor\nfun functionWithParametersByValue(a: Int): Int {\n    return a + 1\n}\n\n// función con parámetros por referencia\nfun functionWithParametersByReference(a: MutableList<Int>): MutableList<Int> {\n    a.add(1)\n    return a\n}\n\nfun swapByValue(a: Int, b: Int): Pair<Int, Int> {\n    return Pair(b, a)\n}\n\nfun swapByReference(\n    a: MutableList<Int>,\n    b: MutableList<Int>,\n): Pair<MutableList<Int>, MutableList<Int>> {\n    return Pair(b, a)\n}"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/kotlin/didacdev.kt",
    "content": "fun main() {\n\n    // Paso por valor\n    var valorUno = 3\n    var valorDos = 5\n\n    val variablesValor = variablesValor(valorUno, valorDos)\n\n    val newValorUno = variablesValor.first\n    val newValorDos = variablesValor.second\n\n    println(\"Variables por valor originales: \")\n    println(\"$valorUno $valorDos\")\n    println(\"Variables por valor nuevas: \")\n    println(\"$newValorUno $newValorDos\")\n\n    // Paso por referencia\n    var referenciaUno = arrayOf(2)\n    var referenciaDos = arrayOf(4)\n\n    val variablesReferencia = variablesReferencia(referenciaUno, referenciaDos)\n\n    val newReferenciaUno = variablesReferencia.first\n    val newReferenciaDos = variablesReferencia.second\n\n    println(\"Variables por referencia originales: \")\n    println(\"${referenciaUno[0]} ${referenciaDos[0]}\")\n    println(\"Variables por referencia nuevas: \")\n    println(\"${newReferenciaUno[0]} ${newReferenciaDos[0]}\")\n}\n\nfun variablesValor(variableUno: Int, variableDos: Int): Pair<Int, Int> {\n    val copyVariableUno = variableUno\n    val copyVariableDos = variableDos\n    \n    return Pair(copyVariableDos, copyVariableUno)\n}\n\nfun variablesReferencia(variableUno: Array<Int>, variableDos: Array<Int>): Pair<Array<Int>, Array<Int>> {\n    val temp = variableUno[0]\n    variableUno[0] = variableDos[0]\n    variableDos[0] = temp\n\n    return Pair(variableUno, variableDos)\n}"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/kotlin/eulogioep.kt",
    "content": "fun main() {\n    println(\"1. Asignación de variables por valor y por referencia:\")\n    // Por valor (tipos primitivos)\n    var numero1 = 5\n    var numero2 = numero1\n    numero2 = 10\n    println(\"  Por valor:\")\n    println(\"  numero1: $numero1\") // 5\n    println(\"  numero2: $numero2\") // 10\n\n    // Por referencia (objetos)\n    data class Persona(var nombre: String)\n    val persona1 = Persona(\"Alice\")\n    val persona2 = persona1\n    persona2.nombre = \"Bob\"\n    println(\"  Por referencia:\")\n    println(\"  persona1.nombre: ${persona1.nombre}\") // Bob\n    println(\"  persona2.nombre: ${persona2.nombre}\") // Bob\n\n    println(\"\\n2. Funciones con parámetros por valor y por referencia:\")\n    // Función con parámetro por valor\n    fun incrementar(x: Int): Int {\n        return x + 1\n    }\n\n    var a = 5\n    println(\"  Por valor:\")\n    println(\"  Antes de incrementar: $a\")\n    a = incrementar(a)\n    println(\"  Después de incrementar: $a\")\n\n    // Función con parámetro por referencia\n    fun cambiarNombre(persona: Persona, nuevoNombre: String) {\n        persona.nombre = nuevoNombre\n    }\n\n    val persona = Persona(\"Charlie\")\n    println(\"  Por referencia:\")\n    println(\"  Antes de cambiar nombre: ${persona.nombre}\")\n    cambiarNombre(persona, \"David\")\n    println(\"  Después de cambiar nombre: ${persona.nombre}\")\n\n    println(\"\\n3. Programa que intercambia valores por valor:\")\n    fun intercambiarPorValor(a: Int, b: Int): Pair<Int, Int> {\n        return Pair(b, a)\n    }\n\n    var original1 = 10\n    var original2 = 20\n    println(\"  Originales antes: $original1, $original2\")\n\n    val (nuevo1, nuevo2) = intercambiarPorValor(original1, original2)\n    println(\"  Originales después: $original1, $original2\")\n    println(\"  Nuevas variables: $nuevo1, $nuevo2\")\n\n    println(\"\\n4. Programa que intercambia valores por referencia:\")\n    data class Contenedor(var valor: Int)\n\n    fun intercambiarPorReferencia(a: Contenedor, b: Contenedor): Pair<Contenedor, Contenedor> {\n        val temp = a.valor\n        a.valor = b.valor\n        b.valor = temp\n        return Pair(Contenedor(a.valor), Contenedor(b.valor))\n    }\n\n    val originalRef1 = Contenedor(10)\n    val originalRef2 = Contenedor(20)\n    println(\"  Originales antes: ${originalRef1.valor}, ${originalRef2.valor}\")\n\n    val (nuevoRef1, nuevoRef2) = intercambiarPorReferencia(originalRef1, originalRef2)\n    println(\"  Originales después: ${originalRef1.valor}, ${originalRef2.valor}\")\n    println(\"  Nuevas variables: ${nuevoRef1.valor}, ${nuevoRef2.valor}\")\n}"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/kotlin/juanppdev.kt",
    "content": "fun main() {\n    // Asignación de variables por valor\n    var a = 10\n    var b = a\n    println(\"Asignación por valor:\")\n    println(\"a: $a, b: $b\")\n\n    // Modificación de variable por valor\n    b = 20\n    println(\"Después de modificar b:\")\n    println(\"a: $a, b: $b\")\n    println()\n\n    // Asignación de variables por referencia\n    val listaOriginal = mutableListOf(1, 2, 3)\n    val listaReferencia = listaOriginal\n    println(\"Asignación por referencia:\")\n    println(\"Original: $listaOriginal, Referencia: $listaReferencia\")\n\n    // Modificación de variable por referencia\n    listaReferencia.add(4)\n    println(\"Después de modificar la lista por referencia:\")\n    println(\"Original: $listaOriginal, Referencia: $listaReferencia\")\n    println()\n\n    // Función con parámetro por valor\n    val originalX = 5\n    val resultadoX = duplicarPorValor(originalX)\n    println(\"Función con parámetro por valor:\")\n    println(\"Original: $originalX, Resultado: $resultadoX\")\n\n    // Función con parámetro por referencia (mutableList)\n    val originalList = mutableListOf(1, 2, 3)\n    duplicarPorReferencia(originalList)\n    println(\"Función con parámetro por referencia:\")\n    println(\"Original: $originalList\")\n}\n\nfun duplicarPorValor(x: Int): Int {\n    return x * 2\n}\n\nfun duplicarPorReferencia(lista: MutableList<Int>) {\n    for (i in 0 until lista.size) {\n        lista[i] *= 2\n    }\n}\n\n// Ejercicio extra\nfun main() {\n    // Programa con parámetros por valor\n    val a = 5\n    val b = 10\n    val resultadoValor = intercambiarPorValor(a, b)\n    println(\"Programa con parámetros por valor:\")\n    println(\"a: $a, b: $b\")\n    println(\"Resultado: $resultadoValor\")\n    println()\n\n    // Programa con parámetros por referencia\n    val listaOriginal = mutableListOf(1, 2, 3)\n    val listaReferencia = mutableListOf(4, 5, 6)\n    intercambiarPorReferencia(listaOriginal, listaReferencia)\n    println(\"Programa con parámetros por referencia:\")\n    println(\"Original: $listaOriginal\")\n    println(\"Referencia: $listaReferencia\")\n}\n\nfun intercambiarPorValor(x: Int, y: Int): Pair<Int, Int> {\n    // Intercambio de valores\n    val temp = x\n    val resultadoX = y\n    val resultadoY = temp\n    return Pair(resultadoX, resultadoY)\n}\n\nfun intercambiarPorReferencia(lista1: MutableList<Int>, lista2: MutableList<Int>) {\n    // Intercambio de listas\n    val temp = ArrayList(lista1)\n    lista1.clear()\n    lista1.addAll(lista2)\n    lista2.clear()\n    lista2.addAll(temp)\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/kotlin/miguelex.kt",
    "content": "class Persona(var name: String, var age: Int)\n\nfun intercambioPorvalor(num1: Int, num2: Int) : Pair<Int, Int> {\n    var aux = num1\n    var num1 = num2\n    var num2 = aux\n\n    return Pair(num1, num2)\n}\n\nfun intercambioPorReferencia(persona1: Persona, persona2: Persona): Pair<Persona, Persona>{\n    var aux = persona1\n    var persona1 = persona2\n    var persona2 = aux\n\n    return Pair(persona1, persona2)\n}\nfun main() {\n\n    var num1 = 1\n    var num2 = num1\n\n    println(\"Valor de las variables por valor\")\n    println(num1)\n    println(num2)\n\n    num1 = 10\n\n    println(\"Valor de las variables por valor tras modificar num1\")\n    println(num1)\n    println(num2)\n\n    var persona1 = Persona(\"Miguel\", 25)\n    var persona2 = persona1\n\n    println(\"Valor de las variables por referencia\")\n    println(persona1.name)\n    println(persona2.name)\n\n    persona1.name = \"Miguel Angel\"\n\n    println(\"Valor de las variables por referencia\")\n    println(persona1.name)\n    println(persona2.name)\n\n    num1 = 5\n    num2 = 10\n\n    println(\"Valor de num1 antes del intercambio = $num1\")\n    println(\"Valor de num2 antes del intercambio = $num2\")\n\n    var result: Pair<Int, Int> = intercambioPorvalor(num1, num2)\n\n    println(\"Intercambio de valores entre $num1 y $num2\")\n    println(\"Valor de num1 despues del intercambio = $num1\")\n    println(\"Valor de num2 despues del intercambio = $num2\")\n    println(\"Valor devuelto para num1 en el intercambio = $result.first\")\n    println(\"Valor devuelvo para num2 en el intercambio = $result.second\")\n\n    persona1 = Persona(\"Juan\", 30)\n    persona2 = Persona(\"María\", 40) \n\n    println(\"Valor de persona1 antes del intercambio = ${persona1.name}\")\n    println(\"Valor de persona2 antes del intercambio = ${persona2.name}\")\n\n    var result2: Pair<Persona, Persona> = intercambioPorReferencia(persona1, persona2)\n\n    println(\"Intercambio de valores entre ${persona1.name} y ${persona2.name}\")\n    println(\"Valor de persona1 despues del intercambio = ${persona1.name}\")\n\n    println(\"Valor de persona2 despues del intercambio = ${persona2.name}\")\n    println(\"Valor devuelto para persona1 en el intercambio = ${result2.first.name}\")\n    println(\"Valor devuelvo para persona2 en el intercambio = ${result2.second.name}\")\n\n\n}"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/kotlin/pedroomar23.kt",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\n // Asignacion de variables por valor \n val x = 5 // El valor de variable x mantiene su valor \n val y = x // El valor de la variable y cambia al valor de la variable x \n\n prinln(x) // Imprimir en la consola el valor de la variable x \n println(y) // Imprimir en la consola el valor de la variables y\n\n // Asignacion de valores por referencia \n data class Person(nombre: String) \n\n val nombre1 = Person(\"Carlos\") \n val nombre2 = nombre1\n\n // Funcion de asignacion de variables por valor \n fun sum(a: Int) {\n    println(a + 2) // Esto modifica una copia del numero y aumenta el valor en 2\n }\n\n fun restar(b: Int) {\n    println(b - 2) // Esto modifica una copia del numero y resta el valor en 2\n }\n\n // Funcion de asignacion de valores por referencia \n fun modify(person: Person) {\n    person.nombre = \"Juan\"\n }\n\n val persons = Person(\"Oscar\")\n modify(person)\n println(person.name) // En esta ocacion imprimira \"Oscar\" porque se ha modificado el objeto referenciado en person\n\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/kotlin/rikmij.kt",
    "content": "// EN Kotlin no existe el paso por referencia, nunca se pasa el valor en sí, siempre una copia\n\nfun ejerExtra() {\n    fun valueFunction(val1: String, val2: Int): Pair<Int, String>{\n        return Pair(val2, val1)\n    }\n    val val1 = \"Tres\"\n    val val2 = 3\n    val (newVal1, newVal2) = valueFunction(val1, val2)\n\n    println(\"Originalmente val1 era $val1, y val2 era $val2\")\n    println(\"Ahora, el nuevo val1 es $newVal1 y el nuevo del 2 es $newVal2\")\n}\n\nfun main() {\n    val value = 1\n\n    var varia = \"hola\"\n    println(varia)\n    varia = \"adiós\"\n    println(varia)\n\n    fun value(valor: String): String{\n        val valu = \"He cambiado\"\n        return valu\n    }\n    val valu = \"Hola\"\n    println(value(valu))\n\n    println(\"\\n\" + \"~\".repeat(9) + \" EJERCICIO EXTRA \" + \"~\".repeat(9))\n    ejerExtra()\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/kotlin/westwbn.kt",
    "content": "fun exchangeValue(a: Int, b: Int): Pair<Int, Int> {\n    return Pair(b, a)\n}\n\n\nfun exchangeByReference(a: Int, b: Int): Pair<Int, Int> {\n    return Pair(a, b)\n}\n\nfun main() {\n    // Variables por valor\n    val originalNumber = 5\n    var referenceNumber = originalNumber\n\n    println(\"Asignación por valor:\")\n    println(\"Original: $originalNumber, Nuevo valor: $referenceNumber\")\n\n    // Modificación del valor\n    referenceNumber = 50\n    println(\"Modificando el valor por referencia:\")\n    println(\"Original: $originalNumber, Nuevo valor: $referenceNumber\")\n\n    // Asignación por referencia\n    data class Person(var name: String)\n\n    val person1 = Person(\"Juan\")\n    val person2 = person1  // Asignación por referencia\n\n    println(person1.name) // Imprimirá \"Pedro\", ya que se modificó el objeto referenciado por 'Person1'\n    println(\"Asignación por referencia:\")\n    println(\"Original: $person1, Referencia: $person2\")\n\n    // Modificación por referencia\n    person2.name = \"Pedro\"\n    println(\"Modificación por referencia:\")\n    println(\"Original: $person1, Referencia: $person2\")\n\n    // función con parámetro por valor\n    println(\"Función con parámetro por valor\")\n\n\n    fun multiplyValue(num: Int) {\n        println(num * 2) // Esto modifica una copia de 'numero'\n    }\n\n    fun modifyName(person: Person) {\n        person.name = \"Carlos\" // Esto modifica el objeto referenciado por 'persona'\n    }\n\n    val x = 5\n    multiplyValue(x)\n    println(x) // Imprimirá 5, ya que 'x' no se modifica dentro de la función\n\n    val person = Person(\"Juan\")\n    modifyName(person)\n    println(person.name) // Imprimirá \"Carlos\", ya que se modificó el objeto referenciado por 'persona'\n\n    val originalA = 10\n    val originalB = 20\n\n    val (newA, newB) = exchangeValue(originalA, originalB)\n\n    println(\"Valores originales: A=$originalA, B=$originalB\")\n    println(\"Valores intercambiados: A=$newA, B=$newB\")\n\n    val firstValue = 1\n    val secondValue = 15\n\n    val (newFirstValue, newSecondValue) = exchangeByReference(firstValue, secondValue)\n    println(\"Valores originales: A= ${firstValue}, B= $secondValue\")\n    println(\"Valores intercambiados: A=$newFirstValue , B=$newSecondValue\")\n}"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/lua/Bert008.lua",
    "content": "--[[\n/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n]]\n\n-- asignacion por valor\na = 10\nb = a\nprint(\"a: \", a)\nprint(\"b: \", b)\n\n-- asignacion por referencia\nlista = {1, 2, 3, 4, 5}\na = lista[1]\nb = lista[2]\nc = lista[3]\nd = lista[4]\ne = lista[5]\n\nprint(a, b, c, d, e)\n\nfunction suma(a, b)\n    return a + b\nend\nc = suma(1, 2)\nprint(\"el resultado de suma es: \", c)\n\nlista1 = {1, 2, 3, 4, 5}\n\nfunction listas(lista1)\n    for i in ipairs(lista1) do\n        print(i)\n    end\n\nend\n    \n\n-- Extras\nfunction xyyx(x, y)\n    return y, x\nend\n\nfunction listas(lista1, lista2)\n    \n    \nend"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/lua/ansuzgs.lua",
    "content": "-- asignacion de variables por valor\n\nlocal a = 1\nlocal b = 2\n\nprint(\"a: \", a)\nprint(\"b: \", b)\n\n-- asignacion por referencia\n-- No es posible hacer asignacion por referencia en lua ya que las variables\n-- son por valor y no por referencia\n\n-- funciones con datos por valor\nfunction sumar(a, b)\n  return a + b\nend\n\nprint(\"sumar(1, 2): \", sumar(1, 2))\n\n-- funciones con datos por referencia\nfunction sumar2(a, b)\n  local tabla = {}\n  for i = 1, #a do\n    tabla[i] = a[i] + b[i]\n  end\n  return tabla\nend\n\nlocal a = {1, 2, 3}\nlocal b = {4, 5, 6}\nlocal c = sumar2(a, b)\nfor i = 1, #c do\n  print(\"a[\"..i..\"] + b[\"..i..\"] = \" .. a[i] .. \" + \" .. b[i] .. \" = \" .. c[i])\nend \n\n\n--[[\n-- EXTRA\n--]]\n\n-- funcion que intercambia dos variables por valor\nfunction swap(a, b)\n  local c, d = b, a\n  return c, d\nend\n\nlocal a = 1\nlocal b = 2\nprint(\"a: \", a)\nprint(\"b: \", b)\na, b = swap(a, b)\nprint(\"a: \", a)\nprint(\"b: \", b)\n\n-- funcion que intercambia dos variables por referencia\n-- no es posible hacerlo en lua, ya que las variables son por valor\n-- y no por referencia\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/ocaml/luishendrix92.ml",
    "content": "open Printf;;\n\n(* OCaml is a functional programming language with a few procedural tidbits\n   that make it different to purely functional languages such as Haskell. This\n   means, we have both immutable and mutable data structures, as well as IO\n   blocks that execute system calls (such as reading and writing to channels\n   and the filysystem, making network calls, control hardware, and more)\n   that in turn return the unit type `()` or a concrete value.\n\n   The language also features something called a [ref] type (reference) that\n   acts exactly like a mutable variable that can be replaced anywhere in the\n   codebase and. This is not the only way to read and write/mutate memory;\n   as I mentioned, there are mutable data structures such as [Hashtbl] and\n   [Array], on top of having a rather obscure syntax for creating objects.\n\n   Having said that, as a primarily functional language, most functions and\n   operators of the langauge act on immutable data which means that any change\n   done to a data structure returns a new data structure leaving the original\n   untouched (or garbage-collected if it's no longer needed). Finally, 99% of\n   the time we'll be declaring local bindings with immutable values instead of\n   mutable references. The language itself doesn't have a way to re-assign a\n   [let] binding, but rather, to shadow it, which is just creating a new one\n   that holds a new value (often derived from the old one).\n\n   {[\n     let foo = 5 in\n     let foo = 5.0 in\n     print_float foo\n   ]}\n\n   The block above will give you a warning because the shadowing of [foo] in\n   line 2 does not use the previous value of [foo], giving us the warning:\n   [Warning 26 [unused-var]: unused variable foo.]. It won't break the program\n   but it gives an insight of the OCaml and functional programing philosophy.\n*)\n\n(* Immutable and primitive values. *)\n\nlet integer_number = 420 in\nlet floating_point_number = 69.69 in\nlet text_string = \"Hello Roadmap 2024\" in\nlet boolean_value = false in\nlet character = 'P' in\nbegin\n  printf\n    \"Operating on integer_number: %d / 2 = %d\\n\"\n    integer_number\n    (integer_number / 2);\n  printf\n    \"Operating on floating_point_number: %f * 3 = %f\\n\"\n    floating_point_number\n    (floating_point_number *. 3.0);\n  printf\n    \"Opearting on text_string: uppercase '%s' = '%s'\\n\"\n    text_string\n    (String.uppercase_ascii text_string);\n  printf\n    \"Opearting on boolean_value: NOT %b = %b\\n\"\n    boolean_value\n    (Bool.not boolean_value);\n  printf\n    \"Opearting on a character: lowercase '%c' = '%c'\\n\"\n    character\n    (Char.lowercase_ascii character);\n  printf \"These operations didn't mutate the original values:\\n\";\n  print_endline (string_of_int integer_number);\n  print_endline (string_of_float floating_point_number);\n  print_endline text_string;\n  print_endline (string_of_bool boolean_value);\n  printf \"%c\\n\" character\nend\n\n(* Immutable built-in data structures. *)\n\nmodule IntSet = Set.Make (Int)\nmodule StringMap = Map.Make (String)\n\nlet pp_int_list l =\n  sprintf \"[ %s ]\" (List.map string_of_int l |> String.concat \"; \")\n;;\n\nlet pp_int_set s =\n  sprintf\n    \"#{ %s }\"\n    (IntSet.to_list s |> List.map string_of_int |> String.concat \", \")\n;;\n\nlet pp_assoc al =\n  sprintf\n    \"{ %s }\"\n    (List.map (fun (k, v) -> sprintf \"\\\"%s\\\" => \\\"%s\\\"\" k v) al\n     |> String.concat \", \")\n;;\n\nlet pp_map m = StringMap.to_list m |> pp_assoc;;\n\nlet list_structure = [ 1; 2; 3; 4; 5 ] in\nlet integer_set = IntSet.of_list [ 9; 8; 7; 9; 8; 3 ] in\nlet capitals = StringMap.of_list [ \"Russia\", \"Moscow\"; \"Mexico\", \"CDMX\" ] in\nbegin\n  printf\n    \"\\nCons'ing to a linked list: 0 :: %s = %s\\n\"\n    (pp_int_list list_structure)\n    (List.cons 0 list_structure |> pp_int_list);\n  printf\n    \"Removing from a set: remove 8 from %s = %s\\n\"\n    (pp_int_set integer_set)\n    (IntSet.remove 8 integer_set |> pp_int_set);\n  printf\n    \"Editing entries in a map: 'CDMX' -> 'Mexico City' in %s = %s\\n\"\n    (pp_map capitals)\n    (StringMap.update \"Mexico\" (fun _ -> Some \"Mexico City\") capitals |> pp_map);\n  print_endline \"These operations didn't mutate the original values:\";\n  print_endline (pp_int_list list_structure);\n  print_endline (pp_int_set integer_set);\n  prerr_endline (pp_map capitals)\nend\n\n(* Mutable data structures\n\n   Note: Even though these structures are mutable, OCaml's standard library\n   provides many functions that create a new structure with the changes done.\n   The way we recognize the ones that do mutate, is by either checking the\n   return type (it must be [unit]) or if their name have the [_inplace] suffix.\n*)\n\nlet pp_str_arr a = sprintf \"[| %s |]\" (Array.to_list a |> String.concat \"; \")\n\nlet pp_hashtbl h =\n  Hashtbl.to_seq h\n  |> Seq.map (fun (k, v) -> string_of_int k, string_of_int v)\n  |> List.of_seq\n  |> pp_assoc\n;;\n\nlet pp_str_queue q =\n  sprintf\n    \"[Front| %s |Back]\"\n    (Queue.to_seq q |> List.of_seq |> String.concat \"->\")\n;;\n\nlet pp_int_stack s =\n  sprintf\n    \"[Top> %s <Bottom]\"\n    (Stack.to_seq s\n     |> Seq.map string_of_int\n     |> List.of_seq\n     |> String.concat \" | \")\n;;\n\nlet colors_array = [| \"Orange\"; \"Blue\"; \"Fucshia\"; \"Black\" |] in\nlet fib_hashtbl = List.to_seq [ 5, 5; 6, 8; 7, 13 ] |> Hashtbl.of_seq in\nlet str_queue = List.to_seq [ \"First\"; \"Second\" ] |> Queue.of_seq in\nlet int_stack = List.to_seq [ 1; 2; 3; 4 ] |> Stack.of_seq in\nbegin\n  printf\n    \"\\nReplacing colors_array %s at index 1 with 'Red' = \"\n    (pp_str_arr colors_array);\n  print_endline\n    (colors_array.(1) <- \"Red\";\n     pp_str_arr colors_array);\n  printf \"Removing keys 5 and 7 from fib_hashtbl %s = \" (pp_hashtbl fib_hashtbl);\n  print_endline\n    (Hashtbl.remove fib_hashtbl 5;\n     Hashtbl.remove fib_hashtbl 7;\n     pp_hashtbl fib_hashtbl);\n  printf\n    \"Enqueue 'Third' and dequeue from str_queue %s = \"\n    (pp_str_queue str_queue);\n  print_endline\n    (Queue.push \"Third\" str_queue;\n     printf \"'%s' out of \" (Queue.take str_queue);\n     pp_str_queue str_queue);\n  printf \"Push 5 and 6, then pop from int_stack %s = \" (pp_int_stack int_stack);\n  print_endline\n    (Stack.push 5 int_stack;\n     Stack.push 6 int_stack;\n     printf \"%d out of \" (Stack.pop int_stack);\n     pp_int_stack int_stack);\n  print_endline \"These operations mutated the original values:\";\n  print_endline (pp_str_arr colors_array);\n  print_endline (pp_hashtbl fib_hashtbl);\n  print_endline (pp_str_queue str_queue);\n  print_endline (pp_int_stack int_stack)\nend\n\n(* DIFICULTAD EXTRA (opcional):\n * ----------------------------\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n *)\n\n(* NOTE: This exercise doesn't make much sense in a functional language but it\n   OCaml provides [ref] types and mutable record fields whose values can be\n   swapped and mutated from functions that accept them as parameters. Paremters\n   are local bindings that can't be re-assigned but rather shadowed. There is\n   no such thing as passing by reference in the language except for passing\n   mutable values, yet the bindings keep pointing to these mutated values.\n   So, what I'm gonna do instead is create two functions, one which swaps two\n   refs (only works if they're the same type), andt the other, swaps the fields\n   in a mutable record; both returning the mutable references and assigning\n   them to new bindings to later dereference and print their values..\n*)\n\nlet a : int ref = ref 5\nlet b : int ref = ref 10\n\n(* printf \"\\nBefore swapping: a = %d ; b = %d\\n\" !a !b;; *)\n\nlet swap_refs ref_a ref_b =\n  let temp = !ref_b in\n  ref_b := !ref_a;\n  ref_a := temp;\n  ref_b, ref_a\n;;\n\nbegin\n  printf \"\\nOriginal refs: a = %d ; b = %d\\n\" !a !b;\n  let new_a, new_b = swap_refs a b in\n  printf\n    \"After swapping and assigning to new bindings: a = %d ; b = %d ; new_a = \\\n     %d ; new_b = %d\\n\"\n    !a\n    !b\n    !new_a\n    !new_b;\n  incr a;\n  incr b;\n  incr new_a;\n  incr new_b;\n  printf\n    \"After incrementing all references by 1: a = %d ; b = %d ; new_a = %d ; \\\n     new_b = %d\\n\"\n    !a\n    !b\n    !new_a\n    !new_b\nend\n\ntype point =\n  { mutable x : float\n  ; mutable y : float\n  }\n\nlet pp_point { x; y } = sprintf \"P(%f, %f)\" x y\nlet p1 = { x = 7.3; y = -0.39 }\n\nlet swap_coords p =\n  let temp = p.y in\n  p.y <- p.x;\n  p.x <- temp;\n  p\n;;\n\nbegin\n  printf \"\\nOriginal point: p1 = %s\\n\" (pp_point p1);\n  let p2 = swap_coords p1 in\n  printf\n    \"After swapping and assigning to new binding: p1 = %s ; p2 = %s\\n\"\n    (pp_point p1)\n    (pp_point p2);\n  p1.x <- p1.x -. 1.0;\n  p1.y <- p1.y -. 1.0;\n  p2.x <- p2.x -. 1.0;\n  p2.y <- p2.y -. 1.0;\n  printf\n    \"After decrementing all coordinates by 1.0: p1 = %s ; p2 = %s ; \\n\"\n    (pp_point p1)\n    (pp_point p2)\nend\n\n(* Observations:\n   -------------\n   As we can see here, references enable the usage of performant procedural\n   code in this functional language. And, as it turns out, the [ref] type is\n   actually just a record with 1 mutable field [contents], and it's easy to\n   re-implement if we learned enough about these subjects:\n\n   {[\n     type 'a my_ref = { mutable contents : 'a }\n\n     let my_ref v = { contents = v }\n     let ( := ) r v = r.contents <- v\n     let ( ! ) r = r.contents\n   ]}\n*)\n\n(* Output of running [ocaml luishendrix92.ml]:\n   -------------------------------------------\n   Operating on integer_number: 420 / 2 = 210\n   Operating on floating_point_number: 69.690000 * 3 = 209.070000\n   Opearting on text_string: uppercase 'Hello Roadmap 2024' = 'HELLO ROADMAP 2024'\n   Opearting on boolean_value: NOT false = true\n   Opearting on a character: lowercase 'P' = 'p'\n   These operations didn't mutate the original values:\n   420\n   69.690000\n   'Hello Roadmap 2024'\n   false\n   'P'\n\n   Cons'ing to a linked list: 0 :: [ 1; 2; 3; 4; 5 ] = [ 0; 1; 2; 3; 4; 5 ]\n   Removing from a set: remove 8 from #{ 3, 7, 8, 9 } = #{ 3, 7, 9 }\n   Editing entries in a map: 'CDMX' -> 'Mexico City' in { \"Mexico\" => \"CDMX\", \"Russia\" => \"Moscow\" } = { \"Mexico\" => \"Mexico City\", \"Russia\" => \"Moscow\" }\n   These operations didn't mutate the original values:\n   [ 1; 2; 3; 4; 5 ]\n   #{ 3, 7, 8, 9 }\n\n   Replacing colors_array [| Orange; Blue; Fucshia; Black |] at index 1 with 'Red' = [| Orange; Red; Fucshia; Black |]\n   Removing keys 5 and 7 from fib_hashtbl { \"6\" => \"8\", \"7\" => \"13\", \"5\" => \"5\" } = { \"6\" => \"8\" }\n   Enqueue 'Third' and dequeue from str_queue [Front| First->Second |Back] = 'First' out of [Front| Second->Third |Back]\n   Push 5 and 6, then pop from int_stack [Top> 4 | 3 | 2 | 1 <Bottom] = 6 out of [Top> 5 | 4 | 3 | 2 | 1 <Bottom]\n   These operations mutated the original values:\n   [| Orange; Red; Fucshia; Black |]\n   { \"6\" => \"8\" }\n   [Front| Second->Third |Back]\n   [Top> 5 | 4 | 3 | 2 | 1 <Bottom]\n\n   Original refs: a = 5 ; b = 10\n   After swapping and assigning to new bindings: a = 10 ; b = 5 ; new_a = 5 ; new_b = 10\n   After incrementing all references by 1: a = 12 ; b = 7 ; new_a = 7 ; new_b = 12\n\n   Original point: p1 = P(7.300000, -0.390000)\n   After swapping and assigning to new binding: p1 = P(-0.390000, 7.300000) ; p2 = P(-0.390000, 7.300000)\n   After decrementing all coordinates by 1.0: p1 = P(-2.390000, 5.300000) ; p2 = P(-2.390000, 5.300000) ;\n*)\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/pascal/miguelex.pas",
    "content": "program miguelex;\n\nvar\n  num1V, num2V, num3V, num4V: integer; // Variables para el ejemplo por valor\n  num1R, num2R, num3R, num4R: ^integer; // Variables para el ejemplo por referencia\n\n{ Funcion con paso por valor }\n\nprocedure incValor(a, b: integer);\nbegin\n  writeLn('El valor de a es: ', a + 1);\n  writeLn('El valor de b es: ', b + 1);\nend;\n\nprocedure incReferencia(var a, b: integer);\nbegin\n  a := a + 1;\n  b := b + 1;\nend;\n\nprocedure byValor (a, b: integer);\nvar\n  aux: integer;\nbegin\n  aux := a;\n  a := b;\n  b := aux;\n  writeln ('En la funcion byValor, a = ', a, ' y b = ', b);\nend;\n\nprocedure byReferencia (var a, b: integer);\nvar\n  aux: integer;\nbegin\n  aux := a;\n  a := b;\n  b := aux;\n  writeln ('En la funcion byReferencia, a = ', a, ' y b = ', b);\nend;\n\n{ Funcion con paso por referencia }\n\nBegin\n\n  writeln('Variables por valor');\n  writeln();\n\n  num1V := 10;\n  num2V := 20;\n\n  num3V := num1V;\n  num4V := num2V;\n\n  writeln('El valor de num1 es: ', num1V);\n  writeln('El valor de num2 es: ', num2V);\n  writeln('El valor de num3 es: ', num3V);\n  writeln('El valor de num4 es: ', num4V);\n\n  writeln('A continuación vamos a cambiar el valor de num1 y num2');\n  writeln();\n\n  num1V := 30;\n  num2V := 40;\n\n  writeln('El valor de num1 es: ', num1V);\n  writeln('El valor de num2 es: ', num2V);\n  writeln('El valor de num3 es: ', num3V);\n  writeln('El valor de num4 es: ', num4V);\n  writeln();\n\n  writeln('Variables por referencia');\n  writeln();\n  { Por referencia }\n  GetMem(num1R, SizeOf(integer));\n  GetMem(num2R, SizeOf(integer));\n  num3R := num1R;\n  num4R := num2R;\n\n  num1R^ := 10;\n  num2R^ := 20;\n\n  writeln('El valor de num1 es: ', num1R^);\n  writeln('El valor de num2 es: ', num2R^);\n  writeln('El valor de num3 es: ', num3R^);\n  writeln('El valor de num4 es: ', num4R^);\n  writeln();\n\n  writeln('A continuación vamos a cambiar el valor de num1 y num2');\n  writeln();\n  num1R^ := 30;\n  num2R^ := 40;\n\n  writeln('El valor de num1 es: ', num1R^);\n  writeln('El valor de num2 es: ', num2R^);\n  writeln('El valor de num3 es: ', num3R^);\n  writeln('El valor de num4 es: ', num4R^);\n\n  writeln('Como podemos ver, el valor de num3 y num4 cambió, ya que son referencias a las variables originales');\n  writeln();\n  FreeMem(num1R);\n  FreeMem(num2R);\n\n  { Ejemplo de funcion con paso por valor }\n\n  writeln('Ejemplo de función con paso por valor');\n  writeln();\n\n  num1V := 1;\n  num2V := 2;\n\n  writeln('Valores de num1 y num2 antes de llamar a la función incValor');\n  writeln('Num1 = ', num1V); \n  writeln('Num2 = ', num2V);\n  writeln();\n\n  incValor(num1V, num2V);\n  writeln();\n\n  writeln('Valores de num1 y num2 después de llamar a la función incValor');\n  writeln('Num1 = ', num1V);\n  writeln('Num2 = ', num2V);\n  writeln();\n\n  writeln('Ejemplo de función con paso por valor');\n  writeln();\n  \n  num1V := 1;\n  num2V := 2;\n\n  writeln('Valores de num1 y num2 antes de llamar a la función incReferencia');\n  writeln('Num1 = ', num1V);\n  writeln('Num2 = ', num2V);\n  writeln();\n\n  incReferencia(num1V, num2V);\n\n  writeln('Valores de num1 y num2 después de llamar a la función incReferencia');\n  writeln('Num1 = ', num1V);\n  writeln('Num2 = ', num2V);\n  writeln();\n\n  { Extra }\n\n  writeln('Ejemplo de función extra con paso por valor');\n  writeln();\n\n  num1V := 5;\n  num2V := 10;\n\n  writeln('Valores de num1 y num2 antes de llamar a la función byValor');\n  writeln('Num1 = ', num1V);\n  writeln('Num2 = ', num2V);\n  writeln();\n\n  byValor(num1V, num2V);\n  writeln();\n\n  writeln('Valores de num1 y num2 después de llamar a la función byValor');\n  writeln('Num1 = ', num1V);\n  writeln('Num2 = ', num2V);\n  writeln();\n\n  writeln('Ejemplo de función extra con paso por referencia');\n  writeln();\n\n  writeln('Valores de num1 y num2 antes de llamar a la función byReferencia');\n  writeln('Num1 = ', num1V);\n  writeln('Num2 = ', num2V);\n  writeln();\n\n  byReferencia(num1V, num2V);\n  writeln();\n\n  writeln('Valores de num1 y num2 después de llamar a la función byReferencia');\n  writeln('Num1 = ', num1V);\n  writeln('Num2 = ', num2V);\n  writeln();\n\nend.\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/php/CeciliaPorras01.php",
    "content": "\n<?php \n\n/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\n\n\n //Tipo de dato por valor \n\n    $a = 5;\n    $b = $a;\n    $b = 10;\n\n    print $a; \n    print $b;\n\n\n    //Tipo de dato por referencia\n\n    $colores = [\"rojo\", \"azul\", \"verde\"];\n    $colores2 = &$colores;\n    $colores2[0] = \"amarillo\";\n    print_r($colores);\n    print_r($colores2);\n\n\n    //Funciones con datos por valor\n    $my_variable = 4;\n\n    function my_function($my_variable){\n        $my_variable = 8 .\"\\n\";\n        print $my_variable;\n    }\n\n    my_function($my_variable);\n    print($my_variable);\n\n\n\n    //Funciones con datos por referencia\n    $my_list = [1, 2, 3];\n\n    function my_function2(&$my_list){\n        $my_list[] = 4;\n        $my_list_2 = &$my_list;\n        $my_list_2[] = 5;\n        print_r($my_list);\n    }\n\n    my_function2($my_list);\n    print_r($my_list);\n\n\n    //Extra\n\n    //Por valor \n    $var_1 = 10;\n    $var_2 = 20;\n\n    function values($var_1, $var_2){\n        $temp = $var_1;\n        $var_1 = $var_2;\n        $var_2 = $temp;\n        return [$var_1, $var_2];\n    }\n\nprint_r(values($var_1, $var_2));\nprint(\"Valor1=\".$var_1.\", Valor2=\". $var_2);\n\n\n //Por referncia\n    $list_1 = [\"azul\",\"rojo\",\"verde\"];\n    $list_2 = [\"amarillo\",\"naranja\",\"morado\"];\n\n    function values_list($list_1, $list_2){\n        $temp = $list_1;\n        $list_1 = $list_2;\n        $list_2 = $temp;\n        return [$list_1, $list_2];\n    }\n\n    print_r(values_list($list_1, $list_2));\n    print_r($list_1);\n    print_r($list_2);\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/php/eulogioep.php",
    "content": "<?php\n\n// Función para imprimir resultados\nfunction printMessage($message) {\n    echo $message . \"\\n\";\n}\n\n// Ejemplos de asignación por valor (tipos escalares)\n$a = 5;\n$b = $a; // $b es una copia del valor de $a\n$b = 10; // Cambiar $b no afecta a $a\nprintMessage(\"Asignación por valor: a: $a, b: $b\"); // a: 5, b: 10\n\n// Ejemplos de asignación por referencia (arrays y objetos)\n$arr1 = [1, 2, 3];\n$arr2 = &$arr1; // $arr2 es una referencia a $arr1\n$arr2[0] = 100; // Cambiar $arr2 afecta a $arr1\nprintMessage(\"Asignación por referencia: arr1[0]: {$arr1[0]}, arr2[0]: {$arr2[0]}\"); // arr1[0]: 100, arr2[0]: 100\n\n// Función con parámetro por valor\nfunction modificarValor($n) {\n    $n = 100; // Este cambio no afecta a la variable original\n}\n\n$x = 5;\nmodificarValor($x);\nprintMessage(\"x después de modificarValor: $x\"); // x no cambia\n\n// Función con parámetro por referencia\nfunction modificarReferencia(&$arr) {\n    $arr[0] = 100; // Este cambio afecta al array original\n}\n\n$array = [1, 2, 3];\nmodificarReferencia($array);\nprintMessage(\"array[0] después de modificarReferencia: {$array[0]}\"); // array[0] cambia\n\n// DIFICULTAD EXTRA\n// Función para intercambio por valor\nfunction intercambioPorValor($a, $b) {\n    $temp = $a;\n    $a = $b;\n    $b = $temp;\n    return [$a, $b];\n}\n\n// Función para intercambio por referencia\nfunction intercambioPorReferencia(&$a, &$b) {\n    $temp = $a;\n    $a = $b;\n    $b = $temp;\n}\n\n// Programa 1: Intercambio por valor\n$num1 = 10;\n$num2 = 20;\nprintMessage(\"Antes del intercambio por valor: num1 = $num1, num2 = $num2\");\nlist($nuevoNum1, $nuevoNum2) = intercambioPorValor($num1, $num2);\nprintMessage(\"Después del intercambio por valor:\");\nprintMessage(\"Variables originales: num1 = $num1, num2 = $num2\");\nprintMessage(\"Nuevas variables: nuevoNum1 = $nuevoNum1, nuevoNum2 = $nuevoNum2\");\n\n// Programa 2: Intercambio por referencia\n$ref1 = 30;\n$ref2 = 40;\nprintMessage(\"\\nAntes del intercambio por referencia: ref1 = $ref1, ref2 = $ref2\");\nintercambioPorReferencia($ref1, $ref2);\nprintMessage(\"Después del intercambio por referencia:\");\nprintMessage(\"Variables modificadas: ref1 = $ref1, ref2 = $ref2\");\n\n?>"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/php/gabrielmoris.php",
    "content": "<?php\n\n/*EXERCISE:\n* Provide examples of variable assignment \"by value\" and \"by reference\" based on their data type.\n* Demonstrate functions with variables passed \"by value\" and \"by reference,\" and how they behave when modified in each case.\n(Understanding these concepts is essential in the majority of programming languages)\n*/\n\n$data = 1;\n\n// Asign by VALUE\n$by_value = $data;\n\n// Asign by REFERENCE\n$by_reference = &$data;\n\n// Demonstration\n\nfunction demonstration($data)\n{\n    echo \"Original before modification: \" . $data . \"\\n\";\n\n    $by_val = $data;\n    $by_ref = &$data;\n\n    $data = 100;\n    echo \"By value: \" . $by_val . \"\\n\" . \"By Reference: \" . $by_ref . \"\\n\" . \"Original after modification: \" . $data . \"\\n\";\n}\n\ndemonstration(1);\n\n/*EXTRA CHALLENGE (optional):\nCreate two programs that receive two parameters each, defined as previously assigned variables.\n* In one case, the programs receive two parameters by value, and in the other case, by reference.\n* Inside the programs, swap the values of these parameters, return them, and assign the returned values to \n* two different variables from the originals.\n* Finally, print the values of the original variables and the new ones, verifying that the values have been inverted in the latter.\n* Also, confirm that the original values are preserved in the former.\n*/\necho \" =============== CHALLENGE ===============\\n\";\nfunction modify_values($val1, $val2)\n{\n    $temp = $val1;\n    $val1 = $val2;\n    $val2 = $temp;\n\n    return [$val1, $val2];\n};\n\nfunction modify_references(&$variable1, &$variable2)\n{\n    $temp = $variable1;\n    $variable1 = $variable2;\n    $variable2 = $temp;\n\n    return [$variable1, $variable2];\n}\n\n$variable1 = 1;\n$variable2 = 2;\n\necho \"Originals Initialized: \" . $variable1 . \", \" . $variable2 . \"\\n\";\n\n$res_val = modify_values($variable1, $variable2);\nvar_dump($res_val);\necho \"Originals after modify values: \" . $variable1 . \", \" . $variable2 . \"\\n\";\n\n$res_ref = modify_references($variable1, $variable2);\nvar_dump($res_ref);\necho \"Originals after modify references: \" . $variable1 . \", \" . $variable2 . \"\\n\";\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/php/kodenook.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/*\n    Assignment By Value\n*/\n\n$var1 = 3;\n$var2 = $var1;\n\n$var1 = 4;\n\necho $var1, PHP_EOL;\necho $var2, PHP_EOL;\n\n/*\n    Assignment By Reference\n*/\n\n$var3 = 3;\n$var4 = &$var3;\n\n$var3 = 4;\n\necho $var3, PHP_EOL;\necho $var4, PHP_EOL;\n\n/*\n    Exercise\n*/\n\nfunction ByValue(int $a, int $b): array\n{\n    $temp = $a;\n\n    $a = $b;\n    $b = $temp;\n\n    return [$a, $b];\n}\n\n$original1 = 20;\n$original2 = 30;\n$values = ByValue($original1, $original2);\n\necho 'By Values', PHP_EOL;\necho 'Original Values', PHP_EOL;\necho $original1, PHP_EOL;\necho $original2, PHP_EOL;\necho 'After Function Values', PHP_EOL;\necho $values[0], PHP_EOL;\necho $values[1], PHP_EOL;\n\nfunction ByReference(int &$c, &$d): array\n{\n    $e = $d;\n    $f = $c;\n\n    return [$e, $f];\n}\n\n$original1 = 50;\n$original2 = 60;\n$values = ByReference($original1, $original2);\n\necho 'By Reference', PHP_EOL;\necho 'Original Values', PHP_EOL;\necho $original1, PHP_EOL;\necho $original2, PHP_EOL;\necho 'After Function Values', PHP_EOL;\necho $values[0], PHP_EOL;\necho $values[1], PHP_EOL;\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/php/marcode24.php",
    "content": "<?php\n/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\n// Ejemplo de asignación por valor para tipos primitivos\n$num1 = 10;\n$num2 = $num1; // Asignación por valor\n$num2 = 20;\n\necho $num1 . PHP_EOL; // Salida: 10 (valor original no cambia)\necho $num2 . PHP_EOL; // Salida: 20\n\n// Ejemplo de asignación por referencia para objetos\n$obj1 = ['nombre' => 'Juan'];\n$obj2 = &$obj1; // Asignación por referencia\n$obj2['nombre'] = 'Carlos';\n\necho $obj1['nombre'] . PHP_EOL; // Salida: Carlos (el valor original cambia)\necho $obj2['nombre'] . PHP_EOL; // Salida: Carlos\n\n// Ejemplo de función que recibe parámetros por valor\nfunction duplicar($numero) {\n  $numero *= 2;\n  return $numero;\n}\n\n$original = 5;\n$resultado = duplicar($original);\n\necho $original . PHP_EOL; // Salida: 5 (el valor original no cambia)\necho $resultado . PHP_EOL; // Salida: 10\n\n// Ejemplo de función que recibe parámetros por referencia (array)\nfunction cambiarNombre(&$persona) {\n  $persona['nombre'] = 'Pedro';\n}\n\n$personaOriginal = ['nombre' => 'Juan'];\ncambiarNombre($personaOriginal);\n\necho $personaOriginal['nombre'] . PHP_EOL; // Salida: Pedro (el valor original cambia)\n\necho str_repeat(PHP_EOL, 2) . str_repeat('*', 50) . PHP_EOL;\n\n// Función que intercambia valores por valor\nfunction intercambiarValoresPorValor($a, $b) {\n  $temp = $a;\n  $a = $b;\n  $b = $temp;\n  return [$a, $b];\n}\n\n// Función que intercambia valores por referencia\nfunction intercambiarValoresPorReferencia($obj) {\n  $copia = $obj; // No es necesario crear una copia ya que en PHP los arrays se pasan por referencia por defecto\n  $temp = $copia['valor1'];\n  $copia['valor1'] = $copia['valor2'];\n  $copia['valor2'] = $temp;\n  return $copia; // Devolver la copia del array modificado\n}\n\n// Ejemplos\n$valorA = 3;\n$valorB = 7;\n\n[$nuevoValorA, $nuevoValorB] = intercambiarValoresPorValor($valorA, $valorB);\necho $valorA . ' ' . $valorB . PHP_EOL; // Salida: 3 7\necho $nuevoValorA . ' ' . $nuevoValorB . PHP_EOL; // Salida: 7 3\n\n$valores = ['valor1' => 10, 'valor2' => 5];\n\n$nuevosValores = intercambiarValoresPorReferencia($valores);\necho $valores['valor1'] . ' ' . $valores['valor2'] . PHP_EOL; // Salida: 10 5\necho $nuevosValores['valor1'] . ' ' . $nuevosValores['valor2'] . PHP_EOL; // Salida: 5 10\n\n// Visita mi repo en GitHub para ver y correr los tests de este código --> https://github.com/marcode24/weekly-challenges\n\n?>\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/php/miguelex.php",
    "content": "<?php \n\n// Crear dos variables por valor\n\n$a = 5;\n$b = \"Hola\";\n\necho \"El valor de a es: \".$a.\"\\n\";\necho \"El valor de b es: \".$b.\"\\n\";\n\n$aCopia = $a;\n$bCopia = $b;\n\necho \"El valor de aCopia es: \".$aCopia.\"\\n\";\necho \"El valor de bCopia es: \".$bCopia.\"\\n\";\n\n// Modificar el contenido de las variables\n\n$a = 10;\n$b = \"Adios\";\necho \"\\nValores despues de la modificación:\\n\";\necho \"El valor de a es: \".$a.\"\\n\";\necho \"El valor de b es: \".$b.\"\\n\";\necho \"El valor de aCopia es: \".$aCopia.\"\\n\";\necho \"El valor de bCopia es: \".$bCopia.\"\\n\";\n\n\n// Crear dos variables por referencia\n\n$c = &$a;\n$d = &$b;\n\necho \"\\nValores de c y d:\\n\";\necho \"El valor de c es: \".$c.\"\\n\";\necho \"El valor de d es: \".$d.\"\\n\";\n\n// Modificar el contenido de las variables\n\n$c = 15;\n$d = \"Hasta luego\";\necho \"\\nValores despues de la modificación:\\n\";\necho \"El valor de a es: \".$a.\"\\n\";\necho \"El valor de b es: \".$b.\"\\n\";\necho \"El valor de c es: \".$c.\"\\n\";\necho \"El valor de d es: \".$d.\"\\n\";\n\n// Ejemplo de una funcio con paso por valor\n\nfunction incrementa($valor){\n    $valor++;\n    return $valor;\n}\n\necho \"\\nEjemplo de funcion con paso por valor:\\n\";\necho \"El valor de a es: \".$a.\"\\n\";\n$resultado = incrementa($a);\necho \"La cantidad que devuelve la funcion es: \".$resultado.\"\\n\";\necho \"Pero el valor de a sigue siendo: \".$a.\"\\n\";\n\n\n// Ejemplo de una funcio con paso por referencia\nfunction decrementa(&$valor){\n    $valor--;\n    return $valor;\n}   \n\necho \"\\nEjemplo de funcion con paso por referencia:\\n\";\necho \"El valor de a es: \".$a.\"\\n\";\n$resultado = decrementa($a);\necho \"La funcion retorna el valor: \".$resultado.\"\\n\";\necho \"Y el valor de a ahora es: \".$a.\"\\n\";\n\n// Extra\n\necho \"\\nExtra:\\n\";\n\necho \"\\nPaso por valor\\n\";\nfunction byValor($a, $b){\n    $aux = $a;\n    $a = $b;\n    $b = $aux;\n\n    return [$a, $b];\n}\n\n$aOriginal = 2;\n$bOriginal = 3;\n\necho \"El valor de aOriginal es: \".$aOriginal.\"\\n\";\necho \"El valor de bOriginal es: \".$bOriginal.\"\\n\";  \n\n$resultado = byValor($aOriginal, $bOriginal);\necho \"La funcion retornó los valores: \".implode(\",\", $resultado).\"\\n\";\necho \"Pero los valores originales siguen siendo: \".$aOriginal.\" y \".$bOriginal.\"\\n\";\n\n$arrAOriginal = [1, 2, 3];\n$arrBOriginal = [4, 5, 6];\n\n$resultado = byValor($arrAOriginal, $arrBOriginal);\necho \"La funcion retornó los valores: \".print_r($resultado, true).\"\\n\";\necho \"pero los valroes valores originales siguen siendo: \".print_r($arrAOriginal, true). \" y \".print_r($arrBOriginal, true).\"\\n\";\n\necho \"\\nPaso por referencia\\n\";\nfunction byReferencia(&$a, &$b){\n    $aux = $a;\n    $a = $b;\n    $b = $aux;\n\n    return [$a, $b];\n}\n\n$aOriginal = 2;\n$bOriginal = 3;\n\necho \"El valor de aOriginal es: \".$aOriginal.\"\\n\";\necho \"El valor de bOriginal es: \".$bOriginal.\"\\n\";\n\n$resultado = byReferencia($aOriginal, $bOriginal);\necho \"La funcion retornó los valores: \".implode(\",\", $resultado).\"\\n\";\necho \"Y los valores originales ahora son: \".$aOriginal.\" y \".$bOriginal.\"\\n\";\n\n$arrAOriginal = [1, 2, 3];\n$arrBOriginal = [4, 5, 6];\n\n$resultado = byReferencia($arrAOriginal, $arrBOriginal);\necho \"La funcion retornó los valores: \".print_r($resultado, true).\"\\n\";\necho \"Y los valores originales ahora son: \".print_r($arrAOriginal, true). \" y \".print_r($arrBOriginal, true).\"\\n\";\n\n\n\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/php/qv1ko.php",
    "content": "<?php\n\n    main();\n\n    function main() {\n\n        $a = 3;\n        $b = 4;\n        $x = 5;\n        $y = 6;\n\n        $newAB = program1($a, $b);\n        $newXY = program2($x, $y);\n\n        echo \"\\nA value: \" . $a;\n        echo \"\\nNew A value: \" . $newAB[0];\n        echo \"\\nB value: \" . $b;\n        echo \"\\nNew b value: \" . $newAB[1];\n        echo \"\\nX value: \" . $x;\n        echo \"\\nNew X value: \" . $newXY[0];\n        echo \"\\nY value: \" . $y;\n        echo \"\\nNew Y value: \" . $newXY[1];\n\n    }\n\n    function program1($a, $b) {\n\n        $temp = $a;\n\n        $a = $b;\n        $b = $temp;\n\n        return [$a, $b];\n\n    }\n\n    function program2(&$x, &$y) {\n\n        $temp = $x;\n\n        $x = $y;\n        $y = $temp;\n\n        return [$x, $y];\n\n    }\n\n?>\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/59822.py",
    "content": "'''Asignación de variables por valor y por referencia'''\n# Referencia significa que si se cambia una variable, la otra también se cambia\n# Valor significa que si se cambia una variable, la otra no se cambiará\n\n# Por valor -> primitivos\n# int, float, boolean, string, tuple\n\nvariable = 19\nvariable1 = variable\nvariable1 = 20\nprint(variable)\nprint(variable1)\n\n# Por referencia -> Listas\n# listas, diccionarios, conjuntos\n\nlista = [10, 20]\nlista2 = lista\nlista2.append(30) # Cambia la lista original porque es por referencia\nprint(lista)\nprint(lista2)\n\n\n# Tipo de dato por valor\n\ndef valor(valor_a: int):\n    valor_a = 20\n    print(valor_a)\n\nvalor(10)\n\n# Tipo de dato por referencia\n\ndef referenca(valor : list):\n    valor.append(30)\n    print(valor)\n    \nreferenca([10, 20])\n\n''' Difficultad extra '''\n# 2 parametros por valor\ndef valores(x, y): \n    z = x\n    x = y\n    y = z\n    return(x, y) # No puede ser print, porque no se puede asignar a una función\n\nvalor0 = 10\nvalor3 = 20\nx1, y1 = valores(valor0, valor3)\n\nprint(valor0, valor3) # 10, 20\nprint(x1, y1) # 20, 10\n\n# 2 parametros por referencia\ndef referencia(x: set, y: set):\n    x = y\n    y = x\n    return x, y\n\nvalor1 = {10, 20}\nvalor2 = {20, 30}\n\nvalornew, valornew2 = referencia(valor1, valor2)\n\nprint(valor1, valor2) # {10, 20}, {20, 30}\nprint(valornew, valornew2) # {20, 30}, {20, 30}\n    "
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/AChapeton.py",
    "content": "# Varaibles por Valor\n\na = 'Hola Mundo'\nb = a # El valor de \"a\" se asigna a \"b\", creando como una copia de este\n\na += \"!\" # Se modifica el valor solo de \"a\"\n\nprint('a', a)\nprint('b', b)\n\n# Variables por Referencia\n# Con estructuras, no se crea un nuevo valor, sino que ambas variables apuntan a un mismo espacio en memoria\n\nc = [1, 2, 3]\nd = c\n\nc.insert(0, 4)\n\nprint('c', c)\nprint('d', d)\n\n\n# Funciones utilizando Variables por Valor\n\ndef firstFunction(str):\n  str = 'Nuevo valor dentro de la funcion'\n  return str\n\nstrOriginal = 'Fuera de la funcion'\nprint('Por valor - Dentro de la funcion: ', firstFunction(strOriginal))\nprint('Por valor - Fuera de la funcion: ', strOriginal)\n\n# Funciones utilizando Variables por Referencia\n\ndef secondFunction(arr):\n  arr.insert(0, 'Moure')\n  return arr\n\narrOriginal = ['Andres', 'Brais', 'Chape']\nprint('Por referencia - Dentro de la funcion: ', secondFunction(arrOriginal))\nprint('Por referencia - Fuera de la funcion: ', arrOriginal)\n\n\n# DIFICULTAD EXTRA\n\n# Funcion para intercambiar variables por valor\n\ndef intercambiarValor(num1, num2):\n  temp = num1\n  num1 = num2\n  num2 = temp\n  return [num1, num2]\n\nprimerValor = 10\nsegundoValor = 5\n\nprint('Valores antes del intercambio')\nprint('primerValor: ', primerValor)\nprint('segundoValor\" ', segundoValor)\n\nnuevosValores = intercambiarValor(primerValor, segundoValor)\n\nprint('Valores despues del intercambio')\nprint('primerValor: ', primerValor)\nprint('segundoValor ', segundoValor)\n\nprint('Nuevos valores intercambiados')\nprint('primerValor: ', nuevosValores[0])\nprint('segundoValor ', nuevosValores[1])\n\n\n# Funcion para intercambiar variables por referencia\n\nnombresOriginal = ['Andres', 'Edith', 'Chape', 'Yc']\n\ndef intercambiarReferencias(arr):\n  temp = arr[1]\n  arr[1] = arr[3]\n  arr[3] = temp\n  return arr\n\nprint('Referencias antes del intercambio')\nprint('Lista original', nombresOriginal)\n\nnombresNuevo = intercambiarReferencias(nombresOriginal)\n\nprint('Referencias despues del intercambio')\nprint('Lista original', nombresOriginal)\n\nprint('Nuevas referencias intercambiadas')\nprint('nombresNuevo', nombresNuevo)\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/AbelPerezCollado.py",
    "content": "# Asignación de variables por VALOR\na = 5\nb = a\nb = 10\nprint(a)\nprint(b)\n\n# Asignación de un flotante\nx = 3.14\ny = x  # y ahora es una copia de x\n\n# Modificando y no afecta a x\ny = 2.71\nprint(x)  # Output: 3.14\nprint(y)  # Output: 2.71\n\n# Asignación de una cadena de caracteres\ns1 = \"Hola\"\ns2 = s1  # s2 ahora es una copia de s1\n\n# Modificando s2 no afecta a s1\ns2 = \"Adiós\"\nprint(s1)  # Output: Hola\nprint(s2)  # Output: Adiós\n\n\n# Asignación de una tupla\nt1 = (1, 2, 3)\nt2 = t1  # t2 ahora es una copia de t1\n\n# Modificando t2 no afecta a t1\nt2 = (4, 5, 6)\nprint(t1)  # Output: (1, 2, 3)\nprint(t2)  # Output: (4, 5, 6)\n\n# Asignación de variables por REFERENCIA\n\n# Listas\n# Asignación de una lista\nlist1 = [1, 2, 3]\nlist2 = list1  # list2 se refiere a la misma lista que list1\n\n# Modificando list2 también afecta a list1\nlist2.append(4)\nprint(list1)  # Output: [1, 2, 3, 4]\nprint(list2)  # Output: [1, 2, 3, 4]\n\n# Asignación de un diccionario\ndict1 = {'a': 1, 'b': 2}\ndict2 = dict1  # dict2 se refiere al mismo diccionario que dict1\n\n# Modificando dict2 también afecta a dict1\ndict2['c'] = 3\nprint(dict1)  # Output: {'a': 1, 'b': 2, 'c': 3}\nprint(dict2)  # Output: {'a': 1, 'b': 2, 'c': 3}\n\n# Asignación de un conjunto\nset1 = {1, 2, 3}\nset2 = set1  # set2 se refiere al mismo conjunto que set1\n\n# Modificando set2 también afecta a set1\nset2.add(4)\nprint(set1)  # Output: {1, 2, 3, 4}\nprint(set2)  # Output: {1, 2, 3, 4}\n\n\n# DIFICULTAD EXTRA\n# VALOR\ndef intercambia_valor(param_1, param_2):\n    return param_2, param_1\n\nparam_1 = input(\"Introduce primer parametro: \")\nparam_2 = input(\"Introduce segundo parametro: \")\n\nnuevo_param_1 , nuevo_param_2 = intercambia_valor(param_1,param_2)\nprint(f\"Variables originales param_1 = {param_1}\")\nprint(f\"Variables originales param_2 = {param_2}\")\nprint(f\"Variables nuevo_param_1 = {nuevo_param_1}\")\nprint(f\"Variables nuevo_param_2 = {nuevo_param_2}\")\n\n# REFERENCIA\nlista_1 = [1,2,3]\nlista_2 = [4,5,6]\n\ndef intercambia_referencia(val_1, val_2):\n    val_1 = val_2\n    val_2 = val_1\n    return val_1, val_2\n\nnueva_lista_1, nueva_lista_2 = intercambia_referencia(lista_1,lista_2)\n\nprint(f\"Variables originales lista_1 = {lista_1}\")\nprint(f\"Variables originales lista_2 = {lista_2}\")\nprint(f\"Variables nueva_lista_1 = {nueva_lista_1}\")\nprint(f\"Variables nueva_lista_2 = {nueva_lista_2}\")"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/AgustinDamonte17.py",
    "content": "# ============================================\n# ASIGNACIÓN DE VARIABLES\n# ============================================\n\nprint(\"===== ASIGNACIÓN DE VARIABLES =====\")\n\n# Inmutables (por valor)\na = 10\nb = a\nb += 5\nprint(\"Inmutables:\")\nprint(f\"a = {a}, b = {b} (modificar b no afecta a a)\")\n\n# Mutables (por referencia)\nlista1 = [1, 2, 3]\nlista2 = lista1\nlista2.append(4)\nprint(\"\\nMutables:\")\nprint(f\"lista1 = {lista1}, lista2 = {lista2} (ambas apuntan al mismo objeto)\")\n\n# Para evitar eso: usar copia\nimport copy\nlista3 = copy.deepcopy(lista1)\nlista3.append(99)\nprint(f\"lista1 = {lista1}, lista3 (copiada) = {lista3}\")\n\n\n# ============================================\n# FUNCIONES CON VARIABLES INMUTABLES Y MUTABLES\n# ============================================\n\nprint(\"\\n===== PASO DE VARIABLES A FUNCIONES =====\")\n\n# Inmutable (int)\ndef modificar_entero(x):\n    x += 1\n    print(\"Dentro de la función (int):\", x)\n\nn = 5\nmodificar_entero(n)\nprint(\"Fuera de la función (int):\", n)\n\n# Mutable (lista)\ndef modificar_lista(lst):\n    lst.append(99)\n    print(\"Dentro de la función (lista):\", lst)\n\nmi_lista = [1, 2, 3]\nmodificar_lista(mi_lista)\nprint(\"Fuera de la función (lista):\", mi_lista)\n\n\n# ============================================\n# DIFICULTAD EXTRA: INTERCAMBIO DE VARIABLES\n# ============================================\n\nprint(\"\\n===== DIFICULTAD EXTRA =====\")\n\n# Intercambio por valor (inmutables)\ndef intercambiar_valores(x, y):\n    x, y = y, x\n    return x, y\n\n# Intercambio por referencia (mutables)\ndef intercambiar_listas(l1, l2):\n    l1[:], l2[:] = l2[:], l1[:]\n    return l1, l2\n\n# Variables originales\nvalor1 = 100\nvalor2 = 200\nlista1 = [1, 2]\nlista2 = [3, 4]\n\n# Llamadas\nnuevo_valor1, nuevo_valor2 = intercambiar_valores(valor1, valor2)\nnueva_lista1, nueva_lista2 = intercambiar_listas(lista1.copy(), lista2.copy())  # Usamos copia para preservar las originales\n\nprint(\">>> Intercambio por valor (enteros)\")\nprint(\"Originales: valor1 =\", valor1, \", valor2 =\", valor2)\nprint(\"Nuevas:     nuevo_valor1 =\", nuevo_valor1, \", nuevo_valor2 =\", nuevo_valor2)\n\nprint(\"\\n>>> Intercambio por referencia (listas con copia)\")\nprint(\"Originales: lista1 =\", lista1, \", lista2 =\", lista2)\nprint(\"Nuevas:     nueva_lista1 =\", nueva_lista1, \", nueva_lista2 =\", nueva_lista2)"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/AlainMartz.py",
    "content": "#05 VALOR Y REFERENCIA\n\n# EJERCICIO:\n# - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según su tipo de dato.\n# - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \"por referencia\", y cómo\n#   se comportan en cada caso en el momento de ser modificadas. \n#   (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n\n# Variables por valor\n# Una variable almacena directamente el valor asignado. Al copiar la variable, se crea una copia independiente del valor orinal.\n# Aunque Python no utiliza estrictamente variables por valor, el comportamiento de tipos inmutables (como enteros, flotantes, cadenas, tuplas, booleanos) puede parecerse a este concepto.\n\nx = 123                                   #   \ny = x                                     # 'x' e 'y' son independientes luego de la asignación de y=x, entonces, cambiar 'y' no afecta a 'x'  \ny = \"ciento veintitres\"                                 \nprint(f\"\"\"\n      x = 123\n      y = x\n      y = 'ciento veintitres'\n\nLa asignación de y = x, no afecta los valores x: {x}, y: {y}\nDirección en la memoria de x: {id(x)}\nDirección en la memoria de y: {id(y)}\n      \"\"\")\n\na = 9\nb = 4.9\nc = \"veintiseis\"\nd = (2,3)\ne = True\nprint(f\"Tipos inmutables que son pasados como valor\\nEntero: {a}\\nFlotante: {b}\\nCadena: {c}\\nTuplas: {d}\\nBooleanos: {e}\\n\")\n\n\n# En este ejemplo\n\nn = 10  \ndef doblar_valor(numero):\n    numero *= 2\n    return numero\n\nx = doblar_valor(n)\nprint(f\"El valor de x es {x}\\nSu ubicación en la memoria es {id(x)}\")\nprint(f\"El valor de x es {n}\\nSu ubicación en la memoria es {id(n)}\")\n\n\n# Variables por referencia\n# Una variable almacena una referencia (o dirección de memoria) al valor real. Al copiar la variable, ambas variables se refieren al mismo valor en memoria.\n\nx = [1,4,7]\ny = x\ny.append(10)\n\nprint(f\"\"\"\n      x = [1,4,7]\n      y = x\n      y.append(10)\n\nLa asignación de y = x, afecta los valores x: {x}, y: {y}, que tienen la misma asignación de memoria\nDirección en la memoria de x: {id(x)}\nDirección en la memoria de y: {id(y)}\n      \"\"\")\n\n\n# otros tipos de variables por referencia\n\nf = ['a','b','c']\ng = {'a':1,'b':2,'c':3}\nh = {1,2,3}\n\nprint(f\"Tipos mutables\\nLista: {f}\\nDiccionario: {g}\\nSet: {h}\")\n\n\n### Desafío extra ### \n\nprint(\"\\nDesafio extra\\n\")\n\na = 1\nb = 2\ndef reverse(v1,v2):\n    v1,v2 = v2,v1\n    return v1,v2\nx,y = reverse(a,b)\n\nprint(f\"Variables originales => a:{a}, b:{b}\\nVariables nuevas     => x:{x}, y:{y}\")\n\nreverse(a,b)\n\nc = [1,2,3]\nd = [4,5,6]\n\ndef inverse(r1,r2):\n    r1,r2 = r2,r1\n    return r1, r2\n\nv,w = inverse(c,d)\nprint(f\"Variables originales => a:{c}, b:{d}\\nVariables nuevas     => x:{v}, y:{w}\")"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/AlbertoMorilla.py",
    "content": "# #05 VALOR Y REFERENCIA\n\n\"\"\"\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n    su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n    \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n    (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n\"\"\"\n\n# Tipos de datos por valor\n\nmy_int_a = 10\nmy_int_b = my_int_a\n#my_int_b = 20\nprint(my_int_a)  # 10\nprint(my_int_b)\n\n# Tipos de datos por referencia\n\nmy_list_a = [10, 20]\nmy_list_b = my_list_a\nmy_list_b.append(30)\nprint(my_list_a)\nprint(my_list_b)\n\n# Funciones con datos por valor\n\ndef my_int_func(my_int: int):\n    my_int = 20\n    print(my_int) \n\nmy_int_c = 10\nmy_int_func(my_int_c)\nprint(my_int_c)\n\n# Funciones con datos por referencia\n\n\ndef my_list_func(my_list: list):\n   my_list.append(30)\n\n   my_list_d = my_list\n   my_list_d.append(40)\n   \n   print(my_list)\n   print(my_list_d)\n\n\nmy_list_c = [10, 20]\nmy_list_func(my_list_c)\nprint(my_list_c)\n\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n    Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n    se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n    variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n    Comprueba también que se ha conservado el valor original en las primeras.\n \n\"\"\"\n\n# Por valor\n\ndef value(value_a: int, value_b:int) -> tuple:\n    temp = value_a\n    value_a = value_b\n    value_b = temp\n    return value_a, value_b\n    \nmy_int_d = 20\nmy_int_e = 30\nmy_int_f, my_int_g = value(my_int_d, my_int_e)\n\nprint(f\"{my_int_d}, {my_int_e}\")\nprint(f\"{my_int_f}, {my_int_g}\")\n\n# Por referencia\n\ndef ref(value_a:list, value_b:list) -> tuple:\n    temp = value_a\n    temp.append(50)\n    value_a = value_b\n    value_b = temp\n    return value_a, value_b\n    \nmy_list_e = [10, 20]\nmy_int_f = [30, 40]\nmy_int_g, my_int_h = ref(my_list_e, my_int_f)\nprint(f\"{my_list_e}, {my_int_f}\")\nprint(f\"{my_int_g}, {my_int_h}\")"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/Aldroide.py",
    "content": "# Ejemplos de asignación de variables por valor y por referencia\n\n\"\"\"Asignación de variables por valor en una función, \nse genera una copia del valor original\nesto permite que no se modifique el valor de la variable ejemplo:\"\"\"\nx = 10\n\n\ndef funcion_valor(v1):\n    v1 = 0\n\n\nfuncion_valor(x)\nprint(x)\n\n# Asignación por valor tipos inmutables\na = 5\nb = a  # se copia el valor e a\nb = 10  # Esto no afecta el valor de a\n\nprint(a)\nprint(b)\n\n# paso por referencia\nnumero = [10, 20, 30]\n\n\ndef duplicar(numeros):\n    for i, numero in enumerate(numeros):\n        numeros[i] *= 2\n\n\nprint(f\"Lista antes de paso por referencia {numero}\")\nduplicar(numero)\nprint(f\"Lista despues de pasar por referencia {numero}\")\n\n\n# paso por parametro\ndef multiplicar_valor(valor):\n    valor *= 2\n    return valor\n\n\nx = 6\nmultiplicado = multiplicar_valor(x)\nprint(f\"Valor original {x}\")\nprint(f\"Valor multimplicado {multiplicado}\")\n\n\n\"\"\" Aqui la dificultad extra de este ejercicio \"\"\"\n\n\ndef cambio_por_valor(val1, val2):\n    tmp = val1\n    val1 = val2\n    val2 = tmp\n    return val1, val2\n\n\nx = 3\ny = 5\nx1, y1 = cambio_por_valor(x, y)\nprint(f\"Variables originales {x}, {y}\")\nprint(f\"Variables nuevas {x1}, {y1}\")\n\n\ndef cambio_por_refer(list1, list2):\n    new_list1 = list2\n    new_list2 = list1\n\n    return new_list1, new_list2\n\n\nlist1 = [23, 45, 54]\nlist2 = [45, 56.45]\n\nnew_list1, new_list2 = cambio_por_refer(list1, list2)\n\nprint(\"Las listas originales son: \", list1, \"y \", list2)\nprint(\"Las listas nuevas son: \", new_list1, \"y \", new_list2)\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/Aleran07.py",
    "content": "# 05\n# Variables por valor int, float, str, bool, tuple\n\n# int\na = 10\nb = a      # b recibe una copia del valor de a\n\na = 20     # Cambiamos 'a'\n\nprint(a)  # 20\nprint(b)  # 10 → b NO se vio afectada\n\n# str\nx = \"Hola\"\ny = x\nx = \"Chao\"\n\nprint(x)  # Chao\nprint(y)  # Hola → no cambia, porque string es INMUTABLE\n\n\n# Variables por referencia list, dict, set, objetos personalizados\n\n#list\nlista1 = [1, 2, 3]\nlista2 = lista1   # lista2 apunta a la MISMA lista en memoria\n\nlista1.append(4)\n\nprint(lista1)  # [1, 2, 3, 4]\nprint(lista2)  # [1, 2, 3, 4] → también cambió\n\n\"\"\"se puede evitar la referecia con . copy()\"\"\"\n\nlista1 = [1, 2, 3]\nlista2 = lista1.copy()  # o lista2 = lista1[:] o list(lista1)\nlista3 = lista1[:]\nlista4 = list(lista1)\n\nlista1.append(4)\n\nprint(lista1)  # [1, 2, 3, 4]\nprint(lista2)  # [1, 2, 3]\nprint(lista3)  # [1, 2, 3]\nprint(lista4)  # [1, 2, 3]\n\n# Ejemplo de referencia en memoria\na = [1, 2, 3]\nb = a\n\nprint(id(a))  # 140192940769920 (ejemplo)\nprint(id(b))  # 140192940769920 → mismo id = MISMO objeto\n\nb = a.copy()  # Con copia\nprint(id(a))  # 140192940769920\nprint(id(b))  # 140192940770288 → distinto id = OBJETO DIFERENTE\n\n# Funciones por valor\n# int\ndef modificar_numero(x): # Se crea una copia del valor, no afecta a 'a'\n    x = x + 10\n    print(\"Dentro de la función:\", x)\n\na = 5\nmodificar_numero(a)\nprint(\"Fuera de la función:\", a)\n\n# str\ndef cambiar_texto(texto):\n    texto = texto.upper()\n    print(\"Dentro de la función:\", texto)\n\nmsg = \"hola\"\ncambiar_texto(msg)\nprint(\"Fuera de la función:\", msg)\n\n# funciones por valor\ndef modificar_lista(lista):\n    lista.append(100) # La modificación AFECTA al original porque apuntan al mismo objeto en memoria\n    print(\"Dentro de la función:\", lista)\n\nnums = [1, 2, 3]\nmodificar_lista(nums)\nprint(\"Fuera de la función:\", nums)\n\n# Evitar que se modifique el original\ndef modificar_sin_afectar(lista):\n    copia = lista.copy()  # o lista[:] o list(lista)\n    copia.append(999)\n    print(\"Dentro de la función:\", copia)\n\nnums = [1, 2, 3]\nmodificar_sin_afectar(nums)\nprint(\"Fuera de la función:\", nums)\n\n# Ejemplo visual de objeto en memoria\ndef revisar(obj):\n    print(\"ID dentro:\", id(obj))\n\na = [1,2,3]\nprint(\"ID fuera:\", id(a)) # Los IDs coinciden → es el mismo objeto en memoria\nrevisar(a)\n\n\"\"\"\n----------------------------------------------------------------------------------------\nTipo de dato                 - Se modifica fuera de la funcion? - Naturaleza\n----------------------------------------------------------------------------------------\nint, float, str, bool, tuple - No cambia                        - Inmutable por valor\n\nlist, dict, set, objetos     - Puede cambiar                    - Mutable por referencia\n\nPara evitarlo                - Usar .copy()                     - se protege el original\n----------------------------------------------------------------------------------------\n\"\"\"\n\n\"\"\"Ejecicio Extra\nCrea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n\"\"\"\n\n# Funcion de intercambio por Valor\n\nvalor1 = 10\nvalor2 = \"Hola\"\n\n# nota si no le añado nada para crear un nuevo objeto, el id no cambia.\ndef  intercam_valor (valor1, valor2):\n    ax = valor1\n    valor1 = valor2 + \" bro\" # <-- aquí se crea una NUEVA cadena\n    valor2 = ax + 10\n    return (valor1, valor2)  # <-- aquí se crea un NUEVO entero (20)\n\nvalor3, valor4 = intercam_valor(valor1, valor2)\n\nprint(valor1, f\"Id variable 1: {id(valor1)}\", valor2, f\"Id variable 2: {id(valor2)}\")\nprint(valor3,f\"Id variable 3: {id(valor3)}\", valor4, f\"Id variable 4: {id(valor4)}\")\n\n\n\n# Funcion de intercambio por Referencia\nvalor1 = [1, 2 , 3]\nvalor2 = [4, 5, 6]\nprint(valor1, f\"Id variable 1: {id(valor1)}\", valor2, f\"Id variable 2: {id(valor2)}\")\n\ndef  intercam_valor (x, y):\n    y.append(10)\n    x.append(100)\n    return (x, y)\n\nvalor3, valor4 = intercam_valor(valor1, valor2)\n\nprint(valor1, f\"Id variable 1: {id(valor1)}\", valor2, f\"Id variable 2: {id(valor2)}\")\nprint(valor3,f\"Id variable 3: {id(valor3)}\", valor4, f\"Id variable 4: {id(valor4)}\")"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/AllanYSalazarG.py",
    "content": "\"\"\" #05 VALOR Y REFERENCIA \"\"\"\n\n# Modulos importados\n\"\"\" import copy\n\n# ---------- Asignación de variable por valor ----------\n\nprint(\"---------- Asignación de variables por valor ----------\")\nstring = \"Hola\"\nanotherString = string\nanotherString = \"mundo\"\nnumber = 1\nanotherNumber = number\nanotherNumber = 2\nfloatNumber = 1.5\nanotherFloatNumber = floatNumber\nanotherFloatNumber = 3.4\nprint(string, anotherString, anotherNumber, anotherFloatNumber)\n\n# Cuando se asigna por valor, pasa que en caso de anotherString = string,\n# anotherString guarda una copia de string, por lo que si modificamos anotherString,\n# string no se ve afectada.\n# Esto aplica para los numeros (enteros y flotantes), caracteres, cadenas y tuplas.\n\n# ---------- Asignación de variable por referencia ----------\n\nprint(\"---------- Asignación de variables por referencia ----------\")\naList = [1, 2, 3]\nanotherList = aList\nanotherList.append(4)\naDicc = {\"id\": 1,\n         \"Name\": \"Allan\",\n         \"LastName\": \"Salazar\"}\nanotherDicc = aDicc\n# Con update tambien podemos agregar claves y valores al diccionario\nanotherDicc[\"age\"] = 29\nnewSet = {1, 2, 3, 4, 5, 6}\nanotherSet = newSet\nanotherSet.add(7)\nprint(aList, anotherList, aDicc, anotherDicc, newSet, anotherSet)\n\n# Las listas, diccionarios y conjuntos (sets) se asignan por referencia\n# pasa que la nueva variable hace referencia a la anterior.\n# Por ejemplo, en anotherList = aList, significa que podemos acceder al mismo espacio\n# de memoria tanto como anotherList como con aList, por lo que se ve reflejado\n# el cambio en ambas variables\n\n# ---------- Copia de variables por referencia ----------\n\n# Si queremos hacer que los datos de listas, diccionaros y conjuntos no se cambien,\n# o que funcionen como las variables asignadas por valor, necesitamos\n# el metodo copy o importar el modulo copy (al inicio del doc)\n\n# Usando el metodo copy\n\nprint(\"---------- Copiando variables asignadas por referencia ----------\")\nprint(\"---------- Usando el metodo copy() ----------\")\nnewList = [7, 8, 9, 10]\nanotherNewList = newList.copy()\nanotherNewList.append(11)\nprint(newList, anotherNewList)\n\n# Usando el modulo copy\n\nprint(\"---------- Usando el modulo copy y su metodo deepcopy() ----------\")\nnewList = [[1, 2], [3, 4]]\nanotherNewList = copy.deepcopy(newList)\nanotherNewList.append([5, 6])\nprint(newList, anotherNewList) \"\"\"\n\n# ---------- EJERCICIO ----------\n\n\nprint(\"---------- EJERCICIO ----------\")\n\nfirstParamValue = 1\nsecondParamValue = \"hola\"\nfirstParamReference = [1, 2, 3]\nsecondParamReference = {4, 5, 6}\n\nprint(firstParamValue, secondParamValue)\nprint(firstParamReference, secondParamReference)\n\n\ndef functionPerValue(firstParamValue, secondParamValue):\n    tempVar = firstParamValue\n    firstParamValue = secondParamValue\n    secondParamValue = tempVar\n    return firstParamValue, secondParamValue\n\n\ndef functionPerReference(firstParamReference, secondParamReference):\n    firstParamReference = secondParamReference\n    secondParamReference = firstParamReference\n    return firstParamReference, secondParamReference\n\n\nnewFirstParamValue, newSecondParamValue = functionPerValue(firstParamValue,\n                                                           secondParamValue)\nnewFirstParamReference, newSecondParamReference = functionPerReference(firstParamReference,\n                                                                       secondParamReference)\nprint(firstParamValue, secondParamValue)\nprint(firstParamReference, secondParamReference)\nprint(newFirstParamValue, newSecondParamValue)\nprint(newFirstParamReference, newSecondParamReference)\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/Alvaro-Neyra.py",
    "content": "# - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según su tipo de dato.\n# Primero hay que aclarar que significan las asignaciones de variables pasadas \"por valor\" y \"referencia\".\n## * Si usamos un parametro pasado por valor, se creara una copia local de la variable, lo que implica que cualquier modificacion sobre la\n##      la misma no tendra efecto sobre la original.\n## * Con una variable pasada como referencia, se actuara directamente sobre la variable pasada, por lo que las modificaciones afectaran\n##      a la variable original.\n\n### Tradicionalmente:\n### * Los tipos de datos inmutables se pasan por valor: Numericos, Textos, Booleanos, Tuplas\n### * Los tipos de datos mutables se pasan por referencia: Listas, Diccionarios, Conjuntos\n\n# Variables por valor:\n# Ya que los numericos son inmutables entonces no se cambiaran sus valores al asignarlo a otra variable, se creara una copia de ellas.\na = 400\nb = a\nb += 5\nprint(a)\nprint(b)\n# Variables por referencia:\n# Ya que las lista son tipos de datos asignados por referencia podran ser modificados luego de haber sido asignados a otra variable (tipo de dato mutable)\nlista_a = [30, 400, 100]\nlista_b = lista_a # Se comparte la referencia\nlista_b.append(60)\nprint(lista_a, lista_b)\n## > Para verificar que la lista_a y lista_b comparten la misma referencia del objeto podemos usar la funcion id()\nprint(f\"Las listas a y b comparten la misma referencia al objeto, id(lista_a): {id(lista_a)} ,id(lista_b): {id(lista_b)} (tienen el mismo id)\")\n\n# - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \"por referencia\", y cómo se comportan en cada caso en \n#   el momento de ser modificadas.\n\n## Tipos de datos pasados por valor\n# Entero: (int)\n# Como puedes ver esta funcion dobla la variable pasada pero como es un tipo de dato entero y es un tipo de dato que se pasa por valor.\n# Entonces la variable no es modificada.\nvariable_numerica = 30\ndef doblar_valor(variable):\n    variable *= 2\n\ndoblar_valor(variable_numerica)\nprint(variable_numerica)\n# Textos (str):\n# Como ves como str es un tipo de dato por valor entonces no sera modificada por la funcion\nvariable_cadena = \"abc\"\ndoblar_valor(variable_cadena)\nprint(variable_cadena)\n# Booleanos\n# En el caso de los booleanos al multiplicarlos por numeros, True seria 1 y False seria 0.\n# Como los booleanos son tipos de datos pasados por valor no seran modificados por la funcion\nvariable_booleana = True\ndoblar_valor(variable_booleana)\nprint(variable_booleana)\n# Tuplas\n# Como puedes ver la tupla es un tipo de dato inmutable, entonces debido a las reglas y caracteristicas que contiene este tipo de dato, no se va\n# a poder modificar luego de haber sido declarada. Entonces al intentar duplicar los elementos de la tupla no se van a poder reasignar.\nvariable_tupla = (\"Hola\", True, 59, \"Mundo\")\ndoblar_valor(variable_tupla)\nprint(variable_tupla)\n\n## Tipos de datos pasados por referencia\n# Listas\n# Como puedes ver la lista si sera modificada por la funcion, ya que es un tipo de dato pasado por referencia.\nvariable_lista = [2, 300, 400, 50, 19]\ndoblar_valor(variable_lista)\nprint(variable_lista)\n# Diccionarios\n# Como puedes ver la funcion anadira una clave al diccionario, ya que el diccionario es un tipo de dato por referencia se modificara.\nvariable_diccionario = {\n    \"nombre\": \"Alvaro\",\n    \"apellido\": \"Neyra\",\n    \"edad\": 19\n}\ndef anadir_clave(dict: dict):\n    dict.update({\"mascota\": True})\nanadir_clave(variable_diccionario)\nprint(variable_diccionario)\n# Conjuntos (sets)\nvariable_conjunto = {True, \"Moure\", \"❤️\"}\n# Una de las caracteristicas de los conjuntos es que no puede tener elementos duplicados, entonces anadiremos un elemento nuevo con otra funcion\n# Ya que el conjunto es un tipo de dato pasado por referencia entonces si se podra modificar.\ndef anadir_elemento(conjunto: set):\n    conjunto.add(\"Gracias por todo!\")\nanadir_elemento(variable_conjunto)\nprint(variable_conjunto)\n\n\"\"\"DIFICULTAD EXTRA:\"\"\"\n# Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\nvariable_valor1 = 400\nvariable_valor2 = \"'Hola, Mundo!'\"\nvariable_referencia1 = [30, 600, 81, 20]\nvariable_referencia2 = {True, \"'Soy Un conjunto'\", 20}\n\ndef modificar_variables_valor(valor1, valor2):\n    valor1, valor2 = valor2, valor1\n    print(f\"Valor1: {valor1}\")\n    print(f\"Valor2: {valor2}\")\n    return valor1, valor2\ndef modificar_variables_referencia(referencia1, referencia2):\n    referencia1, referencia2 = referencia2, referencia1\n    return referencia1, referencia2\n\nresultado_por_valor1, resultado_por_valor2 = modificar_variables_valor(variable_valor1, variable_valor2)\nresultado_por_referencia1, resultado_por_referencia2 = modificar_variables_referencia(variable_referencia1, variable_referencia2)\n\n# Imprimir resultados:\nprint(f\"Variables originales:\")\nprint(f\"- Variables por valor:\")\nprint(f\"Originales: {variable_valor1}, {variable_valor2}, Luego de pasarlas a la funcion: {resultado_por_valor1}, {resultado_por_valor2}\")\nprint(f\"- Variables por referencia:\")\nprint(f\"Originales: {variable_referencia1}, {variable_referencia2}, Luego de pasarlas a la funcion: {resultado_por_referencia1}, {resultado_por_referencia2}\")"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/AndresMCardenas.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n#  *   su tipo de dato.\n#  * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n#  *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n#  * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea dos programas que reciban dos parámetros (cada uno) definidos como\n#  * variables anteriormente.\n#  * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n#  *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n#  *   se asigna a dos variables diferentes a las originales. A continuación, imprime\n#  *   el valor de las variables originales y las nuevas, comprobando que se ha invertido\n#  *   su valor en las segundas.\n#  *   Comprueba también que se ha conservado el valor original en las primeras.\n#  */\n\n# Asignación de variables por valor y por referencia\n\n# Por valor\n\n# En Python, los tipos de datos primitivos (int, float, string, bool) se asignan por valor.\n# Esto significa que si se asigna una variable a otra, se copia el valor de la primera\n# en la segunda, y si se modifica la segunda, la primera no se ve afectada.\n\n# Ejemplo:\n\na = 5 # Se asigna el valor 5 a la variable a\nb = a # Se asigna el valor de a a la variable b\nb = 10 # Se modifica el valor de b\nprint(a) # Imprime 5\nprint(b) # Imprime 10\n\n# Por referencia\n\n# En Python, los tipos de datos compuestos (listas, diccionarios, conjuntos, tuplas) se asignan por referencia.\n# Esto significa que si se asigna una variable a otra, ambas apuntan a la misma dirección de memoria,\n# y si se modifica una de ellas, la otra se ve afectada.\n\n# Ejemplo:\n\nlista1 = [1, 2, 3] # Se asigna una lista a la variable lista1\nlista2 = lista1 # Se asigna la lista de lista1 a la variable lista2\nlista2[0] = 4 # Se modifica el primer elemento de lista2\nprint(lista1) # Imprime [4, 2, 3]\nprint(lista2) # Imprime [4, 2, 3]\n\n# Funciones con variables por valor y por referencia\n\n# Por valor\n\n# Si se pasa una variable por valor a una función, se crea una copia de la variable en la función,\n# y si se modifica la variable en la función, la original no se ve afectada.\n\n# Ejemplo:\n\ndef duplicar(x):\n  x = x * 2\n  return x\n\na = 5\nprint(duplicar(a)) # Imprime 10\nprint(a) # Imprime 5\n\n# Por referencia\n\n# Si se pasa una variable por referencia a una función, se pasa la dirección de memoria de la variable,\n# y si se modifica la variable en la función, la original se ve afectada.\n\n# Ejemplo:\n\ndef duplicar_elementos(lista): # Se pasa una lista por referencia\n  for i in range(len(lista)): # Se recorre la lista\n      lista[i] = lista[i] * 2 # Se duplica cada elemento\n  return lista # Se retorna la lista modificada\n\nlista = [1, 2, 3]\nprint(duplicar_elementos(lista)) # Imprime [2, 4, 6]  \nprint(lista) # Imprime [2, 4, 6]\n\n# Dificultad extra (opcional)\n\n# Programa que recibe dos parámetros por valor, los intercambia y los retorna\n\n# Por valor\n\ndef intercambiar_valores(a:int, b:int) -> tuple: # recibe los valores enviados por al invocarla la funcion\n  temp = a\n  a = b\n  b = temp\n  return a, b\n\nc = 10\nd = 20\ne , f = intercambiar_valores(c , d)\n\nprint(f\"valor inicial de c:{c},y de d:{d}\")\nprint(f\"valor retoranado por la funcion en e:{e},y en f:{f}\")\n\n# Por referencia\n\ndef por_referencia (g:int, h:int) -> tuple: # recibe los parametros\n  temp = g\n  g = h \n  h = temp\n  return g, h\n\ni = [10, 20]\nj = [30, 40]\nk , l = por_referencia(i, j)\nprint(f\"Valor original de i: {i},y de j: {j}\")\nprint(f\"Valor que retorna la funcion en k: {k},y en l: {l}\")"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/Aquiles735.py",
    "content": "\n\n#  su tipo de dato.\n#  * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n#  *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n#  *      *******(Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)*******\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n#  * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n#  *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n#  *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n#  *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n#  *   Comprueba también que se ha conservado el valor original en las primeras.\n#  */\n\n     # variable x pasa por valor 5 y no por valor numero(10). \ndef punto(x):\n    x = 10\n    print(x)  #imprime 10\nx = 5\npunto(x)\nprint(x)  # imprime: 5\n\n\n\n\n   #variable por referencia \n\ndef modific(lista):\n    lista.append(4)  #la funcion es agregar el 4 a una lista no conocida\n    lista=[5, 6, 7, 8] \n    print(lista)   #no se agregó el \"4\"  [5, 6, 7, 8]\nmi_lista = [5, 6, 7, 8]\nmodific(mi_lista)  #aqui se agrega el 4 a mi_lista,la funcion viene de la definicion \nprint(mi_lista) # se gregó 4 [5, 6, 7, 8, 4]\nlista=mi_lista\nprint(lista)  # se imprime lista modificada\n\n    ####esituacion donde se aplican variables por valor y por referencia\n\n\ndef negocio(compra=\"Casa\"):\n    print(f\"buscando,{compra} sin dinero\")\n    negocio=10\n    print(negocio)   #Imprime 10\nnegocio()    # imprime \"buscando,Casa sin dinero\"\nnegocio(\"Carro\")  # imprime \"buscando,Carro sin dinero\"\nnegocio(\"nada de nada\")  #imprime \"buscando,nada de nada sin dinero\"\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/Bert008.py",
    "content": "'''\n/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n'''\n# asignacion de variables por valor\na = 10\nbooleano = True\nb = a\nbooleano2 = booleano\nprint(\"a = \", a)\nprint(\"b = \", b)\nprint(\"booleano = \", booleano)\nprint(\"booleano2 = \", booleano2)\n\n# adignacion de variables por referencia, solo para estructuras en python\nlista = [1, 2, 3, 4, 5]\na, b, c, d, e = lista\na = lista[0]\nb = lista[1]\nc = lista[2]\nd = lista[3]\ne = lista[4]\n\nabcde = [a, b, c, d, e]\nfor i in abcde:\n    print(i)\n\n# asignacion por valores y referencias en funciones\ndef suma(x, y):\n    return x + y\n\nx = 2\ny = 5\n\nprint(\"suma\", suma(x, y))\n\ndef listas(lista):\n    lista.append(len(lista) + 1)\n    return lista\n\nlista = [1, 2, 3, 4, 5]\nprint(listas(lista))\n\n# dificultad extra\n\ndef xyyx(x, y):\n    return y, x\n\nx = 1\ny = 2\nprint(\"valores originales \", (x, y))\nprint(\"valores cambiados: \", xyyx(x, y))\n\ndef referencias(ref1, ref2):\n    ref1[:], ref2[:] = ref2[:], ref1[:]\n    return ref1, ref2\nx = [1, 2]\ny = [3, 4]\nprint(\"original: \",x, y)\nx, y = referencias(x, y)\nprint(\"Cambio: \", x, y)"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/BrianSilvero.py",
    "content": "\"\"\"\nValor y referencia\n\"\"\"\n\n# Tipo de datos por valor\n\nmy_int_a = 10\nmy_int_b = my_int_a\nmy_int_b = 20\nmy_int_a = 30\nprint(my_int_a)\nprint(my_int_b)\n\n# Tipo de datos por referencia\nmy_list_a = [10, 20]\nmy_list_b = my_list_a\nmy_list_b.append(30)\nprint(my_list_a)\nprint(my_list_b)\n\n\n# Funciones con datos de valor \n\ndef my_int_func(my_int: int):\n    my_int = 20\n    print(my_int)\n\nmy_int_c = 10\nmy_int_func(my_int_c)\nprint(my_int_c)\n\n# Funciones con datos de referencia\ndef my_list_func(my_list: list):\n    my_list.append(30)\n    \n    my_list_d = my_list\n    my_list_d.append(40)\n    \n    print(my_list)\n    print(my_list_d)\n\nmy_list_c = [10, 20]\nmy_list_func(my_list_c)\nprint(my_list_c)\n\n\n\"\"\"\nExtra\n\"\"\"\n\n# Por valor\n\ndef value(value_a:int , value_b:int) -> tuple:\n    temp = value_a\n    value_a = value_b\n    value_b = temp\n    \n    return value_a, value_b\n\nmy_int_d = 10\nmy_int_e = 20\nmy_int_f, my_int_g = value(my_int_d, my_int_e)\n\nprint(f\"{my_int_d}, {my_int_e}\")\nprint(f\"{my_int_f}, {my_int_g}\")\n\n# Por referencia \n\ndef ref(value_a:list , value_b:list) -> tuple:\n    temp = value_a\n    value_a = value_b\n    value_b = temp\n    \n    return value_a, value_b\n\nmy_list_d = [10, 20]\nmy_list_e = [30, 40]\nmy_list_f, my_list_g = value(my_list_d, my_list_e)\n\nprint(f\"{my_list_d}, {my_list_e}\")\nprint(f\"{my_list_f}, {my_list_g}\")\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/C-Gabs.py",
    "content": "#Reto 05\n\n'''Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como\n * variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime\n *   el valor de las variables originales y las nuevas, comprobando que se ha invertido\n *   su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.'''\n\n#Variables por valor\n\n#Enteros\nnumero_1 = 1\nnumero_2 = 2\nprint(f\"numero_1: {numero_1} numero_2: {numero_2}\")\nnumero_2 = numero_1\nprint(f\"numero_1: {numero_1} numero_2: {numero_2}\")\nnumero_1 = 3\nprint(f\"numero_1: {numero_1} numero_2: {numero_2}\")\nprint()\n\n#Float\nnumero_1 = 1.5\nnumero_2 = 2.5\nprint(f\"numero_1: {numero_1} numero_2: {numero_2}\")\nnumero_2 = numero_1\nprint(f\"numero_1: {numero_1} numero_2: {numero_2}\")\nnumero_1 = 3.5\nprint(f\"numero_1: {numero_1} numero_2: {numero_2}\")\nprint()\n\n#Cadenas\ncadena_1 = \"python\"\ncadena_2 = \"Swift\"\nprint(f\"cadena_1: {cadena_1} cadena_2: {cadena_2}\")\ncadena_2 = cadena_1\nprint(f\"cadena_1: {cadena_1} cadena_2: {cadena_2}\")\ncadena_1 = \"Kotlin\"\nprint(f\"cadena_1: {cadena_1} cadena_2: {cadena_2}\")\nprint()\n\n#Boolean\nverdadero = True\nfalso = False\nprint(f\"Verdadero: {verdadero} Falso: {falso}\")\nfalso = verdadero\nprint(f\"Verdadero: {verdadero} Falso: {falso}\")\nprint()\n\n#Variables por referencia \n\n#Listas\nlista_1 = [\"Python\",\"Kotlin\",\"Java\"]\nlista_2 = [\"SQL\",\"Pandas\",\"Numpy\"]\nprint(f\"lista_1: {lista_1} lista_2: {lista_2}\")\nlista_2 = lista_1 \nprint(f\"lista_1: {lista_1} lista_2: {lista_2}\")\nlista_2.append([\"HTML\",\"JavaScrip\"])\nprint(f\"lista_1: {lista_1} lista_2: {lista_2}\")\nprint()\n\n#Sets\nset_1 = {1,2,3}\nset_2 = {4,5,6}\nprint(f\"set_1: {set_1} set_2: {set_2}\")\nset_2 = set_1 \nprint(f\"set_1: {set_1} set_2: {set_2}\")\nset_2.update({7,8,9})\nprint(f\"set_1: {set_1} set_2: {set_2}\")\nprint()\n\n#Diccionarios\ndict_1 = {\"Nombre\":\"Brais\",\"Lenguaje\":\"Kotlin\"}\ndict_2 = {\"Nombre\":\"C-Gabs\",\"Lenguaje\":\"Python\"}\nprint(f\"dict_1: {dict_1} dict_2: {dict_2}\")\ndict_2 = dict_1\nprint(f\"dict_1: {dict_1} dict_2: {dict_2}\")\ndict_2.update({\"Librerias\":[\"Numpy\",\"Pandas\"]})\nprint(f\"dict_1: {dict_1} dict_2: {dict_2}\")\nprint()\n\n#Función con variables por valor\nnumero_int = 1\nnumero_float = 1.5\nstring = \"Hola Python\"\nboolean = True\nprint(f\"numero_int: {numero_int} numero_float: {numero_float} string: {string} boolean: {boolean}\")\n\ndef var_por_valor(numero_1, numero_2, cadena, bool):\n    numero_1 = 1+2\n    numero_2 = 1.5*2\n    cadena = \"Hola Mundo\"\n    bool = False\n    print(f\"numero_1: {numero_1}, numero_2: {numero_2}, cadena: {cadena}, bool: {bool}\")\n\nvar_por_valor(numero_int, numero_float, string, boolean)\nprint(f\"numero_int: {numero_int} numero_float: {numero_float} string: {string} boolean: {boolean}\")\nprint()\n\n#Funvión con variables por referencia\nlista = [1,2,3]\ndict = {\"Nombre\":\"C-Gabs\",\"Edad\":24,\"Lenguaje\":\"Python\"}\nset = {\"SQL\",\"Numpy\"}\nprint(f\"lista: {lista} dict: {dict} set: {set}\")\n\n\ndef var_por_ref(lista_num,dict_datos,set_elem):\n    lista_num.append([4,5,6])\n    dict_datos.update({\"Nombre\":\"Brais\",\"Apellido\":\"Moure\",\"Lenguajes\":[\"Swift\",\"Kotlin\"]})\n    set_elem.add(\"Pandas\")\n    print(f\"lista_num: {lista_num}, dict_datos: {dict_datos}, set_elem: {set_elem}\")\n\nvar_por_ref(lista, dict, set)\nprint(f\"lista: {lista} dict: {dict} set: {set}\")\nprint()\n\n#Reto extra\n\nvalor_1 = 5\nvalor_2 = 7\n\ndef por_valor(parametro_1,parametro_2):\n    parametro_1, parametro_2 = parametro_2, parametro_1\n    return parametro_1, parametro_2\n\nvalor_3, valor_4 = por_valor(valor_1,valor_2)\nprint(f\"Valor_1: {valor_1}, valor_2: {valor_2}\")\nprint(f\"Valor_3: {valor_3}, valor_4: {valor_4}\")\n\nref_1 = [1,2,3]\nref_2 = [4,5,6]\n\ndef por_ref(parametro_1,parametro_2):\n    parametro_1, parametro_2 = parametro_2, parametro_1\n    return parametro_1, parametro_2\n\nref_3, ref_4 = por_ref(ref_1,ref_2)\nprint(f\"Ref_1: {ref_1}, ref_2: {ref_2}\")\nprint(f\"Ref_3: {ref_3}, ref_4: {ref_4}\")\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/CaveroBrandon.py",
    "content": "\"\"\"\n- Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según su tipo de dato.\n- Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \"por referencia\",\n y cómo se comportan en cada caso en el momento de ser modificadas\n\"\"\"\n\n\ndef assigning_by_value():\n    print('**** Assigning by value ****')\n    message = 'Hello'\n    greetings = message\n    message = 'New message'\n\n    print('Message:', message)\n    print('Greetings:', greetings)\n    print('Greetings is not affected by the change in message because both values are assigned by value')\n\n\ndef assigning_by_reference():\n    print('\\n**** Assigning by reference ****')\n    list_numbers = [1, 2, 3]\n    second_list_numbers = list_numbers\n    list_numbers.append(4)\n\n    print('List_numbers:', list_numbers)\n    print('Second_list_numbers:', second_list_numbers)\n    print('Both list are affected by the change in the first list because the value is assigned by reference')\n\n\ndef function_with_argument_assigned_by_value(value1):\n    print('\\n**** Function with assignment by value ****')\n    print(\"Value previous to modification:\", value1)\n    value1 = 42\n    print(\"Value after the modification, in the function:\", value1)\n\n\ndef function_with_argument_assigned_by_reference(list1):\n    print('\\n**** Function with assignment by reference ****')\n    print(\"List previous to modification:\", list1)\n    list1.append(4)\n    print(\"List after the modification, in the function:\", list1)\n\n\ndef function_that_exchanges_values_by_value(value1, value2):\n    new_value_1 = value2\n    new_value_2 = value1\n\n    return new_value_1, new_value_2\n\n\ndef function_that_exchanges_values_by_reference(list1, list2):\n    temp_list = list1\n    new_list_1 = list2\n    new_list_2 = temp_list\n\n    return new_list_1, new_list_2\n\n\nassigning_by_value()\nassigning_by_reference()\n\nnumber = 10\nfunction_with_argument_assigned_by_value(number)\nprint(\"Original value after executing the function:\", number)\n\nnumber_list = [1, 2, 3]\nfunction_with_argument_assigned_by_reference(number_list)\nprint(\"Original list after executing the function:\", number_list)\n\n\n\"\"\" * DIFICULTAD EXTRA (opcional):\n- Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n- Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n- Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno se asigna a dos variables diferentes a las originales. \nA continuación, imprime el valor de las variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas. \n- Comprueba también que se ha conservado el valor original en las primeras.\n\"\"\"\n\nvalue1 = 10\nvalue2 = 20\n\nnew_value_1, new_value_2 = function_that_exchanges_values_by_value(value1, value2)\nprint(f\"\\nThe original values are: value_1 = {value1} and value_2 = {value2}\")\nprint(f\"The exchanged values are value_1 = {new_value_1} and value_2 = {new_value_2}\")\n\n\nlist1 = [1, 2, 3, 4]\nlist2 = [5, 6, 7]\nnew_list_1, new_list_2 = function_that_exchanges_values_by_reference(list1, list2)\nprint(f\"\\nThe original list are: list_1 = {list1} and value_2 = {list2}\")\nprint(f\"The exchanged values are list_1 = {new_list_1} and value_2 = {new_list_2}\")\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/CesarCarmona30.py",
    "content": "'''\n  VALOR Y REFERENCIA\n'''\n\n# Datos por valor\n\nvalue_x = 5\nvalue_y = value_x\nvalue_y += 15\n\nprint(value_x)\nprint(value_y)\n\n\n# Datos por referencia\n\nmy_dict_a = {\n  'Mexico': 'Mexico City',\n  'Spain': 'Madrid',\n  'Chile': 'Santiago',\n  'Argentina': 'Buenos Aires'\n}\n\nmy_dict_b = my_dict_a\nmy_dict_b['France'] = 'Paris'\nprint(my_dict_a)\nprint(my_dict_b)\n\n\n# Función con dato por valor\n\ndef modify_val(value_a):\n  value_a = 'valor modificado'\n  print(value_a)\n\nvalue_b = 'valor inicial'\nprint(value_b)\nmodify_val(value_b)\nprint(value_b)\n\n\n# Función con dato por referencia\n\ndef modify_ref(ref_j):\n  ref_j['dato'] = 'dato modificado'\n  print(ref_j)\n\nref_x = {\n  'dato': 'dato inicial',\n  'lenguaje': 'python'\n}\nprint(ref_x)\nmodify_ref(ref_x)\nprint(ref_x)\n\n'''\n  EXTRA\n'''\n\n# Valor\n\ndef replace_val(value_x, value_y):\n  aux = value_x\n  value_x = value_y\n  value_y = aux\n  return value_x, value_y\n\nname = 'César'\nlastname = 'Carmona'\nname_rep, lastname_rep = replace_val(name, lastname)\nprint(f'Name: {name}, Lastname: {lastname}')\nprint(f'Name replaced: {name_rep}, lastname replaced: {lastname_rep}')\n\n# Referencia\n\ndef replace_ref(reference_x, reference_y):\n  aux = reference_x\n  reference_x = reference_y\n  reference_y = aux\n  return reference_x, reference_y\n\nfruits = ['apple', 'orange', 'banana', 'grape']\nvegetables = ['tomato', 'carrot', 'onion', 'radish']\n\nfruits_rep, vegetables_rep = replace_ref(fruits, vegetables)\n\nprint(f'Vegetables: {vegetables}')\nprint(f'Fruits: {fruits}')\nprint(f'Vegetables replaced: {vegetables_rep}')\nprint(f'Fruits replaced: {fruits_rep}')"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/Chrisdev00.py",
    "content": "\"\"\"\n* EJERCICIO:\n* - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n*   su tipo de dato.\n* - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n*   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n* (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n*\n* DIFICULTAD EXTRA (opcional):\n* Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n* - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n*   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n*   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n*   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n*   Comprueba también que se ha conservado el valor original en las primeras.\n*\n\"\"\"\n\n\n###########################  Asignacion por Valor  ###############################\n\n# Tipos de datos inmutables(por ejemplo, enteros, flotantes, cadenas, tuplas):\n\n# Asignación por valor para enteros\nx = 5\ny = x\ny = 10\nprint(x)  # Salida: 5\n\n# Asignación por valor para flotantes\nx = 3.5\ny = x\ny = 5.6\nprint(x)  # Salida: 3.5\n\n# Asignación por valor para cadenas\ncadena_1 = \"Hola\"\ncadena_2 = cadena_1\ncadena_2 = \"Hola Mundo\"\nprint(cadena_1)  # Salida: Hola\n\n# Asignación por valor para tuplas\ntupla_1 = (1, 2, 3)\ntupla_2 = tupla_1\ntupla_2 = (4, 5, 6)\nprint(tupla_1)  # Salida: (1, 2, 3)\n\n\n#############################  Asignación por Referencia  ###########################\n\n# Tipos de datos mutables (por ejemplo, listas, diccionarios, conjuntos):\n\n# Asignación por referencia para listas\nlista_1 = [1, 2, 3]\nlista_2 = lista_1\nlista_2.append(4)\nprint(lista_1)  # Salida: [1, 2, 3, 4]\n\n# Asignación por referencia para diccionarios\ndiccionario_1 = {'a': 1, 'b': 2}\ndiccionario_2 = diccionario_1\ndiccionario_2['c'] = 3\nprint(diccionario_1) # Salida: {'a': 1, 'b': 2, 'c': 3}\n\n# Asignación por referencia para conjuntos (set)\nconjunto_1 = {1, 2, 3}\nconjunto_2 = conjunto_1\nconjunto_2.add(4)\nprint(conjunto_1)  # Salida: {1, 2, 3, 4}\n\n\"\"\"\n              Funciones Paso por valor\n\nCuando se pasa una variable inmutable (como enteros, flotantes, cadenas, tuplas) a una función en Python, \nse pasa por valor. Esto significa que se crea una copia local de la variable dentro de la función, \ny cualquier modificación realizada dentro de la función no afectará a la variable original fuera de la función\n\"\"\"\n\ndef modificar_valor(num):\n    num += 10\n    print(\"Dentro de la función:\", num)\n\nx = 5\nmodificar_valor(x)\nprint(\"Fuera de la función:\", x)  # Salida: Fuera de la función: 5\n\n\n\"\"\"\n             Funciones Paso por Referencia \n\nCuando se pasa una variable mutable (como listas, diccionarios, conjuntos) a una función en Python, \nse pasa por referencia. Esto significa que la función opera directamente sobre la misma variable en memoria, \ny cualquier modificación realizada dentro de la función afectará a la variable original fuera de la función\n\"\"\"\n\ndef change_list(lista):\n    lista.append(5)\n    print(\"Dentro de la función:\", lista)\n\nmi_lista = [1, 2, 3, 4]\nchange_list(mi_lista)\nprint(\"Fuera de la función:\", mi_lista)  # Salida: Fuera de la función: [1, 2, 3, 4, 5]\n\nprint(\"\\n\")\n\n\n\n\"\"\"\n######------------------ Dificultad Extra------------------------ ##########\n\"\"\"\n\nprint(\"Funcion con Parametros por valor\")\n\ndef value_exchange(a, b):\n    # Intercambio de valores sin usar una variable temporal\n    a, b = b, a\n    return a, b\n\nx = 5\ny = 10\n\nprint(\"Antes del intercambio:\")\nprint(\"x =\", x)\nprint(\"y =\", y)\n\nx, y = value_exchange(x, y)\n\nprint(\"Después del intercambio:\")\nprint(\"x =\", x)\nprint(\"y =\", y)\n\nprint(\"\\n\")\nprint(\"Funcion con Parametros por Referencia\")\n\ndef reference_exchange(lista1, lista2):\n    # Verificar que ambas listas tengan exactamente tres elementos\n    if len(lista1) == len(lista2) == 3:\n        # Intercambiar los valores de las listas usando una lista temporal\n        lista_temporal = lista1[:]\n        lista1[:] = lista2\n        lista2[:] = lista_temporal\n    else:\n        raise ValueError(\"Ambas listas deben tener exactamente tres elementos.\")\n\nlista_a = [1, 2, 3]\nlista_b = [4, 5, 6]\n\n# Imprimir valores originales\nprint(\"Valores originales:\")\nprint(\"lista_a =\", lista_a)\nprint(\"lista_b =\", lista_b)\n\n# Intercambiar valores de las listas\nreference_exchange(lista_a, lista_b)\n\n# Imprimir nuevos valores\nprint(\"\\nNuevos valores:\")\nprint(\"lista_a =\", lista_a)\nprint(\"lista_b =\", lista_b)\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/Complex303.py",
    "content": "\"\"\"\nValor y Referencia\n\"\"\"\n\n#Tipo de dato por valor: Cuando copias el valor de una variable en otra. Si cambias una, la otra no se afecta. int, float, bool, str, tuple\n\na = 20\nb = 25\n#b = a\na = b\nprint(a)\nprint(b)\n\n\n\n#tipo de dato por referencia: Cuando dos variables apuntan al mismo objeto en memoria. Si cambias una, la otra también se ve afectada. list, dict, set, bytearray\n\nmy_list_a = [2,4,6]\nmy_list_b = [1,3,5]\nmy_list_b = my_list_a\nmy_list_b.append(7) #tambien se inserta en la lista a\nprint(my_list_a)\nprint(my_list_b)\n\n\n#Funciones con datos por valor\n\n\ndef my_int_funcion(my_int: int):\n    # Dentro de la función, le asignamos a my_int el valor 10\n    # Pero como los enteros son **inmutables**, esto solo cambia la copia local, no la variable original\n    my_int = 10\n    # Mostramos el valor de my_int dentro de la función (que es 10)\n    print(my_int)\n    \nmt_int_c = 20\n# Llamamos a la función y le pasamos mt_int_c\n# Como los enteros son **inmutables**, se pasa solo una copia de su valor\nmy_int_funcion(mt_int_c)\n\n# Mostramos el valor de mt_int_c fuera de la función\n# Sigue siendo 20 porque la función no puede modificar el entero original\nprint(mt_int_c)\n\n\n#Funciones con datos por referencia\n\n# Definimos una función llamada my_list_funcion que recibe un parámetro my_list (que debe ser de tipo lista)\ndef my_list_funcion(my_list: list):\n    # Dentro de la función, agregamos (append) el número 8 a esa lista\n    my_list.append(8)\n    # Mostramos en pantalla cómo quedó la lista después de agregar el 8\n    print(my_list)\n\n# Creamos una lista llamada my_list_c con los valores 2, 4 y 6\nmy_list_c = [2, 4, 6]\n\n# Llamamos a la función y le pasamos nuestra lista my_list_c\n# Como las listas son **mutables**, cualquier cambio dentro de la función afectará también a la lista original\nmy_list_funcion(my_list_c)\n\n# Volvemos a mostrar en pantalla la lista my_list_c\n# Verás que también tiene el 8, porque la función modificó la lista original (ya que se pasa por referencia)\nprint(my_list_c)\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\"\"\"\n\n\n#POR VALOR\n\n# Definimos una función llamada intercambio_value que recibe dos enteros: value1 y value2\ndef intercambio_value(value1: int, value2: int):\n    # Guardamos el valor de value1 en una variable temporal llamada temp\n    temp = value1\n    # Ahora asignamos a value1 el valor de value2\n    value1 = value2\n    # Y a value2 le asignamos el valor guardado en temp (que era el valor original de value1)\n    value2 = temp\n    # Retornamos los dos valores intercambiados\n    return value1, value2\n\n# Creamos dos variables con los valores 50 y 100\nmy_value1 = 50\nmy_value2 = 100\n\n# Llamamos a la función intercambio_value pasando esas dos variables\n# El resultado (que son los valores intercambiados) se guarda en my_value3 y my_value4\nmy_value3, my_value4 = intercambio_value(my_value1, my_value2)\n\n# Imprimimos los valores originales.\nprint(f'{my_value1}, {my_value2}')  # → 50, 100\n\n# Imprimimos los valores intercambiados que devolvió la función\nprint(f'{my_value3}, {my_value4}')  # → 100, 50\n\n\n\n\n#Por referencia\ndef intercambio_referencia(value1: list, value2: list):\n    temp = value1\n    value1 = value2\n    value2 =  temp\n    return value1, value2\n\nmy_lista1 = [50,60,70]\nmy_lista2 = [80,90,100]\n\n# Llamamos a la función y guardamos el resultado (las listas intercambiadas) en my_lista3 y my_lista4\nmy_lista3, my_lista4 = intercambio_referencia(my_lista1, my_lista2)\n\n# Imprimimos las listas originales\n# → Salen igual que al principio porque en la función solo se intercambiaron las REFERENCIAS LOCALES\n#   value1 y value2 apuntaban a las listas, pero no modificaron el contenido ni cambiaron los apuntadores afuera\nprint(f'{my_lista1}, {my_lista2}')\n\n# Imprimimos las listas intercambiadas que devolvió la función\n# → Estas sí muestran las referencias intercambiadas\nprint(f'{my_lista3}, {my_lista4}')"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/D3rk1us.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n \"\"\"\n\n# Asignación de variables \"por valor\"\nsuma = 1 + 40\nmultiplicacion = 20 * 17\n\n# Asignación de variables \"por referencia\".\n\ndef descuentoAplicado(precio):\n    return precio - (precio * 10 / 100)\n\nprecio = 100\n\nprecio_total = descuentoAplicado(precio)\n\nprint(precio_total)\n\n# Asignación de variables según tipo de dato.\n\ncadena = \"Esto es una cadena\"\nnum = 20\nflotante =  43.0\nbooleano = False\n\n# Funciones con variables que se les pasan \"por valor\" y \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n\ndef porValor(num):\n    num * 2\n\nnum = porValor(num)\nprint(num)\n\nlistado = ['Rojo', 'Verde', 'Amarillo', 'Blanco', 'Negro']\n\n# Por referencia\ndef porReferencia(listado):\n    listado.append('Naranja')\n\nporReferencia(listado)\nprint(listado)\n\n# /////////////////////////////////////  DIFICULTAD EXTRA (opcional)  /////////////////////////////////////\n\nparam1 = \"Primer parametro\"\nparam2 = \"Segundo parametro\"\n\nparam_ref1 = ['arroz', 'manzana', 'pollo']\nparam_ref2 = ['destornillador', 'taladro', 'martillo']\n\ndef programa1(valor1, valor2):\n    valor_cambio = valor2\n    valor2 = valor1\n    valor1 = valor_cambio\n\n    return valor1, valor2\n\ndef programa2(ref1, ref2):\n    ref_cambio = ref2\n    ref2 = ref1\n    ref1 = ref_cambio\n\n    return ref1, ref2\n\n\nresultado1 = programa1(param1, param2)\nresultado2 = programa2(param_ref1, param_ref2)\n\nprint(f\"Sin cambio: \\nParametro 1 = {param1} \\nParametro 2 = {param2}\")\nprint(f\"Con cambio: \\nParametro 1 = {resultado1[0]} \\nParametro 2 = {resultado1[1]}\\n\")\n\nprint(f\"Sin cambio: \\nParametro 1 = {param_ref1} \\nParametro 2 = {param_ref2}\")\nprint(f\"Con cambio: \\nParametro 1 = {resultado2[0]} \\nParametro 2 = {resultado2[1]}\")"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/DGrex.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n\"\"\"\n\n### Tipos de datos por valor y referencia ###\n\n# Por valor\n\nnumber_one = 15\nnumber_two = number_one\nprint(f\"number_one: {number_one}\")\nprint(f\"number_two: {number_two}\")\n\nnumber_one = 20 \nprint(f\"number_one: {number_one}\")\nprint(f\"number_two: {number_two}\")\n\nnumber_two = 100 \nprint(f\"number_one: {number_one}\")\nprint(f\"number_two: {number_two}\")\n\n\"\"\"\nLa asignación por valor se refiere al manejo de objetos inmutables, \ncomo números, cadenas y tuplas. Al cambiar el valor de una variable, \nse genera un nuevo objeto en lugar de modificar el objeto original.\n\"\"\"\n\n# Por referencia\n\nmy_list = [15,20,50,100]\nmy_list_copy = my_list\nprint(f\"my_list:      {my_list}\")\nprint(f\"my_list_copy: {my_list_copy}\")\n\nmy_list_copy.append(80)\nprint(f\"my_list:      {my_list}\")\nprint(f\"my_list_copy: {my_list_copy}\")\n\n\"\"\"\nLa asignación por referencia se refiere a la forma en que se manejan\nlos objetos mutables, como listas y diccionarios. Cuando se modifica un objeto\na través de una referencia, dichos cambios afectan a todas las referencias\nque apuntan al mismo objeto.\n\"\"\"\n\n### Funciones con datos por valor y referencia ###\n\n# Por valor\n\ndef funcion_por_valor(number):\n    num_two = 75\n    print(f\"num_two: {num_two}\")\n\nnum_one = 50\nfuncion_por_valor(number_one)\nprint(f\"num_one: {num_one}\")\n\n# Por referencia\n\nmy_list_one = [10,50,60]\n\ndef funcion_por_referencia(list):\n    my_list_two = list \n    my_list_two.append(95)\n    print(f\"my_list_two: {my_list_two}\")\n\nfuncion_por_referencia(my_list_one)\nprint(f\"my_list_one: {my_list_one}\")\n\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como\n * variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime\n *   el valor de las variables originales y las nuevas, comprobando que se ha invertido\n *   su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n\"\"\"\n\n# Por valor\n\ndef por_valor(num_a,num_b):\n    temporary = num_a\n    num_a = num_b\n    num_b = temporary\n    return num_a, num_b\n\nnum_a = 20\nnum_b = 60\nnum_c, num_d = por_valor(num_a,num_b)\n\nprint(num_a, num_b)\nprint(num_c, num_d)\n\n\n# Por referencia\n\ndef por_referencia(list_a, list_b):\n    temporary = list_a\n    list_a = list_b\n    #list_a.append(80)\n    list_b = temporary\n    return list_a, list_b\n\nlist_a = [20, 30, 40]\nlist_b = [50, 60, 70]\nlist_c, list_d = por_referencia(list_a, list_b)\n\nprint(list_a, list_b)\nprint(list_c, list_d)\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/DaniQB99.py",
    "content": "\"\"\"\nEJERCICIO:\n  - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n    su tipo de dato.\n  - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n    \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n(Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n \n\"\"\"\n\n# VARIABLES POR VALOR (inmutables)\nn1 = 10\nn2 = n1 # n2 obtiene el valor de n1 pero en distinta dirreccion de memoria\nn1 = 20\nprint(n1)\nprint(n2)\n\n# VARIABLES POR REFERENCIA\nlist1 = [10, 20]\nlist2 = list1 # la list2 obtiene la misma direccion de memoria de la list1\nlist2.append(40)\nprint(list1) \nprint(list2)\n\n# FUNCIONES CON DATOS POR VALOR\nmy_int_a = 30\n\ndef int_func(my_int: int):\n    my_int = 10\n    print(my_int)\n\nint_func(my_int_a)\nprint(my_int_a)\n\n# FUNCIONES CON DATOS POR REFERENCIA\nimport copy\nmy_list_b = [10, 20]\n\ndef list_func(my_list: list):\n    my_list.append(30)\n    my_list_copy = copy.copy(my_list) # Manera de copiar los valores del objeto sin mutar el objeto original\n    my_list_c = my_list\n    my_list_c.append(40)\n\n    print(my_list_c)\n    print(my_list)\n    print(my_list_copy) # Lista copiada sin mutar\n\n\nlist_func(my_list_b)\nprint(my_list_b)\n\n\"\"\"\nEJERCICIO EXTRA:\nCrea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n- Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n  Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n  se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n  variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n  Comprueba también que se ha conservado el valor original en las primeras.\n\"\"\"\n\nprint('\\n--- EJERCICIO EXTRA ---\\n')\n\n# VARIABLES POR VALOR\nmy_int_a = 30\nmy_int_b = 40\n\ndef func1(value_a: int, value_b: int) -> tuple:\n    value_temp = value_a\n    value_a = value_b\n    value_b = value_temp\n    return value_a, value_b\n\nmy_int_c, my_int_d = func1(my_int_a, my_int_b)\nprint(f\"Valores originales: {my_int_a}, {my_int_b}\")\nprint(f\"Valores invertidos: {my_int_c}, {my_int_d}\")\n\n# VARIABLES POR REFERENCIA\nmy_list_a = [10, 20]\nmy_list_b = [30, 40]\n\ndef func1(value_a: list, value_b: list) -> tuple:\n    value_temp = value_a # value_temp recibe el puntero de memoria de value_a \n    value_a = value_b # value_a recibe el puntero de memoria de value_b\n    value_b = value_temp # value_b recibe el puntero de memoria de value_temp, que es el original de value_a\n    return value_a, value_b\n\nmy_list_c, my_list_d = func1(my_list_a, my_list_b)\nprint(f\"Valores originales: {my_list_a}, {my_list_b}\")\nprint(f\"Valores invertidos: {my_list_c}, {my_list_d}\")\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/Daparradom.py",
    "content": "### VALOR Y REFERENCIA ###\n\nnum_1 = 20 \nnum_2 = num_1 #Parametro por valor\n\nnombres = [\"Ana\", \"Julio\" , \"David\"] #Parametros por referencia\n\nprint(num_2) \nprint(num_1) \nprint(nombres)\n\nnum_1 = 1.5\nnombres[0] = \"Luis\"\n\n\n\nprint(num_2) #mantiene su valor inicial\nprint(num_1) \nprint(nombres) #se modifica\n\ndef saludo(mensaje, nombres) :\n    mensaje = mensaje.upper() #Modificando la variable\n    nombres[0] = nombres[0].upper() #Modificando la lista\n    res = \"\"\n    for nombre in nombres :\n        res += f'{mensaje} {nombre} \\n'\n    return print(res)\n\nusuarios = [\"Ana\", \"Julio\" , \"David\", \"Leonor\"]\nmensaje = \"Hola que hace\"\nprint (mensaje)\nprint (usuarios)\n\nsaludo(mensaje, usuarios) \n\nprint (mensaje) #Dado que es una variable por valor no se modifica, mantiene su valor original\nprint (usuarios) #Al igual que la anterior, se modifica en la funcion y al ser una variable por referencia se modifica\n\ndef var_valor(v_1:int,v_2:int):\n    temp = v_1\n    v_1 = v_2  #Bloque de intercambio de variables por valor\n    v_2 = temp\n    print(v_1)\n    print(v_2)\n    return v_1 ,  v_2\ndef var_referencia(lista:list):\n    print (lista[0])\n    print (lista[1])\n    lista[0], lista[1] = lista[1], lista [0]  # Intercambio variables por referencia\n    return lista [0] , lista[1] \n\nv_3, v_4 = var_valor(2,4)\nprint (v_3)\nprint (v_4)\nprint(\"------------------------------\")\nl_1, l_2 = var_referencia([2,4])\n\nprint(l_1)\nprint(l_2)"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/DataCiriano.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n\"\"\"\n\n# Tipos de dato por valor \n\nentero_1 = 25\nentero_2 = entero_1 #Cada valor tiene su pososición de memoia independiente, y al igualrse una a la otra esto se mantiene\nentero_2 = 15\nprint(entero_1)\nprint(entero_2)\n\n\n#Tipo de dato por referencia (heredan posición de memoria)\n\nlista_1 = [10,20]\nlista_2 = lista_1 #En el momento en que se igualan, los datos pasan a almacenarse en la misma posición de memoria por eso luego al imprimir lista_1 esta tiene el nuevo elemento añadido a las lista_2 con .append\nlista_2.append(50)\nprint(lista_1)\nprint(lista_2)\n\n\n#Funciones con datos por valor\n\nentero = 10\n\ndef funct_valor(entero: int):\n    entero = 20\n    print(entero)\n    \nfunct_valor(entero)\nprint(entero)\n\n\n#Funciones con datos por referencia\n\nlista = [10,20]\n\ndef funct_referencia(lista: list):\n    lista.append(30)\n    print(lista)\n    \nfunct_referencia(lista)\nprint(lista)\n\n\n#----EXTRA----\n\ndef value(value_a:int, value_b:int) -> tuple:\n    temp = value_a\n    value_a = value_b\n    value_b = temp\n    return value_a, value_b\n\ninteger_01 = 10\ninteger_02 = 20\n\nprint(integer_01, integer_02)\nprint(value(integer_01, integer_02))\n\n\ndef reference(value_a:list, value_b:list) -> tuple:\n    temp = value_a\n    value_a =  value_b\n    value_b = temp\n    return value_a, value_b\n\nlist_01 = [10,20]\nlist_02 = [30,40]\n\nprint(list_01, list_02)\nprint(reference(list_01, list_02))"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/DevKnn.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n \"\"\"\npalabra = \"hola\"\npalabra = palabra.split()\nn1 = 9\ndef index(n1):\n    \n return print(n1+4)\ndef index2(palabra):\n    \n    palabra.append(\"esperando un elemento\")\n    return print(palabra)\n\"\"\"\nprint(n1)\nindex2(palabra)\nprint(palabra)\n\"\"\"\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como\n * variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime\n *   el valor de las variables originales y las nuevas, comprobando que se ha invertido\n *   su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\"\"\"\npalabra1 = \"caiman\"\npalabra2 = \"gorilla\"\n\ndef valor(valor1,valor2):\n    valor1,valor2 = valor2,valor1\n    return valor1,valor2\nnuevaPalabra1,nuevaPalabra2 = valor(palabra1, palabra2)\n\nprint(\"Por valor:\")\nprint(\"Original:\", palabra1, palabra2)\nprint(\"Nuevas:\", nuevaPalabra1, nuevaPalabra2)\n\nlista1 = [\"cocodrilo\"]\nlista2 =[\"pescado\"]\ndef referencia(referencia1,referencia2):\n    referencia1[0],referencia2[0] = referencia2[0],referencia1[0]\n    return referencia1,referencia2\n\nnuevaLista1,nuevaLista2 = referencia(lista1,lista2)\nprint(\"\\nPor referencia:\")\nprint(\"Original:\", lista1, lista2)\nprint(\"Nuevas:\", nuevaLista1, nuevaLista2)"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/DiegoIBB.py",
    "content": "'''\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n '''\n\n'''\nDEFINICIÓN:\nParámetros por referencia y valor, son aquellos parámetros que al entrar en una función se comportan de una determinada\nforma, ya sea creando una copia de una variable y operando sobre ella (por valor) o bien operando directamente sobre el valor\noriginal y modificando la variable (por referencia)\n\nSi bien los objetos que se obtienen en una variable original por referencia y el valor que resulta despues de entrar a una función\nparecieran ser diferentes lo cierto es que son el mismo, ya que comparten la misma dirección en la memoria, esto lo podemos notar si\nusamos la función \"id()\" que nos entrega el valor de memoria de cada objeto\n\n'''\n\n#Las modificaciones de variables pueden variar dependiendo del tipo de dato, estos se dividen en mutables e inmutables\n\n'''\nTipos Mutables: Si permiten ser modificados una vez creados (datos pasados por referencia)\n(Estos tipos de datos el programa interpreta que no vale la pena crear una copia ya que pueden ser\nmuy grandes, por ello se actua directamente sobre la dirección de memoria del elemento)\n\n- Listas\n- Bytearray\n- Diccionarios\n- Conjuntos\n'''\n\n'''\nTipos Inmutables: No permiten ser modificados una vez creados (datos pasados por valor)\n\n- Booleanos\n- Integgers(Enteros)\n- Float(Flotantes)\n- Strings(Cadenas)\n- Tuplas\n- Range\n- Bytes\n'''\n\nprint(\"------- EJEMPLOS DE DATOS POR VALOR ------- \")\n\n# ----> Ejemplo_1: Entero\nprint(\"------- Ejemplo: Entero ------- \")\n#---------------------------------\n\nvalue_1 = 70 #Variable pasada por Valor (tipo de dato Int)\nprint(id(value_1))\nprint(f\"Valor original: {value_1}\") #Variable Original de tipo Integger\n\ndef doouble(intValue):\n    doubleValue = intValue * 2\n    return doubleValue\n\np1 = doouble(value_1)\n\nprint(f\"Copia pasada por función: {p1}\") #Copia local de la variable procesada dentro de la función (aumentada al doble)\n#print(id(p1)) #Dirección en memoria de la copia local\nprint(f\"Valor original(No cambia): {value_1}\")\n#print(id(value_1)) #Dirección en memoria de la variable original\n\n\n# ----> Ejemplo_2: Tuplas (Recordar que para poder modificar tuplas primero debemos transformarlas a listas)\nprint(\"------- Ejemplo: Tupla -------\")\n#---------------------------------\n\ntupla_1 = (\"Hola\", \"Como\", \"Estas\")\n\ndef removeItem(t):\n    list_t = list(t)\n    for e in list_t:\n        if e == \"Hola\":\n            list_t.remove(e)\n    t = tuple(list_t)\n    return t\n\nresultado = removeItem(tupla_1)\n\nprint(f\"Elemento tupla_1 original: {tupla_1}\") # Al tratarse de un dato inmutable el valor original no se modifica\nprint(f\"Elemento tupla_1 modificado en la función: {resultado}\") # Lo que si se modifica es la copia local que pasamos a la función\n\n\n# ----> Ejemplo_3: String\nprint(\"------- Ejemplo: Cadena -------\")\n#---------------------------------\n\nstring_1 = \"Cadena 1\"\n\ndef upperString(s):\n    newString = s.upper()\n    return newString\n\nresultado_s = upperString(string_1)\nprint(f\"Copia pasada por función: {resultado_s}\")\nprint(f\"Valor original (sin modificar): {string_1}\")\n\n\nprint(\"------- EJEMPLOS DE DATOS POR REFERENCIA ------- \")\n\n# ----> Ejemplo_1: Lista\nprint(\"------- Ejemplo: Lista -------\")\n#---------------------------------\n\nlist_1 = [1,3,5,7,9] #Variable pasada por referencia (tipo de dato list)\n\nprint(f\"{list_1} lista sin modificaciones\")\nprint(id(list_1)) #Dirección en la memoria de la lista\n\ndef numbersDoubles(lista):\n    for i in range(len(lista)):\n        itemDouble = lista[i] * 2\n        lista.append(itemDouble)\n    return lista\n\np2 = numbersDoubles(list_1)\n\nprint(list_1) #Lista original, referenciada en la función numbersDoubles -> Al ser pasada por referencia tenemos que el valor original a sido modificado\n\nprint(p2) #Lista final, resultado de la aplicación de métodos en la función -> Este valor es otro \"objeto\" al que se le ha asignado la misma dirección de list_1\nprint(id(p2)) #Dirección en la memoria de la lista pasada por la función es la misma que la de la lista original\n\nprint(type(list_1))\n\n'''\nLas listas al pasar por referencia por una función se modifica el contenido de esta de manera permanente, pero mantiene la misma dirección en la memoria\nque la lista original, las variables antiguas de la lista eventualmente es borrada del programa\n'''\n\n\n# ----> Ejemplo_2: Lista (revisar este ejemplo)\nprint(\"------- Ejemplo: Lista 2 -------\")\n#---------------------------------\n\nlista_2 = [23, 43, 53, 12, 54]\nprint(id(lista_2))\n\ndef deletList(l):\n    l = [] #Con esta linea \"vaciamos la lista\"\n    return l\n\nprint(id(deletList(lista_2)))\n\n\n# ----> Ejemplo_3: Diccionarios\nprint(\"------- Ejemplo: Diccionario -------\")\n#---------------------------------\n\ndiasPorMes = {\n    \"Enero\": 31,\n    \"Febrero\": 29,\n    \"Marzo\": 31,\n    \"Abril\": 30,\n    \"Mayo\": 31,\n    \"Junio\": 30,\n    \"Julio\": 31,\n    \"Agosto\": 31,\n    \"Septiembre\": 30,\n    \"Octubre\": 31,\n    \"Noviembre\": 30,\n    \"Diciembre\": 31\n}\n\nprint(diasPorMes)\nprint(id(diasPorMes)) #Dirección de la variable #1669176227520\n\ndef meses(dictionary):\n    print(id(dictionary)) #Dirección de la variable #1669176227520\n    for i in dictionary:\n        if dictionary[i] == 31:\n            print(f\"{i} tiene 31 días\")\n            #print(f\"{diasPorMes.get(i)} tiene 31 días\")\n        elif dictionary[i] <= 30:\n            print(f\"{i} es el mes más corto\")\n            dictionary.update({\"Febrero\": 0})\n        else:\n            continue\n\nmeses(diasPorMes)\nprint(meses(diasPorMes))\nprint(id(meses(diasPorMes))) #Dirección de memoria del resultado del diccionario pasado por la función ha sido modificada #140710946191352\nprint(id(diasPorMes)) #Dirección de la variable #1669176227520\n\n\n'''\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n '''\n\n#PARAMETROS POR VALOR\n\nvariable_1 = \"cadena\"\nvariable_2 = (23, 43, 12, 54, 65)\n\ndef programa_1(v1, v2):\n    var_aux = v1\n    copia_v1 = v2\n    copia_v2 = var_aux\n    return copia_v1, copia_v2\n\ntest_1 = programa_1(variable_1, variable_2)\nprint(f\"Copia Variable 1 (editada): {test_1[0]}, Variable 1 original: {variable_1}\")\nprint(f\"Copia Variable 2 (editada): {test_1[1]}, Variable 2 original: {variable_2}\")\n\n\n#PARAMETROS POR REFERENCIA\n\nvariable_3 = [23, 43, 15, 31, 12, 32]\nvariable_4 = {\n    \"Lord of the Rings\": 3,\n    \"Harry Potter\": 8,\n    \"Pirates of the Caribean\": 5,\n    \"Transformers\": 7,\n}\n\ndef programa_2(v3, v4):\n    var_aux_2 = v3\n    copia_v3 = v4\n    copia_v4 = var_aux_2\n    return copia_v3, copia_v4\n\ntest_2 = programa_2(variable_3, variable_4)\n\nprint(f\"Variable 3 pasada por referencia: {test_2[0]}, Variable 3 original: {variable_3}\")\nprint(f\"Variable 4 pasada por referencia: {test_2[1]}, Variable 4 original: {variable_4}\")\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/Dkp-Dev.py",
    "content": "\"\"\"\n* EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n\"\"\"\n\n# Tipos de dato por valor\n# Los valores de las variables estan indicados y aunque otra variable copie su valor creara su propia direccion\n\na = 10\nb = a\nb = 20\n\nprint(a)    # Imprime 10\nprint(b)    # Imprime 20 a pesar de que en un punto se le indico que copiara el valor de a\n\n# Tipo de dato por referencia\n\nlist_a = [10,20]\nlist_b = list_a\nlist_b.append(30)\n\nprint(list_a)   # Ambas impresiones tienen el mismo valor [10,20,30]\nprint(list_b)\n\n# Los tipos de dato por referencia no \"adquieren\" valores sino \"heredan\" o \"apuntan\" direcciones, por esto mismo al cambiar el valor b cambia el de a\n\n\n# Funciones con datos por referencia\n\ndef list_func(my_list: list):\n    my_list.append(30)\n\n    list_z = my_list\n    list_z.append(40)\n\n    print(my_list)\n    print(list_z)\n\n\nlist_x = [10,20]\nlist_func(list_x)\nprint(list_x)\n\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como\n * variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime\n *   el valor de las variables originales y las nuevas, comprobando que se ha invertido\n *   su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n\"\"\"\n\n# Por Valor\n\ndef box(var1: int, var2: int) -> tuple:\n    var_t = var1\n    var1 = var2\n    var2 = var_t\n    return var1, var2\n\nvar_x = 10\nvar_z = 20\nvar_r, var_s = box(var_x,var_z)\n\nprint(f\"X es {var_x} y Z es {var_z}\")\nprint(f\"R es {var_r} y S es {var_s}\")\n\n# Por referencia\n\ndef chest(var1: list, var2: list) -> tuple:\n    var_t = var1\n    var1 = var2\n    var2 = var_t\n    return var1, var2\n\nlist_x = [10,20]\nlist_z = [30,40]\nlist_r, list_s = chest(list_x,list_z)\n\nprint(f\"X es {list_x} y Z es {list_z}\")\nprint(f\"R es {list_r} y S es {list_s}\")\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/EliasBonnin.py",
    "content": "# Ejercicio 05\n# En el siguiente URL https:/python.org Tenemos la documentacion de phyton.\n# Los retos se encuentran en https://retosdeprogramacion.com\n\n\n# Por valor\n\na = 10\nb = a\nb += 5\n\nprint(a)  # B tiene la misma copia de valor de A pero no hace referencia a su valor A no CAMBIA\nprint(b)  # Esto significa que no es un valor por referencia sino valor de copia\n\nlista_noref = [1, 2, 3]\nlista_noref2 = lista_noref.copy()  # Podemos asignar sin necesidad de referencias haciendo una COPIA\n\nlista_noref2.append(4)\nprint(lista_noref)\n\n\ndef funcion_sumar(valor):\n    valor += 5\n    print(\"Valor adentro\", valor)\n\n\npor_valor = 14\nfuncion_sumar(por_valor)\nprint(\"Valor afuera\", por_valor)  # Vemos como en la funcion no se modifica el valor original\n\n# Por referencia\n\n\nlista_ref = [1, 2, 3]\nlista_ref2 = lista_ref  # Asignamos por referencia\n\nlista_ref2.remove(3)\nprint(lista_ref)  # Estamos cambiando la lista 2 pero el cambio se ve reflejado en la lista 1.\n\n\ndef lista_referencia(lst):  # La funcion modifica el objetio recibido ORIGINAL\n    lst.append(\"Funcion\")\n    print(\"dentro\", lst)\n\n\nmi_lista = [1, 2, 3]\nlista_referencia(mi_lista)\nprint(\"Fuera, \", mi_lista)\n\n\n# Extra\n\n# Variables\n\nvar_ref = 5\nvar_ref2 = 10\nvar_fun = 0\nvar_fun2 = 0\n\nlist_ref = [1, 2, 3]\nlist_ref2 = [1, 2, 3, 4]\nlist_fun = 0\nlist_fun2 = 0\n\n# Programa1\n\n\ndef Programa1(var1, var2):\n    temp = var1\n    var1 = var2\n    var2 = temp\n    return (var1, var2)\n\n\nvar_fun, var_fun2 = Programa1(var_ref, var_ref2)\nprint(f\"Valor Original {var_ref}, {var_ref2}\")\nprint(f\"Valor Funcion {var_fun}, {var_fun2} \\n\")\n\n# Programa2\n\n\ndef Programa2(var3, var4):\n    temp = var3\n    var3 = var4\n    var4 = temp\n    return (var3, var4)\n\n\nlist_fun, list_fun2 = Programa2(list_ref, list_ref2)\nprint(f\"Referencia Original {list_ref}, {list_ref2}\")\nprint(f\"Referencia Funcion {list_fun}, {list_fun2}\")\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/EmmanuelMMontesinos.py",
    "content": "\"\"\"\n * EJERCICIO:\n * X Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * X Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)   \n\"\"\"\n\n# Varible por valor // El original no cambia\nnumero = 10\ncopia_numero = numero\ncopia_numero = 20\n\nprint(f\"Original: {numero}\")\nprint(f\"Copia: {copia_numero}\")\n\n# variable por referencia // El original cambia dado que es una referencia\nnumeros = [1,2,3,4]\nreferencia = numeros\nreferencia[1] = 999\n\nprint(f\"Original: {numeros}\")\nprint(f\"Referencia: {referencia}\")\n\n# Funciones por valor\ndef duplica(numero):\n    numero *= 2\n    print(f\"Función: {numero}\")\n    \nnumero = 10\n\nprint(f\"Original antes de la función: {numero}\")\nduplica(numero)\nprint(f\"Original despues de la función: {numero}\")\n\n# Funciones por referencia\ndef add_numero(lista):\n    lista.append(5)\n    print(f\"Función: {lista}\")\n    \nlista = [1,2,3,4]\n\nprint(f\"Original: {lista}\")\nadd_numero(lista)\nprint(f\"Original despues de la función: {lista}\")\n\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n\"\"\"\n\ndef progam_valor(param1,param2):\n    param2, param1 = param1, param2\n    return param1, param2\n\ndef program_ref(lista,lista2):\n    lista2,lista = lista,lista2\n    return lista,lista2\n\nparam_1 = 1\nparam_2 = 2\n\nprint(f\"Param_1 antes: {param_1}\")\nprint(f\"Param_2 antes: {param_2}\")\n\nparam_1_valor,param_2_valor = progam_valor(param_1,param_2)\n\nprint(f\"\\nParam_1_valor retorno: {param_1_valor}\")\nprint(f\"Param_2_valor retorno: {param_2_valor}\")\n\nprint(f\"\\nParam_1 despues: {param_1}\")\nprint(f\"Param_2 despues: {param_2}\")\n\nlista_1 = [1,2]\nlista_2 = [3,4]\n\nprint(f\"\\nlista_1 antes: {lista_1}\")\nprint(f\"lista_2 antes: {lista_2}\")\n\nlista_1_ref,lista_2_ref = program_ref(lista_1,lista_2)\n\nprint(f\"\\nlista_1_ref antes: {lista_1_ref}\")\nprint(f\"lista_2_ref antes: {lista_2_ref}\")\n\nprint(f\"\\nlista_1 despues: {lista_1}\")\nprint(f\"lista_2 despues: {lista_2}\")\n\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/EricJoel-code.py",
    "content": "## Valor y Referencia\n\n# Paso por valor es cuando se pasa una copia del valor de la variable a la función, y cualquier cambio hecho a ese valor dentro de la función no afecta la variable original fuera de la función.\n\n# Paso por referencia es cuando se pasa una referencia (o dirección) de la variable a la función, y cualquier cambio hecho a la variable dentro de la función afecta la variable original fuera de la función.\n\n# Tipos de datos por valor\n\nmi_entero = 10\nmi_entero2 = mi_entero\n#mi_entero2 = 20\nmi_entero = 30\nprint(mi_entero) \nprint(mi_entero2)\n\n# Tipos de datos por referencia\n\nmi_lista = [1, 2, 3]\nmi_lista2 = [4, 5, 6]\nmi_lista2 = mi_lista\nmi_lista.append(4)\nprint(mi_lista)\nprint(mi_lista2)\n\n# Funciones y paso por valor\n\nentero = 5\n\ndef modificar_valor(x:int):\n    x = 10\n    print(\"Dentro de la función (valor):\", x)\n    \nmodificar_valor(entero)\nprint(\"Fuera de la función (valor):\", entero)\n\n# Funciones y paso por referencia\n\nlista = [1, 2]\n\ndef modificar_lista(lst:list):\n    lst.append(3)\n    \n    lista2 = lst\n    lista2.append(4)\n    \n    print(\"Dentro de la función (referencia):\", lst) \n    print(\"Dentro de la función (referencia):\", lista2)\n    \nmodificar_lista(lista)\nprint(\"Fuerad e la funcion (referencia):\", lista)\n\n\n## Extra\n\n# Por valor \n\nmy_int = 10\nmy_int2 = 20\n\ndef intercambiar_valores(a:int, b:int):\n    temp = a\n    a = b\n    b = temp\n    return a, b\n\nmy_int3, my_int4 = intercambiar_valores(my_int, my_int2)\nprint(f\"Las variables originales son: my_int = {my_int}, my_int2 = {my_int2}\")\nprint(f\"Las nuevas variables son: my_int3 = {my_int3}, my_int4 = {my_int4}\")\n\n# Por referencia\n\nmy_list = [10, 20]\nmy_list2 = [30, 40]\n\ndef intercambiar_listas(lst1:list, lst2:list):\n    temp = lst1\n    lst1 = lst2\n    lst2 = temp\n    return lst1, lst2\n\nmy_list3, my_list4 = intercambiar_listas(my_list, my_list2)\nprint(f\"Las variables originales son: my_list = {my_list}, my_list2 = {my_list2}\")\nprint(f\"Las nuevas variables son: my_list3 = {my_list3}, my_list4 = {my_list4}\")\n\n#Lo mas conveniente seria usar tipos de datos inmutables (por valor) para evitar efectos secundarios no deseados, o realizar una copia de los datos mutables (por referencia) antes de pasarlos a una función si no se desea modificar el original.\n\n# Por referencia con copia de datos\n\nimport copy\n\nmy_list5 = [50, 60]\nmy_list6 = [70, 80]\n\ndef intercambiar_listas_con_copia(lst1:list, lst2:list):\n    lst1_copy = copy.deepcopy(lst1)\n    lst2_copy = copy.deepcopy(lst2)\n    temp = lst1_copy\n    lst1_copy = lst2_copy\n    lst2_copy = temp\n    return lst1_copy, lst2_copy\n\nmy_list7, my_list8 = intercambiar_listas_con_copia(my_list5, my_list6)\nprint(f\"Las variables originales son: my_list5 = {my_list5}, my_list6 = {my_list6}\")\nprint(f\"Las nuevas variables son: my_list7 = {my_list7}, my_list8 = {my_list8}\")\n\n\"\"\" La diferencia entre la funcion intercambiar_listas y la funcion intercambiar_listas_con_copia es que la primera función trabaja directamente con las referencias a las listas. Al reasignar estas referencias dentro de la función, no estás modificando las listas originales en sí mismas, sino el enlace a dónde apuntan las variables locales. El resultado es que my_list y my_list2 permanecen sin cambios, y las nuevas variables my_list3 y my_list4 reciben las referencias a las listas intercambiadas. En cambio, la segunda función crea copias profundas de las listas originales usando copy.deepcopy(). Esto significa que cualquier modificación realizada dentro de la función no afecta a las listas originales. Al intercambiar las copias, las listas originales my_list5 y my_list6 permanecen intactas, y las nuevas variables my_list7 y my_list8 reciben las referencias a las copias intercambiadas. \"\"\""
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/FedeAirala.py",
    "content": "# #05 VALOR Y REFERENCIA\n\n\"\"\"\n\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n \"\"\"\n\n# Asignación de variables por valor\n\nmy_int = 10\nprint (my_int)\nmy_str = \"Hola\"\nprint (my_str)\nmy_boolean = True\nprint (my_boolean)\n\n# Función con variable asignada por valor\n\ndef my_int_func(my_int):\n    my_int = 20\n    print (my_int)\n\nmy_int_func (my_int)\n\n\"\"\"En el caso anterior se puede ver que se pasa la variable por valor\n    y cambia dentro de la función\n\n\"\"\"\n\n# Asignación de variables por referencia\n\nmy_list = [\"Hola\", \"Python\"]\nprint (my_list)\nmy_list_2 = my_list\nmy_list_2.append (\"Web\")\nprint (my_list_2)\nprint (my_list)           \n\n\"\"\" Con los dos últimos print se puede ver que cuando se hace asignación por referencia,\n    este apunta a dirección (puntero) y cuando se hacen moficaciones, se realizan a la\n    dirección, entonces todas las variables que apunten a ella van a cambiar.\n\"\"\"\n\n# Función con variable por referencia\n\ndef my_ref_func(my_list):\n    my_list.append (\"2\")\n    print (my_list)\n\nmy_ref_func(my_list)\nprint (my_list)\n\n\"\"\"\n DIFICULTAD EXTRA (opcional):\n\n *   Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n *   Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n \n \"\"\"\n\nmy_int_1 = 5\nmy_int_2 = 10\n\ndef var_valor(num_1,num_2)-> tuple:\n    num = num_1\n    num_1 = num_2\n    num_2 = num\n    return (num_1, num_2)\n\nmy_int_3 , my_int_4 = var_valor(my_int_1,my_int_2)\nprint (my_int_1,my_int_2)\nprint(my_int_3,my_int_4)\n\nlist_1 = [5,10]\nlist_2 = [15,20]\n\ndef var_ref (list_3:list, list_4:list)-> tuple:\n    list_n = list_3\n    list_3 = list_4\n    list_4 = list_n\n    return (list_3,list_4)\n\nlist_3,list_4 = var_ref(list_1,list_2)\nprint (list_1,list_2)\nprint (list_3,list_4)\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/GaboDev23.py",
    "content": "'''\n- Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según su tipo de dato.\n- Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas. (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n'''\n# Tipos de datos por valor\nmy_int_a = 10\nmy_int_b = my_int_a\n# my_int_b = 20\n# my_int_a = 30\n\nprint(my_int_a)\nprint(my_int_b)\n\n# Tipos de datos por referencia\nmy_list_a = [10, 20]\nmy_list_b = my_list_a\nmy_list_b.append(30)\n\nprint(my_list_a)\nprint(my_list_b)\n\n# Funciones con datos por valor\nmy_int_c = 10\n\ndef my_int_func(my_int: int):\n    my_int = 20\n    print(my_int)\n\nmy_int_func(my_int_c)\nprint(my_int_c)\n\n# Funciones con datos por referencia\nmy_list_c = [10, 20]\n\ndef my_list_func(my_list: list):\n    my_list_e = my_list\n    my_list_e.append(30)\n    \n    my_list_d = my_list_e\n    \n    my_list_d.append(40)\n    \n    print(my_list_e)\n    print(my_list_d)\n    \nmy_list_func(my_list_c)\nprint(my_list_c)\n\nprint('----------------------------------------------------')\n'''\nDIFICULTAD EXTRA (opcional):\nCrea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n- Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia. Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas. Comprueba también que se ha conservado el valor original en las primeras.\n'''\n# Por valor\nvar1 = 2\nvar2 = 4\ndef prog1(var1: int, var2: int):\n    var3 = var1\n    var1 = var2\n    var2 = var3\n    print(var1, var2)\n\nprint(var1, var2)\nprog1(var1, var2)\n\nprint('----------------------------------------------------')\n# Por referencia\nlist1 = [1, 2]\nlist2 = [3, 4]\n\ndef prog2(list1: list, list2: list):\n    list3 = list1\n    list1 = list2\n    list2 = list3\n    \n    print(list1, list2)\n\nprint(list1, list2)\nprog2(list1, list2)"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/Gallitofast.py",
    "content": "#<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>\n#<><><><><><><><><><><><><><><>-------Valor y referencia-------<><><><><><><><><><><><><><><><><><><><><><><><><>\n#<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>\n# ------------------------------------------\n# Parte 1: Asignación por valor y por referencia\n# ------------------------------------------\n\nprint(\"\\n--- Parte 1: Asignación por valor y por referencia ---\")\n\n# Asignación por valor (tipos inmutables: int, float, str, tuple)\nprint(\"\\nAsignación por valor (tipos inmutables):\")\na = 10\nb = a  # b recibe una copia del valor de a\nprint(f\"Antes: a = {a}, b = {b}\")\nb = 20  # Modificamos b\nprint(f\"Después: a = {a}, b = {b}\")  # a no cambia\n\n# Asignación por referencia (tipos mutables: list, dict, set)\nprint(\"\\nAsignación por referencia (tipos mutables):\")\nlista_original = [1, 2, 3]\nlista_copia = lista_original  # Ambas variables apuntan al mismo objeto\nprint(f\"Antes: original = {lista_original}, copia = {lista_copia}\")\nlista_copia.append(4)  # Modificamos la \"copia\"\nprint(f\"Después: original = {lista_original}, copia = {lista_copia}\")  # Ambas cambian\n\n# ------------------------------------------\n# Parte 2: Funciones con parámetros por valor y referencia\n# ------------------------------------------\n\nprint(\"\\n--- Parte 2: Comportamiento en funciones ---\")\n\ndef modificar_parametro_valor(x):\n    print(f\"Dentro (antes): x = {x}\")\n    x = 100  # Esto no afectará al original si es inmutable\n    print(f\"Dentro (después): x = {x}\")\n\ndef modificar_parametro_referencia(lst):\n    print(f\"Dentro (antes): lst = {lst}\")\n    lst.append(99)  # Esto modificará el objeto original\n    print(f\"Dentro (después): lst = {lst}\")\n\n# Prueba con tipo inmutable (por valor)\nprint(\"\\nFUNCIÓN CON PARÁMETRO POR VALOR (int):\")\nvalor = 5\nprint(f\"Antes de función: valor = {valor}\")\nmodificar_parametro_valor(valor)\nprint(f\"Después de función: valor = {valor}\")\n\n# Prueba con tipo mutable (por referencia)\nprint(\"\\nFUNCIÓN CON PARÁMETRO POR REFERENCIA (list):\")\nlista = [1, 2, 3]\nprint(f\"Antes de función: lista = {lista}\")\nmodificar_parametro_referencia(lista)\nprint(f\"Después de función: lista = {lista}\")\n\n# ------------------------------------------\n# Parte 3: Dificultad EXTRA - Intercambio de valores\n# ------------------------------------------\n\nprint(\"\\n--- Parte 3: Dificultad EXTRA ---\")\n\n# Función que intercambia parámetros por valor\ndef intercambiar_por_valor(a, b):\n    print(f\"Dentro (antes): a = {a}, b = {b}\")\n    temp = a\n    a = b\n    b = temp\n    print(f\"Dentro (después): a = {a}, b = {b}\")\n    return a, b\n\n# Función que intercambia parámetros por referencia\ndef intercambiar_por_referencia(lista1, lista2):\n    print(f\"Dentro (antes): lista1 = {lista1}, lista2 = {lista2}\")\n    temp = lista1.copy()\n    lista1.clear()\n    lista1.extend(lista2)\n    lista2.clear()\n    lista2.extend(temp)\n    print(f\"Dentro (después): lista1 = {lista1}, lista2 = {lista2}\")\n    return lista1, lista2\n\n# Prueba con intercambio por valor\nprint(\"\\nINTERCAMBIO POR VALOR (int):\")\nx, y = 10, 20\nprint(f\"Originales antes: x = {x}, y = {y}\")\nnuevo_x, nuevo_y = intercambiar_por_valor(x, y)\nprint(f\"Originales después: x = {x}, y = {y}\")\nprint(f\"Nuevas variables: nuevo_x = {nuevo_x}, nuevo_y = {nuevo_y}\")\n\n# Prueba con intercambio por referencia\nprint(\"\\nINTERCAMBIO POR REFERENCIA (list):\")\nlista_a = [1, 2, 3]\nlista_b = [4, 5, 6]\nprint(f\"Originales antes: lista_a = {lista_a}, lista_b = {lista_b}\")\nnueva_lista_a, nueva_lista_b = intercambiar_por_referencia(lista_a, lista_b)\nprint(f\"Originales después: lista_a = {lista_a}, lista_b = {lista_b}\")\nprint(f\"Nuevas variables: nueva_lista_a = {nueva_lista_a}, nueva_lista_b = {nueva_lista_b}\")"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/Gordo-Master.py",
    "content": "\"\"\"\nValor y referencia\n\"\"\"\n\n# Tipo de dato por valor\n\nmy_int_a = 10\nmy_int_b = my_int_a\nmy_int_b = 20\n# my_int_a = 30\nprint(my_int_a)\nprint(my_int_b)\n\n# Tipo de dato por referencia\n\nmy_list_a = [10, 20]\nmy_list_b = my_list_a\nmy_list_b.append(30)\nprint(my_list_a)\nprint(my_list_b)\n\n# Funciones por datos por valor\n\nmy_int_c = 10\n\n\ndef my_int_func(my_int: int):\n    my_int = 20\n    print(my_int)\n\n\nmy_int_func(my_int_c)\nprint(my_int_c)\n\n# Funciones por datos con referencia\n\n\ndef my_list_func(my_list: list):\n    my_list_e = my_list\n    my_list_e.append(30)\n\n    my_list_d = my_list_e\n    my_list_d.append(40)\n\n    print(my_list_e)\n    print(my_list_d)\n\n\nmy_list_c = [10, 30]\nmy_list_func(my_list_c)\nprint(my_list_c)\n\n\n# Asignación por valor\n# Funciona en los tipos simples: entero, flotante, cadena, logicos, nonetype\n\ndef doblar_numero(numero):\n    numero *= 2\n\nn1= 10\ndoblar_numero(n1) \nprint(n1)\n\n\n# Asignación por referencia\n# Funciona en los tipos compuestos: lista, diccionario, conjuntos, clases\n\n# Para tipos compuestos mutables\ndef doblar_valores(numeros):\n    for i in range(len(numeros)):\n        numeros[i] *= 3\n\nns = [10,50,100]\ndoblar_valores(ns)\nprint(ns)\n\n# Tipos simples, se hace con retorno y reasignación\ndef triplicar_numero(numero):\n    return numero * 3\n\nn = 10\nn = triplicar_numero(n)\nprint(n)\n\n# Para evitar la modificación de los tipos compuestos, enviar copias\ndef triplicar_valores(numeros):\n    for i in range(len(numeros)):\n        numeros[i] *= 3\n\nns = [10,50,100]\ntriplicar_valores(ns[:])    # Se crea copia con slice\nprint(ns)\n\n\n\"\"\"\nExtra\n\"\"\"\n\n# Por valor\n\n\ndef asig_valor(value_1: int, value_2: int): # Asignación por valor\n    temp = value_1\n    value_1 = value_2\n    value_2 = temp\n    return value_1, value_2\n\n\nx1 = 10\nx2 = 20\nx3, x4 = asig_valor(x1,x2)\n\n\nprint(f\"El valor de x1: {x1}\")\nprint(f\"El valor de x2: {x2}\")\n\nprint(f\"El valor de x3(x1.inv): {x3}\")\nprint(f\"El valor de x4(x2.inv): {x4}\")\n\n\n# Asignación por referencia\ndef asig_ref(value_1:list,value_2:list): \n    temp = value_1[:]\n    value_1 = value_2[:]\n    value_2 = temp\n    value_1.append(50)\n    value_2.append(50)\n    return value_1, value_2\n\nw = [15, 80]\nx = [60, 150]\ny, z = asig_ref(w,x)\n\nprint(f\"{w}, {x}\")\nprint(f\"{y}, {z}\")\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/Hyromy.py",
    "content": "#asignacion por valor\na = 5\nb = 10\nprint(a)\nprint(b)\nprint(a is b)\n\n\n#asignacion por referencia\nc = [1, 2, 3]\nd = c\nd[0] = 5\nprint(c)\nprint(c is d)\n\n\n#funcion por valor\ndef aumentar(x):\n    x += 1\n    return x\n\nvalor1 = 10\nvalor2 = aumentar(valor1)\n\nprint(valor1) #10\nprint(valor2) #11\n\n\n#funcion por referencia\ndef doblar(lista):\n    for i in range(len(lista)):\n        lista[i] *= 2\n\n    return lista\n\nnumeros1 = [1, 2, 3]\nnumeros2 = doblar(numeros1)\n\nprint(numeros1) #[2, 4, 6]\nprint(numeros2) #[2, 4, 6]\n\n\n#funcion anterior por valor\ndef dobla2(lista1):\n    lista2 = lista1.copy() #le da solo los valores y no la referencia en memoria\n\n    for i in range(len(lista2)):\n        lista2[i] *= 2\n\n    return lista2\n\nlista1 = [5, 10, 15]\nlista2 = dobla2(lista1)\n\nprint(lista1) #[5, 10, 15]\nprint(lista2) #[10, 20, 30]\n\n\n# ---- DIFICULTAD EXTRA ----\nprint(\"No se que hice funciona medio raro xd\")\n\ndef program1(v1, v2):\n    x1, x2 = v1.copy(), v2.copy()\n    \n    return x1, x2\n\ndef program2(r1, r2):\n    r1[0] *= 2\n    r2[0] *= 2\n\n    return r1, r2\n\na = [2]\nb = [7]\n\na1, b1 = program1(a, b)\na2, b2 = program2(a1, b1)\na3, b3 = program1(a2, b2)\n\nprint(\"Originales\")\nprint(a)\nprint(b)\nprint(\"\\nValor\")\nprint(a1)\nprint(b1)\nprint(\"\\nReferencia\")\nprint(a2)\nprint(b2)\nprint(\"\\nValor\")\nprint(a3)\nprint(b3)\nprint(\"\\nOriginales\")\nprint(a)\nprint(b)"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/Irenetitor.py",
    "content": "#Value and Reference\n\n# Data types passed by value\n\nmy_int_a = 5\nmy_int_b = my_int_a   # my_int_b gets a *copy* of the value 5\nmy_int_b = 15         # changing my_int_b does NOT affect my_int_a\n\nprint(my_int_a)   # 5\nprint(my_int_b)   # 15\n\n# Data types passed by reference\n\nmy_list_a = [1, 2]\nmy_list_b = my_list_a  # both point to the same list in memory\nmy_list_b.append(3)    # modifies the *same* object\n\nprint(my_list_a)   # [1, 2, 3]\nprint(my_list_b)   # [1, 2, 3]\n\n# Functions with data passed by value\n\ndef my_int_func(my_int: int):\n    my_int = 100                                         # Inside function: 100\n    print(\"Inside function:\", my_int)\n\nmy_int_c = 50\nmy_int_func(my_int_c)\nprint(\"Outside function:\", my_int_c)                     # Outside function: 50\n\n# Functions with data passed by reference\n\ndef my_list_func(my_list: list):\n    my_list.append(3)       # modifies the original list\n    my_list_d = my_list\n    my_list_d.append(4)     # also modifies the same object\n    print(\"Inside function:\", my_list)    # [1, 2, 3, 4]\n    print(\"Alias variable:\", my_list_d)   # [1, 2, 3, 4]\n\nmy_list_c = [1, 2]\nmy_list_func(my_list_c)\nprint(\"Outside function:\", my_list_c)  # [1, 2, 3, 4]\n\n\n#Extra \n\nbon1 = 12\nbon2 = 32\n\ndef pro_v(bon_1:int, bon_2:int):\n    yum = bon_1 \n    bon_1 = bon_2\n    bon_2 = yum\n    return bon_1, bon_2\n\nbon3, bon4 = pro_v(bon1, bon2)\nprint(f\"{bon1}, {bon2}\")\nprint(f\"{bon3}, {bon4}\")\n\n#--------------------------------------------------------------------------\n\nbun1 = [23, 56]\nbun2 = [21, 45]\n\ndef pro_r(bun_1:list, bun_2:list):\n    yum = bun_1 \n    bun_1 = bun_2\n    bun_2 = yum\n    return bun_1, bun_2\n\nbun3, bun4 = pro_v(bun1, bun2)\nprint(f\"{bun1}, {bun2}\")\nprint(f\"{bun3}, {bun4}\")"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/JacMac45.py",
    "content": "# Valor y Referencia\n\n# Tipos de dato por valor\n\nmy_int_a = 10\nmy_int_b = my_int_a\nmy_int_b = 20\nmy_int_a = 30 \nprint(my_int_a)\nprint(my_int_b)\n\n# Tipos de dato por referencia (son todos los que no sean primitivos)\n\nmy_list_a = [10, 20]\nmy_list_b = my_list_a\nmy_list_b.append(30)\nprint(my_list_a)\nprint(my_list_b)\n\n# Funciones con datos por valor\nnum1 = 21\nnum2 = 10\n\ndef intercambio(num1, num2):\n    temp = num1\n    num1 = num2\n    num2 = temp\n    return [num1, num2]\n\ninter_num1, inter_num2 = intercambio(num1, num2)\nprint(f\"{inter_num1}, {inter_num2}\")\n\n# Funciones con datos por referencia\n\ndef modificar_lista(lista: list):\n    lista.append(4)\n    \n    lista2 = lista\n    lista2.append(5)\n\n    print(\"Dentro de la función:\", lista)\n    print(\"Dentro de la función:\", lista2)\n\nmy_list = [1, 2, 3]\nmodificar_lista(my_list)\nprint(\"Fuera de la función:\", my_list)\n\n# Dificultad Extra.\n\n# Por valor\n\nint_1 = 30\nint_2 = 45\n\ndef intercambio_valor (parametro_valor_1: int, parametro_valor_2: int) -> tuple:\n    intercambio = parametro_valor_1\n    parametro_valor_1 = parametro_valor_2\n    parametro_valor_2 = intercambio\n    int_1_new = parametro_valor_1\n    int_2_new = parametro_valor_2\n    return int_1_new, int_2_new\n\nint_3, int_4 = intercambio_valor (int_1, int_2)   \n\nprint(f\"{int_1}, {int_2}\")\nprint(f\"{int_3}, {int_4}\")\n\n# Por referencia\n\nlist_1 = [30, 40, 50]\nlist_2 = [60, 70, 80]\n\ndef intercambio_valor (parametro_valor_1: list, parametro_valor_2: list) -> tuple:\n    intercambio = parametro_valor_1\n    parametro_valor_1 = parametro_valor_2\n    parametro_valor_2 = intercambio\n    list_1_new = parametro_valor_1\n    list_2_new = parametro_valor_2\n    return list_1_new, list_2_new\n\nlist_3, list_4 = intercambio_valor (list_1, list_2)   \n\nprint(f\"{list_1}, {list_2}\")\nprint(f\"{list_3}, {list_4}\")\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/Jav-mol.py",
    "content": "# Tipos de datos por valor \n\nvariable_a = 20\n\nvariable_b = variable_a\n\nvariable_b = 40\n\nprint(variable_a)\nprint(variable_b)\n\n# Tipos de datos por referencia\n\nmy_lista_1 = [1,2,3]\n\nmy_lista_2 = my_lista_1\n\nmy_lista_3 = my_lista_2\n\nmy_lista_2.append(4)\n\nprint(my_lista_1)\nprint(my_lista_2)\nprint(my_lista_3)\n\n# Funciones con datos por valor\n\ndef función_valor(value:int):\n    value = value + 10\n    print(value)\n\n# Funciones con datos por referencia\n    \ndef funcion_referencia(lista:list):\n    lista_2 = lista\n    lista_2.append(50)\n    print(lista)\n    print(lista_2)\n    \n     \nfunción_valor(10)\nfuncion_referencia([10,20,30,40])\nprint()\n\n\"\"\" Extra \"\"\"\n\nvariable_1:int = 10\nvariable_2:int = 20\n\ndef variables(var_1, var_2):\n    var_1, var_2 = var_2, var_1    \n    \n    return var_1, var_2\n\nnew_var_1, new_var_2 = variables(variable_1,variable_2)\n\nprint(f\"Parametros: {variable_1} - {variable_2} \\nRetorno: {new_var_1} - {new_var_2}\")\n\nlista_1:list = [10,20,30]\nlista_2:list = [40,50,60]\n\nnew_lista_1, new_lista_2 = variables(lista_1,lista_2) \nprint(f\"Parametros: {lista_1} - {lista_2} \\nRetorno: {new_lista_1} - {new_lista_2}\")"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/JesusAntonioEEscamilla.py",
    "content": "# #05 - Python -> Jesus Antonio Escamilla\n\n\"\"\"\nEJERCIÓ\n\"\"\"\n#--Asignación de Variables--\n#VALOR\nprint(\"Asignación de Variables\")\nprint(\"Valor\")\na = 5\nb = a\n\nprint(\"a: \", a)\nprint(\"b: \", b)\n\n#REFERENCIA\nprint(\"Referencia\")\nlista1 = [1, 2, 3]\nlista2 = lista1\n\nprint(\"lista1: \", lista1)\nprint(\"lista2: \", lista2)\n\n\nlista2.append(4)\nprint(\"lista1: \", lista1)\nprint(\"lista2: \", lista2)\n\n\n#--Variables a Funciones--\n#VALOR\nprint(\"Variables a Funciones\")\nprint(\"Valor\")\ndef modificar_valor(x):\n    x = 10\n\na = 5\nmodificar_valor(a)\nprint(a)\n\n#REFERENCIA\nprint(\"Referencia\")\ndef modificar_referencia(lista):\n    lista.append(4)\n\nlista1 = [1, 2, 3]\nmodificar_referencia(lista1)\nprint(lista1)\n\n\n\n\"\"\"\nEXTRA\n\"\"\"\nprint(\"Extra Valor\")\n# Funciones para intercambiar valores\ndef intercambiar_valor(a, b):\n    a, b = b, a\n    return a, b\n\n# Variables Originales\nx = 5\ny = 10\n\n# Asignamos a nuevas variables\nnuevoX, nuevoY = intercambiar_valor(x, y)\n\n# Imprimir los resultado en la consola\nprint(f\"Originales: x = {x}, y = {y}\")\nprint(f\"Nuevas: nuevo_X = {nuevoX}, nuevo_Y = {nuevoY}\")\n\n\nprint(\"Extra Referencia\")\n# Función para intercambiar valores en lista\ndef intercambio_lista(lista1, lista2):\n    lista1[:], lista2[:] = lista2[:], lista1[:]\n    return lista1, lista2\n\n# Variables Originales\nlista_a = [1, 2, 3]\nlista_b = [4, 5, 6]\n\n# Creamos copias de las listas\nlista_a_original = lista_a[:]\nlista_b_original = lista_b[:]\n\n# Asignación a nuevas variables\nnueva_lista_a, nueva_lista_b = intercambio_lista(lista_a, lista_b)\n\n# Imprimir los resultado en la consola\nprint(f\"Originales: lista_a = {lista_a_original}, lista_b = {lista_b_original}\")\nprint(f\"Nuevas: nueva_lista_a = {nueva_lista_a}, nueva_lista_b = {nueva_lista_b}\")"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/JoseAlberto13.py",
    "content": "\"\"\"* EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\"\"\"\n\n\"\"\"Tipo de datos por Valor\"\"\" # Primitivos\n\nnumero = 10\nnumero2 = numero\nnumero2 = 50\nprint(numero)\nprint(numero2)\n\n\n\"\"\"Tipo de datos por Referencia\"\"\" # Compuestos\n\nnum_lista = [10,50,100]\nnum_lista_Copia = num_lista\nnum_lista_Copia.append(200) # El valor será añadido a ambas listas, ya que la copia de la lista, apunta al espacio en memoria de la lista original\nprint(num_lista)\nprint(num_lista_Copia)\n\n\n\"\"\" Función con datos por valor 'Primitivos' \"\"\"\n\ndef cuadrado_valor(numero):\n    numero *= numero\n    print(numero)\n\ncuadrado_valor(numero)\nprint(numero)\n\n\"\"\" Función con datos por valor 'Compuestos' \"\"\"\n\ndef cuadrado_valores(numeros):\n    for i,n in enumerate(numeros):\n        numeros[i] *= numeros[i]\n    print(numeros[:])\n\ncuadrado_valores(num_lista[:])  # Asignamos una copia de la lista con [:]\nprint(num_lista)\n\n\n\"\"\"Función con datos por referencia 'Compuestos' \"\"\"\n\ndef mitad_numeros(numeros):\n    for i,n in enumerate(numeros):\n        numeros[i] /= 2\n    print(numeros)\n\nmitad_numeros(num_lista)\nprint(num_lista)\n\n\"\"\"* DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\"\"\"\n\nnum1 = 10\nnum2 = 20\n\ndef intercambio(valor1, valor2):\n    return valor2, valor1\n\nprint(f\"{num1}, {num2}\")\nnum3, num4 = intercambio(num1,num2)\nprint(f\"{num1}, {num2}\")\nprint(f\"{num3}, {num4}\")\n\n# Ambas funciones hacen el mismo trabajo, lo importante es el orden de los parámetros \n\ndef intercambio_Mouredev(value_a: int, value_b: int) -> tuple:\n    temp = value_a\n    value_a = value_b\n    value_b = temp\n    return value_a, value_b\n\nnum3, num4 = intercambio_Mouredev(num1,num2)\nprint(f\"{num3}, {num4}\")\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/JuanDAW37.py",
    "content": "\"\"\"\n* EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como\n * variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime\n *   el valor de las variables originales y las nuevas, comprobando que se ha invertido\n *   su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n\"\"\"\n# Variable con asignación por valor:\nvar1 = 15\nvar2 = var1\nprint(var1)\nprint(var2)\nvar1 = 50\nprint(var1)\nprint(var2)\n\n# Variable con asignación por referencia, todos los tipos de datos que no son primitivos\nlista1 = [10, 30,50, 60]\nlista2 = lista1\nprint(lista1)\nprint(lista2)\nlista1.append(100)\nprint(lista1)\nprint(lista2)\n\n# Función con asignación por valor:\nvar3 = 20\n\ndef varVal(var4:int):\n    print(f'Valor de var4 antes de modificarla: {var4}')\n    var4 = 30\n    print(f'Valor de var4 después de modificarla: {var4}')\n    print(f'Valor de var3: {var3}')\n    \nvarVal(var3)\nprint(f'Valor de var3 fuera de la función: {var3}')\n\n# Función con asignación por referencia:\nlista3 = ['Lunes', 'Martes', 'Miércoles', 'Jueves', 'Viernes', 'Sábado']\nprint(f'ANTES de modificar lista3: {lista3}')\n\ndef funcVal(lista:list):\n    lista.append('Domingo')\n    print(f'DESPUÉS de modificar lista3: {lista3}')\n    \nfuncVal(lista3)\nprint(f'DESPUÉS de llamar a funcVal: {lista3}')\n\n# DIFICULTAD EXTRA\n\ndef valor(valor1:int, valor2:int)->tuple:\n    temporal = valor1\n    valor1 = valor2\n    valor2 = temporal\n    return valor1, valor2\n\nv1 = 10\nv2 = 20\nv1_nuevo, v2_nuevo = valor(v1, v2)\nprint(f'Valor de v1 {v1}, valor de v2 {v2}')\nprint(f'Valor de v1_nuevo {v1_nuevo}, valor de v2_nuevo {v2_nuevo}')\n\ndef referencia(lista1:list, lista2:list)->tuple:\n    temporal = lista1\n    lista1 = lista2\n    temporal.append(1000)\n    lista2 = temporal\n    return lista1, lista2\n\nlista4 = [10,20,30]\nlista5=[30,20,10]\nlista4_nueva, lista5_nueva = referencia(lista4, lista5)\nprint(f'Valores de lista4 {lista4}, Valores de lista5 {lista5}')\nprint(f'Valores de lista4_nueva {lista4_nueva}, Valores de lista5_nueva {lista5_nueva}')"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/Juanma0416.py",
    "content": "\"\"\"\nValor y referencia\n\"\"\"\n\n# Tipos de dato por valor\n\nmy_int_a = 10\nmy_int_b = my_int_a\nmy_int_b = 20\n\n# my_int_a = 30\nprint(my_int_a)\nprint(my_int_b)\n\n\n# Tipos de dato por referencia\n\nmy_list_a = [10, 20]\nmy_list_b = my_list_a\nmy_list_b.append(30)\nprint(my_list_a)\nprint(my_list_b)\n\n\n# Funciones con datos por valor\n\ndef my_int_func(my_int: int):\n    my_int = 20\n    print(my_int)\n\n\nmy_int_c = 10\nmy_int_func(my_int_c)\nprint(my_int_c)\n\n\n# Funciones con datos por referencia\n\ndef my_list_func(my_list: list):\n    my_list.append(30)\n\n    my_list_d = my_list\n    my_list_d.append(40)\n\n    print(my_list)\n    print(my_list_d)\n\n\nmy_list_c = [10, 20]\nmy_list_func(my_list_c)\nprint(my_list_c)\n\n\n\"\"\"\nExtra\n\"\"\"\n\n# Por valor\n\ndef value(value_a: int, value_b: int) -> tuple:\n    temp = value_a\n    value_a = value_b\n    value_b = temp\n    return value_a, value_b\n\n\nmy_int_d = 10\nmy_int_e = 20\nmy_int_f, my_int_g = value(my_int_d, my_int_e)\n\nprint(f\"{my_int_d}, {my_int_e}\")\nprint(f\"{my_int_f}, {my_int_g}\")\n\n\n# Por referencia\n\ndef ref(value_a: list, value_b: list) -> tuple:\n    temp = value_a\n    value_a = value_b\n    value_b = temp\n    return value_a, value_b\n\n\nmy_list_e = [10, 20]\nmy_list_f = [30, 40]\nmy_list_g, my_list_h = ref(my_list_e, my_list_f)\nprint(f\"{my_list_e}, {my_list_f}\")\nprint(f\"{my_list_g}, {my_list_h}\")\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/KevinED11.py",
    "content": "asignacion_por_valor = 1\nasignacion_por_referencia = asignacion_por_valor\nasigmación_por_referencia = 2\nprint(asignacion_por_valor)\n\n\nlista_por_valor = [1, 2, 3]\nlista_por_referencia = lista_por_valor\nlista_por_referencia.append(4)\n\nprint(lista_por_valor)\n\n\nlistilla = [1, 2, 3]\n\n\ndef funcion_por_valor(numero: int) -> None:\n    numero += 1\n    print(numero)\n\n\ndef funcion_por_referencia(lista: list) -> None:\n    lista[0] = 100\n\n\ndef funcion_por_valor2(lista: list) -> None:\n    lista[1] = 200\n\n\nvalue1 = 100\nvalue2 = 200\n\n\ndef intercambio_por_valor(a, b) -> tuple[int, int]:\n    a, b = b, a\n\n    return a, b\n\n\ndef intercambio_por_referencia(lista: list) -> list:\n    lista[0], lista[1] = lista[1], lista[0]\n\n    return lista\n\n\ndef intercambio_por_referencia2(lista1: list, lista2: list) -> None:\n    lista1[:], lista2[:] = lista2[:], lista1[:]\n\n\ndef main() -> None:\n    funcion_por_valor(1)\n    funcion_por_referencia(listilla)\n    print(listilla)\n\n    funcion_por_valor2(listilla[:])\n    print(listilla)\n\n    print(\"valores originales\")\n    print(value1, value2)\n\n    print(\"valores intercambiados\")\n    print(intercambio_por_valor(value1, value2))\n\n    lista_original = [10, 20]\n    nueva_lista = lista_original[:]\n    print(\"lista original\")\n    intercambio_por_referencia(nueva_lista)\n    print(lista_original)\n\n    print(\"valores intercambiados\")\n    intercambio_por_referencia(lista_original)\n    print(lista_original)\n\n    lista1 = [10, 20]\n    lista2 = [30, 40]\n    intercambio_por_referencia2(lista1, lista2)\n    print(lista1, lista2)\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/Lazar171717ech.py",
    "content": "## 1.VARIABLES POR VALOR Y REFERENCIA ##\n\n# Voy a crear dos variables, un string y una lista.\nvariableUno: str = \"Hola\"\nvariableDos: list = [\"Hola\", \"Pedro\"]\n\n# Ahora creo dos funciones que alteren un valor:\ndef añadirEspacio1(valor):\n    valor += \" \"\ndef añadirEspacio2(valor):\n    valor.append(\" \")\n\n# Ahora llamo a las respectivas funciones\nañadirEspacio1(variableUno)\nañadirEspacio2(variableDos)\n\n# Escribo los resultados:\nprint(f\"'{variableUno}'\") # Como podemos ver gracias a las comillas, la variableUno no ha cambiado al pasar por la función\nprint(variableDos) # En cambio, la variableDos si ha mantenido el cambio después de pasar por la función ¿Por qué?\n#Lo que sucede es que en el primer caso, dentro de la función se crea una copia del objeto inicial. Los cambios se realizan en la copia.\n#En el segundo caso dentro de las funciones estaríamos modificando el objeto inicial.\n#Si quisieramos devolver el cambio, utilizaríamos el return:\n\ndef añadirEspacio3(valor) -> str:\n    valor += \" \"\n    return valor\nvariableUno = añadirEspacio3(variableUno)\nprint(f\"'{variableUno}'\")\n# Comprobamos que ahora sí que añade el espacio al pasar por la función. Tanto los int, str, float y Bools son de paso por valor.\n\n#Si quisieramos que no se realizara el cambio, usamos la función con una copia:\n\ndef añadirEspacio4(valor):\n    valor.append(\" \")\nañadirEspacio4(variableDos[:]) # Una forma de hacer la copia es mandado un slice[:] completo del original\nprint(variableDos)\n# Comprobamos que ahora no se añade un segundo espacio al pasar por la función. Las listas, tuplas... son de paso por referencia.\n\n\n## 2.DIFICULTAD EXTRA ##\n\ndef programaUno(valor1, valor2):\n    valor3 = valor1\n    valor1 = valor2\n    valor2 = valor3\n    return valor1, valor2\n\ndef programaDos(valor):\n    valor1 = valor[0]\n    valor[0] = valor[1]\n    valor[1] = valor1\n    return valor\n\ndatoUno = \"Hola\"\ndatoDos = \"Adios\"\n\ndatoUno2, doatoDos2 = programaUno(datoUno, datoDos)\nprint(f\"Datos originales: {datoUno, datoDos}. Datos nuevos: {datoUno2, doatoDos2}\")\n# Resultado --> Datos originales: ('Hola', 'Adios'). Datos nuevos: ('Adios', 'Hola')\n\n\ndatoUno = [\"Hola\", \"Adios\"]\n\ndatoUno2 = programaDos(datoUno)\nprint(f\"Datos originales: {datoUno}. Datos nuevos: {datoUno2}\")\n# Resultado --> Datos originales: ['Adios', 'Hola']. Datos nuevos: ['Adios', 'Hola']\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/Lio7master.py",
    "content": "\n#  EJERCICIO:\n#  - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n#    su tipo de dato.\n#  - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n#    \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n#  (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n\n#  DIFICULTAD EXTRA (opcional):\n#  Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n#  - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n#    Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n#    se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n#    variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n#    Comprueba también que se ha conservado el valor original en las primeras.\n\n\n#valor y referencia\n\n#tipos de datos por valor -> en python todos los tipos de datos primitivos\n\nmy_int_a = 10\nmy_int_b = 20\nprint(my_int_a)\nprint(my_int_b)\n\n\nmy_int_b = my_int_a # le asignamos el valor con el momento exacto cuando la asignamos\nmy_int_a = 30\nprint(my_int_a)\nprint(my_int_b)\n\n#tipos de datos por referencia -> en python todos aquellos que no son de tipo primitivo listas, diccionarios, tuplas, etc\n\nmy_list_a = [10, 20]\nmy_list_b = [30, 40]\n\nprint (my_list_a)\nprint(my_list_b)\n\nmy_list_b = my_list_a #aqui no asignamos valor aputamos la posicion de memoria, sigue siendo dos variables pero apuntan al mismo espacion de memoria.\nprint(\"se observa que son la misma lista con my_list_a = my_list_b\")\nprint (my_list_a)\nprint(my_list_b)\n\n\nmy_list_b.append(30)\nprint(\"---aqui ya hemos hecho un append a my_list_b unicamente pero afeta en memoria la lista para las dos vars\")\nprint (my_list_a)\nprint(my_list_b)\n\n\n#funciones con datos por valor\n\nprint(\"---funcion var---\")\ndef my_int_func(my_int: int):\n    print(\"valor recibido por la funcion\")\n    print(my_int)\n    my_int = 20\n    print(\"Cambiamos el valor recibido dentro de la funcion\")\n    print(my_int)\n\nmy_int_c = 10\n\nmy_int_func(my_int_c)\nprint(\"variable inicial despues de pasar la func\")\nprint(my_int_c) #no cambia porque son independientes, la que se untiliza en la fucnion ocupo el valor mas no la referencia de memoria.\n\n#funcion con datos de referencia\nprint(\"---funcion list---\")\nmy_list_c = [10, 20]\nprint(\"lista original declarada (my_list_c):\")\nprint(my_list_c)\n\ndef my_list_fun(mylist: list):#basicamente esto es un puntero\n    my_list_d = mylist.copy()\n    print(\"copiamos mylist a my_list_d\")\n    print(my_list_d)\n    mylist.append(30)\n    print(\"ejecucion del append en var mylist en la func: \")\n    print(mylist)\n    print(\"my_list_d no sufrio cambio porque se creo una referencia nueva con el copy\")\n    print(my_list_d)\n\n\nmy_list_fun(my_list_c)\nprint(\"Lista original despues de la funcion: \")\nprint(my_list_c) #aqui ya podemos observar el cambio de la variable original porque al pasarla a la funcion copia la referencia de memoria.\n\n\n#extra\n\n#por valor\n\nvar_a = 10\nvar_b = 20\n\ndef intercambio(a:int, b:int) -> tuple:\n    temp = a\n    a = b\n    b = temp\n    return a, b\n\nvar_c, var_d = intercambio(var_a, var_b)\n\nprint(f\"var a: {var_a}, var b: {var_b}\")\nprint(f\"var c: {var_c}, var d: {var_d}\")\n\n# por referencia\n\nlist_a = [10, 20]\nlist_b = [30, 40]\n\ndef intercambio(a_list: list, b_list: list) -> tuple:\n    temp = a_list #guardamos el puntero de 'a' temporalmente\n    a_list = b_list #el puntero de 'b' es ahora asignado 'a'\n    b_list = temp#el puntero de la lista 'a' que guardamos temporalmente se asigna a 'b'\n    a_list.append(50)\n    return a_list, b_list\n\n\n\nlist_c, list_d = intercambio(list_a, list_b)\n#esto funciona porque estamos iniciando con dos punteros distintos a y b dentro de la logica de la funcion se copian estos sin mezclarse\nprint(f\"list a: {list_a}, list b: {list_b}\")\nprint(f\"list c: {list_c}, list d: {list_d}\")\n\nlist_d.append(70)\n\nprint(f\"list a: {list_a}, list b: {list_b}\")\nprint(f\"list c: {list_c}, list d: {list_d}\")\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/Lioomx.py",
    "content": "\n''' Asignación de variables'''\n\n\"\"\" POR VALOR \"\"\"\n\n# Tipos inmutables - int, float, str, tuplas, bool\n\nx = 10\ny = x # Se copia el valor de 'x' a 'y'\ny = 20 # Cambiar 'y' no afecta a 'x'\n\nprint(x)\nprint(y)\n\n\"\"\" POR REFERENCIA \"\"\"\n\n# Tipos mutables - list, dict, set\n\na = [1, 2, 3]\nb = a # Se asigna la referencia de 'a' a 'b'\nb.append(4) # Modificamos la lista usando 'b'\n\nprint(a)\nprint(b)\n\n''' Al ser mutables, tanto 'a' como 'b' apuntan al mismo objeto\ny cualquier cambio afecta a ambos\n'''\n\n# Copiar por valor\n\na = [1, 2, 3]\nb = a.copy()\nb.append(4)\n\nprint(a) \nprint(b)\n\n# Funciones con datos por valor\n\ndef my_int_func(my_int: int):\n    my_int = 20\n    print(my_int)\n\nmy_int_c = 10\nmy_int_func(my_int_c)\nprint(my_int_c)\n\n# Funciones con datos por referencia\n\ndef my_list_func(my_list: list):\n    my_list_e = my_list\n    my_list.append(30)\n\n    my_list_d = my_list_e\n    my_list_d.append(40)\n\n    print(my_list_e)\n    print(my_list_d)\n\nmy_list_c = [10, 20] \nmy_list_func(my_list_c)\nprint(my_list_c)\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/LittleMabbit.py",
    "content": "# Tipos de datos por valor - Cada valor tiene su espacio en memoria.\nint_a = 10\nint_b = 20\nprint(int_b)\nint_b = int_a\nprint(int_b)\n\n# Tipos de datos por referencia - Valores que heredan lo que poseen por su espacio en memoria. Todos los datos que no son primitivos. Por referencia entendemos que estamos referenciando el valor en memoria.\nmy_list_a = [10, 20]\nmy_list_b = my_list_a\nmy_list_b.append(30)\nprint(my_list_a) \nprint(my_list_b)\n\n# Funciones con datos por valor\n\n\ndef my_int_func(my_int: int):\n    my_int = 10 # El valor dentro de la scope es asignado como my_int.\n    print(my_int)\n\n\nmy_int_c = 30 # Se asigna el valor que pasa a la función my_int_func, mas ya tiene el 10 establecido.\nmy_int_func(my_int_c) # Recibe el valor asignado realmente dentro del scope de la función.\nprint(my_int_c) # Recibe el valor establecido fuera de la función.\n\n# Funciones con datos por referencia\n\n\ndef my_list_func(my_list: list):\n    my_list.append(30)\n\n    my_list_d = my_list\n    my_list_d.append(40)\n\n    print(my_list)\n    print(my_list_d)\n\n\nmy_list_c = [10, 20]\nmy_list_func(my_list_c)\nprint(my_list_c)\n\n# Los valores se mueven, asignan y reasignan en base al valor hexadecimal que cada variable tenga asignada en memoria."
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/LucasRebuffo.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como\n * variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime\n *   el valor de las variables originales y las nuevas, comprobando que se ha invertido\n *   su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */ \"\"\"\n\n\"\"\" En python el pasaje por valor o por referencia esta determinado por el tipo de valriable,\n    Si es de tipo compuesto se pasa por referencia y si es de tipo simple se pasa por valor \"\"\"\n\n\n\"\"\" Ejemplos: tipos de datos simples \"\"\"\n\n\ndef pasaje_valor_1(valor: int):\n    valor += 1\n\n\ndef pasaje_valor_2(valor: bool):\n    valor = not valor\n\n\ndef pasaje_valor_3(valor: str):\n    valor.upper()\n\n\ndef pasaje_valor_4(valor: float):\n    valor *= 3\n\n\nvalor = 2\n\npasaje_valor_1(valor)\nprint(valor)\n\nvalor = True\n\npasaje_valor_2(valor)\nprint(valor)\n\nvalor = \"lucas\"\n\npasaje_valor_3(valor)\nprint(valor)\n\nvalor = 1.3\n\npasaje_valor_4(valor)\nprint(valor)\n\n\"\"\" Ejemplos tipos complejos \"\"\"\n\n\ndef pasaje_referencia_1(valor: list):\n    valor.append(\"copa\")\n\n\nvalor = [\"America\", \"arg\"]\n\npasaje_referencia_1(valor)\nprint(valor)\n\n\ndef pasaje_referencia_2(valor: set):\n    valor.add(\"copas\")\n\n\nvalor = {\"America\", \"arg\"}\n\npasaje_referencia_2(valor)\nprint(valor)\n\n\ndef pasaje_referencia_1(valor: list):\n    valor.append(\"copa\")\n\n\nvalor = [\"America\", \"arg\"]\n\npasaje_referencia_1(valor)\nprint(valor)\n\n\ndef pasaje_referencia_3(valor: dict):\n    valor[\"nueva llave\"] = \"nuevo valor\"\n\n\nvalor = {\"America\": \"arg\"}\n\npasaje_referencia_3(valor)\nprint(valor)\n\n\"\"\" Lo que esta pasando es que cuando usamos tipos de datos 'primitivos' o simples, se le pasa una copia del valor\n    que tiene la variable pero cuando pasamos los tipos de datos complejos como listas, sets, diccionarios u objetos\n    le pasamos la direccion de memoria donde se aloja esa variable.  \"\"\"\n\n\"\"\" * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como\n * variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime\n *   el valor de las variables originales y las nuevas, comprobando que se ha invertido\n *   su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */ \"\"\"\n\n\ndef programa_valor(value_param1, value_param2):\n    aux = value_param1\n    value_param1 = value_param2\n    value_param2 = aux\n\n    return value_param1, value_param2\n\n\ndef programa_referencia(ref_param1, ref_param2):\n    aux = ref_param1 # copio la direccion de memoria en aux \n    ref_param1 = ref_param2 # ahora los dos paramentros apuntan a la misma direccion de memoria\n    ref_param2 = aux # hago que el param 2 apunte a la direccion de aux que era la de param 1\n\n    return ref_param1, ref_param2\n\n\nvar_1 = 5\nvar_2 = \"lucas\"\n\nvar_3, var_4 = programa_valor(var_1, var_2)\n\nprint(var_1, var_2)\nprint(var_3, var_4)\n\n\nvar_5 = [\"lista\",\"valor\"]\nvar_6 = {\"set\",\"valor\"}\n\nvar_7, var_8 = programa_valor(var_5, var_6)\n\nprint(var_5, var_6)\nprint(var_7, var_8)\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/Lumanet.py",
    "content": "# POR VALOR\n# Asignación por valor con enteros (números inmutables)\na = 5\nb = a\nb = 10\nprint(a)  # Esto imprimirá 5, porque 'a' y 'b' son independientes\n\n# Asignación por valor con cadenas (inmutables)\nstr1 = \"Hola\"\nstr2 = str1\nstr2 = \"Mundo\"\nprint(str1)  # Esto imprimirá \"Hola\", porque 'str1' y 'str2' son independientes\n\n# POR REFERENCIA\n# Asignación por referencia con listas (mutables)\nlista1 = [1, 2, 3]\nlista2 = lista1\nlista2.append(4)\nprint(lista1)  # Esto imprimirá [1, 2, 3, 4], porque 'lista1' y 'lista2' referencian al mismo objeto\n\n# Asignación por referencia con diccionarios (mutables)\ndict1 = {'a': 1, 'b': 2}\ndict2 = dict1\ndict2['c'] = 3\nprint(dict1)  # Esto imprimirá {'a': 1, 'b': 2, 'c': 3}, porque 'dict1' y 'dict2' referencian al mismo objeto\n\n# FUNCIONES CON PARÁMETROS POR VALOR\ndef modificar_valor(x): # x es un parámetro por valor\n    x = 10\n    print(f\"Valor de x dentro de la función: {x}\") # Esto imprimirá 10\n\na = 5\nmodificar_valor(a) # Llamamos a la función con 'a' como argumento\nprint(f\"Valor de a fuera de la función: {a}\") # Esto imprimirá 5\n\n# FUNCIONES CON PARÁMETROS POR REFERENCIA\ndef modificar_lista(lista): # lista es un parámetro por referencia\n    lista.append(4) # Modificamos la lista\n    print(f\"Lista dentro de la función: {lista}\") # Esto imprimirá [1, 2, 3, 4]\n\nmi_lista = [1, 2, 3]\nmodificar_lista(mi_lista) # Llamamos a la función con 'mi_lista' como argumento\nprint(f\"Lista fuera de la función: {mi_lista}\") # Esto imprimirá [1, 2, 3, 4]\n\n\ndef modificar_lista_sin_cambiar_original(lista): # lista es un parámetro por referencia\n    lista = lista.copy() # Creamos una copia de la lista\n    lista.append(4) # Modificamos la lista\n    print(f\"Lista dentro de la función: {lista}\") # Esto imprimirá [1, 2, 3, 4]\n\nmi_lista = [1, 2, 3]\nmodificar_lista_sin_cambiar_original(mi_lista) # Llamamos a la función con 'mi_lista' como argumento\nprint(f\"Lista fuera de la función: {mi_lista}\") # Esto imprimirá [1, 2, 3]\n\n\"\"\"\nCrea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n- Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n  Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n  se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n  variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n  Comprueba también que se ha conservado el valor original en las primeras.\n\"\"\"\n\ndef intercambiar_por_valor(x, y):\n    x, y = y, x # Intercambiamos los valores\n    return x, y # Retornamos los nuevos valores\n\na = 10\nb = 20\n\nnuevo_a, nuevo_b = intercambiar_por_valor(a, b) # Llamamos a la función con 'a' y 'b' como argumentos\n\nprint(f\"Valores originales: a = {a}, b = {b}\") # Esto imprimirá \"Valores originales: a = 10, b = 20\"\nprint(f\"Nuevos valores: nuevo_a = {nuevo_a}, nuevo_b = {nuevo_b}\") # Esto imprimirá \"Nuevos valores: nuevo_a = 20, nuevo_b = 10\"\n\ndef intercambiar_por_referencia(lista1, lista2):\n    lista1, lista2 = lista2.copy(), lista1.copy() # Intercambiamos las listas creando copias\n    return lista1, lista2 # Retornamos las nuevas listas\n\nlista_a = [1, 2, 3]\nlista_b = [4, 5, 6]\n\nnueva_lista_a, nueva_lista_b = intercambiar_por_referencia(lista_a, lista_b) # Llamamos a la función con 'lista_a' y 'lista_b' como argumentos\n\nprint(f\"Listas originales: lista_a = {lista_a}, lista_b = {lista_b}\")\nprint(f\"Nuevas listas: nueva_lista_a = {nueva_lista_a}, nueva_lista_b = {nueva_lista_b}\")\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/Maanghel.py",
    "content": "\"\"\"\nEJERCICIO:\n- Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n    su tipo de dato.\n- Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n    \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n(Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n\nDIFICULTAD EXTRA (opcional):\nCrea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n- Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n    parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n    se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n    variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n    Comprueba también que se ha conservado el valor original en las primeras.\n\"\"\"\n\n# asignacion \"por valor\", los tipos de datos primitivos en Python se asignan por valor\nmy_int = 10\nmy_string = \"Hola\"\nmy_float = 3.14\nmy_bool = True\nmy_copy_int = my_int\nmy_copy_string = my_string\nmy_copy_float = my_float\nmy_copy_bool = my_bool\n\n# asignacion \"por referencia, los tipos de datos compuestos en Python se asignan por referencia\"\nmy_list = [1, 2, 3]\nmy_dict = {\"a\": 1, \"b\": 2}\nmy_set = {1, 2, 3}\nmy_list_ref = my_list\nmy_dict_ref = my_dict\nmy_set_ref = my_set\n\n# Funciones con datos por valor\ndef modify_value(value):\n    value += 10\n    return value\n\n# Funciones con datos por referencia\ndef modify_reference(ref):\n    ref.append(4)\n    return ref\n\n# Prueba de funciones con datos por valor\nprint(\"Antes de modificar por valor:\")\nprint(f\"my_copy_int: {my_copy_int}\")\nmy_copy_int = modify_value(my_copy_int)\nprint(\"Después de modificar por valor:\")\nprint(f\"my_copy_int: {my_copy_int}\")\n\n# Prueba de funciones con datos por referencia\nprint(\"\\nAntes de modificar por referencia:\")\nprint(f\"my_list_ref: {my_list_ref}\")\nmy_list_ref = modify_reference(my_list_ref)\nprint(\"Después de modificar por referencia:\")\nprint(f\"my_list_ref: {my_list_ref}\")\n\n# EXTRA\n\n# Función para intercambiar valores por valor\ndef swap_by_value(copy_a, copy_b):\n    \"\"\"\n    Intercambia los valores de dos variables primitivas (por valor).\n    No afecta las variables originales fuera de la función.\n    \"\"\"\n    copy_a, copy_b = copy_b, copy_a\n    return copy_a, copy_b\n\n# Función para intercambiar valores por referencia\ndef swap_by_reference(ref_a, ref_b):\n    \"\"\"\n    Intercambia los primeros elementos de dos listas (por referencia).\n    Afecta las listas originales fuera de la función.\n    \"\"\"\n    ref_a[0], ref_b[0] = ref_b[0], ref_a[0]\n    return ref_a, ref_b\n\n# Intercambio de valores por valor\nfirst_num = 1\nsecond_num = 2\nnew_first_num, new_second_num = swap_by_value(first_num, second_num)\nprint(\"\\nVariables originales:\")\nprint(f\"{first_num}\\n{second_num}\")\nprint(\"Nuevas variables:\")\nprint(f\"{new_first_num}\\n{new_second_num}\")\n\n# Intercambio de valores por referencia\nfirst_list = [1, 2]\nsecond_list = [3, 4]\nnew_first_list, new_second_list = swap_by_reference(first_list, second_list)\nprint(\"\\nVariables originales:\")\nprint(f\"{first_list}\\n{second_list}\")\nprint(\"Nuevas variables:\")\nprint(f\"{new_first_list}\\n{new_second_list}\")"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/MarcosE-FerretoE.py",
    "content": "\"\"\"EJERCICIO\"\"\"\n\n\"\"\"\"Tipos simples: Se pasan por valor, se crea una copia independiente al modificar.\n    Tipos compuestos: Se pasan por referencia, se modifica la variable original al cambiar la copia.\"\"\"\n\n# Asignación por valor con enteros\n\nmy_number = 50\nmy_two_number = my_number\n# Modifica y no afecta a la original\nmy_two_number = 34\n\nprint(f\"My first number is: {my_number}\")\nprint(f\"My second number is: {my_two_number}\")\n\n# Asignación por valor con flotantes\n\nmy_float = 3.14\nmy_two_float = my_float\n# Modifica y no afecta a la original\nmy_two_float = 2.71\n\nprint(f\"My first float is: {my_float}\")\nprint(f\"My second float is: {my_two_float}\")\n\n# Asignación por valor con cadenas\n\nmy_string = \"Sistema\"\nmy_two_string = my_string\n# Modifica y no afecta a la original\nmy_two_string = \"Operativo\"\n\nprint(f\"My first string is: {my_string}\")\nprint(f\"My second string is: {my_two_string}\")\n\n# Asignación por referencia con listas\n\nmy_list = [1, 1, 2, 3, 5, 8, 13]\ncopy_list = my_list\n# Modificar y sí afecta a la original\ncopy_list.append(4)\n\nprint(f\"My list is: {my_list}\")\nprint(f\"My copy list is: {copy_list}\")\n\n# Asignación por referencia con diccionarios\n\nmy_diccionario = {\"name\": \"María\", \"age\": 17}\ncopy_diccionario = my_diccionario\n# Modificar y sí afecta a la original\ncopy_diccionario[\"age\"] = \"25\"\n\nprint(f\"My dictionary is: {my_diccionario}\")\nprint(f\"My copy dictionary is: {copy_diccionario}\")\n\n\"\"\"\"Variables por valor: Se crea una copia independiente al pasarlas a una función. Modificar la copia no afecta a la variable original.\n    Variables por referencia: Se modifica la variable original al pasarla a una función y modificarla dentro de la misma.\"\"\"\n\n# Asignación por valor en funciones\n\n\ndef multiply_number(number: int):\n    number *= 2\n\n\nn = 10\nmultiply_number(n)\nprint(f\"My multiply_number is: {n}\")\n\n# Asignación por referencia en funciones\n\n\ndef multiply_numbers(numbers: list):\n    for i, n in enumerate(numbers):\n        numbers[i] *= 2\n\n\nns = [1, 5, 10]\nmultiply_numbers(ns)\nprint(f\"My multiply_numbers is: {ns}\")\n\n\"\"\"DIFICULTAD EXTRA\"\"\"\n# Por valor\n\n\ndef exchange_value(value_a: int, value_b: int):\n    temp = value_a\n    value_a = value_b\n    value_b = temp\n    return value_a, value_b\n\n\nmy_number_a = 10\nmy_number_b = 20\n\nnew_a, new_b = exchange_value(my_number_a, my_number_b)\n\nprint(f\"Original value a: {my_number_a}\")\nprint(f\"Original value b: {my_number_b}\")\n\nprint(f\"New a: {new_a}\")\nprint(f\"New b: {new_b}\")\n\n# Por referencia\n\n\ndef exchange_reference(value_a: list, value_b: list) -> tuple:\n    temp = value_a\n    value_a = value_b\n    value_b = temp\n    return value_a, value_b\n\n\nmy_number_c = [10, 20]\nmy_number_d = [30, 40]\n\nnew_c, new_d = exchange_reference(my_number_c, my_number_d)\n\nprint(f\"Original value c: {my_number_c}\")\nprint(f\"Original value d: {my_number_d}\")\n\nprint(f\"New c: {new_c}\")\nprint(f\"New d: {new_d}\")\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/MirandaYuber.py",
    "content": "\"\"\"\nValor y referencia\n\"\"\"\n# Los tipos de datos primitivos\n# Asignación de variables por valor\nmy_int_1 = 1\nmy_int_2 = my_int_1\nmy_int_2 = 3\n\nprint(my_int_1)\nprint(my_int_2)\n\n# Los tipos de datos que no son primitivos\n# Asignación por  referencia\nmy_list_1 = [1, 2]\nmy_list_2 = my_list_1\nmy_list_2.append(3)\n\nprint(my_list_1)\nprint(my_list_2)\n\n\n# Función por valor\n\ndef valor(my_int):\n    my_int = 12\n    print(my_int)\n\n\nmy_int_3 = 4\nvalor(my_int_3)\nprint(my_int_3)\n\n\n# Función por referencia\n\ndef referencia(my_list):\n    my_list.append(11)\n    print(my_list)\n\n\nmy_list_3 = [22, 23]\nreferencia(my_list_3)\nprint(my_list_3)\n\n\"\"\"\nExtra\n\"\"\"\n\n\ndef por_valor(value_1: int, value_2: int) -> tuple:\n    temp = value_1\n    value_1 = value_2\n    value_2 = temp\n    return value_1, value_2\n\n\nmy_int_4 = 4\nmy_int_5 = 5\nmy_int_6, my_int_7 = por_valor(my_int_4, my_int_5)\n\nprint(my_int_4)\nprint(my_int_5)\nprint(my_int_6)\nprint(my_int_7)\n\n\ndef por_referencia(value_1: list, value_2: list) -> tuple:\n    temp = value_1\n    value_1 = value_2\n    value_2 = temp\n    return value_1, value_2\n\n\nmy_list_4 = [4, 5]\nmy_list_5 = [6, 7]\nmy_list_6, my_list_7 = por_referencia(my_list_4, my_list_5)\n\nprint(my_list_4)\nprint(my_list_5)\nprint(my_list_6)\nprint(my_list_7)\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/NeosV.py",
    "content": "# variable por valor \n\"\"\"\nx = 10\ndef funcion(entrada):\n    entrada = 0\n    print(entrada)\n\nfuncion(x)\n\nprint (f\"se imprime 10 ya que python trata los int como variable por valor y no lo modifica a pesar de la funcion {x}\") \n\n# variable por referencia\n\ny = [10 , 20, 30]\ndef funcion_2(entrada):\n      entrada.append(40)\n           \nfuncion_2(y)\n\nprint (f\"esta lista si se modifica ya que la lista python la toma como una variable por referencia{y}\")\n\"\"\"\n\n# Ejercicio Extra\n\n\nvalor_1 = 0\nvalor_2 = 1\n\n\ndef funcionvalor(parametro_1, parametro_2):\n\n  holder = parametro_2\n  parametro_2 = parametro_1\n  parametro_1 = holder\n  print(parametro_1, parametro_2)\n\n  return parametro_1, parametro_2\n\n\nvarnew_1,varnew_2 = funcionvalor(valor_1,valor_2)\n\nprint(f\"{varnew_1, varnew_2} es el return de la funcion, las variables originales son: {valor_1, valor_2}\")\n\n\n\n\nrefer_1 = [1,2,3,4]\nrefer_2 = [5,6,7,8]\n\ndef funcionreferen(parametro1,parametro2):\n \n  holder = parametro2\n  parametro2 = parametro1\n  parametro1 = holder\n\n  \n  return parametro1, parametro2\n\n\nvarnew_3, varnew_4 = funcionreferen(refer_1,refer_2) \n\nfuncionreferen(refer_1, refer_2)\n\nprint(f\"{varnew_3, varnew_4} es el return de la funcion, las variables originales son: {refer_1, refer_2}\")\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/Nicoheguaburu.py",
    "content": "#Valor y referencia\n\n\n\n# tipos de dato por valor\n\nmi_entero_a = 10\nmi_entero_b = 20\n\nmi_entero_a = mi_entero_b\n\nprint(mi_entero_a)\nprint(mi_entero_b)\n\n\n#tipos de dato por referencia\n\nmi_lista_a = [10, 20]\nmi_lista_b = [30, 40]\n\nmi_lista_a = mi_lista_b #cambio de direccion de memoria\n\nmi_lista_a.append(50)\n\nprint(mi_lista_a)\nprint(mi_lista_b)\n\n\n# Funciones con datos por valor\n\ndef mi_entero_funcion(mi_entero: int):\n    mi_entero = 20\n    print(mi_entero)\n\n\nmi_entero_funcion(55)\n\n\n#funciones de datos por referencia\n#funciona como un puntero al igualar valores lo que hace es que tengan el mismo valor de memoria\n\ndef mi_lista_funcion(mi_lista: list):\n    mi_lista.append(4)\n    mi_lista_d = mi_lista\n    mi_lista_d.append(5)\n    print(mi_lista_d)\n    print(mi_lista)\n\nmi_lista_c = [1,2,3]\nmi_lista_funcion(mi_lista_c)\nprint(mi_lista_c)\n\n\n\n#DIFICULTAD EXTRA\n\n#parametros por valor\nvalor_a = 30\nvalor_b = 50\n\n#parametros por referencia\nreferencia_a = [1,2,3,4]\nreferencia_b = [5,6,7,8]\n\n#programa de valor\ndef programa_valor():\n    def cambiar_valores (param_a, param_b):\n        guardar_valor = param_a\n        param_a = param_b\n        param_b = guardar_valor\n        return(param_a , param_b)\n\n\n    resultados = cambiar_valores(valor_a, valor_b)\n    valor_1 = resultados[0]\n    valor_2 = resultados[1]\n\n    print(valor_a)\n    print(valor_b)\n    print(valor_1)\n    print(valor_2)\n\nprograma_valor()\n\n    \n#programa de referencia\ndef programa_referencia():\n    def cambiar_referencia (param_a, param_b):\n        guardar_valor = param_a\n        param_a = param_b\n        param_b = guardar_valor\n        return(param_a , param_b)\n\n\n    resultados = cambiar_referencia(referencia_a, referencia_b)\n    referencia_1 = resultados[0]\n    referencia_2 = resultados[1]\n\n    print(referencia_a)\n    print(referencia_b)\n    print(referencia_1)\n    print(referencia_2)\n\nprograma_referencia()\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/Nicojsuarez2.py",
    "content": "'''\n# #05 VALOR Y REFERENCIA\n> #### Dificultad: Fácil | Publicación: 29/01/24 | Corrección: 05/02/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n'''"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/NightAlchemist.py",
    "content": "import copy\n\n# Assignment by value (immutable types)\na = 10\nb = a\nb = 20\nprint(\"a:\", a)  # Output: a: 10\nprint(\"b:\", b)  # Output: b: 20\n\n# Assignment by reference (mutable types)\nlist1 = [1, 2, 3]\nlist2 = list1\nlist2.append(4)\nprint(\"list1:\", list1)  # Output: list1: [1, 2, 3, 4]\nprint(\"list2:\", list2)  # Output: list2: [1, 2, 3, 4]\n\n# To avoid reference assignment with mutable types, use copy\nlist3 = [1, 2, 3]\nlist4 = copy.copy(list3)\nlist4.append(4)\nprint(\"list3:\", list3)  # Output: list3: [1, 2, 3]\nprint(\"list4:\", list4)  # Output: list4: [1, 2, 3, 4]\n\n# Function demonstrating assignment by value\ndef modify_value(x):\n    x = 20\n    print(\"Inside modify_value, x:\", x)  # Output: x: 20\n\n# Function demonstrating assignment by reference\ndef modify_list(lst):\n    lst.append(4)\n    print(\"Inside modify_list, lst:\", lst)  # Output: lst: [1, 2, 3, 4]\n\n# Assignment by value\na = 10\nprint(\"Before modify_value, a:\", a)  # Output: a: 10\nmodify_value(a)\nprint(\"After modify_value, a:\", a)  # Output: a: 10\n\n# Assignment by reference\nlist1 = [1, 2, 3]\nprint(\"Before modify_list, list1:\", list1)  # Output: list1: [1, 2, 3]\nmodify_list(list1)\nprint(\"After modify_list, list1:\", list1)  # Output: list1: [1, 2, 3, 4]\n\n'''\nExtra\n'''\n\n# Function to swap values (immutable types)\ndef swap_values(x, y):\n    return y, x\n\n# Function to swap references (mutable types)\ndef swap_references(lst1, lst2):\n    return lst2, lst1\n\n# Immutable types\na = 5\nb = 10\nprint(\"Original a:\", a)  # Output: a: 5\nprint(\"Original b:\", b)  # Output: b: 10\nnew_a, new_b = swap_values(a, b)\nprint(\"Swapped new_a:\", new_a)  # Output: new_a: 10\nprint(\"Swapped new_b:\", new_b)  # Output: new_b: 5\nprint(\"After swap, original a:\", a)  # Output: a: 5\nprint(\"After swap, original b:\", b)  # Output: b: 10\n\n# Mutable types\nlist1 = [1, 2, 3]\nlist2 = [4, 5, 6]\nprint(\"Original list1:\", list1)  # Output: list1: [1, 2, 3]\nprint(\"Original list2:\", list2)  # Output: list2: [4, 5, 6]\nnew_list1, new_list2 = swap_references(list1, list2)\nprint(\"Swapped new_list1:\", new_list1)  # Output: new_list1: [4, 5, 6]\nprint(\"Swapped new_list2:\", new_list2)  # Output: new_list2: [1, 2, 3]\nprint(\"After swap, original list1:\", list1)  # Output: list1: [1, 2, 3]\nprint(\"After swap, original list2:\", list2)  # Output: list2: [4, 5, 6]"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/Nightblockchain30.py",
    "content": "'''\n\n* EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n\n'''\n\n\n\n# VARIABLES POR VALOR\n# Ya que los numericos son inmutables entonces no se cambiaran sus valores al asignarlo a otra variable, se creara una copia de ellas.\na = 400\nb = a\nb += 5\nprint(a)\nprint(b)\n\n# VARIABLES POR REFERENCIA:\n# Ya que las lista son tipos de datos asignados por referencia podran ser modificados luego de haber sido asignados a otra variable (tipo de dato mutable)\nlista_a = [30, 400, 100]\nlista_b = lista_a # Se comparte la referencia\n## > Verificamos que no tienen el mismo id con la funcion id()\nprint(f\"Los enteros a y b NO comparten la misma referencia al objeto, id(int_a): {id(a)} ,id(int_b): {id(lista_b)} (NO tienen el mismo id)\")\n\nlista_b.append(60)\nprint(lista_a, lista_b)\n## > Para verificar que la lista_a y lista_b comparten la misma referencia del objeto podemos usar la funcion id()\nprint(f\"Las listas a y b comparten la misma referencia al objeto, id(lista_a): {id(lista_a)} ,id(lista_b): {id(lista_b)} (tienen el mismo id)\")\n\n\n\n# EJEMPLOS VARIABLES POR VALOR\n##  TYPE:int\nnum = 20\n\ndef doblar_valor(numero):\n    numero*=2\n    return numero\n\nprint(num)\nprint(doblar_valor(num))\n\n## TYPE:str\nname= \"Pedro\"\n\ndef rename(nombre):\n    nombre += \" López\"\n    return nombre\n\nprint(f\"El nombre fuera de la funcion es:{name} y el nombre modificado por la función es:{rename(name)}\")\n\n## TYPE:bool\nverdad = True\nmentira = False\ndef doblar_valor(verdad):\n    verdad *=2\n    return verdad\n\nprint(f\"El valor bool inicial verdadero '{verdad}' no se ha modificado pero dentro de la función si: {doblar_valor(verdad)}\")\nprint(f\"El valor bool inicial falso '{mentira}' no se ha modificado pero dentro de la función si: {doblar_valor(mentira)}\")\n\n## TYPE:tuple\nvariable_tupla = (\"Hola\", True, 59, \"Mundo\")\ndoblar_valor(variable_tupla)\nprint(f\"Al ser una estructura de datos inmutables una vez declara no podrá ser modificada:{variable_tupla} id({id(variable_tupla)})\")\n\n# EJEMPLOS VARIABLES POR REFERENCIA\n## TYPE:list\nvariable_lista = [2,4,-5]\ndoblar_valor(variable_lista) # comparten el mismo id\nprint(f\"Como podemos observar al tener el tipo de dato list() y ser mutable el valor de la lista ha sido actualizado: id({id(variable_lista)}) valor({variable_lista})\")\n\n##TYPE: dict\nvariable_dict={\n    \"nombre\":\"Pedro\",\n    \"edad\":30,\n    \"profesion\":\"fontanero\"\n}\n\ndef agregar_sexo_masculino(variable:dict):\n    variable.update({\"sexo\":\"hombre\"})\n    return variable\n\nagregar_sexo_masculino(variable_dict)\nprint(f\"Como podemos observar al tener el tipo de dato dict() y ser mutable hemos añadido un nuevo par clave:valor --> {variable_dict}\")\n\n\n## TYPE:set\n\nvariable_conjunto = {True, \"Moure\", \"❤️\"}\n\ndef agregar_elemento_unico(elemento:set):\n    elemento.add(\"Gracias por el supp!\")\n    return elemento\n\nagregar_elemento_unico(variable_conjunto)\nprint(f\"Como podemos observar al tener el tipo de dato set() y ser mutable hemos podido agregar un nuevo dato de tipo string --> {variable_conjunto}\")\n\n\"\"\"DIFICULTAD EXTRA:\"\"\"\n# Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\nvariable_valor1 = 400\nvariable_valor2 = \"'Hola, Mundo!'\"\nvariable_referencia1 = [30, 600, 81, 20]\nvariable_referencia2 = {True, \"'Soy Un conjunto'\", 20}\n\ndef modificar_variable_valor(valor1,valor2):\n    valor1,valor2 = valor2,valor1\n    print(f\"Valor 1: \",valor1)\n    print(f\"Valor 2: \",valor2)\n    return valor1,valor2\n\n\ndef modificar_variable_referencia(referencia1,referencia2):\n    referencia1,referencia2 = referencia2,referencia1\n    print(f\"Valor Referencia 1: \",referencia1)\n    print(f\"Valor Referencia 2: \",referencia2)\n    return referencia1,referencia2\n\nresultado1,resultado2 = modificar_variable_valor(variable_valor1,variable_valor2)\n\nresultado3,resultado4 = modificar_variable_referencia(variable_referencia1,variable_referencia2)\n\nprint(\"<<<< RESULTADOS >>>>\")\nprint(f\"ANTES:{variable_valor1} | AHORA:{resultado1}\")\nprint(f\"ANTES:{variable_valor2} | AHORA:{resultado2}\")\n\nprint(f\"ANTES:{variable_referencia1} | AHORA:{resultado3}\")\nprint(f\"ANTES:{variable_referencia2} | AHORA:{resultado4}\")\n\n\n\n\n    \n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/Oniricoh.py",
    "content": "########################################################################\n# Paso por copia o valor\n########################################################################\ndef doblar_valor(numero):\n    numero *= 2\n\nn = 10\ndoblar_valor(n)\nprint(n)  # Salida: 10\n\n# Ejemplo con números (tipo de dato inmutable)\na = 5\nb = a  # Asignación por valor\nb = 10\nprint(a)  # Imprimirá 5\n\n# Ejemplo con cadenas (tipo de dato inmutable)\ncadena1 = \"Hola\"\ncadena2 = cadena1  # Asignación por valor\ncadena2 = \"Adiós\"\nprint(cadena1)  # Imprimirá \"Hola\"\n\n\n\n\n########################################################################\n# Paso por referencia\n########################################################################\ndef doblar_valores(numeros):\n    for i, n in enumerate(numeros):\n        numeros[i] *= 2\n\nns = [10, 50, 100]\ndoblar_valores(ns)\nprint(ns)  # Salida: [20, 100, 200]\n\n# Para evitar modificacion hacer copia\ndef doblar_valores(numeros):\n    for i, n in enumerate(numeros):\n        numeros[i] *= 2\n\nns = [10, 50, 100]\ndoblar_valores(ns[:])  # Una copia al vuelo de la lista con [:]\nprint(ns)  # Salida: [10, 50, 100]\n\n# Ejemplo con listas (tipo de dato mutable)\nlista1 = [1, 2, 3]\nlista2 = lista1  # Asignación por referencia\nlista2[0] = 99\nprint(lista1)  # Imprimirá [99, 2, 3]\n\n# Ejemplo con diccionarios (tipo de dato mutable)\ndiccionario1 = {'a': 1, 'b': 2}\ndiccionario2 = diccionario1  # Asignación por referencia\ndiccionario2['a'] = 99\nprint(diccionario1)  # Imprimirá {'a': 99, 'b': 2}\n\n\n\n\n########################################################################\n# Modificación de Tipos Simples y Compuestos\n########################################################################\ndef doblar_valor(numero):\n    return numero * 2\n\nn = 10\nn = doblar_valor(n)\nprint(n)  # Salida: 20\n\n########################################################################\n# DIFICULTAD EXTRA\n########################################################################\np1_value = 1\np2_value = \"Hola\"\n\np1_ref = [1, 2, 3, 4]\np2_ref = {\"Edad\":34, \"Genero\":\"Varon\"}\n\ndef prog1(v1, v2):\n    v1 = p2_value\n    v2 = p1_value\n    return v1, v2\n\n\n\ndef prog2(r1, r2):\n    r1 = p2_ref\n    r2 = p1_ref\n    return r1, r2\n\n\nx1, x2 = prog1(p1_value, p2_value)\nprint(f\"\\nLas variables por valor originales son: {p1_value} y {p2_value}\")\nprint(f\"Las variables por valor nuevas son: {x1} y {x2}\")\n\n\n\n\ny1, y2 = prog2(p1_ref, p2_ref)\nprint(f\"\\nLas variables por valor originales son: {p1_ref} y {p2_ref}\")\nprint(f\"Las variables por valor nuevas son: {y1} y {y2}\")\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/Paprikaistkrieg.py",
    "content": "# Valor y Referencia\n\n\"\"\"\nEn Python, los tipos de datos se dividen en dos categorías principales: tipos mutables e inmutables.\n\nLos tipos mutables son aquellos que pueden ser modificados después de su creación. Ejemplos de tipos mutables en Python son las listas y los diccionarios.\n\nPor otro lado, los tipos inmutables son aquellos que no pueden ser modificados una vez que han sido creados. Ejemplos de tipos inmutables en Python son las tuplas y las cadenas de texto.\n\n\nEs importante entender la diferencia entre estos dos tipos de datos, ya que afecta cómo se manejan en la memoria y cómo se comportan en diferentes situaciones.\n\nCuando se asigna un valor a una variable, Python maneja la asignación de diferentes maneras dependiendo de si el valor es mutable o inmutable.\n\n# Para los tipos inmutables, como las tuplas y las cadenas de texto, cuando se asigna un valor a una variable, Python crea una nueva copia del valor en la memoria. Esto significa que si se modifica la variable original, la copia no se verá afectada.\n#Por ejemplo:\n#Asignación de una cadena de texto (tipo inmutable)\n\"\"\"\noriginal_string = \"Hola\" # String es inmutable\ncopied_string = original_string #Asignación por valor (se crea una copia)\n\n#ejemplos de inmutable o paso por valor\n\n\nmy_int_a = 10\nmy_int_b = my_int_a  # Asignación por valor (se crea una copia)\nmy_int_a = 30  # Modificación de my_int_a\nprint(my_int_a)  # Imprime 30 (valor modificado)\nprint(my_int_b)  # Imprime 10 (valor original)\n\nmy_int_a = 10\nmy_int_b = my_int_a\nprint(id(my_int_a))  # ID de 10\nprint(id(my_int_b))  # Mismo ID ➜ misma referencia al valor 10\n\nmy_int_a = 30\nprint(id(my_int_a))  # Nuevo ID ➜ nueva referencia al valor 30\nprint(id(my_int_b))  # ID de 10 (sin cambios)\n\n\n\n\n#ejemplo de mutable o paso por referencia\n\n\"\"\"\nEn Python, los tipos mutables como list, dict, set y objetos personalizados se pasan por referencia. Esto significa que cuando los usas como argumentos en una función, \nno se copia el valor, sino que se pasa una referencia al mismo objeto en memoria. \nPor lo tanto, si lo modificas dentro de la función, también se modifica fuera\n\"\"\"\n\nmy_list_a = [1, 2, 3]\nmy_list_b = my_list_a  # Asignación por referencia (misma lista en memoria)\nmy_list_b.append(4)  # Modificación de my_list_b\nprint(my_list_a)  # Imprime [1, 2, 3, 4] (lista modificada)\nprint(my_list_b)  # Imprime [1, 2, 3, 4] (lista también modificada)\n\n\n# funciones de datos inmutables o paso por valor\n\n\ndef modificar_texto(texto): #aqui definimos la funcion, texto es un parametro, modificar_texto es el nombre de la funcion\n    texto = texto.upper()  # Convierte a mayúsculas (solo dentro de la función, no afecta la variable original)\n    print(\"Dentro de la función:\", texto)  #imprime el texto modificado dentro de la funcion\n\nmensaje = \"hola mundo\" # Variable original\nmodificar_texto(mensaje) # Llamada a la función con la variable original\nprint(\"Fuera de la función:\", mensaje) #imprime la variable original fuera de la funcion \n\n\nmensaje = \"hola mundo\" # Variable original (aqui es donde se asigna el valor a la variable y este es inmutable)\nprint(\"ID fuera:\", id(mensaje)) #imprime el id de la variable original\nmodificar_texto(mensaje) # Llamada a la función con la variable original\n\ndef modificar_texto(texto): #aqui definimos la funcion, texto es un parametro, modificar_texto es el nombre de la funcion\n    print(\"ID dentro:\", id(texto)) #imprime el id del parametro texto (aqui se puede ver que es igual al id de la variable original, ya que se pasa por valor)\n    texto = texto.upper() # Convierte a mayúsculas (solo dentro de la función, no afecta la variable original)\n    print(\"ID modificado:\", id(texto)) #imprime el id del texto modificado (aqui se puede ver que es diferente al id del parametro texto, ya que se creo una nueva copia en memoria debido al cambio en el valor)\n\nprint(modificar_texto(mensaje)) # Llamada a la función con la variable original\n\n#funciones de datos mutables o paso por referencia\n\ndef modificar_lista(lista): #aqui definimos la funcion, lista es un parametro, modificar_lista es el nombre de la funcion\n    lista.append(4)  # Agrega un elemento a la lista (esto afecta la variable original)\n    print(\"Dentro de la función:\", lista) #imprime la lista modificada dentro de la funcion\nmi_lista = [1, 2, 3] # Variable original\nmodificar_lista(mi_lista) # Llamada a la función con la variable original\nprint(\"Fuera de la función:\", mi_lista) #imprime la variable original fuera de la funcion (aqui se puede ver que si se modifico la variable original, ya que es mutable)\nprint(\"ID fuera:\", id(mi_lista)) #imprime el id de la variable original\nmodificar_lista(mi_lista) # Llamada a la función con la variable original\ndef modificar_lista(lista): #aqui definimos la funcion, lista es un parametro, modificar_lista es el nombre de la funcion\n    print(\"ID dentro:\", id(lista)) #imprime el id del parametro lista (aqui se puede ver que es igual al id de la variable original, ya que se pasa por referencia)\n    lista.append(4)  # Agrega un elemento a la lista (esto afecta la variable original)\n    print(\"ID modificado:\", id(lista)) #imprime el id de la lista modificada (aqui se puede ver que es igual al id del parametro lista, ya que no se creo una nueva copia en memoria debido a que no hubo un cambio en el valor)\n#Asignación de una lista (tipo mutable)\noriginal_list = [1, 2, 3] # List es mutable\ncopied_list = original_list #Asignación por referencia (se crea una referencia al mismo objeto\n# en memoria, no una copia).\n\n#mecanismos de copia\n#Para crear una copia de un objeto mutable en lugar de una referencia, puedes usar los siguientes métodos:\nimport copy\n# Usando el método copy() de la lista\ncopied_list_1 = original_list.copy()\n# Usando el módulo copy para una copia superficial\ncopied_list_2 = copy.copy(original_list)\n# Usando el módulo copy para una copia profunda (útil para listas anidadas)\ncopied_list_3 = copy.deepcopy(original_list)\n# Usando la función list() para crear una nueva lista\ncopied_list_4 = list(original_list)\n# Usando slicing para crear una nueva lista\ncopied_list_5 = original_list[:]\n# Usando la función list() para crear una nueva lista\ncopied_list_6 = list(original_list)\nprint(\"Original List ID:\", id(original_list))# Todos los IDs de las copias serán diferentes al ID de la lista original\nprint(\"Copied List 1 ID:\", id(copied_list_1))\nprint(\"Copied List 2 ID:\", id(copied_list_2))\nprint(\"Copied List 3 ID:\", id(copied_list_3))# Todos los IDs de las copias serán diferentes al ID de la lista original\nprint(\"Copied List 4 ID:\", id(copied_list_4))\nprint(\"Copied List 5 ID:\", id(copied_list_5))\nprint(\"Copied List 6 ID:\", id(copied_list_6))# Todos los IDs de las copias serán diferentes al ID de la lista original\n\nprint(\"Original List:\", original_list) #imprime la lista original\nprint(\"Copied List 1:\", copied_list_1) #imprime la copia de la lista\nprint(\"Copied List 2:\", copied_list_2) #imprime la copia de la lista\nprint(\"Copied List 3:\", copied_list_3) #imprime la copia de la lista\nprint(\"Copied List 4:\", copied_list_4) #imprime la copia de la lista            \nprint(\"Copied List 5:\", copied_list_5) #imprime la copia de la lista\nprint(\"Copied List 6:\", copied_list_6) #imprime la copia de la lista\n# Todos los valores de las copias serán iguales al valor de la lista original\n\n#como romper la referencia en una variable mutable\n#Para romper la referencia en una variable mutable y crear una nueva copia, puedes reasignar la variable a una nueva instancia del objeto mutable.\n# Por ejemplo, si tienes una lista y quieres romper la referencia, puedes hacer lo siguiente:\nmi_lista = [1, 2, 3]\nnueva_lista = mi_lista[:]  # Crea una nueva lista usando slicing\nnueva_lista.append(4)\nprint(\"Lista original:\", mi_lista)\nprint(\"Nueva lista:\", nueva_lista)\n#Salida:\n#Lista original: [1, 2, 3]\n#Nueva lista: [1, 2, 3, 4]\n#En este ejemplo, al usar slicing (mi_lista[:]), se crea una nueva lista que es una copia de mi_lista.\n# Luego, al modificar nueva_lista, la lista original mi_lista no se ve afectada.\n#Otra forma de romper la referencia es usando el método copy() o el módulo copy como se mostró anteriormente.\n# Usando el método copy()\nmi_lista = [1, 2, 3]\nnueva_lista = mi_lista.copy()  # Crea una nueva lista usando el método copy()\nnueva_lista.append(4)\nprint(\"Lista original:\", mi_lista)\nprint(\"Nueva lista:\", nueva_lista)\n\n# Usando el módulo copy para una copia superficial\nimport copy\nmi_lista = [1, 2, 3]\nnueva_lista = copy.copy(mi_lista)  # Crea una nueva lista usando copy.copy\nnueva_lista.append(4)\nprint(\"Lista original:\", mi_lista)\nprint(\"Nueva lista:\", nueva_lista)\n# Usando el módulo copy para una copia profunda (útil para listas anidadas)\n\n#Xtra: \n\nxtra1 = \"hola\"\nxtra2 = \"mundo\"\nxtra3 =  [1, 2, 3]\nxtra4 = [4, 5, 6]\n\ndef xtra_funcion(xtra, xtra_):\n    return xtra_, xtra\nnuevo1, nuevo2 = xtra_funcion(xtra1, xtra2)\nprint(\"Variables originales:\", xtra1, xtra2)\nprint(\"Nuevas variables:\", nuevo1, nuevo2)\nprint(id(xtra1), id(nuevo2)) #mismo id\nprint(id(xtra2), id(nuevo1)) #mismo id\n\ndef xtra_funcion2(xtra5, xtra6):\n    return xtra6.copy(), xtra5.copy()\nnuevo3, nuevo4 = xtra_funcion2(xtra3, xtra4)\nprint(\"Variables originales:\", xtra3, xtra4)\nprint(\"Nuevas variables:\", nuevo3, nuevo4)\nprint(id(xtra3), id(nuevo3)) #diferente id\nprint(id(xtra4), id(nuevo4)) #diferente id"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/Paula2409.py",
    "content": "\"\"\" \n/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n */\n\"\"\"\n\"\"\" \n    Paso por valor: Se crea una copia local de la variable dentro de la función.\n    Paso por referencia: Se maneja directamente la variable, los cambios realizados dentro de la función le afectarán también fuera.\n\n    Los tipos simples se pasan por valor: Enteros, flotantes, cadenas, lógicos...\n    Los tipos compuestos se pasan por referencia: Listas, diccionarios, conjuntos...\n\n\"\"\"\n\n# Paso por valor\na = 5\nb = 10\nprint(f'a={a}')\nprint(f'b={b}')\nprint(f'La direccion de memoria de a = {id(a)}')\nprint(f'La direccion de memoria de b = {id(b)}')\nb = a \nprint(f'Valor de b luego de igualar a \"a\" = {b}')\nprint(f'La direccion de memoria de a = {id(a)}')\nprint(f'La direccion de memoria de b luego de igualar a \"a\" = {id(b)}')\na += 2\nprint(f'Valor de a luego de sumar 2 = {a}')\nprint(f'La direccion de memoria de a luego de sumar 2 = {id(a)}')\nprint(f'Valor de b luego de sumar 2 a \"a\" = {b}')\nprint(f'La direccion de memoria de b luego de sumar 2 a \"a\" = {id(b)}')\n\nb += 3\nprint(f'Valor de b luego de sumar 3 = {b}')\nprint(f'La direccion de memoria de b luego de sumar 3 = {id(b)}')\nprint()\n# Paso por referencia\nlist_a = [1,2,3]\nlist_b = [2,3,4]\nprint(f'Lista a = {list_a}')\nprint(f'Lista b = {list_b}')\nprint(f'Direccion de memoria de lista a = {id(list_a)}')\nprint(f'Direccion de memoria de lista b = {id(list_b)}')\n\nlist_b = list_a\nprint(f'Lista b = {list_b}')\nprint(f'Direccion de memoria de lista b luego de igualarla a lista a = {id(list_b)}')\n\nlist_a.append(4)\nprint(f'Lista b luego de agregar valor a lista a = {list_b}')\nprint(f'Direccion de memoria de lista b luego agregar valor a lista a = {id(list_b)}')\n\nlist_b.append(5)\nprint(f'Lista b luego de agregar valor a lista b = {list_b}')\nprint(f'Direccion de memoria de lista b luego agregar valor a lista b = {id(list_b)}')\nprint(f'Lista a luego de agregar valor a lista a y b = {list_a}')\nprint(f'Direccion de memoria de lista a luego agregar valor a lista a y b = {id(list_a)}')\n\n# Funciones con paso por valor\ndef square_number(number: int):\n    number **= 2\n    print(f'El numero elevado al cuadrado es: {number}')\n\nnumber = 5\nprint(f'Antes de la funcion: {number}')\nsquare_number(number)\nprint(f'Despues de la funcion: {number}')\n\n# Funciones con paso referencia\ndef insert_element(my_list: list):\n    my_list.append(5)\n    my_list_2 = my_list\n    print(f'Lista original luego de agregar elemento: {my_list}')\n    my_list_2.append(3)\n    print(f'Segunda lista luego de agregar elemento: {my_list_2}')\n    \nmy_list = [9]\ninsert_element(my_list)\nprint(f'Lista luego de la funcion: {my_list}')\n\n# Paso por referencia, sin cambiar valor original\ndef insert_element_copy(my_list: list):\n    print('Prueba funcion copiando lista, sin modificar la original')\n    my_list.append(5)\n    my_list_2 = my_list\n    print(f'Lista original luego de agregar elemento: {my_list}')\n    my_list_2.append(3)\n    print(f'Segunda lista luego de agregar elemento: {my_list_2}')\n    \nmy_list = [9]\ninsert_element_copy(my_list[:]) # Envio una copia de la lista\nprint(f'Lista luego de la funcion: {my_list}')\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n\"\"\"\ndef change_values(a: int,b: int):\n    a,b = b,a\n    return a,b\n\na = 1\nb = 2 \nc,d = change_values(a,b)\nprint(f'a = {a}, b = {b}, c = {c}, d = {d}')\n\ndef change_value_reference(list_a: int, list_b: int):\n    list_a, list_b = list_b, list_a\n    return list_a, list_b\n\nlist_a = [1,2,3]\nlist_b = [4,5,6]\n\nlist_c, list_d = change_value_reference(list_a,list_b)\nprint(f'lista a = {list_a}, lista b = {list_b}, lista c = {list_c}, lista d = {list_d}')"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/Pipe281.py",
    "content": "# Asignación por Valor (Enteros, Flotantes, cadenas de texto)\n# Asignación de variables \nx = 10\ny = x\n\n# Modificación de una variable\nx = 20\n\n# Imprimir variables\nprint(\"x:\", x)  # Salida: x: 20\nprint(\"y:\", y)  # Salida: y: 10 (No se modifica)\n\n# Asginación por Referencia (Listas, diccionarios, conjuntos)\n# Asignación de variables\nlista1 = [1, 2, 3]\nlista2 = lista1\n\n# Modificación de una variable \nlista1.append(4)\n\n# Imprimir variables\nprint(\"lista1:\", lista1)  # Salida: lista1: [1, 2, 3, 4] (lista1 se modifica)\nprint(\"lista2:\", lista2)  # Salida: lista2: [1, 2, 3, 4] (lista2 también se modifica)\n\n## Modificando por valor\ndef modificar_valor(numero):\n    numero += 10\n    return numero\n\nx = 5\nprint(\"Antes de llamar a la función:\", x)  # Salida: Antes de llamar a la función: 5\nmodificar_valor(x)\nprint(\"Después de llamar a la función:\",x)  # Salida: Después de llamar a la función: 5 (x no cambia)\n\nresultado = modificar_valor(x)\nprint(\"En cambio aca si se modifica el valor\",resultado)\n\n\n## Modificando por referencia\ndef modificar_lista(lista, valor):\n    lista.append(valor)\n\nmi_lista = [1, 2, 3]\nprint(\"Antes de llamar a la función:\", mi_lista)  # Salida: Antes de llamar a la función: [1, 2, 3]\n\nvalor = int(input(\"Ingrese un valor:\"))\nmodificar_lista(mi_lista, valor)\nprint(\"Después de llamar a la función:\", mi_lista) \n\n### Ejercicio Opcional ### \n\n# Modificando por valor\na = 10\nb = 20\n\ndef modificar_numeros(valor1, valor2):\n    a = valor2\n    b = valor1\n    return(a,b)\n\nprint(a,b)\nc, d = modificar_numeros(a,b)\n\nprint(a, b, c, d)\n\n# Modificando por referencia\n\nfrutas = [\"Manzana\",\"Pera\", \"Naranja\"]\nverduras = [\"Pepino\",\"Cebolla\", \"Repollo\"]\n\ndef modifica_fruta_verdura(valor1, valor2):\n    frutas.append(valor1)\n    verduras.append(valor2)\n    return(frutas, verduras)\n\nfruta_agregar = input(\"Ingrese fruta a agregar\")\nverdura_agregar = input(\"Ingrese verdura a agregar\")\nfrutas2 , verduras2 = modifica_fruta_verdura(fruta_agregar, verdura_agregar)\nprint(frutas, verduras, frutas2, verduras2)"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/Ramirofordev.py",
    "content": "# Valor y referencia\n\n# Tipos de datos por valor\n\nmy_int = 10\nmy_intb = my_int\n#my_intb = 20\nmy_int = 30\nprint(my_int)\nprint(my_intb)\n\n# Tipos de datos por referencia\n\nmy_list = [10, 20]\nmy_listb = my_list\nmy_listb.append(30)\nprint(my_list)\nprint(my_listb)\n\n# Funciones con datos por valor\n\nmy_int_c = 10\n\ndef my_int_func(my_int: int):\n    my_int = 20\n    print(my_int)\n\nmy_int_func(my_int_c)\nprint(my_int_c)\n\n# Fuciones con datos por referencia\n\nmy_list_c = [10, 20]\n\ndef my_list_func(my_list: list):\n    my_list.append(30)\n\n    my_list_d = my_list\n    my_list_d.append(40)\n\n    print(my_list)\n    print(my_list_d)\n\nmy_list_func(my_list_c)\nprint(my_list_c)\n\n# Ejercicio extra\n\n# Funcion por valor\n\nvalor1 = 5\nvalor2 = 10\n\ndef intercambio_por_valor(v1, v2):\n    tmp = 0\n    tmp = v1\n    v1 = v2\n    v2 = tmp\n    return v1, v2\n\nprint(f\"{valor1}  \\n{valor2}\")\nnuevo_valor1, nuevo_valor2 = intercambio_por_valor(valor1, valor2)\nprint(f\"{nuevo_valor1} \\n{nuevo_valor2}\")\n\n# Funcion por referencia\n\nreferencia1 = [10, 20]\nreferencia2 = [30, 40]\n\ndef intercambio_por_referencia(r1: list, r2: list):\n    tmp = r1\n    r1 = r2\n    r2 = tmp\n\n    return r1, r2\n\nnueva_referencia1, nueva_referencia2 = intercambio_por_referencia(referencia1, referencia2)\n\nprint(referencia1, referencia2)\nprint(nueva_referencia1, nueva_referencia2)\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/RicardiJulio.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n#  *   su tipo de dato.\n#  * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n#  *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n#  * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n#  * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n#  *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n#  *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n#  *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n#  *   Comprueba también que se ha conservado el valor original en las primeras.\n#  */\n\n# En python todo es un objeto, y las variables son referencia a esos objetos.\n\n# Hay dos tipos de objetos: \n# Inmutables (int, str, float, tuple) que son tratados como pasados por valor \n# Mutables (list, dict, set), que son tratados como pasados por referencia\n\n# Ejemplo de una variable pasada por valor:\nx = 10\n\n# Funcion con variable pasada por valor\ndef modificar(x):\n    print(f'Antes {x}')\n    x = 5\n    print(f'Despues {x}')\n\nmodificar(x)\n\nprint(f'x Por fuera de la funcion {x}') #---> Aca se ve claramente como la variable original no se ve \n# modificada despues de la funcion\n\n# Ejemplo de una variable pasada por referencia:\n\nlista = [10,20,30]\n\n# Funcion con variable pasada por referencia\ndef modificar_lista(lista):\n    print(f'Antes {lista}')\n    lista = [40,50,60]\n    print(f'Despues {lista}')\n    \n    \nmodificar_lista(lista)\nprint(f'Lista por fuera de la funcion {lista}') #---> Aca se ve claramente como la variable original \n# se ve modificada despues de la funcion\n\na = 10\nb = 20\n\nprint(f'Variables originales: a({a}) b({b})')\n\ndef por_valor(a,b):\n    b2 = a\n    a2 = b\n    print(f'Variables modificadas: a({a2}) b({b2})')\n    return b2,a2\n\npor_valor(a,b)\nprint(f'Variables originales: a({a}) b({b})')\n\nc = [10]\nd = [20]\n\nprint(f'Variables originales: c({c[0]}) d({d[0]})')\n\ndef por_referencia(c,d):\n    c.pop()\n    d.pop()\n    c.append(20)\n    d.append(10) \n    print(f'Variables modificadas: c({c[0]}) d({d[0]})')\n    \n\npor_referencia(c,d)\n\nprint(f'Variables originales: c({c[0]}) d({d[0]})')\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/RoniPG.py",
    "content": "# @RoniPG\n\n# Asignación de variables por valor\n\"\"\"\nAl hacer la asignacion por valor se guarda la copia del original y no su direccion en memoria.\n\"\"\"\noriginal=5\ncopia=original\nprint(f\"El valor de original: {original}\\nEl valor de la copia: {copia}\")\ncopia=10\nprint(f\"El valor de original al modificar la copia: {original}\\nEl nuevo valor de la copia: {copia}\")\n\n# Asignación de variables por referencia\n\"\"\"\nAl hacer la asignacion por referencia se pasa la direccion en memoria, en donde las variables que tengan\nacceso a la misma estan sincronizadas y cualquier cambio realizado en dicha posicion afectaria a todas.\n\"\"\"\nlista_original=list()\nlista_original.append(5)\nlista_copia=list()\nlista_copia=lista_original\nprint(f\"\\nEl valor de original: {lista_original}\\nEl valor de la copia: {lista_copia}\")\nlista_copia.append(10)\nprint(f\"El valor de original al modificar la copia: {lista_original}\\nEl nuevo valor de la copia: {lista_copia}\")\n\n# Funciones con variables que se les pasan por valor\n\"\"\"\nLas funciones que reciben como parametro la copia del valor no pueden modificar los datos originales\n\"\"\"\ndef porValor(a:int,b:int):\n    print(\"***Entramos la funcion porValor***\")\n    a=45\n    b=95\n    print(f\"El valor de original: {a}\\nEl valor de la copia: {b}\")\n    print(\"***Salimos de la funcion porValor***\")\nprint(f\"\\nEl valor de original: {original}\\nEl valor de la copia: {copia}\")\nporValor(original,copia)\nprint(f\"El valor de original despues de la funcion: {original}\\nEl valor de la copia despues de la funcion: {copia}\\n\")\n\n# Funciones con variables que se les pasan referencia\n\"\"\"\nLas funciones que reciben como parametro la referencia de memoria modifican los datos originales\n\"\"\"\ndef porReferencia(a:list,b:list):\n    print(\"***Entramos la funcion porReferencia***\")\n    a.append(45)\n    b.append(95)\n    print(f\"El valor de lista_A: {a}\\nEl valor de la lista_B: {b}\")\n    print(\"***Salimos de la funcion porReferencia***\")\nlista_A=list()\nlista_A.append(5)\nlista_B=list()\nlista_B.append(10)\nprint(f\"El valor de lista_A: {lista_A}\\nEl valor de la lista_B: {lista_B}\")\nporReferencia(lista_A,lista_B)\nprint(f\"El valor de lista_A despues de la funcion: {lista_A}\\nEl valor de la lista_B despues de la funcion: {lista_B}\\n\")\n\"\"\"\nDIFICULTAD EXTRA (opcional):\nCrea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n- Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n  Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n  se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n  variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n  Comprueba también que se ha conservado el valor original en las primeras.\n\"\"\"\ndef intercambioPorValor(a:int, b:int):\n    print(\"***Entramos en la funcion intercambioPorValor***\")\n    temp= a\n    a=b\n    b=temp\n    print(\"***Salimos de la funcion intercambioPorValor***\")\n    return a,b\ndef intercambioPorReferencia(a:list, b:list):\n    print(\"***Entramos en la funcion intercambioPorReferencia***\")\n    temp= a\n    a=b\n    b=temp\n    print(\"***Salimos de la funcion intercambioPorReferencia***\")\n    return a,b\n\nnum_A=5\nnum_B=10\nprint(f\"Valor de num_A: {num_A}.\\tValor de num_B: {num_B}\")\nnum_C,num_D=intercambioPorValor(num_A,num_B)\nprint(f\"Valor de num_A: {num_A}.\\tValor de num_B: {num_B}\")\nprint(f\"Valor de num_C: {num_C}.\\tValor de num_D: {num_D}\\n\")\n\nlista_num_A=list()\nlista_num_A.append(5)\nlista_num_B=list()\nlista_num_B.append(10)\nprint(f\"Valor de lista_num_A: {lista_num_A}.\\tValor de lista_num_B: {lista_num_B}\")\nlista_num_C,lista_num_D=intercambioPorReferencia(lista_num_A,lista_num_B)\nprint(f\"Valor de lista_num_A: {lista_num_A}.\\tValor de lista_num_B: {lista_num_B}\")\nprint(f\"Valor de lista_num_C: {lista_num_C}.\\tValor de lista_num_D: {lista_num_D}\")\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/RuhlMirko.py",
    "content": "print(\"Asignacion por valor:\")\nfirst_int = 123\nsecond_int = 321\nprint(f\"a: {first_int}\")\nprint(f\"b: {second_int}\")\nsecond_int = first_int\nfirst_int = 234\nprint(f\"A: {first_int}\")\nprint(f\"B: {second_int}\")\n\nprint(\"\\nAsignacion por referencia:\")\nfirst_list = [40, 60]\nsecond_list = first_list\nsecond_list.append(80)\nprint(first_list)\nprint(second_list)\n\nprint(\"\\nFunciones: \")\n\n\ndef modify_int(my_int: int):\n    my_int += 20\n    print(my_int)\n\n\ndef modify_list(my_list: list):\n    my_list.append(30)\n    my_second_list = my_list\n    my_second_list.append(30)\n    print(my_list)\n    print(my_second_list)\n\n\nfirst_int = 10\nfirst_list = [10, 20]\nprint(first_int)\nmodify_int(first_int)\n\nmodify_list(first_list)\nprint(first_list)\n\nprint(\"\\n\\nDificultad Extra:\")\n\n\ndef invert_values(a, b):\n    new_a = b\n    new_b = a\n    return f\"A:{new_a}, B:{new_b}\"\n\n\ndef invert_references(list_a, list_b):\n    c_list = list_a\n    list_a = list_b\n    list_b = c_list\n    return f\"A:{list_a}, B:{list_b}\"\n\n\nfirst_var = 2024\nsecond_var = 2020\nprint(f\"Original state = A:{first_var} - B:{second_var}\")\nprint(f\"Modified version = {invert_values(first_var, second_var)}\")\n\n\nprint(f\"Original state = A:{first_list} - B:{second_list}\")\nprint(f\"Modified version = {invert_references(first_list, second_list)}\")\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/Rusanov16.py",
    "content": "\"\"\"\nEJERCICIO:\n- Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n  su tipo de dato.\n- Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n  \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n(Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n\nDIFICULTAD EXTRA (opcional):\nCrea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n- Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n  Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n  se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n  variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n  Comprueba también que se ha conservado el valor original en las primeras.\n\"\"\"\n\n#*-------------------------------------------------------------------------------------------------------------#\nprint(\"-----------------------------------------------------------------------------------------------------\")\nprint(\"Variables por valor:\\n\")\ninicio = 156\nprint(f\"La variable inicio tiene el siguiente valor: {inicio}\")\nfin = inicio\nprint(f\"La variable fin tendrá el mismo valor que incio: {fin}\")\nfin = 456\nprint(f\"La variable fin se ha modificado ya hora tiene el siguiente valor: {fin}\")\n\nprint(\"Funciones con variables por valor:\\n\")\ndef modificar_valor(ini_nuevo):\n    ini_nuevo = 3864\n    print(ini_nuevo)\n\nini = 45\nmodificar_valor(ini)\nprint(ini)\n\n#*-------------------------------------------------------------------------------------------------------------#\n\nprint(\"-----------------------------------------------------------------------------------------------------\")\nprint(\"Variables por Referencia:\\n\")\n\nnotas = [3.5,4.6,7.8,9]\nprint(f\"Esta es una lista con las notas de una materia: {notas}\")\nnot_final = notas \nprint(f\"La nueva lista tendrá el mismo valor que la lista notas: {not_final}\")\nnot_final.append(5.6)\nprint(f\"La lista not_final se modificó y estos son sus valores: {not_final}\")\n\nprint(\"Funciones con variables por referencia:\\n\")\ndef modificar_lista(nota_lista):\n    nota_lista.append(6.8)\n    print(nota_lista)\n\nnueva_notas = [3.4,5.6,8.2,3.2]\nmodificar_lista(nueva_notas)\nprint(nueva_notas)\n\n#*-------------------------------------------------------------------------------------------------------------#\n\"\"\"\nDIFICULTAD EXTRA (opcional):\nCrea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n- Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n  Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n  se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n  variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n  Comprueba también que se ha conservado el valor original en las primeras.\n\"\"\"\n\nprint(\"-----------------------------------------------------------------------------------------------------\")\n\n#Para Valor\nprint(\"Funciones para Valor con dos parametros:\\n\")\ndef valor(u,w):\n    u = w * 15\n    w = 25 - u\n    return u,w\n\nx = 350\ny = 456\nnuevo_x , nuevo_y = valor(x,y)\nprint(f\"Los valores definidos anteriormente son: {x,y}\")\nprint(f\"Los nuevos valores son: {nuevo_x,nuevo_y}\")\n\nprint(\"-----------------------------------------------------------------------------------------------------\")\n\n#Para Referencia\nprint(\"Funciones para Referencia con dos parametros:\\n\")\ndef referencia(list_a,list_b):\n    list_a = [list_b,list_a]\n    list_b = list_a\n    return list_a, list_b\n\nlist_u = [3.4,5,7,8,9]\nlist_w = [4,8,1.2,4.3,7.6]\n\nnueva_lista_u , nueva_lista_w = referencia(list_u,list_w)\nprint(f\"Los valores definidos anteriormente son: {list_u,list_w}\")\nprint(f\"Los nuevos valores son: {nueva_lista_u,nueva_lista_w}\")"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/Sac-Corts.py",
    "content": "\"\"\"\n EJERCICIO\n\"\"\"\n\na = 10\nb = a\nb += 5 \nprint(a) # Salida: 10\nprint(b) # Salida: 15\n\n\nlista1 = [1, 2, 3]\nlista2 = lista1\nlista2.append(4)\nprint(lista1)  # Salida: [1, 2, 3, 4]\nprint(lista2)  # Salida: [1, 2, 3, 4]\n\n\n### Funciones con Variables Pasadas \"por Valor\" y \"por Referencia\" ###\n# Pasar por valor\n# Ejemplo con tipo inmutable:\ndef incrementar_valor(x):\n    x += 1\n    print(\"Dentro de la función:\", x)\n\na = 5\nincrementar_valor(a)\nprint(\"Fuera de la función:\", a)\n\n# Pasar por referencia\n# Ejemplo con tipo mutable:\ndef agregar_elemento(lista):\n    lista.append(4)\n    print(\"Dentro de la función:\", lista)\n\nmi_lista = [1, 2, 3]\nagregar_elemento(mi_lista)\nprint(\"Fuera de la función:\", mi_lista)\n\n\"\"\"\n DIFICULTAD EXTRA\n\"\"\"\n\n### Intercambio de parámetros por valor ###\ndef intercambiar_valores_por_valor(x, y):\n    temp = x\n    x = y\n    y = temp\n    return x, y\n\na = 5\nb = 10\n\nnuevo_a, nuevo_b = intercambiar_valores_por_valor(a, b)\n\nprint(\"Valores originales:\")\nprint(\"a =\", a)\nprint(\"b =\", b)\n\nprint(\"Valores intercambiados:\")\nprint(\"nuevo_a =\", nuevo_a)\nprint(\"nuevo_b =\", nuevo_b)\n\n\n### Intercambio de parámetros por referencia ###\n\ndef intercambiar_valores_por_referencia(lista):\n    temp = lista[0]\n    lista[0] = lista[1]\n    lista[1] = temp\n\nc = [5]\nd = [10]\n\nparametros = [c, d]\n\nintercambiar_valores_por_referencia(parametros)\n\nnuevo_c = parametros[0]\nnuevo_d = parametros[1]\n\nprint(\"Valores originales:\")\nprint(\"c =\", c[0])\nprint(\"d =\", d[0])\n\nprint(\"Valores intercambiados:\")\nprint(\"nuevo_c =\", nuevo_c[0])\nprint(\"nuevo_d =\", nuevo_d[0])\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/SaezMD.py",
    "content": "#05 VALOR Y REFERENCIA\n\"\"\"\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n\"\"\"\n\n\n#Values by value\nvalA = 1\nvalB = 3 * 4\nvalC = 'Pythonista'\n\na, b, c = 1, 2, 3\na = b = c = 12\n\n#by Value:\na = 1\nb = 12.5\nc = \"hello\"\nd = False\n\n#by ref:\nx = [\"a\", \"b\", \"c\"]\ny = {\"a\": 0, \"b\": 1, \"c\": 2}\n\n\n#Function by value:\nx = 10\ndef function(entry):\n    entry = 0\nfunction(x)\n\nprint(x) # 10\n\n#Function by ref:\nx = [10, 20, 30]\ndef function(entrada):\n    entrada.append(40)\n\nfunction(x)\nprint(x) # [10, 20, 30, 40]\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno se asigna \n a dos variables diferentes a las originales. A continuación, imprime el valor de las\n variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n Comprueba también que se ha conservado el valor original en las primeras.\n\"\"\"\n\nval01 = 12\nval02 = \"Home\"\nprint(id(val01), id(val02))\n\ndef function01(value1, value2)-> str:\n    \"\"\"function to check values not changed\"\"\"\n    temp01= value1\n    temp02= value2\n    value1 = temp02\n    value2 = temp01\n    \n    return value1, value2\n\nexit01, exit02 = function01(val01, val02)\n\nprint(val01, val02)\nprint(id(val01), id(val02))\nprint()\nprint(exit01, exit02)\nprint(id(exit01), id(exit02))\n\n\nref01 = [\"car\", \"ramp\"]\nref02 = {\"jan\":12, \"feb\": 10}\nprint(id(ref01), id(ref02))\n\ndef function02(ref1, ref2)-> str:\n    \"\"\"function to check references yes changed\"\"\"\n    temp01= ref1\n    temp02= ref2\n    ref1 = temp02\n    ref2 = temp01\n\n    return ref1, ref2\n\nexit03, exit04 = function02(ref01, ref02)\n\nprint(ref01, ref02)\nprint(id(ref01), id(ref02))\nprint()\nprint(exit03, exit04)\nprint(id(exit03), id(exit04))\n\n\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/SaicoBys.py",
    "content": "# Asignación por valor (tipos de datos inmutables)\nx = 5\ny = x  # Se asigna una copia del valor de x a y\n\nprint(\"Antes de modificar y:\", x, y)  # 5 5\ny = 10\n\nprint(\"Después de modificar y:\", x, y)  # 5 10 (x no cambia)\n\n# Asignación por referencia (tipos de datos mutables)\nlista1 = [1, 2, 3]\nlista2 = lista1  # Se asigna una referencia a la misma lista\n\nprint(\"Antes de modificar lista2:\", lista1, lista2)  # [1, 2, 3] [1, 2, 3]\nlista2.append(4)\n\nprint(\"Después de modificar lista2:\", lista1, lista2)  # [1, 2, 3, 4] [1, 2, 3, 4] (lista1 también cambia)\n\n# Funciones y paso de parámetros\ndef modificar_por_valor(numero):\n    \"\"\"Modifica un número (paso por valor).\"\"\"\n    numero = numero * 2  # Se modifica una copia local del número\n\ndef modificar_por_referencia(lista):\n    \"\"\"Modifica una lista (paso por referencia).\"\"\"\n    lista.append(5)  # Se modifica la lista original\n\n# Ejemplo de uso\na = 7\nb = [6, 7, 8]\n\nprint(\"Antes de las funciones:\", a, b)  # 7 [6, 7, 8]\n\nmodificar_por_valor(a)\nmodificar_por_referencia(b)\n\nprint(\"Después de las funciones:\", a, b)  # 7 [6, 7, 8, 5] (a no cambia, b sí)\n\n# Ejercicio\n\n# Programa 1: Intercambio por valor (no funciona\")\ndef intercambiar_por_valor(x, y):\n    temp = x\n    x = y\n    y = temp\n\n# Programa 2: Intercambio por referencia (funciona)\ndef intercambiar_por_referencia(lista):\n    lista[0], lista[1] = lista[1], lista[0]\n\n# Programa 1: Intercambio por valor (no funciona)\ndef intercambiar_por_valor(x, y):\n    temp = x\n    x = y\n    y = temp\n\n# Programa 2: Intercambio por referencia (funciona)\ndef intercambiar_por_referencia(lista):\n    lista[0], lista[1] = lista[1], lista[0]\n\n# Ejemplo de uso\na = 1\nb = 2\nc = [3, 4]\n\nprint(\"Antes:\", a, b, c)  # 1 2 [3, 4]\n\nintercambiar_por_valor(a, b)\nintercambiar_por_referencia(c)\n\nprint(\"Después:\", a, b, c)  # 1 2 [4, 3] (a y b no cambian, c sí)\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/SergioGI99.py",
    "content": "\"\"\"\n------------------\nVALOR Y REFERENCIA\n------------------\nEJERCICIO:\n- Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n  su tipo de dato.\n- Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n  \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n(Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n\nDIFICULTAD EXTRA (opcional):\nCrea dos programas que reciban dos parámetros (cada uno) definidos como\nvariables anteriormente.\n- Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n  Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n  se asigna a dos variables diferentes a las originales. A continuación, imprime\n  el valor de las variables originales y las nuevas, comprobando que se ha invertido\n  su valor en las segundas.\n  Comprueba también que se ha conservado el valor original en las primeras.\n\"\"\"\n\n# Ejercicio\n\n# Asignación de variable por valor\n\ndef fun_one(number: int):\n    number *= 5\n\nn = 10\nfun_one(n)\nprint(n)\n\nmy_int_a = 20 # Otro ejemplo\nmy_int_b = my_int_a\nmy_int_b = 30\nprint(my_int_a)\nprint(my_int_b)\n\n# Asignación de variable por referencia\n\ndef fun_two(my_list: list):\n    for i, n in enumerate(my_list):\n        my_list[i] *= 2\n\nl = [1, 2, 3]\n\nfun_two(l)\nprint(l)\n\nmy_list_a = [10, 20] # Otro ejemplo\nmy_list_b = my_list_a\nmy_list_b.append(30)\nprint(my_list_a)\nprint(my_list_b)\n\n# Ejercicio Extra\n\nvalue_one = 1\nvalue_two = 2\n\ndef my_fun(value_a: int, value_b: int):\n    temp = value_a\n    value_a = value_b\n    value_b = temp\n    return value_a, value_b\n\nprint(\"\\nAsignación por valor:\")\nvalue_three, value_four = (my_fun(value_one, value_two))\nprint(f\"Originales: {value_one}, {value_two}\")\nprint(f\"Nuevos: {value_three}, {value_four}\")\n\nvalue_ref_one = [10, 20]\nvalue_ref_two = [30, 40]\n\ndef my_other_fun(value_a: list, value_b: list):\n    temp = value_a\n    value_a = value_b\n    value_b = temp\n    value_a.append(50)\n    value_b.append(30)\n    return value_a, value_b\n\nprint(\"\\nAsignación por referencia:\")\nvalue_three, value_four = my_other_fun(value_ref_one, value_ref_two)\nprint(f\"Originales: {value_ref_one}, {value_ref_two}\")\nprint(f\"Nuevos: {value_three}, {value_four}\")"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/SooHav.py",
    "content": "#05 VALOR Y REFERENCIA\n\n#Ejemplos de asignación de variables \"por valor\" y \"por referencia\"\n'''Los tipos de datos primitivos principales se pasan por valor: \nenteros , flotantes, string, booleanos, etc.\n'''\na= 1\nprint(f\"a: {a}, {id(a)}\")\nb = a  # se crea una copia de 'a'\nprint(f\"b: {b}, {id(b)}\")  \nb = 2.3   # 'a' no se ve afectado\nprint(f\"b: {b}, {id(b)}\")\ns = \"sofia\"\nprint(f\"s: {s}, {id(s)}\")\nx = s  # se crea una copia de 's'\nprint(f\"x: {x}, {id(x)}\")  \nx= True # 's' no se ve afectado\nprint(f\"x: {x}, {id(x)}\")  \nprint(\"\")\n\n'''Los tipos de datos compuestos se pasan por referencia: Listas, \ndiccionarios, tuplas, set\n'''\n## La lista es un objeto mutable\nlista_1 = [1, 2, 3]\nprint(f\"Lista 1 original:\",lista_1, id (lista_1))\nlista_2 = lista_1  # lista 1 y 2 referencian a la misma lista\nprint(f\"Lista 2 igual a la original:\",lista_2, id (lista_2)) \nlista_2.append(4)  # si agrego 4 se modifica la lista a través de la referencia lista 2\nprint(f\"La lista 2 sigue sigue referenciando el mismo objeto despues de agregar un elemento:\",lista_2, id (lista_2))  \nlista_2 = lista_1.copy()  # se hace una copia de lista 1 \nprint(\"Lista 2 copia de la original:\",lista_2, id (lista_2))  \nlista_2.append(4) # al modificar lista 2 se convierte en otro objeto\nprint(\"La lista 2 al ser una copia de la lista 1 referencia otro objeto:\", lista_2, id (lista_2))  \n\n## El diccionario es un objeto mutable\ndiccionario_1 = {'a': 1, 'b': 2}\nprint(\"Diccionario 1:\",diccionario_1, id (diccionario_1))  \ndiccionario_2 = diccionario_1  # diccionario 1 y 2 referencian a la misma lista\nprint(\"Diccionario 2:\",diccionario_2, id (diccionario_2))  \ndiccionario_2['c'] = 3  # modifica el diccionario 1 y 2 a través de una de las referencias (dicconario2)\nprint(\"El diccionario 1 se modifica al agregar un elemento al diccionario 2 pero ambos referencia el mismo objeto:\", diccionario_2, id (diccionario_2))  \nprint(\"\")\n\n## La tupla es un objeto inmutable                                                      \ntupla_1 = (1, 2, 3)\nprint(\"Tupla 1:\",tupla_1, id (tupla_1))  # Output: (1, 2, 3) id tupla 1\ntupla_2 = tupla_1  # ambas referencian a la misma tupla\n# tupla2 += (4,)  Error, no se puede modificar la tupla\nprint(\"La tupla 2 referencia el mismo objeto ya que es un objeto inmutable:\",tupla_2, id (tupla_2)) \nprint(\"\")\n\n## El set es un objeto mutable\nset_1 = {1, 2, 3}\nprint(\"Set 1:\",set_1, id (set_1))\nset_2 = set_1  # ambas referencian al mismo set\nset_2.add(4)  # modifica el set1 a través de set2\nprint(\"Set 2 sigue referenciando a set 1 despues de agregar un elemento:\",set_2, id (set_2))  \nprint(\"\")\n\n#Ejemplos de funciones con variables que se les pasan \"por valor\" y \"por referencia\"\n##Objeto inmutable\ndef modificar_dato(a): \n    print(\"Dato dentro de la función (antes de modificar):\", a, id (a))\n    a += 15  \n    print(\"Dato dentro de la función (después de modificar):\", a, id(a))\n    return a\n\nvalor = 5\nresultado = modificar_dato(valor)\nprint(\"Dato fuera de la función:\", valor, id(valor))\nprint(\"Un objeto inmutable al modificar su dato referencia a otro objeto:\", resultado, id(resultado))\nprint(\"\")\n\n##Objeto mutable\ndef modificar_lista(lista): \n    print(\"Lista dentro de la función (antes de modificar):\", lista, id(lista))\n    lista.append(4)  \n    print(\"Lista dentro de la función (después de modificar):\", lista, id(lista))\n    return lista\n\nlista = [1, 2, 3]\nnueva_lista = modificar_lista(lista)\nprint(\"Un objeto mutable 'lista' si es modificada en sus datos sigue referenciando al mismo objeto:\", nueva_lista, id(nueva_lista))  \nprint(\"\")\n\n#Dificultad extra\n##Por valores\ndef intercambiar_por_valores(a, b):\n    a, b = b, a\n    return a, b\n\na = 5\nb = 10\nprint(\"variable a:\", a, id(a))\nprint(\"variable b:\", b, id(b))\n\nn_a, n_b = intercambiar_por_valores(a, b)\nprint(\"Funcion que intercambia por valor:\")\nprint(\"nueva a:\", n_a, id(n_a))\nprint(\"nueva b:\", n_b, id(n_b))\nprint(\"\")\n\n##Por referencia\ndef intercambiar_por_referencia(lista_1, lista_2):\n    lista_1[:], lista_2[:] = lista_2[:], lista_1[:] \n    return lista_1, lista_2\n\nlista_1 = [1, 2]\nlista_2 = [3, 4]\nprint(\"Lista 1:\", lista_1, id(lista_1))\nprint(\"Lista 2:\", lista_2, id(lista_2))\n\nn_lista_1, n_lista_2 = intercambiar_por_referencia(lista_1, lista_2)\nprint(\"Funcion que intercambia por referencia aparente:\")\nprint(\"Nueva lista 1:\", n_lista_1, id(n_lista_1))\nprint(\"Nueva lista 2:\", n_lista_2, id(n_lista_2))"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/TheReDNooB.py",
    "content": "\"\"\"\nValor y referencia\n\"\"\"\n\n# Valor\n\nmy_string = \"Hello World\"\nother_string = my_string\nmy_string = \"Bye World\"\nprint(my_string)\nprint(other_string)\n\n# Referencia\n\nmy_list = [1,2,3,4]\nother_list = my_list\nmy_list.append(5)\nprint(my_list)\nprint(other_list)\n\n# funciones con valor\n\nnum_int = 10\ndef fun_int(num_int: int):\n    num_int = 20\n    print(num_int)\nfun_int(num_int)\nprint(num_int)\n\n# funciones con referencia\n\nnumber_list = [1,2,3,4]\ndef fun_list(number_list: list):\n    number_list.append(5)\n    print(number_list)\nfun_list(number_list)\nprint(number_list)\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n\"\"\"\n# por valor\ndef intercambio_valor(a, b):\n    temp = a\n    a = b\n    b = temp\n    return a, b\nvar1 = 10\nvar2 = 20\nvar3, var4 = intercambio_valor(var1, var2)\nprint(var1, var2)\nprint(var3, var4)\n\n# por referencia\ndef intercambio_referencia(a, b):\n    temp = a\n    a = b\n    b = temp\n    temp.append(50)\n    return a, b\nvar1 = [10, 20]\nvar2 = [30, 40]\nvar3, var4 = intercambio_referencia(var1, var2)\nprint(var1, var2)\nprint(var3, var4)"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/Tomu98.py",
    "content": "\"\"\" Reto 05: Valor y Referencia \"\"\"\n\n# Tipos de datos por valor\nmy_int_a = 12\nmy_int_b = my_int_a\nmy_int_b = 2\n# my_int_a = 21\nprint(my_int_a)\nprint(my_int_b)\n\n# Tipos de datos por referencia\nmy_list_a = [12, 21]\nmy_list_b = my_list_a\nmy_list_b.append(24)\nprint(my_list_a)\nprint(my_list_b)\n\n# Funciones con datos por valor\ndef my_int_func(my_int: int):\n    my_int = 22\n    print(my_int)\n\nmy_int_c = 24\nmy_int_func(my_int_c)\nprint(my_int_c)\n\n# Funciones con datos por referencia\ndef my_list_func(my_list: list):\n    my_list.append(22)\n    my_list_d = my_list\n    my_list_d.append(1)\n    print(my_list)\n    print(my_list_d)\n\nmy_list_c = [2, 16]\nmy_list_func(my_list_c)\nprint(my_list_c)\n\n\n\n\"\"\" Reto extra \"\"\"\n\n# Por valor\ndef value(value_a: int, value_b: int) -> tuple:\n    temp = value_a\n    value_a = value_b\n    value_b = temp\n    return value_a, value_b\n\nmy_int_d = 10\nmy_int_e = 20\nmy_int_f, my_int_g = value(my_int_d, my_int_e)\nprint(f\"{my_int_d}, {my_int_e}\")\nprint(f\"{my_int_f}, {my_int_g}\")\n\n# Por referencia\ndef ref(value_a: list, value_b: list) -> tuple:\n    temp = value_a\n    value_a = value_b\n    value_b = temp\n    return value_a, value_b\n\nmy_list_e = [10, 20]\nmy_list_f = [30, 40]\nmy_list_g, my_list_h = ref(my_list_e, my_list_f)\nprint(f\"{my_list_e}, {my_list_f}\")\nprint(f\"{my_list_g}, {my_list_h}\")\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/TroyNebula.py",
    "content": "'''\r\n EJERCICIO:\r\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\r\n *   su tipo de dato.\r\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \r\n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\r\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)'''\r\n\r\n# Las asignaciones dependen de los tipos de datos:\r\n# Los tipos simples e inmutables como tuplas, enteros, flotantes y cadenas se asignan \"por valor\"\r\n# Los tipos compuestos y mutables como listas, conjuntos/sets y diccionarios se asignan \"por referencia\".\r\n\r\n\r\n# Asignación por Valor -----------------------------------------------------------------------\r\n# Se crea una copia local de la variable independiente del valor original. Cambios en la variable original no afectan.\r\n\r\n# Asignación por valor con tipos simples (entero)\r\nx = 5\r\ny = x  # Se asigna el valor de x a y\r\n\r\ny = 10 # Modificamos y, pero no afectará a x\r\n\r\nprint(x)  # Salida: 5\r\nprint(y)  # Salida: 10\r\n\r\n# Asignación con ej de función con variables que se les pasan \"por valor\" -----------------------------------------------------------------------\r\n\r\nx = 10\r\ndef funcion(entrada):\r\n    entrada = 0   # entrada almacena una copia local de x\r\n    print(entrada)  #Salida: 0\r\n    print(x)        #Salida: 10 dentro de la función sigue siendo 10 lo que cambió fue la variable anterior\r\nfuncion(x)\r\n\r\nprint(x)    #Salida: 10\r\n\r\n# Asignación por valor con tuplas -----------------------------------------------------------------------\r\n# Las tuplas al ser inmutables se comportarn como si fueran por valor:\r\ntupla_original = (1, 2, 3)\r\ntupla_copia = tupla_original  # Asignación por valor\r\n\r\ntupla_copia += (4,) # Modificar la tupla_copia no afectará a tupla_original ya que las tuplas son inmutables\r\n# La coma después del 4 es necesaria para diferenciarla de simplemente un paréntesis que rodea un valor, \r\n# ya que (4) sin la coma se interpretaría como un valor sin formar una tupla.\r\nprint(tupla_original)  # Salida: (1, 2, 3)\r\nprint(tupla_copia)     # Salida: (1, 2, 3, 4)\r\n\r\n# Asignación con ej de función con variables que se les pasan \"por valor\" -----------------------------------------------------------------------\r\n\r\ntupla_original = (1, 2, 3)  # Asignación por valor con tuplas\r\n\r\ndef modificar_tupla(tupla):\r\n    tupla = tupla + (4,)  # Se crea una nueva tupla y se asigna a la variable local 'tupla'\r\n    print(\"Dentro de la función:\", tupla) # la nueva tupla creada dentro de la función no afecta la tupla original fuera de la función.\r\n    #Salida: Dentro de la función: (1, 2, 3, 4)\r\n\r\nmodificar_tupla(tupla_original)\r\nprint(\"Fuera de la función:\", tupla_original)  #Salida: Fuera de la función: (1, 2, 3)\r\n\r\n# Asignación por Referencia -----------------------------------------------------------------------\r\n# La variable apunta al mismo objeto en la memoria. Cambios en una variable afectan tanto dentro como fuera de la función\r\n# Se actúa directamente sobre la variable pasada, por lo que las modificaciones afectarán a la variable original\r\n\r\nlista1 = [1, 2, 3]\r\nlista2 = lista1     # Se asigna la referencia de lista1 a lista2\r\n\r\nlista2.append(4)    # Modificamos lista2, y esto afectará a lista1\r\n\r\nprint(\"lista1:\", lista1)  # Salida: [1, 2, 3, 4]\r\nprint(\"lista2:\", lista2)  # Salida: [1, 2, 3, 4]\r\n\r\n# otro ejemplo con una lista -----------------------------------------------------------------------\r\n\r\noriginal = [1, 2, 3]        # a original le asigno [1,2,3]  ---Se le asigna, no es que valga, son objetos---\r\ncopy = original             # original y copy son [1,2,3]\r\n\t\r\noriginal[0] = 99            # modifico original [99,2,3]\r\n\r\noriginal = [4, 5, 6]        # asigno un nuevo objeto a original, es [4,5,6]\r\nprint( original)            # [4,5,6]\r\nprint (copy)                # [99,2,3]\r\n\r\n# Asignación con ej de función con variables que se les pasan \"por referencia\" -----------------------------------------------------------------------\r\n\r\nx = [10, 20, 30]\r\ndef funcion(entrada):\r\n    entrada.append(40)\r\n\r\nfuncion(x)\r\nprint(x)    # Salida: [10, 20, 30, 40]\r\n\r\n\r\n# Ojo, es distinto reasignar que modificar -----------------------------------------------------------------------\r\n# Son distintos objetos, y no cambia la original porque no estoy modificando la variable, sino reasignándola, lo que crea una nueva temporal\r\nx = [10, 20, 30]\r\ndef funcion(entrada):\r\n    entrada = []\r\n\r\nfuncion(x)\r\nprint(x)    # Salida: [10, 20, 30]\r\n\r\n\r\n# Función id() -----------------------------------------------------------------------\r\n# Esta función nos devuelve un identificador único para cada objeto. \r\n# Volviendo al primer ejemplo podemos ver como los objetos a los que “apuntan” x y entrada son distintos\r\n\r\n# id con ejemplo de variable por valor -----------------------------------------------------------------------\r\nx = 10\r\nprint(\"id variable valor: \", id(x)) # 140724755286744\r\ndef funcion(entrada):\r\n    entrada = 0\r\n    print(id(entrada)) # 140724755286744\r\n\r\nfuncion(x)  #Salida: 10\r\n\r\n# id con ejemplo de variable por referencia -----------------------------------------------------------------------\r\nx = [10, 20, 30]\r\nprint(\"id variable ref: \", id(x)) # 1737715235264\r\ndef funcion(entrada):\r\n    entrada.append(40)\r\n    print(id(entrada)) # 1737715235264\r\n\r\nfuncion(x)  # Salida: [10, 20, 30, 40]\r\n\r\n# id con el último ejemplo -----------------------------------------------------------------------\r\n# Se crea una nueva lista en memoria y asigna la variable entrada a esa nueva lista\r\n# el id de entrada dentro de la función será diferente al id de x fuera de la función.\r\n\r\nx = [10, 20, 30]\r\nprint (id(x))   #1737715235200\r\ndef funcion(entrada):\r\n    entrada = []\r\n    print (id(entrada)) #1737715235264\r\n\r\nfuncion(x)\r\nprint(x)    # Salida: [10, 20, 30]\r\n\r\n'''\r\n DIFICULTAD EXTRA (opcional):\r\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\r\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\r\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\r\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\r\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\r\n *   Comprueba también que se ha conservado el valor original en las primeras.'''\r\n\r\nprint()\r\nvariable_valor1 = 1             # entero\r\nvariable_valor2 = \"Moure\"       # cadena/string\r\n\r\nvariable_referencia1 = [30, 60, 90]             # lista\r\nvariable_referencia2 = {True, \"conjunto\", 0}    # set\r\n\r\ndef intercambiar_variables_valor(valor1, valor2):\r\n    valor1, valor2 = valor2, valor1\r\n    print(f\"Valor1 que era 1, dentro la función: {valor1}\")\r\n    print(f\"Valor2 que era 'Moure', dentro  la función: {valor2}\")\r\n    return valor1, valor2\r\n\r\ndef intercambiar_variables_referencia(referencia1, referencia2):\r\n    referencia1, referencia2 = referencia2, referencia1\r\n    return referencia1, referencia2\r\n\r\n# llamo a las funciones\r\nresultado_valor1, resultado_valor2 = intercambiar_variables_valor(variable_valor1, variable_valor2)\r\nresultado_referencia1, resultado_referencia2 = intercambiar_variables_referencia(variable_referencia1, variable_referencia2)\r\n\r\n# imprimo resultados\r\nprint()\r\nprint(\"Ya sea valor o referencia invierte los valores\")\r\nprint(f\"Originales Valor: {variable_valor1}, {variable_valor2}\")\r\nprint(f\"Después de pasar por la funcion: {resultado_valor1}, {resultado_valor2}\")\r\nprint(f\"Originales Ref: {variable_referencia1}, {variable_referencia2}\")\r\nprint(f\"Después de pasar por la funcion: {resultado_referencia1}, {resultado_referencia2}\")\r\n\r\n\r\n# pruebo otra función, asigno fuera de función -----------------------------------------------------------------------\r\nprint()\r\nprint(\"Es una lista, es mutable, y sería por referencia, modifica las dos\")\r\nlista1 = [1, 2, 3]\r\nprint (\"Lista1 original:\", lista1)\r\nlista2 = lista1     \r\nprint(\"Se asigna la referencia de lista1 a lista2 fuera de función\")\r\nprint(\"Lista2 original:\", lista2)\r\nnum=4\r\n\r\ndef añadir_número(lista_temp):\r\n    lista_temp.append(num) \r\n    print(\"Lista temporal dentro de la función:\", lista_temp)\r\n\r\nañadir_número(lista2)\r\nprint(\"Añado el número 4 a la lista2 con la función añadir_numero...\")\r\nprint(\"Lista1:\", lista1)\r\nprint(\"Lista2:\", lista2)\r\nprint(\"Se han mofificado las dos y sólo pasé la 2 por la función de añadir\")\r\n\r\n# rescato la lista anterior que invertí: variable_referencia1 = [30, 60, 90]  \r\n# otra prueba, asigno dentro de la función -----------------------------------------------------------------------\r\nprint()\r\nprint(\"Pruebo a asignar dentro de la función la ref de la1 como ref de la 2\")\r\nprint(\"Variable original ref1:\", variable_referencia1)\r\nprint(\"Variable original ref2:\", variable_referencia2)\r\ndef asignar_mismas_variables_ref(vr1, vr2):\r\n    vr2= vr1\r\n    return vr1, vr2\r\n\r\nnueva_vr1, nueva_vr2= asignar_mismas_variables_ref(variable_referencia1, variable_referencia2)\r\nprint(\"Nueva Variable ref1:\", nueva_vr1)\r\nprint(\"Nueva Variable ref2:\", nueva_vr2)\r\n\r\n\r\n# Otra prueba de Modificando por referencia -----------------------------------------------------------------------\r\nprint()\r\nnumeros = [1,2,3]\r\nletras = [\"a\",\"b\",\"c\"]\r\nprint(\"originales antes función:\",numeros, letras)\r\n\r\ndef modifica_numyletras(valor1, valor2):\r\n    numeros.append(valor1)\r\n    letras.append(valor2)\r\n    return(numeros, letras)\r\n\r\nnumeros2 , letras2 = modifica_numyletras(valor1=4, valor2=\"d\")\r\n\r\nprint(\"Con añaddido:\", numeros2, letras2)\r\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/VictorRivero1204.py",
    "content": "\"\"\"\nValor y referencia\n\"\"\"\n\n# Tipos de dato por valor\n\nmy_int_a = 10\nmy_int_b = my_int_a\n#my_int_b = 20\n#my_int_a = 30\nprint(my_int_a)\nprint(my_int_b)\n\n# Tipos de datos por referencia\n\nmy_list_a = [10,20]\nmy_list_b = my_list_a\nmy_list_b.append(30)\n\nprint(my_list_a)\nprint(my_list_b)\n\n# Funciones con datos por valor\n\ndef my_int_func(my_int:int):\n    my_int = 20\n    print(my_int)\n\nmy_int_c = 10\nmy_int_func(my_int_c)\nprint(my_int_c)\n\n# Funciones con dator por referencia\n\ndef my_list_func(my_list: list):\n    my_list_e = my_list\n    my_list_e.append(30)\n    \n    my_list_d = my_list_e\n    my_list_d.append(40)\n\n    print(my_list_e)\n    print(my_list_d)\n\nmy_list_c = [10,20]\nmy_list_func(my_list_c)\nprint(my_list_c)\n\n\"\"\"\nEXTRA\n\"\"\"\n\n# Por valor\n\ndef value(value_a: int, value_b:int) -> tuple:\n    temp = value_a\n    value_a = value_b\n    value_b = temp\n    return value_a, value_b\n\nmy_int_d = 10\nmy_int_e = 20\nmy_int_f, my_int_g = value(my_int_d, my_int_e)\n\nprint(f\"{my_int_d}, {my_int_e}\")\nprint(f\"{my_int_f}, {my_int_g}\")\n\n# Por referencia\n\ndef ref(value_a: list, value_b:list) -> tuple:\n    temp = value_a\n    value_a = value_b\n    value_b = temp\n    return value_a, value_b\n\nmy_list_e = [10, 20]\nmy_list_f = [30, 40]\nmy_list_g, my_list_h = ref(my_list_e, my_list_f)\n\nprint(f\"{my_list_e}, {my_list_f}\")\nprint(f\"{my_list_g}, {my_list_h}\")"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/Yani-Git.py",
    "content": "\"\"\"\nValor y referencia\n\n\"\"\"\n\n#Tipos de datos por valor:  Tipos inmutables: int, float, str,  bool, tuplas Etc. \n\nmy_int_a = 10\nmy_int_b = my_int_a\n#my_int_b = -20 +1\n#my_int_a = 30\nprint (my_int_a)\nprint (my_int_b)\n\n\n#Tipos de datos por referencia:  Tipos mutables: list, dict, set, etc.\n\nmy_list_a =[10, 20]\n#my_list_b = [30, 40]\nmy_list_b = my_list_a\nmy_list_b.append (30) \n#my_list_b = [30, 40]\nprint (my_list_a) #dato o variable por referencia, es decir, hereda su posición de referencia y se almacenan en la misma posición de memoria. imprime esto: [10, 20, 30]\nprint (my_list_b)\n\n\n#Funciones con datos por valor\n\n\nmy_int_c = 10 \n\ndef my_int_func(my_int: int):\n    my_int = 20\n    #my_int c = 30\n    print (my_int)\n\nmy_int_func(my_int_c)\nprint (my_int_c)\n\n#Funciones con datos con referencia\n\ndef my_list_func (my_list: list):\n    my_list_e = my_list\n    my_list_e.append (30)\n\n    my_list_d = my_list_e\n    my_list.append (40)\n\n    print(my_list_e)\n    print (my_list_d)\n\n\nmy_list_c =[10, 20]\nmy_list_func(my_list_c)\nprint (my_list_c)\n\n\n\"\"\"\nExtra\n\n\"\"\"\n#Variable por valor \n\ndef value (value_a: int, value_b: int)-> tuple:\n    temp = value_a\n    value_a = value_b\n    value_b = temp\n    return value_a, value_b\n\n\nmy_int_d = 10\nmy_int_e = 20\nmy_int_f, my_int_g = value (my_int_d, my_int_e)\n\nprint (f\"{my_int_d}, {my_int_e}\")\nprint (f\"{my_int_f}, {my_int_g}\")\n\n#Por referencia \n\ndef ref (value_a: list, value_b: list) -> tuple:\n    temp = value_a\n    #gitemp.append(50)\n    value_a = value_b\n    value_b = temp\n    #value_b.append(50)\n    #value_a.append(50)\n\n    return value_a, value_b\n\n\nmy_int_e = [10, 20]\nmy_int_f = [30, 40] \nmy_int_g, my_int_h = ref (my_int_e, my_int_f)\nprint (f\"{my_int_e}, {my_int_f}\")\nprint (f\"{my_int_g}, {my_int_h}\")"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/YgriegaSB.py",
    "content": " # Variables dada por valor\ndef variables_por_valor(a, b):\n    temp = a\n    a = b\n    b = temp\n    return [a, b]\n\nnum1 = 10\nnum2 = 20\n\n[aNuevo, bNuevo] = variables_por_valor(num1, num2)\n\nprint(f\"Valores originales => v1:{num1} v2:{num2}\")\nprint(f\"Valores nuevos => v1:{aNuevo} v2:{bNuevo}\")\n\n\n\n\ndef variables_por_referencia(objeto):\n    keys = list(objeto.keys())\n    if len(keys) >= 2:\n        temp = objeto[keys[0]]\n        objeto[keys[0]] = objeto[keys[1]]\n        objeto[keys[1]] = temp \n    return objeto\n\nobjeto = {'a': 10, 'b': 20}\n\nobjeto_nuevo = variables_por_referencia(objeto)\n\nprint(f\"Valores originales v1:{objeto['a']} v2:{objeto['b']}\")\nprint(f\"Valores nuevos v1:{objeto_nuevo['a']} v2:{objeto_nuevo['b']}\")\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/Yisusocanto.py",
    "content": "'''\nASIGNACION DE VARIABLES POR VALOR\n'''\n#ejemplo con numeros enteros\nvar1 = 5\nvar2 = var1\n\nprint(var1)\nprint(var2 + 10)  #No modifica el valor de la variable original\nprint(var1)\n\n#ejemplo con cadenas de texto\nvar_str1 = \"Hola\"\nvar_str2 = var_str1\n\nprint(var_str1)\nprint(var_str2 + \" mundo\") #No modifica el valor de la variable original\nprint(var_str1)\n\n'''\nASIGNACION POR REFERENCIA\n'''\n#ejemplo con listas\nlista1 = [1, 2, 3]\nlista2 = lista1\n\ndef ref_lista(mi_lista):\n\tmi_lista.append(4)\n\tprint(mi_lista)\n\nprint(lista1)\nref_lista(lista2)\t#aca actualiza la lista original\nprint(lista1)        \n\n#ejemplo con diccionario\n\ndict1 = {\"jesus\": 1, \"pedro\": 2}\ndict2 = dict1\n\ndef ref_dict(my_dict):\n\tmy_dict[\"carlos\"] = 3\n\tprint(my_dict)\n\nprint(dict1)\nref_dict(dict2)\t #aca actualiza el diccionario original \nprint(dict1)\n\n#ejemplo con una lista pero con la funcion copy para no modificar la original\nlist1 = [1, 2, 3]\nlist2 = list1\n\ndef ref_list(mi_list):\n\tmi_list.append(4)\n\tprint(mi_list)\n\nprint(list1)\nref_lista(list2.copy())\t#la funcion copy hace una copia de la lista\nprint(list1)            #la modifica con la funcion y la imprime\n                        #sin modificar ni actualizar la lista original\n\n\n#extra\n\n\n#por valor\nx = 10\ny = 20\n\ndef hh(x, y):\n\ttemp = x\n\tx = y\n\ty = temp\n\tprint(x)\n\tprint(y)\n\nprint(x)\nprint(y)\nhh(x, y)\t\n\n\n#por referencia\nn = [10, 20]\nm = [30, 40]\n\ndef aa(x, y):\n\ttemp = x\n\tx = y\n\ty = temp\n\tprint(x)\n\tprint(y)\n\nprint(n)\nprint(m)\t\naa(n, m)\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/Zequy40.py",
    "content": "''' Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\nsu tipo de dato.\n- Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n\"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n '''\n# Asignación de variables \"por valor\" (entero, un objeto inmutable)\na = 10\nb = a  # Se crea una copia del valor\nb += 5  # Modificamos solo b\n\nprint(a)  # a = 10\nprint(b)  # b = 15\n\n# Asignación de variables \"por referencia\" (lista, un objeto mutable)\nlista_a = [1, 2, 3]\nlista_b = lista_a  # Se comparte la referencia al mismo objeto\nlista_b.append(4)  # Modificamos la lista compartida\n\nprint(lista_a)  # lista_a ahora es [1, 2, 3, 4]\nprint(lista_b)  # lista_b también es [1, 2, 3, 4]\n\n#Funciones con variables \"por valor\" (objetos inmutables):\n\ndef modificar_valor(num):\n    num += 10\n    print(\"Dentro de la función:\", num) #resultado: 15\n\na = 5\nmodificar_valor(a)\nprint(\"Fuera de la función:\", a)  #resultado = 5\n#En este caso, aunque num se modifica dentro de la función, la variable original a fuera de la función no se ve afectada, ya que los enteros son inmutables.\n\n\n#Funciones con variables \"por referencia\" (objetos mutables):\ndef modificar_lista(lista):\n    lista.append(4)\n    print(\"Dentro de la función:\", lista) #resultado: [1, 2, 3, 4]\n\nmi_lista = [1, 2, 3]\nmodificar_lista(mi_lista)\nprint(\"Fuera de la función:\", mi_lista) #resultado: [1, 2, 3, 4]\n#Aquí, la lista original \"mi_lista\" se ve afectada por la función, ya que las listas son objetos mutables y se pasan por referencia.\n\n'''\nDIFICULTAD EXTRA (opcional):\n Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n- Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\nEstos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\nse asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\nvariables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\nComprueba también que se ha conservado el valor original en las primeras.\n '''\ndef intercambio_por_valor(a, b):\n    # Intercambio de valores\n    temp = a\n    a = b\n    b = temp\n    return a, b\n\n# Variables originales\nx = 5\ny = 10\n\n# Llamada a la función y asignación de los nuevos valores\nnuevo_x, nuevo_y = intercambio_por_valor(x, y)\n\n# Imprime los resultados\nprint(\"Variables originales: x =\", x, \", y =\", y)\nprint(\"Nuevas variables: nuevo_x =\", nuevo_x, \", nuevo_y =\", nuevo_y)\n\ndef intercambio_por_referencia(lista):\n    # Intercambio de elementos en la lista\n    temp = lista[0]\n    lista[0] = lista[1]\n    lista[1] = temp\n    return lista\n\n# Lista original\nmi_lista = [5, 10]\n\n# Llamada a la función y asignación de la nueva lista\nnueva_lista = intercambio_por_referencia(mi_lista.copy())\n\n# Imprime los resultados\nprint(\"Lista original:\", mi_lista)\nprint(\"Nueva lista:\", nueva_lista)\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/a-mayans.py",
    "content": "\"\"\" \nPaso por valor: Se crea una copia local de la variable dentro de la función. \nPaso por referencia: Se maneja directamente la variable, los cambios realizados dentro de la función le afectarán también fuera. \n\"\"\"\n\n# Ejemplo de asignacion de variables: Por valor( tipos primitivos: int, float, boolean, strings y tuplas -> son inmutables )\nvalue1 = 27\nvalue2 = value1 # asignacion por valor\nprint(value2)\n# modificacion de la variable\nvalue2 = 13\n\nprint(value1) # la variable 'value1' no se ve afectada\nprint(value2) # la variable 'value2' tiene un valor diferente\n\n\n# Ejemplo de asignacion de variables: Por referencia ( de estructuras: listas, sets, diccionarios -> son mutables )\nlista1 = [14,18,21]\nlista2 = lista1 # asignacion por variable\nprint(lista1)\nprint(lista2)\n# modificacion de la variable\nlista2[2] = 20\n\nprint(lista1) # como ambas variables apuntan a la misma direccion en memoria, las dos se ven afectadas\nprint(lista2)\n\n\n# Funcion con paso por Valor\ndef modificar_valor(value):\n    value = 27 * 3\n    print(f'Valor dentro de la funcion: {value}')\n\n# Ejemplo con un entero ( tipo primitivo )\nvalue = 5\nmodificar_valor(value)\nprint(f'Fuera de la función: {value}')\n\n# Funcion con paso por Referencia\ndef modificar_lista(lista):\n    lista[0] = 13\n    print(f'Dentro de la funcion: {lista}')\n\n# Ejemplo con una lista ( objeto mutable )\nlista3 = [1, 2, 3]\nmodificar_lista(lista3)\nprint(f'Fuera de la función: {lista3}')\n\n\n# DIFICULTAD EXTRA (opcional):\n\n# Crear variables para pasar como parametros\nparam_valor1 = 2727\nparam_valor2 = (13, 'Alex', True)\nparam_referencia1 = [1,2,3,4]\nparam_referencia2 = {'name': 'Carolina', 'age': 30, 'occupation': 'maestra'}\n\n# Imprimimos valores originales\nprint(f'Valor original del valor 1: {param_valor1}')\nprint(f'Valor original del valor 2: {param_valor2}')\nprint(f'Valor original de la referencia 1: {param_referencia1}')\nprint(f'Valor original de la referencia 2: {param_referencia2}')\n\n# Crear funcion con parametros de paso por valor\ndef cambio_valores(param_valor1, param_valor2):\n    # cambiar valores\n    param_valor1, param_valor2 = param_valor2, param_valor1\n    # retornarlos\n    return param_valor1, param_valor2\n\nresult_param_valor1, result_param_valor2 = cambio_valores(param_valor1, param_valor2)\nprint(f'Despues de la funcion: Valor 1: {result_param_valor1} - Valor 2: {result_param_valor2}')\nprint(f'Comprobando el valor original del valor 1: {param_valor1}')\nprint(f'Comprobando el valor original del valor 2: {param_valor2}')\n\n\n# Crear funcion con parametros de paso por referencia\ndef cambio_referencias(param_referencia1, param_referencia2):\n    # cambio valores\n    param_referencia1, param_referencia2 = param_referencia2, param_referencia1\n    # retornarlos\n    return param_referencia1, param_referencia2\n\nresult_param_referencia1, result_param_referencia2 = cambio_referencias(param_referencia1, param_referencia2)\nprint(f'Despues de la funcion: Valor referencia 1: {result_param_referencia1} - Valor referencia 2: {result_param_referencia2}')\nprint(f'Comprobando el valor original de la referencia 1: {param_referencia1}')\nprint(f'Comprobando el valor original de la referencia 2: {param_referencia2}')"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/abascal92.py",
    "content": "'''\n/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n'''\n\n# Asignación de variables por valor (números, strings, booleanos)\na = 1\nb = 2\nb = a\nprint(a, b) # 1 1\n\nc = \"hola\"\nd = \"adios\"\nd = c\nprint(c, d) # hola hola\n\n# Asignación de variables por referencia (listas, diccionarios, objetos)\ne = [1, 2, 3]\nf = [4, 5, 6]\ne = f\nprint(e, f) # [1, 2, 3] [1, 2, 3]\n\ng = {\"a\": 1, \"b\": 2}\nh = {\"c\": 3, \"d\": 4}\ng = h\nprint(g, h) # {'a': 1, 'b': 2} {'a': 1, 'b': 2}\n\n# Funciones con variables por valor\nnum = 1\ndef por_valor(x):\n    x = 2\n    return x\nprint(por_valor(num)) # 2\n\n# Funciones con variables por referencia\nnum = [1, 2, 3]\ndef por_referencia(x):\n    x[0] = 2\n    return x\nprint(por_referencia(num)) # [2, 2, 3]\n\n\n# DIFICULTADO EXTRA\n# Por valor\ndef por_valor(x, y): # Se intercambian los valores de x e y\n    x, y = y, x\n    return x, y\nnum1 = 1\nnum2 = 2\nnum3, num4 = por_valor(num1, num2)\nprint(f\"Valor original de num1: {num1}, valor original de num2: {num2}\") \nprint(f\"Valor de num1: {num3}, valor de num2: {num4}\") # 2 1\n\n# Por referencia\ndef por_referencia(x, y): # Se intercambian los valores de x e y\n    x[0], y[0] = y[0], x[0]\n    return x, y\nnum4 = [1, 2, 3]\nnum5 = [4, 5, 6]\nprint(f\"Valor original de num4: {num4}, valor original de num5: {num5}\")\nnum6, num7 = por_referencia(num4, num5)\nprint(f\"Valor de num4: {num6}, valor de num5: {num7}\") # [4, 2, 3] [1, 5, 6]\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/adra-dev.py",
    "content": "\"\"\"\nEJERCICIO:\n- Muestra ejemplos de asignación de variables \"por valor\" y \"por \nreferencia\", según su tipo de dato.\n- Muestra ejemplos de funciones con variables que se les pasan \"por \nvalor\" y \"por referencia\", y cómo se comportan en cada caso en el \nmomento de ser modificadas.\n(Entender estos conceptos es algo esencial en la gran mayoría de \nlenguajes)\n\nDIFICULTAD EXTRA (opcional):\nCrea dos programas que reciban dos parámetros (cada uno) definidos \ncomo variables anteriormente.\n\n- Cada programa recibe, en un caso, dos parámetros por valor, y en \notro caso, por referencia.\n\nEstos parámetros los intercambia entre ellos en su interior, los \nretorna, y su retorno se asigna a dos variables diferentes a las \noriginales. \n\nA continuación, imprime el valor de las variables originales y las \nnuevas, comprobando que se ha invertido su valor en las segundas.\n\nComprueba también que se ha conservado el valor original en las primeras.\n\nby adra-dev.\n\"\"\"\n\n\n\"\"\"\nEn un lenguaje de programaicon, una variable es un termnio que \nrepresenta un espacio en la memoria del ordenador.\n\"\"\"\n\n# Paso por valor\n\na = int(10)\nb = float(5)\nc = complex(2+5j)\nd = str(\"Hola mundo!\")\ne = list([1, 2, 3])\nf = dict(zip(['a','b','c'],[1, 2, 3]))\ng = set([1, 2, 3])\n\nprint(a, b, c, d, e, f, g,)\nprint(a is b)\nprint(e is f)\nprint(f is g)\nprint(g is e)\n\n# Paso por referencia \n\na = 10\nb = a\n\nc = 5.5\nd = c\n\ne = 2+5j\nf = e\n\ng = \"Hola mundo!\"\nh = g\n\ni = list([1, 2, 3])\nj = i\n\nk = dict(zip(['a','b','c'],[1, 2, 3]))\nl = k\n\nm = set([1, 2, 3])\nn = m\n\nprint(a, b, c, d, e, f, g,)\nprint(a is b)\nprint(g is h)\nprint(i is j)\nprint(k is l)\n\n\"\"\"\nEn python, los argumentos siempre se pasan por referencia, es decir, \nlos identificadores definidos en la cabecera de la funcion quedan \nrefernciados a las posiciones de memoria de los valores indicados en \nllamada a la funcion. Pero resulta que el objeto pasado como \nargumento puede ser mutable o inmutable. Si es inmutable, los \nparametors crean, como ya sabemos, un nuevo espacio en memoria, lo \ncual seria equivalente a un paso por valor. Por tanto, cuando los \nargumentos son objetos inmutables su contenido no se ve alterado por\nla llamada a la funcion, pues los parametros guardan su propia copia \ndel argumento.\n\"\"\"\n\n# paso por valor\ndef appellidar(nombre):\n    nombre += ' Martinez'\n    print(nombre)\n\nnombre = 'Rosa'\nappellidar(nombre)\nprint(nombre)\n\n\"\"\"\nEn cambio, cuando pasamos como argumentos tipos mutables, la tabla \nde simbolos de la funcion tambien contiene sus propios \nidentificadores, pero estos parametros apuntan a las posiciones de \nmemoria donde se alojan los datos pasados como argumento.\n\"\"\"\n\ndef ampliar(lista):\n    lista += [4, 5, 6]\n\nl = [1, 2, 3]\nprint(l)\nampliar(l)\nprint(l)\n\n\n\"\"\"\nExtra\n\"\"\"\n# Por valor\n\ndef value(value_1, value_2):\n    temp = value_1\n    value_1 = value_2\n    value_2 = temp\n\n    return value_1, value_2\n\nvalue_1 ='Hello'\nvalue_2 ='Python'\nvalue_3, value_4 = value(value_1, value_2)\nprint(f\"{value_1}, {value_2}\")\nprint(f\"{value_3}, {value_4}\")\n\n\n\n# Por referencia\ndef ref(value_1: list, value_2: list) -> tuple:\n    temp = value_1\n    value_1 = value_2\n    value_2 = temp\n\n    return value_1, value_2\n\n\nmy_list_a = [10,20]\nmy_list_b = [30,40]\nmy_list_c, my_list_d = ref(my_list_a, my_list_b)\nprint(f\"{my_list_a}, {my_list_b}\")\nprint(f\"{my_list_c}, {my_list_d}\")"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/agusrosero.py",
    "content": "# 05 VALOR Y REFERENCIA\n\n# Asignacion de variables por valor\nvalor1 = 23\nvalor2 = valor1\nvalor2 = 10\n\nprint(valor1)\nprint(valor2)\n\n# Asignacion de variables por referencia\n\n\ndef ejemplo1(num):\n    for i, n in enumerate(num):\n        num[i] *= 2\n    return num\n\n\nmi_lista = [1, 2, 3, 4, 5]\nprint(ejemplo1(mi_lista))\n\n\ndef ejemplo2(num):\n    return num * 2\n\n\nnum = 10\nprint(ejemplo2(num))\n\n# DIFICULTAD EXTRA\n\n\ndef cambio_por_valor(valor1, valor2):\n    temp = valor1\n    valor1 = valor2\n    valor2 = temp\n    return valor1, valor2\n\n\na = 10\nb = 20\nprint(cambio_por_valor(a, b))\n\n\ndef cambio_por_referencia(valor1, valor2):\n    nuevo_valor = valor1\n    nuevo_valor2 = valor2\n    return nuevo_valor, nuevo_valor2\n\n\nx = 30\nz = 40\nprint(cambio_por_referencia(x, z))\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/ainaragmt.py",
    "content": "# Asignación: tipos de dato por valor\nprint(\"\\nAsignación: tipos de dato por valor\")\nmy_int_a = 10\nmy_int_b = my_int_a\nmy_int_a = 30\nprint(my_int_a)\nprint(my_int_b)\n\n# Asignación: tipos de dato por referencia\nprint(\"\\nAsignación: tipos de dato por referencia\")\nmy_list_a = [10, 20, 30, 40]\nmy_list_b = my_list_a\nmy_list_b.append(50)\nprint(my_list_a)\nprint(my_list_b)\n\n# Funciones: variables por valor\nprint(\"\\nFunciones: variables por valor\")\nmy_int_c = 5\n\ndef my_int_funct(my_int:int):\n    my_int = 50\n    print(my_int)\n\nmy_int_funct(my_int_c)\nprint(my_int_c)\n\n# Funciones: variables por referencia\nprint(\"\\nFunciones: variables por referencia\")\nmy_list_c = [1, 2]\n\ndef my_list_funct(my_list:list):\n    my_list.append(3)\n    print(my_list)\n\nmy_list_funct(my_list_c)\nprint(my_list_c)\n\n'''\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n'''\nprint(\"\\nEjercicio de dificultad extra\\n\")\n\ndef programa():\n    numero1 = 10\n    numero2 = 20\n    lista1 = [10, 20]\n    lista2 = [30, 40]\n\n    def dato (n1, n2):\n        copia1 = n1\n        n1 = n2\n        n2 = copia1\n        return n1, n2\n    \n    def referencia (l1, l2):\n        copia1 = l1\n        l1 = l2\n        l2 = copia1\n        return l1, l2\n    \n    numero3, numero4 = dato (numero1, numero2)\n    lista3, lista4 = referencia (lista1, lista2)\n\n    print(f\"Números originales: {numero1, numero2}\")\n    print(f\"Números nuevos: {numero3, numero4}\")\n    print(f\"Listas originales: {lista1, lista2}\")\n    print(f\"Listas nuevas: {lista3, lista4}\")\n\nprograma()"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/alanshakir.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\"\"\"\n# paso por valor: se crea una copia local de la variable dentro de la funcion (int, float, string, boolean)\n# paso por referencia: los cambios realizados dentro de la funcion le afectara tambien afuera (listas, diccionarios, tuplas, set)\n\n#paso por valor un int\nmy_variable_valor = 10\ndef doblar_valor(entrada):\n    entrada * 2\ndoblar_valor(my_variable_valor)\nprint(my_variable_valor) #imprime 10\n\n#paso por referencia\nmy_variable_referencia = [10, 20, 30]\ndef doblar_valores(entrada, valor):\n    entrada.append(valor)\ndoblar_valores(my_variable_referencia, 40)\nprint(my_variable_referencia) #imprimr [10, 20, 30, 40]\n\n\"\"\"\nEXTRA\n\"\"\"\n# por valor\nvariable_valor1 = 15\nvariable_valor2 = 20\ndef funcion_paso_valor(variable_valor1, variable_valor2):\n    variable_valor1 = 38\n    variable_valor2 = 40\n    return(variable_valor1, variable_valor2)\n\nvariable_valor3, variable_valor4 = funcion_paso_valor(variable_valor1, variable_valor2)\nprint(f\"Valores originales: valor1 = {variable_valor1}, valor2 = {variable_valor2}\")\nprint(f\"Nuevos valores: valor3 = {variable_valor3}, valor4 = {variable_valor4}\")\n\n\n#por referencia\nvariable_referencia1 = [10, 20, 30]\nvariable_referencia2 = [5, 6, 7]\ndef funcion_paso_referencia(variable_referencia1, variable_referencia2):\n    variable_aux = variable_referencia1\n    variable_referencia1 = variable_referencia2\n    variable_referencia2 = variable_aux\n    #variable_referencia1.append(40)\n    #variable_referencia2.append(8)\n    return variable_referencia1, variable_referencia2\n\nvariable_referencia3, variable_referencia4 = funcion_paso_referencia(variable_referencia1, variable_referencia2)\nprint(f\"Valores originales: referencia1 = {variable_referencia1}, referencia2 = {variable_referencia2}\")\nprint(f\"Nuevos valores: referencia3 = {variable_referencia3}, referencia4 = {variable_referencia4}\")\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/alexdevrep.py",
    "content": "'''\n/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n'''\n\n#Asignación por valor\nvalor1 = 10\nvalor2 = valor1\nvalor1 =20\nprint(f'El valor2 es {valor2}')\nprint(f'Sin embargo el valor1 es {valor1}')\n'''\nComo podemos comprobar el valor de la variable valor2 no se modifica cuando\nvariamos el valor de la variable valor 1\n'''\n\n#Asignación por referencia\nmi_list = [1,2,3,4,5]\nmi_listNew = mi_list\nmi_list.pop(4)\nprint(mi_listNew)\n'''\nComo podemos comprobar tanto como mi_list como mi_listNew apuntan hacia la misma dirección de memoria\nasi que cuando modificamos una de las dos variables la otra también se ve afectada\n'''\n\n#Dificultad EXTRA\nvalor3 = 3\nvalor4 = 5\ndef programa1(valor3,valor4):\n    valor3 = 5\n    valor4 = 3\n    return [valor3 , valor4]\n\n[resultado3,resultado4] = programa1(valor3,valor4)\nprint(f'El valor de la variable valor3 originalmente es: {valor3}')\nprint(f'El valor de la variable valor3 se ha modificado ahora es: {resultado3}')\nprint(f'El valor de la variable valor4 originalmente es: {valor4}')\nprint(f'El valor de la variable valor4 se ha modificado ahora es: {resultado4}')\n\n\nprint(\"---------------------------\")\nlista = [\"Hola\",\"Alexdevrep\",\"Python\"]\ndef programa2(lista):\n    listaNueva = lista\n    listaNueva.append(\"Mundo\")\n    return listaNueva\n\nresultado = programa2(lista)\n\nprint (f'La lista resultante es :{resultado}')\nprint (f'Y sin embargo nuestra lista original tambien se ha visto modificada{lista}')\n\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/andres54-coder.py",
    "content": "\"\"\"\nvalor referencia en python\n\"\"\"\n\n#tipos de dato por valor\n\nmy_int_a = 10\nmy_int_b = my_int_a\n# my_int_b = 20\n# my_int_a = 30\nprint(\"my_int_a\", my_int_a)\nprint(\"my_int_b\", my_int_b)\n\n#tipos de dato por referencia\n\nmy_list_a = [10, 20]\nmy_list_b = my_list_a\nmy_list_b.append(30)\nprint(\"my_list_a\", my_list_a)\nprint(\"my_list_b\", my_list_b)\n\n#funciones con datos por valor\nmy_int_c = 10\ndef my_int_function(my_int: int):\n    my_int = 20\n    print(\"my_int\", my_int)\n\nmy_int_function(my_int_c)\nprint(\"my_int_c\", my_int_c)\n\n# funciones con datos por referencia\n\nmy_list_c = [10, 20]\ndef my_list_function(my_list: list):\n    my_list_e = my_list\n    my_list_e.append(30)\n    \n    my_list_d = my_list_e\n    my_list_d.append(40)\n    print(\"my_list_e\", my_list_e)\n    print(\"my_list_d\", my_list_d)\n\nmy_list_function(my_list_c)\nprint(\"my_list_c\", my_list_c)\n\n'''\nextra\n'''\n\n\n\ndef value(value_a: int,value_b: int):\n    temp = value_a\n    value_a = value_b\n    value_b = temp\n    return value_a, value_b\n\nmy_int_d = 10\nmy_int_e = 20\nmy_int_f, my_int_g = value(my_int_d, my_int_e)\n\nprint(f\"{my_int_d} {my_int_e}\")\nprint(f\"{my_int_f} {my_int_g}\")\n\n# por referencia\ndef ref(value_a: list,value_b: list):\n    temp = value_a\n    value_a = value_b\n    value_b = temp\n    value_b.append(50)\n    return value_a, value_b\n\nmy_list_e = [10, 20]\nmy_list_f = [30, 40]\nmy_list_g, my_list_h = ref(my_list_e, my_list_f)\nprint(f\"{my_list_e} {my_list_f}\")\nprint(f\"{my_list_g} {my_list_h}\")"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/andresgcastillo.py",
    "content": "# Asignación por valor (inmutable)\nnum1 = 5\nnum2 = num1  # Asignación por valor\nnum2 = 10\nprint(num1)  # Imprime: 5\nprint(num2)  # Imprime: 10\n\n# Asignación por referencia (mutable)\nlist1 = [1, 2, 3]\nlist2 = list1  # Asignación por referencia\nlist2.append(4)\nprint(list1)  # Imprime: [1, 2, 3, 4]\nprint(list2)  # Imprime: [1, 2, 3, 4]\n\n# Función con parámetros por valor (inmutable)\ndef change_num(num):\n    num = 10\n\nnum = 5\nchange_num(num)\nprint(num)  # Imprime: 5\n\n# Función con parámetros por referencia (mutable)\ndef change_list(lst):\n    lst.append(4)\n\nlst = [1, 2, 3]\nchange_list(lst)\nprint(lst)  # Imprime: [1, 2, 3, 4]\n\n#Dificultad Extra\n\"\"\"\nEn Python, todos los parámetros se pasan por referencia. Sin embargo, los tipos primitivos son inmutables, por lo que no puedes cambiar su valor:\n\"\"\"\n\n# Programa 1: Pasando parámetros primitivos (inmutables)\ndef swap_values(val1, val2):\n    temp = val1\n    val1 = val2\n    val2 = temp\n    return val1, val2\n\na = 5\nb = 10\nprint(f\"Original a: {a}, b: {b}\")  # Original a: 5, b: 10\n\nnew_a, new_b = swap_values(a, b)\nprint(f\"Swapped a: {new_a}, b: {new_b}\")  # Swapped a: 10, b: 5\nprint(f\"After swap a: {a}, b: {b}\")  # After swap a: 5, b: 10\n\n# Programa 2: Pasando listas (mutables)\ndef swap_list_values(lst):\n    temp = lst[0]\n    lst[0] = lst[1]\n    lst[1] = temp\n    return lst[:]\n\nlst = [5, 10]\nprint(f\"Original lst: {lst}\")  # Original lst: [5, 10]\n\nnew_lst = swap_list_values(lst)\nprint(f\"Swapped lst: {new_lst}\")  # Swapped lst: [10, 5]\nprint(f\"After swap lst: {lst}\")  # After swap lst: [10, 5]\n\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/annnerssv.py",
    "content": "#VALOR Y REFERENCIA EN PYTHON\n\n\n#Tipos de datos por valor\n\na = 1\nprint(a)\nb = a \na = 2 \nprint(a)\nprint(b)\nprint(\"--------------------\")\n\n#Tipos de datos por referencia\n\nmi_lista = [1,2,3]\nprint(mi_lista)\nmi_lista_modificada = mi_lista \nmi_lista_modificada.append(4)\n\nprint(mi_lista)\nprint(mi_lista_modificada)\n\nprint(\"--------------------\")\n#Funciones con datos por valor\n\nmi_entero = 20\n\ndef fun_entero(mi_entero_modificado : int):\n    mi_entero_modificado = 40\n    print(mi_entero_modificado)\n    \nfun_entero(mi_entero)\nprint(mi_entero)\n\nprint(\"------------------\")\n#Funciones con datos por referencia\n\nmi_lista_a = [1,2,3]\n\ndef añadir_a_lista(mi_lista : list):\n    mi_lista.append(4)\n    print(mi_lista)\n    \nprint(mi_lista_a)\nañadir_a_lista(mi_lista_a)\nprint(mi_lista_a)\n\nprint(\"------------------\")\n\n#EJERCICIO EXTRA\n\n#FUNCION POR VALOR\n\nvalor_1 = 10\nvalor_2 = 20\n\ndef modificador_por_valor(mi_valor_1 : int, mi_valor_2 : int):\n    mi_valor_3 = mi_valor_1\n    mi_valor_4 = mi_valor_2\n    \n    mi_valor_1 = mi_valor_4\n    mi_valor_2 = mi_valor_3\n    \n    print(mi_valor_1)\n    print(mi_valor_2)\n\nmodificador_por_valor(valor_1,valor_2)\nprint(valor_1)\nprint(valor_2)\n\n#FUNCION POR REFERENCIA\n\nlista_1 = [1,2,3]\nlista_2 = [4,5,6]\n\ndef modificar_por_referencia(mi_lista_1 : list, mi_lista_2 : list):  \n    mi_lista_3 = mi_lista_2\n    mi_lista_4 = mi_lista_1\n    \n    print(mi_lista_3)\n    print(mi_lista_4)\n\nmodificar_por_referencia(lista_1, lista_2)\nprint(lista_1)  \nprint(lista_2)  \n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/any7dev.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */ \"\"\"\n\n# Tipo de datos valor\nentero = 10\notro = 5\nsuma = entero + otro\nprint(entero)\nprint(otro)\nprint(suma)\n\n# Tipo de dato referencia\nlista = [1, 2, 5, 10]\notra = [3, 4, 8, 6, 7]\nprint(lista)\nprint(otra)\nlista.append(otra)\nprint(lista)\n\n# Paso por valor\ndef valor(numero):\n    numero += 5\n\nnum = 2\nvalor(num)\nprint(num)\n\ndef por_valor(cadena):\n    cadena = cadena.split(\" \")\n\ncadena = \"Mi cadena\"\npor_valor(cadena)\nprint(cadena)\n\n# Paso por referencia\ndef referencia(lista):\n    for i, _ in enumerate(lista):\n        lista[i] += 5\n\nlista = [0, 1, 2, 3, 4, 5]\nreferencia(lista)\nprint(lista)"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/avcenal.py",
    "content": "\"\"\"VALOR Y REFERENCIA\n\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n\"\"\"\n#ASIGNACIÓN DE VARIABLES POR VALOR Y POR REFERENCIA\n#Por valor, Python realiza una asignación por valor en datos \"simples\"\nprint(\"Asignación por valor\")\na = 10\nprint(id(a))\nb = a\nprint(id(b)) #aqui se puede observar que b apunta a la misma referencia en memoria que a\na += 5\nprint(id(a)) #pero al modificar a sumándole 5 su referncia en memoria cambia\nprint(a)\nprint(b)\n\n#Por referencia, en cambio Python realiza una asignación por referencia para datos complejos\nprint(\"\\n\")\nprint(\"Asignación por referencia\")\nprint(\"Con Listas\")\none_list = [1,2,3,4]\nfor element in one_list: #usando este loop los valores originales de la lista no cambian\n    element *= 2\nprint(one_list)\n\nfor index in range (0,len(one_list)): #pero si usamos este, al acceder al valor mediante la posición, el valor queda modificado\n    one_list[index] *= 2\nprint(one_list)\n\nprint(\"\\n\")\nprint(\"Con diccionarios\")\n\nx = {\n    \"a\":10,\n    \"b\":15\n}\nprint(id(x))\ny = x\nprint(id(y))\nx[\"a\"] = x[\"a\"]+5\nx[\"b\"] = x[\"b\"]+10\n\nprint(x)\nprint(y)\n\n#FUNCIONES CON VARIABLES POR VALOR Y POR REFERENCIA\n#Por valor, igual que antes, datos simples se pasarán siempre por valor\n\ndef increase_value(value):\n    return value+5\n\nnumber = 3\nprint(increase_value(number)) #al ser un tipo de dato simple, aqui aparece modificado (+5)\nprint(number) #y aqui continúa con el mismo valor\n\n#Por referencia, igual, solo datos complejos como las listas\n\ndef append_value(one_list):\n    one_list.append(10) #se hace un append a la lista del número 10 sin retornarla\n    print(one_list)\n\nappend_value(one_list.copy()) #si le paso como parámetro una copia de la lista original \nprint(one_list) #dicha lista original no se modifica\n\nappend_value(one_list) #en cambio, si le paso directamente la lista original\nprint(one_list) #se modifica con el append del número 10\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n\"\"\"\ndef exchange_valor (value1, value2):\n    temp = value1\n    value1 = value2\n    value2 = temp\n    return value1,value2\n\nvar_1 = 5\nvar_2 = 7\nnew_var_1, new_var_2 = exchange_valor(var_1,var_2)\nprint(f\"Los valores de las primeras variables son: {var_1} y {var_2}\")\nprint(f\"Los nuevos valores son: {new_var_1} y {new_var_2}\")\n\ndef exchange_ref (list_1,list_2):\n    temp = list()\n    for index in range(0,len(list_1)):\n        temp.append(list_1[index])\n    list_1.clear()\n    for index in range(0,len(list_2)):\n        list_1.append(list_2[index])\n    list_2.clear()\n    for index in range(0,len(temp)):\n        list_2.append(temp[index])\n    return list_1,list_2\n\nvar_3 = [1,2,3]\nvar_4 = [4,5,6]\nnew_var_3, new_var_4 = exchange_ref(var_3.copy(),var_4.copy()) #si quitamos el copy() los valores de las variables originales se modificarán\nprint(f\"Los valores de las primeras variables son: {var_3} y {var_4}\")\nprint(f\"Los nuevos valores son: {new_var_3} y {new_var_4}\")\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/blancowilson.py",
    "content": "x = 5\ny = x  # Assign the value of x to y\n\ny = 10  # Modify y, but it won't affect x\n\nprint(x)  # Output: 5\nprint(y)  # Output: 10\n\n# Value assignment example with a function and variables passed by value -----------------------------------------------------------------------\nnumber_list = [1, 2, 3]\nPRINCIPAL_VAR = 5\n\n# Function with a variable passed by value\ndef double_value(number):\n    number *= 2\n    return number\n\nprint(double_value(PRINCIPAL_VAR))\nprint(PRINCIPAL_VAR, \"- Its value has not been affected\\n\")  # Original value remains unchanged\n\n# Function with a variable passed by reference\ndef double_values(numbers):\n    for item, number in enumerate(numbers):\n        numbers[item] *= 2\n\ndouble_values(number_list)\nprint(number_list, \"- Its value has been affected\")  # Original value modified\n\n# Value assignment example with tuples -----------------------------------------------------------------------\n# Tuples are immutable, so they behave as if they are passed by value:\noriginal_tuple = (1, 2, 3)\ntuple_copy = original_tuple  # Value assignment with tuples\n\ntuple_copy += (4,)  # Modify tuple_copy, but it won't affect original_tuple because tuples are immutable\n# The comma after the 4 is necessary to differentiate it from a simple parenthesis surrounding a value.\nprint(original_tuple)  # Output: (1, 2, 3)\nprint(tuple_copy)     # Output: (1, 2, 3, 4)\n\n# Value assignment example with function and variables passed by value -----------------------------------------------------------------------\n\noriginal_tuple = (1, 2, 3)  # Value assignment with tuples\n\ndef modify_tuple(tupla):\n    tupla = tupla + (4,)  # Create a new tuple and assign it to the local variable 'tupla'\n    print(\"Inside the function:\", tupla)  # The new tuple created inside the function does not affect the original tuple outside the function.\n\nmodify_tuple(original_tuple)\nprint(\"Outside the function:\", original_tuple)  # Output: (1, 2, 3)\n\n# Value assignment by reference -----------------------------------------------------------------------\n# The variable points to the same object in memory. Changes to a variable affect both the function and outside the function\n# The original variable is directly modified, so the modifications affect the variable outside the function.\n\nlist1 = [1, 2, 3]\nlist2 = list1  # Assign list1's reference to list2\n\nlist2.append(4)  # Modify list2, and it affects list1\n\nprint(\"list1:\", list1)  # Output: [1, 2, 3, 4]\nprint(\"list2:\", list2)  # Output: [1, 2, 3, 4]\n\n# Another example with a list -----------------------------------------------------------------------\n\noriginal = [1, 2, 3]  # Assign the list to original\ncopy = original  # original and copy are the same list\n\noriginal[0] = 99  # Modify original\n\noriginal = [4, 5, 6]  # Reassign a new list to original\nprint(original)  # Output: [4, 5, 6]\nprint(copy)  # Output: [99, 2, 3]\n\n# Value assignment example with function and variables passed by reference -----------------------------------------------------------------------\n\nx = [10, 20, 30]\ndef function(input_param):\n    input_param.append(40)\n\nfunction(x)\nprint(x)  # Output: [10, 20, 30, 40]\n\n\n# Note: Reassigning is different from modifying -----------------------------------------------------------------------\n# They are different objects, and the original does not change because I am not modifying the variable, but reassigning it, which creates a new temporary one\n\nx = [10, 20, 30]\ndef function_obj(entry):\n    entry.append(40)\n\nfunction_obj(x)\nprint(x)    # Output: [10, 20, 30, 40]\n\n\n# Note, reassigning is different from modifying ----------------------------------------------\n# They are different objects, and the original does not change because I am not modifying the variable, but reassigning it, which creates a new temporary one\nx = [10, 20, 30]\ndef function(input_var):\n    input_var = []\n\nfunction(x)\nprint(x)    # Output: [10, 20, 30]\n\n\n# id() function -------------------------------------------------------------\n# This function returns a unique identifier for each object.\n# Returning to the first example, we can see how the objects that \"x\" and \"input_var\" point to are different\n\n# id with example of value variable -------------------------------------------------------------\nx = 10\nprint(\"id value variable: \", id(x)) # 140724755286744\ndef function(input_var):\n    input_var = 0\n    print(id(input_var)) # 140724755286744\n\nfunction(x)  # Output: 10\n\n# id with example of reference variable -------------------------------------------------------------\nx = [10, 20, 30]\nprint(\"id reference variable: \", id(x)) # 1737715235264\ndef function(input_var):\n    input_var.append(40)\n    print(id(input_var)) # 1737715235264\n\nfunction(x)  # Output: [10, 20, 30, 40]\n\n# id with the last example -------------------------------------------------------------\n# It creates a new list in memory and assigns the variable input_var to that new list\n# the id of input_var inside the function will be different from the id of x outside the function.\n\nx = [10, 20, 30]\nprint (id(x))   #1737715235200\ndef function(input_var):\n    input_var = []\n    print (id(input_var)) #1737715235264\n\nfunction(x)\nprint(x)    # Output: [10, 20, 30]\n\n\n\nprint()\nvalue_variable1 = 1             # integer\nvalue_variable2 = \"Moure\"       # string\n\nreference_variable1 = [30, 60, 90]             # list\nreference_variable2 = {True, \"set\", 0}    # set\n\ndef swap_value_variables(var1, var2):\n    var1, var2 = var2, var1\n    print(f\"Var1 that was 1, inside the function: {var1}\")\n    print(f\"Var2 that was 'Moure', inside the function: {var2}\")\n    return var1, var2\n\ndef swap_reference_variables(ref1, ref2):\n    ref1, ref2 = ref2, ref1\n    return ref1, ref2\n\n# call the functions\nresult_value1, result_value2 = swap_value_variables(value_variable1, value_variable2)\nresult_reference1, result_reference2 = swap_reference_variables(reference_variable1, reference_variable2)\n\n# print results\nprint()\nprint(\"Whether it's value or reference, it reverses the values\")\nprint(f\"Original Values: {value_variable1}, {value_variable2}\")\nprint(f\"After passing through the function: {result_value1}, {result_value2}\")\nprint(f\"Original Ref: {reference_variable1}, {reference_variable2}\")\nprint(f\"After passing through the function: {result_reference1}, {result_reference2}\")\n\n\n# test another function, assign outside the function -------------------------------------------------------------\nprint()\nprint(\"It's a list, it's mutable, and it's by reference, it modifies both\")\nlist1 = [1, 2, 3]\nprint (\"Original List1:\", list1)\nlist2 = list1     \nprint(\"List1 reference assigned to List2 outside the function\")\nprint(\"Original List2:\", list2)\nnum=4\n\ndef add_number(temp_list):\n    temp_list.append(num) \n    print(\"Temporary list inside the function:\", temp_list)\n\nadd_number(list2)\nprint(\"Added number 4 to list2 with the add_number function...\")\nprint(\"List1:\", list1)\nprint(\"List2:\", list2)\nprint(\"Both have been modified and only passed the 2 through the add function\")\n\n# retrieve the previous list I reversed: reference_variable1 = [30, 60, 90]  \n# another test, assign inside the function -------------------------------------------------------------\nprint()\nprint(\"Trying to assign inside the function ref1 as ref2\")\nprint(\"Original ref1:\", reference_variable1)\nprint(\"Original ref2:\", reference_variable2)\ndef assign_same_reference_vars(rv1, rv2):\n    rv2= rv1\n    return rv1, rv2\n\nnew_rv1, new_rv2= assign_same_reference_vars(reference_variable1, reference_variable2)\nprint(\"New ref1:\", new_rv1)\nprint(\"New ref2:\", new_rv2)\n\n\n# Another test of Modifying by reference -------------------------------------------------------------\nprint()\nnumbers = [1,2,3]\nletters = [\"a\",\"b\",\"c\"]\nprint(\"Originals before function:\",numbers, letters)\n\ndef modify_nums_and_letters(value1, value2):\n    numbers.append(value1)\n    letters.append(value2)\n    return(numbers, letters)\n\nnumbers2 , letters2 = modify_nums_and_letters(value1=4, value2=\"d\")\n\nprint(\"With addition:\", numbers2, letters2)"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/c3sarmx.py",
    "content": "\n\"\"\"\n/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n */\n\"\"\"\n\n# Tipos de datos por valor\n# int, float, bool, str, tuple\n\na = 10\nb = a # b \"copia\" la referencia al mismo int (da igual, es inmutable)\nb = 99 # # reasignación: b ahora apunta a otro int\n\nprint(a)\nprint(b)\n\n# INMUTABLES: str\ns1 = \"hola\"\ns2 = s1\ns2 += \"!!!\"  # esto crea un string nuevo (no muta el anterior)\n\nprint(s1)  # \"hola\"\nprint(s2)  # \"hola!!!\"\n\n# MUTABLES: list\nlista1 = [1, 2, 3]\nlista2 = lista1     # ambas variables apuntan a la MISMA lista\n\nlista2.append(999)  # mutación: cambia el objeto compartido\n\nprint(lista1)  # [1, 2, 3, 999]\nprint(lista2)  # [1, 2, 3, 999]\n\n\"\"\"\nFunciones: “por valor” vs “por referencia” (lo que pasa de verdad)\n\"\"\"\n\n# Caso A: inmutable (no cambia afuera)\ndef sumar_uno(n):\n    n += 1      # reasigna n a un NUEVO int\n    print(\"Dentro:\", n)\n\nx = 5\nsumar_uno(x)\n\nprint(\"Fuera:\", x)  # sigue siendo 5\n\n# Caso B: mutable (sí cambia afuera si mutas)\ndef agregar_elemento(lista):\n    lista.append(\"🔥\")   # mutación del objeto\n    print(\"Dentro:\", lista)\n\nmi_lista = [\"a\", \"b\"]\nagregar_elemento(mi_lista)\n\nprint(\"Fuera:\", mi_lista)  # se queda con el \"🔥\"\n\n# Caso C: mutable pero REASIGNADO (no cambia afuera)\ndef reemplazar_lista(lista):\n    lista = [0, 0, 0]   # reasignación: ahora lista apunta a otra lista\n    print(\"Dentro:\", lista)\n\noriginal = [1, 2, 3]\nreemplazar_lista(original)\n\nprint(\"Fuera:\", original)  # sigue [1, 2, 3]\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n* Crea dos programas que reciban dos parámetros (cada uno) definidos como\n* variables anteriormente.\n* - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n*   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n*   se asigna a dos variables diferentes a las originales. A continuación, imprime\n*   el valor de las variables originales y las nuevas, comprobando que se ha invertido\n*   su valor en las segundas.\n*   Comprueba también que se ha conservado el valor original en las primeras.\n\"\"\"\n\n\"\"\"\nPrograma A (por “valor”): recibe 2 inmutables (int/str/tuple), los intercambia adentro, retorna los nuevos.\n✅ Originales no cambian.\n\"\"\"\n\ndef swap_valor(a, b):\n    a, b = b, a\n\n    return a, b\n\na1 = 10\nb1 = 20\n\nnuevo_a1, nuevo_b1 = swap_valor(a1, b1)\n\nprint(\"Originales: \", a1, b1)\nprint(\"Nuevas: \", nuevo_a1, nuevo_b1)\n\n\"\"\"\n2) Programa B: swap “por referencia” (mutables)\n\"\"\"\n\ndef swap_referencia(lista_a, lista_b):\n    temp_a = lista_a[:]\n    temp_b = lista_b[:]\n\n    lista_a.clear()\n    lista_a.extend(temp_b)\n    \n    lista_b.clear()\n    lista_b.extend(temp_a)\n\n    return lista_a, lista_b\n\nla = [1, 2]\nlb = [9, 8]\n\nnueva_la, nueva_lb = swap_referencia(la, lb)\n\nprint(\"Originales: \", la, lb)\nprint(\"Nuevas: \", nueva_la, nueva_lb)"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/cbuenrostrovalverde.py",
    "content": "'''\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n'''\n\n# Tipos de dato por valor.\n\nmy_int_a = 10\nmy_int_b = my_int_a\n# my_int_b = 20\n# my_int_a = 30\nprint(my_int_a)\nprint(my_int_b)\n\n# Tipos de dato por referencia.\n\nmy_list_a = [10, 20]\nmy_list_b = my_list_a\nmy_list_b.append(30)\nprint(my_list_a)\nprint(my_list_b) # Los datos por referencia no copian el valor, lo que hacen es copiar su dirección de la memoria.\n\n# Funciones con datos por valor\n\nmy_int_c = 10\ndef my_int_func(my_int: int):\n    my_int = 20\n    print(my_int)\n\nmy_int_func(my_int_c)\nprint(my_int_c)\n\n# Funciones con datos por referencia\n\nmy_list_c = [10, 20]\n\ndef my_list_func(my_list: list):\n    my_list.append(30)\n    my_list_d = my_list\n    my_list_d.append(40)\n\n    print(my_list)\n    print(my_list_d)\n\nmy_list_func(my_list_c)\nprint(my_list_c)\n\n'''\n* DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n'''\n\n# Por valor\n\ndef value(value_a: int, value_b: int) -> tuple:\n    temp = value_a\n    value_a = value_b\n    value_b = temp\n    return value_a, value_b\n\nmy_int_d = 10\nmy_int_e = 20\nmy_int_f, my_int_g = value(my_int_d, my_int_e)\n\nprint(f'{my_int_d}, {my_int_e}')\nprint(f'{my_int_f}, {my_int_g}')\n\n# Por referencia\n\ndef ref(value_a: list, value_b: list) -> tuple:\n    temp = value_a\n    value_a = value_b\n    value_b = temp\n    return value_a, value_b\n\nmy_list_e = [10, 20]\nmy_list_f = [30, 40]\nmy_list_g, my_list_h = ref(my_list_e, my_list_f)\n\nprint(f'{my_list_e}, {my_list_f}')\nprint(f'{my_list_g}, {my_list_h}')"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/cesar-ch.py",
    "content": "# Asignación de variables por valor\na = 10\nb = a\n\na = 5\n\nprint(a)  # 5\nprint(b)  # 10\n\n# Asignación de variables por referencia\nx = {\"a\": 10, \"b\": 5}\ny = x\n\nx[\"a\"] = 12\nx[\"b\"] = 24\n\nprint(x)  # {'a': 12, 'b': 24}\nprint(y)  # {'a': 12, 'b': 24}\n\n\n# Función con parámetro por valor\ndef cambiar_valor(numero):\n    numero = 100\n    print(numero)  # 100\n\n\nnumero = 5\ncambiar_valor(numero)\n\nprint(numero)  # 5\n\n\n# Función con parámetro por referencia\ndef cambiar_referencia(objeto):\n    objeto[\"a\"] = 100\n    print(objeto)  # {'a': 100}\n\n\nobjeto = {\"a\": 5}\ncambiar_referencia(objeto)\n\nprint(objeto)  # {'a': 100}\n\n\n# Ejemplo que intercambia los valores de dos variables por valor\ndef intercambiar_valores(c, d):\n    temp = c\n    c = d\n    d = temp\n\n    return c, d\n\n\n# Ejemplo que intercambia los valores de dos variables por referencia\ndef intercambiar_referencias(obj1, obj2):\n    temp = obj1.copy()\n    temp2 = obj2.copy()\n    temp3 = temp[\"value\"]\n    temp[\"value\"] = temp2[\"value\"]\n    temp2[\"value\"] = temp3\n    return temp, temp2\n\n\nc = 10\nd = 5\nobjA = {\"value\": 10}\nobjB = {\"value\": 5}\n\nnewc, newd = intercambiar_valores(c, d)\nprint(\"Valores iniciales:\", c, d)  # 10 5\nprint(\"Valores por valor:\", newc, newd)  # 5 10\n\nnewObjA, newObjB = intercambiar_referencias(objA, objB)\nprint(\"Valores iniciales:\", objA, objB)  # {'value': 10} {'value': 5}\nprint(\"Valores por referencia:\", newObjA, newObjB)  # {'value': 5} {'value': 10}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/clmiranda.py",
    "content": "# VALOR Y REFERENCIA\n\n# ASIGNACIÓN DE VARIABLES POR VALOR\nv1 = 150\nv2 = v1\nv1 = 100\nprint(f\"Valor de v1: {v1}\")\nprint(f\"Valor de v2: {v2}\")\n\n\n# ASIGNACIÓN DE VARIABLES POR REFERENCIA\nlst1 = [14, 19, 7, 36]\nlst2 = lst1\nlst1.extend([28, 95])\nprint(f\"Valor de v1: {lst1}\")\nprint(f\"Valor de v2: {lst2}\")\n\n\n# FUNCIONES CON VARIABLES QUE SE LES PASAN POR VALOR\nvalor = 123\n\ndef por_valor(val):\n    val = 456\n    return val\n\nprint(f\"Valor retornado por la función: {por_valor(valor)}\")\nprint(f\"Valor de la variable local: {valor}\")\n\n\n\n# FUNCIONES CON VARIABLES QUE SE LES PASAN POR REFERENCIA\ndef por_referencia(lst):\n    lst.sort(reverse=True)\n    return lst\n\nlst3 = [17, 45, 12, 60, 34]\nprint(f\"Lista retornada por la función: {por_referencia(lst3)}\")\nprint(f\"Valor de la lista local: {lst3}\")\n\n\n\n# EJERCICIO - DIFICULTAD EXTRA\n\n# PARÁMETROS PASADOS POR VALOR\ndef by_value(a, b):\n    changeable = a\n    a = b\n    b = changeable\n    return a, b\n\nval_a, val_b = 100, 200\nval_c, val_d = by_value(val_a, val_b)\n\nprint(f\"Valores originales: {val_a}, {val_b}\")\nprint(f\"Valores intercambiados: {val_c}, {val_d}\")\n\n\n\n# PARÁMETROS PASADOS POR REFERENCIA\ndef by_reference(a, b):\n    changeable = a\n    a = b\n    b = changeable\n    return a, b\n\nlist_a = [1, 2, 3]\nlist_b = [4, 5, 6]\nlist_c, list_d = by_reference(list_a, list_b)\n\nprint(f\"Valores originales: {list_a}, {list_b}\")\nprint(f\"Valores originales: {list_c}, {list_d}\")\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/cristianfloyd.py",
    "content": "\n\"\"\"  * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n * \"\"\"\n\n# Asignación por valor (enteros son inmutables)\nmi_entero_a = 5\nmi_entero_b = mi_entero_a\nmi_entero_b = 10\nprint(mi_entero_a) # imprime 5\nprint(mi_entero_b) # imprime 10\n\n# Asignación por referencia (listas son mutables)\nmi_lista_a = [3, 7, 44]\nmi_lista_b = mi_lista_a\nmi_lista_b.append(99)\nprint(f\"Lista A: {mi_lista_a}\") # imprime [3, 7, 44, 99]\nprint(f\"Lista B: {mi_lista_b}\") # imprime [3, 7, 44, 99]\n\n# funciones con datos por valor\ndef funcion_entero(mi_entero: int):\n    mi_entero = 15\n    print(f\"Dentro de la función: {mi_entero}\") # imprime 15\n\nmi_entero_c = 5\nfuncion_entero(mi_entero_c)\nprint(f\"Fuera de la función: {mi_entero_c}\") # imprime 5\n\n# funciones con datos por referencia\ndef funcion_lista(mi_lista: list):\n    mi_lista.append(88)\n    print(f\"Dentro de la función: {mi_lista}\") # imprime la lista con 88 añadido\n\nmi_lista_c = [1, 2, 3]\nfuncion_lista(mi_lista_c)\nprint(f\"Fuera de la función: {mi_lista_c}\") # imprime la lista con 88 añadido\n\n\"\"\"  \n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como\n * variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime\n *   el valor de las variables originales y las nuevas, comprobando que se ha invertido\n *   su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */ \"\"\"\n\n # defino la función para intercambiar valores por valor\ndef intercambiar_por_valor(a: int, b: int) -> tuple:\n    return b, a\n\ndef intercambiar_por_referencia(lista1: list, lista2: list) -> tuple:\n    lista1[:], lista2[:] = lista2[:], lista1[:]\n    return lista1, lista2\n\nlista_d = [10, 20]\nlista_e = [30, 40]\n\nprint(f\"Valores originales: {mi_entero_a, mi_entero_b}\")\nprint(f\"Valores invertidos por valor: {intercambiar_por_valor(mi_entero_a, mi_entero_b)}\")\nprint(f\"Listas originales: {lista_d, lista_e}\")\nprint(f\"Listas invertidas por referencia: {intercambiar_por_referencia(lista_d, lista_e)}\")\n\nprint(f\"Listas originales: {lista_d, lista_e}\") # compruebo que las originales han cambiado\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/danielhdzr.py",
    "content": "# #05 VALOR Y REFERENCIA\n#### Dificultad: Fácil | Publicación: 29/01/24 | Corrección: 05/02/24\n\n## Ejercicio\n\n\"\"\"\n* EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n \"\"\"\n\ndef main():\n    # Variables por valor (inmutables)\n    # al inicio \"b\" vale lo mismo que \"a\", pero son variables independientes\n    a = 5\n    b = a \n    b += 5\n    print(a)\n    print(b)\n\n    # Variables por referencia (mutables)\n    # lista \"b\" se posiciona en el mismo lugar en memoria que lista \"a\", ambas son referencia a la misma lista\n    a = [1, 2, 3]\n    print(\"Lista a\", a)\n    b = a\n    b.append(4)\n    print(\"Lista a\", a)\n    print(\"Lista b\", b)\n\n    # Para crear una lista independiente que herede los valores de otra, se debe hacer una copia explicita\n    x = [1, 2, 3]\n    y = x.copy()\n    y.append(4)\n    print(\"Lista x\", x)\n    print(\"Lista y\", y)\n\n    print()\n\n\n    # funciones con variables \"por valor\". Sin retorno\n    # Las dos variables \"numero1\" son independientes (inmutables)\n    numero1 = 5\n    def func_val(valor):\n        numero1 = valor * 3\n        print(f\"Variable numero1 dentro de la funcion: {numero1}\")\n    \n    func_val(numero1)\n    print(f\"Variable numero1 fuera de la funcion: {numero1}\")\n\n    print()\n\n    # Con retorno\n    def func_val_return(valor):\n        return valor * 2\n    \n    print(func_val_return(5) * 2)\n\n    print()\n\n    # funciones con variables \"por referencia\"\n    lista_original = [1, 2, 3]\n    lista2 = lista_original.copy()\n    \n    def func_ref(lista2):\n        lista3 = lista2\n        lista3.append(4)\n        return lista3\n    \n    lista_nueva = func_ref(lista2)\n\n    print(f\"La lista original era: {lista_original}\")\n    print(f\"La lista 2 es: {lista2}\")\n    print(f\"La lista 3 es: {lista_nueva}\")\n    print(f\"La lista 2 se vio modificada al actualizar la lista 3 porque ambas ocupan el mismo sitio en la memoria\")\n    print(f\"Sin embargo la lista original se mantuvo intacta gracias a que se copio mediante el metodo copy()\")\n        \n\n    '''\n    DIFICULTAD EXTRA (opcional):\n    * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n    * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n    *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n    *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n    *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n    *   Comprueba también que se ha conservado el valor original en las primeras.  \n    '''\n\n \n    var1 = 1\n    var2 = 2\n    # Las variables fuera y dentro de la funcion comparten nombre, pero son variables independientes\n    def val_function(var1, var2):\n        var1 = 3\n        var2  = 4\n        return var1, var2\n    print(f\"Variables 1 y 2 fuera de la funcion: {var1}, {var2}\")\n    print(f\"Variables 1 y 2 dentro de la funcion: {val_function(var1, var2)}\")\n\n    print()\n\n    \"\"\"\n    La lista 1 se mantiene igual ya que no se le modifica dentro de la funcion.\n    La lista 2 si sufre cambios dentro de la funcion, y estos se manifiestan fuera de la funcion \n    debido a que son exportados mediante el return, y la variable externa que los contiene, al ser usada, \n    modifica el codigo origianl\n    \"\"\"\n    lista1 = [1,2,3]\n    lista2 = [1,2,3,4]\n    def ref_function(par1, par2):\n        par1 = lista1\n        par2 = lista2\n        par2.append(5)\n        return par1, par2\n    \n    resultado = ref_function(lista1, lista2)\n    print(\"Resultados encapsulando la funcion en una variable externa\")\n    print(f\"Lista 1 y 2 fuera de la funcion: {lista1}, {lista2}\")\n    print(f\"Lista 1 y 2 dentro de la funcion: {resultado}\")\n\n    print()\n\n    \"\"\"\n    Exactamente el mismo codigo, exceptuando la variable externa que encapsula el return de la funcion.\n    El resultado es que la variable que cambia dentro de la funcion, se mantiene intacta fuera de la misma\n    \"\"\"\n    lista1 = [1,2,3]\n    lista2 = [1,2,3,4]\n    def ref_function(par1, par2):\n        par1 = lista1\n        par2 = lista2\n        par2.append(5)\n        return par1, par2\n    \n    print(\"Resultados sin encapsular la funcion en una variable externa\")\n    print(f\"Lista 1 y 2 fuera de la funcion: {lista1}, {lista2}\")\n    print(f\"Lista 1 y 2 dentro de la funcion: {ref_function(lista1, lista2)}\")\n    \nif __name__==\"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/davidrguez98.py",
    "content": "\"\"\" # #05 VALOR Y REFERENCIA\n> #### Dificultad: Fácil | Publicación: 29/01/24 | Corrección: 05/02/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**. \"\"\"\n\n# Tipos de datos por valor\n\nmy_int_a = 10\nmy_int_b = my_int_a\nmy_int_b = 20\n\"\"\" my_int_a = 30 \"\"\"\nprint(my_int_a)\nprint(my_int_b)\n\n# Tipos de dato por referencia\n\nmy_list_a = [10, 20]\nmy_list_b = my_list_a\nmy_list_b.append(30)\nprint(my_list_a)\nprint(my_list_b)\n\n#Funciones de datos por valor\n\nmy_int_c = 10\n\ndef my_int_func(my_int: int):\n    my_int = 20\n    print(my_int)\n\nmy_int_func(my_int_c)\nprint(my_int_c)\n\n# Funciones con datos por referencia\n\nmy_list_c = [10, 20]\n\ndef my_list_func(my_list: list):\n    my_list.append(30)\n\n    my_list_d = my_list\n    my_list_d.append(40)\n\n    print(my_list)\n    print(my_list_d)\n\nmy_list_func(my_list_c)\nprint(my_list_c)\n\n#DIFICULTAD EXTRA\n\n#Por valor\nint_a = 10\nint_b = 20\n\ndef value(value_a: int, value_b: int):\n    value_a = int_b\n    value_b = int_a\n    print(value_a, value_b)\n\nvalue(int_a, int_b)\nprint(int_a, int_b)\n\n#Por referencia\nlist_a = [10, 20]\nlist_b = [30, 40]\n\ndef value2(value_la: list, value_lb: list):\n    value_la = list_b\n    value_lb = list_a\n    value_la.append(50)\n    value_lb.append(60)\n    print(value_la, value_lb)\n\nvalue2(list_a, list_b)\nprint(list_a, list_b)\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/dimasb69.py",
    "content": "'''\n* - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y\n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como\n * variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime\n *   el valor de las variables originales y las nuevas, comprobando que se ha invertido\n *   su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n'''\n\n# Asignación de variable por valor\nprint('Se asigna por valor cuando se llama a una variable que contiene un valor')\na = 2\nb = 4\nprint(a)\nprint(b)\nprint('\\n\\n')\n\n# Asignación de variable por referencia\nprint('Se asigna por referencia cuando se llama a una variable por una posición de memoria dentro de una lista')\nx = [2, 4]\nx[0] = 3\nx[1] = 5\nprint(x[0])\nprint(x[1])\nprint('\\n\\n')\n\n# Funciones con parámetros por valor y por referencia\n\ndef sumar(a, b):\n    return a + b\n\ndef sumar2(a, b):\n    a[0] = a[0] + b[0]\n    a[1] = a[1] + b[1]\n    return a\n\nprint('\\n\\n\\n')\nwhile True:\n    print(\"1. Sumar por valor\")\n    print(\"2. Sumar por referencia\")\n    print(\"3. Salir\")\n    op = int(input(\"Elige una opció: \"))\n    if op == 1:\n        a = int(input(\"Dame el primer valor: \"))\n        b = int(input(\"Dame el segundo valor: \"))\n        print(sumar(a, b))\n    elif op == 2:\n        a = [int(input(\"Dame el primer valor de la primera lista: \")), int(input(\"Dame el segundo valor de la primera lista: \"))]\n        b = [int(input(\"Dame el primer valor de la segunda lista: \")), int(input(\"Dame el segundo valor de la segunda lista: \"))]\n        print(sumar2(a, b))\n    elif op == 3:\n        print(\"Saliendo...\")\n        break"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/duendeintemporal.py",
    "content": "#5 { Retos para Progarmadores } VALOR Y REFERENCIA\nlog = print  # Shortening print function to log\n\n# Variables by Value\n\n# In Python, immutable data types (such as int, float, str, and tuple) are assigned by value.\n# This means that when you assign a primitive value to a variable, a copy of that value is made.\n\na = 44  # a is an integer (immutable type)\nb = a   # b is assigned the value of a\n\nlog(a)  # 44\nlog(b)  # 44\n\nb += 20  # Changing b does not affect a\nlog(a)  # 44\nlog(b)  # 64\n\n# Variables by Reference\n\n# In Python, mutable data types (such as list, dict, and set) are assigned by reference.\n# This means that when you assign a mutable object to a variable, you are actually assigning a reference to that object, not a copy of it.\n\nobj1 = {\"name\": \"Julia\"}  # obj1 is a dictionary (mutable type)\nobj2 = obj1                # obj2 is assigned the reference of obj1\n\nlog(obj1[\"name\"])  # Julia\nlog(obj2[\"name\"])  # Julia\n\nobj2[\"name\"] = \"Karla\"  # Changing obj2 affects obj1 because they reference the same object\nlog(obj1[\"name\"])  # Karla\nlog(obj2[\"name\"])  # Karla\n\nobj2[\"age\"] = 32\nlog(obj2[\"age\"])  # 32\nlog(obj1[\"age\"])  # 32\n\n# Lists (Mutable Type) in Python are also reference types.\n\narr1 = [7, 4, 90]  # arr1 is a list (mutable type)\narr2 = arr1        # arr2 is assigned the reference of arr1\n\nlog(arr1)  # [7, 4, 90]\nlog(arr2)  # [7, 4, 90]\n\narr2.append(42)  # Modifying arr2 affects arr1\nlog(arr1)  # [7, 4, 90, 42]\nlog(arr2)  # [7, 4, 90, 42]\n\n# By Value: Immutable types (e.g., int, str) are copied when assigned to a new variable.\n# By Reference: Mutable types (e.g., dict, list) are assigned by reference, meaning changes to one variable affect the other if they reference the same object.\n\n# In Python, functions are also first-class objects, which means they can be assigned to variables, passed as arguments, and returned from other functions.\n# When you assign a function to a variable, you are assigning a reference to that function, not a copy of it.\n\n# Functions Assigned by Reference\n\n# When you assign a function to a new variable, both variables point to the same function in memory.\n\ndef greet():\n    log(\"Hello everybody! It's time for coding...\")\n\ngreet_copy = greet  # greet_copy is assigned the reference of greet\n\ngreet()      # Hello everybody! It's time for coding...\ngreet_copy()  # Hello everybody! It's time for coding...\n\n# Changing the function reference\ngreet_copy = lambda: log(\"This world is turning into a weird scenario with all those AIs, M2M (technology), and there are cyber attacks that can explode beepers, cell phones, and big media that shows only a tiny fragment of reality.\")\n\ngreet_copy()  # This world is turning into a weird scenario with all those AIs, M2M (technology), and there are cyber attacks that can explode beepers, cell phones, and big media that shows only a tiny fragment of reality.\n\n# Passing Functions as Arguments\n\n# You can pass functions as arguments to other functions. This demonstrates that functions are treated as reference types.\n\ndef call_funct(fn):\n    fn()\n\ndef say_bye_lady():\n    log(\"See you later, lady!\")\n\ncall_funct(say_bye_lady)  # See you later, lady!\n\n# Returning Functions from Functions\n\n# You can also return functions from other functions, which shows that functions can be created dynamically and assigned by reference.\n\n# Function that returns another function (closure)\ndef say_something_to(greeting):\n    return lambda name: log(f\"{greeting}, {name}!\")\n\nsay = say_something_to(\"Welcome to coding lab\")\nsay2 = say_something_to(\"It's a long way home\")\n\nsay(\"Nicky\")  # Welcome to coding lab, Nicky\nsay2(\"Jhon\")  # It's a long way home, Jhon\n\n# Modifying Functions\n\n# Since functions are reference types, if you modify a function that is referenced by multiple variables, it will affect all references.\n\ndef hi_miss():\n    log(\"Hello, miss. Have a beautiful day\")\n\nfunc_ref = hi_miss  # func_ref points to hi_miss\n\nfunc_ref()  # Hello, miss. Have a beautiful day\n\n# Modifying the original function\nhi_miss = lambda: log(\"Sometimes I feel jealous of the wind that caresses your hair, sometimes the rain....\")\n\nfunc_ref()  # Hello, miss. Have a beautiful day (still points to the original function)\n\n# But if we do, for example...\nfunc_ref = lambda: hi_miss()\n\nfunc_ref()  # Sometimes I feel jealous of the wind that caresses your hair, sometimes the rain.... (now every change in hi_miss will be reflected)\n\n# In Python, when you pass arguments to a function, the behavior depends on whether the argument is a primitive type (passed by value) or a reference type (passed by reference).\n\n# Function that takes a primitive type (passed by value)\ndef do_something(value):\n    value = 20  # This change does not affect the original variable\n    log(\"Value Inside do_something:\", value)  # Value Inside do_something: 20\n\n# Function that takes an object (passed by reference)\ndef set_user_name(obj, name):\n    obj['name'] = name  # This change affects the original object\n    log(\"Value Inside set_user_name:\", obj['name'])\n\n# Testing the functions\nnum = 'something'\nlog(\"Value Before do_something:\", num)  # Value Before do_something: something\ndo_something(num)\nlog(\"After do_something:\", num)  # After do_something: something (remains unchanged)\n\nuser = {'name': \"Luna\", 'age': 32}\nlog(\"Before set_user_name:\", user['name'])  # Before set_user_name: Luna\nset_user_name(user, 'Kia')  # Value Inside set_user_name: Kia\nlog(\"After set_user_name:\", user['name'])  # After set_user_name: Kia (changed)\n\n# Note: the same applies to lists that are reference values.\n\n# Simulating a window load event (not applicable in standard Python, but for demonstration)\ndef on_load():\n    body_style = {\n        'background': '#000',\n        'text-align': 'center'\n    }\n    \n    title = {\n        'text': 'Retosparaprogramadores #5.',\n        'font-size': '3.5vmax',\n        'color': '#fff',\n        'line-height': '100vh'\n    }\n    \n    log(\"Title:\", title['text'])\n    \n    # Simulating a delay (not applicable in standard Python, but for demonstration)\n    import time\n    time.sleep(2)\n    log('Retosparaprogramadores #5')  # this will be logged at the end\n\n# Call the simulated load function\non_load()\n\n# EXTRA DIFFICULTY (optional):\n\nuser1 = {\n    'name': 'Kasperle',\n    'age': 12\n}\n\nuser2 = {\n    'name': 'Snoopy',\n    'age': None\n}\n\nlog('user1:', user1)  # user1: {'name': 'Kasperle', 'age': 12}\nlog('user2:', user2)  # user2: {'name': 'Snoopy', 'age': None}\n\ndef change_user(obj1, obj2):\n    provisional = obj1.copy()  # Create a shallow copy\n    obj1.update(obj2)  # Update obj1 with obj2\n    obj2.update(provisional)  # Update obj2 with the original obj1\n\nchange_user(user1, user2)\n\nlog('user1:', user1)  # user1: {'name': 'Snoopy', 'age': None}\nlog('user2:', user2)  # user2: {'name': 'Kasperle', 'age': 12}\n\ndef swap_values(a, b):\n    return b, a  # Return the swapped values as a tuple\n\n# You can call the function and use tuple unpacking to assign the returned values to new variables:\n\nx = 85\ny = 17\n\nlog(\"Before swap:\", x, y)  # Before swap: 85 17\n\n# Call the function and unpack the returned tuple\nd, e = swap_values(x, y)\n\nlog(\"After swap:\", x, y)  # After swap: 85 17\nlog('New variables with values swapped:', d, e)  # New variables with values swapped: 17 85\n\n# Note: tuple unpacking allows us to achieve the effect of reference values with primitive values.\n# By using tuple unpacking, we can achieve both effects: conserving the original values or swapping the values.\nlog(\"Before swap:\", x, y)  # Before swap: 85 17\nx, y = swap_values(x, y)\n\nlog(\"After swap:\", x, y)  # After swap: 17 85\n\n# Note: using tuple unpacking allows us to achieve both effects: conserving the original values or swapping the values.\n\n# Note2: Keep in mind that when you use copying methods like copy(), it creates a shallow copy,\n# which means that if there are nested objects inside, the nested ones won't be copied.\n\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/eamartin96.py",
    "content": "# #05 VALOR Y REFERENCIA\n'''\nEJERCICIO\n- Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\". según\n  su tipo de dato.\n- Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y\n  \"por referencia\", y como se comportan en cada caso en el momento de ser modificadas.\n'''\n\n# Paso de dato por valor\n'''\nSi usamos un párametro pasado por valor, se creará una copia  local de la variable, lo que implica que cualquier\nmodificación sobre la misma no tendrá efecto sobre la original\n'''\nx = 10\n\ndef funcion(entrada):\n    entrada = 0\n\nfuncion(x)\nprint(x)\n\n# Paso de dato por referencia\n'''\nCon una variable pasada como referencia, se actuará directamente sobre la variable pasada, por lo que las\nmodificaciones afectarán a la variable original.\n'''\nx = [10, 20, 30]\n\ndef funcion(entrada):\n    entrada.append(40)\n\nfuncion(x)\nprint(x)\n\n# DIFICULTAD EXTRA\nprint(\"\\n----------------------------------------------------\")\nprint(\"EXTRA DIFFICULT\")\n'''\nCrea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente\n- Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n  Estos parámetros los intercambia entre ellos en su interior, los retorna y su retorno\n  se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n  variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n  Comprueba también que se ha conservado el valor original en las primeras.\n'''\n\n# Por valor\nvar1 = 10\nvar2 = 20\n\ndef valor(var1, var2):\n    temp = var1\n    var1 = var2\n    var2 = temp\n    return var1, var2\n\nvar3, var4 = valor(var1, var2)\n\nprint(f\"{var1}, {var2}\")\nprint(f\"{var3}, {var4}\")\n\n# Por referencia\nlist_a = [10, 20]\nlist_b = [30, 40]\n\ndef referencia(var1: list, var2: list):\n    temp = var1\n    var1 = var2\n    var2 = temp\n    return var1, var2\n\nlist_c, list_d = referencia(list_a, list_b)\nprint(f\"{list_a}, {list_b}\")\nprint(f\"{list_c}, {list_d}\")\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/evilpotato04.py",
    "content": "\n#/*\n# * EJERCICIO:\n# * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n# *   su tipo de dato.\n# * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n# *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n# * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n# *\n\n# asignación por valor\ngames = [\"Genshin Impact\", \"Sky\", \"Pokémon\"]\nano_de_publicacion = [2020, 2019, 1996]\n\nprint(games)\nprint(ano_de_publicacion)\n\n# asignación por referencia\ngames_ref = games\nano_de_publicacion_ref = ano_de_publicacion\n\nprint(\"-\"*10)\nprint(games_ref)\nprint(ano_de_publicacion_ref)\n\ngames_ref.append(\"The Legend of Zelda\")\nano_de_publicacion_ref.append(1986)\n\nprint(\"-\"*10)\nprint(games)\nprint(ano_de_publicacion)\nprint(games_ref)\nprint(ano_de_publicacion_ref)\n\n# funciones por valor\ndef agregar_nuevo_game(games: list, anos: list, nuevo_game: str, nuevo_ano: int):\n    print(\"-\"*10)\n    games_actualizados = []\n    for game in games:\n        games_actualizados.append(game)\n    games_actualizados.append(nuevo_game)\n\n    anos_actualizados = []\n    for ano in anos:\n        anos_actualizados.append(ano)\n    anos_actualizados.append(nuevo_ano)\n\n    print(games)\n    print(anos)\n    print(games_actualizados)\n    print(anos_actualizados)\n\nagregar_nuevo_game(games, ano_de_publicacion, \"Honkai Star Rail\", 2023)\n\nprint(games)\nprint(ano_de_publicacion)\n\n# funciones por referencia\ndef combinar_listas_de_games(games1: list, games2: list):\n    print(games1)\n    games1.extend(games2)\n    print(games1)\n\ncombinar_listas_de_games(games, [\"Palia\", \"Life Makeover\", \"Candy Crush\"])\nprint(games)\n\n# * DIFICULTAD EXTRA (opcional):\n# * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n# * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n# *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n# *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n# *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n# *   Comprueba también que se ha conservado el valor original en las primeras.\n# */\n\nprint(\"=\"*10)\n\nplayer_1 = \"Mario\"\nplayer_2 = \"Luigi\"\n\ndef cambiar_players(player_1: str, player_2: str):\n    players = [player_1, player_2]\n    player_1 = players[1]\n    player_2 = players[0]\n    print(player_1, \"and\", player_2)\n\n    return player_1, player_2\n\nprint(player_1, \"and\", player_2)\nplayer_1, player_2 = cambiar_players(player_1, player_2)\nprint(player_1, \"and\", player_2)\n\nprint(\"=\"*10)\n\ndef cambiar_players_ref(player_1: str, player_2: str):\n    player_1, player_2 = player_2, player_1\n    print(player_1, \"and\", player_2)\n\nprint(player_1, \"and\", player_2)\ncambiar_players_ref(player_1, player_2)\nprint(player_1, \"and\", player_2)\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/fborjalv.py",
    "content": "# DATOS POR VALOR Y REFERENCIA EN PYTHON \n\n\n# Datos por valor (primitivos)\n\nvar_a = 100\nvar_b = var_a\nvar_b = 150 \nvar_b = var_a\nprint(var_a)\nprint(var_b)\n\n# Datos por referencia \n\nlist_a = [100, 150]\nlist_b = [200, 250]\nprint(list_a)\nprint(list_b)\n\nlist_b = list_a # Desde esta declaración tienen la misma referencia de memoria\nprint(list_b)\n\nlist_b[0] = 300\nprint(list_b)\nprint(list_a)\n\n# Funciones con datos por valor\n\ndato_a = 100\n\ndef funcion_valor(dato: int):\n    dato  = 10\n    print(dato)\n\nfuncion_valor(dato_a)\nprint(dato_a)\n\n\n# Funciones por referencia\nlista_a = [500]\n\ndef funcion_ref(lista: list):\n    lista[0] = 100\n    print(lista)\n\nfuncion_ref(lista_a)\nprint(lista_a)\n\n# EJERCICIO\n\nnum1 = 4\nnum2 = 5\n\ndef func_valor (num_1: int, num_2: int):\n    temp = num_1\n    num_1 = num_2\n    num_2 = temp\n    return num_1, num_2\n\nvariable_a, variable_b = func_valor(num1, num2)\nprint(variable_a, variable_b)\n\n\nlist1 = [100, 200]\nlist2 = [500]\n\ndef func_ref (list_1: list, list_2: list):\n    temp = list_1\n    list_1 = list_2\n    list_2 = temp\n    return list_1, list_2\n\nlista_a, lista_b = func_ref(list1, list2)\nprint(lista_a, lista_b)"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/fishellVvv.py",
    "content": "# datos por valor\nmy_int_a = 10\nmy_int_b = my_int_a\nmy_int_a = 20\nprint(my_int_a)\nprint(my_int_b)\n\n# datos por referencia\nmy_list_a = [10, 20]\nmy_list_b = my_list_a\nmy_list_a.append(30)\nprint(my_list_a)\nprint(my_list_b)\n\n# funcion con datos por valor\ndef my_int_func(my_int: int):\n    my_int = 40\n    print(my_int)\n\nmy_int_c = 30\nmy_int_func(my_int_c)\nprint(my_int_c)\n\n# funcion con datos por referencia\ndef my_list_func(my_list: list):\n    my_list.append(60)\n    print(my_list)\n\nmy_list_c = [40, 50]\nmy_list_func(my_list_c)\nprint(my_list_c)\n\n# EXTRA\n\n# por valor\ndef cross_value(value_a: int, value_b: int) -> tuple:\n    temp = value_a\n    value_a = value_b\n    value_b = temp\n    return value_a, value_b\n\nmy_int_d = 100\nmy_int_e = 200\nmy_int_f, my_int_g = cross_value(my_int_d, my_int_e)\nprint(f\"{my_int_d}, {my_int_e}\")\nprint(f\"{my_int_f}, {my_int_g}\")\n\n# por referencia\ndef cross_ref(value_a: list, value_b: list) -> tuple:\n    temp = value_a\n    value_a = value_b\n    value_b = temp\n    return value_a, value_b\n\nmy_list_d = [100, 200]\nmy_list_e = [300, 400]\nmy_list_f, my_list_g = cross_ref(my_list_d, my_list_e)\nprint(f\"{my_list_d}, {my_list_e}\")\nprint(f\"{my_list_f}, {my_list_g}\")"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/franvozzi.py",
    "content": "# VARIABLES por valor y por referencia\n\n# Por valor\n\"\"\"\nx = 10\n    def funcionValor(entrada):\n        entrada = 0\n        print(entrada)\n        \n    funcionValor(x)\n\"\"\"\n# Por referencia\nx = [10, 20, 30]\ndef funcionReferencia (entrada):\n    entrada.append(40)\n    \nfuncionReferencia(x)\nprint(x)\n\n\"\"\"\nExtra\n\"\"\"\n# Por valor\ndef swap_by_value(a, b):\n    a, b = b, a\n    return a, b\n\n# Variables originales\nx = 10\ny = 20\n\n# Intercambiar por valor\nnew_x, new_y = swap_by_value(x, y)\n\nprint(\"Intercambio por valor:\")\nprint(f\"Original x: {x}, Original y: {y}\")\nprint(f\"Nuevo x: {new_x}, Nuevo y: {new_y}\")\n\ndef swap_by_reference(a, b):\n    a[0], b[0] = b[0], a[0]\n\n# Variables originales\nx_ref = [10]\ny_ref = [20]\n\n# Intercambiar por referencia\nswap_by_reference(x_ref, y_ref)\n\nprint(\"Intercambio por referencia:\")\nprint(f\"Original x_ref: {10}, Original y_ref: {20}\")\nprint(f\"Nuevo x_ref: {x_ref[0]}, Nuevo y_ref: {y_ref[0]}\")\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/franxiscodev.py",
    "content": "'''\nValor y Referencia\n'''\n# Tipos de datos por valor\n'''\nen las variables primitives, el valor se almacena en la variable\n\n'''\n\n# Tipos de datos por referencia\n''''     \nen las variables por referencia, la variable almacena una referencia a la dirección de memoria donde se almacena el valor\nson los tipos de datos no primitivos    \npor ejemplo, las listas, los diccionarios, los conjuntos, las tuplas, los objetos, etc.\nno cpian su valor, heredan su posición en la memoria        \n'''\n\n# ejemplo funciones param por valor\n\n\ndef my_func(x):\n    x = 20\n    print(x)    # 20\n\n\nx = 10\nmy_func(x)  # 20\nprint(x)    # 10\n\n# ejemplo funciones param por referencia\n\n\ndef my_func(x):\n    x.append(20)\n    print(x)    # [10, 20]\n\n\nx = [10]\nmy_func(x)  # [10, 20]\nprint(x)    # [10, 20]\n\n'''\nEXTRA\n'''\n# intercambiar el valor de 2 variables pasadas por valor\n\nprint(\"intercambiar el valor de 2 variables pasadas por valor\")\n\n\ndef value_swap(a: int, b: int) -> tuple:\n    a, b = b, a  # intercambiar el valor de 2 variables sin usar variable auxiliar tipo temp\n    print(f\"a: {a} b: {b}\")\n    return a, b\n\n\nmy_int_a = 10\nmy_int_b = 20\nprint(f\"my_int_a: {my_int_a} my_int_b: {my_int_b}\")\nmy_int_a, my_int_b = value_swap(my_int_a, my_int_b)\nprint(f\"my_int_a: {my_int_a} my_int_b: {my_int_b}\")\n\n# intercambiar el valor de 2 variables pasadas por referencia\n\n\ndef value_swap_ref(a: list, b: list) -> tuple:\n    # intercambiar el valor de 2 variables sin usar variable auxiliar tipo temp x referencia\n    a, b = b, a\n    # print(f\"a: {a} b: {b}\")\n    return a, b\n\n\nprint(\"intercambiar el valor de 2 variables pasadas por referencia\")\nmy_list_a = [10, 20]\nmy_list_b = [30, 40]\nprint(f\"my_list_a: {my_list_a} my_list_b: {my_list_b}\")\nmy_list_a, my_list_b = value_swap_ref(my_list_a, my_list_b)\nprint(f\"my_list_a: {my_list_a} my_list_b: {my_list_b}\")\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/garos01.py",
    "content": "# Ejemplo con enteros paso por valor\nx = 5\ny = x\nx = 10\n\nprint(y)\n\n# Ejemplo con listas paso por referencia\nlista1 = [1, 2, 3]\nlista2 = lista1\nlista1.append(4)\n\nprint(lista2)\n\n\n# Ejemplo de funciones por valor\ndef modificar_valor(numero):\n    numero = 10\n\n\nx = 5\nmodificar_valor(x)\nprint(x)\n\n\n# Ejemplo de funciones por referencia\ndef modificar_lista(lista):\n    lista.append(4)\n\n\nmi_lista = [1, 2, 3]\nmodificar_lista(mi_lista)\nprint(mi_lista)\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/ggilperez.py",
    "content": "# Problem #05 value & pointers\n\n# By value\nmy_int_1 = 1\nmy_int_2 = my_int_1\nmy_int_2 += 1\nprint(f\"{my_int_1 = }\")\nprint(f\"{my_int_2 = }\")\n\n# By references (pointer)\nmy_list_1 = [1]\nmy_list_2 = my_list_1\nmy_list_2.append(2)\nprint(f\"{my_list_1 = }\")\nprint(f\"{my_list_2 = }\")\n\n\ndef by_value(my_int: int):\n    my_int += 3\n    print(f\"{my_int = }\")\n\n\nprint(f\"{my_int_1 = }\")\nprint(\"by_value(my_int_1)\")\nby_value(my_int_1)\nprint(f\"{my_int_1 = }\")\n\n\ndef by_reference(my_list: list):\n    my_list.append(3)\n    print(f\"{my_list = }\")\n\n\nprint(f\"{my_list_1 = }\")\nprint(\"by_reference(my_list_1)\")\nby_reference(my_list_1)\nprint(f\"{my_list_1 = }\")\n\n\n# Extra\n\ndef by_value(my_int_1: int, my_int_2: int) -> tuple:\n    my_int_1, my_int_2 = my_int_2, my_int_1\n    return my_int_1, my_int_2\n\n\ndef by_reference(my_list_1: list, my_list_2: list) -> tuple:\n    my_int_1, my_int_2 = my_list_2, my_list_1\n    return my_int_1, my_int_2\n\n\nmy_outter_int_1 = 1\nmy_outter_int_2 = 2\nmy_outter_int_1_aux, my_outter_int_2_aux = by_value(my_outter_int_1, my_outter_int_2)\n\nprint(f\"{my_outter_int_1 = }\")\nprint(f\"{my_outter_int_2 = }\")\nprint(f\"{my_outter_int_1_aux = }\")\nprint(f\"{my_outter_int_2_aux = }\")\n\nmy_outter_list_1 = [1]\nmy_outter_list_2 = [2]\nmy_outter_list_1_aux, my_outter_list_2_aux = by_value(my_outter_list_1, my_outter_list_2)\n\nprint(f\"{my_outter_list_1 = }\")\nprint(f\"{my_outter_list_2 = }\")\nprint(f\"{my_outter_list_1_aux = }\")\nprint(f\"{my_outter_list_2_aux = }\")\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/gonzadev28.py",
    "content": "\"\"\"EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\"\"\"\n\n#Asignacion por valor(Tipos de datos primitivos(int, string, bool, float...))\nmi_string = \"primer valor\" \nmi_string2 = mi_string\n\nmi_string = \"segundo valor\" \n\"\"\"Aunque se modifique el valor del string, \"mi_string2\" sigue valiendo lo\nque se le asignó en primera instacia \"\"\"\n\nprint(mi_string)\nprint(mi_string2)\n\n#Asignacion por referencia (Funciona en listas, tuplas, diccionarios, set...)\n\nmi_lista : list = [1, 2, 3, 4, 5]\nmi_lista2 : list = mi_lista\n\nmi_lista2.append(26472364763284) #Se agrega \"26472364763284\" a la lista 2\n\"\"\"Si se modifica el valor de alguna de las 2 listas, se modifica en ambas su valor,\nporque ambas apuntan al mismo espacio de memoria\"\"\"\n\nprint(mi_lista)\nprint(mi_lista2)\n\n#Funcion por valor\nx = 10\ndef por_valor(entrada):\n    entrada = 20\npor_valor(x)\n\nprint(x) #Aunque se intente modificar a 20, sigue valiendo 10\n\n#Funcion por referencia\nx = [10, 20, 30]\ndef por_referencia(entrada):\n    entrada.append(40)\n\npor_referencia(x)\nprint(x) #Se imprime [10, 20, 30, 40] por que se le agregó a \"entrada\" el valor de 40\n\n\"\"\"DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\"\"\"\n\n#Intercambio por valor\ndef inter_por_valor(var1, var2):\n    var_temp = var1\n    var1 = var2\n    var2 = var_temp\n    return var1, var2\n\nvar3 = 3\nvar4 = 4\nvar5, var6 = inter_por_valor(var3, var4)\n\nprint(var3, var4)\nprint(var5, var6)\n\n#Intercambio por referencia\ndef inter_por_ref(str1: list, str2: list):\n    str_temp = str1\n    str1 = str2\n    str2 = str_temp\n    return str1, str2\n\nstr3: list = [\"Moure\"]\nstr4: list = [\"Dev\"]\nstr5, str6 = inter_por_ref(str3, str4)\n\nprint(str3, str4)\nprint(str5, str6)"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/gringoam.py",
    "content": "\"\"\"\nValor y referencia\n\"\"\"\n\n# Tipos de dato por valor\n\nmy_int_a = 10\nmy_int_b = my_int_a\nmy_int_b = 20\n# my_int_a = 30\nprint(my_int_a)\nprint(my_int_b)\n\n# Tipos de dato por referencia\n\nmy_list_a = [10, 20]\nmy_list_b = my_list_a\nmy_list_b.append(30)\nprint(my_list_a)\nprint(my_list_b)\n\n# Funciones con datos por valor\n\n\ndef my_int_func(my_int: int):\n    my_int = 20\n    print(my_int)\n\n\nmy_int_c = 10\nmy_int_func(my_int_c)\nprint(my_int_c)\n\n# Funciones con datos por referencia\n\n\ndef my_list_func(my_list: list):\n    my_list.append(30)\n\n    my_list_d = my_list\n    my_list_d.append(40)\n\n    print(my_list)\n    print(my_list_d)\n\n\nmy_list_c = [10, 20]\nmy_list_func(my_list_c)\nprint(my_list_c)\n\n\"\"\"\nExtra\n\"\"\"\n#Funcion de intercambio de valor con parametros por valor\nmy_int_d=10\nmy_int_e=20\n\ndef intercambioValor(my_int_d:int, my_int_e:int):\n    aux=my_int_d\n    my_int_d= my_int_e\n    my_int_e= aux\n\n    return my_int_d, my_int_e\n\nprint(f\"Valores antes de intercambio\\n{my_int_d}\")\nprint(my_int_e)\n\n\n\nmy_int_f, my_int_g= intercambioValor(my_int_d, my_int_e)\n\nprint(f\"Valores después de intercambio\\n{my_int_f}\")\nprint(my_int_g)\n\n#Funcion de intercambio de valor con parametros por valor\n\n\nmy_list_d=[10, 20]\nmy_list_e=[30, 40]\n\ndef intercambioRef(my_int_d:list, my_int_e:list):\n    aux=my_int_d\n    my_int_d= my_int_e\n    my_int_e= aux\n\n    return my_int_d, my_int_e\n\nprint(f\"Valores antes de intercambio\\n{my_list_d}\")\nprint(my_list_e)\n\nmy_list_f, my_list_g= intercambioRef(my_list_d, my_list_e)\n\nprint(f\"Valores después de intercambio\\n{my_list_f}\")\nprint(my_list_g)\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/haroldAlb.py",
    "content": "### Asignación de variables por VALOR ###\n\nnum1= 23\nnum2= 3.1416\nstring1= \"Hola Mario\"\nbool1= True\n\n### Asignación de variables por REFERENCIA ###\n\nnums1= [10, 100, 30]\nnums2= (11, 101, 31)\n\n### funciones con variables por valor ###\ndef func_valor(n):\n    n -= 2\n    print(f\"variable modificada en la funcion: {n}\")\n\nprint(f\"Variable antes de la función: {num1}\")\nfunc_valor(num1)\nprint(f\"Variable despues de la función: {num1}\")\n\n### funciones con variables por referencia ###\n\ndef func_referencia(n):\n    for i, v  in enumerate(n):\n        n[i] -= 1 \n    print(f\"variable modificada en la funcion: {n}\")\n\nprint(f\"Variable antes de la función: {nums1}\")\nfunc_referencia(nums1)\nprint(f\"Variable despues de la función: {nums1}\")\n\n### EXTRA ###\nprint(\"\\n### EXTRA ###\\n\")\ndef intercambio_val(valor1, valor2):\n    aux= valor1\n    valor1= valor2\n    valor2= aux\n    return valor1, valor2\n\nvar1= 333\nvar2= 666\nchar1= [\"hola\", \"Mario\"]\nchar2= [\"Mario\", \"Albiñana\"]\n\nnew1, new2= intercambio_val(var1, var2)\nprint(f\"{var1} -> {new1}\\n{var2} -> {new2}\")\n\nnc1, nc2= intercambio_val(char1, char2)\nprint(f\"\\n{char1} -> {nc1}\\n{char2} -> {nc2}\")\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/hectordbh.py",
    "content": "\"\"\" EJERCICIO \"\"\"\n# Asignación de variables por valor\nS = \"Pedro\" # variable de tipo cadena\nNUM = 32 # variable de tipo int\n\n# Asignación de variables por referencia\nvar3 = [1, 2, 3] # variable de tipo lista\n\n# Función con variable pasada \"por valor\"\ndef doblar_valor(numero):\n    \"\"\"Función para doblar el valor del argumento dado\n\n    Args:\n        numero (int or float): número al que doblar su valor\n\n    Returns:\n        int or float: doble del número pasado como argumento\n    \"\"\"\n    numero *= 2\n    return numero\nprint(doblar_valor(NUM))\nprint(NUM, \"- Su valor no se ha vista afectado\\n\") # valor original no modificado\n\n# Función con variable pasada \"por referencia\"\ndef doblar_valores(numeros):\n    \"\"\"Doblar valores de argumento\n\n    Args:\n        numeros (list): lista de números a doblar\n    \"\"\"\n    for item in numeros:\n        numeros[item] *= 2\ndoblar_valores(var3)\nprint(var3, \"- Su valor sí se ha vista afectado\") # valor original modificado\n\n# DIFICULTAD EXTRA\n# -------------- Primer programa ---------------\ndef prog1(v1, v2):\n    \"\"\"Intercambio de variables por valor\n\n    Args:\n        v1 (int): primer número\n        v2 (int): segundo número\n\n    Returns:\n        tuple: tupla con los valores intercambiados\n    \"\"\"\n    tmp = v1\n    v1 = v2\n    v2 = tmp\n    return (v1, v2)\n\n# Variables originales\nVAR1 = 1\nVAR2 = 2\n# Variables nuevas\nnew_var1, new_var2 = prog1(VAR1, VAR2)\n# Salida\nprint(f\"Las variables originales son {VAR1} y {VAR2}\",\n      \"y las nuevas varibles son {new_var1} y {new_var2}\")\n\n\n# -------------- Segundo programa ---------------\ndef prog2(l1, l2):\n    \"\"\"Intercambio de variables por referencia\n\n    Args:\n        l1 (list): lista de valores 1\n        l2 (list): lista de valores 2\n\n    Returns:\n        tuple: tupla de listas de valores\n    \"\"\"\n    new_l1 = l2\n    new_l2 = l1\n    return (new_l1, new_l2)\n# Variables originales\nlst1 = [1, 2, 3]\nlst2 = [4, 5, 6]\n# Variables nuevas\nnew_lst1, new_lst2 = prog2(lst1, lst2)\n# Salida\nprint(f\"Las variables originales son {lst1} y {lst2}\",\n      \"y las nuevas varibles son {new_lst1} y {new_lst2}\")\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/hectorio23.py",
    "content": "# Autor: Héctor Adán\n# GitHub: https://github.com/hectorio23\n\n# #############################################################\n# ################ DEFINICION DE FUNCIONES ####################\n# #############################################################\n\ndef suma_referencia(value1, value2):\n    # Imprime a su vez la variable y su dirección de memoria\n    print(\"***Dentro de la funcion que recibe valores por referencia***\")\n    print(f\"&a  ->   {id(value1)}\")\n    print(f\"&b  ->   {id(value2)}\")\n    return value1 + value2\n\ndef suma_copia(value1, value2):\n    # Imprime a su vez la variable y su dirección de memoria\n    print(\"\\n***Dentro de la funcion que recibe valores por copia***\")\n    print(f\"a   ->   {id(value1)}\")\n    print(f\"b   ->   {id(value2)}\")\n    return value1 + value2\n\ndef intercambio_valores_referencia(value1, value2):\n    value1, value2 = value2, value1\n    return [value1, value2]\n\ndef intercambio_copia(value1, value2):\n    value1, value2 = value2, value1\n    return [value1, value2]\n\n# #############################################################\n# ################### PROGRAMA PRINCIPAL ######################\n# #############################################################\n\nif __name__ == \"__main__\":\n    # Variables las cuales se van a usar como conejillos de indias\n    numero = 94\n    numero2 = 6\n\n    # En esta sección se imprimirán la dirección en memoria de las variables\n    print(\"*** Estos son las direcciones en memoria de las variables previamente definidas***\")\n    print(f\"Ubicación en memoria de numero: {id(numero)}\")\n    print(f\"Ubicación en memoria de numero2: {id(numero2)}\")\n\n    suma_referencia(numero, numero2)\n    suma_copia(numero, numero2)\n\n    print(\"\\n******************\\n\")\n\n    print(\"Valor de las variables originales\")\n    print(f\"a -> {numero}\")\n    print(f\"b -> {numero2}\")\n\n    # Después de hacer el cambio de variables mediante una función que recibe los parámetros por copia\n    resultado_copia = intercambio_copia(numero, numero2)\n    copia1 = resultado_copia[0]\n    copia2 = resultado_copia[1]\n\n    print(\"\\nValor de las variables después de hacer un intercambio de valores (copia)\")\n    print(\"Variables originales\")\n    print(f\"a -> {numero}\")\n    print(f\"b -> {numero2}\")\n    print(\"Variables retornadas\")\n    print(f\"copia a -> {copia1}\")\n    print(f\"copia b -> {copia2}\")\n\n    # Después de hacer el cambio de variables mediante una función que recibe los parámetros por referencia\n    resultado_referencia = intercambio_valores_referencia(numero, numero2)\n    referencia1 = resultado_referencia[0]\n    referencia2 = resultado_referencia[1]\n\n    print(\"\\nValor de las variables después de hacer un intercambio de valores (referencia)\")\n    print(\"Variables originales\")\n    print(f\"a -> {numero}\")\n    print(f\"b -> {numero2}\")\n    print(\"Variables retornadas\")\n    print(f\"copia a -> {referencia1}\")\n    print(f\"copia b -> {referencia2}\")"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/hozlucas28.py",
    "content": "\"\"\"\n    Variable assignment by value...\n\"\"\"\n\nprint(\"Variable assignment by value...\")\n\nA: int = 3\nB: int = A\n\nprint(\"\\nA: int = 3\\nB: int = A\")\nprint(f\"\\nValue of 'A' = {A}\\nValue of 'B' = {B}\")\n\nA = A * 3\n\nprint(\"\\nA = A * 3\")\nprint(f\"\\nValue of 'A' = {A}\\nValue of 'B' = {B}\")\n\nprint(\n    \"\\n# ---------------------------------------------------------------------------------- #\"\n)\n\n\"\"\"\n    Variable assignment by reference...\n\"\"\"\n\nprint(\"\\nVariable assignment by reference...\")\n\nC: list[int] = [1, 2, 3, 4]\nD: list[int] = C\n\nprint(\"\\nC: list[int] = [1, 2, 3, 4]\\nD: list[int] = C\")\nprint(f\"\\nValue of 'C' = {C}\\nValue of 'D' = {D}\")\n\nC.append(5)\n\nprint(\"\\nC.append(5)\")\nprint(f\"\\nValue of 'C' = {C}\\nValue of 'D' = {D}\")\n\nprint(\n    \"\\n# ---------------------------------------------------------------------------------- #\"\n)\n\n\"\"\"\n    Function with an argument passed by value...\n\"\"\"\n\nprint(\"\\nFunction with an argument passed by value...\")\n\nVALUE: str = 13\n\nprint(\"\\nVALUE: str = 13\")\n\n\ndef fn_with_paramenter_by_value(x: int):\n    \"\"\"Example function which receives a parameter as a value\"\"\"\n    x += x\n\n\nprint(\n    \"def fn_with_paramenter_by_value(x: int):\\n\" + \"    x += x\",\n)\n\nfn_with_paramenter_by_value(VALUE)\n\nprint(\"\\nfn_with_paramenter_by_value(VALUE)\")\n\nprint(f\"\\nValue of 'VALUE' = {VALUE}\")\n\nprint(\n    \"\\n# ---------------------------------------------------------------------------------- #\"\n)\n\n\"\"\"\n    Function with an argument passed by reference...\n\"\"\"\n\nprint(\"\\nFunction with an argument passed by reference...\")\n\nREFERENCE: list[int] = [10, 11, 12, 13, 14]\n\nprint(\"\\nREFERENCE: list[int] = [10, 11, 12, 13, 14]\")\n\n\ndef fn_with_paramenter_by_reference(param: list[int]):\n    \"\"\"Example function which receives a parameter as a reference\"\"\"\n    param.append(15)\n\n\nprint(\n    \"def fn_with_paramenter_by_reference(param: list[int]):\\n\" + \"    param.append(15)\"\n)\n\nfn_with_paramenter_by_reference(REFERENCE)\n\nprint(\"\\nfn_with_paramenter_by_reference(REFERENCE)\")\n\nprint(f\"\\nValue of 'REFERENCE' = {REFERENCE}\")\n\nprint(\n    \"\\n# ---------------------------------------------------------------------------------- #\"\n)\n\n\"\"\"\n    Additional challenge...\n\"\"\"\n\n\ndef first_program(a: int, b: int) -> list[int]:\n    \"\"\"Function which receives value parameters\"\"\"\n    a, b = b, a\n\n    return [a, b]\n\n\ndef second_program(a: list[int], b: list[int]) -> list[list[int]]:\n    \"\"\"Function which receives reference parameters\"\"\"\n    aux: list[int] = a.copy()\n    a.extend(b)\n    b.extend(aux)\n\n    return [a, b]\n\n\nARG_01: int = 5\nARG_02: int = 12\nARG_03: list[int] = [1, 2, 3, 4, 5]\nARG_04: list[int] = [6, 7, 8, 9, 10]\n\n[NEW_ARG_01, NEW_ARG_02] = first_program(ARG_01, ARG_02)\n[NEW_ARG_03, NEW_ARG_04] = second_program(ARG_03, ARG_04)\n\nprint(f\"\\noriginal:\\n    ARG_01: {ARG_01}\\n    ARG_02: {ARG_02}\")\nprint(f\"new:\\n    ARG_01: {NEW_ARG_01}\\n    ARG_02: {NEW_ARG_02}\")\n\nprint(f\"\\noriginal:\\n    ARG_03: {ARG_03}\\n    ARG_04: {ARG_04}\")\nprint(f\"new:\\n    ARG_03: {NEW_ARG_03}\\n    ARG_04: {NEW_ARG_04}\")\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/idiegorojas.py",
    "content": "# Asignacion de variables en python\n# En python los enteros, flotantes, cadenas y tuplas, sea signan por valor.\n# Esto significa que cuando asignas una variable a otra, se crea una copia independiente del valor.\n\n# Asignacion por valor\na = 10\nb = a\nprint(f'a: {a}, b: {b}') # 'b' recibe una copia de del valor de 'a'\n\n# Modificamos b\nb = 20\nprint(f'a:{a}, b:{b}') # 'a' no se ve afectada ya que los enteros son inmutables.\n\n\n# Asignacion por referencia\n# En python las listas, diccionarios y conjuntos, se asignan por referencia.\n# Esto significa que cuando asignas una variable a otra, ambas apuntan al mismo objeto en memoria.\n\nlista_1 = [1, 2 ,3]\nlista_2 = lista_1\nprint(f'Lista 1: {lista_1}, Lista 2: {lista_2}')\n\n# Modificamos la lista 2\nlista_2.append(4)\nprint(f'Lista 1: {lista_1}, Lista 2: {lista_2}') # Al modificar la lista 2, tambien se modifica la lista 1\n\n# Crear una copia independiente de un objeto mutable\nlista_1 = [1, 2 ,3]\nlista_2 = lista_1.copy() # Lista 2 es una copia independiente de lista 1\nprint(f'Lista 1: {lista_1}, Lista 2: {lista_2}') \n\nlista_2.append(4)\nprint(f'Lista 1: {lista_1}, Lista 2: {lista_2}') # Lista 1 no se ve afectada por los cambios de lista 2\n\n\n# Extra\n\n# Función para intercambiar valores por valor\ndef intercambiar_por_valor(a, b):\n    temp = a\n    a = b\n    b = temp\n    return a, b\n\nx = 10\ny = 20\n\nnuevo_x, nuevo_y = intercambiar_por_valor(x, y)\n\nprint(f\"Originales: x = {x}, y = {y}\")\nprint(f\"Nuevos: nuevo_x = {nuevo_x}, nuevo_y = {nuevo_y}\")\n\n\n\n\n# Función para intercambiar valores por referencia\ndef intercambiar_por_referencia(lista1, lista2):\n    temp = lista1[:]\n    lista1[:] = lista2[:]\n    lista2[:] = temp  \n    return lista1, lista2\n\nlista_a = [1, 2, 3]\nlista_b = [4, 5, 6]\n\nnueva_lista_a, nueva_lista_b = intercambiar_por_referencia(lista_a, lista_b)\n\nprint(f\"Originales: lista_a = {lista_a}, lista_b = {lista_b}\")\nprint(f\"Nuevas: nueva_lista_a = {nueva_lista_a}, nueva_lista_b = {nueva_lista_b}\")"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/ignaciovihe.py",
    "content": "\"\"\"\n- Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n  su tipo de dato.\n- Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n\"\"\"\n\n\n\"\"\"\nAsignacion\n\"\"\"\n# Los tipos inmutables de python siempre se asignan por valor.\n# Por lo tanto siempre se creeara un nuevo objeto aunque se asigne una variable a otra,\n# y el valor no cambiara aunque posteriormente cambiemos el valor de la primera.\n# Los datos inmutables en python son: int, float, complex, str, tuple, bool...\n\nmy_variable = 1 #Asignamos los valores\nmy_other_variable = 2\n\nprint(f\"my_variable = {my_variable}\")\nprint(f\"my_other_varibale = {my_other_variable}\")\n\nmy_other_variable = my_variable # aunque apuntemos una variable a otra, como es un tipo inmutable solo copia el valor.\n\nprint(f\"my_variable = {my_variable}\")\nprint(f\"my_other_varibale = {my_other_variable}\")\n\nmy_variable = 3 #Aunque modifiquemos el valor, se mantiene el mismo.\n\nprint(f\"my_variable = {my_variable}\")\nprint(f\"my_other_varibale = {my_other_variable}\")\n\n#Los tipos mutables si se pueden asignar por referencia.\n# Los tipos muitables en python son: list, dict, set\n\nmy_dict = {\"nombre\": \"Ignacio\", \"genero\": \"masculino\", \"edad\": 40} # Asignamos dos variables por valor\nyour_dict = {\"nombre\": \"Maria\", \"genero\": \"femenino\", \"edad\": 33}\n\nprint(f\"my_dict = {my_dict}\")\nprint(f\"your_dict = {your_dict}\")\n\nyour_dict = my_dict #Asignamos la variable your_dict por referencia. \n\nprint(f\"my_dict = {my_dict}\")\nprint(f\"your_dict = {your_dict}\")\n\nyour_dict[\"nombre\"] = \"Nacho\"   #Modificamos el valor de la variable vemos como tambien cambia el de la otra.\n                                #Realmente esta apuntando a la referencia de memoria. Apunta al mismo objeto.\n\nprint(f\"my_dict = {my_dict}\")\nprint(f\"your_dict = {your_dict}\")\n\n\n\n\"\"\"\nFunciones con parametros por valor y referencia\n\"\"\"\n# Realmente en python todo se para por referencia. Pero los tipos inmutables no afectac a la variable exterior\n# Parametros inmutables. Con datos inmutables, cualquier modificación dentro de la función no afecta a la variable fuera de la función.\n\nnumber_1 = 3\n\ndef duplicate(number: int):\n    number *= 2\n\nprint(f\"number_1 = {number_1}\")\nduplicate(number_1)\nprint(f\"number_1 = {number_1}\")\n\n#Si queremos que una funciona modifique la variable de fuera usamos return para modificar el valor.\n\n\n\n\n#Parametros mutables\n\nmy_list = [2,8,3,5,1,9,0,4,6,7]\n\ndef sort_list(unsorted_list: list):\n    unsorted_list.sort()\n    other_list = unsorted_list\n    other_list.append(\"a\") # Aunque lo añado en una variable diferente apuntan a la misma direccion de memoria por lo tanto se añade a\n\nprint(f\"my_list = {my_list}\")\nsort_list(my_list)\nprint(f\"my_list = {my_list}\")   # Aunque no devuelvo un valor como es un tipo mutable se pasa por referencia \n                                # y afecta a la variable exterior.\n\n\n\n# Si queremos que una función no modifique la variable exterior pordemos usar el metodo .copy()\n\nmy_list = [2,8,3,5,1,9,0,4,6,7]\n\ndef sort_list_copy(unsorted_list: list):\n    \n    unsorted_list = unsorted_list.copy() # Esto simula un tipo mutable pasado como valor. No afectara a la variable exterior.\n    unsorted_list.sort()\n    print(f\"La lista dentro = {unsorted_list}\")\n\nprint(f\"La lista original fuera = {my_list}\")\nsort_list_copy(my_list)\nprint(f\"La lista despues de la funcion con copia = {my_list}\")\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n\"\"\"\n\n\ndef swap_values(param1, param2):\n    param_aux = param1\n    param1 = param2\n    param2 = param_aux\n    if type(param2) == list:\n        param2.append(\"Nuevo valor\")\n    return param1, param2\n\n# Por valor\nwin = \"First\"\nlost = \"Last\"\nnew_win, new_lost = swap_values(win, lost)\n\nprint(f\"win: {win}\")\nprint(f\"lost: {lost}\")\n\nprint(f\"new_win: {new_win}\")\nprint(f\"new_lost: {new_lost}\")\n\n#Por referencia\n\nletters = [\"a\", \"b\", \"c\", \"d\", \"e\"]\nnumbers = [1, 2, 3, 4, 5]\nnew_letters, new_numbers = swap_values(letters, numbers)\n\nprint(f\"letters: {letters}\")    # Alintercambiar la referencias dentro de la funcion se hace de forma local.\nprint(f\"numbers: {numbers}\")    # Por lo tanto las variable exteriores no cambian.\n                                # Pero si añado un valor si que cambia la lista.\n\nprint(f\"new_letter: {new_letters}\")\nprint(f\"new_numbers: {new_numbers}\")\n\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/inmortalnight.py",
    "content": "# 05 - VALOR Y REFERENCIA\n\n# Asignación de variables por valor, se copia, tipo de dato primitivo\n\n# int\nvalor1 = 10\nvalor2 = valor1\nprint(\"int: \", valor1, valor2, sep=\" \")\nvalor2 = 20\nprint(\"int: \", valor1, valor2, sep=\" \")\n# float\nvalor1 = 10.5\nvalor2 = valor1\nprint(\"float: \" , valor1, valor2, sep=\" \")\nvalor2 = 20.5\nprint(\"float: \" , valor1, valor2, sep=\" \")\n# boolean\nvalor1_1 = True\nvalor2_2 = valor1_1\nprint(\"boolean: \" , valor1_1, valor2_2, sep=\" \")\nvalor2_2 = False\nprint(\"boolean: \" , valor1_1, valor2_2, sep=\" \")\n# string\nvalor1 = \"Hola\"\nvalor2 = valor1\nprint(\"string: \" , valor1, valor2, sep=\" \")\nvalor2 = \"Adios\"\nprint(\"string: \" , valor1, valor2, sep=\" \")\n\n\n# Asignación de variables por referencia, usa el mismo espacio de memoria, tipo de dato complejo\n# list\nvalor1 = [1, 2, 3]\nvalor2 = valor1\nprint(\"list: \" , valor1, valor2, sep=\" \")\nvalor2.append(4)\nprint(\"list: \" ,  valor1, valor2, sep=\" \")\n# tuple\nvalor1 = (1, 2, 3)\nvalor2 = valor1\nprint(\"tuple: \" ,  valor1, valor2, sep=\" \")\n# dict\nvalor1 = {\"a\": 1, \"b\": 2}\nvalor2 = valor1\nprint(\"dict: \" ,  valor1, valor2, sep=\" \")\nvalor1[\"a\"] = 3\nprint(\"dict: \" ,  valor1, valor2, sep=\" \")\n# set\nvalor1 = {1, 2, 3}\nvalor2 = valor1\nprint(\"set: \" ,  valor1, valor2, sep=\" \")\nvalor1.add(4)\nprint(\"set: \" ,  valor1, valor2, sep=\" \")\n# frozenset\nvalor1 = frozenset({1, 2, 3})\nvalor2 = valor1\nprint(\"frozenset: \" ,  valor1, valor2, sep=\" \")\n# bytearray\nvalor1 = bytearray(b\"abc\")\nvalor2 = valor1\nprint(\"bytearray: \" ,  valor1, valor2, sep=\" \")\nvalor1[0] = 100\nprint(\"bytearray: \" ,  valor1, valor2, sep=\" \")\n\n\n# EXTRA \n''' * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n    def1(a,b), 2 parametros\n    def2(a,b), '''\n\n# Funcion por valor\ndef program1(a:int, b: int) -> tuple:\n    temp = a\n    a = b\n    b = temp\n    return a, b\nvalue1 = 10\nvalue2 = 20\nprint(\"value1\", value1, \"value2\", value2)\nvalue3, value4 = program1(value1, value2)\nprint(\"value1\", value1, \"value2\", value2)\nprint(\"value3\", value3, \"value4\", value4)\n\n# Funcion por referencia\ndef program2(a:list, b: list) -> tuple:\n    a, b = b, a\n    return a, b\nvalue1 = [10, 20]\nvalue2 = [20, 30]\nprint(\"value1\", value1, \"value2\", value2)\nvalue3, value4 = program2(value1, value2)\nprint(\"value1\", value1, \"value2\", value2)\nprint(\"value3\", value3, \"value4\", value4)\n\n'''Explicación: \nEn ambos casos, lo que se trabaja y se cambia son los variables locales dentro de las funciones. \nAunque salga un error al cambiar por referencia, no afectará a las variables originales. \nEn el caso de que se quiera cambiar el valor de las variables originales, \nse deberá convertir las variables locales en datos compuestos; \nlistas a[:], b[:] = b[:], a[:].'''"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/ipfabio.py",
    "content": "\"\"\"\nValor y referencia\n\"\"\"\n\n# Tipos de datos por valor\n\nmy_int_a = 10\nmy_int_b = my_int_a\n# my_int_b = 20\n# my_int_a = 30\nprint(my_int_a)\nprint(my_int_b)\n\n# Tpos de datos por referencia\n# No copian su valor, heredan la posición de memoria.\n\nmy_list_a = [10, 20]\nmy_list_b = my_list_a\nmy_list_b.append(30) # altera también la lista A\nprint(my_list_a)\nprint(my_list_b)\n\n# Funciones con datos por valor\n\nmy_int_c = 10\n\ndef my_int_func(my_int: int):\n    my_int = 20\n    print(my_int)\n\nmy_int_func(my_int_c) # Vale 20\nprint(my_int_c) # Sigue valiendo 10\n\n# Funciones con datos por referencia\n\n\ndef my_list_func(my_list: list):\n    my_list.append(30)\n\n    my_list_d = my_list\n    my_list_d.append(40)\n\n    print(my_list)\n    print(my_list_d)\n\n\nmy_list_c = [10, 20]\nmy_list_func(my_list_c) # Agrega el 30\nprint(my_list_c) # Mantiene el cambio de append\n\n\"\"\"\nExtra\n\"\"\"\n\n# Por valor\n\ndef value(val_a: int, val_b: int) -> tuple:\n    temp = val_a\n    val_a = val_b\n    val_b = temp\n    return val_a, val_b\n\nmy_int_d = 10\nmy_int_e = 20\nmy_int_f, my_int_g = value(my_int_d, my_int_e)\n\nprint(f\"{my_int_d}, {my_int_e}\")\nprint(f\"{my_int_f}, {my_int_g}\")\n\n# Por referencia\n\"\"\"\nPreferentemente no utlizar con copias en caminos separados (que les ocurran cosas distintas a las copias)\nporque se puede generar un error alterando la version original de la lista\n\"\"\"\ndef ref(val_a: list, val_b: list) -> tuple:\n    temp = val_a\n    temp.append(50) # Agrega en ambos/\n    val_a = val_b\n    val_b = temp\n    return val_a, val_b\n\nmy_list_e = [10,20]\nmy_list_f = [30,40]\nmy_list_g, my_list_h = ref(my_list_e, my_list_f)\nprint(f\"{my_list_e}, {my_list_f}\")\nprint(f\"{my_list_g}, {my_list_h}\")"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/isilanes.py",
    "content": "def assignation():\n    print(\"Python trata, de manera más o menos automática, a las variables INMUTABLES (p.e. int, str, tuple),\")\n    print(\"como pasadas por valor:\")\n    a = 1\n    print(\"a = 1\")\n    b = a\n    print(\"b = a\")\n    a += 1\n    print(\"a += 1\")\n    print(f\"a vale {a}, pero b sigue valiendo {b}\")\n    print(f\"Podemos ver que a y b son objetos diferentes, porque id(a) == {id(a)} != id(b) == {id(b)}\")\n    print(\"¿Puedes ver el truqui? Efectivamente, el 'a+=1' NO modifica 'a', sino que le ASIGNA un nuevo valor.\")\n\n    print(\"\\nPor otro lado, las variables MUTABLES (p.e. list, dict) se tratan como pasadas por referencia:\")\n    a = [1, 2, 3]\n    print(\"a = [1, 2, 3]\")\n    b = a\n    print(\"b = a\")\n    a.append(4)\n    print(\"a.append(4)\")\n    print(f\"a vale {a}, y b también se ha actualizado a {b}\")\n    print(f\"Podemos ver que a y b son referencias al mismo objeto, porque id(a) == {id(a)} == id(b) == {id(b)}\")\n\n    print(\"\\nSin embargo, es importante entender que la referencia común existe mientras ambos objetos mutables\")\n    print(\"sean MODIFICADOS:\")\n    a = [1, 2, 3]\n    b = a\n    print(f\"id(a) == {id(a)} == id(b) == {id(b)}\")\n    b.pop()\n    print(\"b.pop()\")\n    print(f\"a == {a} == b == {b}\")\n    print(f\"id(a) == {id(a)} == id(b) == {id(b)}\")\n    print(\"Si son REASIGNADOS, entonces la referencia común se rompe:\")\n    a = [4, 5, 6]\n    print(\"a = [4, 5, 6]\")\n    print(f\"b == {b} != a\")\n    print(f\"id(b) sigue siendo {id(b)}, pero id(a) es {id(a)}\")\n    print(\"Realmente los objetos mutables se comportan como los inmutables: si los reasignas, se pierde\")\n    print(\"la referencia común. La diferencia es que en los inmutables esto es lo único que se puede hacer.\")\n    print(\"En los mutables, además, se pueden MODIFICAR (no reasignar) sin perder la referencia.\")\n\n\ndef immutable_by_value(var: int) -> None:\n    var += 1\n    print(f\"Dentro de la función: var == {var}\")\n\n\ndef mutable_by_reference(var: dict) -> None:\n    var[\"b\"] = 123\n    print(f\"Dentro de la función: var == {var}\")\n\n\ndef mutable_by_value(var: list) -> None:\n    var = [e for e in var]  # var is now a local copy, separated from the argument passed\n    var.append(3)\n    print(f\"Dentro de la función: var == {var}\")\n\n\ndef main():\n    assignation()\n\n    print(\"\\nUso de función que 'modifica' variable inmutable (mentira, las variables inmutables no se modifican)\")\n    print(\"El efecto es como si se pasara por valor:\")\n    var = 1\n    print(f\"Variable antes de función: var == {var}\")\n    immutable_by_value(var)\n    print(f\"Variable después de función: var == {var}\")\n\n    print(\"\\nUso de función que modifica variable mutable. El efecto es como si se pasara por referencia:\")\n    var = {\"a\": 1, \"b\": 1}\n    print(f\"Variable antes de función: var == {var}\")\n    mutable_by_reference(var)\n    print(f\"Variable después de función: var == {var}\")\n\n    print(\"\\nUso de función que modifica variable mutable localmente, siendo el efecto como pasar por valor:\")\n    var = [1, 2]\n    print(f\"Variable antes de función: var == {var}\")\n    mutable_by_value(var)\n    print(f\"Variable después de función: var == {var}\")\n\n\ndef extra_function_1(var_a: list, var_b: list) -> tuple[list, list]:\n    \"\"\"\n    This function receives two mutable variables 'var_a' and 'var_b'. It swaps their values in a\n    'by value' fashion, so that the swap is NOT reflected out of the function.\n    \"\"\"\n    var_b, var_a = var_a, var_b\n\n    return var_a, var_b\n\n\ndef extra_function_2(var_a: list, var_b: list) -> tuple[list, list]:\n    \"\"\"\n    This function receives two mutable variables 'var_a' and 'var_b'. It swaps their values in a\n    'by reference' fashion, so that the swap IS reflected out of the function.\n\n    This is a contrived example, nobody would do that in Python.\n    \"\"\"\n    tmp = [e for e in var_a]\n    var_a.clear()\n    for e in var_b:\n        var_a.append(e)\n    var_b.clear()\n    for e in tmp:\n        var_b.append(e)\n\n    return var_a, var_b\n\n\ndef extra():\n    \"\"\"\n    Entiendo que el enunciado \"crea dos programas\" significa \"crea dos funciones\".\n    \"\"\"\n    print(\"\\nContenido extra:\")\n    a = [1, 2, 3]\n    b = [4, 5, 6]\n    print(f\"Antes de llamar a la Función 1 (pase por valor): a == {a}, b == {b}\")\n    x, y = extra_function_1(a, b)\n    print(\"Después de llamar a la Función 1 (pase por valor):\")\n    print(f\"Los valores de retorno están invertidos: {x} : {y}\")\n    print(f\"Los valores originales no se modifican: {a} : {b}\")\n\n    a = [1, 2, 3]\n    b = [4, 5, 6]\n    print(f\"\\nAntes de llamar a la Función 2 (pase por referencia): a == {a}, b == {b}\")\n    x, y = extra_function_2(a, b)\n    print(\"Después de llamar a la Función 2 (pase por referencia):\")\n    print(f\"Los valores de retorno están invertidos: {x} : {y}\")\n    print(f\"Los valores originales también están invertidos: {a} : {b}\")\n\n\nif __name__ == \"__main__\":\n    main()\n    extra()\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/ivangdev.py",
    "content": "# ------------------- Asignacion por valor ---------------\n# Al ser por valor son datos inmutables, Una vez guardado objeto en memoria no puede ser cambiado, al crear otra variable asignadno el valor de esta, se crea es una copia\n# Int\na = 10\nb = a  # b es una copia del valor de a\nprint(f\"Original: a = {a}, b = {b}\")\na = 20\nprint(f\"Despues del cambio: a = {a}, b = {b}\")\n\n# Float\na = 10.5\nb = a\nprint(f\"Original: a = {a}, b = {b}\")\na = 20.5\nprint(f\"Despues del cambio: a = {a}, b = {b}\")\n\n# bool\na = True\nb = a\nprint(f\"Original: a = {a}, b = {b}\")\na = False\nprint(f\"Despues del cambio: a = {a}, b = {b}\")\n\n# Cadena de texto\ntexto = \"Hola\"\ntexto2 = texto\nprint(f\"Original: texto = {texto}, texto2 = {texto2}\")\ntexto = \"Chao\"\nprint(f\"Despues del cambio: texto = {texto}, texto2 = {texto2}\")\n\n# Tupla\nt = (1, 2, 3)\nt2 = t  # Copia de t\nprint(f\"Original: t = {t}, t2 = {t2}\")\n\n# Al intentar modificar una tupla da error\n# t[0] = 5  # Error\n\n# ---------------- Asignacion por referencia --------------------\n# Al ser por referencia son datos mutables, estos se pueden mutar despues de la creacion, por eso siempre apuntan al mismo objeto en memoria\n# Listas\nlista = [1, 2, 3]\nlista2 = lista\nprint(f\"Original: lista = {lista}, lista2 = {lista2}\")\nlista[0] = 55  # Se modifica el elemento\nprint(f\"Despues del cambio: lista = {lista}, lista2 = {lista2}\")\n\n# Diccionario\ndic = {\"Nombre\": \"Ana\", \"edad\": 40}\ndic2 = dic\nprint(f\"Original: dic = {dic}, dic2 = {dic2}\")\ndic[\"edad\"] = 80\nprint(f\"Despues del cambio: dic = {dic}, dic2 = {dic2}\")\n\n# Conjunto\nconjunto = {1, 2, 3}\nconjunto2 = conjunto\nprint(f\"Original: conjunto = {conjunto}, conjunto2 = {conjunto2}\")\nconjunto.add(4)\nprint(f\"Despues del cambio: conjunto = {conjunto}, conjunto2 = {conjunto2}\")\n\n\n# ------------------ Funciones ----------------------------------------\n# ejemplos de funciones con variables que se les pasan \"por valor\" y \"por referencia\"\n# Valor pasado por parametro es el original dentro de la funcion se crea una copia que es el que se modifica\n\n\n# ------------------- Asignacion por valor ---------------\n# ---------------- inmutables -------------------\n# Int\ndef modificar_numero(numero):\n    print(f\"Valor original = {numero}\")\n    numero = 10\n    print(f\"Despues de modificar numero: = {numero}\")\n\n\nmi_numero = 20\nmodificar_numero(mi_numero)\nprint(f\"Numero fuera de la funcion = {mi_numero}\")\n\n\n# Float\ndef modificar_float(numero):\n    print(f\"Valor original: {numero}\")\n    numero = 40.5\n    print(f\"Despues de modificar: {numero}\")\n\n\nmi_float = 20.5\nmodificar_float(mi_float)\nprint(f\"Float fuera de la fucnion = {mi_float}\")\n\n\n# bool\ndef modificar_bool(bool):\n    print(f\"Valor original: {bool}\")\n    bool = False\n    print(f\"Despues de modificar: {bool}\")\n\n\nmi_bool = True\nmodificar_bool(mi_bool)\nprint(f\"Bool fuera de la funcion = {mi_bool}\")\n\n\n# Cadena de texto\ndef modificar_cadena_texto(texto):\n    print(f\"Valor original: {texto}\")\n    texto = \"Nuevo valor\"\n    print(f\"Despues de modificar: {texto}\")\n\n\nmi_cadena = \"Hola\"\nmodificar_cadena_texto(mi_cadena)\nprint(f\"Cadena fuera de la funcion = {mi_cadena}\")\n\n\n# Tupla\ndef modificar_tupla(tupla):\n    print(f\"Valor original: {tupla}\")\n    tupla = (4, 5, 6)\n    print(f\"Despues de modificar: {tupla}\")\n\n\nmi_tupla = (1, 1, 2, 6)\nmodificar_tupla(mi_tupla)\nprint(f\"Tupla fuera de la funcion = {mi_tupla}\")\n\n# ---------------- Asignacion por referencia --------------------\n# -------------- Mutables ----------------------\n\n\n# Listas\ndef modificar_lista(lista):\n    print(f\"Valor original = {lista}\")\n    lista[0] = 99\n    print(f\"Despues de modificar = {lista}\")\n\n\nmi_lista = [1, 2, 3]\nmodificar_lista(mi_lista)\nprint(f\"Lista fuera de la funcion = {mi_lista}\")\n\n\n# Diccionario\ndef modificar_diccionario(dic):\n    print(f\"valor original = {dic}\")\n    dic[\"nombre\"] = \"ivan\"\n    print(f\"Despues de modificar en la funcion: {dic}\")\n\n\nmi_dic = {\"nombre\": \"Alejandro\"}\nmodificar_diccionario(mi_dic)\nprint(f\"Diccionario fuera de la funcion = {mi_dic}\")\n\n\n# Conjunto\ndef modificar_conjunto(conjunto):\n    print(f\"Valor original = {conjunto}\")\n    conjunto.remove(4)\n    print(f\"Despues de modificar en la funcion = {conjunto}\")\n\n\nmi_conjunto = {5, 4, 6}\nmodificar_conjunto(mi_conjunto)\nprint(f\"Conjunto fuera de la funcion = {mi_conjunto}\")\n\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n#  * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n#  *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n#  *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n#  *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n#  *   Comprueba también que se ha conservado el valor original en las primeras.\n\n\n# ------------ Por valor ----------------\ndef intercambio_parametros1(parametro1, parametro2):\n    print(f\"Valor original = {parametro1}, {parametro2}\")\n    aux = parametro2\n    parametro2 = parametro1\n    parametro1 = aux\n    print(\n        f\"Al intercambiar los parametros tenemos: parametro1 = {parametro1}, parametro2 = {parametro2}\"\n    )\n    return parametro1, parametro2\n\n\nparametro1 = \"Hola\"\nparametro2 = \"Soy ivan\"\nstr1, str2 = intercambio_parametros1(parametro1, parametro2)\nprint(f\"Parametros modificados por la funcion: str1 = {str1}, str2 = {str2}\")\nprint(\n    f\"Fuera de la funcion mantienen du valor original: parametro1 = {parametro1}, parametro2 = {parametro2}\"\n)\n\n\n# ------- Por referencia --------------\ndef intercambio_parametro2(parametro1, parametro2):\n    print(f\"Valor original = {parametro1}, {parametro2}\")\n    aux = parametro2\n    parametro2 = parametro1\n    parametro1 = aux\n    return parametro1, parametro2\n\n\ndic1 = {\"nombre\": \"ivan\"}\ndic2 = {\"pais\": \"Colombia\"}\nrta1, rta2 = intercambio_parametro2(dic1, dic2)\nprint(f\"Parametros modificados por la funcion: rta1 = {rta1}, rta2 = {rta2}\")\nprint(f\"Fuera de la funcion mantienen su valor original: dic1 = {dic1}, dic2 = {dic2}\")\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/javierjoyera.py",
    "content": "#Asignación de tipos inmutables\nx = 190 #Es un objeto de tipo INT\ny = x #y es una referencia a x\ny = y + 3 #y es un nuevo objeto de tipo INT\n\nprint(x)\nprint(y)\n\n#Asignación de tipos mutables\nx = [1,2,3] #Es un objeto de tipo LIST\ny = x #y es una referencia a x\ny[0] = 4 #Modificamos el objeto al que Y (y por tanto X) apunta\n\n#Como hemos modificado el objeto al que apuntan ambas variables, se modifica el valor de ambas\nprint(x)\nprint(y)\n\n\ndef modify_list(lista):\n    lista.append(4)\n    \nx = [1,2,3]\nmodify_list(x)\nprint(x)\n\ndef modify_num (num):\n    num = num + 1\n\nmy_num = 10\nmodify_num(my_num)\nprint(my_num) #devuelve 10 porque el valor de my_num no se ha modificado, sino que ha creado un nuevo objeto\n\n#Para modificar el valor de my_num, se debe hacer de la siguiente forma:\ndef modify_num (num):\n    num = num + 1\n    return num\n\nmy_num = 10\nmy_num = modify_num(my_num)\nprint(my_num) #devuelve 11 porque el valor de my_num se ha modificado, ya que se ha creado un nuevo objeto y se ha asignado a my_num\n\n\ndef intercambio_inmutables(a, b):\n    a, b = b, a\n    return a, b\n\nx = 10\ny = 2\n\nnew_x, new_y = intercambio_inmutables(x, y)\n\nprint(\"Los valores iniciales eran %d y %d\" % (x, y))\nprint(\"Los valores finales son %d y %d\" % (new_x, new_y))\n\ndef intercambio_mutables(a, b):\n    a[:], b[:] = b[:], a[:]\n    return a, b\n\nmy_list = [1, 2, 3]\nmy_other_list = [4, 5, 6]\n\nnew_list, new_other_list = intercambio_mutables(my_list, my_other_list)\n\nprint(\"Los valores iniciales eran %s y %s\" % (my_list, my_other_list))\nprint(\"Los valores finales son %s y %s\" % (new_list, new_other_list))\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/jcdm60.py",
    "content": "# #05 VALOR Y REFERENCIA\n#### Dificultad: Fácil | Publicación: 29/01/24 | Corrección: 05/02/24\n\n## Ejercicio\n\n#\n# EJERCICIO:\n# - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n#   su tipo de dato.\n# - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n#   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n# (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n#\n# DIFICULTAD EXTRA (opcional):\n# Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n# - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n#   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n#   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n#   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n#   Comprueba también que se ha conservado el valor original en las primeras.\n#\n\n\n# POR VALOR\n# Enteros son inmutables\na = 7\nb = a  # Se copia el valor de 'a' en 'b'\nb = 12\nprint(a)  # Salida: 5 (sin cambios)\nprint(b)  # Salida: 10\n\n# POR REFERENCIA\n# Listas son mutables\nlista1 = [1, 2, 3]\nlista2 = lista1  # Se referencia la misma lista con dos nombres diferentes\nlista2.append(4)\nprint(lista1)  # Salida: [1, 2, 3, 4] (modificada a través de 'lista2')\nprint(lista2)  # Salida: [1, 2, 3, 4]\n\n# FNCIONES POR VALOR\ndef modificar_valor(x):\n    x = x + 5\n\na = 10\nmodificar_valor(a)\nprint(a)  # Salida: 10 (sin cambios)\n\n# FUNCIONES POR REFERENCIA\ndef modificar_lista(lista):\n    lista.append(4)\n\nmi_lista = [1, 2, 3]\nmodificar_lista(mi_lista)\nprint(mi_lista)  # Salida: [1, 2, 3, 4] (modificada dentro de la función)\n\n\n# PROGRMAMA 1 - POR VALOR\ndef intercambiar_por_valor(a, b):\n    # Intercambio de valores\n    temp = a\n    a = b\n    b = temp\n    return a, b\n\n# Definición de variables\nvalor1 = 10\nvalor2 = 20\n\n# Llamada a la función y asignación de los nuevos valores\nnuevo_valor1, nuevo_valor2 = intercambiar_por_valor(valor1, valor2)\n\n# Imprimir los resultados\nprint(\"Por valor:\")\nprint(\"Original - Valor1:\", valor1, \"Valor2:\", valor2)\nprint(\"Nuevo - Valor1:\", nuevo_valor1, \"Valor2:\", nuevo_valor2)\n\n# POR REFERENCIA\ndef intercambiar_por_referencia(lista):\n    # Intercambio de valores dentro de la lista\n    temp = lista[0]\n    lista[0] = lista[1]\n    lista[1] = temp\n    return lista\n\n# Definición de variables\nreferencia1 = [10]\nreferencia2 = [20]\n\n# Llamada a la función y asignación de los nuevos valores\nnueva_referencia = intercambiar_por_referencia(referencia1 + referencia2)\n\n# Imprimir los resultados\nprint(\"\\nPor referencia:\")\nprint(\"Original - Referencia1:\", referencia1, \"Referencia2:\", referencia2)\nprint(\"Nuevo - Referencia1:\", nueva_referencia[0], \"Referencia2:\", nueva_referencia[1])\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/jesusgdev.py",
    "content": "'''\nEJERCICIO:\n *   Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n     su tipo de dato.\n *   Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n     \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n     (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n  \n     DIFICULTAD EXTRA (opcional):\n *   Crea dos programas que reciban dos parámetros (cada uno) definidos como\n     variables anteriormente.\n *   Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n     se asigna a dos variables diferentes a las originales. A continuación, imprime\n     el valor de las variables originales y las nuevas, comprobando que se ha invertido\n     su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n'''\n\n# 1. Asignacion por valor\n# La asignacion por valor en python trabaja con las variables de tipo primitivo\n# es decir las variables de tipo int, str, float y las bool.\n\na = 10    # Le asignamos a \"a\" el valor 10\nb = a    # Le asignamos a \"b\" el valor que posee \"a\" es decir 10\n\nb = b + 5    # \"b\" ahora vale 15\nprint(a)    # \"a\" sigue valiendo 10\nprint(b)    # \"b\" vale 15\n\n\n# 2. Asignacion por referencia\n\nlist1 = [7, 15, 23]\nlist2 = list1    # list2 apuntara al mismo objeto, es decir a la referencia en memoria de list1\n\nlist2.append(38)\n\nprint(list1)    # [7, 15, 23, 38]\nprint(list2)    # [7, 15, 23, 38]\n\n# 3. Paso de variables a funciones por valor\n\n# a. Ejemplo con valores primitivos (int)\n\ndef dup(num):\n    num = num * 2\n    print(\"Dentro de la funcion:\", num)\n\nnum = 6\ndup(num)                              # Dentro de la funcion: 12 \nprint(\"Fuera de la funcion:\", num)    # Fuera de la funcion: 6\n\n# b. Ejemplos con referencias (listas)\\\n\ndef add_value(list3):\n    list3.append(\"c\")\n    print(\"Dentro de la función:\", list3)\n\nmy_list = [\"a\", \"b\"]\nadd_value(my_list)                        # ['a', 'b', 'c']\nprint(\"Fuera de la función:\", my_list)    # ['a', 'b', 'c']\n\n\n'''\nExtra\n *   Crea dos programas que reciban dos parámetros (cada uno) definidos como\n     variables anteriormente.\n *   Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n     se asigna a dos variables diferentes a las originales. A continuación, imprime\n     el valor de las variables originales y las nuevas, comprobando que se ha invertido\n     su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n'''\n\nnum1 = 8\nnum2 = 17\nprint(\"\")\ndef exchange_values(a, b):\n    aux = a\n    a = b\n    b = aux\n    return a, b\n\nnew_num1, new_num2 = exchange_values(num1, num2)\nprint(\"Intercambio de valores\")\nprint(f\"Originales: num1 = {num1}, num2 = {num2}\")        # Originales: num1 = 8, num2 = 17\nprint(f\"Nuevos: new_num1 = {new_num1}, new_num2 = {new_num2}\")    # Nuevos: new_num1 = 17, new_num2 = 8\n\n\nlist1 = [20, 40]\nlist2 = [60, 80]\nprint(\"\")\ndef exchange_ref(c, d):\n    aux = c\n    c = d\n    d = aux\n    return c , d\n\nnew_list1, new_list2 = exchange_ref(list1, list2)\nprint(\"Intercambio de Referencias\")\nprint(f\"Originales: list1 = {list1}, list2 = {list2}\")\nprint(f\"Nuevos: new_list1 = {new_list1}, new_list2 = {new_list2}\")\n\n\n\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/jesusway69.py",
    "content": "import os\nos.system('cls')\nos.system('clear')\n\"\"\"\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n\"\"\"\n\nvpv = \"Hola Mundo\" #Al ser un tipo primitivo (string) Python toma la variable por valor\nprint(\"Variable por valor ANTES de la función:\",vpv)\nvpr = [\"Hola\", \"Mundo\"] #Al ser un tipo de estructura (lista) Python toma la variable por referencia\nprint(\"Variable por referencia ANTES de la función:\",vpr)\ndef string_variables(vpv:str, vpr:list[str,str]):\n    vpv = vpv.replace(\"Mundo\",\"Python\") #Modificamos el string dentro de la función\n    print(\"\\nVariable por valor DENTRO de la función:\",vpv)\n    vpr [1] = \"Python\" #Modificamos un elemento de la lista dentro de la función\n    print(\"Variable por referencia DENTRO de la función:\",vpr)\nstring_variables(vpv,vpr)\n\nprint(\"\\nVariable por valor DESPUÉS de la función:\",vpv)\n#El string modificado dentro de la función sigue teniendo su valor original despues de la misma\nprint(\"Variable por referencia DESPUÉS de la función:\",vpr)\n#La lista modificada dentro de la función ha quedado con la modificación despues de la misma\n\n#En el siguiente caso usaremos variable de tipo int para valor y un set para referencia, además\n# añadiremos a la impresión el nº identificativo que asigna Python a la variable en cada caso.\nvpv = 128\nprint(\"\\nVariable por valor ANTES de la función:\",vpv, \"con ID:\", id(vpv))\nvpr = {1,2,4,8,16,32,64}\nprint(\"Variable por referencia ANTES de la función:\",vpr,\"con ID:\", id(vpr))\n\ndef int_variables (vpv:int, vpr:set):\n    vpv = vpv*2\n    print(\"\\nVariable por valor DENTRO de la función:\",vpv,\"con ID:\", id(vpv))\n    vpr.add(128)\n    print(\"Variable por referencia DENTRO de la función:\",vpr,\"con ID:\", id(vpr))\nint_variables(vpv,vpr)\n\nprint(\"\\nVariable por valor DESPUÉS de la función:\",vpv,\"con ID:\", id(vpv))\nprint(\"Variable por referencia DESPUÉS de la función:\",vpr, \"con ID:\", id(vpr), \"\\n\")\n#Observamos a la salida por terminal del programa que los ID siempre se mantienen en el caso de\n# las variables por referencia pero cambia en las de valor dentro de la función para después\n# volver a mostrar su ID original después de la misma.\n\n\n#Sin embargo una variable por referencia no modificará su contenido si lo que hace la función es \n# reasignarle otra lista con valores modificados como vemos en el siguiente ejemplo:\n\nmy_list =[1,2,3]\nprint(\"Variable por referencia ANTES de la función:\", my_list)\ndef re_asign (my_list):\n    my_list =[4,5,6]\n    print(\"\\nVariable por referencia reasignada DENTRO de la función:\",my_list)\nre_asign(my_list)\nprint(\"Variable por referencia reasignada DESPUÉS de la función:\",my_list)\n\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n\"\"\"\nprint(\"\\nEJERCICIO:\\n\")\nvar1 = \"Hola\"\nvar2 = \"Python\"\n\ndef value_exchange(var1,var2):\n    copy = var1\n    var1 = var2\n    var2 = copy\n    return var1, var2\n\nnew_var1, new_var2 = value_exchange(var1,var2)\nprint(var1 + \" \" + var2)\nprint (new_var1 + \" \" + new_var2 + \"\\n\")\n\n\nvar1 = [\"Hola\"]\nvar2 = [\"Python\"]\n\ndef reference_exchange(var1,var2):\n    copy = var1\n    var1 = var2\n    var2 = copy\n    return var1, var2\n\nnew_var1, new_var2 = reference_exchange(var1,var2)\nprint(var1 ,  var2)\nprint (new_var1 ,  new_var2 , \"\\n\")\n\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/jgutierrez9891.py",
    "content": "\"\"\"\nAsignación de variables por valor\n\"\"\"\n\ndef triplicar_valor(valor):\n    valor *= 3\n    return valor\n\nn1 = 10\nn2 = 99\nn2 = n1                     # Se asigna a n2 el valor de n1 en el momento\nn1 = triplicar_valor(n1)\nprint(n1)\nprint(n2)                   # Mantiene el valor que tenía n1 al momento de la asignación \n\n\n\"\"\"\nAsignación de variables por referencia\n\"\"\"\n\ndef cuadrado_lista(valor):\n    for i in valor:\n        valor[i-1] **=2 \n\nlista1 = [1, 2, 3, 4, 5]\nlista2 = [0, 0, 0, 0, 0]\nlista2 = lista1             # Se asigna a lista2 lo posición de memoria de lista1\ncuadrado_lista(lista1)\nprint(lista1)\nprint(lista2)               # Se actualizó con el nuevo valor de lista1 porque apuntan a la misma posición de memoria\n\n\"\"\"\nExtra\n\"\"\"\n\ndef fun_valor(var1, var2):\n    aux = var1\n    var1 = var2\n    var1 = aux\n    return var1, var2\n\ndef fun_param(lis1, lis2):\n    aux = []\n    aux = lis1\n    lis1 = lis2\n    lis2 = aux\n    return lis1, lis2\n\n\noriginal_val1 = 10\noriginal_val2 = 20\nprint(f\"var1 original es:{original_val1} y var2 original es:{original_val2}\")\n\nnueva_val1, nueva_val2 = fun_valor(original_val1 , original_val2)\nprint(f\"var1 ahora es:{nueva_val1} y var2 ahora es:{nueva_val2}\")\n\n\noriginal_lis1_ref = [10,20,30,40,50]\noriginal_lis2_ref = [15,25,35,45,55]\nprint(f\"lista 1 original es:{original_lis1_ref} y lista 2 original es:{original_lis2_ref}\")\n\nnueva_lis1_ref, nueva_lis2_ref = fun_param(original_lis1_ref , original_lis2_ref)\nprint(f\"lista 1 ahora es:{nueva_lis1_ref} y lista 2 ahora es:{nueva_lis2_ref}\")"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/jhoshmc.py",
    "content": "def ejercicio():\n  val=\"hola\"\n  print(f\"texto original: {val} \\n\")\n  f_valor(val)\n  print(f\"texto original: {val}\")\n  print(f\"\\n pasando variables por referencia \")\n  f_referencia()\n\ndef f_valor(text):\n  \"\"\"\n  * cuando se pasa variable inmutables como enteros, tuplas, cadenas, cualquier cambio que se aga dentro\n  * de esa funcion, no afectará a la variable original fuera de es scope\n  \"\"\"\n  print(f\"texto en la funcion: {text}\")\n  text = \"chiao\"\n  print(f\"texto modificado: {text}\")\n\ndef f_referencia():\n  \"\"\"\n  *cuando se pasa variables mutables, como listas, diccionarios, objetos o conjuntos, se pasa la \n  * referencia a ese objeto, por lo que cualquier modificacion se llevara acabo tambien a la variable\n  * original que esta fuera de este scope \n  \"\"\"\n  lista=[1,2,3,4]\n  eliminar_elemento_lista(lista)\n  print(f\"lista original: {lista}\")\n\ndef eliminar_elemento_lista(lista):\n  print(f\"elementos de la lista: {lista}\")\n  lista.pop()\n\nejercicio()\n\ndef extra():\n  print(\"\\n ejercico extra: \\n\")\n  p_1= 1\n  p_2=2\n  [c_1,c_2]= e_valor(p_1,p_2)\n  print(f\"el valor de p_1 es: {p_1}\")\n  print(f\"el valor de p_2 es: {p_2}\")\n  print(\"\\n pasndo por valor: \")\n  print(f\"el valor de c_1 es: {c_1}\")\n  print(f\"el valor de c_2 es: {c_2}\")\n  print(\"\\n pasando por referencia: \")\n  r_1=[1]\n  r_2=[2]\n  print(f\"el valor de r_1 es: {r_1[0]}\")\n  print(f\"el valor de r_2 es: {r_2[0]}\")\n  [cr_1,cr_2]=e_referencia(r_1,r_2)\n  print(f\"el valor de cr_1 es: {cr_1[0]}\")\n  print(f\"el valor de cr_2 es: {cr_2[0]}\")\n  print(\"\\nnuevos valores\\n\")\n  print(f\"valor de r_1 es: {r_1[0]}\")\n  print(f\"valor de r_2 es: {r_2[0]}\")\n\ndef e_valor(p_1,p_2)->int:\n  aux= p_1\n  p_1=p_2\n  p_2= aux\n  return [p_1,p_2]\n\ndef e_referencia(r_1,r_2):\n  aux=r_1[0]\n  r_1[0]=r_2[0]\n  r_2[0]=aux\n\n  return [r_1,r_2]\n\nextra()"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/jorgeadamowicz.py",
    "content": "### valor y referencia ###\n\n\n\n## tipos de datos por valor (int, float, str, tuple, bool)\n\"\"\"\npor valor implica que cuando se asigna una variable a otra o se pasa como argumento, se copia el valor real del objeto \nen ese momento\n\"\"\"\n\nmy_int_a = 10\nmy_int_b = 20\nmy_int_b = my_int_a\n\nprint(my_int_a) #out 10\nprint(my_int_b) #out 20\n\nmy_int_b += 5\nprint(my_int_b) #out: 15\n\nmy_int_a = 10\nmy_int_b = 20\nmy_int_b = my_int_a\n\nmy_int_a = 30\n\nprint(my_int_a) #out: 30\nprint(my_int_b) #out: 10\n\n#muestra la direccion de memoria\nprint(id(my_int_a))\nprint(id(my_int_b))\n\n# tipos de datos por referencia (list, dict, set)\n\"\"\"\nPor referencia implica que las variables contienen una referencia al objeto en memoria, no el valor directamente. \nEsto significa que si se modifica el contenido del objeto usando una de las referencias, los cambios se reflejan en todas\nlas referencias.\nEn el caso por referencia, No copian su valor, sino que heredan su dirección de memoria.\n\"\"\"\nmy_list_a = [10, 20]\nmy_list_b = [30, 40]\n\nprint(my_list_a)\nprint(my_list_b)\n\nmy_list_b = my_list_a\n\nmy_list_a.append(30)\n\nprint(my_list_a)\nprint(my_list_b)\n\n#muestra la direccion de memoria\nprint(id(my_list_a))\nprint(id(my_list_b))\n\n## funcion que recibe variables por valor:\n\nmy_int_c = 10\n\ndef my_int_func(my_int):\n    my_int = 20\n    \n    return my_int\n    \nvalor_en_funcion = my_int_func(my_int_func)\nprint(f\"el valor dentro de la funcion es: {valor_en_funcion}, el valor fuera de la funcion es :{ my_int_c}\")\n\n\n## funcion que recibe variables por referencia:\n\nmy_list_c = [10, 20]\n\ndef my_list_func(my_list):\n    my_list.append(30)\n    \n    return my_list\n    \nvalor_referencia_en_funcion = my_list_func(my_list_c)\nprint(f\"el valor de referencia dentro de la funcion es: {valor_referencia_en_funcion}, el valor fuera de la funcion es :{ my_list_c}\")\n\n\"\"\"\nEjercicio Dificultad Extra:\n\"\"\"\nprint(\"--------------------------\"*5)\nprint(\"Ejercicio Extra:\\n\")\n\n# por valor:\n\nmy_int_d = 10\nmy_int_e = 20\n\ndef value_changer(d, e):\n    #intercambio por desempaquetado (swapping)\n    d,e = e,d\n    return d,e\n\nresultado = value_changer(my_int_d, my_int_e)\n\nprint(f\" el valor original es: \\n my_int_d: {my_int_d}\\n my_int_e: {my_int_e}\")\nprint(f\" el valor cambiado es: \\n my_int_d:{resultado[0]}\\n my_int_e: {resultado[1]}\")\n\nprint(\"\\n\")\nprint(\"--------------------------\"*5)\n\n#por referencia:\n\nmy_list_d = [10, 20]\nmy_list_e = [20, 10]\n\ndef value_changer(d, e):\n    #intercambio por desempaquetado (swapping).\n    # d,e = e,d\n    \n    #tambien puede realizarse con una variable \"temporal\"\n    temp = d\n    d = e\n    e = temp\n    return d,e\n\nresultado = value_changer(my_list_d, my_list_e)\n\nprint(f\" el valor original es: \\n my_list_d: {my_list_d}\\n my_list_e: {my_list_e}\")\nprint(f\" el valor cambiado es: \\n my_list_d:{resultado[0]}\\n my_list_e: {resultado[1]}\")\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/jose-larss.py",
    "content": "\"\"\"\nValor y Referencia\n\"\"\"\n\n# Tipos de dato por valor\n\nmy_int_a = 10\nmy_int_b = my_int_a\nmy_int_b = 20\n#my_int_a = 30\nprint(my_int_a)\nprint(my_int_b)\n\n# Tipos de dato por referencia\n\nmy_list_a = [10, 20]\nmy_list_b = my_list_a\nmy_list_b.append(30)\nprint(my_list_a)\nprint(my_list_b)\n\n# Funciones con datos por valor\n\n\ndef my_int_func(my_int: int):\n    my_int = 20\n    print(my_int)\n\n\nmy_int_c = 10\nmy_int_func(my_int_c)\nprint(my_int_c)\n\n\n# Funciones con datos por referencia\n\n\ndef my_list_func(my_list: list):\n    my_list.append(30)\n\n    my_list_d = my_list\n    my_list_d.append(40)\n\n    print(my_list)\n    print(my_list_d)\n\n\nmy_list_c = [10, 20]\nmy_list_func(my_list_c)\nprint(my_list_c)\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\"\"\"\n\n# Por valor\n\n\ndef value(value_a: int, value_b: int) -> tuple:\n    temp = value_a\n    value_a = value_b\n    value_b = temp\n    return value_a, value_b\n\n\nmy_int_d = 10\nmy_int_e = 20\nmy_int_f, my_int_g = value(my_int_d, my_int_e)\n\nprint(f\"{my_int_d}, {my_int_e}\")\nprint(f\"{my_int_f}, {my_int_g}\")\n\n# Por referencias\n\n\ndef ref(value_a: list, value_b: list) -> tuple:\n    temp = value_a\n    value_a = value_b\n    value_b = temp\n    return value_a, value_b\n\n\nmy_list_e = [10, 20]\nmy_list_f = [30, 40]\nmy_list_g, my_list_h = ref(my_list_e, my_list_f)\nprint(f\"{my_list_e}, {my_list_f}\")\nprint(f\"{my_list_g}, {my_list_h}\")"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/josecox13.py",
    "content": "# Variables por valor\na = 15.8\nb = 23.3\nprint (a)\nprint(b)\na = b\nb = 3.33\nprint(a)\nprint(b)\n\n#Variables por referencia\nc = [1,2,3]\nd = [4,5,6]\nprint(c)\nprint(d)\nc = d\nd.append(1)\nprint(c)\nprint(d)\n\n\n##Funciones con variables por valor\ndef float_func(my_float: float):\n    my_float = 15.3\n    print(my_float)\n\n\ne = 10.2\nfloat_func(e)\nprint(e)\n\n##Funciones con variables por referencia\n\ndef lista_func(mi_lista: list):\n    mi_lista.append('c')\n\n    mi_lista_d = mi_lista\n    mi_lista.append('d')\n\n    print(mi_lista)\n    print(mi_lista_d)\n\n\nmi_lista_c = ['a','b']\nlista_func(mi_lista_c)\nprint(mi_lista_c)\n\n##Dificultad extra\n# Por valor\ndef valor(var_a, var_b):\n    aux = var_a\n    var_a = var_b\n    var_b = aux\n    return var_a, var_b\n\nvar_a = 15\nvar_b = 25\nvar_a, var_b = valor(var_a,var_b)\nprint(var_a)\nprint(var_b)\n\n#Por referencia\n\ndef referencia(list_a, list_b):\n    aux = list_a\n    list_a = list_b\n    list_b = aux\n    return list_a, list_b\n\nlista_a = [1,2]\nlista_b = [3,4]\n\nlista_a, lista_b = referencia(lista_a, lista_b)\nprint(lista_a)\nprint(lista_b)\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/jptxaya.py",
    "content": "#Paso por valor\n#Originales\nprint(\"#####Paso por valor#####\")\nprint(\"Valores originales\")\nmy_string = \"Hola Mundo\"\nmy_int = 10\nmy_boolean = True\nmy_float = 1.5\nprint(my_string)\nprint(my_int)\nprint(my_boolean)\nprint(my_float)\n\n#Paso por valor\ndef paso_valor(mstring, mint, mboolean, mfloat):\n    mtring = \"New String\"\n    mint = 20\n    mboolean = False\n    mfloat = 2.5\n\npaso_valor(my_string, my_int, my_boolean, my_float)\nprint(\"Despues\")\nprint(my_string)\nprint(my_int)\nprint(my_boolean)\nprint(my_float)\n\n#Paso por referencia\n#Originales\nprint(\"######Paso por referencia######\")\nprint(\"Valores originales\")\nmy_list = [1,2,3]\nmy_tuple = (\"first\",\"second\",\"third\")\nmy_dict = {0: \"zero\",1: \"one\", 2:\"two\"}\nmy_set = {10,11,12}\nprint(my_list)\nprint(my_tuple)\nprint(my_dict)\nprint(my_set)\n\ndef paso_referencia(mlist:list,mtuple:tuple,mdict:dict,mset:set):\n    mlist.append(\"4\")\n    mdict[1] = \"Valor modificado\"\n    mtuple = (\"zero\")\n    mset.add(13)\n\npaso_referencia(my_list,my_tuple,my_dict,my_set)\nprint(\"Despues\")\nprint(my_list)\nprint(my_tuple) #La tupla es inmutable\nprint(my_dict)\nprint(my_set)\n\n#Dificultad extra\nprint(\"***DIFICULTAD EXTRA***\")\nprint(\"#####Paso por valor#####\")\nprint(\"Valores originales\")\nmy_string = \"Hola Mundo\"\nmy_int = 10\nprint(f\"String orig: {my_string}\")\nprint(f\"Int orig: {my_int}\")\n\ndef dif_valor( mstring, mint):\n    mstring = \"Fin\"\n    mint = 0\n    return mstring, mint\n\nmy_new_string, my_new_int = dif_valor(my_string,my_int)\nprint(f\"New String: {my_new_string}\")\nprint(f\"New Int: {my_new_int}\")\nprint(f\"String orig: {my_string}\")\nprint(f\"Int orig: {my_int}\")\n\nprint(\"#####Paso por referencia#####\")\nprint(\"Valores originales\")\nmy_list = [1,2,3]\nmy_dict = {0: \"zero\",1: \"one\", 2:\"two\"}\nprint(f\"List orig: {my_list}\")\nprint(f\"Dict orig: {my_dict}\")\n\ndef dif_referencia( mlist, mdict):\n    mlist.append(4)\n    mdict[1] = \"Valor modificado\"\n    return mlist, mdict\n\nmy_new_list, my_new_dict = dif_referencia(my_list,my_dict)\nprint(f\"New List: {my_new_list}\")\nprint(f\"New Dict: {my_new_dict}\")\nprint(f\"List orig: {my_list}\")\nprint(f\"Dict orig: {my_dict}\")\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/jtrujilloalcocer.py",
    "content": "# #05 VALOR Y REFERENCIA\n## Ejercicio\n\n'''\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n'''\n\n#Asignacion de variables por valor\na = 5 #a es un entero\nb = a #b toma el valor de a\nb = 3 #b cambia su valor\nprint(a) #5\nprint(b) #3\n\n#Asignacion de variables por referencia\na = [5] #a es una lista\nb = a #b toma la referencia de a (no el valor)\nb[0] = 3 #b cambia el valor de a (porque es la misma lista)\nprint(a) #[3]\nprint(b) #[3]\n\n#Funciones con variables por valor\na = 5 #a es un entero\ndef funcion_valor(a): #a es una copia de la variable original\n    a = 3 #a cambia su valor\n    return a #se devuelve el valor de a\nprint(funcion_valor(a)) #3\n\n#Funciones con variables por referencia \na = [5] #a es una lista \ndef funcion_referencia(a): #a es una copia de la variable original\n    a[0] = 3 #a cambia el valor de la lista original\n    return a #se devuelve la lista original    \nprint(funcion_referencia(a)) #[3]\n\n#DIFICULTAD EXTRA (opcional):\n#Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n# - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n#   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n#   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n#   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n#   Comprueba también que se ha conservado el valor original en las primeras.\n\na = 5\nb = 3\nc= [10]\nd= [8]\n\n#Programa que recibe dos parámetros por valor\ndef intercambio_valor(a, b): #a y b son copias de las variables originales\n    a, b = b, a #se intercambian los valores\n    return a, b #se devuelven los valores intercambiados\nprint(intercambio_valor(a, b)) #(3, 5)\n\n#Programa que recibe dos parámetros por referencia\ndef intercambio_referencia(c, d):#c y d son copias de las variables originales\n    c[0], d[0] = d[0], c[0]#se intercambian los valores de las listas\n    return c, d #se devuelven las listas intercambiadas\nprint(intercambio_referencia(c, d)) #([3], [5])\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/juanRCoder.py",
    "content": "# Por valor\n\nnum = 10\nnew_num = num       # new_num recibe una copia del valor de num\n\nnew_num = 20        # Cambiamos el valor de new_num\nprint(num)          # num sigue siendo 10\nprint(new_num)      # new_num es 20\n\n\n# Por referencia\n\nlist_a = [1, 2, 3]\nlist_b = list_a     # lista_b referencia a la misma lista que list_a\n\nlist_b.append(4)    # Modificamos la lista a través de lista_b\n\nprint(list_a)       # lista_a también muestra el cambio [1, 2, 3, 4]\nprint(list_b)       # lista_b muestra el cambio [1, 2, 3, 4]\n\n\n# FUNCIONES:\n\n# VALOR\ndef function_valor(x):\n    x = 20                  \n    print(f\"valor dentro de la funcion: {x}\")\n\nx = 10\nfunction_valor(x)\nprint(f\"Fuera de la función: a = {x}\")\n# Salida:\n# Dentro de la función: x = 20\n# Fuera de la función: x = 10\n\n\n# REFERENCIA\ndef function_referencia(lista_a):\n    lista_a.append(4)   # Modificamos la lista\n\nlista_b = [1, 2, 3]\nfunction_referencia(lista_b)\nprint(lista_b)\n# Salida:\n# Dentro de la función: lista = [1, 2, 3] + 4\n# Fuera de la función:  lista = [1, 2, 3, 4]\n\n\n\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea dos programas que reciban dos parámetros (cada uno) definidos como\n#  * variables anteriormente.\n#  * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n#  *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\ndef exercise(a, b):\n    a, b = b, a\n    return a , b\n\n#  *   se asigna a dos variables diferentes a las originales. A continuación, imprime\na = 1\nb = 2\nc, d = exercise(a, b)\n\n\n#  *   el valor de las variables originales y las nuevas, comprobando que se ha invertido\n#  *   su valor en las segundas.\n#  *   Comprueba también que se ha conservado el valor original en las primeras.\n\nprint(f\"{a} ahora sera {c}\")\nprint(f\"{b} ahora sera {d}\")\n#  */\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/juanchernandezdev.py",
    "content": "### Python Value and Reference ###\n\n#! Variables By Reference\n\nmy_list = [1, 4, 5, 3, 6, 8]\nmy_list_second = my_list\nmy_list_second.remove(8)\nprint(my_list)\nprint(my_list_second)\n\ndef more_items(list):\n  list.append(10)\n  \nmore_items(my_list)\nprint(my_list)\n\nmore_items(my_list_second)\nprint(my_list_second)\n\n#! Variables By Value\n\nmy_num = 55\nmy_num_second = my_num\nmy_num_second = 60\nprint(my_num)\nprint(my_num_second)\n\nmy_str = 'Hello Python.'\nmy_str_second = my_str\nmy_str_second = 'Hello Python, And Hello World!!'\nprint(my_str)\nprint(my_str_second)\n\ndef my_sum(num_one, num_two):\n  return num_one + num_two\n\nprint(my_sum(10, 5))\n\n#! Optional Challenge\n\nnum_a = 50\nnum_b = 30\n\ndef value_params(num1, num2):\n  num1, num2 = num2, num1\n  return num1, num2\n\nnew_num_1, new_num_2 = value_params(num_a, num_b)\nprint(new_num_1, new_num_2)\nprint(num_a, num_b)\n\nlist_a = [1, 5, 4, 8, 10]\nlist_b = [100, 500, 600, 800]\n\ndef ref_params(list1, list2):\n  list1, list2 = list2, list1\n  return list1, list2\n\nnew_list_1, new_list_2  = ref_params(list_a, list_b)\nprint(new_list_1, new_list_2)\nprint(list_a, list_b)\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/juandaherrera.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n\"\"\"\n\nfrom typing import List, Union\n\n# Por valor (inmutables)\nnumber = 42\nstring = \"Hola mundo!\"\nboolean = True\n\n# Por referencia (mutables)\nmy_list = [1, 2, 3]\nmy_dict = {\"Nombre\": \"Juan\", \"Apellido\": \"Herrera\"}\n\n\n# Función con parametros \"por valor\"\ndef elevate_value(value: Union[int, float], n: Union[int, float]):\n    value **= n\n    print(value)\n\n\nprint(number)\nelevate_value(number, 2)\nprint(number)\n\n\n# Función con parametros \"por valor\"\ndef elevate_values(container: List[Union[int, float]], n: Union[int, float]):\n    for index, value in enumerate(container):\n        container[index] = value**n\n\n    print(container)\n\n\nprint(my_list)\nelevate_values(my_list, 2)\nprint(my_list)\n\nprint(\"-----------------------------------------\")\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n\"\"\"\n\n\ndef are_values_equal(original_1, original_2, new_1, new_2):\n    return original_1 == new_1 and original_2 == new_2\n\n\ndef swap_by_value(param_1, param_2):\n    param_1, param_2 = param_2, param_1\n    return param_1, param_2\n\n\nvalue_1 = \"Juan\"\nvalue_2 = \"David\"\n\nprint(value_1, value_2)\nvalue_3, value_4 = swap_by_value(value_1, value_2)\nprint(value_1, value_2)\nprint(value_3, value_4)\nprint(\n    \"El valor de las variables originales fue invertido:\",\n    are_values_equal(value_1, value_2, value_3, value_4),\n)\nprint(\"---------------------------\")\n\n\ndef swap_by_reference(param_1, param_2):\n    if len(param_1) == len(param_2):\n        for index in range(len(param_1)):\n            param_1[index], param_2[index] = param_2[index], param_1[index]\n    return param_1, param_2\n\n\nvalue_1 = [\"Juan\", \"David\"]\nvalue_2 = [\"Herrera\", \"Parra\"]\n\nprint(value_1, value_2)\nvalue_3, value_4 = swap_by_reference(value_1, value_2)\nprint(value_1, value_2)\nprint(value_3, value_4)\nprint(\n    \"El valor de las variables originales fue invertido:\",\n    are_values_equal(value_1, value_2, value_3, value_4),\n)\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/juanmax2.py",
    "content": "\"\"\"\nValor y referencia\n\"\"\"\n# Tipos de datos por valor\nmy_int = 10\nmy_int_2 = my_int\nmy_int = 30\nprint(my_int)\nprint(my_int_2)\n\n# Tipos de datos por referenciaç\n# Las dos listas apuntan al mismo guardado en la memória\nlista_a = [10, 20]\nlista_b = lista_a\nlista_b.append(30)\n\nprint(lista_a)\nprint(lista_b)\n\n# Funciones con datos por valor\nmy_int_3 = 10\n\ndef my_int_func(my_int : int):\n    my_int = 20\n    print(my_int)\n\nmy_int_func(my_int_3)\nprint(my_int_3)\n\n# Funciones con datos por referencia\n\ndef my_list_func(my_list: list):\n    my_list.append(30)\n    \n    my_list_d = my_list\n    my_list_d.append(40)\n    \n    my_list_e = my_list_d\n    my_list_e.append(50)\n    \n    print(my_list)\n    print(my_list_d)\n    print(my_list_e)\n    \nmy_list_c = [10, 20]\nmy_list_func(my_list_c)\nprint(my_list_c)\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n\"\"\"\n\ndef valor(parametro1, parametro2):\n    temp = parametro1\n    parametro1 = parametro2\n    parametro2 = temp\n    return parametro1, parametro2\n\ndef referencia(parametro1, parametro2):\n    temp = parametro1\n    parametro1 = parametro2\n    parametro2 = temp\n    return parametro1, parametro2\n\n# Caso de uso por valor\nparametro1 = 10\nparametro2 = 20\nparametro1_retornado, parametro2_retornado = valor(parametro1, parametro2)\nprint(parametro1)\nprint(parametro2)\nprint(parametro1_retornado)\nprint(parametro2_retornado)\n\nprint(\"--------------------\")\nprint(\"--------------------\")\n\n# Caso de uso por referencia\nparametro_ref1 = [10, 20]\nparametro_ref2 = [30, 40]\nparametro_ref1_retornado, parametro_ref2_retornado = referencia(parametro_ref1, parametro_ref2)\nprint(parametro_ref1)\nprint(parametro_ref2)\nprint(parametro_ref1_retornado)\nprint(parametro_ref2_retornado)\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/juanppdev.py",
    "content": "\"\"\"\n* - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n\"\"\"\n\n# Asignación de variables \"por valor\" (int, float, str, tuple)\nnumero = 5\nnumero_copia = numero\nnumero_copia += 1\nprint(\"numero:\", numero)  # Salida: 5\nprint(\"numero_copia:\", numero_copia)  # Salida: 6\n\ncadena = \"Hola\"\ncadena_copia = cadena\ncadena_copia += \" Mundo\"\nprint(\"cadena:\", cadena)  # Salida: Hola\nprint(\"cadena_copia:\", cadena_copia)  # Salida: Hola Mundo\n\ntupla = (1, 2, 3)\ntupla_copia = tupla\ntupla_copia += (4, 5)\nprint(\"tupla:\", tupla)  # Salida: (1, 2, 3)\nprint(\"tupla_copia:\", tupla_copia)  # Salida: (1, 2, 3, 4, 5)\n\n# Asignación de variables \"por referencia\" (list, dict, set)\nlista = [1, 2, 3]\nlista_referencia = lista\nlista_referencia.append(4)\nprint(\"lista:\", lista)  # Salida: [1, 2, 3, 4]\nprint(\"lista_referencia:\", lista_referencia)  # Salida: [1, 2, 3, 4]\n\ndiccionario = {\"a\": 1, \"b\": 2}\ndiccionario_referencia = diccionario\ndiccionario_referencia[\"c\"] = 3\nprint(\"diccionario:\", diccionario)  # Salida: {'a': 1, 'b': 2, 'c': 3}\nprint(\"diccionario_referencia:\", diccionario_referencia)  # Salida: {'a': 1, 'b': 2, 'c': 3}\n\nconjunto = {1, 2, 3}\nconjunto_referencia = conjunto\nconjunto_referencia.add(4)\nprint(\"conjunto:\", conjunto)  # Salida: {1, 2, 3, 4}\nprint(\"conjunto_referencia:\", conjunto_referencia)  # Salida: {1, 2, 3, 4}\n\n# EJERCICIO EXTRA\n\"\"\"\n    Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n\"\"\"\n\n# Por valor\ndef swap_by_value(x, y):\n    # Swap the values of x and y\n    x, y = y, x\n    # Return the swapped values\n    return x, y\n\n# Define two variables with integer values\na = 5\nb = 10\n# Call the swap_by_value function and assign the returned values to new variables\nc, d = swap_by_value(a, b)\n# Print the original and new variables\nprint(\"Por valor:\")\nprint(\"Original variables: a =\", a, \", b =\", b)\nprint(\"New variables: c =\", c, \", d =\", d)\n\n# Por referencia\ndef swap_by_reference(lst):\n    # Swap the first and second elements of the list\n    lst[0], lst[1] = lst[1], lst[0]\n    # Return the modified list\n    return lst\n\n# Define two variables with list values\ne = [5, 10]\nf = [15, 20]\n# Call the swap_by_reference function and assign the returned value to a new variable\ng = swap_by_reference([e, f])\n# Print the original and new variables\nprint(\"Por referencia:\")\nprint(\"Original variables: e =\", e, \", f =\", f)\nprint(\"New variables: g =\", g)"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/juserdev.py",
    "content": "\"\"\" \n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\"\"\"\n\"\"\" \n  ->  Los tipos de datos por valor ocupan cada uno un espacio independiente en memoria y se usan con tipos de datos inputables (números, strings, booleanos, tuplas)\n  ->  Los timpos de datos por referencia ocupan el mismo espacio en memoria y se unsan con tipos de datos mutables (listas, diccionarios, conjuntos, objetos)\n    ->  Al momento de crear una lista y copiar su valor en una variable adiciona se copia por referencia ya que ocupan el mismo espacio en memoria\n    ->  my_list_2.append(30) -> en este ejemplo modifico la my_list_2 pero tambien se modifica my_list_1\n  -> en las funcioens se hace exactamente igual que lo hice fuera de las funciones solo que se le asigno un parametro para funcionar\n\"\"\"\n\n# tipos de datos por valor\n\nvariable_1 = 30 # valor\nvariable_2 = variable_1 # referencia\n\nprint(variable_1) # 30\nprint(variable_2) # 30\n\nvariable_1 = 50\n\nprint(variable_1) # 50\nprint(variable_2) # 30\n\n# tipos de datos por referencia\n\nmy_list_1 = [10, 20] # lista\nmy_list_2 = my_list_1\nmy_list_2.append(30) # my_list_1 = [10, 20, 30]\n\nprint(my_list_1) # [10, 20, 30]\nprint(my_list_2) # [10, 20, 30]\n\n# Funcion con datos por valor\n\nmy_number = 10\ndef my_function_a(my_int: int):\n  my_int = 20\n  return my_int\n\nprint(my_function_a(my_number))\nprint(my_number)\n\n# Funcion con datos por referencia\n\nmy_list_3 = [10, 20 ]\ndef my_function_b(my_list: list):\n  my_list.append(30)\n  return my_list\n\nprint(my_function_b(my_list_3))\nprint(my_list_3)\n\n# DIFICULTAD EXTRA\n\n## Funcion por valor\n\nmy_int_1 = 10\nmy_int_2 = 20\n\ndef values(param_1: int, param_2: int) -> list:\n  temp = param_1\n  param_1 = param_2\n  param_2 = temp\n  \n  return [param_1, param_2]\n\n\nmy_int_3, my_int_4 = values(my_int_1,my_int_2)\n\nprint(f\"my_int_1 = {my_int_1} y my_int_3 = {my_int_3}\")\nprint(f\"my_int_2 = {my_int_2} y my_int_4 = {my_int_4}\")\n\n## Duncion por referencia\n\nmy_list_a = [10, 20]\nmy_list_b = [30, 40]\n\ndef ref(list_1: list, list_2: list):\n  temp = list_1\n  list_1 = list_2\n  list_2 = temp\n\n  return [list_1, list_2]\n\nmy_list_c, my_list_d = ref(my_list_a, my_list_b)\n\nprint(my_list_a)\nprint(my_list_b )\nprint(my_list_c)\nprint(my_list_d)\n\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/k-90.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\"\"\"\n\n# Por valor\n\nmy_num_a = 5\nmy_num_b = my_num_a\nmy_num_b = 10\nprint(my_num_a)\nprint(my_num_b)\n\n# Por referencia\n\nmy_list_a = [1,2,3]\nmy_list_b = my_list_a\nmy_list_b.append(4)\nprint(my_list_a)\nprint(my_list_b)\n\n\n# Funciones por valor\n\nx = 10\nprint(id(x))\ndef func(entrada):\n    entrada = 0\n    print(id(entrada))\n\nfunc(x)\nprint(x)\n\n# Funciones por referencia\n\nx = [10,20,30]\nprint(id(x))\ndef func2(entrada):\n    entrada.append(40)\n    print(id(entrada))\nfunc2(x)\nprint(x)\n\n### Extra\n\n# Por valor\n\ndef valor(valor_1:int, valor_2:int) -> tuple:\n    sor = valor_1\n    valor_1 = valor_2\n    valor_2 = sor\n    return valor_1, valor_2\n\nmy_num_c = 14\nmy_num_d = 15\nmy_num_e, my_num_f = valor(my_num_c,my_num_d)\nprint(f\"{my_num_c},{my_num_d}\")\nprint(f\"{my_num_e},{my_num_f}\")\n\n# Por referencia\n\ndef referencia(valor_1:list, valor_2:list) -> tuple:\n    sor = valor_1\n    valor_1 = valor_2\n    valor_2 = sor\n    return valor_1, valor_2\n\nmy_list_c = [1,2]\nmy_list_d = [11,22]\nmy_list_e, my_list_f = referencia(my_list_c,my_list_d)\nprint(f\"{my_list_c}, {my_list_d}\")\nprint(f\"{my_list_e},{my_list_f}\")\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/keltoi-dev.py",
    "content": "\"\"\"\n* EJERCICIO:\n* - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n*   su tipo de dato.\n* - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n*   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n* (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n\"\"\"\n\n# Asignacion por valor\nx = 100\ny = x\ny = 10\nprint(id(x))\nprint(id(y))\n\nprint(x, y)\nprint(\"Al ser inmutables apuntan a distintos id a pesar que se igualaron\")\n\n# Asignacion por referencia\nl1 = [1, 2, 3, 4]\nl2 = l1\nl2.append(5)\n\nprint(id(l1))\nprint(id(l2))\n\nprint(l1, l2)\nprint(\"Al ser mutables apuntan al mismo id desde que se igualaron\")\n\n\n# Paso a funciones por valor\ndef valor(num):\n    num += 10\n    print(\"La variable dentro de la funcion:\", num)\n    print(id(num))\n\n\nvalor(x)\nprint(\"La variable fuera de la funcion:\", x)\nprint(id(x))\n\n\n# Paso a funciones por referencia\ndef referencia(lista):\n    lista.pop()\n    print(\"La variable dentro de la funcion:\", lista)\n    print(id(lista))\n\n\nreferencia(l1)\nprint(\"La variable fuera de la funcion:\", l1)\nprint(id(l1))\n\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n* Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n* - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n*   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n*   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n*   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n*   Comprueba también que se ha conservado el valor original en las primeras.\n\"\"\"\n\n\n# Funcion con parametros por valor\ndef prog_valor(num1, num2):\n    num2, num1 = num1, num2\n    return num1, num2\n\n\noriginal1 = 10\noriginal2 = 100\nnuevo1, nuevo2 = prog_valor(original1, original2)\n\nprint(f\"El primer valor original es {original1} y el segundo {original2}\")\nprint(f\"El primer valor nuevo es {nuevo1} y el segundo {nuevo2}\")\n\n\n# Funcion con parametros por referencia\ndef prog_referencia(l_orig1, l_orig2):\n    l_orig2, l_orig1 = l_orig1, l_orig2\n    return l_orig1, l_orig2\n\n\nl_orig1 = [1, 2, 3]\nl_orig2 = [4, 5, 6]\n\nl_nueva1, l_nueva2 = prog_referencia(l_orig1, l_orig2)\n\nprint(f\"El primer valor original es {l_orig1} y el segundo {l_orig2}\")\nprint(f\"El primer valor nuevo es {l_nueva1} y el segundo {l_nueva2}\")\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/kenysdev.py",
    "content": "# ╔══════════════════════════════════════╗\n# ║ Autor:  Kenys Alvarado               ║\n# ║ GitHub: https://github.com/Kenysdev  ║\n# ║ 2024 -  Python                       ║\n# ╚══════════════════════════════════════╝\n\n# ---------------------------------------\n# 1. Asignación de variables \"por valor\":\n# ---------------------------------------\n# - se asigna el valor real de la variable a otra variable.\n# - los cambios en una variable no afectarán a la otra.\n\n# inicialización:\nint1 = 111\nboo1 = False\nstr1 = \"Ben\"\n\n# asignación:\nint2 = int1\nboo2 = boo1\nstr2 = str1\n\n# cambio:\nint1 = 777\nboo1 = True\nstr1 = \"Bob\"\n\n# Las segundas variables no fueron afectadas.\nprint(int2, boo2, str2) # 111 False Ben\n\n# -----------------------------\n# ejemplo en una función:\ndef fun_v(en_int, en_boo, en_str):\n    # cambio:\n    en_int = 333\n    en_boo = False\n    en_str = \"Ken\"\n\n# paso por valor\nfun_v(int1, boo1, str1)\n\n# no afectadas por los cambios en la función.\nprint(int1, boo1, str1) # 777 True \"Bob\"\n\n# --------------------------------------------\n# 2. Asignación de variables \"por referencia\":\n# --------------------------------------------\n# - se asigna la referencia o dirección de memoria \n#   de la variable a otra variable.\n# - los cambios en una variable pueden afectar a la otra.\n\n# inicialización:\nlis1 = [444, True, \"Dan\"]\nset1 = {444, True, \"Dan\"}\ndic1 = {\"name\": \"Dan\"}\n\n# asignación:\nlis2 = lis1\nset2 = set1\ndic2 = dic1\n\n# cambio:\nlis1[0:3] = [888, False, \"Zoe\"]\nset1.difference_update({444, \"Dan\"})\ndic1[\"name\"] = \"Zoe\"\n\n# Las variables fueron afectadas por el cambio.\nprint(f\"\"\"\n{lis2}\n{set2}\n{dic2}\n\"\"\")\n\n# -----------------------------\n# ejemplo en una función:\ndef fun_r(en_lis, en_set, en_dic):\n    # cambio:\n    en_lis[0:3] = [333, True, \"Jay\"]\n    en_set.update({333, \"Jay\"})\n    en_dic[\"name\"] = \"Jay\"\n\n# paso por referencia\nfun_r(lis2, set2, dic2)\n\n# fueron afectadas por los cambios en la función.\nprint(f\"\"\"\n{lis2}\n{set2}\n{dic2}\n\"\"\")\n\n# -------------\n# 3. Ejercicio:\n# -------------\n'''\n* Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n'''\ns1 = \"Ben\"\ns2 = \"Zoe\"\nl1 = [12, 21]\nl2 = [\"Ben\", \"Zoe\"]\n\nprint(f\"\"\"\nPre-Intercambio:\n{s1} - {s2}\n{l1} - {l2}\n\"\"\")\n\ndef por_valor(str1, str2):\n    temp = str1\n    str1 = str2\n    str2 = temp\n    return str1, str2\n\ndef por_referencia(list1, list2):\n    cambiar = list1\n    list1 = list2\n    list2 = cambiar\n    return list1, list2\n\nnew_s1, new_s2 = por_valor(s1, s2)\nnew_l1, new_l2 = por_referencia(l1, l2)\n\nprint(f\"\"\"\nOriginales:\n{s1} - {s2}\n{l1} - {l2}\n\nNuevas:\n{new_s1} - {new_s2}\n{new_l1} - {new_l2}\n\"\"\")\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/kodenook.py",
    "content": "\n\"\"\"\n    Assignment By Value\n\"\"\"\n\nvar1 = 3\nvar2 = var1\n\nvar1 = 4\n\nprint(var1)\nprint(var2)\n\n\"\"\"\n    Assignment By Reference\n\"\"\"\n\nvar1 = [10, 20]\nvar2 = var1\n\nvar2.append(30)\n\nprint(var1)\nprint(var2)\n\n\"\"\"\n    Exercise\n\"\"\"\n\ndef ByValue(a: int, b: int) -> tuple:\n    c = b\n    d = a\n\n    return c, d\n\noriginal1 = 20\noriginal2 = 30\nvalue1, value2 = ByValue(original1, original2)\n\nprint('By Values')\nprint('Original Values')\nprint(original1)\nprint(original2)\nprint('After Function Values')\nprint(value1)\nprint(value2)\n\ndef ByReference(a: int, b: int) -> tuple:\n    c = b\n    d = a\n\n    return c, d\n\noriginal1 = 20\noriginal2 = 30\nvalue1, value2 = ByReference(original1, original2)\n\nprint('By Values')\nprint('Original Values')\nprint(original1)\nprint(original2)\nprint('After Function Values')\nprint(value1)\nprint(value2)"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/kuroz00.py",
    "content": "# * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n# *   su tipo de dato.\n\n#Asignacion por valor (Inmutable)\na = 10\nb = 20\ndef valor(a, b):\n    a = b\n    b += a\n    print('valor de A:' ,a ,'valor de B:' ,b)\nvalor(a, b) # A 20  y  B 40\nprint('valor de A:' ,a ,'valor de B:' ,b) #A 10 y B 20\n\n#Asignacion por referencia (Mutable)\nc = [1, 2, 3]\nd = [4, 5, 6]\ndef referencia(c, d):\n    print('C antes de la asignacion en la funcion:',c) \n    c.append(d)\nreferencia(c, d)\nprint('C despues de la asignacion en la funcion:',c)\n\n#Dificultad extra\n\n#variables originales\nentero1 = 10\nentero2 = 20\nlista1 = [1,2,3]\nlista2 = [10, 20, 30]\n\ndef cambiar_enteros(entero1, entero2):\n    caja = entero2\n    entero2_new = entero1   #variables nuevas\n    entero1_new = caja\n    return entero1_new, entero2_new #Retornar variables nuevas como la version invertida de las 2 anteriores\n\ndef cambiar_listas(lista1, lista2):\n    caja = lista2 \n    lista2_new = lista1     #variables nuevas\n    lista1_new = caja\n    return lista1_new, lista2_new #Retornar variables nuevas como la version invertida de las 2 anteriores\n\nprint(f'Enteros antes de la funcion: {entero1} {entero2}')  #10 y 20\nprint('Enteros despues de la funcion:', cambiar_enteros(entero1, entero2)) #20 y 10\n\nprint(f'Listas antes de la funcion: {lista1} {lista2}') #1,2,3 y 10,20,30\nprint('Listas despues de la funcion:', cambiar_listas(lista1, lista2)) #10,20,30 y 1,2,3\n\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/linerlander.py",
    "content": "\"\"\"\nValor y referencia\n\"\"\"\n\n# Tipos de dato por valor\nmy_num_x = 24\nmy_num_z = my_num_x\n#my_num_2 = 20\nmy_num_x = 30\nprint(my_num_x)\nprint(my_num_z)\n\n# Tipos de dato por referencia\nmy_lista_x = [10, 25]\nmy_lista_z = my_lista_x\nmy_lista_z.append(\"liner\")\n\nprint(my_lista_x)\nprint(my_lista_z)\n\n# Funciones con datos por valor\ndef my_int(my_num: int):\n    my_num = 20\n    print(my_num)\n\nmy_num_c = 10\nmy_int(my_num_c)\nprint(my_num_c)\n\n# Funciones con datos por referencia\ndef my_list(my_list: list):\n    my_list.append(30)\n\n    my_list_e = my_list\n    my_list_e.append(40)\n\n    print(my_list)\n    print(my_list_e)\n\nmy_list_d =[10,25]\nmy_list(my_list_d)\nprint(my_list_d)\n\n\"\"\"\nExtra\n\"\"\"\nprint('\\n')\n# Función por valor\ndef por_valor(val_1,val_2):\n    temp = val_1\n    val_1 = val_2\n    val_2 = temp\n    return val_1, val_2\n\nx = 5\ny = 8\na, b = por_valor(x, y)\n\nprint(f'{x},{y}')\nprint(f'{a},{b}')\n\n\n# Función por referencia\ndef por_referencia(ref_1: list,ref_2: list)-> tuple:\n    temp = ref_1\n    ref_1 = ref_2\n    ref_2 = temp\n    ref_2.append(50)\n    return ref_1,ref_2\n\nlista_1 = [10,20]\nlista_2 = [30,40]\nlista_3,lista_4 =por_referencia(lista_1,lista_2)\nprint(f'{lista_1} {lista_2}')\nprint(f'{lista_3} { lista_4}')"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/m1l0j05.py",
    "content": "\n# Asignación por valor: \n# Se copia el valor directamente. \n# Esto ocurre con tipos de datos inmutables como números, cadenas y tuplas. \n# Cambiar el valor de una variable no afecta a las demás.\n\n# Ejemplo\na = 10\nb = a  # a y b son independientes\nb = 20\nprint(a)  # a sigue siendo 10\n\n\n# Asignación por referencia: \n# Se comparte la referencia al objeto en la memoria. \n# Esto sucede con tipos de datos mutables como listas y diccionarios. \n# Modificar un objeto afecta a todas las variables que hacen referencia a él.\n\n#Ejemplo\nlist_1 = [1, 2, 3]\nlist_2 = list_1  # list_2 apunta al mismo objeto que list_1\nlist_2.append(4)\nprint(list_1)  # list_1 se ve afectada, [1, 2, 3, 4]\n\n# En resumen: \n# Con asignación por valor, cada variable tiene su propio valor independiente. \n# Con asignación por referencia, varias variables pueden apuntar al mismo objeto mutable en la memoria.\n\n\n# * DIFICULTAD EXTRA (opcional):\n# * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n# * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n# *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n# *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n# *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n# *   Comprueba también que se ha conservado el valor original en las primeras.\n\ndef exchange_values(value_1, value_2):\n    tmp = value_1\n    value_1 = value_2\n    value_2 = tmp\n    return value_1, value_2\n\n# Ejemplo de uso\noriginal_value_1 = 'Hola'\noriginal_value_2 = 'Mundo'\n\nnew_value_1, new_value_2 = exchange_values(original_value_1, original_value_2)\n\nprint(f\"Original Values: {original_value_1}, {original_value_2}\") # ---> Original Values: Hola, Mundo\nprint(f\"New Values: {new_value_1}, {new_value_2}\") # ---> New Values: Mundo, Hola\n\n\ndef exchange_references(list_1, list_2):\n    list_1[0], list_2[0] = list_2[0], list_1[0]\n    return list_1, list_2\n\n# Ejemplo de uso\noriginal_list_1 = ['Hola']\noriginal_list_2 = ['Python']\n\nnew_list_1, new_list_2 = exchange_references(original_list_1, original_list_2)\n\nprint(f\"Original Lists: [{original_list_1[0]}], [{original_list_2[0]}]\") # ---> Original Lists: [Python], [Hola]\nprint(f\"New Lists: [{new_list_1[0]}], [{new_list_2[0]}]\")  # ---> New Lists: [Python], [Hola]\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/majinka10.py",
    "content": "# Los tipos simples se pasan por valor: Enteros, flotantes, cadenas, lógicos...\n\nentero = 10\nflotante = 3.1415\nbooleano = True\ncadena = 'Hola'\n\ndef cambiar_valor_simple(dato):\n    if type(dato) == int:\n        dato = 20\n    elif type(dato) == float:\n        dato += 3\n    elif type(dato) == bool:\n        dato = False \n    elif type(dato) == str:\n        dato += 'Python!'\n\ncambiar_valor_simple(entero)\nprint(entero)\ncambiar_valor_simple(flotante)\nprint(flotante)\ncambiar_valor_simple(booleano)\nprint(booleano)\ncambiar_valor_simple(cadena)\nprint(cadena)\n\nprint('Caso en el que podemos modificar (con return)')\ndef por_dos(dato):\n    return dato * 2\n\nprint(por_dos(entero))\nprint(por_dos(flotante))\nprint(por_dos(cadena))\nprint(por_dos(booleano))\n\n\n#Los tipos compuestos se pasan por referencia: Listas, diccionarios, conjuntos...\n\nprint('\\nPara tipos de datos compuestos')\n\nlista = [2, 5, 6]\ndiccionario = {'Hola': 3, 'Python': 2, 'Adios': 6}\nconjunto = {3, 2, 1}\n\ndef cambiar_valor_compuesto(compuesto):\n    if type(compuesto) == dict:\n        for clave in diccionario.keys():\n            compuesto[clave] *= 2\n    elif type(compuesto) == set:\n        conjunto.add(5)\n    else:\n        for i, numero in enumerate(compuesto):\n            compuesto[i] *= numero\n\ncambiar_valor_compuesto(lista)\nprint(lista)\ncambiar_valor_compuesto(diccionario)\nprint(diccionario)\ncambiar_valor_compuesto(conjunto)\nprint(conjunto)\n\nprint('Caso en el que NO podemos modificar (pasando una copia a la función)')\nlista2 = [2, 5, 6]\ndiccionario2 = {'Hola': 3, 'Python': 2, 'Adios': 6}\nconjunto2 = {3, 2, 1}\ncambiar_valor_compuesto(lista2[:])\nprint(lista2)\ncambiar_valor_compuesto(diccionario2.copy())\nprint(diccionario2)\ncambiar_valor_compuesto(conjunto2.copy())\nprint(conjunto2)\n\n# Ejercicio EXTRA\nprint('\\nEjercicio EXTRA')\n\nparametro1 = 'Hola'\nparametro2 = 5\n\ndef intercambio_valor(parametro1, parametro2):\n    auxiliar = parametro1\n    parametro1 = parametro2\n    parametro2 = auxiliar\n    return parametro1, parametro2\n\nnot_parametro1, not_parametro2 = intercambio_valor(parametro1, parametro2) \n\nprint(f\"Variables originales: {parametro1, parametro2}.\")\nprint(f\"Variables nuevas: {not_parametro1, not_parametro2}.\")\n\nparametro3 = [9, 0, 3]\nparametro4 = {'Uno': 1, 'Dos': 2, 'Tres': 3}\n\ndef intercambio_referencia(parametro1, parametro2):\n    auxiliar = parametro1\n    parametro1 = parametro2\n    parametro2 = auxiliar\n    return parametro1, parametro2\n\nnot_parametro3, not_parametro4 = intercambio_referencia(parametro3, parametro4) \n\nprint(f\"Variables originales: {parametro3, parametro4}.\")\nprint(f\"Variables nuevas: {not_parametro3, not_parametro4}.\")"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/manjaitan.py",
    "content": "# asignar variales por valor\n\nvar1 = 10\nprint (var1)\n\n# asignar por referencia\n\nlist_refer_a = [1,2]\nlist_refer_b = list_refer_a\nlist_refer_b.append(3)\nprint (list_refer_a)\nprint (list_refer_b)\n\n # Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n # *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n\nvariable2 = [10,20,30]\n\ndef byRefer (entrada):\n    entrada.append (40)\n\nbyRefer(variable2)\nprint (variable2)\n\n\n\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/marcelosanchez166.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n#  *   su tipo de dato.\n#  * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y\n#  *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n#  * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n#  * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n#  *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n#  *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n#  *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n#  *   Comprueba también que se ha conservado el valor original en las primeras.\n#  */\n\n\"\"\"\nEn python las variables son referencias a objetos en memoria, por lo que no hay una distinción clara entre \"por valor\" y \"por referencia\" como en otros lenguajes.\nSin embargo, podemos simular este comportamiento con diferentes tipos de datos. como por ejemplo:\n- Variables por valor: son aquellas que contienen un valor primitivo, como enteros, floats, booleanos, etc. Cuando se asigna una variable por valor, se crea una copia del valor.\n- Variables por referencia: son aquellas que contienen una referencia a un objeto mutable, como listas,\ndiccionarios, sets, etc. Cuando se asigna una variable por referencia, se crea una referencia al objeto original,\nlo que significa que cualquier cambio en el objeto original se reflejará en la variable de referencia\n# Ejemplos de variables por valor y por referencia\n# Variables por valor\n# En Python, los tipos de datos inmutables como enteros, flotantes, cadenas de texto y tuplas se comportan como variables por valor.\n# Variables por referencia \n# En Python, los tipos de datos mutables como listas, diccionarios y sets se comportan como variables por referencia.\n\"\"\"\n\n# una variable por valor es un entero, float, booleano, etc. porque se crea una copia del valor\nvariable_por_valor_entero = 10\n# Modificando el valor de la variable por valor, esto no afecta a la variable original\nvariable_por_valor_entero = 20\nvariable_por_valor_string = \"Hola\"  # Variable por valor de tipo string\nvariable_por_valor_string = \"Mundo\"  # Modificando el valor de la variable\nvariable_por_valor_float = 3.14  # Variable por valor de tipo float\nvariable_por_valor_float = 2.71  # Modificando el valor de la variable por valor\nvariable_por_valor_booleano = True  # Variable por valor de tipo booleano\nvariable_por_valor_booleano = False  # Modificando el valor de la variable por valor\nprint(\"Variable por valor:\", variable_por_valor_booleano)\nprint(\"Variable por valor:\", variable_por_valor_float)\nprint(\"Variable por valor:\", variable_por_valor_string)\nprint(\"Variable por valor:\", variable_por_valor_entero)\n\n\n# una variable por referencia es una lista, diccionario, set, etc. porque se puede modificar su contenido sin crear una nueva variable\nvariable_por_referencia = [1, 2, 3]\nvariable_por_referencia[0] = 100  # Modificando el contenido de la lista por referencia\nprint(\"Variable por referencia:\", variable_por_referencia)\nvariable_por_referencia.append(4)  # Añadiendo un nuevo elemento a la lista por referencia\nprint(\"Variable por referencia:\", variable_por_referencia)\n\n\nvariable_por_referencia = {\"clave\": \"valor\"}  # Variable por referencia de tipo diccionario\nprint(\"Variable por referencia:\", variable_por_referencia)\n# Modificando el contenido del diccionario por referencia\n# Modificando el contenido del diccionario por referencia\nvariable_por_referencia[\"clave\"] = \"nuevo valor\"\nprint(\"Variable por referencia:\", variable_por_referencia)\n\n\nvariable_por_referencia = {1, 2, 3}  # Variable por referencia de tipo set\nprint(\"Variable por referencia:\", variable_por_referencia)\nvariable_por_referencia.add(4)  # Añadiendo un nuevo elemento al set por referencia\nprint(\"Variable por referencia:\", variable_por_referencia)\n# Modificando el contenido del set por referencia\nvariable_por_referencia = {5, 6, 7}  # Modificando el contenido del set por referencia\n# Imprimiendo el contenido de la variable por referencia\nprint(\"Variable por referencia:\", variable_por_referencia)\n\nvariable_por_referencia = (1, 2, 3)  # Variable por referencia de tipo tupla\nprint(\"Variable por referencia:\", variable_por_referencia)\n# Tuplas son inmutables, no se pueden modificar, pero se puede crear una nueva tupla\nvariable_por_referencia = (4, 5, 6)  # Creando una nueva tupla por referencia\nprint(\"Variable por referencia:\", variable_por_referencia)\n\n# ejemplo de función que recibe parámetros por valor y por referencia\n\nvariable_por_valor1 = 10  # Variable por valor\nvariable_por_referencia1 = [1, 2, 3]  # Variable por referencia\n# funcion que recibe parámetros por valor\ndef funcion_por_valor(param1, param2):\n    param1 = 100  # Modificando el valor del parámetro por valor\n    param2.append(4)  # Modificando el contenido del parámetro por referencia\n    return param1, param2\n# enviando parámetros a la función\nresultado_valor, resultado_referencia = funcion_por_valor(\n    variable_por_valor1, variable_por_referencia1)\nprint(\"Resultado por valor:\", resultado_valor)  # Imprime el valor modificado por valor\nprint(\"Resultado por referencia:\", resultado_referencia)  # Imprime el contenido modificado por\n\n\nvariable_ref = [1, 2, 3]  # Variable por referencia\nvariable_valor = 10  # Variable por valor\n# función por referencia\ndef funcion_por_referencia(param1, param2):\n    param1 = 200  # Modificando el valor del parámetro por valor\n    param2[0] = 300  # Modificando el contenido del parámetro por referencia\n    return param1, param2\n# enviando parámetros a la función por referencia\nresultado_valor_ref, resultado_referencia_ref = funcion_por_referencia(variable_valor, variable_ref)\nprint(\"Resultado por valor:\", resultado_valor_ref)  # Imprime el valor modificado por valor\nprint(\"Resultado por referencia:\", resultado_referencia_ref)  # Imprime el contenido modificado\n\n\n# dificultad extra\n# funcion que recibe dos parámetros (cada uno) definidos como variables anteriormente.\nvarible1 = 10\nvarible2 = 20\ndef intercambiar_valores_por_valor(param1, param2):\n    temp = param1\n    param1 = param2\n    param2 = temp\n    return param1, param2\nprint(\"Valores originales por valor:\", varible1, varible2)\nresultado1, resultado2 = intercambiar_valores_por_valor(varible1, varible2)\nprint(\"Valores después de intercambiar por valor:\", resultado1, resultado2)\n\n\nvar1 = [10]\nvar2 = [20]\ndef intercambiar_valores_por_referencia(param1, param2):\n    temp = param1[0]\n    param1[0] = param2[0]\n    param2[0] = temp\n    return param1, param2\nprint(\"Valores originales por referencia:\", var1[0], var2[0])\nresultado1_ref, resultado2_ref = intercambiar_valores_por_referencia(var1, var2)\nprint(\"Valores después de intercambiar por referencia:\", resultado1_ref[0], resultado2_ref[0])\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/mariovelascodev.py",
    "content": "\n#Paso por valor\nnum1 = 6\nnum2 = num1 #En la variable num2 se crea una copia del valor de la variable num1\nnum2 *= 5 #Modificamos solo el valor de la variable num2\nprint(num1)\nprint(num2)\n\n#Paso por referencia\nlista1 = [23, 42, 56]\nlista2 = lista1 #En la variable lista2 se comparte la misma referencia de memoria del objeto de lista1\nlista2.pop() #Al eliminar un valor de lista2 tambien se borra de lista1 ya que tienen la misma referencia de memoria\nprint(lista1)\nprint(lista2)\n\n\n#Ejemplos de funciones con variables\nnumero = 12\nnumero_flotante = 3.8\ncadena = \"Hola Mundo\"\nlista = [2, 5, \"texto\"]\nconjunto = set([5, 6, 7, 8])\ndiccionario = {\n    \"id\": 1,\n    \"nombre\": \"Mario\",\n    \"alias\": \"mariovelascodev\"\n}\n\ndef entrada(arg):\n    arg = \"¡Python mola!\"\n    print(f\"Valor de la variable dentro de la función: {arg}\")\n\ndef entrada1(arg):\n    arg.pop()\n    print(f\"Valor de la variable dentro de la función: {arg}\")\n\ndef entrada2(arg):\n    arg.popitem()\n    print(f\"Valor de la variable dentro de la función: {arg}\")    \n\nprint(\"----PASO POR VALOR----\\n\")\nprint(\"El paso por valor crea una copia local de la variable, \\nlo que implica que cualquier modificación sobre la misma\\nno tenga efecto sobre la original.\\n\")\nprint(f\"Valor de la variable \\\"numero\\\" fuera de la función: {numero}\")\nentrada(numero)\nprint(f\"Valor de la variable \\\"numero\\\" fuera de la función: {numero}\")\nprint(\"\\n\")\n\nprint(f\"Valor de la variable \\\"numero_flotante\\\" fuera de la función: {numero_flotante}\")\nentrada(numero_flotante)\nprint(f\"Valor de la variable \\\"numero_flotante\\\" fuera de la función: {numero_flotante}\")\nprint(\"\\n\")\n\nprint(f\"Valor de la variable \\\"cadena\\\" fuera de la función: {cadena}\")\nentrada(cadena)\nprint(f\"Valor de la variable \\\"cadena\\\" fuera de la función: {cadena}\")\n\n\nprint(\"\\n----PASO POR REFERENCIA----\\n\")\nprint(\"El paso por referencia, actua directamente sobre la variable pasada,\\npor lo que las modificaciones afectarán a la variable original.\\n\")\nprint(f\"Valor de la variable \\\"lista\\\" fuera de la función: {lista}\")\nentrada1(lista)\nprint(f\"Valor de la variable \\\"lista\\\" fuera de la función: {lista}\")\nprint(\"\\n\")\n\nprint(f\"Valor de la variable \\\"conjunto\\\" fuera de la función: {conjunto}\")\nentrada1(conjunto)\nprint(f\"Valor de la variable \\\"conjunto\\\" fuera de la función: {conjunto}\")\nprint(\"\\n\")\n\nprint(f\"Valor de la variable \\\"diccionario\\\" fuera de la función: {diccionario}\")\nentrada2(diccionario)\nprint(f\"Valor de la variable \\\"diccionario\\\" fuera de la función: {diccionario}\")\nprint(\"\\n\")\n\nprint(\"\\n----EXTRA----\\n\")\n\na = 5\nb = \"Python\"\n\ndef intercambio_valor(param1, param2):\n    #Intercambio el valor de las dos variables entre ellas, creando una variable para almacenar el valor del param1 para poder darselo a param2\n    valor_temporal = param1\n    param1 = param2\n    param2 = valor_temporal\n\n    #Retorno el valor de los parámetros\n    return param1, param2\n\n#Añadimos a las nuevas variables el valor retornado de la función\nnuevo_a, nuevo_b = intercambio_valor(a, b)\n\nprint(\"PASO POR VALOR\\n\")\nprint(f\"Valor de la variable a: {a}\")\nprint(f\"Valor de la variable b: {b}\")\nprint(f\"Valor de la variable nuevo_a: {nuevo_a}\")\nprint(f\"Valor de la variable nuevo_b: {nuevo_b}\")\n\n#Comprobamos que no modificamos las variables originales\nnuevo_a = \"JS\"\nnuevo_b += 8\nprint(f\"Valor de la variable nuevo_a: {nuevo_a}\")\nprint(f\"Valor de la variable nuevo_b: {nuevo_b}\")\nprint(f\"Valor de la variable a: {a}\")\nprint(f\"Valor de la variable b: {b}\")\n\nlista_numeros = [1, 30, 256]\nlista_string = [\"Python\", \"Hola mundo\", \"Mario\"]\ndef intercambio_referencia(param1, param2):\n    #Creamos una copia de las lista de los dos parámetros, para no afectar a las listas originales\n    copia_param1 = param1.copy()\n    copia_param2 = param2.copy()\n    #Intercambio el valor de los parámetros con las copias de lista\n    param1 = copia_param2\n    param2 = copia_param1\n\n    #Retorno el valor de los parámetros\n    return param1, param2\n\n#Añadimos a las nuevas variables el valor retornado de la función\nnueva_lista_numeros, nueva_lista_string = intercambio_referencia(lista_numeros, lista_string)\n\n#Comprobamos que no modificamos las variables originales\nnueva_lista_numeros.append(255)\nnueva_lista_string.pop()\n\nprint(\"\\nPASO POR REFERENCIA\\n\")\nprint(f\"Valor de la variable lista_numeros: {lista_numeros}\")\nprint(f\"Valor de la variable lista_string: {lista_string}\")\nprint(f\"Valor de la variable nueva_lista_numeros: {nueva_lista_numeros}\")\nprint(f\"Valor de la variable nueva_lista_string: {nueva_lista_string}\")\nprint(f\"Valor de la variable lista_numeros: {lista_numeros}\")\nprint(f\"Valor de la variable lista_string: {lista_string}\")\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/maxiRica.py",
    "content": "\"\"\"\nEJERCICIO A REALIZAR\n\n Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n\"\"\"\n\n\nimport os\nimport textwrap\n\ndef limpiar(): #creamos la función para limpiar la pantalla para poder aplicarla las veces que necesitemos sin repetir código\n    while True:\n\n        pregunta=input(\"quieres que limpie la pantalla? (si - no): \")\n        if pregunta==\"si\":\n        \n            if os.name==\"posix\":\n                os.system(\"clear\")\n                break\n            else:\n                os.system(\"cls\")\n                break\n        elif pregunta==\"no\":\n            break\n\n# FUNCIONES CON VARIABLES QUE SE LES PASAN \"POR VALOR\"\nlimpiar()\n\nprint(\"VAMOS A TRABAJAR LA ASIGNACIÓN DE VARIABLES QUE SE PASAN POR VALOR EN FUNCIONES\\n\")\n\nprint(textwrap.fill(\"En python siempre se hace referencia a un objeto, pero estos objetos pueden ser mutables o inmutables.\" \n              \"Si pasamos una variable inmutable estamos pasando un valor ya que su modificación dentro de la función no modificará la variable.\" \n              \"Si lo pasamos como referencia ha de ser una variable mutable\\n\",80))\n\ndef multiplicacion3(valor):\n    a=valor\n    print(f\"el valor dentro de la función al multiplicarlo por 3 es {a*3}\\n\")\n\nprint(\"\\nPASAMOS UN VALOR (UN ENTERO) COMO PARÁMETRO DE UNA FUNCIÓN\\n\")\nvalor=input(\"pasame un entero: \")\nvalor=int(valor)\n\nprint(f\"antes de la función la variable tiene el valor {valor}\\n\")\nprint(textwrap.fill(\"Si pasamos un valor a la función multiplicacion3(valor), \"\n      \"nos dará un valor diferente al multiplicarlo por 3.\"\n      \"Como pasamos un entero de parámetro, la variable no se modificara al ser inmutable, crearemos un nuevo objeto con el nuevo valor.\",80))\nmultiplicacion3(valor)\n\n# FUNCIONES CON VARIABLES QUE SE PASAN COMO \"REFERENCIA\"\n\ndef multiplicaLista3(lista):\n    for i in range(len(lista)):\n        lista[i]=lista[i]*3\n\nprint(\"VAMOS A ASIGNACIÓN DE VARIABLES QUE SE PASAN POR REFERENCIA\\n\")\nprint(textwrap.fill(\"Ahora vamos a trabajar la referencia. Para ello creamos una variable\"\n                    \"que ha de ser del tipo mutable. Por ejemplo una lista. Así las modificaciones de esa lista\"\n                    \"haran referéncia a un mismo objeto que se modificará con el nuevo valor\\n\"))\nvalor=input(\"\\npasame una lista de valores separados por comas: \")\nlista=list(map(int,valor.split(\",\")))\nprint(f\"la lista de valores que has pasado es: {lista}\\n\")\nprint(\"Los pasamos como parámetro de una función multiplicaLista3(lista), y nos da: \\n\")\nmultiplicaLista3(lista)\nprint(f\"Ahora nos toca mirar si se han alterado los valores de la lista: {lista}, y observamos que si\\n\")\n\n\n# VAMOS A POR LA DIFICULTAD \nprint(\"\\nVAMOS A POR EL APARTADO DE DIFICULTAD\")\nlimpiar()\nprint(\"DIFICULTAD EXTRA (opcional): \" \n               \"* Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\\n\"\n               \"* - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\\n\"\n               \"*   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\\n\"\n               \"se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\\n\"\n               \"variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\\n\"\n               \"*   Comprueba también que se ha conservado el valor original en las primeras.\")\n\n# definimos la funciones del ejercicio del apartado del parámetro por referencia\n\ndef programa1(lista):\n    lista[0],lista[1]=lista[1],lista[0]\n    return lista\n\n\nprint(\"empezamos por referencia: \\n\")\nlista=input(\"pasame una lista de dos valores separados por comas: \")\nlista=lista.split(\",\")\nprint(f\"\\nLa lista es: {lista}\"+\"\\n\")\nprint(\"usamos una función para dar la vuelta a los valores: \\n\")\nprint(\"def programa1(lista):\\n\"\n      \"lista[0],lista[1]=lista[1],lista[0]\\n\"\n      \"return lista\\n\")\nprint(\"imprimimos el return de la ejecución de la función programa1(lista): \" + str(programa1(lista)))\nprint(f\"ahora el valor de la lista original es: {lista}\\n\\n\")\n\n# definimos la funciones del ejercicio del apartado del parámetro por valor\n\ndef programa2(tupla):\n    nueva_tupla=(tupla[1],tupla[0])\n    return nueva_tupla\n\nprint(\"Ahora vamos a crear la función de los parámetros por valor, para eso usamos una tupla\\n\")\nprint(\"def programa2(tupla)\\n\" \n      \"tupla[0],tupla[1]=tupla[0],tupla[1]\\n\"\n      \"return tupla\\n\")\ntupla1=input(\"pasame una lista de dos valores separados por comas: \\n\")\ntupla1=tuple(tupla1.split(\",\"))\nprint(f\"la tupla es: {tupla1}\\n\")\nprint(\"pasamos como parametro de la función la tupla\\n\")\nprint(\"el resultado es: \"+str(programa2(tupla1)))\nprint(f\"el valor original de la tupla es: {tupla1}\"+\"\\n\")\nprint(\"el valor original de la tupla no se puede modificar\")"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/mensius87.py",
    "content": "\"\"\"\nEJERCICIO:\n- Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n  su tipo de dato.\n- Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n  \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n(Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n\nDIFICULTAD EXTRA (opcional):\nCrea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n- Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n  Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n  se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n  variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n  Comprueba también que se ha conservado el valor original en las primeras.\n\"\"\"\n\n# ------------------------------------------------------------------------------------------------------\n\n\"\"\"\nPaso por Valor (números, cadenas y tuplas):\nEn este enfoque, al llamar a una función, se pasa una copia del valor de la variable como argumento.\nCualquier modificación realizada dentro de la función no afectará a la variable original fuera de ella.\n\nPaso por Referencia (listas, diccionarios y sets):\nEn este enfoque, al llamar a una función, se pasa la referencia a la variable original como argumento.\nEsto significa que cualquier modificación realizada dentro de la función afectará directamente a la variable original\nfuera de la función. Es común en tipos de datos mutables como listas, diccionarios y conjuntos.\n\"\"\"\n\n# Asignación de variables por valor\nnumero_1 = 23\nnumero_2 = 3.14\ncolor = \"rojo\"\nagenda = (1, \"hola\", numero_2)\n\n\n# Asignación de variables por referencia\ncolores = [\"rojo\", \"verde\", \"azul\"]\ningles_espanol = {\n    \"hello\": \"hola\",\n    \"red\": \"rojo\",\n    \"green\": \"verde\",\n    \"blue\": \"azul\"\n    }\n\nmi_set = {1, 2, 3, 4, 5}\n\nprint()\n\n\n# Ejemplos de funciones con variables de paso por valor\ndef suma(num_1, num_2):\n    numero_1 = num_1 + num_2\n    print(f\"El valor de 'numero_1' es {num_1}+{num_2} es {num_1 + num_2}\")\n\n\ndef datos_agenda(datos):\n    print(agenda)\n\n\n# Ejemplos de funciones con variables de paso por referencia\ndef imprimir_vocabulario(vocabulario):\n    for clave, valor in ingles_espanol.items():\n        print(f\"{clave}: {valor}\")\n\n\n\n\n\nsuma(numero_1, numero_2)\nprint()\ndatos_agenda(agenda)\nprint()\nimprimir_vocabulario(ingles_espanol)\n\n\nprint()\nprint(\"::::::::::::::::::::::::::::::::::::: EXTRA :::::::::::::::::::::::::::::::::::::\")\nprint()\n\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/mhayhem.py",
    "content": "# - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n#   su tipo de dato.\n# - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n#   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n# (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n\n# por valor son los datos inmutables tales como los int, float, bool y str\nnum = 15\nprint(f\"La variable 'num' tiene el valor: {num}.\")\nprint(\"Háremos una copia de la variable 'num' en 'num2'.\")\nnum2 = num\nprint(\"Y ahora cambiaremos el valor de 'num2' a 20.\")\nnum2 = 20\nprint(f\"Ahora la variable 'num2' tiene de valor: {num2}, pero la variable 'num' sigur siendio: {num}.\")\n\n# por referencia suelen ser laas estructuras de datos list, dict, set\narray = [12, 3, 45, 99]\nprint(f\"La lista tiene estos valores: {array}.\")\nprint(\"Ahora háremos una copia de la lista en 'array2'.\")\narray2 = array\nprint(\"Ahora vamos a añadir el numero '999' a 'array2'.\")\narray2.append(999)\nprint(f\"Ahora los valores de 'array2' són: {array2} pero al apuntar a la misma referencia en la memoria\\n\"\n      f\"veremos que 'array' también contiene el número '999'. 'array': {array}.\")\n\n# por valor y por referencia despúes de pasar como argumento a una función\n\n# por valor\nnum = 10\n\ndef change_value(int):\n    int = 20\n    print(f\"La función le da el valor de: {int}\")\nchange_value(num)\nprint(f\"pero en el scope global es: {num}\")\n \n# por referencia\narray = [1, 3, 5, 7]\n\ndef add_to_array(list=list):\n    list.append(9)\n    print(f\"La función añadio el '9' al 'array': {list}\")\nadd_to_array(array)\nprint(f\"Pero el 'array' en el scope global también contiene el '9', 'array': {array}\")\n\n\n\n# DIFICULTAD EXTRA (opcional):\n# Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n# - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n#   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n#   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n#   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n#   Comprueba también que se ha conservado el valor original en las primeras.\n\nmy_int = 19\nmy_str = \"Python\"\n\ndef per_value(arg, arg_2):\n    arg, arg_2 = arg_2, arg\n    return arg, arg_2\n\nmod_value, mod_value2 = per_value(my_int, my_str)\n\nprint(f\"valor de my_int: {my_int}, valor de modificado : {mod_value}.\")\nprint(f\"valor de my_str: {my_str}, valor de modificado 2: {mod_value2}.\")\n\n\narray = [23, 45, 23, 45]\ncollection = {23, 45, 55}\ndef per_reference(arg, arg_2):\n    arg_2, arg = arg, arg_2\n    return arg, arg_2\n\nmod_value3, mod_valu4 = per_reference(array, collection)\n\nprint(f\"valor collection: {collection}, valor de modificado 3: {mod_value3}.\")\nprint(f\"Valor array: {array}, modificado 4: {mod_valu4}\")\n\n\n\n\n\nmy_dict = {\"name\": \"Dany\", \"age\": 41}\nmy_dict_2 = my_dict\n\nprint(my_dict_2)\nmy_dict_2[\"age\"] = 42\nprint(my_dict_2)\nprint(my_dict)"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/miguelex.py",
    "content": "entero = 10\ncadena = \"Hola Mundo\"\n\n# Vamos a crear dos variables por valor que tengan los valores de las variables anteriores\n\nentero2 = entero\ncadena2 = cadena\n\nprint(f'El valor del entero original es {entero} y el valor del entero por valor es {entero2}')\nprint(f'La cadena original es \"{cadena}\" y la cadena por valor es \"{cadena2}\"')\n\n# Vamos a cambiar ahora el valor de las variables originales y vamos a mostrar por pantalla las variables originales y por valor\nentero = 20;\ncadena = \"Adios Mundo\"\n\nprint(f'El valor del entero original es {entero} y el valor del entero por valor es {entero2}')\nprint(f'La cadena original es \"{cadena}\" y la cadena por valor es \"{cadena2}\"')\n\n# Variables por referencia\n\nlista = [1, 2, 3, 4, 5]\nlista2 = lista\n\nprint(f'El valor de la lista original es {lista} y el valor de la lista por referencia es {lista2}')\n\nlista[0] = 10\nlista[1] = 20\nlista[2] = 30\n\nprint(f'El valor de la lista original es {lista} y el valor de la lista por referencia es {lista2}')\n\n# Ejemplo de funcion con paso por valor\n\ndef duplicar_valor(numero):\n    numero = numero * 2\n    return numero\n\nnumero = 10\nprint(f'El valor original del numero es {numero}')\nnumero = duplicar_valor(numero)\nprint(f'El valor del numero despues de duplicarlo es {numero}')\n\n# Ejemplo de funcion con paso por referencia\n\ndef duplicar_valores(lista):\n    for i in range(len(lista)):\n        lista[i] = lista[i] * 2\n    return lista\n\nlista = [1, 2, 3, 4, 5]\nprint(f'El valor de la lista original es {lista}')\nlista = duplicar_valores(lista)\nprint(f'El valor de la lista despues de duplicar sus valores es {lista}')\n\n# Extra\n\ndef byValor(a, b):\n    a, b = b, a\n    return a, b\n\nx = 10\ny = 20\n\nnuevo_x, nuevo_y = byValor(x, y)\n\nprint(f\"Valores originales: x = {x}, y = {y}\")\nprint(f\"Nuevos valores: x = {nuevo_x}, y = {nuevo_y}\")\n\ndef byReference(lista):\n    lista[0], lista[1] = lista[1], lista[0]\n    return lista\n\nlista = [10, 20]\nprint(f\"Valores originales (Antes de llamada a función): lista = {lista}\")\nnueva_lista = byReference(lista)\n\nprint(f\"Valores originales (Despues de llamada a función): lista = {lista}\")\nprint(f\"Nuevos valores (retorno de la función): lista = {nueva_lista}\")\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/mikelm2020.py",
    "content": "# Asignación por valor\nnumber: int = 10\nsecond_number = number\nprint(f\"La variable original number vale {number}\")\nprint(f\"La variable por valor second_number vale {second_number}\")\n\n# Ahora le incrementamos 1 a second_number\nsecond_number += 1\nprint(f\"El valor de second_number ahoora es {second_number}\")\nprint(f\"y la variable original number vale {number}\")\n\n\n# Asignación por referencia\nnumber_list = [1, 2, 3, 4, 5]\nsecond_number_list = number_list\nprint(f\"La lista original number_list es: {number_list}\")\nprint(f\"La segunda lista por referencia second_number_list es: {second_number_list}\")\n# Agregaamos un elmento a la segunda lista\nsecond_number_list.append(6)\n# Ahora revisamos ambas listas\nprint(\"Ahora revisamos ambas listas\")\nprint(f\"La lista original number_list es: {number_list}\")\nprint(f\"La segunda lista por referencia second_number_list es: {second_number_list}\")\n\n\ndef per_value(number: int):\n    print(f\"El valor del parametro original es: {number}\")\n    number = 15\n    print(\"Modificamos el parametro original asignando 15\")\n    print(f\"El valor modificado del parametro original ahora es: {number}\")\n\n\ndef per_reference(list_numbers: list):\n    print(f\"El valor del parametro original es: {list_numbers}\")\n    list_numbers.append(15)\n    print(\"Modificamos el parametro original agregando 15 a la lista\")\n    print(f\"El valor modificado del parametro original ahora es: {list_numbers}\")\n    print(\"Ahora creamos una nueva lista por referecia\")\n    other_list_numbers = list_numbers\n    other_list_numbers.append(16)\n    print(\"Agregamos el elmeento 16 a la nueva lista y vemos las 2 listas\")\n    print(f\"El valor del parametro original es: {list_numbers}\")\n    print(f\"El valor de la nueva lista es: {other_list_numbers}\")\n\n\n# Extra\ndef parameters_per_value(number_one: int, number_two: int) -> tuple:\n    temporal_number = number_two\n    number_two = number_one\n    number_one = temporal_number\n\n    return number_one, number_two\n\n\ndef parameters_per_reference(list_one: list, list_two: list) -> tuple:\n    temporal_list = list_two\n    list_two = list_one\n    list_one = temporal_list\n\n    return list_one, list_two\n\n\nif __name__ == \"__main__\":\n    per_value(12)\n    per_reference([10, 11, 12, 13, 14])\n    number = 16\n    other_number = 12\n    number_x, number_y = parameters_per_value(number, other_number)\n    print(\"parametros por vaor\")\n    print(f\"Los argumentos originales son: {number}, {other_number}\")\n    print(f\"Las variables son: {number_x}, {number_y}\")\n    one_list = [16, 17, 18, 19, 20]\n    other_list = [12, 13, 14, 15]\n    list_x, list_y = parameters_per_reference(one_list, other_list)\n    print(\"Parametros por referencia\")\n    print(f\"Los argumentos originales son: {one_list}, {other_list}\")\n    print(f\"Las variables son: {list_x}, {list_y}\")\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/monicavaquerano.py",
    "content": "# 05 VALOR Y REFERENCIA\n# Mónica Vaquerano\n# https://monicavaquerano.dev\n\n\"\"\"\nEJERCICIO:\nMuestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\nsu tipo de dato.\n\"\"\"\n# La asignación de variables \"por valor\" y \"por referencia\" es un concepto importante\n# en la programación y varía según el lenguaje de programación que estés utilizando.\n\n# Asignación por Valor (Assignment by Value):\n# Cuando se asigna una variable por valor, se crea una copia independiente del\n# valor original. Esto significa que cualquier modificación realizada en la copia no\n# afectará al valor original y viceversa.\nprint(\"- Asignación por Valor (Assignment by Value):\")\nnumb = 1\nstr = \"hello\"\nboolean = True\n\n# Ejemplo de asignación\nnumb2 = numb\nstr2 = str\nboolean2 = boolean\n\n# Modificamos, y\nnumb = 2\nstr = \"bye\"\nboolean = False\n\n# los valores no cambian\nprint(numb2, str2, boolean2)  # Output: 1 hello True\nprint()\n\n# Asignación por Referencia (Assignment by Reference):\n# Cuando se asigna una variable por referencia, en lugar de copiar el valor, se asigna\n# una referencia al mismo objeto en la memoria. Esto significa que cualquier modificación\n# realizada en una variable afectará a todas las variables que hacen referencia al mismo objeto.\nprint(\"- Asignación por Referencia (Assignment by Reference):\")\n# Ejemplo de asignación por referencia en listas\nlista1 = [1, 2, 3]\nlista2 = lista1  # Se asigna una referencia a la misma lista\n\n# Modificamos lista2, y lista1 también cambia\nlista2.append(4)\n\nprint(lista1, lista2)  # Output: [1, 2, 3, 4] [1, 2, 3, 4]\nprint()\n# Es importante tener en cuenta que en Python, las asignaciones de variables generalmente se\n# realizan por referencia, pero hay algunas excepciones, como números, cadenas y tuplas, que\n# se asignan por valor. Sin embargo, el comportamiento puede variar según el tipo de datos y\n# el contexto de la asignación\n\n\"\"\"\nMuestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n\"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n(Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n\"\"\"\n# Paso por valor (Pass by value):\n# En Python, los tipos de datos simples como enteros, flotantes y cadenas se pasan por valor.\nprint(\"- Paso por valor (Pass by value):\")\n\n\ndef modify_value(x):\n    x = x + 10\n    print(\"Inside the function:\", x)\n\n\n# Variable original\na = 5\nprint(\"Before function call:\", a)\n\n# Llamada a la función\nmodify_value(a)\n\n# Valor de la variable original no cambia\nprint(\"After function call:\", a)\nprint(\n    \"En este ejemplo, la variable a se pasa a la función modify_value por valor.\\nDentro de la función, se modifica el valor de x, pero esto no afecta a la variable original a.\"\n)\nprint()\n# Paso por Referencia (Pass by Reference):\n# Las listas y otros tipos de datos compuestos se pasan por referencia en Python.\nprint(\"- Paso por valor (Pass by value):\")\n\n\ndef modify_list(lst):\n    lst.append(4)\n    print(\"Inside the function:\", lst)\n\n\n# Lista original\nmy_list = [1, 2, 3]\nprint(\"Before function call:\", my_list)\n\n# Llamada a la función\nmodify_list(my_list)\n\n# La lista original se modifica\nprint(\"After function call:\", my_list)\n\nprint(\n    \"En este caso, la lista my_list se pasa a la función modify_list por referencia.\\nDentro de la función, se agrega un elemento a la lista original my_list, por lo que la lista original se modifica incluso fuera de la función. Esto demuestra el paso por referencia.\"\n)\nprint(\"\\nDIFICULTAD EXTRA (opcional):\\n\")\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n\"\"\"\n\n\ndef intercambioPorValor(param1: int, param2: int) -> tuple:\n    temp = param1\n    param1 = param2\n    param2 = temp\n    print(f\"Originales durante el intercambio: x = {param1}, y = {param2}\")\n    return param1, param2\n\n\ndef intercambioPorReferencia(param1: list, param2: list) -> tuple:\n    temp = param1\n    param1 = param2\n    param2 = temp\n    print(f\"Originales durante el intercambio: a = {param1}, b = {param2}\")\n    return param1, param2\n\n\nprint(\"Intercambio por Valor:\")\nx, y = 5, 10\nprint(f\"Originales antes del intercambio: x = {x}, y = {y}\")\nx2, y2 = intercambioPorValor(x, y)\nprint(f\"Originales después del intercambio: x = {x}, y = {y}\")\nprint(f\"Nuevas variables después del intercambio: x2 = {x2}, y2 = {y2}\")\n\nprint(\"\\nIntercambio por Referencia:\")\na, b = [1, 2, 3], [4, 5, 6]\nprint(f\"Originales antes del intercambio: a = {a}, b = {b}\")\na2, b2 = intercambioPorReferencia(a, b)\nprint(f\"Originales después del intercambio: a = {a}, b = {b}\")\nprint(f\"Nuevas variables después del intercambio: a2 = {a2}, b = {b2}\")\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/mordevspt.py",
    "content": "\"\"\"\n- Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según su tipo de dato.\n\"\"\"\n\n'''\nEn Python, las variables no se asignan por valor ni por referencia en el sentido estricto. \nEn su lugar, Python utiliza un enfoque llamado “pasaje de objetos” o “pasaje de objetos por referencia”.\n'''\n\n# ASIGNACIÓN DE VARIABLES POR VALOR - VALORES PRIMITIVOS\n\n# Asignación de valor numérico\nprint(\"\\nAsignación de valor numérico\\n\")\nvalor1 = 10\nvalor2 = 33\nprint(valor1)\nprint(valor2)\nvalor2 = valor1\nvalor1 = 3 * 5\nprint(valor1)\nprint(valor2)\n\n# Asignación de cadena de texto\nprint(\"\\nAsignación de cadena de texto\\n\")\ncadena1 = \"Hola\"\ncadena2 = \"Python!\"\nprint(cadena1)\nprint(cadena2)\ncadena2 = cadena1\ncadena1 = \"Adios\"\nprint(cadena1)\nprint(cadena2)\n\n# Asignación de valores Booleanos\nprint(\"\\nAsignación de valores Booleanos\\n\")\nsemaforo_en_verde = False\nsenal_peatones = True\nprint(semaforo_en_verde)\nprint(senal_peatones)\nsemaforo_en_verde = senal_peatones\nsenal_peatones = False\nprint(semaforo_en_verde)\nprint(senal_peatones)\n\n# Asignación de valores flotante\nprint(\"\\nAsignación de valores flotante\\n\")\nPI = 3.14\nradio = 4.56\nprint(PI)\nprint(radio)\nPI = radio\nradio = 25.8\nprint(PI)\nprint(radio)\n\n# ASIGNACIÓN DE VARIABLES POR REFERENCIA - NO PRIMITIVOS\n# Heredan la posición de memoria\n\n# Listas\nprint(\"\\nListas\\n\")\nlista_compra = [\"fruta\", \"verdura\", \"carne\"]\nlista_embutidos = [\"jamon\", \"chorizo\", \"butifarra\"]\nprint(lista_compra)\nprint(lista_embutidos)\nlista_embutidos = lista_compra\nlista_embutidos.append(\"chistorra\")\nprint(lista_compra) # Imprime la modificación realizada posteriormente sobre al lista \"lista_embutidos\"\nprint(lista_embutidos)\n\n# Diccionario\nprint(\"\\nDiccionario\\n\")\ndict_dias_de_la_semana = {\n    1:\"Luneas\",\n    2:\"Martes\",\n    3:\"Miércoles\",\n    4:\"Jueves\",\n    5:\"Viernes\",\n    6:\"Sábado\",\n    7:\"Domingo\"\n}\ndict_meses_del_ano = {\n  1:\"Enero\",\n  2:\"Febrero\",\n  3:\"Marzo\",\n  4:\"Abril\",\n  5:\"Mayo\",\n  6:\"Junio\",\n  7:\"Julio\",\n  8:\"Agosto\",\n  9:\"Septiembre\",\n  10:\"Octubre\",\n  11:\"Noviembre\",\n  12:\"Diciembre\"\n}\nprint(dict_dias_de_la_semana)\nprint(dict_meses_del_ano)\ndict_meses_del_ano = dict_dias_de_la_semana\ndict_dias_de_la_semana[13] = \"Nuevo\"\nprint(dict_dias_de_la_semana)\nprint(dict_meses_del_ano) # Imprime la modificación realizada posteriormente sobre el diccionario \"dict_dias_de_la_semana\"\n\n# Sets\nprint(\"\\nSets\\n\")\nset_numeros_dado_6 = {1,2,3,4,5,6}\nset_numeros_dado_20 = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}\nprint(set_numeros_dado_6)\nprint(set_numeros_dado_20)\nset_numeros_dado_20 = set_numeros_dado_6\nset_numeros_dado_20.add(21)\nprint(set_numeros_dado_6)\nprint(set_numeros_dado_20) # Imprime la modificación realizada posteriormente sobre el set \"set_numeros_dado_6\"\n\n\"\"\"\n- Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n  \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n  (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n\"\"\"\nprint(\"\\nFUNCIONES\\n\")\n\n# POR VALOR\n\n# Asignación de valor numérico\nprint(\"\\nAsignación de valor numérico\\n\")\n\ndef modify_int(value):\n  value = 11\n  print(value)\n\nvalor3 = 33\nmodify_int(valor3)\nprint(valor3)\n\n# Asignación de cadena de texto\nprint(\"\\nAsignación de valor numérico\\n\")\n\ndef modify_string(chain):\n  chain = \"java\"\n  print(chain)\n  \ncadena3 = \"Hola, Python!\"\nmodify_string(cadena3)\nprint(cadena3)\n\n# Asignación de valores Booleanos\nprint(\"\\nAsignación de valores Booleanos\\n\")\n\ndef modify_booleano(bool):\n  bool = True\n  print(bool)\n\nletra_devuelta = True\nmodify_booleano(letra_devuelta)\nprint(letra_devuelta)\n\n# Asignación de valores flotante\nprint(\"\\nAsignación de valores flotante\\n\")\n\ndef modify_float(float):\n  float = 7.85\n  print(float)\n\ndiametro = 15.87\nmodify_float(diametro)\nprint(diametro)\n\n# POR REFERENCIA\n\n# Listas\nprint(\"\\nListas\\n\")\nlista_marcas = [\"samsung\", \"apple\"]\n\ndef modify_list(lst):\n  lst.append(\"chocolate\")\n  print(lst)\n\nmodify_list(lista_marcas)\nprint(lista_marcas)\n\n# Diccionario\nprint(\"\\nDiccionario\\n\")\n\ndef modify_dict(dict):\n  dict[3] = \"Laboral\"\n  print(dict)\n\ndict_sexo = {\n  1:\"Hombre\",\n  2:\"Mujer\"\n}\nmodify_dict(dict_sexo)\nprint(dict_sexo)\n\n# Set\nset_numero_meses = {1,2,3,4,5,6,7,8,9,10,11,12}\n\ndef modify_set(set):\n  set.add(13)\n  print(set)\n\nprint(\"\\nSet\\n\")\nmodify_set(set_numero_meses)\nprint(set_numero_meses)\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\nCrea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n- Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n  Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n  se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n  variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n  Comprueba también que se ha conservado el valor original en las primeras.\n\"\"\"\n\nprint(\"\\nEXTRA\\n\")\n\n# Program one\ndef transforming_values(value1, value2):\n  primer_valor = value1\n  value1 = value2\n  value2 = primer_valor\n  return value1, value2\n\n# Program two\ndef transforming_references(reference1, reference2):\n  primer_valor = reference1\n  reference1 = reference2\n  reference2 = primer_valor\n  return reference1, reference2\n\nprint(\"\\nPrimer programa\\n\")\n# Variables\nmi_value1 = 45\nmi_value2 = 4.5\n# Función por valor\na,b = transforming_values(mi_value1,mi_value2)\n# Imprimimos el resultado\nprint(f\"Valores pasados a la función: {mi_value1} y {mi_value2}:\")\nprint(f\"Primer valor devuelto: {a}\")\nprint(f\"Segundo valor devuelto: {b}\")\nprint(f\"Los valores originales: {mi_value1} y {mi_value2}:\")\n\nprint(\"\\nPrimer programa\\n\")\n# Variables\nmi_list1 = [1,2,3,4,5]\nmi_list2 = [6,7,8,9,10]\n# Función por referencia\nc,d = transforming_references(mi_list1,mi_list2)\nprint(f\"Valores pasados a la función: {mi_list1} y {mi_list2}:\")\nprint(f\"Primer valor devuelto: {c}\")\nprint(f\"Segundo valor devuelto: {d}\")\nprint(f\"Los valores originales: {mi_list1} y {mi_list2}:\")"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/mouredev.py",
    "content": "\"\"\"\nValor y referencia\n\"\"\"\n\n# Tipos de dato por valor\n\nmy_int_a = 10\nmy_int_b = my_int_a\nmy_int_b = 20\n# my_int_a = 30\nprint(my_int_a)\nprint(my_int_b)\n\n# Tipos de dato por referencia\n\nmy_list_a = [10, 20]\nmy_list_b = my_list_a\nmy_list_b.append(30)\nprint(my_list_a)\nprint(my_list_b)\n\n# Funciones con datos por valor\n\n\ndef my_int_func(my_int: int):\n    my_int = 20\n    print(my_int)\n\n\nmy_int_c = 10\nmy_int_func(my_int_c)\nprint(my_int_c)\n\n# Funciones con datos por referencia\n\n\ndef my_list_func(my_list: list):\n    my_list.append(30)\n\n    my_list_d = my_list\n    my_list_d.append(40)\n\n    print(my_list)\n    print(my_list_d)\n\n\nmy_list_c = [10, 20]\nmy_list_func(my_list_c)\nprint(my_list_c)\n\n\"\"\"\nExtra\n\"\"\"\n\n# Por valor\n\n\ndef value(value_a: int, value_b: int) -> tuple:\n    temp = value_a\n    value_a = value_b\n    value_b = temp\n    return value_a, value_b\n\n\nmy_int_d = 10\nmy_int_e = 20\nmy_int_f, my_int_g = value(my_int_d, my_int_e)\n\nprint(f\"{my_int_d}, {my_int_e}\")\nprint(f\"{my_int_f}, {my_int_g}\")\n\n# Por referencia\n\n\ndef ref(value_a: list, value_b: list) -> tuple:\n    temp = value_a\n    value_a = value_b\n    value_b = temp\n    return value_a, value_b\n\n\nmy_list_e = [10, 20]\nmy_list_f = [30, 40]\nmy_list_g, my_list_h = ref(my_list_e, my_list_f)\nprint(f\"{my_list_e}, {my_list_f}\")\nprint(f\"{my_list_g}, {my_list_h}\")\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/mrodara.py",
    "content": "'''\nEn Python, el paso de argumentos se hace por asignación de objetos y se puede considerar \nun modelo de \"paso por referencia\", pero con algunos matices:\n\nPara tipos inmutables (como int, float, str, tuple), el comportamiento se asemeja a un paso por valor \nporque no puedes modificar el contenido del objeto en sí, solo puedes reasignarlo.\nPara tipos mutables (como list, dict, set), se asemeja más a un paso por referencia, \nya que cualquier cambio en el objeto dentro de una función afectará el objeto original fuera de ella.\n'''\n\n# Ejemplo de paso por valor\na = 5\n\nprint(a)\n\nb = a\n\nb = 7\n\nprint(a)\nprint(b)\n\n# Ejemplo de paso por referencia\nmy_list = [1,2,3,4,5]\n\nprint(my_list)\n\nmy_list2 = my_list\n\nmy_list2[0] = 100\n\nprint(my_list) # El índice 0 de my_list se ve afectado por el cambio en el mismo índice en my_list2\n\n# Si queremos copiar listas u otros tipo de datos mutables tenemos usar el método copy() o recorrerlos y añadir los campos\n\nmy_list3 = my_list2.copy()\n\nprint(my_list3)\n\nmy_list2[0] = 1\n\nprint(my_list2)\nprint(my_list3)\n\n\n###############################  DIFICULTAD EXTRA   ###################################\n\n# Programa 1 - Paso por valor (int)\n\nnum1 = int(input('Introduce un valor para num1: '))\nnum2 = int(input('Introduce un valor para num2: '))\n\nprint(f'num1 vale: {num1} y num2 vale: {num2}')\n\nprint('Intercambio de valores')\ntemp = num1\nnum1 = num2\nnum2 = temp\n\nprint(f'Ahora num1 vale: {num1} y num2 vale: {num2}')\n\n# Programa 2 - Paso por referencia (list)\n\n# Vamos a generar dos listas con valores entre dos rangos\nlist1 = [i for i in range (1,11)]\nlist2 = [i for i in range (11,21)]\n\nprint(list1)\nprint(list2)\n\ndef paso_referencia(list1: list, list2: list) -> tuple:\n    temp = list1\n    list1 = list2\n    list2 = temp\n    \n    return list1, list2\n\nlist3, list4 = paso_referencia(list1=list1, list2=list2)\n\nprint(f'{list1}: {list3}')\nprint(f'{list2}: {list4}')\n\n\n###############################  FIN DIFICULTAD EXTRA   ###################################"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/mvidalb.py",
    "content": "'''\nValor y referencia\n'''\n# Tipos de dato por valor (ÚNICO): etneros, flotantes, cadenas, booleanos, ...\nmy_int_a = 10\nmy_int_b = my_int_a\nmy_int_b = 20\nmy_int_a = 30\nprint(my_int_a)\nprint(my_int_b)\n\n\n# Tipos de dato por referencia: listas, diccionarios, conjuntos, ...\nmy_list_a = [10, 20]\nmy_list_b = my_list_a\nmy_list_b.append(30)\nprint(my_list_a)    # [10, 20, 30]\nprint(my_list_b)    # [10, 20, 30]\n\n\n# Funciones con datos por valor\nmy_int_c = 10\n\ndef my_int_func(my_int: int):\n    my_int = 20\n    print(my_int)\n\nmy_int_func(my_int_c)\nprint(my_int_c)\n\n\n# Funciones con datos por referencia\n\ndef my_list_func(my_list: list):\n    my_list.append(30)\n    my_list_d = my_list   # my_list_c = my_list = my_list_d (PUNTERO)\n    my_list_d.append(40)\n    print(my_list)\n    print(my_list_d)      # [10, 20, 30, 40]\n\n\nmy_list_c = [10, 20]\nmy_list_func(my_list_c)   # [10, 20, 30]\nprint(my_list_c)          # [10, 20, 30]\n\n\n\n'''\nEjercicio extra\n'''\ndef valor(var1 : int, var2 : int):\n    temp = var1\n    var1 = var2\n    var2 = temp\n    return [var1, var2]\n\nvar1 = 1\nvar2 = 2\nprint(var1)\nprint(var2)\nvarmod_1, varmod_2 = valor(var1, var2)\nprint(varmod_1)\nprint(varmod_2)\n\n\ndef referencia(list1 : int, list2 : int):\n    temp = list1\n    list1 = list2\n    list2 = temp\n    return [list1, list2]\n\nlist1 = [10, 20]\nlist2 = [40, 50]\nprint(list1)\nprint(list2)\nlistmod_1, listmod_2 = referencia(list1, list2)\nprint(listmod_1)\nprint(listmod_2)\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/neslarra.py",
    "content": "\"\"\"\n EJERCICIO:\n - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n   su tipo de dato.\n - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n\n DIFICULTAD EXTRA (opcional):\n Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n   Comprueba también que se ha conservado el valor original en las primeras.\n\"\"\"\na = 'hola'\nb = a\nl = [1, 2, 3]\nm = l\nprint(f\"\"\"\nUna variable es un 'alias' a una dirección de memoria.\nCuando una o más variables tienen el mismo valor, entonces apuntan al mismo objeto. Por ejmeplo:\n  a = 'hola' /  b = a  /  c = 'hola' <= tanto a como b apuntan al mismo objeto =>\n  a paunta a {id(a)}  /  b apunta a {id(b)}  /  id(a) == id(b) = {id(a) == id(b)}\nOtro ejemplo:\n  l = [1, 2, 3]  /  m = l  /  n = [1, 2, 3] <= tanto l como m apuntan al mismo objeto =>\n  l paunta a {id(l)}  /  m apunta a {id(m)}  /  id(l) == id(m) = {id(l) == id(m)}\n\"\"\")\nb += \" mundo\"\nprint(f\"\"\"\nCuando un tipo primitivo se modifica, se destruye esa relación y se crea una nueva apuntando a un nueva dirección:\n  b += \" mundo\"      => id(b) = {id(b)} <= id(a) == id(b) = {id(a) == id(b)}\n\"\"\", end=\"\")\nb += \" mundo mio\"\nprint(f\"\"\"  b += \" mundo mio\"  => id(b) = {id(b)} <= id(a) == id(b) = {id(a) == id(b)} (notar que incluso b cambió respecto de su anterior valor)\"\"\")\nm.append(77)\nprint(f\"\"\"\nEn cambio cuando un tipo compuesto se modifica, mantiene la referencia a la posición de memoria original => todas las variables que la apuntaban verán la modificación:\n  m.append(77) => m es {m}  /  l es {l} (y no la tocamos) => id(l) = {id(l)}  /  id(m) = {id(m)}  /  id(l) == id(m) = {id(l) == id(m)} (notar que el id NO CAMBIÓ)\n\nLa misma característica se cumple cuando se llama a una función pasándole argumentos prmitivos o compuestos:\n\ndef paso_args(a: str, l: list):\n    print(\"Modifico a y l:\")\n    a += \" MODIFCADA DENTRO DE LA FUNCIÓN\"\n    l.append(\"MODIFCADA DENTRO DE LA FUNCIÓN\")\n    print(f\"Nuevos valores dentro de la función: a es \"\"\" + \"\"\"{a}'  (id: {id(a)}) /  l es {l} (id: {id(l)})\")\n\"\"\")\n\n\ndef paso_args(a: str, l: list):\n    print(\"Modifico a y l:\")\n    a += \" MODIFICADA DENTRO DE LA FUNCIÓN\"\n    l.append(\"MODIFICADA DENTRO DE LA FUNCIÓN\")\n    print(f\"Nuevos valores DENTRO de la función: a es '{a}'  (id: {id(a)}) /  l es {l} (id: {id(l)})\")\n\n\nprint(f\"Valores ANTES de la llamada a la función: a es '{a}'  (id: {id(a)}) /  l es {l} (id: {id(l)})\")\npaso_args(a, l)\nprint(f\"Valores DESPUÉS de la llamada a la función: a es '{a}'  (id: {id(a)}) /  l es {l} (id: {id(l)})\")\nprint(f\"\"\"\nLa variable primitiva 'a' se pasa por valor y su contenido solo existe dentro del ámbito en donde es utilizada (fuera O dentro de la función).\nLa variable compuesta 'l' se pasa por referencias y su contenido se mantiente no importa desde que ámbito se modifique.\nNotar como el id de la variable 'a' cambia dentro de la función pero fuera mantiene el valor, en cambio l mantiene el mismo id siempre.\n\nAún así se puede modificar una variable primitiva en un ámbito distinto si se la referencia como global:\n\ndef paso_args_2():\n    global a\n    print(\"Modifico a:\")\n    a += \" MODIFCADA DENTRO DE LA FUNCIÓN\"\n    print(f\"Nuevos valores dentro de la función: a es \"\"\" + \"\"\"{a}'  (id: {id(a)}))\n\"\"\")\n\n\ndef paso_args_2():\n    global a\n    print(\"Modifico a:\")\n    a += \" MODIFICADA DENTRO DE LA FUNCIÓN PERO GLOBAL\"\n    print(f\"Nuevos valores DENTRO de la función: a es '{a}'  (id: {id(a)})\")\n\n\nprint(f\"Valores ANTES de la llamada a la función: a es '{a}'  (id: {id(a)})\")\npaso_args_2()\nprint(f\"Valores DESPUÉS de la llamada a la función: a es '{a}'  (id: {id(a)})\")\n\nprint(f\"\"\"\nTambién podemos evitar modificar una variable compuesta original haciento un \"copy\" de la misma, lo cual genera un nuevo objto:\n\ndef paso_args_3(l: list) -> list:\n    print(\"Copio y modifico l:\")\n    ll = l.copy()\n    _ = ll.pop()\n    ll.append(\"ESTO NO DEBE VERSE REFLEJADO EN l\")\n    print(f\"Nuevos valores dentro de la función: l es \"\"\" + \"\"\"{l}'  (id: {id(l)})  /  ll es {ll} (id: {id(ll)}))\n    return ll\n\"\"\")\n\n\ndef paso_args_3(l: list) -> list:\n    print(\"Copio y modifico l:\")\n    ll = l.copy()\n    _ = ll.pop()\n    ll.append(\"ESTO NO DEBE VERSE REFLEJADO EN l\")\n    print(f\"Nuevos valores dentro de la función: l es {l}'  (id: {id(l)})  /  ll es {ll} (id: {id(ll)})\")\n    return ll\n\n\nprint(f\"Valores ANTES de la llamada a la función: l es '{l}'  (id: {id(l)})\")\nll = paso_args_3(l)\nprint(f\"Valores DESPUÉS de la llamada a la función: l es '{l}'  (id: {id(l)})  /  l es '{ll}'  (id: {id(ll)})\", end=\"\\n\\n\")\n\n# Complejidad extra\nprint(\"Compejidad extra caso 1:\\n\")\n\ncadena1 = \"Hola\"\ncadena2 = \"Mundo\"\n\n\ndef prog_por_valor(cadena1: str, cadena2: str):\n    cadena = cadena1\n    cadena1 = cadena2\n    cadena2 = cadena\n    return cadena1, cadena2\n\n\nprint(f\"Valores originales => cadena1: {cadena1}  /  cadena2: {cadena2}\")\ncadena1_, cadena2_ = prog_por_valor(cadena1, cadena2)\nprint(f\"Valores después de la llamada => cadena1: {cadena1}  /  cadena2: {cadena2}  /  cadena1_: {cadena1_}  /  cadena2_: {cadena2_}\")\n\nprint(\"\\n\\nCompejidad extra caso 2:\\n\")\n\nlista1 = [1, 2, 3]\nlista2 = [\"a\", \"b\"]\n\n\ndef prog_por_referencia(lista1: list, lista2: list):\n    lista = lista1.copy()\n    lista1 = lista2.copy()\n    lista2 = lista.copy()\n    return lista1, lista2\n\n\nprint(f\"Valores originales => lista1: {lista1}  /  lista2: {lista2}\")\nlista1_, lista2_ = prog_por_referencia(lista1, lista2)\nprint(f\"Valores después de la llamada => lista1: {lista1}  /  lista2: {lista2}  /  lista1_: {lista1_}  /  lista2_: {lista2_}\")\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/nlarrea.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n\"\"\"\n\n# Asignación por valor\n\nnumber_a = 11\nnumber_b = number_a\nprint(\"number_a:\", number_a)  # 11\nprint(\"number_b:\", number_b)  # 11\nnumber_b = 7\nprint(\"number_a:\", number_a)  # 11\nprint(\"number_b:\", number_b)  # 7\n\n# Asignación por referencia\n\nlist_a = [1, 2, 3, 4]\nlist_b = list_a\nprint(\"list_a:\", list_a)  # [1, 2, 3, 4]\nprint(\"list_b:\", list_b)  # [1, 2, 3, 4]\nlist_b.append(5)\nprint(\"list_a:\", list_a)  # [1, 2, 3, 4, 5]\nprint(\"list_b:\", list_b)  # [1, 2, 3, 4, 5]\n\n\n# Funciones por valor\n\n\ndef print_double(number: int) -> None:\n    number *= 2\n    print(number)\n\n\nmy_number = 2\nprint_double(my_number)  # 4\nprint(my_number)  # 2\n\n\n# Funciones por referencia\n\n\ndef print_append_number(arr: list, num: int) -> None:\n    arr.append(num)\n    print(\"List inside function:\", arr)\n\n\nmy_arr = [1, 2, 3, 4]\nprint_append_number(my_arr, 5)  # [1, 2, 3, 4, 5]\nprint(\"List outside function:\", my_arr)  # [1, 2, 3, 4, 5]\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n\"\"\"\n\n\ndef exchange_by_value(val_one: int, val_two: int) -> tuple[int]:\n    val_one, val_two = val_two, val_one\n    return val_one, val_two\n\n\nfirst_value = 11\nsecond_value = 7\nval_1, val_2 = exchange_by_value(first_value, second_value)\nprint(f\"\\n1.1. Before function: {first_value}    After function: {val_1}\")\n# 1.1. Before function: 11    After function: 7\nprint(f\"1.2. Before function: {second_value}     After function: {val_2}\")\n# 1.2. Before function: 7     After function: 11\n\n\ndef exchange_by_reference(arr_one: list, arr_two: list) -> tuple[list]:\n    arr_one, arr_two = [*arr_two], [*arr_one]\n    return arr_one, arr_two\n\n\nfirst_list = [1, 2, 3, 4]\nsecond_list = [9, 8, 7, 6]\nlist_1, list_2 = exchange_by_reference(first_list, second_list)\nprint(f\"\\n2.1 Before function: {first_list}    After function: {list_1}\")\n# 2.1 Before function: [1, 2, 3, 4]    After function: [9, 8, 7, 6]\nprint(f\"2.2 Before function: {second_list}    After function: {list_2}\")\n# 2.2 Before function: [9, 8, 7, 6]    After function: [1, 2, 3, 4]\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/oriaj3.py",
    "content": "\"\"\"\n05 - VALOR Y REFERENCIA\nAutor de la solución: Oriaj3\n\nTeoría:\nEn Python, las variables pueden ser asignadas por valor o por referencia, dependiendo del tipo de dato que almacenan.\n- Asignación por valor: Cada variable tiene su propio valor independiente. Esto sucede con tipos de datos primitivos como enteros, flotantes y cadenas.\n- Asignación por referencia: Se comparte la referencia al objeto en la memoria. Esto sucede con tipos de datos mutables como listas y diccionarios. Modificar un objeto afecta a todas las variables que hacen referencia a él.\n- Dentro de una clase, las variables de instancia se pasan por referencia, mientras que las variables de clase se pasan por valor.\n\"\"\"\n\n# EJERCICIOS \n# Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según su tipo de dato.\n# Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n# (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n\n\n# Asignación de variables \"por valor\" y \"por referencia\"\n# Por valor (tipos primitivos)\na = 5\nb = a  # a y b son independientes\nb = 10\nprint(a)  # a sigue siendo 5\nprint(b)  # b es 10\n\n# Por referencia (tipos compuestos)\nlist_1 = [1, 2, 3]\nlist_2 = list_1  # list_2 apunta al mismo objeto que list_1\nlist_2.append(4)\nprint(list_1)  # list_1 se ve afectada, [1, 2, 3, 4]\nprint(list_2)  # list_2 es [1, 2, 3, 4]\n\n# Funciones con parámetros \"por valor\" y \"por referencia\"\n# Por valor\ndef modify_value(value):\n    value = 10\n    return value\n\n# Ejemplo de uso\na = 5\nprint(modify_value(a))  # 10\nprint(a)  # 5\n\n# Por referencia\ndef modify_reference(list):\n    list.append(4)\n    return list\n\n# Ejemplo de uso\nlist_1 = [1, 2, 3]\nprint(modify_reference(list_1))  # [1, 2, 3, 4]\nprint(list_1)  # [1, 2, 3, 4]\n\n\n# DIFICULTAD EXTRA (opcional):\n# Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n# - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n#   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n#   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n#   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n#   Comprueba también que se ha conservado el valor original en las primeras.\n\n# Programa 1: Intercambio de parámetros por valor\ndef exchange_values(value_1, value_2):\n    tmp = value_1\n    value_1 = value_2\n    value_2 = tmp\n    return value_1, value_2\n\n# Ejemplo de uso\noriginal_value_1 = 'Hola'\noriginal_value_2 = 'Mundo'\n\nnew_value_1, new_value_2 = exchange_values(original_value_1, original_value_2)\n\nprint(f\"Original Values: {original_value_1}, {original_value_2}\")  # Original Values: Hola, Mundo\nprint(f\"New Values: {new_value_1}, {new_value_2}\")  # New Values: Mundo, Hola\n\n# Programa 2: Intercambio de parámetros por referencia\n# En este caso, se intercambiará el primer elemento de cada lista entre sí (siendo un seudo-puntero). \ndef exchange_references(puntero_1, puntero_2):\n    puntero_1[0], puntero_2[0] = puntero_2[0], puntero_1[0]\n    return puntero_1, puntero_2\n\n# Ejemplo de uso\noriginal_list_1 = ['Hola']\noriginal_list_2 = ['Python']\n\nnew_list_1, new_list_2 = exchange_references(original_list_1, original_list_2)\n\nprint(f\"Original Lists: [{original_list_1[0]}], [{original_list_2[0]}]\")  # Original Lists: [Python], [Hola]\nprint(f\"New Lists: [{new_list_1[0]}], [{new_list_2[0]}]\")  # New Lists: [Python], [Hola]\n\n# Programa 2: Intercambio de parámetros por referencia (con listas)\n# En este caso, se intercambiara todo el contenido de las listas entre sí.\ndef exchange_references(list_1, list_2):\n    if len(list_1) != len(list_2):\n        return None\n    for i in range(len(list_1)):\n        list_1[i], list_2[i] = list_2[i], list_1[i]\n    return list_1, list_2\n\n# Ejemplo de uso\noriginal_list_1 = ['Lista 1 Elemento 0', 'Lista 1 Elemento 1']\noriginal_list_2 = ['Lista 2 Elemento 0', 'Lista 2 Elemento 1']\n\nnew_list_1, new_list_2 = exchange_references(original_list_1, original_list_2)\n\nprint(f\"Original Lists: {original_list_1}, {original_list_2}\")  # Original Lists: ['Hola', 'Mundo'], ['Python', '3.10.11']\nprint(f\"New Lists: {new_list_1}, {new_list_2}\")  # New Lists: ['Python', '3.10.11'], ['Hola', 'Mundo']\n\n\n#Corrección del programa 2 después de ver directo Mouredev\n#Intercambio de parámetros por referencia (con listas)\n\ndef references(list_1: list, list_2: list) -> tuple:\n    list_1, list_2 = list_2, list_1\n    return list_1, list_2\n\n\n# Ejemplo de uso 1\noriginal_list_1 = ['Hola']\noriginal_list_2 = ['Python']\n\nmy_list_e = [10, 20]\nmy_list_f = [30, 40]\nmy_list_g, my_list_h = references(my_list_e, my_list_f)\nprint(f\"Original: {my_list_e}, {my_list_f}\")\nprint(f\"Modificadas: {my_list_g}, {my_list_h}\")\n\ndef references2(list_1: list, list_2: list) -> tuple:\n    temp = list_1\n    list_1 = list_2\n    list_2 = temp\n    return list_1, list_2\n\n# Ejemplo de uso 2\nmy_list_i = [10, 20]\nmy_list_j = [30, 40]\nmy_list_k, my_list_l = references2(my_list_i, my_list_j)\nprint(f\"Original: {my_list_i}, {my_list_j}\")\nprint(f\"Modificadas: {my_list_k}, {my_list_l}\")\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/pakiuh.py",
    "content": "'''EJERCICIO:\r\n - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\r\n   su tipo de dato.\r\n - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \r\n   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\r\n (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)'''\r\n\r\n#Asignación de variables \"por valor\". Cuando la nueva variable recibe una copia de la original\r\na = 5\r\nb = a\r\nb = 10 #cambiar b no ha supuesto cambiar a\r\nprint(a)\r\nprint(b)\r\n\r\n#Asignación de variables \"por referencia\"\r\nlist1 = [1,2,3,4]\r\nlist2 = list1\r\nlist2.append(3)\r\nprint(list1)\r\n\r\ndict1 = {\"Luke\": \"Jedi\",\r\n         \"Anakin\": \"Jedi\",\r\n         \"Conde Doku\": \"Sith\"}\r\n\r\ndict2 = dict1\r\n\r\ndict2[\"Anakin\"] = \"Sith\"\r\n\r\nprint(dict1)\r\n\r\n'''DIFICULTAD EXTRA (opcional):\r\n Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\r\n - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\r\n   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\r\n   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\r\n   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\r\n   Comprueba también que se ha conservado el valor original en las primeras.'''\r\n#Por Valor\r\nx = 3\r\ny = 9\r\n\r\ndef intercambio_variables(a,b):\r\n    return b,a\r\n\r\nnuevo_x, nuevo_y = intercambio_variables(x,y)\r\nprint(nuevo_x)\r\nprint(nuevo_y)\r\n\r\nlist1 = [1,3,5]\r\nlist2 = [2,4,6]\r\nnueva_list1, nueva_list2 = intercambio_variables(list1, list2)\r\nprint(nueva_list1)\r\nprint(nueva_list2)\r\n\r\n\r\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/pguillo02.py",
    "content": "#Variable por valor, independientes, simple copia de dato\nnumero = 20\nnumero2 = numero\n\nprint(numero)\nprint(numero2)\n\nnumero2 = numero2 + 12\n\nprint(numero)\nprint(numero2)\n\n#Variable por refencia, refencia al mismo espacio en memoria, referencia global para todas las variables de referencia\n\nlista = [1,2,3]\nlista2 = lista\n\nprint(lista)\nprint(lista2)\n\nlista2.append(4)\n\nprint(lista2)\nprint(lista)\n\n#Funciones con variables por valor, variable original no afectada\n\nnumero = 10\n\ndef valor(numero):\n    numero = numero + 1\n    print(numero)\n\nvalor(numero)\nprint(numero)\n\n\n#Funciones con variables referenciadas, variable original sí afectada\n\nlista = [1,2,3]\n\ndef referenciada(lista):\n    lista.append(4)\n    print(lista)\n\nprint(lista)\nreferenciada(lista)\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/pipngpop.py",
    "content": "\"\"\"\nVALOR Y REFERENCIA\n\"\"\"\n\n# Tipos de dato por valor\nmy_int_a = 10\nmy_int_b = my_int_a\nmy_int_b = 20\nmy_int_a = 15\nprint(my_int_a)\nprint(my_int_b)\n\n#Tipos de dato por referencia (todos los datos que no son primitivos)\n\nmy_list_a = [10,20]\nmy_list_b = my_list_a #ahora ambas listas tienen la misma dirección de memoria\nmy_list_b.append(30) #le añado un número\nprint(my_list_a)\nprint(my_list_b) \n\n# Funciones con datos por valor\n\nmy_int_c = 10\n\ndef my_int_func (my_int: int):\n    my_int = 20\n    print(my_int)\n\nmy_int_func(my_int_c)\nprint(my_int_c)\n\n# Funciones con datos por referencia\n\ndef my_list_func(my_list: list):\n    my_list.append(30)\n\n    my_list_d = my_list\n    my_list_d.append(40)\n\n    print(my_list)\n    print(my_list_d)\n\nmy_list_c = [10,20]\nmy_list_func(my_list_c)\nprint(my_list_c) #también aquí aparecerá el 30 que se ha añadido dentro de la función\n\n\n\"\"\"\nEXTRA\n\"\"\"\n\"\"\"\n* Crea dos programas que reciban dos parámetros (cada uno) definidos como\n * variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime\n *   el valor de las variables originales y las nuevas, comprobando que se ha invertido\n *   su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n\"\"\"\n\n\ndef valor (my_val_1: int,my_val_2: int):\n   \n    #temp=my_val_2\n    #my_val_2=my_val_1\n    #my_val_1=temp\n\n    my_val_1, my_val_2 = my_val_2, my_val_1 #esta es otra opción más limpia\n\n    return my_val_1,my_val_2\n    \nval_1 = 1\nval_2 = 2\nnew_val_1, new_val_2 = valor(val_1,val_2)\nprint(f\"{val_1} y {val_2}\")\nprint(f\"{new_val_1} y {new_val_2}\")\n\n\n\ndef referencia (my_ref_1: list,my_ref_2: list):\n   \n    temp=my_ref_2\n    my_ref_2=my_ref_1\n    my_ref_1=temp\n\n    #my_ref_1, my_ref_2 = my_ref_2, my_ref_1 #esta es otra opción más limpia\n\n    return my_ref_1,my_ref_2\n    \nref_1 = [10,20]\nref_2 = [30,40]\nnew_ref_1, new_ref_2 = referencia(ref_1,ref_2)\nprint(f\"{ref_1} y {ref_2}\")\nprint(f\"{new_ref_1} y {new_ref_2}\")\n\n\n\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/pwrxman.py",
    "content": "\n\n#\n#  * EJERCICIO:\n#  * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n#  *   su tipo de dato.\n\n# Asignacion por valor\nx = 24\nname = \"andrei\"\nday = x\nprint(f\"Valor de x = {x}. el Nombre es {name} y se va el dia {day}\")\n\n# Asignacion por referencia\nlista1 = [1, 2, 3]\nlista2 = lista1\nprint(f\"la lista1 es {lista1} y la lista2 es {lista2}\")\nlista2.append(4)\nprint(f\"la lista1 es {lista1} y la lista2 es {lista2}\")\n\n# Variables Globales\n\ny = 5\ndef afunc():\n    global y\n    x = 10\n    y = x + y\n    \n    print(f\"Examp Variables Globales -> el valor de x es {x} y el de y es {y} y la suma es {x + y}\")\n    \nafunc()\nprint(f\"el valor de x es {y}\\n\\n\")\n\n\n#  * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n#  *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n#  * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n#  *\n# funcion por valor\nlax = 24.5\ndef mifuncion(varxvalor: float):\n    varxvalor = 100.5\n    print(f\"por valor {varxvalor}\\n\")\n\nmifuncion(lax)\n\nprint(lax)\n\n#funcion por referencia\nx = [100, 120, 330]\ny = [1, 2]\nprint(x, y)\ndef funcion(entrada: list):\n    y = entrada\n    entrada.append(400)\n    print(entrada, y)\nfuncion(x)\nprint(x, y)\n\nprint(\"\\n\\n> > >  > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > >\\n\\n\")\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como\n * variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime\n *   el valor de las variables originales y las nuevas, comprobando que se ha invertido\n *   su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n \"\"\"\n\n# Por valor\n\ndef interchval(valor1: int, valor2: int):\n    aux = valor1\n    valor1 = valor2\n    valor2 = aux\n    return (valor1, valor2)\n\n\nvar1 = 100\nvar2 = 150\n\nnewval1, newval2 = interchval(var1, var2)\nprint(var1, var2, newval1, newval2)\n\n\n# Por referencia\ndef interchref(valor1: list, valor2: list) -> tuple: \n    aux = valor1\n    valor1 = valor2\n    valor2 = aux\n    return valor1, valor2\n\n\nvar11 = [100, 200]\nvar21 = [350, 450]\n\nnewval1, newval2 = interchref(var1, var2)\nprint(var1, var2)\nprint(newval1, newval2)\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/pyramsd.py",
    "content": "# cuando asignas una variable a otra variable de un tipo inmutable (como int, float, string, tuple),\n# se realiza una asignación por valor\na = 10\nb = a  # Se asigna el valor de 'a' a 'b'\na = 30  # Cambiar 'a' no afecta a 'b'\nprint(a)\nprint(b)\n\n# En el caso de tipos mutables (como listas, diccionarios), la asignación se realiza por referencia.\n# Esto significa que ambas variables apuntan al mismo objeto en la memoria, y los cambios realizados\n# en uno afectarán al otro.\nlista_a = [4, 5, 6]\nlista_b = lista_a\n\nlista_a.append(7)  # Modificar 'lista_a' afecta a 'lista_b'\n\nprint(lista_a)\nprint(lista_b)\n\n\n# funcion paso por valor\ndef mod_valor(n):\n    n = 10*4\n    print(f'El valor dentro de la funcion es {n}')\n\nn = 5\nmod_valor(n)\nprint(f'El valor fuera de la funcion es {n}')\n\n\n# funcion paso por referencia\ndef mod_lista(lista):\n    lista[0] = 20\n    print(f'Dentro de la funcion es {lista}')\n\nlista = [30, 40, 50]\nmod_lista(lista)\nprint(f'Fuera de la funcion es {lista}')\n\n\n# EXTRA\nvar1 = 2025\nvar2 = (30, 'Jorge', 50)\nref1 = [45, 47, 49]\nref2 = {'trabajo': 'Doc. fisica', 'area':'cuantica'}\n\nprint(f'Valores originales:\\n\\tvalor 1: {var1}\\n\\tvalor 2: {var2}\\n\\treferencia 1: {ref1}\\n\\treferencia 2: {ref2}')\n\n\ndef cambioDeValores(var1, var2):\n    var1, var2 = var2, var1\n    return var1, var2\n\nfinal_var1, final_var2 = cambioDeValores(var1, var2)\nprint(f'Valores dentro de la funcion:\\n\\tvar 1: {final_var1}\\n\\tvar 2: {final_var2}')\nprint(f'Valor original de var 1: {var1}\\nValor original de var 2: {var2}')\n\n\ndef cambioDeReferencias(ref1, ref2):\n    ref1, ref2 = ref2, ref1\n    return ref1, ref2\n\nfinal_ref1, final_ref2 = cambioDeReferencias(ref1, ref2)\nprint(f'Valores dentro de la funcion:\\n\\tref 1 : {final_ref1}\\n\\tref 2: {final_ref2}')\nprint(f'Valor original de ref 1: {ref1}\\nValor original de ref 2: {ref2}')\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/pytordev.py",
    "content": "##EJERCICIO:\n##- Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según su tipo de dato.\n# Por valor\na = 1\nb = a\nb = 2\nprint(a)  # Salida: 1\nprint(b)  # Salida: 2\n\n# Por referencia\nlista1 = [1, 2, 3]\nlista2 = lista1\nlista2.append(4)\nprint(lista1)  # Salida: [1, 2, 3, 4]\nprint(lista2)  # Salida: [1, 2, 3, 4]\nlista3 = lista1.copy()\nlista3.append(5)\nprint(lista1)  # Salida: [1, 2, 3, 4]\nprint(lista3)  # Salida: [1, 2, 3, 4, 5]\n\n##- Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n\n# funcion con parametros por valor. No se modifica el valor original\nx = 5\nprint(x)  # Salida: 5\n\n\ndef mod_by_value(x):\n    x = 10\n    return x\n\n\nprint(mod_by_value(x))  # Salida: 10\n\n# funcion con parametros por referencia. Se modifica el valor original\nlista4 = [1, 2, 3]\nprint(lista4)  # Salida: [1, 2, 3]\n\n\ndef mod_by_reference(lista):\n    lista = lista4\n    lista.append(4)\n    return lista\n\n\nprint(mod_by_reference([]))  # Salida: [1, 2, 3, 4]\nprint(lista4)  # Salida: [1, 2, 3, 4]\n\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\nCrea dos programas que reciban dos parámetros (cada uno) definidos como\nvariables anteriormente.\n- Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\nEstos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\nse asigna a dos variables diferentes a las originales. A continuación, imprime\nel valor de las variables originales y las nuevas, comprobando que se ha invertido\nsu valor en las segundas.\nComprueba también que se ha conservado el valor original en las primeras.\n\"\"\"\n# Programa 1\na = 10\nb = 20\n\n\ndef swap_values(x, y):\n    x2, y2 = y, x\n    print(x, y)\n    print(x2, y2)\n    return x2, y2\n\n\nswap_values(a, b)\n\n# Programa 2\nlist_a = [15]\nlist_b = [25]\n\n\ndef swap_references(a: list, b: list):\n    a2, b2 = b.copy(), a.copy()\n    print(list_a, list_b)\n    print(a2, b2)\n    return a2, b2\n\n\nswap_references(list_a, list_b)\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/quejuan52.py",
    "content": "'''\nMuestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\nsu tipo de dato.\n'''\n# asignacion por valor \n\nfrom ast import Return\n\n\nmy_variable = \"hola\"\nmy_new_variable = my_variable\nmy_new_variable = \"mundo\"\n\nprint(my_variable)\nprint(my_new_variable)\n\n#asignacion por referencia\n\nmy_list = [3,4,67,10]\nmy_new_list = my_list\nmy_new_list [3] = \"hello\"\n\nprint(my_list)         #salida: my_list =[3,4,67\"hello\"]\nprint(my_new_list)     #salida: my_new_list =[3,4,67\"hello\"]\n\n'''\nMuestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n\"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas\n'''\n# funcion con variable por valor\n\ndef my_function (my_variable):\n    print(my_variable)   # variable original no se ve afectada \n\n# funcion con variable por referencia \n    \ndef variable_referencia(my_list):\n    my_list.append(5)\n    print(my_list)       # variable original si ve afectada \n\n'''\nDIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n'''\n\ndef intercambio_valor(value1,value2):\n    \n    value_temp = value1\n    value1 = value2 \n    value2 = value_temp\n\n    return value1, value2\n\n# variables originales \nvalor1 = 34\nvalor2 = 15\n\n# llamado de la funcion y asignacion a los nuevas variables los valores\nvalor_new1, valor_new2 = intercambio_valor(valor1,valor2)\n\nprint('valores orginales: ',valor1,valor2)\nprint('\\nvalores intercambiados: ',valor_new1,valor_new2)\n\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/qv1ko.py",
    "content": "a = 3\nb = 4\nx = [5]\ny = [6]\n\ndef program1(a, b):\n    aux = a\n    a = b\n    b = aux\n\n    return [a, b]\n\ndef program2(x, y):\n    aux = x[0]\n    x[0] = y[0]\n    y[0] = aux\n\nnewAB = program1(a, b)\nprogram2(x, y)\n\nprint(f\"A value: {a}\")\nprint(f\"New A value: {newAB[0]}\")\nprint(f\"B value: {b}\")\nprint(f\"New B value: {newAB[1]}\")\nprint(f\"X value: {x[0]}\")\nprint(f\"New X value: {x[0]}\")\nprint(f\"Y value: {y[0]}\")\nprint(f\"New Y value: {y[0]}\")\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/qwik-zgheib.py",
    "content": "# -- exercise --\n# assignment by value\na: int = 5\nb: int = a\nb = 10\nprint(f\"a: {a}, b: {b}\")\n\n# assignment by reference\nlist_i: list[int] = [1, 2, 3]\nlist_ii: list = list_i\nlist_ii.append(4)\nprint(f\"list_i: {list_i}, list_ii: {list_ii}\")\n\n\ndef modify_value(num: int) -> None:\n    num = 10\n    print(f\"num in modify_value: {num}\")\n\n\ndef modify_reference(lista) -> None:\n    lista.append(4)\n\n\n# \"by value\" with an integer (immutable)\nx: int = 5\nmodify_value(x)\nprint(f\"x after modify_value: {x}\")\n\n# \"by reference\" with a list (mutable)\nlist_numbers: list[int] = [1, 2, 3]\nprint(f\"list before modify_reference: {list_numbers}\")\nmodify_reference(list_numbers)\nprint(f\"list after modify_reference: {list_numbers}\")\n\n\n# -- extra challenge --\nprint(\"\\n------ extra challenge ------\")\n\n\n# parameters exchange\nclass ValueSwapper:\n    def swap(self, x, y):\n        return y, x\n\n\nclass ReferenceSwapper:\n    def swap(self, lista1, lista2):\n        lista1[:], lista2[:] = lista2[:], lista1[:]\n\n\ndef main():\n    # values by value\n    a: int = 1\n    b: int = 2\n    swapper_val = ValueSwapper()\n    a_new, b_new = swapper_val.swap(a, b)\n    print(f\"Original a: {a}, b: {b}\")\n    print(f\"Swapped a_new: {a_new}, b_new: {b_new}\")\n    # values by reference\n    list_1 = [1, 2, 3]\n    list_2 = [4, 5, 6]\n    swapper_ref = ReferenceSwapper()\n    swapper_ref.swap(list_1, list_2)\n    print(f\"Original list_1: {list_1}, list_2: {list_2}\")\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/rantamhack.py",
    "content": "\n# Variables asignadas por valor\n'''\nLas variables por valor se asignan a tipos primitivos cuando se le da el valor a una variable se guarda\nen un punto de la memoria que se puede obtener con la funcion \"id\" lo podemos conocer. Por  eso una vez\nque hemos asignado el valor de \"a\" a \"b\" aunque cambiemos el valor de \"a\" el de \"b\" no cambia pues su\nlugar en la memoria no cambia\n'''\n\nprint(\"\\n\\n=========================\\n\\n\")\n\na = 5\nprint(a, id(a))        # 140731962418088\nb = a\nprint(b, id(b))        # 140731962418088\na = 10\n\nprint(a, id(a))     # 10    140731962418248\nprint(b, id(b))     # 5     140731962418088\n\nprint(\"\\n\\n=========================\\n\\n\")\n\n# Variables asignadas por referencia\n'''\nLas variables asignadas por referencia es a tipos compuestos(listas, tuplas, set o diccionarios)\nAqui­ al igualar las variables lo que hacemos es dar el mismo punto de memoria a las dos por lo \nal cambiar el valor de \"list_b\" lo cambiamos en la memoria que comparten \"list_a\" y \"list_b\"\n'''\n\nlist_a = [5, 10]\nprint(list_a, id(list_a))   # [5, 10] 1711738540608\nlist_b = list_a\nprint(list_b, id(list_b))   # [5, 10] 1711738540608\nlist_b.append(15)\n\nprint(list_a, id(list_a))   # [5, 10, 15] 2834210902592\nprint(list_b, id(list_b))   # [5, 10, 15] 2834210902592\n\n\n# Funcion con asignacion por valor\nnum = 5\n\ndef valor(n):\n  n = 10\n  print(n)\n  \nvalor(num)\nprint(num)\n\n# Funcion con asignacion por referencia\nlist_a = [5, 10]\n\ndef referencia(lis):\n  lis.append(15)\n  print(lis)\n\nreferencia(list_a)\nprint(list_a)  \n\n\n\nprint(\"\\n\\n=======================================DIFICULTAD EXTRA=======================================\\n\\n\")\n\n\n# Asignacion por valor\n\na = 5\nb = 10\n\ndef intercambio_valor(num1, num2):\n  num3 = num1\n  num1 = num2\n  num2 = num3\n  return num1, num2\n\n\n(c, d) = (intercambio_valor(a, b))\n\nintercambio_valor(a, b)\nprint(a, b)\nprint(c, d)\n\nprint(\"\\n\\n=========================\\n\\n\")\n\n# Asignacion por referencia\n\nlist_a = [10, 20]\nlist_b = [30, 40]\n\ndef intercambio_ref(lis1, lis2):\n  lis3 = lis1\n  lis1 = lis2\n  lis2 = lis3\n  return lis1, lis2\n\n\n(list_c, list_d) = (intercambio_ref(list_a, list_b))\n\nintercambio_ref(list_a, list_b)\nprint(list_a, list_b)\nprint(list_c, list_d)\n\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/raulG91.py",
    "content": "#Asignacion por valor \na=8\nb = a\nb = 2\n\nprint(\"Asignacion valor: \",a,b)\n\n#Asignacion por referencia\nlist1 = [3,9,6]\nlist2 = list1 \nlist2.append(2)\n\nprint(\"Asignacion por referencia \")\nprint(list1)\nprint(list2)\n\n# Funciones paso por valor\ndef double_num(num):\n    return num **2\n\nnumber = 2\n\nprint(\"Paso por valor\", double_num(number))\n\n#Funciones paso por referencia\ndef double_nums(numbers):\n    \n    for index,number  in enumerate(numbers):\n        numbers[index] = number ** 2\n    \n\nlist_numbers = [6,9,17]\ndouble_nums(list_numbers)\nprint(\"Paso por referencia\",list_numbers) \n\ndef string_referencia(cadena):\n    \n    cadena += \" + concatenate\"       \n\nstring_cadena = \"New string\"    \nstring_referencia(string_cadena)\nprint(\"Paso por referencia string: \", string_cadena)\n\n#Extra exercise \n\ndef intercambia_valor(a,b):\n    aux = a\n    a = b\n    b = aux\n    return a,b\n     \nvalue1 = 4\nvalue2 = 8 \n\nvalue3,value4 = intercambia_valor(value1,value2)  \n\nprint(\"Valores originales: \",value1,value2)\nprint(\"Valores retorno: \",value3,value4)\n\n\ndef intercambia_referencia(a,b):\n    \n    aux = a\n    a = b\n    b = aux\n    return a,b\n\nlist3 = [9,8,7]\nlist4 = [2,1,4]  \n\nlist5,list6 = intercambia_referencia(list3,list4)\nlist4.append(16)\nprint(\"Valores originales\", list3,list4)\nprint(\"Valores retorno: \",list5,list6)\n  "
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/rayn1er.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n#  *   su tipo de dato.\n#  * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n#  *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n#  * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea dos programas que reciban dos parámetros (cada uno) definidos como\n#  * variables anteriormente.\n#  * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n#  *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n#  *   se asigna a dos variables diferentes a las originales. A continuación, imprime\n#  *   el valor de las variables originales y las nuevas, comprobando que se ha invertido\n#  *   su valor en las segundas.\n#  *   Comprueba también que se ha conservado el valor original en las primeras.\n#  */\n\n#datos por valor\n\nvalue_a = 100\nprint(value_a) # mostramos lo que vale a \nvalue_b = value_a # le asignamos a b el valor de a \nprint(value_b) # imprimimos el valor de b\nvalue_a = 200 #cambiamos el valor de a\nprint(value_a,value_b) # imprimimos y notamos que b sigue valiendo lo mismo que valia a, puesto que le hemos asignado el valor que tenia previamente a \nvalue_c = 300\n#datos por referencia\n#son todos aquellos que no son tipos de datos primitivos\n\nlist_a = [10,20,30,40,50]\nlist_b = list_a\n\nprint(list_a,list_b)\n\nlist_b.append(60)\n\nprint(list_a,list_b) #podemos ver que se ha agregado a ambas listas, puesto que como es un dato por referencia, no almacena su valor en un espacio diferente de memoria, si no que lo enlaza a la posicion de memoria que contiene el elemento al que hace referencia\n\n#funciones coon datos por valor\n\ndef ints(int1 : int):\n    value = 400 # asignamos un valor y almacena en otra posicion de memoria\n    print(value)\n \nints(value_c) # cambia\nprint(value_c) # no cambia\n\n#funciones con referencia\n\nlist_c = [100,200,300]\n\ndef lists(my_list: list):\n    my_list.append(400) # agrega el valor a los dos elementos porque asigna enlaza con la posicion de memoria del primero\n    print(my_list)\n\nlists(list_c) # cambia\nprint(list_c) # cambia\n\n#extra\n\n#por valor\n\nvalue_d = 100\nvalue_e = 200\n\ndef value(value_a : int, value_b = int):\n    temp = value_a #almacena el valor de a en una variable nueva\n    value_a = value_b #cambia valor\n    value_b = temp #cambia valor\n\n    return value_a,value_b\n\nprint(value(value_d,value_e))\n\n# por referencia\n\ndef ref(list_a = list, list_b = list):\n\n    temp = list_a #almacena la referencia de valor de a\n    list_a = list_b #cambia la referencia de a para b\n    list_b = temp # cambia la referencia de b para a\n    return list_a, list_b\n\nlist_d = [100,200]\nlist_e = [300,400]\n\nprint(ref(list_d,list_e))"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/raynerpv2022.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n\"\"\"\n\n\ndef x_valor():\n    # int. string, float, tuplas\n    X_coin = 12\n    z_coin = X_coin\n    z_coin  = 0\n    print(X_coin, f\"Direccion memoria {id(X_coin)}\")\n    print(z_coin,f\"Direccion memoria {id(z_coin)}\")\n\n    n_coin = \"CUBACoin\"\n    a_coin =  n_coin+\"Hav_coin\"\n    a_coin = \"asasa\"\n\n    print(n_coin,f\"Direccion memoria {id(n_coin)}\")\n    print(a_coin,f\"Direccion memoria {id(a_coin)}\")\n\n    t1 = (1,2,3,4,5,6)\n    t2 = (t1)\n    t2 = t1+t1\n    print(t1,f\"Direccion memoria {id(t1)}\")\n    print(t2,f\"Direccion memoria {id(t2)}\")\n\n\n\ndef x_referencia():\n\n    # dic , list, set\n    l1 = [1,2,3,4,5,6]\n    l2 = l1\n    l2.append(\"00\")\n    print(l1,f\"Direccion memoria L1 {id(l1)}\")\n    print(l2,f\"Direccion memoria L2 {id(l2)}\")\n\n    d1 = {1:\"a\",2:\"b\" }\n    d2 = d1\n    d2[3] = \"c\"\n    print(d1,f\"Direccion memoria d1 {id(d1)}\")\n    print(d2,f\"Direccion memoria d2 {id(d2)}\")\n\n    s1 = {1 ,2  }\n    s2 = s1\n    s2.add(9)\n    print(s1,f\"Direccion memoria s1 {id(s1)}\")\n    print(s2,f\"Direccion memoria s2 {id(s2)}\")\n    def x_ref(lista1):\n        lista1.append(\"q\")\n        return lista1\n    l100 = x_ref(l1)\n    print(l1,f\"Direccion memoria L1 {id(l1)}\")\n    print(l100,f\"Direccion memoria L100 {id(l100)}\")\n\n\n\nx_valor()\nx_referencia()\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n \"\"\"\n\nnomb1 = \"HOla\"\nnomb2 = \"Python\"\n\ndef prog_X_valor(cad1, cad2: str):\n    \n    cad1,cad2  = cad2, cad1\n    return cad1, cad2\n\nqq1, qq2 =  prog_X_valor(nomb1,nomb2)\nprint(nomb1, nomb2)\nprint(qq1, qq2)\n\n\n\n\ndef prog_X_ref(dic1, dic2: dict):\n    \n    # dic1 = dic2\n    # dic1[\"Francia\"] = \"Paris\"\n    dic1, dic2 = dic2, dic1\n    return dic1,dic2\n\n\nk_v1 = {\"Cuba\":\"Havana\"}\nk_v2 = {\"Rusia\":\"Moscu\"}\nzz1 , zz2 = prog_X_ref(k_v1,k_v2)\nprint(k_v1,\" y \" ,k_v2)\nprint(k_v1,f\"Direccion memoria d2 {id(k_v1)}\")\nprint(k_v2,f\"Direccion memoria d2 {id(k_v2)}\")\nprint(zz1, \" y \", zz2)\nprint(zz1,f\"Direccion memoria d2 {id(zz1)}\")\nprint(zz2,f\"Direccion memoria d2 {id(zz2)}\")\n\n   \n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/restevean.py",
    "content": "# Assignment by value (immutable types)\nnum1 = 5\nnum2 = num1\nnum2 = 7\nprint(num1)  # Output: 5\nprint(num2)  # Output: 7\n\n# Assignment by reference (mutable types)\nlist1 = [1, 2, 3]\nlist2 = list1\nlist2.append(4)\nprint(list1)  # Output: [1, 2, 3, 4]\nprint(list2)  # Output: [1, 2, 3, 4]\n\n\n# Function with variable passed by value\ndef increment(num):\n    num += 1\n    return num\n\n\nnum = 5\nincrement(num)\nprint(num)  # Output: 5\n\n\n# Function with variable passed by reference\ndef append_elem(lst, elem):\n    lst.append(elem)\n\n\nlst = [1, 2, 3]\nappend_elem(lst, 4)\nprint(lst)  # Output: [1, 2, 3, 4]\n\n\n# Program 1: Immutable types (mimics pass by value)\ndef swap_values(a, b):\n    a, b = b, a\n    return a, b\n\n\nx = 5\ny = 10\nnew_x, new_y = swap_values(x, y)\n\nprint(x, y)  # Output: 5 10\nprint(new_x, new_y)  # Output: 10 5\n\n\n# Program 2: Mutable types (pass by reference)\ndef swap_lists(a, b):\n    a[:], b[:] = b[:], a[:]\n    return a, b\n\n\nlist1 = [1, 2, 3]\nlist2 = [4, 5, 6]\nnew_list1, new_list2 = swap_lists(list1, list2)\n\nprint(list1, list2)  # Output: [4, 5, 6] [1, 2, 3]\nprint(new_list1, new_list2)  # Output: [4, 5, 6] [1, 2, 3]\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/rianojnicolas.py",
    "content": "###################################\n# Dev: rianojnicolas              #\n###################################\n\n# 1. Asignacion de variables por valor y referencia\n\n## 1.1 Variables por valor\n##      Generalmente en python, los valores que se pueden asignar por valor son los tipos de datos primitivos\n##      Por ejemplo: Int, float, string y booleanos\n##      Se puede decir que se puede hacer una copia del valor de una variable\nmyIntA = 10\nmyIntB = myIntA\n#myIntB = 20\nmyIntA = 50\nprint(myIntA)\nprint(myIntB)\n\n\n## 1.2 Variables por referencia\n##      Generalmente en python, los valores que se pueden asignar por referencia son los tipos de datos que no son primiticos\n##      Por ejemplo: Listas, tuplas, diccionarios, set, etc\n##      Se traduce a que estos valores por referencia heredan la posición de memoria, parece como si fueran los punteros de C++\n\nmy_setA = {10, 20}\n#my_setB = {30, 40}\nmy_setB = my_setA\nmy_setB.add(30)\nprint(my_setA)\nprint(my_setB)\n\n\n# 2. Ejemplos de funciones por valor y por referencia\n\n## 2.1 Funciones con datos por valor\n\ndef fillCoupValue(fill):\n    fill = 99\n    print(fill)\n    return fill\n\nmy_fill = 50\nfillCoupValue(my_fill)\nprint(my_fill)\n\n## 2.2 Funciones con datos por referencia\ndef fillCoupHistory(fill):\n    fill.append(25)\n    \n    fill_a = fill\n    fill_a.append(45)\n\n    print(fill)\n    print(fill_a)\n    return fill\n\nmy_fill_history = [0, 10, 5, 50, 20]\nfillCoupHistory(my_fill_history)\nprint(my_fill_history)\n\n# Dificultad Extra\n# Caso 1: Parametros por valor\ndef byValue(a, b):\n    c = a\n    a = b\n    b = c\n    return a, b\n\n\n# Caso 2: Parametros por referencia\ndef byRefer(a, b):\n    c = a\n    a = b\n    b = c\n    return a, b\n\n\ndef run():\n    # Caso 1: Parametros por valor\n    my_val_1 = 10\n    my_val_2 = 20\n    print(\"Los valores inciales son: \")\n    print(my_val_1)\n    print(my_val_2)\n    my_val_3, my_val_4 = byValue(my_val_1, my_val_2)\n    print(\"Los valores retornados son: \")\n    print(my_val_3)\n    print(my_val_4)\n    print(\"Los valores originales son: \")\n    print(my_val_1)\n    print(my_val_2)\n\n    # Caso 2: Parametros por referencia\n    my_ref_1 = [10, 30, 50]\n    my_ref_2 = [20, 40, 60]\n    print(\"Los valores inciales son: \")\n    print(my_ref_1)\n    print(my_ref_2)\n    my_ref_3, my_ref_4 = byValue(my_ref_1, my_ref_2)\n    print(\"Los valores retornados son: \")\n    print(my_ref_3)\n    print(my_ref_4)\n    print(\"Los valores originales son: \")\n    print(my_ref_1)\n    print(my_ref_2)\n\n\nif __name__ == '__main__':\n    run()"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/rigo93acosta.py",
    "content": "# 05 VALOR Y REFERENCIA\n\n'''\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n'''\n\n# Tipos de dato por valor\n\nmy_int_a = 10\nmy_int_b = my_int_a\n# my_int_b = 20\n# my_int_a = 30\nprint(my_int_a)\nprint(my_int_b)\n\n# Tipos de dato por referencia\n\nmy_list_a = [10, 20]\nmy_list_b = my_list_a\nmy_list_b.append(30)\nprint(my_list_a)\nprint(my_list_b)\n\n# Para que no suceda\nmy_list_a = [10, 20]\nmy_list_b = my_list_a.copy()\nmy_list_b.append(30)\nprint(my_list_a)\nprint(my_list_b)\n\n'''\nFunciones\n'''\n\n# Funciones datos por valor\n\nmy_int_c = 10\n\ndef my_int_func(my_int: int):\n    my_int = 20\n    print(my_int)\n\nmy_int_func(my_int_c)\nprint(my_int_c)\n\n# Funciones datos por valor\n\nmy_list_c = [10, 20]\n\ndef my_list_func(my_list: list):\n    my_list.append(30)\n    print(my_list)\n\nmy_list_func(my_list_c)\nprint(my_list_c)\n\n'''\n-------\n*Extra*\n-------\n'''\n\n# Por valor\na_int = 10\nb_int = 20\n\ndef changed(val_a: int, val_b: int):\n    temp = val_a\n    val_a = val_b\n    val_b = temp\n    return val_a, val_b\n\nc_int, d_int = changed(a_int, b_int)\nprint(f'Originales: {a_int}-{b_int} <-> Cambiadas {c_int}-{d_int}')\n\n# Por referencia\n\na_list = [10, 20]\nb_list = [30, 40]\n\ndef changed(val_a: list, val_b: list):\n    temp = val_a\n    val_a = val_b\n    val_b = temp\n    return val_a, val_b\n\nc_list, d_list = changed(a_list, b_list)\nprint(f'Originales: {a_list}-{b_list} <-> Cambiadas {c_list}-{d_list}')"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/rikmij.py",
    "content": "#asignación por valor. Son tipos simples: strings, ints, bool...\nvalue = \"Asignado por valor\"\n\n#asignación por referencia. Son colecciones: listas, tuples, sets...\nrefer = [\"Referencia\", 33]\n\n\ndef fun_valor(valor):\n    valor = \"he sido modificado\"\n\nval = \"mondongo\"\nfun_valor(val)\nprint(val)\n\n\ndef fun_reference(ref):\n    ref[0] = \"Ahora el primero soy yo\"\n\nrefe = [1, 2, 3]\nfun_reference(refe)\nprint(refe)\n\n\ndef fun_valor_mod(val):\n    valor = \"He sido modificado\"\n    return valor\n\nval1 = \"mondongo1\"\nval1 = fun_valor_mod(val1)\nprint(val1)\n\n\nprint('\\n', '~'*7, \"EJERCICIO EXTRA\", '~'*7)\n\ndef funcion_valor(v1, v2):\n    aux = v1\n    v1 = v2\n    v2 = aux\n\n    return v1, v2\n\nv1 = 1\nv2 = 2\nnew_v1, new_v2 = funcion_valor(v1, v2)\n\nprint(f\"v1 = {v1}, v2 = {v2}\")\nprint(f\"new_v1 = {new_v1}, new_v2 = {new_v2}\")\n\n\ndef funcion_referencia(ref1, ref2):\n    aux = ref1\n    ref1 = ref2\n    ref2 = aux\n    return ref1, ref2\n\nref1 = [\"Uno\", \"Dos\", \"Tres\"]\nref2 = (1, 2, 3)\nn_ref1, n_ref2 = funcion_referencia(ref1, ref2)\n\nprint(f\"ref1 = {ref1}, ref2 = {ref2}\")\nprint(f\"n_ref1 = {n_ref1}, n_ref2 = {n_ref2}\")\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/santiagobailleres.py",
    "content": "'''EJERCICIO:\n- Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\nsu tipo de dato.\n- Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n\"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n(Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n\nDIFICULTAD EXTRA (opcional):\nCrea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n- Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\nEstos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\nse asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\nvariables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\nComprueba también que se ha conservado el valor original en las primeras.'''\n\n# Asignación de variables por valor\na = 5 # Asignación por valor\nb = a # Asignación por valor\na = 10 # Modificación de a\nprint(a) # a vale 10\nprint(b) # b sigue valiendo 5\nb = 15 # Modificación de b\nprint(b) # b vale 15\n\n# Asignación de variables por referencia\nlista1 = [1, 2, 3] # Asignación por referencia\nlista2 = lista1 # Asignación por referencia\nlista2.append(4) # Modificación de lista2\nprint(lista1) # lista1 vale [1, 2, 3, 4]\nprint(lista2) # lista2 vale [1, 2, 3, 4]\nlista1.append(5) # Modificación de lista1\nprint(lista1) # lista1 vale [1, 2, 3, 4, 5]\nprint(lista2) # lista2 vale [1, 2, 3, 4, 5]\n\n# Funciones con variables por valor\ndef int_func(var_int:int):\n    var_int = 10\n    return var_int\n\nc = 2\nprint(int_func(c)) # Imprime 10\nprint(c) # Imprime 2\n\n# Funciones con variables por referencia\ndef list_func(var_list:list):\n    var_list.append(4)\n    lista = var_list\n    lista.append(5)\n    print(var_list) # Imprime [1, 2, 3, 4, 5]\n    print(lista) # Imprime [1, 2, 3, 4, 5]\n\nvar_lista = [1, 2, 3]\nlist_func(var_lista)\nprint(var_lista) # Imprime [1, 2, 3, 4, 5]\n\n# EXTRA\n'''Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n- Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\nEstos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\nse asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\nvariables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\nComprueba también que se ha conservado el valor original en las primeras.'''\n\n# Por valor\ndef value(value1:int, value2:int):\n    temp = value1\n    value1 = value2\n    value2 = temp\n    return value1, value2\n\nvalue3 = 5\nvalue4 = 10\nvalue5, value6 = value(value3, value4)\n\nprint(f'{value3}, {value4}') # Imprime 5, 10\nprint(f'{value5}, {value6}') # Imprime 10, 5\n\n# Por referencia\ndef reference(ref1:list, ref2:list):\n    temp = ref1\n    ref1 = ref2\n    ref2 = temp\n    return ref1, ref2\n\nref3 = [1, 2, 3]\nref4 = [4, 5, 6]\nref5, ref6 = reference(ref3, ref4)\n\nprint(f'{ref3}, {ref4}') # Imprime [1, 2, 3], [4, 5, 6]\nprint(f'{ref5}, {ref6}') # Imprime [4, 5, 6], [1, 2, 3]"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/santyjL.py",
    "content": "\"\"\"\n#05\nVALOR Y REFERENCIA\n/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y\n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n\"\"\"\n\n# Variables por valor\nx = 30  # Almacena directamente el valor\ny = x\n\n# Variables por asignación\nlista_x = [1, 2, 3, 4, 5]  # Se guardan en memoria\nlista_y = lista_x  # Se copia el contenido en otro lugar de memoria\nlista_y.append(5)\n\n# Verificación\nif x == y:\n    print(\"x es igual que y\")\nelse:\n    print(\"x no es igual a y\")\n\nif lista_x == lista_y:\n    print(\"lista_x es igual a lista_y\")\nelse:\n    print(\"lista_x es diferente a lista_y porque no comparten el mismo contenido\")\n\n# Funciones\ndef modificacion_valor(valor):\n    # Se crea una nueva variable local para evitar modificar la original fuera de la función\n    nuevo_valor = valor + 10\n    return nuevo_valor\n\ndef modificacion_asignacion(lista):\n    # Se crea una nueva lista para evitar modificar la original fuera de la función\n    nueva_lista = lista\n    nueva_lista.append(6)\n    return nueva_lista\n\nx_modificada = modificacion_valor(x)\ny_modificada = modificacion_asignacion(lista_y)\n\n\nprint(f\"\"\"\n      #modificaciones_valor : {x_modificada}\n      #original_valor : {x}\n\n      #modificacion_asignacion : {y_modificada}\n      #original_asignacion : {lista_y}\n\n      \"\"\")\n\n### EXTRA ###\n\n#originales valor\nx = 1\ny = 2\n\n#original asignacion\nxy = [1,2]\nxz = [2,1]\n\n\ndef intercambia_valor(x:int ,y:int):\n    temporal = x\n    x = y\n    y = temporal\n\n    return x , y\n\ndef intercambia_asignacion(x:list,y:list):\n    temporal = x\n    x = y\n    y = temporal\n\n    return x , y\n\n\nx_modificada , y_modificada = intercambia_valor(x , y)\nxy_modificada , xz_modificada = intercambia_valor(xy , xz)\n\nprint(f\"\"\"\n      ### valor ###\n      originales : {x} , {y}\n      intercambiadas : {x_modificada , y_modificada}\n\n      ### asignacion ###\n      originales : {xy} , {xz}\n      intercambiadas : {xy_modificada , xz_modificada}\n      \"\"\")\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/sarismejiasanchez.py",
    "content": "# #05 VALOR Y REFERENCIA\n\n\"\"\"\n* - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n*   su tipo de dato.\n\"\"\"\n\n# PASO POR VALOR\n# Variables inmutables (se comportan como si fueran \"por valor\")\n# Los tipos de datos inmutables en Python incluyen int, float, bool, str, tuple. \n# Si modificas una variable de un tipo inmutable, se crea un nuevo objeto en memoria.\n\nprint(\"PASO POR VALOR\")\n# Variables inmutables (int, str)\na = 10\nb = a   # Apunta al mismo valor que a\n\nb = 20  # Se crea un nuevo valor, b apunta a otro lugar en memoria\n\nprint(a)    # 10 (a no ha cambiado)\nprint(b)    # 20 (b tiene un nuevo valor)\n\n# PASO POR REFERENCIA\n# Variables mutables (se comportan como si fueran \"por referencia\")\n# Los tipos de datos mutables incluyen list, dict, set. Modificar una variable mutable afecta\n# a todas las referencias que apuntan a ese objeto.\n\nprint(\"PASO POR REFERENCIA\")\n# Variables mutables (listas)\nx = [1, 2, 3]\ny = x  # y apunta al mismo espacio en memoria de x\n\ny.append(4)  # Modifica la lista a la que ambos apuntan\n\nprint(x)  # Output: [1, 2, 3, 4] (x ha cambiado)\nprint(y)  # Output: [1, 2, 3, 4] (y también ha cambiado)\n        \n\n\"\"\"\n* - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n*   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n* (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n*\n\"\"\"\n\n# Función con inmutables (se comportan como si fueran \"por valor\")\n# Cuando pasas un tipo inmutable a una función, cualquier modificación dentro de la función no # afectará al valor original fuera de la función.\n\nprint(\"\\nFunciones: Paso por Valor vs Referencia\")\n\nprint(\"PASO POR VALOR\")\n\ndef modificar_numero(n):\n    n = 100  # Se asigna un nuevo valor a n\n    print(f\"Valor dentro de la función: {n}\")   # # Valor dentro de la función: 100\n\nnumero = 10\nmodificar_numero(numero)\nprint(f\"Valor fuera de la función: {numero}\")   # Valor fuera de la función: 10\n\n# Función con mutables (se comportan como si fueran \"por referencia\")\n# Cuando pasas un tipo mutable a una función, las modificaciones dentro de la función \n# afectarán al objeto original.\n\nprint(\"PASO POR REFERENCIA\")\n\ndef modificar_lista(lista):\n    lista.append(100)  # Modifica la lista original\n\nmi_lista = [1, 2, 3]\nmodificar_lista(mi_lista)\nprint(mi_lista)     # [1, 2, 3, 100] (la lista ha sido modificada)\n\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n* Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n* - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n*   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n*   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n*   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n*   Comprueba también que se ha conservado el valor original en las primeras.\n*/\n\"\"\"\n\nprint(\"\\nEXTRA\")\n# POR VALOR\nprint(\"POR VALOR\")\ndef values_exchange(value1, value2):\n    temp = value1  # Guarda temporalmente el valor de value1\n    value1 = value2     # Asigna el valor de value2 a value1\n    value2 = temp     # Asigna el valor temporal (el original de value1) a value2\n    return value1, value2\n\nnum1 = 10\nnum2 = 15\nprint(f\"Valor original num1: {num1}\")\nprint(f\"Valor original num2: {num2}\")\n\ninter_num1, inter_num2 = values_exchange(num1, num2)\nprint(f\"Valor intercambio num1: {inter_num1}\")\nprint(f\"Valor intercambio num2: {inter_num2}\")\n    \n# POR REFERENCIA\nprint(\"\\nPOR REFERENCIA\")\n\ndef reference_exchange(value1, value2):\n    # Intercambiar el contenido de los argumentos mutables\n    value1[:], value2[:] = value2[:], value1[:]     # Asignación por slice para modificar in-place\n    return value1, value2\n\n\nnumbers = [num for num in range(10) if num % 2 == 0]    # Numeros pares entre 0 y 10\nfruits = [\"naranja\", \"melon\", \"manzana\"]    # Lista de frutas\nprint(f\"Valor original numbers: {numbers}\")\nprint(f\"Valor original fruits: {fruits}\")\ninter_value1, inter_value2 = reference_exchange(numbers, fruits)\nprint(f\"Valor intercambio numbers: {inter_value1}\")\nprint(f\"Valor intercambio fruits: {inter_value2}\")"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/sorubadguy.py",
    "content": "\"\"\"\nValor y Referencias\n\"\"\"\n\n#*Valor: solo copia el valor de var1 en var2\nvar1 = 5\nvar2 = var1\nprint(f\"{var1}\\n{var2}\")\nvar1 = 10\nprint(f\"{var1}\\n{var2}\")\n\n#*Referencia: copia la ubicacion en memoria del dato de lista1 en lista2\nlista1 = [1,3,5,2,3]\nlista2 = lista1\nprint(f\"ejemplo listas:\\nlista1: {lista1}\\nlista2: {lista2}\")\nlista1[1] = 2\nlista1[2] = 2\nprint(f\"lista1: {lista1}\\nlista2: {lista2}\")\nbiblio1 = {\"a\" : \"letra a\",\n           \"b\" : \"letra b\",\n           \"c\" : \"letra c\"\n           }\nbiblio2 = biblio1\nprint(f\"ejemplo bibliotecas:\\n{biblio1}\\n{biblio2}\")\nbiblio1[\"b\"] = \"soy otra cosa\"\nprint(f\"{biblio1}\\n{biblio2}\")\n\n#*Valor en funciones\n\ndef valor(numero):\n    numero = numero*2\n    return numero\n\nprint(valor(var1))\nprint(var1)\n\n#*Referencia en funciones\n\ndef referencia(lista: list):\n    lista.append(345)\n    return lista\n\nprint(referencia(lista1))\nprint(lista1)\n\n\"\"\"\n!Extra\n\"\"\"\n#Valor\n\ndef programa_valor(varo1: int, varo2: int) -> tuple:\n    varo3 = varo1\n    varo1 = varo2\n    varo2 = varo3\n    return varo1, varo2\n\n\nvalor1 = 10\nvalor2 = 20\n\nvalor3, valor4 = programa_valor(valor1, valor2)\nprint(valor1, valor2)\nprint(valor3, valor4)\n\n#Referencia\n\ndef programa_referencia(ref1, ref2):\n    ref3 = ref1\n    ref1 = ref2\n    ref2 = ref3\n    return ref1, ref2\n\nreferencia1 = [1,2,3,4,5]\nreferencia2 = [7,8,9,0]\nreferencia3 = []\nreferencia4 = []\n\nreferencia3, referencia4 = programa_referencia(referencia1, referencia2)\n\nprint(referencia1, referencia2)\nprint(referencia3, referencia4)"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/switchdays.py",
    "content": "\"\"\"\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n \"\"\"\n\n\n# Asignación por valor para números\nx = 10\ny = x\ny = 20  # Modificar 'y' no afecta a 'x'\nprint(x)  # Salida: 10\nprint(y)  # Salida: 20\n\n\n# Asignación por referencia para listas\nlista1 = [1, 2, 3]\nlista2 = lista1\nlista2.append(4)  # Modificar 'lista2' también modifica 'lista1'\nprint(lista1)  # Salida: [1, 2, 3, 4]\nprint(lista2)  # Salida: [1, 2, 3, 4]\n\n\ndef modificar_numero(numero):\n    numero = 100\n\nx = 10\nmodificar_numero(x)\nprint(x)  # Salida: 10 (sin cambios)\n\n\ndef modificar_lista(lista):\n    lista.append(4)\n\nmi_lista = [1, 2, 3]\nmodificar_lista(mi_lista)\nprint(mi_lista)  # Salida: [1, 2, 3, 4]\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n \"\"\"\n\n# Por valor:\n\nnum_1_original = 10\nnum_2_original = 20\n\ndef intercambiar_por_valor(num_1, num_2):\n    new_var_1 = num_1\n    new_var_2 = num_2\n\n    return new_var_1, new_var_2\n\nnew_num_1, new_num_2 = intercambiar_por_valor(num_1_original, num_2_original)\n\nprint(\"Los originales son: \", num_1_original, \"y \", num_2_original)\nprint(\"Los nuevos son: \", new_num_1, \"y \", new_num_2)\n\n\n# Por referencia:\n\nlist_1_original = [1, 2, 3, 4]\nlist_2_original = [10, 20, 30, 40]\n\ndef intercambiar_por_referncia(list_1, list_2):\n    new_list_1 = list_2\n    new_list_2 = list_1\n\n    return new_list_1, new_list_2\n\nnew_list_1, new_list_2 = intercambiar_por_referncia(list_1_original, list_2_original)\n\nprint(\"Las originales son: \", list_1_original, \"y \", list_2_original)\nprint(\"Las nuevos son: \", new_list_1, \"y \", new_list_2)"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/thonys07.py",
    "content": "'''\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n '''\n\n#asignación de variables por valor\n\na=1993\nc=a\na=15\nprint('a:', a)\nprint('c:', c)\n\n#asignación de variables por referencia\nlista1=[1,1993,3,4]\nlista2=lista1\nprint('lista1:', lista1)\nprint('lista2:', lista2)\nlista2[2]=5\nlista1.append(1995)\nprint('lista1 after append 1995 :', lista1)\nprint('lista2 after add [2]=5:', lista2)\n\n#funciones que modifican las variables por valor o referencia\n\ndef modificar_por_valor(a):\n    b=a**3\n    return b\n\ndef modificar_por_referencia(lista2):\n    lista2.append(1995)\n    return lista2\n\nvalor_modificado=modificar_por_valor(a)\nreferencia_modificada=modificar_por_referencia(lista2)\nprint(f'el valor a es {a} luego de modificado es {valor_modificado}, y el valor de lista2 es {lista1} luego de modificado es {referencia_modificada}')\n\n\n''' EXTRA '''\n#valores iniciales\ninicial_a=12\ninicial_b=10\n\ndef intercambiar_por_valor(a,b):\n    temp=a\n    a=b\n    b=temp\n    return a,b\n\n#referencias iniciales\n\nlista_inicial_a=[1,2,3]\nlista_inicial_b=[1993,1994,1995]\n\ndef intercambiar_por_referencia(a,b):\n    temp=a\n    a=b\n    b=temp\n    return a,b\n\n#valores y referencias intercambiadas\na_intercambiada,b_intercambiada=intercambiar_por_valor(inicial_a,inicial_b)\nlista_intercambiada_a,lista_intercambiada_b=intercambiar_por_referencia(lista_inicial_a,lista_inicial_b)\n\nprint(f'el valor inicial de a es {inicial_a} y de b es {inicial_b} luego de intercambiado es {a_intercambiada} y {b_intercambiada} respectivamente')\nprint(f'el valor inicial de lista_a es {lista_inicial_a} y de lista_b es {lista_inicial_b} luego de intercambiado es {lista_intercambiada_a} y {lista_intercambiada_b} respectivamente')\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/tito-delpino.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n#  *   su tipo de dato.\n#  * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n#  *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n#  * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n\nstring1 = 'delpino'\nprint(string1)\nstring1 = 'tito-'\nprint(string1)\nstring2 = 'delpino'\nprint(string2)\nstring1 = string1 + string2 # cambiamos el valor de la variable \nprint(string1)\n\n\ndef mi_funcion(lista: list):\n    lista.append(40)\n    print(lista)\n\n    mi_lista2 = lista\n    mi_lista2.append(50)\n\n    print(lista)\n    print(mi_lista2)\n\nmi_lista = [10,20,30]\nmi_funcion(mi_lista)\nprint(mi_lista)\n    \n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n#  * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n#  *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n#  *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n#  *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n#  *   Comprueba también que se ha conservado el valor original en las primeras.\n\n# Por valor\ndef funcion2(valor1, valor2):\n    aux = valor1\n    valor1 = valor2\n    valor2 = aux\n    return valor1, valor2\n\nvalor1 = 20\nvalor2 = 40\nvalor3, valor4 = funcion2(valor1, valor2)\nprint(f'Valor1= {valor1}, valor2= {valor2}')\nprint(f'Valor3= {valor1}, valor4= {valor2}')\n\n\n# Por ref\ndef funcion3(valor1, valor2):\n    aux = valor1\n    valor1 = valor2\n    valor2 = aux\n    return valor1, valor2\n\nlista1 = [20, 30]\nlista2 = [40, 50]\nlista3, lista4 = funcion3(lista1, lista2)\nprint(f'lista1= {lista1}, lista2= {lista2}')\nprint(f'lista3= {lista3}, lista4= {lista4}')"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/toral24.py",
    "content": "'''\nEJERCICIO:\nMuestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\nsu tipo de dato.\nMuestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n\"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n(Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n'''\n# Paso de parametros por valor (la función realiza una copia local de la variable) -valor-\n\nvar = 22\n\ndef local(varialbe):\n    varialbe *2\n\nlocal(var)\n\nprint(var)\n\n# Se puede modificar la variable a nivel global de la siguiente forma\n\ndef ref(variable):\n    return variable*2\nvar = ref(var)\nprint(var)\n\n# Paso de parametros por referencia (la función modifica las variables de forma global) -listas-\n\nvars = [1,4,22]\n\ndef reflis(variables):\n    for i,n in enumerate(variables):\n        variables[i] *=2\n\nreflis(vars)\nprint(vars)\n\n'''\nEXTRA (opcional):\ndos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\nCada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\nEstos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\nse asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\nvariables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\nComprueba también que se ha conservado el valor original en las primeras.\n'''\n\n# Por valor\naux=0\na = 5\nb = 8\n\ndef valor(var1,var2):\n    aux = var1\n    var1 = var2\n    var2 = aux\n    return var1,var2\n\nc,d = valor(a,b)\nprint(f'variables nuevas{c,d}. variables viejas{a,b}')\n\n# por referencia\n\nvalores = [8,5]\ndef referencia(lista):\n    aux = valores[0]\n    valores[0] = valores[1]\n    valores[1] = aux\n    return lista\nauxi = referencia(valores[:])\nprint(f'variables nuevas{auxi}. variables viejas{valores}')"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/victorfer69.py",
    "content": "#VALOR Y REFERENCIA\n\n#Tipos de datos por valor\n\nmy_int_a = 10\nmy_int_b = my_int_a\nmy_int_a = 20\nprint(f\"{type(my_int_a)} y {my_int_a}\")\nprint(f\"{type(my_int_b)} y {my_int_b}\")\n\n#Tipos de datos por referencia\nmy_list_a = [10,20]\nmy_list_b = my_list_a\nmy_list_a.append(30)\nprint(my_list_a)\nprint(my_list_b)\n\n#Funciones con datos por valor\ndef my_int_func(my_int: int):\n    my_int = 20\n    print(my_int)\n\n\nmy_int_c = 10\nmy_int_func(my_int_c)\nprint(my_int_c)\n\n#Funciones con datos por referencia\ndef my_list_func(my_list: list):\n    my_list.append(30)\n    print(my_list)\n\nmy_list_3 = [10,20]\nmy_list_func(my_list_3)\nprint(my_list_3)\n\n\n#EJERCICIO EXTRA\n\ndef programa1(arg1:int, arg2:int):\n    tmp = arg1\n    arg1 = arg2\n    arg2 = tmp\n    return arg1, arg2\n\na = 1\nb = 2\nc,d = programa1(a,b)\nprint(f\"{a} y {b}\")\nprint(f\"{c} y {d}\")\n\n\ndef programa2(arg1:list, arg2:list):\n    tmp = arg1\n    arg1 = arg2\n    arg2 = tmp\n    return arg1, arg2\n\nab = [1,2]\nba = [2,1]\ncd,dc = programa2(ab,ba)\nprint(f\"{ab} y {ba}\")\nprint(f\"{cd} y {dc}\")"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/warclimb.py",
    "content": "# #05 VALOR Y REFERENCIA\n#### Dificultad: Fácil | Publicación: 29/01/24 | Corrección: 05/02/24\n\n## Ejercicio\n\n\"\"\"\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n\"\"\"\n\n# Ejemplos de asignación de variables \"por valor\" y \"por referencia\"\n# por valor\nc = 34\n\n# por referencia, asignamos una variable a otra y ambas apuntan al mismo objeto.\na = [45,420,23]\nb = a\nb.append(79)\nprint(f\"b original: {b}\")\nprint(f\"a original: {a}\")\na.append(99) #modificamos a\nprint(f\"b final: {b}\") # b sigue referenciando a \"a\" y los cambios de \"a\" afectan a \"b\"\n\n\n# ejemplo de función con variable que se le pasan por referencia\ndef doble(numero):\n    return numero * 2\n\nprint(doble(5))\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales.\n *   A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n\"\"\"\n\ndef test1 (param1, param2):\n    param1, param2 = param2, param1\n    return param1, param2\n\n\nparam1 = 5\nparam2 = 10\nprint(f\"Variables originales: {param1} y {param2}\")\n\nprint(f\"Variables nuevas: {test1(param1, param2)}\")\nprint(f\"Las variables conservan su valor: {param1} y {param2}\")"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/worlion.py",
    "content": "\"\"\"\n\nDIFICULTAD EXTRA (opcional):\nCrea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n- Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n    Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n    se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n    variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n    Comprueba también que se ha conservado el valor original en las primeras.\n\"\"\"\n\n# Asignación de variables por valor y por referencia\n\n# Variables por valor: Los enteros, por ejemplo, se asignan por valor\nprint(\"\\n ---- Variables por valor ----\\n\")\na = 10\nb = a\nprint(f\"Variable a: {a}\")   # 10\nprint(f\"Variable b: {b}\")   # 10\nb = 20\nprint(f\"Variable a: {a}\")   # 10\nprint(f\"Variable b: {b}\")   # 20\n\n# Variables por referencia: Los arrays, por ejemplo, se asignan por referencia\nprint(\"\\n ---- Variables por referencia ----\\n\")\narray1 = [10, 20, 30]\narray2 = array1\nprint(f\"Array 1: {array1}\") # [10, 20, 30]\nprint(f\"Array 2: {array2}\") # [10, 20, 30]\narray2[0] = 100\narray1.append(40)\nprint(f\"Array 1: {array1}\") # [100, 20, 30, 40]\nprint(f\"Array 2: {array2}\") # [100, 20, 30, 40]\n\n\n\"\"\"\n\nDIFICULTAD EXTRA (opcional):\nCrea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n- Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n    Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n    se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n    variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n    Comprueba también que se ha conservado el valor original en las primeras.\n\"\"\"\n\nprint(\"\\n ---- 🌩 DIFICULTAD EXTRA 🌩 ----\\n\")\n\n\n# Intercambio por valor\ndef intercambio_valor(a: int, b: int) -> tuple:\n    print(\" - Intercambio por valor - \")\n    temp = a\n    a = b\n    b = temp\n    return a,b\n\nx = 7\ny = 99\nprint(\"Antes del intercambio:\")\nprint(f\"x = {x} ; y = {y}\")\nnew_x, new_y = intercambio_valor(x, y)\nprint(\"Tras el intercambio:\")\nprint(f\"x = {x} ; y = {y}\")\nprint(f\"new_x = {new_x} ; new_y = {new_y}\")\n\n# Intercambio por referencioa\ndef intercambio_referencia(a: list, b: list) -> tuple:\n    print(\" - Intercambio por referencia - \")\n    temp = a\n    a = b\n    b = temp\n    return a,b\n\nx = [7, 8]\ny = [99, 0]\nprint(\"Antes del intercambio:\")\nprint(f\"x = {x} ; y = {y}\")\nnew_x, new_y = intercambio_referencia(x, y)\nprint(\"Tras el intercambio:\")\nprint(f\"x = {x} ; y = {y}\")\nprint(f\"new_x = {new_x} ; new_y = {new_y}\")"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/xemita007.py",
    "content": "##05 VALOR Y REFERENCIA\n#### Dificultad: Fácil | Publicación: 29/01/24 | Corrección: 05/02/24\n\n## Ejercicio\n\n#por valor , solo nos quedamos con el valor\nvar = 5\n\nvar2 = var\n\nprint(\"por valor la variable var \",var, \"y valor de var2 debe ser el mismo \",var2)\n\nvar=10\n\nprint(\"por valor la variable var \",var, \"y valor de var2 debe ser el mismo que al principio \",var2)\n\n#por referencia listas y diccionarios\n\n\n\ndef lista_añadir(var3,lista: list):\n    lista.append(var3)\n    print(\"valor de lista de la función \",lista)\n\nmi_lista = [1,2,3]\nlista_añadir(4,mi_lista)\n\nprint(\"valor de lista fuera de función \",mi_lista)\n\nlista2=[1,2,3]\n\nlista3= lista2\n\nlista2.append(5)\nlista3.append(6)\n\nlista3.sort()\n\nprint(lista2)\nprint(lista3)\n\ndef valor (v1,v2):\n    vp=v1\n    v1=v2\n    v2=vp\n    return v1,v2\n\nv3=10\nv4=20\nv5, v6 = valor(v3,v4)\n\nprint(f\"{v3}, {v4}\")\n\nprint(f\"{v5}, {v6}\")"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/ycanas.py",
    "content": "## I. Ejercicio\n\n# 1. Asignación de variables\n\n# por valor\n\nmy_int_a = 1\nmy_int_b = my_int_a\nmy_int_b = 2\n\nprint(my_int_a, my_int_b)\n\n# por referencia\n\nmy_list_a = [1]\nmy_list_b = my_list_a\nmy_list_b.append(2)\n\nprint(my_list_a, my_list_b)\n\n# 2. Funciones\n\n# por valor\n\ndef my_func_a(my_var):\n    my_var = 2\n    return my_var\n\n\nmy_var_a = 1\nmy_var_b = my_func_a(my_var_a)\nprint(my_var_a, my_var_b)\n\n# por referencia\n\ndef my_func_b(my_var):\n    my_var.append(2)\n    return my_var\n\nmy_var_c = [1]\nmy_var_d = my_func_b(my_var_c)\nprint(my_var_c, my_var_d)"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/yenneralayon142.py",
    "content": "\"\"\"\nValor y referencia\n\"\"\"\n#Tipos de datos por valor\na = 10\nb = a\nb = 20\nprint(a) #El espacio de memoria es independiente\nprint(b)\n#Tipos de datos por referencia\nlist_a = [10,20]\nlist_b = list_a\nlist_b.append(40)\nprint(list_a) #EL espacio de memoria no es independiente, b pasa a ocupar el espacio de memoria de a \nprint(list_b) \n#Funciones con datos por valor\ndef valor(a:int):\n     a = 20\n     print(a)\nb = 10\nvalor(b)\nprint(b) # El espacio de memoria es independiente\n#Funciones con datos por referencia\ndef my_list_reference(my_list:list):\n     my_list.append(30)\n     my_list_d = my_list\n     my_list_d.append(40)\n     print(my_list)\n     print(my_list_d)\nmy_list_c = [10,20]\nmy_list_reference(my_list_c)\nprint(my_list_c) # El espacio de memoria no es independiente, todo funciona con un mismo puntero\n\"\"\"\nEXTRA\n\"\"\"\n#Por valor\ndef exercise_value(value_a:int,value_b:int) -> tuple:\n     temp = value_a\n     value_a = value_b\n     value_b = temp\n     return value_a,value_b\nmy_int_d = 10\nmy_int_e = 20\nmy_int_f, my_int_g = exercise_value(my_int_d, my_int_e)\nprint(f\"{my_int_d}, {my_int_e}\")\nprint(f\"{my_int_f}, {my_int_g}\")\n#Por referencia\ndef exercise_value(value_a:list,value_b:list) -> tuple:\n     temp = value_a\n     value_a = value_b\n     value_b = temp\n     return value_a,value_b\nmy_list_e = [10, 20]\nmy_list_f = [30, 40]\nmy_list_g, my_list_h = exercise_value(my_list_e, my_list_f)\nprint(f\"{my_list_e}, {my_list_f}\")\nprint(f\"{my_list_g}, {my_list_h}\") #Toma dos punteros por la variable auxiliar\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/yoezequiel.py",
    "content": "# Asignación por valor\nx = 10\ny = x  # Se copia el valor de x en y\ny = 20  # Cambiamos el valor de y\nprint(x)  # Imprime 10, el valor original de x no se ve afectado\n# Asignación por referencia\nlista1 = [1, 2, 3]\nlista2 = lista1  # Ambas variables apuntan a la misma lista en memoria\nlista2.append(4)  # Modificamos lista2\nprint(lista1)  # Imprime [1, 2, 3, 4], la lista original se ve afectada\n\n\ndef modificar_valor(num):\n    num += 10  # Se modifica el valor de la variable local num\n    print(\"Dentro de la función:\", num)\n\n\nx = 5\nmodificar_valor(x)\nprint(\"Fuera de la función:\", x)  # Imprime 5, el valor original de x no se ve afectado\n\n\ndef modificar_lista(lista):\n    lista.append(4)  # Modifica la lista pasada como parámetro\n    print(\"Dentro de la función:\", lista)\n\n\nmi_lista = [1, 2, 3]\nmodificar_lista(mi_lista)\nprint(\n    \"Fuera de la función:\", mi_lista\n)  # Imprime [1, 2, 3, 4], la lista original se ve afectada\n\n\ndef intercambiar_valores_por_valor(a, b):\n    temp = a\n    a = b\n    b = temp\n    return a, b\n\n\nx = 10\ny = 20\n\nx, y = intercambiar_valores_por_valor(x, y)\n\n# Imprimimos los valores originales y los nuevos\nprint(\"Valores originales:\")\nprint(\"x =\", x)\nprint(\"y =\", y)\n\n\ndef intercambiar_valores_por_referencia(lista):\n    # Intercambiamos los valores de la lista\n    lista[0], lista[1] = lista[1], lista[0]\n    return lista\n\n\nmi_lista = [10, 20]\n\nnueva_lista = intercambiar_valores_por_referencia(mi_lista[:])\n\nprint(\"Valores originales:\")\nprint(\"mi_lista =\", mi_lista)\nprint(\"nueva_lista =\", nueva_lista)\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/python/zetared92.py",
    "content": "# VALOR Y REFERENCIA\n\n# Tipos de datos por valor\nint_a = 10\nint_b = int_a\nint_b = 20\n\nprint(int_a)\nprint(int_b)\n\n# Tipos de dato por referencia\nlist_a = [10, 20]\nlist_b = list_a\nlist_b.append(30)\n\nprint(list_a)\nprint(list_b)\n\n# Funciones con datos por valor\ndef int_func(my_int: int):\n    my_int = 20\n    print(my_int)\n\nint_c = 10\nint_func(int_c)\nprint(int_c)\n\n# Funciones con datos por referencia\ndef list_func(my_list: list):\n    my_list.append(30)\n\n    list_d = my_list\n    list_d.append(40)\n\n    print(my_list)\n    print(list_d)\n\nlist_c = [10, 20]\nlist_func(list_c)\nprint(list_c)\n\n# Extra\n\nprint(\"🧩 DIFICULTAD EXTRA 🧩\")\n# Por valor\n\ndef value(value_x: int, value_y: int) -> tuple:\n    tmp = value_x\n    value_x = value_y\n    value_y = tmp\n    return value_x, value_y\n\nint_a = 10\nint_b = 20\nint_c, int_d = value(int_a, int_b)\n\n# Por referencia\n\ndef ref(value_x: list, value_y: list) -> tuple:\n    tmp = value_x\n    value_x = value_y\n    value_y = tmp\n    return value_x, value_y\n\nlist_a = [10, 20]\nlist_b = [30, 40]\nlist_c, list_d = ref(list_a, list_b)\nprint(f\"{list_a}, {list_b}\")\nprint(f\"{list_c}, {list_d}\")"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/ruby/kodenook.rb",
    "content": "\n=begin\n    Assignment By Value\n=end\n\nvar1 = 3\nvar2 = var1\n\nvar1 = 5\n\nputs var1\nputs var2\n\n=begin\n    Assignment By Assignment\n=end\n\nvar1 = [10, 30]\nvar2 = var1\n\nvar1.push(50)\n\nputs var1\nputs var2\n\n=begin\n    Exercise\n=end\n\ndef ByValue(a, b)\n    c = b\n    d = a\n\n    return c, d\nend\n\noriginal1 = 20\noriginal2 = 30\nvalue1, value2 = ByValue(original1, original2)\n\nputs 'By Values'\nputs 'Original Values'\nputs original1\nputs original2\nputs 'After Function Values'\nputs value1\nputs value2\n\ndef ByReference(a, b)\n    c = b\n    d = a\n\n    return c, d\nend\n\noriginal1 = 20\noriginal2 = 30\nvalue1, value2 = ByReference(original1, original2)\n\nputs 'By Values'\nputs 'Original Values'\nputs original1\nputs original2\nputs 'After Function Values'\nputs value1\nputs value2\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/rust/brockar.rs",
    "content": "/*\nEJERCICIO:\n- Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\nsu tipo de dato.\n- Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y\n\"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n*/\n\nfn main() {\n    // Asignación por valor\n    let x: u8 = 5;\n    let y;\n    y = 14;\n\n    println!(\"x: {}, y: {}\", x, y);\n\n    // Asignación por valor a un array\n    let mut array: [u8; 5] = [1, 2, 3, 4, 5];\n    println!(\"array: {:?}\", array);\n    array[0] = 4;\n    println!(\"array1: {:?}\", array);\n\n    // Asignación por referencia\n    let mut z = 2;\n    let p = &mut z; // referencia\n    let r = *p;\n    *p = 4;\n    println!(\"z: {}, r: {}\", z, r);\n\n    // Funciones\n    /*\n    // Una vez que se pasa una variable por referencia, la variable original no se puede usar más.\n    // Lo comento porque no compila\n    let mut value = String::from(\"hello\");\n    let ref1 = &mut value;\n    let ref2 = &mut value;\n    println!(\"{}, {}\", ref1, ref2);\n    */\n    let mut s = String::from(\"hello\");\n    up(&mut s);\n    println!(\"{}\", s);\n\n    // Extra\n    // Funcion por parámetros\n    println!(\"EXTRA\");\n\n    let a = 1;\n    let b = 2;\n\n    fn swap_v(a: i32, b: i32) -> (i32, i32) {\n        (b, a)\n    }\n    println!(\"a:{}, b:{}\", a, b);\n    swap_v(a, b);\n    println!(\"post swap_v\\na:{}, b:{}\", a, b);\n\n    // Funcion por referencia\n    let mut c = 3;\n    let mut d = 4;\n\n    fn swap_r(c: &mut i32, d: &mut i32) {\n        let temp = *c;\n        *c = *d;\n        *d = temp;\n    }\n\n    println!(\"\\nc:{}, d:{}\", c, d);\n    swap_r(&mut c, &mut d);\n    println!(\"post swap_r\\nc:{}, d:{}\", c, d);\n}\n\nfn up(s: &mut String) {\n    s.make_ascii_uppercase();\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/rust/gabrielmoris.rs",
    "content": "/*EXERCISE:\n* Provide examples of variable assignment \"by value\" and \"by reference\" based on their data type.\n* Demonstrate functions with variables passed \"by value\" and \"by reference,\" and how they behave when modified in each case.\n(Understanding these concepts is essential in the majority of programming languages)\n*/\n\nfn main() {\n    // ================= Assignment by Value: =================\n    //  When a variable is assigned by value, the actual value is copied from one variable to another.\n    // Ownership of the value is transferred.\n    let x = 42; // x is an integer\n    let _y = x; // y receives a copy of the value in x\n\n    // ================= Assignment by Reference (Borrowing): =================\n    //When a variable is assigned by reference, we create a reference (or borrow) to the original value.\n    // The original value remains owned by the original variable. References are denoted by the & symbol.\n    let s1 = String::from(\"hello\");\n    let _len = calculate_length(&s1); // The &s1 syntax creates a reference to the value of s1 without taking ownership.\n\n    fn calculate_length(s: &String) -> usize {\n        // calculate_length takes a reference to a String as its parameter (&String).\n        s.len()\n        // The value pointed to by the reference (s) is not dropped when the reference goes out of scope.\n    }\n\n    // ================= Modifying Borrowed Values: =================\n    // When modifying a borrowed value, Rust enforces strict rules\n    // 1. Immutable Borrow: If a value is borrowed immutably (using &), it cannot be modified.\n    // 2. Mutable Borrow: If a value is borrowed mutably (using &mut), it can be modified.\n\n    let mut str = String::from(\"hello\");\n\n    modify_string(&mut str);\n    fn modify_string(s: &mut String) {\n        //  takes a mutable reference (&mut String).\n        s.push_str(\", world!\"); // We can modify the borrowed s by appending “, world!” to it.\n    }\n    // The original str is updated after the function call.\n    println!(\"{str}\");\n\n    // ================= Lifetime Parameters: =================\n    // Rust uses lifetimes to manage memory safety and ensure that references remain valid.\n    // When you see 'a in a function signature or struct definition, it indicates that the function or struct is generic over a specific lifetime.\n    // You can annotate references with lifetimes using the 'a syntax. For example, &'a str denotes a reference to a string with a lifetime 'a.\n    // Person has a lifetime parameter 'a, indicating that the name field must live at least as long as 'a\n    struct _Person<'a> {\n        name: &'a str,\n    }\n\n    /*EXTRA CHALLENGE (optional):\nCreate two programs that receive two parameters each, defined as previously assigned variables.\n* In one case, the programs receive two parameters by value, and in the other case, by reference.\n* Inside the programs, swap the values of these parameters, return them, and assign the returned values to \n* two different variables from the originals.\n* Finally, print the values of the original variables and the new ones, verifying that the values have been inverted in the latter.\n* Also, confirm that the original values are preserved in the former.\n*/\n\n    let value1 = String::from(\"Value1\");\n    let value2 = String::from(\"Value2\");\n\n    let (value_changed1, value_changed2) = swap_by_value(value1, value2);\n\n    // println!(\"Original value1: {}\", value1); // Because the reference is lost affter sending it to the function, is no longer accessible\n    // println!(\"Original value2: {}\", value2); // Because the reference is lost affter sending it to the function, is no longer accessible\n    println!(\"Swapped value1: {}\", value_changed1); // Should print \"Value2\"\n    println!(\"Swapped value2: {}\", value_changed2); // Should print \"Value1\"\n\n    let reference1 = String::from(\"Reference1\");\n    let reference2 = String::from(\"Reference2\");\n    let (new_reference1, new_reference2) = swap_by_reference(&reference1, &reference2);\n\n    println!(\"Original reference1: {}\", reference1);\n    println!(\"Original reference2: {}\", reference2);\n    println!(\"Swapped reference1: {}\", new_reference1); // Should print \"eference2\"\n    println!(\"Swapped reference2: {}\", new_reference2); // Should print \"reference1\"\n\n    fn swap_by_value(mut str1: String, mut str2: String) -> (String, String) {\n        let temporal = str1.clone();\n        str1.clear(); // Clear str1\n        str1.push_str(&str2); // Assign str2 to str1\n        str2.clear(); // Clear str2\n        str2.push_str(&temporal); // Assign the clone of str1 (temporal) to str2\n\n        (str1, str2)\n    }\n\n    // 'a represents a lifetime parameter. It indicates that the function or struct is generic over a specific lifetime.\n    // For example, &'a str denotes a reference to a string with a lifetime 'a.\n    fn swap_by_reference<'a>(str1: &'a str, str2: &'a str) -> (&'a str, &'a str) {\n        (str2, str1)\n    }\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/rust/kenysdev.rs",
    "content": "// no advertencia\n#![allow(unused_variables)]\n#![allow(unused_assignments)]\nuse std::collections::HashSet;\n/*\n╔═══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado                ║\n║ GitHub: https://github.com/Kenysdev   ║\n║ 2024 -  Rust                          ║\n╚═══════════════════════════════════════╝\n-----------------------------------------\n* VALOR Y REFERENCIA\n-----------------------------------------\n- Un valor es simplemente un dato que ocupa un espacio de memoria.\n- Los valores pueden ser de dos tipos principales(tipos primitivos y tipos compuestos).\n- Los valores son propietarios de su propio espacio de memoria.\n\n- Las referencias son una forma de \"prestar\" un valor sin transferir la propiedad del mismo.\n- Una referencia simplemente \"apunta\" al valor original en la memoria de ese valor.\n- Las referencias pueden ser Mutables o inmutables.\n*/\nfn main() {\n    // _________________________________________________________________\n    // * ASIGNAR POR VALOR\n    // * Tipos con (trail 'copy') que se copian al asignarse.\n    // * Tipos primitivos\n    let num: u8 = 12; // ,i->n, u->n\n    let assign_num: u8 = num;\n\n    let float: f32 = 12.21; // ,f64\n    let assign_float: f32 = float;\n\n    let chr: char = 'a';\n    let assign_chr: char = chr;\n\n    let boolean: bool = true;\n    let assign_boolean: bool = boolean;\n    \n    // * Tipos Compuestos\n    // * los quee contienen tipos primitivos.\n    let tuple: (u8, bool, char) = (num, boolean, chr);\n    let assign_tuple: (u8, bool, char) = tuple;\n\n    let array: [u8; 3] = [1, 2, 3];\n    let assign_array: [u8; 3] = array;\n\n    // _________________________________________________________________\n    // * ASIGNAR EL VALOR MOVIENDO LA PROPIEDAD\n    // * Son los tipos que no tienen (trail 'copy').\n    // * Despues de moverse, la la variable original ya no sera válida.\n    let original_string: String = String::from(\"Ken\");\n    let assign_string: String = original_string;\n    //println!(\"{original_string}\"); // ya no es valida\n\n    let original_vector: Vec<u8> = vec![1, 2, 3];\n    let assign_vector: Vec<u8> = original_vector;\n    //println!(\"{:?}\", original_vector); // ya no es valida\n\n    let original_set: HashSet<u8> = vec![1, 2, 3].into_iter().collect();\n    let assign_set: HashSet<u8> = original_set;\n    //println!(\"{:?}\", original_set); // ya no es valida\n\n    // _________________________________________________________________\n    // * ASIGNAR POR REFERENCIA INMUTABLE\n    // * La mayoria de tipos pueden asignarse por referencia.\n    // Se asigna usando '&'.\n    let num: u8 = 12;\n    let assign_num: &u8 = &num;\n\n    let original_string: String = String::from(\"REFERENCIA INMUTABLE\");\n    let assign_string: &String = &original_string;\n    println!(\"{original_string}\"); // 'original_string' aun es valida.\n\n    let array: [u8; 3] = [1, 2, 3];\n    let assign_array: &[u8; 3] = &array;\n    println!(\"{:?}\", array); // 'array' aun es valida.\n\n    // _________________________________________________________________\n    // * ASIGNAR POR REFERENCIA MUTABLE\n    // - Solo es posible con aquellos tipos que pueden mutar.\n    // - se asigna usando '&mut' y se modifica aplicando desreferencia con '*'\n    let mut num: u8 = 12;\n    let assign_num: &mut u8 = &mut num;\n    *assign_num = 77;\n    println!(\"{num}\"); // Los cambios afectaron a 'num'.\n\n    let mut original_string: String = String::from(\"Ben\");\n    let assign_string: &mut String = &mut original_string;\n    *assign_string = String::from(\"REFERENCIA MUTABLE\");\n    println!(\"{original_string}\"); // Los cambios afectaron a 'original_string'.\n\n    let mut original_vector: Vec<char> = vec!['a', 'b', 'c'];\n    let assign_vector: &mut Vec<char> = &mut original_vector;\n    assign_vector.push('d');\n    println!(\"{:?}\", original_vector); // Los cambios afectaron a 'original_vector'.\n\n    // _________________________________________________________________\n    // * DEMOSTRACIÓN EN FUNCIONES\n    // Pasando por valor\n    let original_bool: bool;\n\n    original_bool = true;\n    fn by_val(mut boolean: bool) {\n        boolean = false;\n    }\n    by_val(original_bool);\n    println!(\"Value: {original_bool}\"); // no afecto a 'original_bool'\n\n    // Pasando por referencia\n    let mut original_bool: bool = true;\n\n    fn by_ref( boolean: &mut bool) {\n        *boolean = false;\n    }\n    by_ref(&mut original_bool);\n    println!(\"Reference: {original_bool}\"); // si afecto a 'original_bool'\n\n\n/* _________________________________________________________________\n* Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n* Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n* Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n* se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n* variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n* Comprueba también que se ha conservado el valor original en las primeras.\n*/\n\nlet num1: i8 = 1;\nlet num2: i8 = 2;\nlet new_nums: (i8, i8) = by_value(num1, num2);\nprintln!(\"Originales: {num1}, {num2}\");\nprintln!(\"Nuevas: {:?}\", new_nums);\n\nlet mut vec1: Vec<char> = vec!['a', 'b'];\nlet mut vec2: Vec<char> = vec!['c', 'd'];\nlet new_vecs: (Vec<char>, Vec<char>) = by_reference(&mut vec1, &mut vec2);\nprintln!(\"Originales: {:?}, {:?}\", vec1, vec2);\nprintln!(\"Nuevas: {:?}\", new_vecs);\n   \n}\n\nfn by_value(mut num1: i8,mut num2: i8) -> (i8, i8) {\n    let tmp: i8 = num1;\n    num1 = num2;\n    num2 = tmp;\n    return (num1, num2)\n}\n\nfn by_reference(vec1: &mut Vec<char>, vec2: &mut Vec<char>) -> (Vec<char>, Vec<char>) {\n    let vec_1: Vec<char> = vec2.clone();\n    let vec_2: Vec<char> = vec1.clone();\n    return (vec_1, vec_2);\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/rust/raulfauli.rs",
    "content": "/// #05 VALOR Y REFERENCIA\n///\n/// `rustc ./Roadmap/05\\ -\\ VALOR\\ Y\\ REFERENCIA/rust/raulfauli.rs && ./raulfauli && rm raulfauli`\n///\nfn main() {\n\n  // Paso por valor un tipo primitivo\n  let mut foo = 42;\n  let f = foo;\n  foo = 13;\n  println!(\"{}\", f); // 42\n  println!(\"{}\", foo); // 13\n\n  // Paso por valor una lista\n  let mut list = [1, 2, 3];\n  let l = list;\n  list[0] = 4;\n  println!(\"{:?}\", l); // [1, 2, 3]\n\n  // Paso por referencia\n  let mut foo = 42;\n  let f = &mut foo;\n  let bar = *f; // guardo el valor de la referencia\n  *f = 13;      // modifico el valor de la referencia\n  println!(\"{}\", bar); // 42\n  println!(\"{}\", foo); // 13\n\n  // Paso por referencia una lista\n  let mut list = [1, 2, 3];\n  let l = &mut list;\n  let bar = &mut l[0]; // guardo la referencia\n  *bar = 4;            // modifico el valor de la referencia\n  println!(\"{:?}\", l); // [4, 2, 3]\n\n\n\n  // Funciones con paso por referencia\n  fn to_upper(s: &mut String) {\n    s.make_ascii_uppercase();\n  }\n\n  let mut hola = String::from(\"hola\");\n  to_upper(&mut hola);\n  println!(\"{hola}\"); // HOLA\n\n\n  // Extra\n  let mut a = 1;\n  let mut b = 2;\n\n  fn swap_values(a: i32, b: i32) -> (i32, i32) {\n    (b, a)\n  }\n\n  let (c, d) = swap_values(a, b);\n\n  println!(\"a: {a}, b: {b}\"); // a: 1, b: 2\n  println!(\"c: {c}, d: {d}\"); // c: 2, d: 1\n\n  fn swap_references(a: &mut i32, b: &mut i32) {\n    let t = *a;\n    *a = *b;\n    *b = t;\n  }\n\n  swap_references(&mut a, &mut b);\n  println!(\"a: {a}, b: {b}\"); // a: 2, b: 1\n}\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/scala/rianojnicolas.scala",
    "content": "/*###################################\n#   Dev: rianojnicolas              #\n###################################*/\nimport scala.collection.mutable.ArrayBuffer\n\nobject Source5 {\n    def main(args: Array[String]): Unit = {\n\n        // 1. Asignacion de variables por valor y referencia\n    \n        // En Scala, todas las variables y parámetros de funciones se pasan por valor.\n        // Esto significa que siempre se pasa una copia de lo que contiene la variable\n        //  a. Para tipos primitivos como Int, Double, Boolean, etc., la copia es simplemente el valor en sí.\n        //  b. Para objetos (listas, clases, arrays, etc.), la copia es la referencia al objeto, no el objeto\n        //     completo. Entonces, aunque la referencia se pasa por valor, ambas variables (la original y la\n        //     copia) apuntan al mismo objeto en memoria.\n        //\n        // Aunque Scala fomenta el uso de inmutabilidad (con val), las variables mutables (definidas con var)\n        // permiten cambiar la referencia que almacenan, lo que significa que puedes hacer que una variable\n        // apunte a un objeto diferente.\n        // \n        // Mutabilidad e inmutabilidad: Si bien las variables val son inmutables (no pueden cambiar de \n        // referencia), si el objeto que apuntan es mutable, el contenido del objeto puede cambiar.\n        \n        // 1.1 Variables por valor\n        \n        println(\"1. Asignacion de variables por valor - para tipos primitivos\")\n\n        // var\n        println(\"1.1.a Asignacion de variables por valor con definicion var\")\n        var myIntA = 10\n        var myIntB = myIntA\n        //myIntB = 20\n        myIntA = 50\n        println(myIntA)\n        println(myIntB)\n        println(\"\\n\")\n\n        // val\n        println(\"1.1.b Asignacion de variables por valor con definicion val\")\n        val myIntC = 10\n        val myIntD = myIntC\n        // myIntD = 20 // Error: val cannot be reassigned\n        // myIntC = 50 // Error: val cannot be reassigned\n        println(myIntC)\n        println(myIntD)\n        println(\"\\n\")\n\n        // 1.2 Variables por referencia\n        println(\"1.2 Variables por referencia\")\n        //   Como se explicó anteriormente, en Scala no existe la dinamica de variables por referencia, pero a nivel\n        //   de objetos, las variables son referencias a objetos. Es decir que una copia del objeto es la referencia\n        //   al objeto, no el objeto completo.\n        //   Por ejemplo: Cuando se trabaja con objetos (especialmente los mutables), aunque técnicamente se están \n        //       pasando referencias por valor, la referencia apunta al mismo objeto.\n        //   Ahora a nivel codigo sería algo así:\n        println(\"1.2.a. Variables por referencia con definicion val, objeto mutable:\")\n        // Se utiliza una variable de tipo val \"inmutable\" para definir una referencia a un objeto. Pero\n        // en este caso, el objeto es mutable, por lo que puedes modificar su contenido.\n        // En este caso, la referencia apunta al mismo objeto que el objeto original.\n        val array1 = ArrayBuffer(1, 2, 3)\n        val array2 = array1  // Ambas referencias apuntan al mismo objeto\n        array2 += 4  // Modificamos el objeto referenciado\n        println(array1)  // Imprime ArrayBuffer(1, 2, 3, 4)\n        \n        println(\"1.2.b. Variables por referencia con definicion var, objeto mutable:\")\n        // Pero si utilizamos una variable de tipo var, la referencia tambien apunta al objeto original.\n        var array3 = ArrayBuffer(4,5,6)  \n        var array4 = array3  // La referencia apunta al mismo objeto\n        array4 += 7  // Modificamos el objeto referenciado\n        println(array3)  // Imprime ArrayBuffer(4, 5, 6, 7)\n        println(array4)  // Imprime ArrayBuffer(4, 5, 6, 7)\n\n        println(\"1.2.c. Variables por referencia con definicion var, objeto inmutable:\")\n        // Pero si utilizamos una variable de tipo var, con un objeto Lista que es inmutable,\n        // la referencia sigue apuntando al objeto original. pero si \"modificamos el objeto\"\n        // referenciado, la referencia no cambia porque este tipo de objeto no permite modificaciones. Por lo tanto,\n        // el objeto original sigue siendo el mismo objeto y se crea una copia nueva con la modificacion.\n        var my_listA = List(10, 20)\n        var my_listB = my_listA  // La referencia apunta al mismo objeto\n        println(\"my_listA - inicial : \" + my_listA) // Imprime List(10, 20)\n        println(\"my_listB - inicial : \" + my_listB) // Imprime List(10, 20)\n        my_listB :+ 50 // Modificamos el objeto referenciado, crea un NUEVO objeto List(10, 20, 50)\n        println(\"my_listA - Final : \" + my_listA) // Imprime List(10, 20)\n        println(\"my_listB - Final : \" + my_listB) // Imprime List(10, 20, 50)\n\n        // 2. Ejemplos de funciones por valor y por referencia\n        println(\"2. Ejemplos de funciones por valor y por referencia\")\n\n        // 2.1 Funciones con datos por valor\n        println(\"2.1 Funciones con datos por valor\")\n        def fillCoupValue(fill: Int): Int = {\n            // El parametro fill Scala lo toma por valor, por lo que no se puede modificar\n            // Por lo tanto, creamos una variable mutable\n            var modifiedFill = fill \n            val fill1 = 99 \n            modifiedFill = fill1 // Modificamos el valor de la variable\n            println(modifiedFill) // Imprime 99\n            return modifiedFill // Devuelve el valor 99\n        }\n        \n        var my_fill = 50\n        fillCoupValue(my_fill) // Modificamos el valor de la variable con el valor 99\n        println(my_fill) // Imprime 50\n\n        //2.2 Funciones con datos por referencia\n        println(\"2.2 Funciones con datos por referencia\")\n        // Como se explicó anteriormente, en Scala no existe la dinamica de variables por referencia o de\n        // funciones con datos por referencia, pero a nivel de objetos, las variables son referencias a objetos.\n        // Es decir que una copia del objeto es la referencia al objeto, no el objeto completo.\n        \n        def fillCoupHistory(fill: ArrayBuffer[Int]):ArrayBuffer[Int] = {\n            fill += 25 \n            \n            val fill_a = fill\n            fill_a += 45\n\n            println(fill)\n            println(fill_a)\n            return fill\n        }\n\n        val my_fill_history = ArrayBuffer(0, 10, 5, 50, 20)\n        fillCoupHistory(my_fill_history)\n        println(my_fill_history)\n        \n        // Dificultad Extra\n        // Caso 1: Parametros por valor\n        def byValue(a: Int, b: Int):(Int, Int) = {\n            var a_mod = a\n            var b_mod = b\n            val c = a_mod\n            a_mod = b_mod\n            b_mod = c\n            return (a_mod, b_mod)\n        }\n\n        // Caso 2: Parametros por referencia\n        def byRefer(a: ArrayBuffer[Int], b: ArrayBuffer[Int]):(ArrayBuffer[Int], ArrayBuffer[Int]) = {\n            var a_mod = a\n            var b_mod = b\n            val c = a_mod\n            a_mod = b_mod\n            b_mod = c\n            return (a_mod, b_mod)\n        }\n        \n        // Ejecucion final\n        def run(): Unit = {\n            // Caso 1: Parametros por valor\n            var my_val_1 = 10\n            var my_val_2 = 20\n            val (my_val_3, my_val_4) = byValue(my_val_1, my_val_2)\n            println(\"Los valores retornados son: \")\n            println(my_val_3)\n            println(my_val_4)\n            println(\"Los valores originales son: \")\n            println(my_val_1)\n            println(my_val_2)\n\n            // Caso 2: Parametros por referencia\n            var my_ref_1 = ArrayBuffer(10, 30, 50)\n            var my_ref_2 = ArrayBuffer(20, 40, 60)\n            val (my_ref_3, my_ref_4) = byRefer(my_ref_1, my_ref_2)\n            println(\"Los valores retornados son: \")\n            println(my_ref_3)\n            println(my_ref_4)\n            println(\"Los valores originales son: \")\n            println(my_ref_1)\n            println(my_ref_2)\n\n        }\n        \n        run()\n    }\n}"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/sql/Nicojsuarez2.sql",
    "content": "# #05 VALOR Y REFERENCIA\n> #### Dificultad: Fácil | Publicación: 29/01/24 | Corrección: 05/02/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/sql/eulogioep.sql",
    "content": "-- Creación de tablas\nCREATE TABLE Empleados (\n    id INT PRIMARY KEY,\n    nombre VARCHAR(50),\n    salario DECIMAL(10, 2)\n);\n\nCREATE TABLE Departamentos (\n    id INT PRIMARY KEY,\n    nombre VARCHAR(50),\n    jefe_id INT,\n    FOREIGN KEY (jefe_id) REFERENCES Empleados(id)\n);\n\n-- Inserción de datos\nINSERT INTO Empleados (id, nombre, salario) VALUES\n(1, 'Juan', 50000),\n(2, 'María', 60000),\n(3, 'Carlos', 55000);\n\nINSERT INTO Departamentos (id, nombre, jefe_id) VALUES\n(1, 'Ventas', 1),\n(2, 'Marketing', 2);\n\n-- Analogía de \"paso por valor\"\n-- Actualizar el salario de un empleado\nUPDATE Empleados\nSET salario = salario * 1.1\nWHERE id = 1;\n\n-- Verificar el cambio\nSELECT * FROM Empleados WHERE id = 1;\n\n-- Analogía de \"paso por referencia\"\n-- Cambiar el jefe de un departamento\nUPDATE Departamentos\nSET jefe_id = 3\nWHERE id = 1;\n\n-- Verificar el cambio\nSELECT d.nombre AS Departamento, e.nombre AS Jefe\nFROM Departamentos d\nJOIN Empleados e ON d.jefe_id = e.id\nWHERE d.id = 1;\n\n-- Procedimiento almacenado para simular \"paso por valor\"\nDELIMITER //\nCREATE PROCEDURE AumentarSalario(IN empleado_id INT, IN aumento DECIMAL(10, 2))\nBEGIN\n    DECLARE salario_actual DECIMAL(10, 2);\n    \n    -- Obtener el salario actual\n    SELECT salario INTO salario_actual FROM Empleados WHERE id = empleado_id;\n    \n    -- Aumentar el salario (solo dentro del procedimiento)\n    SET salario_actual = salario_actual + aumento;\n    \n    -- Mostrar el nuevo salario (que no afecta a la tabla real)\n    SELECT salario_actual AS NuevoSalario;\nEND //\nDELIMITER ;\n\n-- Procedimiento almacenado para simular \"paso por referencia\"\nDELIMITER //\nCREATE PROCEDURE CambiarJefeDepartamento(IN departamento_id INT, IN nuevo_jefe_id INT)\nBEGIN\n    -- Actualizar el jefe del departamento (afecta a la tabla real)\n    UPDATE Departamentos SET jefe_id = nuevo_jefe_id WHERE id = departamento_id;\n    \n    -- Mostrar el cambio\n    SELECT d.nombre AS Departamento, e.nombre AS NuevoJefe\n    FROM Departamentos d\n    JOIN Empleados e ON d.jefe_id = e.id\n    WHERE d.id = departamento_id;\nEND //\nDELIMITER ;\n\n-- Ejemplos de uso de los procedimientos\nCALL AumentarSalario(1, 5000);\nSELECT * FROM Empleados WHERE id = 1;  -- El salario real no cambia\n\nCALL CambiarJefeDepartamento(2, 3);\nSELECT * FROM Departamentos WHERE id = 2;  -- El jefe sí cambia en la tabla real"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/swift/18miguelgalarza.swift",
    "content": "//: [Previous](@previous)\n\n\n/* 18miguelgalarza.swift Release #05 - swift\n * EJERCICIO: #05 VALOR Y REFERENCIA\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato. .......ok\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y\n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\n\nimport Foundation\n\nvar greeting = \"Hello, playground\"\n\n//Asignacion por valor\n// Tipo de dato: Int (tipo primitivo)\nvar numero1 = 10\nvar numero2 = numero1 // Asignación por valor, se crea una copia independiente de numero1\n\nnumero1 = 20 // Cambiar el valor de numero1 no afecta a numero2\n\nprint(numero1) // Salida: 20\nprint(numero2) // Salida: 10 (se mantiene igual)\n\n\n//Asignacion por referencia\n\nclass Persona {\n    var nombre: String\n    \n    init(nombre: String) {\n        self.nombre = nombre\n    }\n}\n\n// Crear dos instancias de la clase Persona\nlet persona1 = Persona(nombre: \"Juan\")\nlet persona2 = persona1 // Asignación por referencia, persona2 apunta a la misma instancia que persona1\n\n// Modificar el nombre de persona1\npersona1.nombre = \"Pedro\"\n\n// Imprimir los nombres de ambas personas\nprint(\"Nombre de persona1:\", persona1.nombre) // Output: Pedro\nprint(\"Nombre de persona2:\", persona2.nombre) // Output: Pedro, ya que ambas variables apuntan a la misma instancia\n\n// FUNCIONES\n\n\n// Función variable por valor 01\nfunc concatenar(_ subcadena: String) -> String {\n    subcadena + \" birthday\"\n}\n// Asigna el retorno de la función a la variable valueVariable3\nvar variable = concatenar(_: \"Happy\")\n// Imprime el valor de la variable valueVariable1\nprint(variable)\n\n\n\n/** DIFICULTAD EXTRA (opcional):\n* Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n* - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n*   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n*   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n*   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n*   Comprueba también que se ha conservado el valor original en las primeras.\n*/\n\n// Asignación por valor 02\nfunc setValues(x: String, y: String) -> (String, String){\n    return (y, x)\n}\n\nvar input = \"morning\"\nvar input0 = \"night\"\nvar (output, output1) = setValues(x: input, y: input0)\nprint(\"original values \\(input) and \\(input0)\")\nprint(\"new values \\(output) and \\(output1)\")\n\n//Asignación por referencia\nfunc intercambioPorReferencia(x: inout String, y: inout String) -> (String, String){\n    let temporal = x\n    x=y\n    y=temporal\n    return (x,y)\n}\n\nvar v1 = \"morning\"\nvar v2 = \"night\"\nvar (v3, v4) = intercambioPorReferencia(x: &v1, y: &v2)\nprint(\"original values \\(v1) and \\(v2)\")\nprint(\"new values \\(v3) and \\(v4)\")\n\n\n\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/swift/PineroDev.swift",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y\n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\nimport Foundation\n\n// Variables por Valor\nvar palabra: String = \"Hola\"\nvar numero: Int = 32\nvar myArray: [Int] = [1, 2, 3]\nvar miDiccionario: [Int : String] = [1: \"Casa\", 2: \"Chalet\"]\n\nstruct NumModel{\n    var miNumero: Double\n    var esPar: Bool\n}\nvar num1 = NumModel(miNumero: 10.5, esPar: true)\nvar num2 = NumModel(miNumero: 20.5, esPar: false)\n\nenum CarMode{\n    case Honda\n    case Lancia\n}\n\nvar car1 = CarMode.Honda\nvar car2 = CarMode.Lancia\n\n// Variables por referencia\n\nclass VentanaApp{\n    let titulo: String\n    var esVisible: Bool\n    \n    init(titulo: String, esVisible: Bool){\n        self.titulo = titulo\n        self.esVisible = esVisible\n    }\n}\n\n\n// Dificultad Extra\n\nvar valor1: Int = 5\nvar valor2: Int = 7\nvar numeroValor1: Int = 0\nvar numeroValor2: Int = 0\n\n\nfunc cambiarValores(valor1 : Int, valor2 : Int) -> (Int, Int)   {\n    let nuevoValor1 = valor2\n    let nuevoValor2 = valor1\n    return (nuevoValor1, nuevoValor2)\n}\n\nvar valores = cambiarValores(valor1: valor1, valor2: valor2)\nnumeroValor1 = (valores.0)\nnumeroValor2 = (valores.1)\n\nprint(\"Valores originales: valor1: \\(valor1), valor2: \\(valor2)\")\nprint(\"Valores cambiados: valor1: \\(numeroValor1), valor2: \\(numeroValor2)\")\n\nclass ClaseReferencias{\n    var valor: Int = 0\n    \n    init(valor: Int) {\n        self.valor = valor\n    }\n}\n\nvar valorClase1 = ClaseReferencias(valor: 13)\nvar valorClase2 = ClaseReferencias(valor: 25)\nvar valorCambiado1 = ClaseReferencias(valor: 0)\nvar valorCambiado2 = ClaseReferencias(valor: 0)\n\n\nfunc cambiarValoresClase(valorClase1: ClaseReferencias, valorClase2: ClaseReferencias) -> (Int, Int) {\n    let nuevoValorClase1 = valorClase2.valor\n    let nuevoValorClase2 = valorClase1.valor\n    return (nuevoValorClase1, nuevoValorClase2)\n}\n\nvar valoresClase = cambiarValoresClase(valorClase1: valorClase1, valorClase2: valorClase2)\nvalorCambiado1.valor = (valoresClase.0)\nvalorCambiado2.valor = (valoresClase.1)\n\nprint(\"Valores originales: valor1: \\(valorClase1.valor), valor2: \\(valorClase2.valor)\")\nprint(\"Valores cambiados: valor1: \\(valorCambiado1.valor), valor2: \\(valorCambiado2.valor)\")\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/swift/allbertoMD.swift",
    "content": "import Foundation\n\n\nclass Word {\n    var word: String\n\n    init(word: String) {\n        self.word = word\n    }\n\n}\n\n\n// Variables por valor\nprint(\"\\nVARIABLES POR VALOR\")\n\nprint(\"\\nAsignación del String \\\"Hola\\\" a la Variable valueVariable1\")\n// Asigna el string \"Hola\" a la variable valueVariable1\nvar valueVariable1: String = \"Hola\"\n// Imprime el valor de la variable valueVariable1\nprint(valueVariable1)\n\nprint(\"\\nAsignación del valor de la variaable valueVariable1 a valueVariable2\")\n// Asigna el valor de la variable valueVariable1 a valueVariable2\nvar valueVariable2: String = valueVariable1\n// Imprime el valor de la varible valueVariable2\nprint(valueVariable2)\n\nprint(\"\\nCambio Del Valor de la Variable valueVariable1 al String \\\"Adios\\\"\")\n// Cambia el valor de la variable valueVariable1 al String \"Adios\"\nvalueVariable1 = \"Adios\"\nprint(\"El Valor de la Variable valueVariable1 Cambia a \\\"Adios\\\"\")\n// Imprime la variable valueVariable1 \nprint(valueVariable1)\n\nprint(\"\\nEl Valor de la Variable valueVariable2 no Cambia Por Que es una Varaable Por Valor\")\n// Imprime la variable valueVariable2\nprint(valueVariable2)\n\n// Función variable por valor\nfunc modifiesValueVariable(value str: String) -> String {\n    str + \", Mundo\"\n}\n\nprint(\"\\nAsignación Del Retorno de la Función a la Variable valueVariable3\")\n// Asigna el retorno de la función a la variable valueVariable3\nvar valueVariable3 = modifiesValueVariable(value: \"Hola\")\n// Imprime el valor de la variable valueVariable1\nprint(valueVariable3)\n\nprint(\"\\nAsignación Del Valor de la Variable valueVariable3 a valueVariable4\")\n// Asigna el valor de la variable valueVariable1 a valueVariable4\nvar valueVariable4 = valueVariable3\n// Imprime el valor de la variable valueVariable4\nprint(valueVariable4)\n\nprint(\"\\nCambiao Del Valor Del Parametro de la Función y Asignación Del Retorno a la Variable valueVariable3\")\n// Cambia el valor del valor parametro de la función y asigna el retorno a la variable valueVariable3\nvalueVariable3 = modifiesValueVariable(value: \"Adios\")\nprint(\"El Valor de la Variable valueVariable3 Cambia a \\\"Adios, Mundo\\\"\")\n// Imprime la variable valueVariable1\nprint(valueVariable3)\n\nprint(\"\\nEl Valor de la Variable valueVariable4 no Cambia Por Que es Una Variable Por Valor\")\n// Imprime la variable valueVariable4\nprint(valueVariable4)\n\n\n// VARIABLES POR REFERENCIA\nprint(\"\\n\\nVARIABLES POR REFERENCIA\")\n\nprint(\"\\nInstancia de la Clase Word() en la Variable referenceVariable1, y Asignación Del String \\\"Hola\\\" a la Propiedad word\")\n// Instacia la clase Word() en la variable referenceVariable1, y asigna el valor del String \"Hola\"\nvar referenceVariable1 = Word(word: \"Hola\")\n// Imprime el valor de la propiedas word de la variable referenceVariable1\nprint(referenceVariable1.word)\n\nprint(\"\\nCopia de la Instancia de Word() de la variable refeenceVariable1 a referenceVariable2\")\n// Copia la instancia de la clase Word() de referenceVariable1 a referenceVariable2\nvar referenceVariable2 = referenceVariable1\n// Imprime el valor de la variable referenceVariable2\nprint(referenceVariable2.word)\n\nprint(\"\\nCambio Del Valor de la Propiedad word de la Variable referenceVariable1 al String \\\"Adion\\\"\")\n// Cambia el valor de la propiedad word de la variable referenceVariable1 al string \"Adios\"\nreferenceVariable2.word = \"Adios\"\nprint(\"El Valor de la Propiedad word de la Variable referenceVariable1 Cambia a \\\"Adion\\\"\")\n// Imprime la variable referenceVariable1\nprint(referenceVariable1.word)\n\nprint(\"\\nEl Valor de la propiedad word de la variable referenceVariable2 Cambia Por Que es Una Variable Por Referencia\")\n// Imprime la variable referenceVariable2\nprint(referenceVariable2.word)\n\n// Función variable pro referencia\nfunc modifierReferenceVariable(reference ref: String) -> String {\n    \"\\(ref), Mundo\"\n}\n\nprint(\"\\nInstanciación de la Clase Word() en la Variable referenceVariable3 Usando el Retorno de la Función\")\n// Instancia la clase Word() en la variable referenceVariable3 usando el retrono de la funcioón\nvar referenceVariable3 = Word(word: modifierReferenceVariable(reference: \"Hola\"))\n// Imprime el valor de la propiedad word de la variable referenceVariable3\nprint(referenceVariable3.word)\n\nprint(\"\\nCopia de la Instancia de la Clase Word() de la Variable referenceVariable3 a referenceVariable4\")\n// Copia la instancia de la clase Word() a la variable referenceVariable4\nvar referenceVariable4 = referenceVariable3\n// Imprime el valor de la propiedad word de la variable referenceVariable4\nprint(referenceVariable4.word)\n\nprint(\"\\nCambio Del Valor de la Propiedad word de la Variable referenceVariable3 al String \\\"Adion\\\" Usando la Función\")\n// Cambia el valor de la propiedad word de la variable referenceVariable3 al string \"Adios\" usando la funcioón\nreferenceVariable3.word = modifierReferenceVariable(reference: \"Adios\")\nprint(\"El Valor de la Propiedad word de la Variable referenceVariable3 Cambia a \\\"Adion\\\"\")\n// Imprime la variable referenceVariable1\nprint(referenceVariable3.word)\n\nprint(\"\\nEl Valor de la propiedad word de la variable referenceVariable4 Cambia Por Que es Una Variable Por Referencia\")\n// Imprime la variable referenceVariable4\nprint(referenceVariable4.word)\n\n\n\n\n// Dificultad Extra\nprint(\"\\n\\nDIFICULTAD EXTRA\")\n\n\n// Programa de intercambio de variables por valor\nprint(\"\\nPrograma de Intercambio de Variables Por Valor\")\n\n// Declara variable con el String \"España\"\nvar value1 = \"España\"\n// Declara variable con el String \"Portugla\"\nvar value2 = \"Portugal\"\n\n// Define la funcion que intercabiara las variable value1 por value2 y value2 por value1\nfunc exchangeValue(value1 val1: String, value2 val2: String) -> (String, String) {\n    let v1 = val2\n    let v2 = val1\n\n    return (v1, v2)\n}\n\n// Declara una variable con una tupla y le asigna el retorno de la tupla de la funcion\nvar (newValue1, newValue2) = exchangeValue(value1: value1, value2: value2)\nprint(\"\\nEl Valor Del String \\\"España\\\" Ahora es \\\"Portugal\\\"\")\n// Imprime el valor de value2 en lugar de value1\nprint(newValue1)\nprint(\"El Valor Del String \\\"Portugal\\\" Ahora es \\\"España\\\"\")\n// Imprime el valor de value1 en lugar de value2\nprint(newValue2)\nprint(\"\\nEl Valor Del String \\\"España\\\" no ha Cambiado\")\n// Imprime el valor original sin cambiar\nprint(value1)\nprint(\"El Valor Del String \\\"Portugal\\\" no ha Cambiado\")\n// Imprime el valor original sin cambiar\nprint(value2)\n\n\n// Progama de intercabio de variables pro referencia\nprint(\"\\nPrograma de Intercambio de Variables Por Referencia\")\n\n// Instancia de la clase Word() y asigna el String \"Alemania\" a la propiedad word\nvar reference1 = Word(word: \"Alemania\")\n// Instancia de la clase Word() y asigna el Sting \"Italia\" a la propiedad word\nvar reference2 = Word(word: \"Italia\")\n\n// Define la funcion que intercabiara las variable reference1 por reference2 y reference2 por referencde1\nfunc exchangeReference(reference1 ref1: Word, reference2 ref2: Word) -> (Word, Word) {\n    let r1 = ref2\n    let r2 = ref1\n\n    return (r1, r2)\n}\n\n// Declara una variable con una tupla y le asigna el retorno de la tupla de la funcion\nvar (newReference1, newReference2) = exchangeReference(reference1: reference1, reference2: reference2)\nprint(\"\\nEl Valor Del String \\\"Alemania\\\" Ahora es \\\"Italia\\\"\")\n// Imprime el valor de reference2 en lugar de reference1\nprint(newReference1.word)\nprint(\"El Valor Del String \\\"Italia\\\" Ahora es \\\"Alemania\\\"\")\n// Imprime el valor de reference1 en lugar de reference2\nprint(newReference2.word)\nprint(\"\\nEl Valor Del String \\\"Alemania\\\" no ha Cambiado\")\n// Imprime el valor original sin cambiar\nprint(reference1.word)\nprint(\"El Valor Del String \\\"Italia\\\" no ha Cambiado\")\n// Imprime el valor original sin cambiar\nprint(reference2.word)\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/swift/blackriper.swift",
    "content": "import Foundation\n\n\n// variables por valor \nvar x = 10\nvar y = x // y es una copia de x\nx = 20\nprint(x)\nprint(y)\n\n// variables por referencia \nvar z = \"hello\"\nvar a = z\nz = \"goodbye\"\nprint(z)\nprint(a)\n\n// reto extra \n\n// Asignación por valor\nfunc forValue(x: String, y: String) -> (String, String){\n    return (y, x)\n}\n\nvar droid = \"RD-D2\"\nvar android = \"C3-PO\"\nvar (droid1, android1) = forValue(x: droid, y: android)\nprint(\"original values \\(droid) and \\(android)\")\nprint(\"new values \\(droid1) and \\(android1)\")\n\n// Asignación por referencia\nfunc forValue(x: inout String, y: inout String) -> (String, String){\n    let temp = x\n    x=y\n    y=temp\n    return (x,y)\n}\n\nvar dr = \"RD-D2\"\nvar an = \"C3-PO\"\nvar (droid2, android2) = forValue(x: &dr, y: &an)\nprint(\"original values \\(droid) and \\(android)\")\nprint(\"new values \\(droid2) and \\(android2)\")\n\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/swift/didacdev.swift",
    "content": "import Foundation\n\n// Paso por valor\nvar valorUno: Int = 3\nvar valorDos: Int = 5\n\nfunc variablesValor(variableUno: Int, variableDos: Int) ->  (vairableUno: Int, variableDos: Int){\n    let copyVariableUno = variableUno\n    let copyVariableDos = variableDos\n\n    return (copyVariableDos, copyVariableUno)\n}\n\nlet variablesValor: (Int, Int) = variablesValor(variableUno: valorUno, variableDos: valorDos)\n\nlet newValorUno = variablesValor.0\nlet newValorDos = variablesValor.1\n\nprint(\"Variables por valor originales: \")\nprint(\"\\(valorUno) \\(valorDos)\")\nprint(\"Variables por valor nuevas: \")\nprint(\"\\(newValorUno) \\(newValorDos)\")\n\n// Paso por referencia\nvar referenciaUno: Int = 2\nvar referenciaDos: Int = 4\n\nfunc variablesReferencia(variableUno: inout Int, variableDos: inout Int) -> (variableUno: Int, variableDos: Int) {\n    let copyVariableUno = variableUno\n    let copyVariableDos = variableDos\n\n    variableUno = copyVariableDos\n    variableDos = copyVariableUno\n\n    return (variableUno, variableDos)\n    \n}\n\nlet variablesReferencia: (Int, Int) = variablesReferencia(variableUno: &referenciaUno, variableDos: &referenciaDos)\n\nlet newReferenciaUno = variablesReferencia.0\nlet newReferenciaDos = variablesReferencia.1\n\nprint(\"Variables por referencia originales: \")\nprint(\"\\(referenciaUno) \\(referenciaDos)\")\nprint(\"Variables por valor nuevas: \")\nprint(\"\\(newReferenciaUno) \\(newReferenciaDos)\")"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/swift/gliadev.swift",
    "content": "import Foundation\n/* EJERCICIO:\n- Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según su tipo de dato.\n \n - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n \n (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n */\n\n/* Por valor:\n Creamos una copia independiente de la variable original que no afecta a la original.\n \n Ejemplo:\n Tenemos una receta de un pastel que le hacemos una copia y se la pasamos a un amigo si este decide modificar esa copia\n cambiar las cantidades, ingredientes.. nuestra receta orginal que tenemos nosotros no se va ver afectada. */\n\nvar recetaOriginal = \"Harina, azúcar, huevos\" // Receta original\nvar recetaCopia = recetaOriginal // Copia de la receta que le damos a nuestro amigo\n\nrecetaCopia += \", chocolate\" // El colega que es un Gotxo añade chocolate a su copia\nprint(recetaOriginal) // Imprimimos la receta original\nprint(recetaCopia) // imprimimos la receta de nuestro amigo\n\n\n/* Por referencia:\n En lugar de crear copias de esos valores pasarmos una referenica a una variable que si luego la modificas vas a modificar el\n valor de la original\n \n Ejemplo:\n El colega del pastel y tu compartis coche cada uno tiene una copia de la llave con lo que tenemos acceso a la clase coche\n que no es una copia si no el mismo coche, nuestro amigo le cambia el color al coche, nosotros podemos acceder al coche pero\n nos a cambiado el coche */\n\nclass Coche {\n    var color = \"Rojo\"\n}\n\nvar cocheCompartido = Coche() // ahi tenemos nuestro coche compartido\ncocheCompartido.color = \"Azul\" // nuestro amigo va y nos cambia el color\nprint(cocheCompartido.color) // imprimira el color azul\n\n\n/* DIFICULTAD EXTRA (opcional):\nCrea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n* - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n*   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n*   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n*   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n*   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\nfunc intercambiaPorValor(a: String, b: String) -> (String, String) {\n    // Aquí estamos intercambiando los valores a y b.\n    // Como los Strings se pasan por valor, las modificaciones se hacen en copias.\n    return (b, a)\n}\n\n// Variables originales\nvar valor1 = \"Manzana\"\nvar valor2 = \"Banana\"\n\n// Intercambio valores\nlet (nuevoValor1, nuevoValor2) = intercambiaPorValor(a: valor1, b: valor2)\n\n// Imprimo valores originales y nuevos\nprint(\"Original: \\(valor1), \\(valor2)\") // Manzana, Banana\nprint(\"Intercambiado: \\(nuevoValor1), \\(nuevoValor2)\") // Banana, Manzana\n\n\nclass Envoltura {\n    var contenido: String\n\n    init(contenido: String) {\n        self.contenido = contenido\n    }\n}\n\nfunc intercambiaPorReferencia(a: Envoltura, b: Envoltura) {\n    // intercambiando los contenidos de a y b.\n    // Como Envoltura es una clase, a y b se pasan por referencia.\n    let temporal = a.contenido\n    a.contenido = b.contenido\n    b.contenido = temporal\n}\n\n// Instancias de clase pasadas por referencia\nvar envoltura1 = Envoltura(contenido: \"Chocolate\")\nvar envoltura2 = Envoltura(contenido: \"Vainilla\")\n\n// Intercambiando contenidos\nintercambiaPorReferencia(a: envoltura1, b: envoltura2)\n\n// Imprimolos contenidos después del cambio\nprint(\"Envoltura 1: \\(envoltura1.contenido), Envoltura 2: \\(envoltura2.contenido)\") // Vainilla, Chocolate\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/swift/karys4.swift",
    "content": "//Value Types (A copy) -> Struct, Enum, tuples\n//Awesome explanation in the following link: https://www.swift.org/documentation/articles/value-and-reference-types.html\n\nstruct Document {\n    var text: String\n}\n\nvar myDocument = Document(text: \"Kary's document\")\nvar friendDocument = myDocument\n\nfriendDocument.text = \"I am kary's friend and this is my own document\"\n\nprint(myDocument.text) //Kary's document\nprint(friendDocument.text) //I am kary's friend and this is my own document\n\n\n\n//Reference Types -> Class, closure\nclass Car {\n    var color: String\n    \n    init(color: String) {\n        self.color = color\n    }\n}\n\n\nvar myCar = Car(color: \"White\")\nvar friendCar = myCar\n\nfriendCar.color = \"Yellow\" //This assignation affected \"myCar\" because it is a reference to the instance that is assigned.\n\nprint(myCar.color) //Yellow\nprint(friendCar.color) //Yellow\n\n\n\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/swift/kontroldev.swift",
    "content": "import Foundation\n\n/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y\n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\n\n// Asignación por valor\nvar x = 10 // x es de tipo Int, que es un tipo de valor\nvar y = x // y es una copia de x\nx = 20 // cambiamos el valor de x\nprint(x) // imprime 20\nprint(y) // imprime 10, no se ve afectado por el cambio de x\n\n\n// Asignación por valor\nvar x = 10 // x es de tipo Int, que es un tipo de valor\nvar y = x // y es una copia de x\nx = 20 // cambiamos el valor de x\nprint(x) // imprime 20\nprint(y) // imprime 10, no se ve afectado por el cambio de x\n\n\n// Paso por valor\nfunc incrementar(_ n: Int) -> Int { // n es una copia del valor que se pasa como argumento\n    return n + 1\n}\n\nvar a = 5 // a es de tipo Int, que es un tipo de valor\nvar b = incrementar(a) // b es el resultado de la función incrementar con a como argumento\nprint(a) // imprime 5, no se ve afectado por la función\nprint(b) // imprime 6\n\n\n// Paso por valor\nfunc incrementar(_ n: Int) -> Int { // n es una copia del valor que se pasa como argumento\n    return n + 1\n}\n\nvar a = 5 // a es de tipo Int, que es un tipo de valor\nvar b = incrementar(a) // b es el resultado de la función incrementar con a como argumento\nprint(a) // imprime 5, no se ve afectado por la función\nprint(b) // imprime 6\n\n\n\n// Solución para el caso de parámetros por valor\nfunc intercambiarPorValor(_ x: Int, _ y: Int) -> (Int, Int) {\n    // Esta función recibe dos parámetros por valor y los intercambia entre ellos\n    // Retorna una tupla con los valores intercambiados\n    return (y, x)\n}\n\nvar r = 3 // r es de tipo Int, que es un tipo de valor\nvar s = 4 // s es de tipo Int, que es un tipo de valor\nprint(\"Antes del intercambio:\")\nprint(\"r = \\(r)\") // imprime r = 3\nprint(\"s = \\(s)\") // imprime s = 4\nvar (t, u) = intercambiarPorValor(r, s) // llamamos a la función intercambiarPorValor con r y s como argumentos, y asignamos su retorno a dos nuevas variables t y u\nprint(\"Después del intercambio:\")\nprint(\"r = \\(r)\") // imprime r = 3, no se ve afectado por la función\nprint(\"s = \\(s)\") // imprime s = 4, no se ve afectado por la función\nprint(\"t = \\(t)\") // imprime t = 4, tiene el valor de s\nprint(\"u = \\(u)\") // imprime u = 3, tiene el valor de r\n\n\n// Solución para el caso de parámetros por referencia\nfunc intercambiarPorReferencia(_ x: inout Persona, _ y: inout Persona) -> (Persona, Persona) {\n    // Esta función recibe dos parámetros por referencia y los intercambia entre ellos\n    // Retorna una tupla con las referencias intercambiadas\n    let temp = x // guardamos la referencia de x en una variable temporal\n    x = y // asignamos la referencia de y a x\n    y = temp // asignamos la referencia de la variable temporal a y\n    return (x, y)\n}\n\nvar v = Persona(nombre: \"Mario\") // v es una instancia de Persona\nvar w = Persona(nombre: \"Laura\") // w es una instancia de Persona\nprint(\"Antes del intercambio:\")\nprint(\"v.nombre = \\(v.nombre)\") // imprime v.nombre = Mario\nprint(\"w.nombre = \\(w.nombre)\") // imprime w.nombre = Laura\nvar (x, y) = intercambiarPorReferencia(&v, &w) // llamamos a la función intercambiarPorReferencia con v y w como argumentos, usando el operador & para indicar que se pasan por referencia, y asignamos su retorno a dos nuevas variables x y y\nprint(\"Después del intercambio:\")\nprint(\"v.nombre = \\(v.nombre)\") // imprime v.nombre = Laura, se ve afectado por la función\nprint(\"w.nombre = \\(w.nombre)\") // imprime w.nombre = Mario, se ve afectado por la función\nprint(\"x.nombre = \\(x.nombre)\") // imprime x.nombre = Mario, tiene la referencia de w\nprint(\"y.nombre = \\(y.nombre)\") // imprime y.nombre = Laura, tiene la referencia de v\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/swift/miguelex.swift",
    "content": "import Foundation\n\n// variable por valor\n\nvar name = \"Migue\" \nvar nombre = name \n\nprint(\"Antes de cambiar el nombre:\")\nprint(name)\nprint(nombre)\n\nname = \"Miguel Angel\"\n\nprint(\"Despues de cambiar el nombre:\")\nprint(name)\nprint(nombre)\n\n// variable por referencia\n\nclass Persona {\n    var nombre: String\n    init(nombre: String) {\n        self.nombre = nombre\n    }\n}\n\nvar p1 = Persona(nombre: \"Juan\")\nvar p2 = p1 // p2 es una referencia a la misma instancia que p1\n\nprint(\"Antes de cambiar el nombre:\")\nprint(p1.nombre)\nprint(p2.nombre)\n\np1.nombre = \"Pedro\" // cambiamos el nombre de p1\n\nprint(\"Después de cambiar el nombre:\")\nprint(p1.nombre)\nprint(p2.nombre)\n\n// Funcion con paso por valor\n\nfunc incrementar(_ n: Int) -> Int {\n    return n + 1\n}\n\nvar a = 100\n\nvar b = incrementar(a)\n\nprint(a)\nprint(b)\n\n// Extra\n\nlet num1, num2, num3, num4: Int\n\nfunc intercambiarPorValor(_ x: Int, _ y: Int) -> (Int, Int) {\n    return (y, x)\n}\n\nnum1 = 10\nnum2 = 5\n\n(num3, num4) = intercambiarPorValor(10, 5)\nprint(\"Despues de llamar a la funcion, tenemos los valores:\")\nprint(num1)\nprint(num2)\nprint(num3)\nprint(num4)\n\n// parámetros por referencia. Intercambio de array\n\nfunc intercambiarPorReferencia(_ x: inout [Int], _ y: inout [Int]) -> ([Int], [Int]) {\n    let temp = x\n    x = y\n    y = temp\n    return (x, y)\n}\n\nvar arr1 = [1, 2, 3]\nvar arr2 = [4, 5, 6]\n\nprint(\"Antes del intercambio:\")\nprint(\"arr1 = \\(arr1)\")\nprint(\"arr2 = \\(arr2)\")\n\nvar (arr3, arr4) = intercambiarPorReferencia(&arr1, &arr2)\n\nprint(\"\\nDespués del intercambio:\\n\")\nprint(\"arr1 = \\(arr1)\")\nprint(\"arr2 = \\(arr2)\")\nprint(\"arr3 = \\(arr3)\")\nprint(\"arr4 = \\(arr4)\")\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/swift/pedroomar23.swift",
    "content": "import Foundation\n\n/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\n// Asignación de variables por valor \nvar x = 5 // La variable x mantiene su valor \nvar y = x // La variable y cambia al valor de la variable x\n\nprint(x) // Imprimir en la consola x\nprint(y) // Imprimir en la consola y\n\nvar x = y // La variable x cambia al valor de la variable y\nvar y = 10 // La variable y mantiene su valor \n\nprint(x) // Imprimir en la consola x\nprint(y) // Imprimir en la consola y\n\n// Asiganción de varibles por referencia \nstruct Person {\n    var nombre: String \n}\n\nPerson(nombre: \"Julio\") // Llamar la instancia de la estructura\n\nvar perfil1 = Person(nombre: \"Julio\") // La variable perfil mantiene su referencia \nvar perfil2 = perfil1 // La variable perfil2 ahora hace referencia a perfil1\n\nprint(perfil1) // Imprimir en la consola perfil1\nprint(perfil2) // Imprimir en la consola perfil2\n\n// Funciones para asignar valores\nfunc sumar(_ a: Int) -> Int {\n    return a + 1\n}\n\nvar x = sumar(1) // La variable x aunmenta su valor en 1\nvar y = 5 // La variable y mantiene su valor \n\nprint(x) // Imprimir en la consola x\nprint(y) // Imprimir en la consola y\n\nfunc restar(_ a: Int) -> Int {\n    return a - 1\n}\n\nvar x = 5 // La variable x mantiene su valor \nvar y = restar(1) // La variable y disminuye su valor en 1\n\nprint(x) // Imprimir en la consola x\nprint(y) // Imprimir en la consola y\n\n// Funciones para asignar referencias \nfunc Perfil(_ a: String, _ b: String) -> (String, String) {\n    return (a, b)\n}\n\nvar x = Perfil(\"Carlos\", \"Pedro\") // La varible x hace referencia a la funcion\nvar y = x // La variable y pasa a tener la refenrecia de x\n\nprint(x) // Imprimir en la consola x\nprint(y) // Imprimir en la consola y\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/swift/zetared92.swift",
    "content": "import Foundation\n// RETO #05 VALOR Y REFERENCIA\n\n// Asignación por valor\nvar droid: String = \"RD-D2\"\nvar android = droid\ndroid = \"C3-PO\"\nprint(droid)\nprint(android)\n\n// Variable por referencia\n\nclass Droid {\n    var color = \"White\"\n}\n\nvar android = Droid()\nandroid.color = \"Gold\"\nprint(android.color)\n\n\n// 🧩 DIFICULTAD EXTRA 🧩\n\n// Intercambio de valores\nfunc forValue(x: String, y: String) -> (String, String){\n    return (y, x)\n}\n\nvar droid = \"RD-D2\"\nvar android = \"C3-PO\"\n\nlet (droid2, android2) = forValue(x: droid2, y: android2)\nprint(\"First values: \\(droid), \\(android)\")\nprint(\"New values: \\(droid2), \\(android2)\")\n\n// Intercambio por referencia\nclass SpaceShip {\n    var ship: String\n\n    init(ship: String) {\n        self.ship = ship\n    }\n}\n\nfunc forReference(x: SpaceShip, y: SpaceShip) {\n    let newRef = x.ship\n    x.ship = y.ship\n    y.ship = newRef\n}\n\n\nvar spaceShip1 = SpaceShip(ship: \"X-Wing\")\nvar spaceShip2 = SpaceShip(ship: \"Millenium Falcon\")\n\nforReference(x: spaceShip1, y: spaceShip2)\n\n\nprint(\"First Spaceship: \\(spaceShip1.ship), Second Spaceship: \\(spaceShip2.ship)\") "
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/typescript/AChapeton.ts",
    "content": "//Variables por Valor\n\nlet a: string = 'Hola Mundo'\nlet b: string = a //El valor de \"a\" se asigna a \"b\"\n\na += '!' //Se modifica el valor de \"a\"\n\nconsole.log(\"a\", a)\nconsole.log(\"b\", b)\n\n\n//Variables por Referencia\n//Con estructuras, no se crea un nuevo valor, sino que ambas variables apuntan a un mismo espacio en memoria\n\nconst c = [1, 2, 3]\nconst d = c\n\nc.push(4)\n\nconsole.log('c', c)\nconsole.log('d', d)\n\n\n//Funciones utilizando Variables por Valor\n\n\nconst firstFunction = (str: string) => {\n  str = 'nuevo valor dentro de la funcion'\n  return str\n}\n\nconst strOriginal: string = 'Fuera de la funcion'\nconsole.log('Por valor - Dentro de la funcion: ', firstFunction(strOriginal))\nconsole.log('Por valor - Fuera de la funcion: ', strOriginal)\n\n\n//Funciones utilizando Varibles por Referencia\n\nconst secondFunction = (arr: Array<string>) => {\n  arr.push('Moure')\n  return arr\n}\n\nconst arrOriginal: Array<string> = ['Andres', 'Brais', 'Chape']\nconsole.log('Por referencia - Dentro de la funcion: ', secondFunction(arrOriginal))\nconsole.log('Por referencia - Fuera de la funcion: ', arrOriginal)\n\n\n// EJERCICIO EXTRA\n\n//Funcion para intercarbiar variables por valor\n\nconst intercambiarValor = (num1: number, num2: number): [number, number] => {\n  const temp: number = num1\n  num1 = num2\n  num2 = temp\n  return [num1, num2]\n}\n\nlet primerValor: number = 10\nlet segundoValor: number = 5\n\nconsole.group('Valores antes del intercambio')\n  console.log('primerValor: ', primerValor)\n  console.log('segundoValor: ', segundoValor)\nconsole.groupEnd()\n\nlet [nuevoPrimerValor, nuevoSegundoValor] = intercambiarValor(primerValor, segundoValor)\n\nconsole.group('Valores despues del intercambio')\n  console.log('primerValor: ', primerValor)\n  console.log('segundoValor: ', segundoValor)\nconsole.groupEnd()\n\nconsole.group('Nuevos valores intercambiados')\n  console.log('nuevoPrimerValor: ', nuevoPrimerValor)\n  console.log('nuevoSegundoValor: ', nuevoSegundoValor)\nconsole.groupEnd()\n\n\n//Funcion para intercarbiar variables por referecia\n\ninterface Usuario {\n  name: string,\n  mainEmail: string,\n  secondEmail: string\n}\n\nconst intercambiarReferencias = (user: Usuario): Usuario => {\n  let temp: string = user.mainEmail\n  user.mainEmail = user.secondEmail\n  user.secondEmail = temp\n\n  return user\n}\n\nlet usuarioOriginal: Usuario = {\n  name: 'Andres',\n  mainEmail: 'andres@new.com',\n  secondEmail: 'andres@test.com',\n}\n\nconsole.group('Referencias antes del intercambio')\n  console.log('usuarioOriginal: ', usuarioOriginal)\nconsole.groupEnd()\n\nlet nuevoUsuario: Usuario = intercambiarReferencias(usuarioOriginal)\n\nconsole.group('Referencias despues del intercambio')\n  console.log('usuarioOriginal: ', usuarioOriginal)\nconsole.groupEnd()\n\nconsole.group('Nuevas Referencias intercambiadas')\n  console.log('nuevoUsuario: ', nuevoUsuario)\nconsole.groupEnd()"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/typescript/DouglasDiazR.ts",
    "content": "//Asignación por Valor\nlet varA = 10;\nlet varB = varA; // Se asigna el valor de `varA` a `varB`\n\nvarB = 20; // Modificamos el valor de `varB`\n\nconsole.log(\"varA: \", varA); // Imprime: 10 (el valor de la variable`varA` no cambió)\nconsole.log(\"varB: \", varB); // Imprime: 20 (el valor de la variable`varB` se modificó)\n\n//Asignación por Referencia\nlet _obj1 = { name: \"Javier\" };\nlet _obj2 = _obj1; //Se asigna el valor de obj1 a obj2\n\n_obj2.name = \"Douglas\"; // Modificamos la propiedad 'name' del obj2\n\nconsole.log(\"obj1: \", _obj1); // Imprime obj1:  { name: 'Douglas' } la modificación afecta a obj1\nconsole.log(\"obj2: \", _obj2); // imprime obj2:  { name: 'Douglas' }\n\n//Función con parámetros pasados por valor\nfunction incremetarValor(x: number): void {\n  x = x + 1; // Se modifica el valor de x\n  console.log(\"x: \", x);\n}\n\nlet _num = 10;\n\nincremetarValor(_num); //se pasa el valor de _num por valor\n\nconsole.log(\"num: \", _num); //el valor de '_num' no fue modificado\n\n//Función con parámetros pasados por referencia\nfunction actualizarNombre(persona: { nombre: string }): void {\n  persona.nombre = \"Javier\"; // Modificamos el nombre en el objeto\n  console.log(\"persona.nombre: \", persona.nombre);\n}\n\nlet objPersona = { nombre: \"Douglas\" };\n\nactualizarNombre(objPersona); // Se pasa `objPersona` por referencia\n\nconsole.log(\"objPersona: \", objPersona); // Imprime: \"Javier\" (el objeto fue modificado)\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\nlet _num1 = 5;\nlet _num2 = 10;\n\nfunction porValor(param1: number, param2: number): [number, number] {\n  let temporal = param1;\n  console.log(\"temporal\", temporal);\n  param1 = param2;\n  console.log(\"param1\", param1);\n  param2 = temporal;\n  console.log(\"param2\", param2);\n  return [param1, param2];\n}\n\nlet [_nuevoValor1, _nuevoValor2] = porValor(_num1, _num2);\nconsole.log(\"valorInicial1\", _num1); //5\nconsole.log(\"ValorInicial2\", _num2); //10\nconsole.log(\"nuevoValor1\", _nuevoValor1); //10\nconsole.log(\"nuevoValor2\", _nuevoValor2); //5\n\nlet personaObj1 = { nombre: \"Javier\" };\nlet personaOBj2 = { nombre: \"Ivana\" };\n\nfunction porReferencia(param1: { nombre: string }, param2: { nombre: string }) {\n  let temporalObj = param1.nombre;\n  console.log(\"temporal\", temporalObj);\n  param1.nombre = param2.nombre;\n  console.log(\"param1\", param1);\n  param2.nombre = temporalObj;\n  console.log(\"param2\", param2);\n  return [param1, param2];\n}\n\nlet [nuevoValorObj1, nuevoValorObj2] = porReferencia(personaObj1, personaOBj2);\nconsole.log(\"valorinIcialObj1\", personaObj1); // { nombre: 'Ivana' }\nconsole.log(\"valorinIcialObj2\", personaOBj2); // { nombre: 'Javier' }\nconsole.log(\"nuevoValorObj1\", nuevoValorObj1); // { nombre: 'Ivana' }\nconsole.log(\"nuevoValorObj2\", nuevoValorObj2); // { nombre: 'Javier' }\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/typescript/EdiedRamos.ts",
    "content": "// Creado por: EdiedRamos\n\ntype Pet = {\n  name: string;\n};\n\nfunction fooValue(a: number, b: number) {\n  [a, b] = [b, a];\n  return {\n    a,\n    b,\n  };\n}\n\nfunction fooReference(a: Pet, b: Pet) {\n  [a.name, b.name] = [b.name, a.name];\n  return {\n    a,\n    b,\n  };\n}\n\n(() => {\n  const aValue = 5,\n    bValue = 10;\n\n  const aReference: Pet = {\n      name: \"Snoopy\",\n    },\n    bReference: Pet = {\n      name: \"Pluto\",\n    };\n\n  const { a: aValueFoo, b: bValueFoo } = fooValue(aValue, bValue);\n  const { a: aReferenceFoo, b: bReferenceFoo } = fooReference(\n    aReference,\n    bReference\n  );\n\n  console.log(\"*\".repeat(50));\n  console.log(\"CASO: POR VALOR\");\n  console.log(\"Originales:\", { aValue, bValue });\n  console.log(\"Retorno de la función:\", { aValueFoo, bValueFoo });\n  console.log(\"*\".repeat(50));\n\n  console.log(\"*\".repeat(50));\n  console.log(\"CASO: POR REFERENCIA\");\n  console.log(\"Originales:\", { aReference, bReference });\n  console.log(\"Retorno de la función:\", { aReferenceFoo, bReferenceFoo });\n  console.log(\"*\".repeat(50));\n\n  // Se verifica que las variables pasadas por valor no sean alteradas.\n  /*\n    No debería fallar porque el tipo \"number\" es un tipo primitivo,\n    y los primitivos siempre son argumentos pasados por valor.\n  */\n  console.assert(\n    aValue === 5,\n    'El valor original de \"aValue\" ha sido alterado.'\n  );\n  console.assert(\n    bValue === 10,\n    'El valor original de \"bValue\" ha sido alterado.'\n  );\n\n  // Se verifica que las variables pasadas por referencia no sean alteradas.\n  /*\n    Debería fallar porque el tipo \"object\" es un tipo NO primitivo,\n    y los NO primitivos siempre son argumentos pasador por referencia.\n   */\n  console.assert(\n    aReference.name === \"Snoopy\",\n    'El valor original de \"aReference\" ha sido alterado.'\n  );\n  console.assert(\n    bReference.name === \"Pluto\",\n    'El valor original de \"bReference\" ha sido alterado.'\n  );\n})();\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/typescript/Guillemduno.ts",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y\n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n */\n\n/**\n * ASSIGNACIÓN POR VALOR\n * Las variables primitivas de tipo: string, number, bolean, etc, se assignan por valor.\n * Esto quiere decir que el valor de la variable se guarda en un espacio de la memoria\n * del ordenador. Cada variable tiene un valor único.\n *\n * En el ejemplo siguiente vemos que la variable miFrase sigue manteniendo su valor\n * a pesar de utilizarla como parámetro en la función.\n */\n\nlet miFrase = \"La canción tranquila\";\n\nfunction pintaFrase(frase: string) {\n  frase = frase + \"dentro de la función\";\n  console.log(frase);\n}\n\nconsole.log(miFrase); // La canción tranquila\npintaFrase(miFrase); // La canción tranquiladentro de la función\nconsole.log(miFrase); // La canción tranquila\n\n/**\n * ASSIGNACIÓN POR REFERÉNCIA\n *\n * Los objetos y funciones se assignan por referéncia. Eso quiere decir que el\n * valor de la variable sera modificada estemos fuera o dentro de una función ya que\n * ira a buscar al mismo punto de la memória donde reside el valor de la variable y\n * lo modificarà.\n *\n * En el ejemplo siguiente, vemos como el valor del atributo cambia al passar por\n * dentro de la función, así como también después.\n *\n */\n\nlet miObjeto = {\n  nombre: \"Guillem\",\n  edad: 12,\n};\n\nfunction cambiarObjeto(mi: any) {\n  mi.nombre = \"Carol\";\n  console.log(mi.nombre);\n}\n\nconsole.log(miObjeto.nombre); // Guillem\ncambiarObjeto(miObjeto); // Carol\nconsole.log(miObjeto.nombre); // Carol\n\n/**\n *  * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\nlet valor1 = \"Assignación por valor 1\";\nlet valor2 = \"Assignación por valor 2\";\n\nfunction parametrosPorValor(valor1: string, valor2: string) {\n  let iniValor1 = valor1;\n  valor1 = valor2;\n  valor2 = iniValor1;\n  return [valor1, valor2];\n}\n\nconsole.log(`Variable original valor1 ${valor1}`);\nconsole.log(`Variable original valor2 ${valor2}`);\nconst newValores = parametrosPorValor(valor1, valor2);\nconsole.log(`Nuevo valor 1 ${newValores[0]}`);\nconsole.log(`Nuevo valor 2 ${newValores[1]}`);\nconsole.log(`Variable original valor1 ${valor1}`);\nconsole.log(`Variable original valor2 ${valor2}`);\n\ninterface Producto {\n  nombre: string;\n}\n\ninterface Usuario {\n  nombre: string;\n}\n\nlet producto: Producto = {\n  nombre: \"piano\",\n};\n\nlet usuario: Usuario = {\n  nombre: \"Guillem\",\n};\n\nfunction parametrosPorReferencia(producto: Producto, usuario: Usuario) {\n  const initProductoNombre = producto.nombre;\n  producto.nombre = usuario.nombre;\n  usuario.nombre = initProductoNombre;\n\n  return [producto.nombre, usuario.nombre];\n}\n\nconsole.log(`Original producto nombre ${producto.nombre}`);\nconsole.log(`Original usuario nombre ${usuario.nombre}`);\n\nconst nombres = parametrosPorReferencia(producto, usuario);\n\nconsole.log(`Nuevo producto nombre ${nombres[0]}`);\nconsole.log(`Nuevo usuario nombre ${nombres[1]}`);\n\nconsole.log(`Original producto nombre ${producto.nombre}`);\nconsole.log(`Original usuario nombre ${usuario.nombre}`);\n\n/**\n * Recursos visitatdos\n *\n * https://flexiple.com/javascript/javascript-pass-by-reference-or-value\n *\n * https://es.stackoverflow.com/questions/1493/cu%C3%A1l-es-la-diferencia-entre-paso-de-variables-por-valor-y-por-referencia\n */\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/typescript/RicJDev.ts",
    "content": "//Tipos de datos por valor\nlet number1: number = 10\nlet number2: number = number1\n\nconsole.log(number2)\n\nnumber1 += 20\n\nconsole.log(number1)\nconsole.log(number2)\n\n//Función con variables por valor\nlet number3: number = 5\n\nfunction add40(num: number) {\n\treturn num + 40\n}\n\nconsole.log(number3)\n\nadd40(number3)\nconsole.log(number3)\n\n//Tipos de datos por referencia\nlet array1: number[] = [12, 30, 12]\nlet array2: number[] = array1\n\nconsole.log(array1)\n\narray2.push(10)\n\nconsole.log(array1)\nconsole.log(array2)\n\n//Función con variables por referencia\nlet array3: number[] = [10, 20, 30]\n\nfunction customPop(arr: any[]) {\n\treturn (arr.length -= 1)\n}\n\nconsole.log(array3)\n\ncustomPop(array3)\nconsole.log(array3)\n\n//EXTRA\nfunction changeValues(a: any, b: any) {\n\tlet change = a\n\n\ta = b\n\tb = change\n\n\treturn [a, b]\n}\n\n//Variables por valor\nlet number4 = 20\nlet number5 = 50\n\nlet [newNumber4, newNumber5] = changeValues(number4, number5)\n\nconsole.log('Valores originales:', number4, number5)\nconsole.log('Valores cambiados:', newNumber4, newNumber5)\n\n//Variables por referencia\nlet array5 = [12, 10, 14]\nlet array6 = [20, 22, 25]\n\nlet [newArray5, newArray6] = changeValues(array5, array6)\n\nconsole.log('Valores originales:', array5, array6)\nconsole.log('Valores cambiados:', newArray5, newArray6)\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/typescript/RobertoAmaroHub.ts",
    "content": "let asigReferencia:number[]=[2,4,6,6,77,1];\nlet asigValor:string=\"asignación por valor\";\n\n// por valor, no se modifica la variable externa al método\nfunction porValor(_asigValor:string){\n    _asigValor=\"nuevo texto\";\n    console.log(`Dentro de la función por valor, value es \"${_asigValor}\"`);\n}\nporValor(asigValor);\nconsole.log(`Fuera de la función por valor, el valor asigValor es \"${asigValor}\"`);\n\n// por referencia, sí se modifica la variable externa al método\nfunction porReferencia(_asigReferencia:number[]){\n    _asigReferencia[0]=1233;\n    console.log (`Dentro de la función, vale [0] es \"${_asigReferencia[0]}\"`);\n}\nporReferencia(asigReferencia)\nconsole.log (`Fuera de la función, arrNumeros [0] es \"${asigReferencia[0]}\"`);\n\n//EXTRA*********************************************\nlet valor1:string=\"valor1 inicial\";\nlet valor2:string=\"valor2 inicial\";\n\nfunction extraPorValor(_valor1:string,_valor2:string):string[]{\n    _valor1=valor2;\n    _valor2=valor1;\n    return [_valor1,_valor2];\n}\nlet newValues:string[]=extraPorValor(valor1,valor2);\nlet value1:string=newValues[0];\nlet value2:string=newValues[1];\nconsole.log(\"\\n\");\nconsole.log(`Valores originales: valor1 es \"${valor1}\" y valor2 es \"${valor2}\"`);\nconsole.log(`Nuevos valores: valor1 es \"${value1}\" y valor2 es \"${value2}\"`);\n\n\nlet val1:string[]=[\"valor1\",\"inicial\"];\nlet val2:string[]=[\"valor2\", \"inicial\"];\n\nfunction extraPorReferencia(_val1:string[], _val2:string[]){\n    _val1=val2;\n    _val2=val1;\n    return [_val1, _val2];\n}\nlet newVal:string[][]=extraPorReferencia(val1,val2);\nlet nVal1:string[]=newVal[0];\nlet nVal2:string[]=newVal[1];\nconsole.log(\"\\n\");\nconsole.log(`Valores originales: valor1 es \"${val1}\" y valor2 es \"${val2}\"`);\nconsole.log(`Nuevos valores: valor1 es \"${nVal1}\" y valor2 es \"${nVal2}\"`);"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/typescript/Sac-Corts.ts",
    "content": "// By value (with primitive types)\nlet c: number = 10;\nlet d: number = c;\n\nd = 20;\nconsole.log(c);\nconsole.log(d);\n\n// By reference (with objects)\nlet objA = { value: 10 };\nlet objB = objA;\n\nobjB.value = 20;\nconsole.log(objA.value);\nconsole.log(objB.value);\n\n// Function with parameter passed by value\nfunction incrementValue(val: number): void {\n    val += 10;\n    console.log(`Inside the funcion: ${val}`);\n}\n\nlet _num = 5;\nincrementValue(_num);\nconsole.log(`Outside the function: ${_num}`);\n\n// Function with parameter passed by reference\nfunction incrementObject(obj: { value: number }): void {\n    obj.value += 10;\n    console.log(`Inside the function: ${obj.value}`);\n}\n\nlet _myObj = { value: 5 };\nincrementObject(_myObj);\nconsole.log(`Outside the function: ${_myObj.value}`);\n\n// *** Extra Exercise *** //\n// By value\nlet parameter1: number = 10;\nlet parameter2: number = 20;\n\nfunction exchangeValue(x: number, y: number): number[] {\n    let temp = x;\n    x = y;\n    y = temp;\n    return [x, y];\n}\n\nlet [newValue1, newValue2] = exchangeValue(parameter1, parameter2);\nconsole.log(\"Swap by value:\");\nconsole.log(`Original values: parameter1: ${parameter1} and parameter2: ${parameter2}`);\nconsole.log(`New values: parameter1: ${newValue1} and parameter2: ${newValue2}`);\n\n// By reference\ntype ValueObject = { value: string }\ntype Ref = { str1: ValueObject, str2: ValueObject };\n\nlet str1: ValueObject = { value: \"Object 1\" };\nlet str2: ValueObject = { value: \"Object 2\" };\n\nlet ref: Ref = { str1: str1, str2: str2 };\n\nfunction exchangeReference(ref: Ref): void {\n    let temp = ref.str1;\n    ref.str1 = ref.str2;\n    ref.str2 = temp;\n}\n\nconsole.log(\"Swap by reference:\");\nconsole.log(`Original values: str1: ${str1.value} and str2: ${str2.value}`);\nexchangeReference(ref);\nconsole.log(`New values: str1: ${ref.str1.value} and str2: ${ref.str2.value}`);"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/typescript/Sharah07.ts",
    "content": "// ASIGNACIÓN POR VALOR Y POR REFERENCIA\n\n/**ASIGNACIÓN POR VALOR:\nSe asigna el contenido de la variable x a la variable y,\npuedo modificar el valor de y sin alterar a x, \npuesto que cada variable tiene su propio espacio en memoria.\nSI LA VARIABLES ASIGNADA CONTIENE UN VALOR PRIMITIVO ES UNA ASIGNACIÓN POR VALOR.*/\n\n/**ASIGNACIÓN POR REFERENCIA:\nSe asigna la referencia a la variable a,\nes decir no se asigna una copia del valor de a,\npor lo que ambas variables apuntan al mismo espacio en memoria.\nSi se modifica el valor de b automáticamente se modifica a. \nSI LA VARIABLE ASIGNADA NO ES UN VALOR PRIMITIVO ES UNA ASIGNACIÓN POR REFERENCIA.*/\n\n// Por valor:\nlet x, y;\n\nx = 25;\ny = x; //tipo number\ny = 30;\nconsole.log(x, y);\n\n// Por Referencia\nx = [1, 2, 3, 4];\ny = x;\ny.push(5);\nconsole.log(x, y);\n\n//Función con parámetro por valor:\nlet texto = 'Hola mundo!';\n\nfunction funcionPorValor(texto:string){\n    texto = 'Hola Mundo, desde dentro de la función!';\n    return console.log(texto); \n}\nfuncionPorValor(texto); // Hola Mundo, desde dentro de la función!\n\nconsole.log(texto); // Hola mundo!\n\n//Función con parámetro por referencia:\nlet persona = {nombre:'Sharah', apellido:'Palacios'}\n\nfunction funcionPorReferencia(persona){\n    persona.edad = 20;\n    return console.log(persona); \n}\nfuncionPorReferencia(persona); // { nombre: 'Sharah', apellido: 'Palacios', edad: 20 }\n\nconsole.log(persona); // { nombre: 'Sharah', apellido: 'Palacios', edad: 20 }\n\n//Extra:\n// parámetros por valor:\nlet porValor1 = '1';\nlet porValor2 = '2';\n\nfunction funcPorValor(porValor1, porValor2){\n    let tem = porValor1;\n    porValor1 = porValor2;\n    porValor2 = tem;\n    return [porValor1, porValor2];\n}\nlet nuevosValores = funcPorValor(porValor1, porValor2);\n\nlet nuevoPorValor1 = nuevosValores[0];\nlet nuevoPorValor2 = nuevosValores[1];\n\nconsole.log(porValor1, porValor2);  // 1 2\nconsole.log(nuevoPorValor1, nuevoPorValor2); // 2 1\n\n//Parámetros por referencia:\nlet porReferencia1 = [1, 2, 3];\nlet porReferencia2 = ['a','e','i','o','u'];\n\nfunction funcPorReferencia(porReferencia1, porReferencia2){\n    let tem = porReferencia1;\n    porReferencia1 = porReferencia2;\n    porReferencia2 = tem;\n    return [porReferencia1, porReferencia2];\n}\nlet newValores = funcPorReferencia(porReferencia1, porReferencia2);\n\nlet nuevoPorReferencia1 = newValores[0];\nlet nuevoPorReferencia2 = newValores[1];\n\nconsole.log(porReferencia1, porReferencia2); //[ 1, 2, 3 ] [ 'a', 'e', 'i', 'o', 'u' ]\nconsole.log(nuevoPorReferencia1, nuevoPorReferencia2); //[ 'a', 'e', 'i', 'o', 'u' ] [ 1, 2, 3 ]\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/typescript/david-git-dev.ts",
    "content": "//Ejemplo de asignación por valor:\nlet a = 10;\nlet b = a;  // b obtiene una copia del valor de a\nb = 20;     // Cambiamos el valor de b\n\nconsole.log(a);  // 10 (a permanece sin cambios)\nconsole.log(b);  // 20 (b cambió independientemente de a)\n//Aquí, b tiene una copia independiente del valor de a, por lo que cambiar b no afecta a a.\n\n//Ejemplo de asignación por referencia:\nlet obj1 = { name: 'John' };\nlet obj2 = obj1;  // obj2 apunta al mismo objeto que obj1\n\nobj2.name = 'Jane';  // Cambiamos la propiedad \"name\" a través de obj2\n\nconsole.log(obj1.name);  // 'Jane' (obj1 también refleja el cambio)\nconsole.log(obj2.name);  // 'Jane' (obj2 muestra el mismo objeto)\n//En este caso, obj1 y obj2 apuntan al mismo objeto en la memoria, por lo que un cambio en obj2 afecta también a obj1.\n\n//Otro ejemplo con arrays:\nlet arr1 = [1, 2, 3];\nlet arr2 = arr1;  // arr2 apunta al mismo array que arr1\n\narr2.push(4);  // Modificamos el array a través de arr2\n\nconsole.log(arr1);  // [1, 2, 3, 4] (arr1 también refleja el cambio)\nconsole.log(arr2);  // [1, 2, 3, 4] (arr2 muestra el mismo array)\n/* Diferencia clave:\nPor valor: Los cambios en una copia no afectan a la variable original.\nPor referencia: Los cambios en una copia (referencia) afectan a la variable original, ya que ambas apuntan al mismo lugar en la memoria. */\n//ASIGNACION POR VALOR Y REFERENCIAS EN FUNCIONES\n// Ejemplo de paso por valor:\nfunction changeValue(x:number) {\n  x = 20;   // Modificamos el valor de x dentro de la función\n  console.log(x);  // 20\n}\n\nlet aa = 10;\nchangeValue(aa);    // Pasamos el valor de a (10) a la función\nconsole.log(aa);    // 10 (a no cambia porque se pasó por valor)\n//En este caso, el valor de a permanece inalterado fuera de la función porque x es una copia del valor de a, no la variable en sí.\n\n//Pasar parámetros por referencia en funciones\n/* Cuando pasas un objeto (incluyendo arrays) como argumento a una función, lo que se pasa es una referencia al objeto original en la memoria. Esto significa que si la función modifica el objeto, el cambio se reflejará fuera de la función también. */\n\nfunction modifyObject(obj:{name:string}) {\n  obj.name = 'Jane';   // Modificamos una propiedad del objeto\n}\n\nlet person = { name: 'John', age: 30 };\nmodifyObject(person);   // Pasamos el objeto a la función\nconsole.log(person.name);  // 'Jane' (El objeto fue modificado)\n/* En este caso, la función modifyObject cambia la propiedad name del objeto person. Como obj es una referencia a person, cualquier cambio dentro de la función afecta el objeto original. */\n\n//Ejemplo con arrays (paso por referencia):\nfunction addToArray(arr:number[]) {\n  arr.push(4);   // Modificamos el array añadiendo un nuevo valor\n}\n\nlet numbers = [1, 2, 3];\naddToArray(numbers);  // Pasamos el array a la función\nconsole.log(numbers);  // [1, 2, 3, 4] (El array fue modificado)\n/* Aquí, el array numbers es modificado dentro de la función, porque el array se pasa por referencia. Cualquier cambio en el array dentro de la función afecta el array original. */\n/* DIFICULTAD EXTRA (opcional):\n  Crea dos programas que reciban dos parámetros (cada uno) definidos como\n  variables anteriormente.\n  - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n    Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n    se asigna a dos variables diferentes a las originales. A continuación, imprime\n    el valor de las variables originales y las nuevas, comprobando que se ha invertido\n    su valor en las segundas.\n    Comprueba también que se ha conservado el valor original en las primeras. */\n    let option:string\n    do{\noption = prompt(`\n 1.- asignacion por valor\n 2.- asignacion por referencia\n *- Salir\n  `) || ''\nswitch (option) {\n  case '1':\n    const [first,second]= [prompt('dame el valor 1'),prompt('dame el valor 2')]\n    assignByValue(first||'',second||'')\n    break;\n    case '2':\n      const [x,y]= [prompt('dame la referencia x')?.split('')||' '.split(''),prompt('dame la referencia y')?.split('')||' '.split('')]\n    assigByReference(x,y)\n      break;\n\n  default:\n    break;\n}\n    }while(['1','2'].some(select=> select===option))\n\nfunction assignByValue(firstVar:string,secondVar:string){\n  const [firstValue,secondValue] = [secondVar,firstVar]\n  console.log(` Los valores ahora son:\n    ${firstValue}<=>${firstVar}\n    ${secondValue}<=>${secondVar}\n    `)\n}\nfunction assigByReference(originalx:string[],originaly:string[]) {\nlet referenceX= originalx;\nlet referenceY = originaly;\nlet temp = referenceX\nreferenceX = referenceY\nreferenceY = temp\nreferenceX.push('?')// ejemplo intentando alterar las referencias\nreferenceY.push('¿')\n  console.log(` Los valores ahora son:\n    ${referenceX.join('')}<=>${originalx.join('')}\n    ${referenceY.join('')}<=>${originaly.join('')}\n    `)\n}"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/typescript/duendeintemporal.ts",
    "content": "//#5 { Retosparaprogramadores } Valor y Referencia\n// I use GPT and deepseek for translation. generate comments an also as a reference.\n\nlet log = console.log;\n\n//Variables by Value\n\n/*Primitive data types in JavaScript (such as number, string, boolean, null, undefined, and symbol) are assigned by value. This means that when you assign a primitive value to a variable, a copy of that value is made.*/\n\nlet a: number = 44; // a is a number (primitive type)\nlet b: number = a;  // b is assigned the value of a\n\nlog(a); //  44\nlog(b); //  44\n\nb += 20; // Changing b does not affect a\nlog(a); //  44\nlog(b); //  64\n\n//Variables by Reference\n\n/*Reference data types in JavaScript (such as object, array, and function) are assigned by reference. This means that when you assign an object to a variable, you are actually assigning a reference to that object, not a copy of it.*/\n\n\nlet obj1: { name: string, age?: number } = { name: \"Julia\" }; // obj1 is an object (reference type)\nlet obj2: { name: string, age?: number } = obj1; // obj2 is assigned the reference of obj1\n\nlog(obj1.name); //  Julia\nlog(obj2.name); //  Julia\n\nobj2.name = \"Karla\"; // Changing obj2 affects obj1 because they reference the same object\nlog(obj1.name); //  Karla\nlog(obj2.name); //  Karla\n\nobj2.age = 32;\nlog(obj2.age)// 32\nlog(obj1.age)// 32\n\n//Arrays (Reference Type) in JavaScript are also reference types.\n\nlet arr1: number[] = [7, 4, 90]; // arr1 is an array (reference type)\nlet arr2: number[] = arr1; // arr2 is assigned the reference of arr1\n\nlog(arr1); //  [7, 4, 90]\nlog(arr2); //  [7, 4, 90]\n\narr2.push(42); // Modifying arr2 affects arr1\nlog(arr1); //  [7, 4, 90, 42]\nlog(arr2); //  [7, 4, 90, 42]\n\n/*    By Value: Primitive types (e.g., number, string) are copied when assigned to a new variable.\n    By Reference: Reference types (e.g., object, array) are assigned by reference, meaning changes to one variable affect the other if they reference the same object. */\n\n  /*  In JavaScript, functions are also treated as first-class objects, which means they can be assigned to variables, passed as arguments, and returned from other functions. When you assign a function to a variable, you are assigning a reference to that function, not a copy of it. Here are some examples to illustrate how functions work with reference: */\n    \n    //Functions Assigned by Reference\n    \n    //When you assign a function to a new variable, both variables point to the same function in memory.\n        \n    function greet(): void {\n        log(\"Hello everybody! is time for coding...\");\n    }\n    \n    let greetCopy: Function = greet; // greetCopy is assigned the reference of greet\n    \n    greet();      // Hello everybody! is time for coding...\n    greetCopy();  // Hello everybody! is time for coding...\n    \n    // Changing the function reference\n    greetCopy = function(): void {\n        log(\"This world is turning into a weird scenario with all those AIs, M2M (technology), and there are cyber attacks that can explode beepers, cell phones, and a big media that shows only a tiny fragment of reality. \");\n    };\n    \n    greet();      // Hello everybody! is time for coding...\n    greetCopy();  //This world is turning into a weird scenario with all those AIs, M2M (technology), and there are cyber attacks that can explode beepers, cell phones, and big media that shows only a tiny fragment of reality.\n    \n    // Passing Functions as Arguments\n    \n    //You can pass functions as arguments to other functions. This demonstrates that functions are treated as reference types.\n    \n       \n    function callFunct(fn): void {\n        fn();\n    }\n    \n    function sayByeLady(): void {\n        log(\"See you later, lady!\");\n    }\n    \n    callFunct(sayByeLady); // See you later, lady\n    \n    //Returning Functions from Functions\n    \n    //You can also return functions from other functions, which shows that functions can be created dynamically and assigned by reference.\n    \n        \n    function saySomethingTo(greeting): Function {\n        return function(name: string): void {\n            log(`${greeting}, ${name}!`);\n        };\n    }\n    \n    let say: Function = saySomethingTo(\"Wellcome to coding lab\");\n    let say2: Function = saySomethingTo(\"Is a long way home\");\n    \n    say(\"Nicky\"); // Wellcome to coding lab, Nicky\n    say2(\"Jhon\");      // Is a long way home, Jhon\n    \n    //  Modifying Functions\n    \n    //Since functions are reference types, if you modify a function that is referenced by multiple variables, it will affect all references.\n    \n// Define a type for the function to make it reusable and explicit\ntype GreetingFunction = () => any;\n// Note: I decide to use 'any' type for the porpouse of show a possibility of use a Immediately Invoked Function Expression (IIFE) later, but have more sanse 'void' type. \n\n// Original function (use `let` instead of `const` to allow reassignment)\nlet hiMiss: GreetingFunction = () => {\n    console.log(\"Hello, miss. Have a beautiful day\");\n};\n\n// Assign the function reference\nlet funcRef: GreetingFunction = hiMiss;\n\n// Call the function reference\nfuncRef(); // Output: Hello, miss. Have a beautiful day\n\n// Modify the original function\nhiMiss = (): void => {\n    console.log(\"Sometimes I feel jealous of the wind that caresses your hair, sometimes the rain....\");\n};\n\n// Call the function reference again\nfuncRef(); // Output: Hello, miss. Have a beautiful day (still points to the original function)\n\n// Define funcRef as a higher-order function that returns a GreetingFunction\nfuncRef = (): GreetingFunction => {\n    return hiMiss;\n};\n\n// Call the higher-order function and then invoke the returned function\n(funcRef())(); // Output: Sometimes I feel jealous of the wind that caresses your hair, sometimes the rain....\n\n/*  In JavaScript, when you pass arguments to a function, the behavior depends on whether the argument is a primitive type (passed by value) or a reference type (passed by reference). Here’s an example that demonstrates both concepts:  */\n      \n\n// Function that takes a primitive type (passed by value)\nfunction doSomething(value: any): void {\n    value = 20; // This change does not affect the original variable\n    log(\"Value Inside doSomething:\", value); // Value Inside doSomething: 20\n}\n\n// Testing the functions\nlet val: string = 'something';\nlog(\"Value Before doSomething:\", val); // Value Before doSomething: something\ndoSomething(val); // Value Inside setUserName: 20\nlog(\"After doSomething:\", val); // After doSomething: something (remains unchanged)\n\n// Function that takes an object (passed by reference)\nfunction setUserName(obj: { name: string, age: number }, name: string) {\n    obj.name = name; // This change affects the original object\n    log(\"Value Inside setUserName:\", obj.name); \n}\n\nlet user: { name: string, age: number } = { name: \"Luna\", age: 32 };\nlog(\"Before setUserName:\", user.name); // Before setUserName: Luna\nsetUserName(user, 'Kia'); // Value Inside setUserName: Kia\nlog(\"After setUserName:\", user.name); // After setUserName: Kia (changed)\n\n//Note: the same apply to arrays that are reference values.\n\n    log( 'Retosparaprogramadores #5'); // Retosparaprogramadores #5 \n\n\n\n/* EXTRA DIFFICULTY (optional):\n\n    Create two programs that receive two parameters (each) defined as variables previously.\n    One program receives, in one case, two parameters by value, and in another case, by reference.\n    These parameters are swapped between each other internally, returned, and their return values are assigned to two variables different from the originals. Then, print the value of the original variables and the new ones, checking that their values have been inverted in the second set.\n    Also verify that the original values have been preserved in the first set.\n */\n\nlet user1: { name: string, age: number } = {\n    name: 'Kasperle',\n    age: 12\n}\n\nlet user2: { name: string, age: number } = {\n    name: 'Snoopy',\n    age: void(0)\n}\n\nlog('user1: ', user1);// user1: Object { name: \"Kasperle\", age: 12 }\nlog('user2: ', user2);// user2: Object { name: \"Snoopy\", age: undefined }\n\nfunction changeUser(obj1: { name: string, age: number }, obj2: { name: string, age: number }): void {\n   const provisional = {};\n    Object.assign(provisional, obj1);// Object.assign allow a deep copy\n    Object.assign(obj1, obj2);\n    Object.assign(obj2, provisional);\n   // return [obj1, obj2] \n   // We can return the objects in an array, but it becomes unnecessary because objects are treated as reference values. Therefore, the function will affect the original objects directly.\n}\n\nchangeUser(user1, user2)\n\nlog('user1: ', user1);// user1: Object { name: \"Snoopy\", age: undefined }\nlog('user2: ', user2);// user2: Object { name: \"Kasperle\", age: 12 }\n\nfunction swapValues(a: number, b: number) {\n    return { a: b, b: a }; // Return an object with swapped values\n}\n\nlet x: number = 85;\nlet y: number = 17;\n\nconsole.log(\"Before swap: \", x, y); // Before swap: 85 17\n\n// Declare `d` and `e` before using them in destructuring\nlet d: number, e: number;\n// Call the function and destructure the returned object into new variables\n({ a: d, b: e } = swapValues(x, y));\n\nconsole.log(\"After swap: \", x, y); // After swap: 85 17 (original values preserved)\nconsole.log(\"New variables with values swapped: \", d, e); // New variables with values swapped: 17 85\n\n// Now, swap the values in place by updating the original variables\nconsole.log(\"Before swap: \", x, y); // Before swap: 85 17\n({ a: x, b: y } = swapValues(x, y));\n\nconsole.log(\"After swap: \", x, y); // After swap: 17 85 (original values updated)\n\n/*\n * Note: Destructuring allows us to achieve both effects:\n * - Preserving original values by assigning swapped values to new variables.\n * - Swapping values in place by updating the original variables.\n *\n * Note 2: Destructuring creates a shallow copy. If objects are nested, the nested objects are not copied.\n */"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/typescript/eulogioep.ts",
    "content": "// Función para imprimir resultados\nfunction print(message: string): void {\n    console.log(message);\n}\n\n// Ejemplos de asignación por valor (tipos primitivos)\nlet a: number = 5;\nlet b: number = a; // b es una copia del valor de a\nb = 10; // Cambiar b no afecta a a\nprint(`Asignación por valor: a: ${a}, b: ${b}`); // a: 5, b: 10\n\n// Ejemplos de asignación por referencia (objetos y arrays)\nlet arr1: number[] = [1, 2, 3];\nlet arr2: number[] = arr1; // arr2 apunta al mismo array que arr1\narr2[0] = 100; // Cambiar arr2 afecta a arr1\nprint(`Asignación por referencia: arr1[0]: ${arr1[0]}, arr2[0]: ${arr2[0]}`); // arr1[0]: 100, arr2[0]: 100\n\n// Función con parámetro por valor\nfunction modificarValor(n: number): void {\n    n = 100; // Este cambio no afecta a la variable original\n}\n\nlet x: number = 5;\nmodificarValor(x);\nprint(`x después de modificarValor: ${x}`); // x no cambia\n\n// Función con parámetro por referencia\nfunction modificarReferencia(arr: number[]): void {\n    arr[0] = 100; // Este cambio afecta al array original\n}\n\nlet array: number[] = [1, 2, 3];\nmodificarReferencia(array);\nprint(`array[0] después de modificarReferencia: ${array[0]}`); // array[0] cambia\n\n// DIFICULTAD EXTRA\n// Función para intercambio por valor\nfunction intercambioPorValor(a: number, b: number): [number, number] {\n    let temp: number = a;\n    a = b;\n    b = temp;\n    return [a, b];\n}\n\n// Interfaz para el objeto de intercambio por referencia\ninterface IntercambioObj {\n    a: number;\n    b: number;\n}\n\n// Función para intercambio por referencia\nfunction intercambioPorReferencia(obj: IntercambioObj): IntercambioObj {\n    let temp: number = obj.a;\n    obj.a = obj.b;\n    obj.b = temp;\n    return { a: obj.a, b: obj.b };\n}\n\n// Programa 1: Intercambio por valor\nlet num1: number = 10, num2: number = 20;\nprint(`Antes del intercambio por valor: num1 = ${num1}, num2 = ${num2}`);\nlet [nuevoNum1, nuevoNum2] = intercambioPorValor(num1, num2);\nprint(\"Después del intercambio por valor:\");\nprint(`Variables originales: num1 = ${num1}, num2 = ${num2}`);\nprint(`Nuevas variables: nuevoNum1 = ${nuevoNum1}, nuevoNum2 = ${nuevoNum2}`);\n\n// Programa 2: Intercambio por referencia\nlet obj: IntercambioObj = { a: 30, b: 40 };\nprint(`\\nAntes del intercambio por referencia: obj.a = ${obj.a}, obj.b = ${obj.b}`);\nlet nuevoObj: IntercambioObj = intercambioPorReferencia(obj);\nprint(\"Después del intercambio por referencia:\");\nprint(`Objeto original: obj.a = ${obj.a}, obj.b = ${obj.b}`);\nprint(`Nuevo objeto: nuevoObj.a = ${nuevoObj.a}, nuevoObj.b = ${nuevoObj.b}`);"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/typescript/giovanyosorio.ts",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\n\n// Asignación por valor (tipos primitivos)\nlet num1: number = 10;\nlet num2: number = num1;\nnum2 = 20;\nconsole.log(num1); // 10 (no cambia)\nconsole.log(num2); // 20\n\n\n// Asignación por referencia (objetos)\nlet obj1: { prop: number } = { prop: 10 };\nlet obj2: { prop: number } = obj1;\nobj2.prop = 20;\nconsole.log(obj1.prop); // 20 (cambia)\nconsole.log(obj2.prop); // 20\n\n\n// Función con paso por valor\nfunction incrementaPorValor(num: number): number {\n    return num + 1;\n}\n\nlet a: number = 5;\nlet b: number = incrementaPorValor(a);\nconsole.log(a); // 5 (no cambia)\nconsole.log(b); // 6\n\n// Función con paso por referencia\nfunction modificaObjeto(obj: { prop: number }): void {\n    obj.prop += 1;\n}\n\nlet objA: { prop: number } = { prop: 5 };\nmodificaObjeto(objA);\nconsole.log(objA.prop); // 6 (cambia)\n\n// Intercambio por valor\nfunction intercambiaPorValor(x: number, y: number): [number, number] {\n    let temp: number = x;\n    x = y;\n    y = temp;\n    return [x, y];\n}\n\nlet valor1: number = 10;\nlet valor2: number = 20;\nlet [nuevoValor1, nuevoValor2] = intercambiaPorValor(valor1, valor2);\nconsole.log(valor1, valor2); // 10, 20 (no cambian)\nconsole.log(nuevoValor1, nuevoValor2); // 20, 10\n\n// Intercambio por referencia\nfunction intercambiaPorReferencia(obj1: { value: number }, obj2: { value: number }): void {\n    let temp: number = obj1.value;\n    obj1.value = obj2.value;\n    obj2.value = temp;\n}\n\nlet objValor1: { value: number } = { value: 10 };\nlet objValor2: { value: number } = { value: 20 };\nintercambiaPorReferencia(objValor1, objValor2);\nconsole.log(objValor1.value, objValor2.value); // 20, 10 (cambian)\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/typescript/hozlucas28.ts",
    "content": "/*\n    Variable assignment by value...\n*/\n\nconsole.log('Variable assignment by value...')\n\nlet a: number = 5\nconst b: number = a\n\nconsole.log(`\\nlet a: number = 5\nconst b: number = a`)\nconsole.table({ a, b }) // { a: 5, b: 5 }\n\na = a * 2\n\nconsole.log(`\\na = a * 2`)\nconsole.table({ a, b }) // { a: 10, b: 5 }\n\nconsole.log('\\n# ---------------------------------------------------------------------------------- #')\n\n/*\n    Variable assignment by reference...\n*/\n\nconsole.log('\\nVariable assignment by reference...')\n\nconst c: Record<'First property', number> = {\n\t'First property': 6,\n}\nconst d: Record<'First property', number> = c\nconsole.log(`\\nconst c: Record<string, number> = { 'First property': 6 }\nconst d: Record<'First property', number> = c`)\n\nconsole.table({ c, d })\n\nc['First property'] = 6 * 3\nconsole.log(`\\nc['First property'] = 6 * 3`)\n\nconsole.table({ c, d })\n\nconsole.log('\\n# ---------------------------------------------------------------------------------- #')\n\n/*\n    Function with an argument passed by value...\n*/\n\nconsole.log('\\nFunction with an argument passed by value...')\n\nconst value: number = 10\nfunction fnWithParamenterByValue(x: number) {\n\tx += x\n}\n\nconsole.log('\\nconst value: number = 10')\nconsole.log(`function fnWithParamenterByValue(x: number) {\n    x += x\n}`)\n\nfnWithParamenterByValue(value)\nconsole.log('\\nfnWithParamenterByValue(value)')\n\nconsole.table({ value })\n\n/*\n    Function with an argument passed by reference...\n*/\n\nconsole.log('\\nFunction with an argument passed by reference...')\n\nconst reference: { zipCode: number } = { zipCode: 127 }\nfunction fnWithParamenterByReference(params: { zipCode: number }) {\n\tparams.zipCode = params.zipCode * 2\n}\n\nconsole.log('\\nconst reference: { zipCode: number } = { zipCode: 127 }')\nconsole.log(`function fnWithParamenterByReference(params: { zipCode: number }) {\n    params.zipCode = params.zipCode * 2\n}`)\n\nfnWithParamenterByReference(reference)\nconsole.log('\\nfnWithParamenterByReference(reference)')\n\nconsole.table({ reference })\n\nconsole.log('\\n# ---------------------------------------------------------------------------------- #\\n')\n\n/*\n    Additional challenge...\n*/\n\nfunction firstProgram(param01: number, param02: number): [number, number] {\n\tconst aux: number = param01\n\tparam01 = param02\n\tparam02 = aux\n\treturn [param01, param02]\n}\n\nfunction secondProgram(\n\tparam01: Record<'firstName', string>,\n\tparam02: Record<'firstName', string>\n): [Record<'firstName', string>, Record<'firstName', string>] {\n\tconst aux: string = param01.firstName\n\tparam01.firstName = param02.firstName\n\tparam02.firstName = aux\n\treturn [param01, param02]\n}\n\nconst arg01: number = 12\nconst arg02: number = 34\nconst arg03: Record<'firstName', string> = { firstName: 'Lucas' }\nconst arg04: Record<'firstName', string> = { firstName: 'Nahuel' }\n\nconst [newArg01, newArg02]: [number, number] = firstProgram(arg01, arg02)\nconst [newArg03, newArg04]: [Record<string, string>, Record<string, string>] = secondProgram(arg03, arg04)\n\nconsole.table({\n\toriginal: [arg01, arg02],\n\tnew: [newArg01, newArg02],\n})\n\nconsole.table({\n\toriginal: [arg03, arg04],\n\tnew: [newArg03, newArg04],\n})\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/typescript/ialmontedr0.ts",
    "content": "/**\r\n * Asignacion de variables por valor\r\n */\r\n\r\nlet cadenaPorValor: string = \"Cadena original\";\r\ncadenaPorValor = \"Cadena modificada\";\r\n\r\nlet numeroPorValor: number = 10;\r\nnumeroPorValor = 20;\r\n\r\nlet arregloPorValor: number[] = [1, 2, 3];\r\narregloPorValor[0] = 4;\r\n\r\nlet objetoPorValor: { nombre: string; edad: number } = {\r\n  nombre: \"Anthony\",\r\n  edad: 26,\r\n};\r\nobjetoPorValor.nombre = \"Hector\";\r\n\r\nlet undefinedPorValor: undefined | null = undefined;\r\nundefinedPorValor = null;\r\n\r\nlet symbolPorValor: symbol = Symbol(\"Simbolo\");\r\nsymbolPorValor = Symbol(\"Simbolo modificado\");\r\n\r\nlet tuplaPorValor: [string, number, boolean] = [\"Cadena\", 10, true];\r\ntuplaPorValor[0] = \"Cadena modificada\";\r\n\r\nconsole.log(`\r\n    Variables por valor:\r\n    - Cadena: ${cadenaPorValor}\r\n    - Número: ${numeroPorValor}\r\n    - Arreglo: ${arregloPorValor.join(\", \")}\r\n    - Objeto: ${JSON.stringify(objetoPorValor)}\r\n    - Undefined: ${undefinedPorValor}\r\n    - Simbolo: ${symbolPorValor}\r\n    - Tupla: ${JSON.stringify(tuplaPorValor)}\r\n`);\r\n\r\n/**\r\n * Asignacion de variables por referencia\r\n */\r\n\r\nlet objetoPorReferencia: { nombre: string; edad: number } = {\r\n  nombre: \"Anthony\",\r\n  edad: 26,\r\n};\r\nlet objetoPorReferencia2: { nombre: string; edad: number } =\r\n  objetoPorReferencia;\r\n\r\nobjetoPorReferencia2.edad = 27;\r\n\r\nconsole.log(`\r\n    Variables por referencia:\r\n    - Objeto original: ${JSON.stringify(objetoPorReferencia)}\r\n    - Objeto modificado: ${JSON.stringify(objetoPorReferencia2)}\r\n    `);\r\n\r\n/**\r\n * Funciones con variables por valor\r\n */\r\n\r\n// Funcion que recibe dos parametros y devuelve una suma\r\nfunction sumaPorValor(valorA: number, valorB: number): number {\r\n  valorA += valorB; // Esta linea modifica el valor de valorA en la función\r\n  return valorA; // Retorna el valor modificado de valorA\r\n}\r\n\r\nsumaPorValor(5, 10); // Llama a la función con valores por valor\r\n\r\n/**\r\n * Funciones con variables por referencia\r\n */\r\n\r\n// Funcion que recibe dos parametros y los modifica en ellos\r\nfunction sumaPorReferencia(valorA: number, valorB: number): void {\r\n  valorA += valorB; // Esta linea modifica el valor de valorA en la función\r\n  valorB = 0; // Esta linea modifica el valor de valorB en la función\r\n  console.log(`\r\n        Variables modificadas en la función:\r\n        - Valor A: ${valorA}\r\n        - Valor B: ${valorB}\r\n    `);\r\n}\r\n\r\nsumaPorReferencia(5, 10); // Llama a la función con valores por referencia\r\n\r\n/**\r\n * Ejercicio extra (intercambio de variables)\r\n */\r\n\r\nfunction ejercicioUnoExtra(valor1: number, valor2: number): void {\r\n  let temp: number = valor1; // Asigna el valor de valor1 a una variable temporal\r\n  valor1 = valor2; // Asigna el valor de valor2 a valor1\r\n  valor2 = temp; // Asigna el valor de la variable temporal a valor2\r\n  console.log(`\r\n        Variables intercambiadas en el ejercicio extra:\r\n        - Valor 1: ${valor1}\r\n        - Valor 2: ${valor2}\r\n    `);\r\n  // Comprueba que se ha intercambiado el valor de los parámetros\r\n  console.log(`\r\n        Variables originales en el ejercicio extra:\r\n        - Valor 1: ${valor1}\r\n        - Valor 2: ${valor2}\r\n    `);\r\n}\r\n\r\nfunction ejercicioDosExtra(valor1: number, valor2: number): void {\r\n  let temp: number = valor1; // Asigna el valor de valor1 a una variable temporal\r\n  valor1 = valor2; // Asigna el valor de valor2 a valor1\r\n  valor2 = temp; // Asigna el valor de la variable temporal a valor2\r\n  console.log(`\r\n        Variables intercambiadas en el ejercicio extra:\r\n        - Valor 1: ${valor1}\r\n        - Valor 2: ${valor2}\r\n    `);\r\n  // Comprueba que se ha conservado el valor original de los parámetros\r\n  console.log(`\r\n        Variables originales en el ejercicio extra:\r\n        - Valor 1: ${valor1}\r\n        - Valor 2: ${valor2}\r\n    `);\r\n}\r\n\r\nejercicioUnoExtra(10, 20); // Llama al ejercicio con variables por valor\r\nejercicioDosExtra(10, 20); // Llama a los ejercicios con variables por referencia\r\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/typescript/igledev.ts",
    "content": "// 1º Ejemplos de asignación de variables por valor\nlet n1: number = 5;\nlet n2: number = n1;\n\nconsole.log('Antes de la modificación: n1 = ' + n1 + ' n2 = ' + n2);\n\nn1 = 10;\n\nconsole.log('Después de la modificación: n1 = ' + n1 + ' n2 = ' + n2);\n\n// 2º Ejemplos de asignación de variables por referencia\ninterface Persona {\n    nombre : string;\n    edad : number;\n    trabajo : string;\n}\n\nlet programador1 : Persona = { nombre: \"Arrian\", edad: 25 , trabajo : 'desarrolador'};\nlet programador2 : Persona = programador1;\n\nprogramador2.nombre = 'Adrián';\nconsole.log('Valor original: ' + programador1.nombre);\nconsole.log('Valor cambiado: ' + programador2.nombre);\n\n// 3º Funciones con parametros por valor\nfunction gritar(cadena : string): string {\n    return cadena.toUpperCase();\n}\n\nlet cadenaOg : string = 'Igledev'\nlet cadenaMod : string = gritar(cadenaOg);\n\nconsole.log('Valor original: ' + cadenaOg);\nconsole.log('Valor cambiado: ' + cadenaMod);\n\n// 4º Funciones con parametros por referencia\nfunction incrementarEdad(persona: Persona): void {\n    persona.edad++;\n}\n\nlet programador3: Persona = { nombre: \"Ana\", edad: 22 , trabajo : 'Desarrolladora'};\nconsole.log('Edad antes de la función: ' + programador3.edad);\n\nincrementarEdad(programador3);\n\nconsole.log('Edad después de la función: ' + programador3.edad);\n\n// Ejercicio Extra\n// Por valor\n    function intercambiarValor(valor1 : number, valor2 : number): [number, number] {\n        let temp: number = valor1;\n        valor1 = valor2;\n        valor2 = temp;\n        return [valor1, valor2];\n    }\n\n    let valor1: number = 5;\n    let valor2: number = 10;\n\n    console.log('Antes de la modificación: valor1 = ' + valor1 + ' valor2 = ' + valor2);\n\n    let [nuevoValor1, nuevoValor2] = intercambiarValor(valor1, valor2);\n\n    console.log('Después de la modificación: valor1 = ' + valor1 + ' valor2 = ' + valor2);\n    console.log('Valores intercambiados: valor1 = ' + nuevoValor1 + ' valor2 = ' + nuevoValor2);\n\n// Por Referencia\n    interface Datos {\n        dato1: number;\n        dato2: number;\n    }\n\n    function intercambiarReferencia(datos: Datos): Datos {\n        let temp: number = datos.dato1;\n        datos.dato1 = datos.dato2;\n        datos.dato2 = temp;\n        return datos;\n    }\n\n    let datosOriginales: Datos = { dato1: 5, dato2: 10 };\n\n    console.log('Antes del intercambio: datosOriginales = ' + JSON.stringify(datosOriginales));\n\n    let nuevosDatos = intercambiarReferencia({ ...datosOriginales });\n\n    console.log('Después del intercambio: datosOriginales = ' + JSON.stringify(datosOriginales));\n    console.log('Valores intercambiados: nuevosDatos = ' + JSON.stringify(nuevosDatos));"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/typescript/jesusEs1312.ts",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\n//--- Variables por valor\nlet numero: number = 21;\nlet numero2: number = numero + 10;\nlet numero3: number = numero2;\nconsole.log(`numero: ${numero} | numero2: ${numero2} | numero3: ${numero3}`);\n\n//--- Variables por referencia\nlet numArray: number[] = [10, 20, 30];\nlet numArray2: number[] = numArray;\nnumArray2.push(50);\nconsole.log(`${numArray} | ${numArray2}`);\n\n//--- Función que muestra el comportamiento de variables por valor\nconst variablePorValor = (num: number) => {\n    num = num * 2;\n    console.log(`El valor de num dentro de la función: ${num}`);\n};\n\nvariablePorValor(numero);//Ejecutamos la función pasandole por parametro la variable 'numero' que vale 21\nconsole.log(`El valor de num fuera de la función: ${numero}`);\n\n//--- Función que muestra el comportamiento de variable por referencia\nlet arrayNumbers: number[] = [1, 2, 3];\nconst variablePorReferencia = (arrayNumbers) => {\n    arrayNumbers[0] = arrayNumbers[0] * 10;\n    console.log(`El valor dentro de la función de arrayNumbers[0] es: ${arrayNumbers[0]}`);\n};\n\nvariablePorReferencia(arrayNumbers);//Ejecutamos la función pasandole por parametro el arrayNumbers \nconsole.log(`El valor fuera de la función de arrayNumbers[0] es: ${arrayNumbers[0]}`);\n\n//--- Ejercicio Extra\n\n//--- Función por valor \nlet variableOriginal1: number = 5;\nlet variableOriginal2: number = 9;\n\nfunction programaPorValor(param1: number, param2: number): [number, number] {\n    let tempParam1 = param1;\n    param1 = param2;\n    param2 = tempParam1;\n    return [param1, param2];\n}\n\nconsole.log(`Variable Original 1: ${variableOriginal1}`);\nconsole.log(`Variable Original 1: ${variableOriginal2}`);\n\nlet nuevasVariablesPorValor: [number, number] = programaPorValor(variableOriginal1, variableOriginal2);\nconsole.log(`Nueva Variable 1: ${nuevasVariablesPorValor[0]}`);\nconsole.log(`Nueva Variable 2: ${nuevasVariablesPorValor[1]}`);\n\n//--- Función por referencia\nfunction programaPorReferencia(persona1: Persona, persona2: Persona): [string, string]{\n    let tempHobbie: string = persona1.hobbie; \n    persona1.hobbie = persona2.hobbie;\n    persona2.hobbie = tempHobbie;\n    return [persona1.hobbie, persona2.hobbie]; \n}\n\nlet personaOriginal1: Persona = {\n    nombre: \"Peter\",\n    edad: 23,\n    hobbie: \"Fotografia\"\n}\n\nlet personaOriginal2: Persona = {\n    nombre: \"Chuy\",\n    edad: 25,\n    hobbie: \"Guitarra\"\n}\n\nconsole.log(`Hobbie de persona 1 Original: ${personaOriginal1.hobbie}`);\nconsole.log(`Hobbie de persona 2 Original: ${personaOriginal2.hobbie}`);\n\nlet nuevasPersonas: [string, string] = programaPorReferencia(personaOriginal1, personaOriginal2);\n\nconsole.log(`Nuevo Hobbie de persona 1: ${nuevasPersonas[0]}`);\nconsole.log(`Nuevo Hobbie de persona 2: ${nuevasPersonas[1]}`);\n\ninterface Persona {\n    nombre: string,\n    edad: number,\n    hobbie: string\n}"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/typescript/juserdev.ts",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\nlet variable1 = 10\nlet variable2 = variable1\n// variable2 = 20\nvariable1 = 30\nconsole.log(variable1)\nconsole.log(variable2)\n\n// tipos de datos por refernecia\n\nlet myListA = [10, 20]\nlet myListb = myListA\nmyListb.push(30) //aqui se agrego el valor a ambos arrays\nconsole.log(myListA)\nconsole.log(myListb)\n\nlet myNumber: number = 10\n\nfunction myFunctionA(myInt:number):number {\n    myInt = 20\n    return myInt\n}\n\nconsole.log(myFunctionA(myNumber))\nconsole.log(myNumber)\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/typescript/kodenook.ts",
    "content": "/*\n    Assignment By Value\n*/\n\nlet var1: number = 3;\nlet var2: number = var1;\n\nvar1 = 4;\n\nconsole.log(var1)\nconsole.log(var2)\n\n/*\n    Assignment By Reference\n*/\n\nlet var3: number[] = [10, 20]\nlet var4: number[] = var3\n\nvar3.push(30)\n\nconsole.log(var3)\nconsole.log(var4)\n\n/*\n    Exercise\n*/\n\nfunction ByValue(a: number, b: number): number[] {\n    let c = b\n    let d = a\n\n    return [c, d]\n}\n\nlet original1: number = 20\nlet original2: number = 30\nlet values: number[] = ByValue(original1, original2)\n\nconsole.log('By Values')\nconsole.log('Original Values')\nconsole.log(original1)\nconsole.log(original2)\nconsole.log('After Function Values')\nconsole.log(values[0])\nconsole.log(values[1])\n\nfunction ByReference(a: number, b: number): number[] {\n    let c = b\n    let d = a\n\n    return [c, d]\n}\n\nlet original3: number = 20\nlet original4: number = 30\nlet values2: number[] = ByReference(original3, original4)\n\nconsole.log('By Reference')\nconsole.log('Original Values')\nconsole.log(original3)\nconsole.log(original4)\nconsole.log('After Function Values')\nconsole.log(values2[0])\nconsole.log(values2[1])"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/typescript/marcode24.ts",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\n// Ejemplo de asignación por valor para tipos primitivos\nconst num1: number = 10;\nlet num2: number = num1; // Asignación por valor\nnum2 = 20;\n\nconsole.log(num1); // Salida: 10 (valor original no cambia)\nconsole.log(num2); // Salida: 20\n\n// Ejemplo de asignación por referencia para objetos\ninterface Persona {\n  nombre: string;\n}\n\nconst obj1: Persona = { nombre: 'Juan' };\nconst obj2: Persona = obj1; // Asignación por referencia\nobj2.nombre = 'Carlos';\n\nconsole.log(obj1.nombre); // Salida: Carlos (el valor original cambia)\nconsole.log(obj2.nombre); // Salida: Carlos\n\n// Ejemplo de función que recibe parámetros por valor\nfunction duplicar(numero: number): number {\n  numero *= 2;\n  return numero;\n}\n\nconst original: number = 5;\nconst resultado: number = duplicar(original);\n\nconsole.log(original); // Salida: 5 (el valor original no cambia)\nconsole.log(resultado); // Salida: 10\n\n// Ejemplo de función que recibe parámetros por referencia (objeto)\nfunction cambiarNombre(persona: Persona): void {\n  persona.nombre = 'Pedro';\n}\n\nconst personaOriginal: Persona = { nombre: 'Juan' };\ncambiarNombre(personaOriginal);\n\nconsole.log(personaOriginal.nombre); // Salida: Pedro (el valor original cambia)\n\nconsole.log(`${'\\n'}${'*'.repeat(50)}${'\\n'}`);\n\n// Función que intercambia valores por valor\nfunction intercambiarValoresPorValor(a: any, b: any): [any, any] {\n  const temp = a;\n  a = b;\n  b = temp;\n  return [a, b];\n}\n\n// Función que intercambia valores por referencia\nfunction intercambiarValoresPorReferencia(obj: { valor1: any; valor2: any }): { valor1: any; valor2: any } {\n  const { valor1, valor2 } = obj;\n  return { valor1: valor2, valor2: valor1 }; // Devolver un nuevo objeto con valores intercambiados\n}\n\n// Ejemplos\nconst valorA: number = 3;\nconst valorB: number = 7;\n\nconst [nuevoValorA, nuevoValorB]: [number, number] = intercambiarValoresPorValor(valorA, valorB);\nconsole.log(valorA, valorB); // Salida: 3 7\nconsole.log(nuevoValorA, nuevoValorB); // Salida: 7 3\n\nconst valores: { valor1: number; valor2: number } = { valor1: 10, valor2: 5 };\n\nconst nuevosValores: { valor1: number; valor2: number } = intercambiarValoresPorReferencia(valores);\nconsole.log(valores.valor1, valores.valor2); // Salida: 10 5\nconsole.log(nuevosValores.valor1, nuevosValores.valor2); // Salida: 5 10\n\n// Visita mi repo en GitHub para ver y correr los tests de este código --> https://github.com/marcode24/weekly-challenges\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/typescript/markc1234.ts",
    "content": "(() => {\n    //  EJERCICIO:\n    //  Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según su tipo de dato.\n    \n    // asignacion de variables por valor (para tipos primiticos - string - number -boolean - null - undefined - symbol)\n    const a = 10;\n\n    // es una copia de a\n    let b:number = a;\n    b = 20;\n    console.log(a); \n    console.log(b); \n\n    // assignacion de varibles por referencia (para tipos object, array, functions)\n    const obj1 = { name: \"Marcos\" };\n\n    // obj2 apunta al mismo objeto que obj1\n    let obj2 = obj1; \n    obj2.name = \"Fabricio\";\n    console.log(obj1.name);\n    console.log(obj2.name);\n\n\n    //  - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n    // se pasa una copia del valor\n    function incrementaPorValor(valor: number): void {\n        valor += valor;\n        console.log(`Dentro de la función: ${valor}`); \n    }\n    \n    let numero = 10;\n    incrementaPorValor(numero);\n    console.log(`Fuera de la función: ${numero}`);\n\n    // se pasa una referencia al objeto en memoria\n    function incrementaPorReferencia(obj: { valor: number }): void {\n        obj.valor++;\n        console.log(`Dentro de la función: ${obj.valor}`);\n    }\n    \n    let obj3 = { valor: 10 };\n    incrementaPorReferencia(obj3);\n    console.log(`Fuera de la función: ${obj3.valor}`);\n\n    //  (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n\n\n    //  DIFICULTAD EXTRA (opcional):\n    //  Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n    //  - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n    \n    // Programa que recibe dos parámetros por valor\n    function program1(param1:number, param2:number):[number, number] {\n        let temp:number = param1\n        param1 = param2\n        param2 = temp\n        return [param1, param2]\n    }\n\n    \n    // Programa que recibe dos parámetros por referencia \n    function program2(param1: string[], param2: string[]): void { \n        for (let i = 0; i < param1.length; i++) { \n            let temp = param1[i] \n            param1[i] = param2[i]\n            param2[i] = temp\n        } \n    }\n\n    //  Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n    //  Comprueba también que se ha conservado el valor original en las primeras.\n\n    const var1 = 5\n    const var2 = 10\n    const [num1, num2] = program1(var1, var2)\n    console.log(`Valores iniciales var1: ${var1}`)\n    console.log(`Valores iniciales var2: ${var2}`)\n    console.log(`Valores finales var2: ${num1}`)\n    console.log(`Valores finales var2: ${num2}`)\n\n    const var3 = [\"Typescript\", \"Python\", \"Go\"]\n    const var4 = [\"Java\", \"PHP\", \"C++\"]\n    console.log(`Valores iniciales var3: ${var3}`)\n    console.log(`Valores iniciales var4: ${var4}`)\n\n    program2(var3, var4)\n    console.log(`Valores iniciales var4: ${var3}`)\n    console.log(`Valores iniciales var4: ${var4}`)\n    \n})()"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/typescript/miguelex.ts",
    "content": "let myNumber: number = 25;\nlet myString: string = \"Hola Mundo\";\n\nconsole.log(myNumber);\nconsole.log(myString);\n\n// Declaramos dos nuevas variables por valor \n\nlet myNumber2: number = myNumber;\nlet myString2: string = myString;\n\nconsole.log(myNumber2);\nconsole.log(myString2);\n\n// Cambiamos el valor de las variables originales\n\nmyNumber = 50;\nmyString = \"Adios Mundo\";\n\nconsole.log(\"El valor de variable numérica original es: \" + myNumber + \" y el valor de la variable numérica nueva es: \" + myNumber2);\nconsole.log(\"El valor de variable string original es: \" + myString + \" y el valor de la variable string nueva es: \" + myString2);\n\n// Ejemplo por referencia\n\ninterface User {\n    name: string;\n    age: number;\n}\n\nlet obj1: User = {\n    name: \"Miguel\",\n    age: 25\n};\n\nconsole.log(obj1);\n\n// Declaramos un nuevo objeto y le asignamos el valor del objeto original\n\nlet obj2: User = obj1;\n\n// Imprimimos el valor del nuevo objeto\n\nconsole.log(obj2);\n\n// Cambiamos el valor de una propiedad del objeto original\n\nobj1.name = \"Miguelex\";\n\nconsole.log(\"El valor de la propiedad name del objeto original es: \" + obj1.name + \" y el valor de la propiedad name del objeto nuevo es: \" + obj2.name);\n\n// Ejemplo de funcion con paso por valor\n\nfunction changeValue(a): void {\n    a = 50;\n}\n\nlet num = 25;\nchangeValue(num);\nconsole.log(num);\n\n// Ejemplo de funcion con paso por referencia\n\nfunction changeValueObj(obj): void {\n    obj.name = \"Miguelex\";\n}\n\nlet obj = {\n    name: \"Miguel\",\n    age: 25\n};\n\nchangeValueObj(obj);\nconsole.log(obj.name);\n\n// Extra\n\nfunction byValor(a, b): number[] {\n    let aux: number = a;\n    a = b;\n    b = aux;\n    return [a, b];  \n}\n\nfunction byReference(obj1, obj2): User[] {\n    let aux: User = obj1;\n    obj1 = obj2;\n    obj2 = aux;\n    return [obj1, obj2];\n}\n\nlet a: number  = 5;\nlet b: number = 10;\n\nlet user1: User = {\n    name: \"Miguel\",\n    age: 25\n};\n\nlet user2: User = {\n    name: \"Juan\",\n    age: 30\n};\n\nconsole.log(\"Antes de llamar a la función --> El valor de a es: \" + a + \" y el valor de b es: \" + b);\n\n[a, b] = byValor(a, b);\n\nconsole.log(\"Después de llamar a la función --> El valor de a es: \" + a + \" y el valor de b es: \" + b);\n\nconsole.log(\"Antes de llamar a la función --> El valor de user1 es: \" + JSON.stringify(user1) + \" y el valor de user2 es: \" + JSON.stringify(user2));\n\nlet [newUser1, newUser2]: User[] = byReference(user1, user2);\n\nconsole.log(\"Despues de llamar a la función --> El valor de user1 es: \" + JSON.stringify(newUser1) + \" y el valor de user2 es: \" + JSON.stringify(newUser2));"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/typescript/mikelroset.ts",
    "content": "/* -------------------------- ASIGNACIÓN POR VALOR -------------------------- */\n/* \n * Esto aplica a todos los tipos de datos primitivos (números, cadenas, \n * booleanos, null, undefined, symbol y bigInt)\n */\nlet number1: number = 5;\nlet number2: number = number1;  // Se copia el valor de 'number1' en 'number2'\n\nconsole.log(number1); // 5\nconsole.log(number2); // 5\n\n// Ahora cambiamos el valor de 'number1'\nnumber1 = 10;\n\nconsole.log(number1); // 10\nconsole.log(number2); // 5\n\n\n/* ----------------------- ASIGNACIÓN POR REFERENCIA ------------------------ */\n/* \n * Esto aplica a los tipos de datos: objetos, arrays, funciones, clases, \n * instancias de clases, etc.\n */\nlet object1 = { nombre: 'Juan' };\nlet object2 = object1;  // Se asigna la referencia de 'object1' a 'object2'\n\nconsole.log(object1); // { nombre: 'Juan' }\nconsole.log(object2); // { nombre: 'Juan' }\n\n// Ahora cambiamos el valor de 'nombre' en 'object1'\nobject1.nombre = 'Pedro';\n\nconsole.log(object1); // { nombre: 'Pedro' }\nconsole.log(object2); // { nombre: 'Pedro' }\n\n\n/* ------------------------- COPIAR OBJETOS Y ARRAYS ------------------------ */\n// Spread para copiar objetos\nlet originalObject = { nombre: 'Ana' };\nlet copiedObject = { ...originalObject };\ncopiedObject.nombre = 'Maria';\n\nconsole.log(originalObject); // { nombre: 'Ana' }\nconsole.log(copiedObject); // { nombre: 'Maria' }\n\n// Object.assign() para copiar objetos\nlet originalObject2 = { nombre: 'Carlos' };\nlet copiedObject2 = Object.assign({}, originalObject2);\ncopiedObject2.nombre = 'Roberto';\n\nconsole.log(originalObject2); // { nombre: 'Carlos' }\nconsole.log(copiedObject2); // { nombre: 'Roberto' }\n\n\n// Array.slice() o Array.from() para copiar arrays\nlet originalArray = [1, 2, 3];\nlet copiedArray = originalArray.slice();\ncopiedArray.push(4);\n\nconsole.log(originalArray); // [1, 2, 3]\nconsole.log(copiedArray); // [1, 2, 3, 4]\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como \n * variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, \n *   por referencia. Estos parámetros los intercambia entre ellos en su \n *   interior, los retorna, y su retorno se asigna a dos variables diferentes a \n *   las originales. A continuación, imprime el valor de las variables \n *   originales y las nuevas, comprobando que se ha invertido su valor en las \n *   segundas. Comprueba también que se ha conservado el valor original en las \n *   primeras.\n */\n\n// Por valor\nconst number2_1: number = 5;\nconst number2_2: number = 10;\n\nfunction swapPorReferencia(param1: number, param2: number): [number, number] {\n  let temp = param1;\n  param1 = param2;\n  param2 = temp;\n  return [param1, param2];\n}\n\nlet [newNumber1, newNumber2]: [number, number] = swapPorReferencia(\n  number2_1, \n  number2_2\n);\nconsole.log(\"Valor inicial 1\", number2_1); // 5\nconsole.log(\"Valor inicial 2\", number2_2); // 10\nconsole.log(\"Valor final 1\", newNumber1); // 10\nconsole.log(\"Valor final 2\", newNumber2); // 5\n\n\n// Por referencia\ntype Persona = { nombre: string };\nlet object2_1: Persona = { nombre: \"Juan\" };\nlet object2_2: Persona = { nombre: \"Pedro\" };\n\n// Antes de llamar a la función pintamos los valores iniciales\nconsole.log(\"Valor inicial objeto 1\", object2_1); // { nombre: \"Pedro\" }\nconsole.log(\"Valor inicial objeto 2\", object2_2); // { nombre: \"Juan\" }\n\nfunction swapPorReferencia2(a: Persona, b: Persona): void {\n  let tempNombre = a.nombre;\n  a.nombre = b.nombre;\n  b.nombre = tempNombre;\n}\n\nswapPorReferencia2(object2_1, object2_2);\n\n// Después de llamar a la función pintamos los valores finales\nconsole.log(\"Valor final objecto 1\", object2_1); // { nombre: \"Pedro\" }\nconsole.log(\"Valor final objeto 2\", object2_2); // { nombre: \"Juan\" }\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/typescript/mxtrar23.ts",
    "content": "//- Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según su tipo de dato.\n\n//por valor\nconst texto1 = 'TypeScript'\nconst texto2 = texto1\n\nconsole.log(texto1);\nconsole.log(texto2);\n\n// por referencia\nconst array1 = [1,2,3]\nlet array2 = array1\n\narray2.push(4)\n\nconsole.log(array1);\nconsole.log(array2);\n\n\n// - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y  \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n\n\n//por valor\nconst function1 = (param:number) :void => {\n  param = 2\n  console.log(param);\n}\n\nconst num = 1\nfunction1(num)\nconsole.log(num);\n\n\n// por referencia\nconst function2 = (param:number[]) :void => {\n  param.push(4)\n  let array2 = param\n  array2.push(5)\n\n  console.log(param);\n  console.log(array2);\n}\n\nconst arr = [1,2,3]\nfunction2(arr)\nconsole.log(arr);\n\n\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/typescript/nlarrea.ts",
    "content": "/*\n * EJERCICIO:\n * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n *   su tipo de dato.\n * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y \n *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\n\n// Asignación por valor\n\nlet numberA: number = 11;\nlet numberB: number = numberA;\nconsole.log('numberA:', numberA);  // numberA: 11\nconsole.log('numberB:', numberB);  // numberB: 11\nnumberB = 7;\nconsole.log('numberA:', numberA);  // numberA: 11\nconsole.log('numberB:', numberB);  // numberB: 7\n\n// Asignación por referencia\n\nlet arrayA: number[] = [1, 2, 3, 4];\nlet arrayB: number[] = arrayA;\nconsole.log('arrayA:', arrayA);  // [1, 2, 3, 4]\nconsole.log('arrayB:', arrayB);  // [1, 2, 3, 4]\narrayB.push(5);\nconsole.log('arrayA:', arrayA);  // [1, 2, 3, 4, 5]\nconsole.log('arrayB:', arrayB);  // [1, 2, 3, 4, 5]\n\n// Funciones por valor\n\nfunction printDouble(number: number): void {\n    number *= 2;\n    console.log(number);\n}\n\nlet myNumber: number = 2;\nprintDouble(myNumber);  // 4\nconsole.log(myNumber);  // 2\n\n// Funciones por referencia\n\nfunction printAppendNumber(arr: number[], num: number): void {\n    arr.push(num);\n    console.log(arr);\n}\n\nlet myArr: number[] = [1, 2, 3, 4]\nprintAppendNumber(myArr, 5);  // [1, 2, 3, 4, 5]\nconsole.log(myArr);  // [1, 2, 3, 4, 5]\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n *   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n *   Comprueba también que se ha conservado el valor original en las primeras.\n */\n\n\nfunction exchangeByValue(valOne: number, valTwo: number): number[] {\n    [valOne, valTwo] = [valTwo, valOne]\n    return [valOne, valTwo];\n}\n\nlet firstValue: number = 11\nlet secondValue: number = 7\nlet [val1, val2] = exchangeByValue(firstValue, secondValue);\nconsole.log(`1.1 Before function: ${firstValue}, After function: ${val1}`);\n// 1.1 Before function: 11, After function: 7\nconsole.log(`1.2 Before function: ${secondValue}, After function: ${val2}`);\n// 1.2 Before function: 7, After function: 11\n\n\nfunction exchangeByReference(arrOne: number[], arrTwo: number[]): number[][] {\n    [arrOne, arrTwo] = [[...arrTwo], [...arrOne]];\n    return [arrOne, arrTwo]\n}\n\nlet firstArray: number[] = [1, 2, 3, 4]\nlet secondArray: number[] = [9, 8, 7, 6]\nlet [arr1, arr2] = exchangeByReference(firstArray, secondArray);\nconsole.log(`2.1 Before function: ${firstArray}, After function: ${arr1}`);\n// 2.1 Before function: 1,2,3,4, After function: 9,8,7,6\nconsole.log(`2.2 Before function: ${secondArray}, After function: ${arr2}`);\n// 2.2 Before function: 9,8,7,6, After function: 1,2,3,4"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/typescript/qv1ko.ts",
    "content": "let a: number = 3;\nlet b: number = 4;\nconst xy = {x: 5, y: 6};\n\nfunction program1(a: number, b: number): number[] {\n\n    var tmp = a;\n\n    a = b;\n    b = tmp;\n\n    return [a, b];\n\n}\n\nfunction program2(ref: { x: number, y: number }): number[] {\n\n    var tmp = ref.x;\n\n    ref.x = ref.y;\n    ref.y = tmp;\n\n    return [ref.x, ref.y];\n\n}\n\nlet newAB = program1(a, b);\nlet newXY = program2(xy);\n\nconsole.log(\"A value: \" + a);\nconsole.log(\"New A value: \" + newAB[0]);\nconsole.log(\"B value: \" + b);\nconsole.log(\"New B value: \" + newAB[1]);\nconsole.log(\"X value: \" + xy.x);\nconsole.log(\"New X value: \" + newXY[0]);\nconsole.log(\"Y value: \" + xy.y);\nconsole.log(\"New Y value: \" + newXY[1]);\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/typescript/qwik-zgheib.ts",
    "content": "/* -- exercise */\n// -- by value\nlet a: number = 5;\nlet b: number = a;\n\nb = 10;\nconsole.log(a);\nconsole.log(b);\n\n// by reference\ninterface Person {\n  name: string;\n}\n\nlet obj1: Person = { name: \"Alice\" };\nlet obj2: Person = obj1;\n\nobj2.name = \"Bob\";\nconsole.log(obj1.name);\nconsole.log(obj2.name);\n\n// Passing Variables to Functions\n// by value\nfunction changeValue(x: number): void {\n  x = 10;\n}\n\nlet valueA: number = 5;\nchangeValue(valueA);\nconsole.log(valueA);\n\n// by reference\nfunction changeObject(obj: Person): void {\n  obj.name = \"Charlie\";\n}\n\nlet object1: Person = { name: \"Alice\" };\nchangeObject(object1);\nconsole.log(object1.name);\n\n/* -- extra challenge */\nfunction swapByValue(x: number, y: number): [number, number] {\n  let temp: number = x;\n  x = y;\n  y = temp;\n  return [x, y];\n}\n\nlet value1: number = 10;\nlet value2: number = 20;\n\nlet [new1, new2] = swapByValue(value1, value2);\n\nconsole.log(\"Original values: value1 =\", value1, \", valueB =\", value2);\nconsole.log(\"Swapped values: newA =\", new1, \", newB =\", new2);\n\ninterface ValueContainer {\n  value: string;\n}\n\nfunction swapByReference(obj1: ValueContainer, obj2: ValueContainer): [ValueContainer, ValueContainer] {\n  let temp: string = obj1.value;\n  obj1.value = obj2.value;\n  obj2.value = temp;\n  return [obj1, obj2];\n}\n\nlet objectA: ValueContainer = { value: \"Hello\" };\nlet objectB: ValueContainer = { value: \"World\" };\n\nlet [newObjectA, newObjectB] = swapByReference(objectA, objectB);\n\nconsole.log(\"Original values: objectA.value =\", objectA.value, \", objectB.value =\", objectB.value);\nconsole.log(\"Swapped values: newObjectA.value =\", newObjectA.value, \", newObjectB.value =\", newObjectB.value);\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/typescript/victor-Casta.ts",
    "content": "(() => {\n  /*\n    * EJERCICIO:\n    * - Muestra ejemplos de asignación de variables \"por valor\" y \"por referencia\", según\n    *   su tipo de dato.\n    * - Muestra ejemplos de funciones con variables que se les pasan \"por valor\" y\n    *   \"por referencia\", y cómo se comportan en cada caso en el momento de ser modificadas.\n    * (Entender estos conceptos es algo esencial en la gran mayoría de lenguajes)\n  */\n\n  let numberA: number = 7\n  let numberByA: number = numberA\n  console.log(`Valor de numberByA (por valor): ${numberByA}`)\n\n  const userslist: Array<string> = [\"Victor\", \"victorCasta\"]\n  const userslistB: Array<string> = userslist\n  console.log(`Valor de userslistB (por referencia): ${userslistB}`)\n\n  const assignedValue = (a: number): void => {\n    let b: number = a\n    console.log(`Valor inicial de variable a: ${a}`)\n    console.log(`Valor inicial de variable b (copia de a): ${b}`)\n    b = 7\n    console.log(`Valor de a después de cambiar el valor de b: ${a}`)\n    console.log(`Valor de b después de cambiar el valor de b: ${b}`)\n  }\n\n  assignedValue(9)\n\n  const assignedReference = (a: Array<number>): void => {\n    let b: Array<number> = a\n    console.log(`Valor inicial de variable a: ${a}`)\n    console.log(`Valor inicial de variable b (referencia de a): ${b}`)\n    b.push(3)\n    console.log(`Valor de a después de modificar b: ${a}`)\n    console.log(`Valor de b después de modificar b: ${b}`)\n  }\n\n  assignedReference([1, 2])\n\n  /*\n  * DIFICULTAD EXTRA (opcional):\n  * Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n  * - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n  * - Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n  *   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n  *   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n  *   Comprueba también que se ha conservado el valor original en las primeras.\n  */\n\n  let variable1: number = 1\n  let variable2: number = 2\n  let variable3: Array<number> = [1, 2]\n  let variable4: Array<number> = [3, 4]\n\n\n  const program1 = (param1: number, param2: number): Array<number> => {\n    const temp = param1\n    param1 = param2\n    param2 = temp\n    return [param1, param2]\n  }\n\n  const program2 = (param1: Array<number>, param2: Array<number>): Array<Array<number>> => {\n    const temp = [...param1]\n    param1.length = 0\n    param1.push(...param2)\n    param2.length = 0\n    param2.push(...temp)\n    return [param1, param2]\n  }\n\n  const results1: Array<number> = program1(variable1, variable2)\n  const results2: Array<Array<number>> = program2([...variable3], [...variable4])\n\n  const resultVariable1: number = results1[0]\n  const resultVariable2: number = results1[1]\n  const resultVariable3: Array<number> = results2[0]\n  const resultVariable4: Array<number> = results2[1]\n\n\n  console.log(\"Variables por valor originales\")\n  console.log(variable1)\n  console.log(variable2)\n\n  console.log(\"Variables por valor nuevas\")\n  console.log(resultVariable1)\n  console.log(resultVariable2)\n\n  console.log(\"Variables por referencia originales\")\n  console.log(variable3)\n  console.log(variable4)\n\n  console.log(\"Variables por referencia nuevas\")\n  console.log(resultVariable3)\n  console.log(resultVariable4)\n\n})()\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/typescript/victoriaparraf.ts",
    "content": "//Asignacion por valor\nlet a: number = 5;\nlet b: number = a; // Asignación por valor\nconsole.log(a); // 5\nconsole.log(b); // 5\nb = 10;\nconsole.log(a); // 5 (no cambia)\nconsole.log(b); // 10\n\nlet str1: string = \"Hola\";\nlet str2: string = str1; // Asignación por valor\nconsole.log(str1); // \"Hola\"\nconsole.log(str2); // \"Hola\"\nstr2 = \"Adiós\";\nconsole.log(str1); // \"Hola\" (no cambia)\nconsole.log(str2); // \"Adiós\"\n\n//Asignacion por referencia\nlet obj1 = { nombre: \"Alice\" };\nlet obj2 = obj1; // Asignación por referencia\nconsole.log(obj1); // { nombre: \"Alice\" }\nconsole.log(obj2); // { nombre: \"Alice\" }\nobj2.nombre = \"Bob\";\nconsole.log(obj1); // { nombre: \"Bob\" } (cambia también)\nconsole.log(obj2); // { nombre: \"Bob\" }\n\nlet arr1: number[] = [1, 2, 3];\nlet arr2: number[] = arr1; // Asignación por referencia\nconsole.log(arr1); // [1, 2, 3]\nconsole.log(arr2); // [1, 2, 3]\narr2.push(4);\nconsole.log(arr1); // [1, 2, 3, 4] (cambia también)\nconsole.log(arr2); // [1, 2, 3, 4]\n\n//Paso de parametros por valor\nfunction incrementarPorValor(x: number): void {\n    x += 1;\n    console.log(`Dentro de la función: x = ${x}`);\n}\nlet aa: number = 10;\nconsole.log(`Antes de la función: a = ${aa}`); // 10\nincrementarPorValor(aa); // Dentro de la función: x = 11\nconsole.log(`Después de la función: a = ${aa}`); // 10\n\nfunction cambiarCadena(cadena: string): void {\n    cadena = \"Nueva cadena\";\n    console.log(`Dentro de la función: cadena = ${cadena}`);\n}\nlet saludo: string = \"Hola\";\nconsole.log(`Antes de la función: saludo = ${saludo}`); // \"Hola\"\ncambiarCadena(saludo); // Dentro de la función: cadena = \"Nueva cadena\"\nconsole.log(`Después de la función: saludo = ${saludo}`); // \"Hola\"\n\n//Paso de parametros por referencia\nfunction cambiarObjeto(obj: { valor: number }): void {\n    obj.valor += 10;\n    console.log(`Dentro de la función: obj.valor = ${obj.valor}`);\n}\nlet miObjeto = { valor: 20 };\nconsole.log(`Antes de la función: miObjeto.valor = ${miObjeto.valor}`); // 20\ncambiarObjeto(miObjeto); // Dentro de la función: obj.valor = 30\nconsole.log(`Después de la función: miObjeto.valor = ${miObjeto.valor}`); // 30\n\nfunction agregarElemento(arr: number[]): void {\n    arr.push(4);\n    console.log(`Dentro de la función: arr = ${arr}`);\n}\nlet miArray: number[] = [1, 2, 3];\nconsole.log(`Antes de la función: miArray = ${miArray}`); // [1, 2, 3]\nagregarElemento(miArray); // Dentro de la función: arr = [1, 2, 3, 4]\nconsole.log(`Después de la función: miArray = ${miArray}`); // [1, 2, 3, 4]\n\n\n"
  },
  {
    "path": "Roadmap/05 - VALOR Y REFERENCIA/vb.net/kenysdev.vb",
    "content": "' ╔══════════════════════════════════════╗\n' ║ Autor:  Kenys Alvarado               ║\n' ║ GitHub: https://github.com/Kenysdev  ║\n' ║ 2024 -  VB.NET                       ║\n' ╚══════════════════════════════════════╝\n\n' # VALOR Y REFERENCIA\n' --------------------\nModule Program\n    Sub Main(args As String())\n        ' Asignación de variables \"por valor\"\n        ' - se asigna el valor real de la variable a otra variable.\n        ' - los cambios en una variable no afectarán a la otra.\n\n        Console.WriteLine(\"Por valor\")\n        Dim int1 As Integer = 111\n        Dim bool1 As Boolean = False\n        Dim str1 As String = \"Ben\"\n\n        ' Asignación\n        Dim int2 As Integer = int1\n        Dim bool2 As Boolean = bool1\n        Dim str2 As String = str1\n\n        ' Cambio\n        int1 = 777\n        bool1 = True\n        str1 = \"zoe\"\n\n        ' Las variables no fueron afectadas.\n        Console.WriteLine($\"{int2} - {bool2} - {str2}\")\n\n        ' Ejemplo con una función:\n        Sub_value(int1, bool1, str1)\n\n        ' No afectadas por los cambios en la función.\n        Console.WriteLine($\"{int2} - {bool2} - {str2}\")\n\n        '___________________________________________________________________\n        ' Asignación de variables \"por referencia\"\n        ' - se asigna la referencia o dirección de memoria\n        ' - de la variable a otra variable.\n        ' - Los cambios en una variable pueden afectar a la otra.\n\n        Console.WriteLine(\"Por referencia\")\n        Dim list1 As New List(Of String) From {\"Bob\", \"Zoe\", \"Dan\"}\n        Dim dic1 As New Dictionary(Of String, String) From {{\"name\", \"Dan\"}}\n\n        ' Asignación\n        Dim list2 As List(Of String) = list1\n        Dim dic2 As Dictionary(Of String, String) = dic1\n\n        ' Cambio\n        list1(0) = \"Tom\"\n        dic1(\"name\") = \"Zoe\"\n\n        ' Las variables fueron afectadas por el cambio.\n        Dim rList As String = String.Join(\", \", list2)\n        Console.WriteLine($\"{rList}) - {dic2(\"name\")}\")\n\n        ' Ejemplo en una función\n        Sub_reference(list2, dic2)\n\n        ' Fueron afectadas por los cambios en la función.\n        Dim rList2 As String = String.Join(\", \", list2)\n        Console.WriteLine($\"{rList2}) - {dic2(\"name\")}\")\n\n        '___________________________________________________________________\n        ' Ejercicio:\n        ' Crea dos programas que reciban dos parámetros (cada uno) definidos como variables anteriormente.\n        ' - Cada programa recibe, en un caso, dos parámetros por valor, y en otro caso, por referencia.\n        '   Estos parámetros los intercambia entre ellos en su interior, los retorna, y su retorno\n        '   se asigna a dos variables diferentes a las originales. A continuación, imprime el valor de las\n        '   variables originales y las nuevas, comprobando que se ha invertido su valor en las segundas.\n        '   Comprueba también que se ha conservado el valor original en las primeras.\n        Console.WriteLine(\"Ejercicio:\")\n        Dim s1 As String = \"Ben\"\n        Dim s2 As String = \"Zoe\"\n        Dim l1 As New List(Of Object) From {12, 21}\n        Dim l2 As New List(Of Object) From {\"Ben\", \"Zoe\"}\n\n        Dim rL1 As String = String.Join(\", \", l1)\n        Dim rL2 As String = String.Join(\", \", l2)\n        Console.WriteLine($\"Pre-Intercambio:{vbCrLf}{s1} - {s2}{vbCrLf}{rL1} - {rL2}\")\n\n        Dim new_str = ByValue(s1, s2)\n        Dim new_list = ByReference(l1, l2)\n\n        rL1 = String.Join(\", \", l1)\n        rL2 = String.Join(\", \", l2)\n        Console.WriteLine($\"Originales:{vbCrLf}{s1} - {s2}{vbCrLf}{rL1} - {rL2}\")\n\n        rL1 = String.Join(\", \", new_list.Item1)\n        rL2 = String.Join(\", \", new_list.Item2)\n        Console.WriteLine($\"Nuevas:{vbCrLf}{new_str.Item1} - {new_str.Item2}{vbCrLf}{rL1} - {rL2}\")\n    End Sub\n\n    Sub Sub_value(ByVal int3 As Integer, ByVal bool3 As Boolean, ByVal str3 As String)\n        int3 = 333\n        bool3 = False\n        str3 = \"Zoe\"\n    End Sub\n\n    Sub Sub_reference(ByRef list As List(Of String), ByRef dic As Dictionary(Of String, String))\n        list(0) = \"Bob\"\n        dic(\"name\") = \"Dan\"\n    End Sub\n\n    Function ByValue(str1 As String, str2 As String) As (String, String)\n        Dim temp As String = str1\n        str1 = str2\n        str2 = temp\n        Return (str1, str2)\n    End Function\n\n    Function ByReference(list1 As List(Of Object), list2 As List(Of Object)) As (List(Of Object), List(Of Object))\n        Dim temp As List(Of Object) = list1\n        list1 = list2\n        list2 = temp\n        Return (list1, list2)\n    End Function\nEnd Module\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/arduino/santyjl.ino",
    "content": "//06 - RECURSIVIDAD //\n\n/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\nvoid recursividad_100_al_0 (int numero = 100){\n  if(numero < 0){\n    return ;\n  }\n  Serial.print(numero);\n  Serial.print(\" , \");\n  int nuevo_numero = numero -= 1;\n  return recursividad_100_al_0(nuevo_numero);\n\n}\n\n// Extra de dificultad //\nint factorial(int n){\n  if (n == 0 || n == 1){\n    return 1;\n  }\n\n  else{\n    return n * factorial(n - 1);\n  }\n\n}\n\nint fibonacci(int numero , int a = 1 , int b = 0 ){\n  if (numero == 0){\n    return a;\n  }\n\n  return fibonacci(numero -1 , a + b , a );\n}\n\nvoid setup(){\n  Serial.begin(9600);\n\n  Serial.println(\"===================================================== Del 100 al 0 ==========================================================================\");\n  recursividad_100_al_0();\n  \n  Serial.print(\"\\n\");\n    Serial.println(\"=================================================== Factorial de 5 ============================================================================\");\n  Serial.println(factorial(5));\n  \n    Serial.println(\"=================================================== Fibonacci de 20 ============================================================================\");\n  Serial.println(fibonacci(20));\n}\n\n\nvoid loop(){\n\n}\n\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/bash/rantamhack.sh",
    "content": "#!/bin/bash\n\n\n#* EJERCICIO:\n#     * Entiende el concepto de recursividad creando una función recursiva que imprima\n# * números del 100 al 0.\n# *\n# * DIFICULTAD EXTRA (opcional):\n# * Utiliza el concepto de recursividad para:\n# * - Calcular el factorial de un número concreto (la función recibe ese número).\n# * - Calcular el valor de un elemento concreto (según su posición) en la #\n# *   sucesión de Fibonacci (la función recibe la posición).\n\necho -e \"\\n\\n=====================================EJERCICIO=====================================\\n\\n\"\n\nfunction recursive(){\n    if [[ $1 -ge 0 ]]; then\n        echo $1\n        recursive $(( $1 -1 ))\n    fi\n}\nrecursive 100  \n\necho -e \"\\n\\n=====================================DIFICULTAD EXTRA=====================================\\n\\n\"\n\n# Función factorial\n\nfunction factorial(){\n\n    if [[ $1 -eq 1 ]]; then\n        echo 1\n    else \n        value=$(factorial $(( $1 -1 )))\n        result=$(( $1 * value ))\n        echo $result\n    fi\n}\nfactorial 5\necho \"El valor factorial de 5 es:\" $result\n\n# Función factorial aplicada a posicion de elementos  en fibonacci\n\nread -p \"Introduce un numero entero: \" num\necho \"El numero elegido es $num\"\n\nfunction fibonacci(){\n\n    if [[ $1 -lt 2 ]]; then\n        echo 1\n    else\n        value_position=$(( $(fibonacci $(( $1 -1 )))+$(fibonacci $(( $1 -2 ))) ))\n        echo $value_position\n\n    fi\n}\n\n\nfibonacci num\necho \"El valor de la posicion $num en la sucesion de fibonacci es: $value_position\"\n\n\nn=$value_position\n\nfunction factorial_fib(){\n    factor=$(factorial_fib $(( n -1 )))\n    result=$(( factor * n ))\n\n}\nfactorial n\necho \"El valor de la posición $num en la sucesion de fibonacci es: $value_position\"\necho \"El valor del factorial de $n es: $result\"\n\n\n\n "
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/bash/santyjL.sh",
    "content": "#!/bin/bash\n\n: \"\n/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la\n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\"\n\nfunction contador() {\n    local num=$1\n\n    if ((num==0)); then\n        echo \"$num\"\n        return\n    else\n        echo \"$num\"\n        contador $((num - 1))\n    fi\n}\n\ncontador 100\n\nfunction factorial() {\n    local num=$1\n\n    if ((num <= 1)); then\n        echo 1\n        return\n    else\n        echo $((num * $(factorial $((num - 1)))))\n    fi\n}\n\nfactorial 10\n\n\nfunction Fibonacci(){\n    local n=$1\n\n    if ((n <= 0)); then\n        echo 0\n    elif ((n == 1)); then\n        echo 1\n    else\n        echo $(( $(Fibonacci $((n - 1))) + $(Fibonacci $((n - 2))) ))\n    fi\n}\n\nFibonacci 13"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/c/N0HagoNada.c",
    "content": "#include <stdio.h>\n#include <stdlib.h>\n\nvoid NumerosCienaCero(int n);\n\nunsigned long long fibonnaci(int n);\n\nunsigned long long factorial(int n);\n\nvoid main()\n{\n    unsigned long long fibo = fibonnaci(50);\n    printf(\"Calculo fibonnaci para 50: %llu\\n\", fibo);\n    unsigned long long fact = factorial(20);\n    printf(\"\\n Calculo factorial de 20: %llu\\n\", fact);\n    printf(\"********************* Numeros del cien a cero **********************\\n\");\n    NumerosCienaCero(100);\n}\n\nvoid NumerosCienaCero(int n)\n{\n    if (n <= 0)\n    {\n        return;\n    }\n    printf(\"%d\\t\", n);\n    NumerosCienaCero(n - 1);\n}\nunsigned long long factorial(int n)\n{\n    if (n == 1)\n    {\n        return 1;\n    }\n    long long calculo = n * factorial(n - 1);\n    return calculo;\n}\nunsigned long long fibonnaci(int n)\n{\n    if (n <= 1)\n        return n;\n    return fibonnaci(n - 1) + fibonnaci(n - 2);\n}"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/c/jchavescaceres.c",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\n#include <stdio.h>\n#include <string.h>\n\nvoid printCountDown (unsigned int inStart) {\n\n\tprintf (\"%u\\n\", inStart);\n\n\t/* If 0 stop recursive call */\n\tif (inStart != 0) {\n\t\tprintCountDown (inStart-1);\n\t}\n\n};\n\n/*\nfactorial of 5 is 5*4*3*2*1*0, or 5 * factorial(4)\nfactorial of 1 is 1\nfactorial of 0 is 1\n*/\nunsigned long getFactorial (unsigned long inNumber) {\n\n\tunsigned long res = 1;\n\n\tif (inNumber != 1 && inNumber != 0) {\n\t\tres = inNumber * getFactorial (inNumber-1);\n\t};\n\n\treturn res;\n};\n\n/*\nNext numbers is got adding previos to previousPrevious\n0,1,1,2,3,5,8,13,21,etc.\n*/\nunsigned long getFibonacciNumber (unsigned long inPosition) {\n\tunsigned long res = 0; \n\n\tif (inPosition == 0 || inPosition == 1) {\n\t\tres = inPosition;\n\t} else {\n\t\tres =\n\t\t\tgetFibonacciNumber (inPosition-1) +\n\t\t\tgetFibonacciNumber (inPosition-2);\n\t};\n\n\treturn res;\n};\n\nvoid main() {\n\tconst unsigned int C_START = 100;\n\n\tconst unsigned int MAX_BUFFER=200;\n\tchar buffer [MAX_BUFFER];\n\n\n\tunsigned long factorial = 0;\n\tunsigned long posFibonacci = 0;\n\n\t/* Print count down starting from C_START */\n\tprintCountDown (C_START);\n\n\tprintf (\"Calcular factorial de: \");\n\tfgets (buffer, MAX_BUFFER, stdin);\n\tbuffer [strlen (buffer)-1] = '\\0'; /* remove \\n */\n        if (strspn (buffer, \"0123456789\") != strlen (buffer)) {\n\t\tprintf (\"Número tiene que ser mayor o igual que 0\\n\");\n\t}\n\telse {\n        \tsscanf (buffer, \"%lu\\n\", &factorial);\n\t\tprintf (\"El factorial de %lu es %lu\\n\", factorial, getFactorial (factorial));\n\t}\n\n\tprintf (\"Obtener el número de la sucesión de Fibonacci en la posición: \");\n\tfgets (buffer, MAX_BUFFER, stdin);\n\tbuffer [strlen (buffer)-1] = '\\0'; /* remove \\n */\n        if (strspn (buffer, \"0123456789\") != strlen (buffer)) {\n\t\tprintf (\"Número tiene que ser mayor o igual que 0\\n\");\n\t}\n\telse {\n        \tsscanf (buffer, \"%lu\\n\", &posFibonacci);\n\t\tprintf (\"El número de la posición Fibonacci en la posición %lu es %lu\\n\", posFibonacci, getFibonacciNumber (posFibonacci));\n\t}\n\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/c/jhonatanmustiolacas.c",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la\n *   sucesión de Fibonacci (la función recibe la posición).\n */\n// Cabecera\n#include <stdio.h>\n\n// Funciones de cabecera\nvoid                imprimir_del_cien_al_cero_recursivo(int numero);\nlong long int       calculo_feactorial_recursivo(int numero);\nlong long int       fibonacci_en_recursivo(int posicion);\n\n// Definiciones\n#define MINIMO 0\n#define MAXIMO 100\n#define FACTORIAL numero * calculo_feactorial_recursivo(numero - 1)\n#define FIBONACCI fibonacci_en_recursivo(posicion - 2) + fibonacci_en_recursivo(posicion - 1)\n\n\n// Main\nint main(void)\n{\n    imprimir_del_cien_al_cero_recursivo(MAXIMO);\n\n    int numero = 5;\n    printf(\"El factorial de %d es %d\\n\", numero, calculo_feactorial_recursivo(numero));\n\n    printf(\"El fibonacci en la posición %d es %d\\n\", numero, fibonacci_en_recursivo(numero));\n}\n\n// Funciones\nvoid imprimir_del_cien_al_cero_recursivo(int numero)\n{\n    if (numero < MINIMO)\n    {\n        return ;\n    }\n    printf(\"%d\\n\", numero);\n    imprimir_del_cien_al_cero_recursivo(numero - 1);\n}\n\nlong long int calculo_feactorial_recursivo(int numero)\n{\n    if (numero == MINIMO)\n    {\n        return 1;\n    }\n    return FACTORIAL;\n}\n\nlong long int fibonacci_en_recursivo(int posicion)\n{\n    if (posicion == 1)\n    {\n        return 1;\n    }\n    else if (posicion == 0)\n    {\n        return 0;\n    }\n    else\n    {\n        return FIBONACCI;\n    }\n}"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/c/srvariable.c",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la\n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\n#include <stdio.h>\n\nvoid             imprimir_del_100_al_0(int num);\nunsigned int     factorial(unsigned int num);\nunsigned int     fibonacci(unsigned int pos);\nvoid             imprimir_string(char *str, int index);\nvoid             imprimir_string_al_reves(char *str, int index);\n\n// Variables globales que servirán para la dificultad extra\nunsigned int    num1 = 0;\nunsigned int    num2 = 1;\n\nint main(void)\n{\n    printf(\"Imprimir del 100 al 0 con recursividad\\n\");\n    \n    /* === 1 === */\n    imprimir_del_100_al_0(100);\n    printf(\"\\n\\n\\n\");\n\n    /* === DIFICULTAD EXTRA === */\n    // Calcular el factorial\n    unsigned int num;\n    printf(\"Factorial de un número\\n\");\n    printf(\"Introduce un número: \");\n    scanf(\"%u\", &num);\n    printf(\"%u! %u\\n\\n\\n\", num, factorial(num));\n\n    // Encontrar un elemento en la sucesión de Fibonacci\n    unsigned int pos;\n    printf(\"La sucesión de Fibonacci es 0, 1, 1, 2, 3, 5, 8, 13, 21...\\n\");\n    printf(\"Introduce una posición: \");\n    scanf(\"%u\", &pos);\n    printf(\"La posición %u de la sucesión de Fibonacci es: %u\\n\\n\\n\", pos, fibonacci(pos));\n\n    // EXTRA\n    char str[] = \"Hola\";\n    // Imprimir el string con recursividad\n    printf(\"Imprimir el string \\\"%s\\\" del derecho: \", str);\n    imprimir_string(str, 0);\n    printf(\"\\n\");\n    printf(\"Imprimir el string \\\"%s\\\" del revés: \", str);\n    imprimir_string_al_reves(str, 0);\n    printf(\"\\n\");\n\n    return (0);\n}\n\nvoid imprimir_del_100_al_0(int num)\n{\n    // Caso base: Si el número es menor que 0 se sale de la función\n    if (num < 0)\n        return ;\n\n    // Caso recursivo: Imprime el número y se llama a sí misma con un\n    // número menos que el original, hasta que llegue al caso base\n    printf(\"%d \", num);\n    imprimir_del_100_al_0(num - 1);\n}\n\nunsigned int factorial(unsigned int num)\n{\n    // Caso base: Si el número es menor que 2 devuelve 1\n    // Esto se debe a que 0! y 1! es igual a 1\n    if (num < 2)\n        return (1);\n\n    // Caso recursivo: Devuelve el número por el factorial del número\n    // menos uno.\n    // Es decir, si el número es 5 tendremos:\n    // 5 * factorial(4)\n    // 4 * factorial(3)\n    // 3 * factorial(2)\n    // 2 * factorial(1)\n    // Y luego volvería a la función original:\n    // 2 * 1 = 2\n    // 3 * 2 = 6\n    // 4 * 6 = 24\n    // 5 * 24 = 120\n    // Por lo que el resultado sería 120\n    return (num * factorial(num - 1));\n}\n\nunsigned int fibonacci(unsigned int pos)\n{\n    unsigned int        temp;\n                            \n    // Caso base: Si la posición es 1, devuelve el num1 (0)\n    // Si la posición es 2, devuelve num2, que tendrá o 1 (valor original) \n    // o el valor en la posición indicada\n    if (pos == 1)\n        return (num1);\n    else if (pos == 2)\n        return (num2);\n\n    // Caso recursivo: Obtengo el siguiente valor en la sucesión y\n    // llamo a la función con la posición - 1, hasta que llegue al caso\n    // base\n    temp = num1 + num2;\n    num1 = num2;\n    num2 = temp;\n    return (fibonacci(pos - 1));\n}\n\nvoid imprimir_string(char *str, int index)\n{\n    // Caso base: Si el carácter es nulo, se sale\n    if (str[index] == '\\0')\n        return ;\n    // Imprimo el carácter y luego llamo a la función con index + 1\n    printf(\"%c\", str[index]);\n    imprimir_string(str, index + 1);\n}\n\nvoid imprimir_string_al_reves(char *str, int index)\n{\n    // Caso base: Si el carácter es nulo, se sale\n    if (str[index] == '\\0')\n        return ;\n    // Llamo a la función con index + 1 y luego imprimo el carácter\n    imprimir_string_al_reves(str, index + 1);\n    printf(\"%c\", str[index]);\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/c#/Andreavzqz.cs",
    "content": "system user;\n\nPublic class{\n    static void Main (string[] args)\n    {\n        //Llamada inicial a la funcion recursiva para imprimir números del 100 al 0\n        console.WriteLine(\"Imprimiendo números del 100 al 0:\");\n        ImprimirNumeros(100);\n\n        //Calcular y mostrar el factorial de un número\n        int numeroFactorial = 5;\n        Console.WriteLine($\"\\nEl factorial de {numeroFactorial} es: {Factorial(numeroFactorial)}\");\n\n        //Calcular y mostrar el elemento de fibonacci en la posicion dada\n        int posicionFibonacci = 10;\n        Console.WriteLine($\"El elemento en la posicion {posicionFibonacci} de la sucesion de Fibonacci es: {Fibonacci(posicionFibonacci)}\");\n    }\n    //Funcion recursiva para imprimir números del 100 al 0\n    static void ImprimirNumeros (int n)\n    {\n        //Caso base: si n es menor que 0, detiene la recursion\n        if (n < 0)\n        {\n            return;\n        }\n\n        //Imprime el número actual\n        Console.WriteLine(n);\n\n        // Llamada recursiva con el siguente número\n        ImprimirNumeros(n - 1);\n    }\n    \n    //Funcion recursiva para calcular el factorial de un número\n    static int Factorial(int n)\n    {\n        //Caso base: el factorial de 0 o 1 es 1\n        if (n <= 1)\n        {\n            return 1;\n        }\n\n        // Llamada recursiva\n        return n * Factorial(n - 1);\n    }\n\n    //Funcion recursiva para calcular el valor de un elemento en la sucesion de Fibonacci\n\n    static int Fibonacci(int n)\n    {\n        // Caso base: el primer y segundo elemento son 0 y 1, respectivamente\n        if (n <= 0)\n        {\n            return 0;\n        }\n        else if (n == 1)\n        {\n            return 1;\n        }\n        //Llamada recursiva\n        return Fibonacci(n - 1) + Fibonacci(n - 2);\n    }\n  /*\n  \n  -Explicación del Código\n  \nImprimir números del 100 al 0:\nLa función ImprimirNumeros(int n) imprime los números desde n hasta 0 utilizando recursión.\n\nCalcular el factorial de un número:\nLa función Factorial(int n) calcula el factorial de n utilizando recursión. El caso base es n <= 1.\n\nCalcular el valor en la sucesión de Fibonacci:\nLa función Fibonacci(int n) calcula el valor en la posición n de la sucesión de Fibonacci utilizando recursión. Los casos base son n <= 0 y n == 1.\n\n-Ejecución del Código\n\nImprimir números del 100 al 0:\nLa función ImprimirNumeros(100) comienza con 100 e imprime cada número hasta llegar a 0.\n\nFactorial:\nLa función Factorial(5) calcula 5 * 4 * 3 * 2 * 1 = 120 y lo imprime.\n\nFibonacci:\nLa función Fibonacci(10) calcula el 10º elemento de la sucesión de Fibonacci (que es 55) y lo imprime.\n*/\n\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/c#/Arkmiguel379.cs",
    "content": "﻿int Resta(int x)\n{\n    if (x == 0)\n    {\n        return x;\n    }\n    else\n    {\n        Console.WriteLine(x);\n\n        return Resta(x - 1);\n    }\n}\n\nConsole.WriteLine(Resta(100));\n\nConsole.WriteLine();\n\n\n// ====== EXTRA ======\n\nConsole.WriteLine(\"=== CALCULO FACTORIAL ===\");\nint Factorial(int x)\n{\n    if (x == 0)\n    {\n        return 1;\n    }\n\n    return x * Factorial(x - 1);\n}\n\nConsole.WriteLine(Factorial(5));\n\nConsole.WriteLine();\n\n\nConsole.WriteLine(\"=== CALCULO SUCESION FIBONACCI === \\n\");\n\nint Fibonacci(int x)\n{\n    if (x <= 0)\n    {\n        Console.WriteLine(\"No se acepta el numero 0 o valores negativos\");\n        return 0;\n    }\n    else if (x == 1)\n    {\n        return 0;\n    }\n    else if (x == 2)\n    {\n        return 1;\n    }\n    else\n    {\n        return Fibonacci(x - 1) + Fibonacci(x - 2);\n    }\n}\n\nConsole.WriteLine(Fibonacci(5));"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/c#/Isj-code.cs",
    "content": "﻿// Funcion recursiva directa, se llama a si misma\nvoid FuncionRecursiva(int i){\n    \n    if (i >= 0)\n    {\n        Console.WriteLine($\"Numero: {i}\");\n        i--;\n        FuncionRecursiva(i);\n    }\n}\n\nFuncionRecursiva(100);\n\n// ## Opcional\n\n// Factorial\nint Factorial(int i)\n{\n    if (i < 0)\n    {\n        Console.WriteLine(\"No son permitidos los numeros negativos\"); \n    }\n    if (i > 1)\n    {\n        return i *= Factorial(i - 1);\n    }\n    return i;\n}\n\nConsole.WriteLine(\"El Factorial de 4: \" + Factorial(4));\n\n// Fibonacci\n\nint Fibonacci(int i)\n{\n    if (i < 0)\n    {\n        return 0;\n    }else if (i == 0)\n    {\n        return 0;\n    }else if (i == 1)\n    {\n        return 1;\n    }\n    else\n    {\n        return (Fibonacci(i - 1) + Fibonacci(i - 2)); \n    }\n}\n\nConsole.WriteLine($\"La posicion Fibonacci de 8: \" + Fibonacci(8));\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/c#/JoseEsmil04.cs",
    "content": "class Program\n{\n    static void Main(string[] args)\n    {\n        // Imprimir Numeros 100 al 0\n        var cien = 100;\n        ImprimirNumeros100Al0(cien);\n\n        // Factorial\n        var numero = 7;\n        Console.WriteLine($\"El Factorial de {numero} es {Factorial(numero)}\");\n\n        // Fibonacci\n        var posicion = 6;\n        Console.WriteLine($\"El Fibonacci en la posicion {posicion} es {Fibonacci(posicion)}\");\n        \n\n    }\n\n\n    static void ImprimirNumeros100Al0(int num)\n    {\n        if(num < 0) return; // Caso base: si num es menor que 0, se acaba la recursion\n\n        Console.WriteLine(num);\n\n\n        ImprimirNumeros(--num); // Llamada Recursiva con --num (num - 1)\n    }\n\n    static int Factorial(int num)\n    {\n        if(num == 0) return 1; // Caso Base\n\n        return num * Factorial(num - 1); // Llamada Recursiva\n    }\n\n    static int Fibonacci(int num)\n    {\n        if(num == 0) return 0; // Casos Base\n        if(num == 1) return 1;\n\n        Console.WriteLine(num);\n\n        return Fibonacci(num - 1) + Fibonacci(num - 2); // Llamada recursiva\n    }\n}"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/c#/RXVLC.cs",
    "content": "﻿using System;\n\nnamespace R06___2024\n{\n    class Program\n    {\n        public static void ContarHastaCero(int num)\n        {\n            if (num >= 0)\n            {\n                Console.WriteLine(num);\n                ContarHastaCero(num - 1);\n            }\n        }\n\n        //Dif adicional:\n        public static int Factorial(int num)\n        {\n            if (num == 0)\n            {\n                return 1;\n            }\n            else\n            {\n                return num * Factorial(num - 1);\n            }\n        }\n\n        //Fibonacci:\n        //Modo pro:\n        public static int Fibonacci(int n)\n        {\n            if (n < 2)\n                return n;\n            else\n                return Fibonacci(n - 1) + Fibonacci(n - 2);\n        }\n\n        //Modo principiante:\n        public static void FibonacciJunior(int n)\n        {\n            int a = 0;\n            int b = 1;\n            int res = 0;\n\n            for (int i = 2; i <= n; i++)\n            {\n                res = a + b;\n                a = b;\n                b = res;\n            }\n            Console.WriteLine(res);\n        }\n\n        static void Main(string[] args)\n        {\n            Console.WriteLine(\"Recursividad del 100 al 0: \");\n            ContarHastaCero(100);\n\n            Console.WriteLine($\"Factorial (numero por parámetro): {Factorial(5)}\");\n            \n\n            Console.Write(\"Fibonacci (numero por parámetro): \");\n            Console.WriteLine(Fibonacci(9));\n\n            Console.Write(\"Fibonacci Junior: \");\n            FibonacciJunior(9);\n            Console.ReadKey();\n\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/c#/abrahamraies.cs",
    "content": "// Author: Abraham Raies https://github.com/abrahamraies\n\n/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\nusing System;\n\nclass Program {\n    static void Main(string[] args){\n        Console.WriteLine(\"=== IMPRIMIR NUMEROS ===\");\n        ImprimirNumeros(100);\n\n        Console.WriteLine(\"\\n=== FACTORIAL ===\");\n        Console.WriteLine(Factorial(5));\n        Console.WriteLine(Factorial(17));\n\n        Console.WriteLine(\"\\n=== FIBONACCI ===\");\n        Console.WriteLine(Fibonacci(5));\n        Console.WriteLine(Fibonacci(24));\n    }\n\n    // Funcion recursiva que imprime numeros del 100 al 0\n    // Si el numero es menor a 0, se detiene la recursividad\n    // Si el numero es mayor o igual a 0, imprime el numero y llama a la funcion con el numero - 1\n    static void ImprimirNumeros(int numero){\n        if(numero < 0){\n            return;\n        }\n        Console.WriteLine(numero);\n        ImprimirNumeros(numero - 1);\n    }\n\n    // Funcion recursiva que calcula el factorial de un numero\n    // Si el numero es 0 o 1, retorna 1\n    // Si el numero es mayor a 1, retorna el numero multiplicado por el factorial del numero - 1\n    static int Factorial(int numero){\n        if(numero == 0 || numero == 1){\n            return 1;\n        }\n        return numero * Factorial(numero - 1);\n    }\n\n    // Funcion recursiva que calcula el valor de un elemento en la sucesion de Fibonacci\n    // Si el numero es 0, retorna 0\n    // Si el numero es 1, retorna 1\n    // Si el numero es mayor a 1, retorna la suma de los dos numeros anteriores en la sucesion\n    static int Fibonacci(int numero){\n        if(numero == 0){\n            return 0;\n        }\n        if(numero == 1){\n            return 1;\n        }\n        return Fibonacci(numero - 1) + Fibonacci(numero - 2);\n    }\n}"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/c#/alinares94.cs",
    "content": "﻿/*\r\n * EJERCICIO:\r\n * Entiende el concepto de recursividad creando una función recursiva que imprima\r\n * números del 100 al 0.\r\n *\r\n * DIFICULTAD EXTRA (opcional):\r\n * Utiliza el concepto de recursividad para:\r\n * - Calcular el factorial de un número concreto (la función recibe ese número).\r\n * - Calcular el valor de un elemento concreto (según su posición) en la \r\n *   sucesión de Fibonacci (la función recibe la posición).\r\n */\r\n\r\nusing System.Numerics;\r\nConsole.WriteLine(\"#####################################\");\r\nConsole.WriteLine(\"######### 01 - Print n to 0 #########\");\r\nConsole.WriteLine(\"#####################################\");\r\nConsole.WriteLine();\r\nConsole.WriteLine(\"Example for n=100\");\r\nPrintNumbers(100);\r\nConsole.WriteLine();\r\nConsole.WriteLine();\r\n\r\nConsole.WriteLine(\"#####################################\");\r\nConsole.WriteLine(\"######### 02 - Factorial n! #########\");\r\nConsole.WriteLine(\"#####################################\");\r\nConsole.WriteLine();\r\nConsole.WriteLine(\"Example for n=5\");\r\nConsole.WriteLine(Factorial(5));\r\nConsole.WriteLine(\"Example for n=50\");\r\nConsole.WriteLine(Factorial(50).ToString(\"E\"));\r\nConsole.WriteLine();\r\n\r\nConsole.WriteLine(\"#####################################\");\r\nConsole.WriteLine(\"#### 03 - Fibonacci starting at 1 ###\");\r\nConsole.WriteLine(\"#####################################\");\r\nConsole.WriteLine();\r\nConsole.WriteLine(\"Example for n=5\");\r\nConsole.WriteLine(Fibonacci(5));\r\nConsole.WriteLine(\"Example for n=15\");\r\nConsole.WriteLine(Fibonacci(15));\r\nConsole.WriteLine();\r\n\r\n// Print n to 0\r\nstatic void PrintNumbers(int n)\r\n{\r\n    if (n < 0)\r\n        return;\r\n    Console.Write($\"{n} \");\r\n    PrintNumbers(n-1);\r\n}\r\n\r\n// Calculate n!\r\nstatic BigInteger Factorial(uint n)\r\n{\r\n    if (n.Equals(0) || n.Equals(1))\r\n        return 1;\r\n\r\n    return BigInteger.Multiply(n, Factorial(n-1));\r\n}\r\n\r\n// Print n-item in fibonacci sequence starting at 1\r\nstatic ulong Fibonacci(uint n)\r\n{\r\n    if (n.Equals(0))\r\n        throw new ArgumentOutOfRangeException(nameof(n), \"Input should be greather than 0\");\r\n    if (n.Equals(1) || n.Equals(2))\r\n        return 1;\r\n\r\n    return Fibonacci(n-1)+Fibonacci(n-2);\r\n}"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/c#/charlerodriguez3.cs",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n *\n **/\n\nimprimirNumerosDel1Al100(100);\n\nstatic void imprimirNumerosDel1Al100(int num)\n{\n    if (num > -1)\n    {\n        Console.WriteLine(num);\n        imprimirNumerosDel1Al100(num - 1);\n    }\n}\n\n\n\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\nConsole.WriteLine(FactorialNumero(5));\n\nstatic int FactorialNumero(int num)\n{\n    if (num == 1) return num *1;\n    else return num * FactorialNumero(num-1);\n}\n\n\nConsole.WriteLine(ElementoFibonacci(11));\n\nstatic int ElementoFibonacci(int pos)\n{\n    if (pos < 0) return 0;\n    else if (pos == 1 || pos == 2) return 1;\n    else return ElementoFibonacci(pos -1) + ElementoFibonacci(pos - 2);\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/c#/devcherry1.cs",
    "content": "using System;\n\nclass Program\n{\n    static void Main()\n    {\n        contador(100);\n        Console.WriteLine(\"Indique la posicion en la serie Fibonacci: \");\n        int serie;\n        int.TryParse(Console.ReadLine(), out serie);\n        Console.WriteLine(Extra.Fibonacci(serie));\n        int factor;\n        int.TryParse(Console.ReadLine(), out factor);\n        Console.WriteLine(Extra.Factorial(factor));\n    }\n    static void contador(int limite)\n    {\n        if (limite == 0)\n        {\n            Console.WriteLine(limite);\n            return;\n        }\n        Console.WriteLine(limite);\n        contador(limite - 1);\n    }\n}\nclass Extra\n{\n    public static int Fibonacci(int posicion)\n    {\n        // Casos base\n        if (posicion == 0) return 0;\n        if (posicion == 1) return 1;\n\n        // Caso recursivo\n        return Fibonacci(posicion - 1) + Fibonacci(posicion - 2);\n    }\n    public static int Factorial(int numero)\n    {\n        if (numero == 0) return 1;\n\n        return numero * Factorial(numero - 1);\n    }\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/c#/estuardodev.cs",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\nusing System;\nnamespace estuardodev\n{\n    internal class Program\n    {\n        public static void Main(string[] args)\n        {\n            countdown(100);\n            Console.WriteLine(\"Factorial: \" + factorial(5));\n            Console.WriteLine(\"Número fibonacci en valor concreto: \" + fibonacci(5));\n        }\n\n        // Ejercicio\n        static void countdown(int contador)\n        {\n            if (contador >= 0) \n            {\n                Console.WriteLine(contador);\n                countdown(contador - 1);\n            }\n        }\n\n        // Extra\n        static int factorial(int numero)\n        {\n            if (numero < 0)\n            {\n                return 0;\n            } else if (numero == 0) \n            {\n                return 1;\n            }\n            \n            return numero * factorial(numero - 1);\n        }\n\n        static int fibonacci(int numero)\n        {\n            if (numero <= 0)\n            {\n                return 0;\n            } else if (numero == 1)\n            {\n                return 0;\n            } else if (numero == 2)\n            {\n                return 1;\n            }\n            else\n            {\n                 return fibonacci(numero - 1) + fibonacci(numero - 2);\n            }\n        }\n\n    }\n}"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/c#/hequebo.cs",
    "content": "class Program\n{\n    static void Main(string[] args)\n    {\n        // Recursividad\n        Console.WriteLine(\"----Recursividad----\");\n        Console.WriteLine(\"---Imprimir del 100 al 1---\");\n        ImprimirNumeros();\n        Console.ReadLine();\n        Console.Clear();\n\n        // Ejercicio Extra\n        Console.WriteLine(\"---Ejercicio extra---\");\n        bool salir = false;\n\n        do\n        {\n            MostrarMenu();\n            string opcion = Console.ReadLine();\n            switch (opcion)\n            {\n                case \"A\":\n                case \"a\":\n                    Console.Clear();\n                    Console.WriteLine(\"---FACTORIAL---\");\n                    Console.WriteLine(\"Ingresa el número a calcular su factorial:\");\n                    int num = int.Parse(Console.ReadLine());\n                    int factorial = CalcularFactorial(num);\n                    Console.WriteLine($\"El factorial de {num} es {factorial}\");\n                    break;\n                case \"B\":\n                case \"b\":\n                    Console.Clear();\n                    Console.WriteLine(\"---FIBONACCI---\");\n                    Console.WriteLine(\"Ingresa la posición a calcular\");\n                    int posicion = int.Parse(Console.ReadLine());\n                    int valor = CalcularFibonacci(posicion);\n                    Console.WriteLine($\"El valor de la posición {posicion} en la serie Fibonacci es {valor}\");\n                    break;\n                case \"C\":\n                case \"c\":\n                    Console.WriteLine(\"Hasta la próxima\");\n                    salir = true;\n                    Thread.Sleep(2000);\n                    break;\n                default:\n                    Console.WriteLine(\"Opción no valida...\");\n                    break;\n            }\n        } while (!salir);\n\n\n    }\n\n    static void ImprimirNumeros(int n = 100)\n    {\n        Console.WriteLine(n);\n        if (n > 1)\n        {\n            n--;\n            ImprimirNumeros(n);\n        } \n    }\n\n    static void MostrarMenu()\n    {\n        Console.WriteLine(\"----MENU----\");\n        Console.WriteLine(\"a.- Calcular Factorial\");\n        Console.WriteLine(\"b.- Calcular valor de posición en serie Fibonacci\");\n        Console.WriteLine(\"c.- Salir\");\n        Console.WriteLine(\"Seleccione una opción\");\n    }\n    static int CalcularFactorial(int num)\n    {\n        if (num == 0 || num == 1)\n            return 1;\n        return num * CalcularFactorial(num - 1);\n    }\n    static int CalcularFibonacci(int posicion)\n    {\n        if (posicion <= 0)\n        {\n            Console.WriteLine(\"La posición debe de ser un número entero positivo...\");\n            return 0;\n        }\n        if (posicion == 1) \n            return 0;\n        if (posicion == 2 || posicion == 3)\n            return 1;\n\n        return CalcularFibonacci(posicion - 1) + CalcularFibonacci(posicion - 2);\n    }\n        \n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/c#/isaacus98.cs",
    "content": "﻿/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\nnamespace RetosProgramacion2024\n{\n    internal class Reto6\n    {\n        static void Main(string[] args)\n        {\n            ImprimirNumero(100);\n            Console.WriteLine(\"\\nFactorial\");\n            Console.WriteLine(Factorial(10));\n            Console.WriteLine(\"\\nFibonacci\");\n            Console.WriteLine(Fibonacci(10));\n        }\n\n        private static void ImprimirNumero(int numero)\n        {\n            Console.WriteLine(numero--);\n            if (numero >= 1)\n                ImprimirNumero(numero);\n        }\n\n        private static int Factorial(int numero)\n        {\n            if (numero == 1)\n                return 1;\n\n            return numero *= Factorial(--numero);\n        }\n\n        private static int Fibonacci(int pos)\n        {\n            if (pos < 2)\n                return pos;\n            else\n                return Fibonacci(pos - 1) + Fibonacci(pos - 2);\n  \n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/c#/jamerrq.cs",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la\n *   sucesión de Fibonacci (la función recibe la posición).\n*/\n\nusing System;\nclass Recursion\n{\n\n    static void PrintNumbers(int n = 100)\n    {\n        if (n >= 0)\n        {\n            Console.Write($\"{n} -> llamo a PrintNumbers({n - 1})\\n\");\n            PrintNumbers(n - 1);\n        }\n        else\n        {\n            Console.WriteLine(\"Fin de la recursión :D\");\n        }\n    }\n\n    static int Factorial(int n)\n    {\n        if (n == 0)\n        {\n            return 1;\n        }\n        else\n        {\n            return n * Factorial(n - 1);\n        }\n    }\n\n    static int Fibonacci(int n)\n    {\n        if (n == 0)\n        {\n            return 0;\n        }\n        else if (n == 1)\n        {\n            return 1;\n        }\n        else\n        {\n            return Fibonacci(n - 1) + Fibonacci(n - 2);\n        }\n    }\n\n    static void Extra()\n    {\n        Console.WriteLine(\"Factorial de 5: \" + Factorial(5));\n        Console.WriteLine(\"Número 11 de la sucesión de Fibonacci: \" + Fibonacci(11));\n    }\n\n    static void Main()\n    {\n        Console.WriteLine(\"========================================\");\n        Console.WriteLine(\"============== RECURSIVIDAD ============\");\n        Console.WriteLine(\"========================================\\n\");\n        PrintNumbers();\n        Console.WriteLine(\"\\n========================================\\n\");\n        Console.WriteLine(\"============ EJERCICIO EXTRA ===========\");\n        Console.WriteLine(\"========================================\\n\");\n        Extra();\n    }\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/c#/jferchotorres.cs",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\nusing System.Numerics;\n\nclass Program \n{\n    static void Main() \n    {\n        Console.WriteLine(\"Printing numbers\");\n        Solution.PrintingNumbers(100);\n        Console.WriteLine(\"\");\n        Console.WriteLine(\"Factorial\");\n        Console.WriteLine(Solution.Factorial(10));\n        Console.WriteLine(\"\");\n        Console.WriteLine(\"Fibonacci\");\n        Console.WriteLine(Solution.Fibonacci(15));\n        Console.Read();\n\n    }\n}\n\n\npublic static class Solution\n{ \n    //Method to print numbers from a given number to 0\n    public static void PrintingNumbers(int num) \n    {\n\n        if (num >= 0)\n        {\n            Console.Write(num+\" \");\n            PrintingNumbers(num - 1);\n        }\n    }\n\n    public static BigInteger Factorial(int num) \n    {\n        if (num == 0 || num == 1) \n        {\n            return 1;\n        }\n        return BigInteger.Multiply(num,Factorial(num-1));\n    }\n\n    //Using unsigned types\n    public static ulong Fibonacci(uint num) \n    {\n        if (num == 1 || num == 2)\n        {\n            return 1;\n        }\n\n        return Fibonacci(num - 1) + Fibonacci(num - 2);\n\n    }\n}"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/c#/kenysdev.cs",
    "content": "/* ╔══════════════════════════════════════╗\n   ║ Autor:  Kenys Alvarado               ║\n   ║ GitHub: https://github.com/Kenysdev  ║\n   ║ 2024 -  C#                           ║\n   ╚══════════════════════════════════════╝\n   ----------------------------------------\n   # Recursividad\n   ----------------------------------------\n - La recursividad es la capacidad de una función para llamarse a sí misma,ya sea \n   de forma directa o indirecta, con el propósito de resolver un problema. \n   _________________________________\n// imprimiendo números del 100 al 0.\n - Ejemplo con recursividad directa\n   ocurre cuando una función se llama a sí misma. */\n\nConsole.WriteLine(\"recursividad directa\");\nvoid Recursive(int n)\n{\n    Console.WriteLine(n);\n    // caso base\n    if (n > 0) // evitar que la función se llame indefinidamente.\n    {\n        Recursive(n - 1);\n    }    \n}\n\nRecursive(100);\n\n// - Ejemplo con recursividad indirecta\n//   implica que varias funciones se llamen entre sí.\n\nConsole.WriteLine(\"recursividad indirecta\");\nvoid Sub(int n)\n{\n    Recursive2(n - 1);\n}\n\nvoid Recursive2(int n)\n{\n    Console.WriteLine(n);\n    // caso base\n    if (n > 0)\n    {\n        Sub(n);\n    }\n}\n\nRecursive2(100);\n\n/* ___________________________________________________________________\n   Ejercicios:\n   -----------\n1. Calcular el factorial de un número concreto (la función recibe ese número).\n   4! = 4 * 3 * 2 * 1 = 24 */\nint Factorial(int n)\n{\n    if (n != 0)\n    {\n        return n * Factorial(n - 1);\n    }\n    else\n    {\n        return 1;\n    }\n    /* Explicación\n    fac(4)\n        | = 24 \n     return 4 * fac(3) ->(4 * 6)\n                  | = 6 \n         return 3 * fac(2) ->(3 * 2)\n                      | = 2 \n             return 2 * fac(1) ->(2 * 1)\n                          | = 1 \n                 return 1 * fac(0) ->(1 * 1)\n                              | = return 1 -> caso base */\n}\n\n/* ___________________________________________________________________\n2. Calcular el valor de un elemento concreto (según su posición) en la \n   sucesión de Fibonacci (la función recibe la posición).\n   n : |0|1|2|3|4|5|6|..\n   fb: |0|1|1|2|3|5|8|..\n        |+|=^   |+|=^ ..  */\n\nint Fibonacci(int n)\n{\n    if (n <= 1)\n    {\n        return n;\n    }\n    else\n    {\n        return Fibonacci(n - 1) + Fibonacci(n - 2);\n    }\n    /* Explicación fib(4) \n                         return 3\n               fib(3)      / \\    fib(2)\n                / \\ =2      +      / \\ =1\n          fib(2) + fib(1)    fib(1) + fib(0) -> caso base\n          / \\ =1\n    fib(1) + fib(0) -> caso base  */\n}\n// NOTE: Este enfoque recursivo puede ser ineficiente para valores grandes de \"n\".\n\n// ___________________________________________________________________\nConsole.WriteLine(@$\"\nFactorial de 4: {Factorial(4)}\nPosición 4 en Fibonacci: {Fibonacci(4)}\");\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/c#/victormugo.cs",
    "content": "﻿using System.Xml.Linq;\n\nnamespace _06_recursividad\n{\n    internal class Program\n    {\n        static void Main(string[] args)\n        {\n            /*\n             * EJERCICIO:\n             * Entiende el concepto de recursividad creando una función recursiva que imprima números del 100 al 0.\n             *\n             * DIFICULTAD EXTRA (opcional):\n             * Utiliza el concepto de recursividad para:\n             * - Calcular el factorial de un número concreto (la función recibe ese número).\n             * - Calcular el valor de un elemento concreto (según su posición) en la \n             *   sucesión de Fibonacci (la función recibe la posición).\n             */\n\n            // Entiende el concepto de recursividad creando una función recursiva que imprima números del 100 al 0.\n            _RecusiveFunction(100);\n\n\n            // ---------------------------------------------------------------------------------\n            // ---------------------------------------------------------------------------------\n\n\n            // Utiliza el concepto de recursividad para:\n            //      Calcular el factorial de un número concreto(la función recibe ese número).\n            int result = 0;\n            int factorial = 12;\n            result = _RecursiveFactorial(factorial);\n            Console.WriteLine($\"Factorial de {factorial} es: {result}\");\n\n            //      Calcular el valor de un elemento concreto(según su posición) en la sucesión de Fibonacci(la función recibe la posición).\n            int position = 10;\n            result = _RecursiveFibonacci(position);\n            Console.WriteLine($\"Posición en la serie de Fibonacci es: {result}\");\n        }\n\n        private static void _RecusiveFunction(int value)\n        {\n            Console.WriteLine(value);\n            if (value == 0) return;\n\n            value--;\n\n            _RecusiveFunction(value);\n        }\n\n        private static int _RecursiveFactorial(int factorial)\n        {\n            if (factorial <= 1) return 1;\n            return factorial * _RecursiveFactorial(factorial-1);\n        }\n\n        private static int _RecursiveFibonacci(int position)\n        {\n            // 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, ...\n\n            if (position == 0)\n            {\n                return 0;\n            }\n            else if (position == 1)\n            {\n                return 1;\n            }\n\n            return _RecursiveFibonacci(position - 1) + _RecursiveFibonacci(position - 2);\n\n        }\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/c#/vixxtory.cs",
    "content": "﻿using System.Runtime.Intrinsics.X86;\nusing System.Security.Cryptography.X509Certificates;\nusing static System.Runtime.InteropServices.JavaScript.JSType;\n\nnamespace RetosProgramacion\n{\n    class Program\n    {\n        static void Main(string[] args)\n        {\n            //La recursividad ocurre cuando una funcion o metodo se llama a si mismo \n            //¿Cómo podemos detectar soluciones que podrían resolverse de forma más fácil con una aproximación recursiva?\n            //Cuando tengamos un problema que tiene varios pasos, y el resultado de ejecutar cada paso nos deja un problema igual al anterior.\n            //int n = 0;\n            //imprimirNumeros(n);\n            //int factor = 3;\n            //Console.WriteLine(factorial(factor));\n            int posicion = 14;\n            Console.WriteLine(fibonacci(posicion));\n        }\n        static void imprimirNumeros(int num)\n        {\n            //Caso base\n            if (num <= 100)\n            {\n                imprimirNumeros(num + 1);\n                Console.WriteLine(num);\n            }\n        }\n        static int factorial(int n)\n        {\n            if (n < 0)\n            {\n                Console.WriteLine(\"No es posible calcular el factorial de un numero negativo\");\n            }\n            //Caso base \n            if (n == 0)\n                return 1;\n            else\n                return n * factorial(n - 1);\n        }\n        static int fibonacci(int p)\n        {\n            if (p == 0)\n                return 0;\n            if (p == 1)\n                return 1;\n            else\n                return fibonacci(p - 1) + fibonacci(p - 2);\n        }\n    }\n}\n\n\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/c++/Fravelz.cpp",
    "content": "#include <iostream>\n\nusing namespace std;\n\nvoid num_mayorAMenor(int num) {\n    cout << num << ' ';\n\n    if (num != 0) num_mayorAMenor(num - 1);\n};\n\nint factorial(int num) {\n    if (num == 1) return 1;\n\n    return num * factorial(num - 1);\n}\n\n\nint fibonacci(int num) {\n    if (num <= 1) return 0;\n\n    else if (num == 2) return 1;\n\n    else return fibonacci(num - 1) + fibonacci(num - 2);\n}\n\n\nint main() {\n    cout << \"\\n [+] Numeros del 100-0: \";\n    num_mayorAMenor(100);\n\n    cout << '\\n';\n\n    // ************ DIFICULTAD EXTRA ************ //n\n    \n    cout << \"\\n [+] Factorial de 5: \" << factorial(5);\n    cout << '\\n';\n\n    cout << \"\\n [+] Fibonacci Pos 5: \" << fibonacci(5);\n    cout << '\\n';\n\n    return 0;\n}"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/c++/Rgeditv1.cpp",
    "content": "#include <iostream>\n\nusing std::cout;\nusing std::cin;\n\n//Numeros del 100 al 0\n\nint contador(int cont = 100) //en el mandato pide 100 asi que simplemente lo defino\n{\n    if(cont < 0)\n    {\n        return 0;\n    }\n    cout << cont << std::endl;\n    return contador(cont-1);\n\n}\n\nint factorial(int n)\n{\n    if(n == 1 ) return 1;\n    return n * factorial(n-1);\n}\nint main()\n{\n    contador();\n\n    //Dificultad Opcional ::  Factorial de un numero\n    int nFactorial;\n    cout << \"Ingresa un numero: \";\n    cin >> nFactorial; cout << \"El Factorial de \" << nFactorial << \" Es \" << factorial(nFactorial);\n    return 0;\n}"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/c++/RoniPG.cpp",
    "content": "// @RoniPG\n\n#include <iostream>\n\nstatic int count=100;\nstatic int result=1;\nstatic int resultado=0;\nstatic int resultado2=1;\n\nvoid imprimirNumeros(){\n\tif ((count > -1) &&(count<101)){\n\t\tstd::cout<<count<<\",\"<<std::endl;\n\t\tcount--;\n\t\timprimirNumeros();\n\t}else{\n\t\tcount = 0;\n\t}\n}\nint factorial(int a);\nint fibonacci(int a);\n\nint main (){\n\t/*\n\t * Entiende el concepto de recursividad creando una función recursiva que imprima\n   * números del 100 al 0.\n\t */\n\timprimirNumeros();\n\t/*\n\t * DIFICULTAD EXTRA (opcional):\n   * Utiliza el concepto de recursividad para:\n   * - Calcular el factorial de un número concreto (la función recibe ese número).\n   * - Calcular el valor de un elemento concreto (según su posición) en la \n   *   sucesión de Fibonacci (la función recibe la posición).\n\t */\n\tfibonacci(6);\n\tfactorial(6);\n\n\n\treturn 0;\n}\nint factorial(int a){\n\tif (count < (a-1)) {\n\t\tresult=result*(count +2);\n\t\tcount++;\n\t\tfactorial(a);\n\t}else {\n\t\tstd::cout<<a<<\"! = \"<<result;\n\t\tcount =0;\n\t\treturn result;\n\t}\n\treturn 0;\n}\nint fibonacci(int a){\n\tif (a==1) {\n\t\tstd::cout<<0<<std::endl;\n\t\treturn 0;\n\t}else if ((a==2)||(a==3)) {\n\t\tstd::cout <<1<<std::endl;\n\t\treturn 0;\n\t}else if (count+2<a) {\n\t\tint x;\n\t\tx=resultado2+resultado;\n\t\tresultado=resultado2;\n\t\tresultado2=x;\n\t\tcount++;\n\t\tfibonacci(a);\n\t}else if (count+2>=a) {\n\t\tstd::cout<<resultado2<<std::endl;\n\t\tcount=0;\n\t}\n\treturn 0;\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/c++/Vid92.cpp",
    "content": "#include <iostream>\nusing namespace std;\n\nint n = 0;\nint a = 0;\nint b = 1;\n\nint imprimeNumeros(int inicio){\n    if(inicio==0){\n        cout<<inicio<<endl;\n        return 0;\n    }\n    else\n        cout<<inicio<<\", \";\n    return imprimeNumeros(inicio-1);\n}\n\n\nint factorial(int numero){\n    if(numero<0){\n        cout<<endl<<\"Factorial - Numero negativo, no valido!\"<<endl;\n        return 0;\n    }\n    if(numero==0)\n        return 1;\n    else\n        return numero * factorial(numero-1);\n}\n\nint fibonacci(int pos){\n    if(pos<0){\n        cout<<\"Fibonacci, Posicion no valida!\"<<endl;\n        return 0;\n    }\n    if(pos==1)\n        return n;\n    \n    n = a + b;\n    b = a;\n    a = n;\n    return fibonacci(pos-1);\n}\n\nint main()\n{\n    //Ejercicio\n    imprimeNumeros(100);\n    \n    //Extra\n    int fact = 8;   \n    int resultado = factorial(fact);\n    if(fact>=0)\n        cout<<endl<<\"El Factorial de \"<<fact<<\" es: \"<<resultado<<endl;\n    \n    int fibo = 11;\n    int fib = fibonacci(fibo);\n    if (fibo >0)\n        cout<<\"El valor fibonacci de \"<<fibo<<\" es: \"<<fib<<endl;\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/c++/h4ckxel.cpp",
    "content": "#include <iostream>\n\nvoid PrintNumbers(int number)\n{\n    if(number >= 0)\n    {\n        printf(\"%d\\n\", number);\n        PrintNumbers(number-1);\n    }\n\n    return;\n}\n\nint Factorial(int number)\n{\n    if(number==0)\n        return 1;\n    else\n        return (number * Factorial(number-1));\n}\n\nint Fibonacci(int number)\n{\n    if(number == 0)\n        return 0;\n    else if(number == 1)\n        return 1;\n    else\n        return ((Fibonacci(number-1) + Fibonacci(number-2)));\n}\n\nint main()\n{\n    PrintNumbers(100);\n    printf(\"\\n5! = %d\\n\\n\", Factorial(5));\n\n    for(int i=1; i<11; i++)\n    {\n        printf(\"Valor de la %d%c posicion en la sucesion de Fibonacci: %d\\n\", i, 167, Fibonacci(i));\n    }\n    \n    return 0;\n}"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/c++/hectorio23.cpp",
    "content": "#include <iostream>\n\n/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\n/***********************************************\n********** DECLARACION DE VARIABLES ************\n************************************************/\nint recursiveFoo(int);\nint factorial(int);\nint fibonacci(int);\n\nint main() {\n    int numeroCalcularFactorial = 3;\n    int posicion = 10;\n    int valor = fibonacci(posicion);\n\n    /**************************************************************************\n    ********** IMPRIME LOS NUMEROS DEL 100 - 0 DE MANERA RECURSIVA ************\n    **************************************************************************/\n\n    std::cout << \"********* NUMEROS DEL 100 - 0 *********\\n\";\n    recursiveFoo(100);\n    std::cout << \"\\n\";\n\n    /**************************************************************************\n    ********** IMPRIME EL FACTORIAL DE UN NUMERO DADO ************ ************\n    **************************************************************************/\n    std::cout << \"El factorial de <<\" << numeroCalcularFactorial << \">> es: \" << factorial(numeroCalcularFactorial) << \"\\n\";\n\n    /***********************************************************************************************\n    ********** IMPRIME EL VALOR DE UN NUMERO EN FUNCION A SU POSICION DENTRO ***********************\n    ***********************+*** DE LA SERIE DE FIBONACCI ******************************************* \n    ************************************************************************************************/\n\n    std::cout << \"El valor en la posición \" << posicion << \" de la sucesión de Fibonacci es: \" << valor << std::endl;\n\n    return 0;\n}\n\n// LAS FUNCIONES RECURSIVAS PUEDEN LLAMARSE INFINITAMENTE SI NO SE TIENE CUIDADO AL MOMENTO DE \n// PROGRAMARLAS, PUEDEN SATURAR LA PILA DE LLAMADAS Y CAUSAR UN STACK OVERFLOW, AFORTUNADAMENTE\n// LOS LENGUAJES COMO PYTHON, SU LIMITE DE RECURSIVIDAD ES DE 1,000 MIENTRAS QUE EN OTROS LENGUAJES\n// ESTABLECEN UN LIMITE SIMILAR.\n\n// Esta es una funcion recursiva que calculara (realmente imprimira) los valores\n// de valor inicial a 0, es decir, imprime los valores que segun n >= 0, al momento\n// de que el contador recursivo llega a cero, la funcion retorna un 0 y termina la\n// recursividad.\nint recursiveFoo(int valorInicial) {\n    // En caso de que el contador recursivo llegue a -1.\n    // La funcion finaliza su labor\n    if (valorInicial == -1) return 0;\n    std::cout << valorInicial << \", \";\n\n    // Se llama a la misma funcion pero el contador recursivo valdra n - 1 \n    return recursiveFoo(valorInicial - 1);\n}\n\nint factorial(int ivalue) {\n    // En caso de que el contador recursivo llegue a 1.\n    // La funcion finaliza su labor\n    if (ivalue == 1) return 1; \n\n    // El valor se multiplica 100 * (n - 1) * (n - 2) * (n -3) * ... (n - n)\n    return ivalue * factorial(ivalue - 1);\n}\n\n// Calcula el valor de la pocision dada al momento de llamar la funcion,\n// finalmente retorna el valor, recordemos que la sucesion de fibonacci\n// luce de la siguiente manera:\n// 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377 \nint fibonacci(int n) {\n    if (n <= 0) {\n        std::cout << \"La posición debe ser un entero positivo\" << std::endl;\n        return -1; // o manejo de error según sea necesario\n    }\n    else if (n == 1) return 0;\n    else if (n == 2) return 1;\n    else {\n        int a = 0, b = 1, temp;\n        for (int i = 2; i < n; ++i) {\n            temp = b;\n            b = a + b;\n            a = temp;\n        }\n        return b;\n    }\n}\n\n/**************************************************************************\n************************* OUTPUT EN EL TERMINAL ***************************\n**************************************************************************/\n\n/*\n********* NUMEROS DEL 100 - 0 *********\n100, 99, 98, 97, 96, 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80, 79, 78, 77, \n76, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, \n52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, \n28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, \n2, 1, 0, \nEl factorial de <<3>> es: 6\nEl valor en la posición 10 de la sucesión de Fibonacci es: 34\n\n*/\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/c++/jhoshmc.cpp",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n*/\n\n#include <iostream>\n\nusing namespace std;\n\nvoid conteoRecursivo(int);\n//! ejercicio extra\nvoid extra();\nint factorialRecursivo(int);\nint fibonacciRecursivo(int);\n\nint main(){\n  int numero = 100;\n  conteoRecursivo(numero);\n  extra();\n  return 0;\n}\n\nvoid conteoRecursivo(int numero){\n  //* este es el caso de finalizacion y finalizacion de la resurción\n  if(numero == 0){\n    cout << \"numero: \" << numero<<endl;\n    return ;\n  }\n  if(numero > 0){\n    //* se va imprimiendo el numero \n    cout << \"numero: \" << numero << endl;\n    //* se va retornando la funcion con un número menor al ya impreso\n    return conteoRecursivo(numero - 1);\n    \n\n  }\n}\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n*/\n\nvoid extra(){\n  int numeroFactorial;\n  int resultadoFactorial;\n  int posicionFibonacci;\n  int resultadoFibonacci;\n  cout << \"\\n\\t factorial: \\n\";\n  cout << \"ingrese un numero para ver su factorial: \";\n  cin >> numeroFactorial;\n  resultadoFactorial = factorialRecursivo(numeroFactorial);\n  cout << \"el factorial del numero \" << numeroFactorial << \"! es: \" << resultadoFactorial << endl;\n  cout << \"\\n\\t fibonacci: \\n\";\n  cout << \"ingrese la posicion fibonacci: \";\n  cin >> posicionFibonacci;\n  resultadoFibonacci = fibonacciRecursivo(posicionFibonacci);\n  cout << \"el numero fibonacci en la posicion: \" << posicionFibonacci << \" es : \" << resultadoFibonacci << endl;\n}\n\nint factorialRecursivo(int numero){\n  if(numero == 1){\n    return 1;\n  }\n  if (numero >=1)\n  {\n    return numero * factorialRecursivo(numero - 1);\n  }\n  \n}\n\nint fibonacciRecursivo(int numero){\n  if(numero == 0){\n    return 0;\n  }\n  if(numero == 1){\n    return 1;\n  }\n\n  return fibonacciRecursivo(numero - 1) + fibonacciRecursivo(numero - 2);\n}"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/c++/m-doce.cpp",
    "content": "#include <iostream>\r\n\r\nvoid PrintNumbers(int number)\r\n{\r\n    if(number >= 0)\r\n    {\r\n        printf(\"%d\\n\", number);\r\n        PrintNumbers(number-1);\r\n    }\r\n\r\n    return;\r\n}\r\n\r\nint Factorial(int number)\r\n{\r\n    if(number==0)\r\n        return 1;\r\n    else\r\n        return (number * Factorial(number-1));\r\n}\r\n\r\nint Fibonacci(int number)\r\n{\r\n    if(number == 0)\r\n        return 0;\r\n    else if(number == 1)\r\n        return 1;\r\n    else\r\n        return ((Fibonacci(number-1) + Fibonacci(number-2)));\r\n}\r\n\r\nint main()\r\n{\r\n    PrintNumbers(100);\r\n    printf(\"\\n5! = %d\\n\\n\", Factorial(5));\r\n\r\n    for(int i=1; i<11; i++)\r\n    {\r\n        printf(\"Valor de la %d%c posicion en la sucesion de Fibonacci: %d\\n\", i, 167, Fibonacci(i));\r\n    }\r\n    \r\n    return 0;\r\n}"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/c++/yeisonagm.cpp",
    "content": "/* EJERCICIO #06: RECURSIVIDAD\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la\n *   sucesión de Fibonacci (la función recibe la posición).\n */\n#include <iostream>\n\nusing namespace std;\n\n// Imprime números de manera recursiva\nvoid printNumbers(int n) {\n    // Si n es menor a 0, termina la recursividad\n    if (n < 0) {\n        return;\n    }\n\n    cout << n << \", \";\n    // Llamada recursiva\n    printNumbers(n - 1);\n}\n\n// Factorial de un número\nint factorial(int n) {\n    // Si n es 0, el factorial es 1\n    if (n == 0) return 1;\n\n    // Llamada recursiva\n    return n * factorial(n - 1);\n}\n\n// Elemento según la posición de la secuencia de Fibonacci\nint fibonacci(int n) {\n    // Si n es 0, el elemento es 0\n    if (n == 0) return 0;\n    // Si n es 1, el elemento es 1\n    if (n == 1) return 1;\n\n    // Llamada recursiva\n    return fibonacci(n - 1) + fibonacci(n - 2);\n}\n\nint main() {\n    cout << \"EJERCICIO #06: RECURSIVIDAD\" << endl;\n    // Imprime números del 100 al 0\n    cout << \"Imprimiendo números del 100 al 0:\" << endl;\n    printNumbers(100);\n    cout << endl;\n\n    // Factorial de un número\n    cout << \"\\nEjemplos de factoriales\" << endl;\n    for (int i = 0; i < 10; ++i) {\n        cout << i << \"! = \" << factorial(i) << endl;\n    }\n\n    // Elemento según la posición de la secuencia de Fibonacci\n    cout << \"\\nEjemplos de la secuencia de Fibonacci\" << endl;\n    for (int i = 0; i < 10; ++i) {\n        cout << \"Número de la posición \" << i << \" en la secuencia es \" << fibonacci(i) << endl;\n    }\n\n    return 0;\n}"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/cobol/any7dev.cbl",
    "content": "     /*\n      * EJERCICIO:\n      * Entiende el concepto de recursividad creando una función recursiva que imprima\n      * números del 100 al 0.\n      *\n      * DIFICULTAD EXTRA (opcional):\n      * Utiliza el concepto de recursividad para:\n      * - Calcular el factorial de un número concreto (la función recibe ese número).\n      * - Calcular el valor de un elemento concreto (según su posición) en la\n      *   sucesión de Fibonacci (la función recibe la posición).\n      */\n       IDENTIFICATION DIVISION.\n      *En COBOL hay que indicar que el programa es recursivo\n       PROGRAM-ID. RETO-06 RECURSIVE.\n       DATA DIVISION.\n       FILE SECTION.\n       WORKING-STORAGE SECTION.\n           77 NUMERO1 PIC 9(3) VALUE 0.\n           77 NUMERO2 PIC 9(1) VALUE 7.\n           77 FACT PIC 9(5) VALUE 0.\n       LOCAL-STORAGE SECTION.\n           77 NUM PIC 9(1).\n       PROCEDURE DIVISION.\n       RECURSIVIDAD.\n           ADD 1 TO NUMERO1\n           PERFORM UNTIL NUMERO1 > 100\n               DISPLAY NUMERO1\n      *Llamamos al programa para ejecutar la recursividad\n               CALL \"RETO-06\"\n           END-PERFORM.\n           END PROGRAM RETO-06.\n\n      *DIFICULTAD EXTRA\n\n      *Precisamente como en COBOL es el programa entero recursivo y no la función (párrafo), no he conseguido que funcione el ejercicio\n      *y la dificultad extra todo junto. Así que lo dejo en comentario como sería el factorial\n\n      *IDENTIFICATION DIVISION.\n      *PROGRAM-ID. FACTORIAL RECURSIVE.\n      * DATA DIVISION.\n      *FILE SECTION.\n      *WORKING-STORAGE SECTION.\n      *    77 NUMERO PIC 9(1) VALUE 7.\n      *    77 FACT PIC 9(5) VALUE 0.\n      *LOCAL-STORAGE SECTION.\n      *    77 NUM PIC 9(1).\n      *PROCEDURE DIVISION.\n      *    MOVE NUMERO TO NUM.\n      *    IF NUMERO = 0\n      *        MOVE 1 TO FACT\n      *    ELSE\n      *        SUBTRACT 1 FROM NUMERO\n      *        CALL \"FACTORIAL\"\n      *        MULTIPLY NUM BY FACT\n      *    END-IF.\n      *    DISPLAY FACT.\n      *END PROGRAM FACTORIAL.\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/dart/D3rk1us.dart",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n * \n */\n\nvoid main() {\n\n  print(recursividad(100));\n\n  print('------------------------------');\n\n  /*\n    * DIFICULTAD EXTRA (opcional):\n    * Utiliza el concepto de recursividad para:\n    * - Calcular el factorial de un número concreto (la función recibe ese número).\n    * - Calcular el valor de un elemento concreto (según su posición) en la \n    *   sucesión de Fibonacci (la función recibe la posición).\n  */\n\n  print(factorial(5));\n\n  print('------------------------------');\n\n  print(fibonacci(3));\n\n}\n\n// Funciones\n\nint recursividad(int number) {\n\n  if (number == 0) {\n    return number;\n  } else {\n    print(number);\n    return recursividad(number - 1);\n  }\n\n}\n\nint factorial(int number) {\n\n  if (number == 1) {\n    return number;\n  } else {\n    return number * factorial(number - 1);\n  }\n}\n\nint fibonacci(int position) {\n\n  if (position == 0) {\n    return 0;\n  } else if (position == 1) {\n    return 1;\n  } else {\n    return fibonacci(position - 1) + fibonacci(position - 2);\n  }\n}"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/dart/bluefeatherdev.dart",
    "content": "/*\n* EJERCICIO:\n* Entiende el concepto de recursividad creando una función recursiva que imprima\n* números del 100 al 0.\n*\n* DIFICULTAD EXTRA (opcional):\n* Utiliza el concepto de recursividad para:\n* - Calcular el factorial de un número concreto (la función recibe ese número).\n* - Calcular el valor de un elemento concreto (según su posición) en la \n*   sucesión de Fibonacci (la función recibe la posición).\n*/\n\n/// [Recursividad]: Números del 100 al 0\nvoid countDownFrom(int number) {\n  if (number >= 0) {\n    print(number);\n    countDownFrom(number - 1);\n  }\n}\n\n/// [DIFICULTAD EXTRA]: factorial de un número\nint getFactorial(int number) {\n  if (number < 0) return 0;\n  else if (number == 0) return 1;\n  else return number * getFactorial(number - 1);\n}\n\n/// [DIFICULTAD EXTRA]: valor posición en sucesión de Fibonacci\nint getFibonacci(int index) {\n  if (index <= 0) return 0;\n  else if (index == 1) return 0;\n  else if (index == 2) return 1;\n  else return getFibonacci(index - 1) + getFibonacci(index - 2);\n}\n\nvoid main() {\n  /// [Recursividad]: Números del 100 al 0\n  countDownFrom(100); // ...\n\n  /// [DIFICULTAD EXTRA]: factorial de un número\n  print(getFactorial(-5));  // 0\n  print(getFactorial(0));   // 1\n  print(getFactorial(5));   // 120\n\n  /// [DIFICULTAD EXTRA]: valor posición en sucesión de Fibonacci\n  print(getFibonacci(5));  // 3\n  print(getFibonacci(6));  // 5\n  print(getFibonacci(7));  // 8\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/dart/marinaortells.dart",
    "content": "/// URL del sitio web oficial: https://dart.dev/\n\nvoid main() {\n  print100(100);\n\n  /// Dificultad extra\n  \n  print(factorial(3));\n  print(fibonacci(10));\n}\n\nprint100(int num) {\n  if (num == 0 ) { print(0); }\n  else { \n    print(num);\n    print100(num - 1); }\n}\n\nfactorial(int num) {\n  \n  if (num == 0) { return 1; }\n  else { return num * factorial(num - 1); }\n\n}\n\nfibonacci(int num) {\n\n/// [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233]\n  if (num <= 1 ) { return num; }\n  return (fibonacci(num - 1) + fibonacci(num - 2));\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/dart/raulfauli.dart",
    "content": "/// #06 RECURSIVIDAD\n\nvoid main() {\n  printNumbers(100);\n\n  // Extra\n  print(factorial(10));\n  print(fibonacci(10));\n  print(count); // 177 me parecen muchas iteraciones decido mejorar el algoritmo\n  print(fibonacciWithStart(10));\n  print(count2); // 10\n}\n\nprintNumbers(int n) {\n  if (n >= 0) {\n    print(n);\n    printNumbers(n - 1);\n  }\n}\n\n// Extra\n// 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880\nint factorial(int n) {\n  if (n <= 1) {\n    return 1;\n  }\n\n  return n * factorial(n - 1);\n}\n\n// 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144\nint count = 0;\nint fibonacci(int n) {\n  count++;\n  if (n <= 1) {\n    return n;\n  }\n\n  return fibonacci(n - 1) + fibonacci(n - 2);\n}\n\nint count2 = 0;\nint fibonacciWithStart(int n, {(int, int) start = (0, 1)}) {\n  count2++;\n  if (n <= 1) {\n    return (n == 0) ? start.$1 : start.$2;\n  }\n\n  return fibonacciWithStart(n - 1, start: (start.$2, start.$1 + start.$2));\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/delphi/fduron.dpr",
    "content": "(*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una funcin recursiva que imprima\n * nmeros del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un nmero concreto (la funcin recibe ese nmero).\n * - Calcular el valor de un elemento concreto (segn su posicin) en la\n *   sucesin de Fibonacci (la funcin recibe la posicin).\n *)\n\nprogram fduron;\n\n{$APPTYPE CONSOLE}\n\n{$R *.res}\n\nuses\n  System.SysUtils;\n\nprocedure NumerosDescendentes(const Numero: integer);\nbegin\n  if numero >= 0 then\n  begin\n    WriteLn(Numero);\n    NumerosDescendentes(Numero - 1);\n  end;\nend;\n\nfunction Factorial(const Numero: Integer): Integer;\nbegin\n  if Numero > 1 then\n    Result := Numero * Factorial(Numero - 1)\n  else\n    Result := 1;\nend;\n\nfunction Fibonacci(const Posicion: Integer): Integer;\nbegin\n  if Posicion < 2 then\n    Result := Posicion\n  else\n    Result := Fibonacci(Posicion - 1) + Fibonacci(Posicion - 2);\nend;\n\nvar\n  Numero: Integer;\nbegin\n  NumerosDescendentes(100);\n\n  WriteLn('*****************************');\n  WriteLn(' Dificultad extra');\n  WriteLn('*****************************');\n  Write('Escribe un numero entero: ');\n  ReadLn(Numero);\n  WriteLn('El Factorial de ', Numero, ' es: ', Factorial(Numero));\n  WriteLn;\n  Write('Escribe la posicion de la serie fibonacci: ');\n  ReadLn(Numero);\n  WriteLn('En la posicion ', Numero, ' el valor fibonacci es: ', fibonacci(Numero));\n  ReadLn;\nend.\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/ejercicio.md",
    "content": "# #06 RECURSIVIDAD\n> #### Dificultad: Difícil | Publicación: 05/02/24 | Corrección: 12/02/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/erlang/edalmava.erl",
    "content": "-module(edalmava).\n-export([imprimir/1, factorial/1, fibonacci/1]).\n\nimprimir(Num) -> imprimir(Num, 0).\n\nimprimir(0, Result) -> Result; \nimprimir(Num, Result) ->\n    io:format(\"~w~n\", [Num]),\n    imprimir(Num - 1, Result).\n\nfactorial(N) -> factorial(N, 1).\n\nfactorial(0, Result) -> Result;\nfactorial(N, Result) -> factorial(N - 1, Result * N).\n\nfibonacci(N) -> fibonacci(N, 0, 1).\n\nfibonacci(0, Result, _Next) -> Result;\nfibonacci(N, Result, Next) -> fibonacci(N - 1, Next, Result + Next).\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/fortran/LeandroCFD.f90",
    "content": "program RECURSIVIDAD\n    implicit none\n\n    integer :: m\n\n    print*,\"Digite un número para contar hasta cero\"\n    read*,m\n\n    call contador(m)\n\n    !DIFICULTAD EXTRA\n    print*,\"Digite un número para calcular su factorial\"\n    read*,m\n\n    print*,\"El factorial de \",m,\" es \",factorial(m)\n\n    print*,\"Digite la posición de la serie de fibonacci que desea calcular\"\n    read*,m\n\n    print*,\"El número en la posición \",m,\" de la serie de fibonacci es \",fibonacci(m)\n\n    contains\n    recursive subroutine contador(n) !Subrutina recursiva que imprime desde un número hasta cero\n        integer, intent(in) :: n\n        if(n==0)then\n            print*,0\n        else\n            print*,n\n            call contador(n-1)\n        end if\n    end subroutine contador\n\n    recursive function factorial(n) result(resultado) !Función recursiva que calcula el factorial de un número\n        integer , intent(in) :: n\n        integer :: resultado\n        if(n==0)then\n            resultado=1\n        else\n            resultado=n*factorial(n-1)\n        end if\n    end function factorial\n\n    recursive function fibonacci(n) result(resultado) !Función recursiva que calcula la serie de fibonacci hasta cierta posición\n        integer, intent(in) :: n\n        integer (kind=8) :: resultado\n        if(n==0)then\n            resultado=0\n        else if(n==1)then\n            resultado=1\n        else\n            resultado=fibonacci(n-1)+fibonacci(n-2)\n        end if\n    end function fibonacci\n    \nend program RECURSIVIDAD\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/go/AmadorQuispe.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc main() {\n\tcountDownRecursive(2)\n\tf2 := factorialN(7)\n\tfmt.Println(\"Factorial de 7 es\", f2)\n\tresult := factorial(5)\n\tfmt.Println(\"Factorial de 5 es :\", result)\n\tf1 := fibonacci(7)\n\tfmt.Println(\"Fibonacci de 7 es :\", f1)\n\n}\n\nfunc countDownRecursive(n int) {\n\tif n < 0 {\n\t\tfmt.Println(\"La cuenta terminó\")\n\t\treturn\n\t}\n\tfmt.Println(\"Count : \", n)\n\tcountDownRecursive(n - 1)\n\n}\n\nfunc factorialN(n int) int {\n\tif n == 0 {\n\t\treturn 1\n\t}\n\taccumulator := 1\n\tfor i := 1; i <= n; i++ {\n\t\taccumulator *= i\n\t}\n\treturn accumulator\n}\n\nfunc factorial(n int) int {\n\tif n == 0 {\n\t\treturn 1\n\t}\n\treturn n * factorial(n-1)\n}\n\n//Función para calcular el n-ésimo número de Fibonacci\nfunc fibonacci(n int) int {\n\tif n <= 1 {\n\t\treturn 0\n\t} else if n == 2 {\n\t\treturn 1\n\t}\n\treturn fibonacci(n-1) + fibonacci(n-2)\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/go/FreyFonseca117.go",
    "content": "// # #06 RECURSIVIDAD\n// > #### Dificultad: Difícil | Publicación: 05/02/24 | Corrección: 12/02/24\n\n// ## Ejercicio\n\n// ```\n// /*\n//  * EJERCICIO:\n//  * Entiende el concepto de recursividad creando una función recursiva que imprima\n//  * números del 100 al 0.\n//  *\n//  * DIFICULTAD EXTRA (opcional):\n//  * Utiliza el concepto de recursividad para:\n//  * - Calcular el factorial de un número concreto (la función recibe ese número).\n//  * - Calcular el valor de un elemento concreto (según su posición) en la\n//  *   sucesión de Fibonacci (la función recibe la posición).\n//  */\n// ```\n// #### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\n// Sigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n// > Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n\npackage main\n\nimport \"fmt\"\n\n// valores que recibe la funcion.\nvar value1 int = 100\n\n// funcion que recorre los valores\nfunc recorreValores(a int) int {\n\tif a < 0 {\n\t\treturn 0\n\t} else {\n\t\tfmt.Println(a)\n\t\treturn recorreValores(a - 1)\n\t}\n}\n\n// funcion factorial\nfunc funFactorial(a int) int {\n\tif a == 0 {\n\t\treturn 1\n\t}\n\treturn a * funFactorial(a-1)\n}\n\n// funcion de binonacci\nfunc funFibonacci(num int) int {\n\tif num <= 0 {\n\t\treturn 0\n\t} else if num == 1 {\n\t\treturn 1\n\t}\n\treturn funFibonacci(num-1) + funFibonacci(num-2)\n\n}\n\nfunc main() {\n\trecorreValores(value1)\n\tresult := funFactorial(10)\n\tfmt.Println(result)\n\tresult2 := funFibonacci(10)\n\tfmt.Println(result2)\n\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/go/MiguelP-Dev.go",
    "content": "package main\n\nimport \"fmt\"\n\n/*\nLas funciones recursivas son aquellas que se llaman a si mismas dentro de su propio código.\nSon útiles para resolver problemas que pueden dividirse en subproblemas más pequeños del mismo tipo.\n\nVentajas:\nLas funciones recursivas puenden ser más fáciles de escribir y entender para problemas\nque tienen una estructura repetitiva natural(como árboles y gráficos).\n\nDesventajas:\nLas funciones recursivas pueden consumir más memoria debido a las llamadas repetitivas\ny el almacenamiento en la pila.\n\nPueden ser menos eficientes que las soluciones iterativas debido a la sobrecarga de llamas.\n*/\nfunc coutdown(n int) {\n\tfmt.Println(n)\n\tif n >= 1 {\n\t\tcoutdown(n - 1)\n\t}\n\treturn\n}\n\n/*\n1 Calcular el factorial de un número concreto (la función recibe ese número).\nConsiste en en multipllicar ese número por el factorial del número inmediatamente anterior,\nreduciendolo hasta llegar a 1 y devolver el resultado.\n*/\nfunc factorialCalc(n uint) uint {\n\tif n == 0 {\n\t\treturn 1\n\t} else if n == 1 {\n\t\treturn 1\n\t}\n\treturn n * factorialCalc(n-1)\n}\n\n/*\n2 Calcular el valor de un elemento concreto (según su posición) en la sucesión de Fibonacci (la función recibe la posición).\nCada número en la serie de Fibonacci es a suma de los dos números anteriores, usar la recursividad aquí involucra\ncalcular los números previos recursivamente hasta llegar a los casos base(0, 1, 2).\n*/\nfunc fibbo(n int) int {\n\tif n == 0 {\n\t\treturn 0\n\t} else if n == 1 {\n\t\treturn 1\n\t}\n\treturn fibbo(n-1) + fibbo(n-2)\n}\n\n/*\n3 Hanoi Towers:\nMover discos entre varillas siguiendo las reglas espesíficas se puede resolver el problema\ndividiendo el problema en mover discos más pequeños recursivamente.\n*/\n\nfunc hanoi(n int, origin, destiny, auxiliary string) {\n\tif n == 1 {\n\t\tfmt.Printf(\"Mover disco 1 de %s a %s\\n\", origin, destiny)\n\t\treturn\n\t}\n\thanoi(n-1, origin, auxiliary, destiny)\n\tfmt.Printf(\"Mover disco %v de %s a %s\\n\", n, origin, destiny)\n\thanoi(n-1, auxiliary, destiny, origin)\n}\n\nfunc main() {\n\t// Cuenta atrás\n\tcoutdown(100)\n\n\t// Factorial\n\tfmt.Println(\"El factorial de 25 es: \", factorialCalc(25))\n\n\t// Fibbonacci\n\tfmt.Println(\"El número en la posición 25 de la sucesión es: \", fibbo(25))\n\n\t// Torre de hanoi\n\thanoi(7, \"A\", \"B\", \"C\")\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/go/N0HagoNada.go",
    "content": "package main\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n)\n\nfunc main() {\n\tscanner := bufio.NewScanner(os.Stdin)\n\tfor {\n\t\tfmt.Println(\"Introduce una numero (o escribe 'exit' para salir):\")\n\t\tscanner.Scan()\n\t\tinput := strings.TrimSpace(scanner.Text())\n\n\t\tif strings.ToLower(input) == \"exit\" {\n\t\t\tbreak\n\t\t}\n\t\t// Convertir la entrada de string a int\n\t\tnumero, err := strconv.Atoi(input)\n\t\tif err != nil {\n\t\t\tfmt.Println(\"Por favor, introduce un número válido.\")\n\t\t\tcontinue\n\t\t}\n\t\tresutaldoFibo := CalcularFibonacci(numero)\n\t\tresultadoFact := factorial(numero)\n\t\tfmt.Printf(\"El valor en Fibonnaci de %d es: %d\\n\", numero, resutaldoFibo)\n\t\tfmt.Printf(\"El factorial de %d es: %d\\n\", numero, resultadoFact)\n\t\tif err := scanner.Err(); err != nil {\n\t\t\tfmt.Fprintln(os.Stderr, \"Error leyendo entrada:\", err)\n\t\t}\n\t}\n\tfmt.Println(\"El valor en la secuencia fibonacci para 11 es\", CalcularFibonacci(11))\n\tfmt.Println(\"El factorial de 5 es\", factorial(5))\n\tImprimirNumero(100)\n}\nfunc ImprimirNumero(n int) {\n\tif n < 0 {\n\t\tos.Exit(0)\n\t}\n\tfmt.Println(n)\n\tImprimirNumero(n - 1)\n}\n\n// Función recursiva para calcular el factorial de un número\nfunc factorial(n int) int {\n\tif n == 0 {\n\t\treturn 1\n\t}\n\treturn n * factorial(n-1)\n}\n\n// Funcion para  Calcular el valor de un elemento concreto (según su posición) en la sucesión de Fibonacci (la función recibe la posición).+\nfunc CalcularFibonacci(n int) int {\n\tif n <= 1 {\n\t\treturn n\n\t}\n\treturn CalcularFibonacci(n-1) + CalcularFibonacci(n-2)\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/go/hozlucas28.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc main() {\n\t/*\n\t   Recursive function...\n\t*/\n\n\tfmt.Println(\"\\nRecursive function...\")\n\n\tvar recursiveFn func(from int, to int, rtn *[]int)\n\n\trecursiveFn = func(from int, to int, rtn *[]int) {\n\t\tif from < to {\n\t\t\treturn\n\t\t}\n\n\t\t*rtn = append(*rtn, from)\n\t\trecursiveFn(from-1, to, rtn)\n\t}\n\n\tfmt.Println(\"\\nvar recursiveFn func(from int, to int, rtn *[]int)\")\n\n\tfmt.Println(\"\\nrecursiveFn = func(from int, to int, rtn *[]int) {\\n  if from < to {\\n    return\\n  }\\n\\n  *rtn = append(*rtn, from)\\n  recursiveFn(from-1, to, rtn)\\n}\")\n\n\tvar recursiveRtn []int\n\trecursiveFn(100, 0, &recursiveRtn)\n\n\tfmt.Println(\"\\nvar recursiveRtn []int\")\n\tfmt.Println(\"recursiveFn(100, 0, recursiveRtn)\")\n\n\tfmt.Printf(\"\\nrecursiveRtn --> %d\\n\", recursiveRtn)\n\n\tfmt.Println(\"\\n# ---------------------------------------------------------------------------------- #\\n\")\n\n\t/*\n\t   Additional challenge...\n\t*/\n\n\tfmt.Println(\"Get factorial...\")\n\n\tvar getFactorial func(number int) int\n\n\tgetFactorial = func(number int) int {\n\t\tif number < 2 {\n\t\t\treturn 1\n\t\t}\n\n\t\treturn number * getFactorial(number-1)\n\t}\n\n\tfmt.Println(\"\\nvar getFactorial func(number int) int\")\n\n\tfmt.Println(\"\\ngetFactorial = func(number int) int {\\n  if number < 2 {\\n    return 1\\n  }\\n\\n  return number * getFactorial(number-1)\\n}\")\n\n\tfmt.Printf(\"\\ngetFactorial(5) --> %d\\n\", getFactorial(5))\n\n\tfmt.Println(\"\\n# ---------------------------------------------------------------------------------- #\\n\")\n\n\tfmt.Println(\"Get Fibonacci value by position...\")\n\n\tvar getFibonacciValueByPos func(position int) int\n\n\tgetFibonacciValueByPos = func(position int) int {\n\t\tif position == 1 || position == 2 {\n\t\t\treturn 1\n\t\t}\n\n\t\treturn getFibonacciValueByPos(position-1) + getFibonacciValueByPos(position-2)\n\t}\n\n\tfmt.Println(\"\\nvar getFibonacciValueByPos func(position int) int\")\n\n\tfmt.Println(\"\\ngetFibonacciValueByPos = func(position int) int {\\n  if position == 1 || position == 2 {\\n    return 1\\n  }\\n\\n  return getFibonacciValueByPos(position-1) + getFibonacciValueByPos(position-2)\\n}\")\n\n\tfmt.Printf(\"\\ngetFibonacciValueByPos(8) --> %d\", getFibonacciValueByPos(8))\n\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/go/kodenook.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc main() {\n\trecursion(100)\n}\n\nfunc recursion(number uint64) {\n\tfmt.Println(number)\n\n\tif number > 0 {\n\t\trecursion(number - 1)\n\t}\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/go/miguelex.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc factorial(n int) int {\n\tif n == 0 {\n\t\treturn 1\n\t}\n\treturn n * factorial(n-1)\n}\n\nfunc fibonacci(n int) int {\n\tif n <= 1 {\n\t\treturn n\n\t}\n\treturn fibonacci(n-1) + fibonacci(n-2)\n}\n\nfunc potencia(base, exponente int) int {\n\tif exponente == 0 {\n\t\treturn 1\n\t}\n\treturn base * potencia(base, exponente-1)\n}\n\nfunc suma(a, b int) int {\n\tif b == 0 {\n\t\treturn a\n\t}\n\treturn 1 + suma(a, b-1)\n}\n\nfunc imprimirNumeros(numero int) {\n\tif numero >= 0 {\n\t\tfmt.Print(numero, \" \")\n\t\timprimirNumeros(numero - 1)\n\t}\n}\n\nfunc main() {\n\tfmt.Println(\"La suma de 3 + 5 usando recursividad es: \", suma(3, 5))\n\tfmt.Println(\"La potencia de 2^3 usando recursividad es: \", potencia(2, 3))\n\tfmt.Println(\"El valor de 5! es: \", factorial(5))\n\tfmt.Println(\"El valor de del 10º numero de Fibonacci es: \", fibonacci(10))\n\tfmt.Println(\"De 100 a 0 usando rercursividad: \")\n\timprimirNumeros(100)\n\tvar n int\n\tfmt.Println(\"Ingrese un número para calcular su factorial: \")\n\tfmt.Scan(&n)\n\tfmt.Println(\"El valor de \", n, \"! es: \", factorial(n))\n\tfmt.Println(\"Ingrese un número para calcular su número de Fibonacci: \")\n\tfmt.Scan(&n)\n\tfmt.Println(\"El valor de del \", n, \"º numero de Fibonacci es: \", fibonacci(n))\n\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/go/qwik-zgheib.go",
    "content": "package main\n\nimport \"fmt\"\n\n/* example */\ntype RecursivePrinter interface {\n\tPrintNumbers(n int)\n}\n\ntype NumberPrinter struct{}\n\nfunc NewNumberPrinter() *NumberPrinter {\n\treturn &NumberPrinter{}\n}\n\nfunc (np *NumberPrinter) PrintNumbers(n int) {\n\tif n < 0 {\n\t\treturn\n\t}\n\tfmt.Println(n)\n\tnp.PrintNumbers(n - 1)\n}\n\n/* extra - i */\ntype FactorialCalculator interface {\n\tFactorial(n int) int\n}\n\ntype SimpleFactorialCalculator struct{}\n\nfunc NewSimpleFactorialCalculator() *SimpleFactorialCalculator {\n\treturn &SimpleFactorialCalculator{}\n}\n\nfunc (fc *SimpleFactorialCalculator) Factorial(n int) int {\n\tif n <= 1 {\n\t\treturn 1\n\t}\n\treturn n * fc.Factorial(n-1)\n}\n\ntype SimpleFibonacciCalculator struct{}\n\n/* extra - ii */\ntype FibonacciCalculator interface {\n\tFibonacci(n int) int\n}\n\nfunc NewSimpleFibonacciCalculator() *SimpleFibonacciCalculator {\n\treturn &SimpleFibonacciCalculator{}\n}\n\nfunc (fc *SimpleFibonacciCalculator) Fibonacci(n int) int {\n\tif n <= 1 {\n\t\treturn n\n\t}\n\treturn fc.Fibonacci(n-1) + fc.Fibonacci(n-2)\n}\n\nfunc main() {\n\tnumberPrinter := NewNumberPrinter()\n\tfactorialCalculator := NewSimpleFactorialCalculator()\n\tfibonacciCalculator := NewSimpleFibonacciCalculator()\n\n\tfmt.Println(\"Printing numbers from 100 to 0:\")\n\tnumberPrinter.PrintNumbers(100)\n\n\tfmt.Println(\"\\nFactorial of 5:\")\n\tfmt.Println(factorialCalculator.Factorial(5))\n\n\tfmt.Println(\"\\nFibonacci number at position 10:\")\n\tfmt.Println(fibonacciCalculator.Fibonacci(10))\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/go/raynerpv2022.go",
    "content": "package main\n\nimport \"fmt\"\n\n// * EJERCICIO:\n// * Entiende el concepto de recursividad creando una función recursiva que imprima\n// * números del 100 al 0.\n// *\n// * DIFICULTAD EXTRA (opcional):\n// * Utiliza el concepto de recursividad para:\n// * - Calcular el factorial de un número concreto (la función recibe ese número).\n// * - Calcular el valor de un elemento concreto (según su posición) en la\n// *   sucesión de Fibonacci (la función recibe la posición).\n\nfunc number100To0(number int) {\n\tif number >= 0 {\n\n\t\tfmt.Println(number)\n\t\tnumber100To0((number - 1))\n\t}\n\n}\n\nfunc factorial(number int) int {\n\tif number <= 0 {\n\t\treturn 0\n\t} else if number <= 1 {\n\t\treturn 1\n\t} else {\n\t\treturn factorial(number-1) * number\n\t}\n\n}\n\nfunc fibonacci(index int) int {\n\tif index <= 1 {\n\t\treturn 0\n\t} else if index == 2 {\n\t\treturn 1\n\t} else {\n\t\treturn fibonacci((index - 1)) + fibonacci((index - 2))\n\t}\n\n}\nfunc main() {\n\tnumber100To0((100))\n\tfmt.Println(factorial(6))\n\tfmt.Println(fibonacci(8))\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/go/thegera4.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc main() {\n\tfmt.Println(cuentaRegresiva(100))\n\tfmt.Println(factorial(5)) //120\n\tfmt.Println(fibonacci(10)) //55\n}\n\nfunc cuentaRegresiva(number int) int{\n\tif number == 0 { return 0 }\n\tfmt.Println(number)\n\treturn cuentaRegresiva(number - 1)\n}\n\n//Dificultad extra\nfunc factorial(number int) int{\n\tif number == 0 { return 1 }\n\treturn number * factorial(number - 1)\n}\n\n//Dificultad extra\nfunc fibonacci(position int) int{\n\tif position == 0 { return 0 }\n\tif position == 1 { return 1 }\n\treturn fibonacci(position - 1) + fibonacci(position - 2)\n}"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/java/AbelADE.java",
    "content": "/**\n * Solución al ejercicio #06 RECURSIVIDAD.\n * \n * @author AbelADE\n */\npublic class AbelADE {\n\n    public static void recursive(int number) {\n        if (number >= 0) {\n            System.out.println(number--);\n            recursive(number);\n        }\n    }\n    \n    // DIFICULTAD EXTRA (opcional):\n\n    public static Long factorial(int number) {\n        if (number < 0) {\n            System.out.println(\"No acepta números negativos\");\n            return -1L;\n        }else if (number == 0) {\n            return 1L;\n        }\n        \n        return number * factorial(number -1);\n    }\n    \n    public static Long fibonacci(int number) {\n        if (number <= 0) {\n            System.out.println(\"No acepta números negativos\");\n            return -1L;\n        }else if (number == 1) {\n            return 0L;\n        }else if (number == 2) {\n            return 1L;\n        }\n        \n        return fibonacci(number -1) + fibonacci(number -2);\n    }\n\n    /**\n     * @param args the command line arguments\n     */\n    public static void main(String[] args) {\n        System.out.println(\"Recursividad: \");\n        System.out.println();\n        \n        System.out.println(\"Imprimir números: \");\n        recursive(100);\n        System.out.println();\n        \n        System.out.println(\"Factorial: \");\n        System.out.println(factorial(4));\n        System.out.println();\n        \n        System.out.println(\"Fibonacci: \");\n        System.out.println(fibonacci(10));\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/java/Alextc35.java",
    "content": "/*                                                                                                                \n * EJERCICIO:                                                                                                     \n * Entiende el concepto de recursividad creando una función recursiva que imprima                                 \n * números del 100 al 0.                                                                                          \n *                                                                                                                \n * DIFICULTAD EXTRA (opcional):                                                                                   \n * Utiliza el concepto de recursividad para:                                                                      \n * - Calcular el factorial de un número concreto (la función recibe ese número).                                  \n * - Calcular el valor de un elemento concreto (según su posición) en la                                          \n *   sucesión de Fibonacci (la función recibe la posición).                                                       \n */\npublic class Alextc35 {\n    public static void main(String[] args) {\n        // Ejercicio\n        System.out.println(\"----- Recursividad -----\");\n        recursividad(100);\n        System.out.println(\"------------------------\\n\");\n\n        // Opcional\n        // Factorial\n        System.out.println(\"----- Factorial -----\");\n        int fact = 4;\n        System.out.println(\" El factorial de \" + fact\n                + \"! es \" + factorial(fact));\n        System.out.println(\"------------------------\\n\");\n\n        // Fibonacci\n        System.out.println(\"----- Fibonacci -----\");\n        int fib1 = 0;\n        int fib2 = 1;\n        int fib3 = 3;\n        int fib4 = 5;\n        System.out.println(\"En la posición \" + fib1\n                + \" el valor de la sucesión de fibonacci es: \"\n                + fibonacci(fib1)); // 1\n        System.out.println(\"\\nEn la posición \" + fib2\n                + \" el valor de la sucesión de fibonacci es: \"\n                + fibonacci(fib2)); // 1\n        System.out.println(\"\\nEn la posición \" + fib3\n                + \" el valor de la sucesión de fibonacci es: \"\n                + fibonacci(fib3)); // 5\n        System.out.println(\"\\nEn la posición \" + fib4\n                + \" el valor de la sucesión de fibonacci es: \"\n                + fibonacci(fib4)); // 8\n        System.out.println(\"------------------------\");\n    }\n\n    // Ejercicio\n    public static void recursividad(int n) {\n        if (n < 0) {\n            return;\n        }\n        System.out.println(n);\n        recursividad(n - 1);\n    }\n\n    // Opcional\n\n    // Factorial\n    public static int factorial(int n) {\n        if (n == 0) {\n            return 1;\n        } else {\n            return n * factorial(n - 1);\n        }\n    }\n\n    // Fibonacci\n    public static int fibonacci(int pos) {\n        if (pos == 0) {\n            return 0;\n        } else if (pos == 1) {\n            return 1;\n        } else {\n            return fibonacci(pos - 1) + fibonacci(pos - 2);\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/java/AmadorQuispe.java",
    "content": "public class AmadorQuispe {\n    public static void main(String[] args) {\n        // Una función recursiva es una función que llama a sí misma para resolver un\n        // problema, para evitar loop infinito debe tener una condición base donde ya\n        // no sea necesario llamarse a la función.\n        int number = 7;\n        // Ejercicio 01, imprimir cuenta regresiva dado un número hasta llegar a cero.\n        countDown(100); // sin recursividad\n        countDownRecursive(100); // con recursividad\n\n        // Ejercicio 02, Calcular el factorial de un número concreto\n        System.out.println(\"El factorial del número \" + number + \" es :\" + factorial(number));// sin recursividad.\n        System.out.println(\"El factorial del número \" + number + \" es :\" + factorialRecursive(number));// con\n                                                                                                       // recursividad.\n\n        // Ejercicio 03, Calcular el valor de un elemento concreto (según su posición)\n        System.out.println(\"El término \" + number + \" de la secuencia de Fibonacci es: \" + fibonacci(number)); // sin\n                                                                                                               // recursividad.\n        System.out.println(\"El término \" + number + \" de la secuencia de Fibonacci es: \" + fibonacciRecursive(number));// con\n                                                                                                                       // recursividad.\n\n    }\n\n    public static void countDown(int n) {\n        for (int i = n; i >= 0; i--) {\n            System.out.println(i);\n        }\n        System.out.println(\"termino la cuenta regresiva\");\n    }\n\n    public static void countDownRecursive(int n) {\n        if (n < 0) {\n            System.out.println(\"termino la cuenta regresiva\");\n            return;\n        }\n        System.out.println(\"cuenta \" + n);\n        countDownRecursive(--n);\n    }\n\n    public static int factorial(int n) {\n        int result = n;\n        for (int i = n; i >= 2; i--) {\n            result *= i - 1;\n        }\n        return result;\n    }\n\n    public static int factorialRecursive(int n) {\n        if (n == 0) {\n            return 1;\n        }\n        return n * factorial(n - 1);\n    }\n\n    public static int fibonacci(int n) {\n        if (n <= 1) {\n            return n;\n        }\n\n        int prev1 = 0;\n        int prev2 = 1;\n        int fib = 0;\n\n        for (int i = 2; i <= n; i++) {\n            fib = prev1 + prev2;\n            prev1 = prev2;\n            prev2 = fib;\n        }\n\n        return fib;\n    }\n\n    public static int fibonacciRecursive(int n) {\n        if (n <= 1) {\n            return n;\n        }\n        return fibonacci(n - 1) + fibonacci(n - 2);\n    }\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/java/AnaLauDB.java",
    "content": "public class AnaLauDB {\n\n    // Funcion recursiva que imprima todos los numeros del 1 al 100\n    public static void NUmeros(int n) {\n        if (n > 100) {\n            return;\n        }\n        System.out.println(n);\n        NUmeros(n + 1);\n    }\n\n    // Funcion recursiva para factorial\n    public static int Facto(int x) {\n        if (x == 0) {\n            return 1;\n        } else {\n            return x * Facto(x - 1);\n        }\n    }\n\n    // Funcion recursiva para Fibonacci\n    public static int Fibonacci(int n) {\n        if (n <= 1) {\n            return n;\n        }\n        return Fibonacci(n - 1) + Fibonacci(n - 2);\n    }\n\n    public static void main(String[] args) {\n        NUmeros(1);\n\n        int numero = 5;\n        System.out.println(\"Factorial de \" + numero + \" es: \" + Facto(numero));\n\n        int fiboNumero = 10;\n        System.out.println(\"Fibonacci de \" + fiboNumero + \" es: \" + Fibonacci(fiboNumero));\n    }\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/java/AndrewCodev.java",
    "content": "public class AndrewCodev {\n\n\t// Listar números del 100 al 0\n\tpublic static void listarNumeros(int numero) {\n\t\tif (numero >= 0) {\n\t\t\tSystem.out.println(numero);\n\t\t\tlistarNumeros(numero - 1);\n\t\t}\n\t}\n\n\t// Calcular el factorial de un número\n\tpublic static int factorial(int numero) {\n\t\tif (numero < 0) {\n\t\t\tSystem.out.println(\"\\nEl número no es valido para realizar la función factorial\");\n\t\t\treturn 0;\n\t\t} else if (numero == 0) {\n\t\t\treturn 1;\n\t\t} else {\n\t\t\treturn numero * factorial(numero - 1);\n\t\t}\n\t}\n\n\t// Buscar elemento de la serie de Fibonacci segun la posición enviada\n\tpublic static int posicionFibonacci(int posicion) {\n\t\tif (posicion == 0) {\n\t\t\treturn 0;\n\t\t} else if (posicion == 1) {\n\t\t\treturn 0;\n\t\t} else if (posicion == 2) {\n\t\t\treturn 1;\n\t\t} else {\n\t\t\treturn posicionFibonacci(posicion - 1) + posicionFibonacci(posicion - 2);\n\t\t}\n\t}\n\n\tpublic static void main(String[] args) {\n\t\t// Impresión del 100 al 0;\n\t\tint numero = 100;\n\t\tlistarNumeros(numero);\n\n\t\t// Factorial\n\t\tint numero1 = 5;\n\t\tint factorial = factorial(numero1);\n\t\tif (factorial > 0) {\n\t\t\tSystem.out.println(\"\\nEl factorial de: \" + numero1 + \" es: \" + factorial);\n\t\t}\n\t\t// Posicion en la serie de Fibonacci\n\t\tint posicion = 9;\n\t\tif (posicion <= 0) {\n\t\t\tSystem.out.println(\n\t\t\t\t\t\"\\nEl número no es valido para realizar la función Fibonacci, debe ser un número mayor a 0\");\n\t\t} else {\n\t\t\tint elemento = posicionFibonacci(posicion);\n\t\t\tSystem.out.println(\"\\nLa posición: \" + posicion + \" en la serie de Fibonacci \" + \"corresponde al elemento: \"\n\t\t\t\t\t+ elemento);\n\t\t}\n\t}\n}"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/java/FranDev200.java",
    "content": "import java.util.Scanner;\n\npublic class FranDev200 {\n\n    static int numero = 100;\n\n    static int resultadoFactorial = 1;\n\n\n    static int contadorPosicion = 1;\n    static int  a = 0, b = 1, c = 0;\n\n    static void main() {\n        /*\n\n            Entiende el concepto de recursividad creando una función recursiva que imprima\n            números del 100 al 0.\n\n         */\n\n        recursividad();\n\n        /*\n\n         DIFICULTAD EXTRA (opcional):\n          Utiliza el concepto de recursividad para:\n          - Calcular el factorial de un número concreto (la función recibe ese número).\n          - Calcular el valor de un elemento concreto (según su posición) en la\n          sucesión de Fibonacci (la función recibe la posición).\n\n         */\n        Scanner scan = new Scanner(System.in);\n        System.out.print(\"Introduce el numero para calcular su factorial: \");\n        int numFactorial = Integer.parseInt(scan.nextLine());\n        System.out.println(\"Factorial de \" + numFactorial + \": \" + factorial(numFactorial));\n\n        System.out.print(\"Introduce la posicion de la sucesion de Fibonacci que quieres ver: \");\n        int posicionFibonacci = Integer.parseInt(scan.nextLine());\n        System.out.println(\"Numero de la sucesion de Fibonacci de la posicion \" + posicionFibonacci\n                + \": \" + fibonacci(posicionFibonacci));\n\n    }\n\n    public static void recursividad(){\n\n        if(numero >= 0){\n            System.out.println(numero);\n            numero--;\n            recursividad();\n        }\n\n    }\n\n    // - Calcular el factorial de un número concreto (la función recibe ese número).\n    public static int factorial(int num){\n\n        if(num > 0){\n            resultadoFactorial = resultadoFactorial * num;\n            num--;\n            factorial(num);\n        }\n        return resultadoFactorial;\n    }\n\n    // - Calcular el valor de un elemento concreto (según su posición) en la sucesión de Fibonacci (la función recibe la posición).\n\n    public static int fibonacci(int posicion){\n        if(contadorPosicion < posicion){\n\n            c = a + b;\n            a = b;\n            b = c;\n\n            contadorPosicion++;\n            fibonacci(posicion);\n        }\n\n        return c;\n\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/java/Gerthai08.java",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la\n *   sucesión de Fibonacci (la función recibe la posición).\n */\npublic class Gerthai08 {\n    public static void main(String[] args) {\n\n        //Llamando al método \"countdown\"\n        System.out.println(\"=====Countdown=====\");\n        countdown(100);\n\n        //Llamando al método \"factorial\"\n        System.out.println(\"\\n<=====Factorial=====\");\n        System.out.println(\"El factorial de 5 es: \" + factorial(5));\n\n        //Llamado al método para \"la sucesión de Fibonacci\"\n        System.out.println(\"\\n<=====Fibonacci=====\");\n        int position = 7;\n        System.out.println(\"Fibonacci en posición \" + position + \" es \" + fibonacci(position));\n    }\n\n    //Método para la sucesión de Fibonacci\n    private static int fibonacci(int n){\n        if (n == 0) {\n            return 0;\n        }else if (n == 1){\n            return 1;\n        }else{\n            return fibonacci(n-1) + fibonacci(n-2);\n        }\n    }\n\n    //Método para calculo factorial\n    private static int factorial(int n) {\n        if(n > 1){\n            return n * factorial(n - 1);\n        }else{\n            return 1;\n        }\n    }\n\n    //Método que imprime números del 100 al 0\n    static void countdown(int n){\n        if(n >= 0){\n            System.out.print(n + \" \");\n            //si el numero es múltiplo de 10 hace un salto de linea\n            if (n % 10 == 0){\n                System.out.println();\n            }\n            countdown(n - 1);\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/java/GlossyPath.java",
    "content": "/**\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n * \n * @version v1.0\n * \n * @since 05/07/2024\n * \n * @author GlossyPath\n * \n */\n\npublic class GlossyPath {\n    /*\n     * Descripción: método para calcular el valor de un elemento.\n     */\n    public static int Fibonacci(int num){\n\n        if (num <= 1) {\n            return num; \n        } else {\n            return Fibonacci(num - 1) + Fibonacci(num - 2);\n        }\n    }\n    /*\n     * Descripción: método para obtener el factorial de un número.\n     */\n    public static int factorial(int num){\n\n        int total;\n\n        if(num>0){\n            return total = num * factorial(num-1);\n        } else {\n            return 1;\n        }\n    }\n    /*\n     * Descripción: método para imprimir recursivamente numeros de mayor a menor.\n     */\n    public static void impresionRecursiva(int num){\n\n        if(num>=0){\n\n            System.out.println(num);\n            impresionRecursiva(num-1);\n        }\n    }\n\n    public static void main(String[] args) {\n        \n        impresionRecursiva(100);\n\n        int total = factorial(0);\n        System.out.println(total);\n\n        int totalFibo = Fibonacci(5);\n        System.out.println(totalFibo);\n    }\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/java/Guillermo-Munoz.java",
    "content": "/**\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n * \n * @version v1.0\n * @since 05/03/2026\n * @author Guillermo-Munoz\n * \n */\npublic class GuillermoMunoz {\n\n\n    public static void main(String[] args) {\n\n        countDown(100);\n        System.out.println(\"Factorial de 5: \" + factor(5));\n        System.out.println(\"Segun la posición de fibonacci 10 el valor es: \" + fibonacci(5));\n    }\n\n    //Funcion recursiva cuenta decreciente de 100 a 0\n\n    public static void countDown(int num){\n        System.out.println(num);\n        if(num > 0){\n            --num;\n            countDown(num);\n        }\n    }\n\n    //Calcular el factorial de un número concreto (la función recibe ese número).\n\n    public static int factor(int num){\n    \n        if(num < 0){\n            System.out.println(\"Los numeros negativos no son validos\");\n        }else{\n            if(num == 0){\n                return 1;\n            }\n        }\n    \n        return num * factor(num - 1);\n    }\n\n    //Calcular el valor de un elemento concreto (según su posición) en la \n    //sucesión de Fibonacci (la función recibe la posición).\n\n    public static int fibonacci(int num){\n\n        \n        if(num < 0){\n            System.out.println(\"No se admiten numeros negativos\");\n            return 0;\n        }else if(num < 2){\n            return 1;\n        }else{\n            return  fibonacci(num - 1) + fibonacci(num - 2);\n        }\n        \n    }\n\n\n    \n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/java/GustavoGomez19.java",
    "content": "public class GustavoGomez19 {\n\n    // Función recursiva que imprime los números del 100 al 0\n    public static void funcRecursiva(int num){\n        if(num >= 0){\n            System.out.println(num);\n            funcRecursiva(num - 1);\n        }\n    }\n\n    public static int factorial(int num){\n        // Caso base, cuando el número es 0, el factorial es 1\n        if(num == 0){\n            return 1;\n        } else {\n            // Caso de recursividad\n            return num * factorial(num - 1);\n        }\n    }\n\n    public static int fibonacci(int pos){\n        if(pos <=1){\n            // El valor Fibonacci para pos <=1 es pos\n            return pos;\n        } else {\n            // El valor Fibonacci para pos es la suma de los valores de Fibonacci para pos - 1 y pos - 2\n            return fibonacci(pos - 1) + factorial(pos - 2);\n        }        \n    }\n\n    public static void main(String[] args) {\n        // Función recursiva que imprime los números del 100 al 0\n        funcRecursiva(100);\n        \n        // Ejercicio factorial\n        int num = 10;\n        int resultado = factorial(num);\n        System.out.println(\"El factorial de \" + num + \" es \" + resultado);\n\n        // Ejercicio valor elemento sucesión Fibonacci\n        int posicion = 10;\n        int valor = fibonacci(posicion);\n        System.out.println(\"El valor del elemento en la posición \" + posicion + \" de la secuencia Fibonacci es \" + valor);\n    }\n    \n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/java/Jeigar2.java",
    "content": "import java.util.stream.IntStream;\nimport java.util.stream.LongStream;\n\npublic class Jeigar2 {\n    /*\n     * EJERCICIO:\n     * Entiende el concepto de recursividad creando una función recursiva que imprima\n     * números del 100 al 0.\n     *\n     * DIFICULTAD EXTRA (opcional):\n     * Utiliza el concepto de recursividad para:\n     * - Calcular el factorial de un número concreto (la función recibe ese número).\n     * - Calcular el valor de un elemento concreto (según su posición) en la\n     *   sucesión de Fibonacci (la función recibe la posición).\n     */\n    public static final int TOTAL = 100;\n    public static void main(String[] args) {\n        System.out.println(\"Los número del 0 al 100\");\n        impresionRecursiva(TOTAL);\n        System.out.println(\"\");\n\n        System.out.println(\"\\nLos 10 primeros factoriales\");\n        IntStream.rangeClosed(0,10).forEach(fac -> System.out.println(String.format(\" - %d! = %d\", fac, factorial(fac))));\n        System.out.println(\"\\nPosicione Fibonacci de la 10 a la 12\");\n        IntStream.rangeClosed(10,12).forEach(fibo -> System.out.println(String.format(\" - F(%d) = %d\", fibo, (new Fibonacci(fibo)).getValor())));\n    }\n\n    public static void impresionRecursiva(int total){\n        if(total>=0) {\n            if(total%10==0) {\n                System.out.println(\"\");\n                System.out.print(TOTAL - total);\n            }else {\n                System.out.print((((total < TOTAL) ? \", \" : \"\") + (TOTAL - total)));\n            }\n            impresionRecursiva(total-1);\n        }\n    }\n\n    /*\n     * DIFICULTAD EXTRA (opcional):\n     * Utiliza el concepto de recursividad para:\n     * - Calcular el factorial de un número concreto (la función recibe ese número).\n     * - Calcular el valor de un elemento concreto (según su posición) en la\n     *   sucesión de Fibonacci (la función recibe la posición).\n     */\n    public static long factorial(int total){\n        long resultado = 0;\n        if(total == 0 && resultado == 0)\n            resultado = 1;\n        if(total > 0)\n            resultado = total * factorial(total-1);\n        return resultado;\n    }\n\n    static class Fibonacci {\n        private long a = 0;\n        private long b = 1;\n        private long valor = 0;\n\n        Fibonacci(int n){\n            if (n == 0)\n                valor = a;\n            if (n == 1)\n                valor = b;\n            if (n >= 2)\n                valor = secuencia(n);\n        }\n        private long secuencia(int n){\n            long suma = 1;\n            long aux = 0;\n            if(n>2) {\n                aux = this.a;\n                this.a = this.b;\n                this.b = aux + this.b;\n                suma = a + secuencia(n - 1);\n            }\n            return suma;\n        }\n\n        public long getValor() {\n            return valor;\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/java/JesusAntonioEEscamilla.java",
    "content": "\n\n/** #06 - Java -> Jesus Antonio Escamilla */\n\npublic class JesusAntonioEEscamilla {\n    public static void main(String[] args) {\n    //---EJERCIÓ---\n        System.out.println(\"Recursividad\");\n        imprimirNúmeros(100);\n    //---EXTRA---\n        System.out.println(\"Factorial\");\n        System.out.println(factorial(5));\n        System.out.println(\"Fibonacci\");\n        System.out.println(fibonacci(10));\n    }\n\n    //---EJERCIÓ---\n    // Definiendo la función\n    public static void imprimirNúmeros(int n) {\n        if (n < 0) {\n            return;\n        }\n        System.out.println(n);\n        // Aquí es donde se realizar la Recursividad\n        imprimirNúmeros(n - 1);\n    }\n\n    /**-----DIFICULTAD EXTRA-----*/\n\n    // Factorial\n    public static int factorial(int n){\n        if (n == 0 || n == 1) {\n            return 1;\n        }\n        return n * factorial(n - 1);\n    }\n\n    // Fibonacci\n    public static int fibonacci(int n){\n        if (n == 0) {\n            return 0;\n        } else if(n == 1) {\n            return 1;\n        }\n        return fibonacci(n - 1) + fibonacci(n -2);\n    }\n\n    /**-----DIFICULTAD EXTRA-----*/\n}"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/java/JesusEs1312.java",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\n public class JesusEs1312 {\n    public static void main(String[] args) {\n        // Llamada a la función que imprime números del 100 al 0\n        imprimirNumeros(100);\n\n        // Llamada a la función que calcula el factorial de un número concreto\n        System.out.println(factorial(5));\n\n        // Llamada a la función que calcula el valor de un elemento concreto en la sucesión de Fibonacci\n        System.out.println(fibonacci(10));\n    }\n\n    public static void imprimirNumeros(int numero) {\n        if (numero >= 0) {\n            System.out.println(numero);\n            imprimirNumeros(numero - 1);\n        }\n    }\n\n    // Calcula el factorial de un número concreto\n    public static int factorial(int numero){\n        if (numero == 0) {\n            return 1;\n        } else {\n            return numero * factorial(numero - 1);\n        }\n    }\n\n    // Calcula el valor de un elemento concreto en la sucesión de Fibonacci\n    public static int fibonacci(int posicion){\n        if (posicion == 0 || posicion == 1) {\n            return posicion;\n        } else {\n            return fibonacci(posicion - 1) + fibonacci(posicion - 2);\n        }\n    }\n }"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/java/JimsimroDev.java",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\npublic class JimsimroDev {\n  private static final String DIV_LINE = \"::::::::\";\n\n  public static void recursiCount(int number) {\n    if (number < 0) {\n      return;\n    }\n    System.out.println(number);\n    recursiCount(number - 1);\n  }\n\n  public static Long factorialRecursiv(Long n) {\n    if (n < 1L) {\n      return 1L;\n    }\n    return n * factorialRecursiv(n - 1);\n  }\n\n  public static int fibonacciRecursive(int number) {\n    if (number < 0) {\n      return 0;\n    } else if (number == 1) {\n      return 1;\n    } else if (number == 2) {\n      return 1;\n    }\n    return fibonacciRecursive(number - 1) + fibonacciRecursive(number - 2);\n  }\n\n  public static void main(String[] args) {\n    System.out.println(DIV_LINE);\n    recursiCount(100);\n    for (Long i = 1L; i <= 9; i++) {\n      System.out.printf(\"%d! = %d\\n\", i, factorialRecursiv(i));\n    }\n    System.out.println(DIV_LINE);\n    System.out.println(factorialRecursiv(0L));\n    System.out.println(DIV_LINE);\n    int x = 10;\n    for (int n = 0; n <= x; n++) {\n      System.out.print(fibonacciRecursive(n));\n      System.out.print(\" \");\n    }\n    System.out.println();\n    System.out.println(DIV_LINE);\n    System.out.println(fibonacciRecursive(0));\n    System.out.println(fibonacciRecursive(1));\n    System.out.println(fibonacciRecursive(2));\n    System.out.println(fibonacciRecursive(3));\n    System.out.println(fibonacciRecursive(10));\n  }\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/java/Josegs95.java",
    "content": "public class Josegs95 {\n    public static void main(String[] args) {\n        //Método recursivo de 100 a 0\n        printNumDesc(100);\n\n        //Reto\n        System.out.println(\"\\n\");\n        retoFinal();\n    }\n\n    public static void printNumDesc(int n){\n        System.out.println(n);\n        if (n != 0)\n            printNumDesc(n - 1);\n        else\n            return;\n    }\n\n    public static void retoFinal(){\n        int a = 5;\n        System.out.println(\"El factorial de 5 es: \" + calcFactorial(a)); //Out: 'El factorial de 5 es: 120'\n\n        int b = 7;\n        System.out.println(\"El número en la posición \" + b + \" en la sucesión de Fibonacci es : \" + calcNumFibFromPos(b));\n            //Out: El número en la posición 7 en la sucesión de Fibonacci es : 13\n\n    }\n\n    private static int calcFactorial(int n){\n        if (n != 0)\n            return n * calcFactorial(n - 1);\n        else\n            return 1;\n    }\n\n    private static int calcNumFibFromPos(int pos){\n        if (pos < 2)\n            return pos;\n\n        return calcNumFibFromPos(pos - 1) + calcNumFibFromPos(pos - 2);\n    }\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/java/Ldre3.java",
    "content": "public class Ldre3 {\n    public static void main(String[] args) {\n        /*\n         * EJERCICIO:\n         * Entiende el concepto de recursividad creando una función recursiva que imprima\n         * números del 100 al 0.\n         */\n         printRecursive(100);\n         /* DIFICULTAD EXTRA (opcional):\n         * Utiliza el concepto de recursividad para:\n         * - Calcular el factorial de un número concreto (la función recibe ese número).\n         * - Calcular el valor de un elemento concreto (según su posición) en la\n         *   sucesión de Fibonacci (la función recibe la posición).\n         */\n        System.out.println(factorial(7));\n        for(int i = 1; i < 50; i++) {\n            System.out.println(nNumeroFibo(i));\n        }\n\n    }\n    public static void printRecursive(int n){\n        if (n<0)return;\n        System.out.println(n);\n        printRecursive(n-1);\n    }\n    public static int factorial(int n){\n        return n==1?1:n*factorial(n-1);\n    }\n\n    public static int nNumeroFibo (int n){\n        return n==1?0:n==2?1:nNumeroFibo(n-2)+nNumeroFibo(n-1);\n    }\n}"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/java/Qv1ko.java",
    "content": "public class Qv1ko {\n\n    public static void main(String[] args) {\n        \n        func(0);\n\n        System.out.println(\"---\");\n\n        System.out.println(fact(5));\n\n        System.out.println(\"---\");\n\n        System.out.println(fib(5));\n\n    }\n\n    private static void func(int number) {\n\n        System.out.println(number);\n\n        number++;\n\n        if (number <= 100) {\n            func(number);\n        }\n\n    }\n\n    private static int fact(int number) {\n        if (number <= 0) {\n            return 0;\n        } else if (number == 1) {\n            return 1;\n        } else {\n            return number * fact(number - 1);\n        }\n    }\n\n    private static int fib(int pos) {\n        if (pos <= 1) {\n            return 0;\n        } else if (pos == 2 || pos == 3) {\n            return 1;\n        } else {\n            return fib(pos - 1) + fib(pos - 2);\n        }\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/java/RodrigoGit87.java",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la\n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\nimport java.util.InputMismatchException;\n\npublic class RodrigoGit87 {\n    public static void countdown(int number){\n        if (number >= 0){\n        System.out.println(number);\n        countdown(number -1);\n        }\n    }\n\n    //FACTOrial\n    public static int factorial (int numero){\n\n        if (numero < 0) {\n            System.out.println(\" Número establecido no válido, valor establecido a:  1 \");\n            return 1;\n        }else if( numero == 0 || numero == 1){\n            return 1;\n        } else return numero * factorial(numero -1);\n    }\n\n    // Fibbonacci\n    public static int fibbo (int posicion){\n        if (posicion <= 0) {\n            System.out.println(\"La posicion debe ser mayor q 0\");\n            return 0;\n        } else if( posicion == 1 || posicion == 2)\n            return posicion -1;\n        else return fibbo(posicion-1) + fibbo(posicion-2);\n    }\n    \n\n    public static void main (String[] args){\n        countdown(10);\n        System.out.println(\"\");\n\n        int llamadaMetodo = factorial( 6) ;\n        System.out.println(\" REsultado de factorizar: \" + llamadaMetodo + \"\\n\");\n\n        int llamadaFibbo = fibbo(8);\n        System.out.println(\"Fibbo: \" + llamadaFibbo);\n    }\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/java/RoniPG.java",
    "content": "// @Roni\n\npublic class RECURSIVIDAD_06 {\n\t// Variables Globales\n\tstatic int count = 100; \n\tstatic int result = 1;\n\tstatic int resultado=0;\n\tstatic int resultado2=1;\n\n\tpublic static void imprimirNumeros() {\n\n\t\tif ((count > -1) && (count < 101)) {\n\t\t\tSystem.out.println(count + \",\");\n\t\t\tcount--;\n\t\t\timprimirNumeros();\n\t\t} else {\n\t\t\tcount = 0;\n\t\t}\n\n\t}\n\n\tpublic static void main(String[] args) {\n\t\t/*\n\t\t * EJERCICIO:\n     * Entiende el concepto de recursividad creando una función recursiva que imprima\n     * números del 100 al 0.\n\t\t */\n\t\timprimirNumeros();\n\t\t/*\n     * DIFICULTAD EXTRA (opcional):\n     * Utiliza el concepto de recursividad para:\n     * - Calcular el factorial de un número concreto (la función recibe ese número).\n     * - Calcular el valor de un elemento concreto (según su posición) en la \n     *   sucesión de Fibonacci (la función recibe la posición).\n\t\t */\n\t\tfibonacci(6); // 0 1 1 2 3 5 8\n\t\tfactorial(6);\n\t\n\t\t\n\t}\n\n\tpublic static int factorial(int a) {\n\n\t\tif (count < (a - 1)) {\n\t\t\tresult = result * (count + 2);\n\t\t\tcount++;\n\t\t\tfactorial(a);\n\t\t} else {\n\t\t\tSystem.out.print(a + \"! = \" + result);\n\t\t\tcount = 0;\n\t\t\treturn result;\n\t\t}\n\t\treturn 0;\n\t}\n\n\tpublic static int fibonacci(int a) {\n\n\t\tif (a == 1) {\n\t\t\tSystem.out.println(0);\n\t\t\treturn 0;\n\t\t} else if ((a == 2)||(a == 3)) {\n\t\t\tSystem.out.println(1);\n\t\t\treturn 0;\n\t\t} else if (count +2 < a) {\n\t\t\tint x;\n\t\t\tx=resultado2+resultado;\n\t\t\tresultado=resultado2;\n\t\t\tresultado2=x;\n\t\t\tcount++;\n\t\t\tfibonacci(a);\n\t\t} else if (count + 2 >= a) {\n\t\t\tSystem.out.println(resultado2);\n\t\t\tcount = 0;\n\t\t\treturn 0;\n\t\t}\n\t\treturn 0;\n\n\t}\n\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/java/TofeDev.java",
    "content": "import java.util.Scanner;\n\npublic class TofeDev {\n    /* EJERCICIO:\n    * Entiende el concepto de recursividad creando una función recursiva que imprima\n    * números del 100 al 0.\n    *\n    * DIFICULTAD EXTRA (opcional):\n    * Utiliza el concepto de recursividad para:\n    * - Calcular el factorial de un número concreto (la función recibe ese número).\n    * - Calcular el valor de un elemento concreto (según su posición) en la \n    *   sucesión de Fibonacci (la función recibe la posición).\n    */\n    public static void main(String[] args) {\n        //Sacar números del 100 al 0\n        for (int i = 100; i >= 0; i--) {\n            System.out.println(i);\n        }\n\n        //Sacar factorial de un número concreto\n        Scanner scanner = new Scanner(System.in);\n        int num1 = scanner.nextInt();\n        factorial(num1);\n\n        //Sucesión de Fibonacci\n        int num2 = scanner.nextInt();\n        fibonacci(num2);\n\n        scanner.close();\n    }\n\n    public static void factorial(int numero) {\n        int resultado;\n        int temp = numero;\n        numero--;\n        resultado = temp * numero;\n        System.out.println(numero);\n        System.out.println(resultado);\n        for (int i = numero; i > 1; i--) {\n            temp = i;\n            temp--;\n            System.out.println(temp);\n            resultado *= temp;\n            System.out.println(resultado);\n        }\n    }  \n\n    public static void fibonacci(int numero) {\n        int a = 0;\n        int b = 1;\n        int temp;\n        for (int i = numero; i > 0; i--) {\n            temp = a + b;\n            b = a;\n            a = temp;\n            System.out.println(temp);\n        }\n    }\n}\n\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/java/Worlion.java",
    "content": "\npublic class Worlion {\n\n    public static void main(String[] args) {\n        new Worlion().run();\n    }\n\n    public void run(){\n    \n        // Ejercicio de base: imprimir los numeros del 100 al 0\n        printTo(100);\n\n        extra();\n    }\n\n    /**\n     * Imprime los numeros desde number (>= 0) hasta 0 con recursividad\n     * @param number The first number of secuence\n     */\n    private void printTo(int number) {\n        if(number < 0) {\n            System.err.println(\"Error: not negative numbers allowed.\");\n            return;\n        }\n        System.out.println(number);\n        if (number > 0){\n            printTo(number-1);\n        }\n    }\n    \n// DIFICULTAD EXTRA (opcional): Factorial y Fibonacci\n\nprivate void extra() {\n    System.out.println(\" \\n ---- 🌩 DIFICULTAD EXTRA 🌩 ----\\n\");\n\n    System.out.println(\" Factorial de 10 = \"+factorial(10));\n    System.out.println(\" Fibonacci de 10 = \"+fibonacci(10));\n}\n\n/**\n * Calcula el factorial del número recibido como parametro\n * @param num numero cuyo factorial se va a calcular (>=0)\n * @return !num\n */\nprivate int factorial(int num){\n    if(num <0) {\n        System.err.println(\"ERROR: No se puede calcular el factorial de un número negativo!\");\n        return -1;\n    } else if( num == 0) {\n        return 1;\n    }\n    else {\n        return num*factorial(num-1);\n    }\n}\n\n/**\n * \n * @param pos Posición en la serie de Fibonacci\n * @return El valor de esa posición en la serie\n */\nprivate int fibonacci(int pos) {\n    if(pos <= 0) {\n        System.err.println(\"ERROR: La posición en cualquier serie debe ser positiva.\");\n        return -1;\n    }\n    if(pos == 1){\n        return 0;\n    }\n    if(pos == 2){\n        return 1;\n    }\n    return fibonacci(pos-2) + fibonacci(pos-1);\n}\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/java/alexdevrep.java",
    "content": "package _06_Recursividad;\n\npublic class _06_Recursividad {\n    /*\n     * EJERCICIO:\n     * Entiende el concepto de recursividad creando una función recursiva que imprima\n     * números del 100 al 0.\n     *\n     * DIFICULTAD EXTRA (opcional):\n     * Utiliza el concepto de recursividad para:\n     * - Calcular el factorial de un número concreto (la función recibe ese número).\n     * - Calcular el valor de un elemento concreto (según su posición) en la\n     *   sucesión de Fibonacci (la función recibe la posición).\n     */\n    static int numero = 0;\n    static void recursividad(int numero){\n        if (numero<=100){\n            System.out.println(numero);\n        }\n        else{\n            return ;\n        }\n        recursividad(numero+1);\n\n    }\n\n    //Dificultad Extra\n    static int numero2 = 9; //No pongo la opción de ingresar un número porque me da problemas el IDE\n    static int factorial(int numero2){\n        if(numero2==0){\n            return 1;\n        }\n        else{\n            return numero2 * factorial( numero2 - 1);\n        }\n\n    }\n\n    static  int posicion = 4; //No pongo la opción de ingresar un número porque me da problemas el IDE\n    static int fibonacci(int posicion){\n        if(posicion<=1){\n            return posicion;\n\n        }\n        else{\n            return fibonacci(posicion-2)+fibonacci(posicion-1);\n        }\n    }\n\n    public static void main (String[] args){\n        recursividad(numero);\n         int resultado =factorial(numero2);\n         System.out.println(\"El numero 9 factorial es: \"+resultado);\n         int resultado2 = fibonacci(posicion);\n         System.out.println(\"El resultado del valor que ocupa la posición 4 en la sucesión de \" +\n                 \"fibonacci es: \"+ resultado2);\n\n\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/java/asjordi.java",
    "content": "public class Main {\n\n    public static void main(String[] args) {\n\n        printNumber(100);\n\n        System.out.println(\"Factorial de 5: \" + factorial(5));\n\n    }\n\n\n    /**\n     * Función recursiva que imprime los números desde n hasta 0\n     * @param n\n     */\n    public static void printNumber(int n) {\n        if (n >= 0) {\n            System.out.println(n);\n            printNumber(n - 1);\n        }\n    }\n\n    /**\n     * Función recursiva que calcula el factorial de un número\n     * @param n número del que se quiere calcular el factorial\n     * @return factorial de n\n     */\n    public static int factorial(int n) {\n        if (n == 0) return 1;\n        else return n * factorial(n - 1);\n    }\n\n    /**\n     * Función recursiva que calcula el n-ésimo número de la serie de Fibonacci\n     * @param n posición del número en la serie\n     * @return n-ésimo número de la serie de Fibonacci\n     */\n    public static int fibonacci(int n) {\n        if (n <= 1) return n;\n        else return fibonacci(n - 1) + fibonacci(n - 2);\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/java/cesar-ch.java",
    "content": "public class Main {\n\n    // #06 RECURSIVIDAD \n\n    public static void imprimirNumeros(int contador) {\n        if (contador < 0) {\n            return;\n        } else {\n            System.out.println(contador);\n            contador--;\n            imprimirNumeros(contador);\n        }\n    }\n\n    public static void main(String[] args) {\n        imprimirNumeros(100);\n        \n        System.out.println(factorial(5)); // 120\n\n        System.out.println(fibonacci(8)); // 13\n    }\n\n     // Dificultad Extra\n\n    public static int factorial(int numero) {\n        if (numero == 0) {\n            return 1;\n        } else {\n            return numero * factorial(numero - 1);\n        }\n    }\n\n    public static int fibonacci(int numero) {\n        if (numero < 1) {\n            System.out.println(\"El número debe ser mayor o igual a 1\");\n            return -1;\n        } else if (numero == 1) {\n            return 0;\n        } else if (numero == 2) {\n            return 1;\n        } else {\n            return fibonacci(numero - 1) + fibonacci(numero - 2);\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/java/chartypes.java",
    "content": "public class chartypes {\n    public static void main(String[] args) {\n        iterator(100, 0);\n        System.out.println(\"\\nExecrice:\");\n        System.out.println(factorial(6));\n        System.out.println(getFromFibonacci(8));\n\n    }\n\n    static int iterator(int start, int stop) {\n        System.out.print(start + \" \");\n        if (start == stop)\n            return stop;\n        return iterator(start - 1, stop);\n    }\n\n    static int factorial(int number) {\n        if (number == 1)\n            return 1;\n        return number * factorial(number - 1);\n    }\n\n    static int getFromFibonacci(int position) {\n        if (position <= 0 || position == 1)\n            return 0;\n        else if (position == 2)\n            return 1;\n        return getFromFibonacci(position - 1) + getFromFibonacci(position - 2);\n\n    }\n\n}"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/java/danhingar.java",
    "content": "public class danhingar {\n\n    public static void main(String[] args) {\n        printRecursivo(100);\n        System.out.println(factorialRecursivo(5));\n        System.out.println(fibonacciRecursivo(10));\n    }\n\n    private static void printRecursivo(int number) {\n        if (number >= 0) {\n            System.out.println(number);\n            printRecursivo(--number);\n        }\n    }\n\n    // EXTRA\n    private static int factorialRecursivo(int number) {\n        if (number == 0) {\n            return 1;\n        } else if (number < 0) {\n            System.out.println(\"No puede ser negativo\");\n        }\n        return number * factorialRecursivo(--number);\n    }\n\n    private static int fibonacciRecursivo(int posicion) {\n        if (posicion <= 0) {\n            return 0;\n        }else if(posicion ==1){\n            return 0;\n        }else if(posicion ==2){\n            return 1;\n        }\n        return fibonacciRecursivo(posicion - 1) + fibonacciRecursivo(posicion - 2);\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/java/deathwing696.java",
    "content": "/*\n * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license\n * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Main.java to edit this template\n */\n\n/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una funcin recursiva que imprima\n * nmeros del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un nmero concreto (la funcin recibe ese nmero).\n * - Calcular el valor de un elemento concreto (segn su posicin) en la \n *   sucesin de Fibonacci (la funcin recibe la posicin).\n */\n\n/**\n *\n * @author death\n */\npublic class deathwing696 {\n\n    public static void main(String[] args) \n    {        \n        System.out.println(CuentaRecursivo(100));\n        \n        var num = 3;\n        \n        System.out.println(\"El factorial de \" + num + \"! es \" + factorial(num));\n        \n        var pos = 14;\n        \n        System.out.println(\"El valor de la posicin \" + pos + \" en la serie de fibonacci es \" + fibonacci(pos));\n    }\n    \n    static private int CuentaRecursivo(int num)\n    {\n        if (num == 0)\n        {\n            return 0;            \n        }            \n        else\n        {\n            System.out.println(num);\n            \n            return CuentaRecursivo(num - 1);\n        }\n    }\n    \n    static private int factorial(int num)\n    {\n        if (num == 1)\n            return 1;\n        else\n            return num * factorial(num - 1);\n    }\n    \n    static private int fibonacci(int pos)\n    {\n        return switch (pos) \n        {\n            case 0 -> 0;\n            case 1 -> 1;\n            default -> fibonacci(pos - 1) + fibonacci(pos - 2);\n        };\n    }\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/java/derobpe.java",
    "content": "\n/**\n * derobpe.java\n * \n * Descripción breve de la clase o el programa.\n * \n * @autor derobpe\n * @version 1.0\n * @fecha 07/02/2024\n *\n *        EJERCICIO:\n *        Entiende el concepto de recursividad creando una función recursiva que\n *        imprima números del 100 al 0.\n *\n *        DIFICULTAD EXTRA (opcional):\n *        Utiliza el concepto de recursividad para:\n *        - Calcular el factorial de un número concreto (la función recibe ese\n *        número).\n *        - Calcular el valor de un elemento concreto (según su posición) en la\n *        sucesión de Fibonacci (la función recibe la posición).\n */\n\nimport java.util.Scanner;\n\npublic class derobpe {\n    public static void main(String[] args) {\n        // Ejercicio Imprimir Recursivamente\n        imprimirRecursivamenteNNumeros(100);\n\n        // Extra 1: Factorial\n        Scanner scanner = new Scanner(System.in);\n        System.out.println(\"Introduce un número positivo para calcular su factorial: \");\n        int num = scanner.nextInt();\n        System.out.println(\"El factorial de \" + num + \"! es \" + factorial(num));\n\n        // Extra 2: Fibonacci\n        System.out.println(\"Introduce un número positivo para calcular su Fibonacci: \");\n        int pos = scanner.nextInt();\n        System.out.println(\"El valor de la posición \" + pos + \" en la serie de fibonacci es \" + fibonacci(pos));\n        scanner.close();\n\n    }\n\n    public static void imprimirRecursivamenteNNumeros(int n) {\n        // No utilizo for pues sería una aproximación iterativa.\n        // Un método es recursivo cuando se llama a sí mismo para resolver una versión\n        // más pequeña del problema original, hasta que alcanza un caso base que puede\n        // resolver sin necesidad de más llamadas recursivas.\n\n        if (n == 0) {\n            return;\n        } else {\n            System.out.println(n);\n            imprimirRecursivamenteNNumeros(n - 1);\n        }\n        for (int i = n; i >= 0; i--) {\n            System.out.print(i + \",\");\n            if (i == 0) {\n                System.out.println(i + \".\");\n            }\n        }\n    }\n\n    public static int factorial(int n) {\n        // El factorial de un número entero no negativo n, denotado como n!, es el\n        // producto de todos los números enteros positivos desde n hasta 1.\n        // - Para n = 0, el factorial es 1, es decir, 0! = 1.\n        // - Para n > 0, el factorial de n es n! = n × (n-1) × (n-2) × ... × 2 × 1.\n\n        if (n == 0) {\n            return 1;\n        } else {\n            return n * factorial(n - 1);\n        }\n    }\n\n    public static int fibonacci(int n) {\n        // La sucesión de Fibonacci es una secuencia de números en la que cada número es\n        // la suma de los dos números precedentes, empezando por 0 y 1.\n        // La definición formal de la sucesión es la siguiente:\n        // - F(0) = 0\n        // - F(1) = 1\n        // - Para todo n > 1, se cumple que F(n) = F(n-1) + F(n-2)\n\n        if (n <= 1) {\n            return n;\n        } else {\n            return fibonacci(n - 1) + fibonacci(n - 2);\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/java/estuardodev.java",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\n\nprivate class Estuardodev{\n    public static void main(String[] args){\n        numeros(100);\n        System.out.println(factorial(5));\n        System.out.println(fibonacci(5));\n    }\n\n    static void numeros(int numero){\n        if (numero >= 0){\n            System.out.println(numero);\n            numeros(numeros((numero - 1)));\n        }\n    }\n\n    static int factorial(int numero){\n        if (numero < 0){\n            return 1;\n        } else if (numero == 0){\n            return 1;\n        } else{\n            return numero * factorial(numero - 1);\n        }\n    }\n\n    static int fibonacci(int posicion){\n        if (posicion <= 0){\n            return 0;\n        } else if (posicion == 1){\n            return 0;\n        } else if (posicion == 2){\n            return 1;\n        } else{\n            return fibonacci(posicion - 1) + fibonacci(posicion - 2);\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/java/eulogioep.java",
    "content": "public class eulogioep {\n\n    public static void main(String[] args) {\n        // Llamada a la función para imprimir números del 100 al 0\n        System.out.println(\"Números del 100 al 0:\");\n        imprimirNumeros(100);\n        \n        // Prueba del cálculo de factorial\n        int numeroFactorial = 5;\n        System.out.println(\"\\nFactorial de \" + numeroFactorial + \": \" + factorial(numeroFactorial));\n        \n        // Prueba de la sucesión de Fibonacci\n        int posicionFibonacci = 7;\n        System.out.println(\"Elemento en la posición \" + posicionFibonacci + \" de Fibonacci: \" + fibonacci(posicionFibonacci));\n    }\n    \n    /**\n     * Función recursiva para imprimir números del 100 al 0.\n     * @param numero El número actual a imprimir.\n     */\n    public static void imprimirNumeros(int numero) {\n        // Caso base: si el número es menor que 0, terminamos la recursión\n        if (numero < 0) {\n            return;\n        }\n        \n        // Imprimimos el número actual\n        System.out.print(numero + \" \");\n        \n        // Llamada recursiva con el número decrementado\n        imprimirNumeros(numero - 1);\n    }\n    \n    /**\n     * Función recursiva para calcular el factorial de un número.\n     * @param n El número del cual calcular el factorial.\n     * @return El factorial del número.\n     */\n    public static int factorial(int n) {\n        // Casos base: factorial de 0 y 1 es 1\n        if (n == 0 || n == 1) {\n            return 1;\n        }\n        \n        // Llamada recursiva: n * factorial(n-1)\n        return n * factorial(n - 1);\n    }\n    \n    /**\n     * Función recursiva para calcular el valor de un elemento en la sucesión de Fibonacci.\n     * @param posicion La posición del elemento en la sucesión de Fibonacci.\n     * @return El valor del elemento en la posición dada.\n     */\n    public static int fibonacci(int posicion) {\n        // Casos base: posiciones 0 y 1 de Fibonacci son 0 y 1 respectivamente\n        if (posicion == 0) {\n            return 0;\n        }\n        if (posicion == 1) {\n            return 1;\n        }\n        \n        // Llamada recursiva: suma de los dos elementos anteriores\n        return fibonacci(posicion - 1) + fibonacci(posicion - 2);\n    }\n}"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/java/frangarmez21.java",
    "content": "public class frangarmez21 {\n\n    public static void main(String[] args) {\n\n        System.out.println(\"##Ejercicio de recursividad##\");\n        /*\n         * EJERCICIO:\n         * Entiende el concepto de recursividad creando una función recursiva que imprima\n         * números del 100 al 0.\n         */\n        System.out.println(\"##Creando función recursiva que imprime números del 100 al 0.##\");\n        System.out.println();\n\n        int initialNumber = 100;\n        System.out.println(\"Llamamos al método recursivo:\");\n        recursiveCounting(initialNumber);\n        System.out.println(\"Salimos del método recursivo.\");\n\n        System.out.println();\n        System.out.println(\"##Dificultad Extra##\");\n        System.out.println();\n\n        /* * DIFICULTAD EXTRA (opcional):\n         * Utiliza el concepto de recursividad para:\n         * - Calcular el factorial de un número concreto (la función recibe ese número).\n         * - Calcular el valor de un elemento concreto (según su posición) en la\n         *   sucesión de Fibonacci (la función recibe la posición).\n         */\n\n        System.out.println(\"Calcular el factorial de un número concreto:\");\n        System.out.println();\n\n        int number = 10;\n        System.out.println(\"Llamamos al método calcular factorial con el número: \" + number);\n        System.out.println();\n        int factorial = factorialCalculation(number, number);\n        if ((factorial >= 0)) {\n            System.out.println(\"El resultado es: \" + factorial);\n        } else {\n            System.out.println(\"No se ha podido calcular, debe ser un numero natural\");\n        }\n\n        System.out.println();\n        System.out.println(\"Calcular el valor de un elemento concreto en la sucesión de Fibonacci:\");\n        System.out.println();\n\n        int position = 6;\n        int initNumber = 1;\n        int prevNumber = 0;\n        System.out.println(\"Llamamos al método obtener valor en Fibonacci en la posición: \" + position);\n        System.out.println();\n        int fibonacciResult = getFibonacciValue(position - 1, initNumber, prevNumber);\n        System.out.println(\"El valor en la posición \" + position + \" de la sucesión de Fibonacci es: \" + fibonacciResult);\n    }\n\n    private static int getFibonacciValue(int position, int initNumber, int prevNumber) {\n        int result = initNumber + prevNumber;\n        position--;\n        if (position > 0) {\n            result = getFibonacciValue(position, result, initNumber);\n        }\n        return result;\n    }\n\n    private static int factorialCalculation(int number, int initMultiplier) {\n        int multiplier = initMultiplier - 1;\n        int result = number * multiplier;\n\n        if (multiplier == 0) {\n            result = 1;\n            return result;\n        } else if (multiplier == 1) {\n            return result;\n        } else if (multiplier > 1) {\n            return factorialCalculation(result, multiplier);\n        } else {\n            result = -1;\n            return result;\n        }\n    }\n\n    private static void recursiveCounting(int initialNumber) {\n        System.out.println(initialNumber);\n        if (initialNumber > 0) {\n            recursiveCounting(initialNumber - 1);\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/java/h4ckxel.java",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\n public class h4ckxel {\n    public static void main(String[] args) {\n        // Llamada a la función que imprime números del 100 al 0\n        imprimirNumeros(100);\n\n        // Llamada a la función que calcula el factorial de un número concreto\n        System.out.println(factorial(5));\n\n        // Llamada a la función que calcula el valor de un elemento concreto en la sucesión de Fibonacci\n        System.out.println(fibonacci(10));\n    }\n\n    public static void imprimirNumeros(int numero) {\n        if (numero >= 0) {\n            System.out.println(numero);\n            imprimirNumeros(numero - 1);\n        }\n    }\n\n    // Calcula el factorial de un número concreto\n    public static int factorial(int numero){\n        if (numero == 0) {\n            return 1;\n        } else {\n            return numero * factorial(numero - 1);\n        }\n    }\n\n    // Calcula el valor de un elemento concreto en la sucesión de Fibonacci\n    public static int fibonacci(int posicion){\n        if (posicion == 0 || posicion == 1) {\n            return posicion;\n        } else {\n            return fibonacci(posicion - 1) + fibonacci(posicion - 2);\n        }\n    }\n }"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/java/hernanR.java",
    "content": "public class hernanR {\n    public static void main(String[] args) {\n        recursividad(100);\n        System.out.println(factorial(5));\n    }\n\n    public static void recursividad(int num) {\n        if (num >= 0) {\n            System.out.println(num);\n            recursividad(num - 1);\n        }\n    }\n\n    public static int factorial(int num) {\n        if (num == 0) {\n            return 1;\n        } else {\n            return num * factorial(num - 1);\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/java/inmortalnight.java",
    "content": "// 06 - Recursividad\n\npublic class inmortalnight {\n    public static void main(String[] args){\n        print();\n        System.out.println(factorial(3));\n        System.out.println(fibonacci(30));\n    }\n    //Función de recursividad que imprime los números 100-0\n    public static void print(){\n        for(int i=100; i>=0; i--){      \n            System.out.println(i);\n        }\n    }\n    //EXTRA 1: Calcular factorial\n    public static int factorial(int number){\n        if (number == 0) {\n            return 1;\n        } else {\n            return number * factorial(number - 1);\n        }\n    }\n    //EXTRA 2: Calcular el valor según la posición introducida en la sucesión de Fibonacci\n    public static int fibonacci(int position){\n        if(position < 2){\n            return position;\n        } else {\n            return fibonacci(position - 1) + fibonacci(position - 2);\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/java/jesusway69.java",
    "content": "package ejercicio06;\n\nimport java.util.Scanner;\n\n/**\n * EJERCICIO: Entiende el concepto de recursividad creando una función recursiva\n * que imprima números del 100 al 0.\n */\npublic class JesusWay69 {\n\n    private static void countdown(int num) {//Definimos la función y le pasamos el número 100 en la primera ejecución\n        \n        if (num >= 0) { //Establecemos la condición de parada en 0\n            System.out.print(num + \" \"); //Imprimimos cada número horizontalmente y separado en cada ejecución de la función\n            \n            if (num % 10 == 0 && num != 100) { //Establecemos un salto de línea cada 10 números para hacerlo más visual (opcional)\n                System.out.println(\" \"); //Salto de línea\n            }\n            num--; // Al terminar las condiciones para seguir iterando e imprimir le restamos 1 al valor del parámetro de la función...\n            countdown(num); //...y hacemos la llamada recursiva enviando el nuevo valor del parámetro a la función\n        }\n\n    }\n\n /*\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n    public static int fibonacci(int n) {\n        n--;\n        if (n <= 0) {\n            return 0;\n        } else if (n == 1) {\n            return 1;\n        } else {\n            return fibonacci(n) + fibonacci(n - 1);\n        }\n    }\n\n    public static int factorial(int n) {\n        if (n == 0) {\n            return 1;\n        } else {\n            return n * factorial(n - 1);\n        }\n    }\n\n    public static void main(String[] args) {\n        countdown(100);\n        Scanner sc = new Scanner(System.in);\n        System.out.print(\"\"\"\n                           \\n1- Calcular factorial\n                           2- Calcular posici\\u00f3n en la secuencia Fibonacci\n                           3- Salir\n                           Elija una opci\\u00f3n: \"\"\");\n        String choose = sc.next();\n\n        if (choose.matches(\"[1-3]\")) {\n            int option = Integer.parseInt(choose);\n            if (option == 1) {\n                System.out.println(\"\\nIntroduzca un número para calcular su factorial: \");\n                String num = sc.next();\n                if (num.matches(\"[1-9]+\") == true) {\n                    int number = Integer.parseInt(num);\n                    System.out.println(\"El factorial de \" + number + \" es: \" + factorial(number));\n                } else {\n                    System.out.println(\"Sólo se pueden introducir números enteros\");\n                }\n\n            } else if (option == 2) {\n                System.out.println(\"\\nIntroduzca un número para calcular su posición en la secuencia Fibonacci:\");\n                String num = sc.next();\n                if (num.matches(\"[1-9]+\")) {\n                    int number = Integer.parseInt(num);\n                    System.out.println(\"La posición \" + number + \" de la secuencia Fibonacci tiene el valor \" + fibonacci(number));\n                } else {\n                    System.out.println(\"Sólo se pueden introducir números enteros\");\n                }\n\n            } else if (option == 3) {\n                System.out.println(\"Fin del programa\");\n\n            }\n\n        } else {\n            System.out.println(\"Sólo se pueden introducir números enteros del 1 al 3\");\n\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/java/julian98789.java",
    "content": "\npublic class reto_6 {\n    \n    public static void main(String[] args) {\n\n        numRecursivo(0);\n        System.out.println(\"\\n **********************\");\n        int factorial = factorial(5);\n\n        System.out.println(\"Factorial: \" + factorial +\"\\n\");\n\n        int Fibonacci = Fibonacci(5);\n\n        System.out.println(\"El numero es: \" + Fibonacci);\n    }\n\n    public static void numRecursivo( int n){\n    \n        if (n > 100) {\n            return;\n        }\n        System.out.println(n);\n        numRecursivo(n+1);\n\n \n    }\n    public static int factorial( int n){\n\n        if (n == 0 || n == 1) {\n            return 1;\n        }\n        return n * factorial(n - 1);\n    }\n\n    public static int Fibonacci ( int n){\n\n        if (n <= 1) {\n            return n;\n        }else{\n            return (Fibonacci( n - 1) + Fibonacci( n- 2));\n        }\n    }  \n}\n\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/java/kleyner098.java",
    "content": "public class kleyner098 {\n    /*\n     * EJERCICIO:\n     * Entiende el concepto de recursividad creando una función recursiva que\n     * imprima números del 100 al 0.\n     *\n     * DIFICULTAD EXTRA (opcional):\n     * Utiliza el concepto de recursividad para:\n     * - Calcular el factorial de un número concreto (la función recibe ese número).\n     * - Calcular el valor de un elemento concreto (según su posición) en la\n     * sucesión de Fibonacci (la función recibe la posición).\n     */\n\n    public static void main(String[] args) {\n        recursividad(0);\n\n        int num = 5;\n        System.out.printf(\"\\n%1$d! = %2$d\", num, factorial(num));\n        int posicion = 7;\n        System.out.printf(\"\\nEl elemento en la posición %1$d es %2$d\", posicion, fibonacci(posicion));\n    }\n\n    // Método recursivo que impreme los valores de 100 hasta n\n    public static void recursividad(int num) {\n        // caso base\n        if (num >= 100) {\n            System.out.print(num);\n        } else {\n            // Llamada recursiva\n            recursividad(num + 1);\n            System.out.print(\" \" + num);\n        }\n    }\n\n    // Método que calcula el factorial\n    public static int factorial(int num) {\n        if (num == 0) {\n            return 1;\n        } else {\n            return factorial(num - 1) * num;\n        }\n    }\n\n    // Método que devuelve el elemento en la posición n de Fibonacci\n    public static int fibonacci(int posicion) {\n        if (posicion <= 1) {\n            return 0;\n        } else if (posicion == 2) {\n            return 1;\n        } else {\n            return fibonacci(posicion - 1) + fibonacci(posicion - 2);\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/java/lautarorisso.java",
    "content": "public class LogicaJava06 {\n    \n    public static void main(String[] args) {\n        // 1.\n        cuentaAtras(10);\n        \n        // EXTRA\n        factorial(3);\n        \n        fibonacci(3);\n    }\n    \n    // 1.\n    public static int cuentaAtras(int num) {\n        if (num>=0) {\n            System.out.println(num);\n            cuentaAtras(num - 1);\n        }\n        return num;\n    }\n    \n    // EXTRA    \n    public static int factorial(int num) {\n        if (num<0) {\n            return 0;\n        } else if (num==0 || num==1) {\n            return 1;\n        } else {\n            return num * factorial(num-1);\n        }\n    }\n    \n    // en fibonacci hablamos de posiciones\n    public static int fibonacci(int num) {\n        if (num<=1) {\n            return 0;\n        } else if (num==2) {\n            return 1;\n        } else {\n            return fibonacci(num-1) + fibonacci(num-2);\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/java/martinbohorquez.java",
    "content": "/**\n * #06 RECURSIVIDAD\n *\n * @author martinbohorquez\n */\npublic class martinbohorquez {\n    private static int num;\n    private static int counter;\n\n    private static void recursividadDesc(int inf, int sup) {\n        if (inf <= sup) {\n            System.out.printf(\"%d. %d%n\", ++counter, sup--);\n            recursividadDesc(inf, sup);\n        }\n    }\n\n    private static void imprimirRecursividadDesc(int inf, int sup) {\n        System.out.printf(\"Inicio de iteración recursividad de números del %d al %d:%n\", inf, sup);\n        recursividadDesc(inf, sup);\n        System.out.printf(\"Fin de iteración recursividad de números del %d al %d!%n\", inf, sup);\n        counter = 0;\n    }\n\n    private static Long factorial(int num) {\n        if (num == 0) return 1L;\n        return num * factorial(--num);\n    }\n\n    private static void imprimirFactorial(int num) {\n        if (num < 0) System.out.printf(\"El número %d es negativo. Debe ingresar números enteros positivos!%n\", num);\n        else System.out.printf(\"El factorial de %d es: %d%n\", num, factorial(num));\n    }\n\n    private static Long fibonacci(int num) {\n        if (num == 1) return 0L;\n        else if (num == 2) return 1L;\n        return fibonacci(--num) + fibonacci(--num);\n    }\n\n    private static void imprimirFibonacci(int num) {\n        if (num <= 0) System.out.printf(\"El número %d debe ser entero positivo!%n\", num);\n        else System.out.printf(\"El valor del elemento %d° en la serie de Fibonacci es: %d%n\", num, fibonacci(num));\n    }\n\n    private static int solveHanoi(int n, char source, char auxiliary, char destination) {\n        if (n == 1) {\n            System.out.println(\"Move disk 1 from \" + source + \" to \" + destination);\n            return ++counter;\n        }\n        solveHanoi(n - 1, source, destination, auxiliary);\n        System.out.println(\"Move disk \" + n + \" from \" + source + \" to \" + destination);\n        solveHanoi(n - 1, auxiliary, source, destination);\n        return ++counter;\n    }\n\n    public static void main(String[] args) {\n        System.out.println(\"IMPRIMIR RECURSIVIDAD:\");\n        imprimirRecursividadDesc(-30, -20);\n        imprimirRecursividadDesc(30, 60);\n        /*\n         * DIFICULTAD EXTRA\n         */\n        // Factorial\n        System.out.println(\"CALCULAR FACTORIAL:\");\n        imprimirFactorial(-20);\n        imprimirFactorial(0);\n        imprimirFactorial(20);\n        // Fibonacci\n        System.out.println(\"CALCULAR FIBONACCI:\");\n        imprimirFibonacci(-5);\n        imprimirFibonacci(0);\n        imprimirFibonacci(5);\n        imprimirFibonacci(10);\n        System.out.printf(\"La cantidad de movimientos necesarios fue: %d%n\",\n                solveHanoi(5, 'A', 'B', 'C'));\n    }\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/java/miguelex.java",
    "content": "public class miguelex {\n    \n    public static void main(String[] args) {\n        System.out.print(\"De 100 a 0: \");\n        cuentaAtras(100);\n        System.out.println();\n        \n        System.out.println(\"La suma de 5 + 3 es: \" + sumaRecursiva(5, 3));\n        System.out.println(\"El valor de 2^3 es: \" + potenciaRecursiva(2, 3));\n        System.out.println(\"El valor de 5! es: \" + factorial(5));\n        System.out.println(\"El 10º numero de Fibonacci es: \" + fibonacci(10));\n\n        System.out.println(\"Introduce el numero del que queires calcualr el factorial: \");\n        int numero = Integer.parseInt(System.console().readLine());\n        System.out.println(\"El factorial de \" + numero + \" es: \" + factorial(numero));\n\n        System.out.println(\"Introduce el numero de la serie de Fibonacci que quieres calcular: \");\n        int n = Integer.parseInt(System.console().readLine());\n        System.out.println(\"El \" + n + \"º numero de Fibonacci es: \" + fibonacci(n));\n    }\n    \n    public static void cuentaAtras (int n) {\n        if (n >= 0) {\n            System.out.print(n + \" \");\n            cuentaAtras(n - 1);\n        }        \n    }\n\n    public static int sumaRecursiva (int a, int b) {\n        if (b == 0) {\n            return a;\n        }\n        return sumaRecursiva(a + 1, b - 1);\n    }\n\n    public static int potenciaRecursiva(int base, int exponente) {\n        if (exponente == 0) {\n            return 1;\n        }\n        return base * potenciaRecursiva(base, exponente - 1);\n    }\n\n    // Metodo para calcular el factorial de un numero\n    public static int factorial(int n) {\n        if (n == 0) {\n            return 1;\n        }\n        return n * factorial(n - 1);\n    }\n    \n    public static int fibonacci(int n) {\n        if (n == 0) {\n            return 0;\n        }\n        if (n == 1) {\n            return 1;\n        }\n        return fibonacci(n - 1) + fibonacci(n - 2);\n    }\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/java/mtirador.java",
    "content": "public class mtirador {\n    public static void main(String[] args) {\n        \n      \n        \n\n        /*Del 100 al 0 */\n        int dato=100;\n        ejemplo(dato);\n\n      \n        /*Factorial */\n         int num=5;\n         factorial(num); \n\n        /*fibonacci */\n         int pos=4;\n         int resultado = fibonacci(pos);\n         System.out.println(\"El término en la posición \" + pos + \" de la secuencia de Fibonacci es: \" + resultado);\n     }\n        \n        static int fibonacci(int pos) {\n            \n            if (pos <= 0) {\n            } else if (pos == 1) {\n                 return 0; \n            } else if (pos == 2) {\n                   return 1; \n            } else {\n                return fibonacci(pos - 1) + fibonacci(pos - 2); \n            }\n            return pos;\n        }\n        \n        \n\n        static void factorial(int a){\n          int factorial=1;\n\n          for(int i=1;i<=a;i++){\n                factorial*=i;\n                \n          }\n          System.out.println(\"factorial es \"+ factorial);\n        }\n\n      static void ejemplo(int a){\n            if(a>=0){\n                System.out.println(a);\n                ejemplo(a-1);\n            }\n        }\n\n\n        \n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/java/pguillo02.java",
    "content": "//Definición de una función recursiva\n\n/**\n * pguillo02\n */\npublic class pguillo02 {\n\n        public static void main(String[] args) {\n            recursiva(100);\n        }\n\n        public static void recursiva(int n) {\n            if (n == 0){\n                System.out.println(\"Fin de la función recursiva\");\n            } else{\n                System.out.println(n);\n                recursiva(n-1);\n            }\n        }\n\n        public static int factorial(int n){\n            if (n == 0){\n                return 1;\n            } else{\n                return n*factorial(n-1);\n            }\n        }\n} \n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/java/simonguzman.java",
    "content": "public class simonguzman {\n\n    public static void main(String[] args) {\n        contadorInversoRecursivo(100);\n        System.out.println(factorialRecursivo(5));\n        System.out.println(fibonacciRecursivo(6));\n    }\n\n    //Contador de 100 a 0 recursivo\n    public static void contadorInversoRecursivo(int numero){\n        if (numero >= 0 ){\n            System.out.println(numero);\n            contadorInversoRecursivo(numero - 1);\n        }\n    }\n\n    //Factorial recursivo\n    public static int factorialRecursivo(int numero){\n        if(numero < 0){\n            return 0;\n        }else if(numero == 0 || numero == 1){\n                return 1;\n        }else{\n            return (numero * factorialRecursivo(numero - 1));\n        }\n    }\n\n    //Fibonacci por posicion recursivo\n    public static int fibonacciRecursivo(int posicion){\n        if (posicion == 0 ){\n            return 0;\n        }else if ( posicion == 1 ){\n            return 1;\n        }else{\n            return ((fibonacciRecursivo(posicion - 1)) + (fibonacciRecursivo(posicion - 2)));\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/java/ycanas.java",
    "content": "public class ycanas {\n\n    public static void myFunc(int n) {\n        if (n < 0)\n            return;\n\n        System.out.println(n);\n        myFunc(n - 1);\n    }\n\n\n    public static int Factorial(int n) {\n        if (n <= 2)\n            return n;\n\n        return Factorial(n - 1) * n;\n    }\n\n\n    public static int Fibonacci(int n) {\n        if (n <= 1)\n            return n;\n\n        return Fibonacci(n - 1) + Fibonacci(n - 2);\n    }\n\n    public static void main(String[] args) {\n        // Ejercicio\n        System.out.println(\"Ejercicio:\");\n        myFunc(100);\n\n        // Extra\n        System.out.println(\"Factorial:\");\n        System.out.println(Factorial(5));\n\n        System.out.println(\"Fibonacci:\");\n        System.out.println(Fibonacci(8));\n    }\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/7R0N1X.js",
    "content": "function reverse(n) {\n  if (n === 0) {\n    return 0;\n  }\n  console.log(n)\n  return reverse(n - 1);\n}\n\n// console.log(reverse(100));\n\n\n// Dificultad extra\n\nlet n = 5\n\nfunction factorial(n) {\n  if (n === 0) {\n    return 1\n  }\n  return n * factorial(n - 1)\n}\n\nconsole.log(`El factorial de ${n} es ${factorial(n)}`)\n\nfunction fibonacci(n) {\n  if (n === 0 || n === 1) {\n    return 0\n  }\n  if (n === 2 || n === 3) {\n    return 1\n  }\n  return fibonacci(n - 1) + fibonacci(n - 2)\n}\n\nconsole.log(`El número ${n} en la sucesión de Fibonacci es ${fibonacci(n)}`)\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/AChapeton.js",
    "content": "var recursiveFunction = function (value) {\n  console.log(value);\n  if (value === 0) {\n      return;\n  }\n  else {\n      recursiveFunction(value - 1);\n  }\n};\nrecursiveFunction(100);\nvar obtenerFactorial = function (factorial) {\n  if (factorial < 0) {\n      return -1;\n  }\n  else if (factorial === 0) {\n      return 1;\n  }\n  else {\n      return (factorial * obtenerFactorial(factorial - 1));\n  }\n};\nconsole.log('factorial: ', obtenerFactorial(10));\nvar fibonacci = function (position) {\n  if (position <= 1)\n      return 1;\n  var result = fibonacci(position - 1) + fibonacci(position - 2);\n  return result;\n};\nconsole.log('fibonacci: ', fibonacci(5));\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/Alvaro-Neyra.js",
    "content": "/*\n    * EJERCICIO:\n    * Entiende el concepto de recursividad creando una función recursiva que imprima\n    * números del 100 al 0.\n\n    ** QUE ES LA RECURSIVIDAD?\n    ** La recursividad en la programacion es una tecnica de una funcion que se llama a si misma durante su ejecucion. Este proceso\n    ** se repite hasta que se cumpla una condicion base que evita que la funcion se llame recursivamente.\n*/\n\nfunction funcionRecursiva(number) {\n    // Si el numero es 0 entonces, imprimimos el numero y luego retornamos\n    if (number === 0) {\n        console.log(number);\n        return;\n    }\n    // Imprimir el numero actual, luego llamamos a la funcion con el numero - 1\n    console.log(number);\n    funcionRecursiva(number - 1);\n}\n\nfuncionRecursiva(100)\n\n/* \n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n*/\n\nfunction factorialRecursivo(number) {\n    // Si el numero es 0 o 1 retornar 1\n    if (number === 0 || number === 1) {\n        return 1;\n    }\n    // Retonar el valor del numero multiplicado por su factorial del numero - 1\n    return number * factorialRecursivo(number - 1);\n}\n\nlet resultadoDelFactorialRecursivo = factorialRecursivo(6);\nconsole.log(`Este es el resultado de un factorial de 6 por una funcion recursiva: ${resultadoDelFactorialRecursivo}`)\n\n// Creando la sucesion de Fibonacci\nfunction sucesionDeFibonacci(number, diccionarioDeValores = {}) {\n    // Si el numero es menor a 0 retonar null\n    if (number < 0) {\n        return null;\n    }\n    // Si es el numero es 0 retornar 0\n    else if (number === 0) {\n        return 0;\n    }\n    // Si el numero es 1 retornar 1\n    else if (number === 1) {\n        return 1;\n    }\n    // Si el numero existe en el diccionario de valores de la sucesion de Fibonacci entonces, retornar el valor del numero en la sucesion.\n    else if (number in diccionarioDeValores) {\n        return diccionarioDeValores[number];\n    }\n    /* Si ninguna de las condiciones anteriores se cumple, entonces vamos a conseguir el resultado del numero en la sucesion de fibonacci\n    llamandola recursivamente hasta que se cumpla una condicion base */\n    else {\n        // Resultado:\n        let resultado = sucesionDeFibonacci(number - 1, diccionarioDeValores) + sucesionDeFibonacci(number - 2, diccionarioDeValores);\n        // Guardar el resultado con su respectivo numero en el diccionario de valores de la sucesion de fibonacci\n        diccionarioDeValores[number] = resultado;\n        // Retonar el resultado\n        return resultado;\n    }\n}\n\nlet resultadoDeLaSucesionDeFibonacci = sucesionDeFibonacci(15);\nconsole.log(`Este es el resultado de la sucesion de fibonacci: ${resultadoDeLaSucesionDeFibonacci}`);"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/ArticKun.js",
    "content": "\n\n// ⚡ RECURSIVIDAD\n/*\nEn JavaScript, la recursividad es un \nconcepto en el que una función que:\n\n1. Se llama a sí misma durante su ejecución. \n2. Debe tener una condicion donde deje de llamarse asi misma\n\nEsto puede ser útil para resolver problemas que pueden \ndividirse en subproblemas más pequeños y similares al \nproblema original.\n\n*/\n\n//* 1. IMPRIMIR NUMEROS DEL 0 al 100 CON RECURSIVIDAD\n\nfunction numerosRecursivos( numero ) {\n// Caso base: detener la recursión cuando se alcanza el 100\n    if ( numero > 100 ) {\n      return;\n    }\n// Imprimir el número actual\n    console.log( numero );\n// Llamada recursiva con el siguiente número\n    numerosRecursivos( numero + 1 );\n}\n\n\n// Llamada inicial con el número inicial\nnumerosRecursivos( 0 );\n\n\n//* 2. DIFICULTAD EXTRA (opcional):\n\n// Utiliza el concepto de recursividad para:\n// - Calcular el factorial de un número concreto (la función recibe ese número).\n// - Calcular el valor de un elemento concreto (según su posición) en la \n//   sucesión de Fibonacci (la función recibe la posición).\n\n// ⚡ 1. FACTORIAL DE UN NUMERO CON RECURSIVIDAD:\nfunction numeroFactorial( n ){\n    if (  n === 0 ){\n        return 1;\n    }else{\n        return n * numeroFactorial( n - 1 );\n    }\n};\n\n// 5! = 5 x 4 x 3 x 2 x 1\nnumeroFactorial( 5 ); // output : 120 \n\n// ⚡ 2. SECUENCIA FIBONACCI CON RECURSIVIDAD:\n\n\n\nfunction numeroFibonacci( num ){\n    \n    if( num <= 0 ){\n        print('Numeros negativos no válidos');\n        return 0;\n    }\n    else if( num === 1 ){\n        return 0;\n    }\n    else if( num === 2 ){\n        return 1;\n    }\n    else{\n        console.log(num);\n        return numeroFibonacci( num - 1 ) + numeroFibonacci ( num - 2 );\n    }\n\n};\n\nnumeroFibonacci( 3 );"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/CaveroBrandon.js",
    "content": "/*\nEJERCICIO:\nEntiende el concepto de recursividad creando una función recursiva que imprima\nnúmeros del 100 al 0.\n*/\nfunction recursiveCounter(num) {\n    if (num == 0) {\n        console.log(num);\n        return num;\n    }\n    else {\n        console.log(num);\n        recursiveCounter(num-1);\n    }\n}\n/* DIFICULTAD EXTRA (opcional):\nUtiliza el concepto de recursividad para:\n- Calcular el factorial de un número concreto (la función recibe ese número).\n- Calcular el valor de un elemento concreto (según su posición) en la \nsucesión de Fibonacci (la función recibe la posición).\n*/\n\nfunction factorial(num) {\n    if (num == 0) {\n        return 1;\n    }\n    else if (num == 1) {\n        return num;\n    }\n    else {\n        return num * factorial(num - 1);\n    }\n}\n\nfunction myFibonacci(pos) {\n    if (pos == 0) {\n        return 0;\n    }\n    if (pos == 1) {\n        return 1;\n    }\n    else {\n        return myFibonacci(pos - 1) + myFibonacci(pos - 2);\n    }\n}\n\nconsole.log('Counting down from 100 to 0: ');\nrecursiveCounter(100);\n// Factorial function examples\nconsole.log('The factorial of 1 is: ' + factorial(1));\nconsole.log('The factorial of 2 is: ' + factorial(2));\nconsole.log('The factorial of 4 is: ' + factorial(4));\nconsole.log('The factorial of 6 is: ' + factorial(6));\n// Fibonacci function examples\nconsole.log('The Fibonacci of 2 is: ' + myFibonacci(2));\nconsole.log('The Fibonacci of 4 is: ' + myFibonacci(4));\nconsole.log('The Fibonacci of 8 is: ' + myFibonacci(8));\nconsole.log('The Fibonacci of 10 is: ' + myFibonacci(10));\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/CesarCarmona30.js",
    "content": "/**\n * EJERCICIO\n */\n\nfunction numbers(number) {\n  if (number < 0) {\n    return;\n  } else {\n    console.log(number);\n    number--;\n    numbers(number);\n  }\n}\n\nconsole.log('Números del 100 al 0 mediante recursividad:');\nnumbers(100)\n\n/**\n * EXTRA\n */\n\nfunction factorial(number) {\n  if (number === 0) {\n    return 1;\n  } else {\n    return number * factorial(number - 1);\n  }\n}\n\nfunction fibonacci(number) {\n  if (number === 0) {\n    return 0;\n  } else if (number === 1 || number === 2) {\n    return 1;\n  } else {\n    return fibonacci(number - 2) + fibonacci(number - 1);\n  }\n}\n\nconsole.log(`!6 = ${factorial(6)}`);\nconsole.log(`Posición 8 de Fibonacci = ${fibonacci(8)}`);"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/DAVstudy.js",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la\n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\n// Recursividad\n\nfunction recursivity(number) {\n    if (number > 0) {\n        console.log(number)\n        return recursivity(--number)\n    }\n    return console.log(number)\n}\n\nrecursivity(100)\n\n\n// Ejercicio Extra\n\n// Factorial  !5= 5 * 4 * 3 * 2 * 1 = 120\n\nfunction factorial(x) {\n    if (x === 1) {\n        return x\n    }\n    return x * factorial(--x)\n}\n\nconsole.log(factorial(5));\n\n\n// Fibonacci\n\nfunction fibonacci(position) {\n    \n    if (position <= 0) {\n        return 0 \n    } else if (position === 1) {\n        return 1\n    } else if (position === 2) {\n        return 1\n    } else {\n        return fibonacci (position - 1) + fibonacci(position - 2)\n    }\n}\n\n\nconsole.log(fibonacci(18));\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/Dan-Corbo.js",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la\n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\n\n\n/* Soluciones */\n\n\nfunction recursividad(num) {\n  if (num < 0) {\n    return;\n  } else {\n    console.log(`Número: ${num}`);\n    recursividad(num - 1);\n  }\n}\n\nrecursividad(100);\n\n\n/* Extra - Opcional */\n\n\nfunction factoriales(num) {\n  if (num === 0) {\n    return 1;\n  } else {\n    return num * factoriales(num - 1);\n  }\n}\n\nconsole.log(factoriales(8));\n\n\nfunction fibonacci(posicion) {\n  if (posicion === 0 || posicion === 1) {\n    return posicion;\n  } else {\n    return fibonacci(posicion - 1) + fibonacci(posicion - 2);\n  }\n}\n\nconsole.log(fibonacci(25));"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/DavidMoralesDeveloper.js",
    "content": "// Entiende el concepto de recursividad creando una función recursiva que imprima\n//  * números del 100 al 0.\n\nfunction countDown (num) {\n    if (num === 1 ){\n        return  console.log(1)\n    }\n    console.log(num)\n    return countDown( num - 1) \n}\n\n// console.log(countDown(100))\n\n\n// extra \n\n// Utiliza el concepto de recursividad para:\n//  * - Calcular el factorial de un número concreto (la función recibe ese número).\n//  * - Calcular el valor de un elemento concreto (según su posición) en la \n//  *   sucesión de Fibonacci (la función recibe la posición).\n\nfunction factorial (num) {\nif ( num < 0) {\n    return console.log('los numeros negativos no son validos')\n}else if(num == 0) {\n    return 1\n}\nconsole.log(num)\nreturn num * factorial(num -1)\n}\nconsole.log(factorial(5))\n\n// ---------------------------\n\nfunction fibonacci (num) {\nif( num < 2 ) return num\n\nreturn fibonacci( num - 2) + fibonacci(num - 1)\n}\n\nconsole.log(fibonacci(6))\n\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/Deyvid-10.js",
    "content": "function recursividad(n)\n{\n    if(n >= 0)\n    {\n        console.log(n);\n        recursividad(n-1)\n    } \n}\n\nrecursividad(100)\n\n// DIFICULTAD EXTRA\n\nfunction factorial(n) {\n    if(n < 0)\n    {\n        return \"Los numero negativos no tienen factorial\"\n    }\n    else if(n == 0) \n    {\n       return 1 \n    } \n    else \n    { \n       return n * factorial(n-1)\n    }\n\n }\n\nconsole.log(factorial(5));\n\n\nlet fibo = [0, 1]\nlet indice = 0\nfunction fibonacci(posicion)\n{\n    if(indice < posicion)\n    {\n        fibo.push(fibo[indice] + fibo[indice + 1])\n        indice++  \n        fibonacci(posicion)\n        return fibo[posicion - 1]\n    }\n}\n\nconsole.log(fibonacci(5));"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/DjSurgeon.js",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\n/*\nLa recursividad es una propiedad de los lenguajes de programación que significa que una función puede llamarse a si misma.\nEs útil cuando una tarea puede resolverse en tareas del mismo tipo pero más simples.\n*/\n\n// Exercise \n\nfunction recursion(first, last) {\n    if (first === last) {\n        console.log(first);\n        return first;\n    } \n    else {\n        console.log(first)\n        return recursion(first + 1, last)\n    }\n}\n// recursion(0,100);\n\n// Extra\nfunction factorial(number) {\n    if (number === 0) {\n        return 1;\n    } \n    else if (number === 1) {\n        return 1;\n    }\n    else {\n        return number * factorial(number - 1);\n    }\n}\n// console.log(factorial(5)); // Print 120\n\nfunction fibonacci(position) {\n    let array = [0,1];\n    let i;\n        for (i = 0; i < position - 1; i++) {\n            array.push(array[i] + array[i + 1]);\n        }\n    if (array.length - 1 === position) {\n      return array[array.length - 1];\n    }\n}\n// console.log(fibonacci(8)); // Print 21\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/FabianRpv.js",
    "content": "// Recursividad\n\nfunction oneHundred(n) {\n    if (n < 0) {\n        return\n    }\n\n    console.log(n)\n    oneHundred(n - 1)\n}\n\noneHundred(100);\n\n// Factorial\n\nfunction factorial(n) {\n    if (n === 0) {\n        return 1\n    }\n\n    return n * factorial(n - 1)\n}\n\nconsole.log(factorial(4))\n\n// Fibonacci \n\nfunction fibonacci (n) {\n    if (n === 0) {\n        return 0\n    }\n\n    if (n === 1) {\n        return 1\n    }\n\n    return fibonacci(n - 1) + fibonacci(n - 2)\n}\n\nconsole.log(fibonacci(10))"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/Glitzypanic.js",
    "content": "// EJERCICIO\nfunction countDown(number) {\n  console.log(number);\n  if (number === 1) {\n    // Este es el caso base\n    console.log(\"Boom!\");\n  } else {\n    // Esta es la llamada recursiva\n    return countDown(number - 1);\n  }\n}\n\ncountDown(100);\n\n// EJERCICIO OPCIONAL 1\nfunction factorial(numero) {\n  if (numero === 0) {\n    return 1;\n  } else {\n    return numero * factorial(numero - 1);\n  }\n}\n\nfactorial(10);\nconsole.log(factorial(10));\n\n// EJERCICIO OPCIONAL 2\nfunction fibonacci(n) {\n  if (n < 0) {\n    console.log(\"La posición tiene que ser mayor que cero\");\n    return 0;\n  } else if (n == 1) {\n    return 0;\n  } else if (n == 2) {\n    return 1;\n  } else {\n    return fibonacci(n - 1) + fibonacci(n - 2);\n  }\n}\n\nconsole.log(fibonacci(10));\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #06 - JavaScript ->Jesus Antonio Escamilla */\n/**\n * La recursividad es un concepto que se llama la misma función asi misma,\n    siempre y cuanto tenga donde llegar y donde iniciar, claro tener un punto de rotura\n */\n\nfunction cuentaAtrás(numero) {\n    if(numero <= 0){\n        console.log(\"¡Cero!\");\n    }else{\n        console.log(numero);\n        cuentaAtrás(numero - 1);\n    }\n}\n\ncuentaAtrás(100);\n\n/**-----DIFICULTAD EXTRA-----*/\n\n//-----FACTORIAL-----\nfunction factorial(num) {\n    if (num === 0) {\n        return 1;\n    } else if(num < 0){\n        return 0;\n    }else {\n        return num * factorial(num - 1);\n    }\n}\n\nconsole.log(factorial(5));\n\n\n\n//-----FIBONACCI-----\nfunction Fibonacci(a) {\n    if(a <= 1){\n        return a;\n    }else{\n        return Fibonacci(a - 1) + Fibonacci(a - 2);\n    }\n}\n\nconsole.log(Fibonacci(4));\n\n/**-----DIFICULTAD EXTRA-----*/"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/JoseAndresGC.js",
    "content": "// recursividad javascript\n// a grandes rasgos es una funcion que se llama a si misma\n\nfunction countdown(numero) {\n    console.log(numero); // imprime el numero\n    if (numero > 0) { // si numero es mayor a 0\n        countdown(numero - 1); // llama la funcion countdown y le resta 1 numero\n    } else { // de lo contrario\n        console.log(\"cuenta regresiva terminada\") // imprime qie la cuenta regresiva ha terminado\n    }\n}\ncountdown(100); // numero vale ahora 100\n\n// DIFICULTAD EXTRA\n\nfunction factorial(numero) {\n    if (numero < 0) {\n        return \"Error: No se permiten números negativos \"; // si el numero es menor a 0 retorna que no se permiten numeros negativos\n    } else if (numero === 0) {\n        return 1; // si el numero es 0 retorna 1, ya que el factorial de 0 es 1\n    } else {\n        return numero * factorial(numero - 1); // si el numero es mayor a 0, se multiplica el numero por el factorial - 1\n    }\n}\nconsole.log(factorial(5)); // 120\nconsole.log(factorial(0)); // 1\nconsole.log(factorial(-500)); // Error: No se permiten números negativos\n\nfunction fibonacci(numero) {\n    if (numero <= 0) {\n        console.log(\"Error: La posició debe ser mayor a 0\"); // si el numero es menor o igual a 0 retorna que los numeros negativos no son permitidos\n        return 0;\n    } else if (numero === 1 ) {\n        return 0;\n    } else if (numero === 2) {\n        return 1;\n    } else {\n        return fibonacci(numero - 1) + fibonacci(numero - 2); // si el numero es mayor a 1, se suma el fibonacci del numero - 1 y el fibonacci del numero - 2\n    }\n}\n\nconsole.log(fibonacci(5));"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/JuanCaicedo1024.js",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\nfunction recursiva (num) {\n    console.log(num)\n    if (num === 0){\n        return 0\n    }\n    return recursiva(num-1)\n}\n\nrecursiva(100)\n\n\n//factorial\nfunction factorial (num) {\n    if(num === 1){return 1}\n    return num*factorial(num-1)\n}\nconsole.log(factorial(100))\n\n//Fibonacci\nfunction fibonacci(n) {\n    if(n === 0){return 0}\n    else if (n === 1){return 1}\n    return fibonacci(n-1) + fibonacci(n-2)\n}"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/MatiTC.js",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n\n */\n\n//Recusrividad... mi peor enimgo\n//¿Que es la recursividad? Técnica de programación que permite crear instrucciones que se repitan un número n de veces.\n//En resumen: Una funcion que se llama a si misma\n\nfunction imprimirNumeros(num) {\n  // Caso base: cuando num es menor o igual a 0, detenemos la recursión\n  //En la mayoria de los casos, hay que buscar la forma de como se detiene la recursividad\n  if (num <= 0) {\n    console.log(num);\n    return;\n  }\n  // Imprime el número actual\n  console.log(num);\n  // Llama a la función recursivamente con el número decrementado en 1\n  imprimirNumeros(num - 1);\n}\n// Llamamos a la función con 100 para comenzar desde ahí\nimprimirNumeros(100);\nconsole.log(`.........................................`);\n\n/*  * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la\n *   sucesión de Fibonacci (la función recibe la posición).*/\n\n// Factorizacion recursiva\nfunction factorizacionRecursiva(fact) {\n  // Casos base: termina puesto que llego al final, el 1! = 0 y 0! = 1\n  if (fact == 0 || fact == 1) {\n    console.log(fact);\n    return 1;\n  }\n  //bandera\n  console.log(fact, '!');\n  // 5 * 4\n  return fact * factorizacionRecursiva(fact - 1);\n}\nconsole.log('Factorial de 5:', factorizacionRecursiva(5)); // output: 120 = 5x4x3x2x1\nconsole.log(`.........................................`);\n\n// Función recursivo\nfunction fibonacci(pos) {\n  // Casos base: si la posición es 0 o 1, el valor es la misma posición\n  if (pos === 0 || pos === 1) {\n    return pos;\n  }\n\n  // Caso recursivo: fibonacci(pos - 1) + fibonacci(pos - 2)\n  return fibonacci(pos - 1) + fibonacci(pos - 2);\n}\nconsole.log(\"Fibonacci de 0:\", fibonacci(0)); // Resultado: 0\nconsole.log(\"Fibonacci de 1:\", fibonacci(1)); // Resultado: 1\nconsole.log(\"Fibonacci de 2:\", fibonacci(2)); // Resultado: 1\nconsole.log(\"Fibonacci de 4:\", fibonacci(4)); // Resultado: 3\nconsole.log(\"Fibonacci de 6:\", fibonacci(6)); // Resultado: 8\nconsole.log(`.........................................`);\n\n/*\nn =\t0\t1\t2\t3\t4\t5\t6\t7\t8\t9\t10\t11\t12\t13\t14\t...\nxn =0\t1\t1\t2\t3\t5\t8\t13\t21\t34\t55\t89\t144\t233\t377\t...\n*/\n\nconsole.log(`.........................................`);"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/MeLlamoOmar.js",
    "content": "const fibonacci = (n) => {\n  if (n <= 1) {\n    return n;\n  }\n\n  return fibonacci(n - 1) + fibonacci(n - 2);\n};\n\nconst factorial = (n) => {\n  if (n == 0) {\n    return 1;\n  }\n\n  return n * factorial(n - 1);\n};\n\nconsole.log(fibonacci(20));\nconsole.log(factorial(20));\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/MiguelAngelEc.js",
    "content": "// Recursividad\n\nfunction returnNumber(n){\n    if (n === 0) return;\n    console.log(n);\n    returnNumber(n - 1);\n}\nreturnNumber(100);\n\n// Recursividad con Factorila\n\nfunction factoria(n){\n    if(n === 0) return 1;\n    return n *(n - 1);\n}\nconsole.log(factoria(5));\n\n// Fibonacci\n\nfunction Fibonacci(n) {\n    return (n === 0 || n === 1) ? n : Fibonacci(n - 1) + Fibonacci(n - 2);\n}\n\nconsole.log(Fibonacci(10));"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/MiguelAngelMTZ000414.js",
    "content": "console.warn(\"----------(◉◉∖____/◉◉)---------- Recursividad ----------(OO∖____/OO)----------\")\nconsole.log(\"Imprimiendo del número 100 al número 0 usando Recursividad\")\n// Definimos la funcion con un parametro de tipo numero\nfunction recursividad(numero) {\n    // Le indicamos al programa hasta donde queremos que terminer la ejecusión\n    if (numero >= 0) {\n        // Imprimimos por consola el valor de la variable\n        console.log(numero) // 10\n        // Llamamos nuevamente a la funcion\n        recursividad(numero-1) // Haciendo uso de la recursividad\n    }\n}\nrecursividad(100)\n\nconsole.warn(\"----------(◉◉∖____/◉◉)---------- Ejercicio Extra ----------(OO∖____/OO)----------\")\nconsole.log(\"------------ Factorial de un número ------------\")\nfunction factorial(valor_factorial) {\n    if (valor_factorial < 0) {\n        return \"No se aceptan números negativos\"\n    } else if(valor_factorial == 0 || valor_factorial == 1) {\n        return 1\n    } else {\n        return valor_factorial * factorial(valor_factorial - 1)\n    }\n}\nlet num_factorial = 10\nlet resultado_factorial = factorial(num_factorial)\nconsole.log(`Factorial de ${num_factorial}! = ${resultado_factorial}`)\n\nconsole.log(\"------------ Fibonacci ------------\")\nfunction fibonacci(valor_fibonacci) {\n    if (valor_fibonacci <= 0) {\n        console.log(\"No se aceptan números negativos\")\n        return 0\n    } else if (valor_fibonacci == 1) {\n        return 0\n    } else if (valor_fibonacci == 2) {\n        return 1\n    } else {\n        return fibonacci(valor_fibonacci - 1) + fibonacci(valor_fibonacci - 2)\n    }\n}\nlet num_fibonacci = 10\nlet resultado_fibonacci = fibonacci(num_fibonacci)\nconsole.log(`La posición ${num_fibonacci} en fibonacci es = ${resultado_fibonacci}`)\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/Nightblockchain30.js",
    "content": "var recursiveFunction = function(value){\n    console.log(value);\n    if (value == 0){\n        return;\n    } else {\n        recursiveFunction(value - 1);\n    }\n};\n\nrecursiveFunction(10);\n\nvar obtenerFactorial = function(num){\n    if (num === 0 || num === 1){\n        return 1;\n    } else {\n        return (num * obtenerFactorial(num - 1));\n    }\n}\nconsole.log(obtenerFactorial(5));\n\n// Posición Fibonacci\nconst valorFibonacci = function(posicion){\n    if (posicion === 1 || posicion === 2){\n        return 1;\n    } else {\n        return valorFibonacci(posicion - 1) + valorFibonacci(posicion - 2);\n    } \n}\n\nconsole.log(valorFibonacci(10));"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/OmarLand.js",
    "content": "/*\n  * EJERCICIO:\n  * Entiende el concepto de recursividad creando una función recursiva que imprima\n  * números del 100 al 0.\n*/\n\nconst countDownBOOM = ( value ) => {\n    for( let i = value; i>=0; i-- ){\n        console.log(`Countdown => ${i}`);\n        if( i === 0 ){\n          console.log(\"BOOOOOOOM\");\n        }\n    }\n}\ncountDownBOOM(100);\n\n/*\n  * DIFICULTAD EXTRA (opcional):\n  * Utiliza el concepto de recursividad para:\n  * - Calcular el factorial de un número concreto (la función recibe ese número).\n  * - Calcular el valor de un elemento concreto (según su posición) en la\n  *   sucesión de Fibonacci (la función recibe la posición).\n*/\n\n// Calcular el factorial de un numero concreto (Se recibe como parametro)\nconst factorial = ( value ) => {\n    let aux = [];\n\n    for( let i = 1; i <= value; i++ ){\n      aux.push(i);\n    }\n  \n  // console.log( aux );\n  let result = aux.reduce( ( valueA, valueB ) => valueA * valueB );\n  console.log( result );\n}\nfactorial( 6 );\n\n// Fibonacci:\nconst fibonacci = (value) => {\n\n  let numbers = [0, 1];\n  for (let i = 2; i < value; i++) {\n    numbers[i] = numbers[i - 1] + numbers[i - 2];\n  }\n\n  return numbers;\n\n};\n\n// 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89...\nconsole.log( fibonacci( 10 ) );\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/Pancratzia.js",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la\n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\nfunction countTo0(num) {\n  console.log(num);\n\n  if (num === 0) return;\n  else countTo0(num - 1);\n}\n\ncountTo0(100);\n\n//DIFICULTAD EXTRA (opcional):\n\nfunction nFactorial(num) {\n  if (num === 0 || num === 1) return 1;\n  else return num * nFactorial(num - 1);\n}\n\nfunction fibonacci(num) {\n  if (num <= 1) return 1;\n  else return fibonacci(num - 1) + fibonacci(num - 2);\n}\n\nconst randomNum = Math.floor(Math.random() * 10 + 1);\n\nconsole.log(`El factorial de ${randomNum} es ${nFactorial(randomNum)}`);\nconsole.log(`El elemento ${randomNum} de la sucesión de Fibonacci es ${fibonacci(randomNum)}`);\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/RaulDoezon.js",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n*/\n\nconsole.log(\"+++++++++ IMPRIMIR LOS NÚMEROS DEL 100 AL 0 +++++++++\");\nfunction cuentaRegresiva(numero) {\n  if (numero === 0) {\n    return;\n  }\n\n  console.log(numero);\n  return cuentaRegresiva(numero - 1);\n}\n\nconsole.log(cuentaRegresiva(100));\n\nconsole.log(\"\\n+++++++++ DIFICULTAD EXTRA: CALCULAR EL FACTORIAL DE UN NÚMERO CONCRETO +++++++++\");\nfunction calcularFactorial(numero) {\n  if (numero === 0) {\n    return 1;\n  }\n\n  return numero * calcularFactorial(numero - 1);\n}\n\nvar numeroFactorial = 5;\n\nconsole.log(`El factorial de ${numeroFactorial} es: ${calcularFactorial(numeroFactorial)}`);\n\nconsole.log(\"\\n+++++++++ DIFICULTAD EXTRA: CALCULAR EL VALOR DE UN ELEMENTO CONCRETO (SEGÚN SU POSICIÓN) EN LA SUCESIÓN DE FIBONACCI +++++++++\");\nfunction sucesionDeFibonacci(posicion) {\n  if (posicion === 0) {\n    return 0;\n  } else if (posicion === 1) {\n    return 1;\n  }\n\n  return sucesionDeFibonacci(posicion - 1) + sucesionDeFibonacci(posicion - 2);\n}\n\nvar posicionEnSucesion = 8\n\nconsole.log(`El valor de la posición ${posicionEnSucesion} en la sucesión de Fibonacci es: ${sucesionDeFibonacci(posicionEnSucesion)}`);\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/RicJDev.js",
    "content": "//EJERCICIO\nconsole.log(\"\\nNUMEROS DEL 100 AL 0\");\nfunction cuentaAtras(n) {\n\tif (n >= 0) {\n\t\tconsole.log(n);\n\t\tcuentaAtras(n - 1);\n\t}\n}\n\ncuentaAtras(100);\n\n//EXTRA\nconsole.log(\"\\nFACTORIALES\");\nconst factorial = (n) => {\n\tif (n < 0) {\n\t\tconsole.log(\"Numero no valido\");\n\t\treturn 0;\n\t} else if (n === 0) {\n\t\treturn 1;\n\t} else {\n\t\treturn n * factorial(n - 1);\n\t}\n};\n\nconsole.log(factorial(5));\n\nconsole.log(\"\\nSUCESIÓN DE FIBONACCI\");\nconst fibonacci = (n) => {\n\tif (n <= 0) {\n\t\tconsole.log(\"Numero no valido\");\n\t\treturn 0;\n\t} else if (n === 1) {\n\t\treturn 0;\n\t} else if (n === 2) {\n\t\treturn 1;\n\t} else {\n\t\treturn fibonacci(n - 1) + fibonacci(n - 2);\n\t}\n};\n\nconsole.log(fibonacci(23));\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/Sac-Corts.js",
    "content": "// Exercise // \nfunction from100to0(n) {\n    if (n <= 0) {\n        return 0;\n    }\n    console.log(n);\n    return from100to0(n - 1);\n}\n\nconsole.log(from100to0(100));\n\n// Extra Exercise // \nfunction factorial(n) {\n    if (n <= 1) {\n        return 1;\n    }\n    return n * factorial(n - 1);\n} \n\nconsole.log(factorial(5));\n\nfunction fibonacci(n) {\n    if (n == 1) {\n        return 1;\n    } else if (n == 0) {\n        return 0;\n    } else {\n        return fibonacci(n-1) + fibonacci(n-2);\n    }\n}\n\nconsole.log(fibonacci(2));\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/UserMatthew.js",
    "content": "/* #06 RECURSIVIDAD\n\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\nfunction recursiva100to0 (num) {\n    if (num < 0) {\n        return;\n    }\n    console.log(num);\n    recursiva100to0(num - 1);\n}\nrecursiva100to0(100);\n\nfunction factorial (num) {\n    if (num === 0 || num === 1) {\n        return 1;\n    } else {\n        return num * factorial(num - 1);\n    }\n}\nconsole.log(factorial(6));\n\nfunction fibonacci (num) {\n    if (num === 0) {\n        return 0;\n    } else if (num === 1) {\n        return 1;\n    } else {\n        return fibonacci(num - 1) + fibonacci(num - 2);\n    }\n}\nconsole.log(fibonacci(3));\n\n\nfunction sumaRecursiva(n) {\n    if (n === 1) {\n        return 1;\n    } else {\n        return n + sumaRecursiva(n - 1);\n    }\n}\n\nconsole.log(sumaRecursiva(5))"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/YgriegaSB.js",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\nconst printNumbers = (n) => {\n    console.log(n);\n    if(n !== 1) {\n        printNumbers(n-1);\n    }\n}\nprintNumbers(100);\n\nconst factorial = (n) => {\n    if(n > 1){\n        return n * factorial(n-1);\n    }\n    return 1;\n}\n\nfactorial(5);\n\nconst fibonacci = (position) => {\n    if(position > 1) {\n        return fibonacci(position - 1) + fibonacci(position - 2);\n    }\n    return (position === 0) ? 0 : 1;\n}\nfibonacci(8);"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/Younes0-0.js",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\n//Ejercicio\nfunction cuenta_atras(num){\n    if (num <= 0) {\n        return;\n    }\n    console.log(num);\n    return cuenta_atras(num - 1);\n}\n//cuenta_atras(100)\n\n//Factorial\nfunction factorial(num){\n    if (num === 0 || num === 1) {\n        return 1;\n    } else {\n        return num * factorial(num - 1);\n    }\n}\n//console.log(factorial(5));\n\n//Fibonacci\nfunction fibonacci(num){\n    if (num === 0) {\n        return 0;\n    } else if (num === 1) {\n        return 1;\n    } \n    return fibonacci(num - 1) + fibonacci(num - 2);\n    \n}\n//0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55…\nconsole.log(fibonacci(10));\n\n\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/aarxnmendez.js",
    "content": "// Función recursiva para imprimir números del 100 al 0\r\nfunction imprimirNumeros(n) {\r\n    if (n < 0) return;\r\n    console.log(n);\r\n    imprimirNumeros(n - 1);\r\n}\r\n\r\nimprimirNumeros(100);\r\n\r\n// Ejercicio Extra: Función recursiva para calcular el factorial de un número\r\nfunction factorial(n) {\r\n    if (n === 0) return 1;\r\n    return n * factorial(n - 1);\r\n}\r\n\r\nconsole.log(factorial(5)); // 120\r\n\r\n// Ejercicio Extra: Función recursiva para calcular el valor de un elemento en la sucesión de Fibonacci\r\nfunction fibonacci(n) {\r\n    if (n <= 1) return n;\r\n    return fibonacci(n - 1) + fibonacci(n - 2);\r\n}\r\n\r\nconsole.log(fibonacci(10)); // 55"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/adrs1166ma.js",
    "content": "/*\n* EJERCICIO:\n* Entiende el concepto de recursividad creando una función recursiva que imprima\n* números del 100 al 0.\n*\n* DIFICULTAD EXTRA (opcional):\n* Utiliza el concepto de recursividad para:\n* - Calcular el factorial de un número concreto (la función recibe ese número).\n* - Calcular el valor de un elemento concreto (según su posición) en la \n*   sucesión de Fibonacci (la función recibe la posición).\n*/\n\n// 🔥 EJERCICIO\nconst imprimirNumeros = (n) => n < 0 || (console.log(n), imprimirNumeros(n-1))\nimprimirNumeros(100)\n\n// 🔥 Extra\n\n// Fibonacci\n// F(0) = 0, F(1) = 1\n// F(n) = F(n - 1) + F(n - 2) para n > 1.\nconst fibonacci = (n) => n === 0 ? 0 : n === 1 ? 1 : fibonacci(n-1) + fibonacci(n-2)\n\nconsole.log(\"Fibonacci en posición 5:\", fibonacci(5)) // 5\nconsole.log(\"Fibonacci en posición 10:\", fibonacci(10)) // 55\n\n// Factorial\n// n! = n * (n - 1) * (n - 2) * ... * 1\n// Caso base: 0! = 1.\nconst factorial = (n) => (n === 0 || n === 1) ? 1: n * factorial(n - 1)\n\nconsole.log(\"Factorial de 5:\", factorial(5)); // 120\nconsole.log(\"Factorial de 7:\", factorial(7)); // 5040"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/agusrosero.js",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la\n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\n// EJERCICIO:\nfunction recursividad(numero) {\n  if (numero >= 100) {\n    console.log(numero);\n  } else {\n    return;\n  }\n  recursividad(numero - 1);\n}\n\nrecursividad(100);\n\n// DIFICULTAD EXTRA:\nfunction calcularFactorial(numero) {\n  if (numero === 0 || numero === 1) {\n    return 1;\n  } else {\n    let factorial = 1;\n    for (let i = 2; i <= numero; i++) {\n      factorial *= i;\n    }\n    return factorial;\n  }\n}\n\nconsole.log(calcularFactorial(4));\n\nfunction fibonacci(posicion) {\n  if (posicion === 0) {\n    return 0;\n  } else if (posicion === 1) {\n    return 1;\n  } else {\n    let anterior = 0;\n    let actual = 1;\n    for (let i = 2; i <= posicion; i++) {\n      let siguiente = anterior + actual;\n      anterior = actual;\n      actual = siguiente;\n    }\n    return actual;\n  }\n}\n\nconsole.log(fibonacci(6));\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/airesEsteban.js",
    "content": "function cuentaAtras(num){\n    if (num >= 0){\n        console.log(num)\n        cuentaAtras(num-1)\n    }\n}\n\ncuentaAtras(100)\n\n// Dificultad extra\n\nfunction factorial(num){\n    if (num < 0){\n        console.log(\"No se permiten usar numero negativos\")\n        return 0\n    }else if(num == 0){\n        return 1\n    }else{\n        return num * factorial(num-1)\n    }\n}\n\nconsole.log(factorial(5))\n\nfunction fibonacci(pos){\n    if (pos <= 0){\n        console.log(\"La posisicion debe ser mayor a 0\")\n        return 0\n    }else if(pos==1){\n        return 0\n    }else if(pos ==2){\n        return 1\n    }else{\n       return fibonacci(pos - 1) + fibonacci (pos - 2)\n    }\n}\n\nconsole.log(fibonacci(5))"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/alexdevrep.js",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n//Ejercicio\n\nfunction recursividad(numero){\n    if (numero<=100){\n        console.log(numero)\n    }\n    else {\n        return recursividad\n    }\n   \n    recursividad (numero +1)\n\n}\n\nrecursividad(0)\n\n\n\n\n//Dificultad extra\nconst prompt=require('prompt-sync')()\nfunction factorial (numero2){\n    if (numero2==0){\n        return 1\n    }\n    else {\n        return numero2 * factorial(numero2-1)\n    }\n}\n\nlet numero2 = prompt(\"Por favor ingrese un número: \")\n\nlet resultado= factorial(numero2)\nconsole.log(resultado)\n\n\nfunction Fibonacci (posicion){\n    if (posicion<=1){\n        return posicion\n    }\n    else {\n        return Fibonacci(posicion -1)+ Fibonacci(posicion-2)\n    }\n}\nlet posicion = prompt(\"Por favor ingrese la posición del número en la serie: \")\nlet resultado2 = Fibonacci(posicion)\nconsole.log(resultado2)\n\n\n\n\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/andresgcastillo.js",
    "content": "function printNumbers(num) {\n  if (num < 0) {\n    return;\n  }\n  console.log(num);\n  printNumbers(num - 1);\n}\n\nprintNumbers(100);\n\n//Dificultad Extra\n\n//Factorial\nfunction factorial(num) {\n  if (num === 0 || num === 1) {\n    return 1;\n  }\n  return num * factorial(num - 1);\n}\n\nconsole.log(factorial(23));\n\n//Fibonacci\nfunction fibonacci(num) {\n  if (num <= 1) {\n    return num;\n  }\n  return fibonacci(num - 1) + fibonacci(num - 2);\n}\n\nconsole.log(fibonacci(23));\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/bernatcs.js",
    "content": "// ** EJERCICIO\n\nfunction recursividad(n) {\n    if (n >= 0) {\n        console.log(n);\n        recursividad(n - 1);\n    }\n}\n\nrecursividad(100)\n\n// ** DIFICULTAD EXTRA ** --------------------------------------------------------------------------------------------------------------------------------------------\n\n//  Calcula el factorial de un número concreto\n\nfunction factorial(n) { // La función recibe el número a factorizar\n    if (n <= 0) {\n        return 1;\n    } else {\n        return n * factorial(n - 1);\n    }\n}\n\nfactorial(5) // 120\n\n// Calcula el valor de un elementos concreto en la sucesión de Fibonacci\n\nfunction fibonacci() { // La función recibe la posición del número\n    \n}\n\n\nfunction fibonacci(n) { \n    if (n === 0) {\n        return 0;\n    } else if (n === 1) {\n        return 1;\n    } else {\n        return fibonacci(n-1) + fibonacci(n-2);\n    }\n}\n\nconsole.log(fibonacci(5)) // La función empieza a contar desde el 0 como primera posición de la serie de Fibonacci"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/brahiams7.js",
    "content": "\n/**\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n */\n\n\nfunction numberCount(number){\n    if (number>=0){\n        console.log(number);\n        return numberCount(number-1)\n    }\n}\nnumberCount(100)\n\n/** DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n */\nfunction factorial(number){\n    if (number < 0){\n        console.log(\"Numero no valido\");\n        return;\n    } else if (number===0){\n        return 1;\n    } else {\n        return ((number*factorial(number-1)));\n    }\n}\nconsole.log(factorial(5));\n\n/** - Calcular el valor de un elemento concreto (según su posición) en la\n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\nfunction fibonacci(number){\n    if (number===0||number===1){\n        return 0;\n    } else if( number===2 || number==3){\n        return 1;\n    } else {\n        return fibonacci(number-1) + fibonacci(number-2)\n    }\n}\nconsole.log(fibonacci(8));\n\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/caterinarodriguezdev.js",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\nconst decrementByOne = (i = 101) => {\n    let decrementedValue = i - 1;\n    console.log(decrementedValue);\n    if (decrementedValue > 0) {\n        decrementByOne(decrementedValue)\n    }\n}\n\ndecrementByOne();\n\nconst calculateFactorial = (num, total = 1) => {\n    if (num > 1) {\n        const multi = num * total;\n        return calculateFactorial(num - 1, multi)\n    } else {\n        return total;\n    }\n}\n\nconsole.log(calculateFactorial(6));\n\nconst calculateFibonacciVal = (pos) => {\n    if (pos < 1){\n        console.log('El valor tiene que ser positivo y mayor a 0');\n        return 0;\n    } else if (pos === 1){\n        return 0;\n    } else if (pos === 2){\n        return 1;\n    } else {\n        return calculateFibonacciVal(pos - 1) + calculateFibonacciVal(pos - 2);\n    }\n}\n\nconsole.log(calculateFibonacciVal(8));"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/ceciliarava1.js",
    "content": "// In a recursive function, it is crucial to define a condition that stops the recursion \n// to avoid an infinite loop and a stack overflow error.\n\nlet counter = 0\n\nfunction recurse(fromNumber) {\n    console.log(fromNumber)\n    while (counter < 100) {\n        counter++\n        recurse(fromNumber - 1)\n    }\n}\n// recurse(100);\n\n\nfunction factorial(number) {\n    let value = 0\n    let factor = 1\n\n    if (number === 0 || number === 1) {\n        return 1;\n    }\n\n    while (value < number) {\n        factor *= number - value\n        value++\n    }\n    return factor\n}\n// console.log(factorial(0))\n\n\nfunction factorialRecurse(number) {\n    if (number === 0 || number === 1) {\n        return 1;\n    }\n    return number * factorialRecurse(number - 1);\n}\n// console.log(factorialRecurse(0))\n\n\n\n//    - Calcular el valor de un elemento concreto (según su posición) en la sucesión de Fibonacci (la función recibe la posición).\nfunction Fibonacci(number) {\n    let a = 0\n    let b = 1\n    let c = a + b\n    let counter = 0\n    let sequence = []\n    while (counter < number) {\n\n        if (counter == 0) {\n            sequence.push(a, b)\n        } else {\n            sequence.push(c)\n            a = b\n            b = c\n            c = a + b\n        }\n        counter++\n    }\n    return sequence\n}\n\n// console.log(Fibonacci(10))\n\nfunction FibonacciRecursive(positionNumber) {\n    if (positionNumber == 0) {\n        return 0\n    }\n    if (positionNumber == 1) {\n        return 1\n    }\n\n    return FibonacciRecursive(positionNumber - 1) + FibonacciRecursive(positionNumber - 2)\n}\n\nconsole.log(FibonacciRecursive(5))\n\n/* Logic\n    F(2) = F(1) + F(0) = 1 + 0 = 1\n    F(3) = F(2) + F(1) = 1 + 1 = 2\n    F(4) = F(3) + F(2) = 2 + 1 = 3\n    F(5) = F(4) + F(3) = 3 + 2 = 5\n*/"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/cesar-ch.js",
    "content": "// #06 RECURSIVIDAD\n\nfunction imprimirNumeros(contador) {\n    if (contador < 0) {\n        return;\n    } else {\n        console.log(contador);\n        contador--;\n        imprimirNumeros(contador);\n    }\n}\n\nimprimirNumeros(100);\n\n// Dificultad Extra\n\nfunction factorial(numero) {\n    if (numero === 0) {\n        return 1;\n    } else {\n        return numero * factorial(numero - 1);\n    }\n}\nconsole.log(factorial(5)); // 120\n\nfunction fibonacci(numero) {\n    if (numero < 1) {\n        console.log(\"El número debe ser mayor o igual a 1\");\n    } else if (numero === 1) {\n        return 0;\n    } else if (numero === 2) {\n        return 1;\n    } else {\n        return fibonacci(numero - 1) + fibonacci(numero - 2);\n    }\n}\n\nconsole.log(fibonacci(8)); // 13"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/christian-jfr.js",
    "content": "// #06 RECURSIVIDAD\n\n/**\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n */\n\nfunction toZero(num) {\n\tif (num < 0) {\n\t\treturn;\n\t} else {\n\t\tconsole.log(num);\n\t\t// num = num - 1;\n\t\treturn toZero(num - 1);\n\t}\n}\n\ntoZero(100);\n\n/** DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n */\nfunction nFactorial(num) {\n\tif (num === 0 || num === 1) {\n\t\treturn 1;\n\t} else {\n\t\treturn num * nFactorial(num - 1);\n\t}\n}\n\nnFactorial(4);\nnFactorial(0);\nnFactorial(1);\nnFactorial(10);\n\n/** - Calcular el valor de un elemento concreto (según su posición) en la\n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\nconst fibonacci = (position) => {\n\tif (position === 0) {\n\t\treturn 0;\n\t} else if (position === 1) {\n\t\treturn 1;\n\t} else {\n\t\treturn fibonacci(position - 1) + fibonacci(position - 2);\n\t}\n};\n\nfibonacci(0);\nfibonacci(1);\nfibonacci(10);\nfibonacci(26);\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/cmejiajulian.js",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n */\n\nlet recursividad = (numero) =>{\n\n    if (numero>=0){\n        console.log(numero)\n        recursividad(numero-1)\n    }\n}\n\nrecursividad(100);\n\n/*\n\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\nlet factorial =(n)=>{\n\n    if(n===0){\n         return 1\n    } \n    else {\n         return n*factorial(n-1)}\n    }\n\n\nconsole.log(factorial(1));\n\n\nlet fib = (number) =>{\n    if (number<=0){\n        console.log('Los numeros negativos no son validos');\n        return 0\n    }\n    else if (number==1){\n        return 0\n    }\n    else if (number==2) {\n        return 1\n    }\n    else {\n        return fib(number-1)+fib(number-2)\n    }\n}\n\nconsole.log(fib(10));"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/duendeintemporal.js",
    "content": "/*   #06 Recursividad  */\n//I use Eloquent Javascript A Modern Introduction to Programming by Marijn Haverbeke for concepts reference.\n//I also use Professional JavaScript for web developers by Matt Frisbie.\n//and GPT\n\n// short for console.log()\nlet log = console.log.bind(console);\n\n//A recursive function typically is formed when a function calls itself by name\n\nconst countBack = (n)=>{\n    log(n);\n    if(n == 0) return;\n    return countBack(n - 1);\n}\n\nlog(countBack(100))\n\n\n// without recursion\n\nconst power_v1 = (base, exponent)=> {\n   let result; \n    (exponent == 0)? result = 1 : result = base;\n    for(let i = 2; i <= exponent; i++){\n        result *=  base; \n    }\n    return result;\n} \n\nlog(power_v1(4,3)); // 64\n\n// with recursion\n\nconst power = (base, exponent)=> {\n    if (exponent == 0) {\n        return 1;\n    } else {\n        return base * power(base, exponent - 1);\n    }\n}\n\nlog(power(4, 3)); // 64\n\n/*This is rather close to the way mathematicians define exponentiation and\narguably describes the concept more clearly than the looping variant. The\nfunction calls itself multiple times with ever smaller exponents to achieve the\nrepeated multiplication.\n\nBut this implementation has one problem: in typical JavaScript implementa-\ntions, it’s about three times slower than the looping version. Running through\na simple loop is generally cheaper than calling a function multiple times. \n\nIn the case of the power function, the inelegant (looping) version is still fairly\nsimple and easy to read. It doesn’t make much sense to replace it with the\nrecursive version\n*/\n\n//Extra dificulty exercises\n\nconst factorial = (n)=>{\n    if(n <= 1) return 1;\n    return n * factorial(n - 1);\n}\n\nlog(factorial(5))// 120\n\n//this function return the serie fibonacci until the number passed as parameter\nconst fibonacciSerie = (n, a = 0, b = 1)=> {\n    if (a > n) {\n        return [];\n    } else {\n        return [a].concat(fibonacciSerie(n, b, a + b));\n    }\n}\n\n\nlog(fibonacciSerie(17)); // Array(8) [ 0, 1, 1, 2, 3, 5, 8, 13 ]\n\n//this function return the number equivalent to the possition in the fibonacci serie\n\nconst fibonacciNum = (n)=> {\n    if (n === 0) {\n        return 0;\n    }\n    if (n === 1) {\n        return 1;\n    }\n    return fibonacciNum(n - 1) + fibonacciNum(n - 2);\n  }\n\n  log(fibonacciNum(17))// 1597\n\n/*Note: The recursive version with memoization is more efficient than the simple recursive one, as it avoids redundant calculations. However, it still uses the call stack, which can be a problem for very large values of a.*/\n\nconst fibonacciNumMemo = (n, memo = {})=> {\n    if (n in memo) {\n        return memo[n];\n    }\n    if (n === 0) {\n        return 0;\n    }\n    if (n === 1) {\n        return 1;\n    }\n    memo[n] = fibonacciNumMemo(n - 1, memo) + fibonacciNumMemo(n - 2, memo);\n    return memo[n];\n}\n\nlog(fibonacciNumMemo(17)); // 1597\n\n\n\n/* The iterative approach is generally more efficient in terms of time and space, as it does not use the call stack of recursion. */\n\nconst iterativeFibonacci = (n)=> {\n    if (n === 0) return 0;\n    if (n === 1) return 1;\n\n    let a = 0;\n    let b = 1;\n    let resultado;\n\n    for (let i = 2; i <= n; i++) {\n        resultado = a + b;\n        a = b;\n        b = resultado;\n    }\n    return resultado;\n}\n\nlog(iterativeFibonacci(4222)); // infinity\nlog(iterativeFibonacci(453))// 2.0985341020594266e+94  \n\n\n\nwindow.addEventListener('load', ()=>{\n    const body = document.querySelector('body');\n    const title = document.createElement('h1');\n    \n    body.style.setProperty('background', '#000');\n    body.style.setProperty('text-align', 'center');\n    \n    title.textContent = 'Retosparaprogramadores #6.';\n    title.style.setProperty('font-size', '3.5vmax');\n    title.style.setProperty('color', '#fff');\n    title.style.setProperty('line-height', '100vh');\n    \n    body.appendChild(title);\n    \n    setTimeout(()=>{\n    alert('Retosparaprogramadores #6. Please open the Browser Developer Tools.');\n    }, 2000);\n    log( 'Retosparaprogramadores #6'); \n});"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/edalmava.js",
    "content": "function recursiva(num) {    \n  if (num >= 0) {\n      console.log(num)      \n      recursiva(--num)\n  } else {      \n      return 0\n  }\n}\n\nrecursiva(10)\n\nfunction factorial(num) {    \n    return (num === 1) ? 1 : num * factorial(num - 1)    \n}\n\nconsole.log(factorial(6))\n\nfunction fibonacci(posicion) {\n    if (posicion === 0) return 0\n    else if (posicion === 1) return 1\n    else return fibonacci(posicion - 1) + fibonacci(posicion - 2)   \n}\n\nconsole.log(fibonacci(8))\n\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/emedevelopa.js",
    "content": "//Recursividad\n\nfunction numeros (n) {\n    if (n < 0) {\n        return;\n    }\n    console.log(n);\n    numeros (n - 1);\n}\n\nnumeros(100);\n\n//Extra\n\nfunction factorial (num) {\n    if (num === 0) {\n        return 1;\n    }\n    return num * factorial (num - 1);\n} \nconsole.log(factorial(5));"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/estuardodev.js",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\nfunction numeros(n){\n    if(n<0){\n        return;\n    }\n\n    console.log(n);\n    numeros(n-1);\n}\n\nnumeros(100);\n\nfunction factorial(n){\n    if (n < 0){\n        return 0;\n    } else if (n==0){\n        return 1;\n    } else{\n        return n * factorial(n - 1);\n    }\n}\n\nfactorial(5);\n\nfunction fibonacci(posicion){\n    if (posicion <= 0){\n        return 0;\n    } else if (posicion == 1){\n        return 0;\n    } else if (posicion == 2){\n        return 1;\n    } else{\n        return fibonacci(posicion - 1) + fibonacci(posicion - 2)\n    }\n}\n\nfibonacci(5)"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/eulogioep.js",
    "content": "// Función recursiva para imprimir números del 100 al 0\nfunction imprimirNumeros(numero) {\n    // Caso base: si el número es menor que 0, terminamos la recursión\n    if (numero < 0) {\n        return;\n    }\n    \n    // Imprimimos el número actual\n    console.log(numero);\n    \n    // Llamada recursiva con el número decrementado\n    imprimirNumeros(numero - 1);\n}\n\n/**\n * Función recursiva para calcular el factorial de un número.\n * @param {number} n - El número del cual calcular el factorial.\n * @return {number} El factorial del número.\n */\nfunction factorial(n) {\n    // Casos base: factorial de 0 y 1 es 1\n    if (n === 0 || n === 1) {\n        return 1;\n    }\n    \n    // Llamada recursiva: n * factorial(n-1)\n    return n * factorial(n - 1);\n}\n\n/**\n * Función recursiva para calcular el valor de un elemento en la sucesión de Fibonacci.\n * @param {number} posicion - La posición del elemento en la sucesión de Fibonacci.\n * @return {number} El valor del elemento en la posición dada.\n */\nfunction fibonacci(posicion) {\n    // Casos base: posiciones 0 y 1 de Fibonacci son 0 y 1 respectivamente\n    if (posicion === 0) {\n        return 0;\n    }\n    if (posicion === 1) {\n        return 1;\n    }\n    \n    // Llamada recursiva: suma de los dos elementos anteriores\n    return fibonacci(posicion - 1) + fibonacci(posicion - 2);\n}\n\n// Pruebas de las funciones\nconsole.log(\"Números del 100 al 0:\");\nimprimirNumeros(100);\n\nconst numeroFactorial = 5;\nconsole.log(`\\nFactorial de ${numeroFactorial}: ${factorial(numeroFactorial)}`);\n\nconst posicionFibonacci = 7;\nconsole.log(`Elemento en la posición ${posicionFibonacci} de Fibonacci: ${fibonacci(posicionFibonacci)}`);"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/garos01.js",
    "content": "function imprimirNumerosDecrecientes(numero) {\n  // Caso base\n  if (numero < 0) {\n    return;\n  }\n\n  console.log(numero);\n\n  // Llamada recursiva\n  imprimirNumerosDecrecientes(numero - 1);\n}\n\n// Uso\nimprimirNumerosDecrecientes(100);\n\n// Ejercicio extra\n// Factorial\nfunction calcularFactorial(numero) {\n  if (numero === 0) {\n    return 1;\n  } else {\n    return numero * calcularFactorial(numero - 1);\n  }\n}\n\nconst numero = 5;\nconst factorial = calcularFactorial(numero);\n\nconsole.log(`El factorial de ${numero} es: ${factorial}`);\n\n// Posicion Fibonacci\nfunction fibonacci(posicion) {\n  if (posicion === 1 || posicion === 2) {\n    return 1;\n  } else {\n    return fibonacci(posicion - 1) + fibonacci(posicion - 2);\n  }\n}\n\nconst posicion = 10;\nconst valorEnPosicion = fibonacci(posicion);\n\nconsole.log(\n  `El valor en la posición ${posicion} de la sucesión de Fibonacci es: ${valorEnPosicion}`\n);\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/gianbordon.js",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\nconsole.group('Funcion Recursiva')\n\nfunction funcRec (n){\n    if(n >= 0){\n        console.log(n)\n        funcRec(n-1)\n    }\n}\nfuncRec(2)\n\nconsole.groupEnd()\n\n//\n// EXTRA\n//\n\nconsole.group('Funcion Recursiva Factorial')\n\nfunction factorial(n){\n    if( n === 0){\n        return 1\n    } else {\n        return n *= factorial(n-1)\n    }\n}\n\nconsole.log(factorial(100))\nconsole.groupEnd()\n\nconsole.group('Funcion Recursiva Fibonacci Number')\n\nfunction fibonacciPos(num, a = 0, b = 1, pos = 0) {\n    if (num === 0) {\n        return a;\n    } else {\n        return fibonacciPos(num - 1, b, a + b, pos + 1);\n    }\n}\n\nconsole.log(\"El número de Fibonacci en la posición 4 es: \", fibonacciPos(4)); \nconsole.groupEnd()"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/giovanyosorio.js",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\nlet cuentaAtras = numero => {\n    //base case\n    if (numero === 0) {\n        return;\n    }\n    console.log(numero);\n    return cuentaAtras(numero - 1);\n};\ncuentaAtras(100) // \n\nlet factorial = (numero) => {\n\n    if (numero < 0) {\n        return -1\n    }else if(numero ==0){\n      return 1\n    }else{\n      return (numero*factorial(numero-1))\n    }\n};\nfactorial(5)\n\nvar fib = function(n) {\n    if (n <= 1) return n;\n\n    return fib(n-1) + fib(n-2);\n}\n\nfib(8)"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/gonzadev28.js",
    "content": "// Entiende el concepto de recursividad creando una función recursiva\n// que imprima números del 100 al 0.\n\nfunction recursividad(n){\n    if (n < 0){\n        return;\n    }else{\n        console.log(n);\n        return recursividad(n -1);\n    }\n}\nrecursividad(100);\n\n// DIFICULTAD EXTRA (opcional):\n\n// Calcular el factorial de un número concreto (la función recibe ese número).\n\nfunction factorial(fac){\n    if (fac === 0){\n        return 1;\n    }else{\n        return fac * factorial(fac - 1);\n    }\n}\nconsole.log('---FACTORIAL---')\nconsole.log(factorial(9)); //9x8x7x6x5x4x3x2x1 = 362.880\n\n/* Calcular el valor de un elemento concreto (según su posición)\nen la sucesión de Fibonacci (la función recibe la posición).*/\n\nfunction fibonacci(num) {\n    if(num < 1){\n        console.log(\"Numero debe ser mayor o igual a 1\");\n    }else if(num === 1){\n        return 0;\n    }else if(num === 2){\n        return 1;\n    }else{\n        return fibonacci(num - 1) + fibonacci(num - 2);\n    }\n}\nconsole.log('---FIBONACCI---')\nconsole.log(fibonacci(5)); //0, 1, 1, 2, '3'"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/hectorio23.js",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\n\"use strict\";\n\n/***********************************************\n********** DECLARACION DE FUNCIONES ************\n************************************************/\nfunction recursiveFoo(valorInicial) {\n    // Función recursiva para imprimir números desde valorInicial hasta 0\n    if (valorInicial < 0) {\n        return;\n    }\n    console.log(valorInicial + \", \");\n    recursiveFoo(valorInicial - 1);\n}\n\nfunction factorial(ivalue) {\n    // Función recursiva para calcular el factorial de ivalue\n    if (ivalue === 1) {\n        return 1;\n    }\n    return ivalue * factorial(ivalue - 1);\n}\n\nfunction fibonacci(n) {\n    // Función recursiva para calcular el valor en la posición n de Fibonacci\n    if (n <= 0) {\n        console.log(\"La posición debe ser un entero positivo\");\n        return -1; // o manejo de error según sea necesario\n    } else if (n === 1) {\n        return 0;\n    } else if (n === 2) {\n        return 1;\n    } else {\n        let a = 0, b = 1, temp;\n        for (let i = 2; i < n; ++i) {\n            temp = b;\n            b = a + b;\n            a = temp;\n        }\n        return b;\n    }\n}\n\n/*************************************************\n******************* PROGRAMA PRINCIPAL **********\n**************************************************/\nconst numeroCalcularFactorial = 3;\nconst posicion = 10;\n\nconsole.log(\"********* NUMEROS DEL 100 - 0 *********\");\nrecursiveFoo(100);\nconsole.log(\"\\n\");\n\nconsole.log(`El factorial de <<${numeroCalcularFactorial}>> es: ${factorial(numeroCalcularFactorial)}`);\n\nconst valor = fibonacci(posicion);\nconsole.log(`El valor en la posición ${posicion} de la sucesión de Fibonacci es: ${valor}`);\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/jaxi86.js",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */ \n\nconsole.log(\"funcion recursiva del 100 a 0\");\nfunction recursiva (n) {\n    if (n >= 0){\n        console.log(n);\n        recursiva(n - 1);\n    }\n}\nrecursiva(100);\n\nconsole.log(\" \");\n\nconsole.log(\"dificultad extra\");\nfunction factorial (n) {\n    if(n === 0){\n        return 1;\n    }else {\n        return n * factorial(n - 1);\n    }\n}\nlet resultado1 = factorial(5);\nconsole.log(resultado1);\n\nfunction fibonacci(posicion) {\n    if (posicion === 1 ) {\n        return 0;\n    }else if (posicion === 2){\n        return 1;\n    }\n    else {\n    return fibonacci(posicion - 1) + fibonacci(posicion - 2);\n    }\n} \n\nconsole.log(fibonacci(5));\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/jeronimocardu.js",
    "content": "/** RECURSIVIDAD */\nfunction showNumber(number) {\n  if (number >= 0) {\n    console.log(number)\n    showNumber(number - 1)\n  }\n}\nshowNumber(5)\n\n/** FACTORIAL */\nfunction getFactorial(number) {\n  if (number < 0) {\n    console.log('The negative numbers are invalid')\n    return 0\n  }\n  if (number == 0) return 1\n  return number * getFactorial(number - 1)\n}\nconsole.log(getFactorial(5))\n\n/** FIBONACCI  */\nfunction getFibonacci(number) {\n  if (number == 0) return 0\n  if (number == 1) return 1\n  return getFibonacci(number - 1) + getFibonacci(number - 2)\n}\nconsole.log(getFibonacci(7))\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/jhoshmc.js",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n */\n\nfunction ejercicio() {\n  let numero = 100;\n  conteoRecursivo(numero);\n}\n\nfunction conteoRecursivo(numero) {\n  if (numero == 0) {\n    console.log(`numero: ${numero}`);\n    return;\n  }\n  if (numero > 0) {\n    console.log(`numero: ${numero}`);\n    return conteoRecursivo(numero - 1);\n  }\n}\n\nejercicio();\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la\n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\nfunction extra() {\n  let numeroFactorial = 5;\n  let posicionFibonacci = 6;\n  let resultadoFactorial = factorialRecursivo(numeroFactorial);\n  console.log(\"\\n\\t factorial de un numero \\n\");\n  console.log(\n    `el factorial del numero ${numeroFactorial}! es : ${resultadoFactorial}`\n  );\n  console.log(\"\\n\\t numero fibonacci \\n\");\n  let resultadoFibonacci = fibonacciRecursivo(posicionFibonacci);\n  console.log(\n    `el numero fibonacci en la posicion ${posicionFibonacci} es : ${resultadoFibonacci}`\n  );\n}\n\nfunction factorialRecursivo(numero) {\n  if (numero == 1) {\n    return 1;\n  }\n  if (numero >= 1) {\n    return numero * factorialRecursivo(numero - 1);\n  }\n}\n\nfunction fibonacciRecursivo(numero) {\n  if (numero == 0) return 0;\n  if (numero == 1) return 1;\n  return fibonacciRecursivo(numero - 1) + fibonacciRecursivo(numero - 2);\n}\n\nextra();\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/joapalobael.js",
    "content": "console.log('----- Recursividad -----');\nfunction recursividad(num) {\n    if (num < 0){\n        return;\n    }\n    console.log(num)\n    recursividad(num - 1);\n}\n\nrecursividad(100);\n/*\n* DIFICULTAD EXTRA (opcional):\n* Utiliza el concepto de recursividad para:\n* - Calcular el factorial de un número concreto (la función recibe ese número).\n* - Calcular el valor de un elemento concreto (según su posición) en la \n*   sucesión de Fibonacci (la función recibe la posición).\n*/\n\nconsole.log('----- Factorial -----');\nfunction factorial(n) {\n    if(n === 0){\n        return 1; // 0! = 1 por definición\n    }\n    \n    return(n*factorial(n-1));\n}\n\nconsole.log(factorial(9))\n\nconsole.log('----- Fibonacci -----');\n\nfunction fibonacci (f){\n    if (f === 0){\n        return 0;\n    }\n    if (f === 1){\n        return 1;\n    }\n    if( f > 1){\n        return fibonacci(f-1)+fibonacci(f-2);\n    }\n}\nconsole.log(fibonacci(6));"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/juandaherrera.js",
    "content": "function printSep(title = null) {\n    const sep = \"-\";\n    const printVar = title ? sep.repeat(8) + title + sep.repeat(8) : sep.repeat(16);\n    console.log(printVar);\n}\n\n/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n */\n\nfunction myFunction(n) {\n    if (n === 0) {\n        console.log(0);\n    } else {\n        console.log(n);\n        myFunction(n - 1);\n    }\n}\n\nprintSep(\"Ejercicio\");\n\nmyFunction(100);\n\n/*\n* DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\n// Factorial de un número\nfunction factorial(n) {\n    if (n === 1) {\n        return 1;\n    } else {\n        return n * factorial(n - 1);\n    }\n}\n\nprintSep(\"Factorial\");\n\nconsole.log(factorial(9));\n\n// Calcular valor de elemento en la sucesión de fibonacci\nfunction fibonacci(position) {\n    /*\n    Esta función tiene complejidad algorítmica de O(2^n).\n    Es decir que es muy ineficiente para valores grandes de position\n    */\n    if (position === 1 || position === 2) {\n        return position - 1;\n    } else {\n        return fibonacci(position - 1) + fibonacci(position - 2);\n    }\n}\n\nprintSep(\"Fibonacci\");\n\nconsole.log(fibonacci(15));\n\nprintSep();\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n_______________________________________\n#06 RECURSIVIDAD\n---------------------------------------\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n*/\n\n// ________________________________________________________\nfunction num(n) {\n    console.log(n);\n    // Base case\n    if (n > 0) {\n        num(n - 1);\n    }\n}\nnum(100);\n\n// ________________________________________________________\n// DIFICULTAD EXTRA\n\n// Calcular el factorial de un número concreto\n// 4! = 4 * 3 * 2 * 1 = 24\nfunction factorial(n) {\n    if (n !== 0) {\n        return n * factorial(n - 1);\n    } else {\n        return 1;\n    }\n    /* explicación:\n    factorial(4)\n        | = 24 \n     return 4 * factorial(3) -> (4 * 6)\n                  | = 6 \n         return 3 * factorial(2) -> (3 * 2)\n                      | = 2 \n             return 2 * factorial(1) -> (2 * 1)\n                          | = 1 \n                 return 1 * factorial(0) -> (1 * 1)\n                              | = return 1 -> base case\n    */\n}\n\n// Calcular el valor de un elemento concreto (según su posición) en la sucesión de Fibonacci.\n// n : |0|1|2|3|4|5|6|..\n// fb: |0|1|1|2|3|5|8|..\n//      |+|=^   |+|=^ ..\nfunction fibonacci(n) {\n    if (n <= 1) {\n        return n;\n    } else {\n        return fibonacci(n - 1) + fibonacci(n - 2);\n        /* explicación:\n                            return 3\n                  fibonacci(3)      / \\    fibonacci(2)\n                   / \\ =2      +      / \\ =1\n             fibonacci(2) + fibonacci(1)    fibonacci(1) + fibonacci(0) -> base case\n              / \\ =1\n        fibonacci(1) + fibonacci(0) -> base case\n        */\n    }\n}\n\nconsole.log(`Factorial de 4: \\n${factorial(4)}`);\nconsole.log(`Valor según posición 4 en Fibonacci:\\n${fibonacci(4)}`);\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/kodenook.js",
    "content": "\n/**\n * The function \"recursion\" recursively logs numbers starting from the input number until reaching 0.\n * @param number - The `recursion` function takes a parameter `number`, which is used to control the\n * recursion. The function will log the value of `number` and then recursively call itself with\n * `number` decremented by 1, until `number` is no longer greater than 0.\n */\nfunction recursion(number) {\n    console.log(number)\n    if (number > 0) {\n        recursion(--number)\n    }\n}\n\nrecursion(100)\n\n/*\n    Exercise\n*/\n\n/**\n * The factorial function calculates the factorial of a given number recursively.\n * @param number - The `number` parameter in the `factorial` function represents the integer for which\n * you want to calculate the factorial. It is the input value for which the factorial will be computed.\n * @param [result=1] - The `result` parameter in the `factorial` function is used to keep track of the\n * intermediate result as the factorial calculation progresses through recursive calls. It starts with\n * a default value of 1 and gets updated with the multiplication of `number` and the current `result`\n * in each recursive call.\n */\nfunction factorial(number, result = 1) {\n\n    if (number > 1) {\n        factorial(number - 1, number * result)\n    } else {\n        console.log(result)\n    }\n}\n\nfactorial(5)\n\n/**\n * The function calculates the Fibonacci number at a given position using recursion.\n * @param position - The `position` parameter in the `fibonacci` function represents the position of\n * the Fibonacci number in the sequence that you want to calculate. For example, if `position` is 5,\n * the function will return the 5th Fibonacci number in the sequence.\n * @returns the value of the Fibonacci sequence at the specified position.\n */\nfunction fibonacci(position) {\n    if (position > 2) {\n        return fibonacci(position - 1) + fibonacci(position - 2)\n    } else {\n        return 1\n    }\n}\n\nconsole.log(fibonacci(7))\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/marcode24.js",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la\n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\n// Función recursiva para imprimir números del 100 al 0\nfunction imprimirNumeros(num) {\n  if (num < 0) {\n    return;\n  }\n  console.log(num);\n  imprimirNumeros(num - 1);\n}\n\nconsole.log('Imprimiendo números del 100 al 0:');\nimprimirNumeros(100);\n\n// Función recursiva para calcular el factorial de un número\nfunction factorial(n) {\n  if (n === 0 || n === 1) {\n    return 1;\n  }\n  return n * factorial(n - 1);\n}\n\nconst numero = 5;\nconsole.log(`Factorial de ${numero}:`, factorial(numero));\n\n// Función recursiva para calcular el valor de un elemento en la sucesión de Fibonacci\nfunction fibonacci(n) {\n  if (n <= 1) {\n    return n;\n  }\n  return fibonacci(n - 1) + fibonacci(n - 2);\n}\n\nconst posicion = 6;\nconsole.log(`Valor en la posición ${posicion} de la sucesión de Fibonacci:`, fibonacci(posicion));\n\n// Visita mi repo en GitHub para ver y correr los tests de este código --> https://github.com/marcode24/weekly-challenges\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/maximiliano1997.js",
    "content": "/*\r\n* EJERCICIO:\r\n * Entiende el concepto de recursividad creando una función recursiva que imprima\r\n * números del 100 al 0.\r\n *\r\n*/\r\n\r\n// SOLUCION:\r\n\r\nfunction recursiv(num) {\r\n    if (num < 0) {\r\n        console.log('Already 0')\r\n        return;\r\n    }\r\n\r\n\r\n    console.log(num)\r\n    recursiv(num - 1)\r\n}\r\n\r\nrecursiv(100)\r\n\r\n\r\n\r\n/*\r\n DIFICULTAD EXTRA (opcional):\r\n * Utiliza el concepto de recursividad para:\r\n * - Calcular el factorial de un número concreto (la función recibe ese número).\r\n * - Calcular el valor de un elemento concreto (según su posición) en la\r\n *   sucesión de Fibonacci (la función recibe la posición).\r\n*/\r\n\r\n// SOLUCION:\r\n\r\n// FACTORIAL\r\nconst funcionFactorial = (factVal) => {\r\n    if (factVal == 0 || factVal == 1) {\r\n        return 1\r\n    }\r\n\r\n    return factVal * funcionFactorial(factVal - 1)\r\n}\r\n\r\nconsole.log(funcionFactorial(8))\r\n\r\n// FIBONACCI\r\nconst funcionFibonacci = (fibo) => {\r\n    if (fibo == 0 || fibo == 1) {\r\n        return 1;\r\n    }\r\n\r\n    return funcionFibonacci(fibo - 1) + funcionFibonacci(fibo - 2)\r\n}\r\n\r\nconsole.log(funcionFibonacci(4))"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/micendev.js",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\nfunction cuentaAtras(num) {\n    console.log(num);\n    if (num === 0) return;\n    return cuentaAtras(num - 1);\n}\n\ncuentaAtras(100);\n\n//Factorial\n\nfunction factorial(num) {\n\n    \n    if (num < 0) return 'Ingresa un número positivo';\n    if (num === 0) return 1;\n    return num * factorial(num - 1);\n}\n\nconsole.log(factorial(4));\n\n//Fibonacci\n\nfunction fibonacci(num) {\n\n    if (num < 0) return 'Ingresa un número positivo';\n    if (num === 0) return 0;\n    if (num === 1) return 1;\n    return fibonacci(num - 1) + fibonacci(num - 2);\n}\n\nconsole.log(fibonacci(10));"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/miguelex.js",
    "content": "function sumaRecursiva(a, b) {\n  if (b === 0) {\n    return a;\n  }\n  return sumaRecursiva(a + 1, b - 1);\n}\n\nconsole.log(\"La suma de 3 + 5 usando recursividad es = \" + sumaRecursiva(3, 5));\n\nfunction potenciaRecursiva(a, b) {\n  if (b === 0) {\n    return 1;\n  }\n  return a * potenciaRecursiva(a, b - 1);\n}\n\nconsole.log(\"El resultado de 2 elevado a 3 es: \" + potenciaRecursiva(2, 3));\n\nfunction imprimirNumeros(numero) {\n  if (numero >= 0) {\n    console.log(numero);\n    imprimirNumeros(numero - 1);\n  }\n}\n\nconsole.log(\"De 100 a 0 usando rercursividad: \");\nimprimirNumeros(100);\n\n// Extra\n\nfunction factorialRecursivo(a) {\n  if (a === 0) {\n    return 1;\n  }\n  return a * factorialRecursivo(a - 1);\n}\n\nconsole.log(\"El factorial de 5 es: \" + factorialRecursivo(5));\n\nfunction fibonacciRecursivo(a) {\n  if (a === 0) {\n    return 0;\n  }\n  if (a === 1) {\n    return 1;\n  }\n  return fibonacciRecursivo(a - 1) + fibonacciRecursivo(a - 2);\n}\n\nconsole.log(\"El fibonacci de 6 es: \" + fibonacciRecursivo(6));\n\nconsole.log(\n  \"A continuación, vamos a probar las funciones factorial y fibonacci de forma interactiva\"\n);\n\nconst readline = require(\"readline\");\n\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout,\n});\n\nrl.question(\"Introduce un número para calcular su factorial: \", (answer) => {\n  console.log(`El factorial de ${answer} es: ${factorialRecursivo(answer)}`);\n  rl.question(\n    \"Introduce un número para calcular su secuencia Fibonacci: \",\n    (numero) => {\n      console.log(\n        `La secuencia Fibonacci de ${numero} es: ${fibonacciRecursivo(numero)}`\n      );\n      rl.close();\n    }\n  );\n});\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/natalyjoanna.js",
    "content": "\n\n\nlet cuentaAtras = num => {\n  // Cuando parar\n  if(num === 0) return 1;\n\n  console.log(num);\n  return cuentaAtras(num-1);\n}\n\n//cuentaAtras(100)\n\n// DIFICULTAD EXTRA\n\n// Calcular el factorial de un número concreto\nlet factorial = num => {\n  if(num < 0) {\n    console.log('No se aceptan numeros negativos')\n    return 0;\n  } else if (num === 0) { \n    return 1\n  } else {\n    console.log(num);\n    return num * factorial(num-1);\n  }\n}\n\n//console.log(factorial(5))\n\n// Calcular el valor de un elemento concreto (según su posición) en la sucesión de Fibonacci\n\nlet fibonacci = num => {\n  if (num <= 0) {\n    console.log('No se aceptan numeros negativos, ni el 0')\n    return 0;\n  } else if (num === 1) {\n    return 0;\n  } else if (num === 2) {\n    return 1;\n  } else {\n    return fibonacci(num-2) + fibonacci(num-1)\n  }\n}\n\nconsole.log(fibonacci(3))"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/nlarrea.js",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\n\nconst printNumbers = number => {\n    console.log(number);\n\n    if (number === 0) {\n        return;\n    }\n\n    printNumbers(number - 1);\n};\n\nprintNumbers(100);\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\n\nconst factorial = number => {\n    if (number < 0) {\n        console.log('Only positive numbers.');\n        return -1;\n    } else if (number === 0) {\n        return 1;\n    }\n\n    return number * factorial(number - 1);\n};\n\nconsole.log('\\nFactorial:');\nconst number = 4;\nconsole.log(`${number}! = ${factorial(number)}`);           // 24\nconsole.log(`${number + 1}! = ${factorial(number + 1)}`);   // 120\n\n\nconst fibonacci = position => {\n    if (position <= 0) {\n        console.log('Only positive numbers.');\n        return -1;\n    } else if (position === 1) {\n        return 0;\n    } else if (position === 2) {\n        return 1;\n    }\n\n    return fibonacci(position - 1) + fibonacci(position - 2);\n};\n\nconsole.log('\\nFibonacci:');\nconsole.log(`The Fibonacci in position 3 is: ${fibonacci(3)}`);     // 1\nconsole.log(`The Fibonacci in position 7 is: ${fibonacci(7)}`);     // 8"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/ocram1304.js",
    "content": "/*Recursividad Es aquella propiedad que posee una función para llamarse así misma, funciona como una alternativa a la iteración. \nLos subprogramas recursivos -funciones- son aquellos que pueden llamarse así mismos de manera indirecta o directa.\n\nTipos de recursión\nLa recursión puede darse de dos maneras: directa e indirecta. En el código de una recursión directa el subprograma recursivo\nF tiene una sentencia que invoca a F, mientras que una recursión indirecta el subprograma F  invoca al subprograma G y este a su \nvez invoca a P así sucesivamente hasta que se invoca de nuevo a F.\n\nCondición de terminación \nPara que un algoritmo recursivo sea correcto este no debe de  generar una secuencia infinita de llamadas sobre sí mismo, pues cualquier \nalgoritmo que ejecute esto no terminará nunca. Por ello la definición recursiva debe de tener un componente base (una condición de salida) en \nel que una función f(n) se define directamente (es decir no recursiva) para un o más valores de n\n*/\n\n//Generar numeros del 1 al 100 de manera recursiva\nfunction genera(num){\n    \n    num+=1;\n    console.log(num)\n    if(num === 100){ //Caso base (condición de terminación)\n        return \"Se ha terminado de imprimir\";\n    }\n\n    return genera(num);//LLamada recursiva\n\n}\nconsole.log(genera(0))\n\n//Dificultad extra\nfunction factorial (n){\n    //Verifiacar que el argumento es valido. Quea sea un número entero\n    if (typeof n !== 'number' || n < 0 || !Number.isInteger(n)) {\n        return \"Entrada inválida. El número debe ser un entero no negativo.\";\n    } \n\n    if(n === 0){ //Caso base, si \"n\" es igual a cero, se concluye la llamada recursiva y se regreesa el caso base\n                 //El factorial de 0 es 1, es de dónde se empieza a calcular el factorial\n        return 1;\n    }\n    return n*factorial(n-1)\n\n}\nconfirm.log(factorial(4));\nfunction fibonacci(posicion) {\n    if (posicion === 0 || posicion === 1) { //Caso base\n      return posicion;\n    } else {\n      return fibonacci(posicion - 1) + fibonacci(posicion - 2);//Suma valores en las posicio-1 y piscion-2\n    }\n  }\n  \n  console.log(fibonacci(25)); // Debería imprimir el 25º valor en la secuencia Fibonacci\n  \n\n\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/oleojake.js",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.*/\n\nfunction countDown(number){\n    \n    if (number == 0){\n        console.log(number);\n        console.log(\"Fin de la Cuenta Atrás\");\n        return;\n    }\n    else {\n        console.log(number);\n        countDown(number-1);\n    }\n}\ncountDown(100);\n\n/* DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n */\nfunction factorialRecursivo (limit) {\n    if (limit == 0 || limit == 1){\n        return 1;\n    } else {\n        return limit * factorialRecursivo(limit-1);\n    }\n}\n\n/* - Calcular el valor de un elemento concreto (según su posición) en la \n*  - sucesión de Fibonacci (la función recibe la posición).*/\n// fibonacci(6) -> 8 (0, 1, 1, 2, 3, 5, 8)\nfunction fib (limit) {\n    if (limit == 0) {\n        return 0;\n    } else if (limit == 1) {\n        return 1;\n    } else {\n        return fib(limit-2) + fib(limit-1);\n    }\n}\n\nfunction printArrayFib(number){\n    let myArray = new Array ();\n    for (let i = 0; i <= number; i ++){\n        myArray.push(fib(i));\n    }\n    return myArray;\n}\n\n\n// INTERFACE\nconst readline = require(\"readline\");\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout,\n});\n\nrl.question(\"Introduce un número para calcular su factorial: \", (number) => {\n    console.log(\"El factorial de \" + number + \" es: \" + factorialRecursivo(number));\n    rl.question(\"Introduce la posición de un elemento para conocer su valor en la succesión fibonnaci: \", (numfib) => {\n        console.log(\"Para la posición \" + numfib + \" su valor es: \" + fib(numfib));\n        console.log(\"La sucesión es la siguiente: \"+ printArrayFib(numfib));\n        rl.close();\n    });\n});"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/othamae.js",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\nfunction recursivePrint(number) {\n    console.log(number)\n    if (number === 0) return\n    return recursivePrint(number - 1)\n}\n\nrecursivePrint(100)\n\n// EXTRA TASK:\n\nfunction factorial(number) {\n    if (number === 0) return 1\n    return number * factorial(number - 1)\n}\n\nconsole.log(factorial(5)) //120\n\nfunction fibonacci(number) {\n    if (number === 0) return 0\n    if (number === 1) return 1\n    return fibonacci(number - 1) + fibonacci(number - 2)\n}\n\nconsole.log(fibonacci(8))"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/parababire.js",
    "content": "//Cuenta regresiva por recursión\n\nlet cuentaRegresiva = numero => {\n  //Base case: donde finaliza la función de llamarse así misma.\n  if (numero >= 0) {\n    console.log(numero);\n    cuentaRegresiva(numero - 1);\n  }\n}\ncuentaRegresiva(100);\n\n//Extra\n\n/*Número factorial*/\nlet factorial = n => {\n  if (n < 0) {\n    return -1;\n  } else if (n === 0) {\n    return 1;\n  } else {\n    return n * factorial(n - 1);\n  }\n}\n\nconsole.log(factorial(5));\n\n/*Fibonachi*/\nlet fibNum = n => {\n  if (n <= 0) {\n    return \"Posición no valida\";\n  } else if (n === 1) {\n    return 0;\n  } else if (n === 2) {\n    return 1;\n  } else {\n    return fibNum(n - 1) + fibNum(n - 2);\n  }\n}\nconsole.log(fibNum(7));"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/pedamoci.js",
    "content": "// ------------------------------- EJERCICIO -------------------------------\n// function recursiva(cant) {\n//   let i = cant\n//   if (i >= 0){\n//     console.log(i)\n//     i--\n//     recursiva(i)\n//   }\n// }\n// recursiva(100)\n\n// ---------------------------- DIFICULTAD EXTRA ----------------------------\nlet vFactorial = 0\nfunction factorial(num) {\n  vFactorial = vFactorial + num\n  num--\n  if (num !== 0 ) {\n    factorial(num)\n  }\n}\n\nlet posicion = 0\nlet default1 = 0\nlet default2 = 1\nfunction fibonacci(pos) {\n  if (posicion !== pos) {\n    posicion++\n    (posicion % 2 === 0) ? default2 = default1 + default2\n                          : default1 = default1 + default2\n    fibonacci(pos)\n  }\n}\n\nfunction calcular() {\n  let operation = prompt('Que desea calcular factorial o fibonacci').toLowerCase()\n  do {\n    if (operation === 'y'|| operation === 's') operation = prompt('Que desea calcular factorial o fibonacci').toLowerCase()\n    switch (operation) {\n      case 'factorial':\n        let num = prompt('Ingrese el valor del que desee calcular el factorial')\n        factorial(parseInt(num))\n        alert(`El valor de ${num}! es: ${vFactorial}`)\n        break;\n      case 'fibonacci':\n        let pos = prompt('Ingrese la posición de fibonacci que desea averiguar (la secuencia inicia con los valores 0 y 1)' + \"\\n\" + \n                          `posición 1 = 1 --> (0 + 1)` + \"\\n\" + `posición 2 = 2 --> (1 + 1) ` + \"\\n\" + \n                          `posición 3 = 3 --> (2 + 1)` + \"\\n\" + `posición 4 = 5 --> (3 + 2)`\n        )\n        fibonacci(parseInt(pos))\n        alert(`El valor de fibonacci de la posicion ${pos} es ${ pos % 2 === 0 ? default2 : default1}`)\n        break;\n      default:\n        alert('Operación no valida')\n        break;\n    }\n    operation = prompt('Deseas hacer otra operación? Y/N').toLowerCase()\n  } while (operation !== 'n')\n}\ncalcular()"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/popmaquin.js",
    "content": "\n/*---Recursividad---*/\nfunction imprimirN(num){\n    if (num>=0){\n        console.log(num);\n        return imprimirN(num-1)\n    }\n     \n}\nimprimirN(5);\n\n//---Dificulta extra\nfunction factorial(numero){\n    if (numero==0){\n        return 1;\n    }else if(numero<0){\n        return -1;\n    }else{\n        return (numero*factorial(numero-1));\n    }\n}\n\nconsole.log(factorial(5)); //120\n\n    //---Sucesion de fibonacci\n    function fibonacci(num){\n        if(num<2){\n            return num;\n        }else{\n            return ((fibonacci(num-1)+fibonacci(num-2)))\n        }\n    }\n\n    console.log(fibonacci(10));"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/qwik-zgheib.js",
    "content": "/* -- exercise */\nconst printNumbers = (n) => {\n  if (n < 0) return;\n\n  console.log(n);\n  printNumbers(n - 1);\n};\n\nprintNumbers(100);\n\n/* -- extra challenge */\nconst factorial = (n) => (n === 0 ? 1 : n * factorial(n - 1));\n\nlet number = 5;\nconsole.log(\"Factorial of\", number, \"is\", factorial(number));\n\nconst fibonacci = (n) => (n === 0 ? 0 : n === 1 ? 1 : fibonacci(n - 1) + fibonacci(n - 2));\n\nlet position = 7;\nconsole.log(\"Fibonacci number at position\", position, \"is\", fibonacci(position));\n\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/saicobys.js",
    "content": "/* Concepto de Recursividad */\n\nfunction imprimirNumerosDescendente(numero) {\n  if (numero >= 0) {\n    console.log(numero);\n    imprimirNumerosDescendente(numero - 1);\n  }\n}\n\nimprimirNumerosDescendente(100);\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/seandsun.js",
    "content": "/**\n * <-------------- Recursividad -------------->\n * Básicamente la recursión es una función llamándose a sí misma, hasta que llega un punto en que debe parar. Para indicarle a la función\n * recursiva que debe detenerse, le debemos definir un \"caso base\", o sea, una condición de salida o fin de la ejecución.\n*/\nfunction recursividad(numero) {\n    if(numero < 0) { // Caso base, o sea que NO se produce ninguna llamada recursiva\n        return\n    }\n    console.log(numero)\n    recursividad(numero-1)\n}\n\nrecursividad(100)\n\n/**\n * Lo que está sucediendo dentro de la función \"recursividad\" es:\n * 1. La entrada actual es 100\n * 2. ¿ 100 es igual a 0 ? (este es el CASO BASE, o sea la condición que terminará la ejecución de la función)\n * 3. No, entonces imprime 100 por consola\n * 4. La función se llama a sí misma otra vez con el \"numero - 1\", o sea \"100 - 1\" = 99\n * 5. La nueva entrada principal es 99\n * 6. Nuevamente pregunta ¿ 99 es igual a 0 ?\n * 7. No, entonces imprime 99 por consola\n * 8. Y así se sigue repitiendo hasta que la entrada principal es 0, y de esa manera la función deja de llamarse a sí misma \n*/\n\n/**\n * <-------------- Dificultad extra: factorial -------------->\n * Multiplicación de todos los números enteros positivos que hay entre ese número y el 1. El factorial de 0 es 1.\n * Ejemplo: 4! = 4 * 3 * 2 * 1 = 24\n*/\nfunction factorial(numero)  {\n    if(numero === 0) { // Caso base, o sea que NO se produce ninguna llamada recursiva\n        return 1\n    } \n    return numero * factorial(numero-1)    \n}\n\nlet resultado = factorial(num = 4)\nconsole.log(`El factorial de ${num}! es: ${resultado}`) // 24\n\n/*\nEjecución de la función factorial:\n---------------------------------------------\n 4! = 4 * 3! retorna 24  // Este es el primer proceso que se abre, pero es el último en ejecutarse ya que a partir de este se abren los otros\n    --------------------------------------  \n    3! = 3 * 2! retorna 6\n        -------------------------------  \n        2! = 2 * 1! retorna 2\n            ------------------------ \n            1! = 1 * 0! retorna 1\n                ----------------\n                0! = 1 retorna 1  // Primero se resuelve este subproceso para pasarle el \"resultado\" al subproceso anterior\n*/\n\n/**\n * <-------------- Dificultad extra: fibonacci -------------->\n * Secuencia de números en la que después del 0 y del 1, cada numero de la serie se obtiene sumando los dos anteriores.\n * Ejemplo: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55...\n*/\nfunction fibonacci(posicion) {\n    if(posicion < 2) { // Caso base, o sea que NO se produce ninguna llamada recursiva\n        return posicion\n    } \n    return fibonacci(posicion - 2) + fibonacci(posicion - 1)\n}\n\nlet result = fibonacci(numPosicion = 4) \nconsole.log(`El valor de la posición ${numPosicion} en la secuencia Fibonacci es: ${result}`) // 3\n\n\n/*\nEjecución de la función fibonacci:\n---------------------------------------------\n pos4 = pos2(1) + pos3(2) retorna 3  // Este es el primer proceso que se abre, pero es el último en ejecutarse ya que a partir de este se abren los otros\n    --------------------------------------  \n    pos3 = pos1(1) + pos2(1) retorna 2\n        -------------------------------  \n        pos2 = pos0(0) + pos1(1) retorna 1 // Primero se resuelve este subproceso para pasarle el \"resultado\" al subproceso anterior\n            ------------------------ \n            pos1 = 1 retorna 1\n                ----------------\n                pos0 = 0   retorna 0  \n*/"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/shevotool.js",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n */\n\nfunction recursiva(numero) {\n  if (numero < 0) {\n    return;\n  }\n  console.log(numero);\n  recursiva(numero - 1);\n}\n\nrecursiva(100);\n\n/*  * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * */\nfunction calcularFactorial(numero) {\n  if (numero === 0 || numero === 1) {\n    return 1;\n  }\n  return numero * calcularFactorial(numero - 1);\n}\nconsole.log(calcularFactorial(5));\n\n/* \n - Calcular el valor de un elemento concreto (según su posición) en la\n *   sucesión de Fibonacci (la función recibe la posición).\n*/\nfunction calcularValorElemento(posicion) {\n  if (posicion === 0) return 0;\n  if (posicion === 1) return 1;\n\n  let anterior = 0;\n  let actual = 1;\n  for (let i = 2; i <= posicion; i++) {\n    let siguiente = anterior + actual;\n    anterior = actual;\n    actual = siguiente;\n  }\n  return actual;\n}\nconsole.log(calcularValorElemento(6));\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/victor-Casta.js",
    "content": "/*\n   * Entiende el concepto de recursividad creando una función recursiva que imprima\n   * números del 100 al 0.\n*/\n\nconst getNumbers = (number) => {\n  if (number < 0) {\n    return;\n  }\n  console.log(number);\n  return getNumbers(number - 1);\n};\n\nconsole.log(getNumbers(100));\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n  * Utiliza el concepto de recursividad para:\n  * - Calcular el factorial de un número concreto (la función recibe ese número).\n  * - Calcular el valor de un elemento concreto (según su posición) en la \n  *   sucesión de Fibonacci (la función recibe la posición).\n*/\n\nconst myFactorial = (number) => {\n  if(number === 0) {\n    return 1;\n  }\n  return number * myFactorial(number - 1)\n}\n\nconsole.log(myFactorial(5));\n\nconst fibonacci = (n) => {\n  // Caso base: primeros dos elementos de Fibonacci son 0 y 1\n  if (n === 0) {\n    return 0;\n  }\n  if (n === 1) {\n    return 1;\n  }\n  // Caso recursivo: Fibonacci(n) = Fibonacci(n - 1) + Fibonacci(n - 2)\n  return fibonacci(n - 1) + fibonacci(n - 2);\n};\n\n// Ejemplo: calcular el 7mo elemento en la sucesión de Fibonacci\nconsole.log(fibonacci(7)); // Output: 13\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/wapastorv.js",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n */\n\n/*function printNumbers(n) {\n    if (n >= 0) {\n        console.log(n);\n        printNumbers(n - 1);\n    }\n}\n\nprintNumbers(100);*/\n\n// factorial de un número especificado\n/*function factorial(n) {\n    if (n === 0) {\n        return 1;\n    }\n\n    return n * factorial(n - 1);\n}\n\nconsole.log(factorial(5)); // 120*/\n\n// Secuencia de fibonacci de un número especificado\nfunction fibonacci (n) {\n    if (n <= 1) {\n        return n;\n    }\n\n    return fibonacci(n - 1) + fibonacci(n - 2);\n}\n\nconsole.log(fibonacci(6)); // 8"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/wolffcode.js",
    "content": "\n/*\n* EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n*/\n        // recursividad\nfunction conteo(n){\n    if(n== 1){\n        return n\n    }else{\n        console.log(n)\n        return conteo(n-1)\n    }\n}\nconsole.log(conteo(100))\n\n\n\n        // dificultad extra\nfunction factorial(n){\n    if(n<= 1){\n        return 1\n    }else{\n        return n * factorial(n-1)\n    }\n}\nconsole.log(factorial(4))\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/javascript/xmunder.js",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la\n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\nconst printNumbers100to0 = (num) => {\n  if (num < 0) return;\n  console.log(num);\n  printNumbers100to0(num - 1);\n};\n\nprintNumbers100to0(10);\n\n// Dificultad extra\n\nconst factorial = (n) => {\n  if (n === 0 || n === 1) {\n    return 1;\n  } else {\n    return n * factorial(n - 1);\n  }\n};\n\nconsole.log(factorial(5));\n\nfunction fibonacci(n) {\n  if (n === 0) {\n    return 0;\n  } else if (n === 1) {\n    return 1;\n  } else {\n    return fibonacci(n - 1) + fibonacci(n - 2);\n  }\n}\n\nconsole.log(fibonacci(10));\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/kotlin/AnCarlu.kt",
    "content": "fun main() {\n    printNumbers()\n    println(\"Introduce un numero para calcular su factorial\")\n    var i = readln()\n    var x = i.toInt()\n    factorial(x)\n    println(\"El factorial de $x es ${factorial(x)}\")\n    println(\"Escribe el numero de la posicion en la succesion de Fibonacci que quieras saber \")\n    var z = readln()\n    var posicion = z.toInt()\n    println(\"Fibonnacci en posicion $posicion es ${fibonacci(posicion)}\")\n\n}\n\n//Funcion de recursividad que imprime numeros de 1 al 100\nfun printNumbers(n: Int = 1) {\n    if (n > 100) return\n    println(n)\n    printNumbers(n + 1)\n}\n\n//Dificultad Extra\n//Calcular el factorial de un numero\nfun factorial(i: Int): Long {\n    if (i <= 1) {\n        return 1\n    } else {\n        return i * factorial(i - 1)\n    }\n}\n\n//Calcular el valor en la posicion de fibonacci\nfun fibonacci(posicion: Int): Long {\n    return when (posicion) {\n        0 -> 0\n        1 -> 1\n        2 -> 1\n        else -> fibonacci(posicion - 1) + fibonacci(posicion - 2)\n    }\n}"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/kotlin/OcandoDev.kt",
    "content": "fun main() {\n\n    numberPrinter(100)\n\n    println()\n\n    val number = 6\n    val factorial = factorialNumber(number)\n    println(\"El factorial de $number es: $factorial\")\n\n    val fibonacciSequence = fibonacci(8)\n    println(fibonacciSequence)\n}\n\n// 100 -> 100 - 1 = 99 ...\nfun numberPrinter(value: Int){\n\n    if(value >= 0){\n        print(\"$value \")\n        numberPrinter(value - 1)\n    }\n}\n\n// 6!=1x2x3x4x5x6 = 720\n//6x5 = 30 -> 30x4 = 120 -> 120x3 = 360 -> 360x2 = 720\nfun factorialNumber(number: Int): Int{\n\n    if (number != 0) {\n        return number * factorialNumber(number - 1)\n    } else {\n        return 1\n    }\n}\n// 0,1,1,2,3,5,8,13,21...\nfun fibonacci(n: Int): Int {\n    if (n <= 1) {\n        return n\n    } else {\n        return fibonacci(n - 1) + fibonacci(n - 2)\n    }\n}"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/kotlin/VincentRodriguezR.kt",
    "content": "class recursion{\n    fun main(){\n        //Ejercicio de recursividad\n        fun printNumber(number:Int){\n            if(number >= 0){\n                println(number)\n                //La recrsividad es cuando una funcion se llama a si misma generando un bucle de ejecucion de si misma\n                printNumber(number - 1)\n            }\n        }\n\n        //Ejercicio Extra\n        fun factorial(number: Int): Int{\n            if(number<0){\n                println(\"El numero no es valido\")\n                return(0)\n            }else if(number == 0){\n                return(1)\n            }else{\n                return(number * factorial(number-1))\n            }\n        }\n\n        fun fibonacci(number: Int): Int{\n            if(number<0){\n                println(\"La posicion tiene que ser mayor que cero\")\n                return(0)\n            }else if(number == 1){\n                return(0)\n            }else if(number == 2){\n                return(1)\n            }else{\n                return (fibonacci(number-1)+fibonacci(number-2))\n            }\n        }\n\n        printNumber(100)\n        println(factorial(5))\n        println(fibonacci(4))\n\n    }\n\n    companion object {\n        @JvmStatic\n        fun main(args: Array<String>) {\n            val obj = recursion()\n            obj.main()\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/kotlin/adridoce.kt",
    "content": "fun main() {\n    println(funcionRecursiva(100))\n    println(factorial(5))\n    println(fibonacci(20))\n}\n\nfun funcionRecursiva(n: Int){\n    if(n > 0) funcionRecursiva(n-1)\n}\n\nfun factorial(n: Int):Int {\n    return if (n == 0) 1 else n * factorial(n-1)\n}\n\nfun fibonacci(n: Int): Int {\n    return if (n <= 1) n else fibonacci(n - 1) + fibonacci(n - 2)\n}"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/kotlin/blackriper.kt",
    "content": "/*  una funcion recursiva es aquella que puede llmarse  asi misma para realizar un proceso  */\r\n\r\n\r\nfun exmapleRecursive(num:Int ){\r\n     println(num)\r\n    if(num>0) exmapleRecursive(num-1)\r\n\r\n}\r\n\r\n\r\nfun numberFactorial(number: Int): Int {\r\n    return if (number == 1) number\r\n    else number * numberFactorial(number - 1)\r\n}\r\n\r\n\r\nfun fibonacci(number: Int): Int {\r\n    return if (number == 1 || number == 2) 1\r\n    else fibonacci(number - 1) + fibonacci(number - 2)\r\n}\r\n\r\n\r\n\r\nfun main(){\r\n    exmapleRecursive(100)\r\n    numberFactorial(6).let { println(it) }\r\n    fibonacci(20).let { println(it) }\r\n}"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/kotlin/didacdev.kt",
    "content": "fun main() {\n    val number = 5\n    val resultFactorial = factorial(number)\n    println(\"El factorial de $number es $resultFactorial\")\n\n    val position = 4\n    val resultFibonacci = fibonacci(position)\n    println(\"El valor de la posición $position en la secuencia de Fibonacci es $resultFibonacci\")\n}\n\nfun factorial(number: Int): Int {\n\n    if (number == 0) {\n        return 1\n    } else {\n        val i = factorial(number - 1)\n\n        return number * i\n    }\n}\n\nfun fibonacci(position: Int): Int {\n\n    if (position <= 2) {\n        return 1\n    } else {\n        val i = fibonacci(position - 1)\n        val j = fibonacci(position - 2)\n        return j + i\n    }\n}"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/kotlin/eulogioep.kt",
    "content": "fun main() {\n    println(\"Imprimiendo números del 100 al 0:\")\n    imprimirNumeros(100)\n\n    println(\"\\nCalculando factoriales:\")\n    for (i in 0..5) {\n        println(\"Factorial de $i: ${factorial(i)}\")\n    }\n\n    println(\"\\nCalculando elementos de la sucesión de Fibonacci:\")\n    for (i in 0..10) {\n        println(\"Fibonacci($i) = ${fibonacci(i)}\")\n    }\n}\n\n// Función recursiva para imprimir números del 100 al 0\nfun imprimirNumeros(n: Int) {\n    if (n >= 0) {\n        print(\"$n \")\n        imprimirNumeros(n - 1)\n    }\n}\n\n// Función recursiva para calcular el factorial de un número\nfun factorial(n: Int): Long {\n    return when {\n        n < 0 -> throw IllegalArgumentException(\"El factorial no está definido para números negativos\")\n        n == 0 || n == 1 -> 1\n        else -> n * factorial(n - 1)\n    }\n}\n\n// Función recursiva para calcular el valor de un elemento en la sucesión de Fibonacci\nfun fibonacci(n: Int): Int {\n    return when {\n        n < 0 -> throw IllegalArgumentException(\"La posición en la secuencia de Fibonacci debe ser no negativa\")\n        n == 0 -> 0\n        n == 1 -> 1\n        else -> fibonacci(n - 1) + fibonacci(n - 2)\n    }\n}"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/kotlin/isaacus98.kt",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la\n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\nfun main(){\n    imprimirNumero(100)\n    println(\"\\nFactorial\")\n    println(factorial(10))\n    println(\"\\nFibonacci\")\n    println(fibonacci(10))\n}\n\nfun imprimirNumero(numero: Int){\n    println(numero)\n    if (numero > 1)\n        imprimirNumero(numero - 1)\n}\n\nfun factorial(numero: Int) : Int {\n    if (numero == 1)\n        return 1\n\n    val resultado: Int = numero * factorial(numero - 1)\n\n    return resultado\n}\n\nfun fibonacci(pos: Int) : Int {\n    when {\n        pos < 2 -> return pos\n        else -> return fibonacci(pos - 1) + fibonacci(pos - 2)\n    }\n}"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/kotlin/juanppdev.kt",
    "content": "fun recursividad(number) {\n    if(number > 0) {\n        print(\"$number\")\n        recursividad(number - 1)\n    } else if (number == 0 ) {\n        println(number)\n    }\n}\n\nrecursividad(100)\n\n\n// Factorial\n// Función para calcular el factorial de un número\nfun factorial(n: Int): Int {\n    return if (n == 0) {\n        1\n    } else {\n        n * factorial(n - 1)\n    }\n}\n\n// Función para calcular el valor de un elemento en la sucesión de Fibonacci\nfun fibonacci(n: Int): Int {\n    return if (n <= 1) {\n        n\n    } else {\n        fibonacci(n - 1) + fibonacci(n - 2)\n    }\n}\n\n// Prueba de las funciones\nfun main() {\n    val numFactorial = 5\n    val numFibonacci = 6\n\n    println(\"El factorial de $numFactorial es: ${factorial(numFactorial)}\")\n    println(\"El valor en la posición $numFibonacci de Fibonacci es: ${fibonacci(numFibonacci)}\")\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/kotlin/miguelex.kt",
    "content": "import kotlin.io.println\n\nfun sumaRecursiva(a: Int, b: Int): Int = if (b == 0) a else 1 + sumaRecursiva(a, b - 1)\n\nfun potenciaRecursiva(base: Int, exponente: Int): Int = if (exponente == 0) 1 else base * potenciaRecursiva(base, exponente - 1)\n\nfun factorialRecursivo(n: Int): Int = if (n == 0) 1 else n * factorialRecursivo(n - 1)\n\nfun fibonacciRecursivo(n: Int): Int {\n    return if (n <= 1) n else fibonacciRecursivo(n - 1) + fibonacciRecursivo(n - 2)\n} \n\nfun decremento(n: Int): Int {\n    if (n == 0) \n        return 0 \n    else \n        print(n.toString() + \" \") \n        return decremento(n - 1)\n}\n\nfun main() {\n    print(\"Los númeos de 100 a 1  de forma recursica: \")\n    decremento(100)\n    println()\n    println(\"La suma recursiva de 3 + 5 es: ${sumaRecursiva(3, 5)}\")\n    println(\"La potencia recursica de 2^3 es: ${potenciaRecursiva(2, 3)}\")\n    println(\"El valor de 5! es: ${factorialRecursivo(5)}\")\n    println(\"El 10º numero de Fibonacci es: ${fibonacciRecursivo(10)}\")\n\n    println(\"Introduzca el numero del que queire calcular el factorial: \")\n    val numero = readLine()!!.toInt()\n    println(\"El factorial de $numero es: ${factorialRecursivo(numero)}\")\n\n    println(\"Introduzca el numero del que quiere calcular el fibonacci: \")\n    val numeroFib = readLine()!!.toInt()\n    println(\"El $numeroFib º numero de Fibonacci es: ${fibonacciRecursivo(numeroFib)}\")\n\n\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/kotlin/pedroomar23.kt",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\n// Recursividad \nfun example(number: Int): Int {\n    println(number)\n    if (number > o) example(number - 1)\n}\n\n\n\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/kotlin/rikmij.kt",
    "content": "/*\nEJERCICIO:\nEntiende el concepto de recursividad creando una función recursiva que imprima\nnúmeros del 100 al 0.\n\n* DIFICULTAD EXTRA (opcional):\nUtiliza el concepto de recursividad para:\n- Calcular el factorial de un número concreto (la función recibe ese número).\n- Calcular el valor de un elemento concreto (según su posición) en la\nsucesión de Fibonacci (la función recibe la posición).\n */\n\nfun countBack(counter: Int) {\n    if (counter > 0){\n        print(\"$counter, \")\n        countBack(counter-1)\n    }else if (counter == 0){\n        println(counter)\n    }\n}\n\nfun factorial(num: Int): Int {\n    return if (num > 0){\n        num * factorial(num-1)\n    }else{\n        1\n    }\n}\n\nfun fibonacci(num: Int): Int {\n    return when (num-1){\n        1 -> 1\n        2 -> 2\n        else -> fibonacci(num-2) + fibonacci(num-1)\n    }\n}\n\n\nfun main() {\n    countBack(100)\n\n    println(\"\\n ${\"~\".repeat(7)} EJERCICIO EXTRA ${\"~\".repeat(7)}\")\n    println(\"--> FACTORIAL\")\n    println(factorial(5))\n    println(\"--> FIBONACCI\")\n    println(fibonacci(9))\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/kotlin/westwbn.kt",
    "content": "// La recursividad es un concepto fundamental en programación que se refiere a la capacidad de una función para llamarse a sí misma.\nfun recursive(number: Int) {\n    if (number >= 0) {\n        println(number)\n        recursive(number - 1)\n    }\n}\n\nfun factorial(number: Int): Int {\n    return if (number == 0 || number == 1) {\n        1\n    } else {\n        number * factorial(number - 1)\n    }\n}\n\nfun fibonacci(position: Int): Int {\n    return if (position <= 1) {\n        position\n    } else {\n        fibonacci(position - 1) + fibonacci(position - 2)\n    }\n}\n\nfun main() {\n    println(\"Función recursiva:\")\n    recursive(100)\n\n    println(\"Ingresa el número para calcular el factorial:\")\n    val number = readln().toInt()\n    println(\"Función factorial de $number es: ${factorial(number)}\")\n\n    println(\"Ingresa la posición que deseas buscar en la sucesión de Fibonacci:\")\n    val position = readln().toInt()\n    println(\"El valor en la posición $position es: ${fibonacci(position)}\")\n}"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/lua/edalmava.lua",
    "content": "-- Definiendo una función recursiva\nlocal function imprimir (n)\n    print(n .. \" \") \n    if n > 0 then\n        imprimir(n - 1)\n    end \nend\n\n-- Definiendo la función factorial\nlocal function fact (n)\n    if n == 0 then\n      return 1\n    else\n      return n * fact(n-1)\n    end\n  end\n  \n\n-- Definiendo la función Fibonacci\nlocal function fib (n)\n    if n == 0 then\n        return 0\n    elseif n == 1 then \n        return 1\n    else \n        return fib(n - 1) + fib(n - 2)\n    end\nend\n\nprint(\"Imprimiendo los números del 100 al 0\")\nimprimir(100)\nprint(\"Ingresar un número: \")\nlocal a = io.read(\"*number\")        -- read a number\nprint(\"El factorial del número es: \" .. fact(a))\nprint(\"Posición a calcular de la serie de Fibonacci: \")\nlocal p = io.read(\"*number\")\nprint(\"El valor es: \" .. fib(p - 1))\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/nasm/evanz2608.s",
    "content": "; https://nasm.us/\n\n; ====================================================================\n; Ejercicio 06 - Recursividad\n; ====================================================================\n;\n; Simplemente aclarar que existen dos tipos de recursividad: Directa e Indirecta.\n; La recursividad directa se da cuando una función se llama a sí misma, y la recursividad indirecta se da cuando una función A llama a una función B\n; que a su vez llama a la función A.\n\n\nSYS_read:   equ 0\nSYS_write:  equ 1\nSYS_exit:   equ 60\nSTDIN:      equ 0\nSTDOUT:     equ 1\nSTDERR:     equ 2\n\n\nglobal _start\nextern printf\nsection .text\n\n_start:\n  mov rdi, 100\n  call recursion1\n\n  lea rdi, [LF]\n  call printf\n  lea rdi, [LF]\n  call printf\n\n%define FIB_ELEM 30\n  mov rdi, FIB_ELEM\n  call fibonacci\n  mov rdx, rax\n  mov rsi, FIB_ELEM\n  lea rdi, [fibonacci_mask]\n  call printf\n\n%define FACT_NUM 10\n  mov rdi, FACT_NUM\n  call factorial\n  mov rdx, rax\n  mov rsi, FACT_NUM\n  lea rdi, [factorial_mask]\n  call printf\n\n_exit:\n  mov rax, SYS_exit\n  xor rdi, rdi\n  syscall\n\n; En esta función, primero preparamos el stack para poder hacer el CALL tanto a printf, como a la próxima iteración\n; de recursion1.\n; En ensamblador, es necesario que es stack esté alineado a 16 bytes, y cada vez que se usa CALL, el stack se desalinea\n; puesto que CALL guarda en el stack la dirección de retorno, y por consiguiente, se le resta 8 bytes a RSP.\n; Como en este caso tenemos dos llamadas, el stack sigue alineado, pero nesecitamos crear un \"STACK FRAME\", para que cada llamada\n; guarde su punto de regreso sin corromper el punto guardado por la llamada anterior.\nrecursion1:\n  push rbp\n  mov rbp, rsp\n  sub rsp, 16\n  mov rcx, rdi\n  mov [rbp - 16], rcx\n  lea rdi, [printf_mask]\n  mov rsi, rcx\n  call printf\n  mov rcx, [rbp - 16]\n  dec rcx\n  mov rdi, rcx\n  test rcx, rcx\n  jz .done\n  call recursion1\n.done:\n  add rsp, 16\n  pop rbp\n  ret\n\n; RDI: posición del elemento de la sucesión de Fibonacci a calcular.\n; NOTA: esta función es muy lenta. Se puede optimizar bastante puesto que para cada recursión calcula\n; todos los numeros de fibonacci anteriores.\nfibonacci:\n  push rbp\n  mov rbp, rsp\n  sub rsp, 32\n  mov [rbp - 32], rdi\n  \n  cmp rdi, 1\n  mov rax, rdi\n  jle .return\n  sub rdi, 1\n  call fibonacci\n  mov [rbp - 16], rax\n  mov rdi, [rbp - 32]\n  sub rdi, 2\n  call fibonacci\n  add rax, [rbp - 16]\n  jmp .return\n.return:\n  add rsp, 32\n  pop rbp\n  ret\n\n; RDI: el número del cual se va a calcular el factorial.\nfactorial:\n  push rbp\n  mov rbp, rsp\n  sub rsp, 32\n  mov [rbp - 32], rdi\n  cmp rdi, 1\n  jg .calculate\n  mov rax, 1\n  jmp .return\n.calculate:\n  dec rdi\n  call factorial\n  inc rdi\n  mul rdi\n  jmp .return\n.return:\n  add rsp, 32\n  pop rbp\n  ret\n\nsection .data\n  printf_mask: db \"%d \", 0x00\n  fibonacci_mask: db \"El elemento [%d] de fibonacci es: %d\", 0x0A, 0x00\n  factorial_mask: db \"El factorial de [%d] es: %d\", 0x0A, 0x00\n  LF: db 0x0A, 0x00\n\nsection .bss\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/ocaml/luishendrix92.ml",
    "content": "(**************************************************************************)\n(*                                                                        *)\n(*                                Recursion                               *)\n(*                                                                        *)\n(* I understand {b recursion} as a function that calls itself, or, that   *)\n(* is defined in terms of itself. Its use cases are various:              *)\n(*                                                                        *)\n(* - {b Mathematics}: Factorial, fractals, fibonacci sequence.            *)\n(* - {b Computer Science}:                                                *)\n(*   - Dynamic programming algorithms that solve problems by breaking     *)\n(*     them into smaller sub-problems (divide and conquer).               *)\n(*   - Tree-like data structures and their algorithms.                    *)\n(*   - Graph theory algorithms.                                           *)\n(*   - Purely Functional programming, such as those algorithms that       *)\n(*     operate on iterative data structures (lists, sets, maps, etc).     *)\n(* - {b Arts}: Matrioshka dolls, infinity mirror, droste effect.          *)\n(*                                                                        *)\n(* Functional programming languages rely heavily on recursion due to      *)\n(* procedural loops being (mostly) rejected in favour of it. Take for     *)\n(* example a purely FP language like Haskell; there is NO way to write    *)\n(* loops so in order to iterate you are forced to think in terms of       *)\n(* recursion. OCaml is not a purely FP language and provides both loops   *)\n(* and mutable references for cases in which performance is needed.       *)\n(*                                                                        *)\n(* In OCaml, in order to mark a function as recursive, we need to add the *)\n(* [rec] keyword in front of [let], or pass an existing function to a     *)\n(* {e fixing} function so that it works as intended. On top of that, the  *)\n(* compiler guarantees that it will perform {b tail-call optimization}    *)\n(* if it's possible. A tail-call optimized recursive function avoids      *)\n(* creating multiple stack frames (leads to a {e stack overflow} if it's  *)\n(* written in a way that the last call inside the function is the         *)\n(* function itself with nothing in front or behind it, thus avoiding the  *)\n(* need to backtrack. To achieve this, most programmers agree'd on a      *)\n(* convention that involves an {e auxiliar} function defined inside or    *)\n(* outside the main one, which in turn is called with some initial        *)\n(* value for the accumulator and any dependency it might require. The     *)\n(* main tradeoff is that some functions are incredibly complex to write   *)\n(* with TCO in mind and may even require you to make use of stacks.       *)\n(*                                                                        *)\n(**************************************************************************)\n\nmodule type Recursion = sig\n  (** [print_range a b] prints lines with integer numbers from [a] to [b]. If no\n      value is passed to [a], it will default to [0]. The order in which the\n      printing happens depends on if [a > b] (descending order) or if [a <= b]\n      (ascending order). This function is {b tail-call optimized}. *)\n  val print_range : ?a:int -> int -> unit\n\n  (** [factorial n] is the result of multiplying [n * n-1 * n-2 * ...] until\n      [n] reaches 0 (base case that results in 1). The recursive mathematical\n      definition of the {e factorial} is: {m n! = n \\cdot (n - 1)!}. This\n      function is {b not tail-call optimized}. *)\n  val factorial : float -> float\n\n  (** [factorial_tc n] is the {b tail-call optimized} version of {! factorial}.\n\n      @raise Failure if [n < 0] (negative factorials are impossible). *)\n  val factorial_tco : float -> float\n\n  (** [fib n] is the nth integer in the fibonacci sequence\n      ([0, 1, 1, 2, 3, 5, 8, 13, ...]). [n] represents the index in the\n      aforementioned sequence, which is computed by adding the previous two\n      numbers starting with [0] and [1]. It can be solved iteratively with\n      a [for] loop but it's best represented as a recursive evaluation tree:\n\n      {[\n                   ⨍(5)\n                /       \\\n            ⨍(4)    +    ⨍(3) = 5\n           /    \\      /       \\\n        ⨍(3) + ⨍(2) = 3   ⨍(2) + ⨍(1) = 2\n            / \\      / \\\n         ⨍(2) + ⨍(1) = 2 ⨍(1) + ⨍(0) = 1\n            / \\\n         ⨍(1) + ⨍(0) = 1\n      ]}\n\n      Few things can be observed in this evaluation tree:\n\n      + From a very small number ([5]), a lot of branches and individual calls\n        to [fib] are created, making it exponentially inefficient. This is\n        called a {b naive implementation} of a dynamic programming algorithm.\n      + A lot of calls to [fib n] share the same input [n], making it possible\n        to optimize using a technique called {b memoization}.\n\n      It is possible to run the 2 branches [n-1] and [n-2] in parallel which\n      reduces the execution time by a decent margin (depending on how many\n      {e physical cores} the CPU has), though it does come with a cost.\n\n      See https://v2.ocaml.org/releases/5.0/manual/parallelism.html. *)\n  val fib : int -> int\n\n  (** [fib_memo n] is the {b memoized} version of [fib n]. Memoization is a\n      of optimizing dynamic programic algorithms and expensive functions by\n      having a cache map (implemented as a key-value pair) that saves computed\n      results to it and if the function receives the same input(s) again, the\n      cached value can be retrieved thus saving tons of execution time.\n\n      [fib_memo]'s cache is implemented with a [Hashtbl] (initial size [100]).\n\n      @raise Failure if [n < 0]. [n] should be positive (or [0]). *)\n  val fib_memo : int -> int\n\n  (** [fib_tco n] is the {b tail-call optimized} version of [fib n].\n\n      @raise Failure if [n < 0]. [n] should be positive (or [0]). *)\n  val fib_tco : int -> int\nend\n\nmodule Exercise6 : Recursion = struct\n  let rec print_range ?(a = 0) b =\n    let delta = if a > b then -1 else 1 in\n    print_endline (string_of_int a);\n    if a <> b then print_range ~a:(a + delta) b\n  ;;\n\n  (* DIFICULTAD EXTRA (opcional):\n     ----------------------------\n     Utiliza el concepto de recursividad para:\n     - Calcular el factorial de un número concreto (la función recibe ese número).\n     - Calcular el valor de un elemento concreto (según su posición) en la\n       sucesión de Fibonacci (la función recibe la posición).\n  *)\n\n  let rec factorial n = if n < 2. then 1. else n *. factorial (n -. 1.)\n\n  let factorial_tco n =\n    let rec aux ~acc n =\n      if n < 0.\n      then failwith \"Negative factorial\"\n      else if n < 2.\n      then acc\n      else aux ~acc:(acc *. n) (n -. 1.)\n    in\n    aux ~acc:1. n\n  ;;\n\n  let rec fib n = if n < 2 then n else fib (n - 1) + fib (n - 2)\n\n  let fib_memo =\n    let cache = Hashtbl.create 100 in\n    let rec aux n =\n      if n < 0\n      then failwith \"Negative fibonacci sequence index\"\n      else if n < 2\n      then n\n      else begin\n        match Hashtbl.find_opt cache n with\n        | Some n -> n\n        | None ->\n          let result = aux (n - 1) + aux (n - 2) in\n          Hashtbl.replace cache n result;\n          result\n      end\n    in\n    aux\n  ;;\n\n  let fib_tco n =\n    let rec aux ~b ~a i = if i <= 0 then a else aux ~a:b ~b:(a + b) (i - 1) in\n    if n < 0\n    then failwith \"Negative fibonacci sequence index\"\n    else aux ~a:0 ~b:1 n\n  ;;\nend\n;;\n\nbegin\n  let open Exercise6 in\n  let open Printf in\n  print_range ~a:100 0;\n  printf \"Factorial of 5: %f\\n\" (factorial 5.);\n  printf\n    \"Tail-Call Optimized Factorial of -5: %s\\n\"\n    (try factorial_tco (-5.) |> string_of_float with\n     | Failure _ -> \"ERROR\");\n  printf \"Tail-Call Optimized Factorial of 50.0: %f\\n\" (factorial_tco 50.);\n  (* Running [fib 37] is expensive so you will notice a slight delay*)\n  printf \"37th number in the fibonacci sequence (naive): %d\\n\" (fib 37);\n  printf\n    \"100th number in the fibonacci sequence (memoized): %d\\n\"\n    (fib_memo 100);\n  printf \"52nd number in the fibonacci sequence (tco): %d\\n\" (fib_tco 52)\nend\n\n(* Output of [ocaml luishendrix92.ml]:\n\n   100\n   99\n   98\n   97\n   96\n   95\n   94\n   93\n   92\n   91\n   90\n   89\n   88\n   87\n   86\n   85\n   84\n   83\n   82\n   81\n   80\n   79\n   78\n   77\n   76\n   75\n   74\n   73\n   72\n   71\n   70\n   69\n   68\n   67\n   66\n   65\n   64\n   63\n   62\n   61\n   60\n   59\n   58\n   57\n   56\n   55\n   54\n   53\n   52\n   51\n   50\n   49\n   48\n   47\n   46\n   45\n   44\n   43\n   42\n   41\n   40\n   39\n   38\n   37\n   36\n   35\n   34\n   33\n   32\n   31\n   30\n   29\n   28\n   27\n   26\n   25\n   24\n   23\n   22\n   21\n   20\n   19\n   18\n   17\n   16\n   15\n   14\n   13\n   12\n   11\n   10\n   9\n   8\n   7\n   6\n   5\n   4\n   3\n   2\n   1\n   0\n   Factorial of 5: 120.000000\n   Tail-Call Optimized Factorial of -5: ERROR\n   Tail-Call Optimized Factorial of 50.0: 30414093201713375576366966406747986832057064836514787179557289984.000000\n   37th number in the fibonacci sequence (naive): 24157817\n   100th number in the fibonacci sequence (memoized): 3736710778780434371\n   52nd number in the fibonacci sequence (tco): 32951280099\n*)\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/pascal/edalmava.pas",
    "content": "program Recursividad;\nuses Crt;\n\nprocedure mostrarNumeros(num : Integer);\nbegin\n    if num >= 0 then\n    begin\n        WriteLn(num);\n        mostrarNumeros(num - 1);\n    end;\nend;\n\nfunction factorial(num : Integer): QWord;\nbegin\n    if num = 1 then\n        factorial := 1\n    else\n        factorial := num * factorial(num - 1);\nend;\n\nfunction fibonacci(num : Integer): QWord;\nbegin\n    if num = 0 then\n        fibonacci := 0\n    else if num = 1 then\n        fibonacci := 1\n    else\n        fibonacci := fibonacci(num - 1) + fibonacci(num - 2);\nend;\n\nbegin\n    ClrScr;\n    mostrarNumeros(100);\n    WriteLn('Factorial de 6 = ', factorial(6));\n    WriteLn('Posicion 8 de la serie de Fibonacci = ', fibonacci(8));\nend.\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/pascal/miguelex.pas",
    "content": "program miguelex;\n\nvar\n  x: integer;\n\nfunction sumaRecursiva(n, m: integer): integer;\nbegin\n  if m = 0 then\n    sumaRecursiva := n\n  else\n    sumaRecursiva := 1 + sumaRecursiva(n, m - 1);\nend;\n\nfunction potenciaRecursiva(base, exponente: integer): integer;\nbegin\n  if exponente = 0 then\n    potenciaRecursiva := 1\n  else\n    potenciaRecursiva := base * potenciaRecursiva(base, exponente - 1);\nend;\n\nfunction factorialRecursivo(n: integer): integer;\nbegin\n  if n = 0 then\n    factorialRecursivo := 1\n  else\n    factorialRecursivo := n * factorialRecursivo(n - 1);\nend;\n\nfunction fibonacciRecursivo(n: integer): integer;\nbegin\n  if n = 0 then\n    fibonacciRecursivo := 0\n  else if n = 1 then\n    fibonacciRecursivo := 1\n  else\n    fibonacciRecursivo := fibonacciRecursivo(n - 1) + fibonacciRecursivo(n - 2);\nend;\n\nfunction contadorRecursivo(n: integer): integer;\nbegin\n  if n = 0 then\n    contadorRecursivo := 0\n  else\n  begin\n    write(n, ' ');\n    contadorRecursivo := contadorRecursivo(n - 1);\n  end;\nend;\n\nbegin\n  WriteLn('De 100 a 0 de forma recursiva: ',contadorRecursivo(100));\n  WriteLn();\n\n  writeln('Suma recursiva de 3 + 5: ', sumaRecursiva(3, 5));\n  writeln('Potencia recursiva de 2^3: ', potenciaRecursiva(2, 3));\n  writeln('Factorial recursivo de 5: ', factorialRecursivo(5));\n  writeln('Fibonacci recursivo de 7: ', fibonacciRecursivo(10));\n  \n  writeLn('Introduce el numero del que quieres calcular el factorial: ');\n  readLn(x);\n  writeln('Factorial recursivo de ', x, ': ', factorialRecursivo(x));\n\n  writeLn('Introduce el numero del que quieres calcular el fibonacci: ');\n  readln(x);\n  writeln('Fibonacci recursivo de ', x, ': ', fibonacciRecursivo(x));\n\nend."
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/php/eulogioep.php",
    "content": "<?php\n\n/**\n * Función recursiva para imprimir números del 100 al 0.\n * @param int $numero El número actual a imprimir.\n */\nfunction imprimirNumeros($numero) {\n    // Caso base: si el número es menor que 0, terminamos la recursión\n    if ($numero < 0) {\n        return;\n    }\n    \n    // Imprimimos el número actual\n    echo $numero . \" \";\n    \n    // Llamada recursiva con el número decrementado\n    imprimirNumeros($numero - 1);\n}\n\n/**\n * Función recursiva para calcular el factorial de un número.\n * @param int $n El número del cual calcular el factorial.\n * @return int El factorial del número.\n */\nfunction factorial($n) {\n    // Casos base: factorial de 0 y 1 es 1\n    if ($n == 0 || $n == 1) {\n        return 1;\n    }\n    \n    // Llamada recursiva: n * factorial(n-1)\n    return $n * factorial($n - 1);\n}\n\n/**\n * Función recursiva para calcular el valor de un elemento en la sucesión de Fibonacci.\n * @param int $posicion La posición del elemento en la sucesión de Fibonacci.\n * @return int El valor del elemento en la posición dada.\n */\nfunction fibonacci($posicion) {\n    // Casos base: posiciones 0 y 1 de Fibonacci son 0 y 1 respectivamente\n    if ($posicion == 0) {\n        return 0;\n    }\n    if ($posicion == 1) {\n        return 1;\n    }\n    \n    // Llamada recursiva: suma de los dos elementos anteriores\n    return fibonacci($posicion - 1) + fibonacci($posicion - 2);\n}\n\n// Pruebas de las funciones\necho \"Números del 100 al 0:\\n\";\nimprimirNumeros(100);\necho \"\\n\\n\";\n\n$numeroFactorial = 5;\necho \"Factorial de $numeroFactorial: \" . factorial($numeroFactorial) . \"\\n\";\n\n$posicionFibonacci = 7;\necho \"Elemento en la posición $posicionFibonacci de Fibonacci: \" . fibonacci($posicionFibonacci) . \"\\n\";\n\n?>"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/php/gabrielmoris.php",
    "content": "<?php\n/*\n * EXERCISE:\n * Understand the concept of recursion by creating a recursive function that\n * prints numbers from 100 to 0.\n */\n\n$num = 0;\n\nfunction recursive_print(&$num)\n{\n    do {\n        echo $num . \"\\n\";\n        $num++;\n    } while ($num < 101);\n}\n\nrecursive_print($num);\n\n/* EXTRA DIFFICULTY (optional):\n * Use the concept of recursion to:\n * - Calculate the factorial of a specific number (the function receives that number).\n * - Calculate the value of a specific element (according to its position) in the\n *   Fibonacci sequence (the function receives the position).\n */\n\n\n\nfunction factorial($num)\n{\n    if ($num < 0) {\n        return \"Error: Factorial of a negative number doesn't exist.\";\n    } elseif ($num == 0 || $num == 1) {\n        return 1;\n    } else {\n        return (int)$num * (int)factorial($num - 1); // In this way I am specifying the return type as (int)\n    }\n}\n\n\n$num = 7;\n$fac = factorial($num);\necho \"Factorial of \" . $num . \" is \" . $fac . \"\\n\";\n\n$memo = [];\n\nfunction fibonacci($pos, &$memo)\n{\n    if ($pos <= 2) {\n        return 1;\n    }\n\n    if (!isset($memo[$pos])) {\n        $memo[$pos] = fibonacci($pos - 1, $memo) + fibonacci($pos - 2, $memo);\n    }\n\n    return $memo[$pos];\n}\n\n$fib = fibonacci($num, $memo);\necho \"Fibonacci in possition \" . $num . \" is \" . $fib . \"\\n\";\n\n\nfunction get_fibo_pos($num)\n{\n\n    $memo = [];\n    $pos = 0;\n    $fib_res = fibonacci($pos, $memo);\n\n    do {\n        $pos++;\n        $fib_res = fibonacci($pos, $memo);\n    } while ($num > $fib_res);\n\n\n    if ($num != $fib_res) {\n        return \"Error: This Number doesn't belong to fibonacci sequence.\";\n    }\n\n    return $pos;\n}\n\n$fibo_num = 1346269;\n$posi = get_fibo_pos($fibo_num);\necho \"Fibonacci possition of number \" . $fibo_num . \" is \" . $posi . \"\\n\";\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/php/kodenook.php",
    "content": "<?php\n\ndeclare(strict_types = 1);\n\n/**\n * The above PHP function uses recursion to print numbers from the input number down to 0.\n *\n * @param int number The function `recursion` takes an integer parameter `number` and recursively\n * prints the value of `number` until it reaches 0. Each time it prints the value of `number`, it\n * decrements the value by 1 before calling itself recursively.\n */\nfunction recursion(int $number): void\n{\n    echo $number, PHP_EOL;\n    if ($number > 0) recursion(--$number);\n}\n\nrecursion(100);\n\n/*\n    Exercise\n*/\n\n/**\n * The function calculates the factorial of a given number recursively in PHP.\n *\n * @param int number The `number` parameter in the `factorial` function represents the integer for\n * which you want to calculate the factorial. The factorial of a non-negative integer n is the product\n * of all positive integers less than or equal to n.\n * @param int result The `result` parameter in the `factorial` function is used to keep track of the\n * intermediate result as the factorial calculation progresses through recursive calls. It starts with\n * a default value of 1 and gets updated with the multiplication of the current number and the previous\n * result in each recursive call.\n */\nfunction factorial(int $number, int $result = 1): void\n{\n    if ($number > 1) factorial($number - 1, $number * $result);\n    else echo $result, PHP_EOL;\n}\n\nfactorial(5);\n\n/**\n * The function calculates the Fibonacci sequence up to a given number using recursion in PHP.\n *\n * @param int number The function you provided is a recursive implementation of the Fibonacci sequence.\n * It calculates the Fibonacci number at a given position in the sequence.\n * @return int the nth number in the Fibonacci sequence, where n is the input number provided to the\n * function.\n */\nfunction fibonacci(int $number): int\n{\n    if ($number > 2) return fibonacci($number - 1) + fibonacci($number - 2);\n    else return 1;\n\n}\n\necho fibonacci(7);"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/php/marcode24.php",
    "content": "<?php\n/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la\n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\n// Función recursiva para imprimir números del 100 al 0\nfunction imprimirNumeros($num) {\n    if ($num < 0) {\n        return; // La función termina cuando $num es menor que 0\n    }\n    echo $num . \"\\n\"; // Imprime el número seguido de un salto de línea\n    imprimirNumeros($num - 1); // Llamada recursiva con $num decrementado en 1\n}\n\necho \"Imprimiendo números del 100 al 0:\\n\";\nimprimirNumeros(100);\n\n// Función recursiva para calcular el factorial de un número\nfunction factorial($n) {\n    if ($n === 0 || $n === 1) {\n        return 1; // El factorial de 0 y 1 es 1\n    }\n    return $n * factorial($n - 1); // Llamada recursiva con $n decrementado en 1\n}\n\n$numero = 5;\necho \"Factorial de $numero: \" . factorial($numero) . \"\\n\";\n\n// Función recursiva para calcular el valor de un elemento en la sucesión de Fibonacci\nfunction fibonacci($n) {\n    if ($n <= 1) {\n        return $n; // Si $n es 0 o 1, devuelve $n\n    }\n    return fibonacci($n - 1) + fibonacci($n - 2); // Llamada recursiva con $n decrementado en 1 y 2\n}\n\n$posicion = 6;\necho \"Valor en la posición $posicion de la sucesión de Fibonacci: \" . fibonacci($posicion) . \"\\n\";\n\n// Visita mi repo en GitHub para ver y correr los tests de este código --> https://github.com/marcode24/weekly-challenges\n\n?>\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/php/miguelex.php",
    "content": "<?php\n\n    function sumaRecursiva ($a, $b){\n        if ($b == 0) {\n            return $a;\n        } else {\n            return 1 + sumaRecursiva($a, $b - 1);\n        }\n    }\n\n    echo \"Vamos a sumar 5 + 3 usando una función recursiva\\n\";\n    echo sumaRecursiva(5, 3);\n    echo \"\\n\";\n\n    function potenciaRecursiva($a, $b){\n        if ($b == 0) {\n            return 1;\n        } else {\n            return $a * potenciaRecursiva($a, $b - 1);\n        }\n    }\n\n    echo \"Vamos a calcular el cubo de 2 usando una función recursiva\\n\";\n    echo potenciaRecursiva(2, 3);\n    echo \"\\n\";\n\n    function imprimirNumeros($numero) {\n        if ($numero >= 0) {\n            echo $numero . \" \";\n            imprimirNumeros($numero - 1);\n        }\n    }\n    \n    echo \"De 100 a 0 usando rercusividad: \";\n    imprimirNumeros(100);\n    echo \"\\n\";\n\n    // Extra \n\n    echo \"Como ejercicios extras, vamos a calcular el factorial de 5 y el octavo número de la serie de Fibonacci\\n\";\n\n    function factorial($n) {\n        if ($n == 0) {\n            return 1;\n        } else {\n            return $n * factorial($n - 1);\n        }\n    }\n\n    echo \"El numero 5! es = \".factorial(5).\"\\n\";\n\n    function fibonacci($n){\n        if ($n == 0) {\n            return 0;\n        } else if ($n == 1) {\n            return 1;\n        } else {\n            return fibonacci($n - 1) + fibonacci($n - 2);\n        }\n    }\n\n    echo \"El 8º numero de Fibonacci es = \".fibonacci(8).\"\\n\";\n\n    echo \"Finalmente, vamos a comproabr el funcionamiento de amabs funciones de forma interactiva\\n\";\n\n    echo \"Introduce un número para calcular su factorial: \";\n    $n = trim(fgets(STDIN));\n    echo \"El número \".$n.\"! es = \".factorial($n).\"\\n\";\n\n    echo \"Introduce un número para calcular su posición en la serie de Fibonacci: \";\n    $n = trim(fgets(STDIN));\n    echo \"El número \".$n.\" de Fibonacci es = \".fibonacci($n).\"\\n\";\n\n    "
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/php/qv1ko.php",
    "content": "<?php\n\n    func(0);\n\n    echo \"\\n---\\n\";\n\n    echo fact(4);\n\n    echo \"\\n---\\n\";\n\n    echo fib(5);\n\n    function func($number) {\n\n        echo \"\\n\" . $number;\n\n        $number = $number + 1;\n\n        if ($number <= 100) {\n            func($number);\n        }\n\n    }\n\n    function fact($number) {\n        if ($number <= 0) {\n            return 0;\n        } else if ($number == 1) {\n            return 1;\n        } else {\n            return $number * fact($number - 1);\n        }\n    }\n\n    function fib($pos) {\n        if ($pos <= 1) {\n            return 0;\n        } else if ($pos == 2 || $pos == 3) {\n            return 1;\n        } else {\n            return fib($pos - 1) + fib($pos - 2);\n        }\n    }\n\n?>\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/59822.py",
    "content": "'''  * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n * \n'''\ndef countdown(number : int):\n    while number > 0:\n        print(number, end=\" \") \n        number-= 1\n    print(f\"\\nEl número final es {number}\")\n    \ncountdown(52)\n\n'''  * EXTRA:\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n'''\ndef factorial(numero : int):\n    if numero == 0:\n        return 1\n    else:\n        return numero * factorial(numero -1)\n    #retorna la funcion hasta que llegue a 0\n\nprint(factorial(3))\n\n## Fibonacci es la suma de los dos anteriores\n\ndef fibonacci(number : int):\n    if  number <= 0:\n        return \"No se puede un negativo o cero\"\n    elif number == 1:\n        return 0\n    elif number == 2:\n        return 1\n    else:\n        return fibonacci(number - 1)+fibonacci(number - 2)\n    # retorna la funcion hasta que llegue a 0\n    \nprint(fibonacci(3565))"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/AChapeton.py",
    "content": "def recursiveFunction(value):\n  print(value)\n  if(value != 0):\n    recursiveFunction(value - 1)\n\n\nrecursiveFunction(100)\n\n\n# DIFICUTAL EXTRA\n\ndef obtenerFactorial(factorial):\n  if(factorial < 0):\n    return -1\n  elif(factorial == 0):\n    return 1\n  else:\n    return (factorial * obtenerFactorial(factorial - 1))\n\nprint('Factorial: ', obtenerFactorial(10))\n\ndef fibonacci(position):\n  if(position <= 1):\n    return 1\n  result = fibonacci(position - 1) + fibonacci(position -2)\n  return result\n\nprint('fibonacci: ', fibonacci(7))"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/AbelPerezCollado.py",
    "content": "# EJERCICIO: Función recursiva que imprima números del 100 al 0\n\ndef countdown(n : int):\n    print(n)\n    if n > 0:\n        countdown(n-1)\n        \n\n\n#DIFICULTAD EXTRA\n# Calcular el factorial de un número.\n\ndef factorial(n : int):\n    if n > 1:\n        return n * factorial(n - 1)\n    else:\n        return 1\n    \n# Calcular valor elemento concreto en la sucesión de Fibonacci\n\ndef fibonacci(n : int):\n    if n == 0 or n == 1:\n        return 1\n    else:\n        return fibonacci(n - 1) + fibonacci(n - 2)\n    \n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/AlainMartz.py",
    "content": "#06 RECURSIVIDAD\n\n#  * EJERCICIO:\n#  * Entiende el concepto de recursividad creando una función recursiva que imprima\n#  * números del 100 al 0.\n\n\"\"\"\nLa recursividad es una técnica de programación en la que una función se llama a sí misma para resolver subproblemas más pequeños de un problema más grande. \nEs una forma de descomponer problemas complejos en partes más manejables y más pequeñas.\n\nComponentes de la Recursividad\nCaso Base: Es la condición que termina las llamadas recursivas. Sin un caso base, la función recursiva se llamaría indefinidamente, causando un desbordamiento de pila.\n\nCaso Recursivo: Es la parte de la función que divide el problema en subproblemas más pequeños y se llama a sí misma con estos subproblemas.\n\"\"\"\n\ndef count_down(n):\n    #caso base\n    if n == 0:\n        return print(0)\n    else:\n        print(n)\n        return count_down(n-1)\n\ncount_down(100)\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Utiliza el concepto de recursividad para:\n#  * - Calcular el factorial de un número concreto (la función recibe ese número).\n#  * - Calcular el valor de un elemento concreto (según su posición) en la \n#  *   sucesión de Fibonacci (la función recibe la posición).\n\n\n# Factorial\n# n!=n×(n−1)×(n−2)×⋯×2×1\n\nprint(\"\\nDesafio factorial\\n\")\ndef factorial(n):\n    if n == 0:\n        return 1\n    else:        \n        return n * factorial(n-1)\n\nprint(factorial(10))\nprint(factorial(20))    \n\n# Fibonacci \n\"\"\"\nF(0) = 0\nF(1) = 1\n\nPara n>=2\n\nF(n) = F(n-1)+F(n-2)\n\"\"\"\nprint(\"\\nDesafio fibonacci\\n\")\n\ndef fibo(n):\n    if n == 0:\n        return 0\n    if n == 1:\n        return 1\n    else:\n        return fibo(n-1)+fibo(n-2)\n    \nprint(fibo(0))\nprint(fibo(1))\nprint(fibo(2))\nprint(fibo(3))\nprint(fibo(4))\nprint(fibo(5))\nprint(fibo(6))\nprint(fibo(7))\nprint(fibo(8))\nprint(fibo(9))\nprint(fibo(10))"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/Aldroide.py",
    "content": "# Concepto de recursividad: función que se llama así misma\n\ndef contador(number: int):\n    if number >= 0:\n        print(number)\n        contador(number - 1)\n\n\ncontador(100)\n\n\n\"\"\"\n    Dificultad Extra\n    Calcular el factorial y el fibonacci usando recursividad.\n\"\"\"\n\n\ndef factorial(num: int) -> int:\n    if num < 0:\n        print(\"Los números negativos no tienen fibonacci\")\n        return 0\n    elif num == 0:\n        return 1\n    else:\n        return num * factorial(num - 1)\n\n\nprint(factorial(4))\n\n\ndef fibonacci(num: int) -> int:\n    if num <= 0:\n        print(\"La posición tiene que ser mayor que cero\")\n        return 0\n    elif num == 1:\n        return 0\n    elif num == 2:\n        return 1\n    else:\n        return fibonacci(num - 1) + fibonacci(num - 2)\n\n\nprint(fibonacci(5))\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/Aleran07.py",
    "content": "#06git \ndef regresiva(n):\n    if n == 0:  # caso base\n        print(n)\n    else:\n        print(n)\n        regresiva(n - 1) # llamada recursiva\n        \nregresiva(100)\n\n# Ejercicio extra 1\ndef factorial(n):\n    if n == 1:  # caso base\n        return 1\n    else:\n        return n * factorial(n - 1) # llamada recursiva\n\nnumero = int(input(\"Ingresa un numero para hayar el factorial: \"))\nprint(factorial(numero))\n\n# Ejercicio extra 2\n\ndef Fibonacci(n, x, a):\n    y = a\n    if n == 2:  # caso base\n        return y\n    elif n == 1:\n        return 0\n    else:\n        z = x + y\n        x = y\n        y = z\n        fi = Fibonacci(n - 1, x, y) # llamada recursiva\n        return fi\n\nposicion = int(input(\"Ingresa una posicion para la secuencia de fibonacci: \"))\nprint(Fibonacci(posicion, 0, 1))\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/AllanYSalazarG.py",
    "content": "\"\"\" #06 RECURSIVIDAD \"\"\"\n\n\ndef showNumbers(number):\n    if number == 0:\n        print(number)\n        return number\n    print(number, end=\" > \")\n    showNumbers(number-1)\n\n\n# number = int(input(\"Ingresa un valor: \"))\nshowNumbers(10)\n\n\ndef factorial(number):\n    if number == 1 or number == 0:\n        return 1\n    return number * factorial(number-1)\n\n\nprint(f\"Factorial: {factorial(5)}\")\n\n\ndef fibonacci(position):\n    if position == 0 or position == 1:\n        return position\n    return fibonacci(position - 1) + fibonacci(position - 2)\n\n\nprint(f\"Fibonacci: {fibonacci(10)}\")\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/Alvaro-Neyra.py",
    "content": "\n# * EJERCICIO:\n# * Entiende el concepto de recursividad creando una función recursiva que imprima\n# * números del 100 al 0.\n\n# ** QUE ES LA RECURSIVIDAD?\n# ** La recursividad en la programacion es una tecnica de una funcion que se llama a si misma durante su ejecucion. Este proceso\n# ** se repite hasta que se cumpla una condicion base que evita que la funcion se llame recursivamente.\n\ndef recursive_function(number):\n    if number == 0:\n        print(number)\n        return\n    print(number)\n    recursive_function(number - 1)\n\nrecursive_function(100)\n\n# * DIFICULTAD EXTRA (opcional):\n# * Utiliza el concepto de recursividad para:\n# * - Calcular el factorial de un número concreto (la función recibe ese número).\ndef factorial_recursivo(numero):\n    if numero == 1 or numero == 0:\n        return 1\n    return numero * factorial_recursivo(numero - 1)\n\nresultado_del_factorial = factorial_recursivo(6)\nprint(f\"Este es el resultado del factorial de 6: {resultado_del_factorial}\")\n\n# * - Calcular el valor de un elemento concreto (según su posición) en la \n# *   sucesión de Fibonacci (la función recibe la posición).\ndef fibonacci_factorial(number, diccionario_de_valores = {}):\n    # Creamos la funcion fibonacci con un diccionario que guarda los valores de cada valor fibonacci\n    # Si el argumento es menor a 0, no validar\n    if (number < 0):\n        return None\n    elif (number == 0):\n        return 0\n    elif (number == 1):\n        return 1\n    # Si el valor del numero esta en el diccionario de valores de fibonacci, retornar\n    elif number in diccionario_de_valores:\n        return diccionario_de_valores[number]\n    # Si no es 0 ni 1 entonces llamar a la funcion dos veces sumandolas:\n    else:\n        result = fibonacci_factorial(number - 1, diccionario_de_valores) + fibonacci_factorial(number - 2, diccionario_de_valores)\n        # Guardar el valor de fibonacci en el diccionario con su clave y valor correspondiente\n        diccionario_de_valores[number] = result\n        # Retornar resultado\n        return result\n    \nresultado_fibonacci = fibonacci_factorial(15)\nprint(resultado_fibonacci)"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/Aquiles735.py",
    "content": "\n\n\n#  * EJERCICIO:\n#  * Entiende el concepto de recursividad creando una función recursiva que imprima\n#  * números del 100 al 0.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Utiliza el concepto de recursividad para:\n#  * - Calcular el factorial de un número concreto (la función recibe ese número).\n#  * - Calcular el valor de un elemento concreto (según su posición) en la \n#  *   sucesión de Fibonacci (la función recibe la posición).\n#  */\n\n\n     #recursividad , apliacion \ndef factorial(n):\n    if n == 1:\n        return 1   #cuando 7*6*5*4*3*2 (llega a 1) se detiene y retorna el resultado\n    else:\n        return n * factorial(n - 1)\nprint(factorial(7))  # = 5040\n\n\ndef secuencia(n):\n    if n == 5:\n        return 5 # #cuando 7*6*5 (llega a 5) se detiene y retorna el resultado\n    else:\n        return n * secuencia(n - 1)\nprint(secuencia(7))     # = 210\n\n\ndef continu(n):\n    if n == 20:\n        return 20 # #cuando 7*6*5 (llega a 5) se detiene y retorna el resultado\n    else:\n        return n + continu(n - 1)\nprint(continu(50))  # 50+49+48+47.......+20 =1085\n\n\n   #aplicando loops while:\nx= 1\nwhile x <= 100:\n    print(x)  # imprime del 1 al 100\n    x += 1  # Incrementamos la variable en 1 hasta ==100\n   # print(x)  ## ojo, desde aqui del 2 al 101\n\n  ##Imprime de 100 hasta 0\nx = 100\nwhile x >= 0:\n    print(x)\n    x -= 1 ## imprime del 100 al 0\n\n   \n   ####combinación de funcion con bucle while::###\n\ndef imprimir_numeros():\n    x = 100\n    while x >= 0:\n        print(x)\n        x -= 1\n# Llamamos a la función\nimprimir_numeros() #imprime de 100 hasta 0\n\n\n# aplicando para valores de fibonacci\n\ndef fibonacci(n):\n    secuencia = [0, 1]\n    while len(secuencia) < n:\n        secuencia.append(secuencia[-1] + secuencia[-2])\n    return secuencia\nprint(fibonacci(10))     # Generar los primeros 10 números de la secuencia de Fibonacci\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/BatMarc91.py",
    "content": "def countdown(numero: int):\n    if numero >= 0:\n        print(numero)\n        countdown(numero - 1)\n\ncountdown(5)\n\n# Extra #\n\n# Sin recursividad \ndef factorial(number: int) -> int: # Li dic que m'ha de retorna un enter\n    calculo = 1\n    for i in range(1,number + 1):\n        calculo = i * calculo\n    print(f\"Este és el primer factorial {calculo}\")\n\nfactorial(5)\n\n# Con recursividad\ndef factorial_2(number: int) -> int: # Li dic que m'ha de retornar un enter\n    if number < 0:\n        print(\"Els números negatius\")\n        return 0\n    elif number == 0:\n        return 1\n    \n    return number * factorial_2(number - 1)\n\n      \n# print(factorial_2(5))\n\nnumeros = [0,1]\n\ndef fibonnacci(posicio: int)-> int:\n    num1 = numeros[(len(numeros)-1)]\n    num2 = numeros[(len(numeros)-2)]\n    sum_fibo = num1 + num2\n    numeros.append(sum_fibo)\n    if (len(numeros) <= posicio):\n        fibonnacci(posicio)\n    else:\n        return print(numeros[posicio])\nfibonnacci(13)\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/Bert008.py",
    "content": "# #06 RECURSIVIDAD\n'''\n/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n'''\n\n# recursividad\n\n\ndef retorno(n, m):\n    if n == m:\n        print(n)\n    elif n != m:\n        print(n)\n        retorno(n + 1, m)\n \nretorno(1, 100)\n\n# extra\n# factorial\ndef factorial(n):\n    if n <= 1:\n        return n\n    return n * factorial(n-1)\n\nfactor = factorial(8)\nprint(factor)\n\n# fibonachi\ndef fibonachi(n):\n    if n == 0:\n        return n\n    elif n == 1:\n        return n\n    else:\n        return fibonachi(n - 1) + fibonachi(n - 2)\n    \nfibo = fibonachi(8)\n\nprint(fibo)"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/BrianSilvero.py",
    "content": "\"\"\"\nEjercicios\n\"\"\"\n# def countdow(num:int):\n#     if num >= 0: \n#         print(num)\n#         countdow(num-1)\n\n# countdow(100)\n\n\"\"\"\nExtra\n\"\"\"\n\n# Factorial\ndef factorial(number:int):\n    if number < 0:\n        print(\"No se admiten numero negativos\")\n        return 0\n    elif number == 0:\n        return 1 \n    else:\n        return number * (factorial(number - 1))\nprint(factorial(3))\n\n# Fibonnacci \ndef fibonnacci(number:int):\n    if number <= 0:\n        print(\"Tienen que ser mayor que cero\")\n        return 0\n    elif number == 1:\n        return 0\n    elif number == 2:\n        return 2\n    else:\n        return \n\nprint(fibonnacci(5))"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/C-Gabs.py",
    "content": "#Reto 06\n\n''' Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).'''\n\ndef nums(n = 100):\n    if n >= 0:\n        print(n)\n        return nums(n-1)\n\nnums()\n\n\n#Reto extra\n\ndef factorial(n):\n    if n < 0:\n        print(\"Los numeros negativos no tienen factorial\")\n        return 0\n    elif n < 2:\n        return 1\n    else:\n        return n*factorial(n-1)\nprint(factorial(5))\n\n\ndef fibonacci(n):\n    if n <= 1:\n        return 0\n    if n < 3:\n        return 1\n    return fibonacci(n-1) + fibonacci(n-2)\n         \n\nprint(fibonacci(8))"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/CaveroBrandon.py",
    "content": "# EJERCICIO:\n# Entiende el concepto de recursividad creando una función recursiva que imprima números del 100 al 0.\"\"\"\n\n\ndef recursive_function(n=100):\n    if n < 0:\n        return\n    else:\n        print(n, end=' ')\n        recursive_function(n - 1)\n\n\n\"\"\" DIFICULTAD EXTRA (opcional):\nUtiliza el concepto de recursividad para:\n- Calcular el factorial de un número concreto (la función recibe ese número).\n- Calcular el valor de un elemento concreto (según su posición) en la sucesión de Fibonacci (la función recibe la posición).\n\"\"\"\n\n\ndef factorial(n):\n    if n == 0:\n        return 1\n    else:\n        return n * factorial(n - 1)\n\n\ndef fibonacci(n):\n    if n == 0:\n        return 0\n    elif n == 1:\n        return 1\n    else:\n        return fibonacci(n - 1) + fibonacci(n - 2)\n\n\nrecursive_function()\nfac = int(input('\\nEnter a number to calculate the factorial: '))\nprint(f'The factorial of {fac} is:', factorial(fac))\nfib = int(input('Enter a number to calculate fibonacci: '))\nprint(f'The fibonacci of {fib} is:', fibonacci(fib))\n\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/CesarCarmona30.py",
    "content": "'''\n  EJERCICIO: Entiende el concepto de recursividad creando una función recursiva que imprima\n  números del 100 al 0.\n'''\n\ndef numbers(number = 0):\n  if number == 100:\n    print(number)\n  else:\n    print(number)\n    numbers(number + 1)\n  return  \n\nprint('Números: del 0 al 100 mediante recursividad')\nnumbers()\n\n'''\n  EXTRA\n'''\n\n# Factorial de un número concreto:\n\ndef factorial(number):\n  if number == 0:\n    return 1\n  else:\n    return number * factorial(number - 1)\n\nwhile True:\n  user_number = input(\"Introduce un número entero para calcular su factorial: \")\n  if user_number.isnumeric():\n    user_number = int(user_number)\n    result = factorial(user_number)\n    print(f'!{user_number} = {result}')\n    break\n  else:\n    print(\"Por favor, introduce un número entero válido.\")\n\n# Serie de Fibonacci dada una posición como parámetro:\n\ndef fibonacci(number):\n  if number == 0:\n    return 0\n  elif number == 1 or number == 2:\n    return 1\n  else:\n    return fibonacci(number - 2) + fibonacci(number - 1)\n\nwhile True:\n  position = input(\"Introduce un número para calcular el valor de la serie de Fibonacci en esa posición: \")\n  if position.isnumeric():\n    position = int(position)\n    value = fibonacci(position)\n    print(f'Valor de la serie de Fibonacci en la posción {position} = {value}')\n    break\n  else:\n    print(\"Por favor, introduce una posición válida.\")"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/Chrisdev00.py",
    "content": "\"\"\"\n* EJERCICIO:\n* Entiende el concepto de recursividad creando una función recursiva que imprima\n* números del 100 al 0.\n*\n* DIFICULTAD EXTRA (opcional):\n* Utiliza el concepto de recursividad para:\n* - Calcular el factorial de un número concreto (la función recibe ese número).\n* - Calcular el valor de un elemento concreto (según su posición) en la \n*   sucesión de Fibonacci (la función recibe la posición).\n\"\"\"\n\n# La recursividad en Python (y en la programación en general) es un concepto poderoso \n# que se utiliza cuando una función se llama a sí misma directa o indirectamente. \n# La idea detrás de la recursividad es dividir un problema en subproblemas más pequeños \n# y resolverlos de manera recursiva hasta llegar a un caso base que se puede resolver directamente.\n\n# Una función recursiva es aquella que se llama a sí misma dentro de su definición.\n# En cada llamada recursiva, se trabaja con un conjunto de datos más pequeño \n# o se realiza algún tipo de operación para acercarse al caso base.\n\ndef print_numbers(n):\n\n    if n >= 0:\n        print(n)\n        print_numbers(n-1)\n\nprint_numbers(100)\n        \n\"\"\"\n        --------------------------  Dificultad Extra ---------------------------------------\n\"\"\"\n\ndef factorial(n):\n\n    if n == 0:\n        return 1\n    else:\n        return n * factorial(n-1)\n\nresul = factorial(5)\nprint(resul)\n\n\n\ndef fibonnaci(n):\n\n    if n <= 1:\n        return n\n    else:\n        return fibonnaci(n-1) + fibonnaci(n-2)\n\nres = fibonnaci(9)\nprint(res)\n\n    \n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/Complex303.py",
    "content": "\"\"\"\nRecursividad: es cuando una función se llama a sí misma para resolver un problema.\nSe usa cuando un problema se puede dividir en problemas más pequeños del mismo tipo.\n\"\"\"\n\n# def ejemplo():\n#     for i in range(100,-1,-1):\n#         print(i)\n\n# ejemplo()\n\n\ndef recursividad(num: int):\n    if num >= 0:\n        print(num)\n        recursividad(num -1)\n    \nrecursividad(10)\n\n\n\"\"\"* DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición). \"\"\"\n\n\n#Factorial de un numero\n\n# Definimos una función llamada factorialNumero que recibe un número entero como argumento\ndef factorialNumero(numero: int):\n    \n    # Primer caso: Si el número es menor que 0, no se puede calcular el factorial\n    if numero < 0:\n        print(\"El numero debe ser positivo\")\n        return None  # Terminamos la función y devolvemos None (sin resultado)\n    \n    # Segundo caso: Si el número es mayor o igual a 1\n    elif numero >= 1:\n        # Devolvemos el número multiplicado por el factorial del número anterior (n * (n-1)!)\n        return numero * factorialNumero(numero - 1)\n        # Aquí es donde ocurre la recursividad: la función se llama a sí misma con (numero - 1)\n        # y se sigue llamando hasta que llegue a 0\n    \n    # Tercer caso: Si el número es 0, su factorial es 1 (por definición matemática)\n    else:\n        return 1\n\n\nfactorial = 5\n\nprint(f\"El factorial de {factorial} es: {factorialNumero(factorial)}\")\n\n\n\n#Con bucle\ndef factoriabucle(num: int):\n    if num == 0 or num == 1:\n        return 1\n    elif num < 0:\n        print('El resultado debe de ser un numero positivo')\n        return None\n    else:\n        resultado = 1\n        for num in range(1, num +1):\n            resultado *= num\n        return resultado\n    \nprint(factoriabucle(-2))\n\n\n\n\n\n#Sucesion fibonassi\n\n# Definimos una función llamada sucesion_fibonassi que recibe un número entero\n# y devuelve otro entero (por eso el -> int)\ndef sucesion_fibonassi(num: int) -> int:\n\n    # Si la posición es menor a 0, no es válida para la sucesión de Fibonacci\n    if num < 0:\n        print(\"La posicion tiene que ser mayor que 0\")\n        return 0  # Terminamos la función devolviendo 0\n\n    # Caso base: si la posición es 1, el valor es 0 en Fibonacci (según esta versión)\n    if num == 1:\n        return 0\n\n    # Caso base: si la posición es 2, el valor es 1 en Fibonacci\n    if num == 2:\n        return 1\n\n    # Caso recursivo: para cualquier otro número\n    else:\n        # Se devuelve la suma de los dos números anteriores en la secuencia de Fibonacci\n        return sucesion_fibonassi(num - 1) + sucesion_fibonassi(num - 2)\n\nprint(sucesion_fibonassi(5))\n    \n\n#bucle for\ndef fibonassi(num: int):\n    # Definimos una función llamada 'fibonassi' que recibe un número entero 'num'\n    \n    num1 = 0  # Primer número de la sucesión de Fibonacci\n    num2 = 1  # Segundo número de la sucesión de Fibonacci\n\n    # Usamos un bucle for para repetir 'num' veces\n    for i in range(num):\n        # Imprimimos el valor actual de 'num1' seguido de un espacio, sin salto de línea\n        print(num1, end=\" \")\n\n        # Actualizamos ambos valores al mismo tiempo:\n        # - 'num1' toma el valor de 'num2'\n        # - 'num2' toma la suma de 'num1' (antes de actualizar) y 'num2'\n        num1, num2 = num2, num1 + num2\n\n# Llamamos a la función para mostrar los primeros 5 números de Fibonacci\nfibonassi(5)\n\n\n\n\n\n        \n        \n\n\n\n\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/D3rk1us.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n\"\"\"\n\n# Función recursiva\n\ndef recurFuncion(num):\n\n    if num == 0:\n        return num\n    else:\n        print(num)\n        return recurFuncion(num - 1)\n\nprint(recurFuncion(100))\n\n\n# /////////////////////////////////////////////////  DIFICULTAD EXTRA  /////////////////////////////////////////////////\n\n# Factorial\ndef factorial(num):\n\n    if num == 1:\n        return num\n    else:\n        return num * factorial(num - 1)\n\nprint(factorial(5))\n\n\n# Posición Fibonacci\n\ndef fibonacci(posicion):\n\n    if posicion == 0:\n        return 0\n\n    elif posicion == 1:\n        return 1\n\n    else:\n        return fibonacci(posicion - 1) + fibonacci(posicion - 2)\n\nprint(fibonacci(10))"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/DGrex.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n\"\"\"\n\ndef imprimir_numeros(numero):\n    if numero <= 0:\n        print(numero)\n        return\n    else:\n        print(numero)\n        imprimir_numeros(numero - 1)\n\nimprimir_numeros(100)\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n\"\"\"\n\ndef factorial_de_un_numero(numero, factorial = 1):\n\n    if numero < 0:\n        return \"El numero es negativo\"\n    if numero != 0 :\n        factorial= factorial * numero\n        return factorial_de_un_numero(numero - 1, factorial)\n    else:\n        return f\"El factorial es: {factorial}\"\n           \nprint(factorial_de_un_numero(5))\n\n\n\ndef fibonacci(posicion):\n    if posicion <= 0:\n        return \"La posición debe ser mayor o igual a 0\"\n    elif posicion == 1:\n        return 0\n    elif posicion == 2:\n        return 1\n    else:\n        return fibonacci(posicion - 1) + fibonacci(posicion - 2)\n\nprint(fibonacci(5)) \n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/DaniQB99.py",
    "content": "\n'''\nEJERCICIO:\n  Entiende el concepto de recursividad creando una función recursiva que imprima\n  números del 100 al 0.\n'''\n\n# FUNCIONES RECURSIVAS\nnum:int = 100\n\ndef func_recursiva(n: int) -> None:\n    if n >= 0:\n        print(n)\n        func_recursiva(n-1)\n\n\nfunc_recursiva(num)\n\n\n'''\nDIFICULTAD EXTRA (opcional):\n   Utiliza el concepto de recursividad para:\n   - Calcular el factorial de un número concreto (la función recibe ese número).\n   - Calcular el valor de un elemento concreto (según su posición) en la \n     sucesión de Fibonacci (la función recibe la posición).\n'''\n\nprint('\\n--- EJERCICIO EXTRA ---\\n')\n\n# FACTORIAL\ndef factorial(n: int) -> int:\n    if n < 0:\n        print('El numero debe ser positivo')\n    elif n == 0:\n        return 1\n    else:\n        return n * factorial(n-1)\n\nprint('Factorial de 5: ' + str(factorial(5)))\nprint('Factorial de 0: ' + str(factorial(0)))\nprint('Factorial de 24: ' + str(factorial(24)))\n\n# FIBONACCI SIMPLE\ndef fibonacci_simple(n: int) -> int:\n    if n < 0:\n        print('El numero debe ser positivo')\n        return 0\n    elif n == 0:\n        return 0\n    elif n == 1:\n        return 1\n    elif n == 2:\n        return 1\n    else:\n        return fibonacci_simple(n - 1) + fibonacci_simple(n - 2) # Devuelve el resultado de la suma de los dos anteriores\n    \nprint('\\nEJEMPLO DE FIBONACCI SIMPLE\\n')\nprint('Fibonacci de 5: ' + str(fibonacci_simple(5)))\nprint('Fibonacci de 0: ' + str(fibonacci_simple(0)))\nprint('Fibonacci de 24: ' + str(fibonacci_simple(24)))\n\n# FIBONACCI COMPLEJO    \ndef fibonacci_complejo(n: int) -> list[int]:\n    if n < 0:\n        print('El numero debe ser posit ivo')\n        return 0\n    elif n == 0:\n        return 0\n    elif n == 1:\n        return 0\n    elif n == 2:\n        return 1\n    else:\n        fibo = [0, 1]\n        for i in range(2, n):\n            fibo.append(fibo[i - 1] + fibo[i - 2]) \n        return fibo # Devuelve la lista de los resultados hasta la posicion n de la serie\n    \nprint('\\nEJEMPLO DE FIBONACCI COMPLEJO\\n')\nprint('Fibonacci de 5: ' + str(fibonacci_complejo(5)))\nprint('Fibonacci de 0: ' + str(fibonacci_complejo(0)))\nprint('Fibonacci de 24: ' + str(fibonacci_complejo(24))) "
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/Daparradom.py",
    "content": "### 06-RECURSIVIDAD ###\n\ndef cont_regresivo(num:int):\n    if num >= 0 :\n        print(num)\n        cont_regresivo(num-1)\n    else :\n        print(\"Fin conteo regresivo\")\n\ncont_regresivo(100)\n\ndef factorial(number) -> int:\n    if number == 0:\n        return 1\n    elif number < 0:\n        print(\"El numero debe ser entero positivo\")\n        return 0\n    else    :\n        return  number * factorial(number - 1)\n    \n\nmy_num = 8\nres = factorial (my_num)\nprint (f\"El factorial de {my_num} es {res}\")\nprint(\"--------------------------------\")\n\ndef fibo(pos):\n  if pos <= 0:\n     print(\"la posicion debe ser un entero positivo\")\n     return 0\n  elif pos == 1:\n      return 0\n  elif pos == 2 :\n      return 1\n  else :\n      return fibo(pos - 1) + fibo(pos - 2)\n  \nmy_pos = 6\n\nres_fibo = fibo(my_pos)\nprint(f\"El valor de la serie fibonacci en la posicion {my_pos} es {res_fibo} \")"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/DataCiriano.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n\"\"\"\n\n#Función recursiva: es aquella función que se llama a si misma dentro de su propia ejecución\n\ndef print_numbers_recursive(start:int, end:int):\n    if start <= end:\n        print(start)\n        print_numbers_recursive(start + 1, end)\n\nprint_numbers_recursive(0, 100)\n\n\n#----EXTRA----\n\n#Función factorial\n\ndef factorial(num:int) -> int:\n    if num == 0 or num == 1:\n        return 1\n    else:\n        return num * factorial(num - 1)\n    \nanswer = int(input(\"¿De qué número desea calcualr el factorial? \"))\n\nresult = factorial(answer)\nprint(f\"El factorial de {answer} es {result}\")\n\n#Función Fibonacci\n\ndef fibonacci(position:int):\n    if position == 0:\n        return 0\n    elif position == 1:\n        return 1\n    else:\n        return fibonacci(position - 1) + fibonacci(position - 2)\n    \nanswer = int(input(\"¿Qué posición de la serie de Fibonacci desea conocer? \"))    \n    \nresult = fibonacci(answer)\nprint(f\"El valor de Fibonacci de la posición {answer} es: {result}\")\n    \n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/DevKnn.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n \n */\"\"\"\n \n\"\"\"i = 100\nwhile(0<=i):\n    print(i)\n    i-=1\n    \"\"\"\nn = 5\ndef factorial(n):\n    if n < 1:\n        return 1\n    else:\n        resultado = n * factorial(n-1) \n        return resultado\nprint(factorial(n))\n\ndef finobacci(n):\n    if n <= 1:\n        return n\n    else:\n        return finobacci(n-1)+finobacci(n-2)\n\n\n\nn = 5\nprint(finobacci(n))\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/Dkp-Dev.py",
    "content": "\"\"\"\nEJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n\"\"\"\n\ndef countdown(number: int):\n    if number >= 0:\n        print(number)\n        countdown(number - 1)\n\n\ncountdown(100)\n\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n\"\"\"\n\ndef factorial(number: int) -> int:\n    if number < 0:\n        print(\"Los numeros negativos no pueden ser factoriales\")\n        return 0\n    elif number == 0:\n        return 1\n    else:\n        return number * factorial(number - 1)\n    \nprint(factorial(5))\n\n\ndef fibonacci(number: int) -> int:\n    if number <= 0:\n        print(\"La posicion tiene que ser mayor que cero\")\n        return 0\n    elif number == 1:\n        return 0\n    elif number == 2:\n        return 1\n    else:\n        return fibonacci(number - 1) + fibonacci(number -2)\n    \n\n\nprint(fibonacci(11))"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/EliasBonnin.py",
    "content": "# Ejercicio 06\n# En el siguiente URL https:/python.org Tenemos la documentacion de phyton.\n# Los retos se encuentran en https://retosdeprogramacion.\n\nNumero = 100\n\n\ndef Conteo_Numero(valor):\n    if valor < 0 or valor == 0:\n        print(\"Termina la recursividad en \", valor)\n    else:\n        print(valor)\n        Conteo_Numero(valor - 1)\n\n\nConteo_Numero(Numero)\n\n# Extra\n\n# Factorial de un numero concreto\n\n\ndef Factorial(valor: int) -> int:\n    if valor == 0:\n        return 1\n    else:\n        return valor * Factorial(valor - 1)\n\n# Variables\n\n\nNum_factorial = 4\n\nprint(Factorial(Num_factorial))\n\n\ndef fobanacci(num: int) -> int:\n    if num < 0:\n        print(\"La posicion tiene que ser mayor a cero\")\n        return 0\n    elif num == 0:\n        return 0\n    elif num == 1:\n        return 1\n    else:\n        return fobanacci(num - 1) + fobanacci(num - 2)\n\n\nprint(\"Foba\", fobanacci(10))\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/EmmanuelMMontesinos.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n */\n\"\"\"\n\n# Concepto de Recursividad:\n\ndef cuenta_atras(inicio):\n    if inicio != -1:\n        print(inicio)\n        cuenta_atras(inicio - 1)\ncuenta_atras(100)\n\n\"\"\"\n     * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n\"\"\"\ndef factorial(numero):\n    if numero < 0:\n        return f\"Entrada Erronea: {numero}\"\n    elif numero == 0 or numero == 1:\n        return 1\n    else:\n        return numero * factorial(numero - 1)\n        \nprint(factorial(5))\n\ndef fibon(numero):\n    if numero < 0:\n        return f\"Entrada Erronea: {numero}\"\n    elif numero == 0:\n        return 0\n    elif numero == 1:\n        return 1\n    else:\n        return fibon(numero - 1) + fibon(numero - 2)\n\nprint(fibon(4))"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/EricJoel-code.py",
    "content": "## Recursividad\n\n# Concepto: La recursividad es una técnica de programación en la que una función se llama a sí misma para resolver un problema. Se utiliza comúnmente para dividir problemas complejos en subproblemas más simples.\n\n# creando una función recursiva que imprima números del 100 al 0.\n\ndef cuenta_regresiva(num):\n    if num >= 0:\n        print(num)\n        cuenta_regresiva(num-1)\n    \ncuenta_regresiva(100)\n\n\"\"\" Explicación: La función cuenta_regresiva utiliza la recursividad para imprimir números del 100 al 0. En cada llamada, se verifica si el número actual es mayor o igual a 0. Si es así, se imprime el número y se realiza una llamada recursiva a la función con el número decrementado en 1. Esto continúa hasta que el número es menor que 0, momento en el cual la función deja de llamarse a sí misma y finaliza.\"\"\"\n\n\"\"\"Hacer una funcion recursiva para imprimir los numeros del 100 a 0, no es algo que se utilice comumente en la vida real, pero es un buen ejercicio para entender cómo funciona la recursividad. \"\"\"\n\n## Extra\n\n# Calcular el factorial de un número concreto (la función recibe ese número).\n\ndef factorial(n):\n    if n == 0:\n        return 1\n    elif n < 0:\n        print(\"El factorial no está definido para números negativos.\")\n    else:\n        return n * factorial(n-1)\n\nprint(factorial(5))\n\n# Calcular el valor de un elemento concreto (según su posición) en la sucesión de Fibonacci (la función recibe la posición).\n\ndef fibonacci(pos):\n    if pos < 0:\n        print(\"La posicion no puede ser negativa.\")\n    elif pos == 0:\n        return 0\n    elif pos == 1:\n        return 0\n    elif pos == 2:\n        return 1\n    else:\n        return fibonacci(pos-1) + fibonacci(pos-2)\n    \nprint(fibonacci(10))\n\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/FedeAirala.py",
    "content": "# #06 RECURSIVIDAD\n\n\n\"\"\"\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n\"\"\"\n\ndef recursividad (num):\n    if num >= 0:\n        print (num)\n        num-=1\n        recursividad(num)\n    else:\n        print (\"El programa recursivo a finalizado correctamente\")\n\nrecursividad(100)\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n\"\"\"\n\ndef rec_factorial(num:int,result=1):\n    if num == 0:\n        print (f\"El factorial de {x} = {result}\")\n    else:\n        return rec_factorial(num-1,result*num)\n\nx=int( input(\"Ingrese número que desea saber el factorial: \"))\nrec_factorial(x)\n\n\ndef fib(n):\n    if n < 2:\n        return n\n    else:\n        return fib(n-1) + fib(n-2)\n        \ny = int (input(\"Ingrese la posición de sucesió de fibonacci que desea conocer:\"))    \nresultado= fib(y)\nprint (f\"El valor en la posición {y} de fibonacci = {resultado}\")"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/GaboDev23.py",
    "content": "'''\nEJERCICIO:\nEntiende el concepto de recursividad creando una función recursiva que imprima números del 100 al 0.\n'''\ndef countdown(number: int):\n    if number >= 0:\n        print(number)\n        countdown(number-1)\n    \ncountdown(100)\n\nprint('-----------------------------------------------------')\n'''\nDIFICULTAD EXTRA (opcional):\nUtiliza el concepto de recursividad para:\n- Calcular el factorial de un número concreto (la función recibe ese número).\n- Calcular el valor de un elemento concreto (según su posición) en la sucesión de Fibonacci (la función recibe la posición).\n'''\n# Factorial\ndef factorial(n: int):\n    if n >= 0 and n <= 1:\n        return 1\n    elif n < 0:\n        print('No se puede calcular el factorial de un número negativo')\n        return 0\n        \n    return n * factorial(n - 1)\n\nnumero = int(input('Introduce un número: '));\nprint(f'El factorial de {numero} es {factorial(numero)}')\n\n# Fibonacci\n# 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89\ndef fibonacci(p: int):\n    if p <= 0:\n        print('La posición no puede ser negativa')\n        return 0\n    elif p == 1:\n        return 0\n    elif p == 2:\n        return 1\n    else:\n        return fibonacci(p - 1) + fibonacci (p - 2)\n\n    \nn = int(input('Introduce un número: '))\nprint(f'El fibonacci en la posición {n} es {fibonacci(n)}')"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/Gallitofast.py",
    "content": "# Ejercicio 06 \n\"\"\"\nRECURSIVIDAD\n\"\"\"\ndef cuenta_regresiva(n):\n    # Caso base: cuando llegamos a -1, terminamos la recursión\n    if n < 0:\n        return\n    # Imprimimos el número actual\n    print(n)\n    # Llamada recursiva con el siguiente número (n-1)\n    cuenta_regresiva(n - 1)\n\n# Llamamos a la función empezando en 100\ncuenta_regresiva(100)\n \ndef factorial(facto):\n    if facto == 0 or facto == 1:  # Caso base\n        return 1\n    else:\n        return facto * factorial(facto - 1)  # Paso recursivo\n    \nresultado = factorial(5)  # Calcula 5! = 120\nprint(resultado)     \n\ndef fibonacci(number: int)-> int:\n    if number <= 0:\n        print(\"La posición tiene que ser mayor que cero.\")\n        return 0\n    elif number <= 2:\n        return number -1\n    else:\n        return fibonacci(number-1) + fibonacci(number-2)\n    \nprint(fibonacci(10))\n\n    \n    \n\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/Gordo-Master.py",
    "content": "\"\"\" \nRecursividad\n\"\"\"\n\ndef numb_print(value:int):\n    print(value)\n    if value > 0:\n        numb_print(value-1)\n\n# numb_print(100)\n\n\n\"\"\"\nEjercicio extra\n\"\"\"\n\n\n\n# Factorial de un número\n\ndef factorial(value:int) -> int:\n    if value > 1:\n        fact = value * factorial((value-1))\n    elif value <= 1 and value >= 0:\n        fact = 1\n    else:\n        return None\n    return fact\n\nnumero_factorial = 5\n\nif factorial(numero_factorial) != None:\n    print(f\"{numero_factorial}! es: {factorial(numero_factorial)}\")\nelse:\n    print(f\"No existe el factorial de un numero negativo: {numero_factorial}\")\n\n\n\n\n# Buscador de Fibonacci\n\n\ndef fibonacci(pos:int) -> int:\n    if pos < 1:\n        return None\n    elif pos == 1:\n        return 0\n    elif pos == 2:\n        return 1\n    else:\n        return fibonacci(pos - 1) + fibonacci(pos - 2)\n    \n\npos_fibo = 0\nif pos_fibo >= 1:\n    print(f\"El valor en la {pos_fibo}º posicion de la sucesión de fibonacci es: {fibonacci(pos_fibo)}\")\nelse:\n    print(\"La posición debe ser mayor que 0\")\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/Hyromy.py",
    "content": "def serie(numero):\n    if numero >= 0:\n        print(numero)\n        return serie(numero -1) + 1\n    else:\n        return 0\nserie(100)\n\n# ---- DIFICULTAD EXTRA ----\n\ndef factorial(numero):\n    if numero < 1:\n        return 1\n    else:\n        return factorial(numero -1) * numero\nprint(factorial(5))\n\n\ndef fibonacci(index):\n    if index == 0:\n        return 0\n    elif index == 1:\n        return 1\n    else:\n        return fibonacci(index -1) + fibonacci(index -2)\nprint(fibonacci(10))"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/Irenetitor.py",
    "content": "#Recursive\n\ndef countdown(num: int):\n    if num >= 0:\n        print(num)\n        countdown(num - 1)\n\ncountdown(100)\n\n#Extra Exercise\n\n#Factorial\n\ndef factorial(numb:int):\n    if numb < 0:\n        print(f\"The number must be positive\")\n    elif numb == 1 or numb == 0:\n        return 1\n    else:\n        return numb * factorial(numb - 1)\n\nprint(factorial(34))\n\n#Fibonacci\n\ndef fibonacci(n):\n    if n < 0:\n        print(\"Please enter a non-negative number\")\n        return None\n    elif n == 0:\n        return 0\n    elif n == 1:\n        return 1\n    else:\n        return fibonacci(n - 1) + fibonacci(n - 2)\n\nprint(fibonacci(8))\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/JAFeito.py",
    "content": "for num in range(0,101):\n    print(100 - num)\n    \n    \ndef calc_fact (entero):\n    factorial = 1\n    for numero in range  (1,entero+1):\n        factorial = factorial * numero \n        \n    print(factorial)\n    \ncalc_fact(5)\n\ndef fibonacci(pos):\n    a = 0\n    b = 1\n   \n    for x in range (0,pos-1):\n        \n        c = a + b\n        a = b\n        b = c\n    print(a)\n        \n\nfibonacci(7)"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/JacMac45.py",
    "content": "# Recursividad\n\n# Ejercicio\n\ndef cuenta_atras (numero: int):\n    if numero >= 0:\n        print (numero)\n        cuenta_atras(numero - 1)\n    \n        \n    \ncuenta_atras (100)\n\n# Extra\n\ndef factorial (number: int) -> int:\n    if number < 0:\n        return 0\n    elif number == 0:\n        return 1\n    else:    \n        return number * factorial(number - 1)    \n    \n    \nprint(factorial (5))\n\ndef fibonacci(number:int) -> int:\n    if number <= 0:\n        print(\"La posición tiene que ser mayor que cero\")\n        return 0\n    elif number == 1:\n        return 0\n    elif number == 2:\n        return 1\n    else:\n        return fibonacci(number - 1) + fibonacci(number - 2)\n\nprint (fibonacci(10))  # 55 sera el resultado     \n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/Jav-mol.py",
    "content": "# --- Funciones Recursivas ---\n\ndef mostrar_numeros(n:int):\n    \"\"\" La funcion toma un numero y le va sumando uno hasta llegar a 100. \n\n    Args:\n        n (int): Numero Entero menor que 100\n    \"\"\"\n    if n == 100:\n        return\n    elif n > 100 or n < 0:\n        return\n    else:\n        print(n)\n        n += 1\n        mostrar_numeros(n)\n        \nmostrar_numeros(101)\nmostrar_numeros(-1)\nmostrar_numeros(1)\n\n\"\"\" Dificultad Extra \"\"\"\n\n# Factorial de un numero\ndef factorial(n:int):\n    print(n)\n        \n    if n < 0:\n        return 0\n    elif n == 0:\n        return 1\n    else:\n        return n * factorial(n - 1)\n\nprint(factorial(5))\n\n\n# Calcular la posicion de un numero en fibonacci\ndef calcular_posicion(posic:int, fibo:list=[0,1]):\n    \n    if posic < fibo[-1]:\n        print(fibo)\n        return f'La posicion no es valida'\n    elif posic == fibo[-1]:\n        print(fibo)\n        return f'La posicion en fibonacci es {fibo.index(posic) + 1}'\n\n    fibo.append(fibo[-1]+fibo[-2])\n    \n    return calcular_posicion(posic)    \n    \nprint(calcular_posicion(233))\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/JesusAntonioEEscamilla.py",
    "content": "# #06 - Python -> Jesus Antonio Escamilla\n\n\"\"\"\nEJERCIÓ\n\"\"\"\n# Definimos la función\ndef imprimir_números(n):\n    if n < 0:\n        return\n    print(n)\n    # Aquí es donde realiza la Recursividad\n    imprimir_números(n - 1)\n\nprint(\"Recursividad\")\nimprimir_números(100)\n\n\n\n\"\"\"\nEXTRA\n\"\"\"\n# Factorial\ndef factorial(n):\n    if n == 0 or n == 1:\n        return 1\n    return n * factorial(n - 1)\n\nprint(\"Factorial\")\nprint(factorial(5))\n\n# Fibonacci\ndef fibonacci(n):\n    if n == 0:\n        return 0\n    elif n == 1:\n        return 1\n    return fibonacci(n - 1 ) + fibonacci(n - 2)\n\nprint(\"Fibonacci\")\nprint(fibonacci(10))"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/JheisonQuiroga.py",
    "content": "\"\"\"\nRecursividad\n\nLa recursividad es una técnica en la cual una función se llama así misma \n\"\"\"\n\n\n\n# Ejemplo de recursividad\ndef numbers(n):\n    if n <= 0:\n        print(0)\n    else:\n        print(n)\n        numbers(n - 1) # Imprime los números de 100 - 0\n\nnumbers(100)\n\n\"\"\"\nExtra\n\"\"\"\n# Calcular el factorial de un número\n\ndef factorial(n):\n    if n <= 1:\n        return n * 1 # Caso base\n    else:\n        return n * factorial(n - 1) # Llamada recursiva\n    \nprint(factorial(5)) # 120\n\n# Sucesión de fibonacci con recursividad\n\ndef fibonacci(n):\n    if n == 0:  # Caso base 1\n        return 0\n    elif n == 1:  # Caso base 2\n        return 1\n    else:\n        return fibonacci(n - 1) + fibonacci(n - 2) # Llamada recursiva\n\nprint(\"-\" * 5, \"Fibonacci\", \"-\" * 5)\nprint(\"Resultado:\" , fibonacci(3)) # Resultado de la funcion (fibonacci(2) = 1 + fibonacci(1) = 1) = 2\n\n\n# Ejemplo con bucle del factorial\nnum = 5\n\nfor n in range(1, num):\n    num *= n\n    print(num)\n\n# Ejemplo con bucle While\n\na, b = 0, 1\n\nwhile a < 10:\n    print(a)\n    a, b = b, a + b\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/JoseAlberto13.py",
    "content": "\"\"\"EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\"\"\"\n\ninicio = 100\n\ndef funcionRecursiva(num):\n    if num >= 0:\n        print(num)\n        num -= 1\n        funcionRecursiva(num)\n\nfuncionRecursiva(inicio)\n\n\"\"\"* DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\"\"\"\n\ndef factorialRecursiva(num):\n    if num < 0:\n        print(\"Verifica el número ingresado \")\n        return 0\n    elif num == 0:\n        return 1\n    else:\n        resultado = num * factorialRecursiva(num-1)\n        print(f\"{num} * {int(resultado/num)} = {resultado}\") # Observamos la recursividad\n        return(resultado)\n\n\nprint(factorialRecursiva(7))\n\n\ndef fibonacciRecursiva(num):\n    if num <= 0:\n        print(\"Verfica el número ingresado \")\n        return 0\n    elif num == 1:\n        return 0\n    elif num == 2:\n        return 1\n    else:\n        resultado = fibonacciRecursiva(num -1) + fibonacciRecursiva(num -2)\n        return resultado\n    \nprint(fibonacciRecursiva(5))"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/JuanDAW37.py",
    "content": "\"\"\"EJERCICIO\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n\"\"\"\ndef contarAtras(numero:int):\n    if numero >= 0:\n        print(numero)\n        numero -= 1\n        contarAtras(numero) #La función se llama aquí recursivamente, si se da la condición\n\ncontarAtras(100)\n\n# DIFICULTAD EXTRA\n#Factorial\ndef factorial(numero:int)->int:  \n    if numero == 0:\n        return 1\n    elif numero < 0:\n        print('Los números negativos no son válidos')   \n        return 0\n    else:\n        return numero * factorial(numero -1)    \n\nn = factorial(4)\nprint(n)\n\n#Fibonacci\ndef fibonacci(posicion:int)->int:\n    if posicion <= 0 or posicion == 1:        \n        return 0    \n    elif posicion == 2:\n        return 1\n    else:\n        return fibonacci(posicion - 1) + fibonacci(posicion - 2)\n\nprint(fibonacci(10))"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/KevinED11.py",
    "content": "import functools\n\n\ndef decrement_counter(start_number: int = 100) -> None:\n    if start_number >= 0:\n        print(start_number)\n        decrement_counter(start_number - 1)\n\n\n@functools.lru_cache()\ndef factorial(number: int = 5) -> int:\n    return 1 if number == 1 else number * factorial(number - 1)\n\n\n@functools.lru_cache()\ndef fibonacci(number: int = 10) -> int:\n    if number <= 1:\n        return number\n\n    return fibonacci(number - 2) + fibonacci(number - 1)\n\n\ndef main() -> None:\n    decrement_counter(start_number=100)\n    print(factorial(number=5))\n    print(fibonacci(number=10))\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/Lio7master.py",
    "content": "\n#  EJERCICIO:\n#  Entiende el concepto de recursividad creando una función recursiva que imprima\n#  números del 100 al 0.\n\n#  DIFICULTAD EXTRA (opcional):\n#  Utiliza el concepto de recursividad para:\n#  - Calcular el factorial de un número concreto (la función recibe ese número).\n#  - Calcular el valor de un elemento concreto (según su posición) en la \n#    sucesión de Fibonacci (la función recibe la posición).\n\n\n# La recurdividad es una funcion que se llama asi misma para terminar una tarea repetitiva\n\n#La profundidad maxima de recursividad es de 999 en python\ndef countdown(number: int):\n    if number >= 0:\n        print(number)\n        countdown(number-1)\n\ncountdown(100)\n\n#Extra\n\n#Calculo de Factorial\ndef factorial(number: int)-> int:\n    if number < 0:\n        print(\"los numeros negativos no son validos\")\n        return 0\n    elif number == 0:\n        return 1\n    else:\n       return number * factorial(number - 1) #aqui la idea es n! = n * (n - 1) * (n - 2) * ... * 1\n#siendo que se manda a llamar asi mismo puesto que regresa el numero ya restado,ejemplo con 5:  5 * por la funcion de 4 y susecibamente  4 pediria la funcion 3... \n# hasta llegar a 0 que auto finaliza la funcion, y en se momento retrocede para el calculo final desde el que se multiplicarioa 1*1*2*3*4*5 ya que se acumularon.\n\nprint(factorial(5)) \n\n#Fibonacci\ndef fibonacci(number: int) -> int:\n    \n    if number <= 0:\n        print(\"No es una posición validad para contar\")\n        return 0\n    # elif number == 1 :\n    #     return 0 \n    #lo condensamos en el siguiente elif porque logicamente podemos entender que si el se solicita seran menores en -1  a la posicion solicitada \n    # 1 = 0 y 2 = 1 en la calculo de fibonacci\n    elif number <= 2:\n        return number - 1\n    else:\n        return fibonacci(number - 1) + fibonacci(number - 2)\n    #la suma se realiza de modo que la posicion marcara fib(7) = fib(6) + fib(5), donde se llaman bajo los criterios hasta llegar a posicion p1 = 0 y p2 = 1 de la cadena donde\n    # sucecibamente realizara hasta hacer la suma desde las posiciones mas bajas desde donde se ira calculan por pocision para posterior suma:\n    # (desgloce los fib a la izquierda, pero aplica el mismo para todos los elmentos hacer recursion) \n    # fib(p1)= 0 + fib(p2)= 1 -> fib(p3)=1 + fib(p4)=2 -> fib(p5)=3 + fib(p6)=5 -> fib(7)= 8\n    #al hacer el analicis anterior se puede entender que no seria lo mas optimo para el calculo posiciones altas ya que seria mejor un manejo distribuido\n    #para el calculo y con algun algoritmo mas pulido puesto que calculariamos varias veces las mismas posiciones con esta logica,\n    #conveniendo guardar los valores previmente calculados.\n\n    #COMO OBJETO DE EJEMPLIFICACION DE RECURCIVIDAD ES UTIL UNICAMENTE.\n\nprint(fibonacci(7))\n\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/LittleMabbit.py",
    "content": "'''\ndef num(x):\n  if x > -1:\n    print(x)\n    num(x-1)\n  else:\n    pass\n\nnum(100)\n'''\n## -- EXTRA --\n\ndef factorial(x):\n  if x == 0 or x == 1:\n    return 1\n  else:\n    return x * factorial(x - 1)\n\nnumero = 7\nresultado = factorial(numero)\nprint(f\"El factorial de {numero} es {resultado}\")\n\ndef fibonacci_recursivo(n):\n    if n <= 1: # Retornamos el valor que se introduce si es igual o menor a 1.\n        return n\n    else:\n        return fibonacci_recursivo(n - 1) + fibonacci_recursivo(n - 2) # Utilizamos la formula, en donde tomamos 'n' y le restamos uno, a eso le sumamos el valor de 'n' con dos dígitos restados, y así nos queda la formula.\n\nfor i in range(12): # Creamos 12 veces el número que recibe la función fibonacci y así podemos calcular mejor.\n  print(fibonacci_recursivo(i), end=\"-\")\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/LucasRebuffo.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */ \"\"\"\n\n\ndef recursive_print(start_value):\n    print(start_value)\n    if start_value > 0:\n        recursive_print(start_value - 1)\n\n\n\"\"\" recursive_print(100) \"\"\"\n\n\ndef recursive_factorial(num: int):\n    if num == 0:\n        return 1\n    return num * recursive_factorial(num - 1)\n\n\n\"\"\" print(recursive_factorial(0))\nprint(recursive_factorial(1))\nprint(recursive_factorial(2))\nprint(recursive_factorial(3))\nprint(recursive_factorial(4))\nprint(recursive_factorial(5))\nprint(recursive_factorial(6))\nprint(recursive_factorial(7))\n \"\"\"\n\ndef recursive_fibonacci(pos: int):\n    if pos == 0 or pos == 1:\n        return pos\n    return recursive_fibonacci(pos - 1) + recursive_fibonacci(pos - 2)\n\n\"\"\" print(recursive_fibonacci(6)) \"\"\""
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/LuisOlivaresJ.py",
    "content": "\"\"\"Función para imprimir números del 110 al 0.\"\"\"\n\ndef my_print(number: int):\n    print(number)\n    if number > 0:\n        my_print(number - 1)\n    return\n\n#my_print(6) # \"Descomentar\"\n\n\n\"\"\"Función para calcular el factorail.\"\"\"\n\ndef factorial(num: int) -> int:\n    if num < 0:\n        return 0\n    elif num == 0:\n        return 1\n    else:\n        return num*factorial(num-1)\n    \n#print(factorial(4))\n    \n\n\"\"\"Sucesión de Fibonacci\"\"\"\n\ndef fibo(num: int) -> int:\n    if num <= 1:\n        return 0\n    elif num == 2:\n        return 1\n    \n    else:\n        return fibo(num - 2) + fibo(num - 1)\n    \nprint(fibo(9))"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/Lumanet.py",
    "content": "# La recursividad es una técnica en programación donde una función se llama a sí misma\ndef imprimir_num(n):\n    if n < 0:\n        return\n    print(n)\n    imprimir_num(n - 1)\n\nimprimir_num(100)\n\n\n\"\"\"\nUtiliza el concepto de recursividad para:\n- Calcular el factorial de un número concreto (la función recibe ese número).\n- Calcular el valor de un elemento concreto (según su posición) en la \n  sucesión de Fibonacci (la función recibe la posición).\n\"\"\"\n\ndef factorial(n):\n    if n == 0 or n == 1:\n        return 1 # El factorial de 0 y 1 es 1\n    else:\n        return n * factorial(n - 1)\n\nnumero = 5\nresultado = factorial(numero) # 5 * 4 * 3 * 2 * 1 = 120\nprint(f\"El factorial de {numero} es {resultado}\") # 120\n\n\ndef fibonacci(n):\n    if n == 0:\n        return 0 # El primer número de la sucesión de Fibonacci es 0\n    elif n == 1:\n        return 1 # El segundo número de la sucesión de Fibonacci es 1\n    else:\n        return fibonacci(n - 1) + fibonacci(n - 2)\n\nposicion = 7\nvalor_fibonacci = fibonacci(posicion) # 0, 1, 1, 2, 3, 5, 8, 13\nprint(f\"El valor de la posición {posicion} en la sucesión de Fibonacci es {valor_fibonacci}\") # 13\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/Maanghel.py",
    "content": "\"\"\"\nEJERCICIO:\nEntiende el concepto de recursividad creando una función recursiva que imprima\n    números del 100 al 0.\n\nDIFICULTAD EXTRA (opcional):\nUtiliza el concepto de recursividad para:\n- Calcular el factorial de un número concreto (la función recibe ese número).\n- Calcular el valor de un elemento concreto (según su posición) en la \n    sucesión de Fibonacci (la función recibe la posición).\n */\n\"\"\"\n\ndef recursion_example(num = 100):  # Función con parámetro inicial por defecto en 100\n    \"\"\"Ejemplo de una funcion recursiva\"\"\"\n    if num < 0: # Caso base: cuando el número es menor que 0, detenemos la recursión\n        return None\n    print(num) # Imprime el número actual\n    return recursion_example(num - 1) # Llama a la función recursivamente con el número decrementado\n\nrecursion_example()\n\n# EXTRA\n\ndef recursion_factorial(num: int) -> int:\n    \"\"\"Retorna el factorial de un numero dado\"\"\"\n    if num == 1: # Caso base: el factorial de 1 es 1\n        return 1\n    return num * recursion_factorial(num - 1) # Llamada recursiva multiplicando el número actual por el factorial de (num - 1)\n\nprint(recursion_factorial(5))\n\ndef recursion_fibonacci(n: int) -> int:\n    \"\"\"Retorna la posicion en la serie Fibonacci segun un numero dado\"\"\"\n    if n < 0:\n        raise ValueError(\"La posición debe ser mayor o igual a cero.\") # Valida que n no sea negativa\n    if n == 0:\n        return 0 # Caso base: posición 0 → valor 0\n    if n == 1:\n        return 1 # Caso base: posición 1 → valor 1\n    return recursion_fibonacci(n - 1) + recursion_fibonacci(n - 2) # Llamada recursiva sumando los dos valores anteriores\n\nprint(recursion_fibonacci(6))\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/MarcosE-FerretoE.py",
    "content": "\"\"\" EJERCICIO \"\"\"\n\n\ndef counter(value: int):\n    if value == 0:\n        print(value)\n    else:\n        print(value)\n        counter(value - 1)\n\n\nnumber = 100\ncounter(number)\n\n\"\"\" DIFICULTAD EXTRA \"\"\"\n\nn = 17\n\n\ndef factorial(value: int):\n    if value == 0:\n        return 1\n    else:\n        return value * factorial(value - 1)\n\n\nprint(f\"The factorial of {n} is {factorial(n)}\")\n\n\ndef fibonacci(value: int):\n    if value == 0:\n        return 0\n    elif value == 1:\n        return 1\n    else:\n        return fibonacci(value - 1) + fibonacci(value - 2)\n\n\nprint(f\"The {n}° Fibonacci number is {fibonacci(n)}\")\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/MirandaYuber.py",
    "content": "\"\"\"\nRecursividad\n\"\"\"\n\n\ndef recursividad(number: int):\n    print(number)\n    if number > 0:\n        recursividad(number - 1)\n\n\nrecursividad(100)\n\n\"\"\"\nEXTRA\n\"\"\"\n\n\ndef factorial_recursivo(number: int) -> int:  # Calcular factorial\n    if number == 1:\n        return 1\n    else:\n        return number * factorial_recursivo(number - 1)\n\n\nprint(f'Respuesta Factorial recursivo: {factorial_recursivo(3)}')\n\n\ndef fibonacci_recursivo(number: int) -> int:\n    if number <= 0:\n        print('La posisción tiene que ser mayor que cero ')\n        return 0\n    elif number == 1:\n        return 0\n    elif number == 2:\n        return 1\n    else:\n        return fibonacci_recursivo(number - 1) + fibonacci_recursivo(number - 2)\n\n\nprint(f'Resultado Secuencia fibonacci recursivo: {fibonacci_recursivo(6)}')\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/NeosV.py",
    "content": "\n\n\ndef numeros_recursivo(n):\n\n    if n > 100:\n        return \"fin de la lista\"\n    else:\n        print (n)\n        return numeros_recursivo (n+1)\n    \nprint (numeros_recursivo(0))\n\n\n# Ejercicios extra dificultad\n\ndef factorial(n):\n\n    if n == 0:\n     return 1\n    else:\n       return (n * factorial(n-1)) \n    \nprint (factorial(9))\n\n\n\ndef fibonacci (n:int) -> int:\n   if n <= 0:\n    print (\"La posicion tiene que se mayor a 0\")\n    return 0\n   elif n == 1:\n    return 0\n   elif n == 2:\n    return 1\n   else:\n    return fibonacci(n-1) + fibonacci (n-2)\n\n\nprint (f\"el numero en la posicion ingresada es {fibonacci(10)}\")\n\n   \n      \n      \n   \n      \n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/NicoHeguaburu.py",
    "content": "\"\"\"\nejercicio de recursividad\n\"\"\"\n\ndef hola ():\n    print(\"nico\")\n    hola()\n\n#es una funcion recursiva ya que se vuelve a llamar dentro de la funcion\n\n\"\"\"\nFuncion recursiva que imprima los valores del 100 al 1\n\"\"\"\n\ndef fun_recursiva(num : int):\n    if num >= 0:\n        print(num)\n        fun_recursiva(num - 1)\n\n\n# fun_recursiva(100)\n\n\n\n\n#DIFICULTAD EXTRA\n\n#Calcular un factorial\n\ndef calc_factorial(num):   \n    if num == 0 or num == 1:\n        return 1\n    elif num < 0: \n        print(\"no se puede calcular el factorial de un numero negativo\")\n    else:\n        return num * calc_factorial(num - 1)\n        \n    \n\nprint(calc_factorial(10))\n\n\n\n#calcular fibonacci\n\ndef calc_fibonacci(num):\n    if num == 0:\n        return(0)\n    elif num == 1:\n        return(1)\n    elif num < 0:\n        print(\"fibonacci no tiene posiciones negativas\")\n    else:\n        return(calc_fibonacci(num - 1) + calc_fibonacci(num - 2))\n\n\nprint(calc_fibonacci(7))"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/Nicojsuarez2.py",
    "content": "# #06 RECURSIVIDAD\n> #### Dificultad: Difícil | Publicación: 05/02/24 | Corrección: 12/02/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/NightAlchemist.py",
    "content": "# print from 100 to 0\n\ndef cowntown(number):\n    if number >= 0:\n        print(number)\n        number = cowntown(number - 1)\n\ncowntown(100)\n\n#factorial\n\ndef factorial(n: int):\n    if n == 0:\n        return 1\n    else:\n        return n * factorial(n-1)\n    \nnumber_fact = int(input(\"Number to factor:\"))\nfactorial_result = print(f\"The factorial result is: {factorial(number_fact)}\")\n\n#fibonacci\n\ndef fibonacci(n: int):\n    if n == 0:\n        return 0\n    elif n == 1:\n        return 1\n    else:\n        return fibonacci(n-1) + fibonacci(n-2)\n\nnumber_fib = int(input(\"Fibonacci position number:\"))\nprint(f\"The value in this position of the Fibonacci series is: {fibonacci(number_fib)}\")"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/Nightblockchain30.py",
    "content": "# ** QUE ES LA RECURSIVIDAD?\n# ** La recursividad en la programacion es una tecnica de una funcion que se llama a si misma durante su ejecucion. Este proceso\n# ** se repite hasta que se cumpla una condicion base que evita que la funcion se llame recursivamente.\n\ndef recursive_function(number):\n    if number == 0:\n        print(number)\n        return\n    print(number)\n    recursive_function(number - 1)\n\nrecursive_function(50)\n\n# * DIFICULTAD EXTRA (opcional):\n# * Utiliza el concepto de recursividad para:\n# * - Calcular el factorial de un número concreto (la función recibe ese número).\ndef factorial_recursivo(numero):\n    if numero == 1 or numero == 0:\n        return 1\n    return numero * factorial_recursivo(numero - 1)\n\nresultado_del_factorial = factorial_recursivo(6)\nprint(f\"Este es el resultado del factorial de 6: {resultado_del_factorial}\")\n\n# * - Calcular el valor de un elemento concreto (según su posición) en la \n# *   sucesión de Fibonacci (la función recibe la posición).\ndef fibonacci_factorial(number, diccionario_de_valores = {}):\n    # Creamos la funcion fibonacci con un diccionario que guarda los valores de cada valor fibonacci\n    # Si el argumento es menor a 0, no validar\n    if (number < 0):\n        return None\n    elif (number == 0):\n        return 0\n    elif (number == 1):\n        return 1\n    # Si el valor del numero esta en el diccionario de valores de fibonacci, retornar\n    elif number in diccionario_de_valores:\n        return diccionario_de_valores[number]\n    # Si no es 0 ni 1 entonces llamar a la funcion dos veces sumandolas:\n    else:\n        result = fibonacci_factorial(number - 1, diccionario_de_valores) + fibonacci_factorial(number - 2, diccionario_de_valores)\n        # Guardar el valor de fibonacci en el diccionario con su clave y valor correspondiente\n        diccionario_de_valores[number] = result\n        # Retornar resultado\n        return result\n    \nresultado_fibonacci = fibonacci_factorial(15)\nprint(resultado_fibonacci)\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/Paprikaistkrieg.py",
    "content": "#recursividad\n\n\n\"\"\"\nRecursividad es una técnica de programación donde una función se llama a sí misma para resolver un problema.\nCada llamada a la función trabaja en una versión más pequeña del problema hasta llegar a un caso base que se puede resolver directamente.\nEs importante definir un caso base para evitar llamadas infinitas y asegurar que la recursión termine.\nLa recursividad es útil para problemas que pueden dividirse en subproblemas similares, como el cálculo de factoriales, \nla generación de secuencias (como Fibonacci) y \nla exploración de estructuras de datos (como árboles y grafos).\nSin embargo, la recursividad puede ser menos eficiente en términos de uso de memoria y tiempo de ejecución en comparación con las soluciones iterativas, \nespecialmente para problemas con una gran profundidad de recursión.\nCada llamada a una función recursiva se apila en la memoria hasta que se alcanza el caso base, lo que puede llevar a un uso significativo de memoria.\nAdemás, cada llamada a la función implica un pequeño overhead debido a la gestión de la pila de llamadas.\nPor lo tanto, es importante considerar si la recursividad es la mejor solución para un problema específico, especialmente en casos donde la profundidad de recursión puede ser grande.\nEn algunos lenguajes de programación, como Python, existe un límite en la profundidad de recursión para evitar desbordamientos de pila, \nlo que puede ser una limitación para problemas que requieren una gran cantidad de llamadas recursivas.\nEn resumen, la recursividad es una herramienta poderosa en programación que puede simplificar la solución de ciertos problemas, \npero debe usarse con cuidado debido a sus implicaciones en el rendimiento y el uso de memoria.\nEs importante entender cuándo y cómo usar la recursividad de manera efectiva.\nAdemás, algunas funciones recursivas pueden ser optimizadas mediante técnicas como la memorización o la recursión de cola para mejorar su eficiencia.\nLa memorización es una técnica de optimización que consiste en almacenar los resultados de funciones costosas para evitar cálculos redundantes en futuras llamadas con los mismos argumentos.\nLa recursión de cola es una forma de recursión donde la llamada recursiva es la última operación en la función, \nlo que permite optimizaciones por parte del compilador o intérprete para reutilizar el marco de pila actual y reducir el uso de memoria.\nSin embargo, Python no optimiza la recursión de cola, por lo que su uso no mejora el rendimiento en este lenguaje.\nEn conclusión, la recursividad es una técnica valiosa en programación que, cuando se usa adecuadamente, puede simplificar la solución de problemas complejos.\nSin embargo, es crucial considerar sus limitaciones y optimizaciones para garantizar un rendimiento eficiente.\n\"\"\"\n\n\"\"\"/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\"\"\"\ndef print_numbers(number: int) -> int: #aqui definimos la funcion, number es un parametro, print_numbers es el nombre de la funcion\n    if number >= 0: #caso base, si el numero es mayor o igual a 0\n        print(number) #imprime el numero\n        return print_numbers(number-1) #llamada recursiva, se llama a si misma con el numero -1\n\ndef factorial(n: int) -> int:\n    if n == 0:\n        return 1\n    else:\n        return n * factorial(n-1)\n\ndef fibonacci(n: int) -> int:\n    if n == 0:\n        return 0\n    elif n == 1:\n        return 1\n    else:\n        return fibonacci(n-1) + fibonacci(n-2)\nprint_numbers(100)\nprint(factorial(5))\nprint(fibonacci(8)) #Salida: 21\n#La función print_numbers imprime números del 100 al 0 de forma recursiva.\n#La función factorial calcula el factorial de un número dado de forma recursiva.\n#La función fibonacci calcula el n-ésimo número de Fibonacci de forma recursiva.    \n#Por ejemplo, fibonacci(8) devuelve 21, que es el 8º número en la sucesión de Fibonacci (0, 1, 1, 2, 3, 5, 8, 13, 21).\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/Paula2409.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\"\"\"\n\ndef print_numbers(number: int) -> int:\n    if number >= 0:\n        print(number)\n        return print_numbers(number-1)\n\nprint(print_numbers(100))\n\ndef factorial(number: int) -> int:\n    try:\n        if number <= 1:\n            return number\n        return number * factorial(number-1)\n    except ValueError:\n        print('El valor ingresado no es apropiado para el calculo')\n        \nprint(factorial(5))\n\ndef fibonacci(number: int) -> int:\n    if number <= 1:\n        return 0\n    elif number == 2:\n        return 1\n    else:\n        return fibonacci(number - 1) + fibonacci(number - 2)\n\nprint(fibonacci(8))\n    "
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/Pipe281.py",
    "content": "def reducir(n):\n    \"\"\"Función recursiva que devuelve los números del 100 al 1.\"\"\"\n    if n == 0:\n        return []\n    else:\n        return [n] + reducir(n - 1)\n\n# Ejemplo de uso de la función recursiva\nnumeros = reducir(100)\nprint(numeros)\n\n# Factorial #\ndef factorial(n):\n    \"\"\"Función recursiva para calcular el factorial de un número.\"\"\"\n    if n == 0:\n        return 1\n    else:\n        return n * factorial(n - 1)\n\n# Ejemplo de uso de la función factorial\nnumero = 5  # Aquí puedes ingresar el número para calcular su factorial\nresultado = factorial(numero)\nprint(f\"El factorial de {numero} es {resultado}\")\n\n# Fibonaci #\ndef fibonacci(posicion):\n    \"\"\"Función recursiva para calcular el valor de un elemento en la secuencia de Fibonacci.\"\"\"\n    if posicion <= 1:\n        return posicion\n    else:\n        return fibonacci(posicion - 1) + fibonacci(posicion - 2)\n\n# Ejemplo de uso de la función para encontrar el valor en la posición deseada\nposicion = 7  # Aquí puedes ingresar la posición del elemento que deseas calcular\nvalor = fibonacci(posicion)\nprint(f\"El valor en la posición {posicion} de la secuencia de Fibonacci es {valor}\")\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/RicardiJulio.py",
    "content": "#  * EJERCICIO:\n#  * Entiende el concepto de recursividad creando una función recursiva que imprima\n#  * números del 100 al 0.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Utiliza el concepto de recursividad para:\n#  * - Calcular el factorial de un número concreto (la función recibe ese número).\n#  * - Calcular el valor de un elemento concreto (según su posición) en la \n#  *   sucesión de Fibonacci (la función recibe la posición).\n\n# Recursividad:\n\ndef secuencia(n):\n    if n == 0: # ---> Caso base\n        return 0\n    else:\n        print(n)\n        return secuencia(n-1) # ---> Llamada recursiva\n    \nsecuencia(100)\n\n# DIFICULTAD EXTRA\n\ndef factorial(n):\n    if n == 0 or n == 1: # ---> Caso base\n        return 1\n    else:\n        return n * factorial(n-1) # ---> Llamada recursiva\n     \nprint(factorial(5))\n\ndef fibonacci(p):\n    if p == 0:\n        return 0\n    elif p == 1:\n        return 1\n    else:\n        return fibonacci(p-1) + fibonacci(p-2)\n    \nprint(fibonacci(9))\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/RoniPG.py",
    "content": "# @RoniPG\n\n\"\"\"\nEJERCICIO:\nEntiende el concepto de recursividad creando una función recursiva que imprima\nnúmeros del 100 al 0.\n\"\"\"\ncount=100\ndef imprimirNumeros():\n    global count\n    if (count > -1) and (count<101):\n        print(f\"{count},\")\n        count-=1\n        imprimirNumeros()\n    else:\n        count=0\n\nimprimirNumeros()\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\nUtiliza el concepto de recursividad para:\n- Calcular el factorial de un número concreto (la función recibe ese número).\n\"\"\"\nresult =1\ndef factorial(a:int):\n    global count\n    global result\n    if count < a -1:\n        result=result*(2)\n        count +=1\n        factorial(a)\n    else:\n        print(f\"{a}! = {result}\")\n        count=0\n        return result\n    return 0\n\nfactorial(6)\n\"\"\"\n- Calcular el valor de un elemento concreto (según su posición) en la \n  sucesión de Fibonacci (la funciún recibe la posición).\n\"\"\"\nresultado=0\nresultado2=1\ndef fibonacci(a:int):\n    global count\n    global resultado\n    global resultado2\n    if a==1:\n        print(0)\n        return 0\n    elif a==2 and a==3:\n        print(1)\n        return 0\n    elif count+2<a:\n        x=resultado2+resultado\n        resultado=resultado2\n        resultado2=x\n        count+=1\n        fibonacci(a)\n    elif count+2>=a:\n        print(resultado2)\n        count=0\n        return 0\n    return 0\n\nfibonacci(6)\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/RuhlMirko.py",
    "content": "def countdown(number: int):\n    if number >= 0:\n        print(number)\n        countdown(number - 1)\n\n\ncountdown(100)\n\nprint(\"\\nDificultad extra:\")\n\n\ndef factorial(numero: int):\n    if numero < 0:\n        return 0\n    elif numero == 0:\n        return 1\n\n    return numero * factorial(numero - 1)\n\n\ndef fibonacci(posicion: int) -> int:\n    if posicion <= 0:\n        return 0\n    elif posicion == 1:\n        return 0\n    elif posicion == 2:\n        return 1\n    else:\n        return fibonacci(posicion - 1) + fibonacci(posicion - 2)\n\n\nprint(factorial(6))\nprint(fibonacci(10))\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/Rusanov16.py",
    "content": "\"\"\"/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\"\"\"\n#*-------------------------------------------------------------------------------------------------------------#\nprint(\"-----------------------------------------------------------------------------------------------------\")\nprint(\"Recursividad\")\n\ndef numero_recursivo(n):\n    for i in range(n, -1, -1):\n        print(i)\nnumero_recursivo(100)\n\n#*-------------------------------------------------------------------------------------------------------------#\nprint(\"-----------------------------------------------------------------------------------------------------\")\nprint(\"Factorial\")\ndef factorial(n):\n    resultado = 1\n    for i in range(2, n + 1): \n        resultado *= i\n    return resultado\n\nnumero = int(input(\"Indique el número: \"))\nresultado = factorial(numero)\nprint(f\"El factorial de {numero} es {resultado}\")\n\n#*-------------------------------------------------------------------------------------------------------------#\nprint(\"-----------------------------------------------------------------------------------------------------\")\nprint(\"Fibonacci\")\ndef fibonacci(n):\n    if n <= 0:\n        return \"La posición debe ser un número entero positivo.\"\n    elif n == 1:\n        return 0  \n    elif n == 2:\n        return 1  \n    else:\n        return fibonacci(n - 1) + fibonacci(n - 2) \n\nposicion = int(input(\"Ingrese la posición en la sucesión de Fibonacci: \"))\nresultado = fibonacci(posicion)\nprint(f\"El elemento en la posición {posicion} de la sucesión de Fibonacci es {resultado}\")"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/Sac-Corts.py",
    "content": "\"\"\"\n  EJERCICIO\n\"\"\"\n\ndef imprimir_descendente(n):\n    # Caso Base: cuando n es menor que 0, terminamos la recursión\n    if n < 0:\n        return\n    # Caso Recursivo\n    # Imprimimos el número actual\n    print(n)\n    # Llamamos a la función con el siguiente número menor\n    imprimir_descendente(n - 1)\n\n# Llamamos a la función con el valor inicial 100\nimprimir_descendente(100)\n\n\"\"\"\n DIFICULTAD EXTRA\n\"\"\"\n\ndef factorial(n):\n    # Caso Base: el factorial de 0 o 1 es 1\n    if n == 0 or n == 1:\n        return 1\n    # Caso Recursivo: n! = n * (n-1)!\n    else: \n        return n * factorial(n - 1)\n\nprint(factorial(5))\n\ndef fibonacci(n):\n    # Caso Base: la secuencia inicia con 0 y 1\n    if n == 1:\n        return 1\n    elif n == 0:\n        return 0\n    # Caso Recursivo: fn: fn - 1 + fn - 2\n    else: \n        return fibonacci(n - 1) + fibonacci(n - 2)\n    \nprint(fibonacci(10))\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/SaezMD.py",
    "content": "#06 Recursividad\n\"\"\"\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la sucesión de Fibonacci (la función recibe la posición).\n\"\"\"\n\n\ndef decreaseFactorial(number: int)-> int:\n    \"\"\"in a recursive mode, decrease from a number to 0\"\"\"\n    if number == 0:\n        return print(0)\n    else:\n        print(number)\n        return decreaseFactorial(number-1)\n\ndecreaseFactorial(100)\n\n#DIFICULTAD EXTRA (opcional):\n\n#factorial from a given number\ndef factorialRecursive(number: int) -> int:\n\n    if number == 1 or number == 0:\n        return 1\n    elif number < 0 :\n        print(\"Negative numbers are not allowed.\")\n        return 0\n    else:\n        return number * factorialRecursive(number-1)\n\nprint(factorialRecursive(7))\nprint(factorialRecursive(0))\nprint(factorialRecursive(-10))\n\n#calc the value in a Fibonacci list by the given position\n\ndef fiboList(position: int = 51) -> list:\n    \"\"\"this functions returns the value of a position in a Fibonacci list\"\"\"\n    listFibo = [0,1]\n    for i in range(2, position):\n        listFibo.append(listFibo[i-2]+listFibo[i-1]) \n        #print(i)\n        #print(i,\" - \", x)\n    return print(listFibo[position-1])\n    \nfiboList(10)\nfiboList(5)\n\n# recursive Fibonacci\n\ndef fiboPositionRecursive(position: int)-> int:\n    \"\"\"function to return the value of a position in a Fibnonacci list\"\"\"\n\n    if position <= 0:\n        print(\"Position must be greater than 0.\")\n        return 0\n    elif position == 1:\n        return 0\n    elif position == 2:\n        return 1\n    else:\n        return(fiboPositionRecursive(position-1) + fiboPositionRecursive(position-2))\n\n\nprint(fiboPositionRecursive(10))\nprint(fiboPositionRecursive(5))\nprint(fiboPositionRecursive(0))\n\n\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/SergioGI99.py",
    "content": "\"\"\"\n------------\nRECURSIVIDAD\n------------\nEJERCICIO:\nEntiende el concepto de recursividad creando una función recursiva que imprima\nnúmeros del 100 al 0.\nDIFICULTAD EXTRA (opcional):\nUtiliza el concepto de recursividad para:\n- Calcular el factorial de un número concreto (la función recibe ese número).\n- Calcular el valor de un elemento concreto (según su posición) en la \n  sucesión de Fibonacci (la función recibe la posición * EJERCICIO:)\n\"\"\"\ndef countdown(number: int):\n    if number >= 0:\n        print(number)\n        countdown(number - 1)\n\ncountdown(100)\n\ndef factorial(number: int) -> int:\n    if number < 0:\n        print(\"Los números negativos no son validos\")\n        return 0\n    elif number == 0:\n        return 1\n    else:\n        return number * factorial(number - 1)\n\nprint(factorial(10))\n\ndef fibonacci(number: int) -> int:\n    if number <= 0:\n        print(\"La posición tiene que ser mayor que cero\")\n        return 0\n    elif number == 1:\n        return 0\n    elif number == 2:\n        return 1\n    else:\n        return fibonacci(number - 1) + fibonacci(number - 2)\n\nprint(fibonacci(10))"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/SooHav.py",
    "content": "# 06 -RECURSIVIDAD\n\n# EJERCICIO: Entiende el concepto de recursividad creando una función recursiva que imprima\n# numeros del 100 al 0.\n\ndef imprimir_numeros(n):\n    if n >= 0:\n        print(n)\n        imprimir_numeros(n - 1)\n\n\nimprimir_numeros(100)\n\n# EJERCICIO EXTRA: Utiliza el concepto de recursividad para:\n# - Calcular el factorial de un número concreto (la función recibe ese número).\n\n\ndef factorial(n: int) -> int:\n    if n == 0 or n == 1:\n        resultado = 1\n    elif n > 1:\n        resultado = n*factorial(n-1)\n    return resultado\n\n\nnumero = int(input(\"Por favor ingrese un número a factorizar: \"))\nresultado = factorial(numero)\nprint(resultado)\n\n# - Calcular el valor de un elemento concreto (según su posición) en la sucesión de Fibonacci (la función recibe la posición).\n\n\ndef fibonacci(n: int) -> int:\n    if n <= 0:\n        return 0\n    elif n == 1 or n == 2:\n        return 1\n    else:\n        return fibonacci(n - 1) + fibonacci(n - 2)\n\n\nposicion = int(input(\"Por favor ingrese un número entero de posicion: \"))\nvalor = fibonacci(posicion)\nprint(\n    f\"El valor en la posición {posicion} de la secuencia de Fibonacci es: {valor}\")\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/TheReDNooB.py",
    "content": "\"\"\"\nRecursivdidad\n\"\"\"\n\n# imprime los numeros del 1 al 100\ndef print_numbers(number: int)-> int:\n    if number >= 0 and number <= 100:  \n        print(number)\n        print_numbers(number + 1)\nprint_numbers(1)\n\n\"\"\"Dificultad extra\"\"\"\n\ndef factorial(num:int)-> int:\n    if num < 0:\n        print(\"No se puede calcular el factorial de un numero negativo\")\n        return 0\n    elif num == 0:\n        return 1\n    else:\n        return num * factorial(num - 1)\n    \n\nval = 4\nprint(f\"el factorial de {val} es {factorial(val)}\")\n\n\ndef fibonacci(num:int)-> int:\n    if num <= 0:\n        print(\"No se puede calcular el fibonacci de un numero negativo\")\n        return 0\n    elif num == 1:\n        return 0\n    elif num == 2:\n        return 1\n    else:\n        return fibonacci(num - 1) + fibonacci(num - 2)"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/Tomu98.py",
    "content": "\"\"\" Reto 06: Recursividad \"\"\"\n\n# Ejercicio\ndef countdown(n: int):\n    if n >= 0:\n        print(n)\n        countdown(n - 1)\n\ncountdown(100)\n\n\n\n\"\"\" Reto extra \"\"\"\n\ndef factorial(n: int) -> int:\n    if n < 0:\n        return \"Los números negativos no son válidos\"\n    if n in (0, 1):\n        return 1\n    return n * factorial(n - 1)\n\nprint(factorial(5))\n\ndef fibonacci(n: int) -> int:\n    if n <= 0:\n        return \"La posición tiene que ser mayor que cero\"\n    if n <= 2:\n        return n - 1\n    return fibonacci(n - 1) + fibonacci(n - 2)\n\nprint(fibonacci(5))\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/TroyNebula.py",
    "content": "'''\r\n * Entiende el concepto de recursividad creando una función recursiva que imprima\r\n * números del 100 al 0.\r\n '''\r\n\r\n# Recursividad -----------------------------------------------\r\ndef func_recursive(start:int, end:int):\r\n    if start >= end:\r\n        print(start)\r\n        func_recursive(start -1, end)\r\n\r\nfunc_recursive(100, 0)\r\n\r\nprint()\r\n# Función sin tener que usar la recursividad -----------------------------------------------\r\ndef func_sin():\r\n    for i in range (100,-1,-1):\r\n        print (i)\r\n        i +=1\r\n\r\nfunc_sin()\r\n\r\n'''\r\n * DIFICULTAD EXTRA (opcional):\r\n * Utiliza el concepto de recursividad para:\r\n * - Calcular el factorial de un número concreto (la función recibe ese número).\r\n * - Calcular el valor de un elemento concreto (según su posición) en la \r\n *   sucesión de Fibonacci (la función recibe la posición).\r\n'''\r\nprint()\r\n\r\n'''El factorial de un número concreto es el producto de todos los enteros positivos desde 1 hasta ese número. \r\nSe representa con el símbolo \"!\" y se calcula multiplicando todos los números enteros positivos menores o iguales al número dado. \r\nPor ejemplo, el factorial de 5 (denotado como 5!) es igual a 5 × 4 × 3 × 2 × 1, que es igual a 120. \r\nEn notación matemática, se expresa como: n! = n × (n-1) × (n-2) × ... × 2 × 1\r\nEs importante mencionar que el factorial de 0 (0!) se define como 1 por convención matemática.'''\r\n\r\n'''La secuencia de Fibonacci es una serie de números en la que cada número es la suma de los dos anteriores. \r\nLa secuencia comienza típicamente con los números 0 y 1, y los siguientes números son la suma de los dos números anteriores. \r\nAsí que la secuencia comienza como: 0, 1, 1, 2, 3, 5, 8, 13, 21, y así sucesivamente.\r\nMatemáticamente se representa así: \r\nF(0) = 0\r\nF(1) = 1\r\nF(n) = F(n-1) + F(n-2) para n > 1'''\r\n\r\n# Factorial  -----------------------------------------------\r\ndef factorial(numero):\r\n    if numero < 1:\r\n        return 1\r\n    else:\r\n        return factorial(numero -1) * numero\r\nprint(factorial(5))\r\n\r\n# Fibonacci  -----------------------------------------------\r\ndef fibonacci(index):\r\n    if index == 0:\r\n        return 0\r\n    elif index == 1:\r\n        return 1\r\n    else:\r\n        return fibonacci(index -1) + fibonacci(index -2)\r\nprint(fibonacci(10))\r\n\r\n# Me he complicado mucho la vida pero quería practicar otras maneras de llegar a lo mismo y crear listas al mismo tiempo\r\n# Propuesta muy larga para factorial:\r\nlista:list=[]\r\n\r\ndef num_factorial(f:int):\r\n    if f>=1:\r\n        lista.append(f)\r\n        num_factorial(f-1)\r\n\r\nnum_factorial (5)  \r\nprint (lista)\r\n\r\nprimero:int = lista[0]\r\nlargo:int = len(lista)\r\nultimo:int = lista[largo - 1]\r\n\r\nprint (primero) # 5\r\nprint (largo) #5\r\nprint (ultimo) #1\r\n\r\ndef calcula_factorial(num1, num2):\r\n    resultado = 1\r\n    for j in range(num1, (num2 + 1)):\r\n        resultado *= j\r\n    return resultado\r\n\r\nprint (calcula_factorial(ultimo, primero))\r\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/VictorRivero1204.py",
    "content": "\"\"\"\nEjercicio\n\"\"\"\n\n# def countdown(number: int):\n#     if number  >= 0:\n#         print(number)\n#         countdown(number - 1)\n\n# countdown(100)\n\n\"\"\"\nExtra\n\"\"\"\n\ndef factorial(number: int) -> int:\n    if number < 0:\n        print(\"Los numeros negativos no son validos\")\n        return 0\n    elif number == 0:\n        return 1\n    else:\n        return number * factorial(number - 1)\n\nprint(factorial(5))\n\ndef fibonacci(number:int) -> int:\n    if number <= 0:\n        print(\"La posicion tiene que ser mayor que cero\")\n        return 0\n    elif number <= 1:\n        return 0\n    elif number == 2:\n        return 1\n    else:\n        return fibonacci(number - 1) + fibonacci(number - 2) \n    \n\nprint(fibonacci(5))"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/Yani-Git.py",
    "content": "\"\"\"\"\nLa recursividad en Python (y en otros lenguajes) es una técnica de programación donde una función se llama a sí misma para resolver un problema.\n\n¿Para qué se usa?\nSe usa generalmente para resolver problemas que pueden dividirse en subproblemas más pequeños del mismo tipo, como:\n\nFactoriales\n\nFibonacci\n\nBúsqueda en estructuras como árboles\n\nProblemas como las torres de Hanoi\n\nhay que evaluar cuando tiene sentido utilizar recursividad y cuando es necesario utilizar un bucle \n\n\"\"\"\n\n#Ejercicio \n\n#def hello ():\n#    hello ()\n\n\n\n#hello ()\n\ndef countdown (number: int):\n    if number >= 0: \n        print(number)\n        countdown (number - 1)\n\ncountdown  (100)\n\n\n\"\"\"\nExtra\n\n\"\"\"\ndef factorial (number: int) -> int:\n    if number < 0:\n        print (\"Los números negativos no son  validos\")\n        return 0 \n    elif number == 0:\n        return 1\n    else:\n        return number * factorial (number -1) \n\nprint(factorial (5))\n\n\n\"\"\"\n🔁 CUÁNDO USAR BUCLES (for, while)\nUsá bucles cuando:\n\n✅ El número de repeticiones es conocido o fácilmente controlable.\n✅ No necesitás dividir el problema en subproblemas más pequeños.\n✅ Querés mantener eficiencia en memoria y velocidad.\n✅ El lenguaje (como Python) no optimiza bien la recursividad.\n\n🔹 Ejemplos:\n\nRecorrer listas, diccionarios, archivos, etc.\n\nEjecutar una acción hasta que se cumpla una condición.\n\nContar, filtrar, sumar elementos.\n\"\"\"\n\"\"\"\n🔁 CUÁNDO USAR RECURSIVIDAD\nUsá recursividad cuando:\n\n✅ El problema puede dividirse naturalmente en subproblemas del mismo tipo.\n✅ La estructura del problema es jerárquica o en forma de árbol (como árboles binarios, carpetas, etc).\n✅ Es más intuitivo o limpio usar recursividad (aunque menos eficiente).\n✅ No te importa tanto la eficiencia o trabajás con un caso pequeño.\n\n🔹 Ejemplos:\n\nFactorial de un número.\n\nSucesión de Fibonacci.\n\nBúsqueda en estructuras recursivas (como árboles o grafos).\n\nRecorrer carpetas o estructuras anidadas.\n\n\"\"\"\n\n\ndef fibonacci (number: int) -> int: \n    if number <= 0:\n        print (\"Los posición tiene que ser mayor que cero\")\n        return 0\n    elif number == 1:\n        return  0\n    elif number == 2:\n        return 1\n    else: \n        return fibonacci (number - 1) + fibonacci(number - 2)\n\nprint (fibonacci (4))"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/YgriegaSB.py",
    "content": "\"\"\" \n\n/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n \n \"\"\"\n\n\ndef count_to_one(n):\n    print(n)\n    if n > 1:\n        count_to_one(n - 1)\n\ncount_to_one(50)\n\n\ndef factorial(n):\n    if(n > 1):\n        return n * factorial(n - 1)\n    return 1\n\nprint(factorial(5))\n\ndef fibonacci(n):\n    if(n > 1):\n        return fibonacci(n - 1) + fibonacci(n - 2)\n    return 0 if n == 0 else 1\n\nprint(fibonacci(10))\n\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/Yisusocanto.py",
    "content": "#imprimir numero desde el 100 al 0\ndef imprimir(n):\n\tif n >= 0:\n\t\tprint(n)\n\t\timprimir(n-1)\n\nimprimir(100)\t\t\n\n#encontrar el factorial de un numero\ndef calcular(n):\n\tif n == 1 or n == 2:\n\t\treturn(n)\n\telse:\n\t\treturn n * calcular(n-1)\n\n\t    \nprint(f\"el factorial de 4 es: \", calcular(4))\n\n#valor de una posicion de fibonacci\ndef fibo(n):\n\tif n == 0:\n\t\treturn 0\n\telif n == 1:\n\t\treturn 1\n\telse:\n\t\treturn fibo(n-1) + fibo(n-2)\n\n\nprint(fibo(6))\t\t\t\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/Younes0-0.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n\"\"\"\n\ndef cuenta_atras(n):\n    if n < 0:\n        return None\n    cuenta_atras(n - 1)\n    print(n)\n\n#cuenta_atras(100)\n\ndef factorial(num):\n    if num <= 0:\n        return 1\n    return factorial(num - 1) * num\n    \n#print(factorial(10))\n\ndef fibonacci(num):\n    if num <= 0:\n        return 0\n    elif num == 1:\n        return 1\n    return fibonacci(num - 1) + fibonacci(num - 2)\n#  0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55…\n#print(fibonacci(11))\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/Zequy40.py",
    "content": "'''\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n '''\n\ndef imprimir_numeros(n):\n    if n < 0:\n        return\n    else:\n        print(n)\n        imprimir_numeros(n - 1)\n\n# Llamamos a la función con el valor inicial de 100\nimprimir_numeros(100)\n# Esto nos imprimirá de los numero de 100 a cero de manera descendiente. \n\n'''\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n '''\ndef factorial(n):\n    if n == 0 or n == 1:\n        return 1\n    else:\n        return n * factorial(n - 1)\n\n# Ejemplo de uso\nnumero_factorial = 5\nresultado_factorial = factorial(numero_factorial)\nprint(f\"El factorial de {numero_factorial} es {resultado_factorial}\")\n\n'''\n* - Calcular el valor de un elemento concreto (según su posición) en la \n*   sucesión de Fibonacci (la función recibe la posición).\n'''\n\n# Tomando en cuenta la formula de la sucesión de Fibonacci:\n#La fórmula matemática que describe la sucesión de Fibonacci es:\n\n# F(n)=F(n−1)+F(n−2)\n\n# Donde F(n) es el número en la posición y n de la secuencia de Fibonacci.\n#Tenemos que sumar las posiciones acertada primero para poder calcular despues el valor de un elemento concreto.\ndef fibonacci(posicion):\n    if posicion == 0:\n        return 0\n    elif posicion == 1:\n        return 1\n    else:\n        return fibonacci(posicion - 1) + fibonacci(posicion - 2)\n\nposicion_fibonacci = 6\nresultado_fibonacci = fibonacci(posicion_fibonacci)\nprint(f\"El elemento en la posición {posicion_fibonacci} de la sucesión de Fibonacci es {resultado_fibonacci}\")\n\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/a-mayans.py",
    "content": "# CONCEPTO de recursividad: proceso mediante el que una función se llama a sí misma de forma repetida, hasta satisfacer una determinada condición\n# Ejemplo de la funcion recursiva\ndef impresion_numeros(n):\n  if n < 0:\n    return\n  else:\n    print(n)\n    impresion_numeros(n - 1)\n\n# llamamos a la función para que imprima los numero del 100 al 0\nimpresion_numeros(100)\n\n# ---------\n#   Extra\n# ---------\n\n# Funcion recursiva para calcular el factorial de un número\ndef calculo_factorial(n):\n  if n == 0 or n == 1:\n    return 1\n  else:\n    return n * calculo_factorial(n - 1)\n\n# Ejemplo de uso pasandole el número\nnum = 5\nfactorial = calculo_factorial(num)\nprint(f'El factorial del número {num} es: {factorial}')\n\n\n# Funcion recursiva para calcular el valor de un elemento concreto (según su posición) en la sucesión de Fibonacci\ndef valor_fibonacci(n):\n  if n <= 0:\n    print(\"La posición tiene que ser mayor que cero\")\n    return 0\n  elif n == 1:\n    return 0\n  elif n == 2:\n    return 1\n  else:\n    return valor_fibonacci(n-1) + valor_fibonacci(n-2)\n\nnumero = 8\nfib = valor_fibonacci(numero)\nprint(f'El valor de fibonacci del número {numero} es: {fib}')\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/adolfolozaa.py",
    "content": "'''\r\nRECURSIVIDAD: Funcion que se llama a ella misma\r\n\r\nEJERCICIO:\r\n * Entiende el concepto de recursividad creando una función recursiva que imprima\r\n * números del 100 al 0.\r\n *\r\n * DIFICULTAD EXTRA (opcional):\r\n * Utiliza el concepto de recursividad para:\r\n * - Calcular el factorial de un número concreto (la función recibe ese número).\r\n * - Calcular el valor de un elemento concreto (según su posición) en la \r\n *   sucesión de Fibonacci (la función recibe la posición).\r\n */\r\n '''\r\ndef coutdown(number):\r\n    if number >= 0:\r\n        print(number)\r\n        coutdown(number - 1)\r\n        \r\n\r\ncoutdown(100)\r\n\r\n'''\r\n\r\n * DIFICULTAD EXTRA (opcional):\r\n * Utiliza el concepto de recursividad para:\r\n * - Calcular el factorial de un número concreto (la función recibe ese número).\r\n * - Calcular el valor de un elemento concreto (según su posición) en la \r\n *   sucesión de Fibonacci (la función recibe la posición).\r\n '''\r\n\r\n# Factorial\r\ndef factorial(numero: int)->int:\r\n    if numero < 0:\r\n        print(' los numeros negativos no son validos')\r\n        return 0\r\n    elif numero == 0:\r\n        return 1\r\n    else:\r\n        return numero *factorial(numero -1)\r\n    \r\nnumero = 15\r\nprint('--------------------')\r\nprint(f'El factorial de {numero} es {factorial(numero)}')\r\n\r\n\r\n\r\n#Fibonacci\r\ndef fibona(numero: int) -> int: \r\n    if numero <= 0:\r\n        print(' debe ser un numero mayor a cero')\r\n        return 0\r\n    elif numero == 1:\r\n        return 0\r\n    elif numero == 2:\r\n        return 1\r\n    else:\r\n        return fibona(numero - 1) + fibona(numero - 2)\r\n\r\nprint('--------------------')\r\nprint('Calcular el valor de un elemento concreto (según su posición) en la sucesión de Fibonacci (la función recibe la posición)')\r\nposicion = input('Ingrese la posicion deseada?  ')\r\nprint(fibona(int(posicion)))\r\n             "
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/adra-dev.py",
    "content": "\"\"\"\nEJERCICIO:\nEntiende el concepto de recursividad creando una funcion recursiva \nque imprima numeros del 100 al 0.\n\nDIFICULTAD EXTRA (opcional):\nUtiliza el concepto de recursividad para:\n- Calcular el factorial de un numero concreto (la funcion recibe ese\nnumero).\n- Calcular el valor de un elemento concreto (segun su posicion) en la\nsucesion de Fibonacci (la funcion recibe la posicion).\n\nby adra-dev.\n\"\"\"\n\n\"\"\"\nRecursividad:\n    Una funcion recursiva es una funcion que se llama a si misma, un \n    ejemplo tipico es el calculo del factorial\n\"\"\"\n\ndef countdown(number:int):\n    if number >= 0:\n        print(number)\n        countdown(number= number - 1)\n\n\n\ncountdown(100)\n\n\"\"\"\nExtra\n\"\"\"\n\n\ndef factorial(number:int) -> int:\n    if number < 0:\n        print(\"Los numeros negativos no son validos\")\n        return 0\n    elif number == 0 or number == 1:\n        return 1 \n    else:\n        return number * factorial(number - 1)\n\n\nprint(factorial(5))\n\n\ndef fibonacci(number:int) -> int:\n    if number <= 0 :\n        print(\"La posicion tiene que ser mayor que cero\")\n        return 0\n    elif number == 1 :\n        return 0\n    elif number == 2:\n        return 1\n    else:\n        return fibonacci(number - 1) + fibonacci(number - 2)\n\n\n\nprint(fibonacci(5))"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/agusrosero.py",
    "content": "# EJERCICIO:\ndef cuenta_atras(n):\n    if n < 0:\n        return\n    cuenta_atras(n - 1)\n    print(n)\n\n\nprint(cuenta_atras(100))\n\n# DIFICULTAD EXTRA:\n# Calcular el factorial de un número concreto (la función recibe ese número).\n\n\ndef factorial(n):\n    if n == 0:\n        return 1\n    else:\n        return n * factorial(n - 1)\n\n\nprint(factorial(2))\n\n# Calcular el valor de un elemento concreto (según su posición) en la sucesión de Fibonacci (la función recibe la posición).\n\n\ndef fib(n):\n    if n < 2:\n        return n\n    else:\n        return fib(n - 1) + fib(n - 2)\n\n\nprint(fib(7))\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/ainaragmt.py",
    "content": "# Función recursiva\ndef cuenta_atras(numero):\n    if numero >= 0:\n        print(numero)\n        cuenta_atras(numero - 1)\n\ncuenta_atras(100)\n\n'''\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n'''\nprint(\"\\nEjercicio de dificultad extra\\n\")\n\ndef factorial(num):\n    result = 1\n    i = 0\n\n    def calculo(n):\n        nonlocal result, i\n        if n < 0:\n            print(\"Los números negativos no son válidos.\\n\")\n        elif n == 0:\n            print(f\"El factorial de 0 es 1\\n\")\n        elif n > 0:\n            i += 1\n            result *= n\n            calculo(n - 1)\n        else:\n            print(f\"El factorial de {i} es {result}\\n\")\n\n    calculo(num)\n\nnumero = int(input(\"Escribe el valor del factorial que quieras calcular: \"))\nfactorial(numero)\n\ndef num_fibonacci(posicion):\n    num1 = 0\n    num2 = 1\n    i = 2\n\n    def suc_fibonnaci():\n        nonlocal num1, num2, posicion, i\n        if posicion < 0:\n            print(f\"Las posiciones negativas no son válidas.\\n\")\n        elif posicion == 0:\n            print(f\"La posición 0 corresponde al número 0 de la sucesión de Fibonacci.\\n\")\n        elif posicion == 1:\n            print(f\"La posición 1 corresponde al número 1 de la sucesión de Fibonacci.\\n\")\n        elif posicion > i:\n            copia = num2\n            num2 += num1\n            num1 = copia\n            i += 1\n            suc_fibonnaci()\n        else:\n            print(f\"La posición {i} corresponde al número {num2} de la sucesión de Fibonacci.\\n\")\n    \n    suc_fibonnaci()\n    \nposicion = int(input(\"Escribe la posición del número de la sucesión de Fibonacci que desees: \"))\nnum_fibonacci(posicion)"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/alanshakir.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n \"\"\"\n\ndef regresion_recursiva(numero: int):\n    if numero >= 0:\n        print(numero)\n        regresion_recursiva(numero - 1)\n\nregresion_recursiva(100)\n\n\"\"\"\nEXTRA\n\"\"\"\n\ndef factorial_numero(numero: int):\n    if numero == 1:\n        return 1\n    else:\n        return numero * factorial_numero(numero - 1)\n\nprint(factorial_numero(3))\n\ndef sucession_fibonacci(numero: int):\n    if numero == 0 or numero == 1:\n        return numero\n    else:\n        return(sucession_fibonacci(numero-1) + sucession_fibonacci(numero-2))\n    \nprint(sucession_fibonacci(7))\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/albertomorilla.py",
    "content": "\n\"\"\"\n * EJERCICIO:\n  Entiende el concepto de recursividad creando una función recursiva que imprima\n  números del 100 al 0.\n\"\"\"\n\n\ndef countdown(n: int):\n    if n >= 0:\n        print(n)\n        countdown(n -1)\n\ncountdown(100)\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n   Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n    sucesión de Fibonacci (la función recibe la posición).\n\"\"\"\n\ndef factorial(n: int) -> int:\n    if n < 0:\n        print (\"Los numeros negativos no vale\")\n        return 0\n    elif n == 0:\n        return 1\n    else:\n        return n * factorial(n - 1)\n\nprint (factorial(7))\n\ndef fibonacci(n: int) -> int:\n    if n <= 0:\n        print (\"La posicion debe ser mayor a 0\")\n        return 0\n    elif n == 1:\n        return 0\n    elif n == 2:\n        return 1\n    else:\n        return fibonacci(n -1) + fibonacci(n -2)\n\nprint (fibonacci(7))"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/alexdevrep.py",
    "content": "'''\n/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n'''\n\n#Ejercicio\n'''\nLa recursuvidad en programación es una función que se llama a sí misma durante su ejecucción\n'''\n\ndef recursiva(n):\n    if (n<=100):\n        print(n)\n    else:\n        return recursiva\n\n    recursiva(n+1)\n\n    \n    \nrecursiva(0)\n\nprint(\"------------------------------\")\n#Dificultad extra\n\ndef factorial (numero):\n    if (numero==0):\n        return 1\n    else :\n        return numero * factorial(numero-1) \n\nnumero=int(input(\"Por favor ingrese un número: \"))\nresultado = factorial(numero)\nprint(resultado)\n\nprint(\"------------------------------\")\n\ndef fibonacci(posicion):\n    if(posicion<=1):\n        return posicion\n    else :\n        return fibonacci(posicion-1)+ fibonacci (posicion -2) \n\n\nposicion = int(input(\"Por favor ingrese el valor de la posición: \"))\nresultado2= fibonacci(posicion)\nprint(resultado2)\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/andres54-coder.py",
    "content": "''' \nEjercisio\n'''\ndef countdown(n: int):\n    if n >= 0:\n        print(n)\n        countdown(n-1)\n\n    \n# countdown(100)\n\n'''\nExtra   \n'''\n\ndef factorial(n:int):\n    if n < 0:\n        print('los numeros negativos no son validos ')\n        return 0\n    elif n == 0:\n        return 1\n    return n * factorial(n-1)\n    \nprint(factorial(5))\n\ndef fibonacci(n:int):\n    if n <= 1:\n        return n \n    else: return fibonacci(n-1) + fibonacci(n-2)\n    \n# print(fibonacci(10))"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/andresgcastillo.py",
    "content": "def print_numbers(num):\n  if num < 0:\n    return\n  print(num)\n  print_numbers(num - 1)\n\nprint_numbers(100)\n\n#Dificultad Extra \n\n#Factorial\ndef factorial(num):\n  if num == 0 or num == 1:\n    return 1\n  return num * factorial(num - 1)\n\nprint(factorial(23))  \n\n#Fibonacci\ndef fibonacci(num):\n  if num <= 1:\n    return num\n  return fibonacci(num - 1) + fibonacci(num - 2)\n\nprint(fibonacci(23))  "
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/angel-agis.py",
    "content": "#  * EJERCICIO:\n#  * Entiende el concepto de recursividad creando una función recursiva que imprima\n#  * números del 100 al 0.\n\ndef recursive(inicio):\n    '''\n    Mientras 'inicio' sea positivo, es decir, mientras no llegue a cero,\n    lo imprimimos, le restamos uno, y volvemos a llamar recursivamente a la función\n    '''\n    if inicio:\n        print(inicio)\n        inicio-=1\n        recursive(inicio)\n    else:\n        print(\"Has llegado al cero.\")\n\nrecursive(100)\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Utiliza el concepto de recursividad para:\n#  * - Calcular el factorial de un número concreto (la función recibe ese número).\n        \ndef factorial(inicio, total=1):\n    '''\n    Recibe el numero sobre el que se quiere calcular el factorial\n    Va guardando el total en la variable total, que inicialmente siempre es uno para poder multiplicar.\n    '''\n    if inicio:\n        total = total * inicio\n        inicio-=1\n        factorial(inicio, total)\n    else:\n        print(f\"Factorial: {total}\")\n\nfactorial(5)\n\n#  * - Calcular el valor de un elemento concreto (según su posición) en la \n#  *   sucesión de Fibonacci (la función recibe la posición).\n\ndef sucesion_fibonacci(posicion, sucesion = []):\n    \n    if posicion:\n        if len(sucesion) == 0:\n            sucesion.append(0)\n        elif len(sucesion) == 1:\n            sucesion.append(1)\n        else:\n            sucesion.append(sucesion[len(sucesion)-1]+sucesion[len(sucesion)-2])\n        sucesion_fibonacci(posicion-1)\n    else:\n        print(sucesion[len(sucesion)-1])\n\nsucesion_fibonacci(20)"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/annnerssv.py",
    "content": "#RECURSIVIDAD\n\ndef disminuidor(numero : int):\n    if numero >= 0:\n        print(numero)\n        disminuidor(numero - 1) \n\ndisminuidor(100)\n\n\n#EJERCICIO EXTRA\n\ndef factorial(n : int) -> int:\n    if n < 0:\n        print(\"Los numeros negativos no son validos\")\n        return 0\n    elif n == 0:\n        return 1\n    return n * factorial(n -1)\n\nprint(factorial(4))\n\n\ndef fibonacci(n : int) -> int:\n    if n <= 0:\n        print(\"La posicion tiene q ser mayor a 0\")\n        return 0\n    elif n == 1:\n        return 0\n    elif n == 2:\n        return 1\n    else:\n        return fibonacci(n - 1) + fibonacci(n - 2)\n\nprint(fibonacci(5))\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/any7dev.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */ \"\"\"\n\ndef ejercicio(n):\n    print(n)\n    if n > 0:\n        ejercicio(n-1)        \n\ndef factorial(numero):\n    if numero == 1:\n        fact = 1\n    else:\n        fact = numero * factorial(numero-1)\n    return fact\n\nif __name__ == '__main__':\n    ejercicio(100)\n    print(factorial(7))\n    "
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/avcenal.py",
    "content": "\"\"\"\n* EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n\"\"\"\n\ndef recursive_100(number):\n    if number == 0:\n        print (0)\n        return 0\n    else:\n        print(number)\n        return number- recursive_100(number-1)\n\nrecursive_100(100)\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n\"\"\"\n\ndef factorial(number):\n    if number == 1:\n        return 1\n    else:\n        return number * factorial(number-1)\nprint(factorial(5))\n\ndef fibonacci_pos(position):\n    if position == 2 or position == 1:\n        return 1\n    else:\n        return fibonacci_pos(position-1) + fibonacci_pos(position-2)\n    \nprint(fibonacci_pos(10))\n\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/blancowilson.py",
    "content": "def print_numbers_back(number):\n    if number == 0:\n        return\n    print(number)\n    print_numbers_back(number - 1)\n\nprint_numbers_back(10)\n\n\ntest_number=10\n\ndef factorial(number):\n    if number == 0:\n        return 1\n    return number * factorial(number - 1)\n\nprint(factorial(test_number))\n\nfibonacci_list:list=[]\n\ndef fibonacci(number):\n    if number <= 0:\n        return \"El número debe ser mayor a 0\"\n    elif number == 1:\n        return 0\n    elif number == 2:\n        return 1\n    else:\n        return fibonacci(number - 1) + fibonacci(number - 2)\n\n\nif test_number > 0:\n    print(\"Los primeros\", test_number, \"términos de la serie de Fibonacci son:\")\n    for i in range(1, test_number + 1):\n        print(fibonacci(i), end=\" \")\nelse:\n    print(\"El número ingresado no es válido\")"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/cbuenrostrovalverde.py",
    "content": "'''\nEJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n'''\n\n# Función de recursividad\n\ndef recursividad(n):\n    if n < 0:\n        return\n    print(n)\n    \n    recursividad(n - 1)\n\nrecursividad(100)\n\n\n# Cálculo del Factorial de un numero utilzando la recursividad. \n\ndef factorial(n):\n    if n == 0 or n == 1:\n        return 1\n    else:\n        return n * factorial(n - 1)\n\nn = int(input(\"Introduzca el número: \"))\n\nprint(f'El factorial de {n} es: {factorial(n)}')\n\n# Cálculo sucesión de Fibonacci haciendo uso de la recursividad.\n\ndef fibonacci(numero: int)-> int:\n    if numero < 0:\n        raise ValueError('número debe de ser un entero no negativo')\n    if numero == 0:\n        return 0\n    elif numero == 1:\n        return 1\n    else:\n        return fibonacci(numero - 1) + fibonacci(numero - 2)\n\nprint(f'F(5): {fibonacci(5)}')"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/cesar-ch.py",
    "content": "# #06 RECURSIVIDAD\n\n\ndef imprimir_numeros(contador):\n    if contador < 0:\n        return\n    else:\n        print(contador)\n        contador -= 1\n        imprimir_numeros(contador)\n\n\nimprimir_numeros(100)\n\n# Dificultad Extra\n\n\ndef factorial(numero):\n    if numero == 0:\n        return 1\n    else:\n        return numero * factorial(numero - 1)\n\n\nprint(factorial(5))  # 120\n\n\ndef fibonacci(numero):\n    if numero < 1:\n        print(\"El número debe ser mayor o igual a 1\")\n    elif numero == 1:\n        return 0\n    elif numero == 2:\n        return 1\n    else:\n        return fibonacci(numero - 1) + fibonacci(numero - 2)\n\n\nprint(fibonacci(8))  # 13\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/chartypes.py",
    "content": "'''\n# #06 RECURSIVIDAD\n> #### Dificultad: Difícil | Publicación: 05/02/24 | Corrección: 12/02/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\n'''\n\n\ndef counting_down_to_zero(initial_number:int)->None:\n    print(initial_number)\n    if initial_number==0:\n        return 0\n    return counting_down_to_zero(initial_number-1)\n\n\ndef factorial(number:int) -> int:\n    if number <= 1:\n        return number\n    return number * factorial( number-1 )    \n\ndef get_fibonacci_number_by_position(position:int)->int:\n    number:int = 0\n    if position == 1:\n        return 1\n    if position == 0:\n        return 0\n    number = get_fibonacci_number_by_position(position-1) + get_fibonacci_number_by_position(position-2)\n    return number\n   \n\n\n\n\n# counting_down_to_zero(100)\n# print(factorial(5))\n# print(factorial(0))\n# print(factorial(24))\n# print(get_fibonacci_number_by_position(0))\n# print(get_fibonacci_number_by_position(1))\n# print(get_fibonacci_number_by_position(2))\n# print(get_fibonacci_number_by_position(20) )\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/clmiranda.py",
    "content": "# RECURSIVIDAD\n\n# FUNCIÓN RECURSIVA QUE IMPRIMA LOS NÚMEROS DEL 100 AL 0\ndef recursion_100_to_0(num: int) -> str:\n    print(num, end=\" \")\n    if num != 0:\n        recursion_100_to_0(num - 1)\n\nrecursion_100_to_0(100)\n\n\n\n# EJERCICIO - DIFICULTAD EXTRA\n\n\n# CALCULAR EL FACTORIAL DE UN NÚMERO CONCRETO (LA FUNCIÓN RECIBE ESE NÚMERO)\ndef recursion_factorial(num: int) -> int:\n    return num if num == 1 else num * recursion_factorial(num - 1)\n\nprint(f\"\\nEl factorial de 7 es: {recursion_factorial(7)}\")\n\n\n\n# CALCULAR EL VALOR DE UN ELEMENTO CONCRETO (SEGÚN SU POSICIÓN) EN LA SUCESIÓN DE FIBONACCI\ndef recursion_fibonacci(num: int) -> int:\n    return 1 if num in [1, 2] else recursion_fibonacci(num - 1) + recursion_fibonacci(num - 2)\n\nprint(f\"La posición 4 de la serie Fibonacci es: {recursion_fibonacci(4)}\")"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/cristianfloyd.py",
    "content": "\"\"\"  \n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n * \"\"\"\n \ndef imprimir_numeros(n=100):\n    if n < 0:\n        return\n    print(n)\n    imprimir_numeros(n - 1)\n\n# imprimir_numeros(10)\n\n\"\"\" \n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */ \"\"\"\n\n # Factorial\n\n\"\"\"\n El factorial (representado por un signo de exclamación \"!\") es una operación \n matemática que consiste en multiplicar un número entero positivo por todos \n los enteros positivos menores que él hasta llegar a 1.\n\n Definición: El factorial de un número entero positivo n (escrito n!) \n es el producto de todos los enteros positivos desde 1 hasta n.\n Ejemplos: 5! = 5 × 4 × 3 × 2 × 1 = 120\n\"\"\"\n\ndef factorial(n: int) -> int:\n    if n < 0:\n        print(\"Los números negativos no son válidos\")\n        return 0\n    elif n == 0:\n        return 1\n    else:\n        return n * factorial(n - 1)\n\nn = int(input(\"Introduce un número para calcular su factorial: \"))\nprint(f\"El factorial de {n} es {factorial(n)}\")\n\n# fibonacci\ndef fibonacci(n: int) -> int:\n    if n <= 0:\n        print(\"Los números negativos no son válidos\")\n        return 0\n    elif n == 1:\n        return 1\n    elif n == 2:\n        return 1\n    else:\n        return fibonacci(n - 1) + fibonacci(n - 2)\n\nn = int(input(\"Introduce la posición para calcular el valor en la sucesión de Fibonacci: \"))\nprint(f\"El valor en la posición {n} de la sucesión de Fibonacci es {fibonacci(n)}\")"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/cuervo23alpha.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"\n/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n*/\n\nAUTOR: CRISTIAN\n\"\"\"\n\ndef listanumeros():\n    for i in range(100,-1,-1):\n        print(i, \"\\n\")\n\nlistanumeros()\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/d0ubt0.py",
    "content": "#Recursividad\n\ndef recursive_func(n:int):\n    print(n)\n    if n > 0:\n        recursive_func(n - 1)\n        \n\nrecursive_func(100)\n\ndef factorial_func(n: int):\n    if n == 0  or n == 1:\n        return 1\n    else:\n        return (n * factorial_func(n-1))\n    \nprint(factorial_func(5))\n\ndef fibonacci_func(n:int):\n    if n == 1: \n        return 0\n    elif n == 2:\n        return 1\n    else: \n        return fibonacci_func(n - 1) + fibonacci_func(n - 2)\n    \nprint(fibonacci_func(7))"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/danielhdzr.py",
    "content": "# #06 RECURSIVIDAD\n#### Dificultad: Difícil | Publicación: 05/02/24 | Corrección: 12/02/24\n\n## Ejercicio\n'''\n* EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición). \n '''\n\ndef main():\n    '''\n    La recursion es como una muneca Matryoshka rusa, se repite una y otra vez hasta llegar al final (la muneca mas pequena) ese es nuestro base case.\n    El base case o base condition es la condicion para finalizar la funcion.\n    '''\n    # Del 100 al 0\n    def recursion1(n):\n        # Lo primero que hace la funcion en su ciclo es imprimir n\n        print(n)\n        # Caso base o base case. Aqui termina la secuencia \n        if n == 0:\n            print(\"Base case\")\n            return n\n        # Caso de recursion o recursion case\n        else: \n            '''\n            Llama a la funcion de nuevo, \n            se repite el ciclo de la funcion con el nuevo valor de n\n            '''\n            return recursion1(n - 1)\n    \n    recursion1(100)\n    print()\n\n    # Otra forma de hacerlo\n    # Del 100 al 0\n    def recursion2(n):\n        # Caso base o base case. Aqui termina la secuencia \n        if n == 100:\n            print(f\"Base case or base condition {n}\")\n            return n\n        # Caso de recursion o recursion case\n        else: \n            recursion2(n + 1)\n        print(n)\n    recursion2(0)\n\n    print()\n\n    # Del 0 al 100\n    def recursion3(n):\n        # Caso base o base case. Aqui termina la secuencia \n        if n == 0:\n            print(f\"Base case or base condition {n}\")\n            return n\n        # Caso de recursion o recursion case\n        else: \n            recursion3(n - 1)\n        print(n)\n    recursion3(100)\n\n    print()\n\n\n    # def evenNumb(n):\n    #     print(n)\n    #     if n == 2:\n    #         return n\n    #     else: \n    #         return evenNumb(n - 2)\n        \n    \n    # evenNumb(8)\n\nif __name__==\"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/davidrguez98.py",
    "content": "\"\"\" # #06 RECURSIVIDAD\n> #### Dificultad: Difícil | Publicación: 05/02/24 | Corrección: 12/02/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**. \"\"\"\n\n# EJERCICIO\n\ndef countdown(number: int):\n    if number >= 0:\n        print(number)\n        countdown(number - 1)\n\ncountdown(100)\n\n# DIFICULTAD EXTRA\n\ndef factorial(numero: int) -> int:\n    if numero < 0:\n        print(\"Los números negativos no son válidos\")\n    elif numero == 0 or numero == 1:\n        return 1\n    else:\n        return numero * factorial(numero - 1)\n    \nprint(factorial(10))\n\n\n\ndef fibonacci(num: int) -> int:\n    if num <= 0:\n        print(\"Los números negativos no son válidos\")\n    elif num == 1:\n        return 0\n    elif num == 2:\n        return 1\n    else:\n        return fibonacci(num - 1) + fibonacci(num - 2)\n    \nprint(fibonacci(3))\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/duendeintemporal.py",
    "content": "#6 { Retos para Programadores } Recursividad\n\"\"\"\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n \"\"\"\n\nlog = print  # Shortening print function to log\n\n# A recursive function typically is formed when a function calls itself by name\ndef count_back(n):\n    log(n)\n    if n == 0:\n        return # None\n    return count_back(n - 1)\n\nlog(count_back(100))\n\n# Without recursion\ndef power_v1(base, exponent):\n    result = 1 if exponent == 0 else base\n    for i in range(2, exponent + 1):\n        result *= base\n    return result\n\nlog(power_v1(4, 3))  # 64\n\n# With recursion\ndef power(base, exponent):\n    if exponent == 0:\n        return 1\n    else:\n        return base * power(base, exponent - 1)\n\nlog(power(4, 3))  # 64\n\n# This is rather close to the way mathematicians define exponentiation and\n# arguably describes the concept more clearly than the looping variant.\n# The function calls itself multiple times with ever smaller exponents to achieve the\n# repeated multiplication.\n\n# But this implementation has one problem: in typical Python implementations,\n# it’s about three times slower than the looping version. Running through\n# a simple loop is generally cheaper than calling a function multiple times.\n\n# In the case of the power function, the inelegant (looping) version is still fairly\n# simple and easy to read. It doesn’t make much sense to replace it with the\n# recursive version.\n\n# Extra difficulty exercises\n\ndef factorial(n):\n    if n <= 1:\n        return 1\n    return n * factorial(n - 1)\n\nlog(factorial(5))  # 120\n\n\n# This function returns the number equivalent to the position in the Fibonacci series\ndef fibonacci_num(n):\n    if n == 0:\n        return 0\n    if n == 1:\n        return 1\n    return fibonacci_num(n - 1) + fibonacci_num(n - 2)\n\nlog(fibonacci_num(17))  # 1597\n\n# Note: The recursive version with memoization is more efficient than the simple recursive one,\n# as it avoids redundant calculations. However, it still uses the call stack, which can be a problem for very large values of n.\n\ndef fibonacci_num_memo(n, memo={}):\n    if n in memo:\n        return memo[n]\n    if n == 0:\n        return 0\n    if n == 1:\n        return 1\n    memo[n] = fibonacci_num_memo(n - 1, memo) + fibonacci_num_memo(n - 2, memo)\n    return memo[n]\n\nlog(fibonacci_num_memo(17))  # 1597\n\n# The iterative approach is generally more efficient in terms of time and space, as it does not use the call stack of recursion.\n\"\"\" The iterative approach not handle very large Fibonacci numbers properly due to the limitations of standard integer representation in some programming languages. However, Python's integers can grow as large as the memory allows, so it should work fine for large Fibonacci numbers like fibonacci(4222). \"\"\"\n\ndef iterative_fibonacci(n):\n    if n == 0:\n        return 0\n    if n == 1:\n        return 1\n\n    a, b = 0, 1\n    resultado = 0\n\n    for i in range(2, n + 1):\n        resultado = a + b\n        a = b\n        b = resultado\n    return resultado\n\nlog(iterative_fibonacci(4222))  # This will likely result in a very large number\n''' 991589988362642070289381809859238899810818978690066481567009961084370343355020445771885410736432350985748230736466733366235493773173353807008180411573721923522628193615012792654580349124839525370327127087212639668504243599805635642440051280951077467227974758307254927414086395913327066620720820654856388551207498973370655978255046381155991312335751278534594089041280672977552114511923101524007980516923288134966032329067540128365146684772558653549788584628220581142887000982711896691538088856557710641299562290047382724565369870585638339456142817193642656279468367921367028940944988116809057276755968908731893570902338692496954534233789481260096044188777018433397442568357873891235554198879570974119614520991455054319986189584806128290103014082993662230000784648446189143070226650569527550697283718937846526095749543627404591780914731497810266886509088704777805009571566121451309311 '''\nlog(iterative_fibonacci(453))  # 20985341020594289480596202471862246559405946478745659997715004840583924030397583511583383173698\n\n# Simulating a window load event (not applicable in standard Python, but for demonstration)\ndef on_load():\n    body_style = {\n        'background': '#000',\n        'text-align': 'center'\n    }\n    \n    title = {\n        'text': 'Retosparaprogramadores #6.',\n        'font-size': '3.5vmax',\n        'color': '#fff',\n        'line-height': '100vh'\n    }\n    \n    # Simulating a delay (not applicable in standard Python, but for demonstration)\n    import time\n    time.sleep(2)\n\n    log(\"Title:\", title['text'])\n\n# Call the simulated load function\non_load()"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/eamartin96.py",
    "content": "# #06 Recursividad\n# EJERCICIO\n'''\nCrea una funcion recursiva que imprima numeros del 100 al 0\n'''\ndef numbers(number):\n    if number < 0:\n        return\n    else:\n        print(number)\n        numbers(number - 1)\n\nnumbers(100)\n\nprint(\"\\n----------------------------------------------------\")\nprint(\"EXTRA DIFFICULT\")\n'''\nUtiliza el concepto de recursividad para:\n- Calcular el factorial de un numero concreto (la funcion recibe ese numero)\n- Calcular el valor de un elemento concreto (segun su posicion) en la\n  sucesion de Fibonacci (la funcion recibe la posicion).\n'''\n\ndef factorial(number):\n    if number < 0:\n        print(\"Invalid input\")\n        return 0\n    elif number == 0:\n        return 1\n    else:\n        return number*factorial(number - 1)\n\ndef fibonacci(number):\n    if number <= 0:\n        print(\"Input must be greather than 0\")\n        return 0\n    elif number == 1:\n        return 0\n    elif number == 2:\n        return 1\n    else:\n        return fibonacci(number - 1) + fibonacci(number - 2)\n\n\nprint(f\"!0 = {factorial(0)}\")\nprint(f\"!5 = {factorial(5)}\")\n\nprint(f\"1st Fibonacci value is {fibonacci(1)}\")\nprint(f\"2nd Fibonacci value is {fibonacci(2)}\")\nprint(f\"4th Fibonacci value is {fibonacci(4)}\")\nprint(f\"10th Fibonacci value is {fibonacci(10)}\")\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/elbarbero.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n *\n \"\"\"\n \ndef printNumbers(limit: int, current_number: int):\n    if current_number < limit:\n        print(current_number)\n        current_number += 1\n        printNumbers(limit, current_number)\n\ndef recursiveFactorialNumber(n: int, i = 1, factorial = 1):\n    if i < (n + 1):\n        factorial *= i\n        i += 1\n        recursiveFactorialNumber(n, i, factorial)\n    else:\n        print(f\"El factorial de {n} es {factorial}\")\n\ndef factorialNumber(n: int):\n    factorial = 1\n    for i in range(1, num + 1):\n        factorial *= i\n    print(f\"El factorial de {num} es {factorial}\")\n\ndef fibonacci(n: int):\n    num1 = 0\n    num2 = 1\n    next_number = num2  \n    count = 1\n\n    while count <= n:\n        print(next_number, end=\" \")\n        count += 1\n        num1, num2 = num2, next_number\n        next_number = num1 + num2\n    \ndef recursiveFibonacci(n: int):\n    if n < 0:\n        print(\"Incorrect input\")\n    elif n == 0:\n        return 0\n    elif n == 1 or n == 2:\n        return 1\n    else:\n        return recursiveFibonacci(n-1) + recursiveFibonacci(n-2)\n    \n\nif __name__ == \"__main__\":\n    printNumbers(limit = 100, current_number = 0)\n    recursiveFactorialNumber(6)\n    print(f\"El número fibonacci del número 8 es {recursiveFibonacci(9)}\")"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/estuardodev.py",
    "content": "'''\n/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n'''\n\ndef numeros(numero):\n        if numero >= 0:\n            print(numero)\n            numeros(numero - 1)\n\ndef factorial(numero) -> int:\n        if numero < 0:\n            return 1\n        elif numero == 0:\n            return 1\n        else:\n            return numero * factorial(numero - 1)\n        \ndef fibonacci(posicion) -> int:\n        if posicion <= 0:\n            return 0\n        elif posicion == 1:\n            return 0\n        elif posicion == 2:\n            return 1\n        else:\n            return fibonacci(posicion - 1) + fibonacci(posicion - 2)\n\nnumeros(100)\nprint(factorial(5))\nprint(fibonacci(5))"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/evilpotato04.py",
    "content": "\n#/*\n# * EJERCICIO:\n# * Entiende el concepto de recursividad creando una función recursiva que imprima\n# * números del 100 al 0.\n\ndef cuenta_regresiva(numero: int):\n    print(numero)\n    numero -= 1\n    if numero >= 0:\n        cuenta_regresiva(numero)\n\ncuenta_regresiva(100)\n\n# *\n# * DIFICULTAD EXTRA (opcional):\n# * Utiliza el concepto de recursividad para:\n# * - Calcular el factorial de un número concreto (la función recibe ese número).\n# * - Calcular el valor de un elemento concreto (según su posición) en la \n# *   sucesión de Fibonacci (la función recibe la posición).\n# */\n\ndef calcular_factorial(numero: int):\n    if numero == 1:\n        return numero\n    else:\n        return numero * calcular_factorial(numero - 1)\n\nprint(str(calcular_factorial(4)))\n\ndef calcular_posicion_en_secuencia_fibonacci(posicion: int):\n    \n    def generar_fibonacci(posicion_maxima: int, secuencia = [1,1]):\n        if len(secuencia) == posicion_maxima:\n            return secuencia\n        else:\n            secuencia.append(secuencia[-1] + secuencia[-2])\n            return generar_fibonacci(posicion_maxima, secuencia)\n    \n    return generar_fibonacci(posicion)[posicion-1]\n\nposicion = 10\nprint(\"En la secuencia de Fibonacci el número en la posición \" + str(posicion) + \" es: \" + str(calcular_posicion_en_secuencia_fibonacci(posicion)))\n\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/fborjalv.py",
    "content": "\n\n\n# función recursiva que imprime número del 100 al 0\n\n\ndef func_recursiva(num: int):\n    if num > 0: \n        minus = num - 1\n        print(minus)\n        func_recursiva(minus)\n    else:\n        print(\"Fin de la recursividad\")\n\nfunc_recursiva(100)\n\n\n\ndef factorial(num: int):\n    if num < 0:\n        print(\"Los números negativos no son válidos\")\n        return 0\n    elif num == 0:\n        return 1\n    else:\n        return num * factorial(num - 1)\n\n\nprint(factorial(5))\n\n\ndef fibonacci(pos: int):\n    if pos <= 0: \n        return 0\n    elif pos == 1:\n        return 0\n    elif pos == 2:\n        return 1\n    else: \n        return fibonacci(pos - 1) + fibonacci(pos -2)\n\nprint(fibonacci(10))"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/fishellVvv.py",
    "content": "# ejercicio de recursividad\nprint(\"\\nCountdown: \")\ndef countdown(num: int):\n    if num >= 0:\n        print(num, end=\" \")\n        countdown(num - 1)\ncountdown(100)\n\n# EXTRA\nprint(\"\\nFactorial: \")\ndef factorial(num: int) -> int:\n    if num < 0:\n        return 0\n    elif num == 0:\n        return 1\n    else:\n        return num * factorial(num - 1)\nprint(factorial(5))\n\nprint(\"Fibonacci: \")\ndef fibonacci(num: int) -> int:\n    if num <= 1:\n        return 0\n    elif num == 2:\n        return 1\n    else:\n        return fibonacci(num - 1) + fibonacci(num - 2)\nprint(fibonacci(10))"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/franvozzi.py",
    "content": "\"\"\"\ndef printNums (num) :\n    if num < 0:\n        return\n    print(num)\n\n    printNums(num - 1)\n\nprintNums(100)\n\"\"\"\n\n\"\"\"\nEXTRA\n\"\"\"\ndef factorial(n):\n    if n == 0 or n == 1:\n        result = 1\n    elif n > 1:\n        result = n * factorial (n - 1)\n    return result\n\ndef fibonacci(n):\n    if n < 2:\n        return n\n    else:\n        return fibonacci (n - 1) + fibonacci (n - 2)\n\nfor n in range(10):\n    print(fibonacci(n))\n    \n\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/garos01.py",
    "content": "# Recursividad\n\n\ndef decremento(numero):\n    if numero < 0:\n        return\n    print(numero)\n    decremento(numero - 1)\n\n\ndecremento(100)\n\n\n# Ejercicio extra\n\n\n# Factorial\ndef factorial(numero):\n    if numero == 0:\n        return 1\n    else:\n        return numero * factorial(numero - 1)\n\n\nprint(f\"Factorial {factorial(5)}\")\n\n\n# Fibonacci\ndef fibonacci(posicion):\n    if posicion == 1 or posicion == 2:\n        return 1\n    else:\n        return fibonacci(posicion - 1) + fibonacci(posicion - 2)\n\n\nprint(f\"Numero {fibonacci(10)}\")\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/ggilperez.py",
    "content": "# Problem #06 recursion\n\ndef countdown_from_100_to_0(count=100):\n    print(count)\n    if count == 0:\n        return\n\n    count -= 1\n\n    return countdown_from_100_to_0(count)\n\n\ncountdown_from_100_to_0()\n\n\n# Extra\n\n# Factorial\ndef factorial(number: int) -> int:\n    if number <= 0:\n        return 1\n\n    return number * factorial(number - 1)\n\n\nprint(f\"{factorial(4) = }\")\nprint(f\"{factorial(6) = }\")\n\n\ndef fibonacci(number: int) -> int:\n    if number <= 1:\n        return number\n    return fibonacci(number - 1) + fibonacci(number - 2)\n\n\nprint(f\"{fibonacci(9) = }\")\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/gjbecerrae.py",
    "content": "#función recursiva que imprima números del 100 al 0\ndef numeros(numero):\n    if numero != 0:\n        print(numero)\n        return numeros(numero-1)\n    else:\n        print(numero)\n\n#numeros(100)\n        \ndef factorial(n):\n    if n == 1:\n        return  1\n    else:        \n        return (n * factorial(n-1))\n\n\ndef fibonacci(elemento):\n    if elemento == 1:\n        return 0\n    elif elemento == 2:\n        return 1\n    else:\n        return fibonacci(elemento - 1) + fibonacci(elemento - 2)\n\n\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/gonzadev28.py",
    "content": "\"\"\"EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\"\"\"\n\ndef recursividad(n):\n    if (n < 0):\n        return \n    else:\n        print(n)\n        return recursividad(n - 1)\n    \nrecursividad(100)\n\n\"\"\"DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\"\"\"\n\n# - Calcular el factorial de un número concreto (la función recibe ese número).\ndef factorial(fac : int):\n    if (fac == 0):\n        return 1\n    else:\n        return (fac * factorial(fac - 1))\n\nprint(factorial(5))\n\n#- Calcular el valor de un elemento concreto (según su posición) en la sucesión de Fibonacci\n# (la función recibe la posición).\ndef fibonacci(n):\n    if (n < 1):\n        print(\"Numero debe ser mayor o igual a 1\")\n    elif(n == 1):\n        return 0\n    elif(n == 2):\n        return 1\n    else:\n        return fibonacci(n -1) + fibonacci(n - 2)\n    \nprint(fibonacci(5)) # Sucesion de fibonacci 0, 1, 1, 2, \"3\", 5, 8..."
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/gringoam.py",
    "content": "\"\"\"\nRecurcividad\n\"\"\"\n\ndef imp_del_1_al_100(num:int=0):\n    if num<100:\n        imp_del_1_al_100(num+1)\n    print(num)\n\nimp_del_1_al_100()\n\n\n\"\"\"\nExtra\n\"\"\"\n\n#Calcula el factorial de un numero\n\ndef factorial(num:int) -> int:\n    aux=num\n    if num>1:\n        aux=aux*factorial(num-1)\n        \n    else: \n        aux=1\n    return aux\n\n\nnumero= 4\n\nprint(f\"El de {numero} es:{factorial(numero)}\")\n\n#El valor de una posición en la suseción de fibonachi\n\ndef pos_en_fibonachi (pos: int)-> int:\n    if pos==1:\n        return 0\n    elif pos==2:\n        return 1\n    else:\n        return pos_en_fibonachi(pos-1)+ pos_en_fibonachi(pos-2)\n\n\nprint(pos_en_fibonachi(8))"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/h4cker54n.py",
    "content": "# EJERCICIO:\n\n\n\"\"\"\n    Entiende el concepto de recursividad creando una función recursiva que imprima\n    números del 100 al 0.\n\"\"\"\n\n\ndef recursividad(n):\n    if n >= 0:\n        print(n)\n        recursividad(n - 1)\n\n\nrecursividad(100)\n\n\n\"\"\"\n    Calcular el factorial de un número concreto (la función recibe ese número).\n\"\"\"\n\n\ndef factorial(n):\n    if n == 0:\n        return 1\n    else:\n        return n * factorial(n - 1)\n\n\nprint(factorial(5))\n\n\"\"\"\n    Calcular el valor de un elemento concreto (según su posición) en la \n    sucesión de Fibonacci (la función recibe la posición).\n \"\"\"\n\n\ndef fibonacci(n):\n    if n == 0 or n == 1:\n        return n\n    else:\n        return fibonacci(n - 1) + fibonacci(n - 2)\n\n\nprint(fibonacci(3))\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/h4ckxel.py",
    "content": "def printNums (num) :\n    if num < 0:\n        return\n    print(num)\n\n    printNums(num - 1)\n\nprintNums(100)\n\n\"\"\"\nEXTRA\n\"\"\"\ndef factorial(n):\n    if n == 0 or n == 1:\n        result = 1\n    elif n > 1:\n        result = n * factorial (n - 1)\n    return result\n\ndef fibonacci(n):\n    if n < 2:\n        return n\n    else:\n        return fibonacci (n - 1) + fibonacci (n - 2)\n\nfor n in range(10):\n    print(fibonacci(n))\n    \n\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/haroldAlb.py",
    "content": "### 06 - RECURSIVIDAD ###\n\n# Entiende el concepto de recursividad creando una función\n# recursiva que imprima números del 100 al 0. #\n\ndef cuenta_atras(n):\n    print(n)\n    if n > 0:\n        n -= 1\n        cuenta_atras(n)\n    else:\n        print(\"Fin de la cuenta atras.\")\n\ncuenta_atras(100)\n\n### EXTRA ###\n\n# Calcular el factorial de un número concreto (la función recibe ese número) #\n\ndef factorial(n):\n    if n > 1:\n        aux = factorial(n-1)\n    else:\n        return 1\n    return aux * n\n\nresultado = factorial(6)\n\nprint(resultado)\n\n# Calcular el valor de un elemento concreto (según su posición) en la sucesión de Fibonacci (la función recibe la posición) #\n\ndef fibonacci(n): # No me salió bien!!!\n    if n > 1:\n        fib_list = fibonacci(n-1)\n        fib_list.append(fib_list[n-1] + fib_list[n-2])\n        return fib_list\n\t\t\n    else:\n        fib_list = []\n        fib_list.append(0)\n        fib_list.append(1)\n        return fib_list\n\nposicion = fibonacci(5)\t\nprint(posicion[-1])\n\n# Solución de Brais\n\ndef fibo_Brais(number):\n    if number <= 0:\n        print(\"La posición tiene que ser mayor de cero\")\n        return 0\n    elif number == 1:\n        return 0\n    elif number == 2:\n        return 1\n    else:\n        return fibo_Brais(number - 1) + fibo_Brais(number - 2)\n    \nprint(fibo_Brais(5))"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/hectordbh.py",
    "content": "\"\"\"EJERCICIO\"\"\"\n\ndef decrease(num):\n    \"\"\"Función que devuelve valores decrecientes uno a uno\n    hasta cero.\n\n    Args:\n        num (int): valor inicial\n\n    Returns:\n        int: valores\n    \"\"\"\n    # Caso final\n    if num < 0:\n        return num\n    print(num)\n    decrease(num-1)\n\ndecrease(100)\n\n# DIFICULTAD EXTRA\n\n# Factorial\ndef factorial(num, result = 1):\n    \"\"\"Función que devuelve el valor del factorial de un\n    número\n\n    Args:\n        num (int): valor al que hacerle el factorial\n        result (int, optional): _description_. Defaults to 1.\n\n    Returns:\n        int: valor de cálculo\n    \"\"\"\n    if num == 0:\n        return result\n    else:\n        result *= num\n        return factorial(num-1, result)\n\nfactorial(3)\n\n# Fibonacci\ndef fibo(n):\n    \"\"\"FUnción que devuelve el valor de una posición\n    en la sucesión de Fibonacci\n\n    Args:\n        n (int): posición\n\n    Returns:\n        int: valor de la posición\n    \"\"\"\n    if n <= 1:\n        return n\n    else:\n        return fibo(n-1)+fibo(n-2)\n\nfibo(4)\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/hectorio23.py",
    "content": "# Autor: Héctor Adán\n# GitHub: https://github.com/hectorio23\n\n\n# EJERCICIO:\n# Entiende el concepto de recursividad creando una función recursiva que imprima\n# números del 100 al 0.\n#\n# DIFICULTAD EXTRA (opcional):\n# Utiliza el concepto de recursividad para:\n# - Calcular el factorial de un número concreto (la función recibe ese número).\n# - Calcular el valor de un elemento concreto (según su posición) en la \n#   sucesión de Fibonacci (la función recibe la posición).\n\n\ndef recursiveFoo(valorInicial):\n    # Esta función imprime números desde valorInicial hasta 0 recursivamente\n    if valorInicial < 0:\n        return\n    print(valorInicial, end=\", \")\n    recursiveFoo(valorInicial - 1)\n\ndef factorial(ivalue):\n    # Calcula el factorial de ivalue recursivamente\n    if ivalue == 1:\n        return 1\n    return ivalue * factorial(ivalue - 1)\n\ndef fibonacci(n):\n    # Calcula el valor en la posición n de la sucesión de Fibonacci\n    if n <= 0:\n        print(\"La posición debe ser un entero positivo\")\n        return -1  # o manejo de error según sea necesario\n    elif n == 1:\n        return 0\n    elif n == 2:\n        return 1\n    else:\n        a, b = 0, 1\n        for _ in range(2, n):\n            temp = b\n            b = a + b\n            a = temp\n        return b\n\n# Programa principal\nif __name__ == \"__main__\":\n    numeroCalcularFactorial = 3\n    posicion = 10\n\n    print(\"********* NUMEROS DEL 100 - 0 *********\")\n    recursiveFoo(100)\n    print(\"\\n\")\n\n    print(f\"El factorial de <<{numeroCalcularFactorial}>> es: {factorial(numeroCalcularFactorial)}\")\n\n    valor = fibonacci(posicion)\n    print(f\"El valor en la posición {posicion} de la sucesión de Fibonacci es: {valor}\")\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/hozlucas28.py",
    "content": "\"\"\"\n    Recursive function...\n\"\"\"\n\nprint(\"\\nRecursive function...\")\n\n\ndef recursive_fn(start: int, end: int, rtn: list[int]) -> list[int]:\n    \"\"\"Recursive function\"\"\"\n    if start < end:\n        return rtn\n\n    rtn.append(start)\n    recursive_fn(start - 1, end, rtn)\n\n\nprint(\n    \"\"\"\\ndef recursive_fn(start: int, end: int, rtn: list[int]) -> list[int]:\n    if start < end:\n        return rtn\n\n    rtn.append(start)\n    recursive_fn(start - 1, end, rtn)\"\"\"\n)\n\nrecursive_rtn: list[int] = []\nrecursive_fn(100, 0, recursive_rtn)\n\nprint(\"\\nrecursive_rtn: list[int] = []\")\nprint(\"recursive_fn(100, 0, recursive_rtn)\")\n\nprint(f\"\\nrecursive_rtn --> {recursive_rtn}\")\n\nprint(\n    \"\\n# ---------------------------------------------------------------------------------- #\\n\"\n)\n\n\"\"\"\n    Additional challenge...\n\"\"\"\n\nprint(\"Get factorial...\")\n\n\ndef get_factorial(number: int) -> int:\n    \"\"\"Get factorial of a number\"\"\"\n    if number == 1:\n        return 1\n\n    return number * get_factorial(number - 1)\n\n\nprint(\n    \"\"\"\\ndef get_factorial(number: int) -> int:\n    if number == 1:\n        return 1\n\n    return number * get_factorial(number - 1)\"\"\"\n)\n\nprint(f\"\\nget_factorial(5) --> {get_factorial(5)}\")\n\nprint(\n    \"\\n# ---------------------------------------------------------------------------------- #\\n\"\n)\n\nprint(\"Get Fibonacci value by position...\")\n\n\ndef get_fibonacci_value_by_pos(pos: int) -> int:\n    \"\"\"Get Fibonacci value by position\"\"\"\n    if pos in [1, 2]:\n        return 1\n\n    return get_fibonacci_value_by_pos(pos - 1) + get_fibonacci_value_by_pos(pos - 2)\n\n\nprint(\n    \"\"\"\\ndef get_fibonacci_value_by_pos(pos: int)->int: \n    if pos in [1, 2]: \n        return 1\n\n    return get_fibonacci_value_by_pos(pos - 1) + get_fibonacci_value_by_pos(pos - 2)\"\"\"\n)\n\nprint(f\"\\nget_fibonacci_value_by_pos(8) --> {get_fibonacci_value_by_pos(8)}\")\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/idiegorojas.py",
    "content": "# Ejercicio \n\ndef contar_atras(n):\n    if n < 0:\n        return\n    print(n)\n    contar_atras(n-1)\n\nprint(contar_atras(100))\n\n# Calcular el factorial de un número\ndef factorial(n):\n    if n == 0 or n == 1:\n        return 1\n    else:\n        return n * factorial(n - 1)\n    \nprint(factorial(5))\n\n\n#  Fibonacci\ndef fibonacci(posicion):\n    if posicion == 0:\n        return 0\n    elif posicion == 1:\n        return 1\n    else:\n        return fibonacci(posicion - 1) + fibonacci(posicion - 2)\n\nposicion = 10\nprint(f\"El valor en la posición {posicion} de la sucesión de Fibonacci es: {fibonacci(posicion)}\")"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/ignaciovihe.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n\"\"\"\n\ndef countdown(number: int):\n    if number > -1:\n        print(number)\n        countdown(number - 1)\n\ncountdown(100)\n\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n\"\"\"\n\ndef factorial(number: int) -> int:\n    if number < 0:\n        print(\"El factorial de numeros negativos no esta definido\")\n        return 0\n    elif number > 0:\n        return number * factorial(number - 1)\n    else:\n        return 1\n\nmy_number = 5\nprint(f\"Fatorial de {my_number} = {factorial(my_number) if factorial(my_number) != 0 else \"No definido\"}\")\n\n\n\"\"\"\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n\"\"\"\n\ndef fibonacci(position: int) -> int:\n    if position < 0:\n        print(\"La posicion debe ser mayor que 0\")\n        return 0\n    elif position == 1:\n        return 0\n    elif position == 2:\n        return 1\n    else:\n        return fibonacci(position - 1) + fibonacci(position - 2)\n\nmy_position = -1\nprint(f\"La posicion {my_position} de la secuencia de fibonacci es: {fibonacci(my_position)}\")"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/ingjavierpinilla.py",
    "content": "\"\"\"\n\n/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n \n \"\"\"\n\n\ndef imprime_numeros(n: int):\n    if n < 0:\n        return\n    print(n)\n    imprime_numeros(n - 1)\n\n\ndef factorial(n: int):\n    if n == 0:\n        return 1\n    return n * factorial(n - 1)\n\n\n# 1, 1, 2, 3, 5, 8, 13, 21\n\n\ndef fibonacci(n: int):\n    print(f\"calculando el fibonacci de: {n}\")\n    if n <= 1:\n        return n\n    return fibonacci(n - 2) + fibonacci(n - 1)\n\n\ndef main():\n    imprime_numeros(100)\n    print(factorial(5))\n    print(fibonacci(7))\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/inkhemi.py",
    "content": "# Función recursiva 100 a 0\ndef cuenta_regresiva(number: int):\n    if number == 0:\n        print(number)\n        print(\"Final de la cuenta regresiva\")\n    else:\n        print(number)\n        cuenta_regresiva(number-1)\n\n\ncuenta_regresiva(100)\n\n# Dificultad extra\n\n\n# Optimización de funciones recursivas\ndef moize(func):\n    cache = {}\n\n    def wrapper(*args):\n        if args not in cache:\n            cache[args] = func(*args)\n        return cache[args]\n    return wrapper\n\n\n# Factorial\n@moize\ndef factorial(number: int) -> int:\n    if number == 0:\n        return 1\n    else:\n        return number * factorial(number - 1)\n\n\nprint(f\"el factorial de 10 es {factorial(10)}\")\n\n\n# Fibonacci\n@moize\ndef fibonacci(position: int) -> int:\n    if position == 0:\n        return 0\n    elif position == 1:\n        return 1\n    else:\n        return fibonacci(position - 1) + fibonacci(position - 2)\n\n\nprint(\n    f\" el número equivalente a la posición 30 en la sujeción de fibonacci es {fibonacci(30)}\")\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/inmortalnight.py",
    "content": "# 06 - Recursividad\n\n# Función recursiva que imprime números 100-0\ndef imprimir():\n    for i in range(100, -1, -1):\n        print(i)\nimprimir()\n# EXTRA 1: Calcular factorial\ndef factorial(number):\n    factorial = 1\n    for i in range(number, 0, -1):\n        factorial = factorial * i\n        print(number)\n    print(\"Factorial de \", number, \" es \", factorial)\nfactorial(20)\n# EXTRA 2: Calcular el valor según la posición introducida en la sucesión de Fibonacci\ndef fibonacci(n):\n    if n < 2:\n        return n\n    else:\n        return fibonacci(n - 1) + fibonacci(n - 2)\nposition = 4\nprint(f\" Según la posición {position} fibonacci es {fibonacci(position)}\")"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/ipfabio.py",
    "content": "\"\"\"\nEjercicio\n\"\"\"\n# Tiene que llamarse a ella misma y detenerse en algún momento\ndef countdown(number: int):\n    if number >= 0:\n        print(number)\n        countdown(number - 1)\n\ncountdown(100)\n\n\"\"\"\nExtra\n\"\"\"\n# Factorial de 0 es 1\n# Cuando una función se puede acabar diviendo en otros sub-problemas dentro del problema general\ndef factorial(number: int) -> int: \n    # Ej:  Subproblemas\n    if number < 0:\n        print(\"Tienen que ser números enteros y positivos.\")\n        return 0\n    elif number == 0:\n        return 1\n    else: # Problema\n        return number * factorial(number - 1) \n\nprint(factorial(5))\n\n\ndef fibonacci(number: int) -> int:\n    if number <= 0:\n        print(\"La posición tiene que ser mayor que 0\")\n        return 0\n    elif number == 1:\n        return 0\n    elif number == 2:\n        return 1\n    elif number >= 3:\n        return fibonacci(number - 1) + fibonacci(number - 2)\n\nprint(fibonacci(5))\n\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/isilanes.py",
    "content": "def print_down_to_zero(start: int) -> None:\n    \"\"\"\n    Given a starting integer 'start', print it, and all integers below it,\n    down to zero.\n\n    Args:\n        start (int):\n            Starting integer.\n\n    Returns:\n        Nothing. Just prints the numbers out.\n    \"\"\"\n    if not isinstance(start, int):\n        raise TypeError(\"Esta función sólo acepta enteros.\")\n\n    if start < 0:\n        raise ValueError(\"Esta función no acepta números negativos (si lo hiciera, no pararía nunca).\")\n\n    if start > 1000:\n        raise ValueError(\"Vamos, muchacho, ¿para qué quieres imprimir más de 1000 números? Sé razonable.\")\n\n    print(start)\n\n    if start > 0:\n        print_down_to_zero(start-1)\n\n\ndef factorial(n: int) -> int:\n    \"\"\"\n    Given an integer 'n', return its factorial.\n\n    Args:\n        n (int):\n            Integer whose factorial we want to calculate.\n\n    Returns:\n        Factorial of n.\n    \"\"\"\n    if not isinstance(n, int):\n        raise TypeError(\"Esta función sólo acepta enteros (pregunta a tus papás por la función Gamma).\")\n\n    if n < 0:\n        raise ValueError(\"Esta función sólo acepta enteros positivos (busca la función Gamma en la Wikipedia).\")\n\n    if n > 25:\n        raise ValueError(\"Estás jugando a ser dios con factoriales tan grandes.\")\n\n    if n in (0, 1):\n        return 1\n\n    return n * factorial(n-1)\n\n\ndef fibonacci_bad(n: int) -> int:\n    \"\"\"\n    Given an integer \"n\", return n-th member of the Fibonacci sequence.\n\n    This function uses the naïve recursive implementation, which is a terribly inefficient way\n    of performing the calculation. No one in their right mind would or should use this rubbish.\n    Use fibonacci_good() instead.\n\n    Args:\n        n (int):\n            The position in the Fibonacci sequence that we want to calculate.\n\n    Return:\n        Given n, returns fib(n).\n    \"\"\"\n    if not isinstance(n, int):\n        raise TypeError(\"Esta función sólo acepta enteros.\")\n\n    if n < 0:\n        raise ValueError(\"Esta función sólo acepta enteros positivos.\")\n\n    if n > 35:\n        raise ValueError(\"Esta implementación de fib(n) es una mierda. Para valores grandes usa fibonacci_good().\")\n\n    if n == 0:\n        return 0\n\n    if n in (1, 2):\n        return 1\n\n    return fibonacci_bad(n-1) + fibonacci_bad(n-2)\n\n\ndef fibonacci_good(n: int) -> int:\n    \"\"\"\n    More sensible implementation of fib(n) than fibonacci_bad(). The only downside is that\n    it is not recursive, so it is not fit for the '#06 - Recursividad' task :)\n\n    A better implementation yet could be to use Binet's formula.\n\n    Args:\n        n (int):\n            The position in the Fibonacci sequence that we want to calculate.\n\n    Return:\n        Given n, returns fib(n).\n    \"\"\"\n    if not isinstance(n, int):\n        raise TypeError(\"Esta función sólo acepta enteros.\")\n\n    if n < 0:\n        raise ValueError(\"Esta función sólo acepta enteros positivos.\")\n\n    if n == 0:\n        return 0\n\n    prev, curr = 0, 1  # we are sitting at n=1\n    for _ in range(2, n+1):\n        curr, prev = curr + prev, curr\n\n    return curr\n\n\ndef extra():\n    print(f\"25! = {factorial(25)}\")\n    print(f\"fib(25) = {fibonacci_bad(25)}\")\n\n\ndef main():\n    print_down_to_zero(100)\n\n\nif __name__ == \"__main__\":\n    main()\n    extra()\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/ivangdev.py",
    "content": "# # -------------- Recursividad ------------------\ndef recursividadNumeros(numero=100):\n    print(numero)\n    if numero == 0:\n        return 0\n    else:\n        recursividadNumeros(numero - 1)\n\n\nrecursividadNumeros()\n\n\n# DIFICULTAD EXTRA (opcional):\n#  * Utiliza el concepto de recursividad para:\n#  * - Calcular el factorial de un número concreto (la función recibe ese número).\n#  * - Calcular el valor de un elemento concreto (según su posición) en la\n#  *   sucesión de Fibonacci (la función recibe la posición).\n\n\ndef recursividadFactorial(numero):\n    if numero == 1:\n        return 1\n    else:\n        factorial = numero * recursividadFactorial(numero - 1)\n        return factorial\n\n\ndef recursividadFibonacci(posicion):\n    if posicion == 0:\n        return 0\n    elif posicion == 1:\n        return 1\n    else:\n        return recursividadFibonacci(posicion - 1) + recursividadFibonacci(posicion - 2)\n\n\nprint(recursividadFactorial(3))\nprint(recursividadFibonacci(10))\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/javierjoyera.py",
    "content": "##06 RECURSIVIDAD\n\n#Funcion Recursiva que imprime del 100 al 0\ndef imprimir_recursivo(n): \n    if n >= 0:\n        print(n)\n        #Llamada recursiva en la cual le restamos 1 al valor de n\n        imprimir_recursivo(n-1)\n    else:\n        return\n    \n#Llamada a la funcion\nimprimir_recursivo(100)\n\n#Factorial de un numero\n'''\nEl factorial de un número entero positivo n se define como el producto de todos los enteros positivos menores o iguales a n.\n\nn! = n * (n-1) * (n-2) * ... * 1\n\nn! = n * (n-1)!\n\nEjemplo:\n5! = 5 * \n4 * 3 * 2 * 1 = 120\n'''\ndef function_factorial(n):\n    if n == 0:\n        return 1\n    else:\n        return n * function_factorial(n-1)\n    \n#ejemplo\nmy_number = 5\nprint(\"El factorial de %d es %d\" % (my_number, function_factorial(my_number)))\n\n#Calcular el valor de un elemento (según su posición) de la serie de Fibonacci\n'''\nLa sucesión de Fibonacci es una sucesión infinita de números naturales que comienza con los números 0 y 1, y a partir de estos, \ncada término es la suma de los dos anteriores.\n'''\ndef function_fibonaci(n):\n    if n == 0:\n        return 0\n    elif n == 1:\n        return 1\n    else:\n        return function_fibonaci(n-1) + function_fibonaci(n-2)\n    \n#Ejemplo\nmy_number = 7\nprint(\"El número de la serie de Fibonacci en la posición %d es %d\" % (my_number, function_fibonaci(my_number)))\n\nprint(\"---------------------------------------------------\")\n    \n#Ejemplo con entrada por terminal\nprint(\"Ingresa la posición del número de la serie de Fibonacci que deseas calcular\")\nmy_number = int(input())\nprint(\"El número de la serie de Fibonacci en la posición %d es %d\" % (my_number, function_fibonaci(my_number)))\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/jcdm60.py",
    "content": "# #06 RECURSIVIDAD\n#### Dificultad: Difícil | Publicación: 05/02/24 | Corrección: 12/02/24\n\n## Ejercicio\n\n\n#\n# EJERCICIO:\n# Entiende el concepto de recursividad creando una función recursiva que imprima\n# números del 100 al 0.\n#\n# DIFICULTAD EXTRA (opcional):\n# Utiliza el concepto de recursividad para:\n# - Calcular el factorial de un número concreto (la función recibe ese número).\n# - Calcular el valor de un elemento concreto (según su posición) en la \n#   sucesión de Fibonacci (la función recibe la posición).\n#\n\n# IMPRIME NUMEROS DEL 100 al 0\ndef imprimir_numeros(n):\n    if n >= 0:\n        print(n)\n        imprimir_numeros(n - 1)\n\nimprimir_numeros(100)\n\n# FACTORIAL\ndef factorial(n):\n    if n == 0:\n        return 1\n    else:\n        return n * factorial(n - 1)\n\nprint(\"Calcular factorial: \")\nnumero = int(input())\nprint(factorial(numero))\n\n# POSICION FIBONACCI\nmemoria = {}\n\ndef fibonacci(posicion):\n    if posicion in memoria:\n        return memoria[posicion]\n    elif posicion == 0:\n        return 0\n    elif posicion == 1:\n        return 1\n    else:\n        resultado = fibonacci(posicion - 1) + fibonacci(posicion - 2)\n        memoria[posicion] = resultado\n        return resultado\n\nprint(\"Calcular Fibonacci\")\nposicion = int(input())\nvalor = fibonacci(posicion)\nprint(f\"Posición {posicion} su Fibonacci es: {valor}\")\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/jesusgdev.py",
    "content": "'''\nEJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n   números del 100 al 0.\n  \n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n     sucesión de Fibonacci (la función recibe la posición).\n'''\n\n\ndef countdown(num):\n    print(num)\n\n    if num == 0:\n        return\n    \n    countdown(num - 1)\n\ncountdown(100)\n\n\n'''\nExtra\n'''\n\n# Factorial de un numero\n\nprint(\"\")\n\ndef factorial(num):\n    if num < 0:\n        return print(\"Los numeros negativos no son validos\")\n    elif num == 0 or num == 1:\n        result = 1\n        print (result)\n    elif num > 1:\n        result = num * factorial(num - 1)\n        print(result)\n    return result\n\nfactorial(-1)\n\n# Secuencia de fibonacci\n\nprint(\"\")\n\ndef fibonacci(position):\n    if position <= 0:\n        return print(\"La posicion tiene que ser mayor que 0\")\n    \n    def fibonacci_serie(n):\n        if n == 1:\n            return 0\n        elif n == 2:\n            return 1\n        else:\n            return fibonacci_serie(n - 1) + fibonacci_serie(n - 2)\n        \n    for i in range(1, position + 1):\n        print(fibonacci_serie(i))\n\nfibonacci(5)"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/jesusway69.py",
    "content": "import os\nos.system('cls')\n\n\n\"\"\"\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n\"\"\"\nnum = 101\ndef countdown (num):#Definimos la función y le pasamos el número 101 en la primera ejecución\n    num -=1#En la primera iteración deja el número en 100 y va restando 1 en cada entrada a la función\n    if num >= 0:#Establecemos la condición de parada en 0 \n        print(num, end=' ') #imprimimos cada número horizontalmente y separado en cada ejecución de la función\n        if num % 10 == 0 and num != 100: #establecemos un salto de línea cada 10 números para hacerlo más visual (opcional)\n            print('')#Salto de línea\n        countdown(num) #Llamada recursiva a la función con el número ya modificado restándole 1\ncountdown(num)#Llamada inicial a la función\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n\"\"\"\n\n\n#FUNCIÓN FIBONACCI POR RECURSIVIDAD\nlist_fibonacci = [0,1]\ncopy, counter1, counter2 = 0, 0, 1\n\ndef fibonacci (fib_position:int):\n    global copy , counter1, counter2 \n    if fib_position>copy:\n     copy = fib_position\n    if fib_position <=0:\n        print(\"el nº debe ser mayor a 0\")\n        return\n    if fib_position==2:\n        print(f\"\\nLa posición {copy} de la secuencia Fibonacci tiene el valor {list_fibonacci[copy-1]}\\n\")\n        return\n    if fib_position == 1:\n        print (\"\\nLa posición 1 de la secuencia Fibonacci tiene el valor 0 \")\n        return\n    elif fib_position >2:   \n        list_fibonacci.append(list_fibonacci[counter1]+list_fibonacci[counter2])\n        counter1 +=1\n        counter2 +=1    \n        fib_position -=1\n        fibonacci(fib_position)\n\n\n # FUNCIÓN FACTORIAL POR RECURSIVIDAD\nacc = 1\ndef factorial (factorial_num:int):\n  global acc, copy\n  if factorial_num>copy:\n      copy=factorial_num\n  if factorial_num>1:\n      acc = factorial_num * acc\n      factorial_num -=1\n      factorial(factorial_num)\n  else:\n      print(f\"\\nEl factorial de {copy} es: {acc}\\n\")\n      return\n\n\n\n\ndef menu ():   \n while True:\n  num = input(\"\"\"\n            1- Mostrar posición en la secuencia Fibonacci\n            2- Mostrar factorial\n            3- Salir\n              Elija una opción:  \"\"\")\n  try:\n   num = int(num)\n   num == 1 or num == 2\n   if num == 1:\n        num = int(input(\"\\nIntroduzca un número para calcular su posición en la secuencia Fibonacci: \"))\n        fibonacci(num)\n        return\n   if num == 2:\n        num = int(input(\"\\nIntroduzca un número para calcular su factorial: \"))\n        factorial(num)\n        return\n   if num == 3:\n        print(\"\\nFin del programa\\n\")\n        return\n   else:\n        print (\"\\nSólo se pueden elegir opciones entre 1 y 2, pruebe de nuevo\")\n        menu()\n     \n   break\n  except ValueError:\n    print(\"\\nSólo se pueden introducir números enteros, pruebe de nuevo\")\nmenu()\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/jgutierrez9891.py",
    "content": "\"\"\"\nRecursividad\n\"\"\"\n\ndef tri_recursion(x):\n  print(x)\n  if(x==0):\n    return\n  else:\n    tri_recursion(x-1)\n\nprint(\"\\n\\nRecursion Example Results\")\ntri_recursion(100)\n\n\n\"\"\"\nExtra\n\"\"\"\n\n\ndef factorial(x: int) -> int:\n    \"\"\"This is a recursive function\n    to find the factorial of an integer\"\"\"\n    if x <= 0:\n       print(\"Number must be positive\")\n       return 0\n    elif x == 1:\n        return 1\n    else:\n        return (x * factorial(x-1))\n\ndef fibonacci(x : int) -> int:\n    if x <= 0:\n        print (\"Number must be positive\")\n        return 0\n    elif x == 1:\n        return 0\n    elif x == 2:\n        return 1\n    else:\n        return fibonacci(x-1) + fibonacci(x-2)\n\nprint(factorial(5))\n\nprint(fibonacci(5))\n\n\n\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/jhonatanmustiolacas.py",
    "content": "#!/usr/bin/env\n\n# EJERCICIO:\n# Entiende el concepto de recursividad creando una función recursiva que imprima\n# números del 100 al 0.\n#\n# DIFICULTAD EXTRA (opcional):\n# Utiliza el concepto de recursividad para:\n# - Calcular el factorial de un número concreto (la función recibe ese número).\n# - Calcular el valor de un elemento concreto (según su posición) en la \n#   sucesión de Fibonacci (la función recibe la posición).\n\n# TODO: función recursiva que imprime números del 100 al 0\ndef imprime_del_cien_al_cero_recursivo() -> None:\n    \"\"\"\n    Imprime los números del 100 al cero recursivamente\n\n    >>> imprime_del_cien_al_cero_recursivo()\n\n    \"\"\"\n    if hasattr(imprime_del_cien_al_cero_recursivo, \"count\"):\n        if imprime_del_cien_al_cero_recursivo.count < 0:\n            return\n        else:\n            print(imprime_del_cien_al_cero_recursivo.count)\n            setattr(imprime_del_cien_al_cero_recursivo, \"count\", imprime_del_cien_al_cero_recursivo.count - 1)\n    else:\n        imprime_del_cien_al_cero_recursivo.count = 100\n    imprime_del_cien_al_cero_recursivo()\n\n\n# TODO: funcion recursiva para calcular factorial de un número dado\ndef calculo_factorial_recursivo(numero: int) -> int:\n    \"\"\"\n    Retorna el cálculo factorial del argumento numero\n\n    >>> calculo_factorial_recursivo(5)\n    120\n    \"\"\"\n    if numero == 0:\n        return 1\n    return numero * calculo_factorial_recursivo(numero - 1)\n\n\n# TODO: funcion recursivo para calcular valor de un número fibonacci en una posición dada\ndef fibonacci_en_recursivo(posicion: int) -> int:\n    \"\"\"\n    Retorna el valor del número fibonacci en la posición dada con el argumento posicion\n\n    >>> fibonacci_en_recursivo(10)\n    55\n    \"\"\"\n    return 0 if (posicion == 0) else 1 if (posicion == 1) else  (fibonacci_en_recursivo(posicion-1) + fibonacci_en_recursivo(posicion-2))\n\n\n\n# TEST\n\nresultado = imprime_del_cien_al_cero_recursivo()\nprint(resultado)\n\nresultado = calculo_factorial_recursivo(5)\nprint(resultado)\n\nresultado = fibonacci_en_recursivo(10)\nprint(resultado)\n\nimport doctest\n\ndoctest.testmod()"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/jhoshmc.py",
    "content": "\"\"\"\n! EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n\"\"\"\n\ndef ejercicio():\n  numero=100\n  conteoRecursivo(numero)\n\ndef conteoRecursivo(numero):\n  if numero == 0:\n    print(f\"numero: {numero}\")\n    return\n  if numero >0:\n    print(f\"numero: {numero}\")\n    return conteoRecursivo(numero-1)\n  \nejercicio()\n\n\"\"\"\n! DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la\n *   sucesión de Fibonacci (la función recibe la posición).\n\"\"\"\n\ndef extra():\n  numeroFactorial= int(input(\"ingrese el numero factorial: \"))\n  resultadoFactorial= factorialRecursivo(numeroFactorial)\n  print(\"\\n\\t numero factorial \\n\")\n  print(f\"el factorial del numero {numeroFactorial}! es: {resultadoFactorial}\")\n  print(\"\\n\\t numero fibonacci \\n\")\n  posicionFibonacci=int(input(\"ingrese la posicion fibonacci: \"))\n  resultadoFibonacci = fibonacciRecursivo(posicionFibonacci)\n  print(f\"el numero fibonacci en la posicion {posicionFibonacci} es: {resultadoFibonacci}\")\n\ndef factorialRecursivo(numero)->int:\n  if numero == 1:\n    return 1\n  if numero > 1:\n    return numero * factorialRecursivo(numero-1)\n  \ndef fibonacciRecursivo(numero)->int:\n  if numero == 0:return 0\n  if numero == 1: return 1\n  return fibonacciRecursivo(numero-1)+fibonacciRecursivo(numero-2)\n\nextra()"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/joancharles07.py",
    "content": "def cuentaRegresiva(valor):\n    print(valor)\n    if(valor!=0):\n        cuentaRegresiva(valor -1)\n        \ndef factorial(numero):\n    resultado=1\n    if numero > 1:\n        resultado=factorial(numero - 1) * numero\n    else:\n        return 1\n    return resultado\n\n\ndef fibonacci(terminos):\n    resultado=0\n    if terminos != 1 and terminos !=0:\n        resultado=fibonacci(terminos - 1) + fibonacci(terminos - 2)\n    elif terminos == 1 :\n        return 1\n    else:\n        return 0\n    \n    return resultado\n\n#Prueba de uso comentadas para probarlas de una en una\n#cuentaRegresiva(100)\n#print(factorial(5))\n#print(fibonacci(10))\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/jose-larss.py",
    "content": "\"\"\"\nEjercicio\n\"\"\"\n\n\ndef countdown(number: int):\n    if number >= 0:\n        print(number)\n        countdown(number - 1)\n\n\n#countdown(100)\n\n\"\"\"\nExtra\n\"\"\"\n\n\ndef factorial(number: int) -> int:\n    if number < 0:\n        print(\"Los números negativos no son válidos\")\n        return 0\n    elif number == 0:\n        return 1\n    else:\n        return number * factorial(number - 1)\n\n\n#print(factorial(5))\n\n\ndef fibonacci(number: int) -> int:\n    if number <= 0:\n        print(\"La posición tiene que ser mayor que cero\")\n        return 0\n    elif number == 1:\n        return 0\n    elif number == 2:\n        return 1\n    else:\n        return fibonacci(number - 1) + fibonacci(number - 2)\n\n\nprint(fibonacci(5))"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/josecox13.py",
    "content": "\n# Imprime del número al 100, de forma recursiva\ndef imprimir_recursiva(num: int):\n    print(num)\n    if num != 0:\n        imprimir_recursiva(num-1)\n\nimprimir_recursiva(100)\n\n#Factorial\ndef factorial(num:int):\n    if num == 0:\n        return 1\n    else:\n        return num * factorial(num-1)\nprint(factorial(15))\n\n#Posición en la sucesión de Fibonacci\ndef fibonacci(num:int):\n    if num <= 0:\n        print('Introduce un valor positivo')\n    elif num == 1:\n        return 0\n    elif num == 2:\n        return 1\n    else:\n        return fibonacci(num - 1) + fibonacci(num - 2)\n\nprint(fibonacci(15))\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/jptxaya.py",
    "content": "\n#Recursividad\ndef funcion_contar_atras(mint):\n    if mint < 0:\n        return\n    print(mint)\n    funcion_contar_atras(mint - 1)\n\nfuncion_contar_atras(100)\n\n#Dificultad Extra\nprint(\"Dificultad Extra\")\ndef factorial(my_int):\n    if my_int == 1:\n        return 1\n    result = factorial(my_int -1) * my_int\n    return result\n\nprint(\"Calcular factorial\")\nfactor = int(input(\"Introducir numero a calcular:\"))\nprint(f\"Resultado:{factorial(factor)}\")\n\ndef posicion_fibonacci(my_pos):\n    if my_pos == 0:\n        return 0\n    elif my_pos == 1:\n        return 1\n    else:\n        return posicion_fibonacci(my_pos - 2) + posicion_fibonacci(my_pos - 1)\n    \n\nprint(\"Calcular numero en posicion Fibonacci\")\nposicion = int(input(\"Introducir posicion:\"))\nprint(f\"Resultado:{posicion_fibonacci(posicion)}\")\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/jtrujilloalcocer.py",
    "content": "# #06 RECURSIVIDAD\n## Ejercicio\n'''\n/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n'''\n#RECURSIVIDAD\n#La recursividad es una función que se llama a sí misma\ndef imprimir_numero(n):\n    if n >= 0:\n        print(n)\n        imprimir_numero(n-1)\n        \nimprimir_numero(100)\n\n#DIFICULTAD EXTRA\ndef factorial(n): #5! = 5*4*3*2*1\n    if n == 0:\n        return 1\n    else:\n        return n * factorial(n-1)\n    \n#La funcion fibonacci es una sucesion de numeros que se obtiene sumando los dos anteriores    \ndef fibonacci(n): #0,1,1,2,3,5,8,13,21,34,55,89,144,233,377...\n    if n == 0:\n        return 0\n    elif n == 1:\n        return 1\n    else:\n        return fibonacci(n-1) + fibonacci(n-2)\n\ndef menu():\n    print(\"1.- Factorial\")\n    print(\"2.- Fibonacci\")\n    print(\"3.- Salir\")\n    opcion = int(input(\"Selecciona una opcion: \"))\n    if opcion == 1:\n        num = int(input(\"Ingresa un numero: \"))\n        print(factorial(num))\n    elif opcion == 2:\n        num = int(input(\"Ingresa un numero: \"))\n        print(fibonacci(num))\n    elif opcion == 3:\n        print(\"Adios\")\n    else:\n        print(\"Opcion invalida\")\n        menu()\nmenu()  "
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/juanRCoder.py",
    "content": "\n#  * DIFICULTAD EXTRA (opcional):\n#  * Utiliza el concepto de recursividad para:\n#  * - Calcular el factorial de un número concreto (la función recibe ese número).\n#  * - Calcular el valor de un elemento concreto (según su posición) en la \n#  *   sucesión de Fibonacci (la función recibe la posición).\n#  */\n\n# Funcion recursiva que por defecto tiene numero 100 como parametro\ndef printing(n=100):\n    print(n)\n    \n    # Cuando es menor o igual a 0 sale\n    if n <= 0: \n        return 0\n    \n    # La funcion se retornara a si misma(recursiva) restandose en uno su parametro\n    return n - printing(n - 1)  \n\nprinting(100)\n\n\n# DIFICULTAD EXTRA (opcional):\n# Factorial\ndef factorial(n):\n    if n == 1:\n        return 1\n    return n * factorial(n - 1);\n\n# print(factorial(5)) #120\n\n\n# Fibonacci (2)\ndef fibonacci(n):\n    if n <= 0: return 0\n    elif n == 1: return 1 \n    return fibonacci(n - 1) + fibonacci(n - 2)\n\nprint(f\"Posiition 4: {fibonacci(4)}\")"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/juanchernandezdev.py",
    "content": "### Python Recursion ###\n\ndef count_back(num):\n  print(num)\n  \n  if num == 0:\n    return\n  else:\n    count_back(num - 1)\n    \n  \n#! Optional Challenge\n\n#** Factorial\n\ndef factorial(num):\n  if num == 0:\n    return 1\n  else:\n    return num * factorial(num - 1)\n  \nmy_num_factorial = factorial(8)\nprint(my_num_factorial)\n\n#** Fibonacci Value\n\ndef fibonacci_value(pos):\n  if pos < 0:\n    return 'Value must be positive'\n  \n  if pos == 1:\n    return 1\n  \n  if pos == 0:\n    return 0\n  \n  return fibonacci_value(pos - 1) + fibonacci_value(pos - 2)\n\nprint(fibonacci_value(20))\n  "
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/juandaherrera.py",
    "content": "def print_sep(title: str = None) -> None:\n    sep = \"-\"\n    print_var = sep * 8 + title + sep * 8 if title else sep * 16\n    print(print_var)\n\n\n\"\"\"\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n\"\"\"\n\n\ndef my_function(n: int) -> None:\n    if n == 0:\n        print(0)\n    else:\n        print(n)\n        my_function(n - 1)\n\n\nprint_sep(\"Ejercicio\")\n\nmy_function(100)\n\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n\"\"\"\n\n\n# Factorial de un número\ndef factorial(n: int) -> int:\n    if n < 0:\n        print(\"Número no válido\")\n        return 0\n    elif n == 0:\n        return 1\n    return n * factorial(n - 1)\n\n\nprint_sep(\"Factorial\")\n\nprint(factorial(9))\n\n\n# Calcular valor de elemento en la sucesión de fibonacci\n\n\ndef fibonacci(position: int) -> int:\n    \"\"\"\n    Esta función tiene complejidad algorítmica de O(2^n).\n    Es decir que es muy ineficiente para valores grandes de position\n    \"\"\"\n    if position <= 0:\n        print(\"Número no válido\")\n        return 0\n    elif position <= 2:\n        return position - 1\n\n    return fibonacci(position - 1) + fibonacci(position - 2)\n\n\nprint_sep(\"Fibonacci\")\n\nprint(fibonacci(15))\n\nprint_sep()\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/juanmax2.py",
    "content": "\"\"\"\nFuncion recursiva que va del 100 al 0\n\"\"\"\n\ndef recursiva(n):\n    if n == 0:\n        print(n)\n        \n    else:\n        print(n)\n        recursiva(n - 1)\n        \n\nrecursiva(100)\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\n\"\"\"\n\nprint(\"------------------\")\nprint(\"------------------\")\n\n# Factorial\ndef factorial(n):\n    if n == 0:\n        return 1\n    else:\n        return n * factorial(n-1)\n\nprint(factorial(5))\n\nprint(\"------------------\")\nprint(\"------------------\")\n\n\n# Fibonacci\n\ndef fibonacci(n):\n    if n == 0:\n        return 0\n    elif n == 1:\n        return 1\n    else:\n        return fibonacci(n - 1) + fibonacci(n -2)\n    \nprint(fibonacci(10))"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/juanppdev.py",
    "content": "def recursividad(number: int):\n    if number >= 0:\n        print(number)\n        recursividad(number - 1)\n\nrecursividad(100)\n\ndef factorial(number: int) -> int:\n    \"\"\"Calcula el factorial de un número entero\"\"\"\n    if number == 0 or number == 1:\n        return 1\n    else:\n        return number * factorial(number - 1)\n\n\nprint(factorial(5))"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/juserdev.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */ \"\"\"\n\n\ndef my_func(n):\n  print(n)\n  if n > 0:\n    my_func(n -1)\n\n# my_func(100)\n\ndef factorial(n):\n  if n == 0: return 1\n  return n * factorial(n - 1)\n\nprint(factorial(7))\n\ndef fibonacci(n):\n  if n == 0: return 0\n  if n == 1: return 1\n  return fibonacci(n - 1) + fibonacci(n - 2)\n\nprint(fibonacci(6))"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/k-90.py",
    "content": "\"\"\"\"\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n \"\"\"\n\ndef func_recur(number:int):\n    if number >= 0:\n        print(number)\n        func_recur(number -1)\n    \nprint(func_recur(100))    \n\n### Extra\n\ndef factorial (number):\n    r = 1\n    i = 2 \n    while i <= number:\n        r *= i\n        i += 1\n    return r\nprint(factorial(5))\n\ndef factorial_recursivo(n):\n    if n == 1:\n        return 1\n    else:\n        return n * factorial_recursivo(n-1)\n\nprint(factorial_recursivo(5))\n\ndef fib_recur(n):\n    if n == 0:\n        return 0\n    elif n == 1:\n        return 1\n    else:\n        return fib_recur(n-1) + fib_recur(n-2)\n\nprint(fib_recur(7))"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/keltoi-dev.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n\"\"\"\n\n\ndef cuenta_regresiva(num):\n    if num >= 1:\n        print(num, end=\"-\")\n        return cuenta_regresiva(num - 1)\n    else:\n        print(num)\n\n\nprint(\"Cuenta regresiva de 100 a 0\")\ncuenta_regresiva(100)\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n\"\"\"\nprint(\"\\n\")\n\n\ndef calculo_factorial(num1):\n    if num1 <= 1:\n        return num1\n    else:\n        return num1 * calculo_factorial(num1 - 1)\n\n\ndef calculo_fibonacci(num2):\n    if num2 <= 1:\n        return num2\n    else:\n        return calculo_fibonacci(num2 - 1) + calculo_fibonacci(num2 - 2)\n\n\nprint(\"El factorial del numero 6 es:\", calculo_factorial(6))\nprint(\"\\n\")\nprint(\"El valor de la sucecion de Fibonacci en la posicion 8 es:\", calculo_fibonacci(8))\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/kenysdev.py",
    "content": "# ╔══════════════════════════════════════╗\n# ║ Autor:  Kenys Alvarado               ║\n# ║ GitHub: https://github.com/Kenysdev  ║\n# ║ 2024 -  Python                       ║\n# ╚══════════════════════════════════════╝\n\n# -------------\n# Recursividad:\n# -------------\n# - La recursividad es la capacidad de una función para llamarse a sí misma,ya sea \n#   de forma directa o indirecta, con el propósito de resolver un problema.\n# _________________________________\n# imprimiendo números del 100 al 0.\n# Ejemplo con recursividad directa:\n# ocurre cuando una función se llama a sí misma.\ndef num(n: int):\n    print(n)\n    # caso base\n    if n > 0: # evitar que la función se llame indefinidamente.\n        num(n - 1)\nnum(100)\n\n# Ejemplo con recursividad indirecta:\n# implica que varias funciones se llamen entre sí.\ndef resta(n: int):\n    write(n - 1)\n\ndef write(n: int):\n    print(n)\n    # caso base\n    if n > 0:\n        resta(n)\n\nwrite(100)\n\n# -----------\n# Ejercicios:\n# -----------\n# Calcular el factorial de un número concreto (la función recibe ese número).\n# 4! = 4 * 3 * 2 * 1 = 24\ndef factorial(n: int) -> int:\n    if n != 0: \n        return n * factorial(n - 1)\n    else: \n        return 1\n    # explicación\n    '''\n    fac(4)\n        | = 24 \n     return 4 * fac(3) ->(4 * 6)\n                  | = 6 \n         return 3 * fac(2) ->(3 * 2)\n                      | = 2 \n             return 2 * fac(1) ->(2 * 1)\n                          | = 1 \n                 return 1 * fac(0) ->(1 * 1)\n                              | = return 1 -> caso base\n    '''\n\n# -Calcular el valor de un elemento concreto (según su posición) en la \n#  sucesión de Fibonacci (la función recibe la posición).\n# n : |0|1|2|3|4|5|6|..\n# fb: |0|1|1|2|3|5|8|..\n#      |+|=^   |+|=^ ..\ndef fibonacci(n: int) -> int:\n    if n <= 1: \n        return n\n    else:\n        return fibonacci(n - 1) + fibonacci(n - 2)\n        # explicación\n        '''\n                            return 3\n                  fib(3)      / \\    fib(2)\n                   / \\ =2      +      / \\ =1\n             fib(2) + fib(1)    fib(1) + fib(0) -> caso base\n              / \\ =1\n        fib(1) + fib(0) -> caso base\n        '''\n# NOTE: Este enfoque recursivo puede ser ineficiente para valores grandes de \"n\".\n#___________________________________\nprint(f\"\"\"\nFactorial de 4: \n{factorial(4)}\nValor según posición 4 en Fibonacci:\n{fibonacci(4)}\n\"\"\")\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/kodenook.py",
    "content": "\ndef recursion(number: int) -> None:\n    \"\"\"\n    The function `recursion` in Python prints numbers from the input number down to 0 using recursion.\n\n    :param number: The `recursion` function takes an integer `number` as a parameter. The function will\n    print the value of `number` and then recursively call itself with `number-1` until `number` is\n    greater than 0\n    :type number: int\n    \"\"\"\n    print(f'{number}')\n    if number > 0 :\n        recursion(number-1)\n\nrecursion(100)\n\n\"\"\"\n    Exercise\n\"\"\"\n\ndef factorial(number: int, result: int = 1) -> None:\n    \"\"\"\n    The function calculates the factorial of a given number recursively.\n\n    :param number: The `number` parameter in the `factorial` function represents the integer for which\n    you want to calculate the factorial. It is the input number for which the factorial will be computed\n    :type number: int\n    :param result: The `result` parameter in the `factorial` function is used to keep track of the\n    intermediate result of the factorial calculation as the function recursively calls itself. It starts\n    with a default value of 1 and gets updated as the function progresses through the recursive calls,\n    defaults to 1\n    :type result: int (optional)\n    \"\"\"\n    if number > 1 :\n        factorial(number-1, result*number)\n    else:\n        print(f'{result}')\n\nfactorial(5)\n\ndef fibonacci(position: int) -> int:\n    \"\"\"\n    This Python function calculates the Fibonacci number at a given position using recursion.\n\n    :param position: The `position` parameter in the `fibonacci` function represents the position of the\n    Fibonacci number in the sequence that you want to calculate. For example, if `position` is 5, the\n    function will return the 5th Fibonacci number in the sequence\n    :type position: int\n    :return: the value of the Fibonacci sequence at the specified position.\n    \"\"\"\n    if position > 2:\n        return fibonacci(position-1)+fibonacci(position-2)\n    else:\n        return 1\n\nprint(fibonacci(7))"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/kuroz00.py",
    "content": "#Funcion recursiva\ndef funcion_recursiva(numero_ingresado):\n    numero_ingresado -= 1\n    if numero_ingresado >= 0:\n        print(numero_ingresado)\n        funcion_recursiva(numero_ingresado) #recursividad de la funcion(que se llame a si misma)\n    else:\n        print('Fin de la cuenta regresiva.')\nfuncion_recursiva(101)\n\n'''Dificultad extra.-.-.-.-'''\n#Factorial con funcion recursiva\ndef factorial(numero): \n    if numero > 1: \n        numero = numero * factorial(numero -1)\n    return numero\nprint('factorial:', factorial(5)) \n\n#Calcular el valor de un elemento concreto (según su posición) en la \n# sucesión de Fibonacci '''\ndef fibo (num):\n    if num < 2:\n        return num\n    else: \n        return fibo(num -1) + fibo(num -2)\nprint('fibo:', fibo(10)) #55\n#0 1 1 2 3 5  8\n#1 2 3 4 5 6  7 TE QUIERU MUCHITU DADDU :3\n        "
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/lesterdavid31.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\"\"\"\n\n# def imprimirNumeros(n):\n#     if n < 0:\n#         return \n#     print(n)\n#     imprimirNumeros(n-1)\n\n# imprimirNumeros(100)\n\ndef factorial(n):\n    if n == 0:\n        return 1\n    else:\n        return n * factorial(n-1)\n        \nprint(f'El factorial del numero es: {factorial(5)}')\n\n\ndef fibonacci(number: int):\n    if number <= 0:\n        print('La posición tiene que ser mayor que cero')\n        return 0\n    elif number == 1:\n        return 0\n    elif number == 2:\n        return 1\n    else:\n        return fibonacci(number -1) + (fibonacci(number -2))\n    \nprint(f'la posicisión del número es: {fibonacci(10)}')\n    \n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/linerlander.py",
    "content": "\"\"\"\nEjercicio de Recursividad\n\"\"\"\ndef countdown(num: int):\n    if num >= 0: # Condicional que indica hasta que valor asumira num\n        print(num)\n        countdown(num -1)\n\ncountdown(100)\n\n\"\"\"\nExtra\n\"\"\"\n\ndef factorial_number(num: int)-> int:\n    if num < 0:\n        print('Los números negativos no son válidos')\n        return 0\n    elif num == 0:\n        return 1\n    else:\n        return num * factorial_number(num - 1)\nprint(factorial_number(5))\n\ndef fibonacci_position(number: int)-> int:\n    if number <= 0:\n        print('Los posición tiene que ser mayor a 0')\n        return 0\n    elif number == 1:\n        return 0\n    elif number == 2:\n        return 1\n    else:\n        return fibonacci_position(number - 1) + fibonacci_position(number - 2)\n\nprint(fibonacci_position(10))\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/m1l0j05.py",
    "content": "\n# Teoría:\n\n#  La recursividad es un concepto fundamental en la programación que se refiere a la capacidad de una función\n#  para llamarse a sí misma dentro de su propia definición. Funciona permitiendo que un problema se divida en \n#  subproblemas más pequeños de la misma naturaleza, facilitando su solución de manera más sencilla y directa. \n#  La recursividad es especialmente útil en tareas que pueden ser descompuestas en tareas más simples de la \n#  misma índole, como los problemas de búsqueda y ordenamiento, el cálculo de factorial, la generación de \n#  secuencias y el procesamiento de estructuras de datos recursivas (como árboles y grafos).\n\n# Para que una función recursiva funcione correctamente y no entre en un bucle infinito, debe tener:\n# 1.Caso base:\n#  Una condición que detiene la recursión. Es el escenario más simple que no requiere recursividad para resolverse.\n# 2.Caso recursivo: \n# La llamada a sí misma con diferentes argumentos, acercándose al caso base.\n\n### Ejemplo: Búsqueda Binaria\n# La búsqueda binaria es un algoritmo eficiente para encontrar un elemento en una lista ordenada. Funciona dividiendo \n# repetidamente a la mitad la porción de la lista que podría contener al elemento, hasta que queda reducida a un solo \n# elemento.\n\ndef binary_search(arr, low, high, x):\n    if high >= low:\n        mid = (high + low) // 2\n\n        # Si el elemento es el punto medio\n        if arr[mid] == x:\n            return mid\n        \n        # Si el elemento es más pequeño que el medio, entonces solo puede\n        # estar presente en el subarreglo izquierdo\n        elif arr[mid] > x:\n            return binary_search(arr, low, mid - 1, x)\n        \n        # De lo contrario, el elemento solo puede estar presente\n        # en el subarreglo derecho\n        else:\n            return binary_search(arr, mid + 1, high, x)\n\n    else:\n        # El elemento no está presente en el arreglo\n        return -1\n\n# Ejercicio\n\ndef print_numbers(n):\n    if n == 0:\n        return print(n)\n    else:\n        print(n)\n        return print_numbers(n - 1)\n\nprint_numbers(100)\n\n# Ejercicios Extra\n\n# Factorial de un Número\n# El factorial de un número `n` (denotado como `n!`) es el producto de todos los números positivos menores o iguales a \n# `n`. Por definición, `0! = 1`.\n\ndef factorial(n):\n    if n == 0:\n        return 1  # Caso base\n    else:\n        return n * factorial(n - 1)  # Caso recursivo\n\n# Fibonacci\n# La secuencia de Fibonacci es una secuencia de números donde cada número es la suma de los dos anteriores, empezando \n# con 0 y 1. Es decir, Fib(0) = 0, Fib(1) = 1, y Fib(n) = Fib(n-1) + Fib(n-2) para n > 1.\n\ndef fibonacci(n):\n    if n == 0:\n        return 0  # Caso base 1\n    elif n == 1:\n        return 1  # Caso base 2\n    else:\n        return fibonacci(n-1) + fibonacci(n-2)  # Caso recursivo\n\n\nmyFactorialNumber = factorial(15)\nprint(myFactorialNumber)\nmyFiboNumber = fibonacci(15)\nprint(myFiboNumber)\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/majinka10.py",
    "content": "inicial = 100\ndef cientozero(inicial):\n    if inicial >= 0:\n        print(inicial)\n        cientozero(inicial-1)\n        \ncientozero(inicial)\n\n# Ejercicio EXTRA\n\nprint(\"Ejercicio EXTRA\")\n\ndef factorial(numero: int) -> int:\n    if numero < 0:\n        print(\"El número debe ser mayor o igual que cero.\")\n        return 0\n    elif numero == 0:\n        return 1\n    else:\n        return numero*factorial(numero-1)\n\nprint(f\"Factorial: {factorial(5)}\")\n\ndef fibonacci(posicion:int) -> int:\n    if posicion <= 0:\n        print(\"La posición debe ser mayor a cero.\")\n        return 0\n    elif posicion == 1:\n        return 0\n    elif posicion == 2:\n        return 1\n    else:\n        return fibonacci(posicion-1) + fibonacci(posicion-2)\n    \nprint(f\"Fibonacci: {fibonacci(5)}\")"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/manjaitan.py",
    "content": "# * EJERCICIO:\n# Entiende el concepto de recursividad creando una función recursiva que imprima\n# números del 100 al 0.\n\ndef imprimir(n):\n    while (n != -1):\n        print (n)\n        n = n - 1\n        \nimprimir(100)"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/mariovelascodev.py",
    "content": "def recursividad(num):\n    #Si el número introducido es mayor o igual a cero, se imprime y volvemos a llamar a la función restando 1 al nuúmero del parámetro\n    if num >= 0:\n        print(num)\n        recursividad(num - 1)\n        \nrecursividad(100)\n\n#EXTRA\n#Factorial\ndef factorial(num):\n    #Si num es igual a 0 o 1 la función devuelve 1\n    if num == 0 or num == 1:\n        result = 1\n    #Si num es mayor que 1 hacemos que result sea igual al producto de dicho número por el resultado de aplicar la misma función menos 1\n    elif num > 1:\n        result = num * factorial(num - 1)\n    return result\n\nprint(factorial(5))  \n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/mauricioobgo.py",
    "content": "\"\"\"\nEntendiendo el concepto\n\n\"\"\"\ndef count_down(number : int):\n    if number < 0 :\n        return\n    print(number,sep='')\n    count_down(number-1)\n\n#count_down(10)\n\n\"\"\"\nFactorial Calculation\n\n\"\"\"\ndef factorial(number: int, fact=1) -> int:\n    if number <= 1:\n        return fact\n    return factorial(number - 1, fact * number)\n\n#print(factorial(3))\n\n\"\"\"\nNth Fibonacci number\n\"\"\"\ndef fibonacci(n_fib :  int, fib1=0, fib2=1):\n    if n_fib == 0:\n        return fib1\n    elif n_fib == 1:\n        return fib2\n    else:\n        return fibonacci(n_fib - 1, fib2, fib1 + fib2)\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/maxiRica.py",
    "content": "import os\nimport textwrap\n\ndef limpiar(): #creamos la función para limpiar la pantalla para poder aplicarla las veces que necesitemos sin repetir código\n    while True:\n\n        pregunta=input(\"quieres que limpie la pantalla? (si - no): \")\n        if pregunta==\"si\":\n        \n            if os.name==\"posix\":\n                os.system(\"clear\")\n                break\n            else:\n                os.system(\"cls\")\n                break\n        elif pregunta==\"no\":\n            break\n\n\"\"\"\nEJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n\"\"\"\nlimpiar()\n\ndef recursividad(a=100):\n    if a<0:\n        return\n    else:\n        print(a)\n        recursividad(a-1)\n\nrecursividad()\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n\"\"\"\nlimpiar()\n\n# FACTORIAL\ndef factorial_(valor):\n    if valor == 0:\n       \n       return 1\n    else:\n        fact=1\n        for i in range(valor,0,-1):\n            fact=fact*i\n        return fact\n\nprint(\"\\n\\nVAMOS A CALCULAR EL FACTORIAL\\n\")\nvalor=input(\"introduce un número: \")\nvalor=int(valor)\nprint(factorial_(valor))\n\n# POSICIÓN DE FIBO\n\ndef fibo(valor):\n    if valor == 0:\n        return 0\n    elif valor == 1:\n        return 1\n    else: \n        fibonacci=[0,1]\n        for i in range(2,valor+1):\n            calculo=fibonacci[i-1]+fibonacci[i-2]\n            fibonacci.append(calculo)\n    print(fibonacci[valor])\n\nprint(\"\\n\\nVAMOS A CALCULAR EL FIBONACCI SEGÚN POSICIÓN\\n\")\nvalor=int(input(\"dame el valor de la posición de fibo: \\n\"))\nfibo(valor)\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/mensius87.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la\n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\"\"\"\n\n\n# Función recursiva que hace una cuenta atrás de 100 a 1\ndef cuenta_atras_recursiva(n):\n    if n >= 0:\n        print(n)\n        cuenta_atras_recursiva(n-1)\n\n\ncuenta_atras_recursiva(100)\n\nprint()\nprint(\"::::::::::::::::::::::::::::::::::::: EXTRA :::::::::::::::::::::::::::::::::::::\")\nprint()\n\n\n# Calcular el factorial de un número concreto (la función recibe ese número).\ndef factorial(num):\n    if num == 0:\n        return 1\n    else:\n        return num * factorial(num-1)\n\n\n\nprint(factorial(5))\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/mhayhem.py",
    "content": "# Entiende el concepto de recursividad creando una función recursiva que imprima\n# números del 100 al 0.\n\ndef countdown(n):\n    if n < 0:\n        pass\n    else:\n        print(n)\n        countdown(n - 1)\ncountdown(100)\n\n# DIFICULTAD EXTRA (opcional):\n# Utiliza el concepto de recursividad para:\n# - Calcular el factorial de un número concreto (la función recibe ese número).\n# - Calcular el valor de un elemento concreto (según su posición) en la \n#   sucesión de Fibonacci (la función recibe la posición).\n\ndef factorial(n):\n    if n == 0 or n == 1:\n        return 1\n    else:\n        return n * factorial(n-1)\n        \nprint(factorial(9))\n\ndef fibonacci(n):\n    if n == 0:\n        return 0\n    if n == 1: \n        return 1\n    else:\n        return fibonacci(n-1) + fibonacci(n-2)\n    \nprint(fibonacci(25))"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/miguelex.py",
    "content": "def sumaRecursiva (a,b):\n    if b == 0:\n        return a\n    else:\n        return sumaRecursiva(a+1,b-1)\n\nprint(\"Suma recursiva de 5 y 3: \")\nprint(sumaRecursiva(5,3))\n\ndef potenciaRecursiva(a,b):\n    if b == 0:\n        return 1\n    else:\n        return a * potenciaRecursiva(a,b-1)\n\nprint(\"Potencia recursiva de 2^3: \")\nprint(potenciaRecursiva(2,3))\n\ndef imprimir_numeros(numero):\n    if numero >= 0:\n        print(numero, end=\" \")\n        imprimir_numeros(numero - 1)\n\nprint(\"De 100 a 0 usando rercursividad: \")\nimprimir_numeros(100)\nprint();\n\n# Extra\ndef factorial(n):\n    if n == 0:\n        return 1\n    else:\n        return n * factorial(n-1)\n    \nprint(\"Factorial de 5: \")\nprint(factorial(5))\n\ndef fibonacci(n):\n    if n == 0:\n        return 0\n    elif n == 1:\n        return 1\n    else:\n        return fibonacci(n-1) + fibonacci(n-2)\n    \nprint(\"Fibonacci de 5: \")\nprint(fibonacci(5))\n\nprint(\"Vamos a comprobar ahora las funciones de factorial y fibonacci de forma interactiva\")\n\nprint(\"Introduce un número para calcular su factorial: \")\nn = int(input())\nprint(factorial(n))\n\nprint(\"Introduce un número para calcular su fibonacci: \")\nn = int(input())\nprint(fibonacci(n))\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/mikelm2020.py",
    "content": "# Recursividad\n# Crea una función recursiva que imprima números del 100 al 0\n\n\ndef numbers(number: int = 100):\n    if number >= 0:\n        print(number)\n        numbers(number - 1)\n\n\n# Dificultad extra\n# Utiliza el concepto de recursividad para:\n# Calcular el factorial de un número concreto (la funcion recibe ese número)\n\n\ndef factorial(number: int):\n    if number == 1:\n        return 1\n\n    if number >= 2:\n        return number * factorial(number - 1)\n\n\n# Calcular el valor de un elemento concreto (según su posición) en la\n# sucesión de Fibonacci (la función recibe la posición).\n\n\ndef fibonacci(position: int):\n    if position == 0:\n        return 0\n    if position == 1:\n        return 1\n    if position >= 2:\n        return fibonacci(position - 2) + fibonacci(position - 1)\n\n\nif __name__ == \"__main__\":\n    # numbers()\n    print(factorial(5))\n    print(fibonacci(15))\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/monicavaquerano.py",
    "content": "# 06 RECURSIVIDAD\n# Mónica Vaquerano\n# https://monicavaquerano.dev\n\n\"\"\"\nEJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n */\n\"\"\"\n\n\ndef printNumbers(n: int):\n    if n < 0:\n        return\n    else:\n        print(n, end=\" \")\n        printNumbers(n - 1)\n\n\nprint(\"Recursividad\\n\")\nprint(\"Cuenta regresiva de 100 a 0\")\nprintNumbers(100)\nprint()\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\"\"\"\nprint(\"\\nDIFICULTAD EXTRA (opcional):\\n\")\n\n\ndef factorial(n: int) -> int:\n    if n <= 1:\n        return 1\n    else:\n        return n * factorial(n - 1)\n\n\nprint(\"Factorial de un número\")\ncinco = factorial(5)\nprint(f\"Factorial de 5 = {cinco}\")\n\n\n# 1, 2, 3, 4, 5, 6\n# 1, 1, 2, 3, 5, 8, ...\n\n\ndef fibonacci(n: int) -> int:\n    if n <= 1:\n        return n\n    else:\n        return fibonacci(n - 1) + fibonacci(n - 2)\n\n\nprint(\"\\nSecuencia Fibonacci:\")\nx = 6\nprint(f\"Valor de la posición N°{x} es {fibonacci(x)}\")\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/mordevspt.py",
    "content": "\"\"\"\nEntiende el concepto de recursividad creando una función recursiva que imprima números del 100 al 0.\n\"\"\"\n\n'''\nFunción de Recursividad en Python\n\nUna función recursiva en Python es una función que se llama a sí misma durante su ejecución. \nEsto permite dividir un problema complejo en subtareas más simples, \nhasta llegar a un caso base que se puede resolver directamente.\n\nVentajas y desventajas\n\n- Ventajas:\n\nSimplifica la implementación de algoritmos que requieren la repetición de operaciones similares.\nPuede ser más fácil de leer y entender que un bucle iterativo.\n\n- Desventajas:\n\nPuede ser menos eficiente que un bucle iterativo, ya que cada llamada a la función recursiva crea una nueva pila de ejecución.\nSe puede producir un error de “RecursionError” si la función se llama demasiadas veces, lo que puede causar un stack overflow.\n'''\n\nprint(\"\\nFUNCIÓN RECURSIVA\\n\")\n\ndef descent(value:int):\n    if value >= 0:\n        print(value)\n        descent(value - 1)\n\nmi_int = 100\ndescent(mi_int)\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n Utiliza el concepto de recursividad para:\n - Calcular el factorial de un número concreto (la función recibe ese número).\n - Calcular el valor de un elemento concreto (según su posición) en la sucesión de Fibonacci (la función recibe la posición).\n\"\"\"\n\nprint(\"\\nFUNCIÓN FACTORIAL\\n\")\n\n'''\nFunción factorial\nLa función factorial, representada por el símbolo !, es una fórmula matemática que se utiliza para calcular el producto de todos los números enteros positivos desde 1 hasta un número dado n. Se expresa como n!, donde n es el número del que se calcula el factorial.\n\nEjemplo\n5! = 5 × 4 × 3 × 2 × 1 = 120\n'''\n\ndef factorial(number:int):\n    # Evitamos los número negativos\n    if number < 0:\n        print(\"Facilite un número positivo para el cálculo.\")\n        return 0\n    elif number == 0:\n        return 1\n    else:\n        # Al tener la función en el cálculo se consigue crear esa recrsividad restando al número hasta que no se cumple la condición\n        return number * factorial(number - 1)\n\nmi_factorial = 5 \nprint(factorial(mi_factorial))\n\nprint(\"\\nFUNCIÓN FIBONACCI\\n\")\n\n'''\nLa función de Fibonacci es una sucesión infinita de números naturales que se define recursivamente como:\n\nF(n) = F(n-1) + F(n-2)\n\nDonde F(0) = 0 y F(1) = 1.\n'''\n\ndef fibonacci(number:int):\n    # Evitamos los número negativos\n    if number < 0:\n        print(\"Facilite una posición en positivo\")\n        return 0\n    # Los primeros números no son tan exactos por eso se ponen a fuego\n    elif number == 0 or number == 1:\n        return 0\n    elif number == 2:\n        return 1\n    # Resto de números superiores o iguales a 3\n    else:\n        # Aplicamos la función de la explicación\n        return fibonacci(number-1) + fibonacci(number-2)\n    \nmi_fibonacci = 10\nprint(fibonacci(mi_fibonacci))\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/mouredev.py",
    "content": "\"\"\"\nEjercicio\n\"\"\"\n\n\ndef countdown(number: int):\n    if number >= 0:\n        print(number)\n        countdown(number - 1)\n\n\ncountdown(100)\n\n\"\"\"\nExtra\n\"\"\"\n\n\ndef factorial(number: int) -> int:\n    if number < 0:\n        print(\"Los números negativos no son válidos\")\n        return 0\n    elif number == 0:\n        return 1\n    else:\n        return number * factorial(number - 1)\n\n\nprint(factorial(5))\n\n\ndef fibonacci(number: int) -> int:\n    if number <= 0:\n        print(\"La posición tiene que ser mayor que cero\")\n        return 0\n    elif number == 1:\n        return 0\n    elif number == 2:\n        return 1\n    else:\n        return fibonacci(number - 1) + fibonacci(number - 2)\n\n\nprint(fibonacci(5))\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/mrodara.py",
    "content": "################ Recursividad ###################\n'''\nDecimos que una función es recursiva cuando dentro de la función se llama a si misma\nPara hacer que sea recursiva debemos tener un caso base que hará finalizar el bucle de llamadas.\n'''\n\ndef countdown(number: int = 100):\n    if number == 0:\n        print(0)\n    else:\n        print(number)\n        countdown(number=number-1)\n        \ncountdown(100)\n\n\n#####################  EXTRA  ################################\n\n#Calcular el factorial de un número\ndef factorial(number: int) -> int:\n    if number == 0 or number == 1:\n        return 1\n    else:\n        return number * factorial(number=number-1)\n\nprint(factorial(6))\n\n# Calcular valor de un elemento según su posición en la sucesión de Fibonacci\n\n\ndef calcular_valor_fibonacci(position: int) -> int:    \n    \n    if position == 1:\n        return 0\n    elif position == 2:\n        return 1\n    else:        \n        return calcular_valor_fibonacci(position=position-1) + calcular_valor_fibonacci(position=position-2) \n\nprint(calcular_valor_fibonacci(7))\n#####################  FIN EXTRA  ################################"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/mvidalb.py",
    "content": "'''\nEjercicio Recursividad\n'''\n\ndef countdown(number : int):\n    if number >= 0:\n        print(number)\n        countdown(number - 1)\n\ncountdown(100)\n\n'''\nEjercicio extra\n'''\n\ndef factorial(number : int) -> int:\n    if number < 0:\n        print(\"Números negativos no válidos\")\n        return 0\n    elif number == 0:\n        return 1\n    else:\n        return number * factorial(number - 1)\n\nprint(factorial(5))\n\n\ndef fibonacci(posicion) -> int:\n    \n    if posicion <= 0:\n        print(\"Posición tiene que ser mayor que 0\")\n        return 0\n    elif posicion == 1:\n        return 0\n    elif posicion == 2:\n        return 1\n    else:\n        return fibonacci(posicion-1) + fibonacci(posicion - 2)\n\nprint(\"Fibonacci!\")\nprint(fibonacci(1))\nprint(fibonacci(2))\nprint(fibonacci(3))\nprint(fibonacci(4))\nprint(fibonacci(5))\n\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/neslarra.py",
    "content": "\"\"\"\n EJERCICIO:\n Entiende el concepto de recursividad creando una función recursiva que imprima\n números del 100 al 0.\n\n DIFICULTAD EXTRA (opcional):\n Utiliza el concepto de recursividad para:\n - Calcular el factorial de un número concreto (la función recibe ese número).\n - Calcular el valor de un elemento concreto (según su posición) en la \n   sucesión de Fibonacci (la función recibe la posición).\n\"\"\"\n\n\ndef imprime_countdown(entero=100) -> int:\n    if entero == 0:\n        print(entero, end=\"\\n\")\n        return entero\n    print(entero, end=\" - \")\n    return imprime_countdown(entero - 1)\n\n\nprint(f\"\"\"\nCuando para llegar a un resultado determinado se debe repetir el mismo proceso n cantidad de veces, entonces allí se aplica la recursividad: un proceso\nque hace una tarea con la capacidad de autollamarse para procesar hasta lleagr al valor de corte.\n\ndef imprime_countdown(entero=100) -> int:\n    if entero == 0:\n        print(entero, end=\"\"\" + '\"\\\\n\"' + \"\"\")\n        return entero\n    print(entero, end=\" - \")\n    return imprime_countdown(entero - 1)\n    \nimprime_countdown() =>\"\"\")\nimprime_countdown()\nprint(f\"\"\"\nimprime_countdown(50) =>\"\"\")\nimprime_countdown(50)\nprint(f\"\"\"\nimprime_countdown(10) =>\"\"\")\nimprime_countdown(10)\n\n# Dificultad extra\n\n\ndef calcular_factorial(entero: int) -> int:\n    if entero == 1:\n        return 1\n    else:\n        return entero * calcular_factorial(entero - 1)\n\n\ndef calcular_fibonacci(entero: int) -> int:\n    if entero == 0:\n        return 0\n    elif entero == 1:\n        return 1\n    else:\n        return calcular_fibonacci(entero - 1) + calcular_fibonacci(entero - 2)\n\n\ndef cuantas_horas(segundos: int, horas=0, minutos=0):\n    if segundos >= 3600:\n        horas += segundos // 3600\n        segundos -= horas * 3600\n    elif 3600 > segundos >= 60:\n        minutos += segundos // 60\n        segundos -= minutos * 60\n    elif segundos < 60:\n        return f\"{horas} horas, {minutos} minutos y {segundos} segundos.\"\n\n    return cuantas_horas(segundos, horas, minutos)\n\n\nprint(f\"\"\"\nEjemplos de uso de recursividad: calculo de factorial, buscar pocisiones en la serie de Fibonacci o calcular cuantas horas son n segundos:\n\"\"\")\n\nprint(f\"El factorial de 5 es {calcular_factorial(5)}\")\nprint(f\"La décima posición en la serie de Fibonacci es {calcular_fibonacci(10)}\")\nprint(f\"9378 segundos son {cuantas_horas(9378)}\")\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/nlarrea.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n\"\"\"\n\n\ndef print_number(number: int) -> None:\n    print(number)\n\n    if number == 0:\n        return\n\n    print_number(number - 1)\n\n\nprint_number(100)\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n\"\"\"\n\n\ndef factorial(number: int) -> int:\n    if number < 0:\n        print(\"Number must be a positive number.\")\n        return -1\n    elif number == 0:\n        return 1\n\n    return number * factorial(number - 1)\n\n\nprint(\"\\nFactorial:\")\nnumber = 4\nprint(f\"{number}! = {factorial(number)}\")  # 24\nprint(f\"{number + 1}! = {factorial(number + 1)}\")  # 120\n\n\ndef fibonacci(position: int) -> int:\n    if position <= 0:\n        print(\"Only positive numbers are allowed.\")\n        return -1\n    elif position == 1:\n        return 0\n    elif position == 2:\n        return 1\n\n    return fibonacci(position - 1) + fibonacci(position - 2)\n\n\nprint(\"\\nFibonacci:\")\nprint(f\"The Fibonacci in position 3 is: {fibonacci(3)}\")  # 1\nprint(f\"The Fibonacci in position 7 is: {fibonacci(7)}\")  # 8\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/oniricoh.py",
    "content": "########################################################################\n## Recursividad del 100 al 0\n########################################################################\ndef number_counter(max:int=100) ->int:\n    if max == 0:\n        return 0\n    else:\n        print(max)\n        return number_counter(max - 1)\n\n#resultado = number_counter()\n\n\n\n########################################################################\n## DIFICUTAD EXTRA\n########################################################################\n\ndef factorial(n:int)->int:\n    \"\"\"\n    Calcula el factorial de un numero\n    \"\"\"\n    if n == 0 or n == 1:\n        return 1\n    else:\n        return n * factorial(n-1)\n    \nprint(factorial(5))\n\n########################################################################\n\ndef fibonacci_sequence(pos1=0, pos2=1, numbers=[0,1], max=20):\n    \"\"\"\n    Función recursiva para calcular el valor en la sucesión de Fibonacci\n    \"\"\"\n    if len(numbers) >= max:\n        print(numbers)\n    else:\n        suma = numbers[pos1] + numbers[pos2]\n        numbers.append(suma)    \n        return fibonacci_sequence(pos1+1, pos2+1)\n\nfibonacci_sequence()\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/oriaj3.py",
    "content": "\"\"\"\t\n06 - RECURSIVIDAD\t\nAutor de la solución: Oriaj3\t\nTeoría:\t\nLas funciones recursivas son aquellas que se llaman a sí mismas. Son útiles para resolver problemas que pueden ser descompuestos en subproblemas más pequeños,\t\ny que se resuelven de forma similar. La recursividad es una forma de iteración, y puede ser más sencilla de entender y de implementar en algunos casos.\t\n#El factorial de un número n se define como el producto de todos los números enteros positivos desde 1 hasta n. \t\nn! = 1 * 2 * 3 * ... * n\t\n#La sucesión de Fibonacci es una sucesión infinita de números naturales, que comienza con los números 0 y 1, y a partir de ellos, cada término es la suma de los dos anteriores.\t\n0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ...\t\nRecuerda:\t\nNonlocal: Permite modificar variables no locales en una función anidada.\t\nGlobal: Permite modificar variables globales en una función.\t\nPor defecto, las variables en Python son locales, a menos que se especifique lo contrario, por tanto dentro de una función no se puede modificar una variable que esta afuera.\t\n\"\"\"\t\n\n\"\"\"\t\n * EJERCICIO:\t\n * Entiende el concepto de recursividad creando una función recursiva que imprima\t\n * números del 100 al 0.\t\n\"\"\"\t\n# ejercicio 1 variable global\t\nindice = 0\t\ndef recursiva():\t\n    global indice\t\n    print(indice)\t\n    indice += 1 \t\n    if indice<101:\t\n        recursiva()\t\nrecursiva()\t\n\n# ejercicio 1 con parametro\t\ndef recursiva1(indice):\t\n    print(indice)\t\n    indice += 1 \t\n    if indice<101:\t\n        recursiva1(indice)\t\nnumber = 0 \t\nrecursiva1(number)\t\n\n# ejercicio 1 nonlocal\t\ndef recursiva2():\t\n    indice = 0\t\n    def interna():\t\n        nonlocal indice\t\n        print(indice)\t\n        indice += 1 \t\n        if indice<101:\t\n            interna()\t\n    interna()\t\n\nrecursiva2()\t\n\n\"\"\"\"\t\n* DIFICULTAD EXTRA (opcional):\t\n * Utiliza el concepto de recursividad para:\t\n * - Calcular el factorial de un número concreto (la función recibe ese número).\t\n * - Calcular el valor de un elemento concreto (según su posición) en la \t\n *   sucesión de Fibonacci (la función recibe la posición).\t\n\"\"\"\t\n# Factorial\t\n# Se usa indice y resultado como variables no locales para guardar el avance de la recursividad\t\ndef factorial(num: int)-> int:\t\n    indice = 0\t\n    resultado = 1\t\n    def interna():\t\n        nonlocal indice\t\n        nonlocal resultado\t\n        indice += 1 \t\n        if indice<=num:\t\n            resultado *= indice\t\n            interna()\t\n    interna()\t\n    return resultado\t\n\n# Factoriales del 0 al 9:\t\nfor i in range(10):\t\n    print(f\"El factorial de {i} es igual a {factorial(i)}.\")\t\n\n# Calcula la sucesion de fibonacci hasta n\t\n# lista es una lista dónde se guardan los valores de la sucesión\t\n# n_2, n_1 y n son los tres últimos valores de la sucesión, siendo n el actual, n_1 el anterior y n_2 el anterior a n_1\t\ndef fibonacci_hasta(posicion: int)-> list:\t\n    lista = []\t\n    n_2 = 0 \t\n    n_1 = 1\t\n    n = 0\t\n    if posicion==0:\t\n        return None\t\n    for i in range(0, posicion):\t\n        lista.append(n)\t\n        n_2 = n_1\t\n        n_1 = n \t\n        n = n_1 + n_2\t\n    return lista\t\n# Calcula el valor de la sucesión de fibonacci en la posición n\t\n# n_2, n_1 y n son los tres últimos valores de la sucesión, siendo n el actual, n_1 el anterior y n_2 el anterior a n_1\t\n# index es el índice actual de la sucesión por la que va la recursividad\t\n# La función interna() se llama a sí misma hasta que index sea igual a la posición deseada \t\n# y en cada llamada se actualizan los valores de n_2, n_1 y n para que se cumpla la sucesión\t\ndef fibonnaci_valor(posicion: int)-> int:\t\n    n_2 = 0\t\n    n_1 = 1\t\n    n = 0\t\n    index = 1\t\n    if(posicion==0):\t\n        return 0\t\n    def interna():\t\n        nonlocal n_2\t\n        nonlocal n_1\t\n        nonlocal n \t\n        nonlocal index\t\n        if index<=posicion:\t\n            n_2 = n_1\t\n            n_1 = n \t\n            n = n_1 + n_2\t\n            index+=1\t\n            interna()\t\n    interna()\t\n    return n\t\n\n\n\n# Fibonnaci del 0 al 9\t\nprint(f\"El fibonacci hasta {10} es igual a {fibonacci_hasta(11)}.\")\t\n\n\n# Fibonnaci del 0 al 9\t\nfor i in range(11):\t\n    print(f\"El fibonacci de {i} es igual a {fibonnaci_valor(i)}.\")\n\n# Corrección Factorial:\ndef factorial(number: int)-> int:\n    if number == 0:\n        return 1\n    elif number < 0:\n        print(\"No se puede calcular el factorial de un número negativo\")\n        return 0\n    else:\n        return number * factorial(number-1)\n\n#Ejemplo \nprint(factorial(5)) # 120\n\n# Corrección Fibonacci:\ndef fibonacci(number: int)-> int:\n    if number < 0: \n        print(\"No se puede calcular la sucesión de Fibonacci de un número negativo\")\n        return 0\n    elif number == 0:\n        return 0\n    elif number == 1:\n        return 1\n    else:\n        return fibonacci(number-1) + fibonacci(number-2) "
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/pakiuh.py",
    "content": "'''EJERCICIO:\r\nEntiende el concepto de recursividad creando una función recursiva que imprima\r\nnúmeros del 100 al 0.'''\r\n\r\ndef recursividad():\r\n    x = 100 #caso base\r\n    while x>0:\r\n        x = x - 1 #llamada recursiva\r\n        print(x)\r\n\r\nrecursividad()\r\n\r\n'''DIFICULTAD EXTRA (opcional):\r\nUtiliza el concepto de recursividad para:\r\n- Calcular el factorial de un número concreto (la función recibe ese número).\r\n- Calcular el valor de un elemento concreto (según su posición) en la \r\n  sucesión de Fibonacci (la función recibe la posición).'''\r\n\r\ndef calculo_factorial(posicion: int):\r\n    factorial = 1\r\n    while posicion > 1:#método con bucle while\r\n        factorial *= posicion\r\n        posicion -= 1\r\n        print(factorial)\r\n    \r\n    for i in range(posicion,0,-1):#método con bucle for\r\n        factorial *= i\r\n        print(factorial)\r\n\r\n\r\ncalculo_factorial(10)\r\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/pguillo02.py",
    "content": "#Función recursiva para contar hasta 100\n\ndef recursiva(n):\n\n    if n == 0:\n        print(n,\"final de la función recursiva\", sep = \" \" )\n    else:\n        print(n)\n        recursiva(n-1)\n\nrecursiva(100)\n\ndef factorial(n, x =1):\n\n    if n == 0:\n        print(\"Factorial = \", x)\n    else:\n        factorial(n-1, x*n)\n\nfactorial(4)\n\ndef fibonnacci(n):\n\n    if n == 1:\n        return 1\n    elif n == 2: \n        return 1\n    else:\n        return fibonnacci(n-1) + fibonnacci(n-2)\n    \nprint(fibonnacci(3))\n\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/pipngpop.py",
    "content": "\"\"\"\nRECURSIVIDAD -> función que se llama a ella  misma\n\"\"\"\n\n'''\ndef hello():\n    hello()\n\nhello()\n'''\n'''\ndef countdown (number: int):\n    if number >= 0:\n        print(number)\n        countdown(number-1)\n\ncountdown(100)\n'''\n'''\nEXTRA\n'''\n\"\"\"\n* Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n\"\"\"\n\n\n#Factorial\ndef factorial (num: int, fac:  int):\n    \n    if num > 0:\n        num, fac = factorial(num-1, fac*num)\n        \n    return num, fac\n\nfac=1\nwhile True:\n    num1 = int(input(\"\\nIntroduce un número positivo: \"))\n    if num1 <0:\n        print(\"\\nIntroduce un número positivo\")\n    else:\n        break\nnum, fac = factorial(num1, fac)\nprint(f\"\\nEl factorial de {num1} es {fac}\")\n\n\n\n#Fibonacci\ndef fibonacci (pos:  int, fib_a: int, fib_b: int, num: int):\n    if num < pos:\n        pos, fib_a, fib_b, num = fibonacci(pos, fib_b, fib_b+fib_a, num+1)\n        \n    return pos, fib_a, fib_b, num\n\nwhile True:\n    pos = int(input(\"\\nIntroduce una posición: \"))\n    if pos < 0:\n        print(\"\\nIntroduce un número positivo\")\n    else:\n        break\nfib_a = 0\nfib_b = 1\nnum = 0\npos, fib_a,fib_b, num = fibonacci(pos, fib_a, fib_b, num)\nprint(f\"\\nEl número {fib_a} corresponde a la posición {pos}\\n\")\n\n'''\nsu solución\n\ndef factorial(number: int) -> int:\n    if number < 0:\n        print(\"Los números negativos no son válidos\")\n        return 0\n    elif number == 0:\n        return 1\n    else:\n        return number * factorial(number - 1)\n\n\nprint(factorial(5))\n\n\ndef fibonacci(number: int) -> int:\n    if number <= 0:\n        print(\"La posición tiene que ser mayor que cero\")\n        return 0\n    elif number == 1:\n        return 0\n    elif number == 2:\n        return 1\n    else:\n        return fibonacci(number - 1) + fibonacci(number - 2)\n\n\nprint(fibonacci(5))\n\n\n\n'''"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/pwrxman.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n\"\"\"\n\ndef imprime(hasta: int):\n    if hasta >= 0:\n       print(hasta)\n       imprime(hasta-1)\n\nimprime(5)\n\nprint(\"> > > > > > > > > > > > > > > > > INICIA EXTRA > > > > > > > > > > > > > > > > > \\n\\n\")\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\nUtiliza el concepto de recursividad para:\n* - Calcular el factorial de un número concreto (la función recibe ese número).\n* - Calcular el valor de un elemento concreto (según su posición) en la \n*   sucesión de Fibonacci (la función recibe la posición).\n\"\"\"\n\n\ndef fibonacci(num: int) -> int:\n    if num <= 0:\n        print(\"La posicion tiene que ser mayor a cero\")\n        return 0\n    elif num == 1:\n        return 0\n    elif num == 2:\n        return 1\n    else:\n        return fibonacci(num - 1) + fibonacci(num - 2)\n\n\ndef elfactorial(num:int) -> int:\n    if num == 0 or num == 1:\n        return 1\n    elif num < 0:\n        return print(\"El número es menor que cero y no existe\")\n    else:\n        return num * elfactorial(num-1)\n\n\nprint(f\"El factorial es {elfactorial(5)}\")\n\nprint(f\"el fibonacci es {fibonacci(5)}\")\n# 0, 1, 1, 2, 3, 5, 8, 13, 21"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/pyramsd.py",
    "content": "def recur_1al100(n): return n if n < 0 else print(n) or recur_1al100(n-1)\nrecur_1al100(100)\n\nprint()\n\n# EXTRA\n#   factorial de un numero\ndef factorial(n): return 1 if (n==1 or n==0) else n * factorial(n - 1);\nprint(factorial(3))\n\nprint()\n\n#   posicion de numero fibonacci\ndef valor_fibonacci(n):\n  if n <= 0:\n    return \"La posición tiene que ser mayor que cero\"\n  elif n == 1: return 0\n  elif n == 2: return 1\n  else: \n    return valor_fibonacci(n-1) + valor_fibonacci(n-2)\nprint(valor_fibonacci(0))\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/quejuan52.py",
    "content": "'''\r\nEJERCICIO:\r\n Entiende el concepto de recursividad creando una función recursiva que imprima\r\n números del 100 al 0.\r\n'''\r\n\r\n#### funciones recursivas ####\r\n\r\n'''una funcion recursiva es una funcion que sellama asi misma\r\nen su propia ejecucion'''\r\n\r\ndef imprimir (value):\r\n    value -= 1\r\n    if value >=0:\r\n        print(value)\r\n        imprimir(value)\r\n    else:\r\n        print(\"fin de la funcion recursiva\")\r\n       \r\nvalor = 101\r\nimprimir(valor)\r\n\r\n'''\r\nDIFICULTAD EXTRA (opcional):\r\n Utiliza el concepto de recursividad para:\r\n - Calcular el factorial de un número concreto (la función recibe ese número).\r\n - Calcular el valor de un elemento concreto (según su posición) en la \r\n - sucesión de Fibonacci (la función recibe la posición).\r\n'''\r\n##### Calcular el factorial de un número concreto (la función recibe ese número). #####\r\n\r\ndef factorial_number (numero):\r\n    if numero == 1:\r\n        return 1\r\n    else: \r\n        fact= numero * factorial_number(numero-1)\r\n        return fact\r\n       \r\nnumber = int(input(\"proporcione un numero para calcular su factorial: \"))\r\nresultado = factorial_number(number)\r\nprint(f'el factorial de {number} es : ',{resultado})\r\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/qv1ko.py",
    "content": "def func(number):\n    print(number)\n\n    number = number + 1\n\n    if (number <= 100):\n        func(number)\n\ndef fact(number):\n    if (number <= 0):\n        return 0\n    elif (number == 1):\n        return 1\n    else:\n        return number * fact(number - 1)\n\ndef fib(pos):\n    if (pos <= 1):\n        return 0\n    elif (pos == 2 or pos == 3):\n        return 1\n    else:\n        return fib(pos - 1) + fib(pos - 2)\n\nfunc(0)\n\nprint(\"---\")\n\nprint(fact(4))\n\nprint(\"---\")\n\nprint(fib(5))\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/qwik-zgheib.py",
    "content": "# -- exercise\ndef recursive(n):\n    if n >= 0:\n        print(n)\n        recursive(n - 1)\n\n\nrecursive(100)\n\n\n# -- extra challenge\ndef factorial(n: int) -> int:\n    if n == 0:\n        return 1\n    else:\n        return n * factorial(n - 1)\n\n\nprint(f\"Factorial of 5: {factorial(5)}\")\n\n\ndef fibonacci(position):\n    if position <= 0:\n        return \"Position must be a positive integer.\"\n    elif position == 1:\n        return 0\n    elif position == 2:\n        return 1\n    else:\n        fib_list = [0, 1]\n        for i in range(2, position):\n            fib_list.append(fib_list[i - 1] + fib_list[i - 2])\n        return fib_list[position - 1]\n\n\nprint(f\"Fibonacci at position 10: {fibonacci(10)}\")\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/ramxv.py",
    "content": "''' \r\nLa Recursion es un proceso en el que una función se llama a sí misma \r\nde forma repetida hasta que se satisface una condición específica.\r\n'''\r\ndef vamo_pa_atras(n) -> int:\r\n    if n == 0:\r\n        print(n, end=\" \")\r\n        return 0\r\n    print(n, end=\" \")\r\n    return vamo_pa_atras(n-1)\r\n  \r\nvamo_pa_atras(100)\r\n\r\n# EXTRAS #\r\n\r\nprint(\"\\n\\n### FACTORIAL ###\\n\")\r\n\r\ndef factorial(n):\r\n    if n == 0 or n == 1:\r\n        return 1\r\n    return n * factorial(n-1)\r\n\r\n# n = int(input(\"Ingrese un número: \"))\r\n# print(f\"El factorial de {n} es =\", end=\" \")\r\nprint(\"El factorial es =\",factorial(5))\r\n\r\nprint(\"\\n### FIBONACCI ###\\n\")\r\n\r\nsuma_count = 0\r\n\r\ndef fibonacci(posicion):\r\n    global suma_count\r\n    if posicion < 2:\r\n        return posicion\r\n    suma_count += 1\r\n    return fibonacci(posicion-1) + fibonacci(posicion-2)\r\n        \r\n\r\nprint(\"El valor del elemento es =\",fibonacci(10),\"\\n\")\r\nprint(f\"Se realizaron {suma_count} sumas para calcular el número de Fibonacci\\n\")\r\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/rantamhack.py",
    "content": "\"\"\"\n* EJERCICIO:\n     * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n\"\"\"\n\nprint(\"\\n\\n=====================================EJERCICIO=====================================\\n\\n\")\n\ndef recursive(x):\n    if x >= 0:\n        print(x)\n        recursive(x-1)\n\nrecursive(100)    \n\nprint(\"\\n\\n=====================================DIFICULTAD EXTRA=====================================\\n\\n\")\n\n# Función factorial\n\ndef factorial(n):\n    if n == 0:\n        return 1\n    else:\n        return n * factorial(n -1)\n          \nresultado = factorial(6)\nprint(f\"El factorial de 6 es {resultado}\")\n\nprint(\"\\n\\n==========================================================================================\\n\\n\")\n\n# Función factorial aplicada a posicion de elementos  en fibonacci\n\ndef fibonacci(number:int) -> int:\n    if number == 0:\n        return 0\n    elif number == 1:\n        return 1\n    else:\n        return fibonacci(number -1) + fibonacci(number -2)\n\nnumber = int(input(\"¿Que valor, en funcion de la posicion en la serie de fibonacci deseas conocer?: \"))\nfibonacci(number)\nposition = fibonacci(number)\n\nprint(f\"El valor de la posicion {number} es {position}\")\n\nprint(\"\\n\\n==========================================================================================\\n\\n\")\n\n\nn = fibonacci(number)\ndef factorial_fibonacci(n):\n    factorial = n * factorial_fibonacci(n -1)\n    return factorial\n\nfactorial(n)\n\nprint(f\"El valor de la posicion {number} en la sucesion de fibonacci es {position} y el valor factorial de esta posicion es:  {factorial(n)}\")\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/raul-anton-2005.py",
    "content": "print(\"Números del 100 al 0 con recursividad:\")\n\ndef recursividad(n) -> None:\n    if n == 0:\n        print(n)\n    else:\n        print(n, end=', ')\n        recursividad(n - 1)\n\nrecursividad(100)\n\n#---DIFICULTAD: EXTRA---#\n\nprint(\"\\nFactorial de un número con recursividad:\")\n\ndef factorial_recursivo(n) -> int:\n    if n == 0 or n == 1:\n        return 1\n    else:\n        return n * factorial_recursivo(n - 1)\n    \nprint(factorial_recursivo(5))\n\nprint(\"\\nFibonacci de un número con recursividad:\")\ndef fibonacci_recursivo(n) -> int:\n    if n == 0:\n        return 0\n    elif n == 1:\n        return 1\n    else:\n        return fibonacci_recursivo(n - 1) + fibonacci_recursivo(n - 2)\n    \nprint(fibonacci_recursivo(5))\n\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/raulG91.py",
    "content": "\ndef print_numbers(number):\n    \n    if number == 0:\n        print(number)\n    else:\n        print(number)\n        print_numbers(number -1)    \n        \nprint_numbers(100)        \n\n\ndef factorial(number):\n    \n    if number == 0:\n        return 1\n    else:\n        return number * factorial(number-1)\n \nprint(\"Factorial\")    \nprint(factorial(10))    \n\ndef fibonacci(pos):\n    if pos == 0:\n        return 0\n    elif pos == 1:\n        return 1\n    else:\n        return fibonacci(pos-1) + fibonacci(pos-2)\n\n\nprint(\"Fibonacci\")\nprint(fibonacci(10))"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/rayn1er.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * Entiende el concepto de recursividad creando una función recursiva que imprima\n#  * números del 100 al 0.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Utiliza el concepto de recursividad para:\n#  * - Calcular el factorial de un número concreto (la función recibe ese número).\n#  * - Calcular el valor de un elemento concreto (según su posición) en la \n#  *   sucesión de Fibonacci (la función recibe la posición).\n#  */\n\n#la funcion recursiva es una que se llama asi misma\n\ndef counter(value):\n    print(value) #imprimimos nuestro valor, en este caso es 100\n    # value -=1 #restamos uno\n    if value >= 0:\n        counter(value-1) #verificamos condicion y ejecutamos la funcion\n\ncounter(100)\n\ndef factorial(value):\n    if value == 1:\n        return 1\n    else:\n        return value * factorial(value-1)\n\ndef fibonacci(value):\n    if value == 0:\n        return 0\n    elif value == 1:\n        return 1\n    else:\n        return fibonacci(value-1) + fibonacci(value-2)\n    \nprint(factorial(5))\nprint(fibonacci(7))\n\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/raynerpv2022.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n \"\"\"\n\ndef recursividad_100_0(numero : int):\n    if numero == 0:\n        return 0\n    else:\n        print(numero)\n        return recursividad_100_0( numero -1)\n    \nprint(recursividad_100_0(100))\n\n# EXtra\n\n# factorial\n\ndef factorial(n :int):\n    if n < 0:\n        return 0\n    if n == 0:\n      return 1\n    if n == 1:\n         return  n\n    else:\n         return n*factorial(n-1)\n\nprint(factorial(5))\n\n#fibonacci\n\ndef fibo(index :int):\n    if index <= 1:\n        return 0\n    elif  index == 2 :\n        return 1\n     \n    else:\n        return fibo(index-2)+fibo(index-1)\n\nprint(fibo(8))\n\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/restevean.py",
    "content": "# Crea una función recursiva que imprima los números del 100 al 0.\ndef print_numbers(n=100):\n    if n >= 0:\n        print(n)\n        print_numbers(n - 1)\n\n\n# Calcular el factorial de un número concreto (la función recibe ese número)\ndef factorial(n):\n    if n == 0:\n        return 1\n    else:\n        return n * factorial(n - 1)\n\n\n# Calcular el valor de un elemento concreto (según su posición) en la sucesión de\n# Fibonacci (la función recibe la posición).\ndef fibonacci(n):\n    if n == 0 or n == 1:\n        return n\n    else:\n        return fibonacci(n - 1) + fibonacci(n - 2)\n\n\nif __name__ == '__main__':\n    print_numbers()\n    print(factorial(5))\n    print(fibonacci(3))\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/rianojnicolas.py",
    "content": "###################################\n# Dev: rianojnicolas              #\n###################################\n\n# EJERCICIO:\n# función recursiva que imprima números del 100 al 0.\ndef print_numbers(n):\n    if n >= 0:\n        print(n)\n        print_numbers(n-1)\n\nprint_numbers(100)  # Imprime los números del 100 al 0\n\n# DIFICULTAD EXTRA:\n# 1. Factorial de un numero n\ndef calc_factorial(n):\n    if n == 0:\n        return 1\n    else:\n        return n*calc_factorial(n-1)\n\nprint(calc_factorial(5))  # Imprime el factorial de 5\n\n# 2. Valor de un elemento en la sucesión de Fibonacci segun su posición\n# secuencia -> 0, 1, 1, 2, 3, 5, 8, 13\n# Posición ->  0, 1, 2, 3, 4, 5, 6, 7\ndef calc_fibonacci(pos):\n    if pos == 0:\n        return 0\n    elif pos == 1:\n        return 1\n    else:\n        return calc_fibonacci(pos-1) + calc_fibonacci(pos-2)\n\nprint(calc_fibonacci(5))  # Imprime el valor de la posición 5\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/rigo93acosta.py",
    "content": "'''\n/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n'''\n\n### Ejercicio intro\n\ndef countdown(number: int):\n    if number >= 0:\n        print(number)\n        countdown(number-1)\n\ncountdown(100)\n\n### Extra\n# Factorial\ndef factorial(number: int) -> int:\n    if number < 0:\n        print(\"Los números negativos no son válidos.\")\n        return 0\n    elif number == 0:\n        return 1\n    else:\n        return number * factorial(number-1)\n\nn = 4\nprint(f'Factorial: {n} = {factorial(n)}')\n\ndef fibonacci(number: int) -> int:\n    if number == 0:\n        return 0\n    elif number == 1:\n        return 1\n    else:\n        return fibonacci(number-1) + fibonacci(number-2)\n\nn = 10\nprint(f'Fibonacci: {n} = {fibonacci(n)}')"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/rikmij.py",
    "content": "def count_back(counter):\n    \n    print(counter, end = \", \")\n    counter -= 1\n\n    if counter > 0:\n        count_back(counter)\n    \n    elif counter == 0:\n        print(counter)\n\nnumber = 100\ncount_back(number)\n\n\nprint('\\n', '~'*7, \"EJERCICIO EXTRA\", '~'*7)\nprint(\"--> EJERCICIO 1: FACTORIAL\")\n\n#multiplicación de todos los números menores que él hasta 0\ndef factorial(num: int) -> int:\n    if num > 0:\n        res = num * factorial(num-1)\n        return res\n    else:\n        return 1\n\nprint(factorial(5))\n\n\nprint(\"--> EJERCICIO 2: FIBONACCI\")\n#sucesión de números que cada número es la suma de los 2 anteriores\n\ndef fibonacci(num):\n\n    if num-1 < 2:\n        return 1\n    \n    else:\n        return fibonacci(num - 2) + fibonacci(num - 1)\n\nprint(fibonacci(9))\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/santiagobailleres.py",
    "content": "'''EJERCICIO:\nEntiende el concepto de recursividad creando una función recursiva que imprima\nnúmeros del 100 al 0.\nDIFICULTAD EXTRA (opcional):\nUtiliza el concepto de recursividad para:\n- Calcular el factorial de un número concreto (la función recibe ese número).\n- Calcular el valor de un elemento concreto (según su posición) en la sucesión de Fibonacci (la función recibe la posición).'''\n\n# Recursividad para imprimir números del 100 al 0\ndef recursividad(n):\n    if n >= 0:\n        print(n)\n        recursividad(n-1)\n\nrecursividad(100)\n\n# EXTRA\n# Recursividad para calcular el factorial de un número\ndef factorial(n:int):\n    if n < 0:\n        print(\"No se puede calcular el factorial de un número negativo\")\n        return 0\n    elif n == 0:\n        return 1\n    else:\n        return n * factorial(n-1)\n\nprint(factorial(4))\n\n# Recursividad para calcular el valor de un elemento en la sucesión de Fibonacci: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34... es decir, el siguiente número es la suma de los dos anteriores\ndef fibonacci(n:int):\n    if n <= 0:\n        print(\"La posición debe ser mayor a 0\")\n        return 0\n    elif n == 1:\n        return 0\n    elif n == 2:\n        return 1\n    else:\n        return fibonacci(n-1) + fibonacci(n-2)\n\nprint(fibonacci(6))\n\n# Otra forma de hacerlo\ndef fibonacci2(n:int):\n    if n <= 0:\n        print(\"La posición debe ser mayor a 0\")\n        return 0\n    elif n == 1:\n        return 0\n    elif n == 2:\n        return 1\n    else:\n        a, b = 0, 1\n        for i in range(2, n):\n            a, b = b, a+b\n        return b\n\nprint(fibonacci2(6))"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/santyjL.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la\n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\"\"\"\n\nlista = [] #lista para almacenar los numeros del 100 al 0\ndef Recursividad_del_100_al_0(numero = 100 ):\n\n    if numero < 0: # si el numero es menor que 0 termina la funcion , para evitar la recursion infinita\n        return lista\n\n    lista.append(numero)\n    return Recursividad_del_100_al_0(numero - 1) #se resta un numero del numero introducido\n\ndef factorial(n):\n    if n == 0 or n == 1:\n        return 1\n    else:\n        return n * factorial(n - 1)\n\ndef Fibonacci(numero , a = 1 , b = 0 ):\n    if numero == 0 :\n        return a\n\n    return Fibonacci(numero -1 , a + b ,a )\n\nprint(\"recursividad , del 100 al 0 : \" , Recursividad_del_100_al_0(100))\nprint(\"factorial de 5 es : \" , factorial(5))\nprint(\"valor del numero 20 de la suceccion fibonacci : \", Fibonacci(20))\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/sarismejiasanchez.py",
    "content": "# #06 RECURSIVIDAD\n\n\"\"\"\n* EJERCICIO:\n* Entiende el concepto de recursividad creando una función recursiva que imprima\n* números del 100 al 0.\n\"\"\"\n\n\"\"\"\nLa recursividad es una técnica de programación donde una función se llama a sí misma para resolver un problema. En cada llamada, se trabaja con una versión reducida del problema hasta alcanzar una condición base, que detiene la recursión.\n\nCualquier función recursiva tiene dos secciones de código claramente divididas:\n\nPor un lado tenemos la sección en la que la función se llama a sí misma.\nPor otro lado, tiene que existir siempre una condición en la que la función retorna sin volver a llamarse. Es muy importante porque de lo contrario, la función se llamaría de manera indefinida.\n\"\"\"\n\nprint(\"Números del 100 al 0\")\n\ndef print_numbers(n):\n    # Condición base: si n es menor que 0, detenemos la recursión\n    if n < 0:\n        return  # Termina la ejecución\n    # Imprimimos el número actual\n    print(n)\n    # Llamamos recursivamente a la función con n - 1\n    print_numbers(n - 1)\n\n# Llamamos a la función con 100 como punto de partida\nprint_numbers(100)\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n\"\"\"\nprint(\"\\nDIFICULTAD EXTRA\")\n\nprint(\"\\nFactorial de un número\")\n\ndef factorial(n):\n    # Condición base: si n es igual a 1, detenemos la recursión\n    # n! = 1 si n = 1 \n    if n == 1:\n        return 1# Termina la ejecución\n    # Llamada recursiva\n    else:\n        # n! = n * (n-1)! si n > 1\n        return n * factorial(n - 1)\n\nn = 5\nprint(f\"El factorial de {n} es: {factorial(n)}\")\n\nprint(\"\\nCalcular el valor de un elemento concreto (según su posición) en la sucesión de Fibonacci\")\n\n# Dicha serie calcula el elemento n sumando los dos anteriores n - 1 + n - 2\n# Se asume que los dos primeros elementos son 0 y 1.\ndef fibonacci(n):\n    # Condicion base\n    if n == 0:\n        return 0\n    elif n == 1:\n        return 1\n    else:\n        return fibonacci(n - 1) + fibonacci(n - 2)\n\n# 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89\nn = 7\nprint(f\"El valor del elemento {n} en la serie fibonacci es: {fibonacci(7)}\")"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/sorubadguy.py",
    "content": "\"\"\"\n*Recursividad\n\"\"\"\n\ndef numeros(numero: int):\n    if(numero<100):\n        numero += 1\n        numeros(numero)\n        print(numero)\n    \n\nnumeros(0)\n\n\"\"\"\n!Extra\n\"\"\"\n\ndef factorial(numero: int, resultado = 1):\n    if(numero <= 0):\n        print(resultado)\n    else:\n        resultado *= numero\n        numero -= 1\n        factorial(numero, resultado)\n\n#factorial(int(input(\"de que numero entero desea calcular el factorial?: \")))\n\ndef fibonacci(posicion: int, posactual = 2, resultado = [0,1,1]):\n    if(posicion <= 2):\n        print(resultado[posicion])\n    elif(posactual == posicion):\n        print(resultado[len(resultado)-1])\n    else:\n        resultado.append(resultado[len(resultado)-1] + resultado[len(resultado)-2])\n        posactual += 1\n        fibonacci(posicion, posactual, resultado)\n\n#?posicion  0 1   2   3   4   5   6   7   8   9     10 (len(posicion 11))\n#?fibonacci 0 1   1   2   3   5   8   13  21  34    55\n\nfibonacci(10)"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/switchdays.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n\"\"\"\n\n\ndef print_numbers(number):\n    # Caso base: detener la recursión cuando number llega a 0\n    if number < 0:\n        return\n    else:\n        # Imprimir el número actual\n        print(number)\n        # Llamar recursivamente a la función con un número más pequeño\n        print_numbers(number - 1)\n\n# Llamada a la función con number = 100\nprint_numbers(100)\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n\"\"\"\n\n\ndef factorial(number):\n\n    if number == 0:\n        return 1\n    else:\n        return number * factorial(number - 1)\n    \n\ndef fibonacci(posicion):\n\n    if posicion == 0:\n        return 0\n    elif posicion == 1:\n        return 1\n    else:\n        return fibonacci(posicion - 1) + fibonacci(posicion - 2)\n    \n\nprint(\"Introduce un número cualquiera.\\nEn el primer caso sacará el factorial de ese número.\\nEn el segundo caso sacará el valor de fibonaci en la posición de ese número.)\")\n\ninput = input(\"Introduce el número: \")\n\ntry:\n    number = int(input)\n\n    print(\"El factorial de \", number, \"es: \", factorial(number))\n    print(\"El valor de la posición \", number, \"de fibonaci es: \", fibonacci(number))\nexcept:\n    print(\"El valor \", input, \"no es válido.\")\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/thonys07.py",
    "content": "\n'''\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la\n *   sucesión de Fibonacci (la función recibe la posición).\n'''\n\nnumbers_to_print=[]\ndef printing_numbers(n):\n    if n < 0:\n        return numbers_to_print\n    numbers_to_print.append(n)\n    printing_numbers(n - 1)\n\nprinting_numbers(100)\nprint('los valores impresos son: ', numbers_to_print)\n\n\ndef factorial(n):\n    if n == 0:\n        return 1\n    elif n == 0 or n == 1:\n        return 1\n    else:\n        return n * factorial(n - 1)\nn=12\nresult=factorial(n)\nprint(f'el factorial de {n} es: {result}')\n\ndef fibonacci(position):\n    if position <= 0 or position == 1:\n        return 0\n    elif position == 2:\n        return 1\n    else:\n        return fibonacci(position - 1) + fibonacci(position - 2)\n    \nposition=12\nresult=fibonacci(position)\nprint(f'el valor de la serie de fibonacci en la posicion {position} es: {result}')\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/tito-delpino.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * Entiende el concepto de recursividad creando una función recursiva que imprima\n#  * números del 100 al 0.\n\ndef rec(n):\n    if n == 0:\n        return 0\n    else:\n        print(n)\n        return rec(n-1)\n\nnumeros = rec(100)\nprint(numeros)\n\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Utiliza el concepto de recursividad para:\n#  * - Calcular el factorial de un número concreto (la función recibe ese número).\n\ndef factorial(n):\n    if n == 0:\n        return 1\n    else:\n        return n * factorial(n - 1)\n    \nresult = factorial(5)\nprint(result)\n\n\n#  * - Calcular el valor de un elemento concreto (según su posición) en la \n#  *   sucesión de Fibonacci (la función recibe la posición).\n\ndef fibonacci(n):\n    if n == 0 or n == 1:\n        return 1\n    else:\n        return fibonacci(n-1) + fibonacci(n-2)\n    \nvalor = fibonacci(9)\nprint(valor)"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/toral24.py",
    "content": "'''\nEJERCICIO:\nEntiende el concepto de recursividad creando una función recursiva que imprima\nnúmeros del 100 al 0.\n'''\n\ndef nums():\n    list=[]\n    i=1\n    while i <= 100:\n        list.append(i)\n        i +=1\n    return list\n\nprint(nums())\n'''\nDIFICULTAD EXTRA (opcional):\nUtiliza el concepto de recursividad para:\n    - Calcular el factorial de un número concreto (la función recibe ese número).\n    - Calcular el valor de un elemento concreto (según su posición) en la sucesión de Fibonacci (la función recibe la posición).\n'''\n\ndef fact(num):\n    cont = 1\n    resul = 1\n    while cont <=num:\n        resul *= cont\n        cont += 1\n    return resul\n\nprint(fact(5))\n\ndef fibo(num):\n    num1 = 1\n    num2 = 1\n    aux = 0\n    cont = 1\n    while num >= cont:\n        aux = num2\n        num2 += num1\n        num1 = aux\n        cont += 1\n    return num2\n\nprint(fibo(15))\n\n\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/victorfer69.py",
    "content": "#FUNCION RECURSIVA DEL 0 AL 100\n\ndef recursive_function(n:int):\n    if n == 100:\n        print(n)\n    else:\n        print(n)\n        recursive_function(n+1)\n    \nrecursive_function(0)\n\n\n#EJERCICIO EXTRA\ndef factorial(n:int):\n    if n > 0:\n        if n == 1:\n            return 1\n        else:\n            return n * factorial(n-1)\n    else:\n        print(\"Numero invalido\")\n        return 0\n\nprint(factorial(5))\n\n\ndef fibonacci(n:int):\n    if n >= 0:\n        if n == 0:\n            return 0\n        elif n == 1:\n            return 1\n        else:\n            return fibonacci(n-1) + fibonacci(n-2)\n    else:\n        print(\"Numero invalido\")\n        return 0\n    \nprint(fibonacci(10))"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/warclimb.py",
    "content": "# #06 RECURSIVIDAD\n#### Dificultad: Difícil | Publicación: 05/02/24 | Corrección: 12/02/24\n\n## Ejercicio\n\n\n\"\"\"\n* EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n\"\"\"\n# contar de 100 a 0\ndef recursiva():\n    for num in range(100, -1, -1):\n        print(num)\n\n\n# Ejercicio extra\n# Calcular el factorial de un número concreto (la función recibe ese número)\ndef factorial(n):\n    \"\"\"Los factoriales son funciones matemáticas que\n    multiplican un número por todos los números que lo preceden.\n    La fórmula del factorial puede expresarse como: = n ( n − 1 )\n    \"\"\"\n    result = 1 # Almacenamos el resultado\n    for i in range(1, n + 1): # recorremos desde 1 hasta el numero introducido en incrementos de 1\n        result *= i # multiplicamos el resultado por el numero actual\n    return result\n\n# Calcular el valor de un elemento concreto (según su posición) en la sucesión de Fibonacci.\ndef fibonacci(fn):\n    \"\"\"La secuencia de sucesión de Fibonacci consiste en la fórmula:\n    Fn = Fn-1 + Fn-2 .\n    En otras palabras, el siguiente número es una suma de los dos anteriores.\n    Los dos primeros números son 1 , luego 2(1+1) , luego 3(1+2) , 5(2+3) y así sucesivamente: 1, 1, 2, 3, 5, 8, 13, 21...\n    \"\"\"\n    result = 0\n    # recorremos desde 1 hasta el numero introducido en incrementos de 1\n    for i in range(1, fn + 1):\n        result += i # sumamos el el numero anterior por el actual\n    return result\n\n# Vamos a ello! Aqui llamamos las funciones\nif __name__ == \"__main__\":\n    # Llamamos a la funcion del ejercicio 1\n    recursiva()\n\n    # Llamamos a la funcion del factorial\n    print(factorial(8)) # Factorial de 8 deberia dar 40320\n\n    # Llamamos a la funcion de fibonacci\n    print(fibonacci(8)) # Fibonacci de 8 deberia dar 36"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/worlion.py",
    "content": "\n# RECURSIVIDAD\n\n# Imprimir (recursivamente) del 100 al 0\n\ndef conteo_regresivo(x: int):\n    if(x >= 0):\n        print(x)\n        conteo_regresivo(x-1)\n\nprint(\"Imprimiendo los números del 100 al 0 con recursividad...\")\nconteo_regresivo(100)\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n\"\"\"\n\nprint(\"\\n ---- 🌩 DIFICULTAD EXTRA 🌩 ----\\n\")\n\n# Factorial\n\ndef factorial(n: int):\n    if(n>=1):\n        return n*factorial(n-1)\n    elif(n == 0):\n        return 1;\n    else:   \n        print(\"WARNING! No se puede calcular el factorial de un número negativo.\")\n\nnum = 9\nprint(f\"{num}! = {factorial(num)}\")\n\n\n# Fibonacci\n\ndef fibonacci(pos: int):\n    if(pos <= 0):\n        print(\"WARNING! La posición debe ser un entero positivo.\")\n        return 0\n    elif(pos == 1):\n        return 0    \n    elif(pos == 2):\n        return 1\n    else:\n        return fibonacci(pos-1) + fibonacci(pos-2) \n    \n\nnum = 30\nprint(f\"número #{num} de Fibonacci = {fibonacci(num)}\")"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/xemita007.py",
    "content": "\"Ejercicio Recursividad\"\n\n\ndef recursividad (number:int):\n    if number>=0:\n        print(number)\n        recursividad(number-1)\n\n\nrecursividad(100)\n\n\ndef factorial(number: int) -> int:\n    if number < 0:\n        print(\"Los números negativos no son válidos\")\n        return 0\n    elif number == 0:\n        return 1\n    else:\n        return number * factorial(number - 1)\n    \nprint(factorial(3))\n\n\ndef fibonacci(elemento: int) -> int:\n    if elemento < 0:\n        print(\"No puede ser menor de 0\")\n        return 0\n    elif elemento == 0:\n        return 0\n    elif elemento == 1:\n        return 1\n    else:\n        return fibonacci(elemento - 1) + fibonacci(elemento - 2)\n\n# Ejemplo de uso\nprint(fibonacci(5))  # Salida: 5"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/ycanas.py",
    "content": "# I. Ejercicio\n\ndef my_func(n):\n    if n < 0:\n        return\n    \n    print(n)\n    my_func(n - 1)\n\n\nprint()\nprint(\" Ejercicio \".center(30, '-'), end=\"\\n\\n\")\nmy_func(100)\n\n\n# II. Extra\n\ndef factorial(n):\n    if n <= 2:\n        return n\n    \n    return factorial(n - 1) * n\n\n\ndef fibonacci(n):\n    if n <= 1:\n        return n\n    \n    return fibonacci(n - 1) + fibonacci(n - 2)\n\n\nprint()\nprint(\" Factorial \".center(30, '-'), end=\"\\n\\n\")\nprint(factorial(5))\n\nprint()\nprint(\" Fibonacci \".center(30, '-'))\nprint(fibonacci(8))\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/yenneralayon142.py",
    "content": "\"\"\"\nRecursividad\n\"\"\"\ndef countdown(number:int):\n    if number >= 0:\n        print(number)\n        countdown(number - 1)\ncountdown(100)\n\n\"\"\"\nExtra\n\"\"\"\n#Factorial\ndef factorial(number:int) -> int:\n    if number < 0:\n        print(\"El número no puede ser menor que 0\")\n        return 0\n    elif number == 0:\n        return 1\n    else:\n        return number * factorial(number - 1)\nprint(factorial(5))\n\n#Fibonacci\ndef fibonacci(number:int) -> int:\n    if number < 0:\n        print(\"El número tiene que ser mayor a 0\")\n        return 0\n    elif number == 1:\n        return 0\n    elif number == 2:\n        return 1\n    else:\n        return fibonacci(number - 1) + fibonacci(number - 2)\nprint(fibonacci(10))\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/yoezequiel.py",
    "content": "def imprimir_numeros(n):\n    if n < 0:\n        return\n    print(n, end=\" \")\n    imprimir_numeros(n - 1)\n\n\nimprimir_numeros(100)\n\n\ndef factorial(n):\n    if n == 0:\n        return 1\n    return n * factorial(n - 1)\n\n\ndef fibonacci(pos):\n    if pos <= 1:\n        return pos\n    return fibonacci(pos - 1) + fibonacci(pos - 2)\n\n\nprint(\"\\n\")\nprint(\"Factorial de 5:\", factorial(5))\nprint(\"Elemento en la posición 7 de Fibonacci:\", fibonacci(7))\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/zetared92.py",
    "content": "# RECURSIVIDAD\n\ndef countdown(num: int):\n    if num >= 0:\n        print(num)\n        countdown(num - 1)\n\ncountdown(100)\n\n\n\n# Extra\n\nprint(\"🧩 DIFICULTAD EXTRA 🧩\")\n\ndef factorial(num: int) -> int:\n    if num < 0:\n        print(\"Input a positive integer\")\n        return 0\n    elif num == 0:\n        return 1\n    else:\n        return num * factorial(num - 1)\n\nprint(factorial(4))\n\ndef fibonacci(num: int) -> int:\n    if num <= 0:\n        print(\"The position must be greater than zero\")\n        return 0\n    elif num == 1:\n        return 0\n    elif num == 2:\n        return 1\n    else:\n        return fibonacci(num -1) + fibonacci(num - 2)\n    \nprint(fibonacci(4))\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/python/zonnen69.py",
    "content": "#  *\n#  * EJERCICIO:\n#  * Entiende el concepto de recursividad creando una función recursiva que imprima\n#  * números del 100 al 0.\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Utiliza el concepto de recursividad para:\n#  * - Calcular el factorial de un número concreto (la función recibe ese número).\n#  * - Calcular el valor de un elemento concreto (según su posición) en la \n#  *   sucesión de Fibonacci (la función recibe la posición).\n \n# Numeros del 100 al 0\n\ndef imprimir_numeros(n):\n    if n < 0:\n        return\n    print(n)\n    imprimir_numeros(n - 1)\n\nimprimir_numeros(100)\n\n\n#  * - Calcular el factorial de un número concreto (la función recibe ese número).\ndef factorial(n):\n    if n == 0:\n        return 1\n    else:\n        return n * factorial(n-1)\n\nnumero = int(input(\"Ingrese el número para calcular su factorial: \"))\nresultado = factorial(numero)\nprint(f\"El factorial de {numero} es: {resultado}\\n\")\n\n\n#  * - Calcular el valor de un elemento concreto (según su posición) en la \n#  *   sucesión de Fibonacci (la función recibe la posición).\n\ndef fibonacci(posicion):\n    if posicion <= 1:\n        return posicion\n    else:\n        return fibonacci(posicion - 1) + fibonacci(posicion - 2)\n\nposicion = int(input(\"Ingrese la posición del elemento en la sucesión de Fibonacci: \"))\nvalor = fibonacci(posicion)\nprint(f\"El valor del elemento en la posición {posicion} de la sucesión de Fibonacci es {valor}.\")\n\n\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/racket/luishendrix92.rkt",
    "content": "#lang racket\n\n(letrec ([loop (lambda (n)\n                 (when (>= n 0)\n                   (begin\n                     (printf \"n = ~a\\n\" n)\n                     (loop (- n 1)))))])\n  (loop 100))\n\n#| DIFICULTAD EXTRA (opcional):\n|| ----------------------------\n|| Utiliza el concepto de recursividad para:\n|| - Calcular el factorial de un número concreto (la función recibe ese número).\n|| - Calcular el valor de un elemento concreto (según su posición) en la\n||   sucesión de Fibonacci (la función recibe la posición).\n\\+============================================================================|#\n\n(define (factorial n)\n  (if (> n 1)\n      (* n (factorial (- n 1)))\n      1))\n\n(define (fib n)\n  (if (> n 1)\n      (+ (fib (- n 1)) (fib (- n 2)))\n      n))\n\n(printf \"Factorial calculation: 5! = ~a\\n\" (factorial 5))\n(printf \"The 12° number in the fibonacci sequence is: ~a\\n\" (fib 12))\n\n#|\n  Output of running `racket luishendrix92.rkt`:\n  =============================================\n  n = 100\n  n = 99\n  n = 98\n  n = 97\n  n = 96\n  n = 95\n  n = 94\n  n = 93\n  n = 92\n  n = 91\n  n = 90\n  n = 89\n  n = 88\n  n = 87\n  n = 86\n  n = 85\n  n = 84\n  n = 83\n  n = 82\n  n = 81\n  n = 80\n  n = 79\n  n = 78\n  n = 77\n  n = 76\n  n = 75\n  n = 74\n  n = 73\n  n = 72\n  n = 71\n  n = 70\n  n = 69\n  n = 68\n  n = 67\n  n = 66\n  n = 65\n  n = 64\n  n = 63\n  n = 62\n  n = 61\n  n = 60\n  n = 59\n  n = 58\n  n = 57\n  n = 56\n  n = 55\n  n = 54\n  n = 53\n  n = 52\n  n = 51\n  n = 50\n  n = 49\n  n = 48\n  n = 47\n  n = 46\n  n = 45\n  n = 44\n  n = 43\n  n = 42\n  n = 41\n  n = 40\n  n = 39\n  n = 38\n  n = 37\n  n = 36\n  n = 35\n  n = 34\n  n = 33\n  n = 32\n  n = 31\n  n = 30\n  n = 29\n  n = 28\n  n = 27\n  n = 26\n  n = 25\n  n = 24\n  n = 23\n  n = 22\n  n = 21\n  n = 20\n  n = 19\n  n = 18\n  n = 17\n  n = 16\n  n = 15\n  n = 14\n  n = 13\n  n = 12\n  n = 11\n  n = 10\n  n = 9\n  n = 8\n  n = 7\n  n = 6\n  n = 5\n  n = 4\n  n = 3\n  n = 2\n  n = 1\n  n = 0\n  Factorial calculation: 5! = 120\n  The 12° number in the fibonacci sequence is: 144\n|#"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/ruby/kodenook.rb",
    "content": "\n##\n# The `recursion` function in Ruby recursively prints numbers from the input number down to 0.\n#\n# Args:\n#   number: The `recursion` method takes a parameter `number`, which is used to control the recursion.\n# The method will output the value of `number` and then call itself recursively with `number-1` until\n# `number` is less than or equal to 0.\ndef recursion(number)\n    puts number\n    recursion(number-1) if number > 0\nend\n\nrecursion(100)\n\n=begin\n    Exercise\n=end\n\n##\n# The above Ruby function calculates the factorial of a given number recursively.\n#\n# Args:\n#   number: The `number` parameter in the `factorial` function represents the integer for which you\n# want to calculate the factorial. The factorial of a non-negative integer `n`, denoted as `n!`, is\n# the product of all positive integers less than or equal to `n`.\n#   resultado: The `resultado` parameter in the `factorial` function is used to keep track of the\n# intermediate result as the factorial calculation progresses through recursive calls. It starts with\n# a default value of 1 and gets updated with the multiplication of the current number and the previous\n# result in each recursive call. Defaults to 1\ndef factorial(number, resultado = 1)\n    if number > 1\n        factorial(number-1, number*resultado)\n    else\n        puts resultado\n    end\nend\n\nfactorial(5)\n\n##\n# The above Ruby function calculates the Fibonacci number at a given position using recursion.\n#\n# Args:\n#   position: The `fibonacci` function you provided calculates the Fibonacci number at a given\n# position in the sequence. The Fibonacci sequence starts with 1, 1, and each subsequent number is the\n# sum of the two preceding numbers.\n#\n# Returns:\n#   The code is a recursive function to calculate the Fibonacci number at a given position. If the\n# position is greater than 2, it recursively calls itself to calculate the Fibonacci number by adding\n# the previous two Fibonacci numbers. If the position is 2 or less, it returns 1.\ndef fibonacci(position)\n    if position > 2\n        return fibonacci(position - 1) + fibonacci(position - 2)\n    else\n        return 1\n    end\nend\n\nputs fibonacci(7)"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/rust/FullOvellas.rs",
    "content": "use std::collections::HashMap;\n\nfn print_to_100(num: i32) {\n    if num <= 100 {\n        println!(\"{}\", num);\n        print_to_100(num + 1);\n    }\n}\n\nfn factorial(num: i32) -> i32 {\n    if num == 1 {\n        return 1;\n    }\n\n    num * factorial(num - 1)\n}\n\nfn fib_at(n: i32, memo: &mut HashMap<i32, i32>) -> i32 {\n    match n {\n        0 => 0,\n        1 | 2 => 1,\n        3.. => {\n            (if let Some(num) = memo.get(&(n - 1)) {\n                *num\n            } else {\n                let fib = fib_at(n - 1, memo);\n                memo.insert(n - 1, fib);\n                fib\n            }) + (if let Some(num) = memo.get(&(n - 2)) {\n                *num\n            } else {\n                let fib = fib_at(n - 2, memo);\n                memo.insert(n - 2, fib);\n                fib\n            })\n        }\n        _ => panic!(\"Invalid position\"),\n    }\n}\n\nfn main() {\n    print_to_100(0);\n\n    println!(\"{}\", factorial(5));\n\n    println!(\"{}\", fib_at(5, &mut HashMap::new()));\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/rust/brockar.rs",
    "content": "fn main(){\n    println!(\"Contando desde 100 hasta 0\");\n    cien_cero(100);\n\n    println!(\"EXTRA EXTRAA!\");\n    println!(\"Factorial de un número concreto (5)\");\n    let num = 5;\n    println!(\"{}\",factorial(num));\n\n    println!(\"Fibonacci de un número concreto (5)\");\n    println!(\"{}\",fibo(num));\n}\n\nfn cien_cero(num:u8){\n    if num == 0{\n        println!(\"0\");\n    } else {\n        println!(\"{}\", num);\n        cien_cero(num - 1);\n    }\n}\n\n// Los enteros podrían ser unsigned (u16) ya que para esto no se utilizan negativos.\nfn factorial(num:i16) -> i16{\n    if num == 0{\n        return 1;\n    }\n    else{\n        return num * factorial(num - 1);\n    }\n}\n\nfn fibo(num:i16)-> i16{\n    if num<0{\n        println!(\"El numero debe ser mayor a 0.\");\n        return 0;\n    }\n    else if num==0{\n        return 0;\n    }\n    else if num==1{\n        return 1;\n    }\n    return fibo(num-1) + fibo(num-2);\n}"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/rust/gabrielmoris.rs",
    "content": "/*\n * EXERCISE:\n * Understand the concept of recursion by creating a recursive function that\n * prints numbers from 100 to 0.\n *\n * EXTRA DIFFICULTY (optional):\n * Use the concept of recursion to:\n * - Calculate the factorial of a specific number (the function receives that number).\n * - Calculate the value of a specific element (according to its position) in the\n *   Fibonacci sequence (the function receives the position).\n */\n\nuse std::collections::HashMap;\n\nfn main() {\n    let mut n = 1;\n\n    fn print_recursive(num: &mut i32) {\n        if *num > 100 {\n            return;\n        }\n\n        println!(\"{}\", *num);\n\n        let mut new_num = *num + 1;\n        print_recursive(&mut new_num);\n    }\n    print_recursive(&mut n);\n    let fac = factorial(4);\n    println!(\"Factorial of 4 = {fac}\");\n\n    let mut memo = HashMap::new(); // Hashmap to save the recursive answers and save memory.\n    let fib = fibonacci(7, &mut memo);\n    println!(\"Fibonacci number in 7th possition = {fib}\"); // should be 13\n\n    // Own Challenge: Get the possition of a fibonacci number. Return 0 if it doesn't belong to fibonacci serie.\n    let fibo = fibonacci_position(13);\n    println!(\"Fibonacci position of 13 = {fibo}\"); // should be 7\n}\n\nfn factorial(n: i32) -> i32 {\n    if n == 0 {\n        return 1;\n    } else {\n        return n * factorial(n - 1);\n    }\n}\n\nfn fibonacci(n: u32, memo: &mut HashMap<u32, u32>) -> u32 {\n    match n {\n        0 => 0,\n        1 => 1,\n        n => {\n            // Is it not in the memo? save it, otherwise get it from there.\n            if !memo.contains_key(&n) {\n                let fib_n_minus_1 = fibonacci(n - 1, memo);\n                let fib_n_minus_2 = fibonacci(n - 2, memo);\n                memo.insert(n, fib_n_minus_1 + fib_n_minus_2);\n            }\n            *memo.get(&n).unwrap()\n        }\n    }\n}\n\nfn fibonacci_position(n: u32) -> u32 {\n    let mut position: u32 = 0;\n    let mut memo = HashMap::new(); // Saving the data will allow me to dont fall in a stack overflow.\n    let mut fibonacci_calc = fibonacci(position, &mut memo);\n\n    while fibonacci_calc < n {\n        position += 1;\n        fibonacci_calc = fibonacci(position, &mut memo);\n    }\n\n    // I could throw an Error but I decide to return 0 when the number\n    // doesn't belong to fibonacci serie.\n    if fibonacci_calc != n {\n        return 0;\n    }\n\n    position\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/rust/kenysdev.rs",
    "content": "/*\n╔═══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado                ║\n║ GitHub: https://github.com/Kenysdev   ║\n║ 2024 -  Rust                          ║\n╚═══════════════════════════════════════╝\n-----------------------------------------\n* RECURSIVIDAD\n-----------------------------------------\n- La recursividad es la capacidad de una función para llamarse a sí misma,ya sea \n  de forma directa o indirecta, con el propósito de resolver un problema.\n*/\nfn main() {\n    // __________________________________\n    // Recursividad directa(es una función se llama a sí misma.)\n    // imprimiendo números del 100 al 0.\n    fn num(n: i16) {\n        println!(\"{n}\");\n        // Caso base(evitar repetición indefinida)\n        if n > 0 {\n            num(n - 1);\n        }\n    }\n\n    num(100);\n\n    // __________________________________\n    // Recursividad indirecta(Cuando varias funciones se llamen entre sí.)\n    // imprimiendo números de 100 al 0 e indicar si es par.\n    fn is_even(n: i16) {\n        if n %2 == 0 {\n            write(n, true);\n        } else {\n            write(n, false)\n        }              \n    }\n\n    fn write(n: i16, even: bool) {\n        println!(\"- {n} -> es par?: {even}\");\n        if n > 0 {\n            is_even(n - 1)\n        }\n    }\n\n    is_even(100);\n\n    // __________________________________\n    // EJERCICIO\n    // Calcular el factorial de un número concreto (la función recibe ese número).\n    // 4! = 4 * 3 * 2 * 1 = 24\n    fn factorial(n: i32) -> i32{\n        if n != 0 {\n            n * factorial(n - 1)\n        } else {\n            1\n        }\n    }\n    /* explicación\n    fac(4)\n        | = 24 \n     return 4 * fac(3) ->(4 * 6)\n                  | = 6 \n         return 3 * fac(2) ->(3 * 2)\n                      | = 2 \n             return 2 * fac(1) ->(2 * 1)\n                          | = 1 \n                 return 1 * fac(0) ->(1 * 1)\n                              | = return 1 -> caso base\n    */\n\n    println!(\"Factorial de 4: {}\", factorial(4));\n\n    /* __________________________________\n    * - Calcular el valor de un elemento concreto (según su posición) en la \n        sucesión de Fibonacci (la función recibe la posición).\n    * n : |0|1|2|3|4|5|6|...\n    * fb: |0|1|1|2|3|5|8|...\n    *      |+|=^   |+|=^ ...\n    */\n\n    fn fibonacci(n: i16) -> i16{\n        if n <= 1 {\n            return  n;\n        } else {\n            fibonacci(n - 1) + fibonacci(n - 2)\n        }\n    }\n\n    /* explicación fb(4)\n                            return 3\n                  fib(3)      / \\    fib(2)\n                   / \\ =2      +      / \\ =1\n             fib(2) + fib(1)    fib(1) + fib(0) -> caso base\n              / \\ =1\n        fib(1) + fib(0) -> caso base\n\n    NOTE: Esto es ineficiente para valores grandes de \"n\".\n    */\n\n    println!(\"fibonacci(4): {}\", fibonacci(4));\n}\n\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/rust/raulfauli.rs",
    "content": "/// #06 RECURSIVIDAD\n///\n/// `rustc ./Roadmap/06\\ -\\ RECURSIVIDAD/rust/raulfauli.rs && ./raulfauli && rm raulfauli`\n///\n\nfn main() {\n\n    print_numbers(100);\n\n    // Extra\n    println!(\"Factorial 5: {}\", factorial(5));\n    println!(\"Fibonacci 10: {}\", fibonacci(10));\n\n    // Extra, extra: Con notación científica\n    println!(\"Valor máximo: {:e}\", u128::MAX); // 10^38\n    println!(\"Factorial 30: {:e}\", factorial(30)); // 10^32\n    println!(\"Fibonacci 150: {:e}\", fibonacci_memoization(150)); // 10^31\n}\n\nfn print_numbers(n: u32) {\n    println!(\"{n}\");\n\n    if n > 0 {\n        print_numbers(n - 1);\n    }\n}\n\nfn factorial(n: u128) -> u128 {\n    if n <= 1 {\n        return 1;\n    }\n\n    if n > 30 {\n        panic!(\"¡Factorial demasiado largo!\");\n    }\n\n    n * factorial(n - 1)\n}\n\nfn fibonacci(n: u64) -> u64 {\n    if n <= 1 {\n        return n;\n    }\n\n    fibonacci(n - 1) + fibonacci(n - 2)\n}\n\nfn fibonacci_memoization(n: usize) -> u128 {\n    let mut memo: Vec<u128> = vec![0; n + 1];\n\n    fibonacci_memoization_aux(n, &mut memo)\n}\n\nfn fibonacci_memoization_aux(n: usize, memo: &mut Vec<u128>) -> u128 {\n    if n <= 1 {\n        return n as u128;\n    }\n\n    if memo[n] == 0 {\n        memo[n] = fibonacci_memoization_aux(n - 1, memo) + fibonacci_memoization_aux(n - 2, memo);\n    }\n\n    memo[n]\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/rust/troleomotor10.rs",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n*/\n\nfn main(){\n    // Función recursiva\n    fn countdown(number: i32) {\n\n        if number > 0 {\n            println!(\"{}\", number);\n            countdown(number - 1)\n        }\n    }\n    countdown(100);\n\n    // EJERCICIO EXTRA\n    // Numero factorial\n    fn factorial(number: i32) -> i32 {\n        if number < 0 {\n            println!(\"Los números negativos no están permitidos\");\n            return 0;\n        } else if number == 0 {\n            return 1;\n        }\n        \n        number * factorial(number - 1)\n    }\n    println!(\"El resultado de la factorial es: {}\", factorial(5));\n\n    // Sucesión Fibonacci\n    fn fibonacci(position: i32) -> i32{\n        if position <= 0 {\n            println!(\"Los números negativos no están permitidos\");\n            return 0;\n        } else if position == 1 {\n            return 0;\n        } else if position == 2 {\n            return 1;\n        } else {\n            fibonacci(position - 1) + fibonacci(position - 2)\n        }\n    }\n    println!(\"El numero en la sucesión de fibonacci es: {}\", fibonacci(10));\n}"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/scala/rianojnicolas.scala",
    "content": "/*###################################\n#   Dev: rianojnicolas              #\n###################################*/\n\nobject Source6 {\n    def main(args: Array[String]): Unit = {\n        // EJERCICIO\n\n        // 1. FUNCION RECURSIVA QUE IMPRIME NÚMEROS DEL 100 AL 0\n        def print_numbers(n: Int) : Unit = {\n            if (n >= 0) {\n                println(n)\n                print_numbers(n-1)\n            }\n        }\n        print_numbers(100) // Imprime los números del 100 al 0\n\n        // DIFICULTAD EXTRA\n        // 1. FUNCION QUE CALCULE EL FACTORIAL DE UN NÚMERO\n        def calc_factorial(n:Int): Int = {\n            if (n == 0) {\n                return 1\n            }\n            else {\n                return n*calc_factorial(n-1)\n            }\n        }\n\n        println(calc_factorial(5))  // Imprime el factorial de 5 = 120\n\n        // 2. FUNCION QUE CALCULE UN ELEMENTO EN LA SUCESIÓN DE FIBONACCI SEGUN SU POSICIÓN\n        // Secuencia -> 0, 1, 1, 2, 3, 5, 8, 13\n        // Posición ->  0, 1, 2, 3, 4, 5, 6, 7\n        def calc_fibonacci(pos:Int): Int = {\n            if(pos == 0){\n                return 0\n            }\n            else if (pos == 1) {\n                return 1\n            }\n            else {\n                return calc_fibonacci(pos-1) + calc_fibonacci(pos-2)\n            }\n        }\n        println(calc_fibonacci(6)) // Imprime el valor de la posición 6 = 8\n    }\n}"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/sql/Nicojsuarez2.sql",
    "content": "# #06 RECURSIVIDAD\n> #### Dificultad: Difícil | Publicación: 05/02/24 | Corrección: 12/02/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/swift/18miguelgalarza.swift",
    "content": "//: [Previous](@previous)\n\n/* 18miguelgalarza.swift Release #06 - swift\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la\n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\n\nimport Foundation\n\nvar greeting = \"Hello, playground\"\n\n//: [Next](@next)\n\n\nfunc imprimeNumero(_ n: Int) -> Int{\n    print(n)\n    if n == 0 {\n        return 1 // Caso base\n    } else {\n        return imprimeNumero(n-1)\n    }\n}\n\n\nimprimeNumero(100)\n\n\nfunc factorial(_ n: Int) -> Int {\n    if n == 0 {\n        return 1 // Caso base\n    } else {\n        return n * factorial(n - 1) // Caso recursivo\n    }\n}\n\nprint(factorial(5)) // Output: 120 (5 * 4 * 3 * 2 * 1)\n\n\nfunc fibonacci(_ n: Int) -> Int {\n    if n <= 1 {\n        return n // Caso base: si n es 0 o 1, devuelve n\n    } else {\n        return fibonacci(n - 1) + fibonacci(n - 2) // Caso recursivo: devuelve la suma de los dos números Fibonacci anteriores\n    }\n}\n\nprint(fibonacci(7)) // Output: 13 (0, 1, 1, 2, 3, 5, 8, 13)\n\n\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/swift/PineroDev.swift",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la\n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\n\nfunc impNumRecursivo(num: Int) {\n    if num >= 0 {\n        print(num)\n        impNumRecursivo(num: num - 1)\n    }\n}\n\nimpNumRecursivo(num: 100)\n\n\nfunc CalFactorial(num: Int) -> Int {\n    guard num > 1 else {\n        return 1\n    }\n    return num * CalFactorial(num: num - 1)\n}\n\nprint(CalFactorial(num: 5))\n\nfunc fibonacci(_ num: Int) -> Int {\n    if num <= 0 {\n        return 0\n    }else if num == 1 {\n        return 0\n    }else if num == 2 {\n        return 1\n    }else{\n        return fibonacci(num - 1) + fibonacci(num - 2)\n    }\n}\n\nprint(fibonacci(11))\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/swift/allbertoMD.swift",
    "content": "import Foundation \n\n\n\n// Función Recursiva Que Imprime Los Numeros Del 100 al 0\nfunc recursiveFunction(number num: Int = 100) {\n    if num == 0 {  // Si num es igual a 0, imprime num.\n        print(num)\n    } else {\n        print(num)  // Imprime num.\n        recursiveFunction(number: num - 1)  // Llama recursivamente a la función con num decrementado en 1.\n    }\n}\nrecursiveFunction()  // Llama a la función con el valor por defecto (100).\n\n\n// Función Recursiva Que Calcula el Factorial de un Numero\nfunc calculateTheFactorial(number num: Int) -> Int {\n    if num == 0 {  // Si num es igual a 0, devuelve 1.\n        return 1\n    } else {\n        return num * calculateTheFactorial(number: num - 1)  // Devuelve num multiplicado por el factorial de num - 1.\n    }\n}\nlet factorialNumber = calculateTheFactorial(number: 5)  // Calcula el factorial de 5.\nprint(factorialNumber)  // Imprime el resultado.\n\n\n// Función Recursiva que Calcula la Posición de un Numero en la Secuencia Fibonacci\nvar secuence = [0, 1]  // Inicializa una secuencia Fibonacci con los dos primeros números.\nvar stepper1 = 0  // Inicializa el primer índice de la secuencia.\nvar stepper2 = 1  // Inicializa el segundo índice de la secuencia.\nfunc calculateFibonacci(number num: Int) -> Int {\n    if num == 0 {  // Si num es igual a 0, no hace nada.\n        \n    } else {\n        // Añade el siguiente número en la secuencia Fibonacci a la lista.\n        secuence.append(secuence[(num - num) + stepper1] + secuence[(num - num) + stepper2])\n        stepper1 += 1  // Incrementa el primer índice.\n        stepper2 += 1  // Incrementa el segundo índice.\n        _ = calculateFibonacci(number: num - 1)  // Llama recursivamente a la función con num decrementado en 1.\n    }\n    return secuence[stepper1 - 1]  // Devuelve el número en la posición num de la secuencia Fibonacci.\n}\nlet fibonacciPosition = calculateFibonacci(number: 10)  // Calcula el número en la posición 10 de la secuencia Fibonacci.\nprint(fibonacciPosition)  // Imprime el resultado.\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/swift/blackriper.swift",
    "content": "\nfunc counterReversed(n: Int){\n    if n > 0 {\n        print(n)\n        counterReversed(n: n - 1)\n    }\n}\ncounterReversed(n: 100)\n\nfunc factorialNumber(n: Int) -> Int {\n    if n == 0 {\n        return 1\n    }\n    return n * factorialNumber(n: n - 1)\n}\nprint(factorialNumber(n: 5))\n\n\nfunc fibonacciNumber(n: Int) -> Int {\n    if n == 0 || n == 1 {\n        return 1\n    }\n    return fibonacciNumber(n: n - 1) + fibonacciNumber(n: n - 2)\n}\nprint(fibonacciNumber(n: 5))"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/swift/didacdev.swift",
    "content": "import Foundation\n\nfunc factorial(number: Int) -> Int{\n\n    if number == 0 {\n        return 1\n    } else {\n        let i = factorial(number: number - 1)\n\n        return number * i\n    }\n}\n\nlet number = 5\nprint(\"El factorial de \\(number) es \\(factorial(number: number))\")\n\nfunc fibonacci(position: Int) -> Int {\n\n    if position <= 2 {\n        return 1\n    } else {\n        let i = fibonacci(position: position - 1)\n        let j = fibonacci(position: position - 2)\n        return j + i\n    }\n}\n\nlet position = 4\nprint(\"El valor de la posición \\(position) en la secuencia de Fibonacci es \\(fibonacci(position: position))\")\n\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/swift/gliadev.swift",
    "content": "import Foundation\n\n/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n */\n\nfunc imprimirNumerosRecursivos(numero: Int){\n    if numero < 0 {\n        return\n    }\n    print(numero)\n    \n    imprimirNumerosRecursivos(numero: numero - 1)\n}\n\n\nimprimirNumerosRecursivos(numero: 100)\n\n\n\n\n\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la\n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\n// calculamos el factorial de un numero. Le pasamos el numero que queremos calcular\n// y se lo pasamos en la funcion pero\nfunc factorial(numero: Int) -> Int {\n    if numero == 0 { // si el numero es 0 devuelve 1\n        return 1\n    } else {\n        return numero * factorial(numero: numero - 1)\n    }\n}\n\nlet numero = 9\nprint(\"El factorial de \\(numero) es  \\(factorial(numero: numero))\")\n\n\nfunc fibonacci(_ n: Int) -> Int {\n    if n <= 0 {\n        return 0\n    } else if n == 1 {\n        return 1\n    } else {\n        return fibonacci(n - 1) + fibonacci(n - 2)\n    }\n}\n\nlet posicion = 5\nprint(\"El elemento en la posición \\(posicion) de la sucesión de Fibonacci es \\(fibonacci(posicion))\")\n\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/swift/juanppdev.swift",
    "content": "import Foundation\n\nfunc printNumbers(_ n: Int) {\n    if n < 0 {\n        return\n    }\n    \n    print(n)\n    printNumbers(n - 1)\n}\n\nprintNumbers(100)\n\n\n// Función para calcular el factorial de un número\nfunc factorial(_ n: Int) -> Int {\n    if n == 0 {\n        return 1\n    } else {\n        return n * factorial(n - 1)\n    }\n}\n\n// Función para calcular el valor de un elemento en la sucesión de Fibonacci\nfunc fibonacci(_ n: Int) -> Int {\n    if n <= 1 {\n        return n\n    } else {\n        return fibonacci(n - 1) + fibonacci(n - 2)\n    }\n}\n\n// Prueba de las funciones\nlet numFactorial = 5\nlet numFibonacci = 6\n\nprint(\"El factorial de \\(numFactorial) es: \\(factorial(numFactorial))\")\nprint(\"El valor en la posición \\(numFibonacci) de Fibonacci es: \\(fibonacci(numFibonacci))\")\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/swift/karys4.swift",
    "content": "/*\nEJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n*/\n\nfunc myRecursiveFunction(number: Int) {\n  print(number)\n\n  if number == 0 {\n  print(\"End of the exercise\")\n  } else {\n    myRecursiveFunction(number: number - 1)\n  }\n}\n\nmyRecursiveFunction(number:100)"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/swift/kontroldev.swift",
    "content": "import Foundation\n\n/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la\n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\n\n// Función recursiva que imprime números del 100 al 0\nfunc imprimirNumeros(numero: Int) {\n  // Caso base: si el número es 0, lo imprimimos y terminamos\n  if numero == 0 {\n    print(numero)\n    return\n  }\n  // Caso recursivo: si el número es mayor que 0, lo imprimimos y llamamos a la función con el número menos 1\n  else if numero > 0 {\n    print(numero)\n    imprimirNumeros(numero: numero - 1)\n  }\n}\n\n\n// Función recursiva que calcula el factorial de un número\nfunc factorial(numero: Int) -> Int {\n  // Caso base: si el número es 1, devolvemos 1\n  if numero == 1 {\n    return 1\n  }\n  // Caso recursivo: si el número es mayor que 1, devolvemos el número multiplicado por el factorial del número menos 1\n  else if numero > 1 {\n    return numero * factorial(numero: numero - 1)\n  }\n  // Si el número es menor que 1, devolvemos un error\n  else {\n    return -1\n  }\n}\n\n\n// Función recursiva que calcula el valor de un elemento en la sucesión de Fibonacci\nfunc fibonacci(posicion: Int) -> Int {\n  // Caso base: si la posición es 1 o 2, devolvemos 1\n  if posicion == 1 || posicion == 2 {\n    return 1\n  }\n  // Caso recursivo: si la posición es mayor que 2, devolvemos la suma de los valores de las posiciones anteriores\n  else if posicion > 2 {\n    return fibonacci(posicion: posicion - 1) + fibonacci(posicion: posicion - 2)\n  }\n  // Si la posición es menor que 1, devolvemos un error\n  else {\n    return -1\n  }\n}\n\n\n\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/swift/lordzzz.swift",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la\n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\nimport Foundation\n\n\n// recursividad\nfunc recursiva(numero: Int){\n   \n    print(numero )\n   \n    if numero > 0 {\n        recursiva(numero: numero - 1)\n        \n    }\n}\nrecursiva(numero: 100)\n\n// Numero Factorial\nfunc factorial(_ numeros: Int) -> Int{\n    if numero < 1 {\n        return 1\n    }else  {\n        return numero * factorial(numero - 1)\n    }\n    \n}\nlet numero = 5\nvar result = factorial(numero)\nprint(\"Fatorial de \\(numero) es \\(result)\")\n\n\n// Fibonacci\nfunc scesionFibonacci(_ posicion: Int) -> Int {\n    if posicion <= 1{\n        return posicion\n    }else {\n        return scesionFibonacci(posicion - 1) + scesionFibonacci(posicion - 2)\n    }\n}\nlet posicion = factorial(numero)\nlet valorFibonacci = scesionFibonacci(posicion)\nprint(\"el valor en la posición \\(posicion) de la sucesión de Fibonacci es \\(valorFibonacci)\")\n\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/swift/miguelex.swift",
    "content": "import Foundation\n\nfunc sumaRecursiva(a: Int, b: Int) -> Int {\n    if b == 0 {\n        return a\n    } else {\n        return sumaRecursiva(a: a + 1, b: b - 1)\n    }\n}\n\nprint(\"La suma de 5 +3 usando recursividad es = \" +  String(sumaRecursiva(a: 5, b: 3)))\n\nfunc potenciaRecursiva(base: Int, exponente: Int) -> Int {\n    if exponente == 0 {\n        return 1\n    } else {\n        return base * potenciaRecursiva(base: base, exponente: exponente - 1)\n    }\n}\n\nprint(\"La potencia de 2^3 usando recursividad es = \" +  String(potenciaRecursiva(base: 2, exponente: 3)))\n\nfunc imprimirNumeros(_ numero: Int) {\n    if numero >= 0 {\n        print(numero, terminator: \" \")\n        imprimirNumeros(numero - 1)\n    }\n}\n\nprint(\"De 100 a 0 usando rercursividad: \")\nimprimirNumeros(100)\n\n// Extra\n\nfunc factorialRecursivo(numero: Int) -> Int {\n    if numero == 0 {\n        return 1\n    } else {\n        return numero * factorialRecursivo(numero: numero - 1)\n    }\n}\n\nprint(\"El factorial de 5 usando recursividad es = \" +  String(factorialRecursivo(numero: 5)))\n\nfunc fibonacciRecursivo(posicion: Int) -> Int {\n    if posicion == 0 {\n        return 0\n    } else if posicion == 1 {\n        return 1\n    } else {\n        return fibonacciRecursivo(posicion: posicion - 1) + fibonacciRecursivo(posicion: posicion - 2)\n    }\n}\n\nprint(\"El fibonacci de la posicion 5 usando recursividad es = \" +  String(fibonacciRecursivo(posicion: 5)))\n\n// Vamos a continuación a probar las funcioens de factorial y fibonacci de forma iteractiva, pidiendo al usuario que introduzca el número para el factorial y la posición para el fibonacci\n\nprint(\"Introduce un número para calcular su factorial\")\nlet numeroFactorial = Int(readLine()!)!\nprint(\"El factorial de \\(numeroFactorial) es = \" +  String(factorialRecursivo(numero: numeroFactorial)))\n\nprint(\"Introduce una posición para calcular el fibonacci\")\nlet posicionFibonacci = Int(readLine()!)!\nprint(\"El fibonacci de la posición \\(posicionFibonacci) es = \" +  String(fibonacciRecursivo(posicion: posicionFibonacci)))\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/swift/pedroomar23.swift",
    "content": "import Foundation\n\n/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\n// Recursividad \nlet number = 0\n\nfunc recurso(number: Int) {\n    if number == 0 {\n        return \n\n        print(number)\n    } else if number > 0 {\n        return recurso(number: number - 1)\n\n        print(number)\n    }\n}\n\n\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/swift/zetared92.swift",
    "content": "import Foundation\n// Reto #06 RECURSIVIDAD\n\n// Función recursiva que imprima nº del 100 al 0\nfunc printNum(_ num: Int) {\n    if num >= 0 {\n        print(num, terminator: \" \")\n        printNum(num - 1)\n    }\n}\n\nprint(\"Print numbers 100-0 with recursive function: \")\nprintNum(100)\n\n// 🧩 DIFICULTAD EXTRA 🧩\n// Calcular el factorial de un número concreto\nfunc factorialNum(num: Int) -> Int {\n    if num == 0 {\n        return 1\n    } else {\n        return num * factorialNum(num: num - 1)\n    }\n}\n\nprint(\"The factorial of 18 using recursion is = \" +  String(factorialNum(num: 8)))\n\n// Cálculo de un valor concreto (según posición) en la serie Fibonacci\nfunc recursiveFibonacci(position: Int) -> Int {\n    if position == 0 {\n        return 0\n    } else if position == 1 {\n        return 1\n    } else {\n        return recursiveFibonacci(position: position - 1) + recursiveFibonacci(position: position - 2)\n    }\n}\n\nprint(\"The value of the sixth position of the Fibonacci series using recursion is: = \" +  String(recursiveFibonacci(position: 6)))\n\n// 1-1-2-3-5-8"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/tcl/713avo.tcl",
    "content": "#!/usr/bin/tclsh\n\n# EJERCICIO:\n# Entiende el concepto de recursividad creando una función recursiva que imprima\n# números del 100 al 0.\n\nset NUMBER 5\n\nproc recuproc { NUM } {\n\t\tif { $NUM <= 0 } {\n\t\t\treturn\n\t\t} else {\n\t\t\tputs $NUM\t\n\t\t\trecuproc [ expr $NUM - 1 ]\n\t\t}\n}\nrecuproc $NUMBER ; # Ejemplo de uso \n\n#######################\n# DIFICULTAD EXTRA (opcional):\n# Utiliza el concepto de recursividad para \n# - Calcular el factorial de un número concreto (la función recibe ese número).\n# - Calcular el valor de un elemento concreto (según su posición) en la \n# sucesión de Fibonacci (la función recibe la posición).\n########################\n\nproc factorial { NUM } {\n\t\tif { $NUM  == 1} {\n\t\t\treturn 1\n\t\t} else {\n\t\t\treturn [ expr $NUM * [ factorial [ expr $NUM - 1 ] ] ]  \n\t\t}\n} \nputs [ factorial $NUMBER ] ; # Ejemplo de uso \n\n#######################\n\nproc fibonacci { NUM } {\n\tif { $NUM == 0 } {\n\t\treturn 0\n\t} elseif { $NUM == 1} {\n\t\treturn 1\n\t} else { \n\t\treturn [ expr [ fibonacci [ expr $NUM - 1 ] ] + [ fibonacci [ expr $NUM - 2 ] ] ]\n\t}\n}\n\nputs [ fibonacci  8 ] ; # Ejemplo de  uso\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/typescript/AChapeton.ts",
    "content": "const recursiveFunction = (value: number): void => {\n  console.log(value)\n  if(value === 0){\n    return\n  }\n  else{\n    recursiveFunction(value - 1)\n  }\n}\n\nrecursiveFunction(100)\n\nconst obtenerFactorial = (factorial: number): number => {\n  if(factorial < 0){\n    return -1\n  }else if (factorial === 0){\n    return 1\n  }else {\n    return (factorial * obtenerFactorial(factorial - 1))\n  }\n}\n\nconsole.log('factorial: ', obtenerFactorial(10))\n\nconst fibonacci = (position: number): number => {\n  if(position <= 1) return 1\n  const result = fibonacci(position - 1) + fibonacci(position - 2)\n  return result\n}\n\nconsole.log('fibonacci: ', fibonacci(5))\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/typescript/EdiedRamos.ts",
    "content": "// Author: EdiedRamos\n\nfunction countdownToZero(value: number): void {\n  if (value < 0) return;\n  console.log(value);\n  countdownToZero(value - 1);\n}\n\nfunction factorial(value: number): number {\n  if (value < 0)\n    throw new Error(\n      \"No se puede calcular el factorial para números negativos.\"\n    );\n  return value === 0 ? 1 : value * factorial(value - 1);\n}\n\nfunction fibonacci(value: number, memo: Record<number, number> = {}): number {\n  if (value < 2) return value;\n  if (memo[value]) return memo[value];\n  return (memo[value] =\n    fibonacci(value - 1, memo) + fibonacci(value - 2, memo));\n}\n\n(() => {\n  // Numbers from 100 to zero\n  console.log(\"Número desde el 100 hasta el cero\");\n  countdownToZero(100);\n\n  // Factorial test\n  const factorial5 = factorial(5);\n  console.assert(factorial5 === 120);\n  console.log(\"Factorial de 5: \" + factorial5);\n\n  // Fibonacci test\n  const fibo60 = fibonacci(60);\n  console.assert(fibo60 === 1548008755920);\n  console.log(\"Valor de fibonacci en la posición 6: \" + fibo60);\n})();\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/typescript/Igledev.ts",
    "content": "// Ejercicio 1º\n    function recursiva(num : number) : void{\n        if(num < 0){\n            return;\n        }\n        console.log(num);\n\n        recursiva(num - 1);\n    }\n\n// Ejercicio Extra\n    // Factorial\n        function calcularFactorial(numero : number) : number{\n            if(numero === 1 || numero === 0){\n                return 1;\n            }\n\n            return numero * calcularFactorial(numero - 1);\n        }\n\n        let numeroFactorial : number = 5;\n        console.log(calcularFactorial(numeroFactorial));\n\n    // Fibonnacci\n        function calcularFibonacci(num : number){\n            if(num <= 1){\n                return 1;\n            }\n\n            return calcularFibonacci(num - 1) + calcularFibonacci(num - 2);\n        }\n\n        let posicion : number = 6;\n        console.log('La ' + posicion + 'º posición es: ' + calcularFibonacci(posicion));"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/typescript/RicJDev.ts",
    "content": "//EJERCICIO\nconsole.log('\\nNÚMEROS DEL 100 AL 0')\nfunction countdown(n: number): void {\n\tif (n >= 0) {\n\t\tconsole.log(n)\n\n\t\tcountdown(n - 1)\n\t}\n}\n\ncountdown(100)\n\n//EXTRA\nconsole.log('\\nFACTORIALES')\nfunction getFactorial(num: number): number {\n\tif (num < 0) {\n\t\tconsole.log('Número no válido')\n\n\t\treturn 0\n\t} else if (num === 0) {\n\t\treturn 1\n\t} else {\n\t\treturn num * getFactorial(num - 1)\n\t}\n}\n\nconsole.log(getFactorial(5))\n\nconsole.log('\\nSUCESIÓN DE FIBONACCI')\nfunction fibonacciAt(position: number): number {\n\tif (position <= 0) {\n\t\tconsole.log('Número no válido')\n\n\t\treturn 0\n\t} else if (position === 1) {\n\t\treturn 0\n\t} else if (position === 2) {\n\t\treturn 1\n\t} else {\n\t\treturn getFactorial(position - 1) + fibonacciAt(position - 2)\n\t}\n}\n\nconsole.log(fibonacciAt(5))\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/typescript/RobertoAmaroHub.ts",
    "content": "//función recursiva, se llama así misma hasta que cumple la condición que se le pide\nfunction recursiva(_count:number){\n    let count:number=_count;\n    console.log(count);\n    count--;\n    if(count>=0){\n        recursiva(count);\n    }\n}\nrecursiva(100);\n\n//EXTRA\nlet numero:number=7;\nfunction getfactorial(num:number){\n    if(num==0){\n        return 1;\n    } \n    return num * getfactorial(num-1);\n}\n\nfunction getFibonacci(posicion:number){\n    if(posicion<=1){\n        return posicion;\n    } \n    return getFibonacci(posicion-1)+getFibonacci(posicion-2);\n}\n\nconsole.log(`la posición ${numero} de fibonacci es ${getFibonacci(numero)}`)\nconsole.log(`el factorial de ${numero} es ${getfactorial(numero)}`);"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/typescript/Sac-Corts.ts",
    "content": "function printNumbers(num: number): void {\n    if (num < 0) return;\n        console.log(num);\n        printNumbers(num - 1);\n}\n\nprintNumbers(100);\n\n// *** Extra Exercise *** //\nfunction factorial(n: number): number {\n    if (n <= 1) {\n        return 1;\n    } \n    return n * factorial(n - 1);\n}\n\nconsole.log(factorial(5));\n\nfunction fibonacci(n: number): number {\n    if (n <= 1) return n; \n    return fibonacci(n - 1) + fibonacci(n - 2); \n}\n\n\nconsole.log(fibonacci(4));"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/typescript/Sharah07.ts",
    "content": "// Función recursiva: \n//Estas funciones tienen un caso base (condición que al cumplirse detiene la función)\n// y un caso recursivo (caso que modifica el argumento con cada llamada a la función)\n// Esta función se llama a si misma repetidamente cambiando su argumento \n// según se especifique hasta cumplir su caso base.\n// Esto no modifica el argumento fuera de la función.\n\nfunction recursiva(num) { // el argumento es 5\n    if(num < 0) return;\n    console.log(num);\n    return recursiva(--num); // ahora el argumento pasa a valer 4 (solo dentro de la función) y tras cada llamada se decrementa \n}\nrecursiva(100);\n\n//Extra:\n//Calcular factorial.\n\nfunction factorial(num):number{\n    if(num < 0){\n        console.log('Valor no valido') \n        return 0;  \n    } \n    if(num == 1 || num == 0) return 1;\n    return num * factorial(num - 1); //Mientras la función se llama a si misma, \n    // únicamente realiza la reducción del argumento(num-1) que se almacena en la pila de ejecución, \n    // 5 4 3 2 1(el caso base retorna 1) al llegar al caso base empieza el proceso de \n    // retorno(realiza la operación de retorno) en orden inverso y retorna el resultado.  \n\n}\nconsole.log(factorial(5));\n\n\nfunction fibonacci(num:number):number{\n    if(num <= 0){\n        console.log('Posición invalida');\n        return 0;\n    } \n    if(num <= 2) return num-1;\n    return fibonacci(num-1) + fibonacci(num-2);\n\n}\n\nconsole.log(fibonacci(6));\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/typescript/david-git-dev.ts",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la\n *   sucesión de Fibonacci (la función recibe la posición).\n */\nfunction oneHundredToZero(count:number){\n  if(count<0){\n    return 0;\n  }\n  console.log(count)\noneHundredToZero(count-1);\n}\nfunction factorial(n: number):number {\n  if (n <= 1) {\n    console.log(n);\n    return 1;\n  }\n  console.log(n);\n  return n * factorial(n - 1);\n}\nfunction fibonacci(n: number):number {\n  if (n <= 1) {\n    return n;\n  }\n  let res = fibonacci(n - 1) + fibonacci(n - 2);\n  return res;\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/typescript/duendeintemporal.ts",
    "content": "// #06  { Retosparaprogramadores }  Recursividad  \n// I use Eloquent Javascript A Modern Introduction to Programming by Marijn Haverbeke for concepts reference.\n// I also use Professional JavaScript for web developers by Matt Frisbie.\n// and GPT\n\n// short for console.log()\nlet log = console.log;\n\n// A recursive function typically is formed when a function calls itself by name\n\nconst countBack = (n: number): void=>{\n   log(n);\n   if(n != 0) countBack(n - 1);\n}\n\nlog(countBack(100)) // print the numbers from 100 to 0\n\n\n// without recursion\n\nconst power_v1 = (base: number, exponent: number): number => {\n   let result: number; \n    (exponent == 0)? result = 1 : result = base;\n    for(let i = 2; i <= exponent; i++){\n        result *=  base; \n    }\n    return result;\n} \n\nlog(power_v1(4,3)); // 64\n\n// with recursion\n\nconst power = (base: number, exponent: number): number => {\n    if (exponent == 0) {\n        return 1;\n    } else {\n        return base * power(base, exponent - 1);\n    }\n}\n\nlog(power(4, 3)); // 64\n\n/* This is rather close to the way mathematicians define exponentiation and\narguably describes the concept more clearly than the looping variant. The\nfunction calls itself multiple times with ever smaller exponents to achieve the\nrepeated multiplication.\n\nBut this implementation has one problem: in typical JavaScript implementa-\ntions, it’s about three times slower than the looping version. Running through\na simple loop is generally cheaper than calling a function multiple times. \n\nIn the case of the power function, the inelegant (looping) version is still fairly\nsimple and easy to read. It doesn’t make much sense to replace it with the\nrecursive version\n*/\n\n// Extra dificulty exercises\n\nconst factorial = (n: number): number =>{\n    if(n <= 1) return 1;\n    return n * factorial(n - 1);\n}\n\nlog(factorial(5))// 120\n\n// this function return the serie fibonacci until the number passed as parameter\nconst fibonacciSerie = (n: number, a: number = 0, b: number = 1): number[] => {\n    if (a > n) {\n        return [];\n    } else {\n        return [a].concat(fibonacciSerie(n, b, a + b));\n    }\n}\n\n\nlog(fibonacciSerie(17)); // Array(8) [ 0, 1, 1, 2, 3, 5, 8, 13 ]\n\n//this function return the number equivalent to the possition in the fibonacci serie\n\nconst fibonacciNum = (n: number): number => {\n    if (n === 0) {\n        return 0;\n    }\n    if (n === 1) {\n        return 1;\n    }\n    return fibonacciNum(n - 1) + fibonacciNum(n - 2);\n  }\n\n  log(fibonacciNum(17))// 1597\n\n/* Note: The recursive version with memoization is more efficient than the simple recursive one, as it avoids redundant calculations. However, it still uses the call stack, which can be a problem for very large values of a.*/\n\nconst fibonacciNumMemo = (n: number, memo: {} = {})=> {\n    if (n in memo) {\n        return memo[n];\n    }\n    if (n === 0) {\n        return 0;\n    }\n    if (n === 1) {\n        return 1;\n    }\n    memo[n] = fibonacciNumMemo(n - 1, memo) + fibonacciNumMemo(n - 2, memo);\n    return memo[n];\n}\n\nlog(fibonacciNumMemo(17)); // 1597\n\n\n/* The iterative approach is generally more efficient in terms of time and space, as it does not use the call stack of recursion. */\n\nconst iterativeFibonacci = (n: number): number => {\n    if (n === 0) return 0;\n    if (n === 1) return 1;\n\n    let a = 0;\n    let b = 1;\n    let resultado;\n\n    for (let i = 2; i <= n; i++) {\n        resultado = a + b;\n        a = b;\n        b = resultado;\n    }\n    return resultado;\n}\n\nlog(iterativeFibonacci(4222)); // infinity\nlog(iterativeFibonacci(453))// 2.0985341020594266e+94  \n\n\n\n    log( 'Retosparaprogramadores #6'); // Retosparaprogramadores #6 \n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/typescript/eulogioep.ts",
    "content": "/**\n * Función recursiva para imprimir números del 100 al 0.\n * @param numero El número actual a imprimir.\n */\nfunction imprimirNumeros(numero: number): void {\n    // Caso base: si el número es menor que 0, terminamos la recursión\n    if (numero < 0) {\n        return;\n    }\n    \n    // Imprimimos el número actual\n    console.log(numero);\n    \n    // Llamada recursiva con el número decrementado\n    imprimirNumeros(numero - 1);\n}\n\n/**\n * Función recursiva para calcular el factorial de un número.\n * @param n El número del cual calcular el factorial.\n * @returns El factorial del número.\n */\nfunction factorial(n: number): number {\n    // Casos base: factorial de 0 y 1 es 1\n    if (n === 0 || n === 1) {\n        return 1;\n    }\n    \n    // Llamada recursiva: n * factorial(n-1)\n    return n * factorial(n - 1);\n}\n\n/**\n * Función recursiva para calcular el valor de un elemento en la sucesión de Fibonacci.\n * @param posicion La posición del elemento en la sucesión de Fibonacci.\n * @returns El valor del elemento en la posición dada.\n */\nfunction fibonacci(posicion: number): number {\n    // Casos base: posiciones 0 y 1 de Fibonacci son 0 y 1 respectivamente\n    if (posicion === 0) {\n        return 0;\n    }\n    if (posicion === 1) {\n        return 1;\n    }\n    \n    // Llamada recursiva: suma de los dos elementos anteriores\n    return fibonacci(posicion - 1) + fibonacci(posicion - 2);\n}\n\n// Pruebas de las funciones\nconsole.log(\"Números del 100 al 0:\");\nimprimirNumeros(100);\n\nconst numeroFactorial: number = 5;\nconsole.log(`\\nFactorial de ${numeroFactorial}: ${factorial(numeroFactorial)}`);\n\nconst posicionFibonacci: number = 7;\nconsole.log(`Elemento en la posición ${posicionFibonacci} de Fibonacci: ${fibonacci(posicionFibonacci)}`);"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/typescript/hozlucas28.ts",
    "content": "/*\n    Recursive function...\n*/\n\nconsole.log('\\nRecursive function...')\n\nfunction recursiveFn(from: number, to: number, rtn: number[]) {\n\tif (from < to) return rtn\n\trtn.push(from)\n\trecursiveFn(from - 1, to, rtn)\n}\n\nconsole.log(`\\nfunction recursiveFn(from: number, to: number, rtn: number[]) {\n    if (from < to) return rtn\n    rtn.push(from)\n    recursiveFn(from - 1, to, rtn)\n}`)\n\nconst recursiveRtn: number[] = []\nrecursiveFn(100, 0, recursiveRtn)\n\nconsole.log(`\\nrecursiveFn(100, 0, recursiveRtn)`)\nconsole.log(`\\nrecursiveRtn --> [${recursiveRtn}]`)\n\nconsole.log('\\n# ---------------------------------------------------------------------------------- #\\n')\n\n/*\n    Additional challenge...\n*/\n\nconsole.log('Get factorial...')\n\nfunction getFactorial(n: number): number {\n\tif (n === 1) return 1\n\treturn n * getFactorial(n - 1)\n}\n\nconsole.log(`\\nfunction getFactorial(n: number): number {\n    if (n === 1) return 1\n    return n * getFactorial(n - 1)\n}`)\n\nconsole.log(`\\ngetFactorial(5) --> ${getFactorial(5)}`)\n\nconsole.log('\\n# ---------------------------------------------------------------------------------- #\\n')\n\nconsole.log('Get Fibonacci value by position...')\n\nfunction getFibonacciValueByPos(posicion: number): number {\n\tif (posicion === 1 || posicion === 2) {\n\t\treturn 1\n\t}\n\n\treturn getFibonacciValueByPos(posicion - 1) + getFibonacciValueByPos(posicion - 2)\n}\n\nconsole.log(`\\nfunction getFibonacciValueByPos(posicion: number): number {\n    if (posicion === 1 || posicion === 2) {\n        return 1\n    }\n\n    return getFibonacciValueByPos(posicion - 1) + getFibonacciValueByPos(posicion - 2)\n}`)\n\nconsole.log(`\\ngetFibonacciValueByPos(8) --> ${getFibonacciValueByPos(8)}`)\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/typescript/ialmontedr0.ts",
    "content": "/*\r\n * EJERCICIO:\r\n * Entiende el concepto de recursividad creando una función recursiva que imprima\r\n * números del 100 al 0.\r\n *\r\n * DIFICULTAD EXTRA (opcional):\r\n * Utiliza el concepto de recursividad para:\r\n * - Calcular el factorial de un número concreto (la función recibe ese número).\r\n * - Calcular el valor de un elemento concreto (según su posición) en la\r\n *   sucesión de Fibonacci (la función recibe la posición).\r\n */\r\n\r\n// Función para imprimir números del 100 al 0\r\nfunction countDown(numero: number) {\r\n  if (numero >= 0) {\r\n    console.log(numero);\r\n    countDown(numero - 1);\r\n  }\r\n}\r\n\r\ncountDown(100);\r\n\r\n// Funcion extra: calcular el factorial de un número\r\nfunction calculoFactorial(n: number): number {\r\n  if (n < 0) {\r\n    console.log(\"Los numeros negativos no son validos\");\r\n    return 0;\r\n  } else if (n == 0) {\r\n    return 1;\r\n  } else {\r\n    return n * calculoFactorial(n - 1);\r\n  }\r\n}\r\n\r\nconsole.log(calculoFactorial(5)); // Debería imprimir 120\r\n\r\n// Funcion extra: calcular valor de un elememnto (Fibonacci)\r\nfunction calculoFibonacci(num: number): number {\r\n  if (num <= 0) {\r\n    console.log(\"La posicion debe ser mayor que cero\");\r\n    return 0;\r\n  } else if (num == 1) {\r\n    return 0;\r\n  } else if (num == 2) {\r\n    return 1;\r\n  } else {\r\n    return calculoFibonacci(num - 1) + calculoFibonacci(num - 2);\r\n  }\r\n}\r\n\r\nconsole.log(calculoFibonacci(5));\r\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/typescript/jesusEs1312.ts",
    "content": "// Función recursiva que imprime los números del 100 al 0\nconst imprimirNumeros = (numero: number) => {\n    if (numero >= 0) {\n        console.log(numero);\n        imprimirNumeros(numero - 1);\n    }\n};\n\n// Función recursiva que calcula el factorial de un número\nconst factorial = (numero: number): number => {\n    if (numero === 0) {\n        return 1;\n    }\n    return numero * factorial(numero - 1);\n}\n\n// Función recursiva que calcula el número de la serie de Fibonacci\nconst fibonacci = (numero: number): number => {\n    if (numero === 0) {\n        return 0;\n    }\n    if (numero === 1) {\n        return 1;\n    }\n    return fibonacci(numero - 1) + fibonacci(numero - 2);\n}\n\n// Llamada a las funciones\nimprimirNumeros(10);\nconsole.log(factorial(5));\nconsole.log(fibonacci(10));"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/typescript/jonadev19.ts",
    "content": "/**\n * Imprime los números desde el número inicial hasta 0 de forma recursiva.\n *\n * @param startNumber - El número desde el cual comenzar a imprimir.\n * @returns void - No devuelve nada, solo imprime los números en consola.\n */\nconst printNumbers = (startNumber: number): void => {\n  let currentNumber = startNumber;\n\n  if (currentNumber === 0) {\n    console.log(currentNumber);\n    return;\n  }\n\n  console.log(currentNumber);\n\n  printNumbers(currentNumber - 1);\n};\n\n// -------------------------------------------------------------------------------------------\n\n/**\n * Calcula el factorial de un numero de forma recursiva.\n *\n * @param number - El número a calcular su factorial.\n * @returns number - resultado del factorial del numero.\n */\nconst calculateFactorial = (number: number): number => {\n  if (number === 0) return 1;\n\n  if (number < 0) {\n    throw new Error(\"El número no puede ser negativo\");\n  }\n\n  return number * calculateFactorial(number - 1);\n};\n\n// -------------------------------------------------------------------------------------------\n\n/**\n * Calcula el valor de la sucesión de Fibonacci en la posición n.\n *\n * @param n - Posicion del numero de fibonacci.\n * @returns number - numero de la posicion n de fibonacci.\n */\nconst fibonacciAt = (n: number) => {\n  if (n < 0) throw new Error(\"La posición no puede ser negativa\");\n\n  if (n === 0) return 0;\n  if (n === 1) return 1;\n\n  return fibonacciAt(n - 1) + fibonacciAt(n - 2);\n};\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/typescript/juandaherrera.ts",
    "content": "function printSep(title: string | null = null): void {\n    const sep: string = \"-\";\n    const printVar: string = title ? sep.repeat(8) + title + sep.repeat(8) : sep.repeat(16);\n    console.log(printVar);\n}\n\n/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n*/\n\nfunction myFunction(n: number): void {\n    if (n === 0) {\n        console.log(0);\n    } else {\n        console.log(n);\n        myFunction(n - 1);\n    }\n}\n\n/*\n* DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n*/\n\nfunction factorial(n: number): number {\n    if (n === 1) {\n        return 1;\n    } else {\n        return n * factorial(n - 1);\n    }\n}\n\nfunction fibonacci(position: number): number {\n    if (position === 1 || position === 2) {\n        return position - 1;\n    } else {\n        return fibonacci(position - 1) + fibonacci(position - 2);\n    }\n}\n\nfunction runExamples(): void {\n    printSep('Ejercicio');\n    myFunction(100);\n\n    printSep('Factorial');\n    console.log(factorial(9));\n\n    printSep('Fibonacci');\n    console.log(fibonacci(15));\n\n    printSep();\n}\n\nrunExamples();"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/typescript/juserdev.ts",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\nconst countdown = (count: number) =>{\n    if (count >= 0) {\n        console.log(count)\n        countdown(count - 1)\n    }\n}\n\nconsole.log(countdown(10))"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/typescript/kodenook.ts",
    "content": "\n/**\n * The function \"recursion\" in TypeScript prints numbers from the input number down to 0 using\n * recursion.\n * @param {number} number - The `number` parameter in the `recursion` function is a numeric value that\n * determines how many times the function will recursively call itself. The function will log the value\n * of `number` to the console and then recursively call itself with `number - 1` until `number` is\n * greater than\n */\nfunction recursion(number: number): void {\n    console.log(number)\n    if (number > 0) {\n        recursion(--number)\n    }\n}\n\nrecursion(100)\n\n/*\n    Exercise\n*/\n\n/**\n * The function calculates the factorial of a given number recursively in TypeScript.\n * @param {number} number - The `number` parameter in the `factorial` function represents the number\n * for which you want to calculate the factorial. It is the input value for which the factorial will be\n * calculated recursively.\n * @param {number} [result=1] - The `result` parameter in the `factorial` function is used to keep\n * track of the intermediate result as the factorial calculation progresses through recursive calls. It\n * is initialized with a default value of 1 when the function is first called. As the function\n * recursively calculates the factorial of a number, the `\n */\nfunction factorial(number: number, result: number = 1): void {\n\n    if (number > 1) {\n        factorial(number - 1, number * result)\n    } else {\n        console.log(result)\n    }\n}\n\nfactorial(5)\n\n/**\n * The function calculates the Fibonacci number at a given position using recursion.\n * @param {number} position - The `position` parameter in the `fibonacci` function represents the\n * position of the Fibonacci number in the sequence that you want to calculate. For example, if\n * `position` is 5, it means you want to find the 5th Fibonacci number in the sequence.\n * @returns the value of the Fibonacci sequence at the specified position.\n */\nfunction fibonacci(position: number): number {\n    if (position > 2) {\n        return fibonacci(position - 1) + fibonacci(position - 2)\n    } else {\n        return 1\n    }\n}\n\nconsole.log(fibonacci(7))\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/typescript/marcode24.ts",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\n// Función recursiva para imprimir números del 100 al 0\nfunction imprimirNumeros(num: number): void {\n  if (num < 0) {\n    return;\n  }\n  console.log(num);\n  imprimirNumeros(num - 1);\n}\n\nconsole.log('Imprimiendo números del 100 al 0:');\nimprimirNumeros(100);\n\n// Función recursiva para calcular el factorial de un número\nfunction factorial(n: number): number {\n  if (n === 0 || n === 1) {\n    return 1;\n  }\n  return n * factorial(n - 1);\n}\n\nconst numero: number = 5;\nconsole.log(`Factorial de ${numero}:`, factorial(numero));\n\n// Función recursiva para calcular el valor de un elemento en la sucesión de Fibonacci\nfunction fibonacci(n: number): number {\n  if (n <= 1) {\n    return n;\n  }\n  return fibonacci(n - 1) + fibonacci(n - 2);\n}\n\nconst posicion: number = 6;\nconsole.log(`Valor en la posición ${posicion} de la sucesión de Fibonacci:`, fibonacci(posicion));\n\n// Visita mi repo en GitHub para ver y correr los tests de este código --> https://github.com/marcode24/weekly-challenges\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/typescript/markc1234.ts",
    "content": "(() => {\n    // EJERCICIO:\n    // Entiende el concepto de recursividad creando una función recursiva que imprima números del 100 al 0.\n    function recursiveFunction(num:number):void {\n        console.log(num)\n        if(num > 0) {\n            recursiveFunction(num-1)\n        }\n    }\n    // DIFICULTAD EXTRA (opcional):\n    // Utiliza el concepto de recursividad para:\n    // - Calcular el factorial de un número concreto (la función recibe ese número).\n    function factorial(num:number) {\n        if(num <= 1) {\n            return 1\n        } else {\n            return num * factorial(num-1)\n        }\n    }\n    // - Calcular el valor de un elemento concreto (según su posición) en la sucesión de Fibonacci (la función recibe la posición).\n    function fibonacci(posicion: number): number { \n        if (posicion <= 1) { \n            return posicion\n        } else { \n            return fibonacci(posicion - 1) + fibonacci(posicion - 2); \n        } \n    }\n})()"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/typescript/miguelex.ts",
    "content": "function sumaRecursiva(a: number, b: number): number {\n    if (b === 0) {\n        return a;\n    }\n    return sumaRecursiva(a + 1, b - 1);\n}\n\nconsole.log(\"La suma de 3 + 5 usando recursividad es = \" + sumaRecursiva(3, 5));\n\nfunction potenciaRecursiva(a: number, b: number): number {\n    if (b === 0) {\n        return 1;\n    }\n    return a * potenciaRecursiva(a, b - 1);\n}\n\nconsole.log(\"El resultado de 2 elevado a 3 es: \" + potenciaRecursiva(2, 3));\n\nfunction imprimirNumeros(numero: number): void {\n    if (numero >= 0) {\n        console.log(numero);\n        imprimirNumeros(numero - 1);\n    }\n}\n\nconsole.log(\"De 100 a 0 usando rercursividad: \");\nimprimirNumeros(100);\n\n// Extra\n\nfunction factorialRecursivo(a: number): number {\n    if (a === 0) {\n        return 1;\n    }\n    return a * factorialRecursivo(a - 1);\n}\n\nconsole.log(\"El factorial de 5 es: \" + factorialRecursivo(5));\n\nfunction fibonacciRecursivo(a: number): number {\n    if (a === 0) {\n        return 0;\n    }\n    if (a === 1) {\n        return 1;\n    }\n    return fibonacciRecursivo(a - 1) + fibonacciRecursivo(a - 2);\n}\n\nconsole.log(\"El fibonacci de 6 es: \" + fibonacciRecursivo(6));\n\nconsole.log(\"A continuación, vamos a probar las funciones factorial y fibonacci de forma interactiva\");\n\n\nimport * as readline from 'readline';\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nrl.question('Introduce un número para calcular su factorial: ', (answer: string) => {\n    console.log(`El factorial de ${answer} es: ${factorialRecursivo(parseInt(answer))}`);\n    rl.question('Introduce un número para calcular su secuencia Fibonacci: ', (numero: string) => {\n        console.log(`La secuencia Fibonacci de ${numero} es: ${fibonacciRecursivo(parseInt(numero))}`);\n        rl.close();\n    });\n});"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/typescript/misterdan100.ts",
    "content": "// print number 1 - 100 recursive function\n\nconst print1to100 = (initNumber: number): void => {\n    if(initNumber <= 100) {\n        console.log(initNumber)\n        print1to100(initNumber + 1)\n    }\n}\n\nprint1to100(20)\n\n\n//* Factorial number\nconst factorial = (number: number): number => {\n    if( number === 0 || number === 1) {\n        return 1\n    }\n    return number * factorial(number -1)\n}\n\nconsole.log(factorial(5))\n\n\n//* Fibonachi number recursion\n// recursion for fibonacci is slow with big number like 77\n\nconst fibonacci = (number: number): number => {\n    if(number === 1 ) return 1\n    if(number === 0 ) return 0\n\n    return fibonacci(number -1 ) + fibonacci(number -2 )\n}\n\nconsole.log(fibonacci(3))\n\n//* Fibonacci function to big numbers like 77\nconst fibonacciLarge = (n: number): number => {\n    let a = 1\n    let b = 1\n    let c = 1\n    for( let i = 3; i <= n; i++) {\n        c = a + b\n        a = b\n        b = c\n    }\n\n    return b\n}\n\nconsole.log(fibonacciLarge(2))"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/typescript/nlarrea.ts",
    "content": "/*\n * EJERCICIO:\n * Entiende el concepto de recursividad creando una función recursiva que imprima\n * números del 100 al 0.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\n\nfunction printNumbers(num: number): void {\n    console.log(num)\n\n    if (num === 0) return\n    printNumbers(num - 1)\n}\n\n\nprintNumbers(100)\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el concepto de recursividad para:\n * - Calcular el factorial de un número concreto (la función recibe ese número).\n * - Calcular el valor de un elemento concreto (según su posición) en la \n *   sucesión de Fibonacci (la función recibe la posición).\n */\n\n\n// Factorial\n\n\nfunction factorial(num: number): number {\n    // Check if number is negative or 0\n    if (num <= 0) {\n        return -1\n    }\n\n    // Get the factorial of the number\n    if (num === 1) {\n        return 1\n    }\n\n    return num * factorial(num - 1)\n}\n\n\nconsole.log(factorial(4))  // 24\nconsole.log(factorial(5))  // 120\n\n\n// Fibonacci\n\n\nfunction fibonacci(position: number): number {\n    if (position <= 0) {\n        console.log('Only positive numbers')\n        return -1\n    } else if (position === 1) return 0\n    else if (position === 2) return 1\n\n    return fibonacci(position - 1) + fibonacci(position - 2)\n}\n\n\nconsole.log(fibonacci(4))  // 2\nconsole.log(fibonacci(7))  // 8\nconsole.log(fibonacci(10))  // 34"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/typescript/qv1ko.ts",
    "content": "func(0);\n\nconsole.log(\"---\");\n\nconsole.log(fact(12));\n\nconsole.log(\"---\");\n\nconsole.log(fib(12));\n\nfunction func(num: number) {\n\n    console.log(num);\n\n    num = num + 1;\n\n    if (num <= 100) {\n        func(num);\n    }\n\n}\n\nfunction fact(num: number): number {\n    if (num <= 0) {\n        return 0;\n    } else if (num == 1) {\n        return 1;\n    } else {\n        return num * fact(num - 1);\n    }\n}\n\nfunction fib(pos: number): number {\n    if (pos <= 1) {\n        return 0;\n    } else if (pos == 2 || pos == 3) {\n        return 1;\n    } else {\n        return fib(pos - 1) + fib(pos - 2);\n    }\n}\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/typescript/qwik-zgheib.ts",
    "content": "/* -- exercise */\nconst printNumbers = (n: number): void => {\n  if (n < 0) return;\n\n  console.log(n);\n  printNumbers(n - 1);\n};\n\nprintNumbers(100);\n\n/* -- extra challenge */\nconst factorial = (n: number): number => (n === 0 ? 1 : n * factorial(n - 1));\n\nlet number: number = 5;\nconsole.log(\"Factorial of\", number, \"is\", factorial(number));\n\nconst fibonacci = (n: number): number => (n === 0 ? 0 : n === 1 ? 1 : fibonacci(n - 1) + fibonacci(n - 2));\n\nlet position: number = 7;\nconsole.log(\"Fibonacci number at position\", position, \"is\", fibonacci(position));\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/typescript/victor-Casta.ts",
    "content": "(() => {\n  /*\n    * EJERCICIO:\n    * Entiende el concepto de recursividad creando una función recursiva que imprima\n    * números del 100 al 0.\n  */\n\n  const printNumbers = (a: number): void => {\n    if (a < 0) return\n    console.log(a)\n    printNumbers(a - 1)\n  }\n\n  printNumbers(100)\n\n  /*\n    * DIFICULTAD EXTRA (opcional):\n    * Utiliza el concepto de recursividad para:\n    * - Calcular el factorial de un número concreto (la función recibe ese número).\n    * - Calcular el valor de un elemento concreto (según su posición) en la\n    *   sucesión de Fibonacci (la función recibe la posición).\n  */\n\n  const factorial = (n: number): number => {\n    if (n < 1) return 1\n    return n * factorial(n - 1)\n  }\n\n  console.log(factorial(8))\n\n  const fibonacci = (position: number): number => {\n    if (position === 0) {\n      return 0\n    }\n    if (position === 1) {\n      return 1\n    }\n    return fibonacci(position - 1) + fibonacci(position - 2)\n  }\n  console.log(fibonacci(7))\n})()"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/typescript/victoriaparraf.ts",
    "content": "function imprimirNumeros(n: number): void {\n    // Caso base: cuando n es menor que 0, terminamos la recursión\n    if (n < 0) {\n        return;\n    }\n    // Imprime el número actual\n    console.log(n);\n    // Llama a la función recursivamente con el siguiente número decreciente\n    imprimirNumeros(n - 1);\n}\n\n// Llamada inicial a la función con el valor 100\nimprimirNumeros(100);\n\n/*************/\n\nfunction calcularFactorial(numero: number): number {\n    // Caso base: cuando el número es 0 o 1, el factorial es 1\n    if (numero <= 1) {\n        return 1;\n    }\n    // Llamada recursiva: calcula el factorial de numero - 1 y multiplica por numero\n    return numero * calcularFactorial(numero - 1);\n}\n\nfunction verificarNumero(numero: number): number {\n    // Verifica si el número es menor que 0\n    if (numero < 0) {\n        throw new Error(\"El número debe ser no negativo\");\n    }\n    // Calcula el factorial utilizando la función recursiva\n    return calcularFactorial(numero);\n}\n\n// Ejemplo de uso\nlet resultado = verificarNumero(5);\nconsole.log(resultado); // 120\n\n\nfunction fibonacci(n: number): number {\n    // Caso base: los primeros dos números en la sucesión de Fibonacci\n    if (n === 0) {\n        return 0;\n    } else if (n === 1) {\n        return 1;\n    }\n    // Llamadas recursivas para calcular los dos números anteriores\n    return fibonacci(n - 1) + fibonacci(n - 2);\n}\n\n// Ejemplo de uso\nlet posicion = 10;\nlet valor = fibonacci(posicion);\nconsole.log(`El valor en la posición ${posicion} de la sucesión de Fibonacci es ${valor}`);\n"
  },
  {
    "path": "Roadmap/06 - RECURSIVIDAD/vb.net/kenysdev.vb",
    "content": "' ╔══════════════════════════════════════╗\n' ║ Autor:  Kenys Alvarado               ║\n' ║ GitHub: https://github.com/Kenysdev  ║\n' ║ 2024 -  VB.NET                       ║\n' ╚══════════════════════════════════════╝\n\n' # Recursividad\n' --------------\n' - La recursividad es la capacidad de una función para llamarse a sí misma,ya sea \n'   de forma directa o indirecta, con el propósito de resolver un problema. \nModule Program\n    Sub Main(args As String())\n        '- imprimiendo números del 100 al 0.\n        '  Ejemplo con recursividad directa\n        '  ocurre cuando una función se llama a sí misma. */\n\n        Recursive(100)\n\n        '- Ejemplo con recursividad indirecta\n        '  implica que varias funciones se llamen entre sí.\n\n        Recursive2(100)\n\n        ' ___________________________________________________________________\n        ' Ejercicios:\n        ' -----------\n        ' 1. Calcular el factorial de un número concreto (la función recibe ese número).\n        ' 4! = 4 * 3 * 2 * 1 = 24 */\n\n        Console.WriteLine($\"Factorial de 4: {Factorial(4)}\")\n\n        '2. Calcular el valor de un elemento concreto (según su posición) en la \n        '   sucesión de Fibonacci (la función recibe la posición).\n        '   n : |0|1|2|3|4|5|6|..\n        '   fb: |0|1|1|2|3|5|8|..\n        '        |+|=^   |+|=^ ..  */\n\n        Console.WriteLine($\"Posición 4 en Fibonacci: {Fibonacci(4)}\")\n\n    End Sub\n\n    Sub Recursive(ByVal n As Integer)\n        Console.WriteLine(n)\n        If n > 0 Then\n            Recursive(n - 1)\n        End If\n    End Sub\n\n    Sub Subs(ByVal n As Integer)\n        Recursive2(n - 1)\n    End Sub\n\n    Sub Recursive2(ByVal n As Integer)\n        Console.WriteLine(n)\n        If n > 0 Then\n            Subs(n)\n        End If\n    End Sub\n\n    Function Factorial(ByVal n As Integer) As Integer\n        If n <> 0 Then\n            Return n * Factorial(n - 1)\n        Else\n            Return 1\n        End If\n\n        ''* Explicación\n        '    fac(4)\n        '        | = 24 \n        '     return 4 * fac(3) ->(4 * 6)\n        '                  | = 6 \n        '         return 3 * fac(2) ->(3 * 2)\n        '                      | = 2 \n        '             return 2 * fac(1) ->(2 * 1)\n        '                          | = 1 \n        '                 return 1 * fac(0) ->(1 * 1)\n        '                              | = return 1 -> caso base */\n\n    End Function\n\n    Function Fibonacci(ByVal n As Integer) As Integer\n        If n <= 1 Then\n            Return n\n        Else\n            Return Fibonacci(n - 1) + Fibonacci(n - 2)\n        End If\n\n        ''* Explicación fib(4) \n        '                         return 3\n        '               fib(3)      / \\    fib(2)\n        '                / \\ =2      +      / \\ =1\n        '          fib(2) + fib(1)    fib(1) + fib(0) -> caso base\n        '          / \\ =1\n        '    fib(1) + fib(0) -> caso base  */\n\n    End Function\nEnd Module"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/arduino/santyjL.ino",
    "content": "int cola[5]; // Declara una cola de enteros\nint pila[5]; // Declara una pila de tamaño 5\nint frente = -1; // Inicializa el índice del frente de la cola\nint final = -1; // Inicializa el índice del final de la cola\nint top = -1; // Inicializa el índice superior de la pila\n\nvoid setup() {\n  Serial.begin(9600);\n\n  // Simula la adición de datos a la pila\n  for (int i = 1; i <= 5; i++) {\n    if (!pilaLlena()) {\n      push(i * 10); // Agrega valores multiplicados por 10 a la pila\n      Serial.println(\"Añadido a la pila: \" + String(i * 10));\n    } else {\n      Serial.println(\"La pila está llena. No se puede añadir más.\");\n    }\n  }\n\n  Serial.println(\"------------------\");\n\n  // Simula la adición de datos a la cola\n  for (int i = 1; i <= 5; i++) {\n    if (!colaLlena()) {\n      encolar(i * 5); // Agrega valores multiplicados por 5 a la cola\n      Serial.println(\"Añadido a la cola: \" + String(i * 5));\n    } else {\n      Serial.println(\"La cola está llena. No se puede añadir más.\");\n    }\n  }\n\n  Serial.println(\"------------------\");\n\n  // Simula la eliminación de elementos de la pila\n  while (!pilaVacia()) {\n    int valor = pop();\n    Serial.println(\"Eliminado de la pila: \" + String(valor));\n  }\n\n  Serial.println(\"------------------\");\n\n  // Simula la eliminación de elementos de la cola\n  while (!colaVacia()) {\n    int valor = desencolar();\n    Serial.println(\"Eliminado de la cola: \" + String(valor));\n  }\n}\n\nvoid loop() {\n  // El loop está vacío ya que la lógica principal se ejecutó en el setup\n}\n\nvoid push(int dato) {\n  if (!pilaLlena()) {\n    top++;\n    pila[top] = dato;\n  }\n}\n\nint pop() {\n  if (!pilaVacia()) {\n    int valor = pila[top];\n    top--;\n    return valor;\n  }\n  return -1; // Valor de error (pila vacía)\n}\n\nbool pilaLlena() {\n  return top == 4; // Tamaño de la pila - 1\n}\n\nbool pilaVacia() {\n  return top == -1;\n}\n\nvoid encolar(int dato) {\n  if (!colaLlena()) {\n    if (frente == -1) {\n      frente = 0;\n    }\n    final = (final + 1) % 5;\n    cola[final] = dato;\n  }\n}\n\nint desencolar() {\n  if (!colaVacia()) {\n    int valor = cola[frente];\n    if (frente == final) {\n      frente = -1;\n      final = -1;\n    } else {\n      frente = (frente + 1) % 5;\n    }\n    return valor;\n  }\n  return -1; // Valor de error (cola vacía)\n}\n\nbool colaLlena() {\n  return (frente == 0 && final == 4) || (frente == final + 1);\n}\n\nbool colaVacia() {\n  return frente == -1;\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/bash/rantamhack.sh",
    "content": "#!/bin/bash\n\n\necho -e \"\\n\\n=====================================PILAS=====================================\\n\\n\"\n\n\n# Una pila es una colección ordenada de elementos donde la adición de un nuevo elemento y \n# la eliminación de los existentes siempre ocurren desde el mismo extremo.\n\n\nstack=()\n\nfunction push(){   \n    stack=(1 \"${stack[@]}\")\n    echo \"${stack[@]}\"\n    stack=(2 \"${stack[@]}\")\n    echo \"${stack[@]}\"\n    stack=(3 \"${stack[@]}\")\n    echo \"${stack[@]}\"\n    stack=(4 \"${stack[@]}\")\n    echo \"${stack[@]}\"\n    stack=(5 \"${stack[@]}\")\n    echo \"${stack[@]}\"\n}\npush\n\nfunction pop(){\n\n    unset stack[0]\n    echo \"${stack[@]}\"\n    unset stack[1]\n    echo \"${stack[@]}\"\n    unset stack[2]\n    echo \"${stack[@]}\"\n    unset stack[3]\n    echo \"${stack[@]}\"\n    unset stack[4]\n    echo \"${stack[@]}\"\n    \n}\npop\n\necho -e \"\\n\\n=====================================COLAS=====================================\\n\\n\"\n\n\n# Una  cola  es una colección ordenada de elementos donde la adición de nuevos elementos ocurre en un extremo \n# y la eliminación de elementos existentes ocurre en el otro extremo. Se denominan delante y detrás respectivamente.\n\n\n\n\nfunction push2(){\n\n    queue=(\"${queue[@]}\" Miguel)\n    echo \"${queue[@]}\"\n    \n    queue=(\"${queue[@]}\" Jose)\n    echo \"${queue[@]}\"\n    \n    queue=(\"${queue[@]}\" Maria)\n    echo \"${queue[@]}\"\n\n    queue=(\"${queue[@]}\" Mar)\n    echo \"${queue[@]}\"\n\n    queue=(\"${queue[@]}\" Helena)\n    echo \"${queue[@]}\"\n}\npush2\n\nfunction pop2(){\n    \n    unset 'queue[0]'\n    queue=(\"${queue[@]}\")\n\n}\n    \npop2\necho \"${queue[@]}\"\n\npop2\necho \"${queue[@]}\"\n\npop2\necho \"${queue[@]}\"\n\npop2\necho \"${queue[@]}\"\n\npop2\necho \"${queue[@]}\"\n\n\necho -e \"\\n\\n=====================================DIFICULTAD EXTRA=====================================\\n\\n\"\n\n\n# Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n# de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n# que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n# Las palabras \"adelante\", \"atras\" desencadenan esta acción, el resto se interpreta como\n# el nombre de una nueva web.\n\n\nstack=(\"program_languages\")\n\nfunction python(){\n    echo -e \"Las paginas visitadas son: \\n${stack[@]}\\n\"\n    echo -e \"\\nBienvenido a la pagina de python\"\n    read -p \"¿Que pagina quieres visitar ahora?:  siguiente / anterior: \" new_page\n    if [[ $new_page == \"anterior\" ]]; then\n        stack=(\"${stack[@]:0:${#stack[@]}-1}\")\n        program_languages\n    elif [[ $new_page == \"siguiente\" ]];then\n        stack+=(javascript)\n        javascript\n    else\n        echo -e \"Has elegido una opción no disponible \\n [+] Saliendo del programa .....\"\n        exit\n    fi\n}\n        \nfunction javascript(){\n    echo -e \"Las paginas visitadas son: \\n${stack[@]}\\n\"\n    echo -e \"\\nBienvenido a la pagina de javascript\"\n    read -p \"¿Que pagina quieres visitar ahora?:  siguiente / anterior: \" new_page\n    if [[ $new_page == \"anterior\" ]]; then\n        stack=(\"${stack[@]:0:${#stack[@]}-1}\")\n        python\n    elif [[ $new_page == \"siguiente\" ]];then\n        stack+=(java)\n        java\n    else\n        echo -e \"Has elegido una opción no disponible \\n [+] Saliendo del programa .....\"\n        exit\n    fi\n}\n        \nfunction java(){\n    echo -e \"Las paginas visitadas son: \\n${stack[@]}\\n\"\n    echo -e \"\\nBienvenido a la pagina de java\"\n    read -p \"¿Que pagina quieres visitar ahora?:  siguiente / anterior: \" new_page\n    if [[ $new_page == \"anterior\" ]]; then\n        stack=(\"${stack[@]:0:${#stack[@]}-1}\")\n        javascript\n    elif [[ $new_page == \"siguiente\" ]];then\n        stack+=(typescript)\n        typescript\n    else\n        echo -e \"Has elegido una opción no disponible \\n [+] Saliendo del programa .....\"\n        exit\n    fi\n}\n\nfunction typescript(){\n    echo -e \"Las paginas visitadas son: \\n${stack[@]}\\n\"\n    echo -e \"\\nBienvenido a la pagina de typescript\"\n    read -p \"¿Quieres volver a visitar la página anterior? si / no: \" back\n    if [[ $back == \"si\" ]]; then\n        stack=(\"${stack[@]:0:${#stack[@]}-1}\")\n        java\n    else\n        echo \"[+] Saliendo del programa .....\"\n        exit\n    fi\n}\n    \n\nfunction program_languages(){\n    echo -e \"\\n${stack[@]}\\n\"\n    echo -e \"Bienvenido a la pagina principal\\n Los 4 lenguajes mas usados en el roadmap del gran Mouredev son: \\n 1º python\\n 2º javascript\\n 3º java\\n 4º typescript\"\n    read -p \"Quieres visitar la página de python?: si / no: \"  languages\n    \n    if [[ $languages == \"si\" ]];then\n        stack+=(python)\n        python \n    elif [[ $languages == \"no\" ]];then\n        echo \"[+] Saliendo del programa .....\"\n    else\n        echo -e \"Has elegido una opción no disponible \\n [+] Saliendo del programa .....\"\n        exit\n    fi\n}\n\nprogram_languages\n\n\necho -e \"\\n\\n=====================================DIFICULTAD EXTRA=====================================\\n\\n\"\n    \n\n# Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n# impresora compartida que recibe documentos y los imprime cuando así­ se le indica.\n# La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n# interpretan como nombres de documentos.\n\n\nqueue=()  \n\nqueue=(\"${queue[@]}\" doc1.txt)\nqueue=(\"${queue[@]}\" doc2.txt)\nqueue=(\"${queue[@]}\" doc3.txt)\nqueue=(\"${queue[@]}\" doc4.txt)\nqueue=(\"${queue[@]}\" doc5.txt)\n\necho -e \"\\nDocumentos en cola de impresión:\\n\\n${queue[@]}\"\n\nfunction impresion(){\n    echo -e \"\\nImprimiéndose el documento ${queue[0]}\"\n    queue=(\"${queue[@]:1}\")\n    \n}    \n\n\nfunction imprimir(){\n    read -p \"¿Quieres imprimir el primer documento de la cola de impresión?: imprimir / no imprimir: \" result\n    while [[ $result -eq \"imprimir\" ]]; do\n    impresion\n    echo -e \"\\n${queue[@]}\\n\"\n        if [[ ${#queue[@]} -gt 0 ]];then\n            read -p \"¿Quieres imprimir el siguiente documento de la cola de impresión?: imprimir / no imprimir: \" result\n        else\n            echo -e \"\\nNo hay documentos en la cola de impresión\"\n            break\n        fi\n    done\n}\n\nimprimir\n\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/c/N0HagoNada.c",
    "content": "#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#define MAX 100\n\n// Estructura para una cola\ntypedef struct\n{\n    char *items[MAX];\n    int front, rear;\n} Queue;\n\n// Función para inicializar la cola\nvoid initQueue(Queue *queue)\n{\n    queue->front = -1;\n    queue->rear = -1;\n}\n\n// Función para añadir elemento a la cola\nvoid enqueue(Queue *queue, char *item)\n{\n    if (queue->rear == MAX - 1)\n    {\n        printf(\"Queue full\\n\");\n        return;\n    }\n    if (queue->front == -1)\n        queue->front = 0;\n    queue->items[++queue->rear] = strdup(item); // Duplica el item y guarda el puntero\n}\n\n// Función para quitar elemento de la cola\nchar *dequeue(Queue *queue)\n{\n    if (queue->front == -1 || queue->front > queue->rear)\n    {\n        printf(\"Queue empty\\n\");\n        return NULL;\n    }\n    char *item = queue->items[queue->front];\n    queue->items[queue->front++] = NULL; // Evita fugas de memoria\n    if (queue->front > queue->rear)\n    { // Resetea la cola si está vacía\n        queue->front = queue->rear = -1;\n    }\n    return item;\n}\n\nint main()\n{\n    Queue printQueue;\n    initQueue(&printQueue);\n\n    // Simulación de la cola de impresión\n    enqueue(&printQueue, \"Documento1.pdf\");\n    enqueue(&printQueue, \"Imagen.png\");\n    enqueue(&printQueue, \"Tarea.docx\");\n\n    printf(\"Printing: %s\\n\", dequeue(&printQueue)); // Imprime Documento1.pdf\n    printf(\"Printing: %s\\n\", dequeue(&printQueue)); // Imprime Imagen.png\n\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/c/jchavescaceres.c",
    "content": "/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atras\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#define ELEMENT_TYPE const char*\nconst ELEMENT_TYPE C_NULL_ELEMENT_TYPE = NULL;\n\n\n/*\nQueue element type\n*/\ntypedef struct t_struct_queue_element {\n\tELEMENT_TYPE element;\n\tstruct t_struct_queue_element *previous_element;\n\tstruct t_struct_queue_element *next_element;\n} t_queue_element;\n\n/*\nQueue type\n*/\ntypedef struct {\n\tt_queue_element* firstElement;\n\tt_queue_element* lastElement;\n} t_queue;\n\n\n/*\nInitialize queue\n*/\nvoid initialize_queue (t_queue* inOutQueue) {\n\tinOutQueue->firstElement = NULL;\n\tinOutQueue->lastElement = NULL;\n}\n\n/*\nReturn 0 if queue is not empty\n*/\nint isQueueEmpty (t_queue* inOutQueue) {\n\treturn (inOutQueue->firstElement == NULL);\n}\n\n/*\nAdd element at the end of the list\n*/\nvoid push (t_queue* inOutQueue, ELEMENT_TYPE inElement) {\n\n\tt_queue_element* newQueElement = malloc (sizeof (t_queue_element));\n\n\tnewQueElement->element = inElement;\n\n\t/* Add new element at the end of the list*/\n\tnewQueElement->previous_element = inOutQueue->lastElement;\n\tnewQueElement->next_element = NULL;\n\n\tif (inOutQueue->firstElement == NULL ) {\n\t\tinOutQueue->firstElement = newQueElement;\n\t}\n\n\tif (inOutQueue->lastElement == NULL ) {\n\t\tinOutQueue->lastElement = newQueElement;\n\t} else {\n\t\tinOutQueue->lastElement->next_element = newQueElement;\n\t\tinOutQueue->lastElement = newQueElement;\n\t}\n}\n\n/*\nGet element from queue applying LIFO policy\n*/\nELEMENT_TYPE pop_lifo (t_queue* inOutQueue) {\n\n\tELEMENT_TYPE element = C_NULL_ELEMENT_TYPE;\n\tt_queue_element* lastElement = inOutQueue->lastElement;\n\n\tif (lastElement != NULL) {\n\t\telement = lastElement->element;\n\n\t\tif (lastElement->previous_element != NULL) {\n\n\t\t\tinOutQueue->lastElement = lastElement->previous_element;\n\t\t\tlastElement->previous_element->next_element = NULL;\n\n\t\t} else {\n\n\t\t\tinOutQueue->firstElement = NULL;\n\t\t\tinOutQueue->lastElement = NULL;\n\n\t\t};\n\t\tfree (lastElement);\n\t}\n\treturn element;\n\n};\n\n/*\nGet element from queue applying FIFO policy\n*/\nELEMENT_TYPE pop_fifo (t_queue* inOutQueue) {\n\n\tELEMENT_TYPE element = C_NULL_ELEMENT_TYPE;\n\tt_queue_element* firstElement = inOutQueue->firstElement;\n\n\tif (firstElement != NULL) {\n\t\telement = firstElement->element;\n\n\t\tif (firstElement->next_element != NULL) {\n\n\t\t\tinOutQueue->firstElement = firstElement->next_element;\n\t\t\tfirstElement->next_element->previous_element = NULL;\n\n\t\t} else {\n\n\t\t\tinOutQueue->firstElement = NULL;\n\t\t\tinOutQueue->lastElement = NULL;\n\n\t\t};\n\t\tfree (firstElement);\n\t}\n\treturn element;\n\n};\n\n /*\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atras\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n */\nvoid webBrowserSimulator() {\n\n\tconst char* C_ADELANTE = \"adelante\";\n\tconst char* C_ATRAS = \"atras\";\n\tconst char* C_SALIR = \"salir\";\n\tconst unsigned int C_SIZE_BUFFER = 200;\n\n\tchar myBuffer [C_SIZE_BUFFER];\n\tmemset (myBuffer, 0, sizeof (myBuffer));\n\n\tchar myExit = 0;\n\tchar *page = NULL;\n\n\tt_queue queueBack, queueNext;\n\tinitialize_queue (&queueBack);\n\tinitialize_queue (&queueNext);\n\n\t/*\n\tA: \n\tB: push back (old page), empty queue_next\n\tC: push back (old page), empty queue_next\n\tatras: pop lifo back -> str, push str\n\tatras: pop lifo back -> str, push str\n\tdelante: pop lifo next -> str, push back\n\n\n\tA B C\n\tatras\n\tB \n\tatras\n\tA\n\tdelante\n\tB\n\tD\n\tE\n\tatras\n\tE\n\tatras\n\tD\n\tatras\n\tB\n\t*/\n\n\twhile (!myExit) {\n\n\t\tprintf (\"Página? %s? %s? o %s?: \", C_ADELANTE, C_ATRAS, C_SALIR);\n\t\tfgets (myBuffer, C_SIZE_BUFFER, stdin);\n\t\tmyBuffer [strlen (myBuffer)-1] = '\\0'; /* remove \\n */\n\n\t\tif (!strcmp (myBuffer, C_SALIR)) {\n\t\t\tmyExit = 1;\n\t\t} else if (!strcmp (myBuffer, C_ATRAS)) {\n\t\t\t/* save previous page */\n\t\t\tif (page != NULL) {\n\t\t\t\tpush (&queueNext, page);\n\t\t\t}\n\t\t\tpage = (char*) pop_lifo (&queueBack);\n\t\t\t\n\t\t} else if (!strcmp (myBuffer, C_ADELANTE)) {\n\t\t\t/* save previous page */\n\t\t\tif (page != NULL) {\n\t\t\t\tpush (&queueBack, page);\n\t\t\t}\n\t\t\tpage = (char*) pop_lifo (&queueNext);\n\t\t} else {\n\n\t\t\t/* save previous page */\n\t\t\tif (page != C_NULL_ELEMENT_TYPE) {\n\t\t\t\tpush (&queueBack, page);\n\t\t\t}\n\n\t\t\t/* empty queue next */\n\t\t\twhile ( (page=(char*)pop_lifo (&queueNext)) != NULL) {\n\t\t\t\tfree (page);\n\t\t\t}\n\n\t\t\tpage = malloc (strlen (myBuffer)+1);\n\t\t\tstrcpy (page, myBuffer);\n\t\t};\n\n\t\tif (page != C_NULL_ELEMENT_TYPE) {\n\t\t\tprintf (\"Display %s\\n\", page);\n\t\t} else {\n\t\t\tprintf (\"No hay más páginas \\n\");\n\t\t}\n\n\t};\n\n\tfree (page);\n\n\twhile ( (page=(char*)pop_lifo (&queueNext)) != NULL) {\n\t\tfree (page);\n\t}\n\twhile ( (page=(char*)pop_lifo (&queueBack)) != NULL) {\n\t\tfree (page);\n\t}\n\n\n}\n\n /*\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\nvoid printerSimulator() {\n\tconst char* C_IMPRIMIR = \"imprimir\";\n\tconst char* C_SALIR = \"salir\";\n\tconst unsigned int C_SIZE_BUFFER = 200;\n\n\tchar myBuffer [C_SIZE_BUFFER];\n\tmemset (myBuffer, 0, sizeof (myBuffer));\n\n\tchar myExit = 0;\n\tchar *document = NULL;\n\n\tt_queue queue;\n\tinitialize_queue (&queue);\n\n\twhile (!myExit) {\n\n\t\tprintf (\"Documento? %s? o %s?: \", C_IMPRIMIR, C_SALIR);\n\t\tfgets (myBuffer, C_SIZE_BUFFER, stdin);\n\t\tmyBuffer [strlen (myBuffer)-1] = '\\0'; /* remove \\n */\n\n\t\tif (!strcmp (myBuffer, C_SALIR)) {\n\t\t\tmyExit = 1;\n\t\t} else if (!strcmp (myBuffer, C_IMPRIMIR)) {\n\t\t\tdocument = (char*) pop_fifo (&queue);\n\t\t\tif (document != C_NULL_ELEMENT_TYPE) {\n\t\t\t\tprintf (\"Imprimiendo %s\\n\", document);\n\t\t\t\tfree (document);\n\t\t\t} else {\n\t\t\t\tprintf (\"No hay documentos para imprimir \\n\");\n\t\t\t}\n\t\t} else {\n\t\t\tdocument = malloc (strlen (myBuffer)+1);\n\t\t\tstrcpy (document, myBuffer);\n\t\t\tpush (&queue, document);\n\t\t};\n\n\n\t};\n\n\twhile ( (document=(char*)pop_fifo (&queue)) != NULL) {\n\t\tfree (document);\n\t}\n\n}\n\nvoid (* const C_FUNCTIONS []) () = {\n\twebBrowserSimulator,\n\tprinterSimulator };\n\n\n\nvoid main () {\n\t\n\tconst char* C_A = \"Elemento A\";\n\tconst char* C_B = \"Elemento B\";\n\tconst char* C_C = \"Elemento C\";\n\tconst char* C_D = \"Elemento D\";\n\tt_queue queue;\n\tinitialize_queue (&queue);\n\n\tconst unsigned int C_SIZE_BUFFER = 200;\n\n\tchar myBuffer [C_SIZE_BUFFER];\n\tmemset (myBuffer, 0, sizeof (myBuffer));\n\n\tunsigned opcionEscogida = 1;\n\n\tprintf (\"Ejemplo LIFO:\\n\");\n\tpush (&queue, C_A);\n\tprintf (\"push %s\\n\", C_A);\n\tpush (&queue, C_B);\n\tprintf (\"push %s\\n\", C_B);\n\tpush (&queue, C_C);\n\tprintf (\"push %s\\n\", C_C);\n\n\tprintf (\"pop %s\\n\", pop_lifo (&queue));\n\tpush (&queue, C_D);\n\tprintf (\"push %s\\n\", C_D);\n\tprintf (\"pop %s\\n\", pop_lifo (&queue));\n\tprintf (\"pop %s\\n\", pop_lifo (&queue));\n\tprintf (\"pop %s\\n\", pop_lifo (&queue));\n\n\tprintf (\"Ejemplo FIFO:\\n\");\n\tpush (&queue, C_A);\n\tprintf (\"push %s\\n\", C_A);\n\tpush (&queue, C_B);\n\tprintf (\"push %s\\n\", C_B);\n\tpush (&queue, C_C);\n\tprintf (\"push %s\\n\", C_C);\n\n\tprintf (\"pop %s\\n\", pop_fifo (&queue));\n\tpush (&queue, C_D);\n\tprintf (\"push %s\\n\", C_D);\n\tprintf (\"pop %s\\n\", pop_fifo (&queue));\n\tprintf (\"pop %s\\n\", pop_fifo (&queue));\n\tprintf (\"pop %s\\n\", pop_fifo (&queue));\n\n\t/*\n\tDificultad extra\n\t*/\n\twhile (opcionEscogida) {\n\n\t\tprintf (\"1. Navegador web.\\n\");\n\t\tprintf (\"2. Impresora.\\n\");\n\t\tprintf (\"0. Salir.\\n\");\n\t\tprintf (\"\\nSeleccione opción: \");\n\n\t\tfgets (myBuffer, C_SIZE_BUFFER, stdin);\n\t\tmyBuffer [strlen (myBuffer)-1] = '\\0'; /* remove \\n */\n\n\t\tif (strspn (myBuffer, \"012\") != strlen (myBuffer)) {\n\t\t\tprintf (\"Valor no admitido\\n\");\n\t\t}\n\t\telse {\n\t\t\tsscanf (myBuffer, \"%u\\n\", &opcionEscogida);\n\n\t\t\tif (opcionEscogida != 0) {\n\t\t\t\tC_FUNCTIONS [opcionEscogida-1]();\n\t\t\t}\n\t\t}\n\n\t};\n\n};\n\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/c/srvariable.c",
    "content": "/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n\n// Definición de macros\n\n#define MAX_SIZE 2048\n\n// Inclusión de librerías\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n// Enum para las diferentes funciones\n\ntypedef enum e_function\n{\n\tPUSH,\n\tPOP,\n\tPEEK_STACK,\n\tENQUEUE,\n\tDEQUEUE,\n\tPEEK_QUEUE,\n}\t\t\t\tt_function;\n\n// Estructura de un nodo\n\ntypedef struct s_node\n{\n\tchar\t\t\t*item;\n\tstruct s_node\t*next;\n}\t\t\t\tt_node;\n\n/* Declaración de funciones de los nodos */\n\nt_node\t*create_node(const char *item);\nvoid\tdestroy_node(t_node **node);\n\n// Manejo de errores\n\nint\t\terror_handler(void *address, int status, t_function name);\n\n// Utils\n\nvoid\tft_print(t_node *first, t_node *last, t_function name);\n\n// Estructura de una pila\n\ntypedef struct s_stack\n{\n\tt_node\t*bottom;\n\tt_node\t*top;\n}\t\t\t\tt_stack;\n\n/* Declaración de funciones de la pila */\n\nt_stack\t*create_stack(const char *item);\nvoid\tdestroy_stack(t_stack **stack);\nint\t\tpush(t_stack **stack, const char *item);\nint\t\tpop(t_stack **stack);\nchar\t*peek_stack(t_stack *stack);\nint\t\ttest_stack(void);\n\n// Estructura de una cola\ntypedef struct s_queue\n{\n\tt_node\t*back;\n\tt_node\t*front;\n}\t\t\t\tt_queue;\n\n/* Declaración de funciones de la cola */\n\nt_queue\t*create_queue(const char *item);\nvoid\tdestroy_queue(t_queue **queue);\nint\t\tenqueue(t_queue **queue, const char *item);\nint\t\tdequeue(t_queue **queue);\nchar\t*peek_queue(t_queue *queue);\nint\t\ttest_queue(void);\n\n// Estructura del navegador web\n\ntypedef struct s_web\n{\n\tt_stack\t*history;\n\tt_stack\t*temp;\n\tchar\tinput[MAX_SIZE];\n\tint\t\tflag;\n\tint\t\thome_counter;\n}\t\t\t\tt_web;\n\n// Navegador web\n\nint\t\tweb_browser(void);\nvoid\tweb_browser_menu(t_web **web);\nint\t\tweb_browser_navigate(t_web **web);\nint\t\tweb_browser_previous(t_web **web);\nint\t\tweb_browser_forward(t_web **web);\n\ntypedef struct s_printer\n{\n\tt_queue\t*queue;\n\tchar\tinput[MAX_SIZE];\n}\t\t\t\tt_printer;\n\n// Impresora\n\nint\t\tprinter(void);\nvoid\tprinter_menu(void);\nint\t\tprinter_add(t_printer **printer);\nint\t\tprinter_remove(t_printer **printer);\nint\t\tprinter_print(t_printer **printer);\n\nint\tmain(void)\n{\n\tint\tstatus;\n\n\tprintf(\"========== INICIO STACK ==========\\n\\n\");\n\tstatus = test_stack();\n\tif (status) return (status);\n\tprintf(\"========== FIN STACK ==========\\n\");\n\tprintf(\"\\n\");\n\tprintf(\"========== INICIO QUEUE ==========\\n\\n\");\n\tstatus = test_queue();\n\tif (status) return (status);\n\tprintf(\"========== FIN QUEUE ==========\\n\");\n\tstatus = web_browser();\n\tif (status) return (status);\n\tstatus = printer();\n\tif (status) return (status);\n\treturn (0);\n}\n\n/**\n * @brief Crea un nodo.\n *\n * @param item Elemento que se añadirá al nodo.\n *\n * @return - El nodo creado.\n * @return - NULL Si falla la creación del nodo.\n */\nt_node\t*create_node(const char *item)\n{\n\tt_node\t*node;\n\n\tnode = (t_node *) malloc(sizeof(t_node));\n\tif (!node) return (NULL);\n\tnode->item = strdup(item);\n\tif (!node->item)\n\t{\n\t\tfree(node);\n\t\treturn (NULL);\n\t}\n\tnode->next = NULL;\n\treturn (node);\n}\n\n/**\n * @brief Destruye el nodo.\n *\n * @param node Dirección de memoria del nodo.\n */\nvoid\tdestroy_node(t_node **node)\n{\n\tif (!(*node)) return;\n\tif ((*node)->item)\n\t{\n\t\tfree((*node)->item);\n\t\t(*node)->item = NULL;\n\t}\n\tfree(*node);\n\t*node = NULL;\n}\n\n/**\n * @brief Maneja los diferentes posibles errores\n *\n * @param address Dirección de memoria de la pila/cola.\n * @param status Estado que indica en qué llamada ha fallado.\n * @param name Nombre de la función.\n *\n * @return - status Devuelve el parámetro status.\n */\nint\terror_handler(void *address, int status, t_function name)\n{\n\tif (name == POP || name == PEEK_STACK) printf(\"La pila está vacía\\n\\n\");\n\telse if (name == DEQUEUE || name == PEEK_QUEUE) printf(\"La cola está vacía\\n\\n\");\n\telse if (name == PUSH)\n\t{\n\t\tprintf(\"Error añadiendo el elemento a la pila, llamada %d\\n\", status);\n\t\tdestroy_stack((t_stack **) address);\n\t}\n\telse if (name == ENQUEUE)\n\t{\n\t\tprintf(\"Error añadiendo el elemento a la cola, llamada %d\\n\", status);\n\t\tdestroy_queue((t_queue **) address);\n\t}\n\treturn (status);\n}\n\n/**\n * @brief Mensaje personalizado para pilas y colas\n *\n * @param first Nodo al primer elemento.\n * @param last Nodo al último elemento.\n * @param name Nombre de la función.\n */\nvoid\tft_print(t_node *first, t_node *last, t_function name)\n{\n\tif (!first || !last) return ;\n\tif (name == PUSH || name == POP)\n\t\tprintf(\"Bottom: %s | Top: %s\\n\\n\", first->item, last->item);\n\telse if (name == ENQUEUE || name == DEQUEUE)\n\t\tprintf(\"Front: %s | Back: %s\\n\\n\", first->item, last->item);\n}\n\n/**\n * @brief Test de funciones de la pila.\n *\n * @return - > 0 Si hay algún error grave.\n * @return - 0 Si el test se ejecuta correctamente.\n */\nint\ttest_stack(void)\n{\n\tt_stack\t*stack;\n\tint\t\tstatus;\n\tchar\t*element;\n\n\tstack = NULL;\n\n\tstatus = push(&stack, \"Hola\");\n\tprintf(\"Push:\\n\");\n\tif (status) return (error_handler(&stack, status, PUSH));\n\tif (stack->bottom) ft_print(stack->bottom, stack->top, PUSH);\n\n\tstatus = push(&stack, \"Mundo\");\n\tprintf(\"Push:\\n\");\n\tif (status) return (error_handler(&stack, status, PUSH));\n\tif (stack->bottom) ft_print(stack->bottom, stack->top, PUSH);\n\n\tstatus = pop(&stack);\n\tprintf(\"Pop:\\n\");\n\tif (status) error_handler(&stack, status, POP);\n\tif (stack->bottom) ft_print(stack->bottom, stack->top, POP);\n\n\tstatus = pop(&stack);\n\tprintf(\"Pop:\\n\");\n\tif (status) error_handler(&stack, status, POP);\n\tif (stack->bottom) ft_print(stack->bottom, stack->top, POP);\n\n\tstatus = pop(&stack);\n\tprintf(\"Pop:\\n\");\n\tif (status) error_handler(&stack, status, POP);\n\tif (stack->bottom) ft_print(stack->bottom, stack->top, POP);\n\n\tstatus = push(&stack, \"La\");\n\tprintf(\"Push:\\n\");\n\tif (status) return (error_handler(&stack, status, PUSH));\n\tif (stack->bottom) ft_print(stack->bottom, stack->top, PUSH);\n\n\tstatus = push(&stack, \"Pila\");\n\tprintf(\"Push:\\n\");\n\tif (status) return (error_handler(&stack, status, PUSH));\n\tif (stack->bottom) ft_print(stack->bottom, stack->top, PUSH);\n\n\tstatus = push(&stack, \"Funciona\");\n\tprintf(\"Push:\\n\");\n\tif (status) return (error_handler(&stack, status, PUSH));\n\tif (stack->bottom) ft_print(stack->bottom, stack->top, PUSH);\n\n\telement = peek_stack(stack);\n\tprintf(\"Peek_stack:\\n\");\n\tif (!element) error_handler(&stack, status, PEEK_STACK);\n\telse printf(\"El último elemento de la pila es: %s\\n\\n\", element);\n\n\tstatus = pop(&stack);\n\tprintf(\"Pop:\\n\");\n\tif (status) error_handler(&stack, status, POP);\n\tif (stack->bottom) ft_print(stack->bottom, stack->top, POP);\n\n\telement = peek_stack(stack);\n\tprintf(\"Peek_stack:\\n\");\n\tif (!element) error_handler(&stack, status, PEEK_STACK);\n\telse printf(\"El último elemento de la pila es: %s\\n\\n\", element);\n\n\tstatus = pop(&stack);\n\tprintf(\"Pop:\\n\");\n\tif (status) error_handler(&stack, status, POP);\n\tif (stack->bottom) ft_print(stack->bottom, stack->top, POP);\n\n\telement = peek_stack(stack);\n\tprintf(\"Peek_stack:\\n\");\n\tif (!element) error_handler(&stack, status, PEEK_STACK);\n\telse printf(\"El último elemento de la pila es: %s\\n\\n\", element);\n\n\tstatus = pop(&stack);\n\tprintf(\"Pop:\\n\");\n\tif (status) error_handler(&stack, status, POP);\n\tif (stack->bottom) ft_print(stack->bottom, stack->top, POP);\n\n\telement = peek_stack(stack);\n\tprintf(\"Peek_stack:\\n\");\n\tif (!element) error_handler(&stack, status, PEEK_STACK);\n\telse printf(\"El último elemento de la pila es: %s\\n\\n\", element);\n\n\tstatus = pop(&stack);\n\tprintf(\"Pop:\\n\");\n\tif (status) error_handler(&stack, status, POP);\n\tif (stack->bottom) ft_print(stack->bottom, stack->top, POP);\n\n\telement = peek_stack(stack);\n\tprintf(\"Peek_stack:\\n\");\n\tif (!element) error_handler(&stack, status, PEEK_STACK);\n\telse printf(\"El último elemento de la pila es: %s\\n\\n\", element);\n\n\tdestroy_stack(&stack);\n\treturn (0);\n}\n\n/**\n * @brief Test de funciones de la cola.\n *\n * @return - > 0 Si hay algún error grave.\n * @return - 0 Si el test se ejecuta correctamente.\n */\nint\t\ttest_queue(void)\n{\n\tt_queue\t*queue;\n\tint\t\tstatus;\n\tchar\t*element;\n\n\tqueue = NULL;\n\n\tstatus = enqueue(&queue, \"Hola\");\n\tprintf(\"Enqueue:\\n\");\n\tif (status) error_handler(&queue, status, ENQUEUE);\n\tif (queue->front) ft_print(queue->front, queue->back, ENQUEUE);\n\n\tstatus = enqueue(&queue, \"Mundo\");\n\tprintf(\"Enqueue:\\n\");\n\tif (status) error_handler(&queue, status, ENQUEUE);\n\tif (queue->front) ft_print(queue->front, queue->back, ENQUEUE);\n\n\tstatus = dequeue(&queue);\n\tprintf(\"Dequeue:\\n\");\n\tif (status) error_handler(&queue, status, DEQUEUE);\n\tif (queue->front) ft_print(queue->front, queue->back, DEQUEUE);\n\n\tstatus = dequeue(&queue);\n\tprintf(\"Dequeue:\\n\");\n\tif (status) error_handler(&queue, status, DEQUEUE);\n\tif (queue->front) ft_print(queue->front, queue->back, DEQUEUE);\n\n\tstatus = dequeue(&queue);\n\tprintf(\"Dequeue:\\n\");\n\tif (status) error_handler(&queue, status, DEQUEUE);\n\tif (queue->front) ft_print(queue->front, queue->back, DEQUEUE);\n\n\tstatus = enqueue(&queue, \"La\");\n\tprintf(\"Enqueue:\\n\");\n\tif (status) error_handler(&queue, status, ENQUEUE);\n\tif (queue->front) ft_print(queue->front, queue->back, ENQUEUE);\n\n\tstatus = enqueue(&queue, \"Cola\");\n\tprintf(\"Enqueue:\\n\");\n\tif (status) error_handler(&queue, status, ENQUEUE);\n\tif (queue->front) ft_print(queue->front, queue->back, ENQUEUE);\n\n\tstatus = enqueue(&queue, \"Funciona\");\n\tprintf(\"Enqueue:\\n\");\n\tif (status) error_handler(&queue, status, ENQUEUE);\n\tif (queue->front) ft_print(queue->front, queue->back, ENQUEUE);\n\n\telement = peek_queue(queue);\n\tprintf(\"Peek_queue:\\n\");\n\tif (!element) error_handler(&queue, status, PEEK_QUEUE);\n\telse printf(\"El primer elemento de la cola es: %s\\n\\n\", element);\n\n\tstatus = dequeue(&queue);\n\tprintf(\"Dequeue:\\n\");\n\tif (status) error_handler(&queue, status, DEQUEUE);\n\tif (queue->front) ft_print(queue->front, queue->back, DEQUEUE);\n\n\telement = peek_queue(queue);\n\tprintf(\"Peek_queue:\\n\");\n\tif (!element) error_handler(&queue, status, PEEK_QUEUE);\n\telse printf(\"El primer elemento de la cola es: %s\\n\\n\", element);\n\n\tstatus = dequeue(&queue);\n\tif (status) error_handler(&queue, status, DEQUEUE);\n\tif (queue->front) ft_print(queue->front, queue->back, DEQUEUE);\n\n\telement = peek_queue(queue);\n\tprintf(\"Peek_queue:\\n\");\n\tif (!element) error_handler(&queue, status, PEEK_QUEUE);\n\telse printf(\"El primer elemento de la cola es: %s\\n\\n\", element);\n\n\tstatus = dequeue(&queue);\n\tprintf(\"Dequeue:\\n\");\n\tif (status) error_handler(&queue, status, DEQUEUE);\n\tif (queue->front) ft_print(queue->front, queue->back, DEQUEUE);\n\n\telement = peek_queue(queue);\n\tprintf(\"Peek_queue:\\n\");\n\tif (!element) error_handler(&queue, status, PEEK_QUEUE);\n\telse printf(\"El primer elemento de la cola es: %s\\n\\n\", element);\n\n\tstatus = dequeue(&queue);\n\tprintf(\"Dequeue:\\n\");\n\tif (status) error_handler(&queue, status, DEQUEUE);\n\tif (queue->front) ft_print(queue->front, queue->back, DEQUEUE);\n\n\tdestroy_queue(&queue);\n\treturn (0);\n}\n\n/* === 1 === */\n\n/**\n * @brief Crea la pila\n *\n * @param item Elemento que se añadirá al nodo de la pila.\n * \n * @return La pila creada.\n * @return NULL Si la falla la creación de la pila.\n *\n * @warning Utilizar la función destroy_stack al terminar de usar\n * la pila para evitar fugas de memoria.\n */\nt_stack\t*create_stack(const char *item)\n{\n\tt_stack\t*stack;\n\n\tstack = (t_stack *) malloc(sizeof(t_stack));\n\tif (!stack) return (NULL);\n\tstack->bottom = create_node(item);\n\tif (!stack->bottom)\n\t{\n\t\tfree(stack);\n\t\treturn (NULL);\n\t}\n\tstack->top = stack->bottom;\n\treturn (stack);\n}\n\n/**\n * @brief Destruye la pila.\n *\n * @param stack Dirección de memoria de la pila.\n */\nvoid\tdestroy_stack(t_stack **stack)\n{\n\tt_node\t*temp;\n\n\tif (!(*stack)) return;\n\twhile ((*stack)->bottom)\n\t{\n\t\ttemp = (*stack)->bottom->next;\n\t\tdestroy_node(&(*stack)->bottom);\n\t\t(*stack)->bottom = temp;\n\t}\n\tfree(*stack);\n\t*stack = NULL;\n}\n\n/**\n * @brief Añade un elemento al final de la pila.\n *\n * @param stack Dirección de memoria de la pila.\n * @param item El elemento que va a ser añadido.\n *\n * @return - 0 Si el elemento es añadido correctamente.\n * @return - > 0 Si falla el añadir un elemento.\n *\n * @attention El stack tiene que estar previamente inicializado,\n * ya sea a NULL o usando la función create_stack.\n *\n * @warning Utilizar la función destroy_stack al terminar de usar\n * la pila para evitar fugas de memoria.\n */\nint\tpush(t_stack **stack, const char *item)\n{\n\tstatic int\tcalls;\n\n\t++calls;\n\tif (!(*stack))\n\t{\n\t\t*stack = create_stack(item);\n\t\tif (!(*stack)) return (calls);\n\t}\n\telse if (!(*stack)->top)\n\t{\n\t\t(*stack)->top = create_node(item);\n\t\tif (!(*stack)) return (calls);\n\t\t(*stack)->bottom = (*stack)->top;\n\t}\n\telse\n\t{\n\t\t(*stack)->top->next = create_node(item);\n\t\tif (!(*stack)->top->next) return (calls);\n\t\t(*stack)->top = (*stack)->top->next;\n\t}\n\treturn (0);\n}\n\n/**\n * @brief Elimina el último elemento de la pila.\n *\n * @param stack Dirección de memoria de la pila.\n *\n * @return - 0 Si el elemento es eliminado correctamente.\n * @return - > 0 Si no hay elemento que eliminar.\n */\nint\tpop(t_stack **stack)\n{\n\tstatic int\tcalls;\n\tt_node\t\t*temp;\n\n\t++calls;\n\tif (!(*stack) || !(*stack)->top) return (calls);\n\tif (!(*stack)->bottom->next)\n\t{\n\t\tdestroy_node(&(*stack)->bottom);\n\t\t(*stack)->top = NULL;\n\t\treturn (0);\n\t}\n\ttemp = (*stack)->bottom;\n\twhile(temp->next && temp->next->next)\n\t\ttemp = temp->next;\n\t(*stack)->top = temp;\n\tdestroy_node(&temp->next);\n\treturn (0);\n}\n\n/**\n * @brief Devuelve el último elemento de la pila.\n *\n * @param stack La pila.\n *\n * @return - NULL si no hay ningún elemento.\n * @return - El último elemento de la pila.\n */\nchar\t*peek_stack(t_stack *stack)\n{\n\tif (!stack || !stack->top) return (NULL);\n\treturn (stack->top->item);\n}\n\n/**\n * @brief Crea la cola \n *\n * @param item Elemento que se añadirá al nodo de la cola.\n * \n * @return La cola creada.\n * @return NULL Si la falla la creación de la cola.\n *\n * @warning Utilizar la función destroy_queue al terminar de usar\n * la pila para evitar fugas de memoria.\n */\nt_queue\t*create_queue(const char *item)\n{\n\tt_queue\t*queue;\n\n\tqueue = (t_queue *) malloc(sizeof(t_queue));\n\tif (!queue) return (NULL);\n\tqueue->back = create_node(item);\n\tif (!queue->back)\n\t{\n\t\tfree(queue);\n\t\treturn (NULL);\n\t}\n\tqueue->front = queue->back;\n\treturn (queue);\n}\n\n/**\n * @brief Destruye la cola.\n *\n * @param stack Dirección de memoria de la cola.\n */\nvoid\tdestroy_queue(t_queue **queue)\n{\n\tt_node\t*temp;\n\n\tif (!(*queue)) return;\n\twhile ((*queue)->front)\n\t{\n\t\ttemp = (*queue)->front->next;\n\t\tdestroy_node(&(*queue)->front);\n\t\t(*queue)->front = temp;\n\t}\n\tfree(*queue);\n\t*queue = NULL;\n}\n\n/**\n * @brief Añade un elemento al inicio de la cola.\n *\n * @param queue Dirección de memoria de la cola.\n * @param item El elemento que va a ser añadido.\n *\n * @return - 0 Si el elemento es añadido correctamente.\n * @return - > 0 Si falla el añadir un elemento.\n *\n * @attention El stack tiene que estar previamente inicializado,\n * ya sea a NULL o usando la función create_queue.\n *\n * @warning Utilizar la función destroy_queue al terminar de usar\n * la pila para evitar fugas de memoria.\n */\nint\t\tenqueue(t_queue **queue, const char *item)\n{\n\tstatic int\tcalls;\n\n\t++calls;\n\tif (!(*queue))\n\t{\n\t\t*queue = create_queue(item);\n\t\tif (!(*queue)) return (calls);\n\t}\n\telse if (!(*queue)->front)\n\t{\n\t\t(*queue)->front = create_node(item);\n\t\tif (!(*queue)->front ) return (calls);\n\t\t(*queue)->back = (*queue)->front;\n\t}\n\telse\n\t{\n\t\t(*queue)->back->next = create_node(item);\n\t\tif (!(*queue)->back->next) return (calls);\n\t\t(*queue)->back = (*queue)->back->next;\n\t}\n\treturn (0);\n}\n\n/**\n * @brief Elimina el primer elemento de la cola.\n *\n * @param queue Dirección de memoria de la cola.\n *\n * @return - 0 Si el elemento es eliminado correctamente.\n * @return - > 0 Si no hay elemento que eliminar.\n *\n */\nint\t\tdequeue(t_queue **queue)\n{\n\tstatic int\tcalls;\n\tt_node\t\t*temp;\n\n\t++calls;\n\tif (!(*queue) || !(*queue)->front) return (calls);\n\tif (!(*queue)->front->next)\n\t{\n\t\tdestroy_node(&(*queue)->back);\n\t\t(*queue)->front = NULL;\n\t\treturn (0);\n\t}\n\ttemp = (*queue)->back;\n\twhile(temp->next && temp->next->next)\n\t\ttemp = temp->next;\n\t(*queue)->back = temp;\n\ttemp = (*queue)->front;\n\t(*queue)->front = (*queue)->front->next;\n\tdestroy_node(&temp);\n\treturn (0);\n}\n\n/**\n * @brief Devuelve el primer elemento de la cola.\n *\n * @param queue La pila.\n *\n * @return - NULL si no hay ningún elemento.\n * @return - El primer elemento de la cola.\n */\nchar\t*peek_queue(t_queue *queue)\n{\n\tif (!queue || !queue->front) return (NULL);\n\treturn (queue->front->item);\n}\n\n/* === DIFICULTAD EXTRA === */\n\n/**\n * @brief Simulación de un navegador web.\n *\n * @return - 0 Si se ha ejecutado correctamente.\n * @return - != 0 Si ha habido un error grave.\n */\nint\tweb_browser(void)\n{\n\tint\t\tstatus;\n\tt_web\t*web;\n\n\tstatus = 0;\n\tweb = (t_web *)malloc(sizeof(t_web));\n\tif (!web) return (-1);\n\tweb->history = create_stack(\"Inicio\");\n\tif (!web->history)\n\t{\n\t\tfree(web);\n\t\treturn (-2);\n\t}\n\tweb->temp = NULL;\n\tweb->flag = -1;\n\tweb->home_counter = 0;\n\twhile (status <= 0)\n\t{\n\t\tweb_browser_menu(&web);\n\t\tif (!fgets(web->input, MAX_SIZE, stdin))\n\t\t{\n\t\t\tstatus = -3;\n\t\t\tbreak;\n\t\t}\n\t\tweb->input[strlen(web->input) - 1] = '\\0';\n\t\tif (!strcmp(web->input, \"Atrás\") || !strcmp(web->input, \"atrás\")\n\t\t\t\t|| !strcmp(web->input, \"Atras\") || !strcmp(web->input, \"atras\")\n\t\t\t\t|| !strcmp(web->input, \"<-\"))\n\t\t\tstatus = web_browser_previous(&web);\n\t\telse if (!strcmp(web->input, \"Adelante\") || !strcmp(web->input, \"adelante\")\n\t\t\t\t|| !strcmp(web->input, \"->\"))\n\t\t\tstatus = web_browser_forward(&web);\n\t\telse if (!strcmp(web->input, \"Salir\") || !strcmp(web->input, \"salir\")\n\t\t\t\t|| !strcmp(web->input, \"X\") || !strcmp(web->input, \"x\"))\n\t\t{\n\t\t\tprintf(\"Has cerrado el navegador\\n\\n\\n\");\n\t\t\tstatus = 0;\n\t\t\tbreak;\n\t\t}\n\t\telse\n\t\t\tstatus = web_browser_navigate(&web);\n\t\tprintf(\"\\n\\n\");\n\t}\n\tdestroy_stack(&web->history);\n\tdestroy_stack(&web->temp);\n\tfree(web);\n\treturn (status);\n}\n\n/**\n * @brief Menú del navegador web\n *\n * @param web Dirección de memoria de la web.\n */\nvoid\tweb_browser_menu(t_web **web)\n{\n\tprintf(\"Buscador Variable    \");\n\tfor (size_t i = 0; i < strlen(peek_stack((*web)->history)); ++i)\n\t\tprintf(\" \");\n\tprintf(\"- o x\\n\");\n\tprintf(\"===========================\");\n\tfor (size_t i = 0; i < strlen(peek_stack((*web)->history)); ++i)\n\t\tprintf(\"=\");\n\tprintf(\"\\n| <-  -> |    %s    |       |\\n\", (*web)->history->top->item);\n\tprintf(\"===========================\");\n\tfor (size_t i = 0; i < strlen(peek_stack((*web)->history)); ++i)\n\t\tprintf(\"=\");\n\tprintf(\"\\n\");\n\tprintf(\"Introduce:\\n\");\n\tprintf(\"- El enlace una página web, para navegar hacia ella\\n\");\n\tprintf(\"- Adelante, para avanzar en el historial\\n\");\n\tprintf(\"- Atrás, para retroceder en el historial\\n\");\n\tprintf(\"- Salir, para cerrar el navegador\\n\");\n\tprintf(\">> \");\n}\n\n/**\n * @brief Navega hacia un enlace.\n *\n * @param web Dirección de memoria\n *\n * @return - 0 Si la navegación es exitosa.\n * @return - > 0 Si ha habido un problema navegando.\n */\nint\t\tweb_browser_navigate(t_web\t**web)\n{\n\tint\tstatus;\n\n\tstatus = push(&(*web)->history, (*web)->input);\n\tif (status) printf(\"Error navegando a %s\\n\", (*web)->input);\n\tif ((*web)->flag == 1)\n\t\tdestroy_stack(&(*web)->temp);\n\t(*web)->flag = 0;\n\tif (!strcmp(peek_stack((*web)->history), \"Inicio\"))\n\t\t(*web)->home_counter++;\n\treturn (status);\n}\n\n/**\n * @brief Navega una página hacia atrás.\n *\n * @param web Dirección de memoria de la web.\n *\n * @return - 0 Si la navegación es exitosa.\n * @return - != 0  Si ha habido un problema navegando.\n */\nint\t\tweb_browser_previous(t_web **web)\n{\n\tint\tstatus;\n\n\tif (!strcmp(peek_stack((*web)->history), \"Inicio\") && !(*web)->home_counter)\n\t{\n\t\tprintf(\"Has llegado al límite, no puedes retroceder\\n\");\n\t\treturn (-1);\n\t}\n\telse if (!strcmp(peek_stack((*web)->history), \"Inicio\"))\n\t\t(*web)->home_counter--;\n\tstatus = push(&(*web)->temp, peek_stack((*web)->history));\n\tif (status) printf(\"Error retrocediendo\\n\");\n\tpop(&(*web)->history);\n\t(*web)->flag = 1;\n\treturn (0);\n}\n\n/**\n * @brief Navega una página hacia adelante.\n *\n * @param web Dirección de memoria de la web.\n *\n * @return - 0 Si la navegación es exitosa.\n * @return - != 0  Si ha habido un problema navegando.\n */\nint\t\tweb_browser_forward(t_web **web)\n{\n\tint\t\tstatus;\n\tchar\t*link;\n\n\tif (!(*web)->temp || !(*web)->temp->top)\n\t{\n\t\tprintf(\"Has llegado al límite, no puedes avanzar\\n\");\n\t\treturn (-1);\n\t}\n\tif (!strcmp(peek_stack((*web)->temp), \"Inicio\"))\n\t\t(*web)->home_counter++;\n\tlink = peek_stack((*web)->temp);\n\tstatus = push(&(*web)->history, link);\n\tpop(&(*web)->temp);\n\treturn (status);\n}\n\n/**\n * @brief Simulación del comportamiento de una impresora.\n *\n * @return - 0 Si se ha ejecutado correctamente.\n * @return - != 0 Si ha habido un error grave.\n */\nint\t\tprinter(void)\n{\n\tint\t\t\tstatus;\n\tt_printer\t*printer;\n\n\tstatus = 0;\n\tprinter = (t_printer *) malloc(sizeof(t_printer));\n\tif (!printer) return (-1);\n\tprinter->queue = NULL;\n\twhile (status <= 0)\n\t{\n\t\tprinter_menu();\n\t\tif (!fgets(printer->input, sizeof(printer->input), stdin))\n\t\t{\n\t\t\tstatus = -2;\n\t\t\tbreak;\n\t\t}\n\t\tprinter->input[strlen(printer->input) - 1] = '\\0';\n\t\tif (!strcmp(printer->input, \"Imprimir\")\n\t\t\t\t|| !strcmp(printer->input, \"imprimir\"))\n\t\t\tstatus = printer_print(&printer);\n\t\telse if (!strcmp(printer->input, \"Eliminar\")\n\t\t\t\t|| !strcmp(printer->input, \"eliminar\"))\n\t\t\tstatus = printer_remove(&printer);\n\t\telse if (!strcmp(printer->input, \"Fin\")\n\t\t\t\t|| !strcmp(printer->input, \"fin\"))\n\t\t{\n\t\t\tprintf(\"Apagando impresora...\\n\");\n\t\t\tstatus = 0;\n\t\t\tbreak;\n\t\t}\n\t\telse\n\t\t\tstatus = printer_add(&printer);\n\t\tprintf(\"\\n\\n\");\n\t}\n\tdestroy_queue(&printer->queue);\n\tfree(printer);\n\treturn (status);\n}\n\n/**\n * @brief Menú de la impresora.\n */\nvoid\tprinter_menu(void)\n{\n\tprintf(\"========== IMPRESORA ==========\\n\");\n\tprintf(\"Introduce:\\n\");\n\tprintf(\"- El nombre del documento, para añadirlo a la cola\\n\");\n\tprintf(\"- Imprimir, para imprimir el primer documento en la cola\\n\");\n\tprintf(\"- Eliminar, para eliminar el primer documento de la cola\\n\");\n\tprintf(\"- Fin, para terminar de imprimir\\n\");\n\tprintf(\">> \");\n}\n\n/**\n * @brief Añade un documento a la cola.\n *\n * @param printer Dirección de memoria de la impresora.\n *\n * @return - 0 Si se añade correctamente.\n * @return - > 0 Si ha habido un problema.\n */\nint\tprinter_add(t_printer **printer)\n{\n\tint\tstatus;\n\n\tstatus = enqueue(&(*printer)->queue, (*printer)->input);\n\tif (!status)\n\t\tprintf(\"Se ha añadido %s a la cola\\n\", (*printer)->queue->back->item);\n\treturn (status);\n}\n\n/**\n * @brief Imprime el primer elemento en la cola.\n *\n * @param printer Dirección de memoria de la impresora.\n *\n * @return - 0 Si imprime correctamente. \n * @return - != 0 Si no imprime.\n */\nint\tprinter_print(t_printer **printer)\n{\n\tint\t\tstatus;\n\tchar\tdocument[MAX_SIZE];\n\n\tif (!(*printer)->queue || !(*printer)->queue->front)\n\t{\n\t\tprintf(\"No hay nada que imprimir\\n\");\n\t\treturn (-1);\n\t}\n\tstrcpy(document, (*printer)->queue->front->item);\n\tstatus = dequeue(&(*printer)->queue);\n\tif (status) return (status);\n\tprintf(\"Se ha imprimido %s correctamente\\n\", document);\n\treturn (0);\n}\n\n/**\n * @brief Elimina el último documento añadido.\n *\n * @param printer Dirección de memoria de la impresora.\n *\n * @return - 0 Si se elimina correctamente.\n * @return - != 0 Si no se elimina.\n */\nint\tprinter_remove(t_printer **printer)\n{\n\tchar\tdocument[MAX_SIZE];\n\tt_node\t*temp;\n\n\tif (!(*printer)->queue || !(*printer)->queue->front)\n\t{\n\t\tprintf(\"No hay nada en cola\\n\");\n\t\treturn (-1);\n\t}\n\tstrcpy(document, (*printer)->queue->back->item);\n\ttemp = (*printer)->queue->front;\n\tif (temp == (*printer)->queue->back) destroy_queue(&(*printer)->queue);\n\telse\n\t{\n\t\twhile (temp && temp->next != (*printer)->queue->back)\n\t\t\ttemp = temp->next;\n\t\ttemp->next = NULL;\n\t\tdestroy_node(&(*printer)->queue->back);\n\t\t(*printer)->queue->back = temp;\n\t}\n\tprintf(\"Se ha eliminado %s correctamente\\n\", document);\n\treturn (0);\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/c#/Andreavzqz.cs",
    "content": "using System; \n\nnamespace EjemploAsignacionYPaso\n{\n    class Persona\n    {\n        public string Nombre {get; set; }\n    }\n\n    class Program \n    {\n    static void Main (string[] args)\n    {\n        //Ejemplo de asignacion por valor\n        int a = 5;\n        int b = a; //b es una copia de a\n        b = 10;    // Cambiamos b, pero permanece igual\n        Console.WriteLine($\"a: {a}\"); //Imprime 5\n        Console.WriteLine($\"b: {b}\"); //Imprime 10\n\n        //Ejemplo de asignacion por referencia\n        Persona persona1 = new Persona();\n        persona1.Nombre = \"Juan\";\n        Persona.persona2 = persona1 // persona2 referencia el mismo objeto que persona1\n        persona2.Nombre = \"Pedro\"; // Cambiamos el nombre a traves de persona2\n        Console.WriteLine($\"persona1.Nombre: {persona1.Nombre}\"); //Imprime \"Pedro\"\n        Console.WriteLine($\"persona2.Nombre: {persona2.Nombre}\"); //Imprime \"Pedro\"\n\n        //Ejemplo de paso de parametro por valor\n        int numero = 5;\n        Incrementar(numero);\n        Console.WriteLine($\"numero despues de Incrementar: {numero}\"); // Imprime 5\n\n        // Ejemplo de paso de parametros por referencia\n        IncrementarRef(ref numero);\n        Console.WriteLine($\"numero despues de IncrementarRef: {numero}\"); // Imprime 6\n\n        //Ejemplo de paso de parametros por referencia con objetos\n        Persona persona = new Persona();\n        Persona.Nombre = \"Juan\";\n        CambiarNombre(persona);\n        Console.WriteLine($\"persona.Nombre despues de CambiarNombre: {persona.Nombre}\"); // Imprime \"Luis\"\n\n        // Ejemplo de modificazcion de la referencia del objeto\n        crearNuevaPersona(ref persona);\n        Console.WriteLine($\"persona.Nombre despues de crearNuevaPersona: {persona.Nombre}\"); // Imprime \"Carlos\"\n    }\n\n    //Funcion que recibe un parametro por valor\n    static void Incrementar(int x)\n        {\n            x++;\n            Console.WriteLine($\"x en Incrementar: {x}\"); // Imprime 6\n        }\n\n    //Funcion que recibe un parametro por referencia\n    static void IncrementarRef(ref int x)\n        {\n            x++;\n            Console.WriteLine($\"x en IncremetarRef: {x}\"); //Imprime 6\n        }\n\n    //Funcion que modifica una propiedad de un objeto\n    static void CambiarNombre(Persona p)\n    {\n        p.Nombre = \"Luis\";\n    }    \n\n    //Funcion que cambia la referencia de un objeto\n    static void crearNuevaPersona(ref Persona p)\n    {\n        p = new Persona();\n        p.Nombre = \"Carlos\";\n    }\n    \n  }\n /*\n\nExplicación:\n\nAsignación por Valor:\nint a = 5; int b = a;: b es una copia de a.\nCambiar b no afecta a a.\n\nAsignación por Referencia:\nPersona persona1 = new Persona(); Persona persona2 = persona1;: persona2 referencia el mismo objeto que persona1.\nCambiar una propiedad a través de persona2 afecta a persona1.\n\nPaso de Parámetros por Valor:\nIncrementar(numero);: La función recibe una copia del valor.\nCambios dentro de Incrementar no afectan a numero fuera de la función.\n\nPaso de Parámetros por Referencia:\nIncrementarRef(ref numero);: La función trabaja directamente con la variable original.\nCambios dentro de IncrementarRef afectan a numero fuera de la función.\n\nPaso de Parámetros por Referencia con Objetos:\nCambiarNombre(persona);: La función modifica una propiedad del objeto referenciado.\nCambios dentro de CambiarNombre afectan al objeto persona fuera de la función.\n\nModificación de la Referencia del Objeto:\nCrearNuevaPersona(ref persona);: La función cambia la referencia del objeto.\nDespués de CrearNuevaPersona, persona referencia a un nuevo objeto.\n\n*/\n\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/c#/Isj-code.cs",
    "content": "﻿// El Stack es un tipo de coleccion LIFO, el último de entrar es el primero en salir.\n\nStack<string> posiciones = new Stack<string>();\n\n// Añadir\nposiciones.Push(\"Uno\");\nposiciones.Push(\"Dos\");\nposiciones.Push(\"Tres\");\nposiciones.Push(\"Cuatro\");\n\nConsole.WriteLine(\"El Stack actualmente es: \");\nforeach (var item in posiciones)\n{\n    Console.Write($\"{item} \");\n}\n\nConsole.WriteLine(\"\\nEl Push empuja literalmente una posicion\");\n\n// Borramos con Pop el valor posicionado arriba de la pila, que será el ultimo en entrar\nposiciones.Pop();\n\n// Adquirir el valor del ultimo elemento en entrar sin borrar\nstring valorArriba = posiciones.Peek();\nConsole.WriteLine($\"\\nEl valor que está mas arriba despues de un borrado es: {valorArriba}\");\n\n// Busqueda dentro del Stack cocn Contains, este devuelve true en caso de encontrar valor\n\nbool siHay = posiciones.Contains(\"Dos\");\nif (siHay)\n{\n    Console.WriteLine(\"Buscamos el Dos y lo encontramos\");\n}\n\n// Queue es una cola donde el primer en entrar es el primero en salir.\n\nQueue<int> numeros = new Queue<int>();\n\nnumeros.Enqueue(1);\nnumeros.Enqueue(2);\nnumeros.Enqueue(3);\nnumeros.Enqueue(4);\nnumeros.Enqueue(5);\nnumeros.Enqueue(6);\n\nConsole.WriteLine(\"El Queue actualmente es: \");\nforeach (var item in numeros)\n{\n    Console.Write($\"{item} \");\n}\n\n// Borrar al primero en añadir\nnumeros.Dequeue();\n\n// Vemos el que seria el siguiente en salir pero sin borrar\nint proxSalir = numeros.Peek();\n\nConsole.WriteLine($\"\\nDespues de un borrado, el siguiente en salir seria {proxSalir}\");\n\n// añadimos numeros repetidos\n\nnumeros.Enqueue(1);\nnumeros.Enqueue(3);\nnumeros.Enqueue(4);\nnumeros.Enqueue(7);\n\n// Con Distinct podemos reunion los valores no repetidos unicamente\nConsole.WriteLine(\"Valores no repetidos despues de añadir alguno\");\nIEnumerable<int> distintos = numeros.Distinct();\nforeach (var item in distintos)\n{\n    Console.Write($\"{item} \");\n}\n\nConsole.WriteLine(\"----------------------\");\n\n// ## Dificultad Extra\n\n// Navegador\nvoid NavegadorWeb()\n{\n    Stack<string> direcciones = new Stack<string>();\n    Stack<string> descartes = new Stack<string>();\n    string resp = \"\";\n\n    do\n    {\n        Console.WriteLine(\"Indique la pagina a la que navegar, atras, adelante o salir\");\n        resp = Console.ReadLine().ToUpper();\n        switch (resp)\n        {\n            case \"SALIR\":\n                break;\n            case \"ATRAS\":\n                if (direcciones.Count > 0)\n                {\n                    descartes.Push(direcciones.Pop());\n                }\n\n                break;\n            case \"ADELANTE\":\n                if (descartes.Count > 0)\n                {\n                    direcciones.Push(descartes.Pop());\n                }\n\n                break;\n            default:\n                direcciones.Push(resp);\n                break;\n        }\n\n        if (direcciones.Count > 0)\n        {\n            Console.WriteLine($\"Navegaste a {direcciones.Peek()}\");\n        }\n        else\n        {\n            Console.WriteLine(\"Pagina de Inicio\");\n        }\n    } while (resp != \"SALIR\");\n}\n\nNavegadorWeb();\n\n// Impresora\n\nvoid Impresora()\n{\n    string resp = \"\";\n    Queue<string> colaImpresora = new Queue<string>();\n\n    do\n    {\n        Console.WriteLine(\"Impresora compartida, añada documento, indique IMPRIMIR o salir\");\n        resp = Console.ReadLine().ToUpper();\n\n        switch (resp)\n        {\n            case \"SALIR\":\n                break;\n            case \"IMPRIMIR\":\n                colaImpresora.Dequeue();\n                break;\n            default:\n                colaImpresora.Enqueue(resp);\n                break;\n        }\n\n        if (resp == \"SALIR\")\n        {\n            Console.WriteLine(\"SALIENDO\");\n        }\n        else\n        {\n            if (colaImpresora.Count > 0)\n            {\n                Console.WriteLine($\"El documento actual es: {colaImpresora.Peek()}\");\n            }\n            else\n            {\n                Console.WriteLine(\"Sin documentos en cola\");\n            }\n        }\n    } while (resp != \"SALIR\");\n}\n\nImpresora();"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/c#/arkmiguel379.cs",
    "content": "﻿using System.ComponentModel;\n\nList<int> cola = new List<int> {1,2,3,4,5};\n\nEnqueuePush(cola, 10);\n\nDequeueList(cola);\n\nConsole.WriteLine();\n\n//// ====================\n\nList<int> pila = new List<int> { 6, 7, 8, 9, 10 };\n\nEnqueuePush(pila, 11);\n\nPopList(pila);\n\n\n// === METODOS ===\n\nvoid EnqueuePush(List<int> collection, int number) // Este método funciona para ambos tipos de colección, tanto para \"Pilas\" y \"Colas\"\n{                                                   // ya que en realidad son Listas imitando ser otro tipo de colección.\n    collection.Add(number);                         // Este simula el comportamiento del método Enqueue de una Cola o Push de una Pila\n\n    foreach (int i in collection)\n    {\n        Console.Write($\"{i} \");\n    }\n    Console.WriteLine(\"\\n\");\n}\n\n// Método de recuperación para la Queue\nvoid DequeueList(List<int> queue) // Este método recupera el primer elemento que se a introducido dentro de la \"Cola\"\n{                                 // simulando el comportamiento del método Dequeue.\n    int recovered = queue[0];\n    queue.RemoveAt(0);\n    Console.WriteLine($\"El elemento recuperado es: {recovered}\");\n}\n\n// Método de recuperación para la Stack\n\nvoid PopList(List<int> stack) // Este elemento recupera el ultimo elemento que se a introducido dentro de la \"Pila\"\n{                                       // simulando el comportamiento del método Pop.\n    int recovered = stack.Count - 1;\n    int element = stack[recovered];\n    stack.RemoveAt(recovered);\n    Console.WriteLine($\"El elemento recuperado es: {element}\");\n\n    Console.WriteLine(\"\\n\");\n}\n\n// === EXTRA ===\n\nConsole.WriteLine(\"=== Impresora === \\n\");\n\nConsole.WriteLine(\"Ingrese palabras (documentos) para que se vayan acumulando en la cola de la impresora, si desea ir imprimiendo los 'documentos'\");\nConsole.WriteLine(\"escriba la palabra 'imprimir'. \\n\");\nConsole.WriteLine(\"Si ya no desea seguir trabajando con la impresora, escriba 'salir' \\n\");\n\nList<string> documentation = new List<string>();\n\nbool exit = false;\n\nwhile (!exit)\n{\n    string instruction = Console.ReadLine();\n    instruction = instruction.ToLower();\n\n    if (instruction == \"salir\")\n    {\n        exit = true;\n    }\n    else if (instruction == \"imprimir\")\n    {\n        if (documentation.Count() > 0)\n        {\n            PrintDocumentation();\n        }\n        else\n        {\n            Console.WriteLine(\"Ya no hay elementos en la cola para imprimir\");\n        }\n    }\n    else if (instruction != \"imprimir\")\n    {\n        AddDocumentation(instruction);\n    }\n}\n\nConsole.WriteLine();\n\n// ====== Métodos para la impresora ======\n\nvoid AddDocumentation(string doc)\n{\n    documentation.Add(doc);\n}\n\nvoid PrintDocumentation()\n{\n    string recovered = documentation[0];\n    documentation.RemoveAt(0);\n    Console.Write(\"imprimiendo\");\n\n    for (int i = 0; i <= 5; i++)\n    {\n        Thread.Sleep(500);\n        Console.Write(\".\");\n    }\n\n    Console.WriteLine();\n    Console.WriteLine(recovered);\n}\n\n// ====================================\n\nConsole.WriteLine(\"=== Navegador Web === \\n\");\n\nConsole.WriteLine(\"Para moverse por el navegador web puede hacerlo con los comandos 'adelante' y 'atras'\");\nConsole.WriteLine(\"Si desea cerrar el navegador, escriba 'cerrar' \\n\");\n\nList<string> navWeb = new List<string> {\"Pagina Principal\"};\n\nConsole.WriteLine(navWeb[0], \"\\n\");\n\nbool navBool = false;\n\nwhile (!navBool)\n{\n    string page = Console.ReadLine();\n    Console.WriteLine();\n\n    if (page == \"adelante\")\n    {\n        Forward();\n    }\n    else if (page == \"atras\")\n    {\n        Back();\n    }\n    else if (page == \"cerrar\")\n    {\n        navBool = true;\n    }\n    else\n    {\n        Console.WriteLine(\"Comando no valido, solo se admite 'adelante' o 'atras'\");\n    }\n}\n\n// ====== Métodos para el navegador web ======\n\nvoid Forward()\n{\n    int recovered = navWeb.Count - 1;\n    string element = navWeb[recovered];\n\n    if (element == \"Pagina Principal\")\n    {\n        navWeb.Add(\"Menú\");\n        int lastI = navWeb.Count - 1;\n        string valueLastI = navWeb[lastI];\n        Console.WriteLine(valueLastI, \"\\n\");\n    }\n    else if (element == \"Menú\")\n    {\n        navWeb.Add(\"Submenú\");\n        int lastI = navWeb.Count - 1;\n        string valueLastI = navWeb[lastI];\n        Console.WriteLine(valueLastI, \"\\n\");\n    }\n    else if (element == \"Submenú\")\n    {\n        navWeb.Add(\"Opciones\");\n        int lastI = navWeb.Count - 1;\n        string valueLastI = navWeb[lastI];\n        Console.WriteLine(valueLastI, \"\\n\");\n    }\n    else if (element == \"Opciones\")\n    {\n        navWeb.Add(\"Configuración\");\n        int lastI = navWeb.Count - 1;\n        string valueLastI = navWeb[lastI];\n        Console.WriteLine(valueLastI, \"\\n\");\n    }\n    else\n    {\n        Console.WriteLine(\"Ya no se puede ir mas para adelante \\n\");\n    }\n}\n\nvoid Back() \n{\n    int recovered = navWeb.Count - 1;\n    string element = navWeb[recovered];\n\n    if (element == \"Pagina Principal\")\n    {\n        Console.WriteLine(\"Ya no se puede ir mas para atras\");\n    }\n    else\n    {\n        element = navWeb[recovered - 1];\n        navWeb.RemoveAt(recovered);\n        Console.WriteLine(element, \"\\n\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/c#/charlerodriguez3.cs",
    "content": "/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n*/\n\n/*\n * explicitamente tiene que utilizarse List en vez de Array, ya que el array\n * tiende a ser una estructura que tiene que ser inicializada su tamaño o sus elementos\n * antes de compilar\n */\n\n\n//PILA O STACK\nList<int> pila = new();\nint opc = 1, eli = 2;\nint num = 0;\n\n\nwhile (opc != 2)\n{\n    Console.WriteLine(\"Quiere seguir agregando mas numeros ? Si(1) No(2)\");\n    opc = int.Parse(Console.ReadLine());\n    if (opc == 2) continue;\n    Console.Clear();\n    Console.WriteLine(\"Digite el numero a agregar:\");\n    num  = int.Parse(Console.ReadLine());\n    pila.Add(num);\n    Console.Clear();\n    int peek = pila.IndexOf(num);//peek for the stack\n    Console.WriteLine(\"\\nLa pila es esta hasta el momento:\\n \");\n    pila.Reverse();\n    if(pila.Count() > 0)//verificar que la pila tenga elementos para poder mostrarlos\n    {\n        foreach (int i in pila)//mostrar todos los elementos de la pila\n        {\n            Console.WriteLine(i);\n        }\n    }\n    else\n    {\n        Console.WriteLine(\"La pila no tiene elementos\");\n    }\n    pila.Reverse();\n    Console.WriteLine($\"Desea eliminar el ultimo numero de la pila? En este caso {pila[peek]} \\n Si(1) No(2)\");\n    eli = int.Parse(Console.ReadLine());\n    if(eli == 1)\n    {\n        pila.Remove(pila[peek]); //eliminar el ultimo elemento ingresado\n    }\n    Console.Clear();\n}\n\npila.Reverse();\nConsole.WriteLine(\"\\n Pila Final \\n\");\nif (pila.Count() > 0)//verificar que la pila tenga elementos para poder mostrarlos\n{\n    foreach (int i in pila)//mostrar todos los elementos de la pila\n    {\n        Console.WriteLine(i);\n    }\n}\nelse\n{\n    Console.WriteLine(\"La pila no tiene elementos\");\n}\n\n//COLA O QUEUE primero en entrar primero en salir\nList<int> cola = new();\n\n\nint opc = 1, eli = 2;\nint num = 0;\n\n\nwhile (opc != 2)\n{\n    Console.WriteLine(\"Quiere seguir agregando mas numeros a la cola ? Si(1) No(2)\");\n    opc = int.Parse(Console.ReadLine());\n    if (opc == 2) continue;\n    Console.Clear();\n    Console.WriteLine(\"Digite el numero a agregar:\");\n    num = int.Parse(Console.ReadLine());\n    cola.Add(num);\n    Console.Clear();\n    int salida = cola[0];//salida para la cola\n    Console.WriteLine(\"\\nCola o queue actual:\\n \");\n    if (cola.Count() > 0)//verificar que la pila tenga elementos para poder mostrarlos\n    {\n        foreach (int i in cola)//mostrar todos los elementos de la pila\n        {\n            Console.Write(i + \"-\");\n        }\n        Console.WriteLine(\"\");\n    }\n    else\n    {\n        Console.WriteLine(\"La pila no tiene elementos\");\n    }\n    Console.WriteLine($\"Desea eliminar el elemento de la cola[ se eliminará el primero]? En este caso valor: {salida} \\n Si(1) No(2)\");\n    eli = int.Parse(Console.ReadLine());\n    if (eli == 1)\n    {\n        cola.Remove(salida); //eliminar el primer elemento en la cola\n    }\n    Console.Clear();\n}\n\nConsole.WriteLine(\"\\n Cola o queue Final \\n\");\nif (cola.Count() > 0)//verificar que la pila tenga elementos para poder mostrarlos\n{\n    foreach (int i in cola)//mostrar todos los elementos de la pila\n    {\n        Console.Write(i + \"-\");\n    }\n    Console.WriteLine(\"\");\n}\nelse\n{\n    Console.WriteLine(\"La cola no tiene elementos\");\n}\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n\n\n Stack<string> browser = new Stack<string>();\n\nstring pagina = \"\";\n\n\nwhile (true)\n{\n    Console.WriteLine(\"Ingresa una url o interactua con atras/siguiente/salir\");\n    pagina = Console.ReadLine();\n    if(pagina == \"salir\")\n    {\n        break;\n    }else if( pagina == \"siguiente\")\n    {\n        continue;\n    }else if(pagina == \"atras\")\n    {\n        if(browser.Count > 0) browser.Pop();\n    }\n    else\n    {\n        browser.Push(pagina);\n    }\n\n    if (browser.Count > 0)\n    {\n        Console.Clear();\n        Console.WriteLine(\"Pagina actual [HEAD]-> \" + browser.Peek());\n    }\n    else\n    {\n        Console.WriteLine(\"Estas en la pagina de inicio\");\n    }\n}\n\n\nQueue<string> queue = new Queue<string>();\nstring pagina2 = \"\";\nwhile (true)\n{\n    Console.WriteLine(\"Que desea hacer? Imprimir o agregar una hoja a la impresora(nombre del archivo) | Salir\");\n    pagina2 = Console.ReadLine();\n    Console.Clear();\n    if (pagina2 == \"imprimir\")\n    {\n        if(queue.Count > 0) Console.WriteLine($\" Documento impreso correctamente : {queue.Dequeue()}\");\n        else Console.WriteLine(\"Bandeja Vacía. Impresora sin documentos pendientes para imprimir\");\n    }\n    else if(pagina2 == \"salir\")\n    {\n        break;\n    }\n    else\n    {\n        queue.Enqueue(pagina2);\n        Console.WriteLine(\"Documento guardado y listo para imprimir\");\n    }\n}"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/c#/devcherry1.cs",
    "content": "using System;\n\nclass Program\n{\n    static void Main()\n    {\n        Stack<string> urls = new Stack<string>();\n        Extra.Navegador(urls);\n\n        Queue<string> cola = new Queue<string>();\n        Extra.Imprimir(cola);\n    }\n}\nclass Extra\n{\n    public static void Navegador(Stack<string> urls)\n    {\n        Console.WriteLine($\"Ingrese una url valida o seleccione una de estas opciones: \" +\n                          $\"\\n 1.Atras\" +\n                          $\"\\n 2.Salir\");\n        string opcion = Console.ReadLine();\n\n        switch (opcion)\n        {\n            case \"1\":\n                if (urls.Count > 0)\n                {\n                    urls.Pop();\n                    if (urls.Count > 0)\n                    {\n                        Console.WriteLine($\"Has regresado a la web: {urls.Peek()}\");\n                    }\n                    else\n                    {\n                        Console.WriteLine(\"No hay más páginas en el historial.\");\n                    }\n                }\n                else\n                {\n                    Console.WriteLine(\"El historial está vacío. No puedes regresar.\");\n                }\n                break;\n            case \"2\":\n                Console.WriteLine(\"Saliendo del navegador.\");\n                return;\n            default:\n                urls.Push(opcion);\n                Console.WriteLine($\"Has navegado a la web {urls.Peek()}\");\n                break;\n        }\n        Navegador(urls);\n    }\n    public static void Imprimir(Queue<string> cola)\n    {\n        Console.WriteLine($\"Ingrese un documento o seleccione una de estas opciones: \" +\n                          $\"\\n 1.Imprimir\" +\n                          $\"\\n 2.Salir\");\n        string opcion = Console.ReadLine();\n\n        switch (opcion)\n        {\n            case \"1\":\n                if (cola.Count > 0)\n                {\n                    if (cola.Count > 0)\n                    {\n                        Console.WriteLine($\"El documento {cola.Dequeue()} ha sido impreso\");\n                    }\n                    else\n                    {\n                        Console.WriteLine(\"No hay más documentos para imprimir.\");\n                    }\n                }\n                else\n                {\n                    Console.WriteLine(\"No hay más documentos para imprimir.\");\n                }\n                break;\n            case \"2\":\n                Console.WriteLine(\"Apagando impresora.\");\n                return;\n            default:\n                cola.Enqueue(opcion);\n                Console.WriteLine($\"El documento {opcion} ha sido agregado\");\n                break;\n        }\n        Imprimir(cola);\n    }\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/c#/estuardodev.cs",
    "content": "/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atras\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n\n\nusing System;\nnamespace estuardodev\n{\n    internal class Program\n    {\n        public static void Main(string[] args)\n        {\n            Queue<string> queue = new Queue<string>();\n            queue.Enqueue(\"Estuardo\");\n            queue.Enqueue(\"Lilian\");\n            queue.Enqueue(\"C#\");\n            queue.Enqueue(\"Python\");\n\n            Stack<string> stack = new Stack<string>();\n            stack.Push(\"Estuardo\");\n            stack.Push(\"Lilian\");\n            stack.Push(\"C#\");\n            stack.Push(\"Python\");\n\n            Ejercicio(queue, stack);\n            Web();\n            Impresora();\n        }\n        \n\n        static void  Ejercicio(Queue<string> values, Stack<string> valores) \n        {\n            Console.WriteLine(\"-- Primero en entrar, Primero en salir --\");\n            foreach (var item in values)\n            {\n                Console.WriteLine(item.ToString());\n            }\n\n\n            Console.WriteLine(\"\\n-- Último en entrar, Primero en salir --\");\n            foreach (var item in valores)\n            {\n                Console.WriteLine(item.ToString());\n            }\n        }\n\n        static void Web()\n        {\n            Console.WriteLine(\"\\n¿Qué desea hacer?\");\n            Stack<string> historial = new Stack<string>();\n            string paginaActual = \"Google\";\n            int contador = 0;\n\n            while (contador < 5)\n            {\n                Console.WriteLine(\"Estas en : \" + paginaActual);\n                if (paginaActual.Equals(\"Google\"))\n                {\n                    Console.Write(\"Ingrese un comando (adelante 'Nombre de la web'): \");\n                }\n                else\n                {\n                    Console.Write(\"Ingrese un comando (adelante 'Nombre de la web', 'atras'): \");\n                }\n                \n                string comando = Console.ReadLine().ToLower();\n                if (comando.Contains(\"adelante\"))\n                {\n                    string[] palabrras = comando.Split(' ');\n                    Console.WriteLine($\"Entrando a {palabrras[1]}\");\n                    historial.Push(paginaActual);\n                    paginaActual = palabrras[1];\n                }\n                else\n                {\n                    Console.WriteLine($\"Regresando a {historial.Peek()}\");\n                    paginaActual = historial.Peek();\n                    historial.Push(paginaActual);\n                    \n                }\n                contador++;\n            }\n            if (contador == 5)\n            {\n                Console.WriteLine(\"\\n Gracias por usar nuestro navegador :)\");\n            }\n        }\n\n        static void Impresora()\n        {\n            Queue<string> documentos = new Queue<string>();\n            int contador = 0;\n\n            while (contador < 5)\n            {\n                Console.WriteLine(\"\\nPara imprimir escriba 'imprimir' o agregue documentos con 'agregar -Nombre-' y si desea imprimir un solo documento escriba 'imprimir -Nombre-'\");\n                string entrada = Console.ReadLine();\n                if (entrada.Equals(\"imprimir\"))\n                {\n                    foreach(string s in documentos)\n                    {\n                        Console.WriteLine($\"Imprimiendo: {s}\");\n                    }\n                    Console.WriteLine(\"\\nDocumentos totalmente impresos.\");\n                    documentos.Clear();\n                } else if (entrada.Contains(\"imprimir\") && entrada.Length > 8)\n                {\n                    string[] valores = entrada.Split(\" \");\n                    Console.WriteLine($\"Imprimiendo: {valores[1]}\");\n                    Console.WriteLine(\"\\nDocumento totalmente impreso.\");\n\n                } else if (entrada.Contains(\"agregar\"))\n                {\n                    string[] valores = entrada.Split(\" \");\n                    documentos.Enqueue(valores[1]);\n                }\n                contador ++;\n            }\n            if (contador == 5)\n            {\n                Console.WriteLine(\"\\n Gracias por usar nuestra impresora :)\");\n            }\n        }\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/c#/hequebo.cs",
    "content": "class Program\n{\n    static void Main(string[] args)\n    {\n        // Pilas y Colas\n        Console.WriteLine(\"----PILAS Y COLAS----\");\n        List<int> pila = new List<int> {6, 5, 4, 3, 2, 1};\n        Console.WriteLine(\"---Pilas---\");\n        Console.WriteLine(\"Pila Inicial:\");\n        Mostrar(pila);\n        Push(ref pila, 7);\n        Console.WriteLine(\"Se inserta elemento 7 en la pila\");\n        Console.WriteLine(\"Pila Actual:\");\n        Mostrar(pila);\n        Console.WriteLine(\"Se elimina último elemento ingresado en la pila\");\n        Pop(ref pila);\n        Console.WriteLine(\"Pila Actual:\");\n        Mostrar(pila);\n\n        // Colas\n        Console.WriteLine(\"---Colas---\");\n        List<int> cola = new List<int> {1, 2, 3, 4, 5};\n        Console.WriteLine(\"Cola Inicial:\");\n        Mostrar(cola);\n        Console.WriteLine(\"Se agrega número 6 en la cola\");\n        Queue(ref cola, 6);\n        Console.WriteLine(\"Cola Actual:\");\n        Mostrar(cola);\n        Console.WriteLine(\"Se elimina primer elemento agregado a la cola\");\n        Dequeue(ref cola);\n        Console.WriteLine(\"Cola Actual:\");\n        Mostrar(cola);\n        Console.ReadLine();\n        Console.Clear();\n\n        // Ejercicio Extra\n        NavegadorWeb();\n        Console.Clear();\n        Impresora();\n\n    }\n    static void Mostrar(List<int> lista)\n    {\n        if (lista.Count == 0)\n        {\n            Console.WriteLine(\"No hay elemntos por mostar...\");\n            return;\n        }\n        foreach (int i in lista)\n            Console.Write($\"{i},\");\n        Console.WriteLine();\n    }\n    static void Push(ref List<int> pila, int num)\n    {\n        pila.Reverse();\n        pila.Add(num);\n        pila.Reverse();\n    }\n    static void Pop(ref List<int> pila)\n    {\n        if (pila.Count == 0)\n        {\n            Console.WriteLine(\"La pila esta vacía...\");\n            return;\n        }\n\n        Console.WriteLine($\"Elemento eliminado: {pila.First()}\");\n        pila.Remove(pila.First());\n    }\n    static void Queue(ref List<int> cola, int num)\n    {\n        cola.Add(num);\n    }\n    static void Dequeue(ref List<int> cola) \n    { \n        if (cola.Count == 0)\n        {\n            Console.WriteLine(\"La cola está vacía...\");\n            return;\n        }\n        Console.WriteLine($\"Elemento eliminado: {cola.First()}\");\n        cola.Remove(cola.First());\n    }\n    static void NavegadorWeb()\n    {\n        List<string> urls = new List<string>();\n        bool salir = false;\n        Console.Clear();\n        Console.WriteLine(\"---Sistema de navegación web---\");\n        do\n        {\n            Console.WriteLine(\"Ingresa la url a la que deseas acceder o selecciona una de las siguientes opciones\");\n            Console.WriteLine(\"[Atrás/Adelante/Salir]\");\n            string opcion = Console.ReadLine();\n            Console.Clear();\n            if (opcion.ToLower() == \"atrás\")\n            {\n                if (urls.Count == 0)\n                    Console.WriteLine(\"No es posible ir atrás\");\n                else\n                    urls.Remove(urls.First());\n            }\n            else if (opcion.ToLower() == \"adelante\")\n            {\n                Console.WriteLine(\"No es posible ir adelante\");\n            }\n            else if (opcion.ToLower() == \"salir\")\n            {\n                salir = true;\n                Console.WriteLine(\"Estás saliendo del navegador...\");\n                Thread.Sleep(2000);\n            }\n            else\n            {\n                urls.Insert(0, opcion);\n            }\n\n            if (urls.Count == 0)\n                Console.WriteLine(\"Te encuentras en la página de inicio.\");\n            else\n                Console.WriteLine($\"Te encuentras en el sitio {urls.First()}\");\n        } while (!salir);\n    }\n    static void Impresora()\n    {\n        List<string> documentos = new List<string>();\n        bool salir = false;\n\n        do\n        {\n            Console.WriteLine(\"---Sistema de impresión---\");\n            Console.WriteLine(\"Ingresa el nombre de un documento para agregarlo a la cola de impresión.\");\n            Console.WriteLine(\"O utiliza el comando \\\"imprimir\\\" para imprimir el siguiente documento\");\n            Console.WriteLine(\"Utiliza el comando \\\"salir\\\" para salir del sistema...\");\n\n            string opcion = Console.ReadLine();\n            Console.Clear();\n            if (opcion.ToLower() == \"imprimir\")\n            {\n                if (documentos.Count == 0)\n                    Console.WriteLine(\"La cola está vacía...\");\n                else\n                {\n                    Console.WriteLine($\"Imprimiendo documento \\\"{documentos.First()}\\\"\");\n                    Thread.Sleep(1000);\n                    Console.WriteLine($\"El documento \\\"{documentos.First()}\\\" se imprimío correctamente...\");\n                    documentos.Remove(documentos.First());\n                }\n            }\n            else if (opcion.ToLower() == \"salir\")\n            {\n                salir = true;\n                Console.WriteLine(\"Saliendo del sistema de impresión...\");\n                Thread.Sleep(2000);\n            }\n            else\n            {\n                documentos.Add(opcion);\n                Console.WriteLine($\"Se agregó el documento \\\"{opcion}\\\" a la cola de impresión...\");\n            }\n\n            if (documentos.Count == 0)\n                Console.WriteLine(\"No hay documentos pendientes por imprimir...\");\n        } while (!salir);\n    }\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/c#/isaacus98.cs",
    "content": "﻿/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n\nnamespace RetosProgramacion2024\n{\n    internal class Program\n    {\n        static void Main(string[] args)\n        {\n            // Queue\n            Queue<int> fifo = new Queue<int>();\n\n            // Insertar elementos en la cola\n            fifo.Enqueue(1);\n            fifo.Enqueue(2);\n            fifo.Enqueue(3);\n            fifo.Enqueue(4);\n\n            // Mostrar elementos de la cola sin eliminar el elemento. El elemeto que se muestra se va al final de la cola\n            fifo.Peek();\n            fifo.Peek();\n            fifo.Peek();\n            fifo.Peek();\n\n            // Mostrar elementos de la cola\n            fifo.Dequeue();\n            fifo.Dequeue();\n            fifo.Dequeue();\n            fifo.Dequeue();\n\n            // Stack\n            Stack<int> lifo = new Stack<int>();\n\n            // Insertar elementos en la pila\n            lifo.Push(1);\n            lifo.Push(2);\n            lifo.Push(3);\n            lifo.Push(4);\n\n            // Mostrar elementos de la pila sin eliminar el elemento. El elemeto que se muestra se va al final de la pila\n            lifo.Peek();\n            lifo.Peek();\n            lifo.Peek();\n            lifo.Peek();\n\n            // Mostrar elementos de la pila\n            lifo.Pop();\n            lifo.Pop();\n            lifo.Pop();\n            lifo.Pop();\n\n            // Dificultad extra\n            NavegadorWeb();\n            ImpressoraCompartida();\n        }\n\n        private static void NavegadorWeb()\n        {\n            Console.WriteLine(\"Escribe \\\"salir\\\" para salir de la aplicación\");\n            Console.WriteLine(\"Escribe \\\"adelante\\\" para moverte hacia adelante\");\n            Console.WriteLine(\"Escribe \\\"atras\\\" para moverte hacia atras\");\n\n            Stack<string> stackBack = new();\n            Stack<string> stackForward = new();\n            bool exit = false;\n            string webname = \"\";\n\n            while (!exit)\n            {\n                Console.WriteLine(\"Escribe el comando o nombre de la web:\");\n                string? temp = Console.ReadLine();\n                temp ??= \"\";\n\n                switch (temp.ToLower())\n                {\n                    case \"atras\":\n                        if (stackBack.Count == 0)\n                        {\n                            Console.WriteLine(\"No se puede ir atras\");\n                            break;\n                        }\n\n                        stackForward.Push(webname);\n                        webname = stackBack.Pop();\n                        Console.WriteLine($\"web: {webname}\");\n                        break;\n                    case \"adelante\":\n                        if (stackForward.Count == 0)\n                        {\n                            Console.WriteLine(\"No se puede ir adelante\");\n                            break;\n                        }\n\n                        stackBack.Push(webname);\n                        webname = stackForward.Pop();\n                        Console.WriteLine($\"Web: {webname}\");\n                        break;\n                    case \"salir\":\n                        exit = true;\n                        break;\n                    default:\n                        if (temp != \"\")\n                        {\n                            if (webname != \"\")\n                                stackBack.Push(webname);\n                            webname = temp;\n                            Console.WriteLine($\"Web: {webname}\");\n                        }\n                        break;\n                }\n            }\n        }\n\n        private static void ImpressoraCompartida()\n        {\n            Console.WriteLine(\"Escribe \\\"salir\\\" para salir de la aplicación\");\n            Console.WriteLine(\"Escribe \\\"imprimir\\\" para imprimir el documente\");\n\n            Queue<string> documentos = new();\n            bool exit = false;\n\n            while (!exit)\n            {\n                Console.WriteLine(\"Escribe el comando o el nombre del documento:\");\n                string? temp = Console.ReadLine();\n                temp ??= \"\";\n\n                switch (temp.ToLower())\n                {\n                    case \"imprimir\":\n                        if (documentos.Count == 0)\n                        {\n                            Console.WriteLine(\"No hay documetos en la cola\");\n                        }\n                        else\n                        {\n                            Console.WriteLine($\"Imprimiendo el documento {documentos.Dequeue()}\");\n                        }\n                        break;\n                    case \"salir\":\n                        exit = true;\n                        break;\n                    default:\n                        if (temp != \"\")\n                            documentos.Enqueue(temp);\n                        break;\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/c#/jamerrq.cs",
    "content": "/*\n * EJERCICIO: Implementa los mecanismos de introducción y recuperación de\n * elementos propios de las pilas (stacks - LIFO) y las colas (queue - FIFO)\n * utilizando una estructura de array o lista (dependiendo de las posibilidades\n * de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el\n *   mecanismo adelante/atrás de un navegador web. Crea un programa en el que\n *   puedas navegar a una página o indicarle que te quieres desplazar adelante o\n *   atrás, mostrando en cada caso el nombre de la web. Las palabras \"adelante\",\n *   \"atras\" desencadenan esta acción, el resto se interpreta como el nombre de\n *   una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el\n *   mecanismo de una impresora compartida que recibe documentos y los imprime\n *   cuando así se le indica. La palabra \"imprimir\" imprime un elemento de la\n *   cola, el resto de palabras se interpretan como nombres de documentos.\n*/\n\nusing System;\n\nclass Stack<T>(int size)\n{\n    readonly T[] stack = new T[size];\n    private int top = -1;\n    readonly int size = size;\n\n    public void Push(T item)\n    {\n        if (top == size - 1)\n        {\n            Console.WriteLine(\"Stack is full!\");\n            return;\n        }\n        stack[++top] = item;\n    }\n\n    public T? Pop()\n    {\n        if (top == -1)\n        {\n            Console.WriteLine(\"Stack is empty!\");\n            return default;\n        }\n        return stack[top--];\n    }\n\n    public T? Peek()\n    {\n        if (top == -1)\n        {\n            Console.WriteLine(\"Stack is empty!\");\n            return default;\n        }\n        return stack[top];\n    }\n}\n\nclass Queue<T>(int size)\n{\n    readonly T[] queue = new T[size];\n    private int front = -1;\n    private int rear = -1;\n    readonly int size = size;\n\n    public void Enqueue(T item)\n    {\n        if (rear == size - 1)\n        {\n            Console.WriteLine(\"La cola está llena!\");\n            return;\n        }\n        queue[++rear] = item;\n        if (front == -1)\n        {\n            front = 0;\n        }\n    }\n\n    public T? Dequeue()\n    {\n        if (front == -1)\n        {\n            Console.WriteLine(\"No hay elementos en la cola!\");\n            return default;\n        }\n        T item = queue[front];\n        if (front == rear)\n        {\n            front = -1;\n            rear = -1;\n        }\n        else\n        {\n            front++;\n        }\n        return item;\n    }\n\n    public T? Peek()\n    {\n        if (front == -1)\n        {\n            Console.WriteLine(\"Queue is empty!\");\n            return default;\n        }\n        return queue[front];\n    }\n}\n\nclass History\n{\n    private readonly Stack<string> back = new(10);\n    private readonly Stack<string> forward = new(10);\n\n    public void GoTo(string page)\n    {\n        back.Push(page);\n    }\n\n    public string Back()\n    {\n        if (back.Peek() == null)\n        {\n            return \"about:blank\";\n        }\n        forward.Push(back.Pop()!);\n        return back.Peek()!;\n    }\n\n    public string Forward()\n    {\n        if (forward.Peek() == null)\n        {\n            return \"about:blank\";\n        }\n        back.Push(forward.Pop()!);\n        return back.Peek()!;\n    }\n\n    public string Current()\n    {\n        return back.Peek() ?? \"about:blank\";\n    }\n}\nclass StacksAndQueues\n{\n\n    // Pilas\n    static void Stacks()\n    {\n        Console.WriteLine(\"> Crear una pila de 5 elementos\");\n        Console.WriteLine(\"Stack stack = new Stack(3);\");\n        Stack<int> stack = new(3);\n        Console.WriteLine(\"> Agregar elementos a la pila\");\n        Console.WriteLine(\"stack.Push(1);\");\n        stack.Push(1);\n        Console.WriteLine(\"stack.Push(2);\");\n        stack.Push(2);\n        Console.WriteLine(\"stack.Push(3);\");\n        stack.Push(3);\n        Console.WriteLine(\"> Sacar elementos de la pila\");\n        Console.WriteLine(\"stack.Pop();\");\n        Console.WriteLine(stack.Pop());\n        Console.WriteLine(\"stack.Pop();\");\n        Console.WriteLine(stack.Pop());\n    }\n\n    // Colas\n    static void Queues()\n    {\n        Console.WriteLine(\"> Crear una cola de 5 elementos\");\n        Console.WriteLine(\"Queue queue = new Queue(3);\");\n        Queue<int> queue = new(3);\n        Console.WriteLine(\"> Agregar elementos a la cola\");\n        Console.WriteLine(\"queue.Enqueue(1);\");\n        queue.Enqueue(1);\n        Console.WriteLine(\"queue.Enqueue(2);\");\n        queue.Enqueue(2);\n        Console.WriteLine(\"queue.Enqueue(3);\");\n        queue.Enqueue(3);\n        Console.WriteLine(\"> Sacar elementos de la cola\");\n        Console.WriteLine(\"queue.Dequeue();\");\n        Console.WriteLine(queue.Dequeue());\n        Console.WriteLine(\"queue.Dequeue();\");\n        Console.WriteLine(queue.Dequeue());\n    }\n\n    static void NavegadorWeb()\n    {\n        // Historial de navegación\n        History history = new();\n\n        // Mensaje de bienvenida\n        Console.WriteLine(\"Bienvenido al historial de navegación web\\n\");\n        Console.WriteLine(\"Empezarás en la página about:blank\\n\");\n        Console.WriteLine(\"Disfruta de tu navegación!\\n\");\n\n        static void menu()\n        {\n            Console.WriteLine(\"Menú:\\n\");\n            Console.WriteLine(\"1. Navegar a una página\");\n            Console.WriteLine(\"2. Retroceder\");\n            Console.WriteLine(\"3. Avanzar\");\n            Console.WriteLine(\"4. Página actual\");\n            Console.WriteLine(\"5. Salir\\n\");\n        }\n        while (true)\n        {\n            menu();\n            Console.Write(\"> Tu opción: \");\n            string option = Console.ReadLine() ?? \"\";\n            switch (option)\n            {\n                case \"1\":\n                    Console.Write(\"Página: \");\n                    string page = Console.ReadLine() ?? \"about:blank\";\n                    history.GoTo(page);\n                    Console.WriteLine($\"* Navegando a {page}\\n\");\n                    break;\n                case \"2\":\n                    Console.WriteLine($\"* Retrocediendo a {history.Back()}\\n\");\n                    break;\n                case \"3\":\n                    Console.WriteLine($\"* Avanzando a {history.Forward()}\\n\");\n                    break;\n                case \"4\":\n                    Console.WriteLine($\"* Página actual: {history.Current()}\\n\");\n                    break;\n                case \"5\":\n                    Console.WriteLine(\"Nos vemos!\");\n                    return;\n            }\n        }\n    }\n\n    // Impresora\n    static void Impresora()\n    {\n        // Cola de impresión\n        Queue<string> printer = new(10);\n\n        static void menu()\n        {\n            Console.WriteLine(\"Menú:\\n\");\n            Console.WriteLine(\"1. Imprimir un documento\");\n            Console.WriteLine(\"2. Agregar un documento a la cola\");\n            Console.WriteLine(\"3. Salir\\n\");\n        }\n        while (true)\n        {\n            menu();\n            Console.Write(\"Opción: \");\n            string option = Console.ReadLine() ?? \"\";\n            switch (option)\n            {\n                case \"1\":\n                    Console.WriteLine(\"Imprimiendo: \");\n                    Console.WriteLine($\"{printer.Dequeue()}\\n\");\n                    break;\n                case \"2\":\n                    Console.Write(\"Ingresa el nombre del documento: \");\n                    string document = Console.ReadLine() ?? \"unknown\";\n                    printer.Enqueue(document);\n                    Console.WriteLine($\"Documento {document} agregado a la cola\\n\");\n                    break;\n                case \"3\":\n                    return;\n                default:\n                    Console.WriteLine(\"Opción inválida\");\n                    break;\n            }\n        }\n    }\n\n    static void Extra()\n    {\n        // Menu\n        Console.WriteLine(\"1. Navegador web\");\n        Console.WriteLine(\"2. Impresora\");\n        Console.Write(\"Opción: \");\n        string option = Console.ReadLine() ?? \"\";\n        switch (option)\n        {\n            case \"1\":\n                NavegadorWeb();\n                break;\n            case \"2\":\n                Impresora();\n                break;\n            default:\n                Console.WriteLine(\"Opción inválida\");\n                break;\n        }\n    }\n\n    static void Main()\n    {\n        Console.WriteLine(\"========================================\");\n        Console.WriteLine(\"=============== PILAS ==================\");\n        Console.WriteLine(\"========================================\\n\");\n        Stacks();\n        Console.WriteLine(\"========================================\");\n        Console.WriteLine(\"=============== COLAS ==================\");\n        Console.WriteLine(\"========================================\\n\");\n        Queues();\n        Console.WriteLine(\"\\n========================================\\n\");\n        Console.WriteLine(\"============ EJERCICIO EXTRA ===========\");\n        Console.WriteLine(\"========================================\\n\");\n        Extra();\n    }\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/c#/kenysdev.cs",
    "content": "/* ╔══════════════════════════════════════╗\n   ║ Autor:  Kenys Alvarado               ║\n   ║ GitHub: https://github.com/Kenysdev  ║\n   ║ 2024 -  C#                           ║\n   ╚══════════════════════════════════════╝\n   ------------------------------------------\n   # PILAS Y COLAS\n   ------------------------------------------\n// Pilas(stack - LIFO):\n - Sigue el principio LIFO (last in, first out), significa que\n   el último elemento añadido, es el primero en ser retirado. */\n\nvar myStack = new Stack<int>();\nmyStack.Push(1); // Agregar elemento.\nmyStack.Push(2); \nmyStack.Push(3);\n\nConsole.WriteLine(@$\"\n- Eliminar y obtener:   {myStack.Pop()}\n- Obtener sin eliminar: {myStack.Peek()}\n- Total de elementos:   {myStack.Count}\n- Verificar si existe:  {myStack.Contains(5)}\n- Obtener elementos:    {string.Join(\", \", myStack.ToArray())}\");\n\n/* ___________________________________________\n// Colas (Queue - FIFO):\n   - Estructura de datos que sigue el principio FIFO(First In, First Out)\n   - El primer elemento que se inserta es el primero en ser retirado. */\nvar myQueue = new Queue<int>();\nmyQueue.Enqueue(1); // Agregar elemento.\nmyQueue.Enqueue(2);\nmyQueue.Enqueue(3);\n\nConsole.WriteLine(@$\"\n- Eliminar y obtener:   {myQueue.Dequeue()}\n- Obtener sin eliminar: {myQueue.Peek()}\n- Total de elementos:   {myQueue.Count}\n- Verificar si existe:  {myQueue.Contains(5)}\n- Obtener elementos:    {string.Join(\", \", myQueue.ToArray())}\");\n\n/* ____________________________________________\n// Ejercicio usando la implementación de pilas:\nSimula el mecanismo adelante/atrás de un navegador web.\n- Crea un programa en el que puedas navegar a una página o indicarle que te quieres \n  desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n- Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto \n  se interpreta como el nombre de una nueva web. */\n\nstring msgNav = @\"\nHistorial de navegación:\n-------------------------------------------------\nUsar: '<' para página anterior.\n      '>' para página adelante.\n      'h' Ver historial completo.\n      'x' para salir. \nEscribir web para agregar:\n-------------------------------------------------\";\nvoid NavHistory(){\n   var history = new Stack<string>();\n   history.Push(\"Inicio\");\n   var backHistory = new Stack<string>();\n   var forwardHistory = new Stack<string>();\n\n   Console.WriteLine(msgNav);\n   Web(history.Peek());\n   Select();\n\n   void Select(){\n      Console.Write(\"____________\\r\\n Acción: \");\n      string action = Console.ReadLine()!;\n      if (action.Length > 0){\n         switch(action){\n            case \"<\": Back(); break;\n            case \">\": Forward(); break;\n            case \"x\": Home(); break;\n            case \"h\": TheHistory(); break;\n            default:  NewWeb(action); break;\n         }\n      }\n      else {Console.WriteLine(\"Eres muy gracioso xD.\"); Select();}  \n   }\n\n   void Web(string url){\n      Console.WriteLine($\"{backHistory.Count} <-[Actual: {url}]-> {forwardHistory.Count}\");\n   }\n\n   void Back(){\n      if (backHistory.Count > 0){\n         forwardHistory.Push(history.Peek());\n         history.Push(backHistory.Pop());\n         Web(history.Peek());\n      }\n      else {Console.WriteLine(\"No hay página previa.\");}\n      Select();\n   }\n\n   void Forward(){\n      if (forwardHistory.Count > 0){\n         backHistory.Push(history.Peek());\n         history.Push(forwardHistory.Pop());\n         Web(history.Peek());\n      }\n      else {Console.WriteLine(\"No hay página siguiente.\");}\n      Select();\n   }\n\n   void NewWeb(string url){\n      backHistory.Push(history.Peek());\n      forwardHistory.Clear();\n      history.Push(url);\n      Web(url);\n      Select();\n   }\n\n   void TheHistory(){\n      if (forwardHistory.Count > 0){\n         foreach (string item in history){\n            Console.WriteLine(item);\n         }\n      }\n      else {Console.WriteLine(\"Historial vacío.\");}\n      Select();\n   }\n} \n\n/* ____________________________________________\n// Ejercicio usando la implementación de Colas:\nSimula el mecanismo de una impresora compartida.\n- recibe documentos y los imprime cuando así se le indica.\n- La palabra \"imprimir\" imprime un elemento de la cola.\n- El resto de palabras se interpretan como nombres de documentos. */\n\nstring msgPrinter = @\"\n------------------------------------------------\nUsar: 'p' Imprimir.\n      'l' Ver documentos pendientes.\n      'x' para salir.\nEscribir nombre de documento para enviar a cola: \n------------------------------------------------\";\n\nvoid QueuePrinter(){\n   var docQueue = new Queue<string>();\n   Console.WriteLine(msgPrinter);\n   Select();\n\n   void Select(){\n      Console.Write(\"____________\\r\\n Acción: \");\n      string action = Console.ReadLine()!;\n      if (action.Length > 0){\n         switch(action){\n            case \"p\": PrintDoc(); break;\n            case \"l\": QueuePending(); break;\n            case \"x\": Home(); break;\n            default:  SendDoc(action); break;\n         }\n      }\n      else {Console.WriteLine(\"Eres muy gracioso xD.\"); Select();}  \n   }\n\n   void PrintDoc(){\n      if (docQueue.Count > 0){\n         Console.WriteLine(@$\"\n         {docQueue.Dequeue()} -> ha sido impreso.\n         {docQueue.Count} -> archivos faltantes.\");\n      }\n      else{Console.WriteLine(\"No hay archivos.\");}\n      Select();\n   }\n\n   void QueuePending(){\n      if (docQueue.Count > 0){\n         foreach (string doc in docQueue){\n            Console.WriteLine(doc);\n         }\n      }\n      else {Console.WriteLine(\"No hay archivos.\");}\n      Select();\n   }\n\n   void SendDoc(String doc){\n      docQueue.Enqueue(doc);\n      Console.WriteLine(\"Archivo agregado a cola de impresión.\");\n      Select();\n   }\n}\n\n// ____________________________________________\nstring msgHome = @\"\n----------------------------------\nUsar: '1' para simulador_navegador.\n      '2' para simulador_impresora.\n      'Otra tecla' para salir.\n----------------------------------\";\n\nvoid Home(){\n   Console.WriteLine(msgHome);\n   Console.Write(\"____________\\r\\n Acción: \");\n   string action = Console.ReadLine()!;\n   switch(action){\n      case \"1\": NavHistory();; break;\n      case \"2\": QueuePrinter(); break;\n      default:  Console.WriteLine(\"Bye\"); break;\n   }\n}\n\nHome();\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/c#/rxvlc.cs",
    "content": "﻿using System;\nusing System.Collections;\nusing System.Collections.Generic;\n/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n\nnamespace R07___2024\n{\n    class NavegadorWeb\n    {\n        private Stack<string> historial = new Stack<string>();\n        private Stack<string> historialAtras = new Stack<string>();\n\n        public void Navegar(string pagina)\n        {\n            Console.WriteLine($\"Navegando a: {pagina}\");\n            historial.Push(pagina);\n            historialAtras.Clear(); // Limpiar el historial hacia atrás cuando se navega a una nueva página\n        }\n\n        public void Atras()\n        {\n            if (historial.Count > 1)\n            {\n                string paginaActual = historial.Pop();\n                historialAtras.Push(paginaActual);\n\n                string paginaAnterior = historial.Peek();\n                Console.WriteLine($\"Volviendo atrás a: {paginaAnterior}\");\n            }\n            else\n            {\n                Console.WriteLine(\"No hay páginas anteriores para retroceder.\");\n            }\n        }\n\n        public void Adelante()\n        {\n            if (historialAtras.Count > 0)\n            {\n                string paginaSiguiente = historialAtras.Pop();\n                historial.Push(paginaSiguiente);\n\n                Console.WriteLine($\"Avanzando adelante a: {paginaSiguiente}\");\n            }\n            else\n            {\n                Console.WriteLine(\"No hay páginas siguientes para avanzar.\");\n            }\n        }\n    }\n\n    class ImpresoraCompartida\n    {\n        private Queue<string> documentos = new Queue<string>();\n\n        public void AgregarDocumento(string documento)\n        {\n            documentos.Enqueue(documento);\n            Console.WriteLine($\"Documento '{documento}' agregado a la cola de impresión.\");\n        }\n\n        public void Imprimir()\n        {\n            if (documentos.Count > 0)\n            {\n                string documento = documentos.Dequeue();\n                Console.WriteLine($\"Imprimiendo documento: {documento}\");\n            }\n            else\n            {\n                Console.WriteLine(\"No hay documentos en la cola de impresión.\");\n            }\n        }\n    }\n\n    class Program\n    {\n        static void Main(string[] args)\n        {\n            //Pila: \n            //Pila con diferentes objetos:\n            Stack stackList = new Stack();\n            //añado elementos varios:\n            stackList.Push(1);\n            stackList.Push(2);\n            stackList.Push(\"a\");\n            stackList.Push(\"b\");\n\n            //Elimino elementos:\n            //Con pop solo elimino el primer elemento del principio:\n            stackList.Pop();\n            stackList.Pop();\n            //Con clear elimino todos los elementos\n            stackList.Clear();\n\n            //Pila tipo array, sólo con elementos de un mismo tipo\n            Stack<int> stackInt = new Stack<int>();\n            //añado elementos varios:\n            stackInt.Push(1);\n            stackInt.Push(2);\n            stackInt.Push(3);\n            stackInt.Push(4);\n\n            //Elimino elementos:\n            //Con pop solo elimino el primer elemento del principio:\n            stackInt.Pop();\n            stackInt.Pop();\n            //Con clear elimino todos los elementos\n            stackInt.Clear();\n\n            //Colas:\n            //Con diferentes tipos: \n            Queue queueList = new Queue();\n            //Encolo / añado elementos a la lista: \n            queueList.Enqueue(1);\n            queueList.Enqueue(\"Hola\");\n            //Quito el objeto al principio de la cola:\n            queueList.Dequeue();\n            //Elimino todos los elementos de la cola:\n            queueList.Clear();\n\n            //Colas:\n            //Con un mismo tipo: \n            Queue<int> queueInt = new Queue<int>();\n            //Encolo / añado elementos a la lista: \n            queueInt.Enqueue(1);\n            queueInt.Enqueue(2);\n            //Quito el objeto al principio de la cola:\n            queueInt.Dequeue();\n            //Elimino todos los elementos de la cola:\n            queueInt.Clear();\n\n            //Dificultad adicional adaptado a consola:\n            NavegadorWeb navegador = new NavegadorWeb();\n\n            while (true)\n            {\n                Console.WriteLine(\"Ingrese una URL para navegar, 'adelante' para avanzar, 'atrás' para retroceder, o 'salir' para terminar:\");\n                string input = Console.ReadLine();\n\n                if (input.ToLower() == \"salir\")\n                {\n                    break;\n                }\n                else if (input.ToLower() == \"adelante\")\n                {\n                    navegador.Adelante();\n                }\n                else if (input.ToLower() == \"atrás\")\n                {\n                    navegador.Atras();\n                }\n                else\n                {\n                    navegador.Navegar(input);\n                }\n            }\n\n            //Dificultad adicional impresora:\n            ImpresoraCompartida impresora = new ImpresoraCompartida();\n\n            while (true)\n            {\n                Console.WriteLine(\"Ingrese 'imprimir' para imprimir un documento o el nombre de un documento para agregarlo a la cola:\");\n                string input = Console.ReadLine();\n\n                if (input.ToLower() == \"imprimir\")\n                {\n                    impresora.Imprimir();\n                }\n                else\n                {\n                    impresora.AgregarDocumento(input);\n                }\n            }\n\n\n\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/c#/vixxtory.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.ComponentModel.Design;\nusing System.Net.NetworkInformation;\nusing System.Runtime.Intrinsics.X86;\nusing System.Security.Cryptography.X509Certificates;\nusing static System.Runtime.InteropServices.JavaScript.JSType;\n\nnamespace RetosProgramacion\n{\n    class Program\n    {\n        static void Main(string[] args)\n        {\n            /*Las colecciones en C Sharp son grupos de objetos relacionados.\n              Se diferencian de las matrices en que permiten aumentar o disminuir su capacidad de manera dinámica.       \n              Las colecciones genéricas que se encuentran en el espacio de nombres System.Collections.Generic son:\n              List<T>, Queue<T>, Stack<T> y Dictionary<TKey, TValue>.*/\n\n            //La clase Queue<T> (cola) es una colección de elementos organizados “FIFO”; los primeros elementos en entrar son los primeros en salir.\n            Queue<string> kings = new Queue<string>();\n            kings.Enqueue(\"Arturo\");\n            kings.Enqueue(\"Alejandro\");\n            kings.Enqueue(\"Melchor\");\n            kings.Enqueue(\"Gaspar\");\n            kings.Enqueue(\"Baltasar\");\n            foreach(var king in kings)\n            {\n                Console.WriteLine($\"{king}\");\n            }\n            Console.WriteLine(\"\\n\");\n            Console.WriteLine(kings.Dequeue()); //Elimina y devuelve el elemento en el principio de la cola.\n            Console.WriteLine(kings.Peek()); //Devuelve el elemento en el principio de la cola sin eliminarlo.\n            Console.WriteLine(\"\\n\");\n            foreach (var king in kings)\n            {\n                Console.WriteLine($\"{king}\");\n            }\n\n            //La clase Stack<T> (pila) es una colección de objetos organizados “LIFO”; los últimos en entrar son los primeros en salir.\n            Stack<string> pizzas= new Stack<string>();\n            pizzas.Push(\"Cuatro estaciones\"); //Añade elementos al principio de la pila\n            pizzas.Push(\"Romana\");\n            pizzas.Push(\"Barbacoa\");\n            foreach (var pizza in pizzas)\n            {\n                Console.WriteLine(pizza);\n            }\n            Console.WriteLine(\"\\n\");\n            Console.WriteLine(pizzas.Pop()); //Elimina y devuelve el elemento en el principio de la pila.\n            Console.WriteLine(pizzas.Peek()); //Devuelve el elemento al principio de la pila sin eliminarlo\n            Console.WriteLine(\"\\n\");\n            foreach (var pizza in pizzas)\n            {\n                Console.WriteLine(pizza);\n            }\n\n            //Introduccion y recuperacion de elementos con List\n            List<int> list = new List<int>();\n            list.Add(1); // Añade elementos al final de la lista como en el caso de las colas (Queue)\n            list.Add(2);\n            list.Add(3);\n            list.Add(4);\n            list.Add(5);\n            foreach (int item in list)\n            {\n                Console.WriteLine(item);\n            }\n            Console.WriteLine(\"\\n\");\n            list.Insert(0, 0); //Añade el elemento al comienzo de la lista como en el caso de las pilas (Stack)\n            list.Insert(0, -1);\n            foreach (int item in list)\n            {\n                Console.WriteLine(item);\n            }\n            Console.WriteLine(\"\\n\");\n            Console.WriteLine(list[0]); //Devuelve el primer elemento de la lista como Peek() en las colas\n            Console.WriteLine(list[list.Count - 1]); //Devuelve el ultimo elemento de la lista como Peek() en las pilas\n            \n            //DIFICULTAD EXTRA\n            \n            //NAVEGACION WEB\n            //Agrego dos pilas, una para las paginas de la izquierda y otras para las de la derecha\n            Stack<string> websIzq = new Stack<string>();\n            //A la pila de la izquierda le agrego todos los valores iniciales\n            Stack<string> websDer = new Stack<string>();\n            websIzq.Push(\"web A\");\n            websIzq.Push(\"web B\");\n            websIzq.Push(\"web C\");\n            websIzq.Push(\"web D\");\n            //Pagino hacia atras\n            navegarAtras(websIzq, websDer);\n            navegarAtras(websIzq, websDer);\n            navegarAtras(websIzq, websDer);\n            //Pagino hacia adelante\n            navegarAdelante(websIzq, websDer);\n            navegarAdelante(websIzq, websDer);\n\n            //IMPRESORA\n            Queue<string> impresora = new Queue<string>();\n            //Se agregan documentos a la cola\n            impresora.Enqueue(\"DOC 1\");\n            impresora.Enqueue(\"DOC 2\");\n            impresora.Enqueue(\"DOC 3\");\n            impresora.Enqueue(\"DOC 4\");\n            impresora.Enqueue(\"DOC 5\");\n            //Se imprimen los documentos por orden de llegada\n            imprimir(impresora);\n            imprimir(impresora);\n            imprimir(impresora);\n            imprimir(impresora);\n            imprimir(impresora);\n            imprimir(impresora);\n        }\n\n        static void navegarAtras(Stack<string> pilaIzquierda, Stack<string> pilaDerecha)\n        {\n            if (pilaIzquierda.Count() != 0)\n            {\n                pilaDerecha.Push(pilaIzquierda.Pop());\n                Console.WriteLine(pilaIzquierda.Peek());\n                Console.WriteLine(\"\\n\");\n            }\n            else\n                Console.WriteLine(\"No es posible realizar la accción\");\n        }\n        static void navegarAdelante(Stack<string> pilaIzquierda, Stack<string> pilaDerecha)\n        {\n            if (pilaDerecha.Count() != 0)\n            {\n                pilaIzquierda.Push(pilaDerecha.Pop());\n                Console.WriteLine(pilaIzquierda.Peek());\n                Console.WriteLine(\"\\n\");\n            }\n            else\n                Console.WriteLine(\"No es posible realizar la acción\");\n        }\n        static void imprimir(Queue<string> impresora)\n        {\n            if (impresora.Count() > 0)\n                Console.WriteLine(impresora.Dequeue());\n            else\n                Console.WriteLine(\"No se encuentran documentos disponibles para imprimir\");\n        }\n    }\n}\n\n\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/c++/Fravelz.cpp",
    "content": "#include <iostream>\n#include <string>\n#include <vector>\n\nusing namespace std;\n\n// * Mostrar elementos de la Pila y Cola\nvoid mostrarElements(vector<int> v1) {\n    for (int element : v1) cout << element << ' ';\n}\n\n// * Eleminar elementos en Cola\nvoid firstDelete(vector<int> &v1) {\n    int size = v1.size(), i = 0;\n    vector<int> v2;\n\n    while (--size) {\n        if (size != v1.size()) {\n            v2.push_back(v1[++i]);\n        }\n    }\n\n    v1.clear();\n    v1 = v2;\n}\n\n// ********** DIFICULTAD EXTRA CLASE ********** //\n\nclass Historial_Navegacion_Web_Pagina {\n    private:\n        int base = 0;\n        vector<string> stack;\n    \n    public:\n        Historial_Navegacion_Web_Pagina() {};\n\n        void add_pagina(string element) {\n            stack.push_back(element);\n            base = stack.size() - 1;\n        };\n\n        string web() {\n            string texto; int iterador = 0;\n\n            for (string element : stack) {\n                if (iterador <= base) {\n                    texto += '/' + element;\n                    ++iterador; \n                }\n            }\n\n            return texto;\n        }\n\n        void regresar_pagina() { base--; };\n\n        void adelantar_pagina() {\n\n            if (base < stack.size() - 1) { ++base; }\n         };\n};\n\nint main() {\n    //* Pila / Stack (LIFO)\n    vector<int> vector1;\n\n    // Push\n    vector1.push_back(10); // 10\n    vector1.push_back(20); // 10, 20\n    vector1.push_back(30); // 10, 20, 30\n\n    \n    // Mostrar elementos\n    cout << '\\n'; mostrarElements(vector1); // 10, 20, 30\n\n    // Pop\n    vector1.pop_back(); // 10, 20\n    \n    // Mostrar elementos\n    cout << '\\n'; mostrarElements(vector1); // 10, 20\n    cout << '\\n';\n\n    //* Cola (queue - FIFO)\n\n    vector<int> vector2;\n\n    \n    // Enqueue\n    vector2.push_back(1); // 1\n    vector2.push_back(2); // 1, 2\n    vector2.push_back(3); // 1, 2, 3\n\n    \n    // Mostrar elementos\n    cout << '\\n'; mostrarElements(vector2); // 1, 2, 3\n    \n    // Dequeue\n    firstDelete(vector2); // 2, 3\n\n    // Mostrar elementos\n    cout << '\\n'; mostrarElements(vector2); // 2, 3\n    cout << '\\n';\n\n    // ********** DIFICULTAD EXTRA ********** //\n    bool salir = false; string info;\n    \n    Historial_Navegacion_Web_Pagina Web_404;\n\n    while (!salir) {\n        cout << '\\n';\n        cout << \"Digite (una URL / adelante / atras / salir): \";\n        cout << \"\\n > \";\n\n        getline(cin, info);\n        // cin >> info;\n        \n        if (info == \"salir\") { salir = true; }\n \n        else if (info == \"adelante\") { Web_404.adelantar_pagina(); }\n        \n        else if (info == \"atras\") { Web_404.regresar_pagina(); }\n\n        else { Web_404.add_pagina(info); }\n\n        cout << \"\\n [+] Estas en la web: \" << Web_404.web();\n        cout << '\\n'; \n    }\n    \n    cout << '\\n'; \n    return 0;\n}"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/c++/RgeditV1.cpp",
    "content": "#include <iostream>\n#include <cstdlib>\nusing std::cout;\nusing std::endl;\nusing std::cin;\n\nint *ptr=nullptr;\nint size; // Tamaño de la pila o cola\nint array[1]; \nvoid  insertar(int &size);\nvoid mostrarpila();\nvoid mostrarcola();\nvoid pila();\nvoid cola();\n\nint main(){\n\n    cout<< \"Bienvenido al programa de Pilas y Colas\" << endl;\n    cout<< \"Seleccione una opcion:\" << endl;\n    cout<< \"1. Pila\" << endl;\n    cout<< \"2. Cola\" << endl;\n\n    static int opcion;\n    cin >> opcion;\n\n    switch(opcion) {\n        case 1:\n            pila();\n            system(\"cls\"); // para que limpie la pantalla\n            break;\n        case 2:\n            cola();\n            system(\"cls\");\n            break;\n        default:\n            cout << \"Opcion no valida.\" << endl;\n            break;\n    }\n\n    return 0;\n}\n//int &size es una referencia a la variable size, que se usa para pasar el tamaño de la pila o cola a la función insertar.\n//solo lo puse para no crear una copia de la variable size, se que no es necesario ya que esto es un programa muy pequeño, pero es una buena práctica para programas más grandes.\nvoid insertar(int &size) {\n     \n     cout << \"Ingrese los elementos de la pila o cola:\" << endl;\n\n        for (int i = 0; i < size; i++) {\n            cout << \"Elemento \" << (i + 1) << \": \";\n            cin >> array[i];\n        }\n}\n\nvoid mostrarpila() {\n    for (int i = *ptr - 1; i >= 0; i--) {\n        cout << array[i] << endl;\n    }\n}\nvoid pila() {\n    delete ptr; // Liberar memoria si ya se había asignado\n    ptr = &size; // Asignar ptr a la dirección de size\n    cout << \"Has seleccionado Pila.\" << endl;\n    cout << \"Eilje el tamaño de la Pila\" << endl;\n    cin >> *ptr;\n\n    insertar(*ptr);\n    system(\"cls\");\n    cout << \"Elementos de la Pila:\" << endl;\n    mostrarpila();\n}\n\nvoid mostrarcola() {\n    for (int i = 0; i < *ptr; i++) {\n        cout << array[i] << endl;\n    }\n}\n\nvoid cola() {\n    delete ptr; // Liberar memoria si ya se había asignado\n    ptr = &size;\n    cout << \"Has seleccionado Cola.\" << endl;\n    cout << \"Elije el tamaño de la Cola\" << endl;\n    cin >> *ptr;\n\n    insertar(*ptr);\n    system(\"cls\");\n    cout << \"Elementos de la Cola:\" << endl;\n    mostrarcola();\n}"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/c++/RoniPG.Cpp",
    "content": "//@ Roni\n#include <iostream>\n#include <string>\n#include <stack>\n#include <queue>\n#include <algorithm>\n\nvoid Programa1();\nvoid Programa2();\nbool Contains(std::stack<std::string> pila, std::string texto);\nint IndexOf(std::stack<std::string> pila, std::string texto);\nstd::string GetPos(std::stack<std::string> pila, int pos);\nstd::string ToLower(std::string texto);\n\nint main() {\n\t/*\n\t * EJERCICIO: Implementa los mecanismos de introducción y recuperación de\n\t * elementos propios de las pilas (stacks - LIFO) y las colas (queue - FIFO)\n\t * utilizando una estructura de array o lista (dependiendo de las posibilidades\n\t * de tu lenguaje).\n\t */\n\n\t//PILA (STACK)\n\t// Declarar un Stack de strings\n\tstd::stack<std::string> pila;\n\n\t// Insertar elementos en el Stack\n\tpila.push(\"Hola\");\n\tpila.push(\"Mundo\");\n\tpila.push(\"!\");\n\n\t// Mostrar el tamaño del Stack\n\tstd::cout << \"Tamaño del Stack: \" << pila.size() << std::endl;\n\n\t// Acceder al elemento en la cima del Stack\n\tstd::cout << \"Elemento en la cima del Stack: \" << pila.top() << std::endl;\n\n\t// Eliminar elementos del Stack\n\tpila.pop();\n\tstd::cout << \"Tamaño del Stack después de eliminar un elemento: \"\n\t\t\t<< pila.size() << std::endl;\n\n\t// COLA(QUEUE)\n\t// Crear una cola de strings\n\tstd::queue<std::string> cola;\n\n\t// Agregar elementos a la cola\n\tcola.push(\"Hola\");\n\tcola.push(\"Mundo\");\n\tcola.push(\"!\");\n\n\t// Mostrar el primer elemento de la cola\n\tstd::cout << \"Primer elemento de la cola: \" << cola.front() << std::endl;\n\n\t// Eliminar el primer elemento de la cola\n\tcola.pop();\n\n\t// Mostrar el nuevo primer elemento de la cola\n\tstd::cout << \"Nuevo primer elemento de la cola: \" << cola.front()\n\t\t\t<< std::endl;\n\n\t// Mostrar el tamaño de la cola\n\tstd::cout << \"Tamaño de la cola: \" << cola.size() << std::endl;\n\t/*\n\t * DIFICULTAD EXTRA (opcional): - Utilizando la implementación de pila y cadenas\n\t * de texto, simula el mecanismo adelante/atrás de un navegador web. Crea un\n\t * programa en el que puedas navegar a una página o indicarle que te quieres\n\t * desplazar adelante o atrás, mostrando en cada caso el nombre de la web. Las\n\t * palabras \"adelante\", \"atras\" desencadenan esta acción, el resto se interpreta\n\t * como el nombre de una nueva web.\n\t */\n\tPrograma1();\n\t/*\n\t * - Utilizando la implementación de cola y cadenas de texto, simula el\n\t * mecanismo de una impresora compartida que recibe documentos y los imprime\n\t * cuando así se le indica. La palabra \"imprimir\" imprime un elemento de la\n\t * cola, el resto de palabras se interpretan como nombres de documentos.\n\t */\n\tPrograma2();\n\n\treturn 0;\n}\nvoid Programa1() {\n\tstd::stack<std::string> url;\n\turl.push(\"www.google.com\");\n\turl.push(\"www.twitter.com\");\n\turl.push(\"www.gmail.com\");\n\tstd::string texto = \"\";\n\tint pos = 0;\n\tdo {\n\t\tstd::cout << \"\\n*******Navegación web*******\\n\" << std::endl;\n\t\tstd::cout << \"Escribe la url de la página web para dirigirte a ella.\"\n\t\t\t\t<< std::endl;\n\t\tstd::cout << \"Si la url no existe se creara una nueva web\" << std::endl;\n\t\tstd::cout << \"Escribe 'adelante' para ir a la siguiente web.\"\n\t\t\t\t<< std::endl;\n\t\tstd::cout << \"Escribe 'atras' para ir a la web anterior.\" << std::endl;\n\t\tstd::cout << \"Escribe 'salir' para cerrar el programa.\" << std::endl;\n\t\tstd::cout << \"Escribe aquí: \" << std::endl;\n\t\tgetline(std::cin, texto);\n\t\tif (ToLower(texto) == \"adelante\") {\t// -->Implementamos un metodo que convierte el texto a minusculas sin modificar su contenido original\n\t\t\tif (pos + 1 >= url.size()) {\n\t\t\t\tstd::cout << \"Ya te encuentras en la url del final\"\n\t\t\t\t\t\t<< std::endl;\n\t\t\t\tstd::cout << url.top() << std::endl;\n\t\t\t\tpos = url.size() - 1;\n\t\t\t} else {\n\t\t\t\tstd::cout << \"Avanzamos\" << std::endl;\n\t\t\t\tstd::cout << GetPos(url, pos + 1) << std::endl;\n\t\t\t\tpos += 1;\n\t\t\t}\n\t\t} else if (ToLower(texto) == \"atras\") {\n\t\t\tif (pos <= 0) {\n\t\t\t\tstd::cout << \"Ya te encuentras en la url del principio\"\n\t\t\t\t\t\t<< std::endl;\n\t\t\t\tstd::cout << GetPos(url, pos) << std::endl;\n\t\t\t\tpos = 0;\n\t\t\t} else {\n\t\t\t\tstd::cout << \"Retrocedemos\" << std::endl;\n\t\t\t\tstd::cout << GetPos(url, pos - 1) << std::endl;\n\t\t\t\tpos -= 1;\n\t\t\t}\n\t\t} else if (ToLower(texto) == \"salir\") {\n\t\t\tstd::cout << \"Vuelva pronto\" << std::endl;\n\t\t} else if (Contains(url, texto)) { //--> Implementamos un metodo que compruebe la pila\n\t\t\tstd::cout << \"Encotramos la url en la posición: \";\n\t\t\tpos = IndexOf(url, texto); //--> Implementamos un metodo que devuelve la posicion en donde se ha encontrado la coincidencia\n\t\t\tstd::cout << pos << std::endl;\n\t\t\tpos -= 1;\n\t\t} else {\n\t\t\tstd::cout << \"Añadimos nueva url\" << std::endl;\n\t\t\turl.push(texto);\n\t\t}\n\n\t} while (texto != \"salir\");\n\n}\nbool Contains(std::stack<std::string> pila, std::string texto) {\n\twhile (!pila.empty()) {\n\t\tif (pila.top() == texto) {\n\t\t\treturn true;\n\t\t}\n\t\tpila.pop();\n\t}\n\treturn false;\n}\nstd::string ToLower(std::string texto) {\n\tstd::transform(texto.begin(), texto.end(), texto.begin(), ::tolower);\n\treturn texto;\n}\nint IndexOf(std::stack<std::string> pila, std::string texto) {\n\tint count = pila.size();\n\twhile (!pila.empty()) {\n\t\tif (pila.top() == texto) {\n\t\t\treturn count;\n\t\t}\n\t\tpila.pop();\n\t\tcount--;\n\t}\n\treturn count;\n}\nstd::string GetPos(std::stack<std::string> pila, int pos) {\n\tint count = pila.size() - pos;\n\tstd::string aux = \"\";\n\tfor (int i = 0; i < count; ++i) {\n\t\taux = pila.top();\n\t\tpila.pop();\n\t}\n\treturn aux;\n}\nvoid Programa2() {\n\tstd::queue<std::string> doc;\n\tdoc.push(\"Documento 1\");\n\tdoc.push(\"Documento 2\");\n\tdoc.push(\"Documento 2\");\n\tstd::string texto = \"\";\n\n\tdo {\n\t\tstd::cout << \"\\n*******Mecanismo de una impresora*******\\n\"\n\t\t\t\t<< std::endl;\n\t\tstd::cout\n\t\t\t\t<< \"Escribe 'imprimir' para ir a la imprimir el primer documento de la cola.\"\n\t\t\t\t<< std::endl;\n\t\tstd::cout\n\t\t\t\t<< \"Si no, introduce el nombre del nuevo documento a imprimir y se añaadira a la cola\"\n\t\t\t\t<< std::endl;\n\t\tstd::cout << \"Escribe 'salir' para cerrar el programa.\" << std::endl;\n\t\tstd::cout << \"Escribe aquí: \" << std::endl;\n\t\tstd::getline(std::cin, texto);\n\t\tif (ToLower(texto) == \"imprimir\") {\n\t\t\tstd::cout << \"Procedemos a imprimir el documento: \" << doc.front()\n\t\t\t\t\t<< std::endl;\n\t\t\tdoc.pop();\n\t\t} else if (ToLower(texto) == \"salir\") {\n\t\t\tstd::cout << \"Vuelva pronto\" << std::endl;\n\t\t} else {\n\t\t\tstd::cout << \"Introducimos el nuevo documento\" << std::endl;\n\t\t\tdoc.push(texto);\n\t\t}\n\t} while (ToLower(texto) != \"salir\");\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/c++/Vid92.cpp",
    "content": "#include <iostream>\n#include <queue>\n#include <stack>\n#include <ctype.h>\n\nusing namespace std;\n\nvoid pageWeb(){\n    cout<<endl<<\"----------- Ejercicio 1 : pagina web --------------\"<<endl;\n    stack<string> pweb;\n    \n    pweb.push(\"www.github.com\");    //posicion 1\n    pweb.push(\"www.google.com\");    //posicion 2\n    pweb.push(\"www.youtube.com\");   //posicion 3\n    \n    cout<<\"Tamaño de pweb: \"<<pweb.size()<<endl;\n    \n    string opcion;\n    int pos = 1;\n    \n    while(1){\n        cout<<\"Ingrese opcion:  [>>atras<<] [>>adelante<<] [>>salir<<] \"<<endl;\n        cin>>opcion;\n        \n        string cadena;\n        cadena = opcion;\n        \n        for (int indice = 0; cadena[indice] != '\\0'; ++indice){\n\t\t    cadena[indice] = tolower(cadena[indice]);\n\t    }\n        \n        opcion = cadena;\n        \n        if(opcion==\"atras\"){\n            pos-=1;\n            if(pos<=0)\n                pos = 3;\n        }\n        \n        else if(opcion==\"adelante\"){\n            pos+=1;\n            if(pos>=4)\n                pos = 1;\n        }\n        \n        else if(opcion==\"salir\"){\n            break;\n        }\n        \n        if(pos==1)\n            cout<<\"www.github.com\"<<endl;\n        else if(pos==2)\n            cout<<\"www.google.com\"<<endl;\n        else if(pos==3)\n            cout<<\"www.youtube.com\"<<endl;\n    }\n}\n\nvoid doc_printer(){\n    cout<<\"-------------------- Ejercicio 2: Impresora ------------------\"<<endl;\n    queue<string>impresora;\n    \n    string op;\n\n    while(1){\n        cout<<endl<<\"Ingrese opcion [>>Imprimir/Ingrese nombre del documento<<] [>>salir<<]\"<<endl;\n        cin>>op;\n        \n        string cadena;\n        cadena = op;\n        \n        for (int indice = 0; cadena[indice] != '\\0'; ++indice){\n    \t    cadena[indice] = tolower(cadena[indice]);\n        }\n            \n        op = cadena;\n        \n        if(op==\"salir\"){\n            break;\n        }\n        else if(op==\"imprimir\"){\n            if(impresora.size() == 0){\n                cout<<\"No hay archivo que imprimir ...\"<<endl;\n            }else{\n                cout<<\"Imprime: \"<<impresora.front()<<endl;\n                impresora.pop();\n            }\n        }\n        else{\n            cout<<\"se agrega ...\"<<op<<endl;\n            impresora.push(op);\n        }\n    }\n}\n\nint main()\n{\n    queue<int> cola;\n    stack<int> pila;\n    \n    //Cola (Queue)\n    cout<<\"-----------Cola (Queue) -----------\"<<endl;\n    cola.push(10);          //Agrega elementos \n    cola.push(4);\n    cola.push(1);\n    cout<<\"Indica el primer elemento del queue: \"<<cola.front()<<endl;\n    cout<<\"Tamaño del queue: \"<<cola.size()<<endl;\n    cout<<\"Indica el ultimo elemento del queue: \"<<cola.back()<<endl;\n    cola.pop();            //Elimina elementos - el primero del queue\n    cout<<\"Tamaño del queue despues de eliminar un elemento: \"<<cola.size()<<endl;\n    cout<<\"Indica si esta vacia el queue (0-false,1-true): \"<<cola.empty()<<endl;\n    \n    //Pila (Stack)\n    cout<<endl<<\"-----------Pila (Stack) -----------\"<<endl;\n    pila.push(7);           //Agrega elementos\n    pila.push(13);\n    pila.push(9);\n    cout<<\"Tamaño de stack: \"<<pila.size()<<endl;\n    pila.pop();             //Eliminar elementos - primer elemento \n    cout<<\"Indica el primer elemento del stack: \"<<pila.top()<<endl;\n    cout<<\"Tamaño de stack despues de eliminar un elemento: \"<<pila.size()<<endl;\n    cout<<\"Indica si esta vacia el stack (0-false,1-true): \"<<pila.empty()<<endl;\n    \n    //Dificuldad extra\n    pageWeb();\n    doc_printer();\n    \n    return 0;\n}\n\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/c++/hectorio23.cpp",
    "content": "// Author: hectorio23\n#include <iostream>\n#include <memory>\n#include <ostream>\n// #include <cstdlib>\n\n/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atras\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n\n/************************************************************************************************************\n*******************************CLASE PARA LA CREACION DEL OBJETO PAGINA WEB**********************************\n*************************************************************************************************************/\n// The following class structured the data:\n// Objecto{\n//     Atributes\n//     Title:  yourWebPageTitle\n//     length: webPageLength\n//\n//     Methods\n//     getInfo -> imprime en el terminal la informacion relevante del objeto\n//     getTitle -> retorna el titulo del documento\n// }\nclass WebPage {\n    public:\n    int index = 0;\n    WebPage() {}\n    std::string Title;\n    WebPage(std::string title, int index): Title(title), index(index) {}\n    WebPage(const WebPage& other) : Title(other.Title) {}\n\n    void getInfo() {\n        // <Object WebPage at 0x7f61993bf420>\n        std::cout << \"<Object WebPage - \" << Title << \" at \" << (this) << \">\\n\";\n    }\n\n    std::string getTitle() { return this->Title; }\n};\n\n/// OPERATOR OVERLOADED FOR PRINT THE WebPage Memory\nstd::ostream& operator<<(std::ostream& output, WebPage& item) {\n    item.getInfo();\n    return output;\n };\n\n\n/***************************************************\n*******************STACK DINAMICO*******************\n****************************************************/\n\n/// STACK STRUCTURE\n// Objecto{\n//     Atributes\n//     page objecto:  guarda un objeto de tipo WebPage\n//     next: Guarda un puntero de tipo Stack\n//     garbage: Por el momento es experimental\n//\n//     Methods\n//     push -> agrega un objeto WebPage a la Pila\n//     pop -> elimina el ultimo elemento de la Pila\n// }\nstruct Stack {\n    private:\n    std::shared_ptr<Stack> next = nullptr;\n    std::shared_ptr<Stack> garbage = nullptr; // experimental\n\n    public:\n    int size = 0;\n    WebPage page;\n\n    Stack() {}\n    Stack(WebPage& item, std::shared_ptr<Stack> pointer) : page(item), next(pointer) {}\n\n    void push(WebPage& WebPageObject) {\n        std::shared_ptr<Stack> tmp = std::make_unique<Stack>(WebPageObject, next);\n        next = tmp;\n        size++;\n    }\n\n    // Modificación de la función pop para que devuelva el elemento eliminado si existe o nullptr si la pila está vacía\n    WebPage* pop() {\n        if (size == 0) return nullptr;\n\n        std::shared_ptr<Stack> aux = next;\n        next = aux->next;\n\n        size--;\n        return &(aux->page);\n    }\n};\n\n/***************************************************\n*******************QUEUE DINAMICO*******************\n****************************************************/\n\n/// QUEUE STRUCTURE\n// Objecto{\n//     Atributes\n//     page objecto:  guarda un objeto de tipo WebPage\n//     next: Guarda un puntero de tipo Stack\n//     garbage: Por el momento es experimental\n//\n//     Methods\n//     push -> agrega un objeto WebPage a la Pila\n//     pop -> elimina el ultimo elemento de la Pila\n// }\nstruct Queue {\n    private:\n    std::shared_ptr<Queue> next = nullptr;\n    std::shared_ptr<Queue> last = nullptr; // Puntero al último elemento de la cola\n\n    public:\n    int size = 0;\n    WebPage page;\n    \n    Queue() {}\n    Queue(WebPage& item, std::shared_ptr<Queue> pointer) : page(item), next(pointer) {}\n\n    // Agrega un elemento al final de la cola\n    void push(WebPage& WebPageObject) {\n        std::shared_ptr<Queue> tmp = std::make_shared<Queue>(WebPageObject, nullptr);\n        if (size == 0) {\n            next = tmp;\n            last = tmp;\n        } else {\n            last->next = tmp;\n            last = tmp;\n        }\n        size++;\n    }\n\n    // Elimina y retorna el primer elemento de la cola\n    // Si la cola está vacía, devuelve nullptr\n    WebPage* pop() {\n        if (size == 0) return nullptr;\n\n\n        std::shared_ptr<Queue> aux = next;\n        next = aux->next;\n\n        size--;\n\n        // Si después de eliminar el elemento la cola queda vacía,\n        // también actualizamos el puntero al último elemento\n        if (size == 0) {\n            last = nullptr;\n        }\n\n        return &(aux->page);\n    }\n};\n\n// Prototipo de funciones\nvoid imprimirMenu(int&);\n\nint main() {\n    Queue q1;\n    Stack s1;\n    int counter = 1; \n\n\n    /***************************************************\n    ************USO DE UN STACK DINAMICO****************\n    ****************************************************/\n\n    WebPage w1{ \"Index\", 2 };\n    w1.getInfo();\n    WebPage w2{ \"Account\", 5 };\n    w2.getInfo();\n    WebPage w3{ \"Login\", 6 };\n    w3.getInfo();\n\n    std::cout << \"Cantidad de elemtos de Stack antes de agregarlos:  \" << s1.size << \" elementos\\n\";\n    // Agregando elementos al Stack\n    s1.push(w1);\n    s1.push(w2);\n    s1.push(w3);\n\n    std::cout << \"Cantidad de elemtos de Stack despues de agregarlos:  \" << s1.size << \" elementos\\n\";\n    // Eliminando elementos del stack\n    s1.pop();\n    s1.pop();\n    s1.pop();\n    std::cout << \"Cantidad de elemtos de Stack despues de eliminarlos:  \" << s1.size << \" elementos\\n\";\n\n\n    /***************************************************\n    ************USO DE UN QUEUE DINAMICO****************\n    ****************************************************/\n\n    // Agregando elementos al Queue\n    std::cout << \"Cantidad de elemtos de Queue antes de agregarlos:  \" << q1.size << \" elementos\\n\";\n    q1.push(w1);\n    q1.push(w2);\n    q1.push(w3);\n    std::cout << \"Cantidad de elemtos de Queue despues de agregarlos:  \" << q1.size << \" elementos\\n\";\n\n    // Eliminando elementos del Queue\n    std::cout << \"Imprimiendo el documento:  \" << q1.size - 2<< \"\\n\";\n    q1.pop();\n    std::cout << \"Imprimiendo el documento:  \" << q1.size  << \"\\n\";\n    q1.pop();\n    q1.pop();\n    std::cout << \"imprimiendo el documento:  \" << q1.size + 3 << \"\\n\";\n    \n    imprimirMenu(counter);\n\n    return 0;\n}\n\nvoid imprimirMenu(int& counter) {\n    WebPage index { \"index\", counter };\n    WebPage test  = index;\n    Stack stack;\n    Stack back;\n    std::string choose;\n\n    stack.push(index);\n\n    while (true) {\n\n        std::cout << \"\\n=======================================================\\n\";\n        std::cout << \"          Bienvenido a la pagina No.\" << stack.size << \"\\n\";\n        std::cout << \"=======================================================\\n\";\n        std::cout << \"Atras(press a|A)             Siguiente(press s|S)\\n\";\n        std::cout << \"opcion_usuario> \";\n        std::getline(std::cin, choose);\n        \n        if (choose.size() > 1) {\n            WebPage temporal { choose, counter };\n            test = temporal;\n            stack.push(temporal);\n        }\n\n        else if ((choose == \"a\" || choose == \"A\") && stack.size > 1) {\n            WebPage otro_temporal = *stack.pop();\n            test = stack.page;\n            otro_temporal.getInfo();\n            stack.page.getInfo();\n            back.push(otro_temporal);\n            std::cout << \"Mostrando página anterior...\\n\";\n        }\n\n        else if ((choose == \"s\" || choose == \"S\") && back.size > 0) {\n            WebPage atras_temporal = *back.pop();\n            test = atras_temporal;\n            atras_temporal.getInfo();\n            stack.page.getInfo();\n            stack.push(atras_temporal);\n            std::cout << \"Mostrando siguiente página...\\n\";\n        }\n\n        else {\n            std::cout << \"Opcion no disponible, Por favor, crear una Pagina WEB!\\n\";\n        }\n\n        // std::system(\"clear\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/c++/jhoshmc.cpp",
    "content": "/*\n ! EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n*/\n#include<iostream>\n#include<stack>\n#include<queue>\n#include<stdlib.h>// para el new\n#include<algorithm>\n#include<string>\nusing namespace std;\n//! pila con estructua\n// este es un nodo, puede tener cuantos datos quieras\nstruct PilaNodo\n{\n  int dato;\n  PilaNodo *siguiente; // un nodo siempre apunta(* puntero a siguiente) a uno siguiente, por eso delmismo nodo\n  //(PilaNodo) esta apuntando a siguiente\n};\nstruct ColaNodo\n{\n  int dato;\n  ColaNodo *siguiente;\n};\n\n// todo pila\nvoid using_stack();\nvoid pila();//!pila con estructura\nvoid apilar(PilaNodo*&,int);// insertar elemento a la pila, (\"*\"puntero \"&\" referencia)\nvoid desapilar(PilaNodo *&);\nvoid verElementosPila(PilaNodo *&);\n//todo cola\nvoid using_queque();\nvoid cola(); //! cola con structura\nvoid insertarCola(ColaNodo*&,ColaNodo*&,int);\nbool cola_vacia(ColaNodo *);\nvoid eliminar_cola(ColaNodo *&, ColaNodo *&);\nvoid mostrar_cola(ColaNodo *&, ColaNodo *&);\n// todo extra\nvoid historial_web();\nstring tolower_p(string);\nvoid impresora();\nint main(){\n\n  using_stack();\n  pila();\n  using_queque();\n  cola();\n  historial_web();\n  impresora();\n  return 0;\n}\n// todo pila\nvoid using_stack(){\n  //! pila , lifo (last in first out), (ultimo en entrar, primero en salir)\n  /*\n  ?La clase stack tiene varios métodos que puedes utilizar:\n\n  * push: Agrega un elemento al tope de la pila.\n  * pop: Elimina el elemento en el tope de la pila.\n  * top: Devuelve una referencia al elemento en el tope de la pila.\n  * empty: Devuelve true si la pila está vacía, false en caso contrario.\n  * size: Devuelve el número de elementos en la pila.\n  */\n\n  stack<int> pila;\n  // ver si la pila está vacia o no\n  if(pila.empty()){\n    cout << \"la pila esta vacia\" << endl;\n  }else{\n    cout << \"la pila tiene pila\" << endl;\n  }\n\n  pila.push(1); //agregando elemento al tope de la pila\n  pila.push(2); //agregando elemento al tope de la pila\n  pila.push(3); //agregando elemento al tope de la pila\n  cout << \"pila original: \" << pila.empty() << endl; // ver si la pila tiene\n  stack<int> temp = pila; // temporal para imprimir los elementos de la pila\n  while (!temp.empty())\n  {\n    cout << temp.top() << \"-> \";\n    //eliminando el tope de la pila copia \n    temp.pop();\n  }\n  \n  cout << \"\\n tamaño de la pila original: \" << pila.size() << endl;\n}\n\n//! pila con estrucura\nvoid pila(){\n  /*\n  !pila \n  * es una estructua de datos de entradas ordenadas, tales que solo se pueden ingresar\n  * y eliminar por un extremo, llamado cima.\n  */\n  PilaNodo *cima = nullptr;\n  int option;\n  int valor;\n  bool continuar = true;\n  while (continuar)\n  {\n    cout << \"\\n\\tmenu\\n\";\n    cout << \"1- Apilar\" << endl;\n    cout << \"2- Desapilar\" << endl;\n    cout << \"3. Ver pila\" << endl;\n    cout << \"4- Salir\" << endl;\n    cout << \"\\ningrese opcion: \";\n    cin >> option;\n    switch (option)\n    {\n      case 1:\n        cout << \"ingrese un valor: \";\n        cin >> valor;\n        apilar(cima,valor);\n        break;\n      case 2:\n        if(cima == nullptr){\n          cout << \"NULL\" << endl;\n          break;\n        }\n        desapilar(cima);\n        break;\n      case 3:\n        if(cima == nullptr){\n          cout << \" Null\" << endl;\n          break;\n        }\n        verElementosPila(cima);\n        break;\n      case 4:\n        continuar = false;\n        break;\n      \n      default:\n        cout << \"opcion no valida, ingrese otra\" << endl;\n        break;\n    }\n  }\n}\n//? insertar elemento en la pila\nvoid apilar(PilaNodo*& cima,int valor){\n  /*\n  ? pasos para agregar un elemento a la pila\n  *1- crear espacio en memoria para almacerar el nodo (con \"new\")\n  *2- cargar el valor dentro del nodo(dato)\n  *3- cargar el puntero pila dentro del nodo(*siguiente)\n  *4- asignar el nuevo nodo a pila\n  */\n\n  PilaNodo *nuevoNodo = new PilaNodo();// #1\n  nuevoNodo->dato = valor; // #2\n  nuevoNodo->siguiente = cima;// #3\n  cima = nuevoNodo; // #4\n  cout << \"elento apilado\" << endl;\n}\n\nvoid desapilar(PilaNodo*& cima){\n  /*\n  !desapilar\n  *1- creau una variable aux de tipo nodo (Nodo* aux)\n  *2- igual n a aux->dato\n  *3- pasar pila a siguiente nodo\n  *4- eliminar aux\n  */\n  int valor;\n  PilaNodo *aux = cima;// #1\n  valor = aux->dato; // #2\n  cima = aux->siguiente; // #3\n  cout << \"valor: \" << valor << \" eliminado \" << endl;\n  delete aux; // #4\n}\n\nvoid verElementosPila(PilaNodo*& cima){\n \n  PilaNodo *copia = cima; // una copia de la pila para ir desapilando y mostrando los elementos\n  while (copia != nullptr)\n  {\n    cout<<\" \" << copia->dato << \" ->\";\n    copia = copia->siguiente;\n  }\n  cout << \"Null\" << endl;\n}\n\n//todo cola\nvoid using_queque(){\n  /*\n  ! cola (fifo) (first in first out) (primero en entrar, primero en salir)\n  ? queue tiene varios elmentos que puede utilizar\n\n  * push: agrega un elemento al final de la cola\n  * pop: elimina un elemento al principio de la cola\n  * front: acceder al primer elemento de la cola \n  * back: acceder al ultimo elemento de la cola\n  * empty: devuelve true si la pila esta vacia y false si es lo contrario\n  * size: devuelve el numero de elementos de la cola\n  */\n  queue<int> cola;\n  cout << \"cola: \" << cola.empty() << endl;\n  cola.push(1); // agrega un elemento al final de la cola\n  cola.push(2); // agrega un elemento al final de la cola\n  cola.push(3); // agrega un elemento al final de la cola\n  \n  //* recorriendo la cola\n  queue<int> copia = cola;\n  while (!copia.empty())\n  {\n    cout << \" \"<<copia.front()<<\" <- \";\n    copia.pop();\n  }\n  cout << \" Null.\" << endl;\n  cout << \"tamaño de la cola: \" << cola.size()<<endl;\n}\n\nvoid cola(){\n  /*\n  !cola\n  * es una estructura de datos, caracterizada por ser una secuencia de elementos en la que la operacion\n  * de inserción se realiza por un extremo y la extracción por el otro\n  */\n  ColaNodo *frente = nullptr;\n  ColaNodo *fin = nullptr;\n  bool continuar = true;\n  int option;\n  int valor;\n  while (continuar)\n  {\n    cout<<\"\\n\\t menu \\n\"<<endl;\n    cout << \"1- agregar elemento \" << endl;\n    cout << \"2- quitar elemento \" << endl;\n    cout << \"3- mostrar cola \" << endl;\n    cout << \"4- salir\" << endl,\n    cout << \"\\nopcion: \";\n    cin >> option;\n    switch (option)\n    {\n      case 1:\n        cout << \"ingrese el valor: \";\n        cin >> valor;\n        insertarCola(frente, fin, valor);\n        break;\n      case 2:\n        if(cola_vacia(frente)){\n          cout << \"cola vacia \" << endl;\n          break;\n        }\n        eliminar_cola(frente, fin);\n        cout << \" eliminado\" << endl;\n        break;\n      case 3:\n        if(cola_vacia(frente)){\n          cout << \"cola vacia \" << endl;\n          break;\n        }\n        mostrar_cola(frente, fin);\n        break;\n      case 4:\n        continuar = false;\n        break;\n      \n      default:\n        cout << \"opcion no valida, intente denuevo \" << endl;\n        break;\n    }\n  }\n  \n}\n\nvoid insertarCola(ColaNodo*& frente,ColaNodo*& fin,int valor){\n  /*\n    ?pasos para insertar elementos a la cola\n    *1- crear un espacio en memoria para almacenar un nodo.\n    *2- asignar ese nuevo nodo al dato que se quiere insertar.abor.\n    *3- asignar los punteros frente y fin hacia el nuevo nodo.\n  */\n  ColaNodo *nuevo_nodo = new ColaNodo(); // #1\n  nuevo_nodo->dato = valor; // #2\n  nuevo_nodo->siguiente = nullptr;\n  // #3\n  if(cola_vacia(frente)){\n    frente = nuevo_nodo;\n  }else{\n    fin->siguiente=nuevo_nodo;\n  }\n  fin = nuevo_nodo;\n  cout << \"\\n elemento insertado a cola\\n\";\n}\n\n//* funcion para determinar si la cola está vacia o nó\nbool cola_vacia(ColaNodo* frente){\n  return frente == nullptr;\n}\n\nvoid eliminar_cola(ColaNodo *& frente, ColaNodo *& fin){\n  /*\n  ? pasos para eliminar elementos de la cola\n  \n  *1- obtener el valor del nodo\n  *2- crear un nodo aux y asignarele el frente de la cola\n  *3- eliminar el nodo del frente de la cola\n  */\n  int valor = frente->dato; // #1\n  ColaNodo *aux = frente; // #2\n  // #3\n  if(frente == fin){\n    frente = nullptr;\n    fin = nullptr;\n  }else{\n    frente = frente->siguiente;\n  }\n  delete aux;\n  cout << valor;\n}\n\nvoid mostrar_cola(ColaNodo *& frente, ColaNodo *& fin){\n  ColaNodo *copia_frente = frente;\n  ColaNodo *copia_fin = fin;\n  while (copia_frente != nullptr)\n  {\n    eliminar_cola(copia_frente, copia_fin);\n    if(copia_frente != nullptr){\n      cout << \" <- \";\n    }else{\n      cout << \" Null.\" << endl;\n    }\n  }\n  \n  \n}\n/*\n ! DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n*/\n\n\n void historial_web(){\n  //* creando dos pilas para los historiales, tanto de atras como de adelante\n   stack<string> historial_atras;\n   stack<string> historial_adelante;\n   string pagina_actual=\"Inicio\";\n   string var;\n   cout << \"\\t\\nhistorial web\\n\";\n   cout << \"en este menu hay 4 opciones: \" << endl;\n   cout << \"ingrese el nombre de la pagina a la que quiere visitrar\" << endl;\n   cout << \"escribir la letra (b) para retroceder a una pagina anterior(si es que la hay)\" << endl;\n   cout << \"escribir la palabra (f), para avanzar a una pagina ya antes ingresada\" << endl;\n   cout << \"escribir la letra (s), para salir\" << endl;\n   while (true) \n   {\n     cout << \"\\npagina actual: \" << pagina_actual << endl;\n     cout << \"\\ningrese la opcion (b,f,s,pagina): \";\n     getline(cin, var);\n     var = tolower_p(var);\n     if (var ==\"s\" || var ==\"b\" || var==\"f\")\n     {\n      if (var == \"s\")\n      {\n        cout << \"\\nsaliendo del historial........................\" << endl;\n        break;\n      }\n      if (var == \"b\")\n      {\n        if(!historial_atras.empty())//* revisar si aun hay elemtos en la pila\n        {\n          //*es escogio retroceder, la pagina actual, se pasa a la pila de siguiente\n          historial_adelante.push(pagina_actual);\n          pagina_actual = historial_atras.top();//* se asigna el tope de historial atras a pagina actual\n          historial_atras.pop();//* se elimina la ultima pagina del historial de atras\n        }else{\n          cout << \"\\nno hay mas paginas registradas\" << endl;\n        }\n      }\n      if(var == \"f\"){\n        if(!historial_adelante.empty()){//* comprovar si hay elementos en la pila\n        //* se escogio adelantar, la pagina actual, se pasa a la pila de atras\n          historial_atras.push(pagina_actual);//*se pasa a atras la pagina actual\n          pagina_actual = historial_adelante.top();//* se asigna a pagina actual el elemento que este en la sima de siquiente\n          historial_adelante.pop();//* se elimina el tope de la pila siguiente\n        }else{\n          cout << \"\\nno hay mas paginas registradas\" << endl;\n        }\n        \n      }\n     }else{\n      //* se ingreso una nueva pagina\n      historial_atras.push(pagina_actual);//* se pasa a la pila atras la pagina actual\n      pagina_actual = var;//* se asigna a pagina actula, la pagina recien ingresada\n     }\n     \n    \n   }\n   \n }\n\n string tolower_p(string palabra){\n   transform(palabra.begin(), palabra.end(), palabra.begin(), ::tolower);\n   return palabra;\n}\n\nvoid impresora(){\n  queue<string> documentos;\n  string var;\n  string copia;\n\n  cout << \"\\n\\t impresora compartida\\n\";\n  while (true)\n  {\n    if(!documentos.empty()){\n      cout << \"\\nnumero de elmentos en cola: \" << documentos.size() << endl;\n      cout << \"nombre de documento en la cola: \" << documentos.front();\n      cout << \"\\ningrese un nombre de documento, (p) para imprimir o (s) para salir: \";\n      getline(cin, var);\n      copia = tolower_p(var);\n      if(copia ==\"p\" || copia==\"s\"){\n\n        if(copia ==\"p\"){\n          cout << \"imprimiendo: \" << documentos.front() << endl;\n          documentos.pop();\n        }\n        if(copia ==\"s\"){\n          cout << \"\\nsaliendo de la impresora\\n\";\n          break;\n        }\n      }else{\n        documentos.push(var);\n        cout << \"\\nse agrego documento\";\n      }\n    }else{\n      cout<<\" la impresora esta vacia, ingrese un nombre de documento: \";\n      getline(cin, var);\n      documentos.push(var);\n    }\n  }\n  \n}"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/dart/bluefeatherdev.dart",
    "content": "/*\n* EJERCICIO:\n* Implementa los mecanismos de introducción y recuperación de elementos propios de las\n* pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n* o lista (dependiendo de las posibilidades de tu lenguaje).\n*\n* DIFICULTAD EXTRA (opcional):\n* - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n*   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n*   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n*   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n*   el nombre de una nueva web.\n* - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n*   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n*   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n*   interpretan como nombres de documentos.\n*/\n\nimport 'dart:io';\n\n/// 1. [Pila/Stack - LIFO]:\nvoid stackExample() {\n  List<dynamic> stack = [];\n  for (var i = 0; i < 5; i++) stack.add(i);\n  print(stack); // [0, 1, 2, 3, 4]\n\n  dynamic stackItem = stack[stack.length - 1];\n  print(stackItem);   // 4 (OK)\n  print(stack.last);  // 4 (OK)\n  print(stack);       // [0, 1, 2, 3, 4]\n\n  stack.removeAt(stack.length - 1);\n  print(stackItem);   // 4 (not by reference)\n  print(stack.last);  // 3 (OK)\n  print(stack);       // [0, 1, 2, 3]\n\n  stack.removeLast();\n  print(stackItem);   // 4 (not by reference)\n  print(stack.last);  // 2 (OK)\n  print(stack);       // [0, 1, 2]\n}\n\n/// 2. [Cola/Queue - FIFO]:\nvoid queueExample() {\n  List<dynamic> queue = [];\n  for (var i = 0; i < 5; i++) queue.add(i);\n  print(queue); // [0, 1, 2, 3, 4]\n\n  dynamic queueItem = queue[0];\n  print(queueItem);    // 0 (OK)\n  print(queue.first);  // 0 (OK)\n  print(queue);        // [0, 1, 2, 3, 4]\n\n  queue.removeAt(0);\n  print(queueItem);    // 0 (not by reference)\n  print(queue.first);  // 1 (OK)\n  print(queue);        // [1, 2, 3, 4]\n\n  queue.removeAt(0);\n  print(queueItem);    // 0 (not by reference)\n  print(queue.first);  // 2 (OK)\n  print(queue);        // [2, 3, 4]\n}\n\n/// 3. [Pila/Stack - DIFICULTAD EXTRA]:\nvoid browser() {\n  List<dynamic> pageStack = [];\n  int pointer = 0;\n  while (true) {\n    // leer input del usuario\n    print('Escriba acción \"adelante/atrás/salir/ver\" (sin tildes):');\n    String? action = stdin.readLineSync(); /// `stdin.readLineSync()` puede tener problemas para leer caracteres con tilde...\n\n    // finalizar navegación\n    if (action == 'salir') {\n      print('¡Hasta luego!');\n      break;\n    } \n\n    // avanzar en el stack\n    else if (action == 'adelante') {\n      if (pageStack.isEmpty) {\n        print('No has visitado páginas...');\n      }\n      else if (pageStack.length == 1) {\n        print('Solo has visitado una página...');\n      }\n      else if (pointer == pageStack.length - 1) {\n        print('Estás en la última página...');\n      }\n      else {\n        pointer++;\n        print('Ahora estás en: ${pageStack[pointer]}');\n      }\n    }\n\n    // retroceder en el stack\n    else if (action == 'atrás' || action == 'atras') {\n      if (pageStack.isEmpty) {\n        print('No has visitado páginas...');\n      }\n      else if (pointer == 0) {\n        print('Estás en la página de inicio');\n      }\n      else {\n        pointer--;\n        print('Ahora estás en: ${pageStack[pointer]}');\n      }\n    } \n    \n    // ver páginas del stack\n    else if (action == 'ver') {\n      print('Páginas navegador: $pageStack');\n      if (pageStack.isEmpty) {\n        print('No has visitado páginas...');\n      } else {\n        print('Estás en: ${pageStack[pointer]}');\n      }\n    } \n    \n    // añadir páginas al stack\n    else {\n      pageStack.add(action);\n      pointer = pageStack.length - 1;\n    } \n  }\n}\n\n/// 4. [Cola/Queue - DIFICULTAD EXTRA]:\nvoid printer() {\n  List<dynamic> documentQueue = [];\n\n  while (true) {\n    // leer input del usuario\n    print('Escriba acción \"imprimir/salir\":');\n    String? action = stdin.readLineSync();\n\n    // finalizar navegación\n    if (action == 'salir') {\n      print('¡Hasta luego!');\n      break;\n    } \n\n    // imprimir el documento\n    else if (action == 'imprimir') {\n      if (documentQueue.isEmpty) {\n        print('Nada por imprimir...');\n        print('Cola de impresión: $documentQueue');\n      } else {\n        print('Imprimiendo \"${documentQueue.first}\"...');\n        documentQueue.removeAt(0);\n        print('Cola de impresión: $documentQueue');\n      }\n    }\n    \n    // añadir el documento\n    else {\n      documentQueue.add(action);\n      print('Cola de impresión: $documentQueue');\n    } \n  }\n}\n\nvoid main() {\n  /// 1. [Pila/Stack - LIFO]:\n  stackExample();\n\n  /// 2. [Cola/Queue - FIFO]:\n  queueExample();\n\n  /// 3. [Pila/Stack - DIFICULTAD EXTRA]:\n  browser();\n\n  /// 4. [Cola/Queue - DIFICULTAD EXTRA]:\n  printer();\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/dart/raulfauli.dart",
    "content": "/// #07 PILAS Y COLAS\n\nimport 'dart:io';\n\nvoid main() {\n  /**\n   * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n   * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n   * o lista (dependiendo de las posibilidades de tu lenguaje).\n  */\n  exampleQueue();\n  exampleStack();\n\n  // DIFICULTAD EXTRA\n\n  String option = \"\";\n  do {\n    print('''\n    1. Navegador web\n    2. Imprimir documento\n    Q. Salir o \"Ctrl + C\"\n    ''');\n    option = stdin.readLineSync()!.toLowerCase();\n\n    switch (option) {\n      case \"1\":\n        browserHistory();\n        break;\n      case \"2\":\n        printer();\n        break;\n      case \"q\":\n        print('Programa finalizado');\n    }\n  } while (option != \"q\");\n}\n\nvoid exampleQueue() {\n  final List<String> queue = [];\n\n  void pushQueue(String value) {\n    queue.add(value);\n  }\n\n  String? popQueue() {\n    if (queue.isEmpty) {\n      return null;\n    }\n    return queue.removeAt(0);\n  }\n\n  // COLAS\n  pushQueue('A');\n  pushQueue('B');\n  pushQueue('C');\n  print(popQueue()); // A\n  print(popQueue()); // B\n  print(popQueue()); // C\n  print(popQueue()); // null\n}\n\nvoid exampleStack() {\n  final List<String> stack = [];\n\n  void pushStack(String value) {\n    stack.add(value);\n  }\n\n  String? popStack() {\n    if (stack.isEmpty) {\n      return null;\n    }\n    return stack.removeLast();\n  }\n\n  pushStack('A');\n  pushStack('B');\n  pushStack('C');\n  print(popStack()); // C\n  print(popStack()); // B\n  print(popStack()); // A\n  print(popStack()); // null\n}\n\nvoid browserHistory() {\n  const String home = \"duckduckgo.com\";\n\n  final List<String> history = [];\n  final List<String> forwardHistory = [];\n\n  void navigateTo(String page) {\n    print('Navegando a $page');\n    history.add(page);\n    forwardHistory.clear();\n  }\n\n  void goHome() {\n    history.clear();\n    navigateTo(home);\n  }\n\n  void printHistory() {\n    print('Historial:');\n    print(history);\n  }\n\n  void goBack() {\n    if (history.isEmpty) {\n      return;\n    }\n    final page = history.removeLast();\n    print('Volviendo a $page');\n    forwardHistory.add(page);\n  }\n\n  void goForward() {\n    if (forwardHistory.isEmpty) {\n      return;\n    }\n    final page = forwardHistory.removeLast();\n    print('Avanzando a $page');\n    history.add(page);\n  }\n\n  print('''\n    Introduce una web o bien una de las siguientes opciones:\n    N. Inicio\n    H. Historial\n    [. Atrás\n    ]. Adelante\n    Q. Salir\n  ''');\n\n  goHome();\n\n  String option = \"\";\n  do {\n    option = stdin.readLineSync()!.toLowerCase();\n\n    switch (option) {\n      case \"n\" || \"home\":\n        goHome();\n        break;\n      case \"h\" || \"history\":\n        printHistory();\n        break;\n      case \"[\" || \"prev\" || \"back\":\n        goBack();\n        break;\n      case \"]\" || \"next\" || \"forward\":\n        goForward();\n        break;\n      case \"q\":\n        print('Cerrando navegador');\n        break;\n      default:\n        if (!option.isEmpty) {\n          navigateTo(option);\n        }\n    }\n  } while (option != \"q\");\n}\n\nvoid printer() {\n  final List<String> queue = [];\n\n  void addDocument(String document) {\n    queue.add(document);\n    print('Documento añadido: $document');\n    print('Hay ${queue.length} documentos en la cola');\n  }\n\n  void printDocument() {\n    if (queue.isEmpty) {\n      return;\n    }\n    final document = queue.removeAt(0);\n    if (document.isEmpty) {\n      print('No hay documentos para imprimir');\n    } else {\n      print('Imprimiendo: $document');\n    }\n  }\n\n  print('''\n    Añade un nuevo documento o bien una de las siguientes opciones:\n    \"P\" o \"Imprimir\" para imprimir\n    \"Q\" para Salir\n  ''');\n\n  String option = \"\";\n  do {\n    option = stdin.readLineSync()!.toLowerCase();\n\n    switch (option) {\n      case \"p\" || \"print\" || \"imprimir\":\n        printDocument();\n        break;\n      default:\n        if (!option.isEmpty) {\n          addDocument(option);\n        }\n    }\n  } while (option != \"q\");\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/delphi/fduron.dpr",
    "content": "(* Para mi pap, la razn de ser quien soy.\n *\n * EJERCICIO:\n * Implementa los mecanismos de introduccin y recuperacin de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementacin de pila y cadenas de texto, simula el mecanismo adelante/atrs\n *   de un navegador web. Crea un programa en el que puedas navegar a una pgina o indicarle\n *   que te quieres desplazar adelante o atrs, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrs\" desencadenan esta accin, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementacin de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando as se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n *)\nprogram fduron;\n\n{$APPTYPE CONSOLE}\n\n{$R *.res}\n\nuses\n  System.SysUtils,\n  System.Generics.Collections;\n\nfunction MenuDeOpciones: Char;\nbegin\n  WriteLn;\n  WriteLn('**********************************');\n  WriteLn('*        DIFICULTAD EXTRA        *');\n  WriteLn('**********************************');\n  WriteLn('1. Simular el mecanismo Adelante/Atras de un navegador web');\n  WriteLn('2. Simular el mecanismo de una impresora compartida');\n  WriteLn('X. Salir');\n\n  Repeat\n    Write('Selecciona una opcin: ');\n    ReadLn(Result);\n    case Result of\n      '1', '2', 'X', 'x': Exit;\n    else\n      WriteLn('Opcin incorrecta');\n    end;\n  Until UpperCase(Result) = 'X';\nend;\n\nprocedure SimulacionDeNavegador;\nvar\n  PilaAtras, PilaAdelante: TStack<String>;\n  Comando: String;\nbegin\n  WriteLn;\n  WriteLn('SIMULACIN DE NAVEGADOR WEB');\n  WriteLn('  Instrucciones:');\n  WriteLn('  Escribe una direccion URL para agregarla a la pila');\n  WriteLn('  Escribe la palabra \"adelante\" para avanzar en el historial');\n  WriteLn('  Escribe la palabra \"atras\" para regresar en el historial');\n  WriteLn('  Escribe la palabra \"quit\" para salir de la simulacin');\n  WriteLn;\n  PilaAtras := TStack<String>.Create;\n  PilaAdelante := TStack<String>.Create;\n  try\n    PilaAtras.Push('home');\n\n    while true do\n    begin\n      Write('Estas en \"', PilaAtras.Peek, '\" URL o comando: ');\n      ReadLn(Comando);\n\n      if Comando = 'atras' then\n      begin\n        if PilaAtras.Count = 1 then\n          WriteLn('* Err - Has llegado al primer elemento del historial.')\n        else\n        begin\n          PilaAdelante.Push(PilaAtras.Peek);\n          PilaAtras.Pop;\n        end;\n      end\n      else\n      if Comando = 'adelante' then\n      begin\n        if PilaAdelante.Count = 0 then\n          WriteLn('* Err - Has llegado al ultimo elemento del historial.')\n        else\n        begin\n          PilaAtras.Push(PilaAdelante.Peek);\n          PilaAdelante.Pop;\n        end;\n      end\n      else\n      if Comando <> 'quit' then\n      begin\n        PilaAtras.Push(Comando);\n        PilaAdelante.Clear;\n      end\n      else\n        Break;\n\n    end;\n  finally\n    PilaAtras.Free;\n    PilaAdelante.Free;\n  end;\nend;\n\nprocedure SimuladorDeImpresora;\nvar\n  ColaDocumentos: TQueue<string>;\n  Comando: String;\nbegin\n  WriteLn;\n  WriteLn('SIMULACIN DE COLA DE IMPRESIN');\n  WriteLn('  Instrucciones:');\n  WriteLn('  Escribe nombres de documentos PEj. documento1.doc para agregarlo a la lista');\n  WriteLn('  Escribe la palabra \"imprimir\" para imprimir el elemento y eliminarlo de la lista');\n  WriteLn('  Escribe la palabra \"quit\" para salir de la simulacin');\n  WriteLn;\n  ColaDocumentos := TQueue<String>.Create;\n  try\n    while True do\n    begin\n      Write('Nombre del documento o \"imprimir\":');\n      ReadLn(Comando);\n\n      if Comando = 'imprimir' then\n      begin\n        if ColaDocumentos.Count = 0 then\n          WriteLn('* Err - No hay documetos en la cola.')\n        else\n        begin\n          WriteLn(' -Imprimiendo documento ', ColaDocumentos.Dequeue, '...');\n          WriteLn(' -Impresin terminada.');\n        end;\n      end\n      else\n      if Comando <> 'quit' then\n      begin\n        ColaDocumentos.Enqueue(Comando);\n        WriteLn('Documento agregado a la cola');\n      end\n      else\n        Break;\n    end;\n  finally\n    ColaDocumentos.Free;\n  end;\nend;\n\nprocedure DificultadExtra;\nvar\n  Opcion: Char;\nbegin\n  while True do\n  begin\n    Opcion := MenuDeOpciones;\n    case Opcion of\n      '1' : SimulacionDeNavegador;\n      '2' : SimuladorDeImpresora;\n      else\n        break;\n    end;\n  end;\nend;\n\nvar\n  S: TStack<String>;\n  Q: TQueue<String>;\nbegin\n  S := TStack<String>.Create;\n  Q := TQueue<String>.Create;\n  try\n    // Introduccin de datos en una pila\n    S.Push('Valor Uno');\n    S.Push('Valor Dos');\n    S.Push('Valor Tres');\n    S.Push('Valor Cuatro');\n    S.Push('Valor Cinco');\n    S.Push('Valor Seis');\n    WriteLn('Se introdujeron ', S.Count, ' elementos en la pila');\n    WriteLn;\n\n    // Introduccin de datos en una pila\n    Q.Enqueue('Valor Uno');\n    Q.Enqueue('Valor Dos');\n    Q.Enqueue('Valor Tres');\n    Q.Enqueue('Valor Cuatro');\n    Q.Enqueue('Valor Cinco');\n    Q.Enqueue('Valor Seis');\n    WriteLn('Se introdujeron ', S.Count, ' elementos en la cola');\n    WriteLn;\n\n    WriteLn('Recuperacin de datos de una pila (LIFO):');\n    while S.Count > 0 do\n      WriteLn(S.Pop);\n\n    WriteLn;\n\n    WriteLn('Recuperacin de datos de una cola (FIFO):');\n    while Q.Count > 0 do\n      WriteLn(Q.Dequeue);\n\n  finally\n    S.Free;\n    Q.Free;\n  end;\n\n  DificultadExtra;\n\nend.\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/ejercicio.md",
    "content": "# #07 PILAS Y COLAS\n> #### Dificultad: Media | Publicación: 12/02/24 | Corrección: 19/02/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/go/AmadorQuispe.go",
    "content": "package main\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\t//stack -> LIFO\n\t//Push\n\tstackStudents := []string{}\n\tstackStudents = append(stackStudents, \"Amador\")\n\tstackStudents = append(stackStudents, \"Pedro\", \"Alex\")\n\tfmt.Println(stackStudents)\n\t//Pop\n\titemPop := stackStudents[len(stackStudents)-1]\n\tstackStudents = stackStudents[:len(stackStudents)-1]\n\tfmt.Println(\"Pop element :\", itemPop)\n\tfmt.Println(stackStudents)\n\n\t//Queue -> FIFO\n\t//enqueue\n\tqueueNumbers := []int{}\n\tqueueNumbers = append(queueNumbers, 1)\n\tqueueNumbers = append(queueNumbers, 2, 3, 4, 5)\n\tfmt.Println(queueNumbers)\n\n\t//dequeue\n\titemDequeue := queueNumbers[0]\n\tqueueNumbers = queueNumbers[1:]\n\tfmt.Println(\"Dequeue element :\", itemDequeue)\n\tfmt.Println(queueNumbers)\n\tsharedPrinting()\n\twebNavigation()\n}\n\nfunc sharedPrinting() {\n\tjobPrints := []string{}\n\treader := bufio.NewReader(os.Stdin)\n\tfor {\n\t\tfmt.Print(\"Añade un documento o selecciona imprimir/salir: \")\n\t\taction, _ := reader.ReadString('\\n')\n\t\taction = strings.TrimSpace(action)\n\t\tif action == \"salir\" {\n\t\t\tfmt.Println(\"Saliendo...\")\n\t\t\tos.Exit(0)\n\t\t} else if action == \"imprimir\" {\n\t\t\tif len(jobPrints) > 0 {\n\t\t\t\tp := jobPrints[len(jobPrints)-1]\n\t\t\t\tjobPrints = jobPrints[:len(jobPrints)-1]\n\t\t\t\tfmt.Println(\"Imprimiendo :\", p)\n\t\t\t}\n\t\t} else {\n\t\t\tjobPrints = append(jobPrints, action)\n\t\t\tfmt.Println(\"Trabajo impresión agregada a la cola\")\n\t\t}\n\t\tfmt.Println(\"Cola de impresión\", jobPrints)\n\t}\n}\n\nfunc webNavigation() {\n\thistory := []string{}\n\treader := bufio.NewReader(os.Stdin)\n\tfor {\n\t\tif len(history) > 0 {\n\t\t\tfmt.Print(\"Añade una url o interactúa con palabras adelante/atrás/salir:\")\n\t\t} else {\n\t\t\tfmt.Print(\"Añade una url:\")\n\t\t}\n\t\tcommand, _ := reader.ReadString('\\n')\n\t\tcommand = strings.TrimSpace(command)\n\t\tswitch command {\n\t\tcase \"salir\":\n\t\t\tfmt.Println(\"Saliendo del navegador\")\n\t\t\tos.Exit(0)\n\t\tcase \"adelante\":\n\t\t\tfmt.Println(\"No hay historial hacia adelante\")\n\t\tcase \"atrás\":\n\t\t\tif len(history) == 0 {\n\t\t\t\tfmt.Println(\"No hay mas historial hacia atrás\")\n\t\t\t}\n\t\t\thistory = history[:len(history)-1]\n\n\t\tdefault:\n\t\t\thistory = append(history, command)\n\t\t}\n\t\tif len(history) > 0 {\n\t\t\tlastItem := history[len(history)-1]\n\t\t\tfmt.Printf(\"Has navegado a la web: %s.\\n\", lastItem)\n\t\t} else {\n\t\t\tfmt.Println(\"Estás en la página de inicio.\")\n\t\t}\n\n\t}\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/go/FreyFonseca117.go",
    "content": "// # #07 PILAS Y COLAS\n// > #### Dificultad: Media | Publicación: 12/02/24 | Corrección: 19/02/24\n\n// ## Ejercicio\n\n// ```\n// /*\n//  * EJERCICIO:\n//  * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n//  * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n//  * o lista (dependiendo de las posibilidades de tu lenguaje).\n//  *\n//  * DIFICULTAD EXTRA (opcional):\n//  * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n//  *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n//  *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n//  *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n//  *   el nombre de una nueva web.\n//  * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n//  *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n//  *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n//  *   interpretan como nombres de documentos.\n//  */\n// ```\n// #### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\n// Sigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n// > Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n\npackage main\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\n// Stack (Pila - LIFO)\ntype Stack struct {\n\titems []string\n}\n\nfunc (s *Stack) Push(item string) {\n\ts.items = append(s.items, item)\n}\n\nfunc (s *Stack) Pop() (string, bool) {\n\tif len(s.items) == 0 {\n\t\treturn \"\", false\n\t}\n\titem := s.items[len(s.items)-1]\n\ts.items = s.items[:len(s.items)-1]\n\treturn item, true\n}\n\nfunc (s *Stack) Peek() (string, bool) {\n\tif len(s.items) == 0 {\n\t\treturn \"\", false\n\t}\n\treturn s.items[len(s.items)-1], true\n}\n\n// Queue (Cola - FIFO)\ntype Queue struct {\n\titems []string\n}\n\nfunc (q *Queue) Enqueue(item string) {\n\tq.items = append(q.items, item)\n}\n\nfunc (q *Queue) Dequeue() (string, bool) {\n\tif len(q.items) == 0 {\n\t\treturn \"\", false\n\t}\n\titem := q.items[0]\n\tq.items = q.items[1:]\n\treturn item, true\n}\n\nfunc navegadorWeb() {\n\thistorial := Stack{}\n\tadelante := Stack{}\n\tcurrentPage := \"\"\n\n\tfor {\n\t\tfmt.Printf(\"\\nPágina actual: [%s]\\n\", currentPage)\n\t\tfmt.Println(\"1. Ingresar URL\")\n\t\tfmt.Println(\"2. Atrás\")\n\t\tfmt.Println(\"3. Adelante\")\n\t\tfmt.Println(\"4. Salir\")\n\t\tfmt.Print(\"Seleccione opción: \")\n\n\t\tvar input string\n\t\tfmt.Scanln(&input)\n\n\t\tswitch strings.ToLower(input) {\n\t\tcase \"1\", \"url\":\n\t\t\tfmt.Print(\"Ingrese URL: \")\n\t\t\tfmt.Scanln(&input)\n\t\t\tif currentPage != \"\" {\n\t\t\t\thistorial.Push(currentPage)\n\t\t\t}\n\t\t\tcurrentPage = input\n\t\t\tadelante = Stack{} // Resetear pila adelante\n\n\t\tcase \"2\", \"atrás\":\n\t\t\tif page, ok := historial.Pop(); ok {\n\t\t\t\tadelante.Push(currentPage)\n\t\t\t\tcurrentPage = page\n\t\t\t} else {\n\t\t\t\tfmt.Println(\"No hay páginas anteriores\")\n\t\t\t}\n\n\t\tcase \"3\", \"adelante\":\n\t\t\tif page, ok := adelante.Pop(); ok {\n\t\t\t\thistorial.Push(currentPage)\n\t\t\t\tcurrentPage = page\n\t\t\t} else {\n\t\t\t\tfmt.Println(\"No hay páginas siguientes\")\n\t\t\t}\n\n\t\tcase \"4\", \"salir\":\n\t\t\treturn\n\n\t\tdefault:\n\t\t\tfmt.Println(\"Opción no válida\")\n\t\t}\n\t}\n}\n\nfunc main() {\n\tnavegadorWeb()\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/go/MiguelP-Dev.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc main() {\n\tvar lifo sliceStack\n\tvar fifo sliceQueue\n\n\tfor {\n\t\tvar opt uint8\n\t\tfmt.Println(\"Selecciona uan opcion:\")\n\t\tfmt.Println(\"1. Ejecuta las funciones de Pilas.\")\n\t\tfmt.Println(\"2. Ejecuta las funciones de Colas.\")\n\t\tfmt.Println(\"3. Navegador.\")\n\t\tfmt.Println(\"4. Impresora.\")\n\t\tfmt.Println(\"5. Salir.\")\n\t\tfmt.Scan(&opt)\n\n\t\tswitch opt {\n\t\tcase 1:\n\t\t\t// LIFO (Last In, First Out).\n\t\t\tlifo.push(\"MiguelP-Dev\")\n\t\t\tlifo.push(\"master\")\n\n\t\t\tfmt.Println(lifo.pop())\n\t\t\tfmt.Println(lifo.pop())\n\t\t\tfmt.Println(lifo.pop())\n\n\t\tcase 2:\n\t\t\t// FIFO (First In, First Out).\n\n\t\t\tfifo.push(\"0\")\n\t\t\tfifo.push(\"1\")\n\t\t\tfifo.push(\"2\")\n\t\t\tfifo.push(\"3\")\n\n\t\t\tfmt.Println(fifo.pop())\n\t\t\tfmt.Println(fifo.pop())\n\t\t\tfmt.Println(fifo.pop())\n\t\t\tfmt.Println(fifo.pop())\n\t\t\tfmt.Println(fifo.pop())\n\n\t\tcase 3:\n\t\t\twebNavigator(&navigator)\n\t\tcase 4:\n\t\t\tdocPrinter(&printerv)\n\t\tcase 5:\n\t\t\treturn\n\t\tdefault:\n\t\t\tcontinue\n\t\t}\n\n\t}\n}\n\n// LIFO (Last In, First Out).\n// sliceStack Es un slice que funcionará como una pila(Stack).\ntype sliceStack []string\n\n// push Método para agregar datos a un slice que funciona como pila.\nfunc (s *sliceStack) push(v string) {\n\t*s = append(*s, v)\n}\n\n// popSlice Método pop para sacar elementos de uns slice que sirve como pila(Los slices no tienen una función 'Delete', pero son ideales como pilas).\nfunc (s *sliceStack) pop() string {\n\tif len(*s) == 0 {\n\t\tfmt.Println(\"La pila está vacía.\")\n\t\treturn \"\"\n\t}\n\tindex := len(*s) - 1\n\telement := (*s)[index]\n\t*s = (*s)[:index]\n\treturn element\n}\n\n// FIFO (First In, First Out).\n// sliceQueue Es un slice que funcionará como una cola.\ntype sliceQueue []string\n\n// push Método para encolar elementos\nfunc (q *sliceQueue) push(v string) {\n\t*q = append(*q, v)\n}\n\n// pop Método para deencolar elementos\nfunc (q *sliceQueue) pop() string {\n\tif len(*q) == 0 {\n\t\tfmt.Println(\"La cola está vacía.\")\n\t\treturn \"\"\n\t}\n\tpop := (*q)[0]\n\t*q = (*q)[1:]\n\treturn pop\n}\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n */\n// navStack pila para la función que simula un navegador\ntype navStack []string\n\nvar navigator navStack\nvar position = 0\n\nfunc webNavigator(n *navStack) {\n\tfor {\n\t\tvar option string\n\t\tfmt.Printf(\"\\n\")\n\t\tfmt.Println(\"adelante\", \" - \", \"Viajar a la página siguiente.\")\n\t\tfmt.Println(\"atras\", \" - \", \"Viajar a la página anterior.\")\n\t\tfmt.Println(\"salir\", \" - \", \"Salir de la app.\")\n\t\tfmt.Println(\"borrar\", \" - \", \"Borra el historial.\")\n\t\tfmt.Printf(\"Ingresa una de las opciones: \")\n\t\tfmt.Scan(&option)\n\n\t\tswitch option {\n\t\tcase \"salir\":\n\t\t\tfmt.Println(\"Saliendo... Bye!\")\n\t\t\treturn\n\t\tcase \"adelante\":\n\t\t\tif position < len(*n)-1 {\n\t\t\t\tposition++\n\t\t\t\tfmt.Println(\"Viajando a:\", (*n)[position])\n\t\t\t} else {\n\t\t\t\tfmt.Println(\"No hay páginas delante.\")\n\t\t\t}\n\t\tcase \"atras\":\n\t\t\tif position > 0 {\n\t\t\t\tposition--\n\t\t\t\tfmt.Println(\"Viajando a:\", (*n)[position])\n\t\t\t} else {\n\t\t\t\tfmt.Println(\"No hay páginas hacia atrás.\")\n\t\t\t}\n\t\tcase \"borrar\":\n\t\t\t*n = []string{}\n\t\t\tposition = 0\n\t\t\tfmt.Println(\"Histarial borrado.\")\n\t\tdefault:\n\t\t\tif len(*n) == 0 {\n\t\t\t\t*n = append(*n, option)\n\t\t\t\tposition = 0\n\t\t\t} else {\n\t\t\t\t*n = append((*n)[:position+1], option)\n\t\t\t\tposition++\n\t\t\t}\n\t\t\tfmt.Println(\"Navegando a:\", (*n)[position])\n\t\t}\n\t}\n\n}\n\ntype queue []string\n\nvar printerv queue\n\nfunc docPrinter(q *queue) {\n\tvar option string\n\tfmt.Scan(&option)\n\n\tswitch option {\n\tcase \"imprimir\":\n\t\tif len(*q) == 0 {\n\t\t\tfmt.Println(\"La cola de impresión está vacía.\")\n\t\t\treturn\n\t\t}\n\t\tfmt.Println(\"Imprimiendo: \" + (*q)[0])\n\t\t*q = (*q)[1:]\n\tcase \"Salir\":\n\t\treturn\n\tdefault:\n\t\t*q = append(*q, option)\n\t\tfmt.Println(\"Documento agregado a la cola\")\n\t}\n\tdocPrinter(&printerv)\n\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/go/N0HagoNada.go",
    "content": "package main\n\nimport (\n\t\"bufio\"\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n)\n\ntype Stack struct {\n\telements []string\n}\n\nfunc (s *Stack) Push(elem string) {\n\ts.elements = append(s.elements, elem)\n}\n\nfunc (s *Stack) Pop() (string, bool) {\n\tif len(s.elements) == 0 {\n\t\treturn \"\", false\n\t}\n\telem := s.elements[len(s.elements)-1]\n\ts.elements = s.elements[:len(s.elements)-1]\n\treturn elem, true\n}\n\ntype Queue struct {\n\telements []string\n}\n\n// Enqueue añade un elemento al final de la cola.\nfunc (q *Queue) Enqueue(elem string) {\n\tq.elements = append(q.elements, elem)\n}\n\n// Dequeue remueve el primer elemento de la cola y lo devuelve.\nfunc (q *Queue) Dequeue() (error, string) {\n\tif len(q.elements) == 0 {\n\t\treturn errors.New(\"La cola esta vacia\"), \"\" // o manejar el error adecuadamente\n\t}\n\telem := q.elements[0]\n\tq.elements = q.elements[1:]\n\treturn nil, elem\n}\n\ntype WebBrowser struct {\n\thistory Stack\n\tforward Stack\n\tcurrent string\n}\n\nfunc (wb *WebBrowser) Visit(page string) {\n\tif wb.current != \"\" {\n\t\twb.history.Push(wb.current)\n\t}\n\twb.current = page    // Set the current page\n\twb.forward = Stack{} // Clear forward stack\n}\n\nfunc (wb *WebBrowser) Back() (string, bool) {\n\tif page, ok := wb.history.Pop(); ok {\n\t\twb.forward.Push(wb.current)\n\t\twb.current = page\n\t\treturn page, true\n\t}\n\treturn \"\", false\n}\n\nfunc (wb *WebBrowser) Forward() (string, bool) {\n\tif page, ok := wb.forward.Pop(); ok {\n\t\twb.history.Push(wb.current)\n\t\twb.current = page\n\t\treturn page, true\n\t}\n\treturn \"\", false\n}\n\nfunc (wb *WebBrowser) CurrentPage() string {\n\treturn wb.current\n}\n\nfunc main() {\n\twb := WebBrowser{}\n\tscanner := bufio.NewScanner(os.Stdin)\n\n\tfmt.Println(\"Web Browser Simulator\")\n\tfor {\n\t\tfmt.Print(\"Enter a URL, 'atras', 'adelante', or 'exit' to navigate: \")\n\t\tscanner.Scan()\n\t\tinput := strings.TrimSpace(scanner.Text())\n\n\t\tswitch input {\n\t\tcase \"atras\":\n\t\t\tif page, ok := wb.Back(); ok {\n\t\t\t\tfmt.Println(\"Moved back to:\", page)\n\t\t\t} else {\n\t\t\t\tfmt.Println(\"No more history.\")\n\t\t\t}\n\t\tcase \"adelante\":\n\t\t\tif page, ok := wb.Forward(); ok {\n\t\t\t\tfmt.Println(\"Moved forward to:\", page)\n\t\t\t} else {\n\t\t\t\tfmt.Println(\"No pages to move forward to.\")\n\t\t\t}\n\t\tcase \"exit\":\n\t\t\tfmt.Println(\"Exiting Web Browser Simulator.\")\n\t\t\treturn\n\t\tdefault:\n\t\t\twb.Visit(input)\n\t\t\tfmt.Println(\"Visited:\", wb.CurrentPage())\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/go/hozlucas28.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n)\n\nfunc main() {\n\t/*\n\t   Stack methods for insert and recover items...\n\t*/\n\n\tfmt.Println(\"Stack methods for insert and recover items...\")\n\n\tvar stack []int8 = []int8{1, 5, 7, 9, 8}\n\n\tfmt.Println(\"\\nvar stack []int = []int{1, 5, 7, 9, 8}\")\n\n\tfmt.Println(\"\\nInsert an element at the end of the stack...\")\n\n\tstack = append(stack, 12)\n\n\tfmt.Printf(\"\\nstack = append(stack, 12) --> stack = %d\\n\", stack)\n\n\tfmt.Println(\"\\nRecover an element of the stack...\")\n\n\tvar lastStackElement int8 = stack[len(stack)-1]\n\tstack = stack[:len(stack)-1]\n\n\tfmt.Println(\"\\nvar lastStackElement int8 = stack[len(stack)-1]\\nstack = stack[:len(stack)-1]\")\n\n\tfmt.Printf(\"\\nlastStackElement --> %d\\n\", lastStackElement)\n\tfmt.Printf(\"\\nstack --> %d\\n\", stack)\n\n\tfmt.Println(\"\\n# ---------------------------------------------------------------------------------- #\")\n\n\t/*\n\t   Queue methods for insert and recover items...\n\t*/\n\n\tfmt.Println(\"\\nQueue methods for insert and recover items...\")\n\n\tvar queue []string = []string{\"Hello\", \"World\"}\n\n\tfmt.Println(\"\\nvar queue []string = []string{'Hello', 'World'}\")\n\n\tfmt.Println(\"\\nInsert an element at the end of the queue...\")\n\n\tqueue = append(queue, \"Golang\")\n\n\tfmt.Printf(\"\\nqueue = append(queue, 'Golang') --> queue = %s\\n\", queue)\n\n\tfmt.Println(\"\\nRecover an element of the queue...\")\n\n\tvar firstQueueElement string = queue[0]\n\tqueue = queue[1:]\n\n\tfmt.Println(\"\\nvar firstQueueElement string = queue[0]\\nqueue = queue[1:]\")\n\n\tfmt.Printf(\"\\nfirstQueueElement --> %s\\n\", firstQueueElement)\n\tfmt.Printf(\"\\nqueue --> %s\\n\", queue)\n\n\tfmt.Println(\"\\n# ---------------------------------------------------------------------------------- #\")\n\n\t/*\n\t   Additional challenge...\n\t*/\n\n\t// Stack exercise...\n\tfmt.Println(\"\\nStack exercise...\")\n\n\tvar browserHistory []string = []string{}\n\n\tvar shouldExit bool = false\n\tfor !shouldExit {\n\t\tfmt.Printf(\"\\nBrowser history --> %s\\n\", browserHistory)\n\n\t\tvar operation string\n\t\tfmt.Print(\"\\nSelect an operation ('Back', 'Forward', or 'Exit'): \")\n\t\t_, operationErr := fmt.Scanf(\"%s\\n\", &operation)\n\n\t\tif operationErr != nil {\n\t\t\tshouldExit = true\n\t\t\tcontinue\n\t\t}\n\n\t\tvar operationFormatted string = strings.ToUpper(operation)\n\n\t\tswitch operationFormatted {\n\t\tcase \"BACK\":\n\t\t\tif len(browserHistory) > 0 {\n\t\t\t\tbrowserHistory = browserHistory[:len(browserHistory)-1]\n\t\t\t}\n\t\t\tbreak\n\n\t\tcase \"FORWARD\":\n\t\t\tvar lastPageNumber int = 0\n\n\t\t\tif len(browserHistory) > 0 {\n\t\t\t\tvar lastPage string = browserHistory[len(browserHistory)-1]\n\t\t\t\t_, lastPageNumberStr, _ := strings.Cut(lastPage, \" \")\n\t\t\t\tlastPageNumber, _ = strconv.Atoi(strings.TrimSpace(lastPageNumberStr))\n\t\t\t}\n\n\t\t\tvar newPage string = fmt.Sprintf(\"Page %d\", lastPageNumber+1)\n\t\t\tbrowserHistory = append(browserHistory, newPage)\n\t\t\tbreak\n\n\t\tcase \"EXIT\":\n\t\t\tshouldExit = true\n\t\t\tbreak\n\n\t\tdefault:\n\t\t\tbreak\n\t\t}\n\t}\n\n\t// Queue exercise...\n\tfmt.Println(\"\\nQueue exercise...\")\n\n\tvar documents []string = []string{}\n\n\tfor true {\n\t\tfmt.Printf(\"\\nDocuments --> %s\\n\", documents)\n\n\t\tvar userInput string\n\t\tfmt.Print(\"\\nAdd a document to print, or write 'Print' to print the document in the queue: \")\n\t\t_, userInputErr := fmt.Scanf(\"%s\\n\", &userInput)\n\n\t\tif userInputErr != nil {\n\t\t\tbreak\n\t\t}\n\n\t\tvar userInputFormatted string = strings.ToUpper(userInput)\n\n\t\tif userInputFormatted == \"PRINT\" {\n\t\t\tif len(documents) > 0 {\n\t\t\t\tvar printedDocument string = documents[0]\n\t\t\t\tdocuments = documents[1:]\n\t\t\t\tfmt.Printf(\"\\nPrinted document --> %s\\n\", printedDocument)\n\t\t\t}\n\t\t} else {\n\t\t\tdocuments = append(documents, userInput)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/go/kodenook.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc main() {\n\n\t//stack\n\tstack := []string{\"javascript\", \"php\"}\n\n\tstack = append([]string{\"go\"}, stack...)\n\tfmt.Println(stack)\n\n\tstack = stack[1:]\n\tfmt.Println(stack)\n\n\t// queue\n\n\tqueue := []string{\"mongo\", \"mysql\"}\n\n\tqueue = append(queue, \"postgres\")\n\tfmt.Println(queue)\n\n\tqueue = queue[1:]\n\tfmt.Println(queue)\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/go/miguelex.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n)\n\nfunc main() {\n\n\tvar pila [10]int\n\tindice := 0\n\n\tpila[indice] = 3\n\tindice++\n\n\tfmt.Println(\"Contenido de la pila\")\n\tfor i := 0; i < indice; i++ {\n\t\tfmt.Println(pila[i])\n\t}\n\n\tfmt.Println(\"--------------------\")\n\n\tpila[indice] = 4\n\tindice++\n\tpila[indice] = 1\n\tindice++\n\n\tfmt.Println(\"Contenido de la pila\")\n\tfor i := 0; i < indice; i++ {\n\t\tfmt.Println(pila[i])\n\t}\n\n\tfmt.Println(\"--------------------\")\n\n\t// desapilamos\n\n\tindice--\n\n\tfmt.Println(\"Contenido de la pila\")\n\tfor i := 0; i < indice; i++ {\n\t\tfmt.Println(pila[i])\n\t}\n\n\tfmt.Println(\"--------------------\")\n\n\tpila[indice] = 5\n\tindice++\n\n\tfmt.Println(\"Contenido de la pila\")\n\tfor i := 0; i < indice; i++ {\n\t\tfmt.Println(pila[i])\n\t}\n\n\tfmt.Println(\"--------------------\")\n\n\tfmt.Println(\"Cola:\")\n\n\tvar cola [10]int\n\tindice = 0\n\n\tcola[indice] = 3\n\tindice++\n\n\tfmt.Println(\"Contenido de la cola\")\n\tfor i := 0; i < indice; i++ {\n\t\tfmt.Println(cola[i])\n\t}\n\n\tfmt.Println(\"--------------------\")\n\n\tcola[indice] = 4\n\tindice++\n\tcola[indice] = 1\n\tindice++\n\n\tfmt.Println(\"Contenido de la cola\")\n\n\tfor i := 0; i < indice; i++ {\n\t\tfmt.Println(cola[i])\n\t}\n\n\tfmt.Println(\"--------------------\")\n\n\t// desencolamos\n\n\tfor i := 0; i < indice; i++ {\n\t\tcola[i] = cola[i+1]\n\t}\n\tindice--\n\n\tfmt.Println(\"Contenido de la cola\")\n\n\tfor i := 0; i < indice; i++ {\n\t\tfmt.Println(cola[i])\n\t}\n\n\tfmt.Println(\"--------------------\")\n\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/go/qwik-zgheib.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n)\n\n// Stack defines the interface for a LIFO stack.\ntype Stack interface {\n\tPush(item string)\n\tPop() (string, error)\n\tPrint()\n}\n\n// Queue defines the interface for a FIFO queue.\ntype Queue interface {\n\tEnqueue(item string)\n\tDequeue() (string, error)\n\tPrint()\n}\n\ntype StringStack struct {\n\titems []string\n}\n\nfunc NewStringStack() *StringStack {\n\treturn &StringStack{items: []string{}}\n}\n\nfunc (s *StringStack) Push(item string) {\n\ts.items = append(s.items, item)\n}\n\nfunc (s *StringStack) Pop() (string, error) {\n\tif len(s.items) == 0 {\n\t\treturn \"\", fmt.Errorf(\"stack is empty\")\n\t}\n\titem := s.items[len(s.items)-1]\n\ts.items = s.items[:len(s.items)-1]\n\treturn item, nil\n}\n\nfunc (s *StringStack) Print() {\n\tfmt.Println(s.items)\n}\n\ntype StringQueue struct {\n\titems []string\n}\n\nfunc NewStringQueue() *StringQueue {\n\treturn &StringQueue{items: []string{}}\n}\n\nfunc (q *StringQueue) Enqueue(item string) {\n\tq.items = append(q.items, item)\n}\n\nfunc (q *StringQueue) Dequeue() (string, error) {\n\tif len(q.items) == 0 {\n\t\treturn \"\", fmt.Errorf(\"queue is empty\")\n\t}\n\titem := q.items[0]\n\tq.items = q.items[1:]\n\treturn item, nil\n}\n\nfunc (q *StringQueue) Print() {\n\tfmt.Println(q.items)\n}\n\ntype WebNavigator struct {\n\tstack Stack\n}\n\nfunc NewWebNavigator(stack Stack) *WebNavigator {\n\treturn &WebNavigator{stack: stack}\n}\n\nfunc (wn *WebNavigator) Navigate() {\n\tfor {\n\t\tvar action string\n\t\tfmt.Println(\"Enter a URL or type 'forward', 'back', or 'exit':\")\n\t\tfmt.Scan(&action)\n\t\tswitch action {\n\t\tcase \"exit\":\n\t\t\tfmt.Println(\"Exiting web navigator.\")\n\t\t\treturn\n\t\tcase \"forward\":\n\t\t\tfmt.Println(\"Forwarding to next page.\")\n\t\t\t_, err := wn.stack.Pop()\n\t\t\tif err != nil {\n\t\t\t\tfmt.Println(\"No next pages.\")\n\t\t\t}\n\t\tcase \"back\":\n\t\t\t_, err := wn.stack.Pop()\n\t\t\tif err != nil {\n\t\t\t\tfmt.Println(\"No previous pages.\")\n\t\t\t}\n\t\tdefault:\n\t\t\twn.stack.Push(action)\n\t\t}\n\t\twn.stack.Print()\n\t}\n}\n\ntype SharedPrinter struct {\n\tqueue Queue\n}\n\nfunc NewSharedPrinter(queue Queue) *SharedPrinter {\n\treturn &SharedPrinter{queue: queue}\n}\n\nfunc (sp *SharedPrinter) PrintDocuments() {\n\tfor {\n\t\tvar action string\n\t\tfmt.Println(\"Add a document or type 'print' or 'exit':\")\n\t\tfmt.Scan(&action)\n\t\tswitch action {\n\t\tcase \"exit\":\n\t\t\treturn\n\t\tcase \"print\":\n\t\t\tdoc, err := sp.queue.Dequeue()\n\t\t\tif err != nil {\n\t\t\t\tfmt.Println(\"No documents to print.\")\n\t\t\t} else {\n\t\t\t\tfmt.Printf(\"Printing: %s\\n\", doc)\n\t\t\t}\n\t\tdefault:\n\t\t\tsp.queue.Enqueue(action)\n\t\t}\n\t\tsp.queue.Print()\n\t}\n}\n\nfunc main() {\n\tstack := NewStringStack()\n\tstack.Push(\"1\")\n\tstack.Push(\"2\")\n\tstack.Push(\"3\")\n\tstack.Print()\n\titem, _ := stack.Pop()\n\tfmt.Println(\"Popped item:\", item)\n\tstack.Print()\n\n\tqueue := NewStringQueue()\n\tqueue.Enqueue(\"1\")\n\tqueue.Enqueue(\"2\")\n\tqueue.Enqueue(\"3\")\n\tqueue.Print()\n\titem, _ = queue.Dequeue()\n\tfmt.Println(\"Dequeued item:\", item)\n\tqueue.Print()\n\n\twebNavigator := NewWebNavigator(NewStringStack())\n\twebNavigator.Navigate()\n\n\tsharedPrinter := NewSharedPrinter(NewStringQueue())\n\tsharedPrinter.PrintDocuments()\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/go/raynerpv2022.go",
    "content": "/*\n#  * EJERCICIO:\n#  * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n#  * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n#  * o lista (dependiendo de las posibilidades de tu lenguaje).\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n#  *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n#  *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n#  *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n#  *   el nombre de una nueva web.\n#  * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n#  *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n#  *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n#  *   interpretan como nombres de documentos.\n#\n*/\npackage main\n\nimport \"fmt\"\n\ntype Pila struct {\n\titem []string\n}\n\ntype Cola struct {\n\titem []string\n}\n\nfunc (p *Pila) set_pila(items string) {\n\tp.item = append(p.item, items)\n}\n\nfunc (p *Pila) get_pila() string {\n\tlast := p.item[len(p.item)-1]\n\tp.item = append(p.item[:len(p.item)-1])\n\treturn last\n}\n\nfunc (c *Cola) set_cola(items string) {\n\tc.item = append(c.item, items)\n}\n\nfunc (c *Cola) get_cola() string {\n\tlast := c.item[0]\n\tc.item = append(c.item[1:])\n\treturn last\n}\n\nfunc pila_func(pilita *Pila) {\n\top_pila := \"\"\n\tfmt.Println(\" PILA, Set (1) o Get (2)\")\n\tfmt.Scanln(&op_pila)\n\tswitch op_pila {\n\tcase \"1\":\n\t\tprint(\"Items a introducir : \")\n\t\tit := \"\"\n\t\tfmt.Scanln(&it)\n\t\tpilita.set_pila(it)\n\tcase \"2\":\n\t\tfmt.Println(\"Sacando ultimo elemento pila\")\n\t\tfmt.Println(\"Pila completa \", pilita.item)\n\t\tfmt.Println(pilita.get_pila())\n\t\tfmt.Println(\"Pila actualizada \", pilita.item)\n\n\t}\n\n}\n\nfunc cola_func(colita *Cola) {\n\top_cola := \"\"\n\tfmt.Println(\" Cola, Set (1) o Get (2)\")\n\tfmt.Scanln(&op_cola)\n\tswitch op_cola {\n\tcase \"1\":\n\t\tit := \"\"\n\t\tfmt.Println(\"Items a introducir : \")\n\t\tfmt.Scanln(&it)\n\t\tcolita.set_cola(it)\n\tcase \"2\":\n\t\tfmt.Println(\"Sacando ultimo elemento cola\")\n\t\tfmt.Println(\"COla completa \", colita.item)\n\t\tfmt.Println(colita.get_cola())\n\t\tfmt.Println(\"Cola actualizada \", colita.item)\n\n\t}\n\n}\n\nfunc ex1() {\n\tpilita := Pila{\n\t\t[]string{\"11\", \"2\", \"3\", \"4\", \"5\", \"6\"},\n\t}\n\tcolita := Cola{\n\t\t[]string{\"1\", \"2\", \"3\", \"4\", \"5\", \"6\"},\n\t}\n\tvar op string\n\tfor {\n\t\tfmt.Println(\" Pila (1) o  Cola (2) Salir (3):\")\n\t\tfmt.Scanln(&op)\n\t\tswitch op {\n\t\tcase \"1\":\n\t\t\tpila_func(&pilita)\n\t\tcase \"2\":\n\t\t\tcola_func(&colita)\n\t\tcase \"3\":\n\t\t\treturn\n\t\tdefault:\n\t\t\tfmt.Println(\"OPcion no valida\")\n\t\t}\n\n\t}\n}\n\n// ******* EXTRA ******\nfunc isEmpty(list1 []string, cad string) bool {\n\tif len(list1) == 0 {\n\t\tfmt.Println(cad)\n\t\treturn true\n\t} else {\n\t\treturn false\n\t}\n}\nfunc TOR() {\n\tweb_list := []string{}\n\tindex := 0\n\tfor {\n\t\top := \"\"\n\t\tfmt.Println(\"atras, adelante, url, salir :\")\n\t\tfmt.Scanln(&op)\n\t\tswitch op {\n\t\tcase \"atras\":\n\t\t\tif !(isEmpty(web_list, \"Listado de web vacio\")) {\n\t\t\t\tif index > 0 {\n\t\t\t\t\tindex--\n\t\t\t\t}\n\t\t\t\tfmt.Printf(\"navegando a  : %v indice %d \\n\", web_list[index], index)\n\t\t\t}\n\t\tcase \"adelante\":\n\t\t\tif !(isEmpty(web_list, \"Listado de web vacio\")) {\n\t\t\t\tif index < len(web_list)-1 {\n\t\t\t\t\tindex++\n\t\t\t\t}\n\t\t\t\tfmt.Printf(\"navegando a  : %v indice %d \\n\", web_list[index], index)\n\t\t\t}\n\t\tcase \"url\":\n\t\t\tif !(isEmpty(web_list, \"Listado de web vacio\")) {\n\t\t\t\tfmt.Printf(\"TAB de WEB : %v indice %d \\n\", web_list, index)\n\t\t\t}\n\t\tcase \"salir\":\n\t\t\treturn\n\t\tdefault:\n\n\t\t\tweb_list = append(web_list, op)\n\t\t\tindex = len(web_list) - 1\n\t\t\tfmt.Printf(\"navegando a  : %v indice %d \\n\", web_list[index], index)\n\n\t\t}\n\t}\n}\n\nfunc printer() {\n\tprinterQ := []string{}\n\n\tfor {\n\t\top := \"\"\n\t\tfmt.Println(\"imprimir o salir :\")\n\t\tfmt.Scanln(&op)\n\t\tswitch op {\n\t\tcase \"imprimir\":\n\t\t\tfmt.Println(\" IMprimiendo :\", printerQ[0])\n\t\t\tprinterQ = append(printerQ[1:])\n\t\t\tfmt.Println(\" Tareas a imprimir :\", printerQ)\n\t\tcase \"salir\":\n\t\t\treturn\n\t\tdefault:\n\t\t\tprinterQ = append(printerQ, op)\n\t\t\tfmt.Println(\" Tareas a imprimir :\", printerQ)\n\n\t\t}\n\n\t}\n\n}\n\nfunc extra() {\n\tTOR()\n\tprinter()\n}\n\nfunc main() {\n\tex1()\n\textra()\n\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/go/thegera4.go",
    "content": "package main\n\nimport \"fmt\"\n\n// Estructura de pila de números (LIFO)\ntype StringStack struct {\n\tdata []string\n}\n\n// Saber si la pila está vacía\nfunc (stack *StringStack) IsEmpty() bool {\n\treturn len(stack.data) == 0\n}\n\n// Agrega un número a la pila\nfunc (stack *StringStack) Push(element string) {\n\tstack.data = append(stack.data, element)\n}\n\n// Elimina y recupoera/devuelve el último número agregado a la pila. Regresa false si la pila está vacía\nfunc (stack *StringStack) Pop() (string, bool) {\n\tif stack.IsEmpty() {\n\t\treturn \"\", false\n\t} else {\n\t\tindex := len(stack.data) - 1 // Indice del último elemento\n\t\telement := stack.data[index]  // Último elemento\n\t\tstack.data = stack.data[:index] // Elimina el último elemento por su indice\n\t\treturn element, true\n\t}\n}\n\n// Estrucutra de cola de números (FIFO)\ntype StringsQueue struct {\n\tdata []string\n}\n\n// Saber si la cola está vacía\nfunc (queue *StringsQueue) IsEmpty() bool {\n\treturn len(queue.data) == 0\n}\n\n// Agrega un número a la cola\nfunc (queue *StringsQueue) Enqueue(element string) {\n\tqueue.data = append(queue.data, element)\n}\n\n// Elimina y recupera/devuelve el primer número agregado a la cola. Regresa false si la cola está vacía\nfunc (queue *StringsQueue) Dequeue() (string, bool) {\n\tif queue.IsEmpty() {\n\t\treturn \"\", false\n\t} else {\n\t\telement := queue.data[0] // Accedemos al Primer elemento\n\t\tqueue.data = queue.data[1:] // Elimina el primer elemento\n\t\treturn element, true\n\t}\n}\n\nfunc main () {\n\n\t// Ejemplos de Stack\n\tstack := StringStack{}\n\tfmt.Println(\"Pila vacía: \", stack.IsEmpty())\n\tstack.Push(\"1\")\n\tstack.Push(\"2\")\n\tstack.Push(\"3\")\n\tfmt.Println(\"Pila:\" + fmt.Sprint(stack.data))\n\tfmt.Println(\"Ahora se eliminara el ultimo elemento de la pila...\")\n\tstack.Pop()\n\tfmt.Println(\"Pila:\" + fmt.Sprint(stack.data))\n\t\n\t// Ejemplos de Queue\n\tqueue := StringsQueue{}\n\tfmt.Println(\"Cola vacía: \", queue.IsEmpty())\n\tqueue.Enqueue(\"1\")\n\tqueue.Enqueue(\"2\")\n\tqueue.Enqueue(\"3\")\n\tfmt.Println(\"Cola:\" + fmt.Sprint(queue.data))\n\tfmt.Println(\"Ahora se eliminara el primer elemento de la cola...\")\n\tqueue.Dequeue()\n\tfmt.Println(\"Cola:\" + fmt.Sprint(queue.data))\n\n\t// Extra\n\tmenu()\n}\n\n// Funcion auxiliar para mostrar un menu de opciones y elegir entre salir, el navegador web o la impresora compartida\nfunc menu() {\n\tfor {\n\t\tvar input int\n\t\tfmt.Println(\"Bienvenido a las funcinalidades extra. Por favor, elige una opción:\")\n\t\tfmt.Println(\"1. Navegador Web\")\n\t\tfmt.Println(\"2. Impresora Compartida\")\n\t\tfmt.Println(\"3. Salir\")\n\t\tfmt.Scanln(&input)\n\t\tswitch input {\n\t\t\tcase 1:\n\t\t\t\twebBrowser()\n\t\t\tcase 2:\n\t\t\t\tsharedPrinter()\n\t\t\tcase 3:\n\t\t\t\treturn\n\t\t\tdefault:\n\t\t\t\tfmt.Println(\"Opción no válida\")\n\t\t}\n\t}\n}\n\n// Simula el mecanismo adelante/atrás de un navegador web\nfunc webBrowser() {\n\thistory := StringStack{}\n\tforward := StringStack{}\n\tcurrent := \"google.com\"\n\tfmt.Println(\"Bienvenido a: \" + current)\n\tfor {\n\t\tvar input string\n\t\tfmt.Println(\"Ingresa una página web o 'atras' o 'adelante' para navegar o 'salir' para cerrar la aplicacion:\")\n\t\tfmt.Scanln(&input)\n\t\tif input == \"\" {\n\t\t\tfmt.Println(\"Pagina no valida\")\n\t\t\tcontinue\n\t\t}\n\t\tswitch input {\n\t\t\tcase \"salir\":\n\t\t\t\treturn\n\t\t\tcase \"atras\":\n\t\t\t\tif page, ok := history.Pop(); ok { \n\t\t\t\t\tforward.Push(current)\n\t\t\t\t\tcurrent = page\n\t\t\t\t\tfmt.Println(\"Ahora estás en: \" + current)\n\t\t\t\t} else {\n\t\t\t\t\tfmt.Println(\"No hay páginas anteriores\")\n\t\t\t\t}\n\t\t\tcase \"adelante\":\n\t\t\t\tif page, ok := forward.Pop(); ok {\n\t\t\t\t\thistory.Push(current)\n\t\t\t\t\tcurrent = page\n\t\t\t\t\tfmt.Println(\"Ahora estás en: \" + current)\n\t\t\t\t} else {\n\t\t\t\t\tfmt.Println(\"No hay páginas siguientes\")\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\thistory.Push(current)\n\t\t\t\tcurrent = input\n\t\t\t\tfmt.Println(\"Ahora estás en: \" + current)\n\t\t\t}\n\t}\n}\n\n// Simula el mecanismo de una impresora compartida que recibe documentos y los imprime cuando así se le indica\nfunc sharedPrinter() {\n\tqueue := StringsQueue{}\n\tfor {\n\t\tvar input string\n\t\tfmt.Println(\"Ingresa un nombre de documento, 'mostrar' para ver la cola de impresion, 'imprimir' para imprimir un documento en la fila o 'salir' para cerrar la aplicacion:\")\n\t\tfmt.Scanln(&input)\n\t\tif input == \"\" {\n\t\t\tfmt.Println(\"Instruccion no valida\")\n\t\t\tcontinue\n\t\t} else if input == \"salir\" {\n\t\t\treturn\n\t\t} else if input == \"imprimir\" {\n\t\t\tif doc, ok := queue.Dequeue(); ok {\n\t\t\t\tfmt.Println(\"Imprimiendo: \" + doc)\n\t\t\t} else {\n\t\t\t\tfmt.Println(\"No hay documentos para imprimir\")\n\t\t\t}\n\t\t} else if input == \"mostrar\" {\n\t\t\tfmt.Println(\"Documentos en la cola: \" + fmt.Sprint(queue.data))\n\t\t} else {\n\t\t\tqueue.Enqueue(input)\n\t\t\tfmt.Println(\"Documento agregado a la cola\")\n\t\t}\n\t}\n}"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/java/AbelADE.java",
    "content": "public class Main {\n\n    /*Pila*/\n    public static ArrayList<Integer> stack = new ArrayList<>();\n\n    public static void showStack() {\n        System.out.println(\"Stack:\");\n        String space = \", \";\n        for (int i = 0; i < stack.size(); i++) {\n            System.out.print(stack.get(i) + space);\n            if (i == stack.size() - 2) {\n                space = \"\\n\";\n            }\n        }\n        System.out.println();\n    }\n\n    public static void push(int number) {\n        stack.add(number);\n    }\n\n    public static int pop() {\n        int number = stack.get(stack.size() - 1);\n        stack.remove(stack.size() - 1);\n        return number;\n    }\n\n    /*Cola*/\n    public static ArrayList<Integer> queue = new ArrayList<>();\n\n    public static void showQueue() {\n        System.out.println(\"Queue:\");\n        String space = \", \";\n        for (int i = 0; i < queue.size(); i++) {\n            System.out.print(queue.get(i) + space);\n            if (i == queue.size() - 2) {\n                space = \"\\n\";\n            }\n        }\n        System.out.println();\n    }\n\n    public static void enqueue(int number) {\n        queue.add(number);\n    }\n\n    public static int dequeue() {\n        int number = queue.get(0);\n        queue.remove(0);\n        return number;\n    }\n\n    public static void webBrowser(){\n        boolean exit = false;\n        ArrayList<String> stackBrowser = new ArrayList<>();\n        do {\n            Scanner scanner = new Scanner(System.in);\n            System.out.println(\"Bienvenido al navegador web: \");\n            System.out.println(\"'adelante' - Para moverse adelante\");\n            System.out.println(\"'atrás' - Para moverse atrás\");\n            System.out.println(\"'salir' - Para salir del navegador\");\n            System.out.println(\"'URL' - Para cambiar de página\" + \"\\n\");\n\n            System.out.print(\"Introduce el texto: \");\n\n            String option = scanner.nextLine();\n\n            switch (option) {\n                case \"adelante\":\n                    break;\n                case \"atrás\":\n                    if (stackBrowser.size() > 1) {\n                        stackBrowser.remove(stackBrowser.size() - 1);\n                    }\n                    break;\n                case \"salir\":\n                    exit = true;\n                    break;\n                default:\n                    stackBrowser.add(option);\n            }\n            if (stackBrowser.size() > 1) {\n                System.out.println(\"Web actual: \" + stackBrowser.get(stackBrowser.size() - 1));\n            }else{\n                System.out.println(\"Página de inicio\");\n            }\n\n        } while (!exit);\n    }\n\n    public static void printer(){\n        boolean exit = false;\n        ArrayList<String> queuePrinter = new ArrayList<>();\n        do{\n            Scanner scanner = new Scanner(System.in);\n            System.out.println(\"Bienvenido a la impresora: \");\n            System.out.println(\"'imprimir' - Para imprimir un documento\");\n            System.out.println(\"'salir' - Para salir\");\n            System.out.println(\"'documento' - Para añadir un documento a la cola de impresión\"+ \"\\n\");\n\n            String option = scanner.nextLine();\n\n            switch (option) {\n                case \"imprimir\":\n                    if (queuePrinter.size() >= 1) {\n                        System.out.println(\"Imprimiendo documento: \" + queuePrinter.get(0) + \"\\n\");\n                        queuePrinter.remove(0);\n                    }else {\n                        System.out.println(\"No hay documentos para imprimir\" + \"\\n\");\n                    }\n                    break;\n                case \"salir\":\n                    exit = true;\n                    break;\n                default:\n                    queuePrinter.add(option);\n            }\n\n        }while (!exit);\n    }\n\n\n    public static void main(String[] args) {\n        /*Pila*/\n\n        //Añadimos contenido a la pila\n        push(0);\n        push(1);\n        push(2);\n        push(3);\n        push(4);\n        push(5);\n\n        //Mostramos el contenido de la pila\n        showStack();\n\n        //Desapilamos un elemento\n        System.out.println(\"Elemento retirado: \" + pop() + \"\\n\");\n\n        //Mostramos el contenido de la pila\n        showStack();\n\n        //Desapilamos un elemento\n        System.out.println(\"Elemento retirado: \" + pop() + \"\\n\");\n\n        //Mostramos el contenido de la pila\n        showStack();\n\n        System.out.println(\"---------------------------\");\n\n        /*Cola*/\n\n        //Añadimos elementos a la cola\n        enqueue(0);\n        enqueue(1);\n        enqueue(2);\n        enqueue(3);\n        enqueue(4);\n        enqueue(5);\n\n        //Mostramos el contenido de la cola\n        showQueue();\n\n        //Desencolamos un elemento\n        System.out.println(\"Elemento retirado: \" + dequeue() + \"\\n\");\n\n        //Mostramos el contenido de la cola\n        showQueue();\n\n        //Desencolamos un elemento\n        System.out.println(\"Elemento retirado: \" + dequeue() + \"\\n\");\n\n        //Mostramos el contenido de la cola\n        showQueue();\n\n        /*Dificultad Extra*/\n\n        //Navegador web\n        webBrowser();\n\n        //Impresora\n        printer();\n    }\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/java/AmadorQuispe.java",
    "content": "import java.util.ArrayDeque;\nimport java.util.LinkedList;\nimport java.util.Queue;\nimport java.util.Scanner;\nimport java.util.Stack;\n\npublic class AmadorQuispe {\n    public static void main(String[] args) {\n        example();\n        stackNavigation();\n        queuePrint();\n    }\n\n    public static void stackNavigation() {\n        Stack<String> history = new Stack<>();\n        Scanner sc = new Scanner(System.in);\n        int pointerIndex = 1;\n        while (true) {\n            if (!history.isEmpty()) {\n                System.out.println(\"-\".repeat(15));\n                history.forEach(h -> System.out.printf(\"%s | \", h));\n                System.out.println(\"\\n\" + \"-\".repeat(16));\n                System.out.print(\n                        \"Digite la 'pagina' o  'forward' para ir adelante, 'backward' para ir atras o 'exit' para cerrar :\");\n            } else {\n                System.out.println(\"Digita la pagina a visitar\");\n            }\n            String command = sc.next();\n            switch (command) {\n                case \"forward\":\n                    if (pointerIndex == 1) {\n                        System.out.println(\"No hay mas historial hacia adelante\\n\\n\");\n                        break;\n                    }\n                    pointerIndex--;\n                    String pageName = history.get(history.size() - pointerIndex);\n                    System.out.printf(\"Visualizando la pagina %s \\n\\n\\n\\n\", pageName + pointerIndex);\n                    break;\n                case \"backward\":\n                    if (pointerIndex == history.size()) {\n                        System.out.println(\"No hay mas historial hacia atras \\n\\n\");\n                        break;\n                    }\n                    pointerIndex++;\n                    pageName = history.get(history.size() - pointerIndex);\n                    System.out.printf(\"Visualizando la pagina %s \\n\\n\\n\\n\", pageName + pointerIndex);\n                    break;\n                case \"exit\":\n                    System.out.println(\"Saliendo del navegador\");\n                    sc.close();\n                    System.exit(0);\n                default:\n                    pointerIndex = 1;\n                    System.out.printf(\"Visualizando la pagina %s \\n\\n\\n\\n\", command);\n                    history.push(command);\n                    break;\n            }\n\n        }\n    }\n\n    public static void queuePrint() {\n        Queue<String> jobPrints = new LinkedList<>();\n        Scanner sc = new Scanner(System.in);\n        System.out.println(\"Ingresa el comando 'enqueue' para agregar archivo a cola de impresión\");\n        System.out.println(\"Ingresa el comando 'print' para empezar a imprimir un documento de la cola\");\n        System.out.println(\n                \"Ingresa el comando 'print-all' para empezar a imprimir todos los documentos de la cola\");\n        System.out.println(\"Ingresa el comando 'show' para mostrar todos los documentos de la cola\");\n        System.out.println(\"*\".repeat(20));\n        while (true) {\n            System.out.print(\"Ingresa tu comando :\");\n            String command = sc.next();\n            switch (command) {\n                case \"show\":\n                    System.out.println(\"-\".repeat(30));\n                    System.out.println(String.format(\"Documentos en cola (%d)\", jobPrints.size()));\n                    for (String string : jobPrints) {\n                        System.out.println(\"-> \" + string);\n                    }\n                    break;\n                case \"enqueue\":\n                    System.out.println(\"-\".repeat(30));\n                    System.out.print(\"Ingresa el nombre del documento a encolar :\");\n                    String docs = sc.next();\n                    jobPrints.add(docs);\n                    break;\n                case \"print\":\n                    System.out.println(\"-\".repeat(30));\n                    if (jobPrints.isEmpty()) {\n                        System.out.println(\"No hay nada para imprimir\");\n                        break;\n                    }\n                    System.out.println(\"Imprimiendo -> \" + jobPrints.poll());\n                    try {\n                        Thread.sleep(3000);\n                    } catch (InterruptedException e) {\n                        e.printStackTrace();\n                    }\n                    break;\n                case \"print-all\":\n                    System.out.println(\"-\".repeat(30));\n                    System.out.println(\"imprimiendo todo los de la cola\");\n                    while (!jobPrints.isEmpty()) {\n                        System.out.println(\"Imprimiendo -> \" + jobPrints.poll());\n                        try {\n                            Thread.sleep(3000);\n                        } catch (InterruptedException e) {\n                            e.printStackTrace(System.out);\n                        }\n                    }\n                    break;\n                case \"exit\":\n                    System.out.println(\"Apagando impresora\");\n                    System.exit(0);\n                    sc.close();\n                    break;\n                default:\n                    System.out.println(\"!\".repeat(30));\n                    System.out.println(\"comando no reconocido\");\n                    break;\n            }\n        }\n\n    }\n\n    public static void example() {\n        // Pilas con la clase Stack\n        // Crear una pila de libros\n        Stack<String> books = new Stack<>();\n        // Agregando elementos a la pila\n        books.push(\"Book 1\");\n        books.push(\"Book 2\");\n        books.push(\"Book 3\");\n        // Mostrando la pila\n        System.out.println(books);\n        // Ver el ultimo elemento\n        System.out.println(\"ultimo elemento: \" + books.peek());\n        // Eliminar el ultimo elemento\n        System.out.println(\"ultimo elemento eliminado: \" + books.pop());\n        // ver luego de eliminar\n        System.out.println(books);\n        // buscar elemento\n        System.out.println(\"ubicación de Book 1 respecto a la parte superior: \" + books.search(\"Book 1\"));\n\n        // Colas con la clase Dequeue\n        Queue<String> colas = new ArrayDeque<>();\n        colas.add(\"Amador\");\n        colas.add(\"Alex\");\n        colas.add(\"Pedro\");\n\n        System.out.println(colas);\n        // Eliminar el primer elimento\n        System.out.println(colas.poll());\n\n        System.out.println(colas);\n    }\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/java/AnaLauDB.java",
    "content": "import java.util.Scanner;\n\npublic class AnaLauDB {\n    public static void main(String[] args) {\n        // PILA (Stack - LIFO)\n        int[] pila = new int[5];\n        int tope = -1;\n\n        // Push\n        tope++;\n        pila[tope] = 10;\n        tope++;\n        pila[tope] = 20;\n        tope++;\n        pila[tope] = 30;\n\n        // Pop\n        System.out.println(\"Pila (LIFO):\");\n        while (tope >= 0) {\n            System.out.println(pila[tope]);\n            tope--;\n        }\n\n        // COLA\n        int[] cola = new int[5];\n        int inicio = 0, fin = 0;\n\n        // Enqueue\n        cola[fin++] = 100;\n        cola[fin++] = 200;\n        cola[fin++] = 300;\n\n        // Dequeue\n        System.out.println(\"\\nCola (FIFO):\");\n        while (inicio < fin) {\n            System.out.println(cola[inicio]);\n            inicio++;\n        }\n\n        // --- Simulación navegador web (pila de cadenas) ---\n        Scanner sc = new Scanner(System.in);\n        String[] historial = new String[10];\n        String[] adelante = new String[10];\n        int topeHist = -1, topeAdel = -1;\n        String paginaActual = null;\n\n        System.out.println(\n                \"\\nSimulación navegador web (escribe 'atrás', 'adelante' o nombre de web, 'salir' para terminar):\");\n        while (true) {\n            System.out.print(\"> \");\n            String entrada = sc.nextLine();\n            if (entrada.equalsIgnoreCase(\"salir\"))\n                break;\n\n            if (entrada.equalsIgnoreCase(\"atrás\")) {\n                if (topeHist >= 0) {\n                    if (paginaActual != null) {\n                        adelante[++topeAdel] = paginaActual;\n                    }\n                    paginaActual = historial[topeHist--];\n                    System.out.println(\"Página actual: \" + paginaActual);\n                } else {\n                    System.out.println(\"No hay páginas atrás.\");\n                }\n            } else if (entrada.equalsIgnoreCase(\"adelante\")) {\n                if (topeAdel >= 0) {\n                    historial[++topeHist] = paginaActual;\n                    paginaActual = adelante[topeAdel--];\n                    System.out.println(\"Página actual: \" + paginaActual);\n                } else {\n                    System.out.println(\"No hay páginas adelante.\");\n                }\n            } else {\n                if (paginaActual != null) {\n                    historial[++topeHist] = paginaActual;\n                    topeAdel = -1; // Se pierde el historial de adelante\n                }\n                paginaActual = entrada;\n                System.out.println(\"Página actual: \" + paginaActual);\n            }\n        }\n\n        // --- Simulación impresora compartida (cola de cadenas) ---\n        String[] colaDocs = new String[10];\n        int inicioDoc = 0, finDoc = 0;\n\n        System.out.println(\"\\nSimulación impresora (escribe nombre de documento o 'imprimir', 'salir' para terminar):\");\n        while (true) {\n            System.out.print(\"> \");\n            String entrada = sc.nextLine();\n            if (entrada.equalsIgnoreCase(\"salir\"))\n                break;\n\n            if (entrada.equalsIgnoreCase(\"imprimir\")) {\n                if (inicioDoc < finDoc) {\n                    System.out.println(\"Imprimiendo: \" + colaDocs[inicioDoc]);\n                    inicioDoc++;\n                } else {\n                    System.out.println(\"No hay documentos en cola.\");\n                }\n            } else {\n                if (finDoc < colaDocs.length) {\n                    colaDocs[finDoc++] = entrada;\n                    System.out.println(\"Documento añadido a la cola: \" + entrada);\n                } else {\n                    System.out.println(\"La cola está llena.\");\n                }\n            }\n        }\n        sc.close();\n    }\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/java/AndrewCodev.java",
    "content": "import java.util.*;\n\npublic class AndrewCodev {\n\n\tpublic static void main(String[] args) {\n\t\tScanner scanner = new Scanner(System.in);\n\t\t// EJEMPLO DE PILAS - STACKS estas siguen el principio LIFO (Last In, First Out)\n\t\tSystem.out.println(\"EJEMPLO DE PILAS - STACKS\");\n\t\tejemploPilas();\n\n\t\tSystem.out.println(\"\\nEJEMPLO DE COLAS - QUEUE\");\n\t\t// EJEMPLO DE COLAS - QUEUES sigue el principio FIFO (First In, First Out)\n\t\tejemploColas();\n\n\t\t// SELECCIONA UNO DE LOS EJERCICIO DE LA DIFICULTAD EXTRA\n\t\tmenuPrincipal(scanner);\n\t}\n\n\t// EJERCICIO DE EJEMPLO DE PILAS\n\tpublic static void ejemploPilas() {\n\t\tStack<Integer> stack = new Stack<>();\n\t\t// Añadir elementos (push)\n\t\tstack.push(1);\n\t\tstack.push(2);\n\t\tstack.push(3);\n\t\tstack.push(4);\n\t\tSystem.out.println(\"Pila después de push: \" + stack);\n\n\t\t// Remover el elemento superior (pop)\n\t\tint top = stack.pop();\n\t\tSystem.out.println(\"Elemento removido (pop): \" + top);\n\t\tSystem.out.println(\"Pila después de pop: \" + stack);\n\n\t\t// Ver el elemento superior (peek)\n\t\ttop = stack.peek();\n\t\tSystem.out.println(\"Elemento en la cima (peek): \" + top);\n\t\tSystem.out.println(\"Pila después de peek: \" + stack);\n\n\t\t// Comprobar si la pila está vacía\n\t\tboolean isEmpty = stack.isEmpty();\n\t\tSystem.out.println(\"¿La pila está vacía? \" + isEmpty);\n\t}\n\n\t// EJERCICIO DE EJEMPLO DE COLAS\n\tpublic static void ejemploColas() {\n\t\tQueue<Integer> queue = new LinkedList<>();\n\n\t\t// Añadir elementos (add)\n\t\tqueue.add(1);\n\t\tqueue.add(2);\n\t\tqueue.add(3);\n\t\tqueue.add(4);\n\t\tSystem.out.println(\"Cola después de add: \" + queue);\n\n\t\t// Remover el primer elemento (remove)\n\t\tint first = queue.remove();\n\t\tSystem.out.println(\"Elemento removido (remove): \" + first);\n\t\tSystem.out.println(\"Cola después de remove: \" + queue);\n\n\t\t// Ver el primer elemento (peek)\n\t\tfirst = queue.peek();\n\t\tSystem.out.println(\"Primer elemento (peek): \" + first);\n\t\tSystem.out.println(\"Cola después de peek: \" + queue);\n\n\t\t// Comprobar si la cola está vacía\n\t\tboolean isEmpty = queue.isEmpty();\n\t\tSystem.out.println(\"¿La cola está vacía? \" + isEmpty);\n\t}\n\n\t// DIFICULTAD EXTRA\n\t// EJERCICIO DIFICULTAD EXTRA\n\n\t// DEPURANDO\n\t// Se crea un menú principal para escoges el proyecto a correr Navegador o\n\t// Impresora\n\tpublic static void menuPrincipal(Scanner scanner) {\n\t\tQueue<String> impresora = new LinkedList<>();\n\t\tStack<Integer> pagina = new Stack<>();\n\n\t\tSystem.out.println(\"____________________________________________________\");\n\t\tSystem.out.println(\"\\nMENÚ PRINCIPAL\");\n\t\tSystem.out.println(\"Escriba (1) - NAVEGADOR WEB\\nEscriba (2) - IMPRESORA\\nEscribe (3) - FINALIZAR PROGRAMA\");\n\t\tString navegacion = scanner.nextLine();\n\n\t\tswitch (navegacion) {\n\t\tcase \"1\": {\n\t\t\t// EJERCICIO DIFICULTAD EXTRA NAVEGADOR WEB\n\t\t\tnavegadorWeb(pagina,scanner);\n\t\t}\n\t\tcase \"2\": {\n\t\t\t// EJERCICIO DIFICULTAD EXTRA IMPRESORA\n\t\t\tdpImpre(impresora, scanner);\n\t\t}\n\t\tcase \"3\": {\n\t\t\tfinProceso();\n\t\t}\n\t\tdefault:\n\t\t\tSystem.err.println(\"Selección no valida\");\n\t\t\tmenuPrincipal(scanner);\n\t\t}\n\t}\n\n\tpublic static void navegadorWeb(Stack<Integer> pagina, Scanner scanner) {\n\t\tString navegacion = \"\";\n\t\tSystem.out.println(\"____________________________________________________\");\n\t\tif (pagina.isEmpty()) {\n\t\t\tpagina.push(1);\n\t\t\tSystem.out.println(\"Estás en el Home página \" + pagina.peek());\n\t\t\tSystem.out.println(\"Escribe (ADELANTAR)\" + \"\\nEscribe (ATRAS)\" + \"\\nEscribe (CERRAR para ir al menú principal)\");\n\t\t\tSystem.out.println(\"____________________________________________________\");\n\t\t}\n\t\tnavegacion = scanner.nextLine();\n\t\tnavegadorWeb(adelanteAtras(pagina, navegacion.toLowerCase(),scanner),scanner);\n\n\t}\n\n\tpublic static Stack<Integer> adelanteAtras(Stack<Integer> pagina, String navegacion, Scanner scanner) {\n\t\tswitch (navegacion) {\n\t\tcase \"adelantar\": {\n\t\t\tpagina.push(pagina.peek() + 1);\n\t\t\tSystem.out.println(\"Estás en lo página \" + pagina.peek());\n\t\t\treturn pagina;\n\t\t}\n\t\tcase \"atras\": {\n\t\t\tpagina.pop();\n\t\t\tif (pagina.isEmpty()) {\n\t\t\t\tSystem.out.println(\"Redireccionado al Home\");\n\t\t\t} else {\n\t\t\t\tSystem.out.println(\"Estás en lo página \" + pagina.peek());\n\t\t\t}\n\t\t\treturn pagina;\n\t\t}\n\t\tcase \"cerrar\": {\n\t\t\tSystem.out.println(\"Navegador cerrado\");\n\t\t\tpagina.clear();\n\t\t\tmenuPrincipal(scanner);\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t\tSystem.err.println(\"La opción no es valida\");\n\t\t\treturn pagina;\n\t\t}\n\t\treturn pagina;\n\t}\n\t\n\t// EJERCICIO DE IMPRESORA\n\t// Se crea el menú para el programa de impresora\n\n\tpublic static void dpImpre(Queue<String> impresora, Scanner scanner) {\n\t\tString opcion = \"\";\n\t\tSystem.out.println(\"____________________________________________________\");\n\n\t\tif (impresora.isEmpty()) {\n\t\t\tSystem.out.println(\"\\nEscribe (1) - ABRIR MENÚ DE LA IMPRESORA\");\n\t\t\tSystem.out.println(\"Escribe (2) - MENÚ PRINCIPAL\");\n\t\t\tSystem.out.println(\"Escribe (3) - FINALIZAR PROGRAMA\");\n\t\t\topcion = scanner.nextLine();\n\t\t\tswitch (opcion) {\n\t\t\tcase \"1\": {\n\t\t\t\tmenuImpresora(impresora, scanner);\n\t\t\t}\n\t\t\tcase \"2\": {\n\t\t\t\tmenuPrincipal(scanner);\n\n\t\t\t}\n\t\t\tcase \"3\": {\n\t\t\t\tfinProceso();\n\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tSystem.err.println(\"La opción no es valida\");\n\t\t\t\tdpImpre(impresora, scanner);\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic static void menuImpresora(Queue<String> impresora, Scanner scanner) {\n\t\tString opcion = \"\";\n\t\tSystem.out.println(\"\\nLa impresora no tiene archivos para imprimir\");\n\t\tSystem.out.println(\"Escribe (1) - AGREGA UN NUEVO ARCHIVO\");\n\t\tSystem.out.println(\"Escribe (2) - IMPRIMIR ARCHIVO\");\n\t\tSystem.out.println(\"Escribe (3) - IMPRIMIR TODO\");\n\t\tSystem.out.println(\"Escribe (4) - REMOVER ARCHIVO\");\n\t\tSystem.out.println(\"Escribe (5) - REMOVER TODO\");\n\t\tSystem.out.println(\"\\nEscribe (6) - MENÚ PRINCIPAL\");\n\t\tSystem.out.println(\"Escribe (7) - FINALIZAR PROGRAMA\");\n\n\t\topcion = scanner.nextLine();\n\t\tswitch (opcion) {\n\t\tcase \"1\": {\n\t\t\tSystem.out.println(\"Escribe el nombre del archivo\");\n\t\t\timpresora.add(scanner.nextLine());\n\t\t\tSystem.out.println(impresora);\n\t\t\tmenuImpresora(impresora, scanner);\n\t\t}\n\t\tcase \"2\": {\n\t\t\tif (!impresora.isEmpty()) {\n\t\t\t\tSystem.out.println(\"El archivo: (\" + impresora.peek() + \") fue impreso con éxito\");\n\t\t\t\timpresora.remove();\n\t\t\t\tSystem.out.println(\"Pendientes: \"+impresora);\n\t\t\t}\t\t\t\n\t\t\tmenuImpresora(impresora, scanner);\n\t\t}\n\t\tcase \"3\": {\n\t\t\tif (!impresora.isEmpty()) {\n\t\t\t\tSystem.out.println(\"Los archivos: (\" + impresora + \") fueron impresos con éxito\");\n\t\t\t\timpresora.clear();\n\t\t\t}\n\t\t\tmenuImpresora(impresora, scanner);\n\t\t}\n\n\t\tcase \"4\": {\n\t\t\tif (!impresora.isEmpty()) {\n\t\t\t\tSystem.err.println(\"El archivo: (\" + impresora.peek() + \") fue ELIMINADO con éxito\");\n\t\t\t\timpresora.remove();\n\t\t\t\tSystem.out.println(\"Pendientes: \"+impresora);\n\t\t\t}\n\t\t\tmenuImpresora(impresora, scanner);\n\t\t}\n\n\t\tcase \"5\": {\n\t\t\tif (!impresora.isEmpty()) {\n\t\t\t\tSystem.err.println(\"Los archivos: (\" + impresora + \") fueron ELIMINADOS con éxito\");\n\t\t\t\timpresora.clear();\n\t\t\t}\n\t\t\tmenuImpresora(impresora, scanner);\n\t\t}case \"6\": {\n\t\t\tmenuPrincipal(scanner);\n\t\t}\n\t\tcase \"7\": {\n\t\t\tfinProceso();\n\t\t}\n\t\tdefault:\n\t\t\tSystem.err.println(\"La opción no es valida\");\n\t\t\tmenuImpresora(impresora, scanner);\n\t\t}\n\t}\n\t\n\tpublic static void finProceso() {\n\t\tSystem.out.println(\"EJECUCIÓN FINALIZADA\");\n\t\tSystem.exit(0);\n\t}\n}"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/java/FranDev200.java",
    "content": "import java.util.ArrayList;\nimport java.util.Scanner;\n\npublic class FranDev200 {\n\n    static ArrayList<Integer> arrayStack = new ArrayList<>();\n    static ArrayList<Integer> arrayQueue = new ArrayList<>();\n\n    static void main() {\n\n        /*\n            Implementa los mecanismos de introducción y recuperación de elementos propios de las\n            pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n            o lista (dependiendo de las posibilidades de tu lenguaje).\n        */\n\n        // Añadimos elementos al Stack\n        for(int i = 0; i < 5; i++){\n            push(i);\n        }\n\n        // Añadimos elementos al Queue\n        for(int i = 0; i < 5; i++){\n            offer(i);\n        }\n\n        System.out.println(\"STACK\");\n        System.out.println(arrayStack);\n        System.out.println(\"--------------\");\n        System.out.println(\"- Eliminamos y mostramos el primer elemento: \" + pop());\n        System.out.println(\"==============================================\");\n        System.out.println(\"STACK\");\n        System.out.println(arrayStack);\n        System.out.println(\"--------------\");\n        System.out.println(\"- Eliminamos y mostramos el primer elemento: \" + pop());\n        System.out.println(\"==============================================\");\n        System.out.println(\"STACK\");\n        System.out.println(arrayStack);\n        System.out.println(\"--------------\");\n        System.out.println(\"- Mostramos el primer elemento: \" + peek());\n        System.out.println(\"==============================================\");\n        System.out.println(\"STACK\");\n        System.out.println(arrayStack);\n        System.out.println(\"--------------\");\n        System.out.println(\"- Esta vacio el stack: \" + empty());\n        System.out.println(\"- Numero de la posicion 3: \" + search(3));\n        System.out.println(\"- Numero de la posicion 5: \" + search(5));\n        System.out.println(\"=============================================\\n\\n\");\n        System.out.println(\"QUEUE\");\n        System.out.println(arrayQueue);\n        System.out.println(\"--------------\");\n        System.out.println(\"- Eliminamos y mostramos el primer elemento: \" + poll());\n        System.out.println(\"==============================================\");\n        System.out.println(\"QUEUE\");\n        System.out.println(arrayQueue);\n        System.out.println(\"--------------\");\n        System.out.println(\"- Eliminamos y mostramos el primer elemento: \" + poll());\n        System.out.println(\"==============================================\");\n        System.out.println(\"QUEUE\");\n        System.out.println(arrayQueue);\n        System.out.println(\"--------------\");\n        System.out.println(\"- Mostramos el primer elemento: \" + element());\n        System.out.println(\"==============================================\");\n        System.out.println(\"QUEUE\");\n        System.out.println(arrayQueue);\n        System.out.println(\"--------------\\n\\n\\n\\n\");\n\n/*\n        DIFICULTAD EXTRA (opcional):\n        * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n        *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n        *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n        *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n        *   el nombre de una nueva web.\n*/\n        Scanner scan = new Scanner(System.in);\n        ArrayList<String> arrayStackWeb = new ArrayList<>();\n        int endPointWeb = 1;\n        boolean exit = false;\n\n        System.out.println(\"==========================================\");\n        System.out.println(\"||     BIENVENIDO AL NAVEGADOR JAVA     ||\");\n        System.out.println(\"------------------------------------------\");\n        System.out.println(\"   Espero que su uso sea de su agrado.    \");\n        System.out.println(\"==========================================\");\n        System.out.println(\"\\nOpciones:\");\n        System.out.println(\"- - - - - - - - - - - - - - - - - - - - - -\");\n        System.out.println(\"- Navegar adelante --> Escribir \\\"adelante\\\".\");\n        System.out.println(\"- Navegar atras --> Escribir \\\"atras\\\".\");\n        System.out.println(\"- Para exit --> Escribir \\\"salir\\\".\");\n        System.out.println(\"- Navegar a una nueva pagina web --> Escribir \\\"nombre_de_la_web\\\".\");\n        System.out.println(\"===========================================\");\n\n        while(!exit){\n\n            System.out.print(\"Respuesta: \");\n\n            String respuesta = scan.next();\n\n            switch (respuesta){\n\n                case \"salir\":\n                    System.out.println(\"  ---  Saliendo del navegador  ---  \");\n                    exit = true;\n                    break;\n\n                case \"adelante\":\n\n                    if(endPointWeb == 1){\n                        System.out.println(\"No se puede ir más adelante.\");\n                        break;\n                    }\n\n                    endPointWeb--;\n                    System.out.println(\"Pagina actual: \" + arrayStackWeb.get(arrayStackWeb.size() - endPointWeb));\n                    break;\n\n                case \"atras\":\n\n                    if(endPointWeb == arrayStackWeb.size()){\n                        System.out.println(\"No se puede ir más atrás.\");\n                        break;\n                    }\n\n                    endPointWeb++;\n                    System.out.println(\"Pagina actual: \" + arrayStackWeb.get(arrayStackWeb.size() - endPointWeb));\n                    break;\n\n                default:\n                    arrayStackWeb.add(respuesta);\n                    endPointWeb = 1;\n                    System.out.println(\"Pagina actual: \" + arrayStackWeb.get(arrayStackWeb.size() - endPointWeb));\n                    break;\n            }\n\n        }\n\n/*\n        - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n        *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n        *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n        *   interpretan como nombres de documentos.\n*/\n\n        ArrayList<String> arrayQueueImpresora = new ArrayList<>();\n        exit = false;\n\n        System.out.println(\"\\n\\n\\n\\n============================================\");\n        System.out.println(\"||     BIENVENIDO A LA IMPRESORA JAVA     ||\");\n        System.out.println(\"--------------------------------------------\");\n        System.out.println(\"    Espero que su uso sea de su agrado.     \");\n        System.out.println(\"============================================\");\n        System.out.println(\"\\nOpciones:\");\n        System.out.println(\"- - - - - - - - - - - - - - - - - - - - - -\");\n        System.out.println(\"- Añadir documento --> Escribir \\\"nombre\\\".\");\n        System.out.println(\"- Imprimir documento --> Escribir \\\"imprimir\\\".\");\n        System.out.println(\"- Imprimir todos los documento --> Escribir \\\"imprimir_todo\\\".\");\n        System.out.println(\"- Ver los documentos en cola --> \\\"cola\\\"\");\n        System.out.println(\"- Para exit --> Escribir \\\"salir\\\".\");\n        System.out.println(\"===========================================\");\n\n        while (!exit){\n\n            System.out.print(\"Respuesta: \");\n            String respuesta = scan.next();\n\n            switch (respuesta){\n\n                case \"salir\":\n                    exit = true;\n                    System.out.println(\" --- Apagando impresora --- \");\n                    break;\n\n                case \"imprimir\":\n\n                    if(arrayQueueImpresora.isEmpty()){\n                        System.out.println(\"Primero añade un documento a la cola.\");\n                    }else{\n                        System.out.println(\"Imprimiendo \" + arrayQueueImpresora.getFirst());\n                        arrayQueueImpresora.removeFirst();\n                    }\n                    break;\n\n                case \"cola\":\n\n                    if(arrayQueueImpresora.isEmpty()){\n                        System.out.println(\"Primero añade un documento a la cola.\");\n                    }else{\n                        System.out.println(arrayQueueImpresora);\n                    }\n                    break;\n\n                case \"imprimir_todo\":\n\n                    if(arrayQueueImpresora.isEmpty()){\n                        System.out.println(\"Primero añade un documento a la cola.\");\n                    }else{\n                        for(String document: arrayQueueImpresora){\n                            System.out.println(\"Imprimiendo \" + document);\n                            arrayQueueImpresora.remove(document);\n                        }\n\n                    }\n                    break;\n\n                default:\n\n                    arrayQueueImpresora.addLast(respuesta);\n                    System.out.println(\"Documento añadido a la cola.\");\n                    break;\n\n            }\n\n        }\n\n    }\n\n\n\n    // METODOS PARA EL STACK\n    public static void push(int i){\n\n        arrayStack.addFirst(i);\n\n    }\n\n    public static int pop(){\n\n        int result =  arrayStack.getFirst();\n\n        if(!empty()){\n            arrayStack.removeFirst();\n            return result;\n\n        }else{\n            System.out.println(\"El stack esta vacio.\");\n            return 0;\n        }\n\n    }\n\n    public static Integer peek(){\n\n        if(!empty()){\n            return arrayStack.getFirst();\n        }else{\n            System.out.println(\"El array esta vacio.\");\n            return null;\n        }\n\n    }\n\n    public static boolean empty(){\n\n        return arrayStack.isEmpty();\n\n    }\n\n    public static int search(int position){\n\n        if(position > arrayStack.size()){\n            System.out.println(\"Esa posición excede el tamaño del stack.\");\n            return 0;\n        }\n\n        return arrayStack.get(position - 1);\n\n    }\n\n    // METODOS PARA LA QUEUE\n    public static boolean offer(int i){\n\n        arrayQueue.addLast(i);\n        return true;\n\n    }\n\n    public static Integer poll(){\n\n        int result =  arrayQueue.getFirst();\n\n        if(!empty()){\n            arrayQueue.removeFirst();\n            return result;\n\n        }else{\n            System.out.println(\"La cola esta vacio.\");\n            return null;\n        }\n\n    }\n\n    public static Integer element(){\n\n        if(!empty()){\n            return arrayStack.getFirst();\n        }else{\n            System.out.println(\"El array esta vacio.\");\n            return null;\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/java/Gerthai08.java",
    "content": "//TIP To <b>Run</b> code, press <shortcut actionId=\"Run\"/> or\n// click the <icon src=\"AllIcons.Actions.Execute\"/> icon in the gutter.\n/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n\nimport java.util.LinkedList;\nimport java.util.Queue;\nimport java.util.Scanner;\nimport java.util.Stack;\n\npublic class Main {\n    public static void main(String[] args) {\n\n        /*\n        //Pilas\n        Stack<String> myStack =  new Stack<String>();\n\n        //Método \"empty\" para saber si la pila está vacía\n        System.out.println(\"Is my stack empty? \" + myStack.empty());\n\n        //Método \"push\" para agregar elementos\n        myStack.push(\"Orange Ball\");\n        myStack.push(\"Violet Ball\");\n        myStack.push(\"Green Ball\");\n\n        //Imprimiendo elementos\n        //\"empty\" y \"isEmpty\" son lo mismo, solo que hay una diferencia histórica, ya que el\n        //Primero es propio de la clase Stack y el\n        //Segundo es propio de la clase collection (version más moderna)\n        System.out.println(\"Elements in stack: \" + myStack);\n        System.out.println(\"Is my stack empty? \" + myStack.empty());\n        while(!myStack.isEmpty()){\n            myStack.pop();\n            System.out.println(\"Elements in stack : \" + myStack);\n            System.out.println(\"Is my stack empty? \" + myStack.empty());\n        }\n\n        //Colas\n        Queue<String> myQueue = new LinkedList<>();\n\n        //Método add para agregar elementos\n        myQueue.add(\"ana\");\n        myQueue.add(\"Luis\");\n        myQueue.add(\"Marta\");\n\n        //Imprimir cola\n        System.out.println(\"Cola inicial\" + myQueue);\n\n        //consultamos quién está primero\n        System.out.println(\"Primero en la cola: \" + myQueue.peek());\n\n        //Mostramos en pantalla y eliminamos a la primér persona\n        System.out.println(\"Mostramos y eliminamos: \" + myQueue.poll());\n        System.out.println(\"Cola después de mostrar y eliminar: \" + myQueue);\n\n        //consultamos quién está primero\n        System.out.println(\"Primero en la cola: \" + myQueue.peek());\n\n        //Mostramos en pantalla y eliminamos a la primér persona\n        System.out.println(\"Mostramos y eliminamos: \" + myQueue.poll());\n        System.out.println(\"Cola después de mostrar y eliminar: \" + myQueue);\n\n        //consultamos quién está primero\n        System.out.println(\"Primero en la cola: \" + myQueue.peek());\n\n        //Mostramos en pantalla y eliminamos a la primér persona\n        System.out.println(\"Mostramos y eliminamos: \" + myQueue.poll());\n        System.out.println(\"Cola vacía: \" + myQueue);\n\n        //si intento atender con poll en cola vacía, devuelve null\n        System.out.println(\"Intentando atender mas: \" + myQueue.poll());\n        */\n\n        //dificultad extra\n        Scanner scanner = new Scanner(System.in);\n\n        Stack<String> backStack = new Stack<>();\n        Stack<String> fowardStack = new Stack<>();\n        String actual = \"Pagina de inicio\";\n\n        //Página inicial\n        System.out.println(\"Navegador iniciado en: \" + actual);\n\n        while (true){\n            System.out.println(\"\\nEscribe una página, \\\"atras\\\", \\\"adelante\\\" o \\\"salir\\\"\");\n            String comando = scanner.nextLine().trim();\n\n            if (comando.equalsIgnoreCase(\"salir\")){\n                System.out.println(\"Cerrando navegador...\");\n                break;\n            }else if(comando.equalsIgnoreCase(\"atrás\")){\n                if (!backStack.isEmpty()){\n                    fowardStack.push(actual);\n                    actual = backStack.pop();\n                }else{\n                    System.out.println(\"No hay páginas atrás.\");\n                }\n            } else if (comando.equalsIgnoreCase(\"adelante\")) {\n                if (!fowardStack.isEmpty()){\n                    backStack.push(actual);\n                    actual = fowardStack.pop();\n                }else{\n                    System.out.println(\"No hay páginas adelante.\");\n                }\n            }else{\n                //Navegar a una nueva pagina\n                backStack.push(actual);\n                actual = comando;\n                fowardStack.clear();\n            }\n\n            System.out.println(\"Esats en: \" + actual);\n        }\n        scanner.close();\n\n        //Impresora\n        Scanner sc = new Scanner(System.in);\n        Queue<String> colaImpresion = new LinkedList<>();\n\n        System.out.println(\"Impresora iniciada.\");\n        System.out.println(\"Escribe nombres de documentos o 'imprimir'. Escribe 'salir' para terminar.\");\n\n        while (true){\n            System.out.println(\"Escribe un comando: \");\n            String comando = sc.nextLine().trim();\n\n            if (comando.equalsIgnoreCase(\"salir\")){\n                System.out.println(\"Apagando impresora...\");\n                break;\n            }else if (comando.equalsIgnoreCase(\"imprimir\")){\n                if(!colaImpresion.isEmpty()){\n                    String doc = colaImpresion.poll();\n                    System.out.println(\"Imprimiendo: \" + doc);\n                }else {\n                    System.out.println(\"No hay documentos en la cola\");\n                }\n            } else {\n                colaImpresion.offer(comando);\n                System.out.println(\"Documento agregado: \" + comando);\n            }\n            System.out.println(\"Cola actual: \" + colaImpresion);\n        }\n        sc.close();\n    }\n}"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/java/GlossyPath.java",
    "content": "import java.util.Arrays;\nimport java.util.Collections;\nimport java.util.InputMismatchException;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.Queue;\nimport java.util.Scanner;\nimport java.util.Stack;\n\n/**\n * \n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n *  @version v1.0\n * \n *  @since 09/07/2024\n * \n * @author GlossyPath\n */\n\npublic class GlossyPath {\n\n    \n    public static void main(String[] args) {\n        \n        System.out.println(\"---------PILAS(STACK)--------\"); //Last In, First Out\n        Stack<String> frutas = new Stack<>();\n\n        frutas.push(\"melon\");\n        frutas.push(\"fresa\");\n        frutas.push(\"manzana\");\n\n        frutas.remove(0);\n\n        String elementoCima = frutas.pop();\n\n        System.out.println(frutas.peek());\n\n        frutas.set(0, \"Melon griego\");\n\n        frutas.stream().forEach(System.out::println);\n\n        System.out.println(frutas.peek());\n\n        Collections.sort(frutas); //ordenar los objetos\n\n        frutas.stream().forEach(System.out::println);\n\n        System.out.println(\"---------COLAS(QUEUE)---------\");//First In, First Out\n\n        List<String> nom = Arrays.asList(\"Laura\", \"Maria\", \"Paco\", \"Luis\");\n\n        Queue<String> nombres = new LinkedList<>();\n\n        nombres.addAll(nom);\n\n        nombres.add(\"Jose\");\n\n        System.out.println(\"La lista de nombres esta vacia? \" + nombres.isEmpty());\n\n        nombres.remove(\"Laura\");\n\n        while(!nombres.isEmpty()){\n           System.out.println(nombres.poll()); \n        }\n\n/**\n* DIFICULTAD EXTRA (opcional):\n* - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n*   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n*   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n*   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n*   el nombre de una nueva web.\n* - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n*   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n*   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n*   interpretan como nombres de documentos.\n*/\n\n        System.out.println(\"-------DIFICULTAD EXTRA----------\");\n\n        Scanner sc = new Scanner(System.in);\n        int opcion = -1;\n\n        do {\n            System.out.println(\"Escoge la opción que queires realizar(1,2,3): \" +\n            \"\\n1. Navegar por internet.\" +\n            \"\\n2. Impresora\" +\n            \"\\n3. Salir\");\n\n            try {\n                opcion = sc.nextInt();\n                sc.nextLine();\n\n                switch (opcion) {\n                    case 1:\n                        navegador(sc);\n                        break;\n\n                    case 2:\n                        impresora(sc);\n                        break;\n\n                    case 3:\n                        System.out.println(\"Saliendo...\");\n                        break;\n\n                    default:\n                        System.out.println(\"Opción no válida. Inténtalo de nuevo.\");\n                        break;\n                }\n\n            } catch (InputMismatchException e) {\n                System.out.println(\"Introduce una opción válida\");\n                sc.nextLine(); // Limpiar el buffer\n            }\n\n        } while (opcion != 3);\n\n        sc.close();\n        }\n\n        public static void navegador(Scanner sc) {\n\n        Navegador navegador = new Navegador();\n        String input;\n\n        do {\n            System.out.println(\"Introduce la acción que quieres realizar en el navegador (URL, adelante, atras o salir)\");\n\n            System.out.print(\"URL: \");\n            input = sc.nextLine();\n\n            if (input.equalsIgnoreCase(\"adelante\")) {\n                navegador.adelante();\n\n            } else if (input.equalsIgnoreCase(\"atras\")) {\n                navegador.atras();\n\n            } else if (!input.equalsIgnoreCase(\"salir\")) {\n                navegador.nuevaPagina(input);\n            }\n\n            navegador.mostrarEstado();\n\n        } while (!input.equalsIgnoreCase(\"salir\"));\n    }\n\n        static class Navegador {\n\n        private Stack<String> pilaAdelante;\n        private Stack<String> pilaAtras;\n        private String paginaActual;\n\n        public Navegador() {\n            pilaAdelante = new Stack<>();\n            pilaAtras = new Stack<>();\n            paginaActual = \"\";\n        }\n\n        public boolean hayPaginaDelante() {\n            return !pilaAdelante.isEmpty();\n        }\n\n        public boolean hayPaginaDetras() {\n            return !pilaAtras.isEmpty();\n        }\n\n        public void nuevaPagina(String url) {\n            if (!paginaActual.isEmpty()) {\n                pilaAtras.push(paginaActual);\n            }\n            paginaActual = url;\n            pilaAdelante.clear();\n            System.out.println(\"Navegando a: \" + url);\n        }\n\n        public void adelante() {\n            if (hayPaginaDelante()) {\n                pilaAtras.push(paginaActual);\n                paginaActual = pilaAdelante.pop();\n                System.out.println(\"Navegando a: \" + paginaActual);\n            } else {\n                System.out.println(\"No hay páginas adelante.\");\n            }\n        }\n\n        public void atras() {\n            if (hayPaginaDetras()) {\n                pilaAdelante.push(paginaActual);\n                paginaActual = pilaAtras.pop();\n                System.out.println(\"Navegando a: \" + paginaActual);\n            } else {\n                System.out.println(\"No hay páginas atrás.\");\n            }\n        }\n\n        public void mostrarEstado() {\n            System.out.println(\"Página actual: \" + paginaActual);\n            System.out.println(\"Páginas atrás: \" + pilaAtras);\n            System.out.println(\"Páginas adelante: \" + pilaAdelante);\n        }\n    }\n\n        public static void impresora (Scanner sc){\n\n            String accion;\n\n            Impresora impresora = new Impresora();\n\n            do{\n                System.out.println(\"Introduce la acción que quieres realizar en la impresora (Imprimir o salir)\");\n                accion = sc.nextLine();\n\n                if(accion.equalsIgnoreCase(\"Imprimir\")){\n                    impresora.imprimir();\n\n                } else if(!accion.equalsIgnoreCase(\"salir\")){\n                    impresora.añadirDocumento(accion);\n                }\n\n                impresora.mostrarTodo();\n\n            } while(!accion.equalsIgnoreCase(\"salir\"));\n        }\n\n        static class Impresora {\n            private Queue<String> colaImpresion;\n\n\n            public Impresora(){\n                colaImpresion = new LinkedList<>();\n            }\n\n\n            public void imprimir(){\n                if(hayDocumento()){\n                    String impresion = this.colaImpresion.remove();\n                    System.out.println(\"Imprimiendo: \" + impresion);\n                }\n            }\n\n\n            public boolean hayDocumento(){\n                return !colaImpresion.isEmpty();\n            }\n\n\n            public void añadirDocumento(String documento){\n                colaImpresion.add(documento);\n            }\n\n            public void mostrarTodo(){\n\n                System.out.println(\"Cola de impresion\");\n                for(String s: this.colaImpresion){\n                    System.out.println(s);\n                }\n\n\n                \n         }        \n    }\n}"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/java/GustavoGomez19.java",
    "content": "import java.util.ArrayDeque;\nimport java.util.ArrayList;\nimport java.util.Deque;\nimport java.util.LinkedList;\nimport java.util.Queue;\nimport java.util.Scanner;\n\npublic class GustavoGomez19{\n\n    public static void main(String[] args) {\n        /* Ejercicio: Implementa los mecanismos de introducción y recuperación propios de las\n         * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n         * o lista.\n         */\n\n         // Pilas (stack - LIFO)\n        Deque<Integer> pila = new ArrayDeque<>();\n\n        System.out.println(\"**** PILAS (STACK - LIFO) ****\");\n        // Intorducción de elemanto en una pila (stack)\n        pila.push(1);\n        pila.push(2);\n        pila.push(3);\n        System.out.println(\"Pila: \" + pila);\n        pila.addLast(4);\n        System.out.println(pila);\n        pila.addFirst(5);\n        System.out.println(pila);\n\n        // Recuperación de elemento en una pila (stack)\n        int elementoRecuperado = pila.poll();\n        System.out.println(\"Elemento recuperdado: \" + elementoRecuperado);\n        int elementoRecuperado2 = pila.peek();\n        System.out.println(\"Elemento recuperado 2: \" + elementoRecuperado2); // Permite ver el elemento en la parte superior de la fila sin eliminarlo\n        System.out.println(pila.reversed()); // Permite recuperar la pila en oreden invertido\n        System.out.println(pila.getLast()); // Permite recuperar el último elemento de la pila\n        System.out.println(pila);\n        System.out.println();\n\n        System.out.println(\"**** COLAS (QUEUE - FIFO) ****\");\n        // Colas (queue - FIFO)\n        Queue<Integer> cola = new LinkedList<>();\n\n        // Introducción de elementos \n        cola.add(1);\n        cola.add(4);\n        cola.add(2);\n        cola.add(3);\n        System.out.println(\"Cola: \" + cola);\n        \n        // Recuperación de elemento\n        System.out.println(\"Elemento recuperado: \" + cola.peek());\n        int elementoRecuperadoCola = cola.poll(); // Método poll recupera y elimina el elemento\n        System.out.println(\"Elemento recuperado: \" + elementoRecuperadoCola);\n        System.out.println(\"Cola: \" + cola);\n        System.out.println(cola.remove(5)); // Remueve la primer concidencia encontrada según el número especificado, devuelve true si lo borró o false si no los borró\n\n        /* DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos. */\n\n        // Simulación de navegador\n        System.out.println(\"*** NAVEGADOR ***\");\n        Deque<String> browser = new ArrayDeque<>();\n        Scanner sc = new Scanner(System.in);\n        String url = \"\";\n        while (!url.equals(\"salir\")) {\n            System.out.print(\"Dirección URL: \");\n            url = sc.nextLine();\n            switch (url) {\n                case \"atras\":\n                    if (browser.size() > 1) {\n                        browser.add(browser.poll());\n                        System.out.println(\"Regresando a la pagina anterior \" + browser.peek());\n                    } else {\n                        System.out.println(\"No existen más paginas para avanzar.\");\n                    }\n                    break;\n\n                case \"adelante\":\n                    if (browser.size() > 0) {\n                        browser.push(browser.poll());\n                        System.out.println(\"Usted se encuentra en la siguiente pagina \" + browser.peek());\n                    } else {\n                        System.out.println(\"No existen más paginas para avanzar.\");\n                    }\n                    break;\n\n                case \"salir\":\n                    System.out.println(\"Cerrando el navegador.....\");\n                    break;\n            \n                default:\n                    browser.push(url);\n                    System.out.println(\"Se visitó la pagina \" + browser.peek());\n                    break;\n            }\n        }\n        System.out.println();\n\n        // Simulación de impresora\n        System.out.println(\"*** FUNCIONAMIENTO DE IMPRESORA ***\");\n        Queue<String> impresora = new LinkedList<>();\n        String documento = \"\";\n\n        while (!documento.equals(\"salir\")) {\n            System.out.print(\"Ingrese el documento para imprimir: \");\n            documento = sc.nextLine();\n            if (!documento.equals(\"salir\")) {\n                switch (documento) {\n                    case \"imprimir\":\n                        if (impresora.size() > 0) {\n                            System.out.println(\"Se esta imprimiendo el documento...\" + impresora.poll());\n                        } else {\n                            System.out.println(\"No se tienen documentos para imprimir.\");\n                        }\n                        break;\n\n                    case \"salir\":\n                        System.out.println(\"Apagando impresora...\");\n                        break;\n                \n                    default:\n                        impresora.add(documento);\n                        System.out.println(\"Documento \" + documento + \" agregado a la cola de impresión.\");\n                        break;\n                }\n            }\n            \n        }\n\n\n\n\n    }\n\n    \n}"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/java/Jeigar2.java",
    "content": "import java.util.*;\n\npublic class Jeigar2 {\n    /*\n     * EJERCICIO:\n     * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n     * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n     * o lista (dependiendo de las posibilidades de tu lenguaje).\n     *\n     * DIFICULTAD EXTRA (opcional):\n     * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n     *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n     *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n     *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n     *   el nombre de una nueva web.\n     * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n     *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n     *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n     *   interpretan como nombres de documentos.\n     */\n    public static void main(String[] args) {\n        System.out.println(\"---pilas---\");\n        gestionPila();\n        System.out.println(\"OK\");\n        System.out.println(\"---colas---\");\n        gestionCola();\n        System.out.println(\"OK\");\n        int opcion = -1;\n        do {\n            Scanner scanner = new Scanner(System.in);\n            System.out.println(\"Qué acción quieres hacer\");\n            System.out.println(\"(1) Navegación por Internet\");\n            System.out.println(\"(2) Impresora\");\n            System.out.println(\"(0) Salir\");\n            try {\n                opcion = scanner.nextInt();\n                switch (opcion) {\n                    case 1: {\n                        navegar(scanner);\n                        break;\n                    }\n                    case 2: {\n                        imprimir(scanner);\n                        break;\n                    }\n                    case 0: {\n                        scanner.close();\n                        System.exit(0);\n                    }\n                }\n            }catch (InputMismatchException e) {\n                System.out.println(\"Introduce el número de tu opción, por favor\");\n                opcion = -1;\n            }\n        }while (true);\n    }\n\n    private static void imprimir(Scanner scanner){\n        Impresora impresora = Impresora.getInstance();\n        String opcion = null;\n        do {\n            opcion = scanner.nextLine();\n            System.out.println(\"Introduzca <acción> \" + Impresora.IMPRIMIR + \" o nombre del documento a imprimir\");\n            System.out.println(\"(0) Salir\");\n            if(!opcion.equals(\"0\")){\n                impresora.accion(opcion);\n            }\n        } while (!\"0\".equals(opcion));\n\n//        impresora.accion(\"La Biblia\");\n//        impresora.accion(\"Don Quijote de la Mancha\");\n//        impresora.accion(\"El juicio de Cristo\");\n//        impresora.accion(\"El milagro del padre Stu\");\n//        impresora.accion(Impresora.IMPRIMIR);\n    }\n\n    private static void navegar(Scanner scanner) {\n        int comando = -1;\n        Navegador navegador = new Navegador();\n        String pagina = null;\n        do {\n            do {\n                System.out.println(\"Navegador, que accion quieres hacer\");\n                System.out.println(\"(1) Url\");\n                if(navegador.existeSiguentePagina()) {\n                    System.out.println(\"(2) Adelante\");\n                }\n                if(navegador.existeSiguenteAnterior()) {\n                    System.out.println(\"(3) Atrás\");\n                }\n                System.out.println(\"(0) Salir\");\n                scanner = new Scanner(System.in);\n                try {\n                    comando = scanner.nextInt();\n                } catch (InputMismatchException e) {\n                    System.out.println(\"Introduce el número de tu opción, por favor\");\n                    comando = -1;\n                }\n            }while (!(comando >= 0 && comando <= 3));\n\n            switch (Navegador.Comando.values()[comando]){\n                case URL_PAGINA -> {\n                    do{\n                        pagina = scanner.nextLine();\n                        System.out.println(\"introducir URL: \");\n                    } while (pagina == null || pagina.isEmpty() || pagina.isBlank());\n                    navegador.nuevaPagina(pagina);\n                    System.out.println(\"Pagina: \" + pagina);\n                }\n                case ADELANTE -> System.out.println(\"Pagina: \" + navegador.adelante());\n                case ATRAS -> System.out.println(\"Pagina: \" + navegador.atras());\n                case SALIR -> {\n                    System.exit(0);}\n            }\n        }while(true);\n    }\n\n    private static void gestionPila (){\n        Stack<String> pila = new Stack<>();\n        List<String> nombres = Arrays.asList(\"Adriana\", \"Jesús\", \"André\", \"Almudena\");\n        nombres.stream().forEach(pila::push);\n\n        pila.stream().forEach(System.out::println);\n        do {\n            System.out.println(pila.pop());\n        }while (!pila.isEmpty());\n    }\n\n    private static void gestionCola (){\n        Queue<String> cola = new ArrayDeque<>();\n        List<String> nombres = Arrays.asList(\"Adriana\", \"Jesús\", \"André\", \"Almudena\");\n        nombres.stream().forEach(cola::add);\n\n        cola.stream().forEach(System.out::println);\n        do {\n            System.out.println(cola.remove());\n        }while (!cola.isEmpty());\n    }\n\n    /*\n     * DIFICULTAD EXTRA (opcional):\n     * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n     *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n     *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n     *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n     *   el nombre de una nueva web.\n     * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n     *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n     *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n     *   interpretan como nombres de documentos.\n     */\n}\n\nclass Navegador {\n    public enum Comando {\n        SALIR,\n        URL_PAGINA,\n        ADELANTE,\n        ATRAS;\n    }\n    public String HOME = \"Home\";\n\n    private Stack<String> pilaAvance;\n    private Stack<String> pilaRetroceso;\n    private String paginaActual;\n\n    public Navegador(){\n        pilaAvance = new Stack<>();\n        pilaRetroceso = new Stack<>();\n        paginaActual = HOME;\n    }\n\n    public boolean existeSiguentePagina(){\n        return !pilaAvance.isEmpty();\n    }\n    public boolean existeSiguenteAnterior(){\n        return !pilaRetroceso.isEmpty();\n    }\n\n    public void nuevaPagina(String pagina){\n        // vaciamos las páginas siguientes porque hay nueva navegación\n        while(!pilaAvance.isEmpty()) {\n            pilaAvance.pop();\n        }\n        pilaRetroceso.push(paginaActual);\n        paginaActual = pagina;\n    }\n\n    public String adelante(){\n        if(!pilaAvance.isEmpty()){\n            pilaRetroceso.push(paginaActual);\n            paginaActual = pilaAvance.pop();\n        }\n        return paginaActual;\n    }\n\n    public String atras(){\n        if(!pilaRetroceso.isEmpty()){\n            pilaAvance.push(paginaActual);\n            paginaActual = pilaRetroceso.pop();\n        }\n        return paginaActual;\n    }\n}\n\nclass Impresora {\n    public static final String IMPRIMIR = \"Imprimir\";\n    private static Impresora miImpresora;\n    private Queue<String> cola = new ArrayDeque<>();\n\n    private Impresora() {}\n\n    public static Impresora getInstance() {\n        if (miImpresora == null)\n            miImpresora = new Impresora();\n        return miImpresora;\n    }\n\n    public void accion(String documento) {\n        if (IMPRIMIR.equals(documento)){\n            cola.stream().forEach(doc -> System.out.println(cola.remove()));\n        } else {\n            cola.add(documento);\n        }\n\n        if(cola.isEmpty()){\n            System.out.println(\"\\n--- La cola de impresión está vacía ---\\n\");\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/java/JesusAntonioEEscamilla.java",
    "content": "import java.util.ArrayList;\nimport java.util.LinkedList;\nimport java.util.Scanner;\n\n/** #07 - Java -> Jesus Antonio Escamilla */\n\npublic class JesusAntonioEEscamilla {\n    public static void main(String[] args) {\n    //---EJERCIÓ---\n        // PILAS\n        System.out.println(\"PILAS - STACKS - LIFO\");\n        Stack__ stack = new Stack__();\n        stack.push(10);\n        stack.push(20);\n        stack.push(30);\n        System.out.println(\"Contenido de la Pila: \" + stack);\n        System.out.println(\"Elemento de parte superior de la Pila: \" + stack.peek());\n        System.out.println(\"Elemento eliminado de la Pila: \" + stack.pop());\n        System.out.println(\"Contenido de la Pila: \" + stack);\n\n        // COLAS\n        System.out.println(\"COLAS - QUEUE - FIFO\");\n        Queue__ queue = new Queue__();\n        queue.enqueue(40);\n        queue.enqueue(50);\n        queue.enqueue(60);\n        System.out.println(\"Contenido de la Cola: \" + queue);\n        System.out.println(\"Primer elemento de Cola: \" + queue.peek());\n        System.out.println(\"Elemento eliminado de la Cola: \" + queue.dequeue());\n        System.out.println(\"Contenido de la Cola: \" + queue);\n        //---EXTRA---\n        System.out.println(\"EXTRA - PILAS\");\n        SitioWeb();\n        System.out.println(\"EXTRA - COLAS\");\n        Impresora();\n    }\n\n    //---EJERCIÓ---\n    // STACKS - LIFO\n    static class Stack__{\n        private ArrayList<Integer> stack;\n\n        public Stack__(){\n            stack = new ArrayList<>();\n        }\n\n        // Se añade un elemento a la pila\n        public void push(int value){\n            stack.add(value);\n        }\n\n        public int pop(){\n            if (stack.isEmpty()) {\n                throw new IllegalAccessError(\"La pila esta vacía\");\n            }\n            return stack.remove(stack.size() - 1);\n        }\n\n        public int peek(){\n            if (stack.isEmpty()) {\n                throw new IllegalAccessError(\"La pila esta vacía\");\n            }\n            return stack.get(stack.size() - 1);\n        }\n\n        @Override\n        public String toString() {\n            return stack.toString();\n        }\n    }\n\n\n    // QUEUE - FIFO\n    static class Queue__{\n        private LinkedList<Integer> queue;\n\n        public Queue__(){\n            queue = new LinkedList<>();\n        }\n\n        // Se añade un elemento a la pila\n        public void enqueue(int value){\n            queue.addLast(value);\n        }\n\n        public int dequeue(){\n            if (queue.isEmpty()) {\n                throw new IllegalAccessError(\"La cola esta vacía\");\n            }\n            return queue.removeFirst();\n        }\n\n        public int peek(){\n            if (queue.isEmpty()) {\n                throw new IllegalAccessError(\"La pila esta vacía\");\n            }\n            return queue.getFirst();\n        }\n\n        @Override\n        public String toString() {\n            return queue.toString();\n        }\n    }\n\n\n\n    /**-----DIFICULTAD EXTRA-----*/\n\n    // PILAS\n    // Programa - Sitio Web\n    public static void SitioWeb(){\n        Browser browser = new Browser();\n        Scanner scanner = new Scanner(System.in);\n        String input;\n        \n        System.out.println(\"Simulación de Navegación web. Ingresa nombre de paginas web, adelante o atrás\");\n        while(true){\n            System.out.print(\"Ingrese un comando:\\n\");\n            input = scanner.nextLine();\n\n            if (input.equalsIgnoreCase(\"adelante\")){\n                browser.forward();\n            } else if (input.equalsIgnoreCase(\"atras\")){\n                browser.back();\n            } else if (input.equalsIgnoreCase(\"salir\")){\n                break;\n            } else {\n                browser.visit(input);\n            }\n\n            System.out.println(\"Pagina actual: \" + browser.current());\n        }\n        scanner.close();\n    }\n\n    static class Browser{\n        private Stack history;\n        private Stack forwardStack;\n        private String currentPage;\n\n        public Browser(){\n            history = new Stack();\n            forwardStack = new Stack();\n            currentPage = \"home\";\n        }\n\n        public void visit(String url){\n            if(currentPage != null){\n                history.push(currentPage);\n            }\n            currentPage = url;\n            forwardStack = new Stack();\n        }\n\n        public void back(){\n            if (!history.isEmpty()){\n                forwardStack.push(currentPage);\n                currentPage = history.pop();\n            } else {\n                System.out.println(\"No hay paginas anteriores\");\n            }\n        }\n\n        public void forward(){\n            if (!forwardStack.isEmpty()){\n                history.push(currentPage);\n                currentPage = forwardStack.pop();\n            } else {\n                System.out.println(\"No hay paginas siguientes\");\n            }\n        }\n\n        public String current(){\n            return currentPage;\n        }\n    }\n\n    static class Stack{\n        private ArrayList<String> stack;\n\n        public Stack() {\n            stack = new ArrayList<>();\n        }\n\n        public void push(String value) {\n            stack.add(value);\n        }\n\n        public String pop() {\n            if (isEmpty()) {\n                throw new IllegalStateException(\"La pila está vacía\");\n            }\n            return stack.remove(stack.size() - 1);\n        }\n\n        public boolean isEmpty() {\n            return stack.isEmpty();\n        }\n\n        @Override\n        public String toString() {\n            return stack.toString();\n        }\n    }\n\n\n    // COLAS\n    // Programa - Impresora\n    public static void Impresora(){\n        Printer printer = new Printer();\n        Scanner scanner = new Scanner(System.in);\n        String input;\n        \n        System.out.println(\"Simulación Compartida. Ingrese nombres de documentos o imprimir para imprimir\");\n        while(true){\n            System.out.print(\"Ingrese un comando:\\n\");\n            input = scanner.nextLine();\n\n            if (input.equalsIgnoreCase(\"imprimir\")){\n                printer.print();\n            } else if (input.equalsIgnoreCase(\"salir\")){\n                break;\n            } else {\n                printer.addDocument(input);\n            }\n        }\n        scanner.close();\n    }\n\n    static class Printer{\n        private Queue printerQueue;\n\n        public Printer() {\n            printerQueue = new Queue();\n        }\n\n        public void addDocument(String document){\n            printerQueue.enqueue(document);\n            System.out.println(\"Documento agregado a la cola: \" + document);\n        }\n\n        public void print(){\n            if(printerQueue.isEmpty()){\n                System.out.println(\"No hay documentos para imprimir\");\n            } else {\n                String document = printerQueue.dequeue();\n                System.out.println(\"Imprimiendo documento: \" + document);\n            }\n        }\n    }\n\n    static class Queue {\n        private LinkedList<String> queue;\n\n        public Queue() {\n            queue = new LinkedList<>();\n        }\n\n        public void enqueue(String value) {\n            queue.addLast(value);\n        }\n\n        public String dequeue() {\n            if (isEmpty()) {\n                throw new IllegalStateException(\"La cola está vacía\");\n            }\n            return queue.removeFirst();\n        }\n\n        public boolean isEmpty() {\n            return queue.isEmpty();\n        }\n\n        @Override\n        public String toString() {\n            return queue.toString();\n        }\n    }\n\n    /**-----DIFICULTAD EXTRA-----*/\n}"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/java/JimsimroDev.java",
    "content": "\n/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\nimport java.util.LinkedList;\nimport java.util.Scanner;\nimport java.util.Stack;\n\npublic class JimsimroDev {\n\n  private static final String DIV_LINE = \":::::::::::::\";\n  private Stack<Integer> miPila = new Stack<>();\n  private LinkedList<Integer> miCola = new LinkedList<>();\n\n  private void push(int elemento) {\n    miPila.push(elemento);\n  }\n\n  private void peek() {\n    if (!miPila.isEmpty()) {\n      System.out.println(\"•Elemento: \" + miPila.peek());\n    } else {\n      System.out.println(\"❌Pila Esta vacia\");\n    }\n  }\n\n  private void pop() {\n    if (!miPila.isEmpty()) {\n      miPila.pop();\n    } else {\n      System.out.println(\"Ya esta vacia\");\n    }\n  }\n\n  private void colas(Integer elemento) {\n    miCola.push(elemento);\n\n  }\n\n  private void colaPop(LinkedList<Integer> cola) {\n    if (!miCola.isEmpty()) {\n      miCola.remove(0);\n    } else {\n      System.out.println(\"Cola vacia\");\n    }\n  }\n\n  private void peekCola() {\n    System.out.print(\"Elemento en la cola \" + miCola);\n  }\n\n  private void agregarElementosPila(int cantidad) {\n    for (int i = 0; i < 6; i++) {// agrego 6 elemento en la pila de 0 a 5\n      push(i);\n      // Muestra la posicion actual de la pila\n      peek();\n    }\n  }\n\n  private void elimanarDeLaPila(int cantidad) {\n    // Elimina y Muestra la posicion actual antes y despues de elminar los elemento\n    for (int i = 0; i < 6; i++) {// elimino los 6 elemento en la pila de 0 a 5\n      // Muestra la posicion actual de la pila\n      peek();\n      // Elimina el ultimo elemento ingresado a la pila\n      pop();\n    }\n    peek();\n  }\n\n  private void agregarElementosCols(Integer cantidad) {\n    for (int i = 0; i < 4; i++) {\n      colas(i);\n    }\n    colaPop(miCola);\n    peekCola();\n  }\n\n  public static void main(String[] args) {\n    JimsimroDev pilas = new JimsimroDev();\n    JimsimroDev colas = new JimsimroDev();\n    // Las pilas(stacks - LIFO) Nos permite con push agregar elementos a la pila\n    // pop para eliminar y peek para saber en que posicion de la pila estamos\n    // solo esas opciones nos permita las pilas\n\n    // Pilas(stacks - LIFO)\n    System.out.println(DIV_LINE);\n    System.out.println(\"Agrega elemento a la pila\");\n    pilas.agregarElementosPila(6);\n\n    System.out.println(DIV_LINE);\n    System.out.println(\"Muestra y elimino posicion actual\");\n    pilas.elimanarDeLaPila(6);\n\n    // Cola\n    colas.agregarElementosCols(4);\n\n    System.out.println();\n    // EXTRA\n    System.out.println(DIV_LINE);\n    System.out.println(\"Pagina EXTRA\");\n    Scanner in = new Scanner(System.in);\n    String menu = \"\"\"\n        :::::::: MENU ::::::::\n        Digita la pagina web a visitar\n        Digita adelante\n        Digita atras\n        Digita Salir\n        \"\"\";\n    String apcion;\n\n    Stack<String> miPila = new Stack<>();\n\n    while (true) {\n      System.out.println(menu);\n      apcion = in.nextLine();\n\n      if (\"salir\".equals(apcion)) {\n        System.out.println(\"Cerrando la pagina web\");\n        in.close();\n        return;\n      } else if (\"atras\".equals(apcion) && !miPila.isEmpty()) {\n        miPila.pop();\n        if (!miPila.isEmpty()) {\n          System.out.println(\"Navegaste a la web \" + miPila.peek());\n        } else {\n          System.out.println(\"Estas en la pagina principal \");\n        }\n      } else if (\"adelante\".equals(apcion)) {\n        System.out.println(\"Esata opcon esta deshabilitada intenta con otra\");\n      } else {\n        miPila.push(apcion);\n        if (!miPila.isEmpty()) {\n          System.out.println(\"Navegaste a la web \" + miPila.peek());\n        } else {\n          System.out.println(\"Estas en la pagina principal \");\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/java/Josegs95.java",
    "content": "import java.util.*;\n\npublic class Josegs95 {\n    public static void main(String[] args) {\n        //Pilas. En java existe una clase que representa una pila, la clase Stack.\n        Stack<String> bag = new Stack<>();\n        bag.push(\"Bola roja\"); //Sirve para añadir un elemento al final de la pila\n        bag.push(\"Bola negra\");\n        bag.push(\"Bola azul\");\n        System.out.println(\"La pila: \" + bag); //Out: 'La pila: [Bola roja, Bola negra, Bola azul]'\n\n        bag.pop(); //Sirve para sacar el último elemento de la pila\n        System.out.println(\"La pila: \" + bag); //Out: 'La pila: [Bola roja, Bola negra]'\n\n            //Implementación de pila a través de un arrayList\n        List<String> stack = new ArrayList<>();\n        stack.add(\"Elemento 1\");\n        stack.add(\"Elemento 2\");\n        stack.add(\"Elemento 3\");\n        System.out.println(\"Mi stack: \" + stack); //Out: 'Mi stack: [Elemento 1, Elemento 2, Elemento 3]'\n\n        stack.remove(stack.size() - 1); //Borra y devuelve el último elemento, como si fuera una pila\n        System.out.println(\"Mi stack: \" + stack); //Out: 'Mi stack: [Elemento 1, Elemento 2]'\n\n        //Colas. En java existe una clase que representa una pila, la clase Queue.\n        Queue<String> processes = new LinkedList<>();\n        processes.offer(\"Process 1\"); //Añade un elemento\n        processes.offer(\"Process 2\");\n        processes.offer(\"Process 3\");\n        System.out.println(\"La cola: \" + processes); //Out: 'La cola: [Process 1, Process 2, Process 3]'\n\n        processes.poll(); //Borra el primer elemento\n        System.out.println(\"La cola: \" + processes); //Out: 'La cola: [Process 2, Process 3]'\n\n            //Implementación de cola a través de un arrayList\n        List<String> queue = new ArrayList<>();\n        queue.add(\"Elemento 1\");\n        queue.add(\"Elemento 2\");\n        queue.add(\"Elemento 3\");\n        System.out.println(\"Mi queue: \" + queue); //Out: 'Mi queue: [Elemento 1, Elemento 2, Elemento 3]'\n\n        queue.remove(0); //Borra y devuelve el primer elemento, como si fuera una cola\n        System.out.println(\"Mi queue: \" + queue); //Out: 'Mi queue: [Elemento 1, Elemento 2]'\n\n        //Reto\n        System.out.println(\"\\n\");\n        retoFinalPila();\n        retoFinalCola();\n    }\n\n    static Scanner sc;\n\n    public static void retoFinalPila(){\n        sc = new Scanner(System.in);\n        int sitesSize;\n\n        List<String> sites = new ArrayList<>();\n        List<String> cachedSites = new ArrayList<>();\n        sites.add(\"Inicio\");\n\n        app: while(true){\n            sitesSize = sites.size();\n            System.out.println(\"Página actual: \" + sites.get(sites.size() - 1));\n            System.out.print(\"Escribe el nombre de la web, Adelante/Atrás para moverte o Salir: \");\n            String reply = sc.nextLine();\n            switch (reply.toLowerCase()){\n                case \"adelante\":\n                    if (cachedSites.size() > 0)\n                        sites.add(cachedSites.remove(cachedSites.size() - 1));\n                    break;\n                case \"atrás\", \"atras\":\n                    if (sitesSize > 1)\n                        cachedSites.add(sites.remove(sites.size() - 1));\n                    break;\n                case \"salir\":\n                    break app;\n                default:\n                    sites.add(reply);\n                    cachedSites.removeAll(cachedSites);\n            }\n        }\n    }\n\n    public static void retoFinalCola(){\n        sc = new Scanner(System.in);\n\n        List<String> printer = new ArrayList<>();\n\n        app: while(true){\n            System.out.println(\"Documentos para imprimir: \" + printer.size());\n            System.out.print(\"Escribe el nombre de un documento, Imprimir o Salir: \");\n            String reply = sc.nextLine();\n            switch (reply.toLowerCase()){\n                case \"imprimir\":\n                    if (printer.size() > 0)\n                        System.out.println(\"Imprimiendo: \" + printer.remove(0));\n                    break;\n                case \"salir\":\n                    break app;\n                default:\n                    printer.add(reply);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/java/Ldre3.java",
    "content": "import java.util.ArrayList;\nimport java.util.List;\n\npublic class Ldre3 {\n    public static void main(String[] args) {\n        /*\n         * EJERCICIO:\n         * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n         * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n         * o lista (dependiendo de las posibilidades de tu lenguaje).\n         */\n\n\n\n        /*\n         * DIFICULTAD EXTRA (opcional):\n         * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n         *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n         *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n         *   Las palabras \"adelante\", \"atras\" desencadenan esta acción, el resto se interpreta como\n         *   el nombre de una nueva web.\n         * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n         *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n         *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n         *   interpretan como nombres de documentos.\n         */\n        Historial historial = new Historial();\n        System.out.println(historial.atras());\n        System.out.println(historial.adelante());\n        historial.navegar(\"asd\");\n        historial.navegar(\"asasdd\");\n        historial.navegar(\"asasaaadd\");\n        System.out.println(historial.atras());\n        System.out.println(historial.atras());\n        System.out.println(historial.adelante());\n        System.out.println(historial.adelante());\n\n        Impresora impresora = new Impresora();\n        impresora.agregar(\"2asdd\");\n        impresora.agregar(\"2asdsddd\");\n        impresora.agregar(\"2asddaaa\");\n        System.out.println(impresora.imprimir());\n        System.out.println(impresora.imprimir());\n        System.out.println(impresora.imprimir());\n\n\n\n\n\n    }\n    public class Fifo<E> {\n        private List<E> list = new ArrayList<>();\n\n        public void add(E element){\n            list.add(element);\n        }\n\n        public E get (){\n            return list.get(0);\n        }\n\n    }\n\n    public class Lifo <E> {\n        private List<E> list = new ArrayList<>();\n\n        public void add (E element){\n            list.add(0,element);\n        }\n\n        public E get (){\n            return list.get(0);\n        }\n    }\n\n    public static class Historial {\n        private ArrayList<String> historial = new ArrayList<>();\n        private int indice = -1;\n\n        public void navegar (String pagina){\n            historial.add(pagina);\n            indice++;\n        }\n        public String atras(){\n            if (indice > 0){\n                String retorno = historial.get(indice-1);\n                indice--;\n                return retorno;\n            }else {\n                return null;\n            }\n        }\n\n        public String adelante(){\n            if (indice < historial.size()-1){\n                String retorno = historial.get(indice+1);\n                indice++;\n                return retorno;\n            }\n            return null;\n        }\n    }\n\n    public static class Impresora {\n        private ArrayList<String> documentos = new ArrayList<>();\n\n        public void agregar(String documento){\n            documentos.add(documento);\n        }\n\n        public String imprimir(){\n            return documentos.remove(0);\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/java/Qv1ko.java",
    "content": "import java.util.ArrayDeque;\nimport java.util.Deque;\nimport java.util.LinkedList;\nimport java.util.Queue;\n\npublic class Qv1ko {\n\n    public static void main(String[] args) {\n\n        Deque<Integer> stack = new ArrayDeque<>();\n\n        stack.push(1);\n        stack.push(2);\n        stack.push(3);\n\n        while (!stack.isEmpty()) {\n            System.out.println(\"Stack: \" + stack.pop());\n        }\n\n        Queue<Integer> queue = new LinkedList<>();\n\n        queue.add(1);\n        queue.add(2);\n        queue.add(3);\n\n        System.out.println(\"Queue: \" + queue);\n\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/java/RodrigoGit87.java",
    "content": "/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n\nimport java.util.InputMismatchException;\nimport java.util.LinkedList;\nimport java.util.Scanner;\nimport java.util.Stack;\n\npublic class RodrigoGit87 {\n    public static void main (String[] args){\n    // PILAS / STACK (LIFO, Last In First Out)\n        System.out.println(\"Stack\");\n\n        Stack<Integer> pila = new Stack<Integer>();\n        for (int i=0; i <=10; i++) pila.push(i);\n        System.out.println(pila);\n\n        int pop = pila.pop(); //Devuelve el ultimo push y lo elimina\n        System.out.println(pila + \"\\nElemento .pop() eliminado: \" + pop);\n\n\n    // COLAS  / Queue (FIFO, First In First Out) Se recomienda LinkedList o ArrayDeque\n        System.out.println(\"Queue\");\n        LinkedList<Integer> numeros = new LinkedList<>();\n        numeros.add(11);\n        numeros.add(22);\n        numeros.add(33);\n        numeros.add(44);\n        System.out.println(numeros);\n\n        int n = numeros.pop(); // Devuelve el primer elemento y lo elimina\n        System.out.println(numeros + \"\\nElemento .pop() eliminado: \" + n);\n\n\n        // ---------- EXTRA ------------\n        System.out.println(\" --- EXTRA  --- \");\n        Stack<Accion> pilaAcciones = new Stack<>();\n        Scanner sc =  new Scanner(System.in);\n\n            //Añadir opciones\n            pilaAcciones.push(new Accion(\"adelante\"));\n            pilaAcciones.push(new Accion(\"atras\"));\n            pilaAcciones.push(new Accion(\"salir\"));\n\n            //Mostrar opciones\n        System.out.println(\" Elige una acción \");\n        for (int i =0 ; i < pilaAcciones.size(); i++){\n            System.out.println(i + \" -> \" + pilaAcciones.get(i));\n        }\n            //Elegir una accion\n        try {\n            int eleccion = sc.nextInt();\n            if (eleccion >= 0 && eleccion < pilaAcciones.size()) {\n                Accion seleccionado = pilaAcciones.get(eleccion);\n                System.out.println(\" Acción realizada: \" + seleccionado);\n            }\n        } catch (InputMismatchException e) {\n            System.err.println(\" ERROR \" + e);\n        }\n    }\n\n    //Clase para el EXTRA ->  Creo la clase Accion para crear una pila basada en Objetos\npublic static class Accion {\n        protected String nombre;\n\n\n        public Accion(String nombre) {\n            this.nombre = nombre;\n        }\n\n        @Override\n        public String toString() {\n            return \"'\" + nombre + \"'\";\n        }\n    }\n}\n\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/java/RoniPG.java",
    "content": "import java.util.Collections;\nimport java.util.LinkedList;\nimport java.util.Queue;\nimport java.util.Scanner;\nimport java.util.Stack;\n\n// @Roni\npublic class PILAS_Y_COLAS_07 {\n\n\tpublic static void main(String[] args) {\n\t\t/*\n\t\t * EJERCICIO: Implementa los mecanismos de introducción y recuperación de\n\t\t * elementos propios de las pilas (stacks - LIFO) y las colas (queue - FIFO)\n\t\t * utilizando una estructura de array o lista (dependiendo de las posibilidades\n\t\t * de tu lenguaje).\n\t\t */\n\n\t\t// PILA(STACK)\n\n\t\tStack<Integer> pila = new Stack<>();\n\n\t\t// Insertar datos\n\n\t\tpila.push(1);\n\t\tpila.push(2);\n\t\tpila.add(3);\n\t\tpila.push(4);\n\t\tpila.add(5);\n\t\tSystem.out.println(\"Contenido de la pila: \" + pila);\n\n\t\t// Borrar datos\n\n\t\tpila.remove(1); // ---> Borrar dato en la posicion deseada\n\t\t// pila.clear(); ---> Eliminar(limpiar) todos los datos de la lista\n\t\tSystem.out.println(\"Contenido de la pila: \" + pila);\n\t\tint elementoCima = pila.pop(); // ---> Borrar dato en la cima de la pila con un return del dato\n\t\tSystem.out.println(\"Contenido de la pila: \" + pila);\n\t\tSystem.out.println(\"Elemento en la cima de la pila: \" + elementoCima);\n\n\t\t// Actualizar datos\n\n\t\tSystem.out.println(\"Contenido de la pila: \" + pila);\n\t\tpila.set(0, 2);\n\t\tSystem.out.println(\"Contenido de la pila: \" + pila);\n\n\t\t// Ordenar datos\n\n\t\tpila.push(8);\n\t\tpila.push(5);\n\t\tpila.push(7);\n\t\tSystem.out.println(pila);\n\t\tCollections.sort(pila);\n\t\tSystem.out.println(pila);\n\n\t\t// COLA(QUEUE)\n\n\t\t// Creamos una cola usando LinkedList (también podemos usar PriorityQueue)\n\t\tQueue<String> cola = new LinkedList<>();\n\n\t\t// Agregamos elementos a la cola\n\t\tcola.add(\"Elemento 0\");\n\t\tcola.offer(\"Elemento 1\");\n\t\tcola.offer(\"Elemento 2\");\n\t\tcola.offer(\"Elemento 3\");\n\n\t\t// Mostramos la cola\n\t\tSystem.out.println(\"Cola: \" + cola);\n\n\t\t// Eliminamos y mostramos el primer elemento de la cola\n\t\tString firstElement = cola.poll();\n\t\tSystem.out.println(\"Primer elemento de la cola: \" + firstElement);\n\n\t\t// Mostramos la cola actualizada\n\t\tSystem.out.println(\"Cola actualizada: \" + cola);\n\n\t\t// Obtenemos pero no eliminamos el primer elemento de la cola\n\t\tString peekedElement = cola.peek();\n\t\tSystem.out.println(\"Primer elemento de la cola (sin eliminar): \" + peekedElement);\n\n\t\t// Mostramos la cola nuevamente (sin cambios)\n\t\tSystem.out.println(\"Cola actualizada (sin cambios): \" + cola);\n\t\t/*\n\t\t * DIFICULTAD EXTRA (opcional): - Utilizando la implementación de pila y cadenas\n\t\t * de texto, simula el mecanismo adelante/atrás de un navegador web. Crea un\n\t\t * programa en el que puedas navegar a una página o indicarle que te quieres\n\t\t * desplazar adelante o atrás, mostrando en cada caso el nombre de la web. Las\n\t\t * palabras \"adelante\", \"atras\" desencadenan esta acción, el resto se interpreta\n\t\t * como el nombre de una nueva web.\n\t\t */\n\n\t\tPrograma1();\n\t\t/*\n\t\t * - Utilizando la implementación de cola y cadenas de texto, simula el\n\t\t * mecanismo de una impresora compartida que recibe documentos y los imprime\n\t\t * cuando así se le indica. La palabra \"imprimir\" imprime un elemento de la\n\t\t * cola, el resto de palabras se interpretan como nombres de documentos.\n\t\t */\n\t\tPrograma2();\n\t}\n\n\tpublic static void Programa1() {\n\t\tScanner entradaDatos = new Scanner(System.in);\n\t\tStack<String> url = new Stack<>();\n\t\turl.add(\"www.google.com\");\n\t\turl.add(\"www.twitter.com\");\n\t\turl.add(\"www.gmail.com\");\n\t\tString texto = \"\";\n\t\tint pos = 0;\n\n\t\tdo {\n\t\t\tSystem.out.println(\"\\n*******Navegación web*******\\n\");\n\t\t\tSystem.out.println(\"Escribe la url de la página web para dirigirte a ella.\");\n\t\t\tSystem.out.println(\"Si la url no existe se creara una nueva web\");\n\t\t\tSystem.out.println(\"Escribe 'adelante' para ir a la siguiente web.\");\n\t\t\tSystem.out.println(\"Escribe 'atras' para ir a la web anterior.\");\n\t\t\tSystem.out.println(\"Escribe 'salir' para cerrar el programa.\");\n\t\t\tSystem.out.println(\"Escribe aquí: \");\n\t\t\ttexto = entradaDatos.nextLine();\n\t\t\tif (texto.equalsIgnoreCase(\"adelante\")) {\n\t\t\t\tif (pos + 1 >= url.size()) {\n\t\t\t\t\tSystem.out.println(\"Ya te encuentras en la url del final\");\n\t\t\t\t\tSystem.out.println(\"La url es:\\n\" + url.get(pos));\n\t\t\t\t} else {\n\t\t\t\t\tSystem.out.println(\"Avanzamos\");\n\t\t\t\t\tSystem.out.println(\"La siguinente url es:\\n\" + url.get(pos + 1));\n\t\t\t\t\tpos += 1;\n\t\t\t\t}\n\t\t\t} else if (texto.equalsIgnoreCase(\"atras\")) {\n\t\t\t\tif (pos - 1 < 0) {\n\t\t\t\t\tSystem.out.println(\"Ya te encuentras en la url del principio\");\n\t\t\t\t\tSystem.out.println(\"La url es:\\n\" + url.get(pos));\n\t\t\t\t} else {\n\t\t\t\t\tSystem.out.println(\"Retrocedemos\");\n\t\t\t\t\tSystem.out.println(\"La url anterior es:\\n\" + url.get(pos - 1));\n\t\t\t\t\tpos -= 1;\n\t\t\t\t}\n\t\t\t} else if (url.contains(texto)) {\n\t\t\t\tSystem.out.println(\"Encontramos url\");\n\t\t\t\tpos = url.indexOf(texto);\n\t\t\t\tSystem.out.println(\"La url es:\\n\" + url.get(pos));\n\t\t\t} else if (texto.equalsIgnoreCase(\"Salir\")) {\n\t\t\t\tSystem.out.println(\"Vuelva pronto\");\n\t\t\t} else {\n\t\t\t\tSystem.out.println(\"Creamos web\");\n\t\t\t\turl.add(texto);\n\t\t\t\tSystem.out.println(\"La url es:\\n\" + url.lastElement());\n\t\t\t\tpos = (int) Math.round(url.size() / 2);\n\t\t\t}\n\t\t} while (!(texto.equalsIgnoreCase(\"salir\")));\n\t}\n\n\tpublic static void Programa2() {\n\t\tScanner entradaDatos = new Scanner(System.in);\n\t\tQueue<String> doc = new LinkedList<>();\n\t\tString texto = \"\";\n\t\tdoc.add(\"Documento 1\");\n\t\tdoc.add(\"Documento 2\");\n\t\tdoc.add(\"Documento 3\");\n\n\t\tdo {\n\t\t\tSystem.out.println(\"\\n*******Mecanismo de una impresora*******\\n\");\n\t\t\tSystem.out.println(\"Escribe 'imprimir' para ir a la imprimir el primer documento de la cola.\");\n\t\t\tSystem.out.println(\"Si no, introduce el nombre del nuevo documento a imprimir y se añadira a la cola\");\n\t\t\tSystem.out.println(\"Escribe 'salir' para cerrar el programa.\");\n\t\t\tSystem.out.println(\"Escribe aquí: \");\n\t\t\ttexto = entradaDatos.nextLine();\n\t\t\tif (texto.equalsIgnoreCase(\"imprimir\")) {\n\t\t\t\tSystem.out.println(\"Procedemos a imprimir el documento: \" + doc.poll());\n\t\t\t} else if (texto.equalsIgnoreCase(\"salir\")) {\n\t\t\t\tSystem.out.println(\"Vuelva pronto\");\n\t\t\t} else {\n\t\t\t\tSystem.out.println(\"Introducimos el nuevo documento\");\n\t\t\t\tdoc.add(texto);\n\t\t\t}\n\n\t\t} while (!(texto.equalsIgnoreCase(\"salir\")));\n\n\t}\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/java/TofeDev.java",
    "content": "import java.util.Scanner;\nimport java.util.Stack;\nimport java.util.LinkedList;\nimport java.util.Queue;\n\npublic class TofeDev {\n/* EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n    public class Navegador {\n\n        public static void main(String[] args) {\n            stackNavegacion();\n        }\n    \n        public static void stackNavegacion() {\n            Stack<String> historial = new Stack<>();\n            Scanner scan = new Scanner(System.in);\n            int pointerIndex = 0;\n    \n            while (true) {\n                if (!historial.isEmpty()) {\n                    System.out.println(\"---------------------------\");\n                    historial.forEach(h -> System.out.printf(\"%s | \", h));\n                    System.out.println(\"\\n\" + \"---------------------------\");\n                    System.out.print(\"Ingrese la 'página' o 'adelante' para avanzar, 'atras' para retroceder, o 'salir' para finalizar: \");\n                } else {\n                    System.out.println(\"Ingrese la página a visitar: \");\n                }\n                \n                String comando = scan.next();\n                \n                switch (comando) {\n                    case \"adelante\":\n                        if (pointerIndex < historial.size() - 1) {\n                            pointerIndex++;\n                            System.out.printf(\"Visualizando la página %s\\n\\n\", historial.get(pointerIndex));\n                        } else {\n                            System.out.println(\"No hay más historial hacia adelante\\n\\n\");\n                        }\n                        break;\n                        \n                    case \"atras\":\n                        if (pointerIndex > 0) {\n                            pointerIndex--;\n                            System.out.printf(\"Visualizando la página %s\\n\\n\", historial.get(pointerIndex));\n                        } else {\n                            System.out.println(\"No hay más historial hacia atrás\\n\\n\");\n                        }\n                        break;\n                        \n                    case \"salir\":\n                        System.out.println(\"Saliendo del navegador\");\n                        scan.close();\n                        System.exit(0);\n                        break;\n                        \n                    default:\n                        System.out.printf(\"Visualizando la página %s\\n\\n\", comando);\n                        historial.add(comando);\n                        pointerIndex = historial.size() - 1;\n                        break;\n                }\n            }\n        }\n    }\n\n    public class Impresora {\n\n        public static void main(String[] args) {\n            colaImpresora();\n        }\n    \n        public static void colaImpresora() {\n            Queue<String> porImprimir = new LinkedList<>();\n            Scanner scanner = new Scanner(System.in);\n            \n            System.out.println(\"******************************************************************\");\n            System.out.println(\"Ingrese 'agregar' para agregar un archivo a la cola de impresión\");\n            System.out.println(\"Ingrese 'imprimir' para empezar a imprimir un documento de la cola\");\n            System.out.println(\"Ingrese 'mostrar' para mostrar todos los documentos en la cola\");\n            System.out.println(\"Ingrese 'salir' para finalizar\");\n            System.out.println(\"******************************************************************\");\n    \n            while (true) {\n                System.out.print(\"Acción a realizar: \");\n                String comando = scanner.next();\n                \n                switch (comando) {\n                    case \"mostrar\":\n                        System.out.println(\"-----------------------------------\");\n                        System.out.println(String.format(\"Documentos en cola (%d)\", porImprimir.size()));\n                        for (String doc : porImprimir) {\n                            System.out.println(\"- \" + doc);\n                        }\n                        break;\n                        \n                    case \"agregar\":\n                        System.out.println(\"-----------------------------------\");\n                        System.out.print(\"Ingresa el nombre del documento: \");\n                        String nombre = scanner.next();\n                        porImprimir.add(nombre);\n                        break;\n                        \n                    case \"imprimir\":\n                        System.out.println(\"-----------------------------------\");\n                        if (porImprimir.isEmpty()) {\n                            System.out.println(\"No hay nada para imprimir\");\n                            break;\n                        }\n                        System.out.println(\"Imprimiendo \" + porImprimir.poll() + \" ...\");\n                        try {\n                            Thread.sleep(2000);\n                        } catch (InterruptedException e) {\n                            e.printStackTrace();\n                        }\n                        break;\n                    case \"salir\":\n                        System.out.println(\"Apagando la impresora\");\n                        scanner.close();\n                        System.exit(0);\n                        break;\n                    default:\n                        System.out.println(\"Comando no reconocido\");\n                        break;\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/java/Worlion.java",
    "content": "import java.util.Scanner;\nimport java.util.LinkedList;\nimport java.util.List;\n\n/*\n * EJERCICIO: Colas y Pilas\n */\n\nclass Stack<T> {\n    private List<T> stack = new LinkedList<T>();\n\n    public T pop() {\n        if(stack.isEmpty()) {\n            //throw new Exception(\"Pila vacia!\");\n            System.err.println(\"Pila vacia!\");\n            return null;\n        }\n        T element = stack.getLast();\n        stack.removeLast();\n        return element;\n    }\n\n    public void push(T element) {\n        stack.add(element);\n    }\n\n    public void printStack() {\n        System.out.println(\"Stack content:\" + stack);\n    }\n\n    public int size() {\n        return stack.size();\n    }\n\n    public boolean isEmpty() {\n        return stack.isEmpty();\n    }\n\n    public T top(){\n        return stack.getLast();\n    }\n\n    public void clear() {\n        stack.clear();\n    }\n}\n\nclass Queue<T> {\n    private List<T> queue = new LinkedList<T>();\n\n    public T get() {\n        if(queue.isEmpty()) {\n            //throw new Exception(\"Pila vacia!\");\n            System.err.println(\"Cola vacia!\");\n            return null;\n        }\n        T element = queue.getFirst();\n        queue.remove(0);\n        return element;\n    }\n    \n    public void put(T element) {\n        queue.add(element);\n    }\n\n    public void printQueue() {\n        System.out.println(\"Queue content:\" + queue);\n    }\n\n    public int size(){\n        return queue.size();\n    }\n\n    public boolean isEmpty() {\n        return queue.isEmpty();\n    }\n}\n\nclass WebBrowser {\n\n    private Stack<String> history = new Stack<String>();\n    private Stack<String> backHistory = new Stack<String>();\n\n    public void run() {\n\n        history.push(\"Home Page\");\n        \n        String option = null;\n        do{\n            option = showMenu();\n            processOption(option.toLowerCase());\n\n        } while (!\"0\".equals(option));\n    }\n\n    private String showMenu() {\n\n        System.out.println(\"\\n\\n WEB BROWSER\\n\");\n        System.out.println(\"\\n - curren page: \"+ Worlion.GREEN+history.top()+ Worlion.ANSI_RESET);\n        System.out.println(\"\\n Select an option or type the url you want to navigate to: \\n\");\n\n        System.out.println(\"\\t 1.- \"+option1());\n        System.out.println(\"\\t 2.- \"+option2());\n        System.out.println(\"\\t 3.- Show history\");\n        System.out.println(Worlion.RED_BACKGROUND+\"\\t 0.- Exit\"+ Worlion.ANSI_RESET);\n        System.out.print(\"\\n Choose an option (or type url):\");\n\n        return Worlion.scanner.nextLine();\n    }\n\n    private void processOption(String option){\n        Worlion.clearScreen();\n        switch (option) {\n            case \"1\":\n            case \"back\":\n            case \"go back\":\n                if(history.size()==1) {\n                    System.out.println(\"\\n\"+Worlion.RED+\"Invalid option:\"+ Worlion.ANSI_RESET+\" the history is empty (you are in the home page)\");\n                }\n                else {\n                    System.out.println(\"going back...\");\n                    backHistory.push(history.pop());\n                }\n                \n                break;\n\n            case \"2\":\n            case \"ahead\":\n            case \"go ahead\":\n                if(backHistory.isEmpty()) {\n                    System.out.println(\"\\n\"+Worlion.RED+\"Invalid option:\"+ Worlion.ANSI_RESET+\" the forward history is empty\");\n                }\n                else {\n                    System.out.println(\"going forward...\");\n                    history.push(backHistory.pop());\n                }\n                break;\n\n            case \"3\":\n            case \"show\":\n            case \"history\":\n            case \"show history\":\n                System.out.println(\"\\nShowing history:\");\n                System.out.print(\" - Back history: \");\n                history.printStack();\n                System.out.print(\" - Forward history: \");\n                backHistory.printStack();\n                break;\n\n            case \"0\":\n            case \"exit\":\n                System.out.println(\"\\nSee you soon...\");\n                break;\n\n            default:\n                System.out.println(\"Browsing to '\" + option + \"'...\");\n                history.push(option);\n                backHistory.clear();\n                break;\n        }\n    }\n\n    private String option1(){\n        String msg = \"Go back\";\n        if(history.size()==1){\n            return Worlion.RED + msg + Worlion.ANSI_RESET;\n        }\n        return Worlion.GREEN + msg + Worlion.ANSI_RESET;\n    }\n\n    private String option2(){\n        String msg = \"Go ahead\";\n        if(backHistory.size()==0){\n            return Worlion.RED + msg + Worlion.ANSI_RESET;\n        }\n        return Worlion.GREEN + msg + Worlion.ANSI_RESET;\n    }\n\n    \n}\n\nclass Printer {\n\n    private Queue<String> impresora = new Queue<String>();\n\n    public void run() {\n            /* - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n        *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n        *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n        *   interpretan como nombres de documentos.\n        */\n        String option  =\"\";\n        do {\n            option = showMenu();\n        } while(! \"0\".equals(processOption(option)) );\n\n    }\n\n    private String showMenu(){\n\n        System.out.println(\"  --- COLA DE IMPRESIÓN --- \");\n        impresora.printQueue();\n        \n        System.out.println(\"\\nOpciones: \");\n        System.out.println(Worlion.GREEN + \"\\t - Escriba el nombre del documento\" + Worlion.ANSI_RESET);\n        String msg = \"\\t - Escriba 'Imprimir' o '1' para comenzar la impresión'\";\n        if(impresora.size() == 0) {\n            System.out.println( Worlion.RED+ msg + Worlion.ANSI_RESET );\n        } else {\n            System.out.println( Worlion.GREEN+ msg + Worlion.ANSI_RESET );\n        }\n        System.out.println( Worlion.RED + \"\\t - Escriba 'Salir' o '0' para salir de la aplicación'\"+ Worlion.ANSI_RESET);\n\n        System.out.print(\"\\n\\t > \");\n        return Worlion.scanner.nextLine();\n    }\n\n    private String processOption(String option) {\n        if (\"0\".equals(option) || \"salir\".equalsIgnoreCase(option)){\n            return \"0\";\n        }\n        if (\"1\".equals(option) || \"imprimir\".equalsIgnoreCase(option)) {\n            print();\n        } else{\n            impresora.put(option);\n        }\n        return \"1\";\n    }\n\n    private void print() {\n        if(impresora.isEmpty()){\n            System.out.println(Worlion.RED + \"WARNING: \"+Worlion.ANSI_RESET + \"Cola de impresión vacía, nada que imprimir\");\n        }\n        else {\n            System.out.println(\"Imprimiendo '\"+impresora.get()+\"'...\");\n        }\n    }\n}\n\npublic class Worlion {\n\n    public static final String GREEN = \"\\u001B[32m\";\n    public static final String RED = \"\\u001B[31m\";\n    public static final String RED_BACKGROUND = \"\\u001B[41m\";\n    public static final String ANSI_RESET = \"\\u001B[0m\";\n    \n    public static void clearScreen() {\n        System.out.print(\"\\033\\143\");\n    }\n\n    public static Scanner scanner = new Scanner(System.in);\n\n\n\n    public static void main(String[] args) {\n        new Worlion().run();\n    }\n\n    public void run() {\n        playWithStack();\n        playWithQueue();\n        /*\n        * DIFICULTAD EXTRA (opcional):\n        */\n        System.out.println(\" \\n ---- 🌩 DIFICULTAD EXTRA 🌩 ----\\n\");\n\n        new WebBrowser().run();\n\n        new Printer().run();\n    }\n\n    private void playWithStack(){\n        System.out.println(\"\\nJugando con la pila...\");\n        Stack<Integer> stack = new Stack<Integer>();\n        System.out.println(\"Añado 4 valores:\");\n        stack.push(3);\n        stack.push(65);\n        stack.push(1);\n        stack.push(99);\n        stack.printStack();\n\n        System.out.println(\"elimino el primero: \");\n        System.out.println(\"pop: {\" + stack.pop() + \"}\");\n        stack.printStack();\n\n        System.out.println(\"elimino otro: \");\n        System.out.println(\"pop: {\" + stack.pop() + \"}\");\n        stack.printStack();\n\n        System.out.println(\"elimino otro: \");\n        System.out.println(\"pop: {\" + stack.pop() + \"}\");\n        stack.printStack();\n\n        System.out.println(\"elimino otro: \");\n        System.out.println(\"pop: {\" + stack.pop() + \"}\");\n        stack.printStack();\n        \n        System.out.println(\"elimino otro: \");\n        System.out.println(\"pop: {\" + stack.pop() + \"}\");\n        stack.printStack();\n\n    }\n\n    private void playWithQueue(){\n        System.out.println(\"\\nJugando con la cola...\");\n        Queue<String> queue = new Queue<String>();\n\n        System.out.println(\"Añado 4 valores\");\n        queue.put(\"a\");\n        queue.put(\"b\");\n        queue.put(\"c\");\n        queue.put(\"d\");\n                \n        queue.printQueue();\n        \n        System.out.println(\"elimino el primero: \");\n        System.out.println(\"get: {\" + queue.get() + \"}\");\n        queue.printQueue();\n        System.out.println(\"elimino otro: \");\n        System.out.println(\"get: {\" + queue.get() + \"}\");\n        queue.printQueue();\n        System.out.println(\"get: {\" + queue.get() + \"}\");\n        queue.printQueue();\n        System.out.println(\"get: {\" + queue.get() + \"}\");\n        queue.printQueue();\n        System.out.println(\"get: {\" + queue.get() + \"}\");\n    }\n\n\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/java/alexdevrep.java",
    "content": "package _07_Pilas_y_Colas;\n//Importamos las librerías necesarias para el ejercicio\nimport java.util.Stack;\nimport java.util.Queue;\nimport java.util.LinkedList;\nimport java.util.Scanner;\n\n\n/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\npublic class _07_Pilas_y_Colas {\n    //Pilas LIFO Last In, First Out\n    //Creamos una pila\n    static Stack<String> pilaelementos = new Stack<>();\n\n    //Colas FIFO First In, First Out\n    //Creamos una cola\n    static Queue<String> colaelementos = new LinkedList<>();\n\n    public static void main (String[] args){\n        //Añadimos elementos a la pila\n        pilaelementos.push(\"Hola\");\n        pilaelementos.push(\"Java\");\n        pilaelementos.push(\"alexdevrep\");\n        pilaelementos.push(\"Mundo\");\n        System.out.println(pilaelementos);\n        //Recuperamos el último elemento añadido a la lista en este caso \"Mundo\"\n        System.out.println(pilaelementos.pop());\n        System.out.println(pilaelementos);\n\n        System.out.println(\"----------------------------------\");\n        //Añadimos elementos a la cola\n        colaelementos.add(\"Hola\");\n        colaelementos.add(\"Java\");\n        colaelementos.add(\"Mundo\");\n        System.out.println(colaelementos);\n        //Recuperamos el primer elemento añadido a la cola en este caso \"Hola\"\n        System.out.println(colaelementos.poll());\n        System.out.println(colaelementos);\n\n        //Dificultad EXTRA\n        //Ejercicio Pilas\n        Stack<String> pila_web = new Stack<>();\n        Scanner scanner = new Scanner(System.in);\n\n        System.out.println(\"###---NAVEGADOR WEB---###\");\n        System.out.println(\"Pestaña nueva\");\n\n        while (true) {\n            System.out.println(\"Por favor escriba ADELANTE si quiere acceder a una URL nueva, ATRAS si quiere cerrar la última URL, o SALIR para salir: \");\n            String comando = scanner.nextLine();\n            accion(pila_web, comando);\n\n            if (comando.equals(\"SALIR\")) {\n                break;\n            }\n        }\n\n\n        //Ejercicio Colas\n        Queue<String> documentos = new LinkedList<>();\n\n        while(true){\n            System.out.println(\"Por favor escriba el nombre del archivo para añadirlo a la cola de la impresión , IMPRIMIR para imprimirlo y SALIR para apagar la impresora: \");\n            String archivo = scanner.nextLine();\n            impresora(documentos, archivo);\n            if (archivo.equals(\"SALIR\")){\n                scanner.close();\n                System.exit(0);\n            }\n        }\n\n    }\n\n    public static void accion(Stack<String> pila_web, String comando) {\n        if (comando.equals(\"ADELANTE\")) {\n            System.out.println(\"Por favor indique a qué web quiere acceder: \");\n            String web = new Scanner(System.in).nextLine();\n            pila_web.push(web);\n            System.out.println(\"Ahora estás viendo: \" + pila_web.peek());\n        } else if (comando.equals(\"ATRAS\")) {\n            if (pila_web.size() > 1) {\n                pila_web.pop();\n                System.out.println(\"Ahora estás viendo: \" + pila_web.peek());\n            } else {\n                System.out.println(\"No hay historial de navegación para retroceder\");\n            }\n        } else if (comando.equals(\"SALIR\")) {\n            System.out.println(\"Cerrando el navegador web\");\n        } else {\n            System.out.println(\"Comando no reconocido\");\n        }\n    }\n    public static void impresora(Queue<String> documentos,String archivo){\n        if (archivo.equals(\"IMPRIMIR\")){\n            if(documentos.size()>=1){\n                System.out.println(\"Impriendo archivo\"+ documentos.poll());\n            }else {\n                System.out.println(\"No hay archivos para imprimir\");\n            }\n        }else if(archivo.equals(\"SALIR\")){\n            System.out.println(\"Apagando la impresora\");\n        }else{\n            documentos.add(archivo);\n            System.out.println(\"Documento añadido a la cola de impresion\");\n        }\n\n    }\n}\n\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/java/asjordi.java",
    "content": "import java.util.*;\n\npublic class Main {\n\n    public static void main(String[] args) {\n\n        ejemploNavegadorPila();\n        ejemploImpresoraCola();\n\n    }\n\n    /**\n     * Tanto Stack como Deque (cuando se utiliza como pila) siguen siendo estructuras LIFO.\n     * Es decir, independientemente de cómo se impriman,\n     * el último elemento que se insertó será el primero en ser eliminado.\n     */\n    static void estructurasLIFO() {\n\n        // Estructura LIFO (Last In First Out)\n        Stack<Integer> pila = new Stack<>();\n\n        // Agregar elementos\n        pila.push(1);\n        pila.push(2);\n        pila.push(3);\n\n        // Remover el último elemento\n        pila.pop();\n\n        System.out.println(\"Contenido de la pila: \" + pila);\n        System.out.println(\"El último elemento es: \" + pila.peek());\n        System.out.println(\"El elemento 2 está en la posición: \" + pila.search(2));\n        System.out.println(\"La pila está vacía: \" + pila.isEmpty());\n\n        // Una estructura LIFO más completa y consistente es la clase Deque\n        Deque<Integer> pila2 = new ArrayDeque<>();\n\n        // Agregar elementos\n        pila2.push(1);\n        pila2.push(2);\n        pila2.push(3);\n\n        // Remover el último elemento\n        pila2.pop();\n\n        System.out.println(\"Contenido de la pila2 (se muestra en orden inverso): \" + pila2);\n        System.out.println(\"El último elemento es: \" + pila2.peek());\n        System.out.println(\"La pila contiene el elemento 2: \" + pila2.contains(2));\n        System.out.println(\"La pila2 está vacía: \" + pila2.isEmpty());\n        System.out.println(\"Obtener pero no remover el primer elemento: \" + pila2.peekFirst());\n        System.out.println(\"Obtener pero no remover el último elemento: \" + pila2.peekLast());\n\n    }\n\n    static void estructurasFIFO() {\n\n        // Estructuras FIFO (First In First Out)\n        Queue<Integer> cola = new LinkedList<>();\n\n        // Agregar elementos\n        cola.add(1);\n        cola.add(2);\n        cola.add(3);\n\n        // Remover el primer elemento agregado\n        int primero = cola.remove();\n\n        System.out.println(\"El primer elemento removido es: \" + primero);\n        System.out.println(\"Contenido de la cola después de remover: \" + cola);\n\n        /**\n         * Deque (Double Ended Queue)\n         * en Java también puede funcionar como una estructura FIFO (First In First Out).\n         * Esto se debe a que permite la inserción y eliminación de elementos desde ambos extremos.\n         * Cuando se utilizan los métodos addLast (o offer) para agregar elementos\n         * y removeFirst (o poll) para eliminarlos, actúa como una cola FIFO.\n         */\n\n        Deque<Integer> dequeCola = new ArrayDeque<>();\n\n        // Agregar elementos\n        dequeCola.addLast(1);\n        dequeCola.addLast(2);\n        dequeCola.addLast(3);\n\n        // Remover el primer elemento agregado\n        int primerElemento = dequeCola.removeFirst();\n\n        System.out.println(\"El primer elemento removido es: \" + primerElemento);\n        System.out.println(\"Contenido de la cola después de remover: \" + dequeCola);\n\n    }\n\n    /**\n     * LinkedList en Java puede ser utilizado tanto como una estructura FIFO (First In First Out) como LIFO (Last In First Out).\n     * Para usarlo como una estructura FIFO (como una cola),\n     * puedes usar los métodos addLast() para agregar elementos al final de la lista y removeFirst() para eliminar el primer elemento de la lista.\n     * Para usarlo como una estructura LIFO (como una pila),\n     * puedes usar los métodos addLast() o push() para agregar elementos al final de la lista y removeLast() o pop() para eliminar el último elemento de la lista.\n     */\n    static void estructuraLifoFifo() {\n        LinkedList<Integer> fifoList = new LinkedList<>();\n\n        // Agregar elementos\n        fifoList.addLast(1);\n        fifoList.addLast(2);\n        fifoList.addLast(3);\n\n        // Remover el primer elemento agregado\n        int primero = fifoList.removeFirst();\n\n        System.out.println(\"El primer elemento removido es: \" + primero);\n        System.out.println(\"Contenido de la lista después de remover: \" + fifoList);\n\n        LinkedList<Integer> lifoList = new LinkedList<>();\n\n        // Agregar elementos\n        lifoList.addLast(1);\n        lifoList.addLast(2);\n        lifoList.addLast(3);\n\n        // Remover el último elemento agregado\n        int ultimo = lifoList.removeLast();\n\n        System.out.println(\"El último elemento removido es: \" + ultimo);\n        System.out.println(\"Contenido de la lista después de remover: \" + lifoList);\n    }\n\n    /**\n     * Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás de un navegador web.\n     * Crea un programa en el que puedas navegar a una página o indicarle\n     * que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n     * Las palabras \"adelante\", \"atras\" desencadenan esta acción, el resto se interpreta como\n     * el nombre de una nueva web.\n     */\n\n    static void ejemploNavegadorPila() {\n\n        Deque<String> historial = new ArrayDeque<>();\n        Scanner scanner = new Scanner(System.in);\n\n        while (true) {\n            System.out.println(\"Introduce el nombre de la web o 'adelante'/'atras' o salir: \");\n            String input = scanner.nextLine();\n\n            if (input.equalsIgnoreCase(\"salir\")) break;\n\n            if (input.equals(\"adelante\")) {\n                if (historial.isEmpty()) System.out.println(\"No hay páginas para avanzar\");\n                else {\n                    String pagina = historial.pollLast();\n                    System.out.println(\"Avanzando a la página: \" + pagina);\n                }\n            } else if (input.equals(\"atras\")) {\n                if (historial.isEmpty()) System.out.println(\"No hay páginas para retroceder\");\n                else {\n                    String pagina = historial.pollFirst();\n                    System.out.println(\"Retrocediendo a la página: \" + pagina);\n                }\n            } else {\n                historial.addFirst(input);\n                System.out.println(\"Navegando a la página: \" + input);\n            }\n        }\n\n    }\n\n    /**\n     * Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n     * impresora compartida que recibe documentos y los imprime cuando así se le indica.\n     * La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n     * interpretan como nombres de documentos.\n     */\n\n    static void ejemploImpresoraCola() {\n\n        Deque<String> colaImpresion = new ArrayDeque<>();\n        Scanner scanner = new Scanner(System.in);\n\n        while (true) {\n            System.out.println(\"Introduce el nombre del documento o 'imprimir' o salir: \");\n            String input = scanner.nextLine();\n\n            if (input.equalsIgnoreCase(\"salir\")) break;\n\n            if (input.equals(\"imprimir\")) {\n                if (colaImpresion.isEmpty()) System.out.println(\"No hay documentos para imprimir\");\n                else {\n                    String documento = colaImpresion.poll();\n                    System.out.println(\"Imprimiendo el documento: \" + documento);\n                }\n            } else {\n                colaImpresion.addLast(input);\n                System.out.println(\"Añadiendo el documento: \" + input);\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/java/cesar-ch.java",
    "content": "import java.util.ArrayList;\nimport java.util.List;\nimport java.util.Scanner;\n\npublic class Main {\n\n    private static Scanner scanner = new Scanner(System.in);\n\n    public static void main(String[] args) {\n        // pila\n        List<Integer> pila = new ArrayList<>();\n\n        // push\n        pila.add(1);\n        pila.add(2);\n        pila.add(3);\n\n        // pop\n        pila.remove(pila.size() - 1);\n        System.out.println(pila);\n\n        // cola\n        List<Integer> cola = new ArrayList<>();\n\n        // enqueue\n        cola.add(1);\n        cola.add(2);\n        cola.add(3);\n\n        // dequeue\n        cola.remove(0);\n        System.out.println(cola);\n\n        // DIFICULTAD EXTRA\n        webNavigation();\n        sharedPrinted();\n    }\n\n    public static void webNavigation() {\n        List<String> stack = new ArrayList<>();\n\n        while (true) {\n            System.out.print(\"Añade una url o interactúa con palabras adelante/atras/salir: \");\n            String action = scanner.nextLine();\n\n            if (action.equals(\"salir\")) {\n                System.out.println(\"Saliendo del navegador web.\");\n                break;\n            } else if (action.equals(\"adelante\")) {\n                continue;\n            } else if (action.equals(\"atras\")) {\n                if (stack.size() > 0) {\n                    stack.remove(stack.size() - 1);\n                }\n            } else {\n                stack.add(action);\n            }\n\n            if (!stack.isEmpty()) {\n                System.out.println(\"Has navegado a la web: \" + stack.get(stack.size() - 1));\n            } else {\n                System.out.println(\"Estás en la página de inicio.\");\n            }\n        }\n    }\n\n    public static void sharedPrinted() {\n        List<String> queue = new ArrayList<>();\n\n        while (true) {\n            System.out.print(\"Añade un documento o selecciona imprimir/salir: \");\n            String action = scanner.nextLine();\n\n            if (action.equals(\"salir\")) {\n                break;\n            } else if (action.equals(\"imprimir\")) {\n                if (!queue.isEmpty()) {\n                    System.out.println(\"Imprimiendo: \" + queue.remove(0));\n                }\n            } else {\n                queue.add(action);\n            }\n            System.out.println(\"Cola de impresión: \" + queue);\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/java/chartypes.java",
    "content": "import java.util.EmptyStackException;\nimport java.util.LinkedList;\nimport java.util.NoSuchElementException;\nimport java.util.Queue;\nimport java.util.Stack;\n\npublic class chartypes {\n\n  public static void main(String[] args) {\n    System.out.println(\"Exercise\");\n    queue();\n    System.out.println();\n    stack();\n    System.out.println(\"\\n///////////////////////////////////////\\n\");\n    System.out.println(\"Extra:\");\n\n    System.out.println(\"Printer:\");\n    MyPrinter.addSheet(\"hmm..\");\n    MyPrinter.addSheet(\"test\");\n    MyPrinter.addSheet(\"imprimir\");\n    MyPrinter.addSheet(\"test2\");\n    MyPrinter.addSheet(\"ImpRimir\");\n    MyPrinter.addSheet(\"IMPRIMIR\");\n    MyPrinter.addSheet(\"ImpRimir\");\n    MyPrinter.addSheet(\"ImpRimir\");\n\n    System.out.println();\n\n    System.out.println(\"Browser:\");\n    Browser.browser(\"github\");\n    Browser.browser(\"carlosperezm.com\");\n    Browser.browser(\"atras\");\n    Browser.browser(\"mouredev\");\n    Browser.browser(\"atras\");\n    Browser.browser(\"adelante\");\n\n  }\n\n  static void queue() {\n    Queue<Integer> myQueue = new LinkedList<>();\n    myQueue.add(5);\n    myQueue.add(0);\n    myQueue.add(1131);\n    myQueue.add(12);\n    System.out.println(\"Queue: \" + myQueue);\n    System.out.println(\"peek:\" + myQueue.peek());\n\n    myQueue.remove();\n    System.out.println(\"whole queue: \" + myQueue);\n    System.out.println(\"peek:\" + myQueue.peek());\n\n    System.out.println(\"is empty?: \" + myQueue.isEmpty());\n    System.out.println(\"size: \" + myQueue.size());\n\n  }\n\n  static void stack() {\n    Stack<String> myStack = new Stack<>();\n\n    myStack.push(\"1st element of my stack\");\n    myStack.push(\"2nd element of my stack\");\n    myStack.push(\"3rd element of my stack\");\n    myStack.push(\"4th element of my stack\");\n\n    System.out.println(\"Stack: \" + myStack);\n    myStack.pop();\n    System.out.println(\"Stack after popping: \" + myStack);\n    System.out.println(\"Stack peek: \" + myStack.peek());\n\n    System.out.println(\"is empty?: \" + myStack.isEmpty());\n    System.out.println(\"size: \" + myStack.size());\n\n  }\n}\n\nclass MyPrinter {\n  static private Queue<String> printer = new LinkedList<>();\n\n  static void addSheet(String text) {\n\n    if (text.toLowerCase().equals(\"imprimir\")) {\n      String peek = printer.peek();\n      if (peek == null)\n        System.out.println(\"No more elements in the printer\");\n      else {\n        System.out.println(printer.peek());\n        printer.remove();\n      }\n    } else\n      printer.add(text);\n\n  }\n}\n\nclass Browser {\n  static private Stack<String> history = new Stack<>();\n\n  static void browser(String text) {\n    String lastestItem = \"\";\n    if (text.toLowerCase().equals(\"atras\")) {\n      try {\n        System.out.println(history.get(history.size() - 2));\n\n      } catch (EmptyStackException e) {\n        System.out.println(\"No more elements in the browser\");\n      }\n    } else if (text.toLowerCase().equals(\"adelante\")) {\n      lastestItem = history.pop();\n      System.out.println(lastestItem);\n\n    } else {\n      history.push(text);\n\n    }\n  }\n\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/java/danhingar.java",
    "content": "import java.util.Stack;\nimport java.util.ArrayDeque;\nimport java.util.Queue;\nimport java.util.Scanner;\n\npublic class danhingar {\n\n    public static void main(String[] args) {\n        // Declarar una pila\n        Stack<String> books = new Stack<>();\n\n        // Añadir elementos\n        books.addElement(\"Libro2\");\n        books.add(\"Libro3\");\n        books.addFirst(\"Libro1\");\n        books.push(\"Libro4\");\n        books.addLast(\"Libro5\");\n\n        System.out.println(books);\n\n        // Recuperar último elemento introducido y lo elimina\n        String lastBook = books.pop();\n\n        System.out.println(lastBook);\n        System.out.println(books);\n\n        // Recuperar el último elemento sin eliminarlo\n        String lastBook2 = books.peek();\n        System.out.println(lastBook2);\n        System.out.println(books);\n\n        // Buscar elemento\n        int index = books.search(\"Libro3\");\n        System.out.println(books.get(index));\n\n        // Invertir orden\n        System.out.println(books.reversed());\n        System.out.println(books.reversed().getLast());\n        System.out.println(books.reversed().getFirst());\n\n        // Colas\n        Queue<Integer> numbers = new ArrayDeque<>();\n\n        // Añadir elementos\n        numbers.add(1);\n        numbers.add(2);\n        numbers.add(3);\n        numbers.add(4);\n\n        System.out.println(numbers);\n\n        // Recupera el primer elemento añadido y lo elimina\n        Integer number = numbers.poll();\n        System.out.println(number);\n        System.out.println(numbers);\n\n        // Recupera el primer elemento añadido sin eliminarlo\n        Integer number2 = numbers.peek();\n        System.out.println(number2);\n        System.out.println(numbers);\n\n        // Igual que peek pero lanza una excepción si está vacía\n        Integer number3 = numbers.element();\n        System.out.println(number3);\n        System.out.println(numbers);\n\n        // browser();\n        printer();\n    }\n\n    private static Stack<String> pages = new Stack<>();\n    private static int pointer = -1;\n\n    // EXTRA\n    private static void browser() {\n        while (Boolean.TRUE) {\n            System.out.println(\"Añade una url o selecciona la opción adelantes/atras/salir\");\n            Scanner scanner = new Scanner(System.in);\n            String input = scanner.nextLine();\n            switch (input) {\n                case \"atras\":\n                    if (pages.size() > 1 && pointer > 0) {\n                        System.out.println(\"Has navegado a la web: \" + pages.get(pointer - 1));\n                        pointer--;\n                    } else {\n                        System.out.println(\"Estás en la página de inicio\");\n                    }\n                    break;\n                case \"adelante\":\n                    if (pages.size() > 1 && pointer < pages.size() - 1) {\n                        System.out.println(\"Has navegado a la web: \" + pages.get(pointer + 1));\n                        pointer++;\n                    } else {\n                        System.out.println(\"No puedes avanzar más\");\n                    }\n                    break;\n\n                case \"salir\":\n                    scanner.close();\n                    System.exit(0);\n                default:\n                    pages.push(input);\n                    pointer++;\n                    System.out.println(\"Has navegado a la web: \" + pages.peek());\n                    break;\n            }\n        }\n\n    }\n\n    private static Queue<String> documents = new ArrayDeque<>();\n\n    private static void printer() {\n        while (Boolean.TRUE) {\n            System.out.println(\"Añade un docmento o selecciona la opción imprimir/salir\");\n            Scanner scanner = new Scanner(System.in);\n            String input = scanner.nextLine();\n\n            switch (input) {\n                case \"imprimir\":\n                    if (documents.size()>0) {\n                        System.out.println(documents.poll());\n                    }\n                    System.out.println(\"No hay documentos para imprimir\");\n                    break;\n                case \"salir\":\n                    scanner.close();\n                    System.exit(0);\n                    break;\n                default:\n                    documents.add(input);\n                    break;\n            }\n\n            System.out.println(\"Cola de impresión: \" + documents);\n        }\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/java/eulogioep.java",
    "content": "import java.util.Scanner;\n\n// Implementación de la Pila (Stack - LIFO)\nclass Stack {\n    private String[] array;\n    private int top;\n    private int capacity;\n\n    // Constructor\n    public Stack(int size) {\n        array = new String[size];\n        capacity = size;\n        top = -1;\n    }\n\n    // Método para añadir un elemento a la pila\n    public void push(String x) {\n        if (isFull()) {\n            System.out.println(\"Error: Pila llena\");\n            return;\n        }\n        array[++top] = x;\n    }\n\n    // Método para quitar un elemento de la pila\n    public String pop() {\n        if (isEmpty()) {\n            System.out.println(\"Error: Pila vacía\");\n            return null;\n        }\n        return array[top--];\n    }\n\n    // Método para verificar si la pila está vacía\n    public boolean isEmpty() {\n        return top == -1;\n    }\n\n    // Método para verificar si la pila está llena\n    public boolean isFull() {\n        return top == capacity - 1;\n    }\n\n    // Método para obtener el elemento en la cima de la pila sin quitarlo\n    public String peek() {\n        if (isEmpty()) {\n            System.out.println(\"Error: Pila vacía\");\n            return null;\n        }\n        return array[top];\n    }\n}\n\n// Implementación de la Cola (Queue - FIFO)\nclass Queue {\n    private String[] array;\n    private int front;\n    private int rear;\n    private int capacity;\n    private int count;\n\n    // Constructor\n    public Queue(int size) {\n        array = new String[size];\n        capacity = size;\n        front = 0;\n        rear = -1;\n        count = 0;\n    }\n\n    // Método para añadir un elemento a la cola\n    public void enqueue(String x) {\n        if (isFull()) {\n            System.out.println(\"Error: Cola llena\");\n            return;\n        }\n        rear = (rear + 1) % capacity;\n        array[rear] = x;\n        count++;\n    }\n\n    // Método para quitar un elemento de la cola\n    public String dequeue() {\n        if (isEmpty()) {\n            System.out.println(\"Error: Cola vacía\");\n            return null;\n        }\n        String x = array[front];\n        front = (front + 1) % capacity;\n        count--;\n        return x;\n    }\n\n    // Método para verificar si la cola está vacía\n    public boolean isEmpty() {\n        return count == 0;\n    }\n\n    // Método para verificar si la cola está llena\n    public boolean isFull() {\n        return count == capacity;\n    }\n\n    // Método para obtener el primer elemento de la cola sin quitarlo\n    public String peek() {\n        if (isEmpty()) {\n            System.out.println(\"Error: Cola vacía\");\n            return null;\n        }\n        return array[front];\n    }\n}\n\n// Clase principal que contiene los programas de navegador web e impresora\npublic class eulogioep {\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n        \n        // Programa de navegador web\n        Stack backStack = new Stack(100);\n        Stack forwardStack = new Stack(100);\n        String currentPage = \"\";\n\n        System.out.println(\"Simulador de navegador web (escribe 'salir' para terminar):\");\n        while (true) {\n            System.out.print(\"Ingresa una acción o nombre de página web: \");\n            String input = scanner.nextLine().trim().toLowerCase();\n            \n            if (input.equals(\"salir\")) {\n                break;\n            } else if (input.equals(\"atrás\")) {\n                if (!backStack.isEmpty()) {\n                    forwardStack.push(currentPage);\n                    currentPage = backStack.pop();\n                    System.out.println(\"Página actual: \" + currentPage);\n                } else {\n                    System.out.println(\"No hay páginas anteriores\");\n                }\n            } else if (input.equals(\"adelante\")) {\n                if (!forwardStack.isEmpty()) {\n                    backStack.push(currentPage);\n                    currentPage = forwardStack.pop();\n                    System.out.println(\"Página actual: \" + currentPage);\n                } else {\n                    System.out.println(\"No hay páginas siguientes\");\n                }\n            } else {\n                if (!currentPage.isEmpty()) {\n                    backStack.push(currentPage);\n                }\n                forwardStack = new Stack(100);  // Limpia la pila de adelante\n                currentPage = input;\n                System.out.println(\"Página actual: \" + currentPage);\n            }\n        }\n\n        // Programa de impresora compartida\n        Queue printQueue = new Queue(100);\n\n        System.out.println(\"\\nSimulador de impresora compartida (escribe 'salir' para terminar):\");\n        while (true) {\n            System.out.print(\"Ingresa un nombre de documento o 'imprimir': \");\n            String input = scanner.nextLine().trim().toLowerCase();\n            \n            if (input.equals(\"salir\")) {\n                break;\n            } else if (input.equals(\"imprimir\")) {\n                String document = printQueue.dequeue();\n                if (document != null) {\n                    System.out.println(\"Imprimiendo: \" + document);\n                }\n            } else {\n                printQueue.enqueue(input);\n                System.out.println(\"Documento añadido a la cola: \" + input);\n            }\n        }\n\n        scanner.close();\n    }\n}"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/java/frangarmez21.java",
    "content": "import java.util.*;\n\npublic class frangarmez21 {\n\n    public static final String NUEVA_WEB = \"nueva web\";\n    static Scanner sc = new Scanner(System.in);\n\n    public static void main(String[] args) {\n\n        System.out.println(\"##Ejercicios de pilas y colas##\");\n        /*\n         * EJERCICIO:\n         * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n         * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n         * o lista (dependiendo de las posibilidades de tu lenguaje).\n         */\n        System.out.println(\"##Implementando los mecanismos de introducción y recuperación de elementos.##\");\n        System.out.println();\n        System.out.println(\"##Las pilas (stacks - LIFO)##\");\n        ArrayList stack = new ArrayList();\n        System.out.println(\"1-Añadimos elementos a la pila.\");\n        stack.add(1);\n        stack.add(2);\n        stack.add(3);\n        System.out.println(\"2-Tenemos la siguiente pila: \" + stack);\n        System.out.println(\"3-Quitamos elementos de la pila.\");\n        while (!stack.isEmpty()) {\n            stack.removeLast();\n        }\n        System.out.println(\"4-Resultado de desapilar: \" + stack);\n        System.out.println();\n        System.out.println(\"##Las colas (queue - FIFO)##\");\n        ArrayList queue = new ArrayList();\n        System.out.println(\"1-Añadimos elementos a la cola\");\n        queue.add(1);\n        queue.add(2);\n        queue.add(3);\n        System.out.println(\"2-Tenemos la siguiente cola: \" + queue);\n        System.out.println(\"3-Quitamos elementos de la cola\");\n        while (!queue.isEmpty()) {\n            queue.removeFirst();\n        }\n        System.out.println(\"4-Resultado de desencolar: \" + queue);\n        System.out.println();\n        System.out.println(\"##Dificultad Extra##\");\n        System.out.println();\n\n        /*\n         * DIFICULTAD EXTRA (opcional):\n         * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n         *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n         *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n         *   Las palabras \"adelante\", \"atras\" desencadenan esta acción, el resto se interpreta como\n         *   el nombre de una nueva web.\n         */\n        System.out.println(\"Simula el mecanismo adelante/atrás de un navegador web:\");\n        System.out.println();\n        webBrowser();\n\n         /* - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n         *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n         *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n         *   interpretan como nombres de documentos.\n         */\n        System.out.println();\n        System.out.println(\"Simula el mecanismo de una impresora:\");\n        System.out.println();\n        printer();\n    }\n\n    private static void printer() {\n        ArrayList printQueue = new ArrayList<>();\n        System.out.println(\"Introduce acción para el navegador (imprimir|nombre de documento a encolar):\");\n        String action = sc.nextLine();\n        while (!action.isBlank()) {\n            if (action.contains(\"imprimir\")) {\n                if (printQueue.isEmpty()) {\n                    System.out.println(\"No hay documentos para imprimir\");\n                    action = sc.nextLine();\n                } else {\n                    String printElement = printQueue.removeFirst().toString();\n                    System.out.println(\"Se imprime: \" + printElement + \". Quedan \" + printQueue.size() + \" documentos\");\n                    action = sc.nextLine();\n                }\n            } else {\n                printQueue.add(action);\n                System.out.println(\"Se añade a la cola de impresión el documento: \" + action);\n                action = sc.nextLine();\n            }\n        }\n    }\n\n    private static void webBrowser() {\n        int position = 0;\n        ArrayList webs = new ArrayList<>();\n        webs.add(\"Primera_página\");\n        webs.add(\"Segunda_página\");\n\n        System.out.println(\"Estás en: \" + webs.get(position));\n        //Para salir del programa basta con darle a Enter cuando pide acción\n        System.out.println(\"Introduce acción para el navegador (adelante|atras|nombre de nueva pagina):\");\n        String word = sc.nextLine();\n        while (!word.isBlank()) {\n            if (!(word.contains(\"adelante\") || word.contains(\"atras\"))) {\n                webs.add(word);\n                System.out.println(\"Continuas en: \" + webs.get(position) + \" y se añade la página: \" + word);\n                word = sc.nextLine();\n            } else {\n                position = action(word, position);\n                System.out.println(\"Estás en: \" + webs.get(position));\n                word = sc.nextLine();\n            }\n        }\n\n    }\n\n    private static int action(String word, int position) {\n        switch (word) {\n            case \"adelante\":\n                position++;\n                break;\n\n            case \"atras\":\n                position--;\n                break;\n        }\n        return position;\n    }\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/java/julian98789.java",
    "content": "\n\n\nimport java.util.ArrayList;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.Scanner;\n\npublic class reto_7 {\n\n    private static Scanner input = new Scanner(System.in);\n    private static Stack<String> historial = new Stack<>();\n    private static Stack<String> adelante = new Stack<>();\n    private static Queue<String> palabra = new Queue<>();\n\n    public static void main(String[] args) {\n        // Prueba de la pila\n        Stack<Integer> stack = new Stack<>();\n        stack.push(1);\n        stack.push(2);\n        stack.push(3);\n        System.out.println(\"Pila después de insertar 1, 2, 3: \" + stack);\n        System.out.println(\"Elemento retirado de la pila: \" + stack.pop());\n        System.out.println(\"Pila después de retirar un elemento: \" + stack);\n\n        // Prueba de la cola\n        Queue<Integer> queue = new Queue<>();\n        queue.enqueue(1);\n        queue.enqueue(2);\n        queue.enqueue(3);\n        System.out.println(\"Cola después de insertar 1, 2, 3: \" + queue);\n        System.out.println(\"Elemento retirado de la cola: \" + queue.dequeue());\n        System.out.println(\"Cola después de retirar un elemento: \" + queue + \" \\n\");\n\n        // Problema 1: Navegación de páginas\n        historial.push(\"www.pagina1.com\");\n        historial.push(\"www.pagina2.com\");\n        historial.push(\"www.pagina3.com\");\n\n        while (true) {\n            System.out.println(\"Ingresa a donde te quieres dirigir en la pagina\");\n            System.out.println(\"Escribe: adelante, para ir a otra pagina\");\n            System.out.println(\"Escribe: atras, para ir a la pagina anterior\");\n            System.out.println(\"Escribe: impresora, para ingresar al reto de la impresora\");\n            System.out.println(\"Escribe: salir, para salir\");\n            String valor = input.nextLine().toLowerCase();\n\n            switch (valor) {\n                case \"adelante\":\n                    navegarAdelante();\n                    break;\n                case \"atras\":\n                    navegarAtras();\n                    break;\n                case \"impresora\":\n                while (true) {\n                    \n                    // problema 2: impresora\n                    System.out.println(\"Ingresa la palabra 'imprimir' para imprimir el elemento en la consulo \");\n                    System.out.println(\"Ingresa una parabra diferento y se guardara como un archivo para inprimir\");\n                    String palabras = input.nextLine().toLowerCase();\n\n                    imprimir(palabras);\n                }\n                case \"salir\":\n                    System.out.println(\"Saliendo del navegador.\");\n                    input.close();\n                    return;\n                default:\n                    navegarNuevaPagina(valor);\n                    break;\n            }\n\n        }\n\n    }\n\n    private static void imprimir(String palabras) {\n        String calve = \"imprimir\".toLowerCase();\n\n        if (palabras.equals(calve) ) {\n        \n            System.out.println(\"Imprimir: \" + palabra.dequeue());\n\n        } else {\n            palabra.enqueue(palabras);\n            System.out.println(\"Palabra agregada con exito: \" + palabra);\n        }\n    }\n\n    public static void navegarAdelante() {\n        if (adelante.isEmpty()) {\n            System.out.println(\"No hay página siguiente para mostrar.\");\n        } else {\n            String pagina = adelante.pop();\n            historial.push(pagina);\n            System.out.println(\"Navegando adelante a: \" + pagina);\n        }\n    }\n\n    public static void navegarAtras() {\n        if (historial.size() < 2) {\n            System.out.println(\"No hay página anterior para mostrar.\");\n        } else {\n            String paginaActual = historial.pop();\n            adelante.push(paginaActual);\n            String paginaAnterior = historial.peek();\n            System.out.println(\"Navegando atrás a: \" + paginaAnterior);\n        }\n    }\n\n    public static void navegarNuevaPagina(String pagina) {\n        historial.push(pagina);\n        System.out.println(\"Navegando a nueva página: \" + pagina);\n        // Limpiamos la pila de adelante porque se considera una nueva navegación\n        adelante = new Stack<>();\n    }\n\n    // Implementación de la pila (stack)\n    static class Stack<T> {\n        private List<T> elements = new ArrayList<>();\n\n        public void push(T element) {\n            elements.add(element);\n        }\n\n        public T pop() {\n            if (elements.isEmpty()) {\n                throw new RuntimeException(\"La pila está vacía\");\n            }\n            return elements.remove(elements.size() - 1);\n        }\n\n        public T peek() {\n            if (elements.isEmpty()) {\n                throw new RuntimeException(\"La pila está vacía\");\n            }\n            return elements.get(elements.size() - 1);\n        }\n\n        public int size() {\n            return elements.size();\n        }\n\n        public boolean isEmpty() {\n            return elements.isEmpty();\n        }\n\n        @Override\n        public String toString() {\n            return elements.toString();\n        }\n    }\n}\n\n// Implementación de la cola (queue) genérica\nclass Queue<T> {\n    private List<T> elements = new LinkedList<>();\n\n    public void enqueue(T element) {\n        elements.add(element);\n    }\n\n    public T dequeue() {\n        if (elements.isEmpty()) {\n            throw new RuntimeException(\"La cola está vacía\");\n        }\n        return elements.remove(0);\n    }\n\n    @Override\n    public String toString() {\n        return elements.toString();\n    }\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/java/kleyner098.java",
    "content": "import java.util.Arrays;\nimport java.util.Scanner;\n\npublic class kleyner098 {\n\n    public static void main(String[] args) {\n\n        /*\n         * EJERCICIO:\n         * Implementa los mecanismos de introducción y recuperación de elementos propios\n         * de las pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una\n         * estructura de array o lista (dependiendo de las posibilidades de tu\n         * lenguaje).\n         */\n\n        Pila<Integer> pila = new Pila();\n        pila.apilar(1);\n        pila.apilar(2);\n        pila.apilar(3);\n        System.out.println(\"Pila : \" + pila);\n        pila.desapilar();\n        pila.desapilar();\n        System.out.println(\"Pila : \" + pila);\n        Cola<Integer> cola = new Cola();\n        cola.encolar(1);\n        cola.encolar(2);\n        cola.encolar(3);\n        System.out.println(\"Cola :\" + cola);\n        cola.desencolar();\n        cola.desencolar();\n        System.out.println(\"Cola :\" + cola);\n\n        /*\n         * DIFICULTAD EXTRA (opcional):\n         * - Utilizando la implementación de pila y cadenas de texto, simula el\n         * mecanismo adelante/atrás de un navegador web. Crea un programa en el que\n         * puedas navegar a una página o indicarle que te quieres desplazar adelante o\n         * atrás, mostrando en cada caso el nombre de la web.\n         * Las palabras \"adelante\", \"atras\" desencadenan esta acción, el resto se\n         * interpreta como el nombre de una nueva web.\n         * - Utilizando la implementación de cola y cadenas de texto, simula el\n         * mecanismo de una impresora compartida que recibe documentos y los imprime\n         * cuando así se le indica.\n         * La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n         * interpretan como nombres de documentos.\n         */\n\n        impresora();\n        navegar();\n    }\n\n    static void navegar() {\n        // variables\n        Scanner sc = new Scanner(System.in);\n        Pila<String> historial = new Pila();\n        String pagina;\n        String ultimaPagina = \"\";\n\n        // Bucle que acaba cuando se escriba salir\n        do {\n            System.out.println(\n                    \"Escriba la url de la página, \\\"Adelante \\\" para avanzar de página ,\\\"Atras \\\" para retrocer de página o \\\"Salir\\\" para cerrar el programa\");\n            pagina = sc.nextLine();\n\n            // Condición para avanzar de página\n            if (pagina.equalsIgnoreCase(\"adelante\")) {\n                if (!(ultimaPagina.isEmpty())) {\n                    historial.apilar(ultimaPagina);\n                    System.out.println(\"Página: \" + historial.cima() + \"\\n\");\n                    ultimaPagina = \"\";\n                } else {\n                    System.out.println(\"No hay más páginas para avanzar\\n\");\n                }\n\n                // Condición para retroceder de página\n            } else if (pagina.equalsIgnoreCase(\"atras\")) {\n\n                if (historial.size() > 0) {\n                    ultimaPagina = historial.desapilar();\n                    String mensaje = (historial.size() > 0) ? \"Página: \" + historial.cima()\n                            : \"No hay páginas en el historial para retroceder\";\n                    System.out.println(mensaje + \"\\n\");\n                } else {\n                    System.out.println(\"No hay páginas en el historial para retroceder\\n\");\n                }\n\n            } else {\n                historial.apilar(pagina);\n                System.out.println(\"Página actual: \" + historial.cima() + \"\\n\");\n            }\n\n        } while (!(pagina.equalsIgnoreCase(\"salir\")));\n\n        System.out.println(\"Cerrando navegador\");\n        \n    }\n\n    static void impresora() {\n        // Variables\n        Scanner sc = new Scanner(System.in);\n        Cola<String> impresora = new Cola();\n        String documento;\n        String imprimiendo;\n\n        // Bucle que acaba cuando se escriba salir\n        do {\n            System.out.println(\n                    \"Introduzaca el nombre del documento que quiere imprimir, escriba la \\\"Imprimir\\\" para imprimir el documento o \\\"Salir \\\" para cerrar el programa\");\n            documento = sc.nextLine();\n\n            // Condición para imprimir\n            if (documento.equalsIgnoreCase(\"imprimir\")) {\n                // Condición que imprime si la impresora tiene documentos\n                if (impresora.size() > 0) {\n                    imprimiendo = impresora.desencolar();\n                    System.out.println(\"Imprimiendo documento: \" + imprimiendo);\n                } else {\n                    System.out.println(\"No hay documento en la cola de la impresora\");\n                }\n            } else {\n                if (!(documento.equalsIgnoreCase(\"salir\"))) {\n                    impresora.encolar(documento);\n                }\n\n            }\n            System.out.println(\"Documentos en la cola de la impresora: \" + impresora + \"\\n\");\n        } while (!(documento.equalsIgnoreCase(\"salir\")));\n        System.out.println(\"Apagando impresora\");\n        \n    }\n}\n\nclass Pila<T> {\n    private T[] pila;\n\n    Pila() {\n        pila = (T[]) new Object[0];\n    }\n\n    public void apilar(T elemento) {\n        pila = Arrays.copyOf(pila, pila.length + 1);\n        pila[pila.length - 1] = elemento;\n    }\n\n    public T desapilar() {\n        T eliminado = pila[pila.length - 1];\n        pila = Arrays.copyOf(pila, pila.length - 1);\n        return eliminado;\n    }\n\n    @Override\n    public String toString() {\n        return Arrays.toString(pila);\n    }\n\n    public int size() {\n        return pila.length;\n    }\n\n    public T cima() {\n        return pila[pila.length - 1];\n    }\n}\n\nclass Cola<T> {\n    private T[] cola;\n\n    Cola() {\n        cola = (T[]) new Object[0];\n    }\n\n    public void encolar(T elemento) {\n        cola = Arrays.copyOf(cola, cola.length + 1);\n        cola[cola.length - 1] = elemento;\n    }\n\n    public T desencolar() {\n        T eliminado = cola[0];\n        System.arraycopy(cola, 1, cola, 0, cola.length - 1);\n        cola = Arrays.copyOf(cola, cola.length - 1);\n        return eliminado;\n    }\n\n    @Override\n    public String toString() {\n        return Arrays.toString(cola);\n    }\n\n    public int size() {\n        return cola.length;\n    }\n\n    public T finalCola() {\n        return cola[cola.length - 1];\n    }\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/java/lautarorisso.java",
    "content": "import java.util.LinkedList;\nimport java.util.Queue;\nimport java.util.Stack;\n\npublic class LogicaJava07 {\n    \n    public static void main(String[] args) {\n        \n        // 1.\n        \n        // Queue\n        Queue<String> cola = new LinkedList<>();\n\n        cola.add(\"Cliente 1\");\n        cola.add(\"Cliente 2\");\n\n        cola.poll(); // elimina el primero\n\n        System.out.println(cola);\n\n        // Stack\n        Stack<Integer> pila = new Stack<>();\n\n        pila.push(10);\n        pila.push(20);\n\n        pila.pop(); // elimina el último\n\n        System.out.println(pila);\n        \n    }\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/java/matinbohorquez.java",
    "content": "import java.util.LinkedList;\nimport java.util.Queue;\nimport java.util.Scanner;\nimport java.util.Stack;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\n/**\n * #07 PILAS Y COLAS\n *\n * @author martinbohorquez\n */\npublic class matinbohorquez {\n    private static final String DOMAIN_REGEX = \"^(?:https?:\\\\/\\\\/)?(?:www\\\\.)?((?:[a-zA-Z0-9\\\\-]+\\\\.)+[a-zA-Z]{2,})(\\\\/[^\\\\s]*)?$\";\n    private static final Pattern DOMAIN_PATTERN = Pattern.compile(DOMAIN_REGEX);\n    /**\n     * Pila / Stack (LIFO)\n     */\n    private static Stack<Integer> pila = new Stack<>();\n    /**\n     * Cola / Queue (FIFO)\n     */\n    private static Queue<Integer> cola = new LinkedList<>();\n\n    private static void webNavigator() {\n        Stack<String> stack = new Stack<>();\n        Stack<String> stackBackup = new Stack<>();\n\n        outterLoop:\n        while (true) {\n            Scanner scanner = new Scanner(System.in);\n            System.out.print(\"\"\"\n                    -----------------------------------------------------------\n                    Bienvenido al navegador web, ingresar una de las siguientes opciones:\n                    1. Escribir una URL válida para navegar a una página web.\n                    2. \"adelante\" - para regresar a una página posterior.\n                    3. \"atrás\" - para regresar a una página anterior.\n                    4. \"salir\" - para cerrar el navegador.\n                    -----------------------------------------------------------\n                    \"\"\");\n            System.out.print(\"Ingresar su opción: \");\n            String action = scanner.nextLine();\n\n            switch (action) {\n                case \"salir\" -> {\n                    System.out.println(\"Saliendo del navegador web!\");\n                    break outterLoop;\n                }\n                case \"adelante\" -> {\n                    if (!stackBackup.isEmpty()) stack.push(stackBackup.pop());\n                }\n                case \"atrás\" -> {\n                    if (!stack.isEmpty()) stackBackup.push(stack.pop());\n                }\n                default -> {\n                    String formattedURL = formatURL(action);\n                    String lastUrl = stack.isEmpty() ? null : stack.getLast();\n                    if (formattedURL != null && !formattedURL.equals(lastUrl)) stack.push(formattedURL);\n                    stackBackup = new Stack<>();\n                }\n            }\n            if (!stack.isEmpty()) System.out.printf(\"Has navegado a la web: %s%n\", stack.getLast());\n            else System.out.println(\"Página de inicio!\");\n        }\n    }\n\n    private static String formatURL(String input) {\n        Matcher matcher = DOMAIN_PATTERN.matcher(input);\n        StringBuilder result = new StringBuilder();\n\n        if (matcher.find()) {\n            // Captura el dominio completo sin el protocolo, 'www.' y el path\n            String domain = matcher.group(1);\n            String path = matcher.group(2);\n\n            // Verifica si el protocolo está presente, si no, añádelo\n            if (!input.startsWith(\"http://\") && !input.startsWith(\"https://\")) result.append(\"http://\");\n\n            // Verifica si 'www.' está presente, si no, añádelo\n            if (!\"www.\".contains(input)) result.append(\"www.\");\n\n            // Añade el dominio capturado\n            result.append(domain);\n            if (path != null) result.append(path);\n            return result.toString();\n        } else {\n            System.out.printf(\"Formato del URL inválido: '%s'%n\", input);\n            return null;\n        }\n    }\n\n    public static void printer() {\n        Queue<String> cola = new LinkedList<>();\n\n        outterLoop:\n        while (true) {\n            Scanner scanner = new Scanner(System.in);\n            System.out.print(\"\"\"\n                    -----------------------------------------------------------\n                    Bienvenido a la impresora, ingresar una las siguientes opciones:\n                    1. Añadir un documento, escribir el nombre del documento.\n                    2. \"imprimir\" - para imprimir el documento en cola.\n                    3. \"salir\" - para cerrar la impresora.\n                    -----------------------------------------------------------\n                    \"\"\");\n            System.out.print(\"Ingresar su opción: \");\n            String action = scanner.nextLine();\n\n            switch (action) {\n                case \"imprimir\" -> {\n                    if (!cola.isEmpty())\n                        System.out.printf(\"Imprimiendo documento: %s%n\", cola.poll());\n                    else System.out.println(\"No hay documentos para imprimir!\");\n                }\n                case \"salir\" -> {\n                    break outterLoop;\n                }\n                default -> cola.offer(action);\n            }\n            System.out.println(cola);\n        }\n    }\n\n\n    public static void main(String[] args) {\n        //stack\n        pila.push(1);\n        pila.push(2);\n        pila.push(3);\n        System.out.println(\"La pila nueva es: \" + pila);\n        System.out.printf(\"Se elimina el elemento %d de la pila!%n\", pila.pop());\n        System.out.println(\"La pila actualizada es: \" + pila);\n        //queue\n        cola.offer(10);\n        cola.offer(20);\n        cola.offer(30);\n        System.out.println(\"La cola nueva es: \" + cola);\n        System.out.printf(\"Se elimina el elemento %d de la cola!%n\", cola.poll());\n        System.out.println(\"La pila actualizada es: \" + cola);\n\n        /*\n         * DIFICULTAD EXTRA\n         */\n        webNavigator();\n        printer();\n\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/java/miguelex.java",
    "content": "import java.util.Stack;\nimport java.util.Queue;\nimport java.util.LinkedList;\nimport java.util.Scanner;\n\npublic class miguelex{\n    public static void main(String[] args){\n        Stack<Integer> pila = new Stack<Integer>();\n        Queue<Integer> cola = new LinkedList<Integer>();\n        \n        pila.push(1);\n\n        System.out.println(\"Pila: \" + pila);\n        pila.push(2);\n        pila.push(3);\n        System.out.println(\"\\nPila: \" + pila);\n        pila.pop();\n        System.out.println(\"\\nPila: \" + pila);\n\n        cola.add(1);\n        System.out.println(\"\\nCola: \" + cola);\n        cola.add(2);\n        cola.add(3);\n        System.out.println(\"\\nCola: \" + cola);\n        cola.poll();\n        System.out.println(\"\\nCola: \" + cola);\n\n        Stack<String> pilaNavegacion = new Stack<String>();\n        Queue<String> colaImpresion = new LinkedList<String>();\n\n        Scanner sc = new Scanner(System.in);\n        String url = \"\";\n\n        System.out.println(\"Simulando navegador:\");\n        while(!url.equals(\"salir\")){\n            System.out.println(\"Ingrese la URL a visitar: \");\n            url = sc.nextLine();\n            switch (url){\n                case \"atras\":\n                    if(pilaNavegacion.size() > 1){\n                        colaImpresion.add(pilaNavegacion.pop());\n                        System.out.println(\"Se ha regresado a la página: \" + pilaNavegacion.peek());\n                    }else{\n                        System.out.println(\"No hay páginas para regresar\");\n                    }\n                    break;\n                case \"adelante\":\n                    if(colaImpresion.size() > 0){\n                        pilaNavegacion.push(colaImpresion.poll());\n                        System.out.println(\"Se ha avanzado a la página: \" + pilaNavegacion.peek());\n                    }else{\n                        System.out.println(\"No hay páginas para avanzar\");\n                    }\n                    break;\n                case \"salir\":\n                    System.out.println(\"Saliendo del navegador\");\n                    break;\n                default:\n                    pilaNavegacion.push(url);\n                    System.out.println(\"Se ha visitado la página: \" + pilaNavegacion.peek());\n                    break;\n            }\n        }\n        System.out.println(\"Simulando cola de impresion\");\n        String documento = \"\";\n\n        while(!documento.equals(\"salir\")){\n            System.out.println(\"Ingrese el documento a imprimir: \");\n            documento = sc.nextLine();\n            if(!documento.equals(\"salir\")){\n                switch (documento){\n                    case \"imprimir\":\n                        if(colaImpresion.size() > 0){\n                            System.out.println(\"Imprimiendo documento: \" + colaImpresion.poll());\n                        }else{\n                            System.out.println(\"No hay documentos para imprimir\");\n                        }\n                        break;\n                    case \"salir\":\n                        System.out.println(\"Saliendo de la cola de impresion\");\n                        break;\n                    default:\n                        colaImpresion.add(documento);\n                        System.out.println(\"Se ha agregado el documento: \" + documento + \" a la cola de impresion\");\n                        break;\n                }\n            }\n        }\n\n    }\n}"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/java/simonguzman.java",
    "content": "import java.util.Stack;\nimport java.util.Queue;\nimport java.util.*;\n\npublic class simonguzman {\n    public static void main(String[] args) {\n        //Pilas\n        Stack<String> books = new Stack<>();\n        //Agregando elementos a la piila\n        books.push(\"Cien años de soledad\");\n        books.push(\"El amor en los tiempos del colera\");\n        books.push(\"El pianista del gueto de varsovia\");\n        //Monstrando la pila\n        System.out.println(books);\n        //Mostrar el ultimo elemento de la pila, el ultimo que entro en esta\n        System.out.println(\"Ultimo elemento de la pila: \"+ books.peek());\n        //Eliminar el ultimo elemento de la pila, el ultimo que entro\n        books.pop();\n        //Mostrar la pila actualizada\n        System.out.println(books);\n        //Buscar la posicion del elemento en la pila\n        System.out.println(\"Posicion del libro: \"+books.search(\"Cien años de soledad\"));\n\n        //Colas\n        Queue<String> cola = new LinkedList<>();\n        //Añadir elementos a la cola\n        cola.add(\"Simon\");\n        cola.add(\"Julian\");\n        cola.add(\"Camilo\");\n        //Mostrar la cola\n        System.out.println(cola);\n        //Remover elemento\n        cola.remove();\n        System.out.println(cola);\n        //Alternativa a remover elemento\n        cola.poll();\n        System.out.println(cola);\n        //Consultar el primer elemento de la cola\n        System.out.println(cola.element());\n        System.out.println(cola.peek());\n        //Tamaño de la cola\n        System.out.println(cola.size());\n\n        navegadorWeb();\n        impresora();\n\n\n    }\n\n    public static void navegadorWeb(){\n        Stack<String> historial = new Stack<>();\n        Scanner sc = new Scanner(System.in);\n        int index = -1;\n        String opcion;\n        do{\n            System.out.println(\"Ingrese pagina, adelante, atras, o salir: \");\n            opcion = sc.next();\n            if(opcion.equals(\"pagina\")){\n                index = ingresarPagina(historial);\n            }else{\n                index = opcionesNavegador(historial, opcion, index);\n            }\n        }while(!opcion.equals(\"salir\"));\n        \n    }\n\n    public static int opcionesNavegador(Stack<String> pila, String opcion, int index){\n        switch (opcion) {\n            case \"adelante\":\n            index = accionAdelante(pila, index);\n                break;\n            case \"atras\":\n            index = accionDetras(pila, index);\n            break;\n            case \"salir\":\n            System.out.println(\"Saliendo del programa.....\");\n            break;\n            default:\n            System.out.println(\"Opcion no valida\");\n                break;\n        }\n        return index;\n    }\n\n    public static int ingresarPagina(Stack<String> pila){\n        Scanner sc = new Scanner(System.in);\n        System.out.println(\"Ingrese la url de la pagina: \");\n        String pagina = sc.next();\n        pila.push(pagina);\n        System.out.println(\"Has navegado a: \"+pagina);\n        return pila.size()-1;\n    }\n\n    public static int accionAdelante(Stack<String> pila, int index){\n        if(validarPilaVacia(pila)){\n            if(index < pila.size() - 1){\n                index++;\n                System.out.println(\"Link de pagina: \"+pila.get(index));\n            }else{\n                System.out.println(\"No hay mas historial hacia adelante\\n\");\n                //index = pila.size() - 1;\n            }\n        }else{\n            System.out.println(\"No hay historial\");\n        }\n        return index;\n    }\n\n    public static int accionDetras(Stack<String> pila, int index){\n        if(validarPilaVacia(pila)){\n            if(index > 0){\n                index--;\n                System.out.println(\"Link de pagina: \"+pila.get(index));\n            }else{\n                System.out.println(\"No hay mas historial hacia atras\\n\");\n            }\n        }else{\n            System.out.println(\"No hay ningun historial\");\n        }\n        return index;\n    }\n\n    public static boolean validarPilaVacia(Stack<String> pila){\n        return !pila.isEmpty();\n    }\n\n    public static void impresora(){\n        Queue<String> cola = new LinkedList<>();\n        Scanner sc = new Scanner(System.in);\n        String opcion;\n        do{\n            System.out.println(\"Ingrese agregar, imprimir o salir: \");\n            opcion = sc.next();\n            opcionesImpresora(cola, opcion);\n        }while(!opcion.equals(\"salir\"));\n    }\n\n    public static void opcionesImpresora(Queue<String> cola, String opcion){\n        switch (opcion) {\n            case \"agregar\":\n                agregarImpresion(cola);\n                break;\n            case \"imprimir\":\n                imprimir(cola);\n                break;\n            case \"salir\":\n                System.out.println(\"Saliendo del programa...\");\n                break;\n            default:\n            System.out.println(\"Opcion no valida...\");\n                break;\n        }\n    }\n\n    public static void agregarImpresion(Queue<String> cola){\n        Scanner sc = new Scanner(System.in);\n        System.out.println(\"Ingrese el documento a imprimir: \");\n        String documento = sc.next();\n        cola.add(documento);\n    }\n\n    public static void imprimir(Queue<String> cola){\n        if (validarColaVacia(cola)) {\n            String doc= cola.poll();\n            System.out.println(cola);\n            System.out.println(\"Imprimiendo: \"+ doc);\n        }else{\n            System.out.println(\"La cola de impresion esta vacia\");\n        }\n    }\n\n    public static boolean validarColaVacia(Queue<String> cola){\n        return !cola.isEmpty();\n    }\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/7R0N1X.js",
    "content": "// Pila\nvar pila = []\n\npila.push(1)\npila.push(2)\npila.push(3)\n\n// console.log(pila)\n\npila.pop()\n\n// console.log(pila)\n\n// Cola\nvar cola = []\n\ncola.push('a')\ncola.push('b')\ncola.push('c')\n\n// console.log(cola)\n\ncola.shift()\n\n// console.log(cola)\n\n/*\nUtilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\nde un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\nque te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\nLas palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\nel nombre de una nueva web.\n */\n\nlet readline = require('readline')\nlet rl = readline.createInterface({ input: process.stdin, output: process.stdout })\natras = []\nadelante = []\n\n\nfunction web_navigation() {\n\n  rl.question('Ingresa una url o interactua con palabras \"adelante\", \"atras\" o \"salir\": ', (answer) => {\n    let inputFormat = answer.trim().toLowerCase()\n\n    switch (inputFormat) {\n      case 'adelante':\n        atras.push(adelante.pop())\n        currentPage(atras)\n        web_navigation()\n        break\n      case 'atras':\n        if (isEmpty(atras)) {\n          currentPage(atras)\n          web_navigation()\n        } else {\n          adelante.push(atras.pop())\n          currentPage(atras)\n          web_navigation()\n        }\n        break\n      case 'salir':\n        rl.close()\n        break\n      default:\n        adelante = []\n        atras.push(inputFormat)\n        currentPage(atras)\n        web_navigation()\n        break\n    }\n  })\n\n}\n\nfunction isEmpty(pila) {\n  return pila.length === 0\n}\n\nfunction currentPage(pila) {\n  return isEmpty(pila) ? console.log('Estás en la página de inicio') : console.log(`Estas en la web ${pila[pila.length - 1]}`)\n}\n\n// web_navigation()\n\n/*\nUtilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\nimpresora compartida que recibe documentos y los imprime cuando así se le indica.\nLa palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\ninterpretan como nombres de documentos.\n*/\n\ncola = []\n\nfunction printer() {\n\n  printQueue(cola)\n\n  rl.question('Ingresa un documento o elige \"imprimir\" o \"salir\": ', (answer) => {\n    let inputFormat = answer.trim().toLowerCase()\n\n    switch (inputFormat) {\n      case 'imprimir':\n        if (cola.length === 0) {\n          console.log('No hay documentos en cola para imprimir.')\n          printer()\n        } else {\n          console.log(`\\n Imprimiendo ${cola.shift()}`)\n          printer()\n        }\n        break\n      case 'salir':\n        rl.close()\n        break\n      default:\n        cola.push(inputFormat)\n        printer()\n        break\n    }\n  })\n}\n\nfunction printQueue(cola) {\n  if (cola.length === 0) {\n    console.log('\\n No hay documentos en cola para imprimir.\\n')\n  } else {\n    console.log(`\\n         Cola de impresión`)\n    cola.forEach(document => {\n      console.log(document)\n    })\n    console.log('\\n')\n  }\n}\n\nprinter()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/AChapeton.js",
    "content": "//PILAS (STACK)\nvar pila = [1, 2, 3, 4, 5];\nconsole.log('pila original', pila);\n\npila.push(6);\nconsole.log('agregar elemento a la pila en la ultima posicion', pila);\n\npila.pop();\nconsole.log('eliminar el ultimo elemento agregado a la pila', pila);\n\n\n// *COLAS (QUEUE)\nvar cola = ['b', 'c', 'd', 'e', 'f'];\nconsole.log('cola original', cola);\n\ncola.unshift('a');\nconsole.log('agregar elemento a la cola en la ultima posicion (izquierda)', cola);\n\ncola.pop();\nconsole.log('eliminar el ultimo elemento de la cola (elementos que fue agregado primero)', cola);\n\n\n//  *   DIFICULTAD EXTRA\n//  *   Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n//  *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n//  *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n//  *   interpretan como nombres de documentos.\n\nvar documentos = ['cv.txt', 'examen.txt', 'test.txt', 'comandos.txt'];\nvar impresora = [];\n\nconsole.log('agregando a impresora');\nfor (var i = 0; i < documentos.length; i++) {\n    impresora.unshift(documentos[i]);\n    console.log('Cola de impresion: ', impresora);\n}\n\nconsole.log('imprimiendo');\ndo {\n    impresora.pop();\n    console.log('impresiones pendientes: ', impresora);\n} while (impresora.length > 0);\n\n\n//  *   Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n//  *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n//  *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n//  *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n//  *   el nombre de una nueva web.\nvar historial = [];\nvar paginaActual = 0;\n\nvar agregarPagina = function (web) {\n    if (historial.length > 0) {\n        paginaActual++;\n    }\n    historial.push(web);\n};\n\nvar atras = function () {\n    console.log(historial[paginaActual - 1]);\n};\n\nvar adelante = function () {\n    console.log(historial[paginaActual + 1]);\n};\n\nagregarPagina('test.com');\nconsole.log(historial);\n\nagregarPagina('new.com');\nconsole.log(historial);\n\natras();\nconsole.log(historial);\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/ArticKun.js",
    "content": "\n\n/*\n\n⚡⚡ PILAS Y COLAS\n\nEn JavaScript, puedes utilizar un array \npara simular una pila. \n\n\n PILAS / STACK\nLAST IN FIRST OUT (LIFO)\n\nLas operaciones principales en una pila \nson push (añadir un elemento en la cima) \ny pop (eliminar el elemento en la cima).\n\n\n*/\n\n//⚡ LIFO ============================== \nlet pila = [];\n// Añadir elementos a la pila\npila.push(1);\npila.push(2);\npila.push(3);\n// Eliminar el elemento en la cima\n//Y lo recuperamos en una variable\nlet elementoEliminado = pila.pop();\nconsole.log(pila); // Resultado: [1, 2]\nconsole.log(elementoEliminado); // Resultado: 3\n\n/*\n\nQUEUES / COLA \nFIRST IN FIRST OUT (FIFO)\n\nPara implementar una cola en JavaScript, también \npuedes usar un array. Las operaciones principales \nen una cola son push (añadir un elemento al final) \ny shift (eliminar el primer elemento).\n\n*/\n\n\n//⚡ FIFO ============================== \n\nlet cola = [];\n\n// Añadir elementos a la cola\ncola.push(1);\ncola.push(2);\ncola.push(3);\n\n// Eliminar el primer elemento\n//Y lo recuperamos en una variable\nlet primerElemento = cola.shift();\n\nconsole.log(cola); // Resultado: [2, 3]\nconsole.log(primerElemento); // Resultado: 1\n\n\n/* DIFICULTAD EXTRA (opcional):\n\n  - 1. Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n    de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n    que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n    Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n    el nombre de una nueva web.\n\n  - 2. Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n    impresora compartida que recibe documentos y los imprime cuando así se le indica.\n    La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n    interpretan como nombres de documentos.\n\n */\n\n    //1. PILA =========================================\n\n    function simuladorNavegadorWeb() {\n      const paginasVisitadas = [];\n      let paginaActual = \"\";\n  \n      while (true) {\n      const comando = prompt(\"Ingrese 'adelante', 'atrás' o el nombre de una nueva página (o 'salir' para terminar): \");\n  \n          if (comando.toLowerCase() === 'salir') {\n              console.log(\"Saliendo del simulador del navegador.\");\n              break;\n          } else if (comando.toLowerCase() === 'adelante') {\n              if (paginaActual) {\n                  console.log(`Avanzar a la página actual: ${paginaActual}`);\n              } else {\n                  console.log(\"No hay página actual\");\n              }\n          } else if (comando.toLowerCase() === 'atrás') {\n              if (paginasVisitadas.length > 0) {\n                  const paginaAnterior = paginasVisitadas.pop();\n                  console.log(`Retroceder a la página: ${paginaAnterior}`);\n                  paginaActual = paginaAnterior;\n              } else {\n                  console.log(\"No hay páginas anteriores\");\n              }\n          } else {\n              paginasVisitadas.push(paginaActual);\n              paginaActual = comando;\n              console.log(`Ir a la página: ${paginaActual}`);\n          }\n      }\n  };\n  \n\n// Ejecutar el simulador del navegador\n  simuladorNavegadorWeb();\n  \n    \n// 2. COLA ===================================================\n\nconst colaDocumentos = [];\n\nconst agregarDocumento = (documento) => {\n    colaDocumentos.push(documento);\n    console.log(`Documento '${documento}' agregado a la cola.`);\n};\n\nconst imprimirDocumento = () => {\n    if (colaDocumentos.length > 0) {\n        const documentoAImprimir = colaDocumentos.shift();\n        console.log(`Imprimiendo documento: '${documentoAImprimir}'`);\n    } else {\n        console.log(\"La cola de documentos está vacía. No hay documentos para imprimir.\");\n    }\n};\n\n\nwhile (true) {\n    const comando = prompt(\"Ingrese 'imprimir' o el nombre de un nuevo documento (o 'salir' para terminar): \");\n\n    if (comando.toLowerCase() === 'salir') {\n        console.log(\"Saliendo del simulador de impresora compartida.\");\n        break;\n    } else if (comando.toLowerCase() === 'imprimir') {\n        imprimirDocumento();\n    } else {\n        agregarDocumento(comando);\n    }\n};\n\n\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/CesarCarmona30.js",
    "content": "/**\n * EJERCICIO\n */\n\n// PILA\nlet stack = [];\n\n// Push\nstack.push('Cucumber');\nstack.push('Radish');\nstack.push('Tomato');\nstack.push('Orange');\nstack.push('Apple');\n\nconsole.table(stack);\n\n// Pop\nstack.pop()\nconsole.table(stack);\nstack.pop()\nconsole.table(stack);\n\n// COLA\nlet queue = [];\n\n// Enqueue\nqueue.push('Banana');\nqueue.push('Melon');\nqueue.push('Strawberry');\nqueue.push('Onion');\nqueue.push('Garlic');\nconsole.table(queue);\n\n// Dequeue\nqueue.shift();\nconsole.table(queue);\nqueue.shift();\nconsole.table(queue);\n\n//PILA - Navegador\n//COLA - Impresora\n\nclass WebBrowser {\n  constructor() {\n    this.pages = [];\n    this.index = null\n    this.currentPage = null;\n  }\n\n  addPage(page) {\n    this.pages.push(page);\n    this.index = this.pages.length - 1;\n    this.currentPage = this.pages[this.index];\n  }\n\n  goForward() {\n    this.currentPage = this.pages[this.index++];\n    if (this.currentPage != undefined) {\n      return this.currentPage;\n    }\n    this.index--;\n    console.error('Sin referencia de página adelante');\n    return '-';\n  }\n\n  goBackward() {\n    try {\n      this.currentPage = this.pages[this.index--];\n      return this.currentPage;\n    } catch (error) {\n      this.index++;\n      console.error('Sin páginas en el historial');\n      return '-';\n    }\n  }\n}\n\nfunction browserHistory(browser, input) {\n    let page;\n    console.log(`>_${input}`);\n    switch (input) {\n      case 'adelante':\n        page = browser.goForward();\n        console.log(`Página actual: ${page}`);\n        break;\n      case 'atras':\n        page = browser.goBackward();\n        console.log(`Página actual: ${page}`);\n        break;\n      case 'salir':\n        break;\n      default:\n        let new_page = input;\n        browser.addPage(new_page);\n        console.log(`Nueva página: ${new_page}`);\n        break;\n  }\n}\n\nconst edge = new WebBrowser();\nbrowserHistory(edge, 'Wikipedia');\nbrowserHistory(edge, 'YouTube');\nbrowserHistory(edge, 'Amazon');\nbrowserHistory(edge, 'atras');\nbrowserHistory(edge, 'atras');\nbrowserHistory(edge, 'adelante');"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/DAVstudy.js",
    "content": "/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n\nlet myStack = [];\n\n// stack  Last In, First Out (LIFO)\n\nmyStack.push(1)\nmyStack.push(2)\nmyStack.push(3)\n\nconsole.log(myStack);\nmyStack.pop()\nconsole.log(myStack);\n\n// queue First In, FirstOut (FIFO)\n\nlet myQueue = []\n\nmyQueue.push(1)\nmyQueue.push(2)\nmyQueue.push(3)\n\nconsole.log(myQueue);\nmyQueue.shift()\nconsole.log(myQueue)\n\n\n/*\n* Navegacion Adelante y Atras\n* - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n*   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n*   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n*   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n*   el nombre de una nueva web.\n*/\n\nconst browser = {\n    currentWeb : '',\n    backHistory : [],\n    fowardHistory : [],\n    addHistory : function (str) { \n        if (this.backHistory.length === 0 && this.currentWeb === '') {\n            this.currentWeb = str\n            return this.currentWeb\n        }\n        this.backHistory.push(this.currentWeb)\n        this.currentWeb = str\n        return this.currentWeb\n    },\n    backforward : function () {\n        // Si existe una pagina actual y si la pila aun tiene un elemento que no sea igual al actual, quiere decir que podemos volver atras\n        if (this.currentWeb !== '' && this.checkHistory(this.backHistory)) {\n            this.fowardHistory.push(this.currentWeb) // Quitamos de la cola la pagina actual y la guardamos en la pila fowardsHistory\n            this.currentWeb = this.backHistory.pop() // Actualizamos la pagina actual y la retornamos\n            return this.currentWeb\n        }\n        return 'No hay historial'\n    },\n    forward : function () {\n       // Si existe una pagina actual y si la pila aun tiene un elemento que no sea igual al actual, quiere decir que podemos ir hacia delante\n        if (this.currentWeb !== '' && this.checkHistory(this.fowardHistory)) {\n            this.backHistory.push(this.currentWeb) // Almacenamos la pagina actual en la pila backforward\n            this.currentWeb = this.fowardHistory.pop() // obtenemos la nueva pagina actual de la pila foward y se quita de fowardHistory\n            return this.currentWeb\n        }\n        return 'No hay historial'\n\n    },\n    checkHistory : (stack) => stack.length === 0 ? false : true\n}\n\n\nconst readline = require(\"readline\");\nconst read = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout,\n});\n\nconst menu = () => {\n    read.question(\n        `browser: `,\n        (option = (option) => {\n        switch (option) {\n            case \"adelante\":\n                console.log(browser.forward())\n                console.log('Pagina actual: ' + browser.currentWeb);\n                menu()\n                break;\n            case \"atras\":\n                console.log(browser.backforward())\n                console.log('Pagina actual: ' + browser.currentWeb);\n                menu()\n                break;\n            default:\n                browser.addHistory(option)\n                console.log('Pagina actual: ' + browser.currentWeb);\n                menu()\n                break;\n        }\n        })\n    );\n}\n\n//menu()\n\n/*\n* - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n*   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n*   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n*   interpretan como nombres de documentos.\n*/\n\nconst printer = {\n    queue : [],\n    addDocument : function (str) {this.queue.push(str)},\n    printDocument : function () {return this.queue.length === 0 ? 'No hay documentos en cola' : this.queue.shift()}\n}\n\n\nconst menuPrinter = () => {\n    read.question(\n        `Impresora, esperando nueva instruccion: `,\n        (option = (option) => {\n        switch (option) {\n            case \"imprimir\":\n                console.log(printer.printDocument())\n                menuPrinter()\n                break;\n            default:\n                printer.addDocument(option)\n                console.log(printer.queue)\n                menuPrinter()\n                break;\n        }\n        })\n    );\n}\n\n//menuPrinter()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/Dan-Corbo.js",
    "content": "/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atras\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n\n\n\n/* Soluciones */\n\n\n// Estructuras\n\n\nclass Pila {\n  constructor() {\n    this.pila = [];\n  }\n\n  apilar(elemento) {\n    this.pila.push(elemento);\n  }\n\n  desapilar() {\n    return this.pila.pop();\n  }\n\n  estaVacia() {\n    return this.pila.length === 0;\n  }\n}\n\n\n// Ejemplo de uso\n\nconst miPila = new Pila();\n\nmiPila.apilar(\"Hola\");\nmiPila.apilar(\"Mundo\");\nmiPila.apilar(\"!\");\n\nconsole.log(`Primer elemento: ${miPila.desapilar()}`); // Salida: !\nconsole.log(`Segundo elemento: ${miPila.desapilar()}`); // Salida: Mundo\nconsole.log(`¿Pila vacía?: ${miPila.estaVacia()}`); // Salida: false\nconsole.log(`Último elemento: ${miPila.desapilar()}`); // Salida: Hola\nconsole.log(`¿Pila vacía?: ${miPila.estaVacia()}`); // Salida: true\n\n\nclass Cola {\n  constructor() {\n    this.cola = [];\n  }\n\n  encolar(elemento) {\n    this.cola.push(elemento);\n  }\n\n  desencolar() {\n    return this.cola.shift();\n  }\n\n  estaVacia() {\n    return this.cola.length === 0;\n  }\n}\n\n\n// Ejemplo de uso\n\nconst miCola = new Cola();\n\nmiCola.encolar(\"Primero\");\nmiCola.encolar(\"Segundo\");\nmiCola.encolar(\"Tercero\");\n\nconsole.log(`Primer elemento: ${miCola.desencolar()}`); // Salida: Primero\nconsole.log(`Segundo elemento: ${miCola.desencolar()}`); // Salida: Segundo\nconsole.log(`¿Cola vacía?: ${miCola.estaVacia()}`); // Salida: false\nconsole.log(`Último elemento: ${miCola.desencolar()}`); // Salida: Tercero\nconsole.log(`¿Cola vacía?: ${miCola.estaVacia()}`); // Salida: true\n\n\n\n/* Extra - Opcional */\n\n\n\n// Navegador Web\n\n\nclass NavegadorWeb {\n  constructor() {\n    this.historial = new Pila();\n    this.paginaActual = null;\n  }\n\n  navegar(url) {\n    if (this.paginaActual) {\n      this.historial.apilar(this.paginaActual);\n    }\n    this.paginaActual = url;\n  }\n\n  adelante() {\n    if (!this.historial.estaVacia()) {\n      this.paginaActual = this.historial.desapilar();\n    }\n  }\n\n  atras() {\n    if (!this.historial.estaVacia()) {\n      const aux = this.historial.desapilar();\n      this.paginaActual = this.historial.desapilar();\n      this.historial.apilar(aux);\n    }\n  }\n\n  mostrarPaginaActual() {\n    console.log(`Página actual: ${this.paginaActual}`);\n  }\n}\n\nconst navegador = new NavegadorWeb();\n\nnavegador.navegar(\"www.google.com\");\nnavegador.navegar(\"www.youtube.com\");\nnavegador.navegar(\"www.facebook.com\");\n\nnavegador.mostrarPaginaActual(); // Salida: Página actual: www.facebook.com\n\nnavegador.atras();\n\nnavegador.mostrarPaginaActual(); // Salida: Página actual: www.youtube.com\n\nnavegador.adelante();\n\nnavegador.mostrarPaginaActual(); // Salida: Página actual: www.facebook.com\n\n\n\n// Impresora Compartida\n\n\nclass Impresora {\n  constructor() {\n    this.colaImpresion = new Cola();\n  }\n\n  imprimir() {\n    if (!this.colaImpresion.estaVacia()) {\n      console.log(`Imprimiendo documento: ${this.colaImpresion.desencolar()}`);\n    }\n  }\n\n  agregarDocumento(nombreDocumento) {\n    this.colaImpresion.encolar(nombreDocumento);\n  }\n}\n\nconst impresora = new Impresora();\n\nimpresora.agregarDocumento(\"documento1.pdf\");\nimpresora.agregarDocumento(\"documento2.docx\");\nimpresora.agregarDocumento(\"documento3.jpg\");\n\n\n// Ejemplo de uso\n\nwhile (true) {\n  const comando = prompt(\"Introduzca comando (imprimir, nombre_documento): \");\n\n  if (comando === \"imprimir\") {\n    impresora.imprimir();\n  } else {\n    impresora.agregarDocumento(comando);\n  }\n}\n\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/DavidMoralesDeveloper.js",
    "content": "// stacks - LIFO last out, pila\n\nlet stack = [];\nstack.push(1);\nstack.push(2);\nstack.push(3);\nconsole.log(stack);\nstack.pop();\nconsole.log(stack);\n\nfunction peek(stack) {\n  return stack[stack.length - 1];\n}\nconsole.log(peek(stack));\n\n// stack fifo first out cola queue\nlet cola = [];\ncola.push(11);\ncola.push(12);\ncola.push(13);\nconsole.log(cola);\ncola.shift();\nconsole.log(cola);\n\n//Extra\n\n// - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n//  *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n//  *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n//  *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n//  *   el nombre de una nueva web.\n\n//pila - last in first out \n//la pila de estack siempre elimina al ultimo , no guarda el elemento eliminado, solo puedes agregar y eliminar en un sentido\n\nconst readline = require(\"readline\");\n\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout,\n});\n\n\n//sigue bajando amigo ==================================>>>>>>>>>>>\n\n// function web() { //primer intento\n//     let stack = []; // no me guardaba el push :(\n\n//   rl.question(\n//     \"añade una url , o interactua con las palabras adelante/atras/historial/salir : \",\n//     (palabra) => {\n      \n    //   if (palabra == \"salir\") {\n    //     console.log(\"estas saliendo de el programa\");\n    //     return rl.close();\n    //   } else if (palabra == \"adelante\") {\n    //     console.log(\"adelante\");\n    //     web();\n    //   } else if (palabra == \"atras\") {\n    //     console.log(\" pagina de  atras\");\n    //     web();\n    //   } else if (palabra == \"historial\") {\n    //     console.log(stack);\n    //     web();\n    //   } else {\n    //     stack.push(palabra);\n    //     console.log(` bienvenido a la pagina web :  ${palabra} ${stack}`);\n    //     web();\n    //   }\n//     }\n//   );\n// }\n\n// web();\n\n\nfunction webNavigation() {\n    const stack = [];\n  \n    function processInput(action) {\n      if (action === 'salir') {\n        console.log('Saliendo del navegador web.');\n        rl.close();\n        return;\n      } else if (action === 'adelante') {\n        console.log('La función adelante no está implementada no se puede por que el pop elimina el ultimo elemeto .');\n      } else if (action === 'atrás') {\n        if (stack.length > 0) {\n          const poppedUrl = stack.pop();\n          console.log(`Has regresado a la web: ${poppedUrl}`);\n        } else {\n          console.log('No hay páginas anteriores en el historial.');\n        }\n      } else {\n        stack.push(action);\n        console.log(`Has navegado a la web: ${action}`);\n      }\n    }\n  \n    function promptUser() {\n      rl.question('Añade una url o interactúa con palabras adelante/atrás/salir: ', (action) => {\n        processInput(action);\n        if (action !== 'salir') {\n          promptUser(); // Llamada recursiva\n        }\n      });\n    }\n  \n    promptUser();\n  }\n  \n  // webNavigation();\n\n\n\n//   - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n//  *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n//  *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n//  *   interpretan como nombres de documentos.\n\nfunction impresora () {\n\n  let archivos = []\n\n  \n\n    function imprimir (respuesta) {\n      if(respuesta === 'salir'){\n        console.log('saliendo de la impresora')\n        rl.close()\n        return;\n      }else if(respuesta === 'imprimir') {\n        if(archivos.length <=0 ){\n          console.log('esta vacio la impresora introduce un archivo')\n        }else{\n          const archivoAImprimir = archivos.shift()\n          console.log(archivoAImprimir + 'se esta imprimiendo')\n        }\n        \n      }else {\n        console.log(`${respuesta} fue añadiada a la cola de la impresora`)\n        archivos.push(respuesta)\n        console.log(archivos)\n      }\n    }\n\n    function archivosEnCola () {\n    rl.question('añade un documento  o selecciona  imprimir/salir  : ', (respuesta) => {\n\n      imprimir(respuesta)\n      if(respuesta !== 'salir'){\n        archivosEnCola()\n      }\n\n    })\n\n  }\n\n  archivosEnCola()\n\n}\n\nimpresora()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/Deyvid-10.js",
    "content": "// pilas (stacks - LIFO)\n\nlet pila = [1, 2, 3]\n\npila.push(4) // push - Agrega un elemento al tope de la pila\nconsole.log(pila);\npila.pop() // pop - Elimina el elemento en el tope de la pila\nconsole.log(pila);\nconsole.log(pila[pila.length-1]); // peek - Devuelve el elemento en el tope de la pila sin eliminarlo\nconsole.log(pila.length === 0); // isEmpty - Comprueba si la pila está vacía\n\n// colas (queue - FIFO)\n\nlet cola = [1, 2, 3]\n\ncola.push(4) // enqueue - Agrega un elemento al final de la cola\nconsole.log(cola);\ncola.shift() // dequeue - Elimina el primer elemento de la cola\nconsole.log(cola);\nconsole.log(cola[0]); // front - Devuelve el primer elemento de la cola sin eliminarlo\nconsole.log(cola.length === 0); // isEmpty - Comprueba si la cola está vacía"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/DjSurgeon.js",
    "content": "/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n\n// stack - LIFO: Last In, First Out\n\nconst arr = [0,1,2,3,4,5];\n\nconst lastIn = (num) => {\n    arr.push(num);\n    console.log(arr);\n}\nconst firstOut = () => {\n    arr.pop();\n    console.log(arr);\n}\n// lastIn(8); output => [0,1,2,3,4,5,8]\n// firstOut(); output => [0,1,2,3,4,5]\n\n// queue - FIFO: First In, First Out\n\nconst firstIn = (num) => {\n    arr.unshift(num);\n    console.log(arr);\n}\n\n// firstIn(8); output => [8,1,2,3,4,5];\n// firstOut(); output => [8,1,2,3,4];\n\n/*\n* En la pila (stack) el último en llegar es el primero en salir, su analogia seria una pila de platos.\n* En la cola (queue) uno llega por un extremo y el otro sale por el otro extremo, su analogia seria una cola en el supermercado.\n*/\n\nconst webs = [\"inicio\"];\nlet index = 0;\nconst paginaWeb = (string) => {\n    if (string === \"adelante\") {\n        index++;\n        console.log(webs[index])\n    } else if (string===\"atras\") {\n        index--;\n        console.log(webs[index])\n    } else if (string) {\n        webs.push(string);\n        console.log(webs);\n    }\n}\n/* \npaginaWeb(\"55\");\npaginaWeb(\"0\");\npaginaWeb(\"adelante\");\npaginaWeb(\"adelante\");\npaginaWeb(\"atras\");\npaginaWeb(\"adelante\");\n*/\n\nconst documentos = [\"lista\", \"dibujo\", \"redacción\"];\n\nconst impresora = (string) => {\n    if (string === \"imprimir\") {\n        console.log(`Imprimiendo: ${documentos[documentos.length-1]}`)\n        documentos.pop();\n    } else if (string) {\n        documentos.unshift(string);\n        console.log(`Lista de documentos: ${documentos}`);\n    }\n}\n/*\nimpresora(\"cv\");\nimpresora(\"imprimir\");\nimpresora(\"nuevo cv\");\n*/\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/EloyChavezDev.js",
    "content": "/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n\n// 1. Pila (LIFO)\nclass Pila {\n    constructor() {\n      this.pila = [];\n    }\n  \n    // Agregar un elemento a la pila\n    push(elemento) {\n      this.pila.push(elemento);\n    }\n  \n    // Sacar un elemento de la pila\n    pop() {\n      return this.pila.pop();\n    }\n  \n    // Ver el último elemento de la pila sin sacarlo\n    peek() {\n      return this.pila[this.pila.length - 1];\n    }\n  \n    // Ver si la pila está vacía\n    estaVacia() {\n      return this.pila.length === 0;\n    }\n  }\n  \n  // Ejemplo de uso\n  const pila = new Pila();\n  pila.push(\"Elemento 1\");\n  pila.push(\"Elemento 2\");\n  pila.push(\"Elemento 3\");\n  \n  // Imprime [\"Elemento 3\", \"Elemento 2\", \"Elemento 1\"]\n  console.log(\"Pila:\", pila); \n  \n  // Imprime \"Elemento 3\"\n  const elementoSacado = pila.pop();\n  console.log(\"Elemento sacado:\", elementoSacado); \n  \n  // Imprime [\"Elemento 2\", \"Elemento 1\"]\n  console.log(\"Pila:\", pila); \n  \n  // Imprime false\n  console.log(\"¿La pila está vacía?:\", pila.estaVacia()); \n\n//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n  // 2. Cola (FIFO)\nclass Cola {\n  constructor() {\n    this.cola = [];\n  }\n\n  // Agregar un elemento a la cola\n  enqueue(elemento) {\n    this.cola.push(elemento);\n  }\n\n  // Sacar un elemento de la cola\n  dequeue() {\n    return this.cola.shift();\n  }\n\n  // Ver el primer elemento de la cola sin sacarlo\n  peek() {\n    return this.cola[0];\n  }\n\n  // Ver si la cola está vacía\n  estaVacia() {\n    return this.cola.length === 0;\n  }\n}\n\n// Ejemplo de uso\nconst cola = new Cola();\ncola.enqueue(\"Elemento 1\");\ncola.enqueue(\"Elemento 2\");\ncola.enqueue(\"Elemento 3\");\n\n// Imprime [\"Elemento 1\", \"Elemento 2\", \"Elemento 3\"]\nconsole.log(\"Cola:\", cola); \n\n// Imprime \"Elemento 1\"\nconst elementoSacado = cola.dequeue();\nconsole.log(\"Elemento sacado:\", elementoSacado); \n\n// Imprime [\"Elemento 2\", \"Elemento 3\"]\nconsole.log(\"Cola:\", cola); \n\n// Imprime false\nconsole.log(\"¿La cola está vacía?:\", cola.estaVacia()); \n\n//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n// Simulación de Navegación Web con Pila y Cadenas de Texto\n\n// Implementación de Pila\nclass Pila {\n    constructor() {\n      this.pila = [];\n    }\n  \n    // Agregar un elemento a la pila\n    push(elemento) {\n      this.pila.push(elemento);\n    }\n  \n    // Sacar un elemento de la pila\n    pop() {\n      return this.pila.pop();\n    }\n  \n    // Ver el último elemento de la pila sin sacarlo\n    peek() {\n      return this.pila[this.pila.length - 1];\n    }\n  \n    // Ver si la pila está vacía\n    estaVacia() {\n      return this.pila.length === 0;\n    }\n  }\n\n // Simulación de Navegación\n const pilaPaginas = new Pila(); // Pila para almacenar las páginas visitadas\nlet paginaActual = \"\"; // Página actual\n\n// Función para navegar a una nueva página\nfunction navegar(nuevaPagina) {\n  if (paginaActual !== \"\") {\n    pilaPaginas.push(paginaActual); // Guarda la página actual en el historial\n  }\n  paginaActual = nuevaPagina;\n  console.log(`Navegando a: ${paginaActual}`);\n}\n\n// Función para ir hacia atrás\nfunction irAtras() {\n  if (!pilaPaginas.estaVacia()) {\n    paginaActual = pilaPaginas.pop();\n    console.log(`Moviendo hacia atrás a: ${paginaActual}`);\n  } else {\n    console.log(\"No hay páginas en el historial\");\n  }\n}\n\n// Función para ir hacia adelante\nfunction irAdelante() {\n  if (!pilaPaginas.estaVacia()) {\n    paginaActual = pilaPaginas.pop();\n    console.log(`Moviendo hacia adelante a: ${paginaActual}`);\n  } else {\n    console.log(\"No hay páginas por delante\");\n  }\n}\n\n// Ejemplo de uso\nnavegar(\"Google\");\nnavegar(\"Facebook\");\nnavegar(\"YouTube\");\n\nirAtras(); // YouTube -> Facebook\nirAtras(); // Facebook -> Google\n\nirAdelante(); // Facebook\nirAdelante(); // YouTube\n\n/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n// Simulación de Impresora Compartida con Cola y Cadenas de Texto\n\n// Implementación de Cola\nclass Cola {\n    constructor() {\n      this.cola = [];\n    }\n  \n    // Agregar un elemento a la cola\n    enqueue(elemento) {\n      this.cola.push(elemento);\n    }\n  \n    // Sacar un elemento de la cola\n    dequeue() {\n      return this.cola.shift();\n    }\n  \n    // Ver el primer elemento de la cola sin sacarlo\n    peek() {\n      return this.cola[0];\n    }\n  \n    // Ver si la cola está vacía\n    estaVacia() {\n      return this.cola.length === 0;\n    }\n  }\n\n  //  Simulación de Impresora\n  const colaImpresion = new Cola(); // Cola para almacenar los documentos a imprimir\n\n// Función para imprimir un documento\nfunction imprimir() {\n  if (!colaImpresion.estaVacia()) {\n    const documento = colaImpresion.dequeue();\n    console.log(`Imprimiendo documento: ${documento}`);\n  } else {\n    console.log(\"No hay documentos para imprimir\");\n  }\n}\n\n// Función para añadir un documento a la cola de impresión\nfunction agregarDocumento(documento) {\n  colaImpresion.enqueue(documento);\n  console.log(`Documento \"${documento}\" añadido a la cola de impresión`);\n}\n\n// Ejemplo de uso\nagregarDocumento(\"Documento 1\");\nagregarDocumento(\"Documento 2\");\nagregarDocumento(\"Documento 3\");\n\nimprimir(); // Imprimiendo documento: Documento 1\nimprimir(); // Imprimiendo documento: Documento 2\n\nagregarDocumento(\"Documento 4\");\n\nimprimir(); // Imprimiendo documento: Documento 3\nimprimir(); // Imprimiendo documento: Documento 4"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/FabianRpv.js",
    "content": "// Pilas y Colas \n\n// Pilas - Stacks (LIFO \"Last In First Out\")\n\nclass Pila {\n    constructor() {\n        this.elementos = []; // Array para almacenar los elementos de la pila\n    }\n\n    // Añadir un elemento al tope de la pila\n    push(elemento) {\n        this.elementos.push(elemento);\n    }\n\n    // Eliminar y devolver el elemento en el tope de la pila\n    pop() {\n        if (this.isEmpty()) {\n            return \"La pila está vacía\";\n        }\n        return this.elementos.pop();\n    }\n\n    // Ver el elemento en el tope sin eliminarlo\n    peek() {\n        if (this.isEmpty()) {\n            return \"La pila está vacía\";\n        }\n        return this.elementos[this.elementos.length - 1];\n    }\n\n    // Verificar si la pila está vacía\n    isEmpty() {\n        return this.elementos.length === 0;\n    }\n\n    // Tamaño de la pila\n    size() {\n        return this.elementos.length;\n    }\n}\n\nlet pila = new Pila();\npila.push(10);\npila.push(20);\npila.push(30);\n\nconsole.log(pila.peek()); // 30\nconsole.log(pila.pop());  // 30\nconsole.log(pila.pop());  // 20\nconsole.log(pila.isEmpty()); // false\nconsole.log(pila.size()); // 1\n\n\n\n\n// Colas - Queues (FIFO \"First In First Out\")\n\nclass Cola {\n    constructor() {\n        this.elementos = []; // Array para almacenar los elementos de la cola\n    }\n\n    // Añadir un elemento al final de la cola\n    enqueue(elemento) {\n        this.elementos.push(elemento);\n    }\n\n    // Eliminar y devolver el elemento al frente de la cola\n    dequeue() {\n        if (this.isEmpty()) {\n            return \"La cola está vacía\";\n        }\n        return this.elementos.shift();\n    }\n\n    // Ver el elemento al frente sin eliminarlo\n    front() {\n        if (this.isEmpty()) {\n            return \"La cola está vacía\";\n        }\n        return this.elementos[0];\n    }\n\n    // Verificar si la cola está vacía\n    isEmpty() {\n        return this.elementos.length === 0;\n    }\n\n    // Tamaño de la cola\n    size() {\n        return this.elementos.length;\n    }\n}\n\n// Ejemplo de uso\nlet cola = new Cola();\ncola.enqueue(10);\ncola.enqueue(20);\ncola.enqueue(30);\n\nconsole.log(cola.front()); // 10\nconsole.log(cola.dequeue()); // 10\nconsole.log(cola.dequeue()); // 20\nconsole.log(cola.isEmpty()); // false\nconsole.log(cola.size()); // 1"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/FranEspina.js",
    "content": "import * as readline from 'node:readline/promises';\nimport { stdin as input, stdout as output } from 'node:process'\n\n//Implementación Pila (LIFO)\nclass Pila {\n\n  constructor() {\n    this.pila = []\n  }\n\n  encolar(value){\n    this.pila.push(value)\n  }\n\n  desencolar(){\n    return this.pila.pop()\n  }\n\n  numero(){\n    return this.pila.length\n  }\n\n  valores(joinStr){\n    let separator = '\\r\\n'\n    if (joinStr){\n      separator = joinStr\n    }\n    let valores = \"\"\n    this.pila.forEach(item => valores += item + separator)\n    return valores\n\n  }\n\n  actual () {\n    if (this.pila.length === 0){\n      return undefined\n    }\n    else{\n      return this.pila[this.pila.length - 1]\n    }\n  }\n\n  reiniciar(){\n    this.pila = []\n  }\n\n}\n\n//Implementación Cola (FIFO)\nclass Cola {\n\n  constructor() {\n    this.cola = []\n  }\n\n  encolar(value){\n    this.cola.push(value)\n  }\n\n  desencolar(){\n    return this.cola.shift()\n  }\n\n  numero(){\n    return this.cola.length\n  }\n\n  valores(){\n    let valores = \"\"\n    this.cola.forEach(item => valores += \"\\r\\n\" + item)\n    return valores\n  }\n\n}\n\n//Implementación de una impresora que usa Colas\nclass Impresora {\n\n  constructor(rl) {\n    this.colaImpresion = new Cola()\n    this.LogImpresion = new Cola()\n    this.rl = rl\n    this.intervalId = null;\n  }\n\n  async encender(){\n\n    console.clear()\n    console.log(\"Impresora activada\")\n    this.LogImpresion.encolar(`${new Date().toISOString()} Impresora conectada y lista para imprimir'`)    \n    this.#impresionPeriodica(5) //Cada cierto tiempo se imprime todo lo que esté pendiente\n    this.#escucharUsuario()\n\n  }\n\n  async #escucharUsuario() {\n    \n    const opcion = await this.rl.question('¿Qué desea hacer? [I]mprimir documento | [L]og Impresion | [D]ocumentos | [S]alir : ') \n    \n    switch(opcion.toUpperCase()){\n\n      case \"I\": \n        await this.#solicitarDocumentoUsuario()\n        break\n\n      case \"L\":\n        console.log(this.LogImpresion.valores())\n        await this.#escucharUsuario()\n        break\n\n      case \"D\":\n        this.LogImpresion.encolar(`${new Date().toISOString()} Solicitado documentos en cola`)\n        if (this.colaImpresion.length == 0){\n          console.log(\"No existen documentos pendientes de imprimir\")\n        }\n        else{\n          console.log(this.colaImpresion.valores())\n        }\n        await this.#escucharUsuario()\n        break\n\n      case \"S\":\n        this.#desconectarYSalir()\n        break\n         \n      default: \n        await this.#escucharUsuario()\n        break  \n    }\n  }\n\n  //Imprime documentos encolados cada cierto tiempo para simular trabajo asíncrono (cada x tiempo imprime solo 1 documento )\n  #impresionPeriodica(seconds) {\n    this.intervalId = setInterval(() => {\n      if (this.colaImpresion.numero() !== 0){\n        var documento = this.colaImpresion.desencolar()\n        this.LogImpresion.encolar(`${new Date().toISOString()} Imprimiendo documento: '${documento}'`)\n      }\n    }, seconds * 1000);\n  } \n\n  async #solicitarDocumentoUsuario() {\n    var opcion = await this.rl.question('Nombre del documento ([S]alir): ')    \n    switch(opcion.toUpperCase()){\n      case \"S\":\n        await this.#escucharUsuario()\n        break\n      default:\n        this.colaImpresion.encolar(opcion)\n        this.LogImpresion.encolar(`${new Date().toISOString()} Documento encolado: '${opcion}'`)    \n        await this.#solicitarDocumentoUsuario()\n        break    \n    }\n  }\n\n  #desconectarYSalir(){\n    clearInterval(this.intervalId)\n    console.log('Impresora desconectada')\n    this.rl.close()\n    globalThis.process.exit()\n  }\n  \n}\n\n//Implementación de un navegador Web que usa Pilas\nclass NavegadorWeb {\n  constructor(rl){\n    this.historial = new Pila() \n    this.paginasNavegadas = new Pila()\n    this.rl = rl\n\n    console.clear()\n    console.log(\"Navegador Web inicializado\")\n  }\n\n  async mostrarNavegador(){\n    \n    var pagina = this.historial.actual()\n    if (pagina){\n      console.log(`\\r\\nPágina actual : ${pagina}`)\n    }\n    else{\n      console.log(`\\r\\nPágina en blanco`)\n    }\n\n    const navegacion = {\n      \"navegar\": (pagina) => {\n        this.historial.encolar(pagina)\n      }, \n      \"delante\": () => {\n        if (this.paginasNavegadas.numero() > 0 ){\n          var pagina = this.paginasNavegadas.desencolar()\n          this.historial.encolar(pagina)\n        }\n        else{\n          console.log('No existe historial por delante\\r\\n')\n        }  \n      }, \n      \"atras\": () => {\n        if (this.historial.numero() > 0){\n          var pagina = this.historial.desencolar()\n          this.paginasNavegadas.encolar(pagina)\n        }\n        else{\n          console.log('No existe historial atrás\\r\\n')\n        }\n      }, \n      \"salir\": () => {\n        console.log('Navegador cerrado por el usuario')\n        this.rl.close()\n        globalThis.process.exit() \n      }\n\n    }\n\n    var pagina = await this.rl.question(`¿a qué página desea navegar${this.#opcionesDeNavegacion()}?:  `)\n    switch(pagina.toUpperCase()){\n      case \"A\": \n        navegacion[\"atras\"]()    \n        break\n\n      case \"D\": \n        navegacion[\"delante\"]()      \n        break\n\n      case \"S\": \n        navegacion[\"salir\"]()      \n        break\n\n      default:\n        navegacion[\"navegar\"](pagina)\n        break\n    }\n\n    await this.mostrarNavegador()\n  }\n\n  #opcionesDeNavegacion () {\n    let opctionesPosibles = []\n    if (this.historial.numero() > 0){\n      opctionesPosibles.push('[A]trás')\n    }\n    if (this.paginasNavegadas.numero() > 0 ){\n      opctionesPosibles.push('[D]elante')\n    }\n    opctionesPosibles.push('[S]alir')\n\n\n    return ` (${opctionesPosibles.join(\" | \")}) `\n  }\n}\n\n\nconst mainUserQuestion = async () => {\n\n  const rl = readline.createInterface({input, output})\n\n  console.clear()\n\n  var option = await rl.question('¿Qué programa desea probar? [I]mpresora | [N]avegador WEB| [S]alir: ')\n  switch (option.toUpperCase()){\n    case \"I\":\n      console.clear()\n      const impresora = new Impresora(rl)\n      impresora.encender()\n      break\n\n    case \"N\": \n      console.clear()\n      const navegador = new NavegadorWeb(rl)\n      navegador.mostrarNavegador()\n      break\n\n    case \"S\": \n      rl.close()\n      console.log('Operación cancelada por el usuario')\n      globalThis.process.exit()\n      break  \n\n    default: \n      await mainUserQuestion()\n  }\n}\n\nmainUserQuestion()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/Glitzypanic.js",
    "content": "// STACK\nlet stack = [];\n\nstack.push(\"persona1\");\nstack.push(\"persona2\");\n\nconsole.log(stack);\n\nstack.pop();\nconsole.log(stack);\n\n// QUEUE\nlet queue = [];\n\nqueue.push(\"persona3\");\nqueue.push(\"persona4\");\n\nconsole.log(queue);\n\nqueue.shift();\nconsole.log(queue);\n\n// EJERCICIO\nstacks = [];\n\nfunction navigation() {\n  let action = prompt(\"Introduzca la acción a realizar: \");\n\n  if (action == \"salir\") {\n    console.log(\"Saliendo del sistema\");\n  } else if (action == \"Adelante\") {\n    pass;\n  } else if (action == \"Atras\") {\n    if (stacks.length > 0) {\n      console.log(\"Regresando a la página anterior\");\n      stacks.pop();\n    }\n  } else {\n    stacks.push(action);\n  }\n\n  if (stacks.length > 0) {\n    console.log(\"Página actual: \" + stacks[stacks.length - 1]);\n  } else {\n    console.log(\"Pagina de inicio\");\n  }\n}\n\nnavigation();\n\n// EJERCICIO\nfunction shared_printed() {\n  let queue = [];\n\n  while (true) {\n    let action = prompt(\"Añade un documento o selecciona imprimir/salir: \");\n\n    if (action == \"salir\") {\n      console.log(\"Apagando impresora\");\n      break;\n    } else if (action == \"imprimir\") {\n      if (queue.length > 0) {\n        console.log(\"Imprimiendo: \" + queue.pop());\n      } else {\n        console.log(\"No hay archivos para imprimir\");\n      }\n    } else {\n      queue.push(action);\n      console.log(\"Documento añadido a la cola de impresión\");\n    }\n  }\n}\n\nshared_printed();\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #07 - JavaScript ->Jesus Antonio Escamilla */\n/**\n * En JavaScript, las pilas y colas son estructuras de datos comúnmente utilizadas para organizar y gestionar elementos.\n * El LIFO (Last In, First Out) es conocido como Pila, se van apilando y sale el ultimo\n * El FIFO (First In, First Out) es conocida como Cola, el primero en entrar a la cola es primero en salir\n */\n\n//-----PILAS(STACKS - LIFO)-----\n\nconst stack = [];\n\n// Introducir elemento en la pila\nfunction pushPila(elemento) {\n   stack.push(elemento);\n}\n\n// Elimina el ultimo elemento de la pila\nfunction pop() {\n   if (stack.length === 0) {\n      return \"La pila está vacía\";\n   }\n   return stack.pop();\n}\n\n// Obtiene el ultimo elemento de la pila no eliminado\nfunction peek() {\n   return stack[stack.length - 1];\n}\n\n// Obtener el tamaño de la pila\nfunction sizePila() {\n   return stack.length;\n}\n\n// Ejemplo de uso de la Pila\npushPila(1);\npushPila(2);\npushPila(3);\npushPila(4);\n\nconsole.log(pop()); // Imprime el 4 que es el elemento eliminado\nconsole.log(peek()); // Imprime el 3 porque es el ultimo elemento de la pila\nconsole.log(sizePila()); // Imprime el tamaño de la pila que es de 3\n\n\n\n//-----COLAS(QUEUES - FIFO)-----\n\nconst enqueue = [];\n\n// Introducir elemento en la cola\nfunction enqueueCola(elemento) {\n   enqueue.push(elemento);\n}\n\n// Elimina el primero elemento de la pila\nfunction dequeue() {\n   if (enqueue.length === 0) {\n      return \"La cola está vacía\";\n   }\n   return enqueue.shift();\n}\n\n// Obtener el primer elemento de la cola sin eliminarlo\nfunction front() {\n   return enqueue[0];\n}\n\n// Obtener el tamaño de la cola\nfunction sizeCola() {\n   return enqueue.length;\n}\n\n// Ejemplo de uso de la Cola\nenqueueCola(1);\nenqueueCola(2);\nenqueueCola(3);\nenqueueCola(4);\n\nconsole.log(dequeue()); // Imprime el 1 que es el elemento eliminado\nconsole.log(front()); // Imprime el 2 porque es el ultimo elemento de la cola\nconsole.log(sizeCola()); // Imprime el tamaño de la cola que es de 3\n\n\n\n\n/**-----DIFICULTAD EXTRA-----*/\n\n/** PILA */\nconst navegadorWeb = {\n   pilaPaginas: [],\n   paginaActual: \"Inicio\",\n\n   ir_A: function(pagina) {\n      this.pilaPaginas.push(this.paginaActual);\n      this.paginaActual = pagina;\n      console.log(`Navegando a: ${this.paginaActual}`);\n   },\n\n   adelante: function() {\n      if (this.pilaPaginas.length > 0) {\n         this.paginaActual = this.pilaPaginas.pop();\n         console.log(`Página siguiente: ${this.paginaActual}`);\n      } else {\n         console.log(\"No hay páginas siguientes\");\n      }\n   },\n\n   atrás: function() {\n      if (this.paginaActual !== \"Inicio\") {\n         this.pilaPaginas.push(this.paginaActual);\n         this.paginaActual = \"Inicio\";\n         console.log(`Página anterior: ${this.paginaActual}`);\n      } else {\n         console.log(\"No hay páginas anteriores\");\n      }\n   }\n};\n\n // Ejemplo para ejecutar el programa\nnavegadorWeb.ir_A(\"Google\");\nnavegadorWeb.ir_A(\"OpenAI\");\nnavegadorWeb.ir_A(\"moureDev\");\nnavegadorWeb.adelante();\nnavegadorWeb.atrás();\n\n\n\n/** COLA */\nconst impresoraCompartida = {\n   colaDocumentos: [],\n\n   recibirDocumento: function(documento) {\n      this.colaDocumentos.push(documento);\n      console.log(`Documento recibido: ${documento}`);\n   },\n\n   imprimir: function() {\n      if (this.colaDocumentos.length > 0) {\n         const documento = this.colaDocumentos.shift();\n         console.log(`Imprimiendo documento: ${documento}`);\n      } else {\n         console.log(\"No hay documentos en la cola para imprimir\");\n      }\n   }\n};\n\n // Ejemplo de uso de la impresoraCompartida\nimpresoraCompartida.recibirDocumento(\"Contrato.pdf\");\nimpresoraCompartida.recibirDocumento(\"Informe.docx\");\nimpresoraCompartida.recibirDocumento(\"Factura.pdf\");\nimpresoraCompartida.imprimir();\nimpresoraCompartida.imprimir();\n\n/**-----DIFICULTAD EXTRA-----*/"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/MatiTC.js",
    "content": "/*\n * EJERCICIO:\n * DIFICULTAD EXTRA (opcional):\n\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n\n// <--- Pila --->\nlet stack = [];\n\n// introducción de datos a la pila\n// se puede aplicar directo sin la funcion. stack.push(element);\nfunction push(element) {\n  stack.push(element);\n}\npush(1); // [1]\nconsole.log(stack);\npush(2); // [1, 2]\nconsole.log(stack);\n\n// recuperar o eliminar elemento\n// elimina el ultimo\nfunction pop() {\n  if (stack.length === 0) {\n    console.log('El stack esta vació');\n    return null;\n  }\n  return stack.pop();\n}\npop(stack)\nconsole.log(stack); // [1]\n\n// <--- Cola --->\nlet queue  = [];\n\nfunction enqueue(element) {\n    queue.push(element);\n}\nenqueue(10)\nconsole.log(queue) // [10]\nenqueue(20)\nconsole.log(queue)// [10, 20]\n\nfunction dequeue() {\n    if (queue.length === 0) {\n        console.log(\"La cola está vacía\");\n        return null;\n    }\n    return queue.shift();\n}\n\ndequeue(queue)\nconsole.log(queue)// [20]\ndequeue(queue)\nconsole.log(queue)//[]\n\n// * DIFICULTAD EXTRA (opcional):\n//<--- historyStack --->\n\n// Creamos una pila vacía para almacenar las páginas web\nlet historialStack = [];\n\nfunction navegador(url){\n    console.log(\"Navegando a \",url)\n    historialStack.push(url)\n}\n// function para retrocedes\nfunction goBack(){\n    if(historialStack.length > 1){\n        historialStack.pop()\n        let paginaAnterior = historialStack.pop()\n        console.log(\"Regresando a:\", paginaAnterior)\n        historialStack.push(paginaAnterior)\n    }else{\n        console.log(\"No hay pagina que regresar\")\n    }\n}\n\nfunction goNext() {\n    if (historialStack.length > 1) {\n        historialStack.pop\n        let nextPage = historialStack.pop();\n        console.log(\"Avanzando a:\", nextPage);\n        historialStack.push(nextPage);\n    } else {\n        console.log(\"No hay página siguiente\");\n    }\n}\n\n\nfunction simuladorWeb(secuencias){\n    secuencias.forEach(secuencia => {\n        if(secuencia === \"->\"){\n            goNext();\n        } else if (secuencia === \"<-\"){\n            goBack();\n        } else {\n            navegador(secuencia)\n        }\n    })\n}\n// Ejemplo de uso\nlet secuencias = [\"www.google.com\",\"->\",\"www.Dofus.com\", \"->\", \"www.Dofus/foro.com\", \"->\",\"www.Dofus/foro/1332\",\"<-\"];\nsimuladorWeb(secuencias);\n\n// <---Cola--->\n\nlet cola = [];\n\nfunction enqueueDocument(documento) {\n    cola.push(documento);\n}\n\nfunction imprimirDocumento() {\n    if (cola.length > 0) {\n        let documentoAImprimir = cola.shift();\n        console.log(\"Imprimiendo el documento:\", documentoAImprimir);\n        console.log(\"Secuencia de impresión:\", JSON.stringify(cola));\n    } else {\n        console.log(\"No hay documentos en espera para imprimir\");\n    }\n}\n\nfunction simuladorImprimir(mandarImprimir) {\n    mandarImprimir.forEach(mandar => {\n        if (mandar === \"imprimir\") {\n            imprimirDocumento();\n        } else {\n            enqueueDocument(mandar);\n            console.log(\"Documento añadido:\", mandar);\n        }\n    });\n    console.log(\"// <---Cola--->\");\n}\n\nlet mandarImprimir = [\"Documento1\", \"imprimir\", \"Documento2\", \"Documento3\", \"Documento4\", \"imprimir\"];\nconsole.log(\"<---------------------->\");\nsimuladorImprimir(mandarImprimir);\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/Nightblockchain30.js",
    "content": "// <<< STACK >>>\nconst stack = [1,2,3,4];\n// Push new Element\nstack.push(5);\nconsole.log(stack);\n// Pop LAST Element\nstack.pop();\nstack.pop();\nstack.pop();\nconsole.log(stack);\n\n\n// <<< QUEUE >>>\nconst queue = [1,2,3,4,5]\n// Push new Element\nqueue.push(6)\nconsole.log(queue);\n// Pop FIRST Element\nqueue.shift();\nqueue.shift();\nqueue.shift();\nconsole.log(queue);\n\n//  *   DIFICULTAD EXTRA\n//  *   Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n//  *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n//  *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n//  *   interpretan como nombres de documentos.\n\nvar documentos = ['cv.txt', 'examen.txt', 'test.txt', 'comandos.txt'];\nvar impresora = [];\n\nconsole.log(\"Agregando documentos a la cola de impresión..\");\nfor (let i = 0; i < documentos.length; i++){\n    impresora.unshift(documentos[i])\n}\nconsole.log(impresora);\n\nconsole.log(\"Imprimiendo los documentos..\");\ndo {\n    impresora.pop();\n    console.log(`Queda por imprimir [${impresora}]`);\n} while (\n    impresora.length > 0\n)\n\n\n//  *   Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n//  *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n//  *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n//  *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n//  *   el nombre de una nueva web.\n\nhistorial = [];\npagina_actual = 0;\n\nlet agregarWeb = function (web){\n    if (historial.length > 0) {\n        pagina_actual++;\n    }\n    historial.push(web)\n}\n\n\n\nlet volverAtras = function(){\n    console.log(historial[pagina_actual - 1]);\n}\n\nlet adelantar = function(){\n    console.log(historial[pagina_actual + 1]);\n}\n\nagregarWeb(\"www.google.com\");\nagregarWeb(\"www.ikea.com\");\nagregarWeb(\"www.marca.com\");\nconsole.log(historial);\n\nvolverAtras();\n\n\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/OmarLand.js",
    "content": "/*\n    * EJERCICIO:\n    * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n    * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n    * o lista (dependiendo de las posibilidades de tu lenguaje).\n*/\n// Pilas\nclass Stack {\n    constructor() {\n      this.stack = [];\n    }\n    \n    push( element ) {\n      this.stack.push( element );\n      return this.stack;\n    }\n    \n    pop() {\n      return this.stack.pop();\n    }\n    \n    peek() {\n      return this.stack[this.stack.length - 1];\n    }\n    \n    size() {\n      return this.stack.length;\n    }\n  \n    print() {\n      console.log(this.stack);\n    }\n  }\n  \n  const stack = new Stack();\n  console.log(stack.size()); // 0\n  console.log(stack.push('John Cena')); // ['John Cena']\n  console.log(stack.push('The Rock')); // ['John Cena', 'The Rock']\n  console.log(stack.size()); // 2\n  stack.print(); // ['John Cena', 'The Rock]\n  console.log(stack.peek()); // 'The Rock'\n  console.log(stack.pop()); // 'The Rock'\n  console.log(stack.peek()); // John Cena\n\n  // Cola\n  class Queue {\n    constructor() {\n      this.queue = [];\n    }\n  \n    enqueue(element) {\n      this.queue.push(element);\n      return this.queue;\n    }\n  \n    dequeue() {\n      return this.queue.shift();\n    }\n  \n    peek() {\n      return this.queue[0];\n    }\n  \n    size() {\n      return this.queue.length;\n    }\n  \n    isEmpty() {\n      return this.queue.length === 0;\n    }\n  \n    print() {\n      return this.queue;\n    }\n  }\n  \n  const queue = new Queue();\n  console.log(queue.enqueue('The Rock')); // ['The Rock']\n  console.log(queue.enqueue('John Cena')); // ['The Rock', 'John Cena']\n  console.log(queue.enqueue('Stone Cold Steve Austin')); // ['The Rock', 'John Cena', 'Stone Cold Steve Austin']\n  console.log(queue.dequeue()); // 'The Rock'\n  console.log(queue.peek()); // 'John Cena'\n  console.log(queue.isEmpty()); // false\n  console.log(queue.print()); // ['John Cena', 'Stone Cold Steve Austin']\n/*\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/Pancratzia.js",
    "content": "/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atras\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n\n/************************ PARTE 1 ************************/\n\n/***** PILAS *****/\n/*\nUna PILA es una estructura de datos que almacena datos en una secuencia. Solo hay una forma para alegrar elementos y estos se incorportanen un orden determinado. Operan bajo la modalidad llamada LIFO, es decir, siempre el último elemento agregado va a ser el primero que saquemos. \nUn ejemplo de pila es el historial del navegador, donde podemos ver que cada página que visitamos se monta encima de la anterior. Esto genera una pila de registros, y podemos volver a ella dando click al botón de \"Volver\" del navegador.\n*/\n/****************/\n\nclass Pila {\n  constructor() {\n    this.pila = [];\n  }\n\n  push(elemento) {\n    this.pila.push(elemento);\n  }\n\n  pop() {\n    this.pila.pop();\n  }\n\n  peek() {\n    return this.pila[this.pila.length - 1];\n  }\n\n  size() {\n    return this.pila.length;\n  }\n\n  print() {\n    return this.pila;\n  }\n}\n\nconst ejemploPila = new Pila();\n\nconsole.log(\n  `Al inicio, la pila está vacía por lo que el size() devolverá 0: ${ejemploPila.size()}`\n);\n\nfor (let i = 0; i < 5; i++) {\n  ejemploPila.push(i);\n}\n\nconsole.log(\n  `Luego del push, la pila tiene ${ejemploPila.size()} elementos, que son: ${ejemploPila.print()}`\n);\nconsole.log(\n  `El peek o primer elemento de la pila es: ${ejemploPila.peek()}. Recuerda que este es el último elemento agregado a la pila.`\n);\n\nejemploPila.pop();\n\nconsole.log(\n  `Luego del pop, la pila tiene ${ejemploPila.size()} elementos, que son: ${ejemploPila.print()}. Su peek ahora es ${ejemploPila.peek()}`\n);\n\n/***** COLAS *****/\n/*\nUna COLA es una estructura de datos que almacena datos en una secuencia. La operacion de inserción de un elemento en la COLA se llama encolar y la operación de extracción de un elemento se llama desencolar. Operan bajo la modalidad llamada FIFO, es decir, siempre el primer elemento agregado va a ser el primero que se extraiga.\nUn ejemplo de cola es la cola de un banco, donde podemos ver que los clientes en la cola son los primeros en ser atendidos. \n*/\n/****************/\n\nclass Cola {\n  constructor() {\n    this.cola = [];\n  }\n\n  encolar(elemento) {\n    this.cola.push(elemento);\n  }\n\n  desencolar() {\n    this.cola.shift();\n  }\n\n  peek() {\n    return this.cola[0];\n  }\n\n  size() {\n    return this.cola.length;\n  }\n\n  print() {\n    return this.cola;\n  }\n}\n\nconst ejemploCola = new Cola();\nconsole.log(\n  `Al inicio, la cola está vacia por lo que el size() devolverá 0: ${ejemploCola.size()}`\n);\n\nfor (let i = 0; i < 5; i++) {\n  ejemploCola.encolar(i);\n}\n\nconsole.log(\n  `Luego del encolar, la cola tiene ${ejemploCola.size()} elementos, que son: ${ejemploCola.print()}`\n);\nconsole.log(\n  `El peek o primer elemento de la cola es: ${ejemploCola.peek()}. Recuerda que este es el primero en ser encolado y el primero que será desencolado.`\n);\nejemploCola.desencolar();\n\nconsole.log(\n  `Luego del desencolar, la cola tiene ${ejemploCola.size()} elementos, que son: ${ejemploCola.print()}. Su peek ahora es ${ejemploCola.peek()}`\n);\n\n/************************ PARTE 2 ************************/\n\nclass NavegadorWeb extends Pila {\n  constructor() {\n    super();\n    this.paginaActual = \"\";\n    this.indexPaginaActual = 0;\n  }\n\n  navegar(pagina) {\n    this.push(pagina);\n    this.paginaActual = pagina;\n    this.indexPaginaActual = this.size() - 1;\n  }\n\n  adelante() {\n    if (this.size() > 0) {\n      this.indexPaginaActual++;\n      this.paginaActual = this.pila[this.indexPaginaActual]\n    } else {\n      console.log(\"No hay historial en este navegador\");\n    }\n  }\n\n  atras() {\n    if (this.size() > 0) {\n        this.indexPaginaActual--;\n        this.paginaActual = this.pila[this.indexPaginaActual]\n    } else {\n      console.log(\"No hay historial en este navegador\");\n    }\n  }\n\n  mostrarPaginaActual(){\n    return this.paginaActual;\n  }\n}\n\nconst navegador = new NavegadorWeb();\n\nnavegador.atras()\nnavegador.adelante() //No hay historial actualmente\n\nnavegador.navegar(\"https://www.google.com\")\nnavegador.navegar(\"https://www.facebook.com\")\nnavegador.navegar(\"https://www.twitter.com\")\nnavegador.navegar(\"https://www.youtube.com\")\nnavegador.navegar(\"https://www.linkedin.com\")\n\nconsole.log(`Tu historial actual es: ${navegador.print()}. Y te encuentras en al página ${navegador.mostrarPaginaActual()}`);\n\nnavegador.atras()\nnavegador.atras()\nnavegador.atras()\nnavegador.atras()\n\nconsole.log(`Ahora te encuentras en la página: ${navegador.mostrarPaginaActual()}`);\n\nnavegador.adelante()\nnavegador.adelante()\nconsole.log(`Ahora te encuentras en la página: ${navegador.mostrarPaginaActual()}`);\n\nnavegador.navegar(\"www.randompage.com\");\n\nconsole.log(`Ahora te encuentras en la página: ${navegador.mostrarPaginaActual()}`);\n\nclass Impresora{\n\n  constructor(){\n    this.cola = new Cola();\n  }\n\n  imprimir(){\n    if(this.cola.size() > 0){\n    console.log(`Imprimiendo el archivo: ${this.cola.peek()}`);\n    this.cola.desencolar();}\n    else{\n      console.log(\"La cola esta vacia\");\n    }\n  }\n\n}\n\n\nconst impresora = new Impresora();\n\nimpresora.cola.encolar(\"Tarea\");\nimpresora.cola.encolar(\"Trabajo\");\nimpresora.cola.encolar(\"Tesis\");\nimpresora.cola.encolar(\"Cuestionario\");\nimpresora.cola.encolar(\"Reporte\");\nimpresora.cola.encolar(\"Foto\");\n\nconsole.log(`La cola tiene ${impresora.cola.size()} elementos, que son: ${impresora.cola.print()}`);\nconsole.log(`El documento a imprimir es ${impresora.cola.peek()}`);\n\nimpresora.imprimir();\nimpresora.imprimir();\n\nconsole.log(`La cola tiene ${impresora.cola.size()} elementos, que son: ${impresora.cola.print()}`);\n\nimpresora.imprimir();\nimpresora.imprimir();\nimpresora.imprimir();\nimpresora.imprimir();\n\nconsole.log(`La cola tiene ${impresora.cola.size()} elementos, que son: ${impresora.cola.print()}`);\n\nimpresora.imprimir(); //Ya que ya no hay elementos, se nos indica que la cola está vacia"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/RaulDoezon.js",
    "content": "/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n*/\n\n// \"+++++++++ EJERCICIO +++++++++\"\nconsole.log(\"+++++++++ PILA +++++++++\");\nvar names = [\"Peter\", \"Felicia\"];\n\nconsole.log(\"La pila inicial:\");\nconsole.log(names);\nconsole.log(\"Se agregan dos elementos:\");\nnames.push(\"MJ\");\nnames.push(\"Gwen\");\nconsole.log(names);\nnames.pop();\nconsole.log(`Se elimina el último elemento:`);\nconsole.log(names);\n\nconsole.log(\"\\n+++++++++ COLA +++++++++\");\nvar numbers = [7, 19, 15];\n\nconsole.log(\"La cola inicial:\");\nconsole.log(numbers);\nnumbers.push(2018);\nnumbers.push(2019);\nconsole.log(\"Se agregan dos nuevos elementos:\");\nconsole.log(numbers);\nnumbers.shift();\nconsole.log(\"Se elimina el primer elemento:\");\nconsole.log(numbers);\n\n// +++++++++ DIFICULTAD EXTRA +++++++++\nconsole.log(\"\\n+++++++++ CONTROLES DEL NAVEGADOR WEB +++++++++\");\nvar pages = [];\n\nfunction previousPage() {\n  if (pages.length > 0) {\n    pages.pop();\n  }\n    \n  if (pages.length >= 1) {\n    alert(`Navegaste a la página anterior: ${pages[pages.length - 1]}`);\n  } else {\n    alert(\"No existe página para retroceder.\");\n  }\n}\n\nfunction nextPage() {\n  alert(\"No fue posible construir la funcionalidad de navegación adelante con los principios de una pila.\");\n}\n\nfunction addPage() {\n  pages.push(controls);\n  alert(`Navegando a la página web \"${controls}\"`);\n}\n\nwhile (controls !== \"Salir\") {\n  var controls = prompt(\"Elige la opción para navegar: \\n[Escribe el nombre de la página] | Atrás | Adelante | Salir\");\n\n  switch (controls) {\n    case \"Atrás\":\n      previousPage();\n      break;\n\n    case \"Adelante\":\n      nextPage();\n      break;\n\n    case \"Salir\":\n      alert(\"Cerrando el navegador...\");\n      break;\n\n    default:\n      addPage();\n      break;\n  }\n}\n\nconsole.log(\"\\n+++++++++ IMPRESORA +++++++++\");\nvar documents = [];\n\nfunction printDocument() {\n  if (documents.length > 0) {\n    var printDocument = documents.shift();\n    alert(`El documento \"${printDocument}\" fue impreso.`);\n  } else {\n    alert(\"No hay documentos en la cola.\");\n  }\n}\n\nfunction sendDocument() {\n  documents.push(instruction);\n  alert(`El documento \"${documents[documents.length -1]}\" se envió a la cola.`);\n}\n\nwhile (instruction !== \"Salir\") {\n  var instruction = prompt(\"Escribe la acción que debe realizar la impresora: \\n[Escribe el nombre del documento a enviar] | Imprimir | Salir\");\n\n  switch (instruction) {\n    case \"Imprimir\":\n      printDocument();\n      break;\n\n    case \"Salir\":\n      alert(\"Apagando la impresora...\");\n      break;\n\n    default:\n      sendDocument();\n      break;\n  }\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/RicJDev.js",
    "content": "//EJERCICIO\n//LIFO. Last in first out: el ultimo en entrar es el primero en salir\nlet miStack = [1, 2, 3, 4];\nconsole.log(\"\\n---PILAS (STACKS - LIFO)---\");\nconsole.log(\"Antes de agregar elemento: \\n\", miStack);\nmiStack.push(5);\nconsole.log(\"Agregando elemento: \\n\", miStack);\nmiStack.pop();\nconsole.log(\"Después de quitar elemento: \\n\", miStack);\n\n//FIFO. First in first out: el primero en entrar es el primero en salir\nlet miQueue = [1, 2, 3, 4];\nconsole.log(\"\\n---COLAS (QUEUE - FIFO)---\");\nconsole.log(\"Antes de agregar elemento: \\n\", miQueue);\nmiQueue.push(5);\nconsole.log(\"Agregando elemento: \\n\", miQueue);\nmiQueue.shift();\nconsole.log(\"Después de quitar elemento: \\n\", miQueue);\n\n//EXTRA\nconst readline = require(\"readline\");\nconst rl = readline.createInterface({\n\tinput: process.stdin,\n\toutput: process.stdout,\n});\n\nlet navegador = () => {\n\tlet pila = [];\n\n\tfunction muestraPagina() {\n\t\tif (pila.length > 0) {\n\t\t\tconsole.log(`\\nAhora estás en ${pila[pila.length - 1]}`);\n\t\t} else {\n\t\t\tconsole.log(\"\\nEstás en la HomePage\");\n\t\t}\n\n\t\tmuestraOpciones();\n\t}\n\n\tfunction muestraOpciones() {\n\t\trl.question(\n\t\t\t\"\\nELige una opción o introduce una url: \\n(1)Ir adelante \\n(2)Ir atrás \\n(3)Salir \\n\",\n\t\t\t(opcion) => {\n\t\t\t\tswitch (opcion) {\n\t\t\t\t\tcase \"1\":\n\t\t\t\t\t\tif (pila.length > 0) {\n\t\t\t\t\t\t\tconsole.log(\"\\nHistorial borrado. Adquiera la suscripción para configurar\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmuestraPagina();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"2\":\n\t\t\t\t\t\tif (pila.length > 0) {\n\t\t\t\t\t\t\tpila.pop();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmuestraPagina();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"3\":\n\t\t\t\t\t\tconsole.log(\"\\nSaliendo del navegador... abriendo impresora...\");\n\t\t\t\t\t\timpresoraCompartida();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tpila.push(opcion);\n\t\t\t\t\t\tmuestraPagina();\n\t\t\t\t}\n\t\t\t}\n\t\t);\n\t}\n\n\tmuestraPagina();\n};\n\nlet impresoraCompartida = () => {\n\trl.resume();\n\tlet cola = [];\n\n\tfunction muestraOpciones() {\n\t\tif (cola.length > 0) {\n\t\t\tconsole.log(\n\t\t\t\t`\\nCola de impresión actual(${cola.length}): ${cola.join(\", \")}`\n\t\t\t);\n\t\t} else {\n\t\t\tconsole.log(\"\\nNo hay documentos en cola\");\n\t\t}\n\n\t\trl.question(\n\t\t\t\"\\nAgregue un documento o elija: \\n(1)Imprimir \\n(2)Salir \\n\",\n\t\t\t(opcion) => {\n\t\t\t\tswitch (opcion) {\n\t\t\t\t\tcase \"1\":\n\t\t\t\t\t\tif (cola.length > 0) {\n\t\t\t\t\t\t\tconsole.log(`\\nImprimiendo ${cola[0]}`);\n\t\t\t\t\t\t\tcola.shift();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmuestraOpciones();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"2\":\n\t\t\t\t\t\tconsole.log(\"\\nSaliendo de impresora...\");\n\t\t\t\t\t\trl.close();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tcola.push(opcion);\n\t\t\t\t\t\tmuestraOpciones();\n\t\t\t\t}\n\t\t\t}\n\t\t);\n\t}\n\n\tmuestraOpciones();\n};\n\nnavegador();"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/Sac-Corts.js",
    "content": "// Exercise // \nclass Stack {\n    constructor() {\n        this.items = [];\n    }\n\n    push(element) {\n        this.items.push(element);\n    }\n\n    pop() {\n        if (this.isEmpty()) {\n            return \"Stack is empty\";\n        } \n        return this.items.pop();\n    }\n\n    peek() {\n        if (this.isEmpty()) {\n            return \"Stack is empty\";\n        }\n        return this.items[this.items.length - 1];\n    }\n\n    isEmpty() {\n        return this.items.length === 0;\n        }\n\n    size() {\n        return this.items.length;\n    }   \n}\n\nconst stack = new Stack();\nstack.push(11);\nstack.push(7);\nstack.push(21);\nconsole.log(stack.peek());\nconsole.log(stack.pop());\nconsole.log(stack.size());\nconsole.log(stack.isEmpty());\n\nclass Queue {\n    constructor() {\n        this.items = [];\n    }\n\n    enqueue(element) {\n        this.items.push(element);\n    }\n\n    dequeue() {\n        if (this.isEmpty()) {\n            return \"Queue is empty\";\n        }\n        return this.items.shift();\n    }\n\n    front() {\n        if (this.isEmpty()) {\n            return \"Queue is empty\";\n        }\n        return this.items[0];\n    }\n\n    isEmpty() {\n        return this.items.length === 0;\n    }\n\n    size() {\n        return this.items.length;\n    }\n}\n\nconst queue = new Queue();\nqueue.enqueue(11);\nqueue.enqueue(7);\nqueue.enqueue(21);\nconsole.log(queue.front());\nconsole.log(queue.dequeue());\nconsole.log(queue.size());\nconsole.log(queue.isEmpty());\n\n// Extra Exercise //\n\n// Browser History\nconst readline = require('readline');\n\nclass BrowserHistory {\n    constructor() {\n        this.record = [];\n        this.forward = [];\n    }\n    \n    navigateTo(page) {\n        this.record.push(page);\n        this.forward.length = 0;\n        console.log(`Current page: ${page}`);\n    }\n\n    goBack() {\n        if (this.record.length > 1) {\n            const lastPage = this.record.pop();\n            this.forward.push(lastPage);\n            console.log(`Current page: ${this.record[this.record.length - 1]}`);\n        } else {\n            console.log(\"There are no more pages\");\n        }\n    }\n\n    goForward() {\n        if (this.forward.length) {\n            const nextPage = this.forward.pop();\n            this.record.push(nextPage);\n            console.log(`Current page: ${nextPage}`)\n        } else {\n            console.log(\"There are no more pages\");\n        }\n    }\n}\n\n// Printer\nclass Printer {\n    constructor() {\n        this.queue = [];\n    }\n\n    addDocument(document) {\n        this.queue.push(document);\n    }\n\n    printDocument() {\n        if (this.queue.length > 0) {\n            const print = this.queue.shift();\n            console.log(`Printing ${print} | Remaining queue: ${this.queue}`);\n        } else {\n            console.log(\"There are no prints at the moment.\");\n        }\n    }\n}\n\nconst myHistory = new BrowserHistory();\nconst myPrinter = new Printer();\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\n// Functions to control the browser history and the printer\nfunction historyControl() {\n    rl.question(\"Enter a page or 'backward'/'forward' ('exit' to finish): \", (command) => {\n        command = command.toLowerCase();\n        if (command === 'backward') {\n            myHistory.goBack();\n        } else if (command === 'forward') {\n            myHistory.goForward();\n        } else if (command === 'hexit') {\n            console.log(\"Exiting the browser...\");\n            printerControl();\n            return;\n        } else {\n            myHistory.navigateTo(command);\n        }\n    \n        historyControl();\n    });\n}\n\n\nfunction printerControl() {\n    rl.question(\"Enter a document or 'print' (if you want to print a document in the queue): \", (command) => {\n        command = command.toLowerCase();\n        if (command === 'print') {\n            myPrinter.printDocument();\n        } else if (command === 'pexit') {\n            console.log(\"Turning off the printer...\");\n            rl.close();\n        } else {\n            myPrinter.addDocument(command);\n            console.log(`Print queue: ${myPrinter.queue}`);\n        }\n\n        printerControl();\n    });\n}\n\nhistoryControl();   "
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/adrs1166ma.js",
    "content": "/*\n* EJERCICIO:\n* Implementa los mecanismos de introducción y recuperación de elementos propios de las\n* pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n* o lista (dependiendo de las posibilidades de tu lenguaje).\n*\n* DIFICULTAD EXTRA (opcional):\n* - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n*   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n*   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n*   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n*   el nombre de una nueva web.\n* - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n*   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n*   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n*   interpretan como nombres de documentos.\n*/\n\n// 🔥 Implementación de pilas y colas\n\n// Pila (Stack - LIFO)\n/*\nUna pila es una estructura de datos que sigue el principio LIFO \n(Last In, First Out).\nLos elementos se añaden y se eliminan desde la parte superior de la pila.\n*/\nclass Stack {\n    constructor() { this.items = [] }\n\n    // Añadir un elemento a la pila\n    push(element) { this.items.push(element) }\n\n    // Eliminar el último elemento añadido\n    pop() {\n        return this.isEmpty() ? 'La pila está vacía' : this.items.pop()\n    }\n\n    // Ver el último elemento sin eliminarlo\n    peek() {\n        return this.isEmpty() ? 'La pila está vacía' : this.items[this.items.length - 1]\n    }\n\n    // Verificar si la pila está vacía\n    isEmpty() {\n        return this.items.length === 0;\n    }\n\n    // Mostrar el contenido de la pila\n    print() {\n        console.log(this.items.toString()||'La pila está vacía');\n    }\n}\n\nconst stack = new Stack();\nstack.print(); // La pila está vacía\nstack.push(\"A\");\nstack.push(\"B\");\nstack.push(\"C\");\nstack.print(); // C,B,A\nconsole.log(stack.pop()); // C\nconsole.log(stack.peek()); // B\n\n\n\n// Cola (Queue - FIFO)\n/*\nUna cola es una estructura de datos que sigue el principio FIFO \n(First In, First Out). \nLos elementos se añaden al final de la cola y se eliminan desde el frente.\n*/\n\nclass Queue {\n    constructor() { this.items = [] }\n\n    // Añadir un elemento a la cola\n    enqueue(element) { this.items.push(element) }\n\n    // Eliminar el primer elemento añadido\n    dequeue() {\n        return this.isEmpty() ? 'La cola está vacía' : this.items.shift()\n    }\n\n    // Ver el primer elemento sin eliminarlo\n    front() {\n        return this.isEmpty() ? 'La cola está vacía' : this.items[0]\n    }\n\n    // Verificar si la cola está vacía\n    isEmpty() {\n        return this.items.length === 0;\n    }\n\n    // Mostrar el contenido de la cola\n    print() {\n        console.log(this.items.toString()||'La cola está vacía' );\n    }\n}\n\nconst queue = new Queue();\nqueue.print(); // La cola está vacía\nqueue.enqueue(\"A\");\nqueue.enqueue(\"B\");\nqueue.enqueue(\"C\");\nqueue.print(); // A,B,C\nconsole.log(queue.dequeue()); // A\nconsole.log(queue.front()); // B\n\n\n// 🔥 Extra\n\n// 1. Navegador web\nclass Navegador {\n    constructor() {\n        this.backStack = new Stack()\n        this.forwardStack = new Stack()\n        this.actualPage = null;\n    }\n\n    // Visitar una nueva página\n    visitar(pagina) {\n        this.actualPage !== null && this.backStack.push(this.actualPage); // Guardar la página actual en el historial\n        this.actualPage = pagina;\n        this.forwardStack = new Stack(); // Limpiar el historial hacia adelante\n        console.log(`Visitando: ${pagina}`);\n    }\n\n    // Retroceder a la página anterior\n    atras() {\n        if (!this.backStack.isEmpty()) {\n            this.forwardStack.push(this.actualPage); // Guardar la página actual en el historial hacia adelante\n            this.actualPage = this.backStack.pop(); // Retroceder\n            console.log(`Retrocediendo a: ${this.actualPage}`);\n        } else {\n            console.log(\"No hay más páginas hacia atrás.\");\n        }\n    }\n\n    // Avanzar a la siguiente página\n    adelante() {\n        if (!this.forwardStack.isEmpty()) {\n            this.backStack.push(this.actualPage); // Guardar la página actual en el historial hacia atrás\n            this.actualPage = this.forwardStack.pop(); // Avanzar\n            console.log(`Avanzando a: ${this.actualPage}`);\n        } else {\n            console.log(\"No hay más páginas hacia adelante.\");\n        }\n    }\n}\n\n// Ejemplo de uso\nconst navegador = new Navegador();\nnavegador.visitar(\"https://www.google.com\");\nnavegador.visitar(\"https://www.facebook.com\");\nnavegador.visitar(\"https://www.youtube.com\");\nnavegador.atras(); // Retrocediendo a https://www.facebook.com\nnavegador.adelante(); // Avanzando a https://www.youtube.com\nnavegador.atras(); // Retrocediendo a https://www.facebook.com\nnavegador.visitar(\"https://www.twitter.com\"); // Visita https://www.twitter.com\nnavegador.adelante(); // No hay más páginas hacia adelante\n\n\n\n// 2. Impresora\nclass Impresora {\n    constructor() {\n        this.documentos = new Queue(); // Cola de documentos\n    }\n\n    // Agregar un documento a la cola\n    agregarDocumento(documento) {\n        this.documentos.enqueue(documento);\n        console.log(`Documento agregado: ${documento}`);\n    }\n\n    // Imprimir un documento\n    imprimir() {\n        if (!this.documentos.isEmpty()) {\n            const documento = this.documentos.dequeue();\n            console.log(`Imprimiendo: ${documento}`);\n        } else {\n            console.log(\"No hay documentos en la cola.\");\n        }\n    }\n}\n\nconst impresora = new Impresora();\nimpresora.agregarDocumento(\"versiculos.pdf\");\nimpresora.agregarDocumento(\"libro.pptx\");\nimpresora.imprimir(); // Imprime versiculos.pdf\nimpresora.imprimir(); // Imprime libro.pptx\nimpresora.imprimir(); // No hay más documentos"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/agusrosero.js",
    "content": "/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n\n// EJERCICIO:\n\n// pilas (stacks - LIFO)\n\nclass Stack {\n  constructor() {\n    this.stack = [];\n  }\n\n  push(element) {\n    this.stack.push(element);\n    return this.stack;\n  }\n\n  pop() {\n    return this.stack.pop();\n  }\n\n  print() {\n    console.log(this.stack);\n  }\n}\n\nconst stack = new Stack();\nstack.push(1);\nstack.push(2);\nstack.push(3);\nstack.pop();\nstack.print();\n\n// colas (queue - FIFO)\nclass Queue {\n  constructor() {\n    this.queue = [];\n  }\n\n  enqueue(element) {\n    this.queue.push(element);\n    return this.queue;\n  }\n\n  dequeue() {\n    return this.queue.shift();\n  }\n\n  print() {\n    return this.queue;\n  }\n}\n\nconst queue = new Queue();\nqueue.enqueue(\"Test1\");\nqueue.enqueue(\"Test2\");\nqueue.enqueue(\"Test3\");\nqueue.dequeue();\nconsole.log(queue.print());\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/airesEsteban.js",
    "content": "// Pilas (stacks -LIFO)\n\nlet  pila = []\n\npila.push(1)\npila.push(2)\npila.push(3)\n\n//console.log(pila)\n\npila.pop()\n\n//console.log(pila)\n\n// Cola (queue - FIFO)\nlet cola = []\n\ncola.push(\"a\")\ncola.push(\"b\")\ncola.push(\"c\")\n\ncola.shift()\n//console.log(cola)\n\n\n/*\nUtilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\nde un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\nque te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\nLas palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\nel nombre de una nueva web.\n */\n\nlet historial = []\nlet paginaActual = 0\n\nfunction agregarPagina(web) {\n    if (historial.length > 0){\n        paginaActual ++\n    }    \n    historial.push(web)\n}\n\nfunction atras(){\n    console.log(historial[paginaActual-1])\n    paginaActual--\n}\n\nfunction adelante(){\n    console.log(historial[paginaActual+1])\n    paginaActual++\n}\n\nagregarPagina(\"test.com\")\nconsole.log(historial)\n\nagregarPagina(\"vip.com\")\nconsole.log(historial) \n\n\natras()\nadelante()\n\n\n/*\nUtilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\nimpresora compartida que recibe documentos y los imprime cuando así se le indica.\nLa palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\ninterpretan como nombres de documentos.\n*/\nlet readline = require('readline')\nlet rl = readline.createInterface({ input: process.stdin, output: process.stdout })\n\ncola=[]\n\nfunction printer(){\n    printQueue(cola)\n\n    rl.question('Ingresa un documento o elige \"imprimir\" o \"salir\": ', (answer) => {\n    let inputFormat = answer.trim().toLowerCase()\n    switch (inputFormat){\n        case \"imprimir\":\n            if (cola.length === 0){\n                console.log(\"No hay documentos para imprimir\")\n                printer()\n            } else {\n                let doc = cola.shift()\n                console.log(`Imprimiendo ${doc}`)\n                printer()\n            }\n            break\n        case \"salir\":\n            rl.close()\n            break\n        default:\n            cola.push(inputFormat)\n            printer()\n            break  \n    }\n})\n}\n\nfunction printQueue(cola) {\n    if(cola.length === 0) {\n        console.log(\"No hay documentos en cola para imprimir\")\n    }else {\n        console.log(\"Cola de impresion\")\n        cola.forEach(document => {\n          console.log(document)  \n        })\n    }\n}\n\nprinter()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/alexdevrep.js",
    "content": "/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n\n//Pilas\n\n/*\nLas pilas son tipos abstactos de datos que se encuentran en un formato de tipo lista\na cuyos elementos se accede de una forma particular (LIFO) Last In First Out que se puede \ntraducir como \"Lo último en entrar será lo último en salir\"\n*/\n\n//Creamos un array de objetos\nlet arrayObjetos = [\"Hola\",\"Javascript\",\"Alexdevrep\"]\nconsole.log(arrayObjetos)\n\n//Introducimos un elemento en el array\narrayObjetos.push(\"Mundo\") //Añadimos un elemento al final del array\nconsole.log(arrayObjetos)\n\n//Recuperamos el último objeto del array que ha sido añadido\nconsole.log(arrayObjetos.pop()) //Quitamos el último elemento del array\nconsole.log(arrayObjetos)\n\n\nconsole.log(\"---------------------------------------\")\n\n//Colas\n\n/*\nLas colas son los colecciones de elementos ordenados que únicamente permiten dos acciones \n-Añadir un elemento a la cola\n-Sacar un elemento de la cola\nLa peculiaridad es que el primer elemento en entrar es el primero en salir (FIFO) First In First Out\n*/\n\n//Creamos una cola de objetos\nlet colaObjetos = [\"Hola\",\"Mundo\",\"Alexdevrep\"]\n\n//Añadimos un elemento a la cola\ncolaObjetos.push(\"JavaScript\")\nconsole.log(colaObjetos)\n\n//Recuperamos el primer elemento de la cola en ser añadido en este caso \"Hola\"\nconsole.log(colaObjetos.shift()) //Quita el primer elemento del array y lo devuelve\nconsole.log(colaObjetos)\n\nconsole.log(\"---------------------------------------\")\n\n//Dificultad EXTRA\n\n//Ejercicio Pilas\nconst prompt = require('prompt-sync')()\nlet pila_web = []\n\nconsole.log(\"###---NAVEGADOR WEB---###\")\nconsole.log(\"Pestaña Nueva\")\n\nwhile (true) {\n    function accion(arg) {\n        if (arg == \"ADELANTE\") {\n            const web = prompt(\"Por favor indique a qué web quiere acceder: \")\n            pila_web.push(web)\n            console.log(`Ahora estás viendo ${pila_web[pila_web.length - 1]}`)\n        } else if (arg == \"ATRAS\") {\n            if (pila_web.length > 1) {\n                pila_web.pop()\n                console.log(`Ahora estás viendo ${pila_web[pila_web.length - 1]}`)\n            } else {\n                console.log(\"No hay historial de navegación para retroceder\")\n            }\n        } else if (arg == \"SALIR\") {\n            console.log(\"Cerrando el navegador web\")\n            \n        } else {\n            console.log(\"Comando no reconocido\")\n        }\n    }\n\n    const arg = prompt(\"Por favor escriba ADELANTE si quiere acceder a una URL nueva, ATRAS si quiere cerrar la última URL, o SALIR para salir: \")\n    accion(arg)\n    if (arg == \"SALIR\"){\n        break\n    }\n}\n\n\n//Ejercicio Colas\n\nlet documentos = []\n\nwhile (true){\n    function impresora (archivo){\n        if (archivo== \"IMPRIMIR\"){\n            if(documentos.length>=1){\n                console.log(`Imprimiendo archivo ${documentos.shift()}`)\n            }\n            else{\n                console.log(\"No hay archivos para imprimir\")\n            }\n        \n        }\n        else if (archivo == \"SALIR\"){\n            console.log(\"Apagando la impresora\")\n            process.exit()\n        }\n        else {\n            documentos.push(archivo)\n            console.log(\"Documento añadido a la cola de impresión\")\n        }\n    }\n    archivo=prompt(\"Por favor escriba el nombre del archivo para añadirlo a la cola de la impresión , IMPRIMIR para imprimirlo y SALIR para apagar la impresora: \")\n    impresora(archivo)\n    \n\n}\n\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/bernatcs.js",
    "content": "// ** EJERCICIO\n\n// Implementación de una Pila (Stack - LIFO)\n\nclass Stack {\n    constructor() {\n        this.items = [];\n        this.forwardStack = [] // Array secundaria\n    }\n\n    push(element) {\n        this.items.push(element); // Agrega el elemento al final de la lista\n    }\n\n    pop() {\n        if (this.isEmpty()) {\n            return \"La pila está vacía\";\n        }\n        return this.items.pop(); // Elimina y devuelve el último elemento de la lista\n    }\n\n    peek() {\n        if (this.isEmpty()) {\n            return \"La pila está vacía\";\n        }\n        return this.items[this.items.length - 1]; // Devuelve el último elemento sin eliminarlo\n    }\n\n    isEmpty() {\n        return this.items.length === 0; // Comprueba si la lista está vacía\n    }\n\n    size() {\n        return this.items.length; // Devuelve el tamaño de la lista\n    }\n\n    clear() {\n        this.items = []; // Vacía la lista\n    }\n\n    print() {\n        console.log(this.items.toString()); // Imprime los elementos de la lista\n    }\n\n    pushForward(element) {\n        this.forwardStack.push(element); // Añade elementos al forwardStack que son usados para almacenar\n    }\n\n    popForward() {\n        if (this.forwardStack.length === 0) { \n            return \"Forward stack is empty\";\n        }\n        return this.forwardStack.pop(); // Elimina y devuelve el último elemento del forwardStack\n    }\n\n    peekForward() {\n        if (this.forwardStack.length === 0) { \n            return \"Forward stack is empty\";\n        }\n        return this.forwardStack[this.forwardStack.length - 1]; // Devuelve el último elemento del forwardStack sin eliminarlo\n    }\n\n    isEmptyForward() {\n        return this.forwardStack.length === 0; // Comprueba si la lista está vacía\n    }\n}\n\nlet pila = new Stack()\npila.push(10) // Añade 10\npila.push(20) // Añade 20\npila.push(30) // Añade 30\npila.pop() // Devuelve y elimina 30\npila.peek() // Devuelve 20 sin eliminarlo\n// pila.print() // Imprime 10,20\n\n// Implementación de una Cola (Queue - FIFO)\n\nclass Queue {\n    constructor() {\n        this.items = [];\n    }\n\n    enqueue(element) {\n        this.items.push(element); // Agrega el elemento al final de la lista\n    }\n\n    dequeue() {\n        if (this.isEmpty()) {\n            return \"La cola está vacía\";\n        }\n        return this.items.shift(); // Elimina y devuelve el primer elemento de la lista\n    }\n\n    front() {\n        if (this.isEmpty()) {\n            return \"La cola está vacía\";\n        }\n        return this.items[0]; // Devuelve el primer elemento sin eliminarlo\n    }\n\n    isEmpty() {\n        return this.items.length === 0; // Comprueba si la lista está vacía\n    }\n\n    size() {\n        return this.items.length; // Devuelve el tamaño de la lista\n    }\n\n    clear() {\n        this.items = []; // Vacía la lista\n    }\n\n    print() {\n        console.log(this.items.toString()); // Imprime los elementos de la lista\n    }\n}\n\n// Ejemplo de uso:\nlet cola = new Queue();\ncola.enqueue(10); // Añade 10\ncola.enqueue(20); // Añade 20\ncola.enqueue(30); // Añade 30\ncola.dequeue() // Devuelve y elimina 10\ncola.front() // Devuelve 20 sin eliminarlo\n// cola.print(); // Imprime 20,30\n\n// ** DIFICULTAD EXTRA (navegador Web) ** ---------------------------------------------------------------------------------------------------------------------------------------------\n\nlet navegadorWebPila = new Stack();\n// navegadorWebPila.push(10); // Añade 10\n// navegadorWebPila.push(20); // Añade 20\n// navegadorWebPila.push(30); // Añade 30\n// console.log(navegadorWebPila.pop()); // Devuelve y elimina 30\n// console.log(navegadorWebPila.peek()); // Devuelve 20 sin eliminarlo\n// navegadorWebPila.print(); // Imprime 10,20\n\nconst readline = require('readline').createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nlet textoInicio = false\n\n// navegadorWeb()\n\nfunction navegadorWeb(){\n    if (!textoInicio) {\n        readline.question('Bienvenido al búscador.\\nPodrá retroceder con el comando [atrás]\\nPodrá volver hacia delante con el comando [adelante]\\nPodrá ir a una nueva página introduciendo una búsqueda.\\nPara empezar, introduzca la página a la que quiere viajar: ', (respuesta) => {\n            navegadorWebPregunta(respuesta)\n        });\n        textoInicio = true\n    } else {\n        readline.question('', (respuesta) => {\n            navegadorWebPregunta(respuesta)\n        });\n    }\n}\n\n\nfunction navegadorWebPregunta(respuesta){\n    if (respuesta !== 'atrás' && respuesta !== 'adelante' && respuesta !== '') {\n        navegadorWebPila.push(respuesta);\n        console.log(`Usted se encuentra en: ${navegadorWebPila.peek()}\\nLa ruta de páginas es la siguiente: `)\n        navegadorWebPila.print()\n        navegadorWeb(respuesta);\n    } else if (respuesta === 'atrás') {\n        if (!navegadorWebPila.isEmpty()){\n            let atras = navegadorWebPila.pop();\n            navegadorWebPila.pushForward(atras);\n            if (!navegadorWebPila.isEmpty()) {\n                console.log(`Usted ha vuelto a: ${navegadorWebPila.peek()}`);\n            } else {\n                console.log(\"No hay más páginas en el historial.\");\n            }\n        } else {\n            console.log('No hay más páginas hacia atrás');\n        }\n        navegadorWeb();\n    } else if (respuesta === 'adelante') {\n        if (!navegadorWebPila.isEmptyForward()) {\n            let adelante = navegadorWebPila.popForward()\n            navegadorWebPila.push(adelante);\n            console.log(`Usted ha avanzado a: ${adelante}`);\n        } else {\n            console.log('No hay más páginas hacia adelante');\n        }\n        navegadorWeb();\n    } else {\n        console.log(`Por favor, introduzca un texto.`)\n        navegadorWeb()\n    }\n}\n\n// ** DIFICULTAD EXTRA (impresora) ** ---------------------------------------------------------------------------------------------------------------------------------------------\n\nlet impresora = new Queue();\n\nimprimirImpresora()\n\nfunction imprimirImpresora(){\n    if (!textoInicio) {\n        readline.question('Bienvenido a la impresora.\\nPodrá imprimir el primer elemento de la cola con el comando [imprimir]\\nPodrá adjuntar un documento escribiendo el nombre del documento.\\nPara empezar, introduzca el nombre del primer documento: ', (respuesta) => {\n            imprimirImpresoraAccion(respuesta)\n        });\n        textoInicio = true\n    } else {\n        readline.question('', (respuesta) => {\n            imprimirImpresoraAccion(respuesta)\n        });\n    }\n}\n\nfunction imprimirImpresoraAccion(respuesta){\n    if (respuesta !== 'imprimir' && respuesta !== ''){\n        console.log(`Se ha añadido: ${respuesta}.\\nLos documentos que quedan son: `)\n        impresora.enqueue(respuesta)\n        impresora.print()\n        imprimirImpresora()\n    } else if (respuesta === 'imprimir') {\n        if (!impresora.isEmpty()){\n            console.log(`Se está imprimiento: ${impresora.dequeue()}.\\nLos documentos que quedan son: `)\n            impresora.print()\n            imprimirImpresora()\n        } else {\n            console.log('No hay elementos que imprimir')\n            imprimirImpresora()\n        }\n    } else {\n        console.log('Por favor, introduzca un texto:')\n        imprimirImpresora()\n    }\n}"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/brahiams7.js",
    "content": "//  *\n//  * EJERCICIO:\n//  * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n//  * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n//  * o lista (dependiendo de las posibilidades de tu lenguaje).\n\n// Pila o stack LAST IN FIRST OUT\npila=[]\npila.push(1)\npila.push(2)\npila.push(3)\npila.push(4)\npila.pop()\n// console.log(pila);\n\n// // Fila o queue FIRST IN FIRST OUT\npila=[]\npila.push(1)\npila.push(2)\npila.push(3)\npila.push(4)\npila.shift()\n// console.log(pila);\n\n// DIFICULTAD EXTRA (opcional):\n//  * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n//  *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n//  *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n//  *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n//  *   el nombre de una nueva web.  \n\nlet readline = require('readline')\nlet rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n\natras=[]\nadelante=[]\n\nfunction navegar(){\n    rl.question('Ingresa una url o escribe adelante para ir a la siguiente pagina, atras para ir a la anterior y salir para cerrar el programa ',(answer)=>{\n        let ans=answer.trim().toLowerCase()\n        switch(ans){\n            case 'adelante':\n                atras.push(adelante.pop())\n                currentPage(atras)\n                navegar()\n                \n                break\n            case 'atras':\n                if(isEmpty(atras)){\n                    currentPage(atras)\n                    navegar()\n                    \n                } else {\n                    adelante.push(atras.pop())\n                    currentPage(adelante)\n                    navegar()\n                    \n                }\n                break\n            case 'salir':\n                rl.close()\n                \n            default:\n                adelante=[]\n                atras.push(ans)\n                currentPage(atras)\n                navegar()\n                \n                break\n        }\n    })\n    \n}\n\n\nfunction isEmpty(pila){\n    return pila.length===0\n}\nfunction currentPage(pila){\n    return isEmpty(pila) ? console.log(\"Estas en la pagina de inicio\") : console.log(`Estas en la pagina ${pila[pila.length-1]}`);\n    \n    \n}\n// navegar()\n\n\n// /*\n// Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n// impresora compartida que recibe documentos y los imprime cuando así se le indica.\n// La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n// interpretan como nombres de documentos.\n// */\n\ncola=[]\n\nfunction imprimir(){\n\n    printQueue()\n\n    rl.question('Ingresa el documento o escribe imprimir para mostrarlos en pantalla: ',(answer)=>{\n        let ans=answer.trim().toLocaleLowerCase()\n        switch(ans){\n            case 'imprimir':\n                if(cola.length===0){\n                    console.log('No hay elementos');\n                    imprimir()\n                } else {\n                    for(let i=0;i<cola.length;i++){\n                        console.log(cola[i]);\n                    }\n                    for(let i=0;i<=cola.length+1;i++){\n                        cola.shift();\n                    }\n                    imprimir()\n                }\n                break\n            case 'salir':\n                console.log('El proceso ha terminado, hasta luego!');\n                \n                rl.close()\n                break\n            default:\n                cola.push(ans)\n                imprimir()\n                break\n        }\n\n\n    })\n    \n}\n\nfunction printQueue(){\n    if (cola.length===0){\n        console.log('No hay elementos para mostrar');\n    }  else {\n        console.log(`\\n Cola de impresion`);\n        cola.forEach(document =>{\n            console.log(document);\n        })\n        \n    }\n}\n\nimprimir()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/caterinarodriguezdev.js",
    "content": "/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n\nconsole.log('---------------------PILA---------------------');\n\nclass Stack {\n\n    constructor (arr) {\n        this.stack = arr;\n    }\n\n    push (item) {\n        this.stack.push(item);\n    }\n\n    pop () {\n        this.stack.pop();\n    }\n\n    peek () {\n        return this.stack[this.stack.length - 1];\n    }\n\n    size () {\n        return this.stack.length;\n    }\n}\n\nconst pila = new Stack([10, 20, 30]); \n\npila.push(40);\npila.push(50);\npila.pop();\n\nconsole.log(pila.peek());\nconsole.log(pila.size());\n\n\nconsole.log('---------------------COLA---------------------');\n\nclass Queue {\n\n    constructor (arr) {\n        this.queue = arr;\n    }\n\n    enqueue (item) {\n        this.queue.push(item);\n    }\n\n    dequeue () {\n        if (this.isEmpty()) {\n            return null;\n        } else {\n            return this.queue.shift();\n        }\n    }\n\n    isEmpty() {\n        return this.queue.length === 0;\n    }\n\n    size () {\n        return this.queue.length;\n    }\n\n    front () {\n        if (this.isEmpty()) {\n            return null;\n        } else {\n            return this.queue[0];\n        }\n    }\n}\n\nconst cola = new Queue([11, 22, 33]);\nconsole.log(cola);\ncola.dequeue();\ncola.enqueue(1);\nconsole.log(cola.front());\n\nconsole.log('-------------- NAVEGADOR WEB --------------');\n\nconst readline = require('readline');\nconst rl = readline.createInterface(process.stdin, process.stdout);\n\nlet historial = new Stack([]);\nlet forwardStack = new Stack([]);\n\nconst navegador = () => {\n\n    rl.question('Adelante, atrás, o introduce una web -> ', (term) => {\n        switch(term) {\n            case 'adelante':\n                goForward();\n                break;\n            case 'atras':\n                goBack();\n                break;\n            default:\n                navigate(term);\n        }\n    });\n\n}\n\nconst navigate = (term) => {\n    historial.push(term);\n    console.log('Going to -> ', term);\n    forwardStack = new Stack([]);\n    entryPoint();\n}\n\nconst goBack = () => {\n    forwardStack.push(historial.peek())\n    historial.pop();\n    console.log('Going back to -> ', historial.peek());\n    entryPoint();\n}\n\nconst goForward = () => {\n    console.log('Going forward to ->', forwardStack.peek());\n    historial.push(forwardStack.peek());\n    entryPoint();\n}\n\n// * DIFICULTAD EXTRA (opcional):\n// * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n// *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n// *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n// *   interpretan como nombres de documentos.\n\nconsole.log('-------------- IMPRESORA --------------');\n\nlet colaImpresion = new Queue([]);\n\nconst imprimir = () => {\n\n    rl.question('Imprime o añade un documento -> ', (term) => {\n\n        switch (term) {\n            case 'imprimir':\n                console.log('Imprimiendo documento: ', colaImpresion.dequeue());\n                imprimir();\n                break;\n            default:\n                console.log('Documento añadido: ', term);\n                colaImpresion.enqueue(term);\n                imprimir();\n                break;\n        }\n    })\n}\n\nconst entryPoint = () => {\n\n    rl.question('¿Qué programa desea ejecutar? -> ', (term) => {\n        switch (term) {\n            case 'Navegador':\n                navegador();\n                break;\n            case 'Impresora':\n                imprimir();\n                break;\n        }\n    })\n}\n\nentryPoint();"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/ceciliarava1.js",
    "content": "/* Stacks: LIFO. Least In First Out\n   Queue:  FIFO. First In First Out\n*/\n\nlet stack = [1, 2]\nstack.push(3)\n// console.log(stack)\nstack.pop()\n// console.log(stack)\n\nlet queue = [1, 2]\nqueue.push(3)\n// console.log(queue)\nqueue.shift()\n// console.log(queue)\n\n\nconst readline = require('readline')\nconst rl = readline.createInterface({\n   input: process.stdin,\n   output: process.stdout\n})\n\nlet history = []\nlet currentWebsite = ''\n\nfunction showMenu() {\n\n   console.log('----------------------------------------------')\n   console.log('- forward')\n   console.log('- backward')\n   console.log('- Type a new website to go')\n   console.log('- exit')\n\n   rl.question('Choose an option: ', (option) => {\n\n      console.log('----------------------------------------------')\n\n      switch (option) {\n\n         case 'backward':\n            if (history.length == 0) {\n               console.log('The history is empty. Type a new website to go')\n               showMenu()\n            } else {\n               const index = history.indexOf(currentWebsite);\n\n               if (index > 0 && index !== - 1) {\n                  currentWebsite = history[index - 1];\n                  console.log(`Current website: ${currentWebsite}`);\n               } else {\n                  console.log('There is no website to go. Try other option')\n               }\n            }\n            showMenu()\n            break\n\n         case 'forward':\n            if (history.length == 0) {\n               console.log('The history is empty. Type a new website to go')\n            } else {\n               const index = history.indexOf(currentWebsite);\n\n               if (index < history.length - 1 && index !== - 1) {\n                  currentWebsite = history[index + 1];\n                  console.log(`Current website: ${currentWebsite}`);\n               } else {\n                  console.log('There is no website to go. Try other option')\n               }\n            }\n            showMenu()\n            break\n\n         case 'exit':\n            console.log('Bye!')\n            rl.close()\n            break\n\n         default:\n            currentWebsite = option\n            console.log('current', currentWebsite)\n\n            history.push(currentWebsite)\n            console.log(`Current website ${currentWebsite}`)\n            showMenu()\n      }\n   })\n}\n\n// showMenu()\n\n\nlet documents = []\n\nfunction showNewMenu() {\n\n   console.log('----------------------------------------------')\n   console.log('- print')\n   console.log('- Type a new document')\n   console.log('- exit')\n\n   rl.question('Choose an option: ', (option) => {\n\n      console.log('----------------------------------------------')\n\n      switch (option) {\n\n         case 'print':\n            if (documents.length == 0) {\n               console.log('There is no documents to print. Add a document')\n            } else {\n               console.log(`Printing ${documents[0]}`)\n               documents.shift()\n            }\n            showNewMenu()\n            break\n\n         case 'exit':\n            console.log('Bye!')\n            rl.close()\n            break\n\n         default:\n            documents.push(option)\n            console.log(`${option}  added`)\n            showNewMenu()\n      }\n   })\n}\n\n// showNewMenu()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/cesar-ch.js",
    "content": "/*\n    #07 PILAS Y COLAS\n*/\n\n\n// pila\nlet pila = []\n\n// push\npila.push(1)\npila.push(2)\npila.push(3)\n\n// pop\npila.pop()\nconsole.log(pila)\n\n// cola\nlet cola = []\n\n// enqueue\ncola.push(1)\ncola.push(2)\ncola.push(3)\n\n// dequeue\ncola.shift()\nconsole.log(cola)\n\n/*\n    DIFICULTAD EXTRA\n*/\n\nfunction webNavigation() {\n    let stack = [];\n\n    while (true) {\n        let action = prompt(\"Añade una url o interactúa con palabras adelante/atras/salir: \");\n\n        if (action === \"salir\") {\n            console.log(\"Saliendo del navegador web.\");\n            break;\n        } else if (action === \"adelante\") {\n            continue\n        } else if (action === \"atras\") {\n            if (stack.length > 0) {\n                stack.pop();\n            }\n        } else {\n            stack.push(action);\n        }\n\n        if (stack.length > 0) {\n            console.log(`Has navegado a la web: ${stack[stack.length - 1]}.`);\n        } else {\n            console.log(\"Estás en la página de inicio.\");\n        }\n    }\n}\n\n// webNavigation();\n\nfunction printed() {\n    let queue = [];\n\n    while (true) {\n        let action = prompt(\"Añade un documento o selecciona imprimir/salir: \");\n\n        if (action === \"salir\") {\n            break;\n        } else if (action === \"imprimir\") {\n            if (queue.length > 0) {\n                console.log(`Imprimiendo: ${queue.shift()}`);\n            }\n        } else {\n            queue.push(action);\n        }\n        console.log(`Cola de impresión: ${queue}`);\n    }\n}\n\nprinted();"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/christian-jfr.js",
    "content": "// #07 PILAS Y COLAS\n\n/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n */\n\n/** === PILAS ===\n * Convencion para nombrar metodos:\n * push: Agrega un nuevo valor a la pila, ubicándolo al final de ésta.\n * pop: Retorna el último valor ingresado a la pila, sacándolo de ésta.\n * peek: Retorna el último valor ingresado a la pila, sin sacarlo de ésta.\n * size: Retorna el número de elementos que contiene la pila.\n * print: Muestra el contenido de la pila.\n */\n\n// PILA con Array\nclass StackOnArray {\n\tconstructor() {\n\t\tthis.stack = [];\n\t}\n\n\tpush(element) {\n\t\tthis.stack.push(element);\n\t\treturn this.stack;\n\t}\n\n\tpop() {\n\t\treturn this.stack.pop();\n\t}\n\n\tpeek() {\n\t\treturn this.stack[this.stack.length - 1];\n\t}\n\n\tsize() {\n\t\treturn this.stack.length;\n\t}\n\n\tprint() {\n\t\tconsole.log(this.stack);\n\t}\n}\n\nconst colorStack = new StackOnArray();\n\nconsole.log(`Check stack size: ${colorStack.size()}`); // -> 0\nconsole.log(`push element: ${colorStack.push('Yellow')}`); // -> [\"Yellow\"]\nconsole.log(`push element: ${colorStack.push('Blue')}`); // -> [\"Yellow\", \"Blue\"]\nconsole.log(`push element: ${colorStack.push('Red')}`); // -> [\"Yellow\", \"Blue\", \"Red\"]\nconsole.log(`Check stack size: ${colorStack.size()}`); // -> 3\ncolorStack.print(); // -> [\"Yellow\", \"Blue\", \"Red\"]\nconsole.log(`peek last element: ${colorStack.peek()}`); // -> \"Red\"\nconsole.log(`pop last element: ${colorStack.pop()}`); // -> \"Red\"\nconsole.log(`Check stack size: ${colorStack.size()}`); // -> 2\ncolorStack.print(); // -> [\"Yellow\", \"Blue\"]\n\n// PILA con Objeto\nclass StackOnObject {\n\tconstructor() {\n\t\tthis.stack = {};\n\t\tthis.top = 0;\n\t}\n\n\tpush(element) {\n\t\tthis.stack[this.top] = element;\n\t\tthis.top++;\n\t\treturn this.stack;\n\t}\n\n\tpop() {\n\t\tconst element = this.stack[this.top - 1];\n\t\tdelete this.stack[this.top - 1];\n\t\tthis.top--;\n\t\treturn element;\n\t}\n\n\tpeek() {\n\t\treturn this.stack[this.top - 1];\n\t}\n\n\tsize() {\n\t\treturn this.top;\n\t}\n\n\tprint() {\n\t\tconsole.log(this.stack);\n\t}\n}\n\nconst userStack = new StackOnObject();\n\nconsole.log(`Check stack size: ${userStack.size()}`); // 0\nconsole.log(`push element: ${userStack.push('John')}`); // -> { '0': 'John' }\nconsole.log(`push element: ${userStack.push('Jane')}`); // -> { '0': 'Jane' }\nconsole.log(`push element: ${userStack.push('Jim')}`); // -> { '0': 'Jim' }\nuserStack.print(); // -> { '0': 'John', '1': 'Jane', '2': 'Jim' }\nconsole.log(`peek last element: ${userStack.peek()}`); // -> 'Jim'\nconsole.log(`pop last element: ${userStack.pop()}`); // -> 'Jim'\nconsole.log(`Check stack size: ${userStack.size()}`); // -> 2\nuserStack.print(); // -> { '0': 'John', '1': 'Jane' }\n\n/**\n * === COLAS ===\n * Convencion para nombrar metodos:\n * enqueue: Agrega un nuevo elemento a la cola, situándolo al final de ésta.\n * dequeue: Retorna el primer elemento de la cola, quitándolo de ésta.\n * peek: Retorna el primer elemento de la cola, sin quitarlo de ésta.\n * size: Retorna el número de elementos que contiene la cola.\n * print: Muestra el contenido de la cola.\n * **isEmpty: Verifica si la cola está vacía.**\n */\n\n// Cola con Array\nclass QueueOnArray {\n\tconstructor() {\n\t\tthis.queue = [];\n\t}\n\n\tenqueue(element) {\n\t\tthis.queue.push(element);\n\t\treturn this.queue;\n\t}\n\n\tdequeue() {\n\t\treturn this.queue.shift();\n\t}\n\n\tpeek() {\n\t\treturn this.queue[0];\n\t}\n\n\tsize() {\n\t\treturn this.queue.length;\n\t}\n\n\tprint() {\n\t\tconsole.log(this.queue);\n\t}\n\n\tisEmpty() {\n\t\treturn this.queue.length === 0;\n\t}\n}\n\nconst numbersQueue = new QueueOnArray();\n\nconsole.log(`Empty queue? ${numbersQueue.isEmpty()}`); // -> true\nconsole.log(`enqueue element: ${numbersQueue.enqueue(1)}`); // -> [1]\nconsole.log(`enqueue element: ${numbersQueue.enqueue(2)}`); // -> [1, 2]\nconsole.log(`enqueue element: ${numbersQueue.enqueue(3)}`); // -> [1, 2, 3]\nconsole.log(`Check queue size: ${numbersQueue.size()}`); // -> 3\nnumbersQueue.print(); // -> [1, 2, 3]\nconsole.log(`Empty queue? ${numbersQueue.isEmpty()}`); // -> false\nconsole.log(`Check first element: ${numbersQueue.peek()}`); // -> 1\nconsole.log(`dequeue first element: ${numbersQueue.dequeue()}`); // -> 1\nconsole.log(`Check queue size: ${numbersQueue.size()}`); // -> 2\nnumbersQueue.print(); // -> [2, 3]\n\n// DIFICULTAD EXTRA (opcional):\n\n/**\n * Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n * de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n * que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n * Las palabras \"adelante\", \"atras\" desencadenan esta acción, el resto se interpreta como\n * el nombre de una nueva web.\n */\n// Solucion con entorno NodeJS\nimport { createInterface } from 'readline';\n\nconst rl = createInterface({\n\tinput: process.stdin,\n\toutput: process.stdout,\n});\n\nclass BrowserHistory {\n\tconstructor() {\n\t\tthis.history = ['Home'];\n\t\tthis.forwardStack = [];\n\t}\n\n\tpush(url) {\n\t\tthis.history.push(url);\n\t\tconsole.log(`Navigated to ${url}`);\n\t}\n\n\tpop() {\n\t\tconst prevUrl = this.history.pop();\n\t\tif (prevUrl) {\n\t\t\tthis.forwardStack.push(prevUrl);\n\t\t\tconsole.log(`Navigated back from ${prevUrl}`);\n\t\t} else {\n\t\t\tconsole.log('No backward history available.');\n\t\t}\n\t\treturn prevUrl;\n\t}\n\n\tforward() {\n\t\tconst nextUrl = this.forwardStack.pop();\n\t\tif (nextUrl) {\n\t\t\tthis.history.push(nextUrl);\n\t\t\tconsole.log(`Navigated forward to ${nextUrl}`);\n\t\t} else {\n\t\t\tconsole.log('No forward history available.');\n\t\t}\n\t\treturn nextUrl;\n\t}\n\n\tpeek() {\n\t\treturn this.history?.[this.history.length - 1] ?? 'Home';\n\t}\n\n\tsize() {\n\t\treturn this.history.length + this.forwardStack.length;\n\t}\n\n\tprint() {\n\t\tconsole.log(`Back History:\\n ${this.history.join('\\n ')}`);\n\t\tconsole.log('\\n=========================================\\n');\n\t\tconsole.log(`Forward History:\\n ${this.forwardStack.join('\\n ')}`);\n\t}\n}\n\nconst history = new BrowserHistory();\n\nbrowserSimulator();\n\nfunction browserSimulator() {\n\tconsole.clear();\n\t// console.log(history.print());\n\n\tconsole.log(`Current Page: ${history.peek()}`);\n\n\trl.question(\n\t\t'Browser Simulator\\nEnter \"forward\" or \"back\" to navigate\\nOr enter a new URL: ',\n\t\t(answer) => {\n\t\t\tswitch (answer) {\n\t\t\t\tcase '':\n\t\t\t\t\tbrowserSimulator();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'size':\n\t\t\t\t\thistorySize();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'history':\n\t\t\t\t\tbrowsingHistory();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'forward':\n\t\t\t\t\tnavForward();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'back':\n\t\t\t\t\tback();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'exit':\n\t\t\t\t\tconsole.clear();\n\t\t\t\t\tprocess.exit();\n\n\t\t\t\tdefault:\n\t\t\t\t\taddUrl(answer);\n\t\t\t}\n\t\t}\n\t);\n}\n\nfunction load() {\n\tsetTimeout(() => {\n\t\tbrowserSimulator();\n\t}, 1000);\n}\n\nfunction addUrl(url) {\n\thistory.push(url);\n\tload();\n}\n\nfunction back() {\n\thistory.pop();\n\tconsole.log(`... to ${history.peek()}`);\n\tload();\n}\n\nfunction navForward() {\n\thistory.forward();\n\tload();\n}\n\nfunction browsingHistory() {\n\thistory.print();\n\tload();\n}\n\nfunction historySize() {\n\tconsole.log(`History Size: ${history.size()}`);\n\tload();\n}\n\n/* Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n * impresora compartida que recibe documentos y los imprime cuando así se le indica.\n * La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n * interpretan como nombres de documentos.\n */\n// Solucion con entorno NodeJS\nimport { createInterface } from 'readline';\n\nconst rlPrinter = createInterface({\n\tinput: process.stdin,\n\toutput: process.stdout,\n});\n\nclass printerQueue {\n\tconstructor() {\n\t\tthis.queue = ['Lorem Ipsum'];\n\t}\n\n\tenqueue(document) {\n\t\tthis.queue.push(document);\n\t\treturn this.queue;\n\t}\n\n\tdequeue() {\n\t\treturn this.queue.shift();\n\t}\n\n\tpeek() {\n\t\treturn this.queue[0];\n\t}\n\n\tsize() {\n\t\treturn this.queue.length;\n\t}\n\n\tprint() {\n\t\tconsole.log(this.queue.join('\\n'));\n\t}\n\n\tisEmpty() {\n\t\treturn this.queue.length === 0;\n\t}\n}\n\nconst printer = new printerQueue();\n\nprinterSimulator();\n\nfunction printerSimulator() {\n\tconsole.clear();\n\n\tif (printer.isEmpty()) {\n\t\tconsole.log('Queue is empty');\n\t} else {\n\t\tconsole.log(`Next in queue: ${printer.peek()}`);\n\t}\n\n\trlPrinter.question(\n\t\t'Printer Simulator\\nEnter \"print\" to print next document in queue\\nOr enter a document name to enqueue:',\n\t\t(answer) => {\n\t\t\tswitch (answer) {\n\t\t\t\tcase '':\n\t\t\t\t\tprinterSimulator();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'print':\n\t\t\t\t\tprintStart();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'check':\n\t\t\t\t\tcheckAllQueue();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'delete':\n\t\t\t\t\tdeleteDoc();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'exit':\n\t\t\t\t\tconsole.clear();\n\t\t\t\t\tprocess.exit();\n\n\t\t\t\tdefault:\n\t\t\t\t\taddDocument(answer);\n\t\t\t}\n\t\t}\n\t);\n}\n\nfunction loadPrinter() {\n\tsetTimeout(() => {\n\t\tprinterSimulator();\n\t}, 1000);\n}\n\nfunction printStart() {\n\tif (printer.isEmpty()) {\n\t\tconsole.log('Queue is empty');\n\t} else {\n\t\tconsole.log(`Printing ${printer.dequeue()} ...`);\n\t}\n\tloadPrinter();\n}\n\nfunction addDocument(document) {\n\tconsole.log(`adding document \"${document}\" to the queue...`);\n\tprinter.enqueue(document);\n\tloadPrinter();\n}\n\nfunction checkAllQueue() {\n\tif (printer.isEmpty()) {\n\t\tconsole.log('Queue is empty');\n\t} else {\n\t\tconsole.log(`Next in queue: ${printer.print()}`);\n\t}\n\tloadPrinter();\n}\n\nfunction deleteDoc() {\n\tif (printer.isEmpty()) {\n\t\tconsole.log('Queue is empty');\n\t} else {\n\t\tconsole.log(`Deleting ${printer.dequeue()}...`);\n\t}\n\tloadPrinter();\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/cmejiajulian.js",
    "content": "/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n */\n\n//Pila / Stacks (LIFO)\n//Principio: LIFO (Last In, First Out) - El último elemento que se añade es el primero en salir.\n\nlet stack = [];\nstack.push('1');\nstack.push('2');\nstack.push('3');\n\nconsole.log(stack);\n\nlet elemento = stack.pop();\n\nconsole.log(elemento);\nconsole.log(stack);\n\n//Colas (Queues)\n//Principio: FIFO (First In, First Out) - El primer elemento que se añade es el primero en salir.\n\nlet cola = [];\ncola.push(1);\ncola.push(2);\ncola.push(3);\n\nconsole.log(cola);\nlet elementoC = cola.shift();\nconsole.log(elementoC);\nconsole.log(cola);\n\n\n /* DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n */\n const readline = require('readline');\n\n const rl = readline.createInterface({\n   input: process.stdin,\n   output: process.stdout\n });\n\nlet paginaGuardada =  [];\nlet paginaEliminada = [];\n\nlet paginaB = () => {\n  \n  if(paginaGuardada.length>1){\n    let penultimaW = paginaGuardada[paginaGuardada.length-2];\n    let ultimaW = paginaGuardada.pop();\n    paginaEliminada.push(ultimaW);\n    console.log(penultimaW);\n    }\n  else if (paginaGuardada ===1){\n    let ultimaW = paginaGuardada.pop();\n    paginaEliminada.push(ultimaW);\n    console.log('No hay paginas web anteriores ');}\n  else {\n        console.log('no hay paginas web ');\n  }\n  \n}\n\n\n\nlet paginaw = () =>{\n    \n    rl.question('ingrese una pagina web',(pweb) => {\n\n       paginaGuardada.push(pweb); \n       console.log('Página guardada:', paginaGuardada);\n       website();\n\n\n    });\n} ;\n\n\n\n let website = () => {\n\n    rl.question(' interactua con las palabras adelante, atras, salir, insertar: ', (instruccion) => {\n  \n      if (instruccion === 'salir') {\n        console.log('Saliendo del programa');\n        rl.close();\n        return;\n      }\n\n      else if (instruccion === 'insertar'){\n        paginaw();\n        \n      }\n      else if (instruccion === 'adelante'){\n        if(paginaEliminada.length>0){\n          let ultimaW = paginaEliminada.pop();\n          paginaGuardada.push(ultimaW);\n          console.log(ultimaW);\n        }\n        else{\n          console.log('No haya paginas para avanzar');\n        }\n       website();\n\n      }\n      else if (instruccion === 'atras'){\n        \n        paginaB();\n      \n        website();      \n        \n      }\n\n      \n      else {\n        console.log('ingrese otra instruccion por favor.')\n        website ();\n      }\n    \n  \n    });\n    \n  }\n  paginaw();\n \n\n  \n\n\n\n/*\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n\nlet impresoraGua   = [];\n\nlet impresi = () => {\n  rl.question ('Indique un documento a guardar o escribe CONTINUAR para imprimir : ',(palabra) => {\n    \n    if (palabra === 'CONTINUAR'){\n      imprime();\n      return\n    }\n\n    let numeroElemento = impresoraGua.length + 1;\n    impresoraGua.push({numero:numeroElemento, palabra:palabra});\n    impresoraGua.forEach(item => {\n      console.log(`${item.numero}.${item.palabra}`)\n    });\n\n    console.log('siga el proceso')\n    impresi();\n\n    \n   \n     \n    \n\n     \n  });\n};\n\n\n\nlet imprime = () =>\nrl.question('indique la palabra IMPRIMIR para mostrar el primer elemento,ITEM para imprimir un numero segun la seleccion de la lista, SALIR para cerrar el programa y RETORNAR para volver agregar elementos: ',(imprimir)=>{\n\n  if (imprimir === 'IMPRIMIR'){\n    let ultimaP = impresoraGua.shift();\n    console.log(`El elemento de la cola es: ${ultimaP.numero}. ${ultimaP.palabra}`);\n    imprime();\n  }\n  else if (imprimir === 'SALIR') {\n    console.log('saliendo del programa');\n    rl.close();\n  \n  }\n  else if (imprimir === 'RETORNAR'){\n    impresi()\n    \n  }\n  else if( imprimir ==='ITEM'){\n   \n    rl.question('indique el numero de la lista que desea imprimir',(numero)=>{\n\n      numero = parseInt(numero)-1;\n      if(numero>=0  && numero <impresoraGua.length){\n        let item= impresoraGua[numero];\n        console.log(`El elemento seleccionado es: ${item.numero}. ${item.palabra}`)\n      }else{\n        console.log('Numero no valido');\n      }\n\n        imprime();  \n\n    })\n\n    \n\n\n  }\n  else {\n    console.log('Comando no reconocido. Inténtalo de nuevo.');\n    imprime();  \n  }\n\n})\n\nimpresi();\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/duendeintemporal.js",
    "content": "/* #07 Pilas y Colas  */\n//I use GPT to generate accurate comments and also as a reference.\n\n  //shorthand for console.log()\n  let log = console.log.bind(console);\n\n//The array structure can be useful in JavaScript to simulate stacks and queues.\n\n/* A stack is a linear data structure that follows the Last In, First Out (LIFO) principle. This means that the last element added to the stack is the first one to be removed. You can think of it like a stack of plates: you add plates to the top and also remove them from the top.\nKey Operations:\n\n    Push: Add an element to the top of the stack.\n    Pop: Remove the element from the top of the stack.\n    Peek/Top: Retrieve the top element without removing it.\n    IsEmpty: Check if the stack is empty.\n */\n\n  //Pila(Stack)\n  let stack = [1,2,3,4];\n  \n  //view the contents of a stack\n  log('view stack: ', stack); // view stack: [ 1, 2, 3, 4 ]\n\n  //add an element to the stack\n  stack.push(5);\n  log('add an element: ', stack); // add an element: [ 1, 2, 3, 4, 5 ] \n\n  //get the size of the stack\n  log('size: ', stack.length); // size:  5\n\n  //get the last value of the stack\n  log('last value of the stack: ', stack[stack.length - 1]); // last value of the stack:  5\n\n  //remove the last value from the stack and print its value\n log('delete and return the last value: ', stack.pop()); // delete and return the last value:  5\n\n //empty the stack\n stack = [];\n log('empty the stack: ', stack); // empty the stack: []\n\n /* we can also enclosed in a function or a class for better organization and reusability */\n\n class Stack {\n    constructor(initialItems = []) {\n            this.items = Array.isArray(initialItems) ? initialItems : [];\n    }\n\n    push(element) {\n        this.items.push(element);\n    }\n\n    pop() {\n        if (this.isEmpty()) {\n            console.error(\"Stack is empty. Cannot pop an element.\");\n            return null; \n        }\n        return this.items.pop();\n    }\n\n    peek() {\n        if (this.isEmpty()) {\n            console.error(\"Stack is empty. Cannot peek.\");\n            return null; \n        }\n        return this.items[this.items.length - 1];\n    }\n\n    empty() {\n        return this.items = [];\n    }\n\n    isEmpty() {\n        return this.items.length === 0;\n    }\n\n    size() {\n        return this.items.length;\n    }\n}\n\nconst stack2 = new Stack([55, 76, 98, 100]); \nlog('Initial stack2:', stack2.items); // [55, 76, 98, 100]\n\nstack2.push(32);\nlog('After pushing 32:', stack2.items); // [55, 76, 98, 100, 32]\n\nlog('Peek:', stack2.peek()); // 32\n\nlog('Pop:', stack2.pop()); // 32\nlog('After popping:', stack2.items); // [55, 76, 98, 100]\n\nlog('Pop all elements:');\nwhile (!stack2.isEmpty()) {\n    log('Popped:', stack2.pop());\n} // or we can just empty the stack stack2.empty() \n\nlog('Final stack2:', stack2.items); // []\nlog('Pop from empty stack2:', stack2.pop()); // Stack is empty. Cannot pop an element. & null\n\n\n //Cola(Queue)\n\n /* A queue is a linear data structure that follows the First In, First Out (FIFO) principle. This means that the first element added to the queue is the first one to be removed. You can think of it like a line of people waiting for service: the first person in line is the first to be served.\nKey Operations:\n\n    Enqueue: Add an element to the end of the queue.\n    Dequeue: Remove the element from the front of the queue.\n    Front/Peek: Retrieve the front element without removing it.\n    IsEmpty: Check if the queue is empty.\n */\n\n  let queue = [8,5,4,2,1];\n\n  //view the contents of a queue\n  log('view queue: ', queue); // view queue: [ 8, 5, 4, 2, 1 ]\n\n  //add elements to the queue\n  queue.push(7);\n  log('add an element: ', queue); // add an element: [ 8, 5, 4, 2, 1, 7 ]\n\n  //get the size of the queue\n  log('size: ', queue.length); // size:  6\n\n  //get the first value of the queue\n  log('first value: ', queue[0]); // first value:  8\n\n  //remove the first value from the queue and print its value\n  log('delete and return the first value ', queue.shift()); // delete and return the first value  8\n\n  //empty the queue\n  queue = [];\n  log('empty the queue: ', queue); // empty the queue: [] \n\n /* we can also enclosed in a function or a class for better organization and reusability */\n\n class Queue {\n    constructor(initialItems = []) {\n         this.items = Array.isArray(initialItems) ? initialItems : [];\n    }\n\n    enqueue(element) {\n        this.items.push(element); \n    }\n\n    dequeue() {\n        if (this.isEmpty()) {\n            console.error(\"Queue is empty. Cannot dequeue an element.\");\n            return null;\n        }\n        return this.items.shift();\n    }\n\n    peek() {\n        if (this.isEmpty()) {\n            console.error(\"Queue is empty. Cannot peek.\");\n            return null;\n        }\n        return this.items[0];\n    }\n    empty() {\n        return this.items = [];\n    }\n\n    isEmpty() {\n        return this.items.length === 0;\n    }\n\n    size() {\n        return this.items.length; \n    }\n}\n\nconst queue2 = new Queue([45, 32, 16]); \nlog('Initial queue2:', queue2.items); //  [45, 32, 16]\n\nqueue2.enqueue(77);\nlog('After enqueueing 4:', queue2.items); //  [45, 32, 16, 77]\n\nlog('Peek:', queue2.peek()); //  45\n\nlog('Dequeue:', queue2.dequeue()); //  45\nlog('After dequeueing:', queue2.items); //  [32, 16, 77]\n\nlog('Dequeue all elements:');\nwhile (!queue2.isEmpty()) {\n    log('Dequeued:', queue2.dequeue());\n} // or we can just empty the queue queue2.empty()\n\nlog('Final queue2:', queue2.items); //  []\nlog('Dequeue from empty queue2:', queue2.dequeue()); // Queue is empty. Cannot dequeue an element. & null\n\n\n  //Additional exercises: \n  /* #1 Simulate the behavior of the back and forward buttons in a browser. */\n\n  let documentsQueue = [\n    { name: 'Tratado de Tantra.txt', content: 'Here comes the content of Tratado de Tantra.' },\n    { name: 'Nada Sagrado.doc', content: 'Here comes the content of Nada Sagrado.' },\n    { name: 'El Blanco Invisible.pdf', content: 'Here comes the content of El Blanco Invisible.' }\n];\n\nfunction printQueue(arr){\n    if(arr.length == 0){\n        log('There no element to print in the queue!')\n        return;\n    }\n        while (arr.length > 0) {\n            const document = arr.shift(); // Get the first document\n            log('Printing document:', document.name);\n            log('Content:', document.content);\n       }\n    log('There no more element to print in the queue!')\n}\n\nprintQueue(documentsQueue);/* Printing document: Tratado de Tantra.txt \nContent: Here comes the content of Tratado de Tantra. \nPrinting document: Nada Sagrado.doc \nContent: Here comes the content of Nada Sagrado. \nPrinting document: El Blanco Invisible.pdf \nContent: Here comes the content of El Blanco Invisible. \nThere no more element to print in the queue! */\n\n/* To read and print the contents of documents in JavaScript, you would typically need to use a file reading mechanism. However, JavaScript running in a browser environment does not have direct access to the file system for security reasons. Instead, you can simulate reading the contents of the documents by using predefined content or by using the File API if you're working with file inputs. */\n\nlet urlStack = [];\nlet currentIndex = -1; // To keep track of the current position.\n\nfunction browseWeb(str = prompt('Enter a URL or the word \"forward\" or \"back\" to navigate in the browsing history.')) {\n    const back = () => {\n        if (currentIndex > 0) {\n            currentIndex--;\n            const previousUrl = urlStack[currentIndex];\n            log('Location: ', previousUrl);\n            // window.location = previousUrl; // Navigate to the previous URL.\n        } else {\n            log(\"There are no more pages back..\");\n        }\n    };\n\n    const forward = () => {\n        if (currentIndex < urlStack.length - 1) {\n            currentIndex++;\n            const nextUrl = urlStack[currentIndex];\n            log('Location: ', nextUrl);\n            // window.location = nextUrl; // Navigate to the next URL.\n        } else {\n            log(\"There are no more pages forward.\");\n        }\n    };\n\n    if (str !== 'back' && str !== 'forward') {\n        if (currentIndex < urlStack.length - 1) {\n            urlStack = urlStack.slice(0, currentIndex + 1); // Clear forward if navigation has occurred.\n        } // the standard behavior of a web browser's navigation history,\n        urlStack.push(str);\n        currentIndex++;\n        // window.location = str; // Navigate to the new URL.\n        log('Location: ', str);\n    } else if (str === 'back') {\n        back();\n    } else if (str === 'forward') {\n        forward();\n    }\n}\n\n\nbrowseWeb('www.lectura_prospectiva.net'); // Location:  www.lectura_prospectiva.net\nbrowseWeb('www.test.web'); // Location:  www.test.web\nbrowseWeb('back'); // www.lectura_prospectiva.net           \nbrowseWeb('forward'); // www.test.web\n\n\nwindow.addEventListener('load', ()=>{\n    const body = document.querySelector('body');\n    const title = document.createElement('h1');\n    \n    body.style.setProperty('background', '#000');\n    body.style.setProperty('text-align', 'center');\n    \n    title.textContent = 'Retosparaprogramadores #7.';\n    title.style.setProperty('font-size', '3.5vmax');\n    title.style.setProperty('color', '#fff');\n    title.style.setProperty('line-height', '100vh');\n    \n    body.appendChild(title);\n    \n    setTimeout(()=>{\n    alert('Retosparaprogramadores #7. Please open the Browser Developer Tools.');\n    }, 2000);\n    log( 'Retosparaprogramadores #7'); \n});"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/emedevelopa.js",
    "content": "//PILAS\n\nlet pila = [\"Marea\", \"León\", \"Roberto\"];\nconsole.log(pila);\n\npila.push(\"Maria\");\nconsole.log(pila);\n\npila.pop();\nconsole.log(pila);\n\n//COLAS\n\nlet cola = [1, 2, 3];\nconsole.log(cola);\n\ncola.push(4);\nconsole.log(cola);\n\ncola.shift();\nconsole.log(cola);\n\n\n//EXTRA\n\nclass NavegadorWeb {\n    constructor() {\n        this.historial = []; //Array vacío que almacenará las urls\n        this.indiceActual = -1; // indica la posición en el historial, se establece en -1 por que todavía no hemos visitado nada.\n    }\n\n    navegar(url) {\n        if (this.indiceActual < this.historial.length - 1) { // Verificamos si el usuario ha retrocedido en el historial y luego navegado a una nueva página. Si es así, eliminamos todas las páginas futuras del historial.\n            this.historial.splice(this.indiceActual + 1);\n        }\n        this.historial.push(url); //Añade la url visitada al historial\n        this.indiceActual ++;\n        console.log(\"Navegando a:\", url);\n    }\n\n    retroceder() {\n        if (this.indiceActual > 0) { // verificamos si hay páginas anteriores en el historial.\n            this.indiceActual--; // si hay paginas para retroceder se decrementa el indiceActual\n            console.log(\"Navegando hacia atrás a:\", this.historial[this.indiceActual]);\n        } else {\n            console.log(\"No hay páginas disponibles para retroceder.\");\n        }\n    }\n\n    avanzar() {\n        if (this.indiceActual < this.historial.legth - 1) { //Verificamos si hay páginas disponibles después de la página actual en el historial\n            this.indiceActual++; // si las hay, incrementamos y accedemos a la pag correspondiente en el historial y mostramos mensaje.\n            console.log(\"Navegando hacia adelante a:\", this.historial[this.indiceActual]);\n        } else {\n            console.log(\"No hay páginas disponibles para avanzar.\");\n        }\n    }\n}\n\nconst navegador = new NavegadorWeb();\nnavegador.navegar(\"www.google.com\");\nnavegador.navegar(\"www.twitter.com\");\nnavegador.retroceder();\nnavegador.avanzar();\n\n\nclass Impresora {\n    constructor () {\n        this.cola = [];\n    }\n\n    añadirDocumento(documento) {\n        this.cola.push(documento);\n    }\n\n    imprimir() {\n        if (this.cola.length > 0) {\n            const documento = this.cola.shift();\n            console.log(`Imprimiendo documento: ${documento}`);\n        } else {\n            console.log(\"No hay nada que imprimir\");\n        }\n    }\n}\n\nconst impresoraCompartida = new Impresora();\n\nimpresoraCompartida.añadirDocumento(\"Documento 1\");\nimpresoraCompartida.añadirDocumento(\"Documento 2\");\n\nimpresoraCompartida.imprimir();\nimpresoraCompartida.imprimir();\nimpresoraCompartida.imprimir();\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/eulogioep.js",
    "content": "const readline = require('readline');\n\n// Implementación de la Pila (Stack - LIFO)\nclass Stack {\n    constructor() {\n        this.items = [];\n    }\n\n    // Método para añadir un elemento a la pila\n    push(element) {\n        this.items.push(element);\n    }\n\n    // Método para quitar un elemento de la pila\n    pop() {\n        if (this.isEmpty()) {\n            console.log(\"Error: Pila vacía\");\n            return null;\n        }\n        return this.items.pop();\n    }\n\n    // Método para verificar si la pila está vacía\n    isEmpty() {\n        return this.items.length === 0;\n    }\n\n    // Método para obtener el elemento en la cima de la pila sin quitarlo\n    peek() {\n        if (this.isEmpty()) {\n            console.log(\"Error: Pila vacía\");\n            return null;\n        }\n        return this.items[this.items.length - 1];\n    }\n}\n\n// Implementación de la Cola (Queue - FIFO)\nclass Queue {\n    constructor() {\n        this.items = [];\n    }\n\n    // Método para añadir un elemento a la cola\n    enqueue(element) {\n        this.items.push(element);\n    }\n\n    // Método para quitar un elemento de la cola\n    dequeue() {\n        if (this.isEmpty()) {\n            console.log(\"Error: Cola vacía\");\n            return null;\n        }\n        return this.items.shift();\n    }\n\n    // Método para verificar si la cola está vacía\n    isEmpty() {\n        return this.items.length === 0;\n    }\n\n    // Método para obtener el primer elemento de la cola sin quitarlo\n    peek() {\n        if (this.isEmpty()) {\n            console.log(\"Error: Cola vacía\");\n            return null;\n        }\n        return this.items[0];\n    }\n}\n\n// Función para el simulador de navegador web\nfunction webBrowserSimulator() {\n    const backStack = new Stack();\n    const forwardStack = new Stack();\n    let currentPage = \"\";\n\n    const rl = readline.createInterface({\n        input: process.stdin,\n        output: process.stdout\n    });\n\n    console.log(\"Simulador de navegador web (escribe 'salir' para terminar):\");\n\n    function askForAction() {\n        rl.question(\"Ingresa una acción o nombre de página web: \", (input) => {\n            input = input.trim().toLowerCase();\n\n            if (input === 'salir') {\n                rl.close();\n                printerSimulator();\n            } else if (input === 'atrás') {\n                if (!backStack.isEmpty()) {\n                    forwardStack.push(currentPage);\n                    currentPage = backStack.pop();\n                    console.log(\"Página actual:\", currentPage);\n                } else {\n                    console.log(\"No hay páginas anteriores\");\n                }\n            } else if (input === 'adelante') {\n                if (!forwardStack.isEmpty()) {\n                    backStack.push(currentPage);\n                    currentPage = forwardStack.pop();\n                    console.log(\"Página actual:\", currentPage);\n                } else {\n                    console.log(\"No hay páginas siguientes\");\n                }\n            } else {\n                if (currentPage) {\n                    backStack.push(currentPage);\n                }\n                forwardStack = new Stack();  // Limpia la pila de adelante\n                currentPage = input;\n                console.log(\"Página actual:\", currentPage);\n            }\n\n            askForAction();\n        });\n    }\n\n    askForAction();\n}\n\n// Función para el simulador de impresora compartida\nfunction printerSimulator() {\n    const printQueue = new Queue();\n\n    const rl = readline.createInterface({\n        input: process.stdin,\n        output: process.stdout\n    });\n\n    console.log(\"\\nSimulador de impresora compartida (escribe 'salir' para terminar):\");\n\n    function askForDocument() {\n        rl.question(\"Ingresa un nombre de documento o 'imprimir': \", (input) => {\n            input = input.trim().toLowerCase();\n\n            if (input === 'salir') {\n                rl.close();\n                return;\n            } else if (input === 'imprimir') {\n                const document = printQueue.dequeue();\n                if (document) {\n                    console.log(\"Imprimiendo:\", document);\n                }\n            } else {\n                printQueue.enqueue(input);\n                console.log(\"Documento añadido a la cola:\", input);\n            }\n\n            askForDocument();\n        });\n    }\n\n    askForDocument();\n}\n\n// Iniciar el simulador de navegador web\nwebBrowserSimulator();"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/garos01.js",
    "content": "// Implementación de una pila (stack) utilizando un array\nfunction crearPila() {\n  const items = [];\n\n  function push(element) {\n    items.push(element);\n  }\n\n  function pop() {\n    if (isEmpty()) {\n      return \"La pila está vacía\";\n    }\n    return items.pop();\n  }\n\n  function isEmpty() {\n    return items.length === 0;\n  }\n\n  function peek() {\n    if (isEmpty()) {\n      return \"La pila está vacía\";\n    }\n    return items[items.length - 1];\n  }\n\n  function size() {\n    return items.length;\n  }\n\n  return { push, pop, isEmpty, peek, size };\n}\n\n// Implementación de una cola (queue) utilizando un array\nfunction crearCola() {\n  const items = [];\n\n  function enqueue(element) {\n    items.push(element);\n  }\n\n  function dequeue() {\n    if (isEmpty()) {\n      return \"La cola está vacía\";\n    }\n    return items.shift();\n  }\n\n  function isEmpty() {\n    return items.length === 0;\n  }\n\n  function front() {\n    if (isEmpty()) {\n      return \"La cola está vacía\";\n    }\n    return items[0];\n  }\n\n  function size() {\n    return items.length;\n  }\n\n  return { enqueue, dequeue, isEmpty, front, size };\n}\n\n// Ejemplo de la pila\nconst pila = crearPila();\npila.push(1);\npila.push(2);\npila.push(3);\n\nconsole.log(\"Elemento superior de la pila:\", pila.peek());\nconsole.log(\"Desapilando:\", pila.pop());\nconsole.log(\"Elemento superior de la pila después de desapilar:\", pila.peek());\n\n// Ejemplo de la cola\nconst cola = crearCola();\ncola.enqueue(\"A\");\ncola.enqueue(\"B\");\ncola.enqueue(\"C\");\n\nconsole.log(\"Primer elemento de la cola:\", cola.front());\nconsole.log(\"Desencolando:\", cola.dequeue());\nconsole.log(\"Primer elemento de la cola después de desencolar:\", cola.front());\n\n// Ejercicio extra\n// Pila\nfunction simularNavegador() {\n  const historial = crearPila();\n\n  function navegarA(pagina) {\n    historial.push(pagina);\n    console.log(\"Navegando a:\", pagina);\n  }\n\n  function adelante() {\n    const paginaSiguiente = historial.pop();\n    if (paginaSiguiente) {\n      console.log(\"Avanzando a:\", paginaSiguiente);\n    } else {\n      console.log(\"No hay páginas siguientes en el historial\");\n    }\n  }\n\n  function atras() {\n    const paginaAnterior = historial.pop();\n    if (paginaAnterior) {\n      console.log(\"Retrocediendo a:\", paginaAnterior);\n    } else {\n      console.log(\"No hay páginas anteriores en el historial\");\n    }\n  }\n\n  return { navegarA, adelante, atras };\n}\n\n// Uso\nconst navegador = simularNavegador();\n\nnavegador.navegarA(\"Google\");\nnavegador.navegarA(\"Facebook\");\nnavegador.navegarA(\"Twitter\");\n\nnavegador.atras();\nnavegador.adelante();\nnavegador.atras();\nnavegador.atras();\nnavegador.adelante();\nnavegador.atras();\n\n// Cola\nfunction simularImpresora() {\n  const colaImpresion = crearCola();\n\n  function recibirDocumento(documento) {\n    colaImpresion.enqueue(documento);\n    console.log(\"Documento recibido:\", documento);\n  }\n\n  function imprimir() {\n    const documentoAImprimir = colaImpresion.dequeue();\n    if (documentoAImprimir) {\n      console.log(\"Imprimiendo documento:\", documentoAImprimir);\n    } else {\n      console.log(\"No hay documentos en la cola de impresión\");\n    }\n  }\n\n  return { recibirDocumento, imprimir };\n}\n\n// Ejemplo de uso\nconst impresora = simularImpresora();\n\nimpresora.recibirDocumento(\"Documento1.txt\");\nimpresora.recibirDocumento(\"Documento2.pdf\");\nimpresora.recibirDocumento(\"Documento3.doc\");\n\nimpresora.imprimir();\nimpresora.imprimir();\nimpresora.imprimir();\nimpresora.imprimir();\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/gianbordon.js",
    "content": "/* EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n\n//\n// Pilas \n//\n\nconsole.group('|* PILAS *|')\nlet pila = []\n\n// Agregar elementos \npila.push(\"Elemento 1\")\npila.push(\"Elemento 2\")\npila.push(\"Elemento 3\")\n\nconsole.log(\"Pila actual:\", pila) \nconsole.log(\"Tamaño de la pila:\", pila.length) \n\n\n// Eliminar elemento (se elimina el ultimo en entrar a la pila)\nlet ultimo = pila.pop()\nconsole.log(\"Elemento retirado:\", ultimo)\nconsole.log(\"Pila después del pop:\", pila) \nconsole.log(\"Tamaño actualizado:\", pila.length)\n\n// Ver elemento sin Eliminar\nlet tope = pila[pila.length - 1]\nconsole.log(\"Elemento en el tope:\", tope) \nconsole.groupEnd()\n\n//\n// Colas\n//\n\nconsole.group('|* COLAS *|')\nlet cola = []\n\n// Agregar elementos (siempre al final, posicionandose ultimo)\ncola.push(\"Persona 1\")\ncola.push(\"Persona 2\")\ncola.push(\"Persona 3\")\n\nconsole.log(\"Cola actual:\", cola) \nconsole.log(\"Tamaño de la cola:\", cola.length) \n\n// Eliminar elemento (siempre el primero que ingreso)\nlet atendido = cola.shift() \nconsole.log(\"Atendido:\", atendido)\nconsole.log(\"Cola después del dequeue:\", cola)\nconsole.log(\"Tamaño actualizado:\", cola.length)\n\n// Ver quién es el siguiente en Eliminar\nlet primero = cola[0]\nconsole.log(\"Siguiente en la cola:\", primero)\nconsole.groupEnd()\n\n//\n// EXTRA\n//\n\n// * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n// *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n// *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n// *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n// *   el nombre de una nueva web.\n\nconst readline = require(\"readline\")\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout,\n})\n\nfunction mainMenu() {\n    console.clear()\n    console.log(\"╔═══════════════════════════════════════╗\")\n    console.log(\"║         MENÚ PRINCIPAL                ║\")\n    console.log(\"╠═══════════════════════════════════════╣\")\n    console.log(\"║ 1. Navegar en el navegador            ║\")\n    console.log(\"║ 2. Usar la impresora                  ║\")\n    console.log(\"║ 0. Salir                              ║\")\n    console.log(\"╚═══════════════════════════════════════╝\")\n\n    rl.question(\"Selecciona una opción (1 o 2, 0 para salir): \", (opc) => {\n        switch (opc) {\n            case \"1\":\n                console.log(\"→ Accediendo al navegador.\")\n                web()\n                break\n            case \"2\":\n                console.log(\"→ Accediendo a la impresora.\")\n                impresora()\n                break\n            case \"0\":\n                console.log(\"→ Programa finalizado.\")\n                rl.close(); \n                break\n            default:\n                console.log(\"❌ Opción inválida.\")\n                setTimeout(mainMenu, 1500)\n                break\n        }\n    })\n}\n\nlet pagesBack = []\nlet pagesForward = []\nlet actualPage = null\n\nfunction web(){\n    console.clear()\n    console.log(\"╔════════════════════════════════════════════╗\")\n    console.log(\"║             GIANSIN BROWSER                ║\")\n    console.log(\"╠════════════════════════════════════════════╣\")\n    console.log(\"║                                            ║\")\nif(actualPage !== null){\n    console.log(`║             ${actualPage}                  ║`)\n}else {\n    console.log(\"║       No hay una página cargada aún        ║\")\n}\n    console.log(\"║                                            ║\")\n    console.log(\"║  <= Atrás                     Adelante =>  ║\")\n    console.log(\"║                                            ║\")\n    console.log(\"║                Salir                       ║\")\n    console.log(\"╚════════════════════════════════════════════╝\")\n    rl.question('Ingrese \"atrás\" o \"adelante\" o \"salir\" o una nueva pagina para comenzar a navegar: ', (res)=>{\n        res = res.toLowerCase().trim()\n        if (res === \"\") {\n            console.log(\"❌ Entrada vacía. Por favor ingrese una opción válida.\")\n            setTimeout(web, 1000)\n        } else if(res === \"salir\"){\n            console.log(\"Gracias por usar el navegador. ¡Hasta luego!\")\n            mainMenu()\n        } else if (res === \"adelante\") {\n            nextPage()\n        } else if (res === \"atras\") {\n            prevPage()\n        } else {\n            browse(res)\n        }\n    })\n}\n\nfunction nextPage(){\n    if(pagesForward.length === 0){\n        console.log(\"❌ No hay más páginas adelante.\")\n    } else {\n        const nextPage = pagesForward.pop()\n        pagesBack.push(actualPage)\n        actualPage = nextPage\n        console.log(`🔜 Ahora estás en: ${actualPage}`)\n    }\n    setTimeout(web, 1000)\n}\n\nfunction prevPage(){\n    if(pagesBack.length === 0){\n        console.log(\"❌ No hay más páginas atrás.\")\n    } else {\n        const prevPage = pagesBack.pop()\n        pagesForward.push(actualPage)\n        actualPage = prevPage\n        console.log(`🔙 Ahora estás en: ${actualPage}`)\n    }\n    setTimeout(web, 1000)\n}\n\nfunction browse(res){\n    if(res !== null){\n        pagesBack.push(res)\n    }\n    actualPage = res\n    console.log(`🔍 Ahora estás navegando en: ${actualPage}`)\n    pagesForward = []\n    setTimeout(web, 1000)\n}\n\n// * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n// *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n// *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n// *   interpretan como nombres de documentos.\n\nlet archivos = []\n\nfunction impresora() {\n    console.clear()\n\n    console.log(\"╔═══════════════════════════════════════╗\")\n    console.log(\"║         🖨 IMPRESORA XP_2000          ║\")\n    console.log(\"╠═══════════════════════════════════════╣\")\n    console.log(\"║ 1. Agregar documento                  ║\")\n    console.log(\"║ 2. Imprimir                           ║\")\n    console.log(\"║ 3. Lista de documentos                ║\")\n    console.log(\"║ 0. Salir                              ║\")\n    console.log(\"╚═══════════════════════════════════════╝\")\n\n    rl.question(\"Seleccioná una opción (1 al 3): \", (opc) => {\n        switch (opc) {\n        case \"1\":\n            console.log(\"→ Elegiste AGREGAR documento.\")\n            addDocument()\n            break\n        case \"2\":\n            console.log(\"→ Elegiste Imprimir.\")\n            printDocument()\n            break\n        case \"3\":\n            console.log(\"→ Elegiste LISTA de documentos.\")\n            showDocuments()\n            break\n        case \"0\":\n            console.log(\"→ Programa finalizado.\")\n            mainMenu()\n            break\n        default:\n            console.log(\"❌ Opción inválida.\")\n            setTimeout(impresora, 1500)\n        }\n    })\n}\n\nfunction addDocument(){\n    rl.question('Ingrese el nombre del documento PDF que desea ingresar: ', (doc) =>{\n        if (doc.endsWith(\".pdf\")) {\n            archivos.push(doc)\n            console.log(`✅ El archivo \"${doc}\" fue agregado a la cola de archivos para imprimir correctamente.`)\n            backToMenu()\n        } else {\n            console.log('🔁 Archivo inválido., el archivo debe ser .pdf, intente nuevamente.')\n            addDocument()\n        }\n    })\n}\n\nfunction printDocument(){\n    if (archivos.length !== 0){\n        console.log(`Impriminedo el primer archivo de la cola: \"${archivos[0]}\"`)\n        archivos.shift()\n        console.log('✅ Archivo impreso.')\n        backToMenu()\n    } else {\n        console.log('❌ No hay archivos pendientes para imprimir.')\n        backToMenu()\n    }\n}\n\nfunction showDocuments(){\n    if (archivos.length === 0) {\n        console.log(\"❌ No hay archivos en la cola.\")\n    } else {\n        console.log(\"Lista de Archivos pendientes:\")\n        archivos.forEach((doc, index) => {\n            console.log(`${index + 1}. ${doc}`)\n        })\n    }\n    backToMenu()\n}\n\nfunction backToMenu(){\n    rl.question('Presiona ENTER para volver al menú...', ()=>{\n        impresora()\n    })\n}\n\nmainMenu()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/giovanyosorio.js",
    "content": "/* EJERCICIO:\n* Implementa los mecanismos de introducción y recuperación de elementos propios de las\n* pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n* o lista (dependiendo de las posibilidades de tu lenguaje).\n*\n* DIFICULTAD EXTRA (opcional):\n* - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n*   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n*   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n*   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n*   el nombre de una nueva web.\n* - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n*   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n*   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n*   interpretan como nombres de documentos.\n*/\n\n// PILA (STACK - LIFO)\nclass Stack {\n    constructor() {\n        this.items = [];\n    }\n\n    push(element) {\n        this.items.push(element);\n    }\n\n    pop() {\n        if (this.items.length === 0) {\n            return \"Underflow\";\n        }\n        return this.items.pop();\n    }\n\n    peek() {\n        return this.items[this.items.length - 1];\n    }\n\n    isEmpty() {\n        return this.items.length === 0;\n    }\n}\n\n// Ejemplo de uso\nconst stack = new Stack();\nstack.push(\"Google\");\nstack.push(\"YouTube\");\nstack.push(\"Facebook\");\nconsole.log(stack.pop()); // Facebook\nconsole.log(stack.peek()); // YouTube\n\n\n//Cola (Queue - FIFO)\n\nclass Queue {\n    constructor() {\n        this.items = [];\n    }\n\n    enqueue(element) {\n        this.items.push(element);\n    }\n\n    dequeue() {\n        if (this.isEmpty()) {\n            return \"Underflow\";\n        }\n        return this.items.shift();\n    }\n\n    front() {\n        if (this.isEmpty()) {\n            return \"No elements in Queue\";\n        }\n        return this.items[0];\n    }\n\n    isEmpty() {\n        return this.items.length === 0;\n    }\n}\n\n// Ejemplo de uso\nconst queue = new Queue();\nqueue.enqueue(\"Documento1\");\nqueue.enqueue(\"Documento2\");\nqueue.enqueue(\"Documento3\");\nconsole.log(queue.dequeue()); // Documento1\nconsole.log(queue.front()); // Documento2\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/hectorio23.js",
    "content": "// Autor: Héctor Adán \n// GitHub: https://github.com/hectorio23 \nconst readline = require('readline');\n\n/******************************************\n************* CLASE WebPage ***************\n******************************************/\n\nclass WebPage {\n    constructor(title, index) {\n        this.title = title;\n        this.index = index;\n    }\n\n    getInfo() {\n        console.log(`<Object WebPage - ${this.title} at ${this}>`);\n    }\n}\n\n/******************************************\n************* CLASE Stack *****************\n******************************************/\n\nclass Stack {\n    constructor() {\n        this.items = [];\n    }\n\n    push(item) {\n        this.items.push(item);\n    }\n\n    pop() {\n        if (!this.isEmpty()) {\n            return this.items.pop();\n        }\n    }\n\n    isEmpty() {\n        return this.items.length === 0;\n    }\n\n    get size() {\n        return this.items.length;\n    }\n}\n\n/******************************************\n************* CLASE Queue *****************\n******************************************/\n\nclass Queue {\n    constructor() {\n        this.items = [];\n    }\n\n    push(item) {\n        this.items.push(item);\n    }\n\n    pop() {\n        if (!this.isEmpty()) {\n            return this.items.shift();\n        }\n    }\n\n    isEmpty() {\n        return this.items.length === 0;\n    }\n\n    get size() {\n        return this.items.length;\n    }\n}\n\n/******************************************\n************* FUNCIONES *******************\n******************************************/\n\nfunction imprimirMenu(counter) {\n    const stack = new Stack();\n    const backStack = new Stack();\n    let index = new WebPage(\"index\", counter);\n    stack.push(index);\n\n    const rl = readline.createInterface({\n        input: process.stdin,\n        output: process.stdout\n    });\n\n    rl.setPrompt(\"\\nOpción del usuario> \");\n\n    rl.on('line', (choose) => {\n        choose = choose.trim();\n\n        if (choose.length > 1) {\n            let temporal = new WebPage(choose, counter);\n            stack.push(temporal);\n        } else if (choose.toLowerCase() === 'a' && stack.size > 1) {\n            let otroTemporal = stack.pop();\n            otroTemporal.getInfo();\n            stack.items[stack.size - 1].getInfo();\n            backStack.push(otroTemporal);\n            console.log(\"Mostrando página anterior...\");\n        } else if (choose.toLowerCase() === 's' && backStack.size > 0) {\n            let atrasTemporal = backStack.pop();\n            atrasTemporal.getInfo();\n            stack.items[stack.size - 1].getInfo();\n            stack.push(atrasTemporal);\n            console.log(\"Mostrando siguiente página...\");\n        } else {\n            console.log(\"Opción no disponible. Por favor, crea una página web.\");\n        }\n\n        rl.prompt();\n    });\n\n    rl.prompt();\n}\n\n/******************************************\n************* PROGRAMA PRINCIPAL **********\n******************************************/\n\nlet q1 = new Queue();\nlet s1 = new Stack();\nlet counter = 1;\n\n/******************************************\n******** USO DE UN STACK DINÁMICO *********\n******************************************/\n\nconsole.log(\"\\n************ USO DE UN STACK DINÁMICO ************\");\n\nlet w1 = new WebPage(\"Index\", 2);\nlet w2 = new WebPage(\"Account\", 5);\nlet w3 = new WebPage(\"Login\", 6);\n\nconsole.log(`\\nCantidad de elementos de Stack antes de agregarlos: ${s1.size} elementos`);\ns1.push(w1);\ns1.push(w2);\ns1.push(w3);\nconsole.log(`Cantidad de elementos de Stack después de agregarlos: ${s1.size} elementos`);\n\ns1.pop();\ns1.pop();\ns1.pop();\nconsole.log(`Cantidad de elementos de Stack después de eliminarlos: ${s1.size} elementos`);\n\n/******************************************\n******** USO DE UN QUEUE DINÁMICO *********\n******************************************/\n\nconsole.log(\"\\n************ USO DE UN QUEUE DINÁMICO ************\");\n\nconsole.log(`\\nCantidad de elementos de Queue antes de agregarlos: ${q1.size} elementos`);\nq1.push(w1);\nq1.push(w2);\nq1.push(w3);\nconsole.log(`Cantidad de elementos de Queue después de agregarlos: ${q1.size} elementos`);\n\nq1.pop();\nq1.pop();\nq1.pop();\nconsole.log(`Cantidad de elementos de Queue después de eliminarlos: ${q1.size} elementos`);\n\n/******************************************\n************* MENU PRINCIPAL **************\n******************************************/\n\nimprimirMenu(counter);\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/jaxi86.js",
    "content": "/*\n* EJERCICIO:\n* Implementa los mecanismos de introducción y recuperación de elementos propios de las\n* pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n* o lista (dependiendo de las posibilidades de tu lenguaje).\n*\n* DIFICULTAD EXTRA (opcional):\n* - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n*   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n*   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n*   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n*   el nombre de una nueva web.\n* - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n*   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n*   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n*   interpretan como nombres de documentos.\n*/\nconsole.log('pilas');\nlet array = [4, 6, 1, 8, 2, 9];\nconsole.log(array);\n\narray.push(10);//aqui uso la introduccion a la pila\nconsole.log(array);\n\nconsole.log(array.pop());//aqui accedo para recuperar el TOS\nconsole.log(array);\n\nconsole.log(' ');\n\nconsole.log('colas');\nlet arreglo = [1, 7, 4, 2];\nconsole.log(arreglo);\n\narreglo.push(3);//aqui introdusco un elemento segun las espesificaciones de una cola\nconsole.log(arreglo);\n\nconsole.log(arreglo.shift());// aqui accedo al elementos de indice cero (el primero en entrar) tal como las espesificaciones de una cola me lo indica\nconsole.log(arreglo);\n\nconsole.log(' ');\n\nconsole.log('DIFICULTAD EXTRA');\n/* \n- Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\nde un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\nque te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\nLas palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\nel nombre de una nueva web. */\n\n\nfunction web() {\n    let pila = [];\n\n    while (true) {\n        let opcion = prompt(\"agrega una pagina o escribe adelante/atras para navegar en las distintas paginas o salir para salir del panel\");\n\n        if (opcion === \"salir\") {\n            break;\n        } else if (opcion === \"adelante\") {\n            // No se puede volver a delante, pero podríamos mostrar un mensaje\n            console.log(\"No se puede ir hacia adelante\");\n        } else if (opcion === \"atras\" && pila.length > 0) {\n            pila.pop();\n        } else {\n            pila.push(opcion);\n        }\n\n        // Mostrar la página actual solo si la pila no está vacía\n        if (pila.length > 0) {\n            console.log(`Página actual: ${pila[pila.length - 1]}`);\n        }\n    }\n}\n\n//web();  comento la llamada a la funcion para poder hacer la siguinete\n\n/* - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n*   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n*   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n*   interpretan como nombres de documentos.\n*/ \n\nfunction impresora () {\n    let cola =[];\n    while (true) {\n        let opcion = prompt(\"escribe el nombre del ducumento o la palabra 'imprimir', imprime el primer documento\", \"imprimir\");\n\n        if (opcion === \"salir\") {\n            console.log(\"salio del programa\");\n            break;\n        } else if (opcion === \"imprimir\" && cola.length > 0) {\n            console.log(`documento que se esta imprimiendo: ${cola.shift()}`);\n        } else {\n            cola.push(opcion);\n        }\n    }\n}\n\nimpresora();\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/jeronimocardu.js",
    "content": "const pages = ['youtube', 'facebook', 'github', 'instagram', 'google']\n\nfunction web(navegation) {\n  console.log(`Actualmente estas en - ${pages[0]} -`)\n  if (navegation == 'atras') {\n    pages.unshift(pages[pages.length - 1])\n    pages.pop()\n  } else if (navegation == 'adelante') {\n    pages.push(pages[0])\n    pages.shift()\n  } else if (navegation != '') {\n    pages.push(navegation)\n  }\n  console.log(`Actualmente estas en - ${pages[0]} -`)\n}\n\nconst docs = []\n\nfunction imprimir(action) {\n  if (action == 'imprimir' && docs.length == 0)\n    console.log('No hay documentos para imprimir')\n  if (action == 'imprimir') {\n    while (docs.length > 0) {\n      console.log('imprimiendo...' + docs.shift())\n    }\n  } else {\n    docs.unshift(action)\n    console.log('Your Documents: ' + docs)\n  }\n}\n\nimprimir('doc - 1')\nimprimir('doc - 2')\nimprimir('doc - 3')\nimprimir('imprimir')\nimprimir('doc - 4')\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/jhoshmc.js",
    "content": "// todo ---------------------------------------------------- pilas -----------------------------------\n//* mostarndo pila con un array\n//* por defecto con array ya vienen push,pop,size,print, solo faltaria agregar peek,\n//* que seria el tamaño del apila -1\n//* clase pila\nclass Stack {\n  //?atributos: son las propiedades que definen al ogjeto\n  constructor() {\n    this.stack = [];\n  }\n  //? metodos: son la acciones que puede realizar el objeto(funciones)\n  //* poner un elemento al tope de la pila\n  push(elemento) {\n    this.stack.push(elemento);\n    return this.stack;\n  }\n  //* eliminar el último elemento y retornar ese elemento\n  pop() {\n    return this.stack.pop();\n  }\n  //* Retorna el último valor de la pila sin sacarla de ella\n  peek() {\n    return this.stack[this.stack.length - 1];\n  }\n  //* retorna el número de elementos que hay en la pila\n  size() {\n    return this.stack.length;\n  }\n  //* muestra el contenido de la pila\n  print() {\n    console.log(this.stack);\n  }\n}\nfunction ejecutandoStack() {\n  const stack = new Stack();\n  console.log(`tamaño de la pila: ${stack.size()}`);\n  console.log(\"agregando elementos a la pila\");\n  stack.push(1);\n  stack.push(2);\n  stack.push(3);\n  console.log(\"mostarndo pila\");\n  stack.print();\n  console.log(\"eliminando elemenos de la pila \");\n  let el = stack.pop();\n  console.log(`retorno del valor y eliminado: ${el}`);\n  stack.print();\n  console.log(`retornando el ulimo valor sin eliminarlo: ${stack.peek()}`);\n  console.log(`tamalo de la pila: ${stack.size()}`);\n}\n\n// ejecutandoStack();\n\n//* pila usando un objeto\nclass ObjectStack {\n  //* atributos\n  constructor() {\n    this.stack = {};\n    this.count = 0; //* se agrega count, como referencia de la posicion actual y saber cuantos elementos hay agregados\n  }\n  //* metodos\n  push(element) {\n    /**\n     ** para agregar un elemento al objeto,con count se hace referencia a la posicion actual y se hace una\n     ** asignacion directa, se incrementa el contador(numero de elementos) y se retorna el objeto\n     */\n    this.stack[this.count] = element;\n    this.count++;\n    return this.stack;\n  }\n  pop() {\n    /**\n     ** para eliminar el elemento superior en la pila y retornal el valor:\n     ** primero se decrementa el contador, para ver el valor del elemento, el tamaño tal-1 para ver el valor de esa posicion\n     ** luego se guarda ese valor en una variable\n     ** despues se elimina ese valor de la pila\n     ** y por último se retorna el valor de esa posicion previamente extraida\n     */\n    this.count--;\n    const elemento = this.stack[this.count];\n    delete this.stack[this.count];\n    return elemento;\n  }\n  peek() {\n    //* retornamos el último valor de la pila, sin eliminarlo\n    return this.stack[this.count - 1];\n  }\n  size() {\n    //* se retorna el tamaño de la pila\n    return this.count;\n  }\n  print() {\n    //* se muestra los elementos que están en la pila\n    console.log(this.stack);\n  }\n}\nfunction ejecutandoObjectStack() {\n  const oStack = new ObjectStack();\n  console.log(`el tamaño actual de la pila es: ${oStack.size()}`);\n  console.log(\"agregando elementos a la pila \");\n  oStack.push(\"uno\");\n  oStack.push(\"dos\");\n  oStack.push(\"tres\");\n  console.log(`el tamaño actual de la pila es: ${oStack.size()}`);\n  console.log(\"mostrando la pila\");\n  oStack.print();\n  console.log(`sacando un elemento de la pila: ${oStack.pop()}`);\n  console.log(`mostrando el ultimo elemento de la pila: ${oStack.peek()}`);\n  console.log(\"mostrando la pila\");\n  oStack.print();\n}\n// ejecutandoObjectStack();\n\n//todo -------------------------------------- colas ------------------------------------------\n\nclass Queque {\n  //* atributos\n  constructor() {\n    this.queue = [];\n  }\n  //* metodos\n  add(elemento) {\n    //* se va a usar push(), que agrega un nuevo elemento al final del array, retorna la longitud\n    this.queue.push(elemento);\n    return this.queue;\n  }\n  //* retornar el primer valor de la cola, sin removerlo\n  front() {\n    return this.queue[0];\n  }\n  //* retornar el ultimo valor de la cola, sin removerlo\n  back() {\n    return this.queue[this.queue.length - 1];\n  }\n  //* mostrar cola\n  print() {\n    console.log(this.queue);\n  }\n  //* eliminar el primer elemento de la cola Y retornar su valor\n  pop() {\n    return this.queue.shift();\n  }\n  //* retornar el tamaño de la cola\n  size() {\n    return this.queue.length;\n  }\n}\n\nfunction ejecutandoQueque() {\n  const queque = new Queque();\n  console.log(`tamaño de la cola: ${queque.size()}`);\n  console.log(`agregando elementos a la cola .....`);\n  queque.add(\"primero\");\n  queque.add(\"segundo\");\n  queque.add(\"tercero\");\n  console.log(`tamaño de la cola: ${queque.size()}`);\n  console.log(\" mostrando cola: \");\n  queque.print();\n  console.log(`quitando elementod e la cola: ${queque.pop()}`);\n  queque.print();\n  console.log(`mostrando primer elemento de la cola: ${queque.front()}`);\n  console.log(`mostrando ultimo elemento de la cola: ${queque.back()}`);\n}\n\n// ejecutandoQueque();\n\nclass ObjectQueque {\n  //* atributos\n  constructor() {\n    this.queque = {};\n    this.count = 0;\n  }\n  //* metodos\n  add(element) {\n    this.queque[this.count] = element;\n    this.count++;\n    return this.queque;\n  }\n  pop() {\n    this.count--;\n    const val = this.queque[0];\n    const length = Object.keys(this.queque).length;\n    for (let i = 0; i < length - 1; i++) {\n      this.queque[i] = this.queque[i + 1];\n    }\n    delete this.queque[length - 1];\n    return val;\n  }\n  front() {\n    return this.queque[0];\n  }\n  back() {\n    return this.queque[this.count - 1];\n  }\n  print() {\n    console.log(this.queque);\n  }\n  size() {\n    return this.count;\n  }\n}\nfunction ejecutandoObjectQueque() {\n  const oQueque = new ObjectQueque();\n  console.log(`tamaño de la cola: ${oQueque.size()}`);\n  console.log(\"agregando elementos a la cola: \");\n  oQueque.add(\"primero\");\n  oQueque.add(\"segundo\");\n  oQueque.add(\"tercero\");\n  console.log(`tamaño de la cola: ${oQueque.size()}`);\n  console.log(`primer elemento de la cola: ${oQueque.front()}`);\n  console.log(`ultimo elemento en la cola: ${oQueque.back()}`);\n  console.log(\"mostrando cola: \");\n  oQueque.print();\n  console.log(`eliminando elemento de la cola: ${oQueque.pop()}`);\n  oQueque.print();\n  console.log(`eliminando elemento de la cola: ${oQueque.pop()}`);\n  oQueque.print();\n  console.log(`eliminando elemento de la cola: ${oQueque.pop()}`);\n  oQueque.print();\n  console.log(`tamaño de la cola: ${oQueque.size()}`);\n}\n\n// ejecutandoObjectQueque();\n\n//! ejercicios extra\nconst readline = require(\"readline\");\n\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout,\n});\n\nconst preguntar = (texto) => {\n  return new Promise((resolve) => rl.question(texto, resolve));\n};\n\nasync function historialWeb() {\n  const historialAtras = new Stack();\n  const historialSiquiente = new Stack();\n  let paginaActual = \"inicio\";\n  let option;\n  console.log(\"\\t historial web: \\n\");\n  console.log(\"vienvenido al historial web, hay 4 opciones: \");\n  const data = [\n    { option: \"visitar citio\", accion: \"ingresar el nombre de la pagina\" },\n    { option: \"retroceder\", accion: \"ingresar b\" },\n    { option: \"siguiente\", accion: \"ingresar n\" },\n    { option: \"salir\", accion: \"ingresar s\" },\n  ];\n  console.table(data);\n  while (true) {\n    console.log(`\\npagina actual: ${paginaActual}`);\n    option = await preguntar(\"ingrese option: \");\n    let copia = option.toLowerCase();\n    if (copia == \"b\" || copia == \"n\" || copia == \"s\") {\n      if (historialAtras.size() > 0) {\n        if (copia == \"b\") {\n          historialSiquiente.push(paginaActual);\n          paginaActual = historialAtras.pop();\n        }\n      } else {\n        console.log(\"\\n previamente no hay paginas registradas\\n\");\n      }\n      if (historialSiquiente.size() > 0) {\n        if (copia == \"n\") {\n          historialAtras.push(paginaActual);\n          paginaActual = historialSiquiente.pop();\n        }\n      } else {\n        console.log(\"\\naun no hay paginas registradas\\n\");\n      }\n\n      if (copia == \"s\") {\n        console.log(\"\\nsaliendo del historial.......\\n\");\n        break;\n      }\n    } else {\n      historialAtras.push(paginaActual);\n      paginaActual = option;\n    }\n  }\n  rl.close();\n}\n\n// historialWeb();\n\nasync function impresora() {\n  const cola = new Queque();\n  let option;\n  let copia;\n  console.log(\"\\n\\timpresora compartida\\n\");\n  console.log(\n    \"bienvenido a la impresora compartida, estas son las siguientes opciones\"\n  );\n  const data = [\n    {\n      option: \"ingresar documento\",\n      accion: \"ingresar el nombre del documento\",\n    },\n    { option: \"imprimir\", accion: \"escribir i\" },\n    { option: \"salir\", accion: \"escribir s\" },\n  ];\n  console.table(data);\n  while (true) {\n    if (cola.size() > 0) {\n      console.log(\n        `\\ndocumentos en cola:${cola.size()}, documento: ${cola.front()}`\n      );\n      option = await preguntar(\"ingrese opcion: \");\n      copia = option.toLowerCase();\n      if (copia == \"i\" || copia == \"s\") {\n        if (copia == \"i\") {\n          console.log(`\\nimprimendo: ${cola.pop()}`);\n        }\n        if (copia == \"s\") {\n          console.log(\"\\nsaliendo de la impresora......\\n\");\n          break;\n        }\n      } else {\n        cola.add(option);\n      }\n    } else {\n      console.log(\"\\nno hay documentos en cola\\n\");\n      option = await preguntar(\"ingrese documento: \");\n      cola.add(option);\n    }\n  }\n  rl.close();\n}\n\nimpresora();\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/joapalobael.js",
    "content": "\n// Pila/Stack → LIFO \nlet listado = [1, 2, 3, 4, 5, 6];\n// LI (Last In)\nlistado.push(9);\nconsole.log(listado);\n// FO (First Out)\nlistado.pop();\nconsole.log(listado);\n\n// Cola/Queue → FIFO\n//FI (First In)\nlistado.push(7);\nconsole.log (listado);\n//FO (First Out)\nlistado.shift();\nconsole.log(listado);\n\n/* EJERCICIO:\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n\n/*1 - Pila + cadena de texto*/\n/*Simular adelante/atrás navegador web. */\n\nlet navegadorWeb = [\"Inicio\"];\nconsole.log(navegadorWeb.length)\n\nfunction atras() {\n    if(navegadorWeb.length <= 1){\n        console.log(\"Hasta aquí llegaste\");\n    } else {\n        navegadorWeb.pop()\n        console.log(navegadorWeb);\n    }\n}\n\nfunction adelante(site) {\n    navegadorWeb.push(site);\n    console.log(navegadorWeb);\n}\n\nadelante(\"Minijuegos\");\natras();\nadelante(\"Google Drive\");\nadelante(\"Elrellano.com\");\natras();\natras();\n\n/*2- Cola + Cadena de texto*/\n/*Simular una cola de impresión */\n\nlet colaDeImpresion = [\"Archivo 1\", \"Archivo 2\", \"Archivo 3\"];\n\nfunction imprimir(document) {\n    if (colaDeImpresion >= 0){\n        \"No hay elementos por imprimir\"\n    } else {\n        colaDeImpresion.push(document);\n        console.log(`Se está imprimiendo el documento: \"${colaDeImpresion[0]}\". Se elimina de la cola.`)\n        colaDeImpresion.shift();\n        console.log(colaDeImpresion);\n    }\n}\n\nimprimir(\"Archivo 4\");\nimprimir(\"If it bleeds\");"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/juandaherrera.js",
    "content": "// Pilas\nclass Stack {\n    constructor(stack = []) {\n    this.stack = stack;\n    }\n\n    push(value) {\n    this.stack.push(value);\n    }\n\n    pop() {\n    this.stack.pop();\n    }\n\n    toString() {\n    return this.stack.toString();\n    }\n}\n\nlet myStack = new Stack([1, 2, 3, 4, 5]);\nconsole.log(myStack.toString());\n\n// Inserción\nmyStack.push(6);\nconsole.log(myStack.toString());\n\n// Eliminación\nmyStack.pop();\nconsole.log(myStack.toString());\n\nconsole.log(\"---------------------------------\");\n\n// Colas\nclass Queue {\nconstructor(queue = []) {\n    this.queue = queue;\n}\n\nenqueue(value) {\n    this.queue.push(value);\n}\n\ndequeue() {\n    this.queue.shift();\n}\n\ntoString() {\n    return this.queue.toString();\n}\n}\n\nlet myQueue = new Queue([1, 2, 3, 4, 5]);\nconsole.log(myQueue.toString());\n\n// Inserción\nmyQueue.enqueue(6);\nconsole.log(myQueue.toString());\n\n// Eliminación\nmyQueue.dequeue();\nconsole.log(myQueue.toString());\n\n// Ambas\nmyQueue.enqueue(7);\nmyQueue.dequeue();\nmyQueue.dequeue();\nmyQueue.dequeue();\nmyQueue.enqueue(8);\nmyQueue.dequeue();\nmyQueue.enqueue(9);\nconsole.log(myQueue.toString());\n\nconsole.log(\"---------------------------------\");\n\nclass Web extends Stack {\nconstructor(stack = []) {\n    super(stack);\n    this.lastIndexSelection = 0;\n}\n\nforward() {\n    if (this.lastIndexSelection + 1 > this.stack.length - 1) {\n    this.lastIndexSelection = 0;\n    return this.stack[this.lastIndexSelection];\n    }\n    this.lastIndexSelection += 1;\n    return this.stack[this.lastIndexSelection];\n}\n\nback() {\n    if (this.lastIndexSelection - 1 < 0) {\n    this.lastIndexSelection = this.stack.length - 1;\n    return this.stack[this.lastIndexSelection];\n    }\n    this.lastIndexSelection -= 1;\n    return this.stack[this.lastIndexSelection];\n}\n}\n\n// Ejemplo de uso de la clase Web\nlet myWeb = new Web([\"Index\", \"About me\", \"Education\", \"Courses\"]);\nconsole.log(myWeb.toString());\n\nconsole.log(\"Web: 1\");\nconsole.log(\"Impresora: 2\");\n\nlet program = prompt(\"Qué programa quieres probar? \");\n\nif (program === \"1\") {\nconsole.log(\"------------ Web -------------\");\nconsole.log(\"Opciones:\");\nconsole.log(\"adelante -> siguiente página\");\nconsole.log(\"atras -> página anterior\");\nconsole.log(\"web -> todas las páginas\");\nconsole.log(\"exit -> salir\");\nconsole.log(\"cualquier string -> nueva página\")\n\nwhile (true) {\n    let option = prompt(\"Opción: \").toLowerCase();\n    switch (option) {\n    case \"adelante\":\n        console.log(\"Página actual: \", myWeb.forward());\n        break;\n    case \"atras\":\n        console.log(\"Página actual: \", myWeb.back());\n        break;\n    case \"web\":\n        console.log(myWeb.toString());\n        break;\n    case \"exit\":\n        break;\n    default:\n        myWeb.push(option);\n    }\n    if (option === \"exit\") break;\n}\n}\n\nconsole.log(\"---------------------------------\");\n\nif (program === \"2\") {\nlet documents = new Queue([\"Hoja de vida\", \"Trabajo literatura\", \"Carta presentación\"]);\n    \nconsole.log(\"------------ Impresora -------------\");\nconsole.log(\"Opciones:\");\nconsole.log(\"imprimir -> imprime el siguiente documento\");\nconsole.log(\"all -> todas las impresiones pendientes\");\nconsole.log(\"exit -> salir\");\nconsole.log(\"cualquier string -> nuevo documento\")\n\nwhile (true) {\n    let option = prompt(\"Opción: \").toLowerCase();\n    switch (option) {\n    case \"imprimir\":\n        if (documents.queue.length > 0) {\n        console.log(\"Imprimiendo: \", documents.queue[0]);\n        documents.dequeue();\n        } else {\n        console.log(\"No hay documentos para imprimir.\");\n        }\n        break;\n    case \"all\":\n        console.log(documents.toString());\n        break;\n    case \"exit\":\n        break;\n    default:\n        documents.enqueue(option);\n    }\n    if (option === \"exit\") break;\n}\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n_______________________________________\n#07 PILAS Y COLAS\n---------------------------------------\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo Forward/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar Forward o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"Forward\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n*/\n\n// ________________________________________________________\n// Pilas (Stack - LIFO):\n// - Estructura de datos que sigue el principio LIFO (Last In, First Out).\n// - El último elemento agregado es el primero en ser retirado.\n\nclass Stack {\n  constructor() {\n      this.elements = [];\n  }\n\n  // Total de elementos\n  get length() {\n      return this.elements.length;\n  }\n\n  // Verificar si la pila está vacía\n  isEmpty() {\n      return this.length === 0;\n  }\n\n  // Agregar un elemento\n  push(item) {\n      this.elements.push(item);\n  }\n\n  // Agregar múltiples elementos\n  pushBatch(items) {\n      this.elements.push(...items);\n  }\n\n  // Eliminar y obtener el elemento superior\n  pop() {\n      return this.isEmpty() ? null : this.elements.pop();\n  }\n\n  // Obtener el elemento superior sin eliminarlo\n  peek() {\n      return this.isEmpty() ? null : this.elements[this.elements.length - 1];\n  }\n\n  // Obtener la pila como tupla\n  toArray() {\n      return [...this.elements].reverse();\n  }\n\n  // Vaciar la pila\n  clear() {\n      this.elements = [];\n  }\n}\n\n// ________________________________________________________\n// Ejercicio: Historial de navegación\n\nconst MsgNav = `\n  Historial de navegación:\n  -------------------------------------------------\n  Usar: \"<\" para página anterior.\n        \">\" para página Forward.\n        \"h\" Ver historial completo.\n        \"x\" para salir.\n  Escribir web para agregar:\n  -------------------------------------------------`;\n\nfunction NavHistory() {\n  const BackHistory = new Stack();\n  const forwardHistory = new Stack();\n  const history = new Stack();\n  history.push(\"Inicio\");\n\n  const ShowHistory = () => {\n      console.log(MsgNav);\n      ShowStatus(history.peek());\n      SelectAction();\n  };\n\n  const ShowStatus = (url) => {\n      console.log(`(${BackHistory.length}) <- Atrás <- [Actual: ${url}] -> Forward -> (${forwardHistory.length})`);\n  };\n\n  const Back = () => {\n      if (!BackHistory.isEmpty()) {\n          forwardHistory.push(history.pop());\n          history.push(BackHistory.pop());\n          ShowStatus(history.peek());\n      } else {\n          console.log(\"No hay página previa.\");\n      }\n      SelectAction();\n  };\n\n  const Forward = () => {\n      if (!forwardHistory.isEmpty()) {\n          BackHistory.push(history.pop());\n          history.push(forwardHistory.pop());\n          ShowStatus(history.peek());\n      } else {\n          console.log(\"No hay página siguiente.\");\n      }\n      SelectAction();\n  };\n\n  const NewWeb = (url) => {\n      BackHistory.push(history.peek());\n      forwardHistory.clear();\n      history.push(url);\n      ShowStatus(history.peek());\n      SelectAction();\n  };\n\n  const PrintHistory = () => {\n      const historial = history.toArray();\n      console.log(historial.length ? historial.join(\" -> \") : \"Historial vacío.\");\n      SelectAction();\n  };\n\n  const SelectAction = () => {\n      console.log(\"____________\");\n      rl.question(\"Acción: \", (option) => {\n          switch (option) {\n              case \"<\":\n                  Back();\n                  break;\n              case \">\":\n                  Forward();\n                  break;\n              case \"h\":\n                  PrintHistory();\n                  break;\n              case \"x\":\n                  rl.close;\n                  main();\n                  return;\n              default:\n                  NewWeb(option);\n          }\n      });\n  };\n\n  ShowHistory();\n}\n\n// ________________________________________________________\n// Colas (Queue - FIFO):\n// - Estructura de datos que sigue el principio FIFO (First In, First Out).\n// - El primer elemento agregado es el primero en ser retirado.\nclass Queue {\n  constructor() {\n      this.elements = [];\n  }\n\n  // Total de elementos\n  get length() {\n      return this.elements.length;\n  }\n\n  // Verificar si la cola está vacía\n  isEmpty() {\n      return this.length === 0;\n  }\n\n  // Agregar un elemento\n  enqueue(item) {\n      this.elements.push(item);\n  }\n\n  // Agregar múltiples elementos\n  enqueueAll(items) {\n      this.elements.push(...items);\n  }\n\n  // Eliminar y devolver el primer elemento\n  dequeue() {\n      return this.isEmpty() ? null : this.elements.shift();\n  }\n\n  // Obtener el primer elemento sin eliminarlo\n  peek() {\n      return this.isEmpty() ? null : this.elements[0];\n  }\n\n  // Obtener la cola como tupla\n  toArray() {\n      return [...this.elements];\n  }\n\n  // Vaciar la cola\n  clear() {\n      this.elements = [];\n  }\n}\n\n// ________________________________________________________\n// Ejercicio: Simulador de impresora\n\nconst mensajeImpresora = `\n  ------------------------------------------------\n  Usar: \"p\" Imprimir.\n        \"l\" Ver documentos pendientes.\n        \"x\" para salir.\n  Escribir nombre de documento para enviar a cola:\n  ------------------------------------------------`;\n\nfunction QueuePrinter() {\n  const docQueue = new Queue();\n  docQueue.enqueueAll([\"a.pdf\", \"b.txt\", \"c.docx\"]);\n\n  const PrintDoc = () => {\n      if (!docQueue.isEmpty()) {\n          console.log(`${docQueue.dequeue()} -> ha sido impreso.`);\n          console.log(`${docQueue.length} -> archivos faltantes.`);\n      } else {\n          console.log(\"No hay archivos.\");\n      }\n      SelectAction();\n  };\n\n  const DocPending = () => {\n      const documentos = docQueue.toArray();\n      console.log(documentos.length ? documentos.join(\", \") : \"No hay archivos.\");\n      SelectAction();\n  };\n\n  const AddDoc = (doc) => {\n      docQueue.enqueue(doc);\n      console.log(\"Archivo agregado a la cola de impresión.\");\n      SelectAction();\n  };\n\n  const SelectAction = () => {\n      console.log(\"____________\");\n      rl.question(\"Acción: \", (option) => {\n          switch (option) {\n              case \"p\":\n                  PrintDoc();\n                  break;\n              case \"l\":\n                  DocPending();\n                  break;\n              case \"x\":\n                  rl.close;\n                  main();\n                  return\n              default:\n                  AddDoc(option);\n          }\n      });\n  };\n\n  console.log(mensajeImpresora);\n  SelectAction();\n}\n\n// ________________________________________________________\nconst readline = require('readline');\n\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout\n});\n\nconst MenuHome = `\n  ----------------------------------\n  Usar: \"1\" para simulador de navegador.\n        \"2\" para simulador de impresora.\n        \"Otra tecla\" para salir.\n  ----------------------------------`;\n\nfunction main() {\n  console.log(MenuHome);\n  rl.question(\"Seleccionar: \", (option) => {\n      switch (option) {\n          case \"1\":\n              NavHistory();\n              break;\n          case \"2\":\n              QueuePrinter();\n              break;\n          default:\n              console.log(\"Adiós\");\n              rl.close();\n              process.exit();\n      }\n  });\n}\n\nmain();\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/kodenook.js",
    "content": "\n/*\n    Stack\n*/\n\nlet letters = ['a', 'b', 'c', 'd']\n\n/*\n    Insert\n*/\n\nletters.unshift('e')\nletters.unshift('f')\n\nconsole.log(letters)\n\n/*\n    Delete\n*/\n\nletters.shift()\n\nconsole.log(letters)\n\n/*\n    Queue\n*/\n\nletters = ['a', 'b', 'c', 'd']\n\n/*\n    Insert\n*/\n\nletters.push('e')\nletters.push('f')\n\nconsole.log(letters)\n\n/*\n    Delete\n*/\n\nletters.shift()\n\nconsole.log(letters)"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/marcode24.js",
    "content": "/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n\nclass Stack {\n  constructor() {\n    this.items = [];\n  }\n\n  push(element) {\n    this.items.push(element);\n  }\n\n  pop() {\n    if (this.isEmpyt()) {\n      return 'La pila esta vacia';\n    }\n    return this.items.pop();\n  }\n\n  isEmpyt() {\n    return this.items.length === 0;\n  }\n\n  peek() {\n    return this.items[this.items.length - 1];\n  }\n\n  clear() {\n    this.items = [];\n  }\n\n  size() {\n    return this.items.length;\n  }\n}\n\nclass Queue {\n  constructor() {\n    this.items = [];\n  }\n\n  enqueue(element) {\n    this.items.push(element);\n  }\n\n  dequeue() {\n    if (this.isEmpyt()) {\n      return 'La cola esta vacia';\n    }\n    return this.items.shift();\n  }\n\n  isEmpyt() {\n    return this.items.length === 0;\n  }\n\n  size() {\n    return this.items.length;\n  }\n}\n\nconst pila = new Stack();\npila.push(1);\npila.push(2);\npila.push(3);\nconsole.log(pila.pop()); // 3\nconsole.log(pila.pop()); // 2\n\nconst cola = new Queue();\ncola.enqueue('a');\ncola.enqueue('b');\ncola.enqueue('c');\nconsole.log(cola.dequeue()); // a\nconsole.log(cola.dequeue()); // b\n\nclass Navegador {\n  constructor() {\n    this.history = new Stack();\n    this.future = new Stack();\n    this.currentPage = null;\n  }\n\n  // navegar a una nueva pagina\n  goToPage(page) {\n    if (this.currentPage !== null) {\n      this.history.push(this.currentPage);\n    }\n    this.currentPage = page;\n    this.future.clear();\n    console.log('Pagina actual: ', this.currentPage);\n  }\n\n  // retroceder a la pagina anterior\n  goBack() {\n    if (this.history.isEmpyt()) {\n      console.log('No hay paginas anteriores');\n      return;\n    }\n    this.future.push(this.currentPage);\n    this.currentPage = this.history.pop();\n    console.log('Pagina actual: ', this.currentPage);\n  }\n\n  // avanzar a la pagina siguiente\n  goForward() {\n    if (this.future.isEmpyt()) {\n      console.log('No hay paginas siguientes');\n      return;\n    }\n    this.history.push(this.currentPage);\n    this.currentPage = this.future.pop();\n    console.log('Pagina actual: ', this.currentPage);\n  }\n}\n\nconst navegador = new Navegador();\nnavegador.goToPage('google.com');\nnavegador.goToPage('facebook.com');\nnavegador.goToPage('twitter.com');\nnavegador.goBack(); // regresa a facebook.com\nnavegador.goBack(); // regresa a google.com\nnavegador.goForward(); // avanza a facebook.com\nnavegador.goToPage('instagram.com'); // instagram.com\nnavegador.goBack(); // regresa a facebook.com\nnavegador.goForward(); // avanza a instagram.com\n\n// Visita mi repo en GitHub para ver y correr los tests de este código --> https://github.com/marcode24/weekly-challenges\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/miguelex.js",
    "content": "class Cola {\n    constructor() {\n        this.cola = [];\n        this.inicio = 0;\n        this.fin = 0;\n        this.max = 10; // Opcional para limitar el tamaño de la cola\n    }\n\n    encolar(elemento) {\n        if (this.fin < this.max) {\n            this.cola[this.fin] = elemento;\n            this.fin++;\n        } else {\n            console.log(\"La cola está llena\");\n        }\n    }\n\n    desencolar() {\n        if (this.inicio < this.fin) {\n            const elemento = this.cola[this.inicio];\n            delete this.cola[this.inicio];\n            this.inicio++;\n            return elemento;\n        } else {\n            console.log(\"La cola está vacía\");\n        }\n    }\n\n    mostrar() {\n        if (this.inicio === this.fin) {\n            console.log(\"La cola está vacía\");\n        } else {\n            for (let i = this.inicio; i < this.fin; i++) {\n                console.log(this.cola[i] + \" \");\n            }\n        }\n    }\n}\n\nclass Pila {\n    constructor() {\n        this.pila = [];\n        this.tope = 0;\n        this.max = 7; // Opcional para limitar el tamaño de la pila\n    }\n\n    apilar(elemento) {\n        if (this.tope < this.max) {\n            this.pila[this.tope] = elemento;\n            this.tope++;\n        } else {\n            console.log(\"La pila está llena\");\n        }\n    }\n\n    desapilar() {\n        if (this.tope > 0) {\n            this.tope--;\n            const elemento = this.pila[this.tope];\n            delete this.pila[this.tope];\n            return elemento;\n        } else {\n            console.log(\"La pila está vacía\");\n        }\n    }\n\n    mostrar() {\n        if (this.tope === 0) {\n            console.log(\"La pila está vacía\");\n        } else {\n            for (let i = this.tope - 1; i >= 0; i--) {\n                console.log(this.pila[i] + \" \");\n            }\n        }\n    }\n}\n\nconst cola = new Cola();\nconst pila = new Pila();\n\nconsole.log(\"Vamos a trabajar con la cola\");\nconsole.log(\"Vamos a mostrar el contenido de la cola al inicio de la misma: \");\ncola.mostrar();\n\nconsole.log(\"\\nVamos a encolar 3 elementos: 1, 2 y 3\");\ncola.encolar(1);\ncola.encolar(2);\ncola.encolar(3);\n\nconsole.log(\"Vamos a mostrar el contenido de la cola después de encolar 3 elementos: \");\ncola.mostrar();\n\nconsole.log(\"\\nVamos a desencolar un elemento\");\ncola.desencolar();\n\nconsole.log(\"Vamos a mostrar el contenido de la cola después de desencolar un elemento: \");\ncola.mostrar();\n\nconsole.log(\"\\nVamos a encolar 2 elementos: 4 y 5 y vamos a desencolar dos\");\ncola.encolar(4);\ncola.encolar(5);\ncola.desencolar();\ncola.desencolar();\n\nconsole.log(\"Vamos a mostrar el contenido de la cola después de encolar 2 elementos y desencolar dos: \");\ncola.mostrar();\n\nconsole.log(\"\\nPor último, vamos a desencolar tres elementos (recuerda que realmente solo nos quedan 2 dentro de la cola)\");\ncola.desencolar();\ncola.desencolar();\ncola.desencolar();\n\nconsole.log(\"Vamos a mostrar el contenido de la cola después de desencolar tres elementos: \");\ncola.mostrar();\n\nconsole.log(\"\\nAhora, vamos a trabajar con la pila\");\n\nconsole.log(\"Vamos a mostrar el contenido de la pila al inicio de la misma: \");\npila.mostrar();\n\nconsole.log(\"\\nVamos a apilar 3 elementos: 1, 2 y 3\");\n\npila.apilar(1);\npila.apilar(2);\npila.apilar(3);\n\nconsole.log(\"Vamos a mostrar el contenido de la pila después de apilar 3 elementos: \");\npila.mostrar();\n\nconsole.log(\"\\nVamos a desapilar un elemento\");\npila.desapilar();\n\nconsole.log(\"Vamos a mostrar el contenido de la pila después de desapilar un elemento: \");\npila.mostrar();\n\nconsole.log(\"\\nVamos a apilar 2 elementos: 4 y 5 y vamos a desapilar dos\");\n\npila.apilar(4);\npila.apilar(5);\n\npila.desapilar();\npila.desapilar();\n\nconsole.log(\"Vamos a mostrar el contenido de la pila después de apilar 2 elementos y desapilar dos: \");\npila.mostrar();\n\nconsole.log(\"\\nPor último, vamos a desapilar tres elementos (recuerda que realmente solo nos quedan 2 dentro de la pila)\");\npila.desapilar();\npila.desapilar();\npila.desapilar();\n\nconsole.log(\"Vamos a mostrar el contenido de la pila después de desapilar tres elementos: \");\npila.mostrar();\n\nconsole.log(\"\\nVamos a simular el mecanismo adelante/atrás de un navegador web\");\n\nconst pilaNavegador = new Pila();\nlet ultimoIndexVisitado = -1;\n\nconst readline = require('readline').createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nfunction navegacion() {\n    const cabeza = pilaNavegador.tope - 1;\n\n    readline.question(\"Escribe el nombre de la web, adelante, atras o salir: \", (entrada) => {\n        if (entrada === \"adelante\") {\n            if (ultimoIndexVisitado < cabeza) {\n                ultimoIndexVisitado++;\n                console.log(\"Navegando adelante a la web: \" + pilaNavegador.pila[ultimoIndexVisitado]);\n            } else {\n                console.log(\"No hay más webs para navegar adelante\");\n            }\n        } else if (entrada === \"atras\") {\n            if (ultimoIndexVisitado > 0) {\n                ultimoIndexVisitado--;\n                console.log(\"Navegando atrás a la web: \" + pilaNavegador.pila[ultimoIndexVisitado]);\n            } else {\n                console.log(\"No hay más webs para navegar atrás\");\n            }\n        } else if (entrada !== \"salir\") {\n            pilaNavegador.apilar(entrada);\n            ultimoIndexVisitado = pilaNavegador.tope - 1;\n            console.log(\"Estás en la web: \" + entrada);\n        }\n\n        if (entrada !== \"salir\") {\n            navegacion();\n        } else {\n            readline.close();\n        }\n    });\n}\n\nnavegacion();\n\nconsole.log(\"\\nVamos a simular el mecanismo de una cola de impresión\");\n\nconst colaImpresion = new Cola();\n\nfunction impresion() {\n    readline.question(\"Escribe el nombre del documento, imprimir o exit: \", (entrada) => {\n        if (entrada === \"imprimir\") {\n            const documento = colaImpresion.desencolar();\n            if (documento !== undefined) {\n                console.log(\"Imprimiendo documento: \" + documento);\n            } else {\n                console.log(\"No hay documentos para imprimir\");\n            }\n        } else if (entrada !== \"exit\") {\n            colaImpresion.encolar(entrada);\n            console.log(\"Documento encolado: \" + entrada);\n        }\n\n        if (entrada !== \"exit\") {\n            impresion();\n        } else {\n            readline.close();\n        }\n    });\n}\n\nimpresion();\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/natalyjoanna.js",
    "content": "\n// Stacks (Pilas)\nclass Stack {\n  constructor() {\n    this.stack = []\n  }\n\n  push(element) {\n    this.stack.push(element)\n  }\n\n  pop() {\n    if (this.isEmpty()) return \"La pila esta vacia\";\n    return this.stack.pop()\n  }\n\n  // Devuelve el ultimo elemento de la pila sin eliminarlo\n  peek() {\n    return this.stack[this.stack.length - 1]\n  }\n\n  isEmpty() {\n    return this.stack.length === 0;\n  }\n\n  // Devuelve el tamaño del stack\n  size() {\n    return this.stack.length;\n}\n\n// Devuelve una representación en cadena del stack\nprint() {\n  return this.stack.toString();\n}\n\n}\n\nconst stack = new Stack();\n\nstack.push(\"Javascript\"); \nstack.push(\"Python\");\nstack.push(\"C#\");\n\nconsole.log(stack.print());\nconsole.log(stack.pop()) // Elimina el ultimo elemento de la lista\nconsole.log(stack.peek()); // Ultimo elemento de la lista\nconsole.log(stack.size());\nconsole.log(stack.isEmpty());\nconsole.log(stack.print());\n\n// Queue (Colas)\n\nclass Queue {\n  constructor() {\n    this.queue = []\n  }\n\n  // Agregar un elemento a la cola\n  enqueue(element) {\n    this.queue.push(element)\n  }\n\n  // Eliminar elemento de la cola\n dequeue() {\n  if (this.isEmpty()) return \"La cola esta vacia\";\n  return this.queue.shift()\n }\n\n // Devuelve el primer elemento de la cola sin eliminarlo\n front() {\n  if (this.isEmpty()) return \"La cola esta vacia\";\n  return this.queue[0];\n }\n\n // Verificar si la cola esta vacia\n isEmpty() {\n  return this.queue.length === 0;\n }\n\n // Devuelve el tamaño de la cola\n size() {\n  return this.items.length;\n}\n\n// Devuelve la cola\n print() {\n  return this.queue.toString();\n }\n\n }\n\nconst queue = new Queue();\nqueue.enqueue(1)\nqueue.enqueue(2)\nqueue.enqueue(3)\n\nconsole.log(queue.print()) // Imprime la cola\nconsole.log(queue.dequeue()) // Eliminar el primer elemento de la cola\nconsole.log(queue.front()) // Muestra el primer elemento de la cola sin eliminarlo\nconsole.log(queue.isEmpty()) // Revisa si la cola esta vacia\nconsole.log(queue.print()) // Imprime la cola con los ultimos cambios\n\n// DIFICULTAD EXTRA\n\nlet webs = []\n\nconst readLine = require('readline');\nconst { PassThrough } = require('stream');\nconst rl = readLine.createInterface({\n  input: process.stdin,\n  output: process.stdout\n});\n\nfunction menu() {\n  rl.question('\\nAgrega una url o navega utilizando adelante/atras o \"salir\" para terminar el programa ', (accion) => {\n    if(accion){\n      navegacion(accion);\n    } else {\n      console.log('Debes introducir algo')\n      menu();\n    }\n  })\n}\n\n\n\nlet navegacion = accion => {\n \n  if(accion.toLowerCase() === \"adelante\") {\n    console.log('No existen urls adelante de la que estas')\n    menu()\n  } else if (accion.toLowerCase() === \"atras\") {\n    if(webs.length === 0) {\n      console.log('No existen urls actualmente puedes empezar agregando una tu')\n      menu()\n    } else {\n      webs.pop()\n    }\n  } else if(accion.toLowerCase() === \"salir\") {\n    console.log('Saliendo...')\n    rl.close()\n    return;\n  } else {\n    webs.push(accion)\n    console.log(webs)\n  }\n  console.log(`Haz navegado a ${webs[webs.length - 1]}`)\n  menu()\n}\n\n//menu()\n\n// Impresora\n\nlet cola = []\n\nfunction menuImpresora() {\n  rl.question('Agrega un documento o selecciona imprimir/salir: ', (accion) =>{\n    if(accion) {\n      impresora(accion)\n    } else {\n      console.log('Debes introducir algo')\n    }\n  })\n}\n\nlet impresora = accion => {\n\n  if(accion.toLowerCase() === 'imprimir') {\n    if(cola.length === 0) {\n      console.log('No hay elementos para imprimir')\n    } else {\n      console.log('Imprimiendo: ', cola.shift())\n    }\n  } else if(accion.toLowerCase() === 'salir') {\n    console.log('Saliendo...')\n    rl.close()\n    return;\n  } else {\n    cola.push(accion);\n  }\n  console.log('Cola de impresion: ', cola)\n  menuImpresora()\n}\n  \nmenuImpresora()\n "
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/nlarrea.js",
    "content": "/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n\n\n// Stack - LIFO\n\nconst stack = [];\n\n// Add item\nstack.push(1);\nstack.push(2);\nstack.push(3);\nstack.push(4);\nconsole.log(stack);  // [1, 2, 3, 4]\n\n// Remove item\nstack.length = stack.length - 1;\nconsole.log(stack);  // [1, 2, 3]\n\nstack.pop();\nconsole.log(stack); // [1, 2]\n\n\n// Queue - FIFO\n\nlet queue = [];\n\n// Add item\nqueue.push(1);\nqueue.push(2);\nqueue.push(3);\nqueue.push(4);\nconsole.log(queue);  // [1, 2, 3, 4]\n\n// Remove item\nqueue.splice(0, 1);\nconsole.log(queue);  // [2, 3, 4]\n\nqueue = queue.slice(1);  // queue can't be a constant to use this\nconsole.log(queue);  // [3, 4]\n\nqueue.shift();\nconsole.log(queue);  // [4]\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n */\n\n\nconst readline = require('readline');\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\n\nconst history = [];\nlet pointer = -1;\n\nfunction webNavigation() {\n    const showMenu = () => {\n        console.log('\\nType one of the following:');\n        console.log(' - The web page you want to visit');\n        console.log(' - Back (to go to the previous page)');\n        console.log(' - Next (to go to the next page)');\n        console.log(' - Exit');\n    };\n\n    showMenu();\n    \n    rl.question('Where do you want to go?\\n> ', (action) => {\n        if (action && action.trim().toLowerCase() === 'exit') {\n            rl.close();\n            return;\n        } else if (action && action.trim().toLowerCase() === 'next') {\n            if (pointer !== history.length - 1) {\n                pointer++;\n            }\n            console.log(`\\nYou are in: ${history[pointer]}`);\n        } else if (action && action.trim().toLowerCase() === 'back') {\n            pointer--;\n            if (pointer < 0) {\n                pointer = -1;\n                console.log('\\nYou are in home page');\n            } else {\n                console.log(`\\nYou are in: ${history[pointer]}`);\n            }\n        } else if (action) {\n            history.push(action);\n            pointer = history.length - 1;\n            console.log(`\\nYou are in: ${history[pointer]}`);\n        }\n\n        webNavigation();\n    });\n}\n\nwebNavigation();\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n\n\nconst printerQueue = [];\n\nfunction printer() {\n    const showMenu = () => {\n        console.log('\\nPrinter options:');\n        console.log(' - Type a document name to add it to the queue');\n        console.log(' - Type \"print\" to print the first item');\n        console.log(' - Exit');\n    };\n\n    const showQueue = () => {\n        console.log('\\nPrinter Queue:');\n\n        if (printerQueue.length > 0) {\n            for (let doc of printerQueue) {\n                console.log(` - ${doc}`);\n            }\n        } else {\n            console.log('The Queue is empty.');\n        }\n    };\n\n    showMenu();\n    rl.question('Type a document name or \"print\" to print the first item:\\n> ', (action) => {\n        if (action && action.trim().toLowerCase() === 'exit') {\n            rl.close();\n            return;\n        } else if (action && action.trim().toLowerCase() === 'print') {\n            if (printerQueue.length > 0) {\n                let printingDoc = printerQueue.shift();\n                console.log(`Printing: ${printingDoc}`);\n            } else {\n                console.log('There are no documents to print.');\n            }\n        } else if (action) {\n            printerQueue.push(action);\n        }\n\n        showQueue();\n        printer();\n    });\n}\n\nprinter();"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/ocram1304.js",
    "content": "// Pila\nclass Pila {\n    constructor() {\n      this.stack = []\n      this.top = 0\n    }\n  \n    // Añade un elemento al final de la pila\n    push(newValue) {\n      this.stack.push(newValue)\n      this.top += 1\n    }\n  \n    // Regresa y remiueve el último elemento de la  pila\n    pop() {\n      if (this.top !== 0) {\n        this.top -= 1\n        return this.stack.pop()\n      }\n      throw new Error('Stack Underflow')\n    }\n  \n    // Regresa el número de elementos de la pila\n    get length() {\n      return this.top\n    }\n  \n    // Regresa si la pila estta vacia\n    get isEmpty() {\n      return this.top === 0\n    }\n  \n    // Regresa  el último elemento sin removerlo \"peak\"\n    get last() {\n      if (this.top !== 0) {\n        return this.stack[this.stack.length - 1]\n      }\n      return null\n    }\n  \n    // Checa si un objeto es instancia de la clase pila\n    static isStack(el) {\n      return el instanceof Stack\n    }\n  }\n  //Cola\n  class Cola{\n    //Constructor de la cola\n    constructor(){\n      this.queue  = [];\n\n    }\n    //Añadir un nuevo valor a la cola (encolar)\n    push( value){\n        this.queue .push(value);\n    }\n    //Eliminar el primer elemento de la cola (des-encolar)\n    pop(){\n      if(this.queue.length !==  0){\n        return this.queue.shift();\n      }\n     throw new  Error(\"Cola vacia\");\n    }\n    //Obtener el frente de la cola\n    get FrenteCola(){\n      if(this.queue.length !==  0){\n        return this.queue[0];\n      }\n      throw new  Error(\"Cola vacia\");\n    }\n    //Obtener el final de la cola\n   get FinalCola(){\n    if(this.queue.length !==  0){\n      return this.queue[this.queue.length-1];\n    }\n    throw new  Error(\"Cola vacia\");\n    }\n    //Verificar si la cola está vacia\n    isEmpty(){\n      return this.queue.length === 0;\n    }\n\n  }\n\n  //Dificultad extra\n  //Pagina atras/adelante\n  class Pagina {\n    constructor(actual) {\n      this.anterior = new Pila();\n      this.actual = actual; \n      this.siguiente = new Pila(); \n    }\n  \n    get paginaActual() { \n      return this.actual;\n    }\n  \n    avanzarSiguiente() { \n      if (!this.siguiente.isEmpty()) { \n        this.anterior.push(this.actual);\n        this.actual = this.siguiente.pop();\n      }\n      return this.actual;\n    }\n  \n    avanzarAnterior() { \n      if (!this.anterior.isEmpty()) {\n        this.siguiente.push(this.actual);\n        this.actual = this.anterior.pop();\n      }\n      return this.actual;\n    }\n  }\n\n  class Impresora {\n    constructor(documento) {\n      this.documento = documento;\n      this.flujo = new Cola();\n      this.documentoImpreso;\n    }\n  \n    encolarDocumento() {\n      if(this.documento.trim() !== \"\"){\n        this.flujo.push(this.documento.slice(0, 1)); \n      }\n      else{\n        throw new Error(\"No hay documentos para imprimir\");\n      }\n      \n    }\n  \n    imprimirDocumento() {\n      if (!this.flujo.isEmpty()) {\n        this.documentoImpreso = this.flujo.pop(); // Asigna el documento impreso a la propiedad\n        return this.documentoImpreso;\n      }\n      throw new Error(\"No hay documentos para imprimir\"); // Lanza un error si no hay documentos\n    }\n  }\n  \n\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/oleojake.js",
    "content": "/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n */\n\n\n// PILA (Last In First Out)\n\nclass Pila {\n    constructor(){\n        this.elements = []\n    }\n\n    insert (element) {\n        this.elements.push(element);\n    }\n\n    delete () {\n        this.elements.pop();\n    }\n\n    peek () {\n        return this.elements[this.elements.length-1];\n    }\n\n    size () {\n        return this.elements.length;\n    }\n\n    print () {\n        return this.elements;\n    }\n}\n\nconst pila1 = new Pila();\n\npila1.insert('Naranja');\npila1.insert('Manzana');\npila1.insert('Pera');\nconsole.log(pila1.print()); // ['Naranja', 'Manzana', 'Pera']\nconsole.log(pila1.peek()); // Pera\nconsole.log(pila1.size()); // 3\npila1.delete();\nconsole.log(pila1.print()); // ['Naranja', 'Manzana']\n\n\n// COLA First In First Out\n\nclass Cola {\n    constructor(){\n        this.elements = []\n    }\n\n    insert (element) {\n        this.elements.push(element);\n    }\n\n    delete () {\n        this.elements.shift();\n    }\n\n    peek () {\n        return this.elements[0];\n    }\n\n    size () {\n        return this.elements.length;\n    }\n\n    print () {\n        return this.elements;\n    }\n}\n\nconst cola1 = new Cola();\n\ncola1.insert('Naranja');\ncola1.insert('Manzana');\ncola1.insert('Pera');\nconsole.log(cola1.print()); // ['Naranja', 'Manzana', 'Pera']\nconsole.log(cola1.peek()); // Naranja\nconsole.log(cola1.size()); // 3\ncola1.delete();\nconsole.log(cola1.print()); // ['Manzana', 'Pera']\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n */\n\n\nclass Browser{\n    constructor(){\n        this.pila = new Pila();\n        this.index = -1\n    }\n\n    order (element) {\n        if (element == 'adelante'){\n            if (this.index == this.pila.size()-1){\n                return \"No puedes avanzar más, estás en la última página\"\n            }\n            else{\n                this.index ++; \n                return \"Avanzas hasta la página \" + this.pila.elements[this.index];\n            }\n        }\n        else if (element == 'atrás'){\n            if (this.index == 0){\n                return \"No puedes retroceder más, no hay más historial\"\n            }\n            else{\n                this.index --;\n                return \"Retrocedes hasta la página \" + this.pila.elements[this.index];\n            }\n        }\n        else{\n            this.pila.insert(element);\n            this.index = this.pila.size()-1;\n            return \"Navegas hasta la nueva página \" + element + \" | index:\" + this.index;\n        }\n    }\n}\n\nconst navegador1 = new Browser();\n\nconsole.log(navegador1.order('facebook.com'));\nconsole.log(navegador1.order('google.com'));\nconsole.log(navegador1.order('instagram.com'));\nconsole.log(navegador1.order('atrás'));\nconsole.log(navegador1.order('atrás'));\nconsole.log(navegador1.order('adelante'));\nconsole.log(navegador1.order('adelante'));\nconsole.log(navegador1.order('adelante'));\nconsole.log(navegador1.order('adelante'));\nconsole.log(navegador1.order('atrás'));\nconsole.log(navegador1.order('atrás'));\nconsole.log(navegador1.order('youtube.com'));\nconsole.log(navegador1.order('adelante'));\nconsole.log(navegador1.order('atrás'));\nconsole.log(navegador1.order('atrás'));\nconsole.log(navegador1.order('atrás'));\nconsole.log(navegador1.order('atrás'));\nconsole.log(navegador1.order('atrás'));\nconsole.log(navegador1.order('twitter.com'));\n\n\n\n/* - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n\nclass Impresora{\n    constructor(){\n        this.cola = new Cola();\n    }\n\n    order (element) {\n        if (element!='imprimir'){\n            this.cola.insert(element);\n            return \"El documento \" + element + \" se ha puesto a la cola\";\n        }\n        else{\n            let msg = \"Se ha impreso el documento \" + this.cola.peek();\n            this.cola.delete(element);\n            return msg\n        }\n    }\n}\n\nconst impresora1 = new Impresora();\nconsole.log(impresora1.order('Factura'));\nconsole.log(impresora1.order('Email'));\nconsole.log(impresora1.order('Documento 1'));\nconsole.log(impresora1.order('imprimir'));\nconsole.log(impresora1.order('Documento 2'));\nconsole.log(impresora1.order('imprimir'));"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/othamae.js",
    "content": "/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atras\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n\n\n\n// Stacks\n\nconst stack = []\nstack.push('Hello')\nstack.push('World')\nstack.push('from')\nstack.push('JavaScript')\n\nconsole.log('This is the stack:')\nconsole.log(stack)\nconst lastElement = stack.pop()\nconsole.log('LIFO - Last element is the first out: ',lastElement)\nconsole.log('This is the stack after popping:')\nconsole.log(stack)\n\n// Queue\n\nconst queue = []\nqueue.push('Hello')\nqueue.push('World')\nqueue.push('from')\nqueue.push('JavaScript')\n\nconsole.log('This is the queue:')\nconsole.log(queue)\nconst firstElement = queue.shift() \nconsole.log('FIFO - First element is the first in: ', firstElement)\nconsole.log('This is the queue after shifting:')\nconsole.log(queue)\n\n\n// EXTRA TASK:\n\n// Web Browser:\n\nconst history=[]\nlet pointer=-1\nlet actualPage=''\n\nfunction visit(url){\n    history.push(url)\n    pointer++\n}\n\nfunction back(){\n    pointer--\n    console.log(history[pointer])\n}\nfunction next(){\n    pointer++\n    console.log(history[pointer])\n}\n\nvisit('moure.dev')\nvisit('othamae.dev')\nvisit('retosdeprogramacion.com')\nvisit('github.com')\n\nconsole.log('This is the history:')\nconsole.log(history)\nconsole.log(`We are now in page: ${history[pointer]}`)\nconsole.log(`We go back: `)\nback()\nconsole.log(`We go back again: `)\nback()\nconsole.log(`Now we go forward: `)\nnext()\n\n\n// Printer:\n\nconst printerQueue = []\n\nfunction sentToPrinter(document){\n    printerQueue.push(document)\n    console.log(`Document \"${document}\" sent to printer`)\n}\n\nfunction printDocuments(){\n    while(printerQueue.length>0){\n        const currentDocument = printerQueue.shift()\n        console.log(`Printing \"${currentDocument}\"`)\n    }\n    console.log('No documents to print')\n}\n\nsentToPrinter('Document 1')\nsentToPrinter('Document 2')\nsentToPrinter('Document 3')\nsentToPrinter('Document 4')\n\nconsole.log('Pressing IMPRIMIR button:')\nprintDocuments()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/parababire.js",
    "content": "//Stack\n\nlet stackArr = [];\n\n/*push*/\nstackArr.push(\"Luis\");\nstackArr.push(\"María\");\nstackArr.push(\"Luisa\");\nconsole.log(stackArr);\n\n/*pop*/\nconsole.log(stackArr.pop());\nconsole.log(stackArr);\n\n//Queue\n\nlet queueArr = [];\n\n/*enqueue*/\n\nqueueArr.push(\"Corolla\");\nqueueArr.push(\"Ford\");\nqueueArr.push(\"Chevrolet\");\nconsole.log(queueArr);\n\n/*dequeue*/\n\nconsole.log(queueArr.shift());\nconsole.log(queueArr);\n\n//Extra\n\n/*Navegador*/\n\nfunction navegadorWeb() {\n\n  let url;\n  let on = true;\n  let stack = [];\n\n  while (on) {\n\n    console.log(\"\");\n    console.log(\"1.- Ingresar URL\");\n    console.log(\"2.- Adelantar Web\");\n    console.log(\"3.- Atras Web\");\n    console.log(\"4.- Salir\");\n\n    let comand = prompt(\"\\nSelecciona una operación: \", \"\");\n\n    switch (comand) {\n      case \"1\":\n        url = prompt(\"Ingresa la URL deseada: \", \"\");\n        stack.push(url);\n        console.log(`Has ingresado a: ${stack[stack.length - 1]}`);\n        break;\n      case \"2\":\n        if (stack.length !== 0) {\n          console.log(`Te encuentras actualmente en la página: ${stack[stack.length - 1]}`);\n        } else {\n          console.log(\"Estas en la página de inicio\");\n        }\n        break;\n      case \"3\":\n        if (stack.length !== 0) {\n          stack.pop();\n          if (stack.length > 0) {\n            console.log(`Has retornado a la página ${stack[stack.length - 1]}`);\n          } else {\n            console.log(\"El registro ahora está vacio.\");\n          }\n        } else {\n          console.log(\"No existen url's en el registro\");\n        }\n        break;\n      case \"4\":\n        console.log(\"Salir del programa.\");\n        on = false;\n        break;\n      default:\n        console.log(\"Tu elección no es válida. Elige un número del 1 al 4.\");\n        break;\n    }\n  }\n}\nnavegadorWeb();\n\n/*Copiadora*/\n\nfunction impresoraCompartida() {\n\n  let on = true;\n  let stack = [];\n\n  while (on) {\n    \n    console.log(\"\");\n    console.log(\"1.- Ingresar documento en cola\");\n    console.log(\"2.- Imprimir documento\");\n    console.log(\"3.- Salir\");\n\n    let comand = prompt(\"\\nSelecciona una operación: \", \"\");\n\n    switch (comand) {\n      case \"1\":\n        stack.push(prompt(\"Ingresa documento: \"))\n        console.log(`Documentos en cola: ${stack}`);\n        break;\n      case \"2\":\n        if (stack.length !== 0) {\n          if (stack.length > 0) {\n            console.log(`Se imprimió el primer elemento de la cola: ${stack.shift()}`);\n          } \n        } else {\n          console.log(\"No existen documentos en cola\");\n        }\n        break;\n      case \"3\":\n        console.log(\"Salir del programa\");\n        on = false;\n        break;\n    \n      default:\n        console.log(\"Solicitud inválida. Elige números de 1 al 3.\");\n        break;\n    }\n  }\n}\n\nimpresoraCompartida();"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/pedamoci.js",
    "content": "// ------------------------------ MECANISMO DE INTRODUCCION Y RECUPERACION DE ELEMENTO ------------------------------\n  // EN PILAS --> (Un elemento en ejecución (antes de que esta termine) llama a otro elemento y pausa su ejecución, una ves que este se termine de ejecutar renueva la ejecución del anterior)\n    let pila = []\n\n    pila.push(\"PRIMER elemento que se añade a la pila y llama al SEGUNDO\")\n    console.table(pila) // hay un unico elemento en la pila\n    pila.push('SEGUNDO elemento que se añade a la pila llamado por el PRIMERO y llama al TERCERO')\n    console.table(pila) // se le añade un segundo elemento a la pila\n    pila.push('TERCER elemento que se añade a la pila llamado por el SEGUNDO')\n    console.table(pila) // ya hay tres elementos en la pila\n\n    console.log('Ejecución del ULTIMO elemento llamado a la pila: ' + pila[pila.length - 1]) // (pila.length - 1) --> para demostrar que se ejecuta el último elemento\n    pila.pop() // El último elemento llamado a la pila por el segundo ya se ejecuto y finalizo por lo tanto se elimina de esta\n\n    console.log('Ejecución del SEGUNDO elemento llamado a la pila: ' + pila[pila.length - 1])\n    pila.pop() // El segundo elemento llamado a la pila por el primero ya se ejecuto y finalizo por lo tanto se elimina de esta\n\n    console.log('Ejecución del PRIMER elemento llamado a la pila, última en este caso: ' + pila[pila.length - 1])\n    pila.pop() // El primer elemento llamado a la pila ya se ejecuto y finalizo por lo tanto se elimina de esta quedando vacia\n\n    console.table(pila) // ya no hay elementos en la pila\n\n  // EN COLAS --> (Un elemento en ejecución llama a otro elemento, cuando la ejecución del primer elemento termina recien ahí arranca la ejecución del segundo elemento)\n    let cola = []\n\n    cola.push(\"PRIMER elemento que se ejecuta, llama un SEGUNDO y despues un TERCERO\")\n    console.table(cola) // hay un unico elemento en la cola\n    cola.push('SEGUNDO elemento que se añade a la cola llamado por el PRIMERO')\n    console.table(cola) // se le añade un segundo elemento a la cola\n    cola.push('TERCER elemento que se añade a la cola llamado por el PRIMERO')\n    console.table(cola) // ya hay tres elementos en la cola\n\n    console.log('Ejecución del PRIMER elemento en la cola: ' + cola[0])\n    cola.shift() // El primer elemento de la cola ya se ejecuto y finalizo por lo tanto se elimina de esta\n\n    console.log('Ejecución del SEGUNDO elemento en la cola: ' + cola[0])\n    cola.shift() // al finalizar la ejecución del primer elemento inicia la del segundo. Este se ejecuta y una vez finaliza se elimina de la cola\n\n    console.log('Ejecución del TERCER elemento en la cola, última en este caso: ' + cola[0])\n    cola.shift() // al finalizar la ejecución del segundo elemento inicia la del tercero. Este se ejecuta y una vez finaliza se elimina de la cola quedando esta vacia\n\n    console.table(cola) // ya no hay elementos en la cola\n\n// ---------------------------------- DIFICULTAD EXTRA ----------------------------------\nfunction navegadorWeb() {\n  let pagina = []\n  let move = ''\n  do {\n    move = prompt((pagina.length === 0 ? \" \".repeat(31) + `Bienvenidos a la página de incio` + \" \".repeat(31)\n                                          : \" \".repeat(30) + `Bienvenidos a la página número ${pagina.length}` + \" \".repeat(30))\n\n                      + \"\\n\" + \" \".repeat(22) + \"(esbribe exit/salir para terminar la ejecución)\" + \" \".repeat(21) + \"\\n\".repeat(4) +\n                      \"<--(atras/back)\" + \" \".repeat(19) + \"Desea ir hacia\" + \" \".repeat(19) + \"(next/adelante)-->\").toLowerCase()\n    if (move === 'adelante' || move === 'next')  {\n      pagina.push('new page')\n    } else if ((move === 'atras' || move === 'back') && pagina.length !==0) {\n      pagina.pop()\n    }\n  } while (move !== 'salir' && move !== 'exit');\n}\nnavegadorWeb()\n\nfunction impresora() {\n  let colaDocumentos = []\n  let documento = ''\n  do {\n    documento = prompt(\" \".repeat(47) + \"IMPRESORA\" + \" \".repeat(48) + \"\\n\" +\n                        \" \".repeat(14) + \"Escriba el nombre del documento que desea imprimir\" + \" \".repeat(14) + \"\\n\" +\n                        \" \".repeat(34) + `(en cola hay ${colaDocumentos.length} documentos)` + \" \".repeat(34) + \"\\n\".repeat(4)  +\n                        \" \".repeat(19) + \"Escriba 'imprimir' para imprimir un documento\" + \" \".repeat(20)).toLowerCase()\n    if (documento === 'imprimir' && colaDocumentos.length !== 0)  {\n      alert(\" \".repeat(47) + \"IMPRESORA\" + \" \".repeat(48) + \"\\n\".repeat(3) +\n            \"Se ha impreso: \" + colaDocumentos[0] + \".pdf\")\n            colaDocumentos.shift()\n    } else if (documento !== 'imprimir') {\n      colaDocumentos.push(documento)\n      alert(\" \".repeat(47) + \"IMPRESORA\" + \" \".repeat(48) + \"\\n\".repeat(3) +\n            \"Se ha agregado a la cola: \" + documento + \".pdf\")\n    }\n  } while (true);\n}\nimpresora()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/popmaquin.js",
    "content": "/*---Pila---*/\n//Last-in First-out\n\nlet lista= new Array();\n\n//insert elemento al final.\nlista.push(1);\nlista.push(2);\nlista.push(3);\nlista.push(4);\n//elimina el ultimo elemento.\nlista.pop();//4\n\n// Muestra el ultimo elmento\nconsole.log(lista[lista.length - 1]); //5\n\nconsole.log(lista);//[ 1, 2, 3 ]\n\n\n/*---Cola---*/\n//First-in First-out\nlet lista2= new Array();\n\n//Inserta elemento al inicio\nlista2.push(10);\nlista2.push(20);\nlista2.push(30);\n\n//Elimiana 1er elemento shift()\nlista2.shift(); //30\n\n// Muestra el primer elmento\nconsole.log(lista2[0]) // 20\n\nconsole.log(lista2);//[ 20, 30 ]\n\n\n/*---Dificultad extra---*/\n\nfunction navegar_web(){\n    let url_webs= new Array()\n    while(true){\n        let texto= prompt(\"introduce una url para navegar o las palabras atras/adelante/salir: \");\n        if (texto===\"adelante\"){\n          console.log(`Navegando en la pagina principal` );\n        }\n        else if(texto===\"atras\"){\n            if(url_webs.length>0){\n                url_webs.pop()\n            }\n        }\n        else if(texto===\"salir\"){\n            console.log(\"Saliendo de la web \");\n            break;\n        }\n        else{\n            url_webs.push(texto);\n        }\n        \n        if(url_webs.length>0){\n          console.log(\"Navegando a: \"+ (url_webs[url_webs.length- 1]));\n        }\n        else{\n            console.log(`Navegando en la pagina principal` );\n        }\n    }\n}\n\nnavegar_web();\n// https://www.programiz.com/javascript/online-compiler/\n\n\n//programa de impresora compartida --> Cola\n\nfunction impresoraCompartida(){\n    \n    let documento = new Array();\n    while(true){\n        let opcion = prompt(\"Añada un documento o selecciona imprimir/salir: \");\n        \n        if(opcion===\"imprimir\"){\n            if(documento.length>0){\n                console.log(`Imprimiendo... ${documento.shift()}`);\n                \n            }else{\n                console.log(\"Cola de impresion vacia.\");\n            }\n        }\n        else if(opcion===\"salir\"){\n            console.log(\"Apangando impresora...\");\n            break\n        }\n        else{\n            documento.push(opcion);\n        }\n        \n    }\n}\n\nimpresoraCompartida();"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/qwik-zgheib.js",
    "content": "/* -- exercise */\n/* stack - LIFO */\nclass Stack {\n  constructor() {\n    this.items = [];\n  }\n\n  push(element) {\n    this.items.push(element);\n  }\n\n  pop() {\n    if (this.isEmpty()) {\n      return null;\n    }\n    return this.items.pop();\n  }\n\n  isEmpty() {\n    return this.items.length === 0;\n  }\n\n  peek() {\n    if (this.isEmpty()) {\n      return null;\n    }\n    return this.items[this.items.length - 1];\n  }\n\n  size() {\n    return this.items.length;\n  }\n\n  print() {\n    console.log(this.items.toString());\n  }\n}\n\nlet stack = new Stack();\nstack.push(10);\nstack.push(20);\nstack.push(30);\nstack.print();\nconsole.log(stack.pop() !== null ? \"Popped\" : \"Stack is empty\");\nstack.print();\nconsole.log(stack.peek() !== null ? \"Peeked\" : \"Stack is empty\");\n\n/* queue - FIFO */\nclass Queue {\n  constructor() {\n    this.items = [];\n  }\n\n  enqueue(element) {\n    this.items.push(element);\n  }\n\n  dequeue() {\n    if (this.isEmpty()) {\n      return \"Queue is empty\";\n    }\n    return this.items.shift();\n  }\n\n  isEmpty() {\n    return this.items.length === 0;\n  }\n\n  front() {\n    if (this.isEmpty()) {\n      return \"Queue is empty\";\n    }\n    return this.items[0];\n  }\n\n  size() {\n    return this.items.length;\n  }\n\n  printQueue() {\n    console.log(\"Queue:\", this.items.toString());\n  }\n}\n\nlet queue = new Queue();\nqueue.enqueue(10);\nqueue.enqueue(20);\nqueue.enqueue(30);\nqueue.printQueue();\nconsole.log(queue.dequeue());\nqueue.printQueue();\nconsole.log(queue.front());\n\n/* -- extra challenge */\nclass Browser {\n  constructor() {\n    this.backStack = new Stack();\n    this.forwardStack = new Stack();\n    this.currentPage = null;\n  }\n\n  navigate(page) {\n    if (this.currentPage !== null) this.backStack.push(this.currentPage);\n\n    this.currentPage = page;\n    this.forwardStack = new Stack();\n    console.log(\"Navigated to:\", this.currentPage);\n  }\n\n  back() {\n    if (this.backStack.isEmpty()) {\n      console.log(\"No pages to go back to.\");\n      return;\n    }\n    this.forwardStack.push(this.currentPage);\n    this.currentPage = this.backStack.pop();\n    console.log(\"Went back to:\", this.currentPage);\n  }\n\n  forward() {\n    if (this.forwardStack.isEmpty()) {\n      console.log(\"No pages to go forward to.\");\n      return;\n    }\n    this.backStack.push(this.currentPage);\n    this.currentPage = this.forwardStack.pop();\n    console.log(\"Went forward to:\", this.currentPage);\n  }\n}\n\nlet browser = new Browser();\nbrowser.navigate(\"page1.com\");\nbrowser.navigate(\"page2.com\");\nbrowser.navigate(\"page3.com\");\nbrowser.back();\nbrowser.back();\nbrowser.forward();\nbrowser.navigate(\"page4.com\");\nbrowser.forward();\n\nclass Printer {\n  constructor() {\n    this.queue = new Queue();\n  }\n\n  addDocument(document) {\n    this.queue.enqueue(document);\n    console.log(\"Added document:\", document);\n  }\n\n  printDocument() {\n    const document = this.queue.dequeue();\n    if (document !== \"Queue is empty\") console.log(\"Printing document:\", document);\n    else console.log(document);\n  }\n}\n\nlet printer = new Printer();\nprinter.addDocument(\"doc1.pdf\");\nprinter.addDocument(\"doc2.pdf\");\nprinter.addDocument(\"doc3.pdf\");\nprinter.printDocument();\nprinter.printDocument();\nprinter.printDocument();\nprinter.printDocument();\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/rxvlc.js",
    "content": "// En JS estas estructuras no existen cómo tal, las debemos emular, por equivalencia sería como un ArrayList en c#:\nconst pila = [];\n\n// Agregar elementos a la pila\npila.push(1);\npila.push(2);\npila.push(3);\n\n// Eliminar el elemento superior de la pila\nconst elementoEliminadoPila = pila.pop(); // Eliminará 3 de la pila\nconsole.log(elementoEliminadoPila); // Salida: 3\n\nconst cola = [];\n\n// Agregar elementos a la cola\ncola.push(1);\ncola.push(2);\ncola.push(3);\n\n// Eliminar el primer elemento de la cola\nconst elementoEliminadoCola = cola.shift(); // Eliminará 1 de la cola\nconsole.log(elementoEliminadoCola); // Salida: 1\n\n//Dificultad adicional, hecha introduciendo los elementos automáticamente debido a que JS de consola no tiene método de entrada de teclado sin librerías:\nclass NavegadorWeb {\n    constructor() {\n        this.historial = [];\n        this.indiceActual = -1;\n    }\n\n    navegar(pagina) {\n        // Eliminar las páginas futuras al navegar a una nueva página\n        this.historial = this.historial.slice(0, this.indiceActual + 1);\n        \n        // Agregar la nueva página al historial\n        this.historial.push(pagina);\n        \n        // Incrementar el índice actual\n        this.indiceActual++;\n        \n        console.log(`Navegando a: ${pagina}`);\n    }\n\n    retroceder() {\n        if (this.indiceActual > 0) {\n            this.indiceActual--;\n            console.log(`Retrocediendo a: ${this.historial[this.indiceActual]}`);\n        } else {\n            console.log(\"No hay páginas anteriores para retroceder.\");\n        }\n    }\n\n    avanzar() {\n        if (this.indiceActual < this.historial.length - 1) {\n            this.indiceActual++;\n            console.log(`Avanzando a: ${this.historial[this.indiceActual]}`);\n        } else {\n            console.log(\"No hay páginas siguientes para avanzar.\");\n        }\n    }\n}\n\nconst navegador = new NavegadorWeb();\n\n// Ejemplo de uso\nconsole.log();\nconsole.log(\"Navegador: \");\nnavegador.navegar(\"https://www.google.com\");\nnavegador.navegar(\"https://www.wikipedia.org\");\nnavegador.navegar(\"https://www.openai.com\");\n\n// Retroceder una página\nnavegador.retroceder(); // Retrocediendo a: https://www.wikipedia.org\n\n// Retroceder otra página\nnavegador.retroceder(); // Retrocediendo a: https://www.google.com\n\n// Avanzar una página\nnavegador.avanzar(); // Avanzando a: https://www.wikipedia.org\n\n// Navegar a una nueva página\nnavegador.navegar(\"https://www.github.com\");\n\n//Dificultad adicional impresora:\nconsole.log();\nconsole.log(\"Impresora: \");\nclass ImpresoraCompartida {\n    constructor() {\n        this.documentos = [];\n    }\n\n    agregarDocumento(documento) {\n        this.documentos.push(documento);\n        console.log(`Documento '${documento}' agregado a la cola de impresión.`);\n    }\n\n    imprimir() {\n        if (this.documentos.length > 0) {\n            const documento = this.documentos.shift();\n            console.log(`Imprimiendo documento: ${documento}`);\n        } else {\n            console.log(\"No hay documentos en la cola de impresión.\");\n        }\n    }\n\n    mostrarCola() {\n        console.log(\"Documentos en la cola de impresión:\");\n        this.documentos.forEach((documento, index) => {\n            console.log(`${index + 1}. ${documento}`);\n        });\n    }\n}\n\nconst impresora = new ImpresoraCompartida();\n\n// Ejemplo de uso\nimpresora.agregarDocumento(\"Documento1.txt\");\nimpresora.agregarDocumento(\"Documento2.txt\");\nimpresora.agregarDocumento(\"Documento3.txt\");\n\n// Imprimir un documento\nimpresora.imprimir(); // Imprimiendo documento: Documento1.txt\n\n// Mostrar la cola de impresión actual\nimpresora.mostrarCola();"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/saicobys.js",
    "content": "/* Pilas (Stacks - LIFO) */\n\nclass Pila {\n  constructor() {\n    this.elementos = [];\n  }\n\n  push(elementos) {\n    this.elementos.push(elemento);\n  }\n\n  pop() {\n    if (this.isEmpty()) {\n      return null;\n    }\n    return this.elementos.pop();\n  }\n\n  isEmpty() {\n    return this.elementos.length === 0;\n  }\n}\n\n// Ejemplo de uso\nlet pila = new Pila();\npila.push(1);\npila.push(2);\npila.push(3);\n\nconsole.log(pila.pop());\nconsole.log(pila.peek());\nconsole.log(pila.isEmpty());\n\n/* Colas (Queues - FIFO) */\n\nclass Cola {\n  constructor() {\n    this.elementos = [];\n  }\n\n  enqueue(elemento) {\n    this.elementos.push(elemento);\n  }\n\n  dequeue() {\n    if (this.isEmpty()) {\n      return null;\n    }\n    return this.elementos.shift();\n  }\n\n  peek() {\n    if (this.isEmpty()) {\n      return null;\n    }\n    return this.elementos[0];\n  }\n\n  isEmpty() {\n    return this.elementos.length === 0;\n  }\n}\n\n// Ejemplo de uso\nlet cola = new Cola();\ncola.enqueue(1);\ncola.enqueue(2);\ncola.enqueue(3);\n\nconsole.log(cola.dequeue());\nconsole.log(cola.peek());\nconsole.log(cola.isEmpty());\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/seandsun.js",
    "content": "/**\n * <-------------- Pilas -------------->\n * En javascript de manera nativa NO existen las pilas como tal, pero sí podemos hacer uso de los arrays para crearlas.\n * Una pila es una estructura de datos que únicamente nos permite introducir datos en la cima o parte superior; del\n * mismo modo, para eliminar datos únicamente lo podemos hacer por la cima o parte superior. Por tales motivos es más\n * conocida como una estructura LIFO (Last In, First Out), o sea, el último en entrar, es el primero en salir.\n*/\n\nclass Pila {\n  elementos = [] // Este array simulará ser una pila\n\n  insertar = (elemento) => { // Inserta un elemento en la parte superior de la pila\n    this.elementos.push(elemento)\n    return this.elementos\n  }\n\n  Eliminar = () => { // Elimina un elemento de la parte superior de la pila\n    return this.elementos.pop()\n  }\n\n  cima = () => { // Indica cuál es el último elemento de la pila\n    return this.elementos[this.elementos.length-1]\n  }\n\n  estaVacio = () => { // Comprueba si la pila está vacía\n    return this.elementos.length === 0\n  }\n\n  largo = () => { // Indica el número de elementos que contiene la pila\n    return this.elementos.length\n  }\n}\n\nlet pila = new Pila() // Creo una instancia de la clase Pila para poder usar sus métodos\n\nconsole.log(pila.estaVacio()) // true\nconsole.log(pila.insertar(\"Amarillo\")) // [ 'Amarillo' ]\nconsole.log(pila.insertar(\"Azul\")) // [ 'Amarillo', 'Azul' ]\nconsole.log(pila.insertar(\"Verde\")) // [ 'Amarillo', 'Azul', 'Verde' ]\nconsole.log(pila.estaVacio()) // false\nconsole.log(pila.largo()) // 3\nconsole.log(pila.cima()) // Verde\nconsole.log(pila.Eliminar()) // Verde\nconsole.log(pila.Eliminar()) // Azul\nconsole.log(pila.Eliminar()) // Amarillo\n\n/**\n * <-------------- Colas -------------->\n * En javascript de manera nativa NO existen las colas como tal, pero sí podemos hacer uso de los arrays para crearlas.\n * Una cola es una estructura de datos que únicamente nos permite introducir datos al final, o sea después del último dato \n * ingresado; por el contrario, para eliminar datos únicamente lo podemos hacer por el principio o inicio de la cola. Por tales\n * motivos es más conocida como una estructura FIFO (First In, First Out), o sea, el primero en entrar, es el primero en salir.\n*/\n\nclass Cola {\n  elementos = [] // Este array simulará ser una cola\n\n  insertar = (elemento) => { // Inserta un elemento al final de la cola\n    this.elementos.splice(0, 0, elemento)\n    return this.elementos\n  }\n\n  Eliminar = () => { // Elimina un elemento del principio o inicio de la cola\n    return this.elementos.pop()\n  }\n\n  estaVacio = () => { // Comprueba si la cola está vacía\n    return this.elementos.length === 0\n  }\n\n  largo = () => { // Indica el número de elementos que contiene la cola\n    return this.elementos.length\n  }\n}\n\nlet cola = new Cola() // Creo una instancia de la clase Cola para poder usar sus métodos\n\nconsole.log(cola.estaVacio()) // true\nconsole.log(cola.insertar(\"Amarillo\")) // [ 'Amarillo' ]\nconsole.log(cola.insertar(\"Azul\")) // [ 'Azul', 'Amarillo' ]\nconsole.log(cola.insertar(\"Verde\")) // [ 'Verde', 'Azul', 'Amarillo' ]\nconsole.log(cola.estaVacio()) // false\nconsole.log(cola.largo()) // 3\nconsole.log(cola.Eliminar()) // Amarillo\nconsole.log(cola.Eliminar()) // Azul\nconsole.log(cola.Eliminar()) // Verde"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/shevotool.js",
    "content": "/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n */\n\n// Pilas (Stacks - LIFO)  (Last In, First Out)\nconst pilaDias = [\"lunes\", \"martes\", \"miercoles\", \"jueves\", \"viernes\"];\n//console.log(pilaDias);\n\npilaDias.push(\"sabado\");\n//console.log(pilaDias);\n\npilaDias.pop();\n//console.log(pilaDias);\n\n// Colas (Queues - FIFO)  (First In, First Out)\nconst colaDias = [\"lunes\", \"martes\", \"miercoles\", \"jueves\", \"viernes\"];\n\ncolaDias.push(\"sabado\");\n//console.log(colaDias);\n\ncolaDias.shift();\n//console.log(colaDias);\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/victor-Casta.js",
    "content": "/*\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n */\n\n//Pilas (stacks - Last In First Out)\nclass Pila {\n  constructor() {\n    this.items = [];\n  }\n\n  push(element) {\n    this.items.push(element);\n  }\n\n  getLastElement() {\n    if (this.items === 0) {\n      return \"La pila está vacía\";\n    }\n    const lastItem = this.items.splice(this.items.length - 1, 1)[0];\n    return lastItem;\n  }\n}\n\nconst pila = new Pila();\npila.push(1);\npila.push(2);\npila.push(3);\nconsole.log(pila.getLastElement());\nconsole.log(pila.items);\n\n//colas (queue - First In First Out)\nclass Cola {\n  constructor() {\n    this.items = [];\n  }\n\n  push(element) {\n    this.items.push(element);\n  }\n\n  getFirstItem() {\n    const element = this.items.shift();\n    return element;\n  }\n}\n\nconst colas = new Cola();\ncolas.push(1);\ncolas.push(2);\ncolas.push(3);\nconsole.log(colas.getFirstItem());\nconsole.log(colas.items);\n\n/*\n *Extra 1\n */\nclass Web {\n  constructor() {\n    this.navigation = [];\n  }\n\n  action(action, url) {\n    if (action === \"adelante\") {\n      this.next(url);\n    } else if (action === \"atras\") {\n      return this.back();\n    }\n  }\n\n  next(url) {\n    this.navigation.push(url);\n  }\n\n  back() {\n    if (this.navigation.length === 0) {\n      return \"No hay páginas para retroceder\";\n    }\n    return this.navigation.pop();\n  }\n}\n\nconst Chrome = new Web();\nChrome.action(\"adelante\", \"https://chrome.google.com\");\nChrome.action(\"adelante\", \"https://google.com\");\nconsole.log(Chrome.navigation);\nChrome.back();\nconsole.log(Chrome.navigation);\n\n/*\n  *Extra 2\n*/\n\nclass Print {\n  constructor() {\n    this.printSpooler = [];\n  }\n\n  action(action, document) {\n    if (action === 'insertar') {\n      this.insertDocument(document);\n    } else if (action === 'imprimir') {\n      return this.print();\n    } else {\n      console.log('Acción desconocida');\n    }\n  }\n\n  insertDocument(document) {\n    this.printSpooler.push(document);\n  }\n\n  print() {\n    if (this.printSpooler.length <= 0) {\n      console.log('No hay documentos pendientes');\n      return null;\n    } else {\n      return this.printSpooler.shift();\n    }\n  }\n}\n\nlet myPrint = new Print();\nmyPrint.action('insertar', 'Hoja de trabajo 1');\nmyPrint.action('insertar', 'Hoja de trabajo 2');\nmyPrint.action('insertar', 'Hoja de trabajo 3');\nconsole.log(myPrint.printSpooler);\nmyPrint.action('imprimir');\nconsole.log(myPrint.printSpooler);\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/javascript/wapastorv.js",
    "content": "/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista en javascript.\n */\n\n// Implementación de una pila (stack - LIFO)\n/*function Stack() {\n    // Atributos\n    this.stack = [];\n    \n    // Añadir un elemento a la pila\n    this.push = function (element) {\n        this.stack.push(element);\n    }\n\n    // Eliminar un elemento de la pila\n    this.pop = function () {\n        return this.stack.pop();\n    }\n\n    // Devolver el elemento que está en la cima de la pila\n    this.peek = function () {\n        return this.stack[this.stack.length - 1];\n    }\n\n    // Devolver si la pila está vacía\n    this.isEmpty = function () {\n        return this.stack.length === 0;\n    }\n    \n    // Devolver el tamaño de la pila\n    this.size = function () {\n        return this.stack.length;\n    }\n    \n    // Imprimir la pila\n    this.print = function () {\n        console.log(this.stack);\n    }\n    \n    //  Limpiar la pila\n    this.clear = function () {\n        this.stack = [];\n    }\n\n\n}\n\n// Implementación de una cola (queue - FIFO)\nfunction Queue() {\n    // Atributos de la cola (queue) \n    this.queue = [];\n\n    // Métodos de la cola (queue) \n    this.enqueue = function (element) {\n        // Añadir un elemento a la cola\n        this.queue.push(element);\n    }\n\n    // Eliminar un elemento de la cola\n    this.dequeue = function () {\n        return this.queue.shift();\n    }\n\n    // Devolver el primer elemento de la cola\n    this.front = function () {\n        return this.queue[0];\n    }\n\n    // Devolver si la cola está vacía\n    this.isEmpty = function () {\n        return this.queue.length === 0;\n    }\n\n    // Devolver el tamaño de la cola\n    this.size = function () {\n        return this.queue.length;\n    }\n\n    // Imprimir la cola\n    this.print = function () {\n        console.log(this.queue);\n    }\n    \n    // Limpiar la cola\n    this.clear = function () {\n        this.queue = [];\n    }\n}\n \n// Pruebas pila\nvar stack = new Stack();\nstack.push(1);\nstack.push(2);\nstack.push(3);\nstack.print();\nconsole.log(stack.pop());\nconsole.log(stack.peek());\nconsole.log(stack.isEmpty());\nconsole.log(stack.size());\nstack.print();\nstack.clear();\nstack.print();\n\n// Pruebas cola\nvar queue = new Queue();\nqueue.enqueue(1);\nqueue.enqueue(2);\nqueue.enqueue(3);\nqueue.print();\nconsole.log(queue.dequeue());\nconsole.log(queue.front());\nconsole.log(queue.isEmpty());\nconsole.log(queue.size());\nqueue.print();\nqueue.clear();\nqueue.print();/*\n\n/* DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n */\n/*const readline = require(\"readline\");\n\nclass Browser {\n    constructor() {\n        this.historyStack = []; // Pila para el historial hacia atrás\n        this.forwardStack = []; // Pila para el historial hacia adelante\n        this.currentPage = null; // Página actual\n    }\n\n    navigateTo(page) {\n        if (this.currentPage) {\n            this.historyStack.push(this.currentPage);\n        }\n        this.currentPage = page;\n        this.forwardStack = [];\n        console.log(`Navegando a: ${this.currentPage}`);\n    }\n\n    goBack() {\n        if (this.historyStack.length === 0) {\n            console.log(\"No hay más páginas hacia atrás.\");\n            return;\n        }\n        this.forwardStack.push(this.currentPage);\n        this.currentPage = this.historyStack.pop();\n        console.log(`Retrocediendo a: ${this.currentPage}`);\n    }\n\n    goForward() {\n        if (this.forwardStack.length === 0) {\n            console.log(\"No hay más páginas hacia adelante.\");\n            return;\n        }\n        this.historyStack.push(this.currentPage);\n        this.currentPage = this.forwardStack.pop();\n        console.log(`Avanzando a: ${this.currentPage}`);\n    }\n\n    printStatus() {\n        console.log(`Página actual: ${this.currentPage || \"Ninguna\"}`);\n        console.log(`Historial atrás: [${this.historyStack.join(\", \")}]`);\n        console.log(`Historial adelante: [${this.forwardStack.join(\", \")}]`);\n    }\n}\n\n// Configuración del intérprete\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout,\n});\n\nconst browser = new Browser();\n\nfunction showMenu() {\n    console.log(\"\\nAcciones disponibles:\");\n    console.log(\"1. Navegar a una página (escribe el nombre de la página).\");\n    console.log(\"2. Ir atrás (escribe 'atrás').\");\n    console.log(\"3. Ir adelante (escribe 'adelante').\");\n    console.log(\"4. Mostrar estado (escribe 'estado').\");\n    console.log(\"5. Salir (escribe 'salir').\\n\");\n}\n\nfunction processInput(input) {\n    input = input.trim().toLowerCase();\n\n    if (input === \"salir\") {\n        console.log(\"¡Adiós!\");\n        rl.close();\n        return;\n    }\n\n    if (input === \"atrás\") {\n        browser.goBack();\n    } else if (input === \"adelante\") {\n        browser.goForward();\n    } else if (input === \"estado\") {\n        browser.printStatus();\n    } else if (input) {\n        browser.navigateTo(input);\n    } else {\n        console.log(\"Entrada no válida.\");\n    }\n\n    startInteraction(); // Volvemos a mostrar el menú\n}\n\nfunction startInteraction() {\n    showMenu();\n    rl.question(\"¿Qué deseas hacer? \", processInput);\n}\n\n// Iniciar la interacción\nconsole.log(\"¡Bienvenido al navegador interactivo!\");\nstartInteraction();*/\n\n/*DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n\n/*class Impresora {\n    constructor(){\n      this.queue = new Queue();\n    }\n    //Añadir un documento a la cola\n    addDocument(document){\n      this.queue.enqueue(document);\n      console.log(`Documento añadido: ${document}`);\n    }\n    //Imprimir un documento\n    printDocument(){\n      if(this.queue.isEmpty()){\n        console.log(\"No hay documentos para imprimir.\");\n        return;\n      }\n      const document = this.queue.dequeue();\n      console.log(`Imprimiendo documento: ${document}`);\n    }\n    //Mostrar el estado actual\n    printStatus(){\n      console.log(`Documentos en cola: [${this.queue.queue.join(\", \")}]`);\n    }\n}\n\nconst impresora = new Impresora();\nimpresora.addDocument(\"Documento1\");\nimpresora.addDocument(\"Documento2\");\nimpresora.addDocument(\"Documento3\");\nimpresora.printStatus();\nimpresora.printDocument();\nimpresora.printStatus();\nimpresora.printDocument();*/\n\nconst readline = require(\"readline\");\nclass PrinterQueue {\n    constructor() {\n        this.queue = []; // Cola para los documentos\n    }\n\n    addDocument(document) {\n        this.queue.push(document);\n        console.log(`Documento \"${document}\" añadido a la cola.`);\n    }\n\n    printDocument() {\n        if (this.queue.length === 0) {\n            console.log(\"No hay documentos en la cola para imprimir.\");\n        } else {\n            const document = this.queue.shift();\n            console.log(`Imprimiendo: \"${document}\"`);\n        }\n    }\n\n    showQueue() {\n        if (this.queue.length === 0) {\n            console.log(\"La cola de impresión está vacía.\");\n        } else {\n            console.log(`Documentos en la cola: [${this.queue.join(\", \")}]`);\n        }\n    }\n}\n\n// Configuración del intérprete\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout,\n});\n\nconst printer = new PrinterQueue();\n\nfunction showMenu() {\n    console.log(\"\\nAcciones disponibles:\");\n    console.log(\"1. Añadir un documento (escribe el nombre del documento).\");\n    console.log(\"2. Imprimir un documento (escribe 'imprimir').\");\n    console.log(\"3. Ver la cola de impresión (escribe 'cola').\");\n    console.log(\"4. Salir (escribe 'salir').\\n\");\n}\n\nfunction processInput(input) {\n    input = input.trim().toLowerCase();\n\n    if (input === \"salir\") {\n        console.log(\"Cerrando impresora. ¡Adiós!\");\n        rl.close();\n        return;\n    }\n\n    if (input === \"imprimir\") {\n        printer.printDocument();\n    } else if (input === \"cola\") {\n        printer.showQueue();\n    } else if (input) {\n        printer.addDocument(input);\n    } else {\n        console.log(\"Entrada no válida.\");\n    }\n\n    startInteraction(); // Volvemos a mostrar el menú\n}\n\nfunction startInteraction() {\n    showMenu();\n    rl.question(\"¿Qué deseas hacer? \", processInput);\n}\n\n// Iniciar la interacción\nconsole.log(\"¡Bienvenido a la impresora compartida!\");\nstartInteraction();\n\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/kotlin/VincentRodriguezR.kt",
    "content": "import java.util.ArrayDeque\n\nclass queues{\n    fun main() {\n\n        //Definicion\n        var pilaCola =\n            ArrayDeque<Int>() //Esta definicon puede toamr comportamientos tanto de pila como de cola, se debe importar la siguiente dependencia import java.util.ArrayDeque\n\n        //Pilas - Stacks LIFO(Last in, First Out)\n\n        //Insercion de datos\n        pilaCola.push(1)\n        pilaCola.push(2)\n        pilaCola.push(3)\n\n        //Eliminacion\n        var itemEliminadoPila = pilaCola.pop()\n        println(\"En las pilas se elimina el ultimo elemento en ser ingresado al objeto en este caso se elimino $itemEliminadoPila dejando la pila de la siguiente forma $pilaCola\")\n\n        //Obtener elementos\n        var obItemPila = pilaCola.peek()\n        println(\"Al consultar elementos en las pilas se llama al ultimo elemento en la misma, con .peek() por lo que de nuestra pila el ultimo elemento es $obItemPila\")\n\n        //Colas - queue FIFO(First In, First Out)\n\n        //Insercion de datos\n        pilaCola.offer(4)\n        pilaCola.offer(5)\n        pilaCola.offer(6)\n\n        //Eliminacion\n        var itemEliminadoCola = pilaCola.poll()\n        println(\"En las colas se elimina el primer elemento en ser ingresado al objeto en este caso se elimino $itemEliminadoCola dejando la cola de la siguiente forma $pilaCola\")\n\n        //Obtener elementos\n        var obItemCola = pilaCola.last()\n        println(\"Al consultar elementos en las colas se llama al ultimo elemento en la misma, con .last() por lo que de nuestra pila el ultimo elemento es $obItemCola\")\n\n        //Operaciones Comunes\n\n        //Consulta de elementos por indice\n        var obItemPilaCola = pilaCola.elementAt(0)\n        println(\"Si se desea obtener un item especifico se puede usar .elementAt() donde en los parentesis dejaremos la posicion que deseamos obtener, en este caso obtenderemos la 0 = $obItemPilaCola\")\n    }\n\n    //Ejercicio Extra #1 navegacion y adicion de paginas\n    var pages = ArrayDeque<String>()\n    var index = 0\n\n    fun newPage(item: String){\n        pages.push(item)\n        println(\"Se ha agregado la pagina\")\n        start()\n    }\n\n    fun nextPage(){\n        if(index == pages.indices.last){\n            println(\"Se encuentra en la ultima pagina: ${pages.elementAt(index)} no puede avanzar mas\")\n            start()\n        }else{\n            index++\n            println(\"Se encuentra en la siguiente pagina: ${pages.elementAt(index)}\")\n            start()\n        }\n    }\n\n    fun previousPage(){\n        if(index == 0){\n            println(\"Se encuentra en la primera pagina: ${pages.elementAt(index)} no puede retroceder mas\")\n            start()\n        }else{\n            index--\n            println(\"Se encuentra en la siguiente pagina: ${pages.elementAt(index)}\")\n            start()\n        }\n    }\n    fun start() {\n        var action: String?\n        if (pages.size == 0) {\n            println(\"No tiene paginas registradas, por favor registre el nombre de su primera pagina\")\n            newPage(readLine()!!)\n\n        } else {\n            println(\"Escriba la accion que desea realizar, si desea ir hacia adelante escriba 'adelante', si desea ir hacia atras escriba 'atras' y si escribe una palabra diferente se agregara como una pestaña nueva, enc aso que desee finalizar escriba 'finalizar'\")\n            action = readLine()\n            when (action) {\n                \"atras\" -> nextPage()\n                \"adelante\" -> previousPage()\n                \"finalizar\"-> return\n                else -> newPage(action!!)\n            }\n        }\n    }\n\n    //Ejercicio Extra #2 impresiones en cola\n    var documents = ArrayDeque<String>()\n\n    fun begin() {\n        var action: String?\n        if (documents.size == 0) {\n            println(\"No tiene documentos para imprimir, por favor registre el nombre de su primer documento\")\n            newDocument(readLine()!!)\n        } else {\n            println(\"Escriba la accion que desea realizar, Si desea agregar un nuevo documento a la cola ingrese el nombre del documento, si desea imprimir el documento escriba 'Imprimir' y si desea finalizar escriba 'Finalizar'\")\n            action = readLine()\n            when (action) {\n                \"imprimir\" -> printDocument()\n                \"finalizar\"-> return\n                else -> newDocument(action!!)\n            }\n        }\n    }\n\n    fun newDocument(item: String){\n        documents.offer(item)\n        println(\"Se ha agregado el documento a la cola\")\n        begin()\n    }\n\n    fun printDocument(){\n        var printedDocument = documents.pop()\n        println(\"Ha imprimido el siguiente documento $printedDocument\")\n        begin()\n    }\n\n\n    companion object {\n        @JvmStatic\n        fun main(args: Array<String>) {\n            val obj = queues()\n            obj.main()\n            obj.start()\n            obj.begin()\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/kotlin/adridoce.kt",
    "content": "import java.util.*\n\n/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n */\n\nfun main() {\n    val pila = ArrayDeque<String>()\n\n    pila.push(\"Pepe\")\n    pila.push(\"Juan\")\n    pila.push(\"Pedro\")\n\n    println(\"Pila: $pila\")\n\n    val eliminadoPila = pila.pop()\n    println(\"Eliminado: $eliminadoPila\")\n\n    println(\"Pila: $pila\")\n\n    val tope = pila.peek()\n    println(\"Tope: $tope\")\n\n    println(\"Pila: $pila\")\n\n    pila.clear()\n\n    if (pila.isEmpty()) println(\"Pila vacia\") else println(pila)\n\n    val cola = ArrayDeque<String>()\n\n    cola.addLast(\"Adri\")\n    cola.addLast(\"Jose\")\n    cola.addLast(\"Kevin\")\n\n    println(\"\\nCola: $cola\")\n\n    val eliminadoCola = cola.removeFirst()\n    println(\"Eliminado: $eliminadoCola\")\n\n    println(\"Cola: $cola\")\n\n    val front = cola.peek()\n    println(\"Front: $front\")\n\n    println(\"Cola: $cola\")\n\n    //cola.clear()\n\n    if (cola.isEmpty()) println(\"Cola vacia\") else println(cola)\n\n    navegadorWeb()\n    impresora()\n}\n\nfun impresora() {\n\n    /* Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n       impresora compartida que recibe documentos y los imprime cuando así se le indica.\n       La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n       interpretan como nombres de documentos. */\n\n    val cola = ArrayDeque<String>()\n    var accion: String?\n\n    while (true) {\n        println(\"Introduce nombre de documento, imprimir o salir\")\n        accion = readLine()?.trim()?.lowercase()\n\n        when {\n            accion == \"salir\" -> {\n                println(\"Saliendo...\")\n                return\n            }\n\n            accion == \"imprimir\" -> {\n                if (cola.isNotEmpty()) {\n                    println(\"Imprimiendo documento: ${cola.peek()}\")\n                    cola.removeFirst()\n                } else {\n                    println(\"No hay ningun documento pendiente de imprimir !\")\n                }\n            }\n\n            !accion.isNullOrEmpty() -> {\n                cola.addLast(accion)\n                println(\"Documento $accion añadido a la cola de impresion...\")\n            }\n\n            else -> {\n                println(\"Comando invalido...\")\n            }\n        }\n    }\n}\n\nfun navegadorWeb() {\n\n    /* - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n    *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n    *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n    *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n    *   el nombre de una nueva web. */\n\n    val historial = ArrayDeque<String>()\n    val adelante = ArrayDeque<String>()\n\n    var paginaActual: String? = null\n\n    while (true) {\n\n        if (paginaActual != null) {\n            println(\"Pagina actual: $paginaActual\")\n        } else {\n            println(\"Error 404\")\n        }\n\n        println(\"Introduce nombre de web, adelante, atras o salir\")\n        val accion = readlnOrNull()?.trim()?.lowercase()\n\n        when {\n            accion == \"salir\" -> {\n                println(\"Saliendo...\")\n                return\n            }\n\n            accion == \"atras\" -> {\n                if (historial.isNotEmpty() && paginaActual != null) {\n                    adelante.push(paginaActual)\n                    paginaActual = historial.pop()\n                    println(\"Navegando a $paginaActual\")\n                } else {\n                    println(\"No hay ninguna pagina en la pila historial\")\n                }\n            }\n\n            accion == \"adelante\" -> {\n                if (adelante.isNotEmpty() && paginaActual != null) {\n                    historial.push(paginaActual)\n                    paginaActual = adelante.removeFirst()\n                    println(\"Navegando a $paginaActual\")\n                } else {\n                    println(\"No hay ninguna pagina en la pila adelante\")\n                }\n            }\n\n            !accion.isNullOrEmpty() -> {\n                if (paginaActual != null) {\n                    historial.push(paginaActual)\n                }\n                paginaActual = accion\n                adelante.clear()\n                println(\"Navegando a $paginaActual\")\n            }\n\n            else -> {\n                println(\"Comando invalido...\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/kotlin/blackriper.kt",
    "content": "import java.util.*\r\n\r\n/*\r\n   Colas (Primero en Entrar , Primero en Salir)FIFO\r\n   -cada elemento nuevo va al final de la misma\r\n   -primero tiene que salir el primer elemento del mismo y hasta que este salga\r\n    podra salir otro elemento de la lista\r\n*/\r\n\r\nfun exampleWithQueue() {\r\n    // lista de actividades para el dia\r\n    val task= listOf(\"Breakfast\",\"Coworker meeting\",\"buy a food\")\r\n    // cola de procesoa a seguir\r\n    val queueTask:Queue<String> = LinkedList<String>()\r\n    queueTask.addAll(task)\r\n\r\n    // he desayunado completo por lo tanto debo removerlo de la cola\r\n    val firstTask=queueTask.remove()\r\n    println(\"I have to do $firstTask\")\r\n\r\n    // debo mostrar la lista de tareas pendientes\r\n    println(\"I have to do the following tasks: $queueTask\")\r\n}\r\n\r\n// reto extra\r\nfun sharedPrinter(){\r\n   val docs= listOf(\"doc1\",\"doc2\",\"doc3\")\r\n   val printerQueue: Queue<String> = LinkedList<String>()\r\n   printerQueue.addAll(docs)\r\n\r\n    fun addDocument(){\r\n        println(\"What document do you want to add?\")\r\n        val name= readLine()!!.toString()\r\n        printerQueue.add(name)\r\n        println(\"The document $name was added to the printer queue\")\r\n    }\r\n\r\n    fun printDocument(){\r\n        val printerDoc= printerQueue.remove()\r\n        println(\"The document $printerDoc was printed\")\r\n        println(\"the queue is $printerQueue\")\r\n    }\r\n\r\n    do {\r\n      var option:String\r\n      println(\"What do you want to do Add or Print or Exit ?\")\r\n      option= readLine()!!.toString()\r\n      when(option){\r\n         \"Add\" -> addDocument()\r\n         \"Print\" -> printDocument()\r\n        }\r\n    } while (option != \"Exit\")\r\n\r\n}\r\n\r\n/*\r\n  Pila (Last in First Out) LIFO(Ultimo en entrar , primero en salir)\r\n  - el último que entra es el primero que sale\r\n  - apilar coloca un objeto en la pila\r\n  - desapilar saca el último objeto de la pila\r\n  - hasta que se desapila el ultimo elemento  se puede acceder al elemnto que se apilo con anterioridad\r\n  */\r\nfun exampleWithStack(){\r\n    val stackNumber=Stack<Int>()\r\n    stackNumber.push(1)\r\n    stackNumber.push(2)\r\n    stackNumber.push(3)\r\n    println(\"The stack is $stackNumber\")\r\n\r\n    val lastNumber=stackNumber.pop()\r\n    println(\"The last number was $lastNumber\")\r\n\r\n    println(\"The stack is $stackNumber\")\r\n}\r\n\r\n// reto extra\r\nfun webNavigator(){\r\n  val back = Stack<String>()\r\n  val forward = Stack<String>()\r\n\r\n  fun navigate(webPage:String){\r\n     if (back.isEmpty()){\r\n         forward.push(webPage)\r\n         println(\"Navigate to $webPage\")\r\n     }\r\n  }\r\n  fun goBack(){\r\n     if (back.size>1){\r\n         forward.push(back.pop())\r\n         println(\"Go back to ${back.peek()}\")\r\n     }else{\r\n         println(\"Can't go back\")\r\n     }\r\n  }\r\n  fun goForward(){\r\n     if (forward.isNotEmpty()){\r\n         back.push(forward.pop())\r\n         println(\"Go forward to ${forward.peek()}\")\r\n     }else{\r\n         println(\"Can't go forward\")\r\n     }\r\n  }\r\n  navigate(\"google.com\")\r\n  navigate(\"stackoverflow.com\")\r\n  navigate(\"github.com\")\r\n  goBack()\r\n  goBack()\r\n  goForward()\r\n}\r\n\r\n\r\nfun main() {\r\n   //colas\r\n   exampleWithQueue()\r\n   sharedPrinter()\r\n   //pilas\r\n   exampleWithStack()\r\n   webNavigator()\r\n}\r\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/kotlin/didacdev.kt",
    "content": "fun main() {\n    // browser()\n    printer()\n}\n\nclass Stack<T>(initialStack: List<T> = emptyList()) {\n\n    private var stack: MutableList<T> = initialStack.toMutableList()\n\n    fun push(e: T) {\n        stack.addLast(e)\n    }\n\n    fun get(): T? {\n        return this.stack.lastOrNull()\n    }\n\n    fun pop(): T? {\n        return if (stack.isNotEmpty()) {\n            stack.removeLast()\n        } else {\n            null\n        }\n    }\n\n    fun clear() {\n        stack.clear()\n    }\n\n    fun size(): Int {\n        return stack.size\n    }\n}\n\nclass Queue<T>(initialQueue: List<T> = emptyList()) {\n\n    private var queue: MutableList<T> = initialQueue.toMutableList()\n\n    fun enqueue(e: T) {\n        queue.addLast(e)\n    }\n\n    fun get(): T? {\n        return this.queue.lastOrNull()\n    }\n\n    fun dequeue(): T? {\n        return if (queue.isNotEmpty()) {\n            queue.removeLast()\n        } else {\n            null\n        }\n    }\n\n    fun clear() {\n        queue.clear()\n    }\n}\n\nfun browser() {\n    var backward: Stack<String> = Stack()\n    var forward: Stack<String> = Stack()\n\n    fun goBackward() {\n        val actualWeb = backward.pop() ?: \"\"\n        if (actualWeb != \"\") {\n            forward.push(actualWeb)\n        }\n    }\n\n    fun goForward() {\n        val actualWeb = forward.pop() ?: \"\"\n        if (actualWeb != \"\") {\n            backward.push(actualWeb)\n        }\n    }\n\n    fun goWebSite(web: String) {\n        backward.push(web)\n        forward.clear()\n    }\n    var quite = false\n\n    while (!quite) {\n        println()\n        var web = backward.get() ?: \"\"\n        println(\"Web: $web\") \n        println(\"1. Go to a website\")\n        println(\"2. Go back\")\n        println(\"3. Go forward\")\n        println(\"4. Quite\")\n\n        val input = readLine() ?: \"\"\n        if (input == \"1\") {\n            println(\"Web:\")\n                web = readLine() ?: \"\"\n                if (web != \"\") {\n                    goWebSite(web)\n                } else {\n                    println(\"Wrong input\")\n                }\n        } else if (input == \"2\") {\n            goBackward()\n        } else if (input == \"3\") {\n            goForward()\n        } else if (input == \"4\") {\n            quite = true\n        } else {\n            println(\"Wrong input\")\n        }\n    }\n}\n\nfun printer() {\n    var printer: Queue<String> = Queue()\n    var quite = false\n\n    while (!quite) {\n        val word = readLine() ?: \"\"\n\n        if (word != \"\") {\n\n            if (word == \"imprimir\") {\n                val file = printer.dequeue() ?: \"\"\n                println(\"> $file\")\n            } else if (word == \"quite\") {\n                quite = true\n            } else {\n                printer.enqueue(word)\n            }\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/kotlin/eulogioep.kt",
    "content": "// Implementación de una pila (stack - LIFO) utilizando una lista mutable\nclass Stack<T> {\n    private val elements = mutableListOf<T>()\n\n    fun push(item: T) {\n        elements.add(item)\n    }\n\n    fun pop(): T? {\n        if (isEmpty()) return null\n        return elements.removeAt(elements.size - 1)\n    }\n\n    fun peek(): T? {\n        return elements.lastOrNull()\n    }\n\n    fun isEmpty(): Boolean {\n        return elements.isEmpty()\n    }\n}\n\n// Implementación de una cola (queue - FIFO) utilizando una lista mutable\nclass Queue<T> {\n    private val elements = mutableListOf<T>()\n\n    fun enqueue(item: T) {\n        elements.add(item)\n    }\n\n    fun dequeue(): T? {\n        if (isEmpty()) return null\n        return elements.removeAt(0)\n    }\n\n    fun peek(): T? {\n        return elements.firstOrNull()\n    }\n\n    fun isEmpty(): Boolean {\n        return elements.isEmpty()\n    }\n}\n\n// Simulación de navegador web utilizando la pila\nclass WebBrowser {\n    private val backStack = Stack<String>()\n    private val forwardStack = Stack<String>()\n    private var currentPage: String? = null\n\n    fun navigateTo(url: String) {\n        currentPage?.let { backStack.push(it) }\n        currentPage = url\n        while (!forwardStack.isEmpty()) {\n            forwardStack.pop()\n        }\n        println(\"Navegando a: $url\")\n    }\n\n    fun goBack() {\n        if (!backStack.isEmpty()) {\n            currentPage?.let { forwardStack.push(it) }\n            currentPage = backStack.pop()\n            println(\"Retrocediendo a: $currentPage\")\n        } else {\n            println(\"No hay páginas anteriores\")\n        }\n    }\n\n    fun goForward() {\n        if (!forwardStack.isEmpty()) {\n            currentPage?.let { backStack.push(it) }\n            currentPage = forwardStack.pop()\n            println(\"Avanzando a: $currentPage\")\n        } else {\n            println(\"No hay páginas para avanzar\")\n        }\n    }\n}\n\n// Simulación de impresora compartida utilizando la cola\nclass SharedPrinter {\n    private val documentQueue = Queue<String>()\n\n    fun addDocument(document: String) {\n        documentQueue.enqueue(document)\n        println(\"Documento '$document' añadido a la cola de impresión\")\n    }\n\n    fun printNextDocument() {\n        val document = documentQueue.dequeue()\n        if (document != null) {\n            println(\"Imprimiendo: $document\")\n        } else {\n            println(\"No hay documentos en la cola de impresión\")\n        }\n    }\n}\n\nfun main() {\n    // Demostración del navegador web\n    println(\"--- Simulación de Navegador Web ---\")\n    val browser = WebBrowser()\n    browser.navigateTo(\"google.com\")\n    browser.navigateTo(\"openai.com\")\n    browser.goBack()\n    browser.goForward()\n    browser.navigateTo(\"kotlin.com\")\n    browser.goBack()\n    browser.goForward()\n\n    println(\"\\n--- Simulación de Impresora Compartida ---\")\n    val printer = SharedPrinter()\n    printer.addDocument(\"Informe1.pdf\")\n    printer.addDocument(\"Foto.jpg\")\n    printer.printNextDocument()\n    printer.addDocument(\"Contrato.docx\")\n    printer.printNextDocument()\n    printer.printNextDocument()\n    printer.printNextDocument()\n}"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/kotlin/juanppdev.kt",
    "content": "class Stack<T>(initialStack: List<T> = emptyList()) {\n\n    private var stack: MutableList<T> = initialStack.toMutableList()\n\n    fun push(e: T) {\n        stack.addLast(e)\n    }\n\n    fun get(): T? {\n        return this.stack.lastOrNull()\n    }\n\n    fun pop(): T? {\n        return if (stack.isNotEmpty()) {\n            stack.removeLast()\n        } else {\n            null\n        }\n    }\n\n    fun clear() {\n        stack.clear()\n    }\n\n    fun size(): Int {\n        return stack.size\n    }\n}\n\nclass Queue<T>(initialQueue: List<T> = emptyList()) {\n\n    private var queue: MutableList<T> = initialQueue.toMutableList()\n\n    fun enqueue(e: T) {\n        queue.addLast(e)\n    }\n\n    fun get(): T? {\n        return this.queue.lastOrNull()\n    }\n\n    fun dequeue(): T? {\n        return if (queue.isNotEmpty()) {\n            queue.removeLast()\n        } else {\n            null\n        }\n    }\n\n    fun clear() {\n        queue.clear()\n    }\n}\n\nfun browser() {\n    var backward: Stack<String> = Stack()\n    var forward: Stack<String> = Stack()\n\n    fun goBackward() {\n        val actualWeb = backward.pop() ?: \"\"\n        if (actualWeb != \"\") {\n            forward.push(actualWeb)\n        }\n    }\n\n    fun goForward() {\n        val actualWeb = forward.pop() ?: \"\"\n        if (actualWeb != \"\") {\n            backward.push(actualWeb)\n        }\n    }\n\n    fun goWebSite(web: String) {\n        backward.push(web)\n        forward.clear()\n    }\n    var quite = false\n\n    while (!quite) {\n        println()\n        var web = backward.get() ?: \"\"\n        println(\"Web: $web\") \n        println(\"1. Go to a website\")\n        println(\"2. Go back\")\n        println(\"3. Go forward\")\n        println(\"4. Quite\")\n\n        val input = readLine() ?: \"\"\n        if (input == \"1\") {\n            println(\"Web:\")\n                web = readLine() ?: \"\"\n                if (web != \"\") {\n                    goWebSite(web)\n                } else {\n                    println(\"Wrong input\")\n                }\n        } else if (input == \"2\") {\n            goBackward()\n        } else if (input == \"3\") {\n            goForward()\n        } else if (input == \"4\") {\n            quite = true\n        } else {\n            println(\"Wrong input\")\n        }\n    }\n}\n\n/* EXTRA */\n\nfun printer() {\n    var printer: Queue<String> = Queue()\n    var quite = false\n\n    while (!quite) {\n        val word = readLine() ?: \"\"\n\n        if (word != \"\") {\n\n            if (word == \"imprimir\") {\n                val file = printer.dequeue() ?: \"\"\n                println(\"> $file\")\n            } else if (word == \"quite\") {\n                quite = true\n            } else {\n                printer.enqueue(word)\n            }\n        }\n    }\n}\n\nfun main() {\n    // browser()\n    printer()\n}"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/kotlin/rikmij.kt",
    "content": "import java.util.*\n\nfun lifoWeb() {\n    val webs = ArrayDeque<String>()\n    val deletedWebs = mutableListOf<String>()\n\n    do{\n        print(\"\\n¿Quieres buscar una web, avanzar a la siguiente web (adelante) o volver a la anterior (atrás)?\\n\")\n        val action = readln().lowercase()\n        if (action != \"adelante\" && action != \"atrás\" && action != \"esc\"){\n            webs.add(action)\n            println(\"Estás en la web ${webs.peekLast()}\")\n        }\n\n        try {\n            if (action == \"atrás\") {\n                val del = webs.removeLast()\n                deletedWebs.addLast(del)\n                if (webs.size == 0) {\n                    println(\"No hay webs previas.\")\n                } else {\n                    println(\"Estás en la web ${webs.peekLast()}\")\n                }\n            }\n        } catch(e: NoSuchElementException){\n            println(\"No hay webs previas. Estás en ${webs.peekLast()}\")\n        }\n        try {\n            if (action == \"adelante\") {\n                val adit = deletedWebs.removeLast()\n                webs.addLast(adit)\n\n                println(\"Estás en la web ${webs.peekLast()}\")\n\n            }\n        } catch(e: NoSuchElementException){\n            println(\"Estás en la web más reciente: ${webs.peekLast()}\")\n        }\n    }while (action != \"esc\")\n}\n\n\nfun fifoPrint() {\n    val prints = ArrayDeque<String>()\n\n    do{\n        println(\"\\n¿Quieres imprimir el documento (imprimir) o quieres añadir un elemento a la cola?\")\n        println(\"\\\"Next\\\" para siguiente documento, \\\"Prev\\\" para el anterior. \\\"Esc\\\" para salir\")\n        val option = readln().lowercase()\n\n        if (option != \"imprimir\"){\n            prints.add(option)\n            println(\"Documento \\\"${prints.peekFirst()}\\\"\")\n        }else{\n            if (prints.size > 0) {\n                println(\"Documento \\\"${prints.peekFirst()}\\\" imprimiéndose\")\n                prints.removeFirst()\n            }else{\n                println(\"No hay más documentos en cola\")\n            }\n        }\n    } while(option != \"esc\")\n}\n\n\nfun main() {\n    println(\"\\n --> Ejemplo stack - LIFO\")\n    val exampleStack = Stack<String>()\n\n    exampleStack.add(\"Primero\")\n    exampleStack.add(\"Segundo\")\n    exampleStack.add(\"Tercero\")\n    println(exampleStack)\n\n    val last = exampleStack.peek()  //peek busca, pero no elimina\n    println(\"-> $last\")\n    println(exampleStack)\n\n    val popped = exampleStack.pop()\n    println(\"-> $popped\")\n    println(exampleStack)\n\n    println(\"\\n --> Ejemplo queue - FIFO\")\n    val exampleQueue: Queue<Int> = LinkedList()\n    exampleQueue.add(1)\n    exampleQueue.add(2)\n    exampleQueue.add(3)\n    println(exampleQueue)\n\n    val first = exampleQueue.peek()   //peek aquí accede al primer elemento por ser una cola\n    println(\"-> $first\")\n    println(exampleQueue)\n\n    val polled = exampleQueue.poll()\n    println(\"-> $polled\")\n    println(exampleQueue)\n\n    println(\"\\n ${\"~\".repeat(7)} EJERCICIOS EXTRA ${\"~\".repeat(7)}\")\n    println(\"--> EJERCICIO LIFO WEB\")\n    lifoWeb()\n    println(\"\\n--> EJERCICIO FIFO IMPRESORA\")\n    fifoPrint()\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/kotlin/westwbn.kt",
    "content": "/*\nEn Kotlin, <T> es un parámetro de tipo genérico. Estos permiten que las clases y funciones sean reutilizables y\npuedan manejar diferentes tipos sin necesidad de duplicar el código para cada tipo específico.\n*/\nclass Stack<T> {\n    //    Stack (pila): También conocida como LIFO (Last In, First Out), es una estructura de datos donde el último elemento\n    //    que se añade es el primero en ser retirado.\n    private val elements = mutableListOf<T>()\n\n    //    Añadir un elemento a la parte superior de la pila.\n    fun push(data: T) = elements.add(data)\n\n    //    Retirar el elemento superior de la pila.\n    fun pop(): T? = if (elements.isNotEmpty()) elements.removeAt(elements.size - 1) else null\n\n    //    Obtener el elemento superior sin retirarlo.\n    fun peek(): T? = elements.lastOrNull()\n\n    //    Muestra el estado de la pila\n    fun state(): String = if (elements.isNotEmpty()) elements.joinToString() else \"Empty\"\n}\n\nclass Queue<T> {\n    private val elements = mutableListOf<T>()\n\n    //    Añadir un elemento al final de la cola.\n    fun enqueue(data: T) = elements.add(data)\n\n    //    Retirar el elemento al principio de la cola.\n    fun dequeue(): T? = if (elements.isNotEmpty()) elements.removeAt(0) else null\n\n    //    Obtener el elemento al principio de la cola sin retirarlo.\n    fun peek(): T? = elements.firstOrNull()\n\n    //    Muestra el estado de la cola\n    fun state(): String = if (elements.isNotEmpty()) elements.joinToString() else \"Empty\"\n}\n\n\nfun main() {\n    val lifo = Stack<String>()\n    println(\"---Ejemplos de Stack:---\")\n    lifo.push(\"primer plato\")\n    lifo.push(\"segundo plato\")\n    lifo.push(\"tercer plato\")\n    lifo.push(\"cuarto plato\")\n    println(lifo.state())\n    println(\"Elemento a retirar: ${lifo.pop()}\")\n    println(\"Elemento a obtener: ${lifo.peek()}\")\n    println(lifo.state())\n\n    println(\"\\n---Ejemplos de Queue:---\")\n    val fifo = Queue<String>()\n    fifo.enqueue(\"cliente 1\")\n    fifo.enqueue(\"cliente 2\")\n    fifo.enqueue(\"cliente 3\")\n    fifo.enqueue(\"cliente 4\")\n    println(fifo.state())\n    println(\"Elemento a retirar: ${fifo.dequeue()}\")\n    println(\"Elemento al principio de la cola: ${fifo.peek()}\")\n    println(fifo.state())\n}"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/ocaml/luishendrix92.ml",
    "content": "open Printf\n\n(*/------------------------------------------------------------------------\\\n  |                                                                        |\n  |                          Stack Data Structure                          |\n  |                                                                        |\n  |  A {e stack} is a {b LIFO} data structure that contains      <Top>     |\n  |  elements that are added one on top of the other like,      ╔═════╗    |\n  |  for example, in a stack of dirty plates at a restaurant. ┌─║  3  ║    |\n  |  LIFO means {e Last In First Out}; the latest item put    │ ╠═════╣    |\n  |  into the stack is also the first one taken out of it.    └>║  2  ║─┐  |\n  |  Bascially, adding and taking from the top is a O(1)        ╠═════║ │  |\n  |  operation (constant time), which reminds us of a singly  ┌─║  1  ║<┘  |\n  |  linked list, and as a matter of fact, it's implemented   │ ╠═════╣    |\n  |  pretty much in the same way or using one as its backend. └>║  E  ║    |\n  |                                                             ╚═════╝    |\n  |  Stacks are useful in areas like recursion optimization,    <Bottom>   |\n  |  low level function writting, reversing of collections,                |\n  |  lexical evaluation of tokens (I.E reverse polish notation), the       |\n  |  memento pattern for undo/redo operations, backtracking, and more!     |\n  |                                                                        |\n  |  In the module signature below you can see the most common interface   |\n  |  for stacks. Each function signature ([val <identifier> : type]) has   |\n  |  a comment describing what the opertion does among other details.      |\n  |                                                                        |\n  |  NOTE: In the diagram, the bottom cell [E] represents the empty node   |\n  |  often associated to linked lists; it represents an empty structure    |\n  |  and serves as a signal to stop recursion or iteration.                |\n  |                                                                        |\n  \\------------------------------------------------------------------------/*)\n\n(** Last-In-First-Out data structure with constant access and insertion\n    time on the front side. This module performs in-place modification. *)\nmodule type LIFO = sig\n  (** The type of stack containing elements of type ['a]. *)\n  type 'a t\n\n  (** [create ()] returns a {b mutable} empty stack. *)\n  val create : unit -> 'a t\n\n  (** [push elt s] adds [elt] to the top of a stack [s]. *)\n  val push : 'a -> 'a t -> unit\n\n  (** [pop s] removes and returns the topmost element of a stack [s].\n      If the stack is empty, returns [None], otherwise, [Some] element. *)\n  val pop : 'a t -> 'a option\n\n  (** [peek s] returns the topmost element of [s] without removing it.\n      If the stack is empty, returns [None], otherwise, [Some] element. *)\n  val peek : 'a t -> 'a option\n\n  (** [size s] returns the amount of elements in a stack [s]. *)\n  val size : 'a t -> int\n\n  (** [is_empty s] is [true] when [size s = 0], and [false] otherwise. *)\n  val is_empty : 'a t -> bool\n\n  (** [iter s ~f] calls a function [f] of all elements of a stack [s]. *)\n  val iter : f:('a -> unit) -> 'a t -> unit\n\n  (** [clear s] removes all elements from a stack [s], making it empty. *)\n  val clear : 'a t -> unit\nend\n\n(*/------------------------------------------------------------------------\\\n  |                                                                        |\n  |                          Queue Data Structure                          |\n  |                                                                        |\n  |  A queue is a FIFO data structure that can perform insertion on the    | \n  |  back and access/deletion on the front, all in constant time [O(1)].   |\n  |  {b FIFO} stands for {e First In First Out] and it tells us that       |\n  |  when we add elements to the collection, they are added behind the     |\n  |  latest one (the {e rear}) and when it's time to process the elements  |\n  |  in it, a {e dequeue} operation is performed which removes the first   |\n  |  element that was inserted (and then the second, and so on).           |\n  |                                                                        |\n  |  You can find queues being used in graph-related algorithms such as    |\n  |  Breadth-First search for shortest paths, as a simple solution for     |\n  |  resource pooling, in distributed software (like RabbitMQ), server     |\n  |  request processing, task scheduling, event handling, printers, and    |\n  |  much more! There are many implementations here is a rough diagram:    |\n  |                                                                        |\n  |              <Front>                     <Rear>                        |\n  |              ╔═══╗  ╔═══╗  ╔═══╗  ╔═══╗  ╔═══╗  ╔═══════╗              |\n  |              ║ 1 ║->║ 2 ║->║ 3 ║->║ 4 ║->║ 5 ║->║ Empty ║              |\n  |              ╚═══╝  ╚═══╝  ╚═══╝  ╚═══╝  ╚═══╝  ╚═══════╝              |\n  |              First (Dequeue)             Last (Enqueue)                |\n  |                                                                        |\n  |  In the module signature below you can see the most common interface   |\n  |  for queues. Each function signature ([val <identifier> : type]) has   |\n  |  a comment describing what the opertion does among other details.      |\n  |    As a quick note, [iter] is just an OCaml convention for [forEach]   |\n  |  in other programming languages. For simplicity's sake I left out      |\n  |  other useful operations such as [map], [filter], [fold], [is_full],   |\n  |  [of_list], [of_array], [singleton], [bind], [take_n], [add_n], etc.   |\n  |                                                                        |\n  \\------------------------------------------------------------------------/*)\n\n(** First-In-First-Out data structure with constant access time at the front,\n    and constant insertion time at the rear. Performs in-place modification. *)\nmodule type FIFO = sig\n  (** The type of queue containing elements of type ['a]. *)\n  type 'a t\n\n  (** [create ()] returns a {b mutable} empty queue. *)\n  val create : unit -> 'a t\n\n  (** [enqueue elt q] adds [elt] to the front of queue [q]. *)\n  val enqueue : 'a -> 'a t -> unit\n\n  (** [dequeue q] removes the first element at the front of queue [q] and\n      returns it. The retured value is wrapped in an [option] type. *)\n  val dequeue : 'a t -> 'a option\n\n  (** [front q] returns the first element at the front of queue [q]. The\n      returned value is wrapped in an [option] type. *)\n  val front : 'a t -> 'a option\n\n  (** [size q] is the current length of the queue [q]. *)\n  val size : 'a t -> int\n\n  (** [is_empty q] is [true] if [size q = 0], otherwise it's [false]. *)\n  val is_empty : 'a t -> bool\n\n  (** [iter ~f q] calls a consumer function [f] on all elements of [q]. *)\n  val iter : f:('a -> unit) -> 'a t -> unit\n\n  (** [clear q] empties a queue [q] by removing all its elements. *)\n  val clear : 'a t -> unit\nend\n\n(*/------------------------------------------------------------------------\\\n  |                                                                        |\n  |                         Stack Implementations                          |\n  |                                                                        |\n  |  The most common implementation of a stack is a singly-linked list.    |\n  |  As a quick reminder: a SLL is a data structure formed with nodes      |\n  |  that hold a value and point to the next node which can calso be       |\n  |  a null terminator to signal that the end of the list was reached.     |\n  |    In imperative languages we can just create a [struct] that lives    |\n  |  in a random place in memory and points to another node or [null] by   |\n  |  reference; or they are implemented with an array which is a mutable   |\n  |  and sequential (in RAM) data structure with finite size.              |\n  |  Now, in functional programming languages that are able to define      |\n  |  variant types such as Haskell, OCaml, Rust, etc; the type can be      |\n  |  defined as a recursive parameterized variant similar to that of a     |\n  |  singly linked list but with limited operations and semantics.         |\n  |                                                                        |\n  |  Using an [Array] as the underlying type introduces a new concern:     |\n  |  dealing with the finite nature of it. We can just leave the stack     |\n  |  finite and throw an exception (or return an [Error] result) when      |\n  |  the client tries to push elements into a full stack. Or we could      |\n  |  implement a similar mechanism to the [ArrayList] type in {e Java}     |\n  |  which automatically replaces the original array with a new one of     |\n  |  greater length and all the elements of the original copied.           |\n  |                                                                        |\n  \\------------------------------------------------------------------------/*)\n\nmodule Stack : LIFO = struct\n  (* I could have also used my own definition of a linked list:\n     [type 'a t = | Empty | Node of ('a * 'a t)].\n\n     Similar to the standard library: [Nil | Cons of ('a * 'a t)].\n     If I were to create a single element stack: [Node (5, Empty)]...\n     Or push 6 and 7 to that stack: [Node (7, Node (6, Node (5, Empty)))]...\n     Or pop from it by returning the value, and the updated stack:\n     [let pop = function | Node (h, tl) -> Some (h, tl) | Empty -> None]. *)\n  type 'a t =\n    { mutable length : int\n    ; mutable items : 'a list\n    }\n\n  let create () = { length = 0; items = [] }\n\n  let push elt s =\n    s.items <- elt :: s.items;\n    s.length <- s.length + 1\n  ;;\n\n  let pop s =\n    match s.items with\n    | item :: rest ->\n      s.items <- rest;\n      s.length <- s.length - 1;\n      Some item\n    | [] -> None\n  ;;\n\n  let peek s =\n    match s.items with\n    | item :: _ -> Some item\n    | [] -> None\n  ;;\n\n  let clear s =\n    s.items <- [];\n    s.length <- 0\n  ;;\n\n  let size s = s.length\n  let is_empty s = s.length = 0\n  let iter ~f s = List.iter f s.items\nend\n;;\n\n(* Just because the code typechecks doesn't mean it will work 100% as intended.\n   That's why I have to make sure my stack (and queue) works by creating a few\n   {e assertions} that will throw an exception if they're [false]. *)\nlet test_stack = Stack.create () in\nlet f_exec_count = ref 0 in\nlet iteration_values : int list ref = ref [] in\nlet open Stack in\nbegin\n  (* A newly created stack:\n\n     - Must be empty by default.\n     - Must return [None] if peeked and popped at.\n     - Must have a size of 0.\n     - Must not be iterated with a function [f]. *)\n  assert (is_empty test_stack);\n  assert (peek test_stack = None);\n  assert (pop test_stack = None);\n  assert (size test_stack = 0);\n  iter ~f:(fun _ -> incr f_exec_count) test_stack;\n  assert (!f_exec_count = 0);\n  (* After pushing one element, the stack:\n\n     - Must not be empty.\n     - Must return [Some 'a] if peeked at.\n     - Must have a size of 1. *)\n  push 1 test_stack;\n  assert (is_empty test_stack = false);\n  assert (peek test_stack = Some 1);\n  assert (size test_stack = 1);\n  (* After pushing nine more elements, the stack:\n\n     - Must return the last insertion if peeked at.\n     - Must iterate its elements in order of last to firt.\n     - Must have a size of 10. *)\n  for i = 2 to 10 do\n    push i test_stack\n  done;\n  assert (peek test_stack = Some 10);\n  iter ~f:(fun n -> iteration_values := n :: !iteration_values) test_stack;\n  assert (!iteration_values = [ 1; 2; 3; 4; 5; 6; 7; 8; 9; 10 ]);\n  assert (size test_stack = 10);\n  (* After popping once from it, the stack:\n\n     - Must have returned and deleted the topmost element.\n     - Must now have a size of 9.\n     - Peeking at it returns the second to last inserted element. *)\n  let popped = pop test_stack in\n  assert (popped = Some 10);\n  assert (size test_stack = 9);\n  assert (peek test_stack = Some 9);\n  (* After popping nine times from it, the stack:\n\n     - Must have returned the popped elements in order.\n     - Must now be empty and have size of 0. *)\n  let popped_list =\n    Seq.(\n      init 9 Int.succ\n      |> fold_left (fun acc _ -> (pop test_stack |> Option.get) :: acc) [])\n  in\n  assert (popped_list = [ 1; 2; 3; 4; 5; 6; 7; 8; 9 ]);\n  assert (is_empty test_stack && size test_stack = 0)\nend\n\n(*/------------------------------------------------------------------------\\\n  |                                                                        |\n  |                         Queue Implementations                          |\n  |                                                                        |\n  |  Queues are a little bit harder to implement because inserting at the  |\n  |  rear of a collection needs to be a constant time operation just as    |\n  |  removing and accessing the front of it. There are 2 main ways of      |\n  |  doing it and the first one is to have either 2 lists or a list and a  |\n  |  reference to the last node. Having 2 lists achieves immutability      |\n  |  at the cost of having to reverse the rear every time an element is    |\n  |  {e dequeued}; and having a list as the front along with a reference   |\n  |  to its last element as the rear achieves constant time operations at  |\n  |  the very small cost of having to manage pointers and memory in low    |\n  |  level languages, and having to update references in high level        |\n  |  imperative languages. Thankfully, OCaml provides mutable record       |\n  |  fields which allow us to implement queues the imperative way.         |\n  |                                                                        |\n  |  Using arrays, just like with stacks, makes things a bit easier but    |\n  |  we still have to solve the limited length problem and in order not    |\n  |  to waste blocks, we need to implement it as a {b circular array}.     |\n  |                                                                        |\n  |            ┌────R───────────F───────────────────┐                      |\n  |            │  ╔═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╗ │  F=Front             |\n  |            └─>║ 9 ║   ║   ║ 4 ║ 5 ║ 6 ║ 7 ║ 8 ║─┘  R=Rear              |\n  |               ╚═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╝                        |\n  |                 0   1   2   3   4   5   6   7                          |\n  |                                                                        |\n  |               i=0               As the diagram illustrates, there is   |\n  |              ┌───┐              really nothing circular about the      |\n  |        i=7   │ 9 │   i=1        array's shape. The name comes from     |\n  |       ┌───┐  └───┘  ┌───┐       the use of the {e modulo} operator     |\n  |       │ 8 │         │   │       to compute the index of the next       |\n  |   i=6 └───┘         └───┘ i=2   block to enqueue an element into.      |\n  |  ┌───┐                   ┌───┐                                         |\n  |  │ 7 │                   │   │  The modulo operator will return 0 if   |\n  |  └───┘ i=5           i=3 └───┘  the next index is equal to the length  |\n  |       ┌───┐         ┌───┐       of the array, thus giving us the       |\n  |       │ 6 │   i=4   │ 4 │       illusion of a cyclic iteration.        |\n  |       └───┘  ┌───┐  └───┘       When the rear index [+1] is equal to   |\n  |              │ 5 │              the front index, we say it's full.     |\n  |              └───┘              The rear and the front indices are     |\n  |                                 equal at the start (empty state).      |\n  |                                                                        |\n  \\------------------------------------------------------------------------/*)\n\nmodule Queue : FIFO = struct\n  type 'a node =\n    | Empty\n    | Node of\n        { value : 'a\n        ; mutable next : 'a node\n        }\n\n  type 'a t =\n    { mutable length : int\n    ; mutable front : 'a node\n    ; mutable rear : 'a node\n    }\n\n  let create () = { length = 0; front = Empty; rear = Empty }\n\n  let enqueue elt q =\n    let to_insert = Node { value = elt; next = Empty } in\n    (match q.rear with\n     | Empty -> q.front <- to_insert\n     | Node last -> last.next <- to_insert);\n    q.rear <- to_insert;\n    q.length <- q.length + 1\n  ;;\n\n  let clear q =\n    begin\n      q.length <- 0;\n      q.front <- Empty;\n      q.rear <- Empty\n    end\n  ;;\n\n  let dequeue q =\n    match q.front with\n    | Empty -> None\n    | Node { value; next } ->\n      if next = Empty\n      then clear q\n      else (\n        q.length <- q.length - 1;\n        q.front <- next);\n      Some value\n  ;;\n\n  let front q =\n    match q.front with\n    | Empty -> None\n    | Node first -> Some first.value\n  ;;\n\n  let iter ~f q =\n    let rec aux f = function\n      | Empty -> ()\n      | Node { value; next } ->\n        f value;\n        aux f next\n    in\n    aux f q.front\n  ;;\n\n  let size q = q.length\n  let is_empty q = size q = 0\nend\n\nmodule CircularQueue : sig\n  include FIFO\n\n  val enqueue : 'a -> 'a t -> (unit, 'a) result\n\n  (** [create ?len x] is a mutable circular queue of maximum size [len]. The\n      initialization process requires you to pass an placeholder value [x] of\n      type ['a] to fill the underlying {e Array} of type ['a array]. If the\n      optional argument [len] is not provided, it defaults to [10]. *)\n  val create : ?len:int -> 'a -> 'a t\n\n  (** [is_full q] returns [true] if there is no more space for more elements to\n      be enqueued into [q]'s rear. [false] is returned otherwise. *)\n  val is_full : 'a t -> bool\nend = struct\n  type 'a t =\n    { mutable front : int\n    ; mutable rear : int\n    ; elements : 'a array\n    ; max_size : int\n    }\n\n  let create ?(len = 10) x =\n    let max_size = if len < 2 then 2 else len in\n    { max_size; front = -1; rear = -1; elements = Array.make max_size x }\n  ;;\n\n  let is_empty q = q.front = -1 && q.rear = -1\n  let is_full q = (q.rear + 1) mod q.max_size = q.front\n\n  let clear q =\n    q.front <- -1;\n    q.rear <- -1\n  ;;\n\n  let enqueue elt q =\n    if is_full q\n    then Error elt\n    else begin\n      if not (is_empty q)\n      then q.rear <- (q.rear + 1) mod q.max_size\n      else begin\n        q.front <- 0;\n        q.rear <- 0\n      end;\n      q.elements.(q.rear) <- elt;\n      Ok ()\n    end\n  ;;\n\n  let dequeue q =\n    if is_empty q\n    then None\n    else begin\n      let dequeued = Some q.elements.(q.front) in\n      if q.front = q.rear\n      then clear q\n      else q.front <- (q.front + 1) mod q.max_size;\n      dequeued\n    end\n  ;;\n\n  (* The 2nd conditional branch below can be simplified to:\n     [1 + q.rear - q.front + q.max_size * Bool.to_int (q.front > q.rear) ]\n     ----------------------------------------------------------------------- *)\n  let size q =\n    if is_empty q\n    then 0\n    else if q.front <= q.rear\n    then q.rear - q.front + 1\n    else q.max_size - q.front + q.rear + 1\n  ;;\n\n  let iter ~f q =\n    if not (is_empty q)\n    then\n      for i = 0 to size q - 1 do\n        f q.elements.((q.front + i) mod q.max_size)\n      done\n    else ()\n  ;;\n\n  let front q = if is_empty q then None else Some q.elements.(q.front)\nend\n\nlet () =\n  let q = Queue.create () in\n  (* let q = CircularQueue.create 0 in *)\n  let f_exec_count = ref 0 in\n  let iteration_values : int list ref = ref [] in\n  let open Queue in\n  (* let open CircularQueue in *)\n  begin\n    (* A newly created queue:\n\n       - Must be empty by default.\n       - Must return [None] if peeked and dequeued.\n       - Must have a size of 0.\n       - Must not be iterated with a function [f]. *)\n    assert (is_empty q);\n    assert (front q = None);\n    assert (dequeue q = None);\n    assert (size q = 0);\n    iter ~f:(fun _ -> incr f_exec_count) q;\n    assert (!f_exec_count = 0);\n    (* After enqueueing one element, the queue:\n\n       - Must not be empty.\n       - Must return [Some 'a] if peeked at.\n       - Must have a size of 1. *)\n    enqueue 1 q;\n    assert (is_empty q = false);\n    assert (front q = Some 1);\n    assert (size q = 1);\n    (* After enqueueing nine more elements, the queue:\n\n       - Must return the first insertion (1) if peeked at.\n       - Must iterate its elements in order of first to last.\n       - Must have a size of 10. *)\n    for i = 2 to 10 do\n      enqueue i q\n    done;\n    assert (front q = Some 1);\n    iter ~f:(fun n -> iteration_values := n :: !iteration_values) q;\n    assert (!iteration_values = [ 10; 9; 8; 7; 6; 5; 4; 3; 2; 1 ]);\n    assert (size q = 10);\n    (* After dequeueing once, the queue:\n\n       - Must have returned and deleted the first element.\n       - Must now have a size of 9.\n       - Peeking it returns the second element (2). *)\n    let dequeued = dequeue q in\n    assert (dequeued = Some 1);\n    assert (size q = 9);\n    assert (front q = Some 2);\n    (* After dequeueint nine times, the queue:\n\n       - Must have returned the dequeued elements in order.\n       - Must now be empty and have size of 0. *)\n    let dequeue_list =\n      Seq.(\n        init 9 Int.succ\n        |> fold_left (fun acc _ -> (dequeue q |> Option.get) :: acc) [])\n    in\n    assert (dequeue_list = [ 10; 9; 8; 7; 6; 5; 4; 3; 2 ]);\n    assert (is_empty q && size q = 0)\n  end\n;;\n\n(*/------------------------------------------------------------------------\\\n  |                                                                        |\n  |                     DIFICULTAD EXTRA (Opcional)                        |\n  |                                                                        |\n  |  - Utilizando la implementación de pila y cadenas de texto, simula     |\n  |    el mecanismo adelante/atrás de un navegador web. Crea un programa   |\n  |    en el que puedas navegar a una página o indicarle que te quieres    |\n  |    desplazar adelante o atrás, mostrando en cada caso el nombre de     |\n  |    la web. Las palabras \"adelante\", \"atras\" desencadenan esta acción,  |\n  |    el resto se interpreta como el nombre de una nueva web.             |\n  |                                                                        |\n  |  - Utilizando la implementación de cola y cadenas de texto, simula el  |\n  |    mecanismo de una impresora compartida que recibe documentos y los   |\n  |    imprime cuando así se le indica. La palabra \"imprimir\" imprime un   |\n  |    elemento de la cola, el resto de palabras se interpretan como       |\n  |    nombres de documentos.                                              |\n  |                                                                        |\n  \\------------------------------------------------------------------------/*)\n\nmodule BrowserExample = struct\n  type website = string * string (* title , url *)\n\n  type history =\n    { past : website Stack.t\n    ; mutable present : website\n    ; future : website Stack.t\n    }\n\n  type action =\n    | BrowseTo of website\n    | GoForward\n    | GoBack\n\n  let display_history { past; present = title, url; future } =\n    print_endline\n      \"----------------------------------------------------------------\";\n    printf \"MoureFox> Now browsing [%s] (URL: %s)\\n\" title url;\n    printf\n      \"└───────> Web Browsing History: %d [◀] - [▶] %d\\n\\n\"\n      (Stack.size past)\n      (Stack.size future)\n  ;;\n\n  let dispatch h action =\n    begin\n      match action with\n      | BrowseTo web ->\n        Stack.push h.present h.past;\n        printf \"MoureFox> Added [%s] to the past stack.\\n\" (fst h.present);\n        h.present <- web\n      | GoForward ->\n        Stack.push h.present h.past;\n        printf \"MoureFox> Added [%s] to the past stack.\\n\" (fst h.present);\n        (match Stack.pop h.future with\n         | Some web ->\n           printf \"MoureFox> Removed [%s] from the future stack.\\n\" (fst web);\n           h.present <- web\n         | None -> print_endline \"The future stack is empty, can't go forward.\")\n      | GoBack ->\n        Stack.push h.present h.future;\n        printf \"MoureFox> Added [%s] to the future stack.\\n\" (fst h.present);\n        (match Stack.pop h.past with\n         | Some web ->\n           printf \"MoureFox> Removed [%s] from the past stack.\\n\" (fst web);\n           h.present <- web\n         | None -> print_endline \"The past stack is empty, can't go back.\")\n    end;\n    display_history h\n  ;;\n\n  let run () =\n    let browser_history =\n      { past = Stack.create ()\n      ; present = \"New Tab\", \"chrome://newtab\"\n      ; future = Stack.create ()\n      }\n    in\n    begin\n      print_endline\n        \"Mr. Moure is done with today's work. Time for some web browsing!\";\n      print_endline \"He sits on his chair and opens a very dumb web browser...\";\n      display_history browser_history;\n      print_endline \"He first clicks on a bookmark that looks like a letter X.\";\n      dispatch browser_history\n      @@ BrowseTo (\"Inicio / X\", \"https://twitter.com/home\");\n      print_endline\n        \"A random link in a tweet catches his attention and cliks on it.\";\n      dispatch browser_history @@ BrowseTo (\"Project IDX\", \"https://idx.dev/\");\n      print_endline\n        \"He is so impressed with it, his Discord must know about it too!\";\n      dispatch browser_history\n      @@ BrowseTo\n           ( \"Discord | MoureDev\"\n           , \"https://discord.com/channels/729672926432985098\" );\n      print_endline\n        \"And so do his Twitter followers; he clicks on 'Go Back' twice.\";\n      dispatch browser_history GoBack;\n      dispatch browser_history GoBack;\n      print_endline\n        \"Lastly, a click to 'Go Forward' to go back to IDX and call it a day.\";\n      dispatch browser_history GoForward\n    end\n  ;;\nend\n\n(* BrowserExample.run () *)\n(* Output of the example scenario:\n\n   Mr. Moure is done with today's work. Time for some web browsing!\n   He sits on his chair and opens a very dumb web browser...\n   ----------------------------------------------------------------\n   MoureFox> Now browsing [New Tab] (URL: N/A)\n   └───────> Web Browsing History: 0 [◀] - [▶] 0\n\n   He first clicks on a bookmark that looks like a letter X.\n   MoureFox> Added [New Tab] to the past stack.\n   ----------------------------------------------------------------\n   MoureFox> Now browsing [Inicio / X] (URL: https://twitter.com/home)\n   └───────> Web Browsing History: 1 [◀] - [▶] 0\n\n   A random link in a tweet catches his attention and cliks on it.\n   MoureFox> Added [Inicio / X] to the past stack.\n   ----------------------------------------------------------------\n   MoureFox> Now browsing [Project IDX] (URL: https://idx.dev/)\n   └───────> Web Browsing History: 2 [◀] - [▶] 0\n\n   He is so impressed with it, his Discord must know about it too!\n   MoureFox> Added [Project IDX] to the past stack.\n   ----------------------------------------------------------------\n   MoureFox> Now browsing [Discord | MoureDev] (URL: https://discord.com/channels/729672926432985098)\n   └───────> Web Browsing History: 3 [◀] - [▶] 0\n\n   And so do his Twitter followers; he clicks on 'Go Back' twice.\n   MoureFox> Added [Discord | MoureDev] to the future stack.\n   MoureFox> Removed [Project IDX] from the past stack.\n   ----------------------------------------------------------------\n   MoureFox> Now browsing [Project IDX] (URL: https://idx.dev/)\n   └───────> Web Browsing History: 2 [◀] - [▶] 1\n\n   MoureFox> Added [Project IDX] to the future stack.\n   MoureFox> Removed [Inicio / X] from the past stack.\n   ----------------------------------------------------------------\n   MoureFox> Now browsing [Inicio / X] (URL: https://twitter.com/home)\n   └───────> Web Browsing History: 1 [◀] - [▶] 2\n\n   Lastly, a click to 'Go Forward' to go back to IDX and call it a day.\n   MoureFox> Added [Inicio / X] to the past stack.\n   MoureFox> Removed [Project IDX] from the future stack.\n   ----------------------------------------------------------------\n   MoureFox> Now browsing [Project IDX] (URL: https://idx.dev/)\n   └───────> Web Browsing History: 2 [◀] - [▶] 1\n*)\n\nmodule PrinterExample = struct\n  let printer = CircularQueue.create ~len:5 \"\"\n\n  let run () =\n    print_endline \"A shared printer sits on a desk ready to be used.\";\n    print_endline\n      \"One of the officer workers decides to print [2024Q1report.xlsx].\";\n    Result.get_ok @@ CircularQueue.enqueue \"2024Q1report.xlsx\" printer;\n    print_endline\n      \"Shortly after that, before the printer even begins to print the\";\n    print_endline\n      \"previous document, the CEO queues [vacation.pdf] and [vendor.docx]!\";\n    Result.get_ok @@ CircularQueue.enqueue \"vacation.pdf\" printer;\n    Result.get_ok @@ CircularQueue.enqueue \"vendor.docx\" printer;\n    let dequeued = CircularQueue.dequeue printer in\n    printf\n      \"Printer> Document [%s] finished printing.\\n\"\n      (Core.Option.value_exn dequeued);\n    print_endline \"Printer> Here's the printing queue:\";\n    CircularQueue.iter ~f:print_endline printer;\n    print_endline \"The rest of the queue finishes printing.\";\n    while CircularQueue.dequeue printer <> None do\n      ()\n    done;\n    print_endline \"5 more documents are queued, making the queue full...\";\n    for i = 1 to 5 do\n      Result.get_ok\n      @@ CircularQueue.enqueue (sprintf \"document%d.pdf\" i) printer\n    done;\n    print_endline \"Printer> Here's the printing queue:\";\n    CircularQueue.iter ~f:print_endline printer;\n    print_endline \"then, the CFO wants to queue [payroll.xls] but she can't.\";\n    begin\n      match CircularQueue.enqueue \"payroll.xls\" printer with\n      | Error doc ->\n        printf \"Printer> ERROR: Could not enequeue [%s], queue is full.\\n\" doc\n      | Ok () -> ()\n    end\n  ;;\nend\n;;\n\nPrinterExample.run ()\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/pascal/miguelex.pas",
    "content": "{ OJO, el codigo que viene a continuación debe ir en un fichero aparte llamado ColaYPilaUnit.pas }\nunit ColaYPilaUnit;\n\n{$mode objfpc}{$H+}\n\ninterface\n\ntype\n  Cola = class\n  private\n    cola: array of Integer;\n    inicio: Integer;\n    fin: Integer;\n    max: Integer; // Opcional para limitar el tamaño de la cola\n  public\n    constructor Create;\n    procedure encolar(elemento: Integer);\n    function desencolar: Integer;\n    procedure mostrar;\n  end;\n\n  Pila = class\n  private\n    pila: array of Integer;\n    tope: Integer;\n    max: Integer; // Opcional para limitar el tamaño de la pila\n  public\n    constructor Create;\n    procedure apilar(elemento: Integer);\n    function desapilar: Integer;\n    procedure mostrar;\n    function getPosition(i: Integer): Integer;\n    function getTope: Integer;\n  end;\n\nimplementation\n\nconstructor Cola.Create;\nbegin\n  SetLength(cola, 10); // Tamaño predeterminado de la cola\n  inicio := 0;\n  fin := 0;\n  max := 10; // Opcional para limitar el tamaño de la cola\nend;\n\nprocedure Cola.encolar(elemento: Integer);\nbegin\n  if fin < max then\n  begin\n    cola[fin] := elemento;\n    fin := fin + 1;\n  end\n  else\n    WriteLn('La cola está llena');\nend;\n\nfunction Cola.desencolar: Integer;\nbegin\n  if inicio < fin then\n  begin\n    Result := cola[inicio];\n    inicio := inicio + 1;\n  end\n  else\n  begin\n    WriteLn('La cola está vacía');\n    Result := 0; // Puedes elegir un valor de retorno apropiado aquí\n  end;\nend;\n\nprocedure Cola.mostrar;\nvar\n  i: Integer;\nbegin\n  if inicio = fin then\n    WriteLn('La cola está vacía')\n  else\n  begin\n    for i := inicio to fin - 1 do\n      Write(cola[i], ' ');\n    WriteLn;\n  end;\nend;\n\nconstructor Pila.Create;\nbegin\n  SetLength(pila, 7); // Tamaño predeterminado de la pila\n  tope := 0;\n  max := 7; // Opcional para limitar el tamaño de la pila\nend;\n\nprocedure Pila.apilar(elemento: Integer);\nbegin\n  if tope < max then\n  begin\n    pila[tope] := elemento;\n    tope := tope + 1;\n  end\n  else\n    WriteLn('La pila está llena');\nend;\n\nfunction Pila.desapilar: Integer;\nbegin\n  if tope > 0 then\n  begin\n    tope := tope - 1;\n    Result := pila[tope];\n  end\n  else\n  begin\n    WriteLn('La pila está vacía');\n    Result := 0; // Puedes elegir un valor de retorno apropiado aquí\n  end;\nend;\n\nprocedure Pila.mostrar;\nvar\n  i: Integer;\nbegin\n  if tope = 0 then\n    WriteLn('La pila está vacía')\n  else\n  begin\n    for i := tope - 1 downto 0 do\n      Write(pila[i], ' ');\n    WriteLn;\n  end;\nend;\n\nfunction Pila.getPosition(i: Integer): Integer;\nbegin\n  Result := pila[i];\nend;\n\nfunction Pila.getTope: Integer;\nbegin\n  Result := tope;\nend;\n\nend.\n\n{ Aqui acaba el codigo a incluir en el fichero ColaYPilaUnit.pas Lo que sigue es el programa principal y se queda en este archivo}\n\nprogram miguelex;\n\n{$mode objfpc}{$H+}\n\nuses\n  ColaYPilaUnit;\n\nvar\n  miCola: Cola;\n  miPila: Pila;\n  entrada: String;\n  ultimoIndexVisitado: Integer;\n  cabeza: Integer;\n  documento: Integer;\n\nbegin\n  WriteLn('Vamos a trabajar con la cola');\n  WriteLn('Vamos a mostrar el contenido de la cola al inicio de la misma: ');\n  miCola := Cola.Create;\n  miCola.mostrar;\n  WriteLn;\n\n  WriteLn('Vamos a encolar 3 elementos: 1, 2 y 3');\n  miCola.encolar(1);\n  miCola.encolar(2);\n  miCola.encolar(3);\n\n  WriteLn('Vamos a mostrar el contenido de la cola después de encolar 3 elementos: ');\n  miCola.mostrar;\n  WriteLn;\n\n  WriteLn('Vamos a desencolar un elemento');\n  miCola.desencolar;\n\n  WriteLn('Vamos a mostrar el contenido de la cola después de desencolar un elemento: ');\n  miCola.mostrar;\n  WriteLn;\n\n  WriteLn('Vamos a encolar 2 elementos: 4 y 5 y vamos a desencolar dos');\n  miCola.encolar(4);\n  miCola.encolar(5);\n  miCola.desencolar;\n  miCola.desencolar;\n\n  WriteLn('Vamos a mostrar el contenido de la cola después de encolar 2 elementos y desencolar dos: ');\n  miCola.mostrar;\n  WriteLn;\n\n  WriteLn('Por último, vamos a desencolar tres elementos (recuerda que realmente solo nos quedan 2 dentro de la cola)');\n  miCola.desencolar;\n  miCola.desencolar;\n  miCola.desencolar;\n\n  WriteLn('Vamos a mostrar el contenido de la cola después de desencolar tres elementos: ');\n  miCola.mostrar;\n  WriteLn;\n\n  WriteLn('Ahora, vamos a trabajar con la pila');\n  WriteLn;\n\n  miPila := Pila.Create;\n  WriteLn('Vamos a mostrar el contenido de la pila al inicio de la misma: ');\n  miPila.mostrar;\n  WriteLn;\n\n  WriteLn('Vamos a apilar 3 elementos: 1, 2 y 3');\n  miPila.apilar(1);\n  miPila.apilar(2);\n  miPila.apilar(3);\n\n  WriteLn('Vamos a mostrar el contenido de la pila después de apilar 3 elementos: ');\n  miPila.mostrar;\n  WriteLn;\n\n  WriteLn('Vamos a desapilar un elemento');\n  miPila.desapilar;\n\n  WriteLn('Vamos a mostrar el contenido de la pila después de desapilar un elemento: ');\n  miPila.mostrar;\n  WriteLn;\n\n  WriteLn('Vamos a apilar 2 elementos: 4 y 5 y vamos a desapilar dos');\n  miPila.apilar(4);\n  miPila.apilar(5);\n  miPila.desapilar;\n  miPila.desapilar;\n\n  WriteLn('Vamos a mostrar el contenido de la pila después de apilar 2 elementos y desapilar dos: ');\n  miPila.mostrar;\n  WriteLn;\n\n  WriteLn('Por último, vamos a desapilar tres elementos (recuerda que realmente solo nos quedan 2 dentro de la pila)');\n  miPila.desapilar;\n  miPila.desapilar;\n  miPila.desapilar;\n\n  WriteLn('Vamos a mostrar el contenido de la pila después de desapilar tres elementos: ');\n  miPila.mostrar;\n  WriteLn;\n\n  WriteLn('Vamos a simular el mecanismo adelante/atrás de un navegador web');\n\n  ultimoIndexVisitado := -1;\n\n  repeat\n    cabeza := miPila.getTope - 1;\n\n    Write('Escribe el nombre de la web, adelante, atras o exit: ');\n    ReadLn(entrada);\n    if entrada = 'adelante' then\n    begin\n      if ultimoIndexVisitado < cabeza then\n      begin\n        ultimoIndexVisitado := ultimoIndexVisitado + 1;\n        WriteLn('Navegando adelante a la web: ', miPila.getPosition(ultimoIndexVisitado));\n      end\n      else\n        WriteLn('No hay más webs para navegar adelante');\n    end\n    else if entrada = 'atras' then\n    begin\n      if ultimoIndexVisitado > 0 then\n      begin\n        ultimoIndexVisitado := ultimoIndexVisitado - 1;\n        WriteLn('Navegando atrás a la web: ', miPila.getPosition(ultimoIndexVisitado));\n      end\n      else\n        WriteLn('No hay más webs para navegar atrás');\n    end\n    else if entrada <> 'exit' then\n    begin\n      miPila.apilar(StrToInt(entrada[1]));\n      ultimoIndexVisitado := miPila.getTope - 1;\n      WriteLn('Estás en la web: ', entrada);\n    end;\n  until entrada = 'exit';\n\n  WriteLn('Vamos a simular el mecanismo de una cola de impresión');\n\n  repeat\n    Write('Escribe el nombre del documento, imprimir o exit: ');\n    ReadLn(entrada);\n    if entrada = 'imprimir' then\n    begin\n      documento := miCola.desencolar;\n      if documento <> 0 then\n        WriteLn('Imprimiendo documento: ', documento)\n      else\n        WriteLn('No hay documentos para imprimir');\n    end\n    else if entrada <> 'exit' then\n    begin\n      miCola.encolar(StrToInt(entrada[1]));\n      WriteLn('Documento encolado: ', entrada);\n    end;\n  until entrada = 'exit';\n\nend.\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/php/eulogioep.php",
    "content": "<?php\n\n// Implementación de la Pila (Stack - LIFO)\nclass Stack {\n    private $items = [];\n\n    // Método para añadir un elemento a la pila\n    public function push($element) {\n        array_push($this->items, $element);\n    }\n\n    // Método para quitar un elemento de la pila\n    public function pop() {\n        if ($this->isEmpty()) {\n            echo \"Error: Pila vacía\\n\";\n            return null;\n        }\n        return array_pop($this->items);\n    }\n\n    // Método para verificar si la pila está vacía\n    public function isEmpty() {\n        return empty($this->items);\n    }\n\n    // Método para obtener el elemento en la cima de la pila sin quitarlo\n    public function peek() {\n        if ($this->isEmpty()) {\n            echo \"Error: Pila vacía\\n\";\n            return null;\n        }\n        return end($this->items);\n    }\n}\n\n// Implementación de la Cola (Queue - FIFO)\nclass Queue {\n    private $items = [];\n\n    // Método para añadir un elemento a la cola\n    public function enqueue($element) {\n        array_push($this->items, $element);\n    }\n\n    // Método para quitar un elemento de la cola\n    public function dequeue() {\n        if ($this->isEmpty()) {\n            echo \"Error: Cola vacía\\n\";\n            return null;\n        }\n        return array_shift($this->items);\n    }\n\n    // Método para verificar si la cola está vacía\n    public function isEmpty() {\n        return empty($this->items);\n    }\n\n    // Método para obtener el primer elemento de la cola sin quitarlo\n    public function peek() {\n        if ($this->isEmpty()) {\n            echo \"Error: Cola vacía\\n\";\n            return null;\n        }\n        return $this->items[0];\n    }\n}\n\n// Función para el simulador de navegador web\nfunction webBrowserSimulator() {\n    $backStack = new Stack();\n    $forwardStack = new Stack();\n    $currentPage = \"\";\n\n    echo \"Simulador de navegador web (escribe 'salir' para terminar):\\n\";\n\n    while (true) {\n        $input = strtolower(trim(readline(\"Ingresa una acción o nombre de página web: \")));\n\n        if ($input === 'salir') {\n            break;\n        } elseif ($input === 'atrás') {\n            if (!$backStack->isEmpty()) {\n                $forwardStack->push($currentPage);\n                $currentPage = $backStack->pop();\n                echo \"Página actual: $currentPage\\n\";\n            } else {\n                echo \"No hay páginas anteriores\\n\";\n            }\n        } elseif ($input === 'adelante') {\n            if (!$forwardStack->isEmpty()) {\n                $backStack->push($currentPage);\n                $currentPage = $forwardStack->pop();\n                echo \"Página actual: $currentPage\\n\";\n            } else {\n                echo \"No hay páginas siguientes\\n\";\n            }\n        } else {\n            if ($currentPage !== \"\") {\n                $backStack->push($currentPage);\n            }\n            $forwardStack = new Stack();  // Limpia la pila de adelante\n            $currentPage = $input;\n            echo \"Página actual: $currentPage\\n\";\n        }\n    }\n}\n\n// Función para el simulador de impresora compartida\nfunction printerSimulator() {\n    $printQueue = new Queue();\n\n    echo \"\\nSimulador de impresora compartida (escribe 'salir' para terminar):\\n\";\n\n    while (true) {\n        $input = strtolower(trim(readline(\"Ingresa un nombre de documento o 'imprimir': \")));\n\n        if ($input === 'salir') {\n            break;\n        } elseif ($input === 'imprimir') {\n            $document = $printQueue->dequeue();\n            if ($document !== null) {\n                echo \"Imprimiendo: $document\\n\";\n            }\n        } else {\n            $printQueue->enqueue($input);\n            echo \"Documento añadido a la cola: $input\\n\";\n        }\n    }\n}\n\n// Ejecutar los simuladores\nwebBrowserSimulator();\nprinterSimulator();\n\n?>"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/php/gabrielmoris.php",
    "content": "<?php\n/*\n * EXERCISE:\n * Implement the mechanisms of introduction and retrieval of elements typical of\n * stacks (stacks - LIFO) and queues (queue - FIFO) using an array\n * or list (depending on the possibilities of your language).\n */\n\nclass Stack\n{\n    private $pages;\n    private $length;\n\n    // Constructor\n    public function __construct()\n    {\n        $this->items =  [];\n        $this->length = 0;\n    }\n\n    public function push($item)\n    {\n        $this->length += 1;\n        array_push($this->items, $item);\n    }\n\n    public function pop()\n    {\n        $this->length -= 1;\n        return array_pop($this->items);\n    }\n\n    public function peek()\n    {\n        if (empty($this->items)) {\n            return null;\n        }\n\n        return  $this->items[count($this->items) - 1];\n    }\n\n    public function size()\n    {\n        return  $this->length;\n    }\n\n    public function search($item)\n    {\n        $index = array_search($item, $this->items);\n\n        if (!$index && $index !== 0) {\n            return -1;\n        }\n\n        return $index;\n    }\n\n    public function clear()\n    {\n        $this->length = 0;\n        $this->items = [];\n    }\n}\n\necho \"====== STACK ======\\n\";\n$st = new Stack();\n$st->push(1);\necho $st->peek() . \"\\n\"; // 1\n$st->push(2);\necho $st->peek() . \"\\n\"; // 2\necho $st->search(1) . \"\\n\"; //0\necho $st->pop() . \"\\n\"; // 2\necho $st->peek() . \"\\n\"; // 1\necho $st->search(2) . \"\\n\"; // -1\n\n\nclass Queue\n{\n    private $items;\n    private $length;\n\n    // Constructor\n    public function __construct()\n    {\n        $this->items =  [];\n        $this->length = 0;\n    }\n\n    public function enqueue($item)\n    {\n        $this->length += 1;\n        array_push($this->items, $item);\n    }\n\n    public function dequeue()\n    {\n        $this->length -= 1;\n        return array_shift($this->items);\n    }\n\n    public function peek()\n    {\n        if (empty($this->items)) {\n            return null;\n        }\n\n        return  $this->items[0];\n    }\n\n    public function size()\n    {\n        return  $this->length;\n    }\n\n    public function search($item)\n    {\n        $index = array_search($item, $this->items);\n\n        if (!$index && $index !== 0) {\n            return -1;\n        }\n\n        return $index;\n    }\n\n    public function clear()\n    {\n        $this->length = 0;\n        $this->items = [];\n    }\n}\n\necho \"====== QUEUE ======\\n\";\n$qu = new Queue();\n$qu->enqueue(1);\necho $qu->peek() . \"\\n\"; // 1\n$qu->enqueue(2);\necho $qu->peek() . \"\\n\"; // 1\necho $qu->search(1) . \"\\n\"; // 0\necho $qu->dequeue() . \"\\n\"; // 1\necho $qu->peek() . \"\\n\"; // 2\necho $qu->search(2) . \"\\n\"; // 0\n\n/*\n * EXTRA DIFFICULTY (optional):\n * - Using the stack implementation and text strings, simulate the forward/back\n *   mechanism of a web browser. Create a program in which you can navigate to a page or tell it\n *   that you want to move forward or backward, showing in each case the name of the web.\n *   The words \"forward\", \"backward\" trigger this action, the rest is interpreted as\n *   the name of a new web.\n * - Using the queue implementation and text strings, simulate the mechanism of a\n *   shared printer that receives documents and prints them when indicated.\n *   The word \"print\" prints an element from the queue, the rest of the words are\n *   interpreted as document names.\n */\n\nclass Printer\n{\n    private $documents;\n    private $position;\n    // Constructor\n    public function __construct()\n    {\n        $this->documents =  [];\n        $this->position = 0;\n    }\n\n    public function add_document($document)\n    {\n        $this->documents[] = $document;\n        $this->position = count($this->documents) - 1;\n    }\n\n    public function print_all()\n    {\n        if (empty($this->documents)) {\n            echo \"Nothing to print. \\n\";\n            return;\n        }\n\n        $print_positioned_docs = array_reverse($this->documents);\n\n        foreach ($print_positioned_docs as $document) {\n            echo \"Printing \" . $document . \".pdf\\n\";\n        }\n        $this->position = 0;\n        $this->documents = [];\n    }\n\n    public function print_current()\n    {\n        if (empty($this->documents)) {\n            echo \"Nothing to print. \\n\";\n            return;\n        }\n\n        $document = $this->documents[$this->position];\n\n        echo \"Printing \" . $document . \".pdf\\n\";\n        unset($this->documents[$this->position]);\n        $this->position = ($this->position > 0) ? $this->position - 1 : 0;\n    }\n\n    public function search_doc($doc_name)\n    {\n        $position =  array_search($doc_name, $this->documents);\n\n        if ($position !== false) {\n            \n            echo \"The document is in position \" . $position + 1 . \".\\n\";\n            return;\n        } else {\n            echo \"No document named: \" . $doc_name . \".pdf \\n\";\n            return;\n        }\n    }\n\n    public function next_document()\n    {\n        if (empty($this->documents)) {\n            echo \"Printer is empty. \\n\";\n            return;\n        }\n\n        if ($this->position < count($this->documents) - 1) {\n            $this->position += 1;\n            echo \"You are in position \" . ($this->position + 1) . \": \" . $this->documents[$this->position] . \".pdf \\n\";\n        } else {\n            echo \" You are already in LAST possition with document \" . $this->documents[$this->position] . \".pdf \\n\";\n            return;\n        }\n    }\n\n    public function back_document()\n    {\n        if (empty($this->documents)) {\n            echo \"Printer is empty. \\n\";\n            return;\n        }\n\n        if ($this->position > 0) {\n            $this->position -= 1;\n            echo \"You are in postition \" . ($this->position + 1) . \": \" .  $this->documents[$this->position] . \".pdf \\n\";\n        } else {\n            echo \" You are already in the FIRST position with document \" . $this->documents[$this->position] . \".pdf \\n\";\n            return;\n        }\n    }\n\n    public function clear_printer()\n    {\n        $this->position = 0;\n        $this->documents = [];\n\n        echo \"Printer queue has been cleared.\";\n    }\n};\n\nfunction printer()\n{\n\n    $printer = new Printer();\n\n    echo \"\\033c\";\n    echo \"\n    ===== PRINTER =====\n     1.- New Document \n     2.- Print All\n     3.- Print Current\n     4.- Search Document\n     5.- Go Forward\n     6.- Go Back\n     7.- Clear Printer\n     8.- Exit\n    ==================\n     \\n\";\n\n    do {\n        $selection = readline(\"Select an option\\n\");\n        switch ($selection) {\n            case 1:\n                add_document($printer);\n                break;\n            case 2:\n                print_documents($printer);\n                break;\n            case 3:\n                print_document($printer);\n                break;\n            case 4:\n                search_document($printer);\n                break;\n            case 5:\n                forward($printer);\n                break;\n            case 6:\n                back($printer);\n                break;\n            case 7:\n                clear_printer($printer);\n                break;\n            case 8:\n                echo \"\\033c\";\n                echo \"Good bye 👋 🌐\\n\";\n                exit;\n            default:\n                echo \"This option doesn't exist.\\n\";\n        }\n    } while (true);\n};\n\nfunction add_document($printer)\n{\n    $name = readline(\"Write the name of the document without extenstion (.pdf only):\\n\");\n    $printer->add_document($name);\n};\n\nfunction print_documents($printer)\n{\n    $printer->print_all();\n};\n\nfunction print_document($printer)\n{\n    $printer->print_current();\n};\n\nfunction search_document($printer)\n{\n    $document_name = readline(\"Write the name of the document without extenstion (.pdf only):\\n\");\n    $printer->search_doc($document_name);\n};\n\nfunction forward($printer)\n{\n    $printer->next_document();\n};\n\nfunction back($printer)\n{\n    $printer->back_document();\n};\n\nfunction clear_printer($printer)\n{\n    $printer->clear_printer();\n};\n\n\nprinter();\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/php/kodenook.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/*\n    Stack\n*/\n\n$letters = ['a', 'b', 'c', 'd'];\n\n// Insert\narray_unshift($letters, 'e');\narray_unshift($letters, 'f');\n\necho var_dump($letters), PHP_EOL;\n\n// Delete\narray_shift($letters);\n\necho var_dump($letters), PHP_EOL;\n\n/*\nQueue\n*/\n\n$letters = ['a', 'b', 'c', 'd'];\n\n// Insert\n\narray_push($letters, 'e', 'f');\n\necho var_dump($letters), PHP_EOL;\n\n// Delete\n\narray_shift($letters);\n\necho var_dump($letters), PHP_EOL;\n\n/*\n    Exercise\n*/\n\n/**\n * The function `webNavigation` allows users to navigate through web URLs by storing and displaying the\n * current and previous URLs in a stack.\n */\nfunction webNavigation()\n{\n    $stack = [];\n    $option = '';\n    while ($option != 'exit') {\n\n        echo 'give a url or next, before, exit', PHP_EOL;\n        $option = readline();\n\n        switch ($option) {\n            case 'next':\n                break;\n            case 'before':\n                array_shift($stack);\n                $web = $stack[count($stack) - 1];\n                echo 'you are in ' . $web, PHP_EOL;\n                break;\n            default:\n                array_unshift($stack, $option);\n                echo 'you are in ' . $option, PHP_EOL;\n                break;\n        }\n    }\n}\n\nwebNavigation();\n\n/**\n * The function `sharedPrint` allows users to add documents to a queue and print them one by one until\n * the user chooses to exit.\n */\nfunction sharedPrint()\n{\n    $queue = [];\n    $option = '';\n\n    while ($option != 'exit') {\n\n        echo 'give a document or print, exit', PHP_EOL;\n        $option = readline();\n\n        switch ($option) {\n            case 'print':\n                $document = array_shift($queue);\n                echo 'you printed ' . $document, PHP_EOL;\n                break;\n            default:\n                array_push($queue, $option);\n                break;\n        }\n    }\n}\n\nsharedPrint();\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/php/marcode24.php",
    "content": "<?php\n\n/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n\nclass Stack {\n    private $items;\n\n    public function __construct() {\n        $this->items = [];\n    }\n\n    public function push($element) {\n        array_push($this->items, $element);\n    }\n\n    public function pop() {\n        if ($this->isEmpty()) {\n            return 'La pila está vacía';\n        }\n        return array_pop($this->items);\n    }\n\n    public function isEmpty() {\n        return empty($this->items);\n    }\n\n    public function peek() {\n        return end($this->items);\n    }\n\n    public function clear() {\n        $this->items = [];\n    }\n\n    public function size() {\n        return count($this->items);\n    }\n}\n\nclass Queue {\n    private $items;\n\n    public function __construct() {\n        $this->items = [];\n    }\n\n    public function enqueue($element) {\n        array_push($this->items, $element);\n    }\n\n    public function dequeue() {\n        if ($this->isEmpty()) {\n            return 'La cola está vacía';\n        }\n        return array_shift($this->items);\n    }\n\n    public function isEmpty() {\n        return empty($this->items);\n    }\n\n    public function size() {\n        return count($this->items);\n    }\n}\n\n$pila = new Stack();\n$pila->push(1);\n$pila->push(2);\n$pila->push(3);\necho $pila->pop() . PHP_EOL; // 3\necho $pila->pop() . PHP_EOL; // 2\n\n$cola = new Queue();\n$cola->enqueue('a');\n$cola->enqueue('b');\n$cola->enqueue('c');\necho $cola->dequeue() . PHP_EOL; // a\necho $cola->dequeue() . PHP_EOL; // b\n\nclass Navegador {\n    private $history;\n    private $future;\n    private $currentPage;\n\n    public function __construct() {\n        $this->history = new Stack();\n        $this->future = new Stack();\n        $this->currentPage = null;\n    }\n\n    // navegar a una nueva página\n    public function goToPage($page) {\n        if ($this->currentPage !== null) {\n            $this->history->push($this->currentPage);\n        }\n        $this->currentPage = $page;\n        $this->future->clear();\n        echo 'Página actual: ' . $this->currentPage . PHP_EOL;\n    }\n\n    // retroceder a la página anterior\n    public function goBack() {\n        if ($this->history->isEmpty()) {\n            echo 'No hay páginas anteriores' . PHP_EOL;\n            return;\n        }\n        $this->future->push($this->currentPage);\n        $this->currentPage = $this->history->pop();\n        echo 'Página actual: ' . $this->currentPage . PHP_EOL;\n    }\n\n    // avanzar a la página siguiente\n    public function goForward() {\n        if ($this->future->isEmpty()) {\n            echo 'No hay páginas siguientes' . PHP_EOL;\n            return;\n        }\n        $this->history->push($this->currentPage);\n        $this->currentPage = $this->future->pop();\n        echo 'Página actual: ' . $this->currentPage . PHP_EOL;\n    }\n}\n\n$navegador = new Navegador();\n$navegador->goToPage('google.com');\n$navegador->goToPage('facebook.com');\n$navegador->goToPage('twitter.com');\n$navegador->goBack(); // regresa a facebook.com\n$navegador->goBack(); // regresa a google.com\n$navegador->goForward(); // avanza a facebook.com\n$navegador->goToPage('instagram.com'); // instagram.com\n$navegador->goBack(); // regresa a facebook.com\n$navegador->goForward(); // avanza a instagram.com\n\n\n// Visita mi repo en GitHub para ver y correr los tests de este código --> https://github.com/marcode24/weekly-challenges\n\n?>"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/php/miguelex.php",
    "content": "<?php\n\n// La implementacion la vamos a hacer con array y usando POO\nclass Cola {\n    private $cola = array();\n    private $inicio = 0;\n    private $fin = 0;\n    private $max = 10; // Esto es opcional para limitar el tamaño de la cola. Se puede omitir refactorizando el código. alli donde haga falta\n\n    public function encolar($elemento) {\n        if ($this->fin < $this->max) {\n            $this->cola[$this->fin] = $elemento;\n            $this->fin++;\n        } else {\n            echo \"La cola está llena\";\n        }\n    }\n\n    public function desencolar() {\n        if ($this->inicio < $this->fin) {\n            $elemento = $this->cola[$this->inicio];\n            unset($this->cola[$this->inicio]);\n            $this->inicio++;\n            return $elemento;\n        } else {\n            echo \"La cola está vacía\\n\";\n        }\n    }\n\n    public function mostrar() {\n        if ($this->inicio == $this->fin) {\n            echo \"La cola está vacía\\n\";\n            \n        } else {\n            for ($i = $this->inicio; $i < $this->fin; $i++) {\n                echo $this->cola[$i] . \" \";\n            }\n        }        \n    }\n}\n\nclass Pila {\n    private $pila = array();\n    private $tope = 0;\n    private $max = 7; // Esto es opcional para limitar el tamaño de la pila. Se puede omitir refactorizando el código. alli donde haga falta\n\n    public function getTope(){\n        // Esta es una función creada expresamente para el ejercicio extra. No seria necesaria para el funcionamiento de la pila\n        return $this->tope;\n    }\n\n    public function apilar($elemento) {\n        if ($this->tope < $this->max) {\n            $this->pila[$this->tope] = $elemento;\n            $this->tope++;\n        } else {\n            echo \"La pila está llena\\n\";\n        }\n    }\n\n    public function desapilar() {\n        if ($this->tope > 0) {\n            $this->tope--;\n            $elemento = $this->pila[$this->tope];\n            unset($this->pila[$this->tope]);\n            return $elemento;\n        } else {\n            echo \"La pila está vacía\\n\";\n        }\n    }\n\n    public function mostrar() {\n        if ($this->tope == 0) {\n            echo \"La pila está vacía\\n\";\n        } else {\n            for ($i = $this->tope - 1; $i >= 0; $i--) {\n                echo $this->pila[$i] . \" \";\n            }\n        }        \n    }\n\n    public function getPosition($i){\n        // Esta es una función creada expresamente para el ejercicio extra. No seria necesaria para el funcionamiento de la pila\n        return $this->pila[$i];\n    }\n}\n\n$cola = new Cola();\n$pila = new Pila();\n\necho \"Vamos a trabajar con la cola\\n\";\necho \"Vamos a mostrar el contenido de la cola al inicio de la misma: \\n\";\n$cola->mostrar();\necho \"\\n\";\n\necho \"Vamos a encolar 3 elementos: 1, 2 y 3\\n\";\n$cola->encolar(1);\n$cola->encolar(2);\n$cola->encolar(3);\n\necho \"Vamos a mostrar el contenido de la cola después de encolar 3 elementos: \\n\";\n$cola->mostrar();\necho \"\\n\";\n\necho \"Vamos a desencolar un elemento\\n\";\n$cola->desencolar();\n\necho \"Vamos a mostrar el contenido de la cola después de desencolar un elemento: \\n\";\n$cola->mostrar();\necho \"\\n\";\n\necho \"Vamos a encolar 2 elementos: 4 y 5 y vamos a desencolar dos\\n\";\n$cola->encolar(4);\n$cola->encolar(5);\n$cola->desencolar();\n$cola->desencolar();\n\necho \"Vamos a mostrar el contenido de la cola después de encolar 2 elementos y desencolar dos: \\n\";\n$cola->mostrar();\necho \"\\n\";\n\necho \"Por ultimo, vamos a desencolar tres elemento (recuerda que realemnte solo nos quedan 2 dentro de la cola)\\n\";\n$cola->desencolar();\n$cola->desencolar();\n$cola->desencolar();\n\necho \"Vamos a mostrar el contenido de la cola después de desencolar tres elementos: \\n\";\n$cola->mostrar();\necho \"\\n\";\n\necho \"Ahora, vamos a trabajar con la pila\\n\";\n\necho \"Vamos a mostrar el contenido de la pila al inicio de la misma: \\n\";\n\n$pila->mostrar();\necho \"\\n\";\n\necho \"Vamos a apilar 3 elementos: 1, 2 y 3\\n\";\n\n$pila->apilar(1);\n$pila->apilar(2);\n$pila->apilar(3);\n\necho \"Vamos a mostrar el contenido de la pila después de apilar 3 elementos: \\n\";\n$pila->mostrar();\necho \"\\n\";\n\necho \"Vamos a desapilar un elemento\\n\";\n$pila->desapilar();\n\necho \"Vamos a mostrar el contenido de la pila después de desapilar un elemento: \\n\";\n$pila->mostrar();\necho \"\\n\";\n\necho \"Vamos a apilar 2 elementos: 4 y 5 y vamos a desapilar dos\\n\";\n\n$pila->apilar(4);\n$pila->apilar(5);\n\n$pila->desapilar();\n$pila->desapilar();\n\necho \"Vamos a mostrar el contenido de la pila después de apilar 2 elementos y desapilar dos: \\n\";\n\n$pila->mostrar();\necho \"\\n\";\n\necho \"Por ultimo, vamos a desapilar tres elemento (recuerda que realemnte solo nos quedan 2 dentro de la pila)\\n\";\n\n$pila->desapilar();\n$pila->desapilar();\n$pila->desapilar();\n\necho \"Vamos a mostrar el contenido de la pila después de desapilar tres elementos: \\n\";\n$pila->mostrar();\necho \"\\n\";\n\necho \"Vamos a simular el mecanismo adelante/atrás de un navegador web\\n\";\n\n$pila = new Pila();\n\n$ultimoIndexVisitado = -1; \n\ndo {\n    $cabeza = $pila->getTope() - 1;\n\n    echo \"Escribe el nombre de la web, adelante, atras o exit: \";\n    $entrada = trim(fgets(STDIN));\n    if ($entrada == \"adelante\") {\n        if ($ultimoIndexVisitado < $cabeza) { \n            $ultimoIndexVisitado++;\n            echo \"Navegando adelante a la web: \". $pila->getPosition($ultimoIndexVisitado). \"\\n\";\n        } else {\n            echo \"No hay más webs para navegar adelante\\n\";\n        }\n    } elseif ($entrada == \"atras\") {\n        if ($ultimoIndexVisitado > 0) { \n            $ultimoIndexVisitado--;\n            echo \"Navegando atrás a la web:\". $pila->getPosition($ultimoIndexVisitado). \"\\n\";            \n        } else {\n            echo \"No hay más webs para navegar atrás\\n\";\n        }\n    } elseif ($entrada != \"exit\") {\n        $pila->apilar($entrada);\n        $ultimoIndexVisitado = $pila->getTope() - 1; \n        echo \"Estas en la web: $entrada\\n\";\n    }\n} while ($entrada != \"exit\");\n\necho \"Vamos a simular el mecanismo de una cola de impresion\\n\";\n\n$cola = new Cola();\n\ndo {\n    echo \"Escribe el nombre del documento, imprimir o exit: \";\n    $entrada = trim(fgets(STDIN));\n    if ($entrada == \"imprimir\") {\n        $documento = $cola->desencolar();\n        if ($documento != null) {\n            echo \"Imprimiendo documento: $documento\\n\";\n        } else {\n            echo \"No hay documentos para imprimir\\n\";\n        }\n    } elseif ($entrada != \"exit\") {\n        $cola->encolar($entrada);\n        echo \"Documento encolado: $entrada\\n\";\n    }\n} while ($entrada != \"exit\");\n\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/php/qv1ko.php",
    "content": "<?php\n\n    $stack = new SplStack();\n\n    $stack->push(1);\n    $stack->push(2);\n    $stack->push(3);\n\n    echo \"Stack: \";\n\n    $stack->rewind();\n    while($stack->valid()) {\n        echo $stack->current();\n        $stack->next();\n    }\n\n    $queue= new SplQueue();\n\n    $queue->enqueue(1);\n    $queue->enqueue(2);\n    $queue->enqueue(3);\n\n    echo \"\\nQueue: \";\n\n    $queue->rewind();\n    while($queue->valid()) {\n        echo $queue->current();\n        $queue->next();\n    }\n\n?>\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/59822.py",
    "content": "'''Creación de pilas y colas'''\n# PILAS /STACKS\n\n# Pilas son estructuras de datos que siguen el principio LIFO \n# (Last In, First Out), es decir, el último elemento en entrar es el\n# primero en salir. \n\npila = [1, 2, 3, 4, 5]\npila.append(6)\npila.append(7)\nprint('Pila original: ', pila)\n\n# Eliminar el último elemento agregado a la pila\npila_elemento = pila[len(pila) - 1]\n# len(pila) - 1 es el índice del último elemento en la pila\ndel pila[len(pila) - 1] # Elimina el último elemento de la pila\nprint(pila_elemento) # Imprime el último elemento eliminado\nprint(pila)# Imprime la pila actualizada sin el último elemento\n\nprint(pila.pop()) # Elimina el último elemento de la pila y lo imprime\nprint(pila) # Imprime la pila actualizada sin el último elemento\n\n\n\n# COLAS / QUEUES\nqueue = [2, 4, 6, 8, 10]\n\n#Añadir\nqueue.append(12)\nqueue.append(14)\nqueue.append(16)\n\nprint('Cola original: ', queue)\n\n# Eliminar el primer elemento agregado a la cola\n# Dequeue\n\nqueue_elemento = queue[0]\ndel queue[0]\nprint(queue_elemento)\n\nprint(queue.pop(0))\nprint(queue)\n\n# Las pilas sirven para almacenar elementos en un orden específico y\n# las colas para almacenar elementos en un orden específico.\n# Las pilas siguen el principio LIFO y las colas el principio FIFO\n\n\n# DIFICULTAD EXTRA\ndef navegar():\n    total = []\n    \n    while True:\n        action =input(\"Selecciona una opción:\\n1. Agregar nueva url\\n2. Adelante\\n3. Atrás\\n4. Salir\\n\")\n        \n        match action:\n            case \"1\": \n                url =input(input(\"Ingresar la url: \"))\n                total.append(url)\n            case \"2\":\n                print(\"Adelante\")\n            case \"3\":\n                print(\"Atrás\")\n                del total[len(total) -1]\n            case \"4\":\n                break\n            case _:\n                print(\"Opción no válida\")\n        \n        if (len(total) > 0):\n            print(f\"Has navegado a la web: {total[len(total) -1]}.\")\n        \n        else: \n            print(\"No hay nada\")\n\ndef impresion():\n    total = []\n    while True:\n        action = input(\"Selecciona una opción:\\n1. Agregar documento\\n2. Imprimir\\n3. Salir\\n\")\n        \n        match action:\n            case \"1\":\n                documento = input(\"Ingresar el documento: \")\n                total.append(documento)\n            case \"2\":\n                if len(total) > 0:\n                    print(f\"Imprimiendo {total[0]}\")\n                    del total[0]\n                else:\n                    print(\"No hay documentos\")\n                print(\"\")\n            case \"3\":\n                break\n            case _:\n                print(\"Opción no válida\")\n            \n                "
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/AChapeton.py",
    "content": "# Pilas\npila = [1, 2, 3, 4, 5]\n\n# Agregar elementos a una pila\npila.append(6)\npila.append(7)\n\nprint('Pila orignial: ', pila)\n\n# Eliminar el ultimo elemento agregado a la pila\npila.pop()\nprint('Pila nueva: ', pila)\n\n\n# Colas\ncola = [2, 4, 6, 8, 10]\n\ncola.append(12)\ncola.append(14)\n\nprint('Cola original: ', cola)\n\n# Eliminar el primer elemento agregado a la cola\ncola.pop(0)\n\nprint('Cola nueva: ', cola)\n\n\n# DIFICULTAD EXTRA\n\ndef navegador():\n  \n  history = []\n\n  while True:\n    print(\n      \"\"\"\n            AGENDA:\n            1. Agregar nueva url\n            2. Adelante\n            3. Atras\n            4. Salir\n      \"\"\"\n    )\n    option = input('\\nEscoger del menu: ')\n\n    match option:\n      case \"1\":\n        print('Agregar nueva url')\n        name = input('Agregar nueva url para navegar: ')\n        history.append(name)\n      case \"2\":\n        print('Adelante')\n        pass\n      case \"3\":\n        print('Atras')\n        if(len(history) > 0):\n          history.pop()\n      case \"4\":\n        print('Saliendo...')\n        break\n      case _:\n        print('Opcion no valida. Intentar de nuevo.')\n      \n    if(len(history) > 0):\n      print('Has navegado a la web: ', history[len(history) - 1])\n    else:\n      print('No hay nuevas urls')\n    \n\n# navegador()\n\n\ndef impresora():\n  cola = []\n\n  while True:\n    print(\n      \"\"\"\n            AGENDA:\n            1. Agregar nuevo documento a la impresora\n            2. Imprimir\n            3. Salir\n      \"\"\"\n    )\n    option = input('\\nEscoger del menu: ')\n\n    match option:\n      case \"1\":\n        print('Agregar nuevo documento a la impresora')\n        name = input('Nombre del documento: ')\n        cola.append(name)\n\n        if(len(cola) > 0):\n          print('Cola de impresion: ', cola)\n      case \"2\":\n        print('Imprimir')\n        if(len(cola) > 0):\n          print(\"Imprimiendo documento: \", cola.pop(0))\n        else:\n          print(\"No hay documentos en cola.\")\n      case \"3\":\n        print('Saliendo...')\n        break\n      case _:\n        print('Opcion no valida. Intentar de nuevo.')\n\nimpresora()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/AbelPerezCollado.py",
    "content": "# Pilas\npila = [1, 2, 3, 4, 5]\n\n# Agregar elementos a una pila\npila.append(6)\npila.append(7)\n\nprint('Pila orignial: ', pila)\n\n# Eliminar el ultimo elemento agregado a la pila\npila.pop()\nprint('Pila nueva: ', pila)\n\n\n# Colas\ncola = [2, 4, 6, 8, 10]\n\ncola.append(12)\ncola.append(14)\n\nprint('Cola original: ', cola)\n\n# Eliminar el primer elemento agregado a la cola\ncola.pop(0)\n\nprint('Cola nueva: ', cola)\n\n# DIFICULTAD EXTRA\n\npaginas = ['wwww.musica.com','wwww.musica.com/artistas','wwww.musica.com/canciones','wwww.musica.com/downloads']\nindice = 0\nprint(f'La pagina web actual es: {paginas[indice]}')\nwhile True:\n    \n    \n    opcion = input(\"Seleccione la opción deseada: \")\n\n    if opcion == '1' and indice < len(paginas) - 1:\n        indice += 1\n        \n    elif opcion == '2' and indice > -1 * len(paginas):\n        indice -= 1\n        \n    if opcion == '3':\n        print('ADIOS!')\n        break\n    print(f'Indice: {indice}')\n    print(paginas[indice])\n\n#IMPRESORA\n\ndocumentos = ['Documento1',]\nwhile True:\n    print('MENU')\n    print('1.- Imprimir')\n    print('2.- Nuevo documento')\n    print('3.- Salir')\n    opcion = input('Seleccione la opcion deseada: ')\n    if opcion == '1' and len(documentos) > 0:\n        print(f'{documentos.pop(0)}...Imprimiendo')\n    elif opcion == '2':\n        documentos.append(input('Nombre documento: '))\n    elif opcion == '3':\n        print('Adios!')\n        break\n    else:\n        print('Opción incorrecta')"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/AlainMartz.py",
    "content": "# #07 PILAS Y COLAS\n\n# EJERCICIO:\n# Implementa los mecanismos de introducción y recuperación de elementos propios de las\n# pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n# o lista (dependiendo de las posibilidades de tu lenguaje).\n\n\"\"\"\nLIFO: Last in, first out\nDescribe el orden en que los elementos procesados o eliminados de una estructura de datos.\nComo una pila, el último elemento que se coloca es el primero en ser retirado\nHay dos métodos que se utilizan para interactuar con estos elementos:\n- push / en python append(valor) (ingresa un elemento al final de la cola)\n- pop() (retira el último elemento y devuelve su valor)\n- se pueden manejar con listas o arrays\n\"\"\"\nprint(\"LIFO\")\npila = ['alpha','beta','gamma','delta','epsilon','zeta','eta','teta']\nprint(f\"Lista inicial:\\n{pila}\")\npila.append('iota')\nprint(f\"Método push, se inserta un último elemento:\\n{pila}\")\nprint(f\"Método pop, se retira el último elemento (.pop()) y devuelve su valor:\\n{pila.pop()}\\n\")\n\n\n\"\"\"\nFIFO: Last in, first out\nDescribe el orden en que los elementos procesados o eliminados de una estructura de datos.\nSe refiere a una cola, como una cola de clientes, el primero en entrar es el primero en salir\nHay dos métodos que se utilizan para interactuar con estos elementos:\n- push / en python append(valor) (ingresa un elemento al final de la cola)\n- pop(0) (retira el primer elemento y devuelve su valor)\n- se pueden manejar con listas o arrays\n\"\"\"\nprint(\"FIFO\")\npila = ['α','β','γ','δ','ε','ζ','η','θ']\nprint(f\"Lista inicial:\\n{pila}\")\npila.append('ι')\nprint(f\"Método append(valor), se inserta un último elemento:\\n{pila}\")\nprint(f\"Método pop(0), se retira el primer elemento y devuelve su valor:\\n{pila.pop(0)}\\n\")\n\n#### FIFO y LIFO con arrays\nimport array\n\narreglo = array.array('i', [1, 2, 3, 4, 5, 6, 7, 8])\nprint(f\"Arreglo (array) inicial:\\n{arreglo}\")\n\narreglo.append(9)\nprint(f\"Arreglo con método append():\\n{arreglo}\\n\")\n\n# LIFO: Elimina el último elemento\nprint(f\"LIFO con método pop():\\n{arreglo.pop()}\")\nprint(f\"Arreglo después del LIFO:\\n{arreglo}\\n\")\n\narreglo.append(9)\n\n# FIFO: Elimina el primer elemento\nprint(f\"FIFO con método pop(0):\\n{arreglo.pop(0)}\")\nprint(f\"Arreglo después del FIFO:\\n{arreglo}\")\n\n### Con la libreria queue\n\nimport queue\n\npila = queue.LifoQueue(3)\ncola = queue.Queue(3)\n\npila.put(4)\npila.put(5)\npila.put(6)\ncola.put(7)\ncola.put(8)\ncola.put(9)\n\nprint(\"Cola FIFO\")\nprint(cola.get())\nprint(cola.get())\nprint(cola.get())\nprint(\"\\nCola LIFO\")\nprint(pila.get())\nprint(pila.get())\nprint(pila.get())\n\n\n###################\n\"\"\" \n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n \"\"\"\n\n#### NAVEGADOR\n\nhist_back = []\nhist_ford = []\n\ndef navegar():\n    x = input(\"Qué sitio desea visitar?\")\n    hist_back.append(x)\n    hist_ford.clear()\n    print(f\"Visitaste {x}!!\")\n\n\ndef avanzar():\n    if hist_ford: # Verifica que la lista no esté vacía    \n        y = hist_ford.pop()\n        hist_back.append(y)\n        print(f\"Avanzaste a {y}!!\")\n    else:\n        print(\"No hay páginas a las que avanzar x_x\")\n\ndef retroceder():\n    if hist_back:\n        if len(hist_back) == 1:\n            z = hist_back.pop()\n            hist_ford.append(z)\n            print(\"Estás en la página de inicio, no hay hacia dónde retroceder :/\")\n        else:\n            z = hist_back.pop()\n            hist_ford.append(z)\n            print(f\"Retrocediste a {hist_back[-1]}!!\")\n    else:\n        print(\"No hay páginas a las que retroceder :(\")\n\ndef historial():\n    if hist_back:\n        print(\"Historial:\")\n        for j,k in zip(hist_back,range(len(hist_back))):\n            print(f\"{k+1}. {j}\")\n    else:\n        print(f\"El historial está vacío\")    \n\n\ndef browser():\n\n    # Bucle que permite navegar continuamente\n    while True:\n        i = input(\"\"\"\nHa ingresado Shin Navi, qué acción desea realizar:\n            1. Nueva página\n            2. Avanzar\n            3. Retroceder\n            4. Historial              \n            5. Salir                                          \n\"\"\")\n        if i == \"1\":\n            navegar()\n        elif i == \"2\":\n            avanzar()\n        elif i == \"3\":\n            retroceder()\n        elif i == \"4\":\n            historial()\n        elif i == \"5\":\n            print(\"Saliendo del navegador! Bye!\")\n            break\n        else:\n            print(\"Opción no válida. Inténtelo nuevamente c:\")\n\n# browser()        \n\n\n#### Impresoras\n\"\"\"\n- Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n\"\"\"\nclass shared_printer:\n    def __init__(self):\n        self.cola = []\n\n    def imprimir(self):\n        if self.cola:\n            printed = self.cola.pop(0)\n            print(f\"Ha impreso: {printed}\")\n        else:\n            print(\"La cola de impresión está vacia\")\n\n    def cola_impresion(self):\n        if self.cola:\n            for i,j in zip(self.cola,range(len(self.cola))):\n                print(f\"{j+1}. {i}\")\n        else:\n            print(\"La cola de impresión está vacia\")   \n\n    def agregar_documento(self, opcion):\n        self.cola.append(opcion)\n        print(f\"Ha añadido {opcion} a la cola de impresión\")\n\n    def run(self):\n        while True:\n            opcion = input(\n\"\"\"\nSi desea imprimir, escriba: imprimir.\nSi desea revisar la cola de impresión escriba: cola\nDe otra forma, ingrese el nombre de su documento.\nSi desea salir, escriba: salir\n\n\"\"\")            \n            if len(self.cola) <= 3:\n\n                if opcion.lower() == \"imprimir\":\n                    self.imprimir()\n                elif opcion.lower() == \"cola\":\n                    self.cola_impresion()\n                elif opcion.lower() == \"salir\":\n                    print(\"Ha salido de la impresora\")\n                    break\n                elif opcion == \"\":\n                    print(\"No ha ingresado ningún valor\")\n                else:\n                    self.agregar_documento(opcion)\n            else:\n                x = input(\n\"\"\"\nLa cola está llena, debe imprimir un documento antes de continuar\nEscriba imprimir para imprimir\nEscriba cola para revisar la cola\nEscriba salir para salir\n\"\"\")\n                if x.lower() == \"imprimir\":\n                    self.imprimir()\n                elif x.lower() == \"cola\":\n                    self.cola_impresion()\n                elif x.lower() == \"salir\":\n                    print(\"Ha salido de la impresora\")\n                    break\n                else:\n                    print(\"Escoja alguna de las opciones anteriores\")\n\nimpresora = shared_printer()\nimpresora.run()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/Aldroide.py",
    "content": "\"\"\"\n    Una pila se puede inplementar en python utilizando una lista como estructura\n    de datos base. Las operaciones de apilar y desapilar se pueden realizar utilizando\n    los metodos append() y pop de la lista\n\"\"\"\n\npila = []\n\n\ndef apilar(elemento):\n    pila.append(elemento)\n\n\ndef desapilar():\n    return pila.pop()\n\n\ndef esta_vacia():\n    return len(pila) == 0\n\n\ndef tamanio():\n    return len(pila)\n\n\napilar(1)\napilar(2)\napilar(3)\n\nprint(desapilar())  # 3\nprint(desapilar())  # 2\nprint(desapilar())  # 1\n\n\n\"\"\"\nColas\n\"\"\"\ncola = []\n\n\ndef agregar(elemento):\n    cola.append(elemento)\n\n\ndef quitar():\n    return cola.pop(0)\n\n\ndef empty():\n    return len(cola) == 0\n\n\ndef lenght():\n    return len(cola)\n\n\nagregar(1)\nagregar(2)\nagregar(3)\n\nprint(quitar())  # 1\nprint(quitar())  # 2\nprint(quitar())  # 3\n\n\n# Dificultad extra: Implementar pilas y cadenas de texto y simular navegar entre webs\npila = ['www.spider.com', 'www.wolverine.es', 'www.flash.mx']\n\n\ndef w_new(elemento):\n    global pila\n    pila.append(elemento)\n    return str(elemento)\n\n\ndef atras():\n    global pila\n    aux = pila.pop()\n    if len(pila) > 0:\n        pila.insert(0, aux)\n        return pila[-1]\n    else:\n        return \"No existe web\"\n\n\ndef siguiente():\n    global pila\n    if len(pila) > 0:\n        aux = pila.pop(0)\n        pila.append(aux)\n        actual = pila[-1]\n        return actual\n    else:\n        return \"No hay web\"\n\n\ndef navegar(direccion):\n    global pila\n    if direccion.lower() == \"adelante\":\n        print(f\"Estas navegando en: {siguiente()}\")\n    elif direccion.lower() == \"atras\":\n        print(f\"Estas navegando en: {atras()}\")\n    elif (direccion.startswith('www.')):\n        # Se agrega la nueva página a la pila y se muestra\n        pila.append(direccion)\n        print(f\"Mostrando página: {direccion}\")\n    else:\n        print(\"Web invalida\")\n\n\n# Bucle principal de navegación\nwhile True:\n\n    direccion = input(\n        \"Introduce una dirección web ('salir' o 'adelante' o 'atras'): \")\n    if direccion.lower() == 'salir':\n        break\n    navegar(direccion)\n\n\"\"\"\n    Utilizando colas y cadenas de texto, simular el mecanismo de impresora\n\"\"\"\n\ncola = ['Doc1', 'Doc2', 'Doc3', 'Doc4']\n\n\ndef imprimir():\n    global cola\n    print(f\"El documento que se imprime es: {cola.pop(0)}\")\n\n\ndef nuevo(doc):\n    cola.append(doc)\n    return doc\n\n\ndef imprime(doc):\n    global pila\n    if doc.lower() == \"imprimir\":\n        imprimir()\n    else:\n        print(f\"Añadir documento: {nuevo(doc)}\")\n\n\nwhile True:\n    print(\"Documentos a imprimir: \")\n    for docs in cola:\n        print(docs)\n    doc = input(\"Introduce si quieres imprimir o añadir documento o salir: \")\n    if doc.lower() == 'salir':\n        break\n    imprime(doc)\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/Aleran07.py",
    "content": "# 07\n\n# stacks - LIFO\npila = []\npila.append(1)\npila.append(2)\npila.append(3)\nprint(pila)   # [1, 2, 3]\n\npila.pop()    # saca el 3\nprint(pila)   # [1, 2]\n\npila.pop()    # saca el 2\nprint(pila)   # [1]\n\npila.pop()    # saca el 1\nprint(pila)   # []\n\n# queue - FIFO\n\ncola = []\ncola.append('A')\ncola.append('B')\ncola.append('C')\nprint(cola)  # ['A', 'B', 'C']\n\n# Quitar del principio\nprimero = cola.pop(0)\nprint(primero)  # 'A'\nprint(cola)     # ['B', 'C']\n\n\"\"\"- Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\"\"\"\n\ndef navegador():\n    lista_webs = [\"Google\", \"Youtube\", \"Facebook\", \"Pinterest\" ]\n    posicion = 0\n    opciones = [1, 2, 3, 4]\n    # Mensaje de inicio\n    print(f\"\\nEstas en la pagina {lista_webs[posicion]}\\n\")\n\n    def opcion_1():\n        nonlocal posicion\n        posicion += 1\n        try:\n            print(f\"\\nAvanzate a la pagina {lista_webs[posicion]}\")\n            pantalla()\n        except IndexError:\n            print(\"Índice fuera del rango, no hay mas elementos adelante.\")\n            pantalla()\n        \n    def opcion_2():\n        nonlocal posicion\n        posicion -= 1\n        print(f\"\\nRetrocediste a la pagina {lista_webs[posicion]}\")\n        pantalla()\n\n    def opcion_3():\n        nonlocal posicion\n        nueva_web = input(\"\\nEscribe el nombre de la web: \")\n        lista_webs.append(nueva_web)\n\n        posicion = len(lista_webs) - 1\n        print(f\"\\nAhora te encuentras en la pagina {lista_webs[posicion]}\")\n\n        pantalla()\n    \n    def opcion_4():\n        print(\"Saliendo del programa...\")\n        exit()\n         \n    acciones = {\n    1: opcion_1,\n    2: opcion_2,\n    3: opcion_3,\n    4: opcion_4,\n    }\n    def pantalla():\n            while True:\n                try:\n                    x = int(input(\"\\nElige la accion deseas realizar para cambiar de pagina:\\\n                            \\n1. Adelante\\n\" \\\n                            \"2. Atras\\n3. Nombre de la Pagina que deseas digirirte\\n4. Salir\\n\" \\\n                            \"Indique una opción: \"))\n                    if x in opciones:\n                        accion = acciones.get(x, lambda: print(\"Opción no válida\"))\n                        accion()\n                        break\n                    else:\n                        print(\"\\nBoludo es del 1 al 4\\n\")\n                except ValueError:\n                    print(\"\\nSolo se permiten numeros\\n\")\n\n    pantalla()\n\nnavegador()\n\n\"\"\"* - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\"\"\"\n\ndef impresora():\n    lista_webs = []\n    posicion = 0\n    opciones = [\"imprimir\", \"salir\"]\n    \n    def opcion_1():\n        nonlocal posicion\n        print(f\"\\nImprimiendo archivo: {lista_webs[posicion]}\")\n        lista_webs.pop(0)\n        pantalla()\n    \n    def opcion_2():\n        print(\"\\nSaliendo del programa...\\n\")\n        exit()\n\n    def opcion_3(word):\n        lista_webs.append(word)\n        print(f\"\\nArchivo agregado a la cola {word}\")\n        pantalla()\n\n    acciones = {\n    \"imprimir\": opcion_1,\n    \"salir\": opcion_2,\n    \"document\": opcion_3,\n    }\n    def pantalla():\n            while True:\n                try:\n                    x = input(\"\\nEscribe la palabra 'imprimir' si deseas imprimir de lo contrario se tomara como documento: \\nEscribe salir para terminar el programa: \")\n                    minimizar = x.lower()\n                    if minimizar in opciones:\n                        accion = acciones.get(minimizar, lambda: print(\"Opción no válida 1\"))\n                        accion()\n                        break\n                    else:\n                        accion = acciones.get(\"document\", lambda: print(\"Opción no válida\"))\n                        accion(minimizar)\n                        break\n                except ValueError:\n                    print(\"\\nSolo se permite texto\\n\")\n\n    pantalla()\n\nimpresora()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/AllanYSalazarG.py",
    "content": "\"\"\" #07 PILAS Y COLAS \"\"\"\n\nfrom collections import deque\nfrom queue import Queue\n\n\n# ------------- PILAS -------------\n\n# Sin collections deque\n\npila = []\n# Con append agregamos un elemento a la lista (PUSH)\npila.append(\"hola\")\n# con pop, eliminamos el ultimo elemento y este lo retorna (POP)\npila.pop()\n# print(pila)\npila.append(\"hola\")\n# print(pila)\npila.append(\"mundo\")\n# print(pila)\npila.pop()\n# print(pila)\n\n# Con collections deque (recomendado)\n\npila = deque()\npila.append(\"Hola\")\npila.append(\"como\")\npila.append(\"estás\")\n# print(pila)\npila.pop()\n# print(pila)\n\n# ------------- COLAS -------------\n\n# con collections deque\n\ncola = deque()\ncola.append(\"hola\")\ncola.append(\"mundo\")\ncola.append(\"como\")\ncola.append(\"estas\")\n# print(cola)\ncola.popleft()\n# print(cola)\n\n# con queue Queue\n\n# Agregar a la cola\ncola = Queue()\ncola.put(\"hola\")\ncola.put(\"como\")\ncola.put(\"estas\")\n# Quitar de la cola\n# print(cola.get())\n\n\n# ------------- EJERCICIO -------------\n\ndef acrossTheWeb():\n    \"\"\" Funcion que muestra la ultima página en la que estamos\n     al escribir adelante, quita esa ultima al escribir atras y\n      agrega una nueva pagina al escribir cualquier otra cosa\n\n        Ambos casos adelanta o atras, nos imprimie el ultimo\n         valor o el que sigue \"\"\"\n    stack = deque([\"home\"])\n    while True:\n        command = str(input(\"Quieres ir adelante o atrás: \"))\n        if command.lower() == \"adelante\":\n            print(stack[-1])\n        elif command.lower() == \"atras\":\n            stack.pop()\n            if not stack:\n                break\n            print(stack[-1])\n        else:\n            stack.append(command)\n\n\nacrossTheWeb()\n\n\ndef printingDocuments():\n    \"\"\" Funcion que imprime un documento al escribir imprimir\n     de lo contrario, lo que escribamos lo agrega como un nuevo\n      documento a imprimir \"\"\"\n    docList = [\"documento\"]\n    while True:\n        # Mostramos el documento a imprimir\n        print(f\"Documento siguiente: {docList[0]}\")\n        command = str(input(\"$ \"))\n        if command.lower() == \"imprimir\":\n            print(f\"Documento impreso: {docList.pop(0)}\")\n            print(docList)\n        else:\n            print(f\"Documento agregado a la cola: {command}\")\n            docList.append(command)\n            print(docList)\n        if not docList:\n            break\n    print(\"Sin documentos, adios.\")\n\n\n# printingDocuments()\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/Alvaro-Neyra.py",
    "content": "#  * EJERCICIO:\n#  * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n#  * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n#  * o lista (dependiendo de las posibilidades de tu lenguaje).\n\n# Pilas (Stack):\nclass Pila:\n    \"\"\"Representa una pila con operaciones de apilar, desapilar y verificar. Usamos una lista. Esta estructura de datos es de comportamiento LIFO (Last In First Out). Esto quiere decir que el ultimo en ser anadido a la lista es el primero en salir.\"\"\"\n    def __init__(self):\n        self.items = []\n    def ver(self):\n        return self.items\n    def apilar(self, valor):\n        self.items.append(valor)\n    def desapilar(self):\n        try:\n            return self.items.pop()\n        except IndexError:\n            raise ValueError(\"La pila esta vacia\")\n    def es_vacia(self):\n            return self.items == []\n    \n\n# Colas (Queue):\nclass Cola:\n    \"\"\"Representa una cola con operaciones de apilcar, desapilar, y verificar. Usamos una lista. Esta estructura de datos es de comportamiento FIFO (First In First Out). Esto quiere decir que el ultimo en ser anadido va a ser el primero en irse.\"\"\"\n    def __init__(self):\n        self.items = []\n    def ver(self):\n        return self.items\n    def anadir_a_la_cola(self, valor):\n        # Anadiendo el valor al inicio de la lista y moviendo los demas elementos a un indice mas.\n        self.items.insert(0, valor)\n    def sacar_de_la_cola(self):\n        try:\n            return self.items.pop()\n        except IndexError:\n            raise ValueError(\"La cola esta vacia\")\n    def es_vacia(self):\n        return self.items == []\n    \n# Usando las pilas y colas:\n    \n# Generando una pila\npila1 = Pila()\nprint(f\"Generando una pila:\")\nprint(pila1.ver())\n# Anadiendo elementos:\nprint(f\"Anadiendo elementos...\")\npila1.apilar(\"Primer Elemento\")\npila1.apilar(\"Segundo Elemento\")\npila1.apilar(3)\npila1.apilar(400)\nprint(pila1.ver())\n# Sacar el ultimo elemento de la estructura\nprint(f\"Sacando el ultimo elemento de la estructura\")\nultimo_valor = pila1.desapilar()\nprint(pila1.ver())\nprint(f\"Este era el ultimo elemento de la pila: {ultimo_valor}\")\n# Verificando si esta vacia:\nprint(f\"Verificando si la pila esta vacia: {pila1.es_vacia()}\")\n\n# Generando una cola\ncola1 = Cola()\nprint(f\"Generando una cola:\")\nprint(cola1.ver())\n# Anadiendo elementos a la cola:\nprint(f\"Anadiendo elementos a la cola:\")\ncola1.anadir_a_la_cola(\"Primer Elemento\")\ncola1.anadir_a_la_cola(\"Segundo Elemento\")\ncola1.anadir_a_la_cola(3)\ncola1.anadir_a_la_cola(400)\nprint(cola1.ver())\n# Sacar al primer elemento de la cola:\nprint(f\"Sacando al primer elemento de la estructura\")\nultimo_valor_de_la_cola = cola1.sacar_de_la_cola()\nprint(cola1.ver())\nprint(f\"Este era el ultimo elemento de la cola: {ultimo_valor_de_la_cola}\")\n# Verificando si la cola esta vacia:\nprint(f\"Verficando si la cola esta vacia: {cola1.es_vacia()}\")\n\n#  * DIFICULTAD EXTRA (opcional):\n\n# - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n#  *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n#  *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n#  *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n#  *   el nombre de una nueva web.\n\nclass Navegador:\n    def __init__(self):\n        self.items = []\n        self.indice_actual = - 1\n    def historial(self):\n        return self.items\n    def anadir_pagina(self, url):\n        if isinstance(url, str):\n            self.items.append(url)\n        else:\n            print(\"Solo se permiten anadir URLs\")\n    def avanzar(self):\n        if self.indice_actual < len(self.items) - 1 and self.indice_actual != -1:\n            pagina = self.items[self.indice_actual + 1]\n            self.indice_actual =+ self.items.index(pagina)\n            print(f\"Pagina Actual: {pagina}\")\n        else:\n            print(\"No hay mas paginas para avanzar\")\n    def retroceder(self):\n        if self.indice_actual != 0:\n            pagina = self.items[self.indice_actual - 1]\n            self.indice_actual = self.items.index(pagina)\n            print(f\"Pagina Actual: {pagina}\")\n        else:\n            print(\"No se puede retroceder mas\")\n    def eliminar_ultima_pagina_del_historial(self):\n        return self.items.pop()\n    \nprint(\"Creando el historial del navegador...\")\nchrome = Navegador()\n# Viendo el historial del navegador:\nprint(f\"Historial actual del navegador: {chrome.historial()}\")\n\nwhile True:\n    accion = input(\"Que quieres hacer dentro del navegador?: Escribe (Historial, Anadir, Avanzar, Retroceder, Eliminar) o si quieres cerrar la ejecucion escribe (Cerrar):\").lower()\n    if accion == \"historial\":\n        print(f\"Este es el historial actual del navegador: {chrome.historial()}\")\n    elif accion == \"anadir\":\n        url = input(\"Que pagina deseas anadir? Colocar URL completo:\").lower()\n        chrome.anadir_pagina(url)\n    elif accion == \"avanzar\":\n        chrome.avanzar()\n    elif accion == \"retroceder\":\n        chrome.retroceder()\n    elif accion == \"eliminar\":\n        chrome.eliminar_ultima_pagina_del_historial()\n    elif accion == \"cerrar\":\n        break\n\n# - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n#  *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n#  *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n#  *   interpretan como nombres de documentos.\n\nclass Impresora:\n    def __init__(self):\n        self.items = []\n    def anadir_documento(self, valor):\n        if (isinstance(valor, str)):\n            print(f\"Anadiendo elemento: {valor}\")\n            self.items.insert(0, valor)\n        else:\n            print(\"El nombre del documento tiene que ser de valor str\")\n    def imprimir(self):\n        if self.items != []:\n            documento_impreso = self.items.pop()\n            print(f\"Imprimiendo documento....\")\n            print(f\"Impreso: {documento_impreso}\")\n        else:\n            print(\"No hay mas documentos que imprimir!\")\n    def cola_de_impresion(self):\n        return self.items\n\nprint(\"Comprando impresora...\")\nimpresora_nueva = Impresora()\nprint(\"Impresora habilitada!!\")\n\nwhile True:\n    action = input(\"Que deseas hacer con la impresora? Escribe si: (Ver, Anadir, Imprimir o Apagar)\").lower()\n    if action == \"anadir\":\n        documento = input(\"Escribe el nombre de documento a imprimir: \")\n        impresora_nueva.anadir_documento(documento)\n        print(f\"Documento anadido: {documento}\")\n    if action == \"imprimir\":\n        print(f\"Imprimiendo..\")\n        impresora_nueva.imprimir()\n    if action == \"ver\":\n        cola_de_impresion = impresora_nueva.cola_de_impresion()\n        print(cola_de_impresion)\n    if action == \"apagar\":\n        break"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/BrianSilvero.py",
    "content": "\"\"\"\nEjercicio\n\"\"\"\n\nstack = []\n\n# Pila/Stack (LIFO)\n\n#Push\nstack.append(1)\nstack.append(2)\nstack.append(3)\n\nprint(stack)\n\n# Pop\nstack_item = stack[len(stack) - 1]\ndel stack[len(stack) - 1]\nprint(stack_item)\n\nprint(stack.pop())\nprint(stack)\n\n\n# Cola/Queue (FIFO)\nqueue = []\n#queque\nqueue.append(1)\nqueue.append(2)\nqueue.append(3)\n\nprint(queue)\n\nqueue_item = queue[0]\ndel queue[0]\nprint (queue_item)\n\nqueue.pop(0)\n\nprint(queue)\n\n\n\"\"\"\nExtra\n\"\"\"\n\ndef web_navegation():\n    \n    stack= []\n    \n    while True:\n        action = input(\"Añade un url o iteractua con palabras adelante/atras/salir: \")\n\n        if action == \"salir\":\n            print(\"Saliendo del navegador web\")\n            break\n        elif action == \"adelante\":\n            stack.pop(0)\n        elif action == \"atras\":\n            if stack > 0:\n                stack.pop()\n        else: \n            stack.append(action)\n            pass\n        \n        print(f\"Has navegado a la web: {stack[len(stack) - 1]}\")\n        \n        if len(stack) > 0:\n            print(f\"Has navegado a la web: {stack[len(stack) - 1]}\")\n        else:\n            print(\"Estas en la pagina de inicio.\")\n\n# web_navegation()\n\ndef shared_printer ():\n    queue= []\n    \n    while True:\n        action = input(\"Añade documento o selecciona imprimir/salir: \")\n    \n        if action == \"salir\":\n            print(\"Saliendo de impresora\")\n            break\n        elif action == \"imprimir\":\n            if len(queue) > 0:\n                print(f\"Imprimiendo {queue.pop(0)}\")\n            else:\n                print(\"La cola esta vacia\")\n        else:\n            queue.append(action)\n            \n        print(f\"Cola de impresion {queue}\")\n\nshared_printer()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/C-Gabs.py",
    "content": "#Reto 07\n\n'''Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.'''\n\n#Pila\npila = [1,2,3,4,5,6]\nprint(pila)\npila.append(7)\nprint(pila)\nprint(pila.pop())\nprint(pila)\n\n\n#Cola\ncola = [1,2,3,4,5,6]\ncola.insert(0,0)\nprint(cola)\nprint(cola.pop())\nprint(cola)\n\n\n#Reto Extra\n\n#Adelante/Atras\ndef navegacion_web():\n    webs = []\n    tope = []\n    while True:\n        texto = str(input(\"Introduzca Adelante/Atras para navegar entre las paginas web, introduzca una nueva web o introduzca 'Salir': \\n\"))\n        if texto.lower() == \"adelante\":\n            if len(tope) > 0:\n                webs.append(tope.pop())\n                print(f\"Estas en la web: {webs[-1]}\")\n            else:\n                print(\"No hay paginas webs mas recientes\\n\")\n        elif texto.lower() == \"atras\":\n            if len(webs) == 1:\n                print(\"No hay paginas webs mas antiguas\\n\")\n            else:\n                tope.append(webs.pop())\n                print(f\"Estas en la web: {webs[-1]}\")\n        elif texto.lower() == \"salir\":\n            print(\"Finaliza el programa\")\n            break\n        else:\n            if len(tope) > 0:\n                tope.clear()\n            webs.append(texto)\n            print(f\"estas en la web: {texto}\")\n\nnavegacion_web()\n#Imprimir\n\ndef impresora_compartida():\n    impresora = []\n    while True:\n        texto = str(input(\"Introduzca 'imprimir' para imprimir un documento, introduzca un nuevo documento a la cola o introduzca 'Salir': \\n\"))\n        if texto.lower() == \"imprimir\":\n            if len(impresora) == 0:\n                print(\"No hay documentos para imprimir\")\n            else:\n                print(f\"Se imprimió el documento: {impresora.pop()}\")\n        elif texto.lower() == \"salir\":\n            print(\"Finaliza el programa\")\n            break\n        else:\n            print(f\"Se añade el documento: '{texto}' a la cola de impresión\")\n            impresora.insert(0,texto)\n\nimpresora_compartida()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/CaveroBrandon.py",
    "content": "\"\"\"EJERCICIO:\nImplementa los mecanismos de introducción y recuperación de elementos propios de las pilas (stacks - LIFO)\ny las colas (queue - FIFO) utilizando una estructura de array o lista (dependiendo de las posibilidades de tu lenguaje).\n\"\"\"\n\n\ndef enter_value():\n    i = 0\n    while i < 3:\n        value = input(f'Enter value # {i + 1} to the list:')\n        original_list.append(value)\n        print(f'The list is: {original_list}')\n        i += 1\n\n\ndef lifo_recover():\n    copy_list = original_list.copy()\n    print('**** Recovering the information LIFO ****')\n    print(f'The list is: {original_list}')\n    while len(copy_list) != 0:\n        removed_value = copy_list.pop()\n        print(f'The value removed was \\'{removed_value}\\', the list is now: {copy_list}')\n\n\ndef fifo_recover():\n    copy_list = original_list.copy()\n    print('**** Recovering the information FIFO ****')\n    print(f'The list is: {original_list}')\n    while len(copy_list) != 0:\n        removed_value = copy_list.pop(0)\n        print(f'The value removed was \\'{removed_value}\\', the list is now: {copy_list}')\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atras\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n\"\"\"\n\n\ndef web_navigator(web_address, total_address):\n    print()\n    user_input = input('Enter a web address, or \"Adelante\" to go forward, \"Atras\" to go back, or \"Salir\" to exit: ')\n    option = str(user_input).lower()\n\n    if option == 'adelante':\n        if len(total_address) != len(web_address):\n            web_address.append(total_address[len(web_address)])\n            print_website(web_address)\n            web_navigator(web_address, total_address)\n        else:\n            print(f'There is not action to go forward')\n            web_navigator(web_address, total_address)\n    elif option == 'atras':\n        if len(web_address) == 1 or len(web_address) == 0:\n            print(f'There is not action to go back')\n            web_navigator(web_address, total_address)\n        else:\n            web_address.pop()\n            print_website(web_address)\n            web_navigator(web_address, total_address)\n    elif option == 'salir':\n        pass\n    else:\n        web_address.append(user_input)\n        total_address.append(user_input)\n        if web_address != total_address:\n            total_address = web_address.copy()\n        print_website(web_address)\n        web_navigator(web_address, total_address)\n\n\ndef print_website(website_list):\n    for element in website_list:\n        print(element + '/', end='')\n\n\n\"\"\" Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una impresora compartida que \nrecibe documentos y los imprime cuando así se le indica.La palabra \"imprimir\" imprime un elemento de la cola,\nel resto de palabras se interpretan como nombres de documentos\n\"\"\"\n\n\ndef print_spooler(printer_spooler_list):\n    user_input = input('Enter the document you want to print, or \"imprimir\" to print, or \"Salir\" to exit: ')\n    option = str(user_input).lower()\n\n    if option == 'imprimir':\n        if len(printer_spooler_list) == 0:\n            print('There are no more documents to print')\n            print_spooler(printer_spooler_list)\n        else:\n            printed_element = printer_spooler_list.pop(0)\n            print(f'The element printed was \"{printed_element}\", elements in the printer spooler are:')\n            for element in printer_spooler_list:\n                print(element)\n            print_spooler(printer_spooler_list)\n    elif option == 'salir':\n        pass\n    else:\n        printer_spooler_list.append(user_input)\n        print(f'The element added is {user_input}, the documents in the printer spooler are:')\n        for element in printer_spooler_list:\n            print(element)\n        print_spooler(printer_spooler_list)\n\n\n# Exercise\noriginal_list = list()\nenter_value()\nlifo_recover()\nfifo_recover()\n\n# Extra 1\nweb_address = list()\ntotal_address = list()\nweb_navigator(web_address, total_address)\n\n# Extra 2\nprinter_spooler_list = list()\nprint_spooler(printer_spooler_list)\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/CesarCarmona30.py",
    "content": "class Stack:\n\n  def __init__(self):\n    self.data = []\n\n  def push(self, element):\n    self.data.append(element)\n\n  def pop(self):\n    try:\n      element = self.data.pop()\n    except IndexError as e:\n      print(f'Error: {type(e).__name__}, empty stack')\n      return\n    print(f'Stack element out: {element}')\n\n  def showData(self):\n    print(f'Stack: {self.data}')\n\nclass Queue:\n\n  def __init__(self):\n    self.data = []\n\n  def enqueue(self, element):\n    self.data.append(element)\n\n  def dequeue(self):\n    try:\n      element = self.data.pop(0)\n    except IndexError as e:\n      print(f'Error: {type(e).__name__}, empty queue')\n      return\n    print(f'Queue element out: {element}')\n\n  def showData(self):\n    print(f'Queue: {self.data}')\n\nveggies = Stack()\nveggies.push('Cucumber')\nveggies.push('Radish')\nveggies.push('Tomato')\nveggies.push('Orange')\nveggies.push('Apple')\nveggies.showData()\nveggies.pop()\nveggies.pop()\nveggies.showData()\n\nfruits = Queue()\nfruits.enqueue('Banana')\nfruits.enqueue('Melon')\nfruits.enqueue('Strawberry')\nfruits.enqueue('Onion')\nfruits.enqueue('Garlic')\nfruits.showData()\nfruits.dequeue()\nfruits.dequeue()\nfruits.showData()\n\nclass Browser(Stack):\n  \n  def __init__(self):\n    super().__init__()\n    self.currentPage = None\n    self.index = None\n\n  def addPage(self, page):\n    self.push(page)\n    self.index = len(self.data) - 1\n    self.currentPage = self.data[self.index]\n\n  def goBack(self):\n    try:\n      self.index -= 1\n      self.currentPage = self.data[self.index]\n      return self.currentPage\n    except Exception:\n      print('Sin páginas en el historial')\n      return '-'\n\n  def goForward(self):\n    try:\n      self.index += 1\n      self.currentPage = self.data[self.index]\n      return self.currentPage\n    except Exception:\n      print('Sin referencia de página adelante')\n      return '-'\n\ndef history(browser):\n  while True:\n    option = input('>_')\n    page = ''\n    match option.lower():\n      case 'adelante':\n        page = browser.goForward()\n        print(f'Página actual: {page}')\n      case 'atras':\n        page = browser.goBack()\n        print(f'Página actual: {page}')\n      case 'salir':\n        break\n      case _:\n        new_page = option\n        browser.addPage(new_page)\n        print(f'Nueva página: {new_page}')\n\nmyBrowser = Browser()\nhistory(myBrowser)\n\nclass Printer(Queue):\n  def __init__(self):\n    super().__init__()\n  \n  def printDoc(self):\n    printout = self.dequeue()\n    return printout\n\n  def addDoc(self, doc):\n    self.enqueue(doc)\n\n  def dequeue(self):\n    try:\n      element = self.data.pop(0)\n      return element\n    except Exception:\n      return 'No hay elemento'\n    \ndef printQueue(printer):\n  while True:\n    option = input('doc name: ')\n    match option.lower():\n      case 'imprimir':\n        docPrinted = printer.printDoc()\n        print(f'Documento impreso: {docPrinted}')\n      case 'salir':\n        break\n      case _:\n        new_doc = option\n        printer.addDoc(new_doc)\n\nmyPrinter = Printer()\nprintQueue(myPrinter)"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/Chrisdev00.py",
    "content": "\"\"\"\n* EJERCICIO:\n* Implementa los mecanismos de introducción y recuperación de elementos propios de las\n* pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n* o lista (dependiendo de las posibilidades de tu lenguaje).\n*\n* DIFICULTAD EXTRA (opcional):\n\n* - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n*   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n*   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n*   Las palabras \"adelante\", \"atras\" desencadenan esta acción, el resto se interpreta como\n*   el nombre de una nueva web.\n\n* - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n*   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n*   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n*   interpretan como nombres de documentos.\n\"\"\"\n\n####### ---------------------- Stack ------------------------- ######\n\n\"\"\" Un \"stack\" es una estructura de datos que sigue el principio de Last In, First Out (LIFO). \nEsto significa que el último elemento agregado a la pila es el primero en ser eliminado.\"\"\"\n\n\nclass Stack:\n    def __init__(self):\n        self.items = []\n\n    def is_empty(self):\n        return len(self.items) == 0\n\n    def push(self, item):       # funcion para agregar un elemento a la parte superior de la pila\n        self.items.append(item)\n\n    def pop(self):              # funcion para eliminar y devolver el elemento superior de la pila\n        if not self.is_empty():\n            return self.items.pop()\n        else:\n            print(\"La pila está vacía\")\n\n    def peek(self):             # funcion para mostrar el ultimo elemento que se agrego a la pila sin borrarlo\n        if not self.is_empty():\n            return self.items[-1]\n        else:\n            print(\"La pila está vacía\")\n\nstack = Stack()\n\nstack.push(1)\nstack.push(2)\nstack.push(3)\n\nprint(stack.items)\n\nprint(stack.pop())  \nprint(stack.pop()) \nprint(stack.peek())\n\nprint(stack.items)\n\n\n###### ----------------------- Queue ------------------------ ########\n\n\"\"\"Una \"queue\" es una estructura de datos que sigue el principio de First In, First Out (FIFO). \nEsto significa que el primer elemento agregado a la cola es el primero en ser eliminado.\nEs similar a una fila en un supermercado. La primera persona que llega es la primera en ser atendida.\"\"\"\n\nclass Queue:\n    def __init__(self):\n        self.items = []\n\n    def is_empty(self):\n        return len(self.items) == 0\n\n    def enqueue(self, item):                # funcion para agregar un elemento al final de la cola\n        self.items.append(item)\n\n    def dequeue(self):                      # funcion para eliminar y devolver el elemento del principio de la cola\n        if not self.is_empty():\n            return self.items.pop(0)\n        else:\n            print(\"La cola está vacía\")\n\n    def peek(self):                        # funcion que devuelve el elemento que esta en el frente de la cola es\n        if not self.is_empty():            # decir el primer elemento que se agrego a la cola, el elemento no se elimina\n            return self.items[0]\n        else:\n            print(\"La cola está vacía\")\n\nqueue = Queue()\n\nqueue.enqueue(1)\nqueue.enqueue(2)\nqueue.enqueue(3)\n\nprint(queue.items)\n\nprint(queue.dequeue())  \nprint(queue.dequeue()) \nprint(queue.peek())\n\n\n######## -------------------------------DIFICULTAD EXTRA----------------------------- ############\n\n\"\"\"Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n*   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n*   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n*   Las palabras \"adelante\", \"atras\" desencadenan esta acción, el resto se interpreta como\n*   el nombre de una nueva web.\n\"\"\"\n\nclass NavegadorWeb:\n    def __init__(self):\n        self.historial = []\n        self.actual = None\n\n    def navegar(self, sitio_web):\n        if self.actual:\n            self.historial.append(self.actual)\n        self.actual = sitio_web\n        print(f\"Has navegado a: {sitio_web}\")\n        self.mostrar_historial()\n\n    def adelante(self):\n        if self.historial:\n            sitio_web = self.historial.pop()\n            self.actual = sitio_web\n            print(f\"Avanzando hacia adelante a: {sitio_web}\")\n        else:\n            print(\"No hay más páginas para avanzar.\")\n\n    def atras(self):\n        if self.actual:\n            self.historial.append(self.actual)\n            sitio_web = self.historial.pop(-2)\n            self.actual = sitio_web\n            print(f\"Retrocediendo hacia atrás a: {sitio_web}\")\n        else:\n            print(\"No hay historial para retroceder.\")\n    def mostrar_historial(self):\n        print(\"Historial de navegacion:\", self.historial)\n\nnavegador = NavegadorWeb()\n\nwhile True:\n    print(\"\\nIngresa una accion\")\n    accion = input(\"\"\"\n        adelante,\n        atras,\n        nombre de la página web\n        salir\n        opcion: \"\"\")\n    try:\n        if accion == \"adelante\":\n            navegador.adelante()\n        elif accion == \"atras\":\n            navegador.atras()\n        elif accion == \"salir\":\n            print(\"Saliendo del navegador.\")\n            break\n        else:\n            navegador.navegar(accion)\n    except ValueError:\n        print(\"Por favor, ingresa una opcion válida.\")\n\n\n\"\"\" Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n*   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n*   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n*   interpretan como nombres de documentos.\n\"\"\"\n\nfrom collections import deque\n\nclass ImpresoraCompartida:\n    def __init__(self):\n        self.cola_impresion = deque()\n\n    def agregar_documento(self, document_name):\n        self.cola_impresion.append(document_name)\n        print(f\"El documento '{document_name}' ha sido agregado a la cola de impresión.\")        \n\n    def imprimir_documento(self):\n        if self.cola_impresion:\n            document_to_print = self.cola_impresion.popleft()\n            print(f\"Imprimiendo el documento: '{document_to_print}'\")\n        else:\n            print(\"La cola de impresión está vacía. No hay documentos para imprimir.\")\n\n    def mostrar_cola(self):\n        print(\"Cola actual de impresión:\", self.cola_impresion)\n\nprinter = ImpresoraCompartida()\n\nwhile True:\n    print(\"\\n¿Qué deseas hacer?\")\n    opcion = input(\"\"\"\n        1.- Agregar documento\n        2.- Imprimir documento\n        3.- Mostrar cola de impresión\n        4.- Salir\n        Opción: \"\"\")\n    \n    try:\n        opcion = int(opcion)\n        if opcion == 1:\n            documento = input(\"Introduce el nombre del documento que deseas agregar: \")\n            printer.agregar_documento(documento)\n        elif opcion == 2:\n            printer.imprimir_documento()\n        elif opcion == 3:\n            printer.mostrar_cola()           \n        elif opcion == 4:\n            print(\"Programa de impresión cerrado. ¡Hasta luego!\")\n            break\n        else:\n            print(\"Opción no válida. Por favor, ingresa un número del 1 al 4.\")\n    except ValueError:\n        print(\"Por favor, ingresa un número válido.\")\n\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/Complex303.py",
    "content": "\"\"\"\nPilas & Colas\n\"\"\"\n\n#Pila(Stack): Estructura donde el último en entrar es el primero en salir (LIFO). Las pilas se suelen utilizar con listas\n\nstack = []\n\n#push\nstack.append(1) \nstack.append(3) \nstack.append(5) \nstack.append(7) \nprint(stack)\n\n#pop: pop quita el ultimo elemento en entrar\nelemento = stack.pop()\nprint(elemento)\nprint(stack)\n\n#otra forma de hacer el pop\n# # stack_item = stack[len(stack) - 1]\n# # del stack[len(stack) - 1]\n# # print(stack_item)\n# # print(stack)\n\n\n#Cola (Queue): Estructura donde el primero en entrar es el primero en salir (FIFO).\n\nqueue = []\n#enqueue\nqueue.append(2)\nqueue.append(4)\nqueue.append(6)\nqueue.append(8)\nprint(queue)\n\n#dequeue. eleminamos el primer elemento\nprint(queue.pop(0))\nprint(queue)\n\n#otra forma de eliminar el primer elemento\nqueue_item = queue[0]\ndel queue[0]\nprint(queue_item)\nprint(queue)\n\n\"\"\"\nOTRA FORMA DE IMPLEMENTAR QUEUE\"\"\"\nfrom collections import deque\n\ncola = deque()\n\n# Agregar elementos (enqueue)\ncola.append(1)\ncola.append(2)\ncola.append(3)\n\nprint(\"Cola:\", cola)\n\n# Quitar elemento (dequeue)\nprimero = cola.popleft()\nprint(\"Elemento quitado:\", primero)\nprint(\"Cola ahora:\", cola)\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\"\"\"\n\n\n\n#Con lista\n# Definimos la función paginaweb\ndef paginaweb():\n    # Creamos una lista vacía para guardar las URLs\n    lista = []\n    # Definimos la variable 'posicion' en -1, indicando que no hay ninguna página visitada al inicio\n    posicion = -1\n\n    # Iniciamos un bucle infinito que solo se romperá cuando se escriba 'salir'\n    while True:\n        # Pedimos al usuario que escriba una URL o una palabra clave\n        opcion = input(\"Añade una url o interactua con palabras adelante/atras/salir: \")\n        \n        # Si el usuario escribe 'salir', terminamos el bucle y cerramos la función\n        if opcion.lower() == 'salir':\n            print(\"Saliendo del navegador...\")\n            break\n\n        # Si el usuario escribe 'adelante'\n        elif opcion.lower() == 'adelante':\n            # Verificamos si se puede avanzar (es decir, que no esté ya en la última posición)\n            if posicion < len(lista) - 1:\n                # Avanzamos una posición\n                posicion += 1\n                # Mostramos la página actual\n                print(f\"Página actual: {lista[posicion]}\")\n            else:\n                # Si no se puede avanzar, avisamos al usuario\n                print(\"No hay páginas hacia adelante\")\n\n        # Si el usuario escribe 'atras'\n        elif opcion.lower() == 'atras':\n            # Verificamos si se puede retroceder (es decir, que no esté ya al inicio)\n            if posicion > 0:\n                # Retrocedemos una posición\n                posicion -= 1\n                # Mostramos la página actual\n                print(f\"Página actual: {lista[posicion]}\")\n            else:\n                # Si no se puede retroceder, avisamos al usuario\n                print(\"No hay páginas hacia atrás\")\n\n        # Si el usuario escribe cualquier otra cosa (una URL nueva)\n        else:\n            # Agregamos esa URL al final de la lista\n            lista.append(opcion)\n            # Actualizamos la posición actual para que apunte a esa nueva página\n            posicion = len(lista) - 1\n            # Mostramos la página actual\n            print(f\"Página actual: {lista[posicion]}\")\n\n        # Si la lista de páginas está vacía (lo cual nunca pasará aquí, pero está de precaución)\n        if len(lista) == 0:\n            print(\"Estas en la página principal\")\n\n# Llamamos a la función para que empiece a ejecutarse\npaginaweb()\n\n\n\n#Ejercicio de la impresora\n\n# Definimos una función llamada shared_printed\ndef shared_printed():\n    # Creamos una lista vacía llamada queue, que actuará como cola de impresión\n    queue = []\n\n    # Ciclo infinito: se repetirá hasta que el usuario escriba 'salir'\n    while True:\n        # Pedimos al usuario que escriba una opción: documento, 'imprimir' o 'salir'\n        opcion = input(\"Añade un documento o selecciona imprimir/salir: \")\n\n        # Si el usuario escribe 'salir' (ignorando mayúsculas/minúsculas)\n        if opcion.lower() == \"salir\":\n            print(\"Saliendo...\")\n            break  # Rompe el ciclo y termina la función\n\n        # Si el usuario escribe 'imprimir'\n        elif opcion.lower() == 'imprimir':\n            # Verificamos si la cola no está vacía\n            if len(queue) > 0:\n                # quitamos e imprimimos el primer documento de la cola (FIFO)\n                print(f\"Imprimiendo: {queue.pop(0)}\")\n\n        # Si no es 'salir' ni 'imprimir', se considera un nombre de documento\n        else:\n            # Lo agregamos al final de la cola\n            queue.append(opcion)\n\n        # Mostramos el estado actual de la cola de impresión\n        if len(queue) > 0:\n            print(f'Cola de impresion {queue}')\n        else:\n            print(\"No hay archivos que imprimir\")\n\n# Llamamos a la función para que empiece a ejecutarse\n#shared_printed()\n\n\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/DaniQB99.py",
    "content": "\"\"\" \nEJERCICIO:\n  Implementa los mecanismos de introducción y recuperación de elementos propios de las\n  pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n  o lista (dependiendo de las posibilidades de tu lenguaje).\n\"\"\"\n\n# Pila/Stack (LIFO)\nstack = []\nstack.append(\"1\") #Push\nstack.append(\"2\") #Push\nstack.append(\"3\") #Push\nprint(stack)\n\n# Pop\nstack_item = stack[len(stack) -1] \ndel stack[len(stack) -1]\nprint(stack_item)\n\nprint(stack.pop()) # Devuelve el último elemento de la pila\n\n\n# Cola/Queue (FIFO)\nqueue = []\n\n# Enqueue/Encolar\nqueue.append(1)\nqueue.append(2) \nqueue.append(3) \nprint(queue)\n\n# Dequeue/Desencolar\nqueue_item = queue[0]\ndel queue[0]\nprint(queue_item)\n\nprint(queue.pop(0)) # Devuelve el primer elemento de la cola\n\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n  - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n    de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n    que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n    Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n    el nombre de una nueva web.\n  - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n    impresora compartida que recibe documentos y los imprime cuando así se le indica.\n    La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n    interpretan como nombres de documentos.\n\"\"\"\nprint('\\n\\n\\n--- EJERCICIO EXTRA ---\\n')\n\n# NAVEGADOR WEB\ndef web_browser():\n    \n    \"\"\"\n    En esta version del navegador, no se puede usar la \n    funcion adelante sin antes haber utilizado la funcion atras\n    \"\"\"\n    \n    pages = []\n\n    last_page = \"\"\n\n    def insert_web():\n       link = input(\"Introduce una pagina web: \")\n       pages.append(link)\n       print(f\"Redirigiendote a {link}\") \n    \n\n    def forward():\n       if last_page == \"\":\n           print(\"Te encuentras en la ultima pagina\") \n       else:\n           pages.append(last_page)\n           print(\"Redirigiendote a \", pages[-1])\n\n\n    def backwards():\n        backwards = pages.pop()\n        print(f\"Ultima pagina: {backwards}\")\n\n        return backwards\n\n\n    while True:\n\n        print(\"\\n\\n GESTION DE PÁGINAS WEB\\n\")\n        print(\"1. Introducir una pagina\")\n        print(\"2. Adelante\")\n        print(\"3. Atras\")\n        print(\"4. Historial\")\n        print(\"5. Salir\")\n\n        status = input(\"Que opcion deseas realizar?: \")\n\n        match status:\n\n            case \"1\":\n                insert_web()\n            case \"2\":\n                forward()\n            case \"3\": \n                last_page = backwards()\n            case \"4\": \n                print(pages)\n            case \"5\":\n                print(\"Hasta pronto.\")\n                break\n            case _:\n                print(\"Opcion no valida. Elige una opcion del 1 al 5\")\n\nweb_browser()    \n\n\n# IMPRESORA\nfrom collections import deque \n\ndef printer():\n\n   queue = deque() \n\n   def send():\n        doc = input(\"Que documento deseas enviar? :\")\n        queue.append(doc)\n        print(f\"Cola: {queue}\")\n\n\n   def printing():\n       print('Imprimiendo', queue.popleft())\n       print('Qedan:', queue, 'documentos.')\n\n   while True:\n       \n       print(\"\\n\\n GESTION DE DOCUMENTOS\\n\")\n       print(\"1. Enviar\")\n       print(\"2. Imprimir\")\n       print(\"3. Salir\")\n       \n       status = input(\"Que opcion deseas realizar?: \")\n       \n       match status:\n\n        case \"1\":\n            send()\n        case \"2\":\n            if len(queue) == 0:\n                print(\"No hay documentos que imprimir.\")\n            else:\n                printing()\n        case \"3\":\n            print(\"Cerrando la impresorsa.\")\n            break\n        case _:\n            print(\"Opcion no valida. Elige una opcion del 1 al 3\")\n\nprinter()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/Daparradom.py",
    "content": "### 07 -- PILAS Y COLAS ###  \n\n# PILA : ultimo elemento en ingresar es el primero en salir\n\n# cambios realizados\n\ncambios = [\"escribir\", \"borrar frase\", \"aumentar tamano de letra\", \"poner en negrilla\"  ]\n\nprint(f\"Cambios actuales: {cambios}\")\n\nultimo_cambio = cambios.pop()\n\nprint(f'Cambio desecho : {ultimo_cambio}')\n\nprint (f' Historial de cambios actual luego de deshacer el ultimo {cambios}')\n\n# Cola : primer elemento en ingresar es el primero en salir\n\nbanco_cola = [\"Turno 1\",\"Turno 2\",\"Turno 3\",\"Turno 4\"]\n\natendiendo = banco_cola.pop(0)\n\nprint(f\"se atiende turno {atendiendo}, quedan en espera {banco_cola}\")\n    \n\ndef navegacion () :\n    pagina_web = []\n    while True :\n        comando = input(\"Escriba adelante o atras para navegar entre las paginas o escriba el nombre de la pagina que desea abrir, presione s para salir: \")\n        comando_lower = comando.lower()\n        if comando_lower == 's' :\n            print(\"saliendo de la navegacion\")\n            break\n        elif comando_lower == \"adelante\":\n            pass\n        elif comando_lower == \"atras\":\n            if len(pagina_web)>0 :\n               pagina_web.pop()\n        else:\n            pagina_web.append(comando_lower)\n        \n        if len(pagina_web) > 0  :\n            print(f'Estas en la pagina : {pagina_web[len(pagina_web)-1]}')\n        else :\n            print(\"estas en el inicio\")\n\ndef imprimiendo () :\n    cola_impresion = []\n    while True :\n        documento = input('agregue documento, imprimir o presione s para salir: ')\n        documento_lower = documento.lower()\n        if documento_lower == \"s\" :\n            print('saliendo de impresora')\n            break\n        elif documento_lower == \"imprimir\":\n            if len(cola_impresion)>0 :\n                print(f\"Imprimiendo el documento: {cola_impresion.pop(0)}\")\n        else:\n            cola_impresion.append(documento_lower)\n        \n        if len(cola_impresion) > 0:\n            print(f\"Documentos en cola de impresion: {cola_impresion}\")\n        else:\n            print(\"No hay documentos en la cola de impresion\")\n\n#navegacion()\nimprimiendo()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/DataCiriano.py",
    "content": "\"\"\"\n* EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atras\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n\"\"\"\n\n# Pilas/Stacks (LIFO Last In First Out)\n\nstack = []\n\n#Añadir elementos a la pila\nstack.append(\"a\")\nstack.append(\"b\")\nstack.append(\"c\")\n\nprint(stack)\n\n#Eliminar el último elemento de la pila\nstack_item = stack.pop(len(stack) - 1 )\n\nprint(stack_item)\nprint(stack)\n\n\n# Cola/Queue (FIFO First In First Out)\n\nqueue = []\n\n#Añadir elementos a la cola\nqueue.append(1)\nqueue.append(2)\nqueue.append(3)\n\nprint(queue)\n\n#Eliminar el primer elemento de la cola\nqueue_item = queue.pop(0)\n\nprint(queue_item)\nprint(queue)\n\n\n#----EXTRA----\n\n#Navegador web con implementación de pila\n\ndef web():\n    url = [\"www.google.es\", \"www.amazon.es\", \"www.youtube.es\"]\n\n    while True:\n        action = input(\"Añade una URL o navega escribiendo adelante/atrás/salir: \").lower()\n\n        match action:\n            case \"salir\":\n                print(\"Saliendo de la web. Hasta luego.\")\n                break\n\n            case \"adelante\":\n                web = input(\"Introduzca la dirección: \")\n                url.append(web)\n                print(f\"Se encuentra en: {web}\")\n\n            case \"atrás\":\n                try:\n                    elemento = url.pop()\n                    print(f\"Se encuentra en: {elemento}\")\n                except IndexError:\n                    print(\"No hay elementos en la lista de URLs.\")\n\n            case _:\n                url.append(action)\n                print(f\"Añadida la URL {action}\")\n                print(url)\n\n\nweb()\n\n\n#Impresora compartida con implementación de cola\n\ndef printer():\n\n    printing_queue= []\n    papel = [\"hoja 1\", \"hoja 2\", \"hoja 3\", \"hoja 4\", \"hoja 5\"]\n    tinta = 100\n    \n    while True:\n        action = input(\"Escriba imprimir para añadir un documento, o explore las diferentes funciones con cola/estado/papel/tinta/salir: \").lower()\n        \n        match action:\n            \n            case \"salir\":\n                print(\"Saliendo del programa de impresión, hasta pronto.\")\n                break\n            \n            case \"cola\":\n                print(printing_queue)\n        \n            case \"estado\":\n                if papel > 0 and tinta:\n                    print(\"La impresora está lista para la impresión\")\n                else:\n                    if not papel:\n                        print(\"No hay suficiente papel para imprimir. Cargue papel e inténtelo de nuevo.\")\n                    elif tinta <= 0:\n                        print(\"No hay suficiente tinta para imprimir. Rellene el depósito e inténtelo de nuevo.\")\n                break\n                        \n            case \"papel\":\n                print(f\"Quedan {len(papel)} hojas disponibles para imprimir.\")\n            \n            case \"tinta\":\n                tinta = len(papel) * 20\n                print(f\"El nivel de tinta está en {tinta}%.\")\n            \n            case \"imprimir\":\n                try:\n                    if len(papel) > 0 and tinta > 0:\n                        document = printing_queue.pop(0)\n                        papel.pop()\n                        print(f\"Imprimiendo... {document}\")\n                    else: \n                        print(\"No hay suficiente papel o tinta para realizar la impresión.\")\n                except IndexError:\n                    print(\"La cola de impresión está vacía. Añada documentos con 'imprimir'.\")\n                    \n            case _:\n                printing_queue.append(action)\n                print(f\"Se añadió el documento {action}\")\n                \nprinter()\n\n\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/DavidBastosG.py",
    "content": "import os\nimport time\nimport unicodedata\n\nclear = lambda: os.system('cls')\nclear()\n\nclass Pila:\n    def __init__(self):\n        # Define elems list of the stack\n        self.items = []\n    \n    def Add(self, elem):\n        # Add elem to the stack\n        if type(elem) == list:\n            self.items += elem\n        else:\n            self.items.append(elem)\n            \n    def Take(self):\n        # Return last elem from the stack\n        return self.items.pop()\n\nclass Cola:\n    def __init__(self):\n        # Define elems list of the stack\n        self.items = []\n    \n    def Add(self, elem):\n        # Add elem to the stack\n        if type(elem) == list:\n            self.items += elem\n        else:\n            self.items.append(elem)\n    \n    def Take(self):\n        # Return first elem from the queue\n        return self.items.pop(0)\n    \n## EXTRA ##\n    \ndef elimina_tildes(cadena):\n    s = ''.join((c for c in unicodedata.normalize('NFD',cadena) if unicodedata.category(c) != 'Mn'))\n    return s\n\ndef wait_and_clear(t):\n    time.sleep(t)\n    clear()\n\n# Program 1 (Navegador)\ndef navegador():\n    pila = Pila()\n\n    while True:\n        # Ask user what to do\n        t = 2\n        print(\"Estamos navegando ¿Qué desea hacer ahora?\")\n        userIn = input()\n\n        if userIn.lower() == \"end\":\n            break\n        else:\n            #Look for command\n            command = [userIn.lower().find(\"adelante\") > -1,elimina_tildes(userIn.lower()).find(\"atras\") > -1]\n        \n        # Execution\n        if all(command):\n            # Both commands where sent, do nothing\n            print(\"Error, no se puede ir adelante y atrás al mismo tiempo\")\n\n        elif command[0]:\n            # ADELANTE\n            pila.Add(userIn[len(\"adelante\")+1:])\n            print(\"Avanzamos a \" + pila.items[-1])\n            t = 1.5\n\n        elif command[1]:\n            # ATRÁS\n            if not pila.items:\n                # pila is empty\n                print(\"No hay dirección anterior a la actual\")\n            else:\n                # Return to previous adress\n                print(\"Regresamos a \" + pila.Take())\n\n        else:\n            # No commands where sent\n            print('No hay comandos. Use adelante o atrás para navegar')\n            \n        wait_and_clear(t)\n\n# Program 2 (Cola impresión)\ndef cola_impresion():\n    cola = Cola()\n\n    # Ask user what to do\n    while True:\n        t = 1\n        print(\"INSTRUCCIONES PARA LA IMPRESORA. ESCRIBA IMPRIMIR O AÑADA UN ELEMENTO A LA COLA\")\n        userIn = input()\n\n        # Execution\n        if userIn.lower() == \"end\":\n            break\n        elif userIn.lower().find(\"imprimir\") > -1:\n            # Print\n            print(\"Procedemos a imprimir \" + str(cola.Take()) + \". Quedan \" + str(len(cola.items)) + \" elementos en la cola de impresión.\")\n            t = 2\n        else:\n            # Add elem to queue\n            cola.Add(userIn)\n            print(userIn + \" ha sido añadido a la cola de impresión\")\n        \n        wait_and_clear(t)\n\n# navegador()\n# cola_impresion()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/Dkp-Dev.py",
    "content": "\"\"\"\nEJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n\"\"\"\n\n# Pila/Stack (Last In First Out (LIFO))\n\nstack = []\n\n# push\nstack.append(1)\nstack.append(2)\nstack.append(3)\nstack.append(4)\nstack.append(5)\nprint(stack)\n\n# pop\nstack_item = stack[len(stack) - 1]\ndel stack[len(stack) - 1]\nprint(stack_item)\n\nprint(stack.pop())\n\nprint(stack)\n\n# Cola/Queue (First In First Out(FIFO))\n\nqueue = []\n\n# enqueue\nqueue.append(1)\nqueue.append(2)\nqueue.append(3)\nqueue.append(4)\nqueue.append(5)\n\nprint(queue)\n\n# dequeue\nqueue_item = queue[0]\ndel queue[0]\nprint(queue_item)\n\nprint(queue.pop(0))\n\nprint(queue)\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n \"\"\"\n\n\n# Web\n\n\ndef web_navigation():\n\n    stack = []\n\n    while True:\n\n        action = input(\n            \"Añade una url o interactúa con palabras adelante/atras/salir: \"\n        )\n\n        if action == \"salir\":\n            print(\"Saliendo del navegador web.\")\n            break\n        elif action == \"adelante\":          # No se puede realizar con un stack\n            pass\n        elif action == \"atras\":\n            if len(stack) > 0:\n                stack.pop()                 # Al declarar mecanismos de LIFO es como convertimos una lista en un stack\n        else:\n            stack.append(action)\n\n        if len(stack) > 0:\n            print(f\"Estas en la web: {stack[len(stack) - 1]}.\")     # Aqui nuevamente estamos trabajando con el ultimo item en la lista\n        else:\n            print(\"Página de inicio.\")\n\n\nweb_navigation() \n\n\ndef shared_printed():\n\n    queue = []\n\n    while True:\n\n        action = input(\"Añade un documento o selecciona imprimir/salir: \")\n\n        if action == \"salir\":\n            break\n        elif action == \"imprimir\":\n            if len(queue) > 0:\n                print(f\"Imprimiendo: {queue.pop(0)}\")       # Aqui trabajamos con el primer item asi que convertimos la lista en cola FIFO\n        else:\n            queue.append(action)\n\n        print(f\"Cola de impresión: {queue}\")\n\n\nshared_printed()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/EliasBonnin.py",
    "content": "# Ejercicio 07\n# En el siguiente URL https:/python.org Tenemos la documentacion de phyton.\n# Los retos se encuentran en https://retosdeprogramacion.\n\n# Pila/Stack (LIFO)\n\nimport time\nPila = []\n\n# Push\n\nPila.append(1)\nPila.append(2)\nPila.append(3)\n\nprint(Pila)\n\n# Pop\n\nPila_item = Pila[len(Pila) - 1]  # Con esto obtenemos el primer item de la pila.\ndel Pila[len(Pila) - 1]  # Al obtenerlo debemos removerlo del conjnunto de elementos de la pila\nprint(Pila_item)\n\nprint(Pila.pop())  # Remueve el valor mas alto de la pila.\n\nprint(Pila)\n\n\n# Cola/Queue [FIFO]\n\nCola = []\n\n# Encolar\n\nCola.append(1)\nCola.append(2)\nCola.append(3)\n\nprint(Cola)\n\n# Descolar\n\nCola_item = Cola[0]\ndel Cola[0]\nprint(Cola_item)\n\n\nprint(Cola.pop(0))\n\nprint(Cola)\n\n# Extra\n\n# Funcion Web PILA\n\n\ndef NavegacionWeb():\n    pila = []\n    while True:\n        action = input(\"Añade una URL o interactua con las palabras adelante/atras/salir:  \")\n\n        if action == \"salir\":\n            print(\"Esta saliendo del navegador\")\n            time.sleep(1)\n            break\n        elif action == \"adelante\":\n            pass\n        elif action == \"atras\":\n            if len(pila) > 0:\n                pila.pop()\n        else:\n            pila.append(action)\n\n        if len(pila) > 0:\n            print(f\"Has navegado a la web: {pila[len(pila) - 1]}\")\n        else:\n            print(\"Estas en la pagina de inicio\")\n\n\n# NavegacionWeb()\n\n\ndef Impresorapy():\n\n    cola = []\n\n    while True:\n\n        action = input(\"Ingrese el documento o interactue con imprimir/salir:  \")\n\n        if action == \"salir\":\n            print(\"Usted esta saliendo de la impresora\")\n            time.sleep(1)\n            break\n        elif action == \"imprimir\":\n            if len(cola) > 0:\n                print(f\"Se imprime el siguiente archivo: {cola.pop(0)}\")\n        else:\n            cola.append(action)\n\n        print(f\"Cola de impresion {cola}\")\n\n\nImpresorapy()\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/EmmanuelMMontesinos.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n */\n\"\"\"\nprint(\"---Ejercicio 07: Pilas y Colas---\")\n# Pilas, Ultimo en entrar primero en salir\npila = []\n\"\"\"Añadiendo elementos a la pila\"\"\"\nfor n in range(1,11):\n    pila.append(n)\n    print(f\"Añadido a pila: {n}\")\n\"\"\"Quitando elementos de la pila\"\"\"\nfor element in range(len(pila)):\n    print(f\"Quitado de pila: {pila.pop()}\")\n\n# Colas, Primero en entrar primero en salir\ncola = []\n\"\"\"Añadiendo elementos a la cola\"\"\"\nfor n in range(1,11):\n    cola.append(n)\n    print(f\"Añadido a cola: {n}\")\n\"\"\"Quitando elementos de la cola\"\"\"\nfor element in range(len(cola)):\n    print(f\"Quitando de cola: {cola.pop(0)}\")\n    \n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * x- Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n\"\"\"\n\n# Navegador Pila\nclass Navegador:\n    def __init__(self) -> None:\n        self.paginas_visitadas = [\"home\"]\n        self.puntero = -1\n        self.pagina_actual = \"home\"\n        \n    def actual(self,puntero=-1):\n        if puntero == - 1:\n            self.puntero = puntero\n            self.pagina_actual = self.paginas_visitadas[self.puntero]\n        else:\n            if puntero == 1:\n                try:\n                    self.puntero -= 1\n                    self.pagina_actual = self.paginas_visitadas[self.puntero]\n                except IndexError:\n                    print(\"No hay paginas siguientes\")\n                \n            elif puntero == 2:\n                if self.puntero < 0:\n                    try:\n                        self.puntero += 1\n                        self.pagina_actual = self.paginas_visitadas[self.puntero]\n                    except IndexError:\n                        print(\"No hay paginas anteriores\")\n                else:\n                    print(\"No hay paginas anteriores\")\n\n    def mostrar_actual(self):\n        print(f\"Actual: {self.pagina_actual}\")\n\n    def siguiente(self,nueva_pagina=\"adelante\"):\n        if nueva_pagina.lower() != \"adelante\":\n            if self.puntero == -1:\n                self.paginas_visitadas.append(nueva_pagina)\n                self.actual()\n            else:\n                self.paginas_visitadas = [n for n in self.paginas_visitadas[0:self.puntero + 1]]\n                self.paginas_visitadas.append(nueva_pagina)\n                self.actual()\n            \n        else:\n            self.actual(2)\n    \n    def anterior(self):\n        self.actual(1)\n\n    def comando(self,comando):\n        if comando.lower() == \"atras\":\n            self.anterior()\n            self.mostrar_actual()\n        elif comando.lower() == \"historial\":\n            print(f\"Historial: {self.paginas_visitadas}\")\n        else:\n            self.siguiente(comando)\n            self.mostrar_actual()\n\n# Pruebas\nprint(\"---Navegador---\")\nmi_navegador = Navegador()\nmi_navegador.comando(\"pagina 1\")\nmi_navegador.comando(\"atras\")\nmi_navegador.comando(\"historial\")\nmi_navegador.comando(\"pagina 2\")\nmi_navegador.comando(\"historial\")\n\n\n# Impresora Cola\n\nclass Impresora:\n    def __init__(self) -> None:\n        self.cola = []\n        self.paginas_pendientes = len(self.cola)\n    \n    def actualizar_pendientes(self):\n        self.paginas_pendientes = len(self.cola)\n        print(f\"Paginas pendientes: {self.paginas_pendientes}\\n{self.cola}\")\n        \n\n    def agregar(self,documento):\n        self.cola.append(documento)\n        print(f\"Agregado: {documento}\")\n    \n    def imprimir(self):\n        hoja_impresa = self.cola.pop(0)\n        print(f\"Documento impreso: {hoja_impresa}\")\n        self.actualizar_pendientes()\n        \n    def comando(self,comand):\n        if comand.lower() == \"imprimir\":\n            self.imprimir()\n        else:\n            self.agregar(comand)\n            \n# Pruebas\nprint(\"---Impresora---\")\nmi_impresora = Impresora()\nmi_impresora.comando(\"Libro_mouredev.pdf\")\nmi_impresora.comando(\"Libro_minudev.pdf\")\nmi_impresora.comando(\"imprimir\")\nmi_impresora.comando(\"Libro_holamundo.pdf\")\nmi_impresora.comando(\"Libro_pildorasinformaticas.pdf\")\nmi_impresora.comando(\"imprimir\")"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/EricJoel-code.py",
    "content": "## Pilas y Colas\n\n#Pilas/Stacks es una estructura de datos que sigue el principio LIFO (Last In, First Out), es decir, el último elemento en entrar es el primero en salir.\n\n#Colas/Queues es una estructura de datos que sigue el principio FIFO (First In, First Out), es decir, el primer elemento en entrar es el primero en salir.\n\n# Pilas/Stacks\n\nstacks = []\n\n# Agregar elementos a la pila\n\nstacks.append(1)\nstacks.append(2)\nstacks.append(3)\nstacks.append(4)\nprint(stacks)\n\n# Eliminar elementos de la pila\n\n# Opcion 1: usando del y len(), pero es menos común y no recomendado\nitem = stacks[len(stacks) -1]\ndel stacks[len(stacks) -1]\nprint(item)\n\nprint(stacks)\n\n# Opcion 2: usando pop(), que es una funcion propia del lenguaje y es la forma recomendada\nitem = stacks.pop()\nprint(item)\n\nprint(stacks)\n\n#Colas/Queues\n\nqueues = []\n\n# Agregar elementos a la cola\nqueues.append(1)\nqueues.append(2)\nqueues.append(3)\nqueues.append(4)\nprint(queues)\n\n# Eliminar elementos de la cola\n\n# Opcion 1\nitem_queue = queues[0]\ndel queues[0]\nprint(item_queue)\n\nprint(queues)\n\n# Opcion 2: usando pop(0), pasandole el indice en la posicion 0 para eliminar el primer elemento\nitem_queue = queues.pop(0)\nprint(item_queue)\n\nprint(queues)\n\n##Extra\n\n\"\"\"Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\nde un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\nque te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\nLas palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\nel nombre de una nueva web.\"\"\"\n\n# Implementacion de pila para el historial del navegador\n\n\ndef navegador():\n    print(\"Bienvenido al navegador web simulado.\")\n\n    historial = []\n    pagina_actual = None\n\n    while True:\n        # Muestra la página actual para que el usuario sepa dónde está\n        if pagina_actual:\n            print(f\"\\nEstás en: {pagina_actual}\")\n        else:\n            print(\"\\nEstás en la página de inicio.\")\n\n        accion = input(\"Ingresa una URL, 'atras', 'adelante', o 'salir': \").lower()\n\n        if accion == \"salir\":\n            print(\"Saliendo del navegador...\")\n            break\n\n        elif accion == \"atras\":\n            # Si hay elementos en el historial de atrás, se puede retroceder\n            if historial:\n                # Se navega a la última página del historial de atrás\n                pagina_actual = historial.pop()\n                print(f\"Navegando hacia atrás a: {pagina_actual}\")\n            else:\n                pagina_actual = None\n                #print(\"No hay páginas para retroceder.\")\n\n        elif accion == \"adelante\":\n                print(\"No hay páginas para avanzar.\")\n\n        else: # Se considera que el usuario ingresó una nueva URL\n            # La página actual se guarda en el historial\n            if pagina_actual:\n                historial.append(pagina_actual)\n\n            pagina_actual = accion\n            print(f\"Visitando nueva página: {pagina_actual}\")\n\nnavegador()\n\n\"\"\"En la implementacion anterior, la accion adelante no tiene funcionalidad ya que no se\nguarda un historial de páginas hacia adelante. Para implementar esta funcionalidad, se puede\nutilizar una segunda pila que almacene las páginas hacia adelante cuando se navega hacia atrás.\"\"\"\n\n\n\n\"\"\"Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\nimpresora compartida que recibe documentos y los imprime cuando así se le indica.\nLa palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\ninterpretan como nombres de documentos.\"\"\"\n\n# Implementacion de cola para la impresora compartida\n\ndef impresora():\n    \n    print(\"Bienvenido a la impresora compartida simulada.\")\n    \n    cola_impresion = []\n    \n    while True:\n        accion = input(\"Ingrese el nombre del documento, 'imprimir' o 'salir':  \").lower()\n        \n        if accion == \"salir\":\n            print(\"Saliendo de la impresora...\")\n            break\n        elif accion == \"imprimir\":\n            if cola_impresion:\n                documento = cola_impresion.pop(0)\n                print(f\"Imprimiendo documento: {documento}\")\n            else:\n                print(\"No hay documentos en la cola de impresion\")\n        else:\n            cola_impresion.append(accion)\n            print(f\"Documento '{accion}' agregado a la cola de impresion.\")\n            \n        print(f\"Cola de impresion actual: {cola_impresion}\")   \n            \nimpresora()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/FedeAirala.py",
    "content": "# 07 Pilas y Colas con Python\n\n\"\"\"\n    Breve resumen: las pilas y las colas son estructuras de datos en el orden en que ingresan y en el que salen de \n    la misma tiene un orden. Los datos entran a la estructura de manera ordena y el orden en el que salen en una pila\n    es de forma descendente, esto quiere decir que el último en ingresar es el primero en salir en cambio en las colas\n    es de forma ascendente, el primero en entrar es el primero en salir, todo esto hasta que no queden datos por\n    recorrer en la estructura.\n\n\"\"\"\n\n\n# Ejemplo de Cola deque\n\nfrom collections import deque  # Librería en Python para tratar las pilas y colas\n\ncola = deque()     # Estructura de tipo cola\ncola.append(0)     # Con append se insertan datos a la cola\ncola.append(1)\ncola.append(2)\ncola.append(3)\ncola.append(4)\n\nprint (f\" Cola completa: {cola}\") # Impresión de cola completa\n\n\nfor i in range (len(cola)):\n    sacar_datos = cola.popleft()              # popleft va retirando los datos de la cola de manera ascendente\n    print (f\"Dato extraído: {sacar_datos}\")\n    print (f\"Datos que quedan en la cola: {cola}\")\n\n# Ejemplo de cola con listas\n    \n\ncola=[]\ncola.append(0)\ncola.append(1)\ncola.append(2)\ncola.append(3)\ncola.append(4)\n\nfor i in range (len(cola)):\n    print (cola[i])\n    \n\n# Ejemplo de Pilas deque\n    \npila = deque()     # Estructura de tipo pila\npila.append(0)     # Con append se insertan datos a la pila\npila.append(1)\npila.append(2)\npila.append(3)\npila.append(4)\n\nprint (f\" Pila completa: {pila}\") # Impresión de pila completa\n\n\nfor i in range (len(pila)):\n    sacar_datos = pila.pop()              # pop va retirando los datos de la pila de manera descendente\n    print (f\"Dato extraído: {sacar_datos}\")\n    print (f\"Datos que quedan en la cola: {pila}\")\n\n\"\"\"Otras formas de trabajar con pilas y colas es con la estructiura de listas, ya que estas se pueden tratar\n    con el concepto de las mismas variando en cuestios \"\"\"\n\n# Ejemplo de pilas con listas\n\n#Pilas\n\npila = []\npila.append (0)\npila.append (1)\npila.append (2)\npila.append (3)\npila.append (4)\n\nn = len(pila)\n\nfor i in range (n):\n    print (pila[n-i-1])\n\n   \n\n\n\n\"\"\" * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atras\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n\"\"\"\n\n# Primer ejercicio de dificulta extra: Pila\n\nlist_web = []\nindex=0\n\ndef list_empty(list_web):\n    if len(list_web)==0:\n        print (\"Lista vacía\")\n        return True\n    else:\n        return False\n\ndef navegador_web():\n    while True:\n        accion = input (\" 1 Buscar web  !  2 Atrás  ! 3 Adelante  ! 4 Listar Web's  ! 5 Sacar web de lista  !  6 Salir\")\n        global index\n        match accion:\n                case \"1\":\n                    web = input(\"Ingrese nombre de la web:\")\n                    list_web.append(web)\n                    index+=1\n                    print(list_web)\n                \n                case \"2\":\n                    if  not list_empty(list_web):\n                        if index==1:\n                            print (f\"Estás en la primer página: {list_web[index-1]}\")\n                        else:\n                            index-=1\n                            print (list_web[index-1])\n                        \n                case \"3\":\n                    if  not list_empty(list_web):\n                        if index == (len(list_web)):\n                            print (f\"Estás en la última página: {list_web[index-1]}\")\n\n                        else:\n                            index+=1\n                            print (list_web[index-1])\n                       \n                case \"4\":\n                    print (f\"Listado de web ingresadas: {list_web}\")\n                \n                case \"5\":\n                    if  not list_empty(list_web):\n                        list_web.pop()\n                        print (list_web)\n                        index -= 1\n                    \n                case \"6\":\n                    print(\"Saliendo de la aplicación.\")\n                    break\n                    \n                case _:\n                    print(\"Opción no válida. Elige una opción del 1 al 5.\")\n                  \nnavegador_web()\n\n# Segundo ejercicio dificultad extra: Cola\n\ndoc_print = deque() \n\nindex_2 = 0\ndoc = 0\ndoc_impresos = []\ndef doc_empty(doc_print):\n    if len(doc_print)==0:\n        print (\"No hay documentos en la cola de impresión\")\n        return True\n    else:\n        return False\n\ndef print_doc():\n    while True:\n        accion = input (\" 1 Imprimir  !  2 Ingresar Documento   ! 3 Listar Documentos    !  4 Documentos impresos  !  5 Salir\")\n        global index_2,doc\n\n        match accion:\n\n            case \"1\":\n                index_2 -= 1\n                if not doc_empty(doc_print):\n                    print(doc_print[index])\n                    doc_impresos.append(doc_print[index])\n                    doc_print.popleft()\n\n            case \"2\":\n                print (\"Ingreso de documento a la cola de impresión\")\n                doc+=1\n                doc_print.append(doc)\n                print (doc_print)\n                \n            case \"3\":\n                 print (f\"En cola de impresión: {doc_print}\")\n            \n            case \"4\":\n                print (doc_impresos)\n                 \n            case \"5\":\n                print (\"Saliendo de impresión\")\n                break\n            case _:\n                print(\"Opción no válida. Elige una opción del 1 al 4.\")\n\nprint_doc()               \n\n\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/Gallitofast.py",
    "content": "#Ejercicio 07 \n\"\"\"\nPilas (Stacks)\n\"\"\"\n\n\"\"\"\nOperaciones clave:\npush(): Añade un elemento a la parte superior (top) de la pila.\npop(): Elimina y devuelve el elemento superior.\npeek() (o top()): Observa el elemento superior sin eliminarlo.\nisEmpty(): Verifica si la pila está vacía.\n\"\"\"\nstack = []\nstack.append(1)  # push(1)\nstack.append(2)  # push(2)\nstack.append(3)  # push(3)\nprint(stack.pop())  # Devuelve 3 (último elemento)\n\n\n\"\"\"\nColas (Queue)\n\"\"\"\n\"\"\"\nenqueue(): Añade un elemento al final (rear) de la cola.\ndequeue(): Elimina y devuelve el primer elemento (front).\nfront(): Observa el primer elemento sin eliminarlo.\nisEmpty(): Verifica si la cola está vacía.\n\"\"\"\nfrom collections import deque\ndq = deque()\ndq.appendleft(1)  # Añade al frente\ndq.append(2)      # Añade al final\nprint(dq.popleft())  # Elimina del frente\n\nlist_web=[]\nindex=0\ndef list_empty(list_web):\n    if len(list_web)==0:\n        print (\"The list is empty.\")\n        return True\n    else:\n        return False\n\ndef web_navigator():\n    while True:\n        action=input(\" 1 Search web | 2 Back | 3 Forward | 4 Weblist | 5 Remove web from list | 6 Exit\")\n        global index\n        match action:\n            case \"1\":\n                web = input(\"Enter the website:\")\n                list_web.append(web)\n                index+=1\n                print(list_web)\n\n            case \"2\":\n                if not list_empty(list_web):\n                    if index ==1:\n                        print(f\"you are on the very first page: {list_web[index-1]}\")\n                    else:\n                        index-=1\n                        print(list_web[index-1])\n\n            case \"3\":\n                if  not list_empty(list_web):\n                        if index == (len(list_web)):\n                            print(f\"You are on the last web on the list:{list_web[index-1]}\")\n                        else:\n                            index+=1\n                            print(list_web[index-1])\n            case \"4\":\n                print(f\"Weblist{list_web}\")\n            case \"5\":\n                if not list_empty(list_web):\n                    list_web.pop()\n                    print(list_web)\n                    index-=1\n            case \"6\":\n                print(\"exit succesfully\")\n                break\n            case _:\n                print(\"Invalid entry | Select from 1 to 5\")\nweb_navigator()\ndoc_print = deque() \n\nindex_2=0 \ndoc=0\nprinted_doc=[]\n\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/Gordo-Master.py",
    "content": "\"\"\"\nPilas y Colas\n\"\"\"\n\n\n### Pilas / Stack (LIFO) ###\n\npila = list()\n\n\n# Push\n\npila.append(\"python\")\npila.append(\"C++\")\npila.append(\"C#\")\npila.append(\"PHP\")\npila.append(\"Java\")\n\nprint(pila)\n\n\n# Pop\n\npila_item = pila[len(pila)-1]\nprint(pila_item)\ndel pila[len(pila)-1]\nprint(pila)\n\nprint(pila.pop())\nprint(pila)\n\n\n### Cola / Queue (FIFO) ###\n\ncola = list()\n\n\n# enqueue\n\ncola.append(\"Casa\")\ncola.append(\"Casita\")\ncola.append(\"Rancho\")\ncola.append(\"Palacio\")\n\nprint(cola)\n\n\n# dequeue\n\ncola_item = cola[0]\nprint(cola_item)\ndel cola[0]\nprint(cola)\n\nprint(cola.pop(0))\nprint(cola)\n\n\n# Metodo con deque de collections, mas optimo\n\nfrom collections import deque\n\ncola2 = deque()\n\ncola2.append(\"Agua\")\ncola2.append(\"Fuego\")\ncola2.append(\"Tierra\")\ncola2.append(\"Aire\")\n\nprint(cola2)\nprint(cola2.popleft())\nprint(cola2)\nprint(cola2.popleft())\nprint(cola2)\n\n\n\n\"\"\"\nEjercicio Extra\n\"\"\"\n\n\ndef navigator():\n    historial = []\n    historial_ad = []\n    while True:\n        action = input(\n            \"Coloca una url o elige una de las opciónes: adelante/atrás/salir: \"\n        ).lower()\n        if action == \"adelante\":\n            if len(historial_ad) > 0:\n                historial.append(historial_ad.pop())\n        elif action == \"atrás\":\n            if len(historial) > 0:\n                historial_ad.append(historial.pop())\n        elif action == \"salir\":\n            print(\"Saliendo del programa...\")\n            break\n        else: \n            historial.append(action)\n            historial_ad = []\n\n        if len(historial) > 0:\n            print(f\"Pagina web actual: {historial[-1]}\")\n        else:\n            print(\"Panel de inicio de navegación\")\n\n\nnavigator()\n\n\n\ndef impresora(action: str =\"\", cola: list = []):\n    \n    while True:\n        action = input(\n            \"Ingrese 'imprimir', el nombre del documento o 'salir': \"\n        )\n        if action == \"imprimir\":\n            if len(cola) > 0:\n                print(f\"Imprimiendo documento: {cola.pop(0)}....\")\n        elif action == \"salir\":\n            print(\"Saliendo del programa...\")\n            break\n        else :\n            cola.append(action)\n            print(f\"Documento: {action} agregado a la cola\")\n        \n        if len(cola) > 0:\n            print(f\"Cola de impresión: {cola}\")\n        else:\n            print(\"No hay documentos en cola...\")\n\n\nimpresora()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/Hyromy.py",
    "content": "pila = []\n\nprint(pila) #[]\n\npila.append(\"Item 1\")\npila.append(\"Item 2\")\npila.append(\"Item 3\")\npila.append(\"Item 4\")\npila.append(\"Item 5\")\n\nprint(pila) #[1, 2, 3, 4, 5]\n\npila.pop()\nprint(pila) #[1, 2, 3, 4]\n\nfor i in range(len(pila)):\n    print(f\"Item eliminado: {pila.pop()}\")\nelse:\n    print(pila)\n\n\"\"\" ---------------- \"\"\"\n\nfrom collections import deque\n\ncola = deque()\n\nprint(cola) #[]\n\ncola.append(\"Elemento 1\")\ncola.append(\"Elemento 2\")\ncola.append(\"Elemento 3\")\ncola.append(\"Elemento 4\")\ncola.append(\"Elemento 5\")\n\nprint(cola) #[1, 2, 3, 4, 5]\n\ncola.popleft()\nprint(cola) #[2, 3, 4, 5]\n\nfor i in range(len(cola)):\n    print(f\"Elemento eliminado: {cola.popleft()}\")\nelse:\n    print(cola) #[]\n\n\n# ---- DIFICULTAD EXTRA ----\n\nnav = [0]\ndef navegador() -> None:    \n    print(\" ---- NAVEGADOR WEB ----\")\n    print(\"Selecciona una opción del navegador\")\n    while True:\n        print(\"( B ) Buscar \\n\" +\n              \"( <- ) Regresar\\n\" +\n              \"( -> ) Avanzar\\n\" +\n              \"( X ) Salir\")\n        opt = input(\"=> \")\n\n        if opt.casefold() == \"b\":\n            buscar(nav)\n\n        elif opt == \"<-\" or opt.casefold() in \"regresar\":\n            regresar()\n\n        elif opt == \"->\" or opt.casefold() in \"avanzar\":\n            avanzar()\n\n        elif opt.casefold() == \"x\":\n            break\n\n        else:\n            print(\"\\n(!) OPCION NO VALIDA\\n\")\n\n\ndef buscar(nav:list):\n    print(\"\\nEscribe el sitio que quieras buscar\")\n    busqueda = input(\"=> \")\n\n    if nav[0] != len(nav) -1:\n        i = nav[0] + 1\n        copy = nav[:i] \n        nav.clear()\n\n        for i in copy:\n            nav.append(i)\n\n    nav.append(busqueda)\n    nav[0] += 1\n\n    current()\n\ndef regresar():\n    if nav[0] -1 <= 0:\n        print(\"\\n(!) NO PUEDES RERESAR MAS\\n\")\n    else:\n        nav[0] -= 1\n\n    current()\n\ndef avanzar():\n    if nav[0] +1 >= len(nav):\n        print(\"\\n(!) NO PUEDES AVANZAR MAS\\n\")\n    else:\n        nav[0] += 1\n\n    current()\n\ndef current():\n    index = nav[0]\n    print(f\"\\nESTAS NAVEGANDO EN {nav[index]}\\n\")\n\nnavegador()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/Irenetitor.py",
    "content": "#Stacks - LIFO (Last In First Out)\nstack = []\n\nstack.append(1)\nstack.append(2)\nstack.append(3)\nstack.append(4)\n\nprint(stack)\n\nprint(stack.pop())\nprint(stack.pop())\nprint(stack)\n\n#Queue - FIFO (First In First Out)\nqueue = []\n\nqueue.append(6)\nqueue.append(7)\nqueue.append(8)\nqueue.append(9)\n\nprint(queue)\n\nprint(queue.pop(0))\nprint(queue.pop(0))\n\nprint(queue)\n\n#Extra exercises\n#First\n\ndef browsing_web():\n\n    moves = []\n\n    while True:\n        action = input(\"Add a URL or interact using the following words: forward, back, exit.\")\n\n        if action == \"forward\":\n            pass\n        elif action == \"back\":\n            if len(moves) > 0:\n                moves.pop()\n        elif action == \"exit\":\n            print(f\"Leaving the website\")\n            break\n        else:\n            moves.append(action)\n        \n        if len(action) > 0:\n            print(f\"You have navigated to: {moves[len(moves) - 1]}\")\n        else:\n            print(\"You are on the home page.\")\n\nbrowsing_web()\n\n#Second\n\ndef print_doc():\n\n    Docs = []\n\n    while True:\n\n        action = input(\"Add a document or select print/exit: \")\n\n        if action == \"exit\":\n            break\n        elif action == \"print\":\n            print(f\"Printing: {Docs(0)}\")\n        else:\n            Docs.append(action)\n\n    print(f\"Print queue: {Docs}\")\n\nprint_doc()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/JAFeito.py",
    "content": "# EJERCICIO:\n# Implementa los mecanismos de introducción y recuperación de elementos propios de las\n# pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n# o lista (dependiendo de las posibilidades de tu lenguaje).\n \n # DIFICULTAD EXTRA (opcional):\n #- Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n #   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n #   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n #   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n #   el nombre de una nueva web.\n # - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n #   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n #   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n #   interpretan como nombres de documentos.\n \n #Solo dificultad extra\nlista_pag = [\"www.goggle.es\",\"www.microsoft.es\",\"www.youtube.com\"]\n\ndef navegate (lista_pag):\n    posicion = 0\n    continuar = True\n    while continuar :\n        eleccion = input(\"Escriba 'adelante' o 'atras' para navegar, el nombre de la nueva web o 'exit' para salir:\")\n        if eleccion == \"atras\":\n            if posicion == 0:\n                print (f\" {lista_pag[posicion]} es la primera. \")\n            else:\n                posicion -= 1\n                print (lista_pag[posicion])\n        elif eleccion == \"adelante\":\n            if posicion == len(lista_pag) - 1:\n                print (f\" {lista_pag[posicion]} es la ultima. \") \n            else:\n                posicion += 1\n                print (lista_pag[posicion])\n        elif eleccion == \"exit\":\n            continuar = False\n            \n        else:\n            lista_pag.append(eleccion)\n            print (f\" {eleccion} se ha añadido a la lista.\")\nnavegate(lista_pag)\nprint(lista_pag)\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/JacMac45.py",
    "content": "# Pilas y colas\n\n# Pila/Stack (LIFO/Ultimo en entrar, primero en salir)\n\nstack = []\n\n# Añadir elementos a la pila (push)\nstack.append(1)\nstack.append(2)\nstack.append(3)\n\nprint(f'Items de la pila al apilar: {stack}')\n\n# Eliminar el ultimo elemento de la pila\nstack_item = stack[len(stack) - 1]\ndel stack[len(stack) - 1]\nprint(stack_item)\nprint(stack)\n\n# Utilizamos el método pop para quitar el ultimo elemento que haya entrado \" len()-1 \". Mas recomendable y eficiente\nprint(stack.pop())\nprint(stack)\n\n\n# Cola/Queue (FIFO/Primero en entrar, primero en salir)\n\nqueue = []\n\n# Insertar elementos a la cola (enqueue)\nqueue.append(1)\nqueue.append(2)\nqueue.append(3)\n\nprint(f'Items de la cola al apilar: {queue}')\n\n# Eliminar el primer elemento de la cola\nqueue_item = queue[0]\ndel queue[0]\nprint(queue_item)\nprint(queue)\n\n# Utilizamos el método pop para quitar el primer elemento que haya entrado \" 0 \". Mas recomendable y eficiente\nprint(queue.pop(0))\nprint(queue)\n\n# DIFICULTAD EXTRA \n\n# Navegador web con implementación de pila:\n\ndef web_navigation():\n    navigator = []\n    print(\"Panel de inicio de navegación\")\n\n    while True:\n        action = input(\"Introduce una url o elige una de las opciones: adelante/atrás/salir: \").lower()\n        if action == \"salir\":\n            print(\"Saliendo del navegador web.\")\n            break\n        elif action == \"adelante\":\n            if len(navigator) > 0: \n                print(f\"Has navegado a la web: {navigator[len(navigator) - 1]}\")\n                navigator.pop()\n        elif action == \"atrás\":\n            if len(navigator) > 0:\n                print(f\"Has navegado a la web: {navigator[len(navigator) - 1]}\")\n                navigator.pop()\n        else:\n            navigator.append(action)\n\n        if len(navigator) > 0:\n            print(f\"Pagina web actual: {navigator[-1]}\")\n        else:\n            print(\"Panel de inicio de navegación\")        \n            \n\nweb_navigation()\n\n# DIFICULTAD EXTRA 2\n\n# Impresora con implementación de cola:\n\ndef shared_printer():\n    queue = []\n    while True:\n                \n        action = input(\"Introduce el documento que deseas añadir o selecciona 'imprimir' para imprimir o 'salir' \\n\").lower()\n        \n        if action == \"salir\":\n            break\n        elif action == \"imprimir\":\n            if len(queue) > 0:\n                print(f\"Imprimiendo el documento {queue.pop(0)}\")\n            else:\n                print(\"No hay documentos en la cola de impresión.\")\n        else:\n            queue.append(action)\n\n        \n        if len(queue) > 0: print(f\"Cola de impresión: {queue}\")\n        else: print(\"No hay documentos en la cola de impresión.\")\n        \n\nshared_printer()\n\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/Jav-mol.py",
    "content": "# Pilas y Colas\n\n# --- PILAS --- \narray_pila = ['Python', 'Java', 'Rust', 'Go', 'Typescript']\nprint(array_pila)\n\n# stacks - LIFO\npush = lambda x: array_pila.append(x)\npop = lambda: array_pila.pop()\n\npush('Javascript') # -> Agregando elemento\npush('Php')\nprint(array_pila)\n\npop() # -> Eliminando elemento\nprint(array_pila)\nprint()\n\n# --- COLAS ---\narray_cola = ['Go', 'Java', 'Javascript', 'Python', 'Rust', 'Typescript']\nprint(array_cola)\n\n# queue - FIFO\nenqueue = lambda x: array_cola.insert(0, x)\ndequeue = lambda: array_cola.pop()\n\n\nenqueue('Dart') # -> Insertando elemento\nenqueue('C#')\nprint(array_cola)\n\ndequeue() # -> Eliminando elemento\nprint(array_cola)\nprint()\n\n\n# --- Extra ---\n\nclass NavegadorWeb():\n    def __init__(self) -> None:\n        self.web = ['https://github.com','/mouredev', '/roadmap-retos-programacion']\n        self.index = 1\n\n    def adelante(self):\n        print(self.index)\n        if self.index < len(self.web):\n            self.index += 1\n        print(\"\".join(self.web[0:self.index]))\n        cadena_guines()\n        \n    def atras(self):\n        if self.index > 1:\n            self.index -= 1\n        print(\"\".join(self.web[0:self.index]))\n        cadena_guines()\n    \n    def agregar_web(self, web):\n        self.web.append(web)\n        print(\"\".join(self.web))\n        cadena_guines()\n            \n            \nnavegador = NavegadorWeb()\n\ncadena_guines = lambda:print('-'*30)\n\nmenu = '''Adelate - Siguiente Pagina Web\nAtras - Anterior Pagina Web\nExit/q - Salir del Programa\n\"Cualquier-Cadena\" - Agrega una Nueva Pagina Web\n=> '''\n\noptions = {\n    'ad':navegador.adelante,\n    'at':navegador.atras,\n    'exit':False,\n    'q':False\n}\n\nwhile True:\n    cadena_guines()\n    option = input(menu).lower()\n    if not option in options.keys():\n        navegador.agregar_web(option)\n        continue\n    \n    x = options.get(option)\n\n    if not x:\n        break   \n    x()\n    print()\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/JesusAntonioEEscamilla.py",
    "content": "# #07 - Python -> Jesus Antonio Escamilla\n\n\"\"\"\nEJERCIÓ\n\"\"\"\nclass Stack_:\n    def __init__(self):\n        self.stack = []\n\n    def push(self, item):\n        self.stack.append(item)\n\n    def pop(self):\n        if not len(self.stack) == 0:\n            return self.stack.pop()\n        else:\n            raise IndexError(\"pop from an empty stack\")\n\n    def peek(self):\n        if not len(self.stack) == 0:\n            return self.stack[-1]\n        else:\n            raise IndexError(\"peek from an empty stack\")\n\n    def show(self):\n        return self.stack\n\nprint(\"STACKS - PILAS - LIFO\")\nstack = Stack_()\nstack.push(10)\nstack.push(20)\nstack.push(30)\nprint(f\"Mostrando las pilas: {stack.show()}\")\nprint(f\"Eliminando un elemento de la pila: {stack.pop()}\")\nprint(f\"Ultimo elemento de la pila: {stack.peek()}\")\nprint(f\"Mostrando las pilas: {stack.show()}\")\n\n\nclass Queue_:\n    def __init__(self):\n        self.queue = []\n\n    def enqueue(self, item):\n        self.queue.append(item)\n\n    def dequeue(self):\n        if not len(self.queue) == 0:\n            return self.queue.pop(0)\n        else:\n            raise IndexError(\"dequeue from an empty queue\")\n\n    def front(self):\n        if not len(self.queue) == 0:\n            return self.queue[0]\n        else:\n            raise IndexError(\"front from an empty queue\")\n\n    def show(self):\n        return self.queue\n\nprint(\"QUEUE - COLAS - FIFO\")\nqueue = Queue_()\nqueue.enqueue(40)\nqueue.enqueue(50)\nqueue.enqueue(60)\nprint(f\"Mostrando las cola: {queue.show()}\")\nprint(f\"Eliminando un elemento de la cola: {queue.dequeue()}\")\nprint(f\"Primer elemento de la cola: {queue.front()}\")\nprint(f\"Mostrando las cola: {queue.show()}\")\n\n\n\n\"\"\"\nEXTRA\n\"\"\"\n# PILAS\n# Sitio Web\nclass Stack:\n    def __init__(self):\n        self.stack = []\n\n    def push(self, item):\n        self.stack.append(item)\n\n    def pop(self):\n        if not self.is_empty():\n            return self.stack.pop()\n        else:\n            raise IndexError(\"pop from an empty stack\")\n\n    def is_empty(self):\n        return len(self.stack) == 0\n\nclass BrowserNavigation:\n    def __init__(self):\n        self.back_stack = Stack()\n        self.forward_stack = Stack()\n        self.current_page = None\n\n    def visit(self, page):\n        if self.current_page:\n            self.back_stack.push(self.current_page)\n        self.current_page = page\n        self.forward_stack = Stack()\n        self.show_current_page()\n\n    def back(self):\n        if not self.back_stack.is_empty():\n            self.forward_stack.push(self.current_page)\n            self.current_page = self.back_stack.pop()\n        else:\n            print(\"No pages in history to go forward to\")\n        self.show_current_page()\n\n    def forward(self):\n        if not self.forward_stack.is_empty():\n            self.back_stack.push(self.current_page)\n            self.current_page = self.forward_stack.pop()\n        else:\n            print(\"No pages in history to go back to\")\n        self.show_current_page()\n\n    def show_current_page(self):\n        if self.current_page:\n            print(f\"Current page: {self.current_page}\")\n        else:\n            print(\"No page currently loaded\")\n\nbrowser = BrowserNavigation()\n\nwhile True:\n    command = input(\"Ingrese una pagina, 'adelante' o 'atrás' (o 'salir' para terminar):\\n\").strip()\n    if command == \"salir\":\n        break\n    elif command == \"adelante\":\n        browser.forward()\n    elif command == \"atras\":\n        browser.back()\n    else:\n        browser.visit(command)\n\n\n# COLAS\n# Impresora\nclass Queue:\n    def __init__(self):\n        self.queue = []\n\n    def enqueue(self, item):\n        self.queue.append(item)\n\n    def dequeue(self):\n        if not self.is_empty():\n            return self.queue.pop(0)\n        else:\n            raise IndexError(\"dequeue from an empty queue\")\n\n    def is_empty(self):\n        return len(self.queue) == 0\n    \n    def show(self):\n        return self.queue\n\nclass PrinterQueue:\n    def __init__(self):\n        self.queue = Queue()\n\n    def add_document(self, document):\n        self.queue.enqueue(document)\n        self.show_queue()\n\n    def print_document(self):\n        if not self.queue.is_empty():\n            printed_doc = self.queue.dequeue()\n            print(f\"Printing document: {printed_doc}\")\n        else:\n            print(\"No documents to print\")\n        self.show_queue()\n\n    def show_queue(self):\n        if self.queue.is_empty():\n            print(\"The print queue is empty\")\n        else:\n            print(f\"Documents in queue: {self.queue.show()}\")\n\nprinter = PrinterQueue()\n\nwhile True:\n    command = input(\"Ingrese un documento o 'imprimir' (o 'salir' para terminar):\\n\").strip()\n    if command == \"salir\":\n        break\n    elif command == \"imprimir\":\n        printer.print_document()\n    else:\n        printer.add_document(command)"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/JheisonQuiroga.py",
    "content": "from collections import deque\n\n\"\"\"\nPilas y colas\nSon estructuras de datos, se utilizan para almacenar y gestionar información\n\nPilas (Stacks):\nPrincipio LIFO (Last in- First out) \n\"\"\"\n\n# Ejemplo\n\nstack = []\n\nstack.append(1) # Push - Agregar un elemento\nstack.append(2)\nstack.append(3)\nstack.append(4)\nstack.append(5) # Ultimo en entrar\nprint(stack)\n\nprint(stack.pop()) # 5 POP - PRIMERO EN SALIR\n\n\"\"\"\n2. Colas - Queues\nPrincipio FIFO (First in - first out)\n\npush = Agregar elementos\npop = Eliminar elementos\ntop = Ver el elemento en la parte superior sin eliminarlo\nis_empty = Comprobar si la lista está vacia\n\"\"\"\n\nfirst_queue = []\n\nfirst_queue.append(1) # Agregando elementos\nfirst_queue.append(2)\nfirst_queue.append(3)\nfirst_queue.append(4)\nfirst_queue.append(5)\nprint(first_queue)\n\n# Eliminando el primer elemento\nprint(first_queue.pop(0)) # 1\n\n\"\"\"\n2.1. Colas - Utilizando el módulo collections\n\nenqueue = Agregar elementos\ndequeue = Eliminar elementos\nfront = Ver el elemento en frente sin eliminarlo\nis_empy = Comprobar si la cola está vacia\n\"\"\"\n\nqueue = deque()\n\nqueue.append(1) # Agregar el elemento a la cola\nqueue.append(2)\nqueue.append(3)\n\nprint(queue) # deque([1, 2, 3])\n\n#Eliminar el primer elemento\nfirst_element_eliminated = queue.popleft()\nprint(first_element_eliminated) # 1\nprint(queue) # deque([2, 3])\n\n\n\"\"\"\nExtra\n\"\"\"\nlst = [\"github.com\", \"roadmap-retos-programacion\", \"Roadmap\", \"07-pilasycolas\"]\nlst2 = []\n\ndef current_path_show():\n    print(\"Ruta actual:\")\n    print(\"/\".join(lst2))\n\n\ndef navigation_web():\n    print(\"Esta es la ruta de la página\")\n    print(\"/\".join(lst))\n    lst2.append(lst.pop(0))\n    print(lst2[0])\n\n    while True:\n        option = input(\"Quieres ir adelante/atras/salir: \").lower()\n\n        while option not in [\"adelante\", \"atras\", \"salir\"]:\n            option = input(\"Ingresa una opción valida adelante/atras/salir: \").lower()\n        \n        if option == \"adelante\":\n            if len(lst2) == 4:\n                print(\"Has llegado hasta el final de la ruta\")\n            else:\n                lst2.append(lst.pop(0))\n                current_path_show()\n        elif option == \"atras\":\n            if lst2:\n                lst.insert(0, lst2.pop())\n                current_path_show()\n            else:\n                print(\"Has llegado al inicio de la ruta\")\n        else:\n            break\n\n\n# Impresora\nprinter = []\n\n\ndef my_printer():\n    global printer\n    printer = []\n\n    while True:\n\n        print(\"\"\"Operaciones disponibles:\n            1. Agregar a la cola\n            2. Imprimir\n            3. Reiniciar cola\n            4. Apagar impresora\"\"\")\n\n        option = input(\"Que operación deseas realizar: \")\n\n        if option == \"1\":\n            element = input(\"Que deseas imprimir: \")\n            print(push_elements(element))\n        elif option == \"2\":\n            print(prt_element())\n        elif option == \"3\":\n            print(\"Reiniciando cola...\")\n            printer = []\n        elif option == \"4\":\n            print(\"Apagando impresora...\")\n            return\n        else:\n            print(\"Ingrese una opción valida\")\n\n\ndef show_elements():\n    return \"-\".join(printer)\n\ndef push_elements(element):\n    printer.append(element)\n    return show_elements()\n\ndef prt_element():\n    print(f\"Imprimiendo: {printer.pop(0)}\")\n    return f\"Elementos en cola: {show_elements()}\"\n\n\n\n\nmy_printer()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/JoseAlberto13.py",
    "content": "\"\"\" * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\"\"\"\n\n\"\"\" Creamos la Pila / Stack \"\"\"\nstack = []\n\n\"\"\" Añadir elementos (LIFO) \"\"\"\nstack.append(\"primero\")\nprint(stack)\nstack.append(\"segundo\")\nprint(stack)\nstack.append(\"tercero\")\nprint(stack)\nstack.append(\"cuarto\")\nprint(stack)\n\n\n\"\"\" Eliminar / Desapilar elementos (LIFO) \"\"\"\nprint(stack.pop()) # Utilizamos el método pop para quitar el ultimo elemento que haya entrado \" len()-1 \"\nprint(stack)\nprint(stack.pop())\nprint(stack)\n\nprint(stack[len(stack)-1])\ndel stack[len(stack)-1] # Estamos eliminado el elemeto en la ultima posición\nprint(stack)\n\n\n\"\"\" Cola / Queue (FIFO) \"\"\"\nstack.append(\"Cola 1\")\nprint(stack)\nstack.append(\"Cola 2\")\nprint(stack)\nstack.append(\"Cola 3\")\nprint(stack)\n\n\n\"\"\" Eliminar / Desencolar 'Dequeue' \"\"\"\nprint(stack.pop(0))\nprint(stack)\nprint(stack.pop(0))\nprint(stack)\n\nprint(stack[0])\ndel stack[0] # Estamos eliminado el elemeto en la primera posición\nprint(stack)\n\n\n\"\"\" * DIFICULTAD EXTRA (opcional):\n *   Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\"\"\"\n\n\ndef web_navegation():\n    web = [\"home\"]\n    restaurarWeb = []\n    while True:\n        action = input(\"Añade una url o interactua con palabras adelante/atrás/salir: \")\n        match action: \n            case \"salir\":\n                print(\"Cerraste el navegador.\")\n                break\n            case \"atrás\":\n                if len(web) > 1:\n                    restaurarWeb.append(web.pop()) # Quitando el elemento de la web y guardandola en otra lista\n                else:\n                    print(\"Se encuentra en el inicio: \")\n            case \"adelante\":\n                if len(restaurarWeb) > 0:\n                    web.append(restaurarWeb.pop()) # Devolviendo el elemento eliminado de la web\n            case _:\n                web.append(action) # \"Navegando\"\n        print(web)\nweb_navegation()\n\n\n\"\"\" *   Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n    *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n    *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n    *   interpretan como nombres de documentos.\"\"\"\n\ndef printer_actions():\n    documents = []\n    while True:\n        action = input(\"Añade un documento / ingresa (imprimir) ó (salir)\")\n        match action: \n            case \"salir\":\n                print(\"Saliste de la impresora.\")\n                break\n            case \"imprimir\":\n                if len(documents) > 0:\n                    print(f\"Imprimiendo Documento: {documents.pop(0)}\") # Quitando el elemento de la lista de documents\n                else:\n                    print(\"No tiene documentos en la cola de impresión\")\n            case _:\n                documents.append(action) # \"añadienod documento\"\n        print(f\"Cola de impresión: {documents}\")\n\nprinter_actions()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/JuanDAW37.py",
    "content": "\"\"\"\n* EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   historial compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n\"\"\"\n\n#Pila (Last Input First Output, LIFO)\npila = []\n\npila.append('A')\npila.append('B')\npila.append('C')\nprint(f'Pila entera: {pila}')\n\nelemento = pila.pop(len(pila) - 1) #Extraigo el último elemento y lo elimino de la lista\nprint(f'Último elemento: {elemento}')\nprint(f'Pila una vez extraído el último elemento: {pila}')\n\n#Cola (First Input First Output)\ncola = []\ncola.append('A')\ncola.append('B')\ncola.append('C')\nprint(f'Cola entera: {cola}')\n\nelemento = cola[0] #Extraigo el primer elemento y lo elimino de la lista. El cero siempre será el primer elemento\nprint(f'Primer elemento: {elemento}')\ndel cola[0] #Elimino el primer elemento de la cola. Se puede hacer de una sola vez con elemento = cola.pop(0)\nprint(f'Cola una vez extraído el primer elemento: {cola}')\n\n# Extra\n# Simulación de navegador web, pila LIFO\ndef navegador_web():\n    historial = []\n    navegacion = []\n    while True:\n        comando = input('Introduce una acción (adelante, atrás, URL o salir: ')\n        if comando == \"salir\":\n            break            \n        elif comando == \"adelante\":\n            pass\n        elif comando == \"atrás\":\n            if len(historial) > 0:\n                try:\n                    historial.pop()                                   \n                except Exception:\n                    print('No hay más páginas para ir atrás')\n        else:\n            historial.append(comando)            \n            navegacion.append(comando)\n            print(f'Página actual: {historial[len(historial) - 1]}')\n        if len(historial) > 0:\n            print(f'Posición {historial[len(historial)-1]}')                                          \n        else:\n            print('No hay páginas en el historial')\n    return navegacion\n\nprint(navegador_web())\n\n# Simulación de cola de impresión compartida, cola FIFO\ndef impresora():\n    cola = []\n    while True:\n        comando = input('Introduce un nombre de documento o una acción (imprimir, salir): ')\n        if comando == 'salir':\n            break\n        elif comando == 'imprimir':\n            if len(cola) > 0:\n                print(f'Imprimiendo documento {cola.pop(0)}')\n        else:\n            cola.append(comando)\n        print(f'Documentos en cola: {cola}')\n        \nimpresora()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/KevinED11.py",
    "content": "from collections import deque\nfrom abc import ABC, abstractmethod\nfrom typing import NoReturn, Collection, Callable, Iterable, Self\nfrom enum import StrEnum\nfrom functools import partial\n\n\nclass HistoryEmptyException(Exception):\n    pass\n\n\nclass ProgramNotRunningException(Exception):\n    pass\n\n\ndef raise_history_empty_exception(msg: str) -> NoReturn:\n    raise HistoryEmptyException(msg)\n\n\ndef raise_program_not_running_exception(msg: str) -> NoReturn:\n    raise ProgramNotRunningException(msg)\n\n\nraise_program_not_running_partial_fn = partial(\n    raise_program_not_running_exception, msg=\"the program is not running\"\n)\n\n\nclass Structure[T](ABC):\n    @abstractmethod\n    def push(self, element: T) -> Self:\n        pass\n\n    @abstractmethod\n    def pop(self) -> T:\n        pass\n\n    @property\n    @abstractmethod\n    def elements(self) -> Collection[T]:\n        pass\n\n    def __str__(self) -> str:\n        return str(self.elements)\n\n    @property\n    def is_empty(self) -> bool:\n        return len(self.elements) == 0\n\n    def __iter__(self):\n        return iter(self.elements)\n\n\nclass Queue[T](Structure[T]):\n    def __init__(self) -> None:\n        self.__elements: deque[T] = deque()\n\n    def push(self, element: T) -> Self:\n        self.__elements += [element]\n\n        return self\n\n    def pop(self) -> T:\n        return self.__elements.popleft()\n\n    @property\n    def elements(self) -> deque[T]:\n        return self.__elements\n\n\nclass Stack[T](Structure[T]):\n    def __init__(self) -> None:\n        self.__elements: list[T] = []\n\n    def push(self, element: T) -> Self:\n        self.__elements += [element]\n\n        return self\n\n    def pop(self) -> T:\n        return self.elements.pop()\n\n    @property\n    def elements(self) -> list[T]:\n        return self.__elements\n\n\nclass Printable(ABC):\n    @abstractmethod\n    def print(self) -> Self:\n        pass\n\n    @abstractmethod\n    def set_document(self, document: str) -> Self:\n        pass\n\n    @property\n    @abstractmethod\n    def document_history(self) -> Structure[str]:\n        pass\n\n\ndef user_input(prompt: str) -> str:\n    return input(prompt).lower()\n\n\nclass PrinterActions(StrEnum):\n    PRINT: str = \"1\"\n    EXIT: str = \"2\"\n    SHOW_DOCUMENT_HISTORY: str = \"3\"\n    SET_DOCUMENT: str = \"4\"\n\n\nclass Printer(Printable):\n    def __init__(self) -> None:\n        self.__document_history: Queue[str] = Queue[str]()\n\n    def print(self) -> Self:\n        if self.document_history.is_empty:\n            raise_history_empty_exception(\"No documents to print\")\n\n        print(\"Printing...\")\n        print(self.document_history.pop())\n\n        return self\n\n    def set_document(self, document: str) -> Self:\n        self.document_history.push(document)\n\n        return self\n\n    @property\n    def document_history(self) -> Queue[str]:\n        return self.__document_history\n\n\nclass Navegable(ABC):\n    @abstractmethod\n    def go_to_page(self, page: str) -> Self:\n        pass\n\n    @abstractmethod\n    def undo(self) -> Self:\n        pass\n\n    @abstractmethod\n    def redo(self) -> Self:\n        pass\n\n    @abstractmethod\n    def run(self) -> None:\n        pass\n\n    @property\n    @abstractmethod\n    def page_history(self) -> Structure[str]:\n        pass\n\n    @property\n    @abstractmethod\n    def current_page(self) -> str:\n        pass\n\n\nclass WebBrowserActions(StrEnum):\n    EXIT: str = \"exit\"\n    UNDO: str = \"undo\"\n    REDO: str = \"redo\"\n    GO_TO_PAGE: str = \"go_to_page\"\n\n\nclass WebBrowser(Navegable):\n    def __init__(self) -> None:\n        self.__page_history: Stack[str] = Stack[str]()\n        self.__current_page: str = \"inicio\"\n        self.current_page_index: int = 0\n        self.__running = False\n\n    def go_to_page(self, page: str) -> Self:\n        if not self.__running:\n            raise_program_not_running_partial_fn()\n\n        self.page_history.push(self.current_page)\n        self.__current_page = page\n        self.current_page_index += 1\n\n        print(f\"Going to {page}\")\n\n        return self\n\n    def undo(self) -> Self:\n        if not self.__running:\n            raise_program_not_running_partial_fn()\n\n        if self.page_history.is_empty:\n            raise_history_empty_exception(msg=\"there are not previous pages to go back\")\n\n        self.__current_page = self.page_history.elements.pop()\n        print(f\"Going back to {self.current_page}\")\n\n        return self\n\n    def redo(self) -> Self:\n        if not self.__running:\n            raise_program_not_running_partial_fn()\n\n        if self.page_history.is_empty:\n            raise_history_empty_exception(msg=\"there are not next pages to go forward\")\n\n        return self\n\n    def run(self) -> None:\n        self.__running = True\n\n        while self.__running:\n            print(f\"Current page: {self.current_page}\")\n\n    def __operations(self) -> dict[str, Callable]:\n        return {\"go_to_page\": self.go_to_page, \"undo\": self.undo, \"redo\": self.redo}\n\n    @property\n    def page_history(self) -> Stack[str]:\n        return self.__page_history\n\n    @property\n    def current_page(self) -> str:\n        return self.__current_page\n\n\ndef execute_printable(printable: Printable) -> None:\n    while True:\n        print(\"1 - Print, 2 - Exit, 3 - Show document history, 4 - Set document\")\n        user_option = user_input(prompt=\"Choose an option: \")\n\n        match user_option:\n            case PrinterActions.PRINT:\n                try:\n                    printable.print()\n                except HistoryEmptyException as err:\n                    print(err)\n            case PrinterActions.EXIT:\n                print(\"Bye!\")\n                break\n            case PrinterActions.SHOW_DOCUMENT_HISTORY:\n                if printable.document_history.is_empty:\n                    print(\"No documents to print\")\n                    continue\n\n                for document in printable.document_history:\n                    print(document)\n            case PrinterActions.SET_DOCUMENT:\n                document = user_input(prompt=\"Enter a document: \")\n                printable.set_document(document=document)\n                print(f\"Document set: {document} successfully\")\n            case _:\n                print(\"Invalid option\")\n\n\ndef execute_navegable(navegable: Navegable) -> None:\n    navegable.run()\n\n\ndef main() -> None:\n    # Generic queue\n    queue = Queue[int]()\n    queue.push(1)\n    queue.push(2)\n    queue.push(3)\n    print(queue.elements)\n    print(queue.pop())\n    print(queue)\n    print(queue.is_empty)\n\n    # Generic stack\n    stack = Stack[int]()\n    stack.push(1)\n    stack.push(2)\n    stack.push(3)\n    print(stack.elements)\n    print(stack)\n    print(stack.pop())\n\n    print(stack.elements)\n    print(stack)\n    print(stack.is_empty)\n\n    printer = Printer()\n    execute_printable(printable=printer)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/Lio7master.py",
    "content": "#  EJERCICIO:\n#  Implementa los mecanismos de introducción y recuperación de elementos propios de las\n#  pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n#  o lista (dependiendo de las posibilidades de tu lenguaje).\n\n#  DIFICULTAD EXTRA (opcional):\n#  - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n#    de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n#    que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n#    Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n#    el nombre de una nueva web.\n#  - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n#    impresora compartida que recibe documentos y los imprime cuando así se le indica.\n#    La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n#    interpretan como nombres de documentos.\n\n\n# Pila/Stack (LIFO - Last In, First Out)\n\nstack = []\nstack.append(\"1\") #push \nstack.append(\"2\")\nstack.append(\"3\")\n\nprint(stack)\n#pop\nstack_item = stack[len(stack) - 1] \ndel stack[len(stack) - 1]\n\n\n\nprint(stack_item)\nprint(stack)\nprint(stack.pop()) #es un mecanismo nativo de las listas (no en todos los  lenguanjes), internamente en python la lista funciona como una pila/cola con pop.\nprint(stack)\n\n# Cola/Queue (FIFO - Primero en entrar, primero en salir)\n\nqueue = []\n\nqueue.append(1)\nqueue.append(2)\nqueue.append(3)\n\nprint(queue)\n# dequeue\nqueue_item = queue[0]\ndel queue[0]\n\nprint(queue_item)\nprint(queue)\nprint(queue.pop(0)) #el pop lo hacemos del elemento cero porque seria el primero entrar y el primero que debe salir\n\nprint(queue)\n\n# Extra\n\n# WEB\n\ndef web_nav():\n    stack = []\n\n    while True:\n\n        action = input( \"añande una URL o interactua con palabras Adelante/Atras/salir: \")\n\n        if action == \"salir\":\n            print(\"saliendo del programa\")\n            break\n        elif action == \"adelante\":\n            pass \n            #El stack no es fincional para ir para adelante ya que cada que sacamos\n            #un elemento de la pila este desaparece de la mismaa por lo que no \n            #podriamos recuperar amenos que estemos aplicando logica extra que no sea parte del stack\n        elif action == \"atras\":\n            if len(stack) > 0:\n                stack.pop()\n        else:\n            stack.append(action)\n        if len(stack) > 0:\n            print(stack[len(stack)-1])\n        else:\n            print(\"Estas en el inicio.\")\n\nweb_nav()\n\n#Impresora compartida\n\ndef share_printed():\n    queue = []\n\n    while True:\n          action = input(\"Añade documenteso o selecciona instruccion imprimir/salir: \")\n\n          if action == \"salir\":\n              break\n          elif action == \"imprimir\":\n            print(\"------IMPRIMIENDO------\")\n            if len(queue) > 0:\n                print(queue.pop(0))\n            else:\n                print(\"cola de impresion vacia.\")\n          else:\n              queue.append(action)\n\nshare_printed()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/LittleMabbit.py",
    "content": "# Stack / Pilas - LIFO - Last In First Out\n# El último elemento en entrar a una estructura de datos tipo LIFO, es el primero en salir cuando es requerido\n\nstack = []\n# Añadimos a una lista vacía, un conjunto de números con .append.\nstack.append('1')\nstack.append('2')\nstack.append('3')\nstack.append('4')\nstack.append('5')\nstack.append('6')\n\nprint(stack) # Lista.\n\nstack_removed = stack.pop() # El método .pop() remueve el último item de una lista y puede hacer su valor recuperable. \nprint(stack)\nprint(stack_removed) # 6, valor removido mas sí recuperado.\n\n# Cola/Queue - FIFO - First In First Out - El primero que entra en la cola, es el primero que sale.\n\ncola = []\n\ncola.append('Mouse')\ncola.append('Tablet')\ncola.append('Laptop')\ncola.append('Cola')\n\ncola_removed = cola.pop(0) # Eliminamos y obtenemos el valor del elemento 0 dentro de la lista 'cola'.\nprint(cola_removed)\nprint(cola)\n\n'''\nEjercicios\n'''\n\ndef web_browser():\n  stack: list = []\n  \n  while True:\n    action = input('Añade una URL o selecciona entre: adelante / atras / salir:\\n')\n\n    if action == 'salir':\n      print('Saliendo del programa. ¡Hasta luego!')\n      break\n    elif action == 'adelante':\n      # Nos han engañao\n      pass\n    elif action == 'atras':\n      if len(stack) > 0:\n        stack.pop()\n      else:\n        print('Estás en la página de inicio.')\n    else: \n      stack.append(action)\n    \n    if len(stack) > 0:\n      print(f'Has navegado hasta: {stack[len(stack) - 1]}')\n    else:\n      print('Estás en la pagina de inicio.')\n\n# web_browser()\n\ndef printer():\n  queue = []\n\n  while True:\n\n    action = input('Añade un documento a imprimir, o con la palabra: imprimir/salir selecciona tu acción.\\n')\n\n    if action == 'salir':\n      print('Cerrando impresora.')\n      break\n    elif action == 'imprimir':\n      if len(queue) > 0:\n        first_to_print = queue.pop(0)\n        print(f'Imprimiendo: {first_to_print}')\n      else:\n        print('No hay mas elementos en la cola de impresión.')\n    else:\n      queue.append(action)\n\n    # print(f'Cola de impresion: {queue}')\n\nprinter()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/LucasRebuffo.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */ \"\"\"\n\n\"\"\" Pilas / Stacks  --> LIFO \"\"\"\n\n\"\"\" En python no existen las pilas o colas como tal pero usando listas se puede suplir ese\n    requerimiento.\"\"\"\n\npila = [\"Lunes\", \"Martes\"]\n\n\"\"\" Por ejemplo: un push se podria ver como un ... \"\"\"\n\npila.append(\"miercoles\")\nprint(pila)\n\n\"\"\" Un pop se veria como: \"\"\"\n\nprint(pila.pop())\nprint(pila)\n\n\n\"\"\" Colas / Queues  --> FIFO\"\"\"\n\ncola = [\"Manzana\", \"Pera\"]\n\n\"\"\" Un queue item seria igual \"\"\"\n\ncola.append(\"Sandia\")\nprint(cola)\n\n\"\"\" un unqueue item seria \"\"\"\n\nprint(cola.pop(0))\nprint(cola)\n\n\n\"\"\" * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */  \"\"\"\n\n\ndef navegador():\n\n    historial = []\n    actual = 0\n    print(\"Salir - Para salir del sistema\")\n    print(\"adelante - Para avanzar en el hisotrial\")\n    print(\"atras - Para retroceder en el hisotrial\")\n    print(\"URL - Para navegar a la URL\")\n    print(\"----------------------------------------\")\n\n    while 1:\n\n        command = input(\"Ingrese un comando.\")\n        print(\"\")\n\n        match command:\n            case \"salir\":\n                print(\"Saliendo del sistema ...\")\n                break\n\n            case \"adelante\":\n\n                actual += 1\n\n                if actual - 1 >= len(historial):\n                    actual = len(historial)\n                    print(\"Ya no se puede avanzar mas\")\n                    print(\"------------------------------------------\")\n                else:\n                    print(f\"Se avanzo a la pagina {historial[actual-1]}\")\n                    print(\"------------------------------------------\")\n\n            case \"atras\":\n\n                if actual <= 1:\n                    actual = 0\n                    print(\"Ya no se puede retroceder mas\")\n                    print(\"------------------------------------------\")\n                else:\n                    actual -= 1\n                    print(f\"Se retrocedio a la pagina {historial[actual-1]}\")\n                    print(\"------------------------------------------\")\n\n            case _:\n\n                historial = historial[0:actual]\n                historial.append(command)\n\n                actual += 1\n\n                print(f\"Se navego al pagina {historial[actual-1]}\")\n                print(\"------------------------------------------\")\n\n\n# navegador()\n\n\ndef impresora():\n\n    cola = []\n    while 1:\n\n        op = input(\"Ingrese operacion [nombre_documento|imprimir]\\n\")\n\n        match op:\n            case \"salir\":\n                print(\"Saliendo ...\")\n                break\n            \n            case \"imprimir\":\n\n                if len(cola) > 0:\n                    documento = cola.pop(0)\n                    print(f\"Imprimiendo docuemnto '{documento}' ...\")\n                else:\n                    print(\"No hay nada que imprimir ...\")\n\n            case _:\n                cola.append(op)\n                print(f\"Documento '{op}' ingresado en cola\")\n\nimpresora()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/Lumanet.py",
    "content": "# PILAS Y COLAS\n\n# stack o pila - LIFO (Last In, First Out)\nstack = []\nprint(\"Pila (stack) inicial =>\", stack) # -> []\nstack.append(1) # Añade valores a la pila (stack)\nstack.append(2)\nstack.append(3)\nprint(f\"Pila (stack) después de varios appends: stack.append(x) => {stack}\") # -> [1, 2, 3]\npopped = stack.pop() # Elimina el último elemento de la pila (stack)\nprint(f\"Último elemento de la pila (stack) eliminado: stack.pop() => {popped}\") # -> 3\nprint(f\"Pila (stack) después de eliminar el último elemento => {stack}\\n\") # -> [1, 2]\n\n# queue o cola - FIFO (First In, First Out)\nqueue = []\nprint(\"Cola (queue) inicial =>\", queue) # -> []\nqueue.append(\"a\") # Añade valores a la cola (queue)\nqueue.append(\"b\")\nqueue.append(\"c\")\nprint(f\"Cola (queue) después de varios appends: queue.append(x) => {queue}\") # -> ['a', 'b', 'c']\npopFirst = queue.pop(0) # Elimina el primer elemento de la cola (queue)\nprint(f\"Último elemento de la cola (queue) eliminado: queue.pop(0) => {popFirst}\") # -> a\nprint(f\"Cola (queue) después de eliminar el primer elemento => {queue}\\n\") # -> ['b', 'c']\n\n\"\"\" \nDIFICULTAD EXTRA (opcional):\n- Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n  de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n  que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n  Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n  el nombre de una nueva web.\n- Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n  impresora compartida que recibe documentos y los imprime cuando así se le indica.\n  La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n  interpretan como nombres de documentos.\n\"\"\"\ndef web_navigation():\n    stack = []\n    while True:\n        action = input(\n            \"Añade una url o interactúa con palabras adelante/atrás/salir: \"\n        )\n        if action == \"salir\":\n            print(\"Saliendo...\")\n            break\n        elif action == \"adelante\":\n            pass\n        elif action == \"atrás\":\n            if len(stack) > 0:\n                stack.pop()\n        else:\n            stack.append(action)\n        if len(stack) > 0:\n            print(f\"Estás en la web: {stack[len(stack) - 1]}.\")\n        else:\n            print(\"Estás en la página de inicio.\")\n\ndef shared_printed():\n    queue = []\n    while True:\n        action = input(\"Añade un documento o selecciona imprimir o salir: \")\n        if action == \"salir\":\n            break\n        elif action == \"imprimir\":\n            if len(queue) > 0:\n                print(f\"Imprimiendo: {queue.pop(0)}...\")\n            else:\n                print(\"No hay documentos en la cola de impresión.\")\n        else:\n            queue.append(action)\n        print(f\"Cola de impresión: {queue}\")\n\nweb_navigation()\nshared_printed()\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/Maanghel.py",
    "content": "\"\"\"\nEJERCICIO:\nImplementa los mecanismos de introducción y recuperación de elementos propios de las\n    pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n    o lista (dependiendo de las posibilidades de tu lenguaje).\n\nDIFICULTAD EXTRA (opcional):\n- Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n    de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n    que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n    Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n    el nombre de una nueva web.\n- Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n    impresora compartida que recibe documentos y los imprime cuando así se le indica.\n    La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n    interpretan como nombres de documentos\n\"\"\"\n\ndef stack_example():\n    \"\"\"Stacks example (LIFO)\"\"\"\n    stack = []\n    while True:\n        print(\"\\nSeleccione una opcion:\")\n        print(\"1. Ingresar dato\\n2. Eliminar dato\\n3. Mostrar stack\\n4. Salir\")\n        option = input(\"\\n-> \")\n\n        match option:\n            case \"1\":\n                data = input(\"Ingrese el dato: \")\n                stack.append(data)\n            case \"2\":\n                if stack:\n                    print(stack.pop())\n                else:\n                    print(\"El stack está vacío.\")\n                input()\n            case \"3\":\n                print(f\"Contenido del stack:\\n{stack}\")\n                input()\n            case \"4\":\n                print(\"Saliendo del ejemplo de Stack\")\n                break\n\ndef queue_example():\n    \"\"\"Queue example (FIFO)\"\"\"\n    queue = []\n    while True:\n        print(\"\\nSeleccione una opcion:\")\n        print(\"1. Ingresar dato\\n2. Eliminar dato\\n3. Mostrar cola\\n4. Salir\")\n        option = input(\"\\n-> \")\n\n        match option:\n            case \"1\":\n                data = input(\"Ingrese el dato: \")\n                queue.append(data)\n            case \"2\":\n                if queue:\n                    print(f\"Se ha eliminado {queue.pop(0)}\")\n                else:\n                    print(\"La queue está vacía.\")\n                input()\n            case \"3\":\n                print(f\"Contenido de la queue:\\n{queue}\")\n                input()\n            case \"4\":\n                print(\"Saliendo del ejemplo de queue\")\n                break\n\n# queue_example()\n# stack_example()\n\n# EXTRA\n\ndef web_navigation():\n    \"\"\"Web navigation example\"\"\"\n    historial = []\n    adelante = []\n\n    while True:\n        option = input(\"Ingrese una URL o seleccione adelante/atras/salir: \").lower()\n\n        if option == \"salir\":\n            print(\"Saliendo del navegador web.\")\n            break\n        elif option == \"atras\":\n            if len(historial) > 1:\n                adelante.append(historial.pop())\n            else:\n                print(\"No puedes ir más atrás.\")\n        elif option == \"adelante\":\n            if adelante:\n                historial.append(adelante.pop())\n            else:\n                print(\"No puedes ir más adelante.\")\n        else:\n            historial.append(option)\n            adelante.clear()\n\n        if historial:\n            print(f\"Estás en: {historial[-1]}\")\n        else:\n            print(\"Estás en la página de inicio.\")\n\ndef printer():\n    \"\"\"shared printer example\"\"\"\n    queue = []\n\n    while True:\n        option = input(\n            \"Añada un documento o seleccione imprimir/cola/salir: \"\n        ).lower()\n\n        if option == \"salir\":\n            print(\"Saliendo de la impresora.\")\n            break\n        elif option == \"imprimir\":\n            if queue:\n                print(f\"Imprimiendo {queue.pop(0)}\")\n            else:\n                print(\"No hay documentos en la cola.\")\n        elif option == \"cola\":\n            if len(queue) > 0:\n                print(f\"Cola de impresion:\\n{queue}\")\n            else:\n                print(\"No hay documentos en la cola.\")\n        else:\n            queue.append(option)"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/MarcosE-FerretoE.py",
    "content": "\"\"\"\nEjercicio \n\"\"\"\n\n# Pilas/Stack (LIFO)\nstack = []\nstack.append(1)  # push\nstack.append(2)  # push\nstack.append(3)  # push\n\nprint(stack)\n\n# pop\nstack_item = stack[len(stack) - 1]\ndel stack[len(stack) - 1]\nprint(stack_item)\n\nprint(stack.pop())\n\nprint(stack)\n\n# Cola/Queue (FIFO)\n\nqueue = []\nqueue.append(1)  # enqueue\nqueue.append(2)  # enqueue\nqueue.append(3)  # enqueue\n\n# dequeue\nqueue_item = queue[0]\ndel queue[0]\nprint(queue_item)\n\nprint(queue.pop(0))\n\nprint(queue)\n\n\"\"\"\nDIFICULTAD EXTRA\n\"\"\"\n\n\ndef web_navigation():\n    stack = []\n\n    while True:\n        action = input(\"Añade una url o interactúa con palabras atrás/salir: \")\n\n        if action == \"salir\":\n            print(\"Saliendo del navegador web\")\n            break\n        elif action == \"atrás\":\n            if len(stack) > 0:\n                print(stack.pop())\n            else:\n                print(\"No se pueden interactuar con palabras antes de añadir una \")\n        else:\n            stack.append(action)\n\n        if len(stack) > 0:\n            print(f\"Has navegado a la web: {stack[len(stack) - 1]}\")\n        else:\n            print(\"Estás en la página de inicio.\")\n\n\n# web_navigation()\n\n\ndef shared_printed():\n    queue = []\n\n    while True:\n        action = input(\"Añade un documento o selecciona imprimir/salir: \")\n\n        if action == \"salir\":\n            break\n        elif action == \"imprimir\":\n            if len(queue) > 0:\n                print(f\"Imprimiendo: {queue.pop(0)}\")\n            else:\n                print(\n                    \"No se pueden interactuar con palabras antes de añadir una impresión\"\n                )\n        else:\n            queue.append(action)\n\n        if len(queue) > 0:\n            print(f\"Cola de impresión: {queue}\")\n        else:\n            print(\"Estás en la cola de inicio.\")\n\n\nshared_printed()\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/MirandaYuber.py",
    "content": "\"\"\"\nPilas y colas\n\"\"\"\n\n# Pila/Stack (LIFO/Ultimo en entrar, primero en salir)\nitems_pila = []\n\n\ndef apilar(item):\n    items_pila.append(item)\n\n\ndef desapilar():\n    if len(items_pila) > 0:\n        items_pila.pop()\n    else:\n        print('La pila esta vacia.')\n\n\ndef pila_vacia():\n    return len(items_pila) == 0\n\n\ndef tamaño_pila():\n    return len(items_pila)\n\n\napilar(1)\napilar(2)\napilar(3)\nprint(f'Items de la pila al apilar: {items_pila}')\ndesapilar()\nprint(f'Items de la pila al desapilar: {items_pila}')\nprint(f'La pila esta vacia: {pila_vacia()}')\nprint(f'Tamaño de la pila: {tamaño_pila()}')\nprint()\n\n\n# Cola/Queue (FIFO/Primero en entrar, primero en salir)\nitems_cola = []\n\n\ndef agregar_a_la_cola(item):\n    items_cola.insert(0, item)\n\n\ndef quitar_de_la_cola():\n    if len(items_cola) > 0:\n        items_cola.pop()\n    else:\n        print('La cola esta vacia.')\n\n\ndef cola_vacia():\n    return len(items_cola) == 0\n\n\ndef tamaño_cola():\n    return len(items_cola)\n\n\nagregar_a_la_cola(1)\nagregar_a_la_cola(2)\nagregar_a_la_cola(3)\nprint(f'Items de la cola despues de agregar a la cola: : {items_cola}')\nquitar_de_la_cola()\nprint(f'Items de la cola despues de quitar de la cola: : {items_cola}')\nprint(f'Items de la cola: : {items_cola}')\nprint(f'La cola esta vacia: {cola_vacia()}')\nprint(f'Tamaño de la cola: : {tamaño_cola()}')\nprint()\n\n\"\"\"\nEXTRA\n\"\"\"\n\n\ndef navegador():\n    paginas = []\n    ultima_pagina = ''\n\n    while True:\n        accion = input(\n            'Ingrese una pagina o interactue con las palabras atras/adelante/salir: '\n        ).lower()\n\n        match accion:\n            case 'atras':\n                if len(paginas) > 0:\n                    ultima_pagina = paginas.pop()\n            case 'adelante':\n                if ultima_pagina != '':\n                    paginas.append(ultima_pagina)\n            case 'salir':\n                break\n            case _:\n                paginas.append(accion)\n\n        if len(paginas) > 0:\n            print(f'Esta en la página: {paginas[-1]}')\n        else:\n            print('Esta en la paina de inicio.')\n\n\nnavegador()\n\n\ndef impresora():\n    documentos = []\n\n    while True:\n        accion = input('Ingrese un documento o interactue con las palabras imprimir/listar/salir: ')\n\n        match accion:\n            case 'imprimir':\n                if len(documentos) > 0:\n                    documento_impreso = documentos.pop()\n                    print(f'Se ha impreso el documento: {documento_impreso}')\n            case 'salir':\n                break\n            case 'listar':\n                if len(documentos) > 0:\n                    for documento in documentos:\n                        print(documento)\n            case _:\n                documentos.insert(0, accion)\n                print(f'Ha agregado a la cola de impresión el documento: {accion}')\n\n        if len(documentos) == 0:\n            print('No hay documentos en cola de impresión.')\n\n\nimpresora()\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/NeosV.py",
    "content": "# pila\nstack = []\n\nstack.append(1)\nstack.append(2)\nstack.append(3)\nstack.append(4)\n\nprint(stack)\nprint (stack.pop())\nprint(stack)\n\n\"\"\"\"La pila ingresa varios valores pero al usar el pop siempre va a sacar el ultimo item (de la derecha)\"\"\"\n\nqueue = []\n\nqueue.append(1)\nqueue.append(2)\nqueue.append(3)\nqueue.append(4)\n\nprint(queue)\nprint(queue.pop(0))\nprint (queue)\n\n\"\"\"la fila ingresa varios valores pero al usar el pop en el indice 0 siempre va a sacar el primer item (de la izquierda)\"\"\"\n\n#Ejercicios dificultad Extra\n\n\ndef paginaweb():\n\n    stack = []\n\n    while True:\n\n        accion = input(\"Añade una url o la accion que quieras: adelante/atras/salir\")\n\n        if accion == \"salir\":\n            print (\"saliendo de la web\")\n            break\n        elif accion == \"adelante\":\n            pass\n        elif accion == \"atras\":\n            if len(stack) > 0:\n             stack.pop()\n        else:\n            stack.append(accion)\n\n        if len(stack) > 0:\n\n            print(f\"estas en la web: {stack[len(stack)-1]}\")   \n           \n        else:\n            print(\"estas en el inicio\") \n            \n\n\ndef impresora():\n\n    queue = []\n\n    while True:\n        accion = input(\"porfavor indica el nombre del documento a agregar ola accion que quieres hacer: imprimir/salir \" )\n\n        if accion == \"imprimir\":\n\n            if len(queue) > 0:\n             print(f\"El Documento {queue.pop(0)} ha sido impreso\")\n            else:\n                print(\"no hay documentos para imprimir\") \n\n        elif accion == \"salir\":\n            print(\"saliendo de la impresora\")\n            break\n         \n        else:\n            queue.append(accion)  \n            print(f\"documento {accion} agregado\")\n\nimpresora()            "
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/NicoHeguaburu.py",
    "content": "# #Pila/Stack (LIFO) Last In First Out\n\n# stack = []\n# stack.append(\"1\")\n# stack.append(\"2\")\n# stack.append(\"3\")\n\n\n# print(stack)\n\n# stack_last = stack[len(stack) - 1]\n# del stack[len(stack) - 1]\n\n\n# print(stack.pop())\n\n# print(stack_last)\n# print(stack)\n\n\n\n# #Cola/Queue   (FIFO) Firs In First Out\n\n# queue = []\n# queue.append(\"1\")\n# queue.append(\"2\")\n# queue.append(\"3\")\n\n\n# queue_first = queue[0]\n# del queue[0]\n\n\n# print(queue.pop(0))\n\n# print(queue)\n\n\n\n#Dificultad Extra\n\n#Web\n# stack = []\n\n\n\n# def navegar(url):\n#     print(f\"Usted esta visualizando la pagina {url}\")\n#     stack.append(url)\n#     menu()\n\n\n# def ir_atras():\n#     stack.pop()\n#     print(f\"Usted esta visualizando la pagina {stack[len(stack) - 1]}\")\n#     menu()\n\n# # def ir_adelante(): No es posible deberia usar listas XD\n\n# def menu():\n#     print(\"NAVEGADOR DE NICOLAS HEGUABURU\")\n#     print(\"1----------Navegar en la web\")\n#     print(\"2----------Ir hacia atras\")\n#     print(\"3----------Ir hacia adelante\")\n#     print(\"4----------Salir\")\n#     i = input(\"Selecciona una opccion...\")\n\n#     if i == \"1\":\n#         pag = input(\"a que pagina quieres ir...\")\n#         navegar(pag)\n#     elif i == \"2\":\n#         ir_atras()\n#     elif i == \"3\":\n#         print(\"No es posible ir adelante con pilas XD\")\n#     elif i == \"4\":\n#         exit()\n#     else:\n#         print(\"seleccione una opcion valida\")\n#         menu()\n\n# menu()\n\n\n\n\n\n\n\n#Impresora compartida\ncola = []\ndef menu_impresora():\n    print (\"1------------Ingresar Documento\")\n    print (\"2------------Imprimir un documento de la cola\")\n    print (\"3------------Salir\")\n    i = input(\"ingrese una opcion...\")\n\n    if i == \"1\":\n        agregar_documento()\n    elif i == \"2\":\n        imprimir_documento()\n    elif i == \"3\":\n        exit()\n    else:\n        print(\"ingrese una opcion valida!!!\")\n    \n\ndef agregar_documento():\n    doc = input(\"Ingrese el nombre del documento...\")\n    cola.append(doc)\n    print(f\"El documento {doc} se a ingresado con exito.\")\n    menu_impresora()\n\n\ndef imprimir_documento():\n    if len(cola) > 0:\n        print(f\"el documento {cola[0]} se imprimio correctamente\")\n        cola.pop(0)\n        menu_impresora()\n    else:\n        print(\"La cola de impresion esta vacia. Porfavor ingrese un documento\")\n        menu_impresora()\n\n\nmenu_impresora()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/Nicojsuarez2.py",
    "content": "# #07 PILAS Y COLAS\n> #### Dificultad: Media | Publicación: 12/02/24 | Corrección: 19/02/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/NightAlchemist.py",
    "content": "#stacks\n\nstack = [\"a\", \"b\", \"c\"]\nstack.append(\"d\")\nstack.append(\"e\")\nstack.pop()\n\nprint(stack)\n\n#queues\n\nqueue = [\"a\", \"b\", \"c\"]\nqueue.append(\"d\")\nqueue.append(\"e\")\nqueue.pop(0)\n\nprint(queue)\n\n#deque\n\nfrom collections import deque\n\nqueue = deque([\"a\", \"b\", \"c\"])\nqueue.append(\"d\")\nqueue.append(\"e\")\nqueue.popleft()\n\nprint(queue)\n\n'''\nExtra\n'''\n\n\n\n#Stack\n\ndef back_and_forth():\n    history = []\n    ahead = []\n    \n    while True:\n        command = input(\"Enter a website, 'back' to go back, 'forward' to go forward, or 'exit' to quit: \")\n\n        if command == \"exit\":\n            break\n        elif command == \"back\":\n            if len(history) > 1:\n                ahead.append(history.pop())\n                print(\"Current:\", history[-1])\n            else:\n                print(\"No more history to go back to.\")\n        elif command == \"forward\":\n            if ahead:\n                history.append(ahead.pop())\n                print(\"Current:\", history[-1])\n            else:\n                print(\"No forward history available.\")\n        else:\n            history.append(command)\n            ahead.clear()\n            print(\"Current:\", command)\n\nback_and_forth()\n\n#Queue\n\ndef printer():\n    print_queue = []\n    \n    while True:\n        command = input(\"Enter a document name to add to the queue, 'print' to print, or 'exit' to quit: \")\n\n        if command == \"exit\":\n            break\n        elif command == \"print\":\n            if print_queue:\n                print(\"Printing:\", print_queue.pop(0))\n            else:\n                print(\"The queue is empty. No documents to print.\")\n        else:\n            print_queue.append(command)\n            print(f\"'{command}' added to the queue.\")\n\nprinter()\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/Nightblockchain30.py",
    "content": "'''\n/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n'''\n\n# <<<< PILAS >>>>\npila =  [1,2,3,4,5]\n\n## ¿Cómo puedo introducir elementos nuevos a mi pila?-> Método append()\npila.append(6)\nprint(pila)\n## ¿Cómo puedo recuperar elementos de mi pila? Teniendo en cuenta el formata LIFO -> Método pop()\nelemento_extraido_pila = pila.pop();\nprint(f\"Estado pila: {pila}, Elemento extraido = {elemento_extraido_pila}\")\n\n# CASO DE USO\nfor i in range(len(pila)):\n    elemento_target = pila.pop()\n    print(pila)\n\n\n# <<<< COLAS >>>>\ncola = [1,2,3,4,5]\n## ¿Cómo puedo introducir elementos nuevos a mi cola?-> Método append()\ncola.append(6)\nprint(cola)\n## ¿Cómo puedo recuperar elementos de mi cola? Teniendo en cuenta el formata FIFO -> Método pop()\nelemento_extraido_cola = cola.pop(0)\nprint(f\"Estado cola: {cola}, Elemento extraido = {elemento_extraido_cola}\")\n\n# CASO DE USO\nfor i in range(len(cola)):\n    elemento_target = cola.pop(0)\n    print(cola)\n\n\n\n\n#  * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n#  *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n#  *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n#  *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n#  *   el nombre de una nueva web.\n\nhistorial_navegación = []\n\nwhile True:\n    option = int(input(\"¿Qué deseas hacer en nuestro navegador? Ir a una página (1) | Adelante (2) | Atrás (3) | Salir (4) \\n\"))\n\n    match option:\n        case 1:\n            path = str(input(f\"Introduce la ruta a la cual deseas ir: \\n\"))\n            #Agregamos al historial la web visitada\n            historial_navegación.append(path)\n        case 2:\n            pass\n        case 3:\n                if len(historial_navegación) > 0:\n                    historial_navegación.pop()\n        case 4: \n            print(\"Saliendo del navegador web\")\n            break\n    \n    if len(historial_navegación) > 0:\n        print(f\"Estado Historial: {historial_navegación}\")\n    else:\n        print(\"Estás en la página principal\")\n\n# - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n#  *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n#  *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n#  *   interpretan como nombres de documentos.\n\ndef shared_printer():\n    queue = []\n\n    while True:\n        option = str(input(\"Introduce el documento que deseas añadir o la palabra 'imprimir' para imprimir o 'salir' \\n\"))\n    \n        if option == \"salir\":\n            break\n        elif option == \"imprimir\":\n            print(f\"Imprimiendo el documento {queue.pop(0)}\")\n        else:\n            queue.append(option)\n\n        if len(queue) > 0:\n            print(queue)\n        else:\n            print(\"La cola de impresión esta vacía! \")\n\n\nshared_printer()\n\n\n\n\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/Paprikaistkrieg.py",
    "content": "#pilas y colas\n\n\n\n#Pilas (stack LIFO - Last In, First Out)\n\n\"\"\"\nlas pilas y colas son estructuras de datos fundamentales en la programación\nque permiten almacenar y gestionar colecciones de elementos de manera eficiente.\nUna pila (stack) es una estructura de datos que sigue el principio LIFO (Last In, First Out),\n lo que significa que el último elemento en ser añadido a la pila es el primero en ser removido. \n Las operaciones principales en una pila son:\n\n \"push\" (añadir un elemento a la cima de la pila) y\n\n\"pop\" (remover el elemento de la cima de la pila). \n\nLas pilas son útiles para tareas como la gestión de llamadas a funciones,\nla evaluación de expresiones y la navegación por el historial.\n\nLas pilas se pueden implementar utilizando listas, ya que a nivel conceptual,\nuna lista permite añadir y eliminar elementos de un extremo de manera eficiente.\nSin embargo, para aplicaciones que requieren un rendimiento óptimo,\nes recomendable utilizar la biblioteca collections, \nque proporciona una estructura de datos especializada llamada deque (double-ended queue).\nDeque permite añadir y eliminar elementos de ambos extremos de manera eficiente,\nlo que la hace ideal para implementar pilas y colas.\nAquí tienes un ejemplo básico de cómo implementar una pila utilizando una lista en Python:\n\"\"\"\n\nfrom inspect import stack\n\nfrom operator import truediv\n\nfrom argparse import Action\n\n\nstack = []  # Creamos una pila vacía\n#para añadir elementos a la pila, utilizamos el método append() \n\n#PUSH\n\nstack.append(1)  # Añadimos el elemento 1 a la pila\nstack.append(2)  # Añadimos el elemento 2 a la pila\nstack.append(3)  # Añadimos el elemento 3 a la pila\n\nprint(stack)  # Imprimimos la pila actual\n\n#POP\n\n# Para eliminar elementos de la pila, utilizamos el método pop(remover el elemento de la cima de la pila)\nstack_item = stack[len(stack)-1]  # Obtenemos el elemento de la cima de la pila \ndel stack[len(stack)-1] # Removemos el elemento de la cima de la pila que en esencia es lo que hace pop\nelemento = stack.pop()  # Removemos el elemento de la cima de la pila\nprint(elemento)  # Imprimimos el elemento removido\nprint(stack)  # Imprimimos la pila actual después de la operación pop\n\n#lo que se entiende por lista es internamente una pila, ya que el último elemento añadido es el primero en ser removido.\n\n\n\n#Cola / queue ( FIFO - First In, First Out)\n\n\"\"\"\nUna cola (queue), por otro lado, sigue el principio FIFO (First In, First Out), \nlo que significa que el primer elemento en ser añadido a la cola es el primero en ser removido. \nLas operaciones principales en una cola son:\n\n\"enqueue\" (añadir un elemento al final de la cola) y \n\n\"dequeue\" (remover el elemento del frente de la cola). \n\nLas colas son útiles para tareas como la gestión de tareas en sistemas operativos,\nla impresión de trabajos y la simulación de procesos.\nLas pilas y colas se pueden implementar utilizando listas o la biblioteca collections,\nque proporciona estructuras de datos especializadas como deque (double-ended queue) para colas.\n\"\"\"\n\nqueue = []  # Creamos una cola vacía\n#para añadir elementos a la cola, utilizamos el método append()\n\n#ENQUEUE (encolar) \nqueue.append(1)  # Añadimos el elemento 1 a la cola\nqueue.append(2)  # Añadimos el elemento 2 a la cola\nqueue.append(3)  # Añadimos el elemento 3 a la cola\n\nprint(queue)  # Imprimimos la cola actual\n\n#DEQUEUE (desencolar)\n\n# Para eliminar elementos de la cola, utilizamos el método pop(0) (remover el elemento del frente de la cola)\n\nqueue_item = queue[0]  # Obtenemos el elemento del frente de la cola\ndel queue[0]  # Removemos el elemento del frente de la cola\n\n#tambien \nqueue_item = queue.pop(0)  # Removemos el elemento del frente de la cola\n\nprint(queue_item)  # Imprimimos el elemento removido\nprint(queue)  # Imprimimos la cola actual después de la operación dequeue\n\n#lo que se entiende por lista es internamente una cola, ya que el primer elemento añadido es el primero en ser removido.\n#Sin embargo, para aplicaciones que requieren un rendimiento óptimo, es recomendable utilizar la biblioteca collections,\n#que proporciona una estructura de datos especializada llamada deque (double-ended queue).\n\n\n#XTRAJ\n\ndef web_navigation():\n    stack = []\n\n    while True:\n        action = input(\"añade una url o interactua con palabras como adelante, atras o salir: \")\n       \n        if action == \"salir\":\n            print(\"saliendo del navegador Web.\")\n            break\n        elif action == \"adelante\":\n            pass\n        elif action == \"atras\":\n            if len(stack) > 0:\n                stack.pop()\n                if stack:\n                    print(f\"Navegando hacia atrás: {stack[-1]}\")\n                else:\n                    print(\"Estas en la pagina de inicio.\")\n            else:\n                print(\"Estas en la pagina de inicio.\")\n        else:\n            stack.append(action)\n        if len(stack) > 0:\n            print(f\"Has navegado a la Web: {stack[-1]}\")\n        \n \nweb_navigation()\n\ndef impresora():\n    queue = []\n\n    while True:\n        action = input(\"Añade un documento o selecciona imprimir/salir:\")\n        if action == \"salir\":\n            print(\"Saliendo de la impresora.\")\n            break\n        elif action == \"imprimir\":\n            pass\n            if len(queue) > 0:\n                print(f\"Imprimiendo documento: {queue.pop(0)}\")\n            else:\n                print(\"No hay documentos en la cola para imprimir.\")\n        else:\n            queue.append(action)\n            print(f\"Documento añadido a la cola: {queue}\")\n\nimpresora()\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/Paula2409.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n\n */\"\"\"\n \n\"\"\" Stacks - LIFO \"\"\"\nstack = []\n# Insert element (end)\nstack.append(1)\nstack.append(2)\nstack.append(3)\nstack.append(4)\nprint(f'Stack: {stack}')\n\n# Remove element (last)\nstack.pop()\nstack.pop()\nprint(f'Stack: {stack}')\n\n\"\"\" Queues - FIFO \"\"\"\nqueue = []\n# Insert element (first)\nqueue.insert(0,1)\nqueue.insert(0,2)\nqueue.insert(0,3)\nprint(f'Queue: {queue}')\n\n# Remove element(last)\nqueue.pop()\nqueue.pop()\nprint(f'Queue: {queue}')\n\n\"\"\" * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atras\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n\"\"\"\ndef website():\n    page = []\n    history = []\n    print(f'''\n    Ingrese donde desea desplazarse:\n    * nueva web\n    * adelante\n    * atras\n    * salir\n    ''')\n    option = input()\n    while option != 'salir':\n        if option == \"adelante\":\n            if len(history) != 0:\n                page.append(history[0])\n                print(f\"Ahora se encuentra en la pagina {history.pop(0)}\")\n            else:\n                print(\"Ya se encuentra en la ultima pagina visitada\")\n        elif option == 'atras':\n            if len(page) == 0:\n                print(\"Error. Se encuentra en la primer pagina del sitio web\")\n            else:\n                print(f\"Se encuentra en la pagina: {history.append(page.pop())}\")\n        elif option == 'nueva web':\n            web = input(\"Ingrese nombre nueva pagina web: \")\n            page.append(web)\n        print(f'''\n        Ingrese donde desea desplazarse:\n        * nueva web\n        * adelante\n        * atras\n        * salir\n        ''')\n        option = input()\n\ndef printer():\n    queue = []\n    option = input(\"Ingrese 'imprimir' si desea imprimir un documento, de lo contrario, indique nuevo documento para agregar a la cola de impresion. Si desea salir del programa indique 'salir': \")\n\n    while option != 'salir':\n        if option == 'imprimir':\n            if len(queue) == 0:\n                print(\"No hay documentos en la cola de impresion\")\n            else:\n                printer = queue.pop()\n                print(f\"Se imprimio el documento {printer}\")\n        else:\n            queue.insert(0,option)\n            print(f\"Se agrega el documento {option} a la cola de impresion\")\n        option = input(\"Ingrese 'imprimir' si desea imprimir un documento, de lo contrario, indique nuevo documento para agregar a la cola de impresion. Si desea salir del programa indique 'salir': \")\nwebsite()\nprinter()\n    "
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/RicardiJulio.py",
    "content": "#  * EJERCICIO:\n#  * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n#  * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n#  * o lista (dependiendo de las posibilidades de tu lenguaje).\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n#  *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n#  *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n#  *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n#  *   el nombre de una nueva web.\n#  * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n#  *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n#  *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n#  *   interpretan como nombres de documentos.\n\nfrom collections import deque\n\n# Estructura LIFO\n\nstack = [10,20,30]\nstack.append(40)\nprint(stack)\nstack.pop()\nprint(stack)\n\n# Estructura FIFO\n\nqueue = deque([10,20,30])\nqueue.append(40)\nprint(queue)\nqueue.popleft()\nprint(queue)\n\n# DIFICULTAD EXTRA:\n\ndef navegador():\n    pila_adelante = ['youtube.com','google.com','twitch.com','amazon.com','x.com']\n    pila_atras = []\n    pagina_actual = 'Inicio'\n    \n    print(f'Estas en {pagina_actual}')\n    \n    while True:\n        entrada = input('Ingresa una URL, \"atras\", \"adelante\" o \"salir\": ').strip().lower()\n        \n        if entrada == 'salir':\n            print('Estas saliendo del navegador')\n            break\n        elif entrada == 'adelante':\n            if pila_adelante:\n                pila_atras.append(pagina_actual)\n                pagina_actual = pila_adelante.pop()\n                print(f'Estas en {pagina_actual}')\n            else:\n                print('No hay mas paginas adelantes.')\n        elif entrada == 'atras':\n                if pila_atras:\n                    pila_adelante.append(pagina_actual)\n                    pagina_actual = pila_atras.pop()\n                    print(f'Estas en {pagina_actual}')\n                else:\n                    print('No hay mas paginas atras.')\n        else:\n            pila_atras.append(pagina_actual)\n            pagina_actual = entrada\n            pila_adelante.clear()\n            print(f'Estas en {pagina_actual}')\n\n\ndef impresora():\n    cola = deque([])\n    \n    while True:\n        entrada = input('Indique una accion a seguir:\\nEscriba el nombre del documento para añadirlo a la cola.\\nEscriba \"imprimir\" para dar paso al primer documento en la cola.\\nEscriba \"salir\" para salir de la impresora.\\n').strip().lower()\n        if entrada == 'imprimir':\n            if cola:\n                print (cola[0])\n                cola.popleft()\n            else:\n                print('No hay nada en cola para imprimir')\n        elif entrada == 'salir':\n            break         \n        elif entrada != 'imprimir':\n            print(f'El documento {entrada} ha sido ha añadido a la cola de impresion')\n            cola.append(entrada)\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/RoniPG.py",
    "content": "# @Roni\n\n\"\"\"\nEJERCICIO: Implementa los mecanismos de introducción y recuperación de elementos propios de las pilas (stacks - LIFO)\ny las colas (queue - FIFO) utilizando una estructura de array o lista (dependiendo de las posibilidades de tu lenguaje).\n\"\"\"\n\n\"\"\"PILA (STACK)\"\"\"\n\n\"\"\"Creamos una lista y la utilizamos como pila\"\"\"\n\npila= [1,2,3]\n\n\"\"\"Insertar datos\"\"\"\n\nprint(pila)\npila.append(4)\npila.append(5)\nprint(pila)\n\n\"\"\"Borrar datos\"\"\"\nprint(f\"Contenido de la pila: {pila}\")\npila.remove(1) # --> Borrar dato en la posicion deseada\nprint(f\"Contenido de la pila despues del remove(1): {pila}\")\n#pila.clear() --> Eliminar(limpiar) todos los datos de la lista\nprint(f\"Contenido de la pila: {pila}\")\nelementoCima=pila.pop() # ---> Borrar dato en la cima de la pila con un return del dato\nprint(f\"Contenido de la pila despues del pop(): {pila}\")\nprint(f\"Elemento en la cima de la pila: {elementoCima}\")\n\n\"\"\"Actualizar datos\"\"\"\n\nprint(f\"Contenido de la pila: {pila}\")\npila.insert(0,1)\nprint(f\"Contenido de la pila despues del insert(0,1): {pila}\")\n\n\"\"\"Ordenar datos\"\"\"\n\npila.append(8)\npila.append(5)\npila.append(7)\nprint(f\"Contenido de la pila: {pila}\")\npila.sort()\nprint(f\"Contenido de la pila despues del sort(): {pila}\")\n\n\"\"\"COLA(QUEUE)\"\"\"\n\n\"\"\"Creamos una lista y la utilizamos como cola\"\"\"\n\ncola=[\"Elemento 0\",\"Elemento 1\",\"Elemento 2\"]\n\n\"\"\"Agregamos elementos a la cola\"\"\"\n\nprint(f\"Contenido de la cola: {cola}\")\ncola.append(\"Elemento 3\")\nprint(f\"Contenido de la pila despues del append(\\\"Elemento 3\\\"): {cola}\")\n\n\"\"\"Eliminamos y mostramos el primer elemento de la cola\"\"\"\n\nprint(f\"Contenido de la cola: {cola}\")\nfirstElement= cola[0] # --> Obtenemos pero no eliminamos el primer elemento de la cola\nprint(f\"Contenido del primero de la cola: {firstElement}\")\ncola.remove(cola[0])\nprint(f\"Contenido despues del remove(0): {cola}\") # --> Mostramos la cola actualizada\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás de un navegador web.\nCrea un programa en el que puedas navegar a una página o indicarle que te quieres desplazar adelante o atrás,\nmostrando en cada caso el nombre de la web. Laspalabras \"adelante\", \"atras\" desencadenan esta acción,\nel resto se interpreta como el nombre de una nueva web.\n\"\"\"\ndef Programa1():\n    url = [\"www.google.com\", \"www.twitter.com\", \"www.gmail.com\"]\n    texto=\"\"\n    pos=0\n\n    while(texto.lower()!=\"salir\"):\n        print(\"\\n*******Navegación web*******\\n\")\n        print(\"Escribe la url de la página web para dirigirte a ella.\")\n        print(\"Si la url no existe se creara una nueva web\")\n        print(\"Escribe 'adelante' para ir a la siguiente web.\")\n        print(\"Escribe 'atras' para ir a la web anterior.\")\n        print(\"Escribe 'salir' para cerrar el programa.\")\n        texto=input(\"Escribe aquí: \")\n        if texto.lower()==\"adelante\":\n            if pos +1 >= len(url):\n                print(\"Ya te encuentras en la url del final\")\n                print(f\"La url es:\\n{url[pos]}\")\n            else:\n                print(\"Avanzamos\")\n                print(f\"La siguiente url es:\\n{url[pos+1]}\")\n                pos += 1\n        elif texto.lower()==\"atras\":\n            if pos -1 < 0:\n                print(\"Ya te encuentras en la url del principio\")\n                print(f\"La url es:\\n{url[pos]}\")\n            else:\n                print(\"Retrocedemos\")\n                print(f\"La url anterior es:\\n{url[pos-1]}\")\n                pos -= 1 \n        elif texto.lower()==\"salir\":\n            print(\"Vuelva pronto\")\n        elif texto in url: # --> url.__contains__(texto): Es otra manera de comprobarlo.\n            print(\"Encontramos url\")\n            pos= url.index(texto)\n            print(f\"La url es:\\n{url[pos]}\")\n        else:\n            print(\"Creamos url\")\n            url.append(texto)\n            print(f\"La url es:\\n{url[len(url)-1]}\")\n            # pos= round(len(url)/2) --> Nos posiciona en la url del medio\nPrograma1()\n\"\"\"\n- Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una impresora compartida \nque recibe documentos y los imprime cuando así se le indica. La palabra \"imprimir\" imprime un elemento de la cola,\nel resto de palabras se interpretan como nombres de documentos.\n\"\"\"\ndef Programa2():\n    doc=[\"Documento 1\",\"Documento 2\",\"Documento 3\"]\n    texto=\"\"\n    while texto.lower()!=\"salir\":\n        print(\"\\n*******Mecanismo de una impresora*******\\n\")\n        print(\"Escribe 'imprimir' para ir a la imprimir el primer documento de la cola.\")\n        print(\"Si no, introduce el nombre del nuevo documento a imprimir y se añadira a la cola\")\n        print(\"Escribe 'salir' para cerrar el programa.\")\n        texto= input(\"Escribe aquí: \")\n\n        if texto.lower()==\"imprimir\":\n            if len(doc) < 1:\n                print(\"La impresora esta vacía\")\n            else:\n                print(f\"Procedemos a imprimir el documento: {doc[0]}\")\n                doc.remove(doc[0])\n        elif texto.lower()==\"salir\":\n            print(\"Vuelva pronto\")\n        else:\n            print(\"Introducimos el nuevo documento\")\n            doc.append(texto)\nPrograma2()\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/Sac-Corts.py",
    "content": "\"\"\"\n  EJERCICIO\n\"\"\"\n\n# Clase Stack (Pila)\n\nclass Stack:\n    def __init__(self):\n        self.items = []\n\n    def push(self, item):\n        self.items.append(item)\n\n    def pop(self):\n        if not self.is_empty():\n            return self.items.pop()\n        else:\n            return None\n\n    def peek(self):\n        if not self.is_empty():\n            return self.items[-1]\n        else:\n            return None\n\n    def is_empty(self):\n        return len(self.items) == 0\n\n    def size(self):\n        return len(self.items)\n\npila = Stack()\npila.push(1)\npila.push(3)\npila.push(6)\n\nprint(pila.size()) # 3\nprint(pila.pop()) # 6\nprint(pila.peek()) # 3\nprint(pila.is_empty()) # False\n\n\n# Clase Queue (Cola)\n\nclass Queue:\n    def __init__(self):\n        self.items = []\n\n    def enqueue(self, item):\n        self.items.append(item)\n\n    def dequeue(self):\n        if not self.is_empty():\n            return self.items.pop(0)\n        else:\n            return None\n\n    def peek(self):\n        if not self.is_empty():\n            return self.items[0]\n        else:\n            return None\n\n    def is_empty(self):\n        return len(self.items) == 0\n\n    def size(self):\n        return len(self.items)\n\nfila = Queue()\nfila.enqueue(1)\nfila.enqueue(5)\nfila.enqueue(10)\n\nprint(fila.size()) # 3\nprint(fila.dequeue()) # 1\nprint(fila.peek()) # 5\nprint(fila.is_empty()) # False\n\n\n\"\"\"\n DIFICULTAD EXTRA\n\"\"\"\n\n# Navegador Web\n\nhistorial = []\nadelante = []\n\ndef navegar_a(pagina):\n    historial.append(pagina)\n    adelante.clear()\n\ndef ir_atras():\n    if len(historial) > 1:\n        adelante.append(historial.pop())\n        print(f\"Página actual: {historial[-1]}  | {historial} | {adelante}\")\n    else:\n        print(\"No hay más páginas atrás.\")\n\ndef ir_adelante():\n    if adelante:\n        historial.append(adelante.pop())\n        print(f\"Página actual: {historial[-1]}  | {historial} | {adelante}\")\n    else:\n        print(\"No hay más páginas adelante.\")\n\nwhile True:\n    comando = input(\"Introduce una página o 'atrás'/'adelante': \")\n    if comando == \"atrás\" or comando == \"atras\":\n        ir_atras()\n    elif comando == \"adelante\":\n        ir_adelante()        \n    elif comando == \"salir\":\n        print(\"Saliendo del navegador...\")\n        break\n    else:\n        navegar_a(comando)\n        print(f\"Página actual: {comando} | {historial} | {adelante}\")\n\n\n\n# Impresora\n\ndocumentos = []\n\ndef agregar_documento(documento):\n    documentos.append(documento)\n\ndef imprimir_documento():\n    if len(documentos) > 0:\n        imprimir = documentos.pop(0)\n        print(f\"Imprimiendo {imprimir} | {documentos}\")\n    else:\n        print(\"No hay impresiones por el momento\")\n\nwhile True:\n    comando = input(\"Introduce un documento o 'imprimir': \")\n    if comando == \"imprimir\":\n        imprimir_documento()\n    elif comando == \"salir\":\n        print(\"Apagando impresora...\")        \n        break\n    else:\n        agregar_documento(comando)\n        print(\"Fila de impresión:\", documentos)"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/SaezMD.py",
    "content": "#07 PILAS Y COLAS\n\"\"\"/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás  de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web. Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se interpretan como nombres de documentos.\n */\nhttps://stackabuse.com/stacks-and-queues-in-python/\n \"\"\"\n\n#Stacks - LIFO (PILA)\n\nletters = []\n# Add letters into the list PUSH\nletters.append('c')\nletters.append('a')\nletters.append('t')\nletters.append('g')\nprint(letters)\n\n# POP letters, the last one 'g' exits first POP\nlast_item = letters.pop()\nprint(last_item)\n\n# Another way to delete the last one:\nlast_item = letters[len(letters) - 1]\ndel letters[len(letters) - 1]\nprint(last_item)\n\n# 'c' and 'a' remain\nprint(letters) # ['c', 'a']\n\n#Queue - FIFO (COLA)\n\n# enqueue. Add elements\nanimals = []\nanimals.append('cat')\nanimals.append('dog')\nanimals.append('tuna')\nanimals.append('horse')\nprint(animals)\n\n# dequeue\nfirst_item = (animals.pop(0))\nprint(first_item)\nprint(animals)\n\n# Another way to delete the first position:\nfirst_item = animals[0]\ndel animals[0]\nprint(first_item)\nprint(animals)\n\n#EXTRA I\n\ndef runWebMovement():\n    listOfWebs = [\"abc.es\", \"facebook.com\", \"youtube.com\", \"google.com\"]\n    #popped = []\n\n    while True:\n        movement = input('You can enter the webpage or enter the movement command (\"back\"/\"forward\") or \"exit\": ').lower()\n        if movement == \"exit\":\n            print(\"You are exiting from the web browser.\")\n            break\n        elif movement == \"back\":\n            if len(listOfWebs) > 0:\n                listOfWebs.pop()\n            else:\n                print(\"You can't go back anymore.\")\n        elif movement == \"forward\":\n            print(\"You can't go to the next one.\")\n        else:\n            listOfWebs.append(movement)\n    \n        print(f\"You are in web: {listOfWebs[len(listOfWebs) - 1]}.\")\n\nrunWebMovement()\n\n#EXTRA II\n\ndef printUsingQueues():\n    listToPrint = [\"toprint01\",\"toprint02\",\"toprint03\",\"toprint04\",\"toprint05\",\"toprint06\",\"toprint07\",\"toprint08\",\"toprint09\",\"toprint10\",\"toprint11\"]\n\n    while True:\n        instruction = input(\"Add a new document or print from the queu. (You can exit using: 'Exit'): \").lower()\n        if instruction == \"print\":\n            if len(listToPrint) > 0:\n                toPrintNow = listToPrint.pop(0)\n                print(f\"Printing... {toPrintNow}\")\n            else:\n                print(\"Nothing to print.\")\n        elif instruction == \"exit\":\n            break\n        else:\n            listToPrint.append(instruction)\n            print(f'\"{instruction}\" file added to the printer queu.')\n        \n        print(f\"Current files in the queu: {listToPrint}\")\n\n\nprintUsingQueues()\n\n\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/SergioGI99.py",
    "content": "\"\"\"\n-------------\nPILAS Y COLAS\n-------------\nEJERCICIO:\nImplementa los mecanismos de introducción y recuperación de elementos propios de las\npilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\no lista (dependiendo de las posibilidades de tu lenguaje).\n \nDIFICULTAD EXTRA (opcional):\n- Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n  de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n  que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n  Las palabras \"adelante\", \"atras\" desencadenan esta acción, el resto se interpreta como\n  el nombre de una nueva web.\n- Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n  impresora compartida que recibe documentos y los imprime cuando así se le indica.\n  La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n  interpretan como nombres de documentos.\n\"\"\"\n# Ejercicio\n  # Pila/Stack (LIFO)\n\nstack = []\n\n# push\nstack.append(\"1\")\nstack.append(\"2\")\nstack.append(\"3\")\nprint(stack)\n\n# pop\nstack_item = stack[len(stack) - 1]\ndel stack[len(stack) - 1]\nprint(stack_item)\nprint(stack)\nstack.pop()\nprint(stack)\n\n  # Cola/Queue (FIFO)\n\nqueue = []\n\n# enqueue\nqueue.append(1)\nqueue.append(2)\nqueue.append(3)\n\nprint(queue)\n\n# dequeue\nqueue_item = queue[0]\ndel queue[0]\nprint(queue_item)\nprint(queue)\n\n\nprint(queue.pop(0))\nprint(queue)\n\n# Extra\n\"\"\"\nimport queue\n\nimpresora = queue.Queue()\n\nimpresora.put(\"archivo_1\")\n\nimpresora.put(input(\"Que archivo quieres imprimir: \", ))\n\ndef imprimir():\n  while impresora.qsize() > 0:\n    impresión = impresora.get()\n    print(\"Se ha impreso: \", impresión)\n  else:\n    print(\"La impresora esta vacía\")\n\nimprimir()\n\"\"\"\n# Corrección\n\n# Web\ndef web_navigation():\n\n  stack = []\n\n  while True:\n\n    action = input(\n      \"Añade una url o navega con las palabras adelante/atrás/salir: \"\n    )\n\n    if action == \"salir\":\n      print(\"Saliendo del navegador web.\")\n      break\n\n    elif action == \"adelante\":\n      pass\n\n    elif action == \"atrás\":\n      if len(stack) > 0:\n        stack.pop()\n\n    else:\n      stack.append(action)\n\n    if len(stack) > 0:\n      print(f\"Has navegado a la web: {stack[len(stack) - 1]}\")\n\n    else:\n      print(\"Estás en la página de inicio.\")\n\n\n\n#web_navigation()\n      \n# Printer\n\ndef shared_printed():\n\n  queue =[]\n\n  while True:\n\n    action = input(\n      \"Añade un documento o selecciona imprimir/salir: \"\n    )\n\n    if action == \"salir\":\n      break\n    elif action == \"imprimir\":\n      if len(queue) > 0:\n        print(f\"Imprimiendo: {queue.pop(0)}\")\n    else:\n      queue.append(action)\n    \n    print(f\"Cola de impresión: {queue}\")\n\nshared_printed()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/SooHav.py",
    "content": "# 07 Pilas y Colas\n\n# Ejercicio\n\n# Ejercicio pilas\npila = [1, 2, 3]\n\n# metodo append\npila.append(4)\npila.append(5)\nprint(pila[len(pila)-1])\nprint(\n    f'Mi pila tiene los siguientes elementos {pila} y su longitud es de {len(pila)}')\n\n# metodo pop\npila.pop()\ndel pila[len(pila)-1]\nprint(\n    f'Mi pila tiene los siguientes elementos {pila} y su longitud es de {len(pila)}')\n\n# Ejercicio colas\ncola = [1, 2, 3]\n\n# metodo append\ncola.append(4)\ncola.append(5)\nprint(cola[0])\nprint(\n    f'Mi cola tiene los siguientes elementos {cola} y su longitud es de {len(cola)}')\n\n# metodo pop\ncola.pop(0)\ndel cola[0]\nprint(\n    f'Mi cola tiene los siguientes elementos {cola} y su longitud es de {len(cola)}')\n\n# DIFICULTAD EXTRA\n# Navegador web con implementación de pila\n\nhistorial = list()\n\n\ndef abrir_web():\n    url = input(f'Ingresa una nueva url: ')\n    historial.append(url)\n    return print(f\"Página abierta: {url}\")\n\n\ndef atras():\n    web_anterior = historial.pop()\n    web_actual = historial[-1]\n    return print(f\"Retrocediendo a: {web_actual}\")\n\n\ndef adelante():\n    web_adelante = input(f'Ingresa una nueva url:')\n    historial.append(web_adelante)\n    return print(f\"Avanzando a: {web_adelante}\")\n\n\ndef ver_historial():\n    return print(f\"Historial: {historial}\")\n\n# Implementaciòn\n# abrir_web()\n# abrir_web()\n# abrir_web()\n# abrir_web()\n# atras()\n# atras()\n# adelante()\n# ver_historial()\n\n# Impresora\n\n\nimpresion = list()\n\n\ndef nuevo_doc():\n    doc = input(f'Agregue un archivo a la impresora: ')\n    impresion.append(doc)\n    return print(f\"Se agregó el siguiente archivo a la cola de impresión: {doc}\")\n\n\ndef imprimir():\n    if len(impresion) > 0:\n        se_imprime = impresion.pop(0)\n        return print(f\"Imprimiendo: {se_imprime}\")\n    else:\n        print(\"No hay documentos para imprimir\")\n\n\ndef ver_historial_impresion():\n    return print(f\"Documentos en cola de impresión: {impresion}\")\n\n\n# implementacion\nnuevo_doc()\nnuevo_doc()\nnuevo_doc()\nver_historial_impresion()\nimprimir()\nver_historial_impresion()\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/TheReDNooB.py",
    "content": "# #07 PILAS Y COLAS\n\n# Pilas/Stack (LIFO)\n\nstack = []\nstack.append(\"libro 1\") # push\nstack.append(\"libro 2\") # push\nstack.append(\"libro 3\") # push\n\nprint(stack)\n\nstack.pop()\nprint(stack) # pop\n\n# Colas/Queue (FIFO)\n\nqueue = []\nqueue.append(\"cliente 1\") # enqueue\nqueue.append(\"cliente 2\") # enqueue\nqueue.append(\"cliente 3\") # enqueue\n\nprint(queue)\n\nqueue.pop(0) # dequeue\nprint(queue)\n\n# Extra\n\ndef browser():\n    stack = []\n\n    while True:\n        option = input(\"Enter url or select Next / Previous / Exit: \").lower()\n\n        match option:\n            case \"exit\":\n                print(\"Exiting...\")\n                break\n            case \"previous\":\n                if len(stack) > 0:\n                    print(f\"URL: {stack[-1]}\")\n                    stack.pop()\n            case \"next\":\n                pass\n            case _:\n                stack.append(option)\n\n\n#browser()\n\ndef printer():\n    queue = []\n\n    while True:\n        option = input(\"Enter document or select Print / Exit: \").lower()\n\n        match option:\n            case \"exit\":\n                print(\"Exiting...\")\n                break\n            case \"print\":\n                if len(queue) > 0:\n                    print(f\"Printing: {queue[0]}\")\n                    queue.pop(0)\n            case _:\n                queue.append(option)\n                print(f\"Document added: {option}\")\n\n\nprinter()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/Tomu98.py",
    "content": "\"\"\" Reto 07: Pilas y Colas \"\"\"\n\n# Pila/Stack (LIFO)\nstack = []\n\n# Push\nstack.append(1)\nstack.append(2)\nstack.append(3)\nprint(stack)\n\n# Pop\nstack_item = stack[len(stack) - 1]\ndel stack[len(stack) - 1]\nprint(stack_item)\n\nprint(stack.pop())\nprint(stack)\n\n\n# Cola/Queue (FIFO)\nqueue = []\n\n# Enqueue\nqueue.append(1)\nqueue.append(2)\nqueue.append(3)\nprint(queue)\n\n# Dequeue\nqueue_item = queue[0]\ndel queue[0]\nprint(queue_item)\nprint(queue.pop(0))\nprint(queue)\n\n\n\n\"\"\" Reto extra \"\"\"\n\n# Web\ndef web_navigation():\n    stack = []\n\n    while True:\n        action = input(\"Añade una url o interactúa con palabras 'adelante'/'atrás'/'salir': \")\n        if action.lower() == \"salir\":\n            print(\"Saliendo del navegador web.\")\n            break\n        elif action.lower() == \"adelante\":\n            pass\n        elif action.lower() == \"atrás\":\n            if len(stack) > 0:\n                stack.pop()\n        else:\n            stack.append(action)\n\n        if len(stack) > 0:\n            print(f\"Has navegado a la web: {stack[len(stack) - 1]}.\")\n        else:\n            print(\"Estás en la página de inicio.\")\n\nweb_navigation()\n\n\ndef shared_printed():\n    queue = []\n\n    while True:\n        action = input(\"Añade un documento o selección 'imprimir'/'salir': \")\n        if action.lower() == \"salir\":\n            break\n        elif action.lower() == \"imprimir\":\n            if len(queue) > 0:\n                print(f\"Imprimiendo: {queue.pop(0)}\")\n        else:\n            queue.append(action)\n\n        print(f\"Cola de impresión: {queue}\")\n\nshared_printed()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/TroyNebula.py",
    "content": "'''EJERCICIO:\r\nImplementa los mecanismos de introducción y recuperación de elementos propios de las\r\npilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\r\no lista (dependiendo de las posibilidades de tu lenguaje).'''\r\nfrom collections import deque\r\n# La lista en python funciona por defecto como pila, es más eficiente que una pila o cola\r\n\r\n\r\n# pila / stack\r\nlista = []              \r\nlista.append(11)        # Inserción al final de la lista\r\nlista.append(13)        # se le llama push a añadir, a apilar\r\nlista.append(15)\r\nprint (lista)           # [11, 13, 15]\r\nlista.pop (1)           # elimino el index 1 que es el 13\r\nprint (lista)           # [11, 15]\r\n                        #la longitud de la lista es 3 pero en index son 2 (0,1,2) de ahí el -1 en la posición\r\nnum_desapilar = lista[len(lista)-1] \r\nprint (num_desapilar)   # 15\r\n                        # Eliminar elementos de la pila (pop) El último en entrar es el primero en salir LIFO \r\ndel lista[len(lista)-1] # elimino el último por índice, el 15   \"desapilar\"\r\nprint (lista)           # [11]\r\nlista.pop ()            # elimino por defecto el último añadido, el 11   \r\nprint (lista)           # []\r\nprint()\r\n\r\n\r\n# cola / queue  FIFO Lista doblemente finalizada, fácil para insertar/eliminar en principios o finales\r\nmi_deque = deque()\r\nmi_deque.append(1)      # push / inserción igual que en la pila\r\nmi_deque.append(2)      # pero se le llama encolar = enqueue\r\nmi_deque.append(3)\r\nprint (mi_deque)        # deque([1, 2, 3])  \r\nmi_deque.appendleft(5)  # inserta al principio\r\nprint (mi_deque)        # deque([5, 1, 2, 3]) \r\nprint(\"Posición 1: \", mi_deque[1]) \r\n                        # la posicioon 1 es el 1, la 0 es el 5 que acabamos de añadir\r\nmi_deque.pop()          # desencolar / dequeue / elimina el último que es el 3 / actúa como pila\r\nprint (mi_deque)        # deque([5, 1, 2]) \r\nmi_deque.popleft()      #elimina el primero que es el 5\r\nprint(mi_deque)         # deque([1, 2])\r\nprint()\r\n\r\n\r\n''' DIFICULTAD EXTRA (opcional):\r\n* Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\r\nde un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\r\nque te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\r\nLas palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\r\nel nombre de una nueva web.\r\n* Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\r\nimpresora compartida que recibe documentos y los imprime cuando así se le indica.\r\nLa palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\r\ninterpretan como nombres de documentos.'''\r\n\r\n\r\n\r\n'''No conseguía desplazarme por los items de la lista, quería que se fueran imprimiendo una tras otra, pero en el ejercicio\r\nresuelto de Moure se introduce la web completa, quedando la lista así:\r\n['moure.dev', 'moure.dev/inicio', 'moure.dev/inicio/cursos'] '''\r\n\r\ndef navega ():\r\n    stack =[]\r\n    while True:        # Bucle infinito \r\n        \r\n        print (\"\"\"*********************************\\nAdvertencia: Esto es un simulador no un navegador.\\nIntroduce 'adelante/atras/salir' o el nombre de la web donde quieres ir.\\nPor ejemplo: moure.dev/inicio/cursos/python ... etc.\\nNo es necesario introducir 'http://'  pero recuerda incluir la web completa :\\n*********************************\"\"\")\r\n        introducido = input ()\r\n        \r\n        if introducido == \"adelante\":\r\n            # No se puede solucinar con una pila, porque al ir atrás he borrado el último y no tengo ninguno al que avanzar\r\n            print()\r\n            print ( \"---> Error 404 Página no encontrada\") \r\n                    \r\n        elif introducido == \"atras\":\r\n            if len (stack) == 1:\r\n                print()\r\n                print (\"---> Estás en la página principal no puedes volver atrás.\")\r\n\r\n            elif len (stack) > 1:\r\n                stack.pop()\r\n                   \r\n        elif introducido == \"salir\":\r\n            print()\r\n            print (\"---> Has terminado de navegar. Adiós.\")\r\n            break\r\n        else:\r\n            stack.append(introducido)\r\n\r\n        print()                   \r\n        print (f\"---> Estás en la web: http://{stack[len(stack)-1]}\")    # imprimo el último de la fila\r\n        \r\nnavega()\r\n\r\ndef impresora ():\r\n    lista_documentos :list = []\r\n    while True:\r\n\r\n        print (\"\"\"*********************************\\nIntroduce el nombre del documento a imprimir o 'salir'.\\nPor ejemplo: factura.psd\\nCuando quieras empezar la impresión escribe 'imprimir' para imprimir en orden, o 'imprimir' seguido del docuemnto que desee.\\n*********************************\"\"\")\r\n        a_imprimir = input ()\r\n        \r\n        if a_imprimir == \"imprimir\":\r\n            if len(lista_documentos) >0:\r\n                print(f\"---> Se está imprimiendo el archivo {lista_documentos.pop(0)}\")\r\n                if len(lista_documentos) ==0:\r\n                    print (\"---> No quedan documentos a imprimir. Lista vacía\")\r\n            else:\r\n                print (\"---> No quedan documentos a imprimir. Lista vacía\")\r\n                \r\n        elif \"imprimir\" in a_imprimir:\r\n            if len(lista_documentos) >0:\r\n                nombre_concreto = a_imprimir.strip(\"imprimir \")\r\n                # print (\"Nombre concreto:\" + nombre_concreto)  #comprobación ok\r\n                if nombre_concreto in lista_documentos:\r\n                    print()\r\n                    print (f\"---> Se está imprimiendo el archivo {nombre_concreto}\")\r\n                    lista_documentos.remove(nombre_concreto)\r\n                    if len(lista_documentos) ==0:\r\n                        print (\"---> No quedan documentos a imprimir. Lista vacía\")\r\n                else:\r\n                    print (\"---> Archivo no encontrado. Comprueba si está en la cola de impresión.\")\r\n            \r\n        elif a_imprimir == \"salir\":\r\n            print()\r\n            print (\"---> Impresión terminada. Adiós.\")\r\n            break\r\n        else:\r\n            lista_documentos.append(a_imprimir)\r\n        print()\r\n        print (f\"---> Cola de impresión pendiente: {lista_documentos}\")  \r\n        \r\nimpresora ()\r\n\r\n# Fin del ejercicio\r\n\r\n#-----------------------------------------------------------------------------------------\r\n# mis pruebas de salida para ver el formato\r\nmi_web: list = [\"index\"]\r\nmi_web.append (\"segunda\")\r\ninicio : str =mi_web[0]\r\nprint()\r\nprint(\"http://\" + inicio)               # http://index  \r\nprint (\"http://\", mi_web)               # http:// ['index', 'segunda']\r\nprint (f\"http://\", {inicio})            # http:// {'index'}\r\nprint (\"http://\",mi_web[0:])            # http:// ['index', 'segunda']\r\ntemp=str(mi_web[0:])\r\nprint(f\"http://\" + temp)                # http://['index', 'segunda']  Ya no hay espacio, pero sigue saliendo [] y '\r\nprint(f\"http://\" + temp.strip((\"[']\"))) # http://index', 'segunda      Sigue saliendo '\r\nmi_web.pop()\r\nprint(f\"http://\" + str(mi_web[0:]))     # http://['index']  Ya no hay espacio, pero sigue saliendo [] y '\r\nprint()\r\n\r\n#def imprime_web (mi_web):\r\n#   for pagina in mi_web:\r\n#        print (f\"Estás en esta página http://\" + pagina ) # Aquí se imprime con index limpio pero una línea por cada página\r\n#imprime_web (mi_web)"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/VictorRivero1204.py",
    "content": "\"\"\"\nEjercicio\n\"\"\"\n\n# Pila/Stack (LIFO)\n\nstack = []\n\n# push \nstack.append(1) # push\nstack.append(2) # push\nstack.append(3) # push\nprint(stack) \n\n# pop\nstack_item = stack[len(stack) - 1]\ndel stack[len(stack) - 1]\nprint(stack_item)\n\nprint(stack.pop()) \n\nprint(stack)\n\n# Cola/Queue (FIFO)\n\nqueue = []\n\n# enqueue\nqueue.append(1)\nqueue.append(2)\nqueue.append(3)\n\nprint(queue)\n\n#dequeue\nqueue_item = queue[0]\ndel queue[0]\nprint(queue_item)\n\nprint(queue.pop(0))\n\nprint(queue)\n\"\"\"\nExtra\n\"\"\"\n\n# Web\n\ndef web_navegation():\n    \n    stack = []\n\n    while True:\n\n        action = input(\n            \"Añade una URL o iteractua con las palabras adelante/atras/salir:\"\n        )\n\n        if action == \"salir\":\n            print(\"Saliendo del navegador\")\n            break\n        elif action == \"adelante\":\n            pass\n        elif action == \"atras\":\n            if len(stack) > 0:\n                stack.pop()\n        else:\n            stack.append(action)\n\n        \n        if len(stack) > 0:\n            print(\"has navegado a la web: {stack[len(stack) - 1]}\")\n        else:\n            print(\"Estas en la pagina de inicio.\")\n\nweb_navegation()\n\ndef shared_printed():\n\n    queue = []\n\n    while True:\n        action = input(\"Añade un documentos o selecciona imprimir/salir: \")\n\n        if action == \"salir\":\n            break\n        elif action == \"imprimir\":\n            if len(queue) > 0:\n                print(f\"Imprimiendo: {queue.pop(0)}\")\n        else:\n            queue.append(action)\n\n        print(f\"Cola de impresión: {queue}\")\n    \nshared_printed()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/adolfolozaa.py",
    "content": "'''\r\nEJERCICIO:\r\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\r\n o lista (dependiendo de las posibilidades de tu lenguaje).\r\n *\r\n * DIFICULTAD EXTRA (opcional):\r\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\r\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como el nombre de una nueva web.\r\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una impresora compartida que recibe documentos y los imprime cuando así se le indica.\r\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se interpretan como nombres de documentos.'''\r\n\r\n# Pila(stack) (LIFO).   LA LISTA ES UNA PILA\r\nprint('---------------------')\r\nprint('Pila(stack) (LIFO)')\r\nstack = []\r\nstack.append('1')  # push\r\nstack.append('2') # push\r\nstack.append('3') # push\r\nprint(stack)\r\n\r\n#Pop\r\nstack_item = stack[len(stack) - 1] # peek\r\nprint(stack_item)\r\ndel stack[len(stack) - 1] # pop\r\nprint(stack)\r\n\r\n# una mejor opcion de desapilar\r\nstack.append('3') # push\r\n\r\nprint(stack)\r\nprint(stack.pop())  # pop hace la funcion de desapilar (peek y pop)\r\nprint(stack)\r\n\r\n\r\n# COLAS (QUEUE) (FIFO)\r\nprint('---------------------')\r\nprint('COLAS (QUEUE) (FIFO)')\r\nqueue = []\r\nqueue.append('1') # enqueue\r\nqueue.append('2') # enqueue\r\nqueue.append('3') # enqueue\r\n\r\nprint(queue)\r\nprint(queue.pop(0)) # dequeue  Se usa pop(0) para desencolar\r\nprint(queue)\r\n\r\n'''\r\nDIFICULTAD EXTRA (opcional):\r\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\r\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\r\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\r\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\r\n *   el nombre de una nueva web.\r\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\r\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\r\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\r\n *   interpretan como nombres de documentos.'''\r\n\r\n# DIFICULTAD EXTRA (opcional):\r\n\r\ndef navegacion():\r\n    stack = []\r\n    while True:\r\n\r\n\r\n        action = input('Ingrese la accion deseada: ')\r\n        if action == 'salir':\r\n            print(' Usted ha salido del navegador')\r\n            break\r\n        elif action == 'adelante':\r\n            print('pagina bonita')\r\n\r\n        elif action == 'atras':\r\n            if len(stack) == 0:\r\n                print('No hay paginas para atras')\r\n            else:\r\n                print(stack.pop())\r\n        else:\r\n            stack.append(action)\r\n            print(stack)\r\n\r\n        \r\n'''\r\nprint('---------------------')\r\nprint('Navegador web')\r\nprint('adelante, atrás o nombre de la web')\r\nprint('---------------------')\r\nnavegacion()'''\r\n\r\n\r\ndef impresora():\r\n    queue = []\r\n    while True:\r\n        action = input('Ingrese la accion deseada (anadir/imprimir/salir): ')\r\n        if action == 'salir':\r\n            print('Usted ha salido de la impresora')\r\n            break\r\n        elif action == 'imprimir':\r\n            if len(queue) == 0:\r\n                print('No hay documentos para imprimir')\r\n            else:\r\n                print(queue.pop(0))\r\n        else:\r\n            queue.append(action)\r\n            print(queue)\r\n\r\nimpresora()\r\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/adra-dev.py",
    "content": "\"\"\"\nEJERCICIO:\nImplementa los mecanismos de introduccion y recuperacion de elementos\npropios de las pilas (stacks - LIFO) y las colas (queue -FIFO) \nutilizando una estructura de array.\n\nDIFICULTAD EXTRA (opcional):\n- Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\nde un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\nque te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\nLas palabras \"adelante\", \"atras\" desencadenan esta acción, el resto se interpreta como\nel nombre de una nueva web.\n- Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\nimpresora compartida que recibe documentos y los imprime cuando así se le indica.\nLa palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\ninterpretan como nombres de documentos.\n\nby adra-dev.\n\"\"\"\n\n\n\"\"\"\nPilas:\n    Una estructura de tipo pila es una lista en la que los elementos\n    se añaden al final y se sacan del final; es decir, extraemos \n    siempre el elemento añadido más recientemente. A este tipo de \n    estructuras támbien se les denomina stack o LIFO (Last In, First\n    Out).\n\"\"\"\n\n# Este codigo simula la accion de deshacer\n\n# inicializamos la pila\nacciones = [] \n\n# guardamos las acciones del usuario\nacciones.append(\"escribir: 'h'\")\nacciones.append(\"escribir: 'o'\")\nacciones.append(\"escribir: 'y'\")\nacciones.append(\"negrita: 'hoy'\")\n\n# mostramos el contenido\nprint(acciones)\n\n# deshacemos el ultimo cambio y ponemos en cursiva\nprint(\"sacamos:\", acciones.pop())\nacciones.append(\"cursiva: 'hoy'\")\n\n# mostramos estado final de la pila\nprint(acciones)\n\n\n\"\"\"\nColas:\n    Una cola es una lista en la que los elementos llegan por un lado \n    y salen por otro. Támbien se les denomina FIFO (First In, First\n    Out), pues el primero elemento en llegar es el primero en salir.\n\"\"\"\n\n# Este codigo simula una cola de clientes en el supermercado\n\nfrom collections import deque\n\n# Iniciamos la cola\ncola = deque()\n\n# llegan 5 clientes a la cola \nfor i in range(5):\n    cliente = 'cliente ' + str(i+1)\n    print('Llega', cliente)\n    cola.append(cliente)\n    print('Cola:', cola)\n\n\n# salen todos los clientes de la cola \nwhile len(cola) > 0:\n    print('Sale', cola.popleft())\n    print('Qedan:', cola)\n\n\n\"\"\"\nExtra\n\"\"\"\n\n\ndef web_browser():\n    \"\"\"\n    En esta version del navegador, se asume que no se puede usar la \n    funcion forward sin antes haber utilizado la funcion backwards\n    \"\"\"\n    \n    pages = []\n\n    last_page = \"\"\n\n    def url():\n       link = input(\"Introduce una pagina web: \")\n       pages.append(link)\n       print(f\"Rdirigiendote a {link}\") \n    \n\n    def forward():\n       if last_page == \"\":\n           print(\"Te encuentras en la ultima pagina\") \n       else:\n           pages.append(last_page)\n           print(\"Redirigiendote a \", pages[-1])\n\n\n    def backwards():\n        backwards = pages.pop()\n        print(f\"Ultima pagina: {backwards}\")\n\n        return backwards\n\n\n    while True:\n\n        print(\"\")\n        print(\"1. Navegar\")\n        print(\"2. Adelante\")\n        print(\"3. Atras\")\n        print(\"4. Historial\")\n        print(\"5. Salir\")\n\n        status = input(\"Que opcion deseas realizar?: \")\n\n        match status:\n\n            case \"1\":\n                url()\n            case \"2\":\n                forward()\n            case \"3\": \n                last_page = backwards()\n            case \"4\": \n                print(pages)\n            case \"5\":\n                print(\"Cerrando del navegador.\")\n                break\n            case _:\n                print(\"Opcion no valida. Elige una opcion del 1 al 5\")\n\n\nweb_browser()    \n\n\ndef printer():\n\n   queue = deque() \n\n   def send():\n        doc = input(\"Que documento deseas enviar? :\")\n        queue.append(doc)\n        print(f\"Cola: {queue}\")\n\n\n   def printing():\n       print('Imprimiendo', queue.popleft())\n       print('Qedan:', queue, 'documentos.')\n\n   while True:\n       \n       print(\"\")\n       print(\"1. Enviar\")\n       print(\"2. Imprimir\")\n       print(\"3. Salir\")\n       \n       status = input(\"Que opcion deseas realizar?: \")\n       \n       match status:\n\n        case \"1\":\n            send()\n        case \"2\":\n            if len(queue ) == 0:\n                print(\"No hay documentos que imprimir.\")\n            else:\n                printing()\n        case \"3\":\n            print(\"Cerrando la impresorsa.\")\n            break\n        case _:\n            print(\"Opcion no valida. Elige una opcion del 1 al 3\")\n\nprinter()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/agusrosero.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atras\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n\"\"\"\nfrom collections import deque\n\n\n# PILAS\npila = []\n\n# Agregar un elemento al tope de la pila.\n\n\ndef push(elemento):\n    pila.append(elemento)\n    return pila\n\n\npush(1)\npush(2)\npush(3)\nprint(pila)\n\n# Eliminar un elemento del tope de la pila.\n\n\ndef eliminar():\n    pila.pop()\n    return pila\n\n\neliminar()\neliminar()\nprint(pila)\n\n# Mostrar el tope de la pila.\n\n\ndef top():\n    return pila[-1]\n\n\nprint(top())\n\n# Mostrar el tamanio de la pila.\n\n\ndef tamanio():\n    return len(pila)\n\n\nprint(tamanio())\n\n# COLAS\ncola = deque()\n\n# Agregar un elemento al final de la cola.\ncola.append(1)\ncola.append(2)\ncola.append(3)\nprint(cola)\n\n# Eliminar un elemento del final de la cola.\ncola.popleft()\nprint(cola)\n\n# Mostrar el primer elemento de la cola.\nprint(cola[0])\n\n# Mostrar el tamanio de la cola.\nprint(len(cola))\n\n# DIFICULTAD EXTRA:\n\n\nclass NavegadorWeb:\n    def __init__(self):\n        self.pila_atras = []\n        self.pila_adelante = []\n        self.pagina_actual = \"\"\n\n    def navegar(self, direccion):\n        if direccion.lower() == \"atras\" and self.pila_atras:\n            self.pila_adelante.append(self.pagina_actual)\n            self.pagina_actual = self.pila_atras.pop()\n        elif direccion.lower() == \"adelante\" and self.pila_adelante:\n            self.pila_atras.append(self.pagina_actual)\n            self.pagina_actual = self.pila_adelante.pop()\n        else:\n            self.pila_atras.append(self.pagina_actual)\n            self.pagina_actual = direccion\n\n    def mostrar_pagina(self):\n        print(f'Pagina actual: {self.pagina_actual}')\n\n\nnavegador = NavegadorWeb()\nnavegador.navegar(\"www.google.com\")\nnavegador.navegar(\"www.youtube.com\")\nnavegador.navegar(\"www.instagram.com\")\nnavegador.navegar(\"atras\")\nnavegador.mostrar_pagina()\nnavegador.navegar(\"adelante\")\nnavegador.mostrar_pagina()\n\n\nclass Impresora:\n    def __init__(self):\n        self.cola_impresion = deque()\n\n    def agregar_doc(self, doc):\n        self.cola_impresion.append(doc)\n\n    def imprimir(self):\n        if self.cola_impresion:\n            print(f\"Imprimiendo: {self.cola_impresion.popleft()}\")\n        else:\n            print(\"No hay documentos para imprimir\")\n\n\nimpresora = Impresora()\nimpresora.agregar_doc(\"Documento 1\")\nimpresora.agregar_doc(\"Documento 2\")\nimpresora.agregar_doc(\"Documento 3\")\nimpresora.imprimir()\nimpresora.imprimir()\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/ainaragmt.py",
    "content": "# Pila/Stack (LIFO)\nstack = []\nstack.append(\"1\")\nstack.append(\"2\")\nstack.append(\"3\")\nprint(stack)\n\ndel stack[len(stack) - 1]\nprint(stack)\n\nprint(stack.pop()) # printea el Last In\n\n# Cola/Queue (FIFO)\nqueue = []\nqueue.append(\"1\")\nqueue.append(\"2\")\nqueue.append(\"3\")\nprint(queue)\n\ndel queue[0]\nprint(queue)\n\nprint(queue.pop(0)) # printea el First In\n\n'''\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n'''\nprint(\"\\nEjercicio de dificultad extra\\n\")\n\nsalir = 1\nnw = 1\nimpr = 1\n\nwhile(salir):\n    opcion = int(input(\"Elige entre:\\n1. Navegador web\\n2. Impresora\\n3.Salir\\n\"))\n    if opcion == 1:\n        web = [\"google.com\"]\n        i = len(web)\n        print(web)\n        while(nw):\n            accion = int(input(\"\\nElige:\\n1. Desplazar hacia delante\\n2. Desplazar hacia atrás\\n3. Navegar a otra página\\n4. Salir\\n\"))\n            if accion == 1:\n                if i == len(web) - 1:\n                    print(\"No se puede avanzar más hacia delante.\\n\")\n                else:\n                    i += 1\n                print(web[i])\n            elif accion == 2:\n                if i == 0:\n                    print(\"No se puede avanzar más hacia atrás.\\n\")\n                else:\n                    i -= 1\n                print(web[i])\n            elif accion == 3:\n                pagina = str(input(\"Escriba el nombre de la nueva página: \"))\n                web.append(pagina)\n                print(web)\n            elif accion == 4:\n                nw = 0\n            else:\n                print(\"No ha elegido una opción válida.\\n\")\n    elif opcion == 2:\n        impresora = [\"Mapa\"]\n        print(impresora)\n        while(impr):\n            accion = int(input(\"\\nElige:\\n1. Imprimir\\n2. Añadir archivo\\n3. Salir\\n\"))\n            if accion == 1:\n                if len(impresora) == 0:\n                    print(\"No hay nada que imprimir.\\n\")\n                else:\n                    print(\"Imprimiendo \" + impresora[0])\n                    del impresora[0]                    \n            elif accion == 2:\n                archivo = str(input(\"Escriba el nombre del nuevo archivo: \"))\n                impresora.append(archivo)\n                print(impresora)\n            elif accion == 3:\n                impr = 0\n            else:\n                print(\"No ha elegido una opción válida.\\n\")\n    elif opcion == 3:\n        salir = 0\n    else:\n        opcion = int(input(\"Elige entre:\\n1. Navegador web\\n2. Impresora\\n3.Salir\\n\"))"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/alanshakir.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n\"\"\"\n\n#Pilas \nmy_list = [20, 50, 14, 83, 69, 74]\n\n#my_list.remove(20)\nmy_list.insert(1, 25)\nmy_list.pop() #elimina el ultimo de la lista\nmy_list.append(18) #agrega al final de la lista\n\n#Colas\nmy_list.append(18) #agrega al final de la lista\nmy_list.pop(1) #eliminar el elemento de la lista segun el indice\nprint (my_list)\n\n#Extra\ndef web_navigation():\n    user_stack = []\n    while True:\n        movimiento_user = input(\"¿Que movimiento desea realizar:? Seleccione un agregar url, adelante, atras, salir. \")\n        if movimiento_user == \"agregar\":\n            agregar_url = input(\"ingrese la url: \")\n            user_stack.append(agregar_url)\n            print(user_stack)\n        elif movimiento_user == \"adelante\":\n            if len(user_stack) > 0:\n                print(user_stack[-1])\n        elif movimiento_user == \"atras\":\n            if len(user_stack) > 0:\n                user_stack.pop()\n                print(user_stack)\n        else:\n            print(\"Has salido de programa.!\")\n            break\n\n\n\nweb_navigation()\n        \ndef printer():\n    user_queue = []\n    \n    while True: \n        movimiento_user = input(\"¿Desea agregar documento, imprimir o salir:? \")\n        if movimiento_user == \"agregar\":\n\n            user_queue.append(input(\"nombre del documento: \"))\n        elif movimiento_user == \"imprimir\":\n            while len(user_queue) > 0:\n                print(\"Imprimiendo documento: \", user_queue.pop(0))\n        else:\n            print(\"Has salido de programa.!\")\n            break\n\nprinter()\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/albertomorilla.py",
    "content": "# #07 PILAS Y COLAS\n\n\"\"\"\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n  pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n  o lista (dependiendo de las posibilidades de tu lenguaje).\n\"\"\"\n\n# PILAS/Stack (LIFO)\n\nstack = []\n\n# Push\n\nstack.append(1)\nstack.append(2)\nstack.append(3)\n\nprint(stack)\n\n# Pop\n\nstack_item = stack[len(stack)-1]\ndel stack[len(stack)-1]\nprint(stack_item)\n\nprint(stack.pop())\n\nprint(stack)\n\n#COLAS/Queue (FIFO)\nqueue = []\n\n#enqueue\nqueue.append(1)\nqueue.append(2)\nqueue.append(3)\n\n#dequeue\nqueue_item = queue[0]\ndel queue[0]\nprint(queue_item)\n\nprint(queue.pop(0))\n\n\nprint(queue)\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n    de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n    que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n    Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n    el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n    impresora compartida que recibe documentos y los imprime cuando así se le indica.\n    La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n    interpretan como nombres de documentos.\n\"\"\"\n\n# WEB\n\ndef web_oficial():\n    \n   stack = []\n\n   while True:\n    \n      action = input(\"¿Qué deseas hacer? (adelante, atrás, página):\")\n\n      if action == \"salir\":\n         print(\"Saliendo\")\n         break\n      elif action == \"adelante\":\n         pass\n      elif action == \"atras\":\n         if len(stack) > 0:\n            stack.pop() \n      else:\n         stack.append(action)\n\n      if len(stack) > 0:\n         print(f\"Has navegado a la web: {stack[len(stack) - 1]}.\")\n      else: \n         print(\"Estas en la pagina de inicio\")\n\nweb_oficial()\n\ndef shared_print():\n\n   queue = []\n\n   while True:\n\n      action = input(\"Añade un documento o selecciona imprimir/salir:\")\n\n      if action == 'salir':\n         break\n      elif action == 'imprimir':\n         if len(queue) > 0:\n            print(f\"Imprimiendo: {queue.pop(0)}\")\n      else:\n         queue.append(action)\n\n      print(f\"Cola de impresion: {queue}\")\n\nshared_print()\n\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/alcaan16.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\"\"\"\n\n# Pila/Stack (LIFO)\n\nstack = [] #creamos\n\n# push\nstack.append(1)\nstack.append(2)\nstack.append(3)\nprint(stack) #imprime la lista \n\n# pop\nstack_item = stack[len(stack) - 1] #ultimo elemento de la lista (3)\ndel stack[len(stack) - 1] #eliminamos la ultima posicion de la lista (3)\nprint(stack_item) #ultimo elemento lista (3)\n\nprint(stack.pop()) #elimina el ultimo elemento (2)\n\nprint(stack) #ahora solo queda un elemento (1)\n\n# Cola/Queue (FIFO)\n\nqueue = [] #creamos la lista\n\n# enqueue\nqueue.append(1) \nqueue.append(2)\nqueue.append(3)\n\nprint(queue) #imprime la lista\n\n# dequeue\nqueue_item = queue[0] #primer elemento de la lista (1)\ndel queue[0] #elimina el primer elemento (1)\nprint(queue_item) #primer elemento de la lista \n\nprint(queue.pop(0)) #imprime y elimina el ultimo elemento \n\nprint(queue) #imprime el elemeto que queda\n\n# EJERCICIO\n\ndef navegador():\n    historial = []\n    flag = 0\n\n    def mostrar(flag:int):\n        if len(historial) > 1:\n            print(historial[flag])\n        else:\n            print(\"no hay elemento a mostrar\")\n\n    while True:\n        action = []\n        action = input(\"introduce una accion:  \")\n        if action == \"adelante\":\n            action = 0\n            flag = -1\n            mostrar (flag)\n            \n        if action == \"atras\":\n            action = 0\n            flag = -2\n            mostrar (flag)\n    \n        if action == \"mostrar\":\n            action = 0\n            if len(historial) != 0:\n                print(historial[flag])\n            else:\n                print(\"no hay nada que mostrar\")\n        if action == \"salir\":\n            action = 0\n            print (historial)\n            break\n        elif action !=0 :\n            flag = -1\n            historial.append(action)\n            print(f\"la url {action} a sido añadida\")\n        print (historial)\n\nnavegador()\n\ndef impresora():\n    cola=[]\n    while True:\n        print(cola)\n        option=input(\"introduce una palabra o escribe imprimir para imprimir la ultima palabra \")\n        if option == \"salir\":\n            print(\"saliendo\")\n            break\n        if option == \"imprimir\":\n            if len(cola) == 0:\n                print(\"no hay nada que imprimir\")\n            else:\n                print(f\"la palabra {cola[0]} se a impreso\")\n                cola.pop(0)\n                print(cola)\n        else:\n            cola.append(option)\n            print(cola)\nimpresora()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/alexdevrep.py",
    "content": "'''\n/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n'''\n\n'''\nLas pilas son tipos abstactos de datos que se encuentran en un formato de tipo lista\na cuyos elementos se accede de una forma particular (LIFO) Last In First Out que se puede \ntraducir como \"Lo último en entrar será lo último en salir\"\n'''\nfrom collections import deque # Librería para las colas\n\n\n#Creamos un pila de elementos\nmi_list=[\"Hola\",\"Python\",\"Alexdevrep\"]\nprint(mi_list)\n\n# Introducción de un elemento en una pila\nmi_list.append(\"Mundo\")\nprint(mi_list)\n\n#Recuperación del último elemento de la pila\nprint(mi_list.pop())\nprint(mi_list)\n\n\nprint(\"-----------------------------------------\")\n\n'''\nLas colas son los colecciones de elementos ordenados que únicamente permiten dos acciones \n-Añadir un elemento a la cola\n-Sacar un elemento de la cola\nLa peculiaridad es que el primer elemento en entrar es el primero en salir (FIFO) First In First Out\n'''\n\n#Creamos una cola de elementos\ncola = deque([\"Mundo\",\"Python\",\"Alexdevrep\"])\nprint(cola)\n\n#Introducimos un elemento a la cola\ncola.append(\"Hola\")\nprint(cola)\n\n#Recuperación el primer elemento de la cola en este caso \"Mundo\"\nprint(cola.popleft())\nprint(cola)\n\nprint(\"-----------------------------------------\")\n\n#Dificultad EXTRA\n\n\n# Ejercicio Pilas \n\npila_web = []\n\nprint(\"###---NAVEGADOR WEB---###\")\nprint(\"Pestaña nueva:\")\n\nwhile True:\n    def accion(arg):\n        if arg == \"ADELANTE\":\n            web = input(\"Por favor indique a qué web quiere acceder: \")\n            pila_web.append(web)\n            print(f'Ahora estás viendo {pila_web[-1]}')\n\n        elif arg == \"ATRAS\":\n            if len(pila_web) > 1:\n                pila_web.pop()\n                print(f'Ahora estás viendo {pila_web[-1]}')\n            else:\n                print(\"No hay historial de navegación para retroceder.\")\n\n        elif arg == \"SALIR\":\n            print(\"Cerrando el navegador web.\")\n            \n\n        else:\n            print(\"Comando no reconocido.\")\n\n    arg = input(\"Por favor escriba ADELANTE si quiere acceder a una URL nueva, ATRAS si quiere cerrar la última URL, o SALIR para salir: \")\n    accion(arg)\n    if arg == \"SALIR\":\n        break\n\n\n# Ejercicio Colas\n\ndocumentos = deque([])\n\nwhile True:\n    def impresora(archivo):\n        if archivo == \"IMPRIMIR\":\n            if len(documentos)>=1:\n                print(f'Imprimiendo archivo {documentos.popleft()}')\n            else:\n                print (\"No hay archivos para imprimir\")\n        elif archivo == \"SALIR\":\n            print (\"Apagando la impresora\")\n            exit()\n        else :\n            documentos.append(archivo)\n            print(\"Documento añadido a la cola de impresión\")\n    \n    archivo = input(\"Por favor escriba el nombre del archivo para añadirlo a la cola de la impresión , IMPRIMIR para imprimirlo y SALIR para apagar la impresora: \")\n    impresora(archivo)\n        \n    \n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/andres54-coder.py",
    "content": "'''\nejercicio\n'''\n# pila/stack (LIFO)\nstack = []\n\nstack.append('1')\nstack.append('2')\nstack.append('3')\nprint(stack)\n\n#pop\nstack_item = stack[len(stack)- 1 ]\ndel stack[len(stack)- 1 ]\nprint(stack_item)\nprint(stack.pop())\nprint(stack)\n\n# cola/queue (FIFO)\nqueue = []\nqueue.append(1)\nqueue.append(2)\nqueue.append(3)\n\ndel queue[0]\nprint(queue)\n# dequeue\nprint(queue.pop(0))\n\nprint(queue)\n\n'''\nextra\n'''\n\nweb_pages = [\n    'google',\n    'facebook',\n    # 'youtube',\n    # 'temu',\n    # 'x',\n    # 'threads',\n    # 'gmail',\n    # 'outlook'\n    ]\n\ndef navigator():\n    cursor=0\n    action= ''\n    while True:\n        while action == '':\n            print(f\"Usted esta en {web_pages[cursor]}\")\n            print(f\"sus pestañas disponibles son {web_pages}\")\n            action = input(\"Ejecute alguna accion (salir, adelante, atras)\")\n        if action == \"salir\":\n            break\n        if action == \"adelante\":\n            if cursor < len(web_pages) - 1:\n                cursor += 1\n            else:\n                new_page = input(\"No hay más páginas. ¿Desea agregar una nueva? (si/no): \").strip().lower()\n                if new_page == 'si':\n                    new_url = input(\"Ingrese el nombre de la nueva página: \")\n                    web_pages.append(new_url) \n                    cursor += 1  \n                else:\n                    print(\"No se ha agregado ninguna página nueva.\")\n        if action == \"atras\":\n            cursor -= 1   \n        action=''\n# navigator()\n\ndef shared_printer():\n    queue = [] \n    while True:\n       \n        action = input(\" Añade un documento o seleciona imprimir/salir : \")\n\n        if action == \"salir\":\n            break\n        elif action == \"imprimir\":\n            if len(queue) > 0:\n                print(f\"imprimiendo... {queue[0]}\")\n                queue.pop(0)\n            else:\n                print(\"No hay documentos disponibles para impresion\")\n        else:\n            queue.append(action)\n        print(f\"Cola de impresion: {queue}\")\nshared_printer()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/annerssv.py",
    "content": "#PILAS Y COLAS\n\n#PILA (LIFO)\n\n\nmi_pila = []\n\n#APILAR\nmi_pila.append(\"1\")\nmi_pila.append(\"2\")\nmi_pila.append(\"3\")\nprint(mi_pila)\n\n#DESAPILAR\nmi_pila.pop()\nprint(mi_pila)\nmi_pila.pop()\nprint(mi_pila)\nmi_pila.pop()\nprint(mi_pila) #DEVUELVE LA LISTA VACIA\n\n\n#COLA (FIFO)\n\ncola = []\n\n#ENCOLAR\n\ncola.append(\"1\")\ncola.append(\"2\")\ncola.append(\"3\")\nprint(cola)\n\n\n#DESENCOLAR\n\ncola.pop(0)\nprint(cola)\ncola.pop(0)\nprint(cola)\ncola.pop(0)\nprint(cola) #DEVUELVE LA LISTA VACIA\n\n\n\n#EJERCICIO EXTRA NAVEGADOR CON PILA\ndef pila_web():\n    \n    pila = []\n    \n    while True:\n        \n        option = input(\"Añade una url o navega con los comandos: 'adelante/atras/salir': \")\n        \n        if option == \"adelante\":\n            pass\n        elif option == \"atras\":\n            if len(pila) > 0:\n                pila.pop()\n        elif option == \"salir\":\n            print(\"Saliendo del navegador\")\n            break\n        else:\n            pila.append(option)\n        \n        if len(pila) > 0:\n            print(f\"Estas en la pagina {pila[len(pila) - 1]}.\")\n        else:\n            print(\"Estas en la pagina de inicio\")\n        \n#pila_web()\n            \n            \n#EJERCICIO EXTRA IMPRESORA\n\ndef cola_impresora():\n    \n    cola_de_docs = [] \n    \n    while True:\n        \n        print('''Bienvenido al sistema de impresora Canon elige una de las siguientes opciones:\n                    1. Imprimir\n                    2. Añadir documentos\n                    3. Salir''')\n        \n        option = input(\"Elige una opción: \")\n        \n        if option == \"1\":\n            if len(cola_de_docs) > 0:\n                print(f\"Imprimiendo el documento: {cola_de_docs[0]}\")\n                cola_de_docs.pop(0)\n                print(f\"Cola de documentos: {cola_de_docs}\")\n            else:\n                print(\"No tienes documentos en la cola\")\n        elif option == \"2\":\n            documento = input(\"Ingresa el nombre del documento a añadir con la terminación .doc: \")\n            cola_de_docs.append(documento)\n            print(\"Documento añadido correctamente\")\n            print(f\"Cola de documentos: {cola_de_docs}\")\n        elif option == \"3\":\n            print(\"Saliendo del sistema...\")\n            break\n        else:\n            print(\"Elige una opcion valida\")\n        \n        \ncola_impresora()        \n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/any7dev.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */ \"\"\"\n\n# EJERCICIO\n\n# Pilas\npila = [1, 2, 3, 4, 5]\nprint(pila)\n# Añadir elemento a la pila, el último\npila.append(6)\nprint(pila)\n# Quitar elemento, el último\npila.pop()\nprint(pila)\ndel pila[-1]\nprint(pila)\n\n# Colas\ncola = [6, 7, 8, 9, 10]\nprint(cola)\n# Añadir elemento, el último\ncola.append(11)\nprint(cola)\n# Quitar elemento, el primero\ncola.pop(0)\nprint(cola)\ndel cola[0]\nprint(cola)\n\n# DIFICULTAD EXTRA\n\n# Navegador web\npila = []\n\ndef navegador():\n    contador = -1\n    while True:\n        opcion = input(f\"\\nEscribe cualquier página o: \\n\\t·atras --> Para ir a la página web anterior \\n\\t·adelante --> Para ir a la página web anterior \\n\\t·salir --> Para salir \\n -->\")\n        match opcion:\n            case \"salir\":\n                print(f\"Saliendo\\n\")\n                break            \n            case \"atras\":                \n                if not pila:\n                    print(\"Historial Vacío\")\n                elif contador == 0:\n                    actual = pila[contador]\n                    print(f\"Estás en la primera página {actual}\")\n                else:\n                    contador -= 1 \n                    actual = pila[contador]\n                    print(f\"Estás en la página web {actual}\")                                   \n            case \"adelante\":\n                if not pila:\n                    print(\"Historial Vacío\")\n                elif contador+1 == len(pila):\n                    actual = pila[contador]\n                    print(f\"Esta es la última web visitada {actual}, no se puede avanzar\")\n                else:\n                    contador += 1\n                    actual = pila[contador]\n                    print(f\"Estás en la página web {actual}\")                    \n            case _:\n                www = opcion\n                pila.append(www)\n                print(f\"Estás en la página web {www}\")\n                contador += 1            \n\nnavegador()\n\n# Impresora\ncola = []\n\ndef impresora():\n    contador = -1\n    while True:\n        opcion = input(f\"\\nEscribe el nombre del documento, imprimir para imprimer el primer documento o salir para salir: \\n-->\")\n        match opcion:\n            case \"salir\":\n                print(f\"Saliendo\\n\")\n                break\n            case \"imprimir\":\n                if not cola:\n                    print(\"Cola de impresión vacía\")\n                else:\n                    doc = cola[0]\n                    print(f\"Imprimiendo el documento con nombre {doc}\")\n                    cola.pop(0)\n                    contador -= 1\n            case _:\n                cola.append(opcion)\n                contador += 1\n\nimpresora()\n\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/avcenal.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n\"\"\"\nclass Stack:\n    def __init__(self):\n        self.__stack = list()\n\n    def push(self,item):\n        if len(self.__stack) == 0:\n            self.__stack.append(item)\n        else:\n            temp = list()\n            temp = self.__stack.copy()\n            self.__stack.clear()\n            self.__stack.append(item)\n            for element in temp:\n                self.__stack.append(element)\n        return self.__stack\n    \n    def pop(self):\n        if len(self.__stack) == 1:\n            self.__stack.clear()\n        else:\n            self.__stack = self.__stack[1:]\n        return self.__stack\n    \n    def top(self):\n        return self.__stack[0]\n    \n    def size(self):\n        return len(self.__stack)\n    \n    def empty(self):\n        return self.__stack.clear()\n\n    def show(self) -> None:\n        print(self.__stack)\n\nclass Queue():\n    def __init__(self) -> None:\n        self.__queue = list()\n    \n    def enqueue(self,item):\n        return self.__queue.append(item)\n    \n    def dequeued(self):\n        self.__queue = self.__queue[1:]\n        return self.__queue\n    \n    def front(self):\n        return self.__queue[0];\n    \n    def show(self):\n        print(self.__queue)\n\nmy_stack = Stack()\nmy_stack.show()\nmy_stack.push(3)\nmy_stack.show()\nmy_stack.push(2)\nmy_stack.show()\nmy_stack.push(5)\nmy_stack.show()\nmy_stack.push(9)\nmy_stack.show()\nmy_variable = my_stack.top()\nprint(f\"El valor accesible de la pila es el: {my_variable}\")\nmy_stack.pop()\nmy_stack.show()\nprint(f\"La longitud de la pila es: {my_stack.size()}\")\nmy_stack.empty()\nmy_stack.show()\n\nmy_queue = Queue()\nmy_queue.show()\nmy_queue.enqueue(\"hola\")\nmy_queue.enqueue(\"mi nombre\")\nmy_queue.show()\nmy_queue.enqueue(\"es Alex\")\nmy_queue.show()\nmy_queue.dequeued()\nmy_queue.show()\nprint(f\"El primer valor de la cola es: \\\"{my_queue.front()}\\\"\")\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n\"\"\"\nclass Web_Navigator(Stack):\n    def go(self,web):\n        return self.push(web)\n        \n    def back(self):\n        try:\n            popped = (self.top())\n        except IndexError:\n            print(\"no hay sitios web almacenados\")\n        else:\n            self.pop()\n            return self,popped\n        finally:\n            time.sleep(1)\n            print(\"\\n\")\n    \n    def forward(self,popped:list):\n        if len(popped) == 1:\n            self.push(popped[0])\n        else:\n            self.push(popped[-1])\n        popped = popped.pop()\n\n    def show(self):\n        try:\n            print(f\"Ahora estas en la web: {self.top()}\")\n        except IndexError:\n            print(\"No hay más web almacenadas hacia atrás\")\n        finally:\n            time.sleep(1)\n            print(\"\\n\")    \n\ndef go_to_website(navigator,pop_list):\n    pop_list.clear()\n    website = input(\"Perfecto. Dime por favor la web a la que quieres navegar: \")\n    navigator.go(website)\n    navigator.show()\n    return navigator\n\ndef go_back(navigator,pop_list):\n    if navigator.size() != 0:\n        navigator,temp = navigator.back()\n        pop_list.append(temp)\n        navigator.show()\n\n\ndef go_forward(navigator,pop_list):\n    if len(pop_list)!= 0:\n        navigator.forward(pop_list)\n        navigator.show()\n    else:\n        print(\"No hay más webs en adelante\")\n        time.sleep(1)\n        print(\"\\n\")\n\n\nmy_web_navigator = Web_Navigator()\nmy_popped_list = list()\nimport time\nprint(\"\\n\")\ndef web_navigation():\n    web_option = \"\"\n    while web_option != \"4\":\n        web_option = input(\"Elije una de las opciones:\\n1. Navegar a un sitio web.\\n2. Ir hacia adelante.\\n3. Ir hacia atrás.\\n4. Salir\\n ---> \")\n        match web_option:\n            case \"1\":\n                go_to_website(my_web_navigator,my_popped_list)\n            case \"2\":\n                go_forward(my_web_navigator,my_popped_list)\n            case \"3\":\n                go_back(my_web_navigator,my_popped_list)\n            case \"4\":\n                break\n            case _:\n                print(\"La opción introducida no es correcta\")\n                time.sleep(2)\n                print(\"\\n\")\n    print(\"Gracias por usar el sistema de navegación web\")\n    print(\"\\n\")\nweb_navigation()\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n\"\"\"\nclass Printer(Queue):\n    def send_doc(self,doc):\n        self.enqueue(doc)\n        print(f\"El documento {doc} ha quedado encolado en la impresora\")\n        time.sleep(1)\n        print(\"\\n\")\n    \n    def print_doc(self):\n        try:\n            doc = self.front()\n        except IndexError:\n            print(\"No hay más documentos en la cola de impresión\")\n        else:\n            self.dequeued()\n            print(f\"El documento impreso es: {doc}\")\n        finally:\n            time.sleep(1)\n            print(\"\\n\")\n\n    def pending_docs(self):\n        print(\"Los documentos que faltan por imprimit son: \")\n        self.show()\n        time.sleep(1)\n        print(\"\\n\")\n\ndef printer():\n    my_printer = Printer()\n    print_option = \"\"\n    while print_option != 4:\n        print_option = input (\"Elije una de las cuatro opciones:\\n1. Enviar documento a la impresora\\n2. Imprimir documento\\n3. Mostrar cola de impresión\\n4. Salir\\n----> \")\n        match print_option:\n            case \"1\":\n                document = input(\"Dame el nombre del documento: \")\n                my_printer.send_doc(document)\n            case \"2\":\n                my_printer.print_doc()\n            case \"3\":\n                my_printer.pending_docs()\n            case \"4\":\n                break\n            case _:\n                print(\"La opción elegida no es válida. Prueba de nuevo\")\n                time.sleep(1)\n                print(\"\\n\")\n    print(\"Gracias por usar este sistema de impresión\")\n\nprinter()\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/barrancus.py",
    "content": "\"#[número] - [lenguaje_utilizado]\"\n# \n# EJERCICIO:\n# Implementa los mecanismos de introducción y recuperación de elementos propios de las\n# pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n# o lista (dependiendo de las posibilidades de tu lenguaje).\n# \n# DIFICULTAD EXTRA (opcional):\n# - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n#   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n#   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n#   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n#   el nombre de una nueva web.\n# - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n#   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n#   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n#   interpretan como nombres de documentos.\n# \ndef serparacion(cadena):\n    print('{}'.format(cadena * 20))\n\npalabras_aleatorias = [\n    \"Abismo\", \"Brújula\", \"Cántaro\", \"Delicado\", \"Ébano\", \"Fervor\", \"Gema\", \"Horizonte\", \"Ímpetu\", \"Joven\",\n    \"Kilogramo\", \"Laberinto\", \"Mármol\", \"Nácar\", \"Órbita\", \"Papiro\", \"Quirúrgico\", \"Radiante\", \"Sutil\", \"Tímpano\",\n    \"Utopía\", \"Vértigo\", \"Xenofobia\", \"Yacimiento\", \"Zócalo\", \"Armonía\", \"Bohemio\", \"Céfiro\", \"Diligencia\", \"Efímero\",\n    \"Furtivo\", \"Grácil\", \"Hélice\", \"Ígneo\", \"Jolgorio\", \"Kiosco\", \"Lánguido\", \"Melancolía\", \"Nostalgia\", \"Ópalo\",\n    \"Pálido\", \"Quimera\", \"Risueño\", \"Solitario\", \"Tácito\", \"Umbral\", \"Voraz\", \"Xilófono\", \"Yunque\", \"Zodiaco\",\n    \"Algoritmo\", \"Bitácora\", \"Cristal\", \"Destello\", \"Espejismo\", \"Fractal\", \"Glaciar\", \"Hechizo\", \"Ilusión\", \"Jíbaro\",\n    \"Karma\", \"Lunar\", \"Magia\", \"Nebulosa\", \"Ocre\", \"Panacea\", \"Quijote\", \"Relámpago\", \"Sigilo\", \"Tundra\",\n    \"Ukelele\", \"Vaina\", \"Walabi\", \"Yoga\", \"Zafiro\", \"Ágora\", \"Bizarro\", \"Crisálida\", \"Diáfano\", \"Efusión\",\n    \"Fugaz\", \"Gárgola\", \"Hada\", \"Inmune\", \"Júbilo\", \"Kaolín\", \"Límpido\", \"Metamorfosis\", \"Nítido\", \"Onírico\",\n    \"Peregrino\", \"Quórum\", \"Rostro\", \"Súbito\", \"Trémulo\", \"Usurpador\", \"Voluble\", \"Xilografía\", \"Yodo\", \"Zambullida\",\n    \"Abnegación\", \"Botella\", \"Cataclismo\", \"Desván\", \"Enigmático\", \"Filosofía\", \"Girasol\", \"Hilera\", \"Invierno\", \"Jerarquía\",\n    \"Koala\", \"Licor\", \"Mirada\", \"Néctar\", \"Obsequio\", \"Pócima\", \"Quijada\", \"Ráfaga\", \"Sombrío\", \"Talismán\",\n    \"Universo\", \"Vaho\", \"Waflera\", \"Yegua\", \"Zepelín\", \"Acentuar\", \"Binario\", \"Clavícula\", \"Desidia\", \"Énfasis\",\n    \"Fantasma\", \"Glamour\", \"Horizonte\", \"Incandescente\", \"Jazmín\", \"Kaleidoscopio\", \"Luminoso\", \"Monolito\", \"Nudillo\", \"Óleo\",\n    \"Polvo\", \"Quieto\", \"Rompecabezas\", \"Silencio\", \"Transparente\", \"Ulterior\", \"Vertiente\", \"Xiita\", \"Yacimiento\", \"Zaguán\",\n    \"Anacronismo\", \"Bombilla\", \"Colmena\", \"Divagar\", \"Esmeralda\", \"Flecha\", \"Galaxia\", \"Hongo\", \"Idolatría\", \"Joya\",\n    \"Kayak\", \"Letargo\", \"Melodía\", \"Nido\", \"Ocaso\", \"Palabras\", \"Quetzal\", \"Rumor\", \"Sabor\", \"Trama\",\n    \"Urna\", \"Viento\", \"Wombat\", \"Yate\", \"Zarpa\", \"Altruista\", \"Bamba\", \"Célula\", \"Despertar\", \"Escarcha\",\n    \"Farol\", \"Gaveta\", \"Hiena\", \"Incierto\", \"Jacarandá\", \"Kilo\", \"Lápiz\", \"Máscara\", \"Neón\", \"Olla\",\n    \"Pluma\", \"Querubín\", \"Rinoceronte\", \"Sombra\", \"Tijera\", \"Útil\", \"Vacío\", \"Whisky\", \"Yacaré\", \"Zafarrancho\"\n]\ndef fifo():\n    my_lista = []\n    for element in palabras_aleatorias:\n        if len(my_lista) <= 10:\n            my_lista.append(element)\n        else:\n            output = my_lista.pop(0)\n            print(output, end=\", \")\n            my_lista.append(element)\n    restante = len(my_lista)\n    for element in range(restante):\n        output = my_lista.pop(0)\n        if element == restante - 1:\n            print(output)\n        else:\n            print(output, end=\", \")\n\ndef lifo():\n    my_lista = []\n    for element in palabras_aleatorias:\n        if len(my_lista) <= 10:\n            my_lista.append(element)\n        else:\n            output = my_lista.pop(-1)\n            print(output, end=\", \")\n            my_lista.append(element)\n    restante = len(my_lista)\n    for element in range(restante):\n        output = my_lista.pop(-1)\n        if element == restante - 1:\n            print(output)\n        else:\n            print(output, end=\", \")\n\ndef navegacion():\n    my_lista = []\n    my_lista_fow =[]\n    cururl = ''\n    while True:\n        print('Por favor indica la url a la que quieres navegar, o si quieres ir \"atras\" o \"adelante\", o \"salir\"')\n        url = input('>').lower()\n        match url:\n            case \"salir\":\n                return\n            case \"atras\":\n                if len(my_lista) > 0:\n                    my_lista_fow.insert(0, cururl)\n                    cururl = my_lista.pop()\n                    print(f'{\"-\"*50}\\nhttp://{cururl}\\n{\"-\"*50}')\n                else:\n                    print(\"No hay datos de web anteriores\")\n            case \"adelante\":\n                if len(my_lista_fow) > 0:\n                    my_lista.append(cururl)\n                    cururl = my_lista_fow.pop(0)\n                    print(f'{\"-\"*50}\\nhttp://{cururl}\\n{\"-\"*50}')\n                else:\n                    print('No hay ninguna web guardada')\n            case _:\n                my_lista.append(cururl)\n                cururl = url\n                print(f'{\"-\"*50}\\nhttp://{cururl}\\n{\"-\"*50}')\n                if len(my_lista_fow) > 0: my_lista_fow.clear()\n\ndef imprimir():\n    my_lista_impr = []\n    while True:\n        print('Por favor envía el archivo, dale a \"imprimir\" o \"salir\"')\n        document = input('>').lower()\n        match document:\n            case \"salir\":\n                return\n            case \"imprimir\":\n                if len(my_lista_impr) == 0:\n                    print(f'{\"-\"*50}\\nNúmero de documentos que hay en la cola de impresión: {len(my_lista_impr)}\\n{\"-\"*50}')\n                else:\n                    printdocument = my_lista_impr.pop(0)\n                    print(f'{\"-\"*50}\\nImprimiento el documento: {printdocument} \\nNúmero de documentos que quedan en la cola de impresión: {len(my_lista_impr)}\\n{\"-\"*50}')\n            case _:\n                my_lista_impr.append(document)\n                print(f'{\"-\"*50}\\nNúmero de documentos en la cola de impresión: {len(my_lista_impr)}\\n{\"-\"*50}')\n\ndef main():\n    fifo()\n    serparacion('.-')\n    lifo()\n    serparacion('.-')\n    navegacion()\n    serparacion('.-')\n    imprimir()\n    serparacion('.-')\n\nmain()\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/cbuenrostrovalverde.py",
    "content": "# # #07 PILAS Y COLAS\n\n# /*\n#  * EJERCICIO:\n#  * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n#  * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n#  * o lista (dependiendo de las posibilidades de tu lenguaje).\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n#  *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n#  *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n#  *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n#  *   el nombre de una nueva web.\n#  * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n#  *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n#  *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n#  *   interpretan como nombres de documentos.\n#  */\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/cesar-ch.py",
    "content": "# pila\npila = []\n\n# push\npila.append(1)\npila.append(2)\npila.append(3)\n\n# pop\npila.pop()\nprint(pila)\n\n# cola\ncola = []\n\n# enqueue\ncola.append(1)\ncola.append(2)\ncola.append(3)\n\n# dequeue\ncola.pop(0)\nprint(cola)\n\n# DIFICULTAD EXTRA\n\n\ndef webNavigation():\n    stack = []\n\n    while True:\n        action = input(\"Añade una url o interactúa con palabras adelante/atras/salir: \")\n\n        if action == \"salir\":\n            print(\"Saliendo del navegador web.\")\n            break\n        elif action == \"adelante\":\n            continue\n        elif action == \"atras\":\n            if len(stack) > 0:\n                stack.pop()\n        else:\n            stack.append(action)\n\n        if len(stack) > 0:\n            print(\"Has navegado a la web:\", stack[-1])\n        else:\n            print(\"Estás en la página de inicio.\")\n\n\nwebNavigation()\n\n\ndef sharedPrinted():\n    queue = []\n\n    while True:\n        action = input(\"Añade un documento o selecciona imprimir/salir: \")\n\n        if action == \"salir\":\n            break\n        elif action == \"imprimir\":\n            if len(queue) > 0:\n                print(\"Imprimiendo:\", queue.pop(0))\n        else:\n            queue.append(action)\n        print(\"Cola de impresión:\", queue)\n\n\nsharedPrinted()\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/chartypes.py",
    "content": "'''\n# #07 PILAS Y COLAS\n> #### Dificultad: Media | Publicación: 12/02/24 | Corrección: 19/02/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n \n'''\n\nclass Stack(list):\n    '''\n    Stack class with the basics methods of a stack\n    '''\n    def __init__(self)->None:\n        self.__stack = []\n\n    # Adding the new element at the end of the list (Last In First Out)\n    def push_element(self,element:any)->None:\n        self.__stack.append(element)\n\n\n    # Deleting the last element of the list (Last In First Out)\n    def pop_element(self)->any:\n        if len(self.__stack)<1:\n            return 'error stack is empty add more elements'\n        return self.__stack.pop()\n\n    # To show the __stack in a better way\n    def __str__(self):\n        return str( self.__stack )\n\nclass Queve(list):\n    '''\n    Queve class with the basics methods of a queve\n    '''\n    def __init__(self)->None: # Create a new list \n        self.__queve = []\n\n    # Adding the new element at the end of the list (First In First Out)\n    def enqueve(self,element:any)->None: \n        self.__queve.append(element)\n\n    # Deleting the element of the begins of the list (First In First Out)\n    def dequeve(self)-> any:\n        if len(self.__queve)<1:\n            return 'error queve is empty add more elements'\n        return self.__queve.pop(0)\n\n    # To show the __queve in a better way\n    def __str__(self):\n        return str( self.__queve )\n\n\n'''\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atras\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n'''\n\nclass Browser():\n    def __init__(self) -> None:\n        self.__back:Stack =Stack()\n        self.__foward:Stack =Stack()\n        self.__current:str = ''\n\n    def go_to(self,text:str) -> None:\n\n        if text.lower() == 'adelante':\n            self.__back.push_element(self.__current)\n            self.__current = self.__foward.pop_element()\n            print(f'Going foward to... {self.__current}')\n\n        elif text.lower() == 'atras':\n            self.__foward.push_element(self.__current)\n            self.__current = self.__back.pop_element()\n            print(f'Going back to... {self.__current}')\n\n        else:\n            self.__back.push_element(self.__current)\n            self.__current = text\n            print(f'Going to... {self.__current}')\n\n# chrome = Browser()\n# chrome.go_to('retosdeprogramacion.com')\n# chrome.go_to('bsky.social')\n# chrome.go_to('github.com')\n# chrome.go_to('atras')\n# chrome.go_to('atras')\n# chrome.go_to('adelante')\n# chrome.go_to('adelante')\n# chrome.go_to('adelante')\n\n\nclass Printer():\n    def __init__(self)->None:\n        self.__queve:Queve = Queve()\n    def to_print_document(self,document:any)->None:\n        if document == 'imprimir':\n            print(self.__queve.dequeve()) \n        else:\n            print('Adding element...')\n            self.__queve.enqueve(document)\n\n# my_printer = Printer()\n# my_printer.to_print_document(5)\n# my_printer.to_print_document('tall')\n# my_printer.to_print_document('imprimir')\n# my_printer.to_print_document('imprimir')\n# my_printer.to_print_document('imprimir')\n# my_printer.to_print_document('4')\n# my_printer.to_print_document('imprimir')\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/clmiranda.py",
    "content": "# PILAS Y COLAS\n\n# PILA/STACK (LIFO: LAST IN, FIRST OUT)\nstack = [15, 83]\n\n# PUSH\nstack.append(100)\nstack.append(\"Hola Mundo\")\nstack.append(False)\nprint(stack)\n\n# POP\nstack.pop()\nstack.pop()\nprint(stack)\n\n\n# COLA/QUEUE (FIFO: FIRST IN, FIRST OUT)\nqueue = [\"Python\", 78]\n\n# ENQUEUE\nqueue.append(5)\nqueue.append(19)\nprint(queue)\n\n# DEQUEUE\nqueue.pop(0)\nprint(queue)\n\n\n# EJERCICIO - DIFICULTAD EXTRA\n\n# NAVEGADOR WEB\ndef navegador_web():\n    pila = []\n    index = -1\n    while True:\n        valor = input(\"\\nIngrese una opción (nombre de la web, adelante, atrás, salir): \")\n        if valor:\n            try:\n                match valor:\n                    case \"adelante\":\n                        print(f\"Adelantando a la web: {pila[index]}\")\n                        index -= 1\n                    case \"atras\":\n                        if len(pila) > 0:\n                            last = pila.pop()\n                            print(f\"Volviendo a la web: {last}\")\n                        else:\n                            print(\"Página de inicio\")\n                    case \"salir\":\n                        print(\"Saliendo del navegador web\")\n                        break\n                    case _:\n                        pila.append(valor)\n                        print(f\"Navegando a la web: {valor}\")\n            except:\n                print(\"No se puede adelantar a otra página\")\n        else:\n            print(\"Debe ingresar alguna de las opciones\")\n\nnavegador_web()\n\n\n# IMPRESORA\ndef impresora():\n    cola = []\n    while True:\n        valor = input(\"\\nIngrese una opción (nombre del documento, imprimir, salir): \")\n        match valor:\n            case \"imprimir\":\n                if len(cola) > 0:\n                    first = cola.pop(0)\n                    print(f\"Imprimiendo documento: {first}\")\n                else:\n                    print(\"No hay documentos para imprimir\")\n            case \"salir\":\n                print(\"Saliendo de la aplicación\")\n                break\n            case _:\n                cola.append(valor)\n\n        print(f\"Cola de impresión: {cola}\")\n\nimpresora()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/cristianfloyd.py",
    "content": "\"\"\"* EJERCICIO:\n* Implementa los mecanismos de introducción y recuperación de elementos propios de las\n* pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n* o lista (dependiendo de las posibilidades de tu lenguaje).\n*\"\"\"\n\n# pila/Stack (LIFO)\nprint(\"=\" * 80)\nprint(\"PILA/STACK (LIFO)\")\nprint(\"=\" * 80)\n\nstack = []\n# push\nstack.append(1)\nstack.append(2)\nstack.append(3)\nprint(f\"Stack luego de agregar elementos: {stack}\")\n# pop\nitem_extraido = stack.pop()\nprint(f\"Stack luego de eliminar el último elemento: {stack}\")\nprint(f\"Elemento extraído de la pila: {item_extraido}\")\n\nstack_item = stack[len(stack) - 1]\ndel stack[len(stack) - 1]\nprint(f\"Elemento extraído de la pila: {stack_item}\")\nprint(f\"Stack luego de eliminar el último elemento: {stack}\")\n\n# cola/Queue (FIFO)\nprint(\"=\" * 80)\nprint(\"COLA/QUEUE (FIFO)\")\nprint(\"=\" * 80)\n\nqueue = []\n# enqueue\nqueue.append(1)\nqueue.append(2)\nqueue.append(3)\nprint(f\"Queue luego de agregar elementos: {queue}\")\n\n# dequeue\nitem_extraido_cola = queue.pop(0)\nprint(f\"Queue luego de eliminar el primer elemento: {queue}\")\nprint(f\"Elemento extraído de la cola: {item_extraido_cola}\")\n\n\nclass Pila:\n    def __init__(self, lista: list = []) -> None:\n        self.items = lista\n\n    def esta_vacia(self) -> bool:\n        \"\"\"Verifica si la pila está vacía.\"\"\"\n        return len(self.items) == 0\n\n    def apilar(self, valor) -> None:\n        \"\"\"Añade un elemento al tope de la pila.\"\"\"\n        self.items.append(valor)\n\n    def desapilar(self):\n        \"\"\"Elimina y retorna el elemento del tope de la pila.\"\"\"\n        if not self.esta_vacia():\n            return self.items.pop()\n        else:\n            raise IndexError(\"La pila está vacía\")\n\n    def buscar(self, valor):\n        \"\"\"Busca un elemento en la pila.\"\"\"\n        return valor in self.items\n\n    def ver_tope(self):\n        \"\"\"Retorna el elemento del tope de la pila sin eliminarlo.\"\"\"\n        if not self.esta_vacia():\n            return self.items[-1]\n        else:\n            raise IndexError(\"La pila está vacía\")\n\n    def ver(self):\n        \"\"\"Retorna todos los elementos de la pila.\"\"\"\n        return self.items\n    \n    def limpiar(self) -> None:\n        \"\"\"Limpia todos los elementos de la pila.\"\"\"\n        self.items = []\n\n    def __len__(self):\n        \"\"\"Retorna el número de elementos en la pila.\"\"\"\n        return len(self.items)\n\n\n# Ejemplo de uso de la clase Pila\nprint(\"=\" * 80)\nprint(\"Ejemplo de uso de la clase Pila:\")\nprint(\"=\" * 80)\nobjeto_pila = Pila([1, 2, 3])\nprint(f\"Elementos en la pila: {objeto_pila.ver()}\")\n\nobjeto_pila.apilar(4)\nprint(f\"Elementos en la pila después de apilar 4: {objeto_pila.ver()}\")\n\nitem_extraido = objeto_pila.desapilar()\nprint(f\"Elementos en la pila después de desapilar: {objeto_pila.ver()}\")\nprint(f\"Elemento extraído de la pila: {item_extraido}\")\n\nprint(f\"¿Está vacía la pila? {objeto_pila.esta_vacia()}\")\n\nprint(f\"Elemento en el tope de la pila: {objeto_pila.ver_tope()}\")\n\nprint(f\"¿El valor 2 está en la pila? {objeto_pila.buscar(2)}\")\n\nprint(f\"Número de elementos en la pila: {len(objeto_pila)}\")\n\n\nclass Cola:\n    def __init__(self, items: list = []) -> None:\n        self.items = items\n\n    def esta_vacia(self) -> bool:\n        \"\"\"Verifica si la cola está vacía.\"\"\"\n        return len(self.items) == 0\n\n    def encolar(self, valor) -> None:\n        \"\"\"Añade un elemento al final de la cola.\"\"\"\n        self.items.append(valor)\n\n    def desencolar(self):\n        \"\"\"Elimina y retorna el elemento al frente de la cola.\"\"\"\n        if not self.esta_vacia():\n            return self.items.pop(0)\n        else:\n            raise IndexError(\"La cola está vacía\")\n\n    def buscar(self, valor) -> bool:\n        \"\"\"Busca un elemento en la cola.\"\"\"\n        return valor in self.items\n\n    def ver_frente(self):\n        \"\"\"Retorna el elemento al frente de la cola sin eliminarlo.\"\"\"\n        if not self.esta_vacia():\n            return self.items[0]\n        else:\n            raise IndexError(\"La cola está vacía\")\n\n    def ver(self) -> list:\n        \"\"\"Retorna todos los elementos de la cola.\"\"\"\n        return self.items\n\n    def __len__(self) -> int:\n        \"\"\"Retorna el número de elementos en la cola.\"\"\"\n        return len(self.items)\n\n    def __add__(self, valor):\n        \"\"\"Permite usar el operador + para encolar un elemento.\"\"\"\n        self.encolar(valor)\n        return self\n\n\n# Ejemplo de uso de la clase Cola\nprint(\"=\" * 80)\nprint(\"Ejemplo de uso de la clase Cola:\")\nprint(\"=\" * 80)\nobjeto_cola = Cola([1, 2, 3])\nprint(f\"Elementos en la cola: {objeto_cola.ver()}\")\n\nobjeto_cola.encolar(4)\nprint(f\"Elementos en la cola después de encolar 4: {objeto_cola.ver()}\")\nobjeto_cola + 5\nprint(f\"Elementos en la cola después de encolar 5 usando '+': {objeto_cola.ver()}\")\n\nprint(f\"Elemento en el frente de la cola: {objeto_cola.ver_frente()}\")\nitem_extraido = objeto_cola.desencolar()\nprint(f\"Elementos en la cola después de desencolar: {objeto_cola.ver()}\")\nprint(f\"Elemento extraído de la cola: {item_extraido}\")\n\nprint(f\"¿Está vacía la cola? {objeto_cola.esta_vacia()}\")\n\nprint(f\"¿El valor 2 está en la cola? {objeto_cola.buscar(2)}\")\n\nprint(f\"Número de elementos en la cola: {len(objeto_cola)}\")\n\n\n\n\"\"\"  * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n *    \"\"\"\n\nclass NavegadorWeb:\n    \"\"\"\n    Simula un navegador web con funcionalidad adelante/atrás utilizando una pila.\n    \"\"\"\n    def __init__(self):\n        self.historial = Pila()\n        self.adelante_stack = Pila()\n        self.pagina_actual = None\n\n    def navegar_a(self, url: str):\n        if self.pagina_actual:\n            self.historial.apilar(self.pagina_actual)\n        self.pagina_actual = url # se establece la nueva página actual\n        self.adelante_stack.limpiar()  # limpiar el stack de adelante al navegar a una nueva página\n        print(f\"Navegando a: {self.pagina_actual}\")\n\n    def atras(self):\n        if not self.historial.esta_vacia(): # verificar historial no vacio\n            self.adelante_stack.apilar(self.pagina_actual)\n            self.pagina_actual = self.historial.desapilar()\n            print(f\"Regresando a: {self.pagina_actual}\")\n        else:\n            print(\"No hay páginas en el historial.\")\n        \n    def añadir_pagina(self, url: str):\n        if self.pagina_actual:\n            self.historial.apilar(self.pagina_actual)\n        self.pagina_actual = url\n        print(f\"Navegando a: {self.pagina_actual}\")\n\n    def adelante(self):\n        if not self.adelante_stack.esta_vacia():\n            self.historial.apilar(self.pagina_actual)\n            self.pagina_actual = self.adelante_stack.desapilar()\n            print(f\"Avanzando a: {self.pagina_actual}\")\n        else:\n            print(\"No hay páginas adelante.\")\n\n    def obtener_pagina_actual(self):\n        return self.pagina_actual\n\ndef simulacion_navegador():\n    firefox = NavegadorWeb()\n    while True:\n        accion = input(\"Ingresa una URL, 'atras', 'adelante' o 'salir': \")\n        if accion == \"salir\":\n            print(\"Saliendo del navegador.\")\n            break\n        elif accion == \"atras\":\n            firefox.atras()\n        elif accion == \"adelante\":\n            firefox.adelante()\n        else:\n            firefox.navegar_a(accion)\n        print(f\"Página actual: {firefox.obtener_pagina_actual()}\")\n\n\nsimulacion_navegador()\n\n\n#  * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n#  *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n#  *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n\nclass impresoraCompartida:\n    \"\"\"\n    Simula una impresora compartida utilizando una cola.\n    \"\"\"\n    def __init__(self):\n        self.cola_impresion = Cola()\n\n    def agregar_documento(self, documento: str):\n        self.cola_impresion.encolar(documento)\n        print(f\"Documento '{documento}' agregado a la cola de impresión.\")\n\n    def imprimir(self):\n        if not self.cola_impresion.esta_vacia():\n            documento_a_imprimir = self.cola_impresion.desencolar()\n            print(f\"Imprimiendo documento: {documento_a_imprimir}\")\n        else:\n            print(\"No hay documentos en la cola de impresión.\")\n\ndef simulacion_impresora():\n    epson_lx300 = impresoraCompartida()\n    while True:\n        accion = input(\"Ingresa el nombre del documento para agregar a la cola, 'imprimir' o 'salir': \")\n        match accion:\n            case \"salir\":\n                print(\"Saliendo de la impresora.\")\n                break\n            case \"imprimir\":\n                epson_lx300.imprimir()\n            case _:\n                epson_lx300.agregar_documento(accion)\n\nsimulacion_impresora()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/dandreara-boop.py",
    "content": "\r\n\r\ndef pila ():\r\n        print('+' * 30 , 'pila' , '+'*30)\r\n        stack=[]\r\n        stack.append(1)\r\n        stack.append(2)\r\n        stack.append(3)\r\n        print (f'lista completa {stack}')\r\n        print(f'eliminando ultimo en entrar {stack[(len(stack)-1)]}')\r\n        del stack[(len(stack)-1)]\r\n        print (f'lista actual elemento eliminado sin usar pop {stack}' )\r\n\r\n\r\n        print (f'eliminando elemento por metodo pop {stack.pop()}')\r\n        print (f'lista final {stack}')\r\n\r\ndef cola():\r\n        print('+' * 30 , 'cola' , '+'*30)\r\n        stack=[]\r\n        stack.append(1)\r\n        stack.append(2)\r\n        stack.append(3)\r\n\r\n        print (f'lista completa {stack}')\r\n        print(f'primero en entrar {stack[0]}')\r\n        del stack[0]\r\n        print ('ultimo elemento eliminado sin usar pop' )\r\n\r\n\r\n        print (f'eliminando por metodo pop {stack.pop(0)}')\r\n        print (f'lista final {stack}')\r\n\r\n\r\n\r\n\r\ndef N_web():\r\n\r\n        h_nav=[]\r\n        posicion = -1\r\n\r\n        while True:\r\n                \r\n                peticion=input(\"ingrese (p)proximo , (a) anterior , ingrese una nueva url (s)salir : \")\r\n        \r\n        \r\n\r\n                if peticion == \"a\":\r\n                        \r\n                        \r\n                        if posicion > 0 :\r\n                                posicion -= 1\r\n                                print (h_nav[posicion])\r\n                        elif posicion == 0 :\r\n                        \r\n                                        print(f'estas en el comienzo {h_nav[posicion]}')\r\n                        else :\r\n                                print ('esta vacia')\r\n                        \r\n\r\n                        \r\n                elif peticion == \"p\":\r\n                        if posicion <0 :\r\n                                print ('esta vacia')\r\n\r\n                        elif posicion < (len(h_nav)-1):\r\n                                posicion += 1\r\n                                print(h_nav[posicion])\r\n\r\n                        else :\r\n                                print (f'estas en el fina {h_nav[posicion]}')\r\n                \r\n                elif peticion == \"s\":\r\n                        break\r\n                \r\n                else :\r\n                        h_nav.append(peticion)        \r\n                        posicion=len(h_nav)-1\r\n                        \r\n\r\ndef imprimir():\r\n        cola=[]\r\n\r\n        while True :\r\n                peticion=input('ingrese documento ,s/salir,i/imprimir : ')\r\n                \r\n                if peticion == 's' :\r\n                        break\r\n                elif peticion == 'i':\r\n                        if len(cola) > 0 :\r\n                                print(cola.pop(0))\r\n                else:\r\n                        cola.append(peticion)\r\n\r\n\r\npila()\r\ncola()\r\nprint ('+'*25, 'dificultad extra','+' *25)\r\n\r\nwhile True:\r\n        print('''\r\n              1- Ejercicio navegador\r\n              2- Ejercicio imprimir\r\n              3- Salir ''')\r\n        entrada=int(input('ingrese la opcion : '))\r\n        if entrada==3:\r\n                break\r\n        elif entrada== 1:\r\n                N_web()\r\n        elif entrada==2:\r\n                imprimir()\r\n\r\n\r\n    \r\n    "
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/danielhdzr.py",
    "content": "# #07 PILAS Y COLAS\n#### Dificultad: Media | Publicación: 12/02/24 | Corrección: 19/02/24\n\n## Ejercicio\n''' \n* EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n '''\ndef main():\n    \"\"\"\n    Creamos nuestra pila.\n    En las pilas o stacks el ultimo elemnto u objeto en entrar es el primero en salir\n    \"\"\" \n    pila = [1, 2, 3, 4, 5]\n    print(f\"Pila original: {pila}\")\n    # Introducimos nuevo objeto a la lista\n    pila.append(6)\n    print(f\"Pila despues de introducirle nuevo objeto: {pila}\")\n    # Recuperamos un elemento \n    elemento_pila = pila.pop()\n    print(f\"Elemento recuperado: {elemento_pila}\")\n    print(f\"Pila final: {pila}\")\n\n    \"\"\"\n    Creamos nuestra cola.\n    En las colas o queues el primer elemnto u objeto en entrar es el primero en salir\n    \"\"\" \n    cola = [1, 2, 3, 4, 5]\n    print(f\"Cola original: {cola}\")\n    cola.append(6)\n    print(f\"Cola despues de introducirle nuevo objeto: {cola}\")\n    elemento_cola = cola.pop(0)\n    print(f\"Elemento recuperado de cola: {elemento_cola}\")\n    print(f\"Cola final: {cola}\")\n\n   \n\n    \nif __name__==\"__main__\":\n    main()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/davidrguez98.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */ \"\"\"\n\n#EJERCICIO\n\n#Pila/Stack (LIFO - Last In First Out)\n\nstack = []\nstack.append(\"1\") #Push\nstack.append(\"2\") #Push\nstack.append(\"3\") #Push\nprint(stack)\n\n\"\"\" stack_item = stack[len(stack) -1] #Pop\ndel stack[len(stack) -1]\nprint(stack_item) \"\"\"\n\nprint(stack.pop())\n\nprint(stack)\n\n#Cola/Queue (FIFO - First In First Out)\n\"\"\" \nqueue = []\nqueue.append(1) #Enqueue\nqueue.append(2) #Enqueue\nqueue.append(3) #Enqueue\nprint(queue)\n\nqueue_item = queue[0] #Dequeue\ndel queue[0]\nprint(queue_item)\n\nprint(queue.pop(0)) #Dequeue\n\nprint(queue) \"\"\"\n\n#DIFICULTAD EXTRA\n\n# Navegador\n\nnav = []\n\nnav.append(\"Web 1\")\nnav.append(\"Web 1/Web 2\")\nnav.append(\"Web 1/Web 2/Web 3\")\n\nposition = 0 \n\ndef forward():\n    nav[position]\n    \n\ndef backward():\n    nav[position]\n\n\nwhile True:\n\n    print(\"Actualmente estás en: \", nav[position])\n    question = input(\"¿Qué quieres añadir una web, ir hacia adelante, ir hacia atrás o salir: \")\n\n    if question.lower() == \"adelante\" or question.lower() == \"ir hacia adelante\":\n        position += 1\n        forward()\n    elif question.lower() == \"atrás\" or question.lower() == \"atras\" or question.lower() == \"ir hacia atrás\" or question.lower() == \"ir hacia atras\":\n        position -= 1\n        backward()\n    elif question.lower() == \"añadir\":\n        nav.append(input(\"Añade la web:\" ))\n    elif question.lower() == \"salir\":\n        break\n    else:\n        print(\"La opción seleccionada es incorrecta, elija adelante o atrás.\")\n\n# Impresora\n\nqueue_printer = []\n\ndef add_paper():\n    queue_printer.append(input(\"Nombre del documento que quiere añadir a la cola para imprimir: \"))\n\ndef print_paper():\n    print(\"Se está imprimiendo: \", queue_printer.pop(0))\n\nwhile True:\n    quest = input(\"¿Quieres añadir un documento a la cola de impresión, imprimir o salir?: \")\n\n    if quest.lower() == \"añadir\" or quest.lower() == \"añadir un documento a la cola de impresión\":\n        add_paper()\n        print(\"La cola de impresión es: \", queue_printer)\n    elif quest.lower() == \"imprimir\":\n\n        print_paper()\n        print(\"La cola de impresión es: \", queue_printer)\n    elif quest.lower() == \"salir\":\n        break\n    else:\n        print(\"La opción seleccionada es incorrecta, elija añadir, imprimir o salir.\")"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/duendeintemporal.py",
    "content": "#7 { Retos para Programadores }  PILAS Y COLAS\n\"\"\"\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n\"\"\"\n\n# The list structure in Python can be useful to simulate stacks and queues.\n\n# A stack is a linear data structure that follows the Last In, First Out (LIFO) principle.\n# This means that the last element added to the stack is the first one to be removed.\n# You can think of it like a stack of plates: you add plates to the top and also remove them from the top.\n# Key Operations:\n# - Push: Add an element to the top of the stack.\n# - Pop: Remove the element from the top of the stack.\n# - Peek/Top: Retrieve the top element without removing it.\n# - IsEmpty: Check if the stack is empty.\n\nlog = print\n\n# Stack implementation using a list\nstack = [1, 2, 3, 4]\n\n# View the contents of a stack\nlog('View stack:', stack)  # View stack: [1, 2, 3, 4]\n\n# Add an element to the stack\nstack.append(5)\nlog('Add an element:', stack)  # Add an element: [1, 2, 3, 4, 5]\n\n# Get the size of the stack\nlog('Size:', len(stack))  # Size: 5\n\n# Get the last value of the stack\nlog('Last value of the stack:', stack[-1])  # Last value of the stack: 5\n\n# Remove the last value from the stack and print its value\nlog('Delete and return the last value:', stack.pop())  # Delete and return the last value: 5\n\n# Empty the stack\nstack = []\nlog('Empty the stack:', stack)  # Empty the stack: []\n\n# We can also enclose the stack operations in a class for better organization and reusability\nclass Stack:\n    def __init__(self, initial_items=None):\n        # Initialize the stack with an optional list of items\n        self.items = initial_items if isinstance(initial_items, list) else []\n\n    def push(self, element):\n        # Add an element to the top of the stack\n        self.items.append(element)\n\n    def pop(self):\n        # Remove the element from the top of the stack\n        if self.is_empty():\n            log(\"Stack is empty. Cannot pop an element.\")\n            return None\n        return self.items.pop()\n\n    def peek(self):\n        # Retrieve the top element without removing it\n        if self.is_empty():\n            log(\"Stack is empty. Cannot peek.\")\n            return None\n        return self.items[-1]\n\n    def empty(self):\n        # Empty the stack\n        self.items = []\n\n    def is_empty(self):\n        # Check if the stack is empty\n        return len(self.items) == 0\n\n    def size(self):\n        # Get the size of the stack\n        return len(self.items)\n\n# Create a new stack instance\nstack2 = Stack([55, 76, 98, 100])\nlog('Initial stack2:', stack2.items)  # [55, 76, 98, 100]\n\nstack2.push(32)\nlog('After pushing 32:', stack2.items)  # [55, 76, 98, 100, 32]\n\nlog('Peek:', stack2.peek())  # 32\n\nlog('Pop:', stack2.pop())  # 32\nlog('After popping:', stack2.items)  # [55, 76, 98, 100]\n\nlog('Pop all elements:')\nwhile not stack2.is_empty():\n    log('Popped:', stack2.pop())\n# or we can just empty the stack\n# stack2.empty()\n\nlog('Final stack2:', stack2.items)  # []\nlog('Pop from empty stack2:', stack2.pop())  # Stack is empty. \n# Cannot pop an element. & None\n\n# Queue implementation\n# A queue is a linear data structure that follows the First In, First Out (FIFO) principle.\n# This means that the first element added to the queue is the first one to be removed.\n# You can think of it like a line of people waiting for service: the first person in line is the first to be served.\n# Key Operations:\n# - Enqueue: Add an element to the end of the queue.\n# - Dequeue: Remove the element from the front of the queue.\n# - Front/Peek: Retrieve the front element without removing it.\n# - IsEmpty: Check if the queue is empty.\n\n# Queue implementation using a list\nqueue = [8, 5, 4, 2, 1]\n\n# View the contents of a queue\nlog('View queue:', queue)  # View queue: [8, 5, 4, 2, 1]\n\n# Add elements to the queue\n# Add elements to the queue\nqueue.append(7)\nlog('Add an element:', queue)  # Add an element: [8, 5, 4, 2, 1, 7]\n\n# Get the size of the queue\nlog('Size:', len(queue))  # Size: 6\n\n# Get the first value of the queue\nlog('First value:', queue[0])  # First value: 8\n\n# Remove the first value from the queue and log its value\nlog('Delete and return the first value:', queue.pop(0))  # Delete and return the first value: 8\n\n# Empty the queue\nqueue = []\nlog('Empty the queue:', queue)  # Empty the queue: []\n\n# We can also enclose the queue operations in a class for better organization and reusability\nclass Queue:\n    def __init__(self, initial_items=None):\n        # Initialize the queue with an optional list of items\n        self.items = initial_items if isinstance(initial_items, list) else []\n\n    def enqueue(self, element):\n        # Add an element to the end of the queue\n        self.items.append(element)\n\n    def dequeue(self):\n        # Remove the element from the front of the queue\n        if self.is_empty():\n            log(\"Queue is empty. Cannot dequeue an element.\")\n            return None\n        return self.items.pop(0)\n\n    def front(self):\n        # Retrieve the front element without removing it\n        if self.is_empty():\n            log(\"Queue is empty. Cannot peek.\")\n            return None\n        return self.items[0]\n\n    def empty(self):\n        # Empty the queue\n        self.items = []\n\n    def is_empty(self):\n        # Check if the queue is empty\n        return len(self.items) == 0\n\n    def size(self):\n        # Get the size of the queue\n        return len(self.items)\n\n# Create a new queue instance\nqueue2 = Queue([8, 5, 4, 2, 1])\nlog('Initial queue2:', queue2.items)  # [8, 5, 4, 2, 1]\n\nqueue2.enqueue(7)\nlog('After enqueueing 7:', queue2.items)  # [8, 5, 4, 2, 1, 7]\n\nlog('Front:', queue2.front())  # 8\n\nlog('Dequeue:', queue2.dequeue())  # 8\nlog('After dequeueing:', queue2.items)  # [5, 4, 2, 1, 7]\n\nlog('Dequeue all elements:')\nwhile not queue2.is_empty():\n    log('Dequeued:', queue2.dequeue())\n# or we can just empty the queue\n# queue2.empty()\n\nlog('Final queue2:', queue2.items)  # []\nlog('Dequeue from empty queue2:', queue2.dequeue())  # Dequeue from empty queue2:. \n# Cannot dequeue an element. & None\n\n # Additional exercises:\n\n # Simulate the behavior of the back and forward buttons in a browser.\n\n# List of documents to print\ndocuments_queue = [\n    {'name': 'Tratado de Tantra.txt', 'content': 'Here comes the content of Tratado de Tantra.'},\n    {'name': 'Nada Sagrado.doc', 'content': 'Here comes the content of Nada Sagrado.'},\n    {'name': 'El Blanco Invisible.pdf', 'content': 'Here comes the content of El Blanco Invisible.'}\n]\n\ndef print_queue(arr):\n    if len(arr) == 0:\n        log('There are no elements to print in the queue!')\n        return\n    while len(arr) > 0:\n        document = arr.pop(0)  # Get the first document\n        log('Printing document:', document['name'])\n        log('Content:', document['content'])\n    log('There are no more elements to print in the queue!')\n\nprint_queue(documents_queue)\n# Output:\n# Printing document: Tratado de Tantra.txt\n# Content: Here comes the content of Tratado de Tantra.\n# Printing document: Nada Sagrado.doc\n# Content: Here comes the content of Nada Sagrado.\n# Printing document: El Blanco Invisible.pdf\n# Content: Here comes the content of El Blanco Invisible.\n# There are no more elements to print in the queue!\n\n# Simulate the behavior of the back and forward buttons in a browser.\n\n# List of documents to print\ndocuments_queue = [\n    {'name': 'Tratado de Tantra.txt', 'content': 'Here comes the content of Tratado de Tantra.'},\n    {'name': 'Nada Sagrado.doc', 'content': 'Here comes the content of Nada Sagrado.'},\n    {'name': 'El Blanco Invisible.pdf', 'content': 'Here comes the content of El Blanco Invisible.'}\n]\n\ndef print_queue(arr):\n    if len(arr) == 0:\n        log('There are no elements to print in the queue!')\n        return\n    while len(arr) > 0:\n        document = arr.pop(0)  # Get the first document\n        log('Printing document:', document['name'])\n        log('Content:', document['content'])\n    log('There are no more elements to print in the queue!')\n\nprint_queue(documents_queue)\n# Output:\n# Printing document: Tratado de Tantra.txt\n# Content: Here comes the content of Tratado de Tantra.\n# Printing document: Nada Sagrado.doc\n# Content: Here comes the content of Nada Sagrado.\n# Printing document: El Blanco Invisible.pdf\n# Content: Here comes the content of El Blanco Invisible.\n# There are no more elements to print in the queue!\n\n# Simulating browser navigation\nurl_stack = []\ncurrent_index = -1  # To keep track of the current position.\n\ndef browse_web(url):\n    global current_index, url_stack  # Declare these variables as global\n\n    def back():\n        global current_index  # Declare current_index as global\n        if current_index > 0:\n            current_index -= 1\n            previous_url = url_stack[current_index]\n            log('Location:', previous_url)\n        else:\n            log(\"There are no more pages back..\")\n\n    def forward():\n        global current_index  # Declare current_index as global\n        if current_index < len(url_stack) - 1:\n            current_index += 1\n            next_url = url_stack[current_index]\n            log('Location:', next_url)\n        else:\n            log(\"There are no more pages forward.\")\n\n    if url != 'back' and url != 'forward':\n        if current_index < len(url_stack) - 1:\n            url_stack = url_stack[:current_index + 1]  # Clear forward if navigation has occurred.\n        url_stack.append(url)\n        current_index += 1\n        log('Location:', url)\n    elif url == 'back':\n        back()\n    elif url == 'forward':\n        forward()\n\n# Simulating browsing\nbrowse_web('www.lectura_prospectiva.net')  # Location: www.lectura_prospectiva.net\nbrowse_web('www.test.web')  # Location: www.test.web\nbrowse_web('back')  # Location: www.lectura_prospectiva.net\nbrowse_web('forward')  # Location: www.test.web\n\n# Simulating a simple UI setup (console-based)\ndef setup_ui():\n    log('Retosparaprogramadores #7.')\n\n# Call the UI setup function\nsetup_ui()\n\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/elbarbero.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n \"\"\"\n\nfrom collections import deque\n\ndef navigationWeb():\n    webs = [\"https://es.wikipedia.org/wiki/Wikipedia:Portada\", \"https://es.wikipedia.org/wiki/Gran_Premio_de_Abu_Dabi\", \"https://es.wikipedia.org/wiki/Lewis_Hamilton\", \"https://es.wikipedia.org/wiki/Fernando_Alonso\", \"https://es.wikipedia.org/wiki/Asturias\"]\n    index = len(webs)-1\n    print(f\"Estás en la web {webs[index]}\")\n    action = input(\"Introduce acción: \")\n    if action.lower() == \"adelante\":\n        index += 1\n    elif action.lower() == \"atras\":\n        index -= 1\n    else:\n        print(\"Comando incorrecto\")\n        \n    if index > 0 and index <= len(webs)-1:\n        new_url = webs[index]\n        print(f\"Estás en la web {new_url}\")\n    else:\n        print(\"Has llegado al limite\")\n\ndef printer():\n    docs = deque([\"mi_Doc.docx\", \"mi_Doc_FINAL.docx\", \"mi_Doc_ELBUENO.docx\", \"mi_Doc_BUENO_FINAL.pdf\"])\n    action = input(\"Introduce acción: \")\n    if action.lower() == \"imprimir\":\n        print(f\"Estás imprimiendo el documento {docs.popleft()}\")\n    else:\n        print(\"Comando incorrecto\")\n\nif __name__ == \"__main__\":\n\n    # LIFO\n    stack = [5, 6, 14, 52]\n    stack.append(9)\n    print(f\"LIFO in list {stack}-> {stack.pop()}\")\n\n    # FIFO\n    queue = deque([5, 6, 14, 52])\n    queue.append(9)\n    print(f\"FIFO in list {queue} -> {queue.popleft()}\")\n    \n    # Navegador web\n    navigationWeb()\n        \n    # Impresion documentos\n    printer()\n\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/evilpotato04.py",
    "content": "#/*\n# * EJERCICIO:\n# * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n# * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n# * o lista (dependiendo de las posibilidades de tu lenguaje).\n\n# ====== Pilas ======\npila_de_libros = []\n\n# introducción de elementos\npila_de_libros.append(\"Las mil y una noches\")\npila_de_libros.append(\"Don Quijote de la Mancha\")\npila_de_libros.append(\"Orgullo y prejuicio\")\npila_de_libros.append(\"Frankenstein o el moderno Prometeo\")\npila_de_libros.append(\"Los tres mosqueteros\")\n\n# recuperación de elementos\nfor libro in pila_de_libros:\n    print(libro)\n\nultimo_libro = pila_de_libros.pop()\nprint(ultimo_libro)\n\n# ====== Colas ======\nfrom collections import deque\n\ncola_de_personas = deque()\n\n# introducción de elementos\ncola_de_personas.append(\"Samanta\")\ncola_de_personas.append(\"Brais\")\ncola_de_personas.append(\"Roswell\")\ncola_de_personas.append(\"Andrea\")\ncola_de_personas.append(\"Jefferson\")\n\n# recuperación de elementos\nfor persona in cola_de_personas:\n    print(persona)\n\nprimera_persona = cola_de_personas.popleft()\nprint(primera_persona)\n\n# *\n# * DIFICULTAD EXTRA (opcional):\n# * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n# *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n# *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n# *   Las palabras \"adelante\", \"atras\" desencadenan esta acción, el resto se interpreta como\n# *   el nombre de una nueva web.\n\ndef navegador_web():\n    print(\"========== navegador_web ==========\")\n    paginas = []\n    index = 0\n\n    while True:\n        opcion = input(f\"Ingrese la URL del sitio web que desea navegar o escribe una de las opiciones abajo: \\n- adelante \\n- atras \\n- salir \\n\").lower()\n        \n        match opcion:\n            case \"adelante\":\n                if index + 1 <= len(paginas) - 1:\n                    index += 1\n                else:\n                    print(\"Este es el sitio web actual\")\n                print(\"Sitio web actual: \" + paginas[index] + \"\\n\\n\")\n                pass\n            case \"atras\":\n                if index - 1 >= 0:\n                    index -= 1\n                else:\n                    print(\"No hay ningún sitio web anterior al actual\")\n                print(\"Sitio web actual: \" + paginas[index] + \"\\n\\n\")\n                pass\n            case \"salir\":\n                print(\"===== Cerrando navegador_web =====\")\n                return\n            case _:\n                paginas.append(opcion)\n                index = len(paginas) - 1\n                print(\"Sitio web actual: \" + paginas[index] + \"\\n\\n\")\n                pass\n\nnavegador_web()\n\n\n# * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n# *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n# *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n# *   interpretan como nombres de documentos.\n# */\n\ndef impresora():\n    print(\"========== impresora ==========\")\n    documentos = deque()\n\n    while True:\n        opcion = input(\"Ingrese el nombre del documento para cola de impresión \\no escriba 'imprimir' para imprimir el siguiente documento en la cola: \\n('salir' para cerrar la aplicación)\")\n\n        if (opcion == \"salir\"):\n            print(\"========== Cerrando impresora ==========\")\n            return\n\n        if (opcion == \"imprimir\"):\n            if (len(documentos) == 0):\n                print(\"No hay documentos para imprimir\")\n            else:\n                documento_impreso = documentos.popleft()\n                print(\"--> Imprimindo el documento: \" + documento_impreso)\n        else:\n            documentos.append(opcion)\n            print(\"-- cola de documentos para impresión --\")\n            for doc in documentos:\n                print(doc)\n\nimpresora()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/fborjalv.py",
    "content": "# PILAS Y COLAS \n\n# PILAS / STACK (LIFO -> Last Input First Output)\n\nstack = [\"pelota roja\", \"pelota azul\"]\nprint(stack)\n\n\n# Añadir un nuevo elemento a la pila\nstack.append(\"pelota verde\")\nprint(stack)\n\n# Acceder al último elemento, que es el primero en salir y eliminarlo\nprint(stack[-1])\ndel stack[-1]\nprint(stack)\n\n# Hacemos lo mismo con el método pop de python\nstack.append(\"pelota verde\")\nprint(stack)\nstack.pop()\nprint(stack)\n\n# COLAS /QUEUE (FIFO -> First Input First Output)\n\nqueue = [\"pelota roja\", \"pelota azul\", \"pelota verde\"]\n\n# Acceder al primer elemento, que es el primero en salir y eliminarlo\nprint(queue[0])\ndel queue[0]\nprint(queue)\nqueue.insert(0,\"pelota roja\")\n\n# Hacemos lo mismo con el método pop de python\nprint(queue)\nprint(queue.pop(0))\nprint(queue)\n\n\n# EJERCICIO EXTRA\n\"\"\"\n- Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n\"\"\"\npage_history = [\"www.elmundo.es\", \"elpais.es\", \"www.abc.es\"]\n\ndef menu():\n    \n    position = 0\n    while True:\n        user_option = input(\"Introduzca una opción: 'atras', 'adelante' o diga salir. Cualquier otra opción se añadirá como sitio web \")\n        if user_option == \"adelante\":\n            print(\"Ha elegido adelante\")\n            position += 1\n            if position > len(page_history) - 1:\n                \"No hay más páginas que mostrar\"\n                print(f\"Estás en la página:  {page_history[-1]}\")\n            else:\n                print(page_history[position])\n        elif user_option == \"atras\":\n            print(\"Ha elegido atrás\")\n            position -= 1\n            if position < 0: \n                print(\"Estás en la página de inicio\")\n                print(f\"Estás en la página:  {page_history[0]}\")\n            else: \n                print(page_history[position])\n        elif user_option == \"salir\":\n            print(\"Ha salido exitosamente del programa\")\n            break\n        else: \n            print(f\"se añadirá la siguiente web: {user_option} \")\n            page_history.append(user_option)\n\n#menu()\n\n# SEGUNDO EJERCICIO \n\n\"\"\"- Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\"\"\"\n\n\ndef printer():\n    print_queue = []\n    while True:\n        option = input(\"Introduce una opción: imprimir o salir \")\n        if option == \"imprimir\":\n            if len(print_queue) == 0:\n                print(\"No hay documentos en la cola de impresión\")\n            else:\n                print(f\"Imprimiendo... {print_queue.pop(0)} \")\n                print(f\"Documentos en la impresora: {print_queue}\")\n        elif option == \"salir\":\n            print(\"Has salido exitosamente del programa\")\n            break\n        else:\n            print(\"Documento añadido a la cola de impresión\")\n            print_queue.append(option)\n            print(f\"Documentos en la impresora: {print_queue}\")\n\nprinter()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/fishellVvv.py",
    "content": "# ejercicio pila/stack (LIFO)\nstack = []\n# push\nstack.append(1)\nstack.append(2)\nstack.append(3)\nprint(stack)\n# pop\nstack.pop()\nprint(stack)\n\n# ejercicio cola/Queue (FIFO)\nqueue = []\n# enqueue\nqueue.append(1)\nqueue.append(2)\nqueue.append(3)\nprint(queue)\n# dequeue\nqueue.pop(0)\nprint(queue)\n\n# EXTRA\n\n# web_pila\ndef web_navigation():\n    stack = []\n    stack.append(\"fishellVvv.com\")\n    position = 0\n\n    print(f\"https://{stack[0]}/\", end=\"\")\n    while True:\n        action = input(\"\\nAñade una url o interactúa con palabras adelante/atrás/salir: \")\n        if action == \"salir\":\n            print(\"Saliendo del navegador web.\")\n            break\n        elif action == \"adelante\":\n            if position < len(stack) - 1:\n                position += 1\n        elif action == \"atrás\":\n            if position > 0:\n                position -= 1\n        else:\n            for i in range(position, len(stack) - 1):\n                stack.pop()\n            stack.append(action)\n            position += 1\n\n        print(\"https://\", end=\"\")\n        for i in range(position + 1):\n            print(f\"{stack[i]}/\", end=\"\")\n\nweb_navigation()\n\n# impresora_cola\ndef shared_printer():\n    queue = []\n\n    while True:\n        action = input(\"\\nAñade un documento o selecciona imprimir/salir: \")\n        if action == \"salir\":\n            print(\"Saliendo de la impresora.\")\n            break\n        elif action == \"imprimir\":\n            if len(queue) > 0:\n                print(f\"Imprimiendo: {queue.pop(0)}\")\n        else:\n            queue.append(action)\n\n        print(\"Cola de impresión:\")\n        for i in range(len(queue)):\n            print(f\"- {queue[i]}\")\n\nshared_printer()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/garos01.py",
    "content": "# Implementación de una pila (stack) utilizando una lista\ndef crear_pila():\n    return []\n\n\ndef pila_esta_vacia(pila):\n    return len(pila) == 0\n\n\ndef apilar(pila, elemento):\n    pila.append(elemento)\n\n\ndef desapilar(pila):\n    if not pila_esta_vacia(pila):\n        return pila.pop()\n    else:\n        print(\"La pila está vacía.\")\n\n\n# Implementación de una cola (queue) utilizando una lista\ndef crear_cola():\n    return []\n\n\ndef cola_esta_vacia(cola):\n    return len(cola) == 0\n\n\ndef encolar(cola, elemento):\n    cola.insert(0, elemento)\n\n\ndef desencolar(cola):\n    if not cola_esta_vacia(cola):\n        return cola.pop()\n    else:\n        print(\"La cola está vacía.\")\n\n\n# Ejemplo de uso\npila = crear_pila()\napilar(pila, 1)\napilar(pila, 2)\napilar(pila, 3)\n\nprint(\"Elementos de la pila:\")\nwhile not pila_esta_vacia(pila):\n    print(desapilar(pila))\n\ncola = crear_cola()\nencolar(cola, 1)\nencolar(cola, 2)\nencolar(cola, 3)\n\nprint(\"\\nElementos de la cola:\")\nwhile not cola_esta_vacia(cola):\n    print(desencolar(cola))\n\n\n# Ejercicio extra\n\nfrom collections import deque\n\n\ndef simular_impresora():\n    cola_documentos = deque()\n\n    while True:\n        comando = input(\"Ingrese un comando ('imprimir' o el nombre de un documento): \")\n\n        if comando == \"imprimir\":\n            if cola_documentos:\n                documento_a_imprimir = cola_documentos.popleft()\n                print(f\"Imprimir documento: {documento_a_imprimir}\")\n            else:\n                print(\"No hay documentos para imprimir.\")\n        else:\n            cola_documentos.append(comando)\n            print(f\"Añadir documento a la cola: {comando}\")\n\n\nsimular_impresora()\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/ggilperez.py",
    "content": "# problem 07 Stacks & Queues\n\n# Stack - LIFO\nclass Stack:\n    def __init__(self):\n        self.items = []\n\n    def insert(self, item):\n        self.items.append(item)\n\n    def pop(self):\n        try:\n            item = self.items.pop()\n        except IndexError:\n            item = None\n        finally:\n            return item\n\n\nmy_stack = Stack()\nmy_stack.insert(1)\nmy_stack.insert(2)\nmy_stack.insert(3)\nmy_stack.insert(4)\n\nprint(f\"{my_stack.pop() = }\")\n\n\nclass Queue:\n    def __init__(self):\n        self.items = []\n\n    def insert(self, item):\n        self.items.append(item)\n\n    def pop(self):\n        try:\n            item = self.items.pop(0)\n        except IndexError:\n            item = None\n        finally:\n            return item\n\n\nmy_queue = Queue()\nmy_queue.insert(1)\nmy_queue.insert(2)\nmy_queue.insert(3)\nmy_queue.insert(4)\n\nprint(f\"{my_queue.pop() = }\")\n\n\n# Extra\n\ndef web_browser():\n    stack = Stack()\n\n    while True:\n        option = input(\"Enter url or select Next / Previous / Exit: \")\n\n        if option.lower() == \"exit\":\n            print(\"Exiting...\")\n            break\n        elif option.lower() == \"previous\":\n            current_url = stack.pop()\n            previous_url = stack.pop()\n            stack.insert(previous_url)  # Insert to be current next loop\n            if previous_url is None:\n                print(\"Home page\")\n            else:\n                print(f\"URL: {previous_url}\")\n        elif option.lower() == \"next\":\n            # due a stack deletes values when it pops, can't go next\n            pass\n        else:\n            stack.insert(option)\n            print(f\"URL added {option}\")\n\n\nweb_browser()\n\n\ndef printer():\n    queue = Queue()\n\n    while True:\n        option = input(\"Enter document or select Print / Exit: \")\n\n        if option.lower() == \"exit\":\n            print(\"Exiting...\")\n            break\n        elif option.lower() == \"print\":\n            document = queue.pop()\n            if document is None:\n                print(\"Empty queue\")\n            else:\n                print(f\"Printing document {document}\")\n        else:\n            queue.insert(option)\n            print(f\"Document added {option}\")\n\n\nprinter()\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/gjbecerrae.py",
    "content": "\n### Pilas\nlista = []\nlista.append('1')\nlista.append('2')\nlista.append('3')\nprint(f'Para adicionar elementos usamos el metodo append. El ultimo elemento agregado ha sido {lista[-1]}')\nprint(lista)\nprint(f'Para eliminar elementos utilizamos el metodo pop. Sin argumento Pop elimina el ultimo elemento de la lista -> {lista[-1]}')\nlista.pop()\nprint(lista)\nprint('Usando Append y Pop Las listas se comportan como Pilas, Last Input First Output')\n\n\n### Colas\nprint('----------------------------------------------')\nprint('Para hacer un sistema First Input First Output podemos usar append y pop con el argumento 0')\nprint('Vamos a agregar elementos a ListaCola 1, 2, y 3 ')\nlistaCola = []\nlistaCola.append('1')\nlistaCola.append('2')\nlistaCola.append('3')\nprint(listaCola)\nprint(f'Vamos a eliminar el primer elemento -> {listaCola[0]} ')\nlistaCola.pop(0)\nprint(listaCola)\nprint(f'Vamos a adicionar un  elemento -> 4 ')\nlistaCola.append('4')\nprint(f'Vamos a eliminar el primer elemento -> {listaCola[0]} ')\nlistaCola.pop(0)\nprint(listaCola)\n\n### Difucultad Extra\ndef safari():\n    print('--------------Dificultad Extra 1 ----------------------')\n    navegador = []\n    index = len(navegador) - 1\n    while True:\n        accion = input('Precisa si quieres ir adelante o atras o quieres visitar una nueva pagina ')\n        if accion not in ('atras', 'adelante'):        \n            if index == len(navegador) -1 :\n                navegador.append(accion)\n                index = len(navegador) - 1\n                print(f'nueva pagina agregada -> {accion}')            \n                print(index)\n            else:                                \n                for i in range(index+1, len(navegador)): \n                    navegador.pop()\n                navegador.append(accion)\n                index = len(navegador) - 1\n                print(f'nueva pagina agregada -> {accion}')            \n                print(index)\n        elif accion == 'atras':\n            if index > 0:\n                index -= 1\n                print(f'la pagina es {navegador[index]}')\n            else:\n                print('Pagina de Inicio')\n            print(f'atras index is {index}')       \n        elif accion == 'adelante':\n            if index < len(navegador) - 1:\n                index += 1\n                print(f'la pagina es {navegador[index]}')\n            else:\n                print('Has llegado al final del navegador ')\n            \n        print(navegador)\n\ndef canon():\n    impresora = []\n    while True:\n        action = input('Que quieres hacer? ')\n        if action == 'imprimir':\n            if len(impresora) > 0:\n                print(f'Imprimiendo el archivo {impresora[0]}')\n                impresora.pop(0)\n                print(impresora)\n            else:\n                print('La cola de impresion esta vacia')\n        elif action == 'salir':\n            break\n        else:\n            impresora.append(action)\n            print(impresora)\n        \n#safari()\n#canon()\n            \n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/h4ckxel.py",
    "content": "import os\nimport time\nimport unicodedata\n\nclear = lambda: os.system('cls')\nclear()\n\nclass Pila:\n    def __init__(self):\n        # Define elems list of the stack\n        self.items = []\n    \n    def Add(self, elem):\n        # Add elem to the stack\n        if type(elem) == list:\n            self.items += elem\n        else:\n            self.items.append(elem)\n            \n    def Take(self):\n        # Return last elem from the stack\n        return self.items.pop()\n\nclass Cola:\n    def __init__(self):\n        # Define elems list of the stack\n        self.items = []\n    \n    def Add(self, elem):\n        # Add elem to the stack\n        if type(elem) == list:\n            self.items += elem\n        else:\n            self.items.append(elem)\n    \n    def Take(self):\n        # Return first elem from the queue\n        return self.items.pop(0)\n    \n## EXTRA ##\n    \ndef elimina_tildes(cadena):\n    s = ''.join((c for c in unicodedata.normalize('NFD',cadena) if unicodedata.category(c) != 'Mn'))\n    return s\n\ndef wait_and_clear(t):\n    time.sleep(t)\n    clear()\n\n# Program 1 (Navegador)\ndef navegador():\n    pila = Pila()\n\n    while True:\n        # Ask user what to do\n        t = 2\n        print(\"Estamos navegando ¿Qué desea hacer ahora?\")\n        userIn = input()\n\n        if userIn.lower() == \"end\":\n            break\n        else:\n            #Look for command\n            command = [userIn.lower().find(\"adelante\") > -1,elimina_tildes(userIn.lower()).find(\"atras\") > -1]\n        \n        # Execution\n        if all(command):\n            # Both commands where sent, do nothing\n            print(\"Error, no se puede ir adelante y atrás al mismo tiempo\")\n\n        elif command[0]:\n            # ADELANTE\n            pila.Add(userIn[len(\"adelante\")+1:])\n            print(\"Avanzamos a \" + pila.items[-1])\n            t = 1.5\n\n        elif command[1]:\n            # ATRÁS\n            if not pila.items:\n                # pila is empty\n                print(\"No hay dirección anterior a la actual\")\n            else:\n                # Return to previous adress\n                print(\"Regresamos a \" + pila.Take())\n\n        else:\n            # No commands where sent\n            print('No hay comandos. Use adelante o atrás para navegar')\n            \n        wait_and_clear(t)\n\n# Program 2 (Cola impresión)\ndef cola_impresion():\n    cola = Cola()\n\n    # Ask user what to do\n    while True:\n        t = 1\n        print(\"INSTRUCCIONES PARA LA IMPRESORA. ESCRIBA IMPRIMIR O AÑADA UN ELEMENTO A LA COLA\")\n        userIn = input()\n\n        # Execution\n        if userIn.lower() == \"end\":\n            break\n        elif userIn.lower().find(\"imprimir\") > -1:\n            # Print\n            print(\"Procedemos a imprimir \" + str(cola.Take()) + \". Quedan \" + str(len(cola.items)) + \" elementos en la cola de impresión.\")\n            t = 2\n        else:\n            # Add elem to queue\n            cola.Add(userIn)\n            print(userIn + \" ha sido añadido a la cola de impresión\")\n        \n        wait_and_clear(t)\n\n# navegador()\n# cola_impresion()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/haroldAlb.py",
    "content": "### PILAS Y COLAS ###\n# Implementa los mecanismos de introducción y recuperación de elementos propios de las\n# pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de lista.\n\n# PILAS - LIFO #\n\npila_list = [\"Mario\", \"Olga\", \"Ana\"]\n\n# introduce un elemento al final de la pila\npila_list.append(\"Harold\") \nprint(pila_list)\n\n# elimina el último elemento introducido y lo guarda en una variable\neliminado_pila = pila_list.pop()\nprint(eliminado_pila)\n\n# PILAS USANDO EL MÓDULO COLLETIONS\nfrom collections import deque # Módulo para manejar Pilas y Colas\n\npila = deque() # define la pila\n\n# Agregar elementos a la pila\npila.append(\"ESDLA\") \npila.append(\"Harry Poter\")\npila.append(\"La Torre Oscura\")\npila.append(\"El Guardian Entre El Centeno\")\n\neliminado = pila.pop() # Elimina el ultimo elemento en ser agregado y lo guarda en una variable\n\nprint(f\"\\\"{eliminado}\\\" ha sido eliminado de la pila.\")\nprint(pila)\n\n# COLAS - FIFO #\n\ncola_list = []\n\n# Agregar elementos a la cola\ncola_list.append(10)\ncola_list.append(20)\ncola_list.append(30)\ncola_list.append(40)\nprint(cola_list)\n\n# elimina el primer elemento introducido y lo guarda en una variable\neliminado_cola = cola_list.pop(0)\n\nprint(f\"{eliminado_cola} ha sido eliminado de la cola\")\nprint(cola_list)\n\n# COLAS USANDO EL MÓDULO COLLETIONS\n\ncola = deque() # define la cola\n\n# Introducir elementos a la cola con el Método deque()\ncola.append(10)\ncola.append(20)\ncola.append(30)\ncola.append(40)\nprint(cola)\n\n# Eliminar elemento y guardarlo en una variable\neliminado_cola = cola.popleft()\nprint(f\"{eliminado_cola} fue eliminado de la cola\")\nprint(cola)\n\n### EXTRA ###\n# Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n# de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n# que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n# Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n# el nombre de una nueva web.\n\nweb_pila = []\naux_pila = []\npermanecer = True\nmenu = '''\\nElije una opción:\n# [i]ntroducir web\n# [a]trás\n# a[d]elante\n# [s]alir\n-> '''\n\ndef web():\n    direccion = input(\"https://\")\n    web_pila.append(direccion)\n\ndef atras():\n    if len(web_pila) < 1:\n        pass\n    else:\n        borrado = web_pila.pop()\n        aux_pila.append(borrado)\n\ndef adelante():\n    if len(aux_pila) < 1:\n        pass\n    else:\n        borrado = aux_pila.pop()\n        web_pila.append(borrado)\n\nwhile permanecer:\n    opcion = input(menu)\n    match opcion:\n        case \"i\":\n            web()\n        case \"a\":\n            atras()\n        case \"d\":\n            adelante()\n        case \"s\":\n            permanecer = False\n        case _:\n            print(\"Elije un opción valida\")\n    if len(web_pila) > 0:\n        print(f\"Estas en: {web_pila[-1]}\")\n\nprint(\"Saliendo...\")\n\n'''Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n impresora compartida que recibe documentos y los imprime cuando así se le indica.\n La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n interpretan como nombres de documentos.'''\n\ncola_impresion = []\ncontinuo = True\n\ndef entrada_doc(documento):\n    cola_impresion.append(documento)\n    print(f\"El documento \\\"{documento}\\\" se ha agregado a la cola de impresión\")\n\ndef imprimir():\n    if len(cola_impresion) > 0:\n        doc_salida = cola_impresion.pop(0)\n        print(f\"Se está imprimiendo el documento \\\"{doc_salida}\\\"\")\n    else:\n        print(\"La cola de impresión está vacía.\")\n\nwhile continuo:\n    entrada = input(\"Esperando entrada -> \")\n\n    if entrada == \"imprimir\":\n        imprimir()\n    elif entrada == \"salir\":\n        continuo = False\n        print(\"Saliendo...\")\n    else:\n        entrada_doc(entrada)"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/hectordbh.py",
    "content": "\"\"\"EJERCICIO\n\"\"\"\n# stacks - LIFO\nclass Stack():\n    \"\"\"Clase pila para trabajar LIFO\n    \"\"\"\n    def __init__(self):\n        self.items = []\n\n    def isempty(self):\n        \"\"\"Método para verificar si la pila está vacía\n        \"\"\"\n        if not self.items:\n            print(\"La pila está vacía\")\n        else:\n            print(\"Hay elementos en la pila\")\n\n    def push(self, item):\n        \"\"\"Método para añadir un elemento a la pila\n        \"\"\"\n        self.items.append(item)\n        print(\"Se ha añadido el elemento a la pila\")\n\n    def pop(self):\n        \"\"\"Método que elimina de la pila el último elemento introducido\n        \"\"\"\n        print(f\"El elemento {self.items.pop()} se ha eliminado\")\n\n    def top(self):\n        \"\"\"Método que devuelve el elemento más alto de la pila\n        \"\"\"\n        print(self.items[len(self.items)-1])\n\n    def size(self):\n        \"\"\"Método que devuelve el tamaño de la pila\n        \"\"\"\n        print(f\"La pila contiene: {self.items} y su longitud es: {len(self.items)}\")\n\n# queue - FIFO\nclass Queue():\n    \"\"\"Clase cola para trabajar Queue\n    \"\"\"\n    def __init__(self):\n        self.items = []\n\n    def isempty(self):\n        \"\"\"Método para verificar si la cola está vacía\n        \"\"\"\n        if not self.items:\n            print(\"La cola está vacía\")\n        else:\n            print(\"Hay elementos en la cola\")\n\n    def enqueue(self, item):\n        \"\"\"Método para añadir un elemento a la cola\n        \"\"\"\n        self.items.insert(0, item)\n        print(\"Se ha añadido el elemento a la cola\")\n\n    def dequeue(self):\n        \"\"\"Método que elimina de la cola el primer elemento introducido\n        \"\"\"\n        print(f\"El elemento {self.items.pop()} se ha eliminado\")\n\n    def size(self):\n        \"\"\"Método que devuelve el tamaño de la cola\n        \"\"\"\n        print(f\"La cola contiene: {self.items} y su longitud es: {len(self.items)}\")\n\n# ---------------------- PRUEBAS LIFO -----------------------\npila = Stack()\npila.isempty()\npila.push(\"primero\")\npila.size()\npila.push(\"segundo\")\npila.size()\npila.pop()\npila.size()\n\n# ---------------------- PRUEBAS FIFO -----------------------\ncola = Queue()\ncola.isempty()\ncola.enqueue(\"Héctor\")\ncola.size()\ncola.enqueue(\"Pedro\")\ncola.size()\ncola.dequeue()\ncola.size()\n\n# ---------------------- DIFICULTAD EXTRA -------------------\nclass WebNav():\n    \"\"\"Clase para manejar adelante/atrás en un navegador\n    \"\"\"\n    def __init__(self):\n        self.stack = []\n        self.history = [\"www.google.es\", \"www.rae.es\", \"www.apple.com\"]\n\n    def method(self, ins):\n        \"\"\"Método para indicar si avanzamos o retrocedemos\n\n        Args:\n            ins (str): adelante/atras\n\n        Returns:\n            str: elemento más top en la tabla\n        \"\"\"\n        if ins == \"adelante\":\n            if len(self.stack) == len(self.history):\n                web = str(input(\"Introduce una web: \"))\n                self.push(web)\n            else:\n                self.push()\n            return self.top()\n        if ins == \"atras\":\n            if len(self.stack) <= 1:\n                if len(self.stack) == 1:\n                    self.pop()\n                print(\"No tienes historial que recuperar\")\n            else:\n                self.pop()\n                return self.top()\n\n    def push(self, item = \"\"):\n        \"\"\"Método para añadir un elemento a la pila\n        \"\"\"\n        if item != \"\":\n            self.history.append(item)\n        self.stack.append(\"forward\")\n\n    def pop(self):\n        \"\"\"Método que elimina de la pila el último elemento introducido\n        \"\"\"\n        return self.stack.pop()\n\n    def top(self):\n        \"\"\"Método que devuelve el elemento más alto de la pila\n        \"\"\"\n        print(self.history[len(self.stack)-1])\n\n# ---------------------- PRUEBAS NAVEGACIÓN -----------------\nnav = WebNav()\nprint(nav.history)\nnav.method(\"adelante\")\nnav.method(\"adelante\")\nnav.method(\"adelante\")\nnav.method(\"atras\")\nnav.method(\"atras\")\nnav.method(\"atras\")\n\nclass Impress():\n    \"\"\"Clase para manejar la cola de impresión de un dispositivo\n    \"\"\"\n    def __init__(self):\n        self.items = []\n\n    def isempty(self):\n        \"\"\"Método para verificar si la cola de impresión está vacía\n        \"\"\"\n        if not self.items:\n            print(\"La cola de impresión está vacía\")\n        else:\n            print(\"Hay elementos en la cola de impresión\")\n\n    def enqueue(self, item):\n        \"\"\"Método para añadir un elemento a la cola de impresión\n        \"\"\"\n        self.items.insert(0, item)\n        print(\"Se ha añadido el elemento a la cola de impresión\")\n\n    def dequeue(self):\n        \"\"\"Método que elimina de la cola el primer elemento introducido\n        \"\"\"\n        print(f\"El elemento {self.items.pop()} se ha impreso\")\n\n    def size(self):\n        \"\"\"Método que devuelve el tamaño de la cola\n        \"\"\"\n        print(f\"Documentos en la cola de impresión: {self.items}\")\n\n# ---------------------- PRUEBAS COLA DE IMPRESIÓN ----------\nimp = Impress()\nimp.isempty()\nimp.enqueue(\"Archivo1\")\nimp.isempty()\nimp.enqueue(\"Archivo2\")\nimp.size()\nimp.dequeue()\nimp.size()\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/hectorio23.py",
    "content": "# Author: Héctor Adán \n# GitHub: https://github.com/hectorio23\n\n##########################################\n############ CLASE WEBPAGE ###############\n##########################################\n\nclass WebPage:\n    def __init__(self, title, index):\n        self.title = title\n        self.index = index\n\n    def get_info(self):\n        print(f\"<Object WebPage - {self.title} at {hex(id(self))}>\")\n\n##########################################\n############ CLASE STACK #################\n##########################################\n\nclass Stack:\n    def __init__(self):\n        self.items = []\n\n    def push(self, item):\n        self.items.append(item)\n\n    def pop(self):\n        if not self.is_empty():\n            return self.items.pop()\n\n    def is_empty(self):\n        return len(self.items) == 0\n\n    @property\n    def size(self):\n        return len(self.items)\n\n##########################################\n############ CLASE QUEUE #################\n##########################################\n\nclass Queue:\n    def __init__(self):\n        self.items = []\n\n    def push(self, item):\n        self.items.append(item)\n\n    def pop(self):\n        if not self.is_empty():\n            return self.items.pop(0)\n\n    def is_empty(self):\n        return len(self.items) == 0\n\n    @property\n    def size(self):\n        return len(self.items)\n\n##########################################\n############# FUNCIONES ##################\n##########################################\n\ndef imprimir_menu(counter):\n    stack = Stack()\n    back_stack = Stack()\n    index = WebPage(\"index\", counter)\n    stack.push(index)\n\n    while True:\n        print(\"\\n=======================================================\")\n        print(f\"          Bienvenido a la página No. {stack.size}\")\n        print(\"=======================================================\")\n        print(\"Atras (presiona 'a' | 'A')           Siguiente (presiona 's' | 'S')\")\n        choose = input(\"Opción del usuario> \")\n\n        if len(choose) > 1:\n            temporal = WebPage(choose, counter)\n            stack.push(temporal)\n\n        elif (choose.lower() == 'a') and (stack.size > 1):\n            otro_temporal = stack.pop()\n            otro_temporal.get_info()\n            stack.items[-1].get_info()\n            back_stack.push(otro_temporal)\n            print(\"Mostrando página anterior...\")\n\n        elif (choose.lower() == 's') and (back_stack.size > 0):\n            atras_temporal = back_stack.pop()\n            atras_temporal.get_info()\n            stack.items[-1].get_info()\n            stack.push(atras_temporal)\n            print(\"Mostrando siguiente página...\")\n\n        else:\n            print(\"Opción no disponible. Por favor, crea una página web.\")\n\n##########################################\n########### PROGRAMA PRINCIPAL ###########\n##########################################\n\nif __name__ == \"__main__\":\n    q1 = Queue()\n    s1 = Stack()\n    counter = 1\n\n    ##########################################\n    ####### USO DE UN STACK DINÁMICO #########\n    ##########################################\n\n    print(\"\\n************ USO DE UN STACK DINÁMICO ************\")\n\n    w1 = WebPage(\"Index\", 2)\n    w2 = WebPage(\"Account\", 5)\n    w3 = WebPage(\"Login\", 6)\n\n    print(f\"\\nCantidad de elementos de Stack antes de agregarlos: {s1.size} elementos\")\n    s1.push(w1)\n    s1.push(w2)\n    s1.push(w3)\n    print(f\"Cantidad de elementos de Stack después de agregarlos: {s1.size} elementos\")\n\n    s1.pop()\n    s1.pop()\n    s1.pop()\n    print(f\"Cantidad de elementos de Stack después de eliminarlos: {s1.size} elementos\")\n\n    ##########################################\n    ####### USO DE UN QUEUE DINÁMICO #########\n    ##########################################\n\n    print(\"\\n************ USO DE UN QUEUE DINÁMICO ************\")\n\n    print(f\"\\nCantidad de elementos de Queue antes de agregarlos: {q1.size} elementos\")\n    q1.push(w1)\n    q1.push(w2)\n    q1.push(w3)\n    print(f\"Cantidad de elementos de Queue después de agregarlos: {q1.size} elementos\")\n\n    q1.pop()\n    q1.pop()\n    q1.pop()\n    print(f\"Cantidad de elementos de Queue después de eliminarlos: {q1.size} elementos\")\n\n    ##########################################\n    ############### MENU PRINCIPAL ############\n    ##########################################\n\n    imprimir_menu(counter)\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/hozlucas28.py",
    "content": "from collections import deque\n\n\n\"\"\"\n    Stack methods for insert and recover items...\n\"\"\"\n\nprint(\"Stack methods for insert and recover items...\")\n\nSTACK: list[int] = [5, 8, 9, 4, 3, 2]\n\nprint(\"\\nSTACK: list[int] = [5, 8, 9, 4, 3, 2]\")\n\nprint(\"\\nInsert an element at the end of the stack...\")\n\nSTACK.append(10)\n\nprint(f\"\\nSTACK.append(10) --> STACK = {STACK}\")\n\nprint(\"\\nRecover an element of the stack...\")\n\nSTACK_ELEMENT = STACK.pop()\n\nprint(f\"\\nSTACK.pop() --> STACK_ELEMENT = {STACK_ELEMENT}\")\n\nprint(\n    \"\\n# ---------------------------------------------------------------------------------- #\\n\"\n)\n\n\"\"\"\n    Queue methods for insert and recover items...\n\"\"\"\n\nprint(\"Queue methods for insert and recover items...\")\n\nMY_DEQUE: deque[str] = deque([\"Hello\", \"World\"])\n\nprint('\\nMY_DEQUE: deque[str] = deque([\"Hello\", \"World\"])')\n\nprint(\"\\nInsert an element at the end of the queue...\")\n\nMY_DEQUE.append(\"Python\")\n\nprint(f'\\nMY_DEQUE.append(\"Python\") --> MY_DEQUE = {MY_DEQUE}')\n\nprint(\"\\nRecover an element of the queue...\")\n\nDEQUE_ELEMENT = MY_DEQUE.popleft()\n\nprint(f\"\\nMY_DEQUE.popleft() --> DEQUE_ELEMENT = '{DEQUE_ELEMENT}'\")\n\nprint(\n    \"\\n# ---------------------------------------------------------------------------------- #\\n\"\n)\n\n\"\"\"\n    Additional challenge...\n\"\"\"\n\n# Stack exercise\nprint(\"Stack exercise...\")\n\nBROWSER_HISTORY: list[str] = []\n\nwhile True:\n    print(f\"\\nBrowser history --> {BROWSER_HISTORY}\")\n\n    try:\n        OPERATION: str = input(\n            \"\\nEnter an operation ('Back', 'Forward', or 'Exit'): \"\n        ).upper()\n    except KeyboardInterrupt:\n        OPERATION: str = \"\"\n\n    if OPERATION == \"BACK\":\n        if len(BROWSER_HISTORY) > 0:\n            BROWSER_HISTORY.pop()\n    elif OPERATION == \"FORWARD\":\n        LAST_PAGE_NUMBER: str = (\n            BROWSER_HISTORY[len(BROWSER_HISTORY) - 1][-2:]\n            if (len(BROWSER_HISTORY) > 0)\n            else \"0\"\n        )\n        BROWSER_HISTORY.append(f\"Page {int(LAST_PAGE_NUMBER) + 1}\")\n    elif OPERATION == \"EXIT\":\n        break\n\n# Queue exercise\nprint(\"\\nQueue exercise...\")\n\nDOCUMENTS: deque[str] = deque()\n\nwhile True:\n    print(f\"\\nDocuments --> {DOCUMENTS}\")\n\n    try:\n        USER_INPUT: str = input(\n            \"\\nAdd a document to print, or write 'Print' to print the document in the queue: \"\n        )\n    except KeyboardInterrupt:\n        USER_INPUT: str = \"\"\n\n    USER_INPUT_FORMATTED = USER_INPUT.upper()\n\n    if USER_INPUT_FORMATTED == \"PRINT\":\n        if len(DOCUMENTS) > 0:\n            PRINTED_DOCUMENT: str = DOCUMENTS.popleft()\n            print(f\"\\nPrinted document --> '{PRINTED_DOCUMENT}'\")\n    elif USER_INPUT_FORMATTED == \"EXIT\":\n        break\n    elif USER_INPUT_FORMATTED != \"\":\n        DOCUMENTS.append(USER_INPUT)\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/idiegorojas.py",
    "content": "# Simulación de navegador web con pilas\ndef navegador_web():\n    historial_atras = []\n    historial_adelante = []\n    pagina_actual = None\n\n    while True:\n        accion = input(\"Ingresa una página web, 'atrás', 'adelante' o 'salir': \").strip().lower()\n\n        if accion == \"salir\":\n            print(\"Saliendo del navegador...\")\n            break\n        elif accion == \"atrás\":\n            if historial_atras:\n                historial_adelante.append(pagina_actual)\n                pagina_actual = historial_atras.pop()\n                print(f\"Yendo atrás a: {pagina_actual}\")\n            else:\n                print(\"No hay páginas anteriores.\")\n        elif accion == \"adelante\":\n            if historial_adelante:\n                historial_atras.append(pagina_actual)\n                pagina_actual = historial_adelante.pop()\n                print(f\"Yendo adelante a: {pagina_actual}\")\n            else:\n                print(\"No hay páginas siguientes.\")\n        else:\n            if pagina_actual:\n                historial_atras.append(pagina_actual)\n            pagina_actual = accion\n            historial_adelante.clear()\n            print(f\"Navegando a: {pagina_actual}\")\n\nnavegador_web()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/ignaciovihe.py",
    "content": "\"\"\"\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n\"\"\"\n\n# Pila/Stack (LIFO)\n\nstack = []\n\ndef push_stack(element):\n    stack.append(element)\n\ndef pull_stack():\n    return stack.pop()\n\nprint(stack)\npush_stack(1)\nprint(stack)\npush_stack(2)\nprint(stack)\nprint(f\" Elemento sacado: {pull_stack()}\")\nprint(stack)\npush_stack(3)\nprint(stack)\npush_stack(4)\nprint(stack)\nprint(f\" Elemento sacado: {pull_stack()}\")\nprint(stack)\n\n\n# Cola/Queue (FIFO)\n\nqueue = []\n\ndef push_queue(element):\n    queue.append(element)\n\ndef pull_queue():\n    return queue.pop(0)\n\n\nprint(\"----------------------------\")\nprint(queue)\npush_queue(1)\nprint(queue)\npush_queue(2)\nprint(queue)\nprint(f\" Elemento sacado: {pull_queue()}\")\nprint(queue)\npush_queue(3)\nprint(queue)\npush_queue(4)\nprint(queue)\nprint(f\" Elemento sacado: {pull_queue()}\")\nprint(queue)\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n\"\"\"\n\ndef web_browser():\n\n    back = [] #Pila: almacena la web actual en la parte más alta y las de atras acontinuación\n    forward = [] #Pila: Almacena las paginas a las que avanzar cuando vamos atras.\n    salir = False\n\n    while not salir:\n        action = input(\"Introduce una web o una accion (adelante/atras/salir): \")\n\n        if action == \"salir\":\n            salir = True\n\n        elif action == \"adelante\":\n            if len(forward) > 0:    # Si hay paginas para avanzar(si hay elementos en forward)\n                web = forward.pop() # Sacamos de forward y lo pasamos a back.\n                back.append(web)\n                print(f\"Pagina actual: {back[-1]}\") #Pagina actual el pico de la pila\n            else:\n                print(f\"No hay mas paginas adelante\")\n\n        elif action == \"atras\":\n            if len(back) > 1:       # Si hay mas de una web en back podremos usar atras.\n                web = back.pop()    # Sacamos de back y pasamos el elemtno a forward, ya que son los elementos que podremos avanzar.\n                forward.append(web) #\n                print(f\"Pagina actual: {back[-1]}\") #Siempre se imprime el pico de back\n            else:\n                print(\"No hay más paginas atras\")\n\n        else:\n            back.append(action) # Para añadir una nueva web se añade en back\n            print(f\"Pagina actual: {back[-1]}\")\n            forward.clear()     # En el caso de añadir una nueva web se descartan las que estaban\n                                # preparadas para ir adelante (pila forward)\n                                # Asi lo hace chrome.\n\nweb_browser()\n\ndef printer():\n\n    printer_queue =[]\n    salir = False\n    while not salir:\n\n        action = input(\"Introduce nombre de documento, o una acción(imprimir, salir): \")\n\n        if action == \"salir\":\n            salir = True\n\n        elif action == \"imprimir\":\n            if len(printer_queue) > 0:\n                document = printer_queue.pop(0)\n                print(f\"Imprimiendo... {document}\")\n                print(printer_queue)\n            else:\n                print(\"Cola de impresion vacía\")\n\n        else:\n            printer_queue.append(action)\n            print(printer_queue)\n\nprinter()\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/ipfabio.py",
    "content": "\"\"\"\nEjercicio\n\"\"\"\n\n# Pila/Stack (LIFO Last In First Out)\n\n# Push\nstack = []\nstack.append(1)\nstack.append(2)\nstack.append(3)\nprint(stack)\n\n# Pop\nstack_item = stack[len(stack) - 1]\ndel stack[len(stack) - 1] # delete last item\nprint(stack_item)\n\nprint(stack.pop()) # delete last item\n\nprint(stack)\n\n# Cola/Queue (FIFO First In First Out)\nqueue = []\n\n# enqueue (encolar)\nqueue.append(1)\nqueue.append(2)\nqueue.append(3)\n\n# dequeue (desencolar)\nqueue_item = queue[0]\ndel queue[0]\n\nprint(queue.pop(0))\n\nprint(queue)\n\n\"\"\"\nExtra\n\"\"\"\n\n# Opciones\ndef opciones():\n    print(\"\"\"1. Login\\n2. Profile\\n3. Atras\\n4. Salir\"\"\")\n\n# Web\ndef web_navigation():\n    stack = [] # Inicialización pila vacía para rastrear navegación\n    opciones() # Llamada función opciones\n    while True:\n        opcion = input(\"Ingresa la opcion: \") # Solicita al usuario la opción\n        match opcion:\n            case \"1\":\n                stack.append(\"/Login/\") # Agrega \"/Login/\" a la pila\n            case \"2\":\n                stack.append(\"/Login/Profile\") # Agrega \"/Login/Profile\" a la pila\n            case \"3\":\n                if len(stack) > 0:\n                    stack.pop() # Elimina el último elemento de la pila si no está vacía\n            case \"4\":\n                print(\"Saliendo del navegador.\") # Imprime mensaje y sale del bucle\n                break\n            case _:\n                print(\"Opcion no válida.\") # Imprime mensaje si no recibe una opción válida\n        \n        if len(stack) > 0:\n            print(stack[len(stack) - 1]) # Imprime el último elemento de la pila\n        else:\n            print(f\"Esta en Home. Quiere salir? Presione 4.\") # Mensaje cuando la pila está vacía\n\n\nweb_navigation()\n\ndef impresora_compartida():\n    queue = [] # Inicializa cola vacía para documentos\n\n    while True:\n\n        action = input(\"Agrega un documento o selecciona imprimir/salir: \") # Solicita acción del usuario\n\n        if action == \"salir\":\n            break # Sale del bucle\n        elif action == \"imprimir\":\n            if len(queue) == 0:\n                print(f\"No hay elementos a imprimir.\") # Informa si no hay documentos en cola\n\n            if len(queue) > 0:\n                elemento_0 = queue.pop(0) # Elimina y obtiene el documento\n                print(f\"Imprimiendo: {elemento_0}\")\n        else:\n            queue.append(action) # Agrega el documento a cola\n        \n        print(f\"Cola de impresión: {queue}\") # Muestra el estado actual de cola\n\n\n\nimpresora_compartida()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/isilanes.py",
    "content": "from typing import Any\n\n\nclass Stack:\n    \"\"\"\n    Implementation of a stack of elements (LIFO).\n    \"\"\"\n\n    def __init__(self):\n        self.contents = []\n\n    def add(self, element: Any) -> None:\n        \"\"\"\n        Add element 'element' to the stack.\n\n        Args:\n            element (Any):\n                Object to add to the upper position of the stack.\n\n        Returns:\n            Nothing.\n        \"\"\"\n        self.contents.append(element)\n\n    def remove(self) -> Any:\n        \"\"\"\n        Remove (and return) the upper element of the stack.\n\n        Args:\n            None.\n\n        Returns:\n            Last element in the stack, or None if stack is empty.\n        \"\"\"\n        return self.contents.pop() if self.contents else None\n\n    def drop(self) -> None:\n        \"\"\"\n        Remove all elements in the stack, resulting in an empty stack.\n        The dropped elements are not returned.\n\n        Args:\n            None.\n\n        Returns:\n            Nothing.\n        \"\"\"\n        self.contents = []\n\n\nclass Queue:\n    \"\"\"\n    Implementation of a queue of elements (FIFO).\n    \"\"\"\n\n    def __init__(self):\n        self.contents = []\n\n    def add(self, element: Any) -> None:\n        \"\"\"\n        Add element 'element' to the queue.\n\n        Args:\n            element (Any):\n                Object to add to the last position of the queue.\n\n       Returns:\n           Nothing.\n        \"\"\"\n        self.contents.append(element)\n\n    def remove(self) -> Any:\n        \"\"\"\n        Remove (and return) the upper element of the stack.\n\n        Args:\n            None.\n\n        Returns:\n            Last element in the stack, or None if the queue is empty.\n        \"\"\"\n        return self.contents.pop(0) if self.contents else None\n\n\ndef main() -> None:\n    s = Stack()\n    s.add(1)\n    s.add(2)\n    s.add(3)\n    print(f\"Stack after adding 3 elements: {s.contents}\")\n    extracted = s.remove()\n    print(f\"Stack after removing 1 element ({extracted}): {s.contents}\")\n\n    q = Queue()\n    q.add(1)\n    q.add(2)\n    q.add(3)\n    print(f\"Queue after adding 3 elements: {q.contents}\")\n    extracted = q.remove()\n    print(f\"Queue after removing 1 element ({extracted}): {q.contents}\")\n\n\ndef browser(verbose: bool = False) -> None:\n    \"\"\"\n    Simulate a browser history using stacks.\n\n    Each step we are asked for a new URL. Our response options are:\n    - quit: exit the browser.\n    - atrás: go back to the previous URL in the browse history. If we are\n             at the first URL in the history, give a warning and do nothing.\n    - adelante: go to the next URL in the browse history. If we are at the\n                latest URL, give a warning and do nothing.\n    - <url>: go to that URL.\n\n    Note that going to a new URL will erase any existing future URL. For example:\n    If we visit URLs A, B, C and D, the past URLs are (A, B, C), and the current one\n    is D. If we go back (atrás) twice, the current URL will be B. The previous URL will be\n    just A. Now going forward (adelante) would take us to C, then D. However, if we are\n    sitting at B, and now we visit X, the \"future\" URLs (C, D) will be dropped. The current\n    URL will be X, and the \"past\" ones will be (A, B).\n\n    Args:\n        verbose (bool):\n            If True, print the state of the past/present/future URL stacks at every step.\n            By default, do not print it.\n\n    Returns:\n        Nothing.\n    \"\"\"\n    past_stack = Stack()\n    future_stack = Stack()\n    current_url = None\n\n    while True:\n        if verbose:\n            print(f\"{past_stack.contents} <- {current_url} -> {future_stack.contents}\")\n\n        url = input(\"Introduce una URL que visitar, o adelante/atrás para visitar la página correspondiente (quit para salir): \")\n        if url == \"quit\":\n            print(\"Saliendo...\")\n            break\n\n        if url == \"adelante\":\n            url = future_stack.remove()\n            if url is None:\n                print(f\"Ya estás en la última URL: {current_url}\")\n                continue\n            if current_url is not None:  # the undefined initial 'URL'\n                past_stack.add(current_url)\n            current_url = url\n            print(f\"Avanzamos a la URL '{url}'\")\n            continue\n\n        if url == \"atrás\":\n            url = past_stack.remove()\n            if url is None:\n                print(f\"Ya estás en la primera URL: {current_url}\")\n                continue\n            if current_url is not None:  # this should never happen\n                future_stack.add(current_url)\n            current_url = url\n            print(f\"Retrocedemos a la URL '{url}'\")\n            continue\n\n        if current_url is not None:  # the undefined initial 'URL'\n            past_stack.add(current_url)\n        current_url = url\n        future_stack.drop()\n        print(f\"Como pediste, visitamos la URL '{url}'\")\n\n\ndef shared_printer(verbose: bool = False) -> None:\n    \"\"\"\n    Simulate a shared printer, using a Queue. The user is prompted for documents. Any string is\n    interpreted as a 'document', except the string 'quit', which quits, and 'imprimir', which\n    'prints' one document from the queue, effectively removing it from the queue.\n\n    Args:\n        verbose (bool):\n            If True, print the status of the queue at every step.\n            By default, do not print it.\n\n    Return:\n        Nothing.\n    \"\"\"\n    printer = Queue()\n\n    while True:\n        if verbose:\n            print(f\"Cola: {printer.contents}\")\n\n        msg = (\n            \"Introduce un documento a imprimir\"\n            \", o 'imprimir' para procesar un documento de la cola\"\n            \", o 'quit' para salir: \"\n        )\n        doc = input(msg)\n        if doc == \"quit\":\n            print(\"Saliendo...\")\n            break\n\n        if doc == \"imprimir\":\n            doc = printer.remove()\n            if doc is None:\n                print(\"La cola de impresión está vacía.\")\n                continue\n            print(f\"Imprimiendo el documento: {doc}\")\n            continue\n\n        printer.add(doc)\n        print(f\"Añadido el documento {doc} a la cola de impresión.\")\n\n\ndef extra() -> None:\n    browser(verbose=True)\n    shared_printer(verbose=True)\n\n\nif __name__ == \"__main__\":\n    main()\n    extra()\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/ivangdev.py",
    "content": "from collections import deque\nimport queue\n# Pilas - LIFO\n\npila = [\"hola\", 1, 2, 7]\n\n# Agregando elemento al dinal de la pila\npila.append(10)\npila.append(\"Final\")\nprint(pila)\n\n# Sacando elemento del final\npila.pop()\nprint(pila)\n\n# Colas - FIFO\n\ncola = [\"Raul\", \"Ivan\", \"Mario\"]\n\n# Agregando elementos al final\ncola.append(\"Maria\")\n\nprint(cola)\n\n# Sacando el primer elemento -> Principio cola\ncola.pop(0)\n\nprint(cola)\n\n# Con modulo collections - deque\n\ncola2 = [\"Mario\", \"Luis\", \"Ivan\"]\ncola2 = deque(cola2)\ncola2.popleft()\nprint(cola2)\n\n# Con modulo queue\ncola3 = queue.Queue()\ncola3.put(\"Elemento 1\")\ncola3.put(\"Elemento 2\")\ncola3.put(\"Elemento 3\")\n\n# Sacando el primer elemento\nprimer_elemento = cola3.get()\nprint(primer_elemento)\n\n# Ver cuantos elementos quedan en la cola\nprint(cola3.qsize())\n\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n#  *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n#  *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n#  *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n#  *   el nombre de una nueva web.\n#  * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n#  *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n#  *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n#  *   interpretan como nombres de documentos.\n#  */\n\n\n# Navegacion web\npilaAtras = [\"atras\"]\npilaAdelante = [\"Prueba pag\"]\npagina_actual = \"misitio.com\"\n\n\ndef navegacion_web(accion):\n    global pagina_actual\n    if accion == \"adelante\":\n        if pilaAdelante:\n            pilaAtras.append(pagina_actual)\n            pagina_actual = pilaAdelante.pop()\n        else:\n            print(\"No hay paginas adelante\")\n    elif accion == \"atras\":\n        if pilaAtras:\n            pilaAdelante.append(pagina_actual)\n            pagina_actual = pilaAtras.pop()\n        else:\n            print(\"No hay historial atras\")\n    else:\n        pilaAtras.append(pagina_actual)\n        pagina_actual = accion\n        pilaAdelante.clear()\n\n    print(f\"Pagina actual: {pagina_actual}\")\n    print(f\"Historial atras: {pilaAtras}\")\n    print(f\"Historial adelante: {pilaAdelante}\")\n\n\nnavegacion = navegacion_web(\"adelante\")\n\n\n# Impersora compartida\ndocumentos = deque([\"prueba\", \"nueva\"])\n\n\ndef impresora(accion):\n    if accion == \"imprimir\":\n        impreso = documentos.popleft()\n        print(f\"Imprimiendo: {impreso}\")\n        print(f\"Documentos restantes: {list(documentos)}\")\n    else:\n        documentos.append(accion)\n        print(f\"Se ha agregado el documento: {list(documentos)}\")\n\n\nimpresora(\"imprimir\")\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/javierjoyera.py",
    "content": "class Pila:\n    def __init__(self): \n        self.items = []\n    def push(self, item):\n        self.items.append(item)\n    def pop(self):\n        if not self.is_empty():\n            return self.items.pop()\n        else:\n            return \"La pila está vacía\"\n    def is_empty(self):\n        return len (self.items) == 0\n    def is_the_top(self):\n        if not self.is_empty():\n            return self.items[-1]\n        else:\n            return \"La pila está vacía\"\n    \nclass Cola:\n    def __init__(self):\n        self.items = []\n    def enqueue(self, item):\n        self.items.append(item)\n    def dequeue(self):\n        if not self.is_empty():\n            return self.items.pop(0)\n        else:\n            return \"La cola está vacía\"\n    def is_empty(self):\n        return len(self.items) == 0\n    \n\nclass NavegadorWeb:\n    def __init__(self):\n        self.historial = Pila()\n        self.adelante = Pila()\n\n    def ver_pagina(self, pagina):\n        print(\"Estás viendo la página: %s\" % pagina)\n        self.historial.push(pagina)\n        self.adelante = Pila()\n    \n    def retroceder(self):\n        if self.historial.is_empty():\n            print(\"No hay páginas para retroceder\")\n        else:\n            pagina = self.historial.pop()\n            self.adelante.push(pagina)\n            if self.historial.is_empty():\n                print(\"Estás en la página de inicio\")\n            else:\n                print(\"Estás viendo la página: %s\" % self.historial.is_the_top())\n\n    def ir_adelante(self):\n        if self.adelante.is_empty():\n            print(\"No hay páginas hacia adelante\")\n        else:\n            pagina = self.adelante.pop()\n            self.historial.push(pagina)\n            print(\"Estás viendo la página: %s\" % pagina)\n\n\n\nnavegador = NavegadorWeb()\nnavegador.ver_pagina(\"google.com\")\nnavegador.ver_pagina(\"youtube.com\")\nnavegador.ver_pagina(\"retosdeprogramacion.com\")\n\nnavegador.retroceder()\nnavegador.retroceder()\nnavegador.retroceder()\nnavegador.retroceder()\nnavegador.ir_adelante()\nnavegador.ir_adelante()\n\nclass Impresora:\n    def __init__(self):\n        self.cola_impresion = Cola()\n    \n    def agregar_documento(self, documento):\n        self.cola_impresion.enqueue(documento)\n        print(\"Documento %s agregado a la cola de impresión\" % documento)\n    \n    def imprimir(self):\n        if not self.cola_impresion.is_empty():\n            documento = self.cola_impresion.dequeue()\n            print(\"Imprimiendo documento: %s\" % documento)\n        else:\n            print(\"No hay documentos en cola.\")\n\n# Ejemplo de uso\nimpresora = Impresora()\nimpresora.agregar_documento(\"Documento1.pdf\")\nimpresora.agregar_documento(\"Foto_12.png\")\nimpresora.imprimir()\nimpresora.imprimir()\n\n\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/jcdm60.py",
    "content": "# #07 PILAS Y COLAS\n#### Dificultad: Media | Publicación: 12/02/24 | Corrección: 19/02/24\n\n## Ejercicio\n\n#\n# EJERCICIO:\n# Implementa los mecanismos de introducción y recuperación de elementos propios de las\n# pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n# o lista (dependiendo de las posibilidades de tu lenguaje).\n#\n# DIFICULTAD EXTRA (opcional):\n# - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n#   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n#   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n#   Las palabras \"adelante\", \"atras\" desencadenan esta acción, el resto se interpreta como\n#   el nombre de una nueva web.\n# - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n#   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n#   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n#   interpretan como nombres de documentos.\n#\n\nclass Pila:\n    def __init__(self):\n        self.items = []\n\n    def esta_vacia(self):\n        return self.items == []\n\n    def agregar(self, item):\n        self.items.append(item)\n\n    def eliminar(self):\n        return self.items.pop()\n\nclass Cola:\n    def __init__(self):\n        self.items = []\n\n    def esta_vacia(self):\n        return self.items == []\n\n    def agregar(self, item):\n        self.items.append(item)\n\n    def eliminar(self):\n        return self.items.pop(0)\n\n# Ejemplo de uso de la pila\npila = Pila()\npila.agregar(1)\npila.agregar(2)\npila.agregar(3)\n\nprint(\"Elementos en la pila:\")\nwhile not pila.esta_vacia():\n    print(pila.eliminar())\n\n# Ejemplo de uso de la cola\ncola = Cola()\ncola.agregar('a')\ncola.agregar('b')\ncola.agregar('c')\n\nprint(\"\\nElementos en la cola:\")\nwhile not cola.esta_vacia():\n    print(cola.eliminar())\n    \nclass Pila:\n    def __init__(self):\n        self.items = []\n\n    def esta_vacia(self):\n        return self.items == []\n\n    def agregar(self, item):\n        self.items.append(item)\n\n    def eliminar(self):\n        return self.items.pop()\n\n\nclass NavegadorWeb:\n    def __init__(self):\n        self.historial_atras = Pila()\n        self.historial_adelante = Pila()\n        self.pagina_actual = \"\"\n\n    def navegar(self, url):\n        if self.pagina_actual:\n            self.historial_atras.agregar(self.pagina_actual)\n            self.historial_adelante = Pila()  # Limpiar historial adelante cuando navegamos a una nueva página\n        self.pagina_actual = url\n        print(\"Navegando a:\", url)\n\n    def retroceder(self):\n        if not self.historial_atras.esta_vacia():\n            pagina_anterior = self.historial_atras.eliminar()\n            self.historial_adelante.agregar(self.pagina_actual)\n            self.pagina_actual = pagina_anterior\n            print(\"Navegando hacia atrás a:\", pagina_anterior)\n        else:\n            print(\"No hay páginas disponibles para retroceder.\")\n\n    def avanzar(self):\n        if not self.historial_adelante.esta_vacia():\n            pagina_siguiente = self.historial_adelante.eliminar()\n            self.historial_atras.agregar(self.pagina_actual)\n            self.pagina_actual = pagina_siguiente\n            print(\"Navegando hacia adelante a:\", pagina_siguiente)\n        else:\n            print(\"No hay páginas disponibles para avanzar.\")\n\n    def mostrar_pagina_actual(self):\n        print(\"Página actual:\", self.pagina_actual)\n\n\n# EXTRA: SIMULA MECANISMO ADELANTE O ATRAS DE UN PAGINA WEB\nif __name__ == \"__main__\":\n    navegador = NavegadorWeb()\n\n    while True:\n        entrada = input(\"Introduce una URL o 'adelante'/'atras' para navegar (o 'salir' para salir): \")\n\n        if entrada.lower() == \"salir\":\n            print(\"Saliendo del navegador.\")\n            break\n        elif entrada.lower() == \"adelante\":\n            navegador.avanzar()\n        elif entrada.lower() == \"atras\":\n            navegador.retroceder()\n        else:\n            navegador.navegar(entrada)\n\n        navegador.mostrar_pagina_actual()\n    \n\nclass Cola:\n    def __init__(self):\n        self.items = []\n\n    def esta_vacia(self):\n        return self.items == []\n\n    def agregar(self, item):\n        self.items.append(item)\n\n    def eliminar(self):\n        if not self.esta_vacia():\n            return self.items.pop(0)\n        else:\n            return None\n\n\nclass ImpresoraCompartida:\n    def __init__(self):\n        self.cola_impresion = Cola()\n\n    def recibir_documento(self, documento):\n        self.cola_impresion.agregar(documento)\n        print(\"Documento recibido:\", documento)\n\n    def imprimir_documento(self):\n        documento = self.cola_impresion.eliminar()\n        if documento:\n            print(\"Imprimiendo:\", documento)\n        else:\n            print(\"No hay documentos en la cola de impresión.\")\n\n    def mostrar_cola(self):\n        if self.cola_impresion.esta_vacia():\n            print(\"Cola de impresión vacía.\")\n        else:\n            print(\"Cola de impresión:\", self.cola_impresion.items)\n\n# EXTRA: SIMULA EL MECANISMO DE UNA IMPRESORA\nif __name__ == \"__main__\":\n    impresora = ImpresoraCompartida()\n\n    while True:\n        entrada = input(\"Introduce un documento para imprimir o 'imprimir' para imprimir un documento (o 'salir' para salir): \")\n\n        if entrada.lower() == \"salir\":\n            print(\"Saliendo del programa.\")\n            break\n        elif entrada.lower() == \"imprimir\":\n            impresora.imprimir_documento()\n        else:\n            impresora.recibir_documento(entrada)\n\n        impresora.mostrar_cola()\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/jesusgdev.py",
    "content": "'''\nJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n   pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n   o lista (dependiendo de las posibilidades de tu lenguaje).\n  \n * DIFICULTAD EXTRA (opcional):\n *   Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n     de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n     que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n     el nombre de una nueva web.\n *   Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n     impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n     interpretan como nombres de documentos.\n  \n'''\n\n# Pilas\n\n# 1. Stacks - LIFO\n\n# Creamos una pila vacia usando una lista\nstack_lifo = []\n\n# Agregamos elementos a la pila\n# Al usar append(), cada nuevo elemento se añade en la parte superior de la pila.\n# El último elemento en entrar será el primero en salir.\nstack_lifo.append(\"book1\")\nstack_lifo.append(\"book2\")\nstack_lifo.append(\"book3\")\n\nprint(\"Pila actual:\", stack_lifo)\n\n# Eliminamos el último elemento de la pila con pop()\ntop = stack_lifo.pop()    \nprint(\"Quitamos:\", top)\n\n# Mostramos el estado de la pila después de quitar el elemento\nprint(\"Pila despues de quitar el ultimo elemento: \", stack_lifo)\n\n# 2. Colas (Queues) - FIFO (First In, First Out)\n\n# Creamos una cola vacía utilizando una lista\nqueue = []\n\n# Agregamos elementos a la cola con append()\n# Los elementos se añaden al final de la lista, simulando una cola.\nqueue.append(\"Person1\")\nqueue.append(\"Person2\")\nqueue.append(\"Person3\")\n\nprint(\"Cola actual:\", queue)\n\n# Eliminamos el primer elemento agregado usando pop(0)\n# Esto simula el comportamiento de una cola FIFO.\nfirst = queue.pop(0)\nprint(\"Pago en la fila del supermercado:\", first)\n\n# Mostramos el estado de la cola después\nprint(\"Fila despues:\", queue)\n\n\n'''\nExtra\n'''\n\n# Navegador Web (Simulado con pilas LIFO)\n\n# Simulación de un navegador web utilizando pilas (LIFO)\n# La pila backward_history almacena las páginas visitadas anteriormente\n# La pila forward_history almacena las páginas a las que se puede volver si el usuario presiona \"adelante\"\n# current_page contiene la página actual en la que se encuentra el usuario\n\nbackward_history = []\nforward_history = []\n\ndef browser():\n    current_page = \"www.solarflare/home.org\"  # Página inicial del navegador\n    print(\"\\n🌐 Bienvenido al navegador Solarflare\")\n    print(f\"Actualmente estás en: {current_page}\")\n    print('- Escribe el nombre de una nueva página para visitarla.')\n    print('- Escribe \"atras\" para regresar a la página anterior.')\n    print('- Escribe \"adelante\" para avanzar a una página siguiente.')\n    print('- Escribe \"salir\" para cerrar el navegador.')\n\n    while True:\n        action = input(\"\\n🔍 ¿Qué acción deseas realizar?: \")\n\n        # Acción: salir\n        # Esta condición permite al usuario salir del bucle principal y finalizar la simulación\n        if action == \"salir\":\n            print(\"\\n👋 Saliendo del navegador...\")\n            break\n\n        # Acción: adelante\n        # Permite al usuario avanzar a una página previamente visitada (si ha retrocedido antes)\n        elif action == \"adelante\":\n            if len(forward_history) > 0:\n                # Guardamos la página actual en el historial hacia atrás antes de avanzar\n                backward_history.append(current_page)\n                # Extraemos la siguiente página desde el historial hacia adelante\n                current_page = forward_history.pop()\n                # Mostramos al usuario la página a la que ha avanzado\n                print(f\"\\n➡️ Avanzando a: {current_page}\")\n            else:\n                # Si no hay historial hacia adelante, notificamos al usuario\n                print(\"⚠️ No hay páginas siguientes disponibles.\")\n\n        # Acción: atrás\n        # Permite al usuario volver a la página que visitó justo antes de la actual\n        elif action == \"atras\":\n            if len(backward_history) > 0:\n                # Guardamos la página actual en el historial hacia adelante antes de retroceder\n                forward_history.append(current_page)\n                # Extraemos la última página visitada desde el historial hacia atrás\n                current_page = backward_history.pop()\n                # Mostramos al usuario la página a la que ha retrocedido\n                print(f\"\\n⬅️ Regresando a: {current_page}\")\n            else:\n                # Si no hay historial hacia atrás, notificamos al usuario\n                print(\"⚠️ No hay páginas anteriores disponibles.\")\n\n        # Acción: visitar nueva página\n        # Cualquier entrada que no sea una palabra clave se interpreta como una nueva URL\n        else:\n            # Antes de cambiar la página actual, la guardamos en el historial hacia atrás\n            backward_history.append(current_page)\n            # Establecemos la nueva página como la actual\n            current_page = action\n            # Borramos el historial hacia adelante, ya que se inicia un nuevo camino de navegación\n            forward_history.clear()\n            # Mostramos la nueva página al usuario\n            print(f\"\\n🌍 Visitando nueva página: {current_page}\")\n\n\n\n# Impresora Compartida (Simulada con Cola - FIFO)\n\n# Simulación de una impresora compartida utilizando una cola (FIFO)\n# La lista printer_queue funciona como una cola de impresión\n# Los documentos se agregan al final de la cola y se imprimen por orden de llegada\n\nprinter_queue = []\n\ndef printer():\n    print(\"\\n🖨️ Bienvenido al sistema de impresión Lexar Plus\")\n    print('- Escribe el nombre de un documento para agregarlo a la cola de impresión.')\n    print('- Escribe \"imprimir\" para imprimir el documento más antiguo en la cola.')\n    print('- Escribe \"salir\" para cerrar el sistema de impresión.')\n\n    while True:\n        action = input(\"\\n📎 ¿Qué deseas hacer?: \")\n\n        # Acción: salir\n        # Finaliza la simulación de la impresora y sale del bucle principal\n        if action == \"salir\":\n            print(\"\\n👋 Cerrando el sistema de impresión...\")\n            break\n\n        # Acción: imprimir\n        # Extrae el documento más antiguo de la cola y lo \"imprime\"\n        elif action == \"imprimir\":\n            if len(printer_queue) > 0:\n                # Mostramos al usuario qué documento se está imprimiendo\n                print(f\"\\n🖨️ Imprimiendo documento: {printer_queue[0]}\")\n                # Eliminamos el documento de la cola después de imprimirlo\n                printer_queue.pop(0)\n            else:\n                # Si no hay documentos en la cola, se informa al usuario\n                print(\"⚠️ La cola de impresión está vacía. Agrega un documento.\")\n\n        # Acción: agregar documento\n        # Cualquier texto distinto a \"imprimir\" o \"salir\" se considera un nombre de documento\n        else:\n            # Añadimos el nuevo documento al final de la cola\n            printer_queue.append(action)\n            # Notificamos que el documento fue agregado correctamente\n            print(f\"\\n✅ Documento '{action}' agregado a la cola de impresión.\")    \n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/jesusway69.py",
    "content": "import os\n#os.system('clear') #MAC/LINUX\nos.system('cls') #WINDOWS\nimport collections\n\n\"\"\"\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n\"\"\"\n\n\n#MÉTODO PILA (LIFO)\ndef pila (my_list):\n for i in range (1,11):# Generamos números del 1 al 10\n    my_list.append(i)# Los añadimos a la lista\n print(my_list)# Imprimimos la lista con los 10 números\n eliminado = my_list.pop()# El método pop elimina el último elemento de la lista si no le pasamos ningún índice\n print(\"Eliminamos el número\", eliminado)# Mostramos el número eliminado\n print(my_list,\"\\n\")# imprimimos la lista con el último elemento eliminado\n\n\n#MÉTODO COLA (FIFO)\ndef cola (my_list):\n  for i in range (1,11):# Generamos números del 1 al 10\n    my_list.append(i)# Los añadimos a la lista\n  print(my_list)# Imprimimos la lista con los 10 números\n  eliminado = my_list.pop(0)# El método pop elimina el elemento de la lista cuyo índice le pasemos\n  print(\"Eliminamos el número\", eliminado)# Mostramos el número eliminado\n  print(my_list,\"\\n\")# imprimimos la lista con el primer elemento eliminado\n\n#MËTODO COLA (FIFO) CON MÉTODO DEQUE\ndef cola_deque (my_list):\n  my_list = collections.deque(range(1,11))# Generamos y añadimos números del 1 al 10\n  print(my_list)# Imprimimos la lista con los 10 números\n  eliminado = my_list.popleft()# El método popleft elimina el primer elemento de la lista (no admite argumentos)\n  print(\"Eliminamos el número\", eliminado)# Mostramos el número eliminado\n  print(my_list,\"\\n\")# imprimimos la lista con el primer elemento eliminado\n\nmy_list = []\npila(my_list)\nmy_list = []\ncola(my_list)\nmy_list = []\ncola_deque(my_list)\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n\"\"\"\n\ndef browser(my_list: list):\n \n while len(my_list)>=1:\n   print(\"Estás en la web:\",my_list[len(my_list)-1])\n   order = input(\"Introduzca web o escriba back para retroceder:\")\n   order = order.lower()\n   print()\n\n   if order == \"back\":\n     my_list.pop()\n\n   else:\n     my_list.append(order)\n\nmy_list = [\"inicio.com\"]\nbrowser(my_list)\n\ndef printer ():\n \n  while len(my_list)>=0:\n    print(\"\\nLista de documentos a imprimir:\", my_list, \"\\n\")\n    order = input(\"Introduzca un documento , escriba print para imprimir o exit para salir:\")\n    order = order.lower()\n    print()\n\n    if order != \"print\" and order != \"exit\":\n      my_list.append(order)\n\n    elif order == \"exit\":\n     print(\"Fin del programa\")\n     return\n    \n    elif len(my_list)==0:\n      print (\"\\nCola de impresión vacía, añada un documento o escriba exit para salir\")\n\n    elif order == \"print\" and len(my_list)>0:\n      print(\"\\nimprimiendo el documento:\",my_list.pop(0))\n     \n    \n    \nmy_list = []\nprinter()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/jhoshmc.py",
    "content": "from collections import deque\n\"\"\"\ntodo stack pila \n* segun interner, hay varias formas de implementar las pilas en python\n* una seria con una lista o usando una clase (deque) del modulo (collections)\n\"\"\"\n#* implementacion de una pila usando una lista\nclass Stack:\n  #? este seria el costructor de la clase\n  def __init__(self):\n    self.stack=[]\n  #? motodos\n  #* metodo para saber si la pila esta vacia o no\n  def is_empty(self):\n    return self.stack == []\n  \n  #* agregar elemento a la pila\n  def push(self,element):\n    self.stack.append(element)\n\n  #* eliminar el ultimo elemento de la pila y retornar el valor eliminado  \n  def pop(self):\n    return self.stack.pop()\n  \n  #* mostrar el ultimo elemento de la pila sin eliminarlo\n  def peek(self):\n    return self.stack[-1]\n  \n  #* retornar el tamaño de la pila \n  def size(self):\n    return len(self.stack)\n  \n  def print(self):\n    print(self.stack)\n\ndef ejecutandoStack():\n  pila =  Stack()\n  print(f\"la pila esta vacia: {pila.is_empty()}\")\n  print(\"agegando elementos a la pila: \")\n  pila.push(1)\n  pila.push(2)\n  pila.push(3)\n  print(f\"size de la pila: {pila.size()}\")\n  print(\"mostrando pila: \")\n  pila.print()\n  print(f\"eliminando elemento de la pila: {pila.pop()}\")\n  pila.print()\n  print(f\"mostrando ultimo elemento de la pila: { pila.peek()}\")\n\n# ejecutandoStack()\n\n\"\"\"\n! usando deque\n* una alternativa es usar deque del módulo collections, que es más eficiente para operaciones de insercion y\n* eliminación de ambos extremos de la estructura\n\"\"\"\ndef usandoDeque():\n  d_stack=deque() #*creando pila\n  print(\"agregando elementos a la cola\")\n  d_stack.append(1)\n  d_stack.append(2)\n  d_stack.append(3)\n  print(\"mostrando pila\")\n  print(d_stack)\n\n  print(f\"eliminando ultimo elemento de la pila: {d_stack.pop()}\")\n  print(d_stack)\n\n# usandoDeque()\n\n# todo cola \n\nclass Queque:\n  #? constructor\n  #* propiedades, creando una cola vacia\n  def __init__(self):\n    self.queque=[]\n\n  #* retorna si la cola está vacia o no\n  def is_empty(self):\n    return self.queque == []\n  \n  #* añade un elemento al final de la cola\n  def enqueque(self,element):\n    self.queque.append(element)\n  \n  #* eliminando el primer elemento de la cola y retornando el valor, si está vacia levanta una excepcion\n  def dequeque(self):\n    if self.is_empty():\n      raise Exception(\"la cola esta vacia\")\n    return self.queque.pop(0)\n  \n  #* retorna el tamaño de la cola\n  def size(self):\n    return len(self.queque)\n  \n  #* mostrar cola\n  def print(self):\n    print(self.queque)\n  \n  #* mostrar el primer elemento de la cola si eliminarlo\n  def front(self):\n    return self.queque[0]\n\ndef ejecutarQueque():\n  cola= Queque()\n  print(f\"la cola esta vacia?: {cola.is_empty()}\")\n  print(\"agregando elementos a la cola: \")\n  cola.enqueque(1)\n  cola.enqueque(2)\n  cola.enqueque(3)\n  print(f\"size de la cola: {cola.size()}\")\n  print(\"mostrando cola: \")\n  cola.print()\n  print(f\"eliminando primer elemento de la cola: {cola.dequeque()}\")\n  cola.print()\n\n# ejecutarQueque()\n\n#todo ejercicios extra\n\n#? historial web\n\ndef historial_web():\n  historial_Atras= Stack()\n  historial_siguiente= Stack()\n  pagina_Actual=\"inicio\"\n  print(\"\\n---------------------------------------------------------------------------------\")\n  print(\"\\n\\thistorial web\\n\")\n  print(\"vienvenido al historial web, hay algunas opciones que puedes ingresar\")\n  print(\"para ingresar un sitio web, ingresa: el nombre del sitio\")\n  print(\"para volver a una pagina anterior( si es que la hay ), ingresa: b\")\n  print(\"para ir a una pagaina siguiente( si es que hay ), ingresa: n\")\n  print(\"para salir del programa ingresa: s\")\n  print(\"-------------------------------------------------------------------------------\\n\")\n  while True:\n    print(f\"\\npagina actual: {pagina_Actual}\")\n    option= input(\"ingresa la opcion: \")\n    copia = option.lower()\n    if copia == \"b\" or copia ==\"n\" or copia ==\"s\":\n      if copia ==\"b\":\n        if not historial_Atras.is_empty():\n          historial_siguiente.push(pagina_Actual)\n          pagina_Actual= historial_Atras.pop()\n        else:\n          print(\"\\n no hay mas registros\")\n      if copia ==\"n\":\n        if not historial_siguiente.is_empty():\n          historial_Atras.push(pagina_Actual)\n          pagina_Actual= historial_siguiente.pop()\n        else:\n          print(\"\\n no hay mas registros\")\n      if copia == \"s\":\n        print(\"\\n saliendo del historial........\")\n        break\n    else:\n      historial_Atras.push(pagina_Actual)\n      pagina_Actual= option\n\n# historial_web()\n\n#? impresora compartida\ndef impresora():\n  cola=Queque()\n  print(\"\\n---------------------------------------------\")\n  print(\"\\timpresora compartida\\n\")\n  print(\"vienvenido a la impresora compartida, hay algunas opciones que puedes hacer\")\n  print(\"para ingresar un documento(nombre) ingresa: el nombre\")\n  print(\"para imprimir el documento que este en cola ingresa: i\")\n  print(\"para salir de la impresora, ingresa: s\")\n  print(\"---------------------------------------------------\\n\")\n  while True:\n    if not cola.is_empty():\n      print(f\"\\ndocumentos en cola: {cola.size()}, documento: {cola.front()}\")\n      option= input(\"ingrese la opcion: \")\n      copia= option.lower()\n      if copia == \"i\" or copia ==\"s\":\n        if copia ==\"i\":\n          print(f\"\\nimprimiendo el documento: {cola.dequeque()}\")\n        if copia == \"s\":\n          print(\"\\n saliendo de la impresora....\\n\")\n          break\n      else:\n        cola.enqueque(option)\n    else:\n      print(\"impresora sin documentos\")\n      option= input(\"ingrese un documento: \")\n      if option == \"s\":\n        print(\"saliendo........\")\n        break;\n      cola.enqueque(option)\n\nimpresora()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/jorgeadamowicz.py",
    "content": "## Pilas Y Colas\n\n# pilas (stacks - LIFO)\n\nmy_stack = [] #creo una lista\n\n#push\nmy_stack.append(1) #apilo, el primer elemento\nmy_stack.append(2) #apilo, el segundo elemento\nmy_stack.append(3) #apilo, el tercer elemento\n\nprint(my_stack)\n\n#pop\nmy_stack_item = my_stack[len(my_stack)-1] #recupero el ultimo elemento en mi lista(my_stack)\n#del my_stack[len(my_stack)-1] # borra el último elemento de mi lista\ndel my_stack[-1] #tambien se puede eliminar el elemento a travez de su indice\n\nprint(my_stack_item)\nprint(my_stack)\n\n#desapilando un elemento a travez del método \".pop()\"\nmy_pop_item = my_stack.pop()\n\nprint(my_pop_item)\nprint(my_stack)\n\n\n# Colas (Queues - FIFO)\nmy_queue = []\n\n#enqueue\nmy_queue.append(1) \nmy_queue.append(2) \nmy_queue.append(3) \n\nprint(my_queue)\n\n#dequeue\n\nprint(my_queue.pop(0)) # indicar el indice \"0\", que es el mas viejo de la lista. \ndel my_queue[0] #tambien lo podemos hacer como en el caso de pila pero esta vez asignanos el indice \"0\"\n\n\"\"\"\nExtra\n\"\"\"\n\ndef web_navigator():\n    \n    stack_web = []\n    stack_foward = []\n    \n    while True:\n        action = input(\"Añade una ruta, o selecciona atras, adelante o salir: \\n\")\n        \n        if action == \"salir\":\n            print(\"Saliendo de la aplicación\")\n            break\n        elif action == \"adelante\":\n            if stack_foward: # equiva a -> len(stack_foward)>0\n                siguiente_pagina = stack_foward.pop()# recupera la pagina hacia adelante\n                stack_web.append(siguiente_pagina) # la añade al historial\n                \n            else:\n                print(\"No hay paginas para avanzar.\")\n                 \n        elif action == \"atras\":\n            if stack_web: # equivale a -> len(stack_web)> 0:\n                ultima_pagina = stack_web.pop() #retira la pagina actual y la asigna a stack_foward\n                stack_foward.append(ultima_pagina)\n                if stack_web: \n                    print(f\"te envuentras en el sitio: {stack_web[-1]}\\n\")\n                else: \n                    print(\"Te encuentras en la pagina principal. el historial de navegacion se encuentra vacio.\")\n                \n            else:\n                print(\"Te encuentras en la pagina principal. el historial de navegacion se encuentra vacio.\")\n            \n        else:\n            stack_web.append(action)\n            stack_foward.clear()\n            \n        print(f\"Historial de navegación: {stack_web}\")\n        print(f\"pagina hacia adelante: {stack_foward}\\n\")\n        \nweb_navigator()\n    \n    \n\"\"\"\nNota: se implementó un pila temporal, para recuperar el valor alojado en \".pop\" y tener la opción de hacer\nun paso \"adelante\". cuando el usuario ingresa una nueva url la pila temporal se reinicia.\n\"\"\"\n    \ndef shared_printer():\n    \n    cola_impresion = []\n    while True:\n        action = input(\"Añade un documento a la cola, selecciona imprimir o salir: \\n\")\n        \n        if action == \"salir\":\n            break\n        elif action == \"imprimir\":\n            if len(cola_impresion) > 0:\n                print(f\" Imprimiendo el documento: {cola_impresion.pop(0)}\\n\")\n            else:\n                print(\"la cola de impresión esta vacia. no hay documentos por imprimir.\")\n        else:\n            cola_impresion.append(action)\n        print(f\"documentos en cola de impresion:\\n {cola_impresion}\")    \nshared_printer()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/josecox13.py",
    "content": "''' \nEjercicio 7\n* EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n'''\n# Pila / Stack (LIFO)\nstack = [0,1,2,3]\nstack.append(4) # push\nstack_item = stack[-1] # pop\ndel stack[-1]\n\nprint(stack_item)\nprint(stack)\n\n# También se puede hacer con el método pop de las listas\nprint(stack.pop())\nprint(stack)\n\n# Cola / Queue (FIFO)\n\nqueue = [0,1,2,3]\nqueue.append(4) # enqueue\nqueue.append(5) # enqueue\n\nprint(queue.pop(0)) # dequeue\nprint(queue)\n\n#De forma manual\nqueue_item = queue[0]\ndel queue[0]\nprint(queue_item)\nprint(queue)\n\n#Extra navegador web\ndef navegador_web():\n    stack = []\n    paginas_atras = []\n    while True:\n        action = input('Introduce una URL o interactúa con las palabras adelante/atrás/salir: ')\n        if action == \"salir\":\n            break\n        elif action == \"adelante\":\n            if len(paginas_atras) > 0:\n                stack.append(paginas_atras[-1])\n                paginas_atras.pop()\n            else:\n                print('No hay páginas para mostrar')\n        elif action == \"atrás\":\n            if len(stack) > 0:\n                paginas_atras.append(stack[-1])\n                stack.pop()\n        else:\n            stack.append(action)\n            paginas_atras = []\n        if len(stack) == 0:\n            print('No hay páginas para mostrar')\n        else:  \n            print(f'Estas en la web {stack[-1]}')\nnavegador_web()\n\n# Impresora compartida\ndef impresora_compartida():\n    queue = []\n    while True:\n        action = input('Introduce un documento para imprimir o interactúa con la palabra imprimir/salir: ')\n        if action == 'salir':\n            break\n        elif action == 'imprimir':\n            if len(queue) > 0:\n                print(f'Imprimiendo {queue[0]}')\n                queue.pop(0)\n        else:\n            queue.append(action)\n        print(f'Cola de impresion: {queue}')\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/jptxaya.py",
    "content": "#PILAS Y COLAS\n\n#PILAS \n#Last Input First Output\nmy_list = [10,20,30,40]\n\nmy_list.append(50)\nmy_list.append(60)\n#LIFO\nmy_list.pop()\n\nprint(my_list)\n\n#COLAS\n#First Input First Output\nmy_list = [10,20,30,40]\n\nmy_list.append(50)\nmy_list.append(60)\n\n##FIFO\nmy_list.pop(0)\n\nprint(my_list)\n\n\nprint(\"DIFICULTAD EXTRA\")\nprint(\"#######Navegacion########\")\ndef navegador_web():\n    my_navigation = []\n    my_back_urls=[]\n    \n    while True:\n       print(\"Selecciona la opcion:\")\n       print(\"1-Navegar a url\")\n       print(\"2-Adelante\")\n       print(\"3-Atras\")\n       print(\"4-Salir\")\n       option = input(\"Selecciona la opcion:\")\n       match option:\n           case \"4\":\n               break\n           case \"1\":\n               url_actual = input(\"Introduce la url:\")\n               my_navigation.append(url_actual)\n           case \"2\":\n               if len(my_back_urls) > 0:\n                   my_navigation.append(my_back_urls.pop())\n           case \"3\":\n                if len(my_navigation) > 0:\n                    my_back_urls.append(my_navigation.pop())\n       if len(my_navigation) > 0:\n           print(f\"URL actual: {my_navigation[len(my_navigation)-1]}\") \n       else:\n           print(f\"URL actual: None\")\n               \nnavegador_web()\n\nprint(\"#######Impresion########\")\ndef impresion():\n    my_prints = []\n    while True:\n       print(\"Selecciona la opcion:\")\n       print(\"1-Introducir documento\")\n       print(\"2-Imprimir\")\n       print(\"3-Salir\")\n       option = input(\"Selecciona la opcion:\")\n       match option:\n           case \"3\":\n               break\n           case \"1\":\n               doc = input(\"Introduce el documento:\")\n               my_prints.append(doc)\n           case \"2\":\n               if len(my_prints) > 0:\n                   print(f\"Imprimiendo documento.... {my_prints.pop(0)}\")\n                   print(\"Documento impreso\")\n               else:\n                   print(\"No existen documentos para imprimir\")\n\nimpresion()\n         \n\n\n\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/jtrujilloalcocer.py",
    "content": "# #07 PILAS Y COLAS\n## Ejercicio\n'''\n/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n */\n'''\nclass Stack: #LIFO \n    def __init__(self):#Constructor de la clase\n        self.stack = [] #Inicializamos la pila como una lista vacía\n\n    def push(self, item): #Metodo para añadir elementos a la pila\n        self.stack.append(item) #Añadimos el elemento al final de la lista\n\n    def pop(self): #Metodo para eliminar elementos de la pila\n        return self.stack.pop() #Eliminamos el ultimo elemento de la lista y lo retornamos\n\n    def __str__(self): #Metodo para imprimir la pila\n        return str(self.stack)\n    \nclass Queue: #FIFO\n    def __init__(self): #Constructor de la clase\n        self.queue = [] #Inicializamos la cola como una lista vacía\n\n    def push(self, item): #Metodo para añadir elementos a la cola\n        self.queue.append(item) #Añadimos el elemento al final de la lista\n\n    def pop(self): #Metodo para eliminar elementos de la cola\n        return self.queue.pop(0) #Eliminamos el primer elemento de la lista y lo retornamos\n\n    def __str__(self): #Metodo para imprimir la cola\n        return str(self.queue)   \n        \n'''\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atras\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n'''\nclass NavegadorWeb:\n    def __init__(self): #Constructor de la clase\n        self.back = Stack() #Inicializamos la pila de retroceso\n        self.forward = Stack() #Inicializamos la pila de avance\n        self.current = '' #Inicializamos la pagina actual\n        \n    def go_to(self, url): #Metodo para ir a una pagina\n        self.back.push(self.current) #Añadimos la pagina actual a la pila de retroceso\n        self.current = url #Cambiamos la pagina actual por la nueva\n        self.forward = Stack() #Vaciamos la pila de avance\n        \n    def back(self): #Metodo para retroceder\n        if not self.back.empty(): # Si la pila de retroceso no esta vacia\n            self.forward.push(self.current) #Añadimos la pagina actual a la pila de avance\n            self.current = self.back.pop() #Cambiamos la pagina actual por la ultima pagina visitada\n    \n    def forward(self): #Metodo para avanzar\n        if not self.forward.empty(): #Si la pila de avance no esta vacia\n            self.back.push(self.current) #Añadimos la pagina actual a la pila de retroceso\n            self.current = self.forward.pop() #Cambiamos la pagina actual por la ultima pagina visitada\n            \n    def __str__(self): #Metodo para imprimir la pagina actual\n        return self.current #Retornamos la pagina actual\n    \nclass Impresora: #Clase impresora  \n    def __init__(self): #Constructor de la clase\n        self.queue = Queue() #Inicializamos la cola de impresion \n        \n    def print(self, document): #Metodo para añadir documentos a la cola de impresion\n        self.queue.push(document) #Añadimos el documento a la cola de impresion\n        \n    def print_next(self): #Metodo para imprimir el siguiente documento\n        return self.queue.pop() #Eliminamos el primer documento de la cola de impresion y lo retornamos\n    \n    def __str__(self): #Metodo para imprimir la cola de impresion\n        return self.queue.__str__() #Retornamos la cola de impresion\n        "
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/juanRCoder.py",
    "content": "lista = []\r\n\r\n# PILA - LIFO\r\n# Los primeros en entrar son los ultimos en salir\r\nfor i in range(1, 5):     \r\n    lista.append(i)     # -> apilando elementos en la lista comienza con 1, 2, 3, 4\r\n    \r\n# print(lista)          # [1, 2, 3, 4]\r\n\r\nfor _ in range(1, 5):  \r\n    lista.pop()          # -> eliminando elementos en la lista comienza con 4, 3, 2, 1\r\n\r\n# print(lista) # []\r\n\r\n\r\n\r\n# COLA - FIFO:\r\n# Los primeros en entrar son los primeros en salir\r\nfor i in range(1, 5):\r\n    lista.append(i)     # -> apilando elementos en la lista comienza con 1, 2, 3, 4\r\n    \r\n# print(lista)          # [1, 2, 3, 4]\r\n\r\nfor i in range(1, 5):\r\n    lista.remove(i)     # -> removiendo elementos de la lista comienza con 1, 2, 3, 4\r\n    # print(lista)\r\n    \r\n# print(lista) # []\r\n\r\n\r\n#  * DIFICULTAD EXTRA (opcional):\r\n# Simulacion de las flechitas de una pagina web\r\ndef left_rigth():\r\n    webs = ['home', 'services', 'products',  'contact']\r\n    current = webs\r\n    i = 0\r\n    while i < 4:\r\n        if (i != 3):\r\n            print(f'Pagina Actual: {current[i]}')\r\n        else:\r\n            print(f'Pagina Actual: {current[i]} (ultimo)')\r\n           \r\n        eleccion = input(' < | > : ')\r\n        \r\n        if (eleccion == '>'):\r\n            current[i+1]\r\n            i+=1\r\n        else:\r\n            current[i-1]\r\n            i-=1\r\n            \r\nleft_rigth()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/juanchernandezdev.py",
    "content": "### Python Stracks And Queues ###\n\n#! Stack\n\nmy_stack = []\nprint(my_stack)\n\nmy_stack.append(55)\nmy_stack.append(15)\nmy_stack.append(30)\nmy_stack.append(18)\nprint(my_stack)\nmy_stack.pop(-1)\n\nprint(my_stack)\n  \n#! Queue\n\nmy_queue = []\nprint(my_queue)\n\nmy_queue.append(120)\nmy_queue.append(15)\nmy_queue.append(88)\nmy_queue.append(4)\nprint(my_queue)\nmy_queue.pop(0)\n\nprint(my_queue)\n\n#! Optional Challenge\n\nmy_stack = []\n\ndef navigation():\n  while True:\n    direction = input(f'Please enter an URL, \"next\", \"before\" to navigate or \"exit\" to stop the program: ').lower()\n    \n    if direction == 'exit':\n      print('Exiting program')\n      break\n    elif direction == 'next':\n      pass\n    elif direction =='before':\n      my_stack.pop()\n    else:\n      my_stack.append(direction)\n      \n    print(my_stack[len(my_stack) - 1])\n      \nnavigation()\n\nprint_queue = []\n\ndef printer():\n  while True:\n    info = input(f'Please enter a document name, \"print\" to print a document, or \"exit\" to quit the program: ').lower()\n    \n    if info == 'exit':\n      print('Exiting printer program.')\n      break\n    elif info == 'print':\n      if len(print_queue) > 0:\n        print(f'printing {print_queue.pop(0)}...')\n      else:\n        print('Print queue is empty')\n    else:\n      print_queue.append(info)\n      \n    print(f'Documents in queue {print_queue}')\n    \nprinter()\n    \n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/juandaherrera.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n\"\"\"\n\n\n# Pilas\nclass Stack:\n\n    def __init__(self, stack: list = []) -> None:\n        self.stack = stack\n\n    def __str__(self) -> str:\n        return str(self.stack)\n\n    def push(self, value) -> None:\n        self.stack.append(value)\n\n    def pop(self) -> None:\n        self.stack.pop()\n\n\nmy_stack = Stack([1, 2, 3, 4, 5])\nprint(my_stack)\n\n# Inserción\nmy_stack.push(6)\nprint(my_stack)\n\n# Eliminación\nmy_stack.pop()\nprint(my_stack)\n\nprint(\"---------------------------------\")\n\n\n# Colas\nclass Queue:\n    def __init__(self, queue: list = []) -> None:\n        self._queue = queue\n\n    def __str__(self) -> str:\n        return str(self._queue)\n\n    def queue(self, value) -> None:\n        self._queue.append(value)\n\n    def dequeue(self) -> None:\n        self._queue.pop(0)\n\n\nmy_queue = Queue([1, 2, 3, 4, 5])\nprint(my_queue)\n\n# Inserción\nmy_queue.queue(6)\nprint(my_queue)\n\n# Eliminación\nmy_queue.dequeue()\nprint(my_queue)\n\n# Ambas\nmy_queue.queue(7)\nmy_queue.dequeue()\nmy_queue.dequeue()\nmy_queue.dequeue()\nmy_queue.queue(8)\nmy_queue.dequeue()\nmy_queue.queue(9)\nprint(my_queue)\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atras\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n\"\"\"\n\nprint(\"---------------------------------\")\n\n\nclass Web(Stack):\n\n    def __init__(self, stack: list[str] = []) -> None:\n        super().__init__(stack)\n        self.last_index_selection = 0\n\n    def foward(self) -> str:\n        if self.last_index_selection + 1 > len(self.stack) - 1:\n            self.last_index_selection = 0\n            return self.stack[self.last_index_selection]\n        self.last_index_selection += 1\n        return self.stack[self.last_index_selection]\n\n    def back(self) -> str:\n        if self.last_index_selection - 1 < 0:\n            self.last_index_selection = len(self.stack) - 1\n            return self.stack[self.last_index_selection]\n        self.last_index_selection -= 1\n        return self.stack[self.last_index_selection]\n\n\nprint(\"Web: 1\", \"Impresora: 2\", sep=\"\\n\")\nprogram = input(\"Qué programa quieres probar? \")\nmy_web = Web(['Index', 'About me', 'Education', 'Courses'])\nprint(my_web)\n\nif program == \"1\":\n    print(\n        \"------------ Web -------------\",\n        \"Opciones:\",\n        \"adelante -> siguiente página\",\n        \"atras -> página anterior\",\n        \"web -> todas las páginas\",\n        \"exit -> salir\",\n        \"cualquier string -> nueva página\",\n        sep=\"\\n\",\n    )\n\nwhile program == \"1\":\n    option = input(\"Opción: \").lower()\n    match option:\n        case \"adelante\":\n            print(\"Página actual: \", my_web.foward())\n        case \"atras\":\n            print(\"Página actual: \", my_web.back())\n        case \"web\":\n            print(my_web)\n        case \"exit\":\n            break\n        case _:\n            my_web.push(option)\n\n\nprint(\"---------------------------------\")\n\nif program == \"2\":\n    print(\n        \"------------ Impresora -------------\",\n        \"Opciones:\",\n        \"imprimir -> imprime el siguiente documento\",\n        \"all -> todas las impresiones pendientes\",\n        \"exit -> salir\",\n        \"cualquier string -> nuevo documento\",\n        sep=\"\\n\",\n    )\n\ndocuments = Queue([\"Hoja de vida\", \"Trabajo literatura\", \"Carta presentación\"])\n\nwhile program == \"2\":\n    option = input(\"Opción: \").lower()\n    match option:\n        case \"imprimir\":\n            print(\"Imprimiendo: \", documents._queue[0])\n            documents.dequeue()\n        case \"all\":\n            print(documents)\n        case \"exit\":\n            break\n        case _:\n            documents.queue(option)\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/juanmax2.py",
    "content": "\"\"\"\nEjercicio\n\"\"\"\n\n# Pila/Stack\n\nstack = []\n\n# Push de elementos\n\nstack.append(\"1\")\nstack.append(\"2\")\nstack.append(\"3\")\nprint(stack)\n\n# Pop de elementos\n\nstack_item = stack.pop()\nprint(stack)\nprint(stack_item)\n\n# Cola\n\n# Encolar\ncola = []\ncola.append(\"4\")\ncola.append(\"5\")\ncola.append(\"6\")\n\nprint(cola)\n\n# Desencolar\n\ncola_item = cola.pop(0)\nprint(cola)\nprint(cola_item)\n\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n\n\"\"\"\n\n# Pila\ndef navegador_web():\n    continuar = True\n    historial = []\n    historial_pop = []\n    while continuar == True:\n        \n        do = input(\"Añade una url o interactúa con palabras adelante/atras/salir: \")\n        \n        if do == \"adelante\".upper() or do == \"adelante\".lower() \\\n            or do == \"adelante\".capitalize():\n                historial.append(historial_pop.pop())\n                print(historial[-1])\n                \n        elif do == \"atras\".upper() or do == \"atras\".lower() \\\n            or do == \"atras\".capitalize():\n                if len(historial) > 0:\n                    historial_pop.append(historial.pop())\n                    print(historial[-1])\n                else:\n                    print(\"No hay mas webs en el historial\")\n                    \n        elif do == \"salir\".upper() or do == \"salir\".lower() \\\n            or do == \"salir\".capitalize():\n                print(\"Cerrando sesión...\")\n                continuar = False\n        else:\n            historial.append(do)\n        \n        print(f\"Web acutal: {len(historial) - 1}\")\n\nnavegador_web()\n\n# Cola\n\"\"\" * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\"\"\"\n \ndef imprimir():\n    continuar = True\n    documentos = []\n    documentos_impresos = []\n    while continuar == True:\n        \n        do = input(\"\"\"Introduce que quieres hacer:\n                   Escribe el nombre del document para enviarlo\n                   Escribe imprimir para imprimir\n                   Escribe salir para salir   \n                   \"\"\")\n        \n        if do == \"imprimir\".upper() or do == \"imprimir\".lower() \\\n            or do == \"imprimir\".capitalize():\n                if len(documentos) <= 0:\n                    print(\"No hay archivos para imprimir\")\n                else:\n                    documentos_impresos.append(documentos.pop(0))\n                    print(f\"Imprimiendo documento {documentos_impresos[-1]}\")\n        elif do == \"salir\".upper() or do == \"salir\".lower() \\\n            or do == \"salir\".capitalize():\n                print(\"Cerrando sesión...\")\n                continuar = False\n        else:\n            documentos.append(do)\n            print(f\"Documento {do} añadido a la cola de impresion\")\n\n                \nimprimir()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/juanppdev.py",
    "content": "\"\"\"\nImplementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n\"\"\"\n\n\"\"\"\nStack LIFO\n\"\"\"\n\nclass Stack:\n    def __init__(self):\n        self.items = []\n\n    def push(self, item):\n        self.items.append(item)\n\n    def pop(self):\n        if not self.is_empty():\n            return self.items.pop()\n\n    def peek(self):\n        if not self.is_empty():\n            return self.items[-1]\n\n    def is_empty(self):\n        return len(self.items) == 0\n\n    def size(self):\n        return len(self.items)\n    \nstack = Stack()\nstack.push(1)\nstack.push(2)\nstack.push(3)\nprint(stack.peek()) # prints: 3\nprint(stack.pop())  # prints: 3\nprint(stack.size()) # prints: 2\n\n\"\"\"\nQueue (FIFO)\n\"\"\"\n\nclass Queue:\n    def __init__(self):\n        self.items = []\n\n    def enqueue(self, item):\n        self.items.append(item)\n\n    def dequeue(self):\n        if not self.is_empty():\n            return self.items.pop(0)\n\n    def peek(self):\n        if not self.is_empty():\n            return self.items[0]\n\n    def is_empty(self):\n        return len(self.items) == 0\n\n    def size(self):\n        return len(self.items)\n    \nqueue = Queue()\nqueue.enqueue(1)\nqueue.enqueue(2)\nqueue.enqueue(3)\nprint(queue.peek()) # prints: 1\nprint(queue.dequeue()) # prints: 1\nprint(queue.size()) # prints: 2\n\n\"\"\"\nEXTRA\n\"\"\"\n\nclass NavegadorWeb:\n    def __init__(self):\n        self.pila = []\n        self.actual = None\n\n    def navegar(self, sitio):\n        if self.actual is not None:\n            self.pila.append(self.actual)\n        self.actual = sitio\n        print(\"Navegando a:\", sitio)\n\n    def adelante(self):\n        if self.pila:\n            sitio = self.pila.pop()\n            print(\"Avanzando hacia adelante a:\", sitio)\n            self.actual = sitio\n        else:\n            print(\"No hay páginas para avanzar\")\n\n    def atras(self):\n        if self.actual is not None:\n            print(\"Retrocediendo hacia atrás a:\", self.actual)\n            self.actual = None\n        else:\n            print(\"No hay página actual\")\n\n# Probando la implementación\nnavegador = NavegadorWeb()\nnavegador.navegar(\"www.ejemplo1.com\")\nnavegador.navegar(\"www.ejemplo2.com\")\nnavegador.adelante()\nnavegador.atras()\nnavegador.adelante()\n\n\nfrom collections import deque\n\nclass ImpresoraCompartida:\n    def __init__(self):\n        self.cola_impresion = deque()\n\n    def agregar_documento(self, documento):\n        self.cola_impresion.append(documento)\n        print(\"Documento agregado a la cola:\", documento)\n\n    def imprimir(self):\n        if self.cola_impresion:\n            documento = self.cola_impresion.popleft()\n            print(\"Imprimiendo documento:\", documento)\n        else:\n            print(\"No hay documentos para imprimir\")\n\n# Probando la implementación\nimpresora = ImpresoraCompartida()\nimpresora.agregar_documento(\"Documento1\")\nimpresora.agregar_documento(\"Documento2\")\nimpresora.imprimir()\nimpresora.imprimir()\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/juserdev.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */ \"\"\"\n\n\n# stacks\n\nmy_list = []\n\nmy_list.append(1)\nmy_list.append(2)\nmy_list.append(3)\nmy_list.append(4)\nmy_list.append(5)\nprint(my_list)\n\nmy_list.pop()\nprint(my_list)\nmy_list.pop()\nprint(my_list)\nmy_list.pop()\nprint(my_list)\nmy_list.pop()\nprint(my_list)\nmy_list.pop()\nprint(my_list)\n\n\n# queue\n\nmy_list.append(1)\nmy_list.append(2)\nmy_list.append(3)\nmy_list.append(4)\nmy_list.append(5)\n\nprint(my_list)\n\ndel my_list[0]\nprint(my_list)\ndel my_list[0]\nprint(my_list)\ndel my_list[0]\nprint(my_list)\ndel my_list[0]\nprint(my_list)\ndel my_list[0]\nprint(my_list)\n\ndef web_navigation():\n  stack = []\n  forward_stack = []\n  \n  while True:\n    action = input(\"agrega una url: \")\n\n    if action == \"salir\":\n      print(\"saliste del programa\")\n      break\n\n    elif action == \"adelante\":\n      if len(forward_stack) == 0:\n        print(\"No hay pagina para donde coger papa bello\")\n      else:\n        stack.append(forward_stack.pop())\n        print(f\"Volviste a la pagina --> {stack[len(stack) -1]}\")\n\n    elif action == \"atras\":\n      if len(stack) > 1:\n        forward_stack.append(stack.pop())\n        print(f\"has vuelto a la pagina --> {stack[-1]}\")\n      else:\n        print(\"No puedo ir mas atras papa bello\")\n\n\n    elif action == \"ver\":\n      print(\"Historial de navegacion\", \"\".join(stack))\n\n    else:\n      stack.append(action)\n\n    if len(stack) > 0:\n      print(f\"Has navegado a la web {stack[len(stack) -1]}\")\n    else:\n      print(\"estas en la pagina de inicio\")\n    \n\nweb_navigation()\n\ndef impresora():\n  queue = []\n\n  while True:\n    action = input(\"Añade un documento o escrime imprimir o salir: \")\n\n    if action == \"imprimir\":\n      if len(queue) > 0:\n        print(queue.pop(0))\n      else:\n        print(\"No tienes nada que imprimir papa lindo\")\n    elif action == \"ver\":\n      print(\"\".join(queue))\n\n    elif action == \"salir\":\n      print(\"te saliste\")\n      break\n    else:\n      queue.append(action)\n\nimpresora()\n\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/k-90.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n\"\"\"\n\n### Pilas \n\nstack = [] # Se apilan elementos (LIFO: Last In, First Out)\n\nstack.append(1)\nstack.append(2)\nstack.append(3)\nstack.append(4)\nprint(stack)\nstack_item = stack[len(stack) - 1]\ndel stack[len(stack) - 1]\nprint(stack_item)\nstack.pop(1)\nprint(stack)\n\n### Colas\n\nqueue = [] # Se crean colas de elementos (FIFO: First In, First Out)\nqueue.append(1)\nqueue.append(2)\nqueue.append(3)\nqueue.append(4)\n\nqueue_item = queue[0]\ndel queue[0]\nprint(queue)\nqueue.pop(0)\nprint(queue)\n\n### Extra\n\ndef web_navi():\n    \n    stack = []\n\n    while True:\n\n        action = input(\n            \"Inserte una url o continue con adelante/atras/salir: \")\n        \n        \n        if action == \"salir\":\n            break\n        elif action == \"adelante\":\n            pass\n        elif action == \"atrás\":\n            if len(stack) > 0:\n                stack.pop()  \n        else:\n            stack.append(action) \n\n        if len(stack) > 0:\n            print(f\"Has navegado a la web ,{stack[len(stack)-1]}\")\n        else:\n            print(\"Estas en la pagina de inicio\")\n            \n\nweb_navi()\n\ndef online_printed():\n    queue = []\n\n    while True:\n        \n        action = input(\"Añada un elemeno o seleccione Imprimir/Salir\")\n\n        if action == \"Salir\":\n            break\n        elif action == \"Imprimir\":\n            if len(queue) > 0:\n                print(f\"Imprimiendo: {queue.pop(0)}\")\n        else:\n            queue.append(action)\n\n        print(f\"Cola de impresion: {queue}\")\n    \nonline_printed()\n\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/keltoi-dev.py",
    "content": "\"\"\"\n* EJERCICIO:\n* Implementa los mecanismos de introducción y recuperación de elementos propios de las\n* pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n* o lista (dependiendo de las posibilidades de tu lenguaje).\n\"\"\"\n\n# Implementacion de las pilas (stacks - LIFO)\npila = []  # Creamos la pila\n\n# Le agregamos elementos\npila.append(\"Elemento 1\")\npila.append(\"Elemento 2\")\npila.append(\"Elemento 3\")\n\nprint(\"Asi esta la pila: \", pila)\n\n# Desapilamos elementos (Siempre sale primero el ultimo que ingresa)\npila.pop()\npila.pop()\n\nprint(\"Asi esta la pila: \", pila)\n\n# Le agregamos mas elementos\npila.append(\"Elemento 4\")\npila.append(\"Elemento 5\")\n\nprint(\"Asi esta la pila: \", pila)\n\n# Desapilamos elementos (Siempre sale primero el ultimo que ingresa)\npila.pop()\npila.pop()\n\nprint(\"Asi esta la pila: \", pila)\n\nprint(\"-\" * 30)\n# Implementacion de las pilas (stacks - LIFO)\ncola = []  # Creamos la pila\n\n# Le agregamos elementos\ncola.append(\"Elemento 1\")\ncola.append(\"Elemento 2\")\ncola.append(\"Elemento 3\")\n\nprint(\"Asi esta la cola: \", cola)\n\n# Desapilamos elementos (Siempre sale primero el ultimo que ingresa)\ncola.pop(0)\ncola.pop(0)\n\nprint(\"Asi esta la cola: \", cola)\n\n# Le agregamos mas elementos\ncola.append(\"Elemento 4\")\ncola.append(\"Elemento 5\")\n\nprint(\"Asi esta la cola: \", cola)\n\n# Desapilamos elementos (Siempre sale primero el ultimo que ingresa)\ncola.pop(0)\ncola.pop(0)\n\nprint(\"Asi esta la cola: \", cola)\n\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n* - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n*   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n*   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n*   Las palabras \"adelante\", \"atras\" desencadenan esta acción, el resto se interpreta como\n*   el nombre de una nueva web.\n* - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n*   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n*   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n*   interpretan como nombres de documentos.\n\"\"\"\n\n# NAVEGADOR WEB\n\nprint(\"\\nSe inicia el navegador web...\\n\")\n\nhistorial = []\nindice = 0\n\nwhile True:\n    pagina = input(\"Ingrese una URL o navegar con: atras, adelante o salir: \").lower()\n    if pagina == \"salir\":\n        break\n    elif pagina == \"atras\":\n        if indice == (len(historial) - 1):\n            print(\"No se puede ir mas atras\")\n        else:\n            indice += 1\n            print(historial[indice])\n    elif pagina == \"adelante\":\n        if indice == 0:\n            print(\"No se puede ir mas adelante\")\n        else:\n            indice -= 1\n            print(historial[indice])\n    else:\n        historial.insert(0, pagina)\n        indice = 0\n\n\n# IMPRESORA\n\nprint(\"\\nSe inicia la impresora compartida...\\n\")\n\nbuffer = []\n\nwhile True:\n    documento = input(\"Ingrese el nombre de un documento, imprimir o salir: \").lower()\n    if documento == \"imprimir\":\n        if buffer == []:\n            print(\"No hay documentos por imprimir\")\n        else:\n            print(\"Imprimiendo el documento:\", buffer[0])\n            buffer.pop(0)\n    elif documento == \"salir\":\n        break\n    else:\n        buffer.append(documento)\n    print(\"Estado de la cola de impresion\")\n    print(buffer)\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/kenysdev.py",
    "content": "# ╔══════════════════════════════════════╗\n# ║ Autor:  Kenys Alvarado               ║\n# ║ GitHub: https://github.com/Kenysdev  ║\n# ║ 2024 -  Python                       ║\n# ╚══════════════════════════════════════╝\n\n# ----------------------------------------\n# Pilas(stack - LIFO):\n# ----------------------------------------\n# - Es una estructura de datos. \n# - Sigue el principio LIFO (last in, first out), significa que\n#   el último elemento añadido, es el primero en ser retirado.\n# Implementar:\nclass stack:\n    def __init__(self):\n        self.elements = []\n    \n    def __len__(self): # total elementos.\n        return len(self.elements)\n\n    def is_empty(self): # es vacia.\n        return len(self) == 0\n    \n    def push(self, item): # Agregar elemento.\n        self.elements.append(item)\n    \n    def push_batch(self, items): # Agregar multiples.\n        # use <history.push_batch([\"1\", \"2\", \"3\"])\">\n        self.elements.extend(items)\n    \n    def pop_get(self): # Eliminar y obtener.\n        if not self.is_empty():\n            return self.elements.pop()\n        else: \n            return None\n    \n    def get_top(self): # Obtener sin eliminar.\n        if not self.is_empty():\n            return self.elements[-1]\n        else: \n            return None\n    \n    def get_tuple(self): # retornar pila como tupla.\n        return tuple(reversed(self.elements))\n    \n    def clear(self): # vaciar pila.\n        self.elements.clear()\n# ____________________________________________\n# Ejercicio usando la implementación de pilas:\n\"\"\"\nSimula el mecanismo adelante/atrás de un navegador web.\n- Crea un programa en el que puedas navegar a una página o indicarle que te quieres \n  desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n- Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto \n  se interpreta como el nombre de una nueva web.\n\"\"\"\n\nmsg_nav = \"\"\"\nHistorial de navegación:\n-------------------------------------------------\nUsar: \"<\" para página anterior.\n      \">\" para página adelante.\n      \"h\" Ver historial completo.\n      \"x\" para salir. \nEscribir web para agregar:\n-------------------------------------------------\"\"\"\ndef nav_history(history, back_history, forward_history):\n    def web(url):\n        print(f\"({len(back_history)}) <- Atras <-[Actual: {url}]-> Delante -> ({len(forward_history)})\")\n\n    def back():\n        if not back_history.is_empty():\n            forward_history.push(history.get_top()) # Obtener sin eliminar.\n            history.push(back_history.pop_get())    # Eliminar y obtener.\n            web(history.get_top()) \n        else:\n            print(\"No hay página previa.\")\n\n        select()\n\n    def forward():\n        if not forward_history.is_empty():\n            back_history.push(history.get_top())\n            history.push(forward_history.pop_get())\n            web(history.get_top())\n        else:\n            print(\"No hay página siguiente.\")\n\n        select()\n\n    def new_web(url):\n        back_history.push(history.get_top())\n        forward_history.clear()\n        history.push(url)\n        web(history.get_top())\n        select()\n\n    def the_history():\n        if not history.is_empty():\n            for item in history.get_tuple():\n                print(item)\n        else:\n            print(\"Historial vacío.\")\n\n        select()\n\n    def select():\n        print(\"____________\")\n        action = input(\"acción: \")\n        if len(action) > 0:\n            match action:\n                case \"<\": back()\n                case \">\": forward()\n                case \"x\": main()\n                case \"h\": the_history()\n                case _:   new_web(action)\n        else:\n            print(\"Eres muy gracioso xD.\")\n            select()\n\n    print(msg_nav)\n    web(history.get_top())\n    select()\n\n# -----------------------------------------\n# Colas (Queue - FIFO):\n# -----------------------------------------\n# - Estructura de datos que sigue el principio FIFO(First In, First Out)\n# - El primer elemento que se inserta es el primero en ser retirado.\n# Implementar:\nfrom collections import deque\nclass queue:\n    def __init__(self):\n        self.elements = deque()\n\n    def __len__(self): # total elementos.\n        return len(self.elements)\n\n    def is_empty(self): # es vacia.\n        return len(self) == 0\n    \n    def enqueue(self, item): # agregar\n        self.elements.append(item)\n\n    def enqueue_all(self, items): # Agregar multiples.\n        self.elements.extend(items)\n\n    def dequeue(self): # Eliminar y devolver\n        if not self.is_empty():\n            return self.elements.popleft()\n        else:\n            return None\n    \n    def peek(self): # Obtener sin eliminar.\n        if not self.is_empty():\n            return self.elements[-1]\n        else: \n            return None\n    \n    def get_tuple(self): # retornar cola como tupla.\n        return tuple(self.elements)\n\n    def clear(self): # vaciar cola.\n        self.elements.clear()\n\n# ____________________________________________\n# Ejercicio usando la implementación de Colas:\n\"\"\"\nSimula el mecanismo de una impresora compartida.\n- recibe documentos y los imprime cuando así se le indica.\n- La palabra \"imprimir\" imprime un elemento de la cola.\n- El resto de palabras se interpretan como nombres de documentos.\n\"\"\"\n\nmsg_printer = \"\"\"\n------------------------------------------------\nUsar: \"p\" Imprimir.\n      \"l\" Ver documentos pendientes.\n      \"x\" para salir.\nEscribir nombre de documento para enviar a cola: \n------------------------------------------------\"\"\"\ndef queue_printer(doc_queue):\n    def print_doc():\n        if not doc_queue.is_empty():\n            print(f\"{doc_queue.dequeue()} -> ha sido impreso.\")\n            print(f\"{len(doc_queue)} -> archivos faltantes\")\n        else:\n            print(\"No hay archivos.\")\n        select()\n\n    def queue_pending():\n        if not doc_queue.is_empty():\n            for doc in doc_queue.get_tuple():\n                print(doc)\n        else:\n            print(\"No hay archivos.\")\n\n        select()\n\n    def send_doc(doc):\n        doc_queue.enqueue(doc)\n        print(\"Archivo agregado a cola de impresión.\")\n        select()\n\n    def select():\n        print(\"____________\")\n        action = input(\"acción: \")\n        if len(action) > 0:\n            match action:\n                case \"p\": print_doc()\n                case \"l\": queue_pending()\n                case \"x\": main()\n                case _:   send_doc(action)\n        else:\n            print(\"Eres muy gracioso xD.\")\n            select()\n\n    print(msg_printer)\n    select()\n#__________________________________________________________\n#__________________________________________________________\nmsg_home = \"\"\"\n----------------------------------\nUsar: \"1\" para simulador_navegador.\n      \"2\" para simulador_impresora.\n      \"Otra tecla\" para salir.\n----------------------------------\n\"\"\"\ndef main():\n    def case_nav():\n        back_history = stack()\n        forward_history = stack()\n        history = stack()\n        history.push(\"Inicio\")\n        nav_history(history, back_history, forward_history)\n    \n    def case_printer():\n        doc_queue = queue()\n        doc_queue.enqueue_all([\"a.pdf\", \"b.txt\", \"c.docx\"])\n        queue_printer(doc_queue)\n\n    print(msg_home)\n    select = input(\"seleccionar: \")\n    match select:\n        case \"1\": case_nav()          \n        case \"2\": case_printer()\n        case _: print(\"Bye\")\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/kodenook.py",
    "content": "\"\"\"\n    Stack\n\"\"\"\n\nletters = ['a', 'b', 'c', 'd']\n\n''' insert '''\n\nletters.append('e')\nletters.append('f')\n\nprint(letters)\n\n''' delete '''\n\nletters.pop()\n\nprint(letters)\n\n\"\"\"\n    Queue\n\"\"\"\n\nletters = ['a', 'b', 'c', 'd']\n\n''' insert '''\n\nletters.append('e')\nletters.append('f')\n\nprint(letters)\n\n''' delete '''\n\ndel letters[0]\n\nprint(letters)\n\n\"\"\"\n    Exercise\n\"\"\"\n\ndef web_navigation() -> None:\n\n    stack = []\n    option = ''\n\n    while option != 'exit':\n\n        option = input('give a url or next, before, exit: ')\n\n        if option == 'next':\n            pass\n        elif option == 'before':\n            stack.pop()\n            print(f'you are in {stack[-1]}')\n        else:\n            stack.append(option)\n            print(f'you are in {stack[-1]}')\n\nweb_navigation()\n\ndef shared_print() -> None:\n    queue = []\n    option = ''\n\n    while option != 'exit':\n\n        option = input( 'give a document or print, exit: ')\n\n        if option == 'print':\n            printed = queue[0]\n            del queue[0]\n            print(f'you printed {printed}')\n        else:\n            queue.append(option)\n\n\nshared_print()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/kuroz00.py",
    "content": "class stack:\n    def __init__(self):\n        self.stack = [] #se inicia como una lista vacia\n    \n    def push(self):\n        dato = input('que desea agregar?: ')\n        self.stack.append(dato) #se le agrega un valor \n        \n    def pop(self):\n        return self.stack.pop() #se elimina el ultimo valor agregado\n    \n    def view(self):\n        return self.stack.copy() #retorna una copia\n\nclass queue:\n    def __init__(self):\n        self.queue = [] #se inicia como una lista vacia\n    \n    def push(self):\n        self.stack.append()#incorporar valor a la cola\n        \n    def pop(self):\n        return self.stack.remove(stack[0]) #eliminamos el primero en la cola\n    \n    def view(self):\n        return self.stack.copy() #mostramos una copia\n\n''' ###uso de la pila por terminal\nstack = stack()\nwhile 1:\n    print('que desea hacer?\\n 1.- ver\\n 2.- agregar\\n 3.- eliminar\\n 4.- fin')\n    opcion = int(input('-> '))\n\n    if opcion == 1:\n        print('pila ->', stack.view())\n    elif opcion == 2:\n        stack.push()\n    elif opcion == 3:\n        stack.pop()\n    elif opcion == 4:\n        print('adios.')\n        break\n    else:\n        print('Opcion invalida.')\n'''\n\n###DIFICULTAD EXTRA###   \"\"\".-.- Incompleto, lo arreglare y completare una vez estudie mas, no he tenido tiempo esta semana :(  .-.-\"\"\"\nclass navegadorWeb: #Creo un objeto Navegador\n    historial = []  #Historial en el que se guardaran las paginas por las que pase el usuario para despues retornar o regresar\n\n    def __init__(self):\n        pass\n    \n    def pagina_navegar(self, direccion):\n        self.direccion = direccion\n        print(f'Bienvenido a {direccion}!')\n        return navegadorWeb.historial.append(direccion)   \n\n    def pagina_anterior(self):\n\n        return navegadorWeb.historial.pop().copy()\n    \n    def historial(self):\n        return navegadorWeb.historial\n\n\nnavegador = navegadorWeb() \nprint('NAVEGADOR') #titulo del navegador\n\nwhile 1:\n    print('1.- Navegar 2.- Pagina anterior 3.- Historial 4.-Cerrar ')\n    opcion = int(input('Seleccione una accion: '))\n    \n    if opcion == 1:\n        direccion = input('donde desea navegar?')\n        navegador.pagina_navegar(direccion)\n        print(navegador.historial)\n    elif opcion == 2:\n        navegador.pagina_anterior()\n        print(navegadorWeb.historial[-1])\n    elif opcion == 3:\n        print(navegador.historial())\n    elif opcion == 4:\n        print('Que tenga buen dia')\n        break\n    else:\n        print('Opcion no valida')\n        break\n    "
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/linerlander.py",
    "content": "\"\"\"\nEjercicio\n\"\"\"\n\n# Pilas/Stack (LIFO)\n\nstack = []\n\n# push\nstack.append(1) \nstack.append(2) \nstack.append(3) \nprint(stack)\n\n# pop\nstack_item = stack[len(stack) - 1]\ndel stack[len(stack) - 1]\nprint(stack_item)\n\nprint(stack.pop())\n\nprint(stack)\n\n# Cola/Queue(FIFO)\n\n# encolar\nqueue = []\nqueue.append(1)\nqueue.append(2)\nqueue.append(3)\nprint(queue)\n\n# colar\nqueue_item = queue[0]\ndel queue[0]\nprint(queue_item)\n\nprint(queue.pop(0))\n\nprint(queue)\n\n\"\"\"\nExtra\n\"\"\"\n\ndef web_navegation():\n    stack = []\n\n    while True:\n        action = input(\"Añade una urla o interactúa con palabras adelante/atrás/salir: \")\n\n        if action == \"salir\":\n            print('Saliendo del navegador web.')\n            break\n        elif action == \"adelante\":\n            pass\n        elif action == \"atrás\":\n            if len(stack) > 0:\n                stack.pop()\n        else:\n            stack.append(action)\n        if len(stack) > 0:\n            print(f\"Has navegado ala web {stack[len(stack) -1]}.\")\n        else:\n            print('Estás en la página de inicio.')\n#web_navegation()\n            \ndef share_printed():\n    queue = []\n\n    while True:\n        action = input(\"Añade una documento o seleciona imprimir/salir: \")\n\n        if action == \"salir\":\n            break\n        elif action == \"imprimir\":\n            if len(queue) > 0:\n                print(f\"Imprimiendo: {queue.pop(0)}\")\n            else:\n                print('La cola de la impresión esta vacía')\n                break\n        else:\n            queue.append(action)\n\n        print(f'cola de impresión {queue}')\n\n#share_printed()\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/m1l0j05.py",
    "content": "# Teoria\n\n# Pilas (Stacks - LIFO):\n# 1. Una pila es una estructura de datos en la que los elementos\n# se añaden y se eliminan siguiendo una política conocida como LIFO, \n# que significa \"Last In, First Out\" (último en entrar, primero en salir).\n# \n# 2. Imagina una pila de platos: \n# El último plato que colocas sobre la pila será el primero en ser retirado.\n# \n# 3. En Python, puedes implementar una pila utilizando una lista. \n# Puedes añadir elementos a la pila usando el método `append()` \n# y eliminar elementos usando el método `pop()`.\n\n# Colas (Queue - FIFO):\n# 1. Una cola es otra estructura de datos en la que los elementos se añaden y \n# se eliminan siguiendo una política conocida como FIFO, \n# que significa \"First In, First Out\" (primero en entrar, primero en salir).\n#\n# 2. Imagina una cola en una tienda: \n# La persona que llega primero es la primera en ser atendida.\n# \n# 3. En Python, puedes implementar una cola utilizando la clase `deque` \n# del módulo `collections`. Puedes añadir elementos a la cola usando \n# el método `append()` y eliminar elementos usando el método `popleft()`.\n\n\n# Ejercicio\nimport time\nimport random\nfrom collections import  deque\n\ndef ejercicio():\n    stack_lifo = []\n    print(f'\\n[+] Modificando elementos de la pila:')\n    print(f'\\n[+] Contenido de la pila {stack_lifo}')\n\n    for i in range(1,6):\n        stack_lifo.append(f'item_{i}')\n        print(f'\\n[+] Añadido un elemento al stack_LIFO')\n        print(f'[+] Contenido de la pila {stack_lifo}')\n        time.sleep(0.3)\n\n    for i in range(0, len(stack_lifo)):\n        stack_lifo.pop()\n        print(f'\\n[+] Eliminado un elemento al stack_LIFO')\n        print(f'[+] Contenido de la pila {stack_lifo}')\n        time.sleep(0.3)\n\n    stack_fifo = deque()\n\n    for i in range(1,6):\n        stack_fifo.append(f'item_{i}')\n        print(f'\\n[+] Añadido un elemento al stack_FIFO')\n        print(f'[+] Contenido de la pila {stack_fifo}')\n        time.sleep(0.3)\n\n    for i in range(0, len(stack_fifo)):\n        stack_fifo.popleft()\n        print(f'\\n[+] Eliminado un elemento al stack_FIFO')\n        print(f'[+] Contenido de la pila {stack_fifo}')\n        time.sleep(0.3)\n\n\n# Ejercicios Extra\n\nweb_history = []\nurl_anterior = ''\nurl_actual = ''\nurl_posterior = ''\n\ndef adelante(url):\n    global url_actual\n    global url_posterior\n    global url_anterior\n    \n    if not url_posterior:\n        print(f'[i] Se encuentra en el final')\n    else:\n        if url_anterior:\n            url_anterior.append(web_history)\n        url_anterior=url_actual\n        url_actual=url_posterior\n        url_posterior=''\n\ndef atras(url):\n    global url_actual\n    global url_posterior\n    global url_anterior\n    \n    if not url_anterior:\n        print(f'[i] No existe una URL anterior')\n    else:\n        url_posterior=url_actual\n        url_actual=url_anterior\n        if len(web_history) > 0:\n            url_anterior=web_history.pop()\n        else:\n            url_anterior=''\n\n\ndef navegar(url):\n    global url_actual\n    global url_anterior\n    if  url_actual and url_anterior:\n        web_history.append(url_anterior)\n    url_anterior = url_actual\n    url_actual = url\n\n    print(f'[+] Navegar: {url}')\n\ndef navegando():\n    while True:\n        user_intput = input(\"\\nIngrese 'adelante', 'atras' o la URL de una nueva página:\\n\")\n        if user_intput.lower() == \"adelante\":\n            adelante(user_intput)\n        elif user_intput.lower() == \"atras\":\n            atras(user_intput)\n        else:\n            navegar(user_intput)\n        \n        print(f'\\n[i] Informacion. ')\n        print(f'[i] Historial: {web_history}')\n        print(f'[i] Url_Anterior: {url_anterior}')\n        print(f'[i] Url_Actual: {url_actual}')\n        print(f'[i] Url_posterior: {url_posterior}')\n\n\n\n# Ejercicio Extra 2\n\ndef impresora(cola_impresion):\n    cont = 0\n    imprimir = False\n    while True:\n        if not imprimir:\n            documento = f'{cont}.txt'\n            cola_impresion.append(documento)\n            print(f'\\n[i] Añadido documento {documento} a la cola de impresión')\n            print(f'[i] Archivos en cola: {cola_impresion}\\n\\n') \n            time.sleep(0.5)\n            if len(cola_impresion) > 3:\n                imprimir = True\n            else:\n                num = random.randint(1, 5)\n                if num % 2 != 0:\n                    imprimir = True\n            cont += 1\n        else:\n            try:\n                print(f'[i] Imprimiendo {cola_impresion.popleft()}...')\n            except IndexError:\n                print('[i] No hay documentos en la cola para imprimir')\n            imprimir = False\n\n# Ejecucion de los ejercicios.\n#ejercicio()\n#navegando()\ncola_impresion = deque()\nimpresora(cola_impresion)\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/majinka10.py",
    "content": "lista = [3, 2]\nprint(f\"Tratamiento de una lista: {lista} como pila\")\nlista.append(4)\nprint(f\"Añadiendo al final de la pila: {lista}\")\nlista.pop()\nprint(f\"Eliminando el último elemento que entró: {lista}\")\n\nprint(f\"Tratamiento de una lista: {lista} como cola\")\nlista.append(6)\nprint(f\"Añadiendo al final de la cola: {lista}\")\nlista.pop(0)\nprint(f\"Eliminando el primer elemento de la cola: {lista}\")\n\n# Ejercicio EXTRA\nprint(\"\\nEjercicio de navegación en la web.\\n\")\ndef navegacion():\n    webs = []\n    index = 0\n    while True:\n        accion = input('Qué acción quieres relizar: \\n - \"Adelante\" para avanzar \\n - \"Atras\" para retroceder \\n - Nombre de la web a la que quieres acceder \\n - Salir para finalizar la navegación \\n').lower()\n        match accion:\n            case 'adelante':\n                if index < len(webs):\n                    index += 1\n                    print(f\"Estás en {webs[index-1]}\")\n                else:\n                    print(\"No hay nada más adelante.\")\n            case 'atras':\n                if index > 1:\n                    index -= 1\n                    print(f\"Estás en {webs[index-1]}\")\n                else:\n                    print(\"No hay nada más atras.\")\n            case 'salir':\n                print(\"Adiós.\")\n                break\n            case _:\n                webs.append(accion)\n                index = len(webs)\n                print(f\"Estás en {accion}\")\n\nnavegacion()\n            \nprint(\"\\nEjercicio de la impresora\\n\")\n\ndef imprimir():\n    lista = []\n    while True:\n        accion = input(\"Qué quieres realizar: \\n - 'Imprimir' para retirar el primer elemento de la cola. \\n - Agrega un documento escribiendo su nombre. \\n - 'Terminar' para salir. \\n\").lower()\n        match accion:\n            case 'imprimir':\n                if len(lista) < 1:\n                    print(\"No hay elementos para imprimir.\")\n                else:\n                    elemento = lista.pop(0)\n                    print(f\"Se ha impreso el documento {elemento}\")\n            case 'terminar':\n                break\n            case _:\n                lista.append(accion)\n\nimprimir()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/manjaitan.py",
    "content": "'''\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n '''\n\n# añadimos elementos a una pila1.\n\npila1 = []\npila1.append(1)\nprint (pila1)\npila1.append(2)\nprint (pila1)\npila1.append(3)\nprint (pila1)\n\n# retiramos elentos de la pila con el metodo pop\n\npila1.pop()\nprint (pila1)\npila1.pop()\nprint (pila1)\npila1.pop()\n\n# Añadimos elementos de nuevo a la pila.,\n\npila1.append(4)\npila1.append(5)\npila1.append(6)\n\nprint (pila1)\n\n\n# Sale el primero que entra, FIFO.\n\npila1.pop(0)\nprint (pila1) # Desaparece de la pila el 4.\n\n### EXTRA ####\n\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/mariovelascodev.py",
    "content": "#LIFO último en entrar primero en salir\ndef stacks(arg1, arg2, arg3, arg4):\n    stack = []\n\n    #Añaden valores a la pila\n    stack.append(arg1)\n    stack.append(arg2)\n    stack.append(arg3)\n    stack.append(arg4)\n    \n    print(f\"Pila de cosas a hacer durante el día {stack}\")\n    \n    print(f\"Último elemento en entrar {stack[len(stack)-1]}\")\n    \n    print(f\"Primer elemento en salir {stack.pop()}\")\n    print(f\"Pila de cosas a hacer {stack}\")\n\nstacks(\"Pintar\", \"Comer\", \"Ver Tv\", \"Dormir\")\n\n#FIFO Primero en entrar, primero en salir\ndef queue(arg1, arg2, arg3):\n    queue = []\n    queue.append(arg1)\n    queue.append(arg2)\n    queue.append(arg3)\n    \n    print(f\"Lista de tareas a realizar: {queue}\")\n    \n    print(f\"Primera tarea de la lista: {queue[0]}\")\n    \n    print(f\"Terminada la primera tarea de la lista se elimina de ella: {queue.pop(0)}\")\n    \n    print(f\"Lista de tareas a realizar: {queue}\")\n\n\nqueue(\"Desayunar\", \"Estudiar\", \"Hacer ejercicio\")\n\n#EXTRA\nprint(\"---------------------\")\n\ndef simulation_web():\n    browser_web = []\n    forward = []\n    status = True\n\n    while status:\n        order = input(\"Indica el nombre del sitio web, adelante, atras o salir: \")\n\n        #Comparamos la orden introducida por consola\n        if order.lower() == \"adelante\":\n            #Si browser_web esta vacia abre nueva pestaña e introducimos el nombre del sitio web y lo almacena en la lista browser_web\n            if len(browser_web) == 0:\n                print(\"Nueva Pestaña\")\n                web_name = input(\"Indique el nombre del sitio web a acceder: \")\n                browser_web.append(web_name)\n                print(f\"Estas en el sitio web -> {browser_web[len(browser_web) - 1]}\")\n            #Si la lista forward no esta vacia mostrará el último resultado de la lista que hace de historial y añade el valor a browser_web\n            elif len(forward) > 0:\n                print(f\"Estas en el sitio web -> {forward[len(forward) - 1]}\")\n                browser_web.append(forward[len(forward) - 1])\n                forward.pop()\n            #Si no muestra la posición actual de la lista browser_web\n            else:\n                print(f\"Estas en el sitio web -> {browser_web[len(browser_web) - 1]}\")\n        elif order.lower() == \"atras\":\n            #Si browser_web es mayor que 1 borramos el último valor de la lista y la añadimos a la lista forward y se muestra la última posición de browser_web\n            if len(browser_web) > 1:\n                back = browser_web.pop()\n                forward.append(back)\n                print(f\"Estas en el sitio web -> {browser_web[len(browser_web) - 1]}\")\n            #Si no indicamos que el historial está vacio\n            else: \n                print(\"El historial esta vacio, no se puede retroceder\")\n                print(f\"adelante {forward}\")\n        elif order.lower() == \"salir\":\n            print(\"Cerrando el navegador\")\n            status = False\n        else:\n            browser_web.append(order)\n            print(f\"Estas en el sitio web -> {browser_web[len(browser_web) - 1]}\")\n\n\nsimulation_web()\n\ndef printer():\n    queue_printer = []\n    status = True\n\n    while status:\n        order = input(\"Indica el nombre del fichero ha añadir a la cola de impresion, imprimir o salir: \")\n        #Si indicamos que queremos imprimir comprobamos que la lista no este vacia, si es así lo indicamos y se vuelve a pedir la orden anterior\n        #Si la lista no esta vacia se muestra la impresión de los documentos y cuando se finaliza se limpia la cola de impresión\n        if order.lower() == \"imprimir\":\n            if len(queue_printer) == 0:\n                print(\"No hay documentos a imprimir\")\n            else:    \n                for i in queue_printer:\n                    print (f\"Imprimiendo el documento imprimir {i}\")\n                queue_printer.clear()\n        #Si indicamos que queremos salir, se muestra un mensaje que indica que se esta cerrando el programa y cambiamos la variable status para que no pida mas instruciones        \n        elif order.lower() == \"salir\":\n            print(\"Cerrando programa de cola de impresión...\")\n            status = False\n        #Si no se indica que deseamos imprimir o salir, lo introducido por comando se añade a la cola de impresión    \n        else:\n            queue_printer.append(order)\n\nprinter()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/mensius87.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atras\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n\"\"\"\n\n\n# FIFO - First In First Out\nlista_fifo = []\n\ndef introducir_elemento(elem):\n    lista_fifo.append(elem)\n    print(lista_fifo)\n\n\ndef sacar_elemento():\n    elem_sacado = lista_fifo.pop(0)\n    print(f\"Elemento eliminado: {elem_sacado}\")\n\n\nprint(\"\"\"\n    Opciones:\n        1 - Añadir elemento a la pila\n        2 - Ver pila\n        3 - Ver próximo elemento en salir\n        4 - Sacar elemento de la pila\n        5 - Salir\n\"\"\")\n\nopcion_elegida = input(\"Elige una opción: \")\n\nwhile opcion_elegida != '5':\n    match opcion_elegida:\n        case '1':\n            elem = input(\"Introduce un elemento: \")\n            introducir_elemento(elem)\n        case '2':\n            print(\"Pila:\", lista_fifo)\n        case '3':\n            if lista_fifo:\n                print(\"Próximo elemento en salir:\", lista_fifo[0])\n            else:\n                print(\"La pila está vacía.\")\n        case '4':\n            sacar_elemento()\n        case '5':\n            print(\"Gracias por usar la pila.\")\n            break\n        case _:\n            print(\"Opción no válida.\")\n\n    opcion_elegida = input(\"Elige una opción: \")\n\n\n# LIFO - Last In First Out\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/mhayhem.py",
    "content": "from time import sleep\n# EJERCICIO:\n# Implementa los mecanismos de introducción y recuperación de elementos propios de las\n# pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n# o lista (dependiendo de las posibilidades de tu lenguaje).\n\ndef diswaserh():\n    dishes = []\n    while len(dishes) < 5:\n            dish = input()\n            dishes.append(dish)\n    print(dishes)\n    while len(dishes) >= 5:\n        cleaner = dishes.pop()\n        print(cleaner)\n    print(\"Todos los platos límpios, pila vacía\")\n    \ndef queue():\n    queue = []\n    while len(queue) < 5:\n        action = input()\n        queue.append(action)\n    print(action)\n    while len(queue) > 0:\n        action_taken = queue[0]\n        print(action_taken)\n        sleep(0.2)\n        queue.remove(action_taken)\n        \n    print(\"Todas las acciónes realizadas, cola vacía\")\n    \n# DIFICULTAD EXTRA (opcional):\n# - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n#   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n#   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n#   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n#   el nombre de una nueva web.\n\ndef brave():\n   foward_stack = []\n   back_stack = []\n   current = input(\"Introduzca una pagina web.\\n\").strip().lower()\n   while True:\n       print(f\"http://{current}\")\n       action = input(\"Nueva pagina o comandos 'adelante' o 'atras': 'X' para cerrar.\\n\").strip().lower()\n       match action:\n            case \"x\":\n               break\n            case \"atras\":\n               if back_stack:\n                   foward_stack.append(current)\n                   current = back_stack.pop()\n               else:\n                   print(\"No se puede retroceder.\")\n            case \"adelante\":\n                if foward_stack:\n                    back_stack.append(current)\n                    actual = foward_stack.pop()\n                else:\n                    print(\"No se puede avanzar.\")\n            case _:\n                back_stack.append(current)\n                current = action\n                foward_stack.clear()\n\nbrave()                    \n\n# - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n#   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n#   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n#   interpretan como nombres de documentos.\n\ndef printer():\n    queue_print = []\n    while True:\n        action = input(\"Quiere 'imprimir' archivo o crear nuevo archivo? pulsar 'X' para cerrar prógrama.\\n\").strip().lower()\n        match action:\n            case \"imprimir\":\n                if (len(queue_print)) < 1:    \n                    print(\"No hay archivos que imprimir\")\n                else:\n                    printed = queue_print[0]\n                    queue_print.pop(0)\n                    print(f\"Archivo {printed} Imprimiendose\")\n            case \"x\":\n                break\n            case _:\n                queue_print.append(action)\n        print(f\"Archivos en cola: {len(queue_print)}\")\n\nprinter()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/miguelex.py",
    "content": "pila = []\n\npila.append(3)\npila.append(2)\npila.append(1)\n\nprint(\"Mostramos la pila\")\nprint(pila)\n\npila.pop()\n\nprint(\"Mostramos la pila tras sacar el elemento en la parte superior\")\nprint(pila)\n\n\ncola = []\n\ncola.append(1)\ncola.append(2)\ncola.append(3)\n\nprint(\"Mostramos la cola\")\nprint(cola)\n\ncola.pop(0)\n\nprint(\"Mostramos la cola tras sacar el elemento en la parte inferior\")\nprint(cola)\n\n\n# Extra\n\npila = []\n\nwhile True:\n    \n    action = input(\n        \"Añade url/adelante/atras/salir: \"\n    )\n\n    if action == \"salir\":\n        print(\"Saliendo del navegador web.\")\n        break\n    elif action == \"adelante\":\n        pass\n    elif action == \"atras\":\n        if len(pila) > 0:\n            pila.pop()\n    else:\n        pila.append(action)\n\n    if len(pila) > 0:\n        print(f\"Has navegado a la web: {pila[len(pila) - 1]}.\")\n    else:\n        print(\"Estás en la página de inicio.\")\n\n\ncola = []\n\nwhile True:\n        \n        action = input(\"Nombre del documento/imprimir/salir: \")\n\n        if action == \"salir\":\n            break\n        elif action == \"imprimir\":\n            if len(cola) > 0:\n                print(f\"Imprimiendo: {cola.pop(0)}\")\n        else:\n            cola.append(action)\n\n        print(f\"Cola de impresión: {cola}\")"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/mikelm2020.py",
    "content": "# operaciones: introduce - introducir  recover - recuperar\n\n\nclass Stack:\n    def __init__(self):\n        # Crea una pila vacía\n        self.items = []\n\n    def introduce(self, element):\n        # Agrega el elemento element a la pila\n        self.items.append(element)\n\n    def recover(self):\n        # Devuelve el elemento tope y lo elimina\n        # Si la pila está vacía levanta una excepción\n        try:\n            return self.items.pop()\n        except IndexError:\n            raise ValueError(\"La pila está vacía\")\n\n    def is_empty(self):\n        # Devuelve True si la pila esta vacía\n        return self.items == []\n\n    def size(self):\n        return len(self.items)\n\n\nclass Queue:\n    def __init__(self):\n        # Crea una cola vacía\n        self.items = []\n\n    def introduce(self, element):\n        # Agrega el elemento element a la cola\n        self.items.append(element)\n\n    def recover(self):\n        # Devuelve el primer elemento y lo elimina\n        # Si la cola está vacía levanta una excepción\n        try:\n            return self.items.pop(0)\n        except IndexError:\n            raise ValueError(\"La cola está vacía\")\n\n    def is_empty(self):\n        # Devuelve True si la cola esta vacía\n        return self.items == []\n\n\ndef web_navigation():\n    navigation = Stack()\n\n    while True:\n        action_of_navigate = input(\n            \"Escribe la URL o las palabras atras, adelante o salir\"\n        )\n\n        if action_of_navigate == \"adelante\":\n            pass\n        elif action_of_navigate == \"atras\":\n            if not navigation.is_empty():\n                if navigation.size() > 1:\n                    page = navigation.recover()\n                else:\n                    page = navigation.items[0]\n        elif action_of_navigate == \"salir\":\n            break\n        else:\n            navigation.introduce(action_of_navigate)\n            page = navigation.items\n\n        if not navigation.is_empty():\n            print(f\"Estas en {page}\")\n\n\ndef shared_printing():\n    printing_queue = Queue()\n\n    while True:\n        action = input(\"Añade un documento o escribe imprimir/salir: \")\n\n        if action == \"salir\":\n            break\n        elif action == \"imprimir\":\n            if not printing_queue.is_empty():\n                print(f\"Imprimiendo el documento {printing_queue.recover()}\")\n        else:\n            printing_queue.introduce(action)\n\n        print(f\"La cola de impresión restante es: {printing_queue.items}\")\n\n\nif __name__ == \"__main__\":\n    # web_navigation()\n    shared_printing()\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/monicavaquerano.py",
    "content": "# 07 PILAS Y COLAS\n# Monica Vaquerano\n# https://monicavaquerano.dev\n\n\"\"\"\nEJERCICIO:\nImplementa los mecanismos de introducción y recuperación de elementos propios de las\npilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\no lista (dependiendo de las posibilidades de tu lenguaje).\n\"\"\"\nimport os, time\n\n\nprint(\"07 PILAS Y COLAS\\n\")\n\n# Pilas (Stacks):\n# Una pila es una estructura de datos en la que el último elemento añadido es el primero en ser eliminado (LIFO - Last In, First Out).\n# Puedes implementar una pila fácilmente en Python utilizando una lista.\nprint(\"* Pilas (Stacks)\")\nprint(\"- LIFO - Last In, First Out\")\nstack = []\nprint(\"Pila (stack) inicial =>\", stack)\nstack.append(1)\nstack.append(2)\nstack.append(3)\nprint(f\"Pila (stack) después de varios appends: stack.append(x) => {stack}\")\npopped = stack.pop()\nprint(f\"Último elemento de la pila (stack) eliminado: stack.pop() => {popped}\")\nprint(f\"Pila (stack) después de eliminar el último elemento => {stack}\\n\")\n\n# Colas (Queues):\n# Una cola es una estructura de datos en la que el primer elemento añadido es el primero en ser eliminado (FIFO - First In, First Out).\n# Para implementar una cola en Python, puedes utilizar la biblioteca collections que proporciona la clase deque.\nprint(\"* Colas (Queues)\")\nprint(\"- FIFO - First In, First Out\")\nqueue = []\nprint(\"Cola (queue) inicial =>\", queue)\nqueue.append(\"a\")\nqueue.append(\"b\")\nqueue.append(\"c\")\nprint(f\"Cola (queue) después de varios appends: queue.append(x) => {queue}\")\npopFirst = queue.pop(0)\nprint(f\"Último elemento de la cola (queue) eliminado: queue.pop(0) => {popFirst}\")\nprint(f\"Cola (queue) después de eliminar el primer elemento => {queue}\\n\")\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n- Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\nde un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\nque te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\nLas palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\nel nombre de una nueva web.\n\"\"\"\n\nhistory = [\"test1.com\", \"test2.com\", \"test3.com\", \"test4.com\"]\nlasts = []\n\n\ndef web_navigation():\n    while True:\n        os.system(\"clear\")\n        print(\"--- Web navigation ---\")\n\n        numb = len(history) - 1\n\n        if numb < 0:\n            print(\"\\nHome Page\\n\")\n        else:\n            print(\"\\n\", \"https://\", history[numb], \"\\n\")\n\n        choice = input(\"1. Ir a...\\n2. Atrás\\n3. Avanzar\\n4. Salir\\n> \").strip()\n\n        if choice == \"1\":\n            web = input(\"Enter web page: > \").strip().lower()\n            history.append(web)\n        elif choice == \"2\":\n            if numb >= 0:\n                last = history.pop()\n                lasts.append(last)\n        elif choice == \"3\":\n            if lasts:\n                history.append(lasts.pop())\n            else:\n                print(\"\\nYou reached the last page\\n\")\n                time.sleep(1)\n        elif choice == \"4\":\n            break\n\n\n\"\"\"\n- Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\nimpresora compartida que recibe documentos y los imprime cuando así se le indica.\nLa palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\ninterpretan como nombres de documentos.\n\"\"\"\ncola = [\"doc1\", \"doc2\", \"doc3\", \"doc4\"]\n\n\ndef shared_printer():\n    while True:\n        os.system(\"clear\")\n        print(\"--- Impresora Compartida ---\")\n        choice = (\n            input(\"\\n1. Imprimir\\n2. Añadir\\n3. Ver Cola\\n4. Salir\\n> \").strip().lower()\n        )\n        if choice == \"1\" or choice == \"imprimir\":\n            os.system(\"clear\")\n            print(\"--- Documento Impreso ---\\n\")\n            if cola:\n                firstDoc = cola.pop(0)\n\n                print(f\"\\t{firstDoc}\")\n            else:\n                print(\"No hay documentos en la cola\")\n            time.sleep(2)\n        elif choice == \"2\" or choice == \"añadir\":\n            os.system(\"clear\")\n            print(\"--- Añadir Documento ---\\n\")\n            document = input(\"Añadir documento: > \").strip().lower()\n            cola.append(document)\n            print(\"\\nDocumento añadido\")\n            time.sleep(1)\n        elif choice == \"3\" or choice == \"ver\":\n            os.system(\"clear\")\n            print(\"--- Cola de documentos ---\\n\")\n            if cola:\n                print(\n                    f\"Próximo a imprimir: {cola[0]}\\nSiguientes: {', '.join(cola[1:])}\\n\",\n                )\n            else:\n                print(\"No hay documentos en la cola\")\n            time.sleep(4)\n        elif choice == \"4\" or choice == \"salir\":\n            break\n\n\nwhile True:\n    print(\"DIFICULTAD EXTRA (opcional)\")\n    choice = input(\n        \"Escoge la función:\\n1. Web Navigation (pila)\\n2. Shared Printer (cola)\\n3. Exit\\n> \"\n    )\n    if choice == \"1\":\n        web_navigation()\n    elif choice == \"2\":\n        shared_printer()\n    elif choice == \"3\":\n        break\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/mordevspt.py",
    "content": "\"\"\"\nImplementa los mecanismos de introducción y recuperación de elementos propios de las\npilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\no lista (dependiendo de las posibilidades de tu lenguaje).\n\"\"\"\n\n'''\nLIFO\n'''\nprint(\"\\nLIFO\\n\")\n\n# LIST\nprint(\"\\nLISTA\\n\")\n\nmi_list_stack = []\n\n# Añadimos elementos a la pila, usamos el métdo que tenemos en las listas => append() \n# como si fuera la function push\nmi_list_stack.append(\"Hola\")\nmi_list_stack.append(\"Python\")\nmi_list_stack.append(\"!\")\n\nprint(\"\\nPila rellenada\\n\")\nprint(mi_list_stack)\n\n# Usamos pop() para eliminar e último elemento introducido => LIFO\nprint(\"\\nBorrado de elementos de la pila:\\n\")\nprint(mi_list_stack.pop())\nprint(mi_list_stack.pop())\nprint(mi_list_stack.pop())\n\nprint('\\nTras el borrado de elementos de la pila:')\nprint(mi_list_stack)\n\n# QUEUE MODULE\nprint(\"\\nQUEUE MODULE\\n\")\n\nfrom queue import LifoQueue\n\n# Inicializamos el stack con un tamaño máximo\nstack = LifoQueue(maxsize=3)\n\n# Con la función qsize() vemos el número de elementos\n# que tiene la pila\nprint(stack.qsize())\n\n# Hacemos uso de la función put() para hacer el push\nstack.put(\"Hola\")\nstack.put(\"Python\")\nstack.put(\"!\")\n\nprint(\"\\nPila rellenada\\n\")\nprint(\"Lleno: \", stack.full())\nprint(\"Tamaño: \", stack.qsize())\n\n# Hacemos uso de la función get() para hacer pop => LIFO\nprint('\\nBorrado de elementos de la pila:\\n')\nprint(stack.get())\nprint(stack.get())\nprint(stack.get())\n\nprint(\"\\nVaciar: \", stack.empty())\n\n# NODE CLASS\nprint(\"\\nNODE CLASS\\n\")\n\n# Class Node\nclass Node:\n    def __init__(self, value):\n      self.value = value\n      self.next = None\n\n# Class Stack\nclass Stack:\n\n    # Inicializamos una pila haciendo uso de un \n    # modo ficticio, que es más sencillo de\n    # manejar en casos extremos\n    def __init__(self):\n      self.head = Node(\"head\")\n      self.size = 0\n\n    # Representación de un String en la pila\n    def __str__(self):\n      cur = self.head.next\n      out = \"\"\n      while cur:\n          out += str(cur.value) + \"->\"\n          cur = cur.next\n      return out[:-2]\n\n    # Obtener el tamaño actual de la pila\n    def getSize(self):\n      return self.size\n\n    # Comprobar si la pila está vacía\n    def isEmpty(self):\n      return self.size == 0\n\n    # Obtener el elemento superior de la pila por medio de peek\n    def peek(self):\n      #  Comprobación para ver si estamos viendo una pila vacía\n      if self.isEmpty():\n          return None\n      return self.head.next.value\n\n    # Introducir un valor en la pila por medio de push\n    def push(self, value):\n      node = Node(value)\n      node.next = self.head.next # Make the new node point to the current head\n      self.head.next = node #!!! # Update the head to be the new node\n      self.size += 1\n\n    # Elimina un valor de la pila por medio de pop y lo devuelve.\n    def pop(self):\n      # Comprobamos que la pila no esté vacía \n      if self.isEmpty():\n          raise Exception(\"Eliminando desde una pila vacía\")\n      remove = self.head.next\n      self.head.next = remove.next #!!! changed\n      self.size -= 1\n      return remove.value\n\n# Ejecución\n\n# Creamos una instancia de la pila\nstack = Stack()\n\n# Introducimos varios valores creados desde un bucle for\nfor i in range(1, 11):\n    stack.push(i)\n\n# Imprimimos la pila tras el rellenado\nprint(\"\\nPila rellenada\\n\")\nprint(stack)\n\n# Eliminamos varios valores pasados desde un bucle for\nprint(\"\\nBorrado de elementos de la pila:\\n\")\nfor _ in range(1, 6):\n    top_value = stack.pop()\n    print(f\"Eliminado: {top_value}\") # variable name changed\n\n# Imprimimos la pila tras el borrado\nprint('\\nTras el borrado de elementos de la pila\\n:')\nprint(stack)\n\n'''\nFIFO\n'''\nprint(\"\\nFIFO\\n\")\n\n# Creamos una lista a modo de Queue\n\nq = []\n\n# Añadimos varios elementos, por ejemplo desde un for\n# a nuestra Queue\nfor i in range(5):\n\tq.append(i)\n\n# Mostramos el contenido de l Queue una vez rellenada\nprint(\"Elementos en la Queue: \" , q)\n\n# Al eliminar elementos, lo hacemos por el primer\n# elemento en la cola, es decir, índice 0\nremovedele = q.pop(0)\nprint(\"Elmento eliminado: \" , removedele)\n\nprint(q)\n\n# Mostrar el elemento en cabeza en la Queue\nhead = q[0]\nprint(\"Primer elemento (Head) en la Queue:\" , head)\n\n# Tamaño de la Queue, es decir, el número\n# de elementos que la forman\nsize = len(q)\nprint(\"Tamaño de la Queue: \" , size)\n\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n\"\"\"\n\n\"\"\"\n- Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n  de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n  que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n  Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n  el nombre de una nueva web.\n\"\"\"\n\n# EJERCICIO 1\n# Usaremos LIFO\nprint(\"\\nEJERCICIO 1 - CON ADELANTE (COMO LISTA)\\n\")\n\n# Nuestra pila\nmi_list = []\n\n# Posición inicial\nposicion_pila = 0\n\n# Pregunta inicial\ndef preguntarAlUsuario(position = 0):\n  return input(\"Escribe una página a navegar o navega Adelante (adelante) o Atrás (atras): \")\n\n# Respuesta Atrás\ndef goAfter(position):\n  if position <= 0:\n    print(\"Ha llegado al principio\")\n    position = 0\n  elif position > 0:\n    position -= 1\n  # Sea lo que sea lo devolvemos\n  return position\n\n# Respuesta Adelante\ndef goBefore(position):\n  if position == (len(mi_list) - 1):\n    print(\"Ha llegado al final\")\n    position = (len(mi_list) - 1)\n  elif position < (len(mi_list) - 1):\n    position += 1\n  # Sea lo que sea lo devolvemos\n  return position\n\n# Navegación\ndef showWebSite(position):\n  print(f\"Navegando por la web: {mi_list[position]}\")\n\n# Programa inicial\ndef navegacion():\n  respuesta = preguntarAlUsuario() \n  while True:\n    match respuesta:\n      case \"atras\":\n        # Comprobamos\n        if len(mi_list) == 0:\n          print(\"No hay más registros\")\n          respuesta = preguntarAlUsuario()\n        else:\n          posicion_pila = goAfter(posicion_pila)\n          showWebSite(posicion_pila)\n          respuesta = preguntarAlUsuario()\n          \n      case \"adelante\":\n        # Comprobamos\n        if len(mi_list) == 0:\n          print(\"No hay más registros\")\n          respuesta = preguntarAlUsuario()\n        else:\n          posicion_pila = goBefore(posicion_pila)\n          showWebSite(posicion_pila)\n          respuesta = preguntarAlUsuario()\n      case \"salir\":\n        print(\"\\n¡HASTA LUEGO!\\n\")\n        break\n      case _:\n        if len(respuesta) >= 1:\n          mi_list.append(respuesta)\n          posicion_pila = mi_list.index(respuesta)\n          showWebSite(posicion_pila)\n        else:\n          print(\"Escriba una palabra u opción.\")\n        # Pase lo que pase\n        respuesta = preguntarAlUsuario()\n\n# Ejecución programa 1\nnavegacion()\n\nprint(\"\\nEJERCICIO 1 - SIN ADELANTE (COMO PILA)\\n\")\n\n# Nuestra pila\nmi_stack = []\n\n# Navegación\ndef showWebSiteUser(position):\n  print(f\"Navegando por la web: {mi_stack[position]}\")\n\n# Programa Inicial\ndef navegacionWeb():\n  respuesta = preguntarAlUsuario()\n  while True:\n    match respuesta:\n      case \"atras\":\n        if len(mi_stack) >= 1:\n          # Eliminamos el último registro\n          mi_stack.pop()\n          # Para no provocar un problema en caso de no quedar elementos en la pila\n          if (len(mi_stack) > 0):\n            showWebSiteUser(len(mi_stack)-1)\n          else:\n            print(\"Ha llegado al principio\")\n        # Pase lo que pase\n        \n        respuesta = preguntarAlUsuario()\n      case \"adelante\":\n        print(\"No es posible\")\n        respuesta = preguntarAlUsuario()\n      case \"salir\":\n        print(\"\\n¡HASTA LUEGO!\\n\")\n        break\n      case _:\n        if len(respuesta) >= 1:\n          mi_stack.append(respuesta)\n          showWebSiteUser(len(mi_stack)-1)\n        # Pase lo que pase\n        respuesta = preguntarAlUsuario()\n\n# Ejecución programa 1\nnavegacionWeb()\n\n\"\"\"\n- Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n  impresora compartida que recibe documentos y los imprime cuando así se le indica.\n  La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n  interpretan como nombres de documentos.\n\"\"\"\n\n# EJERCICIO 2\n# Usaremos FIFO\nprint(\"\\nEJERCICIO 2\\n\")\n\n# Nuestra pila\npool = []\n\n# Pregunta inicial\ndef preguntarAlUsuarioPool():\n  return input(\"Escribe si deseas imprimir (imprimir) o agrega a la cola de impresión: \")\n\n# Programa inicial\ndef poolPrinter():\n  respuestaUsuario = preguntarAlUsuarioPool()\n  while True:\n    match respuestaUsuario:\n      case \"imprimir\":\n        # Comprobamos\n        if len(pool) == 0:\n          print(\"No hay documentos en la cola de impresión, agregue uno antes\")\n          respuestaUsuario = preguntarAlUsuarioPool()\n        else:\n          print(f\"Imprimimos el documento {pool[0]}\")\n          pool.pop(0)\n          respuestaUsuario = preguntarAlUsuarioPool()\n      case \"salir\":\n        print(\"\\n¡HASTA LUEGO!\\n\")\n        break\n      case _:\n        if len(respuestaUsuario) >= 1:\n          pool.append(respuestaUsuario)\n          print(f\"Agregamos el documento {respuestaUsuario} a la cola de impresión\")\n        else:\n          print(\"Escriba el nombre de un documento o si desea imprimir\")\n        # Pase lo que pase\n        respuestaUsuario = preguntarAlUsuarioPool()\n\n# Ejecución programa 2\npoolPrinter()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/mouredev.py",
    "content": "\"\"\"\nEjercicio\n\"\"\"\n\n# Pila/Stack (LIFO)\n\nstack = []\n\n# push\nstack.append(1)\nstack.append(2)\nstack.append(3)\nprint(stack)\n\n# pop\nstack_item = stack[len(stack) - 1]\ndel stack[len(stack) - 1]\nprint(stack_item)\n\nprint(stack.pop())\n\nprint(stack)\n\n# Cola/Queue (FIFO)\n\nqueue = []\n\n# enqueue\nqueue.append(1)\nqueue.append(2)\nqueue.append(3)\n\nprint(queue)\n\n# dequeue\nqueue_item = queue[0]\ndel queue[0]\nprint(queue_item)\n\nprint(queue.pop(0))\n\nprint(queue)\n\n\"\"\"\nExtra\n\"\"\"\n\n# Web\n\n\ndef web_navigation():\n\n    stack = []\n\n    while True:\n\n        action = input(\n            \"Añade una url o interactúa con palabras adelante/atrás/salir: \"\n        )\n\n        if action == \"salir\":\n            print(\"Saliendo del navegador web.\")\n            break\n        elif action == \"adelante\":\n            pass\n        elif action == \"atrás\":\n            if len(stack) > 0:\n                stack.pop()\n        else:\n            stack.append(action)\n\n        if len(stack) > 0:\n            print(f\"Has navegado a la web: {stack[len(stack) - 1]}.\")\n        else:\n            print(\"Estás en la página de inicio.\")\n\n\nweb_navigation()\n\n\ndef shared_printed():\n\n    queue = []\n\n    while True:\n\n        action = input(\"Añade un documento o selecciona imprimir/salir: \")\n\n        if action == \"salir\":\n            break\n        elif action == \"imprimir\":\n            if len(queue) > 0:\n                print(f\"Imprimiendo: {queue.pop(0)}\")\n        else:\n            queue.append(action)\n\n        print(f\"Cola de impresión: {queue}\")\n\n\nshared_printed()\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/mrodara.py",
    "content": "#################### PILAS Y COLAS #########################\n\n## PILAS\nmy_stack = [i for i in range(1,11)]\n\nprint(my_stack)\n\n# Añadir un elemento a la pila\nmy_stack.append(11)\nprint(my_stack)\n\n# Eliminar una elemento de la pila\nmy_stack.pop()\n\nprint(my_stack)\n\n# Obtención del elemento correspondiente a procesar en una pila\nprint(my_stack[len(my_stack) - 1])\n\n# Simulación de los procesos de una pila\nfor proccess in my_stack[::-1]:\n    print(f\"Procesando el proceso {proccess}\")\n\nprint(\"La pila de procesos ha finalizado\")\n\n## FIN PILAS\n\n## COLAS (FIFO)\n\nmy_queue = [i for i in range(1, 11)]\nprint(my_queue)\n\n# Inserción de un elemento en la cola\nmy_queue.append(11)\n\nprint(my_queue)\n\n# Extracción de un elemento de la cola\nmy_queue.pop(0)\n\nprint(my_queue)\n\n# Procesando todos los elementos de una cola\nfor proccess in my_queue:\n    print(f\"Procesando el proceso {proccess}\")\nprint(\"La pila de procesos ha finalizado\")\n\n## FIN COLAS\n\n#################### FIN PILAS Y COLAS #########################\n\n\n#################### EXTRA #########################\n\n# Implementación navegador web\nmy_websites = [\"blank page\", \"www.marca.com\", \"www.as.com\", \"www.elmundo.es\"]\nposition = 0\nend = False\nwhile not end:\n    action = input(\"Indica que quieres realizar (adelante/atras/web): \")\n    if action.lower() == \"atras\":\n        print(f'Navegando a {my_websites[position-1] if position > 0 else my_websites[0]}')\n        position -= 1 if position > 0  else 0\n    elif action.lower() == \"adelante\":\n        print(f'Navegando a {my_websites[position+1] if position < len(my_websites) else my_websites[len(my_websites)]}')\n        position += 1 if position < len(my_websites) - 1 else len(my_websites) - 1\n    elif action.lower() == 'salir':\n        end = True\n        print(f'Historial de navegación: {my_websites}')\n        print('Cerrando navegador - Fin de programa')\n    else: # Añadimos una nueva web (en este caso en la posición + 1 de donde nos encontremos)\n        my_websites.insert(position+1, action.lower())\n\n\n# Implementación cola de impresión\n\nmy_printer_jobs = [\"Doc1\", \"Doc2\", \"Doc3\"]\nend = False\n\nwhile not end:\n    action = input(\"Indica la acción a realizar (imprimir/nombre documento/salir): \")\n\n    if action.lower() == \"imprimir\":\n        print(f'Imprimiendo {my_printer_jobs.pop(0)}')\n        print(f'Quedan pendientes estos trabajos: {my_printer_jobs}')\n    elif action.lower() == \"salir\":\n        end = True\n        print(f\"Saliendo del spool de impresión, quedan pendientes {len(my_printer_jobs)} documentos por imprimir: {my_printer_jobs}\")\n    else:\n        my_printer_jobs.append(action.lower())\n        print(f'El documento {action.lower()} se ha añadido a la cola de impresión quedando así: {my_printer_jobs}')\n\n#################### FIN EXTRA #########################"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/mvidalb.py",
    "content": "'''\nEjercicio\n'''\n # Pila/Stack (LIFO - Last In First Out)\n\nstack = []\n# push\nstack.append(\"1\")\nstack.append(\"2\")\nstack.append(\"3\")\nprint(stack)\n# pop\nstack_item = stack[len(stack) - 1]\n#del stack[len(stack) - 1]\n\nprint(stack.pop())      #[\"a\",\"b\",\"c\"].pop() --> \"c\"\n\nprint(stack_item)\nprint(stack)\n\n# Cola/Queue (FIFO - First In First Out)\nqueue = []\n# enqueue\nqueue.append(1)\nqueue.append(2)\nqueue.append(3)\n# dequeue\nprint(queue.pop(0))     #[\"a\",\"b\",\"c\"].pop(0) --> \"a\"\n\n\n'''\nEjercicio extra\n'''\n\n# Web\ndef web_navigation():\n    \n    stack = []\n    \n    while True:\n        action = input(\"Añade una url o interactúa con palabra adelante/atrás/salir: \")\n        if action == \"salir\":\n            print(\"Saliendo del navegador web.\")\n            break\n        elif action == \"adelante\":\n            pass\n        elif action == \"atrás\":\n            if len(stack) > 0:\n                stack.pop() \n        else:\n            stack.append(action)\n\n        print(stack)\n        if len(stack) > 0:\n            print(f\"Has navegado a la web: {stack[len(stack) - 1]}\")\n        else:\n            print(\"Estás en la página de inicio.\")\n\nweb_navigation()\n\n\n# Shared printer\ndef shared_printer():\n    queue=[]\n\n    while True:\n        action = input(\"Añade un documento o selecciona imprimir/salir: \")\n        if action == \"salir\":\n            break\n        elif action == \"imprimir\":\n            if len(queue) > 0:\n                impreso = queue.pop(0)   # Elimina el primer elemento que entro en la cola (1º en la lista)\n                print(f\"Archivo impreso: {impreso}\")\n            else:\n                print(\"No hay nada en la cola de impresión\")\n        else:\n            queue.append(action)\n\n        print(f\"Cola de impresión: {queue}\")\n\nshared_printer()\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/neslarra.py",
    "content": "\"\"\"\n EJERCICIO:\n Implementa los mecanismos de introducción y recuperación de elementos propios de las\n pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n o lista (dependiendo de las posibilidades de tu lenguaje).\n\n DIFICULTAD EXTRA (opcional):\n - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n   Las palabras \"adelante\", \"atras\" desencadenan esta acción, el resto se interpreta como\n   el nombre de una nueva web.\n - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n   interpretan como nombres de documentos.\n\"\"\"\n\npila = []\ncola = []\n\n\ndef apilar(elemento):\n    global pila\n    pila.append(elemento)\n\n\ndef encolar(elemento):\n    global cola\n    cola.append(elemento)\n\n\ndef tomar_de_la_pila():\n    global pila\n    if pila:\n        return pila.pop()\n    else:\n        return None\n\n\ndef tomar_de_la_cola():\n    global cola\n    if cola:\n        return cola.pop(0)\n    else:\n        return None\n\n\nprint(f\"\"\"Tanto las pilas (stacks) como las colas (queues) son estructuras lineales con entrada y salida de datos secuencial:\n      1- las pilas se 'apilan' => las últimas entradas son las primeras salidas = tipo LIFO = Last Input First Output\n      2- las colas se 'encolan' => las primeras entradas son las primeras salidas = tipo FIFO = First Input First Output\n\"\"\")\n\nprint(\"Probando pila (Last Input First Output)\\n\")\nprint(\"Apilo 'Mundo'\")\napilar(\"Mundo\")\nprint(\"Apilo 'Hola'\")\napilar(\"Hola\")\nprint(\"Apilo 'World'\")\napilar(\"World\")\nprint(\"Apilo 'Hello'\")\napilar(\"Hello\")\n\nprint(f\"Desapilo {tomar_de_la_pila()}\")\nprint(f\"Desapilo {tomar_de_la_pila()}\")\n\nprint(\"Apilo 'Monde'\")\napilar(\"Monde\")\nprint(\"Apilo 'Alo'\")\napilar(\"Alo\")\n\nprint(f\"Desapilo {tomar_de_la_pila()}\")\nprint(f\"Desapilo {tomar_de_la_pila()}\")\nprint(f\"Desapilo {tomar_de_la_pila()}\")\nprint(f\"Desapilo {tomar_de_la_pila()}\")\nprint(f\"Desapilo {tomar_de_la_pila()}\")\nprint(f\"Desapilo {tomar_de_la_pila()}\")\n\nprint(\"\\n\\nProbando cola (First Input First Output)\\n\")\nprint(\"Encolo 'Hola'\")\nencolar(\"Hola\")\nprint(\"Encolo 'Mundo'\")\nencolar(\"Mundo\")\nprint(\"Encolo 'Hello'\")\nencolar(\"World\")\nprint(\"Encolo 'World'\")\nencolar(\"Hello\")\n\nprint(f\"Desencolo {tomar_de_la_cola()}\")\nprint(f\"Desencolo {tomar_de_la_cola()}\")\n\nprint(\"Encolo 'Alo'\")\nencolar(\"Alo\")\nprint(\"Encolo 'Monde'\")\nencolar(\"Monde\")\n\nprint(f\"Desencolo {tomar_de_la_cola()}\")\nprint(f\"Desencolo {tomar_de_la_cola()}\")\nprint(f\"Desencolo {tomar_de_la_cola()}\")\nprint(f\"Desencolo {tomar_de_la_cola()}\")\nprint(f\"Desencolo {tomar_de_la_cola()}\")\nprint(f\"Desencolo {tomar_de_la_cola()}\")\n\nprint(\"\\n\\nDificultad extra Navegador (usando PILA)\\n\\n\")\n\npila_atras = []\npila_adelante = []\nboton_atras = False\nboton_adelante = False\n\n\ndef apilo_atras(pagina):\n    global pila_atras\n    pila_atras.append(pagina)\n\n\ndef apilo_adelante(pagina):\n    global pila_adelante\n    pila_adelante.append(pagina)\n\n\ndef tomar_de_la_pila_atras():\n    global pila_atras\n    if pila_atras:\n        return pila_atras.pop()\n    else:\n        return None\n\n\ndef tomar_de_la_pila_adelante():\n    global pila_adelante\n    if pila_adelante:\n        return pila_adelante.pop()\n    else:\n        return None\n\n\ndef ver_top_de_pila_atras():\n    global pila_atras\n    if pila_atras:\n        return pila_atras[-1]\n    else:\n        return None\n\n\ndef habilitar_botones():\n    global pila_atras\n    global pila_adelante\n    global boton_atras\n    global boton_adelante\n    if pila_atras.__len__() > 1:\n        boton_atras = True\n    else:\n        boton_atras = False\n    if pila_adelante:\n        boton_adelante = True\n    else:\n        boton_adelante = False\n\n\nhabilitar_botones()\nwhile True:\n    salto = \"\\n\"\n    menu = f\"Elegir opción:\\nhttps://<url-destino>{salto + 'atras' if boton_atras else ''}{salto + 'adelante' if boton_adelante else ''}\\nsalir\\n  ==> \"\n    opcion = input(menu).lower()\n    if opcion == \"salir\":\n        pila_atras.clear()\n        pila_adelante.clear()\n        print(\"Navegador cerrado.\")\n        break\n    if opcion == \"atras\" and boton_atras:\n        pagina = tomar_de_la_pila_atras()\n        apilo_adelante(pagina)\n        pagina = ver_top_de_pila_atras()\n        print(f\"Vuelvo a {pagina}\")\n    elif opcion == \"adelante\" and boton_adelante:\n        pagina = tomar_de_la_pila_adelante()\n        apilo_atras(pagina)\n        print(f\"Voy a {pagina}\")\n    else:\n        if opcion not in (\"atras\", \"adelante\"):\n            pagina = opcion\n            pila_adelante.clear()\n            apilo_atras(pagina)\n        else:\n            pagina = ver_top_de_pila_atras()\n\n    print(f\"Estoy en página https://{pagina}\")\n    habilitar_botones()\n\nprint(\"\\n\\nDificultad extra Navegador (usando COLA)\\n\\n\")\n\nspool_impresion = []\n\n\ndef cargar_documento(documento: str):\n    global spool_impresion\n    spool_impresion.append(documento)\n\n\ndef imprimir():\n    global spool_impresion\n    return spool_impresion.pop(0)\n\n\nsalto = \"\\n\"\ntab = \"\\t\"\nwhile True:\n    menu = f\"Menu de impresora:{salto}{tab}Imprimir{salto}{tab}Ingresar Documento{salto}opcion => \"\n    opcion = input(menu)\n    if not opcion:\n        spool_impresion.clear()\n        print(\"\\n\\nSaliendo.\")\n        break\n    if opcion.lower() == \"imprimir\":\n        if spool_impresion.__len__() > 0:\n            print(f\"Imprimiendo {imprimir()}\", end=\"\\n\\n\")\n        else:\n            print(\"Spool de impresión vacío!!!\", end=\"\\n\\n\")\n    else:\n        print(f\"Mando a imprimir {opcion}\", end=\"\\n\\n\")\n        cargar_documento(opcion)\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/nlarrea.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n\"\"\"\n\n# Stack - LIFO\n\nstack = []\n\n# Add item\nstack.append(1)\nstack.append(2)\nstack.append(3)\nstack.append(4)\nprint(stack)  # [1, 2, 3, 4]\n\n# Remove item\nremoved_item = stack[-1]\ndel stack[-1]\nprint(stack)  # [1, 2, 3]\nprint(removed_item)  # 4\n\nprint(stack.pop())  # 3\nprint(stack)  # [1, 2]\n\n\n# Queue - FIFO\n\nqueue = []\n\n# Add item\nqueue.append(1)\nqueue.append(2)\nqueue.append(3)\nqueue.append(4)\n\n# Remove item\nremoved_item = queue[0]\ndel queue[0]\nprint(queue)  # [2, 3, 4]\nprint(removed_item)  # 1\n\nprint(queue.pop(0))  # 2\nprint(queue)  # [3, 4]\n\nremoved_item = queue[0]\nqueue = queue[1:]\nprint(queue)  # [4]\nprint(removed_item)  # 3\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n\"\"\"\n\n\nhistory = []\npointer = -1\n\n\ndef web_navigation():\n    def show_menu():\n        print(\"\\nType one of the following:\")\n        print(\" - The web page you want to visit\")\n        print(\" - Back (to go to the previous page)\")\n        print(\" - Next (to go to the next page)\")\n        print(\" - Exit\")\n\n    show_menu()\n\n    global pointer\n\n    action: str = input(\"Where do you want to go?\\n> \")\n\n    if action and action.strip().lower() == \"exit\":\n        return\n\n    elif action and action.strip().lower() == \"next\":\n        if pointer != len(history) - 1:\n            pointer += 1\n        print(\"\\nYou are in:\", history[pointer])\n\n    elif action and action.strip().lower() == \"back\":\n        pointer -= 1\n        if pointer < 0:\n            pointer = -1\n            print(\"\\nYou are in home page\")\n        else:\n            print(\"\\nYou are in:\", history[pointer])\n\n    elif action:\n        history.append(action)\n        pointer = len(history) - 1\n        print(\"\\nYou are in:\", history[pointer])\n\n    web_navigation()\n\n\nweb_navigation()\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n\"\"\"\n\n\nprinter_queue = []\n\n\ndef printer():\n    def show_menu():\n        print(\"\\nPrinter options:\")\n        print(\" - Type a document name to add it to the queue\")\n        print(\" - Type 'print' to print the first item\")\n        print(\" - Exit\")\n\n    def show_queue():\n        print(\"\\nPrinter Queue:\")\n\n        if len(printer_queue) > 0:\n            for doc in printer_queue:\n                print(f\" - {doc}\")\n        else:\n            print(\"The Queue is empty.\")\n\n    show_menu()\n\n    action: str = input(\"What do you want to do?\\n> \")\n\n    if action and action.strip().lower() == \"exit\":\n        return\n\n    elif action and action.strip().lower() == \"print\":\n        if len(printer_queue) > 0:\n            printing_doc = printer_queue.pop(0)\n            print(\"Printing:\", printing_doc)\n        else:\n            print(\"There are no documents to print.\")\n\n    elif action:\n        printer_queue.append(action)\n\n    show_queue()\n    printer()\n\n\nprinter()\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/oniricoh.py",
    "content": "########################################################################\n# PILA (stacks - LIFO)\n# El ultimo en entrar en el ultimo en salir\n########################################################################\n\n# Con una lista:\npila = [1, 2, 3]\n\npila.append(4) #se agrega el elemento al final de la lista\npila.pop() #se elimina el ultimo elemento de la lista\n\n#print(pila)\n\n#Con una array:\nstack_array = [[1,2,3],[4,5,6]]\n\nstack_array.append([6, 7, 8])\nstack_array.append([9, 10, 11])\nstack_array.pop()\n\n#print(stack_array)\n\n########################################################################\n# COLA (queue - FIFO) \n# El primero en entrar es el primero en salir\n########################################################################\n\ncola = [1, 2, 3]\n\ncola.append(4)\ncola.append(5)\ncola.pop(0)\n\n#print(cola)\n\n\n\n########################################################################\n########################################################################\n# DIFICULTAD EXTRA \n########################################################################\n########################################################################\n\n#NAVEGADOR WED:\n\nclass Web:\n    def __init__(self):\n        self.pila = [\"Introduccion\", \"Tutoriales\", \"Ejemplos\", \"Practicas\", \"Examen\"]\n        self.actual_pag = []\n        \n    def atras(self):\n        if len(self.pila) > 1:\n            pagina = self.pila.pop()\n            self.actual_pag.append(pagina)\n            print(f\"Navegando a {self.pila[-1]}\")\n        else:\n            print(\"No hay páginas anteriores en el historial.\")\n\n    def adelante(self):\n        if self.actual_pag:\n            pagina = self.actual_pag.pop(0)\n            self.pila.append(pagina)\n            print(f\"Navegando a {self.pila[-1]}\")\n        else:\n            print(\"No hay páginas siguientes en el historial.\")\n\n# Crear una instancia del navegador\nnavegador = Web()\n\n# Ejemplo de uso\nnavegador.atras()\nnavegador.atras()\nnavegador.atras()\nnavegador.adelante()\nnavegador.atras()\nnavegador.atras()\nnavegador.atras()  \n\n\n# IMPRESORA COMPARTIDA:\n\nshared_printer = []\n\ndef enviar_documento(documento):\n    shared_printer.append(documento)\n    print(f\"Enviando documento {documento} a la impresora compartida\")\n\ndef imprimir_documento():\n    if shared_printer:\n        documento = shared_printer.pop(0)\n        print(documento)\n    else:\n        print(\"No hay documentos en la cola\") \n        \n\nimprimir_documento()        \nenviar_documento(\"doc1\")\nenviar_documento(\"doc4\")\nimprimir_documento()\nimprimir_documento()\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/oriaj3.py",
    "content": "\"\"\"\t\n07 - PILAS Y COLAS\t\nAutor de la solución: Oriaj3\t\nTeoría:\t\nLas pilas y las colas son estructuras de datos que permiten almacenar y recuperar elementos.\n\nLas pilas (stacks) son estructuras de datos que siguen el principio LIFO (Last In, First Out), es decir, \nel último elemento que se introduce es el primero en salir. Las pilas se utilizan en multitud de aplicaciones, \ncomo la gestión de llamadas a funciones, la evaluación de expresiones matemáticas, la gestión de memoria, etc.\n\nLas colas (queues) son estructuras de datos que siguen el principio FIFO (First In, First Out), es decir,\nel primer elemento que se introduce es el primero en salir. Las colas se utilizan en multitud de aplicaciones,\ncomo la gestión de tareas, la gestión de recursos compartidos, la impresión de documentos, etc.\n\"\"\"\t\n\n# EJERCICIO BÁSICO:\n\"\"\"\nEJERCICIO:\nImplementa los mecanismos de introducción y recuperación de elementos propios de las\npilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\no lista (dependiendo de las posibilidades de tu lenguaje).\n\"\"\"\n\n# Implementación de pilas sin usar clases con listas \nlista = []\ntope_lista = 0    \ndef l_apilar(elemento: int):\n    global lista, tope_lista\n    lista.append(elemento)\n    tope_lista = len(lista)\n\ndef l_desapilar()-> int:\n    global lista, tope_lista\n    if lista_is_vacia() == False:\n        tope_lista -= 1\n        return lista.pop()\n    else:\n        return None\n    \ndef l_mostrar_pila():\n    global lista, tope_lista\n    print(lista)\n\ndef lista_is_vacia()-> bool:\n    global lista, tope_lista\n    return tope_lista == 0\n\n\n#Prueba, mete 10 elementos en la pila, los muestra y los saca y los muestra\nfor i in range(10):\n    l_apilar(i)\n\nl_mostrar_pila()\n\nfor i in range(5):\n    print(l_desapilar())\n\nl_mostrar_pila()\n\n#Implementación de colas sin clases con listas\ncola = []\n\ndef l_encolar(numero: int):\n    global cola\n    cola.append(numero)\n    \ndef l_is_vacia():\n    global cola\n    return len(cola) == 0\n\ndef l_desencolar() -> int:\n    global cola\n    if(l_is_vacia() == False):\n        return cola.pop(0)\n    else:\n        return None\n    \ndef mostrar_cola():   \n    global cola\n    print(cola)\n\n#Prueba, mete 10 elementos en la cola, los muestra y los saca y los muestra\n    \nfor i in range(10):\n    l_encolar(i)\n\nmostrar_cola()\n\nfor i in range(5):\n    print(l_desencolar())\n\nmostrar_cola()\n\n\n# EJERCICIO EXTRA NAVEGADOR WEB\n\"\"\"\n- Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\nde un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\nque te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\nLas palabras \"adelante\", \"atras\" desencadenan esta acción, el resto se interpreta como\nel nombre de una nueva web.\n\"\"\"\n\n#Al ser una pila, cuando se añade un elemento se añade al final, y cuando se saca se saca del final\ndef     w_new(elemento: str)-> str:\n    global lista_web\n    lista_web.append(elemento)\n    return str(elemento)\n    \ndef w_atras()-> str:\n    global lista_web\n    aux = lista_web.pop()\n    if len(lista_web) > 0:\n        lista_web.insert(0, aux)\n        #Devuelve el último elemento de la lista\n        return lista_web[-1]\n    else:\n        return \"No hay más webs\"\n\ndef w_siguiente()-> str:\n    global lista_web\n    if len(lista_web) > 0:\n        #copia el primer elemento de la lista\n        aux = lista_web.pop(0)\n        lista_web.append(aux)\n        actual = lista_web[-1]\n        return actual\n    else:\n        return \"No hay más webs\" \n\nlista_web = [\"www.google.com\", \"www.youtube.com\", \"www.facebook.com\"]\n#Instrucciones\nprint(\"Introduce una web o 'salir' para terminar, 'atras' para retroceder y 'adelante' para avanzar en el historial de navegación.\")\n\nwhile True:\n    print(f\"Historial de navegación:\")\n    for url in lista_web:\n        print(url, end=\" - \")\n    \n    print()\n    print()\n\n    web = input(\"Introduce una web: \")\n    if (web == \"atras\"):\n        print(f\"Has navegado a {w_atras()}\")\n    elif (web == \"adelante\"):\n        print(f\"Has navegado a {w_siguiente()}\")\n    elif (web.startswith(\"www.\")):\n        print(f\"Has navegado a {w_new(web)}\")\n    elif (web == \"salir\"):\n        break\n    else:\n        print(\"No es una web válida\")\n\n\n# EJERCICIO EXTRA IMPRESORA\n\"\"\"\n- Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\nimpresora compartida que recibe documentos y los imprime cuando así se le indica.\nLa palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\ninterpretan como nombres de documentos.\n\"\"\"\n\n#Al ser una cola, cuando se añade un elemento se añade al final, y cuando se saca se saca del principio\nlista_impresion = [\"Documento1\", \"Documento2\", \"Documento3\", \"Documento4\", \"Documento5\"]\n\ndef imprimir()-> str:\n    print(f\"Imprimiendo {lista_impresion.pop(0)}\")\n\ndef nuevo_documento(nombre: str)-> str:\n    lista_impresion.append(nombre)\n    return nombre\n\nprint(\"Introduce un documento o 'salir' para terminar, 'imprimir' para imprimir un documento.\")\n\nwhile True:\n    print(f\"Documentos en la cola de impresión:\")\n    for doc in lista_impresion:\n        print(doc, end=\" - \")\n    \n    print()\n    print()\n\n    doc = input(\"Introduce un documento: \")\n    if (doc == \"imprimir\"):\n        imprimir()\n    elif (doc == \"salir\"):\n        break\n    else:\n        print(f\"Has añadido el documento {nuevo_documento(doc)}\")\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/pakiuh.py",
    "content": "'''EJERCICIO:\r\nImplementa los mecanismos de introducción y recuperación de elementos propios de las\r\npilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\r\no lista (dependiendo de las posibilidades de tu lenguaje).\r\n'''\r\n#Pilas: Primer elemento que entra es el primero que sale\r\ncomunidad_del_anillo = [\r\n    \"Frodo Bolsón\",\r\n    \"Samwise Gamyi\",\r\n    \"Meriadoc Brandigamo\",\r\n    \"Peregrin Tuk\",\r\n    \"Gandalf el Gris\",\r\n    \"Aragorn\",\r\n    \"Legolas\",\r\n    \"Gimli\",\r\n    \"Boromir\"\r\n]\r\nprint(f\"Inicialmente la Comunidad del Anillo eran: {comunidad_del_anillo}\")\r\n#recuperamos el úlitmo miembro introducido\r\nprimero_muere_el_ultimo = comunidad_del_anillo.pop()\r\nprint(f\"Primero muere el último de la lista: {primero_muere_el_ultimo}\")\r\nprint(f\"y ahora la Comunidad del anillo es: {comunidad_del_anillo}\")\r\n#añadimos un elmento al final de la lista\r\ncomunidad_del_anillo.append(\"Faramir\")\r\nprint(f\"Y luego conocerán a un nuevo miembro y serán: {comunidad_del_anillo}\")\r\n\r\n#Colas: Los últimos serán los primeros, como la cola del Mercadona\r\njedis_caidos = [ #Lista de Jedis muertos\r\n    \"Qui-Gon Jinn\",         # Episodio I – asesinado por Darth Maul\r\n    \"Coleman Trebor\",       # Episodio II – asesinado por Jango Fett durante la batalla de Geonosis\r\n    \"Aayla Secura\",         # Episodio III – ejecutada durante la Orden 66\r\n    \"Ki-Adi-Mundi\",         # Episodio III – ejecutado durante la Orden 66\r\n    \"Plo Koon\",             # Episodio III – ejecutado durante la Orden 66\r\n    \"Saesee Tiin\",          # Episodio III – asesinado por Darth Sidious\r\n    \"Agen Kolar\",           # Episodio III – asesinado por Darth Sidious\r\n    \"Mace Windu\",           # Episodio III – asesinado (presuntamente) por Anakin y Palpatine\r\n    \"Luminara Unduli\",      # (su muerte no se muestra, pero se confirma en la era del Imperio)\r\n    \"Luke Skywalker\",       # Episodio VIII – se une a la Fuerza tras su proyección en Crait\r\n    \"Leia Organa\",          # Episodio IX – muere ayudando a redimir a su hijo, Ben Solo\r\n]\r\n\r\n#Añadimos un nuevo Jedi:\r\njedis_caidos.append(\"Ben Solo (Kylo Ren)\")  # Episodio IX – se sacrifica para revivir a Rey\")\r\n\r\nprint(jedis_caidos)\r\n\r\n#muere_primer_jedi_lista\r\nprimer_jedi_muerto = jedis_caidos.pop(0)\r\nprint(f\"El primer jedi que muere en las películas de Star Wars es: {primer_jedi_muerto}\")\r\nprint(f\"Ahora los Jedis que todavía quedan vivos son: {jedis_caidos}\")\r\n\r\n'''DIFICULTAD EXTRA (opcional):\r\n- Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\r\n  de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\r\n  que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\r\n  Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\r\n  el nombre de una nueva web.'''\r\n\r\n#Simulación de mecanismo adelanta detrás con un navegador web\r\ntexto = \"No todos los que vagan están perdidos. El viejo que olvida su nombre puede aún recordar el camino. La luz brilla más cuando la oscuridad se aproxima.\"\r\n\r\nlistado_de_texto_por_palabras = texto.split()\r\nprint(listado_de_texto_por_palabras)\r\n\r\nposicion_cursor = len(listado_de_texto_por_palabras)-1\r\n\r\ndef atras():\r\n    global posicion_cursor\r\n    if posicion_cursor>0:\r\n        posicion_cursor -=1\r\n        print(listado_de_texto_por_palabras[posicion_cursor])\r\n    else:\r\n        print(\"⚠️ Ya estás al principio del texto.\")\r\n\r\ndef adelante():\r\n    global posicion_cursor\r\n    if posicion_cursor<len(listado_de_texto_por_palabras)-1:\r\n        posicion_cursor +=1\r\n        print(listado_de_texto_por_palabras[posicion_cursor])\r\n    else:\r\n        print(\"⚠️ Ya estás al final del texto.\")\r\n\r\ndef menu():\r\n    while True:\r\n        opciones = input(\"Pulsa 1 para adelante, 2 para atrás, 3 salir: \")\r\n        if opciones == \"1\":\r\n            adelante()\r\n        elif opciones == \"2\":\r\n            atras()\r\n        elif opciones == \"3\":\r\n            break\r\n        else:\r\n            print(\"Opción no válida\")\r\nmenu()\r\n\r\n'''Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\r\n  impresora compartida que recibe documentos y los imprime cuando así se le indica.\r\n  La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\r\n  interpretan como nombres de documentos.'''\r\n\r\n#Tenemos un conjunto de cómics de Marvel en formato pdf que queremos imprimir y están ordenados según debería leerlo\r\ncomics_marvel = [\r\n    \"House of M\",          # Wanda altera la realidad — afecta a todo el universo Marvel\r\n    \"Civil War\",           # Consecuencias sociales y políticas tras House of M\r\n    \"Planet Hulk\",         # Hulk es exiliado tras causar estragos en la Tierra\r\n    \"Infinity Gauntlet\",   # Thanos se convierte en el mayor villano cósmico\r\n    \"Spider-Verse\"         # Multiverso y diferentes versiones de Spider-Man, independiente pero ideal tras conocer el universo\r\n]\r\n\r\ndef imprimir_comic():\r\n    imprimiendo = comics_marvel.pop(0)\r\n    print(f\"La impresora está imprimiendo el cómic {imprimiendo} para que puedas leerlo, quedan pendientes {len(comics_marvel)} por leer\")\r\n\r\ndef añadir_comic(titulo):\r\n    comics_marvel.append(titulo)\r\n    print(f\"Tienes un nuevo cómic pendiente de leer e imprimir, el {titulo} se añade a tu cola de comics pendientes que en estos momentos es {comics_marvel}\")\r\n\r\nañadir_comic(\"Secret Wars\")\r\nimprimir_comic()\r\nimprimir_comic()\r\nañadir_comic(\"Spider-Geddon\")"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/pguillo02.py",
    "content": "class Queue():\n    def __init__(self):\n        self.queue = []\n\n    def push(self, item):\n        self.queue.append(item)\n\n    def pop(self):\n        return self.queue.pop(0)\n    \n    def __str__(self): \n        return str(self.queue)\n\nclass Stack():\n    def __init__(self):\n        self.stack = []\n\n    def push(self, item):\n        self.stack.append(item)\n\n    def pop(self):\n        return self.stack.pop()\n    \n    def __str__(self): \n        return str(self.stack)\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/pipngpop.py",
    "content": "'''\nPILAS Y COLAS\n'''\n\n#Pilas/Stack (LIFO) Last In First Out\n\nstack = []\n\n#push\nstack.append(1) \nstack.append(2) \nstack.append(3) \nprint(stack)\n\n#pop\nstack_item = stack[len(stack) - 1]\ndel stack[len(stack) - 1] #borra elemento del stack\nprint(stack_item)\n\nprint(stack.pop()) #también muestra el último añadido\n\nprint(stack)\n\n#Cola/Queue (FIFO)\n\nqueue = []\n\n#enqueue\nqueue.append(1)\nqueue.append(2)\nqueue.append(3)\nprint(queue)\n\n#dequeue\nprint(queue.pop(0))\n\nprint\n\n\n'''\nEXTRA\n'''\n'''\n* - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n'''\n\n# Navegador web\n\npila = []\nans = \"0\"\ncont=0\nwhile True:\n    \n    if ans != \"adelante\" and ans != \"atras\" and cont!=1:\n        cont=1\n        at=len(pila)-1\n    else: \n        cont=1\n        at=at\n\n    ans = input(\"adelante/atras: \")\n\n\n    if ans == \"adelante\":\n        at=at+1\n    elif ans == \"atras\": #ok\n        at=at-1  \n    elif ans == \"end\":\n        break\n    else:\n        pila.append(ans)\n        at=len(pila)-1\n\n    pos = pila[at]\n    print(f\"\\n Dirección actual: {pos}\")\n    print(\" \")   \n\n\n\n# Impresora\n\ncola = []\n\nwhile True:\n\n    doc = input(\"\\nIMP: \")\n\n    if doc == \"imprimir\" and cola:\n        print(f\"\\nImprimiendo {cola.pop(0)}\")\n    elif doc == \"imprimir\" and not cola:\n        print(\"\\nNo hay elementos en la cola\")\n    elif doc == \"end\":\n        break\n    else:\n        cola.append(doc)\n    \n    print(cola)\n\n\n    '''\n    EL SUYO\n\n    # Web\n\n\ndef web_navigation():\n\n    stack = []\n\n    while True:\n\n        action = input(\n            \"Añade una url o interactúa con palabras adelante/atrás/salir: \"\n        )\n\n        if action == \"salir\":\n            print(\"Saliendo del navegador web.\")\n            break\n        elif action == \"adelante\":\n            pass\n        elif action == \"atrás\":\n            if len(stack) > 0:\n                stack.pop()\n        else:\n            stack.append(action)\n\n        if len(stack) > 0:\n            print(f\"Has navegado a la web: {stack[len(stack) - 1]}.\")\n        else:\n            print(\"Estás en la página de inicio.\")\n\n\nweb_navigation()\n\n\ndef shared_printed():\n\n    queue = []\n\n    while True:\n\n        action = input(\"Añade un documento o selecciona imprimir/salir: \")\n\n        if action == \"salir\":\n            break\n        elif action == \"imprimir\":\n            if len(queue) > 0:\n                print(f\"Imprimiendo: {queue.pop(0)}\")\n        else:\n            queue.append(action)\n\n        print(f\"Cola de impresión: {queue}\")\n\n\nshared_printed()\n\n    '''\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/pwrxman.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n\"\"\"\n\n# # PILAS  (STACKS)  LIFO\n\n# agregar elemento a la pila o la cola\n# def addelem(elem: str, stack: list):\n#      print(\"añadir elemento\")\n#      stack.append(elem)\n\n# # retirar elemento de la pila\n# def pop(stack: list):\n#     print(\"retirar elemento de la Pila\")\n#     if not stackempty(stack):\n#         stack.pop()\n\n# # validar si pila o cola vacia\ndef stackempty(stack: list) -> bool:\n    if len(stack) == 0:\n        print(\"Lista Vacia\")\n        return True\n    else:\n        return False\n\n\n# # COLAS (QUEUES) FIFO\n\n# # retirar elemento de la cola\n# def dequeue(stack: list):\n#     print(\"retirar elemento de la Cola\")\n#     if not stackempty(stack):\n#         stack.pop(0)\n\n# stack = list()\n# queue = list()\n\n# while True:\n#     print(\"PILAS\")\n#     print(\"\\t1 - Agregar elemento en pila\")\n#     print(\"\\t2 - Eliminar elemento de pila\")\n#     print(\"\\t3 - Mostrar pila\\n\")\n#     print(\"COLAS\")\n#     print(\"\\t4 - Agregar elemento en cola\")\n#     print(\"\\t5 - Eliminar elemento de cola\")\n#     print(\"\\t6 - Mostrar cola\\n\")\n#     print(\"q - Terminar\")\n\n#     action= input(\"Que desea hacer? \")\n#     match action:\n#         case '1':\n#             element=input(\"Cual es el elemento que desea añadir a la list? \")\n#             addelem(element, stack)\n#         case '2':\n#             pop(stack)\n#         case '3':\n#             print(f\"Pila -> {stack}\")\n#         case '4':\n#             element=input(\"Cual es el elemento que desea añadir a la cola? \")\n#             addelem(element, queue)\n#         case '5':\n#             dequeue(queue)\n#         case '6': \n#             print(f\"Cola -> {queue}\")\n#         case 'q':\n#             print(\"Hasta la vista...\")\n#             break\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n \n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n \"\"\"\n\n\n\n\n# agregar elemento a la pila o la cola\ndef add_wj(web: str, stack: list):\n    print(f\"Has añadido un nuevo elemento {web}\")\n    stack.append(web)\n\n# retirar elemento de la pila\ndef pop_web(stack: list):\n    print(\"Regresando...\")\n    if not stackempty(stack):\n        print(f\"has navegado a la página {stack_web[len(stack_web)-2]}\")\n        stack.pop()\n\n\n\n# COLAS (QUEUES) FIFO\n\n# imprimir elemento de la cola\ndef job_queue(stack: list):\n    print(\"imprimir job de la Cola\")\n    if not stackempty(stack):\n        stack.pop(0)\n\nstack_web = list()\nprint_queue = list()\n\nwhile True:\n    print(\"PILAS\")\n    print(\"\\t1 - Agregar página web.\")\n    print(\"\\t2 - Avanzar.?????\")\n    print(\"\\t3 - Regresar.\")\n    print(\"\\t4 - Mostrar páginas fr navegación.\\n\")\n\n    print(\"COLAS\")\n    print(\"\\t5 - Agregar job en cola\")\n    print(\"\\t6 - Imprimir job de la cola\")\n    print(\"\\t7 - Mostrar cola de impresion\\n\")\n    print(\"q - Terminar\")\n\n    action= input(\"Que desea hacer? \")\n    match action:\n        case '1':\n            element=input(\"Cual es la página a la que desea navegar? \")\n            add_wj(element, stack_web)\n        case '2':\n            print(\"No se puede implementar con listas en python\")\n        case '3':\n            pop_web(stack_web)\n        case '4':\n            print(f\"Páginas -> {stack_web}\")\n        case '5':\n            element=input(\"Cual es el job de impresión que desea añadir a la cola? \")\n            add_wj(element, print_queue)\n        case '6':\n            job_queue(print_queue)\n        case '7': \n            print(f\"Cola -> {print_queue}\")\n        case 'q':\n            print(\"Hasta la vista...\")\n            break\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/pyramsd.py",
    "content": "'''\nSTACK - LISTA\n'''\n\nlista = [] \n\n# introducir en la lista\nlista.append(\"a\")\nlista.append(\"b\")\nlista.append(\"c\")\nlista.append(\"d\")\n\n# mostramos el contenido\nprint(lista)\n\n# recuperar con .pop()\nprint(\"sacamos:\", lista.pop())\nlista.append(\"e\")\n\nprint(lista)\n\n\n'''\nQUEUE - COLA \n'''\n\nfrom collections import deque\n\ncola = deque()\n\nfor i in range(5):\n    puesto = 'puesto ' + str(i+1)\n    print('Llega', puesto)\n    cola.append(puesto)\n    print('Cola:', cola)\n\n\n# salen todos los puestos de la cola \nwhile len(cola) > 0:\n    print('Sale', cola.popleft())\n    print('Qedan:', cola)\n\n\n'''\nEXTRA\n'''\n\ndef buscador():\n    \n    paginas = []\n\n    ultima_pagina = \"\"\n\n    def link():\n       link = input(\"Ingrese una pagina web: \")\n       paginas.append(link)\n       print(f\"Redirigiendo a {link}\") \n    \n\n    def forward():\n       if ultima_pagina == \"\":\n           print(\"Estás en la ultima pagina\") \n       else:\n           paginas.append(ultima_pagina)\n           print(\"Redirigiendo a \", paginas[-1])\n\n\n    def backwards():\n        backwards = paginas.pop()\n        print(f\"Ultima pagina: {backwards}\")\n\n        return backwards\n\n\n    while True:\n\n        print()\n        print(\"1. Buscar\")\n        print(\"2. Adelante\")\n        print(\"3. Atras\")\n        print(\"4. Historial\")\n        print(\"5. Salir\")\n\n        choice = input(\"Elija una opción: \")\n\n        match choice:\n\n            case \"1\":\n                link()\n            case \"2\":\n                forward()\n            case \"3\": \n                ultima_pagina = backwards()\n            case \"4\": \n                print(paginas)\n            case \"5\":\n                print(\"Cerrar el navegador.\")\n                break\n            case _:\n                print(\"Opcion no valida. Elige una opcion del 1 al 5\")\n\n\nbuscador()    \n\n\ndef printer():\n\n   queue = deque() \n\n   def send():\n        doc = input(\"Documento a enviar :\")\n        queue.append(doc)\n        print(f\"Cola: {queue}\")\n\n\n   def imprimiendo():\n       print('Imprimiendo', queue.popleft())\n       print('Qedan:', queue, 'documentos.')\n\n   while True:\n       \n       print()\n       print(\"1. Enviar\")\n       print(\"2. Imprimir\")\n       print(\"3. Salir\")\n       \n       choice = input(\"Elija una opción: \")\n       \n       match choice:\n\n        case \"1\":\n            send()\n        case \"2\":\n            if len(queue ) == 0:\n                print(\"No hay documentos que imprimir.\")\n            else:\n                imprimiendo()\n        case \"3\":\n            print(\"Impresora cerrada.\")\n            break\n        case _:\n            print(\"Opcion no valida. Elige una opcion del 1 al 3\")\n\nprinter()\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/qv1ko.py",
    "content": "stack = []\n\nstack.append('1')\nstack.append('2')\nstack.append('3')\n\nprint(\"Stack: \", stack)\n\nstack.pop()\nprint(\"Stack after pop: \", stack)\n\nqueue = []\n\nqueue.append('a')\nqueue.append('b')\nqueue.append('c')\n\nprint(\"Queue: \", queue)\n\nqueue.pop(0)\nprint(\"Queue after dequeue: \", queue)\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/qwik-zgheib.py",
    "content": "class Stack:\n    def __init__(self):\n        self.stack = []\n\n    def push(self, item):\n        self.stack.append(item)\n\n    def pop(self):\n        if not self.is_empty():\n            return self.stack.pop()\n        return None\n\n    def peek(self):\n        if not self.is_empty():\n            return self.stack[-1]\n        return None\n\n    def is_empty(self):\n        return len(self.stack) == 0\n\n    def size(self):\n        return len(self.stack)\n\n\nclass Queue:\n    def __init__(self):\n        self.queue = []\n\n    def enqueue(self, item):\n        self.queue.append(item)\n\n    def dequeue(self):\n        if not self.is_empty():\n            return self.queue.pop(0)\n        return None\n\n    def peek(self):\n        if not self.is_empty():\n            return self.queue[0]\n        return None\n\n    def is_empty(self):\n        return len(self.queue) == 0\n\n    def size(self):\n        return len(self.queue)\n\n\nclass Browser:\n    def __init__(self):\n        self.back_stack = Stack()\n        self.forward_stack = Stack()\n        self.current_page = None\n\n    def navigate_to(self, page):\n        if self.current_page:\n            self.back_stack.push(self.current_page)\n        self.current_page = page\n        self.forward_stack = Stack()  # Clear forward stack\n\n    def go_back(self):\n        if not self.back_stack.is_empty():\n            self.forward_stack.push(self.current_page)\n            self.current_page = self.back_stack.pop()\n\n    def go_forward(self):\n        if not self.forward_stack.is_empty():\n            self.back_stack.push(self.current_page)\n            self.current_page = self.forward_stack.pop()\n\n    def current(self):\n        return self.current_page\n\n\n# -- extra challenge\ndef browser_simulation():\n    browser = Browser()\n    while True:\n        command = (\n            input(\"Enter the name of a website, 'forward'|'back'|'exit|: \")\n            .strip()\n            .lower()\n        )\n        if command == \"next\":\n            browser.go_forward()\n        elif command == \"back\":\n            browser.go_back()\n        elif command == \"exit\":\n            break\n        else:\n            browser.navigate_to(command)\n\n        print(f\"actual page: {browser.current()}\")\n\n\nif __name__ == \"__main__\":\n    browser_simulation()\n\n\nclass Printer:\n    def __init__(self):\n        self.print_queue = Queue()\n\n    def add_document(self, document):\n        self.print_queue.enqueue(document)\n\n    def print_document(self):\n        if not self.print_queue.is_empty():\n            document = self.print_queue.dequeue()\n            print(f\"printing document: {document}\")\n        else:\n            print(\"there are no documents in the queue.\")\n\n    def queue_size(self):\n        return self.print_queue.size()\n\n\ndef printer_simulation():\n    printer = Printer()\n    while True:\n        command = (\n            input(\"enter the name of a document or 'print' | 'exit': \").strip().lower()\n        )\n        if command == \"print\":\n            printer.print_document()\n        elif command == \"exit\":\n            break\n        else:\n            printer.add_document(command)\n            print(\n                f\"document '{command}' added to queue. Documents in queue: {printer.queue_size()}\"\n            )\n\n\nif __name__ == \"__main__\":\n    printer_simulation()\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/rantamhack.py",
    "content": "\n\"\"\"\nEJERCICIO:\nImplementa los mecanismos de introducción y recuperación de elementos propios de las\npilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\no lista (dependiendo de las posibilidades de tu lenguaje).\n\"\"\"\n\n\nprint(\"\\n\\n=====================================PILAS=====================================\\n\\n\")\n\n\n'''\nUna pila es una colección ordenada de elementos donde la adición de un nuevo elemento y \nla eliminación de los existentes siempre ocurren desde el mismo extremo.\n'''\n\nstack = []\n\ndef push():\n   \n    stack.append(1)\n    stack.append(2)\n    stack.append(3)\n    stack.append(4)\n    stack.append(5)\n    print(stack)\n\npush()\n\ndef pop():\n\n    print(stack.pop())\n    print(stack)\n    print(stack.pop())\n    print(stack)\n    print(stack.pop())\n    print(stack)\n    print(stack.pop())\n    print(stack)\n    print(stack.pop())\n\npop()\n    \nprint(\"\\n\\n=====================================COLAS=====================================\\n\\n\")\n\n\"\"\"\nUna  cola  es una colección ordenada de elementos donde la adición de nuevos elementos ocurre en un extremo \ny la eliminación de elementos existentes ocurre en el otro extremo. Se denominan delante y detrás respectivamente.\n\n\"\"\"\nqueue = []\n\ndef push():\n\n    queue.append(\"Miguel\")\n    print(queue)\n    \n    queue.append(\"Jose\")\n    print(queue)\n    \n    queue.append(\"Maria\")\n    print(queue)\n\n    queue.append(\"Mar\")\n    print(queue)\n\n    queue.append(\"Helena\")\n    print(queue)\n\npush()\n\ndef pop():\n    \n    return queue.pop(0)\n    \npop()\nprint(queue)\n\npop()\nprint(queue)\n\npop()\nprint(queue)\n\npop()\nprint(queue)\n\npop()\nprint(queue)\n\n\nprint(\"\\n\\n=====================================DIFICULTAD EXTRA=====================================\\n\\n\")\n\n'''\nUtilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\nde un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\nque te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\nLas palabras \"adelante\", \"atras\" desencadenan esta acción, el resto se interpreta como\nel nombre de una nueva web.\n'''\n\nstack = [\"program_languages\"]\n\ndef python():\n    print(f\"\\n{stack}\\n\")\n    print(\"Bienvenido a la pagina de python\")\n    new_page = input(\"¿Que pagina quieres visitar ahora?: \\n siguiente / anterior: \")\n    if new_page.lower() == \"anterior\":\n        stack.pop()\n        program_languages()\n    elif new_page.lower() == \"siguiente\":\n        stack.append(\"javascript\")\n        javascript()\n    else:\n        print(\"Has elegido una opción no disponible \\n [+] Saliendo del programa .....\")\n        exit\n        \ndef javascript():\n    print(f\"\\n{stack}\\n\")\n    print(\"Bienvenido a la pagina de javascript\")\n    new_page = input(\"¿Que pagina quieres visitar ahora?: \\n siguiente / anterior: \")\n    if new_page.lower() == \"anterior\":\n        stack.pop()\n        python()\n    elif new_page.lower() == \"siguiente\":\n        stack.append(\"java\")\n        java()\n    else:\n        print(\"Has elegido una opción no disponible \\n [+] Saliendo del programa .....\")\n        exit\n        \ndef java():\n    print(f\"\\n{stack}\\n\")\n    print(\"Bienvenido a la pagina de java\")\n    new_page = input(\"¿Que pagina quieres visitar ahora?: \\n siguiente / anterior: \")\n    if new_page.lower() == \"anterior\":\n        stack.pop()\n        javascript()\n    elif new_page.lower() == \"siguiente\":\n        stack.append(\"typescript\")\n        typescript()\n    else:\n        print(\"Has elegido una opción no disponible \\n [+] Saliendo del programa .....\")\n        exit\n\ndef typescript():\n    print(f\"\\n{stack}\\n\")\n    print(\"Bienvenido a la pagina de typescript\")\n    back = input(\"¿Quieres volver a visitar la página anterior? si / no: \")\n    if back.lower() == \"si\":\n        stack.pop()\n        java()\n    else:\n        print(\"[+] Saliendo del programa .....\")\n        exit\n\n    \n\ndef program_languages():\n    print(f\"\\n{stack}\\n\")\n    print(\"Bienvenido a la pagina principal\\n Los 4 lenguajes mas usados en el roadmap del gran Mouredev son: \\n 1º python\\n 2º javascript\\n 3º java\\n 4º typescript\")\n    languages = input(\"¿Quieres visitar la página de python?: \\nsi / no: \")\n    \n    if languages.lower() == \"si\":\n        stack.append(\"python\")\n        python() \n    elif languages.lower() == \"no\":\n        print(\"[+] Saliendo del programa .....\")\n    else:\n        print(\"Has elegido una opción no disponible \\n [+] Saliendo del programa .....\")\n        exit\n    \nprogram_languages()\n\n\nprint(\"\\n\\n=====================================DIFICULTAD EXTRA=====================================\\n\\n\")\n    \n'''    \nUtilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\nimpresora compartida que recibe documentos y los imprime cuando así se le indica.\nLa palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\ninterpretan como nombres de documentos.\n'''\n\nqueue = []  \n\ndef new_doc(doc):\n    queue.append(doc)\n    print(queue)\n    \nnew_doc(\"doc1.txt\")\nnew_doc(\"doc2.txt\")\nnew_doc(\"doc3.txt\")\nnew_doc(\"doc4.txt\")\nnew_doc(\"doc5.txt\")\n\ndef impresion():\n    print(f\"Imprimiéndose el documento {queue.pop(0)}\")\n    \n    \n\ndef imprimir():\n    result = input(\"Quieres imprimir el primer documento de la cola de impresión: \\nimprimir / no imprimir: \")\n    while result == \"imprimir\":\n        impresion()\n        print(f\"\\n{queue}\\n\")\n        if queue != []:\n            result = input(\"Quieres imprimir el siguiente documento de la cola de impresión: \\nimprimir / no imprimir: \")\n        else:\n            print(\"No hay documentos en la cola de impresión\")\n            break\n        \nimprimir()\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/raul-anton-2005.py",
    "content": "def add_stack(stack, value):\n    stack.append(value)\n    return stack\n\ndef remove_stack(stack):\n    if stack:\n        stack.pop()\n        return stack\n    else:\n        return None\n\ndef add_queue(queue, value):\n    queue.append(value)\n    return queue\n\ndef remove_queue(queue):\n    if queue:\n        queue.pop(0)\n        return queue\n    else:\n        return None\n\nstack = []\nqueue = []\n\n# Añadiendo elementos a la pila\nadd_stack(stack, 1)\nadd_stack(stack, 2)\nadd_stack(stack, 3)\n\n# Eliminando elementos de la pila\nprint(\"Estado final de la pila:\", remove_stack(stack))\n\n# Añadiendo elementos a la cola\nadd_queue(queue, 1)\nadd_queue(queue, 2)\nadd_queue(queue, 3)\n\n# Eliminando elementos de la cola\nprint(\"Estado final de la cola:\", remove_queue(queue))\n\ndef browser():\n    pages = [\"Google\", \"Facebook\", \"Twitter\", \"Instagram\", \"LinkedIn\", \"YouTube\", \"GitHub\"]\n    history = []\n    forward_history = []\n    current_page = None\n    while True:\n        print(\"\\n--- Navegador Web ---\")\n        print(\"Página actual:\", current_page)\n        print(\"Historial:\", history)\n        print(\"Historial hacia adelante:\", forward_history)\n        print(\"Páginas disponibles:\", pages)\n        action = input(\"Introduce 'adelante' o 'atrás' para navegar, o directamente una web: \")\n        \n        if action == \"atrás\":\n            if history:\n                add_stack(forward_history, current_page)\n                current_page = history[-1]\n                remove_stack(history)\n                print(\"Navegando a:\", current_page)\n            else:\n                print(\"No hay historial disponible.\")\n        elif action == \"adelante\":\n            if forward_history:\n                add_stack(history, current_page)\n                current_page = forward_history[-1]\n                remove_stack(forward_history)\n                print(\"Navegando a:\", current_page)\n            else:\n                print(\"No hay páginas disponibles.\")\n        elif action in pages:\n            if current_page:\n                add_stack(history, current_page)\n            current_page = action\n        elif action == \"salir\":\n            print(\"Saliendo del navegador.\")\n            break\n        else:\n            print(\"Acción invalida.\")\n\ndef printer():\n    queue = []\n    while True:\n        print(\"\\n--- Impresora ---\")\n        print(\"Cola de impresión:\", queue)\n        action = input(\"Introduce 'imprimir' para imprimir el primer documento, o un nombre de documento para añadir a la cola: \")\n        \n        if action == \"imprimir\":\n            if queue:\n                remove_queue(queue)\n                print(\"Imprimiendo documento...\")\n            else:\n                print(\"No hay documentos en la cola.\")\n        elif action == \"salir\":\n            print(\"Saliendo de la impresora.\")\n            break\n        else:\n            add_queue(queue, action)\n            print(f\"Documento '{action}' añadido a la cola.\")\n\nbrowser()\nprinter()\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/raulG91.py",
    "content": "#Stack\n\n\ndef stack_add_element(stack,element):\n    stack.append(element)\n\ndef stack_remove_element(stack):\n    \n    return stack.pop()\n        \n        \nstack = []\nstack_add_element(stack,5)\nstack_add_element(stack,23)\nstack_add_element(stack,5)\nprint(stack)\nprint(\"Delete last element \",stack_remove_element(stack))\nprint(stack)      \n\n#Queue\ndef queue_add_element(queue,element):\n    \n    queue.append(element)\n    \ndef queue_remove_element(queue):\n    \n    if len(queue) > 0:\n        return queue.pop(0)    \n    \nqueue = []\nqueue_add_element(queue,8)   \nqueue_add_element(queue,6)\nqueue_add_element(queue,0)\nprint(queue)\nprint(\"Delete first element \", queue_remove_element(queue))\nprint(queue)\n\n#Extra exercise\n\ndef browser():\n    browser = []\n    history = []\n    current = \"\"\n    index = 0\n    while True:\n        option = input(\"Introduzca adelante/atras o salir \")\n        if option == \"adelante\":\n            if(index +1)< len(browser):\n                stack_add_element(history,current)\n\n                index+=1\n                current = browser[index]\n                \n            print(\"Pagina actual: \",current)\n                \n        elif option == \"atras\":\n            if len(history)>0:\n                current = stack_remove_element(history)\n                index-=1\n            print(\"Pagina actual: \",current)\n            \n                    \n        elif option == \"salir\":\n            break\n        else:\n            browser.append(option)\n            if len(browser) > 1:\n                stack_add_element(history,current)\n            current = option\n            if len(browser)> 1:\n                index+=1\n            print(\"Pagina actual: \",current)\n\n     \n            \nbrowser()            \n            \ndef printer():\n    printer_queue = []\n    \n    while True:\n        option = input(\"Introduzca documento, imprimir,  salir \")\n        if option == \"imprimir\":\n            print(\"Imprimendo: \",queue_remove_element(printer_queue))\n        elif option == \"salir\":\n            break\n        else:\n            queue_add_element(printer_queue,option)          \n                       \nprinter()                        "
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/rayn1er.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n#  * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n#  * o lista (dependiendo de las posibilidades de tu lenguaje).\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n#  *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n#  *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n#  *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n#  *   el nombre de una nueva web.\n#  * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n#  *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n#  *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n#  *   interpretan como nombres de documentos.\n#  */\n\n# pilas o stacks (primero en entrar, ultimo en salir) \n\nstack = []\nstack.append('primero')  #primero en entrar (push)\nprint(stack)\nstack.append(\"segundo\")\nprint(stack)\nstack.pop() # utilizamos pop para eliminar el ultimo elemento (pop)\nprint(stack) #elimina el ultimo funcionando como una pila\n\n# colas or queue (primero en entrar, primero en salir)\nprint()\nqueue = []\nqueue.append('primero')  #primero en entrar (push)\nprint(queue)\nqueue.append(\"segundo\")\nprint(queue)\nqueue.pop(0) # utilizamos pop con el indice cero para eliminar el priemr elemento en la lista (pop)\nprint(queue) # elimina el primero funcionando como una cola\n\n\n#extra \n\n\n\n\ndef surfing_web():\n    web_browser = []\n    while True:\n        element = input(\"Ingrese la url o si desea ir adelante o hacia atras o salir -> \")\n\n        if element.lower() == 'salir':\n                print('Cerrando ')\n                break\n        elif element.lower() == 'adelante':\n                pass\n        elif element.lower() == 'atras':\n            if len(web_browser) > 0:\n                web_browser.pop()\n        else:\n            web_browser.append(element)\n\n        if len(web_browser) > 0:\n              print(f\"has navegado hasta {web_browser[len(web_browser) - 1]} \")\n        else:\n              print(\"Estas en la pagina de inicio \")\n\ndef print_element():\n    printer_queue = []\n\n    while True:\n         element = input(\"Escriba si quiere imprimir un elemento de la cola o agregar uno o salir de la impresora-> \")\n         element = element.lower()\n         if element == 'salir':\n              print('Cerrando ')\n              break\n         if element == \"imprimir\":\n                if printer_queue:\n                    print(f\"Imprimiendo: {printer_queue.pop(0)}\")\n                else:\n                    print(\"No hay documentos en cola\")\n         else:\n                printer_queue.append(element)\n                print(f\"Documento agregado: {element}\")\n\n\n            \nwhile True:\n    print(f'''\n        Seleccione una opcion\n        1 - Navegador web\n        2 - Impresora\n        3 - Salir\n          ''')\n    \n    option = input('Seleccione opcion -> ')\n\n    if option == '1':\n        surfing_web()\n    elif option == '2':\n        print_element()\n    elif option == '3':\n        print('Cerrando ')\n        break\n    else:\n        print(\"Seleccione una opcion correcta -> \") "
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/raynerpv2022.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n#  * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n#  * o lista (dependiendo de las posibilidades de tu lenguaje).\n#  *\n\n\npila = []\ndef set_pila(items):\n    pila.append(items)\n\ndef get_pila():\n    return pila.pop(len(pila)-1)\n\ncola = []\n\ndef set_cola(items):\n    cola.append(items)\n\ndef get_cola():\n    return cola.pop(0)\n\ndef pila_func():\n             print(\" PILA, Set (1) o Get (2)\")\n             op_pila = input(\":\")\n             match op_pila:\n                 case \"1\":\n                     print(\"Items a introducir : \")\n                     it = input(\":\")\n                     set_pila(it)\n                 case \"2\":\n                     print(\"Sacando ultimo elemento pila\")\n                     print(\"Pila completa \",pila)\n                     print(get_pila())\n                     print(\"Pila actualizada \",pila)\n\ndef cola_func():\n             print(\" Cola, Set (1) o Get (2)\")\n             op_cola = input(\":\")\n             match op_cola:\n                 case \"1\":\n                     print(\"Items a introducir : \")\n                     it = input(\":\")\n                     set_cola(it)\n                 case \"2\":\n                     print(\"Sacando ultimo elemento cola\")\n                     print(\"COla completa \",cola)\n                     print(get_cola())\n                     print(\"Cola actualizada \",cola)\n\nwhile True:\n    print(\" Pila (1) o  Cola (2) Salir (3):\")\n    op = input(\":\")\n    match op:\n        case \"1\":\n             pila_func()\n        case \"2\":\n              cola_func()\n        case \"3\":\n            break\n        case _:\n              print( \"OPcion no valida\")\n\n\n\n    \n    #  * DIFICULTAD EXTRA (opcional):\n#  * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n#  *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n#  *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n#  *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n#  *   el nombre de una nueva web.\n#  * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n#  *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n#  *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n#  *   interpretan como nombres de documentos.\n#  */\n\n\n \ndef is_empty(list1: list,cad: str)   :\n     if len(list1) == 0:\n          print(cad)\n          return True\n     else :\n          return False\n     \n# ?muetsra todas las web de la lista, y el ligar donde esta actualmente la lista\ndef mostrar_url(url_list :list, index : int):\n     if not is_empty(url_list,\"No hay direcciones web\"):\n          print(f\"{url_list}, posiscion actual :{index}\")\n\ndef TOR():\n     url_list = []\n     print(\"NAVEGADOR T O R\")\n     index = 0 # inicio con indice en posicion 0\n     while True:\n          len_list_url = len(url_list)\n          print(\"adelante, atras, url, salir ?: \")\n          op = input()\n          match op:\n               case \"adelante\":\n                     \n                    if not is_empty(url_list,\"No hay direcciones web\"):\n                        if(len_list_url- 1) > index:\n                            index+=1 # si no he llegado al final incremento 1 al indice, si llegue al final no incremento\n                    print(\"Navegando en \",url_list[index]) #  muestro web en indice actual, \n\n               case  \"atras\":\n                     \n                    if not is_empty(url_list,\"No hay direcciones web\") :\n                        if 0 < index: \n                            index-=1 # si no he llegado al inicio , decremento el indice actual, si llegue al inicio, muestro el primero\n                    print(\"Navegando en \", url_list[index])\n\n               case \"url\" :\n                    mostrar_url(url_list,index)\n\n               case \"salir\" :\n                    break\n               case _:\n                    url_list.append(op)\n                    index = len(url_list)-1\n                    print(\"Navegando en \", url_list[index])\n                    \n                    \ndef Printer():\n     printer_queue = []\n     while True:\n          print(\"imprimir o salir :\")\n          op = input()\n          match op:\n               case \"imprimir\":\n                    if not is_empty(printer_queue,\"No hay trabajos a imprimir\") and len(printer_queue) > 0:\n                        print(f\"Imprimiendo {printer_queue.pop(0)}\")\n                        print(f\"Tareas por imprimir {printer_queue }\")\n               case \"salir\":\n                    break\n               case _:\n                    printer_queue.append(op)\n          \n               \n\nTOR()   \nPrinter()        "
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/restevean.py",
    "content": "# Stack (LIFO)\nclass Stack:\n    def __init__(self):\n        self.stack = []\n\n    def push(self, item):\n        self.stack.append(item)\n\n    def pop(self):\n        if not self.is_empty():\n            stack_item = self.stack[len(self.stack) - 1]\n            del self.stack[len(self.stack) - 1]\n            return stack_item\n\n    def is_empty(self):\n        return len(self.stack) == 0\n\n\n# Queue (FIFO)\nclass Queue:\n    def __init__(self):\n        self.queue = []\n\n    def enqueue(self, item):\n        self.queue.append(item)\n\n    def dequeue(self):\n        if not self.is_empty():\n            queue_item = self.queue[0]\n            del self.queue[0]\n            return queue_item\n\n    def is_empty(self):\n        return len(self.queue) == 0\n\n\ndef main():\n    # Stack\n    stack = Stack()\n    stack.push(1)\n    stack.push(2)\n    stack.push(3)\n    print(stack.stack)\n\n    print(stack.pop())\n    print(stack.pop())\n    print(stack.pop())\n    print(stack.pop())\n\n    # Queue\n    queue = Queue()\n    queue.enqueue(1)\n    queue.enqueue(2)\n    queue.enqueue(3)\n    print(queue.queue)\n\n    print(queue.dequeue())\n    print(queue.dequeue())\n    print(queue.dequeue())\n    print(queue.dequeue())\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/rianojnicolas.py",
    "content": "###################################\n# Dev: rianojnicolas              #\n###################################\n\nfrom collections import deque\n\n# EJERCICIO:\n\n## Listas como Pilas - LIFO (last in first out)\ndef stackMethod(stack, action, element=None):\n    \"\"\"\n    Inputs:\n        stack: lista de elementos\n        action: accion a realizar \"push\"/\"pop\"/\"peek\"\n        element: elemento a insertar/eliminar/devolver ultimo elemento\n    Outputs:    \n        stack: lista de elementos\n    \"\"\"\n    if action == \"push\":\n        stack.append(element)\n        return stack\n    elif action == \"pop\":\n        stack.pop()\n        return stack\n    elif action == \"peek\":\n        return stack[len(stack)-1]\n\nprint(\"Prueba del metodo stack-LIFO\")\nmyStack = [1,2,3,4,5]\nprint(stackMethod(myStack, \"push\", 6))\nprint(stackMethod(myStack, \"pop\"))\nprint(stackMethod(myStack, \"peek\"))\n\n## Listas como Colas - FIFO (first in first out)\n\ndef queueMethod(queue, action, element=None):\n    \"\"\"\n    Inputs:\n        queue: lista de elementos\n        action: accion a realizar \"enqueue\"/\"dequeue\"/\"queue\"\n        element: elemento a insertar/eliminar/devolver primer elemento\n    Outputs:    \n        queue: lista de elementos\n    \"\"\"\n    if action == \"enqueue\":\n        queue.append(element)\n        return queue\n    elif action == \"dequeue\":\n        queue.popleft()\n        return queue\n    elif action == \"peek\":\n        return queue[0]\n\nprint(\"Prueba del metodo queue-FIFO\")\nmyQueue = deque([1,2,3,4,5])\nprint(queueMethod(myQueue, \"enqueue\", 6))\nprint(queueMethod(myQueue, \"dequeue\"))\nprint(queueMethod(myQueue, \"peek\"))\n\n\n# DIFICULTAD EXTRA\n\n# Web - LIFO\ndef webNavigation():\n    \"\"\"\n    Funcion que simula el navegador web \n    y realiza las acciones de ingreso de url, \n    adelante, atras y salida\n    \n    inputs: -\n    outputs:\n        print(url)\n    \"\"\"\n\n    print(\"\"\"\n\n            Hola, soy el navegador web y\n            Estas en la pagina principal\n            \n        \"\"\")\n    stack = []\n\n    while True:\n        \n        accion = input(\"Ingresa una accion (adelante/atras/salir): \")\n\n        if accion == \"adelante\":\n            url = input(\"Ingresa una url: \")\n            stack = stackMethod(stack, \"push\", url)\n        elif accion == \"atras\":\n            if len(stack) > 0:\n                stack = stackMethod(stack, \"pop\")\n            else:\n                pass\n        elif accion == \"salir\":\n            print(\"Saliendo del navegador\")\n            break\n        else:\n            print(\"Accion incorrecta\")\n            print(\"Opciones: adelante/atras/salir\")\n            pass\n        \n        if len(stack) == 0:\n            print(\"Estas en la pagina principal\")\n            pass\n        elif len(stack) > 0:\n            print(stackMethod(stack, \"peek\"))\n\n\nwebNavigation()\n\n\n# Impresora Compartida - FIFO\ndef printerShared():\n    \"\"\"\n    Funcion que simula la impresora compartida\n    y realiza las acciones de ingreso de documento, \n    impresion y salida\n    \n    inputs: -\n    outputs:\n        print(document)\n    \"\"\"\n\n    print(\"\"\"\n\n            Hola, soy la impresora compartida\n            \n        \"\"\")\n\n    queue = deque()\n\n    while True:\n\n        accion = input(\"Ingresa una accion (agregar/imprimir/salir): \")\n\n        if accion == \"agregar\":\n            document = input(\"Ingresa un documento: \")\n            queue = queueMethod(queue, \"enqueue\", document)\n        elif accion == \"imprimir\":\n            if len(queue) > 0:\n                print(\"Imprimiendo documento - \" + queueMethod(queue, \"peek\"))\n                document = queueMethod(queue, \"dequeue\")\n            else:\n                print(\"No hay documentos en la impresora\")\n                pass\n        elif accion == \"salir\":\n            print(\"Saliendo de la impresora\")\n            break\n        else:\n            print(\"Accion incorrecta\")\n            print(\"Opciones: imprimir/salir\")\n            pass\n\n\nprinterShared()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/rigo93acosta.py",
    "content": "'''\n/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n'''\n\n### Pila/Stack (LIFO) \n## List in Python is a stack\nstack = []\nstack.append(\"1\") # push\nstack.append(\"2\") # push\nstack.append(\"3\") # push\nprint(stack)\nelement = stack.pop() # pop\nprint(element)\nprint(stack)\n\n### Cola/Queue (FIFO)\nqueue = []\n#enqueue\nqueue.append(\"1\") \nqueue.append(\"2\") \nqueue.append(\"3\") \nprint(queue)\n#dequeue\nelement = queue.pop(0)\nprint(element)\nprint(queue)\n\n## EXTRA\n### EXTRA 1\n\ndef web_navegation():\n    \n    stack = []\n\n    while True:\n\n        action = input(\n            \"Añade una url o interactúa con palabras adelante/atrás/salir: \"\n            )\n        \n        if action == 'salir':\n            print('Saliendo del navegador web.')\n            break \n        elif action == 'adelante': # El stack no podemos hacer\n            pass\n        elif action == \"atrás\":\n            if len(stack) > 0:\n                stack.pop()\n        else:\n            stack.append(action)\n        \n        if len(stack) > 0:\n            print(f\"Has navegado a la web: {stack[len(stack) - 1]}\")\n        else:\n            print(\"Estás en la página de inicio.\")\n\n#web_navegation()\n\n### EXTRA 2\ndef online_printer():\n    queue = []\n\n    while True:\n        action = input(\"Añade documento o selecciona imprimir/salir: \")\n\n        if action == \"imprimir\":\n            if len(queue) > 0:\n                print(f\"Imprimiendo documento '{queue.pop(0)}'\")\n            else:\n                print(\"No hay documento en cola.\")\n        elif action == \"salir\":\n            print(\"Apagando la impresora LOL!!!\")\n            break\n        else:\n            queue.append(action)\n\n        print(f\"Cola de Impresora {queue}\")\n\nonline_printer()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/santiagobailleres.py",
    "content": "'''EJERCICIO:\nImplementa los mecanismos de introducción y recuperación de elementos propios de las\npilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\no lista (dependiendo de las posibilidades de tu lenguaje).\n\nDIFICULTAD EXTRA (opcional):\n- Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n  de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n  que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n  Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n  el nombre de una nueva web.\n- Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n  impresora compartida que recibe documentos y los imprime cuando así se le indica.\n  La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n  interpretan como nombres de documentos.'''\n\n# Implementación de pilas y colas en Python\n# Pilas/stack: LIFO (Last In, First Out)\npila = []\n# push: añadir un elemento a la pila\npila.append(1)\npila.append(2)\npila.append(3)\npila.append(4)\npila.append(5)\nprint(pila)\n# pop: eliminar un elemento de la pila\npila.pop() \nprint(pila)\nprint(pila.pop()) # este método devuelve el elemento eliminado\nprint(pila)\nprint(pila.pop())\nprint(pila)\n\n# Colas/queue: FIFO (First In, First Out)\ncola = []\n# enqueue: añadir un elemento a la cola\ncola.append(1)\ncola.append(2)\ncola.append(3)\ncola.append(4)\ncola.append(5)\nprint(cola)\n# dequeue: eliminar un elemento de la cola\ncola.pop(0) # pop(0) elimina el primer elemento de la lista\nprint(cola)\nprint(cola.pop(0)) # este método devuelve el elemento eliminado\nprint(cola)\n\n# EXTRA \n'''- Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n  de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n  que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n  Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n  el nombre de una nueva web.\n- Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n  impresora compartida que recibe documentos y los imprime cuando así se le indica.\n  La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n  interpretan como nombres de documentos.'''\n\n# Navegador web\ndef web_browser():\n    stack = []\n\n    while True:\n\n        action = input(\n            \"Añade una url o interactúa con palabras adelante/atrás/salir: \"\n        )\n\n        if action == \"salir\":\n            print(\"Saliendo del navegador web.\")\n            break\n        elif action == \"adelante\":\n            pass\n        elif action == \"atrás\" or action == \"atras\":\n            if len(stack) > 0:\n                stack.pop()\n        else:\n            stack.append(action)\n\n        if len(stack) > 0:\n            print(f\"Has navegado a la web: {stack[len(stack) - 1]}.\")\n        else:\n            print(\"Estás en la página de inicio.\")\n\n#web_browser()\n\n# Impresora compartida\ndef printer():\n    queue = []\n    while True:\n        action = input(\"Ingrese el nombre de un documento o 'imprimir'/'salir': \")\n        if action == \"salir\":\n            print(\"Saliendo de la impresora...\")\n            break\n        elif action == \"imprimir\":\n            if len(queue) > 0:\n                print(f\"Imprimiendo documento: {queue[0]}.\")\n                queue.pop(0)\n            else:\n                print(\"No hay documentos en la cola.\")\n        else:\n            queue.append(action)\n        print(f\"Documentos en cola: {queue}\")\n\nprinter()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/santyjL.py",
    "content": "#07 - PILAS Y COLAS\n\"\"\"\n/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n\"\"\"\n\n# PILAS #\n\"\"\"\nlo que pasa con las pilas es que utilizan la siguiente idea 'Ultimo en entrar ,\nprimero en salir' lo que tambien se conoce como 'LIFO',para estructuras de datos\n\"\"\"\npila = []\n\n# Añadir elementos a la pila\npila.append(\"Plato1\")\npila.append(\"Plato2\")\npila.append(\"Plato3\")\n\n# Recuperar el elemento en la cima sin quitarlo\nelemento_en_cima = pila[-1]\n\n\n\nprint(\"Pila actual:\", pila)\nplato_retirado = pila.pop()# Sacar el elemento más reciente\nprint(\"Plato retirado:\", plato_retirado)\nprint(\"Pila después de retirar:\", pila)\nprint(\"Elemento en la cima de la pila:\", elemento_en_cima)\n\n# COLAS #\n\"\"\"\nlo que pasa con las colas es que utilizan la siguiente idea 'primero en entrar,\nprimero en salir' , lo que tambien se conoce como LIFO para estructuras de datos\n\"\"\"\n\n\ncola = []\n\ndef añadir(cola, item):\n    cola.append(item)\n\ndef retirar(cola):\n    if not len(cola) == 0:\n        return cola.pop(0)\n    else:\n        print(\"La cola está vacía.\")\n\nañadir(cola , \"plato1\")\nañadir(cola , \"plato2\")\nañadir(cola , \"plato3\")\n\nelemento_en_el_fondo = cola[0]\n\nprint(\"cola actual:\", cola)\nprint(\"Elemento en el fondo de la cola:\", elemento_en_cima)\n\ncola_tirada = retirar(cola)\nprint(\"Plato retirado:\", cola_tirada)\nprint(\"cola después de retirar:\", cola)\n\n\n\n# Simulación de Navegador Web\ndef simulador_navegador():\n    historial = []\n    pagina_actual = \"\"\n\n    while True:\n        comando = input(\"Ingresa un comando ('adelante', 'atrás' , 'el nombre de una web' o 'salir'): \")\n\n        if comando == \"adelante\":\n            if not len(historial) == 0:\n                pagina_actual = historial.pop()\n                print(f\"Navegando adelante a: {pagina_actual}\")\n            else:\n                print(\"No hay historial adelante.\")\n\n        elif comando == \"atras\":\n            if pagina_actual:\n                historial.append(pagina_actual)\n                print(f\"Navegando atrás a la página anterior.\")\n                pagina_actual = \"\"\n            else:\n                print(\"No hay historial atrás.\")\n\n        elif comando == \"salir\":\n            print(\"has salido\")\n            break\n\n        else:\n            if pagina_actual:\n                historial.append(pagina_actual)\n            pagina_actual = comando\n            print(f\"Navegando a la página: {pagina_actual}\")\n\ndef simulador_impresora():\n    cola_impresion = []\n\n    while True:\n        comando = input(\"Ingresa un comando ('imprimir' o el nombre de un documento): \")\n\n        if comando == \"imprimir\":\n            documento = retirar(cola_impresion)\n            if documento:\n                print(f\"Imprimiendo documento: {documento}\")\n            else:\n                print(\"No hay documentos para imprimir.\")\n\n        elif comando == \"salir\":\n            print(\"has salido\")\n            break\n        else:\n            añadir(cola_impresion, comando)\n            print(f\"Documento '{comando}' agregado a la cola de impresión.\")\n\n\nsimulador_navegador()\n\nsimulador_impresora()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/sarismejiasanchez.py",
    "content": "# #07 PILAS Y COLAS\n\n\"\"\"\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n\"\"\"\n# PILAS\n# https://docs.hektorprofe.net/python/colecciones-de-datos/pilas/\nprint(\"PILAS - Stacks LIFO (Last In First Out)\")\n\"\"\"\nSon colecciones de elementos ordenados que únicamente permiten dos acciones:\n\n- Añadir un elemento a la pila.\n- Sacar un elemento de la pila.\n\nLa peculiaridad es que el último elemento en entrar es el primero en salir. En inglés se conocen como estructuras LIFO (Last In First Out).\n\"\"\"\n# Las podemos crear como listas normales\nstack = [3, 5, 7, 9]\nprint(stack)\n\n# Añadir elementos al final con el append():\nstack.append(11)\nstack.append(13)\nprint(stack)    # [3, 5, 7, 9, 11, 13]\n\n# Para sacar los elementos utilizaremos el método pop(). \n# Al utilizar este método devolveremos el último elemento, pero también lo borraremos:\nprint(stack.pop())  # 13\nprint(stack)    # [3, 5, 7, 9, 11]\n\n# Si queremos trabajar con él deberíamos asignarlo a una variable:\nlast_value = stack.pop()\nprint(last_value)   # 11\n\n# Si vamos sacando elementos llegará un momento en que la pila estará vacía \n# y dará error porque no podrá sacar nada más:\nstack.pop()     # 9\nstack.pop()     # 7\nstack.pop()     # 5\nstack.pop()     # 3\n# stack.pop()     # IndexError: pop from empty list\nprint(stack)\n\n\n# COLAS\n# https://docs.hektorprofe.net/python/colecciones-de-datos/colas/\n# https://docs.python.org/es/3.8/library/queue.html\nprint(\"\\nCOLAS - Queue FIFO (First In First Out)\")\n\n\"\"\"\nSon colecciones de elementos ordenados que únicamente permiten dos acciones:\n\n- Añadir un elemento a la cola.\n- Sacar un elemento de la cola.\n\nLa peculiaridad es que el primer elemento en entrar es el primero en salir. En inglés se conocen como estructuras FIFO (First In First Out).\n\nLa mejor alternativa en Python para crear colas es usar el módulo queue\nhttps://docs.python.org/es/3.8/library/queue.html\n\"\"\"\n\nimport queue\n\n# Crear una cola\ncola = queue.Queue()\n\n# Agregar elementos\ndef agregar_elemento(cola, elemento):\n    cola.put(elemento)\n    print(f\"Elemento agregado a la cola: {elemento}\")\n\n# Recuperar elemmentos\ndef recuperar_elemento(cola):\n    try:\n        elemento = cola.get(timeout=1)  # Espera hasta 1 segundo para obtener un elemento\n        print(f\"Elemento recuperado de la cola: {elemento}\")\n        return elemento\n    except queue.Empty:\n        print(\"La cola está vacía, no hay elementos que recuperar.\")\n\n# Probar funciones\n# Agregar elementos a la cola\nagregar_elemento(cola, 1)\nagregar_elemento(cola, 2)\nagregar_elemento(cola, 3)\n\n# Recuperar elementos de la cola\nrecuperar_elemento(cola)  # 1\nrecuperar_elemento(cola)  # 2\nrecuperar_elemento(cola)  # 3\nrecuperar_elemento(cola)  # La cola está vacía, no hay elementos que recuperar.\n\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n* - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n*   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n*   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n*   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n*   el nombre de una nueva web.\n\"\"\"\nprint(\"\\nDIFICULTAD EXTRA\")\n\nprint(\"\\nSimular el mecanismo adelante/atrás de un navegador web\".upper())\n\n# Inicializar la pila para el historial y un índice para la posición actual\nhistorial = []      # Lista que actúa como pila para el historial de páginas visitadas\nindice_actual = -1  # Indica la posición actual en el historial (inicialmente no hay páginas visitadas)\n\ndef navegar(pagina):\n    # Ir a una nueva página.\n    global indice_actual  # Usamos la variable global\n    \n    # Verifica si el indice_actual es menor que la longitud del historial menos uno.\n    if indice_actual < len(historial) - 1:\n        # Si estamos en medio del historial y vamos a una nueva página, descartamos adelante\n        historial[indice_actual + 1:] = []  # Limpiar el historial hacia adelante\n    historial.append(pagina)  # Agregar nueva página al historial\n    indice_actual += 1  # Actualizar la posición\n    print(f\"Navegando a: {pagina}\")\n\ndef atras():\n    # Navegar hacia atrás en el historial.\n    global indice_actual  # Usamos la variable global\n    \n    # Comprueba si indice_actual es mayor que 0. \n    # Si es así, significa que hay una página anterior a la que puede navegar.\n    if indice_actual > 0:\n        # Decrementa indice_actual en uno para moverse hacia atrás en el historial.\n        indice_actual -= 1  # Mover hacia atrás\n        # Muestra el nombre de la página a la que ha retrocedido.\n        print(f\"Navegando a: {historial[indice_actual]}\")\n    else:\n        # Si no hay páginas anteriores, se muestra un mensaje indicando que no se puede retroceder.\n        print(\"No hay más páginas en el historial para ir hacia atrás.\")\n\ndef adelante():\n    # Navegar hacia adelante en el historial.\n    global indice_actual  # Usamos la variable global\n    \n    # Comprueba si indice_actual es menor que el último índice del historial. \n    # Esto indica que hay una página hacia adelante.\n    if indice_actual < len(historial) - 1:\n        indice_actual += 1 # Mover hacia adelante\n        # Muestra el nombre de la página a la que ha avanzado.\n        print(f\"Navegando a: {historial[indice_actual]}\")\n    else:\n        # Si no hay páginas hacia adelante, se muestra un mensaje indicando que no se puede avanzar.\n        print(\"No hay más páginas para avanzar.\")\n\n# Interacción con el usuario\n\n# Se usa un bucle while True para permitir que el usuario \n# siga interactuando con el simulador.\nwhile True:\n    # Se le pide al usuario que ingrese un comando. \n    # strip() elimina los espacios en blanco al principio y al final, y\n    # lower() convierte la entrada a minúsculas para que la comparación \n    # sea insensible a mayúsculas.\n    comando = input(\"Ingresa una página web, 'adelante', o 'atras' (o 'salir' para terminar): \").strip().lower()\n    \n    # Si el usuario ingresa 'salir', se imprime un mensaje y se rompe el bucle, \n    # terminando el programa.\n    if comando == \"salir\":\n        print(\"Saliendo del simulador del navegador\")\n        break\n    # Si el comando es 'atras', se llama a la función atras().\n    elif comando == \"atras\":\n        atras()\n    # Si el comando es 'adelante', se llama a la función adelante().\n    elif comando == \"adelante\":\n        adelante()\n    # Para cualquier otra entrada, se considera que es una nueva página, \n    # por lo que se llama a ir_a_pagina(comando).\n    else:\n        navegar(comando)\n\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n* - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n*   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n*   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n*   interpretan como nombres de documentos.\n\"\"\""
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/sorubadguy.py",
    "content": "import time\n\n\"\"\"\n*Pilas y Colas\n\"\"\"\n#*Pilas\n\npila = [1,2,3,4]\npila.append(5)\nprint(\"Pilas\\n\",pila) #Agrego elemento al final(LI)\npila.pop()\nprint(pila) #Quito el ultimo elemento agregado(FO)\n\n#*Colas\n\ncola = [1,2,3,4]\ncola.append(5) #agrego un elemento al final\nprint(\"Colas\\n\",cola)\ncola.pop(0) #quito el primer elemento \nprint(cola)\n\n\"\"\"\n!Extra\n\"\"\"\n\ndir_web = [\"www.twitch.tv\",\"www.twitch.tv/mouredev\",\"www.twitch.tv/mouredev/videos\",\"www.twitch.tv/mouredev/videos/2162695381\"]\n\ndef navegador(dir):\n    op = 1\n    pagina = 0\n    \n    while op != 0:\n        print(\"Ingrese la opcion deseada\")\n        print(\"1: pagina siguiente\")\n        print(\"2: Pagina anterior\")\n        print(\"0: Cerrar Navegador\")\n        op = input(\"Opcion: \")\n        match op:\n            case \"1\":\n                pagina = pagina_siguiente(dir, pagina)\n            case \"2\":\n                pagina = pagina_anterior(dir, pagina)\n            case \"0\":\n                print(\"El navegador se cerrara\")\n                break\n            case _:\n                print(\"opcion incorrecta\")\n\ndef pagina_anterior(dir: list, pag: int):\n    if(pag != 0):\n        pag -= 1\n        print(dir[pag])\n        return pag\n    else:\n        print(f\"Usted se encuentra en: {dir[pag]}, no quedan paginas anteriores\")\n\ndef pagina_siguiente(dir: list, pag: int):\n    print(dir, pag)\n    if(pag == len(dir)-1):\n        op_sitio = input(\"este es el ultimo sitio visitado, desea visitar otro? s/n:\\n\")\n        if (op_sitio == \"s\"):\n            dir.append(input(\"Ingrese el nuevo sitio:\\n\"))\n            pag += 1\n            print(dir[pag])\n            return pag\n    else:\n        pag += 1\n        print(dir[pag])\n        return pag\n            \nnavegador(dir_web)\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/switchdays.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n\"\"\"\n\n\n# Implementación de una pila (stack):\nclass Stack:\n    def __init__(self):\n        self.items = []\n\n    def push(self, item):\n        self.items.append(item)\n\n    def pop(self):\n        if self.items:\n            return self.items.pop()\n        else:\n            print(\"Pila vacía, no se puede extraer elementos.\")\n\n    def top_element(self):\n        if self.items:\n            return self.items[-1]\n        else:\n            print(\"Pila vacía.\")\n\n\n# Implementación de una cola (queue):\nclass Queue:\n    def __init__(self):\n        self.items = []\n\n    def enqueue(self, item):\n        self.items.append(item)\n\n    def dequeue(self):\n        if self.items:\n            return self.items.pop(0)\n        else:\n            print(\"Cola vacía, no se puede extraer elementos.\")\n            return None\n\n    def front_element(self):\n        if self.items:\n            return self.items[0]\n        else:\n            print(\"Cola vacía.\")\n            return None\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atras\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n\"\"\"\n\nclass NavegadorWeb:\n    def __init__(self):\n        self.pila_atras = []  \n        self.pila_adelante = []  \n        self.pagina_actual = \"PÁGINA DE INICIO\"\n\n    def visitar_pagina(self, nombre_pagina):\n        print(f\"Visitando la página: {nombre_pagina}\")\n        self.pila_atras.append(self.pagina_actual)\n        self.pagina_actual = nombre_pagina\n        self.pila_adelante = [] \n\n    def retroceder(self):\n        if self.pila_atras:\n            pagina_anterior = self.pila_atras.pop()\n            self.pila_adelante.append(self.pagina_actual)\n            self.pagina_actual = pagina_anterior\n            print(f\"Retrocediendo a la página: {pagina_anterior}\")\n        else:\n            print(\"No hay páginas anteriores para retroceder.\")\n\n    def avanzar(self):\n        if self.pila_adelante:\n            pagina_siguiente = self.pila_adelante.pop()\n            self.pila_atras.append(self.pagina_actual)\n            self.pagina_actual = pagina_siguiente\n            print(f\"Avanzando a la página: {pagina_siguiente}\")\n        else:\n            print(\"No hay páginas siguientes para avanzar.\")\n\n\nnavegador = NavegadorWeb()\nprint(\"Visitando la página: PAGINA DE INICIO\")\nfin = 0\n\nwhile fin < 5: # Vamos a dejar que se puedan realizar 5 acciones.\n\n    input_usuario = input(\"Ingrese una acción (adelante/atras) o el nombre de una página: \").lower()\n\n    if input_usuario == \"adelante\":\n        navegador.avanzar()\n        fin += 1\n    elif input_usuario == \"atras\":\n        navegador.retroceder()\n        fin += 1\n    else:\n        navegador.visitar_pagina(input_usuario)\n        fin += 1\n\n\n\"\"\"\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n\"\"\"\n\n\nclass Impresora:\n\n    def __init__(self):\n        self.documentos_cola = []\n\n    def recibir_documento (self, documento):\n        self.documentos_cola.append(documento)\n        print(f\"Se ha añadido el documento {documento} a la cola.\")\n\n    def imprimir(self):\n        if self.documentos_cola:\n            impreso = self.documentos_cola.pop(0)\n            print(f\"Se ha impreso el documento: {impreso}\")\n        else:\n            print(\"No hay documentos pendientes por imprimir.\")\n\nimpresora = Impresora()\nfin = 0\n\nwhile fin < 5: # Vamos a dejar que se puedan realizar 5 acciones.\n\n    input_usuario = input(\"Ingrese 'imprimir' si desea imprimir, o indique el nombre del documento que quiera imprimir: \").lower()\n\n    if input_usuario == \"imprimir\":\n        impresora.imprimir()\n        fin += 1\n    else:\n        impresora.recibir_documento(input_usuario)\n        fin += 1"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/thonys07.py",
    "content": "'''\n\nEJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n\n\n\n'''\npila = []\ndef insertar(elemento):\n    pila.append(elemento)\n    print(pila)\ndef extraer():\n    pila.pop()\n    print(pila)\ninsertar(1)\ninsertar(2)\ninsertar(3)\ninsertar(4)\ninsertar(5)\nextraer()\nprint(pila)\nqueue = []\ndef enqueue(elemento):\n    queue.append(elemento)\n    print(queue)\ndef dequeue():\n    queue.pop(0)\n    print(queue)\nenqueue(1)\nenqueue(2)\nenqueue(3)\nenqueue(4)\nenqueue(5)\ndequeue()\nprint(queue)\n\n#EXTRAAAAA\n\"\"\"\n* - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n\"\"\"\ndef navegacion():\n    page = \"\"\n    stack=[]\n \n    while True:\n        navegar = input(\"Indique la URL a la que desea navegar, adelante, atras o salir: \")\n        if navegar == \"adelante\":\n           if len(stack) == 0:\n               print(\"No hay historial adelante\")\n           else:\n               page = stack.pop()\n               print(f\"Navegando hacia {page}\")\n        elif navegar == \"atras\":\n            if len(stack)==0:\n               print(\"No hay historial atrás\")\n            else:\n             stack.append(page)\n             page = stack.pop()\n             print(f\"Navegando hacia {page}\")          \n        elif navegar == \"salir\":\n            break\n        else:\n            stack.append(page)\n            page=navegar\n            print(f\"Navegando hacia {page}\")\n\ndef imprimir():\n    stack=[]\n \n    while True:\n        imprimir = input(\"Indique i para imprimir, s para salir, o el \")\n        if imprimir == \"i\" | \"I\":\n           if len(stack) == 0:\n               print(\"No hay historial para imprimir. \")\n           else:\n               imprimiendo = stack.pop(0)\n               print(f\"Imprimiendo: {imprimiendo}\")\n        elif imprimir == \"s\" | \"S\":\n            break\n            \n        else:\n            stack.append(imprimir)\n        \n        print(f\"lista de impresion: {stack}\")\n\n\nnavegacion()\nimprimir()\n\n\n\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/tito-delpino.py",
    "content": "\n#  * EJERCICIO:\n#  * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n#  * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n#  * o lista (dependiendo de las posibilidades de tu lenguaje).\n\n# pilas\nlista = [1,2,3]\nprint(lista)\nelemento = lista.pop() # la funcion pop extrae el ultimo elemento que entro en la pila\nprint(lista)\nprint(elemento)\n\n# colas\nlista = [1,2,3]\nprint(lista)\nelemento = lista.pop(0) # la funcion pop indicando el indice que queremos eliminar de la cola\nprint(lista)\nprint(elemento)\n\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n#  *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n#  *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n#  *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n#  *   el nombre de una nueva web.\n\ndef navigation():\n    historial = []\n\n    while True:\n\n        accion = input(\"Agrega una URL o si quieres desplazarte adelante/atras/salir: \")\n        if accion == 'salir':\n            print(\"Saliendo del programa\")\n            break\n        elif accion == 'adelante':\n            pass\n        elif accion == \"atras\":\n            if len(historial) > 0:\n                historial.pop()\n        else:\n            historial.append(accion)\n\n        if len(historial) > 0:\n            print(f'Pagina actual {historial[len(historial)-1]}')\n        else:\n            print('Estas en la pagina de inicio')\n        \n\nnavigation()\n\n\n#  * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n#  *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n#  *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n#  *   interpretan como nombres de documentos.\n\ndef impresora():\n    cola_impresion = []\n    while True:\n        instruccion = input(\"Agrega un documento a la cola de impresion, o indica si quieres imprimir o salir: \")\n\n        if instruccion == 'imprimir':\n            if len(cola_impresion) >= 1:\n                print(f'imprimiendo documento: {cola_impresion[0]}')\n                cola_impresion.pop(0)\n            else:\n                print('no quedan documentos en cola')\n        elif instruccion == 'salir':\n            break\n        else:\n            cola_impresion.append(instruccion)\n\n        if len(cola_impresion) >= 1:\n            print('Documentos en cola')\n            for doc in cola_impresion:\n                print(doc)\n\nimpresora()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/toral24.py",
    "content": "'''\nEJERCICIO:\nImplementa los mecanismos de introducción y recuperación de elementos propios de las\npilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\no lista (dependiendo de las posibilidades de tu lenguaje).\n\nDIFICULTAD EXTRA (opcional):\n\nUtilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\nde un navegador web. Crea un programa en el que puedas navegar a una página o indicarle que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\nLas palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como el nombre de una nueva web.\nUtilizando la implementación de cola y cadenas de texto, simula el mecanismo de una impresora compartida que recibe documentos y los imprime cuando así se le indica.\nLa palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se interpretan como nombres de documentos.\n'''\n\ndef lifo():\n    lista = []\n    action = \"\"\n    while action != \"S\":\n        action = input(\"Introduce la acción que quieres realizar (I: para insertar, E: para extraer, S: para salir) \")\n        action = action.upper()\n        if action == \"I\":\n            nuevo = input(\"Introduce el parametro que quieres insertar \")\n            lista.append(nuevo)\n        elif action == \"E\":\n            print(lista[-1])\n            lista.pop()\n        else:\n            print(\"no se ha introducido una letra valida\")\n    print(f'lista final: {lista}')\n\nlifo()\n\ndef fifo():\n    lista = []\n    action = \"\"\n    while action != \"S\":\n        action = input(\"Introduce la acción que quieres realizar (I: para insertar, E: para extraer, S: para salir )\")\n        action = action.upper()\n        if action == \"I\":\n            nuevo = input(\"Introduce el parametro que quieres insertar \")\n            lista.append(nuevo)\n        elif action == \"E\":\n            print(lista[0])\n            lista.pop(0)\n        else:\n            print(\"no se ha introducido una letra valida\")\n    print(f'lista final: {lista}')\n\nfifo()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/victorfer69.py",
    "content": "#Pila (LIFO)\n\nstack = []\nstack.append(\"1\")\nstack.append(\"2\")\nstack.append(\"3\")\nprint(stack)            #Inicializamos la pila\n\nstack.pop()             #Sacar un item de la pila (el último que se añadió)\nprint(stack)\n\n#Cola (FIFO)\n\nqueue = []\nqueue.append(\"1\")\nqueue.append(\"2\")\nqueue.append(\"3\")\nprint(queue)            #Iniciar la cola\n\nqueue.pop(0)         #Sacar un item de la cola (el primero que se añadió)\nprint(queue)\n\n\n#EJERCICIO EXTRA\n\ndef web_navegation():\n\n    stack = []\n\n    while True:\n\n        action = input(\"Añade una url o interactúa con palabras adelante/atras/salir: \")\n\n        match action:\n            case \"adelante\":\n                #Como la página web no es una pila, entonces no hay operacion de adelante\n                pass\n            case \"atras\":\n                if(len(stack) > 0):\n                    stack.pop()\n                else:\n                    print(\"Añade una URL para poder navegar\")\n            case \"salir\":\n                print(\"Hasta la próxima\")\n                break\n            case _:\n                stack.append(action)\n\n        if len(stack) > 0:\n            print(\"Estas en la web \" + stack[len(stack)-1])\n        else:\n            print(\"Estas en la página de inicio\")\n\nweb_navegation()\n\n\ndef printer():\n\n    queue = []\n\n    while True:\n\n        action = input(\"Añade un documento o interactúa con palabras imprimir/salir: \")\n\n        match action:\n            case \"imprimir\":\n                if len(queue) > 0:\n                    print(f\"Imprimiendo: {queue.pop(0)}\")\n                else:\n                    print(\"No hay documentos en la impresora\")\n            case \"salir\":\n                print(\"Hasta la próxima\")\n                break\n            case _:\n                queue.append(action)\n                print(\"Documento añadido\")\n\nprinter()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/warclimb.py",
    "content": "\"\"\"\n* EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atras\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n \"\"\"\n from collections import deque\n\n# Implementamos las pilas y colas\n# impelemntacion como pila\npila = []\npila.append(\"fuego\") # añadimos fuego a la pila\npila.pop(\"fuego\") # sacamos fuego de la pila\n\n# implementacion como cola\ncola = []\n\ndef enqueue(element):\n    cola.append(element)\n\ndef dequeue():\n    if len(cola) > 0:\n        return cola.pop(0)\n    else:\n        return None\n\n# añadimos a la cola:\nenqueue(\"fuego\")  # añadimos fuego a la cola\ndequeue()  # sacamos fuego de la cola\n\n# Extra: Simulamos el mecanismo adelante/atrás de un navegador web\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/worlion.py",
    "content": "# EJERCICIO 07 - PILAS Y COLAS (by Worlion)\n\n# Pila (stack)\nstack = []\n\ndef initialize_stack():\n    stack = []\n\ndef push(item):\n    stack.append(item)\n\ndef pop():\n    if(len(stack) == 0):\n        raise Exception(\"Empty stack :(\")\n    # return item = stack.pop()      ¯\\_(ツ)_/¯ \n    item = stack[len(stack)-1]\n    del stack[len(stack)-1]\n    return item;\n    \nprint(\"Jugando con la pila...\")\nprint(\"Añado 4 valores\")\npush(3)     \npush(65)        \npush(1)     \npush(99)        \nprint(f\"Stack: {stack}\")\n\nprint(\"elimino el primero: \")\nprint(f\"pop: {pop()}\")\nprint(f\"Stack: {stack}\")\nprint(\"elimino otro: \")\nprint(f\"pop: {pop()}\")\nprint(f\"Stack: {stack}\")\nprint(f\"pop: {pop()}\")\n# print(f\"Stack: {stack}\")\n# print(f\"pop: {pop()}\")\n# print(f\"Stack: {stack}\")\n# print(f\"pop: {pop()}\")\n# print(f\"Stack: {stack}\")\n\n# Cola (queue)\nqueue = []\n\ndef put(item):\n    queue.append(item)\n\ndef get():\n    if(len(queue) == 0):\n        raise Exception(\"Empty queue :(\")\n    item = queue[0]\n    del queue[0]\n    return item;\n\nprint(\"Jugando con la cola...\")\nprint(\"Añado 4 valores\")\nput(\"a\")     \nput(\"b\")     \nput(\"c\")     \nput(\"d\")     \n        \nprint(f\"Queue: {queue}\")\n\nprint(\"elimino el primero: \")\nprint(f\"get: {get()}\")\nprint(f\"Queue: {queue}\")\nprint(\"elimino otro: \")\nprint(f\"get: {get()}\")\nprint(f\"Queue: {queue}\")\nprint(f\"get: {get()}\")\nprint(f\"Queue: {queue}\")\nprint(f\"get: {get()}\")\nprint(f\"Queue: {queue}\")\n# print(f\"get: {get()}\") # Daría excepcion\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n\"\"\"\n# Pintar de colores... para el menú ^_^ \ndef red(skk): print(\"\\033[91m {}\\033[00m\" .format(skk))\ndef grey(skk): print(\"\\033[97m {}\\033[00m\" .format(skk))\ndef green(skk): print(\"\\033[92m {}\\033[00m\" .format(skk))\n\nprint(\"\\n ---- 🌩 DIFICULTAD EXTRA 🌩 ----\\n\")\n\ndef navegador():\n\n    back_history = []\n    forward_history = []\n    \n    def navegar(page):\n        \n        forward_history.clear()\n        back_history.append(page)\n        \n    def adelante():\n        if(len(forward_history) == 0):\n            print(\"No se puede ir hacia adelante\")\n            return\n        # pop adelante y push atrás\n        back_history.append(forward_history.pop())\n        \n    def atras():\n        if(len(back_history) == 1):\n            print(\"No se puede ir hacia atrás, estás en inicio.\")\n            return\n        # pop adelante y push atrás\n        forward_history.append(back_history.pop())\n\n    def print_menu():\n        print(f\"\\n\\n\\n -Página actual: '{back_history[len(back_history)-1]}'\")\n        print(\"\\nElija una opción o escriba la url a la que quiere navegar:\")\n        \n        if(len(forward_history) == 0):\n            grey(\"\\t - 1: Adelante\")\n        else: \n            green(\"\\t - 1: Adelante\")\n            \n        if(len(back_history) == 1):\n            grey(\"\\t - 2: Atrás\")\n        else:   \n            green(\"\\t - 2: Atrás\")\n        red(\"\\t - 0: Salir\")\n        return input(\"¿qué desea hacer?\")\n    \n    finish = False\n    \n    navegar(\"Inicio\")\n    \n    while not finish :\n        action = print_menu()\n        if(action == \"1\" or  action.upper() == \"ADELANTE\" ):\n            adelante()\n        elif(action == \"2\" or  action.upper() == \"ATRÁS\"  or  action.upper() == \"ATRAS\" ):\n            atras()\n        elif(action == \"0\" or  action.upper() == \"SALIR\" ):\n            finish = True\n            print (\"exit...\")\n        else:\n            print(f\"navegar a {action}\")\n            navegar(action)\n                \nnavegador()\n\n# Impresora\n\ndef impresora():\n    \n    option = 1\n    \n    impresora = []\n    \n    def put_impresora(doc_name):\n        impresora.append(doc_name)\n    \n    def get_impresora():\n        if(len(impresora) == 0):\n            red(\"Cola vacía, no hay nada que imprimir.\")\n            return\n        document = impresora[0]\n        del impresora[0]\n        green(f\"Imprimiendo documento: '{document}'\")\n    \n    def print_option_2():\n        msg = \"\\t - Escriba 'Imprimir' para comenzar la impresión'\"\n        if(len(impresora) == 0):\n            grey(msg)\n        else:\n            green(msg)\n    \n    def show_menu_impresora() -> str:\n        print(\"\\nOpciones: \")\n        green(\"\\t - Escriba el nombre del documento\")\n        print_option_2()\n        red(\"\\t - Escriba 'Salir' o '0' para salir de la aplicación'\")\n        return input(\"\\n\\t > \")\n    \n    def process_option(option: str):\n        if option == \"0\" or option.upper() == \"SALIR\":\n            return \"0\"\n        elif option.upper() == \"IMPRIMIR\":\n            get_impresora()\n        else:\n            put_impresora(option)\n        return 1\n    \n    while(option != \"0\"):\n        print(f\"\\n\\n\\nCola de impresión: {impresora}\")\n        option = process_option(show_menu_impresora())\n    \nimpresora()\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/xemita007.py",
    "content": "\"\"\"ejercicio\"\"\"\n\n#pila\nvar=[]\n\n\ndef añadir(elmento):\n    var.append(elmento)\n    print(f\"Elemento añadido {elmento} a la lista\")\n\ndef eliminar():\n    ele_list= var[len(var)-1]\n    del var[len(var)-1]\n    print(f\"Elemento eliminadao {ele_list} de la lista\")\n    \n\n\nañadir(1)\nañadir(2)\nañadir(3)\nañadir(4)\neliminar()\neliminar()\neliminar()\neliminar()\n\n#cola\nvar=[]\n\n\ndef añadir(elmento):\n    var.append(elmento)\n    print(f\"Elemento añadido {elmento} a la lista\")\n\ndef eliminar():\n    ele_list= var[0]\n    var.pop(0)\n    print(f\"Elemento eliminadao {ele_list} de la lista\")\n    \n\n\nañadir(1)\nañadir(2)\nañadir(3)\nañadir(4)\neliminar()\neliminar()\neliminar()\neliminar()\n\n\"\"\"\n#Extra\n\"\"\"\"\"\ndef navegador():\n    \n    var=[]\n\n    while True:   \n        web=input(\"buscar, para introducir la paguina a la que desea navegar, para ir hacia atras escribir atras,\"\n                \"y para volver: adelante , para salir pulse salir\")\n        \n        if web== \"salir\":\n            print(\"Saliendo del navegador web.\")\n            break\n    \n        elif web== \"atras\":\n            if len(var) > 0 :\n                ele_list= var[len(var)-1]\n                var.pop()\n                print(f\" retrocediendo a  {var[len(var) - 1]} \")\n\n            else:\n                print(\"Estas en la paguina de inicio\")\n        \n        elif  web== \"adelante\":\n            pass\n\n        else:\n            var.append(web)\n            print(f\"Has navegado a la web: {var[len(var) - 1]}.\")\n\nnavegador()\n\ndef cola_impresion():\n\n    var=[]\n\n    while True:\n        screem=input(\"introducir documentos a imprimir, para imprimir pulse , imprimir y para salir , salir \")\n        \n        if screem== \"salir\":\n            print(\"Saliendo de la impresión\")\n            break\n    \n        elif screem== \"imprimir\":\n            if len(var) > 0 :\n                print(f\" imprimiendo  {var[0]} \")\n                var.pop(0)\n                if len(var) > 0:\n                    print(f\"siguiente hoja de impresión {var[0]}\")\n                else:\n                    print(\"No hay más documentos para imprimir.\")\n\n            else:\n                print(\"no existen documentos\")\n        \n        else:\n            var.append(screem)\n            print(f\"Has añadido el documento a la cola de impresión: {var[len(var) - 1]}.\")\n\ncola_impresion()\n\n\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/ycanas.py",
    "content": "import time\n\n# ------ Ejercicio\n\n# 1. Pilas\n\nclass Stack:\n\n    # Stack Data Structure\n\n    def __init__(self):\n        self.stack = []\n\n    def isempty(self):\n        return self.stack == []\n\n    def push(self, item):\n        self.stack.append(item)\n\n    def pop(self):\n        return self.stack.pop()\n\n    def top(self):\n        return self.stack[-1]    \n    \n    def size(self):\n        return len(self.stack)\n\n\nmy_stack = Stack()\nprint(\"Empty ?\", my_stack.isempty())\n\nmy_stack.push('A')\nmy_stack.push('B')\nmy_stack.push('C')\nprint(\"Top:\", my_stack.top())\n\nprint(\"Pop:\", my_stack.pop())\nprint(\"Top:\", my_stack.top())\n\nprint(\"Size:\", my_stack.size())\nprint()\n\n# 2. Colas\n\nclass Queue:\n\n    # Queue Data Structure\n\n    def __init__(self):\n        self.queue = []\n\n    def isempty(self):\n        return self.queue == []\n    \n    def push(self, item):\n        self.queue.append(item)\n\n    def pop(self):\n        return self.queue.pop(0)\n    \n    def top(self):\n        return self.queue[0]\n    \n    def size(self):\n        return len(self.queue)\n        \n\nmy_queue = Queue()\nprint(\"Empty ?\", my_queue.isempty())\n\nmy_queue.push('A')\nmy_queue.push('B')\nmy_queue.push('C')\nprint(\"Top:\", my_queue.top())\n\nprint(\"Pop:\", my_queue.pop())\nprint(\"Top:\", my_queue.top())\n\nprint(\"Size:\", my_queue.size())\nprint()\n\n\n# ------ Extra\n\n# 1. Navegador\n\ndef webpage():\n    stack = [\"htts://ycanas.com\"]\n\n    while True:\n        print()\n        action = input(f\"Ingrese el subdominio de la url al que quiere ingresar [{stack[0]}] o (atras/salír): \")\n        action = action.lower()\n\n        if action == \"adelante\":\n            pass\n\n        elif action == \"atras\":\n            if len(stack) > 1:\n                stack.pop()\n        \n        elif action == \"salir\":\n            print(\"* Saliendo del navegador...\")\n            break\n\n        else:\n            stack.append(action)\n\n        print(\"*\", \"/\".join(stack))\n\n\nwebpage()\nprint()\n\n# 2. Impresora\n\ndef printer():\n    queue = []\n\n    while True:\n        print()\n        action = input(\"Cargue un documento o (imprimir/salír): \")\n        action = action.lower()\n\n        if action == \"salir\":\n            print(\"* Apagando impresora...\")\n            break\n\n        elif action == \"imprimir\":\n            if not queue == []:\n                print(f\"* Imprimiendo {queue.pop(0)}\")\n                time.sleep(1.5)\n                print(\"* Impresión terminada...\")\n\n        else:\n            queue.append(action)\n\n\nprinter()\nprint()\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/yenneralayon142.py",
    "content": "\"\"\"\nPILAS Y COLAS\n\"\"\"\n#PILA / STACK (LIFO)\nlist_one = []\n#PUSH (Agregar)\nlist_one.append(1)\nlist_one.append(2)\nlist_one.append(3)\nprint(list_one)\n\n#POP (Eliminar)\n#del list_one(len(list_one - 1))  Hacerlo manualmente\nprint(list_one.pop())\nprint(list_one)\n\n#COLA/QUEUE(FIFO)\nlist_two= []\n# enqueue\nlist_two.append(1)\nlist_two.append(2)\nlist_two.append(3)\nprint(list_two)\n# dequeue\nprint(list_two.pop(0))\nprint(list_two)\n\n\n\"\"\"\nExtra\n\"\"\"\n\n#Navegador web\n\ndef navigation():\n\n    list_three = []\n\n    while True:\n        action = input(\n            \"Añade una url o interactua con palabras adelante/atrás/salir\"\n        )\n        if action == \"salir\":\n            print(\"saliendo del navegador web\")\n            break\n        elif action == \"adelante\":\n            pass\n        elif action == \"atrás\":\n            if len(list_three) > 0:\n                list_three.pop()\n        else:\n            list_three.append(action)\n\n        if len(list_three) > 0:\n            print(f\"Has navegado a la web {list_three[len(list_three) - 1]}.\")\n        else:\n            print(\"Estas en la pagina de inicio\")\n\nnavigation()\n\n\n#Impresora\n\ndef printed():\n\n    queue = []\n    while True:\n        action = input(\"Añade un documento o selecciona imprimir/salir: \")\n        if action == \"salir\":\n            break\n        elif action == \"imprimir\":\n            if len(queue) > 0:\n                print(f\"Imprimiendo {queue.pop(0)}.\")\n        else:\n            queue.append(action)\n\n        print(f\"Cola de impresión:{queue}\")\nprinted()\n\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/yoezequiel.py",
    "content": "class Stack:\n    def __init__(self):\n        self.items = []\n\n    def is_empty(self):\n        return len(self.items) == 0\n\n    def push(self, item):\n        self.items.append(item)\n\n    def pop(self):\n        if not self.is_empty():\n            return self.items.pop()\n        else:\n            print(\"La pila está vacía\")\n\n    def peek(self):\n        if not self.is_empty():\n            return self.items[-1]\n        else:\n            print(\"La pila está vacía\")\n\n    def size(self):\n        return len(self.items)\n\n\nclass Queue:\n    def __init__(self):\n        self.items = []\n\n    def is_empty(self):\n        return len(self.items) == 0\n\n    def enqueue(self, item):\n        self.items.append(item)\n\n    def dequeue(self):\n        if not self.is_empty():\n            return self.items.pop(0)\n        else:\n            print(\"La cola está vacía\")\n\n    def size(self):\n        return len(self.items)\n\n\ndef navegador():\n    historial = Stack()\n    actual = \"\"\n\n    while True:\n        comando = input(\"Ingrese 'adelante', 'atrás' o el nombre de una página web: \")\n\n        if comando == \"adelante\":\n            if not historial.is_empty():\n                actual = historial.pop()\n                print(\"Navegando adelante a:\", actual)\n            else:\n                print(\"No hay más páginas hacia adelante\")\n        elif comando == \"atrás\":\n            if actual != \"\":\n                historial.push(actual)\n                print(\"Navegando atrás desde:\", actual)\n                actual = \"\"\n            else:\n                print(\"No hay más páginas hacia atrás\")\n        else:\n            if actual != \"\":\n                historial.push(actual)\n            actual = comando\n            print(\"Navegando a:\", actual)\n\n\nnavegador()\n\n\ndef navegador():\n    historial = Stack()\n    actual = \"\"\n\n    while True:\n        comando = input(\"Ingrese 'adelante', 'atrás' o el nombre de una página web: \")\n\n        if comando == \"adelante\":\n            if not historial.is_empty():\n                actual = historial.pop()\n                print(\"Navegando adelante a:\", actual)\n            else:\n                print(\"No hay más páginas hacia adelante\")\n        elif comando == \"atrás\":\n            if actual != \"\":\n                historial.push(actual)\n                print(\"Navegando atrás desde:\", actual)\n                actual = \"\"\n            else:\n                print(\"No hay más páginas hacia atrás\")\n        else:\n            if actual != \"\":\n                historial.push(actual)\n            actual = comando\n            print(\"Navegando a:\", actual)\n\n\nnavegador()\n\n\ndef impresora():\n    documentos = Queue()\n\n    while True:\n        comando = input(\"Ingrese 'imprimir' o el nombre de un documento: \")\n\n        if comando == \"imprimir\":\n            if not documentos.is_empty():\n                print(\"Imprimiendo:\", documentos.dequeue())\n            else:\n                print(\"No hay documentos en la cola para imprimir\")\n        else:\n            documentos.enqueue(comando)\n            print(\"Documento agregado a la cola:\", comando)\n\n\nimpresora()\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/python/zetared92.py",
    "content": "# Reto #07 PILAS Y COLAS\n\n\"\"\" Pilas o Stacks: principio LI-FO (Last in First Out) -> último en entrar,\nprimero en salir.\"\"\"\n\nstack = []\n\n# Push\nstack.append(1)\nstack.append(2)\nstack.append(3)\nprint(stack)\n\n# Pop\nstack_item = stack[len(stack) - 1]\ndel stack[len(stack) - 1]\nprint(stack_item)\n\nprint(stack.pop())\n\nprint(stack)\n\n\"\"\" Colas o Queue: principio FI-FO (First In-First Out) -> primero en entrar,\nprimero en salir.\"\"\"\n\nqueue = []\n\n# Enqueue\nqueue.append(1)\nqueue.append(2)\nqueue.append(3)\n\nprint(queue)\n\n# Dequeue\nqueue_item = queue[0]\ndel queue[0]\nprint(queue_item)\n\nprint(queue.pop(0))\n\nprint(queue)\n\n\n# Extra\n\nprint(\"🧩 DIFICULTAD EXTRA - SIMULADOR DE NAVEGADOR WEB🧩\")\ndef web_nav():\n    stack = []\n\n    while True:\n\n        action = input(\n            \"Input your URL\"\n        )\n        if action == \"exit\":\n            print(\"Exit...\")\n            break\n        elif action == \"forward\":\n            pass\n        elif action == \"back\":\n            if len(stack) > 0:\n                stack.pop()\n        else:\n            stack.append(action)\n        if len(stack) > 0:\n            print(f\"You're in the {stack[len(stack) - 1]} web.\")\n        else:\n            print(\"You're in Home page.\")\nweb_nav()\n\nprint(\"🧩 DIFICULTAD EXTRA - SIMULADOR DE IMPRESORA🧩\")\n\ndef shared_printed():\n    queue = []\n    while True:\n\n        action = input(\"Add a doc o select print/exit: \")\n\n        if action == \"exit\":\n            break\n        elif action == \"print\":\n            if len(queue) > 0:\n                print(f\"Printing: {queue.pop(0)}\")\n        else:\n            queue.append(action)\n        print(f\"Print spooler: {queue}\")\n\nshared_printed()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/ruby/kodenook.rb",
    "content": "=begin\n    Stacks\n=end\n\nletters = ['a', 'b', 'c', 'd']\n\n=begin\n    Insert\n=end\n\nletters.unshift('e')\nletters.unshift('f')\n\nputs letters\nputs\n\n=begin\n    Delete\n=end\n\nletters.shift()\n\nputs letters\n\n=begin\n    Queue\n=end\n\nletters = ['a', 'b', 'c', 'd']\n\n=begin\n    Insert\n=end\n\nletters.push('e')\nletters.push('f')\n\nputs\nputs letters\nputs\n\n=begin\n    Delete\n=end\n\nletters.pop()\n\nputs letters\n\n=begin\n    Exercise\n=end\n\ndef webNavigation()\n\n    stack = []\n    option = ''\n\n    while option.strip != 'exit'\n        puts 'give a url or next, before, exit'\n        option = gets\n\n        case option.chomp\n            when 'next'\n            when 'before'\n                stack.shift()\n                puts 'you are in %s' % stack.first()\n            else\n                stack.unshift(option)\n                puts 'you are in %s' % stack.first()\n            end\n    end\nend\n\nwebNavigation()\n\ndef sharedPrint()\n    queue = []\n    option = ''\n\n    while option.strip != 'exit'\n        puts 'give a document or print, exit'\n        option = gets\n\n        case option.chomp\n            when 'print'\n                document = queue.shift()\n                puts 'you printed %s' % document\n            else\n                queue.push(option)\n            end\n    end\nend\n\nsharedPrint()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/rust/brockar.rs",
    "content": "use std::io;\nfn main() {\n    let mut array: Vec<i32> = vec![1, 2, 3];\n    println!(\"pila: {:?}\", array);\n    pila_agregar(&mut array, 4);\n    println!(\"pila_agregar, (4): {:?}\", array);\n\n    println!(\n        \"pila_quitar, quita {}, la pila queda: {:?}\",\n        pila_quitar(&mut array),\n        array\n    );\n\n    println!(\"cola: {:?}\", array);\n    cola_agregar(&mut array, 5);\n    println!(\"cola_agregar, (5): {:?}\", array);\n\n    let ultimo_valor = cola_quitar(&mut array);\n    println!(\n        \"cola_quitar, quita {}, la cola queda: {:?}\",\n        ultimo_valor, array\n    );\n\n    println!(\"Presiona Enter para empezar con las funciones extras\");\n    let mut input = String::new();\n    io::stdin().read_line(&mut input).expect(\"Error de lectura\");\n    clear_terminal().expect(\"Error al limpiar\");\n    extra1();\n    extra2();\n}\n\nfn pila_agregar(vector: &mut Vec<i32>, add: i32) {\n    vector.push(add);\n}\n\nfn pila_quitar(vector: &mut Vec<i32>) -> i32 {\n    vector.pop().unwrap()\n}\n\nfn cola_agregar(vector: &mut Vec<i32>, add: i32) {\n    vector.push(add);\n}\n\nfn cola_quitar(vector: &mut Vec<i32>) -> i32 {\n    vector.remove(0)\n}\n\nuse std::io::Write;\nfn clear_terminal() -> io::Result<()> {\n    // Enviamos el escape code para limpiar la pantalla y colocar el cursor en la esquina superior izquierda\n    print!(\"\\x1B[2J\\x1B[1;1H\");\n    io::stdout().flush()?;\n\n    Ok(())\n}\n\nfn extra1() {\n    /*\n        Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n        de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n        que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n        Las palabras \"adelante\", \"atras\" desencadenan esta acción, el resto se interpreta como\n        el nombre de una nueva web.\n    */\n    let mut historial: Vec<String> = Vec::new();\n    let mut historial1: Vec<String> = Vec::new();\n    let mut cadena: String = String::new(); // cadena = pagina actual\n    let mut comando = String::new();\n    loop {\n        println!(\"-----------\");\n        println!(\"| EXTRA 1 |\");\n        println!(\"-----------\");\n        if !comando.is_empty() {\n            println!(\"{}\", comando);\n            println!(\"----------------------------\");\n        }\n        println!(\"Pagina actual: {}\", cadena);\n\n        println!(\"----------------------------\");\n        println!(\n            \"Historial: {:?} \\nHistorialAdelante: {:?}\",\n            historial, historial1\n        );\n        println!(\"----------------------------\");\n        println!(\n                \"\\\"adelante\\\" para cambiar a una nueva pagina\\n\\\"atras\\\" para ir a la página anteriores\\n\\\"nombre-web\\\" para agregar una web\\n\\\"salir\\\" para cerrar el programa\"\n            );\n        comando = String::new();\n        std::io::stdin().read_line(&mut comando).unwrap();\n        comando = comando.trim().to_string();\n\n        match comando.as_str() {\n            \"atras\" => {\n                if !historial.is_empty() {\n                    if historial.len() > 1 {\n                        pila_quitar_s(&mut historial);\n                    }\n\n                    pila_agregar_s(&mut historial1, cadena.clone());\n                    cadena = pila_quitar_s(&mut historial);\n                    comando = String::new();\n                } else {\n                    comando = \"Historial vacio\".to_string();\n                }\n            }\n            \"adelante\" => {\n                if !historial1.is_empty() {\n                    pila_agregar_s(&mut historial, cadena.clone());\n                    cadena = pila_quitar_s(&mut historial1);\n                    comando = String::new();\n                } else {\n                    comando = \"Estas en la última página\".to_string();\n                }\n            }\n            \"salir\" => {\n                break;\n            }\n            _ => {\n                if !comando.is_empty() {\n                    cadena = comando.clone();\n                    comando = String::new();\n                    pila_agregar_s(&mut historial, cadena.clone());\n                }\n            }\n        }\n        clear_terminal().expect(\"Error al limpiar\");\n    }\n}\n\nfn pila_agregar_s(vector: &mut Vec<String>, add: String) {\n    vector.push(add);\n}\n\nfn pila_quitar_s(vector: &mut Vec<String>) -> String {\n    vector.pop().unwrap()\n}\n\n/*\n- Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\nimpresora compartida que recibe documentos y los imprime cuando así se le indica.\nLa palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\ninterpretan como nombres de documentos.\n*/\n\nfn extra2() {\n    clear_terminal().expect(\"Error al limpiar\");\n    let mut cola: Vec<String> = Vec::new();\n\n    loop {\n        println!(\"-----------\");\n        println!(\"| EXTRA 2 |\");\n        println!(\"-----------\");\n        println!(\"\\\"imprimir\\\" para imprimir\\n\\\"papel\\\" para agregar un papel a la cola de impresion\\n\\\"salir\\\" para cerrar el programa\");\n        let mut entrada: String = String::new();\n        std::io::stdin().read_line(&mut entrada).unwrap();\n        entrada = entrada.trim().to_string();\n        if entrada == \"imprimir\" {\n            if !cola.is_empty() {\n                clear_terminal().expect(\"Error al limpiar\");\n                println!(\"Imprimiendo...\");\n                println!(\"{}\", cola_quitar_s(&mut cola));\n            } else {\n                clear_terminal().expect(\"Error al limpiar\");\n                println!(\"No hay papeles\");\n            }\n        } else if entrada == \"salir\" {\n            break;\n        } else {\n            cola_agregar_s(&mut cola, entrada);\n            clear_terminal().expect(\"Error al limpiar\");\n        }\n    }\n}\n\nfn cola_agregar_s(vector: &mut Vec<String>, add: String) {\n    vector.push(add);\n}\n\nfn cola_quitar_s(vector: &mut Vec<String>) -> String {\n    vector.remove(0)\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/rust/gabrielmoris.rs",
    "content": "/*\n * EXERCISE:\n * Implement the mechanisms of introduction and retrieval of elements typical of\n * stacks (stacks - LIFO) and queues (queue - FIFO) using an array\n * or list (depending on the possibilities of your language).\n */\n\nfn main() {\n    // STACK\n    pub struct Stack<T> {\n        elements: Vec<T>,\n    }\n\n    impl<T> Stack<T> {\n        // Create Stack\n        pub fn new() -> Self {\n            Stack {\n                elements: Vec::new(),\n            }\n        }\n        // Push Item\n        pub fn push(&mut self, item: T) {\n            self.elements.push(item);\n        }\n        // Pop Item\n        pub fn pop(&mut self) -> Option<T> {\n            self.elements.pop()\n        }\n\n        // Check Item\n        pub fn check(&self) -> Option<&T> {\n            self.elements.last()\n        }\n        // Is Empty\n        pub fn is_empty(&self) -> bool {\n            self.elements.is_empty()\n        }\n\n        pub fn clear(&mut self) {\n            self.elements.clear();\n        }\n\n        pub fn length(&self) -> usize {\n            self.elements.len()\n        }\n    }\n    println!(\" ======== STACK ======== \");\n    let mut stack = Stack::new();\n    stack.push(1);\n    stack.push(1);\n    println!(\"{:?}\", stack.length()); // Prints: 2\n    stack.clear();\n    println!(\"{:?}\", stack.length()); // Prints: 0\n    stack.push(1);\n    stack.push(2);\n    println!(\"{:?}\", stack.pop()); // Prints: Some(2)\n    println!(\"{:?}\", stack.check().unwrap()); // Prints: 1\n    println!(\"{:?}\", stack.is_empty()); // Prints: false\n    println!(\"{:?}\", stack.pop().unwrap()); // Prints: 1\n    println!(\"{:?}\", stack.is_empty()); // Prints: true\n\n    // QUEUE\n    pub struct Queue<T> {\n        elements: Vec<T>,\n    }\n\n    impl<T> Queue<T> {\n        // Create Stack\n        pub fn new() -> Self {\n            Queue {\n                elements: Vec::new(),\n            }\n        }\n        // enqueue\n        pub fn enqueue(&mut self, item: T) {\n            self.elements.push(item);\n        }\n\n        pub fn dequeue(&mut self) -> T {\n            self.elements.remove(0)\n        }\n\n        pub fn check(&self) -> Option<&T> {\n            self.elements.first()\n        }\n\n        pub fn length(&self) -> usize {\n            self.elements.len()\n        }\n\n        pub fn is_empty(&self) -> bool {\n            self.elements.is_empty()\n        }\n\n        pub fn clear(&mut self) {\n            self.elements.clear();\n        }\n    }\n    println!(\" ======== QUEUE ======== \");\n    let mut queue = Queue::new();\n    queue.enqueue(1);\n    queue.enqueue(1);\n    println!(\"{:?}\", queue.length()); // Prints: 2\n    queue.clear();\n    println!(\"{:?}\", queue.length()); // Prints: 0\n    queue.enqueue(1);\n    queue.enqueue(2);\n    println!(\"{:?}\", queue.dequeue()); // Prints: 1\n    println!(\"{:?}\", queue.check().unwrap()); // Prints: 2\n    println!(\"{:?}\", queue.is_empty()); // Prints: false\n    println!(\"{:?}\", queue.dequeue()); // Prints: 2\n    println!(\"{:?}\", queue.is_empty()); // Prints: true\n\n    // CHALLENGE\n    challenge();\n}\n\n/*\n * EXTRA DIFFICULTY (optional):\n * - Using the stack implementation and text strings, simulate the forward/back\n *   mechanism of a web browser. Create a program in which you can navigate to a page or tell it\n *   that you want to move forward or backward, showing in each case the name of the web.\n *   The words \"forward\", \"backward\" trigger this action, the rest is interpreted as\n *   the name of a new web.\n * - Using the queue implementation and text strings, simulate the mechanism of a\n *   shared printer that receives documents and prints them when indicated.\n *   The word \"print\" prints an element from the queue, the rest of the words are\n *   interpreted as document names.\n */\nuse std::io::{self};\n\nfn challenge() {\n    pub struct Pages<T> {\n        elements: Vec<T>,\n        position: usize,\n    }\n\n    impl<T> Pages<T> {\n        // Create Stack\n        pub fn new() -> Self {\n            Pages {\n                elements: Vec::new(),\n                position: 0,\n            }\n        }\n        // enqueue\n        pub fn enqueue(&mut self, item: T) {\n            self.elements.push(item);\n            self.position += 1\n        }\n\n        pub fn check(&self) -> Option<&T> {\n            if self.position > 0 {\n                self.elements.get(self.position - 1)\n            } else {\n                self.elements.get(0)\n            }\n        }\n\n        pub fn is_empty(&self) -> bool {\n            self.elements.is_empty()\n        }\n\n        pub fn clear(&mut self) {\n            self.elements.clear();\n        }\n\n        pub fn position_add(&mut self) {\n            if self.position + 1 <= self.elements.len().try_into().unwrap() {\n                self.position += 1\n            }\n        }\n\n        pub fn position_sub(&mut self) {\n            if self.position > 1 {\n                self.position -= 1\n            } else {\n                self.position = 0\n            }\n        }\n    }\n\n    let mut pages = Pages::new();\n\n    loop {\n        println!(\n            \"\n            ===========================\n            What would you like to do?\n            1. Add a page\n            2. Delete all pages\n            3. Forward\n            4. Backward\n            5. Print\n            6. Exit\n            ===========================\n            \"\n        );\n\n        let mut input = String::new();\n        io::stdin()\n            .read_line(&mut input)\n            .expect(\"Failed to read line\");\n\n        let choice: u32 = input.trim().parse().expect(\"Invalid input\");\n\n        match choice {\n            1 => add_page(&mut pages),\n            2 => delete_pages(&mut pages),\n            3 => go_forward(&mut pages),\n            4 => go_backwards(&mut pages),\n            5 => get_page(&mut pages),\n            6 => {\n                println!(\"Goodbye!\");\n                break;\n            }\n            _ => println!(\"Invalid choice. Please try again.\"),\n        }\n\n        println!();\n    }\n    fn add_page(pages: &mut Pages<String>) {\n        println!(\"Enter the URL\");\n        let mut url: String = String::new();\n        io::stdin().read_line(&mut url).expect(\"Failed to read Url\");\n        let url: String = url.trim().to_string();\n\n        pages.enqueue(url)\n    }\n\n    fn delete_pages(pages: &mut Pages<String>) -> () {\n        println!(\"Deleted all pages\");\n        pages.clear()\n    }\n\n    fn go_forward(pages: &mut Pages<String>) -> () {\n        println!(\"Forward\");\n        pages.position_add()\n    }\n\n    fn go_backwards(pages: &mut Pages<String>) -> () {\n        println!(\"Backward\");\n        pages.position_sub()\n    }\n\n    fn get_page(pages: &mut Pages<String>) -> () {\n        println!(\"You are in:\");\n        if pages.is_empty() {\n            println!(\"You have no pages in your browser\");\n            return;\n        }\n\n        let page = pages.check().unwrap();\n        println!(\"{}\", page);\n    }\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/rust/kenysdev.rs",
    "content": "/*\n╔═══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado                ║\n║ GitHub: https://github.com/Kenysdev   ║\n║ 2024 -  Rust                          ║\n╚═══════════════════════════════════════╝\n-----------------------------------------\n* PILAS Y COLAS\n-----------------------------------------\n- Son estructuras de datos comunes utilizadas para \n  organizar y manipular datos.\n*/\nuse std::io::{self, Write};\nuse std::collections::VecDeque;\nfn main() {\n    // ______________________________________________________________\n    // * PILAS (STACK - LIFO):\n    // - Sigue el principio LIFO (last in, first out)\n    // - El último elemento añadido, es el primero en ser retirado.\n\n    let mut stack: Vec<i8> = Vec::new();\n    // Agregar elementos.\n    stack.push(1); \n    stack.push(2);\n    stack.push(3);\n\n    // Eliminar y obtener el elemento superior de la pila (pop):\n    if let Some(top) = stack.pop() {\n        println!(\"Eliminar y obtener: {top}\");\n    } else {\n        println!(\"Pila vacia\");\n    }\n\n    // Obtener el elemento superior de la pila sin eliminarlo (peek)\n    if let Some(top) = stack.last() {\n        println!(\"Obtener sin eliminar: {top}\")\n    } else {\n        println!(\"Pila vacia\")\n    }\n\n    // Verificar si la pila está vacía:\n    if stack.is_empty() {\n        println!(\"Pila vacia\");\n    } else {\n        println!(\"Pila tiene elementos\");\n    }\n\n    // Obtener el tamaño de la pila:\n    println!(\"Total de elementos: {}\", stack.len());\n\n    // Verificar si existe\n    let x: i8 = 5;\n    if stack.contains(&x) {\n        println!(\"{x} está en la pila.\");\n    } else {\n        println!(\"{x} no está en la pila.\");\n    }\n\n    // Imprimir todos\n    println!(\"{:?}\", stack);\n\n\n    // ______________________________________________________________\n    // * COLAS (QUEUE - FIFO)\n    // - sigue el principio FIFO(First In, First Out)\n    // - El primer elemento que se inserta es el primero en ser retirado.\n\n    let mut queue: VecDeque<i8> = VecDeque::new();\n\n    // Agregar elementos a la cola (enqueue):\n    queue.push_back(1);\n    queue.push_back(2);\n    queue.push_back(3);\n\n    // Obtener el elemento sin eliminarlo (peek):\n    if let Some(front) = queue.front() {\n        println!(\"Elemento en el frente de la cola: {front}\");\n    } else {\n        println!(\"Cola vacía.\");\n    }\n\n    // Eliminar y obtener el elemento (dequeue):\n    if let Some(front) = queue.pop_front() {\n        println!(\"Eliminar y obtener en cola: {front}\");\n    } else {\n        println!(\"Cola vacía.\");\n    }\n\n    // otros\n    println!(\"Está vacía?: {}\", queue.is_empty());\n    println!(\"Total de elementos: {}\", queue.len());\n    println!(\"Verificar si existe 5: {}\", queue.contains(&5));\n    println!(\"Imprimir todos: {:?}\", queue);\n\n    // ______________\n    // ejercicio\n    home()\n\n}\n/* ______________________________________________________________\n* * EJERCICIOS:\n* - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n*   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n*   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n*   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n*   el nombre de una nueva web.\n* - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n*   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n*   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n*   interpretan como nombres de documentos.\n*/\nconst MSG_HOME: &str = \"\n-----------------------------------\n- '1' -> simulador_navegador.\n- '2' -> simulador_impresora.\n- 'enter' -> SALIR\n-----------------------------------\n\";\n\nconst MSG_NAV: &str = \"\n-----------------------------------\n- '<' para página anterior.\n- '>' para página adelante.\n- 'h' Ver historial completo.\n- 'x' para salir. \nEscribir web para agregar:\n-----------------------------------\n\";\n\nconst MSG_PRINTER: &str = \"\n-----------------------------------\n- 'p' Imprimir.\n- 'l' Ver documentos pendientes.\n- 'x' para salir.\nEscribir nombre para enviar a cola:\n-----------------------------------\n\";\n\nfn home(){\n    println!(\"{MSG_HOME}\");\n    let action: String = input(\"____________\\nAcción: \");\n    match action.as_str() {\n        \"1\" => nav_history(),\n        \"2\" => queue_printer(),\n        _ => println!(\"Adios\"),\n    }\n}\n\nfn nav_history() {\n    let mut history: Vec<String> = vec![\"Inicio\".to_string()]; \n    let mut back_history: Vec<String> = Vec::new(); \n    let mut forward_history: Vec<String> = Vec::new();\n    println!(\"{}\", MSG_NAV);\n    loop { \n        println!(\"{} <-[{}]-> {}\", \n        back_history.len(), history.last().unwrap(), forward_history.len());\n        let action: String = input(\"____________\\nAcción: \");\n        match action.as_str() {\n            \"<\" => {\n                if back_history.len() > 0 {\n                    forward_history.push(history.last().unwrap().clone()); \n                    history.push(back_history.pop().unwrap());\n                } else {\n                    println!(\"No hay página previa.\")\n                }\n            },\n            \">\" => {\n                if forward_history.len() > 0 {\n                    back_history.push(history.last().unwrap().clone());\n                    history.push(forward_history.pop().unwrap());\n                } else {\n                    println!(\"No hay página siguiente.\")\n                }\n            },\n            \"h\" => {\n                if history.len() > 0 {\n                    for web in &history { \n                        println!(\"{}\", web); \n                    }\n                } else {\n                    println!(\"Historial vacío.\")\n                }\n            },\n            \"x\" => {\n                home(); \n                break;\n            },\n            _ => {\n                back_history.push(history.last().unwrap().clone());\n                forward_history.clear();\n                history.push(action); \n            },\n        }\n    }\n}\n\nfn queue_printer() {\n    let mut doc_queue: VecDeque<String> = VecDeque::new();\n    println!(\"{}\", MSG_PRINTER);\n    loop {\n        let action: String = input(\"____________\\nAcción: \");\n        if action.len() > 0 {\n            match action.as_str() {\n                \"p\" => {\n                    if doc_queue.len() > 0{\n                        println!(\"{} -> ha sido impreso\\n{} -> archivos faltantes.\", \n                        doc_queue.pop_front().unwrap(), doc_queue.len());\n                    } else {\n                        println!(\"No hay archivos.\");\n                    }\n                },\n                \"l\" => {\n                    if doc_queue.len() > 0 {\n                        for doc in &doc_queue {\n                            println!(\"{}\", doc);\n                        }\n                    } else {\n                        println!(\"No hay archivos.\");\n                    }\n                },\n                \"x\" => {\n                    home();\n                    break;\n                },\n                _ => {\n                    doc_queue.push_back(action);\n                    println!(\"Archivo agregado a cola de impresión.\");\n                }\n            }\n        } else {\n            println!(\"xD\");\n        }\n    }\n}\n\nfn input(msg: &str) -> String {\n    print!(\"{msg}\");\n    io::stdout().flush().expect(\"Error al limpiar búfer\");\n\n    let mut input_txt: String = String::new();\n    io::stdin()\n        .read_line(&mut input_txt)\n        .expect(\"Error al leer la entrada\");\n\n    input_txt.trim().to_string()\n}\n\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/rust/troleomotor10.rs",
    "content": "/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n*/\n\nfn webbrowser(){\n    let mut tabs: Vec<String> = Vec::new();\n    let mut input: String = String::new();\n    let mut position = 0;\n    \n    println!(\"-------------------- BIENVENIDO AL NAVEGADOR --------------------\");\n    println!(\"-- -> Para añadir una nueva pestaña simplemente escriba el nombre --\");\n    println!(\"-- -> Si quieres ver todas las pestañas abiertas usa 'tabs' --\");\n    println!(\"-- -> Si deseas salir del programa escribe 'exit' --\");\n\n    loop {\n        input.clear();\n        std::io::stdin().read_line(&mut input).expect(\"Ha ocurrido un error leyendo\");\n\n        let input = input.trim();\n\n        if input == \"adelante\" {\n            if position == tabs.len() - 1{\n                println!(\"No puedes ir mas hacia adelante. No hay mas pestañas.\");\n            } else {\n                position += 1;\n            }\n        } else if input == \"atras\" {\n            if position > 0 {\n                position -= 1;\n            } else {\n                println!(\"No puede ir mas hacia atrás. No hay mas pestañas\");\n            }\n        } else if input == \"exit\" {\n            break;\n        } else if input == \"tabs\" {\n            println!(\"{:?}\", tabs);\n        } else {\n            tabs.push(input.to_string());\n            if tabs.len() > 1 {\n                position += 1;\n            }\n        }\n\n        println!(\"Te encuentras en la pestaña {}\", tabs[position]);\n    }\n\n    println!(\"Se ha cerrado el navegador.\");\n}\n\nfn printer(){\n    let mut document_queue: Vec<String> = Vec::new();\n    let mut input: String = String::new();\n\n    println!(\"-------------------- BIENVENIDO AL PROGRAMA DE IMPRESIÓN --------------------\");\n    println!(\"------ -> Para añadir un nuevo documento simplemente escriba el nombre ------\");\n    println!(\"------ -> Para imprimir un documento escribe la palabra 'imprimir' ------\");\n    println!(\"------ -> Si deseas salir del programa escribe 'exit' ------\");\n    \n    loop {\n        input.clear();\n        std::io::stdin().read_line(&mut input).expect(\"Ha ocurrido un error leyendo\");\n\n        let input = input.trim();\n    \n        if input == \"imprimir\" {\n            if document_queue.len() > 0 {\n                println!(\"Imprimiendo documento {}\", document_queue[0]);\n                document_queue.remove(0);\n            } else {\n                println!(\"No hay documentos para imprimir!\");\n            }\n        } else if input == \"exit\" {\n            break;\n        } else {\n            println!(\"El documento {} ha sido añadido a la cola de impresión\", input);\n            document_queue.push(input.to_string());\n        }\n    }\n\n    println!(\"El programa de impresión finalizo\");\n\n}\n\nfn main(){\n    // LIFO (Last In First Out) STACKS\n    let mut stack: Vec<u32> = Vec::new();\n    // push\n    stack.push(34);\n    stack.push(45);\n    stack.push(10);\n    // Print stack\n    println!(\"{:?}\", stack);\n    // Delete last element\n    stack.pop();\n    // Print stack\n    println!(\"{:?}\", stack);\n\n    // FIFO (First In First Out) QUEUES\n    let mut queue: Vec<u32> = Vec::new();\n    // Push\n    queue.push(89);\n    queue.push(33);\n    queue.push(13);\n    // Print queue\n    println!(\"{:?}\", queue);\n    // Remove first element\n    queue.remove(0);\n    // Print queue\n    println!(\"{:?}\", queue);\n\n    // EXTRA EXERCISE PRINTER\n    printer();\n    // EXTRA EXERCISE WEB BROWSER\n    webbrowser();\n}"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/sql/Nicojsuarez2.sql",
    "content": "# #07 PILAS Y COLAS\n> #### Dificultad: Media | Publicación: 12/02/24 | Corrección: 19/02/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/swift/PineroDev.swift",
    "content": "/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n\n\nimport Foundation\n\n\n// Struct con comportamiento de una pilas (stacks - LIFO)\n\nstruct Stack<T> { // Utilizamos <T> para que se le pueda pasar cualquier tipo de valor\n    \n    private var elementos: [T] = []\n    \n    // Usamos mutating para decirle a Swift que no cree una copia y\n    // modifique el valor de la estructura ya que la struct es de tipo\n    // valor y de modo original hace una copia de la struct al modificarse\n    mutating func push(elemento: T){\n        elementos.append(elemento) //Agrega el valor al final\n    }\n    \n    mutating func pop() -> T? {\n        return elementos.popLast() //Quitamos el ultimo\n    }\n    \n    func peek() -> T? {\n        return elementos.last // Leemos el ultimo valor\n    }\n    \n    func isEmpty() -> Bool {\n        return elementos.isEmpty // Comprobamnos si la pila esta vacia\n    }\n    \n    func size() -> Int {\n        return elementos.count // contamos los elementos de la pila\n    }\n}\n\n// Struct con comportamiento de una colas (queue - FIFO)\n\nstruct Queue<T> {\n    \n    private var elementos: [T] = []\n    \n    mutating func enqueue(elemento: T){ //Agrega el valor al final\n        elementos.append(elemento)\n    }\n    \n    mutating func dequeue() -> T? { //Quitamos el primero\n        return elementos.removeFirst()\n    }\n    \n    func peek() -> T? {\n        return elementos.first // Leemos el primer valor\n    }\n    \n    func isEmpty() -> Bool {\n        return elementos.isEmpty // Comprobamnos si la pila esta vacia\n    }\n    \n    func size() -> Int {\n        return elementos.count // contamos los elementos de la pila\n    }\n        \n}\n\n\nfunc webNavigation() {\n    \n    var posicion: Int = -1\n    var cadena:[String] = []\n    print(\"Introduce una url o atras, adelante o salir\")\n    while true {\n        if let urlString = readLine() {\n            \n            if urlString == \"atras\"{\n                if cadena.isEmpty {\n                    print(\"No hay ninguna web de momento\")\n                }else if cadena.count == 1 || posicion == 0{\n                    print(\"Estas en la primera pagina\")\n                }else{\n                    posicion -= 1\n                    print(cadena[posicion])\n                }\n                \n            }else if urlString == \"adelante\"{\n                if cadena.isEmpty {\n                    print(\"No hay ninguna web de momento\")\n                }else if posicion == cadena.indices.last{\n                    print(\"Estas en la ultima pagina\")\n                }else{\n                    posicion += 1\n                    print(cadena[posicion])\n                }\n                \n            }else if urlString == \"salir\"{\n                print(cadena)\n                break\n                \n            }else{\n                cadena.append(urlString)\n                posicion += 1\n            }\n        }\n    }\n}\n\n//webNavigation()\n\n//----------------------------------------------------------\n\n\nfunc impresora() {\n    //var posicion: Int = -1\n    var documentos:[String] = []\n    print(\"    Introduce el nombre del documento         \")\n    print(\" o imprimir para imprimir el primer documento \")\n    print(\"            salir para salir                  \")\n        \n    while true {\n        if let inText = readLine(){\n            \n            if inText == \"imprimir\"{\n                guard let name = documentos.first else {\n                        print(\"Sin documentos en la cola\")\n                        return\n                    }\n\n                    print(\"Imprimiendo documento \\(name) ...\")\n                    sleep(5)\n                    print(\"Documento \\(name) impreso\")\n\n                    documentos.removeFirst()\n            }else if inText == \"salir\"{\n                break\n            }else{\n                documentos.append(inText)\n            }\n        }\n    }\n}\n\nimpresora()\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/swift/allbertoMD.swift",
    "content": "import Foundation\nprint(\"PILA\")\n// Pila\nvar stackItems: [Any] = []\n\n// Metodo push: añade nuevos elementos al final de la pila.\nstackItems.append(\"Pepe\")\nstackItems.append(\"Alicia\")\nstackItems.append(\"Raul\")\nstackItems.append(\"Marta\")\n\nprint(\"Metodo peak\")\n// Metodo peak: devuelve el ultimo elemento de la pila.\nif let firstOut = stackItems.last {\n    print(firstOut)\n}\n\nprint(\"Metodo pop\")\n// Metodo pop: devuelve el ultimo elemento de la pila y lo elimina.\nif let stackLastIn = stackItems.popLast() {\n    print(stackLastIn)\n\n}\n\n\nprint(\"\\nCOLA\")\n// Cola\nvar queueItems: [Any] = []\n\n// Metodo enqueue: añade nuevo elemento al final de la cola.\nqueueItems.append(\"Cupertino\")\nqueueItems.append(\"Madrid\")\nqueueItems.append(\"Bogota\")\nqueueItems.append(\"Tokio\")\n\nprint(\"Metodo from\")\n// Metodo from: devuelve el primer elemento de la cola.\nif let firstOut = queueItems.first {\n    print(firstOut)\n}\n\nprint(\"Metodo dequeue\")\n// Metodo dequeue: devuelve el primer elementos de la cola y lo elimina.\nlet queueFirstIn = queueItems.removeFirst()\nprint(queueFirstIn)\n\n\n\n\n// Dificultad extra.\nprint(\"\\n\\nDIFICULTAD EXTRA\")\n\n// Simulador de navegación de paginas web.\nprint(\"\\nSimulador de Navegación de Paginas Web\")\n\n// Array donde se almacenas las paginas web.\nvar webSites: [String] = []\n// variable que evalua si termina el programa.\nvar stackProgramContinue = true\n// Variable para contar el indice del array.\nvar stepper: Int = 1\n\n// Nuestra el menu de las opciones que se pueden realizar\nshowStackExerciseMenu()\n\n// Loop que se ejecuta hasta que stackProgramContinue es false (cuando introduces \"exit\").\nwhile stackProgramContinue {\n\n    // Crea la variable input con el texto que introducca el usuario.\n    if let input = readLine() {\n\n        // Evalua la variable input y ejecuta el codigo dependiendo de lo que introducca el usuario.\n        switch input {\n\n            // Si se introduce una pagina web sw imprime la wev introducida.\n            case inputWebSite(web: input):\n                webSites.append(input)\n                if let last = webSites.last {\n                    print(last)\n                }\n\n            // Se mueve al indice anterios del array y imprime el valor.  \n            case \"atras\":\n                if webSites.isEmpty {\n                    print(\"No hay paginas\")\n                    continue\n                }\n                stepper += 1\n                if stepper == webSites.count + 1 {\n                    stepper = webSites.count\n                    print(\"No Hay Mas Paginas\")\n                } else {\n                    print(webSites[webSites.count - stepper])\n                }\n\n            // Se muevo al indice siguiente del array y imprime el calor.\n            case \"adelante\":\n                if webSites.isEmpty {\n                    print(\"No Hay Paginas\")\n                    continue\n                }\n                stepper -= 1\n                if stepper == 0 {\n                    stepper = 1\n                    print(\"No Hay Mas Paginas\")\n                } else {\n                    print(webSites[webSites.count - stepper])\n                }\n\n            // Salir del programa.\n            case \"exit\":\n                stackProgramContinue = false\n\n            // Si la opcion no es valida imprime \"Opcion no Valida\".\n            default:\n                print(\"Opcion no Valida\")\n        }\n    }\n}\n\n// funcion que evalua si una pagina es .com y tiene www. para que sea una direccion correcta y devuelva la pagina si es correcto.\nfunc inputWebSite(web name: String) -> String {\n    // Variable para almacenar los tres primeros caracteres de la pagina.\n    var firstCharacters = \"\"\n    // Variable para almacenar los tres ultimos caracteres de la pagina.\n    var lastCharacters: String = \"\"\n    var lastCharactersReversed: String = \"\"\n    // Variable para almacenar los tres ultimos caracteres de la pagina, pero del reves.\n\n    // Loop que almacena los tres primeros caracteres en la variable firstCharacters\n    for character in name {\n        firstCharacters.append(character)\n        if firstCharacters.count == 4 {\n            break\n        }\n    }\n\n    // Loop que almacena los tres ultimos caracteres de la pagina del reves.\n    for character: Character in name.reversed() {\n        lastCharactersReversed.append(character)\n        if lastCharactersReversed.count == 4 {\n            break\n        }\n    }\n\n    // Loop que almacena los tres ultimos caracteres de la pagina en orden no del reves\n    for character: Character in lastCharactersReversed.reversed() {\n        lastCharacters.append(character)\n    }\n\n    // Evalua si la pagina empieza por \"www\" y termina \".com\" para devolver el nombre de la pagina\n    if firstCharacters == \"www.\" && lastCharacters == \".com\" {\n        return name\n    }\n\n    // Devuelve \"Web no Valida\" si la pagina no empieza por \"www\" y terminal por \".com\"\n    return \"Web no Valida\"\n}\n\n// Funcion que imprime las opciones del menu.\nfunc showStackExerciseMenu() {\n    print(\"\\nIntroduce Una Opción.\\n\")\n    print(\"[Pagina Web .com] - Navega a Una Nueva Pagina.\")\n    print(\"[atras] - Navega a la Pagina Anterior\")\n    print(\"[adelante] - Navega a la Siguiente Pagina.\")\n    print(\"[exit] - Salir Del Programa.\\n\")\n}\n\n\n\n// Simulador de impresora\nprint(\"\\nSimulador de Impresora\")\n\nimport Foundation\n\n// Array que almacena todos los ficheros de la cola.\nvar documents: [String] = []\n// Variable que hace salir del programa cuando es false\nvar queueProgramContinue: Bool = true\n\nshowQueueMenu()\n\n// Loop que se ejecuta hasta que queueProgramContinue es false (cuando introduces \"exit\").\nwhile queueProgramContinue {\n    \n    // Crea la variable input con el texto que introducca el usuario.\n    if let input = readLine() {\n\n        // Evalua la variable input y ejecuta el codigo dependiendo de lo que introducca el usuario.\n        switch input {\n\n            // Si se introduce un nuevo fichero se añade a la cola.\n            case inputDocument(document: input):\n                documents.append(input)\n\n            // Imrime el primer fichero de la cola y lo elimina de la cola.\n            case \"imprimir\":\n                if documents.isEmpty {\n                    print(\"No Hay Documentos en la Cola\")\n                } else {\n                    if let first = documents.first {\n                    print(first)\n                }\n                documents.removeFirst()\n                }\n\n            // Sale del programa.\n            case \"exit\":\n                queueProgramContinue = false\n\n            default:\n                print(\"Opción No Valida\")\n        }\n    }\n}\n\n// funcion que evalua si un tenga la extensión .pdf para que sea un fichero valido y devuelva el fichero si es valido.\nfunc inputDocument(document name: String) -> String {\n    // Evalua si el fichero tiene estensión .pdf y si lo tiene devuelve el fichro\n    if name.contains(\".pdf\") {\n        return name\n    }\n    \n    // Devuelve \"Documento no Valido\" si no tiene extension .pdf.\n    return \"Documento no Valido\"\n}\n\n// Funcion que imprime las opciones del menu.\nfunc showQueueMenu() {\n    print(\"\\nIngresa Una Opción\\n\")\n    print(\"[Fichro .pdf] - Añade un Fichero a la Cola de Impresión\")\n    print(\"[imprimir] - Imprime el Primer Fichero de la Cola\")\n    print(\"[exit] - Salir del Programa\\n\")\n}"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/swift/blackriper.swift",
    "content": "/*\n   Colas (Primero en Entrar , Primero en Salir)FIFO\n   -cada elemento nuevo va al final de la misma\n   -primero tiene que salir el primer elemento del mismo y hasta que este salga\n    podra salir otro elemento de la lista\n   - en swift se puede crear este comportamiento usando un array y una struct \n*/\n\n// crendo estruct con una lista en este caso de tipo String pero se puede usar un generico para cualquier tipo de dato\n\nstruct Queue{\n    var elements=[String]()\n\n    mutating func add(element: String){\n        elements.append(element)\n    }\n\n    mutating func addAll(itemsArray: [String]){\n        self.elements=itemsArray\n    }\n\n    mutating func remove() -> String?{\n        return elements.isEmpty ? nil : elements.removeFirst()\n    }\n\n    func peek() -> String?{\n        return elements.isEmpty ? nil : elements.first\n    }\n\n    var isEmpty: Bool {\n        return elements.isEmpty\n    }\n}\n\n// ejemplo de uso \nvar taskDay=[\"wake up\", \"eat breakfast\", \"go to work\", \"go to bed\"]\nvar myQueue=Queue()\nmyQueue.addAll(itemsArray: taskDay)\nprint(myQueue.peek()!)\nprint(myQueue.remove()!)\nprint(myQueue.peek()!)\nprint(\"task pending: \\(myQueue.elements)\")\n\n//reto extra \nfunc printerDocuments(){\n    var  printerQueue=Queue()\n    var option:String\n    \n    func addDocument(document:String){\n        printerQueue.add(element: document)\n    }\n\n    func printNextDocument(){\n        if let nextDocument=printerQueue.remove(){\n            print(\"printing: \\(nextDocument)\")\n            print(\"pending to print: \\(printerQueue.elements)\")\n            \n        }\n    }\n    \n    repeat{\n        print(\"1. Add document\")\n        print(\"2. Printdocument\")\n        print(\"3. Exit\")\n        print(\"Select an option: \", terminator: \"\")\n        option=readLine()!\n        switch option{\n            case \"1\":\n               print(\"Input the document name\",terminator: \"\")\n               let document=readLine()!\n               addDocument(document: document)\n            case \"2\":\n                 if printerQueue.isEmpty {\n                     print(\"No documents to print\")  \n                 }else {\n                     printNextDocument()\n                 }  \n            default:\n             if option != \"3\" {\n                 print(\"Invalid option\")   \n             }\n                 \n        }\n    }while option != \"3\"    \n\n}\n\nprinterDocuments()\n\n/*\n  Pila (Last in First Out) LIFO(Ultimo en entrar , primero en salir)\n  - el último que entra es el primero que sale\n  - apilar coloca un objeto en la pila\n  - desapilar saca el último objeto de la pila\n  - hasta que se desapila el ultimo elemento  se puede acceder al elemnto que se apilo con anterioridad\n  */\n\nstruct Stack{\n    var elements=[String]()\n\n    mutating func push(element: String){\n        elements.append(element)\n    }\n\n    mutating func pop() -> String?{\n        return elements.isEmpty ? nil : elements.popLast()\n    }\n\n    func peek() -> String?{\n        return elements.isEmpty ? nil : elements.last\n    }\n\n    var isEmpty: Bool{\n        return elements.isEmpty\n    }\n}\n\n// ejemplo de uso \n var awsStack=Stack()\n awsStack.push(element: \"AWSLambda\")\n awsStack.push(element: \"AWSRDS\")\n awsStack.push(element: \"AWSCLOUDFRONT\")\n print(awsStack.peek()!)\n print(awsStack.pop()!)\n print(awsStack.peek()!)\n print(\"task pending: \\(awsStack.elements)\")\n\n //ejercicio extra\n\n func simulateNavigator(){\n    var back=Stack()\n    var forward=Stack()\n\n    func navigate(webPage:String){\n        if back.isEmpty{\n           forward.push(element: webPage)\n           print(\"navigating to: \\(webPage)\")\n        }\n    }\n\n    func goBack(){\n        if !back.isEmpty{\n            forward.push(element: back.pop()!)\n            print(\"back to: \\(back.peek()!)\")\n        }else{\n            print(\"nothing to go back\")\n        }\n    }    \n\n    func goForward(){\n        if !forward.isEmpty{\n            back.push(element: forward.pop()!)\n            print(\"forward to: \\(forward.peek()!)\")\n        }else{\n            print(\"nothing to go forward\")\n        }\n    }\n\n  navigate(webPage: \"google.com\")\n  navigate(webPage: \"stackoverflow.com\")\n  navigate(webPage: \"github.com\")\n  goBack()\n  goBack()\n  goForward()\n    \n }\n\n simulateNavigator()\n\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/swift/didacdev.swift",
    "content": "import Foundation\n\nstruct Stack<T> {\n    var stack = [T]()\n\n    init(array: [T]) {\n        stack = array\n    }\n\n    init() {\n\n    }\n\n    mutating func push(e: T) {\n        stack.append(e)\n    }\n\n    mutating func get() -> T? {\n        guard !stack.isEmpty else {\n            return nil\n        }\n\n        return stack.last\n    }\n\n    mutating func pop() -> T {\n        return stack.removeLast()\n    }\n\n    mutating func clean() {\n        stack.removeAll()\n    }\n}\n\nstruct Queue<T> {\n    var queue = [T]()\n\n    init(array: [T]) {\n        queue = array\n    }\n\n    init() {\n\n    }\n\n    mutating func enqueue(e: T) {\n        queue.insert(e, at: 0)\n    }\n\n    mutating func get() -> T? {\n        guard !queue.isEmpty else {\n            return nil\n        }\n\n        return queue.first\n    }\n\n    mutating func dequeue() -> T {\n        return queue.removeFirst()\n    }\n\n    mutating func clean() {\n        queue.removeAll()\n    }\n}\n\nfunc browser() {\n\n    var backward: Stack<String> = Stack()\n    var forward: Stack<String> = Stack()\n\n    var quite = false\n\n    while !quite {\n        print()\n        if let web = backward.get() {\n            print(\"Web: \\(web)\")\n        } else {\n            print(\"Web:\")\n        }\n        print(\"1. Go to a website\")\n        print(\"2. Go back\")\n        print(\"3. Go forward\")\n        print(\"4. Quite\")\n\n        if let input = readLine() {\n            switch input {\n                case \"1\": \n                    print(\"Web: \")\n                    if let web = readLine() {\n                        goWebSite(web: web)\n                    } else {\n                        print(\"Wrong input\")\n                    }\n                case \"2\":\n                    goBackward()\n                case \"3\":\n                    goForward()\n                case \"4\":\n                    quite = true\n                default:\n                    print(\"Wrong input\")        \n            }\n        }\n    }\n\n    func goBackward() {\n        if backward.stack.count != 0 {\n            let actualWeb = backward.pop()\n            forward.push(e: actualWeb)\n        }\n    }\n\n    func goForward() {\n        if forward.stack.count != 0 {\n            let actualWeb = forward.pop()\n            backward.push(e: actualWeb)\n        }\n    }\n\n    func goWebSite(web: String) {\n        backward.push(e: web)\n        forward.clean()\n    }\n}\n\nfunc printer() {\n    var printer: Queue<String> = Queue()\n\n    var quite = false\n\n    while !quite {\n\n        if let word = readLine() {\n\n            switch word {\n                case \"imprimir\":\n                    if printer.queue.count != 0 {\n                        print(\"> \\(printer.dequeue())\")\n                    }\n                case \"quite\":\n                    quite = true\n                default:\n                    printer.enqueue(e: word)\n                    \n            }\n        }\n    }\n}\n\n// browser()\nprinter()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/swift/juanppdev.swift",
    "content": "/*\n    Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n*/\n// Implementación de una pila (stack) utilizando un array\nstruct Stack<T> {\n    private var elements = [T]()\n    \n    mutating func push(_ element: T) {\n        elements.append(element)\n    }\n    \n    mutating func pop() -> T? {\n        return elements.popLast()\n    }\n    \n    func peek() -> T? {\n        return elements.last\n    }\n    \n    func isEmpty() -> Bool {\n        return elements.isEmpty\n    }\n}\n\n// Implementación de una cola (queue) utilizando un array\nstruct Queue<T> {\n    private var elements = [T]()\n    \n    mutating func enqueue(_ element: T) {\n        elements.append(element)\n    }\n    \n    mutating func dequeue() -> T? {\n        if elements.isEmpty {\n            return nil\n        } else {\n            return elements.removeFirst()\n        }\n    }\n    \n    func peek() -> T? {\n        return elements.first\n    }\n    \n    func isEmpty() -> Bool {\n        return elements.isEmpty\n    }\n}\n\n// Ejemplo de uso de la pila\nvar stack = Stack<Int>()\nstack.push(1)\nstack.push(2)\nstack.push(3)\n\nwhile !stack.isEmpty() {\n    if let element = stack.pop() {\n        print(\"Elemento extraído de la pila: \\(element)\")\n    }\n}\n\n// Ejemplo de uso de la cola\nvar queue = Queue<String>()\nqueue.enqueue(\"Hola\")\nqueue.enqueue(\"Mundo\")\n\nwhile !queue.isEmpty() {\n    if let element = queue.dequeue() {\n        print(\"Elemento extraído de la cola: \\(element)\")\n    }\n}\n\n\n\n// Extra\n\n// Simulación de un navegador web utilizando una pila\nfunc simulateWebBrowser() {\n    var history = Stack<String>()\n    \n    func navigate(to page: String) {\n        print(\"Navegando a la página: \\(page)\")\n        history.push(page)\n    }\n    \n    func goBack() {\n        if let previousPage = history.pop() {\n            print(\"Volviendo a la página anterior: \\(previousPage)\")\n        } else {\n            print(\"No hay páginas anteriores en el historial.\")\n        }\n    }\n    \n    // Simulación de la navegación\n    navigate(to: \"Google\")\n    navigate(to: \"Facebook\")\n    navigate(to: \"Twitter\")\n    \n    goBack()\n    goBack()\n}\n\n// Simulación de una impresora compartida utilizando una cola\nfunc simulateSharedPrinter() {\n    var printerQueue = Queue<String>()\n    \n    func printDocument(_ document: String) {\n        print(\"Imprimiendo documento: \\(document)\")\n    }\n    \n    func processPrintQueue() {\n        if let document = printerQueue.dequeue() {\n            printDocument(document)\n        } else {\n            print(\"No hay documentos en la cola de impresión.\")\n        }\n    }\n    \n    // Simulación de la cola de impresión\n    printerQueue.enqueue(\"Documento1.pdf\")\n    printerQueue.enqueue(\"Documento2.docx\")\n    printerQueue.enqueue(\"Documento3.txt\")\n    \n    processPrintQueue()\n    processPrintQueue()\n}\n\n// Ejecutar simulaciones\nsimulateWebBrowser()\nsimulateSharedPrinter()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/swift/kontroldev.swift",
    "content": "import Foundation\n\n/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atras\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n\n// Implementación de una pila (stack) utilizando un array\nstruct Stack<Element> {\n    private var elements: [Element] = []\n    \n    mutating func push(_ element: Element) {\n        elements.append(element)   // añadir un elemento\n    }\n    \n    mutating func pop() -> Element? {\n        return elements.popLast()\n    }\n    \n    func peek() -> Element? {\n        return elements.last\n    }\n    \n    var isEmpty: Bool {\n        return elements.isEmpty\n    }\n    \n    var count: Int {\n        return elements.count\n    }\n}\n\n\n// Implementación de una cola (queue) utilizando un array\nstruct Queue<Element> {\n    private var elements: [Element] = []\n    \n    mutating func enqueue(_ element: Element) {\n        elements.append(element)\n    }\n    \n    mutating func dequeue() -> Element? {\n        if elements.isEmpty {\n            return nil\n        } else {\n            return elements.removeFirst()\n        }\n    }\n    \n    func peek() -> Element? {\n        return elements.first\n    }\n    \n    var isEmpty: Bool {\n        return elements.isEmpty\n    }\n    \n    var count: Int {\n        return elements.count\n    }\n}\n\n// Ejemplo de uso\nvar stack = Stack<Int>()\nstack.push(1)\nstack.push(2)\nstack.push(3)\n\nprint(\"Elementos de la pila:\")\nwhile let element = stack.pop() {\n    print(element)\n}\n\nvar queue = Queue<String>()\nqueue.enqueue(\"a\")\nqueue.enqueue(\"b\")\nqueue.enqueue(\"c\")\n\nprint(\"\\nElementos de la cola:\")\nwhile let element = queue.dequeue() {\n    print(element)\n}\n\n\n// DIFICULTAD EXTRA (opcional)\nstruct WebBrowser {\n    private var historyStack = Stack<String>()\n    private var forwardStack = Stack<String>()\n    private var currentPage: String?\n    \n    mutating func navigate(to page: String) {\n        if let currentPage = currentPage {\n            historyStack.push(currentPage)\n            forwardStack = Stack<String>()\n        }\n        currentPage = page\n        print(\"Navegando a la página: \\(page)\")\n    }\n    \n    mutating func goBack() {\n        if let page = historyStack.pop() {\n            forwardStack.push(currentPage!)\n            currentPage = page\n            print(\"Retrocediendo a la página anterior: \\(page)\")\n        } else {\n            print(\"No hay páginas anteriores para retroceder.\")\n        }\n    }\n    \n    mutating func goForward() {\n        if let page = forwardStack.pop() {\n            historyStack.push(currentPage!)\n            currentPage = page\n            print(\"Avanzando a la página siguiente: \\(page)\")\n        } else {\n            print(\"No hay páginas siguientes para avanzar.\")\n        }\n    }\n}\n\nvar browser = WebBrowser()\n\nbrowser.navigate(to: \"www.example.com\")\nbrowser.navigate(to: \"www.google.com\")\nbrowser.navigate(to: \"www.openai.com\")\n\nbrowser.goBack()\nbrowser.goForward()\nbrowser.goBack()\nbrowser.goBack()\n\n\nstruct SharedPrinter {\n    private var printQueue = Queue<String>()\n    \n    mutating func enqueueDocument(_ document: String) {\n        printQueue.enqueue(document)\n        print(\"Se ha añadido el documento '\\(document)' a la cola de impresión.\")\n    }\n    \n    mutating func printDocument() {\n        if let document = printQueue.dequeue() {\n            print(\"Imprimiendo el documento: \\(document)\")\n        } else {\n            print(\"La cola de impresión está vacía.\")\n        }\n    }\n}\n\nvar printer = SharedPrinter()\n\nprinter.enqueueDocument(\"Documento 1\")\nprinter.enqueueDocument(\"Documento 2\")\nprinter.enqueueDocument(\"Documento 3\")\n\nprinter.printDocument()\nprinter.printDocument()\nprinter.printDocument()\nprinter.printDocument()\n\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/swift/lordzzz777.swift",
    "content": "/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atras\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n\n\n// Implementación de pila (stack) utilizando un array\nstruct Stack<T>{\n    private var elements = [T]()\n    \n     mutating func push(_ element: T ) {\n       elements.append(element)\n    }\n    \n    mutating func pop() -> T? {\n        return elements.popLast()\n    }\n    \n     func peek() -> T? {\n        return elements.last\n    }\n    \n    func isEmptyElement() -> Bool {\n        return elements.isEmpty\n    }\n    \n    \n}\n\n// Implementación de cola (queue) utilizando un array\nstruct Queue<T> {\n    private var elements = [T]()\n    \n    mutating func enqueue(_ element: T){\n        elements.append(element)\n    }\n    \n    mutating func dequeue() -> T? {\n           if elements.isEmpty {\n               return nil\n           } else {\n               return elements.removeFirst()\n           }\n       }\n    \n    func isEmptyQueue() -> Bool {\n        return elements.isEmpty\n    }\n}\n\n// Simulación de un navegador web\nfunc isWebBrowser(){\n    var historyBack = Stack<String>()\n    var historyForward = Stack<String>()\n    \n    var currentWebsite = \"Homepage\"\n    \n    while true {\n        print(\"ingresa una acción (adelante, atrás o una URL):\")\n        let input = readLine() ?? \"\"\n        \n        switch input.lowercased() {\n        case \"adelante\":\n            if !historyForward.isEmptyElement(){\n                historyBack.push(currentWebsite)\n                currentWebsite = historyForward.pop()!\n            }else {\n                print(\"No hay paginas adelante en el historial\")\n            }\n        case \"atras\":\n            if !historyBack.isEmptyElement(){\n                historyForward.push(currentWebsite)\n                currentWebsite = historyForward.pop()!\n            }else {\n                print(\"No hay paginnas atras del historia.\")\n            }\n        default:\n            historyBack.push(currentWebsite)\n            currentWebsite = input\n            historyForward = Stack<String>()\n        }\n        print(\"Pagina actual \\(currentWebsite)\")\n    }\n}\n\n// probar funcion de simulación de Web\nisWebBrowser()\n\n// Simulación de una Impresora\nfunc isPrint(){\n    var printQueue = Queue<String>()\n    \n    while true {\n        print(\"Ingrsa una acción (imprimiendo documento...):\")\n        \n        let input = readLine() ?? \"\"\n        \n        if input.lowercased() == \"imprimir\" {\n            if let document = printQueue.dequeue(){\n                print(\"imprimiendo documento \\(document)\")\n            }else {\n                print(\"No hay documento en la cola de impresión\")\n            }\n        }else {\n            printQueue.enqueue(input)\n            print(\"Documento agregado a la cola.\")\n        }\n    }\n}\n\n// probar funcion de simulación de inpresión\nisPrint()\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/swift/pedroomar23.swift",
    "content": "import Foundation \n\n/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n \n// Stacks (Pilas)\nstruct Stacks<Element> {\n    private var numero: [Element] = [] // Array de Elementos \n\n    mutating func push(_ numero: Element) {\n        return numero.push(numero) // Añadir un nuevo elemento \n    }\n\n    mutating func pop() -> Element? {\n        return numero.popLast() \n    }\n\n    mutating func peek() -> Element? {\n        return numero.last \n    }\n\n    var isEmpty: Bool {\n        numero.isEmpty // Verificar si hay un elemento vavio \n    }\n\n    var count: Int {\n        numero.count // Contar los eleemntos del array \n    }\n}\n\nvar numeros = Stack<Int>()\nnumeros.push(1)\nnumeros.push(2)\nnumeros.push(3)\n\nprint(nombres)\n\n// Queue (Colas)\nstruct Queue<Element> {\n    private var nombre: [Element] = [] // Array de Elementos \n\n    mutating func append(_ nombre: Element) { // Añadir un elemento al Array \n        return nombre.append(nombre)\n    }\n\n    mutating func pop() -> Element? {\n        if nombre.isEmpty {\n            return nil \n        } else {\n            nombre.removeFirst()\n        }\n    }\n\n    mutating func peek() -> Element? {\n        return nombre.first \n    }\n\n    var isEmpty: Bool {\n        return nombre.isEmpty \n    }\n\n    var count: Int {\n        return nombre.count \n    }\n}\n\nvar nombre = Queue<String>()\nnombre.append(\"Juan\")\nnombre.append(\"Pedro\")\n\nprint(nombre)\n\n\n \n \n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/swift/zetared92.swift",
    "content": "import Foundation\n// Reto #07 PILAS Y COLAS\n\n// PILAS\n/* \nUna pila o stack es una estructura de datos\nque almacena los elementos bajo el principio\nLI-FO (Last in First Out) -> último en entrar,\nprimero en salir.\n\nTiene dos func básicas, Push/Pop.\nPush: Se encarga de agregar un elemento a la\npila. Se inserta en la parte superior.\nPop: Saca el elemento y lo retorna.\n*/\n\nclass Stack {\n    var stack: [AnyObject]\n\n    init() {\n        stack = [AnyObject]()\n    }\n\n    func push(object: AnyObject) -> Bool {\n        return stack.append(object)\n    }\n\n    func pop() -> AnyObject? {\n        if !isEmpty() {\n            return stack.removeLast()\n        } else {\n            return nil \n        }\n    }\n\n    func isEmpty() -> Bool {\n        return stack.isEmpty\n    }\n\n    func peek() -> AnyObject {\n        return stack.last\n    }\n\n    func size() -> Int {\n        return stack.count\n    }\n} \n\n// COLAS\n/*\nLas colas o queues se rigen por el principio\nFI-FO (First In-First Out), primero en entrar,\nprimero en salir.\n*/\n\nclass Queue {\n    var queue: [AnyObject]\n\n    init() {\n        queue = [AnyObject]()\n    }\n\n    func enqueue(object: AnyObject) -> Bool {\n        return queue.append(object)\n    }\n\n    func dequeue() -> AnyObject? {\n        if !isEmpty() {\n            return queue.removeFirst()\n        } else {\n            return nil \n        }\n    }\n\n    func isEmpty() -> Bool {\n        return queue.isEmpty\n    }\n\n    func peek() -> AnyObject? {\n        return queue.first\n    }\n\n    func size() -> Int {\n        return queue.count\n    }\n}\n\n\n// 🧩 DIFICULTAD EXTRA 🧩 - SIMULADOR DE NAVEGADOR WEB.\nvar webSites: [String] = []\nvar stackProgramContinue = true\nvar step: Int = 1\n\nshowStackMenu()\n\nwhile stackProgramContinue {\n    if let input = readLine() {\n        switch input {\n            case inpuWeb(web: input):\n                webSites.append(input)\n                if let last = webSites.last {\n                    print(last)\n                }\n\n            case \"Back\":\n                if webSites.isEmpty {\n                    print(\"Not pages found\")\n                    continue\n                }\n                step += 1\n                if step == webSites.count + 1 {\n                    step = webSites.count\n                    print(\"Not more pages\")\n                } else {\n                    print(webSites[webSites.count - step])\n                }\n\n            case \"Forward\":\n                if webSites.isEmpty {\n                    print(\"Not pages found\")\n                    continue\n                }\n                step -= 1\n                if step == 0 {\n                    step = 1\n                    print(\"Not more pages\")\n                } else {\n                    print(webSites[webSites.count - step])\n                }\n            \n            case \"Exit\":\n                stackProgramContinue = false\n            default:\n                print(\"Invalid option\")\n        }\n    }\n}\n\nfunc inputWebSite(web name: String) -> String {\n    var firstChar = \"\"\n    var lastChar: String = \"\"\n    var lastCharReversed: String = \"\"\n\n    for char in name {\n        firstChar.append(char)\n        if firstChar.count == 4 {\n            break\n        }\n    }\n\n    for char: Character in name.reversed() {\n        lastCharReversed.append(char)\n        if lastCharReversed.count == 4 {\n            break\n        }\n    }\n\n    for char: Character in lastCharReversed.reversed() {\n        lastChar.append(char)\n    }\n\n    if firstChar == \"www.\" && lastChar == \".com\" {\n        return name\n    }\n\n    return \"Invalid Website\"\n}\n\nfunc showStackMenu() {\n    print(\"\\nInput a option.\\n\")\n    print(\"[WebSite]\")\n    print(\"[Back]\")\n    print(\"[Forward]\")\n    print(\"[Exit]\")\n}\n\n// 🧩 DIFICULTAD EXTRA 🧩 - SIMULADOR DE IMPRESORA.\nvar docs: [String] = []\nvar queueProgramContinue: Bool = true\n\nshowQueueMenu()\n\nwhile queueProgramContinue {\n    if let input = readLine() {\n\n        switch input {\n            case inputDocument(doc: input):\n                docs.append(input)\n            case \"Print\":\n                if docs.isEmpty {\n                    print(\"Not Docs for print\")\n                } else {\n                    if let first = docs.first {\n                        print(first)\n                    }\n                    docs.removeFirst()\n                }\n            case \"Exit\":\n                queueProgramContinue = false\n            default:\n                print(\"Invalid option\")\n        }\n    }\n}\n\nfunc inputDocument(doc name: String) -> String {\n    if name.contains(\".pdf\") {\n        return name\n    }\n\n    return \"Invalid Document\"\n}\n\nfunc showQueueMenu() {\n    print(\"\\nInput an option\\n\")\n    print(\"[.pdf File]\")\n    print(\"[Print]\")\n    print(\"Exit\")\n}"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/typescript/AChapeton.ts",
    "content": "//PILAS (STACK)\nconst pila: Array<Number> = [1, 2, 3, 4, 5]\nconsole.log('pila original', pila)\npila.push(6)\nconsole.log('agregar elemento a la pila en la ultima posicion', pila)\npila.pop()\nconsole.log('eliminar el ultimo elemento agregado a la pila', pila)\n\n// *COLAS (QUEUE)\nconst cola: Array<String> = ['b', 'c', 'd', 'e', 'f']\nconsole.log('cola original', cola)\ncola.unshift('a')\nconsole.log('agregar elemento a la cola en la ultima posicion (izquierda)', cola)\ncola.pop()\nconsole.log('eliminar el ultimo elemento de la cola (elementos que fue agregado primero)', cola)\n\n//  *   DIFICULTAD EXTRA\n\n//  *   Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n//  *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n//  *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n//  *   interpretan como nombres de documentos.\nconst documentos: Array<string> = ['cv.txt', 'examen.txt', 'test.txt', 'comandos.txt']\n\nlet impresora: Array<string> = []\n\nconsole.log('agregando a impresora')\nfor(let i: number = 0; i < documentos.length; i++){\n  impresora.unshift(documentos[i])\n  console.log('Cola de impresion: ', impresora)\n}\n\nconsole.log('imprimiendo')\ndo{\n  impresora.pop()\n  console.log('impresiones pendientes: ', impresora)\n} while(impresora.length > 0)\n\n//  *   Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n//  *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n//  *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n//  *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n//  *   el nombre de una nueva web.\n\nconst historial: Array<string | null> = []\nlet paginaActual: number = 0\n\nconst agregarPagina = (web: string) => {\n  if(historial.length > 0){\n    paginaActual++ \n  }\n  historial.push(web)\n}\n\nconst atras = () => {\n  console.log( historial[paginaActual-1])\n}\n\nconst adelante = () => {\n  console.log( historial[paginaActual+1])\n}\n\nagregarPagina('test.com')\n\nconsole.log(historial)\n\nagregarPagina('new.com')\n\nconsole.log(historial)\n\natras()\n\nconsole.log(historial)"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/typescript/IgleDev.ts",
    "content": "// 1º Ejercicio\n    // Array\n        // Pilas (STACKS - LIFO)\n        /**\n         * Se les llama LIFO (Last In First Out) porque\n         * el último elemento agregado, es el primero en salir\n        */\n            // Creamos un Array con el que vamos a trabajar.\n                let aprobados : string[] = ['Adrian', 'IgleDev'];\n            // Añadimos uno nuevo a la lista\n                aprobados.push('Mouredev');\n            // Comprobamos la lista y el tamaño\n                console.log(aprobados.length + ' - ' + aprobados);\n            // Ahora tendremos que sacarlo\n                aprobados.pop();\n            // Comprobamos la lista y el tamaño\n                console.log(aprobados.length + ' - ' + aprobados);\n\n        // Colas (QUEUE  - FIFO)\n        /**\n         * Se les llama FIFO (First In First Out) porque\n         * el primer elemento agregado, es el primero en salir\n        */\n            // Creamos un Array con el que vamos a trabajar.\n                let coladelBanco : string[] = ['Adrian', 'IgleDev'];\n            // Añadimos uno nuevo a la lista\n                coladelBanco.push('Mouredev');\n            // Comprobamos la lista y el tamaño\n                console.log(coladelBanco.length + ' - ' + coladelBanco);\n            // Ahora tendremos que sacar al 1º\n                coladelBanco.shift();\n            // Comprobamos la lista y el tamaño\n                console.log(coladelBanco.length + ' - ' + coladelBanco);\n    // Listas\n            // Pilas (STACKS - LIFO)\n            /**\n             * Se les llama LIFO (Last In First Out) porque\n             * el último elemento agregado, es el primero en salir\n            */\n                // Creamos un Array con el que vamos a trabajar.\n                    let aprobadosLista : Array<string> = ['Adrian', 'IgleDev'];\n                // Añadimos uno nuevo a la lista\n                    aprobadosLista.push('Mouredev');\n                // Comprobamos la lista y el tamaño\n                    console.log(aprobadosLista.length + ' - ' + aprobadosLista);\n                // Ahora tendremos que sacarlo\n                    aprobadosLista.pop();\n                // Comprobamos la lista y el tamaño\n                    console.log(aprobadosLista.length + ' - ' + aprobadosLista);\n\n            // Colas (QUEUE  - FIFO)\n            /**\n             * Se les llama FIFO (First In First Out) porque\n             * el primer elemento agregado, es el primero en salir\n            */\n                // Creamos un Array con el que vamos a trabajar.\n                    let coladelBancoLista : Array<string> = ['Adrian', 'IgleDev'];\n                // Añadimos uno nuevo a la lista\n                    coladelBancoLista.push('Mouredev');\n                // Comprobamos la lista y el tamaño\n                    console.log(coladelBancoLista.length + ' - ' + coladelBancoLista);\n                // Ahora tendremos que sacar al 1º\n                    coladelBancoLista.shift();\n                // Comprobamos la lista y el tamaño\n                    console.log(coladelBancoLista.length + ' - ' + coladelBancoLista);\n// Ejercicio Extra\n    // Ejercicio de Pila (STACKS - LIFO)\n        class Navegador {\n            historial: string[];\n            actual: string;\n        \n            constructor() {\n                this.historial = [];\n                this.actual = '';\n            }\n        \n            navegar(url: string) {\n                if (url === 'atras') {\n                    if (this.historial.length > 0) {\n                        this.actual = this.historial.pop()!;\n                        console.log('Navegando hacia atrás a:' + this.actual);\n                    } else {\n                        console.log('No hay páginas para retroceder.');\n                    }\n                } else if (url === 'adelante') {\n                    console.log('No se puede navegar hacia adelante sin haber retrocedido previamente.');\n                } else {\n                    this.historial.push(this.actual);\n                    this.actual = url;\n                    console.log('Navegando a:' + this.actual);\n                }\n            }\n        }\n\n        let navegador = new Navegador();\n\n        navegador.navegar(\"google.com\");\n        navegador.navegar(\"wikipedia.org\");\n        navegador.navegar(\"atras\");\n        navegador.navegar(\"adelante\");\n        navegador.navegar(\"facebook.com\");\n\n    // Ejercico Cola\n        class Impresora {\n            cola: string[];\n        \n            constructor() {\n                this.cola = [];\n            }\n        \n            recibirDocumento(documento: string) {\n                this.cola.push(documento);\n                console.log('Documento:' + documento);\n            }\n        \n            imprimir() {\n                if (this.cola.length > 0) {\n                    let documento = this.cola.shift()!;\n                    console.log('Imprimiendo documento:' + documento);\n                } else {\n                    console.log('No hay documentos en la cola para imprimir.');\n                }\n            }\n        }\n        \n        let impresora = new Impresora();\n        \n        impresora.recibirDocumento(\"Documento1.txt\");\n        impresora.recibirDocumento(\"Documento2.pdf\");\n        impresora.imprimir();\n        impresora.imprimir();\n        impresora.imprimir();"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/typescript/RicJDev.ts",
    "content": "//EJERCICIO\n//Stack - LIFO\nconsole.log('STACK')\n\nconst stack: number[] = [1, 2, 3]\n\nconsole.log('Array original:', stack)\n\nstack.push(4)\nconsole.log('Después de agregar un elemento:', stack)\n\nstack.pop()\nconsole.log('Después de eliminar un elemento:', stack)\n\n//Queue - FIFO\nconsole.log('\\nQUEUE')\n\nconst queue: number[] = [1, 2, 3]\n\nconsole.log('Array original:', queue)\n\nqueue.push(4)\nconsole.log('Después de agregar un elemento:', queue)\n\nqueue.shift()\nconsole.log('Después de eliminar un elemento:', queue)\n\n//EXTRA\nimport * as readline from 'readline'\n\nconst rl = readline.createInterface({\n\tinput: process.stdin,\n\toutput: process.stdout,\n})\n\n//Sistema de navegación\nfunction browser(): void {\n\tconst pagesStack: string[] = []\n\n\tfunction menu(): void {\n\t\tif (pagesStack.length > 0) {\n\t\t\tconsole.log(`\\nActualmente estas en ${pagesStack[pagesStack.length - 1]}`)\n\t\t} else {\n\t\t\tconsole.log('\\nEstas en la pagina de inicio')\n\t\t}\n\n\t\trl.question(\n\t\t\t'Elige una opcion\\n1. Avanzar\\n2. Retroceder\\n3. Salir del navegador ',\n\t\t\t(answer) => {\n\t\t\t\tif (answer === '1') {\n\t\t\t\t\tmenu()\n\t\t\t\t} else if (answer === '2') {\n\t\t\t\t\tpagesStack.pop()\n\t\t\t\t\tmenu()\n\t\t\t\t} else if (answer === '3') {\n\t\t\t\t\tconsole.log('\\nSaliendo del navegador...')\n\t\t\t\t\tprinter()\n\t\t\t\t} else {\n\t\t\t\t\tpagesStack.push(answer)\n\t\t\t\t\tmenu()\n\t\t\t\t}\n\t\t\t}\n\t\t)\n\t}\n\n\tmenu()\n}\n\n//Impresora compartida\nfunction printer(): void {\n\tconst printerQueue: string[] = []\n\n\tfunction menu(): void {\n\t\tif (printerQueue.length > 0) {\n\t\t\tconsole.log('\\nDocumentos pendientes')\n\n\t\t\tprinterQueue.forEach((doc) => {\n\t\t\t\tconsole.log(`- ${doc}`)\n\t\t\t})\n\t\t} else {\n\t\t\tconsole.log('\\nNo hay documentos pendientes')\n\t\t}\n\n\t\tfunction printDoc() {\n\t\t\tif (printerQueue.length > 0) {\n\t\t\t\tconsole.log(`\\nImprimiendo ${printerQueue[0]}...`)\n\t\t\t\tprinterQueue.shift()\n\t\t\t}\n\t\t}\n\n\t\trl.question('Elige una opcion\\n1. Imprimir\\n2. Salir ', (answer) => {\n\t\t\tif (answer === '1') {\n\t\t\t\tprintDoc()\n\t\t\t\tmenu()\n\t\t\t} else if (answer === '2') {\n\t\t\t\tconsole.log('\\nCerrando impresora...')\n\t\t\t\trl.close()\n\t\t\t} else {\n\t\t\t\tprinterQueue.push(answer)\n\t\t\t\tmenu()\n\t\t\t}\n\t\t})\n\t}\n\n\tmenu()\n}\n\nbrowser()\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/typescript/RobertoAmaroHub.ts",
    "content": "let clientes:string[]=[\"Roberto\", \"Sara\"];\n\nfunction addCliente(nombre:string){\n    if(nombre.length>0){\n        clientes.push(nombre);\n    }\n    console.log(`\\nel cliente ${nombre} agregado:`)\n    console.log(clientes)\n}\nfunction removePila(){\n    clientes.pop();\n    console.log(\"\\nRemoviendo último cliente:\")\n    console.log(clientes)\n}\n\nfunction removeToCola(){\n    clientes.shift();\n    console.log(\"\\nRemoviendo el primer cliente:\")\n    console.log(clientes)\n}\n\naddCliente(\"Carlos\");\nremovePila(); \naddCliente(\"Rodrigo\");\nremoveToCola();\n\n\n//EXTRA PILAS***************************************\nvar prompt = require(\"prompt-sync\")();\nimport * as readline from 'readline';\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nlet paginasWeb:string[]=[\"google.com\"];\n\nconsole.log(\"*****Navegando entre páginas*****\")\nconsole.log(`\\nintroduzca la palabra \"atras\" o \"adelante\" para navegar entre las páginas.\n            cualquier otra palabra introducida servirá para agregar una página nueva a la pila de páginas.\n            escriba \"salir\" para terminar el programa.`)\nconsole.log(\"\\npáginas actuales:\")\nconsole.log(paginasWeb);\n\nlet currentPage:number=0;\nlet accion:string=\"\";\n\nfunction iniciarPila(){\n    accion=prompt(\"Introduzca una palabra: \");\n    if(accion.trim().length<=0){\n        console.log(\"La palabra no puede estar vacía, inténtalo de nuevo\")\n    }\n    if(accion.trim().toLowerCase()==\"atras\"){\n       volverAtras();\n       iniciarPila();\n    } else if(accion.trim().toLowerCase()==\"adelante\"){\n       irAdelante();\n       iniciarPila();\n    } else if(accion.trim().toLowerCase()==\"salir\"){\n        rl.close();\n    } else {\n        agregarPagina();\n        iniciarPila();\n    }\n}\n\nfunction volverAtras(){\n    if(currentPage<=0){\n        return console.log(paginasWeb[0]);\n    }\n    else{\n        currentPage--;\n        return console.log(paginasWeb[currentPage]);\n    }\n}\n\nfunction irAdelante(){\n    if(currentPage>=paginasWeb.length-1){\n        return console.log(paginasWeb[paginasWeb.length-1]);\n    } else{\n        currentPage++;\n        return console.log(paginasWeb[currentPage]);\n    }\n}\n\nfunction agregarPagina(){\n    paginasWeb.push(accion);\n    console.log(`Nueva página ${accion} agregada:`)\n    console.log(paginasWeb);\n}\n\n//EXTRA COLAS***************************************\nlet colaImpresion:string[]=[\"Hoja1\"];\nconsole.log(\"\\n******************Impresión de documentos******************\")\nconsole.log(`Documentos en cola actualmente: ${colaImpresion}`);\nconsole.log(`Si desea agregar una hoja a la cola de impresión escriba el nombre del documento, \n        si desea imprimir la última hoja en la cola escriba \"imprimir\",\n        si desea salir de la aplicación escriba \"salir\".\\n`)\n\nfunction iniciarCola(){\n    let respuesta=prompt(`Introduzca la acción deseada: `)\n    if(validarRespuesta(respuesta)){\n        switch (respuesta.trim().toLowerCase()) {\n            case \"imprimir\":\n                imprimir();\n                iniciarCola();\n                break;\n            case \"salir\":\n                rl.close();\n                break;\n            default:\n                agregarAlaCola(respuesta);\n                iniciarCola();\n                break;\n        }\n    }\n}\nfunction validarRespuesta(res:string):boolean{\n    if(res.trim().length<=0){\n        console.log(\"\\nLa respuesta no puede ser vacía, inténtalo de nuevo.\")\n        return false;\n    } else {\n        return true;\n    }\n}\n\nfunction imprimir(){\n    if(colaImpresion.length<0){\n        console.log(\"\\nNo hay documentos en cola para imprimir.\");\n    } else {\n        console.log(`\\nDocumento impreso: ${colaImpresion.shift()}`);\n        console.log(colaImpresion);\n    }\n}\n\nfunction agregarAlaCola(doc:string){\n    colaImpresion.push(doc);\n    console.log(`\\nEl documento ${doc} fue agregado a la cola de impresión:`);\n    console.log(colaImpresion);\n}\n\n\n\niniciarPila();\nconsole.log(\"\\n\")\niniciarCola();\n\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/typescript/Sac-Corts.ts",
    "content": "// Stack\nclass Stack<T> {\n    private items: T[] = [];\n\n    push(element: T): void {\n        this.items.push(element);\n    }\n\n    pop(): T | undefined {\n        if (this.items.length === 0) {\n            console.log(\"Stack is empty\");\n            return undefined;\n        }\n        return this.items.pop();\n    }\n\n    peek(): T | undefined {\n        if (this.items.length === 0) {\n            console.log(\"Stack is empty\");\n            return undefined;\n        }\n        return this.items[this.items.length - 1];\n    }\n\n    isEmpty(): boolean {\n        return this.items.length === 0;\n    }\n\n    size(): number {\n        return this.items.length;\n    }\n\n    clear(): void {\n        this.items = [];\n    }\n}\n\nconst stack = new Stack<number>();\nstack.push(10);\nstack.push(20);\nconsole.log(stack.peek());\nconsole.log(stack.pop());\nconsole.log(stack.isEmpty());\nconsole.log(stack.size());\nconsole.log(stack.clear());\n\n\n// Queue\nclass Queue<T> {\n    private items: T[] = [];\n\n    enqueue(element: T): void {\n        this.items.push(element);\n    }\n\n    dequeue(): T | undefined {\n        if (this.items.length === 0) {\n            console.log(\"Queue is empty\");\n            return undefined;\n        }\n        return this.items.shift();\n    }\n\n    front(): T | undefined {\n        if (this.items.length === 0) {\n            console.log(\"Queue is empty\");\n            return undefined;\n        }\n        return this.items[0];\n    }\n\n    isEmpty(): boolean {\n        return this.items.length === 0;\n    }\n\n    size(): number {\n        return this.items.length;\n    }\n\n    clear(): void {\n        this.items = [];\n    }\n}\n\nconst queue = new Queue<number>();\nqueue.enqueue(10);\nqueue.enqueue(20);\nconsole.log(queue.front());\nconsole.log(queue.dequeue());\nconsole.log(queue.isEmpty());\nconsole.log(queue.size());\nconsole.log(queue.clear());\n\n// *** Extra Exercise *** //\n\n// Browser History\nclass BrowserNavigation {\n    private backStack: string[] = [];\n    private forwardStack: string[] = [];\n    private currentPage: string | null = null;\n\n    navigateTo(page: string): void {\n        if (this.currentPage) {\n            this.backStack.push(this.currentPage);\n        }\n        this.currentPage = page;\n        this.forwardStack = [];\n        console.log(`Navigate to: ${this.currentPage}`);\n    }\n\n    goBack(): void {\n        if (this.backStack.length === 0) {\n            console.log(\"There are not pages back\");\n            return;\n        }\n        if (this.currentPage) {\n            this.forwardStack.push(this.currentPage);\n        }\n        this.currentPage = this.backStack.pop() || null;\n        console.log(`Going back to: ${this.currentPage}`);\n    }\n\n    goForward(): void {\n        if (this.forwardStack.length === 0) {\n            console.log(\"There are not pages forward\");\n            return;\n        }\n        if (this.currentPage) {\n            this.backStack.push(this.currentPage);\n        }\n        this.currentPage = this.forwardStack.pop() || null;\n        console.log(`Moving forward: ${this.currentPage}`);\n    }\n}\n\nconst browser = new BrowserNavigation();\n\nfunction simulateNavigation(action: string): void {\n    if (action === 'back') {\n        browser.goBack();\n    } else if (action === \"forward\") {\n        browser.goForward();\n    } else {\n        browser.navigateTo(action);\n    }\n}\n\nsimulateNavigation(\"google.com\");\nsimulateNavigation(\"github.com\");\nsimulateNavigation(\"stackoverflow.com\");\nsimulateNavigation(\"back\");\nsimulateNavigation(\"back\");\nsimulateNavigation(\"forward\");\nsimulateNavigation(\"youtube.com\");\nsimulateNavigation(\"back\");\nsimulateNavigation(\"forward\");\n\n// Printer\nclass PrinterQueue {\n    private queue: string[] = [];\n\n    addDocument(document: string): void {\n        this.queue.push(document);\n        console.log(`Document \"${document}\" added to queue`);\n    }\n\n    printDocument(): void {\n        if (this.queue.length === 0) {\n            console.log(\"There are not documents in the queue\");\n            return;\n        }\n        const nextDocument = this.queue.shift();\n        console.log(`Printing: ${nextDocument}`);\n    }\n\n    isEmpty(): boolean {\n        return this.queue.length === 0;\n    }\n}\n\nconst printer = new PrinterQueue();\n\nfunction simulatePrinter(action: string): void {\n    if (action === \"print\") {\n        printer.printDocument();\n    } else {\n        printer.addDocument(action);\n    }\n}\n\nsimulatePrinter(\"document1.pdf\");\nsimulatePrinter(\"document2.pdf\");\nsimulatePrinter(\"print\");\nsimulatePrinter(\"document3.docx\");\nsimulatePrinter(\"print\");\nsimulatePrinter(\"print\");\nsimulatePrinter(\"print\");"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/typescript/david-git-dev.ts",
    "content": "/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).*/\n//pilas (stacks - LIFO)\nclass Stack {\n  private stack: string[] = [];\n  constructor() {}\n  agregar(value: string) {\n    this.stack.push(value);\n  }\n  eliminar() {\n    this.stack.pop();\n  }\n  get getStack() {\n    return this.stack;\n  }\n}\n//las colas (queue - FIFO)\nclass Queque {\n  private queque: string[] = [];\n  constructor() {}\n  agregar(value: string) {\n    this.queque.unshift(value);\n  }\n  eliminar() {\n    this.queque.pop();\n  }\n  get getQueque() {\n    return this.queque;\n  }\n}\nconst cola = new Queque();\nconst pila = new Stack();\ncola.agregar(\"cliente1\");\ncola.agregar(\"cliente2\");\ncola.agregar(\"cliente3\");\ncola.eliminar();\ncola.eliminar();\npila.agregar(\"cliente4\");\npila.agregar(\"cliente5\");\npila.agregar(\"cliente6\");\npila.eliminar();\npila.eliminar();\nconsole.log(cola.getQueque, pila.getStack);\n\n /*\n  DIFICULTAD EXTRA (opcional):\n  - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n    de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n    que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n    Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n    el nombre de una nueva web.*/\nclass WebBrowser{\n  private searchBar:string[]=[]\n  constructor(){\n\n  }\n   search(url:string){\nthis.searchBar.push(url);\n   }\n   /*adelante(){\n    /* const history = this.searchBar.length\n    if(history>1){\n      const url = this.searchBar.shift()\n      this.searchBar.push(url as string)\n    console.log(url);\n    }else{\n    console.log('ya estas en la pagina mas actual');\n\n    } */\n   atras(url:string){\n    const history = this.searchBar.length\n    if(history>1){\n      const url = this.searchBar.pop()\n    }else{\n      console.log('blank tab...');\n    }\n  }\n}\n  /*\n  - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n    impresora compartida que recibe documentos y los imprime cuando así se le indica.\n    La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n    interpretan como nombres de documentos.\n */\n    class Printer {\n      private queque: string[] = [];\n      constructor() {}\n      set add(doc: string) {\n        this.queque.unshift(doc);\n      }\n      print() {\n        return this.queque.length > 0 ? this.queque.pop() : 'No hay nada para imprimir...';\n      }\n      get getQueque() {\n        return this.queque;\n      }\n    }\n    function startPrinter() {\n      const printer = new Printer();\n      console.log(\"//Iniciando interfaz....\");\n      let data: string | null;\n      do {\n        data = prompt(\n          \"Dame el nombre del documento o escribe imprimir para comenzar a trabajar...\"\n        );\n\n        if (data && data.toLocaleLowerCase() !== \"imprimir\") {\n          printer.add = data.toLowerCase();\n          alert(`agregado ->${data}`);\n        } else if (data && data.toLowerCase() === \"imprimir\") {\n          alert(`Imprimiendo->${printer.print()}`);\n        }\n            if(data) alert(printer.getQueque.toString())\n\n      } while (data && printer.getQueque.length>0);\n    }\n    startPrinter();\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/typescript/duendeintemporal.ts",
    "content": "/* #07 { Retosparaprogramadores } Pilas y Colas  */\n//I use GPT & Deepseekto generate accurate comments and also as a reference.\n\n  //shorthand for console.log()\n  let log = console.log;\n\n//The array structure can be useful in JavaScript as in Typescript to simulate stacks and queues.\n\n/* A stack is a linear data structure that follows the Last In, First Out (LIFO) principle. This means that the last element added to the stack is the first one to be removed. You can think of it like a stack of plates: you add plates to the top and also remove them from the top.\nKey Operations:\n\n    Push: Add an element to the top of the stack.\n    Pop: Remove the element from the top of the stack.\n    Peek/Top: Retrieve the top element without removing it.\n    IsEmpty: Check if the stack is empty.\n */\n\n  //Pila(Stack)\n  let stack: number[] = [1,2,3,4];\n  \n  //view the contents of a stack\n  log('view stack: ', stack); // view stack: [ 1, 2, 3, 4 ]\n\n  //add an element to the stack\n  stack.push(5);\n  log('add an element: ', stack); // add an element: [ 1, 2, 3, 4, 5 ] \n\n  //get the size of the stack\n  log('size: ', stack.length); // size:  5\n\n  //get the last value of the stack\n  log('last value of the stack: ', stack[stack.length - 1]); // last value of the stack:  5\n\n  //remove the last value from the stack and print its value\n log('delete and return the last value: ', stack.pop()); // delete and return the last value:  5\n\n //empty the stack\n stack = [];\n log('empty the stack: ', stack); // empty the stack: []\n\n /* we can also enclosed in a function or a class for better organization and reusability */\n interface IStack<T> {\n    push(element: T): void;\n    pop(): T | undefined;\n    peek(): T | undefined;\n    empty(): T[];\n    isEmpty(): boolean;\n    size(): number;\n    getItems(): T[];\n}\n\nclass Stack<T> implements IStack<T> {\n    private items: T[];\n    \n    constructor(initialItems: T[] = []) {\n        this.items = Array.isArray(initialItems) ? initialItems : [];\n    }   \n    \n    getItems(): T[] {\n        return [...this.items];\n    }\n\n    push(element: T): void {\n        this.items.push(element);\n    }\n\n    pop(): T | null {\n        if (this.isEmpty()) {\n            console.error(\"Stack is empty. Cannot pop an element.\");\n\n            return null;\n        }\n        const item = this.items.pop();\n        return item !== undefined ? item : null;\n    }\n\n    peek(): T | undefined {\n        if (this.isEmpty()) {\n            console.error(\"Stack is empty. Cannot peek.\");\n\n            return undefined;\n        }\n        return this.items[this.items.length - 1];\n    }\n\n    empty(): T[] {\n        return this.items = [];\n    }\n\n    isEmpty(): boolean {\n        return this.items.length === 0;\n    }\n\n    size(): number {\n        return this.items.length;\n    }\n}\n\n// Test code starts here\nfunction testStack() {\n    const stack2 = new Stack<number>([55, 76, 98, 100]);\n    log('Initial stack2:', stack2.getItems());\n\n    stack2.push(32);\n    log('After pushing 32:', stack2.getItems());\n\n    log('Peek:', stack2.peek());\n\n    log('Pop:', stack2.pop());\n    log('After popping:', stack2.getItems());\n\n    log('Pop all elements:');\n    while (!stack2.isEmpty()) {\n        log('Popped:', stack2.pop());\n    }\n\n    log('Final stack2:', stack2.getItems());\n    log('Pop from empty stack2:', stack2.pop());\n}\n\n// Run the test\ntestStack();\n/*\nInitial stack2: [ 55, 76, 98, 100 ] \nAfter pushing 32: [ 55, 76, 98, 100, 32 ]\nPeek: 32\nPop: 32\nAfter popping: [ 55, 76, 98, 100 ]\nPop all elements:\nPopped: 100\nPopped: 98\nPopped: 76\nPopped: 55\nFinal stack2: []\nStack is empty. Cannot pop an element.\nPop from empty stack2: null\n*/\n\n //Cola(Queue)\n\n /* A queue is a linear data structure that follows the First In, First Out (FIFO) principle. This means that the first element added to the queue is the first one to be removed. You can think of it like a line of people waiting for service: the first person in line is the first to be served.\nKey Operations:\n\n    Enqueue: Add an element to the end of the queue.\n    Dequeue: Remove the element from the front of the queue.\n    Front/Peek: Retrieve the front element without removing it.\n    IsEmpty: Check if the queue is empty.\n */\n\n  let queue: number[] = [8, 5, 4, 2, 1];\n\n  //view the contents of a queue\n  log('view queue: ', queue); // view queue: [ 8, 5, 4, 2, 1 ]\n\n  //add elements to the queue\n  queue.push(7);\n  log('add an element: ', queue); // add an element: [ 8, 5, 4, 2, 1, 7 ]\n\n  //get the size of the queue\n  log('size: ', queue.length); // size:  6\n\n  //get the first value of the queue\n  log('first value: ', queue[0]); // first value:  8\n\n  //remove the first value from the queue and print its value\n  log('delete and return the first value ', queue.shift()); // delete and return the first value  8\n\n  //empty the queue\n  queue = [];\n  log('empty the queue: ', queue); // empty the queue: [] \n\n /* we can also enclosed in a function or a class for better organization and reusability */\n interface IQueue<T> {\n    enqueue(element: T): void;\n    dequeue(): T | undefined;\n    peek(): T | undefined;\n    empty(): T[];\n    isEmpty(): boolean;\n    size(): number;\n    getItems(): T[];\n}\n\nclass Queue<T> implements IQueue<T> {\n    private items: T[];\n\n    constructor(initialItems: T[] = []) {\n        this.items = Array.isArray(initialItems) ? initialItems : [];\n    }\n\n    getItems(): T[] {\n        return [...this.items];\n    }\n\n    enqueue(element: T): void {\n        this.items.push(element);\n    }\n\n    dequeue(): T | undefined {\n        if (this.isEmpty()) {\n            console.error(\"Queue is empty. Cannot dequeue an element.\");\n            return undefined;\n        }\n        return this.items.shift();\n    }\n\n\n    peek(): T | undefined {\n        if (this.isEmpty()) {\n            console.error(\"Queue is empty. Cannot peek.\");\n            return undefined;\n        }\n        return this.items[0];\n    }\n\n    empty(): T[] {\n        return this.items = [];\n    }\n\n    isEmpty(): boolean {\n        return this.items.length === 0;\n    }\n\n    size(): number {\n        return this.items.length;\n    }\n}\n\nconst queue2 = new Queue<number>([45, 32, 16]); \nlog('Initial queue2:', queue2.getItems()); //  [45, 32, 16]\n\nqueue2.enqueue(77);\nlog('After enqueueing 4:', queue2.getItems()); //  [45, 32, 16, 77]\n\nlog('Peek:', queue2.peek()); //  45\n\nlog('Dequeue:', queue2.dequeue()); //  45\nlog('After dequeueing:', queue2.getItems()); //  [32, 16, 77]\n\nlog('Dequeue all elements:'); // Dequeue all elements:\nwhile (!queue2.isEmpty()) {\n    log('Dequeued:', queue2.dequeue());\n} // or we can just empty the queue queue2.empty()\n/*\nDequeued: 32\nDequeued: 16\nDequeued: 77\n*/\n\nlog('Final queue2:', queue2.getItems()); //  []\nlog('Dequeue from empty queue2:', queue2.dequeue()); // Queue is empty. Cannot dequeue an element. & null\n// Dequeue from empty queue2: undefined\n\n  //Additional exercises: \n  /* #1 Simulate the behavior of the back and forward buttons in a browser. */\n\n  // Custom document interface to avoid conflicts with built-in Document\ninterface FileDocument {\n    name: string;\n    content: string;\n}\n\nlet documentsQueue: FileDocument[] = [\n    { name: 'Tratado de Tantra.txt', content: 'Here comes the content of Tratado de Tantra.' },\n    { name: 'Nada Sagrado.doc', content: 'Here comes the content of Nada Sagrado.' },\n    { name: 'El Blanco Invisible.pdf', content: 'Here comes the content of El Blanco Invisible.' }\n];\n\nfunction printQueue(arr: FileDocument[]): void {\n    if(arr.length === 0) {\n        log('There no element to print in the queue!');\n        return;\n    }\n    while (arr.length > 0) {\n        const doc = arr.shift();\n        if (doc) {\n            log('Printing document:', doc.name);\n            log('Content:', doc.content);\n        }\n    }\n    log('There no more element to print in the queue!');\n}\n\nprintQueue(documentsQueue);/* Printing document: Tratado de Tantra.txt \nContent: Here comes the content of Tratado de Tantra. \nPrinting document: Nada Sagrado.doc \nContent: Here comes the content of Nada Sagrado. \nPrinting document: El Blanco Invisible.pdf \nContent: Here comes the content of El Blanco Invisible. \nThere no more element to print in the queue! */\n\n/* To read and print the contents of documents in JavaScript, you would typically need to use a file reading mechanism. However, JavaScript running in a browser environment does not have direct access to the file system for security reasons. Instead, you can simulate reading the contents of the documents by using predefined content or by using the File API if you're working with file inputs. */\n\n// Browser history types\ninterface BrowserState {\n    urlStack: string[];\n    currentIndex: number;\n}\n\nclass BrowserHistory {\n    private state: BrowserState = {\n        urlStack: [],\n        currentIndex: -1\n    };\n\n    private back(): void {\n        if (this.state.currentIndex > 0) {\n            this.state.currentIndex--;\n            const previousUrl = this.state.urlStack[this.state.currentIndex];\n            log('Location: ', previousUrl);\n            // window.location = previousUrl;\n        } else {\n            log(\"There are no more pages back..\");\n        }\n    }\n\n    private forward(): void {\n        if (this.state.currentIndex < this.state.urlStack.length - 1) {\n            this.state.currentIndex++;\n            const nextUrl = this.state.urlStack[this.state.currentIndex];\n            log('Location: ', nextUrl);\n            // window.location = nextUrl;\n        } else {\n            log(\"There are no more pages forward.\");\n        }\n    }\n\n    public browseWeb(url: string | null = null): void {\n        if (!url) return;\n\n        if (url !== 'back' && url !== 'forward') {\n            if (this.state.currentIndex < this.state.urlStack.length - 1) {\n                this.state.urlStack = this.state.urlStack.slice(0, this.state.currentIndex + 1);\n            }\n            this.state.urlStack.push(url);\n            this.state.currentIndex++;\n            log('Location: ', url);\n        } else if (url === 'back') {\n            this.back();\n        } else if (url === 'forward') {\n            this.forward();\n        }\n    }\n}\n\n// DOM manipulation types and interface\ninterface StyleProperties {\n    background?: string;\n    'text-align'?: string;\n    'font-size'?: string;\n    color?: string;\n    'line-height'?: string;\n}\n\nclass DOMManager {\n    private body: HTMLBodyElement | null;\n    private title: HTMLHeadingElement;\n\n    constructor() {\n        this.body = document.querySelector('body');\n        this.title = document.createElement('h1');\n    }\n\n    private setStyles(element: HTMLElement, styles: StyleProperties): void {\n        Object.entries(styles).forEach(([property, value]) => {\n            element.style.setProperty(property, value);\n        });\n    }\n\n    public initializePage(): void {\n        if (!this.body) return;\n\n        const bodyStyles: StyleProperties = {\n            'background': '#000',\n            'text-align': 'center'\n        };\n\n        const titleStyles: StyleProperties = {\n            'font-size': '3.5vmax',\n            'color': '#fff',\n            'line-height': '100vh'\n        };\n\n        this.setStyles(this.body, bodyStyles);\n        this.setStyles(this.title, titleStyles);\n\n        this.title.textContent = 'Retosparaprogramadores #7.';\n        this.body.appendChild(this.title);\n    }\n}\n\n\n    \n    log('Retosparaprogramadores #7'); // Retosparaprogramadores #7\n\n    // Test browser history\n    const browser = new BrowserHistory();\n    browser.browseWeb('www.lectura_prospectiva.net');\n    browser.browseWeb('www.test.web');\n    browser.browseWeb('back');\n    browser.browseWeb('forward');\n\n    /*  \nLocation:  www.lectura_prospectiva.net\nLocation:  www.test.web\nLocation:  www.lectura_prospectiva.net\nLocation:  www.test.web\n*/\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/typescript/eulogioep.ts",
    "content": "import * as readline from 'readline';\n\n// Implementación de la Pila (Stack - LIFO)\nclass Stack<T> {\n    private items: T[] = [];\n\n    // Método para añadir un elemento a la pila\n    push(element: T): void {\n        this.items.push(element);\n    }\n\n    // Método para quitar un elemento de la pila\n    pop(): T | undefined {\n        if (this.isEmpty()) {\n            console.log(\"Error: Pila vacía\");\n            return undefined;\n        }\n        return this.items.pop();\n    }\n\n    // Método para verificar si la pila está vacía\n    isEmpty(): boolean {\n        return this.items.length === 0;\n    }\n\n    // Método para obtener el elemento en la cima de la pila sin quitarlo\n    peek(): T | undefined {\n        if (this.isEmpty()) {\n            console.log(\"Error: Pila vacía\");\n            return undefined;\n        }\n        return this.items[this.items.length - 1];\n    }\n}\n\n// Implementación de la Cola (Queue - FIFO)\nclass Queue<T> {\n    private items: T[] = [];\n\n    // Método para añadir un elemento a la cola\n    enqueue(element: T): void {\n        this.items.push(element);\n    }\n\n    // Método para quitar un elemento de la cola\n    dequeue(): T | undefined {\n        if (this.isEmpty()) {\n            console.log(\"Error: Cola vacía\");\n            return undefined;\n        }\n        return this.items.shift();\n    }\n\n    // Método para verificar si la cola está vacía\n    isEmpty(): boolean {\n        return this.items.length === 0;\n    }\n\n    // Método para obtener el primer elemento de la cola sin quitarlo\n    peek(): T | undefined {\n        if (this.isEmpty()) {\n            console.log(\"Error: Cola vacía\");\n            return undefined;\n        }\n        return this.items[0];\n    }\n}\n\n// Función para el simulador de navegador web\nfunction webBrowserSimulator(): Promise<void> {\n    const backStack = new Stack<string>();\n    const forwardStack = new Stack<string>();\n    let currentPage = \"\";\n\n    const rl = readline.createInterface({\n        input: process.stdin,\n        output: process.stdout\n    });\n\n    console.log(\"Simulador de navegador web (escribe 'salir' para terminar):\");\n\n    function askForAction(): Promise<void> {\n        return new Promise((resolve) => {\n            rl.question(\"Ingresa una acción o nombre de página web: \", (input: string) => {\n                input = input.trim().toLowerCase();\n\n                if (input === 'salir') {\n                    rl.close();\n                    resolve();\n                } else if (input === 'atrás') {\n                    if (!backStack.isEmpty()) {\n                        forwardStack.push(currentPage);\n                        currentPage = backStack.pop() || \"\";\n                        console.log(\"Página actual:\", currentPage);\n                    } else {\n                        console.log(\"No hay páginas anteriores\");\n                    }\n                } else if (input === 'adelante') {\n                    if (!forwardStack.isEmpty()) {\n                        backStack.push(currentPage);\n                        currentPage = forwardStack.pop() || \"\";\n                        console.log(\"Página actual:\", currentPage);\n                    } else {\n                        console.log(\"No hay páginas siguientes\");\n                    }\n                } else {\n                    if (currentPage) {\n                        backStack.push(currentPage);\n                    }\n                    forwardStack = new Stack<string>();  // Limpia la pila de adelante\n                    currentPage = input;\n                    console.log(\"Página actual:\", currentPage);\n                }\n\n                askForAction().then(resolve);\n            });\n        });\n    }\n\n    return askForAction();\n}\n\n// Función para el simulador de impresora compartida\nfunction printerSimulator(): Promise<void> {\n    const printQueue = new Queue<string>();\n\n    const rl = readline.createInterface({\n        input: process.stdin,\n        output: process.stdout\n    });\n\n    console.log(\"\\nSimulador de impresora compartida (escribe 'salir' para terminar):\");\n\n    function askForDocument(): Promise<void> {\n        return new Promise((resolve) => {\n            rl.question(\"Ingresa un nombre de documento o 'imprimir': \", (input: string) => {\n                input = input.trim().toLowerCase();\n\n                if (input === 'salir') {\n                    rl.close();\n                    resolve();\n                } else if (input === 'imprimir') {\n                    const document = printQueue.dequeue();\n                    if (document) {\n                        console.log(\"Imprimiendo:\", document);\n                    }\n                } else {\n                    printQueue.enqueue(input);\n                    console.log(\"Documento añadido a la cola:\", input);\n                }\n\n                askForDocument().then(resolve);\n            });\n        });\n    }\n\n    return askForDocument();\n}\n\n// Función principal asíncrona para ejecutar los simuladores\nasync function main() {\n    await webBrowserSimulator();\n    await printerSimulator();\n}\n\n// Ejecutar la función principal\nmain();"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/typescript/giovanyosorio.ts",
    "content": "class Stack<T> {\n    private items: T[];\n\n    constructor() {\n        this.items = [];\n    }\n\n    push(element: T): void {\n        this.items.push(element);\n    }\n\n    pop(): T | undefined {\n        return this.items.pop();\n    }\n\n    peek(): T | undefined {\n        return this.items[this.items.length - 1];\n    }\n\n    isEmpty(): boolean {\n        return this.items.length === 0;\n    }\n\n    size(): number {\n        return this.items.length;\n    }\n}\n\nclass Queue<T> {\n    private items: T[];\n\n    constructor() {\n        this.items = [];\n    }\n\n    enqueue(element: T): void {\n        this.items.push(element);\n    }\n\n    dequeue(): T | undefined {\n        return this.items.shift();\n    }\n\n    peek(): T | undefined {\n        return this.items[0];\n    }\n\n    isEmpty(): boolean {\n        return this.items.length === 0;\n    }\n\n    size(): number {\n        return this.items.length;\n    }\n}\n\n// Ejemplo de uso\nconst stack = new Stack<number>();\nstack.push(1);\nstack.push(2);\nstack.push(3);\nconsole.log(stack.pop()); // 3\nconsole.log(stack.peek()); // 2\nconsole.log(stack.size()); // 2\n\nconst queue = new Queue<string>();\nqueue.enqueue(\"documento1\");\nqueue.enqueue(\"documento2\");\nqueue.enqueue(\"documento3\");\nconsole.log(queue.dequeue()); // documento1\nconsole.log(queue.peek()); // documento2\nconsole.log(queue.size()); // 2\n\n\n//\nconst browserStack = new Stack<string>();\nlet currentPage = \"\";\n\nfunction navigateTo(url: string): void {\n    browserStack.push(currentPage);\n    currentPage = url;\n    console.log(`Navegando a ${url}`);\n}\n\nfunction goBack(): void {\n    const previousPage = browserStack.pop();\n    if (previousPage) {\n        currentPage = previousPage;\n        console.log(`Volviendo a ${currentPage}`);\n    } else {\n        console.log(\"No hay páginas anteriores\");\n    }\n}\n\nfunction goForward(): void {\n    const nextPage = browserStack.pop();\n    if (nextPage) {\n        browserStack.push(currentPage);\n        currentPage = nextPage;\n        console.log(`Avanzando a ${currentPage}`);\n    } else {\n        console.log(\"No hay páginas siguientes\");\n    }\n}\n\n// Ejemplo de uso\nnavigateTo(\"google.com\");\nnavigateTo(\"facebook.com\");\ngoBack(); // Volviendo a google.com\ngoForward(); // Avanzando a facebook.com\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/typescript/hozlucas28.ts",
    "content": "/*\n    Stack methods for insert and recover items...\n*/\n\nconsole.log('Stack methods for insert and recover items...')\n\nconst stack: number[] = [6, 4, 2, 0, 5]\n\nconsole.log('\\nconst stack: number[] = [6, 4, 2, 0, 5]')\n\nconsole.log('\\nInsert an element at the end of the stack...')\n\nstack.push(3)\n\nconsole.log(`\\nstack.push(3) --> stack = [${stack}]`)\n\nconsole.log('\\nRecover an element of the stack...')\n\nconst stackElement = stack.pop()\n\nconsole.log(`\\nstack.pop() --> stackElement = ${stackElement}`)\n\nconsole.log('\\n# ---------------------------------------------------------------------------------- #\\n')\n\n/*\n    Queue methods for insert and recover items...\n*/\n\nconsole.log('Queue methods for insert and recover items...')\n\nconst queue: string[] = ['Hello', 'World']\n\nconsole.log(\"\\nconst queue: string[] = ['Hello', 'World']\")\n\nconsole.log('\\nInsert an element at the end of the queue...')\n\nqueue.push('TypeScript')\n\nconsole.log(`\\nqueue.push(\"TypeScript\") --> queue = [${queue}]`)\n\nconsole.log('\\nRecover an element of the queue...')\n\nconst queueElement = queue.shift()\n\nconsole.log(`\\nqueue.shift() --> queueElement = ${queueElement}`)\n\nconsole.log('\\n# ---------------------------------------------------------------------------------- #\\n')\n\n/*\n    Additional challenge...\n*/\n\n// Stack exercise...\nconsole.log('Stack exercise...')\n\ntype Operation = Uppercase<'forward' | 'back'>\n\nconst operationActions: Record<Operation, (stack: string[]) => string[]> = {\n\tBACK: (stack) => [...stack.slice(0, stack.length - 1)],\n\tFORWARD: (stack) => {\n\t\tconst lastPageNumber: number = parseInt(stack.at(-1)?.slice(-2) ?? '0')\n\t\treturn [...stack, `Page ${lastPageNumber + 1}`]\n\t},\n}\n\nlet browserHistory: string[] = []\n\nwhile (true) {\n\tconsole.table(browserHistory)\n\n\tconst operation = prompt('Select an operation (\"Back\", \"Forward\", or \"Exit\"):')\n\tif (!operation || operation.match(/exit/i)) break\n\n\tconst operationFormatted = operation.toUpperCase()\n\tconst operationAction = operationActions[operationFormatted]\n\tbrowserHistory = operationAction ? operationAction(browserHistory) : browserHistory\n}\n\n// Queue exercise...\nconsole.log('Queue exercise...')\n\nconst documents: string[] = []\n\nwhile (true) {\n\tconsole.table(documents)\n\n\tconst userInput = prompt('Add a document to print, or write \"print\" to print the document in the queue:')\n\tif (!userInput) break\n\n\tconst userInputFormatted = userInput.toUpperCase()\n\n\tif (userInputFormatted === 'PRINT') {\n\t\tconst printedDocument = documents.shift()\n\t\tconsole.log(`Printed document --> ${printedDocument}`)\n\t} else documents.push(userInput)\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/typescript/ialmontedr0.ts",
    "content": "/**\r\n * Introduccion y recuperacion de elementos de pilas y colas, con array \r\n */\r\n \r\n// Arreglo Global\r\nlet arreglo: number[] = [1, 2, 3, 4, 5];\r\n\r\n// PILAS (STACK)\r\nconsole.log(`Arreglo de numeros: ${arreglo}`);\r\n\r\n// Insercion de elemento a la lista\r\narreglo.push(6);\r\nconsole.log(`Arreglo de numeros con nuevo digito: ${arreglo}`);\r\n\r\n// Recuperar el ultimo elemento de la lista\r\nlet ultimoElemento = arreglo.push;\r\nconsole.log(`Ultimo elemento: ${ultimoElemento}`);\r\n\r\n// Ver el ultimo elemento de la lista sin eliminarlo\r\nlet lastItem = arreglo[arreglo.length - 1];\r\nconsole.log(`Ultimo elemento sin eliminarlo: ${lastItem}`);\r\n\r\n// Verificar si la pila esta vacia\r\nfunction isEmpty(): boolean {\r\n    return arreglo.length === 0;\r\n}\r\nconsole.log(`Verificando si la pila esta vacia: ${isEmpty()}`);\r\n\r\n// Obtener el tamano de la pila\r\nconst size = (): number => {\r\n    return arreglo.length;\r\n}\r\nconsole.log(`Obteniendo el tamano de la pila: ${size()}`);\r\n\r\n// Eliminacion de elemento de la pila\r\n// Eliminar el ultimo elemento de la pila\r\narreglo.pop();\r\nconsole.log(`Arreglo de numeros sin el ultimo elemento de la lista: ${arreglo}`);\r\n\r\n// Eliminar todosl os elementos de la pila\r\narreglo = [];\r\nconsole.log(`Arreglo vacio: ${arreglo}`)\r\n\r\n\r\n// COLAS (QUEUE)\r\n// Insertar un elemento en la Cola\r\narreglo.push(1);\r\nconsole.log(arreglo);\r\n\r\n// Recuperar el elemento en la Cola\r\nlet primerElemento = arreglo.shift();\r\nconsole.log(`Primer elemento: ${primerElemento}`);\r\n\r\n// Verificar si la cola esta vacia\r\nfunction isEmptyQueue(): boolean {\r\n    return arreglo.length === 0;\r\n}\r\nconsole.log(`Verificando si la cola esta vacia: ${isEmptyQueue()}`);\r\n\r\n// Obtener el tamano de la cola\r\nconst sizeQueue = (): number => {\r\n    return arreglo.length;\r\n}\r\nconsole.log(`Obteniendo el tamano de la cola: ${sizeQueue()}`);\r\n\r\n// Eliminar un elemento de la Cola\r\narreglo.shift();\r\nconsole.log(`Cola sin el primer elemento: ${arreglo}`);\r\n\r\n// Eliminar todos los elementos de la Cola\r\narreglo = [];\r\nconsole.log(`Cola vacia: ${arreglo}`);\r\n\r\n// Ejercicio Extra: Simulacion de navegador web\r\nlet webs: string[] = [\"Google\", \"Yahoo\", \"Facebook\", \"Twitter\", \"Instagram\"];\r\n\r\n// Simulacion de navegacion a una web\r\nfunction navegarA(web: string): void {\r\n    console.log(`Navegando a: ${web}`);\r\n    webs.push(web);\r\n    console.log(`Historial de navegacion: ${webs}`);\r\n    console.log();\r\n    imprimeHistorialWeb();\r\n    imprimeWebActual();\r\n    imprimeBotonesAdelanteAtras();\r\n    console.log();\r\n    imprimeDocumentoCola();\r\n    console.log();\r\n    imprimeCola();\r\n    console.log();\r\n    imprimeDocumentoActual();\r\n    imprimeBotonesImprimir();\r\n    console.log();\r\n}\r\n\r\nfunction imprimeHistorialWeb(): void {\r\n console.log(\"Historial de navegacion:\");\r\n webs.forEach((web, index) => {\r\n     console.log(`${index + 1}. ${web}`);\r\n });\r\n console.log();\r\n}\r\n\r\nfunction imprimeWebActual(): void {\r\n    const currentWebIndex = webs.length - 1;\r\n    console.log(`Pagina actual: ${webs[currentWebIndex]}`);\r\n    console.log();\r\n}\r\n\r\nfunction imprimeBotonesAdelanteAtras(): void {\r\n    const currentWebIndex = webs.length - 1;\r\n    const hasBackButton = currentWebIndex > 0;\r\n    const hasForwardButton = currentWebIndex < webs.length - 2;\r\n    console.log(`Botones de retroceso y avance: ${hasBackButton? \"Habilitado\" : \"Deshabilitado\"} - ${hasForwardButton? \"Habilitado\" : \"Deshabilitado\"}`);\r\n    console.log();\r\n}\r\n\r\nfunction imprimeDocumentoCola(): void {\r\n    console.log(\"Documentos en espera:\");\r\n    webs.forEach((web, index) => {\r\n        console.log(`${index + 1}. ${web}`);\r\n    });\r\n    console.log();\r\n}\r\n\r\nfunction imprimeCola(): void {\r\n    console.log(\"Impresiones en espera:\");\r\n    webs.forEach((web, index) => {\r\n        console.log(`${index + 1}. ${web}`);\r\n    });\r\n    console.log();\r\n}\r\n\r\nfunction imprimeDocumentoActual(): void {\r\n    const currentWebIndex = webs.length - 1;\r\n    console.log(`Documento actual: ${webs[currentWebIndex]}`);\r\n    console.log();\r\n}\r\n\r\nfunction imprimeBotonesImprimir(): void {\r\n    console.log(\"Botones de impresion:\");\r\n    webs.forEach((web, index) => {\r\n        console.log(`${index + 1}. Imprimir ${web}`);\r\n    });\r\n    console.log();\r\n}"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/typescript/juserdev.ts",
    "content": "/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web. Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n\n// Pila/Stacks )LIFO=\n\nlet stack: number[] = []\nstack.push(1)\nstack.push(2)\nstack.push(3)\nconsole.log(\"Este es el stack completo: \", stack)\n\nlet stackItem = stack.pop()\nconsole.log(\"El tulitmo elemento desapilado es: \", stackItem)\nconsole.log(\"Este es el stack actualizado: \", stack)\n\n// Cola/Queve (FIFO)\n\nlet  queve: number[] = []\n\nqueve.push(1)\nqueve.push(2)\nqueve.push(3)\n\nconsole.log(\"Esta es el queve: \", queve)\n\n let queveItem = queve.shift()\n\nconsole.log(\"Este es el primer elementro desapilado: \", queveItem)\nconsole.log(\"Este es el queve actualizado\", queve)\n\n\n// Extra\n\nlet paginaWeb: number[] = []\n\nlet accionMovimiento = (accion: string) =>{\n    if (accion === \"adelante\") {\n        let lastNumber = paginaWeb.length\n        let newNumber = lastNumber + 1\n        paginaWeb.push(newNumber)\n        return paginaWeb\n    } else if (accion === \"atras\"){\n        paginaWeb.pop()\n        return paginaWeb\n    }\n}\n\nconsole.log(accionMovimiento(\"adelante\"))\nconsole.log(accionMovimiento(\"adelante\"))\nconsole.log(accionMovimiento(\"adelante\"))\nconsole.log(accionMovimiento(\"atras\"))\nconsole.log(accionMovimiento(\"atras\"))\n\n//! EXTRA\n\n/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web. Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una impresora compartida que recibe documentos y los imprime cuando así se le indica. La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se interpretan como nombres de documentos.\n */\n\nimport * as readline from \"readline\";\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n})\n\nconst webNavigation = () =>{\n    let stack: string[] = []\n    let memoria: (string | undefined)[] = []\n\n    const preguntar = () =>{\n        rl.question(`Añade una url o navega con las pabaras \"adelante/atras/salir\": `, (action)=>{\n            console.log(\"\")\n            if (action === \"adelante\") {\n                if (memoria.length <= 0) {\n                    console.log(\"\")\n                    console.log(\"no tienes registro de memoria\")\n                    console.log(\"\")\n                    preguntar()\n                } else {\n                    console.log(\"\")\n                    console.log(\"esto es lo que tiene memoria ⬇️:\")\n                    console.log(memoria)\n                    console.log(\"esto es lo que tiene memoria en la ultima posicion ⬇️:\")\n                    console.log(memoria[memoria.length -1])\n                    stack.push(`${memoria[memoria.length -1]}`)\n                    console.log(\"\")\n                    console.log(\"Esta es la pagina en la que estas ahora: ⬇️\")\n                    console.log(stack[stack.length -1])\n                    console.log(\"\")\n                    memoria.pop()\n                    console.log(\"asi quedo memoria ⬇️:\")\n                    console.log(memoria)\n                    console.log(\"\")\n                    console.log(\"Asi quedo stack ⬇️:\")\n                    console.log(stack)\n                    console.log(\"\")\n                }\n            } else if (action === \"atras\"){\n\n                if (stack.length <= 0) {\n                    console.log(\"\")\n                    console.error(\"estas en la pagina de inicio, no puedes ir mas para atras\")\n                    console.log(\"\")\n                    preguntar()\n                }else{\n                    console.log(\"\")\n                    let lastPage = stack.pop()\n                    console.log(\"esta es la ultima pagina eliminada y guardada en la variable lastPage ⬇️:\")\n                    console.log(lastPage)\n                    console.log(\"\")\n                    console.log(\"lastPage ⬇️:\")\n                    console.log(lastPage)\n                    console.log(\"\")\n                    memoria.push(lastPage)\n                    console.log(\"Memoria ⬇️:\")\n                    console.log(memoria)\n                    console.log(\"\")\n                    console.log(\"Volviste a la pagina ⬇️:\")\n                    console.log(stack[stack.length -1])\n                    console.log(\"\")\n                    console.log(\"Asi esta el stack ⬇️:\")\n                    console.log(stack)\n                    console.log(\"\")\n                }\n            } else if (action === \"salir\"){\n                console.log(\"Saliendo del navegador web\")\n                console.log()\n                rl.close()\n            } else{\n                stack.push(action)\n                console.log(\"Has navegado a la web ⬇️:\")\n                console.log(stack[stack.length -1])\n                console.log(stack)\n                console.log(\"\")\n            }\n            preguntar()\n        })\n    }\n    preguntar()\n}\n\n// webNavigation()\n\nconst sharedPrinter = () =>{\n    let quece: string[] = [] \n\n    const preguntar = () =>{\n        rl.question(\"Añade un documento o selecciona imprimir/salir: \", (action)=>{\n            if (action === \"salir\") {\n                console.log(\"\")\n                console.log(\"Saliste del programa\")\n                console.log(\"\")\n                rl.close()\n            } else if (action === \"imprimir\") {\n                console.log(\"\")\n                console.log(`Hay ${quece.length} elemento imprimiendose`)\n                console.log(\"\")\n                while (quece.length > 0) { //ejecuta un bucle siempre que la condicion sea verdadera y se vuelve a evaluar la condicion hasta que esta sea falsa\n                    const documento = quece.shift(); // Elimina el primer elemento\n                    console.log(\"Imprimiendo: \", documento); // en cada bucle imprime el valor de document\n                }\n                console.log(\"\\nLa cola está vacía.\\n\");\n                preguntar()\n            } else {\n                console.log(\"\")\n                quece.push(action)\n                console.log(\"Esto es loque tiene la variable quece ⬇️\")\n                console.log(quece)\n                console.log(\"\")\n                preguntar()\n            }\n        })\n    }\n    preguntar()\n}\n\n// sharedPrinter()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/typescript/kodenook.ts",
    "content": "\n/*\n    Stack\n*/\n\nlet letters: string[] = ['a', 'b', 'c', 'd']\n\n/*\n    Insert\n*/\n\nletters.unshift('e')\nletters.unshift('f')\n\nconsole.log(letters)\n\n/*\n    Delete\n*/\n\nletters.shift()\n\nconsole.log(letters)\n\n/*\n    Queue\n*/\n\nletters = ['a', 'b', 'c', 'd']\n\n/*\n    Insert\n*/\n\nletters.push('e')\nletters.push('f')\n\nconsole.log(letters)\n\n/*\n    Delete\n*/\n\nletters.shift()\n\nconsole.log(letters)"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/typescript/marcode24.ts",
    "content": "/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n\nclass Stack<T> {\n  private items: T[];\n\n  constructor() {\n    this.items = [];\n  }\n\n  push(element: T): void {\n    this.items.push(element);\n  }\n\n  pop(): T | string {\n    if (this.isEmpty()) {\n      return 'La pila está vacía';\n    }\n    return this.items.pop() as T;\n  }\n\n  isEmpty(): boolean {\n    return this.items.length === 0;\n  }\n\n  peek(): T | undefined {\n    return this.items[this.items.length - 1];\n  }\n\n  clear(): void {\n    this.items = [];\n  }\n\n  size(): number {\n    return this.items.length;\n  }\n}\n\nclass Queue<T> {\n  private items: T[];\n\n  constructor() {\n    this.items = [];\n  }\n\n  enqueue(element: T): void {\n    this.items.push(element);\n  }\n\n  dequeue(): T | string {\n    if (this.isEmpty()) {\n      return 'La cola está vacía';\n    }\n    return this.items.shift() as T;\n  }\n\n  isEmpty(): boolean {\n    return this.items.length === 0;\n  }\n\n  size(): number {\n    return this.items.length;\n  }\n}\n\nconst pila = new Stack<number>();\npila.push(1);\npila.push(2);\npila.push(3);\nconsole.log(pila.pop()); // 3\nconsole.log(pila.pop()); // 2\n\nconst cola = new Queue<string>();\ncola.enqueue('a');\ncola.enqueue('b');\ncola.enqueue('c');\nconsole.log(cola.dequeue()); // a\nconsole.log(cola.dequeue()); // b\n\nclass Navegador {\n  private history: Stack<string>;\n  private future: Stack<string>;\n  private currentPage: string | null;\n\n  constructor() {\n    this.history = new Stack<string>();\n    this.future = new Stack<string>();\n    this.currentPage = null;\n  }\n\n  // navegar a una nueva página\n  goToPage(page: string): void {\n    if (this.currentPage !== null) {\n      this.history.push(this.currentPage);\n    }\n    this.currentPage = page;\n    this.future.clear();\n    console.log('Página actual: ', this.currentPage);\n  }\n\n  // retroceder a la página anterior\n  goBack(): void {\n    if (this.history.isEmpty()) {\n      console.log('No hay páginas anteriores');\n      return;\n    }\n    this.future.push(this.currentPage as string);\n    this.currentPage = this.history.pop() as string;\n    console.log('Página actual: ', this.currentPage);\n  }\n\n  // avanzar a la página siguiente\n  goForward(): void {\n    if (this.future.isEmpty()) {\n      console.log('No hay páginas siguientes');\n      return;\n    }\n    this.history.push(this.currentPage as string);\n    this.currentPage = this.future.pop() as string;\n    console.log('Página actual: ', this.currentPage);\n  }\n}\n\nconst navegador = new Navegador();\nnavegador.goToPage('google.com');\nnavegador.goToPage('facebook.com');\nnavegador.goToPage('twitter.com');\nnavegador.goBack(); // regresa a facebook.com\nnavegador.goBack(); // regresa a google.com\nnavegador.goForward(); // avanza a facebook.com\nnavegador.goToPage('instagram.com'); // instagram.com\nnavegador.goBack(); // regresa a facebook.com\nnavegador.goForward(); // avanza a instagram.com\n\n// Visita mi repo en GitHub para ver y correr los tests de este código --> https://github.com/marcode24/weekly-challenges\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/typescript/miguelex.ts",
    "content": "class Cola {\n    private cola: any[];\n    private inicio: number;\n    private fin: number;\n    private max: number;\n\n    constructor() {\n        this.cola = [];\n        this.inicio = 0;\n        this.fin = 0;\n        this.max = 10; // Opcional para limitar el tamaño de la cola\n    }\n\n    encolar(elemento: any): void {\n        if (this.fin < this.max) {\n            this.cola[this.fin] = elemento;\n            this.fin++;\n        } else {\n            console.log(\"La cola está llena\");\n        }\n    }\n\n    desencolar(): any {\n        if (this.inicio < this.fin) {\n            const elemento = this.cola[this.inicio];\n            delete this.cola[this.inicio];\n            this.inicio++;\n            return elemento;\n        } else {\n            console.log(\"La cola está vacía\");\n        }\n    }\n\n    mostrar(): void {\n        if (this.inicio === this.fin) {\n            console.log(\"La cola está vacía\");\n        } else {\n            for (let i = this.inicio; i < this.fin; i++) {\n                console.log(this.cola[i] + \" \");\n            }\n        }\n    }\n}\n\nclass Pila {\n    private pila: any[];\n    private tope: number;\n    private max: number;\n\n    constructor() {\n        this.pila = [];\n        this.tope = 0;\n        this.max = 7; // Opcional para limitar el tamaño de la pila\n    }\n\n    apilar(elemento: any): void {\n        if (this.tope < this.max) {\n            this.pila[this.tope] = elemento;\n            this.tope++;\n        } else {\n            console.log(\"La pila está llena\");\n        }\n    }\n\n    desapilar(): any {\n        if (this.tope > 0) {\n            this.tope--;\n            const elemento = this.pila[this.tope];\n            delete this.pila[this.tope];\n            return elemento;\n        } else {\n            console.log(\"La pila está vacía\");\n        }\n    }\n\n    mostrar(): void {\n        if (this.tope === 0) {\n            console.log(\"La pila está vacía\");\n        } else {\n            for (let i = this.tope - 1; i >= 0; i--) {\n                console.log(this.pila[i] + \" \");\n            }\n        }\n    }\n}\n\nconst cola = new Cola();\nconst pila = new Pila();\n\nconsole.log(\"Vamos a trabajar con la cola\");\nconsole.log(\"Vamos a mostrar el contenido de la cola al inicio de la misma: \");\ncola.mostrar();\n\nconsole.log(\"\\nVamos a encolar 3 elementos: 1, 2 y 3\");\ncola.encolar(1);\ncola.encolar(2);\ncola.encolar(3);\n\nconsole.log(\"Vamos a mostrar el contenido de la cola después de encolar 3 elementos: \");\ncola.mostrar();\n\nconsole.log(\"\\nVamos a desencolar un elemento\");\ncola.desencolar();\n\nconsole.log(\"Vamos a mostrar el contenido de la cola después de desencolar un elemento: \");\ncola.mostrar();\n\nconsole.log(\"\\nVamos a encolar 2 elementos: 4 y 5 y vamos a desencolar dos\");\ncola.encolar(4);\ncola.encolar(5);\ncola.desencolar();\ncola.desencolar();\n\nconsole.log(\"Vamos a mostrar el contenido de la cola después de encolar 2 elementos y desencolar dos: \");\ncola.mostrar();\n\nconsole.log(\"\\nPor último, vamos a desencolar tres elementos (recuerda que realmente solo nos quedan 2 dentro de la cola)\");\ncola.desencolar();\ncola.desencolar();\ncola.desencolar();\n\nconsole.log(\"Vamos a mostrar el contenido de la cola después de desencolar tres elementos: \");\ncola.mostrar();\n\nconsole.log(\"\\nAhora, vamos a trabajar con la pila\");\n\nconsole.log(\"Vamos a mostrar el contenido de la pila al inicio de la misma: \");\npila.mostrar();\n\nconsole.log(\"\\nVamos a apilar 3 elementos: 1, 2 y 3\");\n\npila.apilar(1);\npila.apilar(2);\npila.apilar(3);\n\nconsole.log(\"Vamos a mostrar el contenido de la pila después de apilar 3 elementos: \");\npila.mostrar();\n\nconsole.log(\"\\nVamos a desapilar un elemento\");\npila.desapilar();\n\nconsole.log(\"Vamos a mostrar el contenido de la pila después de desapilar un elemento: \");\npila.mostrar();\n\nconsole.log(\"\\nVamos a apilar 2 elementos: 4 y 5 y vamos a desapilar dos\");\n\npila.apilar(4);\npila.apilar(5);\n\npila.desapilar();\npila.desapilar();\n\nconsole.log(\"Vamos a mostrar el contenido de la pila después de apilar 2 elementos y desapilar dos: \");\npila.mostrar();\n\nconsole.log(\"\\nPor último, vamos a desapilar tres elementos (recuerda que realmente solo nos quedan 2 dentro de la pila)\");\npila.desapilar();\npila.desapilar();\npila.desapilar();\n\nconsole.log(\"Vamos a mostrar el contenido de la pila después de desapilar tres elementos: \");\npila.mostrar();\n\nconsole.log(\"\\nVamos a simular el mecanismo adelante/atrás de un navegador web\");\n\nconst pilaNavegador = new Pila();\nlet ultimoIndexVisitado = -1;\n\nimport * as readline from 'readline';\n\nfunction navegacion() {\n    const cabeza = pilaNavegador['tope'] - 1;\n\n    const rl = readline.createInterface({\n        input: process.stdin,\n        output: process.stdout\n    });\n\n    rl.question(\"Escribe el nombre de la web, adelante, atras o salir: \", (entrada: string) => {\n        if (entrada === \"adelante\") {\n            if (ultimoIndexVisitado < cabeza) {\n                ultimoIndexVisitado++;\n                console.log(\"Navegando adelante a la web: \" + pilaNavegador['pila'][ultimoIndexVisitado]);\n            } else {\n                console.log(\"No hay más webs para navegar adelante\");\n            }\n        } else if (entrada === \"atras\") {\n            if (ultimoIndexVisitado > 0) {\n                ultimoIndexVisitado--;\n                console.log(\"Navegando atrás a la web: \" + pilaNavegador['pila'][ultimoIndexVisitado]);\n            } else {\n                console.log(\"No hay más webs para navegar atrás\");\n            }\n        } else if (entrada !== \"salir\") {\n            pilaNavegador.apilar(entrada);\n            ultimoIndexVisitado = pilaNavegador['tope'] - 1;\n            console.log(\"Estás en la web: \" + entrada);\n        }\n\n        if (entrada !== \"salir\") {\n            navegacion();\n        } else {\n            rl.close();\n        }\n    });\n}\n\nnavegacion();\n\nconsole.log(\"\\nVamos a simular el mecanismo de una cola de impresión\");\n\nconst colaImpresion = new Cola();\n\nfunction impresion() {\n    const rl = readline.createInterface({\n        input: process.stdin,\n        output: process.stdout\n    });\n\n    rl.question(\"Escribe el nombre del documento, imprimir o exit: \", (entrada: string) => {\n        if (entrada === \"imprimir\") {\n            const documento = colaImpresion.desencolar();\n            if (documento !== undefined) {\n                console.log(\"Imprimiendo documento: \" + documento);\n            } else {\n                console.log(\"No hay documentos para imprimir\");\n            }\n        } else if (entrada !== \"exit\") {\n            colaImpresion.encolar(entrada);\n            console.log(\"Documento encolado: \" + entrada);\n        }\n\n        if (entrada !== \"exit\") {\n            impresion();\n        } else {\n            rl.close();\n        }\n    });\n}\n\nimpresion();\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/typescript/nlarrea.ts",
    "content": "/*\n * EJERCICIO:\n * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n * o lista (dependiendo de las posibilidades de tu lenguaje).\n *\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n\n\n// Stack - LIFO\n\nconst stack: number[] = []\n\n// Add item\nstack.push(1)\nstack.push(2)\nstack.push(3)\nstack.push(4)\nconsole.log(stack)  // [1, 2, 3, 4]\n\n// Remove item -> last item\nstack.pop()\nconsole.log(stack)  // [1, 2, 3]\nstack.pop()\nconsole.log(stack)  // [1, 2]\n\n\n// Queue - FIFO\n\nlet queue: number[] = []\n\n// Add item\nqueue.push(1)\nqueue.push(2)\nqueue.push(3)\nqueue.push(4)\nconsole.log(queue)  // [1, 2, 3, 4]\n\n// Remove item -> from the beginning\n// Using splice():\nqueue.splice(0, 1)\nconsole.log(queue)  // [2, 3, 4]\n// Using slice():\nqueue = queue.slice(1)\nconsole.log(queue)  // [3, 4]\n// Using shift()\nqueue.shift()\nconsole.log(queue)  // [4]\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n *   el nombre de una nueva web.\n */\n\n\nimport * as readline from 'readline'\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n})\n\n\nconst history: string[] = []\nlet pointer: number = -1\n\nfunction webNavigation(): void {\n    const showMenu = (): void => {\n        console.log('\\nType one of the following:');\n        console.log(' - The web page you want to visit');\n        console.log(' - Back (to go to the previous page)');\n        console.log(' - Next (to go to the next page)');\n        console.log(' - Exit');\n    }\n\n    showMenu()\n    \n    rl.question('Where do you want to go?\\n> ', (action: string) => {\n        if (action && action.trim().toLowerCase() === 'exit') {\n            rl.close()\n            return\n        } else if (action && action.trim().toLowerCase() === 'next') {\n            if (pointer !== history.length - 1) {\n                pointer++\n            }\n            console.log(`\\nYou are in: ${history[pointer]}`);\n        } else if (action && action.trim().toLowerCase() === 'back') {\n            pointer--\n            if (pointer < 0) {\n                pointer = -1\n                console.log('\\nYou are in home page')\n            } else {\n                console.log(`\\nYou are in: ${history[pointer]}`)\n            }\n        } else if (action) {\n            history.push(action)\n            pointer = history.length - 1\n            console.log(`\\nYou are in: ${history[pointer]}`)\n        }\n\n        webNavigation()\n    })\n}\n\nwebNavigation()\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n *   interpretan como nombres de documentos.\n */\n\n\nconst printerQueue: string[] = []\n\nfunction printer() {\n    const showMenu = () => {\n        console.log('\\nPrinter options:');\n        console.log(' - Type a document name to add it to the queue');\n        console.log(' - Type \"print\" to print the first item');\n        console.log(' - Exit');\n    }\n\n    const showQueue = () => {\n        console.log('\\nPrinter Queue:')\n\n        if (printerQueue.length > 0) {\n            for (let doc of printerQueue) {\n                console.log(` - ${doc}`)\n            }\n        } else {\n            console.log('The Queue is empty.')\n        }\n    }\n\n    showMenu();\n    rl.question('Type a document name or \"print\" to print the first item:\\n> ', (action: string) => {\n        if (action && action.trim().toLowerCase() === 'exit') {\n            rl.close()\n            return\n        } else if (action && action.trim().toLowerCase() === 'print') {\n            if (printerQueue.length > 0) {\n                let printingDoc = printerQueue.shift()\n                console.log(`Printing: ${printingDoc}`)\n            } else {\n                console.log('There are no documents to print.')\n            }\n        } else if (action) {\n            printerQueue.push(action)\n        }\n\n        showQueue()\n        printer()\n    })\n}\n\nprinter()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/typescript/qv1ko.ts",
    "content": "let stack: number[] = [];\n\nstack.push(1);\nstack.push(2);\nstack.push(3);\n\nif (stack.length !== 0) {\n    console.log(stack.pop());\n}\n\nlet queue: string[] = [];\n\nqueue.push('a');\nqueue.push('b');\nqueue.push('c');\n\nif (queue.length !== 0){\n    console.log(queue[0]);\n}\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/typescript/qwik-zgheib.ts",
    "content": "/* -- exercise */\n/* stack - LIFO */\nclass Stack<T> {\n  private items: T[];\n\n  constructor() {\n    this.items = [];\n  }\n\n  push(element: T): void {\n    this.items.push(element);\n  }\n\n  pop(): T | null {\n    if (this.isEmpty()) {\n      return null;\n    }\n    return this.items.pop() as T;\n  }\n\n  isEmpty(): boolean {\n    return this.items.length === 0;\n  }\n\n  peek(): T | null {\n    if (this.isEmpty()) {\n      return null;\n    }\n    return this.items[this.items.length - 1];\n  }\n\n  size(): number {\n    return this.items.length;\n  }\n\n  print(): void {\n    console.log(this.items.toString());\n  }\n}\n\nlet stack = new Stack<number>();\nstack.push(10);\nstack.push(20);\nstack.push(30);\nstack.print();\nconsole.log(stack.pop() !== null ? \"Popped\" : \"Stack is empty\");\nstack.print();\nconsole.log(stack.peek() !== null ? \"Peeked\" : \"Stack is empty\");\n\n/* queue - FIFO */\nclass Queue<T> {\n  private items: T[];\n\n  constructor() {\n    this.items = [];\n  }\n\n  enqueue(element: T): void {\n    this.items.push(element);\n  }\n\n  dequeue(): T | string {\n    if (this.isEmpty()) {\n      return \"Queue is empty\";\n    }\n    return this.items.shift() as T;\n  }\n\n  isEmpty(): boolean {\n    return this.items.length === 0;\n  }\n\n  front(): T | string {\n    if (this.isEmpty()) {\n      return \"Queue is empty\";\n    }\n    return this.items[0];\n  }\n\n  size(): number {\n    return this.items.length;\n  }\n\n  printQueue(): void {\n    console.log(\"Queue:\", this.items.toString());\n  }\n}\n\nlet queue = new Queue<number>();\nqueue.enqueue(10);\nqueue.enqueue(20);\nqueue.enqueue(30);\nqueue.printQueue();\nconsole.log(queue.dequeue());\nqueue.printQueue();\nconsole.log(queue.front());\n\n/* -- extra challenge */\nclass Browser {\n  private backStack: Stack<string>;\n  private forwardStack: Stack<string>;\n  private currentPage: string | null;\n\n  constructor() {\n    this.backStack = new Stack<string>();\n    this.forwardStack = new Stack<string>();\n    this.currentPage = null;\n  }\n\n  navigate(page: string): void {\n    if (this.currentPage !== null) this.backStack.push(this.currentPage);\n\n    this.currentPage = page;\n    this.forwardStack = new Stack<string>();\n    console.log(\"Navigated to:\", this.currentPage);\n  }\n\n  back(): void {\n    if (this.backStack.isEmpty()) {\n      console.log(\"No pages to go back to.\");\n      return;\n    }\n    this.forwardStack.push(this.currentPage as string);\n    this.currentPage = this.backStack.pop() as string;\n    console.log(\"Went back to:\", this.currentPage);\n  }\n\n  forward(): void {\n    if (this.forwardStack.isEmpty()) {\n      console.log(\"No pages to go forward to.\");\n      return;\n    }\n    this.backStack.push(this.currentPage as string);\n    this.currentPage = this.forwardStack.pop() as string;\n    console.log(\"Went forward to:\", this.currentPage);\n  }\n}\n\nlet browser = new Browser();\nbrowser.navigate(\"page1.com\");\nbrowser.navigate(\"page2.com\");\nbrowser.navigate(\"page3.com\");\nbrowser.back();\nbrowser.back();\nbrowser.forward();\nbrowser.navigate(\"page4.com\");\nbrowser.forward();\n\nclass Printer {\n  private queue: Queue<string>;\n\n  constructor() {\n    this.queue = new Queue<string>();\n  }\n\n  addDocument(document: string): void {\n    this.queue.enqueue(document);\n    console.log(\"Added document:\", document);\n  }\n\n  printDocument(): void {\n    const document = this.queue.dequeue();\n    if (document !== \"Queue is empty\") console.log(\"Printing document:\", document);\n    else console.log(document);\n  }\n}\n\nlet printer = new Printer();\nprinter.addDocument(\"doc1.pdf\");\nprinter.addDocument(\"doc2.pdf\");\nprinter.addDocument(\"doc3.pdf\");\nprinter.printDocument();\nprinter.printDocument();\nprinter.printDocument();\nprinter.printDocument();\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/typescript/victor-Casta.ts",
    "content": "var readline = require('readline')\n\nvar rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout\n})\n/*\n  * EJERCICIO:\n  * Implementa los mecanismos de introducción y recuperación de elementos propios de las\n  * pilas (stacks - LIFO) y las colas (queue - FIFO) utilizando una estructura de array\n  * o lista (dependiendo de las posibilidades de tu lenguaje).\n*/\n\n//Pilas LIFO\nclass Lifo {\n  list: (number | string)[] = []\n  adding(data: number | string): void {\n    this.list.push(data)\n  }\n  removing(): void {\n    this.list.pop()\n  }\n}\n\nconst myLifo: Lifo = new Lifo\nmyLifo.adding(1)\nmyLifo.adding(2)\nmyLifo.adding(3)\nmyLifo.removing()\nconsole.log(myLifo)\n\n// Colas FIFO\n\nclass Fifo {\n  list: (number | string)[] = []\n  adding(data: number | string): void {\n    this.list.push(data)\n  }\n  removing(): void {\n    this.list.shift()\n  }\n}\n\nconst myFifo: Fifo = new Fifo\nmyFifo.adding(1)\nmyFifo.adding(2)\nmyFifo.adding(3)\nmyFifo.removing()\nconsole.log(myFifo)\n\n/*\n  * DIFICULTAD EXTRA (opcional):\n  * - Utilizando la implementación de pila y cadenas de texto, simula el mecanismo adelante/atrás\n  *   de un navegador web. Crea un programa en el que puedas navegar a una página o indicarle\n  *   que te quieres desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n  *   Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto se interpreta como\n  *   el nombre de una nueva web.\n  * - Utilizando la implementación de cola y cadenas de texto, simula el mecanismo de una\n  *   impresora compartida que recibe documentos y los imprime cuando así se le indica.\n  *   La palabra \"imprimir\" imprime un elemento de la cola, el resto de palabras se\n  *   interpretan como nombres de documentos.\n*/\n\nfunction webNavigator(): void {\n  const list: Array<string> = []\n  rl.question('Ingresa el nombre de una web, \"adelante\", \"atrás\" o \"salir\": ', (response: string) => {\n    if (response === 'atrás' && list.length > 0) {\n      list.pop()\n    } else if (response !== 'adelante' && response !== 'salir' && response !== 'atrás') {\n      list.push(response)\n    }\n    if (response === 'salir') {\n      rl.close()\n    } else {\n      console.log(`Página actual: ${list[list.length - 1] || \"Inicio\"}`)\n      webNavigator()\n    }\n  })\n}\nwebNavigator()\n\nconst printerList: Array<string> = []\nfunction printer(): void {\n  console.log('list', printerList)\n  rl.question('Ingresa imprimir o un nombre de documento: ', (response: string) => {\n    if (response === 'imprimir') {\n      console.log(printerList[0])\n      printerList.shift()\n      printer()\n    } else if (response !== 'imprimir') {\n      printerList.push(response)\n      printer()\n    } else {\n      console.log('opcion incorrecta')\n      rl.close()\n    }\n  })\n}\n\nprinter()"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/typescript/victoriaparraf.ts",
    "content": "//Implementacionde una pila\n\nclass Stack<T> {\n    private items: T[] = [];\n\n    // Añade un elemento al final de la pila\n    push(element: T): void {\n        this.items.push(element);\n    }\n\n    // Retira el último elemento de la pila y lo devuelve\n    pop(): T | undefined {\n        return this.items.pop();\n    }\n\n    // Mira el último elemento de la pila sin retirarlo\n    peek(): T | undefined {\n        return this.items[this.items.length - 1];\n    }\n\n    // Verifica si la pila está vacía\n    isEmpty(): boolean {\n        return this.items.length === 0;\n    }\n\n    // Devuelve el tamaño de la pila\n    size(): number {\n        return this.items.length;\n    }\n\n    // Imprime todos los elementos de la pila\n    print(): void {\n        console.log(this.items);\n    }\n}\n\n// Ejemplo de uso\nlet stack = new Stack<number>();\nstack.push(1);\nstack.push(2);\nstack.push(3);\nconsole.log(stack.pop()); // 3\nconsole.log(stack.peek()); // 2\nstack.print(); // [1, 2]\n\n//Implementacion de una cola\nclass Queue<T> {\n    private items: T[] = [];\n\n    // Añade un elemento al final de la cola\n    enqueue(element: T): void {\n        this.items.push(element);\n    }\n\n    // Retira el primer elemento de la cola y lo devuelve\n    dequeue(): T | undefined {\n        return this.items.shift();\n    }\n\n    // Mira el primer elemento de la cola sin retirarlo\n    peek(): T | undefined {\n        return this.items[0];\n    }\n\n    // Verifica si la cola está vacía\n    isEmpty(): boolean {\n        return this.items.length === 0;\n    }\n\n    // Devuelve el tamaño de la cola\n    size(): number {\n        return this.items.length;\n    }\n\n    // Imprime todos los elementos de la cola\n    print(): void {\n        console.log(this.items);\n    }\n}\n\n// Ejemplo de uso\nlet queue = new Queue<number>();\nqueue.enqueue(1);\nqueue.enqueue(2);\nqueue.enqueue(3);\nconsole.log(queue.dequeue()); // 1\nconsole.log(queue.peek()); // 2\nqueue.print(); // [2, 3]\n"
  },
  {
    "path": "Roadmap/07 - PILAS Y COLAS/vb.net/kenysdev.vb",
    "content": "' ╔══════════════════════════════════════╗\n' ║ Autor:  Kenys Alvarado               ║\n' ║ GitHub: https://github.com/Kenysdev  ║\n' ║ 2024 -  VB.NET                       ║\n' ╚══════════════════════════════════════╝\n\n' # PILAS Y COLAS\n' ---------------\nModule Program\n    Sub Main(args As String())\n        '' Pilas(stack - LIFO):\n        '- Sigue el principio LIFO (last in, first out), significa que\n        '  el último elemento añadido, es el primero en ser retirado. */\n\n        'Dim myStack As New Stack(Of Integer)()\n        Dim myStack As New Stack()\n        myStack.Push(111) ' Agregar elemento.\n        myStack.Push(\"Hola\")\n        myStack.Push(3.14)\n\n        Console.WriteLine($\"\n        Eliminar y obtener:   {myStack.Pop()}\n        Obtener sin eliminar: {myStack.Peek()}\n        Total de elementos:   {myStack.Count}\n        Verificar si existe:  {myStack.Contains(5)}\n        Obtener elementos:    {String.Join(\", \", myStack.ToArray())}\")\n\n        ' ___________________________________________\n        '' Colas (Queue - FIFO):\n        '- Estructura de datos que sigue el principio FIFO(First In, First Out)\n        '- El primer elemento que se inserta es el primero en ser retirado. */\n\n        'Dim myQueue As New Queue()\n        Dim myQueue As New Queue(Of Integer)\n        myQueue.Enqueue(1) ' Agregar elemento.\n        myQueue.Enqueue(2)\n        myQueue.Enqueue(3)\n\n        Console.WriteLine($\"\n        Eliminar y obtener:   {myQueue.Dequeue()}\n        Obtener sin eliminar: {myQueue.Peek()}\n        Total de elementos:   {myQueue.Count}\n        Verificar si existe:  {myQueue.Contains(5)}\n        Obtener elementos:    {String.Join(\", \", myQueue.ToArray())}\")\n\n        ' Ejercicios:\n        ' ____________________________________________\n        '1 Ejercicio usando la implementación de pilas:\n        'Simula el mecanismo adelante/atrás de un navegador web.\n        '- Crea un programa en el que puedas navegar a una página o indicarle que te quieres \n        '  desplazar adelante o atrás, mostrando en cada caso el nombre de la web.\n        '- Las palabras \"adelante\", \"atrás\" desencadenan esta acción, el resto \n        '  se interpreta como el nombre de una nueva web. */\n\n        ' ____________________________________________\n        '2 Ejercicio usando la implementación de Colas:\n        'Simula el mecanismo de una impresora compartida.\n        '- recibe documentos y los imprime cuando así se le indica.\n        '- La palabra \"imprimir\" imprime un elemento de la cola.\n        '- El resto de palabras se interpretan como nombres de documentos.\n\n        Home()\n\n    End Sub\n\n    ReadOnly msgHome As String = \"\n    ----------------------------------\n    Usar: '1' para simulador_navegador.\n          '2' para simulador_impresora.\n          'Otra tecla' para salir.\n    ----------------------------------\"\n    ReadOnly msgNav As String = \"\n    ------------------------------------------------\n    Usar: '<' para página anterior.\n          '>' para página adelante.\n          'h' Ver historial completo.\n          'x' para salir. \n    Escribir web para agregar:\n    ------------------------------------------------\"\n    ReadOnly msgPrinter As String = \"\n    ------------------------------------------------\n    Usar: 'p' Imprimir.\n          'l' Ver documentos pendientes.\n          'x' para salir.\n    Escribir nombre de documento para enviar a cola: \n    ------------------------------------------------\"\n    Sub Home()\n        Console.WriteLine(msgHome)\n        Console.Write(\"____________\" & vbCrLf & \"Acción: \")\n        Dim action As String = Console.ReadLine()\n        Select Case action\n            Case \"1\"\n                Dim navManager As New NavigationManager()\n                Console.WriteLine(msgNav)\n                navManager.SelectAction()\n            Case \"2\"\n                Dim queueManager As New PrinterQueueManager()\n                Console.WriteLine(msgPrinter)\n                queueManager.SelectAction()\n            Case Else\n                Console.WriteLine(\"Bye\")\n        End Select\n    End Sub\n\n    Public Class NavigationManager\n        Private history As New Stack(Of String)(New String() {\"Inicio\"})\n        Private backHistory As New Stack(Of String)()\n        Private forwardHistory As New Stack(Of String)()\n\n        Public Sub SelectAction()\n            Console.Write(\"____________\" & vbCrLf & \" Acción: \")\n            Dim action As String = Console.ReadLine()\n\n            If action.Length > 0 Then\n                Select Case action\n                    Case \"<\"\n                        Back()\n                    Case \">\"\n                        Forward()\n                    Case \"x\"\n                        Home()\n                    Case \"h\"\n                        TheHistory()\n                    Case Else\n                        NewWeb(action)\n                End Select\n            Else\n                Console.WriteLine(\"Eres muy gracioso xD.\")\n                SelectAction()\n            End If\n        End Sub\n\n        Private Sub NewWeb(url As String)\n            backHistory.Push(history.Peek())\n            forwardHistory.Clear()\n            history.Push(url)\n            Web(url)\n            SelectAction()\n        End Sub\n\n        Private Sub Back()\n            If backHistory.Count > 0 Then\n                forwardHistory.Push(history.Peek())\n                history.Push(backHistory.Pop())\n                Web(history.Peek())\n            Else\n                Console.WriteLine(\"No hay página previa.\")\n            End If\n            SelectAction()\n        End Sub\n\n        Private Sub Forward()\n            If forwardHistory.Count > 0 Then\n                backHistory.Push(history.Peek())\n                history.Push(forwardHistory.Pop())\n                Web(history.Peek())\n            Else\n                Console.WriteLine(\"No hay página siguiente.\")\n            End If\n            SelectAction()\n        End Sub\n\n        Private Sub Web(url As String)\n            Console.WriteLine($\"{backHistory.Count} <-[Actual:{url}]-> {forwardHistory.Count}\")\n        End Sub\n\n        Private Sub TheHistory()\n            If history.Count > 0 Then\n                For Each item As String In history\n                    Console.WriteLine(item)\n                Next\n            Else\n                Console.WriteLine(\"Historial vacío.\")\n            End If\n            SelectAction()\n        End Sub\n    End Class\n\n    '--------------------------------------------------------------------\n    Public Class PrinterQueueManager\n        Private docQueue As New Queue(Of String)()\n\n        Public Sub SelectAction()\n            Console.Write(\"____________\" & vbCrLf & \" Acción: \")\n            Dim action As String = Console.ReadLine()\n\n            If action.Length > 0 Then\n                Select Case action\n                    Case \"p\"\n                        PrintDoc()\n                    Case \"l\"\n                        QueuePending()\n                    Case \"x\"\n                        Home()\n                    Case Else\n                        SendDoc(action)\n                End Select\n            Else\n                Console.WriteLine(\"Eres muy gracioso xD.\")\n                SelectAction()\n            End If\n        End Sub\n\n        Private Sub PrintDoc()\n            If docQueue.Count > 0 Then\n                Console.WriteLine($\"\n            {docQueue.Dequeue()} -> ha sido impreso.\n            {docQueue.Count} -> archivos faltantes.\")\n            Else\n                Console.WriteLine(\"No hay archivos.\")\n            End If\n            SelectAction()\n        End Sub\n\n        Private Sub QueuePending()\n            If docQueue.Count > 0 Then\n                For Each doc As String In docQueue\n                    Console.WriteLine(doc)\n                Next\n            Else\n                Console.WriteLine(\"No hay archivos.\")\n            End If\n            SelectAction()\n        End Sub\n\n        Private Sub SendDoc(doc As String)\n            docQueue.Enqueue(doc)\n            Console.WriteLine(\"Archivo agregado a cola de impresión.\")\n            SelectAction()\n        End Sub\n    End Class\nEnd Module\n"
  },
  {
    "path": "Roadmap/08 - CLASES/arduino/santyjL.ino",
    "content": "// Definición de la clase Telefono\nclass Telefono {\nprivate:\n  String nombre;\n  String camara;\n  String almacenamiento;\n  String ram;\n\npublic:\n  // Constructor para la clase Iphone\n  Telefono(String nombre, String camara, String almacenamiento, String ram) {\n    this->nombre = nombre;\n    this->camara = camara;\n    this->almacenamiento = almacenamiento;\n    this->ram = ram;\n  }\n\n  // Método de presentación\n  String presentacion() {\n    return String(\"\\nNombre: \") + nombre +\n           String(\"\\nCamara: \") + camara +\n           String(\"\\nAlmacenamiento: \") + almacenamiento +\n           String(\"\\nRam: \") + ram + \"\\n\";\n  }\n};\n\n// Instanciar un objeto de la clase Iphone\nTelefono iphone15(\"iPhone15\", \"12MP\", \"256GB\", \"8GB\");\nTelefono sansungS23(\"Sansung S23\", \"200MP\", \"256GB\", \"8GB\");\nTelefono sansungS21(\"Sansung S21\", \"40MP\", \"256GB\", \"12GB\");\n\nvoid setup() {\n  Serial.begin(9600);\n}\n\nvoid loop() {\n  // Presentar la información del iPhone15\n  Serial.println(iphone15.presentacion());\n  delay(2000);\n\n  // Presentar la información del Sansung_S23\n  Serial.println(sansungS21.presentacion());\n  delay(2000);\n\n  // Presentar la información del Sansung_S23\n  Serial.println(sansungS23.presentacion());\n  delay(2000);\n\n  // Terminar el loop para evitar la repetición continua\n  while (true) {}\n}\n"
  },
  {
    "path": "Roadmap/08 - CLASES/c#/Andreavzqz.cs",
    "content": "using System;\nusing System.Collection.Generic;\nusing EjemploClaseYestructuras;\n\nnamespace EjemploClaseYestructuras\n{\n    // Clase Persona\n    class Persona\n    {\n        \n        // Atributos\n        public string Nombre { get; set; }\n        public int Edad { get; set; }\n\n        / Consultor (inicializador)\n        public Persona(string nombre, int edad)\n            {\n                Nombre = nombre;\n                Edad = edad;\n            }\n    \n\n       // Funcion para imprimir los atributos\n       public void Imprimir()\n          {\n              Console.WriteLine($\"Nombre: {Nombre}, Edad: {Edad}\");\n          }\n    }\n   // Clase Pila\n    class Pila<T>\n    {\n        private List<T> elementos = new List<T>\n\n        // Añadir un elemento a la pila\n        public void Push(T elemento)\n        {\n            elementos.Add(elementos);\n        }\n\n        // Eliminar y retornar el elemento en la cima de la pila\n        public T Pop()\n        {\n            if (elementos.Count == 0)\n                throw new InvalidOperationExveption(\"La pila está vacía\");\n            T elemento = elementos[elementos.Count - 1];\n            elementos.RemoveAt(elementos.Count - 1);\n            return elemento;\n        }\n\n        // Retornar el número de elemento en la pila\n        public int Count ()\n        {\n            return elementos.Count;\n        }\n\n        // Imprimir todos los elementos de la pila\n        public void Imprimir()\n        {\n            foreach (var elemento in elementos)\n            {\n                Console.WriteLine(elemento);\n            }\n        }\n    }\n\n    // Clase cola\n    class Cola<T>\n    {\n        private Queue<T> elementos = new Queue<T>();\n\n        // Añadir un elemento a la cola\n        public void Enqueue (T elemento);\n        {\n            elementos.Enqueue(elemento);\n        }\n\n        // Eliminar y retornar el primer elemento de la cola\n        public T Dequeue()\n        {\n            if (elemntos.Count == 0)\n                throw new InvalidOperationException(\"La cola está vacía.\");\n            return elementos.Dequeue();\n        }\n\n        // Retornar el número de elementos en la cola\n        public int Count()\n        {\n            return elementos.Count;\n        }\n\n        // Imprimir todos los elemnentos de la cola\n        public void Imprimir()\n        {\n            foreach (var elemto in elementos)\n            {\n                Console.WriteLine(elemento);\n            }\n        }\n    }\n\n    class Program\n    {\n        static void Main(string[] args)\n        {\n        \n        // Parte 1: Clase persona\n        Persona persona = new Persona(\"Juan\", 25);\n\n        // Imprimir los atributos iniciales\n        persona.Imprimir();\n\n        // Modificar los atributos\n        persona.Nombre = \"Pedro\";\n        persona.Edad = 30;\n\n        // Imprimir los atributos modificados\n        persona.Imprimir();\n\n\n        // Parte 2: Uso de la pila\n        Pila<int> pila = new Pila<int>();\n        Pila.Push(1);\n        Pila.Push(2);\n        Pila.Push(3);\n        Console.WriteLine(\"Elemento de la pila:\");\n        pila.Imprimir();\n        Console.WriteLine($\"Elemento eliminado de la pila: {pila.Pop()}\");\n        Console.WriteLine($\"Número de ekemento en la pila: {pila.Count()}\");\n\n\n        // Parte 3: Uso de la cola\n        Cola<int> cola = new Cola<int>();\n        cola.Enqueue(1);\n        cola.Enqueue(2);\n        cola.Enqueue(3);\n        Console.WriteLine(\"Elementos de la cola:\");\n        cola.Imprimir();\n        Console.WriteLine($\"Elemento eliminado de la cola: {cola.Dequeue()}\");\n        Console.WriteLine($\"Nuúmero de elementos en la cola: {cola.Count()}\");\n\n        }\n    }\n/*\n\nExplicación\n\nClase Persona:\nDefine los atributos Nombre y Edad.\nTiene un constructor para inicializar estos atributos.\nLa función Imprimir muestra los valores de los atributos.\n\nClase Pila<T>:\nImplementa una pila genérica usando una lista interna.\nMétodos Push, Pop, Count e Imprimir para añadir, eliminar, contar e imprimir elementos, respectivamente.\n\nClase Cola<T>:\nImplementa una cola genérica usando una cola interna (Queue).\nMétodos Enqueue, Dequeue, Count e Imprimir para añadir, eliminar, contar e imprimir elementos, respectivamente.\n\nPrograma Principal:\nDemuestra cómo crear y utilizar instancias de Persona, Pila y Cola, realizando varias operaciones y mostrando los resultados.\n*/\n}\n"
  },
  {
    "path": "Roadmap/08 - CLASES/c#/charlerodriguez3.cs",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n * \n */\nAvion avion1 = new();\n\n//Instanciado por el constructor\navion1.DescripcionAeronave();\n\n//Llenado de atributos\n\navion1.NroMatricula = \"HKT-243KD\";\navion1.NumeroMotores = 2;\navion1.TipoMotor = \"Turbina\";\n\navion1.DescripcionAeronave();\n\n\n\n\npublic class Avion\n{\n    public int NumeroMotores { get; set; }\n    public string NroMatricula{ get; set; }\n    public string TipoMotor {  get; set; }\n\n    public Avion()\n    {\n        NumeroMotores = 1;\n        NroMatricula = String.Empty;\n        TipoMotor = \"Turbo-Helice\";\n    }\n\n    public void DescripcionAeronave()\n    {\n        Console.WriteLine(\"El avion 1 tiene las siguientes caracteristicas\");\n        Console.WriteLine($\"Numero de motores: {NumeroMotores}, Numero de matricula: {NroMatricula} y Tipo de motor es: {TipoMotor} \\n\");\n    }\n\n}"
  },
  {
    "path": "Roadmap/08 - CLASES/c#/devcherry1.cs",
    "content": "using System;\nclass Program\n{\n    static void Main()\n    {\n        Videogame videogame1 = new Videogame(\"Lies Of Pi\", 2023, \"Souls\");\n        Videogame videogame2 = new Videogame(\"Sekiro\", 2019, \"Souls\");\n        Videogame.Conteo();\n    }\n}\nclass Videogame\n{\n    public string Nombre { get; set; }\n    public int Lanzamiento { get; set; }\n    public string Genero { get; set; }\n    public static int Total = 0;\n    /*Dado que el campo Total debe mantener un conteo compartido \n     * entre todas las instancias de la clase Videogame, \n     * este debe ser un miembro estático. De lo contrario, \n     * cada instancia tendrá su propio Total y el conteo no funcionará correctamente. \n     */\n    \n    public Videogame (string nombre, int lanzamiento, string genero)\n    {\n        Nombre = nombre;\n        Lanzamiento = lanzamiento;\n        Genero = genero;\n        Total += 1;\n    }\n    public static void Conteo()\n    {\n        Console.WriteLine($\"Tienes {Total} videojuegos en la bibilioteca\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/08 - CLASES/c#/estuardodev.cs",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n * \n */\n\nnamespace estuardodev\n{\n    internal class estuardodev\n    {\n        public static void Main(string[] args)\n        {\n            Personaje personaje = new Personaje(\"Ninja\", \"10\", 100);\n            personaje.Imprimir();\n        }\n    }\n\n    // Reto\n    internal class Personaje\n    {\n        private string nombre;\n        private string fuerza;\n        private int vida;\n\n        public Personaje(string nombre, string fuerza, int vida)\n        {\n            this.nombre = nombre;\n            this.fuerza = fuerza;\n            this.vida = vida;\n        }\n\n        public void Imprimir()\n        {\n            Console.WriteLine(\"Nombre: \" + nombre);\n            Console.WriteLine(\"Fuerza: \" + fuerza);\n            Console.WriteLine(\"Vida: \" + vida);\n\n            Pila pila = new Pila();\n            pila.add(\"Pila 1\");\n            pila.add(\"Pila 2\");\n            pila.add(\"Pila 3\");\n\n            Console.WriteLine(\"Pila: \"+ pila.see());\n            pila.remove();\n            pila.forEach();\n\n            Cola cola = new Cola();\n            cola.add(\"Cola 1\");\n            cola.add(\"Cola 2\");\n            cola.add(\"Cola 3\");\n\n            Console.WriteLine(\"Cola: \" + cola.see());\n            cola.remove();\n            cola.forEach();\n        }\n    }\n\n    // Dificultad extra\n    internal class Pila\n    {\n        private Stack<object> stack = new Stack<object>();\n\n        public void add(object args)\n        {\n            stack.Push(args);\n        }\n\n        public void remove()\n        {\n            stack.Pop();\n        }\n\n        public object see()\n        {\n            return stack.Peek();\n        }\n\n        public void forEach()\n        {\n            foreach (var item in stack)\n            {\n                Console.WriteLine(item);\n            }\n        }\n\n    }\n\n    internal class Cola\n    {\n        private Queue<object> queue = new Queue<object>();\n\n        public void add(object args)\n        {\n            queue.Enqueue(args);\n        }\n\n        public void remove()\n        {\n            queue.Dequeue();\n        }\n\n        public object see()\n        {\n            return queue.Peek();\n        }\n\n        public void forEach()\n        {\n            foreach (var item in queue)\n            {\n                Console.WriteLine(item);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/08 - CLASES/c#/hequebo.cs",
    "content": "class Program\n{\n    static void Main(string[] args)\n    {\n        // Clases\n        var desarrolllador1 = new Desarrollador(\"Emilio Quezada\", 27, \"Mexicano\", new List<string> { \"C#\", \"Javascript\", \"VB\" });\n        desarrolllador1.Imprimir();\n        desarrolllador1.Nombre = \"Héctor Borja\";\n        desarrolllador1.Edad = 28;\n        desarrolllador1.Nacionalidad = \"Español\";\n        desarrolllador1.Lenguajes.Remove(\"VB\");\n        desarrolllador1.Lenguajes.Add(\"SQL\");\n        desarrolllador1.Imprimir();\n        Console.ReadLine();\n\n        // Ejercicio extra\n        // Stack\n        Stack stack = new Stack();\n        stack.Push(1);\n        stack.Push(2);\n        stack.Push(3);\n        stack.Push(4);\n        stack.Imprmir();\n        Console.WriteLine($\"La pila tiene {stack.Count()} elementos...\");\n\n        int eliminado = stack.Pop();\n        Console.WriteLine($\"Se eliminó el elmento {eliminado}\");\n        eliminado = stack.Pop();\n        Console.WriteLine($\"Se eliminó el elmento {eliminado}\");\n        stack.Imprmir();\n        Console.WriteLine($\"La pila tiene {stack.Count()} elementos...\");\n        Console.ReadLine();\n\n        // Queue\n        Queue queue = new Queue();\n        queue.Enqueue(1);\n        queue.Enqueue(2);\n        queue.Enqueue(3);\n        queue.Enqueue(4);\n        queue.Imprmir();\n        Console.WriteLine($\"La cola tiene {queue.Count()} elementos\");\n\n        eliminado = queue.Dequeue();\n        Console.WriteLine($\"Se eliminó el elmento {eliminado}\");\n        eliminado = queue.Dequeue();\n        Console.WriteLine($\"Se eliminó el elmento {eliminado}\");\n        queue.Imprmir();\n        Console.WriteLine($\"La cola tiene {queue.Count()} elementos\");\n    }\n}\n\nclass Desarrollador\n{\n    private string _nombre;\n    private int _edad;\n    private string _nacionalidad;\n    private List<string> _lenguajes;\n\n    public string Nombre\n    {\n        get\n        {\n            return _nombre;\n        }\n        set\n        {\n            _nombre = value;\n        }\n    }\n    public int Edad\n    {\n        get\n        {\n            return _edad;\n        }\n        set\n        {\n            _edad = value;\n        }\n    }\n    public string Nacionalidad\n    {\n        get\n        {\n            return _nacionalidad;\n        }\n        set\n        {\n            _nacionalidad = value;\n        }\n    }\n    public List<string> Lenguajes\n    {\n        get\n        {\n            return _lenguajes;\n        } \n        set\n        {\n            _lenguajes = value;\n        }\n    }\n    public Desarrollador(string nombre, int edad, string nacionalidad, List<string> lenguajes)\n    {\n        _nombre = nombre;\n        _edad = edad;\n        _nacionalidad = nacionalidad;\n        _lenguajes = lenguajes;\n    }\n\n    public void Imprimir()\n    {\n        Console.WriteLine($\"Nombre: {_nombre}, Edad: {_edad}, Nacionalidad: {_nacionalidad}\");\n        Console.WriteLine(\"Lenguajes: \");\n        foreach (string lenguaje in _lenguajes)\n            Console.Write($\"{lenguaje}, \");\n        Console.WriteLine();\n    }\n}\nclass Stack\n{\n    private List<int> _stack;\n\n    public Stack()\n    {\n        _stack = new List<int>();\n    }\n\n    public void Push(int valor)\n    {\n        _stack.Insert(0, valor);\n    }\n    public int Pop()\n    {\n        if (_stack.Count == 0)\n        {\n            Console.WriteLine(\"La pila está vacía...\");\n            return -1;\n        }\n        int eliminado = _stack.First();\n        _stack.RemoveAt(0);\n        return eliminado;\n    }\n\n    public int Count()\n    {\n        return _stack.Count;\n    }\n    public void Imprmir()\n    {\n        if ( _stack.Count == 0 )\n            Console.WriteLine(\"La pila está vacía\");\n        foreach (int elemento in _stack)\n            Console.Write($\"{elemento}, \");\n        Console.WriteLine();\n    }\n}\nclass Queue\n{\n    private List<int> _queue;\n\n    public Queue()\n    {\n        _queue = new List<int>();\n    }\n\n    public void Enqueue(int valor)\n    {\n        _queue.Add(valor);\n    }\n    public int Dequeue()\n    {\n        if (_queue.Count == 0)\n        {\n            Console.WriteLine(\"La cola está vacía...\");\n            return -1;\n        }\n        int eliminado = _queue.First();\n        _queue.RemoveAt(0);\n        return eliminado;\n    }\n\n    public int Count()\n    {\n        return _queue.Count;\n    }\n    public void Imprmir()\n    {\n        if (_queue.Count == 0)\n            Console.WriteLine(\"La cola está vacía\");\n        foreach (int elemento in _queue)\n            Console.Write($\"{elemento}, \");\n        Console.WriteLine();\n    }\n}\n"
  },
  {
    "path": "Roadmap/08 - CLASES/c#/isaacus98.cs",
    "content": "﻿/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n */\n\nnamespace RetosProgramacion2024\n{\n    internal class Reto8\n    {    \n        static void Main(string[] args)\n        {\n            // Crear objeto persona y establecer valor a sus atributos\n            Persona persona = new();\n            persona.Nombre = \"Isaac\";\n            persona.Edad = 26;\n\n            // Imprimir atributos\n            persona.ImprimirAtributos();\n\n            // Canviar valor de los atributos\n            persona.Nombre = \"Sergi\";\n            persona.Edad = 25;\n\n            // Imprimir atributos\n            persona.ImprimirAtributos();\n\n            // Reto extra\n            Console.WriteLine(\"\\nPila\\n\");\n            Pila<int> pila = new();\n            pila.Push(1);\n            pila.Push(2);\n            pila.Push(3);\n\n            Console.WriteLine(pila.Size());\n            pila.Print();\n            Console.WriteLine(\"\\n\" + pila.Pop());\n\n\n            Console.WriteLine(\"\\nCola\\n\");\n            Cola<int> cola = new();\n            cola.Enqueue(1);\n            cola.Enqueue(2);\n            cola.Enqueue(3);\n\n            Console.WriteLine(cola.Size());\n            cola.Print();\n            Console.WriteLine(\"\\n\" + cola.Dequeue());\n        }\n    }\n\n    public class Persona\n    {\n        public string Nombre;\n        public int Edad;\n\n        public Persona()\n        {\n\n        }\n\n        public void ImprimirAtributos()\n        {\n            Console.WriteLine($\"Nombre: {Nombre}, Edad: {Edad}\");\n        }\n    }\n\n\n    // Reto extra\n    public class Cola<T1>\n    {\n        private Queue<T1> queue;\n\n        public Cola()\n        {\n            queue = new Queue<T1> ();\n        }\n\n        public void Enqueue(T1 item)\n        {\n            queue.Enqueue (item);\n        }\n\n        public T1 Dequeue()\n        {\n           return queue.Dequeue ();\n        }\n\n        public int Size()\n        {\n            return queue.Count ();\n        }\n\n        public void Print()\n        {\n            foreach (T1 item in queue)\n            {\n                Console.Write (item + \" \");\n            }\n        }\n    }\n\n    public class Pila<T1>\n    {\n        private Stack<T1> stack;\n\n        public Pila()\n        {\n            stack = new Stack<T1>();\n        }\n\n        public void Push(T1 item)\n        {\n            stack.Push(item);\n        }\n\n        public T1 Pop()\n        {\n            return stack.Pop();\n        }\n\n        public int Size()\n        {\n            return stack.Count();\n        }\n\n        public void Print()\n        {\n            foreach (T1 item in stack)\n            {\n                Console.Write(item + \" \");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/08 - CLASES/c#/jamerrq.cs",
    "content": "﻿using System;\r\n\r\nnamespace Roadmap08\r\n{\r\n    class Example\r\n    {\r\n        // Atributos\r\n        private string message;\r\n        // Propiedades\r\n        public string Message\r\n        {\r\n            get { return message; }\r\n            set { message = value; }\r\n        }\r\n        // Constructor\r\n        public Example(string message)\r\n        {\r\n            this.message = message;\r\n        }\r\n        // Funciones\r\n        public void PrintMessage()\r\n        {\r\n            Console.WriteLine(message);\r\n        }\r\n        // Main\r\n        static void Main(string[] args)\r\n        {\r\n            Example example = new Example(\"Hello, C#!\");\r\n            example.PrintMessage();\r\n            example.Message = \"Goodbye, Julia!\";\r\n            example.PrintMessage();\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "Roadmap/08 - CLASES/c#/kenysdev.cs",
    "content": "/*\n╔══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado               ║\n║ GitHub: https://github.com/Kenysdev  ║\n║ 2024 -  C#                           ║\n╚══════════════════════════════════════╝\n------------------------------------------\n# CLASES\n------------------------------------------\n- Las clases proporcionan una forma de organizar y estructurar\n  el código de manera más modular y reutilizable. */\n\nclass Program{\n   public class Person{\n      // Propiedades\n      public string Name { get; set; }\n      public int Age { get; set; }\n\n      //Constructor\n      public Person(string name, int age){\n         this.Name = name;\n         this.Age = age;\n      }\n\n      // Metodo\n      public void Print(){\n         Console.WriteLine($\"Nombre: {Name} - Edad: {Age}\");\n      }\n   }\n\n   /*----------------------------------------\n     Ejercicio:\n     ----------------------------------------\n   - Implementa dos clases que representen las estructuras de Pila y Cola \n     (estudiadas en el ejercicio número 7 de la ruta de estudio)\n   - Deben poder inicializarse y disponer de operaciones para añadir, \n     eliminar, retornar el número de elementos e imprimir todo su contenido.\n     _________________________________________\n     Pilas(stack - LIFO): */\n   public class MyStack{\n      private Stack<object> _stack = new();\n\n      public void Push(object item){\n         _stack.Push(item);\n      }\n\n      public object? Pop(){\n         if (_stack.Count > 0){\n            return _stack.Pop();\n         }\n         else {\n            return null;\n         }\n      }\n\n      public int Count(){\n         return _stack.Count;\n      }\n\n      public void Print(){\n         if (_stack.Count > 0){\n            foreach (object item in _stack){\n               Console.WriteLine(item);\n            }\n         }\n      }\n   }\n\n// _________________________________________\n// Colas (Queue - FIFO):\n   public class MyQueue{\n      private Queue<object> _queue = new();\n\n      public void Enqueue(object item){\n         _queue.Enqueue(item);\n      }\n\n      public object? Dequeue(){\n         if (_queue.Count > 0){\n            return _queue.Dequeue();\n         }\n         else {\n            return null;\n         }\n      }\n\n      public int Count(){\n         return _queue.Count;\n      }\n\n      public void Print(){\n         if (_queue.Count > 0){\n            foreach (object item in _queue){\n               Console.WriteLine(item);\n            }\n         }\n      }\n   }\n\n// _________________________________________\n   static void Main(){\n      // Crear objeto\n      var person = new Person(\"Ben\", 21);\n      person.Print();\n      person.Age = 19;\n      person.Print();\n      \n      // --------------\n      Console.WriteLine(\"Uso de pila:\");\n      var Stack = new MyStack();\n      Stack.Push(\"uno\");\n      Stack.Push(22222);\n      Stack.Push(false);\n      Stack.Pop();\n      Stack.Print();\n\n      // --------------\n      Console.WriteLine(\"Uso de cola:\");\n      var Queue = new MyQueue();\n      Queue.Enqueue(\"uno\");\n      Queue.Enqueue(22222);\n      Queue.Enqueue(33.33);\n      Queue.Dequeue();\n      Queue.Print();\n   }\n}\n"
  },
  {
    "path": "Roadmap/08 - CLASES/c#/rxvlc.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\n\nnamespace R08___2024\n{\n    //Creacion de clase:\n    class MiClase\n    {\n        //Defino los atributos, por ejemplo una persona:\n        string nombre;\n        int edad;\n\n        //Aquí irían las propiedades, esto está en pocos lenguajes, de normal se usan getters y setters...\n        //Las propiedades sirven para poder ver un atributo (get) o cambiar el atributo (set). Ejemplo:\n        public string Nombre { get { return nombre; } set { nombre = value; } }\n        //También podemos hacerla solo que retorne el valor pero que no lo cambie (set) para el data hiding:\n        public int Edad { get { return edad; } }\n\n        //Después de las propiedades van los constructores:\n        public MiClase(string nombre, int edad)\n        {\n            this.nombre = nombre;\n            this.edad = edad;\n        }\n        //Tambien podemos hacerlo sin parámetros para hacer readlines o asignar los valores que queramos:\n        public MiClase()\n        {\n            this.nombre = \"Ejemplo\";\n            this.edad = 99;\n        }\n\n        //Después de los constructores suelen ir los getter/setters podemos usar getter/setters o propiedades según queramos:\n        public string getNombre()\n        {\n            return this.nombre;\n        }\n        public void setNombre(string nombre)\n        {\n            this.nombre = nombre;\n        }\n\n        //Después van los métodos de implementación como por ejemplo sería cumpliranyos:\n        public void CumplirAnyos()\n        {\n            this.edad++;\n        }\n\n        //Y por último los de interfaz:\n        public string VerInfo()\n        {\n            return $\"{this.nombre},{this.edad}\";\n        }\n\n        //De manera más profesional sobreescribiendo el método toString:\n        public override string ToString()\n        {\n            return $\"{this.nombre},{this.edad}\";\n        }\n\n        //Dentro de la POO hay bastante más cosas pero esto es algo básico, una vez entendido sale solo ;)\n    }\n\n    //Dificultad adicional:\n    //La T mayúscula es un parámetro de tipo genérico, significa que esto funciona con todos los tipos de datos.\n    class Pila<T>\n    {\n        private Stack<T> elementos;\n\n        public Pila()\n        {\n            elementos = new Stack<T>();\n        }\n\n        public void Push(T elemento)\n        {\n            elementos.Push(elemento);\n        }\n\n        public T Pop()\n        {\n            return elementos.Pop();\n        }\n\n        public int Count()\n        {\n            return elementos.Count;\n        }\n\n        public void Imprimir()\n        {\n            Console.WriteLine(\"Contenido de la pila:\");\n            foreach (var elemento in elementos)\n            {\n                Console.WriteLine(elemento);\n            }\n        }\n    }\n\n    class Cola<T>\n    {\n        private Queue<T> elementos;\n\n        public Cola()\n        {\n            elementos = new Queue<T>();\n        }\n\n        public void Enqueue(T elemento)\n        {\n            elementos.Enqueue(elemento);\n        }\n\n        public T Dequeue()\n        {\n            return elementos.Dequeue();\n        }\n\n        public int Count()\n        {\n            return elementos.Count;\n        }\n\n        public void Imprimir()\n        {\n            Console.WriteLine(\"Contenido de la cola:\");\n            foreach (var elemento in elementos)\n            {\n                Console.WriteLine(elemento);\n            }\n        }\n    }\n\n\n\n    class Program\n    {\n        static void Main(string[] args)\n        {\n            MiClase objeto = new MiClase(\"Juan\", 30);\n\n            // Imprimir los atributos usando la función Imprimir\n            Console.WriteLine(\"Valores iniciales:\");\n            Console.WriteLine(objeto.ToString());\n\n            // Modificar los atributos\n            objeto.Nombre = \"Pedro\";\n\n            // Imprimir los atributos actualizados\n            Console.WriteLine(\"Valores modificados:\");\n            Console.WriteLine(objeto.ToString());\n\n\n            //Dificultad adicional:\n            // Ejemplo de uso de la clase Pila\n            Pila<int> pila = new Pila<int>();\n            pila.Push(1);\n            pila.Push(2);\n            pila.Push(3);\n            pila.Imprimir();\n            Console.WriteLine(\"Número de elementos en la pila: \" + pila.Count());\n            pila.Pop();\n            pila.Imprimir();\n            Console.WriteLine(\"Número de elementos en la pila: \" + pila.Count());\n\n            // Ejemplo de uso de la clase Cola\n            Cola<string> cola = new Cola<string>();\n            cola.Enqueue(\"Uno\");\n            cola.Enqueue(\"Dos\");\n            cola.Enqueue(\"Tres\");\n            cola.Imprimir();\n            Console.WriteLine(\"Número de elementos en la cola: \" + cola.Count());\n            cola.Dequeue();\n            cola.Imprimir();\n            Console.WriteLine(\"Número de elementos en la cola: \" + cola.Count());\n\n            Console.ReadKey();\n\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/08 - CLASES/c#/vixxtory.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel.Design;\nusing System.Net.NetworkInformation;\nusing System.Runtime.Intrinsics.X86;\nusing System.Security.Cryptography;\nusing System.Security.Cryptography.X509Certificates;\nusing static System.Runtime.InteropServices.JavaScript.JSType;\n\nnamespace RetosProgramacion\n{\n    class Program\n    {\n        static void Main(string[] args)\n        {\n            //Implemento los objetos basados en las clases\n            Almuerzo menu_1 = new Almuerzo(\"Fideos Con Salsa\", \"Salsa bolognesa con fideos de verdura\");\n            Console.WriteLine(menu_1.getNombre());\n            Console.WriteLine(menu_1.getDescripcion());\n\n            Cola artistas = new Cola();\n            artistas.AgregarElemento(\"Pintor\");\n            artistas.AgregarElemento(\"Escultor\");\n            artistas.ImprimirContenido();\n            Console.WriteLine(artistas.NumeroDeElementos());\n            artistas.EliminarElemento();\n            artistas.ImprimirContenido();\n        }\n    }\n\n    public class Almuerzo\n    {\n        private string nombre;\n        private string descripcion;\n\n        //Constructor predeterminado: inicializa variables por defecto\n        public Almuerzo()\n        {\n            nombre = \"Aprendiendo Logica junto a MoureDev\";\n            descripcion = \"Soy una clase dedicada a Almuerzos\";\n        }\n        //Constructor parametrizado\n        public Almuerzo(string nombre, string descripcion)\n        {\n            this.nombre = nombre;\n            this.descripcion = descripcion;\n        }\n        public string getNombre()\n        {\n            return nombre;\n        }\n        public string getDescripcion()\n        {\n            return descripcion;\n        }   \n\n    }\n    public class Cola\n    {\n        private Queue<string> queue = new Queue<string>();\n        public void AgregarElemento(string elemento)\n        {\n            queue.Enqueue(elemento);\n        }\n        public void EliminarElemento()\n        {\n            queue.Dequeue();\n        }\n        public int NumeroDeElementos()\n        {\n            return queue.Count();\n        }\n        public void ImprimirContenido()\n        {\n            foreach(string elemento in queue)\n            {\n                Console.WriteLine(elemento);\n            }\n        }\n    }\n    public class Pila\n    {\n        private Stack<string> stack = new Stack<string>();\n        public void AgregarElemento(string elemento)\n        {\n            stack.Push(elemento);\n        }\n        public void EliminarElemento()\n        {\n            stack.Pop();\n        }\n        public int NumeroDeElementos()\n        {\n            return stack.Count();\n        }\n        public void ImprimirContenido()\n        {\n            foreach (string elemento in stack)\n            {\n                Console.WriteLine(elemento);\n            }\n        }\n    }\n}\n\n\n"
  },
  {
    "path": "Roadmap/08 - CLASES/c++/Fravelz.cpp",
    "content": "#include <iostream>\n#include <vector>\nusing namespace std;\n\n// ************************** Clase ************************** //\n\nclass Clase {\nprivate:\n    string text_;\n    int number_;\n    \nprotected: string info = \"protegido\";\n\npublic:\n    Clase(string text = \"default\", int number = 0) : text_(text), number_(number) {\n        cout << \"[+]\";\n    }\n\n    ~Clase() { cout << \"[-]\"; }\n\n    string getTexto() { return text_; }\n    int getNumber() { return number_; }\n\n    void setTexto(string text) { text_ = text; }\n    void setNumber(int number) { number_ = number; }\n\n    bool operator==(const Clase& other) const {\n        return text_ == other.text_ && number_ == other.number_;\n    }\n\n    /*\n    friend: Permite que la función acceda a los miembros private de la \n    clase (text_ y number_).\n\n    ostream&: Devuelve una referencia al flujo de salida (por ejemplo \n    cout), para poder encadenar (cout << a << b;).\n\n    operator<<: Estamos definiendo cómo se comporta el operador << con \n    objetos de tipo Clase.\n\n    os << \"(\" << c.text_ << \", \" << c.number_ << \")\": Construye la \n    salida del objeto como una tupla (texto, número).\n    */\n\n    friend ostream& operator<<(ostream& os, const Clase& c) { \n        return os << \"(\" << c.text_ << \", \" << c.number_ << \")\";\n    }\n};\n\n// ******************** Base de Pila y Cola ******************** //\n\ntemplate <class T>\nclass Base {\nprotected:\n    vector<T> elements;\n\npublic:\n    Base(T element = T{}) {\n        if (!(element == T{})) elements.push_back(element);\n    }\n\n    virtual ~Base() {}\n\n    void showElements() {\n        for (const T& element : elements)\n            cout << element << ' ';\n        cout << endl;\n    }\n\n    virtual void addElement(T) = 0;\n    virtual void deleteElement() = 0;\n};\n\n// ************************** Pila (LIFO) ************************** //\n\ntemplate <class T>\nclass Pila : public Base<T> {\n    using Base<T>::elements;\n\npublic:\n    Pila(T element = T{}) : Base<T>(element) {}\n\n    void addElement(T new_data) override {\n        elements.push_back(new_data);\n    }\n\n    void deleteElement() override {\n        if (!elements.empty()) elements.pop_back();\n    }\n};\n\n// ************************** Cola (FIFO) ************************** //\n\ntemplate <class T>\nclass Cola : public Base<T> {\n    using Base<T>::elements;\n\npublic:\n    Cola(T element = T{}) : Base<T>(element) {}\n\n    void addElement(T new_data) override {\n        elements.push_back(new_data);\n    }\n\n    void deleteElement() override {\n        if (!elements.empty())\n            elements.erase(elements.begin());  // elimina el primero\n    }\n};\n\n// ************************** MAIN ************************** //\n\nint main() {\n    //* Pila / Stack (LIFO)\n    Pila<int> stack;\n\n    stack.addElement(10);\n    stack.addElement(20);\n    stack.addElement(30);\n\n    cout << \"\\nPila: \";\n    stack.showElements(); // 10 20 30\n\n    stack.deleteElement(); // elimina 30\n\n    cout << \"Pila tras pop: \";\n    stack.showElements(); // 10 20\n\n    //* Cola / Queue (FIFO)\n    Cola<int> queue;\n\n    queue.addElement(1);\n    queue.addElement(2);\n    queue.addElement(3);\n\n    cout << \"\\nCola: \";\n    queue.showElements(); // 1 2 3\n\n    queue.deleteElement(); // elimina 1\n\n    cout << \"\\nCola tras dequeue: \";\n    queue.showElements(); // 2 3\n    cout << '\\n';\n\n    //* Cola con clases :v\n    Cola<Clase> colaClases;\n    colaClases.addElement(Clase(\"obj1\", 1));\n    colaClases.addElement(Clase(\"obj2\", 2));\n    colaClases.addElement(Clase(\"obj3\", 3));\n\n    cout << '\\n';\n    cout << \"\\nCola de objetos: \";\n\n    colaClases.showElements();\n\n    colaClases.deleteElement();\n\n    cout << '\\n';\n    cout << \"\\nCola de objetos tras dequeue: \";\n\n    colaClases.showElements();\n    cout << '\\n';\n\n    return 0;\n}\n\n\n// Todo: Impresion en terminar...\n/* \nPila: 10 20 30 \nPila tras pop: 10 20\n\nCola: 1 2 3\n\nCola tras dequeue: 2 3\n\n[+][+][-][-][-][+][-][+][-][-][+][-][-][-]\n\nCola de objetos: (obj1, 1) (obj2, 2) (obj3, 3)\n[-]\n\nCola de objetos tras dequeue: (obj2, 2) (obj3, 3)\n\n[-][-]\n*/"
  },
  {
    "path": "Roadmap/08 - CLASES/c++/RoniPG.cpp",
    "content": "//@Roni\n#include <iostream>\n#include <string>\n#include <stack>\n#include <queue>\n/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n */\nclass Iguana{\nprivate:\n\tstd::string genero;\n\tstd::string endemico;\n\tstd::string especie;\npublic:\n\tIguana(){\n\t\tthis ->genero=\"\";\n\t\tthis ->endemico=\"\";\n\t\tthis ->especie=\"\";\n\t}\n\n\tconst std::string& getEndemico() const {\n\t\treturn endemico;\n\t}\n\n\tvoid setEndemico(const std::string &endemico) {\n\t\tthis->endemico = endemico;\n\t}\n\n\tconst std::string& getEspecie() const {\n\t\treturn especie;\n\t}\n\n\tvoid setEspecie(const std::string &especie) {\n\t\tthis->especie = especie;\n\t}\n\n\tconst std::string& getGenero() const {\n\t\treturn genero;\n\t}\n\n\tvoid setGenero(const std::string &genero) {\n\t\tthis->genero = genero;\n\t}\n\tvoid print(){\n\t\tstd::cout<<\"Genero: \"<<this->genero<<\"\\nEndemico: \"<<this->endemico<<\"\\nEspecie: \"<<this->especie<<std::endl;\n\t}\n};\n/*\n* DIFICULTAD EXTRA (opcional):\n* Implementa dos clases que representen las estructuras de Pila y Cola\n* (estudiadas en el ejercicio número 7 de la ruta de estudio)\n* - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n*   retornar el número de elementos e imprimir todo su contenido.\n*/\nclass Pila{\n\tprivate:\n\t\tstd::stack<int> datos;\n\tpublic:\n\tPila() {\n    }\n    void anyadirDatos(int dato) {\n    \tthis->datos.push(dato);\n    }\n    void elminarDatos() {\n    \tif (!datos.empty()) {\n    \t\tthis->datos.pop();\n        }else {\n        \tstd::cout<<\"La pila esta vacía\"<<std::endl;\n        }\n    }\n    int numeroDeElementos() {\n    \treturn datos.size();\n    }\n    void print() {\n    \tstd::stack<int> temp=datos;\n    \tint i=0;\n    \twhile(!temp.empty()){\n    \t\ti++;\n    \t\tstd::cout<<\"Dato \"<<i<<\"= \"<<temp.top()<<std::endl;\n    \t\ttemp.pop();\n    \t}\n    }\n};\nclass Cola{\n\tprivate:\n\tstd::queue<std::string> datos;\n\tpublic:\n\tCola() {\n\t}\n\tvoid anyadirDatos(std::string dato) {\n\t\tthis->datos.push(dato); // --> También podríamos utilizar datos.add(dato);\n\t}\n\tvoid elminarDatos() {\n\t\tif (!datos.empty()) {\n\t\t\tthis->datos.pop();\n\t\t}else {\n\t\t\tstd::cout<<\"La pila esta vacía\"<<std::endl;\n        }\n\t}\n\tint numeroDeElementos() {\n\t\treturn datos.size();\n\t}\n\tvoid print() {\n\t\tstd::queue<std::string> temp=datos;\n\t\tint i=0;\n\t\twhile(!temp.empty()){\n\t\t\ti++;\n\t\t\tstd::cout<<\"Dato \"<<i<<\"= \"<<temp.front()<<std::endl;\n\t\t\ttemp.pop();\n\t\t}\n\t}\n};\n\nint main(){\n\tIguana ig1; // --> Instanciamos/Incicalizamos la clase\n\tstd::cout<<\"****IGUANA****\"<<std::endl;\n\t /*Le asignamos los valores*/\n\tig1.setGenero(\"Macho\");\n\tig1.setEndemico(\"Sudamerica\");\n\tig1.setEspecie(\"Iguana\");\n\tig1.print(); // --> Llamamos al método que nos devolvera los valores\n\tstd::cout<<\"****PILA****\"<<std::endl;\n\tPila pila ; // --> Instanciamos/Incicalizamos la clase\n\t/*Le asignamos los valores*/\n\tpila.anyadirDatos(1);            pila.anyadirDatos(2);            pila.anyadirDatos(3);\n\tstd::cout<<\"El número de elementos es: \"<<pila.numeroDeElementos()<<std::endl; // --> Imprimimos números de elementos\n\tstd::cout<<\"Su contenido es:\\n\"; pila.print(); // --> Imprimimos todos los datos\n\tpila.elminarDatos(); // --> Eliminamos elemento de arriba de la pila\n\tstd::cout<<\"El número de elementos despúes de pila.elminarDatos(): \"<<pila.numeroDeElementos()<<std::endl;\n\tstd::cout<<\"Su contenido despúes de pila.elminarDatos():\\n\"; pila.print();\n\tpila.elminarDatos();\n\tpila.elminarDatos();\n\tpila.elminarDatos(); // --> Salta el aviso\n\tstd::cout<<\"****COLA****\"<<std::endl;\n\tCola cola ; // --> Instanciamos/Incicalizamos la clase\n\t/*Le asignamos los valores*/\n\tcola.anyadirDatos(\"Elemento 0\");         cola.anyadirDatos(\"Elemento 1\");         cola.anyadirDatos(\"Elemento 2\");\n\tstd::cout<<\"El número de elementos es: \"<<cola.numeroDeElementos()<<std::endl; // --> Imprimimos números de elementos\n\tstd::cout<<\"Su contenido es:\\n\"; cola.print(); // --> Imprimimos todos los datos\n\tcola.elminarDatos(); // --> Eliminamos elemento de la cabeza de la cola\n\tstd::cout<<\"El número de elementos despúes de cola.elminarDatos(): \"<<cola.numeroDeElementos()<<std::endl;\n\tstd::cout<<\"Su contenido despúes de cola.elminarDatos():\\n\"; cola.print();\n\tcola.elminarDatos();\n\tcola.elminarDatos();\n\tcola.elminarDatos(); // --> Salta el aviso\n\treturn 0;\n}\n"
  },
  {
    "path": "Roadmap/08 - CLASES/c++/Vid92.cpp",
    "content": "\n#include <iostream>\n#include <queue>\n#include <stack>\n\nusing namespace std;\n\nclass persona{\n    private:\n        string name;\n        string profesion;\n        int edad;\n        \n    public: //constructor \n        persona(string name,string profesion,int edad){\n            this->name = name;\n            this->profesion = profesion;\n            this->edad = edad;\n        }\n        \n        void imprimir(){\n            cout<<\"Nombre: \"<<this->name<<endl<<\"Edad: \"<<this->edad<<endl<<\"Profesion: \"<<this->profesion<<endl;\n        }\n};\n\nclass Pila{\n    private:\n        stack<int>pp;\n        \n    public:\n        Pila(){\n            \n        }\n        \n    void agregarDato(int dato){\n        pp.push(dato);\n        cout<<\"El número ingresado a la Pila: \"<<dato<<endl;\n    }\n    \n    void eliminarDato(){\n        pp.pop();\n        cout<<\"Se elimina un número de la Pila\"<<endl;\n    }\n    \n    void primerStack(){\n        cout<<\"Primer elemento de la Pila: \"<<pp.top()<<endl;\n    }\n    \n    void tamañoStack(){\n        cout<<\"Tamaño de la Pila: \"<<pp.size()<<endl;\n    }\n    \n    void totalStack(){\n        stack<int> tmp=pp;\n        int i = 1;\n        cout<<\"Elementos en Pila:\"<<endl;\n        while(i!=tmp.size()){\n            i++;\n            if(!tmp.empty()){\n                cout<<tmp.top()<<endl;\n                tmp.pop();   \n            }\n            else{\n                break;\n            }\n        }\n    }\n};\n\nclass Cola{\n    private:\n        queue<int>qq;\n        int numero;\n        \n    public:\n        Cola(){\n            this->numero;\n        }\n       \n        \n    void agregarDato(int dato){\n        this->numero = dato;\n        qq.push(this->numero);\n        cout<<\"El número ingresado al Queue: \"<<this->numero<<endl;\n    }\n    \n    void eliminarDato(){\n        qq.pop();\n        cout<<\"Se elimina un número del Queue\"<<endl;\n    }\n    \n    void mostrarQueue(){\n        cout<<\"Primer elemento del Queue: \"<<qq.front()<<endl;\n    }\n    \n    void tamañoQueue(){\n        cout<<\"Tamaño del Queue: \"<<qq.size()<<endl;\n    }\n    \n    void ultimoQueue(){\n        cout<<\"Ultimo elemento: \"<<qq.back()<<endl;\n    }\n    \n    void totalQueue(){\n        queue<int> tmp=qq;\n        int i = 1;\n        cout<<\"Elementos en Queue:\"<<endl;\n        while(i!=tmp.size()){\n            i++;\n            if(!tmp.empty()){\n                cout<<tmp.front()<<endl;\n                tmp.pop();   \n            }\n            else{\n                break;\n            }\n        }\n    }\n};\n\nint main()\n{\n    persona* gente1 = new persona(\"María\",\"Doctora\",19);\n    gente1->imprimir();\n    \n    cout<<endl;\n    \n    persona* gente2 = new persona(\"Jóse\",\"Profesor\",30);\n    gente2->imprimir();\n    \n    //Dificultad extra\n    Cola par;\n    Pila par2;\n    \n    cout<<endl<<\"------------------------Queue------------------------\"<<endl;\n    \n    par.agregarDato(30);\n    par.agregarDato(7);\n    par.agregarDato(11);\n    par.agregarDato(5);\n    \n    cout<<endl;\n    par.mostrarQueue();\n    par.totalQueue();\n    par.ultimoQueue();\n    par.tamañoQueue();\n    par.eliminarDato();\n    par.mostrarQueue();\n    par.tamañoQueue();\n    \n    cout<<endl<<\"-----------------------Stack-----------------------\"<<endl;\n    \n    par2.agregarDato(10);\n    par2.agregarDato(3);\n    par2.agregarDato(9);\n    par2.agregarDato(17);\n    \n    cout<<endl;\n    par2.tamañoStack();\n    par2.totalStack();\n    par2.primerStack();\n    par2.eliminarDato();\n    par2.tamañoStack();\n    par2.primerStack();\n    \n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/08 - CLASES/c++/dylanb55.cpp",
    "content": "#include<iostream>\n#include<stack>\n#include<queue>\nusing namespace std;\n\nclass Persona{\n\tprivate:\n\t\tstring nombre;\n\t\tstring pais_origen;\n\t\tstring titulo_universitario;\n\t\tbool titulo;\n\t\tint edad;\n\tpublic:\n\t\t//Constructor 1 (para personas sin titulo universitario)\n\t\t\n\t\tPersona(string nombre, string pais_origen, int edad){\n\t\t\tthis->nombre = nombre;\n\t\t\tthis->pais_origen = pais_origen;\n\t\t\tthis->edad = edad;\n\t\t\ttitulo = false;\n\t\t}\n\t\t\n\t\t//Constructor 2 (para personas con titulo universitario)\n\t\t\n\t\tPersona(string nombre, string pais_origen, string titulo_universitario, int edad){\n\t\t\tthis->nombre = nombre;\n\t\t\tthis->pais_origen = pais_origen;\n\t\t\tthis->titulo_universitario = titulo_universitario;\n\t\t\tthis->edad = edad;\n\t\t\ttitulo = true;\n\t\t}\n\t\t\n\t\t//Setters\n\t\t\n\t\tvoid setNuevoNombre(string nombre){\n\t\t\tthis->nombre = nombre;\n\t\t}\n\t\t\n\t\tvoid setNuevoPais(string pais_origen){\n\t\t\tthis->pais_origen = pais_origen;\n\t\t}\n\t\t\n\t\tvoid setNuevoTitulo(string titulo_universitario){\n\t\t\tthis->titulo_universitario = titulo_universitario;\n\t\t}\n\t\t\n\t\tvoid setNuevaEdad(int edad){\n\t\t\tthis->edad = edad;\n\t\t}\n\t\t\n\t\tstring getNombre(){\n\t\t\treturn this->nombre;\n\t\t}\n\t\t\n\t\tstring getPais(){\n\t\t\treturn this->pais_origen;\n\t\t}\n\t\t\n\t\tstring getTitulo(){\n\t\t\treturn this->titulo_universitario;\n\t\t}\n\t\t\n\t\tint getEdad(){\n\t\t\treturn this->edad;\n\t\t}\n\t\t\n\t\t//Funciones\n\t\t\n\t\tvoid imprimirDatos(){\n\t\t\tcout << \"Nombre: \" << nombre << endl;\n\t\t\tcout << \"Pais: \" << pais_origen << endl;\n\t\t\tif(titulo == true){\n\t\t\t\tcout << \"Titulo: \" << titulo_universitario << endl;\n\t\t\t}\n\t\t\telse{\n\t\t\t\tcout << nombre << \" no cuenta con titulo universitario \" << endl;\n\t\t\t}\n\t\t\tcout << \"Edad: \" << edad << endl;\n\t\t}\n};\n\nclass Pila{\n\tprivate:\n\t\tstack<int> mi_pila;\n\tpublic:\n\t\t//Constructor por defecto para pila\n\t\tPila(){\n\t\t\t\n\t\t}\n\t\tvoid ingresarNumero(int numero){\n\t\t\tmi_pila.push(numero);\n\t\t\tcout << \"Se ha ingresado correctamente el numero a pila\" << endl;\n\t\t}\n\t\t\n\t\t\n\t\tvoid eliminarDato(){\n\t\t\tmi_pila.pop();\n\t\t\tcout << \"\\nSe ha eliminado correctamente un numero de la pila\" << endl;\n\t\t}\n\t\t\n\t\tvoid mostrarLargo(){\n\t\t\tcout << \"El largo de la pila es: \" << mi_pila.size() << endl;\n\t\t}\n\t\t\n\t\tvoid mostrarElementos(){\n\t\t\twhile(mi_pila.empty() != true){\n\t\t\t\tcout << \"Numero:\" << mi_pila.top() << endl;\n\t\t\t\tmi_pila.pop();\n\t\t\t}\n\t\t}\n};\n\nclass Cola{\n\tprivate:\n\t\tqueue<int> mi_cola;\n\tpublic:\n\t\t//Constructor por defecto para cola\n\t\tCola(){\n\t\t\t\n\t\t}\n\t\t\n\t\tvoid ingresarNumero(int numero){\n\t\t\tmi_cola.push(numero);\n\t\t\tcout << \"Numero ingresado correctamente a la cola\" << endl;\n\t\t}\t\n\t\tvoid eliminarDato(){\n\t\t\tmi_cola.pop();\n\t\t\tcout << \"Se ha eliminado correctamente un numero de la cola\" << endl;\n\t\t}\n\t\t\n\t\tvoid mostrarLargo(){\n\t\t\tcout << \"El largo de la cola es: \" << mi_cola.size() << endl; \n\t\t}\n\t\tvoid mostrarElementos(){\n\t\t\twhile(mi_cola.empty() != true){\n\t\t\t\tcout << \"Numero: \" << mi_cola.front() << endl;\n\t\t\t\tmi_cola.pop();\n\t\t\t}\n\t\t}\n};\nint main(){\n\t//Probamos la clase Persona\n\t\n\tPersona* p1 = new Persona(\"Mauricio\",\"Argentina\",\"Ingeniero en informatica\",30);\n\tp1->imprimirDatos();\n\tcout << endl;\n\tPersona* p2 = new Persona(\"Jorge\",\"Chile\",19);\n\tp2->imprimirDatos();\n\tcout << endl;\n\t//Probamos la pila\n\t\n\tPila* pila1 = new Pila();\n\tpila1->ingresarNumero(5);\n\tpila1->ingresarNumero(10);\n\tpila1->ingresarNumero(323);\n\tpila1->mostrarLargo();\n\tpila1->eliminarDato(); //Recordar que las pilas usan el metodo ultimo en entrar primero en salir, es decir se borraria el elemento 323\n\tpila1->mostrarElementos();\n\tcout << endl;\n\t\n\t//Probamos la cola\n\t\n\tcout << endl;\n\t\n\tCola* cola1 = new Cola();\n\t\n\tcola1->ingresarNumero(50);\n\tcola1->ingresarNumero(300);\n\tcola1->ingresarNumero(23);\n\tcola1->ingresarNumero(3);\n\tcola1->ingresarNumero(-3);\n\tcola1->mostrarLargo();\n\tcola1->eliminarDato(); //Recordar que las colas usan el metodo el primero en entrar es el primero en salir, es decir se borra el elemento 50;\n\tcola1->mostrarElementos();\n}\n \n"
  },
  {
    "path": "Roadmap/08 - CLASES/c++/hectorio23.cpp",
    "content": "// Hector Adan\n// https://github.com/hectorio23\n#include <iostream>\n#include <memory>\n#include <string>\n\n/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n * \n */\n\nclass WebPage {\n    public:\n    int index = 0;\n    WebPage() {}\n    std::string Title;\n    WebPage(std::string title, int index): Title(title), index(index) {}\n    WebPage(const WebPage& other) : Title(other.Title) {}\n\n    void getInfo() {\n        // <Object WebPage at 0x7f61993bf420>\n        std::cout << \"<Object WebPage - \" << Title << \" at \" << (this) << \">\\n\";\n    }\n\n    std::string getTitle() { return this->Title; }\n};\n\n/// OPERATOR OVERLOADED FOR PRINT THE WebPage Memory\nstd::ostream& operator<<(std::ostream& output, WebPage& item) {\n    item.getInfo();\n    return output;\n };\n\nstruct Queue {\n    private:\n    std::shared_ptr<Queue> next = nullptr;\n    std::shared_ptr<Queue> last = nullptr; // Puntero al último elemento de la cola\n\n    public:\n    int size = 0;\n    WebPage page;\n    \n    Queue() {}\n    Queue(WebPage& item, std::shared_ptr<Queue> pointer) : page(item), next(pointer) {}\n\n    // Agrega un elemento al final de la cola\n    void push(WebPage& WebPageObject) {\n        std::shared_ptr<Queue> tmp = std::make_shared<Queue>(WebPageObject, nullptr);\n        if (size == 0) {\n            next = tmp;\n            last = tmp;\n        } else {\n            last->next = tmp;\n            last = tmp;\n        }\n        size++;\n    }\n\n    // Elimina y retorna el primer elemento de la cola\n    // Si la cola está vacía, devuelve nullptr\n    WebPage* pop() {\n        if (size == 0) return nullptr;\n\n\n        std::shared_ptr<Queue> aux = next;\n        next = aux->next;\n\n        size--;\n\n        // Si después de eliminar el elemento la cola queda vacía,\n        // también actualizamos el puntero al último elemento\n        if (size == 0) {\n            last = nullptr;\n        }\n\n        return &(aux->page);\n    }\n};\n\n\nstruct Stack {\n    private:\n    std::shared_ptr<Stack> next = nullptr;\n    std::shared_ptr<Stack> garbage = nullptr; // experimental\n\n    public:\n    int size = 0;\n    WebPage page;\n\n    Stack() {}\n    Stack(WebPage& item, std::shared_ptr<Stack> pointer) : page(item), next(pointer) {}\n\n    void push(WebPage& WebPageObject) {\n        std::shared_ptr<Stack> tmp = std::make_unique<Stack>(WebPageObject, next);\n        next = tmp;\n        size++;\n    }\n\n    // Modificación de la función pop para que devuelva el elemento eliminado si existe o nullptr si la pila está vacía\n    WebPage* pop() {\n        if (size == 0) return nullptr;\n\n        std::shared_ptr<Stack> aux = next;\n        next = aux->next;\n\n        size--;\n        return &(aux->page);\n    }\n};\n\n\nclass Persona {\nprivate:\n    std::string nombre;\n    int edad;\n\npublic:\n    // Constructor que inicializa los atributos\n    Persona(std::string nombre, int edad) {\n        this->nombre = nombre;\n        this->edad = edad;\n    }\n\n    // Función para imprimir los atributos\n    void info() {\n        std::cout << \"Nombre: \" << nombre << std::endl;\n        std::cout << \"Edad: \" << edad << std::endl;\n    }\n\n    // Función para establecer el nombre\n    void setNombre(std::string nuevoNombre) {\n        nombre = nuevoNombre;\n    }\n\n    // Función para establecer la edad\n    void setEdad(int nuevaEdad) {\n        edad = nuevaEdad;\n    }\n};\n\n int main() {\n    // Crear una instancia de Persona\n    Persona persona(\"Juan\", 30);\n\n    // Imprimir los atributos\n    std::cout << \"Datos de la persona:\" << std::endl;\n    persona.info();\n\n    // Modificar los atributos\n    persona.setNombre(\"María\");\n    persona.setEdad(25);\n\n    // Imprimir los atributos actualizados\n    std::cout << \"\\nDatos de la persona actualizados:\" << std::endl;\n\n    persona.info();\n\n    // Creando los objetos que se van a unir y eliminar del Stack y del Queue \n    WebPage p1 { \"index\", 1 };\n    WebPage p2 { \"index\", 2 };\n    WebPage p3 { \"index\", 3 };\n\n    // Creando un objeto de tipo Stack and Queue\n    Queue queue;\n    Stack stack;\n\n    // Zona en donde se agregan los elementos de tipo\n    // WebPage al stack para posteriormente eliminarlos\n    queue.push(p1);\n    queue.push(p2);\n    queue.push(p3);\n\n    std::cout << \"\\nNo. de elementos del queue: \" << queue.size << \"\\n\";\n    queue.pop();\n    queue.pop();\n    queue.pop();\n    std::cout << \"\\nNo. de elementos del queue despues de eliminarlos: \" << queue.size << \"\\n\";\n\n    // Zona en donde se agregan los elementos de tipo\n    // WebPage al Queue para posteriormente eliminarlos\n\n    stack.push(p1);\n    stack.push(p2);\n    stack.push(p3);\n    std::cout << \"\\nNo. de elementos del stack: \" << stack.size << \"\\n\";\n    stack.pop();\n    stack.pop();\n    stack.pop();\n    std::cout << \"\\nNo. de elementos del stack despues de eliminarlos: \" << queue.size << \"\\n\";\n\n    \n    return 0;\n }"
  },
  {
    "path": "Roadmap/08 - CLASES/c++/jchavescaceres.cpp",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n * \n */\n\n#include <iostream>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\nclass MyClass {\n\n\tprivate:\n\n\t\tint arg1;\n\t\tlong arg2;\n\n\tpublic:\n\n\t\tMyClass (int inArg1, int inArg2);\n\n\t\tint getArg1 ();\n\t\tlong getArg2 ();\n\n\t\tvoid setArg1 (int inArg1);\n\t\tvoid setArg2 (long inArg2);\n\n\t\tvoid print ();\n};\n\nMyClass::MyClass (int inArg1, int inArg2) :\n\targ1 (inArg1), arg2 (inArg2) {\n};\n\nint MyClass::getArg1 () {\n\treturn arg1;\n};\n\nlong MyClass::getArg2 () {\n\treturn arg2;\n};\n\n\nvoid MyClass::setArg1 (int inArg1) {\n\targ1 = inArg1;\n\n};\n\nvoid MyClass::setArg2 (long inArg2) {\n\targ2 = inArg2;\n};\n\nvoid MyClass::print () {\n\tstd::cout << \"MyClass : arg1:\" << arg1 << \", arg2:\" << arg2 << \"\\n\";\n};\n\n//Element abstract class, setPrint must be overwrite\nclass Element {\n\tprivate:\n\t\t//Element *previousElement;\n\t\t//Element *nextElement;\n\n\tprotected:\n\t\tElement ();\n\tpublic:\n\t\t//virtual Element* getPreviousElement();\n\t\t//virtual Element* getNextElement();\n\n\t\t//virtual void setPreviousElement(Element *inElement);\n\t\t//virtual void setNextElement(Element *inElement);\n\n\t\tvirtual void print() = 0;\n};\n\nElement::Element () {\n};\n\n//Generic Storage\nclass Storage {\n\n\tprotected:\n\t\tclass InnerElement {\n\t\t\tpublic:\n\n\t\t\t\tInnerElement() :\n\t\t\t\t\telement (NULL), previousElement (NULL),\n\t\t\t\t\tnextElement (NULL) {\n\t\t\t\t};\n\t\t\t\tElement *element;\n\t\t\t\tInnerElement *previousElement;\n\t\t\t\tInnerElement *nextElement;\n\t\t};\n\n\t\tInnerElement *firstElement;\n\t\tInnerElement *lastElement;\n\n\t\tStorage ();\n\n\tpublic:\n\t\tvirtual int isStorageEmpty();\n\t\tvirtual unsigned long getElementsCount();\n\t\tvirtual void push (Element *inElement);\n\t\tvirtual Element* pop () =0;\n\n\t\tvirtual void print();\n};\n\nStorage::Storage () : firstElement (NULL), lastElement (NULL) {\n};\n\nint Storage::isStorageEmpty() {\n\n\treturn firstElement == NULL;\n};\n\nunsigned long Storage::getElementsCount() {\n\n\tInnerElement *currentElement = firstElement;\n\tunsigned long totalElements = 0;\n\n\twhile (currentElement != NULL) {\n\t\ttotalElements++;\n\t\tcurrentElement = currentElement->nextElement;\n\t};\n\treturn totalElements;\n};\n\nvoid Storage::push (Element *newElement) {\n\t/* Add new element at the end of the list*/\n\n\tInnerElement *innerElement = new InnerElement();\n\n\tinnerElement->previousElement = lastElement;\n\tinnerElement->nextElement = NULL;\n\tinnerElement->element = newElement;\n\n\tif (firstElement == NULL) {\n\t\tfirstElement = innerElement;\n\t};\n\n\tif (lastElement == NULL) {\n\t\tlastElement = innerElement;\n\t} else {\n\t\tlastElement->nextElement = innerElement;\n\t\tlastElement = innerElement;\n\t};\n\n};\n\nvoid Storage::print() {\n\tInnerElement *currentElement = firstElement;\n\n\twhile (currentElement != NULL) {\n\t\tcurrentElement->element->print();\n\t\tcurrentElement = currentElement->nextElement;\n\t};\n};\n\n\n//Queue Storage\nclass Queue : public Storage {\n\n\tpublic:\n\t\tQueue();\n\t\tvirtual Element* pop ();\n};\n\nQueue::Queue() : Storage() {\n};\n\n//FIFO\nElement* Queue::pop () {\n\tElement *element = NULL;\n\tInnerElement *nextElement = NULL;\n\n\tif (firstElement != NULL) {\n\t\telement = firstElement->element;\n\n\t\tnextElement = firstElement->nextElement;\n\t\tdelete firstElement;\n\n\t\tif (nextElement != NULL) { \n\t\t\tfirstElement = nextElement;\n\t\t\tfirstElement->previousElement = NULL;\n\t\t} else {\n\t\t\tfirstElement = NULL;\n\t\t\tlastElement = NULL;\n\t\t};\n\t};\n\n\treturn element;\n};\n\n//Stack Storage\nclass Stack : public Storage {\n\n\tpublic:\n\t\tStack();\n\t\tvirtual Element* pop ();\n};\n\nStack::Stack() : Storage() {\n};\n\n//LIFO\nElement* Stack::pop () {\n\tElement *element = NULL;\n\tInnerElement *previousElement = NULL;\n\n\tif (lastElement != NULL) {\n\t\telement = lastElement->element;\n\n\t\tpreviousElement = lastElement->previousElement;\n\t\tdelete lastElement;\n\n\t\tif (previousElement != NULL) { \n\t\t\tlastElement = previousElement;\n\t\t\tlastElement->nextElement = NULL;\n\t\t} else {\n\t\t\tfirstElement = NULL;\n\t\t\tlastElement = NULL;\n\t\t};\n\t};\n\n\treturn element;\n};\n\n//Document element\nclass Document : public Element {\n\tprivate:\n\t\tchar* document;\n\tpublic:\n\t\tDocument (const char* inPage);\n\t\tDocument (const Document& inDocument);\n\t\t~Document ();\n\t\tvirtual void print();\n};\n\nDocument::Document (const char* inPage) : document (NULL) {\n\tif (inPage != NULL) {\n\t\tdocument = (char*)malloc (strlen (inPage)+1);\n\t\tstrcpy (document, inPage);\n\t};\n};\n\nDocument::Document (const Document& inDocument) : document (NULL) {\n\tif (inDocument.document != NULL) {\n\t\tdocument = (char*)malloc (strlen (inDocument.document)+1);\n\t\tstrcpy (document, inDocument.document);\n\t};\n};\n\nDocument::~Document () {\n\tfree (document);\n};\n\nvoid Document::print() {\n\tstd::cout << \"Document \" << document << \"\\n\";\n};\n\nint main () {\n\n \tMyClass myObject (1, 2);\n\n\tmyObject.setArg1 (3);\n\tmyObject.setArg2 (4);\n\tmyObject.print();\n\n//Dificultad extra\n\t//Queue  example\n\tQueue queue;\n\tStack stack;\n\tDocument d1 (\"1\");\n\tDocument d2 (\"2\");\n\tDocument d3 (\"3\");\n\tDocument d4 (\"4\");\n\tDocument d5 (\"5\");\n\n\tstd::cout << \"\\nEjemplo cola\\n\";\n\tqueue.push (&d1);\n\tstd::cout << \"Push \"; \n\td1.print();\n\tqueue.push (&d2);\n\tstd::cout << \"Push \";\n\td2.print();\n\tqueue.push (&d3);\n\tstd::cout << \"Push \";\n\td3.print();\n\n\tstd::cout << \"Número elementos en cola \" << queue.getElementsCount() << \"\\n\";\n\tstd::cout << \"Contenido cola: \\n\";\n\tqueue.print();\n\n\tstd::cout << \"\\n\";\n\n\t//print 1\n\tstd::cout << \"pop \";\n\tqueue.pop()->print();\n\n\tqueue.push (&d4);\n\tstd::cout << \"Push \"; \n\td4.print();\n\n\t//print 2\n\tstd::cout << \"pop \";\n\tqueue.pop()->print();\n\n\tqueue.push (&d5);\n\tstd::cout << \"Push \"; \n\td5.print();\n\n\t//print 3\n\tstd::cout << \"pop \";\n\tqueue.pop()->print();\n\n\t//print 4\n\tstd::cout << \"pop \";\n\tqueue.pop()->print();\n\n\t//print 5\n\tstd::cout << \"pop \";\n\tqueue.pop()->print();\n\n\tstd::cout << \"Número elementos en cola \" << queue.getElementsCount() << \"\\n\";\n\tqueue.print();\n\n\n\t//Stack  example\n\tstd::cout << \"\\nEjemplo pila\\n\";\n\tstack.push (&d1);\n\tstd::cout << \"Push \"; \n\td1.print();\n\tstack.push (&d2);\n\tstd::cout << \"Push \";\n\td2.print();\n\tstack.push (&d3);\n\tstd::cout << \"Push \";\n\td3.print();\n\n\tstd::cout << \"Número elementos en pila \" << stack.getElementsCount() << \"\\n\";\n\tstd::cout << \"Contenido pila: \\n\";\n\tstack.print();\n\n\tstd::cout << \"\\n\";\n\n\t//print 3\n\tstd::cout << \"pop \";\n\tstack.pop()->print();\n\n\tstack.push (&d4);\n\tstd::cout << \"Push \"; \n\td4.print();\n\n\t//print 4\n\tstd::cout << \"pop \";\n\tstack.pop()->print();\n\n\tstack.push (&d5);\n\tstd::cout << \"Push \"; \n\td5.print();\n\n\t//print 5\n\tstd::cout << \"pop \";\n\tstack.pop()->print();\n\n\t//print 2\n\tstd::cout << \"pop \";\n\tstack.pop()->print();\n\n\t//print 1\n\tstd::cout << \"pop \";\n\tstack.pop()->print();\n\n\tstd::cout << \"Número elementos en pila \" << stack.getElementsCount() << \"\\n\";\n\tstack.print();\n\n\treturn 0;\n};\n"
  },
  {
    "path": "Roadmap/08 - CLASES/c++/jhoshmc.cpp",
    "content": "/*\n! EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n*/\n/*\n? sintaxis de una clase\n* pareja(identificador o nombre de la clase )\nclass Pareja{ \n  *atributos (datos)\n  int contador=0\n  string nombre\n\n  *especificador de acceso(opcional)\n  *(public: accesibles desde cualquier lugar donde el objeto al que pertenece sea visible)\n  *(private: solo son accesibles desde dentro de la clase )\n  *(protected: miembros protegidos, solo pueden ser vistos por los demas miembros de la clase y de sus clases hijas o derivadas)\n  public: \n  * metodos (funciones)\n  string getNombre(){\n    return nombre\n  }\n  int getContador(){\n    return contador\n  }\n}\n*/\n#include<iostream>\n#include<string>\n#include<stack>\n#include<vector>\n#include<stdlib.h>\n\nusing namespace std;\n\nclass Mamifero{ \n  private:\n    string especie;\n    string nombre;\n    int edad;\n  public:\n    Mamifero(string _especie,string _nombre,int _edad){\n      especie = _especie;\n      nombre = _nombre;\n      edad = _edad;\n    }\n    void saludar(){\n      if(especie == \"humano\"){\n        cout << \"\\nhola me llamo \" << nombre << \" tengo \" << edad << \" años, mucho gusto\" << endl;\n      }else{\n\n        cout << \"\\nme llamo \" << nombre << \" saludo dando la pata\" << endl;\n      }\n    }\n};\nclass Pila{\n  private:\n    vector<int> numeros;\n    \n\n  public:\n    Pila(){\n    }\n    //* ver si la pila está vacia: true: vacia, false: tiene elementos\n    bool empty(){\n      return numeros.empty();\n    }\n    //* agregar elementos a la pila\n    void push(int elemento){\n      numeros.push_back(elemento);\n    }\n    //* devuelve el tamaño de la pila:\n    int size(){\n      return numeros.size();\n    }\n    //* eliminar el ultimo elemento de la pila y retornarlo\n    int pop(){\n      if(!numeros.empty()){\n\n        int val = numeros.back();\n        numeros.pop_back();\n        return val;\n      };\n    }\n    //* mostrar elementos de la pila\n    void print(){\n      if(!numeros.empty()){\n\n        cout << \"\\n\";\n        for (int i = (numeros.size() -1); i >=0; i--)\n        {\n          cout << numeros[i] << \" -> \";\n        }\n        cout << \" Null\\n\";\n      }else{\n        cout << \"\\n la pila esta vacia\" << endl;\n      }\n    }\n    //* mostrar el ultimo elemento de la pila sin eliminarlo\n    int end(){\n      if(!numeros.empty()){\n\n        return numeros[numeros.size() - 1];\n      }\n    }\n\n};\nclass Cola{\n  private:\n    vector<int> numeros;\n  public:\n    Cola() {};\n    //* ver si la cola esta vacia, true: vacia, false: tiene elementos\n    bool empty() {\n      return numeros.empty();\n    };\n    //* agregar elemento al final de la cola\n    void push(int elemento) {\n      numeros.push_back(elemento);\n    };\n    //* retornar el tamaño de la cola\n    int size() {\n      return numeros.size();\n    };\n    //* eliminar el primer elemento de la cola y retornarlo\n    int pop() {\n      if(!numeros.empty()){\n        int var = numeros[0];\n        numeros.erase(numeros.begin());\n        return var;\n      }\n    };\n    //* mostrar el primer elemento sin eliminarlo\n    int front() {\n      if(!numeros.empty()){\n        return numeros[0];\n      }\n    };\n    //* mostrar cola\n    void print(){\n      if(!numeros.empty()){\n        cout << \"\\n\";\n        for (size_t i = 0; i < numeros.size(); i++)\n        {\n          cout<<numeros[i] << \" <- \";\n        }\n        cout << \" Null\\n\";\n      }else{\n        cout << \"no hay elementos en la cola\" << endl;\n      }\n    }\n};\nvoid ejercicio();\nvoid extraPila();\nvoid extraCola();\nint main(){\n\n  ejercicio();\n  extraPila();\n  extraCola();\n  return 0;\n}\n\nvoid ejercicio(){\n  //*creando objetos\n  Mamifero miguel(\"humano\", \"miguel\", 20);\n  Mamifero chester(\"canina\", \"chester\", 3);\n  Mamifero laila(\"canina\", \"laila\", 2);\n  Mamifero lita(\"filina\", \"lita\", 1);\n  miguel.saludar();\n  chester.saludar();\n  laila.saludar();\n  lita.saludar();\n}\n\n/*\n ! DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n * \n*/\n\nvoid extraPila(){\n  Pila ePila;\n  cout << \"la pila esta vacia?: \" << ePila.empty() << endl;\n  cout << \"agregando elementos a la pila: \"<<endl;\n  ePila.push(1);\n  ePila.push(2);\n  ePila.push(3);\n  cout << \"tamaño de la pila: \" << ePila.size() << endl;\n  cout << \"mostrando pila: \" << endl;\n  ePila.print();\n  cout << \"mostrando ultimo elemento de la pila: \" << ePila.end() << endl;\n  cout << \"eliminado ultimo elemento de la pila: \" << ePila.pop() << endl;\n  ePila.print();\n  cout << \"eliminado ultimo elemento de la pila: \" << ePila.pop() << endl;\n  ePila.print();\n  cout << \"eliminado ultimo elemento de la pila: \" << ePila.pop() << endl;\n  ePila.print();\n  cout << \"eliminado ultimo elemento de la pila: \" << ePila.pop() << endl;\n}\nvoid extraCola(){\n  Cola eCola;\n  cout << \"la cola esta vacia?: \"<<eCola.empty() << endl;\n  cout << \"ingresando elementos a la cola: \" << endl;\n  eCola.push(1);\n  eCola.push(2);\n  eCola.push(3);\n  cout << \"tamaño de la cola: \" << eCola.size() << endl;\n  cout << \"mostrando el primer elemento en la cola: \" << eCola.front() << endl;\n  cout << \"mostrando cola: \" << endl;\n  eCola.print();\n  cout << \"sacando el primer elemento en la cola: \" << eCola.pop() << endl;\n  eCola.print();\n  cout << \"sacando el primer elemento en la cola: \" << eCola.pop() << endl;\n  eCola.print();\n  cout << \"sacando el primer elemento en la cola: \" << eCola.pop() << endl;\n  eCola.print();\n}"
  },
  {
    "path": "Roadmap/08 - CLASES/dart/bluefeatherdev.dart",
    "content": "/*\n* EJERCICIO:\n* Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n* atributos y una función que los imprima (teniendo en cuenta las posibilidades\n* de tu lenguaje).\n* Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n* utilizando su función.\n*\n* DIFICULTAD EXTRA (opcional):\n* Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n* en el ejercicio número 7 de la ruta de estudio)\n* - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n*   retornar el número de elementos e imprimir todo su contenido.\n* \n*/\n\n/// 1. [Implementación de una clase]:\nclass Person {\n  // Atributos\n  String name;\n  int age;\n\n  // Inicializador\n  Person(this.name, this.age);\n\n  // Imprimir\n  void printPerson() {\n    print('name: $name, age: $age');\n  }\n}\n\n/// 3. [Pila/Stack - DIFICULTAD EXTRA]:\nclass Stack {\n  // Atributos\n  List<dynamic> _stack = [];\n\n  // Añadir elementos\n  void push(dynamic element) {\n    _stack.add(element);\n  }\n\n  // Eliminar (LIFO - Last in/First Out)\n  void pop() {\n    if (_stack.isNotEmpty) _stack.removeLast();\n  }\n\n  // Número de elementos\n  int count() {\n    return _stack.length;\n  }\n\n  // Imprimir contenido\n  void printStack() {\n    for (var item in _stack.reversed) {\n      print(item);\n    }\n  }\n\n  // Extra: status del stack\n  void stackStatus() {\n    printStack();\n    print('Stack length: ${count()}');\n  }\n}\n\n/// 4. [Cola/Queue - DIFICULTAD EXTRA]:\nclass Queue {\n  // Atributos\n  List<dynamic> _queue = [];\n\n  // Añadir elementos\n  void push(dynamic element) {\n    _queue.add(element);\n  }\n\n  // Eliminar (FIFO - First in/First Out)\n  void pop() {\n    if (_queue.isNotEmpty) _queue.removeAt(0);\n  }\n\n  // Número de elementos\n  int count() {\n    return _queue.length;\n  }\n\n  // Imprimir contenido\n  void printQueue() {\n    for (var item in _queue) {\n      print(item);\n    }\n  }\n\n  // Extra: status del queue\n  void queueStatus() {\n    printQueue();\n    print('Queue length: ${count()}');\n  }\n} \n\nvoid main() {\n  /// 2. [Instancias de clase]:\n  var person1 = Person('Jesús', 21);  // Creación\n  var person2 = Person('Elie', 20);   // Creación\n\n  person1.printPerson();  // name: Jesús, age: 21\n  person2.printPerson();  // name: Elie, age: 20\n\n  person1.age = 23; // Modificación\n  person2.age = 22; // Modificación\n\n  person1.printPerson();  // name: Jesús, age: 23\n  person2.printPerson();  // name: Elie, age: 22\n\n  /// 3. [Pila/Stack - DIFICULTAD EXTRA]:\n  Stack myStack = Stack();  // crear stack\n  for (var i = 0; i < 5; i++) myStack.push(i);  // llenar stack\n  myStack.stackStatus();  // ver estado del stack\n\n  myStack.pop();   // eliminar elemento\n  myStack.stackStatus();  // ver estado del stack\n\n  myStack.pop();   // eliminar elemento\n  myStack.stackStatus();  // ver estado del stack\n\n  /// 4. [Cola/Queue - DIFICULTAD EXTRA]:\n  Queue myQueue = Queue();  // crear queue\n  for (var i = 97; i < 102; i++) {\n    myQueue.push(String.fromCharCode(i));  // llenar queue\n  }\n  myQueue.queueStatus();  // ver estado del queue\n\n  myQueue.pop();   // eliminar elemento\n  myQueue.queueStatus();  // ver estado del queue\n\n  myQueue.pop();   // eliminar elemento\n  myQueue.queueStatus();  // ver estado del queue\n}\n"
  },
  {
    "path": "Roadmap/08 - CLASES/dart/raulfauli.dart",
    "content": "/// #08 CLASES\n\nvoid main() {\n  final person = Person('Raul', 25);\n  person.age = 101; // Print 'Invalid age'\n  person.printPerson(); // Age: 25\n\n  // Public constant\n  print('Max age: ${Person.MAX_AGE}');\n  // Static method\n  Person.printMaxAge(); // Max age: 100\n\n  // Setter\n  person.age = 40;\n  person.printPerson(); // Age: 40\n\n  // Getter\n  final age = person.age;\n  print('Age: $age'); // Age: 40\n\n  // Name constructor\n  final anonym = Person.anonym();\n  anonym.printPerson(); // Name: Anonymous, Age: 18\n\n  // Extra\n\n  // Queue\n  final queue = Queue();\n  queue.add('Raul');\n  queue.add('Fauli');\n  queue.add('Garcia');\n  print(queue.get()); // Raul\n  print(queue.getAll()); // [Fauli, Garcia]\n\n  // Stack\n  final stack = Stack();\n  stack.add('Raul');\n  stack.add('Fauli');\n  stack.add('Garcia');\n  print(stack.get()); // Garcia\n  print(stack.getAll()); // [Raul, Fauli]\n}\n\n// Clase con constructor\nclass Person {\n  // Constantes\n  static const int MAX_AGE = 100;\n  // Atributos\n  String name;\n  // Atributo privado\n  int _age = 0;\n\n  // Constructor\n  Person(this.name, this._age);\n\n  // Constructor con nombre\n  Person.anonym()\n      : name = 'Anonymous',\n        _age = 18;\n\n  // Métodos\n  void printPerson() {\n    print('Name: $name, Age: $_age');\n  }\n\n  // Getters y Setters\n  int get age => _age;\n  set age(int value) {\n    if (value <= MAX_AGE && value >= 0) {\n      _age = value;\n    } else {\n      print('Invalid age');\n    }\n  }\n\n  // Métodos estáticos\n  static void printMaxAge() {\n    print('Max age: $MAX_AGE');\n  }\n\n  // Métodos privados\n  void _privateMethod() {\n    print('Private method');\n  }\n\n  void publicMethod() {\n    _privateMethod();\n  }\n}\n\nclass Queue {\n  final List<String> _queue = [];\n\n  void add(String value) {\n    _queue.add(value);\n  }\n\n  String? get() {\n    if (_queue.isEmpty) {\n      return null;\n    }\n    return _queue.removeAt(0);\n  }\n\n  List<String> getAll() {\n    return _queue;\n  }\n}\n\nclass Stack {\n  final List<String> _stack = [];\n\n  void add(String value) {\n    _stack.add(value);\n  }\n\n  String? get() {\n    if (_stack.isEmpty) {\n      return null;\n    }\n    return _stack.removeLast();\n  }\n\n  List<String> getAll() {\n    return _stack;\n  }\n}\n"
  },
  {
    "path": "Roadmap/08 - CLASES/delphi/fduron.dpr",
    "content": "(* Para mi pap, la razn de ser quien soy.\n *\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una funcin que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, crala, establece sus parmetros, modifcalos e imprmelos\n * utilizando su funcin.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio nmero 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para aadir, eliminar,\n *   retornar el nmero de elementos e imprimir todo su contenido.\n *)\nprogram fduron;\n\n{$APPTYPE CONSOLE}\n\n{$R *.res}\n\nuses\n  System.SysUtils;\n\ntype\n  TPersona = Class\n  private\n    FNombre: String;\n    FEdad: Integer;\n    FColorFavorito: String;\n    FHobbie: string;\n    function GetNombre: String;\n    procedure SetNombre(const Value: String);\n    function GetEdad: Integer;\n    procedure SetEdad(const Value: Integer);\n  public\n    constructor Create(ANombre: String; Edad: Integer);\n    property Nombre: String read GetNombre write SetNombre;\n    property Edad: Integer read GetEdad write SetEdad;\n    property ColorFavorito: String read FColorFavorito write FColorFavorito;\n    property Hobbie: string read FHobbie write FHobbie;\n    procedure ImprimirDatos;\n  end;\n\n  TPila = Class //LIFO\n  private\n    FListaPila: Array of String;\n    function GetCantidadDeElementos: Integer;\n  public\n    procedure Push(Valor: String);\n    function Pop: String;\n    property CantidadDeElementos: Integer read GetCantidadDeElementos;\n    procedure ImprimirContenido;\n  End;\n\n  TCola = Class //FIFO\n  private\n    FListaCola: Array of String;\n    function GetCantidadDeElementos: Integer;\n  public\n    procedure ALaCola(Valor: String);\n    function DeLaCola: String;\n    property CantidadDeElementos: Integer read GetCantidadDeElementos;\n    procedure ImprimirContenido;\n  End;\n\n{ TPersona }\n\nconstructor TPersona.Create(ANombre: String; Edad: Integer);\nbegin\n  FNombre := ANombre;\n  FEdad := Edad;\nend;\n\nfunction TPersona.GetEdad: Integer;\nbegin\n  Result := FEdad;\nend;\n\nfunction TPersona.GetNombre: String;\nbegin\n  Result := FNombre;\nend;\n\nprocedure TPersona.SetEdad(const Value: Integer);\nbegin\n  FEdad := Value;\nend;\n\nprocedure TPersona.SetNombre(const Value: String);\nbegin\n  FNombre := Value;\nend;\n\nprocedure TPersona.ImprimirDatos;\nbegin\n  WriteLn('INFORMACIN DE LA PERSONA:');\n  WriteLn('Nombre: ', Nombre);\n  WriteLn('Edad: ', Edad);\n  WriteLn('Color favorito: ', ColorFavorito);\n  WriteLn('Hobbie: ', Hobbie);\n  WriteLn;\nend;\n\n{ TPila }\n\nfunction TPila.GetCantidadDeElementos: Integer;\nbegin\n  Result := Length(FListaPila);\nend;\n\nprocedure TPila.ImprimirContenido;\nbegin\n  for var i := Length(FListaPila) - 1 downto 0 do\n    WriteLn(FListaPila[i]);\nend;\n\nfunction TPila.Pop: String;\nvar\n  Posicion: Integer;\nbegin\n  Posicion := Length(FListaPila) - 1;\n  Result := FListaPila[Posicion];\n  SetLength(FListaPila, Posicion);\nend;\n\nprocedure TPila.Push(Valor: String);\nvar\n  Posicion: Integer;\nbegin\n  Posicion := Length(FListaPila) + 1;\n  SetLength(FListaPila, Posicion);\n  FListaPila[Posicion - 1] := Valor;\nend;\n\n{ TCola }\n\nprocedure TCola.ALaCola(Valor: String);\nvar\n  Posicion: Integer;\nbegin\n  Posicion := Length(FListaCola) + 1;\n  SetLength(FListaCola, Posicion);\n  FListaCola[Posicion - 1] := Valor;\nend;\n\nfunction TCola.DeLaCola: String;\nvar\n  Posicion: Integer;\nbegin\n  Result := FListaCola[0];\n  //Recorrer los elementos hacia atrs\n  for var i := 0 to Length(FListaCola) - 2 do\n    FListaCola[i] := FListaCola[i + 1];\n  SetLength(FListaCola, Length(FListaCola) - 1);\nend;\n\nfunction TCola.GetCantidadDeElementos: Integer;\nbegin\n  Result := Length(FListaCola);\nend;\n\nprocedure TCola.ImprimirContenido;\nbegin\n  for var Elemento in FListaCola do\n    WriteLn(Elemento);\nend;\n\nvar\n  UnaPersona: TPersona;\n  UnaPila: TPila;\n  UnaCola: TCola;\nbegin\n  UnaPersona := TPersona.Create('Juanita', 25);\n  UnaPersona.Edad := 26;\n  UnaPersona.ColorFavorito := 'Rojo';\n  UnaPersona.Hobbie := 'Bailar';\n  UnaPersona.ImprimirDatos;\n  UnaPersona.free;\n  WriteLn;\n\n  WriteLn('**********************************');\n  WriteLn('*        DIFICULTAD EXTRA        *');\n  WriteLn('**********************************');\n  UnaPila := TPila.Create;\n  WriteLn('-= PILAS =-');\n  UnaPila.Push('Valor en la pila uno');\n  UnaPila.Push('Valor en la pila dos');\n  UnaPila.Push('Valor en la pila tres');\n  UnaPila.Push('Valor en la pila CUATRO');\n  WriteLn('Elementos en la pila: ', UnaPila.CantidadDeElementos);\n  WriteLn('Contenido de la pila:');\n  UnaPila.ImprimirContenido;\n  WriteLn;\n  WriteLn('Elemento eliminado: ', UnaPila.Pop);\n  WriteLn('Nuevo contenido de la pila:');\n  UnaPila.ImprimirContenido;\n  WriteLn;\n  UnaPila.Free;\n\n  UnaCola := TCola.Create;\n  WriteLn('-= COLAS =-');\n  UnaCola.ALaCola('Valor en la cola uno');\n  UnaCola.ALaCola('Valor en la cola dos');\n  UnaCola.ALaCola('Valor en la cola tres');\n  UnaCola.ALaCola('Valor en la cola cuatro');\n  UnaCola.ALaCola('Valor en la cola CINCO');\n  WriteLn('Elementos en la cola: ', UnaCola.CantidadDeElementos);\n  WriteLn('Contenido de la cola:');\n  UnaCola.ImprimirContenido;\n  WriteLn;\n  WriteLn('Elemento eliminado: ', UnaCola.DeLaCola);\n  WriteLn('Nuevo contenido de la pila:');\n  UnaCola.ImprimirContenido;\n  UnaCola.Free;\n\n  ReadLn;\n\nend.\n"
  },
  {
    "path": "Roadmap/08 - CLASES/ejercicio.md",
    "content": "# #08 CLASES\n> #### Dificultad: Fácil | Publicación: 19/02/24 | Corrección: 26/02/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n * \n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/08 - CLASES/fortran/LeandroCFD.f90",
    "content": "!Fortran propiamente no tiene clases, pero se pueden simular con variables de tipo derivado y modulos\n\nmodule Modulo_Clase !Se define un modulo que contiene la definición de las clases Alumno, Pila y Cola\n    implicit none\n\n    type :: Alumno !Se define el tipo derivado Alumno\n        real :: nota !Atributos de la clase\n        integer :: edad\n        character(len=20) :: nombre\n        contains\n            procedure :: MostrarDatos !Método de la clase\n    end type Alumno\n\n    type :: Pila\n        integer :: tope\n        integer, dimension(100) :: elementos\n        contains\n            procedure :: Apilar\n            procedure :: Desapilar\n            procedure, nopass :: MostrarElementos\n            procedure, nopass :: NumeroElementos\n    end type Pila\n\n    type :: Cola\n        integer :: frente\n        integer :: final\n        integer, dimension(100) :: elementos\n        contains\n            procedure :: Encolar\n            procedure :: Desencolar\n            procedure, nopass :: MostrarElementos\n            procedure, nopass :: NumeroElementos\n    end type Cola\n\ncontains\n    subroutine MostrarDatos(this) !Implementación del método MostrarDatos\n        class(Alumno), intent(in) :: this !Se pasa la instancia de la clase como argumento\n        print *, 'Nombre: ', this%nombre \n        print *, 'Edad: ', this%edad\n        print *, 'Nota: ', this%nota\n    end subroutine MostrarDatos\n\n    subroutine Apilar(this, elemento) !Implementación del método Apilar\n        class(Pila), intent(inout) :: this\n        integer, intent(in) :: elemento\n        this%tope = this%tope + 1 !Se incrementa el tope de la pila\n        this%elementos(this%tope) = elemento !Se añade el elemento a la pila\n    end subroutine Apilar\n\n    subroutine Desapilar(this) !Implementación del método Desapilar\n        class(Pila), intent(inout) :: this\n        if ( this%tope <0 ) then !Se verifica que haya elementos en la pila\n            print *, \"No hay elementos para desapilar\"\n            return            \n        end if\n        this%elementos(this%tope)=0 !Se elimina el elemento\n        this%tope = this%tope - 1 !Se decrementa el tope\n    end subroutine Desapilar\n\n    subroutine Encolar(this, elemento) !Implementación del método Encolar\n        class(Cola), intent(inout) :: this\n        integer, intent(in) :: elemento\n        this%final = this%final + 1 !Se incrementa el final de la cola\n        this%elementos(this%final) = elemento !Se añade el elemento a la cola\n    end subroutine Encolar\n\n    subroutine Desencolar(this) !Implementación del método Desencolar\n        class(Cola), intent(inout) :: this\n        if ( this%final-this%frente <0 ) then !Se verifica que haya elementos en la cola\n            print *, \"No hay elementos para desencolar\"\n            return            \n        end if\n        this%elementos(this%frente)=0 !Se elimina el elemento\n        this%frente = this%frente + 1 !Se incrementa el frente\n    end subroutine Desencolar\n\n    subroutine MostrarElementos(this) !Implementación del método MostrarElementos\n        class(*), intent(in) :: this\n        integer :: i\n        select type(this) !Se selecciona el tipo de la instancia\n            type is (Pila) !Si es de tipo Pila\n                print *,\"Lista de elementos (Pila):\"\n                do i = 0, this%tope-1\n                    print *, this%elementos(this%tope-i)\n                end do\n            type is (Cola) !Si es de tipo Cola\n                print*,\"Lista de elementos (Cola):\"\n                do i = this%frente, this%final\n                    print *, this%elementos(i)\n                end do\n        end select\n    end subroutine MostrarElementos\n\n    subroutine NumeroElementos(this) !Implementación del método NumeroElementos\n        class(*), intent(in) :: this\n        select type(this)\n            type is (Pila)\n                print *,\"Numero de elementos (Pila):\", this%tope\n            type is (Cola)\n                print*,\"Numero de elementos (Cola):\", this%final-this%frente+1\n        end select\n    end subroutine NumeroElementos\n\nend module Modulo_Clase \n\nprogram CLASES\n    use Modulo_Clase !Se importa el modulo que contiene la definición de la clase\n\n    implicit none\n    \n    type(Alumno) :: Alumno1, Alumno2 !Se definen dos instancias \"Variables\" de la clase Alumno\n    type(Pila) :: Mipila !Se define una instancia de la clase Pila\n    type(Cola) :: Micola !Se define una instancia de la clase Cola\n\n    Alumno1%nota = 10.0 !Inicialización de los datos de Alumno1\n    Alumno1%edad = 20\n    Alumno1%nombre = 'Juan'\n\n    Alumno2%nota = 8.0 !Inicialización de los datos de Alumno2\n    Alumno2%edad = 21\n    Alumno2%nombre = 'Pedro'\n\n    call Alumno1%MostrarDatos() ! Llamada a los métodos MostrarDatos\n    call Alumno2%MostrarDatos()\n\n    Alumno1%nombre='Carlos'\n    Alumno1%edad=22\n    Alumno1%nota=6.5\n    \n    call Alumno1%MostrarDatos()\n\n    !DIFICULTAD EXTRA\n    Mipila%tope = 0\n    call Mipila%Apilar(5) !Se apilan elementos\n    call Mipila%Apilar(2)\n    call Mipila%Apilar(10)\n    call Mipila%Apilar(22)\n    call Mipila%Apilar(50)\n\n    call Mipila%MostrarElementos(Mipila) !Se muestran los elementos de la pila\n    call Mipila%NumeroElementos(Mipila) !Se muestra el número de elementos de la pila\n    call Mipila%Desapilar() !Se desapila un elemento\n    call Mipila%MostrarElementos(Mipila)\n    call Mipila%NumeroElementos(Mipila)\n\n    Micola%frente = 1\n    Micola%final = 0    \n\n    call Micola%Encolar(1) !Se encolan elementos\n    call Micola%Encolar(3)\n    call Micola%Encolar(10)\n    call Micola%Encolar(50)\n    call Micola%Encolar(98)\n\n    call Micola%MostrarElementos(Micola) !Se muestran los elementos de la cola\n    call Micola%NumeroElementos(Micola) !Se muestra el número de elementos de la cola\n    call Micola%Desencolar() !Se desencola un elemento\n    call Micola%Desencolar()\n    call Micola%Desencolar()\n    call Micola%Desencolar()\n    call Micola%MostrarElementos(Micola) !Se muestran los elementos de la cola\n    call Micola%NumeroElementos(Micola) !Se muestra el número de elementos de la cola\n\nend program CLASES"
  },
  {
    "path": "Roadmap/08 - CLASES/go/AmadorQuispe.go",
    "content": "package main\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n)\n\n// En GO las clases son diferentes a los demás lenguajes, se usan structs\ntype Student struct {\n\tid   int\n\tname string\n}\n\n// Constructor\nfunc NewStudent() Student {\n\treturn Student{}\n}\n\n// También es posible simular los métodos setter y getter\nfunc (s *Student) SetId(id int) {\n\ts.id = id\n}\nfunc (s *Student) SetName(name string) {\n\ts.name = name\n}\n\nfunc (s *Student) GetId() int {\n\treturn s.id\n}\n\nfunc (s *Student) GetName() string {\n\treturn s.name\n}\n\nfunc (s *Student) ToString() string {\n\treturn fmt.Sprintf(\"{Id: %d, Name: %s}\", s.id, s.name)\n}\n\n// Pila LIFO último en entrar, primero en salir\ntype Stack[T any] struct {\n\telements []T\n}\n\nfunc NewStack[T any]() Stack[T] {\n\treturn Stack[T]{}\n}\n\nfunc (s *Stack[T]) Empty() bool {\n\treturn len(s.elements) == 0\n}\n\nfunc (s *Stack[T]) Push(item T) T {\n\ts.elements = append(s.elements, item)\n\treturn item\n}\n\nfunc (s *Stack[T]) Pop() (T, error) {\n\tvar zero T\n\tif s.Empty() {\n\t\treturn zero, errors.New(\"stack is empty\")\n\t}\n\titem := s.elements[len(s.elements)-1]\n\ts.elements = s.elements[:len(s.elements)-1]\n\treturn item, nil\n}\n\nfunc (s *Stack[T]) Peek() (T, error) {\n\tvar zero T\n\tif s.Empty() {\n\t\treturn zero, errors.New(\"stack is empty\")\n\t}\n\treturn s.elements[len(s.elements)-1], nil\n}\n\nfunc (s *Stack[T]) Size() int {\n\treturn len(s.elements)\n}\n\nfunc (s *Stack[T]) Print() {\n\tfmt.Println(s.elements)\n}\n\n// Colas FIFO primero en entrar, primero en salir\ntype Queue[T any] struct {\n\telements []T\n}\n\nfunc (q *Queue[T]) Empty() bool {\n\treturn len(q.elements) == 0\n}\nfunc NewQueue[T any]() Queue[T] {\n\treturn Queue[T]{}\n}\n\nfunc (q *Queue[T]) Add(item T) T {\n\tq.elements = append(q.elements, item)\n\treturn item\n}\n\nfunc (q *Queue[T]) Poll() (T, error) {\n\tvar item T\n\tif q.Empty() {\n\t\treturn item, errors.New(\"queue is empty\")\n\t}\n\titem = q.elements[0]\n\tq.elements = q.elements[1:]\n\treturn item, nil\n}\n\nfunc (q *Queue[T]) Size() int {\n\treturn len(q.elements)\n}\n\nfunc (q *Queue[T]) Print() {\n\tfmt.Println(q.elements)\n}\n\nfunc main() {\n\t//CLASES\n\tstudent := Student{}\n\tstudent.SetId(100)\n\tstudent.SetName(\"Amador\")\n\tfmt.Println(student.ToString())\n\t//PILAS\n\tstack := NewStack[int]()\n\tstack.Push(1)\n\tstack.Push(2)\n\tstack.Push(3)\n\tstack.Push(4)\n\tstack.Push(5)\n\tfmt.Println(stack.Size())\n\tstack.Print()\n\tstack.Pop()\n\tstack.Pop()\n\tfmt.Println(stack.Size())\n\tstack.Print()\n\n\t//COLAS\n\tqueue := NewQueue[string]()\n\tqueue.Add(\"Amador\")\n\tqueue.Add(\"Alex\")\n\tqueue.Add(\"Pedro\")\n\tfmt.Println(queue.Size())\n\tqueue.Print()\n\tqueue.Poll()\n\tfmt.Println(queue.Size())\n\tqueue.Print()\n\n}\n"
  },
  {
    "path": "Roadmap/08 - CLASES/go/FreyFonseca117.go",
    "content": "// # #08 CLASES\n// > #### Dificultad: Fácil | Publicación: 19/02/24 | Corrección: 26/02/24\n\n// ## Ejercicio\n\n// ```\n// /*\n//  * EJERCICIO:\n//  * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n//  * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n//  * de tu lenguaje).\n//  * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n//  * utilizando su función.\n//  *\n//  * DIFICULTAD EXTRA (opcional):\n//  * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n//  * en el ejercicio número 7 de la ruta de estudio)\n//  * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n//  *   retornar el número de elementos e imprimir todo su contenido.\n//  * \n//  */\n// ```\n// #### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\n// Sigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n// > Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n\npackage main\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n)\n\n// En GO las clases son diferentes a los demás lenguajes, se usan structs\ntype Student struct {\n\tid   int\n\tname string\n}\n\n// Constructor\nfunc NewStudent() Student {\n\treturn Student{}\n}\n\n// También es posible simular los métodos setter y getter\nfunc (s *Student) SetId(id int) {\n\ts.id = id\n}\nfunc (s *Student) SetName(name string) {\n\ts.name = name\n}\n\nfunc (s *Student) GetId() int {\n\treturn s.id\n}\n\nfunc (s *Student) GetName() string {\n\treturn s.name\n}\n\nfunc (s *Student) ToString() string {\n\treturn fmt.Sprintf(\"{Id: %d, Name: %s}\", s.id, s.name)\n}\n\n// Pila LIFO último en entrar, primero en salir\ntype Stack[T any] struct {\n\telements []T\n}\n\nfunc NewStack[T any]() Stack[T] {\n\treturn Stack[T]{}\n}\n\nfunc (s *Stack[T]) Empty() bool {\n\treturn len(s.elements) == 0\n}\n\nfunc (s *Stack[T]) Push(item T) T {\n\ts.elements = append(s.elements, item)\n\treturn item\n}\n\nfunc (s *Stack[T]) Pop() (T, error) {\n\tvar zero T\n\tif s.Empty() {\n\t\treturn zero, errors.New(\"stack is empty\")\n\t}\n\titem := s.elements[len(s.elements)-1]\n\ts.elements = s.elements[:len(s.elements)-1]\n\treturn item, nil\n}\n\nfunc (s *Stack[T]) Peek() (T, error) {\n\tvar zero T\n\tif s.Empty() {\n\t\treturn zero, errors.New(\"stack is empty\")\n\t}\n\treturn s.elements[len(s.elements)-1], nil\n}\n\nfunc (s *Stack[T]) Size() int {\n\treturn len(s.elements)\n}\n\nfunc (s *Stack[T]) Print() {\n\tfmt.Println(s.elements)\n}\n\n// Colas FIFO primero en entrar, primero en salir\ntype Queue[T any] struct {\n\telements []T\n}\n\nfunc (q *Queue[T]) Empty() bool {\n\treturn len(q.elements) == 0\n}\nfunc NewQueue[T any]() Queue[T] {\n\treturn Queue[T]{}\n}\n\nfunc (q *Queue[T]) Add(item T) T {\n\tq.elements = append(q.elements, item)\n\treturn item\n}\n\nfunc (q *Queue[T]) Poll() (T, error) {\n\tvar item T\n\tif q.Empty() {\n\t\treturn item, errors.New(\"queue is empty\")\n\t}\n\titem = q.elements[0]\n\tq.elements = q.elements[1:]\n\treturn item, nil\n}\n\nfunc (q *Queue[T]) Size() int {\n\treturn len(q.elements)\n}\n\nfunc (q *Queue[T]) Print() {\n\tfmt.Println(q.elements)\n}\n\nfunc main() {\n\t//CLASES\n\tstudent := Student{}\n\tstudent.SetId(100)\n\tstudent.SetName(\"Amador\")\n\tfmt.Println(student.ToString())\n\t//PILAS\n\tstack := NewStack[int]()\n\tstack.Push(1)\n\tstack.Push(2)\n\tstack.Push(3)\n\tstack.Push(4)\n\tstack.Push(5)\n\tfmt.Println(stack.Size())\n\tstack.Print()\n\tstack.Pop()\n\tstack.Pop()\n\tfmt.Println(stack.Size())\n\tstack.Print()\n\n\t//COLAS\n\tqueue := NewQueue[string]()\n\tqueue.Add(\"Amador\")\n\tqueue.Add(\"Alex\")\n\tqueue.Add(\"Pedro\")\n\tfmt.Println(queue.Size())\n\tqueue.Print()\n\tqueue.Poll()\n\tfmt.Println(queue.Size())\n\tqueue.Print()\n\n}\n"
  },
  {
    "path": "Roadmap/08 - CLASES/go/MiguelP-Dev.go",
    "content": "package main\n\nimport \"fmt\"\n\n// Golang no posee clases pero si posee estructuras, que son similares.\n// programmer es una estructura que contiene los atributos de un programador.\ntype programmer struct {\n\tname      string\n\tage       uint8\n\tlanguages []string\n}\n\nfunc newProgrammer(name string, age uint8, languages []string) *programmer {\n\treturn &programmer{\n\t\tname:      name,\n\t\tage:       age,\n\t\tlanguages: languages,\n\t}\n}\n\nfunc printLanguages(p programmer) {\n\ttext := \"Languages used: \"\n\tfor _, lang := range p.languages {\n\t\ttext += lang + \", \"\n\t}\n\tfmt.Println(text[:len(text)-2])\n}\n\nfunc (p *programmer) updateAge(newAge uint8) {\n\tp.age = newAge\n}\n\nvar one = programmer{}\n\n// Extra : Stack and Queue\ntype stack struct {\n\titems []int\n}\n\nfunc (s *stack) push(item int) {\n\ts.items = append(s.items, item)\n}\n\nfunc (s *stack) pop() int {\n\tif len(s.items) == 0 {\n\t\tfmt.Println(\"Stack is empty\")\n\t\treturn -1\n\t}\n\n\titem := s.items[len(s.items)-1]\n\ts.items = s.items[:len(s.items)-1]\n\treturn item\n}\n\ntype queue struct {\n\titems []int\n}\n\nfunc (s *queue) push(item int) {\n\ts.items = append(s.items, item)\n}\n\nfunc (s *queue) pop() int {\n\tif len(s.items) == 0 {\n\t\tfmt.Println(\"Queue is empty\")\n\t\treturn -1\n\t}\n\n\titem := s.items[0]\n\ts.items = s.items[1:]\n\treturn item\n}\n\nfunc main() {\n\tone.languages = append(one.languages, \"golang\")\n\tone.name = \"miguel\"\n\tone.age = 31\n\tfmt.Println(\"First: \", one)\n\tone.age = 32\n\tfmt.Println(\"Updated: \", one)\n\tprintLanguages(one)\n\tfmt.Println(\"Programmer: \", newProgrammer(\"Miguel\", 31, []string{\"golang\"}))\n\tone.updateAge(33)\n\tfmt.Println(\"Updating age with method: \", one.age)\n\n\t// Example about stack and queue using structures instead of classes.\n\t// stack\n\tmyStack := new(stack)\n\tmyStack.push(1)\n\tmyStack.push(2)\n\tmyStack.push(3)\n\tfmt.Println(\"Stack: \", myStack)\n\tmyStack.pop()\n\tmyStack.pop()\n\tmyStack.pop()\n\tmyStack.pop()\n\tfmt.Println(\"Stack: \", myStack)\n\n\t// queue\n\tmyQueue := new(queue)\n\tmyQueue.push(1)\n\tmyQueue.push(2)\n\tmyQueue.push(3)\n\tfmt.Println(\"Queue: \", myQueue)\n\tmyQueue.pop()\n\tmyQueue.pop()\n\tmyQueue.pop()\n\tmyQueue.pop()\n\tfmt.Println(\"Queue: \", myQueue)\n\n}\n"
  },
  {
    "path": "Roadmap/08 - CLASES/go/N0HagoNada.go",
    "content": "package main\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n)\n\ntype Stack struct {\n\telements []string\n}\n\nfunc (s *Stack) Push(elem string) {\n\ts.elements = append(s.elements, elem)\n}\n\nfunc (s *Stack) Pop() (string, bool) {\n\tif len(s.elements) == 0 {\n\t\treturn \"\", false\n\t}\n\tlastIndex := len(s.elements) - 1\n\telem := s.elements[lastIndex]\n\ts.elements = s.elements[:lastIndex]\n\treturn elem, true\n}\n\ntype WebBrowser struct {\n\thistory Stack\n\tforward Stack\n\tcurrent string\n}\n\nfunc (wb *WebBrowser) Visit(page string) {\n\tif wb.current != \"\" {\n\t\twb.history.Push(wb.current)\n\t}\n\twb.current = page    // Set the current page\n\twb.forward = Stack{} // Clear forward stack\n}\n\nfunc (wb *WebBrowser) Back() (string, bool) {\n\tif page, ok := wb.history.Pop(); ok {\n\t\twb.forward.Push(wb.current)\n\t\twb.current = page\n\t\treturn page, true\n\t}\n\treturn \"\", false\n}\n\nfunc (wb *WebBrowser) Forward() (string, bool) {\n\tif page, ok := wb.forward.Pop(); ok {\n\t\twb.history.Push(wb.current)\n\t\twb.current = page\n\t\treturn page, true\n\t}\n\treturn \"\", false\n}\n\nfunc (wb *WebBrowser) CurrentPage() string {\n\treturn wb.current\n}\n\nfunc main() {\n\twb := WebBrowser{}\n\tscanner := bufio.NewScanner(os.Stdin)\n\n\tfmt.Println(\"Web Browser Simulator\")\n\tfor {\n\t\tfmt.Print(\"Enter a URL, 'atras', 'adelante', or 'exit' to navigate: \")\n\t\tscanner.Scan()\n\t\tinput := strings.TrimSpace(scanner.Text())\n\n\t\tswitch input {\n\t\tcase \"atras\":\n\t\t\tif page, ok := wb.Back(); ok {\n\t\t\t\tfmt.Println(\"Moved back to:\", page)\n\t\t\t} else {\n\t\t\t\tfmt.Println(\"No more history.\")\n\t\t\t}\n\t\tcase \"adelante\":\n\t\t\tif page, ok := wb.Forward(); ok {\n\t\t\t\tfmt.Println(\"Moved forward to:\", page)\n\t\t\t} else {\n\t\t\t\tfmt.Println(\"No pages to move forward to.\")\n\t\t\t}\n\t\tcase \"exit\":\n\t\t\tfmt.Println(\"Exiting Web Browser Simulator.\")\n\t\t\treturn\n\t\tdefault:\n\t\t\twb.Visit(input)\n\t\t\tfmt.Println(\"Visited:\", wb.CurrentPage())\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Roadmap/08 - CLASES/go/hozlucas28.go",
    "content": "package main\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n)\n\n/* -------------------------------------------------------------------------- */\n/*                                PHONE (CLASS)                               */\n/* -------------------------------------------------------------------------- */\n\n// Attributes\ntype Phone struct {\n\t_brand string\n\t_name  string\n\t_price float32\n}\n\n// Constructor\nfunc NewPhone(brand string, name string, price float32) *Phone {\n\tvar phone Phone = Phone{\n\t\t_brand: brand,\n\t\t_name:  name,\n\t\t_price: price,\n\t}\n\n\treturn &phone\n}\n\n// Setters\nfunc (phone *Phone) setBrand(brand string) *Phone {\n\tphone._brand = brand\n\treturn phone\n}\n\nfunc (phone *Phone) setName(name string) *Phone {\n\tphone._name = name\n\treturn phone\n}\n\nfunc (phone *Phone) setPrice(price float32) *Phone {\n\tphone._price = price\n\treturn phone\n}\n\n// Getters\nfunc (phone *Phone) getBrand() string {\n\treturn phone._brand\n}\n\nfunc (phone *Phone) getName() string {\n\treturn phone._name\n}\n\nfunc (phone *Phone) getPrice() float32 {\n\treturn phone._price\n}\n\n// Methods\nfunc (phone *Phone) printAttributes() {\n\tfmt.Printf(\"\\nBrand --> %s\\n\", phone._brand)\n\tfmt.Printf(\"Name --> %s\\n\", phone._name)\n\tfmt.Printf(\"Price --> $%0.2f\\n\", phone._price)\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                STACK (CLASS)                               */\n/* -------------------------------------------------------------------------- */\n\ntype Stack[T any] struct {\n\t_lastElement T\n\t_length      int\n\t_stack       []T\n}\n\nfunc newStack[T any](stack []T) *Stack[T] {\n\tvar nStack Stack[T] = Stack[T]{\n\t\t_length:      len(stack),\n\t\t_lastElement: stack[len(stack)-1],\n\t\t_stack:       stack,\n\t}\n\n\treturn &nStack\n}\n\nfunc (stack *Stack[T]) getLastElement() (T, error) {\n\tvar lastElementError error\n\tif stack.getLength() <= 0 {\n\t\tlastElementError = errors.New(\"Stack empty\")\n\t}\n\n\treturn stack._lastElement, lastElementError\n}\n\nfunc (stack *Stack[T]) getLength() int {\n\treturn stack._length\n}\n\nfunc (stack *Stack[T]) getStack() []T {\n\treturn stack._stack\n}\n\nfunc (stack *Stack[T]) appendElement(element T) *Stack[T] {\n\tstack._stack = append(stack._stack, element)\n\tstack._lastElement = element\n\tstack._length = len(stack._stack)\n\treturn stack\n}\n\nfunc (stack *Stack[T]) deleteLastElement() *Stack[T] {\n\tvar stackLength int = stack.getLength()\n\n\tif stackLength == 1 {\n\t\tstack._length = stackLength - 1\n\t\tstack._stack = []T{}\n\t} else if stackLength > 1 {\n\t\tstack._lastElement = stack._stack[stackLength-2]\n\t\tstack._length = stackLength - 1\n\t\tstack._stack = stack._stack[:stackLength-1]\n\t}\n\n\treturn stack\n}\n\nfunc (stack *Stack[T]) printAttributes() *Stack[T] {\n\tfmt.Printf(\"\\nLast element --> %v\\n\", stack._lastElement)\n\tfmt.Printf(\"Length --> %d\\n\", stack._length)\n\tfmt.Printf(\"Stack --> %v\\n\", stack._stack)\n\treturn stack\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                QUEUE (CLASS)                               */\n/* -------------------------------------------------------------------------- */\n\ntype Queue[T any] struct {\n\t_firstElement T\n\t_length       int\n\t_queue        []T\n}\n\nfunc newQueue[T any](queue []T) *Queue[T] {\n\tvar nQueue Queue[T] = Queue[T]{\n\t\t_firstElement: queue[0],\n\t\t_length:       len(queue),\n\t\t_queue:        queue,\n\t}\n\n\treturn &nQueue\n}\n\nfunc (queue *Queue[T]) getFirstElement() (T, error) {\n\tvar firstElementError error\n\tif queue.getLength() <= 0 {\n\t\tfirstElementError = errors.New(\"Queue empty\")\n\t}\n\n\treturn queue._firstElement, firstElementError\n}\n\nfunc (queue *Queue[T]) getLength() int {\n\treturn queue._length\n}\n\nfunc (queue *Queue[T]) getQueue() []T {\n\treturn queue._queue\n}\n\nfunc (queue *Queue[T]) appendElement(element T) *Queue[T] {\n\tqueue._queue = append(queue._queue, element)\n\tqueue._length = len(queue._queue)\n\treturn queue\n}\n\nfunc (queue *Queue[T]) deleteFirstElement() *Queue[T] {\n\tvar queueLength int = queue.getLength()\n\tif queueLength == 1 {\n\t\tqueue._length = 0\n\t\tqueue._queue = []T{}\n\t} else if queueLength > 1 {\n\t\tqueue._queue = queue._queue[1:]\n\t\tqueue._firstElement = queue._queue[0]\n\t\tqueue._length = queue._length - 1\n\t}\n\n\treturn queue\n}\n\nfunc (queue *Queue[T]) printAttributes() *Queue[T] {\n\tfmt.Printf(\"\\nLength --> %d\\n\", queue._length)\n\tfmt.Printf(\"First element --> %v\\n\", queue._firstElement)\n\tfmt.Printf(\"Queue --> %v\\n\", queue._queue)\n\treturn queue\n\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\nfunc main() {\n\t/*\n\t   Classes...\n\t*/\n\n\tfmt.Println(\"Classes in TypeScript...\")\n\n\tvar phone *Phone = NewPhone(\"Samsung\", \"A5 2015\", 150000)\n\n\tfmt.Println(\"\\nPhone attributes...\")\n\tphone.printAttributes()\n\n\tphone.setBrand(\"Apple\").setName(\"iPhone 15 Pro Max\").setPrice(300000)\n\n\tfmt.Println(\"\\nPhone attributes...\")\n\tphone.printAttributes()\n\n\tfmt.Println(\"\\n# ---------------------------------------------------------------------------------- #\")\n\n\t/*\n\t   Additional challenge...\n\t*/\n\n\tfmt.Println(\"\\nAdditional challenge...\")\n\n\t// Stack exercise...\n\tvar stack *Stack[string] = newStack[string]([]string{\"Lucas\", \"Hoz\", \"Buenos Aires\"})\n\n\tfmt.Println(\"\\nStack attributes...\")\n\tstack.printAttributes()\n\n\tstack.appendElement(\"Argentina\")\n\n\tfmt.Println(\"\\nStack attributes...\")\n\tstack.printAttributes()\n\n\tstack.deleteLastElement().deleteLastElement()\n\n\tfmt.Println(\"\\nStack attributes...\")\n\tstack.printAttributes()\n\n\tstack.deleteLastElement().deleteLastElement()\n\n\tfmt.Println(\"\\nStack attributes...\")\n\tstack.printAttributes()\n\n\t// Queue exercise...\n\tvar queue *Queue[string] = newQueue[string]([]string{\"América\", \"América Latina\", \"América del Sur\"})\n\n\tfmt.Println(\"\\nQueue attributes...\")\n\tqueue.printAttributes()\n\n\tqueue.appendElement(\"Argentina\")\n\n\tfmt.Println(\"\\nQueue attributes...\")\n\tqueue.printAttributes()\n\n\tqueue.deleteFirstElement().deleteFirstElement()\n\tfmt.Println(\"\\nQueue attributes...\")\n\tqueue.printAttributes()\n\n\tqueue.deleteFirstElement().deleteFirstElement().deleteFirstElement()\n\n\tfmt.Println(\"\\nQueue attributes...\")\n\tqueue.printAttributes()\n\n}\n"
  },
  {
    "path": "Roadmap/08 - CLASES/go/kodenook.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc main() {\n\tvar u User = User{\"name\", \"last_name\"}\n\tu.SetFirstName(\"name2\")\n\tu.FirstName = \"name3\"\n\tu.SetLastName(\"last_name2\")\n\tfmt.Println(u)\n\tfmt.Println(u.LastName)\n\tfmt.Println(u.GetFirstName())\n}\n\ntype User struct {\n\tFirstName string\n\tLastName  string\n}\n\nfunc (u *User) SetFirstName(firstName string) {\n\tu.FirstName = firstName\n}\n\nfunc (u *User) SetLastName(lastName string) {\n\tu.LastName = lastName\n}\n\nfunc (u *User) GetFirstName() string {\n\treturn u.FirstName\n}\n"
  },
  {
    "path": "Roadmap/08 - CLASES/go/miguelex.go",
    "content": "package main\n\nimport \"fmt\"\n\n// Las clases en Go son un poco diferentes a otros lenguajes, no funcionado de forma \"tradicional\"\ntype Vehiculo struct {\n\tnombre    string\n\tnumRuedas int\n}\n\n// Constructor de Vehiculo\nfunc NuevoVehiculo(nombre string, numRuedas int) *Vehiculo {\n\treturn &Vehiculo{nombre: nombre, numRuedas: numRuedas}\n}\n\n// Método ToString para Vehiculo\nfunc (v *Vehiculo) ToString() string {\n\treturn fmt.Sprintf(\"Nombre: %s, Número de Ruedas: %d\", v.nombre, v.numRuedas)\n}\n\n// Definición de la estructura Pila\ntype Pila struct {\n\telementos []interface{}\n}\n\n// Método para agregar un elemento a la pila\nfunc (p *Pila) Push(elemento interface{}) {\n\tp.elementos = append(p.elementos, elemento)\n}\n\n// Método para eliminar y devolver el último elemento agregado a la pila\nfunc (p *Pila) Pop() interface{} {\n\tif len(p.elementos) == 0 {\n\t\treturn nil // Devolver nil si la pila está vacía\n\t}\n\telemento := p.elementos[len(p.elementos)-1]\n\tp.elementos = p.elementos[:len(p.elementos)-1]\n\treturn elemento\n}\n\n// Método para obtener el tamaño de la pila\nfunc (p *Pila) Size() int {\n\treturn len(p.elementos)\n}\n\n// Método para imprimir los elementos de la pila\nfunc (p *Pila) ToString() string {\n\tstr := \"[\"\n\tfor i, elemento := range p.elementos {\n\t\tstr += fmt.Sprintf(\"%v\", elemento)\n\t\tif i < len(p.elementos)-1 {\n\t\t\tstr += \", \"\n\t\t}\n\t}\n\tstr += \"]\"\n\treturn str\n}\n\n// Definición de la estructura Cola\ntype Cola struct {\n\telementos []interface{}\n}\n\n// Método para agregar un elemento a la cola\nfunc (c *Cola) Enqueue(elemento interface{}) {\n\tc.elementos = append(c.elementos, elemento)\n}\n\n// Método para eliminar y devolver el primer elemento agregado a la cola\nfunc (c *Cola) Dequeue() interface{} {\n\tif len(c.elementos) == 0 {\n\t\treturn nil // Devolver nil si la cola está vacía\n\t}\n\telemento := c.elementos[0]\n\tc.elementos = c.elementos[1:]\n\treturn elemento\n}\n\n// Método para obtener el tamaño de la cola\n\nfunc (c *Cola) Size() int {\n\treturn len(c.elementos)\n}\n\n// Método para imprimir los elementos de la cola\nfunc (c *Cola) ToString() string {\n\tstr := \"[\"\n\tfor i, elemento := range c.elementos {\n\t\tstr += fmt.Sprintf(\"%v\", elemento)\n\t\tif i < len(c.elementos)-1 {\n\t\t\tstr += \", \"\n\t\t}\n\t}\n\tstr += \"]\"\n\treturn str\n}\n\nfunc main() {\n\t// Crear un nuevo Vehiculo\n\tcoche := NuevoVehiculo(\"Coche\", 4)\n\tbicicleta := NuevoVehiculo(\"Bicicleta\", 2)\n\n\t// Imprimir los detalles del Vehiculo usando el método ToString\n\tfmt.Println(coche.ToString())\n\tfmt.Println(bicicleta.ToString())\n\n\t// Crear una nueva pila\n\tpila := Pila{}\n\n\t// Agregar elementos a la pila\n\tpila.Push(1)\n\tpila.Push(2)\n\tpila.Push(3)\n\n\t// Imprimir el tamaño de la pila\n\tfmt.Println(\"Tamaño de la pila:\", pila.Size())\n\n\t// Imprimir los elementos de la pila\n\tfmt.Println(\"Elementos de la pila:\", pila.ToString())\n\n\t// Eliminar un elemento de la pila\n\telementoEliminado := pila.Pop()\n\tfmt.Println(\"Elemento eliminado:\", elementoEliminado)\n\n\t// Imprimir el tamaño de la pila después de eliminar un elemento\n\tfmt.Println(\"Tamaño de la pila:\", pila.Size())\n\n\t// Imprimir los elementos de la pila después de eliminar un elemento\n\tfmt.Println(\"Elementos de la pila:\", pila.ToString())\n\n\t// Crear una nueva cola\n\tcola := Cola{}\n\n\t// Agregar elementos a la cola\n\tcola.Enqueue(1)\n\tcola.Enqueue(2)\n\tcola.Enqueue(3)\n\n\t// Imprimir el tamaño\n\tfmt.Println(\"Tamaño de la cola:\", cola.Size())\n\n\t// Imprimir los elementos de la cola\n\tfmt.Println(\"Elementos de la cola:\", cola.ToString())\n\n\t// Eliminar un elemento de la cola\n\telementoEliminado = cola.Dequeue()\n\tfmt.Println(\"Elemento eliminado:\", elementoEliminado)\n\n\t// Imprimir el tamaño de la cola después de eliminar un elemento\n\tfmt.Println(\"Tamaño de la cola:\", cola.Size())\n\n\t// Imprimir los elementos de la cola después de eliminar un elemento\n\tfmt.Println(\"Elementos de la cola:\", cola.ToString())\n}\n"
  },
  {
    "path": "Roadmap/08 - CLASES/go/qwik-zgheib.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n)\n\n/* -- exercise */\ntype Programmer struct {\n\tName      string\n\tSurname   string\n\tAge       int\n\tLanguages []string\n}\n\nfunc NewProgrammer(name string, age int, languages []string) *Programmer {\n\treturn &Programmer{\n\t\tName:      name,\n\t\tAge:       age,\n\t\tLanguages: languages,\n\t}\n}\n\nfunc (p *Programmer) Print() {\n\tfmt.Printf(\"Name: %s | Surname: %s | Age: %d | Languages: %v\\n\", p.Name, p.Surname, p.Age, p.Languages)\n}\n\n/* -- stack */\ntype Stack struct {\n\titems []string\n}\n\nfunc NewStack() *Stack {\n\treturn &Stack{items: []string{}}\n}\n\nfunc (s *Stack) Push(item string) {\n\ts.items = append(s.items, item)\n}\n\nfunc (s *Stack) Pop() string {\n\tif s.Count() == 0 {\n\t\treturn \"\"\n\t}\n\titem := s.items[s.Count()-1]\n\ts.items = s.items[:s.Count()-1]\n\treturn item\n}\n\nfunc (s *Stack) Count() int {\n\treturn len(s.items)\n}\n\nfunc (s *Stack) Print() {\n\tfor i := len(s.items) - 1; i >= 0; i-- {\n\t\tfmt.Println(s.items[i])\n\t}\n}\n\n/* queue */\ntype Queue struct {\n\titems []string\n}\n\nfunc NewQueue() *Queue {\n\treturn &Queue{items: []string{}}\n}\n\n// Enqueue adds an item to the queue.\nfunc (q *Queue) Enqueue(item string) {\n\tq.items = append(q.items, item)\n}\n\nfunc (q *Queue) Dequeue() string {\n\tif q.Count() == 0 {\n\t\treturn \"\"\n\t}\n\titem := q.items[0]\n\tq.items = q.items[1:]\n\treturn item\n}\n\nfunc (q *Queue) Count() int {\n\treturn len(q.items)\n}\n\nfunc (q *Queue) Print() {\n\tfor _, item := range q.items {\n\t\tfmt.Println(item)\n\t}\n}\nfunc main() {\n\tmyProgrammer := NewProgrammer(\"Qwik\", 36, []string{\"Go\", \"Python\", \"Typescript\"})\n\tmyProgrammer.Print()\n\tmyProgrammer.Surname = \"Zgheib\"\n\tmyProgrammer.Print()\n\tmyProgrammer.Age = 37\n\tmyProgrammer.Print()\n\n\tmyStack := NewStack()\n\tmyStack.Push(\"A\")\n\tmyStack.Push(\"B\")\n\tmyStack.Push(\"C\")\n\tfmt.Println(myStack.Count())\n\tmyStack.Print()\n\tmyStack.Pop()\n\tfmt.Println(myStack.Count())\n\tfmt.Println(myStack.Pop())\n\tfmt.Println(myStack.Pop())\n\tfmt.Println(myStack.Pop())\n\tfmt.Println(myStack.Pop())\n\tfmt.Println(myStack.Count())\n\n\tmyQueue := NewQueue()\n\tmyQueue.Enqueue(\"A\")\n\tmyQueue.Enqueue(\"B\")\n\tmyQueue.Enqueue(\"C\")\n\tfmt.Println(myQueue.Count())\n\tmyQueue.Print()\n\tmyQueue.Dequeue()\n\tfmt.Println(myQueue.Count())\n\tfmt.Println(myQueue.Dequeue())\n\tfmt.Println(myQueue.Dequeue())\n\tfmt.Println(myQueue.Dequeue())\n\tfmt.Println(myQueue.Dequeue())\n\tfmt.Println(myQueue.Count())\n}\n"
  },
  {
    "path": "Roadmap/08 - CLASES/go/raynerpv2022.go",
    "content": "// # /*\n// #  * EJERCICIO:\n// #  * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n// #  * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n// #  * de tu lenguaje).\n// #  * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n// #  * utilizando su función.\n// #  *\n// #  * DIFICULTAD EXTRA (opcional):\n// #  * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n// #  * en el ejercicio número 7 de la ruta de estudio)\n// #  * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n// #  *   retornar el número de elementos e imprimir todo su contenido.\n// #  *\n// #  */\npackage main\n\nimport \"fmt\"\n\ntype Pila_o_Cola struct {\n\tlistValue []string\n}\n\nfunc (pc *Pila_o_Cola) Initt(init_value ...string) {\n\tpc.listValue = []string{}\n\tif init_value != nil {\n\t\tpc.listValue = append(pc.listValue, init_value...)\n\t}\n\n}\n\nfunc (pc *Pila_o_Cola) add() {\n\tfmt.Println(\" A rellenar , entra un elemento : \")\n\tvar value string\n\tfmt.Scanln(&value)\n\tpc.listValue = append(pc.listValue, value)\n}\n\nfunc (pc *Pila_o_Cola) is_empty() bool {\n\tif len(pc.listValue) == 0 {\n\n\t\treturn true\n\n\t} else {\n\n\t\treturn false\n\t}\n}\n\nfunc (pc *Pila_o_Cola) items_count() {\n\tif !pc.is_empty() {\n\t\tfmt.Printf(\"There are  %d Items \\n\", len(pc.listValue))\n\t\treturn\n\t}\n\n\tfmt.Println(\"Empty List... Add first\")\n}\n\nfunc (pc *Pila_o_Cola) print_items() {\n\tif !pc.is_empty() {\n\t\tfmt.Println(\" Mostrando elementos ... : \")\n\t\tfmt.Println(pc.listValue)\n\t\treturn\n\t}\n\tfmt.Println(\"Empty List... Add first\")\n}\n\nfunc (pc *Pila_o_Cola) delete_one_value(index int) (string, bool) {\n\tif !pc.is_empty() {\n\t\tvar deleteItem string\n\t\tif index == 0 {\n\t\t\tdeleteItem = pc.listValue[0]\n\t\t\tpc.listValue = pc.listValue[1:]\n\t\t} else {\n\t\t\tdeleteItem = pc.listValue[len(pc.listValue)-1]\n\t\t\tpc.listValue = pc.listValue[:len(pc.listValue)-1]\n\t\t}\n\t\treturn deleteItem, false\n\t}\n\tfmt.Println(\"Empty List... Add first\")\n\treturn \"\", true\n\n}\n\ntype Pila struct {\n\tPila_o_Cola\n}\n\nfunc (p *Pila) delete_lifo() {\n\tvalue, ok := p.delete_one_value(-1)\n\tif !ok {\n\t\tfmt.Println(\" Deleting  LIFO  ... : \")\n\t\tfmt.Printf(\"Item %v  deleted succesfully \\n\", value)\n\t\treturn\n\t}\n\treturn\n\n}\n\ntype Cola struct {\n\tPila_o_Cola\n}\n\nfunc (c *Cola) delete_fifo() {\n\tvalue, ok := c.delete_one_value(0)\n\tif !ok {\n\t\tfmt.Println(\" Deleting  FIFO  ... : \")\n\t\tfmt.Printf(\"Item %v  deleted succesfully \", value)\n\t\treturn\n\t}\n\n}\n\nfunc main() {\n\tpila := Pila{}\n\tcola := Cola{}\n\n\tpoc := \"\"\n\tfor {\n\t\tfmt.Println(\"PIla (P)  o  COLA (C)  Quit (Q) ?\")\n\t\tpc := \"\"\n\t\tfmt.Scanln(&pc)\n\t\tswitch pc {\n\t\tcase \"P\":\n\t\t\tpoc = \"Pila\"\n\t\tcase \"C\":\n\t\t\tpoc = \"Cola\"\n\t\tcase \"Q\":\n\t\t\treturn\n\t\tdefault:\n\n\t\t\tfmt.Println(\"Enter only P, C or Q\")\n\t\t\tcontinue\n\t\t}\n\t\tfor {\n\n\t\t\tfmt.Printf(\" What do you want to do with %v : \\n\", poc)\n\t\t\tfmt.Println(\"1 -  ADD\")\n\t\t\tfmt.Println(\"2 -  PRINT\")\n\t\t\tfmt.Println(\"3 -  How many Items are there\")\n\t\t\tfmt.Println(\"4 -  REMOVE\")\n\t\t\tfmt.Println(\"5 -  EXIT\")\n\t\t\tvar op string\n\t\t\tfmt.Scanln(&op)\n\t\t\tswitch op {\n\t\t\tcase \"1\":\n\n\t\t\t\tif pc == \"P\" {\n\t\t\t\t\tpila.add()\n\t\t\t\t} else {\n\t\t\t\t\tcola.add()\n\t\t\t\t}\n\t\t\tcase \"2\":\n\t\t\t\tif pc == \"P\" {\n\t\t\t\t\tpila.print_items()\n\t\t\t\t} else {\n\t\t\t\t\tcola.print_items()\n\t\t\t\t}\n\t\t\tcase \"3\":\n\t\t\t\tif pc == \"P\" {\n\t\t\t\t\tpila.items_count()\n\t\t\t\t} else {\n\t\t\t\t\tcola.items_count()\n\t\t\t\t}\n\t\t\tcase \"4\":\n\t\t\t\tif pc == \"P\" {\n\t\t\t\t\tpila.delete_lifo()\n\t\t\t\t} else {\n\t\t\t\t\tcola.delete_fifo()\n\t\t\t\t}\n\t\t\tcase \"5\":\n\t\t\t\tfmt.Println(\"EXIT now.. ... \")\n\t\t\t\treturn\n\t\t\tdefault:\n\t\t\t\tfmt.Println(\"Enter number between 1 and 5 , try again\")\n\n\t\t\t\t{\n\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t}\n}\n"
  },
  {
    "path": "Roadmap/08 - CLASES/go/thegera4.go",
    "content": "/* \nNOTA IMPORTANTE:\nGo no tiene clases como tal, pero se pueden simular con structs(estructuras) \ny métodos asociados a ellas.\nEn este ejemplo se simulan las estructuras de pila y cola, y se les agregan\nmétodos para realizar operaciones sobre ellas.\nLos metodos se definen con la estructura a la que pertenecen como primer \nargumento el cual se llama receptor.\n*/\n\npackage main\n\nimport \"fmt\"\n\n// Simulacion de clase \"Car\" con métodos asociados\ntype Car struct {\n\tbrand string // atributos\n\tmodel string\n\tyear int\n}\n\n// Método asociado a la estructura \"Car\"\nfunc (car Car) printInfo() string {\n\treturn fmt.Sprintf(\"Marca: %s, Modelo: %s, Año: %d\", car.brand, car.model, car.year)\n}\n\n// Método asociado a la estructura \"Car\"\nfunc (car *Car) changeBrand(newBrand string) {\n\tcar.brand = newBrand\n}\n\n// Estructura de pila de números (LIFO)\ntype Stack[T any] struct {\n\tdata []T\n}\n\n// Saber si la pila está vacía\nfunc (stack *Stack[T]) IsEmpty() bool {\n\treturn len(stack.data) == 0\n}\n\n// Agrega un número a la pila\nfunc (stack *Stack[T]) Push(element T) {\n\tstack.data = append(stack.data, element)\n}\n\n// Elimina y recupoera/devuelve el último número agregado a la pila. Regresa false si la pila está vacía\nfunc (stack *Stack[T]) Pop() (T, bool) {\n\tif stack.IsEmpty() {\n\t\tvar zeroValue T\n\t\treturn zeroValue, false\n\t} else {\n\t\tindex := len(stack.data) - 1 // Indice del último elemento\n\t\telement := stack.data[index]  // Último elemento\n\t\tstack.data = stack.data[:index] // Elimina el último elemento por su indice\n\t\treturn element, true\n\t}\n}\n\n// Estrucutra de cola de números (FIFO)\ntype Queue[T any] struct {\n\tdata []T\n}\n\n// Saber si la cola está vacía\nfunc (queue *Queue[T]) IsEmpty() bool {\n\treturn len(queue.data) == 0\n}\n\n// Agrega un número a la cola\nfunc (queue *Queue[T]) Enqueue(element T) {\n\tqueue.data = append(queue.data, element)\n}\n\n// Elimina y recupera/devuelve el primer número agregado a la cola. Regresa false si la cola está vacía\nfunc (queue *Queue[T]) Dequeue() (T, bool) {\n\tif queue.IsEmpty() {\n\t\tvar zeroValue T\n\t\treturn zeroValue, false\n\t} else {\n\t\telement := queue.data[0] // Accedemos al Primer elemento\n\t\tqueue.data = queue.data[1:] // Elimina el primer elemento\n\t\treturn element, true\n\t}\n}\n\nfunc main () {\n\n\t// Simulacion de clase \"Car\"\n\tcar1 := Car{brand: \"Ford\", model: \"Fiesta\", year: 2019}\n\tfmt.Println(car1.printInfo())\n\tcar1.changeBrand(\"Chevrolet\")\n\tfmt.Println(car1.printInfo())\n\t\n\t// Extra: Stack / Pila\n\tstack := Stack[string]{}\n\tfmt.Println(\"Pila vacía: \", stack.IsEmpty())\n\tstack.Push(\"1\")\n\tstack.Push(\"2\")\n\tstack.Push(\"3\")\n\tfmt.Println(\"Pila:\" + fmt.Sprint(stack.data))\n\tfmt.Println(\"Ahora se eliminara el ultimo elemento de la pila...\")\n\tstack.Pop()\n\tfmt.Println(\"Pila:\" + fmt.Sprint(stack.data))\n\t\n\t// Extra: Queue / Cola\n\tqueue := Queue[int]{}\n\tfmt.Println(\"Cola vacía: \", queue.IsEmpty())\n\tqueue.Enqueue(1)\n\tqueue.Enqueue(2)\n\tqueue.Enqueue(3)\n\tfmt.Println(\"Cola:\" + fmt.Sprint(queue.data))\n\tfmt.Println(\"Ahora se eliminara el primer elemento de la cola...\")\n\tqueue.Dequeue()\n\tfmt.Println(\"Cola:\" + fmt.Sprint(queue.data))\n\n}"
  },
  {
    "path": "Roadmap/08 - CLASES/java/AbelADE.java",
    "content": "public class Main {\n    public static void main(String[] args) {\n        Client client = new Client(\"Abel\", 20);\n        System.out.println(client);\n        client.setAge(30);\n        System.out.println(client);\n\n        System.out.println(\"--------- DIFICULTAD EXTRA -------------\");\n\n        //Pilas\n        Stack stack = new Stack();\n        stack.push(30);\n        stack.push(20);\n        stack.push(10);\n        System.out.println(stack);\n        System.out.println(\"Tamaño: \" + stack.size());\n        stack.pop();\n        System.out.println(stack);\n        stack.pop();\n        System.out.println(stack + \"\\n\");\n\n        //Colas\n        Queue queue = new Queue();\n        queue.enqueue(10);\n        queue.enqueue(20);\n        queue.enqueue(30);\n        System.out.println(queue);\n        System.out.println(\"Tamaño: \" + queue.size());\n        queue.dequeue();\n        System.out.println(queue);\n        queue.dequeue();\n        System.out.println(queue);\n    }\n}\n\nclass Client {\n    // Atributos\n    String name;\n    int age;\n\n    //Métodos de acceso y sobrescritura de atributos\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public int getAge() {\n        return age;\n    }\n\n    public void setAge(int age) {\n        this.age = age;\n    }\n\n    // Constructor\n    public Client(String name, int age) {\n        this.name = name;\n        this.age = age;\n    }\n\n    //Método para imprimir por pantalla\n    @Override\n    public String toString() {\n        return \"Cliente: \" + name + \", Edad: \" + age;\n    }\n}\n\nclass Stack{\n    ArrayList<Object> stack;\n\n    public Stack() {\n        this.stack = new ArrayList<>();\n    }\n\n    public <T> void push(T valor){\n        stack.add(valor);\n    }\n\n    public <T> T pop(){\n        if (stack.isEmpty()){\n            return null;\n        }\n\n        Object object = stack.get(stack.size()-1);\n        stack.remove(stack.size()-1);\n        return (T) object;\n    }\n\n    public int size(){\n        return stack.size();\n    }\n\n    @Override\n    public String toString() {\n        String text = \"Stack: \\n\";\n        String separator = \", \";\n        for(int i = 0; i<stack.size(); i++){\n            if (i == stack.size()-1){\n                separator = \"\";\n            }\n            text += stack.get(i) + separator;\n        }\n\n        return text;\n    }\n}\n\nclass Queue{\n    ArrayList<Object> queue;\n\n    public Queue() {\n        this.queue = new ArrayList<>();\n    }\n\n    public <T> void enqueue(T valor){\n        queue.add(valor);\n    }\n\n    public <T> T dequeue(){\n        if (queue.isEmpty()){\n            return null;\n        }\n\n        Object object = queue.get(0);\n        queue.remove(0);\n        return (T) object;\n    }\n\n    public int size(){\n        return queue.size();\n    }\n\n    @Override\n    public String toString() {\n        String text = \"Queue: \\n\";\n        String separator = \", \";\n        for(int i = 0; i<queue.size(); i++){\n            if (i == queue.size()-1){\n                separator = \"\";\n            }\n            text += queue.get(i) + separator;\n        }\n        return text;\n    }\n}\n"
  },
  {
    "path": "Roadmap/08 - CLASES/java/AmadorQuispe.java",
    "content": "import java.time.LocalDate;\nimport java.time.Period;\nimport java.util.Iterator;\nimport java.util.NoSuchElementException;\n\npublic class Poo {\n    public static void main(String[] args) {\n        // creamos un objeto de la clase estudiante,\n        Student s = new Student(120, \"Amador\", \"Quispe\", LocalDate.of(1992, 7, 13));\n        System.out.println(s);\n\n        System.out.println(\"Pilas personalizadas\");\n        DinamicStack<Integer> pilaNums = new DinamicStack<>();\n        pilaNums.push(120);\n        pilaNums.push(130);\n        pilaNums.push(140);\n        pilaNums.push(150);\n        System.out.println(pilaNums.peek());\n        System.out.println(pilaNums.size());\n        System.out.println(pilaNums.pop());\n        System.out.println(pilaNums.pop());\n        System.out.println(pilaNums.size());\n        pilaNums.forEach(System.out::print);\n        System.out.println(\"Colas personalizadas\");\n        DinamicQueue<Integer> numbers = new DinamicQueue<>();\n        System.out.println(numbers.enqueue(1));\n        System.out.println(numbers.enqueue(2));\n        System.out.println(numbers.enqueue(3));\n        System.out.println(numbers.enqueue(4));\n        System.out.println(\"Tamaño de cola antes de encolar \" + numbers.size());\n        System.out.println(numbers.dequeue());\n        System.out.println(\"Tamaño de cola despues de encolar \" + numbers.size());\n        numbers.forEach(System.out::println);\n    }\n}\n\nclass Student {\n    private int code;\n    private String firstName;\n    private String lastName;\n    private LocalDate birthdate;\n    private int age;\n\n    public Student(int code, String firstName, String lastName, LocalDate birthdate) {\n        this.code = code;\n        this.firstName = firstName;\n        this.lastName = lastName;\n        this.birthdate = birthdate;\n    }\n\n    public int getCode() {\n        return code;\n    }\n\n    public void setCode(int code) {\n        this.code = code;\n    }\n\n    public String getFirstName() {\n        return firstName;\n    }\n\n    public void setFirstName(String firstName) {\n        this.firstName = firstName;\n    }\n\n    public String getLastName() {\n        return lastName;\n    }\n\n    public void setLastName(String lastName) {\n        this.lastName = lastName;\n    }\n\n    public LocalDate getBirthdate() {\n        return birthdate;\n    }\n\n    public void setBirthdate(LocalDate birthdate) {\n        this.birthdate = birthdate;\n    }\n\n    public int getAge() {\n        Period period = Period.between(birthdate, LocalDate.now());\n        age = period.getYears();\n        return age;\n    }\n\n    @Override\n    public String toString() {\n        return String.format(\"code=%d, firstName=%s, lastName=%s, age=%d \", code, firstName, lastName, getAge());\n    }\n\n}\n\nclass Node<T> {\n    private T value;\n    private Node<T> next;\n\n    public Node(T value, Node<T> next) {\n        this.value = value;\n        this.next = next;\n    }\n\n    public T getValue() {\n        return value;\n    }\n\n    public Node<T> getNext() {\n        return next;\n    }\n\n    public void setNext(Node<T> next) {\n        this.next = next;\n    }\n}\n\nclass DinamicStack<T> implements Iterable<T> {\n    private Node<T> top = null;\n    private int length = 0;\n\n    T push(T element) {\n        Node<T> newNode = new Node<T>(element, null);\n        if (top == null) {\n            top = newNode;\n        } else {\n            newNode.setNext(top);\n            top = newNode;\n        }\n        length++;\n        return top.getValue();\n    }\n\n    T pop() {\n        if (top == null) {\n            return null;\n        }\n        T delete = top.getValue();\n        top = top.getNext();\n        length--;\n        return delete;\n    }\n\n    T peek() {\n        if (top == null) {\n            return null;\n        }\n        return top.getValue();\n    }\n\n    int size() {\n        return length;\n    }\n\n    @Override\n    public Iterator<T> iterator() {\n        return new Iterator<T>() {\n            Node<T> current = top;\n\n            @Override\n            public boolean hasNext() {\n                return current != null;\n            }\n\n            @Override\n            public T next() {\n                if (!hasNext()) {\n                    throw new NoSuchElementException(\"No hay más elementos en la pila\");\n                }\n                T item = current.getValue();\n                current = current.getNext();\n                return item;\n\n            }\n\n        };\n    }\n\n}\n\nclass DinamicQueue<T> implements Iterable<T> {\n    private int size = 0;\n    private Node<T> first = null;\n    private Node<T> last = null;\n\n    public boolean isEmpty() {\n        return first == null;\n    }\n\n    public T first() {\n        if (isEmpty()) {\n            return null;\n        }\n        return first.getValue();\n    }\n\n    public T enqueue(T element) {\n        Node<T> newNode = new Node<>(element, null);\n        if (isEmpty()) {\n            first = newNode;\n            last = newNode;\n        } else {\n            last.setNext(newNode);\n            last = newNode;\n        }\n        size++;\n        return newNode.getValue();\n    }\n\n    public T dequeue() {\n        if (isEmpty()) {\n            return null;\n        }\n        T item = first.getValue();\n        first = first.getNext();\n        size--;\n        if (isEmpty()) {\n            last = null;\n        }\n        return item;\n    }\n\n    public int size() {\n        return this.size;\n    }\n\n    @Override\n    public Iterator<T> iterator() {\n        return new Iterator<T>() {\n            private Node<T> current = first;\n\n            @Override\n            public boolean hasNext() {\n                return current != null;\n            }\n\n            @Override\n            public T next() {\n                if (!hasNext()) {\n                    throw new NoSuchElementException(\"No hay más elementos en la cola\");\n                }\n                T item = current.getValue();\n                current = current.getNext();\n                return item;\n            }\n\n        };\n    }\n}\n"
  },
  {
    "path": "Roadmap/08 - CLASES/java/AnaLauDB.java",
    "content": "import java.util.ArrayList;\n\npublic class AnaLauDB {\n    public static void main(String[] args) {\n        Programador programador1 = new Programador(\"Alice\", \"Java\", 5);\n        programador1.Info();\n\n        programador1.nombre = \"Laura\";\n        programador1.lenguaje = \"Java\";\n        programador1.experiencia = 4;\n        programador1.Info();\n\n        System.out.println(\"   \");\n        Pila p1 = new Pila();\n        p1.push(40);\n        p1.push(50);\n        p1.push(60);\n        p1.print();\n        p1.pop();\n        p1.print();\n\n        Cola c1 = new Cola();\n        c1.enqueue(70);\n        c1.enqueue(80);\n        c1.enqueue(90);\n        c1.print();\n        c1.dequeue();\n        c1.print();\n    }\n\n    // EJERCICIO\n    public static class Programador {\n        String nombre;\n        String lenguaje;\n        int experiencia;\n\n        public Programador(String nombre, String lenguaje, int experiencia) {\n            this.nombre = nombre;\n            this.lenguaje = lenguaje;\n            this.experiencia = experiencia;\n        }\n\n        public void Info() {\n            System.out.println(\"Nombre: \" + nombre);\n            System.out.println(\"Lenguaje: \" + lenguaje);\n            System.out.println(\"Años de experiencia: \" + experiencia);\n            System.out.println(\"     \");\n        }\n    }\n\n    // RETO EXTRA\n    public static class Pila {\n        private ArrayList<Integer> elementos = new ArrayList<>();\n\n        public Pila() {\n            this.elementos = new ArrayList<>();\n        }\n\n        public void push(int elemento) {\n            elementos.add(elemento);\n        }\n\n        public int pop() {\n            if (!elementos.isEmpty())\n                return -1;\n            return elementos.remove(elementos.size() - 1);\n        }\n\n        public int size() {\n            return elementos.size();\n        }\n\n        public void print() {\n            System.out.print(\"Pila: \" + elementos);\n            System.out.println();\n        }\n\n    }\n\n    public static class Cola {\n        private ArrayList<Integer> elementos = new ArrayList<>();\n\n        public Cola() {\n            this.elementos = new ArrayList<>();\n        }\n\n        public void enqueue(int elemento) {\n            elementos.add(elemento);\n        }\n\n        public int dequeue() {\n            if (!elementos.isEmpty())\n                return elementos.remove(0);\n            return -1;\n        }\n\n        public int size() {\n            return elementos.size();\n        }\n\n        public void print() {\n            System.out.print(\"Cola: \" + elementos);\n            System.out.println();\n        }\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/08 - CLASES/java/AndrewCodev.java",
    "content": "\nimport java.util.*;\n\npublic class AndrewCodev {\n\n\t// Creando atributos\n\tprivate String nombre;\n\tprivate String apellido;\n\tprivate int edad;\n\n\t// Inicializamos los atributos en el constructor\n\tpublic AndrewCodev() {\n\t\tthis.nombre = \"Andres\";\n\t\tthis.apellido = \"Lozano\";\n\t\tthis.edad = 29;\n\t}\n\n\t// Creamos los metodos Get y Set de cada atributo para acceder al valor de los\n\t// atributos en el constructor\n\tpublic String getNombre() {\n\t\treturn nombre;\n\t}\n\n\tpublic void setNombre(String nombre) {\n\t\tthis.nombre = nombre;\n\t}\n\n\tpublic String getApellido() {\n\t\treturn apellido;\n\t}\n\n\tpublic void setApellido(String apellido) {\n\t\tthis.apellido = apellido;\n\t}\n\n\tpublic int getEdad() {\n\t\treturn edad;\n\t}\n\n\tpublic void setEdad(int edad) {\n\t\tthis.edad = edad;\n\t}\n\n\tpublic static void main(String[] args) {\n\t\t// creamos la instancia del objeto AndrewCodev y accedemos a sus métodos desde\n\t\t// el metodo main\n\t\tAndrewCodev andrewCodev = new AndrewCodev();\n\t\t// Imprimimos sus atributos\n\t\tSystem.out.println(\"Atributos inicializados\");\n\t\tSystem.out.println(\"Nombre: \" + andrewCodev.getNombre());\n\t\tSystem.out.println(\"Apellido: \" + andrewCodev.getApellido());\n\t\tSystem.out.println(\"Edad: \" + andrewCodev.getEdad());\n\n\t\t// Modificamos los atributos\n\t\tSystem.out.println(\"\\nAtributos modificados\");\n\t\tandrewCodev.setNombre(\"Felipe\");\n\t\tSystem.out.println(\"Nombre: \" + andrewCodev.getNombre());\n\t\tandrewCodev.setApellido(\"Mendoza\");\n\t\tSystem.out.println(\"Apellido: \" + andrewCodev.getApellido());\n\t\tandrewCodev.setEdad(30);\n\t\tSystem.out.println(\"Edad: \" + andrewCodev.getEdad());\n\n\t\t// FIN DEL EJERCICIO BASE\n\t}\n\n\t// Creamos la clase que representa la estructura de PILAS\n\tstatic class ClsPilas {\n\t\tStack<Integer> pila;\n\n\t\t// Creamos los métodos que ejecutarán las acciones de agregar, listar, remover,\n\n\t\t// Agregar elemento\n\t\tpublic Stack<Integer> agregar(Stack<Integer> pila, int numero) {\n\t\t\tpila.push(numero);\n\t\t\treturn pila;\n\t\t}\n\n\t\t// Ver elemento superior en la pila\n\t\tpublic Stack<Integer> verUltimo(Stack<Integer> pila) {\n\t\t\tpila.peek();\n\t\t\treturn pila;\n\t\t}\n\n\t\t// Listar todo\n\t\tpublic Stack<Integer> listarTodo(Stack<Integer> pila) {\n\t\t\treturn pila;\n\t\t}\n\n\t\t// Eliminar elemento superior en la pila\n\t\tpublic Stack<Integer> eliminarUltimo(Stack<Integer> pila) {\n\t\t\tpila.pop();\n\t\t\treturn pila;\n\t\t}\n\n\t\t// Eliminar todos\n\t\tpublic Stack<Integer> eliminarTodos(Stack<Integer> pila) {\n\t\t\tpila.clear();\n\t\t\treturn pila;\n\t\t}\n\t}\n\n\tstatic class OrdenLlegada {\n\t\tQueue<Integer> cola;\n\t\t// Creamos los métodos que ejecutarán las acciones de agregar, listar, remover,\n\n\t\t// Agregar elemento\n\t\tpublic Queue<Integer> agregarPlato(Queue<Integer> cola, int numero) {\n\t\t\tcola.add(numero);\n\t\t\treturn cola;\n\t\t}\n\n\t\t// Ver elemento superior en la pila\n\t\tpublic Queue<Integer> verUltimo(Queue<Integer> cola) {\n\t\t\tcola.peek();\n\t\t\treturn cola;\n\t\t}\n\n\t\t// Ver elemento superior en la pila\n\t\tpublic Queue<Integer> verTodos(Queue<Integer> cola) {\n\t\t\treturn cola;\n\t\t}\n\n\t\t// Eliminar elemento superior en la pila\n\t\tpublic Queue<Integer> eliminarUltimo(Queue<Integer> cola) {\n\t\t\tcola.remove();\n\t\t\treturn cola;\n\t\t}\n\n\t\t// Eliminar todos\n\t\tpublic Queue<Integer> eliminarTodos(Queue<Integer> cola) {\n\t\t\tcola.clear();\n\t\t\treturn cola;\n\t\t}\n\t}\n}"
  },
  {
    "path": "Roadmap/08 - CLASES/java/FranDev200.java",
    "content": "import java.util.ArrayList;\n\npublic class FranDev200 {\n\n    static void main() {\n\n        /*\n\n            EJERCICIO:\n            * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n            * atributos y una función que los imprima (teniendo en cuenta las posibilidades de tu lenguaje).\n            * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos utilizando su función.\n\n         */\n\n        Person person1 = new Person(\"Francisco\", 20, \"Futuro desarrollador de Software\", 1.78, false);\n        viewContent(person1);\n\n        person1.setAge(21);\n        person1.setCouple(true);\n        viewContent(person1);\n\n\n        /*\n\n         * DIFICULTAD EXTRA (opcional):\n         * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas en el ejercicio número 7 de la ruta de estudio)\n\n         */\n\n        // CLASE STACK / PILA\n        StackFran<Object> stackMascotas = new StackFran<>();\n        stackMascotas.push(\"Perro\");\n        stackMascotas.push(\"Gato\");\n        stackMascotas.push(\"Loro\");\n        stackMascotas.push(\"Hamster\");\n\n        System.out.println(\"¿Esta vacio?: \" + stackMascotas.isEmpty());\n        System.out.println(\"Elemento más arriba: \" + stackMascotas.peek());\n        System.out.println(\"Elemento más arriba: \" + stackMascotas.pop());\n        System.out.println(\"Elemento más arriba: \" + stackMascotas.peek());\n        System.out.println(\"Tamaño del stack: \" + stackMascotas.size());\n        System.out.print(\"Elementos del stack: \");\n        stackMascotas.viewAll();\n        stackMascotas.clear();\n        System.out.print(\"Elementos del stack: \");\n        stackMascotas.viewAll();\n\n        // CLASE QUEUE / COLA\n        QueueFran<Object> queueComida = new QueueFran<>();\n        queueComida.offer(\"Tomates\");\n        queueComida.offer(\"Pollo\");\n        queueComida.offer(\"Lechuga\");\n        queueComida.offer(\"huevos\");\n\n        System.out.println(\"¿Esta vacio?: \" + queueComida.isEmpty());\n        System.out.println(\"Elemento más arriba: \" + queueComida.peek());\n        System.out.println(\"Elemento más arriba: \" + queueComida.poll());\n        System.out.println(\"Elemento más arriba: \" + queueComida.peek());\n        System.out.println(\"Numero de elementos del queue: \" + queueComida.size());\n        System.out.print(\"Elementos del queue: \");\n        queueComida.viewAll();\n        queueComida.clear();\n        System.out.print(\"Elementos del queue: \");\n        queueComida.viewAll();\n\n    }\n\n    private static void viewContent(Person person1) {\n        System.out.println(\"\\n\" + person1.getName() + \" (\" + person1.getAge() + \" años)\");\n        System.out.println(\"=\".repeat(person1.getName().length() + 10));\n        System.out.println(\"Trabajo: \" + person1.getJob());\n        System.out.println(\"Estatura: \" + person1.getHeight());\n        System.out.println(\"Pareja: \" + person1.isCouple());\n        System.out.println(\"=\".repeat(person1.getName().length() + 10));\n    }\n\n\n}\n\nclass Person{\n\n    private String name;\n    private int age;\n    private String job;\n    private double height;\n    private boolean couple;\n\n    public Person(){\n    }\n\n    public Person(String name, int age, String job, double height, boolean couple){\n        setName(name);\n        setAge(age);\n        setJob(job);\n        setHeight(height);\n        setCouple(couple);\n    }\n\n    public String getName() { return name; }\n\n    public void setName(String name) { this.name = name; }\n\n    public int getAge() { return age; }\n\n    public void setAge(int age) { this.age = age; }\n\n    public String getJob() { return job; }\n\n    public void setJob(String job) { this.job = job; }\n\n    public double getHeight() { return height; }\n\n    public void setHeight(double height) { this.height = height; }\n\n    public boolean isCouple() { return couple; }\n\n    public void setCouple(boolean couple) { this.couple = couple; }\n}\n\nclass StackFran<T>{\n\n    private ArrayList<T> stack;\n\n    public StackFran(){\n\n        this.stack = new ArrayList<>();\n\n    }\n\n    // Añade elemento\n    public void push(T i){\n\n        stack.addFirst(i);\n\n    }\n\n    // Muestra y elimina el primer elemento\n    public T pop(){\n\n        T result = stack.getFirst();\n        stack.remove(result);\n\n        if(stack.isEmpty()){\n            return null;\n        }else{\n            return result;\n        }\n\n    }\n\n    // Muestra el primer elemento\n    public T peek(){\n\n        if(!isEmpty()){\n            return stack.getFirst();\n        }else{\n            System.out.println(\"El array esta vacio.\");\n            return null;\n        }\n\n    }\n\n    // Comprueba si esta vacio el stack\n    public boolean isEmpty(){\n\n        return stack.isEmpty();\n\n    }\n\n    // Numero de elementos del stack\n    public int size(){\n\n        return stack.size();\n\n    }\n\n    // Ver todos los elementos del stack\n    public void viewAll(){\n\n        System.out.print(\"[\");\n        for (T element: stack){\n            if(!element.equals(stack.getLast())){\n                System.out.print(element + \", \");\n            }else{\n                System.out.print(element);\n            }\n\n        }\n        System.out.println(\"]\");\n    }\n\n    // Limpiar el stack\n    public void clear(){\n        System.out.println(\"Elementos borrados.\");\n        stack.clear();\n    }\n}\n\nclass QueueFran<T>{\n\n    private ArrayList<T> queue;\n\n    public QueueFran(){\n\n        this.queue = new ArrayList<>();\n\n    }\n\n    // Añado un elemento al final del queue\n    public void offer(T i){\n        queue.add(i);\n    }\n\n    // Muestro y elimino el primer elemento del queue\n    public T poll(){\n        T result = queue.getFirst();\n        queue.remove(result);\n\n        if(queue.isEmpty()){\n            return null;\n        }else{\n            return result;\n        }\n    }\n\n    // Muestro el primer elemento del queue\n    public T peek(){\n\n        if(!isEmpty()){\n            return queue.getFirst();\n        }else{\n            System.out.println(\"La cola está vacía.\");\n            return null;\n        }\n    }\n\n    // Compruebo si está vacía el queue\n    public boolean isEmpty(){\n\n        return queue.isEmpty();\n\n    }\n\n    // Devuelvo el tamaño del queue\n    public int size(){\n\n        return queue.size();\n\n    }\n\n    // Muestro todos los elementos del queue\n    public void viewAll(){\n\n        System.out.print(\"[\");\n        for (T element: queue){\n            if(!element.equals(queue.getLast())){\n                System.out.print(element + \", \");\n            }else{\n                System.out.print(element);\n            }\n\n        }\n        System.out.println(\"]\");\n    }\n\n    // Limpiar el queue\n    public void clear(){\n        System.out.println(\"Elementos borrados.\");\n        queue.clear();\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/08 - CLASES/java/GlossyPath.java",
    "content": "import java.util.LinkedList;\nimport java.util.Queue;\nimport java.util.Stack;\n\n/**\n * \n *EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n * \n *  @version v1.0\n * \n *  @since 31/07/2024\n * \n * @author GlossyPath\n */\n\n\npublic class GlossyPath {\n    \n    public static void main(String[] args) {\n        \n        Pila<Empresa> pilaEmpresas = new Pila<>();\n\n        Cola<Empresa> colaEmpresas = new Cola();\n\n        Empresa empresa = new Empresa();\n\n        empresa.setCantidadEmpleados(10);\n        empresa.setEsNueva(true);\n        empresa.setNombre(\"Rolan S.L\");\n        empresa.setUbicadoEnPais(\"Francia\");\n\n        pilaEmpresas.añadirALaPila(empresa);\n\n        colaEmpresas.añadirALaCola(empresa);\n\n        System.out.println(pilaEmpresas);\n\n        System.out.println(colaEmpresas);    \n    }\n}\n\n\nclass Empresa {\n\n    private String nombre, ubicadoEnPais;\n    private int cantidadEmpleados;\n    private boolean esNueva;\n\n    public Empresa(){\n\n    }\n\n    public String getNombre() {\n        return nombre;\n    }\n\n    public void setNombre(String nombre) {\n        this.nombre = nombre;\n    }\n\n    public String getUbicadoEnPais() {\n        return ubicadoEnPais;\n    }\n\n    public void setUbicadoEnPais(String ubicadoEnPais) {\n        this.ubicadoEnPais = ubicadoEnPais;\n    }\n\n    public int getCantidadEmpleados() {\n        return cantidadEmpleados;\n    }\n\n    public void setCantidadEmpleados(int cantidadEmpleados) {\n        this.cantidadEmpleados = cantidadEmpleados;\n    }\n\n    public boolean isEsNueva() {\n        return esNueva;\n    }\n\n    public void setEsNueva(boolean esNueva) {\n        this.esNueva = esNueva;\n    }\n\n    @Override\n    public String toString(){\n\n        String nuevaVieja;\n\n        if(isEsNueva()){\n            nuevaVieja = \"si\";\n\n            } else {\n             nuevaVieja = \"la empresa es antigua\";   \n            }\n\n        return \"Empresa {\" +\n                \"nombre: \" + nombre +\n                \" ubicada en: \" + ubicadoEnPais +\n                \" cantidad de empleados: \" + cantidadEmpleados +\n                \" la empresa es nueva:\" + nuevaVieja + \"}\";         \n            }\n                \n        }\n\n\nclass Pila<T> {\n\n    private Stack<T> pila;\n\n    public Pila() {\n        this.pila = new Stack<>();\n    }\n\n    public int cantidadObjetos(){\n        return this.pila.size();\n    }\n\n    public void añadirALaPila(T o){\n        this.pila.add(o);\n    }\n\n    public void eliminarDeLaPila(){\n        T eliminado = this.pila.pop();\n\n        System.out.println(\"El elemento eliminado es: \" + eliminado);\n    }\n\n    @Override\n    public String toString(){\n        StringBuilder nombreEmpresas = new StringBuilder(\"\\nContenido de la pila: \\n\");\n\n        @SuppressWarnings(\"unchecked\")\n        Stack<T> copiaPila = (Stack<T>) this.pila.clone();\n        \n        while (!copiaPila.isEmpty()) {\n            nombreEmpresas.append(copiaPila.pop().toString()).append(\"\\n\");\n        }\n        \n        return nombreEmpresas.toString();\n    }\n}\n \nclass Cola<T> {\n\n    private Queue<T> cola;\n\n    public Cola() {\n        this.cola= new LinkedList<>();\n    }\n\n\n    public int cantidadObjetos(){\n        return this.cola.size();\n    }\n\n    public void añadirALaCola(T object){\n        this.cola.add(object);\n    }\n\n    public void eliminarDeLaCola(int index) throws IndexOutOfBoundsException{\n        if(this.cola.size() < index || index < 0){\n            throw new IndexOutOfBoundsException(\"El índice no puede ser superior al tamaño de la cola o negativo.\");\n\n        } else {\n            this.cola.remove(index);\n        }      \n    }\n\n    @Override\n    public String toString(){\n        StringBuilder sb = new StringBuilder(\"\\nContenido de la cola:\\n\");\n\n        this.cola.forEach(objeto->sb.append(objeto).append(\"\\n\"));\n\n        return sb.toString();\n        }\n    }   \n\n    \n"
  },
  {
    "path": "Roadmap/08 - CLASES/java/GustavoGomez19.java",
    "content": "import java.security.PublicKey;\nimport java.util.ArrayDeque;\nimport java.util.ArrayList;\nimport java.util.Deque;\nimport java.util.LinkedList;\nimport java.util.Queue;\nimport java.util.Stack;\n\npublic class GustavoGomez19 {\n    /*\n     * EJERCICIO:\n     * Explora el concepto de clase y crea un ejemplo que implemente un\n     * inicializador,\n     * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n     * de tu lenguaje).\n     * Una vez implementada, créala, establece sus parámetros, modifícalos e\n     * imprímelos\n     * utilizando su función.\n     */\n\n    public static void main(String[] args) {\n\n        Animal perro = new Animal(2, \"Roko\", \"Criollo\");\n        Animal gato = new Animal();\n        gato.setEdad(3);\n        gato.setNombre(\"Gael\");\n        gato.setRaza(\"Criollo\");\n\n        System.out.println(perro.verInfo());\n        System.out.println();\n        System.out.println(gato.verInfo());\n        System.out.println(\"******************\");\n\n        // DIFICULTAD EXTRA\n        // Pila\n        Pila miPila = new Pila();\n        // Añadir elementos\n        miPila.agregarElemento(\"Gustavo\");\n        miPila.agregarElemento(\"Katerine\");\n        miPila.agregarElemento(\"María José\");\n        // Eliminar elemento\n        miPila.eleminarElemento();\n        // Ver elementos de la pila\n        miPila.verElementos();\n        // Tamaño de la pila\n        miPila.conocerTamanoPila();\n        System.out.println();\n        System.out.println(\"************************\");\n\n        // Cola\n        Cola miCola = new Cola();\n        // Agregar elementos a la cola\n        miCola.agregarElementoCola(1);\n        miCola.agregarElementoCola(2);\n        miCola.agregarElementoCola(3);\n        // Elimianr elementos de la cola\n        miCola.eleminarElementoCola();\n        // Ver elementos de la cola\n        miCola.verElementosCola();\n        // Tamaño de la cola\n        miCola.conocerTamanoCola();\n\n\n\n    }\n\n    static class Animal {\n        private int edad;\n        private String nombre;\n        private String raza;\n\n        // Contructor vacío\n        public Animal() {\n        };\n\n        // Contructor con parámetros\n        public Animal(int edad, String nombre, String raza) {\n            this.edad = edad;\n            this.nombre = nombre;\n            this.raza = raza;\n        }\n\n        // Métodos accesores (Getters - Setters)\n        public int getEdad() {\n            return edad;\n        }\n\n        public void setEdad(int edad) {\n            this.edad = edad;\n        }\n\n        public String getNombre() {\n            return nombre;\n        }\n\n        public void setNombre(String nombre) {\n            this.nombre = nombre;\n        }\n\n        public String getRaza() {\n            return raza;\n        }\n\n        public void setRaza(String raza) {\n            this.raza = raza;\n        }\n\n        // Método para impirmir la información\n        public String verInfo() {\n            return \"*** INFORMACIÓN DE LA MASCOTA*** \" + \"\\n\" +\n                    \"Edad: \" + edad + \" años\" + \"\\n\" +\n                    \"Nombre: \" + nombre + \"\\n\" +\n                    \"Raza: \" + raza;\n        }\n    }\n\n    /*\n     * DIFICULTAD EXTRA (opcional):\n     * Implementa dos clases que representen las estructuras de Pila y Cola\n     * (estudiadas\n     * en el ejercicio número 7 de la ruta de estudio)\n     * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n     * retornar el número de elementos e imprimir todo su contenido.\n     */\n\n    static class Pila {\n        // Creación de la pila\n        private Stack<String> pila;\n\n        public Pila(){\n            this.pila = new Stack<>();\n        }\n\n        // Agregar elementos a la pila\n        public void agregarElemento(String elemento){\n            this.pila.push(elemento);\n        }\n        // Eliminar elemento de la pila\n        public void eleminarElemento(){\n            this.pila.pop();\n        }\n        // Mostrar los elemanto de la pila\n        public void verElementos(){\n            System.out.println(\"Elementos de la pila: \");\n            for (String elemento : this.pila) {\n                System.out.println(elemento);\n            }\n        }\n        // Método para saber el tamaño de la pila\n        public void conocerTamanoPila(){\n            System.out.print(\"Tamaño de pila: \" + pila.size());\n        }\n\n    }\n\n    static class Cola {\n        // Creación de cola\n        private Queue<Integer> cola;\n\n        public Cola(){\n            this.cola = new LinkedList<>();\n        }\n\n        // Agregar elemanto a la cola\n        public void agregarElementoCola(Integer elemento){\n            this.cola.add(elemento);\n        }\n        // Eliminar elemento de la cola\n        public void eleminarElementoCola(){\n            this.cola.poll();\n        }\n        // Mostrar elementos de la cola\n        public void verElementosCola(){\n            System.out.println(\"Elementos de la cola\");\n            for (Integer elementos : cola) {\n                System.out.println(elementos);\n            }\n        }\n        // Conocer el tamaño de la cola\n        public void conocerTamanoCola(){\n            System.out.print(\"Tamaño de la cola: \" + cola.size());\n        }\n        \n    }\n\n}\n"
  },
  {
    "path": "Roadmap/08 - CLASES/java/Jeigar2.java",
    "content": "import java.util.Collection;\nimport java.util.HashMap;\nimport java.util.Iterator;\nimport java.util.Vector;\n\npublic class Jeigar2 {\n    /*\n     * EJERCICIO:\n     * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n     * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n     * de tu lenguaje).\n     * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n     * utilizando su función.\n     *\n     * DIFICULTAD EXTRA (opcional):\n     * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n     * en el ejercicio número 7 de la ruta de estudio)\n     * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n     *   retornar el número de elementos e imprimir todo su contenido.\n     */\n    public static void main(String[] args) {\n        Persona persona1 = new Persona();\n        persona1.setNombre(\"Pedro\");\n        persona1.setApellido(\"Picapiedra\");\n        persona1.setEdad(65);\n        System.out.println(persona1);\n\n        Persona pablo = new Persona(\"Pablo\", \"Marmol\", 61);\n        System.out.println(pablo);\n\n        LaPila<Persona> lista = new LaPila<>();\n        lista.agregarElemento(persona1);\n        lista.agregarElemento(pablo);\n        System.out.println(lista);\n\n        LaCola<Persona> lista2 = new LaCola<>();\n        lista2.agregarElemento(persona1);\n        lista2.agregarElemento(new Persona(\"Bilma\", \"Topacio\", 60));\n        lista2.agregarElemento(pablo);\n        lista2.agregarElemento(new Persona(\"Maria\", \"Cuarzo\", 59));\n        System.out.println(lista2);\n    }\n}\n\nclass Persona {\n    private final int MAYOR_EDAD = 18;\n\n    private String nombre;\n    private String apellido;\n    private int edad;\n\n    public Persona() {\n        super();\n    }\n\n    public Persona(String nombre, String apellido, int edad) {\n        this.nombre = nombre;\n        this.apellido = apellido;\n        this.edad = edad;\n    }\n\n    public String getNombre() {\n        return nombre;\n    }\n\n    public void setNombre(String nombre) {\n        this.nombre = nombre;\n    }\n\n    public String getApellido() {\n        return apellido;\n    }\n\n    public void setApellido(String apellido) {\n        this.apellido = apellido;\n    }\n\n    public int getEdad() {\n        return edad;\n    }\n\n    public void setEdad(int edad) {\n        this.edad = edad;\n    }\n\n    public boolean isMayorEdad() {\n        return edad >= MAYOR_EDAD;\n    }\n\n    @Override\n    public String toString() {\n        return \"Persona{\" +\n                \"nombre='\" + nombre + '\\'' +\n                \", apellido='\" + apellido + '\\'' +\n                \", edad=\" + edad +\n                '}';\n    }\n}\n\nclass LaPila<T> {\n    private HashMap<Integer, T> laPila;\n\n    public LaPila() {\n        this.laPila = new HashMap<>();\n    }\n\n    public int totalElementos() {\n        return laPila.size();\n    }\n\n    public void agregarElemento(T o) {\n        laPila.put(ultimo(), o);\n    }\n\n    private Integer ultimo() {\n        return Integer.valueOf(laPila.size());\n    }\n\n    public T sacarElemento() {\n        return laPila.remove(ultimo());\n    }\n\n    @Override\n    public String toString() {\n        return toString(false);\n    }\n\n    public String toString(boolean verbose) {\n        String cadena = \"\";\n        for (int item = laPila.size()-1; item >= 0; item--) {\n            cadena = cadena.concat(\"\\n\\t- \");\n            if(verbose) {\n                cadena = cadena.concat(Integer.toString(item)).concat(\": \");\n            }\n            cadena = cadena.concat(laPila.get(Integer.valueOf(item)).toString()).concat(\",\");\n        }\n        if (cadena.length() > 0) {\n            cadena = cadena.substring(0, cadena.length() - 1).concat(\"\\n\");\n        }\n        return \"LaPila=[\" + cadena + \"]\";\n    }\n}\n\nclass LaCola<T> {\n    private HashMap<Integer, T> laCola;\n\n    public LaCola() {\n        this.laCola = new HashMap<>();\n    }\n\n    public int totalElementos() {\n        return laCola.size();\n    }\n\n    public void agregarElemento(T o) {\n        laCola.put(ultimo(), o);\n    }\n\n    private Integer ultimo() {\n        return Integer.valueOf(laCola.size());\n    }\n\n    public T sacarElemento() {\n        return laCola.remove(ultimo());\n    }\n\n    @Override\n    public String toString() {\n        return toString(false);\n    }\n\n    public String toString(boolean verbose) {\n        String cadena = \"\";\n        for (int item = 0; item < laCola.size(); item++) {\n            cadena = cadena.concat(\"\\n\\t- \");\n            if(verbose) {\n                cadena = cadena.concat(Integer.toString(item)).concat(\": \");\n            }\n            cadena = cadena.concat(laCola.get(Integer.valueOf(item)).toString()).concat(\",\");\n        }\n        if (cadena.length() > 0) {\n            cadena = cadena.substring(0, cadena.length() - 1).concat(\"\\n\");\n        }\n        return \"LaCola=[\".concat(cadena).concat(\"]\");\n    }\n}\n\n"
  },
  {
    "path": "Roadmap/08 - CLASES/java/JesusAntonioEEscamilla.java",
    "content": "import java.util.ArrayList;\nimport java.util.LinkedList;\nimport java.util.Queue;\n\n/** #07 - Java -> Jesus Antonio Escamilla */\n\npublic class JesusAntonioEEscamilla {\n    public static void main(String[] args) {\n    //---EJERCIÓ---\n        System.out.println(\"CLASES\");\n        Persona persona = new Persona(\"Jesus Antonio\", 24, \"Programador\");\n        persona.imprimirDetalles();\n    //---EXTRA---\n        // Ejemplo con Pila\n        System.out.println(\"\\nSTACK\");\n        Pila<Integer> pila = new Pila<>();\n        pila.apilar(1);\n        pila.apilar(2);\n        pila.apilar(3);\n        pila.imprimir();  // Contenido de la Pila: [1, 2, 3]\n        pila.desapilar();\n        pila.imprimir();  // Contenido de la Pila: [1, 2]\n\n        // Ejemplo con Cola\n        System.out.println(\"\\nQUEUE\");\n        Cola<String> cola = new Cola<>();\n        cola.encolar(\"A\");\n        cola.encolar(\"B\");\n        cola.encolar(\"C\");\n        cola.imprimir();  // Contenido de la Cola: [A, B, C]\n        cola.desencolar();\n        cola.imprimir();  // Contenido de la Cola: [B, C]\n    }\n\n    //---EJERCIÓ---\n    // Definición de la clase Persona\n    static class Persona {\n        // Atributos de la clase\n        private String nombre;\n        private int edad;\n        private String ocupacion;\n\n        // Constructor de la clase Persona\n        public Persona(String nombre, int edad, String ocupacion) {\n            this.nombre = nombre;       // Inicializa el atributo nombre\n            this.edad = edad;           // Inicializa el atributo edad\n            this.ocupacion = ocupacion; // Inicializa el atributo ocupacion\n        }\n\n        // Método para imprimir los atributos de la clase\n        public void imprimirDetalles() {\n            System.out.println(\"Nombre: \" + nombre);\n            System.out.println(\"Edad: \" + edad);\n            System.out.println(\"Profesión: \" + ocupacion);\n        }\n    }\n\n\n\n    /**-----DIFICULTAD EXTRA-----*/\n\n    // Clase Pila (Stack)\n    public static class Pila<T> {\n        private ArrayList<T> elementos;\n\n        public Pila() {\n            elementos = new ArrayList<>();\n        }\n\n        // Agregar un elemento a la pila\n        public void apilar(T elemento) {\n            elementos.add(elemento);\n        }\n\n        // Eliminar el último elemento agregado (pop)\n        public T desapilar() {\n            if (!estaVacia()) {\n                return elementos.remove(elementos.size() - 1);\n            }\n            return null;  // Devuelve null si la pila está vacía\n        }\n\n        // Retornar el número de elementos en la pila\n        public int tamano() {\n            return elementos.size();\n        }\n\n        // Verificar si la pila está vacía\n        public boolean estaVacia() {\n            return elementos.isEmpty();\n        }\n\n        // Imprimir el contenido de la pila\n        public void imprimir() {\n            System.out.println(\"Contenido de la Pila: \" + elementos);\n        }\n    }\n\n    // Clase Cola (Queue)\n    public static class Cola<T> {\n        private Queue<T> elementos;\n\n        public Cola() {\n            elementos = new LinkedList<>();\n        }\n\n        // Agregar un elemento a la cola\n        public void encolar(T elemento) {\n            elementos.add(elemento);\n        }\n\n        // Eliminar el primer elemento (dequeue)\n        public T desencolar() {\n            if (!estaVacia()) {\n                return elementos.poll();  // poll elimina y retorna el primer elemento\n            }\n            return null;  // Devuelve null si la cola está vacía\n        }\n\n        // Retornar el número de elementos en la cola\n        public int tamano() {\n            return elementos.size();\n        }\n\n        // Verificar si la cola está vacía\n        public boolean estaVacia() {\n            return elementos.isEmpty();\n        }\n\n        // Imprimir el contenido de la cola\n        public void imprimir() {\n            System.out.println(\"Contenido de la Cola: \" + elementos);\n        }\n    }\n\n    /**-----DIFICULTAD EXTRA-----*/\n}"
  },
  {
    "path": "Roadmap/08 - CLASES/java/JesusWay69.java",
    "content": "package roadmap.ejercicio_08;\n\nimport java.util.ArrayList;\n\n/*\n* EJERCICIO:\n* Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n* atributos y una función que los imprima (teniendo en cuenta las posibilidades\n* de tu lenguaje).\n* Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n* utilizando su función.\n*\n*/\n\n\npublic class JesusWay69 {\n\n  public static void main(String[] args) {\n\n    Stack stack_instance = new Stack();\n    Queue queue_instance = new Queue();\n    Coche coche_instance = new Coche();\n\n    stack_instance.add(1, 11);\n    stack_instance.show();\n    System.out.println(\"La lista tiene \" + stack_instance.leight() + \" números\\n\");\n    System.out.println(\"Eliminamos el número \" + stack_instance.unstack() + \"\\n\");\n    stack_instance.show();\n    System.out.println(\"La lista tiene \" + stack_instance.leight() + \" números\\n\");\n    \n    queue_instance.add(1, 11);\n    queue_instance.show();\n    System.out.println(\"La lista tiene \" + queue_instance.leight() + \" números\\n\");\n    System.out.println(\"Eliminamos el número \" + queue_instance.dequeue()+ \"\\n\");\n    queue_instance.show();\n    System.out.println(\"La lista tiene \" + queue_instance.leight() + \" números\\n\");\n    \n\n    coche_instance.setMarca(\"Alfa\");\n    coche_instance.setModelo(\"Giulietta\");\n    coche_instance.setMotorizacion(\"diesel\");\n    coche_instance.setCilindrada(2000);\n    coche_instance.setPotencia(170);\n    coche_instance.setTipo_cambio(\"manual 6v\");\n    coche_instance.setCarroceria(\"hachback\");\n    System.out.println(coche_instance.toString());\n    \n    coche_instance.setMarca(\"Toyota\");\n    coche_instance.setModelo(\"Corolla\");\n    coche_instance.setMotorizacion(\"híbrido\");\n    coche_instance.setCilindrada(1800);\n    coche_instance.setPotencia(140);\n    coche_instance.setTipo_cambio(\"variador cvt\");\n    coche_instance.setCarroceria(\"sedán\");\n    System.out.println(coche_instance.toString());\n    \n    \n\n  }\n\n}\n\n\nclass Coche {\n    \n    private String marca;\n    private String modelo;\n    private String motorizacion;\n    private int cilindrada;\n    private int potencia;\n    private String tipo_cambio;\n    private String carroceria;\n    \n    public Coche(){ \n    }\n\n    public void setMarca(String marca) {\n        this.marca = marca;\n    }\n\n    public void setModelo(String modelo) {\n        this.modelo = modelo;\n    }\n\n    public void setMotorizacion(String motorizacion) {\n        this.motorizacion = motorizacion;\n    }\n\n    public void setCilindrada(int cilindrada) {\n        this.cilindrada = cilindrada;\n    }\n\n    public void setPotencia(int potencia) {\n        this.potencia = potencia;\n    }\n\n    public void setTipo_cambio(String tipo_cambio) {\n        this.tipo_cambio = tipo_cambio;\n    }\n\n    public void setCarroceria(String carroceria) {\n        this.carroceria = carroceria;\n    }\n    \n\n\n    @Override\n    public String toString() {\n        return \"Objeto Coche:\\nMarca = \" + marca + \"\\nModelo = \" + modelo + \"\\nMotorización = \" + motorizacion+  \"\\nCilindrada = \" \n      + cilindrada + \"CC\"+ \"\\nPotencia = \" + potencia + \"CV\"+ \"\\nCambio = \" + tipo_cambio + \"\\nCarrocería = \" + carroceria + \"\\n\";\n    }\n   \n    \n}\n\n/*\n* DIFICULTAD EXTRA (opcional):\n* Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n* en el ejercicio número 7 de la ruta de estudio)\n* - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n*   retornar el número de elementos e imprimir todo su contenido.\n*/\n\nclass Stack {\n\n  public ArrayList my_stack_list;\n\n  public Stack() {\n    my_stack_list = new ArrayList<>();\n\n  }\n\n  public void add(int init_num, int end_num) {\n    for (int i = init_num; i < end_num; i++)  my_stack_list.add(i);\n  }\n\n  public int unstack() {\n    return Integer.parseInt(my_stack_list.remove(my_stack_list.size() - 1).toString());\n  }\n\n  public int leight() {\n    return my_stack_list.size();\n  }\n\n  public void show() {\n    System.out.println(my_stack_list);\n  }\n\n}\n\nclass Queue {\n\n  public ArrayList my_stack_list;\n\n  public Queue() {\n    my_stack_list = new ArrayList<>();\n  }\n\n  public void add(int init_num, int end_num) {\n    for (int i = init_num; i < end_num; i++)  my_stack_list.add(i);\n  }\n\n  public int dequeue() {\n   return Integer.parseInt(my_stack_list.remove(0).toString());\n  }\n\n  public int leight() {\n    return my_stack_list.size();\n  }\n\n  public void show() {\n    System.out.println(my_stack_list);\n  }\n\n}"
  },
  {
    "path": "Roadmap/08 - CLASES/java/JimsimroDev.java",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n */\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\n\n/**\n * JimsimroDev\n */\n// La convencion en java para crear una clase es que la primera letra de cada\n// palabra sea en mayusculas\npublic class JimsimroDev {\n\n  // Declarion de los atributos de la clase\n  private String nombre;\n  private int edad;\n  private List<String> stackTecnologico;\n\n  // Metodo constructo vacio\n  public JimsimroDev() {\n  }\n\n  // Metodo o constructo con parametros para inicializar sus atributos\n  public JimsimroDev(String nombre, int edad, List<String> stackTecnologico) {\n    this.nombre = nombre;\n    this.edad = edad;\n    this.stackTecnologico = stackTecnologico;\n  }\n\n  // función para imprimir sus atributos\n  public void print() {\n    System.out.printf(\"Nombre: %s Edad: %d Stack Tecnologico: %s\",\n        nombre,\n        edad,\n        stackTecnologico);\n    System.out.println();\n  }\n\n  // EXTRA Clase para la crear Pila\n  public class Stack<T> {\n    private List<T> dato;\n    private int posicion = -1;\n\n    public Stack() {\n      dato = new ArrayList<>();\n    }\n\n    public void push(T elemento) {\n      posicion++;\n      dato.add(elemento);\n    }\n\n    public T pop() {\n      if (dato.isEmpty())\n        throw new IllegalStateException(\"None\");\n\n      Collections.reverse(dato);\n      T resultado = dato.get(posicion);\n      dato.remove(posicion);\n      posicion--;\n      return resultado;\n    }\n\n    public T peek() {\n      if (dato.isEmpty()) {\n        throw new IllegalStateException(\"La pila esta vacia\");\n      } else {\n        return (T) dato.get(posicion);\n      }\n    }\n\n    public void print() {\n      System.out.println(\"Cantidad de elemento en la pila \" + dato.size());\n      Collections.reverse(dato);\n      System.out.println(dato);\n    }\n  }\n\n  public class Queue<T> {\n    private List<T> queue;\n    private int ps = -1;\n\n    public Queue() {\n      queue = new ArrayList<>();\n    }\n\n    public void push(T elemento) {\n      ps++;\n      queue.add(elemento);\n    }\n\n    public T pop() {\n      T resul = queue.remove(0);\n      return resul;\n    }\n\n    public void imprimir() {\n      System.out.println(\"Cantidad de elemento en la cola \" + queue.size());\n      System.out.println(queue);\n    }\n  }\n\n  public static void main(String[] args) {\n\n    List<String> tecnologias = new ArrayList<>() {\n      {\n        add(\"Java\");\n        add(\"Spring\");\n        add(\"GIT\");\n        add(\"Doker\");\n        add(\"MySQL\");\n        add(\"nvim\");\n      }\n    };\n    // Creacion del objeto o istancia\n    // Lo puedeo istanciar sin ninguna dato con el constructor vacio\n    JimsimroDev ingeniero = new JimsimroDev();\n    ingeniero.print();\n    // Lo instancio con datos con el constructor que tiene parametros\n    JimsimroDev ingenieroBackend = new JimsimroDev(\"JimsimroDev\", 28, tecnologias);\n    ingenieroBackend.print();\n    ingenieroBackend.edad = 30;// Modifico su edad\n    ingenieroBackend.print();\n\n    JimsimroDev.Stack<String> stack = ingeniero.new Stack<>();\n\n    stack.push(\"Elemento 1\");\n    stack.push(\"Elemento 2\");\n    stack.push(\"Elemento 3\");\n    stack.push(\"Elemento 4\");\n\n    // Imprime la posicion del ultimi elemento\n    System.out.println(stack.peek());\n    stack.print();// Inprime la Cantidad de elemento que tiene\n    stack.pop();\n    System.out.println(stack.peek());\n    stack.print();\n\n    JimsimroDev.Queue<String> queue = ingeniero.new Queue<>();\n\n    queue.push(\"Elemento 1\");\n    queue.push(\"Elemento 2\");\n    queue.push(\"Elemento 3\");\n    queue.push(\"Elemento 4\");\n    queue.imprimir();\n    queue.pop();\n    queue.imprimir();\n    queue.pop();\n  }\n}\n"
  },
  {
    "path": "Roadmap/08 - CLASES/java/Josegs95.java",
    "content": "import java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.List;\n\npublic class Josegs95 {\n    public static void main(String[] args) {\n        //Clases\n        Persona p1 = new Persona(\"Jose\", 29); //Crea un objeto 'p1' de la clase persona\n        Persona p2 = new Persona(\"María\", 27);\n        Persona p3 = new Persona(\"Alberto\", 41);\n\n        System.out.println(\"p1: \" + p1); //Out: 'p1: Nombre: Jose, edad: 29 años.'\n        System.out.println(\"p2: \" + p2); //Out: 'p2: Nombre: María, edad: 27 años.'\n        System.out.println(\"p3: \" + p3); //Out: 'p3: Nombre: Alberto, edad: 41 años.'\n\n        p3.setName(\"Juan Alberto\");\n\n        System.out.println(\"p3: \" + p3); //Out: 'p3: Nombre: Juan Alberto, edad: 41 años.'\n\n        //Reto\n        System.out.println(\"\\n\");\n        retoFinal();\n    }\n\n    public static void retoFinal(){\n        //Pila\n        My_Stack<String> stack = new My_Stack<>();\n        System.out.println(stack); //Out: 'Stack: []'\n\n        stack.push(\"Element 1\");\n        stack.push(\"Element 2\");\n        stack.push(\"Element 3\");\n        stack.print(); //Out: '[Element 3] [Element 2] [Element 1]'\n        System.out.println(stack); //Out: 'Stack: [Element 1, Element 2, Element 3]'\n\n        System.out.println(stack.pop()); //Out: 'Element 3'\n        stack.print(); //Out: '[Element 2] [Element 1]'\n        System.out.println(stack); //Out: 'Stack: [Element 1, Element 2]'\n\n        System.out.println(\"\\n\\n\");\n        //Cola\n        My_Queue<String> queue = new My_Queue<>();\n        System.out.println(queue); //Out: 'Queue: []'\n\n        queue.add(\"Element 1\");\n        queue.add(\"Element 2\");\n        queue.add(\"Element 3\");\n        queue.print(); //Out: '[Element 1] [Element 2] [Element 3]'\n        System.out.println(queue); //Out: 'Queue: [Element 1, Element 2, Element 3]'\n\n        System.out.println(queue.poll()); //Out: 'Element 1'\n        queue.print(); //Out: '[Element 2] [Element 3]'\n        System.out.println(queue); //Out: 'Queue: [Element 2, Element 3]'\n    }\n\n    public static class Persona{\n        private String name;\n        private int age;\n\n        Persona(String name, int age){\n            this.name = name;\n            this.age = age;\n        }\n\n        public String getName() {\n            return name;\n        }\n\n        public void setName(String name) {\n            this.name = name;\n        }\n\n        public int getAge() {\n            return age;\n        }\n\n        public void setAge(int age) {\n            this.age = age;\n        }\n\n        @Override\n        public String toString(){\n            return \"Nombre: \" + name + \", edad: \" + age + \" años.\";\n        }\n    }\n\n    //Reto\n    public static class My_Stack<E>{\n        List<E> elements;\n\n        public  My_Stack(Collection<E> collection){\n            if (collection == null)\n                elements = new ArrayList<>();\n            else\n                elements = new ArrayList<>(collection);\n        }\n        public My_Stack(){\n            this(null);\n        }\n\n        public E push(E element){\n            elements.add(element);\n            return element;\n        }\n\n        public E pop(){\n            if (size() == 0)\n                return null;\n\n            return elements.remove(size() - 1);\n        }\n\n        public int size(){\n            return elements.size();\n        }\n\n        public void print(){\n            List<E> cloneList = new ArrayList<>(elements);\n            Collections.reverse(cloneList);\n            for (E element : cloneList)\n                System.out.print(\"[\" + element + \"] \");\n            System.out.println();\n        }\n\n        @Override\n        public String toString() {\n            return \"Stack: \" + elements.toString();\n        }\n    }\n\n    public static class My_Queue<E>{\n        List<E> elements;\n\n        public  My_Queue(Collection<E> collection){\n            if (collection == null)\n                elements = new ArrayList<>();\n            else\n                elements = new ArrayList<>(collection);\n        }\n        public My_Queue(){\n            this(null);\n        }\n\n        public E add(E element){\n            elements.add(element);\n            return element;\n        }\n\n        public E poll(){\n            if (size() == 0)\n                return null;\n\n            return elements.remove(0);\n        }\n\n        public int size(){\n            return elements.size();\n        }\n\n        public void print(){\n            for (E element : elements)\n                System.out.print(\"[\" + element + \"] \");\n            System.out.println();\n        }\n\n        @Override\n        public String toString() {\n            return \"Queue: \" + elements.toString();\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/08 - CLASES/java/Qv1ko.java",
    "content": "class Qv1ko {\n\n    public static void main(String[] args) {\n        \n        C1 example1 = new C1();\n        System.out.println(example1.toString());\n        example1.setC1String(\"Example 1\");\n        System.out.println(example1.getC1String());\n\n        C2 example2 = new C2();\n        System.out.println(example2.toString());\n        example2.setC2String(\"Example 2\");\n        System.out.println(example2.getC2String());\n\n    }\n\n}\n\nclass C1 {\n\n    String c1String;\n\n    C1() {\n        this.c1String = \"example\";\n    }\n\n    C1(String value) {\n        this.c1String = value;\n    }\n\n    public String getC1String() {\n        return c1String;\n    }\n\n    public void setC1String(String c1String) {\n        this.c1String = c1String;\n    }\n\n    @Override\n    public String toString() {\n        return \"Class 1 value: \" + c1String;\n    }\n    \n}\n\nclass C2 {\n\n    String c2String;\n\n    C2() {\n        this.c2String = \"example\";\n    }\n\n    C2(String value) {\n        this.c2String = value;\n    }\n\n    public String getC2String() {\n        return c2String;\n    }\n\n    public void setC2String(String c2String) {\n        this.c2String = c2String;\n    }\n\n    @Override\n    public String toString() {\n        return \"Class 2 value: \" + c2String;\n    }\n    \n}\n"
  },
  {
    "path": "Roadmap/08 - CLASES/java/RodrigoGit87.java",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n * \n */\nimport java.util.Stack;\nimport java.util.LinkedList;\n\npublic class RodrigoGit87 {\n    private String nombre, genero;\n    private int edad;\n    private boolean esHumano;\n\n    // Constructor\n    public RodrigoGit87(String nombre, String genero, int edad, boolean esHumano) {\n        this.nombre = nombre;\n        this.genero = genero;\n        this.edad = edad;\n        this.esHumano = esHumano;\n    }\n\n    // Getters y Setters\n    public String getNombre() {\n        return nombre;\n    }\n\n    public void setNombre(String nombre) {\n        this.nombre = nombre;\n    }\n\n    public String getGenero() {\n        return genero;\n    }\n\n    public void setGenero(String genero) {\n        this.genero = genero;\n    }\n\n    public int getEdad() {\n        return edad;\n    }\n\n    public void setEdad(int edad) {\n        this.edad = edad;\n    }\n\n    public boolean isEsHumano() {\n        return esHumano;\n    }\n\n    public void setEsHumano(boolean esHumano) {\n        this.esHumano = esHumano;\n    }\n\n    // metodo\n    public void mostrarDatos() {\n        System.out.println(\"Nombre: \" + nombre);\n        System.out.println(\"Genero: \" + genero);\n        System.out.println(\"Edad: \" + edad);\n        System.out.println(\"Es Humano: \" + esHumano);\n    }\n\n    public static void main(String[] args) {\n        // Instanciar\n        var usuario = new RodrigoGit87(\"RodrigoGit87\", \"hombre\", 38, true);\n\n        // llamada a metodo\n        usuario.mostrarDatos();\n\n        System.out.println(\"---------------\");\n\n        // Modificar atributos\n        usuario.setNombre(\" Rodrigo \");\n        usuario.setGenero(\" Gigachad \");\n\n        // Ver valores modificados\n        System.out.println(\"Cambiado genero a : \" + usuario.getGenero());\n        System.out.println(\"Cambiado nombre a : \" + usuario.getNombre());\n\n        //-- EXTRA --\n        System.out.println(\"\\n--- EXTRA - PILA ---\");\n        var pila = new Pila();\n        pila.pushx10();\n        pila.push(50);\n        System.out.println(\n                \" \\nHasta aqui se han añadido 10 numeros con el metodo pushx10() y 1 numero con el metodo push(). Hay \"\n                        + pila.size() + \" elementos en total\");\n        pila.pop();\n        System.out.println(\n                \" \\nNotar como el metodo pop() elimina el ultimo elemento añadido pero de ambos metodos push (el del push normal y el pushx10)- habia 11 elementos, ahora: \"\n                        + pila.size());\n        pila.mostrar();\n\n        System.out.println(\"\\n--- EXTRA - COLA ---\");\n        var cola = new Cola();\n        cola.add(\"Hola\");\n        cola.add(\"Mundo\");\n        cola.add(\"soy\");\n        cola.add(\"RodrigoGit87\");\n        cola.add(\"!\");\n        System.out.println(\" Elementos en la cola: \" + cola.size() +\" --> \" + cola);\n        System.out.println(\" Elemento eliminado: \" + cola.pop() + \" <-- .pop() en una linkedlist elimina el primer elemento\" );\n        \n\n    }\n\n    // --- EXTRA ---\n    // STACK (lifo)\n    public static class Pila {\n        private Stack<Integer> pila;\n\n        public Pila() {\n            this.pila = new Stack<>();\n        };\n\n        /*\n         * Como he creado la clase Pila, aunque el constructor instancia un ' new Stack\n         * ', al ser una clase aislada, no hereda los metodos de java.util.Stack (push,\n         * pop, size ...)\n         * - Para q la instancia use los metodos propios de la clase Stack, usamos un\n         * wrapper de los metodos push, pop, .... Es decir, crear una función en esta\n         * clase que 'conecte' con los\n         * metodos propios de la clase Stack\n         */\n\n        // Metodos push\n        public void push(int numero) {\n            System.out.println(\"pusheado: \" + numero);\n            pila.push(numero);\n        }\n\n        public void pushx10() {\n\n            for (int n = 1; n <= 10; n++) {\n                pila.push(n);\n            }\n            System.out.println(\" 10 numeros consecutivos añadidos a la lista\");\n        }\n\n        // Metodo pop (tiene q retornar)\n        public Integer pop() {\n            if (pila.isEmpty()) {\n                System.out.println(\"La pila está vacía.\");\n                return null;\n            }\n            System.out.println(\" Elemento pop eliminado: \" + pila.pop());\n            return pila.pop();\n        }\n\n        // Metodo size\n        public int size() {\n            System.out.println(\" Tamaño de la pila: \" + pila.size());\n            return pila.size();\n        }\n\n        // mostrar elementos\n        public void mostrar() {\n            System.out.println(\" Elemntos en la pila: \" + pila);\n        }\n    }\n\n    // QUEUE (fifo)\n    // Como he dicho antes, sin herencia, no hay metodos propios. para ahorrarse tener q wrappear, uso la herencia.\n    public static class Cola extends LinkedList<String> {\n\n        // Constructor\n        public Cola() {\n            super(); // Inicializa la propia lista heredada\n        }\n    }\n    \n    // La clase Cola ES una LinkedList, no necesita wrappear metodos, por q ya los hereda.\n    // La clase Pila TIENE un Stack, pero no hereda sus metodos, por eso se crean metodos wrapeables\n\n}"
  },
  {
    "path": "Roadmap/08 - CLASES/java/RoniPG.java",
    "content": "import java.util.LinkedList;\nimport java.util.Queue;\nimport java.util.Stack;\n\n// @Roni\n/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n */\nclass Iguana{\n\tprivate String genero;\n\tprivate String endemico;\n\tprivate String especie;\n\tpublic Iguana(String genero, String endemico, String especie){\n\t\tthis.genero=genero;\n\t\tthis.endemico=endemico;\n\t\tthis.especie=especie;\n\t}\n\tpublic Iguana(){\n\t\tthis.genero=\"\";\n\t\tthis.endemico=\"\";\n\t\tthis.especie=\"\";\n\t}\n\tpublic String getGenero() {\n\t\treturn genero;\n\t}\n\tpublic void setGenero(String genero) {\n\t\tthis.genero = genero;\n\t}\n\tpublic String getEndemico() {\n\t\treturn endemico;\n\t}\n\tpublic void setEndemico(String endemico) {\n\t\tthis.endemico = endemico;\n\t}\n\tpublic String getEspecie() {\n\t\treturn especie;\n\t}\n\tpublic void setEspecie(String especie) {\n\t\tthis.especie = especie;\n\t}\n\tpublic void print() {\n\t\tSystem.out.println(\"Genero: \"+this.genero+ \"\\nEndemico: \"+this.endemico+\"\\nEspecie :\"+this.especie);\n\t}\n}\npublic class CLASES_08{\n\t\n\tpublic static void main(String[] args) {\n\t\t\n\t\tIguana ig1 = new Iguana(); // --> Instanciamos/Incicalizamos la clase\n\t\t/*Le asignamos los valores*/\n\t\tSystem.out.println(\"****IGUANA****\");\n\t\tig1.setGenero(\"Macho\");\n\t\tig1.setEndemico(\"Sudamerica\");\n\t\tig1.setEspecie(\"Iguana\");\n\t\tig1.print(); // --> Llamamos al método que nos devolvera los valores\t\t\n\t\tSystem.out.println(\"****PILA****\");\n\t\tPila pila = new Pila(); // --> Instanciamos/Incicalizamos la clase\n\t\t/*Le asignamos los valores*/\n\t\tpila.añadirDatos(1);\t\tpila.añadirDatos(2);\t\tpila.añadirDatos(3);\n\t\tSystem.out.println(\"El número de elementos es: \"+pila.numeroDeElementos()); // --> Imprimimos números de elementos\n\t\tSystem.out.print(\"Su contenido es:\\n\"); pila.print(); // --> Imprimimos todos los datos\n\t\tpila.elminarDatos(); // --> Eliminamos elemento de arriba de la pila\n\t\tSystem.out.println(\"El número de elementos despúes de pila.elminarDatos(): \"+pila.numeroDeElementos());\n\t\tSystem.out.print(\"Su contenido despúes de pila.elminarDatos():\\n\"); pila.print();\n\t\tpila.elminarDatos();\n\t\tpila.elminarDatos();\n\t\tpila.elminarDatos(); // --> Salta el aviso\n\t\tSystem.out.println(\"****COLA****\");\n\t\tCola cola= new Cola(); // --> Instanciamos/Incicalizamos la clase\n\t\t/*Le asignamos los valores*/\n\t\tcola.añadirDatos(\"Elemento 0\");\t\tcola.añadirDatos(\"Elemento 1\");\t\tcola.añadirDatos(\"Elemento 2\");\n\t\tSystem.out.println(\"El número de elementos es: \"+cola.numeroDeElementos()); // --> Imprimimos números de elementos\n\t\tSystem.out.print(\"Su contenido es:\\n\"); cola.print(); // --> Imprimimos todos los datos\n\t\tcola.elminarDatos(); // --> Eliminamos elemento de la cabeza de la cola\n\t\tSystem.out.println(\"El número de elementos despúes de cola.elminarDatos(): \"+cola.numeroDeElementos());\n\t\tSystem.out.print(\"Su contenido despúes de cola.elminarDatos():\\n\"); cola.print();\n\t\tcola.elminarDatos();\n\t\tcola.elminarDatos();\n\t\tcola.elminarDatos(); // --> Salta el aviso\n\t}\n}\n /*\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola \n * (estudiadas en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n */\nclass Pila{\n\tprivate Stack<Integer> datos;\n\tpublic Pila() {\n\t this.datos=new Stack<>();\n\t}\n\tpublic void añadirDatos(int dato) {\n\t\tthis.datos.push(dato);\n\t}\n\tpublic void elminarDatos() {\n\t\tif (!datos.empty()) {\n\t\t\tthis.datos.pop();\n\t\t}else {\n\t\t\tSystem.out.println(\"La pila esta vacía\");\n\t\t}\t\t\n\t}\n\tpublic int numeroDeElementos() {\n\t\treturn datos.size();\n\t}\n\tpublic void print() {\n\t\tint i=0;\n\t\tfor (Integer dato : datos) {\n\t\t\ti++;\n\t\t\tSystem.out.println(\"Dato \"+i+\"= \"+dato);\n\t\t}\n\t}\n}\nclass Cola{\n\tprivate Queue<String> datos;\n\tpublic Cola() {\n\t this.datos=new LinkedList<>();\t\n\t}\n\tpublic void añadirDatos(String dato) {\n\t\tthis.datos.offer(dato); // --> También podríamos utilizar datos.add(dato);\n\t}\n\tpublic void elminarDatos() {\n\t\tif (!datos.isEmpty()) {\n\t\t\tthis.datos.poll();\n\t\t}else {\n\t\t\tSystem.out.println(\"La pila esta vacía\");\n\t\t}\t\t\n\t}\n\tpublic int numeroDeElementos() {\n\t\treturn datos.size();\n\t}\n\tpublic void print() {\n\t\tint i=0;\n\t\tfor (String dato : datos) {\n\t\t\ti++;\n\t\t\tSystem.out.println(\"Dato \"+i+\"= \"+dato);\n\t\t}\n\t}\t\n}\n"
  },
  {
    "path": "Roadmap/08 - CLASES/java/TofeDev.java",
    "content": "import java.util.LinkedList;\nimport java.util.Queue;\nimport java.util.Stack;\n\npublic class TofeDev {\n    public static void main(String[] args) {\n        Persona usuario1 = new Persona(\"Santiago Rodriguez\", \"Chile\", 25);\n        Persona usuario2 = new Persona();\n        usuario2.setNombre(\"Marta Gonzales\");\n        usuario2.setPais(\"Argentina\");\n        usuario2.setEdad(28);\n\n        System.out.println(usuario1.info());\n        System.out.println(usuario2.info());\n\n        // *EXTRA*\n        // Pila\n        Pila pila = new Pila();\n        // Añadir elementos\n        pila.agregarElementoPila(\"Cajas\");\n        pila.agregarElementoPila(\"Libros\");\n        pila.agregarElementoPila(\"Botellas\");\n        // Eliminar elemento\n        pila.eleminarElementoPila();\n        // Ver elementos\n        pila.verElementosPila();\n        // Ver tamaño\n        pila.sizePila();\n        System.out.println(\"\");\n        // Cola\n        Cola cola = new Cola();\n        // Agregar elementos\n        cola.agregarElementoCola(1);\n        cola.agregarElementoCola(2);\n        cola.agregarElementoCola(3);\n        // Elimianr elementos\n        cola.eleminarElementoCola();\n        // Ver elementos\n        cola.verElementosCola();\n        // Ver tamaño\n        cola.sizeCola();\n    }\n\n    static class Persona {\n        private String nombre;\n        private String pais;\n        private int edad;\n\n        public Persona(String nombre, String pais, int edad) {\n            this.nombre = nombre;\n            this.pais = pais;\n            this.edad = edad;\n        }\n\n        public Persona() {\n\n        }\n\n        //Getters\n        public String getNombre() {\n            return nombre;\n        }\n        public String getPais() {\n            return pais;\n        }\n        public int getEdad() {\n            return edad;\n        }\n\n        //Setters\n        public void setNombre(String nombre) {\n            this.nombre = nombre;\n        }\n        public void setPais(String pais) {\n            this.pais = pais;\n        }\n        public void setEdad(int edad) {\n            this.edad = edad;\n        }\n\n        public String info() {\n            return \"--Información del Usuario-- \" + \"\\n\" +\n                    \"Nombre: \" + nombre + \"\\n\" +\n                    \"Pais: \" + pais + \"\\n\" +\n                    \"Edad: \" + edad + \" años\";\n        }\n    }\n\n    /* DIFICULTAD EXTRA (opcional):\n     * Implementa dos clases que representen las estructuras de Pila y Cola\n     * (estudiadas en el ejercicio número 7 de la ruta de estudio)\n     * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n     * retornar el número de elementos e imprimir todo su contenido.\n     */\n\n    static class Pila {\n        private Stack<String> pila;\n\n        public Pila(){\n            this.pila = new Stack<>();\n        }\n\n        public void agregarElementoPila(String elemento){\n            this.pila.push(elemento);\n        }\n\n        public void eleminarElementoPila(){\n            this.pila.pop();\n        }\n\n        public void verElementosPila(){\n            System.out.println(\"Elementos de la pila: \");\n            for (String elemento : this.pila) {\n                System.out.println(elemento);\n            }\n        }\n\n        public void sizePila(){\n            System.out.print(\"Tamaño de pila: \" + pila.size());\n        }\n\n    }\n\n    static class Cola {\n\n        private Queue<Integer> cola;\n\n        public Cola(){\n            this.cola = new LinkedList<>();\n        }\n\n\n        public void agregarElementoCola(Integer elemento){\n            this.cola.add(elemento);\n        }\n\n        public void eleminarElementoCola(){\n            this.cola.poll();\n        }\n\n        public void verElementosCola(){\n            System.out.println(\"Elementos de la cola\");\n            for (Integer elementos : cola) {\n                System.out.println(elementos);\n            }\n        }\n\n        public void sizeCola(){\n            System.out.print(\"Tamaño de la cola: \" + cola.size());\n        }\n        \n    }\n\n}\n"
  },
  {
    "path": "Roadmap/08 - CLASES/java/Worlion.java",
    "content": "import java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.LinkedList;\nimport java.util.List;\n\npublic class Worlion {\n\n\n/*\n * EJERCICIO: Clases en JAVA\n */\n    class Developer {\n        private String name =\"\";\n        private int age = 0;\n        private List<String> languages = new ArrayList<>();\n\n        public Developer(String name, int age, Collection<String> languages){\n            this.name = name;\n            this.age = age;\n            this.languages.addAll(languages);\n        }\n\n        public void addLanguage(String newLanguage) {\n            if(!this.languages.contains(newLanguage)) {\n                this.languages.add(newLanguage);\n            }\n        }\n\n        public String toString() {\n            StringBuilder s = new StringBuilder(\"\\\"Developer\\\": {\");\n\n            s.append(\"\\n\\t\\\"this.name\\\": \\\"\" + this.name + \"\\\",\");\n            s.append(\"\\n\\t\\\"this.age\\\": \\\"\" + this.age + \"\\\",\");\n            s.append(\"\\n\\t\\\"this.languages\\\": \" + this.languages );\n            s.append(\"\\n}\");\n\n            return s.toString();\n        }\n    }\n\n/*\n * DIFICULTAD EXTRA (opcional):\n */\n\n\nclass Stack<T> {\n    private List<T> stack = new LinkedList<T>();\n\n    public T pop() {\n        if(stack.isEmpty()) {\n            //throw new Exception(\"Pila vacia!\");\n            System.err.println(\"Pila vacia!\");\n            return null;\n        }\n        T element = stack.getLast();\n        stack.removeLast();\n        return element;\n    }\n\n    public void push(T element) {\n        stack.add(element);\n    }\n\n    public void printStack() {\n        System.out.println(\"Stack content:\" + stack);\n    }\n\n    public int size() {\n        return stack.size();\n    }\n\n    public boolean isEmpty() {\n        return stack.isEmpty();\n    }\n\n    public T top(){\n        return stack.getLast();\n    }\n\n    public void clear() {\n        stack.clear();\n    }\n\n    public String toString() {\n        return stack.toString();\n    }\n}\n\nclass Queue<T> {\n    private List<T> queue = new LinkedList<T>();\n\n    public T get() {\n        if(queue.isEmpty()) {\n            //throw new Exception(\"Pila vacia!\");\n            System.err.println(\"Cola vacia!\");\n            return null;\n        }\n        T element = queue.getFirst();\n        queue.remove(0);\n        return element;\n    }\n    \n    public void put(T element) {\n        queue.add(element);\n    }\n\n    public void printQueue() {\n        System.out.println(\"Queue content:\" + queue);\n    }\n\n    public int size(){\n        return queue.size();\n    }\n\n    public boolean isEmpty() {\n        return queue.isEmpty();\n    }\n\n    public String toString() {\n        return queue.toString();\n    }\n}\n\n    public static void main(String[] args) {\n        new Worlion().run();\n    }\n\n    public void run() {\n    \n        Developer me = new Developer(\"Worlion\", 40, List.of(\"Java\", \"Python\"));\n        System.out.println(me);\n\n        testQueueAndStack();\n    }\n\n    private void testQueueAndStack() {\n\n        System.out.println(\" \\n ---- 🌩 DIFICULTAD EXTRA 🌩 ----\\n\");\n        \n        String[] values = {\"A\", \"B\", \"C\", \"D\"};\n\n        Queue<String> queue = new Queue<>();\n        Stack<String> stack = new Stack<>();\n\n        for(String s: values) {\n            queue.put(s);\n            stack.push(s);\n        }\n        System.out.println(\"Contenido de la cola: \"+queue);\n        System.out.println(\"Contenido de la pila: \"+stack);\n\n        int i = 0;\n        int errorCount = 0;\n\n        while(!queue.isEmpty()) {\n            if(!values[i++].equals(queue.get())) {\n                System.out.println(\"Este no coincide (\"+i+\") en la cola!\");\n                errorCount++;\n            }\n        }\n        \n        if(errorCount == 0) {\n            System.out.println(\"Cola sin errores\");\n        }\n\n        i = values.length-1;\n        errorCount = 0;\n        while (!stack.isEmpty()) {\n            if(!values[i--].equals(stack.pop())) {\n                System.out.println(\"Este no coincide (\"+i+\") en la pila!\");\n                errorCount++;\n            }\n        }\n                \n        if(errorCount == 0) {\n            System.out.println(\"Pila sin errores\");\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/08 - CLASES/java/alexdevrep.java",
    "content": "package _08_Clases;\nimport java.util.LinkedList;\nimport java.util.Stack;\nimport java.util.Queue;\n/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n */\n\n\npublic class _08_Clases {\n    public String Nombre;\n    public String Saludo;\n\n    //Creamos el constructor de la clase\n    public _08_Clases(){\n        this.Nombre= \"\";\n        this.Saludo=\"\";\n\n    }\n    //Vamos a crear una función que nos imprima el Saludo\n    public void saludar(){\n        System.out.println(this.Saludo+\",\"+this.Nombre);\n    }\n    public static void main(String[] args){\n        //Creamos una nueva instancia\n        _08_Clases saludo1 = new _08_Clases();\n\n        //Asignamos valores a los atributos\n        saludo1.Nombre=\"Java\";\n        saludo1.Saludo=\"Hola\";\n\n        //Llamamos a la función saludar\n        saludo1.saludar();\n\n        //Modificamos los atributos\n        saludo1.Nombre=\"ALexdevrep\";\n        saludo1.saludar();\n\n        //Dificultad EXTRA Pilas\n\n        Pila miPila = new Pila();\n\n        //Añadimos elementos a la pila\n        miPila.anadirElemento(\"Objeto 1\");\n        miPila.anadirElemento(\"Objeto 2\");\n        miPila.anadirElemento(\"Objeto 3\");\n\n        //Imprimimos los elementos que tenemos en la pila\n        miPila.imprimirelementos();\n\n        //Eliminamos el último elemento en entrar a la pila\n        miPila.borrarElemento();\n\n        //Imprimimos el resultado\n        miPila.imprimirelementos();\n\n        //Comprobamos que el número de elementos es el correcto\n        int numero= miPila.numeroelementos();\n        System.out.println(\"El número de elementos de la pila es: \"+numero);\n\n        //Dificultad EXTRA Colas\n\n        Colas miCola = new Colas();\n\n        //Añadimos objetos a la cola\n        miCola.insertarObjetos(\"Objeto 1\");\n        miCola.insertarObjetos(\"Objeto 2\");\n        miCola.insertarObjetos(\"Objeto 3\");\n\n        //Imprimimos el resultado\n        miCola.imprimirObjetos();\n\n        //Elimimamos el primer objeto en entrar a la cola\n        miCola.borrarObjetos();\n        miCola.imprimirObjetos();\n\n        //Comprobamos que el número de objetos es el correcto\n         int numeroObjetos=miCola.numeroObjetos();\n         System.out.println(\"El número de objetos que hay en la cola es: \"+numeroObjetos);\n\n\n\n\n\n\n\n    }\n\n\n}\n\nclass Pila {\n\n    private Stack<String> pilaelementos ;\n\n    public Pila(){\n\n        this.pilaelementos= new Stack<>();\n\n    }\n    //Añadimos un elemento a la pila\n    public void anadirElemento(String ELemento){\n        this.pilaelementos.push(ELemento);\n\n    }\n    //Borramos el último elemento de la pila\n    public void borrarElemento(){\n        this.pilaelementos.pop();\n    }\n    //Método para imprimir los elementos que hay en la pila\n    public void imprimirelementos(){\n        System.out.println(\"Contenido de la pila\");\n        for(String elemento : this.pilaelementos){\n            System.out.println(elemento);\n        }\n    }\n    //Método para saber el número de elementos que hay en la pila\n    public int numeroelementos(){\n        return this.pilaelementos.size();\n    }\n\n\n}\n\nclass Colas {\n    private Queue<String> colaObjetos;\n\n    public Colas(){\n        this.colaObjetos= new LinkedList<>();\n\n    }\n    public void insertarObjetos(String Objeto){\n        this.colaObjetos.add(Objeto);\n    }\n    public void borrarObjetos(){\n        this.colaObjetos.poll();\n    }\n    public void imprimirObjetos(){\n        System.out.println(\"Contenido de la cola\");\n        for(String Objeto : this.colaObjetos) {\n            System.out.println(Objeto);\n        }\n\n    }\n    public int numeroObjetos(){\n        return this.colaObjetos.size();\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/08 - CLASES/java/asjordi.java",
    "content": "import java.util.LinkedList;\n\npublic class Main {\n\n    /**\n     * Una clase es una plantilla que permite crear objetos de un tipo determinado.\n     * Un objeto representa una entidad del mundo real.\n     * Por lo que, una clase posee atributos (propiedades) y métodos (funciones).\n     * Para utilizar una clase es necesario crear una instancia de la misma.\n     */\n\n    public static void main(String[] args) {\n\n        // Crear una instancia de la clase Persona\n        Persona persona = new Persona(\"Pedrito\", 20);\n\n        // Acceder a los atributos de la clase Persona\n        System.out.println(\"Nombre: \" + persona.getNombre());\n        System.out.println(\"Edad: \" + persona.getEdad());\n\n        // Modificar los atributos de la clase Persona\n        persona.setNombre(\"Juanito\");\n        persona.setEdad(25);\n\n        // Ejecutar métodos de la clase Persona\n        persona.caminar();\n        persona.hablar();\n\n        // Imprimir el objeto\n        System.out.println(persona);\n\n\n        Cola<String> cola = new Cola<>();\n        cola.agregar(\"Elemento 1\");\n        cola.agregar(\"Elemento 2\");\n        cola.agregar(\"Elemento 3\");\n\n        cola.imprimir();\n\n        Pila<Integer> pila = new Pila<>();\n        pila.agregar(1);\n        pila.agregar(2);\n        pila.agregar(3);\n\n        pila.imprimir();\n\n    }\n\n    // Clase Persona\n    static class Persona {\n\n        // Atributos\n        String nombre;\n        int edad;\n\n        // Constructor\n        public Persona(String nombre, int edad) {\n            this.nombre = nombre;\n            this.edad = edad;\n        }\n\n        // Getters y Setters\n        public String getNombre() {\n            return nombre;\n        }\n\n        public void setNombre(String nombre) {\n            this.nombre = nombre;\n        }\n\n        public int getEdad() {\n            return edad;\n        }\n\n        public void setEdad(int edad) {\n            this.edad = edad;\n        }\n\n        // Métodos\n        public void caminar() {\n            System.out.println(nombre + \" está caminando\");\n        }\n\n        public void hablar() {\n            System.out.println(nombre + \" está hablando\");\n        }\n\n        @Override\n        public String toString() {\n            return \"Persona{\" +\n                    \"nombre='\" + nombre + '\\'' +\n                    \", edad=\" + edad +\n                    '}';\n        }\n    }\n\n    /**\n     * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n     * en el ejercicio número 7 de la ruta de estudio)\n     * Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n     * retornar el número de elementos e imprimir todo su contenido.\n     */\n    static class Cola<T> {\n        private LinkedList<T> elementos;\n\n        public Cola() {\n            this.elementos = new LinkedList<>();\n        }\n\n        public void agregar(T elemento) {\n            elementos.addLast(elemento);\n        }\n\n        public T eliminar() {\n            if (elementos.isEmpty()) {\n                return null;\n            }\n            return elementos.removeFirst();\n        }\n\n        public int tamaño() {\n            return elementos.size();\n        }\n\n        public void imprimir() {\n            System.out.println(elementos);\n        }\n    }\n\n    static class Pila<T> {\n        private LinkedList<T> elementos;\n\n        public Pila() {\n            this.elementos = new LinkedList<>();\n        }\n\n        public void agregar(T elemento) {\n            elementos.addLast(elemento);\n        }\n\n        public T eliminar() {\n            if (elementos.isEmpty()) {\n                return null;\n            }\n            return elementos.removeLast();\n        }\n\n        public int tamaño() {\n            return elementos.size();\n        }\n\n        public void imprimir() {\n            System.out.println(elementos);\n        }\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/08 - CLASES/java/cesar-ch.java",
    "content": "import java.util.ArrayList;\nimport java.util.List;\n\nclass Persona {\n    private String nombre;\n    private int edad;\n\n    public Persona(String nombre, int edad) {\n        this.nombre = nombre;\n        this.edad = edad;\n    }\n\n    public void imprimirInformacion() {\n        System.out.println(\"Nombre: \" + this.nombre);\n        System.out.println(\"Edad: \" + this.edad);\n    }\n\n    public void setNombre(String nombre) {\n        this.nombre = nombre;\n    }\n\n    public String getNombre() {\n        return this.nombre;\n    }\n\n    public void setEdad(int edad) {\n        this.edad = edad;\n    }\n\n    public int getEdad() {\n        return this.edad;\n    }\n}\n\nclass Pila {\n    private List<Integer> pila;\n\n    public Pila(List<Integer> pila) {\n        this.pila = pila;\n    }\n\n    public void push(int dato) {\n        this.pila.add(dato);\n    }\n\n    public int pop() {\n        int lastIndex = this.pila.size() - 1;\n        int dato = this.pila.get(lastIndex);\n        this.pila.remove(lastIndex);\n        return dato;\n    }\n\n    public void imprimir() {\n        System.out.println(this.pila);\n    }\n}\n\nclass Cola {\n    private List<Integer> cola;\n\n    public Cola(List<Integer> cola) {\n        this.cola = cola;\n    }\n\n    public void enqueue(int dato) {\n        this.cola.add(dato);\n    }\n\n    public int dequeue() {\n        return this.cola.remove(0);\n    }\n\n    public void imprimir() {\n        System.out.println(this.cola);\n    }\n}\n\npublic class Main {\n    public static void main(String[] args) {\n        Persona person1 = new Persona(\"Juan\", 30);\n        person1.imprimirInformacion();\n        person1.setNombre(\"Pedro\");\n        person1.setEdad(25);\n        person1.imprimirInformacion();\n        System.out.println(person1.getNombre());\n        System.out.println(person1.getEdad());\n\n        Pila pila1 = new Pila(new ArrayList<>());\n        pila1.push(1);\n        pila1.push(2);\n        pila1.push(3);\n        pila1.imprimir();\n        System.out.println(pila1.pop());\n        pila1.imprimir();\n\n        Cola cola1 = new Cola(new ArrayList<>());\n        cola1.enqueue(1);\n        cola1.enqueue(2);\n        cola1.enqueue(3);\n        cola1.imprimir();\n        System.out.println(cola1.dequeue());\n        cola1.imprimir();\n    }\n}\n"
  },
  {
    "path": "Roadmap/08 - CLASES/java/chartypes.java",
    "content": "import java.util.LinkedList;\nimport java.util.List;\n\npublic class chartypes {\n\n  public static void main(String[] args) {\n    // Exercise\n    System.out.println(\"--------------Excercise:---------------\");\n    MyClass object = new MyClass(\"Julio\");\n    object.printSomthing();\n    object.belongs = \"Carlos\";\n    object.printSomthing();\n    System.out.println(\"--------------Extra:---------------\");\n\n    System.out.println(\"Queue\");\n    MyQueue<Integer> intQueue = new MyQueue<>();\n    intQueue.addElement(4);\n    intQueue.addElement(1);\n    intQueue.printContent();\n    intQueue.dropElement();\n    System.out.println(intQueue.len());\n    intQueue.printContent();\n\n    System.out.println(\"\\nStack\");\n    MyStack<String> strStack = new MyStack<>();\n    strStack.pushElm(\"uno\");\n    strStack.pushElm(\"dos\");\n    strStack.pushElm(\"tres\");\n    strStack.printContent();\n    strStack.remove();\n    strStack.printContent();\n    strStack.remove();\n    System.out.println(strStack.len());\n    strStack.printContent();\n\n  }\n}\n\nclass MyClass {\n  public static String belongs = \"Charlie\";\n  public String name;\n\n  public MyClass(String name) {\n    this.name = name;\n  }\n\n  public void printSomthing() {\n    System.out.println(\"name: \" + name);\n    System.out.println(\"belongs to: \" + belongs);\n  }\n}\n\nclass MyQueue<T> {\n  private List<T> queue;\n\n  public MyQueue() {\n    queue = new LinkedList<>();\n  }\n\n  public void addElement(T item) {\n    queue.addLast(item);\n\n  }\n\n  public void dropElement() {\n    queue.removeFirst();\n  }\n\n  public int len() {\n    return queue.size();\n  }\n\n  public void printContent() {\n    System.out.println(queue);\n  }\n\n}\n\nclass MyStack<T> {\n  private List<T> stack;\n\n  public MyStack() {\n    stack = new LinkedList<>();\n  }\n\n  public void pushElm(T item) {\n    stack.addLast(item);\n  }\n\n  public void remove() {\n    stack.removeLast();\n  }\n\n  public int len() {\n    return stack.size();\n  }\n\n  public void printContent() {\n    System.out.println(stack);\n  }\n}\n"
  },
  {
    "path": "Roadmap/08 - CLASES/java/danhingar.java",
    "content": "import java.util.ArrayList;\nimport java.util.List;\n\npublic class danhingar {\n\n    public static void main(String[] args) {\n        Programmer p1 = new Programmer(\"JUAN\", new ArrayList<>(), 32, \"https://www.linkedin.com/p1\");\n        System.out.println(p1);\n        p1.setName(\"PEPE\");\n        p1.setAge(23);\n        p1.setLanguages(List.of(\"JAVA\", \"PYTHON\"));\n        System.out.println(p1);\n\n        Stack myStack = new Stack();\n        myStack.push(\"A\");\n        myStack.push(\"B\");\n        myStack.push(\"C\");\n        myStack.push(\"D\");\n        System.out.println(myStack.count());\n        myStack.print();\n        myStack.pop();\n        myStack.pop();\n        System.out.println(myStack.count());\n        myStack.print();\n\n        Queue myQueue = new Queue();\n        myQueue.equeue(\"E\");\n        myQueue.equeue(\"F\");\n        myQueue.equeue(\"G\");\n        myQueue.equeue(\"H\");\n        System.out.println(myQueue.count());\n        myQueue.print();\n        System.out.println(myQueue.deequeue()); \n        System.out.println(myQueue.deequeue()); \n        System.out.println(myQueue.count());\n        myQueue.print();\n\n    }\n\n    public static class Programmer {\n        private String name;\n        private List<String> languages;\n        private Integer age;\n        private String urlLinkedin;\n\n        public Programmer(String name, List<String> languages, Integer age, String urlLinkedin) {\n            this.name = name;\n            this.languages = languages;\n            this.age = age;\n            this.urlLinkedin = urlLinkedin;\n        }\n\n        public String getName() {\n            return name;\n        }\n\n        public void setName(String name) {\n            this.name = name;\n        }\n\n        public List<String> getLanguages() {\n            return languages;\n        }\n\n        public void setLanguages(List<String> languages) {\n            this.languages = languages;\n        }\n\n        public Integer getAge() {\n            return age;\n        }\n\n        public void setAge(Integer age) {\n            this.age = age;\n        }\n\n        public String getUrlLinkedin() {\n            return urlLinkedin;\n        }\n\n        public void setUrlLinkedin(String urlLinkedin) {\n            this.urlLinkedin = urlLinkedin;\n        }\n\n        public String toString() {\n            return \"Programmer [name=\" + name + \", languages=\" + languages + \", age=\" + age + \", urlLinkedin=\"\n                    + urlLinkedin + \"]\";\n        }\n    }\n\n    // EXTRA\n    public static class Stack {\n\n        List<Object> stack;\n\n        public Stack() {\n            stack = new ArrayList<>();\n        }\n\n        public void push(Object o) {\n            stack.add(o);\n        }\n\n        public Object pop() {\n            if (stack.size() > 1) {\n                Object o = stack.get(stack.size() - 1);\n                stack.remove(stack.size() - 1);\n                return o;\n            } else {\n                return null;\n            }\n\n        }\n\n        public Integer count() {\n            return stack.size();\n        }\n\n        public void print() {\n            for (Object object : stack.reversed()) {\n                System.out.println(object);\n            }\n        }\n\n    }\n\n    public static class Queue {\n\n        List<Object> queue;\n\n        public Queue() {\n            queue = new ArrayList<>();\n        }\n\n        public void equeue(Object o) {\n            queue.add(o);\n        }\n\n        public Object deequeue() {\n            if (queue.size() > 1) {\n                Object o = queue.get(0);\n                queue.remove(0);\n                return o;\n            } else {\n                return null;\n            }\n\n        }\n\n        public Integer count() {\n            return queue.size();\n        }\n\n        public void print() {\n            for (Object object : queue) {\n                System.out.println(object);\n            }\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/08 - CLASES/java/eulogioep.java",
    "content": "// Ejemplo de una clase en Java\n\n/**\n * Clase Persona que representa a una persona con nombre y edad.\n */\npublic class Persona {\n    // Atributos de la clase\n    private String nombre;\n    private int edad;\n\n    // Constructor (inicializador)\n    public Persona(String nombre, int edad) {\n        this.nombre = nombre;\n        this.edad = edad;\n    }\n\n    // Métodos getter y setter\n    public String getNombre() {\n        return nombre;\n    }\n\n    public void setNombre(String nombre) {\n        this.nombre = nombre;\n    }\n\n    public int getEdad() {\n        return edad;\n    }\n\n    public void setEdad(int edad) {\n        this.edad = edad;\n    }\n\n    // Método para imprimir los datos de la persona\n    public void imprimirDatos() {\n        System.out.println(\"Nombre: \" + nombre + \", Edad: \" + edad);\n    }\n}\n\n/**\n * Clase Pila que implementa una estructura de datos de tipo pila (LIFO).\n */\npublic class Pila<T> {\n    private java.util.LinkedList<T> elementos;\n\n    public Pila() {\n        elementos = new java.util.LinkedList<>();\n    }\n\n    public void push(T elemento) {\n        elementos.push(elemento);\n    }\n\n    public T pop() {\n        return elementos.pop();\n    }\n\n    public int size() {\n        return elementos.size();\n    }\n\n    public void imprimirContenido() {\n        System.out.println(\"Contenido de la pila: \" + elementos);\n    }\n}\n\n/**\n * Clase Cola que implementa una estructura de datos de tipo cola (FIFO).\n */\npublic class Cola<T> {\n    private java.util.LinkedList<T> elementos;\n\n    public Cola() {\n        elementos = new java.util.LinkedList<>();\n    }\n\n    public void enqueue(T elemento) {\n        elementos.addLast(elemento);\n    }\n\n    public T dequeue() {\n        return elementos.removeFirst();\n    }\n\n    public int size() {\n        return elementos.size();\n    }\n\n    public void imprimirContenido() {\n        System.out.println(\"Contenido de la cola: \" + elementos);\n    }\n}\n\n// Clase principal para probar las implementaciones\npublic class eulogioep {\n    public static void main(String[] args) {\n        // Prueba de la clase Persona\n        Persona persona = new Persona(\"Juan\", 30);\n        persona.imprimirDatos();\n        persona.setEdad(31);\n        persona.imprimirDatos();\n\n        // Prueba de la Pila\n        Pila<Integer> pila = new Pila<>();\n        pila.push(1);\n        pila.push(2);\n        pila.push(3);\n        pila.imprimirContenido();\n        System.out.println(\"Elemento extraído de la pila: \" + pila.pop());\n        pila.imprimirContenido();\n\n        // Prueba de la Cola\n        Cola<String> cola = new Cola<>();\n        cola.enqueue(\"A\");\n        cola.enqueue(\"B\");\n        cola.enqueue(\"C\");\n        cola.imprimirContenido();\n        System.out.println(\"Elemento extraído de la cola: \" + cola.dequeue());\n        cola.imprimirContenido();\n    }\n}"
  },
  {
    "path": "Roadmap/08 - CLASES/java/h4ckxel.java",
    "content": "import java.util.ArrayList;\nimport java.util.List;\n\nclass Persona {\n    private String nombre;\n    private int edad;\n\n    public Persona(String nombre, int edad) {\n        this.nombre = nombre;\n        this.edad = edad;\n    }\n\n    public void imprimirInformacion() {\n        System.out.println(\"Nombre: \" + this.nombre);\n        System.out.println(\"Edad: \" + this.edad);\n    }\n\n    public void setNombre(String nombre) {\n        this.nombre = nombre;\n    }\n\n    public String getNombre() {\n        return this.nombre;\n    }\n\n    public void setEdad(int edad) {\n        this.edad = edad;\n    }\n\n    public int getEdad() {\n        return this.edad;\n    }\n}\n\nclass Pila {\n    private List<Integer> pila;\n\n    public Pila(List<Integer> pila) {\n        this.pila = pila;\n    }\n\n    public void push(int dato) {\n        this.pila.add(dato);\n    }\n\n    public int pop() {\n        int lastIndex = this.pila.size() - 1;\n        int dato = this.pila.get(lastIndex);\n        this.pila.remove(lastIndex);\n        return dato;\n    }\n\n    public void imprimir() {\n        System.out.println(this.pila);\n    }\n}\n\nclass Cola {\n    private List<Integer> cola;\n\n    public Cola(List<Integer> cola) {\n        this.cola = cola;\n    }\n\n    public void enqueue(int dato) {\n        this.cola.add(dato);\n    }\n\n    public int dequeue() {\n        return this.cola.remove(0);\n    }\n\n    public void imprimir() {\n        System.out.println(this.cola);\n    }\n}\n\npublic class Main {\n    public static void main(String[] args) {\n        Persona person1 = new Persona(\"Juan\", 30);\n        person1.imprimirInformacion();\n        person1.setNombre(\"Pedro\");\n        person1.setEdad(25);\n        person1.imprimirInformacion();\n        System.out.println(person1.getNombre());\n        System.out.println(person1.getEdad());\n\n        Pila pila1 = new Pila(new ArrayList<>());\n        pila1.push(1);\n        pila1.push(2);\n        pila1.push(3);\n        pila1.imprimir();\n        System.out.println(pila1.pop());\n        pila1.imprimir();\n\n        Cola cola1 = new Cola(new ArrayList<>());\n        cola1.enqueue(1);\n        cola1.enqueue(2);\n        cola1.enqueue(3);\n        cola1.imprimir();\n        System.out.println(cola1.dequeue());\n        cola1.imprimir();\n    }\n}\n"
  },
  {
    "path": "Roadmap/08 - CLASES/java/julian98789.java",
    "content": "\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class reto_8 {\n    private String nombre;\n    private int edad;\n    private String direccion;\n\n    public reto_8(String nombre, int edad, String direccion) {\n        this.nombre = nombre;\n        this.edad = edad;\n        this.direccion = direccion;\n    }\n\n    public void imprimir() {\n        System.out.println(\"Nombre: \" + nombre);\n        System.out.println(\"Edad: \" + edad);\n        System.out.println(\"Dirección: \" + direccion);\n    }\n\n    // Implementación de la pila (stack)\n    class Stack<T> {\n        private List<T> elementos = new ArrayList<>();\n\n        // Agregar elementos\n        public void agregar(T elemento) {\n            elementos.add(elemento);\n        }\n\n        public void eliminar() {\n            if (elementos.isEmpty()) {\n                throw new RuntimeException(\"La pila está vacía\");\n            } else {\n                elementos.remove(elementos.size() - 1);\n            }\n        }\n\n        public int numeroElementos() {\n            return elementos.size();\n        }\n\n        public void mostrarElementos() {\n            System.out.println(\"Mostrar elementos de la pila: \" + elementos);\n        }\n\n        @Override\n        public String toString() {\n            return elementos.toString();\n        }\n    }\n\n    // Implementación de la cola (queue) genérica\n    class Queue<T> {\n        private List<T> elementos = new ArrayList<>();\n\n        public void agregar(T elemento) {\n            elementos.add(elemento);\n        }\n\n        public void eliminar() {\n            if (elementos.isEmpty()) {\n                throw new RuntimeException(\"La cola está vacía\");\n            } else {\n                elementos.remove(0);\n            }\n        }\n\n        public int numeroElementos() {\n            return elementos.size();\n        }\n\n        public void mostrarElementos() {\n            System.out.println(\"Mostrando elementos: \" + elementos);\n        }\n\n        @Override\n        public String toString() {\n            return elementos.toString();\n        }\n    }\n}\n\nclass Prueba {\n    public static void main(String[] args) {\n        reto_8 prueba = new reto_8(\"Julian\", 19, \"Carrera 101a\");\n        prueba.imprimir();\n\n        System.out.println(\"\\n****** Pila ******\\n\");\n\n        reto_8.Stack<String> pila = prueba.new Stack<>();\n        pila.agregar(\"Elemento 1\");\n        pila.agregar(\"Elemento 2\");\n        pila.agregar(\"Elemento 3\");\n        System.out.println(\"Agregar elemento: \" + pila);\n\n        pila.eliminar();\n        System.out.println(\"Eliminar elemento: \" + pila);\n\n        int num = pila.numeroElementos();\n        System.out.println(\"Número de elementos en la pila: \" + num);\n\n        pila.mostrarElementos();\n\n        System.out.println(\"\\n****** Cola ******\\n\");\n\n        reto_8.Queue<String> cola = prueba.new Queue<>();\n        cola.agregar(\"Elemento 1\");\n        cola.agregar(\"Elemento 2\");\n        cola.agregar(\"Elemento 3\");\n        System.out.println(\"Agregar elemento: \" + cola);\n\n        cola.eliminar();\n        System.out.println(\"Eliminar elemento: \" + cola);\n\n        int numCola = cola.numeroElementos();\n        System.out.println(\"Número de elementos en la cola: \" + numCola);\n\n        cola.mostrarElementos();\n    }\n}\n"
  },
  {
    "path": "Roadmap/08 - CLASES/java/kleyner098.java",
    "content": "import java.util.Arrays;\n\npublic class kleyner098 {\n    /*\n     * EJERCICIO:\n     * Explora el concepto de clase y crea un ejemplo que implemente un\n     * inicializador, atributos y una función que los imprima (teniendo en cuenta\n     * lasposibilidades de tu lenguaje).\n     * Una vez implementada, créala, establece sus parámetros, modifícalos e\n     * imprímelos utilizando su función.\n     *\n     * DIFICULTAD EXTRA (opcional):\n     * Implementa dos clases que representen las estructuras de Pila y Cola\n     * (estudiadas en el ejercicio número 7 de la ruta de estudio)\n     * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n     * retornar el número de elementos e imprimir todo su contenido.\n     * \n     */\n\n    public static void main(String[] args) {\n        Contador count = new Contador(1, 2);\n        System.out.println(count.toString());\n        count.setFin(10);\n        System.out.println(count.toString());\n        count.contar();\n\n\n        // DIFICULTAD EXTRA (opcional):\n        Pila<Integer> pila = new Pila();\n        pila.apilar(1);\n        pila.apilar(2);\n        pila.apilar(3);\n        System.out.println(\"Pila : \" + pila);\n        pila.desapilar();\n        pila.desapilar();\n        System.out.println(\"Pila : \" + pila);\n        Cola<Integer> cola = new Cola();\n        cola.encolar(1);\n        cola.encolar(2);\n        cola.encolar(3);\n        System.out.println(\"Cola :\" + cola);\n        cola.desencolar();\n        cola.desencolar();\n        System.out.println(\"Cola :\" + cola);\n    } \n}\n\nclass Contador {\n    // Atributos\n    private int inicio;\n    private int fin;\n\n    // Constructor\n    Contador(int inicio, int fin) {\n        this.inicio = inicio;\n        this.fin = fin;\n    }\n\n    // Getters y setters\n    public int getInicio() {\n        return inicio;\n    }\n\n    public void setInicio(int inicio) {\n        this.inicio = inicio;\n    }\n\n    public int getFin() {\n        return fin;\n    }\n\n    public void setFin(int fin) {\n        this.fin = fin;\n    }\n\n    // Método que imprime los números desde inicio hasta fin.\n    public void contar() {\n        for (int i = inicio; i < fin; i++) {\n            System.out.println(i);\n        }\n    }\n\n    // toString\n    @Override\n    public String toString() {\n        return \"Inicio: \" + inicio + \" | Fin: \" + fin;\n    }\n\n}\n\nclass Pila<T> {\n    private T[] pila;\n\n    Pila() {\n        pila = (T[]) new Object[0];\n    }\n\n    public void apilar(T elemento) {\n        pila = Arrays.copyOf(pila, pila.length + 1);\n        pila[pila.length - 1] = elemento;\n    }\n\n    public T desapilar() {\n        T eliminado = pila[pila.length - 1];\n        pila = Arrays.copyOf(pila, pila.length - 1);\n        return eliminado;\n    }\n\n    @Override\n    public String toString() {\n        return Arrays.toString(pila);\n    }\n\n    public int size() {\n        return pila.length;\n    }\n\n    public T cima() {\n        return pila[pila.length - 1];\n    }\n}\n\nclass Cola<T> {\n    private T[] cola;\n\n    Cola() {\n        cola = (T[]) new Object[0];\n    }\n\n    public void encolar(T elemento) {\n        cola = Arrays.copyOf(cola, cola.length + 1);\n        cola[cola.length - 1] = elemento;\n    }\n\n    public T desencolar() {\n        T eliminado = cola[0];\n        System.arraycopy(cola, 1, cola, 0, cola.length - 1);\n        cola = Arrays.copyOf(cola, cola.length - 1);\n        return eliminado;\n    }\n\n    @Override\n    public String toString() {\n        return Arrays.toString(cola);\n    }\n\n    public int size() {\n        return cola.length;\n    }\n\n    public T finalCola() {\n        return cola[cola.length - 1];\n    }\n}"
  },
  {
    "path": "Roadmap/08 - CLASES/java/martinbohorquez.java",
    "content": "import java.util.Queue;\nimport java.util.Stack;\nimport java.util.*;\n\npublic class martinbohorquez {\n\n    private static Queue<Integer> cola = new LinkedList<>(); //Cola\n\n    public static void main(String[] args) {\n        Programador programador = new Programador(\"MartinDev\", 29,\n                Arrays.asList(\"Java\", \"Python\", \"Typescript\"));\n        programador.setSurname(\"Bohorquez\");\n        programador.imprimir();\n        programador.languages.add(\"Kotlin\");\n        programador.imprimir();\n\n        /*\n         * DIFICULTAD EXTRA\n         */\n        //stack\n        System.out.println(\"[------- STACK ---------]\");\n        Pila pila = new Pila(Arrays.asList(10, 20, 30, 40));\n        pila.push(50);\n        pila.count();\n        pila.pop();\n        pila.count();\n        pila.push(60);\n        pila.count();\n        pila.print();\n        //queue\n        System.out.println(\"[------- QUEUE ---------]\");\n        Cola cola = new Cola(Arrays.asList(100, 200, 300, 400));\n        cola.offer(500);\n        cola.count();\n        cola.poll();\n        cola.count();\n        cola.offer(600);\n        cola.count();\n        cola.print();\n\n    }\n\n    private static class Pila {\n        private Stack<Integer> pila = new Stack<>();\n\n        private Pila(List<Integer> pila) {\n            this.pila.addAll(pila);\n        }\n\n        private void push(Integer num) {\n            printStack();\n            System.out.printf(\"Se añade el elemento %d a la pila: %n\", pila.push(num));\n            printStack();\n        }\n\n        private void pop() {\n            printStack();\n            if (!pila.isEmpty()) {\n                System.out.printf(\"Se extrae un elemento %d a la pila: %n\", pila.pop());\n                printStack();\n            }\n        }\n\n        private void count() {\n            System.out.printf(\"La pila cuenta con %d elementos.%n\", pila.size());\n        }\n\n        private void printStack() {\n            System.out.printf(\"La pila contiene los siguientes elementos: %s%n\", pila.toString());\n        }\n\n        private void print() {\n            System.out.println(\"La pila contiene los siguientes elementos:\");\n            pila.forEach(System.out::println);\n        }\n    }\n\n    private static class Cola {\n        private Queue<Integer> cola;\n\n        private Cola(List<Integer> cola) {\n            this.cola = new LinkedList<>(cola);\n        }\n\n        private void offer(Integer num) {\n            printQueue();\n            cola.offer(num);\n            System.out.printf(\"Se añade el elemento %d a la cola: %n\", num);\n            printQueue();\n        }\n\n        private void poll() {\n            printQueue();\n            if (!cola.isEmpty()) {\n                System.out.printf(\"Se extrae un elemento %d a la pila: %n\", cola.poll());\n                printQueue();\n            }\n        }\n\n        private void count() {\n            System.out.printf(\"La pila cuenta con %d elementos.%n\", cola.size());\n        }\n\n        private void printQueue() {\n            System.out.printf(\"La cola contiene los siguientes elementos: %s%n\", cola.toString());\n        }\n\n        private void print() {\n            System.out.println(\"La pila contiene los siguientes elementos:\");\n            cola.forEach(System.out::println);\n        }\n    }\n\n    private static class Programador {\n        private String name;\n        private String surname;\n        private int age;\n        private List<String> languages;\n\n        private Programador(String name, int age, List<String> lenguajes) {\n            this.name = name;\n            this.age = age;\n            this.languages = new ArrayList<>(lenguajes);\n        }\n\n        private void setSurname(String surname) {\n            this.surname = surname;\n        }\n\n        private void imprimir() {\n            System.out.printf(\"Nombre: %s | Apellido: %s | Edad: %d | Lenguajes: %s%n\",\n                    name, surname, age, languages.toString());\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/08 - CLASES/java/mensius87.java",
    "content": "public class Persona {\n    private String nombre;\n    private int edad;\n    \n    public Persona(String nombre, int edad) {\n        this.nombre = nombre;\n        this.edad = edad;\n    }\n    \n    public void imprimirInformacion() {\n        System.out.println(\"Nombre: \" + this.nombre);\n        System.out.println(\"Edad: \" + this.edad);\n    }\n\n    public static void main(String[] args) {\n        // Crear una instancia de la clase Persona\n        Persona persona1 = new Persona(\"Juan\", 30);\n\n        // Imprimir la información utilizando el método de la clase\n        persona1.imprimirInformacion();\n\n        // Modificar los atributos y volver a imprimir la información\n        persona1.nombre = \"María\";\n        persona1.edad = 25;\n        persona1.imprimirInformacion();\n    }\n}\n"
  },
  {
    "path": "Roadmap/08 - CLASES/java/miguelex.java",
    "content": "public class miguelex {\n\n    static class Vehiculo {\n        private String nombre;\n        private int numRuedas;\n\n        public Vehiculo(String nombre, int numRuedas) {\n            this.nombre = nombre;\n            this.numRuedas = numRuedas;\n        }\n\n        public String toString() {\n            return \"Vehiculo{\" +\n                    \"nombre='\" + nombre + '\\'' +\n                    \", numRuedas=\" + numRuedas +\n                    '}';\n        }\n    }\n\n    static class Pila {\n        private int[] elementos;\n        private int tope;\n\n        public Pila() {\n            elementos = new int[10];\n            tope = -1;\n        }\n\n        public void push(int elemento) {\n            if (tope < elementos.length - 1) {\n                elementos[++tope] = elemento;\n            }\n        }\n\n        public int pop() {\n            if (tope >= 0) {\n                return elementos[tope--];\n            }\n            return -1;\n        }\n\n        public int size(){\n            return tope + 1;\n        }\n\n        public void imprimir() {\n            for (int i = 0; i <= tope; i++) {\n                System.out.println(elementos[i]);\n            }\n        }\n    }\n\n    static class Cola {\n        private int[] elementos;\n        private int frente;\n        private int fin;\n\n        public Cola() {\n            elementos = new int[10];\n            frente = 0;\n            fin = -1;\n        }\n\n        public void agregar(int elemento) {\n            if (fin < elementos.length - 1) {\n                elementos[++fin] = elemento;\n            }\n        }\n\n        public int quitar() {\n            if (frente <= fin) {\n                return elementos[frente++];\n            }\n            return -1;\n        }\n\n        public int size(){\n            return fin - frente + 1;\n        }\n\n        public void imprimir() {\n            for (int i = frente; i <= fin; i++) {\n                System.out.println(elementos[i]);\n            }\n        }\n    }\n\n    public static void main(String[] args) {\n        Vehiculo coche = new Vehiculo(\"Coche\", 4);\n        Vehiculo bicicleta = new Vehiculo(\"bicicleta\", 2);\n        System.out.println(coche);\n        System.out.println(bicicleta);\n\n        Pila pila = new Pila();\n        Cola cola = new Cola();\n\n        pila.push(1);\n        pila.push(2);\n        pila.push(3);\n\n        cola.agregar(1);\n        cola.agregar(2);\n        cola.agregar(3);\n\n        pila.imprimir();\n        pila.pop();\n        pila.imprimir();\n        System.out.println(\"Tamaño de la pila: \" + pila.size());\n\n        cola.imprimir();\n        cola.quitar();\n        cola.imprimir();\n        System.out.println(\"Tamaño de la cola: \" + cola.size());\n\n\n    }\n    \n}\n"
  },
  {
    "path": "Roadmap/08 - CLASES/java/simonguzman.java",
    "content": "import java.util.Stack;\nimport java.util.Queue;\nimport java.util.LinkedList;\n\npublic class simonguzman {\n    public static void main(String[] args) {\n\n        Persona persona = new Persona();\n\n        persona.setNombre(\"Simon\");\n        persona.setApellido(\"Guzman\");\n        persona.setEdad(22);\n        \n        System.out.println(persona.toString());\n\n        Pila pila = new Pila();\n        pila.agregarElementoPila(\"Documento1\");\n        pila.agregarElementoPila(\"Documento2\");\n        pila.agregarElementoPila(\"Documento3\");\n        System.out.println(\"************Elementos inciales************\");\n        pila.verElementosPila(); \n        pila.tamañoPila();\n        pila.eliminarElementoPila();\n        System.out.println(\"************Elementos finales************\");\n        pila.verElementosPila();\n\n        Cola cola = new Cola();\n        cola.agregarElementoCola(\"Documento 1\");\n        cola.agregarElementoCola(\"Documento 2\");\n        cola.agregarElementoCola(\"Documento 3\");\n        System.out.println(\"************Elementos inciales************\");\n        cola.verElementosCola();\n        cola.tamañoCola();\n        cola.eliminarElementoCola();\n        System.out.println(\"************Elementos finales************\");\n        cola.verElementosCola();\n    }\n\n    static class Persona{\n        private String nombre;\n        private String apellido;\n        private int edad;\n    \n        public Persona(){\n    \n        }\n    \n        public Persona(String nombre, String apellido, int edad){\n            this.nombre = nombre;\n            this.apellido = apellido;\n            this.edad = edad;\n        }\n    \n        public void setNombre(String nombre) {\n            this.nombre = nombre;\n        }\n    \n        public String getNombre() {\n            return nombre;\n        }\n    \n        public void setApellido(String apellido) {\n            this.apellido = apellido;\n        }\n        \n        public String getApellido() {\n            return apellido;\n        }\n    \n        public void setEdad(int edad) {\n            this.edad = edad;\n        }\n    \n        public int getEdad() {\n            return edad;\n        }\n    \n        @Override\n        public String toString() {\n            return \"Persona: \" + \" nombre \"+ getNombre() + \" apellido \"+ getApellido() + \" edad \"+ getEdad() ;\n        }\n    }\n\n    static class Pila{\n        private Stack<String> pila;\n    \n        public Pila(){\n            this.pila = new Stack<>();\n        }\n    \n        public Pila(Stack<String> pila){\n            this.pila = pila;\n        }\n    \n        public void agregarElementoPila(String cadena){\n            this.pila.push(cadena);\n        }\n    \n        public void eliminarElementoPila(){\n            if(!this.pila.isEmpty()){\n                this.pila.pop();\n            }else{\n                System.out.println(\"La pila esta vacia\");\n            }\n            \n        }\n    \n        public void verElementosPila(){\n            if(!this.pila.isEmpty()){\n                for (int i = pila.size() - 1; i >= 0; i--){\n                    System.out.println(pila.get(i));\n                }\n            }else{\n                System.out.println(\"La pila esta vacia\");\n            }\n            \n        }\n    \n        public int tamañoPila(){\n            return this.pila.size();\n        }\n    }\n\n    static class Cola{\n        private Queue<String> cola;\n    \n        public Cola(){\n            this.cola = new LinkedList<>();\n        }\n    \n        public Cola(Queue<String> cola){\n            this.cola = new LinkedList<>();\n        }\n    \n        public void agregarElementoCola(String cadena){\n            this.cola.add(cadena);\n        }\n    \n        public void eliminarElementoCola(){\n            if(!this.cola.isEmpty()){\n                this.cola.poll();\n            }else{\n                System.out.println(\"La cola esta vacia\");\n            }\n            \n        }\n    \n        public void verElementosCola(){\n            if(!this.cola.isEmpty()){\n                for (String elemento : cola){\n                    System.out.println(elemento);\n                }\n            }else{\n                System.out.println(\"La cola esta vacia\");\n            }\n            \n        }\n    \n        public int tamañoCola(){\n            return this.cola.size();\n        }\n    \n    }\n\n}\n\n\n"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/7R0N1X.js",
    "content": "class Saludo {\n  constructor(lenguaje) {\n    this.lenguaje = lenguaje\n  }\n\n  getSaludo() {\n    return `Hola desde ${this.lenguaje}`\n  }\n}\n\nlet saludo = new Saludo('JavaScript')\nconsole.log(saludo.getSaludo())\n\n// Pila\nclass Pila {\n\n  constructor(data) {\n    this.data = data\n  }\n\n  setData(data) {\n    return this.data.push(data)\n  }\n\n  getRemoveData() {\n    return this.data.pop()\n  }\n\n  getSize() {\n    return this.data.length\n  }\n\n  getData() {\n    return this.data\n  }\n\n  getIsEmpty() {\n    return this.getSize() === 0 ? true : false\n  }\n\n}\n\nlet pila = new Pila([])\nconsole.log(`¿La pila está vacía?: ${pila.getIsEmpty()}`)\npila.setData(5)\npila.setData(10)\npila.setData(6)\npila.setData(2)\npila.setData(8)\nconsole.log(`Elementos en la pila: ${pila.getData()}`)\nconsole.log(`¿La pila está vacía?: ${pila.getIsEmpty()}`)\nconsole.log(`¿Cuál es el tamaño de la pila?: ${pila.getSize()}`)\nconsole.log(`El valor ${pila.getRemoveData()} ha sido removido de la pila`)\nconsole.log(`Elementos en la pila: ${pila.getData()}`)\nconsole.log(`¿Cuál es el tamaño de la pila?: ${pila.getSize()}`)\n\n\n// Cola\nclass Cola {\n\n  constructor(data) {\n    this.data = data\n  }\n\n  setData(data){\n    this.data.push(data)\n  }\n\n  getRemoveData() {\n    return this.data.shift()\n  }\n\n  getSize() {\n    return this.data.length\n  }\n\n  getData() {\n    return this.data\n  }\n\n  getIsEmpty() {\n    return this.getSize() === 0 ? true : false\n  }\n\n}\n\nlet cola = new Cola([])\nconsole.log(`¿La cola está vacía?: ${cola.getIsEmpty()}`)\ncola.setData(5)\ncola.setData(10)\ncola.setData(6)\ncola.setData(2)\ncola.setData(8)\nconsole.log(`Elementos en la cola: ${cola.getData()}`)\nconsole.log(`¿La cola está vacía?: ${cola.getIsEmpty()}`)\nconsole.log(`¿Cuál es el tamaño de la cola?: ${cola.getSize()}`)\nconsole.log(`El valor ${cola.getRemoveData()} ha sido removido de la cola`)\nconsole.log(`Elementos en la cola: ${cola.getData()}`)\nconsole.log(`¿Cuál es el tamaño de la cola?: ${cola.getSize()}`)\n"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/AChapeton.js",
    "content": "class Todo {\n  constructor(title, description, done, user, daysLeft){\n    this.title = title,\n    this.description = description,\n    this.done = done,\n    this.user = user,\n    this.daysLeft = daysLeft\n  }\n\n  //Los Getters se utilizan para no interactuar directamente con las propiedades de la clase.\n  //Tambien se evita para no dar a conocer todas sus propiedades, por seguridad.\n  get finishTodo (){\n    return this.toggleTodo()\n  }\n\n  //Metodos\n  toggleTodo() {\n    return !this.done\n  }\n}\n\nconst myTodo = new Todo('Finish roadmap', 'Finish exercise #08', false, 'Andres', 5)\n\nconsole.log(myTodo)\n\nconsole.log(myTodo.finishTodo)\n\n\n/* DIFICULTAD EXTRA */\n\nclass Pila {\n  constructor(data){\n    this.data = data\n  }\n\n  addElementAction(element){\n    return this.data.unshift(element)\n  }\n\n  deleteElementAction(){\n    return this.data.shift()\n  }\n\n  sizeAction(){\n    return this.data.length\n  }\n\n  get addElement() {\n    return this.addElementAction\n  }\n\n  get deleteElement() {\n    return this.deleteElementAction\n  }\n\n  get size(){\n    return this.sizeAction\n  }\n}\n\nconst nuevaPila = new Pila([])\n\nconsole.log('Pila vacia', nuevaPila)\nnuevaPila.addElement(1)\nnuevaPila.addElement(2)\nnuevaPila.addElement(3)\nconsole.log('Nuevos elementos agregados', nuevaPila)\nconsole.log('Cantidad de elementos', nuevaPila.size())\nnuevaPila.deleteElement()\nconsole.log('Eliminado ultimo elemento', nuevaPila)\n\nclass Cola {\n  constructor(data){\n    this.data = data\n  }\n\n  addElementAction(element){\n    return this.data.push(element)\n  }\n\n  deleteElementAction(){\n    return this.data.shift()\n  }\n\n  sizeAction(){\n    return this.data.length\n  }\n\n  get addElement() {\n    return this.addElementAction\n  }\n\n  get deleteElement() {\n    return this.deleteElementAction\n  }\n\n  get size(){\n    return this.sizeAction\n  }\n}\n\nconst nuevaCola = new Cola([])\n\nconsole.log('Cola vacia', nuevaCola)\nnuevaCola.addElement(1)\nnuevaCola.addElement(2)\nnuevaCola.addElement(3)\nconsole.log('Nuevos elementos agregados', nuevaCola)\nconsole.log('Cantidad de elementos', nuevaCola.size())\nnuevaCola.deleteElement()\nconsole.log('Eliminado primer elemento', nuevaCola)"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/ArticKun.js",
    "content": "\n\n//⚡⚡  CONCEPTO DE CLASE ==================\n\nclass Programmer {\n\n    name;\n    age;\n    language;\n\n    constructor( name,age,language){\n        this.name = name;\n        this.age = age;\n        this.language = language;\n    }\n\n    printProperties(){\n        console.log(`Name: ${this.name} Age: ${this.age} Language: ${this.language} `);\n    }\n};\n\n//* Instancia\nconst programmer1 = new Programmer( 'Artic','34','Javascript' );\n// Imprimir Instancia\nconsole.log( programmer1 );\n// Imprimir método\nprogrammer1.printProperties();\n//Modificar propiedades\nprogrammer1.name = 'Biancho';\nprogrammer1.age = 35;\nprogrammer1.language = 'Java';\n//Imprimir propiedades modificadas\nprogrammer1.printProperties();\n\n\n\n//  DIFICULTAD EXTRA (opcional):\n//  Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n//  en el ejercicio número 7 de la ruta de estudio)\n\n//  - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n//    retornar el número de elementos e imprimir todo su contenido.\n\n\n//⚡  Clase para representar una Pila =====\n\nclass Stack {\n\n    constructor() {\n        this.items = [];\n    }\n    // Método para añadir un elemento a la pila\n    push(element) {\n        this.items.push(element);\n    }\n    // Método para eliminar el último elemento de la pila\n    pop() {\n        if (this.items.length === 0) {\n            return \"La pila está vacía\";\n        }\n        return this.items.pop();\n    }\n    // Método para retornar el número de elementos en la pila\n    size() {\n        return this.items.length;\n    }\n    // Método para imprimir todo el contenido de la pila\n    print() {\n        console.log(\"Contenido de la Pila:\", this.items);\n    }\n};\n\n\n// ⚡ Clase para representar una Cola =====\nclass Queue {\n\n    constructor() {\n        this.items = [];\n    }\n    // Método para añadir un elemento a la cola\n    enqueue(element) {\n        this.items.push(element);\n    }\n    // Método para eliminar el primer elemento de la cola\n    dequeue() {\n        if (this.items.length === 0) {\n            return \"La cola está vacía\";\n        }\n        return this.items.shift();\n    }\n    // Método para retornar el número de elementos en la cola\n    size() {\n        return this.items.length;\n    }\n    // Método para imprimir todo el contenido de la cola\n    print() {\n        console.log(\"Contenido de la Cola:\", this.items);\n    }\n};\n\n// Instancia Stack\nconst stack = new Stack();\nstack.push(10);\nstack.push(20);\nstack.push(30);\nstack.print();\nconsole.log( \"Elemento eliminado de la Pila:\", stack.pop() );\nconsole.log( \"Tamaño de la Pila:\", stack.size() );\n\n//Instancia Queue\nconst queue = new Queue();\nqueue.enqueue(\"A\");\nqueue.enqueue(\"B\");\nqueue.enqueue(\"C\");\nqueue.print();\nconsole.log( \"Elemento eliminado de la Cola:\", queue.dequeue() );\nconsole.log( \"Tamaño de la Cola:\", queue.size() );\n\n\n\n\n//⚡⚡ Resolucion Moure =========================================================\n\n// Stack (LIFO)\nclass Stack {\n    constructor() {\n        this.stack = [];\n    }\n\n    push(item) {\n        this.stack.push(item);\n    }\n\n    pop() {\n        if (this.count() === 0) {\n            return null;\n        }\n        return this.stack.pop();\n    }\n\n    count() {\n        return this.stack.length;\n    }\n\n    print() {\n        for (let i = this.stack.length - 1; i >= 0; i--) {\n            console.log(this.stack[i]);\n        }\n    }\n}\n\n// Example for Stack\nconst myStack = new Stack();\nmyStack.push(\"A\");\nmyStack.push(\"B\");\nmyStack.push(\"C\");\nconsole.log(myStack.count());\nmyStack.print();\nmyStack.pop();\nconsole.log(myStack.count());\nconsole.log(myStack.pop());\nconsole.log(myStack.pop());\nconsole.log(myStack.pop());\nconsole.log(myStack.pop());\nconsole.log(myStack.pop());\nconsole.log(myStack.count());\n\n// Queue (FIFO)\nclass Queue {\n    constructor() {\n        this.queue = [];\n    }\n\n    enqueue(item) {\n        this.queue.push(item);\n    }\n\n    dequeue() {\n        if (this.count() === 0) {\n            return null;\n        }\n        return this.queue.shift();\n    }\n\n    count() {\n        return this.queue.length;\n    }\n\n    print() {\n        for (let i = 0; i < this.queue.length; i++) {\n            console.log(this.queue[i]);\n        }\n    }\n}\n\n// Example for Queue\nconst myQueue = new Queue();\nmyQueue.enqueue(\"A\");\nmyQueue.enqueue(\"B\");\nmyQueue.enqueue(\"C\");\nconsole.log(myQueue.count());\nmyQueue.print();\nmyQueue.dequeue();\nconsole.log(myQueue.count());\nconsole.log(myQueue.dequeue());\nconsole.log(myQueue.dequeue());\nconsole.log(myQueue.dequeue());\nconsole.log(myQueue.dequeue());\nconsole.log(myQueue.dequeue());\nconsole.log(myQueue.count());\n"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/DAVstudy.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n *\n */\n\nclass Developer {\n    constructor(name, code, level, alias = 'Sin alias') {\n        this.name = name\n        this.code = code\n        this.level = level\n        this.alias = alias\n    }\n\n    infoDev = () =>  `${this.name} tiene un nivel de ${this.level}, programando en ${this.exp}` \n\n    setAlias = function (alias) {\n        this.alias = alias        \n    }\n\n}\n\nlet developer1 = new Developer('Diego', 'JavaScript', 'principiante')\n\nconsole.log(developer1.infoDev());\n\nconsole.log(developer1.alias);\n\ndeveloper1.setAlias('DevsDav')\n\nconsole.log(developer1.alias)\n\n\n/*\n*\n* DIFICULTAD EXTRA (opcional):\n* Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n* en el ejercicio número 7 de la ruta de estudio)\n* - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n*   retornar el número de elementos e imprimir todo su contenido.\n*\n*/\n\nclass Stack {\n\n    constructor(initialElements = []) {\n        this.stack = [...initialElements]\n        this.lengthStack = this.stack.length\n    }\n\n    addElement(element) {\n        this.stack.push(element)\n        this.lengthStack = this.stack.length\n    }\n\n    getElement() {\n        let element = this.stack.pop()\n        this.lengthStack = this.stack.length\n        return element\n    }\n\n    show() {\n        console.log('Top')\n        console.log('---')\n        for (let i = this.stack.length - 1; i >= 0; i--) {\n            if (i === this.stack.length - 1) {\n                console.log(this.stack[i] + '  <-  ultimo en entrar, primero en salir.')\n            }\n            console.log(this.stack[i])\n        }\n        console.log('---')\n        console.log('Bot')\n    }\n\n\n}\n\nlet myStack = new Stack()\nconsole.log(myStack);\n\nmyStack.addElement('elemento 1')\nmyStack.addElement('elemento 2')\nmyStack.addElement('elemento 3')\nmyStack.addElement('elemento 4')\nmyStack.addElement('elemento 5')\nmyStack.show()\nconsole.log(myStack.lengthStack);\nconsole.log(myStack.getElement());\nconsole.log(myStack.lengthStack);\nconsole.log('');\n\n\n\n\n\nclass Queue {\n\n    constructor(initialElements = []) {\n        this.queue = [...initialElements]\n        this.lengthQueue= this.queue.length\n    }\n\n    addElement(element) {\n        this.queue.push(element)\n        this.lengthStack = this.queue.length\n    }\n\n    getElement() {\n        let element = this.queue.shift()\n        this.lengthStack = this.queue.length\n        return element\n    }\n\n    show() {\n        console.log('Top')\n        console.log('---')\n        for (let i = this.queue.length - 1; i >= 0; i--) {\n            if (i === 0) {\n                console.log(this.queue[i] + '  <-  Primero en entrar, primero en salir.')\n                continue\n            }\n            console.log(this.queue[i])\n        }\n        console.log('---')\n        console.log('Bot')\n    }\n\n\n}\n\nlet myQueue= new Queue()\nconsole.log(myQueue);\n\nmyQueue.addElement('elemento 1')\nmyQueue.addElement('elemento 2')\nmyQueue.addElement('elemento 3')\nmyQueue.addElement('elemento 4')\nmyQueue.addElement('elemento 5')\nmyQueue.show()\nconsole.log(myQueue.lengthStack);\nconsole.log(myQueue.getElement());\nconsole.log(myQueue.lengthStack);\n\n"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/Dan-Corbo.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n *\n */\n\n\n/* Soluciones */\n\n\nclass Persona {\n  // Inicializador\n  constructor(nombre, apellido, edad) {\n    this.nombre = nombre;\n    this.apellido = apellido;\n    this.edad = edad;\n  }\n\n  // Función para imprimir los atributos\n  imprimirInfo() {\n    console.log(`Nombre: ${this.nombre}`);\n    console.log(`Apellido: ${this.apellido}`);\n    console.log(`Edad: ${this.edad}`);\n  }\n}\n\n// Creación de una instancia de la clase\nconst persona1 = new Persona(\"Juan\", \"Pérez\", 30);\n\n// Modificación de los atributos\npersona1.nombre = \"Daniel\";\npersona1.apellido = \"Corbo\";\npersona1.edad = 24;\n\n// Impresión de los atributos\npersona1.imprimirInfo();\n\n\n/* Extra - Opcional */\n\n\nclass Pila {\n  constructor() {\n    this.pila = [];\n  }\n\n  apilar(elemento) {\n    this.pila.push(elemento);\n  }\n\n  desapilar() {\n    if (this.estaVacia()) {\n      return \"La pila está vacía\";\n    }\n    return this.pila.pop();\n  }\n\n  estaVacia() {\n    return this.pila.length === 0;\n  }\n\n  imprimirElementos() {\n    if (this.estaVacia()) {\n      return \"La pila está vacía\";\n    }\n    let resultado = \"Elementos:\\n\";\n    this.pila.forEach((elemento, index) => {\n      resultado += `Elemento ${index}: ${elemento}\\n`;\n    });\n    return resultado;\n  }\n}\n\nclass Cola {\n  constructor() {\n    this.cola = [];\n  }\n\n  encolar(elemento) {\n    this.cola.push(elemento);\n  }\n\n  desencolar() {\n    if (this.estaVacia()) {\n      return \"La cola está vacía\";\n    }\n    return this.cola.shift();\n  }\n\n  estaVacia() {\n    return this.cola.length === 0;\n  }\n\n  imprimirElementos() {\n    if (this.estaVacia()) {\n      return \"La cola está vacía\";\n    }\n    let resultado = \"Elementos:\\n\";\n    this.cola.forEach((elemento, index) => {\n      resultado += `Elemento ${index}: ${elemento}\\n`;\n    });\n    return resultado;\n  }\n}\n\n// Ejemplo de uso\n\nconst miPila = new Pila();\n\nmiPila.apilar(\"Hola\");\nmiPila.apilar(\"Mundo\");\nmiPila.apilar(\"!\");\n\nconsole.log(miPila.imprimirElementos());\n/* Salida: \nElementos:\nElemento 0: Hola\nElemento 1: Mundo\nElemento 2: ! */\nconsole.log(`Primer elemento: ${miPila.desapilar()}`); // Salida: !\nconsole.log(`Segundo elemento: ${miPila.desapilar()}`); // Salida: Mundo\nconsole.log(`¿Pila vacía?: ${miPila.estaVacia()}`); // Salida: false\nconsole.log(`Último elemento: ${miPila.desapilar()}`); // Salida: Hola\nconsole.log(`¿Pila vacía?: ${miPila.estaVacia()}`); // Salida: true\n\nconst miCola = new Cola();\n\nmiCola.encolar(\"Primero\");\nmiCola.encolar(\"Segundo\");\nmiCola.encolar(\"Tercero\");\n\nconsole.log(miCola.imprimirElementos());\n/* Salida: \nElementos:\nElemento 0: Primero\nElemento 1: Segundo\nElemento 2: Tercero */\nconsole.log(`Primer elemento: ${miCola.desencolar()}`); // Salida: Primero\nconsole.log(`Segundo elemento: ${miCola.desencolar()}`); // Salida: Segundo\nconsole.log(`¿Cola vacía?: ${miCola.estaVacia()}`); // Salida: false\nconsole.log(`Último elemento: ${miCola.desencolar()}`); // Salida: Tercero\nconsole.log(`¿Cola vacía?: ${miCola.estaVacia()}`); // Salida: true\n"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/DavidMoralesDeveloper.js",
    "content": "//clases\nclass Programmer {\n    //constructor en mi inicio \n    constructor(nombre, experiencia, lenguajes){\n        this.nombre = nombre,\n        this.experiencia = experiencia,\n        this.lenguajes = lenguajes\n\n    }\n    //funcion que imprima  console.log\n    mortrarData (){\n        console.log(this.nombre, this.experiencia, this.lenguajes + ' desde funcion mostrardata()')\n    }\n\n}\n//créala y establece sus parámetros\nlet myProgramer = new Programmer('Dav', 2, ['javascript', 'java', 'python'])\nmyProgramer.mortrarData()\n//modifícalos\nmyProgramer.experiencia = 5\nmyProgramer.mortrarData()\nmyProgramer.lenguajes.push('c#')\n//imprímelos utilizando su función.\nmyProgramer.mortrarData()\n\n\n// Extra \n// pila stack\nclass Pila {\n    constructor(stack){\n        this.stack = stack\n    }\n    añadir(num){\n        this.stack.push(num)\n    }\n    eliminar(){\n        this.stack.pop()\n    }\n    mostrar(){\n        console.log('numero de elemtos en mi pila :' + this.stack.length , ', ' + this.stack )\n    }\n}\n\nlet myPila = new Pila([1,2,3])\nmyPila.añadir(10)\nmyPila.añadir(15)\nmyPila.mostrar()\nmyPila.eliminar()\nmyPila.mostrar()\n\n// Cola queue \nclass Cola {\n    constructor(array){\n        this.array = array\n    }\n    añadir(num){\n        this.array.push(num)\n    }\n    eliminar(){\n        this.array.shift()\n    }\n    mostrar(){\n        console.log('numero de elemtos en mi pila :' + this.array.length , ', ' + this.array )\n    }\n\n\n\n}\n\nlet myCola = new Cola([])\n myCola.añadir('cliente')\n myCola.añadir('cliente1')\n myCola.añadir('cliente2')\nmyCola.eliminar()\n myCola.mostrar()\n"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/Deyvid-10.js",
    "content": "// Clases\n\nclass Nacionalidad\n{\n    constructor(pais, ciudad)\n    {\n        this.pais = pais\n        this.ciudad = ciudad\n    }\n\n    mostrarNacionalidad() \n    {\n        console.log(`Soy de ${this.pais} y vivo en la ciudad de ${this.ciudad}`);\n    }\n}\n\n\nlet miNacionalidad = new Nacionalidad(\"República Dominicana\", \"Santo Domingo\")\n\nmiNacionalidad.mostrarNacionalidad()\n\n// DIFICULTAD EXTRA\n\nclass Pilas\n{\n    constructor(pila)\n    {\n        this.pila = pila\n    }\n\n    push(nuevo) \n    {\n        this.pila.push(nuevo)\n    }\n\n    pop()\n    {\n        if(this.pila.length !== 0)\n        {\n            this.pila.pop()\n        }\n        else\n        {\n            console.log(\"La pila esta vacia\");\n        }\n    }\n\n    peek()\n    {\n        if(this.pila.length !== 0)\n        {\n            console.log(this.pila[this.pila.length-1]);\n        }\n        else\n        {\n            console.log(\"La pila esta vacia\");\n        }\n    }\n\n    isEmpty()\n    {\n        console.log(this.pila.length === 0);\n    }\n\n    length()\n    {\n        console.log(this.pila.length);\n    }\n\n    print()\n    {\n        console.log(this.pila);\n    }\n}\n\nlet miPila = new Pilas([1, 2, 3])\n\nmiPila.push(5)\nmiPila.pop()\nmiPila.peek()\nmiPila.isEmpty()\nmiPila.length()\nmiPila.print()\n\n\nclass Colas\n{\n    constructor(cola)\n    {\n        this.cola = cola\n    }\n\n    enqueue(nuevo) \n    {\n        this.cola.push(nuevo)\n    }\n\n    dequeue()\n    {\n        if(this.cola.length !== 0)\n        {\n            this.cola.shift()\n        }\n        else\n        {\n            console.log(\"La cola esta vacia\");\n        }\n    }\n\n    front()\n    {\n        \n        if(this.cola.length !== 0)\n        {\n            console.log(this.cola[0]);\n        }\n        else\n        {\n            console.log(\"La cola esta vacia\");\n        }\n    }\n\n    isEmpty()\n    {\n        console.log(this.cola.length === 0);\n    }\n\n    length()\n    {\n        console.log(this.cola.length);\n    }\n\n    print()\n    {\n        console.log(this.cola);\n    }\n}\n\nlet miCola = new Colas([1, 2, 3])\n\nmiCola.enqueue(4)\nmiCola.dequeue()\nmiCola.front()\nmiCola.isEmpty()\nmiCola.length()\nmiCola.print()"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/EloyChavezDev.js",
    "content": "/* \nEJERCICIO:\n *Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n \n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n*/\n\n// Clase básica con inicializador, atributos y función de impresión:\nclass Persona {\n    constructor(nombre, edad) {\n      this.nombre = nombre;\n      this.edad = edad;\n    }\n  \n    imprimir() {\n      console.log(`Nombre: ${this.nombre}`);\n      console.log(`Edad: ${this.edad}`);\n    }\n  }\n  \n  // Creación de una instancia de la clase\n  const persona1 = new Persona(\"Juan\", 25);\n  \n  // Modificación de los atributos\n  persona1.nombre = \"María\";\n  persona1.edad = 30;\n  \n  // Impresión de los atributos\n  persona1.imprimir();\n\n\n  //Dificultad Extra: Implementación de Pila y Cola\n  class Pila {\n    constructor() {\n      this.pila = [];\n    }\n  \n    // Añadir un elemento\n    push(elemento) {\n      this.pila.push(elemento);\n    }\n  \n    // Sacar un elemento\n    pop() {\n      return this.pila.pop();\n    }\n  \n    // Ver el último elemento sin sacarlo\n    peek() {\n      return this.pila[this.pila.length - 1];\n    }\n  \n    // Ver si la pila está vacía\n    estaVacia() {\n      return this.pila.length === 0;\n    }\n  \n    // Imprimir la pila\n    imprimir() {\n      console.log(\"Pila:\");\n      for (const elemento of this.pila) {\n        console.log(elemento);\n      }\n    }\n  }\n  \n  // Ejemplo de uso\n  const pila = new Pila();\n  pila.push(\"Elemento 1\");\n  pila.push(\"Elemento 2\");\n  pila.push(\"Elemento 3\");\n  \n  pila.imprimir();\n  \n  pila.pop();\n  \n  pila.imprimir();\n\n  //Clase Cola:\n  class Cola {\n    constructor() {\n      this.cola = [];\n    }\n  \n    // Añadir un elemento\n    enqueue(elemento) {\n      this.cola.push(elemento);\n    }\n  \n    // Sacar un elemento\n    dequeue() {\n      return this.cola.shift();\n    }\n  \n    // Ver el primer elemento sin sacarlo\n    peek() {\n      return this.cola[0];\n    }\n  \n    // Ver si la cola está vacía\n    estaVacia() {\n      return this.cola.length === 0;\n    }\n  \n    // Imprimir la cola\n    imprimir() {\n      console.log(\"Cola:\");\n      for (const elemento of this.cola) {\n        console.log(elemento);\n      }\n    }\n  }\n  \n  // Ejemplo de uso\n  const cola = new Cola();\n  cola.enqueue(\"Elemento 1\");\n  cola.enqueue(\"Elemento 2\");\n  cola.enqueue(\"Elemento 3\");\n  \n  cola.imprimir();\n  \n  cola.dequeue();\n  \n  cola.imprimir();"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/FabianRpv.js",
    "content": "// Clases\n\nclass Persona {\n\n    constructor(nombre, apellido, edad) {\n        this.nombre = nombre;\n        this.apellido = apellido;\n        this.edad = edad;\n    }\n\n    saludar(){\n        console.log(`Hola, soy ${this.nombre} ${this.apellido} y tengo ${this.edad} años`);\n    }\n}\n\nlet persona1 = new Persona('Fabian', 'Petit', 20);\n\npersona1.saludar();\n\npersona1.edad = 21;\n\npersona1.saludar();\n\n/*\n* DIFICULTAD EXTRA (opcional):\n* Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n* en el ejercicio número 7 de la ruta de estudio)\n* - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n*   retornar el número de elementos e imprimir todo su contenido.\n*/\n\nclass Pila {\n\n    constructor() {\n        this.elementos = [];\n    }\n\n    push(elemento){\n        this.elementos.push(elemento);\n    }\n\n    pop(){\n\n        if(this.isEmpty()){\n            return \"La pila está vacía\";\n        }\n\n        return this.elementos.pop();\n    }\n\n    peek(){\n        \n        if(this.isEmpty()){\n            return \"La pila está vacía\";\n        }\n\n        return this.elementos[this.elementos.length - 1];\n    }\n\n    isEmpty(){\n        return this.elementos.length === 0;\n    }\n\n    size(){\n        return this.elementos.length;\n    }\n}\n\nlet pila = new Pila();\npila.push(10);\npila.push(20);\npila.push(30);\n\nconsole.log(pila.peek()); // 30\nconsole.log(pila.pop());  // 30\nconsole.log(pila.isEmpty()); // false\nconsole.log(pila.size()); // 2\nconsole.log(pila.elementos);\n\n\n\n\nclass Cola {\n\n    constructor() {\n        this.elementos = [];\n    }\n\n    enqueue(elemento) {\n        this.elementos.push(elemento);\n    }\n\n    dequeue() {\n        if (this.isEmpty()) {\n            return \"La cola está vacía\";\n        }\n        return this.elementos.shift();\n    }\n\n    front() {\n        if (this.isEmpty()) {\n            return \"La cola está vacía\";\n        }\n        return this.elementos[0];\n    }\n\n    isEmpty() {\n        return this.elementos.length === 0;\n    }\n\n    size() {\n        return this.elementos.length;\n    }\n}\n\n\nlet cola = new Cola();\ncola.enqueue(10);\ncola.enqueue(20);\ncola.enqueue(30);\n\nconsole.log(cola.front()); // 10\nconsole.log(cola.dequeue()); // 10\nconsole.log(cola.isEmpty()); // false\nconsole.log(cola.size()); // 2\nconsole.log(cola.elementos);"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/Glitzypanic.js",
    "content": "class Programmer {\n  constructor(name, age, language) {\n    this.name = name;\n    this.age = age;\n    this.language = language;\n  }\n  printInfo() {\n    console.log(\n      `Name: ${this.name} | Age: ${this.age} | Language: ${this.language}`\n    );\n  }\n}\n\nconst my_programmer = new Programmer(\"Glitzypanic\", 25, \"JavaScript\");\nmy_programmer.printInfo();\n\n// EJERCICIO\nclass Stack {\n  constructor() {\n    this.stack = [];\n  }\n  push(item) {\n    this.stack.push(item);\n  }\n  pop() {\n    if (this.count() == 0) {\n      return null;\n    }\n    return this.stack.pop();\n  }\n  count() {\n    return this.stack.length;\n  }\n  print() {\n    for (let i = this.stack.length - 1; i >= 0; i--) {\n      console.log(this.stack[i]);\n    }\n  }\n}\n\nconst my_stack = new Stack();\nmy_stack.push(\"Jose\");\nmy_stack.push(\"Daniel\");\nmy_stack.push(\"Farias\");\nmy_stack.push(\"Cordova\");\nmy_stack.push(\"Glitzypanic\");\nconsole.log(my_stack.count());\nmy_stack.print();\nmy_stack.pop();\nmy_stack.pop();\nconsole.log(my_stack.count());\nconsole.log(my_stack.pop());\nmy_stack.print();\n\n// EJERCICIO 2\nclass Queue {\n  constructor() {\n    this.Queue = [];\n  }\n  push(item) {\n    this.Queue.push(item);\n  }\n  shift() {\n    if (this.Queue.length == 0) {\n      return null;\n    }\n    return this.Queue.shift();\n  }\n  count() {\n    return this.Queue.length;\n  }\n  print() {\n    for (let i = 0; i < this.Queue.length; i++) {\n      console.log(this.Queue[i]);\n    }\n  }\n}\n\nconst my_queue = new Queue();\nmy_queue.push(\"Tamara\");\nmy_queue.push(\"Francisca\");\nmy_queue.push(\"Nuñez\");\nmy_queue.push(\"Rodriguez\");\nmy_queue.count();\nmy_queue.print();\nconsole.log(my_queue.shift());\nconsole.log(my_queue.count());\nmy_queue.shift();\nconsole.log(my_queue.count());\nconsole.log(my_queue.shift());\n"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #08 - JavaScript ->Jesus Antonio Escamilla */\n/**\n * Las cales son plantillas para crear objetos.\n *  Las clases son una forma de encapsular datos y funciones relacionadas en un solo objeto,\n    proporcionando una estructura más organizada y orientada a objetos al código JavaScript. \n */\n\n//-----CLASE-----\nclass Persona{\n    // Inicializar\n    constructor(nombre, edad){\n        this.nombre = nombre;\n        this.edad = edad;\n    }\n\n    // Función\n    saludar(){\n        console.log(`Hola, soy ${this.nombre} y tengo ${this.edad} años.`);\n    }\n}\n\n// Crear un objeto para usar la clase\nconst persona1 = new Persona(\"Jesus Antonio\", 24);\n\n// Imprime la información\npersona1.saludar(); // Llama el saludo que esta dentro de la clase\n\n// Modificación del objeto\npersona1.nombre = \"Fatima\";\npersona1.edad = 19;\n\n// Imprimir información después de la modificación\npersona1.saludar();\n\n\n\n/**-----DIFICULTAD EXTRA-----*/\n\n//-----PILAS-----\nclass Stack{\n    constructor() {\n        this.pila = [];\n    }\n\n    push(item) {\n        return this.pila.push(item);\n    }\n\n    pop() {\n        if(this.count() == 0){\n            return \"None\";\n        }else{\n            return this.pila.pop();\n        }\n    }\n\n    count() {\n        return this.pila.length;\n    }\n\n    print(){\n        return console.log(this.pila);\n    }\n}\n\n//  Ejemplo de Pila\nconst myStack = new Stack();\nmyStack.push(\"A\");\nmyStack.push(\"B\");\nmyStack.push(\"C\");\nconsole.log(myStack.count()); // Imprime -> 3\nmyStack.print(); //[ 'A', 'B', 'C' ]\nconsole.log(myStack.pop()); // Imprime -> 'C'\nconsole.log(myStack.pop()); // Imprime -> 'B'\nconsole.log(myStack.pop()); // Imprime -> 'A'\nconsole.log(myStack.pop()); // Imprime -> None\nconsole.log(myStack.print()); // Imprime -> undefined - Ya no hay elementos en la lista\n\n\n\n//-----COLAS-----\nclass Queue{\n    constructor() {\n        this.cola = [];\n    }\n\n    enqueue(item) {\n        return this.cola.push(item);\n    }\n\n    dequeue() {\n        if (this.count() == 0) {\n            return \"None\"\n        }else{\n            return this.cola.shift();\n        }\n    }\n\n    count() {\n        return this.cola.length;\n    }\n\n    print() {\n        return console.log(this.cola);\n    }\n}\n\n//  Ejemplo de Cola\nconst myQueue = new Queue();\nmyQueue.enqueue(\"A\");\nmyQueue.enqueue(\"B\");\nmyQueue.enqueue(\"C\");\nconsole.log(myQueue.count());\nmyQueue.print(); //[ 'A', 'B', 'C' ]\nconsole.log(myQueue.dequeue()); // Imprime -> 'A'\nconsole.log(myQueue.dequeue()); // Imprime -> 'B'\nconsole.log(myQueue.dequeue()); // Imprime -> 'C'\nconsole.log(myQueue.dequeue()); // Imprime -> None\nconsole.log(myQueue.print()); // Imprime -> undefined - Ya no hay elementos en la lista\n\n/**-----DIFICULTAD EXTRA-----*/"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/MatiTC.js",
    "content": "/*\n * EJERCICIO:\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n *\n */\n\n// Definición de la clase Persona\nclass Persona {\n  // Inicializado (constructor :  es un método especial para crear e inicializar un objeto)\n  constructor(nombre, edad) {\n    this.nombre = nombre; // Atributo nombre\n    this.edad = edad; // Atributo edad\n  }\n\n  // Función para imprimir los atributos\n  imprimirInformacion() {\n    console.log(`Nombre: ${this.nombre}, Edad: ${this.edad}`);\n  }\n  // Función para modificar los atributos\n  modificarNombre(nombre) {\n    this.nombre = nombre;\n  }\n  // Función para modificar los atributos\n  modificarEdad(edad) {\n    this.edad = edad;\n  }\n}\n// Creación de una instancia de la clase Persona\nconst persona1 = new Persona('Matias', 24);\n// Llamada a la función para imprimir los atributos\npersona1.imprimirInformacion(); // Salida esperada: Nombre: Matias, Edad: 24\n// Llamada a la funcion para modificar(edad)\npersona1.modificarEdad(25);\npersona1.imprimirInformacion(); // Salida esperada: Nombre: Matias, Edad: 25\n\n//<---Dificultad extra--->\n//<---Pila/stacks--->\n// Definición de la clase Pila\nclass Pila {\n  // Atributos\n  // Constructor de la clase\n  constructor() {\n    this.items = []; // Array para almacenar los elementos de la pila\n  }\n  //Funciones\n  // Método para agregar un elemento a la pila\n  push(elemento) {\n    this.items.push(elemento);\n  }\n  // Método para eliminar y devolver el último elemento de la pila\n  pop() {\n    if (this.items.length === 0) {\n      return 'La pila está vacía'; // Si la pila está vacía, se devuelve un mensaje\n    }\n    return this.items.pop(); // Se elimina y devuelve el último elemento de la pila\n  }\n  // Método para obtener el tamaño de la pila\n  size() {\n    return this.items.length; // Se devuelve el tamaño de la pila\n  }\n  // Método para vaciar la pila\n  clear() {\n    this.items = []; // Se vacía la pila\n  }\n}\n\n// Ejemplo de uso de la clase Pila\nconst pruebaPila = new Pila(); // Creamos una nueva instancia de la clase Pila\npruebaPila.push(1); // Agregamos el elemento 1 a la pila\npruebaPila.push(2); // Agregamos el elemento 2 a la pila\npruebaPila.push(3); // Agregamos el elemento 3 a la pila\nconsole.log('Elementos de la pila:', pruebaPila.items); // Mostramos los elementos de la pila\nconsole.log('Tamaño de la pila:', pruebaPila.size()); // Mostramos el tamaño de la pila\nconsole.log('Se saca con pop:', pruebaPila.pop()); // Desapilamos un elemento de la pila\nconsole.log('Elementos de la pila después del pop:', pruebaPila.items); //\n\n//<---Cola--->\n// Definición de la clase Cola\nclass Cola {\n  // Constructor de la clase\n  constructor() {\n    this.items = []; // Array para almacenar los elementos de la cola\n  }\n  // Método para agregar un elemento a la cola\n  enqueue(elemento) {\n    this.items.push(elemento); // Agrega el elemento al final de la cola\n  }\n  // Método para eliminar y devolver el primer elemento de la cola\n  dequeue() {\n    if (this.items.length === 0) {\n      return 'La cola está vacía'; // Si la cola está vacía, se devuelve un mensaje\n    }\n    return this.items.shift(); // Elimina y devuelve el primer elemento de la cola\n  }\n  // Método para obtener el tamaño de la cola\n  size() {\n    return this.items.length; // Devuelve el tamaño de la cola\n  }\n  // Método para vaciar la cola\n  clear() {\n    this.items = []; // Vacía la cola\n  }\n}\n// Ejemplo de uso de la clase Cola\nconst cola = new Cola(); // Creamos una nueva instancia de la clase Cola\ncola.enqueue('a'); // Agregamos el elemento \"a\" a la cola\ncola.enqueue('b'); // Agregamos el elemento \"b\" a la cola\ncola.enqueue('C'); // Agregamos el elemento \"b\" a la cola\nconsole.log('Elementos de la cola:', cola.items); // Mostramos los elementos de la cola\nconsole.log('Tamaño de la cola:', cola.size()); // Mostramos el tamaño de la cola\nconsole.log('Se desencola:', cola.dequeue()); // Desencolamos un elemento de la cola\nconsole.log('Elementos de la cola después de desencolar:', cola.items); // Mostramos los elementos de la cola después de desencolar\n"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/Nightblockchain30.js",
    "content": "class Human {\n  constructor(name,username,age){\n    this.name = name;\n    this.username = username;\n    this.age = age;\n    this.nickName = \"No tengo apodo\"; // Está propiedad no es necesario introducirla en el momento de crear la instancia\n  }\n\n  // Métodos GET y SET para el atributo \"privado\" nickName\n  get getNickname(){\n    return this.nickName\n  }\n\n  set setNickName(value){\n    this.nickName = value;\n  }\n}\n\n//CASO DE USO\nlet humano1 = new Human(\"Mimi\",\"Bébe\",26);\nhumano1.getNickname;\nhumano1.setNickName = \"Tio Billete\";\nhumano1.getNickname;\n\n/* DIFICULTAD EXTRA */\n\nclass Stack {\n  constructor(){\n    this.nameStack = null;\n    this.stateStack = [];\n  }\n  // ADD or Push\n  add(num) {\n    this.stateStack.push(num)\n  }\n\n  // REMOVE o Pop\n  pop(){\n    this.stateStack.pop();\n  }\n\n  get getState(){\n    return this.stateStack;\n  }\n\n  get getName(){\n    return this.nameStack;\n  }\n\n  set setName(value){\n      this.nameStack = value;\n    }\n\n}\n\n\n// CASO DE USO\nlet stack1 = new Stack();\n\nstack1.add(1);\nstack1.add(2);\nstack1.add(3);\n\nstack1.getState;\n\nstack1.pop();\n\nstack1.getState;\n\nstack1.getName;\nstack1.setName = \"pila1\";\nstack1.getName;\n\n\nclass Queue{\n  constructor(){\n    this.stateQueue = [];\n  }\n\n  add(num){\n    this.stateQueue.push(num);\n  }\n\n  pop(){\n    this.stateQueue.shift();\n  }\n\n  get getState() {\n    return this.stateQueue;\n  }\n}\n\nlet cola = new Queue();\ncola.add(1);\ncola.add(2);\ncola.add(3);\n\ncola.getState;\n\ncola.pop();\n\ncola.getState;\n\n"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/OmarLand.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n */\n\n// Practicando: Clases:\nclass Player{\n    \n    constructor( name, hatColor, game ){\n        this._name     = name;\n        this._hatColor = hatColor;\n        this._game     = game;\n    }\n\n    jump(){\n        console.log(\"Cada vez que gano yo salto varias veces xD\");\n    }\n    run(){\n        console.log(\"En mis ratos libres salgo a correr\");\n    }\n    walk(){\n        console.log(\"Y cuando me canso salgo a caminar\");\n    }\n\n    greets(){\n        return `Hola soy el Jugador ${this._name} y soy sombrero ${this._hatColor} y me gusta jugar ${this._game}`\n    }\n}\n\nlet player1 = new Player(\"Omar\",\"Negro\",\"God of War\");\nlet player2 = new Player(\"Juan\",\"Gris\", \"Call of duty\");\n\nconsole.log(\">>>\", player1.greets() );\nconsole.log(\">>>\", player2.greets() );\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n */\n\n// Ejercicio aplicando Pila:\nclass Games{\n    constructor( element ){\n        this.element = [];\n    }\n\n    pushing( game ){\n        return this.element.push( game );\n    }\n    poping(){\n        this.size() === 0 ? 'La cola está vacía' : this.element.pop();\n    }\n    sizing(){\n        return this.element.length;\n    }\n    printing(){\n        this.element.forEach( (element) => { console.log(element) } );\n    }\n}\n\nlet myGames = new Games();\nmyGames.pushing(\"God of War\")\nmyGames.pushing(\"PlantsVsZombies\");\nmyGames.pushing(\"Mortal Kombat\");\nmyGames.poping();\nmyGames.poping();\nmyGames.printing();\n\n\n// Ejercicio aplicando Cola:\nclass Queue{\n    constructor( cola ){\n        this.cola = [];\n    }\n\n    //implementamos la función enqueue para meter datos en cola:\n    enqueue( element ){\n        return this.cola.push( element );\n    }\n\n    //Ahora implemenramos función para sacar elementos de la cola\n    dequeue(){\n        if( this.size() === 0){\n            return 'No hay elementos en cola...'\n        }  \n        return this.cola.shift();\n    }\n\n    //Función para ver cantidad de elementos en cola\n    size(){\n        return this.cola.length;\n    }   \n\n    // función para ver los elementos de la cola\n    print(){\n        this.cola.forEach( (element) =>{\n            console.log(element);\n        });\n    }\n}\n\nlet myQueue = new Queue();\nmyQueue.enqueue(\"elemento_1\");\nmyQueue.enqueue(\"elemento_2\");\nmyQueue.enqueue(\"elemento_3\");\nmyQueue.enqueue(\"elemento_4\");\nmyQueue.dequeue();\nmyQueue.dequeue();\nmyQueue.dequeue();\nmyQueue.print();\n//myQueue.size();"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/Pancratzia.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n *\n */\n\n/************* PARTE 1 *************/\n\nclass Perro {\n  constructor(nombre = \"Tiffany\", raza = \"Poodle\", edad = 8) {\n    this._nombre = nombre;\n    this._raza = raza;\n    this._edad = edad;\n  }\n\n  get nombre() {\n    return this._nombre;\n  }\n\n  set nombre(nombre) {\n    this._nombre = nombre;\n  }\n\n  get raza() {\n    return this._raza;\n  }\n\n  set raza(raza) {\n    this._raza = raza;\n  }\n\n  get edad() {\n    return this._edad;\n  }\n\n  set edad(edad) {\n    this._edad = edad;\n  }\n\n  toString() {\n    return `Nombre: ${this._nombre}\n    Raza: ${this._raza}\n    Edad: ${this._edad}`;\n  }\n}\n\nconst perro = new Perro();\nconsole.log(perro.toString());\n\nconsole.log(\"Pero espera... ¡ES EL CUMPLEAÑOS DE TIFFANY!\");\nperro.edad = 9;\nconsole.log(perro.toString());\n\n/************* DIFICULTAD EXTRA *************/\n\nclass Pila {\n  constructor() {\n    this.pila = [];\n  }\n\n  push(elemento) {\n    this.pila.push(elemento);\n  }\n\n  pop() {\n    this.pila.pop();\n  }\n\n  size() {\n    return this.pila.length;\n  }\n\n  print() {\n    return this.pila;\n  }\n}\n\nconst pila = new Pila();\npila.push(\"hola\");\npila.push(\"mundo\");\npila.push(\"!\");\nconsole.log(pila.print());\nconsole.log(pila.size());\n\nclass Cola {\n  constructor() {\n    this.cola = [];\n  }\n\n  encolar(elemento) {\n    this.cola.push(elemento);\n  }\n\n  desencolar() {\n    this.cola.shift();\n  }\n\n  size() {\n    return this.cola.length;\n  }\n\n  print() {\n    return this.cola;\n  }\n}\n\nconst cola = new Cola();\ncola.encolar(\"hola\");\ncola.encolar(\"mundo\");\ncola.encolar(\"!\");\ncola.encolar(\"Soy\");\ncola.encolar(\"una\");\ncola.encolar(\"cola\");\nconsole.log(cola.print());\nconsole.log(cola.size());"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/RaulDoezon.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n * \n*/\n\nconsole.log(\"+++++++++ EJERCICIO +++++++++\");\nclass Greeting {\n  constructor(name, occupation) {\n    this.name = name;\n    this.occupation = occupation;\n  }\n\n  message() {\n    return `Hello, my name is ${this.name} and I'm a ${this.occupation}!`\n  }\n}\n\nlet hello = new Greeting(\"Samus\", \"Bounty Hunter\");\nconsole.log(hello.message());\nconsole.log(\"Modificación de los parámetros e impresión del resultado:\");\nhello.name = \"Peter\";\nhello.occupation = \"Photographer\";\nconsole.log(hello.message());\n\nconsole.log(\"\\n+++++++++ DIFICULTAD EXTRA: PILA +++++++++\");\nclass MyStack {\n  constructor() {\n    this.stackArray = [];\n  }\n\n  add(element) {\n    this.stackArray.push(element);\n    const pushedElement = this.stackArray[this.stackArray.length - 1];\n    console.log(`Se agregó el elemento \"${pushedElement}\" a la pila.`);\n  }\n\n  remove() {\n    const poppedElement = this.stackArray.pop();\n    console.log(`Se eliminó el elemento \"${poppedElement}\" de la Pila.`);\n  }\n\n  length() {\n    console.log(`Hay ${this.stackArray.length} elementos en la pila:`);\n  }\n\n  show() {\n    console.log(this.stackArray);\n  }\n}\n\nlet stack = new MyStack();\n\nstack.add(\"La Historia de un Cowboy\");\nstack.add(\"Plexo Solar\");\nstack.add(\"Espera\");\nstack.length()\nstack.show();\nstack.remove();\nstack.length()\nstack.show();\n\nconsole.log(\"\\n+++++++++ DIFICULTAD EXTRA: COLA +++++++++\");\nclass MyQueue {\n  constructor() {\n    this.queueArray = [];\n  }\n\n  add(element) {\n    this.queueArray.push(element);\n    const pushedElement = this.queueArray[this.queueArray.length - 1];\n\n    console.log(`El elemento \"${pushedElement}\" se agregó a la fila.`);\n  }\n\n  remove() {\n    const shiftedElement = this.queueArray.shift();\n\n    console.log(`El elemento \"${shiftedElement}\" se desplazó de la fila.`);\n  }\n\n  length() {\n    const queueLength = this.queueArray.length;\n    console.log(`La fila contiene ${queueLength} elementos:`);\n  }\n\n  show() {\n    console.log(this.queueArray);\n  }\n}\n\nlet queue = new MyQueue();\n\nqueue.add(\"Alfredo\");\nqueue.add(\"Diego\");\nqueue.add(\"Raúl\");\nqueue.length();\nqueue.show();\nqueue.remove();\nqueue.length();\nqueue.show();\n"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/RicJDev.js",
    "content": "//===CONCEPTO DE CLASE===//\nconsole.log('\\n-CREANDO UNA CLASE-');\nclass Estudiante {\n\tconstructor(nombre, edad, carrera, semestre) {\n\t\tthis.nombre = nombre;\n\t\tthis.edad = edad;\n\t\tthis.carrera = carrera;\n\t\tthis.semestre = semestre;\n\t}\n\n\tmuestraPropiedades() {\n\t\tconsole.log(\n\t\t\t`  Nombre: ${this.nombre}, edad: ${this.edad}, carrera: ${this.carrera}, semestre: ${this.semestre}.`\n\t\t);\n\t}\n}\n\nlet estudiante1 = new Estudiante('Ricardo', 21, 'Ingieneria de sistemas', 'primer semestre');\n\nconsole.log('*Aquí imprimimos el objeto creado a partir de la clase:\\n', estudiante1);\n\nconsole.log('\\n*Ahora utilizaremos el método de la clase para ver sus propiedades:');\nestudiante1.muestraPropiedades();\n\nconsole.log('\\n*Aquí imprimimos una propiedad en específico antes de modificarla:');\nconsole.log(`  Edad: ${estudiante1.edad}`);\n\nestudiante1.edad = 22;\nestudiante1.semestre = 'tercer semestre';\n\nconsole.log('\\n*Aquí imprimimos la misma propiedad luego de modificarla:');\nconsole.log(`  Edad: ${estudiante1.edad}`);\n\nconsole.log('\\n*Utilizando el método se vería así:');\nestudiante1.muestraPropiedades();\n\nconsole.log('\\n*He actualizado el semestre también :D');\n\n//===CREANDO CLASE PILA===//\nconsole.log('\\n-PILA-');\nclass Pila {\n\tconstructor() {\n\t\tthis.pila = [];\n\t}\n\n\tapilar(elemento) {\n\t\tthis.pila.push(elemento);\n\t}\n\n\tdesapilar() {\n\t\tif (this.pila.length > 0) {\n\t\t\treturn this.pila.pop();\n\t\t} else {\n\t\t\tconsole.log('\\nPila vacía');\n\t\t}\n\t}\n\n\tcontar() {\n\t\tif (this.pila.length > 0) {\n\t\t\treturn this.pila.length;\n\t\t} else {\n\t\t\treturn '\\nPila vacía';\n\t\t}\n\t}\n\n\tmostrar() {\n\t\tconsole.log(`\\nContenido de la pila: \\n${this.pila}`);\n\t}\n}\n\nconsole.log(\n\t'\\n*Ya hecha la clase y sus métodos, creamos una nueva pila y le apilamos elementos, cuya cantidad y contenido podemos mostrar en consola:'\n);\n\nlet myStack = new Pila();\n\nmyStack.apilar(23);\nmyStack.apilar(43);\nmyStack.apilar(12);\nmyStack.apilar(98);\nmyStack.apilar(100);\n\nconsole.log(`\\nCantidad de elementos de la pila: ${myStack.contar()}`);\n\nmyStack.mostrar();\n\nconsole.log('\\n*Probamos desapilar elementos y volvemos a mostrar la cantidad y contenido:');\n\nmyStack.desapilar();\n\nconsole.log(`\\nCantidad de elementos de la pila: ${myStack.contar()}`);\n\nmyStack.mostrar();\n\nconsole.log('\\n*Creamos una nueva pila para que nos muestre este mensaje cuando esté vacía:');\n\nlet myStack2 = new Pila();\n\nconsole.log(`\\nCantidad de elementos de la nueva pila: ${myStack2.contar()}`);\n\n//===CREANDO CLASE COLA===//\nconsole.log('\\n-COLA-');\nclass Cola {\n\tconstructor() {\n\t\tthis.cola = [];\n\t}\n\n\tencolar(elemento) {\n\t\tthis.cola.push(elemento);\n\t}\n\n\tdesencolar() {\n\t\tif (this.cola.length > 0) {\n\t\t\treturn this.cola.shift();\n\t\t} else {\n\t\t\tconsole.log('\\nCola vacía');\n\t\t}\n\t}\n\n\tcontar() {\n\t\tif (this.cola.length > 0) {\n\t\t\treturn this.cola.length;\n\t\t} else {\n\t\t\treturn '\\nCola vacía';\n\t\t}\n\t}\n\n\tmostrar() {\n\t\tconsole.log(`\\nContenido de la cola: \\n${this.cola}`);\n\t}\n}\n\nconsole.log(\n\t'\\n*Ya hecha la clase y sus métodos, creamos una nueva cola y encolamos elementos, cuya cantidad y contenido podemos mostrar en consola:'\n);\n\nlet myQueue = new Cola();\n\nmyQueue.encolar(12);\nmyQueue.encolar(20);\nmyQueue.encolar(33);\nmyQueue.encolar(200);\nmyQueue.encolar(1);\n\nconsole.log(`\\nCantidad de elementos de la cola: ${myQueue.contar()}`);\n\nmyQueue.mostrar();\n\nconsole.log('\\n*Probamos desencolar elementos y volvemos a mostrar la cantidad y contenido:');\n\nmyQueue.desencolar();\n\nconsole.log(`\\nCantidad de elementos de la cola: ${myQueue.contar()}`);\n\nmyQueue.mostrar();\n\nconsole.log('\\n*Creamos una nueva cola para ver este mensaje si está vacía:');\n\nlet myQueue2 = new Cola();\n\nconsole.log(`\\nCantidad de elementos de la nueva cola: ${myQueue2.contar()}`);\n"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/Sac-Corts.js",
    "content": "// Exercise\nclass Person {\n    constructor(name, age) {\n        this.name = name;\n        this.age = age;\n    }\n\n    greet() {\n        console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`); \n        }\n}\n\nisaac = new Person('Isaac', 22);\nisaac.greet();\n\nisaac.name = 'Isaac Cortés';\nisaac.age = 23;\nisaac.greet();\n\n// Extra Exercise //\nclass Stack {\n    constructor() {\n        this.array = [];\n    }\n\n    push(item) {\n        this.array.push(item);\n    }\n\n    pop() {\n        if (this.isEmpty()) {\n            return \"Stack is empty.\";\n        }\n        return this.array.pop();\n    }  \n\n    peek() {\n        if (this.isEmpty()) {\n            return \"Stack is empty.\";\n        }\n        return this.array[this.array.length - 1];\n    }\n\n    isEmpty() {\n        return this.array.length === 0;\n    }\n\n    size() {\n        return this.array.length;\n    }\n}\n\nconst stack = new Stack();\nstack.push('Karina');\nstack.push('Isaac');\nstack.push('Danna');\nconsole.log(stack.peek());\nconsole.log(stack.pop());\nconsole.log(stack.isEmpty());\nconsole.log(stack.size());\n\n\nclass Queue{\n    constructor() {\n        this.array = [];\n    }\n\n    enqueue(item) {\n        this.array.push(item);\n    } \n\n    dequeue() {\n        if (this.isEmpty()) {\n            return \"Queue is empty.\"\n        }\n        return this.array.shift();\n    }\n\n    front() {\n        if (this.isEmpty()) {\n            return \"Queue is empty.\"\n        }\n        return this.array[0];\n    }\n\n    isEmpty() {\n        return this.array.length === 0;\n    }\n\n    size() {\n        return this.array.length;\n    }\n}\n\nconst queue = new Queue();\nqueue.enqueue('Marco');\nqueue.enqueue('Ceci');\nqueue.enqueue('Jenni');\nconsole.log(queue.front());\nconsole.log(queue.dequeue());\nconsole.log(queue.isEmpty());\nconsole.log(queue.size());\n\n\n\n\n"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/adrs1166ma.js",
    "content": "/*\nEJERCICIO:\nExplora el concepto de clase y crea un ejemplo que implemente un inicializador,\natributos y una función que los imprima (teniendo en cuenta las posibilidades\nde tu lenguaje).\nUna vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\nutilizando su función.\n\nDIFICULTAD EXTRA (opcional):\nImplementa dos clases que representen las estructuras de Pila y Cola (estudiadas\nen el ejercicio número 7 de la ruta de estudio)\n- Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\nretornar el número de elementos e imprimir todo su contenido.\n*/\n\n// 🔥 Clase básica\nclass Persona {\n    constructor(nombre, edad, ciudad) {\n        this.nombre = nombre;\n        this.edad = edad;\n        this.ciudad = ciudad;\n    }\n\n    imprimirDatos() {\n        console.log(`Nombre: ${this.nombre}, Edad: ${this.edad}, Ciudad: ${this.ciudad}`);\n    }\n}\n\n// Instancia\nconst persona1 = new Persona(\"Anderson\", 20, \"Lima\");\npersona1.imprimirDatos(); // Nombre: Anderson, Edad: 20, Ciudad: Lima\n\n// Modificar los atributos\npersona1.nombre = \"Adrs\";\npersona1.edad = 21;\npersona1.imprimirDatos(); // Nombre: Adrs, Edad: 21, Ciudad: Lima\n\n// 🔥 EXTRA - Pila y Cola\n\n// Clase Pila (Stack - LIFO)\nclass Pila {\n    constructor() { this.items = [] }\n\n    // Añadir un elemento a la pila\n    push(element) { this.items.push(element) }\n\n    // Eliminar el último elemento añadido\n    pop() {\n        return this.isEmpty() ? 'La pila está vacía' : this.items.pop()\n    }\n\n    // Ver el último elemento sin eliminarlo\n    peek() {\n        return this.isEmpty() ? 'La pila está vacía' : this.items[this.items.length - 1]\n    }\n\n    // Verificar si la pila está vacía\n    isEmpty() {\n        return this.items.length === 0;\n    }\n\n    // Retornar el número de elementos\n    size() {\n        return this.items.length;\n    }\n\n    // Mostrar el contenido de la pila\n    print() {\n        console.log(this.items.toString()||'La pila está vacía');\n    }\n}\n\nconst pila = new Pila();\nconsole.log('*************** Clase Pila (Stack - LIFO) ********************')\npila.print(); // La pila está vacía\npila.push(\"A\");\npila.push(\"B\");\npila.push(\"C\");\npila.print(); // A,B,C\nconsole.log(\"Tamaño:\", pila.size()); // Tamaño: 3\nconsole.log(\"Eliminado:\", pila.pop()); // Eliminado: C\npila.print(); // A,B\n\n\n// Clase Cola (Queue - FIFO)\nclass Cola {\n    constructor() { this.items = [] }\n    \n    // Añadir un elemento a la cola\n    enqueue(element) { this.items.push(element) }\n\n    // Eliminar el primer elemento añadido\n    dequeue() {\n        return this.isEmpty() ? 'La cola está vacía' : this.items.shift()\n    }\n\n    // Ver el primer elemento sin eliminarlo\n    front() {\n        return this.isEmpty() ? 'La cola está vacía' : this.items[0]\n    }\n    \n    // Verificar si la cola está vacía\n    isEmpty() {\n        return this.items.length === 0;\n    }\n    \n    // Retornar el número de elementos\n    size() {\n        return this.items.length;\n    }\n\n    // Imprimir el contenido de la cola\n    print() {\n        console.log(this.items.toString() || \"La cola está vacía\");\n    }\n}\n\n\nconst cola = new Cola();\nconsole.log('*************** Clase Cola (Queue - FIFO) ********************')\ncola.print(); // La cola está vacía\ncola.enqueue(\"A\");\ncola.enqueue(\"B\");\ncola.enqueue(\"D\");\ncola.print(); // A,B,D\nconsole.log(\"Tamaño:\", cola.size()); // Tamaño: 3\nconsole.log(\"Eliminado:\", cola.dequeue()); // Eliminado: A\ncola.print(); // B,D"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/agusrosero.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n *\n */\n\n// EJERCICIO\nclass MiClase {\n  constructor(name) {\n    this.name = name;\n  }\n\n  get saludo() {\n    return this.saludar();\n  }\n\n  saludar() {\n    console.log(`Hola ${this.name}!`);\n  }\n}\n\nconst test = new MiClase(\"Hernan\");\nconsole.log(test.name);\ntest.saludar();\n\n// DIFICULTAD EXTRA:\nclass Stack {\n  constructor() {\n    this.stack = [];\n  }\n\n  push(element) {\n    this.stack.push(element);\n    return this.stack;\n  }\n\n  pop() {\n    return this.stack.pop();\n  }\n\n  len() {\n    return this.stack.length;\n  }\n\n  print() {\n    console.log(this.stack);\n  }\n}\n\nconst stack = new Stack();\nstack.push(1);\nstack.push(2);\nstack.push(3);\nstack.pop();\nconsole.log(stack.len());\nstack.print();\n\nclass Queue {\n  constructor() {\n    this.queue = [];\n  }\n\n  enqueue(element) {\n    this.queue.push(element);\n    return this.queue;\n  }\n\n  dequeue() {\n    return this.queue.shift();\n  }\n\n  len() {\n    return this.queue.length;\n  }\n\n  print() {\n    return this.queue;\n  }\n}\n\nconst queue = new Queue();\nqueue.enqueue(\"Test1\");\nqueue.enqueue(\"Test2\");\nqueue.enqueue(\"Test3\");\nqueue.dequeue();\nconsole.log(queue.len());\nconsole.log(queue.print());\n"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/airesEsteban.js",
    "content": "/*\nEJERCICIO:\nExplora el concepto de clase y crea un ejemplo que implemente un inicializador,\natributos y una función que los imprima (teniendo en cuenta las posibilidades\nde tu lenguaje).\nUna vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\nutilizando su función.\n\nDIFICULTAD EXTRA (opcional):\nImplementa dos clases que representen las estructuras de Pila y Cola (estudiadas\nen el ejercicio número 7 de la ruta de estudio)\n- Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\nretornar el número de elementos e imprimir todo su contenido.\n*/\n\nclass Person {\n    constructor(name, age){\n        this.name = name\n        this.age = age\n    }\n\n    imprimirDatos(){\n        console.log(`Nombre: ${this.name}, Edad: ${this.age}`)\n    }\n}\n// Instancia\nconst person = new Person (\"Esteban\", 38)\nperson.imprimirDatos()\n\n// Modificar los atributos\n\nperson.name = \"Carlos\"\nperson.age = 22\nperson.imprimirDatos()\n\n//  EXTRA - Pila y Cola\n\n// Clase Pila (Stack - LIFO)\n\nclass Pila {\n    constructor(data){\n        this.data = data\n    }\n\n    addElementAction(element){\n        return this.data.unshift(element)\n    }\n\n    deleteElementAction(){\n        return this.data.shift()\n    }\n\n    numberElementAction(){\n        return this.data.length\n    }\n\n    get addElement(){\n        return this.addElementAction\n    }\n\n    get deleteElement(){\n        return this.deleteElementAction\n    }\n\n    get numberElement(){\n        return this.numberElementAction\n    }\n}\n\nconst nuevaPila = new Pila([])\n\nconsole.log(\"Pila vacia\", nuevaPila)\nnuevaPila.addElement(1)\nnuevaPila.addElement(2)\nnuevaPila.addElement(3)\nconsole.log('Nuevos elementos agregados', nuevaPila)\nconsole.log('Cantidad de elementos', nuevaPila.numberElement())\nnuevaPila.deleteElement()\nconsole.log('Eliminado ultimo elemento', nuevaPila)\n\nclass Cola {\n    constructor(data){\n        this.data = data\n    }\n\n     addElementAction(element){\n        return this.data.push(element)\n    }\n\n    deleteElementAction(){\n        return this.data.shift()\n    }\n\n    numberElementAction(){\n        return this.data.length\n    }\n\n    get addElement(){\n        return this.addElementAction\n    }\n\n    get deleteElement(){\n        return this.deleteElementAction\n    }\n\n    get numberElement(){\n        return this.numberElementAction\n    }\n\n}\n\nconst nuevaCola = new Cola([])\n\nconsole.log(\"Pila vacia\", nuevaCola)\nnuevaCola.addElement(1)\nnuevaCola.addElement(2)\nnuevaCola.addElement(3)\nconsole.log('Nuevos elementos agregados', nuevaCola)\nconsole.log('Cantidad de elementos', nuevaCola.numberElement())\nnuevaCola.deleteElement()\nconsole.log('Eliminado ultimo elemento', nuevaCola)\n"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/alexdevrep.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n */\n\n//Las clases son funciones \"especiales\", su sintaxis tiene dos componentes: expresiones de clase y declaraciones de clase\n\n//Declaramos una clase en JavaScript\n\n class ejemplo {\n    //Inicializamos la clase con el método constructor\n    constructor(cadena1,cadena2){ \n        //Estos son los atributos de la clase\n        this.saludo = cadena1  \n        this.nombre = cadena2\n\n\n    }\n    //Esta es la función que va a imprimir los atributos de la clase tambien llamado método\n    saludar(){ \n        return this.saludo + \",\" + this.nombre\n    }\n\n}\n\n//Creamos instancias de la clase ejemplo con parámetros diferentes\nconst hola = new ejemplo(\"Hola\",\"JavaScript\") \n\n\n//Imprimimos por pantalla el contenido de la clase\nconsole.log(hola.saludar()) \n\n//Tambien podemos modificar los atributos de la clase\nhola.nombre= \"Alexdevrep\"\n\n//Imprimimos el resultado nuevamente\nconsole.log(hola.saludar())\n\n\n//Dificultad EXTRA\n//Pila\nclass Pila {\n    constructor() {\n        this.elementos = [];\n    }\n\n    añadir(objeto) {\n        this.elementos.push(objeto);\n    }\n\n    eliminar() {\n        if (this.elementos.length === 0) {\n            console.log(\"La pila está vacía\");\n            return;\n        }\n        return this.elementos.pop();\n    }\n\n    imprimirTodo() {\n        if (this.elementos.length === 0) {\n            console.log(\"La pila está vacía\");\n            return;\n        }\n        console.log(\"Contenido de la pila: \");\n        this.elementos.forEach(function(objeto, index) {\n            console.log(`${index + 1}.${objeto}`);\n        });\n    }\n\n    numeroElementos() {\n        return this.elementos.length;  // Corregido para retornar el número de elementos\n    }\n}\n\n// Creamos la instancia de la clase\nconst pilaObjetos = new Pila();\n\n// Añadimos elementos a la pila\npilaObjetos.añadir(\"Objeto 1\");\npilaObjetos.añadir(\"Objeto 2\");\npilaObjetos.añadir(\"Objeto 3\");\n\n// Imprimimos el contenido de la pila\npilaObjetos.imprimirTodo();\n\n// Eliminamos el último elemento de la pila en entrar\npilaObjetos.eliminar();\n\n// Imprimimos de nuevo la pila para comprobar que ha pasado\npilaObjetos.imprimirTodo();\n\n// Obtenemos el numero de elementos de la Pila\nconst cantidadElementos = pilaObjetos.numeroElementos();\nconsole.log(`Número de elementos en la pila: ${cantidadElementos}`);\n\n//Cola\nclass cola {\n    constructor(){\n        this.cola = []\n    }\n    insertar(cadena){\n        this.cola.push(cadena)\n\n    }\n    borrar(){\n        if(this.cola.length===0){\n            console.log(\"La cola está vacía\")\n            return\n        }\n        return this.cola.shift()\n    }\n    imprimirCola(){\n        if (this.cola.length===0){\n            console.log(\"La cola está vacía\")\n            return \n        \n        }\n        console.log(\"Contenido de la cola:\")\n        this.cola.forEach(function(cadena,index){\n            console.log(`${index +1}.${cadena}`)\n        })\n    }\n    objetosEnCola(){\n        return this.cola.length\n    }\n}\n\nconst colaObjetos = new cola()\n\ncolaObjetos.insertar(\"Objeto1\")\ncolaObjetos.insertar(\"Objeto2\")\ncolaObjetos.insertar(\"Objeto3\")\n\ncolaObjetos.imprimirCola()\n\ncolaObjetos.borrar()//Borramos el primer elemento insertado en la cola\n\ncolaObjetos.imprimirCola()\n\nconst cantidadObjetos = colaObjetos.objetosEnCola()\nconsole.log(`Número de elementos en la pila: ${cantidadObjetos}`);\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/bernatcs.js",
    "content": "// ** EJERCICIO\n\nclass Cancion {\n    constructor(nombre, grupo, album) {\n        this.nombre = nombre\n        this.grupo = grupo\n        this.album = album\n    }\n\n    print() {\n        console.log(`Nombre: ${this.nombre}, Grupo: ${this.grupo}, Álbum: ${this.album}`)\n    }\n\n    modNombre(nuevoNombre) {\n        this.nombre = nuevoNombre\n    }\n\n    modGrupo(nuevoGrupo) {\n        this.grupo = nuevoGrupo\n    }\n\n    modAlbum(nuevoAlbum) {\n        this.album = nuevoAlbum\n    }\n}\n\nlet cancion1 = new Cancion('Verdis Duo', 'Daft Punk', 'Discovery')\n\ncancion1.print() //'Nombre: Verdis Duo, Grupo: Daft Punk, Álbum: Discovery'\n\ncancion1.modNombre('Them Changes')\ncancion1.modAlbum('Drunk')\ncancion1.modGrupo('Thundercat')\n\ncancion1.print() //'Nombre: Them Changes, Grupo: Thundercat, Álbum: Drunk'\n\n// ** DIFICULTAD EXTRA ** --------------------------------------------------------------------------------------------------------------------------------------------------\n\n// Implementación de una Pila (Stack - LIFO)\n\nclass Stack {\n    constructor() {\n        this.items = [];\n        this.forwardStack = [] // Array secundaria\n    }\n\n    push(element) {\n        this.items.push(element); // Agrega el elemento al final de la lista\n    }\n\n    pop() {\n        if (this.isEmpty()) {\n            return \"La pila está vacía\";\n        }\n        return this.items.pop(); // Elimina y devuelve el último elemento de la lista\n    }\n\n    peek() {\n        if (this.isEmpty()) {\n            return \"La pila está vacía\";\n        }\n        return this.items[this.items.length - 1]; // Devuelve el último elemento sin eliminarlo\n    }\n\n    isEmpty() {\n        return this.items.length === 0; // Comprueba si la lista está vacía\n    }\n\n    size() {\n        return this.items.length; // Devuelve el tamaño de la lista\n    }\n\n    clear() {\n        this.items = []; // Vacía la lista\n    }\n\n    print() {\n        console.log(this.items.toString()); // Imprime los elementos de la lista\n    }\n\n    pushForward(element) {\n        this.forwardStack.push(element); // Añade elementos al forwardStack que son usados para almacenar\n    }\n\n    popForward() {\n        if (this.forwardStack.length === 0) { \n            return \"Forward stack is empty\";\n        }\n        return this.forwardStack.pop(); // Elimina y devuelve el último elemento del forwardStack\n    }\n\n    peekForward() {\n        if (this.forwardStack.length === 0) { \n            return \"Forward stack is empty\";\n        }\n        return this.forwardStack[this.forwardStack.length - 1]; // Devuelve el último elemento del forwardStack sin eliminarlo\n    }\n\n    isEmptyForward() {\n        return this.forwardStack.length === 0; // Comprueba si la lista está vacía\n    }\n}\n\nlet pila = new Stack()\npila.push(10) // Añade 10\npila.push(20) // Añade 20\npila.push(30) // Añade 30\npila.pop() // Devuelve y elimina 30\npila.peek() // Devuelve 20 sin eliminarlo\n// pila.print() // Imprime 10,20\n\n// Implementación de una Cola (Queue - FIFO)\n\nclass Queue {\n    constructor() {\n        this.items = [];\n    }\n\n    enqueue(element) {\n        this.items.push(element); // Agrega el elemento al final de la lista\n    }\n\n    dequeue() {\n        if (this.isEmpty()) {\n            return \"La cola está vacía\";\n        }\n        return this.items.shift(); // Elimina y devuelve el primer elemento de la lista\n    }\n\n    front() {\n        if (this.isEmpty()) {\n            return \"La cola está vacía\";\n        }\n        return this.items[0]; // Devuelve el primer elemento sin eliminarlo\n    }\n\n    isEmpty() {\n        return this.items.length === 0; // Comprueba si la lista está vacía\n    }\n\n    size() {\n        return this.items.length; // Devuelve el tamaño de la lista\n    }\n\n    clear() {\n        this.items = []; // Vacía la lista\n    }\n\n    print() {\n        console.log(this.items.toString()); // Imprime los elementos de la lista\n    }\n}\n\n// Ejemplo de uso:\nlet cola = new Queue();\ncola.enqueue(10); // Añade 10\ncola.enqueue(20); // Añade 20\ncola.enqueue(30); // Añade 30\ncola.dequeue() // Devuelve y elimina 10\ncola.front() // Devuelve 20 sin eliminarlo\n// cola.print(); // Imprime 20,30"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/caterinarodriguezdev.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n */\n\nclass Robot {\n\n    constructor (nombre, rapidez, superPoder) {\n        this.nombre = nombre ?? 'mimi';\n        this.rapidez = rapidez ?? '0';\n        this.superPoder = superPoder ?? 'iluminidad'\n    }    \n\n    print () {\n        console.log(`>>>>>>>>>>>  Mi robot se llama ${this.nombre} con una velocidad de ${this.rapidez} y su máximo poder es ${this.superPoder}  <<<<<<<<<<<<<<<`);\n    }\n} \n\nconst miRobot = new Robot();\nmiRobot.print();\n\nclass Stack {\n\n    constructor (arr) {\n        this.stack = arr;\n    }\n\n    push (item) {\n        this.stack.push(item);\n    }\n\n    pop () {\n        this.stack.pop();\n    }\n\n    peek () {\n        return this.stack[this.stack.length - 1];\n    }\n\n    size () {\n        return this.stack.length;\n    }\n\n    print () {\n        console.log(this.stack);\n    }\n}\n\nclass Queue {\n\n    constructor (arr) {\n        this.queue = arr;\n    }\n\n    enqueue (item) {\n        this.queue.push(item);\n    }\n\n    dequeue () {\n        if (this.isEmpty()) {\n            return null;\n        } else {\n            return this.queue.shift();\n        }\n    }\n\n    isEmpty() {\n        return this.queue.length === 0;\n    }\n\n    size () {\n        return this.queue.length;\n    }\n\n    front () {\n        if (this.isEmpty()) {\n            return null;\n        } else {\n            return this.queue[0];\n        }\n    }\n\n    print () {\n        console.log(this.queue);\n    }\n}\n\nconst cola = new Queue([11, 22, 33]);\ncola.print();\n\nconst pila = new Stack([10, 20, 30]); \npila.print();"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/ceciliarava1.js",
    "content": "class Animal {\n\n    constructor(name, type) {\n        this.name = name\n        this.type = type\n    }\n\n    setName(newName) {\n        this.name = newName\n    }\n\n    getName() {\n        return this.name\n    }\n}\n\nlet dog = new Animal('Bartolo', 'Dog')\n// console.log(dog)\ndog.setName('Lucio')\n// console.log(dog)\n\n\n\nclass Stack {\n\n    constructor() {\n        this.stackElements = []\n    }\n\n    addElement(element) {\n        this.stackElements.push(element)\n    }\n    deleteElement() {\n        this.stackElements.pop()\n    }\n    getElements() {\n        return this.stackElements\n    }\n    getAmountOfElements() {\n        return `Amount of elements: ${this.stackElements.length}`\n    }\n}\n\n// let newStack = new Stack()\n// newStack.addElement('hello')\n// newStack.addElement('hell')\n// newStack.addElement('hel')\n// newStack.deleteElement('hello')\n// console.log(newStack)\n// console.log(newStack.getAmountOfElements())\n\n\nclass Queue {\n\n    constructor() {\n        this.queueElements = []\n    }\n\n    addElement(element) {\n        this.queueElements.push(element)\n    }\n    deleteElement() {\n        this.queueElements.shift()\n    }\n    getElements() {\n        return this.queueElements\n    }\n    getAmountOfElements() {\n        return `Amount of elements: ${this.queueElements.length}`\n    }\n}\n\nlet newQueue = new Queue()\nnewQueue.addElement('first')\nnewQueue.addElement('second')\nnewQueue.addElement('third')\nnewQueue.deleteElement()\nconsole.log(newQueue)\nconsole.log(newQueue.getAmountOfElements())\n"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/cesar-ch.js",
    "content": "/*\n    #08 CLASES \n*/\nclass Persona {\n\n    // Inicializador (constructor)\n    constructor(nombre, edad) {\n        this.nombre = nombre;\n        this.edad = edad;\n    }\n\n    // Función para imprimir los atributos\n    imprimirInformacion() {\n        console.log(`Nombre: ${this.nombre}`);\n        console.log(`Edad: ${this.edad}`);\n    }\n\n    // Métodos adicionales (opcional)\n\n    setNombre(nombre) {\n        this.nombre = nombre;\n    }\n\n    getNombre() {\n        return this.nombre;\n    }\n\n    setEdad(edad) {\n        this.edad = edad;\n    }\n\n    getEdad() {\n        return this.edad;\n    }\n}\n\n\nconst person1 = new Persona('Juan', 30);\nperson1.imprimirInformacion();\nperson1.setNombre('Pedro');\nperson1.setEdad(25);\nperson1.imprimirInformacion();\nconsole.log(person1.getNombre());\nconsole.log(person1.getEdad());\nconsole.log(person1);\n\n/* \n  DIFICULTAD EXTRA\n*/\n\nclass Pila {\n    constructor(pila) {\n        this.pila = pila;\n    }\n\n    push(dato) {\n        this.pila.push(dato);\n    }\n\n    pop() {\n        return this.pila.pop();\n    }\n\n    imprimir() {\n        console.log(this.pila);\n    }\n}\n\nconst pila1 = new Pila([]);\npila1.push(1);\npila1.push(2);\npila1.push(3);\npila1.imprimir();\nconsole.log(pila1.pop());\npila1.imprimir();\n\nclass Cola {\n    constructor(cola) {\n        this.cola = cola;\n    }\n\n    enqueue(dato) {\n        this.cola.push(dato);\n    }\n\n    dequeue() {\n        return this.cola.shift();\n    }\n\n\n    imprimir() {\n        console.log(this.cola);\n    }\n}\n\nconst cola1 = new Cola([]);\ncola1.enqueue(1);\ncola1.enqueue(2);\ncola1.enqueue(3);\ncola1.imprimir();\nconsole.log(cola1.dequeue());\ncola1.imprimir();\nconsole.log(cola1);"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/christian-jfr.js",
    "content": "// #08 CLASES\n\n/**\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n */\n\n// sin inicializador constructor\nclass Class {\n\tsayHello() {\n\t\tconsole.log('Hello');\n\t}\n}\n\nconst classInstance = new Class();\nclassInstance.sayHello(); // -> Hello\n\n// con inicializador constructor\nclass User {\n\t// inicializador constructor\n\tconstructor(name, id) {\n\t\tthis.name = name;\n\t\tthis.id = id;\n\t}\n\n\t// funcion imprimir\n\tprint() {\n\t\tconsole.log(`Name: ${this.name}`);\n\t\tconsole.log(`Id: ${this.id}`);\n\t}\n\n\t// Modificar atributos\n\teditName(newName) {\n\t\tthis.name = newName;\n\t}\n\n\teditId(newId) {\n\t\tthis.id = newId;\n\t}\n}\n\nconst user = new User('asdf', 99);\nuser.print(); // -> Name: asdf, Id: 99\n\nuser.editName('Christian');\nuser.editId(16);\nuser.print(); // -> Name: Christian, Id: 16\n\n// herencia inheritance\nclass Teacher extends User {\n\tconstructor(name, id, teaches) {\n\t\tsuper(name, id);\n\t\tthis.teaches = teaches;\n\t}\n\n\tprint() {\n\t\tsuper.print();\n\t\tconsole.log(`Teaches: ${this.teaches}`);\n\t}\n}\n\nconst moure = new Teacher('Moure', 0, 'Cooking');\nmoure.print(); // -> Name: Moure, Id: 0, Teaches: Cooking\n\n// encapsulamiento encapsulation\nclass Student extends User {\n\tconstructor(name, id, grade) {\n\t\tsuper(name, id);\n\t\tthis.grade = grade;\n\t}\n\n\tprint() {\n\t\tsuper.print();\n\t\tconsole.log(`Grade: ${this.grade}`);\n\t}\n}\n\nconst christian = new Student('Christian', 16, 10);\nchristian.print(); // -> Name: Christian, Id: 16, Grade: 10\n\n/** DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n *\n */\n\n// Pilas\nclass Stack {\n\t// inicializador constructor\n\tconstructor() {\n\t\tthis.stack = [];\n\t}\n\t// añadir elemento\n\tpush(element) {\n\t\tthis.stack.push(element);\n\t\treturn this.stack;\n\t}\n\t// eliminar ultimo elemento en entrar\n\tpop() {\n\t\treturn this.stack.pop();\n\t}\n\t// retornar ultimo elemento que entro\n\tpeek() {\n\t\treturn this.stack[this.stack.length - 1];\n\t}\n\t// ver el tamaño de la pila\n\tsize() {\n\t\treturn this.stack.length;\n\t}\n\t// imprimir contenido de la pila\n\tprint() {\n\t\tconsole.log(this.stack);\n\t}\n}\n\nconst colorStack = new Stack();\n\nconsole.log(`Check stack size: ${colorStack.size()}`); // -> 0\nconsole.log(`push element: ${colorStack.push('Yellow')}`); // -> [\"Yellow\"]\nconsole.log(`push element: ${colorStack.push('Blue')}`); // -> [\"Yellow\", \"Blue\"]\nconsole.log(`push element: ${colorStack.push('Red')}`); // -> [\"Yellow\", \"Blue\", \"Red\"]\nconsole.log(`Check stack size: ${colorStack.size()}`); // -> 3\ncolorStack.print(); // -> [\"Yellow\", \"Blue\", \"Red\"]\nconsole.log(`peek last element: ${colorStack.peek()}`); // -> \"Red\"\nconsole.log(`pop last element: ${colorStack.pop()}`); // -> \"Red\"\nconsole.log(`Check stack size: ${colorStack.size()}`); // -> 2\ncolorStack.print(); // -> [\"Yellow\", \"Blue\"]\n\n// Colas\nclass Queue {\n\t// inicializador constructor\n\tconstructor() {\n\t\tthis.queue = [];\n\t}\n\t// añadir elemento a la cola\n\tenqueue(element) {\n\t\tthis.queue.push(element);\n\t\treturn this.queue;\n\t}\n\t// eliminar primer elemento de la cola\n\tdequeue() {\n\t\treturn this.queue.shift();\n\t}\n\t// retornar primer elemento de la cola\n\tpeek() {\n\t\treturn this.queue[0];\n\t}\n\t// ver el tamaño de la cola\n\tsize() {\n\t\treturn this.queue.length;\n\t}\n\t// imprimir contenido de la cola\n\tprint() {\n\t\tconsole.log(this.queue);\n\t}\n\t// verificar si la cola esta vacia\n\tisEmpty() {\n\t\treturn this.queue.length === 0;\n\t}\n}\n\nconst numbersQueue = new Queue();\n\nconsole.log(`Empty queue? ${numbersQueue.isEmpty()}`); // -> true\nconsole.log(`enqueue element: ${numbersQueue.enqueue(1)}`); // -> [1]\nconsole.log(`enqueue element: ${numbersQueue.enqueue(2)}`); // -> [1, 2]\nconsole.log(`enqueue element: ${numbersQueue.enqueue(3)}`); // -> [1, 2, 3]\nconsole.log(`Check queue size: ${numbersQueue.size()}`); // -> 3\nnumbersQueue.print(); // -> [1, 2, 3]\nconsole.log(`Empty queue? ${numbersQueue.isEmpty()}`); // -> false\nconsole.log(`Check first element: ${numbersQueue.peek()}`); // -> 1\nconsole.log(`dequeue first element: ${numbersQueue.dequeue()}`); // -> 1\nconsole.log(`Check queue size: ${numbersQueue.size()}`); // -> 2\nnumbersQueue.print(); // -> [2, 3]\n"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/cmejiajulian.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n * \n */\n\n class programador {\n\n    constructor (name,age,languages){\n        this.name = name;\n        this.age = age;\n        this.languages =languages;\n    }\n     \n    contenido(){\n        console.log(`Hola, mi nombre es ${this.name} y tengo ${this.age} años. y programo en estos lenguajes: ${this.languages.join(\", \")}`)\n    }\n    \n }\n\n let newProgramer = new programador('julian',36,['java','Python','solidity']);\n newProgramer.contenido();\n\n\n\nnewProgramer.age = 34;\nnewProgramer.contenido();\n\nnewProgramer.name = 'JuliusCañas';\nnewProgramer.contenido();\n\n\n /*\n *  DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n */\n const readline = require('readline');\n\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout\n});\n\nclass Pila {  // Capitaliza el nombre de la clase\n  constructor() {\n    this.elementos = [];\n  }\n\n  push(elemento) {\n    this.elementos.push(elemento);\n  }\n\n  pop() {\n    if (this.elementos.length === 0) {\n      console.log('La pila está vacía');\n      return null;\n    }\n    return this.elementos.pop();\n  }\n\n  shift() {\n    if (this.elementos.length === 0) {\n      console.log('La pila está vacía');\n      return null;  // Agregar retorno nulo para mantener consistencia\n    }\n    return this.elementos.shift();\n  }\n\n  mostrarElemento() {\n    if (this.elementos.length === 0) {\n      console.log('La pila está vacía');\n    } else {\n      console.log(['Los elementos son:', this.elementos]);\n    }\n  }\n}\n\nlet miPila = new Pila();  // Crear instancia de la clase\n\nlet principalClass = () => {\n  rl.question('Ingrese el elemento que desea guardar: ', (elementoG) => {\n    let numeroElemento = miPila.elementos.length + 1;\n    miPila.push({ numero: numeroElemento, elementoGuardado: elementoG });\n\n    miPila.elementos.forEach(numero => {\n      console.log([`${numero.numero}. ${numero.elementoGuardado}`]);\n    });\n\n    entrada();\n  });\n};\n\nlet entrada = () => {\n  rl.question('Ingrese ENTRAR para guardar los elementos, SALIR para salir del programa, IMPRIMIR para mostrar los elementos en consola, ELIMINAR para eliminar elementos: ', (instruccion) => {\n    if (instruccion === 'ENTRAR') {\n      principalClass();\n    } else if (instruccion === 'IMPRIMIR') {\n      miPila.mostrarElemento();\n      entrada();\n    } else if (instruccion === 'SALIR') {\n      console.log('Saliendo del programa');\n      rl.close();\n    } else if (instruccion === 'ELIMINAR') {  // Corrige el espacio extra\n      let eliminarUltimo = miPila.pop();\n      if (eliminarUltimo) {\n        console.log('El último elemento eliminado es:', eliminarUltimo);\n      }\n\n      let eliminarPrimero = miPila.shift();\n      if (eliminarPrimero) {\n        console.log('El primer elemento eliminado es:', eliminarPrimero);\n      }\n\n      entrada();  // Reingresar al menú después de eliminar elementos\n    } else {\n      console.log('Ingrese una instrucción válida');\n      entrada();\n    }\n  });\n};\n\nentrada();\n"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/duendeintemporal.js",
    "content": "/* #08 CLASES */\n//bibliography reference\n//Secrets of the JavaScript Ninja (John Resig, Bear Bibeault, Josip Maras) (z-lib.org)\n//Professional JavaScript for web developers by Matt Frisbie [Frisbie, Matt] (z-lib.org)\n//JavaScript Notes for Professionals (GoalKicker.com) (Z-Library)\n//Python para todos (Raúl Gonzáles Duque)\n//GPT\n\n/*                                        **Classes and Objects**\n\nTo understand this paradigm, we first need to comprehend what a class is and what an object is. An object is an entity that groups related state and functionality. The state of the object is defined through variables called attributes, while the functionality is modeled through functions known as the object's methods.\n\nAn example of an object could be a car, which would have attributes such as the brand, the number of doors, or the type of fuel, and methods such as start and stop. Alternatively, it could be any other combination of attributes and methods relevant to our program.\n\nA class, on the other hand, is nothing more than a generic template from which to instantiate objects; a template that defines what attributes and methods the objects of that class will have. */\n\n\n\n//Short for console.log()\nlet log = console.log.bind(console);\n\nwindow.addEventListener('load', ()=>{\n    const body = document.querySelector('body');\n    const title = document.createElement('h1');\n    \n    body.style.setProperty('background', '#000');\n    body.style.setProperty('text-align', 'center');\n    \n    title.textContent = 'Retosparaprogramadores #8.';\n    title.style.setProperty('font-size', '3.5vmax');\n    title.style.setProperty('color', '#fff');\n    title.style.setProperty('line-height', '100vh');\n    \n    body.appendChild(title);\n    \n    setTimeout(()=>{\n    alert('Retosparaprogramadores #8. Please open the Browser Developer Tools.');\n    }, 2000);\n    log( 'Retosparaprogramadores #8'); \n});\n\n/* A class can be composed of the class’s constructor method, instance methods, getters, setters, and\nstatic class methods. None of these are explicitly required; an empty class definition is valid syntax.\nBy default, everything inside a class definition executes in strict mode. */\n\n/* The fundamental part of most classes is its constructor, which sets up each instance's initial state and handles any\nparameters that were passed when calling new. */\n\n/* Similar to the function type, there are two primary ways of defining a class: class declarations and\nclass expressions. Both use the class keyword and curly braces:\n// class declaration\nclass Person {}\n// class expression\nconst Animal = class {}; */\n\n/* Note: even though ES6 has introduced the class keyword, under the\nhood we’re still dealing with good old prototypes; classes are syntactic sugar designed\nto make our lives a bit easier when mimicking classes in JavaScript.  */\n\n\nclass User {\n    constructor(name, nickname, email) {\n        this.name = name;\n        this.nickname = nickname;\n        this.email = email;\n    }\n\n    greeting() {\n        log(`Hi ${this.nickname}. Welcome to this Roadmap for Developers!`)\n    }\n\n    getEmail() {\n       if(this.email != undefined) {\n            return this.email;\n       } else {\n            log('no email set yet!');\n            return null;\n       } \n    }\n\n    getName() {\n        if(this.name != undefined) {\n            return this.name;\n       } else {\n            log('no name set yet!');\n            return null;\n       } \n    }\n\n    getNickname() {\n        if(this.nickname != undefined) {\n            return this.nickname;\n       } else {\n            log('no nickname set yet!')\n            return null;\n       } \n    }\n\n    setName(name) {\n       if(name) this.name = name;\n    }\n\n    setEmail(email) {\n       if(email) this.email = email;\n    }\n\n    setNickname(nickname) {\n       if(nickname) this.nickname = nickname;\n    }\n    \n    userInfo() {\n        log(`User name: ${this.name || 'not set'}, User nickname: ${this.nickname || 'not set'}, User email: ${this.email || 'not set'}`);\n    }\n}\n\nlet user1 = new User('Niko Zen', 'duendeintemporal', 'duendeintemporal@hotmail.com');\nuser1.greeting(); // Hi duendeintemporal. Wellcome to this Roadmap for Developers!\n\nuser1.userInfo(); // user name: Niko Zen, user nickname: duendeintemporal, user email: duendeintemporal@hotmail.com \n\nuser1.setNickname('psicotrogato');\n\nlog(user1.getNickname()); // psicotrogato\n\n/* There is no formal class type in the ECMAScript specification, and in many ways ECMAScript classes\nbehave like special functions. Once declared, the class identifier identifies as a function when checked with the typeof operator: */\n\nlog(typeof User); // function\n\n/* As with function constructors, you can use the instanceof operator to test if the constructor prototype appears in the prototype chain of an instance: */\n\nlog(user1 instanceof User); // true\n\n/*  Class Inheritance\nInheritance works just like it does in other object-oriented languages: methods defined on the superclass are accessible in the extending subclass. */\n\nclass Log {\n    constructor() {\n        this.logger = console.log;\n        this.errorLog = console.error;\n    }\n\n    log(msj) {\n       (msj)? this.logger(msj) : this.errorLog('you should provide a msj');\n    }\n}\n// When you extend a class in JavaScript, you must call super() in the constructor of the subclass before you can use this.\n\nclass Greeting extends Log {\n    constructor(msj) {\n        super();\n        this.msj = msj;\n    }\n}\n\nlet sayHiPeople = new Greeting('Hi everybody. Welcome to the most wierd and lonly place in the cyberspace...');\n\nsayHiPeople.log(); // Hi everybody. Welcome to the most wierd and lonly place in the cyberspace...\n\n/*  Static Methods\nStatic methods and properties are defined on the class/constructor itself, not on instance objects. These are specified in a class definition by using the static keyword   */\n\nclass ElectroCat {\n    static catSay() {\n        return 'Miauu';\n    }\n    \n    static get catThink() {\n        return \"Let's see if there's some lovely gircat over there\";\n    } \n}\n\nlog(ElectroCat.catSay()); // Miauu\nlog(ElectroCat.catThink); // Let's see if there's some lovely gircat over there\n\n// We can see that static properties are not defined on object instances:\n\nconst mishu = new ElectroCat();\n//log(mishu.catSay()); // undefined OR throw an error\n//log(mishu.catThink); // undefined or throw an error\n\n// However, they are defined on subclasses:\n\nclass PoetCat extends ElectroCat {}\nlog(PoetCat.catSay()); // Miauu\nlog(PoetCat.catThink); // Let's see if there's some lovely gircat over there\n\n/* Getters and setters allow you to define custom behaviour for reading and writing a given property on your class. To the user, they appear the same as any typical property. However, internally a custom function you provide is used to determine the value when the property is accessed (the getter), and to perform any necessary changes when the property is assigned (the setter).\nIn a class definition, a getter is written like a no-argument method prefixed by the get keyword. A setter is similar, except that it accepts one argument (the new value being assigned) and the set keyword is used instead. */\n\nconst h_method = Symbol('Hidden method');\n\n//We use private properties in JavaScript classes to avoid infinite recursion in getters and setters by referencing the private property instead of the public property.\nclass GopiElectronica {\n    constructor(name) {\n        this._name = name; \n    }\n\n    set name(name) {\n        this._name = name; \n    }\n\n    get name() {\n        return this._name; \n    }\n\n    // You can also create dynamic methods or use symbols or JavaScript expressions as keys \n    [h_method]() {\n        return 'I will hack you boy';\n    }\n}\n\nconst Nicky = new GopiElectronica('Nicky');\nlog(Nicky.name); // Nicky\nNicky.name = 'Samantha';\nlog(Nicky.name); // Samantha\nlog(Nicky[h_method]()); // I will hack you boy\nlog(Object.keys(Nicky)); // [] - will not show the symbol method\nlog(Reflect.ownKeys(Nicky)); // Shows all keys including symbol keys\n\n\n\n\n\n/* Tips: (relevant info) \nClasses are first-class citizens in JavaScript, meaning they can be passed around as you would any\nother object or function reference:\n// Classes may be defined anywhere a function would, such as inside an array:\nlet classList = [\n    class {\n        constructor(id) {\n             this.id_ = id;\n             console.log('instance ${this.id_}');\n        }\n    }\n];\n\nfunction createInstance(classDefinition, id) {\n    return new classDefinition(id);\n}\n\nlet foo = createInstance(classList[0], 3141); // instance 3141 */\n\n\n/* Similar to an immediately invoked function expression, a class can also be immediately instantiated:\n// Because it is a class expression, the class name is optional\nlet p = new class Foo {\n    constructor(x) {\n        console.log(x);\n    }\n}('bar'); // bar\n\nconsole.log(p); // Foo {} */\n\n\n//Aditional Exercises\n\n//QUEUE\n\nclass Queue {\n    constructor(initialItems = []) {\n         this.items = Array.isArray(initialItems) ? initialItems : [];\n    }\n\n    enqueue(element) {\n        this.items.push(element); \n    }\n\n    dequeue() {\n        if (this.isEmpty()) {\n            console.error(\"Queue is empty. Cannot dequeue an element.\");\n            return null;\n        }\n        return this.items.shift();\n    }\n\n    peek() {\n        if (this.isEmpty()) {\n            console.error(\"Queue is empty. Cannot peek.\");\n            return null;\n        }\n        return this.items[0];\n    }\n    empty() {\n        return this.items = [];\n    }\n\n    isEmpty() {\n        return this.items.length === 0;\n    }\n\n    size() {\n        return this.items.length; \n    }\n}\n\nconst queue2 = new Queue([45, 32, 16]); \nlog('Initial queue2:', queue2.items); //  [45, 32, 16]\n\nqueue2.enqueue(77);\nlog('After enqueueing 4:', queue2.items); //  [45, 32, 16, 77]\n\nlog('Peek:', queue2.peek()); //  45\n\nlog('Dequeue:', queue2.dequeue()); //  45\nlog('After dequeueing:', queue2.items); //  [32, 16, 77]\n\nlog('Dequeue all elements:');\nwhile (!queue2.isEmpty()) {\n    log('Dequeued:', queue2.dequeue());\n} // or we can just empty the queue queue2.empty()\n\nlog('Final queue2:', queue2.items); //  []\nlog('Dequeue from empty queue2:', queue2.dequeue()); //Logs error: Queue is empty. Cannot dequeue an element. & Dequeue from empty queue2: null\n\n//STACK\n\nclass Stack {\n    constructor(initialItems = []) {\n            this.items = Array.isArray(initialItems) ? initialItems : [];\n    }\n\n    push(element) {\n        this.items.push(element);\n    }\n\n    pop() {\n        if (this.isEmpty()) {\n            console.error(\"Stack is empty. Cannot pop an element.\");\n            return null; \n        }\n        return this.items.pop();\n    }\n\n    peek() {\n        if (this.isEmpty()) {\n            console.error(\"Stack is empty. Cannot peek.\");\n            return null; \n        }\n        return this.items[this.items.length - 1];\n    }\n\n    empty() {\n        return this.items = [];\n    }\n\n    isEmpty() {\n        return this.items.length === 0;\n    }\n\n    size() {\n        return this.items.length;\n    }\n}\n\nconst stack2 = new Stack([55, 76, 98, 100]); \nlog('Initial stack2:', stack2.items); // [55, 76, 98, 100]\n\nstack2.push(32);\nlog('After pushing 32:', stack2.items); // [55, 76, 98, 100, 32]\n\nlog('Peek:', stack2.peek()); // 32\n\nlog('Pop:', stack2.pop()); // 32\nlog('After popping:', stack2.items); // [55, 76, 98, 100]\n\nlog('Pop all elements:');\nwhile (!stack2.isEmpty()) {\n    log('Popped:', stack2.pop());\n} // or we can just empty the stack stack2.empty() \n\nlog('Final stack2:', stack2.items); // []\nlog('Pop from empty stack2:', stack2.pop()); // Logs error: Stack is empty. Cannot pop an element. & Pop from empty stack2: null\n"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/emedevelopa.js",
    "content": "class song {\n    constructor(titulo, artista, duracion) { //Inicialización\n        this.titulo = titulo;\n        this.artista = artista;\n        this.duracion = duracion;\n    }\n\n    imprimir() { //Impresión\n        console.log(`Título: ${this.titulo}`);\n        console.log(`Artista: ${this.artista}`);\n        console.log(`Duración: ${this.duracion}`);\n    }\n}\n\nconst song1 = new song(\"Before the begining\", \"John Frusciante\", 3 + \" minutos\");\nsong1.imprimir();\n\nsong1.titulo = \"La Macarena\";\nsong1.artista = \"Los del Río\";\nsong1.duracion = 4 + \" min\";\n\nsong1.imprimir();\n\n//\n\nclass pila  {\n    constructor () {\n        this.pila = [];\n    }\n\n    add(elemento) {\n        this.pila.push(elemento);\n    }\n\n    delete() {\n        if (this.pila.length === 0) {\n            return \"La pila está vacía\";\n        }\n        return this.pila.pop();\n    }\n\n    length() {\n        return this.pila.length;\n    }\n\n    imprimirElementos() {\n        for(let i = this.pila.length - 1; i >= 0; i--) {\n            console.log(this.pila[i]);\n        }\n    }\n}\n\nconst pila1 = new pila();\npila1.add(\"Ana\");\npila1.add(\"Garcia\");\npila1.add(88);\n\npila1.delete(); // 88 no lo imprime por que borra el último elemento añadido.\npila1.imprimirElementos();\n\n\nclass cola {\n    constructor() {\n        this.cola = [];\n    }\n\n    add1 (numero) {\n        this.cola.push (numero);\n    }\n\n    delete1 () {\n        this.cola.shift();\n    }\n\n    imprimirElementos1 () {\n        for (let a = 0; a < this.cola.length; a++) {\n            console.log(this.cola[a]);\n        }\n    }\n}\n\nconst cola1 = new cola();\ncola1.add1(1);\ncola1.add1(2);\ncola1.add1(3);\n\ncola1.imprimirElementos1();\ncola1.delete1();\ncola1.imprimirElementos1();"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/eulogioep.js",
    "content": "// Ejemplo de una clase en JavaScript\n\n/**\n * Clase Persona que representa a una persona con nombre y edad.\n */\nclass Persona {\n    // Constructor\n    constructor(nombre, edad) {\n        this.nombre = nombre;\n        this.edad = edad;\n    }\n\n    // Métodos getter y setter\n    getNombre() {\n        return this.nombre;\n    }\n\n    setNombre(nombre) {\n        this.nombre = nombre;\n    }\n\n    getEdad() {\n        return this.edad;\n    }\n\n    setEdad(edad) {\n        this.edad = edad;\n    }\n\n    // Método para imprimir los datos de la persona\n    imprimirDatos() {\n        console.log(`Nombre: ${this.nombre}, Edad: ${this.edad}`);\n    }\n}\n\n/**\n * Clase Pila que implementa una estructura de datos de tipo pila (LIFO).\n */\nclass Pila {\n    constructor() {\n        this.elementos = [];\n    }\n\n    push(elemento) {\n        this.elementos.push(elemento);\n    }\n\n    pop() {\n        if (this.elementos.length === 0) {\n            return \"La pila está vacía\";\n        }\n        return this.elementos.pop();\n    }\n\n    size() {\n        return this.elementos.length;\n    }\n\n    imprimirContenido() {\n        console.log(\"Contenido de la pila:\", this.elementos);\n    }\n}\n\n/**\n * Clase Cola que implementa una estructura de datos de tipo cola (FIFO).\n */\nclass Cola {\n    constructor() {\n        this.elementos = [];\n    }\n\n    enqueue(elemento) {\n        this.elementos.push(elemento);\n    }\n\n    dequeue() {\n        if (this.elementos.length === 0) {\n            return \"La cola está vacía\";\n        }\n        return this.elementos.shift();\n    }\n\n    size() {\n        return this.elementos.length;\n    }\n\n    imprimirContenido() {\n        console.log(\"Contenido de la cola:\", this.elementos);\n    }\n}\n\n// Pruebas de las implementaciones\nfunction main() {\n    // Prueba de la clase Persona\n    const persona = new Persona(\"Juan\", 30);\n    persona.imprimirDatos();\n    persona.setEdad(31);\n    persona.imprimirDatos();\n\n    // Prueba de la Pila\n    const pila = new Pila();\n    pila.push(1);\n    pila.push(2);\n    pila.push(3);\n    pila.imprimirContenido();\n    console.log(\"Elemento extraído de la pila:\", pila.pop());\n    pila.imprimirContenido();\n\n    // Prueba de la Cola\n    const cola = new Cola();\n    cola.enqueue(\"A\");\n    cola.enqueue(\"B\");\n    cola.enqueue(\"C\");\n    cola.imprimirContenido();\n    console.log(\"Elemento extraído de la cola:\", cola.dequeue());\n    cola.imprimirContenido();\n}\n\nmain();"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/garos01.js",
    "content": "// Clases\n\nclass Vehiculo {\n  constructor(marca, modelo, anio, color) {\n    this.marca = marca;\n    this.modelo = modelo;\n    this.anio = anio;\n    this.color = color;\n  }\n\n  imprimirInformacion() {\n    console.log(`Marca: ${this.marca}`);\n    console.log(`Modelo: ${this.modelo}`);\n    console.log(`Año: ${this.anio}`);\n    console.log(`Color: ${this.color}`);\n  }\n}\n\n// Crear una instancia de la clase Vehiculo\nlet vehiculo1 = new Vehiculo(\"Toyota\", \"Camry\", 2022, \"Azul\");\n\n// Imprimir la información inicial\nconsole.log(\"Información inicial del vehículo:\");\nvehiculo1.imprimirInformacion();\n\n// Modificar algunos atributos\nvehiculo1.anio = 2021;\nvehiculo1.color = \"Blanco\";\n\n// Imprimir la información después de la modificación\nconsole.log(\"\\nInformación después de la modificación:\");\nvehiculo1.imprimirInformacion();\n\n// Ejercicio extra\n\nclass NavegadorWeb {\n  constructor() {\n    this.historial = [];\n  }\n\n  navegarA(pagina) {\n    this.historial.push(pagina);\n    console.log(\"Navegando a:\", pagina);\n  }\n\n  adelante() {\n    const paginaSiguiente = this.historial.pop();\n    if (paginaSiguiente) {\n      console.log(\"Avanzando a:\", paginaSiguiente);\n    } else {\n      console.log(\"No hay páginas siguientes en el historial\");\n    }\n  }\n\n  atras() {\n    const paginaAnterior = this.historial.pop();\n    if (paginaAnterior) {\n      console.log(\"Retrocediendo a:\", paginaAnterior);\n    } else {\n      console.log(\"No hay páginas anteriores en el historial\");\n    }\n  }\n}\n\nconst navegador = new NavegadorWeb();\n\nnavegador.navegarA(\"Google\");\nnavegador.navegarA(\"Facebook\");\nnavegador.navegarA(\"Twitter\");\n\nnavegador.atras();\nnavegador.adelante();\nnavegador.atras();\nnavegador.atras();\n"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/gianbordon.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n * \n */\n\n//\n// Clases\n//\n\n// Definición de clase \nclass Persona {\n    constructor(nombre, edad) {\n        this.nombre = nombre\n        this.edad = edad\n    }\n\n    presentar() {\n        console.log(`Nombre: ${this.nombre}`)\n        console.log(`Edad: ${this.edad}`)\n    }\n}\n\n// Instanciar una clase \nconst persona1 = new Persona('Gianfranco', 25)\n\n// Mostrar atributos mediante metodo de la clase\npersona1.presentar()\n\n// Modificar atributos\npersona1.nombre = 'Nataniel'\npersona1.edad = 30\n\n// Mostrar atributos modificados\npersona1.presentar()\n\n//\n// EXTRA\n//\n\nclass Pila {\n    constructor(){\n        this.items = []\n    }\n\n    push(element){\n        this.items.push(element)\n    }\n    pop(){ \n        if (this.items.length === 0) return undefined\n        return this.items.pop()\n    }\n    peek(){\n        if (this.items.length === 0) return undefined\n        return this.items.length -1\n    }\n    size(){\n        return this.items.length\n    }\n    print(){\n        if (this.items.length === 0) return undefined\n        console.log(this.items)\n    }\n    clear(){\n        this.items = []\n    }\n}\nconsole.group('| PILAS |')\n// Creación de una nueva pila\nconst miPila = new Pila()\n// Agregar elementos\nmiPila.push('Documento 1')\nmiPila.push('Documento 2')\nmiPila.push('Documento 3')\n// Ver el contenido de la pila\nconsole.log(\"Contenido de la pila:\")\nmiPila.print()  \n// Ver el último elemento sin eliminarlo\nconsole.log(\"Último elemento (peek):\", miPila.peek())  \n// Ver el tamaño de la pila\nconsole.log(\"Tamaño de la pila:\", miPila.size())  \n// Eliminar el último elemento\nconsole.log(\"Elemento eliminado (pop):\", miPila.pop())  \n// Ver el contenido después de hacer pop\nconsole.log(\"Contenido de la pila después de pop:\")\nmiPila.print()  \n// Ver el tamaño de la pila después de pop\nconsole.log(\"Tamaño de la pila después de pop:\", miPila.size())  \n// Vaciar completamente la pila\nmiPila.clear()\nconsole.log(\"Contenido de la pila después de clear:\")\nmiPila.print()\nconsole.groupEnd()\n\nclass Cola {\n    constructor(){\n        this.cola = []\n    }\n\n    push(element){\n        this.cola.push(element)\n    }\n    shift(){\n        if (this.size() > 0){\n            return this.cola.shift()\n        } else {\n            console.log('La cola esta vacia')\n            return undefined\n        }\n    }\n    peek(){\n        if (this.size() > 0){\n            return this.cola[0]\n        } else {\n            console.log('La cola esta vacia')\n            return undefined\n        }\n    }\n    size(){\n        return this.cola.length\n    }\n    print(){\n        console.log(this.cola)\n    }\n}\n\nconsole.group('| COLAS |')\n// Crear una nueva cola\nconst cola = new Cola()\n\n// Inicializar\nconsole.log(\"Inicializando cola:\")\ncola.print()  \n\n// Agregar elementos a la cola\ncola.push('Documento 1')\ncola.push('Documento 2')\ncola.push('Documento 3')\n\n// Imprimir la cola con elementos\nconsole.log(\"Después de agregar elementos:\")\ncola.print() \n// Ver el primer elemento sin eliminarlo\nconsole.log(\"Primer elemento (peek):\", cola.peek())  \n// Ver el tamaño de la cola\nconsole.log(\"Tamaño de la cola:\", cola.size()) \n// Eliminar un elemento de la cola\nconsole.log(\"Eliminando primer elemento:\", cola.shift()) \n// Ver el primer elemento y tamaño después de la eliminación\nconsole.log(\"Primer elemento después del shift:\", cola.peek()) \nconsole.log(\"Tamaño después del shift:\", cola.size())  \n// Imprimir la cola después de una eliminación\nconsole.log(\"Cola después de eliminar un elemento:\")\ncola.print()  \n// Intentar eliminar todos los elementos\nconsole.log(\"Eliminando el resto de los elementos:\")\ncola.shift()  \ncola.shift()  \ncola.shift()  \n// Ver el tamaño de la cola después de eliminar todos los elementos\nconsole.log(\"Tamaño final de la cola:\", cola.size())  \n// Ver el primer elemento cuando la cola está vacía\nconsole.log(\"Intentando ver el primer elemento cuando la cola está vacía:\", cola.peek())  \nconsole.groupEnd()"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/giovanyosorio.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n * \n */\nclass Persona {\n    constructor(nombre, edad) {\n        this.nombre = nombre;\n        this.edad = edad;\n    }\n\n    imprimirDatos() {\n        console.log(`Nombre: ${this.nombre}, Edad: ${this.edad}`);\n    }\n}\n\n\nlet persona1 = new Persona('Juan', 30);\npersona1.imprimirDatos();\n\npersona1.nombre = 'Ana';\npersona1.edad = 25;\npersona1.imprimirDatos();\n\n\n//DIFICULTAD EXTRA \n\n//DIFICULTAD EXTRA \nclass Pila{\n    constructor(){\n        this.elementos=[]\n    }\n    agregar(elemento){\n        this.elementos.push(elemento)\n    }\n    eliminar(elemento){\n        return this.elementos.pop()\n    }\n    longitud() {\n        return this.elementos.length;\n    }\n    imprimir() {\n        console.log(this.elementos);\n    }\n}\n\n\nclass Cola {\n    constructor() {\n        this.elementos = [];\n    }\n\n    agregar(elemento) {\n        this.elementos.push(elemento);\n    }\n\n    eliminar() {\n        return this.elementos.shift();\n    }\n\n    longitud() {\n        return this.elementos.length;\n    }\n\n    imprimir() {\n        console.log(this.elementos);\n    }\n}\n\nlet miPila = new Pila();\nmiPila.agregar(1);\nmiPila.agregar(2);\nmiPila.agregar(3);\nmiPila.imprimir();\nconsole.log('Elemento eliminado:', miPila.eliminar());\nmiPila.imprimir();\n\n\nlet miCola = new Cola();\nmiCola.agregar(1);\nmiCola.agregar(2);\nmiCola.agregar(3);\nmiCola.imprimir();\nconsole.log('Elemento eliminado:', miCola.eliminar());\nmiCola.imprimir();"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/hectorio23.js",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\n/*******************************************\n * CLASE WebPage\n *******************************************/\n\nclass WebPage {\n    constructor(title, index) {\n        this.title = title;\n        this.index = index;\n    }\n\n    getInfo() {\n        console.log(`<Object WebPage - ${this.title} at ${this}`);\n    }\n}\n\n/*******************************************\n * CLASE Queue\n *******************************************/\n\nclass Queue {\n    constructor() {\n        this.next = null;\n        this.last = null;\n        this.size = 0;\n        this.page = null;\n    }\n\n    push(webPage) {\n        const tmp = new Queue();\n        tmp.page = webPage;\n        if (this.size === 0) {\n            this.next = tmp;\n            this.last = tmp;\n        } else {\n            this.last.next = tmp;\n            this.last = tmp;\n        }\n        this.size++;\n    }\n\n    pop() {\n        if (this.size === 0) return null;\n        const aux = this.next;\n        this.next = aux.next;\n        this.size--;\n        if (this.size === 0) {\n            this.last = null;\n        }\n        return aux.page;\n    }\n}\n\n/*******************************************\n * CLASE Stack\n *******************************************/\n\nclass Stack {\n    constructor() {\n        this.next = null;\n        this.garbage = null; // experimental\n        this.size = 0;\n        this.page = null;\n    }\n\n    push(webPage) {\n        const tmp = new Stack();\n        tmp.page = webPage;\n        tmp.next = this.next;\n        this.next = tmp;\n        this.size++;\n    }\n\n    pop() {\n        if (this.size === 0) return null;\n        const aux = this.next;\n        this.next = aux.next;\n        this.size--;\n        return aux.page;\n    }\n}\n\n/*******************************************\n * CLASE Persona\n *******************************************/\n\nclass Persona {\n    constructor(nombre, edad) {\n        this.nombre = nombre;\n        this.edad = edad;\n    }\n\n    info() {\n        console.log(`Nombre: ${this.nombre}`);\n        console.log(`Edad: ${this.edad}`);\n    }\n\n    setNombre(nuevoNombre) {\n        this.nombre = nuevoNombre;\n    }\n\n    setEdad(nuevaEdad) {\n        this.edad = nuevaEdad;\n    }\n}\n\n/*******************************************\n * PROGRAMA PRINCIPAL\n *******************************************/\n\n// Crear una instancia de Persona\nconst persona = new Persona(\"Juan\", 30);\n\n// Imprimir los atributos\nconsole.log(\"Datos de la persona:\");\npersona.info();\n\n// Modificar los atributos\npersona.setNombre(\"María\");\npersona.setEdad(25);\n\n// Imprimir los atributos actualizados\nconsole.log(\"\\nDatos de la persona actualizados:\");\npersona.info();\n\n// Crear objetos WebPage para usar en Stack y Queue\nconst p1 = new WebPage(\"index\", 1);\nconst p2 = new WebPage(\"index\", 2);\nconst p3 = new WebPage(\"index\", 3);\n\n// Crear una instancia de Queue\nconst queue = new Queue();\n\n// Agregar elementos a Queue\nqueue.push(p1);\nqueue.push(p2);\nqueue.push(p3);\n\nconsole.log(`\\nNúmero de elementos en Queue: ${queue.size}`);\nqueue.pop();\nqueue.pop();\nqueue.pop();\nconsole.log(`Número de elementos en Queue después de eliminar: ${queue.size}`);\n\n// Crear una instancia de Stack\nconst stack = new Stack();\n\n// Agregar elementos a Stack\nstack.push(p1);\nstack.push(p2);\nstack.push(p3);\n\nconsole.log(`\\nNúmero de elementos en Stack: ${stack.size}`);\nstack.pop();\nstack.pop();\nstack.pop();\nconsole.log(`Número de elementos en Stack después de eliminar: ${stack.size}`);\n"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/jeronimocardu.js",
    "content": "class Phone {\n  constructor(marca, color) {\n    ;(this.marca = marca), (this.color = color)\n  }\n  imprimirDatos() {\n    console.log(`Tengo un celular ${this.marca} de color ${this.color}`)\n  }\n}\n\nconst myPhone = new Phone('samsung', 'rojo')\n// myPhone.imprimirDatos()\n\nmyPhone.marca = 'Apple'\nmyPhone.color = 'gris'\n// myPhone.imprimirDatos()\n\n/** EJERCICIO */\n\nclass Pila {\n  constructor(pilaArray) {\n    this.pila = pilaArray\n  }\n  add(element) {\n    this.pila.push(element)\n  }\n  delete() {\n    this.pila.pop()\n  }\n  length() {\n    console.log(this.pila.length)\n  }\n  print() {\n    console.log(this.pila)\n  }\n}\n\nclass Cola {\n  constructor(colaArray) {\n    this.cola = colaArray\n  }\n\n  add(element) {\n    this.cola.push(element)\n  }\n  delete() {\n    this.cola.shift()\n  }\n  length() {\n    console.log(this.cola.length)\n  }\n  print() {\n    console.log(this.cola)\n  }\n}\n\nconst arrayOfThePila = new Pila([1, 2, 3, 4, 5, 6])\nconst arrayOfTheCola = new Cola([1, 2, 3, 4, 5, 6])\n\nconsole.log('/////// PILA ///////')\narrayOfThePila.print()\narrayOfThePila.length()\narrayOfThePila.add(7)\narrayOfThePila.print()\narrayOfThePila.length()\narrayOfThePila.delete()\narrayOfThePila.print()\n\nconsole.log('/////// COLA ///////')\narrayOfTheCola.print()\narrayOfTheCola.length()\narrayOfTheCola.add(7)\narrayOfTheCola.print()\narrayOfTheCola.length()\narrayOfTheCola.delete()\narrayOfTheCola.print()\n"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/jhoshmc.js",
    "content": "class Mamifero {\n  //? Atributos\n  constructor(especie, nombre, edad) {\n    this._especie = especie;\n    this._nombre = nombre;\n    this._edad = edad;\n  }\n  //? metodos\n  saludar() {\n    if (this._especie == \"humano\") {\n      console.log(\n        `\\nhola mi nombre es ${this._nombre} y tengo ${this._edad}, mucho gusto`\n      );\n    } else {\n      console.log(`\\n mi nombre es ${this._nombre} y saludo dandote la pata`);\n    }\n  }\n}\n\nclass Pila {\n  //? atributos\n  constructor() {\n    this.stack = [];\n  }\n  //? metodos\n  //*ver si la pila está vacia, true:vacia, false: tiene elementos\n  empty() {\n    return this.stack.length == 0;\n  }\n  //* agregar elementos a la pila\n  push(elemento) {\n    this.stack.push(elemento);\n  }\n  //* mostrar el último elemento de la pila sin eliminarlo\n  end() {\n    if (this.stack.length !== 0) {\n      return this.stack[this.stack.length - 1];\n    }\n    console.log(\"\\nno se puede mostrar elemento, la pila esta vacia\");\n  }\n  //* eliminar el último elemento de la pila y retornarlo\n  pop() {\n    if (this.stack.length !== 0) {\n      return this.stack.pop();\n    }\n    console.log(\"\\nno se puele elimnar cuando la pila esta vacia\");\n  }\n  //*retornar el tamaño de la pila\n  size() {\n    return this.stack.length;\n  }\n  //* mostrar la pila\n  print() {\n    if (this.stack.length !== 0) {\n      console.log(this.stack);\n    } else {\n      console.log(\"\\n la pila esta vacia\");\n    }\n  }\n}\n\nclass Cola {\n  //? atributos\n  constructor() {\n    this.queque = [];\n  }\n  //? metodos\n  //* metodo para saber si la cola esta vacia, true: esta vacia, false: tiene elementos\n  empty() {\n    return this.queque.length == 0;\n  }\n  //*para egregar un elemento al final de la cola\n  push(elemento) {\n    this.queque.push(elemento);\n  }\n  //* para eliminar el primer elemento de la cola y retornar su valor\n  pop() {\n    if (this.queque.length !== 0) {\n      return this.queque.shift();\n    }\n    console.log(\"\\n no hay elemento en la cola\");\n  }\n  //*para mostrar el primer elmento de la cola sin eliminarlo\n  front() {\n    if (this.queque.length !== 0) {\n      return this.queque[0];\n    } else {\n      console.log(\"\\nno hay elementos en la cola\");\n    }\n  }\n  //* para mostrar el tamaño de la cola\n  size() {\n    return this.queque.length;\n  }\n  //* mostrar la cola\n  print() {\n    if (this.queque.length !== 0) {\n      console.log(this.queque);\n    } else {\n      console.log(\"\\nno hay elementos en la cola para mostrar\");\n    }\n  }\n}\n\nfunction ejercicio() {\n  const miguel = new Mamifero(\"humano\", \"miguel\", 20);\n  const chester = new Mamifero(\"canina\", \"chester\", 3);\n  const laila = new Mamifero(\"canina\", \"laila\", 2);\n  const lita = new Mamifero(\"felina\", \"lita\", 1);\n  miguel.saludar();\n  chester.saludar();\n  laila.saludar();\n  lita.saludar();\n}\n//todo ejercicios extras\nfunction extraPila() {\n  const pila = new Pila();\n  console.log(`la pila esta vacia?: ${pila.empty()}`);\n  console.log(\"agregando elementos a la pila: \");\n  pila.push(1);\n  pila.push(2);\n  pila.push(3);\n  console.log(`el tamaño de la pila es: ${pila.size()}`);\n  console.log(\"mostrando elementos de la pila: \");\n  pila.print();\n  console.log(`la pila esta vacia?: ${pila.empty()}`);\n  console.log(`mostrado ultimo elemento de la pila: ${pila.end()}`);\n  console.log(`eliminando el ultimo elmento de la pila: ${pila.pop()}`);\n  pila.print();\n  console.log(`eliminando el ultimo elmento de la pila: ${pila.pop()}`);\n  pila.print();\n  console.log(`eliminando el ultimo elmento de la pila: ${pila.pop()}`);\n  pila.print();\n}\nfunction extraCola() {\n  const cola = new Cola();\n  console.log(`la cola esta vacia?: ${cola.empty()}`);\n  console.log(\"agregando elementos a la pila\");\n  cola.push(1);\n  cola.push(2);\n  cola.push(3);\n  console.log(`tamaño de la cola: ${cola.size()}`);\n  console.log(`primer elemento de la cola: ${cola.front()}`);\n  console.log(\"mostrando cola: \");\n  cola.print();\n  console.log(`eliminando el primer elemento de la cola: ${cola.pop()}`);\n  cola.print();\n  console.log(`eliminando el primer elemento de la cola: ${cola.pop()}`);\n  cola.print();\n  console.log(`eliminando el primer elemento de la cola: ${cola.pop()}`);\n  cola.print();\n}\n//todo ejecutando programas\nejercicio();\nextraPila();\nextraCola();\n"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/joapalobael.js",
    "content": "/* Clase */\n\nclass Persona {\n    // Constructor\n    constructor(nombre, apellido, edad) {\n        this.nombre = nombre;\n        this.apellido = apellido;\n        this.edad = edad;\n    }\n    // Métodos\n    saludar (){\n        console.log (`${this.nombre} ${this.apellido} tiene ${this.edad} años.`);\n    }\n\n}\n\nlet persona1 = new Persona (\"Alan\", \"Martinez\", 65);\npersona1.saludar();\n\n/* DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n * \n */\n\n/*Pila*/\nclass SesionChrome{\n    //Constructor\n    constructor(){\n        this.navegador = [\"Inicio\"] //Inicia lista\n    }\n    //LI (Push)\n    adelante (web){\n        this.navegador.push(web);\n        console.log(this.navegador);\n    }\n    //FO (POP)\n    atras(){\n        if (this.navegador.length <= 1) {\n            console.log(\"Hasta aquí llegaste\");\n        } else {\n            this.navegador.pop();\n            console.log(this.navegador);\n        }\n    }\n    cantidadSitios(){\n        if (this.navegador.length <= 1) {\n            console.log(`Estas en el inicio`);\n        } else {\n            console.log(`Estas a ${this.navegador.length} webs del inicio`);\n        }\n    }\n    listaDeSitios(){\n        console.log(this.navegador);\n    }\n}\n\nlet user1 = new SesionChrome();\nuser1.adelante(\"Instragram\");\nuser1.adelante(\"Facebook\");\nuser1.atras();\nuser1.cantidadSitios();\nuser1.listaDeSitios();\n\n/*Cola*/\nclass Impresion {\n    constructor(){\n        this.colaImpresion = [];\n    }\n    //FI (push)\n    agregar(archivo){\n        this.colaImpresion.push(archivo);\n    }\n    //FO (shift)\n    imprimir(){\n         if (this.colaImpresion.length <=0) {\n            console.log(\"No hay archivos para imprimir\");\n         } else {\n            let archivoImpreso = this.colaImpresion.shift();\n            console.log(`El archivo \"${archivoImpreso}\" fue impreso y luego se eliminó de la cola`);\n         }\n    }\n    mostrarCola(){\n        console.log(this.colaImpresion);\n    }\n    cantidadCola(){\n        console.log(`Hay ${this.colaImpresion.length} archivos en cola.`);\n    }\n\n}\n\nlet cola1 = new Impresion;\ncola1.agregar(\"notas\");\ncola1.agregar(\"boletín\");\ncola1.mostrarCola();\ncola1.imprimir();\ncola1.cantidadCola();\ncola1.imprimir();\ncola1.cantidadCola();"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/juandaherrera.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n */\n\nclass Persona {\n    constructor(firstName, lastName, birthDate) {\n        this.firstName = firstName;\n        this.lastName = lastName;\n        this.birthDate = new Date(birthDate); // birthDate debe ser una cadena en formato 'YYYY-MM-DD'\n    }\n\n    get age() {\n        const today = new Date();\n        let age = today.getFullYear() - this.birthDate.getFullYear();\n        const m = today.getMonth() - this.birthDate.getMonth();\n        if (m < 0 || (m === 0 && today.getDate() < this.birthDate.getDate())) {\n            age--;\n        }\n        return age;\n    }\n\n    describe() {\n        console.log(\n            `${this.firstName} ${this.lastName} tiene ${this.age} años`\n        );\n    }\n}\n\nconst juanDavid = new Persona(\"Juan David\", \"Herrera\", \"1999-12-05\");\njuanDavid.describe();\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n */\n\nclass Stack {\n    constructor(stack = []) {\n        this.stack = stack;\n    }\n\n    push(value) {\n        this.stack.push(value);\n    }\n\n    pop() {\n        this.stack.pop();\n    }\n\n    toString() {\n        return this.stack.toString();\n    }\n}\n\nlet myStack = new Stack([1, 2, 3, 4, 5]);\nconsole.log(myStack.toString());\n\n// Inserción\nmyStack.push(6);\nconsole.log(myStack.toString());\n\n// Eliminación\nmyStack.pop();\nconsole.log(myStack.toString());\n\nconsole.log(\"---------------------------------\");\n\n// Colas\nclass Queue {\n    constructor(queue = []) {\n        this.queue = queue;\n    }\n\n    enqueue(value) {\n        this.queue.push(value);\n    }\n\n    dequeue() {\n        this.queue.shift();\n    }\n\n    toString() {\n        return this.queue.toString();\n    }\n}\n\nlet myQueue = new Queue([1, 2, 3, 4, 5]);\nconsole.log(myQueue.toString());\n\n// Inserción\nmyQueue.enqueue(6);\nconsole.log(myQueue.toString());\n\n// Eliminación\nmyQueue.dequeue();\nconsole.log(myQueue.toString());\n\n// Ambas\nmyQueue.enqueue(7);\nmyQueue.dequeue();\nmyQueue.dequeue();\nmyQueue.dequeue();\nmyQueue.enqueue(8);\nmyQueue.dequeue();\nmyQueue.enqueue(9);\nconsole.log(myQueue.toString());\n"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/juserdev.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n */\n\nclass Producto {\n    constructor(nombre, precio, stock) {\n        this.nombre = nombre;\n        this.precio = precio;\n        this.stock = stock;\n    }\n\n    print() {\n        return `Producto: ${this.nombre}, Precio: ${this.precio}, Stock: ${this.stock}`\n    }\n\n}\n\nconst mesa = new Producto(\"Mesa\", 1000, 10)\n\nconsole.log(mesa.print())\nmesa.precio = 100\nconsole.log(mesa.print())\n\n\n// Dificultad extra\n//* Stack\nconsole.log(\"--------------- Stack ---------------\")\n\nclass Stack {\n    constructor(stack = []) {\n        this.stack = stack\n    }\n\n    addStack(number) { return this.stack.push(number) }\n    removeStack() { return this.stack.pop() }\n    print() { return this.stack }\n    elements() { return this.stack.length }\n\n}\n\nconst stack = new Stack()\n\nconsole.log(stack.addStack(1))\nconsole.log(stack.addStack(2))\nconsole.log(stack.addStack(3))\nconsole.log(stack.addStack(4))\nconsole.log(stack.print())\nconsole.log(stack.removeStack())\nconsole.log(stack.addStack(5))\nconsole.log(stack.print())\nconsole.log(stack.elements())\n\nconsole.log(\"--------------- Queue ---------------\")\n\nclass Queue {\n    constructor(stack = []) {\n        this.stack = stack\n    }\n\n    addStack(number) { return this.stack.push(number) }\n    removeStack() { return this.stack.shift() }\n    print() { return this.stack }\n    elements() { return this.stack.length }\n\n}\n\nconst queue = new Queue()\n\nconsole.log(queue.addStack(1))\nconsole.log(queue.addStack(2))\nconsole.log(queue.addStack(3))\nconsole.log(queue.addStack(4))\nconsole.log(queue.print())\nconsole.log(queue.removeStack())\nconsole.log(queue.addStack(5))\nconsole.log(queue.print())\nconsole.log(queue.elements())\nconsole.log(queue.removeStack())\nconsole.log(queue.print())"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n_______________________________________\n#08 CLASES\n---------------------------------------\n* EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n*/\n\n// ________________________________________________________\nclass Employee {\n    // Atributos de clase\n    static baseSalary = 25000;\n    static vacationDays = 15;\n\n    // Constructor\n    constructor(name, hireDate) {\n        this.name = name;\n        this.hireDate = hireDate;\n    }\n\n    // Métodos de instancia\n    edit(name, hireDate) {\n        this.name = name;\n        this.hireDate = hireDate;\n    }\n\n    println() {\n        console.log(`Name: ${this.name} - Hire date: ${this.hireDate}`);\n    }\n}\n\n// Crear objeto\nconst employeeInstance = new Employee(\"Ben\", \"2024-02-01\");\n\n// Acceder a los atributos\nconsole.log(`\nName:          ${employeeInstance.name}\nHire date:     ${employeeInstance.hireDate}\nBase salary:   ${Employee.baseSalary}\nVacation days: ${Employee.vacationDays}\n`);\n\n// Utilizar métodos\nemployeeInstance.edit(\"Ben edit\", \"2024-03-01\");\nemployeeInstance.println();\n\n// ________________________________________________________\n// DIFICULTAD EXTRA\n// __________________________\n// Clase Stack (Pila - LIFO):\nclass Stack {\n    constructor() {\n        this.elements = [];\n    }\n\n    get length() { // Total elementos\n        return this.elements.length;\n    }\n\n    isEmpty() { // Es vacía\n        return this.length === 0;\n    }\n\n    push(item) { // Agregar elemento\n        this.elements.push(item);\n    }\n\n    pushBatch(items) { // Agregar múltiples\n        this.elements.push(...items);\n    }\n\n    popGet() { // Eliminar y obtener\n        return this.isEmpty() ? null : this.elements.pop();\n    }\n\n    getTop() { // Obtener sin eliminar\n        return this.isEmpty() ? null : this.elements[this.elements.length - 1];\n    }\n\n    toArray() { // Retornar pila como tupla\n        return [...this.elements].reverse();\n    }\n\n    clear() { // Vaciar pila\n        this.elements = [];\n    }\n}\n\n// __________________________\n// Clase Queue (Cola - FIFO):\nclass Queue {\n    constructor() {\n        this.elements = [];\n    }\n\n    get length() { // Total elementos\n        return this.elements.length;\n    }\n\n    isEmpty() { // Es vacía\n        return this.length === 0;\n    }\n\n    enqueue(item) { // Agregar elemento\n        this.elements.push(item);\n    }\n\n    enqueueAll(items) { // Agregar múltiples\n        this.elements.push(...items);\n    }\n\n    dequeue() { // Eliminar y devolver\n        return this.isEmpty() ? null : this.elements.shift();\n    }\n\n    peek() { // Obtener sin eliminar\n        return this.isEmpty() ? null : this.elements[0];\n    }\n\n    toArray() { // Retornar cola como tupla\n        return [...this.elements];\n    }\n\n    clear() { // Vaciar cola\n        this.elements = [];\n    }\n}\n\n// __________________________\nconsole.log(\"\\nUso de pila:\");\nconst mystack = new Stack();\nmystack.push(\"Zoe\");\nmystack.pushBatch([\"Ben\", \"Dan\"]);\nif (!mystack.isEmpty()) {\n    console.log(mystack.popGet());\n}\nconsole.log(`Número de elementos: ${mystack.length}`);\nfor (const name of mystack.toArray()) {\n    console.log(name);\n}\n\n// __________________________\nconsole.log(\"\\nUso de cola:\");\nconst myqueue = new Queue();\nmyqueue.enqueue(\"Zoe\");\nmyqueue.enqueueAll([\"Ben\", \"Dan\"]);\nif (!myqueue.isEmpty()) {\n    console.log(myqueue.dequeue());\n}\nconsole.log(`Número de elementos: ${myqueue.length}`);\nfor (const name of myqueue.toArray()) {\n    console.log(name);\n}\n"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/marcode24.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n */\n\nclass Stack {\n  constructor() {\n    this.items = [];\n  }\n\n  push(element) {\n    this.items.push(element);\n  }\n\n  pop() {\n    if (this.isEmpyt()) {\n      return 'La pila esta vacia';\n    }\n    return this.items.pop();\n  }\n\n  isEmpyt() {\n    return this.items.length === 0;\n  }\n\n  peek() {\n    return this.items[this.items.length - 1];\n  }\n\n  clear() {\n    this.items = [];\n  }\n\n  size() {\n    return this.items.length;\n  }\n}\n\nclass Queue {\n  constructor() {\n    this.items = [];\n  }\n\n  enqueue(element) {\n    this.items.push(element);\n  }\n\n  dequeue() {\n    if (this.isEmpyt()) {\n      return 'La cola esta vacia';\n    }\n    return this.items.shift();\n  }\n\n  isEmpyt() {\n    return this.items.length === 0;\n  }\n\n  size() {\n    return this.items.length;\n  }\n}\n\nconst pila = new Stack();\npila.push(1);\npila.push(2);\npila.push(3);\nconsole.log(pila.pop()); // 3\nconsole.log(pila.pop()); // 2\n\nconst cola = new Queue();\ncola.enqueue('a');\ncola.enqueue('b');\ncola.enqueue('c');\nconsole.log(cola.dequeue()); // a\nconsole.log(cola.dequeue()); // b\n\nclass Navegador {\n  constructor() {\n    this.history = new Stack();\n    this.future = new Stack();\n    this.currentPage = null;\n  }\n\n  // navegar a una nueva pagina\n  goToPage(page) {\n    if (this.currentPage !== null) {\n      this.history.push(this.currentPage);\n    }\n    this.currentPage = page;\n    this.future.clear();\n    console.log('Pagina actual: ', this.currentPage);\n  }\n\n  // retroceder a la pagina anterior\n  goBack() {\n    if (this.history.isEmpyt()) {\n      console.log('No hay paginas anteriores');\n      return;\n    }\n    this.future.push(this.currentPage);\n    this.currentPage = this.history.pop();\n    console.log('Pagina actual: ', this.currentPage);\n  }\n\n  // avanzar a la pagina siguiente\n  goForward() {\n    if (this.future.isEmpyt()) {\n      console.log('No hay paginas siguientes');\n      return;\n    }\n    this.history.push(this.currentPage);\n    this.currentPage = this.future.pop();\n    console.log('Pagina actual: ', this.currentPage);\n  }\n}\n\nconst navegador = new Navegador();\nnavegador.goToPage('google.com');\nnavegador.goToPage('facebook.com');\nnavegador.goToPage('twitter.com');\nnavegador.goBack(); // regresa a facebook.com\nnavegador.goBack(); // regresa a google.com\nnavegador.goForward(); // avanza a facebook.com\nnavegador.goToPage('instagram.com'); // instagram.com\nnavegador.goBack(); // regresa a facebook.com\nnavegador.goForward(); // avanza a instagram.com\n\n// Visita mi repo en GitHub para ver y correr los tests de este código --> https://github.com/marcode24/weekly-challenges\n"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/miguelex.js",
    "content": "class Vehiculo {\n    constructor(nombre, numRuedas){\n        this.nombre = nombre;\n        this.numRuedas = numRuedas;\n    }\n\n    toString(){\n        return \"Nombre: \" + this.nombre + \", Ruedas: \" + this.numRuedas;\n    }\n}\n\nlet coche = new Vehiculo(\"Coche\", 4);\nlet bicicleta = new Vehiculo(\"Bicicleta\", 2);\n\nconsole.log(coche.toString());\nconsole.log(bicicleta.toString());\n\nclass Pila {\n    constructor(){\n        this.pila = [];\n    }\n\n    push(elemento){\n        this.pila.push(elemento);\n    }\n\n    pop(){\n        return this.pila.pop();\n    }\n\n    toString(){\n        return this.pila.toString();\n    }\n\n    size(){\n        return this.pila.length;\n    }\n}\n\nclass Cola {\n    constructor(){\n        this.cola = [];\n    }\n\n    push(elemento){\n        this.cola.push(elemento);\n    }\n\n    pop(){\n        return this.cola.shift();\n    }\n\n    toString(){\n        return this.cola.toString();\n    }\n\n    size(){\n        return this.cola.length;\n    }\n}\n\nlet pila = new Pila();\n\nconsole.log(\"Ejemplo de pila\");\n\npila.push(1);\npila.push(2);\npila.push(3);\nconsole.log(\"Contendido de la pila: \" + pila.toString());\nconsole.log(\"Extraigo en elemento que esta en la cima: \" + pila.pop());\nconsole.log(\"Contendido de la pila: \" + pila.toString());\nconsole.log(\"Tamaño de la pila: \" + pila.size());\n\nlet cola = new Cola();\n\nconsole.log(\"Ejemplo de cola\");\n\ncola.push(1);\ncola.push(2);\ncola.push(3);\n\nconsole.log(\"Contendido de la cola: \" + cola.toString());\nconsole.log(\"Extraigo el primer elemento de la cola: \" + cola.pop());\nconsole.log(\"Contendido de la cola: \" + cola.toString());\nconsole.log(\"Tamaño de la cola: \" + cola.size());\n"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/natalyjoanna.js",
    "content": "\n// Declaracion \n\nclass Rectangulo {\n  constructor(ancho, altura) {\n    this.altura = altura;\n    this.ancho = ancho;\n  }\n  \n  printRectangulo() {\n    console.log(`La altura del rectangulo es de ${this.altura} y su ancho de ${this.ancho}`)\n  }\n}\n\n\n// Expresion: la clase es anonima pero esta asignada a una variable\n// const Rectangulo = class {\n//   constructor(ancho, altura) {\n//     this.ancho = ancho;\n//     this.altura = altura;\n//   }\n// }\n\n// // Expresion: la clase tiene su propio nombre diferente al de la variable que se le asigna\n// const Rectangulo = class Rectangulo2 {\n//   constructor(ancho, altura) {\n//     this.ancho = ancho;\n//     this.altura = altura;\n//   }\n// }\n\nlet rec = new Rectangulo(23, 50)\nrec.printRectangulo()\n// Modificar parametros\nrec.altura = 33\nrec.printRectangulo()\n\n// DIFICULTAD EXRA\nclass Pila {\n  constructor() {\n    this.pila = [];\n  }\n\n  // Agregar nuevo eleento a la pila\n  agregar(elemento) {\n    this.pila.push(elemento)\n  }\n\n  // Elimina el ultimo elemento de la pila\n  eliminar() {\n    if (this.size() === 0) return null;\n    return this.pila.pop()\n  }\n\n  // Imprime toda la pila\n  printPila() {\n    console.log(this.pila)\n  }\n\n  // Devuelve el numero de elementos que contiene la pila\n  size() {\n    return this.pila.length\n  }\n\n}\n\nlet pila = new Pila()\n\n// Agregamos valores a la pila\npila.agregar('Manuel')\npila.agregar('Maria')\npila.agregar('Federico')\npila.printPila()\n// Eliminamos el ultimo elemento de la pila\npila.eliminar()\npila.printPila()\n// Mostrar numero de elementos actual de la pila\nconsole.log(pila.size())\n\nclass Cola {\n  constructor() {\n    this.cola = [];\n  }\n\n  // Agregar un elemento a la cola\n  agregar(elemento) {\n    this.cola.push(elemento)\n  }\n\n  // Eliminar el primer elemento de la cola\n  eliminar() {\n    if(this.size() === 0) return null;\n      return this.cola.shift();\n    \n  }\n\n  // Imprime toda la cola\n  printCola() {\n    if(this.cola.length === 0) {\n      console.log('La cola esta vacia');\n    } else {\n    console.log(this.cola);\n    }\n  }\n\n  // Devuelve el numero de elementos que contiene la cola\n  size() {\n    return this.cola.length\n  }\n\n}\n\nlet cola = new Cola()\n\n\n// Agregamos elementos a la cola\ncola.agregar(50);\ncola.agregar(15);\ncola.agregar(515);\ncola.agregar(13);\ncola.printCola() \n// Eliminamos el primer elemento de la cola\ncola.eliminar();\ncola.printCola();\n// Mostrar el numero de elementos que contiene la cola\nconsole.log(cola.size());"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/nlarrea.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n */\n\n\nclass Person {\n\n    languages = []\n    \n    constructor(name, username, age) {\n        this.name = name;\n        this.username = username;\n        this.age = age;\n    }\n    \n    printPerson() {\n        console.log(`\\nPrinting ${this.username}'s data:`);\n        console.log('name:', this.name);\n        console.log('age:', this.age);\n        \n        if (this.languages) {\n            console.log('This person uses the following languages to code:');\n            for (let language of this.languages) {\n                console.log(` - ${language}`);\n            }\n        }\n    }\n}\n        \n\nme = new Person(name='Naia', username='nlarrea', age=25);\nme.printPerson();\nme.languages = ['Python', 'JavaScript', 'Kotlin'];\nme.printPerson();\nme.age = 26;\nme.printPerson();\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n */\n\n\nconsole.log('\\nLIFO:\\n')\n\n\n/**\n * Stack is a LIFO (Last In First Out).\n */\nclass Stack{\n    constructor() {\n        this.stack = [];\n    }\n    \n    add(...items) {\n        this.stack = this.stack.concat([...items]);\n    }\n        \n    remove() {\n        if (this.length() === 0) {\n            return null;\n        }\n        return this.stack.pop();\n    }\n        \n    length() {\n        return this.stack.length;\n    }\n        \n    print() {\n        for (let item of this.stack.slice().reverse()) {\n            console.log(item);\n        }\n    }\n}\n        \n\nlifo = new Stack();\nlifo.add(1, 2, 3);\nlifo.print();\n/*\n3\n2\n1\n*/\nconsole.log('LIFO length:', lifo.length());\n// LIFO length: 3\n\nlifo.remove();  // This would print the number 3 because it's the removed one\nlifo.print();\n/*\n2\n1\n*/\nconsole.log('LIFO length:', lifo.length());\n// LIFO length: 2\n\n\nconsole.log('\\nFIFO:\\n');\n\n\n/**\n * A Queue is a FIFO (First In, First Out).\n */\nclass Queue {\n    constructor() {\n        this.queue = [];\n    }\n\n    add(...items) {\n        this.queue = this.queue.concat([...items]);\n    }\n    \n    remove() {\n        if (this.length() === 0) {\n            return null;\n        }\n        return this.queue.shift();\n    }\n\n    length() {\n        return this.queue.length;\n    }\n    \n    print() {\n        for (let item of this.queue) {\n            console.log(item);\n        }\n    }\n}\n        \n\nfifo = new Queue();\nfifo.add(1, 2, 3);\nfifo.print();\n/*\n1\n2\n3\n*/\nconsole.log('FIFO length:', fifo.length());\n// FIFO length: 3\n\nfifo.remove();\nfifo.print();\n/*\n2\n3\n*/\nconsole.log('FIFO length:', fifo.length());\n// FIFO length: 2"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/ocram1304.js",
    "content": "//Clases\nclass Persona{\n    #nombre;\n    #edad;\n    #sexo;\n    #carrera;\n    constructor(nombre,edad, sexo,carrera){\n        this.#nombre=  nombre;\n        this.#sexo = sexo;\n        this.#edad = edad;\n        this.#carrera = carrera;\n\n    }\n    saludos(){\n        console.log(`Hola soy ${this.#nombre}, tengo ${this.#edad} y soy ${this.#carrera}`);\n\n    }\n    actualizar(nuevaEdad,nuevaCarrera){\n        this.#edad = nuevaEdad;\n        this.#carrera = nuevaCarrera;\n    }\n\n}\nconst  Gerardo  = new Persona(\"Gerardo\",23,\"masculino\",\"Sistemas\");\nGerardo.saludos();\nGerardo.actualizar(24,\"Barbero\");\nGerardo.saludos();\n\n//Difucultad  extra\nclass Pila {\n    constructor() {\n      this.stack = []\n      this.top = 0\n    }\n  \n    // Añade un elemento al final de la pila\n    push(newValue) {\n      this.stack.push(newValue)\n      this.top += 1\n    }\n  \n    // Regresa y remiueve el último elemento de la  pila\n    pop() {\n      if (this.top !== 0) {\n        this.top -= 1\n        return this.stack.pop()\n      }\n      throw new Error('Stack Underflow')\n    }\n\n    showItems(){\n        if(!this.isEmpty()){\n            for(let i= 0; i< top;i++){\n            console.log(this.stack[i]);\n             }\n        }\n        else{\n            throw new Error (\"Pila  vacia\"); \n        }\n        \n    }\n  \n    // Regresa el número de elementos de la pila\n    get length() {\n      return this.top\n    }\n  \n    // Regresa si la pila estta vacia\n    get isEmpty() {\n      return this.top === 0\n    }\n  \n    // Regresa  el último elemento sin removerlo \"peak\"\n    get last() {\n      if (this.top !== 0) {\n        return this.stack[this.stack.length - 1]\n      }\n      return null\n    }\n  \n    // Checa si un objeto es instancia de la clase pila\n    static isStack(el) {\n      return el instanceof Stack\n    }\n  }\n\n  const monedas = new Pila();\n  monedas.push(\"1\");\n  monedas.push(\"5\");\n  monedas.push(\"10\");\n  monedas.push(\"20\");\n  monedas.showItems();\n\n  class Cola{\n    //Constructor de la cola\n    constructor(){\n      this.queue  = [];\n \n    }\n    //Añadir un nuevo valor a la cola (encolar)\n    push( value){\n        this.queue .push(value);\n    }\n    //Eliminar el primer elemento de la cola (des-encolar)\n    pop(){\n      if(this.queue.length !==  0){\n        return this.queue.shift();\n      }\n     throw new  Error(\"Cola vacia\");\n    }\n    showItems(){\n        if(!this.isEmpty()){\n            for(let i  = this.queue.length-1;i>=0;i--){\n                console.log(this.queue[i]);\n            }\n        }\n        else{\n            throw new Error (\"Cola vacia\");\n        }\n        \n    }\n    //Obtener el frente de la cola\n    get FrenteCola(){\n      if(this.queue.length !==  0){\n        return this.queue[0];\n      }\n      throw new  Error(\"Cola vacia\");\n    }\n    //Obtener el final de la cola\n   get FinalCola(){\n    if(this.queue.length !==  0){\n      return this.queue[this.queue.length-1];\n    }\n    throw new  Error(\"Cola vacia\");\n    }\n    //Verificar si la cola está vacia\n    isEmpty(){\n      return this.queue.length === 0;\n    }\n\n  }\n\n  const filaTortillas = new Cola();\n  filaTortillas.push(1);\n  filaTortillas.push(2);\n  filaTortillas.push(3);\n  filaTortillas.push(4);\n  filaTortillas.showItems();\n"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/oleojake.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n */\n\nclass Car {\n    constructor(initMarca, initModelo, initColor, initPrecio){\n        this.marca = initMarca;\n        this.modelo = initModelo;\n        this.color = initColor;\n        this.precio = initPrecio;\n    }\n\n    getSpecs(){\n        return \"| SPECS | Marca: \" + this.marca + \" | Modelo: \" + this.modelo + \" | Color: \" + this.color + \" | Precio: \" + this.precio\n    }\n}\n\nconst coche1 = new Car('Ford', 'Fiesta', 'Rojo', 12000);\nconsole.log(coche1.getSpecs())\ncoche1.modelo = 'Focus'\ncoche1.color = 'Blanco'\ncoche1.precio = '18000'\nconsole.log(coche1.getSpecs())\n\n\n\n/* DIFICULTAD EXTRA (opcional):\n* Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n* en el ejercicio número 7 de la ruta de estudio)\n* - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n*   retornar el número de elementos e imprimir todo su contenido.\n*/\n\n\n// PILA (Last In First Out)\n\nclass Pila {\n    constructor(initElements){\n        this.elements = [...initElements];\n    }\n\n    insert (element) {\n        this.elements.push(element);\n    }\n\n    delete () {\n        this.elements.pop();\n    }\n\n    peek () {\n        return this.elements[this.elements.length-1];\n    }\n\n    size () {\n        return this.elements.length;\n    }\n\n    print () {\n        return this.elements;\n    }\n}\n\n\nconst pila1 = new Pila(['Fresa', 'Mango']);\nconsole.log(pila1.print()); \npila1.insert('Naranja');\npila1.insert('Manzana');\npila1.insert('Pera');\nconsole.log(pila1.print()); \nconsole.log(pila1.peek()); \nconsole.log(pila1.size()); \npila1.delete();\nconsole.log(pila1.print()); \n\n\n// COLA First In First Out\n\nclass Cola {\n    constructor(initElements){\n        this.elements = [...initElements]\n    }\n\n    insert (element) {\n        this.elements.push(element);\n    }\n\n    delete () {\n        this.elements.shift();\n    }\n\n    peek () {\n        return this.elements[0];\n    }\n\n    size () {\n        return this.elements.length;\n    }\n\n    print () {\n        return this.elements;\n    }\n}\n\nconst cola1 = new Cola(['Papaya', 'Plátano']);\nconsole.log(cola1.print()); \ncola1.insert('Naranja');\ncola1.insert('Manzana');\ncola1.insert('Pera');\nconsole.log(cola1.print());\nconsole.log(cola1.peek());\nconsole.log(cola1.size());\ncola1.delete();\nconsole.log(cola1.print());"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/parababire.js",
    "content": "//Clases: funciones especiales. La sintaxis puede ser de dos formas.\n\n/*Declaración de clases*/\n\nclass Vehiculo {//Utilizamos la palabra reservada class y por convención el nombre en mayuscula.\n  constructor(fabricante, modelo) {//Solo puede ser llamado un constructor o inicializador por clase.\n    this.fabricante = fabricante;\n    this.modelo = modelo;\n  }\n  get fabricante() {\n    return this._fabricante;\n  }\n  set fabricante(fabricante) {\n    this._fabricante = fabricante;\n  }\n  get modelo() {\n    return this._modelo;\n  }\n  set modelo(modelo) {\n    this._modelo = modelo;\n  }\n  caracteristicas() {\n    console.log(`Vehiculo marca ${this.fabricante} modelo ${this.modelo}`);\n  }\n}\nlet carro = new Vehiculo(\"Toyota\", \"Corrolla\");\nconsole.log(`Compre un ${carro.fabricante} ${carro.modelo}.`);\ncarro.caracteristicas();\ncarro.modelo = \"Prius\";\ncarro.caracteristicas();\n\n/*Expresión de clases*/\n\n//Anónima\nlet Perro = class {\n  constructor(patas, cola, raza) {\n    this.patas = patas;\n    this.cola = cola;\n    this.raza = raza;\n  }\n}\n\n//Nombrada\nlet Rectangulo = class Rectangulo1 {\n  constructor(alto, ancho) {\n    this.alto = alto;\n    this.ancho = ancho;\n  }\n}\n\n//Extra\n\nclass Pila {\n  constructor() {\n    this.pila = [];\n  }\n  push(element) {\n    this.pila.push(element);\n    return this.pila;\n  }\n  pop() {\n    if (this.pila.length === 0) {\n      return \"Sin elementos\";\n    } else {\n      return this.pila.pop();\n    }\n  }\n  size() {\n    return this.pila.length;\n  }\n  print() {\n    console.log(this.pila);\n  }\n}\n\nlet pila = new Pila();\nconsole.log(pila.pop());\npila.push(\"María\");\npila.push(\"Luis\");\npila.push(\"Pedro\");\npila.push(\"Yolanda\");\npila.print();\nconsole.log(pila.pop());\nconsole.log(pila.size());\npila.print();\n\nclass Queue {\n  constructor() {\n    this.queue = [];\n  }\n  enqueue(element) {\n    this.queue.push(element);\n  }\n  dequeue() {\n    return this.queue.shift();\n  }\n  size() {\n    return this.queue.length;\n  }\n  print() {\n    console.log(this.queue);\n  }\n}\n\nlet queue = new Queue();\nqueue.enqueue(\"María\");\nqueue.enqueue(\"Luis\");\nqueue.enqueue(\"Pedro\");\nqueue.enqueue(\"Yolanda\");\nqueue.print();\nconsole.log(queue.dequeue());\nconsole.log(queue.size());\nqueue.print();"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/pedamoci.js",
    "content": "class Pokemon {\n  name  //  <--- atributo\n  primerTipo  //  <--- atributo\n  segundoTipo  //  <--- atributo\n\n  constructor(name, primerTipo, segundoTipo) {  //  <--- inicializador\n    this.name = name\n    this.primerTipo = primerTipo\n    this.segundoTipo = segundoTipo\n  }\n\n  imprimirAtributos() {  //  <--- función que imprime los atributos\n    console.log(`${this.name} es de tipo ${this.primerTipo} y ${this.segundoTipo}`)\n  }\n\n  /*imprimirAtributos(name) {  //  <--- función que imprime los atributos\n    Object.entries(name).forEach(([key, value]) => {\n      console.log(`${key}: ${value}`)\n    })\n    //console.log(`${this.name} es de tipo ${this.primerTipo} y ${this.segundoTipo}`)\n  }*/\n}\n\nconst dartix = new Pokemon('Dartix', 'Planta', 'Volador')  // <--- crandola y estableciendo sus parametros\ndartix.imprimirAtributos()\n\n/*dartix.imprimirAtributos(dartix)*/\n\ndartix.name = 'Decidueye'  // <--- modificando sus parametros\ndartix.segundoTipo = 'Fantasma'  // <--- modificando sus parametros\ndartix.imprimirAtributos()  // <--- imprimiendo los parametros con la función dentro de la clase\n\n/*dartix.imprimirAtributos(dartix)*/\n\n// ----------------------------------------- DIFICULTAD EXTRA -----------------------------------------\n  // CLASE REPRESENTANDO ESTRUCTURA DE PILA\n    class Pila {\n      constructor(name) {\n        this.namePila = name\n        this.pila = []\n      }\n    \n      add(name) {\n        this.pila.push(name)\n        console.log(`Se ha añadido a la pila el elemento '${name}'`)\n      }\n    \n      delete(name) {\n        if (this.pila.length === 0) {\n          console.log('La pila esta vacia')\n        } else if (name === undefined) {\n          this.pila.pop()\n          console.log('Ultimo elemento de la pila eliminado')\n        } else if (this.pila.includes(name)) {\n          let index = this.pila.lastIndexOf(name)  // <--- obtiene en el array la posición del elemento que se quiere eleminar\n          let lastElementPila = this.pila.slice(index + 1) // <--- guarda los elementos que hay despues del que se desea eliminar\n          this.pila = this.pila.slice(0, index).concat(lastElementPila) // <--- corta el array original hasta el elemento que se quiere eliminar (no incluido) y se le añade el   array   con los elemntos guardados\n          console.log(`se ha eliminado ${name} de la pila`)\n        } else {\n          console.log(`No hay elementos con el nombre: '${name}' en la pila`)\n        }\n      }\n    \n      numberElements() {\n        console.log(`Hay ${this.pila.length} elementos en la pila`)\n      }\n    \n      printAll() {\n        while (this.pila.length !== 0) {\n          console.log(`Se a impreso el elemento ${this.pila[this.pila.length - 1]}`)\n          this.pila.pop()\n        }\n        console.log('La pila esta vacia')\n      }\n    }\n\n    const nuevaPila = new Pila('primera pila')\n    console.log(nuevaPila)\n\n    // añade elementos\n    nuevaPila.add('pepe'); nuevaPila.add('jaime'); nuevaPila.add('juan'); nuevaPila.add('pedro'); nuevaPila.add('luffy'); nuevaPila.add('deadpool'); nuevaPila.add('red');  nuevaPila. add('aang'); nuevaPila.add('homero'); nuevaPila.add('spiderman'); nuevaPila.numberElements()\n\n    nuevaPila.delete('zoro') // <--- intento de borrar elemento no existente\n    nuevaPila.delete('red') // <--- borrar elemento existente por nombre\n    nuevaPila.delete() // <--- borrar último elemento\n\n    nuevaPila.numberElements()\n    nuevaPila.printAll()\n\n  // CLASE REPRESENTANDO ESTRUCTURA DE COLA\n  class Cola {\n    constructor(name) {\n      this.nameCola = name\n      this.cola = []\n    }\n  \n    add(name) {\n      this.cola.push(name)\n      console.log(`Se ha añadido a la cola el elemento '${name}'`)\n    }\n  \n    delete(name) {\n      if (this.cola.length === 0) {\n        console.log('La cola esta vacia')\n      } else if (name === undefined) {\n        this.cola.shift()\n        console.log('Primer elemento de la cola eliminado')\n      } else if (this.cola.includes(name)) {\n        let index = this.cola.lastIndexOf(name)  // <--- obtiene en el array la posición del elemento que se quiere eleminar\n        let lastElementCola = this.cola.slice(index + 1) // <--- guarda los elementos que hay despues del que se desea eliminar\n        this.cola = this.cola.slice(0, index).concat(lastElementCola) // <--- corta el array original hasta el elemento que se quiere eliminar (no incluido) y se le añade el   array   con los elemntos guardados\n        console.log(`se ha eliminado ${name} de la cola`)\n      } else {\n        console.log(`No hay elementos con el nombre: '${name}' en la cola`)\n      }\n    }\n  \n    numberElements() {\n      console.log(`Hay ${this.cola.length} elementos en la cola`)\n    }\n  \n    printAll() {\n      while (this.cola.length !== 0) {\n        console.log(`Se a impreso el elemento ${this.cola[0]}`)\n        this.cola.shift()\n      }\n      console.log('La pila esta vacia')\n    }\n  }\n\n  const nuevaCola = new Cola('primera cola')\n  console.log(nuevaCola)\n\n  // añade elementos\n  nuevaCola.add('pepe'); nuevaCola.add('jaime'); nuevaCola.add('juan'); nuevaCola.add('pedro'); nuevaCola.add('luffy'); nuevaCola.add('deadpool'); nuevaCola.add('red');  nuevaCola. add('aang'); nuevaCola.add('homero'); nuevaCola.add('spiderman'); nuevaCola.numberElements()\n\n  nuevaCola.delete('zoro') // <--- intento de borrar elemento no existente\n  nuevaCola.delete('red') // <--- borrar elemento existente por nombre\n  nuevaCola.delete() // <--- borrar último elemento\n\n  nuevaCola.numberElements()\n  nuevaCola.printAll()"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/popmaquin.js",
    "content": "/*---Clase---*/\nclass miclase{\n    constructor(nombre, pais){\n        this.nombre = nombre;\n        this.pais = pais;\n    }\n    saludar(){\n        console.log(\"Bienvenido a \" + this.pais +\" \"+ this.nombre);\n    }\n}\n\nlet bienvenido = new miclase(\"Julio\",\"Guatemala\");\nbienvenido.saludar(); //Bienvenido a Guatemala Julio\n\nbienvenido.pais = \"Peten\";\nbienvenido.saludar(); //Bienvenido a Peten Julio\n\n/*---Dificultad extra---*/\n//--Pila\nclass Pila {\n   constructor(pila) {\n           this.pila =[]\n   }\n   push(elemento){\n       return this.pila.push(elemento)\n   }\n   pop(){\n       if(this.size()===0){\n           return \"Cola vacia\";\n       }\n       return this.pila.pop();\n   }\n   size(){\n       return this.pila.length;\n   }\n   print(){\n       this.pila.forEach((element) => {\n           console.log(element);         \n       });\n   }  \n}\n\n\nlet mipila = new Pila();\nmipila.push(1);\nmipila.push(2);\nmipila.push(3);\nmipila.pop(); // 3\nmipila.pop(); // 2\nmipila.print();//1\n//mipila.size();\n\n\n//---Cola\nclass Cola {\n   constructor(cola) {\n           this.cola =[];\n   }\n   enqueue(elemento){\n       return this.cola.push(elemento);\n   }\n   dequeue(){\n       if(this.size()===0){\n           return \"Cola vacia\";\n       }\n       return this.cola.shift();\n   }\n   size(){\n       return this.cola.length;\n   }\n   print(){\n       this.cola.forEach((element) => {\n           console.log(element);         \n       });\n   }  \n}\n\nlet micola = new Cola();\nmicola.enqueue(1);\nmicola.enqueue(2);\nmicola.enqueue(3);\nmicola.dequeue(); // 1\nmicola.dequeue(); // 2\nmicola.print();//3\n//micola.size();\n\n"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/qwik-zgheib.js",
    "content": "/* -- exercise */\nclass Person {\n  constructor(name, age) {\n    this.name = name;\n    this.age = age;\n  }\n\n  printDetails() {\n    console.log(`Name: ${this.name}, Age: ${this.age}`);\n  }\n\n  setDetails(name, age) {\n    this.name = name;\n    this.age = age;\n  }\n}\n\nlet person = new Person(\"Abdul Rahman\", 22);\nperson.printDetails();\nperson.setDetails(\"Ahmed Khedr\", 20);\nperson.printDetails();\n\n/* -- extra challenge */\nclass Stack {\n  constructor() {\n    this.items = [];\n  }\n\n  push(element) {\n    this.items.push(element);\n  }\n\n  pop() {\n    if (this.isEmpty()) {\n      return \"Stack is empty\";\n    }\n    return this.items.pop();\n  }\n\n  size() {\n    return this.items.length;\n  }\n\n  print() {\n    console.log(\"Stack:\", this.items.toString());\n  }\n\n  isEmpty() {\n    return this.items.length === 0;\n  }\n}\n\nlet stack = new Stack();\nstack.push(10);\nstack.push(20);\nstack.push(30);\nstack.print();\nconsole.log(\"Popped:\", stack.pop());\nstack.print();\nconsole.log(\"Size:\", stack.size());\n\nclass Queue {\n  constructor() {\n    this.items = [];\n  }\n\n  enqueue(element) {\n    this.items.push(element);\n  }\n\n  dequeue() {\n    if (this.isEmpty()) {\n      return \"Queue is empty\";\n    }\n    return this.items.shift();\n  }\n\n  size() {\n    return this.items.length;\n  }\n\n  print() {\n    console.log(\"Queue:\", this.items.toString());\n  }\n\n  isEmpty() {\n    return this.items.length === 0;\n  }\n}\n\nlet queue = new Queue();\nqueue.enqueue(10);\nqueue.enqueue(20);\nqueue.enqueue(30);\nqueue.print();\nconsole.log(\"Dequeued:\", queue.dequeue());\nqueue.print();\nconsole.log(\"Size:\", queue.size());\n"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/raulG91.js",
    "content": "class MyClass{\n\n    constructor(value1,value2){\n\n        this.public_attibute = value1;\n        this._privateAttribute = value2;\n    }\n    get_private_attribute(){\n        return this._privateAttribute;\n    }\n    set_private_attribute(value){\n        this._privateAttribute = value;\n    }\n    get_public_attribute(){\n        return this.public_attibute;\n    }\n    set_public_attribute(value){\n        this.public_attibute = value;\n    }\n}\n\nlet my_object = new MyClass(2,3);\nconsole.log(\"Initial value private attribute \",my_object.get_private_attribute());\nconsole.log(\"Initial value public attribute \",my_object.get_public_attribute());\nmy_object.set_private_attribute(8);\nmy_object.set_public_attribute(19);\nconsole.log(\"Value private attribute \",my_object.get_private_attribute())\nconsole.log(\"Value public attribute \",my_object.get_public_attribute())\n\n//Extra exercise\n\nclass Stack{\n\n    constructor(){\n        this.array = [];\n    }\n    push(element){\n        this.array.push(element)\n    }\n    pop(){\n\n        if (this.array.length > 0){\n            this.array.pop();\n        }\n    }\n    count(){\n        return this.array.length;\n    }\n    print(){\n        console.log(this.array)\n    }\n\n}\n\nlet my_stack = new Stack();\nmy_stack.push(\"hi\");\nmy_stack.push(4);\nconsole.log(\"Number of elements\",my_stack.count());\nmy_stack.print()\nmy_stack.pop()\nconsole.log(\"Number of elements\",my_stack.count());\nmy_stack.print()\n\n\nclass myQueue{\n\n    constructor(){\n        this.array = []\n    }\n    push(element){\n\n        this.array.push(element);\n    }\n    pop(){\n\n        if(this.array.length > 0){\n            this.array.shift();\n        }\n    }\n    count(){\n        return this.array.length;\n    }\n    print(){\n        console.log(this.array);\n    }\n}\n\nlet my_queue = new myQueue();\nmy_queue.push(\"Hi!\")\nmy_queue.push(\"Bye\");\nconsole.log(\"Number of records: \",my_queue.count());\nmy_queue.print()\nmy_queue.pop()\nconsole.log(\"Number of records: \",my_queue.count());\nmy_queue.print()"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/rxvlc.js",
    "content": "// Definición de la clase MiClase\nclass MiClase {\n    // Constructor de la clase MiClase\n    constructor(nombre, edad) {\n        this.nombre = nombre;\n        this.edad = edad;\n    }\n\n    // Método para incrementar la edad\n    CumplirAnyos() {\n        this.edad++;\n    }\n\n    // Método para devolver información sobre la instancia de la clase\n    VerInfo() {\n        return `${this.nombre},${this.edad}`;\n    }\n\n    // Método toString para representación de cadena\n    toString() {\n        return `${this.nombre},${this.edad}`;\n    }\n}\n\n// Definición de la clase Pila\nclass Pila {\n    // Constructor de la clase Pila\n    constructor() {\n        this.elementos = [];\n    }\n\n    // Método para agregar un elemento a la pila\n    Push(elemento) {\n        this.elementos.push(elemento);\n    }\n\n    // Método para quitar y devolver el elemento superior de la pila\n    Pop() {\n        return this.elementos.pop();\n    }\n\n    // Método para obtener la cantidad de elementos en la pila\n    Count() {\n        return this.elementos.length;\n    }\n\n    // Método para imprimir el contenido de la pila\n    Imprimir() {\n        console.log(\"Contenido de la pila:\");\n        this.elementos.forEach(elemento => {\n            console.log(elemento);\n        });\n    }\n}\n\n// Definición de la clase Cola\nclass Cola {\n    // Constructor de la clase Cola\n    constructor() {\n        this.elementos = [];\n    }\n\n    // Método para agregar un elemento a la cola\n    Enqueue(elemento) {\n        this.elementos.push(elemento);\n    }\n\n    // Método para quitar y devolver el primer elemento de la cola\n    Dequeue() {\n        return this.elementos.shift();\n    }\n\n    // Método para obtener la cantidad de elementos en la cola\n    Count() {\n        return this.elementos.length;\n    }\n\n    // Método para imprimir el contenido de la cola\n    Imprimir() {\n        console.log(\"Contenido de la cola:\");\n        this.elementos.forEach(elemento => {\n            console.log(elemento);\n        });\n    }\n}\n\n// Creación de una instancia de la clase MiClase\nlet objeto = new MiClase(\"Juan\", 30);\nconsole.log(\"Valores iniciales:\");\nconsole.log(objeto.toString());\nobjeto.nombre = \"Pedro\";\nconsole.log(\"Valores modificados:\");\nconsole.log(objeto.toString());\n\n// Ejemplo de uso de la clase Pila\nlet pila = new Pila();\npila.Push(1);\npila.Push(2);\npila.Push(3);\npila.Imprimir();\nconsole.log(\"Número de elementos en la pila: \" + pila.Count());\npila.Pop();\npila.Imprimir();\nconsole.log(\"Número de elementos en la pila: \" + pila.Count());\n\n// Ejemplo de uso de la clase Cola\nlet cola = new Cola();\ncola.Enqueue(\"Uno\");\ncola.Enqueue(\"Dos\");\ncola.Enqueue(\"Tres\");\ncola.Imprimir();\nconsole.log(\"Número de elementos en la cola: \" + cola.Count());\ncola.Dequeue();\ncola.Imprimir();\nconsole.log(\"Número de elementos en la cola: \" + cola.Count());\n"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/saicobys.js",
    "content": "class Persona {\n  constructor(nombre, edad) {\n    this.nombre = nombre;\n    this.edad = edad;\n  }\n\n  imprimirInformacion() {\n    console.log(`Nombre: ${this.nombre}, Edad: ${this.edad}`);\n  }\n}\n\n// Crear un objeto de la clase Persona\nlet persona1 = new Persona(\"Ana\", 30);\n\n// Establecer y modificar atributos\npersona1.edad = 31; // Modificar la edad\n\n// Llamar al metodo para imprimir informacion\npersona1.imprimirInformacion();\n"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/seandsun.js",
    "content": "/*\n<-------------- Clases -------------->\nBásicamente una clase es una manera en la que podemos organizar o gestionar nustro código con el objetivo de simplificar\nel funcionamiento de nuestros programas y que nuestro código se pueda leer y entender de una mejor manera.\n*/\n\n// Declaración de una clase. La primera letra del nombre debe ir en mayúscula.\nclass Deporte {\n\n  // Constructor: solo puede haber uno, se encarga de inicializar o crear las propiedades que contiene en los objetos creados a partir de esta clase.\n  constructor(nombre) {       \n    this.nombre = nombre    // Propiedad sin definir (undefined), se recibirá su valor como parámetro al crear el objeto.\n    this.tipo = \"Acuático\"  // Propiedad definida, o sea que será igual para todos los objetos creados. Se puede moficar después.\n  }\n\n  // Métodos: son como funciones pero sin la palabra \"function\"\n  velocidad() {\n    return \"Va muy rápido.\"\n  }\n\n  print() {\n    return `${this.nombre} - ${this.tipo} - ${this.velocidad()}`\n  }\n} \n\n// Instanciar o crear un objeto de la clase Deporte, esto nos permitirá trabajar con sus propiedades y métodos\nconst nuevoDeporte = new Deporte(\"Natación\") // nuevoDeporte = {nombre: \"Natación\", tipo: \"Acuático\"}\nconsole.log(nuevoDeporte.print());           // 'Natación - Acuático - Va muy rápido.'\nnuevoDeporte.nombre = \"Paracaidismo\"         // Modifico el valor del atributo \"nombre\"\nnuevoDeporte.tipo = \"Aéreo\"                  // Modifico el valor del atributo \"tipo\"\nconsole.log(nuevoDeporte.print());           // 'Paracaidismo - Aéreo - Va muy rápido.' \n\n\n/*\n<-------------- Palabra clave: this -------------->\nEsta palabra clave se utiliza bastante dentro de las clases para hacer referencia al OBJETO INSTANCIADO, más no a la clase.\n*/\n\nclass Arbol {\n\n  constructor(nombre) {\n    this.nombre = nombre // \"this\" hace referencia al \"nombre\" del \"objeto instanciado\"\n    // nuevoArbol.nombre = \"cerezo\"    \n  }\n\n  /*\n  Fuera de la clase instanciamos el objeto \"nuevoArbol\" de la clase \"Arbol\", por lo tanto la palabra \"this\" haría\n  referencia a \"nuevoArbol\", en otras palabras \"this.nombre\" estaría haciendo referencia a \"nuevoArbol.nombre\"\n  */\n}\n\nconst nuevoArbol = new Arbol('cerezo')\nconsole.log(nuevoArbol.nombre); // cerezo \n\n\n// <-------------- Clase Pila -------------->\n// Last In, First Out\n\nclass Pila {\n\n  constructor() {\n    this.elementos = []\n  }\n\n  insertar = (elemento) => {\n    this.elementos.push(elemento)\n    return this.elementos\n  }\n\n  Eliminar = () => {\n    return this.elementos.pop()\n  }\n\n  largo = () => {\n    return this.elementos.length\n  }\n\n  imprimir = () => {\n    return this.elementos\n  }\n}\n\nconst pila = new Pila() \n\npila.insertar(\"Amarillo\")\npila.insertar(\"Azul\")\npila.insertar(\"Verde\")\nconsole.log(pila.largo()) // 3\nconsole.log(pila.imprimir()); // [ 'Amarillo', 'Azul', 'Verde' ]\npila.Eliminar()\npila.Eliminar()\npila.Eliminar()\nconsole.log(pila.imprimir()); //  []\n\n\n// <-------------- Clase Colas -------------->\n// First In, First Out\n\nclass Cola {\n  \n  constructor() {\n    this.elementos = []\n  }\n  \n  insertar = (elemento) => {\n    this.elementos.splice(0, 0, elemento)\n    return this.elementos\n  }\n\n  Eliminar = () => {\n    return this.elementos.pop()\n  }\n\n  largo = () => {\n    return this.elementos.length\n  }\n\n  imprimir = () => {\n    return this.elementos\n  }\n}\n\nconst cola = new Cola()\n\ncola.insertar(\"Amarillo\")\ncola.insertar(\"Azul\")\ncola.insertar(\"Verde\")\nconsole.log(cola.largo()) // 3\nconsole.log(cola.imprimir()); // [ 'Verde', 'Azul', 'Amarillo' ]\ncola.Eliminar()\ncola.Eliminar()\ncola.Eliminar()\nconsole.log(cola.imprimir()); // []"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/shevotool.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n */\n\nclass automovil {\n  constructor(marca, modelo, color) {\n    this.marca = marca;\n    this.modelo = modelo;\n    this.color = color;\n  }\n\n  imprimirAtributos() {\n    return `Marca:${this.marca} Modelo:${this.modelo} Color:${this.color}`;\n  }\n}\n\nconst ford = new automovil(\"Ford\", \"Focus\", \"Azul\");\nconst toyota = new automovil(\"Toyota\", \"Land Cruiser\", \"Blanco\");\n\nconsole.log(ford.imprimirAtributos());\nconsole.log(toyota.imprimirAtributos());\n\ntoyota.color = \"gris\";\nconsole.log(toyota.color);\nconsole.log(toyota);\n"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/victor-Casta.js",
    "content": "class Personaje {\n  constructor(nombre, poder) {\n    this.nombre = nombre;\n    this.poder = poder;\n  }\n\n  hablar() {\n    return `Soy ${this.nombre}`;\n  }\n\n  atacar() {\n    return this.poder;\n  }\n}\n\nconst batman = new Personaje('Batman', 'Lucha');\nconsole.log(batman.hablar());\nconsole.log(batman.atacar());\n\n/*\n  *Extra\n*/\n\nclass Pila {\n  constructor() {\n    this.items = [];\n  }\n\n  insert(element) {\n    this.items.push(element);\n  }\n\n  delete() {\n    return this.items.pop();\n  }\n\n  counter() {\n    return this.items.length;\n  }\n\n  getContent() {\n    this.items.forEach(item => console.log(item));\n  }\n}\n\nlet pila1 = new Pila();\n//----------- insertar elementos ----------\npila1.insert(1);\npila1.insert(2);\npila1.insert(3);\nconsole.log('Contenido de la pila:', pila1.items);\nconsole.log('-'.repeat(10));\n//----------- Eliminar elemento ----------\npila1.delete();\nconsole.log('Contenido de la pila después de eliminar:', pila1.items);\nconsole.log('-'.repeat(10));\n//----------- Cantidad de elementos ----------\nconsole.log('Cantidad de elementos en la pila:', pila1.counter());\nconsole.log('-'.repeat(10));\n//----------- Contenido ----------\nconsole.log('Contenido de la pila:');\npila1.getContent();\n\nclass Cola {\n  constructor() {\n    this.items = [];\n  }\n\n  insert(element) {\n    this.items.push(element);\n  }\n\n  delete() {\n    return this.items.splice(0, 1)[0];\n  }\n\n  counter() {\n    return this.items.length;\n  }\n\n  getContent() {\n    this.items.forEach(item => console.log(item));\n  }\n}\n\nconst cola1 = new Cola();\ncola1.insert('a');\ncola1.insert('b');\ncola1.insert('c');\ncola1.delete(); // Se eliminó 'a' de la cola\nconsole.log('Cantidad de elementos en la cola:', cola1.counter());\nconsole.log('Contenido de la cola:');\ncola1.getContent();\n"
  },
  {
    "path": "Roadmap/08 - CLASES/javascript/wapastorv.js",
    "content": "/*\nEJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (en javascript).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n*/\n/* ¿Que es una clase?\n    Una clase es un modelo que define un conjunto de atributos y métodos que tendrán los objetos que se creen a partir de ella.\n\n    Ejemplo:\n*/\nclass Persona{\n    constructor(nombre, edad, sexo) {\n        //Propiedades de la clase\n        // el this hace referencia al objeto que se está creando a partir de la clase, en este caso, Persona\n        // this.nombre, this.edad y this.sexo son atributos de la clase Persona\n        // nombre, edad y sexo son los parámetros que recibe el constructor\n        /* el metodo constructor es un método especial que se ejecuta automaticamente al crear una nueva instancia de la clase. \n        Se inicializan los atributos de la clase con los valores que se pasan como parámetros*/\n        this.nombre = nombre;\n        this.edad = edad;\n        this.sexo = sexo;\n    }\n    /*Método de la clase\n        Un método es una función que pertenece a un objeto, en este caso, a la clase Persona.\n        En este caso, el método saludar() imprime un mensaje con los atributos de la clase Persona\n    */\n    saludar(){\n        console.log(`Hola, mi nombre es ${this.nombre}, tengo ${this.edad} años y soy ${this.sexo}`);\n    }\n}\n\n//Creación de un objeto a partir de la clase Persona\nconst persona1 = new Persona('Juan', 30, 'Hombre');\npersona1.saludar(); //la salida será: Hola, mi nombre es Juan, tengo 30 años y soy Hombre\n\n// Modificación de los atributos del objeto persona1\npersona1.nombre = 'Maria';\npersona1.edad = 25;\npersona1.sexo = 'Mujer';\npersona1.saludar(); //la salida será: Hola, mi nombre es Maria, tengo 25 años y soy Mujer\n\n//Creación de un nuevo objeto a partir de la clase Persona\nconst persona2 = new Persona('Pedro', 40, 'Hombre');\npersona2.saludar(); //la salida será: Hola, mi nombre es Pedro, tengo 40 años y soy Hombre\n\n/* Herencia en clases:\n    La herencia es un mecanismo que permite que una clase (clase hija) herede los atributos y métodos de otra clase (clase padre).\n    En javascript, la herencia se logra utilizando la palabra clave extends.\n    Ejemplo:\n*/\nclass Empleado extends Persona{\n    constructor(nombre, edad, sexo, salario){\n        //El método super() se utiliza para llamar al constructor de la clase padre (Persona)\n        super(nombre, edad, sexo);\n        this.salario = salario;\n    }\n    //Método de la clase Empleado\n    mostrarSalario(){\n        console.log(`Mi salario es de ${this.salario}`);\n    }\n}\n\n//Creación de un objeto a partir de la clase Empleado\nconst empleado1 = new Empleado('Carlos', 35, 'Hombre', 2000);\nempleado1.saludar(); //la salida será: Hola, mi nombre es Carlos, tengo 35 años y soy Hombre\nempleado1.mostrarSalario(); //la salida será: Mi salario es de 2000\n\n/* Método Estático: \n    Un método estático es un método que pertenece a la clase en lugar de a los objetos creados a partir de ella.\n    Para definir un método estático, se utiliza la palabra clave static.\n    Ejemplo:\n*/\nclass Calculadora{\n    //Método estático de la clase Calculadora\n    static sumar(a, b){\n        return a + b;\n    }\n    static restar(a, b){\n        return a - b;\n    }\n    static multiplicar(a, b){\n        return a * b;\n    }\n}\nconsole.log(Calculadora.sumar(5, 3)); //la salida será: 8\nconsole.log(Calculadora.restar(5, 3)); //la salida será: 2\nconsole.log(Calculadora.multiplicar(5, 3)); //la salida será: 15\n\n/* Getter y Setter:\n    Los métodos getter y setter son métodos especiales que se utilizan para obtener y establecer el valor de un atributo de un objeto.\n    Para definir un getter o un setter, se utiliza la palabra clave get o set, respectivamente.\n    Ejemplo:\n\n*/\nclass Rectangulo{\n    constructor(base, altura){\n        this.base = base;\n        this.altura = altura;\n    }\n    //Getter para obtener el área del rectángulo\n    get area(){\n        return this.base * this.altura;\n    }\n    //Setter para establecer la base del rectángulo\n    set nuevaBase(base){\n        this.base = base;\n    }\n    //Setter para establecer la altura del rectángulo\n    set nuevaAltura(altura){\n        this.altura = altura;\n    }\n}\n\nconst rectangulo = new Rectangulo(5, 3);\nconsole.log(rectangulo.area); //la salida será: 15\nrectangulo.nuevaBase = 10;\nrectangulo.nuevaAltura = 6;\nconsole.log(rectangulo.area); //la salida será: 60\n\n/* Encapsulamiento \n    El encapsulamiento es un concepto que se refiere a la ocultación de los detalles de implementación de un objeto y la exposición de una interfaz para interactuar con él.\n    En javascript, el encapsulamiento se logra utilizando métodos getter y setter para acceder a los atributos de un objeto.\n    Ejemplo:\n \n*/\nclass Banco {\n    #saldo; //Atributo privado\n    constructor(saldoInicial){\n        this.#saldo = saldoInicial;\n    }\n    depositar(monto){\n        this.#saldo += monto;\n        console.log(`Se depositaron ${monto} dólares. Saldo actual: ${this.#saldo} dólares`);\n    }\n\n    retirar(monto){\n        if(monto <= this.#saldo){\n            this.#saldo -= monto;\n            console.log(`Se retiraron ${monto} dólares. Saldo actual: ${this.#saldo} dólares`);\n        } else {\n            console.log('Fondos insuficientes');\n        }\n    }\n}\n\nconst cuenta = new Banco(1000);\ncuenta.depositar(500); //la salida será: Se depositaron 500 dólares. Saldo actual: 1500 dólares\ncuenta.retirar(200); //la salida será: Se retiraron 200 dólares. Saldo actual: 1300 dólares\ncuenta.retirar(1500); //la salida será: Fondos insuficientes\n\n/* Polimorfismo:\n    El polimorfismo permie que un objeto pueda comportarse de diferentes maneras según el contexto en el que se encuentre.\n    En javascript, el polimorfismo se logra al redefinir un método en una clase hija.\n    Ejemplo:\n*/\nclass Figyra{\n    calcularArea(){\n        return 0; //Método a ser redefinido en las clases hijas\n    }\n}\nclass Cuadrado extends Figyra{\n    constructor(lado){\n        super();\n        this.lado = lado;\n    }\n    calcularArea(){\n        return this.lado * this.lado;\n    }\n}\nclass Circulo extends Figyra{\n    constructor(radio){\n        super();\n        this.radio = radio;\n    }\n    calcularArea(){\n        return Math.PI * this.radio * this.radio;\n    }\n}\nconst cuadrado = new Cuadrado(5);\nconsole.log(`El Area del cuadrado es: ${cuadrado.calcularArea()}`); //la salida será: 25\n\nconst circulo = new Circulo(3);\nconsole.log(`El Area del Circulo es: ${circulo.calcularArea()}`); //la salida será: 28.274333882308138\n\n"
  },
  {
    "path": "Roadmap/08 - CLASES/kotlin/VincentRodriguezR.kt",
    "content": "import java.util.ArrayDeque\n\nclass estudiante(val nombre: String, var edad: Int, val ciudad: String) {\n    //Se definen parametros opcionales dentro de la clase\n    var carrera:String = \"\"\n    //Funcion de comportamiento del objeto\n    fun show(){\n        println(\"el estudiante se llama $nombre tiene $edad años y vive en la ciudad de $ciudad y estudia la carrera de $carrera\")\n    }\n}\n\nfun main(){\n\n    //Se construye el objeto dando como paarametros los datos requeridos por la clase, algo muy similar a las funciones\n    var estudianteNuevo = estudiante(\"Santiago\", 24, \"Bogota\")\n    //Se llama un comportamiento del objeto\n    estudianteNuevo.show()\n    //Se puede interactuar con las variables definidas dentro de la clase\n    estudianteNuevo.carrera = \"Programacion\"\n    estudianteNuevo.show()\n    //Se pueden editar tanto como los parametros ingresados como las variables de la clase siempre y cuando estendefinidas como variables y no como valores (definidas como var)\n    estudianteNuevo.edad = 25\n    estudianteNuevo.show()\n    //No se pueden modificar las variables creadas en una funcion ya estas son exclusivas de cada una, si se necesita tener una variable que se deba editar debe estar definida al nivel de la clase\n\n    //Ejecuciones ejercicio extra\n\n    //Stack\n    //Stack Definition\n    var tempStack = ArrayDeque<String>()\n    tempStack.add(\"Esto es\")\n    tempStack.add(\"un\")\n    tempStack.add(\"Stack\")\n\n    //Build stack object\n    var buildStack = stack(tempStack)\n\n    //Add in stack\n    buildStack.addStack(\"Esta es una adicion en la pila\")\n\n    //Erase in stack\n    buildStack.deleteStack()\n\n    //Show all stack items\n    buildStack.showAllStack()\n\n    //Show stack size\n    buildStack.showSizeStack()\n\n    //Queue\n    //Queue definition\n    var tempQueue = ArrayDeque<String>()\n    tempQueue.add(\"Esto es\")\n    tempQueue.add(\"una\")\n    tempQueue.add(\"cola\")\n\n    //Build queue object\n    var buildQueue = queue(tempQueue)\n\n    //Add in queue\n    buildQueue.addQueue(\"Esta es una adicion en la cola\")\n\n    //Erase in queue\n    buildQueue.deleteQueue()\n\n    //Show all queue items\n    buildQueue.showAllQueue()\n\n    //Show queue size\n    buildQueue.showSizeQueue()\n\n\n\n}\n\n//Ejercicio extra\n//Stack\nclass stack(var stackItems: ArrayDeque<String>){\n\n    fun addStack(item: String){\n        stackItems.push(item)\n        println(\"Se ha agregado el item $item a la pila\")\n    }\n\n    fun deleteStack(){\n        val erasedItem = stackItems.pop()\n        println(\"Se ha eliminado el ultimo elemento ingresado de la pila: $erasedItem\")\n    }\n\n    fun showAllStack(){\n        println(\"A continuacion se mostraran todos los datos de la pila\")\n        stackItems.forEachIndexed{index, value -> println(\"${index+1}. $value\")}\n    }\n\n    fun showSizeStack(){\n        println(\"La pila contiene un total de ${stackItems.size} registros\")\n    }\n}\n\n//Queue\nclass queue(var queueItems: ArrayDeque<String>){\n\n    fun addQueue(item: String){\n        queueItems.offer(item)\n        println(\"Se ha agregado el item $item a la cola\")\n    }\n\n    fun deleteQueue(){\n        val erasedItem = queueItems.poll()\n        println(\"Se ha eliminado el primer elemento ingresado de la cola: $erasedItem\")\n    }\n\n    fun showAllQueue(){\n        println(\"A continuacion se mostraran todos los datos de la cola\")\n        queueItems.forEachIndexed{index, value -> println(\"${index+1}. $value\")}\n    }\n\n    fun showSizeQueue(){\n        println(\"La pila contiene un total de ${queueItems.size} registros\")\n    }\n}"
  },
  {
    "path": "Roadmap/08 - CLASES/kotlin/adridoce.kt",
    "content": "/* EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n */\n\n\nfun main() {\n\n    val yo = Alumno(\"Adrian\", 29, true)\n    yo.verDatos()\n\n    yo.edad = 30\n    yo.aprobado = false\n\n    yo.verDatos()\n\n    val stack = Stack<Int>()\n    println(\"Creando pila...\")\n    stack.push(3)\n    stack.push(5)\n    stack.push(7)\n    stack.printStack()\n    println(\"Tamaño: ${stack.size()}\")\n    println(\"Eliminado: ${stack.pop()}\")\n    stack.printStack()\n\n    val queue = Queue<String>()\n    println(\"Creando cola...\")\n    queue.push(\"Perro\")\n    queue.push(\"Gato\")\n    queue.push(\"Mono\")\n    queue.printQueue()\n    println(\"Tamaño: ${queue.size()}\")\n    println(\"Eliminado: ${queue.pop()}\")\n    queue.printQueue()\n\n}\n\nclass Alumno(\n    val nombre: String,\n    var edad: Int,\n    var aprobado: Boolean\n) {\n    init {\n        println(\"Alumno $nombre creado\")\n    }\n\n    fun verDatos() {\n        println(\"Nombre: $nombre\")\n        println(\"Edad: $edad\")\n        println(\"Aprobado: ${if (aprobado) \"Si\" else \"No\"}\")\n    }\n}\n\n/* DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n */\nclass Queue<T> {\n    private val queue = ArrayDeque<T>()\n\n    fun push(element: T){\n        queue.addLast(element)\n    }\n\n    fun pop(): T?{\n        return queue.removeFirstOrNull()\n    }\n\n    fun size(): Int {\n        return queue.size\n    }\n\n    fun printQueue(){\n        println(queue)\n    }\n}\n\nclass Stack<T> {\n    private val stack = ArrayDeque<T>()\n\n    fun push(element: T){\n        stack.addLast(element)\n    }\n\n    fun pop(): T? {\n        return stack.removeLastOrNull()\n    }\n\n    fun size(): Int {\n        return stack.size\n    }\n\n    fun printStack(){\n        println(stack)\n    }\n}\n\n"
  },
  {
    "path": "Roadmap/08 - CLASES/kotlin/blackriper.kt",
    "content": "import java.util.*\r\n\r\n/*\r\n  una clase es una estructura  que nos sirve para reprentar objectos del mundo real\r\n  la clase es tratada como un molde para crear objetos y a la vez representa un nuevo tipo de dato.\r\n\r\n  las clases contienen los siguientes elementos :\r\n  - atributos (variables)\r\n  - metodos (funciones)\r\n  - constructor (una funcion que se ejecuta cuando se crea una instancia de una clase es la encargada de construir el objeto)\r\n  - propiedades (propiedades generedas con la interacion de atributos y metodos)\r\n  - metodos estaticos (metodos que no requieren de una instancia de la clase y estos no influyen en el comportamiento del objeto)\r\n\r\n  mas informacion en https://kotlinlang.org/docs/classes.html#constructors\r\n\r\n */\r\n\r\n// ejemplo de clase  una clase se crea con una palabra clave class\r\n// en kotlin los valores que estan dentro de los parestesis son los atributos de la clase\r\n//los parentesis despues del nombre de la clase representan el constructor\r\nclass Person(var name: String, var age: Int){\r\n\r\n    fun greet() {\r\n        println(\"Hello, my name is $name and I am $age years old\")\r\n    }\r\n}\r\n\r\n// en kotlin tambien se puede crear una clase con un constructor secuandario\r\nclass Animal{\r\n    val name: String\r\n    val specie: String\r\n    constructor(name: String, specie:String){\r\n        this.name = name\r\n        this.specie = specie\r\n    }\r\n\r\n   fun fly() {\r\n        println(\"$name is a $specie and is flying\")\r\n    }\r\n}\r\n\r\n// los atributos de una clase  se puede limitar su visibilidad con el modificador de acceso public, private o protected\r\n// por defecto los atributos de una clase son publicos asi que no es necesario especificar el modificador\r\n// kotlin cuenta con un  modificador que agrega funcionalidades a nuestras clases  solo tenemos que agregarle el modificador data antes de la palabra class\r\ndata class Hokage(private val name: String, private val numberHokage: Int){\r\n    fun hokageData() {\r\n        println(\"My name is $name and iam the $numberHokage hokage\")\r\n    }\r\n}\r\n\r\n// ejercicio extra\r\nclass QueuePrinter(private val docs: List<String>){\r\n   // atributos  de uso interno\r\n   private val printerQueue: Queue<String> = LinkedList<String>()\r\n   private var option:String=\"\"\r\n\r\n   // use inicializer blocks para agregar la lista a la cola\r\n   init {\r\n       this.printerQueue.addAll(docs)\r\n   }\r\n   private fun addDocument(){\r\n        println(\"What document do you want to add?\")\r\n        val name= readLine()!!.toString()\r\n        printerQueue.add(name)\r\n        println(\"The document $name was added to the printer queue\")\r\n    }\r\n\r\n   private fun printDocument(){\r\n        val printerDoc= printerQueue.remove()\r\n        println(\"The document $printerDoc was printed\")\r\n        println(\"the queue is $printerQueue\")\r\n    }\r\n\r\n    fun sharedPrinter(){\r\n        do {\r\n            println(\"What do you want to do Add or Print or Exit ?\")\r\n            option= readLine()!!.toString().lowercase()\r\n            when(option){\r\n                \"add\" -> this.addDocument()\r\n                \"print\" -> this.printDocument()\r\n            }\r\n        } while (option != \"exit\")\r\n    }\r\n\r\n}\r\n\r\nclass WebNavigator{\r\n    private val back = Stack<String>()\r\n    private  val forward = Stack<String>()\r\n\r\n    fun navigate(webPage:String){\r\n        if (back.isEmpty()){\r\n            forward.push(webPage)\r\n            println(\"Navigate to $webPage\")\r\n        }\r\n    }\r\n\r\n    fun goBack():String{\r\n        if (back.size>1){\r\n            forward.push(back.pop())\r\n            return \"Go back to ${back.peek()}\"\r\n        }else{\r\n            return \"Can't go back\"\r\n        }\r\n    }\r\n\r\n    fun goForward():String{\r\n        if (forward.isNotEmpty()){\r\n            back.push(forward.pop())\r\n            return \"Go forward to ${forward.peek()}\"\r\n        }else{\r\n            return \"Can't go forward\"\r\n        }\r\n    }\r\n\r\n}\r\n\r\n\r\n\r\n\r\nfun main() {\r\n    // creando una instancia de la clase  la variable person es un objeto de la clase Person\r\n    val person = Person(\"John\", 25)\r\n    person.greet()\r\n    // modificando atributos de la instancia solo se puede hacer si este atributo es var\r\n    person.age=29\r\n    println(person)\r\n    val bird = Animal(\"condor\", \"bird\")\r\n    bird.fly()\r\n    // al tener atributos publicos estos son accesibles desde nuestra instancia bird\r\n    println(bird.name)\r\n\r\n    val secondHokage=Hokage(\"Tobirama Senju\", 2)\r\n    secondHokage.hokageData()\r\n    //secondHokage.name  genera un error por el modificador privado\r\n\r\n    val queuePrinter=QueuePrinter(listOf(\"doc1\",\"doc2\",\"doc3\"))\r\n    queuePrinter.sharedPrinter()\r\n\r\n    val webNavigator=WebNavigator()\r\n    webNavigator.navigate(\"https://www.google.com\")\r\n    webNavigator.navigate(\"https://www.stackoverflow.com\")\r\n    webNavigator.navigate(\"https://www.github.com\")\r\n    println(webNavigator.goBack())\r\n    println(webNavigator.goBack())\r\n    println(webNavigator.goForward())\r\n\r\n}\r\n\r\n"
  },
  {
    "path": "Roadmap/08 - CLASES/kotlin/didacdev.kt",
    "content": "fun main() {\n    var queue = Queue<Int>()\n    var stack = Stack<Int>()\n\n    queue.enqueue(1)\n    queue.enqueue(2)\n    queue.enqueue(3)\n    queue.enqueue(4)\n    queue.enqueue(5)\n    queue.printQueue()\n    println(queue.size())\n    println(queue.get())\n    println(queue.dequeue())\n    queue.printQueue()\n    println(queue.size())\n\n    stack.push(1)\n    stack.push(2)\n    stack.push(3)\n    stack.push(4)\n    stack.push(5)\n    stack.printStack()\n    println(stack.size())\n    println(stack.get())\n    println(stack.pop())\n    stack.printStack()\n    println(stack.size())\n}\n\nclass Stack<T>(initialStack: List<T> = emptyList()) {\n\n    private var stack: MutableList<T> = initialStack.toMutableList()\n\n    fun push(e: T) {\n        stack.add(0, e)\n    }\n\n    fun get(): T? {\n        return this.stack.firstOrNull()\n    }\n\n    fun pop(): T? {\n        return if (stack.isNotEmpty()) {\n            stack.removeFirst()\n        } else {\n            null\n        }\n    }\n\n    fun clear() {\n        stack.clear()\n    }\n\n    fun size(): Int {\n        return stack.size\n    }\n\n    fun printStack() {\n        println(stack)\n    }\n}\n\nclass Queue<T>(initialQueue: List<T> = emptyList()) {\n\n    private var queue: MutableList<T> = initialQueue.toMutableList()\n\n    fun enqueue(e: T) {\n        queue.addLast(e)\n    }\n\n    fun get(): T? {\n        return this.queue.firstOrNull()\n    }\n\n    fun dequeue(): T? {\n        return if (queue.isNotEmpty()) {\n            queue.removeFirst()\n        } else {\n            null\n        }\n    }\n\n    fun clear() {\n        queue.clear()\n    }\n\n    fun size(): Int {\n        return queue.size\n    }\n\n    fun printQueue() {\n        println(queue)\n    }\n}"
  },
  {
    "path": "Roadmap/08 - CLASES/kotlin/eulogioep.kt",
    "content": "// Clase principal para demostrar el concepto de clase\nclass Persona(var nombre: String, var edad: Int) {\n    // Inicializador\n    init {\n        println(\"Se ha creado una nueva Persona: $nombre\")\n    }\n\n    // Función para imprimir los atributos\n    fun imprimirDatos() {\n        println(\"Nombre: $nombre, Edad: $edad\")\n    }\n}\n\n// Implementación de una Pila (Stack - LIFO)\nclass Pila<T> {\n    private val elementos = mutableListOf<T>()\n\n    fun agregar(elemento: T) {\n        elementos.add(elemento)\n    }\n\n    fun eliminar(): T? {\n        if (estaVacia()) return null\n        return elementos.removeAt(elementos.size - 1)\n    }\n\n    fun numeroElementos(): Int = elementos.size\n\n    fun estaVacia(): Boolean = elementos.isEmpty()\n\n    fun imprimir() {\n        println(\"Contenido de la Pila:\")\n        for (i in elementos.size - 1 downTo 0) {\n            println(elementos[i])\n        }\n    }\n}\n\n// Implementación de una Cola (Queue - FIFO)\nclass Cola<T> {\n    private val elementos = mutableListOf<T>()\n\n    fun agregar(elemento: T) {\n        elementos.add(elemento)\n    }\n\n    fun eliminar(): T? {\n        if (estaVacia()) return null\n        return elementos.removeAt(0)\n    }\n\n    fun numeroElementos(): Int = elementos.size\n\n    fun estaVacia(): Boolean = elementos.isEmpty()\n\n    fun imprimir() {\n        println(\"Contenido de la Cola:\")\n        elementos.forEach { println(it) }\n    }\n}\n\nfun main() {\n    // Demostración de la clase Persona\n    println(\"--- Demostración de la clase Persona ---\")\n    val persona = Persona(\"Alice\", 30)\n    persona.imprimirDatos()\n    \n    persona.edad = 31\n    persona.nombre = \"Alicia\"\n    persona.imprimirDatos()\n\n    // Demostración de la Pila\n    println(\"\\n--- Demostración de la Pila ---\")\n    val pila = Pila<String>()\n    pila.agregar(\"Primero\")\n    pila.agregar(\"Segundo\")\n    pila.agregar(\"Tercero\")\n    \n    println(\"Número de elementos en la pila: ${pila.numeroElementos()}\")\n    pila.imprimir()\n    \n    println(\"Elemento eliminado: ${pila.eliminar()}\")\n    println(\"Nuevo número de elementos: ${pila.numeroElementos()}\")\n    pila.imprimir()\n\n    // Demostración de la Cola\n    println(\"\\n--- Demostración de la Cola ---\")\n    val cola = Cola<Int>()\n    cola.agregar(1)\n    cola.agregar(2)\n    cola.agregar(3)\n    \n    println(\"Número de elementos en la cola: ${cola.numeroElementos()}\")\n    cola.imprimir()\n    \n    println(\"Elemento eliminado: ${cola.eliminar()}\")\n    println(\"Nuevo número de elementos: ${cola.numeroElementos()}\")\n    cola.imprimir()\n}"
  },
  {
    "path": "Roadmap/08 - CLASES/kotlin/juanppdev.kt",
    "content": "/*\nEJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n*/\n\n// Definición de la clase\nclass Persona(var nombre: String, var edad: Int) {\n    // Inicializador\n    init {\n        println(\"Se ha creado una persona llamada $nombre, de $edad años.\")\n    }\n\n    // Función para imprimir los atributos\n    fun imprimirDatos() {\n        println(\"Nombre: $nombre, Edad: $edad\")\n    }\n}\n\n// Creación de un objeto de la clase\nval persona1 = Persona(\"Juan\", 25)\n\n// Modificación de los atributos\npersona1.nombre = \"Juan Carlos\"\npersona1.edad = 30\n\n// Impresión de los atributos\npersona1.imprimirDatos()\n\n\n/*\nDIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n*/\n\n// Clase Pila\nclass Pila<T> {\n    private var elementos: MutableList<T> = mutableListOf()\n\n    // Función para añadir un elemento\n    fun agregar(elemento: T) {\n        elementos.add(elemento)\n    }\n\n    // Función para eliminar y retornar el último elemento\n    fun eliminar(): T? {\n        return if (elementos.isEmpty()) {\n            null\n        } else {\n            elementos.removeAt(elementos.size - 1)\n        }\n    }\n\n    // Función para retornar el número de elementos\n    fun tamaño(): Int {\n        return elementos.size\n    }\n\n    // Función para imprimir todos los elementos\n    fun imprimir() {\n        println(\"Pila: $elementos\")\n    }\n}\n\n// Clase Cola\nclass Cola<T> {\n    private var elementos: MutableList<T> = mutableListOf()\n\n    // Función para añadir un elemento\n    fun agregar(elemento: T) {\n        elementos.add(elemento)\n    }\n\n    // Función para eliminar y retornar el primer elemento\n    fun eliminar(): T? {\n        return if (elementos.isEmpty()) {\n            null\n        } else {\n            elementos.removeAt(0)\n        }\n    }\n\n    // Función para retornar el número de elementos\n    fun tamaño(): Int {\n        return elementos.size\n    }\n\n    // Función para imprimir todos los elementos\n    fun imprimir() {\n        println(\"Cola: $elementos\")\n    }\n}\n\n// Creación de objetos de las clases\nval pila1 = Pila<Int>()\nval cola1 = Cola<Int>()\n\n// Añadir elementos a las estructuras\npila1.agregar(1)\npila1.agregar(2)\npila1.agregar(3)\n\ncola1.agregar(1)\ncola1.agregar(2)\ncola1.agregar(3)\n\n// Imprimir elementos\npila1.imprimir()\ncola1.imprimir()"
  },
  {
    "path": "Roadmap/08 - CLASES/kotlin/pedroomar23.kt",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n * \n */\n\nclass Test(var name: String, var name1: String) {\n    init {\n        name = \"Test 1\"\n        name1 = \"Test 2\"\n    }\n\n    fun printDates(): String {\n        return \"Name: $name, Name1: $name1\"\n    }\n}\n\nval test = Test(\"Test 1\", \"Test2\")\ntest.name = \"Test3\"\ntest.name1 = \"Test4\"\n\nprint(test.printDates())"
  },
  {
    "path": "Roadmap/08 - CLASES/kotlin/rikmij.kt",
    "content": "class Tablet(private val model: String, private val color: String,\n             private val screen: Float, private val ram: String) {\n\n    private val brand = \"Lenovo\"\n\n    fun presentarse(): String{\n        return \"$brand $model: color $color, pantalla $screen\\\", RAM $ram\"\n    }\n}\n\n\nclass MyQueue<E>(private val cola: ArrayList<E>) {\n    \n    fun addComponent(vararg elem: E){\n        for (e in elem){\n            cola.addLast(e)\n        }\n    }\n\n    fun removeComponent(){\n        cola.removeFirst()\n    }\n\n    fun peekComponent(): E{\n        return cola.first()\n    }\n\n    fun printQueue(): ArrayList<E>{\n        return cola\n    }\n}\n\n\nclass MyStack<E>(private val pila: ArrayList<E>) {\n\n    fun addComponent(vararg elem: E){\n        for (e in elem){\n            pila.addLast(e)\n        }\n    }\n\n    fun removeComponent(){\n        pila.removeLast()\n    }\n\n    fun peekComponent(): E{\n        return pila.last()\n    }\n\n    fun printStack(): ArrayList<E>{\n        return pila\n    }\n}\n\n\nfun main() {\n    val tablet1 = Tablet(\"Tab M10\", \"Gris\", 10.6f, \"4GB\")\n    val tablet2 = Tablet(\"Tab P12\", \"Gris\", 12.7f, \"8GB\")\n    val tablet3 = Tablet(\"Tab K10\", \"Azul\", 10.3f, \"4GB\")\n\n    println(tablet1.presentarse())\n    println(tablet2.presentarse())\n    println(tablet3.presentarse())\n\n\n    println(\"${\"\\n\"+\"~\".repeat(7)} EJERCICIO EXTRA ${\"~\".repeat(7)}\")\n    println(\"-> QUEUES\")\n    val colaList = ArrayList<String>()\n    val queue = MyQueue(colaList)\n\n    queue.addComponent(\"Uno\")\n    queue.addComponent(\"Dos\", \"Tres\")\n    queue.addComponent(\"Cuatro\", \"Cinco\", \"Seis\")\n    println(queue.printQueue())\n\n    queue.removeComponent()\n    println(queue.printQueue())\n\n    println(queue.peekComponent())\n\n    println(\"-> STACKS\")\n    val pilaList = ArrayList<Int>()\n    val stack = MyStack(pilaList)\n\n    stack.addComponent(1, 2, 3)\n    stack.addComponent(4, 5)\n    println(stack.printStack())\n\n    stack.removeComponent()\n    println(stack.printStack())\n\n    println(stack.peekComponent())\n}\n"
  },
  {
    "path": "Roadmap/08 - CLASES/kotlin/thegera4.kt",
    "content": " fun main (){\n    // Creación de un objeto de la clase Car\n    val car1 = Car(\"Toyota\", \"Corolla\", 2020)\n    // Impresión de los atributos del objeto\n    car1.printCar()\n    // Impresión de la cantidad de autos creados\n    car1.printCount()\n\n    val car2 = Car(\"Ford\", \"Fiesta\", 2019)\n    car2.printCar()\n    car2.printCount()\n\n    // Extra: Creación de un objeto de la clase Pila\n    val pila = Pila<String>() // Inicializa un objeto de la clase Pila con tipo de dato String\n    pila.push(\"Elemento 1\") // Añade un elemento a la pila\n    pila.push(\"Elemento 2\")\n    pila.push(\"Elemento 3\")\n    pila.printPila() // Imprime el contenido de la pila\n    pila.pop() // Elimina el último elemento\n    pila.printPila()\n    println(\"Número de elementos: ${pila.size()}\") // Imprime el número de elementos\n\n    // Extra: Creación de un objeto de la clase Cola\n    val cola = Cola<Int>() // Inicializa un objeto de la clase Cola con tipo de dato Int\n    cola.add(1) // Añade un elemento a la cola\n    cola.add(2)\n    cola.add(3)\n    cola.printCola() // Imprime el contenido de la cola\n    cola.remove() // Elimina el primer elemento\n    cola.printCola()\n    println(\"Número de elementos: ${cola.size()}\") // Imprime el número de elementos\n\n }\n\n // Clase de ejemplo con inicializador, atributos y función.\n // Una clase en kotlin tiene un constructor primario y puede tener uno o más constructores secundarios.\n // El constructor primario es parte de la declaración de la clase y se encuentra después del nombre de la clase.\n // Si el constructor primario no tiene anotaciones o modificadores, la palabra constructor puede omitirse.\n class Car /*constructor*/ (val brand: String, val model: String, val year: Int) {\n    // Los atributos de la clase son brand, model y year\n\n    // Atributo para contar la cantidad de autos creados, es parte de la clase, por lo que es compartido por todos las instancias\n    companion object {\n        var count = 0\n    }\n\n    // Si quieres ejecutar código al momento de la creación del objeto, puedes hacerlo en el bloque init\n    init {\n        println(\"Car created\")\n        count++\n    }\n\n    // Función que imprime los atributos del objeto\n    fun printCar(){\n        println(\"Car: $brand $model $year\")\n    }\n\n    // Función que imprime la cantidad de autos creados\n    fun printCount(){\n        println(\"Cars created: $count\")\n    }\n }\n\n // Extra: Clase Pila\nclass Pila<T> { // T es un tipo genérico, es decir, puede ser cualquier tipo de dato\n    // Atributo privado que almacena los elementos de la pila. Un atributo privado es accesible solo dentro de la clase que lo declara\n    private val pila = mutableListOf<T>()\n    \n    // Función que añade un elemento a la pila\n    fun push(element: T){\n        pila.add(element)\n    }\n    \n    // Función que elimina el último elemento de la pila\n    fun pop(){\n        pila.removeAt(pila.size - 1)\n    }\n    \n    // Función que retorna el número de elementos de la pila\n    fun size(): Int{\n        return pila.size\n    }\n    \n    // Función que imprime el contenido de la pila\n    fun printPila(){\n        println(\"Contenido de la Pila: $pila\")\n    }\n}\n\n//Extra: Clase Cola\nclass Cola<T> {\n    private val cola = mutableListOf<T>()\n    \n    fun add(element: T){\n        cola.add(element)\n    }\n    \n    fun remove(){\n        cola.removeAt(0)\n    }\n    \n    fun size(): Int{\n        return cola.size\n    }\n    \n    fun printCola(){\n        println(\"Contenido de la Cola: $cola\")\n    }\n}"
  },
  {
    "path": "Roadmap/08 - CLASES/ocaml/luishendrix92.ml",
    "content": "open Printf\n\n(*/------------------------------------------------------------------------\\\n  |                                                                        |\n  |                          Objects and Classes                           |\n  |                                                                        |\n  |  As a functional programming language, OCaml's main focus is to make   |\n  |  use of immutable data and functions as much as possible without       |\n  |  reaching the strictly pure levels of Haskell where mutations and      |\n  |  side-effects are disallowed in favour of composing IO operations      |\n  |  through monads and syntactic sugar with the [do] block. OCaml is a    |\n  |  bit more flexible and as I already explored a few exercises ago,      |\n  |  the user is more than free (and sometimes encouraged) to write        |\n  |  records with mutable fields, references, perform unsafe IO, throw     |\n  |  exceptions and even make use of imperative [while] and [for] loops.   |\n  |                                                                        |\n  |  To my surprise, the language does provide syntactic aid to harness    |\n  |  the most used concepts of Object-Oriented Programming: classes,       |\n  |  interfaces, virtuals, objects, public and private methods, proper-    |\n  |  ties, inheritance, initialization, and instanciation. Sure it may     |\n  |  not offer the whole scope of OOP but what we can use is more than     |\n  |  enough to satisfy our object-oriented needs.                          |\n  |                                                                        |\n  |  If you are curious about what is available in terms of OOP, you can   |\n  |  check the official manual with complete information about it:         |\n  |  https://v2.ocaml.org/manual/objectexamples.html                       |\n  |                                                                        |\n  \\------------------------------------------------------------------------/*)\n\nclass animal (name : string) (age : int) (species : string) =\n  (* Unlike in OOP languages, we do not always need to specify the [self]\n     binding unless we need to call instance methods within the object's\n     definition. This reference can't espace the class, for example, to\n     store it in an outside container from within. It needs to be done\n     from the outside, there might be workarounds but I don't know yet. *)\n  object (self : 'a)\n    (* There is no way to mutate properties from the outside, it has to be done\n       from the inside and expose methods such as getters and setters. *)\n    val mutable name = name\n    val mutable age = age\n    val mutable love = 0\n\n    (* An animal can never change species, therefore this property can just\n       be non-mutable, which in terms of OOP languages could be similar to\n       [final], [const], and other similar keywords. *)\n    val species = species\n\n    (* Methods can be private like in OOP languages *)\n    method private increase_love =\n      let new_love = love + 1 in\n      love <- (if new_love > 100 then 100 else new_love)\n\n    (* The OCaml way of doing getters and setters. *)\n    method get_name = name\n    method set_name name' = name <- name'\n    method get_age = age\n    method set_age age' = age <- age'\n\n    method pet =\n      self#increase_love;\n      printf \"%s was petted, its love for you is now Lv.%d!\\n\" name love\n\n    method greet =\n      printf \"Hello, my name is %s, I'm a %s of age %d!\\n\" name species age\n\n    (* In the OCaml Manual, they call methods that accept other objects of the\n       same type [binary methods] and they require you to add a type hint to\n       the [self] reference (line 36) and use it to annotate the parameter. *)\n    method fight (other_animal : 'a) =\n      printf \"%s and %s are fighting...\\n\" name other_animal#get_name\n\n    (* The [initializer] keyword allows us to run some code just after the\n       instance was creatd. It's similar to a post-constructor hook body. *)\n    initializer\n      printf\n        \"Animal name=[%s] species=[%s] age=[%d] was created.\\n\"\n        name\n        species\n        age\n  end\n\nlet pickles = new animal \"Mr Pickles\" 6 \"Dog\"\nlet garfield = new animal \"Garfield\" 14 \"Cat\"\n\nlet () =\n  pickles#greet;\n  garfield#greet;\n  pickles#pet;\n  pickles#pet;\n  garfield#pet;\n  pickles#pet;\n  pickles#fight garfield;\n  garfield#set_age 20;\n  pickles#set_name \"Pickles Goodman\";\n  pickles#greet;\n  garfield#greet\n;;\n\n(*/------------------------------------------------------------------------\\\n  |                                                                        |\n  |                      DIFICULTAD EXTRA (Opcional)                       |\n  |                                                                        |\n  |  Implementa dos clases que representen las estructuras de Pila y Cola  |\n  |  (estudiadas en el ejercicio número 7 de la ruta de estudio).          |\n  |                                                                        |\n  |  - Deben poder incializarse y disponer de operaciones para añadir,     |\n  |    eliminar, retornar el número de elementos e imiromir todo su        |\n  |    contenido.                                                          |\n  |                                                                        |\n  \\------------------------------------------------------------------------/*)\n\nclass type ['a] lifo = object\n  method push : 'a -> unit\n  method pop : 'a option\n  method peek : 'a option\n  method size : int\n  method print : to_str:('a -> string) -> unit\nend\n\n(* This interface implementation syntax may be familiar to people coming from\n   an object-oriented background but the idiomatic way to do this in OCaml is\n   by type-annotating the [self] reference (if it's not used, replace it with\n   a [_]) with the type [<type params> #interface] like this:\n\n   {[\n     class ['a] stack = object (_self : 'a #lifo) end\n   ]}\n\n   The language server's diagnostics behave differently when using one or the\n   other. If we use the idiomatic way, it says that the \"non virtual class\" is\n   missing some method implementations which is a very useful error message. *)\nclass ['a] stack : ['a] lifo =\n  object\n    val mutable length = 0\n    val mutable items = []\n\n    method push elt =\n      items <- elt :: items;\n      length <- length + 1\n\n    method pop =\n      match items with\n      | h :: tl ->\n        items <- tl;\n        length <- length - 1;\n        Some h\n      | [] -> None\n\n    method print ~to_str =\n      let print_node x =\n        printf\n          \"|  %s   |\\n+-------+\\n\"\n          (to_str x |> Core.String.pad_left ~char:' ' ~len:2)\n      in\n      if length > 0\n      then begin\n        print_endline \"Stack Top\";\n        print_endline \"+-------+\";\n        List.iter print_node items;\n        print_endline \"Stack Btm\"\n      end\n      else print_endline \"Empty Stack\"\n\n    method peek = Core.List.hd items\n    method size = length\n  end\n\nlet () =\n  let s = new stack in\n  s#print ~to_str:string_of_int;\n  for i = 1 to 7 do\n    s#push i\n  done;\n  let popped1 = Option.value ~default:0 s#pop in\n  let popped2 = Option.value ~default:0 s#pop in\n  printf \"Popped %d and %d.\\n\" popped1 popped2;\n  s#print ~to_str:string_of_int\n;;\n\n(* I will wrap this class inside its own module because I want to encapsulate\n   the constuctors for [node] ([Empty] and [Node]). The way it's done is by\n   declaring the necessary types, interfaces, and classes while also exposing a\n   factory function that instantiates a new object of the underlying class. *)\nmodule Queue = struct\n  type 'a node =\n    | Empty\n    | Node of\n        { value : 'a\n        ; mutable next : 'a node\n        }\n\n  class type ['a] fifo = object\n    method enqueue : 'a -> unit\n    method dequeue : 'a option\n    method first : 'a option\n    method size : int\n    method print : to_str:('a -> string) -> unit\n  end\n\n  class ['a] linear_queue =\n    object (self : 'a #fifo)\n      val mutable length = 0\n      val mutable front : 'a node = Empty\n      val mutable rear : 'a node = Empty\n\n      method private clear =\n        length <- 0;\n        front <- Empty;\n        rear <- Empty\n\n      method enqueue elt =\n        let to_insert = Node { value = elt; next = Empty } in\n        (match rear with\n         | Node last -> last.next <- to_insert\n         | Empty -> front <- to_insert);\n        rear <- to_insert;\n        length <- length + 1\n\n      method dequeue =\n        match front with\n        | Node { value; next = Empty } ->\n          self#clear;\n          Some value\n        | Node { value; next } ->\n          length <- length - 1;\n          front <- next;\n          Some value\n        | Empty -> None\n\n      method first =\n        match front with\n        | Node { value; _ } -> Some value\n        | Empty -> None\n\n      method print ~to_str =\n        if length > 0\n        then begin\n          print_string \"Queue <front> \";\n          let rec iterate node =\n            match node with\n            | Node { value; next } ->\n              printf \"[%s]->\" (to_str value);\n              iterate next\n            | Empty -> ()\n          in\n          iterate front;\n          print_endline \"[] <rear>\"\n        end\n        else print_endline \"Empty Queue\"\n\n      method size = length\n    end\n\n  let create () = new linear_queue\nend\n\nlet () =\n  let q = Queue.create () in\n  q#print ~to_str:string_of_int;\n  for i = 1 to 7 do\n    q#enqueue i\n  done;\n  let dequeued1 = Option.value ~default:0 q#dequeue in\n  let dequeued2 = Option.value ~default:0 q#dequeue in\n  printf \"Dequeued %d and %d.\\n\" dequeued1 dequeued2;\n  q#print ~to_str:string_of_int\n;;\n\n(* Output of [dune exec reto8]:\n\n   Animal name=[Mr Pickles] species=[Dog] age=[6] was created.\n   Animal name=[Garfield] species=[Cat] age=[14] was created.\n   Hello, my name is Mr Pickles, I'm a Dog of age 6!\n   Hello, my name is Garfield, I'm a Cat of age 14!\n   Mr Pickles was petted, its love for you is now Lv.1!\n   Mr Pickles was petted, its love for you is now Lv.2!\n   Garfield was petted, its love for you is now Lv.1!\n   Mr Pickles was petted, its love for you is now Lv.3!\n   Mr Pickles and Garfield are fighting...\n   Hello, my name is Pickles Goodman, I'm a Dog of age 6!\n   Hello, my name is Garfield, I'm a Cat of age 20!\n   Empty Stack\n   Popped 7 and 6.\n   Stack Top\n   +-------+\n   |   5   |\n   +-------+\n   |   4   |\n   +-------+\n   |   3   |\n   +-------+\n   |   2   |\n   +-------+\n   |   1   |\n   +-------+\n   Stack Btm\n   Empty Queue\n   Dequeued 1 and 2.\n   Queue <front> [3]->[4]->[5]->[6]->[7]->[] <rear>\n*)\n"
  },
  {
    "path": "Roadmap/08 - CLASES/pascal/miguelex.pas",
    "content": "program miguelex;\n\n{$mode objfpc}{$H+}\n\n// Clase\n\ntype \n    // Clase\n    TVehiculo = class\n        private\n            nombre: string;\n            numRuedas: integer;\n        public\n            // Constructor\n            constructor create(nom: string; ruedas: integer);\n            procedure MostrarInformacion;\n    end;\n\n    TPila = class\n        private\n            pila: array[1..100] of integer;\n            tope: integer;\n        public\n            constructor create;\n            procedure push(valor: integer);\n            function pop: integer;\n            procedure mostrar;\n    end;\n\n    TCola = class\n        private\n            cola: array[1..100] of integer;\n            inicio: integer;\n            fin: integer;\n        public\n            constructor create;\n            procedure push(valor: integer);\n            function pop: integer;\n            procedure mostrar;\n    end;\n\n// Constructor\nconstructor TVehiculo.create(nom: string; ruedas: integer);\nbegin\n    nombre := nom;\n    numRuedas := ruedas;\nend;\n\nprocedure TVehiculo.MostrarInformacion;\nbegin\n  writeln('Nombre: ', nombre);\n  writeln('Número de ruedas: ', numRuedas);\nend;\n\nconstructor TPila.create;\nbegin\n    tope := 0;\nend;\n\nprocedure TPila.push(valor: integer);\nbegin\n    tope := tope + 1;\n    pila[tope] := valor;\nend;\n\nfunction TPila.pop: integer;\nbegin\n    pop := pila[tope];\n    tope := tope - 1;\nend;\n\nprocedure TPila.mostrar;\nvar i: integer;\nbegin\n    for i := 1 to tope do\n        write(pila[i], ' ');\n    writeln;\nend;\n\nconstructor TCola.create;\nbegin\n    inicio := 1;\n    fin := 0;\nend;\n\nprocedure TCola.push(valor: integer);\nbegin\n    fin := fin + 1;\n    cola[fin] := valor;\nend;\n\nfunction TCola.pop: integer;\nbegin\n    pop := cola[inicio];\n    inicio := inicio + 1;\nend;\n\nprocedure TCola.mostrar;\nvar i: integer;\nbegin\n    for i := inicio to fin do\n        write(cola[i], ' ');\n    writeln;\nend;\n\nvar\n    // Crear objeto\n    coche: TVehiculo;\n    bicicleta: TVehiculo;\n    pila: TPila;\n    cola: TCola;\n\nbegin\n\n    // Crear objeto\n    coche := TVehiculo.create('Coche', 4);\n    bicicleta := TVehiculo.create('Bicicleta', 2);\n    pila := TPila.create;\n    cola := TCola.create;\n\n    // Mostrar\n    coche.MostrarInformacion;\n    bicicleta.MostrarInformacion;\n    \n    // Liberar memoria\n    coche.free();\n    bicicleta.free();\n\n    // Pila\n\n    pila.push(1);\n    pila.push(2);\n    pila.push(3);\n\n    pila.mostrar;\n\n    pila.pop();\n    pila.mostrar; \n\n    cola.push(1);\n    cola.push(2);\n    cola.push(3);\n\n    cola.mostrar;\n\n    cola.pop();\n    cola.mostrar;\n\n    pila.free();\n    cola.free();\n\nend."
  },
  {
    "path": "Roadmap/08 - CLASES/php/eulogioep.php",
    "content": "<?php\n\n/**\n * Clase Persona que representa a una persona con nombre y edad.\n */\nclass Persona {\n    private $nombre;\n    private $edad;\n\n    // Constructor\n    public function __construct($nombre, $edad) {\n        $this->nombre = $nombre;\n        $this->edad = $edad;\n    }\n\n    // Métodos getter y setter\n    public function getNombre() {\n        return $this->nombre;\n    }\n\n    public function setNombre($nombre) {\n        $this->nombre = $nombre;\n    }\n\n    public function getEdad() {\n        return $this->edad;\n    }\n\n    public function setEdad($edad) {\n        $this->edad = $edad;\n    }\n\n    // Método para imprimir los datos de la persona\n    public function imprimirDatos() {\n        echo \"Nombre: {$this->nombre}, Edad: {$this->edad}\\n\";\n    }\n}\n\n/**\n * Clase Pila que implementa una estructura de datos de tipo pila (LIFO).\n */\nclass Pila {\n    private $elementos;\n\n    public function __construct() {\n        $this->elementos = array();\n    }\n\n    public function push($elemento) {\n        array_push($this->elementos, $elemento);\n    }\n\n    public function pop() {\n        if (empty($this->elementos)) {\n            return \"La pila está vacía\";\n        }\n        return array_pop($this->elementos);\n    }\n\n    public function size() {\n        return count($this->elementos);\n    }\n\n    public function imprimirContenido() {\n        echo \"Contenido de la pila: \" . implode(', ', $this->elementos) . \"\\n\";\n    }\n}\n\n/**\n * Clase Cola que implementa una estructura de datos de tipo cola (FIFO).\n */\nclass Cola {\n    private $elementos;\n\n    public function __construct() {\n        $this->elementos = array();\n    }\n\n    public function enqueue($elemento) {\n        array_push($this->elementos, $elemento);\n    }\n\n    public function dequeue() {\n        if (empty($this->elementos)) {\n            return \"La cola está vacía\";\n        }\n        return array_shift($this->elementos);\n    }\n\n    public function size() {\n        return count($this->elementos);\n    }\n\n    public function imprimirContenido() {\n        echo \"Contenido de la cola: \" . implode(', ', $this->elementos) . \"\\n\";\n    }\n}\n\n// Función principal para probar las implementaciones\nfunction main() {\n    // Prueba de la clase Persona\n    $persona = new Persona(\"Juan\", 30);\n    $persona->imprimirDatos();\n    $persona->setEdad(31);\n    $persona->imprimirDatos();\n\n    // Prueba de la Pila\n    $pila = new Pila();\n    $pila->push(1);\n    $pila->push(2);\n    $pila->push(3);\n    $pila->imprimirContenido();\n    echo \"Elemento extraído de la pila: \" . $pila->pop() . \"\\n\";\n    $pila->imprimirContenido();\n\n    // Prueba de la Cola\n    $cola = new Cola();\n    $cola->enqueue(\"A\");\n    $cola->enqueue(\"B\");\n    $cola->enqueue(\"C\");\n    $cola->imprimirContenido();\n    echo \"Elemento extraído de la cola: \" . $cola->dequeue() . \"\\n\";\n    $cola->imprimirContenido();\n}\n\n// Ejecutar la función principal\nmain();\n\n?>"
  },
  {
    "path": "Roadmap/08 - CLASES/php/gabrielmoris.php",
    "content": "<?php\n/*\n* EXERCISE:\n* Explore the concept of a class and create an example that implements an initializer,\n* attributes, and a function that prints them (taking into account the possibilities\n* of your language).\n* Once implemented, create it, set its parameters, modify them, and print them\n* using its function.\n*/\nclass My_Class\n{\n    // This would be the private properties:\n    private $data;\n\n    // Constructor\n    public function __construct()\n    {\n        $this->data = [];\n    }\n\n    // Private functions are available only internally\n\n    private function _count()\n    {\n        return count($this->data);\n    }\n\n    // Public Functions are available outside\n    public function add(string $item): int\n    {\n        $this->data[] = $item;\n        return  $this->_count();\n    }\n\n    public function delete($item): int\n    {\n        $pos = array_search($item, $this->data);\n        unset($this->data[$pos]);\n        return  $this->_count();\n    }\n\n    public function clear(): int\n    {\n        $this->data = [];\n        return  $this->_count();\n    }\n\n    public function find($item)\n    {\n        $pos = array_search($item, $this->data);\n        return $this->data[$pos];\n    }\n\n    public function is_empty()\n    {\n        return empty($this->data);\n    }\n\n\n    // Getters\n    public function get_data(): array\n    {\n        return $this->data;\n    }\n\n    // Setters\n    public function set_data(array $data): void\n    {\n        $this->data = $data;\n    }\n}\n\n$my_class = new My_Class();\n$my_class->add(\"item1\");\n$my_class->add(\"item2\");\n$my_class->add(\"item3\");\n$my_class->add(\"item4\");\n$my_class->add(\"item5\");\n\nforeach ($my_class->get_data() as $data) {\n    echo \"Data: \" . $data . \"\\n\";\n}\n\n$my_class->set_data([1, 2, 3, 4, 5]);\nforeach ($my_class->get_data() as $data) {\n    echo \"Data: \" . $data . \"\\n\";\n}\n$is_empty = $my_class->is_empty() ? \" YES\\n\" : \" NO\\n\";\necho \"Is Empty? : \" .  $is_empty;\n$my_class->clear();\n$is_empty2 = $my_class->is_empty() ? \" YES\\n\" : \" NO\\n\";\necho \"And Now? : \" . $is_empty2;\n\n/* EXTRA DIFFICULTY (optional):\n* Implement two classes that represent the Stack and Queue structures (studied\n* in exercise number 7 of the study path)\n* - They must be able to initialize and have operations to add, remove,\n*   return the number of elements, and print all their contents.\n*/\n\n\nclass Stack\n{\n    private $pages;\n    private $length;\n\n    // Constructor\n    public function __construct()\n    {\n        $this->items =  [];\n        $this->length = 0;\n    }\n\n    public function push($item)\n    {\n        $this->length += 1;\n        array_push($this->items, $item);\n    }\n\n    public function pop()\n    {\n        $this->length -= 1;\n        return array_pop($this->items);\n    }\n\n    public function peek()\n    {\n        if (empty($this->items)) {\n            return null;\n        }\n\n        return  $this->items[count($this->items) - 1];\n    }\n\n    public function size()\n    {\n        return  $this->length;\n    }\n\n    public function search($item)\n    {\n        $index = array_search($item, $this->items);\n\n        if (!$index && $index !== 0) {\n            return -1;\n        }\n\n        return $index;\n    }\n\n    public function clear()\n    {\n        $this->length = 0;\n        $this->items = [];\n    }\n}\n\necho \"====== STACK ======\\n\";\n$st = new Stack();\n$st->push(1);\necho $st->peek() . \"\\n\"; // 1\n$st->push(2);\necho $st->peek() . \"\\n\"; // 2\necho $st->search(1) . \"\\n\"; //0\necho $st->pop() . \"\\n\"; // 2\necho $st->peek() . \"\\n\"; // 1\necho $st->search(2) . \"\\n\"; // -1\n\n\nclass Queue\n{\n    private $items;\n    private $length;\n\n    // Constructor\n    public function __construct()\n    {\n        $this->items =  [];\n        $this->length = 0;\n    }\n\n    public function enqueue($item)\n    {\n        $this->length += 1;\n        array_push($this->items, $item);\n    }\n\n    public function dequeue()\n    {\n        $this->length -= 1;\n        return array_shift($this->items);\n    }\n\n    public function peek()\n    {\n        if (empty($this->items)) {\n            return null;\n        }\n\n        return  $this->items[0];\n    }\n\n    public function size()\n    {\n        return  $this->length;\n    }\n\n    public function search($item)\n    {\n        $index = array_search($item, $this->items);\n\n        if (!$index && $index !== 0) {\n            return -1;\n        }\n\n        return $index;\n    }\n\n    public function clear()\n    {\n        $this->length = 0;\n        $this->items = [];\n    }\n}\n\necho \"====== QUEUE ======\\n\";\n$qu = new Queue();\n$qu->enqueue(1);\necho $qu->peek() . \"\\n\"; // 1\n$qu->enqueue(2);\necho $qu->peek() . \"\\n\"; // 1\necho $qu->search(1) . \"\\n\"; // 0\necho $qu->dequeue() . \"\\n\"; // 1\necho $qu->peek() . \"\\n\"; // 2\necho $qu->search(2) . \"\\n\"; // 0"
  },
  {
    "path": "Roadmap/08 - CLASES/php/marcode24.php",
    "content": "<?php\n/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n */\n\n\nclass Stack {\n    private $items;\n\n    public function __construct() {\n        $this->items = [];\n    }\n\n    public function push($element) {\n        array_push($this->items, $element);\n    }\n\n    public function pop() {\n        if ($this->isEmpty()) {\n            return 'La pila está vacía';\n        }\n        return array_pop($this->items);\n    }\n\n    public function isEmpty() {\n        return empty($this->items);\n    }\n\n    public function peek() {\n        return end($this->items);\n    }\n\n    public function clear() {\n        $this->items = [];\n    }\n\n    public function size() {\n        return count($this->items);\n    }\n}\n\nclass Queue {\n    private $items;\n\n    public function __construct() {\n        $this->items = [];\n    }\n\n    public function enqueue($element) {\n        array_push($this->items, $element);\n    }\n\n    public function dequeue() {\n        if ($this->isEmpty()) {\n            return 'La cola está vacía';\n        }\n        return array_shift($this->items);\n    }\n\n    public function isEmpty() {\n        return empty($this->items);\n    }\n\n    public function size() {\n        return count($this->items);\n    }\n}\n\n$pila = new Stack();\n$pila->push(1);\n$pila->push(2);\n$pila->push(3);\necho $pila->pop() . PHP_EOL; // 3\necho $pila->pop() . PHP_EOL; // 2\n\n$cola = new Queue();\n$cola->enqueue('a');\n$cola->enqueue('b');\n$cola->enqueue('c');\necho $cola->dequeue() . PHP_EOL; // a\necho $cola->dequeue() . PHP_EOL; // b\n\nclass Navegador {\n    private $history;\n    private $future;\n    private $currentPage;\n\n    public function __construct() {\n        $this->history = new Stack();\n        $this->future = new Stack();\n        $this->currentPage = null;\n    }\n\n    // navegar a una nueva página\n    public function goToPage($page) {\n        if ($this->currentPage !== null) {\n            $this->history->push($this->currentPage);\n        }\n        $this->currentPage = $page;\n        $this->future->clear();\n        echo 'Página actual: ' . $this->currentPage . PHP_EOL;\n    }\n\n    // retroceder a la página anterior\n    public function goBack() {\n        if ($this->history->isEmpty()) {\n            echo 'No hay páginas anteriores' . PHP_EOL;\n            return;\n        }\n        $this->future->push($this->currentPage);\n        $this->currentPage = $this->history->pop();\n        echo 'Página actual: ' . $this->currentPage . PHP_EOL;\n    }\n\n    // avanzar a la página siguiente\n    public function goForward() {\n        if ($this->future->isEmpty()) {\n            echo 'No hay páginas siguientes' . PHP_EOL;\n            return;\n        }\n        $this->history->push($this->currentPage);\n        $this->currentPage = $this->future->pop();\n        echo 'Página actual: ' . $this->currentPage . PHP_EOL;\n    }\n}\n\n$navegador = new Navegador();\n$navegador->goToPage('google.com');\n$navegador->goToPage('facebook.com');\n$navegador->goToPage('twitter.com');\n$navegador->goBack(); // regresa a facebook.com\n$navegador->goBack(); // regresa a google.com\n$navegador->goForward(); // avanza a facebook.com\n$navegador->goToPage('instagram.com'); // instagram.com\n$navegador->goBack(); // regresa a facebook.com\n$navegador->goForward(); // avanza a instagram.com\n\n// Visita mi repo en GitHub para ver y correr los tests de este código --> https://github.com/marcode24/weekly-challenges\n\n?>"
  },
  {
    "path": "Roadmap/08 - CLASES/php/miguelex.php",
    "content": "<?php\n\n    // Clases en PHP\n    class Vehiculo{\n        // Atributos\n        private $nombre;\n        private $numRuedas;\n\n        // Constructor\n        public function __construct($nombre, $numRuedas){\n            $this->nombre = $nombre;\n            $this->numRuedas = $numRuedas;\n        }\n\n        // Método mágico __toString\n        public function __toString(){\n            return \"Nombre: \" . $this->nombre . \" - Ruedas: \" . $this->numRuedas;\n        }\n    }\n\n    $coche = new Vehiculo(\"Coche\", 4); // Instanciamos un objeto de la clase Vehiculo\n    $bicicleta = new Vehiculo(\"Bicicleta\", 2);\n\n    echo $coche . \"\\n\"; // Llamamos al método __toString para imprimir el contenido del objeto\n    echo $bicicleta . \"\\n\";\n\n    // Extra\n\n    class Stack {\n        private $stack = array();\n\n        public function __construct($item){\n            $this->push($item);\n        }\n\n        public function push($item){\n            array_push($this->stack, $item);\n        }\n\n        public function pop(){\n            return array_pop($this->stack);\n        }\n\n        public function numElements(){\n            return count($this->stack);\n        }\n\n        public function __toString(){\n            return implode(\", \", $this->stack);\n        }\n    }\n\n    // Ejemplo de uso de la clase Stack\n    $stack = new Stack(1); // Instanciamos un objeto de la clase Stack\n    \n    // añadimos dos elementos mas a la pila\n    $stack->push(2);\n    $stack->push(3);\n\n    // Mostramos el contenido de la pila\n    echo \"El contenido actual de la pila es: \".$stack . \"\\n\";\n    echo \"Extraemos el elemeto \".$stack->pop() . \" que es el que esta en la cima de la pila\\n\";\n    echo \"La pila tiene un total de \".$stack->numElements() . \" elementos\\n\";\n    echo \"Volvemos a mostrar el contenido de la pila: \".$stack . \"\\n\";\n\n    class Queue {\n        private $queue = array();\n\n        public function __construct($item){\n            $this->enqueue($item);\n        }\n\n        public function enqueue($item){\n            array_push($this->queue, $item);\n        }\n\n        public function dequeue(){\n            return array_shift($this->queue);\n        }\n\n        public function numElements(){\n            return count($this->queue);\n        }\n\n        public function __toString(){\n            return implode(\", \", $this->queue);\n        }\n    }\n\n\n    // Ejemplo de uso de la clase Queue\n    $queue = new Queue(1); // Instanciamos un objeto de la clase Queue\n    \n    // añadimos tres elementos a la cola\n    $queue->enqueue(2);\n    $queue->enqueue(3);\n    $queue->enqueue(4);\n\n    // Mostramos el contenido de la cola\n    echo \"El contenido actual de la cola es: \".$queue . \"\\n\";\n    echo \"Extraemos el elemeto \".$queue->dequeue() . \" que es el que esta en la cabeza de la cola\\n\";\n    echo \"La cola tiene un total de \".$queue->numElements() . \" elementos\\n\";\n    echo \"Volvemos a mostrar el contenido de la cola: \".$queue . \"\\n\";\n    \n\n\n\n\n"
  },
  {
    "path": "Roadmap/08 - CLASES/php/qv1ko.php",
    "content": "<?php\n\n    class C1 {\n\n        private $c1String;\n\n        public function __construct($value = \"example\") {\n            $this->c1String = $value;\n        }\n\n        public function getC1String() {\n            return $this->c1String;\n        }\n\n        public function setC1String($c1String) {\n            $this->c1String = $c1String;\n        }\n\n        public function __toString() {\n            return \"Class 1 value: \" . $this->c1String;\n        }\n\n    }\n\n    class C2 {\n\n        private $c2String;\n\n        public function __construct($value = \"example\") {\n            $this->c2String = $value;\n        }\n\n        public function getC2String() {\n            return $this->c2String;\n        }\n\n        public function setC2String($c2String) {\n            $this->c2String = $c2String;\n        }\n\n        public function __toString() {\n            return \"Class 2 value: \" . $this->c2String;\n        }\n\n    }\n\n    function main() {\n\n        $example1 = new C1();\n        echo $example1 . \"\\n\";\n        $example1->setC1String(\"Example 1\");\n        echo $example1->getC1String() . \"\\n\";\n\n        $example2 = new C2();\n        echo $example2 . \"\\n\";\n        $example2->setC2String(\"Example 2\");\n        echo $example2->getC2String() . \"\\n\";\n\n    }\n\n    main();\n\n?>\n"
  },
  {
    "path": "Roadmap/08 - CLASES/php/torvicv.php",
    "content": "<?php\n\nclass Pila {\n\n    private $pila;\n\n    private $attribute1;\n    private $attribute2;\n\n    public function __construct(array $pila, int $attribute1, string $attribute2)\n    {\n        $this->pila = $pila;\n        $this->attribute1 = $attribute1;\n        $this->attribute2 = $attribute2;\n    }\n\n    public function getPila(): array {\n        return $this->pila;\n    }\n\n    public function getPilaString(): string {\n        return json_encode($this->pila);\n    }\n\n    public function getAttribute1(): int {\n        return $this->attribute1;\n    }\n\n    public function getAttribute2(): string {\n        return $this->attribute2;\n    }\n\n    public function setPila(array $pila) {\n        $this->pila = $pila;\n    }\n\n    public function setAttribute1(int $attribute1) {\n        $this->attribute1 = $attribute1;\n    }\n\n    public function setAttribute2(string $attribute2) {\n        $this->attribute2 = $attribute2;\n    }\n\n    public function __toString(): string\n    {\n        return 'pila: ' . json_encode($this->pila) . \n        ', attribute1: ' . $this->attribute1 . \n        ', attribute2: ' . $this->attribute2;\n    }\n}\n\n$pila1 = new Pila([1, 2, 3, 4, 5], 1, 'world');\n\necho $pila1->__toString().'<br />';\n\necho $pila1->getPilaString().'<br />';\n\necho $pila1->getAttribute1().'<br />';\n\necho $pila1->getAttribute2().'<br />';\n\n$pila1->setPila(['hello', 'world']);\n\n$pila1->setAttribute1(2);\n\n$pila1->setAttribute2('bye');\n\necho $pila1->__toString().'<br />';\n\necho $pila1->getPilaString().'<br />';\n\necho $pila1->getAttribute1().'<br />';\n\necho $pila1->getAttribute2().'<br />';\n\n/**\n * Clase para la dificultad extra.\n */\nclass PilaOpt {\n\n    private $pila;\n\n    public function __construct(array $pila)\n    {\n        $this->pila = $pila;\n    }\n\n    public function getPila(): array {\n        return $this->pila;\n    }\n\n    public function getPilaString(): string {\n        return json_encode($this->pila);\n    }\n\n    public function setPila(array $pila) {\n        $this->pila = $pila;\n    }\n\n    /**\n     * Método para introducir un elemento en la pila.\n     */\n    public function push($element) {\n        array_push($this->pila, $element);\n    }\n\n    /**\n     * Método para eliminar un elemento de la pila.\n     * Último en entrar, primero en salir.\n     */\n    public function pop() {\n        return array_pop($this->pila);\n    }\n\n    /**\n     * Método para conseguir la cantidad de elementos.\n     */\n    public function counter() {\n        return count($this->pila);\n    }\n\n    public function __toString(): string\n    {\n        return 'pila: ' . json_encode($this->pila);\n    }\n}\n\n$pilaOpt = new PilaOpt([1, 2, 3]);\n\necho 'Mostramos los elementos del array: '.$pilaOpt->getPilaString().'<br />';\n\necho 'Mostramos la cantidad de elementos en la pila(3): '.$pilaOpt->counter();\n\necho 'Añadimos un nuevo elemento al array.<br />';\n\n$pilaOpt->push(4);\n\necho 'Mostramos los elementos del array: '.$pilaOpt->getPilaString().'<br />';\n\necho 'Mostramos la cantidad de elementos en la pila(4): '.$pilaOpt->counter();\n\necho 'Eliminamos el último elemento del array que se introdujo(4): '.$pilaOpt->pop().'<br />';\n\necho 'Mostramos los elementos del array: '.$pilaOpt->getPilaString().'<br />';\n\necho 'Mostramos la cantidad de elementos en la pila(3): '.$pilaOpt->counter();\n\necho 'Eliminamos el último elemento del array que se introdujo(3): '.$pilaOpt->pop().'<br />';\n\necho 'Mostramos los elementos del array: '.$pilaOpt->getPilaString().'<br />';\n\necho 'Mostramos la cantidad de elementos en la pila(2): '.$pilaOpt->counter();\n\n/**\n * Clase para la dificultad extra.\n */\nclass ColaOpt {\n\n    private $cola;\n\n    public function __construct(array $cola)\n    {\n        $this->cola = $cola;\n    }\n\n    public function getCola(): array {\n        return $this->cola;\n    }\n\n    public function getcolaString(): string {\n        return json_encode($this->cola);\n    }\n\n    public function setCola(array $cola) {\n        $this->cola = $cola;\n    }\n\n    /**\n     * Método para introducir un elemento en la pila.\n     */\n    public function push($element) {\n        array_push($this->cola, $element);\n    }\n\n    /**\n     * Método para eliminar un elemento de la pila.\n     * Último en entrar, primero en salir.\n     */\n    public function shift() {\n        return array_shift($this->cola);\n    }\n\n    public function counter() {\n        return count($this->cola);\n    }\n\n    public function __toString(): string\n    {\n        return 'cola: ' . json_encode($this->cola);\n    }\n}\n\n$colaOpt = new ColaOpt([1, 2, 3]);\n\necho 'Mostramos los elementos del array: '.$colaOpt->getcolaString().'<br />';\n\necho 'Mostramos la cantidad de elementos en la pila(3): '.$colaOpt->counter();\n\necho 'Añadimos un nuevo elemento al array.<br />';\n\n$colaOpt->push(4);\n\necho 'Mostramos los elementos del array: '.$colaOpt->getcolaString().'<br />';\n\necho 'Mostramos la cantidad de elementos en la pila(4): '.$colaOpt->counter();\n\necho 'Eliminamos el primer elemento del array que se introdujo(1): '.$colaOpt->shift().'<br />';\n\necho 'Mostramos los elementos del array: '.$colaOpt->getcolaString().'<br />';\n\necho 'Mostramos la cantidad de elementos en la pila(3): '.$colaOpt->counter();\n\necho 'Eliminamos el segundo elemento del array que se introdujo(2): '.$colaOpt->shift().'<br />';\n\necho 'Mostramos los elementos del array: '.$colaOpt->getcolaString().'<br />';\n\necho 'Mostramos la cantidad de elementos en la pila(2): '.$colaOpt->counter();\n\n?>"
  },
  {
    "path": "Roadmap/08 - CLASES/python/59822.py",
    "content": "'''Una clase es un modelo que define un conjunto de atributos y métodos que tendrán \nlos objetos que se creen a partir de ella. '''\n\n\n## Los parametros de los metodos de instancia deben ser self,\n# que es una referencia al objeto que invoca el metodo\n\nclass Persona:\n    persona = \"Persona es un ser humano\"\n    #M Persona es un atributo de la clase\n    \n    def __init__(self, nombre, apellido): # Metodo constructor\n        self.nombre = nombre # Atributo de instancia\n        self.apellido = apellido\n        \n    def hablar(self, mensaje):\n        print(f\"{self.nombre} dice {mensaje}\")\n\nisabel = Persona(\"Isabel\", \"García\")\nisabel.hablar(\"Hola, soy Isabel\")\n        \n'''Dificultad'''\n##  LIFO\nclass LIFO:\n    \n    def __init__(self):\n        self.opciones = []\n    \n    def añadir(self, item):\n        self.opciones.append(item)\n        \n    def quitar(self):\n        if self.count() == 0: \n            return None\n        else:\n            return self.opciones.pop()\n    \n    def count(self):\n        return len(self.opciones)\n    \n    def mostrar(self):       \n        for item in self.opciones:\n            print(\"Las opciones son:\\n\", item)\n\nclass Fifo:\n    \n    def __init__(self):\n        self.fila = []\n    \n    def añadir(self, item):\n        self.fila.append(item)\n    \n    def eliminar(self):\n        if self.count() == 0:\n            return None\n        else:\n            return self.fila.pop(0)\n    \n    def count(seLf):\n        return len(self.fila)\n    \n    def mostrar(self):       \n        for item in self.opciones:\n            print(\"Las opciones son:\\n\", item)"
  },
  {
    "path": "Roadmap/08 - CLASES/python/AChapeton.py",
    "content": "class Todo:\n  def __init__(self, title, description, done, user, daysLeft):\n    self.title = title\n    self.description = description\n    self.done = done\n    self.user = user\n    self.daysLeft = daysLeft\n\n  def toggleStatus(self):\n    self.done = not self.done\n  \n  def printTodo(self):\n    print(f\"\"\"\n      Title: {self.title}\n      Description: {self.description}\n      Done: {self.done}\n      User: {self.user}\n      Days left: {self.daysLeft}\n    \"\"\")\n  \nnewTodo = Todo('Test', 'Just testing', False, 'Andres', 4)\n\nnewTodo.printTodo()\n\nnewTodo.toggleStatus()\n\nnewTodo.printTodo()\n\n\n# DIFICULTAD EXTRA\n\nclass Pila:\n  def __init__(self, data):\n    self.data = data\n\n  def checkData(self):\n    print(self.data)\n\n  def addElement(self, value):\n    return self.data.append(value)\n  \n  def deleteElement(self):\n    return self.data.pop()\n\nnewPila = Pila([1, 2, 3])\n\nnewPila.checkData()\nnewPila.addElement(4)\nnewPila.addElement(5)\nnewPila.addElement(6)\nnewPila.checkData()\nnewPila.deleteElement()\nnewPila.checkData()\n\nclass Cola:\n  def __init__(self, data):\n    self.data = data\n\n  def checkData(self):\n    print(self.data)\n\n  def addElement(self, value):\n    return self.data.append(value)\n  \n  def deleteElement(self):\n    return self.data.pop(0)\n\nnewCola = Cola([1, 2, 3])\n\nnewCola.checkData()\nnewCola.addElement(4)\nnewCola.addElement(5)\nnewCola.addElement(6)\nnewCola.checkData()\nnewCola.deleteElement()\nnewCola.checkData()"
  },
  {
    "path": "Roadmap/08 - CLASES/python/AlainMartz.py",
    "content": "#08 CLASES\n\n\"\"\"\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n\"\"\"\n\nclass bici():\n\n    def __init__(self, marca, modelo, talla) -> None:\n        self.marca = marca\n        self.modelo = modelo\n        self.talla = talla\n\n    def infobike(self):\n        print(f\"Bicicleta: {self.marca}, Modelo: {self.modelo}, Talla: {self.talla}\")\n    \nnueva_bici = bici(\"Giant\",\"Talon 2\",\"L\")\nnueva_bici.infobike()\n\nnueva_bici.talla = [\"XL\",\"L\"]\nnueva_bici.infobike()\n\nnueva_bici.marca = \"Trek\"\nnueva_bici.modelo = \"Marlon 5\"\nnueva_bici.infobike()\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n\"\"\"\n\nclass pila():\n\n    def __init__(self) -> None:\n        self.stack = []\n    \n    def añadir(self, value):\n        self.stack.append(value)\n    \n    def eliminar(self):\n        self.stack.pop()\n    \n    def infopila(self):\n        if self.stack:\n            print(self.stack)\n        else:\n            print(\"La pila está vacía, añada elementos\")\n\nx = pila()\nx.añadir(1)\nx.añadir(2)\nx.añadir(3)\nx.añadir(4)\nx.infopila()\nx.eliminar()\nx.infopila()\nx.eliminar()\nx.infopila()\nx.eliminar()\nx.infopila()\nx.eliminar()\nx.infopila()\n\nclass cola():\n\n    def __init__(self) -> None:\n        self.queue = []\n\n    def enqueue(self, value):\n        self.queue.append(value)\n    \n    def dequeue(self):\n        self.queue.pop(0)\n    \n    def infocola(self):\n        if self.queue:\n            print(self.queue)\n        else:\n            print(\"La cola está vacía, añada elementos\")\n\ny = cola()\ny.enqueue(\"a\") \ny.enqueue(\"b\") \ny.enqueue(\"c\") \ny.enqueue(\"d\")\ny.infocola()\ny.dequeue()\ny.infocola()\ny.dequeue()\ny.infocola()\ny.dequeue()\ny.infocola()\ny.dequeue()\ny.infocola()   "
  },
  {
    "path": "Roadmap/08 - CLASES/python/Aldroide.py",
    "content": "\"\"\" Explorar el concepto de clase crear un ejemplo con:\n    inicializador, atributos y una funcion que los imprima\n    una vez implementada, creala establece parametros \n    modificalos e imprimelos\n\"\"\"\n\n\nclass Persona:\n    def __init__(self, nombre, edad):\n        self.nombre = nombre\n        self.edad = edad\n\n    def imprime(self):\n        print(f\"El nombre es: {self.nombre}, edad: {self.edad}\")\n\n\npersona1 = Persona(\"Emmanuel\", 32)\npersona1.imprime()\n\n\n\"\"\"\n    Dificultad extra\n    Implementar dos clases que representaen las estructuras de Pila y Cola\n    (estudiadas en el ejercicio 7 de la ruta de estudio)\n    Debe poder inicializarse y disponer de operaciones para añadir, eliminar\n    retornar el numero de elementos e imprimir el contenido\n\"\"\"\n\n\nclass Pila:\n    def __init__(self) -> None:\n        self.items = []\n    \n    def is_empty(self):\n        return len(self.items) == 0\n\n    def add(self, value):\n        self.items.append(value)\n\n    def delete(self):\n        if not self.is_empty():\n            return self.items.pop()\n        else:\n            return \"Pila Vacia\"\n\n    def numbers_of_element(self):\n        if not self.is_empty():\n            return len(self.items)\n        else:\n            return \"La pila esta vacia\"\n\n    def information(self):\n        print(self.items)\n\npila1=Pila()\n\npila1.add(\"Sebastian\")\npila1.add(\"Jorge\")\npila1.add(\"Ricardo\")\nnum=pila1.numbers_of_element()\nprint(f\"Este es el numero de elementos de la pila: {num}\")\npila1.information()\nitem=pila1.delete()\nprint(f\"Este es el item eliminado, {item}\")\npila1.information()\n\n\n\nclass Cola:\n    def __init__(self) -> None:\n        self.items = []\n\n    def add(self, value):\n        self.items.append(value)\n\n    def is_empty(self):\n        return len(self.items) == 0\n\n    def delete(self):\n        if not self.is_empty():\n            return self.items.pop(0)\n        else:\n            return \"La cola está vacía\"\n\n    def numbers_of_element(self):\n        if not self.is_empty():\n            return len(self.items)\n        else:\n            return \"La cola está vacía\"\n\n    def information(self):\n        print(self.items)\n\ncola1=Cola()\n\ncola1.add(\"Edith\")\ncola1.add(\"Hortensia\")\ncola1.add(\"Yubesny\")\nnum=cola1.numbers_of_element()\nprint(f\"Este es el numero de elementos de la cola: {num}\")\ncola1.information()\nitem=cola1.delete()\nprint(f\"Este es el item eliminado, {item}\")\ncola1.information()"
  },
  {
    "path": "Roadmap/08 - CLASES/python/Aleran07.py",
    "content": "#08\n#Clases\nclass Perro: # La primera en mayuscula\n    def __init__(self, nombre, raza): # Inicializador\n        self.nombre = nombre\n        self.raza = raza\n\n    def ladrar(self):\n        print(f\"{self.nombre} está ladrando\")\n\nmi_perro = Perro(\"Max\", \"Labrador\")\ntu_perro = Perro(\"Luna\", \"Poodle\")\n\nmi_perro.ladrar()  # Max está ladrando\ntu_perro.ladrar()  # Luna está ladrando\n\n# Herencias\nclass Animal:\n    def __init__(self, nombre):\n        self.nombre = nombre\n\n    def hablar(self):\n        print(\"Este animal hace un sonido\")\n\nclass Gato(Animal):\n    def hablar(self):\n        print(f\"{self.nombre} dice miau\")\n\nmi_gato = Gato(\"Michi\")\nmi_gato.hablar()  # Michi dice miau\n\n\n# Ejercicio\n# Definición de la clase\nclass Persona:\n    # Inicializador: se ejecuta al crear un nuevo objeto\n    def __init__(self, nombre, edad):\n        self.nombre = nombre  # atributo de instancia\n        self.edad = edad      # atributo de instancia\n\n    # Método: función dentro de la clase\n    def mostrar_info(self):\n        print(f\"Nombre: {self.nombre}, Edad: {self.edad}\")\n    \n    def cumplir_años(self):\n        self.edad += 1\n\n# Crear un objeto (instancia) de la clase Persona\npersona1 = Persona(\"Brian\", 24)\n\n# Llamamos al método que imprime los datos\npersona1.mostrar_info()  # 👉 Nombre: Brian, Edad: 24\n\n# Modificamos los atributos directamente\npersona1.nombre = \"Andrés\"\npersona1.edad = 25\n\n# Imprimimos de nuevo\npersona1.mostrar_info()  # 👉 Nombre: Andrés, Edad: 25\n\npersona1.cumplir_años()\npersona1.mostrar_info()\n\n\"\"\" * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\"\"\"\n\nclass Pila:\n    def __init__(self):\n        self.list = []\n\n    def add(self, dato):\n        self.list.append(dato)\n        pass\n    def remove_pila(self):\n        self.list.pop()\n\n    def remove_cola(self):\n        self.list.pop(0)\n    \n    def count_list(self):\n        self.cuenta = len(self.list)\n        print(f\"\\nHay {self.cuenta} elementos en la lista\")\n    \n    def mostrar_info(self):\n        print(f\"\\nLista: {self.list}\")\n\nmi_pila = Pila()\nmi_pila.add(1)\nmi_pila.add(2)\nmi_pila.add(3)\nmi_pila.add(4)\n\nmi_pila.mostrar_info()\nmi_pila.count_list()\n\nmi_pila.remove_pila()\n\nmi_pila.mostrar_info()\nmi_pila.count_list()\n\nmi_pila.remove_cola()\n\nmi_pila.mostrar_info()\nmi_pila.count_list()\n\nmi_cola = Pila()\nmi_cola.add(1)\nmi_cola.add(\"A\")\nmi_cola.add(\"B\")\n\nmi_cola.mostrar_info()"
  },
  {
    "path": "Roadmap/08 - CLASES/python/AllanYSalazarG.py",
    "content": "\"\"\" #08 CLASES \"\"\"\n\nfrom collections import deque\n\n# ----------------- CONOCIENDO CLASES -----------------\n\n# Creacion de una clase\n\n\nclass Transporte:\n    # Creacion de atributos globales\n    ruedas = True\n\n    # Creacion del constructor\n    def __init__(self, conductor):\n        self.conductor = conductor\n\n    # Creacion del destructor\n    def __delattr__(self):\n        print(\"Transporte dado de baja\")\n\n    # Creacion de metodos especializados para la clase\n    def avanzar(self):\n        if self.ruedas:\n            print(f\"{self.conductor} comenzará a avanzar\")\n\n    def frenar(self):\n        print(f\"{self.conductor} comenzará a frenar\")\n\n\n# automovil = Transporte(\"Allan\")\n# automovil.avanzar()\n\n# ------------------------ EJERCICIO EXTRA --------------------------\n\n# -------- CLASE PILA ---------\nprint(\"-------- CLASE PILA ---------\")\n\n\nclass Pila:\n    def __init__(self):\n        self.items = []\n\n    def add_item(self, item):\n        print(\"-> add_item() en acción\")\n        self.items.append(item)\n\n    def remove_last_item(self):\n        print(\"-> remove_last_item() en acción\")\n        if not self.items:\n            print(\"sin elementos\")\n        else:\n            item_removed = self.items.pop()\n            print(f\"Elemento eliminado: {item_removed}\")\n\n    def show_items(self):\n        print(\"-> show_items() en acción: \")\n        if not self.items:\n            print(\"sin elementos\")\n        else:\n            for item in self.items:\n                print(item, end=\" - \")\n            print(\"\")\n\n\npila = Pila()\npila.add_item(\"Hola\")\npila.add_item(\"Mundo\")\npila.show_items()\npila.remove_last_item()\npila.show_items()\n\n\n# -------- CLASE COLA ---------\n\nprint(\"-------- CLASE COLA ---------\")\n\n\nclass Cola:\n    def __init__(self):\n        self.items = deque()\n\n    def add_item(self, item):\n        print(\"-> add_item() en acción\")\n        self.items.append(item)\n\n    def remove_first_item(self):\n        print(\"-> remove_fisrt_item() en acción\")\n        if not self.items:\n            print(\"sin elementos\")\n        else:\n            item_removed = self.items.popleft()\n            print(f\"Elemento atendido: {item_removed}\")\n\n    def show_items(self):\n        print(\"-> show_items() en acción\")\n        if not self.items:\n            print(\"sin elementos\")\n        else:\n            for item in self.items:\n                print(item, end=\" - \")\n            print(\"\")\n\n\ncola = Cola()\ncola.add_item(\"Persona 1\")\ncola.add_item(\"Persona 2\")\ncola.add_item(\"Persona 3\")\ncola.show_items()\ncola.remove_first_item()\ncola.show_items()\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/Alvaro-Neyra.py",
    "content": "#  * EJERCICIO:\r\n#  * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\r\n#  * atributos y una función que los imprima (teniendo en cuenta las posibilidades\r\n#  * de tu lenguaje).\r\n#  * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\r\n#  * utilizando su función.\r\n\r\n# Creando la clase Persona:\r\nclass Persona:\r\n    def __init__(self, nombre, apellido, edad, email):\r\n        self.nombre = nombre\r\n        self.apellido = apellido\r\n        self.edad = edad\r\n        self.email = email\r\n    def saludar(self):\r\n        print(f\"Hola, como estas?. Mi nombre es {self.nombre}!\")\r\n    def get_information(self):\r\n        print(f\"Nombre: {self.nombre}\")\r\n        print(f\"Apellido: {self.apellido}\")\r\n        print(f\"Edad: {self.edad}\")\r\n        print(f\"Email: {self.email}\")\r\n\r\n# Instanciando de la clase Persona y estableciendo sus parametros:\r\npersona1 = Persona(\"Alvaro\", \"Neyra\", 19, \"alvaro.neyra.salazar@gmail.com\")\r\n# Modificando uno de sus atributos:\r\npersona1.edad = 10\r\nprint(f\"Edad modificada: {persona1.edad}\")\r\n# Usando sus metodos:\r\npersona1.saludar()\r\n# Imprimiendo la informacion del objeto instanciado usando su metodo \"get_information\":\r\npersona1.get_information()\r\n\r\n#  * DIFICULTAD EXTRA (opcional):\r\n#  * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\r\n#  * en el ejercicio número 7 de la ruta de estudio)\r\n#  * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\r\n#  *   retornar el número de elementos e imprimir todo su contenido.\r\n\r\n# * Pilas:\r\n# Definiendo la clase Pila (Stack)\r\nclass Pila:\r\n    def __init__(self):\r\n        self.items = []\r\n    def add(self, value):\r\n        self.items.append(value)\r\n        print(self.items)\r\n    def delete(self):\r\n        elemento_eliminado = self.items.pop()\r\n        return elemento_eliminado\r\n    def number_of_elements(self):\r\n        numero_de_elementos = len(self.items)\r\n        if numero_de_elementos == 0:\r\n            return 0\r\n        else:\r\n            return numero_de_elementos\r\n    def get_information(self):\r\n        print(self.items)\r\n# Instanciando un objeto de la clase Pila\r\npila1 = Pila()\r\n# Usando sus metodos:\r\n## Anadiendo elementos:\r\npila1.add(1)\r\npila1.add(\"Segundo elemento\")\r\npila1.add(True)\r\n## Obteniendo el numero de elementos:\r\nnumero_de_elementos_de_la_pila = pila1.number_of_elements()\r\nprint(f\"Este es el numero de elementos de la pila iniciada: {numero_de_elementos_de_la_pila}\")\r\n## Conseguiendo los elementos de la pila:\r\npila1.get_information()\r\n## Eliminando el elemento:\r\nelemento = pila1.delete()\r\nprint(f\"Este es el elemento eliminado: {elemento}\")\r\n## Consiguiendo los elementos de la pila actual:\r\nprint(f\"Estructura de la pila actual:\")\r\npila1.get_information()\r\n\r\n# * Colas:\r\n# Definiendo la clase de la cola (Queue)\r\nclass Cola:\r\n    def __init__(self):\r\n        self.items = []\r\n    def add(self, value):\r\n        self.items.insert(0, value)\r\n        print(self.items)\r\n    def delete(self):\r\n        elemento_eliminado = self.items.pop()\r\n        return elemento_eliminado\r\n    def number_of_elements(self):\r\n        numero_de_elementos = len(self.items)\r\n        if numero_de_elementos == 0:\r\n            return 0\r\n        else:\r\n            return numero_de_elementos\r\n    def get_information(self):\r\n        print(self.items)\r\n# Instanciando un objeto de la clase Cola\r\ncola1 = Cola()\r\n# Usando sus metodos:\r\n## Anadiendo elementos\r\ncola1.add(\"Primer elemento\")\r\ncola1.add(2)\r\ncola1.add(False)\r\n## Obteniendo el numero de elementos:\r\nnumero_de_elementos_de_la_cola = cola1.number_of_elements()\r\nprint(f\"Este es el numero de elementos de la cola iniciada: {numero_de_elementos_de_la_cola}\")\r\n## Conseguiendo los elementos de la cola:\r\ncola1.get_information()\r\n## Eliminando el elemento:\r\nelemento = cola1.delete()\r\nprint(f\"Elemento eliminado: {elemento}\")\r\n## Conseguiendo los elementos de la cola actual:\r\nprint(f\"Estructura actual de la cola:\")\r\ncola1.get_information()"
  },
  {
    "path": "Roadmap/08 - CLASES/python/BrianSilvero.py",
    "content": "\"\"\"\nEjercicio\n\"\"\"\n\nclass Programer:\n    apellido:str = None\n    \n    def __init__(self,name: str, age: int, lenguaje: list):\n        self.name = name\n        self.age = age\n        self.lenguaje = lenguaje\n        \n    def print(self):\n        print(f\"Nombre: {self.name} | Apellido: {self.apellido} Edad: {self.age} | Lenguaje: {self.lenguaje}\")\n        \nmy_programador = Programer(\"Brian\", 27,[\"Python\", \"JavaScript\"])\nmy_programador.print()\nmy_programador.apellido = \"Silvero\"\nmy_programador.print()\nmy_programador.age = 28\nmy_programador.print()\n\n\n\"\"\"\nExtra\n\"\"\"\n\n# LIFO\n\nclass Stack:\n    def __init__(self):\n        self.stack = []\n        \n    def push(self,item):\n        self.stack.append(item)\n        \n    def pop(self):\n        if self.count() == 0:\n            return None\n        return self.stack.pop()\n\n    def count(self):\n        return len(self.stack)\n\n    def print(self):\n        for item in reversed(self.stack):\n            print(item)\n            \nmy_stack = Stack()\nmy_stack.push(\"A\")\nmy_stack.push(\"B\")\nmy_stack.push(\"C\")\nprint(my_stack.count())\nmy_stack.print()\n\nprint(\"-----------------------------------------------------------\")\n# FIFO\n\nclass Cola:\n    def __init__(self):\n        self.cola = []\n    \n    def push(self,item):\n        self.cola.append(item)\n        \n    def pop(self):\n        if self.count() == 0:\n            return None\n        self.cola.pop(0)\n        \n    def count(self):\n        return len(self.cola)\n    \n    def print(self):\n        for item in self.cola:\n            print(item)\n            \nmy_cola = Cola()\nmy_cola.push(\"F\")\nmy_cola.push(\"G\")\nmy_cola.push(\"H\")\nprint(my_cola.count())\nmy_cola.print()\nmy_cola.pop()\nmy_cola.pop()\nmy_cola.pop()\nprint(my_cola.count())\nmy_cola.print()"
  },
  {
    "path": "Roadmap/08 - CLASES/python/C-Gabs.py",
    "content": "'''Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.'''\n\n #Clases\n\nclass Programador:\n    def __init__(self, nombre, apellido, lenguajes) -> None:\n      self.nombre = nombre\n      self.apellido = apellido\n      self.lenguajes = lenguajes\n    librerias = None\n\n    def programar(self):\n      print(f\"{self.nombre} {self.apellido} está practicando clases con {self.lenguajes}\")\n\n    def datos(self):\n       print(f\"Datos del programador: Nombre:{self.nombre}, apellido:{self.apellido}, lenguajes:{self.lenguajes}, librerias:{self.librerias}\")\n\nmy_programador = Programador(\"Brais\",\"Moure\",[\"Kotlin\",\"Swift\"])\nprint(f\"{my_programador.nombre} programa en los lenguajes {my_programador.lenguajes}\")\nmy_programador.datos()\n\nyo = Programador(f\"Gabriel\",\"Castro\",\"Python\")\nyo.programar()\nyo.datos()\nyo.librerias = [\"Pandas\",\"Numpy\"]\nyo.lenguajes = [\"Python\",\"SQL\"]\nyo.datos()\n\n#Reto extra\n\nclass Pila:\n    def __init__(self,lista) -> None:\n      self.lista = lista\n    def pop(self):\n        if len(self.lista) == 0:\n           print(\"La pila está vacia\")\n        else:   \n            return self.lista.pop()\n      \n    def push(self,element):\n        self.lista.append(element)\n      \n    def imprimir(self):\n        for elemento in self.lista[::-1]:\n            print(elemento)\n    \n    def cantidad_elementos(self):\n       print(len(self.lista))\n\npila = Pila([1,2,3])\npila.imprimir()\npila.pop()\npila.imprimir()\npila.push(4)\npila.imprimir()\npila.cantidad_elementos()\n\n\nclass Cola:\n    def __init__(self,lista) -> None:\n        self.lista = lista\n    \n    def enqueue(self,element):\n        self.lista.insert(0,element)\n    \n    def dequeue(self):\n        if len(self.lista) == 0:\n            print(\"Cola vacía\")\n        else:\n            return self.lista.pop()\n    \n    def imprimir(self):\n        for elemento in self.lista:\n            print(elemento)\n    \n    def cantidad_elementos(self):\n        print(len(self.lista))\n\ncola = Cola([\"a\",\"b\",\"c\"])\ncola.imprimir()\ncola.dequeue()\ncola.imprimir()\ncola.enqueue(\"d\")\ncola.imprimir()\ncola.cantidad_elementos()"
  },
  {
    "path": "Roadmap/08 - CLASES/python/CaveroBrandon.py",
    "content": "\"\"\"EJERCICIO:\n- Explora el concepto de clase y crea un ejemplo que implemente un inicializador, atributos y una función que los imprima (teniendo en cuenta las posibilidades de tu lenguaje).\n- Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos utilizando su función.\n\"\"\"\n\n\nclass Doctor:\n    office = '101'\n\n    def __init__(self, specialty, name, age):\n        self.specialty = specialty\n        self.name = name\n        self.age = age\n\n    def show_psychology_doctor(self):\n        return (f\"Psychology doctor's information:\\n\"\n                f\"Name: {self.name}\\n\"\n                f\"Age: {self.age}\")\n\n    def show_doctor(self):\n        return (f\"**************************************\\n\"\n                f\"{self.specialty} doctor's information:\\n\"\n                f\"Name: {self.name}\\n\"\n                f\"Age: {self.age}\\n\"\n                f\"Office: {self.office}\")\n\n\ndef menu():\n    print('**************************************\\n'\n          'Select the specialty: \\n'\n          '1. Psychology\\n'\n          '2. Traumatology\\n'\n          '3. Exit')\n    try:\n        option = int(input('Option: '))\n        if option == 1:\n            name = input('Name: ')\n            age = input('Age: ')\n            if age.isdigit():\n                psychology_doctor = Doctor(specialty='Psychology',\n                                           name=name,\n                                           age=age)\n                print(psychology_doctor.show_doctor())\n            else:\n                print('Try again, enter a correct value')\n            menu()\n        elif option == 2:\n            name = input('Name: ')\n            age = input('Age: ')\n            if age.isdigit():\n                traumatology_doctor = Doctor(specialty='Traumatology',\n                                           name=name,\n                                           age=age)\n                print(traumatology_doctor.show_doctor())\n            else:\n                print('Try again, enter a correct value')\n            menu()\n        elif option == 3:\n            pass\n        else:\n            print('Enter a correct option')\n            menu()\n    except ValueError:\n        print('Enter a valid option')\n        menu()\n\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\nImplementa dos clases que representen las estructuras de Pila y Cola (estudiadas en el ejercicio número 7 de la ruta de estudio)\n- Deben poder inicializarse y disponer de operaciones para añadir, eliminar, retornar el número de elementos e imprimir todo su contenido.\"\"\"\n\n\ndef menu_stack():\n    print('**************************************\\n'\n          'MENU FOR STACK: \\n'\n          '1. Append a value\\n'\n          '2. Remove a value\\n'\n          '3. Count elements\\n'\n          '4. Print all content\\n'\n          '5. Exit')\n    try:\n        option = int(input('Option: '))\n        if option == 1:\n            value = input('Enter the value: ')\n            new_list.element_append(value)\n            menu_stack()\n        elif option == 2:\n            new_list.remove_element()\n            menu_stack()\n        elif option == 3:\n            print(f'The quantity of elements is: {new_list.element_count()}')\n            menu_stack()\n        elif option == 4:\n            new_list.print_all()\n            menu_stack()\n        elif option == 5:\n            pass\n        else:\n            print('Enter a correct option')\n            menu_stack()\n    except ValueError:\n        print('Enter a valid option')\n        menu_stack()\n\n\ndef menu_queue():\n    print('**************************************\\n'\n          'MENU FOR QUEUE: \\n'\n          '1. Append a value\\n'\n          '2. Remove a value\\n'\n          '3. Count elements\\n'\n          '4. Print all content\\n'\n          '5. Exit')\n    try:\n        option = int(input('Option: '))\n        if option == 1:\n            value = input('Enter the value: ')\n            new_queue.element_append(value)\n            menu_queue()\n        elif option == 2:\n            new_queue.remove_element()\n            menu_queue()\n        elif option == 3:\n            print(f'The quantity of elements is: {new_queue.element_count()}')\n            menu_queue()\n        elif option == 4:\n            new_queue.print_all()\n            menu_queue()\n        elif option == 5:\n            pass\n        else:\n            print('Enter a correct option')\n            menu_queue()\n    except ValueError:\n        print('Enter a valid option')\n        menu_queue()\n\n\nclass Stack:\n    def __init__(self):\n        self.stack = list()\n\n    def element_append(self, element):\n        self.stack.append(element)\n        print(f'The list is {self.stack}')\n\n    def remove_element(self):\n        if len(self.stack) == 0:\n            print('The list is empty, add at least one value first')\n            return\n        else:\n            try:\n                print(f'The current list is: {self.stack}')\n                position_to_remove = int(input('Which position you want to remove: '))\n                self.stack.pop(position_to_remove)\n                print(f'The list after removing the element is: {self.stack}')\n            except IndexError:\n                print('The position does not exist, please try again')\n                new_list.remove_element()\n            except ValueError:\n                print('Select a correct position')\n                new_list.remove_element()\n\n    def element_count(self):\n        return len(self.stack)\n\n    def print_all(self):\n        copy_list = self.stack.copy()\n        print('**** Recovering the information LIFO ****')\n        print(f'The list is: {self.stack}')\n        while len(copy_list) != 0:\n            removed_value = copy_list.pop()\n            print(f'The value recovered is \\'{removed_value}\\', the list is now: {copy_list}')\n\n\nclass Queue:\n    def __init__(self):\n        self.queue = list()\n\n    def element_append(self, element):\n        self.queue.append(element)\n        print(f'The list is {self.queue}')\n\n    def remove_element(self):\n        if len(self.queue) == 0:\n            print('The list is empty, add at least one value first')\n            return\n        else:\n            try:\n                print(f'The current list is: {self.queue}')\n                position_to_remove = int(input('Which position you want to remove: '))\n                self.queue.pop(position_to_remove)\n                print(f'The list after removing the element is: {self.queue}')\n            except IndexError:\n                print('The position does not exist, please try again')\n                new_queue.remove_element()\n            except ValueError:\n                print('Select a correct position')\n                new_queue.remove_element()\n\n    def element_count(self):\n        return len(self.queue)\n\n    def print_all(self):\n        copy_list = self.queue.copy()\n        print('**** Recovering the information FIFO ****')\n        print(f'The list is: {self.queue}')\n        while len(copy_list) != 0:\n            removed_value = copy_list.pop(0)\n            print(f'The value recovered is \\'{removed_value}\\', the list is now: {copy_list}')\n\n\nnew_list = Stack()\nnew_queue = Queue()\n\nmenu()\nmenu_stack()\nmenu_queue()\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/CesarCarmona30.py",
    "content": "'''\n  EJERCICIO\n'''\n\nclass Animal:\n  def __init__(self, name, race):\n    self.name = name\n    self.race = race\n\n  def __str__(self):\n    return f'Nombre: {self.name}, Raza: {self.race}'  \n\nclass Dog(Animal):\n  def __init__(self, name, race):\n    super().__init__(name, race)\n\n  def sound(self):\n    print(f\"{self.name} ladrando!!\")\n\nclass Cat(Animal):\n  def __init__(self, name, race):\n    super().__init__(name, race)\n\n  def sound(self):\n    print(f\"{self.name} maullando!!\")\n\ndef animalSound(animal):\n  animal.sound()\n\n\nmanchas = Cat(\"Manchas\", \"Calicó\")\nfirulais = Dog(\"Firulais\", \"Labrador\")\n\nanimalSound(manchas)\nanimalSound(firulais)\n\nprint(f'Manchas: {manchas.__str__()}')\nprint(f'Manchas es un perro?: {isinstance(manchas, Dog)}')\nprint(f'Manchas es un gato?: {isinstance(manchas, Cat)}')\nprint(f'Manchas es un animal?: {isinstance(manchas, Animal)}')\nprint(f'Firulais: {firulais.__str__()}')\nprint(f'Firulais es un perro?: {isinstance(firulais, Dog)}')\nprint(f'Firulais es un gato?: {isinstance(firulais, Cat)}')\nprint(f'Firulais es un animal?: {isinstance(firulais, Animal)}')\n\n'''\n  EXTRA\n'''\n\nclass Stack:\n\n  def __init__(self):\n    self.data = []\n\n  def push(self, element):\n    self.data.append(element)\n\n  def pop(self):\n    try:\n      element = self.data.pop()\n    except IndexError as e:\n      print(f'Error: {type(e).__name__}, empty stack')\n      return\n    print(f'Stack element out: {element}')\n\n  def itemsNumber(self):\n    return len(self.data)\n\n  def showData(self):\n    print(f'Stack: {self.data}')\n\nclass Queue:\n\n  def __init__(self):\n    self.data = []\n\n  def enqueue(self, element):\n    self.data.append(element)\n\n  def dequeue(self):\n    try:\n      element = self.data.pop(0)\n    except IndexError as e:\n      print(f'Error: {type(e).__name__}, empty queue')\n      return\n    print(f'Queue element out: {element}')\n\n  def itemsNumber(self):\n    return len(self.data)  \n\n  def showData(self):\n    print(f'Queue: {self.data}')\n\nveggies = Stack()\nveggies.push('Cucumber')\nveggies.push('Radish')\nveggies.push('Tomato')\nveggies.push('Orange')\nveggies.push('Apple')\nprint(f'Cantidad de vegetales: {veggies.itemsNumber()}')\nveggies.showData()\nveggies.pop()\nveggies.pop()\nveggies.showData()\nprint(f'Cantidad de vegetales: {veggies.itemsNumber()}')\n\nfruits = Queue()\nfruits.enqueue('Banana')\nfruits.enqueue('Melon')\nfruits.enqueue('Strawberry')\nfruits.enqueue('Onion')\nfruits.enqueue('Garlic')\nprint(f'Cantidad de frutas: {fruits.itemsNumber()}')\nfruits.showData()\nfruits.dequeue()\nfruits.dequeue()\nfruits.showData()\nprint(f'Cantidad de frutas: {fruits.itemsNumber()}')"
  },
  {
    "path": "Roadmap/08 - CLASES/python/Complex303.py",
    "content": "\"\"\"\nClases\n\"\"\"\n\n\n# Definimos una clase llamada Programmer\nclass Programmer:\n\n    # Atributo de clase: se comparte entre todas las instancias, pero aquí no se usa directamente\n    surname: str = None\n\n    # Método constructor que se ejecuta cuando se crea un objeto de esta clase\n    def __init__(self, name: str, age: int, language: list):\n        # Atributo de instancia: guarda el nombre\n        self.name = name\n        # Atributo de instancia: guarda la edad\n        self.age = age\n        # Atributo de instancia: guarda la lista de lenguajes\n        self.language = language\n\n    # Método para imprimir los datos del objeto de forma ordenada\n    def print(self):\n        print(f\"Nombre: {self.name} | Apellido: {self.surname} | Edad: {self.age} | Lenguajes: {self.language}\")\n\n\n# Creamos una instancia (objeto) de la clase Programmer con nombre, edad y lista de lenguajes\nmy_class = Programmer('Eddy', 24, ['Python', 'C#', 'Java'])\n\n# Llamamos al método print para mostrar los datos actuales\nmy_class.print()\n\n# Asignamos un valor al atributo surname del objeto (aunque originalmente es un atributo de clase)\nmy_class.surname = 'Complex'\n\n# Modificamos el valor de la edad\nmy_class.age = 25\n\n# Añadimos un nuevo lenguaje a la lista language\nmy_class.language.append('SQL')\n\n# Volvemos a mostrar los datos actualizados\nmy_class.print()\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\"\"\"\n\n\n#PILA (LIFO)\n\nclass Stack:\n\n    def __init__(self):\n        self.stack = []\n\n    def push(self, item):\n        self.stack.append(item)\n\n    def pop(self):\n        if self.count() == 0:\n            return None\n        return self.stack.pop()\n\n    def count(self):\n        return len(self.stack)\n    \n    def print(self):\n        for item in reversed(self.stack):\n            print(item)\n    \n\nmy_stack = Stack()\nmy_stack.push(2)\nmy_stack.push(4)\nmy_stack.push(6)\nmy_stack.push(8)\nprint(my_stack.count())\nmy_stack.print()\nprint(my_stack.pop())\nprint(my_stack.count())\nmy_stack.print()\n\n\nprint(\"==========================\")\n#COLA(FIFO)\n\nclass Queue:\n\n    def __init__(self):\n        self.queue = []\n\n    def enqueue(self, item):\n        self.queue.append(item)\n\n    def deenqueue(self):\n        if self.count() == 0:\n            return None\n        return self.queue.pop(0)\n\n    def count(self):\n        return len(self.queue)\n    \n    def print(self):\n        for item in (self.queue):\n            print(item)\n\n\nmy_queue = Queue()\nmy_queue.enqueue('A')\nmy_queue.enqueue('B')\nmy_queue.enqueue('C')\nprint(f\"Cantidad de cola: {my_queue.count()} \")\nmy_queue.print()\nprint(f\"Siguiente en la cola: {my_queue.deenqueue()}\")\nmy_queue.print()\n\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/DaniQB99.py",
    "content": "\"\"\"\nEJERCICIO:\nExplora el concepto de clase y crea un ejemplo que implemente un \ninicializador, atributos y una funcion que los imprima (teniendo en \ncuenta las posibilidades de tu lenguaje).\nUna vez implementada, creala, establece sus parametros, modificalos e\nimprimelos utilizando una funcion.\n\"\"\"\n\n\n# POO (Programacion Orientada a Objetos.)\n\nclass Animal:\n\n    color: str = None\n\n    def __init__(self, nombre, edad, raza):\n        self.nombre = nombre\n        self.edad = edad\n        self.raza = raza\n\n    def print_animal(self):\n        print(f\"Nombre: {self.nombre} | Edad: {self.edad} | Color: {self.color} | Raza: {self.raza}\")\n\nmy_animal = Animal(\"Shena\", 5, \"Perro\")\nmy_animal.color = \"Blanco\"\nmy_animal.print_animal()\nmy_animal.edad = 6\nmy_animal.print_animal()\n\n\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n- Implementa dos clases que representen las estructuras de Pila y \nCola (estudiadas en el ejercicio numero 7 de la ruta de estudio)\n- Deben poder inicializarse y disponer de operaciones para añadir, \neliminar, retornar el número de elementos e imprimir todo su \ncontenido.\n\"\"\"\n\nprint('\\n\\n\\n--- EJERCICIO EXTRA ---\\n')\n\n\n#LIFO\nclass Pila:\n\n    def __init__(self): # Inicializador\n        self.lista = []\n\n    def añadir(self, numero): # Añadir atributo\n        self.lista.append(numero)\n        print('Atributo añadido')\n\n    def eliminar(self): # Eliminar atributo\n        if len(self.lista) == 0:\n            return None \n        else:\n            return self.lista.pop()\n\n    def contar(self): # Contar atributo\n        return 'Atributos: ' + str(len(self.lista))\n    \n    def imprimir(self): #Imprimir atributos\n        for item in reversed(self.lista):\n            print(item)\n\nmy_pila = Pila()\nmy_pila.añadir('A')\nmy_pila.añadir('B')\nmy_pila.añadir('C')\nmy_pila.imprimir()\nprint(my_pila.contar())\nprint(my_pila.eliminar())\nprint(my_pila.contar())\nprint(my_pila.eliminar())\nprint(my_pila.eliminar())\nprint(my_pila.contar())\n\n\n\n# FIFO\nclass Cola:\n\n    def __init__(self): # Inicializador\n        self.cola = []\n    \n    def equeue(self, item): # Encolar atributo\n        self.cola.append(item)\n\n    def deequeue(self): # Desencolar atributo\n        if len(self.cola) == 0:\n            return None\n        self.cola.pop(0)\n\n    def contar(self): # Contar atributo\n        return len(self.cola)\n    \n    def imprimir(self): #Imprimir atributos\n        print(self.cola)\n\nmy_cola = Cola()\nmy_cola.equeue('A')\nmy_cola.equeue('B')\nmy_cola.equeue('C')\nmy_cola.imprimir()\nprint(my_cola.contar())\nprint(my_cola.deequeue())\nprint(my_cola.contar())\nprint(my_cola.deequeue())\nprint(my_cola.deequeue())\nprint(my_cola.contar())\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/Daparradom.py",
    "content": "### 08-CLASES ###\n\nclass animal :\n    def __init__(self,name : str ,grupo : str):  \n        self.name = name\n        self.grupo = grupo \n\n    def presentacion (self) :\n        print(f\"Mi animal es un {self.name} y es un {self.grupo}\")\n\n\n\nmy_animal = animal(\"Leon\", \"Mamifero\")\n\nmy_animal.presentacion()\n\nmy_second_animal = animal (\"Sapo\" , \"Anfibio\")\n\nmy_second_animal.presentacion()\n\n\nclass cola :\n    def __init__(self):\n        self.elementos = []\n    \n    def vacio (self) :\n        if len(self.elementos) == 0 :\n            return True\n        else:\n            return False\n    def añadir (self, elemento) :\n        self.elementos.append(elemento)\n    def eliminar (self) :\n        if self.vacio() == False :\n            self.elementos.pop(0)\n        else:\n            print(\"El conjunto de elementos de la cola esta vacio\")\n    def show (self) :\n        for item in self.elementos:\n            print(item)\n\nmi_cola = cola()\n\nmi_cola.añadir(\"Hola\")\nmi_cola.añadir(\"python\")\nmi_cola.añadir(\"te saluda\")\nmi_cola.añadir(\"David\")\n\nmi_cola.show()\n\nmi_cola.eliminar()\n\nmi_cola.show()\n\nmi_cola.eliminar()\n\nmi_cola.show()\n\n\nprint(\"*******************************************\\n\")\nclass pila :\n    def __init__(self):\n        self.elementos = []\n    \n    def vacio (self) :\n        if len(self.elementos) == 0 :\n            return True\n        else:\n            return False\n    def añadir (self, elemento) :\n        self.elementos.append(elemento)\n    def eliminar (self) :\n        if self.vacio() == False :\n            self.elementos.pop()\n        else:\n            print(\"El conjunto de elementos de la pila esta vacio\")\n    def show (self) :\n        for item in reversed(self.elementos):\n            print(item)\n\n\nmi_pila = pila()\n\nmi_pila.añadir(\"Hola\")\nmi_pila.añadir(\"python\")\nmi_pila.añadir(\"te saluda\")\nmi_pila.añadir(\"David\")\n\nmi_pila.show()\n\nmi_pila.eliminar()\n\nmi_pila.show()\n\nmi_pila.eliminar()\n\nmi_pila.show()"
  },
  {
    "path": "Roadmap/08 - CLASES/python/DataCiriano.py",
    "content": "\"\"\"\n* EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n\"\"\"\n\nclass Animal():\n    def __init__(self, nombre:str, especie:str, raza:str, edad:int, sexo:str, color:str):\n        self.nombre = nombre\n        self.especie = especie\n        self.raza = raza\n        self.edad = edad\n        self.sexo = sexo\n        self.color = color\n        \n    def caracteristicas(self):\n        print(f\"{self.nombre.capitalize()} es un {self.especie} de raza {self.raza}.\")\n        print(f\"Tiene {self.edad} años de edad, es {self.sexo} y es de color {self.color}.\")\n        \n    def modificar_atributos(self, nuevo_nombre=None, nueva_edad=None, nuevo_color=None):\n        if nuevo_nombre is not None:\n            self.nombre = nuevo_nombre\n        if nueva_edad is not None:\n            self.edad = nueva_edad\n        if nuevo_color is not None:\n            self.color = nuevo_color\n        \n        \n        \n#Crear instancia de clase          \nsnoopy = Animal(\"snoopy\", \"perro\", \"beagle\", 10, \"macho\", \"tricolor\")\nsnoopy.caracteristicas()\n#Modificar los atributos de la calse 'Snoopy'\nsnoopy.modificar_atributos(\"Snoopyus\", 12, \"negro con blanco\")\nsnoopy.caracteristicas()\n\n#Crear instancia de clase\nfelix = Animal(\"felix\", \"gato\", \"común\", 5, \"macho\", \"blanco y negro\")\nfelix.caracteristicas()\n#Modificar los atributos de la clase 'Felix el gato'\nfelix.modificar_atributos(\"felix el gato\", 7, \"negro\" )\nfelix.caracteristicas()\n\n\n#-----EXTRA-----\n\n#Clase que simula un pila de libros\n\nclass PilaLibros:\n    \n    def __init__(self):\n        self.pila = []\n    \n    def añadir(self, libro):\n        self.libro = libro\n        self.pila.append(self.libro)\n    \n    def eliminar(self):\n        try:\n            libro_eliminado = self.pila.pop()\n            print(f\"Se elimino el libro {libro_eliminado}\")\n        except IndexError:\n            print(\"No se puedo eliminar ningún libro ya que la Pila está vacía.\")\n    \n    def elementos(self):\n        print(f\"La pila contiene un total de {len(self.pila)} libros.\")\n    \n    def imprimir(self):\n        print(f\"Estos son los libros almacenados en la pila: {self.pila}\")\n    \n#Crear instancia de clase\ncuentos = PilaLibros()\n\n#Uso de los métodos de la clase\ncuentos.añadir(\"Blancanieves y los 7 enanitos\")\ncuentos.añadir(\"Perter Pan\")\n\ncuentos.elementos()\n\ncuentos.imprimir()\n\ncuentos.eliminar()\ncuentos.eliminar()\ncuentos.eliminar() #Arroja el mensaje de error de que la Pila está vacía.\n\n\n\n#Clase que simula una cola de clientes que realizan pedidos en una cafetería y son atendidos en orden de llegada\n\nclass ColaClientes:\n    \n    def __init__(self):\n        self.cola = []\n        \n    def añadir(self, nombre_cliente,):\n        self.nombre_cliente = nombre_cliente\n        self.cola.append(self.nombre_cliente)\n    \n    def eliminar(self):\n        try:\n            pedido_eliminado = self.cola.pop(0)\n            print(f\"Se eliminó el pedido {pedido_eliminado}\")\n        except IndexError:\n            print(\"No se puedo eliminar ningún pedido ya que la Cola está vacía.\")\n    \n    def elementos(self):\n        print(f\"La cola contiene un total de {len(self.cola)} pedidos.\")\n    \n    def imprimir(self):\n        print(f\"Estos son los pedidos en curso: {self.cola}\")\n        \n        \n#Crear instancia de clase para simular una cola de clientes que realizan pedidos en una cafetería en prden de llegada\npedidos = ColaClientes()\n\n#Uso de los métodos de la clase\npedidos.añadir(\"Juan Rodríguez - Café con leche sin lactosa\")\npedidos.añadir(\"Ana García - Café con leche + tarta chocolate\")\npedidos.añadir(\"Luís Perez - Bodadillo jamón serrano\")\npedidos.añadir(\"Esther Coronado - Zumo naranja + sandwich huevo\")\n\npedidos.elementos()\n\npedidos.imprimir()\n\npedidos.eliminar()\n\npedidos.imprimir()\n\npedidos.eliminar()\npedidos.eliminar()\npedidos.eliminar()\npedidos.eliminar() #Arroja el mensaje de error de que la Cola está vacía.\n\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/Dkp-Dev.py",
    "content": "\"\"\"\n* EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n\"\"\"\n\nclass Programmer:\n\n    surname: str = None\n\n    def __init__(self, name: str, age: int, languages: list):\n        self.name = name\n        self.age = age\n        self.languages = languages\n\n    def print(self):\n        print(\n            f\"Nombre: {self.name} | Apellidos: {self.surname} | Edad: {self.age} | Lenguajes: {self.languages}\")\n\n\nmy_programmer = Programmer(\"Dkp\", 29, [\"Python\", \"Kotlin\", \"Java\"])\nmy_programmer.print()\nmy_programmer.surname = \"Dev\"\nmy_programmer.print()\nmy_programmer.age = 30\nmy_programmer.print()\n\n\"\"\"\n DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n\"\"\"\n\n# LIFO\n\n\nclass Stack:\n\n    def __init__(self):\n        self.stack = []\n\n    def push(self, item):\n        self.stack.append(item)\n\n    def pop(self):\n        if self.count() == 0:\n            return None\n        return self.stack.pop()\n\n    def count(self):\n        return len(self.stack)\n\n    def print(self):\n        for item in reversed(self.stack):\n            print(item)\n\n\nmy_stack = Stack()\nmy_stack.push(\"Primero\")\nmy_stack.push(\"Segundo\")\nmy_stack.push(\"Ultimo\")\nprint(my_stack.count())\nmy_stack.print()\nmy_stack.pop()\nprint(my_stack.count())\nprint(my_stack.pop())\nprint(my_stack.pop())\nprint(my_stack.pop())\nprint(my_stack.count())\n\n\n# FIFO\n\n\nclass Queue:\n\n    def __init__(self):\n        self.queue = []\n\n    def enqueue(self, item):\n        self.queue.append(item)\n\n    def dequeue(self):\n        if self.count() == 0:\n            return None\n        return self.queue.pop(0)\n\n    def count(self):\n        return len(self.queue)\n\n    def print(self):\n        for item in self.queue:\n            print(item)\n\n\nmy_queue = Queue()\nmy_queue.enqueue(\"Primero\")\nmy_queue.enqueue(\"Segundo\")\nmy_queue.enqueue(\"Ultimo\")\nprint(my_queue.count())\nmy_queue.print()\nmy_queue.dequeue()\nprint(my_queue.count())\nprint(my_queue.dequeue())\nprint(my_queue.dequeue())\nprint(my_queue.dequeue())\nprint(my_queue.count())\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/EmmanuelMMontesinos.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función. \n */\n\"\"\"\n# Clases\nprint(\"---Clases en Python---\")\n\nclass Bebida:\n    bebidas = 0\n    def __init__(self,nombre:str,precio:float,es_alcohol:bool) -> None:\n        self.nombre = nombre\n        self.precio = precio\n        self.es_alcohol = es_alcohol\n        Bebida.bebidas += 1\n        self.n_bebida = Bebida.bebidas\n    \n    def imprimir(self):\n        print(f\"Nombre: {self.nombre}\")\n        print(f\"Precio: {self.precio}\")\n        print(f\"Es Alcohol: {self.es_alcohol}\")\n        print(f\"Numero de Bebida: {self.n_bebida}\")\n        print(f\"Numero de Bebidas Totales: {Bebida.bebidas}\")\n        print(\"------\")\n        \n\ncocacola = Bebida(\"cocacola\",2.5,False)\ncafe = Bebida(\"cafe\",1.5,False)\ncerveza = Bebida(\"cerveza\",2,True)\n\ncocacola.imprimir()\ncafe.imprimir()\ncerveza.imprimir()\n\ncocacola.nombre = \"Cocacola Ligth\"\ncafe.precio = 1.2\ncerveza.es_alcohol = False\n\ncocacola.imprimir()\ncafe.imprimir()\ncerveza.imprimir()\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n\"\"\"\n# Pila\nclass Alumnos:\n    \n    def __init__(self) -> None:\n        self.elementos = []\n    \n    def añadir(self,entrada):\n        self.elementos.append(entrada)\n        \n    def eliminar(self):\n        antiguo = self.elementos.pop()\n        print(f\"{antiguo} ha sido eliminado\")\n        \n    def listado(self):\n        print(f\"Numero de Alumnos: {len(self.elementos)}\")\n        \n    def imprimir(self):\n        print(f\"{self.elementos}\")\n        print(\"------\")\n\nclase_1a = Alumnos()\nclase_1a.añadir(\"Juan\")\nclase_1a.añadir(\"Sergio\")\nclase_1a.añadir(\"Emmanuel\")\n\nclase_1a.listado()\nclase_1a.imprimir()\n\nclase_1a.eliminar()\nclase_1a.listado()\nclase_1a.imprimir()\n\n\n# Cola\n\nclass Restaurante:\n    clientes_consumiendo = 0\n    def __init__(self,n_personas) -> None:\n        Restaurante.clientes_consumiendo += 1\n        self.grupos = []\n        self.añadir(n_personas)\n\n    def añadir(self,n_personas):\n        self.grupos.append(n_personas)\n        \n    def eliminar(self):\n        if len(self.grupos) > 0:\n            self.grupos.pop(0)\n        else:\n            print(\"No hay grupos para eliminar\")\n        \n    def listar(self):\n        print(f\"Numeros de grupos: {len(self.grupos)}\")\n        \n    def imprimir(self):\n        print(f\"Grupos activos: {self.grupos}\")\n        \nbar_pepito = Restaurante(\"4\")\nbar_pepito.listar()\nbar_pepito.imprimir()\n\nbar_pepito.añadir(\"6\")\nbar_pepito.añadir(\"9\")\nbar_pepito.listar()\nbar_pepito.imprimir()\n\nbar_pepito.eliminar()\nbar_pepito.listar()\nbar_pepito.imprimir()"
  },
  {
    "path": "Roadmap/08 - CLASES/python/EricJoel-code.py",
    "content": "## Clases\n\n# Concepto: Una clase es una plantilla para crear objetos, que encapsula datos y comportamientos relacionados.\n\nclass Persona:\n    \n    apellido = None  # Atributo de clase compartido por todas las instancias\n    \n    def __init__(self, nombre, edad, ciudad):\n        self.nombre = nombre\n        self.edad = edad\n        self.ciudad = ciudad\n        \n    def imprimir_info(self):\n        print(f\"Nombre: {self.nombre}, Apellido: {self.apellido} Edad: {self.edad}, Ciudad: {self.ciudad}\")\n        \n# Crear instancias de la clase Persona\npersona1 = Persona(\"Alice\", 30, \"New York\")\npersona1.imprimir_info()\npersona1.apellido = \"Smith\" \npersona1.imprimir_info()\n\npersona2 = Persona(\"Bob\", 25, \"Los Angeles\")\npersona2.imprimir_info()\npersona2.edad = 26 \npersona2.imprimir_info()\n\n\n##Extra\n\n\"\"\"Implementa dos clases que representen las estructuras de Pila y Cola. \nDeben poder inicializarse y disponer de operaciones para añadir, eliminar,\nretornar el número de elementos e imprimir todo su contenido.\"\"\"\n\n#Pila/Stacks/LIFO (Last In, First Out)\n\nclass Pila:\n    def __init__(self):\n        self.elementos = []\n        \n    def agregar(self, elemento):\n        self.elementos.append(elemento)\n    \n    def eliminar(self):\n        if self.tamaño() > 0:\n            return self.elementos.pop()\n        return None\n    \n    def tamaño(self):\n        return len(self.elementos)\n    \n    def imprimir(self):\n        for elemento in reversed(self.elementos):\n            print(elemento)\n            \nmi_pilas = Pila()\nmi_pilas.agregar(1)\nmi_pilas.agregar(2)\nmi_pilas.agregar(3)\nmi_pilas.imprimir()\nprint(mi_pilas.tamaño())\nmi_pilas.eliminar()\nmi_pilas.eliminar()\nmi_pilas.eliminar()\nmi_pilas.eliminar()\nmi_pilas.eliminar()\nmi_pilas.imprimir()\nprint(mi_pilas.tamaño())\n\n#Cola/Queues/PIFO (First In, First Out)\n\nclass Cola:\n    def __init__(self):\n        self.elementos = []\n        \n    def agregar(self, elemento):\n        self.elementos.append(elemento)\n        \n    def eliminar(self):\n        if self.tamaño() > 0:\n            return self.elementos.pop(0)\n        return None\n    \n    def tamaño(self):\n        return len(self.elementos)\n    \n    def imprimir(self):\n        for elemento in self.elementos:\n            print(elemento)\n            \nmi_colas = Cola()\nmi_colas.agregar(10)\nmi_colas.agregar(20)\nmi_colas.agregar(30)\nmi_colas.imprimir()\nprint(mi_colas.tamaño())\nmi_colas.eliminar()\nmi_colas.eliminar()\nmi_colas.eliminar()\nmi_colas.eliminar()\nmi_colas.eliminar()\nmi_colas.eliminar()\nmi_colas.eliminar()\nmi_colas.imprimir()\nprint(mi_colas.tamaño())"
  },
  {
    "path": "Roadmap/08 - CLASES/python/FedeAirala.py",
    "content": "# Reto #08 Clases\n\n\n\"\"\"\n  EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n \"\"\"\n\nclass Persona:                                                  # Se crea la clase Persona\n                                                               \n    def __init__(self, name, surname) -> None:                  # Se inicializa la clase\n        self.name = name                                        # Creaciòn de atributos\n        self.surname = surname\n    \n    def printer(self):                                          # Función para imprimir \n        print (f\"Nombre y Apellido: {self.name}, {self.surname}\")\n\np1 = Persona(\"Jhon\",\"Python\")                                   # Creación de un objeto de la clase Persona\np2 = Persona (\"My\",\"SQL\")\np1.printer()                                                    # Llamada a función imprimir de la clase Persona\np2.printer()\np2.name = \"María\"                                               # Modificacón del objeto p2\np2.surname = \"DB\"\np2.printer()\n\n\n\"\"\"   \n DIFICULTAD EXTRA (opcional):\n\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n * \n\"\"\"\n\nclass Stack():\n\n    def __init__(self, items : list) -> list:\n        self.items = items\n    \n    def add(self,items):\n        self.items.append(items)\n\n    def remove(self):\n        if len (self.items) > 0:\n            self.items.remove(self.items[-1])\n        else:\n            print (\"Stack vacía\")\n    \n    def elements(self):\n        print (f\"Cantidad de elementos en Stack: {len(self.items)}\")\n    \n    def printer (self):\n        print (f\"Stack: {self.items}\")\n\n    \n\npila1 = Stack ([1,2,3])\npila1.printer()\npila1.elements()\npila1.add(4)\npila1.printer()\npila1.remove()\npila1.printer()\npila1.remove()\npila1.printer()\npila1.remove()\npila1.remove()\npila1.remove()\npila1.printer()\npila1.elements()\n\nclass Queue():\n    def __init__(self, items : list) -> list:\n        self.items = items\n    \n    def add(self,items):\n        self.items.append(items)\n\n    def remove(self):\n        if len (self.items) > 0:\n            self.items.remove(self.items[0])\n        else:\n            print (\"Queue vacía\")\n    \n    def elements(self):\n        print (f\"Cantidad de elementos en Queue: {len(self.items)}\")\n    \n    def printer (self):\n        print (f\"Queue: {self.items}\")\n\ncola1 = Queue ([\"A\",\"B\",\"C\"])\ncola1.printer()\ncola1.add(\"D\")\ncola1.printer()\ncola1.remove()\ncola1.printer()\ncola1.remove()\ncola1.printer()\ncola1.remove()\ncola1.remove()\ncola1.remove()\ncola1.printer()\ncola1.elements()"
  },
  {
    "path": "Roadmap/08 - CLASES/python/Gallitofast.py",
    "content": "class Persona:\n    def __init__(self,name,age):\n        self.name=name\n        self.age=age\n    \n    def printer(self):\n        print(f\"{self.name} is {self.age} years old!\")\n    \np1= Persona(\"Jose Miguel Gallo Zuno\",23)\np2= Persona(\"Monica Gabriela Zuno Ramirez\", 55)\np1.printer()\np2.printer()\np1.name=(\"Gallolobo\")\np1.age=(24)\np1.printer()\n\n\"\"\"   \n DIFICULTAD EXTRA (opcional):\n\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n * \n\"\"\"\nclass Pila:\n    def __init__(self):\n        self.items = []\n\n    def push(self, item):\n        self.items.append(item)\n\n    def pop(self):\n        if not self.is_empty():\n            return self.items.pop()\n        return None\n\n    def size(self):\n        return len(self.items)\n\n    def is_empty(self):\n        return len(self.items) == 0\n\n    def print_content(self):\n        print(\"Pila:\", self.items)\n\n\nclass Cola:\n    def __init__(self):\n        self.items = []\n\n    def enqueue(self, item):\n        self.items.append(item)\n\n    def dequeue(self):\n        if not self.is_empty():\n            return self.items.pop(0)\n        return None\n\n    def size(self):\n        return len(self.items)\n\n    def is_empty(self):\n        return len(self.items) == 0\n\n    def print_content(self):\n        print(\"Cola:\", self.items)\n\n#Pruebas\npilates= Pila()\npilates.push(\"Gallolobo\")\npilates.push(\"tontito\")\npilates.push(\"Hola\")\npilates.print_content()\npilates.pop()\npilates.print_content()\n\npopola=Cola()\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/Gordo-Master.py",
    "content": "\"\"\"\nClases\n\"\"\"\n\nclass Persona:\n\n    age: int = None\n\n    def __init__(self, name: str = \"Joy\", surname: str = \"Boy\") -> None:\n        self.name = name\n        self.surname = surname\n    \n    def data(self):\n        print(f\"Esta persona se llama {self.name} {self.surname} y tiene: {self.age} años\")\n\np1 = Persona(\"Gordo\", \"Master\")\n\np1.data()\n\np1.age = 29\np1.name = \"Pro\"\n\np1.data()\n\n\"\"\"\nEjercicio extra\n\"\"\"\n\nclass Stack:\n    \n    def __init__(self, *items):\n        self.stack = []\n        for i in items:\n            self.stack.append(i)\n    \n    def push(self, item):\n        self.stack.append(item)\n    \n    def pop(self):\n        if len(self.stack) == 0:\n            return None\n        return self.stack.pop()\n    \n    def count_items(self):\n        print(f\"El numero de elementos es: {len(self.stack)}\")\n    \n    def view_items(self):\n        for i in reversed(self.stack):\n            print(i)\n\nlanguages = Stack()\nlanguages.push(\"Python\")\nlanguages.push(\"C++\")\nlanguages.push(\"C#\")\nlanguages.push(\"Java\")\nlanguages.push(\"PHP\")\n\nlanguages.count_items()\nlanguages.view_items()\nprint(f\"Se saca el último elemento: {languages.pop()}\")\nlanguages.count_items()\nlanguages.view_items()\nprint(f\"Se saca el último elemento: {languages.pop()}\")\nprint(f\"Se saca el último elemento: {languages.pop()}\")\nprint(f\"Se saca el último elemento: {languages.pop()}\")\nprint(f\"Se saca el último elemento: {languages.pop()}\")\nprint(f\"Se saca el último elemento: {languages.pop()}\")\nlanguages.count_items()\nlanguages.view_items()\n\n\nclass Queue:\n    def __init__(self, *items) -> None:\n        self.queue = []\n        for i in items:\n            self.queue.append(i)\n    \n    def equeue(self, item) -> None:\n        self.queue.append(item)\n    \n    def deequeue(self):\n        if len(self.queue) == 0:\n            return None\n        return self.queue.pop(0)\n    \n    def count_items(self) -> None:\n        print(f\"El numero de elementos es: {len(self.queue)}\")\n    \n    def view_items(self) -> None:\n        for i in self.queue:\n            print(i)\n\nnumbers = Queue(10,20)\n\nnumbers.equeue(30)\nnumbers.count_items()\nnumbers.view_items()\nprint(numbers.deequeue())\nnumbers.count_items()\nnumbers.view_items()\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/Hyromy.py",
    "content": "# definicion de la clase \"Car\"\nclass Car:\n\n    # constructor de la clase\n    def __init__(self, color, marca, modelo): # self hace referencia a si mismo\n        \n        # declaracion e inicializacion de atributos\n        self.color = color\n        self.marca = marca\n        self.modelo = modelo\n\n    def imprimir(self): # metodo \"imprimir\"\n        print(f\"Soy un {self.marca} modelo {self.modelo} de color {self.color}\")\n\n# crear instancias de \"Car\" (crear objetos \"Car\")\ncoche_1 = Car(\"blanco\", \"HotWheels\", \"Terreneitor\")\ncoche_2 = Car(\"azul\", \"Transformer\", \"willy\")\n\n# ejecutar el metodo \"imprimir\" en ambos objetos\ncoche_1.imprimir()\ncoche_2.imprimir()\n\n# modificar coche_1\ncoche_1.color = \"naranja\"\ncoche_1.modelo = None\n\n# comprobar cambios\ncoche_1.imprimir()\n\n\n\n\"\"\"\n ---- DIFICULTAD EXTRA ----\n\"\"\"\n\nclass Pila:\n    def __init__(self, *items):\n        self.content = []\n\n        for item in items:\n            self.content.append(item)\n\n    def show(self):\n        pila = \"|\"\n        \n        for value in self.content:\n            pila += f\"{value}|\"\n\n        print(pila)\n\n    def add(self, item):\n        self.content.insert(0, item)\n\n    def pop(self):\n        if len(self.content) == 0:\n            print(\"No hay elementos por remover\")\n        else:\n            self.content.pop(0)\n\n    def len(self) -> int:\n        return len(self.content)\n\nclass Cola:\n    def __init__(self, *items):\n        self.content = []\n\n        for item in items:\n            self.content.append(item)\n\n    def show(self):\n        cola = \"-\"\n        \n        for value in self.content:\n            cola += f\"{value}-\"\n\n        print(cola)\n\n    def add(self, item):\n        self.content.append(item)\n\n    def pop(self):\n        if len(self.content) == 0:\n            print(\"No hay elementos por remover\")\n        else:\n            self.content.pop(0)\n\n    def len(self) -> int:\n        return len(self.content)\n\npila = Pila(\"A\")\nfor i in range(5, 10):\n    pila.add(i)\npila.show()\n\npila.pop()\npila.pop()\npila.show()\n\n\n\ncola = Cola(\"B\")\nfor i in range(5, 10):\n    cola.add(i)\ncola.show()\n\ncola.pop()\ncola.pop()\ncola.show()\n\nprint(cola.len())\ncola.pop()\nprint(cola.len())"
  },
  {
    "path": "Roadmap/08 - CLASES/python/Irenetitor.py",
    "content": "#Class\nclass User:\n\n    surname: str = None\n\n    def __init__(self, name: str, age: int, languages: list):\n        self.name = name\n        self.age = age\n        self.languages = languages\n\n    def profile(self):\n        print(f\"Name: {self.name} | Surname: {self.surname} | Age: {self.age} | Languages: {self.languages}\")\n\nmy_user = User(\"Antonia\", 45, [\"English\", \"Spanish\", \"French\"])\nmy_user.profile()\nmy_user.surname = \"Sanchez\"\nmy_user.languages = [\"English\", \"Spanish\", \"French\", \"Hindi\"]\nmy_user.profile()\n\n\n#Extra Exercise\n#LIFO\n\nclass Stack:\n    def __init__(self):\n        self.stack = []\n    \n    def push(self, item):\n        self.stack.append(item)\n    \n    def pop(self):\n        if self.count() > 0:\n            self.stack.pop()\n        else:\n            print(\"The list is empty, please add few items before delete it\")\n    \n    def count(self):\n        return len(self.stack)\n    \n    def print(self):\n        for item in reversed(self.stack):\n            print(item)\n\nmy_stack = Stack()\nmy_stack.push(\"The jungle book\")\nmy_stack.push(\"The lion king\")\nmy_stack.push(\"Coco\")\nprint(my_stack.count())\nmy_stack.print()\nmy_stack.pop()\nprint(my_stack.count())\n\n#FIFO\n\nclass Queue:\n\n    def __init__(self):\n        self.queue = []\n\n    def enqueue(self, item):\n        self.queue.append(item)\n\n    def dequeue(self):\n        if self.count() > 0:\n            self.queue.pop(0)\n        else:\n            print(\"The list is empty, please add few items before delete it\")\n\n    def count(self):\n        return len(self.queue)\n    \n    def print(self):\n        for item in self.queue:\n            print(item)\n\n\nmy_queue = Queue()\nmy_queue.enqueue(\"The Godfather\")\nmy_queue.enqueue(\"The Godfather 2\")\nmy_queue.enqueue(\"The Godfather 3\")\nprint(my_queue.count())\nmy_queue.print()\nmy_queue.dequeue()\nprint(my_queue.count())\nmy_queue.print()\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/JAFeito.py",
    "content": "class Pila:\n    def __init__(self):\n        self.pila =[]\n        \n    def push(self):\n        elemento = input(f\"Introduzca un elemento para añadir a la pila.\\n\")\n        self.pila.append(elemento)\n        \n    def pop(self):\n        if len(self.pila) == 0:\n            return None\n        return self.pila.pop()\n            \n    def count(self):\n        return len(self.pila)    \n        \n    def imprime(self):\n        print(self.pila)\n      \n      \nclass Cola:\n    def __init__(self):\n        self.cola = []\n        \n    def push(self):\n        elemento = input(f\"Introduzca un elemento para añadir a la pila.\\n\")\n        self.cola.append(elemento)\n        \n    def pop(self):\n        if len(self.cola) == 0:\n            return None\n        return self.cola.pop(0)\n            \n    def count(self):\n        return len(self.cola)    \n        \n    def imprime(self):\n        print(self.cola)    \n        \n                \n        \nmi_pila = Pila()     \nmi_pila .push()\nmi_pila .push()\nmi_pila .push()\nprint(mi_pila.count())\nmi_pila.imprime()\nmi_pila.pop()\nprint(mi_pila.count())\nmi_pila.imprime()\n\nmi_cola = Cola()     \nmi_cola .push()\nmi_cola .push()\nmi_cola .push()\nprint(mi_cola.count())\nmi_cola.imprime()\nmi_cola.pop()\nprint(mi_cola.count())\nmi_cola.imprime()"
  },
  {
    "path": "Roadmap/08 - CLASES/python/Jav-mol.py",
    "content": "### Clases ###\n\nclass MiClasePersona:\n    def __init__(self, nombre:str, apellido:str) -> None:\n        self.nombre = nombre\n        self.apellido = apellido\n    \n    def imprimir_atributos(self) -> None:\n        print(f'Atributos de la clase: \\n[{self.nombre} - {self.apellido}]')\n    \n    def __str__(self) -> str:\n        return f'Nombre: {self.nombre} - Apellido: {self.apellido}'\n    \n# Inicializando la clase\n\nmi_clase_persona = MiClasePersona('Javier', 'Molina')\n\nmi_clase_persona.imprimir_atributos() # Llamando una funcion\nprint(mi_clase_persona) # Por defecto se llama la funcion __str__ al imprimir el objeto\n\n\n# --- Extra ---\nclass NavegadorWeb():\n    def __init__(self) -> None:\n        self.web = ['https://github.com','/mouredev', '/roadmap-retos-programacion']\n        self.index = 1\n\n    def adelante(self):\n        print(self.index)\n        if self.index < len(self.web):\n            self.index += 1\n        print(\"\".join(self.web[0:self.index]))\n        cadena_guines()\n        \n    def atras(self):\n        if self.index > 1:\n            self.index -= 1\n        print(\"\".join(self.web[0:self.index]))\n        cadena_guines()\n    \n    def agregar_web(self, web):\n        self.web.append(web)\n        print(\"\".join(self.web))\n        cadena_guines()\n            \n            \nnavegador = NavegadorWeb()\n\ncadena_guines = lambda:print('-'*30)\n\nmenu = '''Adelate - Siguiente Pagina Web\nAtras - Anterior Pagina Web\nExit/q - Salir del Programa\n\"Cualquier-Cadena\" - Agrega una Nueva Pagina Web\n=> '''\n\noptions = {\n    'ad':navegador.adelante,\n    'at':navegador.atras,\n    'exit':False,\n    'q':False\n}\n\nwhile True:\n    cadena_guines()\n    option = input(menu).lower()\n    if not option in options.keys():\n        navegador.agregar_web(option)\n        continue\n    \n    x = options.get(option)\n\n    if not x:\n        break   \n    x()\n    print()\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/JesusAntonioEEscamilla.py",
    "content": "# #08 - Python -> Jesus Antonio Escamilla\n\n\"\"\"\nEJERCIÓ\n\"\"\"\n# Definición de la clase Persona\nclass Persona:\n    # Inicializador con atributos nombre y edad\n    def __init__(self, nombre, edad, ocupacion):\n        self.nombre = nombre\n        self.edad = edad\n        self.ocupacion = ocupacion\n\n    # Método para imprimir los atributos\n    def imprimir_informacion(self):\n        print(f\"Nombre: {self.nombre}, Edad: {self.edad}, Ocupación: {self.ocupacion}\")\n\n# Crear una instancia de la clase Persona\npersona1 = Persona(\"Jesus Antonio\", 30, \"Programador\")\n\nprint(\"CLASES\")\npersona1.imprimir_informacion()\n\n\n\n\"\"\"\nEXTRA\n\"\"\"\n# Ejemplos de CLASES con Pilas y Colas\nclass Pila:\n    def __init__(self):\n        self.items = []\n\n    def push(self, item):\n        self.items.append(item)\n\n    def pop(self):\n        if not self.is_empty():\n            return self.items.pop()\n        else:\n            return None\n\n    def is_empty(self):\n        return len(self.items) == 0\n\n    def size(self):\n        return len(self.items)\n\n    def print_stack(self):\n        print(self.items)\n\n\nclass Cola:\n    def __init__(self):\n        self.items = []\n\n    def enqueue(self, item):\n        self.items.append(item)\n\n    def dequeue(self):\n        if not self.is_empty():\n            return self.items.pop(0)\n        else:\n            return None\n\n    def is_empty(self):\n        return len(self.items) == 0\n\n    def size(self):\n        return len(self.items)\n\n    def print_queue(self):\n        print(self.items)\n\n\n# Ejemplo de uso:\nprint(\"\\nSTACK\")\npila = Pila()\npila.push(1)\npila.push(2)\npila.push(3)\npila.print_stack()\npila.pop()\npila.print_stack()\n\n\nprint(\"\\nQUEUE\")\ncola = Cola()\ncola.enqueue(\"A\")\ncola.enqueue(\"B\")\ncola.enqueue(\"C\")\ncola.print_queue()\ncola.dequeue()\ncola.print_queue()\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/JheisonQuiroga.py",
    "content": "\"\"\" 1. Clases \nLas clases son planos o modelos para la creacion de objetos\n\"\"\"\n# Syntaxys\nclass Person:\n    pass\n\nprint(Person)\n\n# Object Class\nclass Person:\n    \"\"\" A simple example class\"\"\"\n    name = \"Duban\" # class variable\n\n    def greet(self): # class Method\n        return f\"Hi there, i`m {self.name}\"\n    \np = Person()\nprint(p.greet()) # Hi there, i`m Duban\n\n# 1.1.Constructor Function\n\nclass Person:\n    def __init__(self):\n        # Automatically run\n        print(\"Creando mi primer objeto de la clase persona\")\n    \np = Person() # Creando mi primer objeto de la clase persona\n\n# 1.2. Atributtes and Methods\n\"\"\"\nUn atributo es una variable asociada a un objeto y un metodo es una funcion\ndentro de una clase que realiza alguna accion. Es decir es una funcion que puede ejecutar un\nobjeto\n\"\"\"\n\nclass Person:\n    def __init__(self, firstname, lastname, age, country):\n        self.fname = firstname\n        self.lname = lastname\n        self.age = age\n        self.country = country\n        self.skills = []\n\n    def person_info(self):\n        return f\"I'm {self.fname} {self.lname}, im {self.age}, and live in {self.country}\"\n    \n    def greet(self):\n        return \"Hello World\"\n    \n    def add_skill(self, skill):\n        self.skills.append(skill) \n\n\np = Person(\"Duban\", \"Quiroga\", 25, \"Colombia\")\nprint(p) # <__main__.Person object at 0x000001CB727E1910> id object\nprint(p.person_info())\nprint(p.greet()) # Hello World\np.add_skill(\"Python\")\np.add_skill(\"Java\")\nprint(p.skills) # ['Python', 'Java']\n\n\"\"\"\nExtra\n\"\"\"\n\nclass Stack: # Pilas\n    def __init__(self):\n        self.stack = []\n\n    def push(self, item):\n        self.stack.append(item)\n\n    def pop(self):\n        return self.stack.pop() if self.stack else 0\n        \n    def top(self): # Top of Stack (TOS)\n        return self.stack[-1]\n    \n    def len_stack(self):\n        return len(self.stack)\n    \n    def print_stack(self):\n        for item in reversed(self.stack):\n            print(item)\n\n    \n\nmy_stack = Stack()\nmy_stack.push(1)\nmy_stack.push(2)\nmy_stack.push(3)\nmy_stack.push(4)\nprint(my_stack.stack) # [1, 2, 3, 4]\nprint(my_stack.top()) # 4\nprint(my_stack.len_stack()) # 4\nmy_stack.print_stack()\n\n# Queue - FIFO (First in - First Out)\n\nclass Queue: \n    def __init__(self):\n        self.deque = []\n\n    def add(self, item):\n        self.deque.append(item)\n\n    def dequeue(self):\n        return self.deque.pop(0)if self.deque else None\n    \n    def len_queue(self):\n        return len(self.deque)\n    \n    def print_queue(self):\n        for item in self.deque:\n            if item:\n                print(item)\n\nqueue = Queue()\nqueue.add(\"A\")\nqueue.add(\"B\")\nqueue.add(\"C\")\nqueue.add(\"D\")\n\nqueue.print_queue()\n\nprint(queue.dequeue()) # A\nprint(queue.len_queue()) # 3\nqueue.print_queue() # B, C, D"
  },
  {
    "path": "Roadmap/08 - CLASES/python/JuanDAW37.py",
    "content": "\"\"\"\n* EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n\"\"\"\n\nclass Vehiculo:\n    color = \"None\"\n    \n    def __init__(self, marca:str, modelo:str, ruedas: int, cilindrada:int, potencia:int):\n        self.marca = marca\n        self.modelo = modelo\n        self.ruedas = ruedas\n        self.cilindrada = cilindrada\n        self.potencia = potencia\n    \n    def imprimir(self):\n        print(f\"Marca: {self.marca}, Modelo: {self.modelo}, Color: {self.color}, Ruedas {self.ruedas}, Cilindrada: {self.cilindrada}, Potencia: {self.potencia}\")\n        \nmi_coche = Vehiculo('Toyota', 'Auris', 4, 1500, 115)\nmi_coche.color = 'Azul'\nmi_coche.imprimir()\n\nmi_moto = Vehiculo('Vespa', 'GTS', 2, 300, 75)\nmi_moto.color = 'Verde'\nmi_moto.imprimir()\n\n# EXTRA\n# Pila, LIFO\nclass Pila:\n    def __init__(self):\n        self.contenido = []\n        \n    def anadir(self, item):\n        self.contenido.append(item)    \n        \n    def quitar(self):\n        if self.contar() > 0:\n            return self.contenido.pop() # Como es una pila, sacamos siempre el último elemento\n    \n    def contar(self):\n        return len(self.contenido)\n    \n    def imprimir(self):\n        for  item in reversed(self.contenido):\n            if isinstance(item, Vehiculo):\n                item.imprimir()\n            else:\n                print(item)\n            \nmi_pila = Pila()\nmi_pila.anadir(1)\nmi_pila.anadir(mi_moto)\nmi_pila.anadir('Juan')\nmi_pila.anadir(['A', 'B', 'C', 'D'])\nprint(mi_pila.contar())\nmi_pila.imprimir()\nmi_pila.quitar()\nprint(mi_pila.contar())\nmi_pila.imprimir()\n\n# Cola, FIFO\nclass Cola:\n    def __init__(self):\n        self.contenido = []\n    \n    def anadir(self, item):\n        self.contenido.append(item)\n    \n    def quitar(self):\n        if self.contar() > 0:\n            self.contenido.pop(0) #Como es una cola, sacamos siempre el primer elemento\n    \n    def contar(self):\n        return len(self.contenido)\n    \n    def imprimir(self):\n        for item in self.contenido:\n            if isinstance(item, Vehiculo):\n                item.imprimir()\n            else:\n                print(item)\n                \nmi_cola = Cola()\nmi_cola.anadir(3)\nmi_cola.anadir(mi_coche)\nmi_cola.anadir('Mónica')\nmi_cola.anadir(['E', 'F', 'G', 'H'])\nprint(mi_cola.contar())\nmi_cola.imprimir()\nmi_cola.quitar()\nprint(mi_cola.contar())\nmi_cola.imprimir()"
  },
  {
    "path": "Roadmap/08 - CLASES/python/KevinED11.py",
    "content": "from abc import ABC, abstractmethod\nfrom collections import deque\nfrom typing import Collection\n\n\nclass Person:\n    def __init__(self, name: str, surname: str, age: int) -> None:\n        self.__name = name\n        self.__surname = surname\n        self.__age = age\n\n    def full_info(self) -> str:\n        return f\"{self.__name} {self.__surname} - {self.__age} years\"\n\n    @property\n    def name(self) -> str:\n        return self.__name\n\n    @property\n    def surname(self) -> str:\n        return self.__surname\n\n    @property\n    def age(self) -> int:\n        return self.__age\n\n    @name.setter\n    def name(self, name: str) -> None:\n        self.__name = name\n\n    @age.setter\n    def age(self, age: int) -> None:\n        self.__age = age\n\n    @surname.setter\n    def surname(self, surname: str) -> None:\n        self.__surname = surname\n\n    def __str__(self) -> str:\n        name, surname, age = self.__name, self.__surname, self.__age\n        return f\"Person({name=} {surname=} {age=})\"\n\n\ndef create_person(name: str, surname: str, age: int) -> Person:\n    return Person(name, surname, age)\n\n\nclass Structure[T](ABC):\n    @abstractmethod\n    def push(self, element: T) -> None:\n        pass\n\n    @abstractmethod\n    def pop(self) -> T:\n        pass\n\n    @property\n    @abstractmethod\n    def elements(self) -> Collection[T]:\n        pass\n\n    def __str__(self) -> str:\n        return str(self.elements)\n\n    @property\n    def is_empty(self) -> bool:\n        return len(self.elements) == 0\n\n    @property\n    def length(self) -> int:\n        return len(self.elements)\n\n\nclass Queue[T](Structure[T]):\n    def __init__(self) -> None:\n        self.__elements: deque[T] = deque()\n\n    def push(self, element: T) -> None:\n        self.__elements += [element]\n\n    def pop(self) -> T:\n        return self.__elements.popleft()\n\n    @property\n    def elements(self) -> deque[T]:\n        return self.__elements\n\n\nclass Stack[T](Structure[T]):\n    def __init__(self) -> None:\n        self.__elements: list[T] = []\n\n    def push(self, element: T) -> None:\n        self.__elements += [element]\n\n    def pop(self) -> T:\n        return self.elements.pop()\n\n    @property\n    def elements(self) -> list[T]:\n        return self.__elements\n\n\ndef main() -> None:\n    kevin = create_person(name=\"kevin\", surname=\"dueñas\", age=23)\n    print(kevin.full_info())\n    print(kevin)\n\n    kevin.surname = \"asael\"\n    kevin.age = 24\n    print(kevin)\n    print(kevin.full_info())\n\n    # Generic queue\n    queue = Queue[int]()\n    queue.push(1)\n    queue.push(2)\n    queue.push(3)\n    print(queue.elements)\n    print(queue.pop())\n    print(queue)\n    print(queue.is_empty)\n    print(queue.length)\n\n    # Generic stack\n    stack = Stack[int]()\n    stack.push(1)\n    stack.push(2)\n    stack.push(3)\n    print(stack.elements)\n    print(stack)\n    print(stack.pop())\n\n    print(stack.elements)\n    print(stack)\n    print(stack.is_empty)\n    print(stack.length)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/Lio7master.py",
    "content": "#   EJERCICIO:\n#   Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n#   atributos y una función que los imprima (teniendo en cuenta las posibilidades\n#   de tu lenguaje).\n#   Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n#   utilizando su función.\n \n#   DIFICULTAD EXTRA (opcional):\n#   Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n#   en el ejercicio número 7 de la ruta de estudio)\n#   - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n#     retornar el número de elementos e imprimir todo su contenido.\n\n\n#Ejercicio\nclass Programmer: #Clase: Es la plantilla que define cómo deben ser los objetos. Especifica qué datos tienen y qué pueden hacer.\n\n    surname: str = None\n    def __init__(self, name: str, age: int, language: list):\n\n        self.name = name\n        self.age = age\n        self. language = language\n\n    def print(self):\n        print(\n            f'Nombre: {self.name}, | Apellido: {self.surname} | Edad: {self.age} | Lenguajes: {self.language} ')\n\nmy_programmer = Programmer(\"leo\", 31, ['python', 'js', 'sql'])\nmy_programmer.print()\nmy_programmer.surname = \"Limon\"\nmy_programmer.print()\n\nmy_programmer.age = 32\nmy_programmer.print()\n\n\n#LIFO\n#Extra\nclass Stack:\n    def __init__(self):\n        self.stack =[]\n    \n    def push(self, item):\n        self.stack.append(item)\n    \n    def pop(self):\n        if self.count() == 0:\n            return None\n        return self.stack.pop()\n    \n    def count(self):\n        return len(self.stack)\n    \n    def print(self):\n        for item in reversed(self.stack): #Tomamos los items a la inversa ya que se imprimira primero el ultimo item que entro que debe ser el primero en salir\n            print(item)\n\nmy_stack = Stack()\n\nmy_stack.push(\"A\")\nmy_stack.push(\"B\")\nmy_stack.push(\"C\")\nmy_stack.push(\"D\")\nprint(my_stack.count())\nmy_stack.print()\nmy_stack.pop()\nprint(my_stack.count())\nmy_stack.pop()\nmy_stack.pop()\nmy_stack.pop()\nmy_stack.pop()\nmy_stack.pop()\nprint(my_stack.count())\n\n\n#FIFO\n\nclass Queue:\n    def __init__(self):\n        self.queue = []\n\n    def equeue(self, item):\n        self.queue.append(item)\n\n    def dequeue(self):\n        if self.count() == 0:\n            return None\n        return self.queue.pop(0) #Colocamos 0 ya que en una cola sacamos el elemento primero en la lista y pop por definicion elimina el ultimo de la lista\n    \n    def count(self):\n        return len(self.queue)\n    \n    def print(self):\n        for item in self.queue:\n            print(item)\n\nmy_queue = Queue()\n\nmy_queue.equeue(\"A\")\nmy_queue.equeue(\"B\")\nmy_queue.equeue(\"C\")\nmy_queue.equeue(\"D\")\nprint(my_queue.count())\nmy_queue.print()\nmy_queue.dequeue()\nmy_queue.count()\nmy_queue.dequeue()\nmy_queue.dequeue()\nprint(my_queue.count())\nmy_queue.print()\nmy_queue.dequeue()\nprint(my_queue.count())"
  },
  {
    "path": "Roadmap/08 - CLASES/python/LittleMabbit.py",
    "content": "# Clases\n# Las clases deben estar escritas en CamelCase, ej: ClaseProgramador, HuesosDelCuerpo.\n\nclass Programmer:\n\n  surname: str = None # Se pueden crear variables utilizables a futuro.\n  def __init__(self, name, age, languages):\n    self.name = name\n    self.age = age\n    self.languages = languages\n  \n\n  def print(self):\n    print(f'Nombre {self.name}, Apellido: {self.surname}, edad: {self.age}, lenguajes: {self.languages}')\n\nname = 'Cesar'\nage = 21\nlanguages = ['Spanish', 'English', 'Portugese']\n\nmy_programmer = Programmer(name, age, languages) # Instancio la clase.\nmy_programmer.print() # La muestro dandole print a la variable my_programmer, instancia de la clase Programmer.\nmy_programmer.surname = 'Moran' # Accedo a la clase 'Programmer' ya instanciada, y luego a la variable 'surname' dentro de ella, le asigno un valor después.\nmy_programmer.print()\nmy_programmer.age = 22 # Actualizamos el valor de la misma forma que accedimos a surname.\nmy_programmer.print()\n\n'''\nEjercicio\n'''\n\n# LIFO\n\nclass Stack:\n  def __init__(self):\n    self.stack: list = []\n  \n  def push(self, item):\n    return self.stack.append(item)\n  \n  def pop(self):\n    if self.count() == 0:\n      return print('No hay suficientes elementos para imprimir.')\n    else:\n      return self.stack.pop()\n  \n  def count(self):\n    return len(self.stack)\n  \n  def print(self):\n    for item in reversed(self.stack):\n      print(f'Imprimiendo {item}')\n\nmy_stack = Stack()\nmy_stack.push('A')\nmy_stack.push('B')\nmy_stack.push('C')\nprint(my_stack.count())\nmy_stack.print()\nmy_stack.pop()\nprint(my_stack.count())\nmy_stack.print()\n\n\n# FIFO\n\nclass Cola:\n  def __init__(self):\n    self.queue: list = []\n\n  def push(self, item):\n    return self.queue.append(item)\n\n  def pop(self):\n    if len(self.queue) > 0:\n      self.queue.pop(0)\n    else:\n      return print('No hay mas elementos para imprimir.')\n\n  def print(self):\n    print(f'Imprimiendo {self.queue[0]}')\n    self.pop()\n\n  def count(self):\n    for item in self.queue:\n      print(f'Tienes {item} elementos para imprimir.')\n\nmy_cola = Cola()\nmy_cola.push('1')\nmy_cola.push('2')\nmy_cola.push('3')\nprint(my_cola.queue)\nmy_cola.print()\nprint(my_cola.queue)\nmy_cola.pop()\nprint(my_cola.queue)\nmy_cola.pop()\nmy_cola.pop()"
  },
  {
    "path": "Roadmap/08 - CLASES/python/LucasRebuffo.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n */ \"\"\"\n\n\"\"\" Ejemplo de clase: \"\"\"\n\n\nclass Client:\n\n    def __init__(self, id: int, name: str, surname: str, email: str) -> None:\n        self.id = id\n        self.name = name\n        self.surname = surname\n        self.email = email\n\n    def __str__(self) -> str:\n        return f\"Id: {self.id} | Nombre: {self.name} | Apellido: {self.surname} | Email: {self.email}\"\n\n\njose = Client(1, \"Jose\", \"Lopez\", \"jose26@gmail.com\")\nmaria = Client(2, \"Maria\", \"Martinez\", \"mary@gmail.com\")\nrosa = Client(3, \"Rosa\", \"Garcia\", \"ros@gmail.com\")\n\n# print(jose)\n# print(maria)\n# print(rosa)\n\n\n\"\"\" * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n */ \"\"\"\n\n\nclass Pila:\n\n    def __init__(self, pila: list = []) -> None:\n        self.pila = pila\n\n    def show(self):\n        for element in reversed(self.pila):\n            print(f\"--> {element}\")\n\n    def push(self, element):\n        self.pila.append(element)\n\n    def pop(self):\n        if self.is_empty():\n            return None\n        return self.pila.pop()\n\n    def is_empty(self):\n        return len(self.pila) == 0\n\n\nnew_stack = Pila()\n\nnew_stack.push(5)\nnew_stack.push(4)\nnew_stack.push(3)\nnew_stack.push(8)\nnew_stack.push(7)\n\nnew_stack.show()\n\nprint(new_stack.pop())\nprint(new_stack.pop())\nprint(new_stack.pop())\nprint(new_stack.pop())\nprint(new_stack.pop())\nprint(new_stack.pop())\nprint(new_stack.pop())\n\n\nclass Cola:\n\n    def __init__(self, cola: list = []) -> None:\n        self.cola = cola\n\n    def show(self):\n        for element in self.cola:\n            print(f\"--> {element}\")\n\n    def enqueue(self, element):\n        self.cola.append(element)\n\n    def dequeue(self):\n        if self.is_empty():\n            return None\n        return self.cola.pop(0)\n\n    def peek(self):\n        return self.cola[0]\n\n    def is_empty(self):\n        return len(self.cola) == 0\n\n\nnew_queue = Cola()\n\nnew_queue.enqueue(\"Juan\")\nnew_queue.enqueue(\"Pedro\")\nnew_queue.enqueue(\"Pablo\")\n\nnew_queue.show()\n\n\nprint(new_queue.dequeue())\nprint(new_queue.dequeue())\nprint(new_queue.dequeue())\nprint(new_queue.dequeue())\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/Lumanet.py",
    "content": "# CLASES\nclass Pala:\n  def __init__(self, marca, modelo, precio, tiendas):\n    self.marca = marca\n    self.modelo = modelo\n    self.precio = precio\n    self.tiendas = tiendas\n    \n  def __str__(self):\n    return f\"{self.marca} {self.modelo} {self.precio} {self.tiendas}\"\n  \n  def info(self):\n    print(f\"--- Pala ---\\nMarca: {self.marca}\\nModelo: {self.modelo}\\nPrecio: {self.precio} €\\nDisponible en: {self.tiendas}\")\n\ncosa = Pala(\"Varlion\", \"LW Carbon Hexagon\", 200, [\"El Corte Inglés\", \"Decathlon\"])\ncosa.info()\nprint(cosa)\n\n\"\"\"\nImplementa dos clases que representen las estructuras de Pila y Cola (estudiadas\nen el ejercicio número 7 de la ruta de estudio)\n- Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n  retornar el número de elementos e imprimir todo su contenido.\n\"\"\"\nclass Stack:\n    def __init__(self):\n        self.stack = []\n\n    def mete(self, item):\n        self.stack.append(item)\n\n    def saca(self):\n        sacado = self.stack.pop()\n        return sacado\n\n    def __str__(self):\n        return str(self.stack)\n\n    def muestra(self):\n        print(\n            f\"--- Stack (Pila) ---\\nStack actual: {self.stack}\\nSiguiente elemento a sacar: {self.stack[-1]}\"\n        )\n\nstack1 = Stack()\nstack1.mete(1)\nstack1.mete(3)\nstack1.mete(5)\nstack1.mete(7)\n# Usando método muestra()\nstack1.muestra()\n# Usar método saca()\nsacado = stack1.saca()\nprint(\"Elemento sacado =>\", sacado)\n# Usando método __str__()\nprint(\"Stack después del pop:\", stack1)\n\n\nclass Queue:\n    def __init__(self):\n        self.queue = []\n\n    def mete(self, item):\n        self.queue.append(item)\n\n    def saca(self):\n        sacado = self.queue.pop(0)\n        return sacado\n\n    def __str__(self):\n        return str(self.queue)\n\n    def muestra(self):\n        print(\n            f\"--- Queue (Cola) ---\\nQueue actual: {self.queue}\\nSiguiente elemento a sacar: {self.queue[0]}\"\n        )\n\n\nqueue1 = Queue()\nqueue1.mete(1)\nqueue1.mete(3)\nqueue1.mete(5)\nqueue1.mete(7)\n# Usando método muestra()\nqueue1.muestra()\n# Usar método saca()\nsacado = queue1.saca()\nprint(\"Elemento sacado =>\", sacado)\n# Usando método __str__()\nprint(\"Queue después del pop:\", queue1)\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/Maanghel.py",
    "content": "\"\"\"\nEJERCICIO:\nExplora el concepto de clase y crea un ejemplo que implemente un inicializador,\n    atributos y una función que los imprima (teniendo en cuenta las posibilidades\n    de tu lenguaje).\nUna vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n    utilizando su función.\n\nDIFICULTAD EXTRA (opcional):\nImplementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n    en el ejercicio número 7 de la ruta de estudio)\n- Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n    retornar el número de elementos e imprimir todo su contenido.\n\"\"\"\n\nclass Persona:\n    \"\"\"\n    Class representing a person with a first name, last name, and age.\n    \n    Attributes:\n        first_name (str): The person's first name.\n        last_name (str): The person's last name.\n        age (int): The person's age.\n    \n    Methods:\n        print_info(): Prints the person's information.\n    \"\"\"\n\n    def __init__(self, first_name: str, last_name: str, age: int):\n        \"\"\"\n        Initializes a new instance of the Persona class.\n\n        Args:\n            first_name (str): The person's first name.\n            last_name (str): The person's last name.\n            age (int): The person's age.\n        \"\"\"\n        self.first_name = first_name\n        self.last_name = last_name\n        self.age = age\n\n    def print_info(self):\n        \"\"\"\n        Prints the person's information in a readable format.\n        \"\"\"\n        print(\n            f\"\\nName: {self.first_name}\\nLast Name: {self.last_name}\\nAge: {self.age}\"\n        )\n\n\n# Example of using the Persona class\npersona = Persona(\"Manuel\", \"Gamez\", 29)\npersona.print_info()\npersona.first_name = \"Maanghel\"\npersona.print_info()\n\n\n# Data structure classes: Stack and Queue\n\nclass Stack:\n    \"\"\"\n    Class representing a stack (LIFO: Last In First Out).\n\n    Attributes:\n        stack (list): List that stores the stack's elements.\n\n    Methods:\n        add(item): Adds an item to the stack.\n        delete(): Removes the last item from the stack.\n        count(): Returns the number of elements in the stack.\n        print_stack(): Prints all elements in the stack.\n    \"\"\"\n\n    def __init__(self):\n        \"\"\"\n        Initializes a new empty stack.\n        \"\"\"\n        self.stack = []\n\n    def add(self, item):\n        \"\"\"\n        Adds a new item to the stack.\n\n        Args:\n            item: Item to add to the stack.\n        \"\"\"\n        self.stack.append(item)\n\n    def delete(self):\n        \"\"\"\n        Removes the last item from the stack. If the stack is empty, prints a warning message.\n        \"\"\"\n        if self.count() > 0:\n            self.stack.pop()\n        else:\n            print(\"The stack is empty.\")\n\n    def count(self):\n        \"\"\"\n        Returns the number of elements in the stack.\n\n        Returns:\n            int: The number of elements in the stack.\n        \"\"\"\n        return len(self.stack)\n\n    def print_stack(self):\n        \"\"\"\n        Prints the elements in the stack, numbered.\n\n        Example output:\n            1 - Item1\n            2 - Item2\n        \"\"\"\n        for id_, item in enumerate(self.stack, 1):\n            print(f\"{id_} - {item}\")\n\n\nclass Queue:\n    \"\"\"\n    Class representing a queue (FIFO: First In First Out).\n\n    Attributes:\n        queue (list): List that stores the queue's elements.\n\n    Methods:\n        add(item): Adds an item to the queue.\n        delete(): Removes the first item from the queue.\n        count(): Returns the number of elements in the queue.\n        print_queue(): Prints all elements in the queue.\n    \"\"\"\n\n    def __init__(self):\n        \"\"\"\n        Initializes a new empty queue.\n        \"\"\"\n        self.queue = []\n\n    def add(self, item):\n        \"\"\"\n        Adds a new item to the queue.\n\n        Args:\n            item: Item to add to the queue.\n        \"\"\"\n        self.queue.append(item)\n\n    def delete(self):\n        \"\"\"\n        Removes the first item from the queue. If the queue is empty, prints a warning message.\n        \"\"\"\n        if self.count() > 0:\n            self.queue.pop(0)\n        else:\n            print(\"The queue is empty.\")\n\n    def count(self):\n        \"\"\"\n        Returns the number of elements in the queue.\n\n        Returns:\n            int: The number of elements in the queue.\n        \"\"\"\n        return len(self.queue)\n\n    def print_queue(self):\n        \"\"\"\n        Prints the elements in the queue, numbered.\n\n        Example output:\n            1 - Item1\n            2 - Item2\n        \"\"\"\n        for id_, item in enumerate(self.queue, 1):\n            print(f\"{id_} - {item}\")\n\n\n# Using the Stack class\nstack = Stack()\nstack.print_stack()\nstack.add(1)\nstack.add(2)\nstack.add(3)\nprint(stack.count())\nstack.print_stack()\nstack.delete()\nstack.delete()\nprint(stack.count())\nstack.print_stack()\nstack.delete()\nprint(stack.count())\nstack.delete()\n\n# Using the Queue class\nqueue = Queue()\nqueue.print_queue()\nqueue.add(1)\nqueue.add(2)\nqueue.add(3)\nqueue.add(4)\nprint(queue.count())\nqueue.print_queue()\nqueue.delete()\nqueue.delete()\nqueue.delete()\nqueue.delete()\nprint(queue.count())\nqueue.print_queue()\nqueue.delete()\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/MarcosE-FerretoE.py",
    "content": "\"\"\" EJERCICIO \"\"\"\n\n\nclass People:\n    last_name: str = None\n\n    def __init__(self, name: str, age: int):\n        self.name = name\n        self.age = age\n\n    def greet(self):\n        print(f\"Hello I'm {self.name} {self.last_name} and my age {self.age}\")\n\n\npeople = People(\"Marco\", 17)\npeople.last_name = \"Ferreto\"\npeople.greet()\npeople.age = 18\npeople.greet()\n\n\"\"\" DIFICULTAD EXTRA \"\"\"\n\n# LIFO\n\n\nclass Stack:\n    def __init__(self):\n        self.items = []\n\n    def push(self, item):\n        self.items.append(item)\n\n    def pop(self):\n        if self.is_empty() == 0:\n            return None\n        return self.items.pop()\n\n    def is_empty(self):\n        return len(self.items)\n\n    def print(self):\n        for item in reversed(self.items):\n            print(item)\n\n\nmy_stack = Stack()\nmy_stack.push(\"A\")\nmy_stack.push(\"B\")\nmy_stack.push(\"C\")\nprint(my_stack.is_empty())\nmy_stack.print()\nmy_stack.pop()\nprint(my_stack.is_empty())\n\n\nprint(\"----------------------------------------------------------------\")\n# FIFO\n\n\nclass Queue:\n    def __init__(self):\n        self.items = []\n\n    def enqueue(self, item):\n        self.items.append(item)\n\n    def dequeue(self):\n        if self.is_empty() == 0:\n            return None\n        return self.items.pop(0)\n\n    def is_empty(self):\n        return len(self.items)\n\n    def print(self):\n        for item in self.items:\n            print(item)\n\n\nmy_queue = Queue()\n\nmy_queue.enqueue(\"A\")\nmy_queue.enqueue(\"B\")\nmy_queue.enqueue(\"C\")\nprint(my_queue.is_empty())\nmy_queue.print()\nmy_queue.dequeue()\nprint(\"\\n================================\")\nmy_queue.print()\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/MirandaYuber.py",
    "content": "print(\"\"\"\nClases\n\"\"\")\n\n\nclass Phone:\n    reference = '000'\n\n    def __init__(self, marca: str, serie: str, anio: int):\n        self.marca = marca\n        self.anio = anio\n        self.serie = serie\n\n    def imprimir(self):\n        print(f'Celular marca {self.marca}, serie {self.serie}, referencia {self.reference} del año {self.anio}')\n\n\nclass_phone = Phone(marca='Xiaomi', serie='Note 10 Pro', anio=2024)\nclass_phone.imprimir()\nclass_phone.marca = 'Poco'\nclass_phone.imprimir()\nprint()\n\nprint(\"\"\"\nEXTRA\n\"\"\")\n\nprint('Pila:')\n\n\nclass Stack:\n    def __init__(self):\n        self.stack_items = []\n\n    def push_item(self, item):\n        self.stack_items.append(item)\n\n    def pop_item(self):\n        if len(self.stack_items) > 0:\n            self.stack_items.pop()\n\n    def count_items(self):\n        print(len(self.stack_items))\n\n    def get_items(self):\n        print(self.stack_items)\n\n\nstack = Stack()\nstack.push_item(1)\nstack.push_item(2)\nstack.push_item(3)\nstack.get_items()\nstack.pop_item()\nstack.pop_item()\nstack.get_items()\nstack.count_items()\nprint()\n\n\nprint('Cola:')\n\n\nclass Cola:\n    def __init__(self):\n        self.cola_items = []\n\n    def push_item(self, item):\n        self.cola_items.insert(0, item)\n\n    def pop_item(self):\n        if len(self.cola_items) > 0:\n            self.cola_items.pop()\n\n    def get_items(self):\n        print(self.cola_items)\n\n    def count_items(self):\n        print(len(self.cola_items))\n\n\ncola = Cola()\ncola.push_item(1)\ncola.push_item(2)\ncola.push_item(3)\ncola.push_item(4)\ncola.get_items()\ncola.pop_item()\ncola.pop_item()\ncola.get_items()\ncola.count_items()\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/NeosV.py",
    "content": "\n\nclass Programador:\n\n    def __init__(self, nombre:str, edad:int, lenguaje:list):\n        self.nombre = nombre\n        self.edad = edad\n        self.lenguaje = lenguaje\n\n    def impri(self):\n        print(f\"Nombre: {self.nombre} Edad: {self.edad} Lenguaje: {self.lenguaje}\")\n\n\n\n\n\nmy_programador = Programador(\"Andres\", 22 , [\"css\",\"Python\"])\nmy_programador.impri()      \nmy_programador.edad = 24\nmy_programador.impri()\n\n\nclass Stack:\n    def __init__(self):\n        self.stack = []\n        \n    def anadir(self,item):\n\n        self.stack.append(item)\n        print(\"Accion completada\")\n\n    def eliminar(self):\n\n        self.stack.pop() \n\n        print(\"Eliminacion completada\")\n\n    def cont(self):\n\n        print(len(self.stack))\n\n    def imprimir(self): \n\n        for item in reversed(self.stack):\n            print(item)\n       \n\n\n\nmy_stack = Stack()  \nmy_stack.anadir(\"a\")   \nmy_stack.anadir(\"b\")   \nmy_stack.anadir(\"c\")      \nmy_stack.imprimir()\nmy_stack.cont()\nmy_stack.eliminar()\nmy_stack.imprimir()\n\n\nclass Queue:\n    def __init__(self):\n        self.queue = []\n        \n    def anadir(self,item):\n\n        self.queue.append(item)\n        print(\"Accion completada\")\n\n    def eliminar(self):\n\n        self.queue.pop(0) \n\n        print(\"Eliminacion completada\")\n\n    def cont(self):\n\n        print(len(self.queue))\n\n    def imprimir(self): \n\n        for item in (self.queue):\n            print(item)\n       \n\n\n\nmy_queue = Queue()  \nmy_queue.anadir(\"a\")   \nmy_queue.anadir(\"b\")   \nmy_queue.anadir(\"c\")      \nmy_queue.imprimir()\nmy_queue.cont()\nmy_queue.eliminar()\nmy_queue.imprimir()\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/NicoHeguaburu.py",
    "content": "# Clases\n\nclass Programador:\n\n    apellido = None\n\n    def __init__(self, nombre: str, edad: int, lenguajes: list) -> None:\n        self.nombre = nombre\n        self.edad = edad\n        self.lenguajes = lenguajes        \n        \n    def print(self):\n        print(f\"Nombre: {self.nombre} | Apellido: {self.apellido} | Edad: {self.edad} | Lenguajes: {self.lenguajes}\")\n\n\nmi_programador = Programador(\"Nicolás\", 22, [\"Python\", \"Javascript\", \"Typescript\"])\nmi_programador.print()\n\nmi_programador.apellido = \"Heguaburu\"\nmi_programador.print()\n\n\n\n#Dificultad extra\n\nclass Stack:\n\n    def __init__(self):\n        self.stack = []\n\n    def push(self, item):\n        self.stack.append(item)\n    \n    def count(self):\n        return(len(self.stack))                          \n    \n    def pop(self):\n        if self.count() == 0:\n            return None\n        else:\n            self.stack.pop()\n        \n\n        \n    def printer(self):\n        for i in self.stack:\n            print(i)\n\n\n\nmy_stack = Stack()\n\nmy_stack.push(\"nico\")\nmy_stack.push(\"fede\")\nmy_stack.push(\"uli\")\nmy_stack.push(\"marcos\")\n\nprint(my_stack.count())\n\nmy_stack.pop()\n\n\nprint(my_stack.count())\n \nmy_stack.printer()\n\n\nclass Queue:\n    def __init__(self):\n        self.queue = []\n\n    def push(self, item):\n        self.queue.append(item)\n\n    def count(self):\n        return(len(self.queue))\n    \n    def pop(self):\n        if self.count() > 0:\n            self.queue.pop(0)\n        else:\n            print(\"No hay mas valores en la lista para eliminar\")\n    \n    def printer(self):\n        for i in self.queue:\n            print(i)\n\n\n\nmy_queue = Queue()\n\nmy_queue.push(\"danet\")\nmy_queue.push(\"serenito\")\nmy_queue.push(\"conamigos\")\nmy_queue.push(\"danonino\")\n\nmy_queue.printer()\nmy_queue.pop()\nmy_queue.printer()\n\nprint(my_queue.count())\n\n\n\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/Nicojsuarez2.py",
    "content": "# #08 CLASES\n> #### Dificultad: Fácil | Publicación: 19/02/24 | Corrección: 26/02/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n * \n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/NightAlchemist.py",
    "content": "'''\nExercise\n'''\n\n#Classes\n\nclass Person:\n    def __init__(self, name, age):\n        self.name = name\n        self.age = age\n\n    def say_hello(self):\n        print(f'Hello, my name is {self.name} and I am {self.age} years old')\n        \nperson1 = Person('Jake', 36)\nperson1.say_hello()\n\nperson2 = Person('Jane', 25)\nperson2.say_hello()\n\nperson1.age = 45\nperson1.say_hello()\n\n'''\nExtra\n'''\n\n#Stack class\n\nclass Stack:\n    def __init__(self):\n        self.stack = []\n\n    def push(self, item):\n        return self.stack.append(item)\n    def pop(self):\n        if self.count() == 0:\n            return None\n        return self.stack.pop()\n    def count(self):\n        return len(self.stack)\n    def print(self):\n        for item in reversed(self.stack):\n            print(item)\n        \n\nmy_stack = Stack()\nmy_stack.push('Marvel')\nmy_stack.push('DC')\nmy_stack.push('Dark Horse')\nprint(my_stack.count())\nprint(my_stack.print())\n\n\n#Queue class\n\nclass Queue:\n    def __init__(self):\n        self.queue = []\n        \n    def enqueue(self, item):\n        return self.queue.append(item)\n    def dequeue(self):\n        if self.count() == 0:\n            return None\n        return self.queue.pop(0)\n    def count(self):\n        return len(self.queue)\n    def print(self):\n        for item in self.queue:\n            print(item)\n            \nmy_queue = Queue()\nmy_queue.enqueue('Marvel')\nmy_queue.enqueue('DC')\nmy_queue.enqueue('Dark Horse')\nprint(my_queue.count())\nprint(my_queue.print())"
  },
  {
    "path": "Roadmap/08 - CLASES/python/Nightblockchain30.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n#  * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n#  * de tu lenguaje).\n#  * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n#  * utilizando su función.\n#  */\n\n# CLASE -> Es un tipo de estructura de datos en la cual podemos definir un conjunto de atributos y métodos privados o no\n# de una instancia de esa clase.Por así decirlo es como una plantilla con la que podemos crear objetos/instancias independientes\n# de esa misma clase.\n\n\nclass Humano():\n    \"\"\"Plantilla para crear instancias/objetos de humanos independientes\"\"\"\n    # Método constructor interno de la clase. Cada vez que se cree una instancia nueva se ejecuta de forma automática\n    def __init__(self,name,username,age):\n        # ATRIBUTOS con lo que se inicializa cualquier instancia\n        self.nombre = name\n        self.apellido = username\n        self.edad= age\n    \n\n    def saludar(self):\n        print(f\"Hola soy {self.nombre.capitalize()} {self.apellido.capitalize()} y tengo {self.edad} años.\")\n\n\n    def update(self,new_name,new_username,new_age):\n        \"\"\"Este método lo vamos a usar para actualizar los datos de los objetos de las clase Humano\"\"\"\n        self.nombre = new_name\n        self.apellido = new_username\n        self.edad = new_age\n\n\n# CASO DE USO\nhumano1 = Humano(\"night\",\"blockchain\",\"26\")\nhumano1.saludar()\nhumano1.update(\"pepe\",\"blanco\",18)\nhumano1.saludar()\n\n\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n#  * en el ejercicio número 7 de la ruta de estudio)\n#  * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n#  *   retornar el número de elementos e imprimir todo su contenido.\n#  * \n\nclass Stack():\n\n    def __init__(self,name_stack):\n        self.name_stack = name_stack\n        self.contenido_stack = []\n\n    def add(self,num:int):\n        \"\"\"Método para agregar elementos a la pila según el método LIFO. También conocido como PUSH\"\"\"\n        self.contenido_stack.append(num)\n\n    def remove(self):\n        \"\"\"Método eliminar el último elemento agregado a la pila.También conocido como POP\"\"\"\n        self.contenido_stack.pop()\n\n\n    def show_stack(self):\n        \"\"\"Método para mostrar el estado de la pila\"\"\"\n        print(f\"{self.contenido_stack}\")\n    \n\n# Caso de uso STACK\nstack1 = Stack(\"Stack1\")\n\nstack1.add(1)\nstack1.add(2)\nstack1.add(3)\n\nstack1.show_stack()\n\nstack1.remove()\nstack1.remove()\n\nstack1.show_stack()\n\n\nclass Queue():\n\n    def __init__(self,name_queue):\n        self.name_queue = name_queue\n        self.contenido_queue= []\n\n    def add(self,num:int):\n        \"\"\"Método para agregar elementos a la cola según el método FIFO. También conocido como PUSH\"\"\"\n        self.contenido_queue.append(num)\n\n    def remove(self):\n        \"\"\"Método eliminar el primer elemento de la cola.También conocido como POP\"\"\"\n        self.contenido_queue.pop(0)\n\n\n    def show_cola(self):\n        \"\"\"Método para mostrar el estado de la cola\"\"\"\n        print(f\"{self.contenido_queue}\")\n\n# Caso de uso QUEUE\ncola1 = Queue(\"qu1\")\n\ncola1.add(1)\ncola1.add(2)\ncola1.add(3)\n\ncola1.show_cola()\n\ncola1.remove()\ncola1.remove()\n\ncola1.show_cola()"
  },
  {
    "path": "Roadmap/08 - CLASES/python/Paprikaistkrieg.py",
    "content": "#clases\n\n\"\"\"\nque es una clase en python\nUna clase en Python es una plantilla o un molde para crear objetos. \nDefine un conjunto de atributos (propiedades o datos) y métodos (funciones) que los objetos creados a partir de la clase tendrán. \nLas clases permiten encapsular datos y comportamientos relacionados, \nfacilitando la organización y reutilización del código.\n\"\"\"\n\nclass Persona: #definimos una clase llamada Persona\n    surname: str \n    def __init__(self, nombre: str, edad: int, lenguaje: list): #el metodo __init__ es el constructor de la clase, se ejecuta automaticamente al crear un objeto de la clase\n        self.nombre = nombre #self es una referencia al objeto actual, se usa para acceder a los atributos y metodos de la clase\n        self.edad = edad #aqui estamos definiendo los atributos de la clase, que son nombre y edad\n        self.lenguaje = lenguaje\n\n    def saludar(self): #aqui estamos definiendo un metodo de la clase, que es saludar\n        print(f\"Hola, soy {self.nombre} {self.surname} y tengo {self.edad} años y estoy aprendiendo logica de programacion en {self.lenguaje}.\") #aqui estamos definiendo el comportamiento del metodo saludar\n\n\"\"\"\nAquí, Persona es una clase que describe cómo será cada persona: qué datos tendrá (nombre, edad) y qué podrá hacer (saludar).\n\"\"\"\n\npersona1 = Persona(\"Ivan\", 25, \"Python\") #creamos un objeto de la clase Persona, llamado persona1\npersona1.surname = \"RN\" #asignamos un valor al atributo surname del objeto persona1\nprint(persona1.nombre)  # Imprime: Ivan\npersona1.saludar()  # Imprime: Hola, soy Ivan RN y tengo 25 años y estoy aprendiendo logica de programacion en Python.\npersona2 = Persona(\"Ana\", 30, [\"Python\", \"Java\", \"C++\", \"JavaScript\"]) #creamos otro objeto de la clase Persona, llamado persona2\npersona2.surname = \"Doe\" #asignamos un valor al atributo surname del objeto persona2\npersona2.saludar()  # Imprime: Hola, soy Ana Doe y tengo 30 años y estoy aprendiendo logica de programacion en ['Python', 'Java', 'C++', 'JavaScript'].\nprint(persona2.edad)  # Imprime: 30\npersona1.edad = 26 #modificamos el atributo edad del objeto persona1\npersona1.saludar()  \n# Imprime: Hola, soy Ivan RN y tengo 26 años y estoy aprendiendo logica de programacion en Python. \n#(ya que hemos modificado la edad)\n\n\n\n\"\"\"\nAquí, hemos creado dos objetos de la clase Persona: persona1 y persona2.\n\nCada uno tiene sus propios atributos (nombre, apellido, edad y lenguajes) \ny puede realizar acciones (saludar) de forma independiente.\n\nLas clases son fundamentales en la programación orientada a objetos (POO)\n y permiten crear estructuras de datos complejas y comportamientos personalizados.\n\"\"\"\n\n#XtraJ\n\nclass pila: #LIFO (Last In, First Out)\n    def __init__(self):\n        self.stack = []  # Inicializa una lista vacía para almacenar los elementos de la pila\n\n    def push(self, item):\n        self.stack.append(item)  # Añade un elemento a la cima de la pila\n\n    def pop(self):\n        if len(self.stack) > 0: # Verifica si la pila no está vacía\n            return self.stack.pop()  # Remueve y devuelve el elemento de la cima de la pila\n        return None  # Si la pila está vacía, devuelve None\n        \n\n    def size(self):\n        return len(self.stack)  # Devuelve el número de elementos en la pila\n    \n    def print(self):\n        for item in reversed(self.stack): # Recorre los elementos de la pila\n            print(item)  # Imprime cada elemento\n\n# Instanciación y uso de la clase pila fuera de la definición de la clase\nmi_pila = pila()  # Crea una instancia de la clase pila\n\nmi_pila.push(1)  # Añade el elemento 1 a la pila\nmi_pila.push(2)  # Añade el elemento 2 a la pila\nmi_pila.push(3)  # Añade el elemento 3 a la pila\nprint(\"Tamaño de la pila:\", mi_pila.size())  # Imprime el tamaño actual de la pila\nmi_pila.print()  # Imprime los elementos actuales de la pila\nelemento = mi_pila.pop()  # Remueve el elemento de la cima de la pila\nprint(\"Elemento removido:\", elemento)  # Imprime el elemento removido\nprint(\"Tamaño de la pila después de pop:\", mi_pila.size())  # Imprime el tamaño de la pila después de la operación pop\n    \n\n#cola FIFO (First In, First Out)\nclass Cola: \n    def __init__(self):\n        self.queue = []  # Inicializa una lista vacía para almacenar los elementos de la cola\n\n    def enqueue(self, item):\n        self.queue.append(item)  # Añade un elemento al final de la cola\n\n    def dequeue(self):\n        if len(self.queue) > 0: # Verifica si la cola no está vacía\n            return self.queue.pop(0)  # Remueve y devuelve el primer elemento de la cola\n        return None  # Si la cola está vacía, devuelve None\n\n    def size(self):\n        return len(self.queue)  # Devuelve el número de elementos en la cola\n    \n    def print(self):\n        for item in self.queue: # Recorre los elementos de la cola\n            print(item)  # Imprime cada elemento\n# Instanciación y uso de la clase Cola fuera de la definición de la clase\nmi_cola = Cola()  # Crea una instancia de la clase Cola\nmi_cola.enqueue(1)  # Añade el elemento 1 a la cola\nmi_cola.enqueue(2)  # Añade el elemento 2 a la cola\nmi_cola.enqueue(3)  # Añade el elemento 3 a la cola\nprint(\"Tamaño de la cola:\", mi_cola.size())  # Imprime el tamaño\nmi_cola.print()  # Imprime los elementos actuales de la cola\nelemento = mi_cola.dequeue()  # Remueve el primer elemento de la cola\nprint(\"Elemento removido:\", elemento)  # Imprime el elemento removido\nprint(\"Tamaño de la cola después de dequeue:\", mi_cola.size())  # Imprime el tamaño de la cola después de la operación dequeue\n\n\n "
  },
  {
    "path": "Roadmap/08 - CLASES/python/Paula2409.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n\"\"\"\n\nclass Vehiculo:\n    def __init__(self, tipo: str, modelo: str, color: str, ruedas: int):\n        self.tipo = tipo\n        self.modelo = modelo\n        self.color = color\n        self.ruedas = ruedas\n\n    def __str__(self):\n        return f\"El vehiculo {self.tipo} es modelo {self.modelo}, con color {self.color} y de {self.ruedas} ruedas\"\n\n    \nauto = Vehiculo('automovil', 'classic', 'gris', 4)\nprint(auto)\nmoto = Vehiculo('motocicleta', 'scooter', 'negro', 2)\nprint(moto)\nauto.color = 'azul'\nprint(\"Se modifico el color del auto: \")\nprint(auto)\nmoto.modelo = 'motocross'\nprint(\"Se modifico el modelo de la moto\")\nprint(moto)\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n * \n */\"\"\"\n\nclass Stack:\n    def __init__(self):\n        self.stack = []\n\n    def add_element(self,element):\n        return f\"Se agrego el elemento a la pila: {self.stack.append(element)}\"\n        \n\n    def remove_element(self):\n        return f\"Se elimino el ultimo elemento ingresado: {self.stack.pop()}\"\n\n    def size(self):\n        return f\"La pila tiene {len(self.stack)} elementos\"\n\n    def __str__(self):\n        for element in self.stack[::-1]:\n            return element\n\nstack1 = Stack()\n\nclass Queue:\n    def __init__(self):\n        self.queue = []\n\n    def add_element(self, element):\n        return f\"Se agrego el elemento a la cola: {self.queue.insert(0,element)}\"\n        \n    def remove_element(self):\n        return f\"Se elimino el primer elemento que ingreso a la cola: {self.queue.pop()}\"\n\n    def size(self):\n        return f\"La cola tiene {len(self.queue)} elementos\"\n\n    def __str__(self):\n        for element in self.queue[::-1]:\n            return element\n            \nqueue = Queue()"
  },
  {
    "path": "Roadmap/08 - CLASES/python/RicardiJulio.py",
    "content": "# EJERCICIO:\n#  * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n#  * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n#  * de tu lenguaje).\n#  * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n#  * utilizando su función.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n#  * en el ejercicio número 7 de la ruta de estudio)\n#  * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n#  *   retornar el número de elementos e imprimir todo su contenido.\n#  */\n\nclass Miclase():\n    atributo1 = 'valor1'#---> Atributos de clase\n    atributo2 = 'valor2'\n    def __init__(self,argumento1):\n        self.argumento1 = argumento1#---> Atributo de instancia\n    def funcion1(self):#---> Funcion de clase\n        print('Esta es la funcion 1')\n    \nobjeto = Miclase('Primer argumento')\n\nprint(objeto.atributo1)\nprint(objeto.atributo2)\nprint(objeto.argumento1)\nobjeto.funcion1()\n\nobjeto.atributo1 = 'Valor modificado'\nobjeto.atributo2 = 'Valor modificado'\nobjeto.argumento1 = 'Primer valor modificado'\n\nprint(objeto.atributo1)\nprint(objeto.atributo2)\nprint(objeto.argumento1)\n\n# DIFICULTAD EXTRA:\n\nclass Pila(): # Pila LIFO (Last In, First Out)\n    pila = []\n    \n    def __init__(self,nombre):\n        self.nombre = nombre\n    \n    def añadir(self,valor):\n        self.pila.append(valor)\n        print(f'Se ha añadido {valor} a {self.nombre}')\n    \n    def eliminar(self):\n        print(f'Se ha eliminado {self.pila[-1]} de {self.nombre}')\n        self.pila.pop()\n    \n    def retornar_elementos(self):\n        print(f'El numero de elementos de {self.nombre} es {len(self.pila)}')\n    \n    def imprimir(self):\n        print(self.pila)\n        \npila = Pila('Mi pila')\n\npila.añadir('Elemento')\npila.añadir('Elemento1')\npila.añadir('Elemento2')\npila.añadir('Elemento3')\n\npila.imprimir()\npila.retornar_elementos()\n\npila.eliminar()\n\npila.imprimir()\npila.retornar_elementos()\n\nclass Cola():\n    from collections import deque\n    cola = deque([])\n    \n    def __init__(self,nombre):\n        self.nombre = nombre\n    \n    def añadir(self,valor):\n        self.cola.append(valor)\n        print(f'Se ha añadido {valor} en {self.nombre}')\n        \n    def eliminar(self):\n        print(f'Se ha eliminado {self.cola[0]} de {self.nombre}')\n        self.cola.popleft()\n    \n    def retornar_elementos(self):\n        print(f'El numero de elementos de {self.nombre} es {len(self.cola)}')\n        \n    def imprimir(self):\n        print(self.cola) \n        \ncola = Cola('Mi cola xD')\n\ncola.añadir('Elemento')\ncola.añadir('Elemento1')\ncola.añadir('Elemento2')\ncola.añadir('Elemento3')\n\ncola.imprimir()\ncola.retornar_elementos()\n\ncola.eliminar()\n\ncola.imprimir()\ncola.retornar_elementos()\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/RoniPG.py",
    "content": "# @Roni\n\"\"\"\nEJERCICIO:\nExplora el concepto de clase y crea un ejemplo que implemente un inicializador,\natributos y una función que los imprima (teniendo en cuenta las posibilidades de tu lenguaje).\nUna vez implementada, créala, establece sus parámetros, modifícalos e imprímelos utilizando su función.\n\"\"\"\nclass Iguana:\n    def __init__(self,genero=\"\",endemico=\"\", especie=\"\") -> None:\n        self.genero=genero\n        self.endemico=endemico\n        self.especie=especie\n    def imprimir(self):\n        print(f\"Genero: {self.genero}\\nEndemico: {self.endemico} \\nEspecie:{self.especie}\")\n\nig1=Iguana() # --> Instanciamos/Incicalizamos la clase\nprint(\"****IGUANA****\")\n\"\"\"Le asignamos los valores\"\"\"\nig1.genero=\"Macho\"\nig1.endemico=\"Sudamerica\"\nig1.especie=\"Iguana\"\nig1.imprimir() # --> Llamamos al método que nos devolvera los valores\n\"\"\"\nDIFICULTAD EXTRA (opcional):\nImplementa dos clases que representen las estructuras de Pila y Cola\n(estudiadas en el ejercicio número 7 de la ruta de estudio)\n- Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n  retornar el número de elementos e imprimir todo su contenido.\n\"\"\"\nclass Pila:\n    def __init__(self,datos=None) -> None:\n        self.datos=list()\n    def añadir(self,dato):\n        self.datos.append(dato)\n    def eliminar(self):\n        if len(self.datos)>0:\n            self.datos.pop()\n        else:\n            print(\"La pila esta vacía\")\n    def numeroDeElementos(self) -> int:\n        return len(self.datos)\n    def imprimir(self):\n        i=0\n        for dato in self.datos:\n            i=i+1\n            print(f\"Dato {i}= {dato}\")\nprint(\"****PILA****\")\npila =Pila() # --> Instanciamos/Incicalizamos la clase\n\"\"\"Le asignamos los valores\"\"\"\npila.añadir(1)\npila.añadir(2)\npila.añadir(3)\nprint(f\"El número de elementos es: {pila.numeroDeElementos()}\"); # --> Imprimimos números de elementos\nprint(\"Su contenido es:\") # --> Imprimimos todos los datos\npila.imprimir()\npila.eliminar() # --> Eliminamos elemento de arriba de la pila\nprint(f\"El número de elementos después de pila.elminarDatos(): {pila.numeroDeElementos()}\"); # --> Imprimimos números de elementos\nprint(\"Su contenido después de pila.elminarDatos():\") # --> Imprimimos todos los datos\npila.imprimir()\npila.eliminar()\npila.eliminar()\npila.eliminar() # --> Salta el aviso\n\nclass Cola:\n    def __init__(self,datos=None) -> None:\n        self.datos=list()\n    def añadir(self,dato):\n        self.datos.append(dato)\n    def eliminar(self):\n        if len(self.datos)>0:\n            self.datos.pop(0)\n        else:\n            print(\"La cola esta vacía\")\n    def numeroDeElementos(self) -> int:\n        return len(self.datos)\n    def imprimir(self):\n        i=0\n        for dato in self.datos:\n            i = i+1\n            print(f\"Cola {i}= {dato}\")\nprint(\"****COLA****\")\ncola =Cola() # --> Instanciamos/Incicalizamos la clase\n\"\"\"Le asignamos los valores\"\"\"\ncola.añadir(\"Elemento 0\")\ncola.añadir(\"Elemento 1\")\ncola.añadir(\"Elemento 2\")\nprint(f\"El número de elementos es: {cola.numeroDeElementos()}\"); # --> Imprimimos números de elementos\nprint(\"Su contenido es:\") # --> Imprimimos todos los datos\ncola.imprimir()\ncola.eliminar() # --> Eliminamos el primer elemento de de la cola\nprint(f\"El número de elementos después de cola.elminarDatos(): {cola.numeroDeElementos()}\"); # --> Imprimimos números de elementos\nprint(\"Su contenido después de cola.elminarDatos():\") # --> Imprimimos todos los datos\ncola.imprimir()\ncola.eliminar()\ncola.eliminar()\ncola.eliminar() # --> Salta el aviso\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/Sac-Corts.py",
    "content": "\"\"\"\nEJERCICIO\n\"\"\"\nclass Persona:\n    def __init__(self, nombre, edad):\n        self.nombre = nombre\n        self.edad = edad\n\n    def saludar(self):\n        self.saludar = print(f\"Hola {self.nombre} ({self.edad}), ¿cómo estás?\")\n\nisaac = Persona(\"Isaac\", 22)\nisaac.saludar()\n\n\"\"\"\nEJERCICIO EXTRA\n\"\"\"\n\nclass Stack:\n    def __init__(self):\n        self.items = []\n\n    def push(self, item):\n        self.items.append(item)\n    \n    def pop(self):\n        if not self.is_empty():\n            return self.items.pop()\n        else: \n            return None\n    \n    def peek(self):\n        if not self.is_empty():\n            return self.items[-1]\n        else:\n            return None\n        \n    def is_empty(self):\n        return len(self.items) == 0\n    \n    def size(self):\n        size = len(self.items)\n        items = self.items[::-1]\n        print(f\"{size} | {items}\")\n        return size, items  \n    \npila = Stack()\npila.push(10)\npila.push(20)\npila.push(30)\nprint(pila.is_empty())\ndimension, elementos = pila.size()\nprint(pila.pop())\nprint(pila.peek())\n\nclass Queue:\n    def __init__(self):\n        self.items = []\n\n    def enqueue(self, item):\n        self.items.append(item)\n    \n    def dequeue(self):\n        if not self.is_empty():\n            return self.items.pop(0)\n        else:\n            return None\n    \n    def peek(self):\n        if not self.is_empty():\n            return self.items[0]\n        else:\n            return None\n    \n    def is_empty(self):\n        return len(self.items) == 0\n    \n    def size(self):\n        size = len(self.items)\n        items = self.items\n        print(f\"{size} | {items}\")\n        return size, items\n    \ncola = Queue()\ncola.enqueue(11)\ncola.enqueue(12)\ncola.enqueue(13)\nprint(pila.is_empty())\ndimension, elementos = cola.size()\nprint(cola.dequeue())\nprint(cola.peek())\n\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/SaezMD.py",
    "content": "#08 CLASES\n\"\"\"\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador, atributos y una función que los imprima (teniendo en cuenta las posibilidades de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar, retornar el número de elementos e imprimir todo su contenido.\n\"\"\"\n\n#Attribute references\nclass MyClass:\n    \"\"\"A simple example class\"\"\"\n    i = 12345\n\n    def f(self):\n        return 'hello world'\n\nprint(MyClass.i)\n\n#Class instantiation \nclass Complex:\n    def __init__(self, realpart, imagpart):\n        self.r = realpart\n        self.i = imagpart\n\nx = Complex(3.0, -4.5)\nprint(x.r)\nprint(x.i)\n\n#another example:\nclass Person:\n  def __init__(self, name, age):\n    self.name = name\n    self.age = age\n\np1 = Person(\"Saez\", 36)\n\nprint(p1.name)\nprint(p1.age)\np1.name = \"MD\"\nprint(p1.name)\n\n#EXTRA\n\nclass Queue:\n    def __init__(self):\n        self.listOfObjects = []\n\n    def addItem(self,toAdd):\n        self.listOfObjects.append(toAdd)\n    \n    def removeItem(self):\n        try:\n            return self.listOfObjects.pop(0)\n        except IndexError:\n            print(\"Empty queue!\")\n    \n    def lenght(self):\n        return len(self.listOfObjects)\n    \n    def printAll(self):\n        for item in self.listOfObjects:\n            print(item)\n\nd = Queue()\nd.addItem(\"cap01\")\nd.addItem(\"cap02\")\nd.addItem(\"cap03\")\nd.addItem(\"cap04\")\nd.removeItem()\nprint(d.lenght())\nd.printAll()\n\nclass Stack: #LIFO\n    def __init__(self):\n        self.listOfObjects = []\n\n    def addItem(self,toAdd):\n        self.listOfObjects.append(toAdd)\n    \n    def removeItem(self):\n        try:\n            self.listOfObjects.pop()\n        except IndexError:\n            print(\"Stack is empty!\")\n    \n    def lenght(self):\n        return len(self.listOfObjects)\n    \n    def printAll(self):\n        for item in reversed(self.listOfObjects):\n            print(item)\n\ns = Stack()\ns.addItem(\"show01\")\ns.addItem(\"show02\")\ns.addItem(\"show03\")\ns.addItem(\"show04\")\ns.removeItem()\nprint(s.lenght())\ns.printAll()\n\n\n        \n\n\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/SergioGI99.py",
    "content": "\"\"\"\n------\nCLASES\n------\nEJERCICIO:\nExplora el concepto de clase y crea un ejemplo que implemente un inicializador,\natributos y una función que los imprima (teniendo en cuenta las posibilidades\nde tu lenguaje).\nUna vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\nutilizando su función.\n\nDIFICULTAD EXTRA (opcional):\nImplementa dos clases que representen las estructuras de Pila y Cola (estudiadas\nen el ejercicio número 7 de la ruta de estudio)\n- Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n  retornar el número de elementos e imprimir todo su contenido.\n\"\"\"\n# Ejercicio\n\nclass BankAcc:\n    \n    def __init__(self,id: int, saldo: float):\n        self.saldo = saldo\n        self.id = id\n\n    def deposit(self, amount: float):\n        self.saldo += amount\n\n    def imprimir(self):\n        print(\"Tu balance actual es de: \", self.saldo)\n\nmy_account = BankAcc(1, 0)\n\nmy_account.deposit(100)\n\nmy_account.imprimir()\n\n# Extra\n\nclass Pila: # Stack LIFO\n    \n    def __init__(self):\n        self.pila = []\n        \n    def push(self, add):\n        (self.pila).append(add)\n        print(f\"Se ha añadido {add} a la pila\")\n        \n    def pop(self):\n        if len(self.pila) == 0:\n            return None\n        return print(\"Se ha eliminado: \", (self.pila).pop())\n        \n    def count(self):\n        print(\"El tamaño de la pila es: \", len(self.pila))\n        \n    def print(self):\n        for item in reversed(self.pila):\n            print(item)\n        \nmy_pila = Pila()\n\nmy_pila.push(\"uno\")\nmy_pila.push(\"dos\")\nmy_pila.push(\"tres\")\n\nmy_pila.count()\n\nmy_pila.pop()\n\nmy_pila.print()\n\nclass Cola: # Queue FIFO\n    \n    def __init__(self):\n        self.cola = []\n        \n    def enqueue(self, add):\n        (self.cola).append(add)\n        print(f\"Se ha añadido {add} a la cola\")\n        \n    def dequeue(self):\n        if len(self.cola) == 0:\n            return None\n        return print(\"Se ha eliminado: \", (self.cola).pop(0))\n        \n    def count(self):\n        print(\"El tamaño de la cola es: \", len(self.cola))\n        \n    def print(self):\n        for item in self.cola:\n            print(item)\n        \nmy_cola = Cola()\n\nmy_cola.enqueue(\"uno\")\nmy_cola.enqueue(\"dos\")\nmy_cola.enqueue(\"tres\")\n\nmy_cola.count()\n\nmy_cola.dequeue()\n\nmy_cola.print()"
  },
  {
    "path": "Roadmap/08 - CLASES/python/SooHav.py",
    "content": "# 08 Clases\n\n# Ejercicio\n\n'''Las clases en Python proporcionan una forma de empaquetar datos y funcionalidad juntos. \nAl crear una nueva clase, estamos creando un nuevo tipo de objeto, lo que nos permite crear \nnuevas instancias de ese tipo. Cada instancia de clase puede tener atributos adjuntos \npara mantener su estado, y también puede tener métodos definidos por su clase para modificar ese estado.\n\nEn la definición de una clase, los atributos se definen como variables que se inicializan en el \nmétodo especial init. Por ejemplo, en la clase Mascota, los atributos son nombre, edad y animal.\n\nLos métodos son funciones que se definen dentro de una clase y se utilizan para realizar operaciones \nen los objetos creados a partir de esa clase. Siempre tienen como primer parámetro el objeto al que se \naplicará el método, por convención llamado self.\n\nPara utilizar un método de una clase, primero debemos crear un objeto a partir de esa clase, como perro \no gato, y luego llamar al método sobre ese objeto. Por ejemplo, para hacer que un perro \nladre: perro.hacer_sonido('Guau').'''\n\n\nfrom collections import deque\n\n\nclass Mascota:\n    def __init__(self, nombre, edad, animal):\n        self.nombre = nombre\n        self.edad = edad\n        self.animal = animal\n\n    def hacer_sonido(self, sonido):\n        print(f\"{self.nombre} dice {sonido}\")\n\n    def comer(self, comida):\n        print(f\"{self.nombre} está comiendo {comida}\")\n\n    def dormir(self):\n        print(f\"{self.nombre} está durmiendo\")\n\n    def __str__(self):\n        return f\"Nombre: {self.nombre}, Edad: {self.edad}, Mascota: {self.animal}\"\n\n\n# Implementacion\nperro = Mascota(\"Fido\", 5, \"Perro\")\nprint(perro)\nperro.comer(\"croquetas\")\nperro.hacer_sonido(\"Guauu\")\nperro.dormir()\ngato = Mascota(\"Kiti\", 2, \"Gato\")\nprint(gato)\ngato.comer(\"pescado\")\ngato.hacer_sonido(\"Miuauu\")\ngato.dormir()\n\n\n'''La herencia es un proceso mediante el cual se puede crear una clase hija que hereda \nde una clase padre, compartiendo sus métodos y atributos.'''\n\n\nclass Cuidado(Mascota):\n    def __init__(self, nombre, edad, animal, cuidador):\n        super().__init__(nombre, edad, animal)\n        self.cuidador = cuidador\n\n    def bañar(self, numero_veces):\n        print(f\"{self.cuidador} baña a {self.nombre} {numero_veces} veces al mes.\")\n\n    def entrenar(self,  juego):\n        print(f\"{self.cuidador} {juego} a {self.nombre}.\")\n\n\n# Implementaciòn\ngato = Cuidado(\"Kiti\", 2, \"gato\", \"Sofi\")\ngato.bañar(2)\ngato.entrenar(\"pasea\")\n\n# Ejercicio extra\n\n# Colas\n\n\nclass HacerFila:\n    def __init__(self):\n        self.primero = None\n        self.ultimo = None\n        self.cola = []\n\n    def primer_elemento(self):\n        return self.primero\n\n    def ultimo_elemento(self):\n        return self.ultimo\n\n    def agrega_elemento(self, elemento):\n        self.cola.append(elemento)\n        self.ultimo = elemento\n        return self.ultimo\n\n    def saca_elemento(self):\n        self.cola.pop(0)\n        self.primero = self.cola[0]\n        return self.primero\n\n    def __str__(self):\n        return str(self.cola)\n\n    def __len__(self):\n        return len(self.cola)\n\n\n# Implementacion\nen_fila = HacerFila()\nen_fila.agrega_elemento(1)\nen_fila.agrega_elemento(2)\nen_fila.agrega_elemento(3)\nen_fila.agrega_elemento(4)\nprint(en_fila)\nen_fila.saca_elemento()\nen_fila.saca_elemento()\nprint(en_fila)\nprint(len(en_fila))\n\n# Navegador web\n\n\nclass NavegadorWeb:\n    def __init__(self):\n        self.historial = deque()\n        self.actual = \"\"\n\n    def atras(self):\n        if self.historial:\n            self.actual = self.historial.pop()\n            print(\"Retrocediendo a la pagina anterior\")\n        else:\n            print(\"No hay páginas para retroceder\")\n\n    def adelante(self, url):\n        if self.actual:\n            self.historial.append(self.actual)\n        else:\n            print(\"No hay página adelante\")\n        self.actual = url\n\n    def ver_historial(self):\n        print(\"Historial:\")\n        for pagina in self.historial:\n            print(pagina)\n        print(f\"Página actual: {self.actual}\")\n\n    def __str__(self):\n        return f\"Página actual: {self.actual}\"\n\n\n# Implementacion\nnavegador = NavegadorWeb()\nnavegador.adelante(\"https://www.ejemplo.com/pagina-1\")\nprint(navegador)\nnavegador.adelante(\"https://www.ejemplo.com/pagina-2\")\nprint(navegador)\nnavegador.adelante(\"https://www.ejemplo.com/pagina-3\")\nprint(navegador)\nnavegador.atras()\nprint(navegador)\nnavegador.ver_historial()\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/TheReDNooB.py",
    "content": "# #08 CLASES\n\nclass Animal:\n    def __init__(self, nombre, edad, raza, color) -> None:\n        self.nombre = nombre\n        self.edad = edad\n        self.raza = raza\n        self.color = color\n\n    def __str__(self) -> str:\n        return f\"{self.nombre} es un {self.raza} de {self.edad} años y es de color {self.color}\"\n    \ngato: Animal = Animal(\"Felix\", 3, \"Persa\", \"Gris\")\nprint(gato)\ngato.nombre = \"Felix el gato\"\nprint(gato)\nperro: Animal = Animal(\"Firulais\", 5, \"Labrador\", \"Negro\")\nprint(perro)\nperro.edad = 6\nprint(perro)\n\n# Extra\n\nclass Stack:\n    def __init__(self, stack: list = []) -> None:\n        self.stack = stack\n\n    def push(self, element) -> None:\n        self.stack.append(element)\n    \n    def pop(self) -> None:\n        if len(self.stack) > 0:\n            self.stack.pop()\n        else:\n            print(\"La pila está vacía\")\n\n    def stack_size(self) -> int:\n        return len(self.stack)\n    \n    def __str__(self) -> str:\n        return f\"{self.stack}\"\n    \npila: Stack = Stack()\nprint(pila)\npila.push(1)\npila.push(2)\npila.push(3)\nprint(pila)\npila.pop()\nprint(pila)\nprint(pila.stack_size())\nprint(pila)\n\nclass Queue:\n    def __init__(self, queue: list = []) -> None:\n        self.queue = queue\n        \n    def enqueue(self, element) -> None:\n        self.queue.append(element)\n    \n    def dequeue(self) -> None:\n        if len(self.queue) > 0:\n            self.queue.pop(0)\n        else:\n            print(\"La cola está vacía\")\n            \n    def queue_size(self) -> int:\n        return len(self.queue)\n    \n    def __str__(self) -> str:\n        return f\"{self.queue}\"\n    \ncola: Queue = Queue()\nprint(cola)\ncola.enqueue(4)\ncola.enqueue(5)\ncola.enqueue(6)\nprint(cola)\ncola.dequeue()\nprint(cola)\nprint(cola.queue_size())\nprint(cola)"
  },
  {
    "path": "Roadmap/08 - CLASES/python/Tomu98.py",
    "content": "\"\"\" Reto 08: Clases \"\"\"\n\nclass Programmer:\n    surname: str = None\n    \n    def __init__(self, name: str, age: int, languages: list):\n        self.name = name\n        self.age = age\n        self.languages = languages\n\n    def print(self):\n        print(f\"Nombre: {self.name} | Apellidos: {self.surname} | Edad: {self.age} | Lenguajes: {self.languages}\")\n\nmy_programmer = Programmer(\"Tomu\", 25, [\"Python\", \"SQLite\", \"FastAPI\"])\nmy_programmer.print()\nmy_programmer.surname = \"Arlert\"\nmy_programmer.print()\nmy_programmer.age = 26\nmy_programmer.print()\n\n\n\n\"\"\" Reto extra \"\"\"\n\n# LIFO\nclass Stack:\n    def __init__(self):\n        self.stack = []\n\n    def push(self, item):\n        self.stack.append(item)\n\n    def pop(self):\n        if self.count() == 0:\n            return None\n        return self.stack.pop()\n\n    def count(self):\n        return len(self.stack)\n\n    def print(self):\n        for item in reversed(self.stack):\n            print(item)\n\nmy_stack = Stack()\nmy_stack.push(1)\nmy_stack.push(2)\nmy_stack.push(3)\nprint(my_stack.count())\nmy_stack.print()\nmy_stack.pop()\nmy_stack.print()\n\n\n# FIFO\nclass Queue:\n    def __init__(self):\n        self.queue = []\n\n    def enqueue(self, item):\n        self.queue.append(item)\n\n    def dequeue(self):\n        if self.count() == 0:\n            return None\n        return self.queue.pop(0)\n\n    def count(self):\n        return len(self.queue)\n\n    def print(self):\n        for item in self.queue:\n            print(item)\n\nmy_queue = Queue()\nmy_queue.enqueue(1)\nmy_queue.enqueue(2)\nmy_queue.enqueue(3)\nprint(my_queue.count())\nmy_queue.print()\nmy_queue.dequeue()\nmy_queue.print()\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/TroyNebula.py",
    "content": "'''EJERCICIO:\r\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\r\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\r\n * de tu lenguaje).\r\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\r\n * utilizando su función.'''\r\n\r\n# Clases: representan y definen objetos\r\n# Objetos: son las instancias de las clases (int, str, list, dict...)\r\n# Atributos: características asociadas a un tipo / type (ej. color y sabor de una manzana)\r\n# Métodos: funciones asociadas a un tipo (ej. lo que vayamos a hacer con la manzana, comerla, cortarla...)\r\n\r\n# Constructores de Clases : __init__  \r\n# Método especial que se usa para inicializar los atributos de un objeto al crear una nueva instancia de esta clase.\r\n\r\nclass Person:\r\n\r\n    lugar : str = \"Federación\"       # Puedo crear un atributo fuera del inicializador y después imprimirlo. Puedo dejarlo en None\r\n\r\n    def __init__ (self, name, edad):      # 'self' hace referencia a la instancia en la que estamos\r\n        self.name = name\r\n        self.edad = edad\r\n\r\n    def imprimir (self):\r\n        print (f\"Hola mundo, me llamo {self.name}, vivo en {self.lugar} y tengo {self.edad} años.\")\r\n\r\nperson1 = Person (\"Troy\", 45)        # creo una nueva instancia 'person1' de la clase 'Person'\r\nperson1.imprimir()\r\n\r\nperson1.lugar =\"Vulcano\"\r\nperson1.imprimir()\r\n\r\nperson1.edad = \"44\"     # Modifico un atributo\r\nperson1.imprimir()\r\n\r\n# Constructores de Clases : __str__  \r\n# Método especial útil si tengo que andar imprimiendo mucho después\r\n\r\nclass Person2:\r\n    def __init__ (self, name, edad):      \r\n        self.name = name\r\n        self.edad = edad\r\n\r\n    def __str__ (self):\r\n        return \"Hola mundo, me llamo {}, y tengo {} años.\".format(person2.name, person2.edad)   # Retorno el texto formateado a imprimir\r\n\r\nperson2 = Person2 (\"Nebula\", 36)        # creo una nueva instancia 'person2' de la clase 'Person2'\r\nprint (person2)\r\n\r\n\r\n\r\nclass Ropa:\r\n    stock : dict = { 'nombre': [], 'material': [], 'cantidad': []} # Diccionario que contiene str de clave y lista de valor\r\n\r\n    def __init__ (self, nombre):\r\n        self.material = \"\"  # Si no lo inicializo aquí nunca se guarda como parte de una instancia de Ropa\r\n        self.nombre = nombre\r\n\r\n    def añadir_item (self, nombre, material, cantidad):\r\n        Ropa.stock ['nombre'].append (nombre)\r\n        Ropa.stock ['material'].append (material)  # Usar el material pasado como parámetro\r\n        Ropa.stock ['cantidad'].append (cantidad)\r\n\r\n    def stock_por_material(self, material):\r\n        contador = 0\r\n        for i, item in enumerate(Ropa.stock['material']):  \r\n            # enumerate se utiliza para iterar sobre una secuencia mientras lleva un recuento del índice actual de los elementos\r\n            if item == material:\r\n                contador += Ropa.stock['cantidad'][i]  \r\n                # Uso este índice i para acceder a la cantidad correcta y agregarla al contador.\r\n            \r\n        return contador\r\n        \r\nclass Camiseta (Ropa):      # Creo dos subclases Camiseta y Vestido de la clase Ropa y los inicializo añadiendo el material\r\n    def __init__(self, nombre):\r\n        super().__init__(nombre)   # super() función que permite acceder a los métodos y atributos de la clase padre desde una subclase\r\n        self.material = 'algodon'\r\n\r\nclass Vestido (Ropa):\r\n    def __init__(self, nombre):\r\n        super().__init__(nombre)\r\n        self.material = 'algodon'\r\n\r\nmanga_corta = Camiseta (\"manga corta\")   # Creo dos instancias una de cada subclase y las inicializo con los nombres que es el 1º atributo\r\nde_fiesta = Vestido (\"de fiesta\")\r\n\r\nmanga_corta.añadir_item(manga_corta.nombre, manga_corta.material, 4)\r\nde_fiesta.añadir_item(de_fiesta.nombre, de_fiesta.material, 6)\r\n\r\nstock_actual = manga_corta.stock_por_material(\"algodon\")\r\n\r\nprint (f\"Tenemos en stock de {manga_corta.nombre}, y {de_fiesta.nombre} en {manga_corta.material} la siguiente cantidad: {stock_actual}\")\r\n# No nos muestra el total por material independiente sino todo lo de algodon, usease 10\r\n\r\nprint()\r\n''' DIFICULTAD EXTRA (opcional):\r\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\r\n * en el ejercicio número 7 de la ruta de estudio)\r\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\r\n *   retornar el número de elementos e imprimir todo su contenido.'''\r\n\r\nprint(\"Stack_pila:\")\r\nclass Stack_pila ():   \r\n\r\n    def __init__(self):\r\n        self.stack =[]  #lista vacía\r\n\r\n    def push_apliar (self, elemento):     # Todas las funciones tienen que recibirse a ellas mismas\r\n        self.stack.append(elemento)\r\n\r\n    def pop_desapilar (self):\r\n        if len(self.stack) >0:            # Podría poner en vez del len, self.contar()\r\n            return self.stack.pop()        # LIFO última en entrar primera en salir\r\n        else:\r\n            return None\r\n        \r\n    def contar (self):\r\n        return len(self.stack)\r\n    \r\n    def imprimir (self):\r\n        for i in reversed(self.stack):   # Si queremos que salga lo último añadido hay que darle la vuelta a la lista con reversed\r\n            print (i)\r\n\r\ninstancia_stack = Stack_pila()          # Creo una instancia\r\ninstancia_stack.push_apliar (1)  \r\ninstancia_stack.push_apliar (2)  \r\ninstancia_stack.push_apliar (3)  \r\ninstancia_stack.imprimir()              # 3 2 1\r\nprint()\r\nprint(instancia_stack.contar())         # 3\r\nprint()\r\ninstancia_stack.pop_desapilar()         # 2\r\ninstancia_stack.imprimir()              # 1\r\nprint()\r\nprint(instancia_stack.pop_desapilar())  # 2\r\nprint(instancia_stack.pop_desapilar())  # 1\r\nprint(instancia_stack.pop_desapilar())  # None\r\nprint()\r\nprint(instancia_stack.contar())         # 0\r\n\r\nprint(\"Queue_cola:\")\r\nclass Queue_cola ():   \r\n\r\n    def __init__(self):\r\n        self.queue =[]  #lista vacía\r\n\r\n    def push_apliar (self, elemento):     # Todas las funciones tienen que recibirse a ellas mismas\r\n        self.queue.append(elemento)\r\n\r\n    def pop_desapilar (self):\r\n        if len(self.queue) >0:            # Podría poner en vez del len, self.contar()\r\n            return self.queue.pop(0)      # FIFO primera en entrar primera en salir así que le digo que la posición 0\r\n        else:\r\n            return None\r\n        \r\n    def contar (self):\r\n        return len(self.queue)\r\n    \r\n    def imprimir (self):\r\n        for i in self.queue:   \r\n            print (i)\r\n\r\ninstancia_queue = Queue_cola()          # Creo una instancia\r\ninstancia_queue.push_apliar (1)  \r\ninstancia_queue.push_apliar (2)  \r\ninstancia_queue.push_apliar (3)  \r\ninstancia_queue.imprimir()              # 1 2 3\r\nprint()\r\nprint(instancia_queue.contar())         # 3\r\nprint()\r\ninstancia_queue.pop_desapilar()         # 2\r\ninstancia_queue.imprimir()              # 3\r\nprint()\r\nprint(instancia_queue.pop_desapilar())  # 2\r\nprint(instancia_queue.pop_desapilar())  # 3\r\nprint(instancia_queue.pop_desapilar())  # None\r\nprint()\r\nprint(instancia_queue.contar())         # 0"
  },
  {
    "path": "Roadmap/08 - CLASES/python/Yisusocanto.py",
    "content": "class Traductor:\n\n    apellido = None\n\n    def __init__(self, name: str, edad: int, idioma: list):\n        self.name = name\n        self.edad = edad\n        self.idioma = idioma\n\n    def print(self):\n        print(f\"Nombre: {self.name} / apellido: {self.apellido} / Edad: {self.edad} / idioma: {self.idioma}\") \n\n\nmi_traductor = Traductor(\"Jesus\", 20, [\"español\", \"ingles\", \"frances\"])\nmi_traductor.print()\nmi_traductor.apellido = \"ocanto\"\nmi_traductor.print()\nmi_traductor.idioma.pop(0)\nmi_traductor.print()\n\n\n#extra\n#\nclass Pila:\n\n    def __init__(self, contenido: list):\n        self.contenido = contenido\n\n    def print(self):\n        print(f\"contenido de la pila: {self.contenido}\")\n\n    def agregar(self, elemento):\n        self.contenido.append(elemento)\n\n    def quitar(self):\n        self.contenido.pop()    \n\n\n\nmi_pila = Pila([\"manzana\"])\nmi_pila.print()\nmi_pila.agregar(\"pera\")\nmi_pila.print()\nmi_pila.quitar()\nmi_pila.print()\n\n\nclass Cola:\n\n    def __init__(self, contenido: list):\n        self.contenido = contenido\n\n    def print(self):\n        print(f\"contenido de la cola: {self.contenido}\")\n\n    def agregar(self, elemento):\n        self.contenido.append(elemento)\n\n    def quitar(self):\n        self.contenido.pop(0)    \n\n\n\nmi_cola = Cola([\"manzana\"])\nmi_cola.print()\nmi_cola.agregar(\"pera\")\nmi_cola.print()\nmi_cola.quitar()\nmi_cola.print()"
  },
  {
    "path": "Roadmap/08 - CLASES/python/adolfolozaa.py",
    "content": "'''\r\n EJERCICIO:\r\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\r\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\r\n * de tu lenguaje).\r\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\r\n * utilizando su función.\r\n *\r\n * DIFICULTAD EXTRA (opcional):\r\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\r\n * en el ejercicio número 7 de la ruta de estudio)\r\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\r\n *   retornar el número de elementos e imprimir todo su contenido.\r\n '''\r\n\r\n\r\nclass Programmer:\r\n    surname: str = None\r\n    def __init__(self, name: str, age: int,  languages: list):\r\n        self.name = name\r\n        self.age = age\r\n        self.languages = languages\r\n\r\n    \r\n    def print(self):\r\n        print(\r\n            f'Name: {self.name} Lastname: {self.surname} Age: {self.age} Languages: {self.languages}')    \r\n\r\n'''my_programmer = Programmer('Adolfo', 25, ['Python', 'Java', 'C++'])\r\nmy_programmer.print()\r\nmy_programmer.surname = 'Loza'\r\nmy_programmer.print()\r\nmy_programmer = Programmer('Pedro', 35, ['Rust', 'Javascript', 'Basic'])\r\nmy_programmer.print()\r\nmy_programmer.age = 40\r\nmy_programmer.print()\r\n'''\r\n\r\n'''\r\n * DIFICULTAD EXTRA (opcional):\r\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\r\n * en el ejercicio número 7 de la ruta de estudio)\r\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar, retornar el número de elementos e imprimir todo su contenido.\r\n '''\r\n\r\n# LIFO (PILA)\r\nprint('---------------------')\r\nprint('Pila(stack) (LIFO)')\r\nclass Stack:\r\n\r\n    def __init__(self):\r\n        self.stack = []\r\n\r\n    def push(self, item):\r\n        self.stack.append(item)\r\n\r\n    def pop(self):\r\n        if self.count() == 0:\r\n            return None\r\n        return self.stack.pop()\r\n    \r\n    def count(self):\r\n        return len(self.stack)\r\n\r\n    def print(self):\r\n        for item in reversed(self.stack):\r\n            print(item)\r\n\r\n\r\nmy_stack = Stack()\r\nmy_stack.push(\"A\")\r\nmy_stack.push(\"B\")\r\nmy_stack.push(\"C\")\r\nprint(my_stack.count())\r\nmy_stack.print()\r\nmy_stack.pop()\r\nprint(my_stack.count())\r\nprint(my_stack.pop())\r\nprint(my_stack.pop())\r\nprint(my_stack.pop())\r\nprint(my_stack.pop())\r\nprint(my_stack.pop())\r\nprint(my_stack.count())\r\n\r\n# FIFO (COLA)\r\nprint('---------------------')\r\nprint('COLAS (QUEUE) (FIFO)')\r\n\r\nclass Queue:\r\n\r\n    def __init__(self):\r\n        self.queue = []\r\n    def enqueue(self, item):\r\n        self.queue.append(item)\r\n    def dequeue(self):\r\n        if self.count() == 0:\r\n            return None\r\n        return self.queue.pop(0)\r\n    def count(self):\r\n        return len(self.queue)  \r\n    def print(self):\r\n        for item in self.queue:\r\n            print(item)     \r\n\r\nmy_queue = Queue()\r\nmy_queue.enqueue(\"A\")\r\nmy_queue.enqueue(\"B\")\r\nmy_queue.enqueue(\"C\")\r\nprint(my_queue.count())\r\nmy_queue.print()\r\nmy_queue.dequeue()\r\nprint(my_queue.count())\r\nprint(my_queue.dequeue())\r\nprint(my_queue.dequeue())\r\nprint(my_queue.dequeue())\r\nprint(my_queue.dequeue())\r\nprint(my_queue.dequeue())\r\nprint(my_queue.count())\r\n    \r\n\r\n\r\n\r\n\r\n\r\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/adra-dev.py",
    "content": "\"\"\"\nEJERCICIO:\nExplora el concepto de clase y crea un ejemplo que implemente un \ninicializador, atributos y una funcion que los imprima (teniendo en \ncuenta las posibilidades de tu lenguaje).\nUna vez implementada, creala, establece sus parametros, modificalos e\nimprimelos utilizando una funcion.\n\nDIFICULTAD EXTRA (opcional):\n- Implementa dos clases que representen las estructuras de Pila y \nCola (estudiadas en el ejercicio numero 7 de la ruta de estudio)\n- Deben poer inicializarse y disponer de operaciones para añadir, \neliminar, retornar el número de elementos e imprimir todo su \ncontenido.\n\nby adra-dev.\n\"\"\"\n\n# POO (Programacion Orientada a Objetos.)\n\n\"\"\"\n            Todo en python es un objeto.\n\nLa progamacion orientada a objetos es un paradigma de progamacion, es\ndecir, un estilo y tecnica de programacion, que va mas alla de la \npropia implementacion. Este paradigma se fundamenta en el concepto de\n<<objeto>>, el cual puede contener tando datos, bajo la forma de \ncampos denominados atributos, como codigo para su manipulacion, bajo \nla forma de procedimientos y funciones, denominados <<metodos>>.\nGracias a esto podemos agruparlo todo bajo un solo tipo de dato (la \n<<clase>> objeto), la cual facilita la modularidad y la reusabilidad \ndel codigo.\n\nLos cuatro principios fundamentales de este paradigma son los \nsiguientes:\n            Abstraccion de datos.\n            Encapsulacion\n            Herencia\n            Polimorfismo.\n\n\"\"\"\n\n\n\"\"\"\nClases:\nUna clase es como un tipo abstracto para los objetos que, ademas de \nalmacenar valores denominados atributos, tiene asociados una serie de\nfunciones que llamamos metodos. Una instacia de una clase es lo mismo\nque decir un objeto de esa clase. Instanciar una clase hace referencia\na la creacion de un objeto que pertenece a esa clase.\n\n\"\"\"\n\nclass Dispositivo:\n    \"\"\" Clase dispositivo, para objetos conectados a la red \"\"\"\n\n    def __init__(self, IP) -> None:\n        \"\"\" Constructor \"\"\"\n        self.IP = IP            # Atributo con valor definido\n        self.encendido = False  # Atributo con valor por defecto\n\n    def __del__(self):\n        \"\"\" Destructor \"\"\"\n        print(\"Destruyendo el dispositivo en\", self.IP)\n\n    def encender(self):\n        \"\"\" Enciende el dispositivo \"\"\"\n        self.encendido = True\n\n    def apagar(self):\n        \"\"\" Apaga el dispositivo \"\"\"\n        self.encendido = False\n\n    def estado(self):\n        \"\"\" Muestra en pantalla el estado del dispositivo \"\"\"\n        mensaje = f\"IP: {self.IP}\\n\"\n        if self.encendido:\n            mensaje += 'Estado: encendido'\n        else:\n            mensaje += 'Estado: apagado'\n        return mensaje\n    \n# Instanciacion\n    \ntv = Dispositivo('4.6.2.3')            # creamos el objeto\n\nprint(tv.encendido)                    # accedemos a un atributo\n\nprint(tv.IP)                           # accedemos a otro atributo\n\nprint(tv.encender())                   # invocamos un metodo\n\nprint(tv.encendido)                    # accedemos al atributo\n\nprint(tv.estado())                     # invocamos un metodo\n\n\n\n\"\"\"\nExtra\n\"\"\"\n\n# LIFO\n\n\nclass Stack:\n\n    def __init__(self):\n        self.stack = []\n\n    def push(self, item):\n        self.stack.append(item)\n\n    def pop(self):\n        if self.count() == 0:\n            return None\n        return self.stack.pop()\n\n    def count(self):\n        return len(self.stack)\n\n    def print(self):\n        for item in reversed(self.stack):\n            print(item)\n\n\nmy_stack = Stack()\nmy_stack.push(\"A\")\nmy_stack.push(\"B\")\nmy_stack.push(\"C\")\nprint(my_stack.count())\nmy_stack.print()\nmy_stack.pop()\nprint(my_stack.count())\nprint(my_stack.pop())\nprint(my_stack.pop())\nprint(my_stack.pop())\nprint(my_stack.pop())\nprint(my_stack.pop())\nprint(my_stack.count())\n\n# FIFO\n\n\nclass Queue:\n\n    def __init__(self):\n        self.queue = []\n\n    def enqueue(self, item):\n        self.queue.append(item)\n\n    def dequeue(self):\n        if self.count() == 0:\n            return None\n        return self.queue.pop(0)\n\n    def count(self):\n        return len(self.queue)\n\n    def print(self):\n        for item in self.queue:\n            print(item)\n\n\nmy_queue = Queue()\nmy_queue.enqueue(\"A\")\nmy_queue.enqueue(\"B\")\nmy_queue.enqueue(\"C\")\nprint(my_queue.count())\nmy_queue.print()\nmy_queue.dequeue()\nprint(my_queue.count())\nprint(my_queue.dequeue())\nprint(my_queue.dequeue())\nprint(my_queue.dequeue())\nprint(my_queue.dequeue())\nprint(my_queue.dequeue())\nprint(my_queue.count())\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/agusrosero.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n * \n */\n\"\"\"\n\n# EJERCICIO:\n\n\nclass Persona:\n    def __init__(self, nombre, apellido):\n        self.nombre = nombre\n        self.apellido = apellido\n\n    def __str__(self):\n        return f'Nombre: {self.nombre}, Apellido: {self.apellido}'\n\n    def saludar(self):\n        return f'¡Hola {self.nombre} {self.apellido}!'\n\n    def despedir(self):\n        return f'¡Adiós {self.nombre} {self.apellido}!'\n\n\nobjeto1 = Persona('Hernan', 'Rosero')\nprint(objeto1)\nprint(objeto1.saludar())\nprint(objeto1.despedir())\n\n# DIFICULTAD EXTRA:\n\n\nclass Pila:\n    def __init__(self):\n        self.items = []\n\n    def add(self, value):\n        self.items.append(value)\n        print(self.items)\n\n    def delete(self):\n        elemento_eliminado = self.items.pop()\n        return elemento_eliminado\n\n    def number_of_elements(self):\n        numero_de_elementos = len(self.items)\n        if numero_de_elementos == 0:\n            return 0\n        else:\n            return numero_de_elementos\n\n    def get_information(self):\n        print(self.items)\n\n\npila1 = Pila()\npila1.add(1)\npila1.add(2)\npila1.add(3)\nprint(pila1.delete())\nprint(pila1.number_of_elements())\npila1.get_information()\n\n\nclass Cola:\n    def __init__(self):\n        self.items = []\n\n    def add(self, value):\n        self.items.insert(0, value)\n        print(self.items)\n\n    def delete(self):\n        elemento_eliminado = self.items.pop()\n        return elemento_eliminado\n\n    def number_of_elements(self):\n        numero_de_elementos = len(self.items)\n        if numero_de_elementos == 0:\n            return 0\n        else:\n            return numero_de_elementos\n\n    def get_information(self):\n        print(self.items)\n\n\ncola1 = Cola()\ncola1.add(1)\ncola1.add(2)\ncola1.add(3)\nprint(cola1.delete())\nprint(cola1.number_of_elements())\ncola1.get_information()\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/alanshakir.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n * \n */\n\"\"\"\nclass Person:\n        \n    def __init__(self, name, surname):\n        self.name = name\n        self.surname = surname\n\n    def get_name(self):\n        return self.name\n\n    def perso_info(self):\n        print(f\"Mi nombre es: {self.name} y mi apellido es: {self.surname}\")\n    \nmy_person = Person(\"Nicolle\", \"Ramirez\")\nmy_person.perso_info()\n\nmy_person = Person(\"Matheo\", \"ramirez\")\nmy_person.perso_info()\n\nclass Pila:\n    def __init__(self):\n        self.my_class_pila = []\n    \n    def is_empty(self):\n        return len(self.my_class_pila) == 0\n    \n    def agregar_elemento(self, elemento):\n        self.my_class_pila.append(elemento)\n    \n    def eliminar_elemento(self):\n        if not self.is_empty():\n            self.my_class_pila.pop()\n    \n    def imprimir_elemento(self):\n        for n in reversed(self.my_class_pila):\n            print(n)\n\nmy_pila = Pila()\nmy_pila.agregar_elemento(\"python\") \nmy_pila.agregar_elemento(\"fastapi\")\nmy_pila.agregar_elemento(\"github\")\nmy_pila.imprimir_elemento()\nmy_pila.eliminar_elemento()\nmy_pila.imprimir_elemento()\n\nclass Cola:\n    def __init__(self):\n        self.my_class_cola = []\n    \n    def is_empty(self):\n        return len(self.my_class_cola) == 0\n    \n    def agregar_elemento(self, elemento):\n        self.my_class_cola.append(elemento)\n    \n    def eliminar_elemento(self):\n        if not self.is_empty():\n            self.my_class_cola.pop(0)\n    \n    def imprimir_elemento(self):\n        for n in self.my_class_cola:\n            print(n)\n\n\nqueue = Cola()\nqueue.agregar_elemento(\"retos\") \nqueue.agregar_elemento(\"programacion\")\nqueue.agregar_elemento(\"logica\")\nqueue.imprimir_elemento()\nqueue.eliminar_elemento()\nqueue.imprimir_elemento()\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/alexdevrep.py",
    "content": "'''\n/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n */\n'''\n\n# Declaramos una clase en Python\nclass ejemplo:\n    #Inicializamos la clase \n    def __init__(self, saludo,nombre):\n        #Atributos de la clase\n        self.saludo= saludo\n        self.nombre= nombre\n    \n    def saludar(self): #Esta es la función que va a imprimir los atributos de la clase tambien llamado método\n        print(f'{self.saludo},{self.nombre}')\n\n#Creamos instancias de la clase ejemplo \nsaludo = ejemplo(\"Hola\",\"Alexdevrep\")\nsaludo.saludar()\n#Modificamos los atributos de la clase \nsaludo.nombre = \"Python\"\nsaludo.saludar() #instancia (saludo).método(saludar)()\n\n\n\n#Dificultad EXTRA\n#Pilas\nclass Pila:\n    def __init__(self):\n        self.elementos = []\n    \n    def añadir(self, elemento):\n        self.elementos.append(elemento)\n    \n    def eliminar(self):\n        if len(self.elementos) == 0:\n            print(\"La pila está vacía\")\n            return\n        else:\n            return self.elementos.pop()\n    \n    def imprimirTodo(self):\n        if len(self.elementos)==0:\n            print(\"La pila está vacía\")\n            return\n        else:\n            print(\"Contenido de la pila\")\n            for index, elemento in enumerate(self.elementos, start=1) :\n                print(index,elemento)\n                \n\n    def numeroElementos(self):\n        return len(self.elementos)\n\n\n#Creamos la instancia de la clase \nmiPila= Pila()\n\n#Añadimos elementos a la pila\n\nmiPila.añadir(\"Objeto 1\")\nmiPila.añadir(\"Objeto 2\")\nmiPila.añadir(\"Objeto 3\")\n\nmiPila.imprimirTodo()\n\n#Eliminamos el último elemento añadido en la Pila\nmiPila.eliminar()\nmiPila.imprimirTodo()\n\n#Comprobamos que el número de elementos en la pila es el correcto (2)\nnumero=miPila.numeroElementos()\nprint(f'El número de elementos que hay en la Pila es {numero}')\n\n#Colas\n#Importamos las librerías necesarias\nfrom collections import deque\n\nclass Cola:\n    def __init__(self):\n        self.objetos =deque([])\n    def insertar(self, objeto):\n        self.objetos.append(objeto)\n    def borrar(self):\n        if len(self.objetos)==0:\n            print(\"La cola está vacía\")\n            return\n        else:\n            return self.objetos.popleft()\n    def imprimir(self):\n        if len(self.objetos)==0:\n            print(\"La cola está vacía\")\n            return\n        else:\n            print(\"Contenido de la Cola\")\n            for index , objeto in enumerate(self.objetos, start=1):\n                print(index,objeto)\n    \n    def numeroObjetos(self):\n        return len(self.objetos)\n\n\n#Creamos una nueva instancia\nmiCola = Cola()\n\nmiCola.insertar(\"Objeto 1\")\nmiCola.insertar(\"Objeto 2\")\nmiCola.insertar(\"Objeto 3\")\n\n#Imprimimos los objetos que hay en la cola\nmiCola.imprimir()\n\n#Vamos a eliminar el primer objeto añadido a la cola \nmiCola.borrar()\nmiCola.imprimir()\n\n#Comprobamos que la cola tiene los objetos deseados despues de la modificación (2)\nnumeroObjetos=miCola.numeroObjetos()\nprint(f'El número de objetos que hay en la cola es: {numeroObjetos}')\n\n\n        \n\n            \n\n\n\n        "
  },
  {
    "path": "Roadmap/08 - CLASES/python/andres54-coder.py",
    "content": "'''\nEjercicio\n'''\n\nclass Programmer:\n    \n    surname : str = ''\n    \n    def __init__ (self, name: str, age: int, lenguages: list):\n        self.name = name\n        self.age = age\n        self.lenguages= lenguages\n\n    def print(self):\n        print(\n            f\"Nombre {self.name}| Apellidos: {self.surname} | Edad: {self.age} | lenguages: {self.lenguages}\"\n        )\n        \nmy_programmer = Programmer('Andres',25, ['java','go','swift'])\nmy_programmer.print()\nmy_programmer.surname = 'Castañeda'\nmy_programmer.print()\nmy_programmer.age=24\nmy_programmer.print()\n\n'''\nExtra\n'''\n\nclass Stack:\n    \n    def __init__(self):\n        self.stack = []\n    def push(self, item):\n        self.stack.append(item)\n    def pop(self):\n        if self.count == 0:\n            return None\n        return self.stack.pop()\n    def count(self):\n        return len(self.stack)\n    def print(self):\n        for item in reversed(self.stack):\n            print(item)\n            \nmy_stack = Stack()\nmy_stack.push('a')\nmy_stack.push('b')\nmy_stack.push('c')\nmy_stack.push('d')\nprint(my_stack.count())\nmy_stack.print()\nmy_stack.pop()\nprint(my_stack.count())\n\n'''\n#FIFO\n'''\n\nclass Queue:\n    \n    def __init__(self):\n        self.queue = []\n    \n    def equeue(self, item):\n        self.queue.append(item)\n    def deequeue(self):\n        if self.count() == 0:\n            return None\n        self.queue.pop(0)\n    def count(self):\n        return len(self.queue)\n    def print(self):\n        for item in self.queue:\n            print(item)   \n\nmy_queue = Queue()\nmy_queue.equeue('a')\nmy_queue.equeue('b')\nmy_queue.equeue('c')\nmy_queue.equeue('d')\nprint(my_queue.count())\nmy_queue.print()\nmy_queue.deequeue()\nmy_queue.deequeue()\nmy_queue.deequeue()\nmy_queue.deequeue()\nmy_queue.deequeue()\nmy_queue.deequeue()\nmy_queue.deequeue()\nprint(my_queue.count())"
  },
  {
    "path": "Roadmap/08 - CLASES/python/annerssv.py",
    "content": "#CLASES en PYHTON\n\nclass Developer:\n    def __init__(self, name : str, age : int):\n        self.name = name\n        self.age = age\n        \n    def saludar(self):\n        print(f\"Hola soy el desarrollador {self.name} y tengo {self.age} años\")\n        \n\ndesarrollador_1 = Developer(\"Juan\", 22)\ndesarrollador_1.saludar()\ndesarrollador_1.name = \"Pablo\"\ndesarrollador_1.age= 25\ndesarrollador_1.saludar()\n\n\n#EJERCICIO EXTRA\n\n\nclass Pila:\n    \n    def __init__(self):\n        self.stack = []\n        \n    def apilar(self, item):\n        self.stack.append(item)\n    \n    def desapilar(self):\n        if self.contador() == 0:\n            return None\n        return self.stack.pop()\n    \n    def contador(self):\n        return len(self.stack)\n    \n    def listar(self):\n        for i in reversed(self.stack):\n            print(i)\n\n# mi_pila = Pila()\n# mi_pila.apilar(\"ITEM1\")\n# mi_pila.apilar(\"ITEM2\")\n# mi_pila.apilar(\"ITEM3\")\n# mi_pila.contador()\n# mi_pila.listar()\n# mi_pila.desapilar()\n# print(\"-------------------\")\n# mi_pila.contador()\n# mi_pila.listar()\n\nclass Cola:\n    def __init__(self):\n        self.line = []\n        \n    def encolar(self, item):\n        self.line.append(item)\n    \n    def desencolar(self):\n        if self.contador() == 0:\n            return None\n        return self.line.pop(0)\n    \n    def contador(self):\n        return len(self.line)\n    \n    def listar(self):\n        for i in (self.line):\n            print(i)\n\ncola_1 = Cola()\ncola_1.encolar(\"ITEM1\")\ncola_1.encolar(\"ITEM2\")\ncola_1.encolar(\"ITEM3\")\nprint(cola_1.contador())\ncola_1.listar()\ncola_1.desencolar()"
  },
  {
    "path": "Roadmap/08 - CLASES/python/any7dev.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n#  * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n#  * de tu lenguaje).\n#  * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n#  * utilizando su función.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n#  * en el ejercicio número 7 de la ruta de estudio)\n#  * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n#  *   retornar el número de elementos e imprimir todo su contenido.\n#  * \n#  */\n\n# EJERCICIO\nclass Vehiculo:\n    def __init__(self, tipo, marca, modelo):\n        self.tipo = tipo\n        self.marca = marca\n        self.modelo = modelo\n    def imprimir(self):\n        print(f\"Soy un {self.tipo} de la marca {self.marca} modelo {self.modelo}\")\n\nmi_vehiculo = Vehiculo(\"coche\", \"Toyota\", \"Auris\")\nmi_vehiculo.imprimir()\n\n#DIFICULTAD EXTRA\nclass Pila:\n    def __init__(self, lista):\n        self.lista = lista\n    def añadir(self, numero):\n        self.lista.append(numero)\n    def eliminar(self):\n        self.lista.pop()\n    def elementos(self):\n        return len(self.lista)\n    def imprimir(self):\n        print(self.lista)\n\nmi_pila = Pila(lista=[1, 2, 3, 4, 5])\nmi_pila.añadir(6)\nmi_pila.eliminar()\nprint(mi_pila.elementos())\nmi_pila.imprimir()\n\nclass Cola:\n    def __init__(self, cola):\n        self.cola = cola\n    def añadir(self, numero):\n        self.cola.append(numero)\n    def eliminar(self):\n        self.cola.pop(0)\n    def elementos(self):\n        return len(self.cola)\n    def imprimir(self):\n        print(self.cola)\n\nmi_cola = Cola(cola=[6, 7, 8, 9, 10])\nmi_cola.añadir(11)\nmi_cola.eliminar()\nprint(mi_cola.elementos())\nmi_cola.imprimir()"
  },
  {
    "path": "Roadmap/08 - CLASES/python/avcenal.py",
    "content": "\"\"\"\nEJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n\"\"\"\n\nclass Person():\n    def __init__(self,name, lastname):\n        self.__fullname = f\"Tu nombre es {name} y tu apellido es {lastname}\"\n    \n    def show(self):\n        print(self.__fullname)\n\nmy_person = Person(\"Alex\",\"Valderrama\")\nmy_person.show()\nmy_person = Person(\"Brais\",\"Moure\")\nmy_person.show()\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n\"\"\"\nclass Stack:\n    def __init__(self):\n        self.__stack = list()\n\n    def push(self,item): #apilar\n        temp = list()\n        if len((self.__stack)) == 0:\n            self.__stack.append(item)\n        else:\n            temp= self.__stack.copy()\n            self.__stack.clear()\n            self.__stack.append(item)\n            self.__stack.extend(temp)\n        return self.__stack\n    \n    def pop(self): #desapilar\n        if self.empty():\n            print(\"La pila está vacía, no se puede desapilar nada\")\n        else:\n            self.__stack = self.__stack[1:]\n        return self.__stack\n    \n    def top(self): #devuelve el primer elemento de la pila\n        return self.__stack[0]\n    \n    def size(self): #devuelve la longitud de la pila\n        return len(self.__stack)\n\n    def show(self): #muestra la pila\n        print(self.__stack)\n\n    def empty(self): #devuelve un boolean según la pila esté vacía o no\n        if self.size() == 0:\n            return True\n        else:\n            return False\n        \nmy_stack = Stack()\nprint(my_stack.empty())\nmy_stack.pop()\nmy_stack.push(1)\nmy_stack.push(2)\nmy_stack.push(3)\nmy_stack.show()\nmy_stack.pop()\nmy_stack.show()\nprint(my_stack.top())\nmy_stack.size()\n    \nclass Queue():\n    def __init__(self):\n        self.__queue = list()\n\n    def enqueue (self,item): #encolar\n        return self.__queue.append(item)\n\n    def dequeue(self): #desencolar\n        try:\n            self.__queue = self.__queue[1:]\n        except IndexError:\n            print(\"La cola está vacía, no se puede desencolar nada\")\n        finally:\n            return self.__queue\n        \n    def front(self): #devuelve el primer item que entró en la cola\n        return self.__queue[0]\n    \n    def size(self): #según he investigado, la estructura \"cola\" no debería tener un método que muestre su longitud\n        return len(self.__queue) #aún así queda implementado en estas líneas\n    \n    def show(self): #imprime la cola\n        if self.size() == 0:\n            print(\"La cola está vacía\")\n        else:\n            print(self.__queue)\n    \nmy_queue = Queue()\nmy_queue.show()\nmy_queue.enqueue(\"Mi nombre\")\nmy_queue.enqueue(\"es Alex\")\nmy_queue.enqueue(\"Valderrama\")\nmy_queue.show()\nprint(my_queue.front())\nmy_queue.dequeue()\nmy_queue.show()\nprint(my_queue.size())\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/cesar-ch.py",
    "content": "\"\"\"\n    #08 CLASES \n\"\"\"\n\n\nclass Persona:\n    def __init__(self, nombre, edad):\n        self.nombre = nombre\n        self.edad = edad\n\n    def imprimir_informacion(self):\n        print(f\"Nombre: {self.nombre}\")\n        print(f\"Edad: {self.edad}\")\n\n    def set_nombre(self, nombre):\n        self.nombre = nombre\n\n    def get_nombre(self):\n        return self.nombre\n\n    def set_edad(self, edad):\n        self.edad = edad\n\n    def get_edad(self):\n        return self.edad\n\n\nperson1 = Persona(\"Juan\", 30)\nperson1.imprimir_informacion()\nperson1.set_nombre(\"Pedro\")\nperson1.set_edad(25)\nperson1.imprimir_informacion()\nprint(person1.get_nombre())\nprint(person1.get_edad())\n\n\"\"\"\n  DIFICULTAD EXTRA\n\"\"\"\n\n\nclass Pila:\n    def __init__(self, pila):\n        self.pila = pila\n\n    def push(self, dato):\n        self.pila.append(dato)\n\n    def pop(self):\n        return self.pila.pop()\n\n    def imprimir(self):\n        print(self.pila)\n\n\npila1 = Pila([])\npila1.push(1)\npila1.push(2)\npila1.push(3)\npila1.imprimir()\nprint(pila1.pop())\npila1.imprimir()\n\n\nclass Cola:\n    def __init__(self, cola):\n        self.cola = cola\n\n    def enqueue(self, dato):\n        self.cola.append(dato)\n\n    def dequeue(self):\n        return self.cola.pop(0)\n\n    def imprimir(self):\n        print(self.cola)\n\n\ncola1 = Cola([])\ncola1.enqueue(1)\ncola1.enqueue(2)\ncola1.enqueue(3)\ncola1.imprimir()\nprint(cola1.dequeue())\ncola1.imprimir()\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/clmiranda.py",
    "content": "# CLASES\n\n# CLASE CON INICIALIZADOR, ATRIBUTOS Y UNA FUNCIÓN QUE LOS IMPRIMA\nclass Perro:\n    def __init__(self, nombre, raza, sexo, edad) -> None:\n        self.nombre = nombre\n        self.raza = raza\n        self.edad = edad\n        self.sexo = sexo\n    \n    def imprimir(self):\n        print(f\"{self.nombre} es un {self.raza}, es {self.sexo} y tiene {self.edad} años de edad.\")\n    \n    def actualizar_datos(self, nuevo_nombre, nueva_raza, nuevo_sexo, nueva_edad):\n        self.nombre = nuevo_nombre\n        self.raza = nueva_raza\n        self.edad = nueva_edad\n        self.sexo = nuevo_sexo\n        \nperro = Perro(\"Duke\", \"Golden Retriever\", \"macho\", 2)\nperro.imprimir()\n\nperro.actualizar_datos(\"Floppy\", \"Chihuahua\", \"hembra\", 3)\nperro.imprimir()\n\n\n\n# EJERCICIO - DIFICULTAD EXTRA\n\n# PILA\nclass PilaCartas:\n    def __init__(self) -> None:\n        self.pila = []\n\n    def agregar(self, carta):\n        self.pila.append(carta)\n    \n    def quitar(self):\n        if self.pila:\n            last = self.pila.pop()\n            print(f\"Se quitó la carta: {last}\")\n        else:\n            print(\"La pila esta vacía, no se puede quitar más cartas\")\n\n    def imprimir(self):\n        print(f\"Las cartas de la pila son: {self.pila}\")\n\ncarta = PilaCartas()\n\ncarta.agregar(\"Rey de corazón\")\ncarta.agregar(\"As de corazón\")\ncarta.agregar(\"Trebol de espadas\")\ncarta.imprimir()\n\ncarta.quitar()\ncarta.imprimir()\n\n\n# COLA\nclass ColaCajero:\n    def __init__(self) -> None:\n        self.cola = []\n\n    def agregar(self, persona):\n        self.cola.append(persona)\n    \n    def quitar(self):\n        if self.cola:\n            first = self.cola.pop(0)\n            print(f\"{first} ingresó al cajero\")\n        else:\n            print(\"La cola esta vacía\")\n\n    def imprimir(self):\n        print(f\"Las personas en la cola son: {self.cola}\")\n\ncola = ColaCajero()\n\ncola.agregar(\"Juan\")\ncola.agregar(\"Ana\")\ncola.agregar(\"Pedro\")\ncola.imprimir()\n\ncola.quitar()\ncola.imprimir()"
  },
  {
    "path": "Roadmap/08 - CLASES/python/cristianfloyd.py",
    "content": "#  * EJERCICIO:\n#  * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n#  * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n#  * de tu lenguaje).\n#  * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n#  * utilizando su función.\n\n\nclass Programador:\n    def __init__(self, nombre: str, lenguaje: list):\n        self.nombre = nombre\n        self.lenguaje = lenguaje\n\n    def imprimir_info(self):\n        print(f\"Programador: {self.nombre}, Lenguaje: {self.lenguaje}\")\n    \n    def __str__(self):\n        return f\"Programador: {self.nombre}, Lenguaje: {self.lenguaje}\"\n\n\ncristianfloyd = Programador(\"Cristian Floyd\", [\"Python\"])\ncristianfloyd.imprimir_info()\nprint(cristianfloyd)\n\ncristianfloyd.lenguaje.append(\"JavaScript\")\ncristianfloyd.imprimir_info()\nprint(cristianfloyd)\n\ncristianfloyd.nombre = \"C. Floyd\"\ncristianfloyd.imprimir_info()\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n#  * en el ejercicio número 7 de la ruta de estudio)\n#  * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n#  *   retornar el número de elementos e imprimir todo su contenido.\n\n\nclass Pila:\n    def __init__(self, elementos=[]) -> None:\n        self.elementos = elementos\n\n    def push(self, elemento) -> None:\n        \"\"\"Añade un elemento a la pila.\"\"\"\n        self.elementos.append(elemento)\n\n    def pop(self):\n        \"\"\"Elimina y retorna el último elemento de la pila.\"\"\"\n        if self.count() == 0:\n            return None\n        return self.elementos.pop()\n\n    def count(self) -> int:\n        return len(self.elementos)\n\n    def imprimir(self) -> None:\n        print(f\"Pila: {self.elementos}\")\n\n    def mostrar(self) -> None:\n        for elemento in reversed(self.elementos):\n            print(elemento)\n\n    def __len__(self) -> int:\n        return self.count()\n\n\npila = Pila()\npila.push(\"A\")\npila.push(\"B\")\npila.push(\"C\")\npila.imprimir()\nprint(f\"Cantidad de elementos en la pila: {pila.count()}\")\npila.pop()\npila.imprimir()\n\nprint(len(pila))\n\n\nclass Cola:\n    def __init__(self, elementos=[]) -> None:\n        self.elementos = elementos\n\n    def enqueue(self, elemento) -> None:\n        \"\"\"Añade un elemento a la cola.\"\"\"\n        self.elementos.append(elemento)\n\n    def dequeue(self):\n        \"\"\"Elimina y retorna el primer elemento de la cola.\"\"\"\n        if self.count() == 0:\n            return None\n        return self.elementos.pop(0)\n\n    def count(self) -> int:\n        return len(self.elementos)\n\n    def imprimir(self) -> None:\n        print(f\"Cola: {self.elementos}\")\n\n    def mostrar(self) -> None:\n        for elemento in self.elementos:\n            print(elemento)\n\n    def __len__(self) -> int:\n        return self.count()\n\ncola = Cola([1, 2, 3])\ncola.imprimir()\ncola.enqueue(4)\ncola.imprimir()\nprint(f\"Cantidad de elementos en la cola: {cola.count()}\")\ncola.dequeue()\ncola.imprimir()\nprint(len(cola))"
  },
  {
    "path": "Roadmap/08 - CLASES/python/danielhdzr.py",
    "content": "# #08 CLASES\n#### Dificultad: Fácil | Publicación: 19/02/24 | Corrección: 26/02/24\n\n## Ejercicio\n\n\n\"\"\" \n* EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n \n \"\"\"\n \ndef main():\n    class my_class:\n        \"\"\"\n        Funcion inicializadora __init__()\n        Self hace referencia a la clase en si misma, y a todo lo que en ella hay guardado. Puedes llamarla como quieras\n        \"\"\"\n        def __init__(self, name, last_name):\n            # Los valores que asignaremos a los parametros se guardaran en las variables \"nombre\" y \"apellido\"\n            self.nombre = name\n            self.apellido = last_name\n\n        # Creo un metodo para saludar. Accedo a las variables en mi clase mediante la sintaxis \"clase.variable\"\n        def saludo(self):\n            print(f\"Hola, mi nombre completos es: {person.nombre} {person.apellido}\")\n\n    # Guardo mi clase y sus argumentos en una variable fuera de mi clase\n    person = my_class(\"Daniel\", \"Hernandez\")\n\n    # Llamo a mi clase (guardada en la variable \"person\") y ejecuto el metodo saludo, \n    person.saludo()\n\n    # Modifico los valores en las variables\n    person.apellido = \"Renteria\"\n    person.saludo()\n\n    \"\"\"\n    DIFICULTAD EXTRA (opcional):\n    Implementa dos clases que representen las estructuras de pila y Cola (estudiadas\n    en el ejercicio número 7 de la ruta de estudio)\n    Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n    retornar el número de elementos e imprimir todo su contenido.\n    \"\"\"\n\n    # clase_pila\n    class clase_pila:\n        def __init__(self):\n            # Variable que contendra nuestra clase_pila\n            self.mi_pila = []\n\n        def agregar(self, value):\n            self.mi_pila.append(value)\n            print(self.mi_pila)\n\n        def eliminar(self):\n            self.mi_pila.pop()\n            print(self.mi_pila)\n            \n        def retornar(self):\n            retorno = self.mi_pila.pop()\n            print(f\"Retorno: {(retorno)}\")\n\n        def imprimir(self):\n            print(f\"Pila final {self.mi_pila}\")\n    \n    print(\"-----Pila-----\")\n    # Guardo la clase \"clase_pila\" en una variable\n    pila = clase_pila()\n    # Agrego\n    pila.agregar(1)\n    pila.agregar(2)\n    pila.agregar(3)\n    pila.agregar(4)\n    pila.agregar(5)\n    # Elimino el 5 (la pila ahora es de 4)\n    pila.eliminar()\n    # Retorno el 4, y la pila ahora es de 3\n    pila.retornar()\n    # Imprimo la pila final\n    pila.imprimir()\n\n\n    # Clase_cola\n    class clase_cola:\n        # Variable que contendra nuestra clase_cola\n        def __init__(self) -> None:\n            self.cola = []\n        \n        def agregar(self, value):\n            self.cola.append(value)\n            print(self.cola)\n\n        def eliminar(self):\n            self.cola.pop(0)\n            print(self.cola)\n            \n        def retornar(self, ):\n            retorno = self.cola.pop(0)\n            print(f\"Retorno: {(retorno)}\")\n\n        def imprimir(self):\n            print(f\"Cola final {self.cola}\")\n\n    print(\"-----Cola-----\")\n    # Guardo la clase \"clase_cola\" en una variable\n    cola = clase_cola()\n    # Agrego\n    cola.agregar(1)\n    cola.agregar(2)\n    cola.agregar(3)\n    cola.agregar(4)\n    cola.agregar(5)\n    # Elimino el 1 (index 0), la cola ahora es de 4 (index 0,1,2,3)\n    cola.eliminar()\n    # Retorno el 2 (index 0), y la cola ahora es: 3, 4, 5\n    cola.retornar()\n    # Imprimo la cola final\n    cola.imprimir()\n\n    \n            \nif __name__==\"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/davidrguez98.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n * \n */ \"\"\"\n\n#EJERCICIO\n\nclass programmer:\n\n    surname: str = None\n\n    def __init__(self, name: str, age: int, languages: list):\n        self.name = name\n        self.age = age\n        self.languages = languages\n\n    def print(self):\n        print(f\"Nombre: {self.name} | Apellido: {self.surname} | Edad: {self.age} | Lenguajes: {self.languages}\")\n\nmy_programmer = programmer(\"David\", 26, [\"Python\", \"HTML\", \"CSS\"])\nmy_programmer.print()\nmy_programmer.surname = \"Rodríguez\"\nmy_programmer.print()\n\nmy_programmer.age = 27\nmy_programmer.print()\n\n#DIFICULTAD EXTRA\n\n#Pila\n\nclass pila:\n\n    def __init__(self):\n        self.pila = []\n\n    def add(self, item):\n        self.pila.append(item)\n\n    def delete(self):\n        return self.pila.pop()\n\n    def count(self):\n        print(len(self.pila))\n\n    def print(self):\n        for item in reversed(self.pila):\n            print(item)\n\n\nmy_pila = pila()\nmy_pila.add(\"1\")\nmy_pila.add(\"2\")\nmy_pila.add(\"3\")\nmy_pila.count()\nmy_pila.print()\n\nmy_pila.delete()\nmy_pila.count()\nmy_pila.print()\n\n#Cola\n\nclass cola:\n\n    def __init__(self):\n        self.cola = []\n\n    def add(self, item2):\n        self.cola.append(item2)\n\n    def delete(self):\n        return self.cola.pop(0)\n\n    def count(self):\n        print(len(self.cola))\n\n    def print(self):\n        for item2 in reversed(self.cola):\n            print(item2)\n\n\nmy_cola = cola()\nmy_cola.add(\"1\")\nmy_cola.add(\"2\")\nmy_cola.add(\"3\")\nmy_cola.count()\nmy_cola.print()\n\nmy_cola.delete()\nmy_cola.count()\nmy_cola.print()"
  },
  {
    "path": "Roadmap/08 - CLASES/python/devVdroid01.py",
    "content": "\"\"\"\n    EJERCICIO:\n    Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n    atributos y una función que los imprima (teniendo en cuenta las posibilidades\n    de tu lenguaje).\n    Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n    utilizando su función.\n\"\"\"\n\nclass Computadora:\n    def __init__(self, marca, color, precio):\n        self.marca = marca\n        self.color = color\n        self.precio = precio\n\n    def ver_atributos(self):\n        print(f\"Carácterísticas de la computadora: {self.marca}, {self.color}, {self.precio}.\")\n\n# Creamos una instancia de la clase 'Computadora'\ncompu_ph = Computadora(\"HP\", \"Azul\", 7999)\n\n# Llamamos al método \"ver_atributos\"\ncompu_ph.ver_atributos()\n\n# Cambiamos algunos atributos, por ejemplo, el color y precio.\ncompu_ph.color = \"Rojo\"\ncompu_ph.precio = 10000\n\n# Volvemos a llamar el método para ver los cambios\ncompu_ph.ver_atributos()\n\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\nImplementa dos clases que representen las estructuras de Pila y Cola (estudiadas\nen el ejercicio número 7 de la ruta de estudio)\n    - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n    retornar el número de elementos e imprimir todo su contenido.\n\"\"\"\n\n############################\n# Clase Pila/Stack (LIFO) #\n###########################\n\nclass Pila:\n    def __init__(self):\n        self.stack = []\n    \n    def insertar(self, element):\n        self.stack.append(element) # Push\n\n    def eliminar(self):\n        if len(self.stack) > 0:\n            self.stack.pop() # Pop\n        else:\n            Pila.vacio()\n\n    def all_elements(self):\n        if len(self.stack) > 0:\n            print(f\"La Pila tiene estos elementos: {self.stack}\")\n        else:\n            Pila.vacio()\n\n    def total_elements(self):\n        if len(self.stack) > 0:\n            print(f\"Total de elementos de la Pila: {len(self.stack)}\") \n        else:\n            Pila.vacio()\n\n    def vacio():\n        print(\"Pila vacía\")\n\n\n# Creamos una instancia de la clase\npila1 = Pila()\n\n# Usamos el método \"insertar\" para poner elementos en la pila (1, \"uno\", 2 y \"dos\" respectivamente)\npila1.insertar(1)\npila1.insertar(\"uno\")\npila1.insertar(2)\npila1.insertar(\"dos\")\n\n# Usamos el método 'eliminar' para eliminar el último elemento de la pila\npila1.eliminar()\n\n# Vemos los elementos con el que se quedó la pila y el total de este\npila1.total_elements() #Total\npila1.all_elements() #Elementos\n\n\n# Creamos una función para manipular los valores de la pila ya instanciada\ndef clase_pila():\n     while True:\n        action = input(\"Elige una opción para manipular la pila: insertar/eliminar/ver/total/salir: \")\n        if action == \"insertar\":\n            insert = input(\"Escriba lo que desea insertar a la pila: \")\n            pila1.insertar(insert)\n        elif action == \"eliminar\":\n            pila1.eliminar()\n        elif action == \"ver\":\n            pila1.all_elements()\n        elif action == \"total\":\n            pila1.total_elements()\n        elif action == \"salir\":\n            break\n        else:\n            pass\n\n#clase_pila()\n\n############################\n# Clase Cola/Queue (FIFO) #\n###########################\n\nclass Cola:\n    def __init__(self):\n        self.queue = []\n\n    def insertar(self, element):\n        self.queue.append(element) # Push\n\n    def eliminar(self):\n        if len(self.queue) > 0:\n            self.queue.pop(0) # Pop\n        else:\n            Cola.vacio()\n\n    def all_elements(self):\n        if len(self.queue) > 0:\n            print(f\"La Cola tiene estos elementos: {self.queue}\")\n        else:\n            Cola.vacio()\n\n    def total_elements(self):\n        if len(self.queue) > 0:\n            print(f\"Total de elementos de la Cola: {len(self.queue)}\") \n        else:\n           Cola.vacio()\n\n    def vacio():\n        print (\"Cola vacío\")\n\n\n# Creamos una instancia de la clase Cola\ncola1 = Cola()\n\n# Usamos el método \"insertar\" para poner elementos en la cola (1, 2, 3 y 4 respectivamente)\ncola1.insertar(1)\ncola1.insertar(2)\ncola1.insertar(3)\ncola1.insertar(4)\n\n# Usamos el método 'eliminar' para  eliminar el primer elemento de la Cola\npila1.eliminar()\n\n# Vemos los elementos con el que se quedó la Cola y el total de este\ncola1.total_elements() #Total\ncola1.all_elements() #Elementos\n\n\n\n# Creamos una función para manipular los valores de la Cola ya instanciada\ndef clase_cola():\n     while True:\n        action = input(\"Elige una opción para manipular la Cola: insertar/eliminar/ver/total/salir: \")\n        if action == \"insertar\":\n            insert = input(\"Escriba lo que desea insertar a la Cola: \")\n            cola1.insertar(insert)\n        elif action == \"eliminar\":\n            cola1.eliminar()\n        elif action == \"ver\":\n            cola1.all_elements()\n        elif action == \"total\":\n            cola1.total_elements()\n        elif action == \"salir\":\n            break\n        else:\n            pass\n\nclase_cola()"
  },
  {
    "path": "Roadmap/08 - CLASES/python/dgquintero.py",
    "content": "# Estudio de Clases en python\n# Autor: Daniel Quintero\n\n\"\"\"\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n * \n */\n\"\"\"\n\nclass Clase:\n  def __init__(self, nombre, edad):\n    self.nombre = nombre\n    self.edad = edad\n\n  def imprimir(self):\n    print(\"Nombre: \", self.nombre)\n    print(\"Edad: \", self.edad)\n\n\nclase = Clase(\"Daniel\", 32)\nclase.imprimir()\nclase.nombre = \"Daniel Quintero\"\nclase.imprimir()\n\nclass Pila:\n  def __init__(self):\n    self.pila = []\n\n  def apilar(self, elemento):\n    self.pila.append(elemento)\n\n  def desapilar(self):\n    return self.pila.pop()\n\n  def esta_vacia(self):\n    return len(self.pila) == 0\n\n  def tamano(self):\n    return len(self.pila)\n\n  def imprimir(self):\n    print(self.pila)\n\n\npila = Pila()\npila.apilar(1)\npila.apilar(2)\npila.apilar(3)\npila.imprimir()\nprint(pila.desapilar())\nprint(pila.desapilar())\nprint(pila.desapilar())\n\nclass Cola:\n  def __init__(self):\n    self.cola = []\n\n  def agregar(self, elemento):\n    self.cola.append(elemento)\n\n  def quitar(self):\n    return self.cola.pop(0)\n\n  def esta_vacia(self):\n    return len(self.cola) == 0\n\n  def tamano(self):\n    return len(self.cola)\n\n  def imprimir(self):\n    print(self.cola)\n\ncola = Cola()\ncola.agregar(1)\ncola.agregar(2)\ncola.agregar(3)\ncola.imprimir()\nprint(cola.quitar())\nprint(cola.quitar())\nprint(cola.quitar())\n\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/duendeintemporal.py",
    "content": "#8 { Retos para Programadores } CLASES \n\"\"\" \n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n\n\"\"\"\n\n# Bibliography reference\n# Secrets of the JavaScript Ninja (John Resig, Bear Bibeault, Josip Maras)\n# Professional JavaScript for web developers by Matt Frisbie\n# Python para todos (Raúl Gonzáles Duque)\n# GPT\n\n# Classes and Objects\n\n# To understand this paradigm, we first need to comprehend what a class is and what an object is.\n# An object is an entity that groups related state and functionality. The state of the object is defined\n# through variables called attributes, while the functionality is modeled through functions known as the object's methods.\n\n# An example of an object could be a car, which would have attributes such as the brand, the number of doors,\n# or the type of fuel, and methods such as start and stop. Alternatively, it could be any other combination\n# of attributes and methods relevant to our program.\n\n# A class, on the other hand, is a generic template from which to instantiate objects; a template that defines\n# what attributes and methods the objects of that class will have.\n\n# The fundamental part of most classes is its constructor, which sets up each instance's initial state\n# and handles any parameters that were passed when calling the class.\n\n# In Python, we define a class using the 'class' keyword.\n\nlog = print\n\nclass User:\n    def __init__(self, name, nickname, email):\n        self.name = name\n        self.nickname = nickname\n        self.email = email\n\n    def greeting(self):\n        log(f\"Hi {self.nickname}. Welcome to this Roadmap for Developers!\")\n\n    def get_email(self):\n        if self.email is not None:\n            return self.email\n        else:\n            log('No email set yet!')\n            return None\n\n    def get_name(self):\n        if self.name is not None:\n            return self.name\n        else:\n            log('No name set yet!')\n            return None\n\n    def get_nickname(self):\n        if self.nickname is not None:\n            return self.nickname\n        else:\n            log('No nickname set yet!')\n            return None\n\n    def set_name(self, name):\n        if name:\n            self.name = name\n\n    def set_email(self, email):\n        if email:\n            self.email = email\n\n    def set_nickname(self, nickname):\n        if nickname:\n            self.nickname = nickname\n\n    def user_info(self):\n        log(f\"User name: {self.name or 'not set'}, User nickname: {self.nickname or 'not set'}, User email: {self.email or 'not set'}\")\n\n\n# Creating an instance of User\nuser1 = User('Niko Zen', 'duendeintemporal', 'duendeintemporal@hotmail.com')\nuser1.greeting()  # Hi duendeintemporal. Welcome to this Roadmap for Developers!\n\nuser1.user_info()  # User name: Niko Zen, User nickname: duendeintemporal, User email: duendeintemporal@hotmail.com\n\nuser1.set_nickname('psicotrogato')\nlog(user1.get_nickname())  # psicotrogato\n\n# In Python, we can check the type of a class using the type() function.\nlog(type(User))  # <class 'type'>\n\n# We can use isinstance() to check if an instance is of a certain class.\nlog(isinstance(user1, User))  # True\n\n# Class Inheritance\n# Inheritance works just like it does in other object-oriented languages: methods defined on the superclass\n# are accessible in the extending subclass.\n\nclass Log:\n    def __init__(self):\n        self.logger = log\n        self.error_log = log\n\n    def log(self, msg):\n        if msg:\n            self.logger(msg)\n        else:\n            self.error_log('You should provide a message')\n\n\n# When you extend a class in Python, you must call the superclass constructor using super().\nclass Greeting(Log):\n    def __init__(self, msg):\n        super().__init__()\n        self.msg = msg\n\n\nsay_hi_people = Greeting('Hi everybody. Welcome to the most weird and lonely place in cyberspace...')\nsay_hi_people.log(say_hi_people.msg)  # Hi everybody. Welcome to the most weird and lonely place in cyberspace...\n\n# Static Methods\n# Static methods and properties are defined on the class itself, not on instance objects.\n# These are specified in a class definition using the @staticmethod decorator.\n\nclass ElectroCat:\n    @staticmethod\n    def cat_say():\n        return 'Miauu'\n\n    @property\n    def cat_think(self):\n        return \"Let's see if there's some lovely gircat over there\"\n\n\nlog(ElectroCat.cat_say())  # Miauu\nlog(ElectroCat().cat_think)  # Let's see if there's some lovely gircat over there\n\n# We can see that static properties are not defined on object instances:\nmishu = ElectroCat()\n# The following lines would raise an AttributeError if uncommented, as static methods are not available on instances.\n# log(mishu.cat_say())  # Raises AttributeError\n# log(mishu.cat_think)  # Raises AttributeError\n\n# However, they are defined on subclasses:\nclass PoetCat(ElectroCat):\n    pass\n\nlog(PoetCat.cat_say())  # Miauu\nlog(PoetCat().cat_think)  # Let's see if there's some lovely gircat over there\n\n# Getters and setters allow you to define custom behavior for reading and writing a given property on your class.\n# In Python, we can use the @property decorator for getters and the @<property_name>.setter decorator for setters.\n\nclass Cat:\n    def __init__(self, name):\n        self._name = name  # Using a private variable\n\n    @property\n    def name(self):\n        \"\"\"Getter for the name property.\"\"\"\n        return self._name\n\n    @name.setter\n    def name(self, new_name):\n        \"\"\"Setter for the name property.\"\"\"\n        if new_name:\n            self._name = new_name\n        else:\n            log(\"Name cannot be empty!\")\n\n# Example usage of the Cat class with getters and setters\nmy_cat = Cat(\"Whiskers\")\nlog(my_cat.name)  # Whiskers\n\nmy_cat.name = \"Fluffy\"  # Using the setter\nlog(my_cat.name)  # Fluffy\n\nmy_cat.name = \"\"  # Attempting to set an empty name\n# Output: Name cannot be empty!\n\n# Hidden methods can be indicated by prefixing the method name with an underscore.\nclass HiddenMethodExample:\n    def __init__(self):\n        self._hidden_method = \"This is a hidden method\"\n\n    def _hidden_method_function(self):\n        return self._hidden_method\n\nhidden_example = HiddenMethodExample()\nlog(hidden_example._hidden_method_function())  # This is a hidden method\n# Note: The method is not truly private, but it's a convention to indicate that it should not be accessed directly.\n\n# Summary\n# This code demonstrates the use of classes, inheritance, static methods, and property decorators in Python.\n# It also illustrates how to define and use getters and setters, as well as the concept of hidden methods.\n\n# We use private properties in Python classes to avoid infinite recursion in getters and setters\n# by referencing the private property instead of the public property.\n\nclass GopiElectronica:\n    def __init__(self, name):\n        self._name = name  # Using a private variable\n\n    @property\n    def name(self):\n        \"\"\"Getter for the name property.\"\"\"\n        return self._name\n\n    @name.setter\n    def name(self, new_name):\n        \"\"\"Setter for the name property.\"\"\"\n        self._name = new_name\n\n    def hidden_method(self):\n        return 'I will hack you boy'\n\n# Example usage of GopiElectronica\nNicky = GopiElectronica('Nicky')\nlog(Nicky.name)  # Nicky\nNicky.name = 'Samantha'\nlog(Nicky.name)  # Samantha\nlog(f\"{Nicky.name} says: {Nicky.hidden_method()}!\")  # Samantha says: I will hack you boy!\n\n# Note: In Python, we don't have a direct equivalent to JavaScript's Symbol for hiding methods.\n# However, we can use naming conventions (like prefixing with an underscore) to indicate that a method is intended to be private.\n\n# Tips: (relevant info)\n# Classes are first-class citizens in Python, meaning they can be passed around as you would any other object or function reference.\n\n# Classes may be defined anywhere a function would, such as inside a list:\nclass_list = [\n    type('DynamicClass', (object,), {\n        '__init__': lambda self, id_: log(f'instance {id_}')\n    })\n]\n\ndef create_instance(class_definition, id_):\n    return class_definition(id_)\n\nfoo = create_instance(class_list[0], 3141)  # instance 3141\n\n# Similar to an immediately invoked function expression, a class can also be immediately instantiated.\n# Because it is a class expression, the class name is optional.\n# Create a class dynamically and instantiate it immediately\n# Create a class dynamically using type with a different name\nbar = type('Bar', (object,), {\n    '__init__': lambda self, x: log(x)  # This lambda will log the value of x\n})\n\n# Now create an instance of Bar\np = bar('bar')  # This will log 'bar'\n\n# log the instance\nlog(p)  # This will log something like <__main__.Bar object at 0x000002108065EF90>\n\n# Additional Exercises\n\n# QUEUE\nclass Queue:\n    def __init__(self, initial_items=None):\n        self.items = initial_items if isinstance(initial_items, list) else []\n\n    def enqueue(self, element):\n        self.items.append(element)\n\n    def dequeue(self):\n        if self.is_empty():\n            log(\"Queue is empty. Cannot dequeue an element.\")\n            return None\n        return self.items.pop(0)\n\n    def peek(self):\n        if self.is_empty():\n            log(\"Queue is empty. Cannot peek.\")\n            return None\n        return self.items[0]\n\n    def empty(self):\n        self.items = []\n\n    def is_empty(self):\n        return len(self.items) == 0\n\n    def size(self):\n        return len(self.items)\n\n# Example usage of Queue\nqueue2 = Queue([45, 32, 16])\nlog('Initial queue2:', queue2.items)  # [45, 32, 16]\n\nqueue2.enqueue(77)\nlog('After enqueueing 77:', queue2.items)  # [45, 32, 16, 77]\n\nlog('Peek:', queue2.peek())  # 45\n\nlog('Dequeue:', queue2.dequeue())  # 45\nlog('After dequeueing:', queue2.items)  # [32, 16, 77]\n\nlog('Dequeue all elements:')\nwhile not queue2.is_empty():\n    log('Dequeued:', queue2.dequeue())\n# or we can just empty the queue\n# queue2.empty()\n\nlog('Final queue2:', queue2.items)  # []\nlog('Dequeue from empty queue2:', queue2.dequeue())  # Logs error: Queue is empty. Cannot dequeue an element. & Dequeue from empty queue2: None\n\n# STACK\nclass Stack:\n    def __init__(self, initial_items=None):\n        self.items = initial_items if isinstance(initial_items, list) else []\n\n    def push(self, element):\n        self.items.append(element)\n\n    def pop(self):\n        if self.is_empty():\n            log(\"Stack is empty. Cannot pop an element.\")\n            return None\n        return self.items.pop()\n\n    def peek(self):\n        if self.is_empty():\n            log(\"Stack is empty. Cannot peek.\")\n            return None\n        return self.items[-1]\n\n    def empty(self):\n        self.items = []\n\n    def is_empty(self):\n        return len(self.items) == 0\n\n    def size(self):\n        return len(self.items)\n\n# Example usage of Stack\nstack2 = Stack([55, 76, 98, 100])\nlog('Initial stack2:', stack2.items)  # [55, 76, 98, 100]\n\nstack2.push(32)\nlog('After pushing 32:', stack2.items)  # [55, 76, 98, 100, 32]\n\nlog('Peek:', stack2.peek())  # 32\n\nlog('Pop:', stack2.pop())  # 32\nlog('After popping:', stack2.items)  # [55, 76, 98, 100]\n\nlog('Pop all elements:')\nwhile not stack2.is_empty():\n    log('Popped:', stack2.pop())\n# or we can just empty the stack\n# stack2.empty()\n\nlog('Final stack2:', stack2.items)  # []\nlog('Pop from empty stack2:', stack2.pop())  # Logs error: Stack is empty. Cannot pop an element. & Pop from empty stack2: None\n\n\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/elbarbero.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n \"\"\"\n\nfrom collections import deque\n\nclass MiClase:\n    def __init__(self):\n        self.n_reto = 8\n        self.nombre_reto = \"Clases\"\n        self.url_web_retos = \"https://retosdeprogramacion.com/roadmap/\"\n        self.url_github = \"https://github.com/mouredev/roadmap-retos-programacion/tree/main/Roadmap/08%20-%20CLASES\"\n    \n    def print(self):\n        print(f\"\"\"\n              \"-----------------DATOS del RETO-----------------\n              \"Número del reto: {self.n_reto}\n              \"Nombre del reto: {self.nombre_reto}\n              \"Web de los retos: {self.url_web_retos}\n              \"Github del reto: {self.url_github}\n              \"\"\")\n\nclass Pila(list):\n    def __init__(self, *args):\n        self.__count = len(*args)\n        super().__init__(item for item in args)\n    \n    def add(self, element):\n        super().append(element)\n        self.__count += 1\n    \n    def delLIFO(self):\n        super().pop()\n        self.__count -= 1\n    \n    def delete(self, index):\n        try:\n            del self[0][index]\n            self.__count -= 1\n        except IndexError as ex:\n            print(\"No existe ese indice en la colección\")\n       \n    @property        \n    def count(self):\n        return self.__count\n    \n    def print(self):\n        print(f\"Tiene un total de {self.__count} elementos -> {self}\")\n\n\nclass Cola():\n    def __init__(self, *args):\n        self.cola = deque(*args)\n    \n    def add(self, element):\n        self.cola.append(element)\n    \n    def delFIFO(self):\n        print(f\"El elemento borrado es: {self.cola.popleft()}\")\n    \n    def delete(self, index):\n        try:\n            del self.cola[index]\n        except IndexError as ex:\n            print(\"No existe ese indice en la colección\")\n            \n    def count(self):\n        return len(self.cola)\n    \n    def print(self):\n        print(f\"Tiene un total de {self.count()} elementos -> {self.cola}\")\n\nif __name__ == \"__main__\":\n\n    print(\"----------------------CLASE----------------------------\")\n    miclase = MiClase()\n    miclase.print()\n    \n    print(\"----------------------PILAS----------------------------\")\n    webs = Pila([\"https://es.wikipedia.org/wiki/Wikipedia:Portada\", \"https://es.wikipedia.org/wiki/Gran_Premio_de_Abu_Dabi\", \"https://es.wikipedia.org/wiki/Lewis_Hamilton\", \"https://es.wikipedia.org/wiki/Fernando_Alonso\", \"https://es.wikipedia.org/wiki/Asturias\"])\n    print(webs)\n    webs.add(\"www.google.es\")\n    print(webs)\n    webs.delLIFO()\n    print(webs)\n    webs.delete(3)\n    webs.print()\n    \n    print(\"----------------------COLAS----------------------------\")\n    numbers = Cola([1, 2, 3, 4, 5, 6])\n    numbers.print()\n    print(numbers.cola)\n    numbers.delFIFO()\n    numbers.print()\n    numbers.delete(2)\n    numbers.print()\n\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/evilpotato04.py",
    "content": "#/*\n# * EJERCICIO:\n# * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n# * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n# * de tu lenguaje).\n# * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n# * utilizando su función.\n\nfrom collections import deque\n\nclass personaje:\n    def __init__(self, nombre: str, clase: str, genero: str):\n        self.nombre = nombre\n        self.genero = genero\n        self.nivel = 1\n        self.experiencia = 0\n        self.clase = self.obtener_clase(clase.lower())\n    \n    def asignar_atributos(self, ataque: int, destreza: int, salud: int, magia: int):\n                self.puntos_de_ataque = ataque\n                self.puntos_de_destreza = destreza\n                self.puntos_de_salud = salud\n                self.puntos_de_magia = magia\n        \n    def obtener_clase(self, clase: str):\n        match clase:\n            case \"guerrero\":\n                self.arma = \"Espada\"\n                self.asignar_atributos(4, 3, 8, 0)\n                pass\n            case \"arquero\":\n                self.arma = \"Arco y flechas\"\n                self.asignar_atributos(2, 8, 5, 0)\n                pass\n            case \"mago\":\n                self.arma = \"Cetro\"\n                self.asignar_atributos(1, 3, 4, 7)\n                pass\n\n        return clase\n    \n    def presentacion(self):\n        print(\"Nombre: \" + self.nombre)\n        print(\"Genero: \" + self.genero)\n        print(\"Clase: \" + self.clase)\n\n    def atacar(self):\n        print(self.nombre +\" usó \" + self.arma + \" para atacar \\ny causó \" + str(self.puntos_de_ataque) + \" puntos de daño al inimigo!\")\n        return self.puntos_de_ataque\n    \n    def evolucionar(self):\n        if (self.experiencia >= 10):\n            self.nivel += 1\n            self.experiencia = 0\n    \n    def perder_salud(self, dano: int):\n        self.puntos_de_salud -= dano\n        if (self.puntos_de_salud < 0):\n            self.puntos_de_salud = 0\n\ndef batalla(char_01: personaje, char_02: personaje):\n    print(\"\\n===== BATALLA ======\\n  \" + char_01.nombre + \" VS. \" + char_02.nombre + \"\\n\\n\")\n    while (char_01.puntos_de_salud > 0 and char_02.puntos_de_salud > 0):\n        dano = char_01.atacar()\n        char_02.perder_salud(dano)\n        \n        dano = char_02.atacar()\n        char_01.perder_salud(dano)\n\n        if (char_01.puntos_de_salud == 0):\n            print(char_01.nombre + \" murió!\\n\\nVictoria de \" + char_02.nombre + \"!!\")\n        if (char_02.puntos_de_salud == 0):\n            print(char_02.nombre + \" murió!\\n\\nVictoria de \" + char_01.nombre + \"!!\")\n\namber = personaje(\"Amber\", \"arquero\", \"niña\")\ndiluc = personaje(\"Diluc\", \"guerrero\", \"niño\")\n\nbatalla(amber, diluc)\n\n# *\n# * DIFICULTAD EXTRA (opcional):\n# * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n# * en el ejercicio número 7 de la ruta de estudio)\n# * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n# *   retornar el número de elementos e imprimir todo su contenido.\n# * \n# */\n\nclass grupo_pila:\n    grupo = []\n\n    def agregar(self, nuevo_char: personaje):\n        self.grupo.append(nuevo_char)\n    \n    def eliminar(self):\n        print(\"Eliminando personaje...\")\n        self.grupo.pop()\n    \n    def listar_grupo(self):\n        print(\"\\nLista de personajes del grupo:\")\n        for char in self.grupo:\n            print(\" -> \" + char.nombre)\n\nclass grupo_cola:\n    grupo = deque()\n\n    def agregar(self, nuevo_char: personaje):\n        self.grupo.append(nuevo_char)\n    \n    def eliminar(self):\n        print(\"Eliminando personaje...\")\n        self.grupo.popleft()\n    \n    def listar_grupo(self):\n        print(\"\\nLista de personajes del grupo:\")\n        for char in self.grupo:\n            print(\" -> \" + char.nombre)\n\nprint(\"\\n===== GRUPO PILA =====\")\ngp = grupo_pila()\n\ngp.agregar(amber)\ngp.agregar(diluc)\ngp.agregar(personaje(\"Lumine\", \"guerrero\", \"niña\"))\ngp.listar_grupo()\n\ngp.eliminar()\ngp.listar_grupo()\n\nprint(\"\\n===== GRUPO COLA =====\")\ngp2 = grupo_cola()\n\ngp2.agregar(amber)\ngp2.agregar(diluc)\ngp2.agregar(personaje(\"Lumine\", \"guerrero\", \"niña\"))\ngp2.listar_grupo()\n\ngp2.eliminar()\ngp2.listar_grupo()"
  },
  {
    "path": "Roadmap/08 - CLASES/python/fborjalv.py",
    "content": "\nclass Car:\n    \n    def __init__(self, color, marca, modelo): #Constructor / inicializador\n        self.color = color\n        self.marca = marca\n        self.modelo = modelo\n\n    def muestra_datos(self):\n        print(f\"Color del vehículo: {self.color}\")\n        print(f\"Marca del vehículo: {self.marca}\")\n        print(f\"Modelo del vehículo: {self.modelo}\") \n\nmy_car1 = Car(\"Negro Perlado\", \"Toyota\", \"CH-R\")\n\nmy_car1.muestra_datos()\n\nmy_car2 = Car(\"Rojo\", \"Hyunday\", \"Kona\")\n\nmy_car2.muestra_datos()\n\n\n# EJERCICIO EXTRA \n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n\"\"\"\n\nclass Stack: \n\n    def __init__(self, lista) -> None:\n        self.lista = lista\n\n    def add(self, elemento):\n        self.lista.append(elemento)\n\n    def delete(self):\n        self.lista.pop()\n\n    def length(self):\n        print(len(self.lista))\n\n    def print(self):\n        print(self.lista)\n\nmy_stack = Stack([1, 2, 3, 5])\n\nmy_stack.print()\nmy_stack.add(6)\nmy_stack.print()\nmy_stack.delete()\nmy_stack.print()\nmy_stack.length()\n\n\nclass Queue: \n    def __init__(self, lista) -> None:\n        self.lista = lista\n    \n    def add(self, elemento):\n        self.lista.append(elemento)\n\n    def delete(self):\n        self.lista.pop(0)\n\n    def length(self):\n        print(len(self.lista))\n\n    def print(self):\n        print(self.lista)\n\nmy_queue = Queue([1, 2, 3, 5])\n\nmy_queue.add(6)\nmy_queue.print()\nmy_queue.print()\nmy_queue.delete()\nmy_queue.print()\nmy_queue.length()\n\n\n\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/fishellVvv.py",
    "content": "# clases\nclass Programmer:\n\n    nick: str = \"\"\n\n    def __init__(self, name: str, age: int, languages: list):\n        self.name = name\n        self.age = age\n        self.languages = languages\n\n    def print(self):\n        print(f\"Nombre: {self.name} | Edad: {self.age} | Lenguajes: {self.languages} | Nick: {self.nick}\")\n\nmy_programmer = Programmer(\"Victor\", 41, [\"Python\", \"Java\", \"JavaScript\"])\nmy_programmer.print()\nmy_programmer.nick = \"fishellVvv\"\nmy_programmer.print()\nmy_programmer.age += 1\nmy_programmer.print()\n\n# EXTRA\nclass Stack:\n    def __init__(self):\n        self.stack = []\n\n    def push(self, item):\n        self.stack.append(item)\n    \n    def pop(self):\n        if self.count() == 0:\n            return None\n        return self.stack.pop()\n    \n    def count(self):\n        return len(self.stack)\n    \n    def print(self):\n        for item in reversed(self.stack):\n            print(item, end=\" \")\n        print()\n\nprint(\"\\nExtra: class Stack\")\nmy_stack = Stack()\nmy_stack.push(\"A\")\nmy_stack.push(\"B\")\nmy_stack.push(\"C\")\nprint(f\"Recuento: {my_stack.count()}\")\nmy_stack.print()\nprint(f\"Desapilamos: {my_stack.pop()}\")\nprint(f\"Recuento: {my_stack.count()}\")\nmy_stack.print()\n\nclass Queue:\n    def __init__(self):\n        self.queue = []\n\n    def enqueue(self, item):\n        self.queue.append(item)\n\n    def dequeue(self):\n        if self.count() == 0:\n            return None\n        return self.queue.pop(0)\n\n    def count(self):\n        return len(self.queue)\n\n    def print(self):\n        for item in self.queue:\n            print(item, end=\" \")\n        print()\n\nprint(\"\\nExtra: class Queue\")\nmy_queue = Queue()\nmy_queue.enqueue(\"A\")\nmy_queue.enqueue(\"B\")\nmy_queue.enqueue(\"C\")\nprint(f\"Recuento: {my_queue.count()}\")\nmy_queue.print()\nprint(f\"Desencolamos: {my_queue.dequeue()}\")\nprint(f\"Recuento: {my_queue.count()}\")\nmy_queue.print()"
  },
  {
    "path": "Roadmap/08 - CLASES/python/garos01.py",
    "content": "# Clases\n\n\nclass Vehiculo:\n    def __init__(self, marca, modelo, anio, color):\n        self.marca = marca\n        self.modelo = modelo\n        self.anio = anio\n        self.color = color\n\n    def imprimir_informacion(self):\n        print(f\"Marca: {self.marca}\")\n        print(f\"Modelo: {self.modelo}\")\n        print(f\"Año: {self.anio}\")\n        print(f\"Color: {self.color}\")\n\n\n# Crear una instancia de la clase Vehiculo\nvehiculo1 = Vehiculo(marca=\"Toyota\", modelo=\"Camry\", anio=2022, color=\"Azul\")\n\n# Imprimir la información inicial\nprint(\"Información inicial del vehículo:\")\nvehiculo1.imprimir_informacion()\n\n# Modificar algunos atributos\nvehiculo1.anio = 2023\nvehiculo1.color = \"Rojo\"\n\n# Imprimir la información después de la modificación\nprint(\"\\nInformación después de la modificación:\")\nvehiculo1.imprimir_informacion()\n\n# Ejercicio extra\n\n\nclass Impresora:\n    def __init__(self):\n        self.cola_impresion = []\n\n    def recibir_documento(self, documento):\n        self.cola_impresion.append(documento)\n        print(\"Documento recibido:\", documento)\n\n    def imprimir(self):\n        if self.cola_impresion:\n            documento_a_imprimir = self.cola_impresion.pop(0)\n            print(\"Imprimiendo documento:\", documento_a_imprimir)\n        else:\n            print(\"No hay documentos en la cola de impresión\")\n\n\nimpresora = Impresora()\n\nimpresora.recibir_documento(\"Documento1.txt\")\nimpresora.recibir_documento(\"Documento2.pdf\")\nimpresora.recibir_documento(\"Documento3.doc\")\n\nimpresora.imprimir()\nimpresora.imprimir()\nimpresora.imprimir()\nimpresora.imprimir()\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/ggilperez.py",
    "content": "# Problem 08 Classes\n\nclass Cat:\n\n    def __init__(self, name, age, color):\n        self.name = name\n        self.age = age\n        self.color = color\n\n    def meow(self):\n        print(\"Meow!\")\n\n    def describe(self):\n        print(f\"My name is {self.name}\")\n        print(f\"I'm {self.color}\")\n        print(f\"And I'm {self.age}yo\")\n\n\norange_cat = Cat(\"Mordisquitos\", 1, \"orange\")\norange_cat.describe()\n\n\n# Stack - LIFO\nclass Stack:\n    def __init__(self):\n        self.items = []\n\n    def insert(self, item):\n        self.items.append(item)\n\n    def delete(self):\n        try:\n            item = self.items.pop()\n        except IndexError:\n            item = None\n        finally:\n            return item\n\n    def length(self):\n        return len(self.items)\n\n    def show(self):\n        for item in reversed(self.items):\n            print(item)\n\n\nmy_stack = Stack()\nmy_stack.insert(1)\nmy_stack.insert(2)\nmy_stack.insert(3)\nmy_stack.insert(4)\nprint(f\"{my_stack.length() = }\")\nprint(f\"my_stack.show()\")\nmy_stack.show()\n\n\n# Queue - FIFO\nclass Queue:\n    def __init__(self):\n        self.items = []\n\n    def insert(self, item):\n        self.items.append(item)\n\n    def delete(self):\n        try:\n            item = self.items.pop(0)\n        except IndexError:\n            item = None\n        finally:\n            return item\n\n    def length(self):\n        return len(self.items)\n\n    def show(self):\n        for item in self.items:\n            print(item)\n\n\nmy_queue = Queue()\nmy_queue.insert(1)\nmy_queue.insert(2)\nmy_queue.insert(3)\nmy_queue.insert(4)\nprint(f\"{my_queue.length() = }\")\nprint(f\"my_queue.show()\")\nmy_queue.show()\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/gjbecerrae.py",
    "content": "class helloPython:\n   \n    def __init__(self, name, lastName): \n        self.name = name #instance variable unique to each instance\n        self.lastname = lastName\n\n    def modParam(self, nameMod, lastNameMod):\n        self.name = nameMod\n        self.lastname = lastNameMod\n\n    def printAtt(self): # class method\n        print(f'{self.name} {self.lastname}')\n\nhola = helloPython('Gabriel', 'Becerra')\n#hola.printAtt()\n#hola.modParam('Jaime', 'Eslava')\n#hola.printAtt()\n\n#### Dificultad Extra ######\nclass Pilas:\n\n    def __init__(self, elementos:list) -> None:\n        self.elementos = elementos\n\n    def adicionarElemento(self, elementoExtra):\n        self.elementos.append(elementoExtra)\n\n    def eliminarElemento(self):\n        self.elementos.pop()\n\n    def numeroElementos(self):\n        return len(self.elementos)\n\n    def imprimirElementos(self):\n        for i in self.elementos: print(i)\n\nclass Colas:\n\n    def __init__(self, elementos) -> None:\n        self.elementos = elementos\n\n    def adicionarElemento(self, elementoExtra):\n        self.elementos.append(elementoExtra)\n\n    def eliminarElemento(self):\n        self.elementos.pop(0)\n\n    def numeroElementos(self):\n        return len(self.elementos)\n\n    def imprimirElementos(self):\n        for i in self.elementos: print(i)\n\nprint('Pilas-------------------------\\n')\nmiPila = Pilas(['goku'])\nmiPila.imprimirElementos()\nmiPila.adicionarElemento('Gohan')\nmiPila.adicionarElemento('Picoro')\nnumero = miPila.numeroElementos()\nprint(numero)\nmiPila.imprimirElementos()\nmiPila.eliminarElemento()\nmiPila.imprimirElementos()\n\nprint('\\n\\Colas-------------------------\\n')\nmiCola = Colas(['goku'])\nmiCola.imprimirElementos()\nmiCola.adicionarElemento('Gohan')\nmiCola.adicionarElemento('Picoro')\nnumero = miCola.numeroElementos()\nprint(numero)\nmiCola.imprimirElementos()\nmiCola.eliminarElemento()\nmiCola.imprimirElementos()"
  },
  {
    "path": "Roadmap/08 - CLASES/python/gringoam.py",
    "content": "\"\"\"\nEjercicio\n\"\"\"\n\n\nclass Programmer:\n\n    surname: str = None\n\n    def __init__(self, name: str, age: int, languages: list):\n        self.name = name\n        self.age = age\n        self.languages = languages\n\n    def print(self):\n        print(\n            f\"Nombre: {self.name} | Apellidos: {self.surname} | Edad: {self.age} | Lenguajes: {self.languages}\")\n\n\nmy_programmer = Programmer(\"Brais\", 36, [\"Python\", \"Kotlin\", \"Swift\"])\nmy_programmer.print()\nmy_programmer.surname = \"Moure\"\nmy_programmer.print()\nmy_programmer.age = 37\nmy_programmer.print()\n\n\"\"\"\nExtra\n\"\"\"\n\n#Stack(pila)\n\nclass Stack:\n    \n\n    def __init__(self) -> None:\n        self.stack=[]\n\n    def push(self, item):\n        self.stack.append(item)\n    \n    def pop(self):\n\n        if len(self.stack) == 0:\n            return None\n        return self.stack.pop()\n    \n    def print(self):\n        for item in reversed(self.stack):\n            print(item)\n\n    def count(self):\n        return len(self.stack)\n\nmy_stack= Stack()\nmy_stack.push(\"A\")\nmy_stack.push(\"B\")\nmy_stack.push(\"C\")\nmy_stack.print()\nprint(f\"Cantidad: {my_stack.count()}\")\nprint(f\"Se elimino {my_stack.pop()}\")\nmy_stack.print()\nprint(f\"Cantidad: {my_stack.count()}\")\nprint(f\"Se elimino {my_stack.pop()}\")\nprint(f\"Se elimino {my_stack.pop()}\")\nprint(f\"Se elimino {my_stack.pop()}\")\nmy_stack.print()\nmy_stack.count()\n    \n#Queue (Cola)\n\nclass Queue:\n    \n\n    def __init__(self) -> None:\n        self.queue=[]\n\n    def push(self, item):\n        self.queue.append(item)\n    \n    def pop(self):\n\n        if len(self.queue) == 0:\n            return None\n        return self.queue.pop(0)\n    \n    def print(self):\n        for item in self.queue:\n            print(item)\n\n    def count(self):\n        return len(self.queue)\n\nmy_queue= Queue()\nmy_queue.push(1)\nmy_queue.push(2)\nmy_queue.push(3)\nmy_queue.print()\nprint(f\"Cantidad: {my_queue.count()}\")\nprint(f\"elimi {my_queue.pop()}\")\nmy_queue.print()\nprint(f\"Cantidad: {my_queue.count()}\")\nprint(f\"elimi {my_queue.pop()}\")\nmy_queue.print()\nprint(f\"Cantidad: {my_queue.count()}\")\n    \n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/haroldAlb.py",
    "content": "### EJERCICIO ###\n # Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n # atributos y una función que los imprima (teniendo en cuenta las posibilidades\n # de tu lenguaje). Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n # utilizando su función.\n\nclass Coche():\n    def __init__(self, marca: str, cilindrada: int, color: str):\n        self.marca = marca\n        self.cilindrada = cilindrada\n        self.color = color\n        self.motor_encendido: bool = False\n\n    def estado(self):\n        print(f\"Marca: {self.marca}\", f\"Cilindrada: {self.cilindrada}\", f\"Color: {self.color}\", f\"Estado del motor: {self.motor_encendido}\", sep= \" | \")\n\n    def arrancar(self):\n        self.motor_encendido = True\n\nmercedes = Coche(\"Mercedes\", 2500, \"Negro\")\nmercedes.estado()\nmercedes.color = \"Rosa\"\nmercedes.cilindrada = 3000\nmercedes.estado()\n\n### EXTRA ###\n # Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n # en el ejercicio número 7 de la ruta de estudio).\n # Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n # retornar el número de elementos e imprimir todo su contenido.\n\n# PILAS - LIFO #\nprint(\"#\" * 10,\"PILAS - LIFO\",\"#\" * 10, sep=\" \")\n\n\nclass Pila():\n    def __init__(self):\n        self.pila = []\n        self.elemento_borrado = None\n       \n    def añadir(self, elemento):\n        self.pila.append(elemento)\n\n    def eliminar(self):\n        self.elemento_borrado = self.pila.pop()\n\n    def num_elementos(self):\n        return len(self.pila)\n\n    def mostrar(self):\n        print(\"Elementos de la Pila:\")\n        for i, e in enumerate(self.pila):\n            print(f\"    Index_{i}: {e}\")\n\nmi_pila = Pila()\n\nmi_pila.añadir(00)\nmi_pila.añadir(10)\nmi_pila.añadir(20)\n\nprint(f\"El número de elementos en la pila es de {mi_pila.num_elementos()}\")\n\nmi_pila.eliminar()\nprint(f\"El elemento borrado fue {mi_pila.elemento_borrado}\")\n\nprint(f\"El número de elementos en la pila es de {mi_pila.num_elementos()}\")\n\nmi_pila.mostrar()\n\n# COLAS - FIFO #\nprint(\"#\" * 10,\"COLAS - FIFO\",\"#\" * 10, sep=\" \")\n\nclass Cola():\n    def __init__(self):\n        self.cola = []\n        self.elemento_borrado = None\n    \n    def añadir(self, elemento):\n        self.cola.append(elemento)\n\n    def eliminar(self):\n        self.elemento_borrado = self.cola.pop(0)\n\n    def num_elementos(self):\n        return len(self.cola)\n\n    def mostrar(self):\n        print(\"Elementos de la Cola:\")\n        for i, e in enumerate(self.cola):\n            print(f\"    Index_{i}: {e}\")\n    \nmi_cola = Cola()\n\nmi_cola.añadir(0)\nmi_cola.añadir(10)\nmi_cola.añadir(20)\n\nprint(f\"El número de elementos de la cola es de {mi_cola.num_elementos()}\")\n\nmi_cola.eliminar()\nprint(f\"El elemento borrado fue {mi_cola.elemento_borrado}\")\n\nprint(f\"El número de elementos de la cola es de {mi_cola.num_elementos()}\")\n\nmi_cola.mostrar()"
  },
  {
    "path": "Roadmap/08 - CLASES/python/hectordbh.py",
    "content": "\"\"\" ---------------------- EJERCICIO -------------------- \"\"\"\nclass Triangle():\n    \"\"\"Clase de ejemplo\n    \"\"\"\n    def __init__(self, base, altura):\n        \"\"\"Método que inicia las propiedades\n\n        Args:\n            base (float): base del triángulo\n            altura (float): altura del triángulo\n        \"\"\"\n        self.base = base\n        self.altura = altura\n\n    @property\n    def area(self):\n        \"\"\"Método para calcular su área\n        \"\"\"\n        area = (self.base*self.altura)/2\n        return area\n\n    def __str__(self):\n        \"\"\"Método que imprime el objeto creado\n        \"\"\"\n        return f\"El área del triángulo es {self.area}\"\n\n# ----------------- PRUEBAS CLASE TRIANGLE() -------------- #\ntriangulo = Triangle(5, 3)\nprint(triangulo)\n\ntriangulo2 = Triangle(2.5, 4)\nprint(triangulo2)\n\n# ---------------------- DIFICULTAD EXTRA ----------------- #\n# Pila\nclass Stack():\n    \"\"\"Clase pila para el embarco y desembarco de\n    pasajeros en un avión - LIFO\n    \"\"\"\n    def __init__(self):\n        self.stack = []\n\n    def add(self, passenger):\n        \"\"\"Embarcar pasajeros\n\n        Args:\n            passenger (str): pasajeroXX\n\n        Returns:\n            str: pasajeroXX a bordo\n            Acción de añadir a la lista\n        \"\"\"\n        print(f\"\\nPasajero: {passenger} a bordo\")\n        return self.stack.append(passenger)\n\n    def out(self):\n        \"\"\"Desembarcar pasajero\n\n        Returns:\n            str: pasajeroXX ha desembarcado\n            Acción de eliminar de la lista el último elemento\n        \"\"\"\n        while len(self.stack) > 0:\n            print(f\"Parajero: {self.stack[-1]} ha desembarcado\")\n            return self.stack.pop()\n        print(\"Ya no hay pasajeros a bordo\")\n\n    def quantity(self):\n        \"\"\"Cantidad de pasajeros a bordo\n        \"\"\"\n        passengers = len(self.stack)\n        print(f\"El número de pasajeros a bordo es: {passengers}\")\n\n    def listview(self):\n        \"\"\"Ver la lista de pasajeros\n\n        Returns:\n            list: lista de pasajeros\n        \"\"\"\n        print(\"\\nLISTA DE PASAJEROS\")\n        print(self.stack)\n\n# -------------------- PRUEBAS CLASE STACK() -------------- #\ndef pruebas_stack():\n    \"\"\"Función para probar la clase Stack()\n    \"\"\"\n    embarco = Stack()\n    embarco.add(\"pasajero01\")\n    embarco.quantity()\n    embarco.add(\"pasajero02\")\n    embarco.quantity()\n    embarco.listview()\n    embarco.out()\n    embarco.quantity()\n    embarco.listview()\n    embarco.out()\n    embarco.quantity()\n    embarco.listview()\n    embarco.out()\n    embarco.add(\"pasajero03\")\n    embarco.listview()\n\npruebas_stack()\n\n# Cola\nclass Queue():\n    \"\"\"Clase cola para atención presencial en oficina\n    \"\"\"\n    def __init__(self):\n        self.queue = []\n\n    def arrived(self, name):\n        \"\"\"Llegar a la cola\n\n        Args:\n            name (str): nombre de la persona\n        \n        Returns:\n            str: (nombre), su turno es: (número)\n            Acción de incluir en la cola a una persona\n        \"\"\"\n        self.queue.append(name)\n        print(f\"{name}, su turno es: {len(self.queue)}\")\n\n    def gone(self):\n        \"\"\"Atención al ciudadano y eliminación de la cola\n\n        Returns:\n            str: (nombre) ha sido atendido\n            Acción de quitar de la cola el primer registro\n        \"\"\"\n        while len(self.queue) > 0:\n            print(f\"{self.queue[0]} ha sido atendido\")\n            return self.queue.pop(0)\n        print(\"La cola está vacía\")\n\n    def size(self):\n        \"\"\"Conocer la cantidad de personas que están esperando\n        \n        Returns:\n            str: El tamaño de la cola actual es de (número) personas\n        \"\"\"\n        if len(self.queue) == 0:\n            print(\"La cola está vacía\")\n        else:\n            print(f\"El tamaño de la cola actual es de {len(self.queue)} personas\")\n\n    def names(self):\n        \"\"\"Obtener los integrantes de la lista\n\n        Returns:\n            str: integrantes de la lista\n        \"\"\"\n        print(\"\\nINTEGRANTES DE LA LISTA\")\n        if len(self.queue) == 0:\n            print(\"No hay integrantes\")\n        else:\n            for item in self.queue:\n                print(item)\n\n# -------------------- PRUEBAS CLASE QUEUE() -------------- #\n\ndef pruebas_queue():\n    \"\"\"Función para probar la clase Queue()\n    \"\"\"\n    cola = Queue()\n    cola.size()\n    cola.arrived(\"Héctor\")\n    cola.size()\n    cola.names()\n    cola.arrived(\"Juan\")\n    cola.size()\n    cola.names()\n    cola.gone()\n    cola.size()\n    cola.names()\n    cola.gone()\n    cola.size()\n    cola.names()\n\npruebas_queue()\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/hectorio23.py",
    "content": "# Autor: Héctor Adán\n# GitHub: https://github.com/hectorio23\n\nfrom typing import Optional\n\n###########################################\n# CLASE WebPage\n###########################################\n\nclass WebPage:\n    def __init__(self, title: str, index: int):\n        self.title = title\n        self.index = index\n\n    def get_info(self):\n        print(f\"<Object WebPage - {self.title} at {hex(id(self))}>\")\n\n    def __str__(self):\n        return f\"<Object WebPage - {self.title} at {hex(id(self))}>\"\n\n###########################################\n# CLASE Queue\n###########################################\n\nclass Queue:\n    def __init__(self):\n        self.next: Optional[Queue] = None\n        self.last: Optional[Queue] = None\n        self.size = 0\n        self.page: Optional[WebPage] = None\n\n    def push(self, web_page: WebPage):\n        tmp = Queue()\n        tmp.page = web_page\n        if self.size == 0:\n            self.next = tmp\n            self.last = tmp\n        else:\n            self.last.next = tmp\n            self.last = tmp\n        self.size += 1\n\n    def pop(self) -> Optional[WebPage]:\n        if self.size == 0:\n            return None\n        aux = self.next\n        self.next = aux.next\n        self.size -= 1\n        if self.size == 0:\n            self.last = None\n        return aux.page\n\n###########################################\n# CLASE Stack\n###########################################\n\nclass Stack:\n    def __init__(self):\n        self.next: Optional[Stack] = None\n        self.garbage: Optional[Stack] = None  # experimental\n        self.size = 0\n        self.page: Optional[WebPage] = None\n\n    def push(self, web_page: WebPage):\n        tmp = Stack()\n        tmp.page = web_page\n        tmp.next = self.next\n        self.next = tmp\n        self.size += 1\n\n    def pop(self) -> Optional[WebPage]:\n        if self.size == 0:\n            return None\n        aux = self.next\n        self.next = aux.next\n        self.size -= 1\n        return aux.page\n\n###########################################\n# CLASE Persona\n###########################################\n\nclass Persona:\n    def __init__(self, nombre: str, edad: int):\n        self.nombre = nombre\n        self.edad = edad\n\n    def info(self):\n        print(f\"Nombre: {self.nombre}\")\n        print(f\"Edad: {self.edad}\")\n\n    def set_nombre(self, nuevo_nombre: str):\n        self.nombre = nuevo_nombre\n\n    def set_edad(self, nueva_edad: int):\n        self.edad = nueva_edad\n\n###########################################\n# PROGRAMA PRINCIPAL\n###########################################\n\nif __name__ == \"__main__\":\n    # Crear una instancia de Persona\n    persona = Persona(\"Juan\", 30)\n\n    # Imprimir los atributos\n    print(\"Datos de la persona:\")\n    persona.info()\n\n    # Modificar los atributos\n    persona.set_nombre(\"María\")\n    persona.set_edad(25)\n\n    # Imprimir los atributos actualizados\n    print(\"\\nDatos de la persona actualizados:\")\n    persona.info()\n\n    # Creando los objetos WebPage para utilizar en Stack y Queue\n    p1 = WebPage(\"index\", 1)\n    p2 = WebPage(\"index\", 2)\n    p3 = WebPage(\"index\", 3)\n\n    # Crear una instancia de Queue\n    queue = Queue()\n\n    # Agregar elementos a Queue\n    queue.push(p1)\n    queue.push(p2)\n    queue.push(p3)\n\n    print(f\"\\nNúmero de elementos en Queue: {queue.size}\")\n    queue.pop()\n    queue.pop()\n    queue.pop()\n    print(f\"Número de elementos en Queue después de eliminar: {queue.size}\")\n\n    # Crear una instancia de Stack\n    stack = Stack()\n\n    # Agregar elementos a Stack\n    stack.push(p1)\n    stack.push(p2)\n    stack.push(p3)\n\n    print(f\"\\nNúmero de elementos en Stack: {stack.size}\")\n    stack.pop()\n    stack.pop()\n    stack.pop()\n    print(f\"Número de elementos en Stack después de eliminar: {stack.size}\")\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/hozlucas28.py",
    "content": "\"\"\"\n    Classes...\n\"\"\"\n\nfrom dataclasses import dataclass\nfrom typing import Any\n\n\n@dataclass\nclass Employee:\n    \"\"\"Employee class\"\"\"\n\n    _first_name: str\n    _last_name: str\n    _salary: int\n\n    def set_first_name(self, first_name: str):\n        \"\"\"Set a new first name\"\"\"\n        self._first_name = first_name\n        return self\n\n    def set_last_name(self, last_name: str):\n        \"\"\"Set a new last name\"\"\"\n        self._last_name = last_name\n        return self\n\n    def set_salary(self, salary: str):\n        \"\"\"Set a new salary\"\"\"\n        self._salary = salary\n        return self\n\n    def get_first_name(self) -> str:\n        \"\"\"Return first name\"\"\"\n        return self._first_name\n\n    def get_last_name(self) -> str:\n        \"\"\"Return last name\"\"\"\n        return self._last_name\n\n    def get_salary(self) -> str:\n        \"\"\"Return salary\"\"\"\n        return self._salary\n\n    def print_attributes(self):\n        \"\"\"Print attributes values\"\"\"\n        print(f'\\nFirst name --> \"{self._first_name}\"')\n        print(f'Last name --> \"{self._last_name}\"')\n        print(f\"Salary --> {self._salary}\")\n        return self\n\n\nprint(\"Classes in Python...\\n\")\n\nprint(\n    '''from dataclasses import dataclass\nfrom typing import Any\n\n\n@dataclass\nclass Employee:\n    \"\"\"Employee class\"\"\"\n\n    _first_name: str\n    _last_name: str\n    _salary: int\n\n    def set_first_name(self, first_name: str):\n        \"\"\"Set a new first name\"\"\"\n        self._first_name = first_name\n        return self\n\n    def set_last_name(self, last_name: str):\n        \"\"\"Set a new last name\"\"\"\n        self._last_name = last_name\n        return self\n\n    def set_salary(self, salary: str):\n        \"\"\"Set a new salary\"\"\"\n        self._salary = salary\n        return self\n\n    def get_first_name(self) -> str:\n        \"\"\"Return first name\"\"\"\n        return self._first_name\n\n    def get_last_name(self) -> str:\n        \"\"\"Return last name\"\"\"\n        return self._last_name\n\n    def get_salary(self) -> str:\n        \"\"\"Return salary\"\"\"\n        return self._salary\n\n    def print_attributes(self):\n        \"\"\"Print attributes values\"\"\"\n        print(f'\\\\nFirst name --> \\\\\"{self._first_name}\\\\\"')\n        print(f'Last name --> \\\\\"{self._last_name}\\\\\"')\n        print(f\"Salary --> {self._salary}\")\n        return self'''\n)\n\nprint('\\nemployee = Employee(\"Lucas\", \"Hoz\", 2300)')\n\nmy_employee = Employee(\"Lucas\", \"Hoz\", 2300)\n\nprint(\"\\nEmployee attributes...\")\nmy_employee.print_attributes()\n\nmy_employee.set_first_name(\"Nahuel\")\nprint('\\nemployee.set_first_name(\"Nahuel\")')\n\nprint(\"\\nEmployee attributes...\")\nmy_employee.print_attributes()\n\nprint(\n    \"\\n# ---------------------------------------------------------------------------------- #\\n\"\n)\n\n\"\"\"\n    Additional challenge...\n\"\"\"\n\nprint(\"Additional challenge...\")\n\n\n# Stack exercise...\nclass Stack:\n    \"\"\"Stack class\"\"\"\n\n    def __init__(self, stack: list[Any]) -> None:\n        if stack is None:\n            stack = []\n        stack_length: int = len(stack)\n\n        self._last_element: Any | None = stack[-1] if (stack_length > 0) else None\n        self._length: int = stack_length\n        self._stack: list[Any] = stack\n\n    def get_stack(self) -> list[Any]:\n        \"\"\"Return stack\"\"\"\n        return self._stack\n\n    def get_length(self) -> int:\n        \"\"\"Return length\"\"\"\n        return self._length\n\n    def get_last_element(self) -> Any | None:\n        \"\"\"Return last element\"\"\"\n        return self._last_element\n\n    def append_element(self, element: any):\n        \"\"\"Append element at the end\"\"\"\n        self._stack.append(element)\n        self._last_element = element\n        self._length = len(self._stack)\n        return self\n\n    def delete_last_element(self):\n        \"\"\"Delete last element\"\"\"\n        self._stack.pop()\n        self._length = len(self._stack)\n        self._last_element = self._stack[-1] if (self._length > 0) else None\n        return self\n\n    def print_attributes(self):\n        \"\"\"Print attributes values\"\"\"\n        print(f\"\\nLast element --> {self._last_element}\")\n        print(f\"Length --> {self._length}\")\n        print(f\"Stack --> {self._stack}\")\n        return self\n\n\nmy_stack = Stack([\"Lucas\", \"Nahuel\"])\nmy_stack.append_element(\"Buenos Aires\")\n\nprint(\"\\nStack attributes...\")\nmy_stack.print_attributes()\n\nmy_stack.delete_last_element().delete_last_element()\n\nprint(\"\\nStack attributes...\")\nmy_stack.print_attributes()\n\nmy_stack.delete_last_element()\n\nprint(\"\\nStack attributes...\")\nmy_stack.print_attributes()\n\n\n# Queue exercise...\nclass Queue:\n    \"\"\"Queue class\"\"\"\n\n    def __init__(self, queue: list[Any]) -> None:\n        if queue is None:\n            queue = []\n        queue_length: int = len(queue)\n\n        self._length: int = queue_length\n        self._queue: list[Any] = queue\n        self._first_element: Any | None = queue[0] if queue_length > 0 else None\n\n    def get_length(self) -> int:\n        \"\"\"Return length\"\"\"\n        return self._length\n\n    def get_queue(self) -> list[Any]:\n        \"\"\"Return queue\"\"\"\n        return self._queue\n\n    def get_first_element(self) -> Any:\n        \"\"\"Return first element\"\"\"\n        return self._first_element\n\n    def append_element(self, element: Any):\n        \"\"\"Append element at the end\"\"\"\n        self._queue.append(element)\n        self._length = len(self._queue)\n        return self\n\n    def delete_first_element(self):\n        \"\"\"Delete first element\"\"\"\n        self._queue = self._queue[1:]\n        self._length = len(self._queue)\n        self._first_element = self._queue[0] if (self._length > 0) else None\n        return self\n\n    def print_attributes(self):\n        \"\"\"Print attributes values\"\"\"\n        print(f\"\\nLength --> {self._length}\")\n        print(f\"Queue --> {self._queue}\")\n        print(f\"First element --> {self._first_element}\")\n        return self\n\n\nmy_queue = Queue([\"Estados Unidos\", \"Miami\"])\n\nmy_queue.append_element(\"Beach\")\n\nprint(\"\\nQueue attributes...\")\nmy_queue.print_attributes()\n\nmy_queue.delete_first_element().delete_first_element()\n\nprint(\"\\nQueue attributes...\")\nmy_queue.print_attributes()\n\nmy_queue.delete_first_element()\n\nprint(\"\\nQueue attributes...\")\nmy_queue.print_attributes()\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/idiegorojas.py",
    "content": "class Perro:\n\n    def __init__(self, nombre, edad):\n        self.nombre = nombre\n        self.edad = edad\n\n    def ladar(self):\n        print(f'{self.nombre} dice: ¡Guau!')\n\n    def mostrar_info(self):\n        print(f'Nombre: {self.nombre}, Edad: {self.edad} años.')\n\n\nclass PerroGuardian(Perro):\n    def vigilar(self):\n        print(f'{self.nombre} esta vigilando la casa.')\n\n\nperro1 = Perro('Rex', 3)\nperro2 = Perro('Luna', 7)\nguardian = PerroGuardian('Thor', 10)\n\nperro1.ladar()\nperro2.mostrar_info()\nguardian.vigilar()\n\n# Extra\n\nclass Pila:\n    def __init__(self):\n        self.elementos = []\n\n    def esta_vacia(self):\n        return len(self.elementos) == 0\n    \n    def anadir(self, elemento):\n        self.elementos.append(elemento)\n\n    def eliminar(self):\n        if self.esta_vacia():\n            raise IndexError('Esta vacio')\n        return self.elementos.pop()\n    \n    def tamano(self):\n        return len(self.elementos)\n    \n    def imprimir(self):\n        print('Contenido:', self.elementos)\n\npila = Pila()\npila.anadir(1)\npila.anadir(2)\npila.anadir(3)\npila.imprimir()\npila.eliminar()\npila.imprimir()\nprint('Tamaño: ', pila.tamano())\n\nclass Cola:\n    def __init__(self):\n        self.elementos = []\n\n    def esta_vacia(self):\n        return len(self.elementos) == 0\n    \n    def anadir(self, elemento):\n        self.elementos.append(elemento)\n\n    def eliminar(self):\n        if self.esta_vacia():\n            raise IndexError('Esta vacio')\n        return self.elementos.pop(0)\n    \n    def tamano(self):\n        return len(self.elementos)\n    \n    def imprimir(self):\n        print('Contenido:', self.elementos)\n\ncola = Cola()\ncola.anadir(1)\ncola.anadir(2)\ncola.anadir(3)\ncola.imprimir()\ncola.eliminar()\ncola.imprimir()\nprint('Tamaño: ', cola.tamano())"
  },
  {
    "path": "Roadmap/08 - CLASES/python/ignaciovihe.py",
    "content": "\"\"\"\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n\"\"\"\n\nclass Npc:\n\n    total_npc = 0 # Atributo de clase compartido por todas las instancias. (para probar)\n\n    def __init__(self, first_name = \"unknown\", last_name = \"unknown\", age = \"unknown\", location = \"unknown\"):\n        self.fisrt_name = first_name\n        self.last_name = last_name\n        self.age = age\n        self.location = location\n        Npc.increment_count()\n\n    @classmethod    # Decorador que indica que el siguiente metodo es de clase\n    def increment_count(cls): # cls es igual que self pero para metodos de clase\n        cls.total_npc += 1\n\n    @classmethod\n    def decrement_count(cls):\n        if cls.total_npc > 0:\n            cls.total_npc -= 1\n\n    def delete(self)-> None:\n        Npc.decrement_count()\n        del self\n\n    def set_first_name(self,f_n):\n        self.fisrt_name = f_n\n\n    def set_last_name(self,l_n):\n        self.last_name = l_n\n\n    def set_age(self,a):\n        self.age = a\n\n    def set_location(self,lct):\n        self.location = lct\n\n    def print(self):\n        print(f\"Fisrt name: {self.fisrt_name}\\nLast name: {self.last_name}\\nAge: {self.age}\\nLocation:{self.location}\")\n\n\n\nperson = Npc(\"Pedro\", \"Rodriguez\", 45)\nperson.print()\nperson.set_location((4,7))\nperson.print()\n\nperson2 = Npc(\"Mike\", \"Jones\", 29,)\nperson2.set_location((3,0))\nperson2.print()\n\nprint(f\"Total Npc : {Npc.total_npc}\")\nperson.delete()\nprint(f\"Total Npc : {Npc.total_npc}\")\n\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n\"\"\"\nfrom typing import Any, Optional\n\nclass Stack:\n\n\n    def __init__(self):\n        self.stack = []\n\n    def push(self,element: Any) -> None:\n        self.stack.append(element)\n\n    def pull(self)->Optional[Any]:\n        if self.stack:\n            return self.stack.pop()\n        print(\"La pila esta vacía\")\n        return None\n\n    def get_len(self)-> int:\n        return len(self.stack)\n    \n    def print(self)-> None:\n        for item in reversed(self.stack):\n            print(item)\n\n\nsaludos = Stack()\nsaludos.push(\"Hola\")\nsaludos.push(\"Buenos días\")\nsaludos.print()\nprint(saludos.get_len())\nsaludos.pull()\nsaludos.print()\nsaludos.pull()\nsaludos.print()\nsaludos.pull()\nsaludos.print()\n\n\n\n\nclass Queue:\n\n    def __init__(self):\n        self.queue = []\n\n    def push(self,element: Any) -> None:\n        self.queue.append(element)\n\n    def pull(self)->Optional[Any]:\n        if self.queue:\n            return self.queue.pop(0)\n        print(\"La cola esta vacía\")\n        return None\n\n    def get_len(self)-> int:\n        return len(self.queue)\n    \n    def print(self)-> None:\n        print(self.queue)\n\n\npersons = Queue()\npersons.push(\"Antonio\")\npersons.push(\"Marcos\")\npersons.push(\"Roberto\")\npersons.print()\npersons.pull()\npersons.print()\npersons.pull()\npersons.print()\npersons.push(\"Javier\")\npersons.print()\npersons.pull()\npersons.print()\npersons.pull()\npersons.print()\npersons.pull()\npersons.print()"
  },
  {
    "path": "Roadmap/08 - CLASES/python/ipfabio.py",
    "content": "\"\"\"\nEjercicios\n\"\"\"\n\nclass Programmer:\n\n    surname: str = \"\"\n\n    def __init__(self, name: str, age: int, lenguage: list) -> None:\n        self.name = name\n        self.age = age\n        self.lenguage = lenguage\n\n    \n    def print(self):\n        print(f\"Nombre: {self.name} | Apellidos: {self.surname} | Edad: {self.age} | Lenguajes: {self.lenguage}\")\n\nmy_progammer = Programmer(\"Marco\", 39, [\"Python\", \"Java\", \"C\"])\nmy_progammer.print()\nmy_progammer.surname = \"Polo\"\nmy_progammer.print()\nmy_progammer.age = 35\nmy_progammer.print()\n\n\"\"\"\nExtra\n\"\"\"\n\n# LIFO\n\nclass Stack:\n\n    def __init__(self):\n        self.stack = []\n    \n    def push(self, item):\n        self.stack.append(item)\n        # Agregamos {item} al stack\"\n    \n    def pop(self):\n        if self.count() == 0:\n            return None\n        return self.stack.pop()\n        # Eliminamos el último {item} del stack\"\n \n    def count(self):\n        return len(self.stack)\n    \n    def print(self):\n        for item in reversed(self.stack):\n            print(item)\n        # Estado del stack: {self.stack}\"\n\nmy_stack = Stack()\nmy_stack.push(\"A\")\nmy_stack.push(\"B\")\nmy_stack.push(\"C\")\nprint(my_stack.count())\nmy_stack.print()\nmy_stack.pop()\nprint(my_stack.count())\nprint(my_stack.pop())\nprint(my_stack.pop())\nprint(my_stack.pop())\nprint(my_stack.pop())\nprint(my_stack.pop())\nprint(my_stack.count())\n\n# FIFO\n\nclass Queue:\n\n    def __init__(self) -> None:\n        self.queue = []\n\n    def equeue(self, item):\n        self.queue.append(item)\n    \n    def deequeue(self):\n        if self.count() == 0:\n            return None\n        self.queue.pop(0)\n    \n    def count(self):\n        return len(self.queue)\n    \n    def print(self):\n        for item in self.queue:\n            print(item)\n\nmy_queue = Queue()\nmy_queue.equeue(\"A\")\nmy_queue.equeue(\"B\")\nmy_queue.equeue(\"C\")\nprint(my_queue.count())\nmy_queue.print()\nmy_queue.deequeue()\nprint(my_queue.count())\nmy_queue.print()\nprint(my_queue.deequeue())\nprint(my_queue.deequeue())\nprint(my_queue.deequeue())\nprint(my_queue.deequeue())\nprint(my_queue.deequeue())\nprint(my_queue.count())"
  },
  {
    "path": "Roadmap/08 - CLASES/python/isilanes.py",
    "content": "from abc import ABC, abstractmethod\nfrom typing import TypeVar\n\n\nT = TypeVar(\"T\")\n\n\nclass Dog:\n\n    def __init__(self, name: str, age: int = 1):\n        self.name = name\n        self.age = age\n\n    def __str__(self):\n        if self.age == 1:\n            return f\"El cachorrito {self.name} tiene un añito\"\n\n        if self.age < 5:\n            return f\"El cachorro {self.name} tiene {self.age} años\"\n\n        return f\"{self.name} tiene {self.age} años\"\n\n\nclass Collection(ABC):\n\n    def __init__(self, content: list[T] | None = None):\n        self.content: list[T] = content or []\n\n    def add(self, element: T) -> None:\n        \"\"\"\n        Add 'element' to the collection.\n\n        Args:\n            element (T):\n                Element to add to the collection.\n\n        Return:\n            Nothing.\n        \"\"\"\n        self.content.append(element)\n\n    @abstractmethod\n    def extract(self) -> T:\n        \"\"\"\n        Remove (and return) next element in the collection, according\n        to the rules of the specific collection (FILO/LIFO for Stack,\n        FIFO for Queue).\n\n        Args:\n            None.\n\n        Returns:\n            The extracted element.\n        \"\"\"\n\n    @property\n    def size(self) -> int:\n        \"\"\"\n        Return the size of the collection, as the count of elements in it.\n        \"\"\"\n        return len(self.content)\n\n    def __str__(self) -> str:\n        return str(self.content)\n\n\nclass Stack(Collection):\n\n    def extract(self) -> T:\n        return self.content.pop()\n\n\nclass Queue(Collection):\n\n    def extract(self) -> T:\n        return self.content.pop(0)\n\n\ndef extra():\n    stack = Stack([1, 2, 3])\n    print(f\"\\nContenido inicial de la pila: {stack}\")\n    print(f\"Extraemos un elemento (el {stack.extract()})\")\n    print(f\"Contenido de la pila actualizado: {stack}\")\n    print(f\"Ahora la pila tiene tamaño {stack.size}\")\n    print(\"Añadimos un elemento a la pila (el 4)\")\n    stack.add(4)\n    print(f\"Contenido de la pila actualizado: {stack}\")\n\n    queue = Queue([\"a\", \"b\", \"c\"])\n    print(f\"\\nContenido inicial de la cola: {queue}\")\n    print(f\"Extraemos un elemento (la '{queue.extract()}')\")\n    print(f\"Contenido de la cola actualizado: {queue}\")\n    print(f\"Ahora la cola tiene tamaño {queue.size}\")\n    print(\"Añadimos un elemento a la cola (la 'd')\")\n    queue.add(\"d\")\n    print(f\"Contenido de la cola actualizado: {queue}\")\n\n\ndef main():\n    dog = Dog(name=\"Pluto\")\n    print(dog)\n    dog.age = 3\n    print(dog)\n    dog.age = 10\n    print(dog)\n\n\nif __name__ == \"__main__\":\n    main()\n    extra()\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/javierjoyera.py",
    "content": "class Coche:\n    def __init__ (self, marca, modelo, color, precio):\n        self.marca = marca\n        self.modelo = modelo\n        self.color = color\n        self.precio = precio\n\n    def imprimir(self):\n        print(\"Marca: %s\" % self.marca)\n        print(\"Modelo: %s\" % self.modelo)\n        print(\"Color: %s\" % self.color)\n        print(\"Precio: %s\" % self.precio)\n\ncoche = Coche(\"Seat\", \"Ibiza\", \"Rojo\", 10000)\ncoche.imprimir()\n\ncoche.marca = \"Renault\"\ncoche.modelo = \"Clio\"\ncoche.color = \"Negro\"\ncoche.precio = 14599\ncoche.imprimir()\n\n\nclass Pila:\n    def __init__(self): \n        self.items = []\n    def push(self, item):\n        self.items.append(item)\n    def pop(self):\n        if not self.is_empty():\n            return self.items.pop()\n        else:\n            return \"La pila está vacía\"\n    def is_empty(self):\n        return len (self.items) == 0\n    def is_the_top(self):\n        if not self.is_empty():\n            return self.items[-1]\n        else:\n            return \"La pila está vacía\"\n    def contenido(self):\n        return len(self.items)\n    def imprimir_contenido(self):\n        for item in self.items:\n            print(item)\n    \nclass Cola:\n    def __init__(self):\n        self.items = []\n    def enqueue(self, item):\n        self.items.append(item)\n    def dequeue(self):\n        if not self.is_empty():\n            return self.items.pop(0)\n        else:\n            return \"La cola está vacía\"\n    def is_empty(self):\n        return len(self.items) == 0\n    \n    def contenido(self):\n        return len(self.items)\n    def imprimir_contenido(self):\n        for item in self.items:\n            print(item)\n\npila = Pila()\npila.push(1)\npila.push(2)\npila.push(3)\n\nprint(pila.pop())\nprint(pila.is_the_top())\nprint(pila.contenido())\npila.imprimir_contenido()\n\ncola = Cola()\ncola.enqueue(1)\ncola.enqueue(2)\ncola.enqueue(3)\n\nprint(cola.dequeue())\nprint(cola.contenido())\ncola.imprimir_contenido()\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/jcdm60.py",
    "content": "# #08 CLASES\n#### Dificultad: Fácil | Publicación: 19/02/24 | Corrección: 26/02/24\n\n## Ejercicio\n\n#\n# EJERCICIO:\n# Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n# atributos y una función que los imprima (teniendo en cuenta las posibilidades\n# de tu lenguaje).\n# Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n# utilizando su función.\n#\n# DIFICULTAD EXTRA (opcional):\n# Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n# en el ejercicio número 7 de la ruta de estudio)\n# - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n#   retornar el número de elementos e imprimir todo su contenido.\n# \n#\n\nclass Pila:\n    def __init__(self):\n        self.items = []\n\n    def esta_vacia(self):\n        return self.items == []\n\n    def agregar(self, item):\n        self.items.append(item)\n\n    def eliminar(self):\n        return self.items.pop()\n\nclass Cola:\n    def __init__(self):\n        self.items = []\n\n    def esta_vacia(self):\n        return self.items == []\n\n    def agregar(self, item):\n        self.items.append(item)\n\n    def eliminar(self):\n        return self.items.pop(0)\n\n# Ejemplo de uso de la pila\npila = Pila()\npila.agregar(1)\npila.agregar(2)\npila.agregar(3)\n\nprint(\"Elementos en la pila:\")\nwhile not pila.esta_vacia():\n    print(pila.eliminar())\n\n# Ejemplo de uso de la cola\ncola = Cola()\ncola.agregar('a')\ncola.agregar('b')\ncola.agregar('c')\n\nprint(\"\\nElementos en la cola:\")\nwhile not cola.esta_vacia():\n    print(cola.eliminar())\n    \nclass Pila:\n    def __init__(self):\n        self.items = []\n\n    def esta_vacia(self):\n        return self.items == []\n\n    def agregar(self, item):\n        self.items.append(item)\n\n    def eliminar(self):\n        return self.items.pop()\n\n\nclass NavegadorWeb:\n    def __init__(self):\n        self.historial_atras = Pila()\n        self.historial_adelante = Pila()\n        self.pagina_actual = \"\"\n\n    def navegar(self, url):\n        if self.pagina_actual:\n            self.historial_atras.agregar(self.pagina_actual)\n            self.historial_adelante = Pila()  # Limpiar historial adelante cuando navegamos a una nueva página\n        self.pagina_actual = url\n        print(\"Navegando a:\", url)\n\n    def retroceder(self):\n        if not self.historial_atras.esta_vacia():\n            pagina_anterior = self.historial_atras.eliminar()\n            self.historial_adelante.agregar(self.pagina_actual)\n            self.pagina_actual = pagina_anterior\n            print(\"Navegando hacia atrás a:\", pagina_anterior)\n        else:\n            print(\"No hay páginas disponibles para retroceder.\")\n\n    def avanzar(self):\n        if not self.historial_adelante.esta_vacia():\n            pagina_siguiente = self.historial_adelante.eliminar()\n            self.historial_atras.agregar(self.pagina_actual)\n            self.pagina_actual = pagina_siguiente\n            print(\"Navegando hacia adelante a:\", pagina_siguiente)\n        else:\n            print(\"No hay páginas disponibles para avanzar.\")\n\n    def mostrar_pagina_actual(self):\n        print(\"Página actual:\", self.pagina_actual)\n\n\n# EXTRA: SIMULA MECANISMO ADELANTE O ATRAS DE UN PAGINA WEB\nif __name__ == \"__main__\":\n    navegador = NavegadorWeb()\n\n    while True:\n        entrada = input(\"Introduce una URL o 'adelante'/'atras' para navegar (o 'salir' para salir): \")\n\n        if entrada.lower() == \"salir\":\n            print(\"Saliendo del navegador.\")\n            break\n        elif entrada.lower() == \"adelante\":\n            navegador.avanzar()\n        elif entrada.lower() == \"atras\":\n            navegador.retroceder()\n        else:\n            navegador.navegar(entrada)\n\n        navegador.mostrar_pagina_actual()\n    \n\nclass Cola:\n    def __init__(self):\n        self.items = []\n\n    def esta_vacia(self):\n        return self.items == []\n\n    def agregar(self, item):\n        self.items.append(item)\n\n    def eliminar(self):\n        if not self.esta_vacia():\n            return self.items.pop(0)\n        else:\n            return None\n\n\nclass ImpresoraCompartida:\n    def __init__(self):\n        self.cola_impresion = Cola()\n\n    def recibir_documento(self, documento):\n        self.cola_impresion.agregar(documento)\n        print(\"Documento recibido:\", documento)\n\n    def imprimir_documento(self):\n        documento = self.cola_impresion.eliminar()\n        if documento:\n            print(\"Imprimiendo:\", documento)\n        else:\n            print(\"No hay documentos en la cola de impresión.\")\n\n    def mostrar_cola(self):\n        if self.cola_impresion.esta_vacia():\n            print(\"Cola de impresión vacía.\")\n        else:\n            print(\"Cola de impresión:\", self.cola_impresion.items)\n\n# EXTRA: SIMULA EL MECANISMO DE UNA IMPRESORA\nif __name__ == \"__main__\":\n    impresora = ImpresoraCompartida()\n\n    while True:\n        entrada = input(\"Introduce un documento para imprimir o 'imprimir' para imprimir un documento (o 'salir' para salir): \")\n\n        if entrada.lower() == \"salir\":\n            print(\"Saliendo del programa.\")\n            break\n        elif entrada.lower() == \"imprimir\":\n            impresora.imprimir_documento()\n        else:\n            impresora.recibir_documento(entrada)\n\n        impresora.mostrar_cola()\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/jesusgdev.py",
    "content": "'''\n* EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n   atributos y una función que los imprima (teniendo en cuenta las posibilidades\n   de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n   utilizando su función.\n  \n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n   en el ejercicio número 7 de la ruta de estudio)\n   - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n     retornar el número de elementos e imprimir todo su contenido.\n \n'''\n\n# 1. Crea la clase y el inicializador\n\n# Voy a crear una clase como ejemplo que tenga como atributos el nombre y la edad\nclass Pet:\n    # Atributo opcional que no es requerido al crear una instancia pero que podemos usar\n    specie: str = None\n\n    def __init__(self, name: str, age: int):\n        self.name = name    # Guardamos el nombre como atributo\n        self.age = age      # Guardamos la edad como atributo\n\n# 2. Agrega una funcion para mostrar los datos\n\n    # Creo un metodo para la clase mascota que imprima tanto el nombre como la edad\n    def show_info(self):\n        print(f\"Nombre: {self.name}| Specie: {self.specie} | Edad: {self.age}\")\n\n# 3. Usa la clase(crea una mascota)\nmy_pet = Pet(\"Fawler\", 17)\n\n# 4. Llama a la funcion para mostrar la informacion\nmy_pet.show_info()\n\n# Podemos agregar un atributo opcional a cualquier instancia y utilizarlo cuando se requiera\nmy_pet.specie = \"Ave\"  \nmy_pet.show_info() \n\n# 5. Modifica los atributos despues de crear el objeto\nmy_pet.name = \"Zerk\"\nmy_pet.age = 12\nmy_pet.specie = \"Camaleon\"\nmy_pet.show_info()\n\n'''\nExtra\n'''\n\n# 1. Implementacion de clases usando la estructura de datos pila\n\nclass Stack:\n    def __init__(self):\n        self.stack = []\n\n    def push(self, item):\n        self.stack.append(item)\n        print(f\"Agregando {item} a la pila\")\n\n    def pop(self):\n        if len(self.stack) == 0:\n            print(\"La pila esta vacia\")\n        else:\n            removido = self.stack.pop()\n            print(f\"\\nDesapilando {removido} de la pila\")\n\n    def count(self):\n        longitud = len(self.stack)\n        print(f\"\\nLa pila tiene {longitud} elementos\")\n\n    def print(self):\n        if len(self.stack) == 0:\n            print(\"La pila esta vacia\")\n        else:\n            print(\"\\nImprimiendo la pila:\")\n            for elemento in reversed(self.stack):\n                print(elemento)\n\nmy_stack = Stack()\n\nmy_stack.push(1)\nmy_stack.push(2)\nmy_stack.push(3)\nmy_stack.push(4)\n\nmy_stack.print()\n\nmy_stack.count()\n\nmy_stack.pop()\n\nmy_stack.print()\n\nmy_stack.count()\n\n\n# 2. Implementacion de clases usando la estructura de datos cola\n\nclass Queue:\n    def __init__(self):\n        self.queue = []\n\n    def enqueue(self, item):\n        self.queue.append(item)\n        print(f\"Agregando {item} a la cola\")\n\n    def dequeue(self):\n        if len(self.queue) == 0:\n            print(\"La cola esta vacia\")\n        else:\n            removido = self.queue.pop(0)\n            print(f\"\\nEl elemento {removido} a salido de la cola\")\n\n    def count(self):\n        if len(self.queue) == 0:\n            print(\"La cola esta vacia\")\n        else:\n            print(f\"La cola tiene {len(self.queue)} elementos\")\n\n    def print(self):\n        if len(self.queue) == 0:\n            print(\"La cola esta vacia\")\n        else:\n            print(\"\\nImprimiendo la cola:\")\n            for elementos in self.queue:\n                print(elementos)\n\nmy_queue = Queue()\n\nmy_queue.enqueue(1)\nmy_queue.enqueue(2)\nmy_queue.enqueue(3)\nmy_queue.enqueue(4)\n\nmy_queue.print()\n\nmy_queue.count()\n\nmy_queue.dequeue()\n\nmy_queue.print()\n\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/jesusway69.py",
    "content": "import os\n#os.system('clear') #MAC/LINUX\nos.system('cls') #WINDOWS\n\"\"\" * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n\"\"\"\n\n\nclass MyClass: #Declaración de clase\n    def __init__(self) -> None: #Definición del constructor de clase o método de instancia\n        self.my_num_list = [] #Objeto con el que trabajaremos en la clase\n        \n    def my_iterator(self,init_num, end_num):#Función de clase que en este caso llenará de valores\n     for i in range(init_num,end_num):# numéricos la lista que creamos como objeto recibiendo los\n          self.my_num_list.append(i)# parámetros que indiquen el rango de numeración a incluir\n     self.show_list(self.my_num_list)#Dentro de esta función llamaremos a la otra función que se\n                                     # encarga de imprimir la lista\n    def show_list(self, my_num_list):# Función de clase que imprime la lista\n       print(self.my_num_list)\n\nresult = MyClass()#Instanciamos la clase en una variable\nresult.my_iterator(1,11)#a partir de esa instancia ya podemos \n                       # llamar a las funciones y pasarle sus parámetros si son necesarios\nprint(\"\\n\\n\")\n\n\n       \n\n\n\n\"\"\" * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\"\"\"\n\nclass Stack(): #Clase pila (LIFO)\n    def __init__(self) -> None:\n      self.my_stack_list = []\n\n    def add (self, init_number, end_number):\n      for num in range (init_number, end_number):\n       self.my_stack_list.append(num)\n\n    def unstack (self):#Método de clase que elimina el último elemento añadido\n      self.my_stack_list.pop()\n    \n    def leght (self):\n       return len(self.my_stack_list)\n    \n    def show (self):\n       print(self.my_stack_list)\n\n\nclass Queue():  #Clase cola (FIFO)\n    def __init__(self) -> None:\n      self.my_stack_list = []\n\n    def add (self, init_number, end_number):\n     for num in range (init_number, end_number):\n       self.my_stack_list.append(num)\n\n    def dequeue (self):#Método de clase que elimina el primer elemento añadido\n      self.my_stack_list.pop(0)\n    \n    def leght (self):\n       return len(self.my_stack_list)\n    \n    def show (self):\n       print(self.my_stack_list)\n\nstack_instance = Stack()#Instacia de clase\nqueue_instance = Queue()#Instacia de clase\n\nstack_instance.add(1,11)\nstack_instance.show()\nprint(f\"La lista tiene {stack_instance.leght()} números\\n\")\nstack_instance.unstack()\nstack_instance.show()\nprint(f\"La lista tiene {stack_instance.leght()} números\\n\")\n\nqueue_instance.add(1,11)\nqueue_instance.show()\nprint(f\"La lista tiene {queue_instance.leght()} números\\n\")\nqueue_instance.dequeue()\nqueue_instance.show()\nprint(f\"La lista tiene {queue_instance.leght()} números\\n\")\n\n\"\"\"\nEn este caso concreto hemos hecho una clase para cada uno de los requerimientos de pila y cola\ntal y como pide el enunciado del ejercicio pero en un caso real lo ideal sería hacer una sola \nclase para ambos casos dada la semejanza que existe entre ambos casos, en la misma clase incluiríamos\nun método para eliminar el primer elemento de la lista y otro para eliminar el último ya que el resto\nde métodos son idénticos para ambos propósitos como vemos en la clase creada mas abajo \n\"\"\"\n\nclass ListModificator:\n    def __init__(self):\n        self.my_num_list = []\n \n    def add (self, init_number, end_number):\n     for num in range (init_number, end_number):\n       self.my_stack_list.append(num)\n\n    def pop_first(self):#Elimina el primer elemento para un ejeplo de cola (FIFO)\n        return self.my_num_list.pop(0)\n \n    def pop_last(self):#Elimina el último elemento para un ejeplo de pila (LIFO)\n        return self.my_num_list.pop()\n\n    def leght(self):\n        return len(self.my_num_list)\n   \n   "
  },
  {
    "path": "Roadmap/08 - CLASES/python/jhoshmc.py",
    "content": "class Mamifero:\n  #? atributos\n  def __init__(self,especie,nombre,edad):\n    self._especie = especie\n    self._nombre = nombre\n    self._edad = edad\n  def saludar(self):\n    if self._especie == \"humano\":\n      print(f\"\\nhola mi nombre es {self._nombre} y tengo {self._edad}, mucho gusto\")\n    else:\n      print(f\"\\nmi nombre es {self._nombre} y saludo dando la pata\")\n\nclass Pila:\n  #?atributos\n  def __init__(self):\n    self.stack=[]\n  #? metodos\n  #*metodo para saber si la cola está vacia, true: vacio, false: tiene elementos\n  def empy(self)->bool:\n    return self.stack == []\n  #*metodo para agregar un elemento al final de la pila\n  def push(self,elemento):\n    self.stack.append(elemento)\n  #* metodo para retornar el ultimo elemento sin eliminarlo\n  def back(self):\n    if not self.empy():\n      return self.stack[-1]\n  #* metodo para eliminar el ultimo elemento de la pila y retornarlo\n  def pop(self):\n    if not self.empy():\n      return self.stack.pop()\n  #* metodo para mostrar el tamaño de la pila\n  def size(self)->int:\n    return len(self.stack)\n  #* mostar pila\n  def print(self):\n    if not self.empy():\n      \n      print(self.stack)\n    else:\n      print(\"\\nno hay elementos en la pila para mostrar\")\n    \nclass Cola:\n  #? atributos\n  def __init__(self):\n    self.queque=[]\n  #?metodos\n  #* metodo para saber si la cola esta vacia, true:vacia, false: hay elementos\n  def empty(self)->bool:\n    return self.queque == []\n  #* metodo para agregar un elemnto al final de la cola\n  def push(self,elemento):\n    self.queque.append(elemento)\n  #* metodo para mostrar el primer elemento de la cola, sin eliminarlo\n  def front(self):\n    if not self.empty():\n      return self.queque[0]\n    else:\n      print(f\"\\nno hay elementos en la cola\")\n  #* metodo para eliminar el primer elemento de la cola\n  def pop(self):\n    if not self.empty():\n      return self.queque.pop(0)\n    print(f\"\\nno hay elementos para mostrar\")\n  #* metodo para saber el tamaño de la cola\n  def size(self):\n    return len(self.queque)\n  #* metodo para mostrar la cola\n  def print(self)->None:\n    if not self.empty():\n      print(self.queque)\n    else:\n      print(\"\\nno hay elementos que mostrar en la cola\")\n\n#todo funciones\ndef ejercicio():\n  martin =  Mamifero(edad=20,especie=\"humano\",nombre=\"martin\")\n  chester = Mamifero(\"canina\",\"chester\",3)\n  laila = Mamifero(\"canina\",\"laila\",2)\n  lita = Mamifero(\"felina\",\"lita\",1)\n  martin.saludar()\n  chester.saludar()\n  laila.saludar()\n  lita.saludar()\ndef extraPila():\n  pila = Pila()\n  print(f\"la pila esta vacia?: {pila.empy()}\")\n  print(\"agregano elementos a la pila: \")\n  pila.push(1)\n  pila.push(2)\n  pila.push(3)\n  print(f\"el tamaño de la pila es: {pila.size()}\")\n  print(f\"mostrando el ultimo elemento: {pila.back()}\")\n  print(\"mostrando pila\")\n  pila.print()\n  print(f\"eliminado ultimo elemento de la pila: {pila.pop()}\")\n  pila.print()\n  print(f\"eliminado ultimo elemento de la pila: {pila.pop()}\")\n  pila.print()\n  print(f\"eliminado ultimo elemento de la pila: {pila.pop()}\")\n  pila.print()\ndef extraCola():\n  cola = Cola()\n  print(f\"la cola esta vacia?: {cola.empty()}\")\n  print(\"agregando elementos a la cola\")\n  cola.push(1)\n  cola.push(2)\n  cola.push(3)\n  print(f\"tamaño de la cola: {cola.size()}\")\n  print(f\"el primer elemto de la cola es: {cola.front()}\")\n  print(\"los elementos de la cola son : \")\n  cola.print()\n  print(f\"eliminado el primer elemento de la cola: {cola.pop()}\")\n  cola.print()\n  print(f\"eliminado el primer elemento de la cola: {cola.pop()}\")\n  cola.print()\n  print(f\"eliminado el primer elemento de la cola: {cola.pop()}\")\n  cola.print()\n\n#todo ejecutando \nejercicio()\nextraPila()\nextraCola()\n  "
  },
  {
    "path": "Roadmap/08 - CLASES/python/jorgeadamowicz.py",
    "content": "\"\"\"\nEJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n \"\"\"\n\n### EJERCICIO: ###\nclass Persona:\n    #metodo inicializador\n    def __init__(self, nombre, edad, actividad):\n        self.nombre = nombre\n        self.edad = edad\n        self.actividad = actividad\n    \n    #metodo para imprimir atributos de clase a traves del metodo __str__\n    def __str__(self):\n        return f\"Nombre: {self.nombre} \\nEdad: {self.edad} \\nActividad: {self.actividad} \\n\"\n    \n    #metodo que muestra los atributos de clase\n    def mostrar_atributos(self):\n        print(f\"Nombre: {self.nombre}\\nEdad: {self.edad} \\nActividad: {self.actividad}\\n\")\n    \n#instancia de clases\npersona1 = Persona(\"juank\", 25 , \"Programador\")\n\n#llamo al método mostrar_atributos\npersona1.mostrar_atributos()\n\n#modifico atributo de clase\npersona1.nombre = \"Juan Gabriel\"\n\n#llamo al método __str__\nprint(persona1)\n\n### DIFICULTAD EXTRA: ###\n\n## Pila (LIFO)##\nclass Pila:\n    #metodo inicializador\n    def __init__(self):\n        self.pila = []\n        \n    #metodo 'Push' que añade un elemento a la pila    \n    def añadir_elemento(self, elemento):\n        self.pila.append(elemento)\n        \n    #metodo 'Pop' que elimina un elemento de la pila\n    def eliminar_elemento(self):\n        #verifica que la pila no este vacia\n        if self.contar_elementos() == 0:\n            #retorna None si la pila esta vacia\n            return None\n        return self.pila.pop()\n        \n    \n    #metodo 'Count' que retorna el numero de elementos de la pila\n    def contar_elementos(self):\n        return len(self.pila)\n    \n    #metodo 'Print' que imprime el contenido de la pila\n    def imprimir_elementos(self):\n        #recorre la lista de manera inversa\n        for elemento in reversed(self.pila): #reverse() invierte los valores de la secuencia dada \n            print(elemento)\n\n#creo una instacia de la clase Pila\nmi_pila = Pila()\n#añado elementos a la pila\nmi_pila.añadir_elemento(\"elemento 1\")\nmi_pila.añadir_elemento(\"elemento 2\")\nmi_pila.añadir_elemento(\"elemento 3\")\nmi_pila.añadir_elemento(\"elemento 4\")\n#muestro la lista de elementos\nmi_pila.imprimir_elementos()\n#muestro la cantidad de elementos\nprint(f\"la cantidad de elementos es: {mi_pila.contar_elementos()}\\n\")\n\n#elimino un elemento de la pila\nmi_pila.eliminar_elemento()\n#muestro la lista de elementos\nmi_pila.imprimir_elementos()\n#muestro la cantidad de elementos\nprint(f\"la cantidad de elementos es: {mi_pila.contar_elementos()}\\n\")\n\n\n## Cola (FIFO)##\n\nclass Cola:\n    #metodo inicializador\n    def __init__(self):\n        self.cola = []\n    \n    #metodo 'enqueue' que añade un elemento a la cola\n    def añadir_elemento(self, elemento):\n        self.cola.append(elemento)\n        \n    #metodo 'dequeue' que elimina un elemento de la cola\n    def eliminar_elemento(self):\n        #verifica que la cola no este vacia\n        if self.contar_elementos() == 0:\n            #retorna None si la cola esta vacia\n            return None\n        #se elimina el primer elemento de la cola indicando el indice '0'\n        return self.cola.pop(0)\n    \n    #metodo 'Count' que retorna el numero de elemntos de la cola\n    def contar_elementos(self):\n        return len(self.cola)\n    \n    #metodo 'Print' que imprime el contenido de la cola\n    def imprimir_elementos(self):\n        for elemntos in self.cola:\n            print(elemntos)\n            \n#creo una instancia de la clase Cola\nmi_cola = Cola()\n#añado elementos a la cola\nmi_cola.añadir_elemento(\"elemento 1\")\nmi_cola.añadir_elemento(\"elemento 2\")\nmi_cola.añadir_elemento(\"elemento 3\")\nmi_cola.añadir_elemento(\"elemento 4\")\n\n#muestro la lista de elementos\nmi_cola.imprimir_elementos()\n#muestro la cantidad de elementos\nprint(f\"la cantidad de elementos es: {mi_cola.contar_elementos()}\\n\")\n\n#elimino un elemento de la pila\nmi_cola.eliminar_elemento()\n#muestro la lista de elementos\nmi_cola.imprimir_elementos()\n#muestro la cantidad de elementos\nprint(f\"la cantidad de elementos es: {mi_cola.contar_elementos()}\\n\")\n    \n    \n    \n    "
  },
  {
    "path": "Roadmap/08 - CLASES/python/josealberto13.py",
    "content": "\"\"\" EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\"\"\"\n \n \nclass Profile:\n    def __init__(self, name: str, surname: str, age: int, job: str) -> None:\n        self.name = name\n        self.surname = surname\n        self.age = age\n        self.job = job\n\n    def details(self):\n        print(f\"Nombre: {self.name}\\nApellido: {self.surname}\\nEdad: {self.age}\\nCargo: {self.job}\")\n\nperfil_1 = Profile(\"José\", \"Figueroa\", 22, \"Programador\")\nperfil_1.details()\n\nperfil_1.age = 26\nperfil_1.details()\n\n\n\"\"\" DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n\"\"\"\n\nclass Stack:\n    def __init__(self):\n        self.stack = []\n\n\n    def push(self, item):\n        self.stack.append(item)\n    \n    def pop(self):\n        if len(self.stack) == 0:\n            return None\n        return self.stack.pop()\n    \n    def count(self):\n        return len(self.stack)\n    \n    def print(self):\n        for item in reversed(self.stack):\n            print(item)\n    \nmy_stack = Stack()\nmy_stack.push(\"a\")\nmy_stack.push(\"b\")\nmy_stack.push(\"c\")\nprint(my_stack.count())\nmy_stack.print()\nprint(f\"Eliminado: {my_stack.pop()}\")\nprint(my_stack.count())\nmy_stack.print()\n\nclass Queue():\n    def __init__(self):\n        self.queue = []\n    \n    def inqueue(self, item):\n        self.queue.append(item)\n\n    def deequeue(self):\n        if len(self.queue) == 0:\n            return None\n        return self.queue.pop(0)\n    \n    def count(self):\n        return len(self.queue)\n    \n    def print(self):\n        for item in self.queue:\n            print(item)\n\n\nmy_queue = Queue()\nmy_queue.inqueue(\"A\")\nmy_queue.inqueue(\"B\")\nmy_queue.inqueue(\"C\")\nmy_queue.inqueue(\"D\")\nprint(my_queue.count())\nmy_queue.print()\nmy_queue.deequeue()\nmy_queue.deequeue()\nprint(my_queue.count())\nmy_queue.print()"
  },
  {
    "path": "Roadmap/08 - CLASES/python/josecox13.py",
    "content": "'''\n EJERCICIO 8:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n */\n'''\nclass Coche:\n    def __init__(self, marca: str, años: int):\n        self.marca = marca\n        self.años = años\n    def print(self):\n        print(f'Marca: {self.marca}, Años: {self.años}')\ncoche1 = Coche('Seat', 5)\n\ncoche1.print()\ncoche1.marca = 'Renault'\ncoche1.print()\n\n'''\nEjercicio extra\n'''\nclass Stack:\n    def __init__(self):\n        self.stack = []\n    def push(self, item):\n        self.stack.append(item)\n    def pop(self):\n        if len(self.stack) == 0:\n            return('No hay elementos en la pila')\n        return self.stack.pop()\n    def contar(self):\n        return len(self.stack)\n    def print(self):\n        print(self.stack)\nmi_stack = Stack()\nmi_stack.push(1)\nmi_stack.push(2)\nmi_stack.push(3)\nprint(mi_stack.contar())\nmi_stack.print()\nmi_stack.pop()\nmi_stack.print()\nmi_stack.pop()\nmi_stack.pop()\nmi_stack.print()\n\nclass Queue():\n    def __init__(self):\n        self.queue = []\n    def enqueue(self, item):\n        self.queue.append(item)\n    def dequeue(self):\n        if len(self.queue) == 0:\n            return('No hay elementos en la cola')\n        return self.queue.pop(0)\n    def contar(self):\n        return len(self.queue)\n    def print(self):\n        print(self.queue)\n\nmi_queue = Queue()\nmi_queue.enqueue(1)\nmi_queue.enqueue(2)\nmi_queue.enqueue(3)\nprint(mi_queue.contar())\nmi_queue.print()\nmi_queue.dequeue()\nmi_queue.print()\nmi_queue.dequeue()\nmi_queue.dequeue()\nmi_queue.print()\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/jptxaya.py",
    "content": "#CLASES\n\nclass Person:\n    name = \"\"\n    surname = \"\"\n    age = 0\n    def __init__(self,param_name,param_surname,param_age) -> None:\n        self.name = param_name\n        self.surname = param_surname\n        self.age = param_age\n    def __str__(self) -> str:\n        return \" \".join([\"Name:\",self.name,\"Surname:\",self.surname,\"Age:\",str(self.age)])\n\nperson = Person(\"jptx\",\"aya\",40)\n\nprint(str(person))\n\n#Dificultad Extra\nprint(\"Pila\")\nclass Pila:\n\n    def __init__(self, p_list: list) -> None:\n        self.my_list = p_list\n    def add(self,p_value) -> None:\n        self.my_list.append(p_value)\n    def remove(self):\n        self.my_list.pop()\n    def count(self):\n        print(f\"Total Elements: {len(self.my_list)}\")\n    def print_all(self) -> None:\n        print(\"Elementos en la Pila:\")\n        for elem in self.my_list:\n            print(elem)\n\npila = Pila([\"aa\",\"bb\",\"cc\"])\npila.print_all()\nprint(\"Adding dd y ff\")\npila.add(\"dd\")\npila.add(\"ff\")\npila.print_all()\nprint(\"Removing last input\")\npila.remove()\npila.print_all()\npila.count()\n\nprint(\"************************************************\")\nprint(\"Cola\")\nclass Cola:\n    def __init__(self,p_list:list) -> None:\n        self.my_list = p_list\n    def add(self,p_value) -> None:\n        self.my_list.append(p_value)\n    def remove(self):\n        return self.my_list.pop(0)\n    def count(self):\n        print(f\"Total Elements: {len(self.my_list)}\")\n    def print_all(self) -> None:\n        print(\"Elementos en la Cola:\")\n        for elem in self.my_list:\n            print(elem)\n\ncola = Cola([\"aa\",\"bb\",\"cc\"])\ncola.print_all()\nprint(\"Adding dd y ff\")\ncola.add(\"dd\")\ncola.add(\"ff\")\ncola.print_all()\nprint(\"Removing first input\")\ncola.remove()\ncola.print_all()\nprint(f\"Total Elementos: {cola.count}\")\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/juanRCoder.py",
    "content": "\n# CLASES, estructura de datos abstrata, que permite el encapsulamiento de datos y comportamientos.\n\n# Sintaxis\nclass Animal:\n    default_name = 'perro'  # Atributo de clase\n\n    def __init__(self, name=None):  # Constructor, inicializa atributos de instancia\n        if not name:\n            self.name = Animal.default_name  # Accediendo al atributo de clase\n        else:\n            self.name = name  # Atributo de instancia\n\n    def greet(self):  # Método de instancia\n        print(f'Hola {self.name}')\n\n    def default(self):  # Método de instancia que accede directamente al atributo de clase\n        print(Animal.default_name)\n\n    @classmethod\n    def method(cls):  # Método de clase\n        print(cls.default_name)  # Accediendo al atributo de clase mediante cls\n\n\n\nperro = Animal('Scott') # Crear un objeto a partir de la clase\nperro.greet()   # accediendo al metodo de instancia 'greet'\n# Hola Scott\nperro.method() # accediendo al metodo de clase 'method'\n# perro\nprint(perro.default_name) # imprimiedo el atributo de la clase\n# perro\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/juanchernandezdev.py",
    "content": "### Python Classes ###\n\nclass Worker:\n  def __init__(self, name, age, job):\n    self.name = name\n    self.age = age\n    self.job = job\n    \n  def print_attributes(self):\n    print(self.name, self.age, self.job)\n  \nfirst_worker = Worker('jonh', 45, 'teacher')\n\nfirst_worker.print_attributes()\n\n#! Optional Challenge\n\n#* Stack Class\n\nclass Stack:\n  def __init__(self):\n    self.stack = []\n    \n  def add(self, elem):\n    self.stack.append(elem)\n    \n  def remove(self):\n    self.stack.pop()\n    \n  def clear(self):\n    self.stack.clear()\n    \n  def size(self):\n    return len(self.stack)\n    \n  def is_empty(self):\n    if len(self.stack) > 0:\n      return 'Stack is not empty'\n    else:\n      return 'The stack is empty'\n      \nmy_stack = Stack()\n\nmy_stack.add(4)\nmy_stack.add(10)\nmy_stack.add(50)\nmy_stack.add(15)\n\nprint(my_stack.stack)\nprint(my_stack.size())\n\nmy_stack.remove()\nprint(my_stack.stack)\n\n\n#* Queue Class\n\nclass Queue:\n  def __init__(self):\n    self.queue = []\n    \n  def add(self, elem):\n    self.queue.append(elem)\n    \n  def remove(self):\n    self.queue.pop(0)\n    \n  def clear(self):\n    self.queue.clear()\n    \n  def size(self):\n    return len(self.queue)\n    \n  def is_empty(self):\n    if len(self.stack) > 0:\n      return 'Queue is not empty'\n    else:\n      return 'The queue is empty'\n    \nmy_queue = Queue()\n\nmy_queue.add(10)\nmy_queue.add(45)\nmy_queue.add(8)\nmy_queue.add(12)\nmy_queue.add(5)\n\nprint(my_queue.queue)\nprint(my_queue.size())\n\nmy_queue.remove()\nprint(my_queue.queue)\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/juandaherrera.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n\"\"\"\n\nfrom datetime import date\n\n\nclass Persona:\n    def __init__(self, first_name: str, last_name: str, birth_date: date):\n        self.first_name = first_name\n        self.last_name = last_name\n        self.birth_date = birth_date\n\n    @property\n    def age(self):\n        today = date.today()\n        age = today.year - self.birth_date.year\n        if today.month < self.birth_date.month or (\n            today.month == self.birth_date.month and today.day < self.birth_date.day\n        ):\n            age -= 1\n        return age\n\n    def describe(self):\n        print(f'{self.first_name} {self.last_name} tiene {self.age} años')\n\n\njuan_david = Persona('Juan David', 'Herrera', date(1999, 12, 5))\njuan_david.describe()\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n\"\"\"\n\n\n# Pilas\nclass Stack:\n\n    def __init__(self, stack: list = []) -> None:\n        self.stack = stack\n\n    def __str__(self) -> str:\n        return str(self.stack)\n\n    def push(self, value) -> None:\n        self.stack.append(value)\n\n    def pop(self) -> None:\n        self.stack.pop()\n\n\nmy_stack = Stack([1, 2, 3, 4, 5])\nprint(my_stack)\n\n# Inserción\nmy_stack.push(6)\nprint(my_stack)\n\n# Eliminación\nmy_stack.pop()\nprint(my_stack)\n\n\n# Colas\nclass Queue:\n    def __init__(self, queue: list = []) -> None:\n        self._queue = queue\n\n    def __str__(self) -> str:\n        return str(self._queue)\n\n    def queue(self, value) -> None:\n        self._queue.append(value)\n\n    def dequeue(self) -> None:\n        self._queue.pop(0)\n\n\nmy_queue = Queue([1, 2, 3, 4, 5])\nprint(my_queue)\n\n# Inserción\nmy_queue.queue(6)\nprint(my_queue)\n\n# Eliminación\nmy_queue.dequeue()\nprint(my_queue)\n\n# Ambas\nmy_queue.queue(7)\nmy_queue.dequeue()\nmy_queue.dequeue()\nmy_queue.dequeue()\nmy_queue.queue(8)\nmy_queue.dequeue()\nmy_queue.queue(9)\nprint(my_queue)\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/juanmax2.py",
    "content": "\"\"\"\nClases\n\"\"\"\n\nclass Persona():\n    \n    def __init__(self, nombre, edad, profesion):\n        self.nombre = nombre\n        self.edad = edad\n        self.profesion = profesion\n    \n    def saludar(self):\n        print(f\"Saludos soy {self.nombre} tengo {self.edad} años y soy {self.profesion}\")\n\n# Caso de uso\n\npersona1 = Persona(\"Juanma\", 32, \"Programador\")\n\npersona1.saludar()\n\n# Modificar un parametro\n\npersona1.edad = 33\n\npersona1.saludar()\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n\"\"\"\n\nclass Pila():\n    \n    def __init__(self):\n        self.stack = []\n\n    def push(self, archivo):\n        self.stack.append(archivo)   \n        \n    def pop(self):\n        if self.count() == 0:\n            return None\n        else:\n            return self.stack.pop()\n    \n    def count(self):\n        return len(self.stack)\n    \n    def print(self):\n        for item in reversed(self.stack):\n            print(item)\n        \nclass Cola():\n    \n    def __init__(self):\n        self.cola = []\n    \n    def push(self, archivo):\n        self.cola.append(archivo)\n        \n    def pop(self):\n        if self.count() == 0:\n            return None\n        else:\n            return self.cola.pop(0)\n    \n    def count(self):\n        return len(self.cola)\n    \n    def print(self):\n        for item in self.cola:\n            print(item)\n        \nmy_stack = Pila()\nmy_stack.push(\"A\")\nmy_stack.push(\"B\")\nmy_stack.push(\"C\")\n\nmy_stack.print()\nprint(my_stack.count())\nprint(\"-----------------\")\nmy_stack.pop()\nprint(\"-----------------\")\nmy_stack.print()\nprint(my_stack.count())\n\nprint(\"-----------------\")\nprint(\"-----------------\")\ncola = Cola()\ncola.push(\"A\")\ncola.push(\"B\")\ncola.push(\"C\")\n\ncola.print()\nprint(cola.count())\nprint(\"-----------------\")\nprint(\"-----------------\")\ncola.pop()\ncola.print()\nprint(cola.count())"
  },
  {
    "path": "Roadmap/08 - CLASES/python/juanppdev.py",
    "content": "\"\"\"\nEJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n\"\"\"\n# Clase Persona con atributo\nclass Persona:\n    def __init__(self, nombre, apellido):  # Inicializador o constructor\n        self.nombre = nombre\n        self.apellido = apellido\n\n    def imprimir(self):\n        print(\"Nombre: \", self.nombre)\n        print(\"Apellido: \", self.apellido)\n\npersona1 = Persona(\"John\", \"Doe\")\nprint(\"\\nPersona 1:\\n\")\npersona1.imprimir()\n\n# Modificar los datos de persona\npersona2 = Persona(\"Jane\", \"Smith\")\nprint(\"\\n\\nPersona 2:\\n\")\npersona2.nombre = \"Michael\"\npersona2.apellido = \"Jackson\"\npersona2.imprimir()\n# Crear una subclase llamada Estudiante que herede de la clase Persona\n# y agregue un nuevo atributo, estudiante_id. Implementar el método imprimir para mostrar este dato adicional.\n\n\nclass Estudiante(Persona):\n    def __init__(self, nombre, apellido, curso):\n        super().__init__(nombre, apellido)\n        self.curso = curso\n\n    def imprimir_estudiante(self):\n        print(\"Curso: \", self.curso)\n\n\nestudiante1 = Estudiante(\"Ana\", \"Rodríguez\", 3)\nprint(\"\\nEstudiante 1:\\n\")\nestudiante1.imprimir()\nestudiante1.imprimir_estudiante()\n\n# Probar el acceso a los atributos privados (no recomendado pero se puede hacer)\nprint(\"\\nAccediendo directamente al atributo 'curso' del estudiante 1:\\n\")\nprint(\"Curso: \", estudiante1.curso)\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola \n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n\"\"\"\n\nclass Pila:\n    def __init__(self):\n        self.elementos = []\n\n    def push(self, elemento):\n        self.elementos.append(elemento)\n\n    def pop(self):\n        if not self.esta_vacia():\n            return self.elementos.pop()\n        else:\n            raise Exception(\"La pila está vacía\")\n\n    def esta_vacia(self):\n        return len(self.elementos) == 0\n\n    def tamaño(self):\n        return len(self.elementos)\n\n    def imprimir(self):\n        print(self.elementos)\n\n\nclass Cola:\n    def __init__(self):\n        self.elementos = []\n\n    def encolar(self, elemento):\n        self.elementos.append(elemento)\n\n    def desencolar(self):\n        if not self.esta_vacia():\n            return self.elementos.pop(0)\n        else:\n            raise Exception(\"La cola está vacía\")\n\n    def esta_vacia(self):\n        return len(self.elementos) == 0\n\n    def tamaño(self):\n        return len(self.elementos)\n\n    def imprimir(self):\n        print(self.elementos)\n\n\n# Ejemplo de uso\npila = Pila()\npila.push(1)\npila.push(2)\npila.push(3)\npila.imprimir()  # [1, 2, 3]\nprint(pila.tamaño())  # 3\nprint(pila.pop())  # 3\nprint(pila.tamaño())  # 2\n\ncola = Cola()\ncola.encolar(1)\ncola.encolar(2)\ncola.encolar(3)\ncola.imprimir()  # [1, 2, 3]\nprint(cola.tamaño())  # 3\nprint(cola.desencolar())  # 1\nprint(cola.tamaño())  # 2"
  },
  {
    "path": "Roadmap/08 - CLASES/python/juserdev.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n * \n */ \"\"\"\n\nclass Person:\n  def __init__(self, name, surname, age, alias=\"sin alias\"):\n    self.name = name\n    self.surname = surname\n    self.age = age\n    self.__alias = alias\n\n  def get_name(self):\n    return (f\"Mi nombre es: {self.name}, mi apellido es: {self.surname}, tengo {self.age} años y mi alias es: {self.__alias}\")\n  \n  def get_alias(self): \n    return (f\"Mi alias es: {self.__alias}\")\n  \n  def set_alias(self, new_alias):\n    self.__alias = new_alias\n\nperson_one = Person(\"juan\", \"rodriguez\",35, \"juserdev\")\n\nprint(person_one.get_name())\nprint(person_one.get_alias()) # para poder acceder al alias debo crear una funcion para poder acceder al alias tuve que crear una funcion get_alias\nperson_one.set_alias(\"JuserDev\")\nprint(person_one.get_name())\nprint(person_one.get_alias())\n\n\n### DIFICULTAD EXTRA ###\n\n'''\n  ->  declaro una clase Stack\n  ->  creo una funcion add para agregar contendio a stack\n  ->  creo una funcion count para contar los elementos dentro de stack\n  ->  creo una funcion delete con un condicional donde dice que si stack es igual a o retorna una resputa informando que el stack esta vacio\n      de lo contrario elimina el ultimo elemento y muestra el elemento eliminado\n  ->  cfeo una fucion printElement que recorre la lista e imprime el contenido\n\n  ->  en Queue la diferencia es que el primer elemento en ingresar es el primer elemento en salir\n'''\n\nclass Stack:\n  def __init__(self): # de esta manera lo inicializamos vacio\n    self.stack = []\n  \n  def add(self, item: int):\n    self.stack.append(item)\n    return f\"Item agregado correctamente --> {item}\"\n\n  def count(self):\n    return len(self.stack)\n\n  def delete(self):\n    if self.count() == 0:\n      return \"No hay elemento que eliminar\"\n    else:\n      item = self.stack.pop()\n      return f\"Elemento elminado correctamente --> {item}\"\n  \n  def printElements(self):\n    for item in self.stack:\n      print(item)\n    \nnumber = Stack()\n\nprint(number.add(1))\nprint(number.add(2))\nprint(number.add(3))\nprint(number.add(4))\n\nnumber.printElements() # aqui imprime todos los elementos uno despues de otro\nprint(number.stack) # aqui imprime todos los elemento en una lista\nprint(number.count()) # aqui cuenta todos los elementos\nprint(number.delete())\nprint(number.count()) # aqui elimina el ultimo elemento agregado\n\n# QUEUE\n\nclass Queue:\n  def __init__(self): # de esta manera lo inicializamos vacio\n    self.queue = []\n  \n  def add(self, item: int):\n    self.queue.append(item)\n    return f\"Item agregado correctamente --> {item}\"\n\n  def count(self):\n    return len(self.queue)\n\n  def delete(self):\n    if self.count() == 0:\n      return \"No hay elemento que eliminar\"\n    else:\n      item = self.queue.pop(0)\n      return f\"Elemento elminado correctamente --> {item}\"\n  \n  def printElements(self):\n    for item in self.queue:\n      print(item)\n\nqueue = Queue()\n\nprint(queue.add(1))\nprint(queue.add(2))\nprint(queue.add(3))\nprint(queue.add(4))\n\nqueue.printElements()\nprint(queue.count())\nprint(queue.delete())\nqueue.printElements()\nprint(queue.count())"
  },
  {
    "path": "Roadmap/08 - CLASES/python/k-90.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n * \n */\n\"\"\"\n\nclass Operario_Quimico():\n\n    def __init__(self, name:str, work:list, age:int):\n        self.name = name\n        self.work = work\n        self.age = age\n    \n    def print(self):\n        return print(\n            f\"Nombre {self.name}| Puesto de trabajo {self.work}| Edad {self.age}\")\n    \n\n\noperario_1 = Operario_Quimico(\"Antonio\",[\"Thermos,Slitter\"], 48)\noperario_1.print()\nprint(type(operario_1))\n\n\n\"\"\"\nExtra\n\"\"\"\n\nclass stack():\n    def __init__(self):\n        self.stack = []\n\n    def añadir(self, item:int):\n        self.stack.append(item)\n    \n    def eliminar(self):\n        if self.contar() == 0:\n            return None\n        self.stack.pop()\n\n    def contar(self):\n        return len(self.stack)\n    \n    def imprimir(self):\n        for item in reversed(self.stack):\n            print(item)\n\nmi_pila = stack()\nmi_pila.añadir(5)\nmi_pila.añadir(4)\nmi_pila.añadir(3)\nmi_pila.añadir(2)\nmi_pila.añadir(1)\nprint(mi_pila.contar())\nmi_pila.imprimir()\nmi_pila.eliminar()\n\n\nclass queue():\n    def __init__(self):\n        self.queue = []\n\n    def encolar(self, item:int):\n        self.queue.append(item)\n    \n    def desencolar(self):\n        if self.contar() == 0:\n            return None\n        self.queue.pop()\n\n    def contar(self):\n        return len(self.queue)\n    \n    def imprimir(self):\n        for item in self.queue:\n            print(item)\n\nmi_cola = queue()\nmi_cola.encolar(1)\nmi_cola.encolar(2)\nmi_cola.encolar(3)\nmi_cola.encolar(4)\nmi_cola.encolar(5)\nprint(mi_cola.contar())\nmi_cola.imprimir()\nmi_cola.desencolar()\nprint(mi_cola.desencolar())\nprint(mi_cola.contar())\nprint(mi_cola.desencolar())"
  },
  {
    "path": "Roadmap/08 - CLASES/python/kenysdev.py",
    "content": "# ╔══════════════════════════════════════╗\n# ║ Autor:  Kenys Alvarado               ║\n# ║ GitHub: https://github.com/Kenysdev  ║\n# ║ 2024 -  Python                       ║\n# ╚══════════════════════════════════════╝\n\n# ----------------------------------------\n# Concepto de clases:\n# ----------------------------------------\n# Las clases proporcionan una forma de organizar y estructurar\n# el código de manera más modular y reutilizable.\n#_________________________________________\nclass Employee:\n    # Atributos de clase (compartidos por todas las instancias)\n    base_salary = 25000\n    vacation_days = 15\n\n    # Constructor con argumentos (instanciación)\n    def __init__(self, name, hire_date):\n        self.name = name\n        self.hire_date = hire_date\n\n    # Métodos de instancia\n    def edit(self, name, hire_date):\n        self.name = name\n        self.hire_date = hire_date\n\n    def println(self):\n        print(f\"Name: {self.name} - Hire date: {self.hire_date}\")\n\n# Crear objeto\nemployee_instance = Employee(\"Ben\", \"2024-02-01\")\n\n# Acceder a los atributos\nprint(f\"\"\"\nName:          {employee_instance.name}\nHire date:     {employee_instance.hire_date}\nBase salary:   {employee_instance.base_salary}\nVacation days: {employee_instance.vacation_days}\n\"\"\")\n\n# Utilizar metodos.\nemployee_instance.edit(\"Ben edit\", \"2024-03-01\")\nemployee_instance.println()\n\n# ----------------------------------------\n# Ejercicio:\n# ----------------------------------------\n\"\"\"\n* Implementa dos clases que representen las estructuras de Pila y Cola \n* (estudiadas en el ejercicio número 7 de la ruta de estudio)\n* Deben poder inicializarse y disponer de operaciones para añadir, \n* eliminar, retornar el número de elementos e imprimir todo su contenido.\n\"\"\"\n#_________________________________________\n# Pilas(stack - LIFO):\nclass Stack:\n    def __init__(self):\n        self.elements = []\n    \n    def __len__(self): # total elementos.\n        return len(self.elements)\n\n    def is_empty(self): # es vacia.\n        return len(self) == 0\n    \n    def push(self, item): # Agregar elemento.\n        self.elements.append(item)\n    \n    def push_batch(self, items): # Agregar multiples.\n        # use <history.push_batch([\"1\", \"2\", \"3\"])\">\n        self.elements.extend(items)\n    \n    def pop_get(self): # Eliminar y obtener.\n        if not self.is_empty():\n            return self.elements.pop()\n        else: \n            return None\n    \n    def get_top(self): # Obtener sin eliminar.\n        if not self.is_empty():\n            return self.elements[-1]\n        else: \n            return None\n    \n    def get_tuple(self): # retornar pila como tupla.\n        return tuple(reversed(self.elements))\n    \n    def clear(self): # vaciar pila.\n        self.elements.clear()\n\n#_________________________________________\n# Colas (Queue - FIFO):\nfrom collections import deque\nclass Queue:\n    def __init__(self):\n        self.elements = deque()\n\n    def __len__(self): # total elementos.\n        return len(self.elements)\n\n    def is_empty(self): # es vacia.\n        return len(self) == 0\n    \n    def enqueue(self, item): # agregar\n        self.elements.append(item)\n\n    def enqueue_all(self, items): # Agregar multiples.\n        self.elements.extend(items)\n\n    def dequeue(self): # Eliminar y devolver\n        if not self.is_empty():\n            return self.elements.popleft()\n        else:\n            return None\n    \n    def peek(self): # Obtener sin eliminar.\n        if not self.is_empty():\n            return self.elements[-1]\n        else: \n            return None\n    \n    def get_tuple(self): # retornar cola como tupla.\n        return tuple(self.elements)\n\n    def clear(self): # vaciar cola.\n        self.elements.clear()\n\n#_________________________________________\nprint(\"Uso de pila:\")\nmystack = Stack()\nmystack.push(\"Zoe\")\nmystack.push_batch([\"Ben\", \"Dan\"])\nif not mystack.is_empty():\n    print(mystack.pop_get())\nprint(f\"número de elementos: {len(mystack)}\")\nfor name in mystack.get_tuple():\n    print(name)\n\n#_________________________________________\nprint(\"Uso de Cola:\")\nmyqueue = Queue()\nmyqueue.enqueue(\"Zoe\")\nmyqueue.enqueue_all([\"Ben\", \"Dan\"])\nif not myqueue.is_empty():\n    print(myqueue.dequeue())\nprint(f\"número de elementos: {len(myqueue)}\")\nfor name in myqueue.get_tuple():\n    print(name)\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/kuroz00.py",
    "content": "\"\"\"\nEJERCICIO:\n*Explora el concepto de clase y crea un ejemplo que implemente un \ninicializador,\n\n*atributos y una funcion que los imprima (teniendo en \ncuenta las posibilidades de tu lenguaje).\n\n*Una vez implementada, creala, establece sus parametros, modificalos e\nimprimelos utilizando una funcion.\n.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-\nDIFICULTAD EXTRA (opcional):\n- Implementa dos clases que representen las estructuras de Pila y \nCola (estudiadas en el ejercicio numero 7 de la ruta de estudio)\n- Deben poer inicializarse y disponer de operaciones para añadir, \neliminar, retornar el número de elementos e imprimir todo su \ncontenido.\n\"\"\"\n\n#creacion del molde de una persona promedio\nclass persona:\n\n    #Datos personales\n    def __init__(self, nombre,edad,direccion,afp,prevision): #se le atribuyen parametros como sus datos personales\n        self.nombre = nombre\n        self.edad = edad\n        self.direccion = direccion\n        self.afp = afp\n        self.prevision = prevision\n        \n        self.red_social = [] #.-.-.- Lista la cual contendra redes sociales sea por nombre o url  .-.-.-\n        self.contador_turno = 5 #Tiene 5 puntos de turno, cada accion le quitara uno y al llegar a 0 termina el turno\n    \n    #Mostrar datos por pantalla\n    def mostrar_info(self):\n        print(f'Nombre:{self.nombre} \\nEdad:{self.edad} \\nDireccion:{self.direccion}')\n        print(f'Afp:{self.afp} \\nprevision:{self.prevision}')\n\n    #Mover al personaje\n    def moverse(self, pasos):\n        self.pasos = pasos\n        if pasos < 0:\n            print('No puede dar pasos negativos')\n        elif pasos == 1:\n            self.contador_turno -= 1\n            print(f'{self.nombre} dio un paso...')\n        else:\n            self.contador_turno -= pasos\n            print(f'{self.nombre} dio {pasos} pasos!')\n\n    #El personaje canta        \n    def cantar (self, cancion, banda):\n        self.cancion = cancion\n        print(f'{self.nombre} esta cantando {cancion} de {banda}! Como mola!')\n\n    #Saltito\n    def saltar(self, salto):\n        self.salto = salto\n        print(f'{self.nombre} ha dado {salto} salto/s ')\n\n#Se crea el objeto (instanciar la clase)    \nusuario = persona('pepito', 24, 'Calle maipu', 'vital', 'Isapre') \nusuario.mostrar_info() #datos personales\n\n#Bucle que se rompe al terminar los turnos (o quedar en negativo)\nwhile 1:\n    if usuario.contador_turno <= 0:\n        print('Fin del turno')\n        break\n\n    print(f'Seleccione su accion:')\n    print(f'mover.-.- \\ncantar.-.- \\nsaltar.-.- \\nfin del turno.-.-.-')\n\n    alternativa = input('->')\n    if alternativa == 'fin del turno':\n        break\n    elif alternativa == 'mover':\n        usuario.moverse(int(input('Cuantos pasos?: ')))\n        print(f'contador de turno: ,.,.{usuario.contador_turno},.,.')\n    elif alternativa == 'cantar':\n        usuario.cantar(input('Cancion:'), input('Banda:'))\n        print(f'contador de turno: ,.,.{usuario.contador_turno},.,.')\n    elif alternativa == 'saltar':\n        usuario.saltar(input('Cuantos saltos? :'))\n        print(f'contador de turno: ,.,.{usuario.contador_turno},.,.')\n\n#Extra\nclass stack:\n    def __init__(self):\n        self.stack = [] #se inicia como una lista vacia\n    \n    def push(self):\n        dato = input('que desea agregar?: ')\n        self.stack.append(dato) #se le agrega un valor \n        \n    def pop(self):\n        return self.stack.pop() #se elimina el ultimo valor agregado\n    \n    def view(self):\n        return self.stack.copy() #retorna una copia\n\nclass queue:\n    def __init__(self):\n        self.queue = [] #se inicia como una lista vacia\n    \n    def push(self):\n        self.stack.append()#incorporar valor a la cola\n        \n    def pop(self):\n        return self.stack.remove(stack[0]) #eliminamos el primero en la cola\n    \n    def view(self):\n        return self.stack.copy() #mostramos una copia"
  },
  {
    "path": "Roadmap/08 - CLASES/python/m1l0j05.py",
    "content": "# Teoria\n\n# Una clase en Python es como un molde que define \n# las características y comportamientos que tendrán \n# los objetos creados a partir de ella. \n# Es una forma de organizar y estructurar el código para crear y \n# manipular objetos de manera consistente.\n\n#Un objeto en Python es una instancia de una clase. \n# Piensa en una clase como un molde y un objeto como una\n# pieza creada a partir de ese molde. Un objeto tiene atributos (datos) \n# y métodos (funciones) que definen su comportamiento. \n# Por ejemplo, si tienes una clase llamada \"Perro\", un objeto de esa \n# clase podría tener atributos como \"nombre\" y \"edad\", y métodos como \"ladrar\" o \"correr\".\n\n# El inicializador en una clase de Python es un método especial llamado __init__()\n# que se ejecuta automáticamente al crear un nuevo objeto de esa clase.\n# Sirve para inicializar los atributos del objeto con los valores que se le pasan como parámetros.\n\n# Los parámetros en el inicializador son variables que se pasan al crear un objeto\n# y se utilizan para asignar valores a los atributos del objeto.\n\n# Los métodos en una clase son funciones que están definidas dentro de la clase\n# y se utilizan para realizar operaciones con los objetos de esa clase.\n# Pueden acceder a los atributos del objeto utilizando la palabra clave self.\n\n\n# Ejercicio\n\n# Definición de la clase Persona\nclass Persona:\n    # Inicializador (__init__) con atributos nombre y edad\n    def __init__(self, nombre, edad):\n        self.nombre = nombre\n        self.edad = edad\n    # Método para imprimir los atributos de la persona\n    def imprimir_info(self):\n        print(\"Nombre:\", self.nombre)\n        print(\"Edad:\", self.edad)\n\n# Creación de un objeto persona1\n# persona1 = Persona(\"Juan\", 30)\n# Impresión de la información de persona1\n# print(\"Información de persona1:\")\n# persona1.imprimir_info()\n# Modificación de los atributos de persona1\n# persona1.nombre = \"María\"\n# persona1.edad = 25\n# Impresión de la información actualizada de persona1\n# print(\"\\nInformación actualizada de persona1:\")\n# persona1.imprimir_info()\n\n\n# Extra_1\nimport sys\nimport time\nimport random\nfrom collections import  deque\n\nclass Navigate():\n    web_history = []\n    back_url = ''\n    forward_url = ''\n    \n    def __init__(self, current_url):\n        self.current_url = current_url\n    \n    def show_history(self):\n        print(f'\\n[i] Informacion. ')\n        print(f'[i] {self.web_history}')\n        print(f'[i] Url_Anterior: {self.back_url}')\n        print(f'[i] Url_Actual: {self.current_url}')\n        print(f'[i] Url_posterior: {self.forward_url}')\n    \n    def back(self):\n        if not self.back_url:\n            print(f'[i] No existe una URL anterior')\n        else:\n            self.forward_url = self.current_url\n            self.current_url= self.back_url\n            if len(self.web_history) > 0:\n                self.back_url = self.web_history.pop()\n            else:\n                self.back_url = \"\"\n    \n    def forward(self):\n        if not self.forward_url:\n            print(f'[i] Se encuentra en el final')\n        else:\n            if self.back_url:\n                self.web_history.append(self.back_url)\n        \n            self.back_url = self.current_url\n            self.current_url = self.forward_url\n            self.forward_url=''\n\n    def navigate(self, new_url):\n        if  new_url != '':\n            if self.back_url:\n                self.web_history.append(self.back_url)\n            self.back_url = self.current_url\n            self.current_url = new_url\n            print(f'[+] Navegando a ---> {self.current_url}')  \n        else:\n            print(f'[+] Ingrese una url.')  \n\n    def exit(self):\n        return sys.exit(0)\n\ndef navegando():\n    my_session = Navigate(current_url='google')\n    while True:\n        my_session.show_history()\n        user_intput = input(\"\\n[+] Ingrese 'adelante', 'atras' o la URL de una nueva página para navergar.\\n[+] Use 'salir' para cerrar.\\n\")\n        \n        if user_intput.lower() == \"adelante\":\n            my_session.forward()\n        elif user_intput.lower() == \"atras\":\n            my_session.back()\n        elif user_intput.lower() == \"exit\":\n            my_session.exit()\n        else:\n            my_session.navigate(user_intput)\n\n# Extra_2\n\nclass Printer():\n    print_queue = deque()\n\n    def __init__(self, document):\n        self.document = document\n    \n    def add_doc(self, new_doc):\n        self.print_queue.append(self.document)\n        self.document = new_doc\n        print(f'\\n[i] Añadido documento {new_doc} a la cola de impresión')\n        print(f'[i] Archivos en cola: {len(self.print_queue)}\\n\\n') \n    \n    def print_doc(self):\n        try:\n            print(f'[i] Imprimiendo {self.print_queue.popleft()}...')\n        except IndexError:\n            print('[i] No hay documentos en la cola para imprimir')\n\n\ndef printer():\n    cont = 0\n    printing = False\n    my_printer = Printer(document='doc.txt')\n\n    while True:\n        if not printing:\n            new_doc = f'{cont}.txt'\n            my_printer.add_doc(new_doc)\n            time.sleep(0.5)\n\n            if len(my_printer.print_queue) > 3:\n                printing = True\n            else:\n                num = random.randint(1, 5)\n                if num % 2 != 0:\n                    printing = True\n            cont += 1\n        \n        else:\n            my_printer.print_doc()\n            printing = False\n\n\n\n# navegando()\n# printer()\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/majinka10.py",
    "content": "class Mascota:\n    def __init__(self, edad, nombre) -> None:\n        self.edad = edad\n        self.nombre = nombre\n    \n    def printData(self):\n        print(f\"Soy {self.nombre} y tengo {self.edad} años.\")\n    \n    def modifyData(self, new_edad, new_nombre):\n        self.edad = new_edad\n        self.nombre = new_nombre\n\ngato = Mascota(4, 'Mishi')\ngato.printData()\ngato.modifyData(6, 'Tom')\ngato.printData()\n\n# Ejercicio EXTRA\nprint(\"\\nColas y Pilas con Clases\\n\")\n\nclass Cola:\n    def __init__(self) -> None:\n        self.array = []\n    \n    def addElement(self, element):\n            self.array.append(element)\n\n    def delElement(self):\n        try:\n            element = self.array.pop(0)\n            return element\n        except IndexError:\n            return \"La cola está vacía.\"\n\n    def lenght(self):\n        return len(self.array)\n    \n    def printContent(self):\n        print(self.array)\n\nprint(\"Ejercicio con las Colas\\n\")\ncola = Cola()\ncola.addElement(2)\ncola.printContent()\ncola.addElement(3)\ncola.printContent()\nprint(f\"El tamaño de la cola es: {cola.lenght()}\")\nprint(f\"Elemento eliminado: {cola.delElement()}\")\ncola.printContent()\n\nclass Pila:\n    def __init__(self) -> None:\n        self.array = []\n    \n    def addElement(self, element):\n            self.array.append(element)\n\n    def delElement(self):\n        try:\n            element = self.array.pop(-1)\n            return element\n        except IndexError:\n            return \"La pila está vacía.\"\n\n    def lenght(self):\n        return len(self.array)\n    \n    def printContent(self):\n        print(self.array)\n\nprint(\"\\nEjercicio con las Pilas\\n\")\npila = Pila()\npila.addElement(2)\npila.printContent()\npila.addElement(3)\npila.printContent()\nprint(f\"El tamaño de la pila es: {pila.lenght()}\")\nprint(f\"Elemento eliminado: {pila.delElement()}\")\npila.printContent()    \nprint(f\"Elemento eliminado: {pila.delElement()}\")\nprint(f\"{pila.delElement()}\")"
  },
  {
    "path": "Roadmap/08 - CLASES/python/manjaitan.py",
    "content": "class coche:\n\n    def __init__(self, marca, modelo, color) -> None:\n        self.marca = marca\n        self.modelo = modelo\n        self.color = color\n\n    def imprimir (self):\n        print (\n            f\"Marca: {self.marca} | Modelo: {self.modelo} | Color: {self.color}\")\n\n\n\ncoche1 = coche(\"Ford\" , \"Escort\" , \"Rojo\")\ncoche1.imprimir()\n# modifico el parametro color\ncoche1.color = \"Verde\"\ncoche1.imprimir()\n\n\n#### EXTRA ####\n\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/mariovelascodev.py",
    "content": "#Creación de una clase\nclass Person:\n    def __init__(self, name, surname, age, email):\n        self.name = name\n        self.surname = surname\n        self.age = age\n        self.email = email\n    def information(self):\n        print(f\"Nombre: {self.name}\")\n        print(f\"Apellidos: {self.surname}\")\n        print(f\"Edad: {self.age}\")\n        print(f\"Email: {self.email}\")\n\n#Instanciamos la clase y le añadimos los parámetros y mostramos la información\npersona_1 = Person(\"Mario\", \"Velasco\", 34, \"mario@mario.com\")\npersona_1.information()\n\n#Modificamos algún atributo\npersona_1.email = \"correo@nocorreo.com\"\nprint(f\"El correo a sido cambiado a: {persona_1.email}\")\n\n\n#EXTRA\n\nclass Pila:\n    def __init__(self):\n        self.pila = []\n    def agregar(self, param):\n        self.pila.append(param)\n    def eliminar(self):\n        return f\"Se ha eliminado: {self.pila.pop()}\"\n    def numero_elementos(self):\n        return f\"El número de elementos de la pila es: {len(self.pila)}\"\n    def contenido(self):\n        return f\"El contenido de la pila es: {self.pila}\"\n\nprint(\"\\nClase Pila\")        \npila = Pila()\npila.agregar(34)\npila.agregar(2)\npila.agregar(200)\npila.agregar(98)\nprint(pila.contenido())\nprint(pila.numero_elementos())\nprint(pila.eliminar())\nprint(pila.contenido())\nprint(pila.numero_elementos())\n\nclass Cola:\n    def __init__(self):\n        self.cola = []\n    def agregar(self, param):\n        self.cola.append(param)\n    def eliminar(self):\n        return f\"Se ha eliminado: {self.cola.pop(0)}\"\n    def numero_elementos(self):\n        return f\"El número de elementos de la cola es: {len(self.cola)}\"\n    def contenido(self):\n        return f\"El contenido de la cola es: {self.cola}\"\n\nprint(\"\\nClase Cola\")    \ncola = Cola()\ncola.agregar(34)\ncola.agregar(2)\ncola.agregar(200)\ncola.agregar(98)\nprint(cola.contenido())\nprint(cola.numero_elementos())\nprint(cola.eliminar())\nprint(cola.contenido())\nprint(cola.numero_elementos())"
  },
  {
    "path": "Roadmap/08 - CLASES/python/mensius87.py",
    "content": "\"\"\"\n* EJERCICIO:\n* Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n* atributos y una función que los imprima (teniendo en cuenta las posibilidades\n* de tu lenguaje).\n* Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n* utilizando su función.\n*\n* DIFICULTAD EXTRA (opcional):\n* Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n* en el ejercicio número 7 de la ruta de estudio)\n* - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n*   retornar el número de elementos e imprimir su contenido al completo.\n*\n\"\"\"\n\n\nclass Persona:\n    def __init__(self, nombre, edad):\n        self.nombre = nombre\n        self.edad = edad\n\n    def imprimir_informacion(self):\n        print(\"Nombre:\", self.nombre)\n        print(\"Edad:\", self.edad)\n\n\n# Crear una instancia de la clase Persona\npersona1 = Persona(\"Juan\", 30)\n\n# Imprimir la información utilizando el método de la clase\npersona1.imprimir_informacion()\n\n# Modificar los atributos y volver a imprimir la información\npersona1.nombre = \"María\"\npersona1.edad = 25\npersona1.imprimir_informacion()\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/mhayhem.py",
    "content": "# @Author mhayhem\n\n# EJERCICIO:\n# Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n# atributos y una función que los imprima (teniendo en cuenta las posibilidades\n# de tu lenguaje).\n# Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n# utilizando su función.\n\nclass Car:\n    def __init__(self, brand, model, fuel, hp):\n        self.brand = str(brand)\n        self.model = str(model)\n        self.fuel = str(fuel)\n        self.hp = int(hp)\n\n    def display_car(self):\n        print(f\"Marca {self.brand}, modelo {self.model}, tipo de combustible {self.fuel} y potencia {self.hp} cv\")\n    \nmy_car = Car(\"SEAT\", \"Leon\", \"Gasolina\", 150)\nmy_car.display_car()\nmy_car.hp = 180\nmy_car.display_car()\nmy_car.model = \"Ibiza\"\nmy_car.display_car()\n\n# DIFICULTAD EXTRA (opcional):\n# Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n# en el ejercicio número 7 de la ruta de estudio)\n# - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n#   retornar el número de elementos e imprimir todo su contenido.\n\n\n# Stack\n\nclass Stack:\n    def __init__(self):\n        # inicializamos la clase\n        self.stack = []\n        \n    def push(self, item):\n        # añadimos elemento al stack\n        self.stack.append(item)\n    def pop(self):\n        # comprobamos que la pila no este vacía antes de desapilar\n        try:\n            item_pop = self.stack.pop()\n            return item_pop\n        # si esta vacía capturamos el error de índice\n        except IndexError:\n            return \"Pila Vacía\"\n    def show(self):\n        # retornamos copia\n        return self.stack[:]\n    def length(self):\n        # retornamos la longitud\n        return len(self.stack)\n    \n\nbooks = Stack()\nbooks.push(\"LOTR\")\nbooks.push(\"Harry potter\")\nbooks.push(\"Discworld\")\nbooks.push(\"Dark Elf\")\nprint(books.show())\nprint(books.pop())\nprint(books.length())\nprint(books.pop())\nprint(books.length())\nprint(books.show())\n\n# Queue\n        \nclass Queue:\n    def __init__(self):\n        # inicializamos la clase\n        self.queue = []\n        \n    def enqueue(self, item):\n        # añadimos elemento\n        self.queue.append(item)\n    def dequeue(self):\n        # antes de dequeue comprobamos que no este vacía \n        try:\n            item_dequeue = self.queue.pop(0)\n            return item_dequeue\n        # capturamos el error de índice\n        except IndexError:\n            return \"Cola vacía\"\n    def show(self):\n        # retornamos copia de la cola\n        return self.queue[:]\n    def length(self):\n        # retornamos la longitud\n        return len(self.queue)\n    \neshop = Queue()\neshop.enqueue(\"Recepción del pedido\")\neshop.enqueue(\"Preparación del pedido\")\neshop.enqueue(\"Envio del pedido\")\nprint(eshop.show())\nprint(eshop.dequeue())\nprint(eshop.length())\nprint(eshop.dequeue())\nprint(eshop.show())\nprint(eshop.dequeue())\nprint(eshop.show())\nprint(eshop.length())"
  },
  {
    "path": "Roadmap/08 - CLASES/python/miguelex.py",
    "content": "class Vehiculo:\n    def __init__(self, nombre, numRuedas):\n        self.nombre = nombre\n        self.numRuedas = numRuedas\n    \n    def toString(self):\n        return f'Nombre: {self.nombre}, Ruedas: {self.numRuedas}'\n    \n\ncoche = Vehiculo('Coche', 4)\nprint(coche.toString())\n\nbicicleta = Vehiculo('Bicicleta', 2)\nprint(bicicleta.toString())\n\n# Extra\n\nclass Stack:\n    def __init__(self):\n        self.stack = []\n    \n    def push(self, item):\n        self.stack.append(item)\n    \n    def pop(self):\n        return self.stack.pop()\n    \n    def peek(self):\n        return self.stack[-1]\n    \n    def size(self):\n        return len(self.stack)\n    \n    def isEmpty(self):\n        return self.stack == []\n    \n    def __str__(self):\n        return str(self.stack)\n\nprint(\"Ejemplo de uso de pila\")\nmiPila = Stack()\nmiPila.push(1)\nmiPila.push(2)\nmiPila.push(3)\nprint(\"Estado de la pila actual:\")\nprint(miPila)\nprint(\"Saco el elemento en la cima, que es: \")\nprint(miPila.pop())\nprint(\"La cima actual es: \")\nprint(miPila.peek())\nprint(\"Esta vacia la pila?\")\nprint(miPila.isEmpty())\nprint(\"Saco el elemento en la cima, que es: \")\nprint(miPila.pop())\nprint(\"Estado de la pila actual:\")\nprint(miPila)\n\nclass Queue:\n    def __init__(self):\n        self.queue = []\n        \n    def enQueue(self, item):\n        self.queue.append(item)\n        \n    def deQueue(self):\n        return self.queue.pop(0)\n    \n    def size(self):\n        return len(self.queue)\n    \n    def isEmpty(self):\n        return self.queue == []\n    \n    def __str__(self):\n        return str(self.queue)\n    \nprint(\"Ejemplo de uso de cola\")\nmiCola = Queue()\nmiCola.enQueue(1)\nmiCola.enQueue(2)\nmiCola.enQueue(3)\nprint(\"Estado de la cola actual:\")\nprint(miCola)\nprint(\"Saco el elemento en la cabeza, que es: \")\nprint(miCola.deQueue())\nprint(\"Estado de la cola actual:\")\nprint(miCola)\nprint(\"Esta vacia la cola?\")\nprint(miCola.isEmpty())\nprint(\"Saco el elemento en la cabeza, que es: \")\nprint(miCola.deQueue())\nprint(\"Estado de la cola actual:\")\nprint(miCola)\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/mikelm2020.py",
    "content": "# Clases\nclass Store:\n    def __init__(self, name):\n        self.name = name\n        self.items = []\n\n    def add_item(self, name, price):\n        self.items.append({\"name\": name, \"price\": price})\n\n    def stock_price(self):\n        total = 0\n        for item in self.items:\n            total += item[\"price\"]\n        return total\n\n\n# Extra\nclass Stack:\n    def __init__(self):\n        # Crea una pila vacía\n        self.items = []\n\n    def introduce(self, element):\n        # Agrega el elemento element a la pila\n        self.items.append(element)\n\n    def recover(self):\n        # Devuelve el elemento tope y lo elimina\n        # Si la pila está vacía levanta una excepción\n        try:\n            return self.items.pop()\n        except IndexError:\n            raise ValueError(\"La pila está vacía\")\n\n    def is_empty(self):\n        # Devuelve True si la pila esta vacía\n        return self.items == []\n\n    def size(self):\n        return len(self.items)\n\n    def content(self):\n        return print(self.items)\n\n\nclass Queue:\n    def __init__(self):\n        # Crea una cola vacía\n        self.items = []\n\n    def introduce(self, element):\n        # Agrega el elemento element a la cola\n        self.items.append(element)\n\n    def recover(self):\n        # Devuelve el primer elemento y lo elimina\n        # Si la cola está vacía levanta una excepción\n        try:\n            return self.items.pop(0)\n        except IndexError:\n            raise ValueError(\"La cola está vacía\")\n\n    def is_empty(self):\n        # Devuelve True si la cola esta vacía\n        return self.items == []\n\n    def size(self):\n        return len(self.items)\n\n    def content(self):\n        return print(self.items)\n\n\nif __name__ == \"__main__\":\n    store = Store(\"Test\")\n    store2 = Store(\"Amazon\")\n    store2.add_item(\"Keyboard\", 100)\n\n    stack = Stack()\n    for number in range(1, 10):\n        stack.introduce(number)\n    stack.recover()\n    stack.content()\n    print(f\"El tamaño de la pila es:  {stack.size()}\")\n\n    queue = Queue()\n    for number in range(1, 10):\n        queue.introduce(number)\n    queue.recover()\n    queue.content()\n    print(f\"El tamaño de la cola es:  {queue.size()}\")\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/monicavaquerano.py",
    "content": "# 08 CLASES\n# Monica Vaquerano\n# https://monicavaquerano.dev\n\n\"\"\"\nEjercicio:\n\nExplora el concepto de clase y crea un ejemplo que implemente un inicializador,\natributos y una función que los imprima (teniendo en cuenta las posibilidades\nde tu lenguaje).\n\nUna vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\nutilizando su función. \n\"\"\"\n\n\n# Clases (Classes)\n#  En Python, una clase es una plantilla para crear objetos que comparten atributos y métodos comunes. Los objetos son instancias de una clase.\nclass Auto:\n    # Inicializador (__init__)\n    def __init__(self, marca, modelo, ano):\n        self.marca = marca\n        self.modelo = modelo\n        self.ano = ano\n\n    # Método para imprimir los atributos\n    def imprimir_informacion(self):\n        print(\n            f\"--- Auto ---\\nMarca: {self.marca}\\nModelo: {self.modelo}\\nAño: {self.ano}\"\n        )\n\n    # La función __str__(): esta controla lo que debe ser retornado cuando el objeto de clase se representa como una string.\n    def __str__(self):\n        return f\"{self.marca}, {self.modelo} ({self.ano})\"\n\n\nprint(\"08 CLASES\\n\")\n# Crear una instancia de la clase Persona\nprint(\"* Instanciando:\\n\")\nprint('auto1 = Auto(\"Toyota\", \"Yaris\", 2024)\\n')\nauto1 = Auto(\"Toyota\", \"Yaris\", 2024)\n# Llamar al método para imprimir los atributos\nprint(\"* Llamado al método:\\nauto1.imprimir_informacion()\\n\")\nauto1.imprimir_informacion()\n# Llamar al método __str__()\nprint(\"\\n* Usando el método __str__():\\n\")\nprint(auto1)\n# Modificando los valores o atributos del objeto\nprint(\"\\n* Modificando sus atributos:\\n\")\nprint('auto1.marca = \"Volkswagen\"\\nauto1.modelo = \"T-Roc\"')\nauto1.marca = \"Volkswagen\"\nauto1.modelo = \"T-Roc\"\n# Llamar nuevamente al método para imprimir los atributos\nprint(\"\\n* Llamado nuevamente al método:\\nauto1.imprimir_informacion()\\n\")\nauto1.imprimir_informacion()\n# Llamar nuevamente al método __str__()\nprint(\"\\n* Usando nuevamente el método __str__():\\n\")\nprint(auto1)\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\nImplementa dos clases que representen las estructuras de Pila y Cola (estudiadas\nen el ejercicio número 7 de la ruta de estudio)\n\n- Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n  retornar el número de elementos e imprimir todo su contenido.\n\"\"\"\nprint(\"\\nDIFICULTAD EXTRA (opcional):\\n\")\n\n\n# Pilas (Stacks):\n# Una pila es una estructura de datos en la que el último elemento añadido es el primero en ser eliminado (LIFO - Last In, First Out).\nclass Stack:\n    def __init__(self):\n        self.stack = []\n\n    def addIn(self, item):\n        self.stack.append(item)\n\n    def popOut(self):\n        popped = self.stack.pop()\n        return popped\n\n    def __str__(self):\n        return str(self.stack)\n\n    def ver_stack(self):\n        print(\n            f\"--- Estado Stack ---\\nStack actual: {self.stack}\\nSiguiente elemento a salir: {self.stack[-1]}\"\n        )\n\n\nprint(\"* Pilas (Stacks)\")\n# Instanciar Stack\nstack1 = Stack()\n# Usar método add()\nstack1.addIn(1)\nstack1.addIn(2)\nstack1.addIn(3)\nstack1.addIn(4)\n# Usando método ver_stack()\nstack1.ver_stack()\n# Usar método popOut()\npopped = stack1.popOut()\nprint(\"Elemento sacado =>\", popped)\n# Usando método __str__()\nprint(\"Stack después del pop:\", stack1)\n\n\nclass Queue:\n    def __init__(self):\n        self.queue = []\n\n    def addIn(self, item):\n        self.queue.append(item)\n\n    def popOut(self):\n        popped = self.queue.pop(0)\n        return popped\n\n    def __str__(self):\n        return str(self.queue)\n\n    def ver_queue(self):\n        print(\n            f\"--- Estado Queue ---\\nQueue actual: {self.queue}\\nSiguiente elemento a salir: {self.queue[0]}\"\n        )\n\n\nprint(\"\\n* Colas (Queues)\")\n# Instanciar Queue\nqueue1 = Queue()\n# Usar método add()\nqueue1.addIn(1)\nqueue1.addIn(2)\nqueue1.addIn(3)\nqueue1.addIn(4)\n# Usando método ver_queue()\nqueue1.ver_queue()\n# Usar método popOut()\npopped = queue1.popOut()\nprint(\"Elemento sacado =>\", popped)\n# Usando método __str__()\nprint(\"Queue después del pop:\", queue1)\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/mordevspt.py",
    "content": "\"\"\"\nExplora el concepto de clase y crea un ejemplo que implemente un inicializador,\natributos y una función que los imprima (teniendo en cuenta las posibilidades\nde tu lenguaje).\n\nUna vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\nutilizando su función.\n\"\"\"\n\n# Clase única\nclass Alumno:\n    # Inicializador - Constructor\n    def __init__(self,nombre, curso):\n        self.nombre = nombre\n        self.clase = curso\n    # Método para saludar a otro alumno por su nombre\n    def saludar(self,nombre):\n        print(f\"Hola {nombre}\")\n    # Método donde nos identifica y muestra nuestro nombre como alumno\n    def quienSoy(self):\n        print(f\"Soy {self.nombre}\")\n        \n# Instanciación        \nalumno1 = Alumno(\"Juan\",\"Primaria\")\nprint(f\"Se ha instanciado un alumno con nombre {alumno1.nombre} en la clase de {alumno1.clase}.\")\n\nalumno2 = Alumno(\"Pablo\",\"Secundaria\")\nprint(f\"Se ha instanciado un alumno con nombre {alumno2.nombre} en la clase de {alumno2.clase}.\")\n\n# Uso de sus métodos\nalumno1.saludar(alumno2.nombre)\nalumno1.quienSoy()\nalumno2.saludar(alumno1.nombre)\n\n# Clase con Herencia\nclass Area:\n    # Método iniciador común para el cálculo de área\n    def __init__(self,b,h):\n        self.b = b\n        self.h = h\n# Cada tipo de polígono tiene una forma diferente de calcular su área\nclass Rectangulo(Area):\n    # Cálculo de área concreto de un rectángulo\n    def calcularArea(self):\n        return self.b * self.h\n    \nclass Triangulo(Area):\n    # Cálculo de área concreto de un triángulo\n    def calcularArea(self):\n        return (self.b * self.h) / 2\n\n# Instanciación\nrectangulo = Rectangulo(30,80)\nprint(f\"Se ha instanciado un Rectángulo de 30 de base * 80 de altura\")\ntriangulo = Triangulo(75,90)\nprint(f\"Se ha instanciado un Triángulo de 75 de base * 90 de altura\")\n\n# Uso de sus métodos\nprint(f\"El área del rectángulo es de: {rectangulo.calcularArea()}\")\nprint(f\"El área del triángulo es de: {triangulo.calcularArea()}\")\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\nImplementa dos clases que representen las estructuras de Pila y Cola (estudiadas\nen el ejercicio número 7 de la ruta de estudio)\n- Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n  retornar el número de elementos e imprimir todo su contenido.\n\"\"\"\n\n# EJERCICIO 1 - REESCRITO\n# LIFO\nprint(\"\\nEJERCICIO 1 - REESCRITO\\n\")\n\nclass navegacionWeb():\n    # INICIALIZADOR\n    def __init__(self):\n       self.mi_stack = [] # Iniciamos la pila\n    # METODOS\n    # Añadir elemento\n    def nuevoElemento(self,respuesta):\n        self.mi_stack.append(respuesta)\n    # Eliminar elemento\n    def eliminarElemento(self):\n        self.mi_stack.pop()\n    # Imprimir elementos\n    def imprimirElementos(self):\n        # Recorrido a la reversa\n        for elemento in reversed(self.mi_stack):\n            print(elemento)\n    # Cantidad elementos\n    def cantidadElementos(self):\n        return len(self.mi_stack)\n    # Pregunta inicial\n    def preguntarAlUsuario(self):\n        return input(\"Escribe una página, navega hacia adelante, atras, imprimir o salir: \")\n    # Navegación\n    def showWebSiteUser(self):\n        print(f\"Navegando por la web: {self.mi_stack[len(self.mi_stack)-1]}\")\n        \n# Programa Inicial\ndef navegacion():\n    # Instanciamos un objeto\n    browser = navegacionWeb()\n    respuesta = browser.preguntarAlUsuario()\n    while True:\n        match respuesta:\n            case \"atras\":\n                if browser.cantidadElementos() >= 1:\n                    # Eliminamos el último registro\n                    browser.eliminarElemento()\n                # Para no provocar un problema en caso de no quedar elementos en la pila\n                if (browser.cantidadElementos() > 0):\n                    browser.showWebSiteUser()\n                else:\n                    print(\"Ha llegado al principio\")\n                # Pase lo que pase\n                respuesta = browser.preguntarAlUsuario()\n            case \"adelante\":\n                print(\"No es posible\")\n                respuesta = browser.preguntarAlUsuario()\n            case \"salir\":\n                print(\"\\n¡HASTA LUEGO!\\n\")\n                break\n            case \"imprimir\":\n                if browser.cantidadElementos() >= 1:\n                    print(\"\\nELEMENTOS DE LA PILA\\n\")\n                    print(f\"Hay {browser.cantidadElementos()} elementos en la pila, los elementos son:\\n\")\n                    browser.imprimirElementos()\n                else:\n                    print(\"No hay elementos en la pila\")\n                respuesta = browser.preguntarAlUsuario()\n            case _:\n                if len(respuesta) >= 1:\n                    browser.nuevoElemento(respuesta)\n                    browser.showWebSiteUser()\n                # Pase lo que pase\n                respuesta = browser.preguntarAlUsuario()\n\n# Ejecución programa 1\nnavegacion()\n\n# EJERCICIO 1 - CLASE STACK\n# LIFO\nprint(\"\\nEJERCICIO 1 - CLASE STACK\\n\")\n\nclass stack:\n    # INICIALIZADOR\n    def __init__(self):\n       self.mi_stack = [] # Iniciamos la pila\n    # METODOS\n    # Añadir elemento\n    def push(self,item):\n        self.mi_stack.append(item)\n    # Eliminar elemento\n    def pop(self):\n        if self.count() >= 1:\n            self.mi_stack.pop()\n    # Contar elementos\n    def count(self):\n        return len(self.mi_stack)\n    # IMprimir elementos\n    def print(self):\n        for item in reversed(self.mi_stack):\n            print(item)\n\n# Ejemplo de uso\nalcalina = stack()\nalcalina.push(\"Duracel\")\nalcalina.push(\"Varta\")\nalcalina.push(\"Panasonic\")\nprint(\"----------\")\nalcalina.print()\nprint(alcalina.count())\nprint(\"----------\")\nalcalina.pop()\nalcalina.pop()\nalcalina.print()\nprint(alcalina.count())\nprint(\"----------\")\n\n# EJERCICIO 2 - REESCRITO\n# FIFO\nprint(\"\\nEJERCICIO 2 - REESCRITO\\n\")\n\nclass poolPrinter:\n    # INICIALIZADOR\n    def __init__(self):\n       self.pool = [] # Iniciamos la pila\n    # METODOS\n    # Añadir elemento\n    def nuevoElemento(self,respuesta):\n        self.pool.append(respuesta)\n        print(f\"Agregamos el documento {respuesta} a la cola de impresión\")\n    # Imprimer elemento y eliminarlo\n    def imprimirElemento(self):\n        print(f\"Imprimimos el documento {self.pool[0]}\")\n        self.pool.pop(0)\n    # Imprimir elementos\n    def imprimirElementos(self):\n        for elemento in self.pool:\n            print(elemento)\n    # Cantidad elementos\n    def cantidadElementos(self):\n        return len(self.pool)\n    # Pregunta inicial\n    def preguntarAlUsuarioPool(self):\n        return input(\"Escribe si deseas imprimir, agregar un nuevo documento, mostrar o salir: \")\n    # Navegación\n    def showWebSiteUser(self):\n        print(f\"Navegando por la web: {self.pool[len(self.pool)-1]}\")\n\n# Programa inicial\ndef printer():\n    # Instanciamos un objeto\n    poolPrinterUser = poolPrinter()\n    respuestaUsuario = poolPrinterUser.preguntarAlUsuarioPool()\n    while True:\n        match respuestaUsuario:\n            case \"imprimir\":\n                # Comprobamos\n                if poolPrinterUser.cantidadElementos() == 0:\n                    print(\"No hay documentos en la cola de impresión, agregue uno antes\")\n                    respuestaUsuario = poolPrinterUser.preguntarAlUsuarioPool()\n                else:\n                    poolPrinterUser.imprimirElemento()\n                    respuestaUsuario = poolPrinterUser.preguntarAlUsuarioPool()\n            case \"salir\":\n                print(\"\\n¡HASTA LUEGO!\\n\")\n                break\n            case \"mostrar\":\n                if poolPrinterUser.cantidadElementos() >= 1:\n                    poolPrinterUser.imprimirElementos()\n                else:\n                  print(\"Escriba el nombre de un documento o si desea imprimir\")\n                # Pase lo que pase\n                respuestaUsuario = poolPrinterUser.preguntarAlUsuarioPool()\n            case _:\n                if len(respuestaUsuario) >= 1:\n                    poolPrinterUser.nuevoElemento(respuestaUsuario)\n                else:\n                  print(\"Escriba el nombre de un documento o si desea imprimir\")\n                # Pase lo que pase\n                respuestaUsuario = poolPrinterUser.preguntarAlUsuarioPool()\n\n# Ejecución programa 2\nprinter()\n\n# EJERCICIO 2 - CLASE QUEUE\n# LIFO\nprint(\"\\nEJERCICIO 2 - CLASE QUEUE\\n\")\n\nclass queue:\n    # INICIALIZADOR\n    def __init__(self):\n       self.mi_queue = [] # Iniciamos la pila\n    # METODOS\n    # Añadir elemento\n    def equeue(self,item):\n        self.mi_queue.append(item)\n    # Eliminar elemento\n    def deequeue(self):\n        if self.count() >= 1:\n            self.mi_queue.pop(0)\n    # Contar elementos\n    def count(self):\n        return len(self.mi_queue)\n    # IMprimir elementos\n    def print(self):\n        for item in self.mi_queue:\n            print(item)\n\n# Ejemplo de uso\ntail = queue()\ntail.equeue(\"Zorro\")\ntail.equeue(\"Lagarto\")\ntail.equeue(\"Puma\")\nprint(\"----------\")\ntail.print()\nprint(tail.count())\nprint(\"----------\")\ntail.deequeue()\ntail.deequeue()\ntail.print()\nprint(tail.count())\nprint(\"----------\")"
  },
  {
    "path": "Roadmap/08 - CLASES/python/mouredev.py",
    "content": "\"\"\"\nEjercicio\n\"\"\"\n\n\nclass Programmer:\n\n    surname: str = None\n\n    def __init__(self, name: str, age: int, languages: list):\n        self.name = name\n        self.age = age\n        self.languages = languages\n\n    def print(self):\n        print(\n            f\"Nombre: {self.name} | Apellidos: {self.surname} | Edad: {self.age} | Lenguajes: {self.languages}\")\n\n\nmy_programmer = Programmer(\"Brais\", 36, [\"Python\", \"Kotlin\", \"Swift\"])\nmy_programmer.print()\nmy_programmer.surname = \"Moure\"\nmy_programmer.print()\nmy_programmer.age = 37\nmy_programmer.print()\n\n\"\"\"\nExtra\n\"\"\"\n\n# LIFO\n\n\nclass Stack:\n\n    def __init__(self):\n        self.stack = []\n\n    def push(self, item):\n        self.stack.append(item)\n\n    def pop(self):\n        if self.count() == 0:\n            return None\n        return self.stack.pop()\n\n    def count(self):\n        return len(self.stack)\n\n    def print(self):\n        for item in reversed(self.stack):\n            print(item)\n\n\nmy_stack = Stack()\nmy_stack.push(\"A\")\nmy_stack.push(\"B\")\nmy_stack.push(\"C\")\nprint(my_stack.count())\nmy_stack.print()\nmy_stack.pop()\nprint(my_stack.count())\nprint(my_stack.pop())\nprint(my_stack.pop())\nprint(my_stack.pop())\nprint(my_stack.pop())\nprint(my_stack.pop())\nprint(my_stack.count())\n\n# FIFO\n\n\nclass Queue:\n\n    def __init__(self):\n        self.queue = []\n\n    def enqueue(self, item):\n        self.queue.append(item)\n\n    def dequeue(self):\n        if self.count() == 0:\n            return None\n        return self.queue.pop(0)\n\n    def count(self):\n        return len(self.queue)\n\n    def print(self):\n        for item in self.queue:\n            print(item)\n\n\nmy_queue = Queue()\nmy_queue.enqueue(\"A\")\nmy_queue.enqueue(\"B\")\nmy_queue.enqueue(\"C\")\nprint(my_queue.count())\nmy_queue.print()\nmy_queue.dequeue()\nprint(my_queue.count())\nprint(my_queue.dequeue())\nprint(my_queue.dequeue())\nprint(my_queue.dequeue())\nprint(my_queue.dequeue())\nprint(my_queue.dequeue())\nprint(my_queue.count())\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/mrodara.py",
    "content": "##########################  POO  ################################\n\n'''\nLlamamos clase a la representación abstracta de un concepto. Por ejemplo, “perro”, “número entero” o “servidor web”.\nLas clases se componen de atributos y métodos.\nUn objeto es cada una de las instancias de una clase.\nLos atributos definen las características propias del objeto y modifican su estado. Son datos asociados a las clases y a los objetos creados a partir de ellas.\nUn atributo de objeto se define dentro de un método y pertenece a un objeto determinado de la clase instanciada.\nLos métodos son bloques de código (o funciones) de una clase que se utilizan para definir el comportamiento de los objetos.\n'''\n\n'''\nMétodo constructor init\n\nLos atributos de objetos no se crean hasta que no hemos ejecutado el método. \nTenemos un método especial, llamado constructor init, que nos permite inicializar los atributos de objetos. \nEste método se llama cada vez que se crea una nueva instancia de la clase (objeto).\n'''\n'''\nEl método constructor, al igual que todos los métodos de cualquier clase, recibe como primer parámetro a la instancia \nsobre la que está trabajando. Por convención a ese primer parámetro se lo suele llamar self \n(que podríamos traducir como yo mismo), pero puede llamarse de cualquier forma.\n\nPara referirse a los atributos de objetos hay que hacerlo a partir del objeto self.\n'''\n\nfrom math import sqrt\n\n# Definición de Clases:\n\nclass Punto():\n    '''\n    Representación de un punto en el plano, los atributos son x e y que representan\n    los valores de sus coordenadas cartesianas\n    '''\n    # Constructor\n    def __init__(self, x: int = 0, y: int = 0) -> None:\n        self.x = x\n        self.y = y\n    \n    def mostrar(self) -> str:\n        return str(self.x) + \":\" + str(self.y)\n    \n    def distancia(self, point):\n        # Devuelve la distancia entre ambos puntos\n        dx = self.x - point.x\n        dy = self.y - point.y\n        \n        return sqrt((dx*dy + dy*dy))\n    \n# Instanciar objetos de la clase Punto\na = Punto()\nb = Punto(4,6)\n\n# Llamada a método de la clase en los objetos\nprint(a.mostrar())\nprint(b.mostrar())\n\nprint(a.distancia(b))\n\na.x = 10\na.y = 10\n\nprint(a.mostrar())\nprint(a.distancia(b))\n\n\n##########################  FIN POO  ################################\n\n##########################  EXTRA  ################################\nclass Stack():\n    \n    def __init__(self, stack: list = []) -> None:\n        self.stack = stack\n\n    def add(self, value) -> None:\n        self.stack.append(value)\n        print(f'Se ha añadido el elemento {value} a la pila')\n        \n    def print_elements(self):\n        return self.stack if len(self.stack) > 0 else \"No hay elementos en la pila\"\n    \n    def count(self) -> int:\n        return len(self.stack)\n\n    def pop(self) -> None:\n        if len(self.stack) > 0:\n            print(f'Se ha eliminado {self.stack.pop()} de la pila')\n        else:\n            print('La pila está vacía')\n            \n    def get_value(self, position: int = 0):\n        if position < len(self.stack) and position >= 0:\n            return self.stack[position]\n\nclass Queue():\n    \n    def __init__(self, queue: list = [])-> None:\n        self.queue = queue\n    \n    def add(self, value: int) -> None:\n        if self.queue.insert(0,value):\n            print(f'Se ha añadido el elemento {value} a la cola.')\n    \n    def count(self) -> int:\n        return len(self.queue)\n\n    def print_elements(self):\n        return self.queue if len(self.queue) > 0 else \"No hay elementos en la cola\"\n    \n    def pop(self) -> None:\n        if len(self.queue) > 0:\n            print(f'Se extraido el elemento {self.queue.pop()} de la cola')\n        else:\n            print('No hay elementos en la cola')\n            \n    def get_value(self, position: int = 0):\n        if position < len(self.queue) and position >= 0:\n            return self.queue[position]\n\n\nmy_stack = Stack([i for i in range(1,11)])\nprint('Inicio de Pila')\nprint(my_stack.count())\nprint(my_stack.get_value(2))\nmy_stack.pop()\nmy_stack.add(55)\nprint(my_stack.print_elements())\nmy_stack.pop()\nprint(my_stack.print_elements())\n\nmy_queue = Queue([i for i in range(1,11)])\n\nprint('Inicio de Cola')\nprint(my_queue.count())\nprint(my_queue.get_value(2))\nmy_queue.pop()\nmy_queue.add(55)\nprint(my_queue.print_elements())\nmy_queue.pop()\nprint(my_queue.print_elements())\nprint('Fin de Cola')\n##########################  FIN EXTRA  ################################\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/mvidalb.py",
    "content": "'''\nClases\n'''\n\nclass Programmer:\n\n    surname: str = None\n\n    def __init__(self, name : str, age : int, languages: list) -> None:\n        self.name = name\n        self.age = age\n        self.languages = languages\n\n    def print(self):\n        print(f\"Nombre: {self.name}\")\n        print(f\"Apellidos: {self.surname}\")\n        print(f\"Edad: {self.age}\")\n        print(f\"Lenguajes: {self.languages}\")\n\nmy_programmer = Programmer(\"Pedro\", 35, [\"Python\", \"C#\"])\nmy_programmer.print()\nmy_programmer.surname = \"García\"\nmy_programmer.print()\nmy_programmer.age = 37\nmy_programmer.print()\n\n'''\nEjercicio extra\n'''\n# Pila (LIFO)\nclass Stack:\n\n    def __init__(self) -> None:\n        self.stack = []\n\n    def push(self, item):\n        self.stack.append(item)\n\n    def pop(self):\n        if self.count() == 0:\n            return None\n        return self.stack.pop()\n\n    def count(self):\n        return len(self.stack)\n    \n    def print(self):\n        for item in reversed(self.stack):\n            print(item)\n\n\nprint(\"\\nEjercicio extra - LIFO!\")\nmy_stack = Stack()\nmy_stack.push(\"A\")\nmy_stack.push(\"B\")\nmy_stack.push(\"C\")\nprint(my_stack.stack)\nmy_stack.print()\nmy_stack.pop()\nprint(my_stack.stack)\nprint(my_stack.count())\n\n\n# Cola (FIFO)\nclass Queue:\n\n    def __init__(self) -> None:\n        self.queue = []\n\n    def equeue(self, item):\n        self.queue.append(item)\n\n    def dequeue(self):\n        if self.count() == 0:\n            return None\n        return self.queue.pop(0)\n\n    def count(self):\n        return len(self.queue)\n    \n    def print(self):\n        for item in self.queue:\n            print(item)\n\n\nprint(\"\\nEjercicio extra - FIFO!\")\nmy_queue = Queue()\nmy_queue.equeue(\"A\")\nmy_queue.equeue(\"B\")\nmy_queue.equeue(\"C\")\nprint(my_queue.queue)\nmy_queue.print()\nmy_queue.dequeue()\nprint(my_queue.queue)\nprint(my_queue.count())\n\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/neslarra.py",
    "content": "\"\"\"\n EJERCICIO:\n Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n atributos y una función que los imprima (teniendo en cuenta las posibilidades\n de tu lenguaje).\n Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n utilizando su función.\n\n DIFICULTAD EXTRA (opcional):\n Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n en el ejercicio número 7 de la ruta de estudio)\n - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n   retornar el número de elementos e imprimir todo su contenido.\n\"\"\"\n\n\nclass LinearStructure:\n\n    def __init__(self, tipo: str):\n        self.tipo = tipo.upper()\n        self.elementos = []\n        if not self.validate():\n            raise TypeError(f\"Los stack solo pueden ser de tipo PILA o tipo COLA => {tipo} NO es válido.\")\n\n    def put(self, elemento) -> None:\n        self.elementos.append(elemento)\n\n    def take(self) -> object:\n        if self.elementos.__len__():\n            if self.tipo == \"PILA\":\n                elemento = self.elementos.pop()\n            else:\n                elemento = self.elementos.pop(0)\n            return elemento\n        return None\n\n    def __len__(self):\n        return self.elementos.__len__()\n\n    def __str__(self):\n        return f\"{self.tipo} contiene {self.__len__()} elementos.\"\n\n    def clear(self):\n        self.elementos.clear()\n\n    def validate(self) -> bool:\n        return self.tipo in (\"PILA\", \"COLA\")\n\n\ndef anonymous_block(function):\n    titulo = function.__name__.replace('_', ' ').title()\n    print(f\"\\nBEGIN {titulo}:\\n\")\n    function()\n    print(f\"\\nEND {titulo}\\n\")\n\n\n@anonymous_block\ndef explicacion():\n    print(\"\"\"Las clases proveen una forma de empaquetar datos y funcionalidad juntos. Al crear una nueva clase, se crea un nuevo tipo de objeto,\n    permitiendo crear nuevas instancias de ese tipo. Cada instancia creada en base a esta clase heredará todos sus atributos y métodos que, a su vez\n    los puede reimplementar y/o agregar nuevos.\n    \n    Como ejemplo creamos la clase LinearStructure (que permite implementar pilas y colas) la cual re-implementa los métodos \"__len__\" y \"__str__\". \n    Luego implementaremos una clase \"Navegador\" que, sobre los métodos heredados de LinearStructure, redefine validate y va a agragar un método \n    extra \"get_top\".\n    Tambien vamos a impementar una clase PrintSpooler que hereda LinearStructure, redefine validate y crea métodos propios.\n\n    class LinearStructure:\n\n        def __init__(self, tipo: str):\n            self.tipo = tipo.upper()\n            self.elementos = []\n            if not self.validate():\n                raise TypeError(f\"Los stack solo pueden ser de tipo PILA o tipo COLA => {tipo} NO es válido.\")\n\n        def put(self, elemento) -> None:\n            self.elementos.append(elemento)\n\n        def take(self) -> object:\n            if self.elementos.__len__():\n                if self.tipo == \"PILA\":\n                    elemento = self.elementos.pop()\n                else:\n                    elemento = self.elementos.pop(0)\n                return elemento\n            return None\n\n        def __len__(self):\n            return self.elementos.__len__()\n\n        def __str__(self):\n            return f\"{self.tipo} contiene {self.__len__()} elementos.\"\n\n        def clear(self):\n            self.elementos.clear()\n\n        def validate(self) -> bool:\n            return self.tipo in (\"PILA\", \"COLA\"))\n    \n    class Navegador(LinearStructure):\n        def __init__(self, tipo):\n            super().__init__(tipo)\n    \n        def get_top(self) -> object:\n            if self.tipo == \"PILA\":\n                return self.elementos[-1]\n            if self.tipo == \"PILA\":\n                return self.elementos[0]\n\n    class PrintSpooler(LinearStructure):\n        def __init__(self, tipo):\n            super().__init__(tipo)\n            if not self.validate():\n                raise TypeError(f\"Solo puede instanciar COLA.\")\n\n        def print_doc(self) -> None:\n            print(f\"Printing {self.take()}\")\n\n        def print_all(self) -> None:\n            while self.elementos:\n                self.print_doc()\n\n        def remove_doc(self, doc_idx: int):\n            if doc_idx == 0:\n                print(f\"Doc {self.elementos[0]} is Ready To Print => can't be removed.\")\n            else:\n                print(f\"Removig {self.elementos.pop(doc_idx)}\")\n\n        def list_spool(self):\n            for index, doc in enumerate(self.elementos):\n                if index == 0:\n                    print(f\"Document {doc} is ready to print.\")\n                else:\n                    print(f\"Document {doc} is waiting for ({index}) document to print.\")\n\n        def validate(self):\n            return self.tipo == \"COLA\"\n\n    pila_atras = Navegador(\"PILA\")\n    pila_adelante = Navegador(\"PILA\")\n    spooler = PrintSpooler(\"COLA\")\n    \"\"\")\n\n\n@anonymous_block\ndef dificultad_extra_navegar():\n    class Navegador(LinearStructure):\n        def __init__(self, tipo):\n            super().__init__(tipo)\n            if not self.validate():\n                raise TypeError(f\"Solo puede instanciar PILA.\")\n\n        def get_top(self) -> object:\n            return self.elementos[-1]\n\n        def validate(self):\n            return self.tipo == \"PILA\"\n\n    pila_atras = Navegador(\"PILA\")\n    pila_adelante = Navegador(\"PILA\")\n    boton_adelante = False\n    boton_atras = False\n\n    def navegar(opcion: str) -> str:\n        nonlocal pila_atras\n        nonlocal pila_adelante\n        nonlocal boton_atras\n        nonlocal boton_adelante\n\n        if opcion == \"atras\" and boton_atras:\n            pagina = pila_atras.take()\n            pila_adelante.put(pagina)\n            pagina = pila_atras.get_top()\n            print(f\"Vuelvo a {pagina}\")\n        elif opcion == \"adelante\" and boton_adelante:\n            pagina = pila_adelante.take()\n            pila_atras.put(pagina)\n            print(f\"Voy a {pagina}\")\n        else:\n            if opcion not in (\"atras\", \"adelante\"):\n                pagina = opcion\n                pila_adelante.clear()\n                pila_atras.put(pagina)\n            else:\n                pagina = pila_atras.get_top()\n\n        return pagina\n\n    def habilitar_botones() -> None:\n        nonlocal pila_atras\n        nonlocal pila_adelante\n        nonlocal boton_atras\n        nonlocal boton_adelante\n\n        if pila_atras.__len__() > 1:\n            boton_atras = True\n        else:\n            boton_atras = False\n        if pila_adelante:\n            boton_adelante = True\n        else:\n            boton_adelante = False\n\n    salto = \"\\n\"\n    habilitar_botones()\n    while True:\n        menu = f\"Elegir opción:\\nhttps://<url-destino>{salto + 'atras' if boton_atras else ''}{salto + 'adelante' if boton_adelante else ''}\\nsalir\\n  ==> \"\n        opcion = input(menu).lower()\n        if opcion == \"salir\":\n            pila_atras.clear()\n            pila_adelante.clear()\n            print(\"Navegador cerrado.\")\n            break\n        pagina = navegar(opcion)\n\n        print(f\"\\nEstoy en página https://{pagina}\\n\")\n        habilitar_botones()\n\n\n@anonymous_block\ndef dificultad_extra_imprimir():\n    class PrintSpooler(LinearStructure):\n        def __init__(self, tipo):\n            super().__init__(tipo)\n            if not self.validate():\n                raise TypeError(f\"Solo puede instanciar COLA.\")\n\n        def print_doc(self) -> None:\n            print(f\"Printing {self.take()}\")\n\n        def print_all(self) -> None:\n            while self.elementos:\n                self.print_doc()\n\n        def remove_doc(self, doc_idx: int):\n            if doc_idx == 0:\n                print(f\"Doc {self.elementos[0]} is Ready To Print => can't be removed.\")\n            else:\n                print(f\"Removig {self.elementos.pop(doc_idx)}\")\n\n        def list_spool(self):\n            if not self.elementos:\n                print(\"Spooler vacío.\")\n            else:\n                for index, doc in enumerate(self.elementos):\n                    if index == 0:\n                        print(f\"Document {doc} is ready to print.\")\n                    else:\n                        print(f\"Document {doc} is waiting for ({index}) document to print.\")\n\n        def validate(self):\n            return self.tipo == \"COLA\"\n\n    spooler = PrintSpooler(\"COLA\")\n\n    menu = f\"\"\"\n    Menu de impresora:\n        Documento (nombre)\n        Eliminar\n        Imprimir\n        ImprimirTodo\n        Listar\n        Salir\n    opcion => \"\"\"\n\n    while True:\n        opcion = input(menu)\n        if opcion.lower() == \"salir\":\n            spooler.clear()\n            print(\"\\n\\nSaliendo.\")\n            break\n        if opcion.lower() == \"imprimir\":\n            spooler.print_doc()\n        elif opcion.lower() == \"imprimirtodo\":\n            spooler.print_all()\n        elif opcion.lower() == \"listar\":\n            spooler.list_spool()\n        elif opcion.lower() == \"eliminar\":\n            if spooler:\n                spooler.list_spool()\n                doc_id = \"-1\"\n                while not doc_id.isnumeric() or int(doc_id) not in range(0, spooler.__len__()):\n                    doc_id = input(\"\\nIngrese el número de orden del documento a eliminar: \")\n                spooler.remove_doc(int(doc_id))\n            else:\n                print(\"No hay elementos en el spooler.\")\n        else:\n            print(f\"Mando a imprimir {opcion}\", end=\"\\n\\n\")\n            spooler.put(opcion)\n\n    print(f\"{spooler} => Spool vacío. FIN del procesamiento.\")\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/nlarrea.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n\"\"\"\n\nfrom typing import Any\n\n\nclass Person:\n    languages: list = []\n\n    def __init__(self, name: str, username: str, age: int) -> None:\n        self.name = name\n        self.username = username\n        self.age = age\n\n    def print_person(self):\n        print(f\"\\nPrinting {self.username}'s data:\")\n        print(\"name:\", self.name)\n        print(\"age:\", self.age)\n\n        if self.languages:\n            print(\"This person uses the following languages to code:\")\n            for language in self.languages:\n                print(f\" - {language}\")\n\n\nme = Person(name=\"Naia\", username=\"nlarrea\", age=25)\nme.print_person()\nme.languages = [\"Python\", \"JavaScript\", \"Kotlin\"]\nme.print_person()\nme.age = 26\nme.print_person()\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n\"\"\"\n\n\nprint(\"\\nLIFO:\\n\")\n\n\nclass Stack:\n    \"\"\"Stack is a LIFO (Last In First Out).\"\"\"\n\n    def __init__(self) -> None:\n        self.stack = []\n\n    def add(self, *items) -> None:\n        self.stack.extend([*items])\n\n    def remove(self) -> Any:\n        if self.length() == 0:\n            return None\n        return self.stack.pop()\n\n    def length(self) -> int:\n        return len(self.stack)\n\n    def print(self) -> None:\n        for item in reversed(self.stack):\n            print(item)\n\n\nlifo = Stack()\nlifo.add(1, 2, 3)\nlifo.print()\n\"\"\"\n3\n2\n1\n\"\"\"\nprint(\"LIFO length:\", lifo.length())\n# LIFO length: 3\n\nlifo.remove()  # This would print the number 3 because it's the removed one\nlifo.print()\n\"\"\"\n2\n1\n\"\"\"\nprint(\"LIFO length:\", lifo.length())\n# LIFO length: 2\n\n\nprint(\"\\nFIFO:\\n\")\n\n\nclass Queue:\n    \"\"\"A Queue is a FIFO (First In, First Out).\"\"\"\n\n    def __init__(self) -> None:\n        self.queue = []\n\n    def add(self, *items) -> None:\n        self.queue.extend([*items])\n\n    def remove(self) -> Any:\n        if self.length() == 0:\n            return None\n        return self.queue.pop(0)\n\n    def length(self) -> int:\n        return len(self.queue)\n\n    def print(self) -> None:\n        for item in self.queue:\n            print(item)\n\n\nfifo = Queue()\nfifo.add(1, 2, 3)\nfifo.print()\n\"\"\"\n1\n2\n3\n\"\"\"\nprint(\"FIFO length:\", fifo.length())\n# FIFO length: 3\n\nfifo.remove()\nfifo.print()\n\"\"\"\n2\n3\n\"\"\"\nprint(\"FIFO length:\", fifo.length())\n# FIFO length: 2\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/oniricoh.py",
    "content": "\n\nclass Rapper:\n    def __init__(self,apodo, edad, localidad):\n        self.apodo = apodo\n        self.edad = edad\n        self.localidad = localidad\n    \n    def info(self):\n        print(\"Apodo:\",self.apodo)\n        print(\"Edad:\", self.edad)\n        print(\"Localidad:\", self.localidad)\n    \n    def __str__(self):\n        return f\"El rapero {self.apodo} tiene {self.edad} años y vive en {self.localidad}.\"\n    \n    def __del__(self):\n       print(f\"The object {self.apodo} has been deleted.\")\n\n\nEl_langui = Rapper(\"Langui\", 44, \"Jaen\")\nEl_langui.info()\n\natributos = vars(El_langui)\nprint(atributos)\n\nEl_langui.localidad = \"Pan bendito\"\n\natributos = El_langui.__dict__\nprint(atributos)\n\nprint(str(El_langui))\n\ndel El_langui\nEl_langui.info()\n\n\n########################################################################\n#  DIFICULTAD EXTRA\n########################################################################\n\n\nclass Stack:\n    def __init__(self, elements: list) -> list:\n        self.elements = elements\n    \n    def push(self, element):\n        self.elements.append(element)\n        print(f\"Se ha añadido {element} a la pila\")\n    \n    def pop(self):\n        if self.elements:\n            element = self.elements.pop()\n            print(f\"Se ha eliminado {element} de la pila\")\n            return element\n        else:\n            print(\"La pila está vacía\")\n    \n    def __str__(self):\n        if not self.elements:\n            return \"La pila está vacía\"\n        else:\n            return self.elements\n\n\nclass Queue:\n    def __init__(self, elements: list) -> list:\n        self.elements = elements\n        \n    def enqueue(self, element):\n        self.elements.append(element)\n        print(f\"Se ha añadido {element} a la cola\")\n    \n    def dequeue(self):\n        if self.elements:\n            element = self.elements.pop(0)\n            print(f\"Se ha eliminado {element} de la cola\")\n            return element\n        else:\n            print(\"La cola está vacía\")\n    \n    def __str__(self):\n        if not self.elements:\n            return \"La cola está vacía\"\n        else:\n            return self.elements\n\n\npila = Stack([])\nprint(pila)\npila.push(4)\npila.push(8)\nprint(pila)\npila.pop()\nprint(pila)\n\n\ncola = Queue([])\nprint(cola)\ncola.enqueue([1,2])\ncola.enqueue(3)\nprint(cola)\ncola.dequeue()\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/oriaj3.py",
    "content": "\"\"\"\t\n08 - CLASES\nAutor de la solución: Oriaj3\t\nTeoría:\t\nLas clases son una forma de organizar y estructurar el código.\nEn la mayoría de los lenguajes de programación, las clases son la base de la\nprogramación orientada a objetos.\n\nUna clase es una plantilla para crear objetos. Un objeto es una instancia de una\nclase. Cuando se crea un objeto, se le asigna un espacio en memoria y se le\nasignan los atributos y métodos de la clase.\n\nLas clases pueden tener atributos y métodos:\n*Los atributos son variables que pertenecen a la clase.\n*Los métodos son funciones que pertenecen a la clase.\n\nTambién pueden tener un inicializador, que es un método especial que se ejecuta\ncuando se crea un objeto.\n\nEn Python, las clases se definen con la palabra clave class, seguida del nombre\nde la clase y dos puntos. Los atributos y métodos de la clase se definen dentro\nde la clase, con sangría.\n\nEjemplo:\nclass Persona:\n    def __init__(self, nombre, edad):\n        self.nombre = nombre\n        self.edad = edad\n\n    def saludar(self):\n        print(f'Hola, me llamo {self.nombre} y tengo {self.edad} años')\n\nTambién existen los destructores y los métodos estáticos, pero no son tan\ncomunes. En python se definen con las palabras clave __del__ y @staticmethod\nrespectivamente.\n\nPara crear un objeto de una clase, se llama al nombre de la clase como si fuera\nuna función, pasando los argumentos que requiera el inicializador.\n\nEjemplo:\npersona1 = Persona('Juan', 25)\npersona1.saludar()\n\nEn este ejemplo, se crea un objeto de la clase Persona, con el nombre 'Juan' y\nla edad 25. Luego se llama al método saludar del objeto persona1.\n\nPara acceder a los atributos y métodos de un objeto, se utiliza la notación de\npunto.\n\nEjemplo:\nprint(persona1.nombre)\n\nTambién es importante mencionar que en Python, todos los atributos y métodos de\nuna clase son públicos, a menos que se especifique lo contrario. Esto significa\nque se pueden acceder y modificar desde cualquier parte del código.\n\nEjemplo:\npersona1.nombre = 'Pedro'\n\nEn este ejemplo, se cambia el nombre del objeto persona1 a 'Pedro'.\n\nEjemplo private:\nclass Persona:\n    def __init__(self, nombre, edad):\n        self.__nombre = nombre\n        self.__edad = edad\n\n    def saludar(self):\n        print(f'Hola, me llamo {self.__nombre} y tengo {self.__edad} años')\n        \nEn este ejemplo, se utiliza dos guiones bajos antes del nombre de los atributos \n\"\"\"\t\n\n# EJERCICIO BÁSICO:\n\"\"\"\nEJERCICIO:\n Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n atributos y una función que los imprima (teniendo en cuenta las posibilidades\n de tu lenguaje).\n Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n utilizando su función.\n\"\"\"\n\nclass persona1: \n    def __init__(self, nombre, edad) -> None:\n        self.__nombre = nombre\n        self.__edad = edad\n    \n    def setNombre(self, nombre) -> None: \n        self.__nombre = nombre\n    \n    def getNombre(self) -> str:\n        return self.__nombre\n    \n    def setEdad(self, edad) -> None: \n        self.__edad = edad\n    \n    def getEdad(self) -> str:\n        return self.__edad\n    \n    def print(self) -> None:\n        print(f\"La persona se llama {self.__nombre} y tiene {self.__edad} años.\")\n        \npepe = persona1(\"Pepe\", 23)\n\npepe.print()\n\npepe.setNombre(\"Juan\")\npepe.setEdad(25) \n\npepe.print()\n\nprint(pepe.getNombre())\nprint(pepe.getEdad())   \n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\nImplementa dos clases que representen las estructuras de Pila y Cola (estudiadas\nen el ejercicio número 7 de la ruta de estudio)\n- Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n    retornar el número de elementos e imprimir todo su contenido.\n\"\"\"\n\nclass pila:\n    lista = []\n    \n    def anadir(self, elemento) -> None:\n        self.lista.append(elemento)\n        \n    def sacar(self) -> any:\n        return self.lista.pop()\n    \n    def tamano(self) -> int:\n        return len(self.lista)\n    \n    def imprimir(self) -> None:\n        print(self.lista)\n        \n# Ejemplo de uso\np = pila()\np.anadir(1)\np.anadir(2)\np.anadir(3)\n\nprint(\"LISTAS.....\")\np.imprimir()\nprint(f\"El tamaño es: {p.tamano()}\")\nprint(p.sacar())\np.imprimir()\nprint(f\"El tamaño es: {p.tamano()}\")\n\n        \nclass cola:\n    cola = []\n    \n    def anadir(self, elemento) -> None:\n        self.cola.append(elemento)\n        \n    def sacar(self) -> any:  # Add return type annotation\n        return self.cola.pop(0)\n    \n    def tamano(self) -> int:\n        return len(self.cola)\n    \n    def imprimir(self) -> None:\n        print(self.cola)\n        \n# Ejemplo de uso\nc = cola()\nc.anadir(1)\nc.anadir(2)\nc.anadir(3)\n\nprint(\"COLAS.....\")\nc.imprimir()\nprint(f\"El tamaño es: {c.tamano()}\")\nprint(c.sacar())\nc.imprimir()\nprint(f\"El tamaño es: {c.tamano()}\")\n\n    \n        "
  },
  {
    "path": "Roadmap/08 - CLASES/python/pguillo02.py",
    "content": "class Animal:\n    def __init__(self, tipo: str, altura: int):\n        self.__tipo = tipo\n        self.__altura = altura\n\n    @property\n    def tipo(self):\n        return self.__tipo\n    \n    @tipo.setter\n    def tipo(self, new_tipo):\n        self.__tipo = new_tipo\n\n    @property\n    def altura(self):\n        return self.__altura\n    \n    @altura.setter\n    def altura(self, new_altura):\n        self.__altura = new_altura\n    \n    def __str__(self):\n        return f\"Este es una animal de tipo {self.tipo} y de altura {self.altura}\"\n\nejemplo = Animal(\"mamífero\", 3)\nprint(ejemplo)\n\n    \n\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/pwrxman.py",
    "content": "\"\"\"\n* EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n\"\"\"\nclass Auto:\n      def __init__ (self, marca: str, modelo: str, tipo: str, anio: int, caracteristicas: list):\n          self.marca = marca\n          self.modelo = modelo\n          self.tipo = tipo\n          self.anio = anio\n          self.caracteristicas = caracteristicas\n\n      def car_info(self):\n        return f\"El auto solicitado es un {self.marca}:{self.modelo}:{self.tipo}:{self.anio} con el siguiente equipo especial {self.caracteristicas}\"  \n\n      def add_carac_especial(self, adicional: str):\n          self.caracteristicas.append(adicional)\n\n\ncar = Auto(\"Honda\", \"Civic\", \"Sedan\", 2024,[\"Blanco\", \"Faros Niebla\", \"Frenos Ventilados\"])\nprint(car.marca)\nprint(car.car_info())\n\n\ncar.add_carac_especial(\"Quemacocos\")\ncar.add_carac_especial(\"Rines Aluminio\")\nprint(car.car_info())  \n\n\n\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n\"\"\"\n\n# LIFO\nclass Stack:\n    def __init__(self):\n        self.stack = []\n\n    def push(self, item):       # Insertar elemento en la pila\n        self.stack.append(item)\n    \n    def pop(self):              # Eliminar elemento de la pila\n        if self.count() == 0:\n            return None\n        return self.stack.pop()\n    \n    def count(self):\n        return len(self.stack)\n    \n    def print(self):\n        for item in reversed(self.stack):\n            print(item)\n\n# FIFO\n\nclass Queue:\n    def __init__(self):\n        self.queue = []\n\n    def enqueue(self, item):\n        self.queue.append(item)\n\n    def unqueue(self):\n        if self.count() == 0:\n            return None\n        return self.queue.pop(0)\n\n    def count(self):\n        return len(self.queue)\n    \n    def print(self):\n        for item in self.queue:\n            print(item)\n\n    \n\n\npila = Stack()\ncola = Queue()\n\nwhile True:\n    print(\"PILAS\")\n    print(\"\\t1 - Agregar elemento en Pila\")\n    print(\"\\t2 - Eliminar elemento de Pila\")\n    print(\"\\t3 - Mostrar Elementos de la Pila\\n\")\n    print(\"\\t4 - Contar Elementos de la Pila\\n\")\n\n    print(\"COLAS\")\n    print(\"\\t5 - Agregar elemento en cola\")\n    print(\"\\t6 - Eliminar elemento de cola\")\n    print(\"\\t7 - Mostrar Elementos de la cola\\n\")\n    print(\"\\t8 - Contar Elementos de la cola\\n\")\n    print(\"q - Terminar\")\n\n    action= input(\"Que desea hacer? \")\n    match action:\n        case '1':\n            element=input(\"Cual es el elemento que desea añadir a la Pila? \")\n            pila.push(element)\n            # addelem(element, stack)\n        case '2':\n            pila.pop()\n            # pop(stack)\n        case '3':\n            pila.print()\n        case '4':\n            pila.count()\n        case '5':\n            element=input(\"Cual es el elemento que desea añadir a la Cola? \")\n            cola.enqueue(element)\n        case '6': \n            cola.unqueue()\n        case '7': \n            cola.print()\n        case '8': \n            cola.count()\n\n        case 'q':\n            print(\"Hasta la vista...\")\n            break\n\n\n\n\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/pyramsd.py",
    "content": "class FocoLedRGB:\n\n    def __init__(self, color:str) -> None:\n        self.color = color\n        self.encendido = False\n\n    def Led_ON(self) -> None:\n        self.encendido = True\n\n    def Led_OFF(self) -> None:\n        self.encendido = False\n\n    def change_Color(self, color) -> None:\n        self.color = color\n\n    def get_Color(self) -> None:\n        return self.color\n\n    def get_Status(self):\n        status = f'El led es de color {self.color} y '\n        if self.encendido:\n            status += 'esta encendido'\n        else:\n            status += 'esta apagado'\n        \n        return status\n    \nled = FocoLedRGB('blanco')\nprint(led.get_Status())\n\nled.Led_ON()\nprint(led.get_Status())\n\nprint(led.get_Color())\n\nled.change_Color('verde')\nprint(led.get_Color())\n\nled.Led_OFF()\nprint(led.get_Status())\n\nled.Led_ON()\nprint(led.get_Status())\n\n\n'''\nEXTRA\n'''\n\nclass Stack:\n\n    def __init__(self) -> None:\n        self.stack = []\n\n    def push(self, item) -> None:\n        self.stack.append(item)\n\n    def pop(self):\n        if self.count() == 0:\n            return None\n        return self.stack.pop()\n\n    def count(self) -> int:\n        return len(self.stack)\n    \n    def print(self) -> list:\n        print(self.stack)\n\nlista = Stack()\nlista.print()\nlista.push('A')\nlista.print()\nlista.push('B')\nlista.push('c')\nlista.push('d')\nlista.print()\nprint(lista.count())\nlista.pop()\nlista.print()\nprint(lista.pop())\nlista.print()\n\n\nclass Queue:\n    \n    def __init__(self) -> None:\n        self.queue = []\n\n    def enqueue(self, item):\n        self.queue.append(item)\n\n    def dequeue(self):\n        if self.count() == 0:\n            return None\n        return self.queue.pop(0)\n\n    def count(self):\n        return len(self.queue)\n    \n    def print(self):\n        print(self.queue)\n\n\nmy_queue = Queue()\nmy_queue.enqueue(\"A\")\nmy_queue.enqueue(\"B\")\nmy_queue.enqueue(\"c\")\nmy_queue.enqueue(\"D\")\nmy_queue.print()\nmy_queue.dequeue()\nprint(my_queue.count())\nprint(my_queue.dequeue())\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/qv1ko.py",
    "content": "class C1:\n\n    def __init__(self, value = \"example\"):\n        self.c1_string = value\n\n    def get_c1_string(self):\n        return self.c1_string\n\n    def set_c1_string(self, value):\n        self.c1_string = value\n\n    def __str__(self):\n        return f\"Class 1 value: {self.c1_string}\"\n\n\nclass C2:\n\n    def __init__(self, value = \"example\"):\n        self.c2_string = value\n\n    def get_c2_string(self):\n        return self.c2_string\n\n    def set_c2_string(self, value):\n        self.c2_string = value\n\n    def __str__(self):\n        return f\"Class 2 value: {self.c2_string}\"\n\n\nif __name__ == \"__main__\":\n\n    example1 = C1()\n    print(example1)\n    example1.set_c1_string(\"Example 1\")\n    print(example1.get_c1_string())\n\n    example2 = C2()\n    print(example2)\n    example2.set_c2_string(\"Example 2\")\n    print(example2.get_c2_string())\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/qwik-zgheib.py",
    "content": "# -- exercise\nclass Person:\n    def __init__(self, name: str, age: int) -> None:\n        self.name = name\n        self.age = age\n\n    def printPerson(self):\n        print(f\"name: {self.name}\")\n        print(f\"age: {self.age}\")\n\n\nperson: Person = Person(\"Qwik\", 22)\nperson.printPerson()\n\n\n# -- extra challenge\nclass Stack:\n    def __init__(self) -> None:\n        self.stack = []\n\n    def push(self, element: any) -> any:\n        self.stack.append(element)\n        return self.stack\n\n    def pop(self) -> any:\n        return self.stack.pop()\n\n    def size(self) -> int:\n        return len(self.stack)\n\n    def printStack(self) -> None:\n        print(\"stack elements:\")\n        for i, element in enumerate(self.stack):\n            print(f\"element {i + 1} -> {element}\")\n\n\nclass Queue:\n    def __init__(self) -> None:\n        self.queue = []\n\n    def push(self, element):\n        self.queue.append(element)\n\n    def pop(self):\n        return self.queue.pop(0)\n\n    def size(self):\n        return len(self.queue)\n\n    def printQueue(self):\n        for index, element in enumerate(self.queue):\n            print(f\"element {index + 1} -> {element}\")\n\n\nprint(\"extra cchallenge ------------------\")\nprint(\"----- stack ------------------\")\nstack: Stack = Stack()\nprint(f\"stack added 1: {stack.push(1)}\")\nprint(f\"stack added 2: {stack.push(2)}\")\nprint(f\"stack size: {stack.size()}\")\nprint(f\"stack pop element: {stack.pop()}\")\nprint(f\"stack added 4: {stack.push(4)}\")\nprint(f\"stack size: {stack.size()}\")\nstack.printStack()\n\n\nprint(\"----- queue ------------------\")\nqueue: Queue = Queue()\nqueue.push(1)\nqueue.push(2)\nqueue.push(3)\nqueue.push(4)\nprint(f\"queue size: {queue.size()}\")\nprint(f\"queue pop element: {queue.pop()}\")\nprint(f\"queue size: {queue.size()}\")\nqueue.printQueue()\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/rantamhack.py",
    "content": "'''\n* EJERCICIO:\n* Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n* atributos y una funciÃ³n que los imprima (teniendo en cuenta las posibilidades\n* de tu lenguaje).\n* Una vez implementada, crÃ©ala,w establece sus parÃ¡metros, modifÃ­calos e imprÃ­melos\n* utilizando su funciÃ³n.\n'''\n\nclass Car:\n    def __init__ (self, marca, modelo, aÃ±o):\n        self.marca = marca\n        self.modelo = modelo\n        self.aÃ±o = aÃ±o\n        \n    def car_of_the_year(self):\n        return f\"El premio coche del aÃ±o en {self.aÃ±o} fue para el {self.marca} {self.modelo}\"\n        \n\nmy_first_car = Car(\"seat\", \"1430\", 1975)\nmy_last_car = Car(\"ford\", \"Mustang Shelby\", 2020)\nprint(my_first_car.car_of_the_year())\nprint(my_last_car.car_of_the_year())\n\n\n'''\n* DIFICULTAD EXTRA (opcional):\n* Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n* en el ejercicio nÃºmero 7 de la ruta de estudio)\n* - Deben poder inicializarse y disponer de operaciones para aÃ±adir, eliminar,\n*   retornar el nÃºmero de elementos e imprimir todo su contenido.\n'''\n\nclass Stack:\n    \n    def __init__(self):\n        self.my_stack = []\n        \n    def len_items(self):\n        return len(self.my_stack)\n\n    def add(self, name):\n        self.my_stack.append(name)\n        return self.my_stack\n        \n    def pop(self):\n        if len(self.my_stack) > 0:\n            self.my_stack.pop()\n            return self.my_stack\n        else:\n            return \"No hay elementos para eliminar la lista estÃ¡ vacÃ­a\"\n            \npila = Stack()\nprint(pila.len_items())   \nprint(pila.add(\"Juan\"))\nprint(pila.add(\"Pedro\"))\nprint(pila.add(\"MarÃ­a\"))\nprint(pila.len_items()) \nprint(pila.pop())\nprint(pila.len_items()) \nprint(pila.pop())\nprint(pila.len_items()) \nprint(pila.pop())\nprint(pila.len_items())\nprint(pila.pop())\n\n \nclass Queue:\n    def __init__(self):\n        self.my_queue = []\n        \n    def len_items(self):\n        return len(self.my_queue)\n    \n    def add(self,name):\n        self.my_queue.append(name)\n        return self.my_queue\n    def pop(self):\n        if len(self.my_queue) > 0:\n            self.my_queue.pop(0)\n            return self.my_queue\n        else:\n            return \"No hay elementos para eliminar\"\n\ncola = Queue()\nprint(cola.len_items())\nprint(cola.add(\"Juan\"))\nprint(cola.add(\"Pedro\"))\nprint(cola.add(\"MarÃ­a\"))\nprint(cola.len_items())    \nprint(cola.pop()) \nprint(cola.len_items())  \nprint(cola.pop()) \nprint(cola.len_items()) \nprint(cola.pop()) \nprint(cola.len_items()) \nprint(cola.pop())      \n\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/raulG91.py",
    "content": "class myClass:\n    public_attribute = \"This is a public attribute\"\n    _private_attribute = 0\n    def __init__(self):\n        self._private_attribute = 1\n        print(\"Class constructor\")\n    \n    def print_attributes(self):\n        print(\"Public attribute: \",self.public_attribute) \n        print(\"Private attribute: \", self._private_attribute) \n    \n    def get_public_attribute(self):\n        return self.public_attribute \n    def get_private_attribute(self):\n        return self._private_attribute\n    def set_private_attribute(self,value):\n        self._private_attribute = value\n    def set_public_attribute(self,value):\n        self.public_attribute = value       \n        \n        \nclass_instance = myClass() #Constructor will be triggered\nclass_instance.print_attributes()\nclass_instance.set_public_attribute(\"Hello!\")\nclass_instance.set_private_attribute(5)\nprint(\"Public attribute\", class_instance.get_public_attribute())\nprint(\"Private attribute\", class_instance.get_private_attribute())\n\n#Extra exercise\n\nclass myQueue:\n    \n    def __init__(self):\n        self.queue = []\n    \n    def push(self,element):\n        self.queue.append(element)    \n    def pop(self):\n        if len(self.queue) > 0:\n            return self.queue.pop(0)   \n    def count(self)->int:\n        return len(self.queue)\n    def print_content(self):\n        print(\"Content of the queue\", self.queue)\n            \n        \nmy_queue_object = myQueue() \nmy_queue_object.push(3)\nmy_queue_object.push(\"Hola\")\nmy_queue_object.push(\"adios\")\nprint(\"Number of elements: \", my_queue_object.count())\nmy_queue_object.print_content()\nprint(my_queue_object.pop()) \nprint(my_queue_object.pop()) \nprint(my_queue_object.pop()) \n\nclass myStack():\n    def __init__(self):\n        self.stack = []\n    \n    def push(self,element):\n        self.stack.append(element) \n    def pop(self):\n        if len(self.stack) > 0:\n            return self.stack.pop()\n    def count(self)->int:\n        return len(self.stack)\n    def print_content(self):\n        print(\"Content of the stack\", self.stack)\n            \n\nmy_stack_object = myStack()\nmy_stack_object.push(5)\nmy_stack_object.push(8)\nprint(\"Number of objects: \", my_stack_object.count())\nmy_stack_object.print_content()\nprint(my_stack_object.pop())               \nprint(my_stack_object.pop())\n           "
  },
  {
    "path": "Roadmap/08 - CLASES/python/rayn1er.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n#  * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n#  * de tu lenguaje).\n#  * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n#  * utilizando su función.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n#  * en el ejercicio número 7 de la ruta de estudio)\n#  * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n#  *   retornar el número de elementos e imprimir todo su contenido.\n#  */\n\n#clases en python, se crean con la palabra reservada class\n\nclass Persona:\n    \n    def __init__(self,nombre,edad,profesion): # creamos un constructor con la palabra init y asignamos a el todos los atributos de la clase\n        self.nombre = nombre\n        self.edad = edad\n        self.profesion = profesion\n\n    def greetings(self): # creamos una funcion la cual sera un metodo, un metodo es una funcion que realiza diferentes funcionalidades, en este caso la funcion greetins envia un saludo\n        print(f'{self.nombre} te saluda! ')\n\n    def presentation(self):\n        print(f'Hola, soy {self.nombre}. Tengo {self.edad} y soy un {self.profesion} :) ')\npersona_1 = Persona('Raul',25,'informatico') # para crear una instancia de la clase creamos una variable y le asignamos el nombre de la clase junto con los atributos que queremos asignarle\n\npersona_1.greetings() # para utilizar el metodo utilizamos la variable que hemos creado junto con su metodo\npersona_1.presentation()\n\npersona_1.profesion = 'Programador' #podemos acceder a un metodo para cambiarlo si asi lo deseamos\npersona_1.presentation()\n\n#extra\n\n#pila o stack\n\nclass Stack:\n\n    # stack_elements = []\n    def __init__(self):\n        self.elements = []\n    \n    def add_element(self,element):\n        self.elements.append(element)\n        print(f'{element} ha sido agregado con exito al stack')\n    \n    def delete_element(self):\n        if self.count_elements() == 0:\n            print(0)\n        else:\n            print(f\"{self.elements.pop()} ha sido eliminado del stack\")\n    \n    def show_elements(self):\n        print(f\"Los elementos presentes en el stack son {self.elements}\")\n\n    def count_elements(self):\n        print(f\"hay {len(self.elements)} elementos en el stack \")\n\nmy_stack = Stack()\nmy_stack.count_elements()\nmy_stack.add_element('raul')\nmy_stack.add_element(\"yander\")\nmy_stack.show_elements()\nmy_stack.count_elements()\nmy_stack.delete_element()\nmy_stack.count_elements()\n\nclass Queue:\n\n    def __init__(self):\n        self.elements = []\n\n    def add_element(self,element):\n        self.elements.append(element)\n        print(f'{element} ha sido agregado con exito al queue')\n    \n    def delete_element(self):\n        if self.count_elements() == 0:\n            print(0)\n        else:\n            print(f\"{self.elements.pop(0)} ha sido eliminado del queue\")\n    \n    def show_elements(self):\n        print(f\"Los elementos presentes en el queue son {self.elements}\")\n\n    def count_elements(self):\n        print(f\"hay {len(self.elements)} elementos en el queue \")\n\nmy_queue = Queue()\nmy_queue.count_elements()\nmy_queue.add_element('raul')\nmy_queue.add_element(\"yander\")\nmy_queue.show_elements()\nmy_queue.count_elements()\nmy_queue.delete_element()\nmy_queue.count_elements()"
  },
  {
    "path": "Roadmap/08 - CLASES/python/raynerpv2022.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n#  * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n#  * de tu lenguaje).\n#  * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n#  * utilizando su función.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n#  * en el ejercicio número 7 de la ruta de estudio)\n#  * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n#  *   retornar el número de elementos e imprimir todo su contenido.\n#  * \n#  */\n\nclass Pila_o_Cola:\n    def __init__(self,init_value = None) -> None:\n        if init_value == None:\n            init_value = []\n        self.__list_value = init_value\n\n    def add(self):\n        print(\" A rellenar , entra un elemento : \")\n        item = input()\n        self.__list_value.append(item)\n\n    def is_empty(self):\n        return self.__list_value == []\n\n    def items_count(self):\n        if not self.is_empty():\n            print(f\"There are  {len(self.__list_value)} Items \")\n            return  \n        print(\"eEmpty List... Add first\")\n    \n    def print_items(self):\n        if not self.is_empty():\n            print(\" Mostrando elementos ... : \")\n            print(self.__list_value)\n            return\n        print(\"eEmpty List... Add first\")\n\n\n    def delete_one_value(self, index=None):\n        if not self.is_empty():\n            if index == None :\n                index = len (self.__list_value)-1\n            return self.__list_value.pop(index)\n        \n        \n\n\nclass Pila(Pila_o_Cola):\n    \n    def delete_lifo(self):\n        if not super().is_empty():\n            print(\" Deleting  LIFO  ... : \")\n            print(f\"Item {self.delete_one_value()} deleted succesfully \")\n            return\n        print(\"Empty List... Add first\")\n    \n    \nclass Cola(Pila_o_Cola):\n     \n    def delete_fifo(self):\n        if not super().is_empty():\n            print(\" Deleting  FIFO  ... : \")\n            print(f\"Item {self.delete_one_value(0)} deleted succesfully \")\n            return\n        print(\"Empty List... Add first\")\n\n\npila = Pila()\ncola = Cola()\npoc = \"\"\nwhile True:\n    print(\"PIla (P)  o  COLA (C)  Quit (Q) ?\")\n    pc = input()\n    if pc == \"P\":\n        poc = \"Pila\"\n    elif pc == \"C\":\n            poc = \"Cola\"\n    elif pc == \"Q\":\n        break\n    else :\n        print(\"Enter only P, C or Q\")\n        continue\n\n    while True:\n    \n        print(f\" What do you want to do with {poc} : \")\n        print(\"1 - ) ADD\")\n        print(\"2 - ) PRINT\")\n        print(\"3 - ) How many Items are there\")\n        print(\"4 - ) REMOVE\")\n        print(\"5 - ) EXIT\")\n        op = input()\n        match op:\n            case \"1\":\n                \n                pila.add() if pc == \"P\" else cola.add()\n            case \"2\":\n                pila.print_items()   if pc == \"P\" else cola.print_items()\n            case \"3\":\n                pila.items_count()  if pc == \"P\" else cola.items_count()\n            case \"4\":\n                pila.delete_lifo()  if pc == \"P\" else cola.delete_fifo()\n            case \"5\":\n                print(\"EXIT now.. ... \")\n                break\n            case _:\n                print(\"Enter number between 1 and 5 , try again\")         \n                \n\n    \n\n\n    \n    \n    \n\n\n\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/restevean.py",
    "content": "class Vehicle:\n    def __init__(self):\n        self.state = \"stopped\"\n        self.speed = 0\n\n    def accelerate(self):\n        self.speed += 10\n        self.state = \"running\"\n\n    def brake(self):\n        self.speed -= 10\n        if self.speed < 0:\n            self.speed = 0\n        if self.speed == 0:\n            self.state = \"stopped\"\n\n\n# Stack (LIFO)\nclass Stack:\n    def __init__(self):\n        self.stack = []\n\n    def push(self, item):\n        self.stack.append(item)\n\n    def pop(self):\n        if not self.is_empty():\n            stack_item = self.stack[len(self.stack) - 1]\n            del self.stack[len(self.stack) - 1]\n            return stack_item\n\n    def is_empty(self):\n        return len(self.stack) == 0\n\n    def count(self):\n        return len(self.stack)\n\n\n# Queue (FIFO)\nclass Queue:\n    def __init__(self):\n        self.queue = []\n\n    def enqueue(self, item):\n        self.queue.append(item)\n\n    def dequeue(self):\n        if not self.is_empty():\n            queue_item = self.queue[0]\n            del self.queue[0]\n            return queue_item\n\n    def is_empty(self):\n        return len(self.queue) == 0\n\n    def count(self):\n        return len(self.queue)\n\n\ndef main():\n\n    # Vehicle\n    car = Vehicle()\n    print(car.state)\n    print(car.speed)\n    car.accelerate()\n    print(car.state)\n    print(car.speed)\n\n    # Stack\n    stack = Stack()\n    stack.push(1)\n    stack.push(2)\n    stack.push(3)\n    print(stack.stack)\n\n    print(f\"stack elements count: {stack.count()}\")\n    print(stack.pop())\n    print(stack.pop())\n    print(stack.pop())\n    print(stack.pop())\n\n    # Queue\n    queue = Queue()\n    queue.enqueue(1)\n    queue.enqueue(2)\n    queue.enqueue(3)\n    print(queue.queue)\n\n    print(f\"queue elements count: {queue.count()}\")\n    print(queue.dequeue())\n    print(queue.dequeue())\n    print(queue.dequeue())\n    print(queue.dequeue())\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/rigo93acosta.py",
    "content": "'''\n/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n *\n */\n'''\n\n\"\"\"\nEjercicios\n\"\"\"\n\nclass Programmer:\n\n    surname: str = None\n\n    def __init__(self, name: str, age: int, language: list) -> None:\n        self.name = name\n        self.age = age\n        self.language = language\n\n    def print(self):\n        print(f\"Name: {self.name} | Apellido: {self.surname} | Age: {self.age} | Language: {self.language}\")\n\n\nProgrammer1 = Programmer(\"Rigo\", 30, [\"Python\", \"Java\", \"C++\"])\nProgrammer1.surname = \"Acosta\"\nProgrammer1.print()\nProgrammer1.age = 31\nProgrammer1.print()\n\n\"\"\"\nExtra\n\"\"\"\n\n## LIFO\n\nclass Stack:\n\n    def __init__(self) -> None:\n        self.stack = []\n\n    def push(self, value):\n        self.stack.append(value)\n\n    def pop(self):\n        if self.size() == 0:\n            return None\n        return self.stack.pop()\n\n    def print(self):\n        for item in self.stack[::-1]:\n            print(item)\n\n    def size(self):\n        return len(self.stack)\n\nmy_stack = Stack()\nmy_stack.push(\"A\")\nmy_stack.push(\"B\")\nmy_stack.push(\"C\")\nmy_stack.print()\nprint(my_stack.size())\nmy_stack.pop()\nmy_stack.print()\n\n## FIFO\n\nclass Queue:\n\n    def __init__(self) -> None:\n        self.queue = []\n\n    def equeue(self, value):\n        self.queue.append(value)\n\n    def dequeue(self):\n        if self.size() == 0:\n            return None\n        return self.queue.pop(0)\n\n    def print(self):\n        for item in self.queue:\n            print(item)\n\n    def size(self):\n        return len(self.queue)\n\nmy_queue = Queue()\nmy_queue.equeue(\"A\")\nmy_queue.equeue(\"B\")\nmy_queue.equeue(\"C\")\nmy_queue.print()\nprint(my_queue.size())\nmy_queue.dequeue()\nmy_queue.dequeue()\nmy_queue.print()\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/rikmij.py",
    "content": "class Mobile:\n    brand = \"Samsung\"\n\n    def __init__(self, model, color, camera) -> None:\n        self.model = model\n        self.color = color\n        self.camera = camera\n    \n    def saludo(self):\n        return f\"{self.brand} {self.model}: color {self.color} y cámara de {self.camera}\"\n\nmovil1 = Mobile(\"S24+\", \"Azul\", \"50MP\")\nmovil2 = Mobile(\"ZFlip5\", \"Verde\", \"12MP\")\nmovil3 = Mobile(\"A54 5G\", \"Negro\", \"50MP\")\n\nprint(movil1.saludo())\nprint(movil2.saludo())\nprint(movil3.saludo())\n\n\nprint('\\n','~'*7, \"EJERCICIOS EXTRA\", '~'*7)\n\nclass Queue:\n    def __init__(self, *args):\n        self.cola = list(args)\n    \n    def add_queue_component(self, *elem):\n        for e in elem:\n            self.cola.append(e)\n    \n    def remove_queue_component(self):\n        self.cola.pop(0)\n    \n    def peek_queue_component(self):\n        return self.cola[0]\n\nprint('\\n -> QUEUES')\nqueue = Queue(1, 2, 3, 4, 5)\nprint(queue.cola)\n\nqueue.add_queue_component(6, 7, 8, 9)\nprint(queue.cola)\n\nqueue.remove_queue_component()\nprint(queue.cola)\n\nprint(queue.peek_queue_component())\n\n\nclass Stack:\n    def __init__(self, *args):\n        self.pila = list(args)\n    \n    def add_stack_component(self, *elem):\n        for e in elem:\n            self.pila.append(e)\n    \n    def remove_stack_component(self):\n        self.pila.pop(len(self.pila)-1)\n    \n    def peek_stack_component(self):\n        return self.pila[len(self.pila)-1]\n\nprint('\\n -> STACKS')\nstack = Stack(\"Uno\", \"Dos\", \"Tres\")\nprint(stack.pila)\n\nstack.add_stack_component(\"Cuatro\", 5)\nprint(stack.pila)\n\nstack.remove_stack_component()\nprint(stack.pila)\n\nprint(stack.peek_stack_component())\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/santiagobailleres.py",
    "content": "'''EJERCICIO:\nExplora el concepto de clase y crea un ejemplo que implemente un inicializador,\natributos y una función que los imprima (teniendo en cuenta las posibilidades\nde tu lenguaje).\nUna vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\nutilizando su función.\nDIFICULTAD EXTRA (opcional):\nImplementa dos clases que representen las estructuras de Pila y Cola (estudiadas\nen el ejercicio número 7 de la ruta de estudio)\n- Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\nretornar el número de elementos e imprimir todo su contenido.'''\n\n# Clase/class: es un molde para crear objetos. Un objeto es una instancia de una clase.\n# Atributos/atributes: son las características que tiene un objeto.\n# Métodos/methods: son las acciones que puede realizar un objeto. \n# Constructor/initializer: es un método que se llama cuando se crea un objeto.\n# self: es una referencia al objeto que se está creando.\n# __init__: es el método constructor de una clase.\n# __str__: es el método que se llama cuando se imprime un objeto.\n\nclass Persona:\n    surname: str = None # surname es un atributo de clase\n    def __init__(self, name: str, age: int, habilidades: list):\n        self.name = name\n        self.age = age\n        self.habilidades = habilidades\n    \n    def __str__(self):\n        return f'Nombre: {self.name}, Apellido: {self.surname}, Age: {self.age}, Habilidades: {self.habilidades}'\n\nmi_persona = Persona('Santiago', 24, ['Python', 'SQL'])\nmi_persona.surname = 'Bailleres'\nprint(mi_persona)\nmi_persona.age = 25\nprint(mi_persona)\n\n# EXTRA\n# Clase Pila (Stack) LIFO\nclass Pila:\n    def __init__(self): # self es una referencia al objeto que se está creando \n        self.items = []\n    \n    def push(self, item):\n        self.items.append(item)\n    \n    def pop(self):\n        if self.count() == 0:\n            return None\n        return self.items.pop()\n    \n    def count(self):\n        return len(self.items)\n    \n    def print(self):\n        for item in reversed(self.items):\n            print(item)\n\nmi_pila = Pila()\nmi_pila.push(1)\nmi_pila.push(2)\nmi_pila.push(3)\nprint(mi_pila.count())\nmi_pila.print()\nmi_pila.pop()\nprint(mi_pila.count())\nprint('---')\nprint(mi_pila.pop())\nprint(mi_pila.pop())\nprint(mi_pila.pop())\nprint(mi_pila.pop())\nprint(mi_pila.count())\nprint('---')\n\n# Clase Cola (Queue) FIFO\nclass Cola:\n    def __init__(self):\n        self.queue = []\n    \n    def enqueue(self, item):\n        self.queue.append(item)\n    \n    def dequeue(self):\n        if self.count() == 0:\n            return None\n        return self.queue.pop(0)\n    \n    def count(self):\n        return len(self.queue)\n    \n    def print(self):\n        for item in self.queue:\n            print(item)\n\nmi_cola = Cola()\nmi_cola.enqueue('A')\nmi_cola.enqueue('B')\nmi_cola.enqueue('C')\nprint(mi_cola.count())\nprint('---')\nmi_cola.print()\nmi_cola.dequeue()\nprint(mi_cola.count())\nprint('---')\nprint(mi_cola.dequeue())\nprint(mi_cola.dequeue())\nprint(mi_cola.dequeue())\nprint(mi_cola.dequeue())\nprint(mi_cola.count())"
  },
  {
    "path": "Roadmap/08 - CLASES/python/santyjL.py",
    "content": "#08 CLASES\n\"\"\"\n/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n */\n\"\"\"\n\n\nclass Iphone:\n    def __init__(self) :\n        self.nombre = \"iPhone15\"\n        self.camara = \"12MP\"\n        self.almacenamiento = \"265GB\"\n        self.ram = \"8GB\"\n\n    def presentacion(self):\n        return f\"\"\"\n    Nombre: {self.nombre}\n    Camara: {self.camara}\n    Almacenamiento: {self.almacenamiento}\n    Ram: {self.ram}\n    \"\"\"\n\nclass Telefono:\n    def __init__(self , nombre :str , camara : str , almacenamiento : str , ram : str ) -> str:\n        self.nombre = nombre\n        self.camara = camara\n        self.almacenamiento = almacenamiento\n        self.ram = ram\n\n    def presentacion(self):\n        return f\"\"\"\n    Nombre: {self.nombre}\n    Camara: {self.camara}\n    Almacenamiento: {self.almacenamiento}\n    Ram: {self.ram}\n    \"\"\"\n\niphone15 = Iphone()\nprint(iphone15.presentacion())\n\nSansung_S23 = Telefono(\"Sansung S23\", \"200MP\" ,\"256GB\" , \"8GB\" )\nprint(Sansung_S23.presentacion())\n\n### Extra\nclass Pila:\n    def __init__(self):\n        self.pila : list = []\n\n    def añadir (self , elemento_a_añadir):\n        self.pila.append(elemento_a_añadir)\n\n    def eliminar(self):\n        del self.pila[-1]\n\n    def ultimo_elemento(self):\n        print(self.pila[-1])\n\n    def pila_actual(self):\n        print(self.pila)\n\n\nclass Cola:\n    def __init__(self) :\n        self.cola : list = []\n\n    def añadir(self , elemento_a_añadir):\n        self.cola.append(elemento_a_añadir)\n        print(\"se añadio el elemento\")\n\n    def eliminar(self):\n        del self.cola[0]\n        print(\"se elimino el elemento\")\n\n    def primer_elemento(self):\n        print(self.cola[0])\n\n    def cola_actual(self):\n        print(self.cola)\n\ncola = Cola()\npila = Pila()\n\nwhile True :\n    pila_cola = int(input(\"que vas a usar? , colas(1) , pilas(2) o salir(3) : \"))\n\n    if pila_cola == 1 :\n\n        while True :\n            print(\"\"\"\n                1.añadir\n                2.eliminar\n                3.primer_elemento\n                4.cola_actual\n                5.salir\n                \"\"\")\n            try:\n                decicion = int(input(\"eliga segun el indice : \"))\n            except Exception as error:\n                print(\" ha habido un error que es : \" , error)\n\n\n            if decicion == 1:\n                elemento = input(\"elemento a añadir : \")\n                cola.añadir(elemento)\n\n            elif decicion == 2:\n                cola.eliminar()\n\n            elif decicion == 3:\n                cola.primer_elemento()\n\n            elif decicion == 4:\n                cola.cola_actual()\n\n            elif decicion == 5 :\n                break\n\n            else :\n                print(\"opcion no existente\")\n\n\n    elif pila_cola == 2:\n        while True:\n            print(\"\"\"\n                1.añadir\n                2.eliminar\n                3.ultimo_elemento\n                4.pila_actual\n                5.salir\n                \"\"\")\n            try:\n                decicion = int(input(\"eliga segun el indice : \"))\n            except Exception as error:\n                print(\"ha habido un error el cual es : \" , error)\n\n\n            if decicion == 1:\n                elemento = input(\"elemento a añadir : \")\n                pila.añadir(elemento)\n\n            elif decicion == 2:\n                pila.eliminar()\n\n            elif decicion == 3:\n                pila.ultimo_elemento()\n\n            elif decicion == 4:\n                pila.pila_actual()\n\n            elif decicion == 5 :\n                break\n\n            else :\n                print(\"opcion no existente\")\n\n    elif pila_cola == 3:\n        break\n\n    else :\n        print(\"opcion no correcta\")"
  },
  {
    "path": "Roadmap/08 - CLASES/python/sorubadguy.py",
    "content": "import time\n\"\"\"\n*Clases\n\"\"\"\n\n#?Ejemplo de definicion de clase\nclass Perro:\n\n    #?Atributo general de la clase\n    \n    \n    #?Inicializador de la clase\n    def __init__(self, nombre: str):\n        self.nombre = nombre #?Atributo unico para cada instancia\n        self.trucos = [] #?Si la lista estuviese como atributo general, todas las instancias de esta clase compartirian la misma lista\n\n    def agregar_truco(self, truco):\n        self.trucos.append(truco)\n\nperro1 = Perro(\"Gero\")\nperro2 = Perro(\"Mily\")\n\nperro1.agregar_truco(\"saltar\")\nperro1.agregar_truco(\"voltereta\")\nperro2.agregar_truco(\"dar la pata\")\n\nprint(f\"{perro1.nombre} puede hacer los siguientes trucos: {perro1.trucos}\")\nprint(f\"{perro2.nombre} puede hacer los siguientes trucos: {perro2.trucos}\")\n\n#?Herencia, raza tiene las mismas caracteristicas de perro, ademas de las suyas propias\n\nclass Raza(Perro):#!Las clases pueden heredar tambien 2 o mas clases base\n\n    def __init__(self, nombre: str, color_pelo: str, tipo_pelo: str, altura: float, raza = \"puro perro\"):\n        super().__init__(nombre)\n        self.raza = raza\n        self.color_pelo = color_pelo\n        self.tipo_pelo = tipo_pelo\n        self.altura = altura\n\n    def mostrar_raza(self):\n        print(f\"Raza: {self.raza}\\nTipo de Pelo: {self.tipo_pelo}\\nColor del Pelo: {self.color_pelo}\\nAltura: {self.altura} mt(s)\")\n\nperro3 = Raza(\"pancho\", \"marron\", \"corto\", 1.2)\nperro3.agregar_truco(\"Hacerce el muertito\")\nperro3.mostrar_raza()\nprint(perro3.trucos) #?caracteristica de la clase perro, heredada por raza\n\n\"\"\"\n!Extra\n\"\"\"\n\"\"\"\n*Clase Pila\n\"\"\"\nclass Pila:\n\n    def __init__(self, pila = []) -> None:\n        self.pila = []\n        if len(pila) == 0:\n            self.pila = []\n        else:\n            for i in range(0, len(pila)):\n                self.pila.append(pila[i])\n\n\n    def tamano_pila(self):\n        print(f\"La pila posee {len(self.pila)} elementos\")\n\n    def anadir_elemento(self):\n        self.pila.append(input(\"Ingrese el valor a agregar: \"))\n    \n    def quitar_elemento(self):\n        self.pila.pop()\n    \n    def mostrar_contenido(self):\n        elemento = self.pila.pop()\n        print(elemento)\n        if(len(self.pila) > 0):\n            self.mostrar_contenido()\n        self.pila.append(elemento)\n\n\npila = Pila([1,2,3,4,5,6,7,8,9])\npila.tamano_pila()\npila.mostrar_contenido()\n#pila.anadir_elemento()\npila.tamano_pila()\npila.mostrar_contenido()\npila.quitar_elemento()\npila.mostrar_contenido()\n\n\"\"\"\n*Clase Cola\n\"\"\"\n\nclass Cola:\n\n    def __init__(self, cola = []) -> None:\n        self.cola = []\n        if len(cola) == 0:\n            self.cola = []\n        else:\n            for i in range(0, len(cola)):\n                self.cola.append(cola[i])\n\n    def tamano_cola(self):\n        print(f\"La cola posee {len(self.cola)} elementos\")\n\n    def anadir_elento(self):\n        self.cola.append(input(\"Ingrese el valor a agregar: \"))\n\n    def quitar_elemento(self):\n        self.cola.pop(0)\n\n    def mostrar_contenido(self):\n        for i in range(0, len(self.cola)):\n            print(self.cola[i])\n\n\ncola = Cola([1,2,3,4,5,6,7,8,9])\ncola.anadir_elento()\ncola.tamano_cola()\ncola.quitar_elemento()\ncola.tamano_cola()\ncola.mostrar_contenido()"
  },
  {
    "path": "Roadmap/08 - CLASES/python/sperezsa.py",
    "content": "#08 - CLASES\n\nclass Person:\n    def __init__(self, id: int, name: str):\n        self.id = id\n        self.name =  name\n        \n    def imprimir(self):\n        print(f\"id: {self.id} y nombre: {self.name}\")\n\n\nmy_person = Person('Jose', 1)\nmy_person.name = 'Pepe'\nmy_person.id = 11\nmy_person.imprimir()\n\n\"\"\"\nExtra\n\"\"\"\n\n# LIFO\nclass Stack:\n    def __init__(self):\n        self.stack = []\n        \n    def add_stack(self, item):\n        self.stack.append(item)\n        \n    def del_stack(self):\n        if self.count() == 0:\n            return None\n        return self.stack.pop()\n    \n    def count(self):\n        return len(self.stack)\n    \n    def print(self):\n        for i in reversed(self.stack):\n            print(i)\n        \nprint(\"PILA\")   \npila = Stack() \npila.add_stack(1)\npila.add_stack(2)\npila.add_stack(3)\nprint(pila.count())\npila.del_stack()\npila.print()  \n\n\n# FIFO\nclass Queue:\n    def __init__(self):\n        self.queue = []\n        \n    def add_queue(self, item):\n        self.queue.append(item)\n        \n    def del_queue(self):\n        if self.count() == 0:\n            return None\n        return self.queue.pop(0)\n    \n    def count(self):\n        return len(self.queue)\n    \n    def print(self):\n        for i in self.queue:\n            print(i)\n\nprint(\"COLA\")  \ncola = Queue() \ncola.add_queue(1)\ncola.add_queue(2)\ncola.add_queue(3)\ncola.add_queue(4)\ncola.add_queue(5)\nprint(cola.count())\ncola.print()  \ncola.del_queue()\ncola.print()  \n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/switchdays.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n\"\"\"\n\nclass Perro:\n\n    # Clase con constructor:\n    def __init__(self, color, raza, nombre, numero_patas=4):\n\n        self.color = color\n        self.numero_patas = numero_patas\n        self.raza = raza\n        self.nombre = nombre\n\n\ndef imprimir():\n    perro = Perro(\"negro\", \"pitbull\", \"toby\")\n\n    print(f\"Color: {perro.color}\")\n    print(f\"Número de patas: {perro.numero_patas}\")\n    print(f\"Raza: {perro.raza}\")\n    print(f\"Nombre: {perro.nombre}\")\n\nimprimir()\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n * \n\"\"\"\n\nprint(\"\\n================================\\n\")\n\nclass Pila:\n\n    def __init__(self):\n        self.pila = []\n\n    def añadir(self, elemento):\n        self.pila.append(elemento)\n\n    def eliminar(self):\n        self.pila.pop()\n    \n    def numero_elementos(self):\n        numero_elementos = len(self.pila)\n        return numero_elementos\n    \n    def imprimir(self):\n        print(\"Contenido de la pila:\")\n        index = 0\n        for i in self.pila:\n            print (index,\": \", i)\n            index += 1\n\n\npila = Pila()\npila.añadir(\"Manolo\")\npila.añadir(\"Benito\")\npila.añadir(\"Martinez\")\npila.añadir(\"Ocasio\")\nprint(f\"Número de elementos de la pila: {pila.numero_elementos()}\")\npila.imprimir()\npila.eliminar()\nprint(f\"Número de elementos de la pila: {pila.numero_elementos()}\")\npila.imprimir()\n\n\nprint(\"\\n================================\\n\")\n\n\nclass Cola:\n    \n    def __init__(self):\n        self.cola = []\n\n    def añadir(self, elemento):\n        self.cola.append(elemento)\n\n    def eliminar(self):\n        self.cola.pop(0)\n    \n    def numero_elementos(self):\n        numero_elementos = len(self.cola)\n        return numero_elementos\n    \n    def imprimir(self):\n        print(\"Contenido de la cola:\")\n        index = 0\n        for i in self.cola:\n            print (index,\": \", i)\n            index += 1\n\ncola = Cola()\ncola.añadir(\"Manolo\")\ncola.añadir(\"Benito\")\ncola.añadir(\"Martinez\")\ncola.añadir(\"Ocasio\")\nprint(f\"Número de elementos de la cola: {cola.numero_elementos()}\")\ncola.imprimir()\ncola.eliminar()\nprint(f\"Número de elementos de la cola: {cola.numero_elementos()}\")\ncola.imprimir()"
  },
  {
    "path": "Roadmap/08 - CLASES/python/thonys07.py",
    "content": "'''\n\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n\n\n'''\n\nclass Pokemon:\n\n    def __init__(self, nombre:str, tipo:str, ataque:str, ataque_especial:str, vida:int, cp:int):\n        self.nombre=nombre\n        self.tipo=tipo       \n        self.ataque=ataque\n        self.ataque_especial=ataque_especial\n        self.vida=vida\n        self.cp=cp\n    \n    def atacar(self):\n        print(self.nombre +\" usó \" + self.ataque + \" para atacar \\ny causó \" + str(self.cp/4) + \" puntos de daño al inimigo!\")\n        return self.ataque\n    def atacar_especial(self):\n        print(self.nombre +\" usó \" + self.ataque_especial + \" para atacar \\ny causó \" + str(self.cp*1.5) + \" puntos de daño al inimigo!\")\n        return self.ataque_especial\n\nsquirtle=Pokemon(\"Squirtle\",\"agua\",\"chorro de agua\",\"cañon de agua\",82,105)\nprint(squirtle)\nsquirtle.atacar()\nsquirtle.atacar_especial()\n\n\n#EXTRA\n\nclass Pila:\n    def __init__(self):\n        self.elementos = []\n    \n    def apilar(self, item):\n        self.elementos.append(item)\n    \n    def desapilar(self):\n        if not self.esta_vacia():\n            return self.elementos.pop()\n        else:\n            return \"La pila está vacía\"\n    \n    def esta_vacia(self):\n        return len(self.elementos) == 0\n    \n    def numero_de_elementos(self):\n        return len(self.elementos)\n    \n    def imprimir_contenido(self):\n        print(\"Contenido de la pila:\", self.elementos)\n\n# Ejemplo de uso de la clase Pila\npila = Pila()\npila.apilar(1)\npila.apilar(2)\npila.apilar(3)\npila.imprimir_contenido()\nprint(\"Desapilando:\", pila.desapilar())\npila.imprimir_contenido()\nprint(\"Número de elementos en la pila:\", pila.numero_de_elementos())\n\nclass Cola:\n    def __init__(self):\n        self.elementos = []\n    \n    def encolar(self, item):\n        self.elementos.append(item)\n    \n    def desencolar(self):\n        if not self.esta_vacia():\n            return self.elementos.pop(0)\n        else:\n            return \"La cola está vacía\"\n    \n    def esta_vacia(self):\n        return len(self.elementos) == 0\n    \n    def numero_de_elementos(self):\n        return len(self.elementos)\n    \n    def imprimir_contenido(self):\n        print(\"Contenido de la cola:\", self.elementos)\n\n# Ejemplo de uso de la clase Cola\ncola = Cola()\ncola.encolar(1)\ncola.encolar(2)\ncola.encolar(3)\ncola.imprimir_contenido()\nprint(\"Desencolando:\", cola.desencolar())\ncola.imprimir_contenido()\nprint(\"Número de elementos en la cola:\", cola.numero_de_elementos())\n\n\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/tito-delpino.py",
    "content": "#  * EJERCICIO:\n#  * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n#  * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n#  * de tu lenguaje).\n#  * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n#  * utilizando su función.\n\nclass ClasePrincipal:\n    def __init__(self, atributo1, atributo2, atributo3):\n        self.atributo = atributo1\n        self.atributo2 = atributo2\n        self.atributo3 = atributo3\n\n    def impresion(self):\n        print(f'{self.atributo},{self.atributo2} o {self.atributo3}...una...dos...tres!')\n\nopciones = ClasePrincipal('piedra','piedra', 'tijera') # creamos el objeto de clase, agregamos los atributos\n\nopciones.impresion() # usamos la funcion de la clase, para la impresion\nopciones.atributo2 = 'papel' # modificamos atributo\nopciones.impresion() \n\nprint('/' * 50)\n#  * DIFICULTAD EXTRA (opcional):\n#  * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n#  * en el ejercicio número 7 de la ruta de estudio)\n#  * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n#  *   retornar el número de elementos e imprimir todo su contenido.\n\nclass Pila():\n    def __init__(self):\n        self.listado = []\n    \n    def agregar_elementos(self, elemento):\n        if elemento in self.listado:\n            print('Ese elemento ya esta en la lista')\n        else:\n            print(f'Elemento {elemento} agregado a la lista')\n            self.listado.append(elemento)\n    \n    def eliminar_elementos(self):\n        if self.contar_elementos == 0:\n            print('Lista vacias')\n        else:\n            print(f'Elemento {self.listado[-1]} eliminado de la lista')\n            return self.listado.pop()\n\n    def contar_elementos(self):\n        return len(self.listado)\n    \n    def impresion_lista(self):\n        print('Listado actual:')\n        for elemento in self.listado[::-1]:\n            print(elemento)\n\npila = Pila()\n\npila.agregar_elementos('A')\npila.agregar_elementos('B')\nprint(pila.contar_elementos())\npila.agregar_elementos('C')\nprint(pila.contar_elementos())\npila.impresion_lista()\n\npila.eliminar_elementos()\npila.impresion_lista()\npila.eliminar_elementos()\npila.impresion_lista()\n\nprint('--------------------------------------------------------------------------------')\nclass Cola():\n    def __init__(self):\n        self.listado_cola = []\n    \n    def agregar_elementos(self, elemento):\n        if elemento in self.listado_cola:\n            print('Ese elemento ya esta en la lista')\n        else:\n            print(f'Elemento {elemento} agregado a la lista')\n            self.listado_cola.append(elemento)\n    \n    def eliminar_elementos(self):\n        if self.contar_elementos == 0:\n            print('Lista vacias')\n        else:\n            print(f'Elemento {self.listado_cola[-1]} eliminado de la lista')\n            return self.listado_cola.pop(0)\n\n    def contar_elementos(self):\n        return len(self.listado_cola)\n    \n    def impresion_lista(self):\n        print('Listado actual:')\n        for elemento in self.listado_cola:\n            print(elemento)\n\ncola = Cola()\n\ncola.agregar_elementos('A')\ncola.agregar_elementos('B')\nprint(cola.contar_elementos())\ncola.agregar_elementos('C')\nprint(cola.contar_elementos())\ncola.impresion_lista()\n\ncola.eliminar_elementos()\ncola.impresion_lista()\ncola.eliminar_elementos()\ncola.impresion_lista()"
  },
  {
    "path": "Roadmap/08 - CLASES/python/victorfer69.py",
    "content": "#Clases\n\nclass Programmer:\n\n    surname = None\n    \n    def __init__(self, name: str, age: int, languages: list):\n        self.name = name\n        self.age = age\n        self.languajes = languages\n\n    def print(self):\n        print(f\"Nombre: {self.name} | Apellido: {self.surname} | Edad: {self.age} | Lenguajes {self.languajes}\")\n\nmy_programmer = Programmer(\"Victor\", 21, [\"Python\", \"Java\", \"Swift\"])\nmy_programmer.print()\nmy_programmer.surname = \"Fer\"\nmy_programmer.print()\nmy_programmer.age = 22\nmy_programmer.print()\n\n\n#EJERCICIO EXTRA\n\n#Pila\nclass Stack():\n\n    def __init__(self):\n        self.stack = []\n\n    def agregarItem(self, item):\n        self.stack.append(item)\n\n    def sacarItem(self):\n        if self.numElem() == 0:\n            return None\n        self.stack.pop()\n\n    def numElem(self):\n        return len(self.stack)\n\n    def print(self):\n        if self.numElem() == 0:\n            print(\"Pila vacia\")\n        else:    \n            for i in reversed(self.stack):\n                print(i)\n\n\nmy_stack = Stack()\nmy_stack.agregarItem(\"A\")\nmy_stack.agregarItem(\"B\")\nmy_stack.agregarItem(\"C\")\nmy_stack.agregarItem(\"D\")\nprint(my_stack.numElem())\nmy_stack.print()\nmy_stack.sacarItem()\nmy_stack.sacarItem()\nmy_stack.sacarItem()\nmy_stack.sacarItem()\nmy_stack.sacarItem()\nmy_stack.sacarItem()\nprint(my_stack.numElem())\nmy_stack.print()\n\n#Cola\n\nclass Queue():\n\n    def __init__(self):\n        self.queue = []\n\n    def agregarItem(self, item):\n        self.queue.append(item)\n\n    def sacarItem(self):\n        if self.numElem() == 0:\n            return None\n        self.queue.pop()\n\n    def numElem(self):\n        return len(self.queue)\n\n    def print(self):\n        if self.numElem() == 0:\n            print(\"Cola vacia\")\n        else:    \n            for i in self.queue:\n                print(i)\n\n\nmy_queue = Queue()\nmy_queue.agregarItem(\"A\")\nmy_queue.agregarItem(\"B\")\nmy_queue.agregarItem(\"C\")\nmy_queue.agregarItem(\"D\")\nprint(my_queue.numElem())\nmy_queue.print()\nmy_queue.sacarItem()\nmy_queue.sacarItem()\nmy_queue.sacarItem()\nmy_queue.sacarItem()\nmy_queue.sacarItem()\nmy_queue.sacarItem()\nprint(my_queue.numElem())\nmy_queue.print()"
  },
  {
    "path": "Roadmap/08 - CLASES/python/warclimb.py",
    "content": "\"\"\" * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n\"\"\"\n\nclass Vehiculo():\n    def __init__(self, marca, modelo, año):\n        self._marca = marca\n        self._modelo = modelo\n        self._año = año\n\n    # getters y setters\n    @property\n    def marca(self):\n        return self._marca\n    \n    @marca.setter\n    def marca(self, marca):\n        self._marca = marca\n    \n    @property\n    def modelo(self):\n        return self._modelo\n\n    @modelo.setter\n    def modelo(self, modelo):\n        self._modelo = modelo\n    \n    @property\n    def año(self):\n        return self._año\n    \n    @año.setter\n    def año(self, año):\n        self._año = año\n\n# Creo un vehículo\ncoche = Vehiculo(\"Ford\", \"Fiesta\", 2010)\n\n# muestra atributos del coche\nprint(f\"Caracteristicas del vehículo:\")\nfor attr, value in coche.__dict__.items():\n    print(f\"{value}\")\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\"\"\"\n\nclass Pila:\n    def __init__(self):\n        self.items = []\n\n    def esta_vacia(self):\n        return self.items == []\n\n    def agregar(self, item):\n        self.items.append(item)\n\n    def eliminar(self):\n        return self.items.pop()\n\n    def num_elementos(self):\n        return len(self.items)\n\n    def imprimir(self):\n        print(\"Elementos en la pila:\")\n        for item in self.items:\n            print(item)\n\n# Ejemplo de uso con cola\nclass Cola:\n    def __init__(self):\n        self.items = []\n\n    def esta_vacia(self):\n        return self.items == []\n\n    def agregar(self, item):\n        self.items.insert(0, item)\n\n    def eliminar(self):\n        return self.items.pop()\n\n    def num_elementos(self):\n        return len(self.items)\n\n    def imprimir(self):\n        print(\"Elementos en la cola:\")\n        for item in self.items:\n            print(item)\n\n\n# testeo\n\nif __name__ == \"__main__\":\n    pila = Pila()\n    pila.agregar(\"Queso\")\n    pila.agregar(\"Pan\")\n    pila.agregar(\"Leche\")\n    pila.agregar(\"Huevos\")\n    pila.imprimir()\n    print(f\"La pila tiene {pila.num_elementos()} elementos.\")\n    print(f\"Eliminamos el elemento {pila.eliminar()}.\")\n    print(f\"La pila tiene {pila.num_elementos()} elementos.\")\n    pila.imprimir()\n\n    cola = Cola()\n    cola.agregar(\"Libros\")\n    cola.agregar(\"Cuadernos\")\n    cola.agregar(\"Lápices\")\n    cola.agregar(\"Borradores\")\n    cola.imprimir()\n    print(f\"La cola tiene {cola.num_elementos()} elementos.\")\n    print(f\"Eliminamos el elemento {cola.eliminar()}.\")\n    print(f\"La cola tiene {cola.num_elementos()} elementos.\")\n    cola.imprimir()"
  },
  {
    "path": "Roadmap/08 - CLASES/python/worlion.py",
    "content": "\"\"\"\nCLASES EN PYTHON 🐍\n\"\"\"\nclass MyFirstClass:\n    \"\"\" My first class in Python\"\"\"\n    atributo_int :int\n    atributo_str :str\n    \n    # En el init le he puesto valores por defecto a los parametros :)  \n    def __init__(self, cantidad=0, texto=\"vacio\") -> None:\n        self.atributo_int = cantidad\n        self.atributo_str = texto\n    \n    def print(self):\n        print(f\"\\t- cantidad: {self.atributo_int}\\t- texto: {self.atributo_str} \")\n\n\nmyObjectEmpty = MyFirstClass()\nmyObjectEmpty.print()\n\nmyObject = MyFirstClass(99, \"Patatin\")\nmyObject.print()\n\nmyObject.atributo_int = 55\nmyObject.atributo_str = \"otro texto\"\nmyObject.print()\n\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\nImplementa dos clases que representen las estructuras de Pila y Cola (estudiadas\nen el ejercicio número 7 de la ruta de estudio)\n- Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n    retornar el número de elementos e imprimir todo su contenido.\n\"\"\"\n\nprint(\"\\n ---- 🌩 DIFICULTAD EXTRA 🌩 ----\\n\")\n\n# Pila / Stack (LIFO)\nclass Stack:\n    \n    data = []\n    \n    def __init__(self) -> None:\n        data = []\n    \n    def push(self, item) -> None:\n        self.data.append(item)\n    \n    def pop(self):\n        if(len(self.data) == 0):\n            print(\"WARN: empty stack!\")\n        else:\n            return self.data.pop()\n    \n    def size(self):\n        return len(self.data)\n    \n    def print(self):\n        print(\"heap\")\n        print(\"  ↓\")\n        print(self.data[::-1])\n\ndef test_stack():\n    print(\"\\n\\n\\t - STACK TEST -\")\n    pila = Stack()\n    pila.push(\"A\")\n    pila.push(\"B\")\n    pila.push(\"C\")\n    pila.print()\n\n    print(f\"pop: {pila.pop()}\")\n    pila.print()\n    print(f\"pop: {pila.pop()}\")\n    pila.print()\n    print(f\"pop: {pila.pop()}\")\n    pila.print()\n    print(f\"pop: {pila.pop()}\")\n    pila.print()\n\ntest_stack()\n\n# Cola / Queue (FIFO)\nclass Queue:\n    \n    data = []\n    def __init__(self) -> None:\n        self.data = []\n        \n    def get(self):\n        if(len(self.data) == 0):\n            # raise Exception(\"Empty queue :(\")\n            print(\"WARN: empty queue!\")\n            return None\n        return self.data.pop(0)\n        \n    def put(self, element):\n        self.data.append(element)\n        \n    def size(self):\n        return len(self.data)\n    \n    def print(self):\n        print(f\"OUTPUT ← :{self.data}: ← INPUT\")\n    \ndef test_queue():\n    print(\"\\n\\n\\t - STACK TEST -\")\n    cola = Queue()\n    cola.put(\"A\")\n    cola.put(\"B\")\n    cola.put(\"C\")\n    cola.print()\n    print(f\"get: {cola.get()}\")\n    cola.print()\n    print(f\"get: {cola.get()}\")\n    cola.print()\n    print(f\"get: {cola.get()}\")\n    cola.print()\n    print(f\"get: {cola.get()}\")\n    cola.print()\n    \ntest_queue()"
  },
  {
    "path": "Roadmap/08 - CLASES/python/xemita007.py",
    "content": "\n\"ejercicio\"\n\n\nclass Pila:\n    \n    def __init__(self):\n        self.var= []\n        \n\n\n    def añadir(self, elmento):\n        self.var.append(elmento)\n        print(f\"Elemento añadido {elmento} a la lista\")\n\n    def eliminar(self):\n        ele_list= self.var[len(self.var)-1]\n        del self.var[len(self.var)-1]\n        print(f\"Elemento {ele_list} eliminadao de la lista\")\n\n\n    def ir_a(self,elemnto):\n        \n        ele_list= self.var.index(f\"{elemnto}\")\n        \n        print(f\"estamos en el el elemento {ele_list} de la lista\")\n\nmi_pila=Pila()\n\nmi_pila.añadir(\"A\")\nmi_pila.añadir(\"B\")\nmi_pila.añadir(\"C\")\nmi_pila.añadir(\"D\")\n\nmi_pila.ir_a(\"C\")\n\nmi_pila.eliminar()\nmi_pila.eliminar()\nmi_pila.eliminar()\nmi_pila.eliminar()\n\n\n\n\nclass Cola:\n\n    def __init__(self) :\n        self.cola=[]\n\n    def añadir(self,elmento):\n        self.cola.append(elmento)\n        print(f\"Elemento {elmento}  añadidoa la lista\")\n\n    def eliminar(self):\n        ele_list= self.cola[0]\n        self.cola.pop(0)\n        print(f\"Elemento {ele_list} eliminadao de la lista\")\n\n    def contar(self):\n        print(f\"hay {len(self.cola)} elementos\") \n\n\nmi_cola=Cola()\n\nmi_cola.añadir(\"a\")\nmi_cola.añadir(\"b\")\nmi_cola.añadir(\"c\")\nmi_cola.añadir(\"d\")\nmi_cola.añadir(\"e\")\n\nmi_cola.contar()\n\nmi_cola.eliminar()\nmi_cola.eliminar()\nmi_cola.eliminar()"
  },
  {
    "path": "Roadmap/08 - CLASES/python/ycanas.py",
    "content": "# ------ Ejercicio\n\nclass Computador:\n\n    def __init__(self, marca, modelo, precio):\n        self.marca = marca\n        self.modelo = modelo\n        self.precio = precio\n\n\n    def print(self):\n        print(f\"Marca: {self.marca} | Modelo: {self.modelo} | Precio: {self.precio}\")\n\n\nlenovo = Computador(\"Lenovo\", \"Legion 5 Pro\", \"8'000.000 COP\")\nlenovo.print()\nlenovo.modelo = \"Ideapad s145\"\nlenovo.precio = \"2'000.000 COP\"\nlenovo.print()\nprint()\n\n\n# ------ Extra\n\n# 1. Pilas\n\nclass Stack:\n\n    # Stack Data Structure\n\n    def __init__(self):\n        self.stack = []\n        \n    def count(self):\n        return len(self.stack)\n    \n    def push(self, item):\n        self.stack.append(item)\n    \n    def pop(self):\n        return None if self.stack == [] else self.stack.pop()\n    \n    def print(self):\n        print(self.stack[::-1])\n    \n\nmy_stack = Stack()\n\nmy_stack.push(\"A\")\nmy_stack.push(\"B\")\nmy_stack.push(\"C\")\nmy_stack.print()\nmy_stack.pop()\nmy_stack.print()\nmy_stack.push(\"C\")\nmy_stack.print()\nmy_stack.push(\"D\")\nmy_stack.print()\nmy_stack.push(\"E\")\nmy_stack.print()\nmy_stack.pop()\nmy_stack.print()\nmy_stack.pop()\nmy_stack.print()\nmy_stack.pop()\nmy_stack.print()\nprint(my_stack.count())\n\nprint()\n\n# 2. Cola\n\nclass Queue:\n\n    # Queue Data Structure\n\n    def __init__(self):\n        self.queue = []\n        \n    def count(self):\n        return len(self.queue)\n    \n    def push(self, item):\n        self.queue.append(item)\n    \n    def pop(self):\n        return None if self.queue == [] else self.queue.pop(0)\n    \n    def print(self):\n        print(self.queue[::-1])\n    \n\nmy_queue = Queue()\n\nmy_queue.push(\"A\")\nmy_queue.push(\"B\")\nmy_queue.push(\"C\")\nmy_queue.print()\nmy_queue.pop()\nmy_queue.print()\nmy_queue.push(\"D\")\nmy_queue.print()\nmy_queue.push(\"E\")\nmy_queue.print()\nmy_queue.push(\"F\")\nmy_queue.print()\nmy_queue.pop()\nmy_queue.print()\nmy_queue.pop()\nmy_queue.print()\nmy_queue.pop()\nmy_queue.print()\nprint(my_queue.count())\n\nprint()\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/yenneralayon142.py",
    "content": "\"\"\"\"\nClases\n\"\"\"\n\nclass Student:\n    surname : str = None\n    def __init__(self, name:str, age:int, notes:list) :\n         self.name = name\n         self.age = age\n         self.notes = notes\n    \n    def print(self):\n      print(\n          f\"name:{self.name},surname:{self.surname} ,age:{self.age}, notes:{self.notes}\"\n      )   \n\nmy_student = Student(\"Yenner Alayon\", 21 ,[12,54,67,87])\nmy_student.print()\nmy_student.surname = \"Benavides\"\nmy_student.print()\nmy_student.age = 22\nmy_student.print()\n\n\n#LIFO\n\nclass Pila:\n\n    def __init__(self):\n        self.pila = []\n    \n    def push(self,item):\n        self.pila.append(item)\n    \n    def pop(self):\n        if self.count() == 0:\n            return None\n        return self.pila.pop()\n\n    def count(self):\n        return len(self.pila)\n\n    def print(self):\n        for i in reversed(self.pila):\n            print(i)\n\nmy_pila = Pila()\nmy_pila.push(\"A\")\nmy_pila.push(\"B\")\nmy_pila.push(\"C\")\nprint(my_pila.count())\nmy_pila.print()\nprint(my_pila.pop())\nmy_pila.print()\nprint(my_pila.pop())\nprint(my_pila.pop())\nprint(my_pila.pop())\nprint(my_pila.count())\n\n\n#FIFO\n\nclass Queue:\n\n    def __init__(self):\n        self.queue = []\n    \n    def enqueue(self,item):\n        self.queue.append(item)\n\n    def dequeue(self):\n        if self.count() == 0:\n            return None\n        return self.queue.pop(0)\n\n    def count(self):\n        return len(self.queue)        \n    \n    def print(self):\n        for i in self.queue:\n            print(i)\n\nmy_queue = Queue()\nmy_queue.enqueue(\"A\")\nmy_queue.enqueue(\"B\")\nmy_queue.enqueue(\"C\")\nprint(my_queue.count())\nmy_queue.print()\nmy_queue.dequeue()\nprint(my_queue.count())\nmy_queue.print()"
  },
  {
    "path": "Roadmap/08 - CLASES/python/yoezequiel.py",
    "content": "class MyClass:\n    def __init__(self, param1, param2):\n        self.attribute1 = param1\n        self.attribute2 = param2\n\n    def print_attributes(self):\n        print(\"Attribute 1:\", self.attribute1)\n        print(\"Attribute 2:\", self.attribute2)\n\n\n# Crear una instancia de MyClass\nmy_instance = MyClass(\"Value 1\", \"Value 2\")\n\n# Imprimir los atributos iniciales\nprint(\"Atributos iniciales:\")\nmy_instance.print_attributes()\n\n# Modificar los atributos\nmy_instance.attribute1 = \"New Value 1\"\nmy_instance.attribute2 = \"New Value 2\"\n\n# Imprimir los atributos modificados\nprint(\"\\nAtributos modificados:\")\nmy_instance.print_attributes()\n\n\nclass Stack:\n    def __init__(self):\n        self.elements = []\n\n    def push(self, element):\n        self.elements.append(element)\n\n    def pop(self):\n        if self.is_empty():\n            return None\n        return self.elements.pop()\n\n    def size(self):\n        return len(self.elements)\n\n    def is_empty(self):\n        return self.size() == 0\n\n    def print_stack(self):\n        print(\"Stack elements:\")\n        for element in self.elements:\n            print(element)\n\n\nclass Queue:\n    def __init__(self):\n        self.elements = []\n\n    def enqueue(self, element):\n        self.elements.append(element)\n\n    def dequeue(self):\n        if self.is_empty():\n            return None\n        return self.elements.pop(0)\n\n    def size(self):\n        return len(self.elements)\n\n    def is_empty(self):\n        return self.size() == 0\n\n    def print_queue(self):\n        print(\"Queue elements:\")\n        for element in self.elements:\n            print(element)\n\n\n# Ejemplo de uso de las clases Stack y Queue\n\n# Crear una instancia de Stack\nmy_stack = Stack()\n\n# Añadir elementos a la pila\nmy_stack.push(1)\nmy_stack.push(2)\nmy_stack.push(3)\n\n# Imprimir la pila\nmy_stack.print_stack()\n\n# Crear una instancia de Queue\nmy_queue = Queue()\n\n# Añadir elementos a la cola\nmy_queue.enqueue(\"a\")\nmy_queue.enqueue(\"b\")\nmy_queue.enqueue(\"c\")\n\n# Imprimir la cola\nmy_queue.print_queue()\n"
  },
  {
    "path": "Roadmap/08 - CLASES/python/zetared92.py",
    "content": "# Reto #08 CLASES\n\nclass Samurai:\n\n    surname: str = None\n\n    def __init__(self, name: str, age: int, affiliation: list):\n        self.name = name\n        self.age = age\n        self.affiliation = affiliation\n\n    def print(self):\n        print(\n            f\"Name: {self.name} | Surname: {self.surname} | Age: {self.age} | Affiliation: {self.affiliation}\"\n        )\n\nthe_samurai = Samurai(\"Johnny\", 34, [\"U.S. Army\", \"Samurai\", \"Silverhand Studios\"])\nthe_samurai.print()\nthe_samurai.surname = \"Silverhand\"\nthe_samurai.print()\nthe_samurai.age = 88\nthe_samurai.print()\n\n\n# Extra\n\nprint(\"🧩 DIFICULTAD EXTRA - IMPLEMENTACIÓN DE DOS CLASES (STACK-QUEUE) 🧩\")\n\n# STACK\n\nclass Stack:\n\n    def __init__(self):\n        self.stack = []\n    \n    def push(self, item):\n        self.stack.append(item)\n    \n    def pop(self):\n        if self.count() == 0:\n            return None\n        return self.stack.pop()\n    \n    def count(self):\n        return len(self.stack)\n    \n    def print(self):\n        for item in reversed(self.stack):\n            print(item)\n\nmy_stack = Stack()\nmy_stack.push(\"X\")\nmy_stack.push(\"Y\")\nmy_stack.push(\"Z\")\nprint(my_stack.count())\nmy_stack.print()\nmy_stack.pop()\nprint(my_stack.count())\nprint(my_stack.pop())\nprint(my_stack.pop())\nprint(my_stack.pop())\nprint(my_stack.pop())\nprint(my_stack.pop())\nprint(my_stack.count())\n\n\n# QUEUE\n\nclass Queue:\n\n    def __init__(self):\n        self.queue = []\n\n    def enqueue(self, item):\n        self.queue.append(item)\n\n    def dequeue(self):\n        if self.count() == 0:\n            return None\n        return self.queue.pop(0)\n    \n    def count(self):\n        return len(self.queue)\n    \n    def print(self):\n        for item in self.queue:\n            print(item)\n\nmy_queue = Queue()\nmy_queue.enqueue(\"X\")\nmy_queue.enqueue(\"Y\")\nmy_queue.enqueue(\"Z\")\nprint(my_queue.count())\nmy_queue.print()\nmy_queue.dequeue()\nprint(my_queue.count())\nprint(my_queue.dequeue())\nprint(my_queue.dequeue())\nprint(my_queue.dequeue())\nprint(my_queue.dequeue())\nprint(my_queue.dequeue())\nprint(my_queue.count())"
  },
  {
    "path": "Roadmap/08 - CLASES/ruby/Elmer125.rb",
    "content": "#  * EJERCICIO:\n#  * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n#  * atributos y una función que los imprima (teniendo en cuenta las posibilidades de tu lenguaje).\n#  * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos utilizando su función.\n\nclass SayHello\n  def initialize(name, age)\n    @name = name\n    @age = age\n  end\n\n  def print_name\n    puts \"Hello #{@name}\"\n  end\n\n  def print_age\n    puts \"You are #{@age} years old\"\n  end\nend\n\nhello_ruby = SayHello.new('Ruby', 10)\n\nhello_ruby.print_name\nhello_ruby.print_age\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n#  * en el ejercicio número 7 de la ruta de estudio)\n#  * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n#  *   retornar el número de elementos e imprimir todo su contenido.\n#  */\n\nclass WebNavigation\n  def initialize\n    @stack = []\n  end\n\n  def navigate(option)\n    unless option == 'exit'\n      case option\n      when 'back'\n        remove_web\n        puts \"You are in #{@stack.first}\"\n      when 'forward'\n        puts \"You are in #{@stack[1]}\"\n      else\n        add_web(option)\n      end\n    end\n  end\n\n  def add_web(web)\n    @stack.unshift(web)\n  end\n\n  def remove_web\n    @stack.shift\n  end\nend\n\nbrowser = WebNavigation.new\n\nbrowser.navigate('google')\nbrowser.navigate('facebook')\nbrowser.navigate('twitter')\nbrowser.navigate('back')\nbrowser.navigate('back')\nbrowser.navigate('exit')\n\nclass SharedPrinter\n  def initialize\n    @queue = []\n  end\n\n  def print_document\n    document = @queue.pop\n    puts \"Printing #{document}\"\n  end\n\n  def add_document(document)\n    puts \"Adding #{document} to the queue\"\n    @queue.push(document)\n  end\nend\n\nprinter = SharedPrinter.new\n\nprinter.add_document('Document 1')\nprinter.add_document('Document 2')\nprinter.add_document('Document 3')\nprinter.print_document\nprinter.print_document\nprinter.print_document\n"
  },
  {
    "path": "Roadmap/08 - CLASES/ruby/edalmava.rb",
    "content": "class MegaAnfitrion\n    attr_accessor :nombres\n\n    def initialize(nombres = 'Mundo')\n        @nombres = nombres\n    end\n\n    def decir_hola\n        if @nombres.nil?\n            puts '...'\n        elsif @nombres.respond_to?('each')\n            @nombres.each { |nombre|\n                puts \"Hola #{nombre}\"\n        }\n        else\n            puts \"Hola #{@nombres}\"\n        end\n    end\n\n    def decir_adios\n        if @nombres.nil?\n            puts '...'\n        elsif @nombres.respond_to?('join')\n            puts \"Adiós #{@nombres.join(',')}. Vuelvan pronto\"\n        else\n            puts \"Adiós #{nombres}\"\n        end\n    end\nend\n\nif __FILE__ == $0\n    ma = MegaAnfitrion.new\n    ma.decir_hola\n    ma.decir_adios\n\n    ma.nombres = 'Edward'\n    ma.decir_hola\n    ma.decir_adios\n\n    ma.nombres = ['Alexis', 'Maldonado', 'Vargas']\n    ma.decir_hola\n    ma.decir_adios\n\n    ma.nombres = nil\n    ma.decir_hola\n    ma.decir_adios\nend\n"
  },
  {
    "path": "Roadmap/08 - CLASES/rust/brockar.rs",
    "content": "/*\n* EJERCICIO:\nExplora el concepto de clase y crea un ejemplo que implemente un inicializador,\natributos y una función que los imprima (teniendo en cuenta las posibilidades\nde tu lenguaje).\nUna vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\nutilizando su función.\n*/\nuse std::fmt;\nstruct User {\n    username: String,\n    email: String,\n    count: u8,\n}\n\nfn init_user(email: String, username: String) -> User {\n    User {\n        email,\n        username,\n        count: 0,\n    }\n}\n\nfn count_user(user: &mut User) {\n    user.count += 1;\n}\nimpl fmt::Display for User {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        write!(\n            f,\n            \"User: \\n -Username: {}\\n -Email: {}\\n -Count: {}\",\n            self.username, self.email, self.count\n        )\n    }\n}\n\nfn main() {\n    let mut user = init_user(\"brockar@mouredev.com\".to_string(), \"brockar\".to_string());\n    count_user(&mut user);\n    println!(\"{}\", user);\n\n    //Extra Pila\n    println!(\"\\n\\nEXTRA PILA\");\n\n    let mut p: Pila<u32> = init_pila::<u32>();\n    println!(\"{}\", p);\n\n    push_pila(&mut p, 1);\n    push_pila(&mut p, 2);\n    push_pila(&mut p, 3);\n    println!(\"{}\", p);\n    println!(\"\\nLa pila tiene {} elementos.\\n\", n_elementos_pila(&p));\n    println!(\"Pop: {:?}\", pop_pila(&mut p));\n    println!(\"Pop: {:?}\", pop_pila(&mut p));\n    println!(\"Pop: {:?}\", pop_pila(&mut p));\n    println!(\"Pop: {:?}\", pop_pila(&mut p));\n    println!(\"{}\", p);\n\n    println!(\"\\n\\nEXTRA COLA\");\n\n    let mut c: Cola<u32> = init_cola::<u32>();\n    println!(\"{}\", c);\n\n    push_cola(&mut c, 1);\n    push_cola(&mut c, 2);\n    push_cola(&mut c, 3);\n\n    println!(\"{}\", c);\n    println!(\"\\nLa cola tiene {} elementos.\\n\", n_elementos_cola(&c));\n    \n    println!(\"Pop: {:?}\", pop_cola(&mut c));\n    println!(\"Pop: {:?}\", pop_cola(&mut c));\n    println!(\"Pop: {:?}\", pop_cola(&mut c));\n    println!(\"Pop: {:?}\", pop_cola(&mut c));\n    println!(\"{}\", c);\n}\n\n /*\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n */\n//-----------------PILA-----------------\nstruct Pila<T> {\n    contenido: Vec<T>,\n}\n\nfn init_pila<T>() -> Pila<T>{\n    Pila{\n        contenido: vec![]\n    }\n}\n\nfn push_pila<T>(pila: &mut Pila<T>, valor: T) {\n    pila.contenido.push(valor);\n}\n\nfn pop_pila<T: Default>(pila: &mut Pila<T>) -> T {\n    if !pila.contenido.is_empty() {\n        return pila.contenido.pop().unwrap();\n    }\n    println!(\"Pila vacia!!!\");\n    T::default()\n}\n\nfn n_elementos_pila <T>(pila: &Pila<T>) -> usize {\n    pila.contenido.len()\n}\n\nimpl<T: std::fmt::Debug> fmt::Display for Pila<T>{\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        write!(f, \"Pila: \\n -Contenido: {:?}\", self.contenido)\n    }\n}\n\n\n\n//-----------------COLA-----------------\nstruct Cola<T> {\n    contenido: Vec<T>,\n}\n\nfn init_cola<T>() -> Cola<T>{\n    Cola{\n        contenido: vec![]\n    }\n}\n\nfn push_cola<T>(cola: &mut Cola<T>, valor: T) {\n    cola.contenido.push(valor);\n}\n\nfn pop_cola<T: Default>(cola: &mut Cola<T>) -> T {\n    if !cola.contenido.is_empty() {\n        return cola.contenido.remove(0);\n    }\n    println!(\"Cola vacia!!!\");\n    T::default()\n}\n\nfn n_elementos_cola <T>(cola: &Cola<T>) -> usize {\n    cola.contenido.len()\n}\n\nimpl<T: std::fmt::Debug> fmt::Display for Cola<T>{\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        write!(f, \"Cola: \\n -Contenido: {:?}\", self.contenido)\n    }\n}"
  },
  {
    "path": "Roadmap/08 - CLASES/rust/gabrielmoris.rs",
    "content": "/*\n * EXERCISE:\n * Explore the concept of a class and create an example that implements an initializer,\n * attributes, and a function that prints them (taking into account the possibilities\n * of your language).\n * Once implemented, create it, set its parameters, modify them, and print them\n * using its function.\n */\n\nfn main() {\n    // Creation. The where specifies that Items can be displayed\n    pub struct Class<T>\n    where\n        T: std::fmt::Display,\n    {\n        elements: Vec<T>,\n    }\n\n    // Initialization\n    impl<T> Class<T>\n    where\n        T: std::fmt::Display,\n    {\n        // Create Stack\n        pub fn new() -> Self {\n            Class {\n                elements: Vec::new(),\n            }\n        }\n\n        pub fn print(&mut self) {\n            for n in &self.elements {\n                println!(\"{}\", n);\n            }\n        }\n\n        pub fn push(&mut self, item: T) {\n            self.elements.push(item);\n        }\n\n        pub fn clear(&mut self) {\n            self.elements.clear();\n        }\n    }\n\n    let mut class_example: Class<i32> = Class::new();\n    class_example.push(1);\n    class_example.push(1);\n    class_example.push(3);\n    class_example.push(7);\n    class_example.push(12);\n    class_example.print();\n    class_example.clear();\n\n    /* EXTRA DIFFICULTY (optional):\n     * Implement two classes that represent the Stack and Queue structures (studied\n     * in exercise number 7 of the study path)\n     * - They must be able to initialize and have operations to add, remove,\n     *   return the number of elements, and print all their contents.\n     */\n\n    // STACK\n    pub struct Stack<T> {\n        elements: Vec<T>,\n    }\n\n    impl<T> Stack<T> {\n        // Create Stack\n        pub fn new() -> Self {\n            Stack {\n                elements: Vec::new(),\n            }\n        }\n        // Push Item\n        pub fn push(&mut self, item: T) {\n            self.elements.push(item);\n        }\n        // Pop Item\n        pub fn pop(&mut self) -> Option<T> {\n            self.elements.pop()\n        }\n\n        // Check Item\n        pub fn check(&self) -> Option<&T> {\n            self.elements.last()\n        }\n        // Is Empty\n        pub fn is_empty(&self) -> bool {\n            self.elements.is_empty()\n        }\n\n        pub fn clear(&mut self) {\n            self.elements.clear();\n        }\n\n        pub fn length(&self) -> usize {\n            self.elements.len()\n        }\n    }\n    println!(\" ======== STACK ======== \");\n    let mut stack = Stack::new();\n    stack.push(1);\n    stack.push(1);\n    println!(\"{:?}\", stack.length()); // Prints: 2\n    stack.clear();\n    println!(\"{:?}\", stack.length()); // Prints: 0\n    stack.push(1);\n    stack.push(2);\n    println!(\"{:?}\", stack.pop()); // Prints: Some(2)\n    println!(\"{:?}\", stack.check().unwrap()); // Prints: 1\n    println!(\"{:?}\", stack.is_empty()); // Prints: false\n    println!(\"{:?}\", stack.pop().unwrap()); // Prints: 1\n    println!(\"{:?}\", stack.is_empty()); // Prints: true\n\n    // QUEUE\n    pub struct Queue<T> {\n        elements: Vec<T>,\n    }\n\n    impl<T> Queue<T> {\n        // Create Stack\n        pub fn new() -> Self {\n            Queue {\n                elements: Vec::new(),\n            }\n        }\n        // enqueue\n        pub fn enqueue(&mut self, item: T) {\n            self.elements.push(item);\n        }\n\n        pub fn dequeue(&mut self) -> T {\n            self.elements.remove(0)\n        }\n\n        pub fn check(&self) -> Option<&T> {\n            self.elements.first()\n        }\n\n        pub fn length(&self) -> usize {\n            self.elements.len()\n        }\n\n        pub fn is_empty(&self) -> bool {\n            self.elements.is_empty()\n        }\n\n        pub fn clear(&mut self) {\n            self.elements.clear();\n        }\n    }\n    println!(\" ======== QUEUE ======== \");\n    let mut queue = Queue::new();\n    queue.enqueue(1);\n    queue.enqueue(1);\n    println!(\"{:?}\", queue.length()); // Prints: 2\n    queue.clear();\n    println!(\"{:?}\", queue.length()); // Prints: 0\n    queue.enqueue(1);\n    queue.enqueue(2);\n    println!(\"{:?}\", queue.dequeue()); // Prints: 1\n    println!(\"{:?}\", queue.check().unwrap()); // Prints: 2\n    println!(\"{:?}\", queue.is_empty()); // Prints: false\n    println!(\"{:?}\", queue.dequeue()); // Prints: 2\n    println!(\"{:?}\", queue.is_empty()); // Prints: true\n}\n"
  },
  {
    "path": "Roadmap/08 - CLASES/rust/kenysdev.rs",
    "content": "/*\n╔═══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado                ║\n║ GitHub: https://github.com/Kenysdev   ║\n║ 2024 -  Rust                          ║\n╚═══════════════════════════════════════╝\n-----------------------------------------\n* CLASES\n-----------------------------------------\n- En Rust no existen clases.\n- Rust usa estructuras y enumeraciones para crear tipos personalizados y \n  bloques impl para definir métodos en esos tipos.\n*/\nstruct Person {\n    name: String,\n    age: u32,\n}\n  \nimpl Person {\n    // Constructor\n    fn new(name: String, age: u32) -> Self {\n        Person { name, age }\n    }\n  \n    // Método\n    fn print(&self) {\n        println!(\"Nombre: {} - Edad: {}\", self.name, self.age);\n    }\n}\n  \n/* ----------------------------------------\n * Ejercicio:\n   ----------------------------------------\n - Implementa dos clases que representen las estructuras de Pila y Cola \n   (estudiadas en el ejercicio número 7 de la ruta de estudio)\n - Deben poder inicializarse y disponer de operaciones para añadir, \n   eliminar, retornar el número de elementos e imprimir todo su contenido.\n  _________________________________________\n * Pilas(stack - LIFO): \n*/\nuse std::fmt::Display;\n\nstruct MyStack<T> {\n    stack: Vec<T>,\n}\n\nimpl<T> MyStack<T> {\n    fn new() -> Self {\n        MyStack {\n            stack: Vec::new(),\n        }\n    }\n\n    fn push(&mut self, item: T) {\n        self.stack.push(item);\n    }\n\n    fn pop(&mut self) -> Option<T> {\n        self.stack.pop()\n    }\n\n    fn count(&self) -> usize {\n        self.stack.len()\n    }\n\n    fn print(&self)\n        where\n            T: std::fmt::Display,\n        {\n            for item in self.stack.iter().rev() {\n                println!(\"{}\", item);\n            }\n        }\n}\n\n// _________________________________________\n// Colas (Queue - FIFO):\nuse std::collections::VecDeque;\n\nstruct MyQueue<T> {\n    queue: VecDeque<T>,\n}\n\nimpl<T> MyQueue<T> {\n    fn new() -> Self {\n        MyQueue {\n            queue: VecDeque::new(),\n        }\n    }\n\n    fn enqueue(&mut self, item: T) {\n        self.queue.push_back(item);\n    }\n\n    fn dequeue(&mut self) -> Option<T> {\n        self.queue.pop_front()\n    }\n\n    fn count(&self) -> usize {\n        self.queue.len()\n    }\n\n    fn print(&self)\n        where\n            T: Display,\n        {\n\n            for item in &self.queue {\n                println!(\"{}\", item);\n            }\n        }\n}\n\nfn main() {\n    // ______________\n    let person = Person::new(String::from(\"Ben\"), 21);\n    person.print();\n\n    // ______________\n    println!(\"\\nUso de pila:\");\n    let mut stack = MyStack::<i32>::new();\n    stack.push(1);\n    stack.push(2);\n    stack.push(3);\n\n    println!(\"Count: {}\", stack.count());\n    stack.print();\n\n    stack.pop();\n    println!(\"Count: {}\", stack.count());\n    stack.print();\n\n    // ______________\n    println!(\"\\nUso de cola:\");\n    let mut queue = MyQueue::<i32>::new();\n    queue.enqueue(1);\n    queue.enqueue(2);\n    queue.enqueue(3);\n\n    println!(\"Count: {}\", queue.count());\n    queue.print();\n\n    queue.dequeue();\n    println!(\"Count: {}\", queue.count());\n    queue.print();\n\n}\n"
  },
  {
    "path": "Roadmap/08 - CLASES/sql/Nicojsuarez2.sql",
    "content": "# #08 CLASES\n> #### Dificultad: Fácil | Publicación: 19/02/24 | Corrección: 26/02/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n * \n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/08 - CLASES/swift/PineroDev.swift",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n *\n */\n\n\nclass Vehiculo {\n    var marca: String\n    var modelo: String\n    var año: Int\n    \n    init(marca: String, modelo: String, año: Int) {\n        self.marca = marca\n        self.modelo = modelo\n        self.año = año\n    }\n    \n    func imprimirDatos() {\n        print(marca)\n        print(modelo)\n        print(año)\n        \n    }\n}\n\nvar miVehiculo = Vehiculo(marca: \"Toyota\", modelo: \"Corolla\", año: 2020)\nmiVehiculo.imprimirDatos()\n\n\n//-------------------------------------\n\nclass Stack <T>{\n    var items: [T]\n    \n    init(items: [T] ){\n        self.items = items\n    }\n    \n    func push(_ element: T) { // Declaro el argumento con _ para que no sea necesario indicar el nombre cuando se le pase en la llamada\n        items.append(element)\n    }\n    \n    func pop() -> T? { //Lo declaro como opcional ? por si el array esta vacio\n        return items.popLast()\n    }\n}\n\n\nlet stack = Stack<Int>(items: [1, 2, 3])\nstack.push(4)\nprint(stack.pop() ?? 0) // Uso ?? para que al imprimir no aparezca opcional\n\n\nclass Queue<T>{\n    var items: [T]\n    \n    init(items: [T] ){\n        self.items = items\n    }\n    \n    func enqueue(_ element: T) { \n        items.append(element)\n    }\n    \n    func dequeue() -> T? {\n        return items.removeFirst()\n    }\n}\n\nlet queue = Queue<Int>(items: [1, 2, 3, 5, 6])\nqueue.enqueue(7)\nprint(queue.dequeue() ?? 0)\n"
  },
  {
    "path": "Roadmap/08 - CLASES/swift/allbertoMD.swift",
    "content": "import Foundation\n\n\n// Creación de la clase UserInfo\nclass UserInfo {\n\n    // Declaración de las propiedades de la clase.\n    var id: String\n    let name: String\n    var userName: String\n    var email: String\n    var age: Int\n\n    // Definición del inicializador de la clase.\n    init(id: String, name: String, userName: String, email: String, age: Int) {\n        self.id = id\n        self.name = name\n        self.userName = userName\n        self.email = email\n        self.age = age\n    }\n    // Definición de los metodos de la clasw.\n    func showName() {\n        print(name)\n    }\n    func showUserName() {\n        print(userName)\n    }\n    func showEmail() {\n        print(email)\n    }\n    func showAge() {\n        print(age)\n    }\n}\n\n// USER1\nprint(\"\\nuser1\\n\")\n\n// Crea el objeto user1 de la clase UserInfo().\nvar user1 = UserInfo(id: \"01\", name: \"Raul\", userName: \"Ra01Mad\", email: \"raulrst@gmail.com\", age: 39)\n\n// Asigna la propiedad name de la clase a la variable user1Nmae.\nlet user1Name = user1.name\n// Accede al metodo showName() del objeto user1.\nuser1.showName()\n\n// Asigna la propiedad userName de la clase a la variable user1UserName.\nvar user1UserName = user1.userName\n// Accede al metodo showUserName() del objeto user1.\nuser1.showUserName()\n\n// Asigna la propiedad email de la clase a la variable user1Email.\nvar user1Email = user1.email\n// Accede al metodo showEmail() del objwto user1.\nuser1.showEmail()\n\n// Asigna la propiedad age de la clase a la variable user1Age.\nvar user1Age = user1.age\n// Accede al metodo showAge() del objeto user1.\nuser1.showAge()\n\n// uSER2\nprint(\"\\nuser2\\n\")\n\n// Crea el objeto user2 de la clase UserInfo().\nvar user2: UserInfo = UserInfo(id: \"02\", name: \"Selvia\", userName: \"Silvi3\", email: \"silviarod@gmail.com\", age: 27)\n\n// Asigna la propiedad name de la clase a la variable user2Name.\nlet user2Name = user2.name\n// Accede al metodo showName del objeto user2.\nuser2.showName()\n\n// Asigna la propiedad userName de la clase a la variable user2UserName.\nvar user2UserName = user2.userName\n// Accede al metodo showUserName() del objeto user2.\nuser2.showUserName()\n\n// Asigna la propiedad email de la clase a la variable user2Email.\nvar user2Email = user2.email\n// Accede al metodo showEmail() del objeto user2.\nuser2.showEmail()\n\n// Asigna la propiedad age a la variable user2Age.\nvar user2Age = user2.age\n// Accede al metodo showAge() del objeto user2.\nuser2.showAge()\n\n// CAMBIOS EN USER1\nprint(\"\\nCambios de user1\\n\")\n\n// Cambia el valor de la propiedad userName del objeto user1.\nuser1.userName = \"RaulitoEDLG\"\n// Accede al metodo showUserName() del objeto user1\nuser1.showUserName()\n\n// Cambiar el valor de la propiedad age del objeto user1.\nuser1.age = 40\n// Accede al metodo showAge() del objeto user1.\nuser1.showAge()\n\n// CAMBIOS EN USER2\nprint(\"\\nCambios de user2\\n\")\n\n// Cambia el valor de la proiedad email del objeto user2.\nuser2.email = \"sil07.via@gmail.com\"\n// Accede al metodo showEmail() del objeto user2\nuser2.showEmail()\n\n// Cambia el valor de la propiedad age del objeto user2.\nuser2.age = 28\n// Accede al metodo showAge() del objeto user2\nuser2.showAge()\n\n\n\n// DIFICULTAD EXTRA\n\nprint(\"\\nSTACK\\n\")\n// Crea una clase Stack.\nclass Stack<T> {\n\n    // Declaracion de la propiedad staxk\n    private var stack: [T] = []\n    \n    // Definición del inicializador de la clase\n    init(stack: [T]) {\n        self.stack = stack\n    }\n\n    // Definicion del metodo push(), que añade elementos.\n    func push(_ item: T) {\n        stack.append(item)\n    }\n    \n    // Definición del metodo pop(), que elimina el ultimo item de la lista y lo reotorna.\n    func pop() -> T? {\n        return stack.removeLast()\n    }\n\n    // Definición del metodo peek(), que retorna el ultimo item de la lista.\n    func peek() -> T? {\n        return stack.last\n    }\n\n    // Definición del metodo isEmpty(), que retorna si la lista esta vacio.\n    func isEmpty() -> Bool {\n        return stack.isEmpty\n    }\n\n    // Definición del metodo count(), que retorna la cantidad de items que tiene la lista.\n    func count() -> Int {\n        return stack.count\n    }\n}\n\n// Crea el objeto myStack de la clase Stack().\nvar myStack = Stack(stack: [\"Paris\", \"Madrid\", \"Tokio\", \"New York\"])\n\n// Añade un nuevo item a la lista usando el metodo push().\nmyStack.push(\"El Kaito\")\n\n// Elimina el ultimo item de la lista y lo devuelve en e imprime la variable pop usando el metodo pop().\nif let pop = myStack.pop() {\n    print(pop)\n}\n\n// Devuelve e imprime el ultimo item de la lista en la variable peek usando el metodo peek().\nif let peek = myStack.peek() {\n    print(peek)\n}\n\n// Devuelve si la lista esta vacia.\nprint(myStack.isEmpty())\n\n// Devuelve la cantidad de items de la lista.\nprint(myStack.count())\n\n\n\nprint(\"\\nQUEUE\\n\")\n// Crea la clase Queue.\nclass Queue<T> {\n    \n    // Declaración de la propiedad queue.\n    var queue: [T] = []\n\n    // Definicion del inicializador de la clase.\n    init(queue: [T]) {\n        self.queue = queue\n    }\n\n    // Definición del metodo enqueue(), que anade un item al final de la lista.\n    func enqueue(_ Item: T) {\n        queue.append(Item)\n    }\n\n    // Definición del metodo dequeue(), que elimina y retorna el primer item de la lista.\n    func dequeue() -> T? {\n        return queue.removeFirst()\n    }\n\n    // Definición del metodo peek(), que retorna el primer item de la lista.\n    func peek() -> T? {\n        return queue.first\n    }\n\n    // Definición del metodo isEmpy(), que retorno si la lista esta vacia.\n    func isEmpty() -> Bool {\n        return queue.isEmpty\n    }\n\n    // Definición del metodo count(), que retorna el numero de items de la lista.\n    func count() -> Int {\n        return queue.count\n    }\n}\n\n// Crea el objeto myQueue de la clase Queue().\nvar myQueue = Queue(queue: [\"Roberto\", \"Alicia\", \"Ruben\", \"Almudena\"])\n\n// Añade un nuevo item a la lista usando el metodo enqueue().\nmyQueue.enqueue(\"Oliver\")\n\n// Elimina el ultimo item de la lista y lo devuelve e imprime la variable dequeue usando el metodo dequeue().\nif let dequeue = myQueue.dequeue() {\n    print(dequeue)\n}\n\n// Devuelve e imprime el ultimo item de la lista en la variable peek usando el metodo peek().\nif let peek = myQueue.peek() {\n    print(peek)\n}\n\n// Devuelve si la lista esta vacia.\nprint(myQueue.isEmpty())\n\n// Devuelve la cantidad de items de la lista.\nprint(myQueue.count())"
  },
  {
    "path": "Roadmap/08 - CLASES/swift/blackriper.swift",
    "content": "/*\n  En swift hay dos tipos para representar un tipo complejo:\n  - Struct\n    -Puede tener metodos y atributos\n    -No necesita un constructor para  inicializarlos\n    -Actuan como un Value Type quiere decir que cada vez que se crea uno este tiene diferentes\n     espacios de memoria \n  - Class\n    -Puede tener metodos y atributos\n    -Debe tener un constructor para inicializarlos\n    -Actuan como un Reference Type quiere decir que cada vez que se crea uno el comparten un espacio de memoria\n    -Pueden tener herencia \n */\n \n class Person{\n   let name: String\n   let age:Int\n   let city: String\n\n   init(name: String, age: Int, city: String){\n     self.name = name\n     self.age = age\n     self.city = city\n   }\n\n   func sayHello(){\n     print(\"Hello, my name is \\(name) and I am \\(age) years old and I live in \\(city)\") \n   }\n }\n\n  let person=Person(name: \"Diego\", age: 31, city: \"Madrid\")\n  person.sayHello()\n  \n  struct Phone{\n    let brand: String\n    let model: String\n    let color: String\n\n    func call(number:String) -> String {\n      return \"Calling \\(number)\"\n    }\n \n    func getMobileInfo() -> String {\n      return \"Brand: \\(brand) \\nModel: \\(model) \\nColor: \\(color)\"\n    }\n  } \n\n  let phone=Phone(brand: \"iPhone\", model: \"X\", color: \"Black\")\n  print(phone.getMobileInfo())\n  print(phone.call(number: \"123456789\"))\n  \n  // ejercicio extra\n struct Queue{\n    var elements=[String]()\n\n    mutating func add(element: String){\n        elements.append(element)\n    }\n\n    mutating func addAll(itemsArray: [String]){\n        self.elements=itemsArray\n    }\n\n    mutating func remove() -> String?{\n        return elements.isEmpty ? nil : elements.removeFirst()\n    }\n\n    func peek() -> String?{\n        return elements.isEmpty ? nil : elements.first\n    }\n\n    var isEmpty: Bool {\n        return elements.isEmpty\n    }\n}\n\nclass Printer{\n    private var  printerQueue=Queue()\n    private var option:String=\"\"\n\n    init(itemsArray: [String]){\n        self.printerQueue.addAll(itemsArray: itemsArray)\n    }\n    \n    private func addDocument(document:String){\n        printerQueue.add(element: document)\n    }\n\n    private func printNextDocument(){\n        if let nextDocument=printerQueue.remove(){\n            print(\"printing: \\(nextDocument)\")\n            print(\"pending to print: \\(printerQueue.elements)\")\n            \n        }\n    }\n\n    func printDocuments(){\n      repeat{\n        print(\"1. Add document\")\n        print(\"2. Printdocument\")\n        print(\"3. Exit\")\n        print(\"Select an option: \", terminator: \"\")\n        option=readLine()!\n        switch option{\n            case \"1\":\n               print(\"Input the document name\",terminator: \"\")\n               let document=readLine()!\n               addDocument(document: document)\n            case \"2\":\n                 if printerQueue.isEmpty {\n                     print(\"No documents to print\")  \n                 }else {\n                     printNextDocument()\n                 }  \n            default:\n             if option != \"3\" {\n                 print(\"Invalid option\")   \n             }\n                 \n        }\n    }while option != \"3\"    \n \n  }\n}\n\nlet printer=Printer(itemsArray: [\"document1\",\"document2\",\"document3\"])\nprinter.printDocuments()\n\nstruct Stack{\n    var elements=[String]()\n\n    mutating func push(element: String){\n        elements.append(element)\n    }\n\n    mutating func pop() -> String?{\n        return elements.isEmpty ? nil : elements.popLast()\n    }\n\n    func peek() -> String?{\n        return elements.isEmpty ? nil : elements.last\n    }\n\n    var isEmpty: Bool{\n        return elements.isEmpty\n    }\n}\n\nclass WebNavigator {\n    private var back=Stack()\n    private var forward=Stack()\n\n    func navigate(webPage:String){\n        if back.isEmpty{\n           forward.push(element: webPage)\n           print(\"navigating to: \\(webPage)\")\n        }\n    }\n\n    func goBack(){\n        if !back.isEmpty{\n            forward.push(element: back.pop()!)\n            print(\"back to: \\(back.peek()!)\")\n        }else{\n            print(\"nothing to go back\")\n        }\n    }    \n\n    func goForward(){\n        if !forward.isEmpty{\n            back.push(element: forward.pop()!)\n            print(\"forward to: \\(forward.peek()!)\")\n        }else{\n            print(\"nothing to go forward\")\n        }\n    }\n}\n\nlet webNavigator=WebNavigator()\nwebNavigator.navigate(webPage: \"google.com\")\nwebNavigator.navigate(webPage: \"facebook.com\")\nwebNavigator.navigate(webPage: \"twitter.com\")\nwebNavigator.goBack()\nwebNavigator.goForward()\n"
  },
  {
    "path": "Roadmap/08 - CLASES/swift/didacdev.swift",
    "content": "import Foundation \n\nstruct Stack<T> {\n    private var stack = [T]()\n\n    init(array: [T]) {\n        stack = array\n    }\n\n    init() {\n\n    }\n\n    mutating func push(e: T) {\n        stack.insert(e, at: 0)\n    }\n\n    mutating func get() -> T? {\n        if let e = stack.first {\n            return e\n        } else {\n            return nil\n        }\n    }\n\n    mutating func pop() -> T? {\n        if stack.first != nil {\n            return stack.removeFirst()\n        } else {\n            return nil\n        }\n\n    }\n\n    mutating func clean() {\n        stack.removeAll()\n    }\n\n    mutating func size() -> Int{\n        return stack.count\n    }\n\n    mutating func printStack() {\n        print(stack)\n    }\n}\n\nstruct Queue<T> {\n    private var queue = [T]()\n\n    init(array: [T]) {\n        queue = array\n    }\n\n    init() {\n\n    }\n\n    mutating func enqueue(e: T) {\n        queue.append(e)\n    }\n\n    mutating func get() -> T? {\n        if let e = queue.first {\n            return e\n        } else {\n            return nil\n        }\n    }\n\n    mutating func dequeue() -> T? {\n        if queue.first != nil {\n            return queue.removeFirst()\n        } else {\n            return nil\n        }\n    }\n\n    mutating func clean() {\n        queue.removeAll()\n    }\n\n    mutating func size() -> Int {\n        return queue.count\n    }\n\n    mutating func printQueue() {\n        print(queue)\n    }\n}\n\nvar queue: Queue<Int> = Queue()\nvar stack: Stack<Int> = Stack()\n\nqueue.enqueue(e: 1)\nqueue.enqueue(e: 2)\nqueue.enqueue(e: 3)\nqueue.enqueue(e: 4)\nqueue.enqueue(e: 5)\nqueue.printQueue()\nprint(queue.size())\nprint(queue.get())\nprint(queue.dequeue())\nqueue.printQueue()\nprint(queue.size())\n\nstack.push(e: 1)\nstack.push(e: 2)\nstack.push(e: 3)\nstack.push(e: 4)\nstack.push(e: 5)\nstack.printStack()\nprint(stack.size())\nprint(stack.get())\nprint(stack.pop())\nstack.printStack()\nprint(stack.size())\n"
  },
  {
    "path": "Roadmap/08 - CLASES/swift/juanppdev.swift",
    "content": "/*EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n */\n\n class Persona {\n    var nombre: String\n    var edad: Int\n    \n    // Inicializador\n    init(nombre: String, edad: Int) {\n        self.nombre = nombre\n        self.edad = edad\n    }\n    \n    // Función para imprimir los atributos\n    func imprimirDatos() {\n        print(\"Nombre: \\(nombre)\")\n        print(\"Edad: \\(edad)\")\n    }\n}\n\n// Crear una instancia de la clase\nlet persona1 = Persona(nombre: \"Juan\", edad: 25)\n\n// Imprimir los atributos\npersona1.imprimirDatos()\n\n// Modificar los atributos\npersona1.nombre = \"Juan Carlos\"\npersona1.edad = 26\n\n// Imprimir los atributos modificados\npersona1.imprimirDatos()\n\n/*\n DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.*/\n\n class Pila {\n    private var elementos: [Int] = []\n    \n    // Inicializador\n    init() {}\n    \n    // Función para añadir un elemento\n    func push(_ elemento: Int) {\n        elementos.append(elemento)\n    }\n    \n    // Función para eliminar un elemento\n    func pop() -> Int? {\n        if elementos.isEmpty {\n            return nil\n        } else {\n            return elementos.removeLast()\n        }\n    }\n    \n    // Función para retornar el número de elementos\n    func count() -> Int {\n        return elementos.count\n    }\n    \n    // Función para imprimir todo su contenido\n    func imprimir() {\n        print(\"Pila: \\(elementos)\")\n    }\n}\n\nclass Cola {\n    private var elementos: [Int] = []\n    \n    // Inicializador\n    init() {}\n    \n    // Función para añadir un elemento\n    func enqueue(_ elemento: Int) {\n        elementos.append(elemento)\n    }\n    \n    // Función para eliminar un elemento\n    func dequeue() -> Int? {\n        if elementos.isEmpty {\n            return nil\n        } else {\n            return elementos.removeFirst()\n        }\n    }\n    \n    // Función para retornar el número de elementos\n    func count() -> Int {\n        return elementos.count\n    }\n    \n    // Función para imprimir todo su contenido\n    func imprimir() {\n        print(\"Cola: \\(elementos)\")\n    }\n}\n\n// Crear instancias de las clases\nlet pila1 = Pila()\nlet cola1 = Cola()\n\n// Añadir elementos a las estructuras\npila1.push(1)\npila1.push(2)\ncola1.enqueue(1)\ncola1.enqueue(2)\n\n// Imprimir los elementos de las estructuras\npila1.imprimir()\ncola1.imprimir()\n\n// Eliminar elementos de las estructuras\nlet elementoPila = pila1.pop()\nlet elementoCola = cola1.dequeue()\n\n// Imprimir los elementos eliminados\nprint(\"Elemento eliminado de la pila: \\(elementoPila ?? 0)\")\nprint(\"Elemento eliminado de la cola: \\(elementoCola ?? 0)\")\n\n// Imprimir los elementos restantes de las estructuras\npila1.imprimir()\ncola1.imprimir()"
  },
  {
    "path": "Roadmap/08 - CLASES/swift/karys4.swift",
    "content": "/*\n EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n*/\n\nclass Person {\n    var name: String\n    var country: String\n    var hobby: String\n    var isHappy: Bool\n    \n    init(name: String, country: String, hobby:String, isHappy: Bool) {\n        self.name = name\n        self.country = country\n        self.hobby = hobby\n        self.isHappy = isHappy\n    }\n    \n    func printPersonalData() {\n        \n        if isHappy {\n            print(\"My name is \\(name), I live in \\(country) and I enjoy \\(hobby).\")\n        } else {\n            print(\"This is a person that isn't currently happy.\")\n        }\n    }\n}\n\nvar me = Person(name: \"Karys\", country: \"Mexico\", hobby: \"Learn\", isHappy: true)\nvar sadPerson = Person(name: \"James\", country: \"Argentina\", hobby: \"Soccer\", isHappy: false)\nme.printPersonalData()\nsadPerson.printPersonalData()"
  },
  {
    "path": "Roadmap/08 - CLASES/swift/kontroldev.swift",
    "content": "import Foundation\n\n\n/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n *\n */\n\n// Definición de la clase Libro\nclass Libro {\n    var titulo: String\n    var autor: String\n    var paginas: Int\n    \n    // Inicializador de la clase Libro\n    init(titulo: String, autor: String, paginas: Int) {\n        self.titulo = titulo\n        self.autor = autor\n        self.paginas = paginas\n    }\n    \n    // Función para imprimir los atributos del libro\n    func imprimirDetalles() {\n        print(\"Título: \\(titulo)\")\n        print(\"Autor: \\(autor)\")\n        print(\"Número de páginas: \\(paginas)\")\n    }\n}\n\n// Creación de una instancia de Libro\nvar miLibro = Libro(titulo: \"El insondable sonido del silencio.\", autor: \"N_Mu\", paginas: 429)\n\n// Impresión de los detalles del libro utilizando la función imprimirDetalles()\nmiLibro.imprimirDetalles()\n\n// Modificación de los atributos del libro\nmiLibro.titulo = \"La niña del por qué\"\nmiLibro.autor = \"N Mu\"\nmiLibro.paginas = 282\n\n// Impresión de los detalles del libro actualizados\nmiLibro.imprimirDetalles()\n\n\n// DIFICULTAD EXTRA (opcional)\n\n// Definición de la clase Pila\nclass Pila<T> {\n    var elementos: [T] = []\n    \n    // Función para añadir un elemento a la pila\n    func push(_ elemento: T) {\n        elementos.append(elemento)\n    }\n    \n    // Función para eliminar y retornar el elemento en la cima de la pila\n    func pop() -> T? {\n        return elementos.popLast()\n    }\n    \n    // Función para retornar el número de elementos en la pila\n    func count() -> Int {\n        return elementos.count\n    }\n    \n    // Función para imprimir todo el contenido de la pila\n    func imprimirContenido() {\n        print(\"Contenido de la pila:\")\n        for elemento in elementos {\n            print(elemento)\n        }\n    }\n}\n\n// Definición de la clase Cola\nclass Cola<T> {\n    var elementos: [T] = []\n    \n    // Función para añadir un elemento a la cola\n    func enqueue(_ elemento: T) {\n        elementos.append(elemento)\n    }\n    \n    // Función para eliminar y retornar el primer elemento de la cola\n    func dequeue() -> T? {\n        if elementos.isEmpty {\n            return nil\n        } else {\n            return elementos.removeFirst()\n        }\n    }\n    \n    // Función para retornar el número de elementos en la cola\n    func count() -> Int {\n        return elementos.count\n    }\n    \n    // Función para imprimir todo el contenido de la cola\n    func imprimirContenido() {\n        print(\"Contenido de la cola:\")\n        for elemento in elementos {\n            print(elemento)\n        }\n    }\n}\n\n// Ejemplo de uso de las clases Pila y Cola\nvar pila = Pila<Int>()\npila.push(1)\npila.push(2)\npila.push(3)\npila.imprimirContenido()\n\nprint(\"Número de elementos en la pila: \\(pila.count())\")\n\nvar cola = Cola<String>()\ncola.enqueue(\"A\")\ncola.enqueue(\"B\")\ncola.enqueue(\"C\")\ncola.imprimirContenido()\n\nprint(\"Número de elementos en la cola: \\(cola.count())\")\n\n"
  },
  {
    "path": "Roadmap/08 - CLASES/swift/pedroomar23.swift",
    "content": "import Foundation\n\n/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n * \n */\n\n// Clase \nclass Person {\n\n    // Atributos\n    var name: String \n    var age: Int \n    var city: String \n    var work: String \n\n    // Inicializador \n    init(name: String, age: Int, city: String, work: String) {\n        self.name = name \n        self.age = age \n        self.city = city \n        self.work = work \n    }\n\n    // Funcion para imprimir los atributos \n    func perfil() {\n        print(\"Name: \\(name)\")\n        print(\"Age: \\(age)\")\n        print(\"City: \\(city)\")\n        print(\"Work: \\(work)\")\n    }\n}\n\n// Instancia para llamar a los atributos de la clase \nvar myDates = Person(name: \"James\", age: 40, city: \"New York\", work: \"Programer\")\n\n// Llamar a la funcion para imprimir en la consola \nmyDates.perfil()\n\n// Modificar los atributos de la clase \nmyDates.name = \"Jason\"\nmyDates.age = 30\nmyDates.city = \"Miami\"\nmyDates.work = \"Abogado\"\n\n// Actualizar los atributos modificados \nmyDates.perfil()\n\n// Extra \nclass Pila<Numeros> {\n\n    // Array \n    var numeros: [Numeros] = []\n\n    // Agregar un elemento al array \n    func push(_ numeros: Numeros) {\n        return numeros.append(numeros)\n    }\n\n    // Eliminar el ultimo elemento\n    func pop() -> Numeros? {\n        return numeros.popLast()\n    }\n\n    peek() -> Numeros? {\n        return numeros.last \n    }\n\n    // Imprimir en la consola \n    for numero in numeros {\n        print(numero)\n    }\n}\n\nclass Cola<Nombres> {\n\n    // Array\n    var nombres; [Nombres] = []\n\n    // Añadir un elemento al array \n    func push(_ nombres: Nombres) {\n        return nombres.append(nombres)\n    }\n\n    // Eliminar el ultimo elemento \n    func pop() -> Nombres? {\n        return nombres.removeLast()\n    }\n\n    func peek() -> Nombres? {\n        return nombres.removelast \n    }\n\n    // Imprimir en la consola \n    for nombre in nombres {\n        print(nombre)\n    }\n}"
  },
  {
    "path": "Roadmap/08 - CLASES/swift/zetared92.swift",
    "content": "import Foundation\n// Reto #08 CLASES\n\n// Definimos la clase\nclass Spartan {\n    var name: String\n    var id: Int\n    var rank: String\n\n    init(name: String, id: Int, rank: String) {\n        self.name = name\n        self.id = id\n        self.rank = rank\n    }\n\n    func printData() {\n        print(\"Name: \\(name)\")\n        print(\"Spartan ID: \\(id)\")\n        print(\"Rank: \\(rank)\")\n    }\n}\n\nvar spartanSoldier = Spartan(name: \"John\", id: 117, rank: \"Master Chief Petty Officer of the Navy\")\nspartanSoldier.printData()\n\n// Modificación de los datos introducidos previamente en los datos de los atributos de la clase\nspartanSoldier.name = \"Linda\"\nspartanSoldier.id = 058\nspartanSoldier.rank = \"Petty Officer Second Class\"\n\nspartanSoldier.printData()\n\n// 🧩 DIFICULTAD EXTRA 🧩 - CLASE PILA Y COLA\n\n// Pila/Stack\nclass Stack<T> {\n    var items: [T] = []\n\n    // Adición de elementos dentro del stack\n    func push(_ items: T) {\n        items.append(item)\n    }\n    // Supresión de elementos dentro del stack\n    func pop() -> T? {\n        return items.popLast()\n    }\n    // Retorna el nº de elementos dentro del Stack\n    func count() -> Int {\n        return items.count\n    }\n    // Imprimir el contenido del Stack\n    func printData() {\n        print(\"Stack: \")\n        for item in items {\n            print(item)\n        }\n    }\n}\n\n// Cola/Queue\nclass Queue<T> {\n    var items: [T] = []\n    items.append(item)\n}\n\nfunc dequeue() -> T? {\n    if items.isEmpty {\n        return nil\n    } else {\n        return items.removeFirst()\n    }\n}\n\nfunc count() -> Int {\n    return items.count\n}\n\nfunc printData() {\n    print(\"Queue: \")\n    for item in items {\n        print(item)\n    }\n}\n\n"
  },
  {
    "path": "Roadmap/08 - CLASES/typescript/AChapeton.ts",
    "content": "class Todo {\n  constructor(title: string, description: string, done: boolean, user: string, daysLeft: number){\n    this.title = title,\n    this.description = description,\n    this.done = done,\n    this.user = user,\n    this.daysLeft = daysLeft\n  }\n\n  //Los Getters se utilizan para no interactuar directamente con las propiedades de la clase.\n  //Tambien se evita para no dar a conocer todas sus propiedades, por seguridad.\n  get finishTodo (){\n    return this.toggleTodo()\n  }\n\n  //Metodos\n  toggleTodo() {\n    return !this.done\n  }\n}\n\nconst myTodo = new Todo('Finish roadmap', 'Finish exercise #08', false, 'Andres', 5)\n\nconsole.log(myTodo)\n\nconsole.log(myTodo.finishTodo)\n\n\n/* DIFICULTAD EXTRA */\n\nclass Pila {\n  constructor(data: Array<any>){\n    this.data = data\n  }\n\n  addElementAction(element: any){\n    return this.data.unshift(element)\n  }\n\n  deleteElementAction(){\n    return this.data.shift()\n  }\n\n  sizeAction(){\n    return this.data.length\n  }\n\n  get addElement() {\n    return this.addElementAction\n  }\n\n  get deleteElement() {\n    return this.deleteElementAction\n  }\n\n  get size(){\n    return this.sizeAction\n  }\n}\n\nconst nuevaPila = new Pila([])\n\nconsole.log('Pila vacia', nuevaPila)\nnuevaPila.addElement(1)\nnuevaPila.addElement(2)\nnuevaPila.addElement(3)\nconsole.log('Nuevos elementos agregados', nuevaPila)\nconsole.log('Cantidad de elementos', nuevaPila.size())\nnuevaPila.deleteElement()\nconsole.log('Eliminado ultimo elemento', nuevaPila)\n\nclass Cola {\n  constructor(data: Array<any>){\n    this.data = data\n  }\n\n  addElementAction(element: any){\n    return this.data.push(element)\n  }\n\n  deleteElementAction(){\n    return this.data.shift()\n  }\n\n  sizeAction(){\n    return this.data.length\n  }\n\n  get addElement() {\n    return this.addElementAction\n  }\n\n  get deleteElement() {\n    return this.deleteElementAction\n  }\n\n  get size(){\n    return this.sizeAction\n  }\n}\n\nconst nuevaCola = new Cola([])\n\nconsole.log('Cola vacia', nuevaCola)\nnuevaCola.addElement(1)\nnuevaCola.addElement(2)\nnuevaCola.addElement(3)\nconsole.log('Nuevos elementos agregados', nuevaCola)\nconsole.log('Cantidad de elementos', nuevaCola.size())\nnuevaCola.deleteElement()\nconsole.log('Eliminado primer elemento', nuevaCola)"
  },
  {
    "path": "Roadmap/08 - CLASES/typescript/EdiedRamos.ts",
    "content": "// * EdiedRamos\n\n// * Exercise\n\nclass Car {\n  constructor(\n    private brand: string,\n    private doors: number,\n    private color: string\n  ) {}\n\n  set setBrand(brand: string) {\n    this.brand = brand;\n  }\n\n  set setDoors(doors: number) {\n    this.doors = doors;\n  }\n\n  set setColor(color: string) {\n    this.color = color;\n  }\n\n  get toString(): string {\n    return `Marca: ${this.brand}\\nPuertas: ${this.doors}\\nColor: ${this.color}`;\n  }\n}\n\n// * Extra exercise\n\nclass Stack<T> {\n  constructor(private data: T[]) {}\n\n  push(item: T) {\n    this.data.unshift(item);\n  }\n\n  pop() {\n    if (!this.data.length) throw new Error(\"La pila está vacía\");\n    this.data.shift();\n  }\n\n  size() {\n    return this.data.length;\n  }\n\n  show() {\n    if (!this.data.length) throw new Error(\"La pila está vacía\");\n    console.log(`[${this.data.join(\",\")}]`);\n  }\n}\n\nclass Queue<T> {\n  constructor(private data: T[]) {}\n\n  push(item: T) {\n    this.data.push(item);\n  }\n\n  pop() {\n    if (!this.data.length) throw new Error(\"La cola está vacía\");\n    this.data.pop();\n  }\n\n  size() {\n    return this.data.length;\n  }\n\n  show() {\n    if (!this.data.length) throw new Error(\"La cola está vacía\");\n    console.log(`[${this.data.join(\",\")}]`);\n  }\n}\n\n// * Main\n(() => {\n  // * First exercise\n  const car = new Car(\"Porshe\", 2, \"black\");\n  console.log(car.toString);\n  car.setBrand = \"Mazda\";\n  car.setDoors = 4;\n  car.setColor = \"red\";\n  console.log(car.toString);\n\n  // * Second exercise\n  console.log(\"== PILA ==\");\n  const stack = new Stack<number>([1]);\n  stack.push(33);\n  stack.push(12);\n  stack.show();\n  stack.pop();\n  stack.show();\n\n  console.log(\"== COLA ==\");\n  const queue = new Queue<number>([1]);\n  queue.push(33);\n  queue.push(12);\n  queue.show();\n  queue.pop();\n  queue.show();\n})();\n"
  },
  {
    "path": "Roadmap/08 - CLASES/typescript/IgleDev.ts",
    "content": "// 1º Ejercicio\n    /**\n     * Hay varios tipo de clases y que se pueden utilizar en clases\n     * Herencia (Clases Extendidas), Abstractas, Interfaces, etc... \n    */\n\n    // Vamos a empezar por las clases más básicas hasta la más complicada:\n        // class\n        class Persona{\n            // Un constructor se encarga de inicializar las propiedades de la clase cuando se crea el objeto.\n            constructor(private _nombre : string,\n                private _edad : number, \n                private _profesion : string)\n            {};\n            /**\n             * En este caso estamos utilizando public pero hay más, lo normal no es utilizarlo ahora veremos porqué.\n             * public => Es la que vamos a utilizar en el ejemplo y significa que podemos usarlas desde cualquier lugar\n             * no suele ser lo normal.\n             * private => Se puede acceder solo a sus propiedades desde su misma clase. Para solventar esto hacemos los\n             * famosos métodos, si un atributo es privado se utiliza el '_' delante.\n             * protected => Se puede acceder a sus propiedades desde su clase y desde otra que herede esa clase.\n             */\n\n            // Los get se utilizan para pillar el valor de la propiedad\n            get nombre() : string{\n                return this._nombre;\n            }\n\n            //Los set se utilizan para establecer sus valores\n            set nombre(nombre : string){\n                this._nombre = nombre;\n            }\n\n            get edad() : number{\n                return this._edad;\n            }\n\n            set edad(edad : number){\n                this._edad = edad;\n            }\n\n            get profesion() : string{\n                return this._profesion;\n            }\n\n            set profesion(profesion : string){\n                this._profesion = profesion;\n            }\n\n            //Tambien podemos incluir métodos\n            cumplirAnhos() : number{\n                this.edad = this.edad + 1;\n                return this.edad;\n            }\n\n            cambiarProfesion(profesion : string) : string{\n                this.profesion = profesion;\n                return this.profesion;\n            }\n\n            // Esta funión nos va a servir para mostrar la información de nuestra persona\n            toString() : string{\n                return `Mi nombre es: ${this.nombre} tengo ${this.edad} Años, mi profesion es ser un/a ${this.profesion}`;\n            }\n        }\n\n        //Vamos a crear a una persona\n        let persona = new Persona('Igledev', 19, 'Programador');    // Le ponemos datos por defecto.\n        console.log(persona)\n        /**\n         * Si hacemos nos va a aparecer un objeto con nuestras propiedades pero podremos acceder a ellas porque\n         * estan en 'private', si fuese 'public' no tendríamos problema. Para ello vamos a utilizar los conocidos\n         * setters & getters\n        */\n\n        //Una vez hechos los setter & getters podremos acceder a las propiedades\n        // console.log(persona.nombre + ' ' + persona.edad + ' ' + persona.profesion); // Nos saldrá IgleDev 19 Profesión.\n        //En vez de utilizar todo esto, lo hacemos llamando a una función\n        console.log(persona.toString());\n\n        //Utilizamos los métodos que hemos puesto en la clase\n        persona.cumplirAnhos();\n        persona.cambiarProfesion('Desarrollador Web');\n        console.log(persona.toString());\n        // Nos saldrá que nuestra edad ahora es de 20 y que somos desarrolladores web\n\n        // Herencia (clases extendidas)\n        /**\n         * Que tenga la palabra reservada 'extends' hace referencia a que vamos a tener que utilar los\n         * parametros establecedidos en la clase Padre (en nuestro caso la clase Persona)\n         */\n        class Hijo extends Persona{\n            constructor(nombre : string, \n            edad : number, \n            profesion : string, \n            private _escuela : string)\n            {super(nombre, edad, profesion)}    // El super se utiliza para avisar de que las propiedades que estén entre los () son de la clase Padre\n                \n            //Hacemos lo setter & getters necesarios\n            get escuela() : string{\n                return this._escuela;\n            }\n\n            set escuela(escuela : string){\n                this._escuela = escuela; \n            }\n        \n            toString(): string {\n                return super.toString() + ' y mi escuela es: ' + this.escuela;  //Si utilizamos super más un método va a heredar tambien el contenido del método padre\n            }\n        }\n\n        let hijo = new Hijo('Arrian', 14, 'Estudiante', 'Montecastelo');\n        console.log(hijo.toString());\n\n        //Abstracta\n        /**\n         * Una clase abstracta se utiliza cuando sabemso que nuncan la vamos a utilizar pero \n         * si sus propiedades y que estén en clases derivadas.\n         * \n        */\n\n        abstract class ProductoDatos{\n            constructor(private _nombre : string, \n                private _desc : string, \n                private _creado_en : Date, \n                private _creado_por : number)\n            {};\n\n            getFullYear(){\n                return this._creado_en.getFullYear();\n            }\n        \n            getFullDesc(){\n                return this._nombre + ' ' + this._desc;\n            }\n\n            //Tambien puede contener métodos abstractos que obviamente solo se pueden utilizar en ella\n            abstract guardar() : void;  // No se utilizan {}.\n        }\n\n        //Ahora es cuando vamos a entender mejor esto:\n        class Producto extends ProductoDatos{\n            constructor(\n                nombre : string,\n                desc : string,\n                creado_en : Date,\n                creado_por : number,\n                public stock : number,)\n            {super(nombre, desc, creado_en, creado_por)};\n\n            override guardar(): void {\n                console.log('Se ha guardado');\n            }\n\n        }\n\n        // let datos = new ProductoDatos(). Si hacemos esto nos va saltar un error, debido a que una clase abstracta NO se puede instanciar\n\n        let producto1 = new Producto('iPhone','Movil',new Date(), 1, 100);\n        producto1.guardar();    // Podremos acceder a sus métodos!\n\n\n        //Interfaces\n        /**\n         * Se utilizan cuando NO vamos a compartir lógica pero si necesitamos la implementación de métodos y propiedades.\n        */\n\n        interface Animal{\n            nombre : string, \n            caminar() : string;\n            onomatopeya() : string;\n        } // En una Interfaz se pueden declarar tanto propiedades como métodos.\n\n        class Gato implements Animal{\n            nombre: string = 'Zelda';\n\n            caminar(): string {\n                return 'va caminando...';\n            }\n\n            onomatopeya(): string {\n                return 'meow';\n            }\n        }\n\n        let gato1 = new Gato();\n        console.log(`El nombre del gato es ${gato1.nombre} y ${gato1.caminar()} mientras dice ${gato1.onomatopeya()}`);\n\n// Ejercicio Extra\nclass Nodo<T> {\n    dato: T | null;\n    siguiente: Nodo<T> | null;\n\n    constructor(dato: T) {\n        this.dato = dato;\n        this.siguiente = null;\n    }\n}\n\nclass Pila<T> {\n    tope: Nodo<T> | null;\n\n    constructor() {\n        this.tope = null;\n    }\n\n    isEmpty(): boolean {\n        return this.tope === null;\n    }\n\n    push(dato: T): void {\n        const nuevoNodo = new Nodo(dato);\n        nuevoNodo.siguiente = this.tope;\n        this.tope = nuevoNodo;\n    }\n\n    pop(): T | null {\n        if (this.isEmpty()) {\n            return null;\n        }\n\n        const datoEliminado = this.tope!.dato;\n        this.tope = this.tope!.siguiente;\n\n        return datoEliminado;\n    }\n\n    size(): number {\n        let contador = 0;\n        let actual = this.tope;\n\n        while (actual !== null) {\n            contador++;\n            actual = actual.siguiente;\n        }\n\n        return contador;\n    }\n\n    print(): void {\n        let actual = this.tope;\n\n        while (actual !== null) {\n            console.log(actual.dato);\n            actual = actual.siguiente;\n        }\n    }\n}\n\nclass Cola<T> {\n    frente: Nodo<T> | null;\n    fin: Nodo<T> | null;\n\n    constructor() {\n        this.frente = null;\n        this.fin = null;\n    }\n\n    isEmpty(): boolean {\n        return this.frente === null;\n    }\n\n    enqueue(dato: T): void {\n        const nuevoNodo = new Nodo(dato);\n\n        if (this.isEmpty()) {\n            this.frente = nuevoNodo;\n            this.fin = nuevoNodo;\n        } else {\n            this.fin!.siguiente = nuevoNodo;\n            this.fin = nuevoNodo;\n        }\n    }\n\n    dequeue(): T | null {\n        if (this.isEmpty()) {\n            return null;\n        }\n\n        const datoEliminado = this.frente!.dato;\n\n        if (this.frente === this.fin) {\n            // Último elemento en la cola\n            this.frente = null;\n            this.fin = null;\n        } else {\n            this.frente = this.frente!.siguiente;\n        }\n\n        return datoEliminado;\n    }\n\n    size(): number {\n        let contador = 0;\n        let actual = this.frente;\n\n        while (actual !== null) {\n            contador++;\n            actual = actual.siguiente;\n        }\n\n        return contador;\n    }\n\n    print(): void {\n        let actual = this.frente;\n\n        while (actual !== null) {\n            console.log(actual.dato);\n            actual = actual.siguiente;\n        }\n    }\n}\n\n// Ejemplo de uso:\n\nlet pila = new Pila<number>();\npila.push(1);\npila.push(2);\npila.push(3);\n\nconsole.log('Pila:');\npila.print();\nconsole.log('Tamaño de la pila:', pila.size());\n\nconsole.log('Elemento eliminado de la pila:', pila.pop());\nconsole.log('Pila después de eliminar un elemento:');\npila.print();\n\nlet cola = new Cola<string>();\ncola.enqueue('A');\ncola.enqueue('B');\ncola.enqueue('C');\n\nconsole.log('\\nCola:');\ncola.print();\nconsole.log('Tamaño de la cola:', cola.size());\n\nconsole.log('Elemento eliminado de la cola:', cola.dequeue());\nconsole.log('Cola después de eliminar un elemento:');\ncola.print();"
  },
  {
    "path": "Roadmap/08 - CLASES/typescript/RicJDev.ts",
    "content": "//EJERCICIO\ninterface Person {\n  name: string\n  age: number\n}\n\ninterface Programer {\n  languages: string[]\n}\n\nclass Programer implements Person, Programer {\n  name: string\n  age: number\n\n  constructor(name: string, age: number, languages: string[]) {\n    this.name = name\n    this.age = age\n    this.languages = languages\n  }\n\n  sayHi(): void {\n    console.log(`Hi, my name is ${this.name}`)\n  }\n\n  sayYourAge(): void {\n    console.log(`I'm ${this.age} years older`)\n  }\n\n  sayLangs(): void {\n    console.log(`I learned this languanges: ${this.languages.join(', ')}`)\n  }\n\n  learnLang(lang: string): void {\n    this.languages.push(lang)\n\n    console.log(`Learning ${lang}...`)\n  }\n}\n\nlet Sebas = new Programer('Sebastian', 23, ['Java', 'Python', 'C++'])\n\nSebas.sayHi()\nSebas.sayYourAge()\nSebas.sayLangs()\n\nSebas.learnLang('Golang')\nSebas.sayLangs()\n\n//EXTRA\nconsole.log('\\nSTACK')\nclass Stack {\n  stack: number[] = []\n\n  add(item: number): void {\n    this.stack.push(item)\n  }\n\n  remove(): void {\n    this.stack.pop()\n  }\n\n  count(): number | string {\n    if (this.stack.length > 0) {\n      return this.stack.length\n    } else {\n      return 'Void stack'\n    }\n  }\n\n  display(): void {\n    this.stack.forEach((elem) => {\n      console.log(elem)\n    })\n  }\n}\n\nconst myStack = new Stack()\n\nconsole.log('Stack elements:', myStack.count())\n\nmyStack.add(1)\nmyStack.add(2)\nmyStack.add(3)\nmyStack.add(4)\n\nconsole.log('\\nBefore remove: ')\nmyStack.display()\n\nconsole.log('After remove: ')\nmyStack.remove()\nmyStack.display()\n\nconsole.log('Stack elements:', myStack.count())\n\nconsole.log('\\nQUEUE')\nclass Queue {\n  queue: any[] = []\n\n  add(item: any): void {\n    this.queue.push(item)\n  }\n\n  remove(): void {\n    this.queue.shift()\n  }\n\n  count(): number | string {\n    if (this.queue.length > 0) {\n      return this.queue.length\n    } else {\n      return 'Void queue'\n    }\n  }\n\n  display(): void {\n    this.queue.forEach((elem) => {\n      console.log(elem)\n    })\n  }\n}\n\nconst myQueue = new Queue()\n\nconsole.log('Queue elements:', myQueue.count())\n\nmyQueue.add(1)\nmyQueue.add(2)\nmyQueue.add(3)\nmyQueue.add(4)\n\nconsole.log('\\nBefore remove: ')\nmyQueue.display()\n\nconsole.log('After remove: ')\nmyQueue.remove()\nmyQueue.display()\n\nconsole.log('Queue elements:', myQueue.count())\n"
  },
  {
    "path": "Roadmap/08 - CLASES/typescript/RobertoAmaroHub.ts",
    "content": "class Imprimir{\n\n    private nombre:string;\n    constructor(){\n        this.nombre=\"\";\n    }\n\n    public getNombre(){\n        return this.nombre;\n    }\n    public setNombre(_nombre:string){\n        if(_nombre.trim().length>0){\n            this.nombre=_nombre;\n        } else {\n            throw new Error(\"El nombre no puede estar vacío.\");\n            \n        }\n    }\n\n    public bienvenida(): void{\n        console.log(`Hola ${this.nombre} bienvenido al curso de programación`)\n    }\n}\n\nlet imprime:Imprimir= new Imprimir();\nimprime.setNombre(\"Roberto\");\nimprime.bienvenida();\n\n\n//EXTRA\nclass Estructuras{\n\n    protected elementos:string[];\n    constructor(){\n        this.elementos=[];\n    }\n\n    public setElementos(value:string[]){\n        this.elementos=value;\n    }\n    public getElementos(){\n        return this.elementos;\n    }\n\n    public validarPalabra(value:string):boolean{\n        if(value.trim().length<0){\n            return false;\n        } else {\n            return true;\n        }\n    }\n    public añadir(value:string){\n        this.elementos.push(value)\n        console.log(`\\nElemento ${value} agregado correctamente!`)\n    }\n    public printLengthOfElements(){\n        console.log(`\\nTotal de elementos: ${this.elementos.length}`);\n    }\n    public printElements(){\n        console.log(\"\\nElementos actuales:\")\n        console.log(this.elementos);\n    }\n}\n\nclass Pilas extends Estructuras{\n    \n    constructor(){\n        super();\n    }\n\n    public eliminar(){\n        let removed=this.elementos.pop();\n        console.log(`\\nElemento ${removed} eliminado correctamente!`)\n    }\n}\n\nclass Colas extends Estructuras{\n    \n    constructor(){\n        super();\n    }\n\n    public eliminar(){\n        let removed=this.elementos.shift();\n        console.log(`\\nElemento ${removed} eliminado correctamente!`)\n    }\n}\n\nvar prompt = require(\"prompt-sync\")();\nimport * as readline from 'readline';\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nlet pila:Pilas= new Pilas();\nlet cola:Colas= new Colas();\nlet menu:string[]=[\"Añadir\",\"Eliminar\", \"Total de elementos\", \"Ver elementos\", \"Salir\"]\n\nfunction getResponseFromMenu():string{\n    for(let item in menu){\n        console.log(`[${item}]: ${menu[item]}`)\n    }\n    let accion=prompt(\"Escribe el número de la acción que necesites:\");\n    return accion;\n}\n\nfunction initPilas(){\n    console.log(\"\\n******PILAS******\");\n   let accion=+getResponseFromMenu();\n    if(!isNaN(accion) && accion>=0 && accion<menu.length){\n        switch(accion){\n            case 0:\n                let res=prompt(\"Escribe una palabra: \");\n                if(pila.validarPalabra(res)){\n                    pila.añadir(res);\n                    initPilas();\n                } else {\n                    respuestaIncorrectaPilas();\n                }\n            break;\n            case 1:\n                pila.eliminar();\n                initPilas();\n            break;\n            case 2:\n                pila.printLengthOfElements();\n                initPilas();\n            break;\n            case 3:\n                pila.printElements();\n                initPilas();\n            break;\n            case 4:\n                rl.close();\n            break;\n            default:\n                respuestaIncorrectaPilas();\n                break;\n        }\n    } else {\n        respuestaIncorrectaPilas();\n    }\n}\n\nfunction respuestaIncorrectaPilas(){\n    console.log(\"Respuesta incorrecta\");\n    initPilas();\n}\n\nfunction initColas(){\n    console.log(\"\\n******COLAS******\");\n    let accion=+getResponseFromMenu();\n    if(!isNaN(accion) && accion>=0 && accion<menu.length){\n        switch(accion){\n            case 0:\n                let res = prompt(\"Escribe una palabra: \")\n                if(cola.validarPalabra(res)){\n                    cola.añadir(res);\n                    initColas();\n                } else {\n                    respuestaIncorrectaColas();\n                }\n                break;\n            case 1:\n                cola.eliminar();\n                initColas();\n                break;\n            case 2:\n                cola.printLengthOfElements();\n                initColas();\n                break;\n            case 3:\n                cola.printElements();\n                initColas();\n                break;\n            case 4:\n                rl.close()\n                break;\n            default:\n                respuestaIncorrectaColas\n                break;\n        }\n    } else {\n        respuestaIncorrectaColas();\n    }\n}\nfunction respuestaIncorrectaColas(){\n    console.log(\"Respuesta incorrecta\");\n    initPilas();\n}\n\ninitPilas();\n\ninitColas();\n\n"
  },
  {
    "path": "Roadmap/08 - CLASES/typescript/Sac-Corts.ts",
    "content": "class Person {\n    name: string;\n    age: number;\n    job: string;\n\n    constructor(name: string, age: number, job: string) {\n        this.name = name;\n        this.age = age;\n        this.job = job;\n    }\n\n    printDetails(): void {\n        console.log(`Name: ${this.name}`);\n        console.log(`Age: ${this.age}`);\n        console.log(`Job: ${this.job}`);\n    }\n}\n\nlet person1 = new Person(\"Isaac\", 22, \"Backend Developer\");\nperson1.printDetails();\n\nperson1.name = \"Yusuke\";\nperson1.age = 14;\nperson1.job = \"Fighter\";\nperson1.printDetails();\n\n// *** Extra Exercise *** //\n\n// Stack\nclass Stack<T> {\n    private elements: T[] = [];\n\n    push(element: T): void {\n        this.elements.push(element);\n    }\n\n    pop(): T | undefined {\n        return this.elements.pop();\n    }\n\n    size(): number {\n        return this.elements.length;\n    }\n\n    print(): void {\n        console.log(\"Stack: \", this.elements);\n    }\n}\n\nlet stack = new Stack<number>();\nstack.push(10);\nstack.push(11);\nconsole.log(stack.print());\nconsole.log(stack.pop());\nconsole.log(stack.size());\n\n// Queue\nclass Queue<T> {\n    private elements: T[] = [];\n\n    enqueue(element: T): void {\n        this.elements.push(element);\n    }\n\n    dequeue(): T | undefined {\n        return this.elements.shift();\n    }\n\n    size(): number {\n        return this.elements.length;\n    }\n\n    print(): void {\n        console.log(\"Queue: \", this.elements);\n    }\n}\n\nlet queue = new Queue<string>();\nqueue.enqueue(\"A\");\nqueue.enqueue(\"B\");\nconsole.log(queue.print());\nconsole.log(queue.dequeue());\nconsole.log(queue.size());\n"
  },
  {
    "path": "Roadmap/08 - CLASES/typescript/david-git-dev.ts",
    "content": "/*\n  EJERCICIO:\n  Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n  atributos y una función que los imprima (teniendo en cuenta las posibilidades\n  de tu lenguaje).\n  Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n  utilizando su función.\n  */\nclass Ventilador {\n  private velocidad: number = 0;\n  private encendido: boolean = false;\n  constructor() {\n    this.encendido = true;\n  }\n  subir() {\n    this.velocidad += 1;\n  }\n  bajar() {\n    if (this.velocidad > 0) this.velocidad -= 1;\n  }\n  encenderApagar(): boolean {\n    return (this.encendido = !this.encendido);\n  }\n  estado(): {} {\n    return { staus: this.encendido, velocidad: this.velocidad };\n  }\n}\nconst ventilador = new Ventilador();\nventilador.estado();\nventilador.encenderApagar();\nventilador.subir();\nventilador.subir();\nventilador.subir();\nventilador.estado();\nventilador.bajar();\nventilador.estado();\nventilador.encenderApagar();\nventilador.estado();\nventilador.encenderApagar();\nventilador.estado();\n/*\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n */\nclass Stack {\n  private stack: any[] = [];\n  constructor(stack: any[] = []) {\n    this.stack = stack;\n  }\n  agregar(value: any) {\n    this.stack.push(value);\n  }\n  eliminar() {\n    return this.stack.pop();\n  }\n  get getLength() {\n    return this.stack.length;\n  }\n  get content() {\n    return this.stack;\n  }\n}\nconst stack = new Stack([1, 2, 3, 4]);\nstack.agregar(999);\nstack.getLength;\nstack.eliminar();\nstack.content;\n"
  },
  {
    "path": "Roadmap/08 - CLASES/typescript/duendeintemporal.ts",
    "content": "/* #08 { Retosparaprogramadores } CLASES */\n//bibliography reference\n//Secrets of the JavaScript Ninja (John Resig, Bear Bibeault, Josip Maras) (z-lib.org)\n//Professional JavaScript for web developers by Matt Frisbie [Frisbie, Matt] (z-lib.org)\n//JavaScript Notes for Professionals (GoalKicker.com) (Z-Library)\n//Python para todos (Raúl Gonzáles Duque)\n//GPT & Deepseek\n// I also trying the Cursor editor and his IA chat integrated\n\n/*                                        **Classes and Objects**\n\nTo understand this paradigm, we first need to comprehend what a class is and what an object is. An object is an entity that groups related state and functionality. The state of the object is defined through variables called attributes, while the functionality is modeled through functions known as the object's methods.\n\nAn example of an object could be a car, which would have attributes such as the brand, the number of doors, or the type of fuel, and methods such as start and stop. Alternatively, it could be any other combination of attributes and methods relevant to our program.\n\nA class, on the other hand, is nothing more than a generic template from which to instantiate objects; a template that defines what attributes and methods the objects of that class will have. */\n\n\n\n//Short for console.log() or we can just log = console.log; as in previus exercises\nconst log = console.log.bind(console);\n\n    log( 'Retosparaprogramadores #8'); \n\n\n/* A class can be composed of the class's constructor method, instance methods, getters, setters, and\nstatic class methods. None of these are explicitly required; an empty class definition is valid syntax.\nBy default, everything inside a class definition executes in strict mode. */\n\n/* The fundamental part of most classes is its constructor, which sets up each instance's initial state and handles any\nparameters that were passed when calling new. */\n\n/* Similar to the function type, there are two primary ways of defining a class: class declarations and\nclass expressions. Both use the class keyword and curly braces:\n// class declaration\nclass Person {}\n// class expression\nconst Animal = class {}; */\n\n/* Note: even though ES6 has introduced the class keyword, under the\nhood we're still dealing with good old prototypes; classes are syntactic sugar designed\nto make our lives a bit easier when mimicking classes in JavaScript.  */\n\n// User interface definition\ninterface IUser {\n    name: string;\n    nickname: string;\n    email: string;\n    greeting(): void;\n    getEmail(): string | void;\n    getName(): string | null;\n    getNickname(): string | null;\n    setName(name: string): void;\n    setEmail(email: string): void;\n    setNickname(nickname: string): void;\n    userInfo(): void;\n}\n\nclass User implements IUser {\n    public name: string;\n    public nickname: string;\n    public email: string;\n\n    constructor(name: string, nickname: string, email: string) {\n        this.name = name;\n        this.nickname = nickname;\n        this.email = email;\n    }\n\n    greeting(): void {\n        log(`Hi ${this.nickname}. Welcome to this Roadmap for Developers!`);\n    }\n\n    getEmail(): string | void {\n        if (this.email !== undefined) {\n            return this.email;\n        }\n        log('no email set yet!');\n        return;\n    }\n\n    getName(): string | null {\n        if (this.name !== undefined) {\n            return this.name;\n        }\n        log('no name set yet!');\n        return null;\n    }\n\n    getNickname(): string | null {\n        if (this.nickname !== undefined) {\n            return this.nickname;\n        }\n        log('no nickname set yet!');\n        return null;\n    }\n\n    setName(name: string): void {\n        if (name) this.name = name;\n    }\n\n    setEmail(email: string): void {\n        if (email) this.email = email;\n    }\n\n    setNickname(nickname: string): void {\n        if (nickname) this.nickname = nickname;\n    }\n    \n    userInfo(): void {\n        log(`User name: ${this.name || 'not set'}, User nickname: ${this.nickname || 'not set'}, User email: ${this.email || 'not set'}`);\n    }\n}\n\nlet user1 = new User('Niko Zen', 'duendeintemporal', 'duendeintemporal@hotmail.com');\nuser1.greeting(); // Hi duendeintemporal. Wellcome to this Roadmap for Developers!\n\nuser1.userInfo(); // user name: Niko Zen, user nickname: duendeintemporal, user email: duendeintemporal@hotmail.com \n\nuser1.setNickname('psicotrogato');\n\nlog(user1.getNickname()); // psicotrogato\n\n/* There is no formal class type in the ECMAScript specification, and in many ways ECMAScript classes\nbehave like special functions. Once declared, the class identifier identifies as a function when checked with the typeof operator: */\n\nlog(typeof User); // function\n\n/* As with function constructors, you can use the instanceof operator to test if the constructor prototype appears in the prototype chain of an instance: */\n\nlog(user1 instanceof User); // true\n\n/*  Class Inheritance\nInheritance works just like it does in other object-oriented languages: methods defined on the superclass are accessible in the extending subclass. */\n\n// Logger class\ninterface ILogger {\n    logger: typeof console.log;\n    errorLog: typeof console.error;\n    log(msj?: string): void;\n}\n\nclass Log implements ILogger {\n    public logger: typeof console.log;\n    public errorLog: typeof console.error;\n\n    constructor() {\n        this.logger = console.log;\n        this.errorLog = console.error;\n    }\n\n    log(msj?: string): void {\n        msj ? this.logger(msj) : this.errorLog('you should provide a msj');\n    }\n}\n\nclass Greeting extends Log {\n    private msj: string;\n\n    constructor(msj: string) {\n        super();\n        this.msj = msj;\n    }\n}\n\nlet sayHiPeople = new Greeting('Hi everybody. Welcome to the most wierd and lonly place in the cyberspace...');\n\nsayHiPeople.log(); // Hi everybody. Welcome to the most wierd and lonly place in the cyberspace...\n\n/*  Static Methods\nStatic methods and properties are defined on the class/constructor itself, not on instance objects. These are specified in a class definition by using the static keyword   */\n\nclass ElectroCat {\n    static catSay(): string {\n        return 'Miauu';\n    }\n    \n    static get catThink(): string {\n        return \"Let's see if there's some lovely gircat over there\";\n    } \n}\n\nlog(ElectroCat.catSay()); // Miauu\nlog(ElectroCat.catThink); // Let's see if there's some lovely gircat over there\n\n// We can see that static properties are not defined on object instances:\n\nconst mishu = new ElectroCat();\n//log(mishu.catSay()); // undefined OR throw an error\n//log(mishu.catThink); // undefined or throw an error\n\n// However, they are defined on subclasses:\n\nclass PoetCat extends ElectroCat {}\nlog(PoetCat.catSay()); // Miauu\nlog(PoetCat.catThink); // Let's see if there's some lovely gircat over there\n\n/* Getters and setters allow you to define custom behaviour for reading and writing a given property on your class. To the user, they appear the same as any typical property. However, internally a custom function you provide is used to determine the value when the property is accessed (the getter), and to perform any necessary changes when the property is assigned (the setter).\nIn a class definition, a getter is written like a no-argument method prefixed by the get keyword. A setter is similar, except that it accepts one argument (the new value being assigned) and the set keyword is used instead. */\n\nconst h_method = Symbol('Hidden method');\n\n//We use private properties in JavaScript classes to avoid infinite recursion in getters and setters by referencing the private property instead of the public property.\nclass GopiElectronica {\n    private _name: string;\n\n    constructor(name: string) {\n        this._name = name;\n    }\n\n    set name(name: string) {\n        this._name = name;\n    }\n\n    get name(): string {\n        return this._name;\n    }\n\n    // You can also create dynamic methods or use symbols or JavaScript expressions as keys \n    [h_method]() {\n        return 'I will hack you boy';\n    }\n}\n\nconst Nicky = new GopiElectronica('Nicky');\nlog(Nicky.name); // Nicky\nNicky.name = 'Samantha';\nlog(Nicky.name); // Samantha\nlog(Nicky[h_method]()); // I will hack you boy\nlog(Object.keys(Nicky)); // [ '_name' ] - will not show the symbol method\nlog(Reflect.ownKeys(Nicky)); // [ '_name' ] - Shows all keys including symbol keys\n\n\n\n\n\n\n/* Tips: (relevant info) \nClasses are first-class citizens in JavaScript, meaning they can be passed around as you would any\nother object or function reference:\n// Classes may be defined anywhere a function would, such as inside an array:\nlet classList = [\n    class {\n        constructor(id) {\n             this.id_ = id;\n             console.log('instance ${this.id_}');\n        }\n    }\n];\n\nfunction createInstance(classDefinition, id) {\n    return new classDefinition(id);\n}\n\nlet foo = createInstance(classList[0], 3141); // instance 3141 */\n\n\n/* Similar to an immediately invoked function expression, a class can also be immediately instantiated:\n// Because it is a class expression, the class name is optional\nlet p = new class Foo {\n    constructor(x) {\n        console.log(x);\n    }\n}('bar'); // bar\n\nconsole.log(p); // Foo {} */\n\n\n//Aditional Exercises\n\n//QUEUE\n\n// Queue interface\ninterface IQueue<T> {\n    enqueue(element: T): void;\n    dequeue(): T | undefined;\n    peek(): T | undefined;\n    empty(): T[];\n    isEmpty(): boolean;\n    size(): number;\n    getItems(): T[];\n}\n\nclass Queue<T> implements IQueue<T> {\n    private items: T[];\n\n    constructor(initialItems: T[] = []) {\n        this.items = Array.isArray(initialItems) ? initialItems : [];\n    }\n\n    getItems(): T[] {\n        return [...this.items];\n    }\n\n    enqueue(element: T): void {\n        this.items.push(element);\n    }\n\n    dequeue(): T | undefined {\n        if (this.isEmpty()) {\n            console.error(\"Queue is empty. Cannot dequeue an element.\");\n            return undefined;\n        }\n        return this.items.shift();\n    }\n\n    peek(): T | undefined {\n        if (this.isEmpty()) {\n            console.error(\"Queue is empty. Cannot peek.\");\n            return undefined;\n        }\n        return this.items[0];\n    }\n\n    empty(): T[] {\n        return this.items = [];\n    }\n\n    isEmpty(): boolean {\n        return this.items.length === 0;\n    }\n\n    size(): number {\n        return this.items.length;\n    }\n}\n\n// Test Queue\nfunction testQueue(): void {\n    const queue2 = new Queue<number>([45, 32, 16]);\n    log('Initial queue2:', queue2.getItems()); // Initial queue2: [45, 32, 16]\n\n    queue2.enqueue(77);\n    log('After enqueueing 77:', queue2.getItems()); // After enqueueing 77: [45, 32, 16, 77]\n\n    log('Peek:', queue2.peek());\n\n    log('Dequeue:', queue2.dequeue()); // Dequeue: 45\n    log('After dequeueing:', queue2.getItems()); // After dequeueing: [32, 16, 77]\n\n\n    log('Dequeue all elements:'); // Dequeue all elements:\n    while (!queue2.isEmpty()) {\n        log('Dequeued:', queue2.dequeue()); // Dequeued: 45\n    }\n\n    log('Final queue2:', queue2.getItems()); // Final queue2: []\n    log('Dequeue from empty queue2:', queue2.dequeue()); // Dequeue from empty queue2: undefined        \n\n}\n\n//STACK\n\n\n// Stack interface\ninterface IStack<T> {\n    push(element: T): void;\n    pop(): T | undefined;\n    peek(): T | undefined;\n    empty(): T[];\n    isEmpty(): boolean;\n    size(): number;\n    getItems(): T[];\n}\n\nclass Stack<T> implements IStack<T> {\n    private items: T[];\n\n    constructor(initialItems: T[] = []) {\n        this.items = Array.isArray(initialItems) ? initialItems : [];\n    }\n\n    getItems(): T[] {\n        return [...this.items];\n    }\n\n    push(element: T): void {\n        this.items.push(element);\n    }\n\n    pop(): T | undefined {\n        if (this.isEmpty()) {\n            console.error(\"Stack is empty. Cannot pop an element.\");\n            return undefined;\n        }\n        return this.items.pop();\n    }\n\n    peek(): T | undefined {\n        if (this.isEmpty()) {\n            console.error(\"Stack is empty. Cannot peek.\");\n            return undefined;\n        }\n        return this.items[this.items.length - 1];\n    }\n\n    empty(): T[] {\n        return this.items = [];\n    }\n\n    isEmpty(): boolean {\n        return this.items.length === 0;\n    }\n\n    size(): number {\n        return this.items.length;\n    }\n}\n\n// Test Stack\nfunction testStack(): void {\n    const stack2 = new Stack<number>([55, 76, 98, 100]);\n    log('Initial stack2:', stack2.getItems()); // Initial stack2: [55, 76, 98, 100]\n\n    stack2.push(32);\n    log('After pushing 32:', stack2.getItems()); // After pushing 32: [55, 76, 98, 100, 32]\n\n\n    log('Peek:', stack2.peek()); // 32\n\n    log('Pop:', stack2.pop()); // 32\n    log('After popping:', stack2.getItems()); // [55, 76, 98, 100, 32]\n\n    log('Pop all elements:'); // Pop all elements:\n    while (!stack2.isEmpty()) {\n        log('Popped:', stack2.pop());\n    }\n    \n    log('Final stack2:', stack2.getItems()); // Final stack2: []\n    log('Pop from empty stack2:', stack2.pop()); // Pop from empty stack2: undefined\n\n}\n\n\n// Run tests\ntestQueue(); // Queue\ntestStack(); // Stack\n\n/* Example 1: Classes as first-class citizens */\ninterface ClassWithId {\n    id_: number;\n}\n\n// Classes may be defined anywhere a function would, such as inside an array\nconst classList: Array<new (id: number) => ClassWithId> = [\n    class {\n        id_: number;\n        constructor(id: number) {\n            this.id_ = id;\n            console.log(`instance ${this.id_}`);\n        }\n    }\n];\n\nfunction createInstance(classDefinition: new (id: number) => ClassWithId, id: number): ClassWithId {\n    return new classDefinition(id);\n}\n\nconst foo = createInstance(classList[0], 3141); // instance 3141\n\n/* Example 2: Immediately instantiated class expression */\ninterface ImmediateClass {\n    value: string;\n}\n\n// Because it is a class expression, the class name is optional\nconst p = new class Foo implements ImmediateClass {\n    value: string;\n    \n    constructor(x: string) {\n        this.value = x;\n        console.log(x);\n    }\n}('bar'); // logs: bar\n\nconsole.log(p); // Foo { value: 'bar' }\n\n/* Note: These examples demonstrate TypeScript's ability to handle:\n1. Classes as values in arrays\n2. Generic type constraints\n3. Constructor signatures\n4. Immediately invoked class expressions\n5. Interface implementations */\n"
  },
  {
    "path": "Roadmap/08 - CLASES/typescript/eulogioep.ts",
    "content": "// Ejemplo de una clase en TypeScript\n\n/**\n * Clase Persona que representa a una persona con nombre y edad.\n */\nclass Persona {\n    private nombre: string;\n    private edad: number;\n\n    constructor(nombre: string, edad: number) {\n        this.nombre = nombre;\n        this.edad = edad;\n    }\n\n    // Métodos getter y setter\n    getNombre(): string {\n        return this.nombre;\n    }\n\n    setNombre(nombre: string): void {\n        this.nombre = nombre;\n    }\n\n    getEdad(): number {\n        return this.edad;\n    }\n\n    setEdad(edad: number): void {\n        this.edad = edad;\n    }\n\n    // Método para imprimir los datos de la persona\n    imprimirDatos(): void {\n        console.log(`Nombre: ${this.nombre}, Edad: ${this.edad}`);\n    }\n}\n\n/**\n * Clase Pila que implementa una estructura de datos de tipo pila (LIFO).\n */\nclass Pila<T> {\n    private elementos: T[];\n\n    constructor() {\n        this.elementos = [];\n    }\n\n    push(elemento: T): void {\n        this.elementos.push(elemento);\n    }\n\n    pop(): T | undefined {\n        return this.elementos.pop();\n    }\n\n    size(): number {\n        return this.elementos.length;\n    }\n\n    imprimirContenido(): void {\n        console.log(\"Contenido de la pila:\", this.elementos);\n    }\n}\n\n/**\n * Clase Cola que implementa una estructura de datos de tipo cola (FIFO).\n */\nclass Cola<T> {\n    private elementos: T[];\n\n    constructor() {\n        this.elementos = [];\n    }\n\n    enqueue(elemento: T): void {\n        this.elementos.push(elemento);\n    }\n\n    dequeue(): T | undefined {\n        return this.elementos.shift();\n    }\n\n    size(): number {\n        return this.elementos.length;\n    }\n\n    imprimirContenido(): void {\n        console.log(\"Contenido de la cola:\", this.elementos);\n    }\n}\n\n// Función principal para probar las implementaciones\nfunction main(): void {\n    // Prueba de la clase Persona\n    const persona = new Persona(\"Juan\", 30);\n    persona.imprimirDatos();\n    persona.setEdad(31);\n    persona.imprimirDatos();\n\n    // Prueba de la Pila\n    const pila = new Pila<number>();\n    pila.push(1);\n    pila.push(2);\n    pila.push(3);\n    pila.imprimirContenido();\n    console.log(\"Elemento extraído de la pila:\", pila.pop());\n    pila.imprimirContenido();\n\n    // Prueba de la Cola\n    const cola = new Cola<string>();\n    cola.enqueue(\"A\");\n    cola.enqueue(\"B\");\n    cola.enqueue(\"C\");\n    cola.imprimirContenido();\n    console.log(\"Elemento extraído de la cola:\", cola.dequeue());\n    cola.imprimirContenido();\n}\n\n// Ejecutar la función principal\nmain();"
  },
  {
    "path": "Roadmap/08 - CLASES/typescript/hozlucas28.ts",
    "content": "/*\n    Classes...\n*/\n\ntype Brand = 'BMW' | 'Ford' | 'Toyota' | 'Fiat'\ntype Color = 'black' | 'grey' | 'red' | 'blue' | 'yellow'\n\ntype Constructor = {\n\tbrand: Brand\n\tcolor: Color\n\tname: string\n\tprice: number\n}\n\nclass Car {\n\tprivate _brand: Brand\n\tprivate _color: Color\n\tprivate _name: string\n\tprivate _price: number\n\n\tconstructor({ brand, color, name, price }: Constructor) {\n\t\tthis._brand = brand\n\t\tthis._color = color\n\t\tthis._name = name\n\t\tthis._price = price\n\t}\n\n\tpublic get brand(): Brand {\n\t\treturn this._brand\n\t}\n\n\tpublic get color(): Color {\n\t\treturn this._color\n\t}\n\n\tpublic get name(): string {\n\t\treturn this._name\n\t}\n\n\tpublic get price(): number {\n\t\treturn this._price\n\t}\n\n\tpublic set brand(brand: Brand) {\n\t\tthis._brand = brand\n\t}\n\n\tpublic set color(color: Color) {\n\t\tthis._color = color\n\t}\n\n\tpublic set name(name: string) {\n\t\tthis._name = name\n\t}\n\n\tpublic set price(price: number) {\n\t\tthis._price = price\n\t}\n\n\tpublic printAttributes(): void {\n\t\tconsole.log('\\nCar attributes:')\n\t\tconsole.log(`Brand --> ${this._brand}`)\n\t\tconsole.log(`Color --> ${this._color}`)\n\t\tconsole.log(`Name --> ${this._name}`)\n\t\tconsole.log(`Price --> $${this._price}`)\n\t}\n}\n\nconsole.log('Classes in TypeScript...\\n')\n\nconsole.log(`type Brand = 'BMW' | 'Ford' | 'Toyota' | 'Fiat'\ntype Color = 'black' | 'grey' | 'red' | 'blue' | 'yellow'\n\ntype Constructor = {\n    brand: Brand\n    color: Color\n    name: string\n    price: number\n}\n\nclass Car {\n    private _brand: Brand\n    private _color: Color\n    private _name: string\n    private _price: number\n\n    constructor({ brand, color, name, price }: Constructor) {\n        this._brand = brand\n        this._color = color\n        this._name = name\n        this._price = price\n    }\n\n    public get brand(): Brand {\n        return this._brand\n    }\n\n    public get color(): Color {\n        return this._color\n    }\n\n    public get name(): string {\n        return this._name\n    }\n\n    public get price(): number {\n        return this._price\n    }\n\n    public set brand(brand: Brand) {\n        this._brand = brand\n    }\n\n    public set color(color: Color) {\n        this._color = color\n    }\n\n    public set name(name: string) {\n        this._name = name\n    }\n\n    public set price(price: number) {\n        this._price = price\n    }\n\n    public printAttributes(): void {\n        console.log('\\\\nCar attributes:')\n        console.log(\\`Brand --> \\${this._brand}\\`)\n        console.log(\\`Color --> \\${this._color}\\`)\n        console.log(\\`Name --> \\${this._name}\\`)\n        console.log(\\`Price --> $\\${this._price}\\`)\n    }\n}`)\n\nconsole.log(\n\t'\\n' +\n\t\t`const car = new Car({ brand: 'Ford', color: 'grey', name: 'Focus', price: 21000 })\ncar.printAttributes()`\n)\n\nconst car = new Car({ brand: 'Ford', color: 'grey', name: 'Focus', price: 21000 })\ncar.printAttributes()\n\nconsole.log(\n\t'\\n' +\n\t\t`car.brand = 'Fiat'\ncar.color = 'grey'\ncar.name = 'Cronos'\ncar.price = 18000\ncar.printAttributes()`\n)\n\ncar.brand = 'Fiat'\ncar.color = 'grey'\ncar.name = 'Cronos'\ncar.price = 18000\ncar.printAttributes()\n\nconsole.log('\\n# ---------------------------------------------------------------------------------- #\\n')\n\n/*\n    Additional challenge...\n*/\n\nconsole.log('Additional challenge...')\n\n// Stack exercise...\nclass Stack<T extends number | string> {\n\tprivate _lastElement: T | undefined\n\tprivate _length: number\n\tprivate _stack: T[]\n\n\tconstructor(stack: T[] = []) {\n\t\tthis._lastElement = stack.at(-1)\n\t\tthis._length = stack.length\n\t\tthis._stack = stack\n\t}\n\n\tpublic get lastElement(): T | undefined {\n\t\treturn this._lastElement\n\t}\n\n\tpublic get length(): number {\n\t\treturn this._length\n\t}\n\n\tpublic get stack(): T[] {\n\t\treturn this._stack\n\t}\n\n\tpublic appendElement(element: T): this {\n\t\tthis._length = this._stack.push(element)\n\t\tthis._lastElement = this._stack.at(-1)\n\t\treturn this\n\t}\n\n\tpublic deleteLastElement(): this {\n\t\tthis._stack.pop()\n\t\tthis._lastElement = this._stack.at(-1)\n\t\tthis._length--\n\t\treturn this\n\t}\n\n\tpublic printAttributes(): this {\n\t\tconsole.table({\n\t\t\tlastElement: this._lastElement,\n\t\t\tlength: this._length,\n\t\t\tstack: this._stack,\n\t\t})\n\t\treturn this\n\t}\n}\n\nconst myStack = new Stack<string>(['Lucas', 'Nahuel', 'Hoz'])\n\nmyStack.appendElement('21')\n\nconsole.log('\\nStack attributes...')\nmyStack.printAttributes()\n\nmyStack.deleteLastElement().deleteLastElement()\n\nconsole.log('\\nStack attributes...')\nmyStack.printAttributes()\n\nconst stackLength = myStack.length\nconsole.log(`\\nStack length --> ${stackLength}`)\n\n// Queue exercise...\n\nclass Queue<T extends number | string> {\n\tprivate _length: number\n\tprivate _firstElement: T | undefined\n\tprivate _queue: T[]\n\n\tconstructor(queue: T[]) {\n\t\tthis._length = queue.length\n\t\tthis._firstElement = queue.at(0)\n\t\tthis._queue = queue\n\t}\n\n\tpublic get length(): number {\n\t\treturn this._length\n\t}\n\n\tpublic get firstElement(): T | undefined {\n\t\treturn this._firstElement\n\t}\n\n\tpublic get queue(): T[] {\n\t\treturn this._queue\n\t}\n\n\tpublic appendElement(element: T): this {\n\t\tthis._length = this._queue.push(element)\n\t\treturn this\n\t}\n\n\tpublic deleteFirstElement(): this {\n\t\tthis._queue.shift()\n\t\tthis._length--\n\t\tthis._firstElement = this._queue.at(0)\n\t\treturn this\n\t}\n\n\tpublic printAttributes(): this {\n\t\tconsole.table({\n\t\t\tlength: this._length,\n\t\t\tfirstElement: this._firstElement,\n\t\t\tqueue: this._queue,\n\t\t})\n\t\treturn this\n\t}\n}\n\nconst myQueue = new Queue<string>(['Buenos', 'Aires', 'Argentina'])\n\nmyQueue.appendElement('2024')\n\nconsole.log('\\nQueue attributes...')\nmyQueue.printAttributes()\n\nmyQueue.deleteFirstElement().deleteFirstElement()\n\nconsole.log('\\nQueue attributes...')\nmyQueue.printAttributes()\n\nconst queueLength = myQueue.length\nconsole.log(`\\nQueue length --> ${queueLength}`)\n"
  },
  {
    "path": "Roadmap/08 - CLASES/typescript/ialmontedr0.ts",
    "content": "/**\r\n * Clase Persona\r\n */\r\n\r\n// Implementación del inicializador\r\nclass Persona {\r\n  nombre: string; // Atributo de la clase\r\n  edad: number; // Atributo de la clase\r\n  lenguajes: string[]; // Atributo de la clase\r\n\r\n  constructor(nombre: string, edad: number, lenguajes: string[]) {\r\n    // Inicializador de la clase\r\n    this.nombre = nombre; // Asignación del valor al atributo\r\n    this.edad = edad; // Asignación del valor al atributo\r\n    this.lenguajes = lenguajes; // Asignación del valor al atributo\r\n  }\r\n\r\n  imprimir() {\r\n    // Función que imprime los datos de la persona\r\n    console.log(\r\n      \"Hola, mi nombre es \" +\r\n        this.nombre +\r\n        \", tengo \" +\r\n        this.edad +\r\n        \" y conozco los lenguajes: \" +\r\n        this.lenguajes\r\n    );\r\n  }\r\n}\r\n\r\nlet persona1 = new Persona(\"Anthony\", 26, [\"TS\", \"Py\", \"C\"]); // Creación y establecimiento de parámetros\r\npersona1.imprimir(); // Impresión de los datos\r\n\r\n// Ejercicio extra: Implementación de Pila y Cola (LIFO y FIFO)\r\n// Clase Pila (Last In, First Out)\r\nclass Pila {\r\n  arreglo: any[];\r\n\r\n  constructor() {\r\n    this.arreglo = [];\r\n  }\r\n\r\n  // Métodos de la Pila\r\n  apilar(elemento: any) {\r\n    this.arreglo.push(elemento);\r\n  }\r\n\r\n  // Método desapilar\r\n  desapilar(): any {\r\n    if (this.arreglo.length === 0) {\r\n      throw new Error(\"La pila está vacía\");\r\n      return null;\r\n    }\r\n    return this.arreglo.pop();\r\n  }\r\n\r\n  // Método contar\r\n  contar(): number {\r\n    return this.arreglo.length;\r\n  }\r\n\r\n  // Método imprimir\r\n  imprimir() {\r\n    console.log(\"Contenido de la pila:\");\r\n    for (let i = this.arreglo.length - 1; i >= 0; i--) {\r\n      console.log(this.arreglo[i]);\r\n    }\r\n  }\r\n}\r\n\r\nlet pila = new Pila(); // Creación de la pila\r\npila.apilar(\"Hola\");\r\npila.apilar(\"Mundo\");\r\npila.contar(); // Impresión del número de elementos en la pila\r\npila.imprimir(); // Impresión del contenido de la pila\r\n\r\n// Clase Cola (First In, First Out)\r\nclass Cola {\r\n  arreglo: any[];\r\n\r\n  constructor() {\r\n    this.arreglo = [];\r\n  }\r\n\r\n  // Métodos de la Cola\r\n  // Metodo encolar\r\n  encolar(elemento: any) {\r\n    this.arreglo.push(elemento);\r\n  }\r\n\r\n  // Método desencolar\r\n  desencolar(): any {\r\n    if (this.arreglo.length === 0) {\r\n      throw new Error(\"La cola esta vacia\");\r\n    }\r\n    return this.arreglo.pop(0);\r\n  }\r\n\r\n  // Método contar\r\n  contar(): number {\r\n    return this.arreglo.length;\r\n  }\r\n\r\n  // Método imprimir para mostrar los elementos de la cola\r\n  imprimir() {\r\n    console.log(\"Contenido de la cola:\");\r\n    for (let i = 0; i < this.arreglo.length; i++) {\r\n      console.log(this.arreglo[i]);\r\n    }\r\n  }\r\n}\r\n\r\nlet cola = new Cola(); // Creación de la cola\r\ncola.encolar(\"Hola\");\r\ncola.encolar(\"Mundo\");\r\ncola.contar(); // Impresión del número de elementos en la cola\r\ncola.imprimir(); // Imprimimos la cola\r\ncola.desencolar(); // Eliminación del primer elemento en la cola\r\ncola.imprimir(); // Imprimimos la cola\r\n"
  },
  {
    "path": "Roadmap/08 - CLASES/typescript/juserdev.ts",
    "content": "// # #08 CLASES\n// > #### Dificultad: Fácil | Publicación: 19/02/24 | Corrección: 26/02/24\n\n// ## Ejercicio\n\n\n/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n * \n */\n\n\n//Estructura basica de Clases\n\nnamespace clase8 {\n    class Persona { // Porpiedad\n        nombre: string;\n\n        constructor(nombre: string){\n            this.nombre = nombre //Inicializacion\n        }\n\n        saludar(): string{ //metodo - esto es como una funcion\n            return `¡Hola! soy ${this.nombre}` \n        }\n    }\n\n    //crear una instancia\n    const Persona1 = new Persona(\"Sebastian\")\n    console.log(Persona1.saludar()) //¡Hola! soy Sebastian\n\n\n    //Modificadores de acceso\n\n    class Banco {\n        public nombreBanco: string\n        private balanceBanco: number\n\n        constructor(Nombre: string, balance: number){\n            this.nombreBanco = Nombre\n            this.balanceBanco = balance\n        }\n\n        public consultarBalance(): string{\n            return `el balance es $${this.balanceBanco}`\n        }\n\n        private actualizarBalance(cantidad: number): void {\n            this.balanceBanco += cantidad\n        }\n    }\n\n    const banco1 = new Banco(\"Banco Central\", 1000)\n    console.log(banco1.consultarBalance())\n    \n    //banco1.actualizarBalance(500) //la propidad actualizarBalance es privada\n\n    //Metodos y propieaddes estaticas\n\n    class Matematicas {\n        static PI: number = 3.1416\n\n        static calcularCircunferencia(radio: number): number{\n            return 2 * this.PI * radio\n        }\n    }\n\n    console.log(Matematicas.PI)\n    console.log(Matematicas.calcularCircunferencia(5))\n\n    // Herencia\n\n    class Animal {\n        nombre: string\n\n        constructor(nombre: string) {\n            this.nombre = nombre\n        }\n\n        emitirSonido(): string {\n            return `Hace un sonido generico`\n        }\n    }\n\n    class Perro extends Animal {\n        emitirSonido(): string {\n            return `¡Guau!`\n        }\n    }\n\n    class Pollito extends Animal{\n        emitirSonido(): string {\n            return `Pio pio pio!!`\n        }\n    }\n\n    const gato = new Animal(\"Michi\")\n    console.log(gato.nombre)\n    console.log(gato.emitirSonido())\n\n    const perro = new Perro(\"Firulais\")\n    console.log(perro.nombre)\n    console.log(perro.emitirSonido())\n\n    const pollito = new Pollito(\"Theo\")\n    console.log(pollito.nombre)\n    console.log(pollito.emitirSonido())\n\n    // Clases abstractas\n\n    abstract class Figura {\n        abstract calcularArea(): number\n\n        description(): string {\n            return `Soy una figura geometria`\n        }\n    }\n\n    class Cuadrado extends Figura {\n        lado: number\n\n        constructor(lado: number){\n            super()\n            this.lado = lado\n        }\n\n        calcularArea(): number {\n            return this.lado ** 2\n        }\n    }\n\n\n    const cuadrado = new Cuadrado(4)\n    console.log(cuadrado.description())\n    console.log(cuadrado.calcularArea())\n\n\n    // Interface vs Calses\n\n    interface Vehiculo {\n        marca: string\n        modelo: string\n        conducir(): void\n    }\n\n    class Coche implements Vehiculo {\n        marca: string\n        modelo: string\n\n        constructor(marca: string, modelo: string){\n            this.marca = marca\n            this.modelo = modelo\n        }\n\n        conducir(): void {\n            console.log(`Conduiendo un ${this.marca} modelo ${this.modelo}`)\n            return\n        }\n    }\n\n    const coche = new Coche(\"toyota\", \"corola\")\n    coche.conducir()\n\n    // Ejemplo practico mas largo\n\n    class Personas {\n        nombre: string\n        edad: number\n        ocupacion: string\n\n        constructor(nombre: string, edad: number, ocupacion: string) {\n            this.nombre = nombre\n            this.edad = edad\n            this.ocupacion = ocupacion\n        }\n\n        saludar(): string{\n            return `¡Hola! soy ${this.nombre}`\n        }\n\n        presentarse(): string {\n            return `Me llamo ${this.nombre}, tengo ${this.edad} y soy ${this.ocupacion}.`\n        }\n\n        cumplirAnios(): void {\n            this.edad++\n        }\n    }\n\n    const personas1 = new Personas(\"Ana\", 25, \"desarrolladora Web\")\n    const personas2 = new Personas(\"Sebastian\", 33, \"desarrollador web\")\n\n\n    console.log(personas1.saludar())\n    console.log(personas1.presentarse())\n\n    console.log(personas2.nombre)\n    console.log(personas2.edad)\n    console.log(personas2.ocupacion)\n    console.log(personas2.presentarse())\n\n    personas2.cumplirAnios()\n    console.log(personas2.presentarse())\n\n\n\n    //! SOLUCION DEL PROBLEMA\n\n    class Programer {\n        name: string\n        sername?: string\n        age: number\n        lenguajes: string[]\n\n        constructor(name: string, age: number, lenguajes: string[], sername?: string){\n            this.name = name\n            this.sername = sername\n            this.age = age\n            this.lenguajes = lenguajes\n        }\n\n        print(): string{\n            return `nombre: ${this.name}${this.sername ? \", Apellido: \" + this.sername : \"\"}, edad: ${this.age}, lenguajes: ${this.lenguajes}`\n        }\n\n    }\n\n    const sebastian = new Programer(\"Sebastian\", 30, [\"JavaScipt\", \"TypeScript\"])\n    const juan = new Programer(\"juan\", 33, [\"JavaScipt\", \"TypeScript\"], \"rocha\")\n\n    console.log(sebastian.print())\n    console.log(juan.print())\n\n    sebastian.age = 33 //modifique la edad\n\n    console.log(sebastian.print()) //edad modificada\n\n    //! DIFICULTAD EXTRA\n\n    class Stack {\n        stack: any[]\n\n        constructor(){\n            this.stack = []\n        }\n\n        push(item){\n            this.stack.push(item)\n            return this.stack\n        }\n\n        pop(){\n            if (this.count() === 0) {\n                return \"no hay nada que borrar\"\n            }\n            return this.stack.pop()\n        }\n\n        count(){\n            return this.stack.length\n        }\n\n        print(){\n            if (this.count() > 0) {\n                return this.stack.slice().reverse()\n            }\n            return \"El Stack esta vacio\"\n        }\n    }\n\n    const stack = new Stack()\n    \n    stack.push(\"A\")\n    stack.push(\"B\")\n    stack.push(\"C\")\n    console.log(stack.count())\n    console.log(stack.print())\n    console.log(stack.pop())\n    console.log(stack.count())\n    console.log(stack.print())\n    console.log(stack.pop())\n    console.log(stack.count())\n    console.log(stack.print())\n    console.log(stack.pop())\n    console.log(stack.count())\n    console.log(stack.print())\n\n\n    class Queue {\n        queue: any[]\n\n        constructor(){\n            this.queue = []\n        }\n\n        push(item){\n            this.queue.push(item)\n            return this.queue\n        }\n\n        shift(){\n            if (this.count() === 0) {\n                return \"no hay nada que borrar\"\n            }\n            return this.queue.shift()\n        }\n\n        count(){\n            return this.queue.length\n        }\n\n        print(){\n            if (this.count() > 0) {\n                return this.queue.slice()\n            }\n            return \"El queue esta vacio\"\n        }\n    }\n\n    const myQueue = new Queue()\n    \n    myQueue.push(\"A\")\n    myQueue.push(\"B\")\n    myQueue.push(\"C\")\n    console.log(myQueue.count())\n    console.log(myQueue.print())\n    console.log(myQueue.shift())\n    console.log(myQueue.count())\n    console.log(myQueue.print())\n    console.log(myQueue.shift())\n    console.log(myQueue.count())\n    console.log(myQueue.print())\n    console.log(myQueue.shift())\n    console.log(myQueue.count())\n    console.log(myQueue.print())\n    console.log(myQueue.shift())\n    console.log(myQueue.count())\n    console.log(myQueue.print())\n\n}"
  },
  {
    "path": "Roadmap/08 - CLASES/typescript/marcode24.ts",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n */\n\nclass Stack<T> {\n  private items: T[];\n\n  constructor() {\n    this.items = [];\n  }\n\n  push(element: T): void {\n    this.items.push(element);\n  }\n\n  pop(): T | string {\n    if (this.isEmpty()) {\n      return 'La pila está vacía';\n    }\n    return this.items.pop() as T;\n  }\n\n  isEmpty(): boolean {\n    return this.items.length === 0;\n  }\n\n  peek(): T | undefined {\n    return this.items[this.items.length - 1];\n  }\n\n  clear(): void {\n    this.items = [];\n  }\n\n  size(): number {\n    return this.items.length;\n  }\n}\n\nclass Queue<T> {\n  private items: T[];\n\n  constructor() {\n    this.items = [];\n  }\n\n  enqueue(element: T): void {\n    this.items.push(element);\n  }\n\n  dequeue(): T | string {\n    if (this.isEmpty()) {\n      return 'La cola está vacía';\n    }\n    return this.items.shift() as T;\n  }\n\n  isEmpty(): boolean {\n    return this.items.length === 0;\n  }\n\n  size(): number {\n    return this.items.length;\n  }\n}\n\nconst pila = new Stack<number>();\npila.push(1);\npila.push(2);\npila.push(3);\nconsole.log(pila.pop()); // 3\nconsole.log(pila.pop()); // 2\n\nconst cola = new Queue<string>();\ncola.enqueue('a');\ncola.enqueue('b');\ncola.enqueue('c');\nconsole.log(cola.dequeue()); // a\nconsole.log(cola.dequeue()); // b\n\nclass Navegador {\n  private history: Stack<string>;\n  private future: Stack<string>;\n  private currentPage: string | null;\n\n  constructor() {\n    this.history = new Stack<string>();\n    this.future = new Stack<string>();\n    this.currentPage = null;\n  }\n\n  // navegar a una nueva página\n  goToPage(page: string): void {\n    if (this.currentPage !== null) {\n      this.history.push(this.currentPage);\n    }\n    this.currentPage = page;\n    this.future.clear();\n    console.log('Página actual: ', this.currentPage);\n  }\n\n  // retroceder a la página anterior\n  goBack(): void {\n    if (this.history.isEmpty()) {\n      console.log('No hay páginas anteriores');\n      return;\n    }\n    this.future.push(this.currentPage as string);\n    this.currentPage = this.history.pop() as string;\n    console.log('Página actual: ', this.currentPage);\n  }\n\n  // avanzar a la página siguiente\n  goForward(): void {\n    if (this.future.isEmpty()) {\n      console.log('No hay páginas siguientes');\n      return;\n    }\n    this.history.push(this.currentPage as string);\n    this.currentPage = this.future.pop() as string;\n    console.log('Página actual: ', this.currentPage);\n  }\n}\n\nconst navegador = new Navegador();\nnavegador.goToPage('google.com');\nnavegador.goToPage('facebook.com');\nnavegador.goToPage('twitter.com');\nnavegador.goBack(); // regresa a facebook.com\nnavegador.goBack(); // regresa a google.com\nnavegador.goForward(); // avanza a facebook.com\nnavegador.goToPage('instagram.com'); // instagram.com\nnavegador.goBack(); // regresa a facebook.com\nnavegador.goForward(); // avanza a instagram.com\n\n// Visita mi repo en GitHub para ver y correr los tests de este código --> https://github.com/marcode24/weekly-challenges\n"
  },
  {
    "path": "Roadmap/08 - CLASES/typescript/miguelex.ts",
    "content": "class Vehiculo {\n    nombre: string;\n    numRuedas: number;\n\n    constructor(nombre: string, numRuedas: number) {\n        this.nombre = nombre;\n        this.numRuedas = numRuedas;\n    }\n\n    toString(): string {\n        return `Nombre: ${this.nombre}, Ruedas: ${this.numRuedas}`;\n    }\n}\n\nlet coche = new Vehiculo(\"Coche\", 4);\nlet bicicleta = new Vehiculo(\"Bicicleta\", 2);\n\nconsole.log(coche.toString());\nconsole.log(bicicleta.toString());\n\nclass Pila {\n    pila: any[];\n\n    constructor() {\n        this.pila = [];\n    }\n\n    push(elemento: any): void {\n        this.pila.push(elemento);\n    }\n\n    pop(): any {\n        return this.pila.pop();\n    }\n\n    toString(): string {\n        return this.pila.toString();\n    }\n\n    size(): number {\n        return this.pila.length;\n    }\n}\n\nclass Cola {\n    cola: any[];\n\n    constructor() {\n        this.cola = [];\n    }\n\n    push(elemento: any): void {\n        this.cola.push(elemento);\n    }\n\n    pop(): any {\n        return this.cola.shift();\n    }\n\n    toString(): string {\n        return this.cola.toString();\n    }\n\n    size(): number {\n        return this.cola.length;\n    }\n}\n\nlet pila = new Pila();\n\nconsole.log(\"Ejemplo de pila\");\n\npila.push(1);\npila.push(2);\npila.push(3);\nconsole.log(\"Contendido de la pila: \" + pila.toString());\nconsole.log(\"Extraigo en elemento que esta en la cima: \" + pila.pop());\nconsole.log(\"Contendido de la pila: \" + pila.toString());\nconsole.log(\"Tamaño de la pila: \" + pila.size());\n\nlet cola = new Cola();\n\nconsole.log(\"Ejemplo de cola\");\n\ncola.push(1);\ncola.push(2);\ncola.push(3);\n\nconsole.log(\"Contendido de la cola: \" + cola.toString());\nconsole.log(\"Extraigo el primer elemento de la cola: \" + cola.pop());\nconsole.log(\"Contendido de la cola: \" + cola.toString());\nconsole.log(\"Tamaño de la cola: \" + cola.size());\n"
  },
  {
    "path": "Roadmap/08 - CLASES/typescript/nlarrea.ts",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n * de tu lenguaje).\n * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n * utilizando su función.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n */\n\n\nclass Student {\n    name: string\n    email: string\n    subjects: string[]\n\n    constructor(name: string, email: string, subjects: string[]) {\n        this.name = name\n        this.email = email\n        this.subjects = subjects\n    }\n\n    printStudentData() {\n        console.log(`Name: ${this.name}`)\n        console.log(`Email: ${this.email}`)\n        \n        console.log('These are this student\\'s subjects:')\n        for (const subject of this.subjects) {\n            console.log(` - ${subject}`)\n        }\n    }\n}\n\n\nconst student1 = new Student(\n    'Naia',\n    'naia@email.com',\n    ['Electronics', 'Informatics', 'Maths']\n)\nconst student2: Student = new Student(\n    'Cristina',\n    'cristina@email.com',\n    ['Anatomy', 'Pathologies']\n)\n\nstudent1.printStudentData()\n/**\n * Name: Naia\n * Email: naia@email.com\n * These are this student's subjects:\n *  - Electronics\n *  - Informatics\n *  - Maths\n */\nstudent2.printStudentData()\n/**\n * Name: Cristina\n * Email: cristina@email.com\n * These are this student's subjects:\n *  - Anatomy\n *  - Pathologies\n */\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n * en el ejercicio número 7 de la ruta de estudio)\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n *   retornar el número de elementos e imprimir todo su contenido.\n */\n\n\n// Stack - LIFO\n\n\nclass Stack {\n    stack: any[]\n\n    constructor(stack: any[] = []) {\n        this.stack = stack\n    }\n\n    insert(item: any): void {\n        this.stack.push(item)\n    }\n\n    remove() {\n        this.stack.pop()\n    }\n\n    length(): number {\n        return this.stack.length\n    }\n\n    getContent(): any[] {\n        return this.stack\n    }\n}\n\n\nconst myStack: Stack = new Stack()\nconsole.log(myStack.length())  // 0\n\n// Add data\nmyStack.insert(1)\nmyStack.insert(2)\nmyStack.insert(3)\nmyStack.insert(4)\n\nconsole.log(myStack.getContent())  // [1, 2, 3, 4]\nconsole.log(myStack.length())  // 4\n\n// Remove data\nmyStack.remove()\nconsole.log(myStack.getContent())  // [1, 2, 3]\nconsole.log(myStack.length())  // 3\n\nmyStack.remove()\nconsole.log(myStack.getContent())  // [1, 2]\nconsole.log(myStack.length())  // 2\n\n\n// Queue - FIFO\n\n\nclass Queue {\n    queue: any[]\n\n    constructor(queue: any[] = []) {\n        this.queue = queue\n    }\n\n    insert(item: any): void {\n        this.queue.push(item)\n    }\n\n    remove() {\n        this.queue.splice(0, 1)\n    }\n\n    length(): number {\n        return this.queue.length\n    }\n\n    getContent(): any[] {\n        return this.queue\n    }\n}\n\n\nconst myQueue: Queue = new Queue()\nconsole.log(myQueue.length())  // 0\n\n// Add data\nmyQueue.insert(1)\nmyQueue.insert(2)\nmyQueue.insert(3)\nmyQueue.insert(4)\n\nconsole.log(myQueue.getContent())  // [1, 2, 3, 4]\nconsole.log(myQueue.length())  // 4\n\n// Remove data\nmyQueue.remove()\nconsole.log(myQueue.getContent())  // [2, 3, 4]\nconsole.log(myQueue.length())  // 3\n\nmyQueue.remove()\nconsole.log(myQueue.getContent())  // [3, 4]\nconsole.log(myQueue.length())  // 2"
  },
  {
    "path": "Roadmap/08 - CLASES/typescript/qv1ko.ts",
    "content": "class C1 {\n\n    c1String: string;\n\n    constructor(c1String: string) {\n        this.c1String = c1String;\n    }\n\n    getC1String() {\n        return this.c1String;\n    }\n\n    setC1String(c1String: string) {\n        this.c1String = c1String;\n    }\n\n    toString() {\n        return this.c1String;\n    }\n\n    print() {\n        console.log(this.c1String);\n    }\n\n}\n\nclass C2 {\n\n    c2String: string;\n\n    constructor(c2String: string) {\n        this.c2String = c2String;\n    }\n\n    getC2String() {\n        return this.c2String;\n    }\n\n    setC2String(c2String: string) {\n        this.c2String = c2String;\n    }\n\n    toString() {\n        return this.c2String;\n    }\n\n    print() {\n        console.log(this.c2String);\n    }\n\n}\n\nfunction main() {\n    \n    let example1: C1 = new C1(\"example\");\n    example1.print();\n    example1.setC1String(\"Example 1\");\n    console.log(example1.toString());\n\n    let example2: C2 = new C2(\"example\");\n    example2.print();\n    example2.setC2String(\"Example 2\");\n    console.log(example2.toString());\n\n}\n\nmain();\n"
  },
  {
    "path": "Roadmap/08 - CLASES/typescript/qwik-zgheib.ts",
    "content": "/* -- exercise */\nclass Person {\n  name: string;\n  age: number;\n\n  constructor(name: string, age: number) {\n    this.name = name;\n    this.age = age;\n  }\n\n  printDetails(): void {\n    console.log(`Name: ${this.name}, Age: ${this.age}`);\n  }\n\n  setDetails(name: string, age: number): void {\n    this.name = name;\n    this.age = age;\n  }\n}\n\nlet person = new Person(\"Abdul Rahman\", 22);\nperson.printDetails();\nperson.setDetails(\"Ahmed Khedr\", 20);\nperson.printDetails();\n\n/* -- extra challenge */\nclass Stack<T> {\n  private items: T[];\n\n  constructor() {\n    this.items = [];\n  }\n\n  push(element: T): void {\n    this.items.push(element);\n  }\n\n  pop(): T | string {\n    if (this.isEmpty()) {\n      return \"Stack is empty\";\n    }\n    return this.items.pop() as T;\n  }\n\n  size(): number {\n    return this.items.length;\n  }\n\n  print(): void {\n    console.log(\"Stack:\", this.items.toString());\n  }\n\n  isEmpty(): boolean {\n    return this.items.length === 0;\n  }\n}\n\nlet stack = new Stack<number>();\nstack.push(10);\nstack.push(20);\nstack.push(30);\nstack.print();\nconsole.log(\"Popped:\", stack.pop());\nstack.print();\nconsole.log(\"Size:\", stack.size());\n\nclass Queue<T> {\n  private items: T[];\n\n  constructor() {\n    this.items = [];\n  }\n\n  enqueue(element: T): void {\n    this.items.push(element);\n  }\n\n  dequeue(): T | string {\n    if (this.isEmpty()) {\n      return \"Queue is empty\";\n    }\n    return this.items.shift() as T;\n  }\n\n  size(): number {\n    return this.items.length;\n  }\n\n  print(): void {\n    console.log(\"Queue:\", this.items.toString());\n  }\n\n  isEmpty(): boolean {\n    return this.items.length === 0;\n  }\n}\n\nlet queue = new Queue<number>();\nqueue.enqueue(10);\nqueue.enqueue(20);\nqueue.enqueue(30);\nqueue.print();\nconsole.log(\"Dequeued:\", queue.dequeue());\nqueue.print();\nconsole.log(\"Size:\", queue.size());\n"
  },
  {
    "path": "Roadmap/08 - CLASES/typescript/victor-Casta.ts",
    "content": "/*\n  * EJERCICIO:\n  * Explora el concepto de clase y crea un ejemplo que implemente un inicializador,\n  * atributos y una función que los imprima (teniendo en cuenta las posibilidades\n  * de tu lenguaje).\n  * Una vez implementada, créala, establece sus parámetros, modifícalos e imprímelos\n  * utilizando su función.\n*/\n\nclass User {\n  name: string\n  age: number\n  email: string\n  constructor(name: string, age: number, email: string) {\n    this.name = name\n    this.age = age\n    this.email = email\n  }\n\n  print():void {\n    console.log(`Nombre: ${this.name}, Edad: ${this.age}, Email: ${this.email}`)\n  }\n}\n\nconst user1 = new User('Victor', 21, 'victor@gmail.com')\nuser1.print()\n\n/*\n  * DIFICULTAD EXTRA (opcional):\n  * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\n  * en el ejercicio número 7 de la ruta de estudio)\n  * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar,\n  *   retornar el número de elementos e imprimir todo su contenido.\n*/\n\n// Pilas - LIFO\n\nclass Stack<T> {\n  private listStack: T[]\n\n  constructor() {\n    this.listStack = []\n  }\n\n  adding(input: T): void {\n    this.listStack.push(input)\n  }\n\n  removing(): T | undefined {\n    return this.listStack.pop()\n  }\n\n  numberOfElements(): number {\n    return this.listStack.length\n  }\n\n  printStackContent(): void {\n    console.table(this.listStack)\n  }\n}\n\nconst numberStack = new Stack<number>()\nnumberStack.adding(1)\nnumberStack.adding(2)\nnumberStack.adding(3)\nnumberStack.removing()\nconsole.log(numberStack.numberOfElements())\nnumberStack.printStackContent()\n\n// Colas - FIFO\n\nclass Queue<T> {\n  private listQueue: T[]\n\n  constructor() {\n    this.listQueue = []\n  }\n  adding(input: T): void {\n    this.listQueue.push(input)\n  }\n\n  removing(): T | undefined {\n    return this.listQueue.shift()\n  }\n\n  numberOfElements(): number {\n    return this.listQueue.length\n  }\n\n  printStackContent(): void {\n    console.table(this.listQueue)\n  }\n}\n\nconst myQueue: Queue<number> = new Queue()\nmyQueue.adding(1)\nmyQueue.adding(2)\nmyQueue.adding(3)\nmyQueue.removing()\nconsole.log(myQueue.numberOfElements())\nmyQueue.printStackContent()"
  },
  {
    "path": "Roadmap/08 - CLASES/typescript/victoriaparraf.ts",
    "content": "class Persona {\n    // Atributos\n    nombre: string;\n    edad: number;\n    // Constructor (inicializador)\n    constructor(nombre: string, edad: number) {\n        this.nombre = nombre;\n        this.edad = edad;\n    }\n    // Método para imprimir los detalles de la persona\n    imprimirDetalles(): void {\n        console.log(`Nombre: ${this.nombre}, Edad: ${this.edad}`);\n    }\n}\n\n// Crear una instancia de la clase Persona\nlet persona1 = new Persona('Juan', 30);\n// Imprimir detalles de la persona\npersona1.imprimirDetalles(); // Nombre: Juan, Edad: 30\n// Modificar los atributos\npersona1.nombre = 'Carlos';\npersona1.edad = 35;\n// Imprimir los detalles actualizados\npersona1.imprimirDetalles(); // Nombre: Carlos, Edad: 35\n"
  },
  {
    "path": "Roadmap/08 - CLASES/vb.net/kenysdev.vb",
    "content": "' ╔══════════════════════════════════════╗\n' ║ Autor:  Kenys Alvarado               ║\n' ║ GitHub: https://github.com/Kenysdev  ║\n' ║ 2024 -  VB.NET                       ║\n' ╚══════════════════════════════════════╝\nModule Program\n\n    ' # CLASES\n    ' ------------\n    ' - Las clases proporcionan una forma de organizar y estructurar\n    '   el código de manera más modular y reutilizable.\n\n    Public Class Person\n        ' Propiedades\n        Public Name As String\n        Public Property Age As Integer\n\n        ' Constructor\n        Public Sub New(name As String, age As Integer)\n            Me.Name = name\n            Me.Age = age\n        End Sub\n\n        ' Metodo\n        Public Sub Print()\n            Console.WriteLine($\"Nombre: {Name} - Edad: {Age}\")\n        End Sub\n    End Class\n\n    ' ----------------------------------------\n    ' Ejercicio:\n    ' ----------------------------------------\n    ' - Implementa dos clases que representen las estructuras de Pila y Cola \n    '   (estudiadas en el ejercicio número 7 de la ruta de estudio)\n    ' - Deben poder inicializarse y disponer de operaciones para añadir, \n    '   eliminar, retornar el número de elementos e imprimir todo su contenido.\n    '_________________________________________\n    ' Pilas(stack - LIFO): */\n    Public Class MyStack\n        Private _stack As New Stack()\n\n        Public Sub Push(item As Object)\n            _stack.Push(item)\n        End Sub\n\n        Public Function Pop() As Object\n            If _stack.Count > 0 Then\n                Return _stack.Pop\n            Else\n                Return Nothing\n            End If\n        End Function\n\n        Public Function Count() As Integer\n            Return _stack.Count\n        End Function\n\n        Public Sub Print()\n            If _stack.Count > 0 Then\n                For Each item In _stack\n                    Console.WriteLine(item)\n                Next\n            End If\n        End Sub\n    End Class\n\n    '_________________________________________\n    'Colas (Queue - FIFO)\n    Public Class MyQueue\n        Private _queue As New Queue()\n\n        Public Sub Enqueue(item As Object)\n            _queue.Enqueue(item)\n        End Sub\n\n        Public Function Dequeue() As Object\n            If _queue.Count > 0 Then\n                Return _queue.Dequeue\n            Else\n                Return Nothing\n            End If\n        End Function\n\n        Public Function Count() As Integer\n            Return _queue.Count\n        End Function\n\n        Public Sub Print()\n            If _queue.Count > 0 Then\n                For Each item In _queue\n                    Console.WriteLine(item)\n                Next\n            End If\n        End Sub\n    End Class\n\n    '_________________________________________\n    Sub Main()\n        Dim Person As New Person(\"Ben\", 21)\n        Person.Print()\n        Person.Age = 19\n        Person.Print()\n\n        '---------------\n        Console.WriteLine(\"Uso de pila:\")\n        Dim Stack As New MyStack()\n        Stack.Push(\"uno\")\n        Stack.Push(22222)\n        Stack.Push(False)\n        Stack.Pop()\n        Stack.Print()\n\n        '---------------\n        Console.WriteLine(\"Uso de cola:\")\n        Dim Queue As New MyQueue()\n        Queue.Enqueue(\"uno\")\n        Queue.Enqueue(22222)\n        Queue.Enqueue(33.33)\n        Queue.Dequeue()\n        Queue.Print()\n    End Sub\nEnd Module\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/arduino/santyjl.ino",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n\n// Clase base para representar un Animal\nclass Animal {\npublic:\n    // Constructor que recibe el nombre del animal\n    Animal(const char* nombre) : nombre(nombre) {}\n\n    // Función virtual pura para obtener el sonido del animal\n    virtual void sonido() const = 0;\n\nprotected:\n    const char* nombre;  // Nombre del animal\n};\n\n// Clase derivada Perro que hereda de la clase Animal\nclass Perro : public Animal {\npublic:\n    // Constructor que llama al constructor de la clase base con el nombre del perro\n    Perro(const char* nombre) : Animal(nombre) {}\n\n    // Implementación de la función virtual para obtener el sonido del perro\n    void sonido() const override {\n        Serial.print(\"El perro \");\n        Serial.print(nombre);\n        Serial.println(\" hace guau\");\n    }\n};\n\n// Clase derivada Gato que hereda de la clase Animal\nclass Gato : public Animal {\npublic:\n    // Constructor que llama al constructor de la clase base con el nombre del gato\n    Gato(const char* nombre) : Animal(nombre) {}\n\n    // Implementación de la función virtual para obtener el sonido del gato\n    void sonido() const override {\n        Serial.print(\"El gato \");\n        Serial.print(nombre);\n        Serial.println(\" hace miau\");\n    }\n};\n\n\n\n// Clase base para representar un Empleado\nclass Empleado {\npublic:\n    // Constructor que recibe el nombre y la edad del empleado\n    Empleado(const char* nombre, int edad) : nombre(nombre), edad(edad) {}\n\n    // Función virtual pura para deber\n    virtual void deber() const = 0;\n\n    // Función virtual pura para obtener el sueldo\n    virtual void sueldo() const = 0;\n\n    // Función para obtener una representación en cadena del empleado\n    virtual const char* toString() const {\n        return \"\";\n    }\n\nprotected:\n    const char* nombre;  // Nombre del empleado\n    int edad;            // Edad del empleado\n};\n\n// Clase derivada Gerente que hereda de la clase Empleado\nclass Gerente : public Empleado {\npublic:\n    // Constructor que llama al constructor de la clase base y recibe información adicional\n    Gerente(const char* nombre, int edad, const char** empleados, int salario)\n        : Empleado(nombre, edad), empleados(empleados), salario(salario) {}\n\n    // Implementación de la función para deber\n    void deber() const override {\n        // Imprimir deber específico del Gerente\n        Serial.print(\"El gerente tiene el deber de manejar, controlar y planificar el trabajo de sus empleados que son: \");\n        for (int i = 0; empleados[i] != NULL; ++i) {\n            Serial.print(empleados[i]);\n            if (empleados[i + 1] != NULL) {\n                Serial.print(\", \");\n            }\n        }\n        Serial.println();\n    }\n\n    // Implementación de la función para obtener el sueldo\n    void sueldo() const override {\n        Serial.print(\"El gerente tiene un sueldo de \");\n        Serial.print(salario);\n        Serial.println(\"$.\");\n    }\n\n    // Implementación de la función para obtener una representación en cadena del gerente\n    const char* toString() const override {\n        return \"Gerente\";\n    }\n\nprivate:\n    const char** empleados;  // Arreglo de empleados a cargo\n    int salario;            // Salario del gerente\n};\n\n// Clase derivada GerenteDeProyecto que hereda de la clase Empleado\nclass GerenteDeProyecto : public Empleado {\npublic:\n    // Constructor que llama al constructor de la clase base y recibe información adicional\n    GerenteDeProyecto(const char* nombre, int edad, const char** proyectos)\n        : Empleado(nombre, edad), proyectos(proyectos) {}\n\n    // Implementación de la función para deber\n    void deber() const override {\n        // Imprimir deber específico del Gerente de Proyecto\n        Serial.print(\"El Gerente de Proyecto tiene el deber de supervisar y coordinar proyectos como: \");\n        for (int i = 0; proyectos[i] != NULL; ++i) {\n            Serial.print(proyectos[i]);\n            if (proyectos[i + 1] != NULL) {\n                Serial.print(\", \");\n            }\n        }\n        Serial.println();\n    }\n\n    // Implementación de la función para obtener el sueldo\n    void sueldo() const override {\n        Serial.println(\"El sueldo del Gerente de Proyecto depende del éxito de los proyectos.\");\n    }\n\n    // Implementación de la función para obtener una representación en cadena del gerente de proyecto\n    const char* toString() const override {\n        return \"Gerente de Proyecto\";\n    }\n\nprivate:\n    const char** proyectos;  // Arreglo de proyectos supervisados\n};\n\n// Clase derivada Programador que hereda de la clase Empleado\nclass Programador : public Empleado {\npublic:\n    // Constructor que llama al constructor de la clase base y recibe información adicional\n    Programador(const char* nombre, int edad, const char** lenguajes)\n        : Empleado(nombre, edad), lenguajes(lenguajes) {}\n\n    // Implementación de la función para deber\n    void deber() const override {\n        // Imprimir deber específico del Programador\n        Serial.print(\"El Programador tiene el deber de desarrollar software utilizando los siguientes lenguajes: \");\n        for (int i = 0; lenguajes[i] != NULL; ++i) {\n            Serial.print(lenguajes[i]);\n            if (lenguajes[i + 1] != NULL) {\n                Serial.print(\", \");\n            }\n        }\n        Serial.println();\n    }\n\n    // Implementación de la función para obtener el sueldo\n    void sueldo() const override {\n        Serial.println(\"El sueldo del Programador se basa en su experiencia y habilidades técnicas.\");\n    }\n\n    // Implementación de la función para obtener una representación en cadena del programador\n    const char* toString() const override {\n        return \"Programador\";\n    }\n\nprivate:\n    const char** lenguajes;  // Arreglo de lenguajes de programación utilizados\n};\n\n\n// Función de inicialización de Arduino\nvoid setup() {\n    Serial.begin(9600);  // Iniciar comunicación serial\n\n    // Crear instancias de las clases y llamar a la función sonido\n    Perro perro(\"Gaston\");\n    perro.sonido();\n\n    Gato gato(\"Cachito\");\n    gato.sonido();\n\n    //llamado al extra\n    // Crear instancias de las clases Empleado, Gerente, GerenteDeProyecto y Programador\n    const char* empleadosGerente[] = {\"Fernando\", \"Cesar\", NULL}; // null para señalar el final del conjunto\n    Gerente gerente(\"Julian\", 38, empleadosGerente, 6000);\n    Serial.println(gerente.toString());\n    gerente.deber();\n    gerente.sueldo();\n\n    const char* proyectosGerenteProyecto[] = {\"Proyecto A\", \"Proyecto B\", NULL};\n    GerenteDeProyecto gerente_proyecto(\"Ana\", 32, proyectosGerenteProyecto);\n    Serial.println(gerente_proyecto.toString());\n    gerente_proyecto.deber();\n    gerente_proyecto.sueldo();\n\n    const char* lenguajesProgramador[] = {\"Python\", \"JavaScript\", NULL};\n    Programador programador(\"Carlos\", 25, lenguajesProgramador);\n    Serial.println(programador.toString());\n    programador.deber();\n    programador.sueldo();\n\n}\nvoid loop() {\n    // Código que se ejecuta en bucle continuo\n}\n\n\n// Extra\n// Resto del código para la jerarquía de empleados\n\n// Extra\n// Resto del código para la jerarquía de empleados\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/c#/Andreavzqz.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace EjemploHerenciaYEmpresa\n{\n    // Parte 1: Herencia con Superclase Animal y Subclases Perro y Gato\n\n    // Superclase Animal\n    class Animal\n    {\n\n        public string Nombre { get; set; }\n\n        public Animal(string nombre)\n        {\n            Nombre = nombre;\n        }\n\n        //Método virtual para el sonido del animal\n        public virtual void HacerSonido()\n        {\n            Console.WriteLine(\"Sonido de animal\");\n        }\n    }\n\n    // Subclase Perro\n    class Perro : Animal\n    {\n        public Perro (string nombre) : base(nombre) { }\n\n        public override void HacerSonido()\n        {\n            Console.WriteLine($\"{Nombre} dice: Guau\");\n        }\n    }\n\n    // Subclase Gato\n\n    class Gato : Animal\n    {\n        public Gato(string nombre) : base(nombre) { }\n\n        public override void HacerSonido()\n        {\n            Console.WriteLine($\"{Nombre} dice Miau\");\n        }\n    }\n\n    // Parte 2: Jerarqía de una Empresa de Desarrollo\n\n    // Superclase Empleado\n\n    class Empleado \n    {\n        public int Id { get; set; }\n        public string Nombre { get; set; }\n\n        public Empleado(int id nombre)\n        {\n            Id = id;\n            Nombre = Nombre;\n        }\n\n        public virtual void MostrarInfo()\n        {\n            Console.WriteLine($\"ID:{id}, Nombre: {Nombre}\");\n        }\n    }\n\n    // Subclase Gerente de Proyectos\n    class Gerente : Empleado\n    {\n        public List<Empleado> EmpleadosAcargo { get; set; } = new List<Empleado>();\n        public Gerente(int id, string nombre) : base(id, nombre) { }\n        public override void MostrarInfo()\n        {\n            base.MostrarInfo();\n            Console.WriteLine(\"Empleados a cargo: \");\n            foreach (var empleado in EmpleadosAcargo)\n            {\n                Console.WriteLine($\" - {empleado.Nombre}\");\n            }\n        }\n    }\n\n    // Subclase Gerente de Proyectos\n    class GerenteDeProyectos : Empleado\n    {\n        public List<Empleado> EmpleadosAcargo { get; set; } = new List<Empleado>();\n        public  GerenteDeProyectos(int id, string nombre) : base(id, nombre) { }\n\n        public override void MostrarInfo()\n        {\n            base.MostrarInfo();\n            Console.WriteLine(\"Proyectos a cargo:\");\n            foreach(var empleado in EmpleadosAcargo)\n            {\n                Console.WriteLine($\" - {empleado.Nombre}\");\n            }\n        }\n    }\n\n    // Subclase Programador\n    class Programador : Empleado\n    {\n        public string LenguajeDeProgramacion { get; set; }\n\n        public Programador(in id, string nombre, string lenguaje) : base (id, nombre)\n        {\n            LenguajeDeProgramacion = lenguaje;\n        }\n\n        public override void MostrarInfo()\n        {\n            base.MostrarInfo();\n            Console.WriteLine($\"Lenguaje de programacion: {LenguajeDeProgramacion}\");\n        }\n    }\n\n    class Program\n    {\n        static void Main(string[] args)\n        {\n            // Parte 1: Uso de Animal, Perro y Gato\n            Perro perro = new Perro(\"Rex\");\n            Gato gato = new Gato(\"Wiskers\");\n\n            perro.HacerSonido(); //Imprime \" Rex dice: Guau\"\n            gato.HacerSonido();  // Imprime \"Wiskers dice: Miau\n\n            // Parte 2: Uso de Empleado, Gerente, GerenteDeProyectos y Programador\n            Programador programador1 = new Programador(1, \"Alice\", \"C#\");\n            Programador programador2 = new Programador(2, \"Bob\", \"Java\");\n            GerenteDeProyectos gerenteDeProyectos = new GerenteDeProyectos(3, \"Charlie\");\n            Gerente gerente = new Gerente(4, \"Diana\");\n\n            // Asignar empleados a cargo\n            gerenteDeProyectos.EmpleadosAcargo.Add(programador1);\n            gerenteDeProyectos.EmpleadosAcargo.Add(programador2);\n            gerente.EmpleadosAcargo.Add(gerenteDeProyectos);\n\n            // Mostrar informacion de cada empleado\n            programador1.MostrarInfo();\n            programador2.MostrarInfo();\n            gerenteDeProyectos.MostrarInfo();\n            gerente.MostrarInfo();\n        }\n    }\n\n  /*\nExplicación \n\n- Parte 1: Herencia con Superclase Animal y Subclases Perro y Gato\n\nSuperclase Animal:\nDefine el atributo Nombre.\nTiene un constructor para inicializar Nombre.\nMétodo virtual HacerSonido que puede ser sobrescrito por las subclases.\n\nSubclase Perro:\nHereda de Animal.\nSobrescribe el método HacerSonido para imprimir \"Guau\".\n\nSubclase Gato:\nHereda de Animal.\nSobrescribe el método HacerSonido para imprimir \"Miau\".\n\nPrograma Principal:\nCrea instancias de Perro y Gato.\nLlama al método HacerSonido para cada instancia.\n\n- Parte 2: Jerarquía de una Empresa de Desarrollo\n\nSuperclase Empleado:\nDefine los atributos Id y Nombre.\nTiene un constructor para inicializar Id y Nombre.\nMétodo virtual MostrarInfo para mostrar la información del empleado.\n\nSubclase Gerente:\nHereda de Empleado.\nAtributo EmpleadosACargo, una lista de empleados.\nSobrescribe el método MostrarInfo para mostrar información adicional de los empleados a cargo.\nSubclase GerenteDeProyectos:\n\nHereda de Empleado.\nAtributo EmpleadosACargo, una lista de empleados.\nSobrescribe el método MostrarInfo para mostrar información adicional de los proyectos a cargo.\n\nSubclase Programador:\nHereda de Empleado.\nAtributo LenguajeDeProgramacion.\nSobrescribe el método MostrarInfo para mostrar información adicional del lenguaje de programación.\n\nPrograma Principal:\nCrea instancias de Programador, GerenteDeProyectos y Gerente.\nAsigna empleados a cargo.\nLlama al método MostrarInfo para cada instancia.\n\n*/\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/c#/charlerodriguez3.cs",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n\n Animal gato1 = new Gato(\"Marcelo\",4,\"lamer patas\",\"leche\");\nAnimal perro1 = new Perro(\"Max\",10,\"Lucas\");\n\ngato1.EmitirSonido();\nperro1.EmitirSonido();\n\n\nclass Animal\n{\n    public int Edad { get; set; }\n    public string Nombre { get; set; }\n\n\n    public Animal(string nombre, int edad)\n    {\n        Nombre = nombre;\n        Edad = edad;\n    }\n    public virtual void EmitirSonido()\n    {\n        Console.WriteLine(\"Sonido de animal predeterminado\");\n    }\n}\n\nclass Gato : Animal\n{\n    public string ActividadFavorita { get; set; }\n\n    public string Bebida { get; set; }\n    public Gato(string nombre, int edad, string actividadFavorita, string bebida) : base(nombre, edad)\n    {\n        ActividadFavorita = actividadFavorita;\n        Bebida = bebida;\n    }\n    public override void EmitirSonido()\n    {\n        Console.WriteLine(\"Miau miau\");\n    }\n}\n\n\nclass Perro : Animal\n{\n    public string AmoPreferido { get; set; }\n    public Perro(string nombre, int edad, string amoPreferido) : base(nombre, edad)\n    {\n        AmoPreferido = amoPreferido;\n    }\n    public override void EmitirSonido()\n    {\n        Console.WriteLine(\"Guau guau\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/c#/deivisaherreraj.cs",
    "content": "using System.ComponentModel;\nusing System.Reflection;\n\n/**\n * Clase base Animal\n */\npublic abstract class Animal\n{\n    public string? Name { get; }\n    public string? Color { get; }\n    public int? Age { get; }\n\n    protected Animal(string name, string color, int age) \n    { \n        this.Name = name;\n        this.Color = color;\n        this.Age = age;\n    }\n\n    public abstract string Sonido();\n}\n\n/**\n * Subclase Perro que hereda de Animal\n */\npublic class Dog : Animal\n{\n    public Dog(string name, string color, int age) : base(name, color, age) { }\n\n    public override string Sonido()\n    {\n        return \"Guau!\";\n    }\n}\n\n/**\n * Subclase Gato que hereda de Animal\n */\npublic class Cat : Animal\n{\n    public Cat(string name, string color, int age) : base(name, color, age) { }\n\n    public override string Sonido()\n    {\n        return \"Miau!\";\n    }\n}\n\n/**\n * Enumeración para los roles de los empleados\n */\npublic enum EmployeeRole\n{\n    [Description(\"Gerente\")]\n    Managers,\n    [Description(\"Gerente de proyecto\")]\n    ProjectManagers,\n    [Description(\"Programador\")]\n    Programmers,\n    [Description(\"Programador Senior\")]\n    Senior,\n    [Description(\"Programador Midle\")]\n    Midle,\n    [Description(\"Programador Junior\")]\n    Junior\n}\n\n/**\n * Clase base Empleado\n */\npublic abstract class Employee\n{\n    public int Identifier { get; }\n    public string Name { get; }\n    public EmployeeRole Rol { get; }\n\n    protected Employee(int identifier, string name, EmployeeRole rol)\n    {\n        Identifier = identifier;\n        Name = name;\n        Rol = rol;\n    }\n\n    /**\n     * Obtener el Description attribute del enum\n     */\n    public string GetNameRol()\n    {\n        MemberInfo? field = Rol.GetType().GetField(Rol.ToString());\n        DescriptionAttribute? attribute = Attribute.GetCustomAttribute(element: field, attributeType: typeof(DescriptionAttribute)) as DescriptionAttribute;\n        return attribute.Description;\n    }\n\n    public virtual string GetEmployeeInformation()\n    {\n        return $\"=> ID: {Identifier}, Nombre: {Name}, Rol: {GetNameRol()}\";\n    }\n\n    public abstract void Work();\n}\n\n/**\n * Subclase Gerente que hereda de Empleado\n */\npublic class Managers : Employee\n{\n    public decimal Salary { get; }\n    public string Department { get; }\n    public int Experience { get; }\n    public DateTime HiringDate { get; }\n    public List<Employee> EmployeesInCharge { get; }\n\n    public Managers(int identifier, string name, EmployeeRole rol, decimal salary, string department, int experience, DateTime hiringDate) : base(identifier, name, rol) \n    { \n        Salary = salary;\n        Department = department;\n        Experience = experience;\n        HiringDate = hiringDate;\n        EmployeesInCharge = new List<Employee>();\n    }\n\n    public void AddEmployee(Employee employee)\n    {\n        EmployeesInCharge.Add(employee);\n    }\n\n    public override void Work()\n    {\n        Console.WriteLine($\"{base.GetEmployeeInformation()}\");\n        Console.WriteLine($\"Salario: {Salary}, Departamento: {Department}, Experiencia: {Experience} años, Fecha de Contratación: {HiringDate.ToString(\"dd/MM/yyyy\")}\");\n        Console.WriteLine($\"Empleados a cargo: {EmployeesInCharge.Count}\");\n        Console.WriteLine(\"Supervisando equipos y proyectos\");\n    }\n}\n\n/**\n * Subclase GerenteProyecto que hereda de Gerente\n */\npublic class ProjectManagers : Managers\n{\n    public List<string> Project { get; }\n\n    public ProjectManagers(int identifier, string name, EmployeeRole rol, decimal salary, string department, int experience, DateTime hiringDate) : base(identifier, name, rol, salary, department, experience, hiringDate)\n    {\n        Project = new List<string>();\n    }\n\n    public void AddProject(string proyecto)\n    {\n        Project.Add(proyecto);\n    }\n\n    public override void Work()\n    {\n        Console.WriteLine($\"{base.GetEmployeeInformation()}\");\n        Console.WriteLine($\"Salario: {Salary}, Departamento: {Department}, Experiencia: {Experience} años, Fecha de Contratación: {HiringDate.ToString(\"dd/MM/yyyy\")}\");\n        Console.WriteLine($\"Número de empleados a cargo: {EmployeesInCharge.Count}\");\n        Console.WriteLine($\"Número de proyectos asignados: {Project.Count}\");\n        Console.WriteLine(\"Gestionando proyectos y recursos\");\n    }\n}\n\n/**\n * Subclase Programador que hereda de Empleado\n */\npublic class Programmers : Employee\n{\n    protected string[] Technologies { get; }\n    protected string Level { get; }\n\n    public Programmers(int id, string nombre, string[] technologies, string level) : base(id, nombre, GetRolByNivel(level))\n    {\n        Technologies = technologies;\n        Level = level;\n    }\n\n    /**\n     * Método para obtener el RolEmpleado según el nivel del programador\n     */\n    private static EmployeeRole GetRolByNivel(string level)\n    {\n        switch (level.ToLower())\n        {\n            case \"junior\":\n                return EmployeeRole.Junior;\n            case \"midle\":\n                return EmployeeRole.Midle;\n            case \"senior\":\n                return EmployeeRole.Senior;\n            default:\n                return EmployeeRole.Programmers;\n        }\n    }\n\n    public override void Work()\n    {\n        Console.WriteLine($\"{base.GetEmployeeInformation()}\");\n        Console.WriteLine($\"Tecnologias: {string.Join(\", \", Technologies)}\");\n        Console.WriteLine($\"Nivel: {Level}\");\n        Console.WriteLine(\"Desarrollando código\");\n    }\n}\n\nclass Program\n{\n    static void Main(string[] args)\n    {\n        // Ejemplo de animales\n        Animal perro = new Dog(\"Tom\", \"Negro\", 5);\n        Animal gato = new Cat(\"Jerry\", \"Blanco\", 5);\n\n        Console.WriteLine(\"Sonido del perro: \" + perro.Sonido());\n        Console.WriteLine(\"Sonido del gato: \" + gato.Sonido());\n\n        // Ejemplo de empleados Gerente/Gerente proyecto/Programador\n        Employee gerente = new Managers(1, \"Juan\", EmployeeRole.Managers, 50000, \"Recursos Humanos\", 10, DateTime.Now.AddYears(-5));\n        Employee gerenteProyecto = new ProjectManagers(2, \"María\", EmployeeRole.ProjectManagers, 60000, \"Arquitecto\", 8, DateTime.Now.AddYears(-3));\n        Employee programadorSenior = new Programmers(3, \"Pedro\", new string[] { \"C#\", \"JavaScript\", \"SQL\", \"Angular\", \"Nodejs\" }, \"senior\");\n        Employee programadorJunior = new Programmers(4, \"Carlos\", new string[] { \"C#\", \"JavaScript\", \"SQL\" }, \"junior\");\n        \n        ((Managers)gerente).AddEmployee(gerenteProyecto);\n        ((Managers)gerente).AddEmployee(programadorSenior);\n        ((Managers)gerente).AddEmployee(programadorJunior);\n\n        ((ProjectManagers)gerenteProyecto).AddEmployee(programadorSenior);\n        ((ProjectManagers)gerenteProyecto).AddEmployee(programadorJunior);\n\n        ((ProjectManagers)gerenteProyecto).AddProject(\"Proyecto A\");\n        ((ProjectManagers)gerenteProyecto).AddProject(\"Proyecto B\");\n\n        gerente.Work();\n        gerenteProyecto.Work();\n        programadorSenior.Work();\n        programadorJunior.Work();\n    }\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/c#/devcherry1.cs",
    "content": "using System;\nclass Program\n{\n    static void Main()\n    {\n        Perro miPerro = new Perro();\n        miPerro.Nombre = \"Firulais\";\n        miPerro.Comer();  // Método heredado de la clase Animal\n        miPerro.Ladrar();\n        Gato miGato = new Gato();\n        miGato.Nombre = \"Michin\";\n        miGato.Comer();\n        miGato.Maullar();\n\n        Developer dev1 = new Developer { Nombre = \"Luis\", ID = 7 };\n        Developer dev2 = new Developer { Nombre = \"Camila\", ID = 2 };\n        Developer dev3 = new Developer { Nombre = \"Alexandra\", ID = 3 };\n        Developer dev4 = new Developer { Nombre = \"Carlos\", ID = 4 };\n        Developer dev5 = new Developer { Nombre = \"Sofia\", ID = 8 };\n\n        ProjectManager pm1 = new ProjectManager { Nombre = \"Gerald\", ID = 5 };\n        ProjectManager pm2 = new ProjectManager { Nombre = \"Edgar\", ID = 6 };\n\n        Manager boss = new Manager { Nombre = \"Ernesto\", ID = 1 };\n\n        dev1.Funcion();\n        pm1.Funcion();\n        boss.Funcion();\n\n        // Asignar Developers a cada ProjectManager\n        pm1.AsignarDeveloper(dev1);\n        pm1.AsignarDeveloper(dev2);\n\n        pm2.AsignarDeveloper(dev3);\n        pm2.AsignarDeveloper(dev4);\n        pm2.AsignarDeveloper(dev5);\n\n        // Asignar ProjectManagers al Manager\n        boss.AsignarProjectManager(pm1);\n        boss.AsignarProjectManager(pm2);\n\n        // Mostrar la jerarquía\n        Console.WriteLine($\"\\n**Jerarquía del Manager:**\");\n        boss.MostrarJerarquia();\n    }\n}\npublic class Animal\n{\n    public string Nombre { get; set; }\n\n    public void Comer()\n    {\n        Console.WriteLine($\"{Nombre} está comiendo.\");\n    }\n}\npublic class Perro : Animal\n{\n    public void Ladrar()\n    {\n        Console.WriteLine($\"{Nombre} está ladrando.\");\n    }\n}\npublic class Gato : Animal\n{\n    public void Maullar()\n    {\n        Console.WriteLine($\"{Nombre} está maullando.\");\n    }\n}\npublic class Empleado\n{\n    public string Nombre { get; set; }\n    public int ID { get; set; }\n}\npublic class Developer : Empleado\n{\n    public void Funcion()\n    {\n        Console.WriteLine($\"{Nombre} convierte el cafe en codigo.\");\n    }\n}\npublic class ProjectManager : Empleado\n{\n    public List<Developer> Developers { get; private set; } = new List<Developer>();\n    public void Funcion()\n    {\n        Console.WriteLine($\"{Nombre} se encarga de que todos planifica y coordina.\");\n    }\n    public void AsignarDeveloper(Developer developer)\n    {\n        Developers.Add(developer);\n    }\n\n    public void MostrarDevelopers()\n    {\n        Console.WriteLine($\"  {Nombre} tiene asignados los siguientes Developers: ({Developers.Count})\");\n        foreach (var dev in Developers)\n        {\n            Console.WriteLine($\"    - {dev.Nombre} (ID: {dev.ID})\");\n        }\n    }\n}\npublic class Manager : Empleado\n{\n    public List<ProjectManager> ProjectManagers { get; private set; } = new List<ProjectManager>();\n\n    public void Funcion()\n    {\n        Console.WriteLine($\"{Nombre} asigna responsabilidades y supervisa operaciones.\");\n    }\n    public void AsignarProjectManager(ProjectManager projectManager)\n    {\n        ProjectManagers.Add(projectManager);\n    }\n    public void MostrarJerarquia()\n    {\n        Console.WriteLine($\"\\n{Nombre} supervisa a los siguientes ProjectManagers: ({ProjectManagers.Count})\");\n        foreach (var pm in ProjectManagers)\n        {\n            Console.WriteLine($\"- {pm.Nombre} (ID: {pm.ID})\");\n            pm.MostrarDevelopers();\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/c#/estuardodev.cs",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n\n using System.ComponentModel.Design;\n\nnamespace AppParaRetos\n{\n    public class estuardodev\n    {\n        public static void Main(string[] args)\n        {\n            Animal perro = new Perro(\"Firulais\", 5);\n            Animal gato = new Gato(\"Garfield\", 3);\n\n            perro.Ruido();\n            gato.Ruido();\n\n            Empleado gerente = new Gerenete(\"Estuardo\", \"Gerente\");\n            Console.WriteLine($\"El empleado {gerente.nombre} con puesto de {gerente.puesto} con identificador {gerente.getIdentificador()}\");\n            gerente.Laborar();\n\n            Empleado gerenteProyecto = new GerenteProyecto(\"Estuardo\", \"Gerente de Proyecto\");\n            Console.WriteLine($\"El empleado {gerenteProyecto.nombre} con puesto de {gerenteProyecto.puesto} con identificador {gerenteProyecto.getIdentificador()}\");\n            gerenteProyecto.Laborar();\n\n            Empleado programador = new Programador(\"Estuardo\", \"Programador\");\n            Console.WriteLine($\"El empleado {programador.nombre} con puesto de {programador.puesto} con identificador {programador.getIdentificador()}\");\n            programador.Laborar();\n        }\n    }\n\n    public abstract class Animal\n    {\n        public string Nombre { get; set; }\n        public int anios { get; set; }\n\n        public Animal(string Nombre, int anios)\n        {\n            this.Nombre = Nombre;\n            this.anios = anios;\n        }\n\n        public virtual void Ruido()\n        {\n            Console.WriteLine(\"Hace ruido\");\n        }\n    }\n\n    public class Perro : Animal\n    {\n        public Perro(string Nombre, int anios) : base(Nombre, anios){ }\n\n        public override void Ruido()\n        {\n            Console.WriteLine(\"Hace guau\");\n        }\n    }\n\n    public class Gato : Animal\n    {\n        public Gato(string Nombre, int anios) : base(Nombre, anios) { }\n\n        public override void Ruido()\n        {\n            Console.WriteLine(\"Hace miau\");\n        }\n    }\n\n    public abstract class Empleado\n    {\n        public string nombre { get; set; }\n        private string identificador = \"\";\n        public string puesto { get; set; }\n\n        public Empleado(string nombre, string puesto)\n        {\n            this.nombre = nombre;\n            this.puesto = puesto;\n        }\n\n        public string getIdentificador()\n        {\n            string concat = nombre.ToLower().Replace(\" \", \"\").Trim() + puesto.ToLower().Replace(\" \", \"\").Trim();\n            int size = concat.Length;\n            Random random = new Random();\n\n            for (int i = 0; identificador.Length < 7 ; i++)\n            {\n                \n                int num = random.Next(0, size);\n                if (!identificador.Contains(concat[num].ToString()))\n                {\n                    identificador += concat[num];\n                }\n                \n            }\n\n            return identificador;\n        }\n\n        public virtual void Laborar()\n        {\n            Console.WriteLine(\"Laborando\");\n        }\n    }\n\n    public class Gerenete : Empleado\n    {\n        public Gerenete(string nombre, string puesto) : base(nombre, puesto) { }\n\n        public override void Laborar()\n        {\n            Console.WriteLine(\"Dirigiendo\");\n        }\n    }\n\n    public class GerenteProyecto : Empleado\n    {\n        public GerenteProyecto(string nombre, string puesto) : base(nombre, puesto) { }\n\n        public override void Laborar()\n        {\n            Console.WriteLine(\"Planificando\");\n        }\n    }\n\n    public class Programador : Empleado\n    {\n        public Programador(string nombre, string puesto) : base(nombre, puesto) { }\n\n        public override void Laborar()\n        {\n            Console.WriteLine(\"Programando\");\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/c#/hequebo.cs",
    "content": "class Program\n{\n    static void Main(string[] args)\n    {\n        Perro perro = new Perro();\n        Gato gato = new Gato();\n\n        EmitirSonido(perro);\n        EmitirSonido(gato);\n        Console.ReadLine();\n\n        Manager manager = new Manager(1, \"Joaquín\");\n        ProjectManager projectManager1 = new ProjectManager(2, \"Ramiro\", \"App móvil\");\n        ProjectManager projectManager2 = new ProjectManager(3, \"Alberto\", \"Página Web\");\n        Programmer programmer1 = new Programmer(4, \"Emilio\", \"C#\");\n        Programmer programmer2 = new Programmer(5, \"Luis\", \"Python\");\n        Programmer programmer3 = new Programmer(6, \"Aldo\", \"Java\");\n        Programmer programmer4 = new Programmer(7, \"Ale\", \"PHP\");\n        Programmer programmer5 = new Programmer(8, \"Samantha\", \"SQL\");\n        Programmer programmer6 = new Programmer(9, \"Mario\", \"VB\");\n\n        manager.AgregarEmpleado(projectManager1.Nombre);\n        manager.AgregarEmpleado(projectManager2.Nombre);\n        manager.ImprimirEmpleados();\n        manager.CoordinarProyectos();\n        Console.WriteLine();\n\n        projectManager1.AgregarEmpleado(programmer1.Nombre);\n        projectManager1.AgregarEmpleado(programmer3.Nombre);\n        projectManager1.AgregarEmpleado(programmer5.Nombre);\n\n        projectManager1.ImprimirEmpleados();\n        projectManager1.ConsultarProyecto();\n        Console.WriteLine();\n\n        projectManager2.AgregarEmpleado(programmer2.Nombre);\n        projectManager2.AgregarEmpleado(programmer4.Nombre);\n        projectManager2.AgregarEmpleado(programmer6.Nombre);\n\n        projectManager2.ImprimirEmpleados();\n        projectManager2.ConsultarProyecto();\n        Console.WriteLine();\n\n        programmer1.AgregarEmpleado(\"Ziggy\");\n        programmer1.ImprimirEmpleados();\n        programmer1.Consultar();\n\n    }\n    static void EmitirSonido(Animal animal)\n    {\n        animal.EmitirSonido();\n    }\n}\nclass Animal\n{\n    public virtual void EmitirSonido()\n    {\n\n    }\n}\n\nclass Perro : Animal\n{\n    public override void EmitirSonido() \n    {\n        Console.WriteLine(\"Guau!\");\n    }\n}\nclass Gato : Animal\n{\n    public override void EmitirSonido()\n    {\n        Console.WriteLine(\"Miau!\");\n    }\n}\n\nclass Empleado\n{\n    protected int _id;\n    protected string _nombre;\n    protected List<string> _empleados;\n\n    public string Nombre { get { return _nombre; } }\n\n    public Empleado(int id, string nombre)\n    {\n        _id = id;\n        _nombre = nombre;\n        _empleados = new List<string>();\n    }\n    public virtual void AgregarEmpleado(string empleado)\n    {\n        _empleados.Add(empleado);\n    }\n    public virtual void ImprimirEmpleados()\n    {\n        if (_empleados.Count == 0)\n        {\n            Console.WriteLine($\"No hay empleados al cargo de {_nombre}\");\n            return;\n        }\n        Console.WriteLine($\"Los empleados a cargo de {_nombre} son:\");\n        foreach(string empleado in _empleados)\n            Console.WriteLine($\"{empleado}\");\n    }\n}\nclass Manager : Empleado\n{\n    public Manager(int id, string nombre) : base(id, nombre) { }\n    public void CoordinarProyectos()\n    {\n        Console.WriteLine($\"{_nombre} esta coordinando todos los proyectos\");\n    }\n}\nclass ProjectManager : Empleado\n{\n    private string _proyecto;\n    public ProjectManager(int id, string nombre, string proyecto) : base(id, nombre) \n    {\n        _proyecto = proyecto;\n    }\n    public void ConsultarProyecto()\n    {\n        Console.WriteLine($\"{_nombre} coordina el proyecto {_proyecto}\");\n    }\n}\nclass Programmer : Empleado\n{\n    private string _lenguaje;\n    public Programmer(int id, string nombre, string lenguaje): base(id, nombre)\n    {\n        _lenguaje = lenguaje;\n    }\n    public override void AgregarEmpleado(string empleado)\n    {\n        Console.WriteLine($\"{_nombre} no puede agregar empleados\");\n    }\n    public void Consultar()\n    {\n        Console.WriteLine($\"{_nombre} programa en {_lenguaje}\");\n    }\n}"
  },
  {
    "path": "Roadmap/09 - HERENCIA/c#/isaacus98.cs",
    "content": "﻿/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n\nnamespace Roadmap\n{\n    internal class Reto09\n    {\n        static void Main(string[] args)\n        {\n            Perro perro = new(\"perro\", \"guau\");\n            Gato gato = new(\"gato\", \"miau\");\n\n            perro.ImprimirSonido();\n            gato.ImprimirSonido();\n\n            // Reto extra\n            Programador programador1 = new(1, \"Isaac\", \"C#\");\n            Programador programador2 = new(2, \"Sergi\", \"Java\");\n            Programador programador3 = new(3, \"Gerard\", \"Kotlin\");\n            Programador programador4 = new(4, \"Pol\", \"C#\");\n            Programador programador5 = new(5, \"Josep\", \"Java\");\n            Programador programador6 = new(6, \"Guillem\", \"Kotlin\");\n            programador1.Trabajar();\n            programador2.Trabajar();\n            programador3.Trabajar();\n            programador4.Trabajar();\n            programador5.Trabajar();\n            programador6.Trabajar();\n\n            GerenteProyectos gerenteProyectos1 = new(7, \"Joan\", \"App C#\");\n            gerenteProyectos1.Add(programador1);\n            gerenteProyectos1.Add(programador4);\n            gerenteProyectos1.Trabajar();\n            gerenteProyectos1.EmpleadosACargo();\n\n            GerenteProyectos gerenteProyectos2 = new(8, \"Max\", \"App Java\");\n            gerenteProyectos2.Add(programador2);\n            gerenteProyectos2.Add(programador5);\n            gerenteProyectos2.Trabajar();\n            gerenteProyectos2.EmpleadosACargo();\n\n            GerenteProyectos gerenteProyectos3 = new(9, \"Nuria\", \"App Kotlin\");\n            gerenteProyectos3.Add(programador3);\n            gerenteProyectos3.Add(programador6);\n            gerenteProyectos3.Trabajar();\n            gerenteProyectos3.EmpleadosACargo();\n\n\n            Gerente gerente = new(10, \"Ricard\");\n            gerente.Add(gerenteProyectos1);\n            gerente.Add(gerenteProyectos2);\n            gerente.Add(gerenteProyectos3);\n            gerente.Trabajar();\n            gerente.EmpleadosACargo();\n\n        }\n    }\n\n    public class Animal\n    {\n        protected string Especie;\n        protected string Sonido;\n\n        public Animal(string especie, string sonido)\n        {\n            Especie = especie;\n            Sonido = sonido;\n        }\n\n        public void ImprimirSonido()\n        {\n            Console.WriteLine($\"El {Especie} hace {Sonido}\");\n        }\n    }\n\n    public class Perro(string especie, string sonido) : Animal(especie, sonido) { }\n\n    public class Gato(string especie, string sonido) : Animal(especie, sonido) { }\n\n    // Reto extra\n\n    public abstract class Empleado\n    {\n        public readonly int Id;\n        public readonly string Nombre;\n\n        protected Empleado(int id, string nombre)\n        {\n            Id = id;\n            Nombre = nombre;\n        }\n    }\n\n    public class Gerente : Empleado\n    {\n        private List<GerenteProyectos> GerentesProyecto;\n        public Gerente(int id, string nombre) : base(id, nombre) \n        {\n            GerentesProyecto = new List<GerenteProyectos>();\n        }\n\n        public void Add(GerenteProyectos gerenteProyectos) => GerentesProyecto.Add(gerenteProyectos);\n        public void Trabajar() => Console.WriteLine($\"El gerente {Nombre} gestiona todos los proyectos.\");\n        public void EmpleadosACargo()\n        {\n            Console.WriteLine($\"El gerente {Nombre} tiene los siguiente empleados a su cargo:\");\n            foreach (GerenteProyectos gerenteProyectos in GerentesProyecto)\n            {\n                Console.WriteLine(gerenteProyectos.Nombre);\n            }\n        }\n    }\n\n    public class GerenteProyectos : Empleado\n    {\n        private List<Programador> Programadores;\n        private string Proyecto;\n        public GerenteProyectos(int id, string nombre, string proyecto) : base(id, nombre) \n        {\n            Proyecto = proyecto;\n            Programadores = new List<Programador>();    \n        }\n\n        public void Add(Programador programador) => Programadores.Add(programador);\n        public void Trabajar() => Console.WriteLine($\"El gerente de proyecto {Nombre} gestiona el proyecto {Proyecto}.\");\n        public void EmpleadosACargo()\n        {\n            Console.WriteLine($\"El gerente de proyecto {Nombre} tiene los siguiente empleados a su cargo:\");\n            foreach (Programador programador in Programadores)\n            {\n                Console.WriteLine(programador.Nombre);\n            }\n        }\n    }\n\n    public class Programador : Empleado\n    {\n        private string Lenguaje;\n\n        public Programador(int id, string nombre, string lenguage) : base(id, nombre) \n        {\n            Lenguaje = lenguage;\n        }\n\n        public void Trabajar() => Console.WriteLine($\"El programador {Nombre} programa con el lenguaje de programación {Lenguaje}\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/c#/jamerrq.cs",
    "content": "using System;\n\n/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n\nnamespace Roadmap09\n{\n    class Animal\n    {\n        public string Sound { get; set; }\n        public Animal(string sound)\n        {\n            Sound = sound;\n        }\n        public void MakeSound()\n        {\n            Console.WriteLine(Sound);\n        }\n    }\n\n    class Dog : Animal\n    {\n        public Dog() : base(\"Woof!\") { }\n    }\n\n    class Cat : Animal\n    {\n        public Cat() : base(\"Meow!\") { }\n    }\n\n    // Extra ejercicio: Empresa de desarrollo\n\n    class Employee\n    {\n        public int Id { get; set; }\n        public string Name { get; set; }\n        public Employee(int id, string name)\n        {\n            Id = id;\n            Name = name;\n        }\n    }\n\n    class Manager : Employee\n    {\n        public Manager(int id, string name) : base(id, name) { }\n    }\n\n    class ProjectManager : Employee\n    {\n        public ProjectManager(int id, string name) : base(id, name) { }\n    }\n\n    class Programmer : Employee\n    {\n        public Programmer(int id, string name) : base(id, name) { }\n    }\n\n    class Company\n    {\n        public Employee[] Employees { get; set; }\n        public Company(Employee[] employees)\n        {\n            Employees = employees;\n        }\n    }\n\n    class Tasks\n    {\n        public void AssignTask(Employee employee, string description)\n        {\n            Console.WriteLine($\"Assigning task to {employee.Name}: {description}\");\n            switch (employee)\n            {\n                case Manager manager:\n                    Console.WriteLine($\"Assigning task to manager {manager.Name}\");\n                    break;\n                case ProjectManager projectManager:\n                    Console.WriteLine($\"Assigning task to project manager {projectManager.Name}\");\n                    break;\n                case Programmer programmer:\n                    Console.WriteLine($\"Assigning task to programmer {programmer.Name}\");\n                    break;\n                default:\n                    Console.WriteLine(\"Employee not found\");\n                    break;\n            }\n        }\n    }\n\n    class CompanyProgram\n    {\n        public static void CompanyMain(string[] args)\n        {\n            Employee[] employees = new Employee[3];\n            employees[0] = new Manager(1, \"John Doe\");\n            employees[1] = new ProjectManager(2, \"Jane Doe\");\n            employees[2] = new Programmer(3, \"Julia Doe\");\n            Company company = new Company(employees);\n            Tasks tasks = new Tasks();\n            tasks.AssignTask(employees[0], \"Create a new project\");\n            tasks.AssignTask(employees[1], \"Assign tasks to programmers\");\n            tasks.AssignTask(employees[2], \"Create a new feature\");\n        }\n    }\n\n    class Program\n    {\n        static void Main(string[] args)\n        {\n            Animal dog = new Dog();\n            Animal cat = new Cat();\n            dog.MakeSound();\n            cat.MakeSound();\n            Console.WriteLine(\"========================================\");\n            Console.WriteLine(\"============ EJERCICIO EXTRA ===========\");\n            Console.WriteLine(\"========================================\\n\");\n            CompanyProgram.CompanyMain(args);\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/c#/kenysdev.cs",
    "content": "/*\n╔══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado               ║\n║ GitHub: https://github.com/Kenysdev  ║\n║ 2024 -  C#                           ║\n╚══════════════════════════════════════╝\n------------------------------------------\n# Herencia\n------------------------------------------\n- Permite definir una clase que hereda atributos y métodos de una \n  clase existente, para reutilización y organización.\n- La clase que hereda se conoce como “subclase” o “clase hija”.\n- La clase de la que hereda se conoce como “superclase” o “clase padre”.\n\n# Polimorfismo:\n# ----------------------------------------\n# - Los objetos de diferentes clases pueden ser accedidos utilizando el \n#   mismo interfaz, mostrando un comportamiento distinto \n#   (tomando diferentes formas) según cómo sean accedidos. */\n\nclass Program{\n\n    // Superclase\n    public class Animal(string name, string sound)\n    {\n        public string Name { get; set; } = name;\n        public string Sound { get; set; } = sound;\n\n        public void MakeSound(){\n            Console.WriteLine($\"{Name} hace: {Sound}\");\n        }\n    }\n\n    // Subclases\n    class Dog(string name) : Animal(name, \"Woof\"){\n\n    }\n\n    class Cat(string name) : Animal(name, \"Meow\"){\n\n    }\n\n/*____________________________________________________\n* Ejercicio usando herencia y Polimorfismo.\n- Implementa la jerarquía de una empresa de desarrollo formada por \n  empleados que pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n- Cada empleado tiene un identificador y un nombre.\n- Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n  actividad, y almacenan los empleados a su cargo. */\n\n    class Employees{\n        public static List<string[]> employees = [];\n        public string identifier = \"\";\n        public HashSet<string> tasks = [];\n        public HashSet<string> staff = [];\n\n        public void Add(params string[] names){\n            foreach (var name in names){\n                employees.Add([identifier, name]);\n            }\n        }\n\n        public void Print(){\n            foreach (var employee in employees){\n                if (employee[0] == identifier){\n                    Console.WriteLine($\"{employee[1]} -> {identifier}\");\n                }\n            }\n        }\n\n        public void Functions(){\n            Console.WriteLine($\"\\nFunciones de {identifier}\");\n            foreach (var task in tasks){\n                Console.WriteLine(task);\n            }\n            Console.WriteLine(\"--------------------\");\n        }\n\n        public void Subordinates(){\n            Console.WriteLine($\"\\nSubordinados de un {identifier}\");\n            foreach (var employee in employees){\n                 if (staff.Contains(employee[0])){\n                    Console.WriteLine($\"{employee[1]} -> {employee[0]}\");\n                 }\n            }\n            Console.WriteLine(\"--------------------\");\n        }\n    }\n\n    // Subclases\n    class Manager : Employees{\n        public Manager(){\n            identifier = \"Gerente\";\n            tasks = [\"- Supervisión\", \"- Toma de decisiones\"];\n            staff = [\"Gerente de Proyecto\", \"Programador\"];\n        }\n    }\n\n    class ProjectManager : Employees{\n        public ProjectManager(){\n            identifier = \"Gerente de Proyecto\";\n            tasks = [\"- Planificación\", \"- Coordinación de proyectos\"];\n            staff = [\"Programador\"];\n        }\n    }\n\n    class Programmer : Employees{\n        public Programmer(){\n            identifier = \"Programador\";\n            tasks = [\"- Desarrollo\", \"- Mantenimiento de código\"];\n            staff = [\"No tiene subordinados\"];\n        }\n    }\n\n//____________________________________________________\n    static void Main(){\n        Dog dog = new(\"Max\");\n        Cat cat = new(\"Milo\");\n        dog.MakeSound();\n        cat.MakeSound();\n\n        //--------------\n        Manager manager = new();\n        ProjectManager projectManager = new();\n        Programmer programmer = new();\n\n        manager.Add(\"Ben\", \"Dan\");\n        projectManager.Add(\"Ray\", \"Joe\");\n        programmer.Add(\"Leo\", \"Sam\", \"Zoe\", \"Ana\");\n\n        manager.Functions();\n        projectManager.Functions();\n        programmer.Functions();\n\n        manager.Subordinates();\n        projectManager.Subordinates();\n\n        Console.WriteLine(\"Total:\");\n        manager.Print();\n        projectManager.Print();\n        programmer.Print();\n    }\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/c#/rxvlc.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\n\nnamespace R09___2024\n{\n    //Superclase\n    class Animal\n    {\n        //Defino atributos Puedes poner protected (Es para que la clase heredera pueda manipular los atributos sin necesidad de propiedades/getters/setters)\n        protected string nombre;\n        int edad;\n\n        public Animal(string nombre,int edad)\n        {\n            this.nombre = nombre;\n            this.edad = edad;\n        }\n    }\n\n    //Heredera perro:\n    class Perro : Animal\n    {\n        public Perro(string nombre,int edad):base(nombre,edad){ }\n\n        public void Sonido()\n        {\n            Console.WriteLine(\"guau guau!\");\n        }\n    }\n\n    //Heredera gato:\n    class Gato : Animal\n    {\n        public Gato(string nombre, int edad) : base(nombre, edad) { }\n\n        public void Sonido()\n        {\n            Console.WriteLine(\"miau miau!\");\n        }\n    }\n\n    //Dificultad adicional:\n    // Clase base abstracta para representar a un empleado genérico\n    class Empleado\n    {\n        // Defino atributos como protected (para que las clases heredadas puedan acceder directamente a ellos)\n        protected int id;\n        protected string nombre;\n\n        // Constructor\n        public Empleado(int id, string nombre)\n        {\n            this.id = id;\n            this.nombre = nombre;\n        }\n\n        // Método virtual para obtener información del empleado\n        public virtual void Informacion()\n        {\n            Console.WriteLine($\"ID: {id}, Nombre: {nombre}\");\n        }\n    }\n\n    // Clase Gerente hereda de Empleado\n    class Gerente : Empleado\n    {\n        // Lista de empleados a cargo\n        protected List<Empleado> empleadosACargo;\n\n        // Constructor\n        public Gerente(int id, string nombre) : base(id, nombre)\n        {\n            empleadosACargo = new List<Empleado>();\n        }\n\n        // Método para agregar un empleado a su lista de empleados a cargo\n        public void AgregarEmpleado(Empleado empleado)\n        {\n            empleadosACargo.Add(empleado);\n        }\n\n        // Sobrescribe el método de la clase base para incluir información adicional\n        public override void Informacion()\n        {\n            base.Informacion();\n            Console.WriteLine(\"Tipo: Gerente\");\n            Console.WriteLine($\"Empleados a cargo: {empleadosACargo.Count}\");\n        }\n    }\n\n    // Clase GerenteProyecto hereda de Gerente\n    class GerenteProyecto : Gerente\n    {\n        // Propiedad específica de un Gerente de Proyectos\n        protected string areaProyecto;\n\n        // Constructor\n        public GerenteProyecto(int id, string nombre, string areaProyecto) : base(id, nombre)\n        {\n            this.areaProyecto = areaProyecto;\n        }\n\n        // Sobrescribe el método de la clase base para incluir información adicional\n        public override void Informacion()\n        {\n            base.Informacion();\n            Console.WriteLine($\"Área del Proyecto: {areaProyecto}\");\n        }\n    }\n\n    // Clase Programador hereda de Empleado\n    class Programador : Empleado\n    {\n        // Propiedad específica de un Programador\n        protected string lenguaje;\n\n        // Constructor\n        public Programador(int id, string nombre, string lenguaje) : base(id, nombre)\n        {\n            this.lenguaje = lenguaje;\n        }\n\n        // Sobrescribe el método de la clase base para incluir información adicional\n        public override void Informacion()\n        {\n            base.Informacion();\n            Console.WriteLine($\"Lenguaje: {lenguaje}\");\n        }\n    }\n    class Program\n    {\n        static void Main(string[] args)\n        {\n\n            // Creación de instancias de Perro y Gato\n            Perro miPerro = new Perro(\"Bobby\", 5);\n            Gato miGato = new Gato(\"Whiskers\", 3);\n\n            // Llamada a los métodos específicos de cada clase\n            miPerro.Sonido(); // Salida: ¡Guau Guau!\n            miGato.Sonido(); // Salida: ¡Miau Miau!\n\n            // Creación de instancias de empleados\n            Gerente gerente1 = new Gerente(1, \"Juan\");\n            GerenteProyecto gerenteProyecto1 = new GerenteProyecto(2, \"María\", \"Desarrollo Web\");\n            Programador programador1 = new Programador(3, \"Pedro\", \"C#\");\n\n            // Agregar empleados a cargo del gerente\n            gerente1.AgregarEmpleado(gerenteProyecto1);\n            gerenteProyecto1.AgregarEmpleado(programador1);\n\n            // Mostrar información de los empleados\n            Console.WriteLine(\"Información del Gerente:\");\n            gerente1.Informacion();\n            Console.WriteLine(\"\\nInformación del Gerente de Proyecto:\");\n            gerenteProyecto1.Informacion();\n            Console.WriteLine(\"\\nInformación del Programador:\");\n            programador1.Informacion();\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/c++/Fravelz.cpp",
    "content": "#include <iostream>\n#include <vector>\n\nusing namespace std;\n\nclass Animal {\nprivate:\n    string name;\n\npublic:\n    Animal(string name_) : name(name_) {}\n\n    virtual void sonido() = 0;\n};\n\nclass Perro : public Animal {\npublic:\n    Perro(string name_) : Animal(name_) {};\n\n    void sonido() override { cout << \"\\nGuau!!\"; }\n};\n\nclass Gato : public Animal {\npublic:\n    Gato(string name_) : Animal(name_) {};\n\n    void sonido() override { cout << \"\\nMiau!!\"; }\n};\n\n// ***************** DIFICULTAD EXTRA (opcional) ***************** //\n\nclass Empleados {\nprotected:\n    int id;\n    string name;\n    vector<string> empleados;\n\n\npublic:\n    Empleados(string name_, int id_) {\n        this->id = id_;\n        this->name = name_;\n    }\n\n    virtual void agregar_empleados(string) = 0;\n\n    void mostrarEmpreados() {\n        if (empleados.size() >= 1) {\n            cout << \"\\n > Empleados de \" << name << \": \";\n            for (string empleado : empleados) cout << empleado << ' ';\n\n        } else {\n            cout << \"\\n [!] \" << name << \" no tienes empleados...\";\n        }\n    };\n};\n\nclass Gerente : public Empleados {\npublic:\n    Gerente(string name_=\"001\", int id_=0) : Empleados(name_, id_) {}\n\n    void cordinar_proyectos() { \n        cout << '\\n' << name << \" esta cordinando todos los proyectos...\"; \n    };\n\n    void agregar_empleados(string name_) { empleados.push_back(name_); };\n};\n\nclass Gerente_de_Proyectos : public Empleados {\npublic:\n    Gerente_de_Proyectos(string name_=\"001\", int id_=0) : Empleados(name_, id_) {}\n\n    void cordinar_proyecto() { cout << '\\n' << name << \" esta cordinando un proyecto...\"; };\n\n    void agregar_empleados(string name_) { empleados.push_back(name_); };\n};\n\nclass Programador : public Empleados {\nprotected:\n    string habilidad;\n\npublic:\n    Programador(string name_, int id_, string habilidad) : Empleados(name_, id_) {\n        this->habilidad = habilidad;\n    }\n\n    void codeando() { \n        cout << '\\n' << name << \" esta programando el codigo...\" << \" en lenguaje \" << habilidad; \n    };\n\n    void agregar_empleados(string info=\"Error\") {\n        cout << \"\\nEl programador no puede agregar empleados...\";\n    }\n};\n\nint main() {\n    Perro perro(\"Zeus\");\n    Gato gato(\"Adonis\");\n\n    perro.sonido();\n    gato.sonido();\n\n    cout << '\\n';\n\n    // ************ Prueba Ejercicio Dificultad Extra ************ //\n    \n    Gerente gerente(\"MouroDev\", 1);\n\n    gerente.agregar_empleados(\"NinoTv\");\n    gerente.agregar_empleados(\"AFK Programming\");\n    gerente.cordinar_proyectos();\n    gerente.mostrarEmpreados();\n    cout << '\\n';\n    \n    Gerente_de_Proyectos gerente_de_proyectos(\"Javier\", 1);\n    \n    gerente_de_proyectos.agregar_empleados(\"Nasha DEV\");\n    gerente_de_proyectos.cordinar_proyecto();\n    gerente_de_proyectos.mostrarEmpreados();\n    cout << '\\n';\n    \n    Programador programador(\"Francisco\", 1, \"C++\");\n    \n    programador.agregar_empleados(\"Minecraft Delevoper\");\n    programador.codeando();\n    programador.mostrarEmpreados();\n    cout << '\\n';\n\n    return 0;\n}"
  },
  {
    "path": "Roadmap/09 - HERENCIA/c++/RoniPG.cpp",
    "content": "// @Roni\n\n#include<iostream>\n#include<vector>\n#include<string>\n\n/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n */\nclass Animal{ // --> Superclase\npublic :\n\tvoid sonidoAnimal(){\n\t\tstd::cout<<\"Soy un animal que emite sonido\\n\";\n\t}\n};\nclass Perro : Animal{ // --> Subclase\npublic:\n\tvoid sonidoAnimal(){\n\t\tstd::cout<<\"Soy un perro y ladro\\n\";\n\t}\n};\nclass Gato : Animal{\npublic:\n\tvoid sonidoAnimal(){ // --> Subclase\n\t\tstd::cout<<\"Soy un gato y maúllo\\n\";\n\t}\n};\n/* DIFICULTAD EXTRA (opcional):\n\t * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n\t * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n\t * Cada empleado tiene un identificador y un nombre.\n\t * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n\t * actividad, y almacenan los empleados a su cargo.\n\t */\n//Declaracion de clases para su posterior creación\nclass Empleado;\nclass Gerente;\nclass Gerente_de_Proyectos;\nclass Programador;\nclass Empleado{ // --> Superclase\n//Atibutos heredables\nprotected :\n\tint identificador;\n\tstd::string nombre;\n\npublic:\n\tEmpleado(int identificador, std::string nombre) :\n\tidentificador(identificador),\n\tnombre(nombre)\n\t{}\n\tint getIdentificador() const {\n\t\treturn identificador;\n\t}\n\n\tvoid setIdentificador(int identificador) {\n\t\tthis->identificador = identificador;\n\t}\n\n\tconst std::string& getNombre() const {\n\t\treturn nombre;\n\t}\n\n\tvoid setNombre(const std::string &nombre) {\n\t\tthis->nombre = nombre;\n\t}\n};\nclass Gerente : public Empleado{ // --> Subclase\n//Atributos propios\nprivate:\n\tstd::string cargo;\n\tstd::vector<Empleado> g_d_p; // --> Lista de empleados\npublic:\n\tGerente(int identificador, std::string nombre) :\n\tEmpleado(identificador, nombre),\n\tcargo(\"Gerente\")\n\t{}\n\t//Metodos propios\n\tvoid asignarEmpleado(Empleado& gdp){\n\t\tg_d_p.push_back(gdp);\n\t}\n\tvoid soy(){\n\t\tstd::cout<<\"\\nSoy: \"<<this->nombre<<\"\\nMi cargo es: \"<<this->cargo;\n\t\tfor(Empleado gdp : this->g_d_p){\n\t\t\tstd::cout<<\"\\nTengo a cargo a: \"<<gdp.getNombre();\n\t\t}\n\t}\n\n};\nclass Gerente_de_Proyectos : public Empleado{ // --> Subclase\n//Atibutos propios\nprivate:\n\tstd::string cargo;\n\tstd::vector<Empleado> programadores; // --> Lista de empleados\npublic:\n\tGerente_de_Proyectos(int identificador, std::string nombre) :\n\t\tEmpleado(identificador,nombre),\n\t\tcargo(\"Gerente de Proyectos\")\n\t{}\n\tvoid asignarEncargado(Gerente& ger){\n\t\tger.asignarEmpleado(*this);\n\t}\n\tvoid asignarEmpleado(Empleado& pgr){\n\t\tprogramadores.push_back(pgr);\n\t}\n\tvoid soy(){\n\t\tstd::cout<<\"\\nSoy: \"<<this->nombre<<\"\\nMi cargo es: \"<<this->cargo;\n\t\tfor(Empleado gdp : this->programadores){\n\t\t\tstd::cout<<\"\\nTengo a cargo a: \"<<gdp.getNombre();\n\t\t}\n\t}\n};\nclass Programador : public Empleado{ // --> Subclase\n//Atributos propios\nprivate:\n\tstd::string cargo;\npublic:\n\tProgramador(int identificador, std::string nombre) :\n\t\tEmpleado(identificador,nombre),\n\t\tcargo(\"Programador\")\n\t{}\n\tvoid asignarEncargado(Gerente_de_Proyectos& gdp){\n\t\tgdp.asignarEmpleado(*this);\n\t}\n\tvoid soy(){\n\t\tstd::cout<<\"\\nSoy: \"<<this->nombre<<\"\\nMi cargo es: \"<< this->cargo;\n\t}\n};\n\n\nint main() {\n\t//Instanciamos los objetos\n\tAnimal an; // --> Objeto animal\n\tPerro perro; // --> Objeto perro\n\tGato gt; // --> Objeto gato\n\t//Llamamos a su funciones\n\tan.sonidoAnimal(); // --> Función de la superclase\n\tperro.sonidoAnimal(); // --> Función de la subclase sobreescrita\n\tgt.sonidoAnimal();// --> Función de la subclase\n\n\t// Instaciamos los objetos\n\tGerente ger1(0,\"A\"); // --> Objeto gerente\n\tGerente ger2(1,\"B\"); // --> Objeto gerente\n\tGerente_de_Proyectos gdp1(2,\"C\"); // --> Objeto gerente de proyectos\n\tGerente_de_Proyectos gdp2(3,\"D\"); // --> Objeto gerente de proyectos\n\tProgramador pgr1(4,\"E\"); // --> Objeto gerente de programador\n\tProgramador pgr2(5,\"F\"); // --> Objeto gerente de programador\n\t// Le asignamos un empleado(Gerente de proyecto) al Gerente\n\tger1.asignarEmpleado(gdp1); // --> Le asignamos un empleado\n\tger1.soy(); // --> Llamamos a la función propia del Gerente\n\t// Le asignamos un Encargado(Gerente) al Gerente de proyecto\n\tgdp2.asignarEncargado(ger2);// --> Le asignamos un encargado\n\tger2.soy(); // --> Llamamos a la función propia del Gerente\n\t// Le asignamos un empleado(Programador) al Gerente de proyecto\n\tgdp1.asignarEmpleado(pgr1);\n\tgdp1.soy(); // --> Llamamos a la función propia del Gerente de proyecto de proyecto sobrescrita\n\t// Le asignamos un Encargado(Gerente de proyecto) al Programador\n\tpgr2.asignarEncargado(gdp2);\n\tgdp2.soy();// --> Llamamos a la función propia del Gerente de proyecto de proyecto sobrescrita\n\tpgr1.soy();// --> Llamamos a la función propia del Programador de proyecto sobrescrita\n\tpgr2.soy();// --> Llamamos a la función propia del Programador de proyecto sobrescrita\n\n\treturn 0;\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/c++/dylanb55.cpp",
    "content": "#include<iostream>\nusing namespace std;\n\nclass Animal{\n\tprivate:\n\t\tstring nombre_animal;\n\t\tint edad_animal;\n\tpublic:\n\t\t//Constructor\n\t\tAnimal(string nombre_animal, int edad_animal){\n\t\t\tthis->nombre_animal = nombre_animal;\n\t\t\tthis->edad_animal = edad_animal;\n\t\t}\n\t\t\n\t\t//Setters\n\t\t\n\t\tvoid setNombreAnimal(string nuevoNombreAnimal){\n\t\t\tthis->nombre_animal = nuevoNombreAnimal;\n\t\t}\n\t\t\n\t\tvoid setNuevaEdad(int nuevaEdad){\n\t\t\tthis->edad_animal = nuevaEdad;\n\t\t}\n\t\n\t\t//Getters\n\t\t\n\t\tstring getNombreAnimal(){\n\t\t\treturn nombre_animal;\n\t\t}\n\t\t\n\t\tint getEdadAnimal(){\n\t\t\treturn edad_animal;\n\t\t}\n\t\n\t\t//Funcion virtual\n\t\t\n\t\tvoid virtual sonido() = 0;\n};\n\nclass Perro : public Animal{\n\tpublic:\n\t\t//Constructor por defecto, inicializamos con la herencia animal\n\t\tPerro(string nombre_animal, int edad_animal) : Animal(nombre_animal,edad_animal){\n\t\t\t\n\t\t}\n\t\t\n\t\t//Ya tenemos la certeza del sonido de un perro implementamos la funcion sonido\n\t\t\n\t\tvoid sonido(){\n\t\t\tcout << \"El Perro hace de sonido: Guau\" << endl;\n\t\t}\n};\n\nclass Gato : public Animal{\n\tpublic:\n\t\t//Constructor por defecto, inicializamos con la herencia animal\n\t\t\n\t\tGato(string nombre_animal,int edad_animal) : Animal(nombre_animal,edad_animal){\n\t\t\t\n\t\t}\n\t\t\n\t\t//Ya tenemos la certeza del sonido de un gato implementamos la funcion sonido\n\t\t\n\t\tvoid sonido(){\n\t\t\tcout << \"El gato hace de sonido: Miau\" << endl;\n\t\t}\n};\n\n//EMPIEZA DIFICULTAD EXTRA\n\nclass Empleados{\n\tprivate:\n\t\tstring nombre_empleado;\n\t\tstring identificador_empleado;\n\tpublic:\n\t\t//Constructor de un empleado\n\t\tEmpleados(string nombre_empleado, string identificador_empleado){\n\t\t\tthis->nombre_empleado = nombre_empleado;\n\t\t\tthis->identificador_empleado = identificador_empleado;\n\t\t}\n\t\t\n\t\t//Setters\n\t\t\n\t\tvoid setNombreEmpleado(string nuevoNombreEmpleado){\n\t\t\tthis->nombre_empleado = nuevoNombreEmpleado;\n\t\t}\n\t\t\n\t\tvoid setIdentificadorEmpleado(string nuevoIdentificadorEmpleado){\n\t\t\tthis->identificador_empleado = nuevoIdentificadorEmpleado;\n\t\t}\n\t\t\n\t\t//Getters\n\t\t\n\t\tstring getNombreEmpleado(){\n\t\t\treturn nombre_empleado;\n\t\t}\n\t\t\n\t\tstring getIdentificadorEmpleado(){\n\t\t\treturn identificador_empleado;\n\t\t}\n\t\t\n\t\t//Funciones\n\t\tvirtual void actividad() = 0;\n\t\tvirtual void almacen_cargo() = 0;\n};\n\nclass Gerente : public Empleados{\n\tprivate:\n\t\tint anios_exp;\n\t\tstring titulo_universitario;\n\tpublic:\n\t\t//Constructor\n\t\t\n\t\tGerente(string nombre_empleado, string identificador_empleado, int anios_exp, string titulo_universitario) : Empleados(nombre_empleado,identificador_empleado){\n\t\t\tthis->anios_exp = anios_exp;\n\t\t\tthis->titulo_universitario = titulo_universitario;\n\t\t}\n\t\t\n\t\t//Getters\n\t\t\n\t\tint getAniosExp(){\n\t\t\treturn this->anios_exp;\n\t\t}\n\t\t\n\t\tstring getTituloUniversitario(){\n\t\t\treturn this->titulo_universitario;\n\t\t}\n\t\t\n\t\t//Setters\n\t\t\n\t\tvoid setNuevosAnios(int nuevaExp){\n\t\t\tthis->anios_exp = nuevaExp;\n\t\t}\n\t\t\n\t\tvoid setNuevoTitulo(string nuevo_titulo_universitario){\n\t\t\tthis->titulo_universitario = nuevo_titulo_universitario;\n\t\t}\n\t\t\n\t\t\n\t\t//Ya tenemos clara la actividad de un Gerente programamos las funciones virtuales\n\t\tvoid actividad(){\n\t\t\tcout << \"Los gerentes se encargan de mantener una empresa, a traves del liderazgo, las reuniones con directores, entre otros. \" << endl;\n\t\t}\n\t\tvoid almacen_cargo(){\n\t\t\tcout << \"Los gerentes tienen a cargo a los gerentes de proyecto y programadores, ademas de otros empleados menores\" << endl;\n\t\t}\n};\n\nclass GerenteProyectos : public Empleados{\n\tprivate:\n\t\tstring titulo_universitario;\n\t\tint anios_exp;\n\tpublic:\n\t\t//Constructor\n\t\t\n\t\tGerenteProyectos(string nombre_empleado, string identificador_empleado, int anios_exp, string titulo_universitario) : Empleados(nombre_empleado,identificador_empleado){\n\t\t\tthis->anios_exp = anios_exp;\n\t\t\tthis->titulo_universitario = titulo_universitario;\n\t\t}\n\t\t\n\t\t//Getters\n\t\t\n\t\tstring getTituloUniversitario(){\n\t\t\treturn this->titulo_universitario;\n\t\t}\n\t\t\n\t\tint getAniosExp(){\n\t\t\treturn this->anios_exp;\n\t\t}\n\t\t\n\t\t//Setters\n\t\t\n\t\tvoid setTituloUniversitario(string nuevoTituloUniversitario){\n\t\t\tthis->titulo_universitario = nuevoTituloUniversitario;\n\t\t}\n\t\t\n\t\tvoid setAniosExp(int nuevaExp){\n\t\t\tthis->anios_exp = nuevaExp;\n\t\t}\n\t\t\n\t\t//Ya tenemos clara la actividad de un gerente de proyectos programamos las funciones virtuales\n\t\tvoid actividad(){\n\t\t\tcout << \"Los gerente de proyecto se encargan de la supervision de un proyecto en una empresa, los cuales generalmente los programadores tienen la tarea de realizar, el gerente apoya\" << endl;\n\t\t}\n\t\tvoid almacen_cargo(){\n\t\t\tcout << \"Los gerente de proyecto tienen en su almacen de cargos a los programadores especialmente\" << endl;\n\t\t}\n};\n\nclass Programadores : public Empleados{\n\tprivate:\n\t\tstring lenguaje_programacionExperimentado;\n\t\tstring titulo_universitario;\n\t\tbool es_jr;\n\tpublic:\n\t\t//Constructor 1 (No todos los programadores tenemos titulo)\n\t\t\n\t\tProgramadores(string nombre_empleado, string identificador_empleado,string lenguaje_programacionExperimentado, bool es_jr) : Empleados(nombre_empleado,identificador_empleado){\n\t\t\tthis->lenguaje_programacionExperimentado = lenguaje_programacionExperimentado;\n\t\t\tthis->es_jr = es_jr;\n\t\t}\n\t\t\n\t\t//Constructor 2 (Con titulo universitario)\n\t\tProgramadores(string nombre_empleado, string identificador_empleado,string lenguaje_programacionExperimentado, string titulo_universitario, bool es_jr) : Empleados(nombre_empleado,identificador_empleado){\n\t\t\tthis->lenguaje_programacionExperimentado = lenguaje_programacionExperimentado;\n\t\t\tthis->titulo_universitario = titulo_universitario;\n\t\t}\n\t\t\n\t\tvoid actividad(){\n\t\t\tcout << \"Los programadores se encargan de la creacion, mantenimiento, de software computacional \" << endl;\n\t\t}\n\t\tvoid almacen_cargo(){\n\t\t\tif(es_jr == false){\n\t\t\t\tcout << \"Este programador tiene a en su almacen de cargo a todos los programadores juniors\" << endl;\n\t\t\t}\n\t\t\telse{\n\t\t\t\tcout << \"Este programador no tiene personas en su almacen de cargos \" << endl;\n\t\t\t}\n\t\t}\n\t\t\n\t\t\t\n};\n\nint main(){\n\t//Probamos nuestras clases con dos objetos dinamicos del tipo perro y gato\n\tPerro* perro1 = new Perro(\"Rex\",4);\n\tGato* gato1 = new Gato(\"Manchitas\",3);\n\t\n\tperro1->sonido();\n\tgato1->sonido();\n\t\n\tcout << endl;\n\t//Probamos la jerarquia de empleados\n\t\n\tGerente* gerente1 = new Gerente(\"Jose\",\"765423\",10,\"Ingeniero Industrial y Doctorado en Ciencias de la computacion\");\n\tgerente1->actividad();\n\tgerente1->almacen_cargo();\n\tcout << endl;\n\tGerenteProyectos* gerentep1 = new GerenteProyectos(\"Ricardo\",\"543456\",5,\"Ingeniero en informatica\");\n\tgerentep1->actividad();\n\tgerentep1->almacen_cargo();\n\tcout << endl;\n\tcout << endl;\n\tProgramadores* programador1 = new Programadores(\"Pedro\",\"54123\",\"JavaScript\",false);\n\tprogramador1->actividad();\n\tprogramador1->almacen_cargo();\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/c++/hectorio23.cpp",
    "content": "#include <iostream>\n#include <string>\n#include <vector>\n\n/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n\n// Clase base Animal\nclass Animal {\nprivate:\n    // Atributos comunes para todos los animales\n    std::string nombre;\n    std::string alimentacion;\n    std::string habitad_natural;\n    int age;\n\npublic:\n    // Constructores\n    Animal() {}\n    Animal(std::string name, std::string alimentacion, std::string habitd, int edad): \n    nombre(name), alimentacion(alimentacion), habitad_natural(habitd), age(edad) {}\n\n    // Función virtual para hacer sonido del animal\n    virtual void hacer_sonido() { std::cout << \"Sonido de la clase Animal\\n\"; }\n\n    // Función para mostrar los detalles del animal\n    void getInfo() const {\n        std::cout << \"Nombre: \" << nombre << \"\\n\";\n        std::cout << \"Alimentacion: \" << alimentacion << \"\\n\";\n        std::cout << \"Habitad: \" << habitad_natural << \"\\n\";\n        std::cout << \"Edad: \" << age << \"\\n\";\n    }\n    \n    // Destructor virtual\n    virtual ~Animal() {}\n};\n\n// Clase derivada Perro\nclass Perro: public Animal {\npublic:\n    // Constructor\n    Perro(std::string name, std::string alimentacion, std::string habitd, int edad): Animal(name, alimentacion, habitd, edad) {}\n\n    // Función para hacer sonido del perro\n    void hacer_sonido() override {  std::cout << \"¡Woow Woow!\\n\"; }\n};\n\n// Clase derivada Gato\nclass Gato: public Animal {\npublic:\n    // Constructor\n    Gato(std::string name, std::string alimentacion, std::string habitd, int edad): Animal(name, alimentacion, habitd, edad) {}\n\n    // Función para hacer sonido del gato\n    void hacer_sonido() override {  std::cout << \"¡Miauu Miauu!\\n\"; }\n};\n\n/********************************************************************************\n************************** CLASES PARA LA RESOLUCION ****************************\n***************************** DEL EJERCICIO EXTRA *******************************\n*********************************************************************************/\n\n// Clase base Empleado\nclass Empleado {\nprotected:\n    std::string nombre;\n    int identificador;\n\npublic:\n    // Constructor\n    Empleado(const std::string& nombre, int identificador)\n        : nombre(nombre), identificador(identificador) {}\n\n    // Función virtual para mostrar detalles del empleado\n    virtual void mostrarDetalles() const {\n        std::cout << \"Nombre: \" << nombre << \", ID: \" << identificador;\n    }\n};\n\n// Clase derivada Gerente\nclass Gerente : public Empleado {\nprotected:\n    std::vector<Empleado*> empleadosACargo;\n\npublic:\n    // Constructor\n    Gerente(const std::string& nombre, int identificador)\n        : Empleado(nombre, identificador) {}\n\n    // Función para asignar empleado a cargo\n    void asignarEmpleado(Empleado* empleado) {\n        empleadosACargo.push_back(empleado);\n    }\n\n    // Función para mostrar detalles del gerente y empleados a cargo\n    void mostrarDetalles() const override {\n        std::cout << \"Gerente - \";\n        Empleado::mostrarDetalles();\n        std::cout << std::endl;\n        std::cout << \"Empleados a cargo:\\n\";\n        for (const auto& empleado : empleadosACargo) {\n            empleado->mostrarDetalles();\n            std::cout << std::endl;\n        }\n    }\n};\n\n// Clase derivada GerenteProyecto\nclass GerenteProyecto : public Gerente {\npublic:\n    // Constructor\n    GerenteProyecto(const std::string& nombre, int identificador)\n        : Gerente(nombre, identificador) {}\n\n    // Función para mostrar detalles del gerente de proyecto\n    void mostrarDetalles() const override {\n        std::cout << \"Gerente de Proyecto - \";\n        Gerente::mostrarDetalles();\n    }\n};\n\n// Clase derivada Programador\nclass Programador : public Empleado {\npublic:\n    // Constructor\n    Programador(const std::string& nombre, int identificador)\n        : Empleado(nombre, identificador) {}\n\n    // Función para mostrar detalles del programador\n    void mostrarDetalles() const override {\n        std::cout << \"Programador - \";\n        Empleado::mostrarDetalles();\n    }\n};\n\n// Función principal\nint main() {\n    // Creación de un gato\n    std::cout << \"Instancia de la clase GATO:\\n\";\n    Gato g1 { \"Musides\", \"Omnívoro\", \"Hogar\", 1 };\n    g1.hacer_sonido(); // Emite el sonido del gato\n    g1.getInfo(); // Muestra los detalles del gato\n\n    std::cout << \"\\n------------------------------------\\n\";\n\n    // Creación de un perro\n    std::cout << \"Instancia de la clase PERRO:\\n\";\n    Perro p1 { \"Rufus\", \"Carnívoro\", \"Hogar\", 2 };\n    p1.hacer_sonido(); // Emite el sonido del gato\n    p1.getInfo(); // Muestra los detalles del gato\n\n     std::cout << \"\\n\\n**********************************\\n\\n\";\n\n    // Ejercicio Extra: Creación de empleados y un gerente de proyecto\n    GerenteProyecto gerenteProyecto(\"Juan\", 1001);\n    Programador programador1(\"Pedro\", 2001);\n    Programador programador2(\"Maria\", 2002);\n\n    // Asignación de empleados al gerente de proyecto\n    gerenteProyecto.asignarEmpleado(&programador1);\n    gerenteProyecto.asignarEmpleado(&programador2);\n\n    // Mostrar detalles del gerente de proyecto y empleados a su cargo\n    gerenteProyecto.mostrarDetalles();\n\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/c++/jchavescaceres.cpp",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n\n#include <iostream>\n#include <string>\n#include <list>\n\n class Animal {\n\n\tpublic:\n\n \t\tvirtual const char* sound() const = 0;\n\t\tvirtual void printSound () const ;\n };\n\nvoid Animal::printSound()  const {\n\t\n\tstd::cout << sound() << \"\\n\";\n\n};\n\nclass Dog : public Animal {\n\n\tpublic:\n \t\tvirtual const char* sound() const;\n};\n\n\nconst char* Dog::sound() const {\n\treturn \"guau\";\n};\n\nclass Cat : public Animal {\n\n\tpublic:\n \t\tvirtual const char* sound() const;\n};\n\nconst char* Cat::sound() const {\n\treturn \"miau\";\n};\n\nclass Employee {\n\tprivate:\n\t\tconst unsigned int id;\n\t\tconst std::string name;\n\t\tstd::list<Employee*> listSubordinates;\n\t\t\n\tprotected:\n\t\tEmployee (unsigned int inId, std::string inName);\n\t\n\tpublic:\n\t\tint getId();\n\t\tstd::string getName();\n\n\t\tvoid addSubordinate (Employee* inEmployee);\n\t\tstd::list<Employee*> getListSubordinates();\n\n\t\tvirtual void print();\n};\n\nEmployee::Employee (unsigned int inId, std::string inName) :\n\tid (inId), name (inName), listSubordinates() {\n\n};\n\nint Employee::getId() {\n\treturn id;\n};\n\nstd::string Employee::getName() {\n\treturn name;\n};\n\nvoid Employee::addSubordinate (Employee* inEmployee) {\n\n\tlistSubordinates.push_back (inEmployee);\n\n};\n\nstd::list<Employee*> Employee::getListSubordinates() {\n\treturn listSubordinates;\n};\n\nvoid Employee::print() {\n\tstd::cout << \"id: \" << id << \" nombre: \" << name << \" , empleados a su cargo: \\n\" ;\n\tfor (std::list<Employee*>::iterator it=listSubordinates.begin(); it != listSubordinates.end(); ++it) {\n\t      (*it)->print();\n\t}\n}\n\nclass GeneralManager : public Employee {\n\tprivate:\n\t\tconst std::string department;\n\t\n\tpublic:\n\t\tGeneralManager (unsigned int inId, std::string inName, std::string inDepartment);\n\t\tstd::string getDepartment();\n\n\t\tvirtual void print();\n};\n\nGeneralManager::GeneralManager (unsigned int inId, std::string inName, std::string inDepartment) : \n\tEmployee (inId, inName), department (inDepartment) {\n\n};\n\nstd::string GeneralManager::getDepartment() {\n\treturn department;\n}\n\nvoid GeneralManager::print() {\n\tstd::cout << \"Gerente - departamento : \" << department << \" \";\n\tEmployee::print();\n}\n\nclass ProjectManager : public Employee {\n\tprivate:\n\t\tconst std::string project;\n\t\n\tpublic:\n\t\tProjectManager (unsigned int inId, std::string inName, std::string inProject);\n\t\tstd::string getProject();\n\n\t\tvirtual void print();\n};\n\nProjectManager::ProjectManager (unsigned int inId, std::string inName, std::string inProject) : \n\tEmployee (inId, inName), project (inProject) {\n\n};\n\nstd::string ProjectManager::getProject() {\n\treturn project;\n}\n\nvoid ProjectManager::print() {\n\tstd::cout << \"  Jefe de proyecto - proyecto : \" << project << \" \";\n\tEmployee::print();\n}\n\nclass Developer : public Employee {\n\tprivate:\n\t\tconst std::string mainProgrammingLanguage;\n\t\n\tpublic:\n\t\tDeveloper (unsigned int inId, std::string inName, std::string inMainProgrammingLanguage);\n\t\tstd::string getMainProgrammingLanguage();\n\n\t\tvirtual void print();\n};\n\nDeveloper::Developer (unsigned int inId, std::string inName, std::string inMainProgrammingLanguage) : \n\tEmployee (inId, inName), mainProgrammingLanguage (inMainProgrammingLanguage) {\n\n};\n\nstd::string Developer::getMainProgrammingLanguage() {\n\treturn mainProgrammingLanguage;\n}\n\nvoid Developer::print() {\n\tstd::cout << \"    Desarrollador - Lenguaje principal : \" << mainProgrammingLanguage << \" \";\n\tEmployee::print();\n}\n\nint main() {\n\n\tunsigned int identificador = 1;\n\n\tconst Animal* C_ARRAY_ANIMALS [] = {\n\t\tnew Dog(),\n\t\tnew Cat(),\n\t\tnew Cat(),\n\t\tnew Dog(),\n\t\tnew Cat()};\n\n\tfor (int i = 0; i < sizeof (C_ARRAY_ANIMALS) / sizeof (Animal*); i++) {\n\t\tC_ARRAY_ANIMALS [i]->printSound();\n\t};\n\n\t//Dificultad extra\n\tGeneralManager manager (identificador++, \"Gerente\" , \"Departamento\");\n\tProjectManager projectManager1 (identificador++, \"Jefe proyecto1\" , \"Proyecto1\");\n\tProjectManager projectManager2 (identificador++, \"Jefe proyecto1\" , \"Proyecto1\");\n\tDeveloper developer1 (identificador++, \"Desarrollador1\", \"Java\");\n\tDeveloper developer2 (identificador++, \"Desarrollador2\", \"Html\");\n\tDeveloper developer3 (identificador++, \"Desarrollador3\", \"Java\");\n\n\tDeveloper developer4 (identificador++, \"Desarrollador4\", \"C++\");\n\tDeveloper developer5 (identificador++, \"Desarrollador5\", \"Java\");\n\n\tmanager.addSubordinate (&projectManager1);\n\tmanager.addSubordinate (&projectManager2);\n\tprojectManager1.addSubordinate (&developer1);\n\tprojectManager1.addSubordinate (&developer2);\n\tprojectManager1.addSubordinate (&developer3);\n\tprojectManager2.addSubordinate (&developer4);\n\tprojectManager2.addSubordinate (&developer5);\n\n\tmanager.print();\n\n\n\t//Free memory\n\tfor (int i = 0; i < sizeof (C_ARRAY_ANIMALS) / sizeof (Animal*); i++) {\n\t\tdelete C_ARRAY_ANIMALS [i];\n\t};\n\n\treturn 0;\n};\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/c++/jhoshmc.cpp",
    "content": "/*\n ! EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n*/\n/*\n ! DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n*/\n#include<iostream>\n#include<string>\n#include<vector>\nusing namespace std;\n// todo clases ejercicio\nclass Animal{\n  //* atributos, en este caso como solo piden el sonido que hacen , solo sonido\n  private:\n    string _sonido;\n    string _nombre;\n\n  public:\n    //* constructor, está vacio :v\n    Animal(string nombre, string sonido){\n      _nombre = nombre;\n      _sonido = sonido;\n    };\n    //? metodos\n    //* metodo set sonido , para ingresar el sonido que produce el  animal\n    // void setAtributos(string nombre, string nuevoSonido){\n    //    _sonido = nuevoSonido;\n    //    _nombre = nombre;\n    // }\n    //* metodo para mostrar el sonido que produce el animal\n    void get_sonido(){\n      cout <<_nombre<<\": \"<< _sonido << endl;\n    };\n};\n\nclass Perro : public Animal{\n  public:\n    Perro(string nombre, string sonido):Animal(nombre,sonido){};\n};\n\nclass Gato : public Animal{\n  public:\n    Gato(string nombre,string sonido):Animal(nombre,sonido){};\n};\n// todo clases extra\n\nclass Empleado{\n  private:\n    string _id;\n    string _nombre;\n    string _cargo;\n\n  public:\n  Empleado(string id,string nombre,string cargo){\n    _id = id;\n    _nombre = nombre;\n    _cargo = cargo;\n  }\n  void getInfoEmpleado(){\n    cout << \"Empleado: \" << _id << \": \" << _nombre<<\" cargo: \"<<_cargo << endl;\n  }\n};\nclass Gerente: public Empleado{\n  private:\n    string _nombre;\n    vector<Empleado> personal;\n\n  public:\n    Gerente(string id,string nombre,string cargo): Empleado(id,nombre,cargo){\n      _nombre = nombre;\n    }\n    void set_agregar_personal(Empleado nuevoP){\n      personal.push_back(nuevoP);\n    }\n    void getPersonal(){\n      cout << \"Gerente: \" << _nombre << \" personal a cargo \\n\";\n      for (int i = 0; i < personal.size();i++){\n        personal[i].getInfoEmpleado();\n      }\n      \n    }\n  \n};\n\nclass GerenteProyecto : public Empleado{\n  private:\n    string _nombre;\n    vector<Empleado>equipo;\n    vector<string> proyectos;\n\n  public:\n   GerenteProyecto(string id, string nombre,string cargo):Empleado(id,nombre,cargo){\n     _nombre = nombre;\n   }\n   void setPersonalAcargo(Empleado miembro){\n    equipo.push_back(miembro);\n   }\n       \n   void setProyectos(string nombreProyecto){\n     proyectos.push_back(nombreProyecto);\n   }\n   void getEquipo(){\n     cout << \"Gerente de proyectos \" << _nombre << \": miembros de su equipo:\\n\";\n     for (int i = 0; i < equipo.size();i++){\n       equipo[i].getInfoEmpleado();\n     }\n   }\n   void getProyectos(){\n    cout << \"Gerente de proyectos \" << _nombre << \": proyectos a cargo:\\n\";\n    for (int i = 0; i < proyectos.size();i++){\n      cout << proyectos[i] << endl;\n    }\n   }\n};\n\nclass Programador : public Empleado{\n  private:\n    string _nombre;\n    string _proyectoEnCurso =\"ninguno\";\n\n  public:\n    Programador(string id, string nombre,string cargo):Empleado(id,nombre,cargo){\n      _nombre = nombre;\n    }\n    void setProyecto(string proyecto){\n    _proyectoEnCurso = proyecto;\n    }\n    void getProyectoEnCurso(){\n      cout << \"Programador: \" << _nombre << endl;\n      cout << \"proyecto en curso: \" << _proyectoEnCurso << endl;\n    }\n};\n\nvoid ejercicio();\nvoid extra();\nint main(){\n\n  ejercicio();\n  extra();\n  return 0;\n}\nvoid ejercicio(){\n  Perro chester(\"Chester\",\"Guau!\");\n  Gato lita(\"Lita\",\"Miau!\");\n  // chester.setAtributos(\"Chester\",\"Guau!\");\n  // lita.setAtributos(\"Lita\",\"Miau!\");\n  chester.get_sonido();\n  lita.get_sonido();\n}\n\nvoid extra(){\n  Gerente manuel(\"A125\", \"Manuel Zoto\",\"Gerente\");\n  GerenteProyecto jonas(\"G233\", \"Jonas Marques\",\"Gerente de proyectos\");\n  Programador roberto(\"P564\", \"Roberto Hernandez\",\"programador\");\n  manuel.getInfoEmpleado();\n  jonas.getInfoEmpleado();\n  roberto.getInfoEmpleado();\n  manuel.set_agregar_personal(jonas);\n  manuel.set_agregar_personal(roberto);\n  manuel.getPersonal();\n  jonas.setPersonalAcargo(roberto);\n  jonas.setProyectos(\"cambiar color del boton\");\n  jonas.setProyectos(\"reiniciar la pc\");\n  jonas.getEquipo();\n  jonas.getProyectos();\n  roberto.setProyecto(\"cambiar color boton\");\n  roberto.getProyectoEnCurso();\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/dart/bluefeatherdev.dart",
    "content": "/*\n* EJERCICIO:\n* Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n* implemente una superclase Animal y un par de subclases Perro y Gato,\n* junto con una función que sirva para imprimir el sonido que emite cada Animal.\n*\n* DIFICULTAD EXTRA (opcional):\n* Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n* pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n* Cada empleado tiene un identificador y un nombre.\n* Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n* actividad, y almacenan los empleados a su cargo.\n*/\n\n/// 1. [Concepto de herencia]:\nclass Animal {\n  void speak() {\n    print('...');\n  }\n}\n\nclass Dog extends Animal {\n  // Dog hereda métodos de Animal,\n  // Dog puede sobrescribírlos:\n  @override\n  void speak() {\n    print('Woof!');\n  }\n}\n\nclass Cat extends Animal {\n  // Cat hereda métodos de Animal,\n  // Cat puede sobrescribírlos:\n  @override\n  void speak() {\n    print('Meow!');\n  }\n}\n\n/// 2. [DIFICULTAD EXTRA]:\nclass Employees {\n  // Atributos de todo empleado\n  int id;\n  String name;\n  List employees = [];\n\n  // Constructor de empleados\n  Employees(this.id, this.name);\n\n  // Añadir un empleado\n  void addEmploy(Employees employ) {\n    employees.add(employ);\n  }\n\n  // Ver todos los empleados\n  void showEmployees() {\n    for (var employ in employees) {\n      print('id: ${employ.id}, name: ${employ.name}');\n    }\n  }\n\n  // Método común de todo empleado\n  void greet() {\n    print('I\\'m $name (Cargo: Employ, Id: $id)');\n  }\n}\n\nclass Managers extends Employees {\n  // Usar atributos de Empleados\n  Managers(super.id, super.name);\n\n  // Sobrescribir el método común\n  @override\n  void greet() {\n    print('I\\'m $name (Cargo: Manager, Id: $id)');\n  }\n\n  // Método único de Gerentes\n  void coordinateProjects() {\n    print('$name is coordinating all our projects!');\n  }\n}\n\nclass ProjectManager extends Employees {\n  // Atributo único de Gerentes de Proyectos\n  String project;\n\n  // Usar atributos de Empleados\n  ProjectManager(super.id, super.name, this.project);\n\n  // Sobrescribir el método común\n  @override\n  void greet() {\n    print('I\\'m $name (Cargo: Project Manager, Id: $id)');\n  }\n\n  // Método único de Gerentes de Proyectos\n  void coordinateProjects() {\n    print('$name is coordinating only his/her project: $project');\n  }\n}\n\nclass Programmers extends Employees {\n  // Atributo único de Programadores\n  String language;\n\n  // Usar atributos de Empleados\n  Programmers(super.id, super.name, this.language);\n\n  // Sobrescribir el método común\n  @override\n  void greet() {\n    print('I\\'m $name (Cargo: Programmer, Id: $id)');\n  }\n\n  // Método único de Programadores\n  void makeSoftware() {\n    print('$name is coding in $language!');\n  }\n}\n\nvoid main() {\n  /// 1. [Concepto de herencia]:\n  final myAnimal = Animal();\n  myAnimal.speak(); // ...\n\n  final myDog = Dog();\n  myDog.speak(); // Woof!\n\n  final myCat = Cat();\n  myCat.speak(); // Meow!\n\n  /// 2. [DIFICULTAD EXTRA]:\n  \n  // Definir roles de la empresa\n  final myManager = Managers(1, 'MoureDev');\n  \n  final myProjectManager1 = ProjectManager(2, 'KontrolDev', 'hello-ios');\n  final myProjectManager2 = ProjectManager(3, 'Roswell468', 'hello-android');\n  \n  final myProgrammer1 = Programmers(4, 'BlueFeatherDev', 'Dart');\n  final myProgrammer2 = Programmers(5, 'MeryDev', 'Swift');\n  final myProgrammer3 = Programmers(6, 'SwordDev', 'Java');\n  final myProgrammer4 = Programmers(7, 'WingDev', 'Kotlin');\n\n  // Empleados del Gerente\n  myManager.addEmploy(myProjectManager1);\n  myManager.addEmploy(myProjectManager2);\n\n  // Empleados de Gerentes de Proyectos  \n  myProjectManager1.addEmploy(myProgrammer1);\n  myProjectManager1.addEmploy(myProgrammer2);\n\n  myProjectManager2.addEmploy(myProgrammer3);\n  myProjectManager2.addEmploy(myProgrammer4);\n\n  // Actividad del Gerente + Sus empleados \n  myManager.coordinateProjects();\n  myManager.showEmployees();\n\n  // Actividad de los Gerentes de Proyectos + Sus empleados\n  myProjectManager1.coordinateProjects();\n  myProjectManager1.showEmployees();\n\n  myProjectManager2.coordinateProjects();\n  myProjectManager2.showEmployees();\n\n  // Actividades de los Programadores + No tienen empleados\n  myProgrammer1.makeSoftware();\n  myProgrammer2.makeSoftware();\n  myProgrammer3.makeSoftware();\n  myProgrammer4.makeSoftware();\n\n  // La empresa entera te saluda\n  myManager.greet();\n  myProjectManager1.greet();\n  myProjectManager2.greet();\n  myProgrammer1.greet();\n  myProgrammer2.greet();\n  myProgrammer3.greet();\n  myProgrammer4.greet();\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/dart/raulfauli.dart",
    "content": "/// #09 HERENCIA\n\nabstract class Animal {\n  String nombre;\n\n  Animal(this.nombre);\n\n  void emitirSonido();\n}\n\nclass Perro extends Animal {\n  Perro(String nombre) : super(nombre);\n\n  @override\n  void emitirSonido() {\n    print('$nombre dice \"Guau\"');\n  }\n}\n\nclass Gato extends Animal {\n  Gato(String nombre) : super(nombre);\n\n  @override\n  void emitirSonido() {\n    print('$nombre dice \"Miau\"');\n  }\n}\n\n// Extra\nclass Employee {\n  int id;\n  String nombre;\n\n  Employee(this.id, this.nombre);\n\n  void trabajar() {\n    print('$nombre está trabajando');\n  }\n}\n\nclass ProjectManager extends Employee {\n  ProjectManager(int id, String nombre) : super(id, nombre);\n\n  void gestionarProyecto() {\n    print('$nombre está gestionando un proyecto');\n  }\n}\n\nclass Manager extends ProjectManager {\n  Manager(int id, String nombre) : super(id, nombre);\n\n  void gestionar() {\n    print('$nombre está gestionando');\n  }\n}\n\nvoid main() {\n  final perro = Perro('Laica');\n  final gato = Gato('Calcetín');\n\n  perro.emitirSonido();\n  gato.emitirSonido();\n\n  // Extra\n  final empleado = Employee(1, 'Raúl');\n  empleado.trabajar();\n  final projectManager = ProjectManager(2, 'Alejandro');\n  projectManager.trabajar();\n  projectManager.gestionarProyecto();\n  final manager = Manager(3, 'Rafa');\n  manager.trabajar();\n  manager.gestionarProyecto();\n  manager.gestionar();\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/ejercicio.md",
    "content": "# #09 HERENCIA Y POLIMORFISMO\n> #### Dificultad: Media | Publicación: 26/02/24 | Corrección: 04/03/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/09 - HERENCIA/fortran/LeandroCFD.f90",
    "content": "module modulo_herencia !Definicion del modulo\n    implicit none\n\n    type :: Animal !Definición de la superclase Animal\n        character(len=20) :: nombre !Atributos de la clase\n        character(len=20) :: especie\n        integer :: edad\n        contains\n            procedure :: Sonido !Metodo de la clase\n    end type Animal\n\n    type, extends(Animal) :: Perro !Definición de la subclase Perro utilizando la sentencia extends para heredar de la clase Animal\n        character(len=20) :: raza !Atributos de la clase\n        contains\n            procedure :: Sonido => Ladrar !Sobrecarga del metodo Sonido\n    end type Perro\n\n    type, extends(Animal) :: Gato !Definición de la subclase Gato utilizando la sentencia extends para heredar de la clase Animal\n        character(len=20) :: raza !Atributos de la clase\n        contains\n            procedure :: Sonido => Maullar !Sobrecarga del metodo Sonido\n    end type Gato\n    \ncontains\n\n    subroutine Sonido(this) !Implementación del metodo Sonido de la clase Animal\n        class(Animal), intent(in) :: this\n        print *, 'El animal ', this%nombre,'no hace ningun sonido' \n    end subroutine Sonido\n\n    subroutine Ladrar(this) !Implementación del metodo Sonido de la clase Perro\n        class(Perro), intent(in) :: this\n        print *, 'El perro ', this%nombre, 'hace guau'\n    end subroutine Ladrar\n\n    subroutine Maullar(this) !Implementación del metodo Sonido de la clase Gato\n        class(Gato), intent(in) :: this\n        print *, 'El gato ', this%nombre, 'hace miau'\n    end subroutine Maullar\n    \nend module modulo_herencia\n\nmodule Empleados \n    implicit none\n\n    type :: Empleado\n        character(len=20) :: Nombre\n        integer :: Identificador\n        character(len=20), dimension(100) :: Empleados_a_cargo\n    contains\n        procedure :: Agregando_Empleado\n    end type Empleado\n\n    type, extends(Empleado) :: Gerente\n    contains\n        procedure :: Proyectos \n    end type Gerente\n\n    type, extends(Empleado) :: Gerente_de_proyecto\n    contains\n        procedure :: Proyecto\n    end type Gerente_de_proyecto\n\n    type, extends(Empleado) :: Programador\n        character(len=20) :: Lenguaje\n    contains\n        procedure :: Code\n        procedure :: Agregando_Empleado => Empleados_Programador\n    end type Programador\n\ncontains\n\n    subroutine Agregando_Empleado(this, Nombre, Identificador)\n        class(Empleado), intent(inout) :: this\n        character(len=20), intent(in) :: Nombre\n        integer, intent(in) :: Identificador\n        this%Empleados_a_cargo(Identificador)=Nombre\n    end subroutine Agregando_Empleado\n\n    subroutine Empleados_Programador(this, Nombre, Identificador)\n        class(Programador), intent(inout) :: this\n        character(len=20), intent(in) :: Nombre\n        integer, intent(in) :: Identificador\n        integer :: i\n        i=Identificador\n        print*, \"No se puede agregar empleados a cargo de un programador, \", this%Nombre, \"no puede estar a cargo de \", Nombre\n    end subroutine Empleados_Programador\n\n    subroutine Proyectos(this)\n        class(Gerente), intent(in) :: this\n        print *, 'El gerente ', this%Nombre, 'esta coordinando proyectos'\n    end subroutine Proyectos\n\n    subroutine Proyecto(this)\n        class(Gerente_de_proyecto), intent(in) :: this\n        print *, 'El gerente de proyecto ', this%Nombre, 'esta trabajando en su proyecto '\n    end subroutine Proyecto\n\n    subroutine Code(this)\n        class(Programador), intent(in) :: this\n        print *, 'El programador ', this%Nombre, 'esta programando en ', this%Lenguaje\n    end subroutine Code\n\nend module Empleados\n\nprogram HERENCIA\n    use modulo_herencia !Se llama a el modulo que contiene las clases\n    use Empleados\n    implicit none\n    integer :: i\n\n    type(Animal) :: Mianimal !Se crean objetos de las clases\n    type(Perro) :: Miperro\n    type(Gato) :: Migato\n\n    type(Gerente) :: MiGerente\n    type(Gerente_de_proyecto) :: MiGerente_de_proyecto\n    type(Programador) :: MiProgramador\n\n    Mianimal=Animal('Leandro', 'Desconocida', 0) !Se inicializan los objetos\n    Miperro=Perro('Toby', 'Canino', 5, 'Labrador')\n    Migato=Gato('Garfield', 'Felino', 3, 'Siames')\n\n    call Miperro%Sonido() !Se llama al metodo Sonido de cada objeto\n    call Migato%Sonido()\n    call Mianimal%Sonido()\n    \n    !DIFICULTAD EXTRA\n    print*, \" \"\n    print*, \"****************\"\n    print*, \"DIFICULTAD EXTRA\"\n    print*, \"****************\"\n    print*, \" \"\n    \n    MiGerente=Gerente('Juan', 1, '')\n    MiGerente_de_proyecto=Gerente_de_proyecto('Pedro', 2, '')\n    MiProgramador=Programador('Luis', 3, '', 'Fortran')\n\n    call MiGerente%Proyectos()\n    call MiGerente_de_proyecto%Proyecto()\n    call MiProgramador%Code()\n\n    call MiGerente%Agregando_Empleado(MiGerente_de_proyecto%Nombre,MiGerente_de_proyecto%Identificador)\n    call MiGerente%Agregando_Empleado(MiProgramador%Nombre,MiProgramador%Identificador)\n    call MiGerente_de_proyecto%Agregando_Empleado(MiProgramador%Nombre,MiProgramador%Identificador)\n    call MiProgramador%Agregando_Empleado(MiGerente%Nombre, MiGerente%Identificador)\n\n    print*, \"Los empleados a cargo de \", MiGerente%Nombre, \"son: \"\n    \n    do i = 1, 100\n        if (MiGerente%Empleados_a_cargo(i) /= '') then\n            print*,\" \", MiGerente%Empleados_a_cargo(i)\n        end if  \n    end do\n\n    print*, \"Los empleados a cargo de \", MiGerente_de_proyecto%Nombre, \"son: \"\n    \n    do i = 1, 100\n        if (MiGerente_de_proyecto%Empleados_a_cargo(i) /= '') then\n            print*,\" \", MiGerente_de_proyecto%Empleados_a_cargo(i)\n        end if  \n    end do\n    \nend program HERENCIA"
  },
  {
    "path": "Roadmap/09 - HERENCIA/go/AmadorQuispe.go",
    "content": "package main\n\nimport \"fmt\"\n\n//Go no cuenta con una palabra para declarar herencia en los structs, sin embargo sí tiene algo parecido.\n//Para que un struct en go posea todos los campos que declara otro struct, le pasamos este último como un campo anónimo\n\ntype Animal struct {\n\tcode string\n\tname string\n}\n\ntype Cat struct {\n\tAnimal\n}\n\ntype Dog struct {\n\tAnimal\n}\n\ntype Sound interface {\n\tMakeSound()\n}\n\nfunc (c *Cat) MakeSound() {\n\tfmt.Printf(\"El gato %s hace miau miau \\n\", c.name)\n}\n\nfunc (d *Dog) MakeSound() {\n\tfmt.Printf(\"El perro %s hace wau wau \\n\", d.name)\n}\n\n//Está función puede recibir cualquier struct que implemente la interfaz Sound\nfunc PrintAnimal(sound Sound) {\n\tsound.MakeSound()\n}\n\n//=============================================================\n//======================= EXTRA ===============================\n//=============================================================\ntype EmployeeManager interface {\n\tAddEmployee(employee Employee)\n\tPrintEmployees()\n}\n\ntype Employee struct {\n\tid        int\n\tname      string\n\temployees []Employee\n}\n\nfunc (e *Employee) AddEmployee(employee Employee) {\n\te.employees = append(e.employees, employee)\n}\n\nfunc (e *Employee) PrintEmployees() {\n\tfor _, employee := range e.employees {\n\t\tfmt.Printf(\"id : %d, name:%s\\n\", employee.id, employee.name)\n\t}\n}\n\ntype Manager struct {\n\tEmployee\n}\n\nfunc (m *Manager) CoordinateProjects() {\n\tfmt.Printf(\"%s está coordinando todos los proyectos de la empresa.\\n\", m.name)\n}\n\ntype ProjectManager struct {\n\tEmployee\n\tproject string\n}\n\nfunc (pm *ProjectManager) CoordinateProject() {\n\tfmt.Printf(\"%s está coordinando su proyecto %s \\n\", pm.name, pm.project)\n}\n\ntype Programmer struct {\n\tEmployee\n\tlanguages []string\n}\n\nfunc (e *Programmer) AddEmployee(employee Employee) {\n\tfmt.Println(\"Un programador no puede tener empleados, no se ha agregado\")\n}\n\nfunc (e *Programmer) Code() {\n\tfmt.Printf(\"%s está programando en %v\", e.name, e.languages)\n}\n\nfunc main() {\n\tcat1 := Cat{Animal{code: \"0001\", name: \"Thor\"}}\n\tPrintAnimal(&cat1)\n\tdog1 := Dog{Animal{code: \"0002\", name: \"Run Run\"}}\n\tPrintAnimal(&dog1)\n\t//EXTRA\n\tm := Manager{Employee{id: 100, name: \"Amador\"}}\n\tm.AddEmployee(Employee{id: 200, name: \"Alex\"})\n\tp := Programmer{languages: []string{\"Java\", \"Go\"}, Employee: Employee{id: 100, name: \"Mia\"}}\n\tp.AddEmployee(Employee{id: 300, name: \"Pedro\"})\n\n\tvar employeeManagers []EmployeeManager\n\temployeeManagers = append(employeeManagers, &m, &p)\n\n\tfor _, manager := range employeeManagers {\n\t\tmanager.AddEmployee(Employee{id: 500, name: \"New Employee\"})\n\t}\n\tm.CoordinateProjects()\n\tm.PrintEmployees()\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/go/FreyFonseca117.go",
    "content": "// # #09 HERENCIA Y POLIMORFISMO\n// > #### Dificultad: Media | Publicación: 26/02/24 | Corrección: 04/03/24\n\n// ## Ejercicio\n\n// ```\n// /*\n//  * EJERCICIO:\n//  * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n//  * implemente una superclase Animal y un par de subclases Perro y Gato,\n//  * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n//  *\n//  * DIFICULTAD EXTRA (opcional):\n//  * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n//  * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n//  * Cada empleado tiene un identificador y un nombre.\n//  * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n//  * actividad, y almacenan los empleados a su cargo.\n//  */\n// ```\n// #### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\n// Sigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n// > Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n\npackage main\n\nimport \"fmt\"\n\n//Go no cuenta con una palabra para declarar herencia en los structs, sin embargo sí tiene algo parecido.\n//Para que un struct en go posea todos los campos que declara otro struct, le pasamos este último como un campo anónimo\n\ntype Animal struct {\n\tcode string\n\tname string\n}\n\ntype Cat struct {\n\tAnimal\n}\n\ntype Dog struct {\n\tAnimal\n}\n\ntype Sound interface {\n\tMakeSound()\n}\n\nfunc (c *Cat) MakeSound() {\n\tfmt.Printf(\"El gato %s hace miau miau \\n\", c.name)\n}\n\nfunc (d *Dog) MakeSound() {\n\tfmt.Printf(\"El perro %s hace wau wau \\n\", d.name)\n}\n\n//Está función puede recibir cualquier struct que implemente la interfaz Sound\nfunc PrintAnimal(sound Sound) {\n\tsound.MakeSound()\n}\n\n//=============================================================\n//======================= EXTRA ===============================\n//=============================================================\ntype EmployeeManager interface {\n\tAddEmployee(employee Employee)\n\tPrintEmployees()\n}\n\ntype Employee struct {\n\tid        int\n\tname      string\n\temployees []Employee\n}\n\nfunc (e *Employee) AddEmployee(employee Employee) {\n\te.employees = append(e.employees, employee)\n}\n\nfunc (e *Employee) PrintEmployees() {\n\tfor _, employee := range e.employees {\n\t\tfmt.Printf(\"id : %d, name:%s\\n\", employee.id, employee.name)\n\t}\n}\n\ntype Manager struct {\n\tEmployee\n}\n\nfunc (m *Manager) CoordinateProjects() {\n\tfmt.Printf(\"%s está coordinando todos los proyectos de la empresa.\\n\", m.name)\n}\n\ntype ProjectManager struct {\n\tEmployee\n\tproject string\n}\n\nfunc (pm *ProjectManager) CoordinateProject() {\n\tfmt.Printf(\"%s está coordinando su proyecto %s \\n\", pm.name, pm.project)\n}\n\ntype Programmer struct {\n\tEmployee\n\tlanguages []string\n}\n\nfunc (e *Programmer) AddEmployee(employee Employee) {\n\tfmt.Println(\"Un programador no puede tener empleados, no se ha agregado\")\n}\n\nfunc (e *Programmer) Code() {\n\tfmt.Printf(\"%s está programando en %v\", e.name, e.languages)\n}\n\nfunc main() {\n\tcat1 := Cat{Animal{code: \"0001\", name: \"Thor\"}}\n\tPrintAnimal(&cat1)\n\tdog1 := Dog{Animal{code: \"0002\", name: \"Run Run\"}}\n\tPrintAnimal(&dog1)\n\t//EXTRA\n\tm := Manager{Employee{id: 100, name: \"Amador\"}}\n\tm.AddEmployee(Employee{id: 200, name: \"Alex\"})\n\tp := Programmer{languages: []string{\"Java\", \"Go\"}, Employee: Employee{id: 100, name: \"Mia\"}}\n\tp.AddEmployee(Employee{id: 300, name: \"Pedro\"})\n\n\tvar employeeManagers []EmployeeManager\n\temployeeManagers = append(employeeManagers, &m, &p)\n\n\tfor _, manager := range employeeManagers {\n\t\tmanager.AddEmployee(Employee{id: 500, name: \"New Employee\"})\n\t}\n\tm.CoordinateProjects()\n\tm.PrintEmployees()\n}"
  },
  {
    "path": "Roadmap/09 - HERENCIA/go/MiguelP-Dev.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n)\n\n/*\nEn 'Golang' no existe la herencia como en otros lenguajes, pero existe la composición.\nEsto no es un problema de diseño, el lenguaje está diseñado de esta manera\nen parte para evitar las jerarquías de tipo y evitar realizar un sobrediseño temprano en la solución.\nasí evitamos hacerla más compleja(pero no más funcional).\n\nComposición: Facil de testear, DI/DIP(Inyección de dependencias/Principio de inversión  de dependencias).\nGolang nos ofrece caracteristicas que van más allá:\n- Métodos que pueden usarse en diferentes tipos declarados.(maps, structs, slices, y otros tipos)\n- Interfaces implicitas: No necesitamos usar la palabra reservada 'Implements', ya que golang verifica si nuesto tipo\ntiene los métodos que requiere la interface y esto es muy util ya que varios tipos puenden satisfacer a una interface\ny no hace falta especificar que el tipo 'X' implementa a las interfaces '1', '2', '3', etc...\n- Incrustación de cammpos: Permite integrar tipos en otros tipos y esto no es analogo a las clases, pero no es idéntico.\n\nGolang no posee las funciones setter y getter aunque estas se pueden diseñar de manera simple com métodos.\n\nTipos: En golang existen muchos tipos; como los predeclarados: string, float, int, etc...\ntambién los tipos compuestos como los arreglos, maps, slice, estructs, etc...\nPero adicionalmente existen tipos compuestos, estos tienen ciertas condiciones como ser referenciados en el mismo\npaquete en que los declaramos.\npor eso no podemos añadir funcionalidades a los tipos predeclarados, pero lo que si podemos es construir un nuevo tipo a partir de uno\npredeclarado y añadirle nuevas funcionalidades\n\nGolang tampoco posee sobreescritura de métodos, en cambio tiene ocultación de métodos, aunque hay que tener cuidado cone esto\nporque pueden generarse conflictos.\n\npor ejemplo cuando tienes un capo de nombre en dos estructuras \"Humano y Empleado\" y embebemos empleado en humano para obtener sus métodos\ny atributos, puede haber conflicto al llamar el nombre, esto se soluciona llamando el nombre espesificando si lo queremos de la clase humano o\nla clase empleado.\n\nfmt.Println(e.Human.age) o fmt.Println(e.Employee.age) dependiendo desde de clase se requiera.\n*/\n\n// newBool nuevo tipo a partir de un tipo predeclarado\ntype newBool bool\n\n// String es el método de un nuevo tipo a partir de uno predeclarado\nfunc (b newBool) String() string {\n\tif b {\n\t\treturn \"VERDADERO\"\n\t}\n\treturn \"FALSO\"\n}\n\n// Composición de estructuras.\n// character es una clase padre\ntype character struct {\n\tname  string\n\trace  string\n\tatack bool\n}\n\n// animal es la clase padre\ntype animal struct {\n\tanimalType string\n\tsound      string\n}\n\n// sound es método de la clase padre animal\nfunc (a animal) makeSound() {\n\tfmt.Println(a.animalType, \" dice: \", a.sound)\n}\n\n// instancias con asignación directa de la clase padre \"animal\"\nvar cat = animal{animalType: \"Gato\", sound: \"Miau\"}\nvar dog = animal{animalType: \"Perro\", sound: \"Guau\"}\n\n// NewCharacter es el constructor de caracteres\nfunc NewCharacter(name, animalType string, atack bool) character {\n\treturn character{name, animalType, atack}\n}\n\n// Extra\n\n// employee es la clase padre del ejercio extra\ntype employee struct {\n\tid       int\n\tname     string\n\tposition string\n}\n\n// manager es una subclase de empleado\ntype manager struct {\n\temployee\n\temployees []employee\n}\n\n// projectManager es una subclase de empleado\ntype projectManager struct {\n\tmanager\n\tprojects []string\n}\n\n// programmer es la subclase de empleado\ntype programmer struct {\n\temployee\n\tlanguages []string\n}\n\nfunc main() {\n\tmonster := NewCharacter(\"Golg\", \"Dragon\", true)\n\tfmt.Println(\"Nombre: \", monster.name)\n\tfmt.Println(\"Raza: \", monster.race)\n\tfmt.Println(\"¿Ataca?: \", monster.atack)\n\n\t// Método impresor de sonido de los nimales\n\tcat.makeSound()\n\tdog.makeSound()\n\n\t// Extra\n\temployee1 := employee{id: 1, name: \"Miguel\", position: \"Programmer\"}\n\temployee2 := employee{id: 2, name: \"Ricardo\", position: \"Manager\"}\n\temployee3 := employee{id: 3, name: \"Vicente\", position: \"Project Manager\"}\n\tmanager1 := manager{employee: employee1, employees: []employee{employee2, employee3}}\n\tprojectManager1 := projectManager{manager: manager1, projects: []string{\"Project 1\", \"Project 2\"}}\n\tprogrammer1 := programmer{employee: employee1, languages: []string{\"Go\", \"Python\", \"Java\"}}\n\tprogrammer2 := programmer{employee: employee3, languages: []string{\"Java\", \"C#\"}}\n\n\tfmt.Println(\"Employee 1: \", employee1)\n\tfmt.Println(\"Employee 2: \", employee2)\n\tfmt.Println(\"Employee 3: \", employee3)\n\tfmt.Println(\"Manager 1: \", manager1)\n\tfmt.Println(\"Project Manager 1: \", projectManager1)\n\tfmt.Println(\"Programmer 1: \", programmer1)\n\tfmt.Println(\"Programmer 2: \", programmer2)\n\n\t// nuevo tipo a partir de uno predeclarado y con nueva funcionalidad(Simple)\n\tvar b newBool = true\n\tfmt.Println(b.String())\n\tb = false\n\tfmt.Println(b.String())\n\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/go/N0HagoNada.go",
    "content": "package main\n\nimport \"fmt\"\n\n/*\nEn Go, no existe la herencia en la forma tradicional\nEn su lugar, Go utiliza un sistema de composición e interfaces para lograr una funcionalidad similar a la herencia\nEn lugar de \"heredar\" comportamientos y propiedades de una clase base, una \"struct\" en Go puede incluir (o \"componerse de\") otras structs. Esto se hace incrustando una struct dentro de otra\nA través del uso de interfaces, Go permite un tipo de polimorfismo donde diferentes tipos pueden implementar la misma interfaz pero proporcionar implementaciones distintas para los métodos de la interfaz. Esto no  es sobrescritura en la froma tradicional.\n*/\n\ntype Animal interface {\n\tEmitirSonido()\n}\n\n/*\nLa interfaz Animal actua como una clase base abstracta con un contrato EmitirSonido() que las 'subclases' deben implementar.\n*/\ntype Perro struct {\n\tNombre string\n\tSonido string\n}\n\ntype Gato struct {\n\tNombre string\n\tSonido string\n}\n\nfunc (p *Perro) EmitirSonido() {\n\tfmt.Println(\"El perro dice: \", p.Sonido)\n}\nfunc (g *Gato) EmitirSonido() {\n\tfmt.Println(\"El gato dice: \", g.Sonido)\n}\n\n/*\nLa función invocarSonido, que acepta un argumento de tipo Animal, demuestra polimorfismo. Puedes pasar cualquier objeto que implemente la interfaz Animal (como un Perro o un Gato)\n*/\nfunc invocarSonido(a Animal) {\n\ta.EmitirSonido()\n}\n\n/********************RETO********************/\n// Empleado es la estructura base para todos los tipos de empleados.\ntype Empleado struct {\n\tIdentificador int\n\tNombre        string\n}\n\n// Gerente es un tipo de Empleado con empleados a su cargo.\ntype Gerente struct {\n\tEmpleado\n\tEmpleadosACargo []Empleado\n}\n\n// GerenteDeProyectos es similar a Gerente pero específico de proyectos.\ntype GerenteDeProyectos struct {\n\tEmpleado\n\tEmpleadosACargo []Empleado\n\tProyectoActual  string\n}\n\n// Programador es un empleado sin empleados a su cargo pero con tecnologías específicas.\ntype Programador struct {\n\tEmpleado\n\tTecnologias []string\n}\n\nfunc main() {\n\tp := &Perro{Nombre: \"temur\", Sonido: \"wof wof wof\"}\n\tg := &Gato{Nombre: \"michi\", Sonido: \"miau miau\"}\n\tinvocarSonido(p)\n\tinvocarSonido(g)\n\tfmt.Println(\"******************* RETO *******************\")\n\t// Creación de un Gerente\n\tgerente := Gerente{\n\t\tEmpleado: Empleado{\n\t\t\tIdentificador: 1,\n\t\t\tNombre:        \"Juan Pérez\",\n\t\t},\n\t\tEmpleadosACargo: []Empleado{}, // Inicialmente sin empleados a su cargo\n\t}\n\n\t// Creación de un Gerente de Proyectos\n\tgerenteDeProyectos := GerenteDeProyectos{\n\t\tEmpleado: Empleado{\n\t\t\tIdentificador: 2,\n\t\t\tNombre:        \"Ana Gómez\",\n\t\t},\n\t\tProyectoActual:  \"Desarrollo de Software\",\n\t\tEmpleadosACargo: []Empleado{}, // Inicialmente sin empleados a su cargo\n\t}\n\n\t// Creación de un Programador\n\tprogramador := Programador{\n\t\tEmpleado: Empleado{\n\t\t\tIdentificador: 3,\n\t\t\tNombre:        \"Carlos López\",\n\t\t},\n\t\tTecnologias: []string{\"Go\", \"Python\", \"JavaScript\"},\n\t}\n\n\tfmt.Println(gerente)\n\tfmt.Println(gerenteDeProyectos)\n\tfmt.Println(programador)\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/go/hozlucas28.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n)\n\n/* -------------------------------------------------------------------------- */\n/*                               ANIMAL (CLASS)                               */\n/* -------------------------------------------------------------------------- */\n\ntype Animal struct {\n\t_averageSpeed  float32\n\t_averageWeight float32\n\t_name          string\n\t_sound         string\n}\n\nfunc (animal *Animal) setAverageSpeed(averageSpeed float32) *Animal {\n\tanimal._averageSpeed = averageSpeed\n\treturn animal\n}\n\nfunc (animal *Animal) setAverageWeight(averageWeight float32) *Animal {\n\tanimal._averageWeight = averageWeight\n\treturn animal\n}\n\nfunc (animal *Animal) setName(name string) *Animal {\n\tanimal._name = name\n\treturn animal\n}\n\nfunc (animal *Animal) setSound(sound string) *Animal {\n\tanimal._sound = sound\n\treturn animal\n}\n\nfunc (animal *Animal) getAverageSpeed() float32 {\n\treturn animal._averageSpeed\n}\n\nfunc (animal *Animal) getAverageWeight() float32 {\n\treturn animal._averageWeight\n}\n\nfunc (animal *Animal) getName() string {\n\treturn animal._name\n}\n\nfunc (animal *Animal) getSound() string {\n\treturn animal._sound\n}\n\nfunc (animal *Animal) getAttributes() string {\n\treturn fmt.Sprintf(\"Average speed --> %.2f\", animal.getAverageSpeed()) +\n\t\tfmt.Sprintf(\"\\nAverage weight --> %.2f\", animal.getAverageWeight()) +\n\t\tfmt.Sprintf(\"\\nName --> %s\", animal.getName()) +\n\t\tfmt.Sprintf(\"\\nSound --> %s\", animal.getSound())\n}\n\nfunc (animal *Animal) printSound() *Animal {\n\tfmt.Printf(\"%s!\", animal.getSound())\n\treturn animal\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                 DOG (CLASS)                                */\n/* -------------------------------------------------------------------------- */\n\ntype Dog struct {\n\t_ownerName   string\n\t_ownerPhone  string\n\t_parentClass Animal\n}\n\nfunc (dog *Dog) setOwnerName(ownerName string) *Dog {\n\tdog._ownerName = ownerName\n\treturn dog\n}\n\nfunc (dog *Dog) setOwnerPhone(ownerPhone string) *Dog {\n\tdog._ownerPhone = ownerPhone\n\treturn dog\n}\n\nfunc (dog *Dog) getOwnerName() string {\n\treturn dog._ownerName\n}\n\nfunc (dog *Dog) getOwnerPhone() string {\n\treturn dog._ownerPhone\n}\n\nfunc (dog *Dog) getAttributes() string {\n\treturn dog._parentClass.getAttributes() +\n\t\tfmt.Sprintf(\"\\nOwner name --> %s\", dog.getOwnerName()) +\n\t\tfmt.Sprintf(\"\\nOwner phone --> %s\", dog.getOwnerPhone())\n}\n\nfunc (dog *Dog) printSound() *Dog {\n\tdog._parentClass.printSound()\n\treturn dog\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                 CAT (CLASS)                                */\n/* -------------------------------------------------------------------------- */\n\ntype Cat struct {\n\t_ownerName   string\n\t_ownerPhone  string\n\t_parentClass Animal\n}\n\nfunc (cat *Cat) setOwnerName(ownerName string) *Cat {\n\tcat._ownerName = ownerName\n\treturn cat\n}\n\nfunc (cat *Cat) setOwnerPhone(ownerPhone string) *Cat {\n\tcat._ownerPhone = ownerPhone\n\treturn cat\n}\n\nfunc (cat *Cat) getOwnerName() string {\n\treturn cat._ownerName\n}\n\nfunc (cat *Cat) getOwnerPhone() string {\n\treturn cat._ownerPhone\n}\n\nfunc (cat *Cat) getAttributes() string {\n\treturn cat._parentClass.getAttributes() +\n\t\tfmt.Sprintf(\"\\nOwner name --> %s\", cat.getOwnerName()) +\n\t\tfmt.Sprintf(\"\\nOwner phone --> %s\", cat.getOwnerPhone())\n}\n\nfunc (cat *Cat) printSound() *Cat {\n\tcat._parentClass.printSound()\n\treturn cat\n}\n\n/* -------------------------------------------------------------------------- */\n/*                              EMPLOYEE (CLASS)                              */\n/* -------------------------------------------------------------------------- */\n\ntype Employee struct {\n\t_id     int\n\t_name   string\n\t_salary float32\n}\n\nfunc (employee *Employee) setName(name string) *Employee {\n\temployee._name = name\n\treturn employee\n}\n\nfunc (employee *Employee) setSalary(salary float32) *Employee {\n\temployee._salary = salary\n\treturn employee\n}\n\nfunc (employee *Employee) getId() int {\n\treturn employee._id\n}\n\nfunc (employee *Employee) getName() string {\n\treturn employee._name\n}\n\nfunc (employee *Employee) getSalary() float32 {\n\treturn employee._salary\n}\n\nfunc (employee *Employee) getAttributes() string {\n\treturn fmt.Sprintf(\"Id --> %d\", employee.getId()) +\n\t\tfmt.Sprintf(\"\\nName --> %s\", employee.getName()) +\n\t\tfmt.Sprintf(\"\\nSalary --> %.2f\", employee.getSalary())\n}\n\n/* -------------------------------------------------------------------------- */\n/*                             PROGRAMMER (CLASS)                             */\n/* -------------------------------------------------------------------------- */\n\ntype Programmer struct {\n\t_languages   []string\n\t_side        string\n\t_parentClass Employee\n}\n\nfunc (programmer *Programmer) setLanguages(languages []string) *Programmer {\n\tprogrammer._languages = languages\n\treturn programmer\n}\n\nfunc (programmer *Programmer) setSide(side string) *Programmer {\n\tprogrammer._side = side\n\treturn programmer\n}\n\nfunc (programmer *Programmer) getLanguages() []string {\n\treturn programmer._languages\n}\n\nfunc (programmer *Programmer) getSide() string {\n\treturn programmer._side\n}\n\nfunc (programmer *Programmer) getAttributes() string {\n\treturn programmer._parentClass.getAttributes() +\n\t\tfmt.Sprintf(\"\\nLanguages --> %s\", programmer.getLanguages()) +\n\t\tfmt.Sprintf(\"\\nSide --> %s\", programmer.getSide())\n}\n\nfunc (programmer *Programmer) writeCode(language string) *Programmer {\n\tfmt.Printf(\"\\nWriting code in %s\", language)\n\treturn programmer\n}\n\n/* -------------------------------------------------------------------------- */\n/*                           PROJECT MANAGER (CLASS)                          */\n/* -------------------------------------------------------------------------- */\n\ntype ProjectManager struct {\n\t_functions   []string\n\t_programmers []Programmer\n\t_parentClass Employee\n}\n\nfunc (projectManager *ProjectManager) setFunctions(functions []string) *ProjectManager {\n\tprojectManager._functions = functions\n\treturn projectManager\n}\n\nfunc (projectManager *ProjectManager) setProgrammers(programmers []Programmer) *ProjectManager {\n\tprojectManager._programmers = programmers\n\treturn projectManager\n}\n\nfunc (projectManager *ProjectManager) getFunctions() []string {\n\treturn projectManager._functions\n}\n\nfunc (projectManager *ProjectManager) getProgrammers() []Programmer {\n\treturn projectManager._programmers\n}\n\nfunc (projectManager *ProjectManager) getAttributes() string {\n\treturn projectManager._parentClass.getAttributes() +\n\t\tfmt.Sprintf(\"\\nFunctions --> %s\", projectManager.getFunctions()) +\n\t\tfmt.Sprintf(\"\\nProgrammers --> %v\", projectManager.getProgrammers())\n}\n\nfunc (projectManager *ProjectManager) makeManagement() *ProjectManager {\n\tfmt.Printf(\"\\nJust a project manager doing everything expect programming.\")\n\treturn projectManager\n}\n\n/* -------------------------------------------------------------------------- */\n/*                               MANAGER (CLASS)                              */\n/* -------------------------------------------------------------------------- */\n\ntype Manager struct {\n\t_department      string\n\t_functions       []string\n\t_projectManagers []ProjectManager\n\t_parentClass     Employee\n}\n\nfunc (manager *Manager) setDepartment(department string) *Manager {\n\tmanager._department = department\n\treturn manager\n}\n\nfunc (manager *Manager) setFunctions(functions []string) *Manager {\n\tmanager._functions = functions\n\treturn manager\n}\n\nfunc (manager *Manager) setProjectManagers(projectManagers []ProjectManager) *Manager {\n\tmanager._projectManagers = projectManagers\n\treturn manager\n}\n\nfunc (manager *Manager) getDepartment() string {\n\treturn manager._department\n}\n\nfunc (manager *Manager) getFunctions() []string {\n\treturn manager._functions\n}\n\nfunc (manager *Manager) getProjectManagers() []ProjectManager {\n\treturn manager._projectManagers\n}\n\nfunc (manager *Manager) getAttributes() string {\n\treturn manager._parentClass.getAttributes() +\n\t\tfmt.Sprintf(\"\\nDepartment --> %s\", manager.getDepartment()) +\n\t\tfmt.Sprintf(\"\\nFunctions --> %s\", manager.getFunctions()) +\n\t\tfmt.Sprintf(\"\\nProject managers --> %v\", manager.getProjectManagers())\n\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\nfunc main() {\n\tvar dog Dog = Dog{\n\t\t_ownerName:  \"Juan Nuñez\",\n\t\t_ownerPhone: \"1148574862\",\n\t\t_parentClass: Animal{\n\t\t\t_averageSpeed:  28.60,\n\t\t\t_averageWeight: 21.78,\n\t\t\t_name:          \"Cunca\",\n\t\t\t_sound:         \"Woof\",\n\t\t},\n\t}\n\n\tfmt.Println(\"Dog attributes...\")\n\tfmt.Printf(\"\\n%s\", dog.getAttributes())\n\n\tfmt.Println(\"\\n\\nDog sound...\")\n\tfmt.Printf(\"\\ndog.printSound() --> \")\n\tdog.printSound()\n\n\tvar cat Cat = Cat{\n\t\t_ownerName:  \"Lucas Hoz\",\n\t\t_ownerPhone: \"1124565887\",\n\t\t_parentClass: Animal{\n\t\t\t_averageSpeed:  18.56,\n\t\t\t_averageWeight: 10.86,\n\t\t\t_name:          \"Mini\",\n\t\t\t_sound:         \"Meow\",\n\t\t},\n\t}\n\n\tfmt.Println(\"\\n\\nCat attributes...\")\n\tfmt.Printf(\"\\n%s\", cat.getAttributes())\n\n\tfmt.Println(\"\\n\\nCat sound...\")\n\tfmt.Printf(\"\\ncat.printSound() --> \")\n\tcat.printSound()\n\n\tfmt.Println(\"\\n\\n# ---------------------------------------------------------------------------------- #\\n\")\n\n\t/*\n\t\tAdditional challenge...\n\t*/\n\n\tfmt.Println(\"Additional challenge...\")\n\n\tvar programmer Programmer = Programmer{\n\t\t_languages: []string{\"TypeScript\", \"Python\", \"Golang\"},\n\t\t_side:      \"Backend\",\n\t\t_parentClass: Employee{\n\t\t\t_id:     0,\n\t\t\t_name:   \"Lucas Hoz\",\n\t\t\t_salary: 125000,\n\t\t},\n\t}\n\n\tfmt.Println(\"\\nProgrammer attributes...\")\n\tfmt.Printf(\"\\n%s\", programmer.getAttributes())\n\n\tvar projectManager ProjectManager = ProjectManager{\n\t\t_functions:   []string{\"Time management\", \"Management\"},\n\t\t_programmers: []Programmer{programmer},\n\t\t_parentClass: Employee{\n\t\t\t_id:     1,\n\t\t\t_name:   \"Juan Nuñez\",\n\t\t\t_salary: 175000,\n\t\t},\n\t}\n\n\tfmt.Println(\"\\n\\nProject manager attributes...\")\n\tfmt.Printf(\"\\n%s\", projectManager.getAttributes())\n\n\tvar manager Manager = Manager{\n\t\t_department:      \"Development\",\n\t\t_functions:       []string{\"Time management\", \"Financial planning\", \"Communication\"},\n\t\t_projectManagers: []ProjectManager{projectManager},\n\t\t_parentClass: Employee{\n\t\t\t_id:     2,\n\t\t\t_name:   \"Martin Gomez\",\n\t\t\t_salary: 225000,\n\t\t},\n\t}\n\n\tfmt.Println(\"\\n\\nManager attributes...\")\n\tfmt.Printf(\"\\n%s\", manager.getAttributes())\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/go/kodenook.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc main() {\n\tvar animal Animal = Animal{\"bob\"}\n\tvar dog Dog = Dog{animal, \"black\"}\n\n\tanimal.MakeSound()\n\tdog.MakeSound()\n}\n\ntype Animal struct {\n\tName string\n}\n\nfunc (a *Animal) MakeSound() {\n\tfmt.Println(\"Some generic animal sound\")\n}\n\ntype Dog struct {\n\tAnimal\n\tcolor string\n}\n\ntype Cat struct {\n\tAnimal\n\tcolor string\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/go/miguelex.go",
    "content": "package main\n\nimport \"fmt\"\n\n// Como vimos en el reto anterior, en Go el concepto de clases es algo distinto a otros lenguajes.\n\ntype Animal interface {\n\tsonido()\n}\n\ntype Perro struct {\n\tnombre string\n\tsound  string\n}\n\ntype Gato struct {\n\tnombre string\n\tsound  string\n}\n\nfunc (perro *Perro) sonido() {\n\tfmt.Println(\"El perro de nombre \" + perro.nombre + \" emite el sonido \" + perro.sound)\n}\n\nfunc (gato *Gato) sonido() {\n\tfmt.Println(\"El gato de nombre \" + gato.nombre + \" emite el sonido \" + gato.sound)\n}\n\ntype Empleado struct {\n\tIdentificador int\n\tNombre        string\n}\n\ntype Gerente struct {\n\tEmpleado  // Incorpora todos los campos de Empleado en Gerente\n\tEmpleados []string\n}\n\ntype GerenteP struct {\n\tEmpleado      // Incorpora todos los campos de Empleado en GerenteP\n\tProgramadores []string\n}\n\ntype Programador struct {\n\tEmpleado  // Incorpora todos los campos de Empleado en Programador\n\tLenguajes []string\n}\n\nfunc (gerente *Gerente) gestiona() {\n\tfmt.Println(\"El gerente de proyectos \" + gerente.Nombre + \" gestiona a los empleados \" + fmt.Sprint(gerente.Empleados))\n}\n\nfunc (gerenteP *GerenteP) gestiona() {\n\tfmt.Println(\"El gerente \" + gerenteP.Nombre + \" gestiona a los programadores \" + fmt.Sprint(gerenteP.Programadores))\n}\n\nfunc (programador *Programador) programa() {\n\tfmt.Println(\"El programador \" + programador.Nombre + \" programa en los lenguajes \" + fmt.Sprint(programador.Lenguajes))\n}\n\nfunc main() {\n\tperro := Perro{\"Milu\", \"Guau, guau\"}\n\tgato := Gato{\"Garfield\", \"Miauuuuuuu\"}\n\n\tperro.sonido()\n\tgato.sonido()\n\n\t// Extra\n\n\tgerente := Gerente{\n\t\tEmpleado: Empleado{\n\t\t\tIdentificador: 1,\n\t\t\tNombre:        \"Migue\",\n\t\t},\n\t\tEmpleados: []string{\"Fran\", \"Maria\", \"Ana\"},\n\t}\n\n\tgerenteP := GerenteP{\n\t\tEmpleado: Empleado{\n\t\t\tIdentificador: 2,\n\t\t\tNombre:        \"Fran\",\n\t\t},\n\t\tProgramadores: []string{\"Pablo\", \"Rafa\", \"Carlos\"},\n\t}\n\n\tprogramador := Programador{\n\t\tEmpleado: Empleado{\n\t\t\tIdentificador: 3,\n\t\t\tNombre:        \"Carlos\",\n\t\t},\n\t\tLenguajes: []string{\"Go\", \"Python\", \"Java\"},\n\t}\n\n\tgerente.gestiona()\n\tgerenteP.gestiona()\n\tprogramador.programa()\n\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/go/qwik-zgheib.go",
    "content": "package main\n\nimport \"fmt\"\n\ntype Animal interface {\n\tMakeSound() string\n}\n\ntype Dog struct {\n\tName string\n}\n\nfunc (d Dog) MakeSound() string {\n\treturn \"Woof!\"\n}\n\ntype Cat struct {\n\tName string\n}\n\nfunc (c Cat) MakeSound() string {\n\treturn \"Meow!\"\n}\n\nfunc PrintSound(a Animal) {\n\tfmt.Printf(\"%s\\n\", a.MakeSound())\n}\n\n/* extra */\ntype Employee struct {\n\tID   int\n\tName string\n}\n\ntype Manager struct {\n\tEmployee\n\tEmployees []Employee\n}\n\ntype ProjectManager struct {\n\tManager\n\tProjects []string\n}\n\ntype Programmer struct {\n\tEmployee\n\tLanguages []string\n}\n\nfunc PrintDetails(e Employee) {\n\tfmt.Printf(\"ID: %d, Name: %s\\n\", e.ID, e.Name)\n}\n\nfunc PrintManagerDetails(m Manager) {\n\tPrintDetails(m.Employee)\n\tfmt.Println(\"Employees under management:\")\n\tfor _, emp := range m.Employees {\n\t\tPrintDetails(emp)\n\t}\n}\n\nfunc PrintProjectManagerDetails(pm ProjectManager) {\n\tPrintManagerDetails(pm.Manager)\n\tfmt.Println(\"Projects managed:\")\n\tfor _, project := range pm.Projects {\n\t\tfmt.Println(project)\n\t}\n}\n\nfunc PrintProgrammerDetails(p Programmer) {\n\tPrintDetails(p.Employee)\n\tfmt.Println(\"Programming languages known:\")\n\tfor _, lang := range p.Languages {\n\t\tfmt.Println(lang)\n\t}\n}\n\nfunc main() {\n\tdog := Dog{Name: \"Buddy\"}\n\tcat := Cat{Name: \"Whiskers\"}\n\n\tPrintSound(dog)\n\tPrintSound(cat)\n\n\t/* extra */\n\tmanager := Manager{\n\t\tEmployee: Employee{ID: 1, Name: \"Alice\"},\n\t\tEmployees: []Employee{\n\t\t\t{ID: 2, Name: \"Bob\"},\n\t\t\t{ID: 3, Name: \"Charlie\"},\n\t\t},\n\t}\n\n\tprojectManager := ProjectManager{\n\t\tManager: Manager{\n\t\t\tEmployee: Employee{ID: 4, Name: \"Diana\"},\n\t\t\tEmployees: []Employee{\n\t\t\t\t{ID: 5, Name: \"Eve\"},\n\t\t\t\t{ID: 6, Name: \"Frank\"},\n\t\t\t},\n\t\t},\n\t\tProjects: []string{\"Project X\", \"Project Y\"},\n\t}\n\n\tprogrammer := Programmer{\n\t\tEmployee:  Employee{ID: 7, Name: \"Grace\"},\n\t\tLanguages: []string{\"Go\", \"Python\", \"Java\"},\n\t}\n\n\tPrintManagerDetails(manager)\n\tfmt.Println()\n\tPrintProjectManagerDetails(projectManager)\n\tfmt.Println()\n\tPrintProgrammerDetails(programmer)\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/go/raynerpv2022.go",
    "content": "package main\n\nimport \"fmt\"\n\n// /*\n//  * EJERCICIO:\n//  * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n//  * implemente una superclase Animal y un par de subclases Perro y Gato,\n//  * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n//  *\n\ntype Salvaje interface {\n\tSonido()\n}\ntype Animal struct {\n\tnombre string\n}\n\ntype Gusano struct {\n\tAnimal\n\tsonido string\n}\n\ntype Hormiga struct {\n\tAnimal\n\tsonido string\n}\n\nfunc (g Gusano) Sonido() {\n\tfmt.Printf(\"Me llamo  %s y hago %s\\n\", g.nombre, g.sonido)\n}\n\nfunc (h Hormiga) Sonido() {\n\tfmt.Printf(\"Me llamo  %s y hago %s\\n\", h.nombre, h.sonido)\n}\n\nfunc AnimalSalvaje(AS Salvaje) {\n\tAS.Sonido()\n\n}\n\n// ************************************************************\n//  * DIFICULTAD EXTRA (opcional):\n//  * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n//  * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n//  * Cada empleado tiene un identificador y un nombre.\n//  * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n//  * actividad, y almacenan los empleados a su cargo.\n//  */\n\ntype Empleado struct {\n\tid              int\n\tnombre          string\n\templeadosACargo []Empleado\n}\n\ntype Gerente struct {\n\tEmpleado\n\tproyectos []string\n}\n\ntype GerenteP struct {\n\tEmpleado\n\tproyecto string\n}\n\ntype Programador struct {\n\tEmpleado\n\tlenguajes []string\n}\n\nfunc (p *Programador) MostrarLenguajes() {\n\tfmt.Printf(\"Soy el programador %v y puedo programar en %v \\n\", p.nombre, p.lenguajes)\n}\n\nfunc (p *Programador) Addlengajes(lenguaje string) {\n\n\tp.lenguajes = append(p.lenguajes, lenguaje)\n\tfmt.Println(\"Lenguaje guardado\")\n}\n\nfunc (p *Programador) MostrarEmpleados() {\n\tfmt.Printf(\"Soy el programador %v y no puedo tener empleados a cargo \\n\", p.nombre)\n}\n\nfunc (g *GerenteP) MostrarEmpleados() {\n\tfmt.Printf(\"Soy el Gerente de Proyecto %v \\n\", g.nombre)\n\tfmt.Printf(\"Mis empleados a cargo son  %v \\n\", g.empleadosACargo)\n\n}\n\nfunc (g *GerenteP) AddEmpleados(empleado Empleado) {\n\tg.empleadosACargo = append(g.empleadosACargo, empleado)\n\tfmt.Println(\"Empleado guardado\")\n\n}\n\nfunc (g *GerenteP) Mostrarproyecto() {\n\tfmt.Printf(\"Soy el Gerente de Proyecto %v \\n\", g.nombre)\n\tfmt.Printf(\"Miproyecto es   %v \\n\", g.proyecto)\n}\n\nfunc (g *GerenteP) AddProyecto(proyecto string) {\n\tg.proyecto = proyecto\n\tfmt.Println(\"Proyecto guardado\")\n\n}\n\nfunc (g *Gerente) Mostrarproyectos() {\n\tfmt.Printf(\"Soy el Gerente   %v \\n\", g.nombre)\n\tfmt.Printf(\"Mis proyecto son   %v \\n\", g.proyectos)\n}\n\nfunc (g *Gerente) Addproyectos(proyecto string) {\n\tg.proyectos = append(g.proyectos, proyecto)\n\tfmt.Println(\"Proyecto guardado\")\n}\nfunc (g *Gerente) MostrarEmpleados() {\n\tfmt.Printf(\"Soy el Gerente   %v \\n\", g.nombre)\n\tfmt.Printf(\"Mis empleados son   %v \\n\", g.empleadosACargo)\n}\n\nfunc (g *Gerente) AddEmpleados(empleado Empleado) {\n\tg.empleadosACargo = append(g.empleadosACargo, empleado)\n\tfmt.Println(\"Proyecto guardado\")\n}\nfunc main() {\n\tgusanito := Gusano{Animal{\"gusi\"}, \"ffffff\"}\n\thormiguita := Hormiga{Animal{\"hormi\"}, \"gggggg\"}\n\tAnimalSalvaje(gusanito)\n\tAnimalSalvaje(hormiguita)\n\n\tfmt.Println(\"************* Extra ************\")\n\tp1 := Programador{\n\t\tEmpleado{\n\t\t\t9,\n\t\t\t\"Pepito\",\n\t\t\tnil,\n\t\t},\n\t\tnil}\n\n\tp1.Addlengajes(\"Java\")\n\tp1.Addlengajes(\"Python\")\n\tp2 := Programador{\n\t\tEmpleado{\n\t\t\t8,\n\t\t\t\"Juannito\",\n\t\t\tnil,\n\t\t},\n\t\tnil}\n\tp2.Addlengajes(\"Golang\")\n\tp2.Addlengajes(\"C++\")\n\n\tgp1 := GerenteP{\n\t\tEmpleado{\n\t\t\t2,\n\t\t\t\"kuko\",\n\t\t\tnil,\n\t\t},\n\t\t\"\"}\n\tgp2 := GerenteP{\n\t\tEmpleado{\n\t\t\t3,\n\t\t\t\"lalo\",\n\t\t\tnil,\n\t\t},\n\t\t\"\"}\n\tgp1.AddProyecto(\"Web\")\n\tgp2.AddProyecto(\"MOngodb\")\n\tgp1.AddEmpleados(p1.Empleado)\n\tgp2.AddEmpleados(p2.Empleado)\n\tg := Gerente{\n\t\tEmpleado{\n\t\t\t1,\n\t\t\t\"Jefesito\",\n\t\t\tnil,\n\t\t},\n\t\tnil}\n\tg.Addproyectos(gp1.proyecto)\n\tg.Addproyectos(gp2.proyecto)\n\tg.AddEmpleados(gp1.Empleado)\n\tg.AddEmpleados(gp2.Empleado)\n\n\tp1.MostrarLenguajes()\n\tp1.MostrarEmpleados()\n\n\tp2.MostrarLenguajes()\n\tp2.MostrarEmpleados()\n\n\tgp1.MostrarEmpleados()\n\tgp1.Mostrarproyecto()\n\n\tgp2.MostrarEmpleados()\n\tgp2.Mostrarproyecto()\n\n\tg.MostrarEmpleados()\n\tg.Mostrarproyectos()\n\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/go/thegera4.go",
    "content": "package main\n\nimport \"fmt\"\n\n// En go no existen las clases, pero se pueden simular con estructuras y métodos\ntype Animal struct {\n\tname string\n} \n\nfunc (a *Animal) makeSound() {\n\tfmt.Printf(\"Soy un %s y hago ruido\\n\", a.name)\n}\n\ntype Dog struct {\n\tAnimal // \"Herencia\" (composición)\n}\n\nfunc (d *Dog) makeSound() {\n\t// imprimir la frase 'El <nombre> hace guau!' y agregar un salto de línea\n\tfmt.Printf(\"El %s hace guau!\\n\", d.name)\n}\n\ntype Cat struct {\n\tAnimal\n}\n\nfunc (c *Cat) makeSound() {\n\tfmt.Printf(\"El %s hace miau!\\n\", c.name)\n}\n\nfunc main() {\n\td := Dog{Animal{\"Perro\"}}\n\tc := Cat{Animal{\"Gato\"}}\n\n\td.makeSound()\n\tc.makeSound()\n\n\t// Extra:\n\tmgr := Manager{Employee{1, \"Gerardo\"}, []Employee{{2, \"Pedro\"}, {3, \"María\"}, {4, \"Juan\"}}}\n\tpm := ProjectManager{Employee{5, \"Luis\"}, []string{\"Proyecto 1\", \"Proyecto 2\"}}\n\tp := Programmer{Employee{6, \"Ana\"}, \"Go\"}\n\n\n\tmgr.work()\n\tmgr.evaluate()\n\tpm.work()\n\tpm.manageProject()\n\tp.work()\n\tp.code()\n}\n\n// Solución extra:\ntype Employee struct {\n\tid   int\n\tname string\n\n}\n\nfunc (e *Employee) work() {\n\tfmt.Printf(\"El empleado %s está trabajando\\n\", e.name)\n}\n\n\ntype Manager struct {\n\tEmployee\n\temployees []Employee\n}\n\nfunc (m *Manager) evaluate(){\n\tfmt.Printf(\"El gerente %s está evaluando a sus empleados %v\\n\", m.name, m.employees)\n}\n\ntype ProjectManager struct {\n\tEmployee\n\tprojects []string\n}\n\nfunc (pm *ProjectManager) manageProject(){\n\tfmt.Printf(\"El gerente de proyecto %s está manejando los proyectos %v\\n\", pm.name, pm.projects)\n}\n\ntype Programmer struct {\n\tEmployee\n\tlanguage string\n}\n\nfunc (p *Programmer) code(){\n\tfmt.Printf(\"El programador %s está programando en %s\\n\", p.name, p.language)\n}"
  },
  {
    "path": "Roadmap/09 - HERENCIA/java/AbelADE.java",
    "content": "public class Main {\n    public static void main(String[] args) {\n        Dog dog = new Dog(\"Tobby\");\n        System.out.println(dog);\n        dog.speak();\n\n        Cat cat = new Cat(\"Dora\");\n        System.out.println(cat);\n        cat.speak();\n\n        System.out.println(\"\\n------ DIFICULTAD EXTRA ---------\\n\");\n\n        Manager manager = new Manager(0,\"Moure\");\n        ProjectManager projectManager1 = new ProjectManager(1, \"Luis\", \"09\");\n        ProjectManager projectManager2 = new ProjectManager(2, \"Carlos\", \"08\");\n        Programmer programmer1 = new Programmer(3,\"Abel\",\"Java\");\n        Programmer programmer2 = new Programmer(4,\"María\",\"PHP\");\n        Programmer programmer3 = new Programmer(5,\"Cecília\",\"JavaScript\");\n        Programmer programmer4 = new Programmer(6,\"Julián\",\"Kotlin\");\n\n        manager.addEmployee(projectManager1);\n        manager.addEmployee(projectManager2);\n        manager.printEmployees();\n\n        projectManager1.addEmployee(programmer1);\n        projectManager1.addEmployee(programmer2);\n        projectManager1.printEmployees();\n\n        projectManager2.addEmployee(programmer3);\n        projectManager2.addEmployee(programmer4);\n        projectManager2.printEmployees();\n\n        programmer1.addEmployee(programmer2);\n        programmer1.printEmployees();\n\n        programmer2.code();\n    }\n}\n\nclass Animal{\n    //Atributos\n    String name;\n    String sound;\n\n    //Geters y Seters\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public String getSound() {\n        return sound;\n    }\n\n    public void setSound(String sound) {\n        this.sound = sound;\n    }\n\n    //Constructor\n    public Animal(String name) {\n        this.name = name;\n    }\n\n    //Método para hablar\n    public void speak(){\n        System.out.println(sound);\n    }\n\n    @Override\n    public String toString() {\n        return getClass().getName() + \": \" + name;\n    }\n}\n\nclass Dog extends Animal{\n    public Dog(String name) {\n        super(name);\n        this.sound = \"Guau!\";\n    }\n}\n\nclass Cat extends Animal{\n    public Cat(String name) {\n        super(name);\n        this.sound = \"Miau!\";\n    }\n}\n\nclass Employee{\n    int id;\n    String name;\n    ArrayList<Employee> employees;\n\n    public int getId() {\n        return id;\n    }\n\n    public void setId(int id) {\n        this.id = id;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public ArrayList<Employee> getEmployees() {\n        return employees;\n    }\n\n    public void setEmployees(ArrayList<Employee> employees) {\n        this.employees = employees;\n    }\n\n    public Employee(int id, String name) {\n        this.id = id;\n        this.name = name;\n        this.employees = new ArrayList<>();\n    }\n\n    public void addEmployee(Employee employee) {\n        this.employees.add(employee);\n    }\n\n    public void printEmployees() {\n        System.out.print(\"Trabajadores a cargo de \" + name + \":\");\n        for (Employee employee : employees) {\n            System.out.print(\" - \" + employee.getName());\n        }\n        System.out.println();\n    }\n}\n\nclass Manager extends Employee{\n    public Manager(int id, String name) {\n        super(id, name);\n    }\n\n    public void coordinate(){\n        System.out.println(name + \" está coordinando los proyectos.\");\n    }\n}\n\nclass ProjectManager extends Employee{\n    String project;\n\n    public ProjectManager(int id, String name, String project) {\n        super(id, name);\n        this.project = project;\n    }\n\n    public void coordinate(){\n        System.out.println(name + \" está coordinando el proyecto \" + project);\n    }\n}\n\nclass Programmer extends Employee{\n    String language;\n\n    public Programmer(int id, String name, String language) {\n        super(id, name);\n        this.language = language;\n    }\n\n    public void code(){\n        System.out.println(name + \" está programando un proyecto en \" + language);\n    }\n\n    @Override\n    public void addEmployee(Employee employee) {\n        System.out.println(\"No puede tener empleados a su cargo.\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/java/AmadorQuispe.java",
    "content": "/* Clase principal */\npublic class Inheritance {\n\n    public static void main(String[] args) {\n        Animal dog = new Dog(1, \"Lalo\");\n        dog.sound();\n        Animal cat = new Cat(1, \"Lalo\");\n        cat.sound();\n\n        Programmer programmer1 = new Programmer(1, \"Amador\");\n        programmer1.addLanguage(\"Java\");\n        programmer1.addLanguage(\"Go\");\n        programmer1.addLanguage(\"Python\");\n\n        Programmer programmer2 = new Programmer(2, \"Rosa\");\n        programmer2.addLanguage(\"PHP\");\n        programmer2.addLanguage(\"C#\");\n\n        Programmer programmer3 = new Programmer(3, \"Mario\");\n        programmer3.addLanguage(\"JavaScript\");\n        programmer3.addLanguage(\"HTML\");\n        programmer3.addLanguage(\"CSS\");\n\n        Project project1 = new Project(\"P001\", \"Desarrollo E-Commerce\");\n        project1.addToTeam(programmer1);\n        project1.addToTeam(programmer3);\n\n        ProjectManager projectManager1 = new ProjectManager(4, \"Pedro\");\n        projectManager1.addProject(project1);\n        projectManager1.listProjects();\n\n        Manager manager = new Manager(5, \"Maure Dev\");\n        manager.addProgramer(programmer1);\n        manager.addProgramer(programmer2);\n        manager.addProgramer(programmer3);\n\n        manager.addProjectManager(projectManager1);\n\n    }\n}\n\n\n\n/*==================CLASE ANIMAL======================*/\npublic class Animal {\n    private int code;\n    private String name;\n\n    public Animal() {\n    }\n\n    public Animal(int code, String name) {\n        this.code = code;\n        this.name = name;\n    }\n\n    public void sound() {\n        System.err.println(\"hace sonido\");\n    }\n\n    public int getCode() {\n        return code;\n    }\n\n    public void setCode(int code) {\n        this.code = code;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n}\n\n\n/*==================CLASE CAT======================*/\npublic class Cat extends Animal {\n    public Cat() {\n    }\n\n    public Cat(int code, String name) {\n        super(code, name);\n    }\n\n    @Override\n    public void sound() {\n        System.err.println(\"El gato Hace Miau Miau\");\n    }\n}\n\n\n\n/*==================CLASE DOG======================*/\npublic class Dog extends Animal {\n    public Dog() {\n    }\n\n    public Dog(int code, String name) {\n        super(code, name);\n    }\n\n    @Override\n    public void sound() {\n        System.err.println(\"El perro Hace Wau Wau\");\n    }\n}\n\n\n\n/*==================CLASE EMPLOYEE======================*/\npublic class Employee {\n    private Integer code;\n    private String name;\n\n    public Employee() {\n    }\n\n    public Employee(Integer code, String name) {\n        this.code = code;\n        this.name = name;\n    }\n\n    public Integer getCode() {\n        return code;\n    }\n\n    public void setCode(Integer code) {\n        this.code = code;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    @Override\n    public boolean equals(Object obj) {\n        if (obj instanceof Employee) {\n            Employee e = (Employee) obj;\n            if (this.code.equals(e.code))\n                return true;\n        }\n        return false;\n    }\n\n}\n\n\n\n\n/*==================CLASE PROJECT======================*/\npublic class Project {\n    private String code;\n    private String name;\n    private Set<Programmer> team;\n\n    public Project() {\n    }\n\n    public Project(String code, String name) {\n        this.code = code;\n        this.name = name;\n    }\n\n    public void addToTeam(Programmer programmer) {\n        if (team == null) {\n            this.team = new HashSet<>();\n        }\n        this.team.add(programmer);\n    }\n\n    public String getCode() {\n        return code;\n    }\n\n    public void setCode(String code) {\n        this.code = code;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public Set<Programmer> getTeam() {\n        return team;\n    }\n\n}\n\n\n\n\n/*==================CLASE MANAGER======================*/\npublic class Manager extends Employee {\n    private Set<ProjectManager> projectManagers;\n    private Set<Programmer> programmers;\n\n    public Manager() {\n    }\n\n    public Manager(Integer code, String name) {\n        super(code, name);\n    }\n\n    public void addProjectManager(ProjectManager projectManager) {\n        if (projectManagers == null) {\n            this.projectManagers = new HashSet<>();\n        }\n        this.projectManagers.add(projectManager);\n    }\n\n    public void addProgramer(Programmer programmer) {\n        if (programmers == null) {\n            this.programmers = new HashSet<>();\n        }\n        this.programmers.add(programmer);\n    }\n\n    public Set<ProjectManager> getProjectManagers() {\n        return projectManagers;\n    }\n\n    public Set<Programmer> getProgrammers() {\n        return programmers;\n    }\n\n}\n\n\n\n\n\n/*==================CLASE PROJECT MANAGER======================*/\npublic class ProjectManager extends Employee {\n    private List<Project> projects;\n\n    public ProjectManager() {\n    }\n\n    public ProjectManager(Integer code, String name) {\n        super(code, name);\n    }\n\n    public void addProject(Project project) {\n        if (projects == null) {\n            this.projects = new ArrayList<>();\n        }\n        this.projects.add(project);\n    }\n\n    public List<Project> getProjects() {\n        return projects;\n    }\n\n    public void listProjects() {\n        this.projects.forEach(p -> {\n            System.out.println(\"#\".repeat(20));\n            System.out.println(String.format(\"Proyecto %s - %s\", p.getCode(), p.getName()));\n            System.out.println(String.format(\"Gerentes de Proyecto : %s - %s\", getCode(), getName()));\n            System.out.println(\"Equipo conformado por :\");\n            p.getTeam().forEach(t -> System.out.println(t.toString()));\n        });\n    }\n\n}\n\n\n\n/*==================CLASE PROGRAMMER======================*/\npublic class Programmer extends Employee {\n    private Set<String> languages;\n\n    public Programmer() {\n    }\n\n    public Programmer(Integer code, String name) {\n        super(code, name);\n        this.languages = new HashSet<>();\n    }\n\n    public Set<String> getLanguages() {\n        return languages;\n    }\n\n    public void setLanguages(Set<String> languages) {\n        this.languages = languages;\n    }\n\n    public void addLanguage(String language) {\n        this.languages.add(language);\n    }\n\n    @Override\n    public String toString() {\n        return String.format(\"Código : %s, Nombre : %s, Lenguajes : %s\", getCode(), getName(), getLanguages());\n    }\n\n}"
  },
  {
    "path": "Roadmap/09 - HERENCIA/java/AnaLauDB.java",
    "content": "import java.util.ArrayList;\n\npublic class AnaLauDB {\n    public static void main(String[] args) {\n        // Animales\n        Animal perro = new Perro(\"Toby\");\n        Animal gato = new Gato(\"Garfield\");\n\n        perro.hacerSonido();\n        gato.hacerSonido();\n\n        // Empleados\n        Gerente jefe = new Gerente(1, \"Laura\");\n        GerenteDeProyecto gproyecto = new GerenteDeProyecto(2, \"Leonel\", \"App Móvil\");\n        Programador prog1 = new Programador(3, \"Abril\", \"Java\");\n        Programador prog2 = new Programador(4, \"Angie\", \"Python\");\n\n        jefe.agregarEmpleado(gproyecto);\n        jefe.agregarEmpleado(prog1);\n        jefe.agregarEmpleado(prog2);\n\n        jefe.mostrarInfo();\n        gproyecto.mostrarInfo();\n        prog1.mostrarInfo();\n        prog2.mostrarInfo();\n    }\n\n    // ==================\n    // EJERCICIO ANIMALES\n    // ==================\n    public static class Animal {\n        String nombre;\n\n        public Animal(String nombre) {\n            this.nombre = nombre;\n        }\n\n        public void hacerSonido() {\n            System.out.println(\"El animal hace un sonido.\");\n        }\n    }\n\n    public static class Perro extends Animal {\n        public Perro(String nombre) {\n            super(nombre);\n        }\n\n        @Override\n        public void hacerSonido() {\n            System.out.println(nombre + \" el perro hace ¡Guau guau!\");\n        }\n    }\n\n    public static class Gato extends Animal {\n        public Gato(String nombre) {\n            super(nombre);\n        }\n\n        @Override\n        public void hacerSonido() {\n            System.out.println(nombre + \" el gato hace ¡Miau miau!\");\n        }\n    }\n\n    // ==================\n    // EXTRA EMPLEADOS\n    // ==================\n    public static class Empleado {\n        int id;\n        String nombre;\n\n        public Empleado(int id, String nombre) {\n            this.id = id;\n            this.nombre = nombre;\n        }\n\n        public void mostrarInfo() {\n            System.out.println(\"ID: \" + id + \", Nombre: \" + nombre);\n        }\n    }\n\n    public static class Gerente extends Empleado {\n        ArrayList<Empleado> empleadosACargo = new ArrayList<>();\n\n        public Gerente(int id, String nombre) {\n            super(id, nombre);\n        }\n\n        public void agregarEmpleado(Empleado e) {\n            empleadosACargo.add(e);\n        }\n\n        @Override\n        public void mostrarInfo() {\n            System.out.println(\"Gerente: \" + id + \" - \" + nombre);\n            System.out.println(\"Empleados a cargo:\");\n            for (Empleado e : empleadosACargo) {\n                System.out.println(\"   - \" + e.nombre);\n            }\n        }\n    }\n\n    public static class GerenteDeProyecto extends Empleado {\n        String proyecto;\n\n        public GerenteDeProyecto(int id, String nombre, String proyecto) {\n            super(id, nombre);\n            this.proyecto = proyecto;\n        }\n\n        @Override\n        public void mostrarInfo() {\n            System.out.println(\"Gerente de Proyecto: \" + id + \" - \" + nombre + \" (Proyecto: \" + proyecto + \")\");\n        }\n    }\n\n    public static class Programador extends Empleado {\n        String lenguaje;\n\n        public Programador(int id, String nombre, String lenguaje) {\n            super(id, nombre);\n            this.lenguaje = lenguaje;\n        }\n\n        @Override\n        public void mostrarInfo() {\n            System.out.println(\"Programador: \" + id + \" - \" + nombre + \" (Lenguaje: \" + lenguaje + \")\");\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/java/AndrewCodev.java",
    "content": "package ejercicio09;\n\nimport java.util.ArrayList;\n\npublic class AndrewCodev {\n\tpublic static void main(String[] args) {\n\t\tPerro perro = new Perro(null, null);\n\t\tperro.setNombre(\"Pluto\");\n\t\tperro.setRaza(\"Labrador\");\n\t\tperro.ladra();\n\n\t\tSystem.out.println(perro.getNombre() + \" - \" + perro.getRaza() + \" - \" + perro.ladra());\n\t\tGato gato = new Gato(null, null);\n\t\tgato.setNombre(\"Tom\");\n\t\tgato.setRaza(\"Persa\");\n\t\tgato.maulla();\n\n\t\tSystem.out.println(gato.getNombre() + \" - \" + gato.getRaza() + \" - \" + gato.maulla());\n\n\t\tSystem.out.println(\"\\n\");\n\n\t\t// Instancio la clase Gerente\n\t\t// Gerente gerente = new Gerente(null, null, null);\n\t\tArrayList<Gerente> gerentes = new ArrayList<>();\n\t\tgerentes.add(new Gerente(1L, \"Andres\", \"Desarrollo\"));\n\t\tgerentes.add(new Gerente(2L, \"Laura\", \"Diseño Gráfico\"));\n\t\tgerentes.add(new Gerente(3L, \"Luis\", \"Contabilidad\"));\n\t\tGerente.listarGerentes(gerentes);\n\n\t\tArrayList<GerenteDeProyecto> gerentePro = new ArrayList<>();\n\t\tgerentePro.add(new GerenteDeProyecto(1L, \"Diego\", \"Curso Java Web\"));\n\t\tgerentePro.add(new GerenteDeProyecto(2L, \"Ana\", \"Diseño de interfeces de usuario\"));\n\t\tgerentePro.add(new GerenteDeProyecto(3L, \"Sara\", \"Automatización Nómina\"));\n\t\tGerenteDeProyecto.listarGerentesProyecto(gerentePro);\n\n\t\tArrayList<Programador> programadorer = new ArrayList<>();\n\t\tprogramadorer.add(new Programador(1L, \"Julio Cesar\", \"Roma\"));\n\t\tprogramadorer.add(new Programador(2L, \"Alejandro\",\"Grecia\"));\n\t\tprogramadorer.add(new Programador(3L, \"Willian\", \"Escocia\"));\n\t\tProgramador.listarProgramadores(programadorer);\n\t}\n}\n\n//Se crea la superclase Animal\nclass Animal {\n\tprivate String nombre;\n\tprivate String raza;\n\n\tpublic Animal(String nombre, String raza) {\n\t\tsuper();\n\t\tthis.nombre = nombre;\n\t\tthis.raza = raza;\n\t}\n\n\tpublic String getNombre() {\n\t\treturn nombre;\n\t}\n\n\tpublic void setNombre(String nombre) {\n\t\tthis.nombre = nombre;\n\t}\n\n\tpublic String getRaza() {\n\t\treturn raza;\n\t}\n\n\tpublic void setRaza(String raza) {\n\t\tthis.raza = raza;\n\t}\n}\n\n//Se crea la clase perro que hereda de la Clase Animal\nclass Perro extends Animal {\n\n\tpublic Perro(String nombre, String raza) {\n\t\tsuper(nombre, raza);\n\t}\n\n\tpublic String ladra() {\n\t\treturn \"guau, guau\";\n\t}\n}\n\n//Se crea la clase Gato que hereda de la Clase Animal\nclass Gato extends Animal {\n\tpublic Gato(String nombre, String raza) {\n\t\tsuper(nombre, raza);\n\t}\n\n\tpublic String maulla() {\n\t\treturn \"miau, miau\";\n\t}\n}\n\n//DIFICULTAD EXTRA\n\nclass Empleado {\n\tprivate Long idEmpleado;\n\tprivate String nombre;\n\n\tpublic Empleado(Long idEmpleado, String nombre) {\n\t\tsuper();\n\t\tthis.idEmpleado = idEmpleado;\n\t\tthis.nombre = nombre;\n\t}\n\n\tpublic Long getIdEmpleado() {\n\t\treturn idEmpleado;\n\t}\n\n\tpublic void setIdEmpleado(Long idEmpleado) {\n\t\tthis.idEmpleado = idEmpleado;\n\t}\n\n\tpublic String getNombre() {\n\t\treturn nombre;\n\t}\n\n\tpublic void setNombre(String nombre) {\n\t\tthis.nombre = nombre;\n\t}\n}\n\nclass Gerente extends Empleado {\n\tString area;\n\n\tpublic Gerente(Long idEmpleado, String nombre, String area) {\n\t\tsuper(idEmpleado, nombre);\n\t\tthis.area = area;\n\t}\n\n\tpublic String getArea() {\n\t\treturn area;\n\t}\n\n\tpublic void setArea(String area) {\n\t\tthis.area = area;\n\t}\n\n\tpublic static void listarGerentes(ArrayList<Gerente> gerentes) {\n\t\tSystem.out.println(\"\\nLISTA DE GERENTES DE LA EMPRESA\");\n\t\tfor (int i = 0; i < gerentes.size(); i++) {\n\t\t\tSystem.out.println(\"Área: \" + gerentes.get(i).getArea() + \" | Gerente: \" + gerentes.get(i).getNombre());\n\t\t}\n\t}\n\t\n\tpublic static void contratarEmpleados() {\n\t\tSystem.out.println(\"Vas a contratar un nuevo empleado\");\n\t}\n\t\n\tpublic static void nuevoProyecto() {\n\t\tSystem.out.println(\"Creando nuevo proyecto\");\n\t}\n}\n\nclass GerenteDeProyecto extends Empleado {\n\tString proyecto;\n\n\tpublic GerenteDeProyecto(Long idEmpleado, String nombre, String proyecto) {\n\t\tsuper(idEmpleado, nombre);\n\t\tthis.proyecto = proyecto;\n\t}\n\n\tpublic String getProyecto() {\n\t\treturn proyecto;\n\t}\n\n\tpublic void setProyecto(String proyecto) {\n\t\tthis.proyecto = proyecto;\n\t}\n\n\tpublic static void listarGerentesProyecto(ArrayList<GerenteDeProyecto> gerentePro) {\n\t\tSystem.out.println(\"\\nLISTA DE GERENTES DE PROYECTOS\");\n\t\tfor (int i = 0; i < gerentePro.size(); i++) {\n\t\t\tSystem.out.println(\n\t\t\t\t\t\"Proyecto: \" + gerentePro.get(i).getProyecto() + \" | Gerente: \" + gerentePro.get(i).getNombre());\n\t\t}\n\t}\n\t\n\tpublic static void asignarDesarrollador() {\n\t\tSystem.out.println(\"Asignando nuevo desarrollador al equipo y proyecto\");\n\t}\n}\n\nclass Programador extends Empleado {\n\tString equipoDeTrabajo;\n\n\tpublic Programador(Long idEmpleado, String nombre, String equipoDeTrabajo) {\n\t\tsuper(idEmpleado, nombre);\n\t\tthis.equipoDeTrabajo = equipoDeTrabajo;\n\t}\n\n\tpublic String getEquipoDeTrabajo() {\n\t\treturn equipoDeTrabajo;\n\t}\n\n\tpublic void setEquipoDeTrabajo(String equipoDeTrabajo) {\n\t\tthis.equipoDeTrabajo = equipoDeTrabajo;\n\t}\n\n\tpublic static void listarProgramadores(ArrayList<Programador> programadores) {\n\t\tSystem.out.println(\"\\nLISTA DE PROGRAMADORES\");\n\t\tfor (int i = 0; i < programadores.size(); i++) {\n\t\t\tSystem.out.println(\"Equipo de trabajo: \" + programadores.get(i).getEquipoDeTrabajo() + \" | Programador: \"\n\t\t\t\t\t+ programadores.get(i).getNombre());\n\t\t}\n\t}\n\t\n\tpublic static void desarrollarAplicacion() {\n\t\tSystem.out.println(\"Iniciando el desarrollo de la app para el equipo\");\n\t}\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/java/FranDev200.java",
    "content": "import java.util.ArrayList;\n\npublic class FranDev200 {\n\n    static void main() {\n\n        /*\n            EJERCICIO:\n            * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n            * implemente una superclase Animal y un par de subclases Perro y Gato,\n            * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n         */\n\n        ArrayList<Animal> animales = new ArrayList<>();\n        animales.add(new Gato(\"Hipatia\"));\n        animales.add(new Perro(\"Rubi\"));\n        animales.add(new Gato(\"Cleo\"));\n        animales.add(new Perro(\"Indi\"));\n        animales.add(new Perro(\"Mark\"));\n\n        for(Animal a : animales){\n\n            System.out.print(a.getNombre() + \" hace \");\n            a.getSonido();\n\n        }\n\n\n        // EJERCICIO EXTRA\n\n        ArrayList<Empleado>  empleados = new ArrayList<>();\n\n        Gerente g1 = new Gerente( 1, \"Laura Gomez\", 45, \"Tecnología\", 150000.00 );\n        Gerente g2 = new Gerente( 2, \"Carlos Diaz\", 50, \"Operaciones\", 200000.00 );\n\n        GerenteProyecto gp1 = new GerenteProyecto(3, \"Mario Ruiz\", 38, \"Proyecto Atlas\", \"2026-06-30\");\n        GerenteProyecto gp2 = new GerenteProyecto(4, \"Ana Torres\", 35, \"Proyecto Orion\", \"2026-09-15\");\n        GerenteProyecto gp3 = new GerenteProyecto(5, \"Sergio Lopez\", 40, \"Proyecto Nova\", \"2027-01-20\");\n\n        Programador p1 = new Programador(6, \"Ana Torres\", 27, \"Java\", \"Junior\");\n        Programador p2 = new Programador(7, \"Sergio Lopez\", 30, \"Kotlin\", \"Mid\");\n        Programador p3 = new Programador(8, \"Lucia Perez\", 32, \"C#\", \"Senior\");\n        Programador p4 = new Programador(9, \"David Hernandez\", 35, \"Python\", \"Senior\");\n        Programador p5 = new Programador(10, \"Elena Navarro\", 26, \"JavaScript\", \"Junior\");\n        Programador p6 = new Programador(11, \"Carlos Diaz\", 38, \"TypeScript\", \"Senior\");\n        Programador p7 = new Programador(12, \"Mario Ruiz\", 33, \"SQL\", \"Mid\");\n        Programador p8 = new Programador(13, \"Raquel Gomez\", 29, \"Go\", \"Mid\");\n\n        g1.aniadirEmpleado(gp1);\n        g1.aniadirEmpleado(gp2);\n        g1.aniadirEmpleado(p1);\n        g1.aniadirEmpleado(p2);\n\n        g2.aniadirEmpleado(gp3);\n        g2.aniadirEmpleado(p3);\n\n        gp1.aniadirProgramador(p4);\n        gp2.aniadirProgramador(p5);\n        gp2.aniadirProgramador(p6);\n        gp3.aniadirProgramador(p7);\n        gp3.aniadirProgramador(p8);\n\n        empleados.add(g1);\n        empleados.add(g2);\n        empleados.add(gp1);\n        empleados.add(gp2);\n        empleados.add(gp3);\n        empleados.add(p1);\n        empleados.add(p2);\n        empleados.add(p3);\n        empleados.add(p4);\n        empleados.add(p5);\n        empleados.add(p6);\n        empleados.add(p7);\n        empleados.add(p8);\n\n        System.out.println(\"\\n\\nINFORMACION DE LOS EMPLEADOS DE LA EMPRESA.\");\n        System.out.println(\"===========================================\");\n\n        for (Empleado empleado :  empleados) {\n\n            empleado.infoEmpleado();\n\n        };\n\n        System.out.println(\"\\n\\nEMPLEADOS ASIGANDOS A \" + g1.getNombre());\n        g1.infoEmpleadosASuCargo();\n\n        System.out.println(\"\\n\\nEMPLEADOS ASIGANDOS A \" + gp3.getNombre());\n        gp3.infoProgramadoresASuCargo();\n\n        g2.reunirseConDirectivos();\n        gp2.planificarSprint();\n        gp3.planificarSprint();\n\n        p2.programando();\n        p6.programando();\n        p1.programando();\n        p8.programando();\n    }\n\n    static abstract class Animal {\n        private String nombre;\n\n        public Animal() { }\n\n        public Animal(String nombre) {\n\n            setNombre(nombre);\n\n\n        }\n\n        public String getNombre() { return nombre; }\n\n        public void setNombre(String nombre) { this.nombre = nombre; }\n\n        public void getSonido() {\n            System.out.println(\"\");\n        }\n\n    }\n\n    static class Gato extends Animal {\n\n        public Gato(String name) {\n            super(name);\n        }\n\n        @Override\n        public void getSonido() {\n            System.out.println(\"MIAU MIAU\");\n        }\n    }\n\n    static class Perro extends Animal {\n\n        public Perro(String name) {\n            super(name);\n        }\n\n        @Override\n        public void getSonido() {\n            System.out.println(\"GUAU GUAU\");\n        }\n    }\n\n    /*\n\n        DIFICULTAD EXTRA (opcional):\n        * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n        * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n        * Cada empleado tiene un identificador y un nombre.\n        * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n        * actividad, y almacenan los empleados a su cargo.\n\n     */\n\n    static abstract class Empleado{\n\n        private int id;\n        private String nombre;\n        private int edad;\n\n        public Empleado() { }\n        public Empleado(int id, String nombre, int edad) {\n\n            this.id = id;\n            this.nombre = nombre;\n            this.edad = edad;\n\n        }\n\n        public int getId() { return id; }\n\n        public void setId(int id) { this.id = id; }\n\n        public String getNombre() { return nombre; }\n\n        public void setNombre(String nombre) { this.nombre = nombre; }\n\n        public int getEdad() { return edad; }\n\n        public void setEdad(int edad) { this.edad = edad; }\n\n        public void infoEmpleado(){}\n    }\n    static class Gerente extends Empleado{\n\n        private String departamento;\n        private double presupuesto;\n        private ArrayList<Empleado> empleadosACargo = new ArrayList<>();\n\n        public Gerente() {\n            super();\n        }\n\n        public Gerente(int id, String nombre, int edad, String departamento,  double presupuesto) {\n            super(id, nombre, edad);\n            this.departamento = departamento;\n            this.presupuesto = presupuesto;\n        }\n\n        public String getDepartamento() { return departamento; }\n\n        public void setDepartamento(String departamento) { this.departamento = departamento; }\n\n        public double getPresupuesto() { return presupuesto; }\n\n        public void setPresupuesto(double presupuesto) { this.presupuesto = presupuesto; }\n\n        public void aniadirEmpleado(Empleado empleado) {\n            empleadosACargo.add(empleado);\n        }\n\n        public void reunirseConDirectivos(){\n            System.out.println(getNombre() + \" se está reuniendo con los directivos.\");\n        }\n\n        @Override\n        public void infoEmpleado(){\n            System.out.println(getNombre() + \"[\" +getId() + \"]: \" + getEdad() + \" años.\");\n            System.out.println(\"-----------------\");\n            System.out.println(\"Gerente del departamento de \" +  getDepartamento());\n            System.out.println(\"Su presupuesto asignado para el proyecto es: \" + getPresupuesto());\n            System.out.println(\"=================\");\n        }\n\n        public void infoEmpleadosASuCargo(){\n            for(Empleado empleado : empleadosACargo){\n\n                empleado.infoEmpleado();\n\n            }\n        }\n    }\n    static class GerenteProyecto extends Empleado{\n\n        private String proyectoAsignado;\n        private String fechaEntrega;\n        private ArrayList<Programador> programadoresACargo = new ArrayList<>();\n\n        public GerenteProyecto() {\n            super();\n        }\n\n        public GerenteProyecto(int id, String nombre, int edad, String departamento, String fechaEntrega) {\n            super(id, nombre, edad);\n            this.proyectoAsignado = departamento;\n            this.fechaEntrega = fechaEntrega;\n        }\n\n        public String getProyectoAsignado() { return proyectoAsignado; }\n\n        public void setProyectoAsignado(String proyectoAsignado) { this.proyectoAsignado = proyectoAsignado; }\n\n        public String getFechaEntrega() { return fechaEntrega; }\n\n        public void setFechaEntrega(String fechaEntrega) { this.fechaEntrega = fechaEntrega; }\n\n        public void aniadirProgramador(Programador programador) {\n            programadoresACargo.add(programador);\n        }\n\n        public void planificarSprint(){\n            System.out.println(getNombre() + \" ha planificado una sprint para hablar sobre el \" +\n                    \"de \" + getProyectoAsignado() + \". Su fecha de entrega es el \" + getFechaEntrega());\n        }\n\n        @Override\n        public void infoEmpleado(){\n            System.out.println(getNombre() + \"[\" +getId() + \"]: \" + getEdad() + \" años.\");\n            System.out.println(\"-----------------\");\n            System.out.println(\"Gerente del \" +  getProyectoAsignado());\n            System.out.println(\"La fecha máxima de entrega es el: \" +  getFechaEntrega());\n            System.out.println(\"=================\");\n        }\n\n        public void infoProgramadoresASuCargo(){\n            for(Programador programador : programadoresACargo){\n\n                programador.infoEmpleado();\n\n            }\n        }\n\n    }\n    static class Programador extends Empleado{\n\n        private String lenguajePrincipal;\n        private String nivel;\n\n        public Programador() { }\n\n        public Programador(int id, String nombre, int edad, String lenguajePrincipal, String nivel) {\n            super(id, nombre, edad);\n            this.lenguajePrincipal = lenguajePrincipal;\n            this.nivel = nivel;\n        }\n\n        public String getLenguajePrincipal() { return lenguajePrincipal; }\n\n        public void setLenguajePrincipal(String lenguajePrincipal) { this.lenguajePrincipal = lenguajePrincipal; }\n\n        public String getNivel() { return nivel; }\n\n        public void setNivel(String nivel) { this.nivel = nivel; }\n\n        public void programando(){\n\n            System.out.println(getNombre() + \" esta desarrollando una nueva funcionalidad para el proyecto.\");\n\n        }\n\n        @Override\n        public void infoEmpleado(){\n            System.out.println(getNombre() + \"[\" +getId() + \"]: \" + getEdad() + \" años.\");\n            System.out.println(\"-----------------\");\n            System.out.println(\"Programador \" +  getNivel());\n            System.out.println(\"Su lenguaje principal es \" +  getLenguajePrincipal());\n            System.out.println(\"=================\");\n        }\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/java/GlossyPath.java",
    "content": "/*\r\n * EJERCICIO:\r\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\r\n * implemente una superclase Animal y un par de subclases Perro y Gato,\r\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\r\n *\r\n * DIFICULTAD EXTRA (opcional):\r\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\r\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\r\n * Cada empleado tiene un identificador y un nombre.\r\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\r\n * actividad, y almacenan los empleados a su cargo.\r\n * \r\n * @version v1.0\r\n * \r\n * @since 09/09/2024\r\n * \r\n * @author GlossyPath\r\n */\r\n\r\n import java.util.ArrayList;\r\nimport java.util.Arrays;\r\nimport java.util.List;\r\nimport java.util.Scanner;\r\n\r\npublic class GlossyPath {\r\n    public static void main(String[] args) throws Exception {\r\n\r\n        Gato cat = new Gato();\r\n        Perro dog = new Perro();\r\n\r\n        cat.sonidoAnimal();\r\n        dog.sonidoAnimal();\r\n        \r\n        System.out.println();\r\n\r\n        Gerentes gerentePaco = new Gerentes(\"Paco\", \"Gerente\");\r\n\r\n        GerentesProyecto gerenteProyectoAna = new GerentesProyecto(\"Ana\", \"Gerente de proyecto\");\r\n\r\n        gerenteProyectoAna.setProyecto(\"Valerian\");\r\n\r\n        GerentesProyecto.Programador claraProgramadora = gerenteProyectoAna.new Programador(\"Clara\", \"Programador\", gerenteProyectoAna);\r\n\r\n        gerentePaco.añadirGerentesProyecto(gerenteProyectoAna);\r\n        \r\n        gerenteProyectoAna.añadirProgramador(claraProgramadora);\r\n        System.out.println();\r\n\r\n        System.out.println(gerentePaco);\r\n        System.out.println();\r\n\r\n        System.out.println(gerenteProyectoAna);\r\n        System.out.println();\r\n\r\n        System.out.println(claraProgramadora);\r\n\r\n    }\r\n}\r\n\r\n abstract class Animal {\r\n\r\n    public abstract void sonidoAnimal();\r\n}\r\n\r\n\r\nclass Perro extends  Animal {\r\n\r\n    @Override\r\n    public void sonidoAnimal() {\r\n        System.out.println(\"El perro hace GUAU\");\r\n    }\r\n}\r\n\r\n\r\nclass Gato extends Animal {\r\n\r\n    @Override\r\n    public void sonidoAnimal() {\r\n        System.out.println(\"El gato hace MIAUUU\");\r\n    }  \r\n}\r\n\r\n\r\nabstract class Empleados {\r\n\r\n    private String identificador;\r\n    private String nombre;\r\n    private String puesto;\r\n\r\n    public Empleados (String nombre, String categoria){\r\n        this.nombre = nombre;\r\n        this.puesto = categoriaTrabajador(categoria);\r\n        this.identificador = indentificadorAleatorio();\r\n    }\r\n\r\n    private String categoriaTrabajador(String categoria) throws IllegalArgumentException {\r\n\r\n        String[] categorias = {\"gerente\", \"gerente de proyecto\", \"programador\"};\r\n\r\n        boolean correcto = Arrays.stream(categorias).anyMatch(c -> c.equalsIgnoreCase(categoria));\r\n\r\n        if(correcto) {\r\n            return categoria;\r\n\r\n        } else {\r\n            throw new IllegalArgumentException (\"Categoria no valida\");\r\n        }\r\n    }\r\n\r\n\r\n    private String indentificadorAleatorio () {\r\n\r\n        StringBuilder id = new StringBuilder();\r\n        char[] letras = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'};\r\n\r\n        for(int i=0; i<5; i++){\r\n            String numsAle = String.valueOf((int) (Math.random()*10));\r\n            id.append(numsAle);\r\n        }\r\n\r\n        for(int i=0; i<5; i++){\r\n            int indice  = (int) (Math.random()*letras.length);\r\n            id.append(letras[indice]);\r\n        }\r\n\r\n        return id.toString();\r\n    }\r\n\r\n    public String getPuesto(){\r\n        return this.puesto;\r\n    }\r\n\r\n    public String getIdentificador() {\r\n        return identificador;\r\n    }\r\n\r\n    public void setIdentificador(String identificador) {\r\n        this.identificador = identificador;\r\n    }\r\n\r\n    public String getNombre() {\r\n        return nombre;\r\n    }\r\n\r\n    public void setNombre(String nombre) {\r\n        this.nombre = nombre;\r\n    }\r\n\r\n    @Override\r\n    public String toString() {\r\n\r\n        return \"Empleado: \" + getNombre() + \"\\n\" +\r\n        \"Puesto de trabajo: \" + getPuesto() + \"\\n\" +\r\n        \"Identificador: \" + getIdentificador();\r\n    }\r\n}\r\n\r\n\r\n\r\nclass Gerentes extends Empleados {\r\n\r\n    private List<GerentesProyecto> gerentesProyecto;\r\n\r\n    private final Scanner SC = new Scanner(\"System.in\");\r\n\r\n    public Gerentes(String nombre, String categoria) {\r\n        super(nombre, categoria);\r\n\r\n        this.gerentesProyecto = new ArrayList<>();\r\n    }\r\n\r\n    public void añadirGerentesProyecto(GerentesProyecto gerenteAñadir) {\r\n\r\n      boolean existe = gerentesProyecto.stream().anyMatch(gp -> gp.getNombre().equals(gerenteAñadir.getNombre()));\r\n       \r\n      if(!existe){\r\n        gerentesProyecto.add(gerenteAñadir);\r\n        System.out.println(\"El gerente de proyecto \" + gerenteAñadir.getNombre() + \" ha sido añadido correctamente.\");\r\n\r\n      } else {\r\n        System.out.println(\"El gerente de proyectos ya esta en la lista\");\r\n        }\r\n    }\r\n\r\n    public void despedirGerenteProyecto() {\r\n\r\n        gerentesProyecto.stream().forEach(System.out::println);\r\n\r\n        System.out.println(\"Introduce el nombre del gerente de proyecto que quieres despedir\");\r\n        String nombre = SC.nextLine();\r\n\r\n        boolean existe = gerentesProyecto.stream().anyMatch(p -> p.getNombre().equals(nombre));\r\n\r\n        if(existe) { \r\n            gerentesProyecto.removeIf(p -> p.getNombre().equals(nombre));\r\n            System.out.println(\"El programador \" + nombre + \" ha sido despedido.\");\r\n\r\n        } else {\r\n            System.out.println(\"Ese programador no existe\");\r\n        }\r\n    }\r\n\r\n\r\n    public List<GerentesProyecto> getGerentesProyecto() {\r\n        return gerentesProyecto;\r\n    }\r\n\r\n    public void setGerentesProyecto(List<GerentesProyecto> gerentesProyecto) {\r\n        this.gerentesProyecto = gerentesProyecto;\r\n    }\r\n\r\n    @Override\r\n    public String toString(){\r\n        return super.toString() +\r\n        \"\\nGerentes de proyecto que gestiona: \" + gerentesProyecto.size();\r\n    }\r\n}\r\n\r\n\r\n\r\nclass GerentesProyecto extends Empleados {\r\n\r\n    private final Scanner SC = new Scanner(System.in);\r\n    String proyecto;\r\n    private List<Programador> programadores;\r\n\r\n    public GerentesProyecto(String nombre, String categoria) {\r\n        super(nombre, categoria);\r\n\r\n        this.programadores = new ArrayList<>();\r\n    }\r\n\r\n\r\n    public void añadirProgramador(Programador programador){\r\n\r\n        boolean existe = programadores.stream().anyMatch(p -> p.getNombre().equals(programador.getNombre()));\r\n\r\n        if(!existe) {\r\n            this.programadores.add(programador);\r\n\r\n        } else {\r\n            System.out.println(\"El nombre del programador ya existe\");\r\n        }\r\n    }\r\n\r\n    public void despedirProgramador() {\r\n\r\n        programadores.stream().forEach(System.out::println);\r\n\r\n        System.out.println(\"Introduce el nombre del programador que quieres despedir\");\r\n        String nombre = SC.nextLine();\r\n\r\n        boolean existe = programadores.stream().anyMatch(p -> p.getNombre().equals(nombre));\r\n\r\n        if(existe) { \r\n            programadores.removeIf(p -> p.getNombre().equals(nombre));\r\n            System.out.println(\"El programador \" + nombre + \" ha sido despedido.\");\r\n\r\n\r\n        } else {\r\n            System.out.println(\"Ese programador no existe\");\r\n        }\r\n    }\r\n\r\n\r\n    public List<Programador> getProgramadores() {\r\n        return programadores;\r\n    }\r\n\r\n\r\n    public void setProgramadores(List<Programador> programadores) {\r\n        this.programadores = programadores;\r\n    }\r\n\r\n\r\n    public String getProyecto() {\r\n        return proyecto;\r\n    }\r\n\r\n\r\n    public void setProyecto(String proyecto) {\r\n        this.proyecto = proyecto;\r\n    }\r\n\r\n    @Override\r\n    public String toString(){\r\n        return super.toString() +\r\n        \"\\nProgramadores que gestiona: \" + programadores.size() +\r\n        \"\\nProyecto en el que esta involucrado: \" + proyecto;\r\n    }\r\n\r\n    class Programador extends Empleados {\r\n\r\n        GerentesProyecto gerenteJefe;\r\n\r\n        public Programador(String nombre, String puesto, GerentesProyecto gerenteProyecto) {\r\n            super(nombre, puesto);\r\n\r\n            this.gerenteJefe = gerenteProyecto;\r\n\r\n        }\r\n\r\n        @Override\r\n        public String toString() {\r\n            return super.toString() +\r\n            \"\\nSu jefe es: \" + gerenteJefe.getNombre();\r\n        }\r\n    \r\n    }\r\n\r\n}\r\n\r\n\r\n\r\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/java/GustavoGomez19.java",
    "content": "import java.util.ArrayList;\nimport java.util.List;\n\n\npublic class GustavoGomez19 {\n\n    /*\n     * EJERCICIO:\n     * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n     * implemente una superclase Animal y un par de subclases Perro y Gato,\n     * junto con una función que sirva para imprimir el sonido que emite cada\n     * Animal.\n     */\n    public static void main(String[] args) {\n\n        Perro p1 = new Perro(\"Roko\");\n        p1.sonido();\n        Gato g1 = new Gato(\"Gael\");\n        g1.sonido();\n\n        // Ejercicio extra\n        Gerente gerente = new Gerente(1, \"Gustavo\");\n        gerente.coordinarProyectos();\n\n        GerenteProyecto gerenteProyecto1 = new GerenteProyecto(2, \"Katerine\", \"Proyecto 1\");\n        GerenteProyecto gerenteProyecto2 = new GerenteProyecto(3, \"Javier\", \"Proyecto 2\");\n        gerenteProyecto1.coordinarProyecto();\n        gerenteProyecto2.coordinarProyecto();\n\n        Programador programador1 = new Programador(4, \"María José\", \"Java\");\n        Programador programador2 = new Programador(5, \"Adolfo\", \"JavaScript\");\n        Programador programador3 = new Programador(6, \"Johnny\", \"Pytho\");\n        Programador programador4 = new Programador(7, \"Joan\", \"Ruby\");\n\n        programador1.codificar();\n        programador2.codificar();\n        programador3.codificar();\n        programador4.codificar();\n\n        gerente.agregarEmpleado(gerenteProyecto1);\n        gerente.agregarEmpleado(gerenteProyecto2);\n\n        gerenteProyecto1.agregarEmpleado(programador1);\n        gerenteProyecto1.agregarEmpleado(programador4);\n        gerenteProyecto2.agregarEmpleado(programador2);\n        gerenteProyecto2.agregarEmpleado(programador3);\n\n        gerente.listarEmpleados();\n        gerenteProyecto1.listarEmpleados();\n        programador1.agregarEmpleado(programador4);\n    }\n\n    static class Animal {\n        String nombre;\n\n        public Animal(String nombre) {\n            this.nombre = nombre;\n        }\n\n        public void sonido() {\n\n        }\n    }\n\n    static class Perro extends Animal {\n        public Perro(String nombre) {\n            super(nombre);\n        }\n\n        @Override\n        public void sonido() {\n            System.out.println(\"!Guau¡\");\n        }\n    }\n\n    static class Gato extends Animal {\n        public Gato(String nombre) {\n            super(nombre);\n        }\n\n        public void sonido() {\n            System.out.println(\"!Miau¡\");\n        }\n    }\n\n    // Ejercicio extra\n    /*\n     * Implementa la jerarquía de una empresa de desarrollo formada por Empleados\n     * que\n     * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n     * Cada empleado tiene un identificador y un nombre.\n     * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n     * actividad, y almacenan los empleados a su cargo.\n     */\n    /**\n     \n     */\n    static class Empleado{\n        int id;\n        String nombre;\n        List<Empleado> empleados;\n        \n\n        public Empleado(int id, String nombre){\n            this.id = id;\n            this.nombre = nombre;\n            this.empleados = new ArrayList<>();\n        }\n\n        public void agregarEmpleado(Empleado empleado){\n            this.empleados.add(empleado);\n        }\n\n        public void listarEmpleados(){\n            for (Empleado empleado : empleados) {\n                System.out.println(\"El empleado \" + empleado.nombre + \" está bajo el mando de \" + nombre);\n            }\n        }        \n    }\n\n    static class Gerente extends Empleado{\n        public Gerente(int id, String nombre){\n            super(id, nombre);\n        }\n        public void coordinarProyectos(){\n            System.out.println(this.nombre + \" está coordinando todos los proyectos de la empresa\");\n        }\n    }\n\n    static class GerenteProyecto extends Empleado{\n        String proyecto;\n        public GerenteProyecto(int id, String nombre, String proyecto){\n            super(id, nombre);\n            this.proyecto = proyecto;\n        }\n        public void coordinarProyecto(){\n            System.out.println(this.nombre + \" está coordinando su proyecto \" + this.proyecto);\n        }\n\n    }\n\n    static class Programador extends Empleado{\n        String lenguaje;\n        public Programador(int id, String nombre, String lenguaje){\n            super(id, nombre);\n            this.lenguaje = lenguaje;\n        }\n\n        public void codificar(){\n            System.out.println(this.nombre + \" etsá codificando la aplicación con el lenguaje \" + lenguaje + \".\");\n        } \n        \n        public void agregarEmpleado(Empleado empleado){\n            System.out.println(\"El programador \" + this.nombre + \" no puede tener personal a cargo.\");\n        }\n\n\n    }\n    \n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/java/Jeigar2.java",
    "content": "import java.util.ArrayList;\nimport java.util.List;\nimport java.util.Random;\n\npublic class Jeigar {\n    /*\n     * EJERCICIO:\n     * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n     * implemente una superclase Animal y un par de subclases Perro y Gato,\n     * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n     *\n     * DIFICULTAD EXTRA (opcional):\n     * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n     * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n     * Cada empleado tiene un identificador y un nombre.\n     * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n     * actividad, y almacenan los empleados a su cargo.\n     */\n\n    public static void main(String[] args) {\n        MiGato gato = new MiGato();\n        MiPerro perro = new MiPerro();\n        gato.sonido();\n        perro.sonido();\n\n        Programador p1 = new Programador(\"R2D2\", \"C\");\n        Programador p2 = new Programador(\"C3P0\", \"COBOL\");\n        Programador p3 = new Programador(\"Spok\", \"FORTRAN\");\n        Programador p4 = new Programador(\"Bender\", \"GO\");\n        Programador p5 = new Programador(\"WALL-E\", \"KOTRLIN\");\n        Programador p6 = new Programador(\"HAL 9000\", \"PYTHON\");\n        GerenteProyecto neo = new GerenteProyecto(\"Neo\", \"Sion\");\n        neo.setProyecto(\"Defender la base\");\n        neo.setPresupuesto(2000.00);\n        neo.contratarProgramador(p1);\n        neo.contratarProgramador(p2);\n        GerenteProyecto trinity = new GerenteProyecto(\"Trinity\", \"Matrix\");\n        trinity.setProyecto(\"Buscar a Morfeo\");\n        trinity.setPresupuesto(3000.00);\n        trinity.contratarProgramador(p3);\n        trinity.contratarProgramador(p4);\n        trinity.contratarProgramador(p5);\n\n        System.out.println(neo);\n        System.out.println(trinity);\n        System.out.println(p3);\n        trinity.liberarProgramador(p6);\n        trinity.liberarProgramador(p3);\n        System.out.println(p3);\n        System.out.println(p6);\n        if(!p6.isAsignado()){\n            System.out.println(\"Puedes dar formación al Empleado: \" + p6.getNombre());\n        }\n    }\n}\n\nabstract class MiAnimal {\n    public MiAnimal(){\n        super();\n    }\n    public void sonido(){\n        System.out.print(\"Mi animalito hace un sonido :\");\n    }\n}\n\nclass MiGato extends MiAnimal{\n    @Override\n    public void sonido() {\n        super.sonido();\n        System.out.println(\"¡Miau!\");\n    }\n}\n\nclass MiPerro extends MiAnimal{\n    @Override\n    public void sonido() {\n        super.sonido();\n        System.out.println(\"¡Guau!\");\n    }\n}\n\nabstract class Empleado {\n    private long identificador;\n    private String nombre;\n    private String departamento;\n\n    public Empleado(String nombre) {\n        this.nombre = nombre;\n        this.identificador = Math.abs(new Random().nextLong());\n    }\n\n    public long getIdentificador() {\n        return identificador;\n    }\n\n    public void setIdentificador(long identificador) {\n        this.identificador = identificador;\n    }\n\n    public String getDepartamento() {\n        return departamento;\n    }\n\n    public void setDepartamento(String departamento) {\n        this.departamento = departamento;\n    }\n\n    public String getNombre() {\n        return nombre;\n    }\n\n    public void setNombre(String nombre) {\n        this.nombre = nombre;\n    }\n\n    @Override\n    public String toString() {\n        return \"Empleado{\" +\n                \"identificador=\" + identificador +\n                \", nombre='\" + nombre + '\\'' +\n                \", departamento='\" + departamento + '\\'' +\n                '}';\n    }\n}\n\nclass Programador extends Empleado {\n    private String lenguaje;\n    private boolean asignado;\n\n    public Programador(String nombre) {\n        super(nombre);\n    }\n    public Programador(String nombre, String lenguaje) {\n        super(nombre);\n        this.lenguaje = lenguaje;\n    }\n\n    public String getLenguaje() {\n        return lenguaje;\n    }\n\n    public void setLenguaje(String lenguaje) {\n        this.lenguaje = lenguaje;\n    }\n\n    public boolean isAsignado() {\n        return asignado;\n    }\n\n    public void asignar() {\n        this.asignado = true;\n    }\n    public void liberar() {\n        this.asignado = false;\n    }\n\n    @Override\n    public String toString() {\n        return \"Programador{\" + super.toString() +\n                \", lenguaje='\" + lenguaje + '\\'' +\n                \", asignado=\" + asignado +\n                '}';\n    }\n}\n\nabstract class Gerente extends Empleado {\n\n    private double presupuesto;\n\n    public Gerente(String nombre) {\n        super(nombre);\n    }\n\n    public double getPresupuesto() {\n        return presupuesto;\n    }\n\n    public void setPresupuesto(double presupuesto) {\n        this.presupuesto = presupuesto;\n    }\n\n    @Override\n    public String toString() {\n        return super.toString() + \", presupuesto=\" + presupuesto;\n    }\n}\n\nclass GerenteProyecto extends Gerente {\n\n    private String proyecto;\n    private List<Programador> programadores;\n\n\n    public GerenteProyecto(String nombre, String departamento) {\n        super(nombre);\n        super.setDepartamento(departamento);\n        programadores = new ArrayList<>();\n    }\n\n    public void contratarProgramador(Programador programador){\n        if (!programadores.contains(programador)){\n            programadores.add(programador);\n            programador.asignar();\n            programador.setDepartamento(getDepartamento());\n        }\n    }\n\n    public Programador liberarProgramador (Programador programador){\n        if(programadores.contains(programador)){\n            programadores.remove(programador);\n            programador.liberar();\n            programador.setDepartamento(null);\n            return programador;\n        } else {\n            System.out.println(programador.getIdentificador() + \" \" + programador.getNombre() + \" No está contratado por ti\");\n            return null;\n        }\n    }\n\n    public String getProyecto() {\n        return proyecto;\n    }\n\n    public void setProyecto(String proyecto) {\n        this.proyecto = proyecto;\n    }\n\n    @Override\n    public String toString() {\n        return \"GerenteProyecto{\" + super.toString() +\n                \", proyecto='\" + proyecto + '\\'' +\n                \", programadores (\" + programadores.size() + \")=\" + programadores +\n                '}';\n    }\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/java/JesusAntonioEEscamilla.java",
    "content": "import java.util.UUID;\nimport java.util.ArrayList;\nimport java.util.List;\n\n/** #09 - Java -> Jesus Antonio Escamilla */\n\npublic class JesusAntonioEEscamilla {\n    public static void main(String[] args) {\n    //---EJERCIÓ---\n        Animal perro = new Perro();\n        Animal gato = new Gato();\n        Animal pajaro = new Pajaro();\n\n        System.out.println(\"Herencia\");\n        imprimirSonido(perro);\n        imprimirSonido(gato);\n        imprimirSonido(pajaro);\n\n        System.out.println(\"\\n\");\n\n        System.out.println(\"Extra Métodos\");\n        // Extra: Mostrar acciones adicionales\n        ((Perro) perro).correr();\n        ((Gato) gato).cazar();\n        ((Pajaro) pajaro).volar();\n    //---EXTRA---\n        System.out.println(\"\\n\");\n        // Crear Gerente\n        Manager gerente = new Manager(\"Jesus\");\n\n        // Crear Gerente de Proyecto\n        ProjectManager gerenteProyecto1 = new ProjectManager(\"Antonio\", \"Proyecto1\");\n        ProjectManager gerenteProyecto2 = new ProjectManager(\"Faty\", \"Proyecto2\");\n\n        // Crear Programadores\n        Programmer programmer1 = new Programmer(\"Adolfo\", \"Python\");\n        Programmer programmer2 = new Programmer(\"Naty\", \"C#\");\n        Programmer programmer3 = new Programmer(\"Ruben\", \"Kotlin\");\n        Programmer programmer4 = new Programmer(\"Axel\", \"JavaScript\");\n\n        // Agregar empleados a cargo del gerente\n        gerente.agregarEmpleado(gerenteProyecto1);\n        gerente.agregarEmpleado(gerenteProyecto2);\n        gerente.agregarEmpleado(programmer1);\n        gerente.agregarEmpleado(programmer2);\n        gerente.agregarEmpleado(programmer3);\n        gerente.agregarEmpleado(programmer4);\n\n        // Mostrar detalle de los empleados\n        gerente.showDetails();\n        gerenteProyecto1.showDetails();\n        gerenteProyecto2.showDetails();\n        programmer1.showDetails();\n        programmer2.showDetails();\n        programmer3.showDetails();\n        programmer4.showDetails();\n    }\n\n    //---EJERCIÓ---\n    // Superclase Animal\n    static class Animal {\n        public void hacerSonido(){\n            System.out.println(\"El animal hace ruido\");\n        }\n    }\n\n    // Subclases Perro\n    static class Perro extends Animal {\n        @Override\n        public void hacerSonido(){\n            System.out.println(\"El perro ladra: ¡Guau Guau!\");\n        }\n\n        // Método adicional para perro\n        public void correr(){\n            System.out.println(\"Esta corriendo felizmente\");\n        }\n    }\n\n    // Subclases Gato\n    static class Gato extends Animal {\n        @Override\n        public void hacerSonido(){\n            System.out.println(\"El gato maúlla: ¡Miau Miau!\");\n        }\n\n        // Método adicional para gato\n        public void cazar(){\n            System.out.println(\"Esta cazando un ratón\");\n        }\n    }\n\n    // Nueva Subclases Pájaro\n    static class Pajaro extends Animal {\n        @Override\n        public void hacerSonido(){\n            System.out.println(\"El pájaro canta: ¡Pio Pio!\");\n        }\n\n        // Método adicional para gato\n        public void volar(){\n            System.out.println(\"Esta volando alto en el cielo\");\n        }\n    }\n\n    // Función que recibe un objeto de tipo Animal y llama a su método hacerSonido\n    public static void imprimirSonido(Animal animal){\n        animal.hacerSonido();\n    }\n\n\n\n    /**-----DIFICULTAD EXTRA-----*/\n\n\n    // Clase empleado\n    public static abstract class Employ {\n        private String id;\n        private String nombre;\n\n        // Constructor\n        public Employ(String nombre){\n            this.id = generarIdentificador();\n            this.nombre = nombre;\n        }\n\n        // Método para generar un identificador único\n        private String generarIdentificador() {\n            return UUID.randomUUID().toString();\n        }\n\n        public String getId(){\n            return id;\n        }\n\n        public String getNombre(){\n            return nombre;\n        }\n\n        // Método abstracto que debe ser implementado por las subclases\n        public abstract void showDetails();\n    }\n\n    // Clase Gerente\n    public static class Manager extends Employ {\n        private List<Employ> empleadosACargo;\n\n        // Constructor\n        public Manager(String nombre){\n            super(nombre);\n            this.empleadosACargo = new ArrayList<>();\n        }\n\n        // Añadir empleados a cargo\n        public void agregarEmpleado(Employ empleado) {\n            empleadosACargo.add(empleado);\n        }\n\n        // Método especifico para mostrar los empleados a cargo\n        public void showEmployToPosition(){\n            System.out.println(\"\\nGerente: \" + getNombre() + \" tiene a cargo los siguientes empleados:\");\n            for (Employ e : empleadosACargo) {\n                System.out.println(\"- \" + e.getNombre());\n            }\n        }\n\n        @Override\n        public void showDetails() {\n            System.out.println(\"\\nGerente: \" + getNombre() + \" (ID: \" + getId() + \")\");\n            showEmployToPosition();\n        }\n    }\n\n    // Clase Gerente de Proyecto\n    public static class ProjectManager extends Employ {\n        private String currentProject;\n\n        // Constructor\n        public ProjectManager(String nombre, String currentProject){\n            super(nombre);\n            this.currentProject = currentProject;\n        }\n\n        // Método específico para mostrar el proyecto actual\n        public void showProject() {\n            System.out.println(\"\\nGerente de Proyecto: \" + getNombre() + \" está gestionando el proyecto: \" + currentProject);\n        }\n\n        @Override\n        public void showDetails() {\n            System.out.println(\"\\nGerente de Proyecto: \" + getNombre() + \" (ID: \" + getId() + \")\");\n            showProject();\n        }\n    }\n\n    // Clase Programador\n    public static class Programmer extends Employ {\n        private String lenguajeDominante;\n\n        // Constructor\n        public Programmer(String nombre, String lenguajeDominante){\n            super(nombre);\n            this.lenguajeDominante = lenguajeDominante;\n        }\n\n        // Método específico para mostrar el lenguaje dominante del programador\n        public void showLenguaje() {\n            System.out.println(\"\\nProgramador: \" + getNombre() + \" domina el lenguaje: \" + lenguajeDominante);\n        }\n\n        @Override\n        public void showDetails() {\n            System.out.println(\"\\nGerente: \" + getNombre() + \" (ID: \" + getId() + \")\");\n            showLenguaje();\n        }\n    }\n\n    /**-----DIFICULTAD EXTRA-----*/\n}"
  },
  {
    "path": "Roadmap/09 - HERENCIA/java/JesusWay69.java",
    "content": "package ejercicio09;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/*\n* EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n */\npublic class JesusWay69 {\n\n    public static void main(String[] args) {\n        Perro perro = new Perro();\n        Gato gato = new Gato();\n        Vaca vaca = new Vaca();\n        Gerente gerente = new Gerente();\n        GerenteProyectos gerenteproyectos = new GerenteProyectos();\n        Programador programador = new Programador();\n\n        perro.print(perro.animal, perro.sonido);\n        gato.print(gato.sonido, gato.animal);\n        vaca.print(vaca.sonido, vaca.animal);\n        System.out.println(\"\");\n\n        String[] nombres = {\"Carlos\", \"Ana\", \"Francisco\", \"Paula\", \"Felipe\", \"Ainhoa\", \"Jesus\", \"Raquel\", \"Álvaro\"};\n        List<String> empleadosGerencia = new ArrayList<>();\n        List<String> empleadosProyectos = new ArrayList<>();\n        for (int i = 1; i <= nombres.length; i++) {\n            if (i > 2 && i <= nombres.length) {\n                empleadosGerencia.add(nombres[i - 1]);\n            }\n            if (i > 5 && i <= nombres.length) {\n                empleadosProyectos.add(nombres[i - 1]);\n\n            }\n        }\n\n        for (int i = 1; i <= nombres.length; i++) {\n            if (i > 0 && i < 3) {\n                gerente.print(i, nombres[i - 1], gerente.cargo);\n                gerente.print(empleadosGerencia);\n            } else if (i > 2 && i < 6) {\n                gerenteproyectos.print(i, nombres[i - 1], gerenteproyectos.cargo);\n                gerenteproyectos.print(empleadosProyectos);\n\n            } else {\n                programador.print(i, nombres[i - 1], programador.cargo);\n\n            }\n\n        }\n\n    }\n\n}\n\nabstract class Animal {\n\n    public String animal;\n    public String sonido;\n    private String articulo;\n\n    public Animal() {\n\n        articulo = \"El\";\n    }\n\n    protected void print(String sonido, String animal) {\n        if (animal.charAt(animal.length() - 1) == 'a') {\n            articulo = \"La\";\n        }\n        System.out.println(articulo + \" \" + animal + \" \" + sonido);\n\n    }\n\n}\n\nclass Perro extends Animal {\n\n    public Perro() {\n        this.animal = \"perro\";\n        this.sonido = \"ladra\";\n    }\n\n    @Override\n    public void print(String sonido, String animal) {\n        super.print(\"ladra\", \"perro\");\n    }\n\n}\n\nclass Gato extends Animal {\n\n    public Gato() {\n        this.animal = \"gato\";\n        this.sonido = \"maulla\";\n    }\n}\n\nclass Vaca extends Animal {\n\n    public Vaca() {\n        this.animal = \"vaca\";\n        this.sonido = \"muge\";\n    }\n}\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\nabstract class Empleado {\n\n    public String finanzas = \"NO\";\n    public String compras = \"NO\";\n    public String proyectos = \"NO\";\n    public String organizacion = \"NO\";\n    public String programacion = \"NO\";\n    public String despliegue = \"NO\";\n    public int id;\n    public String nombre;\n    public String cargo;\n\n    public Empleado() {\n\n    }\n\n    protected Empleado(int id, String nombre) {\n        this.id = id;\n        this.nombre = nombre;\n    }\n\n    protected Empleado(int id, String nombre, String cargo) {\n        this.id = id;\n        this.nombre = nombre;\n        this.cargo = cargo;\n    }\n\n    protected void print(int id, String nombre, String cargo) {\n        System.out.println(\"\\nID: \" + id + \"\\nnombre: \" + nombre + \"\\ncargo: \" + cargo + \"\\nHace finanzas? \" + finanzas\n                + \"\\nHace compras? \" + compras + \"\\nHace proyectos? \" + proyectos + \"\\nOrganiza el trabajo? \" + organizacion\n                + \"\\nPica código? \" + programacion + \"\\nDespliega programas? \" + despliegue);\n    }\n\n    protected void print(List listaEmpleados) {\n\n        System.out.print(\"Empleados a su cargo: \");\n        for (int i = 0; i < listaEmpleados.size() - 1; ++i) {\n            System.out.print(listaEmpleados.get(i) + ((i != listaEmpleados.size() - 2) ? \" , \" : \" y \"));\n        }\n        System.out.println(listaEmpleados.get(listaEmpleados.size() - 1));\n    }\n\n}\n\nclass Gerente extends Empleado {\n\n    protected Gerente() {\n        this.compras = \"SI\";\n        this.finanzas = \"SI\";\n        this.cargo = \"Gerente\";\n    }\n\n}\n\nclass GerenteProyectos extends Empleado {\n\n    protected GerenteProyectos() {\n        this.organizacion = \"SI\";\n        this.proyectos = \"SI\";\n        this.cargo = \"Gerente de proyectos\";\n    }\n\n}\n\nclass Programador extends Empleado {\n\n    protected Programador() {\n        this.programacion = \"SI\";\n        this.despliegue = \"SI\";\n        this.cargo = \"Programador\";\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/java/JimsimroDev.java",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\n\npublic class JimsimroDev {\n\n  public static void main(String[] args) {\n    var perro = new Perro(\"max\");\n    perro.sonido();\n\n    var gato = new Gato(\"garfield\");\n    System.out.println(gato.getNombre());\n    gato.sonido();\n\n    // Puedo crear un arreglo pero como el arreglo solo acepta datos del mismo tipo\n    // uso la clase Padre JimsimroDev\n    Animal animales[] = new Animal[4]; // Aquie le digo que puedo guardar 4 animales\n    // Ahora asigno valor a cada posicoin del arreglo\n    animales[0] = perro;\n    animales[1] = gato;\n    animales[2] = new Perro(\"Dante\");\n    animales[3] = new Perro(\"Gilver\");\n    System.out.println(animales[2].toString());\n    // Lo puedo recorre con un for o usando Arrays.toString() para mostrarlos\n    for (int a = 0; a < animales.length; a++) {\n      System.out.println(animales[a].toString());\n    }\n    System.out.println(Arrays.toString(animales));\n\n    System.out.println(\"::::::::::EXTRA::::::::::::::\");\n    // EXTRA\n    var gerente = new Gerente(1L, \"Jhoan\");\n\n    var gerenteDeProyectos = new GerenteProyecto(2L, \"Isabel\", \"Proyecto 1\");\n    var gerenteDeProyectos1 = new GerenteProyecto(3L, \"Keren\", \"Proyecto 2\");\n\n    var desarrollador = new Programador(4L, \"Jesus\", \"PHP\");\n    var desarrollador1 = new Programador(5L, \"Jarvis\", \"Ruby\");\n    var desarrollador2 = new Programador(6L, \"Carmen\", \"perl\");\n    var desarrollador3 = new Programador(7L, \"Jimmis\", \"Java\");\n\n    System.out.println(\"::::::::::EXTRA::::::::::::::\");\n    System.out.println(\"::::::::::GERENTE::::::::::::\");\n    gerente.agregarEmpleado(gerenteDeProyectos);\n    gerente.agregarEmpleado(gerenteDeProyectos1);\n    gerente.coordinarImplementacion();\n    gerente.mostrarNombreYPuesto();\n    gerente.print();\n\n    System.out.println(\"::::::::::GERENTE DE PROYECTOS::::::::::::::\");\n    gerenteDeProyectos.agregarEmpleado(desarrollador);\n    gerenteDeProyectos.agregarEmpleado(desarrollador1);\n    gerenteDeProyectos.agregarEmpleado(desarrollador2);\n    gerenteDeProyectos.agregarEmpleado(desarrollador3);\n    gerenteDeProyectos.mostrarNombreYPuesto();\n    gerenteDeProyectos.coordinarImplementacion();\n    gerenteDeProyectos.print();\n\n    System.out.println(\"::::::::::DESARROLLADOR::::::::::::::\");\n    desarrollador.mostrarNombreYPuesto();\n    desarrollador.agregarEmpleado(desarrollador3);\n    desarrollador.print();\n  }\n}\n\nclass Animal {\n  private String nombre;\n\n  public String getNombre() {\n    return this.nombre;\n\n  }\n\n  public Animal(String nombre) {\n    this.nombre = nombre;\n  }\n\n  public Animal() {\n  }\n\n  public void sonido() {\n    System.out.println(\"Soindio generico\");\n  }\n\n}\n\nclass Perro extends Animal {\n\n  public Perro(String nombre) {\n    super(nombre);\n  }\n\n  // Para sobrescribir el metodo en tiempo de ejecucion en java se usa la\n  // anotacion @Overrideo\n  @Override\n  public void sonido() {\n    System.out.println(\"El perro ladra: ┬íGuau!\");\n  }\n\n  @Override\n  public String toString() {\n    return \"Nombre: \" + getNombre();\n  }\n\n}\n\nclass Gato extends Animal {\n\n  public Gato(String nombre) {\n    super(nombre);\n  }\n\n  @Override\n  public void sonido() {\n    System.out.println(\"El gato maulla: Miau!\");\n  }\n\n  @Override\n  public String toString() {\n    return \"Nombre: \" + getNombre();\n  }\n}\n\n// Extra\nclass Empleado {\n  private Long id;\n  private String puesto;\n  private String nombre;\n  private List<Empleado> empleadosACargo;\n\n  public Empleado() {\n\n  }\n\n  public Empleado(Long id, String puesto, String nombre) {\n    this.id = id;\n    this.puesto = puesto;\n    this.nombre = nombre;\n    this.empleadosACargo = new ArrayList<>();\n  }\n\n  public void agregarEmpleado(Empleado empleado) {\n    if (this instanceof Gerente || this instanceof GerenteProyecto) {\n      empleadosACargo.add(empleado);\n    } else {\n      System.out.println(\"Solo gerente y gerente de Proyectos pueden tener empleados a cargo\");\n    }\n  }\n\n  public void print() {\n    System.out.println(\"Empleados a cargo\");\n    for (Empleado empleado : empleadosACargo) {\n      System.out.print(empleado.getNombre());\n      System.out.print(\",\");\n    }\n    System.out.println();\n  }\n\n  public void mostrarNombreYPuesto() {\n    System.out.println(getPuesto() + getNombre());\n  }\n\n  public Long getId() {\n    return this.id;\n  }\n\n  public String getNombre() {\n    return this.nombre;\n  }\n\n  public void setNombre(String nombre) {\n    this.nombre = nombre;\n  }\n\n  public List<Empleado> getEmpleadosACargo() {\n    return this.empleadosACargo;\n  }\n\n  public String getPuesto() {\n    return puesto;\n  }\n}\n\nclass Gerente extends Empleado {\n\n  public Gerente() {\n\n  }\n\n  public Gerente(Long id, String nombre) {\n    super(id, \" Gerente \", nombre);\n  }\n\n  public void coordinarImplementacion() {\n    System.out.printf(\"%s Coordinando la Implementación de los proyecto informatico\\n\", getNombre());\n  }\n}\n\nclass Programador extends Empleado {\n  private String lenguaje;\n\n  public Programador(Long id, String nombre, String lenguaje) {\n    super(id, \" Programador \", nombre);\n    this.lenguaje = lenguaje;\n  }\n\n  public void codeando() {\n    System.out.printf(\"%s Esta Desrrollando en el %s\\n \", getNombre(), lenguaje);\n  }\n\n  public String getlenguaje() {\n    return lenguaje;\n  }\n\n  public void setlenguaje(String lenguaje) {\n    this.lenguaje = lenguaje;\n  }\n}\n\nclass GerenteProyecto extends Empleado {\n  private String proyecto;\n\n  public GerenteProyecto(Long id, String nombre, String proyecto) {\n    super(id, \" Gerente de Proyectos \", nombre);\n    this.proyecto = proyecto;\n  }\n\n  public void coordinarImplementacion() {\n    System.out.printf(\"%s Coordinando la Implementación su proyecto informatico\\n\", getNombre());\n  }\n\n  public String getProyecto() {\n    return this.proyecto;\n  }\n\n  public void setProyecto(String proyecto) {\n    this.proyecto = proyecto;\n  }\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/java/Josegs95.java",
    "content": "import java.util.ArrayList;\nimport java.util.List;\n\npublic class Josegs95 {\n    public static void main(String[] args) {\n        //Herencia\n        Animal animal = new Animal(null);\n        Perro dog = new Perro();\n        Gato cat = new Gato();\n\n        animal.makeSound(); //Out: null\n        dog.makeSound(); //Out: Guau\n        cat.makeSound(); //Out: Miau\n\n        //Reto\n        System.out.println(\"\\n\");\n        retoFinal();\n    }\n\n    public static class Animal{\n\n        private String sound;\n\n        public Animal(String sound){\n            this.sound = sound;\n        }\n\n        public void makeSound(){\n            System.out.println(sound);\n        }\n\n    }\n\n    public static class Perro extends Animal{\n\n        public Perro(){\n            super(\"Guau\");\n        }\n    }\n\n    public static class Gato extends Animal{\n\n        public Gato(){\n            super(\"Miau\");\n        }\n    }\n\n    public static void retoFinal(){\n        Manager manager = new Manager(\"1154257\", \"Jose\");\n        ProyectManager pm1 = new ProyectManager(\"9822361\", \"Rocío\");\n        ProyectManager pm2 = new ProyectManager(\"5418742\", \"Guillermo\");\n        Programmer p1 = new Programmer(\"7739682\", \"Lucía\", \"Java\");\n        Programmer p2 = new Programmer(\"3125055\", \"Nuria\", \"Python\");\n        Programmer p3 = new Programmer(\"4060533\", \"Isidoro\", \"C#\");\n\n        manager.addEmployee(pm1);\n        manager.addEmployee(pm2);\n        pm1.addEmployee(p1);\n        pm1.addEmployee(p2);\n        pm2.addEmployee(p3);\n\n        p1.addEmployee(manager);\n        p1.programme();\n\n        pm2.addEmployee(manager);\n        pm2.manageProyect();\n\n        manager.manageCompany();\n\n        System.out.print(\"Empleados a cargo de \" + manager.getName() + \": \");\n        manager.printEmployeeList();\n        System.out.println();\n\n        System.out.print(\"Empleados a cargo de \" + pm1.getName() + \": \");\n        pm1.printEmployeeList();\n        System.out.println();\n\n        System.out.print(\"Empleados a cargo de \" + pm2.getName() + \": \");\n        pm2.printEmployeeList();\n        System.out.println();\n    }\n\n    public static class Employee {\n        private final String ID;\n        private String name;\n        private List<Employee> employeeList;\n\n        public Employee(String id, String name){\n            this.ID = id;\n            this.name = name;\n            employeeList = new ArrayList<>();\n        }\n\n        public void addEmployee(Employee e){\n            employeeList.add(e);\n        }\n\n        public void printEmployeeList(){\n            for (Employee e : employeeList){\n                e.printEmployeeList();\n                System.out.print(e + \" \");\n            }\n        }\n\n        public String getID() {\n            return ID;\n        }\n\n        public String getName() {\n            return name;\n        }\n\n        public void setName(String name) {\n            this.name = name;\n        }\n\n        @Override\n        public String toString() {\n            return \"[\" + name + \":\" + ID + \"]\";\n        }\n    }\n\n    public static class Manager extends Employee{\n\n        public Manager(String id, String name){\n            super(id, name);\n        }\n\n        public void manageCompany(){\n            System.out.println(getName() + \" is managing the company...\");\n        }\n    }\n\n    public static class ProyectManager extends Employee{\n\n        public ProyectManager(String id, String name){\n            super(id, name);\n        }\n\n        public void manageProyect(){\n            System.out.println(getName() + \" is managing their project...\");\n        }\n\n        @Override\n        public void addEmployee(Employee e){\n            if (e instanceof Manager){\n                System.out.println(\"The project manager can not have a manager in their charge\");\n                return;\n            }\n\n            super.addEmployee(e);\n        }\n    }\n\n    public static class Programmer extends Employee{\n\n        private String language;\n\n        public Programmer(String id, String name, String language){\n            super(id, name);\n            this.language = language;\n        }\n\n        public void programme(){\n            System.out.println(getName() + \" is programming with \" + language);\n        }\n\n        @Override\n        public void addEmployee(Employee e) {\n            System.out.println(\"The programmer can not have employees in their charge\");\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/java/Qv1ko.java",
    "content": "public class Qv1ko {\n\n    public static void main(String[] args) {\n\n        Dog dog = new Dog();\n        dog.setName(\"Rex\");\n        \n        Cat cat = new Cat();\n        cat.setName(\"Whiskers\");\n\n        animalSound(dog);\n        animalSound(cat);\n\n    }\n\n    public static void animalSound(Animal animal) {\n        System.out.println(animal.getName() + \" makes the sound: \");\n        animal.makeSound();\n    }\n\n}\n\nclass Animal {\n\n    String name;\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public void makeSound() {\n        System.out.println(\"Unknown sound\");\n    }\n\n    @Override\n    public String toString() {\n        return name;\n    }\n\n}\n\nclass Dog extends Animal {\n\n    @Override\n    public void makeSound() {\n        System.out.println(\"Guau Guau\");\n    }\n\n}\n\nclass Cat extends Animal {\n\n    @Override\n    public void makeSound() {\n        System.out.println(\"Miau Miau\");\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/java/RodrigoGit87.java",
    "content": "public class RodrigoGit87 {\n\n    // Superclase\n    public static class Animal {\n        protected String nombre, genero;\n\n        // Constructor\n        public Animal(String nombre, String genero) {\n            this.nombre = nombre;\n            this.genero = genero;\n        }\n\n        // Metodo\n        public void emitirSonido() {\n        }\n    }\n\n    // Subclase\n    public static class Perro extends Animal {\n        String tamaño;\n\n        // Constructor\n        public Perro(String nombre, String genero) {\n            super(nombre, genero);\n        }\n\n        // Metodo sobreescrito\n        @Override\n        public void emitirSonido() {\n            System.out.println(\"Guau guau\");\n        }\n\n        public String getTamaño() {\n            return tamaño;\n        }\n\n        public void setTamaño(String tamaño) {\n            this.tamaño = tamaño;\n        }\n    }\n\n    // Subclase\n    public static class Gato extends Animal {\n        String pelaje;\n\n        // Constructor\n        public Gato(String nombre, String genero, String pelaje) {\n            super(nombre, genero);\n            this.pelaje = pelaje;\n        }\n\n        // Metodo sobreescrito\n        @Override\n        public void emitirSonido() {\n            System.out.println(\"Miau miau\");\n        }\n    }\n\n    // ----------------- EXTRA ------------------\n    // Superclase\n    public static class Empleado { // Empleado podría ser una clase abstracta, de la cual crear las subclases con\n                                   // sus respectivos constructores y metodos sobreescritos y/o propios. para el\n                                   // ejercicio, es una clase normal\n        protected String nombre;\n        protected String apellidos;\n        protected String dni;\n        protected int edad;\n\n        // Constructor\n        public Empleado(String nombre, String apellidos, String dni, int edad) {\n            this.nombre = nombre;\n            this.apellidos = apellidos;\n            this.dni = dni;\n            this.edad = edad;\n        }\n\n        // metodo\n        public String trabajar() {\n            return \"\";\n        }\n\n        // Subclase Gerente\n        public static class Gerente extends Empleado {\n            private String zona;\n\n            public Gerente(String nombre, String apellidos, String dni, int edad, String zona) {\n                super(nombre, apellidos, dni, edad);\n                this.zona = zona;\n            }\n\n            @Override\n            public String trabajar() {\n                return \"El gerente \" + nombre + \" \" + apellidos + \"\\nSupervisa a programadores de la zona \" + zona;\n            }\n\n        }\n\n        // Subclase Programadores\n        public static class Programadores extends Empleado {\n            protected String cargo, lenguaje;\n            protected int horasTrabajadas;\n\n            // constructor\n            public Programadores(String nombre, String apellidos, String dni, int edad, String cargo, String lenguaje) {\n                super(nombre, apellidos, dni, edad);\n                this.cargo = cargo;\n                this.lenguaje = lenguaje;\n            }\n\n            public int getHoras() {\n\n                return horasTrabajadas;\n            }\n\n            public void setHoras(int horas) {\n                this.horasTrabajadas = horas;\n            }\n\n            // metodo sobreescrito\n            @Override\n            public String trabajar() {\n                return \" El programador \" + nombre + \" \" + apellidos + \" trabaja con el lenguaje, \" + lenguaje\n                        + \", tiene el puesto de: \"\n                        + cargo + \".\\n Lleva \" + horasTrabajadas + \" horas trabajadas\";\n            }\n\n        }\n\n    }\n\n    // ----------- main ----------------\n    public static void main(String[] args) {\n        var perro = new Perro(\"Fido\", \"macho\");\n        perro.setTamaño(\" mediano \");\n        IO.println(\"El perro es de tamaño\" + perro.getTamaño());\n\n        var gato = new Gato(\"Garfield\", \" macho\", \" naranja\");\n\n        perro.emitirSonido();\n        gato.emitirSonido();\n\n        // ------------------ extra ------------------\n        var gerente = new Empleado.Gerente(\"Bruce\", \"Wayne\", \"12345678A\", 30, \"Sur\");\n        var programador = new Empleado.Programadores(\"Peter\", \"Parker\", \"87654321B\", 25, \"Junior\", \"Java\");\n\n        IO.println(gerente.trabajar());\n        System.out.println(\"----------------\");\n        programador.setHoras(10);\n        IO.println(programador.trabajar());\n\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/java/RoniPG.java",
    "content": "import java.util.ArrayList;\nimport java.util.List;\n\n// Roni\n/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n */\nclass Animal{ // --> Superclase\n\tprotected void sonidoAnimal() {\t\n\t\tSystem.out.println(\"Soy un animal que emite sonido\");\n\t}\n}\nclass Perro extends Animal{ // --> Subclase\n\tprotected void sonidoAnimal() {\t\n\t\tSystem.out.println(\"Soy un perro y ladro\");\n\t}\n}\nclass Gato extends Animal{ // --> Subclase\n\tprotected void sonidoAnimal() {\t\n\t\tSystem.out.println(\"Soy un gato y maúllo\");\n\t}\n}\npublic class HERENCIA_09{\n\tpublic static void main(String[] args) {\n\t\t// Instaciamos los objetos\n\t\tAnimal an = new Animal();// --> Objeto Animal\n\t\tan.sonidoAnimal();// --> Llamamos a la función\n\t\tPerro perro = new Perro();// --> Objeto Perro\n\t\tperro.sonidoAnimal();// --> Llamamos a la función sobrescrita\n\t\tGato gato = new Gato();// --> Objeto Gato\n\t\tgato.sonidoAnimal();// --> Llamamos a la función sobrescrita\n\t\t/* DIFICULTAD EXTRA (opcional):\n\t\t * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n\t\t * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n\t\t * Cada empleado tiene un identificador y un nombre.\n\t\t * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n\t\t * actividad, y almacenan los empleados a su cargo.\n\t\t */\n\t\t// Instaciamos los objetos\n\t\tGerente ger1 =new Gerente(0, \"A\");// --> Objeto Gerente\n\t\tGerente ger2 =new Gerente(1, \"B\");// --> Objeto Gerente\n\t\tGerente_de_Proyecto gdp1 = new Gerente_de_Proyecto(3, \"C\");// --> Objeto Gerente de Proyecto\n\t\tGerente_de_Proyecto gdp2 = new Gerente_de_Proyecto(4, \"D\");// --> Objeto Gerente de Proyecto\n\t\tProgramador pgr1= new Programador(5, \"E\");// --> Objeto Programador\n\t\tProgramador pgr2= new Programador(6, \"F\");// --> Objeto Programador\n\t\t// Le asignamos un empleado(Gerente de proyecto) al Gerente\n\t\tger1.asignarEmpleado(gdp1);\n\t\tger1.soy();// --> Llamamos a la función propia del Gerente\n\t\t// Le asignamos un Encargado(Gerente) al Gerente de proyecto\n\t\tgdp2.asignarEncargado(ger2);\n\t\tger2.soy();// --> Llamamos a la función propia del Gerente\n\t\t// Le asignamos un empleado(Programador) al Gerente de proyecto\t\t\n\t\tgdp1.asignarEmpleado(pgr1);\n\t\tgdp1.soy();// --> Llamamos a la función propia del Gerente de proyecto de proyecto sobrescrita\n\t\t// Le asignamos un Encargado(Gerente de proyecto) al Programador\n\t\tpgr2.asignarEncargado(gdp2);\n\t\tgdp2.soy();// --> Llamamos a la función propia del Gerente de proyecto de proyecto sobrescrita\n\t\tpgr1.soy();// --> Llamamos a la función propia del Programador de proyecto sobrescrita\n\t\tpgr2.soy();// --> Llamamos a la función propia del Programador de proyecto sobrescrita\n\t}\n}\nclass Empleado{ // --> Superclase\n\t//Atributos heredables\n\tprotected int identificador;\n\tprotected String nombre;\n\tpublic Empleado(int identificador, String nombre) {\n\t\tthis.identificador=identificador;\n\t\tthis.nombre=nombre;\n\t}\n\tpublic int getIdentificador() {\n\t\treturn identificador;\n\t}\n\tpublic void setIdentificador(int identificador) {\n\t\tthis.identificador = identificador;\n\t}\n\tpublic String getNombre() {\n\t\treturn nombre;\n\t}\n\tpublic void setNombre(String nombre) {\n\t\tthis.nombre = nombre;\n\t}\n}\nclass Gerente extends Empleado{ // --> Subclase\n\t//Atributos propios\n\tprivate String cargo;\n\tprivate List<Gerente_de_Proyecto> g_d_p;// --> Lista de empleados\n\tpublic Gerente(int identificador, String nombre) {\n\t\tsuper(identificador, nombre);\n\t\tthis.g_d_p= new ArrayList<>();\n\t\tthis.cargo=\"Gerente\";\n\t}\n\t//Metodos propios\n\tpublic void asignarEmpleado(Gerente_de_Proyecto gdp) {\n\t\tthis.g_d_p.add(gdp);\n\t}\n\tpublic void soy() {\n\t\tSystem.out.print(\"\\nSoy: \" +this.nombre+ \"\\nMi cargo es: \"+ this.cargo + \"\\nTengo a cargo a: \");\n\t\tfor(Gerente_de_Proyecto gdp : g_d_p) {\n\t\t\tSystem.out.print(\" - \"+gdp.nombre);\n\t\t}\n\t}\n}\nclass Gerente_de_Proyecto extends Empleado{ // --> Subclase\n\t//Atributos propios\n\tprivate String cargo;\n\tprivate List<Programador> programadores;// --> Lista de empleados\n\tpublic Gerente_de_Proyecto(int identificador, String nombre) {\n\t\tsuper(identificador,nombre);\n\t\tthis.programadores= new ArrayList<>();\n\t\tthis.cargo=\"Gerente de Proyecto\";\n\t}\n\t//Metodos propios\n\tpublic void asignarEncargado(Gerente ger) {\n\t\tger.asignarEmpleado(this);;\n\t}\n\tpublic void asignarEmpleado(Programador pgr) {\n\t\tthis.programadores.add(pgr);\n\t}\n\tpublic void soy() {\n\t\tSystem.out.print(\"\\nSoy: \" +this.nombre+ \"\\nMi cargo es: \"+ this.cargo + \"\\nTengo a cargo a: \");\n\t\tfor(Programador programador : programadores) {\n\t\t\tSystem.out.print( \" - \" + programador.nombre);\n\t\t}\n\t}\n}\nclass Programador extends Empleado{ // --> Subclase\n\t//Atributos propios\n\tprivate String cargo;\n\tpublic Programador(int identificador, String nombre) {\n\t\tsuper(identificador,nombre);\n\t\tthis.cargo=\"Programador\";\n\t}\n\t//Metodos propios\n\tpublic void asignarEncargado(Gerente_de_Proyecto gdp) {\n\t\tgdp.asignarEmpleado(this);;\n\t}\n\tpublic void soy() {\n\t\tSystem.out.print(\"\\nSoy: \" +this.nombre+ \"\\nMi cargo es: \"+ this.cargo);\n\t}\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/java/TofeDev.java",
    "content": "import java.util.ArrayList;\nimport java.util.List;\n\npublic class TofeDev {\n    public static void main(String[] args) {\n        Gato gato = new Gato(\"Miri\", 3);\n        Perro perro = new Perro(\"Firulais\", 5);\n    \n        System.out.println(\"Un gato llamado \" + gato.nombre + \" hace: \");\n        gato.sonido();\n        System.out.println(\"y tiene \" + gato.edad + \" años de edad.\");\n        System.out.println(\"Un perro llamado \" + perro.nombre + \" hace: \");\n        perro.sonido();\n        System.out.println(\"y tiene \" + perro.edad + \" años de edad.\");\n\n        //Extra\n        Gerente jefe = new Gerente(1, \"Ricardo Gonzales\");\n        jefe.coordEmpresa();\n\n        JefeProyecto projectManager1 = new JefeProyecto(2, \"Marta Rodriguez\", \"Proyecto 1\");\n        projectManager1.coordProyecto();\n\n        JefeProyecto projectManager2 = new JefeProyecto(3, \"Carolina Espíndola\", \"Proyecto 2\");\n        projectManager2.coordProyecto();\n    \n        Programador programador1 = new Programador(4, \"Mauricio Villanueva\", \"Backend\");\n        programador1.trabajo();\n        Programador programador2 = new Programador(5, \"Carlos Lopez\", \"Frontend\");\n        programador2.trabajo();\n        Programador programador3 = new Programador(6, \"Rubén Gutierrez\", \"Backend\");\n        programador3.trabajo();\n        Programador programador4 = new Programador(7, \"Guadalupe del Valle\", \"DevOps\");\n        programador4.trabajo();\n\n        projectManager1.agregarEmpleado(programador1);\n        projectManager1.agregarEmpleado(programador2);\n        projectManager2.agregarEmpleado(programador3);\n        projectManager2.agregarEmpleado(programador4);\n\n        projectManager1.listarEmpleados();\n        projectManager2.listarEmpleados();\n    }\n    \n    static class Animal {\n        String nombre;\n        int edad;\n        \n        public Animal(String nombre, int edad) {\n            this.nombre = nombre;\n            this.edad = edad;\n        }\n        \n        public void sonido() {\n        }\n    }\n\n    static class Gato extends Animal {\n\n        public Gato(String nombre, int edad) {\n            super(nombre, edad);\n        }\n        \n        @Override\n        public void sonido() {\n            System.out.println(\"Miau\");\n        }\n    }\n\n    static class Perro extends Animal {\n        public Perro(String nombre, int edad) {\n            super(nombre, edad);\n        }\n        \n        @Override\n        public void sonido() {\n            System.out.println(\"Guau\");\n        }\n    }\n\n    /* DIFICULTAD EXTRA (opcional):\n    * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n    * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n    * Cada empleado tiene un identificador y un nombre.\n    * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n    * actividad, y almacenan los empleados a su cargo.\n    */\n\n    static class Empleado {\n        int id;\n        String nombre;\n        List<Empleado> empleados;\n        \n        public Empleado(int id, String nombre) {\n            this.id = id;\n            this.nombre = nombre;\n            this.empleados = new ArrayList<>();\n        }\n\n        public void agregarEmpleado(Empleado empleado) {\n            this.empleados.add(empleado);\n        }\n\n        public void listarEmpleados(){\n            for (Empleado empleado : empleados) {\n                System.out.println(\"El empleado \" + empleado.nombre + \" está bajo el mando de \" + nombre);\n            }\n        } \n\n    }\n\n    static class Gerente extends Empleado{\n        public Gerente(int id, String nombre){\n            super(id, nombre);\n        }\n        public void coordEmpresa(){\n            System.out.println(this.nombre + \" está a cargo de todos los proyectos de la empresa\");\n        }\n    }\n\n    static class JefeProyecto extends Empleado{\n        String proyecto;\n        public JefeProyecto(int id, String nombre, String proyecto){\n            super(id, nombre);\n            this.proyecto = proyecto;\n        }\n        public void coordProyecto(){\n            System.out.println(this.nombre + \" tiene a cargo el \" + this.proyecto);\n        }\n\n    }\n\n    static class Programador extends Empleado{\n        String tipo;\n        public Programador(int id, String nombre, String tipo){\n            super(id, nombre);\n            this.tipo = tipo;\n        }\n\n        public void trabajo(){\n            System.out.println(this.nombre + \" es un desarrollador \" + tipo + \".\");\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/java/Worlion.java",
    "content": "import java.util.List;\nimport java.util.ArrayList;\nimport java.util.Arrays;\n\npublic class Worlion {\n\n    /*\n    * EJERCICIO: Herencia\n    */\n    abstract class Animal {\n        String name;\n        String family;\n        String sound;\n        String icon;\n\n        abstract String doSound();\n    }\n\n    class Dog extends Animal {\n        String family = \"Canidae\";\n        String sound = \"guau\";\n        String icon = \"🐶\";\n\n        public Dog(String name){\n            this.name = name;\n        }\n        \n        public String doSound() {\n            StringBuilder s = new StringBuilder(\"Los perros ladran asi: \");\n            s.append(this.sound);\n            s.append(this.icon);\n            s.append(\", y este se llama \"+this.name);\n\n            return s.toString();\n        }\n    }\n\n    class Cat extends Animal {\n        String family = \"Felidae\";\n        String sound = \"miau\";\n        String icon = \"🐱\";\n\n        public Cat(String name){\n            this.name = name;\n        }\n        \n        public String doSound() {\n            StringBuilder s = new StringBuilder(\"Los gatos maullan asi: \");\n            s.append(this.sound);\n            s.append(this.icon);\n            s.append(\", y este se llama \"+this.name);\n\n            return s.toString();\n        }\n    }\n    \n\n    public static void main(String[] args) {\n        new Worlion().run();\n    }\n\n    public void run(){\n        Animal perro = new Dog(\"Juanito\");\n        System.out.println(perro.doSound());\n\n        Animal cat = new Cat(\"Botitas\");\n        System.out.println(cat.doSound());\n\n        testEmployeesClasses();\n    }\n\n    /*\n    * DIFICULTAD EXTRA (opcional): Employees\n    */\n\n    abstract class Employee {\n        String id;\n        String name;\n        List<Employee> minionList = new ArrayList<>();\n        public abstract String toString();\n        private void addMinionEmployee(Employee e){\n            this.minionList.add(e);\n        }\n        private List<Employee> getMinionEmployees(){\n            return this.minionList;\n        }\n        protected String getId(String typeId, int counter){\n            return typeId+ String.format(\"%03d\", counter);\n        }\n    }\n\n    class Manager extends Employee{\n        static int idCount=0;\n        \n        public Manager(String name){\n            this.id = getId(\"MNG_\",++idCount);\n            this.name = name;\n        }\n\n        public void addMinionEmployee(Employee employee) {\n            this.minionList.add(employee);\n        }\n\n\n        public String toString(){\n            StringBuilder sb = new StringBuilder(\"\\nMANAGER: {\");\n            sb.append(\"\\n\\tId: \"+this.id);\n            sb.append(\"\\n\\tName: \"+this.name);\n            sb.append(\"\\n\\tEmployees in charge: \"+this.minionList);\n\n            sb.append(\"}\");\n            return sb.toString();\n        }\n    }\n    class ProjectManager extends Employee{\n        static int idCount=0;\n\n        List<String> projects = new ArrayList<>();\n\n        public ProjectManager(String name){\n            this.id = getId(\"PM_\",++idCount);\n            this.name = name;\n        }\n\n        public void addProject(String project) {\n            this.projects.add(project);\n        }\n\n        public void addMinionEmployee(Developer developer) {\n            this.minionList.add(developer);\n        }\n\n        public String toString(){\n            StringBuilder sb = new StringBuilder(\"\\nPROJECT MANAGER: {\");\n            sb.append(\"\\n\\tId: \"+this.id);\n            sb.append(\"\\n\\tName: \"+this.name);\n            sb.append(\"\\n\\tProjects: \"+this.projects);\n            sb.append(\"\\n\\tIn charge developers: \"+this.minionList);\n\n            sb.append(\"}\");\n            return sb.toString();\n        }\n    }\n    class Developer extends Employee{\n        private static int idCount=0;\n        private List<String> languages = new ArrayList<>();\n\n        public Developer(String name){\n            this.id = getId(\"DEV_\",++idCount);\n            this.name = name;\n        }\n\n        public Developer(String name, List<String> languages){\n            this(name);\n            this.languages = languages;\n        }\n\n        public void addLanguage(String language) {\n            this.languages.add(language);\n        }\n\n        public String toString(){\n            StringBuilder sb = new StringBuilder(\"\\nDEVELOPER: {\");\n            sb.append(\"\\n\\tId: \"+this.id);\n            sb.append(\"\\n\\tName: \"+this.name);\n            sb.append(\"\\n\\tLanguages: \"+this.languages);\n\n            sb.append(\"}\");\n            return sb.toString();\n        }\n    }\n\n    public void testEmployeesClasses() {\n    \n        System.out.println(\" \\n ---- 🌩 DIFICULTAD EXTRA 🌩 ----\\n\");\n\n        Developer kevin = new Developer(\"Kevin\");\n        kevin.addLanguage(\"Java\");\n        Developer stuart = new Developer(\"Stuart\", Arrays.asList(new String[]{\"PHP\", \"Lisp\"}));\n        Developer Jerry = new Developer(\"Jerry\", Arrays.asList(new String[]{\"Haskel\", \"Rust\", \"C#\"}));\n\n        ProjectManager oneil = new ProjectManager(\"O'Neil\");\n        oneil.addProject(\"proyecto caca\");\n        oneil.addProject(\"otro\");\n        \n        oneil.addMinionEmployee(kevin);\n        oneil.addMinionEmployee(stuart);\n\n        ProjectManager ripley = new ProjectManager(\"Ripley\");\n        ripley.addProject(\"TOP SECRET\");\n        ripley.addMinionEmployee(Jerry);\n\n\n        Manager theKing = new Manager(\"Jaffe Joffer\");\n        theKing.addMinionEmployee(oneil);\n        theKing.addMinionEmployee(ripley);\n\n        System.out.println(theKing.toString());\n\n        //System.out.println(kevin);\n        //System.out.println(stuart);\n        //System.out.println(Jerry);\n\n    }\n}\n\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/java/alexdevrep.java",
    "content": "package _09_Herencia;\nimport java.util.Stack;\n/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\npublic class _09_Herencia {\n\n    public static void main (String[] args){\n        Perro Animal1 = new Perro (\"Kinder\",\"Ladrando\");\n        Gato Animal2 = new Gato(\"Manchita\",\"Maullando\");\n        System.out.println(Animal1.ladrar());\n        System.out.println(Animal2.maullar());\n        //Dificultad EXTRA\n        Programador programador1 = new Programador(1,\"Alexdevrep\",null);\n        System.out.println(programador1.desarrollar());\n        Stack<String> personas = new Stack<>();\n        personas.push(\"Alexdevrep\"); //Añdimos personas a cargo del gerente\n        Gerente_Proyecto gerenteProyecto1 = new Gerente_Proyecto(2,\"Brais\",personas);\n        System.out.println(gerenteProyecto1.supervisar());\n        Stack<String> personas2 = new Stack<>();\n        personas2.push(\"Brais\");\n        Gerente gerente1 =new Gerente(3,\"MoureDev\",personas2);\n        System.out.println(gerente1.dirigir());\n    }\n}\n\nclass Animal{ //Inicializamos la clase principal\n    public String Nombre;\n\n    public Animal (String Nombre){ //Este es el constructor de la clase principal\n        this.Nombre=Nombre;\n    }\n}\n\nclass Perro extends Animal{ //Así se heredan las clases\n\n    private String sonido;\n    public Perro(String Nombre,String sonido) { //Constructor de la subclase\n        super(Nombre);\n        this.sonido=sonido;\n    }\n    public String ladrar(){ //Método de l clase\n        return (\"El perro con nombre \"+ this.Nombre+\" está \"+ this.sonido);\n    }\n}\n\nclass Gato extends Animal{\n    private String sonido;\n    public Gato(String Nombre,String sonido){\n        super(Nombre);\n        this.sonido=sonido;\n    }\n    public String maullar(){\n        return(\"El Gato con nombre \"+ this.Nombre+\" está \"+ this.sonido);\n    }\n}\n\n//Dificultad EXTRA\n\nclass Empleado{\n    public int id;\n    public String Nombre;\n    public Stack<String> personas;\n\n\n    public Empleado(int id,String Nombre,Stack<String> personas){\n        this.id= id;\n        this.Nombre=Nombre;\n        this.personas=(personas !=null)? personas : new Stack<>();\n\n    }\n}\n\nclass Programador extends Empleado{\n    public Programador(int id,String Nombre,Stack<String> personas){\n        super(id,Nombre,personas);\n    }\n    public String desarrollar(){\n        return (\"La persona \"+this.Nombre+\" con ID \"+this.id+\" está desarrollando una aplicación y lleva a cargo a \"\n        + this.personas.size()+ \" personas\");\n    }\n}\n\nclass Gerente_Proyecto extends Empleado{\n    public Gerente_Proyecto(int id,String Nombre,Stack<String> personas){\n        super(id,Nombre,personas);\n    }\n    public String supervisar(){\n        return (\"La persona \"+this.Nombre+\" con ID \"+this.id+\" está comprobando que no hay bugs y lleva a cargo a \"\n                + this.personas.size()+ \" personas\");\n    }\n}\n\nclass Gerente extends Empleado{\n    public Gerente(int id,String Nombre,Stack<String> personas){\n        super(id,Nombre,personas);\n    }\n    public String dirigir(){\n        return (\"La persona \"+this.Nombre+\" con ID \"+this.id+\" está decidiendo  que nueva característica \" +\n                \"añadir y lleva a cargo a \" + this.personas.size()+ \" personas\");\n    }\n}\n\n\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/java/alfaroo1.java",
    "content": "public class Animal {\n\t\n//\tAtributos que van a heredar todos los animales\n\t\n\tprotected String nombre;\n\tprotected int numPatas;\n\tprotected int edad;\n\tprotected boolean cola;\n\tprotected int numVacunas;\n\t\n//\tMetodos de la superclase Animal\n\tpublic Animal(String nombre, int numPatas, int edad, boolean cola, int numVacunas) {\n\t\tthis.nombre = nombre;\n\t\tthis.numPatas = numPatas;\n\t\tthis.edad = edad;\n\t\tthis.cola = cola;\n\t\tthis.numVacunas = numVacunas;\n\t}\n\t\n//\tMetodo sin parametros para la superclase Animal\n\tpublic Animal(){\n\t\tthis.nombre=\"\";\n\t\tthis.numPatas=0;\n\t\tthis.edad=0;\n\t\tthis.cola=false;\n\t\tthis.numVacunas=0;\n\t}\n\n\t\n//\tGetters and setters\n\tpublic String getNombre() {\n\t\treturn nombre;\n\t}\n\n\tpublic void setNombre(String nombre) {\n\t\tthis.nombre = nombre;\n\t}\n\n\tpublic int getNumPatas() {\n\t\treturn numPatas;\n\t}\n\n\tpublic void setNumPatas(int numPatas) {\n\t\tthis.numPatas = numPatas;\n\t}\n\n\tpublic int getEdad() {\n\t\treturn edad;\n\t}\n\n\tpublic void setEdad(int edad) {\n\t\tthis.edad = edad;\n\t}\n\n\tpublic boolean isCola() {\n\t\treturn cola;\n\t}\n\n\tpublic void setCola(boolean cola) {\n\t\tthis.cola = cola;\n\t}\n\n\tpublic int getNumVacunas() {\n\t\treturn numVacunas;\n\t}\n\n\tpublic void setNumVacunas(int numVacunas) {\n\t\tthis.numVacunas = numVacunas;\n\t}\n}\n\n------------- CLASS DOG -----------\npublic class Perro extends Animal{\n\t\n\tprivate String ladrido;\n\n\t\n//\tConstructor con todos los parametros de la superclase Animal\n\tpublic Perro(String nombre, int numPatas, int edad, boolean cola, int numVacunas, String ladrido) {\n\t\tsuper(nombre, numPatas, edad, cola, numVacunas);\n\t\tthis.ladrido = ladrido;\n\t}\n\t\n\tpublic Perro() {\n\t\tthis.ladrido=\"\";\n\t}\n\n\t\n//\tGetters and setters\n\tpublic String getLadrido() {\n\t\treturn ladrido;\n\t}\n\n\tpublic void setLadrido(String ladrido) {\n\t\tthis.ladrido = ladrido;\n\t}\n\t\n\t\n//\tMetodo para ver el sonido del animal\n\t\n\tpublic void ladrido() {\n\t\tScanner sn=new Scanner(System.in);\n\t\tSystem.out.println(\"Que sonido hace el perro?\");\n\t\tthis.setLadrido(sn.next());\n\t\t\n\t\tSystem.out.println(\"El perro hace: \"+this.getLadrido());\n\t}\n\t\n//\tMain para realizar las pruebas \n\tpublic static void main(String[] args) {\n\t\tPerro p=new Perro();\n\t\tp.ladrido();\n\t} \n\t\n}\n-----------CLASS CAT--------------\npublic class Gato extends Animal{\n\t\n\tprivate String mauyido;\n\n\t\n//\tConstructor con todos los parametros de la superclase Animal\n\tpublic Gato(String nombre, int numPatas, int edad, boolean cola, int numVacunas, String mauyido) {\n\t\tsuper(nombre, numPatas, edad, cola, numVacunas);\n\t\tthis.mauyido = mauyido;\n\t}\n\t\n//\tConstructor sin parametros\n\t\n\tpublic Gato() {\n\t\tthis.mauyido=\"\";\n\t}\n\n\t\n//\tGetters and setters\n\tpublic String getMauyido() {\n\t\treturn mauyido;\n\t}\n\n\tpublic void setMauyido(String mauyido) {\n\t\tthis.mauyido = mauyido;\n\t}\n\t\n//\tMetodo para ver el sonido del animal\n\t\n\tpublic void mauyido() {\n\t\tScanner sn=new Scanner(System.in);\n\t\tSystem.out.println(\"Que sonido hace el gato?\");\n\t\tthis.setMauyido(sn.next());\n\t\t\n\t\tSystem.out.println(\"El gato hace: \"+this.getMauyido());\n\t}\n\t\n//\tMain para realizar las pruebas\n\t\n\tpublic static void main(String[] args) {\n\t\tGato g= new Gato();\n\t\tg.mauyido();\n\t\t\n\t}\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/java/asjordi.java",
    "content": "import java.util.LinkedList;\nimport java.util.List;\n\npublic class Main {\n\n    /**\n     * La herencia es la capacidad de una clase para heredar o extender los atributos y métodos de otra clase.\n     * Esto permite crear clases más especializadas a partir de clases más generales.\n     * Es uno de los conceptos fundamentales de la programación orientada a objetos.\n     * La clase hija o subclase puede tener atributos y métodos que no existen en la clase padre o superclase.\n     * Con extends se indica que una clase hereda de otra.\n     * La palabra clave super en Java se utiliza para referirse a la clase padre de la clase actual.\n     * Se puede utilizar para llamar a métodos de la clase padre, acceder a variables de instancia de la clase padre y crear instancias de la clase padre.\n     */\n\n    public static void main(String[] args) {\n        new Animal().hacerRuido();\n        new Perro().hacerRuido();\n        new Gato().hacerRuido();\n\n        Gerente gerente = new Gerente(1, \"Gerente\");\n        GerenteProyecto gerenteProyecto = new GerenteProyecto(2, \"Gerente de Proyecto\");\n        Programador programador1 = new Programador(3, \"Programador Java Back\", \"Java\");\n        Programador programador2 = new Programador(4, \"Programador Python Back\", \"Python\");\n        Programador programador3 = new Programador(5, \"Programador Js Front\", \"JavaScript\");\n\n        gerente.contratarEmpleado(gerenteProyecto);\n        gerente.contratarEmpleado(programador1);\n        gerente.contratarEmpleado(programador2);\n        gerente.contratarEmpleado(programador3);\n\n        gerente.mostrarEmpleados();\n\n        gerenteProyecto.contratarEmpleado(programador1);\n        gerenteProyecto.contratarEmpleado(programador2);\n        gerenteProyecto.contratarEmpleado(programador3);\n\n        gerenteProyecto.mostrarEmpleados();\n    }\n\n    static class Animal {\n        public void hacerRuido() {\n            System.out.println(\"Haciendo ruido\");\n        }\n    }\n\n    static class Perro extends Animal {\n        public void hacerRuido() {\n            System.out.println(\"Guau\");\n        }\n    }\n\n    static class Gato extends Animal {\n        public void hacerRuido() {\n            System.out.println(\"Miau\");\n        }\n    }\n\n    /**\n     * DIFICULTAD EXTRA (opcional):\n     * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n     * pueden ser Gerentes, Gerentes de Proyecto o Programadores.\n     * Cada empleado tiene un identificador y un nombre.\n     * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n     * actividad, y almacenan los empleados a su cargo.\n     */\n\n    static class Empleado {\n        private int id;\n        private String nombre;\n        List<Empleado> empleados;\n\n        public Empleado(int id, String nombre) {\n            this.id = id;\n            this.nombre = nombre;\n            this.empleados = new LinkedList<>();\n        }\n\n        public int getId() {\n            return id;\n        }\n\n        public String getNombre() {\n            return nombre;\n        }\n\n        public void contratarEmpleado(Empleado empleado) {\n            empleados.add(empleado);\n        }\n\n        public void mostrarEmpleados() {\n            System.out.println(\"Empleados a cargo de \" + getNombre() + \":\");\n            for (Empleado empleado : empleados) {\n                System.out.println(empleado.getNombre());\n            }\n        }\n    }\n\n    static class Gerente extends Empleado {\n        public Gerente(int id, String nombre) {\n            super(id, nombre);\n        }\n    }\n\n    static class GerenteProyecto extends Empleado {\n        public GerenteProyecto(int id, String nombre) {\n            super(id, nombre);\n            empleados = new LinkedList<>();\n        }\n    }\n\n    static class Programador extends Empleado {\n        String lenguaje;\n\n        public Programador(int id, String nombre, String lenguaje) {\n            super(id, nombre);\n            this.lenguaje = lenguaje;\n        }\n\n        public String getLenguaje() {\n            return lenguaje;\n        }\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/java/cesar-ch.java",
    "content": "import java.util.ArrayList;\nimport java.util.List;\n\n/*\n    #09 HERENCIA Y POLIMORFISMO\n*/\n\nclass Animal {\n    protected String name;\n\n    public Animal(String name) {\n        this.name = name;\n    }\n\n    public void sound() {\n        System.out.println(name + \" makes a sound.\");\n    }\n}\n\nclass Dog extends Animal {\n    public Dog(String name) {\n        super(name);\n    }\n\n    public void sound() {\n        System.out.println(\"Guau, guau!\");\n    }\n}\n\nclass Cat extends Animal {\n    public Cat(String name) {\n        super(name);\n    }\n\n    public void sound() {\n        System.out.println(\"Miau, miau!\");\n    }\n}\n\n/* \n    DIFICULTAD EXTRA \n*/\n\nclass Empleado {\n    protected int id;\n    protected String nombre;\n    protected List<Empleado> empleadosACargo;\n\n    public Empleado(int id, String nombre) {\n        this.id = id;\n        this.nombre = nombre;\n        this.empleadosACargo = new ArrayList<>();\n    }\n\n    public void agregarEmpleado(Empleado empleado) {\n        this.empleadosACargo.add(empleado);\n    }\n\n    public void imprimirEmpleados() {\n        for (Empleado empleado : empleadosACargo) {\n            System.out.println(empleado.nombre);\n        }\n    }\n}\n\nclass Gerente extends Empleado {\n    public Gerente(int id, String nombre) {\n        super(id, nombre);\n    }\n\n    public void actividad() {\n        System.out.println(\"Gerente\");\n    }\n}\n\nclass GerenteProyecto extends Empleado {\n    public GerenteProyecto(int id, String nombre) {\n        super(id, nombre);\n    }\n\n    public void actividad() {\n        System.out.println(\"Gerente de Proyecto\");\n    }\n}\n\nclass Programador extends Empleado {\n    public Programador(int id, String nombre) {\n        super(id, nombre);\n    }\n\n    public void actividad() {\n        System.out.println(\"Programador\");\n    }\n}\n\npublic class Main {\n    public static void main(String[] args) {\n        Dog dog = new Dog(\"Fido\");\n        dog.sound();\n        Cat cat = new Cat(\"Mishi\");\n        cat.sound();\n\n        Gerente gerente = new Gerente(1, \"Juan\");\n        GerenteProyecto gerenteProyecto = new GerenteProyecto(2, \"Pedro\");\n        GerenteProyecto gerenteProyecto2 = new GerenteProyecto(3, \"Luis\");\n        Programador programador = new Programador(4, \"Maria\");\n        Programador programador2 = new Programador(5, \"Ana\");\n        Programador programador3 = new Programador(6, \"Jorge\");\n        Programador programador4 = new Programador(7, \"Carlos\");\n\n        gerente.agregarEmpleado(gerenteProyecto);\n        gerente.agregarEmpleado(gerenteProyecto2);\n\n        gerenteProyecto.agregarEmpleado(programador);\n        gerenteProyecto.agregarEmpleado(programador2);\n        gerenteProyecto2.agregarEmpleado(programador3);\n        gerenteProyecto2.agregarEmpleado(programador4);\n\n        gerente.imprimirEmpleados();\n        gerenteProyecto.imprimirEmpleados();\n        gerenteProyecto2.imprimirEmpleados();\n        programador.imprimirEmpleados();\n\n        gerente.actividad();\n        gerenteProyecto.actividad();\n        programador.actividad();\n    }\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/java/chartypes.java",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n\npublic class chartypes {\n\n  public static void main(String[] args) {\n    // Exercise\n    Dog dog1 = new Dog(\"My dog1\");\n    dog1.sound();\n    Cat cat1 = new Cat(\"my cat1\");\n    cat1.sound();\n    Animal cat2 = new Cat(\"my cat2\");\n    cat2.sound();\n    System.out.println(cat1);\n\n    // Extra\n    System.out.println(\"/////////////////// Extra ////////////////////\");\n    Manager myManager1 = new Manager(\"robert\", \"12\");\n    ProjectManager myProjManager1 = new ProjectManager(\"Gonzalo\", \"234\");\n    Programmer myProgrammer1 = new Programmer(\"Coby\", \"12312234\");\n    myManager1.checkEmployee(\"Coby\");\n    myProjManager1.checkProject();\n    myProgrammer1.createProgram();\n\n  }\n\n}\n\n// Exercise\nclass Animal {\n  private String name;\n\n  public Animal(String name) {\n    this.name = name;\n  }\n\n  public void sound() {\n    System.out.println(\"\");\n  }\n  @Override\n  public String toString() {\n    return this.name;\n  }\n}\n\nclass Dog extends Animal {\n  public Dog(String name){\n    super(name);\n  }\n  \n  @Override\n  public void sound() {\n    System.out.println(\"Guauuuuuu\");\n  }\n}\n\nclass Cat extends Animal {\n  public Cat(String name){\n    super(name);\n  }\n  @Override\n  public void sound() {\n    System.out.println(\"Miauuu\");\n  }\n}\n/////////////////////////////////////////\n//\n//Extra\n\nclass Employee{\n  String name;\n  String id;\n\n  public Employee(String name, String id){\n    this.name = name;\n    this.id = id;\n  }\n\n  @Override\n  public String toString() {\n    return this.name;\n  }\n\n}\n\nclass Manager extends Employee{\n\n  public Manager(String name, String id){\n    super(name,id);\n  }\n\n  public void checkEmployee(String name){\n    System.out.println(this.name + \" is checking everything is alright with \" + name);\n  }\n\n}\n\n\nclass ProjectManager extends Employee{\n\n  public ProjectManager(String name, String id){\n    super(name,id);\n  }\n\n  public void checkProject(){\n    System.out.println(this.name + \" is checking a project right now...\");\n  }\n\n}\n\n\nclass Programmer extends Employee{\n\n  public Programmer(String name, String id){\n    super(name,id);\n  }\n\n  public void createProgram(){\n    System.out.println(this.name + \" is coding to create a program... \");\n  }\n\n}\n\n\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/java/danhingar.java",
    "content": "import java.util.ArrayList;\nimport java.util.List;\n\npublic class danhingar {\n\n    public static void main(String[] args) {\n        Animal dog = new Dog(\"Pastor Alemán\");\n        Animal cat = new Cat(\"Gato persa\");\n        Cat cat1 = new Cat(\"Gato siamés\");\n        Dog dog1 = new Dog(\"Bulldog\");\n        Animal animal = new Animal(\"Pez\");\n        sound(dog);\n        sound(cat);\n        sound(dog1);\n        sound(cat1);\n        sound(animal);\n\n        Manager myManager = new Manager(1, \"Daniel\");\n        ProjectManager myProjectManager = new ProjectManager(2, \"Juan\", \"Proyecto 1\");\n        ProjectManager myProjectManager2 = new ProjectManager(3, \"Pepe\", \"Proyecto 2\");\n        Programmer myProgrammer = new Programmer(4, \"Luis\", \"Java\");\n        Programmer myProgrammer2 = new Programmer(5, \"Marcos\", \"Python\");\n        Programmer myProgrammer3 = new Programmer(6, \"Pablo\", \"Dart\");\n        Programmer myProgrammer4 = new Programmer(7, \"Rubén\", \"Typescript\");\n\n        myManager.add(myManager, List.of(myProjectManager,myProjectManager2));\n        myProjectManager.add(myProjectManager, List.of(myProgrammer,myProgrammer2));\n        myProjectManager2.add(myProjectManager2, List.of(myProgrammer3,myProgrammer4));\n\n        myProgrammer.add(myProgrammer, myProgrammer2);\n        myProgrammer3.code();\n\n        myProjectManager.coordinateProject();\n\n        myManager.coordinateProject();\n        myManager.printEmployees();\n\n        myProjectManager.printEmployees();\n        myProjectManager2.printEmployees();\n\n    }\n\n    public static class Animal {\n        private String name;\n\n        public Animal(String name) {\n            this.name = name;\n        }\n\n        public String getName() {\n            return name;\n        }\n\n        public void setName(String name) {\n            this.name = name;\n        }\n\n        public void sound() {\n            System.out.println(\"Sonido genérico\");\n        }\n    }\n\n    public static class Dog extends Animal {\n\n        public Dog(String name) {\n            super(name);\n        }\n\n        public void sound() {\n            System.out.println(\"Guau!\");\n        }\n\n    }\n\n    public static class Cat extends Animal {\n\n        public Cat(String name) {\n            super(name);\n        }\n\n        public void sound() {\n            System.out.println(\"Miau!\");\n        }\n\n    }\n\n    public static void sound(Animal animal) {\n        animal.sound();\n    }\n\n    // EXTRA\n    public static class Employee {\n        private Integer id;\n        private String name;\n        private List<Employee> employees = new ArrayList<>();\n\n        public Employee(Integer id, String name) {\n            this.id = id;\n            this.name = name;\n        }\n\n        public String getName() {\n            return name;\n        }\n\n        public void setName(String name) {\n            this.name = name;\n        }\n\n        public Integer getId() {\n            return id;\n        }\n\n        public void setId(Integer id) {\n            this.id = id;\n        }\n\n        public List<Employee> getEmployees() {\n            return employees;\n        }\n\n        public void setEmployees(List<Employee> employees) {\n            this.employees = employees;\n        }\n\n        public void add(Employee employee, List<Employee> employees) {\n            employee.employees.addAll(employees);\n        }\n\n        public void printEmployees(){\n            for (Employee employee : employees) {\n                System.out.println(employee.name);\n            }\n        }\n\n    }\n\n    public static class Programmer extends Employee {\n\n        private String language;\n\n        public Programmer(Integer id, String name,String language) {\n            super(id, name);\n            this.language = language;\n        }\n\n        public String getLanguage() {\n            return language;\n        }\n\n        public void setLanguage(String language) {\n            this.language = language;\n        }\n\n        public void add(Employee e,Employee e2){\n            System.out.println(\"Un programador no tiene empleados a su cargo. \"+e2.getName()+\" no se añadirá.\");\n        }\n\n        public void code(){\n            System.out.println(this.getName()+\" está programando en \"+this.getLanguage());\n        }\n\n    }\n\n    public static class Manager extends Employee {\n\n        public Manager(Integer id, String name) {\n            super(id, name);\n        }\n\n        public void coordinateProject(){\n            System.out.println(this.getName()+\" coordina todos los proyectos.\");\n        }\n\n    }\n\n    public static class ProjectManager extends Employee {\n\n        private String project;\n\n        public ProjectManager(Integer id, String name,String project) {\n            super(id, name);\n            this.project = project;\n        }\n\n        public void coordinateProject(){\n            System.out.println(this.getName()+\" está coordinando su proyecto \"+this.project+\".\");\n        }\n\n        public String getProject() {\n            return project;\n        }\n\n        public void setProject(String project) {\n            this.project = project;\n        }\n\n        \n\n    }\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/java/eulogioep.java",
    "content": "// Clase base o superclase\nclass Animal {\n    protected String nombre;\n\n    public Animal(String nombre) {\n        this.nombre = nombre;\n    }\n\n    public String sonido() {\n        return \"No hay sonido por defecto para el animal\";\n    }\n}\n\n// Clase derivada o subclase de Animal\nclass Perro extends Animal {\n    public Perro(String nombre) {\n        super(nombre);\n    }\n\n    @Override\n    public String sonido() {\n        return \"Guau\";\n    }\n}\n\n// Clase derivada o subclase de Animal\nclass Gato extends Animal {\n    public Gato(String nombre) {\n        super(nombre);\n    }\n\n    @Override\n    public String sonido() {\n        return \"Miau\";\n    }\n}\n\n// Dificultad extra: Clase base para Empleados\nclass Empleado {\n    protected int identificador;\n    protected String nombre;\n\n    public Empleado(int identificador, String nombre) {\n        this.identificador = identificador;\n        this.nombre = nombre;\n    }\n\n    public int getIdentificador() {\n        return identificador;\n    }\n\n    public String getNombre() {\n        return nombre;\n    }\n}\n\n// Clase derivada de Empleado para Gerentes\nclass Gerente extends Empleado {\n    private int cantidadEmpleados;\n\n    public Gerente(int identificador, String nombre, int cantidadEmpleados) {\n        super(identificador, nombre);\n        this.cantidadEmpleados = cantidadEmpleados;\n    }\n\n    public void setCantidadEmpleados(int cantidadEmpleados) {\n        this.cantidadEmpleados = cantidadEmpleados;\n    }\n\n    public int getCantidadEmpleados() {\n        return cantidadEmpleados;\n    }\n}\n\n// Clase derivada de Empleado para Gerentes de Proyectos\nclass GerenteDeProyecto extends Empleado {\n    private String proyecto;\n\n    public GerenteDeProyecto(int identificador, String nombre, String proyecto) {\n        super(identificador, nombre);\n        this.proyecto = proyecto;\n    }\n\n    public String getProyecto() {\n        return proyecto;\n    }\n}\n\n// Clase derivada de Empleado para Programadores\nclass Programador extends Empleado {\n    private String lenguajeFavorito;\n\n    public Programador(int identificador, String nombre, String lenguajeFavorito) {\n        super(identificador, nombre);\n        this.lenguajeFavorito = lenguajeFavorito;\n    }\n\n    public String getLenguajeFavorito() {\n        return lenguajeFavorito;\n    }\n}\n\npublic class EulogioEP {\n    public static void main(String[] args) {\n        // Instancia de las subclases de Animal\n        Perro perro = new Perro(\"Bobby\");\n        Gato gato = new Gato(\"Whiskers\");\n\n        // Llamado a la función sonido() en las instancias de las subclases\n        System.out.println(perro.nombre + \": \" + perro.sonido());\n        System.out.println(gato.nombre + \": \" + gato.sonido());\n\n        // Instancia de las subclases de Empleado\n        Gerente gerente = new Gerente(1001, \"Juan Pérez\", 10);\n        GerenteDeProyecto gerenteProyecto = new GerenteDeProyecto(1002, \"Luis Morales\", \"Proyecto X\");\n        Programador programador = new Programador(1003, \"Maria García\", \"Java\");\n\n        // Llamado a las funciones específicas de cada subclase de Empleado\n        System.out.println(\"Gerente: \" + gerente.getNombre() + \", Cantidad de empleados: \" + gerente.getCantidadEmpleados());\n        System.out.println(\"Gerente de Proyecto: \" + gerenteProyecto.getNombre() + \", Proyecto: \" + gerenteProyecto.getProyecto());\n        System.out.println(\"Programador: \" + programador.getNombre() + \", Lenguaje favorito: \" + programador.getLenguajeFavorito());\n    }\n}"
  },
  {
    "path": "Roadmap/09 - HERENCIA/java/h4ckxel.java",
    "content": "package ejercicio09;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/*\n* EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n */\npublic class JesusWay69 {\n\n    public static void main(String[] args) {\n        Perro perro = new Perro();\n        Gato gato = new Gato();\n        Vaca vaca = new Vaca();\n        Gerente gerente = new Gerente();\n        GerenteProyectos gerenteproyectos = new GerenteProyectos();\n        Programador programador = new Programador();\n\n        perro.print(perro.animal, perro.sonido);\n        gato.print(gato.sonido, gato.animal);\n        vaca.print(vaca.sonido, vaca.animal);\n        System.out.println(\"\");\n\n        String[] nombres = {\"Carlos\", \"Ana\", \"Francisco\", \"Paula\", \"Felipe\", \"Ainhoa\", \"Jesus\", \"Raquel\", \"Álvaro\"};\n        List<String> empleadosGerencia = new ArrayList<>();\n        List<String> empleadosProyectos = new ArrayList<>();\n        for (int i = 1; i <= nombres.length; i++) {\n            if (i > 2 && i <= nombres.length) {\n                empleadosGerencia.add(nombres[i - 1]);\n            }\n            if (i > 5 && i <= nombres.length) {\n                empleadosProyectos.add(nombres[i - 1]);\n\n            }\n        }\n\n        for (int i = 1; i <= nombres.length; i++) {\n            if (i > 0 && i < 3) {\n                gerente.print(i, nombres[i - 1], gerente.cargo);\n                gerente.print(empleadosGerencia);\n            } else if (i > 2 && i < 6) {\n                gerenteproyectos.print(i, nombres[i - 1], gerenteproyectos.cargo);\n                gerenteproyectos.print(empleadosProyectos);\n\n            } else {\n                programador.print(i, nombres[i - 1], programador.cargo);\n\n            }\n\n        }\n\n    }\n\n}\n\nabstract class Animal {\n\n    public String animal;\n    public String sonido;\n    private String articulo;\n\n    public Animal() {\n\n        articulo = \"El\";\n    }\n\n    protected void print(String sonido, String animal) {\n        if (animal.charAt(animal.length() - 1) == 'a') {\n            articulo = \"La\";\n        }\n        System.out.println(articulo + \" \" + animal + \" \" + sonido);\n\n    }\n\n}\n\nclass Perro extends Animal {\n\n    public Perro() {\n        this.animal = \"perro\";\n        this.sonido = \"ladra\";\n    }\n\n    @Override\n    public void print(String sonido, String animal) {\n        super.print(\"ladra\", \"perro\");\n    }\n\n}\n\nclass Gato extends Animal {\n\n    public Gato() {\n        this.animal = \"gato\";\n        this.sonido = \"maulla\";\n    }\n}\n\nclass Vaca extends Animal {\n\n    public Vaca() {\n        this.animal = \"vaca\";\n        this.sonido = \"muge\";\n    }\n}\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\nabstract class Empleado {\n\n    public String finanzas = \"NO\";\n    public String compras = \"NO\";\n    public String proyectos = \"NO\";\n    public String organizacion = \"NO\";\n    public String programacion = \"NO\";\n    public String despliegue = \"NO\";\n    public int id;\n    public String nombre;\n    public String cargo;\n\n    public Empleado() {\n\n    }\n\n    protected Empleado(int id, String nombre) {\n        this.id = id;\n        this.nombre = nombre;\n    }\n\n    protected Empleado(int id, String nombre, String cargo) {\n        this.id = id;\n        this.nombre = nombre;\n        this.cargo = cargo;\n    }\n\n    protected void print(int id, String nombre, String cargo) {\n        System.out.println(\"\\nID: \" + id + \"\\nnombre: \" + nombre + \"\\ncargo: \" + cargo + \"\\nHace finanzas? \" + finanzas\n                + \"\\nHace compras? \" + compras + \"\\nHace proyectos? \" + proyectos + \"\\nOrganiza el trabajo? \" + organizacion\n                + \"\\nPica código? \" + programacion + \"\\nDespliega programas? \" + despliegue);\n    }\n\n    protected void print(List listaEmpleados) {\n\n        System.out.print(\"Empleados a su cargo: \");\n        for (int i = 0; i < listaEmpleados.size() - 1; ++i) {\n            System.out.print(listaEmpleados.get(i) + ((i != listaEmpleados.size() - 2) ? \" , \" : \" y \"));\n        }\n        System.out.println(listaEmpleados.get(listaEmpleados.size() - 1));\n    }\n\n}\n\nclass Gerente extends Empleado {\n\n    protected Gerente() {\n        this.compras = \"SI\";\n        this.finanzas = \"SI\";\n        this.cargo = \"Gerente\";\n    }\n\n}\n\nclass GerenteProyectos extends Empleado {\n\n    protected GerenteProyectos() {\n        this.organizacion = \"SI\";\n        this.proyectos = \"SI\";\n        this.cargo = \"Gerente de proyectos\";\n    }\n\n}\n\nclass Programador extends Empleado {\n\n    protected Programador() {\n        this.programacion = \"SI\";\n        this.despliegue = \"SI\";\n        this.cargo = \"Programador\";\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/java/julian98789.java",
    "content": "package MauroDevRetos;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class reto_9_Animal {\n\n     \n\n     public void sonido( ){\n\n        System.out.println(\"el sonido de tu animal es \");\n\n\n     }\n\n}\n\nclass perro extends reto_9_Animal{\n\n\n    @Override\n    public void sonido( ){\n\n        System.out.println(\"el sonido de tu animal es guau\");\n\n     }\n    \n    \n}\n\nclass gato extends reto_9_Animal{\n\n    \n    @Override\n    public void sonido( ){\n\n        System.out.println(\"el sonido de tu animal es miau\");\n\n     }\n\n}\n\nclass Empleado {\n    private int id;\n    private String nombre;\n\n    // Constructor\n    public Empleado(int id, String nombre) {\n        this.id = id;\n        this.nombre = nombre;\n    }\n\n  \n    public int getId() {\n        return id;\n    }\n\n    public String getNombre() {\n        return nombre;\n    }\n\n   \n    public void mostrarInfo() {\n        System.out.println(\"ID: \" + id + \", Nombre: \" + nombre);\n    }\n}\n\nclass Gerente extends Empleado {\n    private List<Empleado> empleadosACargo;\n\n    // Constructor\n    public Gerente(int id, String nombre) {\n        super(id, nombre);\n        this.empleadosACargo = new ArrayList<>();\n    }\n\n    public void agregarEmpleado(Empleado empleado) {\n        empleadosACargo.add(empleado);\n    }\n\n  \n    @Override\n    public void mostrarInfo() {\n        super.mostrarInfo();\n        System.out.println(\"Empleados a cargo:\");\n        for (Empleado e : empleadosACargo) {\n            System.out.println(\"\\t- \" + e.getNombre());\n        }\n    }\n}\n\nclass GerenteDeProyecto extends Gerente {\n    private String proyecto;\n\n    public GerenteDeProyecto(int id, String nombre, String proyecto) {\n        super(id, nombre);\n        this.proyecto = proyecto;\n    }\n\n    @Override\n    public void mostrarInfo() {\n        super.mostrarInfo();\n        System.out.println(\"Proyecto: \" + proyecto);\n    }\n}\n\n\nclass Programador extends Empleado {\n    private String lenguajePrincipal;\n\n\n    public Programador(int id, String nombre, String lenguajePrincipal) {\n        super(id, nombre);\n        this.lenguajePrincipal = lenguajePrincipal;\n    }\n    @Override\n    public void mostrarInfo() {\n        super.mostrarInfo();\n        System.out.println(\"Lenguaje Principal: \" + lenguajePrincipal);\n    }\n}\n\nclass principal {\n\n    public static void mostrarSonido(reto_9_Animal animal){\n        animal.sonido();\n    }\n\n   \n\n\n\n\n    public static void main(String[] args) {\n\n        perro perro = new perro();\n        gato gato = new gato();\n\n        mostrarSonido(gato);\n        mostrarSonido(perro);\n        \n        Programador prog1 = new Programador(1, \"Ana\", \"Java\");\n        Programador prog2 = new Programador(2, \"Luis\", \"Python\");\n\n    \n        GerenteDeProyecto gerenteProy = new GerenteDeProyecto(3, \"Marta\", \"Proyecto X\");\n        gerenteProy.agregarEmpleado(prog1);\n        gerenteProy.agregarEmpleado(prog2);\n\n  \n        Gerente gerenteGen = new Gerente(4, \"Carlos\");\n        gerenteGen.agregarEmpleado(gerenteProy);\n\n \n        prog1.mostrarInfo();\n        System.out.println();\n        prog2.mostrarInfo();\n        System.out.println();\n        gerenteProy.mostrarInfo();\n        System.out.println();\n        gerenteGen.mostrarInfo();\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/java/kleyner098.java",
    "content": "/**\n * kleyner098\n */\nimport java.util.ArrayList;\n\npublic class kleyner098 {\n    \n        /*\n         * EJERCICIO:\n         * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n         * implemente una superclase Animal y un par de subclases Perro y Gato,\n         * junto con una función que sirva para imprimir el sonido que emite cada\n         * Animal.\n         *\n         * DIFICULTAD EXTRA (opcional):\n         * Implementa la jerarquía de una empresa de desarrollo formada por Empleados\n         * que pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n         * Cada empleado tiene un identificador y un nombre.\n         * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n         * actividad, y almacenan los empleados a su cargo.\n         */\n        public static void main(String[] args) {\n    \n            Animal animal = new Animal(\"Alberto\", \"humano\");\n            animal.sonido();\n            Perro estrella = new Perro(\"Estrella\",\"Yorkshire\");\n            estrella.sonido();\n            Gato tony = new Gato(\"Tony\", \"Siamés\");\n            tony.sonido();\n\n            System.out.println(\"---------------\");\n\n            Programador programador1 = new Programador(987654321, \"Maria\", \"Java\");\n            Programador programador2 = new Programador(8423212, \"Celia\", \"Kotlin\");\n            Programador programador3 = new Programador(6234234, \"Daniel\", \"Phyton\");\n            Programador programador4 = new Programador(454232, \"CArlos\", \"C++\");\n\n            GerenteProyecto gerenteProyecto1 = new GerenteProyecto(1111111, \"Sara\");\n            GerenteProyecto gerenteProyecto2 = new GerenteProyecto(2222222, \"Antonio\");\n\n            Gerente gerente1 = new Gerente(123456789, \"Juan\");\n            \n            gerente1.supervisar(gerenteProyecto1);\n            gerente1.supervisar(gerenteProyecto2);\n\n            gerenteProyecto1.supervisar(programador1);\n            gerenteProyecto1.supervisar(programador4);\n            gerenteProyecto2.supervisar(programador2);\n            gerenteProyecto2.supervisar(programador3);\n\n            System.out.println(gerente1);\n            gerente1.supervisados();\n            System.out.println(\"\\n\");\n\n            System.out.println(gerenteProyecto1);\n            System.out.println(gerenteProyecto2);\n            gerenteProyecto1.supervisados();\n            gerenteProyecto2.supervisados();\n            System.out.println(\"\\n\");\n\n            System.out.println(programador1);\n            System.out.println(programador2);\n            System.out.println(programador3);\n            System.out.println(programador4);\n        }\n}\n\nclass Animal{\n    \n    String nombre;\n    String raza;\n\n    Animal(String nombre, String raza){\n        this.nombre = nombre;\n        this.raza = raza;\n    }\n\n    public void sonido(){\n        System.out.println(\"Sonido genérico de animal\");\n    }\n}\n\nclass Perro extends Animal{\n\n    Perro(String nombre, String raza){\n        super(nombre, raza);\n    }\n\n    @Override\n    public void sonido() {\n        System.out.println(\"Gua guau guauuuuuu\");\n    }\n}\n\nclass Gato extends Animal{\n\n    Gato(String nombre, String raza){\n        super(nombre, raza);\n    }\n\n    @Override\n    public void sonido() {\n        System.out.println(\"Miau miel miauuuu\");\n    }\n}\n\nclass Empleado{\n    private int identificador;\n    private String nombre;\n\n    Empleado(int identificador, String nombre){\n        this.identificador = identificador;\n        this.nombre = nombre;\n    }\n\n    @Override\n    public String toString() {\n        return \"Indentidicación: \" + identificador + \" | Nombre: \" + nombre;  \n    }\n}\n\nclass Gerente extends Empleado{\n\n    private ArrayList<GerenteProyecto> gerenteProyectos;\n\n    Gerente(int identificador, String nombre){\n        super(identificador, nombre);\n        gerenteProyectos = new ArrayList<GerenteProyecto>();\n    }\n\n    @Override\n    public String toString() {\n        return \"Gerente \" + super.toString();\n    }\n\n    public void supervisar(GerenteProyecto nuevoGerenteProyecto){\n        gerenteProyectos.add(nuevoGerenteProyecto);\n    }\n\n    public void supervisados(){\n        System.out.println(this.toString() + \" está a cargo de :\");\n        System.out.println(gerenteProyectos);\n    }\n}\n\nclass GerenteProyecto extends Empleado{\n    private ArrayList<Programador> programadores;\n\n    GerenteProyecto(int identificador, String nombre){\n        super(identificador, nombre);\n        programadores = new ArrayList<Programador>();\n    }\n\n    @Override\n    public String toString() {\n        return \"Gerente de proyecto \" + super.toString();\n    }\n\n    public void supervisar(Programador nuevoProgramador){\n        programadores.add(nuevoProgramador);\n    }\n\n    public void supervisados(){\n        System.out.println(this.toString() + \"está a cargo de :\");\n        System.out.println(programadores);\n    }\n}\n\nclass Programador extends Empleado{\n    private String leguaje;\n\n    Programador(int identificador, String nombre, String lenguaje){\n        super(identificador, nombre);\n        this.leguaje = lenguaje;\n    }\n\n    @Override\n    public String toString() {\n        return \"Programador \" + super.toString() + \" | Lenguaje de programación: \" + leguaje;\n    }\n}"
  },
  {
    "path": "Roadmap/09 - HERENCIA/java/martinbohorquez.java",
    "content": "/**\n * #09 HERENCIA Y POLIMORFISMO\n *\n * @author martinbohorquez\n */\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\n\npublic class martinbohorquez {\n\n    public static void main(String[] args) {\n        Animal perro = new Perro(\"Punky\");\n        printSound(perro);\n        Animal gato = new Gato(\"Smoking\");\n        printSound(gato);\n        /*\n         *  DIFICULTAD EXTRA\n         */\n        Manager manager = new Manager(1, \"MartinDev\");\n        ProjectManager projectManager1 = new ProjectManager(2, \"Robert\",\n                Arrays.asList(\"Project 1\", \"Project 2\", \"Project 3\"));\n        ProjectManager projectManager2 = new ProjectManager(3, \"Kathie\",\n                Arrays.asList(\"Project 11\", \"Project 12\"));\n        Programmer programmer1 = new Programmer(4, \"Mark\",\n                Arrays.asList(\"Java\", \"Typescript\"));\n        Programmer programmer2 = new Programmer(5, \"Tim\",\n                Arrays.asList(\"Python\", \"JavaScript\"));\n        Programmer programmer3 = new Programmer(6, \"Linus\",\n                Arrays.asList(\"Java\", \"Python\", \"JavaScript\"));\n        Programmer programmer4 = new Programmer(7, \"Moure\",\n                Arrays.asList(\"Python\", \"Typescript\"));\n\n        manager.coordinateProjects();\n        manager.addEmployee(projectManager1);\n        manager.addEmployee(projectManager2);\n        manager.printEmployees();\n        projectManager1.coordinateProject();\n        projectManager1.addEmployee(programmer1);\n        projectManager1.addEmployee(programmer3);\n        projectManager1.printEmployees();\n        programmer2.code();\n        programmer3.addEmployee(programmer4);\n        programmer2.printEmployees();\n    }\n\n    private static void printSound(Animal animal) {\n        animal.sonido();\n    }\n\n    private static class Animal {\n        protected String name;\n\n        public Animal(String name) {\n            this.name = name;\n        }\n\n        protected void sonido() {\n            System.out.println(\"El animal emite un sonido!\");\n        }\n    }\n\n    private static class Perro extends Animal {\n\n        public Perro(String name) {\n            super(name);\n        }\n\n        @Override\n        protected void sonido() {\n            System.out.printf(\"El perro %s dice guau!%n\", name);\n        }\n    }\n\n    private static class Gato extends Animal {\n\n        public Gato(String name) {\n            super(name);\n        }\n\n        @Override\n        protected void sonido() {\n            System.out.printf(\"El gato %s dice miau!%n\", name);\n        }\n    }\n\n    private static class Employee {\n        protected int id;\n        protected String name;\n        protected List<Employee> employees = new ArrayList<>();\n\n        public Employee(int id, String name) {\n            this.id = id;\n            this.name = name;\n        }\n\n        protected void addEmployee(Employee employee) {\n            employees.add(employee);\n            System.out.printf(\"Se asigna empleado %s a cargo de %s%n\", employee.name, name);\n        }\n\n        protected void printEmployees() {\n            System.out.printf(\"Los empleados a cargo de %s:%n\", name);\n            employees.forEach(e -> System.out.println(e.name));\n        }\n    }\n\n    private static class Manager extends Employee {\n\n        public Manager(int id, String name) {\n            super(id, name);\n        }\n\n        private void coordinateProjects() {\n            System.out.printf(\"%s está coordinando todos los proyectos de la empresa%n\", name);\n        }\n    }\n\n    private static class ProjectManager extends Employee {\n        private List<String> projects = new ArrayList<>();\n\n        public ProjectManager(int id, String name, List<String> projects) {\n            super(id, name);\n            this.projects = new ArrayList<>(projects);\n        }\n\n        private void coordinateProject() {\n            System.out.printf(\"%s está coordinando sus proyectos %s%n\", name, projects.toString());\n        }\n    }\n\n    private static class Programmer extends Employee {\n        private List<String> languages = new ArrayList<>();\n\n        public Programmer(int id, String name, List<String> languages) {\n            super(id, name);\n            this.languages = new ArrayList<>(languages);\n        }\n\n        @Override\n        protected void addEmployee(Employee employee) {\n            System.out.printf(\"Un programador no tiene empleados a su cargo. %s no se añadirá!%n\", employee.name);\n        }\n\n        private void code() {\n            System.out.printf(\"%s está programando en %s%n\", name, languages.toString());\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/java/miguelex.java",
    "content": "import java.util.List;\nimport java.util.ArrayList;\n\npublic class miguelex {\n    public static void main(String[] args) {\n        Perro perro = new Perro(\"Milú\", \"Guau, guau\");\n        Gato gato = new Gato(\"Garfield\", \"Miauuuuu\");\n\n        perro.hacerSonido();\n        gato.hacerSonido();\n\n        Gerente gerente = new Gerente(1, \"Miguel\", List.of(new Empleado(101, \"Juan\"), new Empleado(102, \"Pedro\"), new Empleado(103, \"Luis\")));\n        gerente.mostrarPersonas();\n\n        Programador programador = new Programador(2, \"Juan\", List.of(\"Java\", \"Python\", \"C++\"));\n        programador.mostrarLenguajes();\n\n        GerenteProyecto gerenteP = new GerenteProyecto(3, \"Pedro\", List.of(new Empleado(104, \"Juan\"), new Empleado(105, \"Rebeca\")));\n        gerenteP.mostrarPersonas();\n    }\n}\n\nclass Animal {\n    private String nombre;\n    private String sonido;\n\n    public Animal(String nombre, String sonido) {\n        this.nombre = nombre;\n        this.sonido = sonido;\n    }\n\n    public void hacerSonido() {\n        System.out.println(\"El animal con nombre \" + this.nombre + \" está diciendo \" + this.sonido);\n    }\n}\n\nclass Perro extends Animal {\n    public Perro(String nombre, String sonido) {\n        super(nombre, sonido);\n    }\n}\n\nclass Gato extends Animal {\n    public Gato(String nombre, String sonido) {\n        super(nombre, sonido);\n    }\n}\n\nclass Empleado {\n    public int id;\n    public String nombre;\n\n    public Empleado(int id, String nombre) {\n        this.id = id;\n        this.nombre = nombre;\n    }\n\n    @Override\n    public String toString() {\n        return \"Empleado [id=\" + id + \", nombre=\" + nombre + \"]\";\n    }\n}\n\nclass Gerente extends Empleado {\n    public List<Empleado> personas;\n\n    public Gerente(int id, String nombre, List<Empleado> personas) {\n        super(id, nombre);\n        this.personas = personas;\n    }\n\n    public void mostrarPersonas() {\n        for (Empleado persona : this.personas) {\n            System.out.println(persona);\n        }\n    }\n}\n\nclass GerenteProyecto extends Empleado {\n    public List<Empleado> programadores;\n\n    public GerenteProyecto(int id, String nombre, List<Empleado> programadores) {\n        super(id, nombre);\n        this.programadores = programadores;\n    }\n\n    public void mostrarPersonas() {\n        for (Empleado persona : this.programadores) {\n            System.out.println(persona.nombre);\n        }\n    }\n}\n\nclass Programador extends Empleado {\n    public List<String> lenguajes;\n\n    public Programador(int id, String nombre, List<String> lenguajes) {\n        super(id, nombre);\n        this.lenguajes = lenguajes;\n    }\n\n    public void mostrarLenguajes() {\n        for (String lenguaje : this.lenguajes) {\n            System.out.println(lenguaje);\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/java/pguillo02.java",
    "content": "class Animal{\n    final String name;\n    final int peso;\n    final int tamaño;\n\n    public Animal(String name, int peso, int tamaño){\n        this.name = name;\n        this.tamaño = tamaño;\n        this.peso = peso;\n    }\n\n    public void sound(){}\n}\n\nclass Gato extends Animal{\n    private final String sonido;\n\n    public Gato(String name, int peso, int tamaño, String sonido){\n        super(name, peso, tamaño);\n        this.sonido = sonido;\n    }\n\n    @Override\n    public void sound(){\n        System.out.println(\"El\" + name + \"suena\" + sonido);\n    }\n}\n\npublic class pguillo02 {\n\n    public static void main(String args[]){\n        Gato g = new Gato(\"Gato\", 22, 22, \"Miau\");\n        g.sound();\n    }\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/java/simonguzman.java",
    "content": "import java.util.List;\nimport java.util.ArrayList;\npublic class simonguzman {\n    public static void main(String[] args) {\n        Dog dog1 = new Dog(\"Ares\", \"Lobo siberiano\");\n        Cat cat1 = new Cat(\"Katy\", \"Carey\");\n\n        \n        System.out.println(\"Nombre: \"+ dog1.getName() + \" Raza: \"+dog1.getRaza());\n        dog1.hacerSonido();\n        System.out.println(\"Nombre: \"+ cat1.getName() + \" Raza: \"+cat1.getRaza());\n        cat1.hacerSonido();\n\n        // Crear instancias de Manager, ProjectManager y Programmer\n        Manager manager1 = new Manager(1001, \"Alice\", \"TechCorp\");\n        ProjectManager pm1 = new ProjectManager(1002, \"Bob\", \"Project X\");\n        Programmer programmer1 = new Programmer(1003, \"Charlie\", \"Java\");\n        Programmer programmer2 = new Programmer(1004, \"Diana\", \"Python\");\n\n        // Agregar empleados al manager\n        manager1.agregarEmpleado(pm1);\n        manager1.agregarEmpleado(programmer1);\n        manager1.agregarEmpleado(programmer2);\n\n        // Listar empleados bajo el manager\n        System.out.println(\"Empleados a cargo de \" + manager1.name + \":\");\n        manager1.listarEmpleados();\n\n        // Probar métodos específicos de cada clase\n        manager1.coordManager();\n        pm1.coordProjManager();\n        programmer1.programmerProyect();\n        programmer2.programmerProyect();\n    }\n\n    static class Animal{\n        private String name;\n        private String raza;\n    \n        public Animal(){\n    \n        }\n    \n        public Animal(String name, String raza){\n            this.name = name;\n            this.raza = raza;  \n        }\n    \n        public void hacerSonido(){\n            \n        }\n\n        public String getName() {\n            return name;\n        }\n\n        public void setName(String name) {\n            this.name = name;\n        }\n\n        public String getRaza() {\n            return raza;\n        }\n\n        public void setRaza(String raza) {\n            this.raza = raza;\n        }\n    }\n    \n     static class Dog extends Animal{\n    \n        public Dog(){\n    \n        }\n    \n        public Dog(String name, String raza){\n            super(name, raza);\n        }\n    \n        @Override\n        public void hacerSonido() {\n            System.out.println(\"Guau\");\n        }\n        \n    }\n    \n    static class Cat extends Animal{\n    \n        public Cat(){\n    \n        }\n    \n        public Cat(String name, String raza){\n            super(name, raza);\n        }\n    \n        @Override\n        public void hacerSonido() {\n            System.out.println(\"Miau\");\n        } \n    }\n\n    static class Employee{\n        protected int id;\n        protected String name;\n        List<Employee> employees; \n\n        public Employee(){\n\n        }\n\n        public Employee(int id, String name){\n            this.id = id;\n            this.name = name;\n            this.employees = new ArrayList<>();\n        }\n\n        public void agregarEmpleado(Employee employee){\n            this.employees.add(employee);\n        }\n\n        public void listarEmpleados() {\n            if (!this.employees.isEmpty()) {\n                for (Employee emp : employees) {\n                    System.out.println(\"ID: \"+emp.id+\" Nombre: \"+emp.name);\n                }\n            } else {\n                System.out.println(\"No hay empleados\");\n            }\n        }\n    }\n\n    static class Manager extends Employee{\n\n        private String nameEnterprise;\n\n        public Manager(){\n\n        }        \n\n        public Manager(int id, String name, String nameEnterprise){\n            super(id, name);\n            this.nameEnterprise = nameEnterprise;\n        }\n\n        public void coordManager(){\n            System.out.println(\"El gerente \" +this.name + \" esta a cargo de los proyectos de la empresa \"+this.nameEnterprise);\n        }\n\n    }\n\n    static class ProjectManager extends Employee{\n\n        private String proyName;\n\n        public ProjectManager(){\n\n        }\n\n        public ProjectManager(int id, String name, String proyName){\n            super(id, name);\n            this.proyName = proyName;\n        }\n\n        public void coordProjManager(){\n            System.out.println(\"El gerente de proyecto \"+this.name+\" dirije al proyecto \"+this.proyName);\n        }\n    }\n\n    static class Programmer extends Employee{\n\n        private String languaje;\n\n        public Programmer(){\n\n        }\n\n        public Programmer(int id, String name, String languaje){\n            super(id, name);\n            this.languaje = languaje;\n        }\n\n        public void programmerProyect(){\n            System.out.println(\"El programador de proyecto \"+this.name+ \" programa en lenguaje \"+this.languaje);\n        }\n\n    }\n\n}\n\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/7R0N1X.js",
    "content": "class Animal {\n\n  constructor(nombre) {\n    this.nombre = nombre\n  }\n\n  sonido() {\n    return `${this.nombre} hace un sonido.`\n  }\n}\n\nclass Perro extends Animal {\n\n  constructor(nombre) {\n    super(nombre)\n  }\n\n  sonido() {\n    return `${this.nombre} ladra: ¡Guau guau!`\n  }\n\n}\n\nclass Gato extends Animal {\n\n  constructor(nombre) {\n    super(nombre)\n  }\n\n  sonido() {\n    return `${this.nombre} maúlla: ¡Miau miau!`\n  }\n\n}\n\nfunction imprimirSonido(animal) {\n  return animal.sonido();\n}\n\nconst miPerro = new Perro(\"Rex\")\nconst miGato = new Gato(\"Mimi\")\n\nconsole.log(imprimirSonido(miPerro))\nconsole.log(imprimirSonido(miGato))\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/AChapeton.js",
    "content": "class Animal{\n  constructor(name, size, isDomestic){\n    this.name = name\n    this.size = size\n    this.isDomestic = isDomestic\n  }\n}\n\nclass Dog extends Animal{\n  get makeDogSound(){\n    return this.dogSound()\n  }\n  \n  dogSound() {\n    return 'bark' + ' ' + this.name\n  }\n}\n\nclass Cat extends Animal{\n  get makeCatSound(){\n    return this.catSound()\n  }\n  \n  catSound() {\n    return 'meow' + ' ' + this.name\n  }\n}\n\nconst myDog = new Dog('Dolly', 'small', true)\nconsole.log(myDog.makeDogSound)\n\nconst myCat = new Cat('Snowball', 'small', true)\nconsole.log(myCat.makeCatSound)\n\n\n\n\n/* DIFICULTAD EXTRA */\n\nclass Empleado{\n  constructor(id, employeeName){\n    this.id = id\n    this.employeeName = employeeName\n  }\n\n  get makePresentation(){\n    return this.presentation()\n  }\n\n  presentation(){\n    return 'Hola, mi nombre es ' + this.employeeName\n  }\n}\n\nclass Gerente extends Empleado{\n  constructor(id, employeeName, clients = []){\n  super(id, employeeName)\n    this.clients = clients\n  }\n\n  get showClientsList(){\n    return this.clientsList()\n  }\n\n  clientsList(){\n    return this.clients\n  }\n\n  addNewClient(companyName){\n    this.clients.push(companyName)\n  }\n\n}\n\nconst newGerente = new Gerente('1', 'Andres')\nconsole.log(newGerente.makePresentation)\nconsole.log(newGerente.showClientsList)\nnewGerente.addNewClient('ITO')\nconsole.log(newGerente.showClientsList)\n\n\nclass GerenteProyecto extends Empleado{\n  constructor(id, employeeName, projects = []){\n    super(id, employeeName)\n    this.projects = projects\n  }\n\n  get showProjectsList(){\n    return this.projectsList()\n  }\n\n  projectsList(){\n    return this.projects\n  }\n\n  startProject(projectName){\n    this.projects.push(projectName)\n  }\n\n  finishProject(projectName){\n    this.projects = this.projects.filter(project => project !== projectName)\n  }  \n}\n\n\nconst newGerenteProyecto = new GerenteProyecto('2', 'Edith')\nconsole.log(newGerenteProyecto.makePresentation)\nconsole.log(newGerenteProyecto.showProjectsList)\nnewGerenteProyecto.startProject('Web page')\nnewGerenteProyecto.startProject('Mobile app')\nnewGerenteProyecto.startProject('Logo refresh')\nconsole.log(newGerenteProyecto.showProjectsList)\nnewGerenteProyecto.finishProject('Mobile app')\nconsole.log(newGerenteProyecto.showProjectsList)\n\n\nclass Programador extends Empleado{\n  constructor(id, employeeName, tasks = []){\n    super(id, employeeName)\n    this.tasks = tasks\n  }\n\n  get showTasksList(){\n    return this.tasksList()\n  }\n\n  tasksList(){\n    return this.tasks\n  }\n\n  startNewTask(newTask){\n    this.tasks.push(newTask)\n  }\n\n  finishTask(taskName){\n    this.tasks = this.tasks.filter(task => task !== taskName)\n  }\n}\n\nconst newProgramador = new Programador('3', 'Jesus')\nconsole.log(newProgramador.makePresentation)\nconsole.log(newProgramador.showTasksList)\nnewProgramador.startNewTask('refactor sign in function')\nnewProgramador.startNewTask('fix form styles')\nnewProgramador.startNewTask('create props TS interface')\nconsole.log(newProgramador.showTasksList)\nnewProgramador.finishTask('fix form styles')\nconsole.log(newProgramador.showTasksList)"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/AngelArgumedo.js",
    "content": "// herencia y polimorfismo\n\nclass Animal {\n    constructor(name, age, gender) {\n        this.name = name;\n        this.age = age;\n        this.gender = gender;\n    }\n    sonido() {\n        console.log(`${this.name} hace sonido`);\n    }\n};\n\n// herencia\nclass Dog extends Animal {\n    constructor(name, age, gender, raza) {\n        super(name, age, gender);\n        this.raza = raza;\n    }\n    getRaza() {\n        console.log(`${this.name} es un perro de raza ${this.raza}`);\n    }\n    sonido() {\n        console.log(`${this.raza} es un perro que ladra`);\n    }\n};\n\nclass Cat extends Animal {\n    constructor(name, age, gender, raza) {\n        super(name, age, gender);\n        this.raza = raza;\n    }\n    getRaza() {\n        console.log(`${this.name} es un gato de raza ${this.raza}`);\n    }\n    sonido() {\n        console.log(`${this.raza} es un gata que maulla`);\n    }\n};\n\n// polimorfismo\n/**\n * El polimorfismo permite que los metodos se comporten de diferentes maneras\n * segun el contexto en el que ses llamen.\n */\nclass Ave extends Animal{\n    sonido() {\n        console.log(\"El ave canta\");\n    }\n}\n\nconst animales = [\n    new Animal(\"Pedro\", 5, \"masculino\"),\n    new Dog(\"Pedro\", 3, \"masculino\", \"Labrador\"),\n    new Cat(\"Gatito\", 6, \"masculino\", \"Siamese\"),\n    new Ave()\n];\n\nanimales.forEach(animal => {\n    animal.sonido();\n});\n\n/*\n* DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n\nclass Empleados{\n    constructor(id, nombre){\n        this.id = id;\n        this.nombre = nombre;\n    }\n    getNombre() {\n        return this.nombre;\n    }\n};\n\nclass Gerente extends Empleados{\n    constructor(id, nombre, proyectos){\n        super(id, nombre);\n        this.proyectos = proyectos;\n    }\n    getProyectos() {\n        return this.proyectos;\n    }\n};\n\nclass GerenteDeProyecto extends Gerente{\n    agregarProyecto(proyecto){\n        this.proyectos.push(proyecto);\n    }\n};\n\nclass Programador extends Empleados{\n    constructor(id, nombre, lenguajes){\n        super(id, nombre);\n        this.lenguajes = lenguajes;\n    }\n    getLenguajes() {\n        return this.lenguajes;\n    }\n};\n\nconst gerentes = [\n    new Gerente(1, \"Pedro\", [\"Proyecto 1\", \"Proyecto 2\"]),\n    new GerenteDeProyecto(2, \"Juan\", [\"Proyecto 3\", \"Proyecto 4\"]),\n    new Programador(3, \"Carlos\", [\"Java\", \"Python\", \"C++\"])\n];\n\ngerentes.forEach(gerente => {\n    console.log(gerente.getNombre());\n});\n\ngerentes.forEach(gerente => {\n    console.log(gerente.getProyectos());\n});\n\ngerentes.forEach(gerente => {\n    gerente.agregarProyecto(\"Proyecto 5\");\n    console.log(gerente.getProyectos());\n});\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/Artickun.js",
    "content": "\n\n// HERENCIA ============================\n\n/*\n\nEn la programación orientada a objetos, la herencia \nes un mecanismo que permite a una clase heredar propiedades \ny métodos de otra clase. En JavaScript ES6, la herencia se \nlogra mediante la palabra clave class.\n\n*/\n\n/*\n ⚡  EJERCICIO ===============================\n   - Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n   - implemente una superclase Animal y un par de subclases Perro y Gato,\n   - junto con una función que sirva para imprimir el sonido que emite cada Animal.\n*/\n\n\n// Super Clase\nclass Animal {\n\n    name  = 'Animal';\n    sound = 'Sound';\n\n    constructor( name,sound ){\n        this.name  = name;\n        this.sound = sound;\n    }\n\n};\n\n//Clases extendida de Animal\nclass Species extends Animal {\n\n    constructor( name,sound ){\n        super( name,sound );\n    }\n\n    makeSound(){\n        console.log(\n            `${this.name} : ${this.sound}`\n            );\n    }\n};\n\n// Instancias de Species\nconst dog1  = new Species('Dog','Woof,Woof!');\nconst cat1  = new Species('Cat','Meow,Meow!');\nconst bird1 = new Species('Bird','Pío,Pío!');\n\n// Muestro en consola\nconsole.log( dog1 );\ndog1.makeSound();\nconsole.log( cat1 );\ncat1.makeSound();\nconsole.log( bird1 );\nbird1.makeSound();\n\n\n\n/*\n\n⚡ DIFICULTAD EXTRA (opcional) ===========================\n   Implementa la jerarquía de una empresa de desarrollo formada por Empleados que:\n\n   - pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n   - Cada empleado tiene un identificador y un nombre.\n   - Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n   - actividad, y almacenan los empleados a su cargo.\n\n*/\n\n// ⚡ Super Clase  =========================\n\nclass Empleado {\n\n    id;\n    nombre;\n    empleadosACargo = [];\n\n    constructor( id, nombre,empleadosACargo = [] ) {\n        this.id = id;\n        this.nombre = nombre;\n        this.empleadosACargo = empleadosACargo;\n    }\n\n    trabajar(){\n        console.log(\n            `${this.nombre} Esta trabajando ...`\n            );\n    }\n\n    verEmpleadosACargo() {\n        if (this.empleadosACargo.length === 0) {\n          console.log(`${this.nombre} no tiene empleados a cargo.`);\n        } else {\n          console.log(\n            `${this.nombre} tiene empleados a cargo:`);\n          this.empleadosACargo.forEach(empleado => {\n            console.log(\n                `- ${empleado.nombre}`\n                );\n          });\n        }\n      }\n\n};\n\n\n//⚡  Clase Gerente ==========================\n\nclass Gerente extends Empleado{\n\n    constructor(Id, nombre,area){\n        super(Id, nombre);\n        this.area = area;\n    }\n\n    asignarTarea(empleado) {\n\n        this.empleadosACargo.push(empleado);\n\n        console.log(\n            `${this.nombre} asignó una tarea a ${empleado.nombre}\n            en el area de ${this.area}`\n            );\n    }\n};\n\n\n// ⚡ Clase Gerente de Proyecto ===============\n\nclass GerenteProyecto extends Gerente{\n\n    constructor(id, nombre, area, proyecto) {\n        super( id,nombre,area );\n        this.proyecto = proyecto;\n    }\n    \n    coordinarProyecto() {\n        console.log(\n            `${this.nombre} está coordinando el proyecto : \n            ${this.proyecto} en el área: ${this.area}`\n            );\n    }\n};\n\n\n// ⚡ Clase Programador ========================\n\nclass Programador extends Empleado {\n\n    constructor(id, nombre, lenguaje) {\n      super(id, nombre);\n      this.lenguaje = lenguaje;\n    }\n  \n    programar() {\n      console.log(\n        `${this.nombre} está programando en : \n        ${this.lenguaje}.`\n        );\n    }\n};\n\n\n// Instancias: \nconst gerente1 = new Gerente( 1, 'Artic', 'Programación' );\nconst programador1 = new Programador( 2, 'Luisa', 'JavaScript' );\nconst gerenteProyecto1 = new GerenteProyecto(3, 'María', 'Desarrollo', 'Sistema X');\n\n\nconsole.log( gerente1 );\nconsole.log( programador1 );\nconsole.log( gerenteProyecto1 );\n\n\n//Métodos\ngerente1.trabajar();      // Salida: Artic está trabajando.\nprogramador1.trabajar();  // Salida: Luisa está trabajando.\n\n\n//Asignar Tareas con Método\ngerente1.asignarTarea( programador1 ); \n// Artic asignó una tarea a Luisa en el area de Programación\n\n//Coordinar Proyecto con Método\ngerenteProyecto1.coordinarProyecto();\n// Salida: María está coordinando el proyecto : Sistema X en el área: Desarrollo  \n\n//Ver empleados a cargo\ngerente1.verEmpleadosACargo();\ngerenteProyecto1.verEmpleadosACargo();\nprogramador1.verEmpleadosACargo();"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/Chrisdev00.js",
    "content": "//  * EJERCICIO:\n//  * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n//  * implemente una superclase Animal y un par de subclases Perro y Gato,\n//  * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n//  *\n//  * DIFICULTAD EXTRA (opcional):\n//  * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n//  * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n//  * Cada empleado tiene un identificador y un nombre.\n//  * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n//  * actividad, y almacenan los empleados a su cargo.\n\n\nclass Animal {\n    constructor(nombre) {\n        this.nombre = nombre;\n    }\n    sonido() {\n        throw new Error(\"El método sonido debe ser implementado por las clases hijas.\");\n    }\n}\n\nclass Perro extends Animal {\n    constructor(nombre) {\n        super(nombre);\n    }\n\n    sonido() {\n        return \"Guauu\";\n    }\n}\n\nclass Gato extends Animal {\n    constructor(nombre) {\n        super(nombre);\n    }\n\n    sonido() {\n        return \"Miauu\";\n    }\n}\n\n\nconst mi_perro = new Perro(\"Rufo\");\nconst mi_gato = new Gato(\"Bigotes\");\n\nconsole.log(mi_perro.nombre);  \nconsole.log(mi_perro.sonido()); \n\nconsole.log(mi_gato.nombre);    \nconsole.log(mi_gato.sonido());\n\n//  -----------------------------  EXTRA  -----------------------------------\n\nclass Empleado {\n    constructor(identificador, nombre) {\n        this.identificador = identificador;\n        this.nombre = nombre;\n    }\n\n    toString() {\n        return `ID: ${this.identificador}, Nombre: ${this.nombre}`;\n    }\n}\n\nclass Gerente extends Empleado {\n    constructor(identificador, nombre, departamento) {\n        super(identificador, nombre);\n        this.departamento = departamento;\n    }\n\n    toString() {\n        return `ID: ${this.identificador}, Nombre: ${this.nombre}, Departamento: ${this.departamento}`;\n    }\n}\n\nclass GerenteProyecto extends Gerente {\n    constructor(identificador, nombre, departamento, proyectos) {\n        super(identificador, nombre, departamento);\n        this.proyectos = proyectos;\n    }\n\n    toString() {\n        return `ID: ${this.identificador}, Nombre: ${this.nombre}, Departamento: ${this.departamento}, Proyectos: ${this.proyectos}`;\n    }\n}\n\nclass Programador extends Empleado {\n    constructor(identificador, nombre, lenguaje) {\n        super(identificador, nombre);\n        this.lenguaje = lenguaje;\n    }\n\n    toString() {\n        return `ID: ${this.identificador}, Nombre: ${this.nombre}, Lenguaje: ${this.lenguaje}`;\n    }\n}\n\nconst gerente_proyecto = new GerenteProyecto(1, \"Juan\", \"Desarrollo\", [\"Proyecto A\", \"Proyecto B\"]);\nconst programador = new Programador(2, \"Pedro\", \"JavaScript\");\n\nconsole.log(gerente_proyecto.toString());\nconsole.log(programador.toString());\n\n\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/DAVstudy.js",
    "content": "/*\n* EJERCICIO:\n* Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n\nclass Animal {\n    constructor(name, owner) {\n        this.name = name\n        this.owner = owner\n    }\n\n    sound = () => 'Sonido sin identificar'\n    \n}\n\nclass Dog extends Animal {\n\n    sound = () => 'Guau'\n}\n\nclass Cat extends Animal {\n\n    sound = () => 'Miau'\n}\n\n\nlet oreo = new  Cat('Oreo', 'Diego')\nlet chasca = new  Dog('Chasca', 'Juan')\n\nconsole.log(oreo.sound());\nconsole.log(chasca.sound());\n\n /*\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n\nclass Employees {\n    constructor(id, name) {\n        this.id = id\n        this.name = name\n    }\n}\n\nclass Manager extends Employees {\n\n    constructor(id, name, area, projectManagers = []) {\n        super(id, name);\n        this.area = area;\n        this.projectManagers = projectManagers;\n    }\n\n    addProjectManager(id, name, area, team) {\n        this.projectManagers.push(new ProjectManager(id, name, area, team));\n    }\n\n    removeProjectManager(id) {\n        this.projectManagers = this.projectManagers.filter(pm => pm.id !== id);\n    }\n    \n}\n\nclass ProjectManager extends Employees {\n\n    constructor(id, name, area, team = []) {\n        super(id, name);\n        this.area = area;\n        this.team = team;\n    }\n\n    addDeveloper(id, name, level) {\n        this.team.push(new Developers(id, name, level));\n    }\n\n    removeDeveloper(id) {\n        this.team = this.team.filter(dev => dev.id !== id);\n    }\n}\n\nclass Developers extends Employees {\n    constructor(id, name,level) {\n        super(id, name)\n        this.level = level\n    }\n}\n\nlet juan = new Developers(255, 'Juan', 'Senior')\nlet miguel = new Developers(256, 'Miguel', 'Mid-Senior')\nlet luis = new Developers(257, 'Luis', 'Senior')\nlet fabian = new Developers(258, 'Fabian', 'Junior')\n\nlet team1 = [juan, miguel]\nlet team2 = [luis, fabian]\n\nlet carlos = new ProjectManager(127, 'Carlos', 'Backend', team1)\nlet felipe = new ProjectManager(128, 'Felipe', 'Frontend', team2)\n\nlet diego = new Manager(0, 'Diego', 'Web Development', [carlos, felipe])\n\nconsole.log(diego.projectManagers)\ndiego.removeProjectManager(128)\nconsole.log(diego.projectManagers)\n\n\nconsole.log(carlos.team)\ncarlos.addDeveloper(12, 'Joaquim', 'Mid-Senior')\nconsole.log(carlos.team)\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/Dan-Corbo.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n\n\n/* Soluciones */\n\n\nclass Animal {\n  constructor(nombre, raza, color, sonido) {\n    this.nombre = nombre;\n    this.raza = raza;\n    this.color = color;\n    this._sonido = sonido; // Prefijo _ para indicar que es un atributo protegido\n  }\n\n  // Método para imprimir los atributos\n  informacion() {\n    let informacion = `\n    Nombre: ${this.nombre}\n    Raza: ${this.raza}\n    Color: ${this.color}\n    `;\n    if (this.clase) {\n      informacion += `Clase: ${this.clase}`;\n    }\n    return informacion;\n  }\n\n  // Getter para obtener el sonido que hace el animal\n    get sonido() {\n    return `\n      ${this._sonido}\n    `;\n  }\n}\n\nclass Perro extends Animal {\n  constructor(nombre, raza, color, sonido) {\n    super(nombre, raza, color, sonido);\n    this.clase = \"Perro\\n\";\n  }\n}\n\nclass Gato extends Animal {\n  constructor(nombre, raza, color, sonido) {\n    super(nombre, raza, color, sonido);\n    this.clase = \"Gato\\n\";\n  }\n}\n\nconst vaca = new Animal(\"Clementina\", \"Holstein\", \"Blanco y Negro\", \"Muuuu!!\");\nconsole.log(vaca.informacion());\n\nconst perro = new Perro(\"Rex\", \"Pastor Alemán\", \"Negro\", \"Woof Woof!!\");\nconsole.log(perro.sonido);\n\nconst gato = new Gato(\"Chimuelo\", \"Siamés\", \"Amarillo\", \"Meoww!!\");\nconsole.log(gato.informacion());\n\n\n\n/* Extra - Opcional */\n\n\n\nclass Empleado {\n  constructor(nombre, identificador) {\n    this.nombre = nombre;\n    this.identificador = identificador;\n  }\n\n  presentacion() {\n    return `Me llamo ${this.nombre}, mi rol en la empresa es ser ${this.identificador}.\\n`;\n  }\n}\n\nclass Gerente extends Empleado {\n  constructor(nombre, empleados = []) {\n    super(nombre, \"Gerente\");\n    this.empleados = empleados;\n  }\n\n  presentacion() {\n    let info = super.presentacion();\n    if (this.empleados.length > 0) {\n      info += `Además, tengo ${this.empleados.length === 1 ? 'a un empleado' : `a ${this.empleados.length} empleados`} a mi cargo: ${this.empleados.map(empleado => empleado.nombre).join(', ')}.\\n`;\n    }\n    return info;\n  }\n\n  dirigir(empleado) {\n    return `No me cierran los números muchachos, lo siento ${empleado.nombre} voy a tener que hacer recortes.\\n`;\n  }\n}\n\nclass SupervisorProyectos extends Gerente {\n  constructor(nombre, empleados) {\n    super(nombre, empleados);\n    this.identificador = \"Supervisor de Proyectos\";\n  }\n\n  supervisar() {\n    return `Falta una semana para el plazo del proyecto, por favor no se demoren, ${this.nombre} supervisando.\\n`;\n  }\n}\n\nclass Programador extends Empleado {\n  constructor(nombre) {\n    super(nombre, \"Programador\");\n  }\n\n  programar() {\n    return `Creando programa, no sea impaciente y espere, ${this.nombre} trabajando.\\n`;\n  }\n}\n\nconst jefe = new Gerente(\"Martín\", [new Empleado(\"Geronimo\", \"Empleado\"), new Empleado(\"Juan\", \"Empleado\")]);\nconsole.log(jefe.presentacion());\nconsole.log(jefe.dirigir(new Empleado(\"Geronimo\", \"Empleado\")));\n\nconst supervisor = new SupervisorProyectos(\"Geronimo\", [new Empleado(\"Juan\", \"Empleado\")]);\nconsole.log(supervisor.presentacion());\nconsole.log(supervisor.supervisar());\n\nconst empleado = new Programador(\"Juan\");\nconsole.log(empleado.presentacion());\nconsole.log(empleado.programar());\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/DavidMoralesDeveloper.js",
    "content": "// Super clase\n//primera forma encontrada en internet \nclass Animales{\n    type = 'animal'\n    sonido = 'Sonido'\n    color = 'color de tu perro'\n    constructor(){\n        \n    }\n    sound(){\n        console.log(`mi animal es un ${this.type} y hace ${this.sonido}`)\n    }  \n    aColor(){\n        console.log(`mi ${this.type} de color  ${this.color}`)\n    }\n    setColor(nuevoColor){\n        this.color = nuevoColor\n    } \n  \n}\n//sub clase\nclass Perro extends Animales {\n    type='perro'\n    sonido= 'Guau'\n    color = 'negro'\n    constructor(){\n        super() //entiendo que hereda el nombre y la funcion sound\n    }\n\n}\n\nconst perro = new Perro()\nconsole.log(perro)\nperro.sound()\nperro.aColor()\nperro.setColor('amarillo')\nperro.aColor()\n// -----------------------------------------------\n//segundaForma\n\nclass Animal2 {\n    constructor(nombre, color){\n        this.nombre= nombre\n        this.color = color\n        \n    }\n}\n\nclass Cat extends Animal2{\n    //ya no ocupo el constructor por que lo hereda juntos a los strings\n    sound(){\n        console.log(`mi gato ${this.nombre} hace Miauuuuu y es color ${this.color}`)\n    }\n}\n\nconst gato = new Cat('Michis', 'blanco')\ngato.sound()\n\n// ---------------------------------------------------------------------------------\n\n// Extra\n\nclass Empleados {\n    constructor( id, nombre, empleadosACargo = []){\n        this.id = id\n        this.nombre = nombre\n        this.empleadosACargo = empleadosACargo\n    }\n\n    addEmploye(ACargo){\n        this.empleadosACargo.push(ACargo)\n\n    }\n    verEmplye(){\n        if(this.empleadosACargo.length === 0){\n            console.log('no tiene a nadie a carargo')\n        }else{//chat gpt me ayudo con esto por que no me salia el for in\n            const nombresEmpleados =this.empleadosACargo.map(empleado => empleado.nombre);\n            console.log(this.nombre,'Empleados a cargo:', nombresEmpleados);\n        }\n    }\n}\n\n\nclass Gerentes extends Empleados{\n    coodinarProjectos(){\n        console.log(`${this.nombre} esta coodinando projectos de la empresa`)\n    }\n}\nclass GerentesProject extends Empleados{\n    constructor(id, nombre, projecto){\n        super(id, nombre)\n        this.projecto = projecto\n    }\n    coodinarUnProjecto(){\n        console.log(`${this.nombre} esta coodinando ${this.projecto}`)\n    }\n}\nclass Programadores extends Empleados{\n    constructor(id, nombre, lenguaje){\n        super(id, nombre)\n        this.lenguaje = lenguaje\n    }\n\n    programando(){\n        console.log(`${this.nombre} esta programando en ${this.lenguaje}`)\n    }\n\n    addEmploye(ACargo){\n        console.log(`el Programado no tiene empleados a cargo el ${ACargo} no se agrego` )\n\n    }\n}\n\nconsole.log('Gerente------------------------------- solo hay 1')\n\nconst gerente = new Gerentes(1 , 'Dav.Dev')\ngerente.coodinarProjectos()\n\nconsole.log('Gerentes de los projectos --------------------- solo hay2')\n\nconst miGerenteDeProjecto = new GerentesProject(2, 'Juan', 'Projecto 1')\nmiGerenteDeProjecto.coodinarUnProjecto()\nconst miGerenteDeProjecto2 = new GerentesProject(3, 'Diego', 'Projecto 2')\nmiGerenteDeProjecto2.coodinarUnProjecto()\n\nconsole.log('programadores-------------------------------- solo hay 4')\n\nconst miProgramador = new Programadores(4,'Dani', 'JavaScript')\nmiProgramador.programando()\nconst miProgramador2 = new Programadores(5,'Jowell', 'Python')\nmiProgramador2.programando()\nconst miProgramador3 = new Programadores(6,'Fer', 'Python')\nmiProgramador3.programando()\nconst miProgramador4 = new Programadores(7,'Santi', 'JavaScript')\nmiProgramador4.programando()\n\nconsole.log('jerarquias de los empleados Dav.Dev ---------------------------- Gerente ')\ngerente.addEmploye(miGerenteDeProjecto) //juan\ngerente.addEmploye(miGerenteDeProjecto2) //Diego\ngerente.verEmplye()\n\nconsole.log('jerarquias de los empleados ---------------------------- Gerentes de projectos')\nconsole.log('projecto1------------------ Juan')\nmiGerenteDeProjecto.addEmploye(miProgramador) //Dani\nmiGerenteDeProjecto.addEmploye(miProgramador4)//Santi\nmiGerenteDeProjecto.verEmplye()\n\nconsole.log('projecto2------------------ Diego')\nmiGerenteDeProjecto2.addEmploye(miProgramador2) //Jowell\nmiGerenteDeProjecto2.addEmploye(miProgramador3)//fer\nmiGerenteDeProjecto2.verEmplye()\n\nconsole.log('jerarquias de los empleados ---------------------------- Gerentes de projectos')\nmiProgramador.addEmploye(miProgramador2)\n\n\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/Deyvid-10.js",
    "content": "class Animal\n{\n    constructor(sonido)\n    {\n        this.sonido = sonido\n    }\n}\n\nclass Perro extends Animal\n{\n    constructor(sonido, raza)\n    {\n        super(sonido)\n        this.raza = raza\n    }\n\n    hablar() \n    {\n        console.log(`El perro hace ${this.sonido}`);\n    }\n\n    razaPerro() \n    {\n        console.log(`El perro es de raza ${this.raza}`);\n    }\n}\n\nlet miPerro = new Perro(\"Wao!\")\nmiPerro.hablar()\nmiPerro.razaPerro()\n\nclass Gato extends Animal\n{\n    constructor(sonido)\n    {\n        super(sonido)\n    }\n\n    hablar() \n    {\n        console.log(`El gato hace ${this.sonido}`);\n    }\n}\n\nlet miGato = new Gato(\"Firulais\", \"Miau!\")\n\n// DIFICULTAD EXTRA\n\nclass Empleado\n{\n    constructor(id, nombre)\n    {\n        this.id = id\n        this.nombre = nombre\n    }\n\n    datos()\n    {\n        console.log(`Identificador: ${this.id}`);\n        console.log(`Nombre: ${this.nombre}`);\n    }\n}\n\nlet miEmpleado = new Empleado(\"05\", \"Manuel\")\nmiEmpleado.datos()\n\nclass Gerentes extends Empleado\n{\n    constructor(id, nombre)\n    {\n        super(id, nombre)\n    }\n\n    supervisioGeneral() \n    {\n        console.log(`${this.nombre} se encarga de monitorear el desempeño de todos los departamentos.`);\n    }\n\n    gestionRecursos()\n    {\n        console.log(`${this.nombre} aprueba los presupuestos y controla los gastos.`);\n    }\n}\n\nlet miGerente = new Gerentes(\"06\", \"Alberto\")\nmiGerente.datos()\nmiGerente.gestionRecursos()\nmiGerente.supervisioGeneral()\n\nclass GerentesProyectos extends Empleado\n{\n    constructor(id, nombre, proyecto)\n    {\n        super(id, nombre)\n        this.proyecto = proyecto\n    }\n\n    planificacion() \n    {\n        console.log(`${this.nombre} crea el cronograma del proyecto`);\n    }\n\n    gestionEquipos()\n    {\n        console.log(`${this.nombre} asigna tareas y responsabilidades a los miembros del equipo`);\n    }\n\n    comunicacion()\n    {\n        console.log(`${this.nombre} provee informes de estado del proyecto y realiza reuniones de actualización`)\n    }\n}\n\nlet miGerenteProyectos = new GerentesProyectos(\"07\", \"Garcia\", \"Web de negocios\")\nmiGerenteProyectos.datos()\nmiGerenteProyectos.comunicacion()\nmiGerenteProyectos.gestionEquipos()\nmiGerenteProyectos.comunicacion()\n\nclass Programador extends Empleado\n{\n    constructor(id, nombre, tegnologia)\n    {\n        super(id, nombre)\n        this.tegnologia = tegnologia\n    }\n\n    desarrollo() \n    {\n        console.log(`${this.nombre} escribe y revisa código en el lenguaje ${this.tegnologia}.`);\n    }\n}\n\nlet miProgramador = new Programador(\"09\", \"Jaime\", \"JavaScript\")\nmiProgramador.datos()\nmiProgramador.desarrollo()"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/EloyChavezDev.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n\n//Superclase Animal y subclases Perro y Gato:\nclass Animal {\n    constructor(nombre) {\n      this.nombre = nombre;\n    }\n  \n    hablar() {\n      console.log(\"**Sonido genérico de animal**\");\n    }\n  }\n  \n  class Perro extends Animal {\n    constructor(nombre, raza) {\n      super(nombre);\n      this.raza = raza;\n    }\n  \n    hablar() {\n      console.log(\"**Woof!**\");\n    }\n  }\n  \n  class Gato extends Animal {\n    constructor(nombre, raza) {\n      super(nombre);\n      this.raza = raza;\n    }\n  \n    hablar() {\n      console.log(\"**Meow!**\");\n    }\n  }\n  \n  // Ejemplo de uso\n  const perro1 = new Perro(\"Toby\", \"Labrador\");\n  perro1.hablar();\n  \n  const gato1 = new Gato(\"Luna\", \"Siamés\");\n  gato1.hablar();\n\n  //Dificultad Extra: Jerarquía de Empresa de Desarrollo\n  class Empleado {\n    constructor(id, nombre) {\n      this.id = id;\n      this.nombre = nombre;\n      this.empleadosACargo = [];\n    }\n  \n    getInfo() {\n      console.log(`ID: ${this.id}`);\n      console.log(`Nombre: ${this.nombre}`);\n    }\n  }\n  \n  //Clase Gerente:\n  class Gerente extends Empleado {\n    constructor(id, nombre, departamento) {\n      super(id, nombre);\n      this.departamento = departamento;\n    }\n  \n    getInfo() {\n      super.getInfo();\n      console.log(`Departamento: ${this.departamento}`);\n    }\n  }\n  \n  //Clase Gerente de Proyectos:\n  class GerenteProyecto extends Gerente {\n    constructor(id, nombre, departamento, proyectos) {\n      super(id, nombre, departamento);\n      this.proyectos = proyectos;\n    }\n  \n    getInfo() {\n      super.getInfo();\n      console.log(`Proyectos: ${this.proyectos.join(\", \")}`);\n    }\n  }\n  \n  //Clase Programador:\n  class Programador extends Empleado {\n    constructor(id, nombre, lenguajes) {\n      super(id, nombre);\n      this.lenguajes = lenguajes;\n    }\n  \n    getInfo() {\n      super.getInfo();\n      console.log(`Lenguajes de programación: ${this.lenguajes.join(\", \")}`);\n    }\n  }\n  \n  // Ejemplo de uso\n  const gerente1 = new Gerente(1, \"Ana\", \"Ventas\");\n  gerente1.getInfo();\n  \n  const gerenteProyecto1 = new GerenteProyecto(2, \"Pedro\", \"Desarrollo\", [\"Proyecto X\", \"Proyecto Y\"]);\n  gerenteProyecto1.getInfo();\n  \n  const programador1 = new Programador(3, \"María\", [\"JavaScript\", \"Python\"]);\n  programador1.getInfo();\n  \n  // Asignación de empleados a cargo\n  gerente1.empleadosACargo.push(programador1);\n  gerenteProyecto1.empleadosACargo.push(programador1);\n  \n  // Mostrar la información de los empleados a cargo del gerente\n  console.log(\"Empleados a cargo del gerente:\");\n  for (const empleado of gerente1.empleadosACargo) {\n    empleado.getInfo();\n  }\n  \n  // Mostrar la información de los empleados a cargo del gerente de proyecto\n  console.log(\"Empleados a cargo del gerente de proyecto:\");\n  for (const empleado of gerenteProyecto1.empleadosACargo) {\n    empleado.getInfo();\n  }"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/FabianRpv.js",
    "content": "// Herencia y Polimorfismo\n\nclass Animal {\n    \n    constructor(nombre){\n        this.nombre = nombre;\n    }\n\n}\n\nclass Perro extends Animal {\n\n    sonido(){\n        console.log('El Perro Ladra')\n    }\n}\n\nclass Gato extends Animal {\n\n    sonido(){\n        console.log('El Gato Maulla')\n    }\n}\n\nconst miPerro = new Perro('Milca');\n\nmiPerro.sonido()\n\nconst miGato = new Gato('Mishi');\n\nmiGato.sonido();\n\n\n/*\n* DIFICULTAD EXTRA (opcional):\n* Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n* pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n* Cada empleado tiene un identificador y un nombre.\n* Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n* actividad, y almacenan los empleados a su cargo.\n*/\n\nclass Empleado {\n    \n    constructor(id, nombre){\n        this.id =id;\n        this.nombre = nombre;\n    }\n\n}\n\nclass Gerente extends Empleado {\n\n    constructor(id, nombre){\n        super(id, nombre);\n        this.empleados = [];\n    }\n\n    mostrarInformacion(){\n        console.log(`Gerente: ${this.nombre}, ID: ${this.id}`);\n    }\n\n    agregarEmpleado(empleado){\n        this.empleados.push(empleado);\n    }\n\n    mostrarEmpleados(){\n\n        console.log('Empleados a cargo: ');\n\n        this.empleados.forEach( empleado => { console.log(`Gerente de Proyecto: ${empleado.nombre}`); });\n    }\n}\n\nclass GerenteProyecto extends Empleado {\n\n    constructor(id, nombre){\n        super(id, nombre);\n        this.empleados = [];\n    }\n\n    mostrarInformacion(){\n        console.log(`Gerente de Proyecto: ${this.nombre}, ID: ${this.id}`);\n    }\n\n    agregarEmpleado(empleado){\n        this.empleados.push(empleado)\n    }\n\n    mostrarEmpleados(){\n\n        console.log('Empleados a cargo: ');\n\n        this.empleados.forEach( empleado => { console.log(`Programador: ${empleado.nombre}`); });\n    }\n\n\n\n}\n\nclass Programador extends Empleado {\n\n    mostrarInformacion(){\n        console.log(`Programador: ${this.nombre}, ID: ${this.id}`);\n    }\n\n}\n\n\nconst gerente = new Gerente(1, 'Juan');\nconst gerenteProyecto = new GerenteProyecto(2, 'Pedro');\nconst programador1 = new Programador(3, 'Luis');\nconst programador2 = new Programador(4, 'Carlos');\n\ngerente.agregarEmpleado(gerenteProyecto);\ngerenteProyecto.agregarEmpleado(programador1);\ngerenteProyecto.agregarEmpleado(programador2);\n\ngerente.mostrarInformacion();\ngerente.mostrarEmpleados();\nconsole.log('------------------------------')\ngerenteProyecto.mostrarInformacion();\ngerenteProyecto.mostrarEmpleados();\nconsole.log('------------------------------')\nprogramador1.mostrarInformacion();\nprogramador2.mostrarInformacion();\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/Glitzypanic.js",
    "content": "// // HERENCIA\n// // SUPERCLASE\n// class Animal {\n//   constructor(nombre, color) {\n//     this.nombre = nombre;\n//     this.color = color;\n//   }\n//   sonido() {}\n// }\n\n// // SUBCLASES\n// class Perro extends Animal {\n//   coloring() {\n//     console.log(`${this.nombre} es de color ${this.color}`);\n//   }\n\n//   sonido(sonido) {\n//     console.log(`${this.nombre} hace ${sonido}`);\n//   }\n// }\n\n// class Gato extends Animal {\n//   coloring() {\n//     console.log(`${this.nombre} es de color ${this.color}`);\n//   }\n\n//   sonido(sonido) {\n//     console.log(`${this.nombre} hace ${sonido}`);\n//   }\n// }\n\n// let perro = new Perro(\"Milkshake\", \"cafe\");\n// let gato = new Gato(\"Vaquita\", \"negro\");\n// perro.sonido(\"guau\");\n// gato.sonido(\"miau\");\n// perro.coloring();\n// gato.coloring();\n\n// EJERCICIO\nclass Company {\n  constructor(id, nombre) {\n    this.id = id;\n    this.nombre = nombre;\n    this.employees = [];\n  }\n  add(employee) {\n    this.employees.push(employee);\n  }\n  print_employees() {\n    for (let employee of this.employees) {\n      console.log(employee.nombre);\n    }\n  }\n}\n\nclass Manager extends Company {\n  coordinate_projects() {\n    console.log(\n      `${this.nombre} está coordinando todos los proyectos de la empresa.`\n    );\n  }\n}\n\nclass ProjectManager extends Company {\n  constructor(id, nombre, proyect) {\n    super(id, nombre);\n    this.proyect = proyect;\n  }\n  coordinate_proyect() {\n    console.log(`${this.nombre} está coordinando su proyecto.`);\n  }\n}\n\nclass Programmer extends Company {\n  constructor(id, nombre, lenguage) {\n    super(id, nombre);\n    this.lenguage = lenguage;\n  }\n  code() {\n    console.log(`${this.nombre} está programando en ${this.lenguage}`);\n  }\n\n  add(employee = Employee) {\n    console.log(\n      `Un programador no tiene empleados a su cargo. ${employee.nombre} no se añadira.`\n    );\n  }\n}\nmy_manager = new Manager(1, \"Jose\");\n\nmy_proyectManager = new ProjectManager(2, \"Maria\", \"Proyecto 1\");\nmy_protectManager2 = new ProjectManager(3, \"Pedro\", \"Proyecto 2\");\n\nmy_programmer = new Programmer(4, \"Juan\", \"JavaScript\");\nmy_programmer2 = new Programmer(5, \"Carlos\", \"Python\");\nmy_programmer3 = new Programmer(6, \"Luis\", \"Java\");\nmy_programmer4 = new Programmer(7, \"Rodrigo\", \"Java\");\n\nmy_manager.add(my_proyectManager);\nmy_manager.add(my_protectManager2);\n\nmy_proyectManager.add(my_programmer);\nmy_proyectManager.add(my_programmer2);\n\nmy_protectManager2.add(my_programmer3);\nmy_protectManager2.add(my_programmer4);\n\nmy_programmer.add(my_programmer2);\n\nmy_programmer.code();\nmy_proyectManager.coordinate_proyect();\nmy_manager.coordinate_projects();\nmy_manager.print_employees();\nmy_proyectManager.print_employees();\nmy_programmer.print_employees();\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #09 - JavaScript ->Jesus Antonio Escamilla */\n/**\n * La herencia se refiere la capacidad de un objeto (Clase), de heredar propiedades\n    y métodos de otra clase en este caso de una SuperClase que seria una clase principal.\n * Los objetos pueden compartir características entre ellos a través de algo llamado \"prototipo\".\n * Imagina que cada objeto tiene un amigo especial (su prototipo) al que puede preguntarle si no sabe algo.\n * Si ese amigo tampoco lo sabe, puede preguntar a su propio amigo, y así sucesivamente hasta llegar a un amigo\n    que siempre sabe todo, y ese amigo es como el \"amigo base\" que todos comparten, llamado Object.prototype. \n */\n\n// Se define una superclase Animal\nclass Animal {\n    constructor(nombre) {\n        this.nombre = nombre;\n    }\n}\n\n// El Perro es herencia de Animal por tener nombre y emitir sonido\nclass Perro extends Animal{\n    constructor(nombre, raza){\n        // Llamamos al constructor de la clase base utilizando \"super\"\n        super(nombre);\n\n        // Agregamos propiedades específicas de la subclase\n        this.raza = raza;\n\n    }\n    saludar(){\n        console.log(`Hola, soy ${this.nombre} y mi raza es ${this.raza}`);\n    }\n}\n\n// El Gato es herencia de Animal por tener nombre y emitir sonido\nclass Gato extends Animal {\n    constructor(nombre, color) {\n        super(nombre);\n        this.color = color;\n    }\n    // Sobrescribimos el método saludar para la subclase\n    saludar() {\n        console.log(`Hola, soy ${this.nombre} y mi pelaje es de color ${this.color}`);\n    }\n}\n\n// El Hamster es herencia de Animal por tener nombre y emitir sonido\nclass Hamster extends Animal{\n    constructor(nombre, size){\n        super(nombre);\n        this.size = size;\n    }\n    saludar(){\n        console.log(`Hola, soy ${this.nombre} y mi tamaño es de ${this.size}`);\n    }\n}\n\n// Crear instancias de las clases\nvar perro = new Perro('Hachico', 'Labrador');\nvar gato = new Gato('Kenta', 'Gris');\nvar hamster = new Hamster('Petronilo', 'Mediano');\n\n// Ejemplo de herencia\nperro.saludar();\ngato.saludar();\nhamster.saludar();\n\n\n/**-----DIFICULTAD EXTRA-----*/\n\n// Función que genera un identificador único\nfunction generarIdentificador() {\n    const numeroAleatorio = Math.floor(Math.random() * 1000);\n    const identificador = `ID_${numeroAleatorio}`;\n    return identificador;\n}\n\n// Super-Clase de Empleado\nclass Empleado{\n    constructor(nombre){\n        this.Id = generarIdentificador();\n        this.nombre = nombre;\n        this.empleado = [];\n    }\n    agregar_empleados(empleado){\n        this.empleado.push(empleado);\n    }\n    imprimirEmpleado(){\n        console.log(this.empleado);\n    }\n}\n\n//  Clase Gerente que extiende de Empleado\nclass Gerente extends Empleado{\n    constructor(Id, nombre){\n        super(Id, nombre);\n    }\n    coordinar_proyectos(){\n        console.log(`${this.nombre} esta coordinando todos los proyectos de la empresa`);\n    }\n}\n\n//  Clase Gerente de Proyecto que extiende de Empleado\nclass GerenteProyecto extends Empleado{\n    constructor(nombre, proyecto){\n        super(nombre);\n        this.proyecto = proyecto;\n    }\n\n    coordinar_proyecto(){\n        console.log(`${this.nombre} esta coordinando su proyecto`);\n    }\n}\n\n//  Clase Programador que extiende de Empleado\nclass Programador extends Empleado{\n    constructor(nombre, language){\n        super(nombre);\n        this.language = language;\n    }\n\n    code(){\n        console.log(`${this.nombre} esta programando en ${this.language}`)\n    }\n\n    agregar_empleado(){\n        console.log(`Un programador no puede tener empleado.`);\n    }\n}\n\n\n//  Asignamos valores a la empresa\nconst mi_gerente = new Gerente(\"Jesus Antonio\");\nconst mi_gerente_proyecto_1 = new GerenteProyecto(\"Fatima\", \"Proyecto1\");\nconst mi_gerente_proyecto_2 = new GerenteProyecto(\"Angel\", \"Proyecto2\");\nconst mi_programador_1 = new Programador(\"Adolfo\", \"Python\");\nconst mi_programador_2 = new Programador(\"Naty\", \"JavaScript\");\nconst mi_programador_3 = new Programador(\"Ruben\", \"Kotlin\");\nconst mi_programador_4 = new Programador(\"Axel\", \"PHP\");\n\n//  Agregamos la jerarquía\nmi_gerente.agregar_empleados(mi_gerente_proyecto_1);\nmi_gerente.agregar_empleados(mi_gerente_proyecto_2);\nmi_gerente_proyecto_1.agregar_empleados(mi_programador_1);\nmi_gerente_proyecto_1.agregar_empleados(mi_programador_2);\nmi_gerente_proyecto_2.agregar_empleados(mi_programador_3);\nmi_gerente_proyecto_2.agregar_empleados(mi_programador_4);\n\nmi_programador_1.agregar_empleado(mi_gerente_proyecto_1); // Esta No Puede Agregar\n\n//  Usamos las funciones o propiedades de las clases\nmi_programador_1.code();\nmi_gerente_proyecto_1.coordinar_proyecto();\nmi_gerente.coordinar_proyectos();\nmi_gerente.imprimirEmpleado();\nmi_gerente_proyecto_1.imprimirEmpleado();\nmi_programador_1.imprimirEmpleado();\n\n/**-----DIFICULTAD EXTRA-----*/"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/Nightblockchain30.js",
    "content": "class Animal {\n    constructor(name,age){\n        this.name = name\n        this.age = age  \n    }\n\n    speakAnimmal(){\n        return `Animal Power!`;\n    }\n}\n\n\nclass Dog extends Animal {\n    constructor(name,age,breed){\n        super(name,age)\n        this.breed = breed\n    }\n\n    speakDog(){\n        return `GUAU GUAU`\n    }\n}\n\n\nclass Cat extends Animal {\n    constructor(name,age,size){\n        super(name,age)\n        this.size = size\n    }\n\n    speakCat(){\n        return `MIAU MIAU`\n    }\n}\n\n\n// CASOS DE USO\nlet animal1 = new Animal(\"caballo\",10)\nlet dog1= new Dog(\"perro\",5,\"Bull Terrier\")\nlet cat1= new Cat(\"gato\",10,\"small\")\n\nconsole.log(animal1.speakAnimmal());\nconsole.log(dog1.speakDog());\nconsole.log(cat1.speakCat());\n\n\n// << EXTRA >>\n\nclass Employee {\n    constructor(id,name){\n        this.id = id;\n        this.name = name;\n        this.empleadosAsignados = [];\n    }\n\n    getInfo(){\n        console.log(`ID:${this.id} | NAME:${this.name}`);\n    }\n}\n\nclass Manager extends Employee {\n    constructor(id,name,age){\n        super(id,name)\n        this.age = age;\n    }\n\n    getInfo(){\n        super.getInfo();\n        console.log(`AGE: ${this.age}`);\n    }\n}\n\n\nclass ProjectManager extends Employee {\n    constructor(id,name,experience){\n        super(id,name)\n        this.experience = experience\n    }\n}\n\n\nclass Programmer extends Employee{\n    constructor(id,name,language){\n        super(id,name)\n        this.language = language\n    }\n\n\n}\n\nlet empleado1 = new Employee(1234,\"Pepe\");\nlet empleado2 = new Employee(6789,\"María\");\n\nconsole.log(empleado1);\nconsole.log(empleado1.getInfo());\n\nlet manager1 = new Manager(333,\"Juan\",37)\nconsole.log(manager1);\n\nlet projectManager1 = new ProjectManager(555,\"Lydia\",7)\nconsole.log(projectManager1);\n\nlet programmer1 = new Programmer(888,\"Pedro\",\"Java Script\")\nconsole.log(programmer1);\n\n\n// Agregamos empleados al manager1 y al projectManager1\nmanager1.empleadosAsignados.push(empleado1);\nmanager1.empleadosAsignados.push(empleado2);\nconsole.log(manager1.empleadosAsignados);\n\n// Mostramos por pantalla los empleados a cargo del manager1\nfor (const empleado of manager1.empleadosAsignados){\n    console.log(empleado.getInfo());\n}"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/Pancratzia.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n\n/*******************PARTE 1*******************/\n\n/* Definición de la superclase Animal */\n\nclass Animal {\n  constructor(sound) {\n    this._sound = sound;\n  }\n\n  makeSound() {\n    console.log(this._sound);\n  }\n}\n\n/* Definición de las subclases Perro*/\nclass Dog extends Animal {\n  constructor(breed) {\n    super(\"Guaugau\");\n    this._breed = breed;\n  }\n\n  makeSound() {\n    console.log(`Hi! I'm a dog. My breed is ${this._breed}. And my sound is: `);\n    super.makeSound();\n  }\n}\n\n/* Definición de las subclases Gato */\nclass Cat extends Animal {\n  constructor(favFood) {\n    super(\"Miau\");\n    this._favFood = favFood;\n  }\n\n  makeSound() {\n    console.log(`Hi! I'm a cat. My favorite food is ${this._favFood}. And my sound is: `);\n    super.makeSound();\n  }\n}\n\n// Objetos de perro y gato\nconst dog = new Dog(\"Boxer\");\ndog.makeSound();\n\nconst cat = new Cat(\"Tuna\");\ncat.makeSound();\n\n/*******************EJERCICIO EXTRA*******************/\n\nclass Employee {\n    constructor(name) {\n        this.id = Math.floor(Math.random() * 1000) + 1;\n        this.name = name;\n    }\n}\n\nclass Manager extends Employee {\n    constructor(name, department) {\n        super(name);\n        this.department = department;\n        this.employeesUnderManagement = [];\n    }\n\n    assignEmployee(employee) {\n        this.employeesUnderManagement.push(employee);\n    }\n}\n\nclass ProjectManager extends Manager {\n    constructor(name, department, projects) {\n        super(name, department);\n        this.projects = projects;\n    }\n\n    assignProject(project) {\n        this.projects.push(project);\n    }\n}\n\nclass Programmer extends Employee {\n    constructor(name, language) {\n        super(name);\n        this.language = language;\n    }\n\n    develop() {\n        console.log(`${this.name} is developing in ${this.language}.`);\n    }\n}\n\n\nconst manager1 = new Manager('Arthuro Dugarte', 'Development');\nconst projectManager1 = new ProjectManager('Laura Ortega', 'Development', ['Project A']);\nconst programmer1 = new Programmer('Tiffany Ortega', 'JavaScript');\n\nmanager1.assignEmployee(projectManager1);\nprojectManager1.assignEmployee(programmer1);\n\nconsole.log(manager1);\nconsole.log(projectManager1);\nconsole.log(programmer1);\n\nprogrammer1.develop();\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/RaulDoezon.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n*/\n\nconsole.log(\"+++++++++ EJERCICIO +++++++++\");\nclass Animal {\n  constructor(animalName, animalSound) {\n    this.animalName = animalName;\n    this.animalSound = animalSound;\n  }\n\n  showAnimal() {\n    console.log(`Soy un ${this.animalName}.`);\n  }\n}\n\nclass Perro extends Animal {\n  constructor(animalName, animalSound) {\n    super(animalName, animalSound);\n  }\n\n  showSound() {\n    console.log(`El sonido que emito es un ${this.animalSound}.`);\n  }\n}\n\nclass Gato extends Animal {\n  constructor(animalName, animalSound) {\n    super(animalName, animalSound);\n  }\n\n  showSound() {\n    console.log(`El sonido que emito es un ${this.animalSound}.`);\n  }\n}\n\nlet perro = new Perro(\"perro\", \"ladrido\");\nperro.showAnimal();\nperro.showSound();\nlet gato = new Gato(\"gato\", \"maullido\");\ngato.showAnimal();\ngato.showSound();\n\nconsole.log(\"\\n+++++++++ DIFICULTAD EXTRA +++++++++\");\nclass Employees {\n  constructor(employeeId, employeeName) {\n    this.employeeId = employeeId;\n    this.employeeName = employeeName;\n    this.employeesInCharge = [];\n  }\n\n  add(employee) {\n    this.employeesInCharge.push(employee);\n  }\n\n  showEmployees() {\n    for (let index = 0; index < this.employeesInCharge.length; index++) {\n      const theEmployee = this.employeesInCharge[index];\n      console.log(theEmployee.employeeName);\n    }\n  }\n}\n\nclass Manager extends Employees {\n  constructor(employeeId, employeeName) {\n    super(employeeId, employeeName);\n  }\n\n  manageGeneral() {\n    console.log(`ID: ${this.employeeId}. ${this.employeeName} está a cargo de todos los proyectos activos.`);\n  }\n}\n\nclass ProjectManager extends Employees {\n  constructor(employeeId, employeeName, areaName) {\n    super(employeeId, employeeName);\n    this.areaName = areaName;\n  }\n\n  manageArea() {\n    console.log(`ID: ${this.employeeId}. ${this.employeeName} está manejando el área de ${this.areaName}.`);\n  }\n}\n\nclass Programmer extends Employees {\n  constructor(employeeId, employeeName, projectName) {\n    super(employeeId, employeeName, projectName);\n    this.projectName = projectName;\n  }\n\n  project() {\n    console.log(`ID: ${this.employeeId}. ${this.employeeName}  está desarrollando el proyecto de ${this.projectName}.`);\n  }\n}\n\nlet manager = new Manager(\"05\", \"Fabián\");\nlet projectManager1 = new ProjectManager(\"33\", \"Juan\", \"Diseño de niveles\");\nlet projectManager2 = new ProjectManager(\"19\" ,\"Ana\", \"Programación\");\nlet programmer1 = new Programmer(\"03\", \"Raúl\", \"Metroid 6\");\nlet programmer2 = new Programmer(\"20\", \"Luis\", \"Resident Evil: Code Veronica - Remake\");\n\nmanager.manageGeneral();\nmanager.add(projectManager1);\nmanager.add(projectManager2);\n\nprojectManager1.manageArea();\nprojectManager1.add(programmer1);\n\nprojectManager2.manageArea();\nprojectManager2.add(programmer2);\n\nprogrammer1.project();\nprogrammer2.project();\n\nconsole.log(\"\\nEmpleados a cargo del Gerente:\");\nmanager.showEmployees();\nconsole.log(\"\\nEmpleados a cargo del Gerente de Proyectos:\");\nprojectManager1.showEmployees();\nprojectManager2.showEmployees();\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/RicJDev.js",
    "content": "console.log('\\n---HERENCIA--');\nclass Animal {\n\tconstructor(nombre, sonido) {\n\t\tthis.nombre = nombre;\n\t\tthis.sonido = sonido;\n\t}\n\temiteSonido() {\n\t\tif (this.sonido != null) {\n\t\t\tconsole.log(this.sonido);\n\t\t}\n\t}\n}\n\nclass Gato extends Animal {\n\tconstructor(nombre, sonido) {\n\t\tsuper(nombre, sonido);\n\t\tthis.sonido = 'Miau!';\n\t}\n}\n\nclass Perro extends Animal {\n\tconstructor(nombre, sonido) {\n\t\tsuper(nombre, sonido);\n\t\tthis.sonido = 'Guau!';\n\t}\n}\n\nlet = habla = (Animal) => {\n\tAnimal.emiteSonido();\n};\n\nconsole.log('\\nA partir de una clase creamos un animal');\nlet miAnimal = new Animal('Ter');\nconsole.log(miAnimal);\n\nmiAnimal.emiteSonido();\n\nconsole.log('\\nHeredando sus propiedades creamos un perro');\nlet miPerro = new Perro('Ferr');\nconsole.log(miPerro);\n\nconsole.log('\\nHeredando las propiedades de animal también creamos un gato');\nlet miGato = new Gato('Fran');\nconsole.log(miGato);\n\nconsole.log(\n\t'\\nEn la clase animal almacenamos un método para que el animal emita sonido, el cual es heredado a perro y gato'\n);\nmiPerro.emiteSonido();\nmiGato.emiteSonido();\n\nconsole.log(\n\t'\\nTambién creamos una función que le dice a los animales que \"hablen\", es decir, que emitan su sonido'\n);\nhabla(miPerro);\nhabla(miGato);\n\nconsole.log('\\n---DIFICULTAD EXTRA---');\nclass Empleado {\n\tconstructor(cargo, nombre, id, aSuCargo = []) {\n\t\tthis.cargo = cargo;\n\t\tthis.nombre = nombre;\n\t\tthis.id = id;\n\t\tthis.aSuCargo = aSuCargo;\n\t}\n\n\ttrabaja() {\n\t\tconsole.log(`\\n${this.nombre} está trabajando...`);\n\t}\n\n\tverCredencial() {\n\t\tconsole.log(\n\t\t\t`\\n${this.nombre} posee la credencial: #${this.id}\\nCargo: ${this.cargo}`\n\t\t);\n\t}\n\n\tverCargaDeEmpleados() {\n\t\tif (this.aSuCargo.length > 0) {\n\t\t\tconsole.log(\n\t\t\t\t`\\n${this.nombre} tiene ${this.aSuCargo.length} empleado(s) a su cargo:`\n\t\t\t);\n\t\t\tfor (let i = 0; i < this.aSuCargo.length; i++) {\n\t\t\t\tconsole.log(`-${this.aSuCargo[i]}`);\n\t\t\t}\n\t\t} else {\n\t\t\tconsole.log(`\\n${this.nombre} no tiene empleados a su cargo`);\n\t\t}\n\t}\n}\n\nclass Gerente extends Empleado {\n\tconstructor(nombre, id, aSuCargo, cargo) {\n\t\tsuper(cargo, nombre, id, aSuCargo);\n\t\tthis.cargo = 'Gerente';\n\t}\n\n\tasignarProyecto(Empleado, proyecto) {\n\t\tconsole.log(\n\t\t\t`\\n${this.nombre} le asignó el proyecto \\\"${proyecto}\\\" a ${Empleado.nombre}`\n\t\t);\n\t\tEmpleado.proyectoActual = proyecto;\n\t\tthis.aSuCargo.push(Empleado.nombre);\n\t\tthis.aSuCargo = new Set(this.aSuCargo);\n\t\tthis.aSuCargo = Array.from(this.aSuCargo);\n\t}\n\n\tcancelarProyecto(Empleado) {\n\t\tif (Empleado.proyectoActual != null) {\n\t\t\tconsole.log(\n\t\t\t\t`\\n${this.nombre} ha cancelado el proyecto \\\"${Empleado.proyectoActual}\\\" asignado a ${Empleado.nombre}`\n\t\t\t);\n\t\t\tEmpleado.proyectoActual = null;\n\t\t\tthis.aSuCargo.splice(this.aSuCargo.indexOf(Empleado.nombre), 1);\n\t\t} else {\n\t\t\tconsole.log(`\\n${Empleado.nombre} no tiene ningún proyecto asignado`);\n\t\t}\n\t}\n}\n\nclass GerenteDeProyecto extends Empleado {\n\tconstructor(nombre, id, proyectoActual, aSuCargo, cargo) {\n\t\tsuper(cargo, nombre, id, aSuCargo);\n\t\tthis.cargo = 'Gerente de proyecto';\n\t\tthis.proyectoActual = proyectoActual;\n\t}\n\n\tsumarAlEquipo(Empleado) {\n\t\tconsole.log(\n\t\t\t`\\n${this.nombre} ha pedido a ${Empleado.nombre} que se una a su equipo de desarrollo`\n\t\t);\n\t\tthis.aSuCargo.push(Empleado.nombre);\n\t\tthis.aSuCargo = new Set(this.aSuCargo);\n\t\tthis.aSuCargo = Array.from(this.aSuCargo);\n\t}\n\n\tretirarDelEquipo(Empleado) {\n\t\tif (this.aSuCargo.includes(Empleado.nombre)) {\n\t\t\tconsole.log(\n\t\t\t\t`\\n${this.nombre} ha pedido a ${Empleado.nombre} que se retire de su equipo de desarrollo`\n\t\t\t);\n\t\t\tthis.aSuCargo.splice(this.aSuCargo.indexOf(Empleado.nombre), 1);\n\t\t} else {\n\t\t\tconsole.log(\n\t\t\t\t`\\n${Empleado.nombre} no está en la carga de epleados de ${this.nombre}`\n\t\t\t);\n\t\t}\n\t}\n\n\tasignarTareas(Empleado, tarea) {\n\t\tif (this.aSuCargo.includes(Empleado.nombre)) {\n\t\t\tif (this.proyectoActual != null) {\n\t\t\t\tconsole.log(\n\t\t\t\t\t`\\n${this.nombre} le encomendó ${tarea} a ${Empleado.nombre} para su proyecto \\\"${this.proyectoActual}\\\"`\n\t\t\t\t);\n\t\t\t\tEmpleado.tareaActual = tarea;\n\t\t\t} else {\n\t\t\t\tconsole.log(\n\t\t\t\t\t`\\n${this.nombre} no puede asignar tareas si no está trabajando en ningún proyecto`\n\t\t\t\t);\n\t\t\t}\n\t\t} else {\n\t\t\tconsole.log(\n\t\t\t\t`\\n${this.nombre} debe incuir a ${Empleado.nombre} en el equipo para enomendarle tareas`\n\t\t\t);\n\t\t}\n\t}\n\n\tquitarTareas(Empleado) {\n\t\tif (this.aSuCargo.includes(Empleado.nombre)) {\n\t\t\tif (Empleado.tareaActual != null) {\n\t\t\t\tconsole.log(\n\t\t\t\t\t`\\n${this.nombre} le ha quitado a ${Empleado.nombre} la tarea ${Empleado.tareaActual}`\n\t\t\t\t);\n\t\t\t\tEmpleado.tareaActual = null;\n\t\t\t} else {\n\t\t\t\tconsole.log(`\\n${Empleado.nombre} no tiene tareas pendientes`);\n\t\t\t}\n\t\t} else {\n\t\t\tconsole.log(\n\t\t\t\t`\\nEste empleado no pertenece a la carga de empleados de ${this.nombre}. No se cambiarán sus tareas pendientes`\n\t\t\t);\n\t\t}\n\t}\n}\n\nclass Programador extends Empleado {\n\tconstructor(nombre, id, lenguajes, tareaActual, cargo) {\n\t\tsuper(cargo, nombre, id);\n\t\tthis.lenguajes = lenguajes;\n\t\tthis.tareaActual = tareaActual;\n\t\tthis.cargo = 'Programador';\n\t}\n\n\tconcluirTarea() {\n\t\tif (this.tareaActual != null) {\n\t\t\tconsole.log(\n\t\t\t\t`\\n${this.nombre} ha terminado su tarea actual: ${this.tareaActual}`\n\t\t\t);\n\t\t\tthis.tareaActual = null;\n\t\t} else {\n\t\t\tconsole.log(`\\n${this.nombre} no tiene tareas asignadas`);\n\t\t}\n\t}\n\n\tprogramar() {\n\t\tconsole.log(`\\n${this.nombre} está programando...`);\n\t}\n\n\tverCargaDeEmpleados() {\n\t\tconsole.log(`\\n${this.nombre} no puede tener empleados a su cargo`);\n\t}\n}\n\nconsole.log(\n\t'\\nHemos simulado la jerarquía de una empresa de desarrollo. Para ello creamos una súper clase \"Empleados\", de la cual heredan sus propiedades las clases \"Gerente\", \"GerenteDeProyecto\" y \"Programador\", cada una con métodos específicos según su cargo'\n);\n\n//Gerente del área de desarrollo web\n\nlet manager = new Gerente('Peter', 1632);\n\n//Gerentes de proyecto\n\nlet projectManager1 = new GerenteDeProyecto('Alicia', 1390);\nlet projectManager2 = new GerenteDeProyecto('Jaime', 1001);\n\n//Equipo de programadores\n\nlet progamer1 = new Programador('Alex', 1200, ['Python', 'Java', 'Php']);\nlet progamer2 = new Programador('Erika', 1435, ['Kotlin', 'Swift']);\nlet progamer3 = new Programador('Fabian', 2345, ['Python', 'TypeScript']);\nlet progamer4 = new Programador('Ric', 1437, ['JavaScript', 'Html/Css', 'C++']);\n\n//Aquí me divertí un rato creando y probando métodos\nconsole.log(\n\t'\\nHe creado unos cuantos objetos derivados de estas clases para probar y añadir métodos'\n);\n\nmanager.verCredencial();\n\nprojectManager1.verCredencial();\n\nprogamer4.verCredencial();\n\nmanager.asignarProyecto(projectManager1, 'Calculadora Web personalizable');\n\nprojectManager1.sumarAlEquipo(progamer4);\nprojectManager1.sumarAlEquipo(progamer1);\nprojectManager1.asignarTareas(progamer4, 'elaborar los ficheros de Html y Css');\nprojectManager1.asignarTareas(progamer1, 'programar la interactividad');\nprojectManager1.verCargaDeEmpleados();\n\nmanager.cancelarProyecto(projectManager1);\n\nprojectManager1.asignarTareas(progamer4, 'elaborar los ficheros de Html y Css');\n\nprogamer4.concluirTarea();\n\nmanager.asignarProyecto(projectManager2, 'Tienda online');\n\nprojectManager2.sumarAlEquipo(progamer1);\nprojectManager2.sumarAlEquipo(progamer2);\nprojectManager2.sumarAlEquipo(progamer3);\nprojectManager2.asignarTareas(progamer3, 'organizar el menú de interacción');\nprojectManager2.sumarAlEquipo(progamer4);\nprojectManager2.verCargaDeEmpleados();\n\nlet todosLosEmpleados = [\n\tprojectManager2,\n\tprogamer1,\n\tprogamer2,\n\tprogamer3,\n\tprogamer4,\n];\nfor (let i = 0; i < todosLosEmpleados.length; i++) {\n\ttodosLosEmpleados[i].trabaja();\n}\n\nprogamer3.concluirTarea();\n\nmanager.cancelarProyecto(projectManager2);\n\nprojectManager2.retirarDelEquipo(progamer1);\nprojectManager2.retirarDelEquipo(progamer2);\nprojectManager2.retirarDelEquipo(progamer3);\nprojectManager2.retirarDelEquipo(progamer4);\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/Sac-Corts.js",
    "content": "// Exercise\nclass Animal {\n    constructor(name) {\n        this.name = name;\n    }\n\n    sound() {\n        console.log(`${this.name} makes a sound`);\n    }\n}\n\nclass Dog extends Animal {\n    constructor(name) {\n        super(name);\n    }\n\n    sound() {\n        console.log('gua gua gua!');\n    }\n}\n\nclass Cat extends Animal {\n    constructor(name) {\n        super(name);\n    }\n\n    sound() {\n        console.log('miau miau miau!')\n    }\n}\n\nfunction makeASound(animal) {\n    animal.sound();\n}\n\nconst myDog = new Dog('Junior');\nconst myCat = new Cat ('Luna');\n\nmakeASound(myDog);\nmakeASound(myCat);\n\n// Extra Exercise //\nclass Employee {\n    constructor(name, id) {\n        this.name = name;\n        this.id = id;\n        this.employeesInCharge = [];\n    }\n\n    addEmployee(employee) {\n        this.employeesInCharge.push(employee);\n    }\n\n    showInformation() {\n        console.log(`ID: ${this.id}`);\n        console.log(`Name: ${this.name}`);\n        if (this.employeesInCharge.length > 0) {\n            console.log(\"Employees in charge:\");\n            this.employeesInCharge.forEach((employee) => {\n                employee.showInformation();\n            });\n        } \n    }\n}\n\nclass Manager extends Employee { \n    constructor(name, id, deparment) {\n        super(name, id);\n        this.deparment = deparment;\n    }\n\n    assignEmployee(employee) {\n        this.addEmployee(employee);\n    }\n\n    showInformation() {\n        super.showInformation();\n        console.log(`Deparment: ${this.deparment}`);\n    }\n}\n\nclass ProjectManager extends Manager {\n    constructor(name, id, deparment, currentProject) {\n        super(name, id, deparment);\n        this.currentProject = currentProject; \n    }\n    \n    assignProject(project) {\n        this.currentProject = project;\n    }\n\n    showInformation() {\n        super.showInformation();\n        console.log(`Current Project: ${this.currentProject}`);\n    } \n}\n\nclass Developer extends Employee {\n    constructor(name, id, languages, level) {\n        super(name, id);\n        this.languages = languages;\n        this.level = level;\n    }\n\n    writeCode() {\n        console.log(`${this.name} is writing code in ${this.languages.join(\", \")}`);\n    }\n\n    showInformation() {\n        super.showInformation()\n        console.log(`Programming languages: ${this.languages.join(\", \")}`);\n        console.log(`Level: ${this.level}`);\n    }\n}\n\nconst developer1 = new Developer('Angelo', '3', ['Python, JavaScript, Java, C'], 'Senior');\nconst developer2 = new Developer('Isaac', '4', ['Python, JavaScript'], 'Junior');\nconst projectManager = new ProjectManager('Luisa', '2', 'Web Development', 'Project IG');\nconst manager = new Manager('Luis', '1', 'IT');\n\nmanager.assignEmployee(developer1);\nprojectManager.assignEmployee(developer2);\nmanager.assignEmployee(projectManager);\nmanager.showInformation();\ndeveloper2.writeCode();\nprojectManager.assignProject('Project X');\nmanager.showInformation();"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/adrs1166ma.js",
    "content": "/*\nEJERCICIO:\nExplora el concepto de herencia según tu lenguaje. Crea un ejemplo que\nimplemente una superclase Animal y un par de subclases Perro y Gato,\njunto con una función que sirva para imprimir el sonido que emite cada Animal.\n\nDIFICULTAD EXTRA (opcional):\nImplementa la jerarquía de una empresa de desarrollo formada por Empleados que\npueden ser Gerentes, Gerentes de Proyectos o Programadores.\nCada empleado tiene un identificador y un nombre.\nDependiendo de su labor, tienen propiedades y funciones exclusivas de su\nactividad, y almacenan los empleados a su cargo.\n*/\n// 🔥 Superclase Animal\nclass Animal {\n    constructor(nombre) { this.nombre = nombre }\n\n    // Método genérico para emitir sonido\n    emitirSonido() {\n        return \"Este animal no tiene un sonido definido.\"\n    }\n}\n\n// 🔥 Subclase Perro\nclass Perro extends Animal {\n    constructor(nombre) {\n        super(nombre); // Llama al constructor de la superclase\n    }\n\n    // Sobrescribe el método emitirSonido\n    emitirSonido() {\n        return \"Guau guau!\";\n    }\n}\n\n// 🔥 Subclase Gato\nclass Gato extends Animal {\n    constructor(nombre) {\n        super(nombre); // Llama al constructor de la superclase\n    }\n\n    // Sobrescribe el método emitirSonido\n    emitirSonido() {\n        return \"Miau miau!\";\n    }\n}\n\n// 🔥 Función para imprimir el sonido de un animal\nfunction imprimirSonido(animal) {\n    console.log(`${animal.nombre} dice: ${animal.emitirSonido()}`);\n}\n\n\nconst miPerro = new Perro(\"Camilo\");\nconst miGato = new Gato(\"Reina\");\n\nimprimirSonido(miPerro); // Camilo dice: Guau guau!\nimprimirSonido(miGato);  // Reina dice: Miau miau!\n\n\n// 🔥 Extra\n\n// Clase base Empleado\nclass Empleado {\n    constructor(id, nombre) {\n        this.id = id;\n        this.nombre = nombre;\n    }\n\n    mostrarInfo() {\n        return `ID: ${this.id}, Nombre: ${this.nombre}`;\n    }\n}\n\n// Subclase Gerente\nclass Gerente extends Empleado {\n    constructor(id, nombre) {\n        super(id, nombre);\n        this.empleadosACargo = [];\n    }\n\n    // Añadir empleado a su cargo\n    agregarEmpleado(empleado) {\n        this.empleadosACargo.push(empleado);\n    }\n\n    // Mostrar empleados a su cargo\n    mostrarEmpleadosACargo() {\n        if (this.empleadosACargo.length === 0) {\n            return `${this.nombre} no tiene empleados a su cargo.`;\n        }\n        const listaEmpleados = this.empleadosACargo.map(emp => emp.mostrarInfo()).join(\"\\n\");\n        return `Empleados a cargo de ${this.nombre}:\\n${listaEmpleados}`;\n    }\n}\n\n// Subclase Gerente de Proyectos\nclass GerenteProyecto extends Empleado {\n    constructor(id, nombre, proyecto) {\n        super(id, nombre);\n        this.proyecto = proyecto;\n    }\n\n    // Supervisar proyectos\n    supervisarProyecto() {\n        return `${this.nombre} está supervisando el proyecto \"${this.proyecto}\".`;\n    }\n}\n\n// Subclase Programador\nclass Programador extends Empleado {\n    constructor(id, nombre, lenguaje) {\n        super(id, nombre);\n        this.lenguaje = lenguaje;\n    }\n\n    // Programar\n    programar() {\n        return `${this.nombre} está programando en ${this.lenguaje}.`;\n    }\n}\n\n\nconst gerente = new Gerente(1, \"Juan Pérez\");\nconst gerenteProyecto = new GerenteProyecto(2, \"Ana López\", \"Sistema de Gestión\");\nconst programador1 = new Programador(3, \"Carlos Ramírez\", \"JavaScript\");\nconst programador2 = new Programador(4, \"María González\", \"Python\");\n\ngerente.agregarEmpleado(gerenteProyecto);\ngerente.agregarEmpleado(programador1);\ngerente.agregarEmpleado(programador2);\n\nconsole.log(gerente.mostrarInfo());\nconsole.log(gerente.mostrarEmpleadosACargo());\nconsole.log(gerenteProyecto.supervisarProyecto());\nconsole.log(programador1.programar());\nconsole.log(programador2.programar());"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/agusrosero.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n\n// EJERCICIO:\nclass Animal {\n  constructor() {\n    console.log(\"Clase Animal\");\n  }\n}\n\nconst a1 = new Animal();\n\nclass Perro extends Animal {\n  sonido() {\n    console.log(\"Wuau! Wuau!\");\n  }\n}\n\nconst b1 = new Perro();\nb1.sonido();\n\nclass Gato extends Animal {\n  sonido() {\n    console.log(\"Miau, Miau!\");\n  }\n}\n\nconst c1 = new Gato();\nc1.sonido();\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/airesEsteban.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n\n// EJERCICIO\n\nclass Animal {\n    constructor(nombre) {\n        this.nombre = nombre\n    }\n\n    sonido(){\n        return `${this.nombre} hace un sonido`\n    }\n}\n\nclass Perro extends Animal {\n    constructor(nombre){\n    super(nombre)\n    }\n\n    sonido(){\n        return `${this.nombre} ladra: Guau Guaau!`\n    }\n}\n\nclass Gato extends Animal {\n    constructor(nombre){\n        super(nombre)\n    }\n\n    sonido(){\n        return `${this.nombre} maúlla: Miau Miaau!`\n    }\n}\n\nfunction imprimirSonido(animal){\n    return animal.sonido()\n}\n\nconst miPerro = new Perro(\"Dino\")\nconst miGato = new Gato(\"Démocles\")\n\nconsole.log(imprimirSonido(miPerro))\nconsole.log(imprimirSonido(miGato))\n\n\n// DIFICULTAD EXTRA\n\nclass Empleado {\n    constructor(id, nombre){\n        this.id = id\n        this.nombre = nombre\n    }\n\n    mostrarInfo(){\n        return `ID: ${this.id} , Nombre: ${this.nombre}`\n    }\n}\n\nclass Gerente extends Empleado{\n    constructor(id, nombre){\n        super(id, nombre)\n        this.empleadosCargo = []\n    }\n\n    agregarEmpleadoACargo(empleado){\n        this.empleadosCargo.push(empleado)\n    }\n\n    mostrarEmpleadosACargo(){\n        if (this.empleadosCargo.length === 0){\n            retunr `${this.nombre} no tiene empleados a cargo`\n        }\n        const listaEmpleados = this.empleadosCargo.map(emp => emp.mostrarInfo()).join(\"\\n\")\n        return `Empleados a cargo de ${this.nombre}:\\n${listaEmpleados}`\n    }\n}\n\nclass GerenteProyecto extends Empleado{\n    constructor(id, nombre, proyecto){\n        super(id,nombre)\n        this.proyecto = proyecto\n    }\n\n    supervisarProyecto(){\n        return `${this.nombre} esta supervisando el proyecto ${this.proyecto}`\n    }\n}\n\nclass Programador extends Empleado{\n    constructor(id, nombre, lenguaje){\n        super(id,nombre)\n        this.lenguaje = lenguaje\n    }\n\n    programar(){\n        return `${this.nombre} esta programando en ${this.lenguaje}`\n    }\n}\n\nconst gerente = new Gerente(1,\"juan Peretz\")\nconst gerenteProyecto = new GerenteProyecto(2, \"Raul Lopex\", \"Sistemas de control\")\nconst programador1 = new Programador(3, \"Alvaro Navas\", \"Java\")\nconst programador2 = new Programador(4, \"Julian Lopez\", \"Javascript\")\nconst programador3 = new Programador(5, \"Agustina Romanucci\", \"Python\")\n\ngerente.agregarEmpleadoACargo(gerenteProyecto)\ngerente.agregarEmpleadoACargo(programador1)\n\nconsole.log(gerente.mostrarInfo())\nconsole.log(gerente.mostrarEmpleadosACargo())\nconsole.log(gerenteProyecto.supervisarProyecto())\nconsole.log(programador1.programar())\nconsole.log(programador2.programar())\nconsole.log(programador3.programar())\n\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/alexdevrep.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n\nclass Animal{\n    constructor(nombre){\n        this.nombre=nombre\n    }\n}\n\nclass Perro extends Animal{\n   constructor(nombre,sonido){\n    super(nombre)\n    this.sonido=sonido\n   }\n   ladrar(){\n    return `${this.nombre} está ${this.sonido}`\n   }\n}\n\nclass Gato extends Animal { //Extends palabra reservada para indicar de la clase que se hereda\n    constructor(nombre,sonido){\n        super(nombre) //Ejecutamos el constructor de la clase que heredamos\n        this.sonido=sonido\n    }\n    maullar(){\n        return `${this.nombre} está ${this.sonido}`\n    }\n}\n\n//Instanciamos los objetos\nconst mi_perro= new Perro('Kinder','ladrando') //New palabra reservada para crear objetos de una clase \nconst mi_Gato= new Gato('Manchita','maullando')\n\n//Imprimimos los objetos por pantalla\nconsole.log(mi_perro.ladrar())\nconsole.log(mi_Gato.maullar())\n\n//Dificultad EXTRA\n\nclass Empleados{\n    constructor(id,nombre,equipo){\n        this.id=id\n        this.nombre=nombre\n        this.equipo=equipo || []\n    }\n}\n\nclass Programador extends Empleados{\n    constructor(id,nombre,equipo){\n        super(id,nombre,equipo)\n    }\n    desarrollar(){\n        return `${this.nombre} con el ID ${this.id} está desarrollando una aplicación móvil y lleva a cargo a ${this.equipo.length} personas`\n    }\n}\n\nclass Gerente_Proyecto extends Empleados{\n    constructor(id,nombre,equipo){\n        super(id,nombre,equipo)\n    }\n    supervisar(){\n        return `${this.nombre} con el ID ${this.id} está supervisando que no haya bugs y lleva a cargo a ${this.equipo.length} personas`\n    }\n}\n\n\nclass Gerente extends Empleados{\n    constructor(id,nombre,equipo){\n        super(id,nombre,equipo)\n    }\n    dirigir(){\n        return `${this.nombre} con el ID ${this.id} está decidiendo que característica añadir a la aplicación y lleva a cargo a ${this.equipo.length} personas`\n    }\n}\n\nconst programador1= new Programador('1','Alexdevrep',[])\nconst programador2= new Programador('1','Carlos',[])\nconst gerente_proyecto1= new Gerente_Proyecto('3','Brais',[programador1,programador2])\nconst gerente1=new Gerente('4','MoureDev',[gerente_proyecto1])\n\nconsole.log(programador1.desarrollar())\nconsole.log(programador2.desarrollar())\nconsole.log(gerente_proyecto1.supervisar())\nconsole.log(gerente1.dirigir())"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/bernatcs.js",
    "content": "// ** EJERCICIO\n\nclass Animal { // Definición de la superclase Animal\n    constructor(nombre, edad) {\n        this.nombre = nombre\n        this.edad = edad\n    }\n\n    emitirSonido() {\n        console.log(`${this.nombre} hace un sonido.`);\n    }\n\n    imprimirDatos() {\n        console.log(`Nombre: ${this.nombre}, Edad: ${this.edad}`);\n    }\n}\n\nclass Perro extends Animal { // Definición de la subclase Perro que extiende de Animal\n    constructor(nombre, edad, raza) {\n        super(nombre, edad);\n        this.raza = raza;\n    }\n\n    emitirSonido() {\n        console.log(`${this.nombre} dice: ¡Guau! ¡Guau!`);\n    }\n\n    imprimirDatos() {\n        super.imprimirDatos();\n        console.log(`Raza: ${this.raza}`);\n    }\n}\n\nclass Gato extends Animal { // Definición de la subclase Gato que extiende de Animal\n    constructor(nombre, edad, color) {\n        super(nombre, edad);\n        this.color = color;\n    }\n\n    emitirSonido() {\n        console.log(`${this.nombre} dice: ¡Miau! ¡Miau!`);\n    }\n\n    imprimirDatos() {\n        super.imprimirDatos();\n        console.log(`Color: ${this.color}`);\n    }\n}\n\n// Creación de instancias de las subclases\nlet miPerro = new Perro('Rex', 5, 'Labrador');\nlet miGato = new Gato('Mishi', 3, 'Negro');\n\n// Modificación de atributos\nmiPerro.nombre = 'Max';\nmiGato.edad = 4;\n\n// Uso de métodos\nmiPerro.emitirSonido(); // Max dice: ¡Guau! ¡Guau!\nmiGato.emitirSonido(); // Mishi dice: ¡Miau! ¡Miau!\n\n// Imprimir datos\nmiPerro.imprimirDatos();\n// Nombre: Max, Edad: 5\n// Raza: Labrador\n\nmiGato.imprimirDatos();\n// Nombre: Mishi, Edad: 4\n// Color: Negro\n\n\n// ** DIFICULTAD EXTRA ** -----------------------------------------------------------------------------------------------------------------------------------------------\n\nclass Empleado {\n    constructor(id, nombre) {\n        this.id = id\n        this.nombre = nombre\n    }\n\n    printInfo() {\n        console.log(`Nombre: ${this.nombre}, ID: ${this.id}`)\n    }\n}\n\nclass Gerente extends Empleado {\n    constructor(id, nombre, empleadosACargo) {\n        super(id, nombre)\n        this.empleadosACargo = empleadosACargo\n    }\n\n    planear() {\n        console.log(`${this.nombre} está planeando con los empleados: ${this.empleadosACargo}.`);\n        console.log(`Plan de tarea número: ${Math.floor(Math.random() * 100)}`);\n        // David está planeando con los empleados: Alícia, Pepe. Plan de tarea número: 56.\n    }\n}\n\nclass GerenteDeProyectos extends Empleado {\n    constructor(id, nombre, empleadosACargo) {\n        super(id, nombre);\n        this.empleadosACargo = empleadosACargo;\n    }\n\n    gestionaProyectos() {\n        console.log(`${this.nombre} está gestionando proyectos con los empleados: ${this.empleadosACargo}.`);\n        console.log(`Proyecto número: ${Math.floor(Math.random() * 100)}`);\n        // Eva está gestionando proyectos con los empleados: Carlos,Saray. Proyecto número 98.\n    }\n}\n\nclass Programador extends Empleado {\n    constructor(id, nombre, empleadosACargo) {\n        super(id, nombre);\n        this.empleadosACargo = empleadosACargo;\n    }\n\n    programa() {\n        console.log(`${this.nombre} está programando proyectos con los empleados: ${this.empleadosACargo}.`);\n        console.log(`Proyecto número: ${Math.floor(Math.random() * 100)}`);\n        // Juan está programando proyectos con los empleados: Quique,Pablo. Proyecto número: 88.\n    }\n}\n\n// Datos de ejemplo\nconst empl1 = new Empleado(1, 'Alícia')\nconst empl2 = new Programador(2, 'Pepe')\nconst empl3 = new Programador(3, 'Carlos')\nconst empl4 = new Empleado(4, 'Saray')\nconst empl5 = new Empleado(5, 'Quique')\nconst empl6 = new Empleado(6, 'Pablo')\n\nconst gerente1 = new Gerente(7, 'David', [empl1.nombre, empl2.nombre]);\nconst gerenteDeProyectos = new GerenteDeProyectos(8, 'Eva', [empl3.nombre, empl4.nombre]);\nconst programador = new Programador(9, 'Juan', [empl5.nombre, empl6.nombre]);\n\n// Uso de métodos\n\ngerente1.planear();\ngerenteDeProyectos.gestionaProyectos();\nprogramador.programa();\n\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/caterinarodriguezdev.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n\nclass Animal {\n    \n    constructor(nombre){\n        this.nombre = nombre;\n    }\n\n    print() {\n        console.log('Soy un animal.');\n    }\n}\n\nclass Perro extends Animal {\n\n    constructor(nombre, raza) {\n        super(nombre);\n        this.raza = raza;\n    }\n\n    sonido() {\n       return 'Guau!'\n    }\n\n    print() {\n        console.log(`Este perro se llama ${this.nombre}, es de raza ${this.raza} y hace: ${this.sonido()}`);\n    }\n}\n\nclass Gato extends Animal {\n    \n    constructor(nombre, raza) {\n        super(nombre);\n        this.raza = raza;\n    }\n\n    sonido() {\n        return 'Miaaaau';\n    }\n\n    print() {\n        console.log(`Este gato se llama ${this.nombre}, es de raza ${this.raza} y hace: ${this.sonido()}`);\n    }\n}\n\nconst loki = new Perro('Loki', 'border collie');\nconst gatoConBotas = new Gato('El gato con botas','siames');\n\nloki.print();\ngatoConBotas.print();\n\n// * DIFICULTAD EXTRA (opcional):\n// * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n// * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n// * Cada empleado tiene un identificador y un nombre.\n// * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n// * actividad, y almacenan los empleados a su cargo.\n// */\n\nclass Empleado {\n\n    constructor(id, nombre) {\n        this.id = id;\n        this.nombre = nombre;\n    }\n}\n\nclass Gerente extends Empleado {\n\n    constructor(id, nombre, departamentosSupervisados, empleadosGestionados) {\n        super(id, nombre);\n        this.departamentosSupervisados = departamentosSupervisados;\n        this.empleadosGestionados = empleadosGestionados;\n    }\n\n    listDepartamentos() {\n        return this.departamentosSupervisados;\n    }\n\n    listEmpleadosGestionados() {\n        return this.empleadosGestionados;\n    }\n\n    print() {\n        console.log(`El gerente ${this.nombre} con id ${this.id} supervisa los departamentos: ${this.departamentosSupervisados} y tiene a cargos los siguientes empleados: ${this.empleadosGestionados}.`);\n    }\n}\n\nclass GerenteProyecto extends Empleado {\n\n    constructor(id, nombre, proyectosActivos, metasProyectos) {\n        super(id, nombre);\n        this.proyectosActivos = proyectosActivos;\n        this.metasProyectos = metasProyectos;\n    }\n\n    listProyectosActivos() {\n        return this.proyectosActivos;\n    }\n\n    listMetasProyectos() {\n        return this.metasProyectos;\n    }\n\n    print() {\n        console.log(`El gerente de proyecto ${this.nombre} con id ${this.id} tiene los siguientes proyectos activos: ${this.proyectosActivos} y las siguientes metas: ${this.metasProyectos}.`);\n    }\n}\n\nclass Programadora extends Empleado {\n\n    constructor(id, nombre, tickets, rol) {\n        super(id, nombre);\n        this.tickets = tickets;\n        this.rol = rol;\n    }\n\n    countOpenTickets() {\n        return this.tickets.filter(ticket => ticket.open).length;\n    }\n\n    getRol() {\n        return this.rol;\n    }\n\n    print() {\n        console.log(`El programador ${this.nombre} con id ${this.id} tiene ${this.countOpenTickets()} tickets abiertos. Su rol es ${this.getRol()}.`);\n    }\n}\n\nconst gerente = new Gerente('001', 'Mike', ['contabilidad', 'economato'], ['Robo, Tere, Shin Shan'])\ngerente.print();\n\nconst gerenteProyecto = new GerenteProyecto('002', 'Tere', ['FaceLibro', 'JustCome'], 'completar el 80% de tareas de cada sprint');\ngerenteProyecto.print();\n\nconst programadora = new Programadora('003', 'Caterina', [{id: 't1', open: true}, {id: 't2', open: false}, {id: 't3', open: true}], 'FullStack');\nprogramadora.print();"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/ceciliarava1.js",
    "content": "class Animal {\n\n    constructor(name, color) {\n        this.name = name\n        this.color = color\n    }\n\n    makeNoise() {\n        console.log('Some nice noise')\n    }\n \n}\n\nclass Cat extends Animal {\n\n    makeNoise() {\n        console.log('miau')\n    }\n\n}\n\nclass Dog extends Animal {\n\n    makeNoise() {\n        console.log('guau')\n    }\n\n}\n\n// let newAnimal = new Animal()\n// newAnimal.makeNoise()\n// let newCat = new Cat()\n// newCat.makeNoise()\n// let newDog = new Dog()\n// newDog.makeNoise()\n\n\n class CompanyWorkers {\n\n    constructor(name, id) {\n        this.name = name\n        this.id = id\n    }\n }\n\n class Manager extends CompanyWorkers {\n    constructor(name, id, department) {\n        super(name, id)\n        this.department = department\n        this.workersList = []\n    }\n\n    addWorker(worker) {\n        this.workersList.push(worker)\n    }\n }\n\n class ProjectManager extends CompanyWorkers {\n\n    constructor(name, id, projectName) {\n        super(name, id)\n        this.projectName = projectName\n        this.workersList = []\n    }\n\n    addWorker(worker) {\n        this.workersList.push(worker)\n    }\n }\n\n class Developer extends CompanyWorkers {\n\n    constructor(name, id, programmingLanguage) {\n        super(name, id)\n        this.programmingLanguage = programmingLanguage\n    }\n }\n\n // Manager\nlet company = new CompanyWorkers(\"Company\", 1)\nlet newManager = new Manager('Lucia', 2, 'Marketing')\nlet newProjectManager = new ProjectManager('Fernanda', 3, 'Marketing')\nnewManager.addWorker(newProjectManager)\nconsole.log(newManager.workersList)\n\n// ProjectManager\nlet newDeveloper = new Developer('Juan', 4, 'Python')\nnewProjectManager.addWorker(newDeveloper)\nconsole.log(newProjectManager.workersList)"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/cesar-ch.js",
    "content": "/*\n    #09 HERENCIA Y POLIMORFISMO\n*/\n\nclass Animal {\n    constructor(name) {\n        this.name = name\n    }\n\n    sound() {\n        console.log(`${this.name} makes a sound.`)\n    }\n}\n\nclass Dog extends Animal {\n    constructor(name) {\n        super(name)\n    }\n    sound() {\n        console.log(`Guau, guau!`)\n    }\n}\n\nclass Cat extends Animal {\n    constructor(name) {\n        super(name)\n    }\n    sound() {\n        console.log(`Miau, miau!`)\n    }\n}\n\nconst dog = new Dog('Firulais')\nconsole.log(dog.name)\ndog.sound()\nconst cat = new Cat('Garfield')\nconsole.log(cat.name)\ncat.sound()\n\n/* \n    DIFICULTAD EXTRA \n*/\n\nclass Empleado {\n    constructor(id, nombre) {\n        this.id = id\n        this.nombre = nombre\n        this.empleadosACargo = []\n    }\n    agregarEmpleado(empleado) {\n        this.empleadosACargo.push(empleado)\n    }\n\n    imprimirEmpleados() {\n        console.log(this.empleadosACargo.map(empleado => empleado.nombre));\n    }\n}\n\nclass Gerente extends Empleado {\n    constructor(id, nombre) {\n        super(id, nombre)\n    }\n    actividad() {\n        console.log('Gerente')\n    }\n}\n\nclass GerenteProyecto extends Empleado {\n    constructor(id, nombre) {\n        super(id, nombre)\n    }\n    actividad() {\n        console.log('Gerente de Proyecto')\n    }\n}\n\nclass Programador extends Empleado {\n    constructor(id, nombre) {\n        super(id, nombre)\n    }\n    actividad() {\n        console.log('Programador')\n    }\n}\n\nconst gerente = new Gerente(1, 'Juan')\nconst gerenteProyecto = new GerenteProyecto(2, 'Pedro')\nconst gerenteProyecto2 = new GerenteProyecto(3, 'Luis')\nconst programador = new Programador(4, 'Maria')\nconst programador2 = new Programador(5, 'Ana')\nconst programador3 = new Programador(6, 'Jorge')\nconst programador4 = new Programador(7, 'Carlos')\n\ngerente.agregarEmpleado(gerenteProyecto)\ngerente.agregarEmpleado(gerenteProyecto2)\n\ngerenteProyecto.agregarEmpleado(programador)\ngerenteProyecto.agregarEmpleado(programador2)\ngerenteProyecto2.agregarEmpleado(programador3)\ngerenteProyecto2.agregarEmpleado(programador4)\n\ngerente.imprimirEmpleados()\ngerenteProyecto.imprimirEmpleados()\ngerenteProyecto2.imprimirEmpleados()\nprogramador.imprimirEmpleados()\n\ngerente.actividad()\ngerenteProyecto.actividad()\nprogramador.actividad()"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/christian-jfr.js",
    "content": "// #09 HERENCIA\n\n/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n */\nclass Animal {\n\tconstructor(name) {\n\t\tthis.name = name;\n\t}\n}\n\nclass Dog extends Animal {\n\tconstructor(name) {\n\t\tsuper(name);\n\t}\n\n\tbark() {\n\t\treturn `${this.name} woof woof!`;\n\t}\n}\n\nclass Cat extends Animal {\n\tconstructor(name) {\n\t\tsuper(name);\n\t}\n\n\tmeow() {\n\t\treturn `${this.name} meow!`;\n\t}\n}\n\nconst myDog = new Dog('Fido');\nconst myCat = new Cat('Garfield');\n\nconsole.log(myDog.bark()); // -> Fido woof woof!\nconsole.log(myCat.meow()); // -> Garfield meow!\n\n/**\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n\nclass Employee {\n\tconstructor(id, name) {\n\t\tthis.id = id;\n\t\tthis.name = name;\n\t\tthis.employees = [];\n\t}\n\n\tassignEmployee(employee) {\n\t\tthis.employees.push(employee);\n\t}\n\n\tunderSupervision() {\n\t\tconsole.log(\n\t\t\t`${this.name} has ${this.employees.length} employees under his supervision.`\n\t\t);\n\t}\n}\n\nclass Manager extends Employee {\n\tconstructor(id, name) {\n\t\tsuper(id, name);\n\t}\n\n\thireEmployees() {\n\t\tconst rng = Math.floor(Math.random() * 10 + 1);\n\t\tconsole.log(\n\t\t\t`${this.name} is hiring ${rng} efficient employees and delegating work.`\n\t\t);\n\t}\n}\n\nclass ProjectManager extends Employee {\n\tconstructor(id, name) {\n\t\tsuper(id, name);\n\t}\n\n\tprojectPlanning() {\n\t\tconsole.log(\n\t\t\t`${this.name}  is defining project scope, objectives, and deliverables.`\n\t\t);\n\t}\n}\n\nclass Programmer extends Employee {\n\tconstructor(id, name, language) {\n\t\tsuper(id, name);\n\t\tthis.language = language;\n\t}\n\n\tcode() {\n\t\tconsole.log(`${this.name} is writing code in ${this.language}`);\n\t}\n\n\tassignEmployee() {\n\t\tconsole.log(`${this.name} does not have permissions to assign employees.`);\n\t}\n}\n\nconst luke = new Programmer('2', 'Luke Skywalker', 'TypeScript');\nconsole.log(luke.code()); // -> Luke is writing code in TypeScript\nconsole.log(luke.assignEmployee()); // -> Luke does not have permissions to assign employees\nconsole.log(luke.underSupervision()); // -> Luke has 0 employees under his supervision.\n\nconst vader = new Manager('1', 'Darth Vader');\nconsole.log(vader.underSupervision()); // -> Darth Vader has 0 employees under his supervision.\nconsole.log(vader.assignEmployee(luke)); // -> Darth Vader is hiring 1 efficient employees and delegating work.\nconsole.log(vader.underSupervision()); // -> Darth Vader has 1 employee under his supervision.\nconsole.log(vader.hireEmployees()); // -> Darth Vader is hiring 8 efficient employees and delegating work.\n\nconst han = new ProjectManager('3', 'Han Solo');\nconsole.log(han.underSupervision()); // -> Han Solo has 0 employees under his supervision.\nconsole.log(han.assignEmployee(luke)); // -> Han Solo is hiring 1 efficient employees and delegating work.\nconsole.log(han.underSupervision()); // -> Han Solo has 1 employee under his supervision.\nconsole.log(han.projectPlanning()); // -> Han Solo is defining project scope, objectives, and deliverables.\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/duendeintemporal.js",
    "content": "/* #09 HERENCIA Y POLIMORFISMO */\n// bibliography\n//Professional JavaScript for web developers by Matt Frisbie [Frisbie, Matt] (z-lib.org)\n//GTT\n\n/* In JavaScript, inheritance is a mechanism that allows one object to acquire the properties and methods of another object. This is typically achieved through prototypes, where an object can inherit from another object's prototype, enabling code reuse and the creation of hierarchical relationships between objects. JavaScript supports both classical inheritance (using constructor functions and the `prototype` property) and modern inheritance (using `class` syntax introduced in ES6).\nAll objects have an internal property called [[Prototype]], which is a reference to another object. This prototype chain allows for inheritance, where an object can access properties and methods from its prototype.\nWhen you create an object using a constructor function, you can set its prototype using the prototype property. \nWith the introduction of ES6, JavaScript introduced class syntax, which is essentially syntactic sugar over the existing prototype-based inheritance. When you define a class, JavaScript still uses prototypes behind the scenes*/\n\n// short for console.log()\nlet log = console.log;\n\nwindow.addEventListener('load', ()=>{\n    const body = document.querySelector('body');\n    const title = document.createElement('h1');\n    \n    body.style.setProperty('background', '#000');\n    body.style.setProperty('text-align', 'center');\n    \n    title.textContent = 'Retosparaprogramadores #9.';\n    title.style.setProperty('font-size', '3.5vmax');\n    title.style.setProperty('color', '#fff');\n    title.style.setProperty('line-height', '100vh');\n    \n    body.appendChild(title);\n    \n    setTimeout(()=>{\n    alert('Retosparaprogramadores #9. Please open the Browser Developer Tools.');\n    }, 2000);\n    log( 'Retosparaprogramadores #9'); \n});\n\n\nclass Animal{\n    constructor(name, sound, type){\n        this._name = name || 'set no name';\n        this._sound = sound || 'set no sound';\n        this._type = type || 'set no type';\n    }\n\n    get name(){\n        return this._name; \n    }\n\n    set name(name){\n        this._name = name;\n    }\n\n    speak(){\n        log(`${this.name} the ${this._type} say: ${this._sound}!`)\n    }\n}\n\nclass Dog extends Animal{\n    constructor(name, sound, type){\n      super(name, sound, type);\n    }\n\n    eat(meal){\n        log(`${this._name} the ${this._type} eat some: ${meal}`)\n    }\n\n    move(){\n        log(`the ${this._type} moves it's tail`)\n    }\n}\n\nconst capDog = new Dog('Capitan', 'I guau some pizza', 'Dog');\ncapDog.speak(); // Capitan the Dog say: I guau some pizza!\ncapDog.eat('pizza'); // Capitan the Dog eat some: pizza\ncapDog.move(); // the Dog moves it's tail\n\nclass Cat extends Animal{\n    constructor(name, sound, type){\n        super(name, sound, type);\n    }\n\n    eat(meal){\n        log(`${this._name} the ${this._type} eat some: ${meal}`)\n    }\n\n    move(){\n        log(`the ${this._type} hunt the rat`)\n    }\n\n}\n\nconst blackJack = new Cat('BlackJack', 'Miuauuuu', 'Cat');\nblackJack.speak(); // BlackJack the Cat say: Miuauuuu!\nblackJack.eat('rat snack'); // BlackJack the Cat eat some: rat snack\nblackJack.move(); // the Cat hunt the rat\n\n//Note: is interesting know that we can use variables like key-value assign to object properties, this also work with functions, see:\n\nconst makePerson = (name, age, email)=> {\n    return { name, age, email };\n}\nconst person = makePerson('Angy', 28, 'badgirl@greenhouse.net');\nlog(person); // { name: \"Angy\", age: 28, email: \"badgirl@greenhouse.net\" }\n\n//using destructuring\nlet {name: personName, age: personAge, email: personEmail, personJob = 'Web Developer'} = person;\nlog(personAge); // 28\nlog(personJob)// Web Developer\n\n\nclass User {\n    constructor(id, name, email, country) {\n        try {\n            this._id = this.setId(id);\n            this._name = this.setName(name);\n            this._email = this.setEmail(email);\n            this._country = this.setCountry(country);\n            this.validateProperties(); // Validate properties before freezing or sealing\n            //Object.seal(this); // Seal the object to prevent further properties deletions\n        } catch (error) {\n            console.error('Error creating User:', error.message);\n            // Handle the error as needed (e.g., set default values, rethrow, etc.)\n        }\n    }\n\n    get id() {\n        return this._id;\n    }\n\n    get name() {\n        return this._name;\n    }\n\n    get email() {\n        return this._email;\n    }\n\n    get country() {\n        return this._country;\n    }\n\n    set id(id) {\n        this._id = this.setId(id);\n    }\n\n    set name(name) {\n        this._name = this.setName(name);\n    }\n\n    set email(email) {\n        this._email = this.setEmail(email);\n    }\n\n    set country(country) {\n        this._country = this.setCountry(country);\n    }\n\n    setId(id) {\n        const idString = String(id);\n        const maxLength = 15;\n\n        if (idString.length > maxLength) {\n            throw new Error(`ID must be at most ${maxLength} characters long.`);\n        }\n\n        return idString;\n    }\n\n    setName(name) {\n        const nameString = String(name);\n        const maxLength = 35;\n\n        if (nameString.length > maxLength) {\n            throw new Error(`Name must be at most ${maxLength} characters long.`);\n        }\n\n        return nameString;\n    }\n\n    setEmail(email) {\n        const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[a-zA-Z]{2,}(\\.[a-zA-Z]{2,})?$/;\n\n        if (!emailRegex.test(email)) {\n            throw new Error('Invalid email address format.');\n        }\n\n        return email;\n    }\n\n    setCountry(country) {\n        const countryString = String(country);\n        const maxLength = 35;\n\n        if (countryString.length > maxLength) {\n            throw new Error(`Country must be at most ${maxLength} characters long.`);\n        }\n\n        return countryString;\n    }\n\n    validateProperties() {\n        if (!this._id || !this._name || !this._email || !this._country) {\n            throw new Error('All properties must be set before freezing the object.');\n        }\n    }\n\n    userData() {\n        return { id: this._id, name: this._name, email: this._email, country: this._country };\n    }\n}\n\n\ntry {\n    let sussy = new User('0067', 'Sussan', 'sussy45@something.dt', 'Canada');\n    console.log(sussy.userData());\n} catch (error) {\n    console.error('Failed to create user:', error.message);\n}\n\n//Note: if we use a number to set the value for id 0067 becomes 55 cause is turned to a decimal value \n\nclass SuperUser extends User{\n    constructor(id, name, email, country){\n        super(id, name, email, country);\n        this.permission = true;\n    }\n\n        hasPermission() {\n            return this.permission;\n        }\n    \n        displayUserInfo() {\n            const userInfo = this.userData();\n            return `${userInfo.name} has permission: ${this.hasPermission()}`;\n        }\n}\n\nconst niko = new SuperUser('001', 'Niko', 'duendeintemporal@hotmail.com', 'Venezuela');\nniko.country = 'undefined'; \nlog(niko._id); // 001\nlog(niko.country) // undefined\nlog(niko.permission); // true\nlog(niko.userData()); // { id: \"001\", name: \"Niko\", email: \"duendeintemporal@hotmail.com\", country: \"undefined\" }\n\n// Extra Exercises\n\n\nclass Employed {\n    constructor(id, name, occupation) {\n        try {\n            this._id = this.setId(id);\n            this._name = this.setName(name);\n            this._occupation = this.setOccupation(occupation);\n            this.validateProperties();\n        } catch (error) {\n            console.error('Error creating Employed:', error.message);\n            // Handle the error as needed (e.g., set default values, rethrow, etc.)\n        }\n    }\n\n    get id() {\n        return this._id;\n    }\n\n    get name() {\n        return this._name;\n    }\n\n    get occupation() {\n        return this._occupation;\n    }\n\n    set id(id) {\n        this._id = this.setId(id);\n    }\n\n    set name(name) {\n        this._name = this.setName(name);\n    }\n\n    set occupation(occupation) {\n        this._occupation = this.setOccupation(occupation);\n    }\n\n    setId(id) {\n        const idString = String(id);\n        const maxLength = 15;\n\n        if (idString.length > maxLength) {\n            throw new Error(`ID must be at most ${maxLength} characters long.`);\n        }\n\n        return idString;\n    }\n\n    setName(name) {\n        const nameString = String(name);\n        const maxLength = 35;\n\n        if (nameString.length > maxLength) {\n            throw new Error(`Name must be at most ${maxLength} characters long.`);\n        }\n\n        return nameString;\n    }\n\n    setOccupation(occupation) {\n        const occupationStr = String(occupation);\n        const maxLength = 50;\n\n        if (occupationStr.length > maxLength) {\n            throw new Error(`Occupation must be at most ${maxLength} characters long.`);\n        }\n\n        return occupationStr;\n    }\n\n    validateProperties() {\n        if (!this._id || !this._name || !this._occupation) {\n            throw new Error('All properties must be set before freezing the object.');\n        }\n    }\n\n    employedData() {\n        return { id: this._id, name: this._name, occupation: this._occupation };\n    }\n}\n\nclass Developer extends Employed {\n    constructor(id, name, occupation, languages, area) {\n        super(id, name, occupation);\n        this._languages = languages;\n        this._area = area;\n    }\n\n    functions() {\n        log(`Developer ID: ${this._id} | Name: ${this._name} | Occupation: ${this._occupation} | Area: ${this._area} | Languages: ${this._languages.join(', ')}`);\n    }\n}\n\nclass Secretary extends Employed {\n    constructor(id, name, occupation) {\n        super(id, name, occupation);\n    }\n\n    functions() {\n        log(`Secretary ID: ${this._id} | Name: ${this._name} | Occupation: ${this._occupation} | Responsibilities: Administrative operations and user attention.`);\n    }\n}\n\nclass Manager extends Employed {\n    constructor(id, name, occupation, employeds) {\n        super(id, name, occupation);\n        this._employeds = employeds; // Expecting an array of employees\n    }\n\n    functions() {\n        log(`Manager ID: ${this._id} | Name: ${this._name} | Occupation: ${this._occupation} | Supervising Employees: ${this._employeds.join(', ')}`);\n    }\n}\n\nclass GeneralManager extends Manager{\n    constructor(id, name, ocupation, employeds){\n        super(id, name, ocupation, employeds);\n    }\n\n    functions() {\n        log(`General Manager ID: ${this._id} | Name: ${this._name} | Occupation: ${this._occupation} | Supervising Employees: ${this._employeds.join(', ')}`);\n    }\n}\n\nconst s1 = new Secretary('0023', 'Gabriela Mistral', 'Secretary');\nconst d12 = new Developer('0041', 'Niko Zen', 'Web Developer', ['Python, ','JavaScript', 'Rust', 'Ruby', 'Bash']);\nconst m3 = new Manager('0098', 'Patty Smith', 'Manager', [s1.name, d12.name]);\nconst mg2 = new GeneralManager('003', 'Lenny Kravitz', 'General Manager', [m3.name]);\n\nlog(s1.employedData()); // id: \"0023\", name: \"Gabriela Mistral\", occupation: \"Secretary\"\nlog(d12.functions()); // Developer ID: 0041 | Name: Niko Zen | Occupation: Web Developer | Area: undefined | Languages: Python, , JavaScript, Rust, Ruby, Bash\nlog(m3.functions()); // Manager ID: 0098 | Name: Patty Smith | Occupation: Manager | Supervising Employees: Gabriela Mistral, Niko Ze\nlog(mg2.functions()); // General Manager ID: 003 | Name: Lenny Kravitz | Occupation: General Manager | Supervising Employees: Patty Smith\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/emedevelopa.js",
    "content": "class Animal {\n    constructor(animal, name, sound) {\n        this.animal = animal;\n        this.name = name;\n        this.sound = sound;\n    }\n\n    emiteSonido() {\n        console.log(`${this.animal} ${this.name} hace ${this.sound}`);\n    }\n}\n\nclass Perro extends Animal {\n    \n}\nlet perro = new Perro(\"El perro\",\"Pipo\", \"Woof\");\nperro.emiteSonido();\n\nclass Gato extends Animal {\n\n}\nlet gato = new Gato(\"La gata\", \"Misi\", \"meow\");\ngato.emiteSonido();\n\n//\n\nclass Empleado {\n    constructor(cargo, id, name) {\n        this.cargo = cargo;\n        this.id = id;\n        this.name = name;\n    }\n    datos() {\n        console.log(`${this.name} ocupa el cargo de ${this.cargo} y su ID es ${this.id}`);\n    }\n}\n\nclass Gerente extends Empleado {\n    constructor(cargo, id, name, empleadosACargo) {\n        super(cargo, id, name);\n        this.empleadosACargo = empleadosACargo;\n    }\n    aCargo() {\n        console.log(`${this.name} tiene ${this.empleadosACargo} empleados a cargo`);\n    }\n}\n\n\nclass gerenteDeProyectos extends Empleado {\n    constructor(cargo, id, name, proyecto) {\n        super(cargo, id, name);\n        this.proyecto = proyecto;\n    }\n    gestionProyecto() {\n        console.log(`${this.name} esta gestionando ${this.proyecto} proyectos`);\n    }\n}\n\n\nclass Desarrollador extends Empleado {\n    constructor(cargo, id, name, lenguaje) {\n        super(cargo, id, name)\n        this.lenguaje = lenguaje;\n    }\n    code() {\n        console.log(`${this.name} esta usando ${this.lenguaje}`);\n    }\n}\n\nlet gerente = new Gerente(\"gerente\", 1234, \"Roberto\", 13);\ngerente.datos();\ngerente.aCargo();\n\nlet gerenteDeProyecto = new gerenteDeProyectos(\"gerente de proyectos\", 7774, \"Luis\", 3);\ngerenteDeProyecto.datos();\ngerenteDeProyecto.gestionProyecto();\n\nlet desarrollador = new Desarrollador(\"desarrollador\", 6765, \"Benito\", \"Javascript\");\ndesarrollador.datos();\ndesarrollador.code();\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/eulogioep.js",
    "content": "// Ejemplo de implementación del concepto de herencia en JavaScript\n\n// Definición de la clase base (superclase) Animal\nclass Animal {\n    constructor(especie, sonido) {\n      this.especie = especie;\n      this.sonido = sonido;\n    }\n  \n    // Método que muestra el sonido que hace el animal\n    hacerSonido() {\n      return `El ${this.especie} hace: ${this.sonido}`;\n    }\n  }\n  \n  // Definición de la subclase Perro\n  class Perro extends Animal {\n    constructor(nombre, especie, sonido) {\n      super(especie, sonido); // Llamada al constructor de la superclase\n      this.nombre = nombre;\n    }\n  \n    // Método exclusivo de la subclase Perro\n    ladrar() {\n      return `${this.nombre} lanza un ladrido`;\n    }\n  }\n  \n  // Definición de la subclase Gato\n  class Gato extends Animal {\n    constructor(nombre, especie, sonido) {\n      super(especie, sonido); // Llamada al constructor de la superclase\n      this.nombre = nombre;\n    }\n  \n    // Método exclusivo de la subclase Gato\n    maullar() {\n      return `${this.nombre} emite un maullido`;\n    }\n  }\n  \n  // Ejemplo de implementación adicional (dificultad extra)\n  // Definición de la clase base (superclase) Empleado\n  class Empleado {\n    constructor(id, nombre) {\n      this.id = id;\n      this.nombre = nombre;\n    }\n  }\n  \n  // Definición de la subclase Gerente que hereda de Empleado\n  class Gerente extends Empleado {\n    constructor(id, nombre, subordinados) {\n      super(id, nombre);\n      this.subordinados = subordinados;\n    }\n  \n    // Método exclusivo de la subclase Gerente\n    informarSobreSubordinados() {\n      let informacion = `El gerente ${this.nombre} tiene a los siguientes subordinados: \\n`;\n      this.subordinados.forEach((subordinado) => {\n        informacion += ` - ${subordinado.nombre}\\n`;\n      });\n      return informacion;\n    }\n  }\n  \n  // Definición de la subclase GerenteDeProyectos que hereda de Empleado\n  class GerenteDeProyectos extends Empleado {\n    constructor(id, nombre, proyectos) {\n      super(id, nombre);\n      this.proyectos = proyectos;\n    }\n  \n    // Método exclusivo de la subclase GerenteDeProyectos\n    informarSobreProyectos() {\n      let informacion = `El gerente de proyectos ${this.nombre} tiene los siguientes proyectos: \\n`;\n      this.proyectos.forEach((proyecto) => {\n        informacion += ` - ${proyecto}\\n`;\n      });\n      return informacion;\n    }\n  }\n  \n  // Definición de la subclase Programador que hereda de Empleado\n  class Programador extends Empleado {\n    constructor(id, nombre, lenguajes) {\n      super(id, nombre);\n      this.lenguajes = lenguajes;\n    }\n  \n    // Método exclusivo de la subclase Programador\n    informarSobreLenguajes() {\n      let informacion = `El programador ${this.nombre} domina los siguientes lenguajes: \\n`;\n      this.lenguajes.forEach((lenguaje) => {\n        informacion += ` - ${lenguaje}\\n`;\n      });\n      return informacion;\n    }\n  }\n  \n  // Ejemplo de uso\n  let perro = new Perro(\"Lucky\", \"Perro\", \"Gua\");\n  console.log(perro.hacerSonido()); // El Perro hace: Gua\n  console.log(perro.ladrar()); // Lucky lanza un ladrido\n  \n  let gato = new Gato(\"Whiskers\", \"Gato\", \"Miau\");\n  console.log(gato.hacerSonido()); // El Gato hace: Miau\n  console.log(gato.maullar()); // Whiskers emite un maullido\n  \n  let gerente = new Gerente(1, \"Juan Perez\", [new Programador(2, \"Maria Rodriguez\", [\"JavaScript\", \"Python\"])]);\n  console.log(gerente.informarSobreSubordinados());\n  \n  let gerenteProyectos = new GerenteDeProyectos(3, \"Luis Martinez\", [\"Proyecto A\", \"Proyecto B\"]);\n  console.log(gerenteProyectos.informarSobreProyectos());\n  \n  let programador = new Programador(4, \"Karla Sanchez\", [\"JavaScript\", \"Python\"]);\n  console.log(programador.informarSobreLenguajes());"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/garos01.js",
    "content": "// Herencia\n\nclass Animal {\n  constructor(nombre) {\n    this.nombre = nombre;\n  }\n\n  hacerSonido() {\n    // Este método será implementado por las subclases\n  }\n}\n\nclass Perro extends Animal {\n  hacerSonido() {\n    return \"Guau\";\n  }\n}\n\nclass Gato extends Animal {\n  hacerSonido() {\n    return \"Miau\";\n  }\n}\n\nfunction imprimirSonido(animal) {\n  const tipoAnimal = animal.constructor.name;\n  console.log(\n    `${animal.nombre} mi ${tipoAnimal} hace: ${animal.hacerSonido()}`\n  );\n}\n\nconst miPerro = new Perro(\"Buddy\");\nconst miGato = new Gato(\"Whiskers\");\n\nimprimirSonido(miPerro);\nimprimirSonido(miGato);\n\n// Ejercicio extra\n\nclass Empleado {\n  constructor(identificador, nombre) {\n    this.identificador = identificador;\n    this.nombre = nombre;\n  }\n\n  realizarTarea() {\n    // Este método será implementado por las subclases\n  }\n}\n\nclass Gerente extends Empleado {\n  constructor(identificador, nombre, departamento) {\n    super(identificador, nombre);\n    this.departamento = departamento;\n    this.empleadosACargo = [];\n  }\n\n  asignarTarea(tarea) {\n    console.log(`El gerente ${this.nombre} asigna la tarea: ${tarea}`);\n  }\n\n  realizarTarea() {\n    console.log(`El gerente ${this.nombre} está gestionando el departamento.`);\n  }\n}\n\nclass GerenteProyecto extends Gerente {\n  constructor(identificador, nombre, departamento, proyecto) {\n    super(identificador, nombre, departamento);\n    this.proyecto = proyecto;\n  }\n\n  realizarTarea() {\n    console.log(\n      `El gerente de proyecto ${this.nombre} está supervisando el proyecto ${this.proyecto}.`\n    );\n  }\n}\n\nclass Programador extends Empleado {\n  constructor(identificador, nombre, lenguaje) {\n    super(identificador, nombre);\n    this.lenguaje = lenguaje;\n  }\n\n  codificar() {\n    console.log(\n      `El programador ${this.nombre} está codificando en ${this.lenguaje}.`\n    );\n  }\n\n  realizarTarea() {\n    this.codificar();\n  }\n}\n\nconst gerenteJefe = new Gerente(1, \"Ana\", \"Desarrollo\");\nconst gerenteProyecto1 = new GerenteProyecto(\n  2,\n  \"Carlos\",\n  \"Desarrollo\",\n  \"ProyectoX\"\n);\nconst gerenteProyecto2 = new GerenteProyecto(\n  3,\n  \"Diana\",\n  \"Desarrollo\",\n  \"ProyectoY\"\n);\nconst gerenteProyecto3 = new GerenteProyecto(4, \"Eduardo\", \"QA\", \"ProyectoZ\");\nconst programador1 = new Programador(5, \"Fernando\", \"Python\");\nconst programador2 = new Programador(6, \"Gabriela\", \"Java\");\nconst programador3 = new Programador(7, \"Hugo\", \"C++\");\nconst programador4 = new Programador(8, \"Isabel\", \"JavaScript\");\nconst programador5 = new Programador(9, \"Javier\", \"Ruby\");\nconst programador6 = new Programador(10, \"Karen\", \"Swift\");\n\ngerenteJefe.empleadosACargo.push(\n  gerenteProyecto1,\n  gerenteProyecto2,\n  gerenteProyecto3,\n  programador1,\n  programador2,\n  programador3,\n  programador4,\n  programador5,\n  programador6\n);\n\ngerenteJefe.asignarTarea(\"Planificación anual\");\nfor (const empleado of gerenteJefe.empleadosACargo) {\n  empleado.realizarTarea();\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/gianbordon.js",
    "content": "/*\n    * EJERCICIO:\n    * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n    * implemente una superclase Animal y un par de subclases Perro y Gato,\n    * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n    *\n    * DIFICULTAD EXTRA (opcional):\n    * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n    * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n    * Cada empleado tiene un identificador y un nombre.\n    * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n    * actividad, y almacenan los empleados a su cargo.\n */\n\n//\n// HERENCIA \n//\n\n// Superclase Animal\nclass Animal {\n    constructor(nombre){\n        this.nombre = nombre\n    }\n\n    emitirSonido(){\n        console.log(this.nombre + ' hace un sonido')\n    }\n}\n\n// Subclase Perro \nclass Perro extends Animal {\n    emitirSonido(){\n        console.log(this.nombre + ' dice: guau')\n    }\n}\n\n// Subclase Gato \nclass Gato extends Animal {\n    emitirSonido(){\n        console.log(this.nombre + ' dice: miau')\n    }\n}\n\n// Instancio las clases \nconst perro = new Perro('Firulais')\nconst gato = new Gato('Michi')\n\n// LLamo al metodo de la clase y se obversa la herencia del nombre que viene desde el padre Animal \nperro.emitirSonido() \ngato.emitirSonido()  \n\n//\n// EXTRA\n//\n\nclass Empleado {\n    constructor(nombre, id) {\n        this.nombre = nombre\n        this.id = id\n        this.empleadosACargo = []\n    }\n\n    mostrarDatos() {\n        console.log(`- Empleado: ${this.nombre} - ${this.id}`)\n    }\n\n    agregarEmpleadosACargo(empleado) {\n        this.empleadosACargo.push(empleado)\n    }\n\n    listarEmpleadosACargo() {\n        this.empleadosACargo.forEach(e => e.mostrarDatos())\n    }\n}\n\nclass Gerente extends Empleado {\n    constructor(nombre, id, departamento) {\n        super(nombre, id)\n        this.departamento = departamento\n    }\n\n    mostrarDatos() {\n        console.log(`- Gerente: ${this.nombre} - ${this.id} - ${this.departamento}`)\n    }\n}\n\nclass GerenteProyecto extends Empleado {\n    constructor(nombre, id, proyecto) {\n        super(nombre, id)\n        this.proyecto = proyecto\n    }\n\n    cambiarProyecto(nuevoProyecto) {\n        this.proyecto = nuevoProyecto\n    }\n\n    mostrarDatos() {\n        console.log(`- Gerente de Proyecto: ${this.nombre} - ${this.id} - ${this.proyecto}`)\n    }\n}\n\nclass Programador extends Empleado {\n    constructor(nombre, id) {\n        super(nombre, id)\n        this.lenguajes = []\n    }\n\n    agregarLenguaje(lenguaje) {\n        this.lenguajes.push(lenguaje)\n    }\n\n    mostrarDatos() {\n        console.log(`- Programador: ${this.nombre} - ${this.id} - Lenguajes: ${this.lenguajes.join(', ')}`)\n    }\n}\n\n// Crear instancias\nconst gerente = new Gerente('Laura', 1, 'Tecnología')\nconst gerenteProyecto = new GerenteProyecto('Marcos', 2, 'WebApp 2025')\nconst programador1 = new Programador('Lucía', 3)\nconst programador2 = new Programador('Juan', 4)\n\n// Asignar relaciones y propiedades\ngerente.agregarEmpleadosACargo(gerenteProyecto)\ngerenteProyecto.agregarEmpleadosACargo(programador1)\ngerenteProyecto.agregarEmpleadosACargo(programador2)\nprogramador1.agregarLenguaje('JavaScript')\nprogramador1.agregarLenguaje('Python')\nprogramador2.agregarLenguaje('Java')\ngerenteProyecto.cambiarProyecto('MobileApp 2026')\n\n// Mostrar datos\nconsole.log('📋 Datos del Gerente:')\ngerente.mostrarDatos()\nconsole.log('👥 Empleados a cargo del Gerente:')\ngerente.listarEmpleadosACargo()\n\nconsole.log('📋 Datos del Gerente de Proyecto:')\ngerenteProyecto.mostrarDatos()\nconsole.log('👥 Empleados a cargo del Gerente de Proyecto:')\ngerenteProyecto.listarEmpleadosACargo()\n\nconsole.log('📋 Datos de los Programadores:')\nprogramador1.mostrarDatos()\nprogramador2.mostrarDatos()\n\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/giovanyosorio.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n// clase padre\nclass Animal{\n    constructor(nombre){\n       this.nombre=nombre\n    }\n    emitirSonido() {\n        console.log(\"Este animal hace un sonido\");\n      }\n}\n// clase hija\nclass Perro extends Animal {\n    emitirSonido() {\n      console.log(\"Guau guau\");\n    }\n  }\n  \n  class Gato extends Animal {\n    emitirSonido() {\n      console.log(\"Miau miau\");\n    }\n  }\n\n  function imprimirSonido(animal) {\n    animal.emitirSonido();\n  }\n  \n  // Prueba\n  let perro = new Perro(\"Firulais\");\n  let gato = new Gato(\"Michi\");\n  imprimirSonido(perro); // Guau guau\n  imprimirSonido(gato);  // Miau miau\n\n\n\n  class Empleado {\n    constructor(id, nombre) {\n      this.id = id;\n      this.nombre = nombre;\n    }\n  }\n\n  class Gerente extends Empleado {\n    constructor(id, nombre) {\n      super(id, nombre);\n      this.empleadosACargo = [];\n    }\n  \n    agregarEmpleado(empleado) {\n      this.empleadosACargo.push(empleado);\n    }\n  }\n\n  class GerenteDeProyectos extends Gerente {\n    constructor(id,nombre){\n        super(id,nombre)\n        \n    }\n  }\n  \n\n  class Programador extends Empleado {\n    constructor(id, nombre, lenguaje) {\n      super(id, nombre);\n      this.lenguaje = lenguaje;\n    }\n  }\n\n\nlet gerente = new Gerente(1, \"Ana\");\nlet gerenteProyectos = new GerenteDeProyectos(2, \"Carlos\");\nlet programador = new Programador(3, \"Luis\", \"JavaScript\");\n\ngerente.agregarEmpleado(gerenteProyectos);\ngerente.agregarEmpleado(programador);\n\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/hectorio23.js",
    "content": "\"use strict\";\n\n\n// Definición de la clase Animal\nclass Animal {\n  // Constructor de la clase Animal\n  constructor(sound) {\n    this.sound = sound;\n  }\n\n  // Método que imprime el sonido del animal\n  makeSound() {\n    console.log(this.sound);\n  }\n}\n\n// Definición de la subclase Perro que hereda de Animal\nclass Perro extends Animal {\n  // Constructor de la clase Perro\n  constructor() {\n    // Llamada al constructor de la clase padre (Animal)\n    super(\"Guau\");\n  }\n}\n\n// Definición de la subclase Gato que hereda de Animal\nclass Gato extends Animal {\n  // Constructor de la clase Gato\n  constructor() {\n    // Llamada al constructor de la clase padre (Animal)\n    super(\"Miau\");\n  }\n}\n\n// Función para imprimir el sonido de un animal\nfunction imprimirSonido(animal) {\n  animal.makeSound();\n}\n\n// Definición de la clase Empleado\nclass Empleado {\n  // Constructor de la clase Empleado\n  constructor(id, nombre) {\n    this.id = id;\n    this.nombre = nombre;\n  }\n\n  // Método para obtener el nombre del empleado\n  getNombre() {\n    return this.nombre;\n  }\n\n  // Método para obtener el identificador del empleado\n  getId() {\n    return this.id;\n  }\n\n  // Método para mostrar detalles del empleado\n  mostrarDetalles() {\n    console.log(`ID: ${this.id}, Nombre: ${this.nombre}`);\n  }\n}\n\n// Definición de la subclase Gerente que hereda de Empleado\nclass Gerente extends Empleado {\n  // Constructor de la clase Gerente\n  constructor(id, nombre, departamento) {\n    // Llamada al constructor de la clase padre (Empleado)\n    super(id, nombre);\n    this.departamento = departamento;\n    this.empleadosACargo = [];\n  }\n\n  // Método para agregar empleados a su cargo\n  agregarEmpleado(empleado) {\n    this.empleadosACargo.push(empleado);\n  }\n\n  // Método para mostrar detalles del gerente\n  mostrarDetalles() {\n    super.mostrarDetalles();\n    console.log(`Departamento: ${this.departamento}`);\n    console.log(\"Empleados a cargo:\");\n    this.empleadosACargo.forEach((empleado) => {\n      console.log(`  - ${empleado.getNombre()}`);\n    });\n  }\n}\n\n// Definición de la subclase GerenteProyecto que hereda de Gerente\nclass GerenteProyecto extends Gerente {\n  // Constructor de la clase GerenteProyecto\n  constructor(id, nombre, departamento, proyectos) {\n    // Llamada al constructor de la clase padre (Gerente)\n    super(id, nombre, departamento);\n    this.proyectos = proyectos;\n  }\n\n  // Método para mostrar detalles del gerente de proyecto\n  mostrarDetalles() {\n    super.mostrarDetalles();\n    console.log(\"Proyectos:\");\n    this.proyectos.forEach((proyecto) => {\n      console.log(`  - ${proyecto}`);\n    });\n  }\n}\n\n// Definición de la subclase Programador que hereda de Empleado\nclass Programador extends Empleado {\n  // Constructor de la clase Programador\n  constructor(id, nombre, lenguaje) {\n    // Llamada al constructor de la clase padre (Empleado)\n    super(id, nombre);\n    this.lenguaje = lenguaje;\n  }\n\n  // Método para mostrar detalles del programador\n  mostrarDetalles() {\n    super.mostrarDetalles();\n    console.log(`Lenguaje: ${this.lenguaje}`);\n  }\n}\n\n// Creación de instancias de Perro y Gato\nconst miPerro = new Perro();\nconst miGato = new Gato();\n\n// Imprime el sonido del perro y del gato\nimprimirSonido(miPerro); // Salida esperada: \"Guau\"\nimprimirSonido(miGato); // Salida esperada: \"Miau\"\n\n// Creación de instancias de empleados\nconst gerente1 = new Gerente(1, \"Carlos\", \"Desarrollo\");\nconst gerenteProyecto1 = new GerenteProyecto(2, \"Laura\", \"Desarrollo\", [\n  \"Proyecto A\",\n  \"Proyecto B\",\n]);\nconst programador1 = new Programador(3, \"Ana\", \"JavaScript\");\nconst programador2 = new Programador(4, \"Juan\", \"Python\");\n\n// Agregar empleados a cargo del gerente\ngerente1.agregarEmpleado(gerenteProyecto1);\ngerenteProyecto1.agregarEmpleado(programador1);\ngerenteProyecto1.agregarEmpleado(programador2);\n\n// Mostrar detalles de los empleados\nconsole.log(\"Detalles del gerente:\");\ngerente1.mostrarDetalles();\nconsole.log(\"\\nDetalles del gerente de proyecto:\");\ngerenteProyecto1.mostrarDetalles();\nconsole.log(\"\\nDetalles del programador 1:\");\nprogramador1.mostrarDetalles();\nconsole.log(\"\\nDetalles del programador 2:\");\nprogramador2.mostrarDetalles();\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/jeronimocardu.js",
    "content": "class Animal {\n  constructor(animal) {\n    this.animal = animal\n  }\n  sonido() {\n    return `${this.animal} hace un sonido`\n  }\n}\n\nclass Perro extends Animal {\n  constructor(animal, ruido) {\n    super(animal)\n    this.ruido = ruido\n  }\n  ladra() {\n    return this.sonido() + ' ' + this.ruido\n  }\n}\n\nconst gato = new Animal('gato')\nconst perro = new Perro('Perro', 'Guau')\n\n// console.log(gato.sonido())\n// console.log(perro.ladra())\n\n\n\n\n\n\n\n\nclass Developer {\n  constructor(ident, fullname, language) {\n    this.ident = ident\n    this.fullname = fullname\n    this.language = language\n  }\n  presentation() {\n    return `Hi, my name is ${this.fullname} and my ID is ${this.ident}. I use ${this.language}`\n  }\n}\nclass GerenteProyecto extends Developer {\n  constructor(ident, fullname, language, employees) {\n    super(ident, fullname, language)\n    this.employees = employees\n  }\n  add(employerID) {\n    this.employees.push(employerID)\n  }\n  sendOf(employerID) {\n    this.employees = this.employees.filter((emp) => emp.ident != employerID)\n  }\n  showEmployees() {\n    return this.employees\n  }\n}\nclass Gerente extends GerenteProyecto {\n  constructor(ident, fullname, language, employees) {\n    super(ident, fullname, language, employees)\n  }\n  sendOfAll(exit) {\n    if (exit) this.employees = []\n  }\n}\n\n\n\n\n\n\n\nconst jeronimo = new Developer(1, 'Jeronimo Cardu', 'javascript')\nconst tobias = new Developer(2, 'Tobias Acuña', 'python')\nconst leo = new Developer(3, 'Leonardo Skoliber', 'c')\n\n// console.log(jeronimo.presentation())\n// console.log(tobias.presentation())\n// console.log(leo.presentation())\n\nconst agustin = new GerenteProyecto(4, 'Agustin Botella', 'React Native', [\n  jeronimo,\n  tobias,\n  leo,\n])\n\nconst lara = new Developer(12, 'Lara', 'Kotlin')\n\n// console.log(agustin.presentation())\n// console.log(agustin.showEmployees())\n// agustin.add(lara)\n// agustin.sendOf(2)\n// console.log(agustin.showEmployees())\n\nconst jorge = new Gerente(100, 'Jorge Cardu', 'none', [\n  jeronimo,\n  tobias,\n  leo,\n  lara,\n  agustin,\n])\n\n// console.log(jorge.presentation())\n// console.log(jorge.showEmployees())\n// jorge.sendOf(12)\n// console.log(jorge.showEmployees())\n// jorge.sendOfAll(true)\n// console.log(jorge.showEmployees())\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/jhoshmc.js",
    "content": "/*\n ! EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n*/\n// todo ejercicio\nclass Animal {\n  constructor(nombre) {\n    this._nombre = nombre;\n  }\n  get_Sonido() {}\n}\n\nclass Perro extends Animal {\n  constructor(nombre) {\n    super(nombre);\n  }\n  get_Sonido() {\n    console.log(`${this._nombre}: Guau!`);\n  }\n}\n\nclass Gato extends Animal {\n  constructor(nombre) {\n    super(nombre);\n  }\n  get_Sonido() {\n    console.log(`${this._nombre}: Miau!`);\n  }\n}\n\n//todo extra\n/*\n ! DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n*/\n\nclass Empleado {\n  constructor(id, nombre, cargo) {\n    this._id = id;\n    this._nombre = nombre;\n    this._cargo = cargo;\n  }\n  getInfoEmpleado() {\n    console.log(\n      `\\nEmpleado: ${this._id} : ${this._nombre} : cargo : ${this._cargo}`\n    );\n  }\n}\n\nclass Gerente extends Empleado {\n  constructor(id, nombre, cargo) {\n    super(id, nombre, cargo);\n    this.personal = [];\n  }\n  setAgregarPersonal(nuevoP) {\n    this.personal.push(nuevoP);\n  }\n  getPersonal() {\n    console.log(`\\nGerente: ${this._nombre} con personal a cargo: \\n`);\n    this.personal.forEach((element) => {\n      element.getInfoEmpleado();\n    });\n  }\n}\n\nclass GerenteProyectos extends Empleado {\n  constructor(id, nombre, cargo) {\n    super(id, nombre, cargo);\n    this.equipo = [];\n    this.proyectos = [];\n  }\n  setPersonalAcargo(miembro) {\n    this.equipo.push(miembro);\n  }\n  setProyectos(nombreProyecto) {\n    this.proyectos.push(nombreProyecto);\n  }\n  getEquipo() {\n    console.log(\n      `\\nGerente de proyectos ${this._nombre}: miembros en su equipo:\\n`\n    );\n    this.equipo.forEach((element) => {\n      element.getInfoEmpleado();\n    });\n  }\n  getProyectos() {\n    console.log(\n      `\\nGerente de proyectos ${this._nombre}: proyectos a su cargo:\\n`\n    );\n    this.proyectos.forEach((element) => {\n      console.log(element);\n    });\n  }\n}\n\nclass Programador extends Empleado {\n  constructor(id, nombre, cargo) {\n    super(id, nombre, cargo);\n    this._proyectoEnCurso = \"ninguno\";\n  }\n  setProyecto(proyecto) {\n    this._proyectoEnCurso = proyecto;\n  }\n  getProyectoEnCurso() {\n    console.log(`Programador: ${this._nombre}`);\n    console.log(`proyecto en curso: ${this._proyectoEnCurso}`);\n  }\n}\n//todo ejericico\nfunction ejercicio() {\n  const chester = new Perro(\"Chester\");\n  const lita = new Gato(\"Lita\");\n  chester.get_Sonido();\n  lita.get_Sonido();\n}\n\nejercicio();\n\n// todo extra\n\nfunction extra() {\n  const manuel = new Gerente(\"A125\", \"Manuel Zoto\", \"Gerente\");\n  const jonas = new GerenteProyectos(\n    \"G233\",\n    \"Jonas Marques\",\n    \"Gerente de proyectos\"\n  );\n  const roberto = new Programador(\"P564\", \"Roberto Hernandez\", \"programador\");\n  manuel.getInfoEmpleado();\n  // jonas.getInfoEmpleado();\n  // roberto.getInfoEmpleado();\n  manuel.setAgregarPersonal(jonas);\n  manuel.setAgregarPersonal(roberto);\n  manuel.getPersonal();\n  jonas.setPersonalAcargo(roberto);\n  jonas.setProyectos(\"cambiar color del boton\");\n  jonas.setProyectos(\"reiniciar la pc\");\n  jonas.getEquipo();\n  jonas.getProyectos();\n  roberto.setProyecto(\"cambiar color boton\");\n  roberto.getProyectoEnCurso();\n}\n\nextra();\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/juandaherrera.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n */\n\nclass Animal {\n    constructor(name) {\n        this.name = name;\n    }\n\n    makeSound() {\n        throw new Error(\n            \"Método makeSound() debe ser implementado por subclases\"\n        );\n    }\n}\n\nclass Perro extends Animal {\n    makeSound() {\n        console.log(\"Guauuu\");\n    }\n}\n\nclass Gato extends Animal {\n    makeSound() {\n        console.log(\"Miauu\");\n    }\n}\n\nconst firulais = new Perro(\"Firulais\");\nconst mishi = new Gato(\"Mishi\");\n\nfirulais.makeSound(); // Guauuu\nmishi.makeSound(); // Miauu\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n\n// Simulación simple de generación de UUID en JavaScript\nfunction generateUUID() {\n    return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(\n        /[xy]/g,\n        function (c) {\n            var r = (Math.random() * 16) | 0,\n                v = c === \"x\" ? r : (r & 0x3) | 0x8;\n            return v.toString(16);\n        }\n    );\n}\n\nclass Employee {\n    constructor(name, salary, leader = null) {\n        this.id = generateUUID();\n        this.name = name;\n        this.salary = salary;\n        this.leader = leader;\n        this.directReports = [];\n\n        if (leader) {\n            leader.addDirectReport(this);\n        }\n    }\n\n    addDirectReport(employee) {\n        this.directReports.push(employee);\n    }\n\n    execute() {\n        throw new Error(\"Método execute() debe ser implementado por subclases\");\n    }\n}\n\nclass Manager extends Employee {\n    execute() {\n        return \"Definiendo estrategía para que la compañía crezca...\";\n    }\n}\n\nclass ProjectManager extends Employee {\n    constructor(name, salary, project, leader = null) {\n        super(name, salary, leader);\n        this.project = project;\n    }\n\n    execute() {\n        return `Liderando y supervisando el proyecto: ${this.project}`;\n    }\n}\n\nclass Developer extends Employee {\n    constructor(name, salary, leader = null) {\n        super(name, salary, leader);\n        this.project = leader ? leader.project : \"sin proyecto\";\n    }\n\n    execute() {\n        return `Desarrollando en el proyecto: ${this.project}`;\n    }\n}\n\nconst manager = new Manager(\"Juan David\", 35000000);\nconst projectManager1 = new ProjectManager(\n    \"Esteban\",\n    13000000,\n    \"Incentivos\",\n    manager\n);\nconst projectManager2 = new ProjectManager(\n    \"Santiago\",\n    12500000,\n    \"Algoritmo\",\n    manager\n);\n\nconst developer1 = new Developer(\"Daniel\", 8000000, projectManager1);\nconst developer2 = new Developer(\"Julian\", 8500000, projectManager1);\nconst developer3 = new Developer(\"Felipe\", 8000000, projectManager1);\nconst developer4 = new Developer(\"Duván\", 9000000, projectManager2);\nconst developer5 = new Developer(\"Brais\", 11000000, projectManager2);\n\n// Función para imprimir la información de un empleado\nfunction printEmployeeInfo(employee) {\n    console.log(`ID: ${employee.id}`);\n    console.log(`Nombre: ${employee.name}`);\n    console.log(`Salario: ${employee.salary}`);\n    console.log(`Líder: ${employee.leader ? employee.leader.name : \"N/A\"}`);\n    console.log(\n        \"Reportes Directos: \",\n        employee.directReports.map((e) => e.name).join(\", \")\n    );\n    console.log(`Ejecutando: ${employee.execute()}`);\n    console.log(\"----------------------\");\n}\n\nprintEmployeeInfo(manager);\nprintEmployeeInfo(projectManager1);\nprintEmployeeInfo(developer5);\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/juserdev.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n\nclass Animal {\n    constructor(name) {\n        this.name = name\n    }\n\n    speak() { console.log(`${this.name} hace un ruido`) }\n}\n\nclass Dog extends Animal {\n    speak() { console.log(`${this.name} ladra.`) }\n}\n\nclass Cat extends Animal {\n    speak() { console.log(`${this.name} maulla.`) }\n}\n\nconst maxDog = new Dog(\"Max dog\")\nconst maxCat = new Cat(\"Max cat\")\n\n\nmaxDog.speak()\nmaxCat.speak()\n\nconsole.log(\"\")\nconsole.log(\"----------------- Dificultad extra -----------------\")\nconsole.log(\"\")\n\nclass Employee {\n    constructor(name, id) {\n        this.name = name\n        this.id = id\n    }\n\n    task() { return `${this.name} trabaja en la empresa de desarrollo` }\n\n}\n\nclass PeopleManager extends Employee {\n    constructor(name, id, employees = []) {\n        super(name, id)\n        this.employees = employees\n    }\n\n    addEmployees(employee) {\n        this.employees.push(employee)\n        return employee\n    }\n    countEmployess() { return this.employees.length }\n    viewEmployees() { return this.employees }\n\n}\n\nclass Programer extends Employee {\n    task() { return `${this.name} es programdor y no tiene personal a cargo` }\n}\n\nclass ProjectManager extends PeopleManager {\n    task() { return `${this.name} es gerente de proyecto y tiene programadores a cargo` }\n}\n\nclass Manager extends PeopleManager {\n    task() { return `${this.name} es gerente y tiene gerentes de proyectos a cargo` }\n}\n\nconst pedro = new Programer(\"Pedro\", 1)\nconst max = new Programer(\"Max\", 2)\nconst milton = new Programer(\"Milton\", 3)\nconst filipino = new Programer(\"Filipino\", 4)\n\nconst laura = new ProjectManager(\"Laura\", 5)\nconst jeronimo = new ProjectManager(\"Jeronimo\", 6, [milton])\n\nconst sebastian = new Manager(\"Sebastian\", 7)\n\nconsole.log(pedro)\nconsole.log(max)\n\nconsole.log(laura)\nconsole.log(laura.addEmployees(pedro))\nconsole.log(laura.addEmployees(max))\nconsole.log(laura.viewEmployees())\nconsole.log(laura.countEmployess())\nconsole.log(laura)\n\nconsole.log(jeronimo)\nconsole.log(jeronimo.addEmployees(filipino))\nconsole.log(jeronimo.viewEmployees())\nconsole.log(jeronimo.countEmployess())\nconsole.log(jeronimo)\n\nconsole.log(sebastian)\nconsole.log(sebastian.addEmployees(laura))\nconsole.log(sebastian.task())\nconsole.log(sebastian.countEmployess())\nconsole.log(sebastian)\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n_______________________________________\n#9 HERENCIA Y POLIMORFISMO\n---------------------------------------\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n*/\n\n// ________________________________________________________\n// Clase base Animal\nclass Animal {\n    constructor(name, sound) {\n        this.name = name;\n        this.sound = sound;\n    }\n\n    makeSound() {\n        console.log(`${this.name} hace: ${this.sound}`);\n    }\n}\n\n// Subclases\nclass Dog extends Animal {\n    constructor(name) {\n        super(name, \"Woof\");\n    }\n}\n\nclass Cat extends Animal {\n    constructor(name) {\n        super(name, \"Meow\");\n    }\n}\n\n// Crear instancias y llamar a sus métodos\nconst dog = new Dog(\"Max\");\nconst cat = new Cat(\"Milo\");\ndog.makeSound();\ncat.makeSound();\n\n// ________________________________________________________\n// DIFICULTAD EXTRA\n\n// Jerarquía de empleados\nclass Employee {\n    static employees = [];\n\n    constructor(identifier, tasks, staff = new Set()) {\n        this.identifier = identifier;\n        this.tasks = tasks;\n        this.staff = staff;\n    }\n\n    add(names) {\n        names.forEach(name => Employee.employees.push({ identifier: this.identifier, name }));\n    }\n\n    println() {\n        Employee.employees\n            .filter(employee => employee.identifier === this.identifier)\n            .forEach(employee => console.log(`${employee.name} -> ${this.identifier}`));\n    }\n\n    functions() {\n        console.log(`\\nFunciones de ${this.identifier}`);\n        this.tasks.forEach(task => console.log(task));\n        console.log(\"--------------------\");\n    }\n\n    subordinates() {\n        console.log(`\\nSubordinados de un ${this.identifier}`);\n        Employee.employees\n            .filter(employee => this.staff.has(employee.identifier))\n            .forEach(employee => console.log(`${employee.name} -> ${employee.identifier}`));\n        console.log(\"--------------------\");\n    }\n}\n\nclass Manager extends Employee {\n    constructor() {\n        super(\"Gerente\", [\"- Supervisión\", \"- Toma de decisiones\"], new Set([\"Gerente de Proyecto\", \"Programador\"]));\n    }\n}\n\nclass ProjectManager extends Employee {\n    constructor() {\n        super(\"Gerente de Proyecto\", [\"- Planificación\", \"- Coordinación de proyectos\"], new Set([\"Programador\"]));\n    }\n}\n\nclass Programmer extends Employee {\n    constructor() {\n        super(\"Programador\", [\"- Desarrollo\", \"- Mantenimiento de código\"], new Set());\n    }\n}\n\n// __________________________\nconst manager = new Manager();\nconst projectManager = new ProjectManager();\nconst programmer = new Programmer();\n\nmanager.add([\"Ben\", \"Dan\"]);\nprojectManager.add([\"Ray\", \"Joe\"]);\nprogrammer.add([\"Leo\", \"Sam\", \"Zoe\", \"Ana\"]);\n\nmanager.functions();\nprojectManager.functions();\nprogrammer.functions();\n\nmanager.subordinates();\nprojectManager.subordinates();\n\nmanager.println();\nprojectManager.println();\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/marcode24.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n\n/* eslint-disable no-console */\n/* eslint-disable no-useless-constructor */\n/* eslint-disable class-methods-use-this */\n/* eslint-disable max-classes-per-file */\n// Superclase Animal\nclass Animal {\n  constructor(nombre) {\n    this.nombre = nombre;\n  }\n\n  // Método para imprimir el sonido del animal\n  hacerSonido() {\n    console.log('El animal hace un sonido');\n  }\n}\n\n// Subclase Perro que hereda de Animal\nclass Perro extends Animal {\n  constructor(nombre) {\n    super(nombre);\n  }\n\n  // Método para imprimir el ladrido del perro\n  hacerSonido() {\n    console.log(`El perro ${this.nombre} hace guau`);\n  }\n}\n\n// Subclase Gato que hereda de Animal\nclass Gato extends Animal {\n  constructor(nombre) {\n    super(nombre);\n  }\n\n  // Método para imprimir el maullido del gato\n  hacerSonido() {\n    console.log(`El gato ${this.nombre} hace miau`);\n  }\n}\n\n// Crear instancias de Perro y Gato\nconst miPerro = new Perro('Bobby');\nconst miGato = new Gato('Whiskers');\n\n// Llamar al método para hacer sonido de cada animal\nmiPerro.hacerSonido(); // Imprime: El perro Bobby hace guau\nmiGato.hacerSonido(); // Imprime: El gato Whiskers hace miau\n\n// Visita mi repo en GitHub para ver y correr los tests de este código --> https://github.com/marcode24/weekly-challenges\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/miguelex.js",
    "content": "class Animal {\n    constructor(nombre, sonido) {\n        this.nombre = nombre\n        this.sonido = sonido\n    }\n}\n\nclass Perro extends Animal {\n    constructor(nombre, sonido) {\n        super(nombre, sonido)\n    }\n    get Sonido() {\n        return \"El perro \" + this.nombre + \" hace \" + this.sonido + \"!\"\n    }\n}\n\nclass Gato extends Animal {\n    constructor(nombre, sonido) {\n        super(nombre, sonido)\n    }\n    get Sonido() {\n        return \"El gato \" + this.nombre + \" hace \" + this.sonido + \"!\"\n    }\n}\n\nconst milu = new Perro('Milu', 'Guau, guau')\nconsole.log(milu.Sonido)\n\nconst garfield = new Gato('Garfield', 'Miauuuu')\nconsole.log(garfield.Sonido)\n\n// Extra\n\nclass Empleado {\n    constructor(id, nombre) {\n        this.id = id\n        this.nombre = nombre\n    }\n}\n\nclass Gerente extends Empleado {\n    constructor(id, nombre, empleados) {\n        super(id, nombre)\n        this.empleados = empleados\n    }\n    \n    get gestiona() {\n        return \"El gerente \" + this.nombre + \" gestiona a \" + this.empleados.length + \" empleados, que son \" + this.empleados.join(\", \") + \".\"\n    }\n}\n\nclass GerenteP extends Empleado {\n    constructor(id, nombre, empleados) {\n        super(id, nombre)\n        this.empleados = empleados\n    }\n    \n    get gestiona() {\n        return \"El gerente \" + this.nombre + \" gestiona a \" + this.empleados.length + \" empleados, que son \" + this.empleados.join(\", \") + \".\"\n    }\n\n}\n\nclass Programador extends Empleado {\n    constructor(id, nombre, lenguaje) {\n        super(id, nombre)\n        this.lenguaje = lenguaje\n    }\n    \n    get programa() {\n        return \"El programador \" + this.nombre + \" programa en \" + this.lenguaje.join(\", \") + \".\"\n    }\n\n}\n\nconst gerente = new Gerente(1, 'Migue', ['Ana', 'Pedro', 'Luis'])\nconsole.log(gerente.gestiona)\n\nconst gerenteP = new GerenteP(2, 'Ana', ['Rafa', 'Maria', 'Luisa'])\nconsole.log(gerenteP.gestiona)\n\nconst programador = new Programador(3, 'Pedro', ['JavaScript', 'Python', 'Java'])\nconsole.log(programador.programa)"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/natalyjoanna.js",
    "content": "\n// // Superclase\n\n// class Animal {\n// \tsonido = \"sonido de animal\";\n\t\n// \tconstructor(nombre) {\n// \t\tconsole.log(\"El animal hace: \");\n//     this.nombre = nombre;\n// \t}\n\t\n// \tsound() {\n// \t\tconsole.log(`Soy ${this.nombre} y soy un animal que hace el sonido ${this.sonido}`);\n// \t}\n// }\n\n// // Subclases\n\n// class Perro extends Animal {\n// \tsonido = \"wof\";\n\t\n// \tconstructor(nombre) {\n// \t\tsuper(nombre);\n// \t}\n// }\n\n// class Gato extends Animal {\n// \tsonido = \"miau\";\n\t\n// \tconstructor(nombre) {\n// \t\tsuper(nombre);\n// \t}\n// }\n\n// const myDog = new Perro(\"Pepito\");\n// myDog.sound();\n// const myCat = new Gato(\"Pepita\");\n// myCat.sound();\n\n// DIFICULTAD EXTRA\n\nclass Empleado {\n  constructor(id, nombre) {\n    this.id = id;\n    this.nombre = nombre;\n    this.empleados = []\n  }\n\n  add(empleado) {\n    this.empleados.push(empleado);\n    console.log('Empleado agregado.')\n  }\n\n  print() {\n    for(let empleado of this.empleados) {\n      console.log(empleado.nombre)\n    }\n  }\n\n}\n\nclass Gerente extends Empleado {\n\n  coordinarProyectos() {\n    console.log(`${this.nombre} esta coordinando los proyectos de la empresa`)\n  }\n}\n\nclass GerenteDeProyecto extends Empleado {\n  constructor(id, nombre, proyecto) {\n    super(id, nombre, proyecto);\n    this.proyecto = proyecto;\n  }\n\n  coordinarProyecto() {\n    console.log(`${this.nombre} esta coordinando el proyecto ${this.proyecto}`)\n  }\n}\n\nclass Programador extends Empleado {\n  constructor(id, nombre, lenguaje) {\n    super(id, nombre, lenguaje);\n    this.lenguaje = lenguaje;\n  }\n\n  programar() {\n    console.log(`${this.nombre} esta programdo en ${this.lenguaje}`)\n  }\n\n  add(empleado) {\n    console.log(`Un programador no debe de terner empleados a su cargo. ${empleado} no se agregara`)\n  }\n}\n\nlet myManger = new Gerente(1, \"Nataly\");\nlet myProjectManager1 = new GerenteDeProyecto(2, \"Joanna\", \"Proyecto 1\");\nlet myProjectManager2 = new GerenteDeProyecto(3, \"Marcos\", \"Proyecto 2\");\nlet myProgramer1 = new Programador(4, \"Mar\", \"Javascript\");\nlet myProgramer2 = new Programador(5, \"Joan\", \"Dart\");\nlet myProgramer3 = new Programador(6, \"Nat\", \"Kotlin\");\n\nmyManger.add(myProjectManager1)\nmyManger.add(myProjectManager2)\n\nmyProjectManager1.add(myProgramer1)\nmyProjectManager1.add(myProgramer2)\nmyProjectManager2.add(myProgramer3)\n\nmyProgramer1.add(myProgramer2)\n\nmyManger.coordinarProyectos()\nmyProjectManager1.coordinarProyecto()\nmyProgramer3.programar()\n\nmyManger.print()\nmyProjectManager1.print()\n\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/nlarrea.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n\n\nclass Animal {\n    constructor(name) {\n        this.name = name;\n    }\n\n    sound() {\n        console.log(null);\n    }\n}\n\n\nclass Dog extends Animal {\n    sound() {\n        console.log('Guau!');\n    }\n}\n\n\nclass Cat extends Animal {\n    sound() {\n        console.log('Miau!');\n    }\n}\n\n\nconst myDog = new Dog('Lagun');\nmyDog.sound();  // Guau\n\nconst myCat = new Cat('Kira');\nmyCat.sound();  // Miau\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n\n\nclass Employee {\n    constructor(id, name) {\n        this.id = id;\n        this.name = name;\n        this.employees = [];\n    }\n\n    add(employee) {\n        this.employees.push(employee);\n    }\n\n    printEmployees() {\n        console.log(`\\n${this.name}'s employees:`);\n        for (let employee of this.employees) {\n            console.log(` - ${employee.name}`);\n        }\n    }\n}\n\n\nclass Manager extends Employee {\n    coordinate() {\n        console.log(`\\n${this.name} is coordinating all of the company's projects`);\n    }\n}\n\n\nclass ProjectManager extends Employee {\n    constructor(id, name, project) {\n        super(id, name);\n        this.project = project;\n    }\n\n    coordinate() {\n        console.log(`\\n${this.name} is coordinating: ${this.project}`);\n    }\n}\n\n\nclass Programmer extends Employee {\n    constructor(id, name, language) {\n        super(id, name);\n        this.language = language;\n    }\n\n    code() {\n        console.log(`\\n${this.name} is programming using ${this.language} language`);\n    }\n\n    add(employee) {\n        console.log(`\\nA programmer has no employees.\\n${employee.name} won't be added.`);\n    }\n}\n\n\n// Initializing employees\nconst myManager = new Manager(1, 'ManagerName');\nconst myPm1 = new ProjectManager(2, 'PM1', 'Project 1');\nconst myPm2 = new ProjectManager(3, 'PM2', 'Project 2');\nconst myProgrammer1 = new Programmer(4, 'P1', 'Python');\nconst myProgrammer2 = new Programmer(5, 'P2', 'React');\nconst myProgrammer3 = new Programmer(6, 'P3', 'JavaScript');\nconst myProgrammer4 = new Programmer(7, 'P4', 'SQL');\n\n// Adding employees\nmyManager.add(myPm1);\nmyManager.add(myPm2);\n\nmyPm1.add(myProgrammer1);\nmyPm1.add(myProgrammer2);\n\nmyPm2.add(myProgrammer3);\nmyPm2.add(myProgrammer4);\n\nmyProgrammer1.add(myProgrammer4);  // won't work\n/* prints:\nA programmer has no employees.\nP4 won't be added.\n*/\n\n// Tasks\nmyManager.coordinate();\n// ManagerName is coordinating all of the company's projects\nmyPm1.coordinate();\n// PM1 is coordinating: Project 1\nmyProgrammer1.code();\n// P1 is programming using Python language\nmyProgrammer2.code();\n// P2 is programming using React language\nmyPm1.printEmployees();\n/* prints:\nPM1's employees:\n - P1\n - P2\n*/\nmyManager.printEmployees();\n/* prints:\nManagerName's employees:\n - PM1\n - PM2\n*/"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/ocram1304.js",
    "content": "class Animal{\n\n    especie;\n    tamano;\n    color;\n    amo;\n    constructor(especie,tamano,color,amo){\n        this.especie = especie;\n        this.tamano = tamano;\n        this.color = color;\n        this.amo = amo;\n\n    }\n\n    sonido(){//Este método puede se puede sobreescribir en las clases  que recigan herencia de está,\n             //lo que significa que puede tomar direntes formas (polimorfismo)\n        console.log(\"Sonidos de animales\");\n    }\n\n}\nclass Perro extends Animal(){//La clase perro es hija de la superclase animal\n    raza;\n    constructor(especie,tamano,color,amo,raza){\n        super(especie,tamano,color,amo);\n        this.raza = raza;\n    }\n    sonido(){//Se sobreescribe el método herdado de la clase padre\n        console.log(\"gua,gua,gua\");\n    }\n}\nclass Gato extends Animal(){//La clase perro es hija de la superclase animal\n    raza;\n    constructor(especie,tamano,color,amo,raza){\n        super(especie,tamano,color,amo);\n        this.raza = raza;\n    }\n    sonido(){//Se sobreescribe el método herdado de la clase padre\n        console.log(\"miau,miau,miau\");\n    }\n}\n//Herencia y objetos en el sismema de objetos y prototipos de JS\n//En JS existen las cadenas de prototipos, están son una manera de implentar el polimorfismo y la herencia en \n//objetos, aunque en realidad en JS, más que herencia se trata de delegación,  si se intenta acceder a un método\n//pero este no está definido dentro de el, se busca en su prototipo. Todos los objetos tienen un atributo llamado\n//__proto__ el cual es el ultimo valor en la cadena de prototipos, si se recorre toda la cadeena de prototipos y se\n//llega hasta el final de está (__proto__)\nconst objetoAnimal= {\n    especie: \"\",\n    sonidoAnimal(){\n    console.log(\"sonido animal\");\n  },\n};\n//Las funciones tienen un atributo  llamdo prototipe, cuando la función se llama como constructor, está propiedad\n//se establece como el prototipo del nuevo objeto creado.\n//Un patrón muy común a la hora de utilizar prototipos es el de deninir los métodos en este último, mientras que \n//las propiedades se asignan en los objetos ya que generalmente los métodos son comunes a todos los objetos. \nfunction ObjetoPerro(nombre){\n this.nombre = nombre;\n\n}\nObjetoPerro.prototype = Object.create(objetoAnimal); // Asignar prototipo\nObjetoPerro.prototype.sonidoAnimal = function() {\n    console.log(\"gua,gua,gua\");\n};\n//Los métodos en el prototipos se pueden sobreescribir, cuando se llama a un métedo se recurre simpre primero al \n//que está definodo dentro del objeto, sino lo encuentra o no está defindo; se recurre al prototipo.\nfunction ObjetoGato(nombre) {\n    this.nombre = nombre;\n}\nObjetoGato.prototype = Object.create(objetoAnimal); // Asignar prototipo\n\nObjetoGato.prototype.sonidoAnimal = function() {\n    console.log(\"miau,miau,miau\");\n};\n// Probando los métodos\nconst perro = new ObjetoPerro(\"Darwin\");\nconst gato = new ObjetoGato(\"Fiona\");\nperro.sonidoAnimal(); // Debería imprimir \"gua,gua,gua\"\ngato.sonidoAnimal();  // Debería imprimir \"miau,miau,miau\"\n\n//Difucultad extra\nclass Empleado {\n    #nombre;\n    #id;\n    constructor(nombre,id){\n        this.#nombre = nombre;\n        this.#id = id;\n    }\n}\nclass Gerente extends Empleado{\n #area;\n constructor(nombre,id,area){\n    super(nombre,id)\n    this.#area = area;\n }\n supervisar(){\n    console.log(\"Supervisar tareas\");\n }\n\n}\nclass GerenteProyecto extends Gerente{\n #proyecto;\n constructor(nombre,id, area, proyecto){\n  super(nombre,id,area,proyecto);\n  this.#proyecto = proyecto;\n }\n gestionar(){\n    console.log(\"Gestionar proyecto\");\n }\n}\nclass Programador extends Empleado{\n #ParteProyecto;\n constructor(nombre,id,ParteProyecto){\n    super(nombre,id);\n    this.#ParteProyecto = ParteProyecto;\n }\n programar(){\n    console.log(\"Programar\");\n }\n\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/oleojake.js",
    "content": "import \"./style.css\";\n\n/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n */\n\nclass Animal {\n\tconstructor(sound) {\n\t\tthis.sound = sound;\n\t}\n\n\tmakeSound() {\n\t\tconsole.log(this.sound);\n\t}\n}\n\nclass Perro extends Animal {\n\tconstructor() {\n\t\tsuper(\"Guau\");\n\t}\n}\n\nclass Gato extends Animal {\n\tconstructor() {\n\t\tsuper(\"Miau\");\n\t}\n}\n\nconst perro = new Perro();\nconst gato = new Gato();\nperro.makeSound();\ngato.makeSound();\n\n/*\n* DIFICULTAD EXTRA (opcional):\n* Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n* pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n* Cada empleado tiene un identificador y un nombre.\n* Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n* actividad, y almacenan los empleados a su cargo.\n*/\n\nclass Empleado {\n\tconstructor(id, nombre) {\n\t\tthis.id = id;\n\t\tthis.nombre = nombre;\n\t}\n}\n\nclass Gerente extends Empleado {\n\tconstructor(id, nombre) {\n\t\tsuper(id, nombre);\n\t\tthis.empleados = [];\n\t}\n\n\taddEmpleado(empleado) {\n\t\tthis.empleados.push(empleado);\n\t}\n}\n\nclass GerenteProyecto extends Gerente {\n\tprojects = [];\n\n\tconstructor(id, nombre) {\n\t\tsuper(id, nombre);\n\t}\n\n\tassignProject(project) {\n\t\tthis.projects.push(project);\n\t}\n}\n\nclass Programador extends Empleado {\n\tconstructor(id, nombre) {\n\t\tsuper(id, nombre);\n\t}\n\n\tdevelop() {\n\t\tconsole.log(\"Desarrollando...\");\n\t}\n}\n\nconst gerente = new Gerente(1, \"Gerente\");\nconst gerenteProyecto = new GerenteProyecto(2, \"Gerente de Proyecto\");\nconst programador = new Programador(3, \"Programador\");\n\ngerente.addEmpleado(gerenteProyecto);\nconsole.log(gerente);\n\ngerenteProyecto.assignProject(\"Proyecto 1\");\ngerenteProyecto.addEmpleado(programador);\nconsole.log(gerenteProyecto);\n\nprogramador.develop();"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/parababire.js",
    "content": "class Animal {\n  constructor(raza, color, nombre) {\n    this.raza = raza;\n    this.color = color;\n    this.nombre = nombre;\n  }\n  caracteristicas() {\n    return `${this.nombre} es un ${this.raza} de color ${this.color}`;\n  }\n}\nclass Perro extends Animal {\n  constructor(raza, color, nombre) {\n    super(raza, color, nombre);\n  }\n  sonido() {\n    return `${super.caracteristicas()} hace Woof Woof.`;\n  }\n}\nclass Gato extends Animal {\n  constructor(raza, color, nombre) {\n    super(raza, color, nombre);\n  }\n  sonido() {\n    return `${super.caracteristicas()} hace Meau.`;\n  }\n}\n\nlet perro = new Perro(\"Poodle\", \"blanco\", \"FeFe\");\nlet gato = new Gato(\"Abisinio\", \"negro\", \"Pesadilla\");\nconsole.log(perro.sonido());\nconsole.log(gato.sonido());\n\n/*Extra*/\n\nclass Empleado {\n  constructor(id, nombre) {\n    this.id = id;\n    this.nombre = nombre;\n    this.empleados = [];\n  }\n  contratar(empleados) {\n    this.empleados.push(empleados);\n  }\n  print() {\n    this.empleados.forEach(empleados => {\n      console.log(empleados.nombre);\n    });\n  }\n}\nclass Gerente extends Empleado {\n  coordinar() {\n    console.log(`${this.nombre} coordina todos los proyectos de la empresa`);\n  }\n}\nclass GerenteProyecto extends Empleado {\n  constructor(id, nombre, proyecto) {\n    super(id, nombre);\n    this.proyecto = proyecto;\n  }\n  coordinar() {\n    console.log(`${this.nombre} coordina su proyecto`);\n  }\n}\nclass Programador extends Empleado {\n  constructor(id, nombre, lenguaje) {\n    super(id, nombre);\n    this.lenguaje = lenguaje;\n  }\n  code() {\n    console.log(`${this.nombre} está programando en ${this.lenguaje}`);\n  }\n  contratar(empleados) {\n    console.log(`${this.nombre} no puede contratar. ${empleados.nombre} no será contratado`);\n  }\n}\n\nconst gerente = new Gerente(1, \"Luis\");\nconst gerenteProyecto1 = new GerenteProyecto(2, \"Pedro\", \"Proyecto1\");\nconst gerenteProyecto2 = new GerenteProyecto(3, \"José\", \"Proyecto2\");\nconst programador = new Programador(4, \"Ángel\", \"Javascript\");\nconst programador2 = new Programador(5, \"Tomas\", \"Java\");\nconst programador3 = new Programador(6, \"Marcos\", \"Phyton\");\n\ngerente.contratar(gerenteProyecto1);\ngerente.contratar(gerenteProyecto2);\n\ngerenteProyecto1.contratar(programador);\ngerenteProyecto2.contratar(programador2);\ngerenteProyecto2.contratar(programador3);\n\nprogramador.contratar(programador2);\n\nprogramador.code();\ngerente.coordinar();\ngerenteProyecto1.coordinar();\ngerenteProyecto2.coordinar();\ngerente.print();\ngerenteProyecto2.print();\nprogramador.print();"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/pedamoci.js",
    "content": "class Animal {\n  constructor(name) {\n    this.name = name\n  }\n  hablar(modo){\n    console.log(modo)\n  }\n}\n\nclass Perro extends Animal {\n  constructor(name){\n    super(name)\n  }\n  ladrar() {\n    this.hablar('guau')\n  }\n}\n\nclass Gato extends Animal {\n  constructor(name){\n    super(name)\n  }\n  maullar() {\n    this.hablar('miau')\n  }\n}\n\nconst perro = new Perro('Teo')\nconst gato = new Gato('Cleopatra')\n\nperro.ladrar()\ngato.maullar()\n\n// ------------------------------------ DIFICULTAD EXTRA ------------------------------------\nclass Empleado {\n  constructor(id, name) {\n    this.id = id\n    this.name = name\n    this.subordinados = []\n  }\n\n  agregarSubordinado(empleado) {\n    this.subordinados.push(empleado)\n  }\n}\nclass Gerente extends Empleado {\n  constructor(id, name) {\n    super(id, name)\n  }\n\n  asingProycet(manager, proyect) {\n    console.log(`${this.name} le ha asignado a ${manager.name} el proyecto ${proyect}`)\n  }\n}\n\nclass ProjectManager extends Empleado {\n  constructor(id, name, gerente) {\n    super(id, name)\n    gerente.agregarSubordinado(this)\n  }\n\n  asignTaskProgramador(programador, tarea) {\n    console.log(`${this.name} le ha asignado a ${programador.name} programar ${tarea}`)\n    programador.programar(tarea)\n  }\n}\n\nclass Programador extends Empleado {\n  constructor(id, name, manager) {\n    super(id, name)\n    manager.agregarSubordinado(this)\n  }\n\n  programar(tarea) {\n    console.log(`Empezando a programar ${tarea}`)\n    console.log(`${this.name} ha teminado de programar ${tarea}`)\n  }\n}\n\nconst gerente1 = new Gerente(1, \"Gerardo\")\nconst gerente2 = new Gerente(2, \"Alfredo\")\nconst gerente3 = new Gerente(3, \"Jaime\")\n\nconst pm1 = new ProjectManager(10, \"Laura\", gerente1)\nconst pm2 = new ProjectManager(20, \"Roberto\", gerente1)\nconst pm3 = new ProjectManager(30, \"Walter\", gerente2)\nconst pm4 = new ProjectManager(40, \"Sofía\", gerente2)\nconst pm5 = new ProjectManager(50, \"Carmela\", gerente3)\nconst pm6 = new ProjectManager(60, \"Bautista\", gerente3)\n\n\nconst programador1 = new Programador(100, 'Juan', pm1)\nconst programador2 = new Programador(200, 'Mauricio', pm1)\nconst programador3 = new Programador(300, 'Federico', pm2)\nconst programador4 = new Programador(400, 'Baltazar', pm2)\nconst programador5 = new Programador(500, 'Sergio', pm3)\nconst programador6 = new Programador(600, 'Dario', pm3)\nconst programador7 = new Programador(700, 'Manuel', pm4)\nconst programador8 = new Programador(800, 'Raul', pm4)\nconst programador9 = new Programador(900, 'Horacio', pm5)\nconst programador10 = new Programador(1000, 'Tomas', pm5)\nconst programador11 = new Programador(1100, 'Carlos', pm6)\nconst programador12 = new Programador(1200, 'Francisco', pm6)\n\n// Proyect manger le asigna una tarea a un programador y este la realiza\npm1.asignTaskProgramador(programador1, 'Página web')\n\n// Gerente le asigna un proyecto a un proyect manager\ngerente2.asingProycet(pm4, 'silksong')\n\n\n// Programador programa \nprogramador12.programar('ToDo')\n\nconsole.log(`El gerente ${gerente1.name} tiene de subordinados a ${gerente1.subordinados[0].name} y a ${gerente1.subordinados[1].name}, ${gerente1.subordinados[0].name} tiene como subordinados a ${gerente1.subordinados[0].subordinados[0].name} y a ${gerente1.subordinados[0].subordinados[1].name} y ${gerente1.subordinados[1].name} tiene como subordinados a ${gerente1.subordinados[1].subordinados[0].name} y a ${gerente1.subordinados[1].subordinados[1].name}`)\n\nconsole.log(`El gerente ${gerente2.name} tiene de subordinados a ${gerente2.subordinados[0].name} y a ${gerente2.subordinados[1].name}, ${gerente2.subordinados[0].name} tiene como subordinados a ${gerente2.subordinados[0].subordinados[0].name} y a ${gerente2.subordinados[0].subordinados[1].name} y ${gerente2.subordinados[1].name} tiene como subordinados a ${gerente2.subordinados[1].subordinados[0].name} y a ${gerente2.subordinados[1].subordinados[1].name}`)\n\nconsole.log(`El gerente ${gerente3.name} tiene de subordinados a ${gerente3.subordinados[0].name} y a ${gerente3.subordinados[1].name}, ${gerente3.subordinados[0].name} tiene como subordinados a ${gerente3.subordinados[0].subordinados[0].name} y a ${gerente3.subordinados[0].subordinados[1].name} y ${gerente3.subordinados[1].name} tiene como subordinados a ${gerente3.subordinados[1].subordinados[0].name} y a ${gerente3.subordinados[1].subordinados[1].name}`)"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/popmaquin.js",
    "content": "//---Herencia--\nclass Empleado{\n    constructor(id, nombre){\n        this.id = id;\n        this.nombre = nombre;\n        this.empleados =[];\n    }\n    guardar(emp){\n        this.empleados.push(emp);\n    }\n    imprimir_empleados(){\n        this.empleados.forEach((emp)=>{\n            console.log(emp.nombre);\n        });\n    }\n}\n\nclass Gerente extends Empleado{\n    cordinador_general(){\n        console.log(`${this.name} es el Gerente general del proyecto`);\n    }\n}\n\nclass GerenteProyecto extends Empleado{\n    constructor(id, nombre, proyecto){\n        super(id, nombre);\n        this.proyecto = proyecto;       \n    }\n    coordinador_proyecto(){\n        console.log(`${this.nombre} es el coordinador del proyecto `);\n    }\n}\n\nclass Programador extends Empleado{\n    constructor(id, nombre, lenguaje){\n        super(id, nombre);\n        this.lenguaje = lenguaje;       \n    }\n    codigo(){\n        console.log(`${this.nombre} esta programando en ${this.lenguaje}`);\n    }\n    guardar(emp){\n        console.log(`EL programador no tiene ningun empleado a su cargo, ${emp.nombre} no se añadirá`);\n    }\n}\n\n\nlet gerente = new Gerente(1, \"Julio\")\nlet gerenteProyecto1 = new GerenteProyecto(2, \"Pedro\", \"Proyecto 1\");\nlet gerenteProyecto2 = new GerenteProyecto(3, \"Roberto\", \"Proyecto 2\");\nlet programador1 = new Programador(4, \"José\", \"Javascript\");\nlet programador2 = new Programador(5, \"Marcos\", \"Java\");\nlet programador3 = new Programador(6, \"William\", \"Phtyon\");\n\n//En la funcion guardar se le añade los empleados a su cargo\ngerente.guardar(gerenteProyecto1);\ngerente.guardar(gerenteProyecto2);\n\ngerenteProyecto2.guardar(programador1);\ngerenteProyecto2.guardar(programador2);\ngerenteProyecto2.guardar(programador3);\n\nprogramador1.guardar(programador2)\n\n//Imprime el nombre del programador y su lenguaje\nprogramador1.codigo();\n\n//Imprime los empleados a su cargo\ngerente.imprimir_empleados(); // [Pedro, Roberto]\ngerenteProyecto2.imprimir_empleados(); // [José, Marcos, William]\nprogramador1.imprimir_empleados();\n\n\n\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/qwik-zgheib.js",
    "content": "/* -- exercise */\nclass Animal {\n  constructor(name) {\n    this.name = name;\n  }\n\n  makeSound() {\n    console.log(`${this.name} makes a sound.`);\n  }\n}\n\nclass Dog extends Animal {\n  constructor(name) {\n    super(name);\n  }\n\n  makeSound() {\n    console.log(`${this.name} says: Woof! Woof!`);\n  }\n}\n\nclass Cat extends Animal {\n  constructor(name) {\n    super(name);\n  }\n\n  makeSound() {\n    console.log(`${this.name} says: Meow! Meow!`);\n  }\n}\n\nfunction printAnimalSound(animal) {\n  animal.makeSound();\n}\n\nlet dog = new Dog(\"Firulais\");\nlet cat = new Cat(\"Silvester\");\n\nprintAnimalSound(dog);\nprintAnimalSound(cat);\n\n/* -- extra chanllenge */\nclass Employee {\n  constructor(id, name) {\n    this.id = id;\n    this.name = name;\n  }\n\n  printDetails() {\n    console.log(`ID: ${this.id}, Name: ${this.name}`);\n  }\n}\n\nclass Manager extends Employee {\n  constructor(id, name) {\n    super(id, name);\n    this.employeesInCharge = [];\n  }\n\n  addEmpleado(employee) {\n    this.employeesInCharge.push(employee);\n  }\n\n  printDetails() {\n    super.printDetails();\n    console.log(\"Employees under this manager:\");\n    this.employeesInCharge.forEach((emp) => emp.printDetails());\n  }\n}\n\nclass ProjectManager extends Manager {\n  constructor(id, name, project) {\n    super(id, name);\n    this.project = project;\n  }\n\n  printDetails() {\n    super.printDetails();\n    console.log(`Project: ${this.project}`);\n  }\n}\n\nclass Programmer extends Employee {\n  constructor(id, name, language) {\n    super(id, name);\n    this.language = language;\n  }\n\n  printDetails() {\n    super.printDetails();\n    console.log(`Programming Language: ${this.language}`);\n  }\n}\n\nlet manager = new Manager(1, \"Alice\");\nlet projectManager = new ProjectManager(2, \"Bob\", \"Project X\");\nlet programmer1 = new Programmer(3, \"Charlie\", \"JavaScript\");\nlet programmer2 = new Programmer(4, \"David\", \"Python\");\n\nmanager.addEmpleado(programmer1);\nprojectManager.addEmpleado(programmer2);\nmanager.printDetails();\nprojectManager.printDetails();\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/raulG91.js",
    "content": "class Animal{\n\n    constructor(name){\n        this.name = name;\n    }\n    sound(){\n        console.log(\"Animal sound\");\n    }\n    get_name(){\n        return this.name\n    }\n}\n\nclass Dog extends Animal{\n\n    sound(){\n        console.log(\"Guau!\");\n    }\n}\n\nclass Cat extends(Animal){\n\n    sound(){\n        console.log(\"Miau!\")\n    }\n}\n\nlet my_dog = new Dog(\"Luna\");\nconsole.log(\"Dog name: \",my_dog.get_name());\nmy_dog.sound();\nlet my_cat = new Cat(\"Miso\");\nconsole.log(\"Cat name: \",my_cat.get_name());\nmy_cat.sound();"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/rxvlc.js",
    "content": "// Superclase\nclass Animal {\n    constructor(nombre, edad) {\n        this.nombre = nombre;\n        this.edad = edad;\n    }\n}\n\n// Heredera Perro\nclass Perro extends Animal {\n    constructor(nombre, edad) {\n        super(nombre, edad);\n    }\n\n    sonido() {\n        console.log(\"¡guau guau!\");\n    }\n}\n\n// Heredera Gato\nclass Gato extends Animal {\n    constructor(nombre, edad) {\n        super(nombre, edad);\n    }\n\n    sonido() {\n        console.log(\"¡miau miau!\");\n    }\n}\n\n// Clase base para representar a un empleado genérico\nclass Empleado {\n    constructor(id, nombre) {\n        this.id = id;\n        this.nombre = nombre;\n    }\n\n    informacion() {\n        console.log(`ID: ${this.id}, Nombre: ${this.nombre}`);\n    }\n}\n\n// Clase Gerente hereda de Empleado\nclass Gerente extends Empleado {\n    constructor(id, nombre) {\n        super(id, nombre);\n        this.empleadosACargo = [];\n    }\n\n    agregarEmpleado(empleado) {\n        this.empleadosACargo.push(empleado);\n    }\n\n    informacion() {\n        super.informacion();\n        console.log(\"Tipo: Gerente\");\n        console.log(`Empleados a cargo: ${this.empleadosACargo.length}`);\n    }\n}\n\n// Clase GerenteProyecto hereda de Gerente\nclass GerenteProyecto extends Gerente {\n    constructor(id, nombre, areaProyecto) {\n        super(id, nombre);\n        this.areaProyecto = areaProyecto;\n    }\n\n    informacion() {\n        super.informacion();\n        console.log(`Área del Proyecto: ${this.areaProyecto}`);\n    }\n}\n\n// Clase Programador hereda de Empleado\nclass Programador extends Empleado {\n    constructor(id, nombre, lenguaje) {\n        super(id, nombre);\n        this.lenguaje = lenguaje;\n    }\n\n    informacion() {\n        super.informacion();\n        console.log(`Lenguaje: ${this.lenguaje}`);\n    }\n}\n\n// Creación de instancias de Perro y Gato\nlet miPerro = new Perro(\"Bobby\", 5);\nlet miGato = new Gato(\"Whiskers\", 3);\n\n// Llamada a los métodos específicos de cada clase\nmiPerro.sonido(); // Salida: ¡guau guau!\nmiGato.sonido(); // Salida: ¡miau miau!\n\n// Creación de instancias de empleados\nlet gerente1 = new Gerente(1, \"Juan\");\nlet gerenteProyecto1 = new GerenteProyecto(2, \"María\", \"Desarrollo Web\");\nlet programador1 = new Programador(3, \"Pedro\", \"C#\");\n\n// Agregar empleados a cargo del gerente\ngerente1.agregarEmpleado(gerenteProyecto1);\ngerenteProyecto1.agregarEmpleado(programador1);\n\n// Mostrar información de los empleados\nconsole.log(\"Información del Gerente:\");\ngerente1.informacion();\nconsole.log(\"\\nInformación del Gerente de Proyecto:\");\ngerenteProyecto1.informacion();\nconsole.log(\"\\nInformación del Programador:\");\nprogramador1.informacion();\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/saicobys.js",
    "content": "/* Concepto de Herencia: Animal, Perro y Gato */\n\nclass Animal {\n  constructor(nombre) {\n    this.nombre = nombre;\n  }\n\n  emitirSonido() {\n    console.log(\"Sonido genérico de animal \");\n  }\n}\n\nclass Perro extends Animal {\n  emitirSonido() {\n    console.log(\"Guau!\");\n  }\n}\n\nclass gato extends Animal {\n  emitirSonido() {\n    console.log(\"Miau!\");\n  }\n}\n\nlet perro1 = new Perro(\"Buddy\");\nlet gato1 = new gato(\"Whiskers\");\n\nperro1.emitirSonido();\ngato1.emitirSonido();\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/seandsun.js",
    "content": "/*\n<-------------- Herencia -------------->\nBásicamente la herencia de clases es una característica que nos permite reutilizar, simplificar y añadir nuevo código. EL funcionamiento\nde la herencia parte de que una \"clase hija\" obtiene acceso a las propiedades y métodos de una \"clase padre\". Dicho acceso se establece\nmediante la palabra clave \"extends\" y el método \"super()\" que se encarga de llamar o ejecutar el constructor de la clase padre cuando\nse crea o instancia un objeto de la clase hija. El método super() que debe usarse antes de usar \"this\".\n*/\n\nclass Animal {\n  constructor(nombre, color) {\n    this.nombre = nombre\n    this.color = color\n  }\n\n  sonido(sonido) {\n    return console.log(sonido)\n  }\n\n  correr(velocidad) {\n    return console.log(`La velocidad de ${this.nombre} es de ${velocidad}km/h`)\n  }\n}\n\nclass Perro extends Animal {\n  constructor(nombre, color, edad) {\n    super(nombre, color)\n    this.edad = edad\n  }\n\n  dormir() {\n    return console.log(`Shhh, ${this.nombre} de color ${this.color} y edad ${this.edad} años está durmiendo`)\n  }\n}\n\nclass Gato extends Animal {\n  constructor(nombre, color, comida) {\n    super(nombre, color)\n    this.comida = comida\n  }\n\n  comer() {\n    return console.log(`${this.nombre} de color ${this.color} está comiendo ${this.comida}`)    \n  }\n}\n\nconsole.log('<-- Perro:')\n\nconst perro = new Perro('Anubis', 'naranja', 4)\nperro.dormir()         // Shhh, Anubis de color naranja y edad 4 años está durmiendo\nperro.correr(45)       // La velocidad de Anubis es de 45km/h\nperro.sonido('¡guau!') // ¡guau!\n\nconsole.log('<-- Gato:')\n\nconst gato = new Gato('Dakota', 'amarillo', 'ratones')\ngato.comer()         // Dakota de color amarillo está comiendo ratones\ngato.correr(48)      // La velocidad de Dakota es de 48km/h\ngato.sonido('¡miau') // ¡miau!\n\n\n// <-------------- Extra -------------->\n\nclass Empleados {\n  constructor(identificador, nombre) {\n    this.identificador = identificador\n    this.nombre = nombre\n  }\n\n  presentacion() {\n    return console.log(`Me llamo ${this.nombre}, mi número de Id de emplead@ es: ${this.identificador}`)\n  }\n}\n\nclass Gerentes extends Empleados {\n  constructor(identificador, nombre, gestion) {\n    super(identificador, nombre)\n    this.gestion = gestion\n    this.empleadosACargo = []\n  }\n\n  planear() {\n    return console.log(`Soy la encargada de toda la gestión ${this.gestion}`)\n  }\n\n  /*\n  Con ayuda de la sintaxis \"super.metodo()\" sobreescribo el método \"presentacion()\" de la clase padre para que se\n  llame a él primero, y luego llame al método \"planear()\" de la clase hija.\n  */\n  presentacion() {\n    super.presentacion()\n    this.planear()\n  }\n}\n\nclass GerentesDeProyectos extends Empleados {\n  constructor(identificador, nombre, proyecto) {\n    super(identificador, nombre)\n    this.proyecto = proyecto\n    this.empleadosACargo = []\n  }\n\n  dirigir() {\n    return console.log(`Estoy dirigiendo la construcción de una ${this.proyecto}`)\n  }\n\n  presentacion() {\n    super.presentacion()\n    this.dirigir()\n  }\n}\n\nclass Programadores extends Empleados {\n  constructor(identificador, nombre, lenguaje) {\n    super(identificador, nombre)\n    this.lenguaje = lenguaje\n  }\n\n  codificar() {\n    return console.log(`Estoy codificando un sitio web con ${this.lenguaje}`)\n  }\n\n  presentacion() {\n    super.presentacion()\n    this.codificar()\n  }\n}\n\nconsole.log('<-- Gerente:')\n\nconst gerente = new Gerentes(1, 'Margot', 'administrativa')\ngerente.presentacion()\n\n\nconsole.log('<-- Gerente de proyectos:')\n\nconst gerenteDeProyecto = new GerentesDeProyectos(2, 'Andy', 'página web')\ngerenteDeProyecto.presentacion()\n\n\nconsole.log('<-- Programadores:')\n\nconst programador = new Programadores(3, 'Robert', 'javascript')\nconst programador1 = new Programadores(4, 'Lucas', 'python')\nprogramador.presentacion()\nprogramador1.presentacion()\n\n\n// Inserto el Gerente de proyectos en el array del Gerente\ngerente.empleadosACargo.push(gerenteDeProyecto)\n\n// Inserto los programadores en el array del Gerente de Proyectos\ngerenteDeProyecto.empleadosACargo.push(programador) \ngerenteDeProyecto.empleadosACargo.push(programador1)\n\n\nconsole.log('<-- Empleados a cargo del Gerente:')\n\ngerente.empleadosACargo.map(empleado => console.log(`Id: ${empleado.identificador} - nombre: ${empleado.nombre} - proyecto actual: ${empleado.proyecto}`))\n\nconsole.log('<-- Empleados a cargo del Gerente de proyectos:')\n\ngerenteDeProyecto.empleadosACargo.map(empleado => console.log(`Id: ${empleado.identificador} - nombre: ${empleado.nombre} - lenguaje: ${empleado.lenguaje}`))"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/victor-Casta.js",
    "content": "/*\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n*/\n\nclass Animal {\n  constructor(name, sonido) {\n    this.name = name;\n    this.sonido = sonido;\n  }\n\n  emitirSonido() {\n    console.log(this.sonido);\n  }\n}\n\nclass Perro extends Animal {\n  constructor(name) {\n    super(name, \"Guau guau\");\n  }\n}\n\nclass Gato extends Animal {\n  constructor(name) {\n    super(name, \"Miau miau\");\n  }\n}\n\nconst mi_perro = new Perro(\"Rufo\");\nconst mi_gato = new Gato(\"Bigotes\");\n\nmi_perro.emitirSonido(); // Output: Guau guau\nmi_gato.emitirSonido(); // Output: Miau miau\n\n\n/*\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n*/\nclass Empleado {\n  constructor(identificador, nombre) {\n    this.identificador = identificador;\n    this.nombre = nombre;\n  }\n}\n\nclass Gerente extends Empleado {\n  constructor(identificador, nombre, clientes) {\n    super(identificador, nombre);\n    this.clientes = clientes;\n    this.subordinados = []; // Almacenar empleados a cargo\n  }\n  \n  agregarSubordinado(empleado) {\n    this.subordinados.push(empleado);\n  }\n}\n\nclass GerenteDeProyecto extends Empleado {\n  constructor(identificador, nombre, proyecto) {\n    super(identificador, nombre);\n    this.proyecto = proyecto;\n    this.subordinados = []; // Almacenar empleados a cargo\n  }\n  \n  agregarSubordinado(empleado) {\n    this.subordinados.push(empleado);\n  }\n}\n\nclass Programador extends Empleado {\n  constructor(identificador, nombre, lenguaje) {\n    super(identificador, nombre);\n    this.lenguaje = lenguaje;\n  }\n}\n\n// Ejemplo de uso:\nconst gerente1 = new Gerente(1, \"Juan\", [\"Cliente A\", \"Cliente B\"]);\nconst gerenteDeProyecto1 = new GerenteDeProyecto(2, \"Pedro\", \"Proyecto X\");\nconst programador1 = new Programador(3, \"María\", \"JavaScript\");\n\n// Asignar subordinados a un gerente\ngerente1.agregarSubordinado(gerenteDeProyecto1);\ngerenteDeProyecto1.agregarSubordinado(programador1);\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/javascript/wapastorv.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n/* Herencia en JavaScript \n    * En JavaScript, la herencia se logra mediante la propiedad prototype de los objetos.\n    * En el siguiente ejemplo, se define una superclase Animal y dos subclases Perro y Gato.\n    * La función emitirSonido() se define en la superclase Animal y se sobreescribe en las subclases.\n*/\nclass Animal {\n    constructor(nombre, sonido){\n        this.nombre = nombre;\n        this.sonido = sonido;\n    }\n    hacerSonido(){\n        console.log(`${this.nombre} dice ${this.sonido}`);\n    }\n}\nclass Perro extends Animal {\n    constructor(nombre){\n        super(nombre, 'guau');// Llama al constructor de la superclase Animal, con super() y le pasa los argumentos necesarios. \n    }\n}\nclass Gato extends Animal {\n    constructor(nombre){\n        super(nombre, 'miau'); // Llama al constructor de la superclase Animal, con super() y le pasa los argumentos necesarios.\n    }\n}\nconst perro = new Perro('Firulais');\nconst gato = new Gato('Garfield');\nperro.hacerSonido();// Firulais dice guau\ngato.hacerSonido();// Garfield dice miau\n\n/*DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n\nclass Empleado {\n    #id; // Propiedad privada  para encapsular el id\n    constructor(id, nombre){\n        this.#id = id;// ID privado\n        this.nombre = nombre;\n    }\n    // Getter para acceder al id\n    getid(){\n        return this.#id;\n    }\n\n    //Método comun para todos los empleados\n    trabajar(){\n        console.log(`${this.nombre} está trabajando.`);\n    }\n}\n\n// clase Gerente que hereda de Empleado\nclass Gerente extends Empleado {\n    constructor(id, nombre){\n        super(id, nombre);\n        this.empleadosACargo = [];// Lista de empleados a cargo\n    }\n    // Método exclusivo de la clase Gerente\n    agregarEmpleado(empleado){\n        this.empleadosACargo.push(empleado);\n    }\n\n    // Método exclusivo de la clase Gerente\n    trabajar(){\n        console.log(`${this.nombre} está gestionado su equipo de ${this.empleadosACargo.length} empleados.`);\n    }\n\n    mostarEquipo(){\n        console.log(`${this.nombre} tiene a su cargo a:`);\n        this.empleadosACargo.forEach((empleado, index) => {\n            console.log(`${index + 1}. ${empleado.nombre} (ID: ${empleado.getid()})`);\n        });\n    }\n}\n\n//clase GerenteProyecto que hereda de Gerente\n\nclass GerenteProyecto extends Gerente {\n    constructor(id, nombre){\n        super(id, nombre);\n        this.proyectos = [];// Lista de proyectos\n    }\n\n    // Método exclusivo de la clase GerenteProyecto\n    agregarProyecto(proyecto){\n        this.proyectos.push(proyecto);\n    }\n\n    // Método exclusivo de la clase GerenteProyecto\n    trabajar(){\n        console.log(`${this.nombre} está gestionando los siguientes proyectos: ${this.proyectos.join(\", \")} proyectos.`);\n    }\n}\n\n// clase Programador que hereda de Empleado\nclass Programador extends Empleado {\n    constructor(id, nombre, lenguaje){\n        super(id, nombre);\n        this.lenguaje = lenguaje;\n    }\n    // Método exclusivo de la clase Programador\n    desarrollar(){\n        console.log(`${this.nombre} está desarrollando en ${this.lenguaje}.`);\n    }\n\n    trabajar(){\n        console.log(`${this.nombre} está escribiendo código en ${this.lenguaje}.`);\n    }\n}\n\n// Clase Diseñador que hereda de Empleado\nclass Diseñador extends Empleado {\n    constructor(id, nombre, especialidad){\n        super(id, nombre);\n        this.especialidad = especialidad;\n    }\n    diseñar(){\n        console.log(`${this.nombre} está creadi un diseño ${this.especialidad}.`);\n    }\n\n    trabajar(){\n        console.log(`${this.nombre} está creado un diseño ${this.especialidad}.`);\n    }\n}\n\n// Implementación de la jerarquía de empleados\nconst gerente = new Gerente(1, 'Laura');\nconst gerenteProyecto = new GerenteProyecto(2, 'Carlos');\nconst programador1 = new Programador(3, 'Juan', 'JavaScript');\nconst programador2 = new Programador(4, 'Ana', 'Python');\nconst diseñador = new Diseñador(5, 'María', 'UI/UX');\n\n// Asignación de empleados  a los gerentes\ngerente.agregarEmpleado(gerenteProyecto);\ngerenteProyecto.agregarEmpleado(programador1);\ngerenteProyecto.agregarEmpleado(programador2);\ngerenteProyecto.agregarEmpleado(diseñador);\n\n// Asignación de proyectos a los gerentes de proyecto\ngerenteProyecto.agregarProyecto('Sistema de ventas');\ngerenteProyecto.agregarProyecto('Aplicación móvil');\ngerenteProyecto.agregarProyecto('Plataforma web');\n\n// Interacturar con la jerarquía de empleados\n\ngerente.trabajar();// Laura está gestionado su equipo de 1 empleados.\ngerenteProyecto.trabajar();// Carlos está gestionando los siguientes proyectos: Sistema de ventas, Aplicación móvil, Plataforma web proyectos.\nprogramador1.trabajar();// Juan está escribiendo código en JavaScript.\nprogramador2.trabajar();// Ana está escribiendo código en Python.\ndiseñador.trabajar();// María está creado un diseño UI/UX.\n\n// Mostrar equipos\ngerente.mostarEquipo(); // Laura tiene a su cargo a: 1. Carlos (ID: 2)\n\ngerenteProyecto.mostarEquipo(); // Carlos tiene a su cargo a: 1. Juan (ID: 3) 2. Ana (ID: 4) 3. María (ID: 5)\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/kotlin/VincentRodriguezR.kt",
    "content": "//Clase padre, debe estar en open para que sea accesible para las demas  clases\nopen class animal(val nombre: String, val edad:Int){\n    open fun sonido(){\n        println(\"Los animales pueden tener muchos tipos de sonidos diferentes\")\n    }\n}\n\n//Calse heradada, se heredan los datos de nombre y edad pero las clases traen un atributo de raza propio\nclass perro(nombre: String, edad:Int, val raza: String): animal(nombre,edad){\n    //con Overide se demuestra el polimorfismo modificando por completo la funcionalidad del metodo llamado\n    override fun sonido() {\n        println(\"El perro hace Guau!\")\n    }\n}\n\nclass gato(nombre: String, edad:Int, val raza: String): animal(nombre,edad){\n    override fun sonido() {\n        println(\"El gato hace Miau!\")\n    }\n}\n\n//funcion intermedia para demostrar polimofismo\nfun hacerSonido(animal: animal){\n    animal.sonido()\n}\n\n//Ejercicio Extra\nopen class employee(val id: Int, val name:String){\n    var hierarchy = listOf(\"\")\n    open fun Id(){\n        println(\"el empleado con nombre $name se identifica con el numero $id\")\n    }\n\n    open fun labors(){\n        println(\"Descripcion de labores las cuales pueden variar dependiendo del rol\")\n    }\n\n    open fun inChargeEmployees(){\n        println(\"El empleado $name tiene a su cargo las siguienets personas $hierarchy\")\n    }\n\n    open fun shift(){\n        println(\"El horario puede variar dependiendo de que empleado sea\")\n    }\n\n}\n\nclass manager(name: String, id:Int): employee(id, name){\n    override fun labors() {\n        println(\"El gerente debe velar por el exito del proyecto orquestando todos los equipos necesarios para su desarrollo y asegurando una buena relacion y comunicacion con el cliente\")\n    }\n    override fun shift() {\n        println(\"El gerente peude trabajar en el horario que lo desee, debe estar disponible 24/7\")\n    }\n\n}\n\nclass projectManager(name: String, id:Int): employee(id, name){\n    override fun labors() {\n        println(\"El PM es el puente de comunicaicon entre los equipos de desarrollo y la gerencia, encargandose de orquestar todos los equipos para el exito del proyecto\")\n    }\n    override fun shift() {\n        println(\"El gerente de proyectos debe asistir en un horario de 8:00 Am a 6:00 Pm, y debe estar disponible 24/7\")\n    }\n}\n\nclass developer(name: String, id:Int): employee(id, name){\n    override fun labors() {\n        println(\"El desarrollador es el encargado de desarrollar todas las funciones requeridas por el cliente, es el encargado netamente de la parte tecnica del proyecto\")\n    }\n    override fun shift() {\n        println(\"El desarrollado peude trabajar en el horario que desee pero debe segurar su asistencia a las reuniones programadas, no debe estar disponible 24/7 a menos de que este asignado a disponibilidad del proyecto\")\n    }\n    override fun inChargeEmployees() {\n        println(\"Los desarrolladores no tienen personal a su cargo\")\n    }\n}\n\n//middle functions\nfun showlabors(employee: employee){\n    employee.labors()\n}\nfun showShift(employee: employee){\n    employee.shift()\n}\nfun showHierarchy(employee: employee){\n    employee.inChargeEmployees()\n}\n\n//al ejecutar la funcion intermedia que recibe un objeto de tipo animal se puede optimizar el codigo haciendo que una misma funcionalidad tenga comportamientos diferenets dependiendo de como se construya el objeto\nfun main(){\n    var nuevoPerro = perro(\"Zeus\", 14, \"schnauzer\")\n    hacerSonido(nuevoPerro)\n\n    var nuevoGato = gato(\"Chopper\", 7, \"Criollo\")\n    hacerSonido(nuevoGato)\n\n    //Ejecucion ejercicio extra\n\n    //Objects definition\n    //Manager\n    var managerHierarchy = listOf(\"PM Juan\", \"PM Pedro\", \"PM Andres\")\n    var newManager = manager(\"Alberto\", 314)\n    newManager.hierarchy = managerHierarchy\n    //Project Manager\n    var projectMagaerHierarchy = listOf(\"Dev Carlos\", \"Dev Sergio\", \"Dev Sandra\")\n    var newProjectManager = projectManager(\"Juan\", 480)\n    newProjectManager.hierarchy = projectMagaerHierarchy\n    //Developer\n    var newDeveloper = developer(\"Carlos\", 450)\n\n    //Run processes\n    //Manager\n    newManager.Id()\n    showlabors(newManager)\n    showShift(newManager)\n    showHierarchy(newManager)\n\n    //Project Manager\n    newProjectManager.Id()\n    showlabors(newProjectManager)\n    showShift(newProjectManager)\n    showHierarchy(newProjectManager)\n\n    //Developer\n    newDeveloper.Id()\n    showlabors(newDeveloper)\n    showShift(newDeveloper)\n    showHierarchy(newDeveloper)\n\n}"
  },
  {
    "path": "Roadmap/09 - HERENCIA/kotlin/adridoce.kt",
    "content": "fun main() {\n    val miPerro = Perro(\"Yaki\")\n    val miGato = Gato(\"Yoga\")\n\n    hacerSonido(miPerro)\n    hacerSonido(miGato)\n\n\n    val programador = Programador(1, \"Adri\", \"Kotlin\")\n    val gerente = Gerente(2, \"Pepe\", \"Marketing\")\n    val gerenteProyecto = GerenteProyecto(2, \"Juan\", \"herencia\")\n\n    programador.trabajar()\n    gerente.trabajar()\n    gerenteProyecto.trabajar()\n\n    gerenteProyecto.agregarSubordinado(programador)\n    gerenteProyecto.agregarSubordinado(gerente)\n    gerenteProyecto.verSubordinados()\n    gerenteProyecto.eliminarSubordinado(programador)\n    gerenteProyecto.verSubordinados()\n}\n\n/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n */\n\nopen class Animal(val nombre: String) {\n    open fun sonido() {}\n}\n\nclass Perro(nombre: String) : Animal(nombre) {\n    override fun sonido() {\n        println(\"Guau Guau!\")\n    }\n}\n\nclass Gato(nombre: String) : Animal(nombre) {\n    override fun sonido() {\n        println(\"Miau Miau!\")\n    }\n}\n\nfun hacerSonido(animal: Animal) {\n    animal.sonido()\n}\n\n/* DIFICULTAD EXTRA (opcional):\n* Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n* pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n* Cada empleado tiene un identificador y un nombre.\n* Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n* actividad, y almacenan los empleados a su cargo.\n*/\n\nopen class Empleado(val id: Int, val nombre: String) {\n    open fun trabajar() {\n        println(\"Empleado $nombre esta trabajando\")\n    }\n}\n\nclass Gerente(id: Int, nombre: String, val departamento: String) : Empleado(id, nombre) {\n    override fun trabajar() {\n        println(\"$nombre es gerente y esta en el departamento $departamento\")\n    }\n}\n\nclass GerenteProyecto(id: Int, nombre: String, val proyecto: String) : Empleado(id, nombre) {\n    val subordinados = mutableListOf<Empleado>()\n\n    fun agregarSubordinado(empleado: Empleado) {\n        subordinados.add(empleado)\n    }\n\n    fun eliminarSubordinado(empleado: Empleado) {\n        subordinados.remove(empleado)\n    }\n\n    fun verSubordinados() {\n        for (subordinado in subordinados) {\n            println(subordinado.nombre)\n        }\n    }\n\n    override fun trabajar() {\n        println(\"$nombre es gerente del proyecto $proyecto\")\n    }\n}\n\nclass Programador(id: Int, nombre: String, val lenguaje: String) : Empleado(id, nombre) {\n    override fun trabajar() {\n        println(\"$nombre es programador y utiliza $lenguaje\")\n    }\n}"
  },
  {
    "path": "Roadmap/09 - HERENCIA/kotlin/blackriper.kt",
    "content": "import com.sun.security.auth.UnixNumericUserPrincipal\r\nimport java.util.UUID\r\n\r\n/*\r\n La herencia es la capacidad de crear una nueva clase a partir de otra al hacer esto la clase padre o super\r\n clase puede pasar sus atributos y metodos a la clase hija o sub clase\r\n\r\n ventajas principales de la herencia:\r\n\r\n    -Organización de objetos: La herencia organiza los objetos en una jerarquía\r\n     desde lo más general hasta lo más específico.\r\n\r\n    -Relación entre clases: Representa la relación existente entre diferentes clases.\r\n\r\n    -Reutilización de código: Permite reutilizar el código existente, evitando tener que escribir\r\n     desde cero.\r\n\r\n    -Jerarquía de clases: Conforma una jerarquía de clases cada vez más especializada.\r\n\r\n    -Herencia múltiple: Algunos lenguajes permiten que una clase pueda heredar los atributos de varias superclases.\r\n */\r\n\r\n\r\n//ejemplo de herencia\r\n\r\n// nuestra superclase o clase padre en kotlin toso es final por defecto quiere decir que no espera\r\n// para que una clase puede ser heredada esta debe incluir la palabra open\r\nopen class Animal(val name: String) {\r\n    fun eat() = println(\"I'm eating\")\r\n    fun sound() = println(\"I'm making sound ${this.name}\")\r\n}\r\n\r\nclass Dog(name: String) : Animal(name) {\r\n    fun bark() = println(\"I'm barking\")\r\n}\r\n\r\nclass Cat(name: String) : Animal(name) {\r\n    fun meow() = println(\"I'm meowing\")\r\n}\r\n\r\n//ejercicio adicional\r\n\r\nenum class Role {\r\n    MANAGER,PROYECT_MANAGER ,PROGRAMMER\r\n}\r\n\r\n// la keyword protected permite que solo las clases hijas accedan al metodo work otras clases no podran acceder\r\nopen class Employee(val id:UUID,val name:String,val role:Role){\r\n    protected fun work():String=\"my name is $name and work as ${role.name.lowercase()}\"\r\n }\r\n\r\nclass Programmer(id: UUID, name: String, role: Role, val tecnology: String) : Employee(id, name, role){\r\n    fun code(){\r\n        println(this.work())\r\n        println(\"I'm coding in $tecnology\")\r\n    }\r\n}\r\n\r\nclass ProyectManager(id: UUID, name: String,\r\n                     role: Role, val projectName: String ,\r\n                     val team: List<Programmer>) : Employee(id, name, role){\r\n    fun manage(){\r\n        println(this.work())\r\n        println(\"I'm managing $projectName \")\r\n    }\r\n    fun manageTeam(){\r\n        team.forEach { println(\"${it.id} -- ${it.name}\" ) }\r\n    }\r\n}\r\n\r\nclass Manager(id: UUID, name: String,\r\n              role: Role, val team: List<ProyectManager>,\r\n              val department: String) : Employee(id, name, role){\r\n    fun manage(){\r\n        println(this.work())\r\n        println(\"I'm managing $department\")\r\n    }\r\n    fun manageTeam(){\r\n        team.forEach { println(\"${it.id} -- ${it.name}\" ) }\r\n    }\r\n}\r\n\r\n\r\nfun main() {\r\n    val dog = Dog(\"Max\")\r\n    val cat = Cat(\"Kitty\")\r\n    dog.eat()\r\n    dog.sound()\r\n    dog.bark()\r\n    cat.eat()\r\n    cat.sound()\r\n    cat.meow()\r\n\r\n    // ejercicio extra\r\n    // creando objetos programadores\r\n    val uuid=UUID.randomUUID()\r\n    val p1=Programmer(uuid,\"blackriper\",Role.PROGRAMMER, \"kotlin\")\r\n    val p2=Programmer(uuid,\"miguelex\",Role.PROGRAMMER, \"kotlin\")\r\n    val p3 = Programmer(uuid,\"allbertomd\",Role.PROGRAMMER, \"swift\")\r\n    val p4 = Programmer(uuid,\"didacdev\",Role.PROGRAMMER, \"swift\")\r\n\r\n    // llamndo a metodos propios\r\n    p1.code()\r\n    p2.code()\r\n    p3.code()\r\n    p4.code()\r\n\r\n    // creando listas de equipos a cargo del gerente de proyecto\r\n    val teamKotlin = listOf(p1,p2)\r\n    val teamSwift = listOf(p3,p4)\r\n\r\n    // creando el objeto gerente de proyecto\r\n    val pm1 = ProyectManager(uuid,\"Roswell\",Role.PROYECT_MANAGER, \"kotlin app\",teamKotlin)\r\n    val pm2= ProyectManager(uuid,\"Kontroldev\",Role.PROYECT_MANAGER, \"swift app\",teamSwift)\r\n\r\n    // llamando a metodos propios de encargado de proyecto\r\n    pm1.manage()\r\n    pm1.manageTeam()\r\n    pm2.manage()\r\n    pm2.manageTeam()\r\n    // creando listas de los gerentes de proyectos\r\n    val teamMoure = listOf(pm1,pm2)\r\n\r\n    // creando el objeto gerente\r\n    val m1 = Manager(uuid,\"mouredev\",Role.MANAGER,teamMoure,\"Mobile development\")\r\n\r\n    // llamando a metodos propios de gerente\r\n    m1.manage()\r\n    m1.manageTeam()\r\n\r\n\r\n\r\n}\r\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/kotlin/didacdev.kt",
    "content": "import java.util.UUID\n\nfun main() {\n    var gerente = Gerente(\"Paco\")\n    var gerentesDeProyectos1 = GerentesDeProyectos(\"Pedro\")\n    var gerentesDeProyectos2 = GerentesDeProyectos(\"Ana\")\n    var programador1 = Programador(\"Sandra\", mutableListOf(\"Swift\", \"Java\"))\n    var programador2 = Programador(\"Julian\", mutableListOf(\"Kotlin\"))\n    var programador3 = Programador(\"Jose\", mutableListOf(\"Python\", \"CSS\"))\n    var programador4 = Programador(\"Lisa\", mutableListOf(\"HTML\", \"C\"))\n\n    gerentesDeProyectos1.addProgramador(programador1)\n    gerentesDeProyectos1.addProgramador(programador2)\n    gerentesDeProyectos1.addProgramador(programador3)\n    gerentesDeProyectos2.addProgramador(programador4)\n\n    gerente.addGerenteDeProyectos(gerentesDeProyectos1)\n    gerente.addGerenteDeProyectos(gerentesDeProyectos2)\n\n    println(\"${programador1.nombre} sabe programar ${programador1.lenguajes}\")\n    println(\"${programador2.nombre} sabe programar ${programador2.lenguajes}\")\n    println(\"${programador3.nombre} sabe programar ${programador3.lenguajes}\")\n    println(\"${programador4.nombre} sabe programar ${programador4.lenguajes}\")\n\n    println(\"${gerentesDeProyectos1.nombre} está a cargo de:\")\n    for (programador in gerentesDeProyectos1.programadores) {\n        println(\"${programador.nombre}\")\n    }\n    println(\"${gerentesDeProyectos2.nombre} está a cargo de:\")\n    for (programador in gerentesDeProyectos2.programadores) {\n        println(\"${programador.nombre}\")\n    }\n    println(\"${gerente.nombre} manda sobre:\")\n    for (gerenteDeProyecto in gerente.gerentesDeProyectos) {\n        println(\"${gerenteDeProyecto.nombre}\")\n    }\n}\n\nopen class Empleado(val identificador: String = UUID.randomUUID().toString(), val nombre: String = \"\") {\n}\n\nclass Gerente(nombre: String) : Empleado(nombre = nombre) {\n    val gerentesDeProyectos: MutableList<GerentesDeProyectos> = mutableListOf()\n\n    fun addGerenteDeProyectos(gerente: GerentesDeProyectos) {\n        gerentesDeProyectos.add(gerente)\n    }\n}\n\nclass GerentesDeProyectos(nombre: String): Empleado(nombre = nombre) {\n    val programadores: MutableList<Programador> = mutableListOf()\n\n    fun addProgramador(programador: Programador) {\n        programadores.add(programador)\n    }\n}\n\nclass Programador(nombre: String, lenguajes: MutableList<String>): Empleado(nombre = nombre) {\n    val lenguajes: MutableList<String> = lenguajes\n\n    fun addLenguajes(lenguaje: String) {\n        lenguajes.add(lenguaje)\n    }\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/kotlin/eulogioep.kt",
    "content": "// Ejercicio principal: Animales\n\nopen class Animal(val nombre: String) {\n    open fun emitirSonido() {\n        println(\"$nombre hace un sonido genérico\")\n    }\n}\n\nclass Perro(nombre: String) : Animal(nombre) {\n    override fun emitirSonido() {\n        println(\"$nombre hace: Guau guau!\")\n    }\n}\n\nclass Gato(nombre: String) : Animal(nombre) {\n    override fun emitirSonido() {\n        println(\"$nombre hace: Miau miau!\")\n    }\n}\n\n// Dificultad extra: Jerarquía de empresa\n\nopen class Empleado(val id: Int, val nombre: String) {\n    open fun trabajar() {\n        println(\"$nombre está trabajando\")\n    }\n}\n\nclass Programador(id: Int, nombre: String, val lenguaje: String) : Empleado(id, nombre) {\n    override fun trabajar() {\n        println(\"$nombre está programando en $lenguaje\")\n    }\n}\n\nopen class Gerente(id: Int, nombre: String) : Empleado(id, nombre) {\n    val subordinados = mutableListOf<Empleado>()\n\n    fun agregarSubordinado(empleado: Empleado) {\n        subordinados.add(empleado)\n    }\n\n    override fun trabajar() {\n        println(\"$nombre está gestionando el equipo\")\n    }\n\n    open fun listarSubordinados() {\n        println(\"Subordinados de $nombre:\")\n        subordinados.forEach { println(\"- ${it.nombre}\") }\n    }\n}\n\nclass GerenteProyecto(id: Int, nombre: String, val proyecto: String) : Gerente(id, nombre) {\n    override fun trabajar() {\n        println(\"$nombre está gestionando el proyecto $proyecto\")\n    }\n\n    override fun listarSubordinados() {\n        println(\"Subordinados de $nombre en el proyecto $proyecto:\")\n        subordinados.forEach { println(\"- ${it.nombre}\") }\n    }\n}\n\nfun main() {\n    // Demostración de Animales\n    val perro = Perro(\"Buddy\")\n    val gato = Gato(\"Whiskers\")\n\n    perro.emitirSonido()\n    gato.emitirSonido()\n\n    // Demostración de Jerarquía de Empresa\n    val programador1 = Programador(1, \"Ana\", \"Kotlin\")\n    val programador2 = Programador(2, \"Carlos\", \"Java\")\n    val gerenteProyecto = GerenteProyecto(3, \"Diana\", \"App Móvil\")\n    val gerente = Gerente(4, \"Eduardo\")\n\n    gerenteProyecto.agregarSubordinado(programador1)\n    gerenteProyecto.agregarSubordinado(programador2)\n    gerente.agregarSubordinado(gerenteProyecto)\n\n    programador1.trabajar()\n    gerenteProyecto.trabajar()\n    gerente.trabajar()\n\n    gerenteProyecto.listarSubordinados()\n    gerente.listarSubordinados()\n}"
  },
  {
    "path": "Roadmap/09 - HERENCIA/kotlin/juanppdev.kt",
    "content": "    /*Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.*/\n\n\n// Definición de la superclase Animal\nopen class Animal(val nombre: String) {\n    open fun hacerSonido() {}\n}\n\n// Definición de la subclase Perro\nclass Perro(nombre: String) : Animal(nombre) {\n    override fun hacerSonido() {\n        println(\"$nombre dice: ¡Guau!\")\n    }\n}\n\n// Definición de la subclase Gato\nclass Gato(nombre: String) : Animal(nombre) {\n    override fun hacerSonido() {\n        println(\"$nombre dice: ¡Miau!\")\n    }\n}\n\n// Función para imprimir el sonido de un Animal\nfun imprimirSonido(animal: Animal) {\n    animal.hacerSonido()\n}\n\n// Ejemplo de uso\nfun main() {\n    val miPerro = Perro(\"Buddy\")\n    val miGato = Gato(\"Whiskers\")\n\n    imprimirSonido(miPerro) // Salida: Buddy dice: ¡Guau!\n    imprimirSonido(miGato)  // Salida: Whiskers dice: ¡Miau!\n}\n\n\n /*Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.*/\n\n// Clase base Empleado\nopen class Empleado(val identificador: Int, val nombre: String) {\n    open fun trabajar() {}\n}\n\n// Clase Gerente, subclase de Empleado\nclass Gerente(identificador: Int, nombre: String, val departamento: String) : Empleado(identificador, nombre) {\n    val empleadosACargo = mutableListOf<Empleado>()\n\n    fun asignarEmpleado(empleado: Empleado) {\n        empleadosACargo.add(empleado)\n    }\n\n    override fun trabajar() {\n        println(\"$nombre está supervisando el departamento $departamento\")\n    }\n}\n\n// Clase GerenteProyecto, subclase de Gerente\nclass GerenteProyecto(identificador: Int, nombre: String, departamento: String, val proyecto: String) : Gerente(identificador, nombre, departamento) {\n    override fun trabajar() {\n        println(\"$nombre está supervisando el proyecto $proyecto\")\n    }\n}\n\n// Clase Programador, subclase de Empleado\nclass Programador(identificador: Int, nombre: String, val lenguaje: String) : Empleado(identificador, nombre) {\n    override fun trabajar() {\n        println(\"$nombre está programando en $lenguaje\")\n    }\n}\n\n// Ejemplo de uso\nfun main() {\n    val gerente = Gerente(1, \"Juan\", \"Desarrollo\")\n    val gerenteProyecto = GerenteProyecto(2, \"Maria\", \"Desarrollo\", \"Sistema de Gestión\")\n    val programador1 = Programador(3, \"Pedro\", \"Python\")\n    val programador2 = Programador(4, \"Ana\", \"JavaScript\")\n\n    gerente.asignarEmpleado(programador1)\n    gerente.asignarEmpleado(programador2)\n\n    gerente.trabajar()\n    for (empleado in gerente.empleadosACargo) {\n        empleado.trabajar()\n    }\n\n    gerenteProyecto.trabajar()\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/kotlin/rikmij.kt",
    "content": "open class Animal {\n    val patas = 4\n    val cola = true\n    open fun talk() {\n    }\n}\n\nclass Perro : Animal() {\n    override fun talk() {\n        println(\"Guau\")\n    }\n}\n\nclass Gato : Animal() {\n    override fun talk() {\n        println(\"Miau\")\n    }\n}\n\nopen class Employee(\n    val name: String, private val identif: Int, private val employment: String,\n    private val employees: MutableList<Employee>\n) {\n    fun meetEmployee() {\n        println(\"$name ($employment): id - $identif\")\n    }\n\n    fun showEmployees() {\n        println(\"$name está a cargo de:\")\n        for (employee in employees) {\n            println(\"${employee.name} (${employee.employment}), identificador: ${employee.identif}\")\n        }\n    }\n}\n\nclass Programmer(\n    name: String, identif: Int, employment: String, employees: MutableList<Employee>,\n    private val language: String\n) : Employee(name, identif, employment, employees) {\n\n    fun work() {\n        println(\"-> $name: Estoy programando en $language\")\n    }\n}\n\nclass ProjectManager(\n    name: String, identif: Int, employment: String, employees: MutableList<Employee>,\n    private val project: String\n) : Employee(name, identif, employment, employees) {\n    fun supervise() {\n        println(\"\\n-> $name: Estoy \\\"supervisando\\\" $project. ¿Cómo vais muchachos?\")\n    }\n}\n\nclass Manager(\n    name: String, identif: Int, employment: String, employees: MutableList<Employee>,\n    private val organization: String\n) : Employee(name, identif, employment, employees) {\n    fun organize() {\n        println(\"\\n-> $name: Estoy organizando en $organization\")\n    }\n}\n\n\nfun main() {\n    val canino = Perro()\n    canino.talk()\n    println(canino.patas)\n\n    val michi = Gato()\n    michi.talk()\n    println(michi.cola)\n\n    println(\"${\"\\n\" + \"~\".repeat(7)} EJERCICIO EXTRA ${\"~\".repeat(7)}\")\n\n    val employeeList = mutableListOf<Employee>()\n    val victor = Programmer(\"Víctor\", 11, \"Programador\", mutableListOf(), \"Python\")\n    victor.work()\n    val joel = Programmer(\"Joel\", 12, \"Programador\", mutableListOf(), \"Java\")\n    joel.meetEmployee()\n\n    employeeList.add(victor)\n    employeeList.add(joel)\n\n    val giovanni = ProjectManager(\n        \"Giovanni\", 13, \"Project Manager\",\n        employeeList, \"COBOL Multiplatform\"\n    )\n    giovanni.supervise()\n    giovanni.showEmployees()\n\n    employeeList.add(giovanni)\n\n    val jetbrains = Manager(\"JetBrains\", 14, \"Manager\", employeeList, \"Kotlin\")\n    jetbrains.organize()\n    jetbrains.showEmployees()\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/kotlin/thegera4.kt",
    "content": "// En Kotlin, necesitamos agregar la palabra 'open' a la clase padre (para que puede heredar)\n// y a la función que queremos sobreescribir (cambiar) en la clase hija.\nopen class Animal(val nombre: String) {\n    open fun sonido() {\n        println(\"$nombre hace un sonido.\")\n    }\n}\n \n// La clase Perro hereda de la clase Animal\nclass Perro(nombre: String) : Animal(nombre) {\n    // Sobreescribimos la función sonido\n    override fun sonido() {\n        println(\"$nombre hace guau.\")\n    }\n}\n\nclass Gato(nombre: String) : Animal(nombre) {\n    override fun sonido() {\n        println(\"$nombre hace miau.\")\n    }\n}\n\nfun main() {\n    val perro = Perro(\"Firulais\")\n    val gato = Gato(\"Garfield\")\n\n    perro.sonido()\n    gato.sonido()\n\n    //Extra\n    val empleado1 = Empleado(1, \"Juan\")\n    val empleado2 = Empleado(2, \"Pedro\")\n    val empleado3 = Empleado(3, \"Maria\")\n\n    val gerente = Gerente(4, \"Luis\", listOf(empleado1, empleado2, empleado3))\n    val programador = Programador(5, \"Carlos\", \"Kotlin\")\n    val gerenteProyecto = GerenteProyecto(6, \"Ana\", \"Martes\")\n\n    gerente.trabajar()\n    gerente.evaluar()\n    programador.trabajar()\n    programador.programar()\n    gerenteProyecto.trabajar()\n    gerenteProyecto.coordinar()\n\n}\n\n//Extra:\nopen class Empleado(val id: Int, val nombre: String) {\n    fun trabajar() {\n        println(\"El empleado $id de nombre $nombre está trabajando...\")\n    }\n}\n\nclass Gerente(id: Int, nombre: String, val subordinados: List<Empleado>) : Empleado(id, nombre) {\n    fun evaluar() {\n        val empleadosSubordinados = subordinados.map { it.nombre }\n        println(\"$nombre está evaluando a sus empleados: $empleadosSubordinados\")\n    }\n}\n\nclass Programador(id: Int, nombre: String, val lenguajeFavorito: String) : Empleado(id, nombre) {\n    fun programar() {\n        println(\"$nombre está programando en $lenguajeFavorito.\")\n    }\n}\n\nclass GerenteProyecto(id: Int, nombre: String, val diaFavorito: String) : Empleado(id, nombre) {\n    fun coordinar() {\n        println(\"Al gerente de proyecto $nombre le gusta hacer juntas los $diaFavorito\")\n    }\n}"
  },
  {
    "path": "Roadmap/09 - HERENCIA/ocaml/luishendrix92.ml",
    "content": "open Printf\n\n(**************************************************************************)\n(*                                                                        *)\n(*                           Class Inheritance                            *)\n(*                                                                        *)\n(*  Inheritance is possible in OCaml, however, it's failry limited and    *)\n(*  you need to use the explicit subtype to parent type coercion          *)\n(*  operator [:>] to, for example, keep a list of subtypes of the same    *)\n(*  parent type. The only caveat is that once you coerce an object's      *)\n(*  type, you will not be able to call specialized subtype methods.       *)\n(*                                                                        *)\n(*  The way inheritance works in OCaml is throug the [inherit] keyword    *)\n(*  right at the start of an object definition; this keyword behaves      *)\n(*  the same way as the [super] constructor in langauges like Java/C#.    *)\n(*    You can also define a class as virtual (and some or all methods)    *)\n(*  so that the programmer can't instantiate it but can extend it and     *)\n(*  use or override the default implementation of its virtual methods.    *)\n(*  The language also features class types as pseudo-interfaces and       *)\n(*  member/method restrictors, but that's a topic for another time :) !   *)\n(*                                                                        *)\n(**************************************************************************)\n\nclass virtual animal name age breed =\n  object\n    val mutable name : string = name\n    val mutable age : int = age\n    val breed : string = breed\n    method get_name = name\n    method set_name name' = name <- name'\n    method get_age = age\n    method set_age age' = age <- age'\n    method get_breed = breed\n    method virtual make_sound : unit\n  end\n\nclass dog name age breed =\n  object (self)\n    inherit animal name age breed\n\n    method make_sound =\n      printf\n        \"%s the %d year old %s dog says: WOOF WOOF!!\\n\"\n        self#get_name\n        self#get_age\n        self#get_breed\n  end\n\nclass cat name age breed =\n  object (self)\n    inherit animal name age breed\n\n    method make_sound =\n      printf\n        \"%s the %d year old %s cat says: MEOW MEOW...\\n\"\n        self#get_name\n        self#get_age\n        self#get_breed\n  end\n\nlet () =\n  (* These 2 animals don't require type coercion because none of these subtypes\n     implement methods that aren't defined in the parent type. Virtual methods\n     defined in the parent type can be either left unimplemented and ready for\n     any subtype to implement them by themselves; or, they can be defined and\n     let the subtype choose to overwrite or use the default implementation. *)\n  let firulais : animal = new dog \"Firulais\" 3 \"Dachshund\" in\n  let bigotes : animal = new cat \"Bigotes\" 12 \"Russian Blue\" in\n  firulais#make_sound;\n  bigotes#make_sound;\n  print_newline ()\n;;\n\n(**************************************************************************)\n(*                                                                        *)\n(*                      Dificultad Extra (Opcional)                       *)\n(*                                                                        *)\n(*  Implementa la jerarquía de una empresa de desarrollo formada por      *)\n(*  empleados que pueden ser gerentes, gerentes de proyectos o            *)\n(*  programadores. Cada empleado tiene un identificador y un nombre.      *)\n(*  Dependiendo de su labor, tienen propiedades y funciones exclusivas    *)\n(*  de su actividad, y almacenan los empleados a su cargo.                *)\n(*                                                                        *)\n(**************************************************************************)\n\nlet curr_id : int ref = ref 0\n\nclass virtual employee name skills =\n  let generated_id =\n    incr curr_id;\n    !curr_id\n  in\n  object\n    val id : int = generated_id\n    val name : string = name\n    val mutable skills : string list = skills\n    method get_id = id\n    method get_name = name\n    method get_skills = skills\n    method set_skills skills' = skills <- skills'\n    method virtual to_string : string\n  end\n\ntype proj =\n  { name : string\n  ; requirements : string list\n  }\n\nclass programmer name languages =\n  object (self : 'a)\n    inherit employee name languages\n    method get_languages = self#get_skills\n\n    method learn_language language =\n      self#set_skills (language :: self#get_skills)\n\n    method to_string =\n      sprintf\n        \"[Programmer #%d | Name: %s | Tech stack: %s]\"\n        self#get_id\n        self#get_name\n        (String.concat \", \" self#get_skills)\n  end\n\nclass project_manager name skills project =\n  let open Core.Option in\n  object (self : 'a)\n    inherit employee name skills\n    val mutable project : proj option = project\n    val mutable team : employee list = []\n    method get_project = project\n\n    method private get_project_name =\n      match project with\n      | Some project -> sprintf \"project '%s'\" project.name\n      | None -> \"no project\"\n\n    method assign_project project' =\n      project <- project';\n      printf\n        \"%s has been assigned %s to manage!\\n\"\n        self#get_name\n        self#get_project_name\n\n    method select_team (candidates : employee list) =\n      team\n      <- Core.List.filter\n           ~f:(fun candidate ->\n             let requirements =\n               Option.fold ~none:[] ~some:(fun p -> p.requirements) project\n             in\n             Core.List.exists\n               ~f:(fun skill ->\n                 Core.List.exists ~f:(fun req -> req = skill) requirements)\n               candidate#get_skills)\n           candidates;\n      printf\n        \"%s were selected to work for PM %s on %s!\\n\"\n        (List.map (fun e -> e#get_name) team |> String.concat \", \")\n        self#get_name\n        self#get_project_name\n\n    method to_string =\n      sprintf\n        \"[PM #%d | Name: %s | Managing: %s | Skills: %s]\"\n        self#get_id\n        self#get_name\n        self#get_project_name\n        (String.concat \", \" self#get_skills)\n  end\n\nlet () =\n  let e1 =\n    new programmer \"Luis\" [ \"spring boot\"; \"github\"; \"ocaml\"; \"circleci\" ]\n  in\n  let e2 = new programmer \"Karla\" [ \"python\"; \"figma\"; \".net\"; \"mongodb\" ] in\n  let e3 = new programmer \"Doug\" [ \"flutter\"; \"github\"; \"aws\"; \"azure\" ] in\n  let e4 = new programmer \"Smith\" [ \"react\"; \"javascript\"; \"c#\"; \"angular\" ] in\n  let e5 = new programmer \"Marina\" [ \"haskell\"; \"python\" ] in\n  let pm1 =\n    new project_manager \"Moure\" [ \"scrum\"; \"architecture design\" ] None\n  in\n  let pm2 =\n    new project_manager \"Julia\" [ \"scrum\"; \"devops\"; \"mobile development\" ] None\n  in\n  print_endline \"Corporation roster:\";\n  print_endline \"-------------------\";\n  print_endline e1#to_string;\n  print_endline e2#to_string;\n  print_endline e3#to_string;\n  print_endline e4#to_string;\n  print_endline e5#to_string;\n  print_endline pm1#to_string;\n  print_endline pm2#to_string;\n  print_endline \"-------------------\";\n  pm1#assign_project\n  @@ Some\n       { name = \"MoureApp\"\n       ; requirements = [ \"flutter\"; \"aws\"; \"github\"; \"spring boot\" ]\n       };\n  pm2#assign_project\n  @@ Some\n       { name = \"AirBnB\"\n       ; requirements = [ \"react\"; \"mongodb\"; \".net\"; \"rabbitmq\" ]\n       };\n  (* Type coercion from subtype to parent type is needed because the code that\n     is consuming them (select_team) needs a list of any employee subtype (not\n     just programmers) and it will not use any specialized method. *)\n  let candidates : employee list =\n    [ (e1 : programmer :> employee)\n    ; (e2 : programmer :> employee)\n    ; (e3 : programmer :> employee)\n    ; (e4 : programmer :> employee)\n    ; (e5 : programmer :> employee)\n    ]\n  in\n  pm1#select_team candidates;\n  pm2#select_team candidates;\n  print_endline \"-------------------\";\n  print_endline \"Marina's current skills didn't fit any existing project but...\";\n  print_endline\n    \"a new project is coming and she learns 2 of its 3 requirements.\";\n  pm1#assign_project\n  @@ Some\n       { name = \"WhatIsThis 2.0\"\n       ; requirements = [ \"machine learning\"; \"pytorch\"; \"scikitlearn\" ]\n       };\n  e5#learn_language \"machine learning\";\n  e5#learn_language \"pytorch\";\n  pm1#select_team candidates\n;;\n\n(* Output of running [dune exec reto9]\n   ===================================\n   Firulais the 3 year old Dachshund dog says: WOOF WOOF!!\n   Bigotes the 12 year old Russian Blue cat says: MEOW MEOW...\n\n   Corporation roster:\n   -------------------\n   [Programmer #1 | Name: Luis | Tech stack: spring boot, github, ocaml, circleci]\n   [Programmer #2 | Name: Karla | Tech stack: python, figma, .net, mongodb]\n   [Programmer #3 | Name: Doug | Tech stack: flutter, github, aws, azure]\n   [Programmer #4 | Name: Smith | Tech stack: react, javascript, c#, angular]\n   [Programmer #5 | Name: Marina | Tech stack: haskell, python]\n   [PM #6 | Name: Moure | Managing: no project | Skills: scrum, architecture design]\n   [PM #7 | Name: Julia | Managing: no project | Skills: scrum, devops, mobile development]\n   -------------------\n   Moure has been assigned project 'MoureApp' to manage!\n   Julia has been assigned project 'AirBnB' to manage!\n   Luis, Doug were selected to work for PM Moure on project 'MoureApp'!\n   Karla, Smith were selected to work for PM Julia on project 'AirBnB'!\n   -------------------\n   Marina's current skills didn't fit any existing project but...\n   a new project is coming and she learns 2 of its 3 requirements.\n   Moure has been assigned project 'WhatIsThis 2.0' to manage!\n   Marina were selected to work for PM Moure on project 'WhatIsThis 2.0'!\n*)\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/php/eulogioep.php",
    "content": "<?php\n\n// Ejemplo de implementación del concepto de herencia en PHP\n\n// Definición de la clase base (superclase) Animal\nclass Animal {\n  protected $especie;\n  protected $sonido;\n\n  public function __construct($especie, $sonido) {\n    $this->especie = $especie;\n    $this->sonido = $sonido;\n  }\n\n  // Método que muestra el sonido que hace el animal\n  public function hacerSonido() {\n    return \"El \" . $this->especie . \" hace: \" . $this->sonido;\n  }\n}\n\n// Definición de la subclase Perro\nclass Perro extends Animal {\n  private $nombre;\n\n  public function __construct($nombre, $especie, $sonido) {\n    parent::__construct($especie, $sonido); // Llamada al constructor de la superclase\n    $this->nombre = $nombre;\n  }\n\n  // Método exclusivo de la subclase Perro\n  public function ladrar() {\n    return $this->nombre . \" lanza un ladrido\";\n  }\n}\n\n// Definición de la subclase Gato\nclass Gato extends Animal {\n  private $nombre;\n\n  public function __construct($nombre, $especie, $sonido) {\n    parent::__construct($especie, $sonido); // Llamada al constructor de la superclase\n    $this->nombre = $nombre;\n  }\n\n  // Método exclusivo de la subclase Gato\n  public function maullar() {\n    return $this->nombre . \" emite un maullido\";\n  }\n}\n\n// Ejemplo de implementación adicional (dificultad extra)\n// Definición de la clase base (superclase) Empleado\nclass Empleado {\n  protected $id;\n  protected $nombre;\n\n  public function __construct($id, $nombre) {\n    $this->id = $id;\n    $this->nombre = $nombre;\n  }\n}\n\n// Definición de la subclase Gerente que hereda de Empleado\nclass Gerente extends Empleado {\n  private $subordinados;\n\n  public function __construct($id, $nombre, array $subordinados) {\n    parent::__construct($id, $nombre);\n    $this->subordinados = $subordinados;\n  }\n\n  // Método exclusivo de la subclase Gerente\n  public function informarSobreSubordinados() {\n    $informacion = \"El gerente \" . $this->nombre . \" tiene a los siguientes subordinados: \\n\";\n    foreach ($this->subordinados as $subordinado) {\n      $informacion .= \" - \" . $subordinado->nombre . \"\\n\";\n    }\n    return $informacion;\n  }\n}\n\n// Definición de la subclase GerenteDeProyectos que hereda de Empleado\nclass GerenteDeProyectos extends Empleado {\n  private $proyectos;\n\n  public function __construct($id, $nombre, array $proyectos) {\n    parent::__construct($id, $nombre);\n    $this->proyectos = $proyectos;\n  }\n\n  // Método exclusivo de la subclase GerenteDeProyectos\n  public function informarSobreProyectos() {\n    $informacion = \"El gerente de proyectos \" . $this->nombre . \" tiene los siguientes proyectos: \\n\";\n    foreach ($this->proyectos as $proyecto) {\n      $informacion .= \" - \" . $proyecto . \"\\n\";\n    }\n    return $informacion;\n  }\n}\n\n// Definición de la subclase Programador que hereda de Empleado\nclass Programador extends Empleado {\n  private $lenguajes;\n\n  public function __construct($id, $nombre, array $lenguajes) {\n    parent::__construct($id, $nombre);\n    $this->lenguajes = $lenguajes;\n  }\n\n  // Método exclusivo de la subclase Programador\n  public function informarSobreLenguajes() {\n    $informacion = \"El programador \" . $this->nombre . \" domina los siguientes lenguajes: \\n\";\n    foreach ($this->lenguajes as $lenguaje) {\n      $informacion .= \" - \" . $lenguaje . \"\\n\";\n    }\n    return $informacion;\n  }\n}\n\n// Ejemplo de uso\n$perro = new Perro(\"Lucky\", \"Perro\", \"Gua\");\necho $perro->hacerSonido(); // El Perro hace: Gua\necho $perro->ladrar(); // Lucky lanza un ladrido\n\n$gato = new Gato(\"Whiskers\", \"Gato\", \"Miau\");\necho $gato->hacerSonido(); // El Gato hace: Miau\necho $gato->maullar(); // Whiskers emite un maullido\n\n$gerente = new Gerente(1, \"Juan Perez\", [new Programador(2, \"Maria Rodriguez\", [\"JavaScript\", \"PHP\"])]);\necho $gerente->informarSobreSubordinados();\n\n$gerenteProyectos = new GerenteDeProyectos(3, \"Luis Martinez\", [\"Proyecto A\", \"Proyecto B\"]);\necho $gerenteProyectos->informarSobreProyectos();\n\n$programador = new Programador(4, \"Karla Sanchez\", [\"JavaScript\", \"PHP\"]);\necho $programador->informarSobreLenguajes();"
  },
  {
    "path": "Roadmap/09 - HERENCIA/php/gabrielmoris.php",
    "content": "<?php\n/*\n * EXERCISE:\n * Explore the concept of inheritance in your language. Create an example that\n * implements a superclass Animal and a pair of subclasses Dog and Cat,\n * along with a function that prints the sound each Animal makes.\n */\n\n\nclass Animal\n{\n    protected $name;\n    protected $activity;\n\n    public function __construct($name, $activity)\n    {\n        $this->name = $name;\n        $this->activity = $activity;\n    }\n\n    public function what_is_doing()\n    {\n        echo $this->name . \" \" . $this->activity . \"\\n\";\n    }\n}\n\nclass Dog extends Animal\n{\n    private $sound;\n\n    public function __construct($name, $activity, $sound)\n    {\n        parent::__construct($name, $activity); // Call the parent constructor\n        $this->sound = $sound;\n    }\n\n    public function make_sound()\n    {\n        echo $this->name . \" makes \" . $this->sound . \"\\n\";\n    }\n}\n\nclass Cat extends Animal\n{\n    private $sound;\n\n    public function __construct($name, $activity, $sound)\n    {\n        parent::__construct($name, $activity);\n        $this->sound = $sound;\n    }\n\n    public function make_sound()\n    {\n        echo $this->name . \" makes \" . $this->sound . \"\\n\";\n    }\n}\n\n$cat = new Cat(\"Felix\", \"asks for food\", \"Miauuuu\");\n$cat->what_is_doing();\n$cat->make_sound();\n\n$dog = new Dog(\"Pipo\", \"runs after a cat\", \"Woof Wof\");\n$dog->what_is_doing();\n$dog->make_sound();\n\n/* EXTRA CHALLENGE (optional):\n * Implement the hierarchy of a development company consisting of Employees who\n * can be Managers, Project Managers, or Programmers.\n * Each employee has an identifier and a name.\n * Depending on their role, they have properties and functions exclusive to their\n * activity, and they store the employees under their supervision.\n */\nclass Employee\n{\n    protected $name;\n    protected $identifier;\n    protected $activity;\n\n    public function __construct($name, $identifier, $activity)\n    {\n        $this->name = $name;\n        $this->identifier = $identifier;\n        $this->activity = $activity;\n    }\n\n    public function what_are_you_doing()\n    {\n        echo $this->name . \" is \" . $this->activity . \"\\n\";\n    }\n\n    public function get_name()\n    {\n        return $this->name;\n    }\n};\n\n\nclass Manager extends Employee\n{\n    private $managed_pm;\n\n    public function __construct($name, $identifier, $activity)\n    {\n        parent::__construct($name, $identifier, $activity);\n        $this->managed_pm = [];\n    }\n\n    // OverWrite Parent Method\n    public function what_are_you_doing()\n    {\n        if (!empty($this->managed_pm)) {\n\n            foreach ($this->managed_pm as $project_manager) {\n                echo $this->name . \" asks \" . $project_manager->get_name() . \" what is he doing.\\n\";\n                $project_manager->what_are_you_doing();\n            }\n        } else {\n            echo $this->name . \" \" . $this->activity . \"\\n\";\n        }\n    }\n\n    public function add_pm($new_pm)\n    {\n        $this->managed_pm[] = $new_pm;\n    }\n\n    public function fire_everyone()\n    {\n        $output = \"\";\n        foreach ($this->managed_pm as $project_manager) {\n            if ($project_manager instanceof Project_manager) {\n                $output .=  $project_manager->fire_devs();\n            }\n        }\n        $this->managed_pm = [];\n        $output .= $this->name . \" is now alone and sad.\\n\";\n        echo $output;\n    }\n}\n\nclass Project_manager extends Employee\n{\n    private $managed_devs;\n\n    public function __construct($name, $identifier, $activity)\n    {\n        parent::__construct($name, $identifier, $activity);\n        $this->managed_devs = [];\n    }\n\n    // OverWrite Parent Method\n    public function what_are_you_doing()\n    {\n        if (!empty($this->managed_devs)) {\n\n            foreach ($this->managed_devs as $dev) {\n                echo $this->name . \" asks \" . $dev->get_name() . \" what is he doing. \" . $dev->what_are_you_doing();\n            }\n        } else {\n            echo $this->name . \" \" . $this->activity . \"\\n\";\n        }\n    }\n\n    public function add_dev($new_dev)\n    {\n        $this->managed_devs[] = $new_dev;\n    }\n\n\n    public function fire_devs()\n    {\n        $output = \"\";\n        foreach ($this->managed_devs as $dev) {\n            $output .= $this->name . \" fired \" . $dev->get_name() . \". He \" . $dev->complain() . \".\\n\";\n        }\n        $this->managed_devs = [];\n        return $output;\n    }\n}\n\nclass Developer extends Employee\n{\n    public function __construct($name, $identifier, $activity)\n    {\n        parent::__construct($name, $identifier, $activity);\n    }\n\n    // OverWrite Parent Method\n    public function what_are_you_doing()\n    {\n        return $this->name . \" \" . $this->activity  . \".\\n\";\n    }\n\n    public function complain()\n    {\n        $arr_of_complains = [\"says - NOOOoooo\", \"cries silently..\", \"enters in a state of rage and burns the complete building\", \"runs in circles\", \"now has more time for his other side jobs\", \"doesn't accept it\"];\n\n        $complain = $arr_of_complains[array_rand($arr_of_complains)];\n\n        return $complain;\n    }\n}\n\necho \"================== THE OFFICE ==================\\n\";\n$manager = new Manager(\"Juan\", \"Manager\", \"is making a coffe\");\n$pm1 = new Project_manager(\"Jean\", \"P_M\", \"hepls devs to make a cofffe\");\n$pm2 = new Project_manager(\"Julian\", \"P_M\", \"drinks his coffe\");\n$dev1 = new Developer(\"John\", \"Dev\", \"looks the manager how he makes a coffe\");\n$dev2 = new Developer(\"Jim\", \"Dev\", \"grinds coffe\");\n$dev3 = new Developer(\"Jan\", \"Dev\", \"coding\");\n$future_dev4 = new Developer(\"Jonny\", \"Dev\", \"something\");\n$pm1->add_dev($dev1);\n$pm1->add_dev($dev2);\n$pm2->add_dev($dev3);\n\n$manager->what_are_you_doing(); // Juan is making a coffee.\n$manager->add_pm($pm1);\n$manager->add_pm($pm2);\n$pm1->what_are_you_doing();\n// Jean asks John what is he doing. John looks the manager how he makes a coffe. \n// Jean asks Jim what is he doing. Jim grinds coffe.\necho $pm2->fire_devs(); // Julian fired Jan. He runs in circles.\n$pm2->add_dev($future_dev4);\n$manager->fire_everyone();\n// Jean fired John. He cries silently...\n// Jean fired Jim. He runs in circles.\n// Julian fired Jonny. He enters in a state of rage and burns the complete building.\n// Juan is now alone and sad."
  },
  {
    "path": "Roadmap/09 - HERENCIA/php/marcode24.php",
    "content": "<?php\n\n/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n\n\n// Superclase Animal\nclass Animal {\n    public $nombre;\n\n    public function __construct($nombre) {\n        $this->nombre = $nombre;\n    }\n\n    // Método para imprimir el sonido del animal\n    public function hacerSonido() {\n        echo \"El animal hace un sonido\\n\";\n    }\n}\n\n// Subclase Perro que hereda de Animal\nclass Perro extends Animal {\n    public function __construct($nombre) {\n        parent::__construct($nombre);\n    }\n\n    // Método para imprimir el ladrido del perro\n    public function hacerSonido() {\n        echo \"El perro $this->nombre hace guau\\n\";\n    }\n}\n\n// Subclase Gato que hereda de Animal\nclass Gato extends Animal {\n    public function __construct($nombre) {\n        parent::__construct($nombre);\n    }\n\n    // Método para imprimir el maullido del gato\n    public function hacerSonido() {\n        echo \"El gato $this->nombre hace miau\\n\";\n    }\n}\n\n// Crear instancias de Perro y Gato\n$miPerro = new Perro('Bobby');\n$miGato = new Gato('Whiskers');\n\n// Llamar al método para hacer sonido de cada animal\n$miPerro->hacerSonido(); // Imprime: El perro Bobby hace guau\n$miGato->hacerSonido(); // Imprime: El gato Whiskers hace miau\n\n// Visita mi repo en GitHub para ver y correr los tests de este código --> https://github.com/marcode24/weekly-challenges\n\n\n?>"
  },
  {
    "path": "Roadmap/09 - HERENCIA/php/miguelex.php",
    "content": "<?php\n\n    class Animal {\n        private $nombre;\n\n        public function __construct ($nombre){\n            $this->nombre = $nombre;\n        \n        }\n        public function getNombre() {\n            return $this->nombre;\n        }\n        public function sonido() {\n            return \"Sonido de animal\";\n        }\n    }\n\n    class Perro extends Animal {\n\n        public function __construct($nombre) {\n            parent::__construct($nombre);\n        }\n        public function sonido() {\n            return \"EL perro de nombre {$this->getNombre()} hace el sonido Guau\";\n        }\n    }\n       \n\n    class Gato extends Animal {\n        public function __construct($nombre) {\n            parent::__construct($nombre);\n        }\n        public function sonido() {\n            return \"EL gato de nombre {$this->getNombre()} hace el sonido Miau\";\n        }\n    }\n\n    $perro = new Perro(\"Milu\");\n    echo $perro->sonido();\n    echo \"\\n\";\n    $gato = new Gato(\"Garfield\");\n    echo $gato->sonido();\n\n    // EXTRA\n\n    class Empleado {\n        private $id;\n        private $name;\n\n        public function __construct($id, $name) {\n            $this->id = $id;\n            $this->name = $name;\n        }\n\n        public function getId(){\n            return $this->id;\n        }\n\n        public function getName(){\n            return $this->name;\n        }\n    }\n\n    class Gerente extends Empleado {\n        private $empleados = [];\n        \n        public function __construct($id , $name, $empleados) {\n            parent::__construct($id, $name);\n            $this->empleados = $empleados;\n        }\n\n        public function __toString(){\n            $empleados = implode(\", \", $this->empleados);\n            return \"El gerente {$this->getName()} tiene a su cargo a los empleados: {$empleados}\";\n        }\n\n        public function gestion(){\n            return \"El gerente {$this->getName()} esta gestionando un total de \" . count($this->empleados) . \" gerentes de proyecto\";\n        }\n    }\n\n    class GerenteP extends Empleado{\n        private $programadores = [];\n\n        public function __construct($id, $name, $programadores){\n            parent::__construct($id, $name);\n            $this->programadores = $programadores;\n        }\n\n        public function __toString(){\n            $programadores = implode(\", \", $this->programadores);\n            return \"El gerente de proyecto {$this->getName()} tiene a su cargo los programadores: {$programadores}\";\n        }\n\n        public function gestion(){\n            return \"El gerente de proyecto {$this->getName()} esta gestionando un total de \" . count($this->programadores) . \" programadores\";\n        }\n    }\n\n    class Programador extends Empleado {\n        private $lenguajes = [];\n\n        public function __construct($id, $name, $lenguajes){\n            parent::__construct($id, $name);\n            $this->lenguajes = $lenguajes;\n        }\n\n        public function __toString(){\n            $lenguajes = implode(\", \", $this->lenguajes);\n            return \"El programador {$this->getName()} sabe los lenguajes: {$lenguajes}\";\n        }\n\n        public function programar(){\n            return \"El programador {$this->getName()} esta programando en un total de \" . count($this->lenguajes) . \" lenguajes\";\n        }\n    }\n\n\n    echo \"\\n\";\n\n    $gerente1 = new Gerente (1, \"Miguel\", [\"Juan\", \"Pedro\", \"Luis\"]);\n    echo $gerente1;\n    echo \"\\n\";\n    echo $gerente1->gestion();\n    echo \"\\n\";\n\n\n    $gerente2 = new Gerente (2, \"Luis\", [\"Maria\", \"Ana\"]);\n    echo $gerente2 . \"\\n\";\n    echo $gerente2->gestion();\n    echo \"\\n\";\n\n    $gerenteP1 = new GerenteP (3, \"Juan\", [\"Carlos\", \"Jose\"]);\n    echo $gerenteP1 . \"\\n\";\n    echo $gerenteP1->gestion();\n    echo \"\\n\";\n\n    $gerenteP2 = new GerenteP (4, \"Ana\", [\"Sara\", \"Lucia\"]);\n    echo $gerenteP2 . \"\\n\";\n    echo $gerenteP2->gestion();\n    echo \"\\n\";\n\n    $programador1 = new Programador (5, \"Carlos\", [\"PHP\", \"JS\"]);\n    echo $programador1 . \"\\n\";\n    echo $programador1->programar();\n    echo \"\\n\";\n\n    $programador2 = new Programador (6, \"Jose\", [\"C#\", \"Python\", \"Ada\", \"Kotlin\"]);\n    echo $programador2 . \"\\n\";\n    echo $programador2->programar();\n    echo \"\\n\";\n    \n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/php/rxvlc.php",
    "content": "<?php\n\n// Superclase\nclass Animal {\n    protected $nombre;\n    protected $edad;\n\n    public function __construct($nombre, $edad) {\n        $this->nombre = $nombre;\n        $this->edad = $edad;\n    }\n}\n\n// Heredera Perro\nclass Perro extends Animal {\n    public function sonido() {\n        echo \"¡guau guau!\\n\";\n    }\n}\n\n// Heredera Gato\nclass Gato extends Animal {\n    public function sonido() {\n        echo \"¡miau miau!\\n\";\n    }\n}\n\n// Clase base abstracta para representar a un empleado genérico\nabstract class Empleado {\n    protected $id;\n    protected $nombre;\n\n    public function __construct($id, $nombre) {\n        $this->id = $id;\n        $this->nombre = $nombre;\n    }\n\n    abstract public function informacion();\n}\n\n// Clase Gerente hereda de Empleado\nclass Gerente extends Empleado {\n    protected $empleadosACargo;\n\n    public function __construct($id, $nombre) {\n        parent::__construct($id, $nombre);\n        $this->empleadosACargo = [];\n    }\n\n    public function agregarEmpleado($empleado) {\n        $this->empleadosACargo[] = $empleado;\n    }\n\n    public function informacion() {\n        echo \"ID: {$this->id}, Nombre: {$this->nombre}\\n\";\n        echo \"Tipo: Gerente\\n\";\n        echo \"Empleados a cargo: \" . count($this->empleadosACargo) . \"\\n\";\n    }\n}\n\n// Clase GerenteProyecto hereda de Gerente\nclass GerenteProyecto extends Gerente {\n    protected $areaProyecto;\n\n    public function __construct($id, $nombre, $areaProyecto) {\n        parent::__construct($id, $nombre);\n        $this->areaProyecto = $areaProyecto;\n    }\n\n    public function informacion() {\n        parent::informacion();\n        echo \"Área del Proyecto: {$this->areaProyecto}\\n\";\n    }\n}\n\n// Clase Programador hereda de Empleado\nclass Programador extends Empleado {\n    protected $lenguaje;\n\n    public function __construct($id, $nombre, $lenguaje) {\n        parent::__construct($id, $nombre);\n        $this->lenguaje = $lenguaje;\n    }\n\n    public function informacion() {\n        parent::informacion();\n        echo \"Lenguaje: {$this->lenguaje}\\n\";\n    }\n}\n\n// Creación de instancias de Perro y Gato\n$miPerro = new Perro(\"Bobby\", 5);\n$miGato = new Gato(\"Whiskers\", 3);\n\n// Llamada a los métodos específicos de cada clase\n$miPerro->sonido(); // Salida: ¡Guau Guau!\n$miGato->sonido(); // Salida: ¡Miau Miau!\n\n// Creación de instancias de empleados\n$gerente1 = new Gerente(1, \"Juan\");\n$gerenteProyecto1 = new GerenteProyecto(2, \"María\", \"Desarrollo Web\");\n$programador1 = new Programador(3, \"Pedro\", \"C#\");\n\n// Agregar empleados a cargo del gerente\n$gerente1->agregarEmpleado($gerenteProyecto1);\n$gerenteProyecto1->agregarEmpleado($programador1);\n\n// Mostrar información de los empleados\necho \"Información del Gerente:\\n\";\n$gerente1->informacion();\necho \"\\nInformación del Gerente de Proyecto:\\n\";\n$gerenteProyecto1->informacion();\necho \"\\nInformación del Programador:\\n\";\n$programador1->informacion();\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/php/yablik.php",
    "content": "<?php\n/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n  * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n */\nclass Animal{\n    protected $nombre;\n    protected $sonido;\n\n    public function __construct($nombre, $sonido){\n        $this->nombre = $nombre;\n        $this->sonido = $sonido;\n    }\n    public function hacerSonido(){\n        return $this->nombre . \" \" . $this->sonido;\n    }\n}\n\nclass Perro extends Animal {\n    public function __construct($nombre){\n        parent::__construct($nombre, \"ladra.\");\n    }\n}\n\nclass Gato extends Animal {\n    public function __construct($nombre){\n        parent::__construct($nombre, \"maulla.\");\n    }\n}\n\nfunction imprimirSonido(Animal $animal) {\n    echo $animal->hacerSonido() . PHP_EOL;\n}\n\n$perro = new Perro(\"Pluto\");\n$gato = new Gato(\"Garfield\");\nimprimirSonido($perro);\nimprimirSonido($gato);\n\n\n\n /* DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n\n// Definición de la clase Empleado\nclass Empleado {\n    protected $id;\n    protected $nombre;\n\n    public function __construct($id, $nombre) {\n        $this->id = $id;\n        $this->nombre = $nombre;\n    }\n\n    public function getId() {\n        return $this->id;\n    }\n\n    public function getNombre() {\n        return $this->nombre;\n    }\n}\n\n// Definición de la clase Gerente que hereda de Empleado\nclass Gerente extends Empleado {\n    protected $empleadosACargo;\n\n    public function __construct($id, $nombre) {\n        parent::__construct($id, $nombre);\n        $this->empleadosACargo = [];\n    }\n\n    public function agregarEmpleado(Empleado $empleado) {\n        $this->empleadosACargo[] = $empleado;\n    }\n\n    public function getEmpleadosACargo() {\n        return $this->empleadosACargo;\n    }\n}\n\n// Definición de la clase GerenteProyecto que hereda de Gerente\nclass GerenteProyecto extends Gerente {\n    protected $proyectoAsignado;\n\n    public function __construct($id, $nombre, $proyectoAsignado) {\n        parent::__construct($id, $nombre);\n        $this->proyectoAsignado = $proyectoAsignado;\n    }\n\n    public function getProyectoAsignado() {\n        return $this->proyectoAsignado;\n    }\n}\n\n// Definición de la clase Programador que hereda de Empleado\nclass Programador extends Empleado {\n    protected $lenguaje;\n\n    public function __construct($id, $nombre, $lenguaje) {\n        parent::__construct($id, $nombre);\n        $this->lenguaje = $lenguaje;\n    }\n\n    public function getLenguaje() {\n        return $this->lenguaje;\n    }\n}\n\n// Crear instancias de empleados\n$gerente1 = new Gerente(1, \"MoureDev\");\n$gerente2 = new GerenteProyecto(2, \"Carlos\", \"Pilbeo\");\n$programador1 = new Programador(3, \"Jose\", \"PHP\");\n$programador2 = new Programador(4, \"Cristina\", \"JavaScript\");\n\n// Agregar empleados a cargo del gerente\n$gerente1->agregarEmpleado($gerente2);\n$gerente1->agregarEmpleado($programador1);\n$gerente1->agregarEmpleado($programador2);\n\n$gerente2->agregarEmpleado($programador1);\n$gerente2->agregarEmpleado($programador2);\n\n// Mostrar información\necho \"Información del Gerente:\" . PHP_EOL;\necho \"ID: \" . $gerente1->getId() . \", Nombre: \" . $gerente1->getNombre() . PHP_EOL;\necho \"Empleados contratados:\" . PHP_EOL;\nforeach ($gerente1->getEmpleadosACargo() as $empleado) {\n    echo \"- ID: \" . $empleado->getId() . \", Nombre: \" . $empleado->getNombre() . PHP_EOL;\n}\n\necho \"Información del Gerente Proyecto:\" . PHP_EOL;\necho \"ID: \" . $gerente2->getId() . \", Nombre: \" . $gerente2->getNombre() . PHP_EOL;\necho \"Proyecto Asignado: \" . $gerente2->getProyectoAsignado() . PHP_EOL;\necho \"Empleados a cargo:\" . PHP_EOL;\nforeach ($gerente2->getEmpleadosACargo() as $empleado) {\n    echo \"- ID: \" . $empleado->getId() . \", Nombre: \" . $empleado->getNombre() . PHP_EOL;\n}\n\necho \"Información del Programador 1:\" . PHP_EOL;\necho \"ID: \" . $programador1->getId() . \", Nombre: \" . $programador1->getNombre() . PHP_EOL;\necho \"Lenguaje: \" . $programador1->getLenguaje() . PHP_EOL;\n\necho \"Información del Programador 2:\" . PHP_EOL;\necho \"ID: \" . $programador2->getId() . \", Nombre: \" . $programador2->getNombre() . PHP_EOL;\necho \"Lenguaje: \" . $programador2->getLenguaje() . PHP_EOL;\n\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/59822.py",
    "content": "class Animal:\n    animal = \"Ser vivo\"\n    \n    def __init__(self, color, sonido):\n        self.color = color\n        self.sonido = sonido\n        \n    def hacer_sonido(self):\n        print(f\"hola {self.sonido}\")\n        \nclass Perro(Animal):\n    \n    def __init__(self, color, sonido, raza):\n        self.raza = raza\n        super().__init__(color, sonido)\n    \n    def saludo(self):\n        print(f\"hola soy un perro de raza {self.raza} y mi color es {self.color}\")\n\nclass Gato(Animal):\n    def __init__(self, color, sonido, pelaje):\n        self.pelaje = pelaje\n        super().__init__(color, sonido)\n    \n    def saludo(self):\n        print(f\"hola soy un gato con pelaje {self.pelaje} y mi color es {self.color}\")\n    \nperro = Perro(\"cafe\", \"guau\", \"labrador\")\nperro.hacer_sonido()\n\n\n''' Ejercicios de Herencia'''\n\nclass Empresa:\n    \n    def __init__(self, id, name, cargo):\n        self.id = id\n        self.name = name\n        self.cargo = cargo\n    \n    def presentacion(self):\n        print(f\"Hola, soy {self.name} y mi cargo  es {self.cargo}\")\n        \nclass Gerente(Empresa):\n    def __init__(self, id, name, cargo):\n        super().__init__(id, name, cargo)\n    \n    def personal(self, numero_personal):\n        print(f\"Mi numero de personal es {numero_personal}\")\n    \nclass Gerente_proyectos(Empresa):\n    def __init__(self, id, name, cargo):\n        super().__init__(id, name, cargo)\n    \n    def proyectos(self, numero_proyectos):\n        print(f\"Mi numero de proyectos es {numero_proyectos}\")\n\nclass Programador(Empresa):\n    def __init__(self, id, name, cargo):\n        super().__init__(id, name, cargo)\n    \n    def tareas(self, numero_tareas):\n        print(f\"Mi numero de tareas es {numero_tareas}\")\n        \n        \n# Crear un objeto de la clase Empresa\nprogramador = Programador(2, \"Juan\", \"Programador\")\nprogramador.tareas(5)\ngerente = Gerente(3, \"Ana\", \"Gerente\")\ngerente.personal(10)\ngerente_proyecto = Gerente_proyectos(4, \"Carlos\", \"Gerente de Proyecto\")\ngerente_proyecto.proyectos(15)\n\n        "
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/AChapeton.py",
    "content": "class Animal:\n  def __init__(self, name, sound):\n    self.name = name\n    self.sound = sound\n  \n  def makeSound(self):\n    print(f\"{self.name} dice {self.sound}\")\n\nclass Dog(Animal):\n  def __init__(self, name):\n    super().__init__(name, 'Woof')\n\nclass Cat(Animal):\n  def __init__(self, name):\n    super().__init__(name, \"Meow\")\n\n\nmyDog = Dog(\"Dolly\")\nmyDog.makeSound()\n\nmyCat = Cat(\"Snowball\")\nmyCat.makeSound()\n\n\n# DIFICULTAD EXTRA\n\nclass Empleado:\n  def __init__(self, id, name, tasks, staff):\n    self.id = id\n    self.name = name\n    self.tasks = tasks\n    self.staff = staff\n  \n  def makePresentation(self):\n    print(f\"Hola, mi nombre es {self.name}\")\n\n  def showTasksList(self):\n    print(f\"Lista de tareas: {self.tasks}\")\n\n  def showTeam(self):\n    print(f\"A cargo de: {self.staff}\")\n\nclass Gerente(Empleado):\n  def __init__(self, name):\n    super().__init__('Gerente', name, {'Obtener clientes', 'Ventas'}, {'Gerente de Proyecto', 'Programador'})\n\nclass GerenteDeProyecto(Empleado):\n  def __init__(self, name):\n    super().__init__('Gerente de Proyecto', name, {'Gestionar proyectos', 'Crear tickets', 'Agendar meets'}, {'Programador'})\n\nclass Programador(Empleado):\n  def __init__(self, name):\n    super().__init__('Programador', name, {'Resolver tickets'}, {'No tiene nadie a cargo'})\n\ngerente = Gerente(\"Brais Moure\")\ngerente.makePresentation()\ngerente.showTasksList()\ngerente.showTeam()\n\ngerenteDeProyecto = GerenteDeProyecto(\"Edith Romero\")\ngerenteDeProyecto.makePresentation()\ngerenteDeProyecto.showTasksList()\ngerenteDeProyecto.showTeam()\n\nprogramador = Programador(\"Andres Chapeton\")\nprogramador.makePresentation()\nprogramador.showTasksList()\nprogramador.showTeam()\n\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/AlainMartz.py",
    "content": "#09 HERENCIA Y POLIMORFISMO\n\n\"\"\"\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n\"\"\"\n\nclass animal():\n    def __init__(self, nombre, raza, edad) -> None:\n        self.nombre = nombre\n        self.raza = raza\n        self.edad = edad\n\n    def hacer_sonido(self):\n        print(\"Sonido de algún animal\")\n\n    def __str__(self):\n        return f\"{self.nombre} es un {self.raza} de {self.edad} años\"\n\nclass perro(animal):\n    def sonido(self):\n        print(\"Guaf\")\n\nclass gato(animal):\n    def sonido(self):\n        print(\"Maau\")        \n\ndef print_sonido(animal):\n    animal.sonido()\n\ncat = gato(\"Sally\",\"Montañeza\",5)\ncat.sonido()\nprint(cat)\nprint_sonido(cat)\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n\"\"\"\n\nclass empleado():\n\n    def __init__(self, nombre, id) -> None:\n        self.nombre = nombre\n        self.id = id\n        self.empleados = []\n\nclass gerente(empleado):\n\n    def __init__(self, nombre, id, departamento) -> None:\n        super().__init__(nombre, id)\n        self.departamento = departamento\n\n    def gestionar(self):\n        if len(self.empleados) > 0:\n            return print(f\"{self.nombre} gestiona el departamento {self.departamento}\\nTiene {len(self.empleados)} empleados a cargo\")\n        else:\n            return print(f\"{self.nombre} gestiona el departamento {self.departamento}\\nFalta asignar empleados a cargo\")\n        \nclass proyecto(empleado):\n\n    def __init__(self, nombre, id, proyecto) -> None:\n        super().__init__(nombre, id)\n        self.proyecto = proyecto\n\n    def asignar(self):\n        return print(f\"{self.nombre} se encuentra dirigiendo el proyecto {self.proyecto}\")\n\n\nclass programador(empleado):\n\n    def __init__(self, nombre, id, lenguajes) -> None:\n        super().__init__(nombre, id)\n        self.lenguajes = lenguajes\n\n    def programar(self):\n        return print(f\"{self.nombre} se encuentra programando en los siguientes lenguajes: {self.lenguajes}\")\n    \n\nmanager001 = gerente('Kimm','00001','Estad´siticas')\nmanager002 = proyecto('Jann','03450','Global46')\nprogram001 = programador('Otto', '33394',['Python','R'])\nmanager001.empleados = [manager002.nombre, program001.nombre]\nmanager002.empleados = [program001.nombre]\nmanager001.gestionar()\nmanager002.asignar()\nprogram001.programar()\nprint(f\"{manager001.nombre} tiene {len(manager001.empleados)} a cargo: {manager001.empleados}\")\nprint(f\"{manager002.nombre} tiene {len(manager002.empleados)} a cargo: {manager002.empleados}\")\nprint(f\"La ID de {manager001.nombre} es: {manager001.id}\")\nprint(f\"La ID de {manager002.nombre} es: {manager002.id}\")\nprint(f\"La ID de {program001.nombre} es: {program001.id}\")"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/Aldroide.py",
    "content": "\"\"\"\nEjercicio crear un ejemplo que implemente una superclase animal \ny subclases de perro y gato junto a una función que imprima\nel sonido que emite cada animal\n\"\"\"\n\n\nclass Animal:\n    def __init__(self, name):\n        self.name = name\n\n    def sound(self):\n        pass\n\n\nclass Perro(Animal):\n\n    def sound(self):\n        print(f\"El {self.name} hace Guau!\")\n\n\nclass Gato(Animal):\n\n    def sound(self):\n        print(f\"El {self.name} hace Miau!\")\n\n\ndef print_sound(animal: Animal):\n    animal.sound()\n\n\nmi_animal = Animal(\"Animal\")\nprint_sound(mi_animal)\nmi_perro = Perro(\"Perro\")\nprint_sound(mi_perro)\nmi_gato = Gato(\"Gato\")\nprint_sound(mi_gato)\n\n\n\"\"\"\n* DIFICULTAD EXTRA :\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n\"\"\"\n\n\nclass Empleado:\n    def __init__(self, id: int, name: str):\n        self.id = id\n        self.name = name\n        self.empleados = []\n\n    def añadir(self, empleado):\n        self.empleados.append(empleado)\n\n    def imprime(self):\n        for empleado in self.empleados:\n            print(empleado.name)\n\n\nclass Gerente(Empleado):\n    def Cor_proyectos(self):\n        print(f\"{self.name} está coordinando todos los proyectos\")\n\n\nclass Gerente_proyectos (Empleado):\n    def __init__(self, id: int, name: str, proyecto: str):\n        super().__init__(id, name)\n        self.proyecto = proyecto\n\n    def Cor_proyecto(self):\n        print(f\"{self.name} esta cordinando su proyecto.\")\n\n\nclass Programador(Empleado):\n    def __init__(self, id: int, name: str, lenguaje: str):\n        super().__init__(id, name)\n        self.lenguaje = lenguaje\n\n    def codigo(self):\n        print(f\"{self.name} programa un proyecto en {self.lenguaje}\")\n\n    def añadir(self, empleado: Empleado):\n        print(\n            f\"El progamador tiene empleados a su cargo. {empleado.name} no se unirá\")\n\n\nGerente1 = Gerente(1, \"Aldroide\")\nGerente_proyectos1 = Gerente_proyectos(2, \"Samira\", \"Proyecto gatitos\")\nGerente_proyectos2 = Gerente_proyectos(3, \"Sebastian\", \"Proyecto perritos\")\nProgamador1 = Programador(4, \"Erwin\", \"Swift\")\nProgamador2 = Programador(5, \"Emmanuel\", \"Cobol\")\nProgamador3 = Programador(6, \"Anahi\", \"Dart\")\nProgamador4 = Programador(7, \"Yubesny\", \"Python\")\n\nGerente1.añadir(Gerente_proyectos1)\nGerente1.añadir(Gerente_proyectos2)\n\nGerente_proyectos1.añadir(Progamador1)\nGerente_proyectos1.añadir(Progamador2)\nGerente_proyectos2.añadir(Progamador3)\nGerente_proyectos2.añadir(Progamador4)\n\nProgamador1.añadir(Progamador2)\n\nProgamador1.codigo()\nGerente_proyectos1.Cor_proyecto()\nGerente1.Cor_proyectos()\nGerente1.imprime()\nGerente_proyectos1.imprime()\nProgamador1.imprime()\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/Aleran07.py",
    "content": "#09\n\n\"\"\"* EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\"\"\"\n\nclass Animal:\n    def __init__(self, nombre):\n        self.nombre = nombre\n\n    def hablar(self):\n        return \"Este animal habla\"\n    \nclass Perro(Animal):\n    def hablar(self):\n        return \"Guau\"\n    \nclass Gato(Animal):\n    def hablar(self):\n        return \"Miau\"\n    \nlista_animales = [Perro(\"Toby\"), Gato(\"Michi\")]\n\nfor x in lista_animales:\n    print(x.nombre, \"dice\", x.hablar())\n\n\n\"\"\" * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\"\"\"\n\nclass Persona:\n    def __init__(self, nombre, id):\n        self.nombre = nombre\n       \n        self.id = id\n\n    def presentarse(self):\n        print(f\"Buen dia, soy {self.nombre}\")\n\nclass Empleado(Persona):\n    def __init__(self, nombre, id, cargo):\n        super().__init__(nombre, id)\n        self.cargo = cargo\n        self.empleados_a_cargo = []\n    \n    def agregar_empleado(self, empleado):\n        self.empleados_a_cargo.append(empleado)\n\n    def mostrar_empleados(self):\n        if not self.empleados_a_cargo:\n            print(f\"{self.nombre} no tiene empleados a su cargo.\")\n            return\n\n        print(f\"Empleados a cargo de {self.nombre}:\")\n        for emp in self.empleados_a_cargo:\n            print(f\" - {emp.nombre} ({emp.__class__.__name__})\")\n\n    def mostrar_empleo(self):\n        print(f\"{self.nombre} trabaja como {self.cargo}\")\n    \n    def informacion(self):\n        print(f\"[{self.__class__.__name__}] ID: {self.id}, Nombre: {self.nombre}\")\n\nclass Gerente(Empleado):\n    def __init__(self, nombre, id, cargo):\n        super().__init__(nombre, id, cargo)\n\n    def supervisar(self):\n        print(f\"{self.nombre} esta supervisando\")\n\n    \n\nclass GerenteDeProyectos(Empleado):\n    def __init__(self, nombre, id, cargo):\n        super().__init__(nombre, id, cargo)\n\n    def administrar(self):\n        print(f\"{self.nombre} esta administrando el proyecto\")\n\n    def informacion(self):\n        super().informacion()\n        print(f\"Proyecto: {self.proyecto}\")\n\nclass Programador(Empleado):\n    def __init__(self, nombre, id, cargo):\n        super().__init__(nombre, id, cargo)\n\n    def programar(self):\n        print(f\"{self.nombre} esta programando\")\n    \n    def informacion(self):\n        super().informacion()\n        print(f\"Lenguaje principal: {self.lenguaje}\")\n\n\n# Crear empleados\ng1 = Gerente(\"Sofía\", 1, \"Desarrollo\")\ngp1 = GerenteDeProyectos(\"Carlos\", 2, \"App Bancaria\")\np1 = Programador(\"Laura\", 3, \"Python\")\np2 = Programador(\"Diego\", 4, \"Java\")\n\n# Relacionar jerarquía\ng1.agregar_empleado(gp1)\ng1.agregar_empleado(p1)\n\ngp1.agregar_empleado(p2)\n\n# Mostrar información\ng1.informacion()\ng1.mostrar_empleados()\n\nprint(\"\\n--- Acciones específicas ---\")\ng1.supervisar()\ngp1.administrar()\np1.programar()\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/AllanYSalazarG.py",
    "content": "\"\"\" #09 HERENCIA Y POLIMORFISMO \"\"\"\n\nfrom abc import ABC, abstractmethod\n\n# ----------------- EJERCICIO ------------------------\n\n\nclass Animal:\n    def __init__(self, nombre, edad):\n        self.nombre = nombre\n        self.edad = edad\n        patas = 4\n\n    def caminar(self):\n        print(\"Caminando\")\n\n    def correr(self):\n        print(\"Corriendo\")\n\n\nclass Perro(Animal):\n    def __init__(self, nombre, edad):\n        super().__init__(nombre, edad)\n\n    def ladrar(self):\n        print(f\"{self.nombre} está ladrando: Guau!\")\n\n\nclass Gato(Animal):\n    def __init__(self, nombre, edad):\n        super().__init__(nombre, edad)\n\n    def mauyar(self):\n        print(f\"{self.nombre} está mauyando: Miau!\")\n\n\nperro = Perro(\"Cucho\", 5)\nperro.ladrar()\n\ngato = Gato(\"Minino\", 1)\ngato.mauyar()\n\n# ----------------- EJERCICIO ADICIONAL --------------\n\n# Clase Empleado (Padre)\n\n\nclass Employee:\n    \"\"\" Clase Empleado (Clase Padre) \"\"\"\n\n    def __init__(self, name, identificator):\n        \"\"\" Constructor \"\"\"\n        self.name = name\n        self.id = identificator\n\n    @property\n    @abstractmethod\n    def working(self):\n        pass\n\n    @abstractmethod\n    def having_a_break(self):\n        pass\n\n\n# Clase Gerente\n\n\nclass Manager(Employee):\n    \"\"\" Clase Gerente \"\"\"\n\n    def __init__(self, name, identificator):\n        super().__init__(name, identificator)\n        self.employees = []\n        self.employees_num = 0\n\n    def lead(self):\n        \"\"\" Lidera \"\"\"\n        print(f\"{self.name} esta dirigiendo\")\n\n    def working(self):\n        \"\"\" Trabajando \"\"\"\n        print(\"Trabajando\")\n\n    def having_a_break(self):\n        \"\"\" Tomando un descanso \"\"\"\n        print(\"Tomando un descanso\")\n\n    def my_employees(self, employee):\n        self.employees.append(employee)\n\n    def count_my_employees(self):\n        self.employees_num = len(self.employees)\n        print(self.employees_num)\n\n\n# Clase Gerente de Proyectos\n\n\nclass ProyectManager(Manager):\n    \"\"\" Clase Gerente de Proyectos \"\"\"\n\n    def __init__(self, name, identificator):\n        \"\"\" Constructor \"\"\"\n        super().__init__(name, identificator)\n        self.employees = []\n        self.employees_num = 0\n\n    def ask_for_work(self):\n        \"\"\" Pregunta como vamos \"\"\"\n        print(f\"{self.name} pregunta como vas\")\n\n    def working(self):\n        \"\"\" Trabajando \"\"\"\n        print(\"Trabajando\")\n\n    def having_a_break(self):\n        \"\"\" Tomando un descanso \"\"\"\n        print(\"Tomando un descanso\")\n\n    def my_employees(self, employee):\n        self.employees.append(employee)\n\n    def count_my_employees(self):\n        self.employees_num = len(self.employees)\n        print(self.employees_num)\n\n\n# Clase Programador\n\n\nclass Developer(Employee):\n    \"\"\" Clase Programador \"\"\"\n\n    def __init__(self, name, identificator):\n        \"\"\" Constructor \"\"\"\n        super().__init__(name, identificator)\n\n    def coding(self):\n        \"\"\" Tirando codigo \"\"\"\n        print(f\"{self.name} está programando\")\n\n    def debugging(self):\n        \"\"\" Corrigiendo codigo \"\"\"\n        print(f\"{self.name} está depurando su código\")\n\n    def crying(self):\n        \"\"\" Frustrado \"\"\"\n        print(f\"{self.name} está llorando por que no compila\")\n\n    def working(self):\n        \"\"\" Trabajando \"\"\"\n        print(\"Trabajando\")\n\n    def having_a_break(self):\n        \"\"\" Tomando un descanso \"\"\"\n        print(\"Tomando un descanso\")\n\n\ngerente = Manager(\"Ruben\", 1)\ngerente_proyectos = ProyectManager(\"Enrique\", 2)\nprogramador = Developer(\"Allan\", 3)\nprogramador2 = Developer(\"Francisco\", 4)\n\ngerente_proyectos.my_employees([programador, programador2])\ngerente.my_employees(gerente_proyectos)\n\ngerente.count_my_employees()\ngerente.lead()\ngerente_proyectos.ask_for_work()\nprogramador.crying()\nprogramador2.coding()\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/Alvaro-Neyra.py",
    "content": "#  * EJERCICIO:\n#  * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n#  * implemente una superclase Animal y un par de subclases Perro y Gato,\n#  * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n\n# Superclase Animal:\nclass Animal:\n    def __init__(self, name, especie, edad):\n        self.name = name\n        self.especie = especie\n        self.edad = edad\n    def eat(self):\n        print(f\"{self.name} is eating.\")\n    def sleep(self):\n        print(f\"{self.sleep} is sleeping.\")\n    def make_sound(self):\n        pass # Dejamos este metodo sin implementar, ya que los animales hacen sonidos distintos para comunicarse\n    def description(self):\n        print(f\"Soy un animal del tipo: {type(self).__name__}\")\n    def datos(self):\n        print(f\"Mi nombre es {self.name}\")\n        print(f\"Tengo {self.edad} años de edad!\")\n\n# Subclase de Animal para Perro:\nclass Perro(Animal):\n    def __init__(self, name, edad, breed = \"No especificado\"):\n        super().__init__(name, \"Perro\", edad)\n        self.breed = breed\n    def make_sound(self):\n        print(\"Woof!!\")\n    \n# Subclase de Animal para Gato:\nclass Gato(Animal):\n    def __init__(self, name, edad, breed = \"No especificado\"):\n        super().__init__(name, \"Gato\", edad)\n        self.breed = breed\n    def make_sound(self):\n        print(\"Miau!!\")\n\n## Probando las clases:\nmi_perro = Perro(\"Luke\", 2)\nun_gato = Gato(\"Michi\", 8)\nun_gato_de_raza = Gato(\"Bigotes\", 2, \"Persa\")\nun_perro_de_raza = Perro(\"Bobi\", 1, \"Cane Corso\")\n\n# Usamos make_sound en la clase perro:\nmi_perro.make_sound()\n# Imprimimos en consola la raza no especificada de mi perro:\nraza_de_mi_perro = mi_perro.breed\nprint(raza_de_mi_perro)\n# Cambiamos la raza de mi perro\nmi_perro.breed = \"Mestizo\"\nraza_de_mi_perro = mi_perro.breed\nprint(raza_de_mi_perro)\n# Usamos make_sound() de un gato:\nun_gato.make_sound()\n# Usamos description de la clase padre\nun_perro_de_raza.description()\n# Usamos description de la clase padre con una subclase de gato:\nun_gato_de_raza.description()\n# Usamos el metodo datos de la superclase Animal en una subclase (mi_perro):\nmi_perro.datos()\n# un_gato.datos():\nun_gato.datos()\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n#  * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n#  * Cada empleado tiene un identificador y un nombre.\n#  * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n#  * actividad, y almacenan los empleados a su cargo.\n\n# Superclase Empleado:\nclass Empleado:\n    def __init__(self, nombre, id_de_empleado):\n        self.nombre = nombre\n        self.id = id_de_empleado\n    def __str__(self):\n        return \"El id del empleado %s es %s\" % (self.nombre, self.id)\n    def mostrar_informacion(self):\n        print(f\"Nombre: {self.nombre}\")\n        print(f\"Id del empleado: {self.id}\")\n        print(f\"Cargo: {type(self).__name__}\")\n    def cargo(self):\n        print(f\"Cargo: {type(self).__name__}\")\n\n# Subclase Gerente:\nclass Gerente(Empleado):\n    def __init__(self, nombre, id_de_empleado):\n        super().__init__(nombre, id_de_empleado)\n        self.empleados_a_monitorear = []\n    def agregar_empleados(self, empleado):\n        if not empleado in self.empleados_a_monitorear:\n            self.empleados_a_monitorear.append(empleado)\n        else:\n            print(f\"Ya esta en la lista de empleados a cargo!\")\n    def despedir_empleado(self, empleado):\n        if empleado in self.empleados_a_monitorear:\n            self.empleados_a_monitorear.remove(empleado)\n        else:\n            print(f\"El gerente: {self.nombre} no esta a cargo del empleado: {empleado}\")\n    def mostrar_informacion(self):\n        super().mostrar_informacion()\n        print(\"Empleados a monitorear: \")\n        for indice, empleado in enumerate(self.empleados_a_monitorear):\n            print(f\"{indice + 1}: {empleado}\")\n\n# Subclase Gerente de Proyectos:\nclass GerenteDeProyectos(Empleado):\n    def __init__(self, nombre, id_de_empleado):\n        super().__init__(nombre, id_de_empleado)\n        self.proyectos_a_cargo = []\n    def agregar_proyectos(self, proyecto):\n        if not proyecto in self.proyectos_a_cargo:\n            self.proyectos_a_cargo.append(proyecto)\n        else:\n            print(f\"{proyecto} ya esta en la lista de proyectos a cargo del gerente de proyectos {self.nombre}\")\n    def eliminar_proyectos(self, proyecto):\n        if proyecto in self.proyectos_a_cargo:\n            self.proyectos_a_cargo.remove(proyecto)\n        else:\n            print(f\"El Gerente de Proyectos: {self.nombre} no esta a cargo del proyecto: {proyecto}\")\n    def mostrar_informacion(self):\n        super().mostrar_informacion()\n        print(\"Proyectos a cargo:\")\n        for indice, proyecto in enumerate(self.proyectos_a_cargo):\n            print(f\"{indice + 1}: {proyecto}\")\n\n# Subclase Programador:\nclass Programador(Empleado):\n    def __init__(self, nombre, id_de_empleado):\n        super().__init__(nombre, id_de_empleado)\n        self.lenguages = []\n    def anadir_lenguage(self, lenguaje):\n        if lenguaje not in self.lenguages:\n            self.lenguages.append(lenguaje)\n        else:\n            print(f\"{lenguaje} ya esta en la lista de lenguajes del programador: {self.nombre}\")\n    def mostrar_informacion(self):\n        super().mostrar_informacion()\n        print(f\"Lenguajes aprendidos por el programador: {self.nombre}\")\n        for lenguaje in self.lenguages:\n            print(\"- %s\" % lenguaje)\n\n\n## GERENTE:\n## Usando las subclases de la superclase Empleado:\ngerente_principal = Gerente(\"Alvaro\", 143)\ngerente_principal_de_proyectos = GerenteDeProyectos(\"Juan\", 120)\nprogramador_junior = Programador(\"Carlos\", 902)\nprogramador_midlevel = Programador(\"Coder\", 101)\nel_mejor_programador_del_mundo = Programador(\"Brais Moure\", 404)\nlider_del_proyecto = Programador(\"SuperCoder\", 1902)\n\n# Agregando empleados como gerente\ngerente_principal.agregar_empleados(programador_junior)\ngerente_principal.agregar_empleados(programador_midlevel)\ngerente_principal.agregar_empleados(el_mejor_programador_del_mundo)\n# Mostrando informacion del gerente principal\ngerente_principal.mostrar_informacion()\n# Eliminando un empleado (despedir):\ngerente_principal.despedir_empleado(programador_junior)\ngerente_principal.mostrar_informacion()\n# Eliminando un empleado que no esta en la lista de empleados del gerente principal:\ngerente_principal.despedir_empleado(lider_del_proyecto)\n# Usando el metodo .cargo() de la superclase Empleado:\ngerente_principal.cargo()\n\n## GERENTE DE PROYECTOS:\ngerente_principal_de_proyectos = GerenteDeProyectos(\"Alvaro Neyra\", 1293)\n# Agregando proyectos:\ngerente_principal_de_proyectos.agregar_proyectos(\"Clon de Spotify\")\ngerente_principal_de_proyectos.agregar_proyectos(\"PassVault\")\ngerente_principal_de_proyectos.agregar_proyectos(\"E-Commerce\")\n# Conseguiendo la informacion del gerente de proyectos:\ngerente_principal_de_proyectos.mostrar_informacion()\n# Eliminando un proyecto\ngerente_principal_de_proyectos.eliminar_proyectos(\"Clon de Spotify\")\ngerente_principal_de_proyectos.mostrar_informacion()\n\n## PROGRAMADOR:\n# Anadiendo lenguajes al lider del proyecto\nlider_del_proyecto.anadir_lenguage(\"Java\")\nlider_del_proyecto.anadir_lenguage(\"Python\")\nlider_del_proyecto.anadir_lenguage(\"JavaScript\")\nlider_del_proyecto.anadir_lenguage(\"Rust\")\n# Repetiendo un lenguaje:\nlider_del_proyecto.anadir_lenguage(\"Python\")\n# Mostrando informacion\nlider_del_proyecto.mostrar_informacion()\n\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/BrianSilvero.py",
    "content": "\"\"\"\nEjercicio\n\"\"\"\n\nclass Animal:\n    def __init__(self, name: str):\n        self.name = name\n        \n    def sound (self):\n        pass\n\n#Subclases\n\nclass Perro(Animal):\n    def sound(self):\n        print(\"Guau!\")\n\nclass Gato(Animal):\n    def sound(self):\n        print(\"Miau!\")\n\ndef print_sound(animal: Animal):\n    animal.sound()\n\nmy_animal = Animal(\"Animal\")\nprint_sound(my_animal)\nmy_dog = Perro(\"Perro\")\nprint_sound(my_dog)\nmy_cat = Gato(\"Gato\")\nprint_sound(my_cat)\n\n\n\"\"\"\nExtra\n\"\"\"\n\nclass Empleado:\n    def __init__(self, id, name):\n        self.id = id\n        self.name = name\n        self.empleados = []\n\n    def add(self, empleado):\n        self.empleados.append(empleado)\n\n    def print_empleados(self):\n        for empleado in self.empleados:\n            print(empleado.name)\n\nclass Manager(Empleado):\n    def coordinate_projects(self):\n        print(f\"{self.name} esta coordinando todos los proyectos de la empresa.\")\n\nclass ProjectManager(Empleado):\n    \n    def __init__(self, id: int, name: str, proyecto: str):\n        super().__init__(id,name)\n        self.proyecto = proyecto\n        \n    def cordinate_project(self):\n        print(f\"{self.name} esta cordinando su proyecto llamado: {self.proyecto}.\")\n        \nclass Programador(Empleado):\n    def __init__(self, id: int, name: str, lenguaje: str):\n        super().__init__(id,name)\n        self.lenguaje = lenguaje\n    \n    def code (self):\n        print(f\"{self.name} esta progrmando {self.lenguaje}.\")\n    def add(self, empleado: Empleado):\n        print(f\"Un programador no tiene empleados a su cargo. {empleado.name} no se añadira.\")\n        \nmy_manager = Manager(1, \"Brian\")\nmy_project_manager = ProjectManager(2, \"David\",\"Proyecto1\")\nmy_project_manager2 = ProjectManager(3, \"Gabriel\",\"Proyecto2\")\nmy_programador = Programador(4,\"Maximiliano\",\"Python\")\nmy_programador2 = Programador(5,\"Juan\", \"Java\")\n\nmy_manager.add(my_project_manager)\nmy_manager.add(my_project_manager2)\n\nmy_project_manager.add(my_programador)\nmy_project_manager2.add(my_programador2)\n\nmy_programador.add(my_programador2) \n\nmy_programador.code()\nmy_project_manager.cordinate_project()\nmy_manager.coordinate_projects()\nmy_manager.print_empleados()\nmy_project_manager.print_empleados()\nmy_programador.print_empleados()\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/C-Gabs.py",
    "content": "#Reto 09\n\n'''Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.'''\n\nclass Animal:\n    def __init__(self) -> None:\n        pass\n    def hablar():\n        pass\n\nclass Perro(Animal):\n    def hablar(self):\n        print(\"Guau\")\n\nclass Gato(Animal):\n    def hablar(self):\n        print(\"Miau\")\n\ngato = Gato()\ngato.hablar()\n\nperro = Perro()\nperro.hablar()\n\n\n#Reto extra\nclass Empleado:\n    def __init__(self, nombre, id) -> None:\n        self.nombre = nombre\n        self.id = id\n        self.empleados = []\n    \n    def añadir_empleados(self,nombre,id):\n        self.empleados.append((nombre,id))\n        print(f\"Se añade el empleado {nombre} a la lista del gerente {self.nombre}\")\n\nclass Gerente(Empleado):\n    def gestion_proyectos(self):\n        print(f\"{self.nombre} gestiona los proyectos\")\n    \n    def define_mision(self):\n        print(f\"{self.nombre} define la misión de la empresa\")\n    \n    def define_vision(self):\n        print(f\"{self.nombre} define la visión de la empresa\")\n\nclass GerentesDeProyecto(Empleado):\n    def __init__(self, nombre, id, proyecto) -> None:\n        super().__init__(nombre, id)\n        self.proyecto = proyecto\n\n\n    def planificacion_proyecto(self):\n        print(f\"{self.nombre} planifica el proyecto: {self.proyecto}\")\n    \n    def supervicion_proyecto(self):\n        print(f\"{self.nombre} supervisa el proyecto: {self.proyecto}\")\n    \n    def ejecucion_proyecto(self):\n        print(f\"{self.nombre} ejecuta el proyecto: {self.proyecto}\")\n\nclass Programador(Empleado):\n    def añadir_empleados(self):\n        pass\n\n    def desarrollar_codigo(self):\n        print(f\"{self.nombre} programa el código\")\n    \n    def mantener_codigo(self):\n        print(f\"{self.nombre} mantiene el código\")\n\ngerente_1 = Gerente(\"Juan\",1)\ngerente_1.define_mision()\ngerente_1.define_vision()\ngerente_1.gestion_proyectos()\ngerente_proyecto_1 = GerentesDeProyecto(\"Carlos\",2, \"proyecto 1\")\ngerente_1.añadir_empleados(gerente_proyecto_1.nombre, gerente_proyecto_1.id)\ngerente_proyecto_1.planificacion_proyecto()\ngerente_proyecto_1.supervicion_proyecto()\ngerente_proyecto_1.ejecucion_proyecto()\nprogramador_1 = Programador(\"Gabriel\",3)\ngerente_proyecto_1.añadir_empleados(programador_1.nombre, programador_1.id)\nprogramador_1.desarrollar_codigo()\nprogramador_1.mantener_codigo()\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/CaveroBrandon.py",
    "content": "\"\"\"EJERCICIO:\nExplora el concepto de herencia según tu lenguaje. Crea un ejemplo que implemente\nuna superclase Animal y un par de subclases Perro y Gato, junto con una función que\nsirva para imprimir el sonido que emite cada Animal\"\"\"\n\n\nclass Animal:\n    mascot = True\n\n    def __init__(self, name):\n        self.name = name\n\n    def print_sound(self, specie, sound):\n        print(f'The {specie} {self.name} makes the sound \"{sound}\"')\n\n\nclass Dog(Animal):\n    specie = 'dog'\n    sound = 'Wuf'\n\n\nclass Cat(Animal):\n    specie = 'cat'\n    sound = 'Miau'\n\n\ndog = Dog(name='Scooby')\ncat = Cat(name='Garfield')\n\ndog.print_sound(specie=dog.specie, sound=dog.sound)\ncat.print_sound(specie=cat.specie, sound=cat.sound)\n\n\"\"\"DIFICULTAD EXTRA (opcional):\nImplementa la jerarquía de una empresa de desarrollo formada por Empleados que pueden ser: \nGerentes, Gerentes de Proyectos o Programadores.\n- Cada empleado tiene un identificador y un nombre.\n- Dependiendo de su labor, tienen propiedades y funciones exclusivas de su  actividad, \ny almacenan los empleados a su cargo.\n\"\"\"\n\n\nclass Employee:\n    def __init__(self, employee_name, employee_id):\n        self.name = employee_name\n        self.id = employee_id\n        self.subordinate_list = list()\n\n    def show_information(self, position, salary, functions):\n        print(f'Employee information\\n'\n              f'Name: {self.name}\\n'\n              f'Id: {self.id}\\n'\n              f'Position: {position}\\n'\n              f'Salary: {salary}\\n'\n              f'Functions: {functions}')\n\n    def add_subordinate(self, subordinate):\n        self.subordinate_list.append(subordinate)\n\n    def show_subordinate(self):\n        print(f'The subordinates of {self.name} are: ')\n        for subordinate in self.subordinate_list:\n            print(f'Name: {subordinate.name}, Position: {subordinate.position}')\n\n\nclass Manager(Employee):\n    position = 'Manager'\n    salary = 1000\n    functions = 'Decision making'\n\n\nclass ProjectManager(Employee):\n    position = 'Project Manager'\n    salary = 500\n    functions = 'Tech decision'\n\n\nclass Programmer(Employee):\n    position = 'Programmer'\n    salary = 300\n    functions = 'Coding'\n\n\nprogrammer1 = Programmer(employee_name='Alpha', employee_id=000)\nprogrammer2 = Programmer(employee_name='Bravo', employee_id=111)\n\npro_manager1 = ProjectManager(employee_name='Charly', employee_id=222)\npro_manager1.add_subordinate(programmer1)\npro_manager1.add_subordinate(programmer2)\n\nmanager1 = Manager(employee_name='Delta', employee_id=333)\nmanager1.add_subordinate(pro_manager1)\nmanager1.add_subordinate(programmer1)\nmanager1.add_subordinate(programmer2)\n\nprogrammer1.show_information(position=programmer1.position, salary=programmer1.salary, functions=programmer1.functions)\nprint('**********')\npro_manager1.show_information(position=pro_manager1.position, salary=pro_manager1.salary, functions=pro_manager1.functions)\npro_manager1.show_subordinate()\nprint('**********')\nmanager1.show_information(position=manager1.position, salary=manager1.salary, functions=manager1.functions)\nmanager1.show_subordinate()\nprint('**********')\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/CesarCarmona30.py",
    "content": "'''\n  EJERCICIO\n'''\n\nclass Animal:\n  def __init__(self, name, race):\n    self.name = name\n    self.race = race\n\n  def __str__(self):\n    return f'Nombre: {self.name}, Raza: {self.race}'  \n\nclass Dog(Animal):\n  def __init__(self, name, race):\n    super().__init__(name, race)\n\n  def sound(self):\n    print(f\"{self.name} ladrando!!\")\n\nclass Cat(Animal):\n  def __init__(self, name, race):\n    super().__init__(name, race)\n\n  def sound(self):\n    print(f\"{self.name} maullando!!\")\n\ndef animalSound(animal):\n  animal.sound()\n\n\nmanchas = Cat(\"Manchas\", \"Calicó\")\nfirulais = Dog(\"Firulais\", \"Labrador\")\n\n\nprint(f'Manchas: {manchas.__str__()}')\nanimalSound(manchas)\nprint(f'Manchas es un perro?: {isinstance(manchas, Dog)}')\nprint(f'Manchas es un gato?: {isinstance(manchas, Cat)}')\nprint(f'Manchas es un animal?: {isinstance(manchas, Animal)}')\nprint(f'Firulais: {firulais.__str__()}')\nanimalSound(firulais)\nprint(f'Firulais es un perro?: {isinstance(firulais, Dog)}')\nprint(f'Firulais es un gato?: {isinstance(firulais, Cat)}')\nprint(f'Firulais es un animal?: {isinstance(firulais, Animal)}')\n\n'''\n  EXTRA\n'''\n\nclass Employee:\n  def __init__(self, id, name):\n    self.id = id\n    self.name = name\n\n  def job(self):\n    return \"Executing assigned tasks\"\n\nclass Manager(Employee):\n  def __init__(self, id, name, employees):\n    super().__init__(id, name)\n    self.employees = employees\n\n  def job(self):\n    return \"Management\"\n\nclass ProjectManager(Manager):\n  def __init__(self, id, name, employees):\n    super().__init__(id, name, employees)\n\n  def job(self):\n    return \"Managing project\"\n\nclass Programmer(Employee):\n  def __init__(self, id, name):\n    super().__init__(id, name)\n\n  def job(self):\n    return \"Working on development\"\n\n\nemp_1 = Employee(1, \"Santiago\")\nemp_2 = Employee(2, \"Valentina\")\nemp_3 = Employee(3, \"Camilo\")\nemp_4 = Employee(4, \"Andrés\")\nemp_5 = Employee(5, \"Alejandro\")\n\npgr_1 = Programmer(11, \"César\")\npgr_2 = Programmer(12, \"Christian\")\npgr_3 = Programmer(13, \"Sebastián\")\npgr_4 = Programmer(14, \"Miriam\")\npgr_5 = Programmer(15, \"Nicole\")\n\nproject_employees = [emp_2, emp_4, emp_5, pgr_1, pgr_3,]\n\npmng = ProjectManager(101, \"Leonardo\", project_employees)\n\nfull_employees = [emp_1, emp_2, emp_3, emp_4, emp_5, pgr_1, pgr_2, pgr_3, pgr_4, pgr_5, pmng]\n\nmng = Manager(1001, \"Mauricio\", [emp_1, emp_2, emp_4, ])\n\nfor employee in full_employees:\n  print(f\"{employee.id}. {employee.name}: {employee.job()}\")\n\nprint(\"Project manager's employees:\")\nfor employee in pmng.employees:\n    print(F\"- {employee.name}\")\n\nprint(f\"{mng.id}. {mng.name}: {mng.job()}\")\n\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/Chrisdev00.py",
    "content": "\"\"\"\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n\"\"\"\n\n\nclass Animal:\n    def __init__(self, nombre):\n        self.nombre = nombre\n    \n    def sonido (self):\n        pass\n\nclass Perro (Animal):\n    def sonido(self):\n        return \"Guauu\"\n    \nclass Gato (Animal):\n    def sonido(self):\n        return \"Miauu\"\n    \nmi_perro = Perro(\"Rufo\")\nmi_gato = Gato(\"Bigotes\")\n\nprint(mi_perro.nombre)\nprint(mi_perro.sonido())\n\nprint(mi_gato.nombre)\nprint(mi_gato.sonido())\n\n\n########  ---------------------- EXTRA -------------------------------  ##########\n\n\nclass Empleado:\n    def __init__(self, identificador, nombre):\n        self.identificador = identificador\n        self.nombre = nombre\n\n    def __str__(self):\n        return f\"ID: {self.identificador}, Nombre: {self.nombre}\"\n\n\nclass Gerente(Empleado):\n    def __init__(self, identificador, nombre, departamento):\n        super().__init__(identificador, nombre)\n        self.departamento = departamento\n\n    def __str__(self):\n        return f\"ID: {self.identificador}, Nombre: {self.nombre}, Departamento: {self.departamento}\"\n\n\nclass GerenteProyecto(Gerente):\n    def __init__(self, identificador, nombre, departamento, proyectos):\n        super().__init__(identificador, nombre, departamento)\n        self.proyectos = proyectos\n\n    def __str__(self):\n        return f\"ID: {self.identificador}, Nombre: {self.nombre}, Departamento: {self.departamento}, Proyectos: {self.proyectos}\"\n\n\nclass Programador(Empleado):\n    def __init__(self, identificador, nombre, lenguaje):\n        super().__init__(identificador, nombre)\n        self.lenguaje = lenguaje\n\n    def __str__(self):\n        return f\"ID: {self.identificador}, Nombre: {self.nombre}, Lenguaje: {self.lenguaje}\"\n\n\ngerente_proyecto = GerenteProyecto(1, \"Juan\", \"Desarrollo\", [\"Proyecto A\", \"Proyecto B\"])\nprogramador = Programador(2, \"Pedro\", \"Python\")\n\nprint(gerente_proyecto)\nprint(programador)\n\n\n    "
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/Complex.303.py",
    "content": "\"\"\"\nHerencia y Polimorfismo\n\"\"\"\n\n# Superclase (clase base)\nclass Animal:\n    # Constructor que recibe un nombre\n    def __init__(self, name: str):\n        self.name = name\n\n    # Método que se espera que las subclases sobrescriban\n    def sound(self):\n        pass  # No hace nada aquí\n\n# Subclase Dog que hereda de Animal\nclass Dog(Animal):\n    # Sobreescribe el método sound()\n    def sound(self):\n        print(\"Guau!!\")\n\n# Subclase Cat que hereda de Animal\nclass Cat(Animal):\n    # Sobreescribe el método sound()\n    def sound(self):\n        print(\"Miau!!\")\n\n# Función que recibe un objeto Animal (o sus subclases)\n# y llama a su método sound()\ndef print_sound(animal: Animal):\n    animal.sound()\n\n# Creamos un objeto de tipo Animal\nmy_animal = Animal('Animal')\nprint_sound(my_animal)  # Como Animal.sound() está vacío (pass), no imprime nada\n\n# Creamos un objeto de tipo Dog\nmy_dog = Dog('Perro')\nprint_sound(my_dog)  # Llama a Dog.sound() y muestra \"Guau!!\"\n\n# Creamos un objeto de tipo Cat\nmy_cat = Cat('Gato')\nprint_sound(my_cat)  # Llama a Cat.sound() y muestra \"Miau!!\"\n\n\n\"\"\" * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\"\"\"\n\n\n\n# Clase base Employee (Empleado)\nclass Employee:\n    def __init__(self, id: int, name: str):\n        self.id = id                    # ID del empleado\n        self.name = name                # Nombre del empleado\n        self.employee = []              # Lista para guardar empleados a su cargo\n\n    def add(self, employee):\n        # Método para agregar empleados a la lista\n        self.employee.append(employee)\n\n    def print_employee(self):\n        # Método para mostrar los nombres de los empleados a su cargo\n        for employee in self.employee:\n            print(employee.name)\n\n# Clase Manager que hereda de Employee\nclass Manager(Employee):\n    def coordinate_projects(self):\n        # Método específico del Manager\n        print(f\"{self.name} está coordinando todos los proyectos de la empresa.\")\n\n# Clase ProjectManager que hereda de Employee\nclass ProjectManager(Employee):\n    def __init__(self, id: int, name: str, proyecto: str):\n        super().__init__(id, name)      # Llama al constructor de Employee\n        self.proyecto = proyecto        # Proyecto a su cargo\n\n    def coordinate_project(self):\n        # Método específico del ProjectManager\n        print(f\"{self.name} está coordinando su proyecto.\")\n\n# Clase Programmer que hereda de Employee\nclass Programmer(Employee):\n    def __init__(self, id: int, name: str, languaje: str):\n        super().__init__(id, name)\n        self.languaje = languaje        # Lenguaje de programación\n\n    def code(self):\n        # Método específico del Programmer\n        print(f\"{self.name} está programando en {self.languaje}.\")\n\n    def add(self, employee: Employee):\n        # Sobreescritura de add(): los programadores no pueden tener empleados\n        print(f\"Un programador no tiene empleados a su cargo. {employee.name} no se añadirá.\")\n\n# ----------------- INSTANCIAS Y USO ----------------------\n\n# Creamos un Manager\nmy_manager = Manager(1, 'Eddy')\n\n# Creamos dos ProjectManagers\nmy_proyect_manager = ProjectManager(2, 'Raul', 'Proyecto1')\nmy_proyect_manager2 = ProjectManager(3, 'Maria', 'Proyecto2')\n\n# Creamos cuatro Programadores\nmy_programmer = Programmer(4, 'Jose', 'Python')\nmy_programmer2 = Programmer(5, 'Duran', 'Kotlin')\nmy_programmer3 = Programmer(6, 'Migue', 'Java')\nmy_programmer4 = Programmer(7, 'Ana', 'C#')\n\n# El Manager agrega a los ProjectManagers\nmy_manager.add(my_proyect_manager)\nmy_manager.add(my_proyect_manager2)\n\n# Cada ProjectManager agrega programadores a su proyecto\nmy_proyect_manager.add(my_programmer)\nmy_proyect_manager.add(my_programmer2)\nmy_proyect_manager2.add(my_programmer3)\nmy_proyect_manager2.add(my_programmer4)\n\n# Intentamos agregar un programador a otro programador (no permitido)\nmy_programmer.add(my_programmer4)\n\n# Acciones de los empleados\nmy_programmer.code()                   # Jose está programando\nmy_proyect_manager.coordinate_project()# Raul coordina su proyecto\nmy_manager.coordinate_projects()       # Eddy coordina todo\n\n# Ver lista de empleados de cada quien\nmy_manager.print_employee()            # Muestra a Raul y Maria\nmy_proyect_manager.print_employee()    # Muestra a Jose y Duran\nmy_programmer.print_employee()         # No tiene empleados\n\n\n\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/DaniQB99.py",
    "content": "'''\nEJERCICIO:\nExplora el concepto de Herencia segun tu lenguaje. Crea un ejemplo \nque implemente una superclase Animal y un par de subclases Perro y \nGato, junto con una función que sirva para imprimir el sonido que \nemite cada Animal.\n'''\n\nclass Animal: # Superclase Animal\n\n    def __init__(self, name: str):\n        self.name = name\n\n    def sound(self):\n        print('Sonido desconocido')\n\n# Subclase Perro\ndef Dog(Animal): \n\n    def sound(self):\n        print('Guau!')\n\n# Subclase Gato\ndef Cat(Animal): \n\n    def sound(self):\n        print('Miau!')\n\ndef print_sound(animal: Animal):\n    animal.sound()\n    \nmy_animal = Animal('????') \nmy_dog = Dog('Shena')\nmy_cat = Cat('Lucas')\n\n\n'''\nDIFICULTAD EXTRA (opcional):\n- Implementa la jerarquía de una empresa de desarrollo formada por \nEmpleados que pueden ser Gerentes, Gerentes de Proyectos o \nProgramadores.\n- Cada empleado tiene un identificador y un nombre.\n- Dependiendo de su labor, tienen propiedades y funciones exclusivas \nde su actividad, y almacenan los empleados a su cargo.\n'''\n\nprint('\\n\\n\\n--- EJERCICIO EXTRA ---\\n')\n\n# Superclase Empleado\nclass Employee:\n\n    def __init__(self, ID: int, name: str):\n        self.ID = ID\n        self.name = name\n        self.employees = []\n\n    def add(self, employee):\n        self.employees.append(employee)\n\n    def print_employees(self):\n        for employee in self.employees:\n            print('Nombre:', employee.name, '| ID:', employee.ID)\n\n# Subclase Gerente\nclass Manager(Employee):\n    \n    def coordinate_projects(self):\n        print(f'{self.name} está coordinando todos los proyectos de la empresa.')\n    \n    def add(self, employee):\n        self.employees.append(employee)\n\n# Subclase Gerente de Proyectos\nclass ProjectManager(Manager, Employee): \n    \n    def __init__(self, ID: int, name: str, project: str):\n        super().__init__(ID, name) # Llama al inicializador de Gerente\n        self.project = project\n        \n    def coordinate_project(self):\n        print(f'{self.name} está coordinando su proyecto.')\n        \n\n# Subclase Programador\nclass Programmer(Employee):\n    \n    def __init__(self, ID: int, name: str, language):\n        super().__init__(ID, name) # Llama al inicializador de Gerente\n        self.language = language\n        \n    def code(self):\n        print(f'{self.name} está programando en {self.language}.')\n\n    def add(self, employee: Employee):\n        print(f'Un programador no tiene empleados a su cargo. {employee.name} no se añadirá.')\n\n# Crear Gerente\nmy_manager = Manager(1, 'MoureDev')\n\n# Crear Gerentes de Proyectos\nmy_project_manager = ProjectManager(2, 'Fernando', 'Proyecto MotoGP')\nmy_project_manager2 = ProjectManager(3, 'Javier', 'Proyecto Formula 1')\n\n# Crear Programadores\nmy_programmer = Programmer(4, 'Paco', 'python')\nmy_programmer2 = Programmer(5, 'Fran', 'python')\nmy_programmer3 = Programmer(6, 'Victor', 'java')\nmy_programmer4 = Programmer(7, 'Jose Andres', 'java')\nmy_programmer5 = Programmer(8, 'Eduardo', 'HTML&CSS')\n\n# Empleados del Gerente\nmy_manager.add(my_project_manager)\nmy_manager.add(my_project_manager2)\n\n# Empleados del Gerente de Proyectos\nmy_project_manager.add(my_programmer)\nmy_project_manager.add(my_programmer2)\nmy_project_manager2.add(my_programmer3)\nmy_project_manager2.add(my_programmer4)\nmy_project_manager2.add(my_programmer5)\n\n# Empleados del Programador\nmy_programmer.add(my_programmer2)\n\n# Tareas de cada EMPLEADO\nmy_programmer2.code()\nmy_project_manager.coordinate_project()\nmy_manager.coordinate_projects()\nmy_manager.print_employees()\nmy_project_manager2.print_employees()\nmy_programmer.print_employees()\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/Daparradom.py",
    "content": "### HERENCIA ###\n\nclass Animal:\n    def __init__(self,tipo,name,grupo):\n        self.tipo = tipo\n        self.name = name\n        self.grupo = grupo\n    def caracteristicas(self):\n        print(f\"El animal es de tipo: {self.tipo}, es un/a {self.name} y pertenece al grupo de {self.grupo}\")\n\nclass Perro(Animal):\n    def sonido(self):\n        print(\"El perro hace: Guau-Guau\")\n\nclass Gato(Animal):\n    def sonido(self):\n        print(\"El gato hace: Miau-Miau\")\n\n\nmy_animal = Animal (\"Salvaje\", \"Ballena\",\"Mamifero\")\n\nmy_animal.caracteristicas() \n\nmy_dog = Perro (\"Domestico\", \"Perro\" , \"Mamifero\")\n\nmy_dog.caracteristicas()\n\nmy_dog.sonido()\n\nmy_cat = Gato (\"Domestico\", \"Gato\", \"Mamifero\")\n\nmy_cat.caracteristicas()\n\nmy_cat.sonido()\n\n## *********EXTRA********** ##\n\nclass Empleado:\n    def __init__(self, id , name) :\n     self.id = id\n     self.name = name\n     self.empleados = []\n    def add(self,empleado):\n        self.empleados.append(empleado)\n    def print_empleados(self):\n        for empleado in self.empleados:\n            print(empleado.name)\n\n    \n\n\nclass Programador(Empleado):\n    def __init__(self, id , name , language) :\n     super().__init__(id,name)\n     self.language = language\n    def funciones (self) :\n        print (f\"El programador {self.name} programa en {self.language} y tiene las siguientes funciones: \")\n        print(\"Desarrollo de aplicaciones moviles y web \\nAcatar las instrucciones del Gerente de proyectos.\")\n    def add(self,empleado:Empleado):\n        print(f\"Un programador no tiene trabajadores a su cargo. {empleado.name} no se agregará\")\n\n\n\nclass GerenteProyectos(Empleado):\n\n    def funciones (self) :\n        print (f\"El Gerente de Proyectos {self.name} tiene las siguientes funciones: \")\n        print(\"Coordinar y definir actividades para el desarollo del proyecto asignado \\nAsignar tareas a los programadores a su cargo\")\n\nclass Gerente(Empleado):\n    def funciones (self) :\n        print (f\"El Gerente {self.name} tiene las siguientes funciones: \")\n        print(\"Establecer los requerimientos del cliente \\nAcatar los lineamientos del proyecto por parte del CEO y del cliente \\nAsignar el proyecto al gerente del proyecto\")\n\n\np_1 = Programador(1,\"Julio Cesar Torres\",\"Kotlin\")\n\np_1.funciones()\n\nm1_manager = Gerente(1,\"Francisco Gutierrez\")\nm2_manager = GerenteProyectos(1,\"Laura Jimenez\")\n\nm1_manager.add(m2_manager)\n\nm1_manager.print_empleados()"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/DataCiriano.py",
    "content": "\"\"\"\n* EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n\"\"\"\n#Crear la superclase Animal\nclass Animal():\n    \n    def __init__(self, name: str, age: int, color: str):\n        self.name = name\n        self.age = age\n        self.color = color\n    \n#Crer la subclase Perro y Gato que heredan de la clase Animal\nclass Perro(Animal):\n    \n    def __init__(self, name: str, age: int, color: str, race: str):\n        super().__init__(name, age, color)\n        self.race = race\n        \n    def bark(self):\n        print(f\"{self.name} started to bark\")\n        \n    def features(self):\n        print(f\"Name: {self.name}\")\n        print(f\"Age: {self.age}\")\n        print(f\"Race: {self.race}\")\n        print(f\"Color: {self.color}\")\n        \n        \nclass Gato(Animal):\n    \n    def __init__(self, name: str, age: int, color: str, race: str):\n        super().__init__(name, age, color)\n        self.race = race\n        \n    def meow(self):\n        print(f\"{self.name} started to meow\")\n        \n    def features(self):\n        print(f\"Name: {self.name}\")\n        print(f\"Age: {self.age}\")\n        print(f\"Race: {self.race}\")\n        print(f\"Color: {self.color}\")\n        \n#Instanciar objetos de clase\nrex = Perro(\"Rex\", 10, \"Brown\", \"German Shepherd\")\ntom = Gato(\"Tom\", 7, \"Grey\", \"Russina Blue\")\n\nrex.features()\nrex.bark()\n\ntom.features()\ntom.meow()\n\n\n\n\n#-----EXTRA-----\n\n#Crear superclase Employee\n\nclass Employee():\n    \n    def __init__(self, employee_id: int, name: str, surname: str, level: str, salary: int):\n        self.employee_id = employee_id\n        self.name = name\n        self.surname = surname\n        self.level = level\n        self.salary = salary\n        \n    def data(self):\n        print(f\"Employee ID: {self.employee_id}\")\n        print(f\"Name: {self.name}\")\n        print(f\"Surname: {self.surname}\")\n        print(f\"Level: {self.level}\")\n        print(f\"Salary: {self.salary}$\")\n\n       \n#Crear subclases Manager, ProjectManager y Developer que heredan de la superclase Employee\n\nclass Manager(Employee):\n    \n    def __init__(self, employee_id: int, name: str, surname: str, level: str, salary: int, position: str):\n        super().__init__(employee_id, name, surname, level, salary)\n        self.position = position\n        self.pm_list = []\n        self.dev_list = []\n        \n    def hire_employee(self, new_employee):\n        if new_employee.level.lower() == \"pm\":\n            self.pm_list.append(new_employee)\n            print(f\"¡¡Welcome to the team {new_employee.name} {new_employee.surname} as Project Manger!!\\n\")\n        elif new_employee.level.lower() == \"dev\":\n            self.dev_list.append(new_employee)\n            print(f\"¡¡Welcome to the team {new_employee.name} {new_employee.surname} as Developer!!\\n\")\n        else:\n            print(\"We are not hiring people with your skills. Thanks for your time.\\n\")\n            \n    def fire_employee(self, employee):\n        if employee in self.pm_list:\n            self.pm_list.remove(employee)\n            print(f\"{employee.name} {employee.surname} thank you for your work.\\n\")\n        elif employee in self.dev_list:\n            self.dev_list.remove(employee)\n            print(f\"{employee.name} {employee.surname} thank you for your work.\\n\")\n        else:\n            print(\"The employee doesn't exsist.\")\n        \n    def assign_project(self, pm_id, project):\n        for team_member in self.pm_list: \n            if team_member.employee_id == pm_id:\n                print(f\"{team_member.name} {team_member.surname} is assign to: {project}\\n\")\n                return\n        print(f\"¡¡ERROR!! No existe un empleado con el id {pm_id}.\\n\")\n        \n    def show_employees(self):\n        print(\"Project Manager List:\\n\")\n        for pm in (self.pm_list):\n            pm.data()\n            print()\n\n        print(\"Developers List:\\n\")\n        for dev in (self.dev_list):\n            dev.data()\n            print()\n    \n    def manager_data(self):\n        self.data()\n        print(f\"Position: {self.position}\\n\")\n            \nclass ProjectManager(Employee):\n    \n    def __init__(self, employee_id: str, name: str, surname: str, level: str, salary: int, projects: str):\n        super().__init__(employee_id, name, surname, level, salary)\n        self.projects = projects\n        self.project_team = []\n        \n    def show_project(self):\n        print(f\"{self.name} is on charge of the {self.projects} project.\\n\")\n        \n    def add_project_employee(self, new_developer, projects):\n        self.project_team.append(new_developer)\n        print(f\"{self.name}: ¡¡Welcome {new_developer.name} to the {projects} project!!\\n\")\n        \n    def show_team(self):\n        print(f\"Team {self.projects}\\n\")\n        print(f\"Project Manager: {self.name} {self.surname}\\n\")\n        print(\"Developers:\\n\")\n        for project_member in self.project_team:\n            print(f\"Name: {project_member.name}\")\n            print(f\"Surname: {project_member.surname}\")\n            print(f\"Level: {project_member.level}\\n\")\n            \nclass Developer(Employee):\n    \n    def __init__(self, employee_id: int, name: str, surname: str, level: str, salary: int, languages: list):\n        super().__init__(employee_id, name, surname, level, salary)\n        self.languages = languages\n        \n    def new_functionality(self, code_language):\n        for language in self.languages:\n            if language.lower() == code_language.lower():\n                print(f\"{self.name} {self.surname} is developing a new functionality in {code_language}.\")\n                return\n        print(f\"{self.name} {self.surname}: We need a new {code_language} developer.\")\n            \n    def fix_bug(self,bug: str):\n        print(f\"{self.name} {self.surname} is working on the issue '{bug}'.\")\n        \n\n\n#Instanciar clases \n\ndev_01 = Developer(21, \"Miguel\", \"Ciriano\", \"Dev\", 30000, [\"Python\", \"SQL\"])\ndev_02 = Developer(22, \"Gabriel\", \"Rojo\", \"Dev\", 30000, [\"JS\", \"SQL\"])\ndev_03 = Developer(23, \"Ana\", \"García\", \"Dev\", 30000, [\"Rust\", \"JS\",\"HTML\", \"CSS\"])\ndev_04 = Developer(24, \"Beatriz\", \"Mandel\", \"Dev\", 30000, [\"TypeScrip\", \"Java\"])\ndev_05 = Developer(25, \"Pedro\", \"Zamora\", \"Dev\", 30000, [\"Java\", \"SQL\", \"JS\", \"HTML\", \"CSS\"])\n\n\npm_01 = ProjectManager(31, \"Juanito\", \"Pérez\", \"PM\", 50000, \"Backend\")\npm_02 = ProjectManager(32, \"Alfonso\", \"Molinero\", \"PM\", 50000, \"UX/UI\")\npm_03 = ProjectManager(33, \"Rodrigo\", \"Salta\", \"PM\", 50000, \"Frontend\")\npm_04 = ProjectManager(34, \"Valeria\", \"Araya\", \"PM\", 50000, \"Marketing\")\npm_05 = ProjectManager(35, \"Susana\", \"Jara\", \"PM\", 50000, \"Sales\")\n\ndesigner = Employee(41, \"Juan\", \"Lorca\", \"Dsgn\", 30000)\n\nmanager_01 = Manager(1, \"Elon\", \"Musk\", \"CEO\", 100000, \"Management\")\n\n#Funcionalidades de la clase Manager\nmanager_01.hire_employee(dev_01)\nmanager_01.hire_employee(dev_02)\nmanager_01.hire_employee(dev_03)\nmanager_01.hire_employee(dev_04)\nmanager_01.hire_employee(dev_05)\n\nmanager_01.hire_employee(designer)\n\nmanager_01.hire_employee(pm_01)\nmanager_01.hire_employee(pm_02)\nmanager_01.hire_employee(pm_03)\nmanager_01.hire_employee(pm_04)\nmanager_01.hire_employee(pm_05)\n\nmanager_01.show_employees()\n\nmanager_01.fire_employee(dev_03)\nmanager_01.fire_employee(pm_03)\n\nmanager_01.show_employees()\n\nmanager_01.assign_project(35, \"Sales\")\nmanager_01.assign_project(32, \"UX/UI\")\nmanager_01.assign_project(4, \"UX/UI\")\n\nmanager_01.manager_data()\n\n#Funcionalidades de la clase Project Manager\npm_01.show_project()\npm_05.add_project_employee(dev_05, \"Sales\")\npm_05.add_project_employee(dev_03, \"Sales\")\n\npm_05.show_team()\n\n#Funcionalidades de la clase Developer\n\ndev_01.new_functionality(\"PYTHON\")\ndev_01.new_functionality(\"HTML\")\n\ndev_03.fix_bug(\"Cancelation order\")\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/Dkp-Dev.py",
    "content": "\"\"\"\nEJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n\"\"\"\n\n# Superclase\n\nclass Animal:\n\n    def __init__(self, name: str):\n        self.name = name\n\n    def sound(self):\n        pass\n\n# Subclases\n\n\nclass Dog(Animal):\n\n    def sound(self):\n        print(\"Guau!\")\n\n\nclass Cat(Animal):\n\n    def sound(self):\n        print(\"Miau!\")\n\n\ndef print_sound(animal: Animal):\n    animal.sound()\n\n\nmy_animal = Animal(\"Animal\")\nprint_sound(my_animal)\nmy_dog = Dog(\"Perro\")\nprint_sound(my_dog)\nmy_cat = Cat(\"Gato\")\nprint_sound(my_cat)\n\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n\"\"\"\n\n\nclass Employee:\n\n    def __init__(self, id: int, name: str):\n        self.id = id\n        self.name = name\n        self.employees = []\n\n    def add(self, employee):\n        self.employees.append(employee)\n\n    def print_employees(self):\n        for employee in self.employees:\n            print(employee.name)\n\n\nclass Manager(Employee):\n\n    def coordinate_projects(self):\n        print(f\"{self.name} está coordinando todos los proyectos de la empresa.\")\n\n\nclass ProjectManager(Employee):\n\n    def __init__(self, id: int, name: str, project: str):\n        super().__init__(id, name)\n        self.project = project\n\n    def coordinate_project(self):\n        print(f\"{self.name} está coordinando su {self.project}.\")\n\n\nclass Programmer(Employee):\n\n    def __init__(self, id: int, name: str, language: str):\n        super().__init__(id, name)\n        self.language = language\n\n    def code(self):\n        print(f\"{self.name} está programando en {self.language}.\")\n\n    def add(self, employee: Employee):\n        print(\n            f\"Un programador no tiene empleados a su cargo. {employee.name} no se añadirá.\")\n\n\nmy_manager = Manager(1, \"MoureDev\")\nmy_project_manager = ProjectManager(2, \"Brais\", \"Proyecto 1\")\nmy_project_manager2 = ProjectManager(3, \"Moure\", \"Proyecto 2\")\nmy_programmer = Programmer(4, \"Kontrol\", \"Swift\")\nmy_programmer2 = Programmer(5, \"Ros\", \"Cobol\")\nmy_programmer3 = Programmer(6, \"Bushi\", \"Dart\")\nmy_programmer4 = Programmer(7, \"Nasos\", \"Python\")\n\nmy_manager.add(my_project_manager)\nmy_manager.add(my_project_manager2)\n\nmy_project_manager.add(my_programmer)\nmy_project_manager.add(my_programmer2)\n\nmy_project_manager2.add(my_programmer3)\nmy_project_manager2.add(my_programmer4)\n\nmy_programmer.add(my_programmer2)\n\nmy_programmer.code()\nmy_project_manager.coordinate_project()\nmy_project_manager2.coordinate_project()\nmy_manager.coordinate_projects()\nmy_manager.print_employees()\nmy_project_manager.print_employees()\nmy_project_manager2.print_employees()\nmy_programmer.print_employees()\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/EmmanuelMMontesinos.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n */\n\"\"\"\n\n# Herencia\n'''Super Clase / Clase Padre'''\nclass Animal:\n    # Inicializo con todos los parametros comunes para todos los animales\n    def __init__(self,nombre,categoria,sonido=\"\") -> None:\n        self.nombre = nombre\n        self.categoria = categoria\n        self.sonido = sonido\n    \n    # Utilizo el metodo\n    def __str__(self) -> str:\n        return \"Animal\"\n    \n    # Funciones comunes para todos los animales: Mostrar los datos y emitir sonidos\n    def imprimir_datos(self):\n        print(f\"Nombre: {self.nombre}\")\n        print(f\"Categoría: {self.categoria}\\n\")\n        \n    def emitir_sonido(self):\n        print(f\"{self.nombre.title()} hace:\",end=\" \")\n        print(self.sonido + \"\\n\")\n        \n\n'''Clases que heredan de Animal'''\nclass Perro(Animal):\n    def __init__(self, nombre, categoria) -> None:\n        super().__init__(nombre, categoria,sonido=\"Guau!\")\n    \n    def __str__(self) -> str:\n        return \"Perro\"\n    \n    # Función propia de Perro\n    def rastrar(self):\n        print(f\"El {self} esta rastreando\\n\")\n        \nclass Gato(Animal):\n    def __init__(self, nombre, categoria) -> None:\n        super().__init__(nombre, categoria,sonido=\"Miau!\")\n        \n    def __str__(self) -> str:\n        return \"Gato\"\n    \n    # Función propia de Gato\n    def ronronear(self):\n        print(f\"El {self} esta ronroneando: Grrrrr\\n\")\n\n\n# Pruebas\nperro = Perro(\"Ojala\",\"Grande\")\nperro.imprimir_datos()\nperro.emitir_sonido()\nperro.rastrar()\n\ngato = Gato(\"Salomon\",\"Pequeño\")\ngato.imprimir_datos()\ngato.emitir_sonido()\ngato.ronronear()\n\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n\"\"\"\n\n\nclass Empleados:\n    \n    def __init__(self,nombre,puesto) -> None:\n        Empleados.n_empleados += 1\n        self.id = Empleados.n_empleados\n        self.nombre = nombre\n        self.puesto = puesto\n\n    def imprimir_datos(self):\n        print(\"Información del trabajador:\")\n        print(f\"Nombre: {self.nombre}\")\n        print(f\"Id: {self.id}\\n\")\n    \n    n_empleados = 0\n    lista_empleados = []\n    \n        \nclass Programadores(Empleados):\n    \n    def __init__(self, nombre, puesto,lider) -> None:\n        super().__init__(nombre, puesto)\n        self.tarea = \"\"\n        self.lider = lider\n        self.objetivo = \"\"\n        Empleados.lista_empleados.append(self)\n        print(f\"{self.nombre} ha sido añadido al grupo de {self.lider}\\n\")\n            \nclass Lider(Empleados):\n    \n    def __init__(self, nombre, puesto) -> None:\n        super().__init__(nombre, puesto)\n        print(f\"{self.nombre} es ahora Lider de Equipo!\\n\")\n        \n    def asignar_tarea(self,tarea):\n        empleados = self.ver_empleados()\n        for empleado in empleados:\n            empleado.tarea = tarea\n            print(f\"{self.nombre} ha asignado una tarea a {empleado.nombre}: {empleado.tarea}\\n\")\n            \n    def ver_empleados(self):\n        lista = [empleado for empleado in Empleados.lista_empleados if empleado.lider == self.nombre]\n        return lista\n    \n    def imprimir_empleados(self):\n        lista = self.ver_empleados()\n        print(f\"Equipo de {self.nombre}:\")\n        for empleado in lista:\n            print(f\"{empleado.nombre} ---> {empleado.puesto}\")\n        print()\n    \nclass Jefe(Empleados):\n    \n    def __init__(self, nombre, puesto) -> None:\n        super().__init__(nombre, puesto)\n        print(f\"{self.nombre} ha comprado la Empresa\\n\")\n        \n    def asignar_objetivo(self,lider,objetivo):\n        lider.objetivo = objetivo\n        print(f\"{self.nombre} ha asignado el objetivo de '{objetivo}' a {lider.nombre}\\n\")\n\n\n# Pruebas\n    \nlider = Lider(\"MoureDev\",\"Jefe de Proyecto\")\nempleado_1 = Programadores(\"Emmanuel\",\"Junior\",\"MoureDev\")\njefe = Jefe(\"Elon Musk\",\"CEO\")\n\nlider.imprimir_datos()\nlider.imprimir_empleados()\n\nlider.asignar_tarea(\"Haz este Ejercicio!\")\njefe.asignar_objetivo(lider,\"destruir Twitter\")\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/EricJoel-code.py",
    "content": "## Herencia y Polimorfismo\n\n\"\"\"Concepto: La Herencia es un pilar de la programación orientada a objetos (POO) que permite a una clase nueva (hija o subclase) adquirir propiedades (atributos) y comportamientos (métodos) de una clase existente (padre o superclase), fomentando la reutilización de código y creando una jerarquía entre las clases. El polimorfismo permite que objetos de diferentes clases se traten como si pertenecieran a una misma superclase, gracias a que implementan el mismo método de formas distintas. Esto se traduce en código más flexible, reutilizable y potente, ya que diferentes objetos responden a la misma solicitud con su comportamiento específico. \"\"\"\n\n#Clase Padre\nclass Animal:\n    def __init__(self, name):\n        self.name = name\n        \n    def sonido(self):\n        pass\n    \n\n#Subclases\nclass Perro(Animal):\n    \n    def sonido(self):\n        print(\"Guau!\")\n        \nclass Gato(Animal):\n    \n    def sonido(self):\n        print(\"Miau!\")\n        \n        \ndef imprimir_sonido(animal: Animal):\n    animal.sonido()\n        \nanimal = Animal(\"Animal\")\nimprimir_sonido(animal)\nperro = Perro(\"Ody\")\nimprimir_sonido(perro)\ngato = Gato(\"Chiquitina\")\nimprimir_sonido(gato)\n\n##Extra\n\nclass Empleado:\n    \n    def __init__(self, id:int, name:str):\n        self.id = id\n        self.name = name\n        self.empleados = []\n        \n    def agregar(self, empleado):\n        self.empleados.append(empleado)\n        \nclass Gerente(Empleado):\n    \n    def cordinar_proyectos(self):\n        print(f\"{self.name} esta cordinando todos los proyectos de la empresa\")\n    \nclass GerenteProyectos(Empleado):\n    \n    def __init__(self, id:int, name:str, proyecto:str):\n        super().__init__(id, name)\n        self.proyecto = proyecto\n        \n    def cordinar_proyecto(self):\n        print(f\"{self.name} esta cordinando el {self.proyecto}\")\n\nclass Programador(Empleado):\n    def __init__(self, id:int, name:str, lenguaje:str):\n        super().__init__(id, name)\n        self.lenguaje = lenguaje\n        \n    def codificar(self):\n        print(f\"{self.name} esta programando en {self.lenguaje}\")\n        \n    def agregar(self, empleado:Empleado):\n        print(f\"Un programador no tiene empleados a su cargo. {empleado.name} no se agregara\")\n        \n        \ngerente = Gerente(1, \"Eric\")\ngerente_de_proyecto = GerenteProyectos(2, \"Joel\",\"Proyecto 1\")\ngerente_de_proyecto2 = GerenteProyectos(3, \"Paul\", \"Proyecto 2\")\nprogramador = Programador(4,\"Juan\", \"Java\")\nprogramador2 = Programador(5,\"Pepe\", \"C\")\nprogramador3 = Programador(6,\"Ana\", \"C++\")\n\ngerente.agregar(gerente_de_proyecto)\ngerente.agregar(gerente_de_proyecto2)\n\ngerente_de_proyecto.agregar(programador)\n\ngerente_de_proyecto2.agregar(programador2)\ngerente_de_proyecto2.agregar(programador3)\n\nprogramador.agregar(programador2)\n\nprogramador2.codificar()\ngerente_de_proyecto.cordinar_proyecto()\ngerente.cordinar_proyectos()"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/FedeAirala.py",
    "content": "# Reto #09 Herencia\n\n\"\"\"\n\n/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n \"\"\"\n \n # Herencia de clases\n\n\"\"\" En la hrencia de clases una nueva clase hereda todos las propiedades y méetodos de otra clase (Clase Base)\"\"\"\n\nclass Animal():\n    def __init__(self,name:str,race:str) -> None:\n        self.name = name\n        self.race =race\n\n    def sounds(self):\n        print (f\"El sonido del {self.animal}  es {self.sound}\")   \n\nclass Dog(Animal):\n    def __init__(self,name,race) -> None:\n        super().__init__(name,race)             # Toma los parámetros y métodos de la superclase Animal\n        self.animal=\"perro\"\n        self.sound=\"Guau\"\n        \nclass Cat(Animal):\n    def __init__(self,name,race):\n        super().__init__(name,race)              # Toma los parámetros y métodos de la superclase Animal\n        self.animal= \"gato\"\n        self.sound=\"Miau\"\n        \n\ndog1 = Dog (\"Oliver\",\"Dobrman\")    \ndog2 = Dog (\"León\",\"Ovejero\")\ncat1 = Cat(\"Peluchin\",\"Siames\")\nprint (f\"El perro {dog2.name} es de raza {dog2.race}\")\nprint (f\"El perro {dog1.name} es de raza {dog1.race}\")\ndog1.sounds()\nprint (f\"El gato {cat1.name} es de raza {cat1.race}\")\ncat1.sounds()\n\nprint (\"\\n\"*3)\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n\"\"\"\nprint (\"-\"*100)\nprint (\"Empresa X\")\n\n\nclass Empleados():\n    def __init__(self,fname,id:int) -> None:\n        self.fname = fname\n        self.id = id\n\n\nclass Gerente(Empleados):\n    def __init__(self, fname,id,emp_a_cargo) -> None:\n        super().__init__(fname,id)\n        self.emp_a_cargo = emp_a_cargo\n    \n    def mostrar_id(self):\n        print (f\"El gerente {self.fname} tiene id {self.id}\")\n    \n    def list_pers_a_cargo(self):\n        print (f\"El gerente {self.fname} tiene a cargo a :\")\n        for i in range (0,len(self.emp_a_cargo)):\n            print (self.emp_a_cargo[i])\n\n\nclass GerenteProyectos(Empleados):\n    def __init__(self, fname,id: int,proy_a_cargo) -> None:\n        super().__init__( fname, id)\n        self.proy_a_cargo = proy_a_cargo\n    \n    def mostrar_id(self):\n        print (f\"El gerente de proyectos {self.fname} tiene id {self.id}\")\n\n    def list_proy_a_cargo(self):\n        print (f\"El gerente de proyectos {self.fname} tiene a cargo los proyectos:\")\n\n        for i in range (0,len(self.proy_a_cargo)):\n            print (self.proy_a_cargo[i])\n\n\nclass Programadores(Empleados):\n    def __init__(self, fname, id: int,programas) -> None:\n        super().__init__(fname, id)\n        self.programas = programas\n\n    def mostrar_id(self):\n        print (f\"El Programador {self.fname} tiene id {self.id}\")\n    \n    def list_program(self):\n        print (f\"El Programador {self.fname} conoce los siguientes lenguajes:\")\n\n        for i in range (0,len(self.programas)):\n            print (self.programas[i])\n   \n\ne1 = Empleados(\"María\",1)\ne2 = Empleados(\"José\",2)\ne3 = Empleados(\"Pedro\",3)\ne4 = Empleados(\"Roberto\",4)\ne5 = Empleados(\"Pepe\",5)\ne6 = Empleados(\"Javier\",6)\n\ng1 = Gerente (e1.fname,e1.id,[e2.fname,e3.fname,e4.fname])\ng2 = GerenteProyectos(e4.fname,e4.id, [\"P1\",\"P2\",\"P3\"])\nprog1 = Programadores( e6.fname,e6.id, [\"Python\",\"R\",\"Javascript\"])\n\ng1.mostrar_id()\ng1.list_pers_a_cargo()\nprog1.mostrar_id()\nprog1.list_program()\ng2.mostrar_id()\ng2.list_proy_a_cargo()\n\n\n\n\n\n\n\n\"\"\"\n\n\ndef cargar_emp(list_emp):\n    \n    id= len(list_emp)\n    while True:\n        fname = input (\"Ingrese nombre:\")\n        sname = input (\"Ingrese apellido: \")\n        age = input (\"Ingrese edad: \")\n        id +=1\n        \n        puesto = input (\"Ingrese puesto: \")\n\n        list_emp.append (Empleados(fname, sname,age,id,puesto))\n        continuar_carga = input (\"Desea seguir cargando empleados S/N: \")\n\n        if continuar_carga == \"S\":\n            continue\n        else: \n            break\n    return list_emp\n\ndef listar_empleados(list_emp):\n    for i in range (0,int(len(list_emp))):\n        x=(list_emp[i])\n        print (f\"{x.id} --- {x.fname} --- {x.puesto}\")\n\nlist_emp=[]\n\ndef main():\n    print (\"-\"*60)\n    while True:\n        print (\"1.Empleados  !  2.Cargar !  3.Salir\")\n\n        accion = (input(\"Ingrese una opción: \"))\n        match accion:\n            case \"1\":\n                listar_empleados(list_emp)\n            case \"2\":\n                cargar_emp(list_emp)\n            case \"3\":\n                print(\"Saliendo del programa\")\n                break\n            \n            case _:\n                print (\"Ingrese una opción válida\")\n\n\n                 \n   \n    \nif __name__ == \"__main__\":\n    main()\n\n\"\"\"\n\n\n\n\n        \n       \n\n\n        \n\n    "
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/Gallitofast.py",
    "content": "\"\"\"Herencia y polimorfismo\"\"\"\n'''Heredacion de metodos, atributos, etc.'''\nclass Animal:\n    def __init__(self,name: str):\n        self.name = name \n    def sound(self):\n        pass\n    \nclass Dog(Animal):\n    \n    def sound(self):\n        print(\"WOOF WOOF\")\n \n\nclass Cat(Animal):\n        def sound(self):\n            print(\"MIAW MIAW\")\n \n\nperrito= Dog(\"Panchito\")\nperrito.sound()\ngatito= Cat(\"Alpaccino\")\ngatito.sound()\n\n\nclass Employee():\n     def __init__(self,name,id:int)-> None:\n          self.name = name\n          self.id = id \n\nclass Manager(Employee):\n     def __init__(self,name,id:int,designations)-> None:\n          self.name = name\n          self.id = id\n          self.designations = designations\n     def show_id(self):\n        print (f\"The manager {self.name} has this id {self.id}\")\n    \n     def list_designations(self):\n        print (f\"The manager {self.name} has in charge :\")\n        for i in range (0,len(self.designations)):\n            print (self.designations[i])\n\nclass Project_Manager(Employee):\n     def __init__(self,name,id:int,project_designations) -> None:\n          self.name= name\n          self.id= id\n          self.project_designations = project_designations\n     def show_id(self):\n        print (f\"The project manager {self.name} has this id {self.id}\")\n     def list_projects(self):\n         print (f\"The manager {self.name} has in charge the following projects:\")\n\n         for i in range (0,len(self.project_designations)):\n             print (self.project_designations[i])\n\nclass Programmer(Employee):\n     def __init__(self, name, id: int,programs) -> None:\n        super().__init__(name, id)\n        self.programs = programs\n\n     def show_id(self):\n        print (f\"The programmer {self.name} has this id {self.id}\")\n    \n     def list_program(self):\n        print (f\"This programmer {self.name} knows the following languages:\")\n\n        for i in range (0,len(self.programs)):\n            print (self.programs[i])\n\n\ne1 = Employee(\"María\",1)\ne2 = Employee(\"José\",2)\ne3 = Employee(\"Pedro\",3)\ne4 = Employee(\"Roberto\",4)\ne5 = Employee(\"Pepe\",5)\ne6 = Employee(\"Javier\",6)\n\ng1 = Manager (e1.name,e1.id,[e2.name,e3.name,e4.name])\ng2 = Project_Manager(e4.name,e4.id, [\"P1\",\"P2\",\"P3\"])\nprog1 = Programmer( e6.name, e6.id, [\"Python\",\"R\",\"Javascript\"])\n\ng1.show_id()\ng1.list_designations()\nprog1.show_id()\nprog1.list_program()\ng2.show_id()\ng2.list_projects()"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/Gordo-Master.py",
    "content": "\"\"\"\nHerencia y polimorfismo\n\"\"\"\n\nclass Animal:\n    \n    def __init__(self, name):\n        self.name = name\n        self.sound = \"desconocido\"\n    \n    def call_sound(self):\n        print(f\"El sonido que hace {self.name} es: {self.sound}\")\n\nclass Perro(Animal):\n    def __init__(self, name):\n        super().__init__(name)\n        self.sound = \"guau guau\"\n\nclass Gato(Animal):\n    def __init__(self, name):\n        super().__init__(name)\n        self.sound = \"miau miau\"\n\ndef print_sound(animal: Animal):\n    animal.call_sound()\n\n\nmy_animal = Animal(\"pepe\")\nmy_perro = Perro(\"Doggie\")\nmy_perro.call_sound()\nmy_gato = Gato(\"Michael\")\nmy_gato.call_sound()\n\nprint_sound(my_animal)\nprint_sound(my_perro)\nprint_sound(my_gato)\n\n\n\n\n\"\"\"\nEjercicio Extra\n\"\"\"\n\nclass Empleado:\n    def __init__(self, identificador, name: str):\n        self.id = identificador\n        self.name = name\n        self.empleados = []\n\n    def agregar(self, empleado):\n        self.empleados.append(empleado)\n\n    def print_empleados(self):\n        if len(self.empleados) > 0:\n            print(f\"{self.name} esta acargo de los siguientes empleados: \")\n            for empleados in self.empleados:\n                print(empleados.name)\n        else:\n            print(f\"{self.name} no tiene empleados a su cargo\")\n\n\nclass Gerentes(Empleado):\n    \n    def coordinar_proyectos(self):\n        print(f\"{self.name} está coordinando todos los proyectos de la empresa\")\n    \n    \n\n\nclass GerentesDeProyectos(Empleado):\n\n    def __init__(self, identificador, name: str, proyecto: str):\n        super().__init__(identificador, name)\n        self.proyecto = proyecto\n    \n    def coordinar_proyecto(self):\n        print(f\"{self.name} está coordinando el siguiente proyecto: {self.proyecto}\")\n\n\nclass Programadores(Empleado):\n\n    def __init__(self, identificador, name: str, language: str):\n        super().__init__(identificador, name)\n        self.language = language\n    \n    def programar(self):\n        print(f\"{self.name} esta programando en {self.language}\")\n\n    def agregar(self, empleado: Empleado):\n        print(f\"Un programador no tiene empleados a su cargo. {empleado.name} no se añadirá\")\n\n\nmy_manager = Gerentes(1, \"Gordo-Master\")\nmy_proyect_manager = GerentesDeProyectos(2, \"Gordo\", \"Proyecto 1\")\nmy_proyect_manager2 = GerentesDeProyectos(3, \"Master\", \"Proyecto 2\")\nmy_programer = Programadores(4, \"Franco\", \"C++\")\nmy_programer2 = Programadores(5, \"José\", \"JavaScript\")\nmy_programer3 = Programadores(6, \"Luis\", \"Python\")\nmy_programer4 = Programadores(7, \"Alberto\", \"Java\")\n\nmy_manager.agregar(my_proyect_manager)\nmy_manager.agregar(my_proyect_manager2)\nmy_proyect_manager.agregar(my_programer)\nmy_proyect_manager.agregar(my_programer2)\nmy_proyect_manager2.agregar(my_programer3)\nmy_proyect_manager2.agregar(my_programer4)\n\nmy_programer.agregar(my_programer2)\n\n# my_programer.programar()\nmy_programer2.programar()\n# my_programer3.programar()\n# my_programer4.programar()\n\n# my_proyect_manager.coordinar_proyecto()\nmy_proyect_manager2.coordinar_proyecto()\n\nmy_manager.coordinar_proyectos()\n\nmy_manager.print_empleados()\nmy_proyect_manager.print_empleados()\nmy_programer4.print_empleados()"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/Hyromy.py",
    "content": "# clase padre\nclass Animal:\n\n    # contructor de la clase padre\n    def __init__(self, nombre, tamaño):\n        self.nombre = nombre\n        self.tamaño = tamaño\n\n    # metodos comunes\n\n    def mostrar(self):\n        print(f\"Soy un {self.nombre} {self.tamaño}\")\n\n    def comer(self):\n        print(f\"{self.nombre} está comiendo\")\n\n# clase perro que hereda de animal\nclass Perro(Animal):\n\n    # constructor para la clase perro (similar al constructor de la clase padre)\n    def __init__(self, nombre, tamaño, raza):\n        super().__init__(nombre, tamaño) # super hace referencia al padre o a la super clase\n        self.raza = raza # atributo de la clase perro\n\n    # metodos propios\n\n    def sonido(self):\n        print(\"Guau!\")\n\n    def mostrar_raza(self):\n        print(f\"Soy un {self.raza}\")\n\n# clase gato que hereda de animal (diferente a perro)\nclass Gato(Animal):\n\n    # constructor para la clase gato (similar al constructor de la clase padre )\n    def __init__(self, nombre, tamaño, pelaje):\n        super().__init__(nombre, tamaño) # heredando las mismas propiedades de animal\n        self.pelaje = pelaje # atributo propio de la clase gato\n\n    def sonido(self):\n        print(\"Miau\")\n\n    def tocar_pelaje(self):\n        print(f\"{self.nombre} tiene un pelaje {self.pelaje}\")\n\n# instanciar objetos de cada clase\nfreddy = Animal(\"oso\", \"grande\")\nfirulais = Perro(\"Firulais\", \"mediano\", \"Shiba Inu\")\nmichi = Gato(\"micchi\", \"pequeño\", \"suave\")\n\n# metodo mostrar\nfreddy.mostrar()\nfirulais.mostrar()\nmichi.mostrar()\n\n# metodo comer\nfreddy.comer()\nfirulais.comer()\nmichi.comer()\n\n# metodo sonido\n#freddy.sonido() # Animal no puede porque no esta definido el metodo sonido\nfirulais.sonido() # Perro.sonido() => Guau\nmichi.sonido() # Gato.sonido() => Miau\n\n# metodo mostrar_raza\nfirulais.mostrar_raza() # Animal y Gato no poseen dicho metodo\n\n# metetodo tocar_pelaje\nmichi.tocar_pelaje() # Animal y Perro no poseen dicho metodo\n\n\"\"\"\n ---- DIFICULTAD EXTRA ----\n\"\"\"\n\nfrom abc import ABC, abstractmethod\n\nclass Empleado(ABC): # clase abstracta\n    def __init__(self, nombre, edad, matricula):\n        self.nombre = nombre\n        self.edad = edad\n        self.matricula = matricula\n\n    # metodo comun\n    def presentarse(self):\n        print(f\"Me llamo {self.nombre}, tengo {self.edad}. Mi matricula es {self.matricula}\")\n\n    # metodo abstracto\n    @abstractmethod\n    def trabajar(self):\n        pass\n\n\nclass Programador(Empleado):\n    def __init__(self, nombre, edad, matricula, lenguaje):\n        super().__init__(nombre, edad, matricula)\n        self.lenguaje = lenguaje\n\n    def trabajar(self):\n        print(f\"{self.nombre} esta trabajando en {self.lenguaje}\")\n\nclass Gerente(Empleado):\n    def __init__(self, nombre, edad, matricula):\n        super().__init__(nombre, edad, matricula)\n        self.programadores = []\n\n    def trabajar(self):\n        if len(self.empleados_matricula) > 0:\n            print(f\"El gerente {self.nombre} esta trabajando con los programadores: {self.programadores}\")\n        else:\n            print(f\"El gerente {self.nombre} no tiene empleados a cargo\")\n\n    def agregar_programador(self, programador):\n        self.programadores.append(programador)\n\n    def quitar_programador(self, index = -1):\n        if len(self.programadores) > 0:\n            self.programadores.pop(index)\n        else:\n            print(\"No hay programadores por remover\")\n\nclass Gerente_P(Empleado):\n    def __init__(self, nombre, edad, matricula, proyecto):\n        super().__init__(nombre, edad, matricula)\n        self.proyecto = proyecto\n\n    def trabajar(self):\n        print(f\"El gerente {self.nombre} está trabajando en el proyecto {self.proyecto}\")\n\n    def dormir(self):\n        print(f\"{self.nombre} se durmió xd\")"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/Irenetitor.py",
    "content": "#Inheritance\n\nclass Animal:\n    def __init__(self, name):\n        self.name = name\n        \n    def sound(self):\n        return \"This animal does not have a specific sound\"\n\n    def print(self):\n        print(f\"{self.name}: {self.sound()}\")\n\n\nclass Dog(Animal):\n    def __init__(self, name, breed):\n        super().__init__(name)\n        self.breed = breed\n\n    def print(self):\n        print(f\"{self.name} ({self.breed}): {self.sound()}\")\n\n    def sound(self):\n        return \"Woof\"\n\n\nclass Cat(Animal):\n    def sound(self):\n        return \"Meow\"\n\n\ndef print_sound(animal: Animal):\n    print(animal.sound())\n\n\n# Create objects\ndog = Dog(\"Bobbi\", \"Beagle\")\ncat = Cat(\"Kuba\")\n\n# Print their sounds\nprint_sound(dog)  # Woof\nprint_sound(cat)  # Meow\n\n# Print full profile\ndog.print()  # Bobbi: Woof\ncat.print()  # Kuba: Meow\n\n\n#Extra Exercise\n\nclass Employee:\n\n    def __init__(self, id, name):\n        self.id = id\n        self.name = name\n        self.employees = []\n\n    def add(self, employee):\n        self.employees.append(employee)\n\n    def print_employees(self):\n        for employee in self.employees:\n            print(employee.name)\n\nclass Manager(Employee):\n    def coordinate_projects(self):\n        print(f\"{self.name} is coordinating all the projects\")\n\nclass ProjectManager(Employee):\n    def __init__(self, id, name, project):\n        super().__init__(id, name)\n        self.project = project\n\n    def coord_project(self):\n        print(f\"{self.name} is coordinating  it owns project\")\n\n\n\nclass Programmer(Employee):\n    def __init__(self, id, name, language):\n        super().__init__(id, name)\n        self.language = language\n\n    def code(self):\n        print(f\"{self.name} is coding in {self.language}\")\n\n    def add(self, employee):\n        print(f\"A programmer doesn’t supervise any employees. {employee.name} will not be added.\")\n\nmy_manager = Manager(1, \"Anna\")\nmy_project_manager = ProjectManager(2, \"Pablo\", \"Project 1\")\nmy_project_manager2 = ProjectManager(3, \"David\", \"Project 2\")\nmy_programmer = Programmer(4, \"Rose\", \"Java\")\nmy_programmer2 = Programmer(5, \"Ross\", \"JavaScript\")\nmy_programmer3 = Programmer(6, \"Marta\", \"Python\")\n\nmy_manager.add(my_project_manager)\nmy_manager.add(my_project_manager2)\nmy_project_manager.add(my_programmer2)\nmy_project_manager2.add(my_programmer3)\nmy_project_manager.add(my_programmer)\n\nmy_programmer3.add(my_programmer3)\n\n\nmy_programmer.code()\nmy_manager.coordinate_projects()\nmy_project_manager.coord_project()\nmy_manager.print_employees()\nmy_project_manager.print_employees()\nmy_project_manager2.print_employees()\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/JAFeito.py",
    "content": " # EJERCICIO:\n # Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n # implemente una superclase Animal y un par de subclases Perro y Gato,\n # junto con una función que sirva para imprimir el sonido que emite cada Animal.\n \n # DIFICULTAD EXTRA (opcional):\n # Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n # pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n # Cada empleado tiene un identificador y un nombre.\n # Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n # actividad, y almacenan los empleados a su cargo.\n \nclass Empleado:\n    def __init__(self,id : int, nombre : str):\n        self.id = id\n        self.nombre = nombre\n        self.equipo = []\n\nclass Gerente(Empleado):\n\n    def add_trabajador(self, trabajador):\n        self.equipo.append(trabajador)\n        \n    def trabajo(self):\n        print(f\"{self.nombre} es el gerente a cargo del siguiente equipo:\")\n        \n        for i in self.equipo:\n            print(f\"{i} \\n\")\n    \n        \nclass GerenteP(Empleado):\n    \n    def add_trabajador(self, trabajador):\n        self.equipo.append(trabajador)\n        \n    def __init__(self, id: int, nombre: str, proyecto: str):\n        super().__init__(id, nombre)\n        self.proyecto = proyecto    \n        \n    def trabajo(self):\n        print(f\"{self.nombre} es gerente de proyectos a cargo del proyecto {self.proyecto} con el siguiente equipo:\")\n        for i in self.equipo:\n            print(f\"{i}\\n\")\n\n\nclass Programador(Empleado):\n    def __init__(self, id: int, nombre: str, lenguaje: str):\n        super().__init__(id, nombre)\n        self.lenguaje = lenguaje\n    def trabajo(self):\n        print(f\"{self.nombre} programando en {self.lenguaje}\")\n        \n        \ngerente_1 = Gerente(1,\"Paco\")\ngerente_p_1 = GerenteP(2, \"Manolo\",\"Login\")\nprogramador_1 = Programador(3, \"Antonio\", \"Python\")\nprogramador_2 = Programador(4, \"Manel\", \"Python\")\nprogramador_3 = Programador(5, \"Laila\", \"Python\")\ngerente_1.add_trabajador(programador_1.nombre)\ngerente_1.add_trabajador(programador_2.nombre)\ngerente_1.add_trabajador(programador_3.nombre)\ngerente_1.trabajo()\ngerente_p_1.add_trabajador(programador_1.nombre)\ngerente_p_1.add_trabajador(gerente_1.nombre)\ngerente_p_1.trabajo()"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/Jav-mol.py",
    "content": "# --- 09 HERENCIA Y POLIMORFISMO ---\n# --- Javer Molina ---\n\n# SuperClase\nclass Animal: \n    def __init__(self, name: str) -> None:\n        self.name = name\n\n\n# SubClases\nclass Gato(Animal):    \n    def sonido(self):\n        print('<MIAU>')\n        \n        \nclass Perro(Animal):\n    def sonido(self):\n        print('<GUAU>')\n        \ngato = Gato('gato')\ngato.sonido()\n\nperro = Perro('perro')\nperro.sonido()\n\nprint()\n\n# --- Dificultad Extra ---\n\nclass Empleado: #SuperClase\n    def __init__(self,id: int, name: str, cargo: str) -> None:\n        self.id = id\n        self.name = name\n        self.cargo = cargo\n    \n    def description():\n        pass\n    \n    def __str__(self) -> str:\n        return f'[Id: {self.id} - Nombre: {self.name} - Cargo: {self.cargo}]'\n\n\nclass Gerente(Empleado): #SubClase\n    def __init__(self, id: int, name: str, cargo: str, empleados: list[Empleado]) -> None:\n        super().__init__(id, name, cargo)\n        self.empleados = [empleado.name for empleado in empleados]\n        \n    def description(self):\n        return f'{self.cargo}: Tiene una jerarquia mas elevada, lidera los demas empleados'\n    \n    def empleados_a_cargo(self):\n        return f'Empleados: {self.empleados}'\n    \n    \nclass GerenteDeProyecto(Empleado): #SubClase\n    def __init__(self, id: int, name: str, cargo: str, empleados: list[Empleado]) -> None:\n        super().__init__(id, name, cargo)\n        self.empleados = [empleado.name for empleado in empleados]\n    \n    def description(self):\n        return f'{self.cargo}: Tiene una jerarquia intermedia, lidera los proyectos bajo su cargo'\n\n    def empleados_a_cargo(self):\n        return f'Empleados a cargo: {self.empleados}'\n    \n    \nclass Programador(Empleado): #SubClase\n    def __init__(self, id: int, name: str, cargo: str) -> None:\n        super().__init__(id, name, cargo)\n\n    def description(self):\n        return f'{self.cargo}: Tiene una jerarquia baja, puede diriguir los demas programadores a su cargo'\n\n    \ndesarrollador_1 = Programador(1,'Javi','Software Developer')\ndesarrollador_2 = Programador(2,'Camila','Software Developer')\ndesarrollador_3 = Programador(3,'Nico','Software Developer')\ndesarrollador_4 = Programador(4,'Sofia','Software Developer')\n\ngerente_de_proyecto_1 = GerenteDeProyecto(\n    id = 5,\n    name = 'Pedro',\n    cargo = 'Gerente de Proyecto', \n    empleados = [desarrollador_1,desarrollador_2]\n)\n\ngerente_de_proyecto_2 = GerenteDeProyecto(\n    id = 6,\n    name = 'Martin',\n    cargo = 'Gerente de Proyecto', \n    empleados = [desarrollador_3,desarrollador_4]\n)\n\ngerente_1 = Gerente(\n    id = 7,\n    name = 'Alvaro',\n    cargo = 'Gerente', \n    empleados = [gerente_de_proyecto_1,gerente_de_proyecto_2]\n)\n\n# Desarrolladores\nprint(desarrollador_1)\nprint(desarrollador_2.description())\nprint()\n\n# Gerente De Proyectos\nprint(gerente_de_proyecto_1)\nprint(gerente_de_proyecto_1.description())\nprint(gerente_de_proyecto_1.empleados_a_cargo())\nprint()\n\n# Gerente\nprint(gerente_1)\nprint(gerente_1.description())\nprint(gerente_1.empleados_a_cargo())\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/JesusAntonioEEscamilla.py",
    "content": "# #09 - Python -> Jesus Antonio Escamilla\n\n\"\"\"\nEJERCIÓ\n\"\"\"\n# Definimos la superclase Animal\nclass Animal:\n    def hacer_sonido(self):\n        raise NotImplemented(\"Este método debe ser implementado por las subclases\")\n\n# Definimos la subclase Perro\nclass Perro(Animal):\n    def hacer_sonido(self):\n        return \"El perro dice: ¡Guau Guau!\"\n\n# Definimos la subclase Gato\nclass Gato(Animal):\n    def hacer_sonido(self):\n        return \"El gato dice: ¡Miau Miau!\"\n\n# Definimos la subclase Pájaro\nclass Pajaro(Animal):\n    def hacer_sonido(self):\n        return \"El pájaro dice: ¡Pio Pio!\"\n\n# Función para imprimir el sonido de cualquier animal\ndef imprimir_sonido(animal):\n    print(f\"{animal.hacer_sonido()}\")\n\n# Crear instancias\nperro = Perro()\ngato = Gato()\npajaro = Pajaro()\n\nimprimir_sonido(perro)\nimprimir_sonido(gato)\nimprimir_sonido(pajaro)\n\n\n\n\"\"\"\nEXTRA\n\"\"\"\n# Creando la superclase\nclass Employ:\n    _contador_id = 1  # Contador de ID estático\n\n    def __init__(self, nombre):\n        self.id = Employ._contador_id\n        Employ._contador_id += 1\n        self.nombre = nombre\n\n    def show_details(self):\n        print(f\"\\nID: {self.id}, Nombre: {self.nombre}\")\n\n# Creando la clase Gerente\nclass Manager(Employ):\n    def __init__(self, nombre):\n        super().__init__(nombre)\n        self.empleados_a_cargo = []\n\n    def add_employ(self, empleados):\n        self.empleados_a_cargo.append(empleados)\n\n    def show_details(self):\n        super().show_details()\n        print(\"\\nEmpleados a cargo:\")\n        for empleado in self.empleados_a_cargo:\n            empleado.show_details()\n\n# Creando la clase Gerente de Proyecto\nclass ProjectManager(Employ):\n    def __init__(self, nombre, proyectos):\n        super().__init__(nombre)\n        self.proyectos = proyectos\n\n    def show_details(self):\n        super().show_details()\n        print(f\"Proyectos: {', '.join(self.proyectos)}\")\n\n# Creando la clase Programador\nclass Programmer(Employ):\n    def __init__(self, nombre, lenguaje):\n        super().__init__(nombre)\n        self.lenguaje = lenguaje\n\n    def show_details(self):\n        super().show_details()\n        print(f\"Lenguaje: {self.lenguaje}\")\n\n# Ejecutar\n# Crear Gerente\ngerente = Manager(\"Jesus\")\n\n# Crear Gerentes de Proyecto\ngerente_proyecto1 = ProjectManager(\"Antonio\", [\"Proyecto 1\"])\ngerente_proyecto2 = ProjectManager(\"Faty\", [\"Proyecto 2\"])\n\n# Crear Programadores\nprogrammer1 = Programmer(\"Adolfo\", \"Python\")\nprogrammer2 = Programmer(\"Naty\", \"C#\")\nprogrammer3 = Programmer(\"Ruben\", \"Kotlin\")\nprogrammer4 = Programmer(\"Axel\", \"JavaScript\")\n\n# Agregar empleados a cargo del gerente\ngerente.add_employ(gerente_proyecto1)\ngerente.add_employ(gerente_proyecto2)\ngerente.add_employ(programmer1)\ngerente.add_employ(programmer2)\ngerente.add_employ(programmer3)\ngerente.add_employ(programmer4)\n\n# Mostrar detalle de los empleados\ngerente.show_details()\ngerente_proyecto1.show_details()\ngerente_proyecto2.show_details()\nprogrammer1.show_details()\nprogrammer2.show_details()\nprogrammer3.show_details()"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/JheisonQuiroga.py",
    "content": "# Superclase\nclass Animal:\n    def __init__(self, name):\n        self.name = name\n\n    def sound(self):\n        pass\n    \n\n# Herencia\n# Subclase    \nclass Dog(Animal):\n    def __init__(self, name, kind):\n        super().__init__(name)\n        self.kind = kind\n\n    # Polimorfismo\n    def sound(self):\n        print(\"Guau!\")\n\n\nclass Cat(Animal):\n    def __init__(self, name, kind):\n        super().__init__(name)\n        self.kind = kind\n\n    def sound(self):\n        print(\"Miau!\")\n\n\nd1 = Dog(\"Tobby\", \"Yorkshire\")        \nc1 = Cat(\"Lucas\", \"Desconocido\")\n\n\nfor obj in (d1, c1):\n    print(obj.name, obj.kind)\n    obj.sound()\n\n\n\"\"\"\nExtra\n\"\"\"\n\nclass Employee:\n    def __init__(self, id, firstname, lastname):\n        self.id = id\n        self.firstname = firstname\n        self.lastname = lastname\n\nclass Manager(Employee):\n    def __init__(self, id, firstname, lastname):\n        super().__init__(id, firstname, lastname)\n        self.role = \"Manager\"\n        self.employee_in_charge = []\n\n    def add_employee_in_charge(self, employee):\n        self.employee_in_charge.append(employee)\n\nclass ProjectManager(Employee):\n    def __init__(self, id, firstname, lastname):\n        super().__init__(id, firstname, lastname)\n        self.projects = []\n\n    def add_project(self, project):\n        self.projects.append(project)\n\n\nclass Developer(Employee):\n    def __init__(self, id, firstname, lastname, language):\n        super().__init__(id, firstname, lastname)\n        self.language = language\n\n    def code(self):\n        print(f\"{self.firstname} is programming in {self.language}\")\n\n# Creando instancias de los colaboradores\n\nmanager = Manager(\"001\", \"Duban\", \"Quiroga\")\nprint(manager.id, manager.firstname, manager.lastname, manager.role)\np_man = ProjectManager(\"002\", \"Toji\", \"Fushiguro\")\np_man.add_project(\"Project1\")\nprint(p_man.id, p_man.firstname, p_man.lastname)\nprint(p_man.projects)\ndeveloper1= Developer(\"003\", \"Gojo\", \"Satoru\", \"Python\")\ndeveloper2 = Developer(\"004\", \"Suguru\", \"Geto\", \"Java\")\n\nfor obj in (p_man, developer1, developer2):\n    manager.add_employee_in_charge(obj)\n\nfor empl in manager.employee_in_charge:\n    print(f\"Employee in charge: {empl.firstname} {empl.lastname}, ID: {empl.id}\")"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/JuanDAW37.py",
    "content": "\"\"\"\n* EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n\"\"\"\n\n# Superclase\nclass Animal:\n    def __init__(self, nombre:str):\n        self.nombre = nombre        \n    \n    def sonido(self):\n        pass\n\n#Subclase Perro, lo que se incluye entre los paréntesis es el nombre de la superclase\nclass Perro(Animal): \n    \n    def sonido(self):\n        return \"Guauuu!!\"\n\n#Subclase Gato, lo que se incluye entre los paréntesis es el nombre de la superclase        \nclass Gato(Animal):\n    \n    def sonido(self):\n        return \"Miauuuu!!\"\n\n# Instancia de subclase tipo Perro, hereda de Animal la propiedad nombre y sobreescribe el método sonido\nperro = Perro(\"Fido\")\nprint(f'Una de mis mascotas se llama {perro.nombre} y su sonido es {perro.sonido()}')\n\n# Instancia de subclase tipo Gato, hereda de Animal la propiedad nombre y sobreescribe el método sonido\ngato = Gato(\"Micifú\")\nprint(f'Una de mis mascotas se llama {gato.nombre} y su sonido es {gato.sonido()}')\n\n# Polimorfismo en tiempo de ejecución, recibe un objeto de tipo Animal (superclase), y dependiendo de la instancia de superclase o subclase que reciba, imprimirá una u otra cosa\ndef sonidoAnimal(animal:Animal):\n    print(f'El animal {animal.nombre} hace {animal.sonido()}')\n\nsonidoAnimal(perro) # Imprime la info de perro\nsonidoAnimal(gato) # Imprime la info de gato\n\n# EXTRA\n\nclass Empleado:\n    def __init__(self, identificador, nombre):\n        self.identificador = identificador\n        self.nombre = nombre\n        self.empleados = []\n        self.proyectos = []\n        self.lenguajes = []\n        \n    def addEmpleado(self, empleado):\n        self.empleados.append(empleado)\n        \n    def addProyecto(self, proyecto):\n        self.proyectos.append(proyecto)\n        \n    def addLenguaje(self, lenguajes):\n        self.lenguajes.append(lenguajes)\n        \nclass Gerente(Empleado):\n    def __init__(self, identificador, nombre):\n        super().__init__(identificador, nombre)\n        \n    def coordinar(self):\n        return f'El gerente {self.nombre} coordina a {len(self.empleados)} empleados {self.empleados}'\n\n    def addProyecto(self, empleado):\n        print(\"Un gerente no gestiona proyectos\")\n    \n    def addLenguaje(self, lenguajes):\n        print(\"Un gerente no desarrolla\")\n\n\nclass GerenteProyecto(Empleado):\n    def __init__(self, identificador:int, nombre:str):\n        super().__init__(identificador, nombre)        \n    \n    def gestionar(self):\n        return f'El gerente de proyecto {self.nombre} gestiona {len(self.proyectos)} proyecto/s {self.proyectos}'\n    \n    def addEmpleado(self, empleado):\n        print(\"Un gerente de proyectos no puede tener empleados\")\n        \n    def addLenguaje(self, lenguajes):\n        print(\"Un gerente de proyectos no desarrolla\")\n\nclass Programador(Empleado):\n    def __init__(self, identificador, nombre):\n        super().__init__(identificador, nombre)        \n        \n    def  programar(self):\n        return f'El programador {self.nombre} programa en {len(self.lenguajes)} lenguaje/s {self.lenguajes}'\n    \n    def addProyecto(self, empleado):\n        print(\"Un programador no gestiona proyectos\")\n    \n    def addEmpleado(self, empleado):\n        print(\"Un programador no puede tener empleados\")\n\n# PRUEBAS\ngerente = Gerente(1, 'Pepe')\ngerente.addEmpleado('Luis')\ngerente.addEmpleado('Antonio')\nprint(gerente.coordinar())\n\ngerenteProyecto = GerenteProyecto(2, 'Luis')\ngerenteProyecto.addProyecto('Proyecto 1')\ngerenteProyecto.addProyecto('Proyecto 2')\nprint(gerenteProyecto.gestionar())\n\nprogramador = Programador(3, 'Antonio')\nprogramador.addLenguaje('Java')\nprogramador.addLenguaje('JavaScript')\nprogramador.addLenguaje('Python')\nprogramador.addLenguaje('PHP')\nprint(programador.programar())\n\n# Un gerente puede tener un objeto de tipo empleado\ngerente.addEmpleado(programador)\nprint(gerente.coordinar())\n\n# Control de añadido de funciones según su categoría\n\n# Un gerente no desarrolla\ngerente.addLenguaje('Cobol')\n# Un gerente no gestiona proyectos\ngerente.addProyecto('Proyecto 3')\n\n# Un Gerente de Proyectos no gestiona personal\ngerenteProyecto.addEmpleado('Juan')\ngerenteProyecto.addEmpleado(programador)\n# Un Gerente de Proyectos no desarrolla\ngerenteProyecto.addLenguaje('Ruby')\n\n# Un programador no gestiona proyectos\nprogramador.addProyecto('Proyecto 4')\n# Un programador no puede tener empleados\nprogramador.addEmpleado('José')\nprogramador.addEmpleado(programador)"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/LittleMabbit.py",
    "content": "class Animal:\n    def __init__(self, especie, raza, color):\n        self.especie = especie\n        self.raza = raza\n        self.color = color\n    \n    \n    def sound(self, sonido: str):\n        return print(f'El {self.especie} hace {sonido}')\n        \n    def print(self):\n        print(f'Especie: {self.especie}, es de raza {self.raza}, y su color es {self.color}.')\n\nclass Gato(Animal):\n    pass\n\nclass Perro(Animal):\n    pass\n        \nmy_dog = Perro('Canino', 'Pitbull', 'Blanco')\nmy_dog.print()\n\nmy_cat = Gato('Felino', 'Persa', 'Amarillo')\nmy_cat.print()\n\nmy_cat.sound('Miau')\nmy_dog.sound('Guau')\n\n'''\nEjercicio\n'''\n\nclass Employees():\n    def __init__(self, identifier: int, name: str):\n        self.identifier = identifier\n        self.name = name\n        self.employees = []\n    \n    def add(self, employee):\n        self.employees.append(employee)\n\n    def print_employees(self):\n        for employee in self.employees:\n            print(employee.name)\n\nclass Manager(Employees):\n    def projects_coordination(self):\n        print(f'{self.name} is the manager, they coordinate all of the company projects.')\n        \nclass ProjectManager(Employees):\n    def __init__(self, identifier:int, name: str, project: str):\n        super().__init__(identifier, name)\n        self.project = project\n    \n    def print_projects(self):\n        print(f'{self.project} is one of the projects that {self.name} works on.')\n\nclass Programmer(Employees):\n    def __init__(self, identifier: int, name: str, languages: list, expertise: int):\n        super().__init__(identifier, name)\n        self.languages = languages\n        self.expertise = expertise        \n        \n    def print_programmer(self):\n        print(f\"The programmer {self.name} is one of the organizations programmers (ID:{self.identifier}). He manages {self.languages} properly and has {self.expertise} level of expertise in a 0 - 5 scale.\")\n    \n    def add(self, employee: Employees):\n        print(f\"Un programador no tiene empleados a su cargo. {employee.name} no se añadirá.\")\n    \nmanager1 = Manager(1, 'César Morán')\nproject_manager1 = ProjectManager(2,'Jesus Moran', 'Perfumery Web Page')\nproject_manager2 = ProjectManager(3,'Ruby Rose', 'Perfumery Web Page')\nprogrammer1 = Programmer(4, 'Jose Moran', ['Ruby', 'Java', 'Python'], 3)\nprogrammer2 = Programmer(5, 'Pucho Almendras', ['JavaScript', 'Python'], 4)\nprogrammer3 = Programmer(6, 'Pelango Navaz', ['Python'], 5)\nmanager1.projects_coordination()\nproject_manager1.print_projects()\nprogrammer1.print_programmer()\n\nmanager1.add(project_manager1)\nmanager1.add(project_manager2)\n\nproject_manager1.print_projects()\nproject_manager2.print_projects()\n\nprogrammer3.add(programmer3)\n\nprogrammer3.print_programmer()"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/LucasRebuffo.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */ \"\"\"\n\n\"\"\" Ejemplo de herencia \"\"\"\n\n\nclass Animal:\n    def __init__(self, nombre) -> None:\n        self.nombre = nombre\n\n    def sonido(self):\n        print(\"Un sonido desconocido ...\")\n\n\nclass Perro(Animal):\n\n    def sonido(self):\n        print(\"Guau! Guau! ...\")\n\n\nclass Gato(Animal):\n\n    def sonido(self):\n        print(\"Miau! Miauuu! ...\")\n\n\n\"\"\" Polimorfismo  \"\"\"\n\nanimal_generico = Animal(\"????\")\nperro = Perro(\"Toby\")\ngato = Gato(\"Dorito\")\n\n\ndef sonido_animal(animal: Animal):\n    animal.sonido()\n\n\n# sonido_animal(animal_generico)\n# sonido_animal(perro)\n# sonido_animal(gato)\n\n\"\"\" * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */ \"\"\"\n\n\nclass Empleado:\n\n    def __init__(self, name: str, id: int) -> None:\n        self.id = id\n        self.name = name\n        self.empleados_a_cargo: list[Empleado] = []\n\n    def agregar(self, empleado):\n        self.empleados_a_cargo.append(empleado)\n\n    def empleados(self):\n        for e in self.empleados_a_cargo:\n            print(f\"{self.name} esta a cargo de {e.name}\")\n\n\nclass Gerente(Empleado):\n\n    def coordinar_projectos(self):\n        print(f\"{self.name} esta coordinando projectos de generales de empresa ...\")\n\n\nclass Programador(Empleado):\n\n    def __init__(self, name: str, id: int, lenguaje: str) -> None:\n        super().__init__(name, id)\n        self.lenguaje = lenguaje\n\n    def codear(self):\n        print(f\"{self.name} esta codeando en {self.lenguaje}\")\n\n    def agregar(self, empleado: Empleado):\n        print(f\"No se puede agregar {empleado.name} a cargo de {self.name} ...\")\n\n\nclass GereteProyecto(Empleado):\n\n    def __init__(self, name: str, id: int, proyecto: str) -> None:\n        super().__init__(name, id)\n        self.proyecto = proyecto\n\n    def coordinar_projectos(self):\n        print(f\"{self.name} esta coordinando el proyecto {self.proyecto} ...\")\n\n\ngerente = Gerente(\"Manuel\", 1)\ngerente_proyecto1 = GereteProyecto(\"Jose\", 2, \"Proyecto1\")\ngerente_proyecto2 = GereteProyecto(\"Maria\", 3, \"Proyecto2\")\nprogramador1 = Programador(\"Lucas\", 4, \"Python\")\nprogramador2 = Programador(\"David\", 5, \"Kobol\")\nprogramador3 = Programador(\"Sofia\", 6, \"Dart\")\nprogramador4 = Programador(\"Rosa\", 7, \"Java\")\nprogramador5 = Programador(\"Pedro\", 8, \"Ruby\")\n\ngerente.agregar(gerente_proyecto1)\ngerente.agregar(gerente_proyecto2)\ngerente_proyecto1.agregar(programador1)\ngerente_proyecto1.agregar(programador2)\ngerente_proyecto1.agregar(programador3)\ngerente_proyecto2.agregar(programador4)\ngerente_proyecto2.agregar(programador5)\n\nprogramador1.agregar(programador2)\n\ngerente.empleados()\ngerente_proyecto1.empleados()\ngerente_proyecto2.empleados()\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/Lumanet.py",
    "content": "class Animal:\n    def __init__(self, name):\n        self.name = name\n\n    def sound(self):\n        pass # Método abstracto que será implementado por las subclases\n\nclass Perro(Animal):\n    def sound(self): # Polimorfismo (sobrescritura de método)\n        print(f\"{self.name} hace ¡Guau!\")\n    \nclass Gato(Animal):\n    def sound(self):\n        print(f\"{self.name} hace ¡Miauuuu!\")\n        \ndef suena(animal):\n    animal.sound()\n\nperro = Perro(\"Tom\")\nperro.sound() # Tom hace ¡Guau!\ngato = Gato(\"Rusby\")\ngato.sound() # Rusby hace ¡Miauuuu!\n\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\nImplementa la jerarquía de una empresa de desarrollo formada por Empleados que\npueden ser Gerentes, Gerentes de Proyectos o Programadores.\nCada empleado tiene un identificador y un nombre.\nDependiendo de su labor, tienen propiedades y funciones exclusivas de su\nactividad, y almacenan los empleados a su cargo.\n\"\"\"\nclass Empleado:\n    def __init__(self, id, nombre):\n        self.id = id\n        self.nombre = nombre\n        self.empleados = []\n\n    def add(self, empleado):\n        self.empleados.append(empleado)\n\n    def listar_empleados(self):\n        print(f\"Empleados a cargo de {self.nombre}:\")\n        for empleado in self.empleados:\n            print(empleado.nombre)\n\n    def __str__(self):\n        return f\"{self.__class__.__name__}: {self.nombre} - ID: {self.id}\"\n\nclass Gerente(Empleado):\n    def __init__(self, id, nombre):\n        super().__init__(id, nombre) # Llamada al constructor de la clase padre\n\n    def coordinar_proyectos(self):\n        print(f\"{self.nombre} está coordinando todos los proyectos de la empresa.\")\n\nclass GerenteProyecto(Empleado):\n    def __init__(self, id, nombre):\n        super().__init__(id, nombre)\n\n    def asignar_tareas(self):\n        print(f\"{self.nombre} está asignando tareas a los programadores.\")\n        \nclass Programador(Empleado):\n    def __init__(self, id, nombre, lenguaje):\n        super().__init__(id, nombre)\n        self.lenguaje = lenguaje\n\n    def programar(self):\n        print(f\"{self.nombre} está programando en {self.lenguaje}.\")\n        \n    def add(self, empleado):\n        print(f\"Un programador ({self.nombre}) no tiene empleados a su cargo. {empleado.nombre} no se añadirá.\")\n    \n    def listar_empleados(self):\n        print(f\"El programador {self.nombre} no tiene empleados a su cargo.\")\n        \ngerente = Gerente(1, \"Marcos\")\ngerente_proyecto = GerenteProyecto(2, \"Susi\")\ngerente_proyecto2 = GerenteProyecto(3, \"Laura\")\nprogramador = Programador(4, \"Juan\", \"Python\")\nprogramador2 = Programador(5, \"Pedro\", \"Java\")\nprogramador3 = Programador(6, \"Luis\", \"Javascript\")\n\nprint(gerente)\ngerente.add(gerente_proyecto)\ngerente.add(gerente_proyecto2)\ngerente.listar_empleados()\ngerente.coordinar_proyectos()\ngerente_proyecto.add(programador)\ngerente_proyecto.add(programador2)\ngerente_proyecto2.add(programador3)\ngerente_proyecto.listar_empleados()\ngerente_proyecto.asignar_tareas()\ngerente_proyecto2.listar_empleados()\ngerente_proyecto2.asignar_tareas()\nprogramador.add(gerente)\nprogramador.listar_empleados()\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/Maanghel.py",
    "content": "\"\"\"\nEJERCICIO:\nExplora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n    implemente una superclase Animal y un par de subclases Perro y Gato,\n    junto con una función que sirva para imprimir el sonido que emite cada Animal.\n\nDIFICULTAD EXTRA (opcional):\nImplementa la jerarquía de una empresa de desarrollo formada por Empleados que\n    pueden ser Gerentes, Gerentes de Proyectos o Programadores.\nCada empleado tiene un identificador y un nombre.\n    Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n    actividad, y almacenan los empleados a su cargo.\n\"\"\"\n\n# Superclass Animal\nclass Animal:\n    \"\"\"\n    A base class representing an animal.\n    \n    Attributes:\n        name (str): The name of the animal.\n    \"\"\"\n    def __init__(self, name: str):\n        \"\"\"\n        Initializes the animal with a given name.\n        \n        Args:\n            name (str): The name of the animal.\n        \"\"\"\n        self.name = name\n\n    def make_sound(self):\n        \"\"\"\n        Prints a generic message indicating the animal is making a sound.\n        \"\"\"\n        print(f\"{self.name} is making a sound\")\n\n# Subclasses\nclass Dog(Animal):\n    \"\"\"\n    A class representing a dog, which is a type of animal.\n    \n    Inherits from the Animal class and overrides the make_sound method.\n    \"\"\"\n    def make_sound(self):\n        \"\"\"\n        Prints the sound made by a dog: \"guau guau\".\n        \"\"\"\n        print(\"guau guau\")\n\n\nclass Cat(Animal):\n    \"\"\"\n    A class representing a cat, which is a type of animal.\n    \n    Inherits from the Animal class and overrides the make_sound method.\n    \"\"\"\n    def make_sound(self):\n        \"\"\"\n        Prints the sound made by a cat: \"miau miau\".\n        \"\"\"\n        print(\"miau miau\")\n\n# Instantiate objects\nmy_animal = Animal(\"animal\")\nmy_dog = Dog(\"Perro\")\nmy_cat = Cat(\"gato\")\n\nmy_dog.make_sound()\nmy_cat.make_sound()\nmy_animal.make_sound()\n\n# EXTRA\n\nclass Employee:\n    \"\"\"\n    A class representing an employee in a company.\n    \n    Attributes:\n        id (int): The employee's ID.\n        name (str): The employee's name.\n        employees (list): A list of employees that report to this employee.\n    \"\"\"\n    def __init__(self, id: int, name: str):\n        \"\"\"\n        Initializes the employee with an ID and name.\n        \n        Args:\n            id (int): The employee's ID.\n            name (str): The employee's name.\n        \"\"\"\n        self.id = id\n        self.name = name\n        self.employees = []\n\n    def add_employee(self, employee) -> None:\n        \"\"\"\n        Adds an employee to the list of employees under this employee.\n        \n        Args:\n            employee (Employee): The employee to be added.\n        \"\"\"\n        self.employees.append(employee)\n\n    def print_employees(self) -> None:\n        \"\"\"\n        Prints the list of employees under this employee's supervision.\n        \"\"\"\n        print(f\"\\n{self.name} is managing:\")\n        for id, employee in enumerate(self.employees, 1):\n            print(f\"{id}.- {employee.name}\")\n\n\nclass Manager(Employee):\n    \"\"\"\n    A class representing a manager, a type of employee.\n    \n    Inherits from Employee and has the ability to coordinate projects.\n    \"\"\"\n    def coordinate_projects(self) -> None:\n        \"\"\"\n        Prints a message indicating the manager is coordinating the company.\n        \"\"\"\n        print(f\"\\n{self.name} is coordinating the entire company.\")\n\n\nclass ProjectManager(Employee):\n    \"\"\"\n    A class representing a project manager, a type of employee.\n    \n    Inherits from Employee and coordinates a specific project.\n    \n    Attributes:\n        project (str): The project that the project manager is overseeing.\n    \"\"\"\n    def __init__(self, id, name, project: str):\n        \"\"\"\n        Initializes the project manager with an ID, name, and project.\n        \n        Args:\n            id (int): The project manager's ID.\n            name (str): The project manager's name.\n            project (str): The name of the project they are coordinating.\n        \"\"\"\n        super().__init__(id, name)\n        self.project = project\n\n    def coordinate_project(self) -> None:\n        \"\"\"\n        Prints a message indicating the project manager is coordinating a specific project.\n        \"\"\"\n        print(f\"\\n{self.name} is coordinating the project '{self.project}'\")\n\n\nclass Programmer(Employee):\n    \"\"\"\n    A class representing a programmer, a type of employee.\n    \n    Inherits from Employee and has the ability to program in a specific language.\n    \n    Attributes:\n        language (str): The programming language the programmer uses.\n    \"\"\"\n    def __init__(self, id, name, language: str):\n        \"\"\"\n        Initializes the programmer with an ID, name, and programming language.\n        \n        Args:\n            id (int): The programmer's ID.\n            name (str): The programmer's name.\n            language (str): The programming language the programmer uses.\n        \"\"\"\n        super().__init__(id, name)\n        self.language = language\n\n    def code(self) -> None:\n        \"\"\"\n        Prints a message indicating the programmer is coding in a specific language.\n        \"\"\"\n        print(f\"\\n{self.name} is coding in {self.language}\")\n\n    def add_employee(self, employee) -> None:\n        \"\"\"\n        Prints a message indicating that programmers cannot have employees under their supervision.\n        \n        Args:\n            employee (Employee): The employee to be added (will not be added for programmers).\n        \"\"\"\n        print(f\"\\n{self.name} cannot have employees under their supervision.\")\n\n# Example usage\nmy_manager = Manager(1, \"Manuel\")\nmy_project_manajer = ProjectManager(2, \"Angel\", \"Web Page\")\nmy_project_manajer2 = ProjectManager(3, \"Jose\", \"Desktop App\")\nmy_programmer = Programmer(4, \"Ana\", \"Python\")\nmy_programmer2 = Programmer(5, \"Juan\", \"Python\")\nmy_programmer3 = Programmer(6, \"Maria\", \"JavaScript\")\nmy_programmer4 = Programmer(7, \"Fer\", \"JavaScript\")\n\nmy_manager.add_employee(my_project_manajer)\nmy_manager.add_employee(my_project_manajer2)\nmy_project_manajer.add_employee(my_programmer3)\nmy_project_manajer.add_employee(my_programmer4)\nmy_project_manajer2.add_employee(my_programmer)\nmy_project_manajer2.add_employee(my_programmer2)\n\nmy_manager.coordinate_projects()\nmy_manager.print_employees()\n\nmy_project_manajer.coordinate_project()\nmy_project_manajer.print_employees()\n\nmy_project_manajer2.coordinate_project()\nmy_project_manajer2.print_employees()\n\nmy_programmer.add_employee(my_programmer2)\nmy_programmer.code()\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/MarcosE-FerretoE.py",
    "content": "\"\"\"\nEjercicio\n\"\"\"\n\n\n# Superclase\nclass Animal:\n    def __init__(self, name: str):\n        self.name = name\n\n    def sound(self):\n        pass\n\n\n# Subclases\nclass Dog(Animal):\n    def sound(self):\n        print(\"Guau\")\n\n\nclass Cat(Animal):\n    def sound(self):\n        print(\"Miau\")\n\n\ndef print_sound(animal: Animal):\n    animal.sound()\n\n\nmy_animal = Animal(\"Animal\")\nprint_sound(my_animal)\nmy_dog = Dog(\"Perro\")\nprint_sound(my_dog)\nmy_cat = Cat(\"Gato\")\nprint_sound(my_cat)\n\n\"\"\"\nExtra\n\"\"\"\n\n\nclass Employee:\n    def __init__(self, id: int, name: str):\n        self.id = id\n        self.name = name\n        self.employees = []\n\n    def add_employee(self, employee):\n        self.employees.append(employee)\n\n    def print_employees(self):\n        for employee in self.employees:\n            print(employee.name)\n\n\nclass Manager(Employee):\n\n    def equipment_supervision(self):\n        print(f\"{self.name} supervises and manages teams and resources\")\n\n\nclass ProjectManager(Employee):\n\n    def __init__(self, id: int, name: str, project: str):\n        super().__init__(id, name)\n        self.project = project\n\n    def control_projects(self):\n        print(f\"{self.name} plans, executes and controls projects with {self.project}\")\n\n\nclass Programmer(Employee):\n    def __init__(self, id: int, name: str, language: str):\n        super().__init__(id, name)\n        self.language = language\n\n    def code(self):\n        print(f\"{self.name} está programando en {self.language}\")\n\n    def add_employee(self, employee: Employee):\n        print(f\"{employee.name} no tiene cargos\")\n\n\nmy_manager = Manager(\n    1,\n    \"Marcos\",\n)\nmy_project_manager = ProjectManager(\n    2,\n    \"Pedro\",\n    \"Proyecto 1\",\n)\nmy_project_manager2 = ProjectManager(\n    3,\n    \"Pepe\",\n    \"Proyecto 2\",\n)\n\nmy_programmer = Programmer(4, \"Raul\", \"Python\")\nmy_programmer2 = Programmer(5, \"Bruno\", \"Java\")\nmy_programmer3 = Programmer(6, \"Ana\", \"Python\")\n\n\nmy_manager.add_employee(my_project_manager)\nmy_manager.add_employee(my_project_manager2)\n\nmy_project_manager.add_employee(my_programmer)\n\nmy_programmer2.code()\n\nmy_manager.print_employees()\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/MirandaYuber.py",
    "content": "print(\"\"\"\nHERENCIA Y POLIMORFISMO\n\"\"\")\n\n\nclass Animal:\n    def __init__(self, name, age):\n        self.name = name\n        self.age = age\n\n    @staticmethod\n    def make_sound(self):\n        print('Esta animal hace algun sonido')\n\n\nclass Dog(Animal):\n    def __init__(self, name, age, race):\n        super().__init__(name, age)\n        self.race = race\n\n    def make_sound(self):\n        print('El perro hace guau guau')\n\n\ndog = Dog(name='Lucas', age=5, race='Labrador')\nprint(f'El nombre del perro es: {dog.name}')\nprint(f'El edad del perro es: {dog.age}')\nprint(f'El raza del perro es: {dog.race}')\nprint(dog.make_sound())\nprint()\n\n\nclass Cat(Animal):\n    def __init__(self, name, age, race):\n        super().__init__(name, age)\n        self.race = race\n\n    def make_sound(self):\n        print('El gato hace miau miau')\n\n\ncat = Cat(name='Miel', age=2, race=None)\nprint(f'El nombre del gato es: {cat.name}')\nprint(f'El edad del gato es: {cat.age}')\nprint(f'El raza del gato es: {cat.race}')\nprint(cat.make_sound())\nprint()\n\nprint(\"\"\"\nEXTRA\n\"\"\")\n\n\nclass Employee:\n    def __init__(self, identification: int, name: str):\n        self.identification = identification\n        self.name = name\n        self.employees = []\n\n    def add(self, employee):\n        self.employees.append(employee)\n\n    def print_employees(self):\n        for employee in self.employees:\n            print(employee.name)\n\n\nclass Manager(Employee):\n    def coordinate_projects(self):\n        print(f'{self.name} esta coordinando todos los proyectos de la empresa')\n\n\nclass ProjectManager(Employee):\n    def __init__(self, identification: id, name: str, project: str):\n        super().__init__(identification, name)\n        self.project = project\n\n    def coordinate_project(self):\n        print(f'{self.name} esta coordinando su proyecto')\n\n\nclass Programmer(Employee):\n    def __init__(self, identification: int, name: str, language: str):\n        super().__init__(identification, name)\n        self.language = language\n\n    def code(self):\n        print(f'{self.name} esta programando en {self.language}')\n\n    def add(self, employee):\n        print('Un progrmamador no puede tener empleados a cargo.')\n\n\nmy_manager = Manager(1, 'Yuber')\nmy_project_manager = ProjectManager(2, 'Esteban', 'Proyecto 1')\nmy_project_manager2 = ProjectManager(3, 'Esteban2', 'Proyecto 2')\nmy_programmer = Programmer(4, 'Julio', language='PHP')\nmy_programmer2 = Programmer(5, 'Omar', language='Python')\nmy_programmer3 = Programmer(6, 'Mateo', language='NodeJS')\nmy_programmer4 = Programmer(7, 'Pedro', language='JS')\n\nmy_manager.add(my_project_manager)\nmy_manager.add(my_project_manager2)\n\nmy_project_manager.add(my_programmer)\nmy_project_manager.add(my_programmer2)\nmy_project_manager2.add(my_programmer3)\nmy_project_manager2.add(my_programmer4)\n\nmy_programmer.add(my_programmer2)\nmy_project_manager.coordinate_project()\nmy_manager.coordinate_projects()\nmy_manager.print_employees()\nmy_project_manager.print_employees()\nmy_programmer.print_employees()\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/NeosV.py",
    "content": "class Animal:\n\n    def __init__(self,name):\n        self.name = name  \n\n    def sound(self):\n        pass   \n\n\n\nclass Perro(Animal):\n\n    def sound(self):\n\n        print(\"Guau\")       \n\nclass Gato(Animal):\n\n    def sound(self):\n\n        print(\"Miau\")   \n\n\nmy_animal = Animal(\"Animal\")\nmy_animal.sound()              \nmy_perro = Perro(\"Perro\")\nmy_perro.sound()\nmy_gato = Gato(\"Gato\")\nmy_gato.sound()\n\n\n\n\nclass Empresa:\n\n    def __init__(self, id:int, name:str):\n\n        self.id = id\n        self.name = name\n        self.empleados = []\n\n\n    def emplear(self, empleados):\n        self.empleados.append(empleados)\n        \n\nclass Gerente(Empresa):\n\n    def coordinar_proyectos(self):\n        print(f\"{self.name} esta coordinando los proyectos de la empresa\")\n\n\nclass Gerente_Proyecto(Empresa):\n    \n    def __init__(self, id: int, name: str, proyecto:str):\n        super().__init__(id, name)\n        self.proyecto = proyecto\n\n    def coordinar_proyecto(self):\n        print(f\"{self.name} esta coordinando su proyecto {self.proyecto}\")\n\n    def proyecto_ger(self):\n        print(f\"{self.name} esta coordinando el {self.proyecto}\")   \n\n\nclass Programador(Empresa):\n\n    def __init__(self, id: int, name: str, lenguaje:str):\n        super().__init__(id, name)\n        self.lenguaje = lenguaje\n\n    def programar(self):\n        print(f\"{self.name} esta programando en {self.lenguaje}\")\n\n    def emplear(self, empleados):\n        print(f\"un programdor no tiene empleados a su cargo\")   \n\n\nmy_gerente= Gerente(1, \"Andres\")\nmy_gerente_proyecto1= Gerente_Proyecto(2, \"Jose\", \"Carrosdev\" ) \nmy_gerente_proyecto2= Gerente_Proyecto(3, \"Carlos\", \"Motosdev\")\nmy_programador= Programador(4, \"Maykol\" , \"Python\") \nmy_programador2= Programador(5, \"Abraham\" , \"Go\") \n \nmy_gerente.emplear(my_gerente_proyecto1)\nmy_gerente.emplear(my_gerente_proyecto2)\n\nmy_gerente_proyecto1.emplear(my_programador)\nmy_gerente_proyecto2.emplear(my_programador2)\n\nmy_programador.emplear(my_programador2)\nmy_programador.programar()\n\nmy_gerente_proyecto1.coordinar_proyecto()\n\nmy_gerente.coordinar_proyectos()\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/NicoHeguaburu.py",
    "content": "# Herencia\n\n\nclass Animal:\n\n    def __init__(self, name: str):\n        self.name = name\n        \n    def sound(self):\n        pass\n    \n\n\nclass Dog(Animal):\n\n    def sound(self):\n        print(\"Guau!\")\n\nclass Cat(Animal):\n\n    def sound(self):\n        print(\"Miau!\")\n\n\ndef print_sound(animal: Animal):\n    animal.sound()\n\n\nmy_animal = Animal(\"Animal\")\nmy_animal.sound()\n\nmy_dog = Dog(\"Dog\")\nmy_dog.sound()\n\nmy_cat = Cat(\"Cat\")\nmy_cat.sound()\n\n\nprint_sound(my_cat)\n\n\n\n\n#Dificultad Extra\nplanilla = []\n\nclass Empleado:\n    def __init__(self, nombre: str):\n        self.nombre = nombre\n        self.id = len(planilla) + 1\n        self.puesto = self.definir_puesto()\n        perfil_empleado = {}\n        perfil_empleado[\"Nombre\"] = nombre\n        perfil_empleado[\"ID\"] = self.id\n        perfil_empleado[\"Puesto\"] = self.puesto\n        planilla.append(perfil_empleado)\n    \nclass Gerente(Empleado):\n    def definir_puesto(self):\n        return \"Gerente\"\n    \n    def desarolladores_a_cargo(self):\n        desarolladores = []\n        for i in planilla:\n            if i[\"Puesto\"] == \"Desarollador\":\n                desarolladores.append(i[\"Nombre\"])\n        print(desarolladores)\n        \n        \n    def pms_a_cargo(self):\n        pms = []\n        for i in planilla:\n            if i[\"Puesto\"] == \"PM\":\n                pms.append(i[\"Nombre\"])\n        print(pms)\n        \n\n    \nclass Pm(Empleado):\n    def definir_puesto(self):\n        return \"PM\"\n    \n    def desarolladores_a_cargo(self):\n        desarolladores = []\n        for i in planilla:\n            if i[\"Puesto\"] == \"Desarollador\":\n                desarolladores.append(i[\"Nombre\"])\n        print(desarolladores)\n\n\nclass Desarollador(Empleado):\n    def definir_puesto(self):\n        return \"Desarollador\"\n\n\nempleado1 = Gerente(\"Jorge\")\nempleado2 = Pm(\"Nicolás\")\nempleado3 = Desarollador(\"Sofia\")\nempleado4 = Gerente(\"Matias\")\nempleado5 = Pm(\"Lorenzo\")\nempleado6 = Desarollador(\"Julio\")\nempleado7 = Gerente(\"Marcos\")\nempleado8 = Pm(\"Maria\")\nempleado9 = Desarollador(\"Sebastian\")\n\n\n\n\n\nprint(planilla)\n\nempleado1.desarolladores_a_cargo()\nempleado1.pms_a_cargo()\nempleado2.desarolladores_a_cargo()"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/Nicojsuarez2.py",
    "content": "# #09 HERENCIA Y POLIMORFISMO\n> #### Dificultad: Media | Publicación: 26/02/24 | Corrección: 04/03/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/NightAlchemist.py",
    "content": "'''\nExercise\n'''\n\nclass Animal():\n    def __init__(self, race):\n        self.race = race\n\n\nclass Dog(Animal):\n    def __init__(self, race = \"Dog\", sound = \"Woof\"):\n        super().__init__(race)\n        self.sound = sound\n\n    def __str__(self):\n        return (f\"I am a {self.race} and I say {self.sound}\")\n\nclass Cat(Animal):\n    def __init__(self, race = \"Cat\", sound = \"Meow\"):\n        super().__init__(race)\n        self.sound = sound\n\n    def __str__(self):\n        return (f\"I am a {self.race} and I say {self.sound}\")\n\nmichi = Cat()\nprint(michi)\n\ndoggy = Dog()\nprint(doggy)\n\nsphinx = Cat(\"Sphinx\")\nprint(sphinx)\n\ndoberman = Dog(\"Doberman\", \"Bark!\")\nprint(doberman)\n\n'''\nExtra\n'''\n#Main Class\n\nclass Employee():\n    def __init__(self, name: str, id: int):\n        self.name = name\n        self.id = id\n        self.employees = []\n\n    def __str__(self):\n        return f\"Name: {self.name}, ID Number: {self.id}\"\n    \n    def add(self, employee):\n        self.employees.append(employee)\n    \n    def print_employees(self):\n        for employee in self.employees:\n            print(employee.name)\n    \n    def checkin(self):\n        return True\n    \n    def checkout(self):\n        return False\n\n#CEO Class\n\nclass Ceo(Employee):\n    def __init__(self, name, id, position = \"CEO\"):\n        super().__init__(name, id)\n        self.position = position\n\n    def __str__(self):\n        return super().__str__() + f\" Position: {self.position}\"\n    \n    def coordinate_projects(self):\n        print(f\"{self.name} is coordinating all the projects in the company.\")\n\n\n#Project Manager Class\n\nclass ProjectManager(Employee):\n    def __init__(self, name, id, position = \"Project Manager\", project: str = None):\n        super().__init__(name, id)\n        self.position = position\n        self.project = project\n\n    def __str__(self):\n        return super().__str__() + f\" Position: {self.position}\"\n    \n    def coordinate_project(self):\n        if self.project == None:\n            return f\"{self.name} is not coordinating any project at the moment.\"\n        else:\n            return f\"{self.name} is coordinating the {self.project} project.\"\n\n#Programmer Class\n\nclass Programmer(Employee):\n    def __init__(self, name, id, language, position = \"Programmer\"):\n        super().__init__(name, id)\n        self.language = language\n        self.position = position\n\n    def __str__(self):\n        return super().__str__() + f\" Position: {self.position}\"\n    \n    def code(self):\n        print(f\"{self.name} is programming in {self.language}.\")\n\n    def add(self, employee: Employee):\n        print(\n            f\"A programmer doesn't have employees under them. {employee.name} won't be added.\")\n\n\n#try\n\njack = Ceo(\"Jack Donovan\", 231)\n\njill = ProjectManager(\"Jill Valentine\", 563)\n\njhoao = Programmer(\"Jhoao Fajardo\", 502, \"Python\")\nprint(jhoao)\n\njack.add(jill)\njill.add(jhoao)\njhoao.add(jill)\n\njack.coordinate_projects()\n\nprint(jill)\nprint(jill.coordinate_project())\njill.project = \"Restaurant\"\nprint(jill.coordinate_project())\n\njhoao.code()\n\nprint(jhoao.checkin())\nprint(jill.checkout())"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/Nightblockchain30.py",
    "content": "\n# /*\n#  * EJERCICIO:\n#  * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n#  * implemente una superclase Animal y un par de subclases Perro y Gato,\n#  * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n#  */\n\n# << DUCK TYPING >>\n# Si existe Herencia estariamos hablando de Polimorfismo.\n# Incluso en lenguajes que no soportan el concepto de Duck Typing, es decir que son de tipado estático,gracias al poliformismo podemos conseguir algo parecido al Duck Typing.\n\n\"\"\"\n#TIPOS POLIFORMISMO:\n# --> Subtipos\n\nEn python tenemos que tener muy en cuenta el DUCK TYPING: If is walks like a duck and it quacks like a duck then it must be a duck.\n\nEn python lo más importante importa si existe el método el tipo de dato!!\n\n\n1.Poliformismo de \"subtipos\" (tiene lugar en tiempo de EJECUCIÓN). Existen dos vertientes del mismo:\n    -Single Dispatch -> Es el más utilizado, lo que quiere decir es que mientras el programa se esta ejecutando se decide que versión del método se va a invocar basándose en el tipo de la referencia del objeto\n    -Multiple Dispatch -> Consiste en utilizar/despachar el método correcto según el ORDEN,TIPO y NÚMERO de parámetros o argumentos del método/función.\n\n    Ejemplo: Si tenemos los siguientes métodos homónimos:\n                                                A) métodoCualquiera(String a, Integer b, Boolean c),\n                                                B) métodoCualquiera(),\n                                                C) métodoCualquiera(String x, String y, String z)\n    El compilador o interprete decidirá el método correcto basándose en el ORDEN, NÚMERO y TIPO de datos.\n                                                Si tengo este método: métodoCualquiera(\"Hola\", \"Hello\", \"Ciao\") --> Invocaremos el método A\n\n    CARACTERÍSTICAS:\n        1. Poliformimso dinámico \n\n\n2.Poliformismo \"paramétrico\" = Genéricos en JAVA\n    CARACTERÍSTICAS:\n        1. Poliformimso estático y se realiza en tiempo de EJECUCIÓN\n        2. Pueden utilizar técnicas de mejoramiento del desempeño que aplica el compilador\n        3. Menos flexibilidad\n        4. El programador puede crear programas de forma más general y abstracta. Siempre y cuando se usen lenguajes de tipado estático como Java\n\n\n3.Poliformismo \"ad hoc\" (tiene lugar en tiempo de COMPILACIÓN)-> Capacidad que tiene un método o función para arrojar un resultado para diferentes tipos de datos que recibe como argumentos\n        CARACTERÍSTICAS:\n        1. Poliformimso estático y se realiza en tiempo de EJECUCIÓN\n        2. Pueden utilizar técnicas de mejoramiento del desempeño que aplica el compilador\n        3. Menos flexibilidad\n        4. El programador puede crear programas de forma más general y abstracta. Siempre y cuando se usen lenguajes de tipado estático como Java\n\n        Ejemplo: Si tengo un función de multiplicar que me devuelve un resultado independientemente de los tipos de datos que le paso como argumentos INT, FLOAT etc.\n        Tengo un función polimórfica AD HOC\n\n\"\"\"\nclass Animal():\n    def __init__(self,name: str,age: int):\n        self.name = name\n        self.age = age\n\n    def sound(self):\n        print(\"Soy un sonido genérico\")\n\n\nclass Perro(Animal):\n\n    def __init__(self, breed):\n        self.breed = breed\n\n    # Poliformismo en compilacuón\n    def sound(self):\n        print(\"GUAU!\")\n\n\nclass Gato(Animal):\n\n    def __init__(self, breed):\n        self.breed = breed\n\n    def sound(self):\n        print(\"MIAU!\")\n\n\n# Función para demostrar el poliformismo de tipo AD HOC o OVERLOAD(Sobrecarga)\ndef saludo_polimorfico(animal: Animal):\n    animal.sound()\n\n# CASOS DE USO: Poliformismo en tiempo de compilación.\nanimal = Animal(\"Ani1\",4)\nanimal.sound()\n\n\nperro = Perro(\"Bull Terrier\")\nperro.sound()\n\ngato = Gato(\"British\")\ngato.sound()\n\n\nsaludo_polimorfico(animal)\nsaludo_polimorfico(perro)\nsaludo_polimorfico(gato)\n\n\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n#  * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n#  * Cada empleado tiene un identificador y un nombre.\n#  * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n#  * actividad, y almacenan los empleados a su cargo.\n\nclass Employee():\n    # Atributo de clase que heredara cualquier clase hija\n    human = True\n\n    def __init__(self,id: int,name: str):\n        # Atributos de instancia\n        self.id = id\n        self.name = name\n        print(f\"Creando una instancia de Employee: [ID: {self.id} | NAME: {self.name}]\")\n\n\nclass Manager(Employee):\n    #Atributo de Clase\n    fav_color = \"blue\"\n\n    def __init__(self, id: int, name: str, age: int):\n        # Heredamos del constructor de la super clase ID y NAME\n        super().__init__(id, name)\n        # Añadimos un atributo específico de los Manager\n        self.age = age\n\n\n    def coordinate1(self):\n        return f\"{self.name} tiene {self.age} y está coordinando un proyecto.\"\n\n\nclass ProjectManager(Employee):\n    #Atributo de Clase\n    fav_color = \"red\"\n\n    def __init__(self, id: int, name: str, username: str):\n        # Heredamos del constructor de la super clase ID y NAME\n        super().__init__(id, name)\n        # Añadimos un atributo específico de los Manager\n        self.username = username\n\n\n    def coordinate2(self):\n        return f\"El color favorito de {self.name} {self.username} es el {ProjectManager.fav_color.upper()} y está coordinando varios proyectos.\"\n\n\nclass Programmer(Employee):\n    #Atributo de Clase\n    fav_color = \"green\"\n\n    def __init__(self, id: int, name: str, language: str):\n        # Heredamos del constructor de la super clase ID y NAME\n        super().__init__(id, name)\n        # Añadimos un atributo específico de los Manager\n        self.language = language\n\n\n    def code(self):\n        return f\"El color favorito de {self.name} es el {Programmer.fav_color.upper()} y le encanta picar código {self.language}.\"\n\n\n#CASOS DE USO\nempleado1 = Employee(1234,\"Roberto\")\n#print(Employee.human) # CURIOSIDAD -> Puedo imprimir por pantalla cualquier atributo de clase sin necesidad de crear una instancia/objeto de la clase\n\nmanager1 = Manager(6789,\"Berta\",32)\nprint(manager1.coordinate1())\n#print(Manager.human) # CURIOSIDAD -> Como es hija de Employee hereda su atributo de clase\n#print(Manager.fav_color) # Y tiene un atributo de clase extra\n\nprojectManager1 = ProjectManager(5333,\"Juan\",\"López\")\nprint(projectManager1.coordinate2())\n\nprogrammer1 = Programmer(222,\"Night\",\"Python\")\nprint(programmer1.code())"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/Paprikaistkrieg.py",
    "content": "#HERENCIA y POLIMORFISMO\n\n\"\"\"\nLa herencia es un concepto fundamental en la programación orientada a objetos (OOP) que\npermite a una clase (llamada clase hija o subclase) heredar atributos y métodos de otra clase (llamada clase padre o superclase).\nEsto promueve la reutilización del código y facilita la creación de jerarquías de clases.\n\nEl polimorfismo, por otro lado, es la capacidad de diferentes clases para ser tratadas como instancias de una clase común.\nEsto significa que una función o método puede operar en objetos de diferentes clases,\nsiempre que esas clases implementen los mismos métodos o interfaces.\nEl polimorfismo permite que el mismo código funcione con diferentes tipos de objetos,\nlo que mejora la flexibilidad y la extensibilidad del software.\n\nAquí tienes un ejemplo básico de herencia y polimorfismo en Python:\n\"\"\"\nclass Animal:  # Clase padre o superclase\n    def __init__(self, name :str):\n        self.name = name\n\n    def hacer_sonido(self):  # Método que será sobrescrito por las subclases\n        raise NotImplementedError(\"Subclase debe implementar este método\")\n        # Esta excepción indica que las subclases deben proporcionar su propia implementación\n        # si intentan llamar a este método directamente desde la clase padre.\n        # Esto es útil para definir una interfaz común que todas las subclases deben seguir.\n        # Si no se implementa en la subclase, se lanzará esta excepción.\n        # Esto es una forma de asegurar que las subclases implementen este método.\n        # También se puede usar la palabra clave 'pass' si no se desea lanzar una excepción.\n        # pass  # Si no se desea lanzar una excepción, se puede usar 'pass' para indicar que el método no hace nada.\n        # Sin embargo, lanzar NotImplementedError es una práctica común para indicar que el método debe ser implementado por las subclases.\n        # Esto es especialmente útil en clases base o abstractas donde se espera que las subclases proporcionen una implementación específica.\n            # raise NotImplementedError(\"Subclase debe implementar este método\")\n    \n    \n    class Animal:\n        def hablar(self):\n            print(\"Hace un sonido\")\n\nclass Perro(Animal):\n    def hablar(self):\n        print(\"Ladra\")\n\nclass Gato(Animal):\n    def hablar(self):\n        print(\"Maulla\")\n\n\n# Uso del polimorfismo\ndef hacer_hablar(animal: Animal): # Función que acepta un objeto de tipo Animal\n    animal.hablar()  # Llama al método hablar del objeto animal\n\nhacer_hablar(Perro(\"Kuky\"))  # Imprime: Ladra\nhacer_hablar(Gato(\"Wildson\"))   # Imprime: Maulla\n\n\n     # Llama al método hablar del objeto animal, que puede ser de cualquier subclase de Animal\n    # Esto demuestra el polimorfismo, ya que el mismo método puede comportarse de manera diferente según el tipo de objeto\n    # que se le pase (Perro, Gato, etc.).\n    # La función hacer_hablar puede aceptar cualquier objeto que sea una instancia de Animal o sus subclases\n    # y llamar al método hablar, sin importar la implementación específica de cada subclase.\n    # Esto permite que el mismo código funcione con diferentes tipos de objetos,\n    # mejorando la flexibilidad y la extensibilidad del software.\n    # Esto es especialmente útil en situaciones donde se desea tratar diferentes tipos de objetos de manera uniforme,\n    # siempre que implementen la misma interfaz o métodos.\n    # En este caso, cualquier objeto que sea una instancia de Animal o sus subclases\n    # puede ser pasado a la función hacer_hablar y se llamará al método hablar correspondiente.\n    # Esto es un ejemplo de polimorfismo en acción.\n    \n#XtraJ\n\nclass Empleado:\n    def __init__(self,id: int, nombre: str):\n        self.id = id\n        self.nombre = nombre\n        self.empleados = []  # Lista para almacenar empleados a cargo\n\n    def agregar_empleados(self, empleados):\n        self.empleados.extend([empleados])  # Agrega varios empleados a la lista de empleados a cargo\n\n    def print_empleados(self):\n        for empleado in self.empleados:\n            print(empleado.nombre)  # Imprime los nombres de los empleados a cargo\n\n\nclass Gerente(Empleado): #Gerente hereda de Empleado\n  def coordinar_proyectos(self):\n    print(f\"El gerente {self.nombre} está coordinando proyectos de la empresa.\")\n\nclass Gerente_de_proyectos(Empleado): #Gerente_de_proyectos hereda de Gerente\n  def __init__(self,id: int, nombre: str, proyecto: str):\n        super().__init__(id, nombre)\n        self.proyecto = proyecto\n\n  def coordinar_proyectos(self):\n      print(f\"El gerente de proyectos {self.nombre} está coordinando el {self.proyecto}.\")\n\nclass programador(Empleado): #Programador hereda de Empleados\n  def __init__(self,id: int, nombre: str, lenguaje: str):\n        super().__init__(id, nombre,)\n        self.lenguaje = lenguaje\n  def programar(self):\n      print(f\"El programador {self.nombre} está programando en {self.lenguaje}.\")\n\n  def agregar_empleados(self, empleados): #Los programadores no pueden tener empleados a cargo\n      for empleado in empleados:\n          print(\n                f\"Los programadores no pueden tener empleados a cargo. {empleado} no se agregó.\")\n# Crear instancias de las clases\ngerente = Gerente(1, \"Charly\")\ngerente.coordinar_proyectos()  # El gerente Charly está coordinando proyectos.\n\ngerente_de_proyectos = Gerente_de_proyectos(2, \"Ana\", \"Proyecto X\")\ngerente_de_proyectos.coordinar_proyectos()  # El gerente de proyectos Ana está coordinando el Proyecto X.\ngerente_de_proyectos2 = Gerente_de_proyectos(3, \"Luis\", \"Proyecto Y\")\ngerente_de_proyectos2.coordinar_proyectos()  # El gerente de proyectos Luis está coordinando el Proyecto Y.\nprogramador1 = programador(4, \"Ivan\", \"Python\")\nprogramador1.programar()  # El programador Ivan está programando en Python.\nprogramador2 = programador(5, \"Maria\", \"JavaScript\")\nprogramador2.programar()  # El programador Maria está programando en JavaScript.\nprogramador3 = programador(6, \"Pedro\", \"C++\")\nprogramador3.programar()  # El programador Pedro está programando en C++.\nprogramador3.agregar_empleados([\"Pedro\"])  # Los programadores no pueden tener empleados a cargo. Pedro no se agregó.\n\ngerente.agregar_empleados(gerente_de_proyectos) # Agrega Ana a la lista de empleados a cargo de Charly\ngerente.agregar_empleados(gerente_de_proyectos2) # Agrega Luis a la lista de empleados a cargo de Charly\n\"\"\"\naqui estamos agregando a los gerentes de proyectos a la lista de empleados a cargo del gerente\n\"\"\"\n\ngerente_de_proyectos.agregar_empleados(programador1) # Agrega Ivan a la lista de empleados a cargo de Ana\ngerente_de_proyectos.agregar_empleados(programador2) # Agrega Maria a la lista de empleados a cargo de Ana\n\"\"\"\naqui estamos agregando a los programadores a la lista de empleados a cargo del gerente de proyectos\n\"\"\"\n\nprint(f\"Empleados a cargo de {gerente.nombre}:\")\ngerente.print_empleados()  # Imprime los empleados a cargo de Charly\n\n# En este ejemplo, tenemos una clase base Empleado y tres subclases: Gerente, Gerente_de_proyectos y Programador.\n# Cada subclase hereda atributos y métodos de la clase base Empleado.\n# Además, cada subclase puede tener sus propios métodos y atributos específicos.\n# La función coordinar_proyectos en las subclases Gerente y Gerente_de_proyectos demuestra el polimorfismo,\n# ya que el mismo método se comporta de manera diferente según la subclase que lo implemente.\n# La clase Programador también tiene su propio método programar.\n# Además, la clase Programador sobrescribe el método agregar_empleados para evitar que los programadores tengan empleados a cargo.\n# Esto muestra cómo la herencia y el polimorfismo pueden ser utilizados para crear una jerarquía de clases con comportamientos específicos.\n            "
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/Paula2409.py",
    "content": "\"\"\" \n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n\"\"\"\nclass Animal:\n    def __init__(self, tipo: str, sonido: str):\n        self.tipo = tipo\n        self.sonido = sonido\n        \n    def hablar(self):\n        return f\"El animal {self.tipo} hace {self.sonido}\"\n    \nclass Perro(Animal):\n    def __init__(self, tipo, sonido):\n        super().__init__(tipo, sonido)\n        \nclass Gato(Animal):\n    def __init__(self, tipo, sonido):\n        super().__init__(tipo, sonido)\n        \nperro = Perro('perro', 'guau')\ngato = Gato('gato', 'miau')\nprint(perro.hablar())\nprint(gato.hablar())\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo. \n\"\"\"\n\nclass Empleados:\n    id = 0\n    empleados = {}\n    \n    @classmethod\n    def agregar_empleado(cls):\n        cls.id += 1\n        return cls.id\n            \n    def __init__(self, nombre: str, puesto: str, funcion: str):\n        self.id = Empleados.agregar_empleado()\n        self.nombre = nombre\n        self.puesto = puesto\n        self.funcion = funcion\n        Empleados.empleados[self.id] = self.nombre\n        \n        \nclass GerenteDeProyectos(Empleados):\n    gerente_proyecto = {}\n    a_cargo_gp = []\n    \n    def agrega_gerente_proyecto(self):\n        GerenteDeProyectos.gerente_proyecto['Nombre'] = self.nombre\n        GerenteDeProyectos.gerente_proyecto['Puesto'] = self.puesto\n        GerenteDeProyectos.gerente_proyecto['Proyecto'] = self.proyecto\n    \n    def __init__(self, nombre: str, puesto: str, funcion: str, proyecto: str):\n        super().__init__(nombre, puesto, funcion)\n        self.proyecto = proyecto\n        GerenteDeProyectos.agrega_gerente_proyecto(self)\n        Empleados.empleados[self.id] = GerenteDeProyectos.gerente_proyecto\n\n        \n    def __str__(self):\n        return f\"Nombre: {self.nombre}, Puesto: {self.puesto}, Proyecto: {self.proyecto}\"\n\nclass Gerente(Empleados):\n    gerentes = {}\n    a_cargo_g = []\n    \n    def agrega_gerente(self):\n        Gerente.gerentes['Nombre'] = self.nombre\n        Gerente.gerentes['Puesto'] = self.puesto\n        Gerente.gerentes['Proyecto'] = self.proyecto\n        GerenteDeProyectos.a_cargo_gp.append(Gerente.gerentes)\n    \n    def __init__(self, nombre: str, puesto: str, funcion: str, proyecto: str):\n        super().__init__(nombre, puesto, funcion)\n        self.proyecto = proyecto\n        Gerente.agrega_gerente(self)\n        Empleados.empleados[self.id] = Gerente.gerentes\n\n    def __str__(self):\n        return f\"Nombre: {self.nombre}, Puesto: {self.puesto}, Proyecto: {self.proyecto}\"\n\nclass Programador(Empleados):\n    programadores = {}\n    \n    def agregar_programador(self):\n        Programador.programadores['nombre'] = self.nombre\n        Programador.programadores['puesto'] = self.puesto\n        Programador.programadores['salario'] = self.salario\n        Gerente.a_cargo_g.append(Programador.programadores)\n        \n    def __init__(self, nombre: str, puesto: str, funcion: str, salario: int):\n        super().__init__(nombre, puesto, funcion)\n        self.salario = salario\n        Programador.agregar_programador(self)\n        Empleados.empleados[self.id] = Programador.programadores\n        \n    def __str__(self):\n        return f\"Nombre: {self.nombre}, Puesto: {self.puesto}, Salario: {self.salario}\"\n\nempleado1 = Programador('Paula','Programador', 'Programar', 1000)\nempleado2 = Gerente('Jose','Gerente','Gestion','Web')\nempleado3 = GerenteDeProyectos('Marcos','Gerente de Proyectos','Coordinar','Web')\nprint(f\"Empleados: {Empleados.empleados}\")\nprint(f\"Gerentes: {Gerente.gerentes}\")\nprint(f\"Gerentes de Proyecto: {GerenteDeProyectos.gerente_proyecto}\")\nprint(f\"Personal a cargo de Gerentes: {Gerente.a_cargo_g}\")\nprint(f\"Personal a cargo de Gerentes de Proyectos: {GerenteDeProyectos.a_cargo_gp}\")\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/Pipe281.py",
    "content": "class Animal:\n    def __init__(self, nombre, sonido):\n        self.nombre = nombre\n        self.sonido = sonido\n\n    def mostrar_datos(self):\n        txt = \"{0}, {1}\"\n        return txt.format(self.nombre,self.sonido)\n\nclass perro(Animal):\n    pass    \n\nclass gato(Animal):\n    pass  \n\nperro1 = perro(\"Perro\", \"Guau Guau\")\nprint(perro1.mostrar_datos())\n\ngato1 = gato(\"Gato\", \"Miau Miau\")\nprint(gato1.mostrar_datos())"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/Ricardijulio.py",
    "content": "#  * EJERCICIO:\n#  * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n#  * implemente una superclase Animal y un par de subclases Perro y Gato,\n#  * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n#  * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n#  * Cada empleado tiene un identificador y un nombre.\n#  * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n#  * actividad, y almacenan los empleados a su cargo.\n\nclass Animal:\n    def __init__(self,especie,edad):\n        self.especie = especie\n        self.edad = edad\n    \n    def comunicar(self):\n        pass\n    \nclass Perro(Animal):\n    def comunicar(self):\n        print('Wof! wof!')\n        \nclass Gato(Animal):\n    def comunicar(self):\n        print('Miau! miau!')\n        \nperro = Perro('Mamifero','2 años')\ngato = Gato('Mamifero','9 meses')\n\nperro.comunicar()\ngato.comunicar()\n\n# DIFICULTAD EXTRA:\n\nclass Empleado:\n    def __init__(self,nombre,identificador):\n        self.nombre = nombre\n        self.identificador = identificador\n    \n    def mostrar_info(self):\n        print(f'Mi nombre es {self.nombre} y mi identificador es {self.identificador}')\n        \nclass Gerente(Empleado):\n    def __init__(self,nombre,identificador):\n        super().__init__(nombre,identificador)\n    \n    equipo = []    \n    \n    def asignar(self,persona):\n        self.equipo.append(persona)\n        print (f'Se ha añadido a {persona} al equipo de {self.nombre}')\n\nclass Gerente_proyectos(Gerente):\n    def __init__(self,nombre,identificador):\n        super().__init__(nombre,identificador)\n    proyectos = []\n    tareas = {}\n    \n    def asignar_proyecto(self, proyecto):\n        self.proyectos.append(proyecto)\n        print (f'Se ha añadido {proyecto} a la lista de proyectos de {self.nombre}')\n        \n    def asignar_tarea(self, tarea, persona):\n        self.tareas[tarea]=persona\n        print(f'Se le ha asignado {tarea} a {persona}')\n           \n\nclass Programador(Empleado):\n    \n    def __init__(self,nombre,identificador,nivel):\n        super().__init__(nombre,identificador)\n        self.nivel = nivel\n    lenguajes = []\n    \n    def usar_lenguaje(self,lenguaje):\n        self.lenguajes.append(lenguaje)\n        print(f'{self.nombre} puede usar {lenguaje}')\n        \n    def escribir_codigo(self,lenguaje):\n        for i in self.lenguajes:\n            if lenguaje == i:\n                print(f'{self.nombre} esta escribiendo codigo en {lenguaje}')\n            else:\n                print(f'{self.nombre} no maneja {lenguaje}')\n        \ng = Gerente('Daniel','1002')\ng.asignar('Pedro')\ng.asignar('Sofia')\ng.asignar('Federico')\n\ngp = Gerente_proyectos('Pedro','1030')\ngp.asignar_proyecto('San juan')\ngp.asignar_tarea('Ruta de acceso','Angel')\n\np = Programador('Angel','1023','Senior')\np.usar_lenguaje('python')\np.escribir_codigo('python')\n\ng.mostrar_info()\ngp.mostrar_info()\np.mostrar_info()\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/RoniPG.py",
    "content": "#Roni\n\"\"\"\nEJERCICIO:\nExplora el concepto de herencia según tu lenguaje. Crea un ejemplo que\nimplemente una superclase Animal y un par de subclases Perro y Gato,\njunto con una función que sirva para imprimir el sonido que emite cada Animal.\n\"\"\"\nclass Animal : # Superclase\n    def __init__(self) -> None:\n          pass\n    def sonidoAnimal(self) :\n        print(\"Soy un animal que emite sonido\")\n        \nclass Perro(Animal) : # --> Subclase\n    def __init__(self) -> None:\n        pass\n    def sonidoAnimal(self) :\n        print(\"Soy un perro y ladro\")\n        \nclass Gato (Animal) : # --> Subclase\n    def __init__(self) -> None:\n        pass\n    def sonidoAnimal(self) :\n        print(\"Soy un gato y maúllo\")\n\n# Instaciamos los objetos\nan = Animal() # --> Objeto Animal\nan.sonidoAnimal() # --> Llamamos a la función\nperro = Perro() # --> Objeto Perro\nperro.sonidoAnimal() # --> Llamamos a la función sobrescrita\ngato = Gato() # --> Objeto Gato\ngato.sonidoAnimal() # --> Llamamos a la función sobrescrita\n\"\"\"\nDIFICULTAD EXTRA (opcional):\nImplementa la jerarquía de una empresa de desarrollo formada por Empleados que\npueden ser Gerentes, Gerentes de Proyectos o Programadores.\nCada empleado tiene un identificador y un nombre.\nDependiendo de su labor, tienen propiedades y funciones exclusivas de su\nactividad, y almacenan los empleados a su cargo.\n\"\"\"\n#Instaciamos los objetos\nclass Empleado : # --> Superclase\n    #Atributos heredables\n    identificador :int\n    nombre : str\n    def __init__(self,identificador : int, nombre : str) -> None:\n        self.identificador=identificador\n        self.nombre=nombre\nclass Gerente (Empleado) : # --> Subclase\n    #Atributos propios\n    cargo : str\n    g_p_d : list # --> Lista de empleados\n    def __init__(self, identificador: int, nombre: str) -> None:\n        super().__init__(identificador, nombre)\n        self.g_p_d=list()\n        self.cargo=\"Gerente\"\n    #Metodos propios\n    def asignarEmpleado(self, gdp) :\n        self.g_p_d.append(gdp)\n    def soy(self) :\n        print(f\"Soy: {self.nombre}\\nMi cargo es: {self.cargo}\")\n        for gdp in self.g_p_d:\n           print(f\"Tengo a cargo a: {gdp.nombre}\")\nclass Gerente_de_Proyecto (Empleado) : # --> Subclase\n    # Atributos propios\n    cargo : str\n    programadores : list # --> Lista de empleados\n    def __init__(self, identificador: int, nombre: str) -> None:\n        super().__init__(identificador, nombre)\n        self.programadores= list()\n        self.cargo=\"Gerente de Proyecto\"\n    # Metodos propios\n    def asignarEmpleado(self, pgr ) :\n        self.programadores.append(pgr) \n    def asignarEncargado(self, ger:Gerente) :\n        ger.asignarEmpleado(self)\n    def soy(self) :\n        print(f\"Soy: {self.nombre}\\nMi cargo es: {self.cargo}\")   \n        for pgr in self.programadores:\n            print(f\"Tengo a cargo a: {pgr.nombre}\")\nclass Programador (Empleado) : # --> Subclase\n    # Atributos propios\n    cargo :str\n    def __init__(self, identificador: int, nombre: str) -> None:\n        super().__init__(identificador, nombre)\n        self.cargo=\"Programador\"\n    # Metodos propios\n    def asignarEncargado(self, gdp:Gerente_de_Proyecto) :\n        gdp.asignarEmpleado(self)\n    def soy(self) :\n        print(f\"Soy: {self.nombre}\\nMi cargo es: {self.cargo}\")\nger1 = Gerente(0, \"A\") # --> Objeto Gerente\nger2 = Gerente(1, \"B\") # --> Objeto Gerente\ngdp1 = Gerente_de_Proyecto(3, \"C\") # --> Objeto Gerente de Proyecto       \ngdp2 = Gerente_de_Proyecto(4, \"D\") # --> Objeto Gerente de Proyecto       \npgr1 = Programador(5, \"E\") # --> Objeto Programador\npgr2 = Programador(6, \"F\") #--> Objeto Programador\n# Le asignamos un empleado(Gerente de proyecto) al Gerente\nger1.asignarEmpleado(gdp1)\nger1.soy() # --> Llamamos a la función propia del Gerente\n# Le asignamos un Encargado(Gerente) al Gerente de proyecto\ngdp2.asignarEncargado(ger2)\nger2.soy() #--> Llamamos a la función propia del Gerente\n# Le asignamos un empleado(Programador) al Gerente de proyecto\ngdp1.asignarEmpleado(pgr1)\ngdp1.soy() # --> Llamamos a la función propia del Gerente de proyecto de proyecto sobrescrita     \n# Le asignamos un Encargado(Gerente de proyecto) al Programador\npgr2.asignarEncargado(gdp2)\ngdp2.soy() #--> Llamamos a la función propia del Gerente de proyecto de proyecto sobrescrita     \npgr1.soy() # --> Llamamos a la función propia del Programador de proyecto sobrescrita\npgr2.soy() # --> Llamamos a la función propia del Programador de proyecto sobrescrita\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/Sac-Corts.py",
    "content": "### Ejercicio ###\n\nclass Animal:\n    def __init__(self, nombre, edad):\n        self.nombre = nombre\n        self.edad = edad\n    \n    def hacer_sonido(self):\n        print(\"El animal hace un sonido\")\n\n\nclass Perro(Animal):\n    def hacer_sonido(self):\n        print(\"Guau guau\") \n    \n\nclass Gato(Animal):\n    def hacer_sonido(self):\n        print(\"Miau miau\")\n\nperro = Perro(\"Junior\", \"10 años\")\ngato = Gato(\"Malvavisco\", \"3 años\")\nperro.hacer_sonido()\ngato.hacer_sonido()\n\n\n### Ejercicio Extra ###\n\nclass Empleado:\n    def __init__(self, id, nombre):\n        self.id = id    \n        self.nombre = nombre\n\n    def __str__(self):\n        return f\"{self.nombre} (ID: {self.id})\"\n\n\nclass Gerente(Empleado):\n    def __init__(self, id, nombre):\n        super().__init__(id, nombre)\n        self.empleados_a_cargo = []\n\n    def agregar_empleado_a_cargo(self, empleado):\n        self.empleados_a_cargo.append(empleado)\n\n    def listar_empleados_a_cargo(self):\n        return [str(empleado) for empleado in self.empleados_a_cargo]\n    \n\nclass GerenteDeProyectos(Gerente): \n    def __init__(self, id, nombre):\n        super().__init__(id, nombre)\n        self.proyectos = []\n\n    def agregar_proyecto(self, proyecto):\n         self.proyectos.append(proyecto)\n\n    def listar_proyectos(self):\n        return self.proyectos\n    \n\nclass Programador(Empleado):\n    def __init__(self, id, nombre, habilidades):\n        super().__init__(id, nombre)\n        self.habilidades = habilidades\n\n    def listar_habilidades(self):\n        return self.habilidades\n    \n\ngerente = Gerente(11, \"Geovanni\")\nprogramador1 = Programador(21, \"Isaac\", [\"Python\", \"JavaScript\"])\nprogramador2 = Programador(22, \"Karina\", [\"Python\", \"C#\"])\ngerente_proyectos = GerenteDeProyectos(31, \"Jessica\")\n\ngerente.agregar_empleado_a_cargo(programador1)\ngerente.agregar_empleado_a_cargo(programador2)\ngerente_proyectos.agregar_proyecto(\"Proyecto X\")\n\nprint(f\"Gerente: {gerente}\")\nprint(\"Empleados a cargo del gerente:\")\nfor empleado in gerente.listar_empleados_a_cargo():\n    print(f\" - {empleado}\")\n\nprint(f\"\\nGerente de Proyectos: {gerente_proyectos}\")\nprint(\"Proyectos a cargo:\")\nfor proyecto in gerente_proyectos.listar_proyectos():\n    print(f\" - {proyecto}\")\n\nprint(f\"\\nProgramador: {programador1}\")\nprint(\"Habilidades:\")\nfor habilidad in programador1.listar_habilidades():\n    print(f\" - {habilidad}\")\n\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/SaezMD.py",
    "content": "#09 Herencia\n\"\"\"\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su actividad, y almacenan los empleados a su cargo.\n\"\"\"\n#Superclase:\nclass Animal():\n    def __init__(self, name: str) -> None:\n        self.name = name\n    \n    def talk(self):\n        pass\n\n\n#Subclases:\nclass Dog(Animal):\n    def talk(self):\n        print(\"¡GUAU!\")\n\nclass Cat(Animal):\n    def talk(self):\n        print(\"¡MIAU!\")\n\nmyDog = Dog(\"Perrito\")\nmyDog.talk()\n\nmyCat = Cat(\"Micho\")\nmyCat.talk()\n\n#polimorfismo\ndef printSound(animal: Animal):\n    animal.talk()\n\nmyAnimal = Animal(\"Animal\")\nprintSound(myAnimal)\nmyDog = Dog(\"Perrito Caliente\")\nprintSound(myDog)\nmyCat = Cat(\"bisbi\")\nprintSound(myCat)\n\n\n#EXTRA\n\nclass Employee():\n    def __init__(self, idNumber: int, name: str):\n        self.name = name\n        self.id = idNumber\n        self.employees = []\n    \n    def addEmployee(self, employee):\n        self.employees.append(employee)\n\n    def printAll(self):\n        for employee in self.employees:\n            print(employee.name)\n\nclass Manager(Employee):\n    def budgetControl(self):\n        return print(f\"{self.name} is controlling the Budget\")\n    \n    def resources(self):\n        return print(f\"{self.name} is organizating the resources\")\n    \nclass ProjectManager(Employee):\n    def __init__(self, idNumber: int, name: str, project: str):\n        super().__init__(idNumber, name)\n        self.project = project \n\n    def peopleTasks(self):\n        return print(f\"{self.name} is controlling the people tasks\")\n\nclass Programmer(Employee):\n\n    def __init__(self, idNumber: int, name: str, language: str):\n        super().__init__(idNumber, name)\n        self.language = language\n\n    def develop(self):\n        return print(f\"{self.name} is programming in: {self.language}.\")\n                     \n    def coffee(self):\n        return \"make coffee\"\n    \n    def addEmployee(self, employee: Employee):\n        print(f\"Programmer can't have employees. {employee.name} not added.\")\n\n\nmyManager = Manager(1,\"SaezMD\")\nmyProjectManager = ProjectManager(2, \"Antonio Marcelo\", \"Project 1\")\nmyProjectManager2 = ProjectManager(3, \"Barcelo\", \"Project 2\")\nmyProgrammer = Programmer(4, \"Carlos\", \"Python\")\nmyProgrammer2 = Programmer(5, \"Dario\", \"Kobol\")\nmyProgrammer3 = Programmer(6, \"Elena\", \"Go\")\nmyProgrammer4 = Programmer(7, \"Fran\", \"Java\")\n\n#add people:\nmyManager.addEmployee(myProjectManager)\nmyManager.addEmployee(myProjectManager2)\n\nmyProjectManager.addEmployee(myProgrammer)\nmyProjectManager.addEmployee(myProgrammer2)\nmyProjectManager2.addEmployee(myProgrammer3)\nmyProjectManager2.addEmployee(myProgrammer4)\n\nmyProgrammer.addEmployee(myProgrammer2)\n\nmyProgrammer.develop()\nmyProjectManager.peopleTasks()\nmyManager.budgetControl()\n\nmyManager.printAll()\nmyProjectManager.printAll()\nmyProgrammer.printAll()\n\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/SergioGI99.py",
    "content": "\"\"\"\n--------\nHERENCIA\n--------\nEJERCICIO:\nExplora el concepto de herencia según tu lenguaje. Crea un ejemplo que\nimplemente una superclase Animal y un par de subclases Perro y Gato,\njunto con una función que sirva para imprimir el sonido que emite cada Animal.\n\nDIFICULTAD EXTRA (Opcional):\nImplementa la jerarquía de una empresa de desarrollo formada por Empreados que\npueden ser Gerentes, Gerentes de Proyectos o Programadores.\nCada empleado tiene un identificador y un nombre.\nDependiendo de su labor, tienen propiedades y funciones exclusivas de su\nactividad, y almacenan los empleados a su cargo.\n\"\"\"\n# Ejercicio\n\nclass Animal:\n    def __init__(self, name: str, species: str):\n        self.species = species\n        self.name = name\n\n    def speak():\n        pass\n\n    def describe(self):\n        print(f\"{self.name} un Animal {self.species} de la especie\", type(self).__name__)\n\nclass Perro(Animal):\n    def __init__(self, name):\n        self.species = \"mamífero\"\n        self.name = name\n    def speak(self):\n        print(\"Guau!\")\n\n    \nclass Gato(Animal):\n    def __init__(self, name) -> None:\n        self.species = \"mamífero\"\n        self.name = name\n    def speak(self):\n        print(\"Miau!\")\n\nmy_dog = Perro(\"Keta\")\nmy_cat = Gato(\"Garfield\")\n\nmy_dog.describe()\nmy_dog.speak()\n\nmy_cat.describe()\nmy_cat.speak()\n\n# Extra\n\nclass Empleado:\n    def __init__(self, id: int, name: str):\n        self.id = id\n        self.name = name\n        self.empleados: list = []\n\n    def fichar(self):\n        print(f\"{self.name}, ha entrado a trabajar\")\n\n    def salir(self):\n        print(f\"{self.name}, ha salido de trabajar\")\n        \n    def contratar(self, candidato):\n        self.empleados.append(candidato.name)\n\n    def despedir(self, candidato):\n        self.empleados.remove(candidato.name)\n\n    def print_empleados(self):\n        print(f\"{self.name} esta al cargo de: {self.empleados}\")\n\n\nclass Gerente(Empleado):\n\n    def coordinar_projectos(self):\n        print(f\"{self.name} está coordinando todos los proyectos\")\n\nclass GerenteProyectos(Empleado):\n\n    def coordinar_projectos(self):\n        pass\n\n    def coordinar_projecto(self):\n        print(f\"{self.name} está coordinando su proyecto\")\n\nclass Programador(Empleado):\n\n    def __init__(self, id: int, name: str, language: str):\n        super().__init__(id, name)\n        self.language = language\n\n    def programar(self):\n        print(f\"{self.name} está programando en {self.language}\")\n\n    def contratar(self):\n        pass\n\n    def despedir(self):\n        pass\n\n    def coordinar_projectos(self):\n        pass\n\n    def coordinar_projecto(self):\n        pass\n    \n    def print_empleados(self):\n        print(f\"{self.name} no puede tener empleados a su cargo\")\n\nmy_manager = Gerente(1, \"Jokos\")\nmy_project_manager = GerenteProyectos(2, \"Sergio\")\nmy_project_manager2 = GerenteProyectos(3, \"David\")\nmy_programmer = Programador(4, \"Randy\", \"Python\")\nmy_programmer2 = Programador(5, \"José\", \"JavaScript\")\n\nmy_manager.contratar(my_project_manager)\nmy_manager.contratar(my_project_manager2)\nmy_manager.print_empleados()\nmy_project_manager.contratar(my_programmer)\nmy_project_manager2.contratar(my_programmer2)\nmy_project_manager.print_empleados()\nmy_project_manager2.print_empleados()\nmy_programmer.print_empleados()\n\nmy_manager.coordinar_projectos()\nmy_project_manager.coordinar_projecto()\nmy_programmer.programar()"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/SooHav.py",
    "content": "# 9 Herencia\n\n# Ejercicio\n\n# Superclase Animal\nclass Animal:\n    def __init__(self, nombre: str, raza: str, edad: int, sonido_emitido: str):\n        self.nombre = nombre\n        self.raza = raza\n        self.edad = edad\n        self.sonido_emitido = sonido_emitido\n\n    def sonido(self):\n        print(f\"{self.sonido_emitido}.\")\n\n    def jugar(self):\n        pass\n\n# Subclase Perro que hereda de Animal\n\n\nclass Perro(Animal):\n    def __init__(self, nombre: str, raza: str, edad: int, sonido_emitido: str, tamaño: str, objeto: str):\n        super().__init__(nombre, raza, edad, sonido_emitido)\n        self.tamaño = tamaño\n        self.objeto = objeto\n\n    def ladrar(self):\n        print(f\"{self.nombre} dice \", end='')\n        self.sonido()  # Llamada al método sonido de la superclase Animal\n\n    def jugar(self):\n        return f\"{self.nombre} juega con la {self.objeto}.\"\n\n# Subclase Gato que hereda de Animal\n\n\nclass Gato(Animal):\n    def maullar(self):\n        print(f\"{self.nombre} dice \", end='')\n        self.sonido()\n\n    def jugar(self):\n        return f\"{self.nombre} juega con un ovillo de lana.\"\n\n# Polimorfismo\n\n\ndef mostrar_juego(animal: Animal):\n    print(animal.jugar())\n\n\n# Instancia de la clase Perro\nmi_perro = Perro(\"Rex\", \"Labrador\", 5, \"Guau\", \"Grande\", \"Pelota\")\n\n# Llamar al método ladrar\nmi_perro.ladrar()\n\n# Instancia de la clase Gato\nmi_gato = Gato(\"Tom\", \"Persa\", 2, \"Miau\")\n\n# Llamar al método ladrar\nmi_gato.maullar()\n\n# Acceder a los atributos\nprint(\"Nombre:\", mi_gato.nombre)\nprint(\"Raza:\", mi_gato.raza)\nprint(\"Edad:\", mi_gato.edad)\nprint(\"Sonido emitido:\", mi_gato.sonido_emitido)\nmostrar_juego(mi_perro)\nmostrar_juego(mi_gato)\n\n\n# Dificultad Extra\n\nclass Empleado:\n    def __init__(self, id: int, nombre: str):\n        self.id = id\n        self.nombre = nombre\n        self.cargo = \"\"\n        self.area = \"\"\n        self.proyecto = \"\"\n        self.empleados_a_cargo = []\n\n    def asignar_cargo(self, cargo):\n        self.cargo = cargo\n\n    def asignar_area(self, area):\n        self.area = area\n\n    def asignar_proyecto(self, proyecto):\n        self.proyecto = proyecto\n\n    def asignar_empleado(self, empleado: 'Empleado'):\n        self.empleados_a_cargo.append(empleado)\n\n    def empleados(self):\n        for emp in self.empleados_a_cargo:\n            print(emp.nombre)\n\n\n# Subclase Gerente\nclass Gerente(Empleado):\n    def coordinar(self):\n        print(f\"{self.nombre} coordina los proyectos de la empresa\")\n\n    def asignar_area(self, area):\n        print(f\"{self.nombre} coordina todas las areas.\")\n\n# Subclase GerenteProyectos\n\n\nclass GerenteProyectos(Empleado):\n    def coordinar(self):\n        print(f\"{self.nombre} coordina el proyecto {self.proyecto}.\")\n\n# Subclase Programador\n\n\nclass Programador(Empleado):\n    def __init__(self, id: int, nombre: str, lenguaje: str):\n        super().__init__(id, nombre)\n        self.lenguaje = lenguaje\n\n    def asignar_empleado(self, empleado: Empleado):\n        pass\n\n\n# Instancia\ngerente = Gerente(1, \"Juan\")\ngerente.asignar_cargo(\"Gerente de Desarrollo\")\ngerente.asignar_area(\"Desarrollo\")\n\ngerente_proyecto = GerenteProyectos(2, \"María\")\ngerente_proyecto.asignar_area(\"Desarrollo\")\ngerente_proyecto.asignar_cargo(\"Gerente de BD\")\ngerente_proyecto.asignar_proyecto(\"Implementación de base de datos\")\n\nprogramador1 = Programador(3, \"Pedro\", \"Python\")\nprogramador1.asignar_area(\"Desarrollo\")\nprogramador1.asignar_proyecto(\"Implementación de base de datos\")\nprogramador1.asignar_cargo(\"Programador\")\nprogramador2 = Programador(4, \"Lucía\", \"Java\")\nprogramador2.asignar_area(\"Desarrollo\")\nprogramador2.asignar_cargo(\"Programador\")\nprogramador3 = Programador(4, \"Pablo\", \"Cobol\")\nprogramador3.asignar_area(\"Desarrollo\")\nprogramador3.asignar_cargo(\"Programador\")\n\n\ngerente.asignar_empleado(gerente_proyecto)\ngerente_proyecto.asignar_empleado(programador1)\ngerente_proyecto.asignar_empleado(programador2)\ngerente_proyecto.asignar_empleado(programador3)\nprogramador1.asignar_empleado(programador2)\n\n\n# Uso\nprint(\"Empleados de gerente:\")\ngerente.empleados()\n\nprint(\"Empleados de gerente de proyectos:\")\ngerente_proyecto.empleados()\n\nprint(programador1.empleados_a_cargo)\nprint(programador1.lenguaje)\nprint(programador2.lenguaje)\n\ngerente.coordinar()\ngerente_proyecto.coordinar()\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/Tomu98.py",
    "content": "\"\"\" Reto 09: Herencia y Polimorfismo \"\"\"\n\n# Superclase\nclass Animal:\n    def __init__(self, name: str):\n        self.name = name\n\n    def sound(self):\n        pass\n\n# Subclases\nclass Dog(Animal):\n    def sound(self):\n        print(\"Guau!\")\n\nclass Cat(Animal):\n    def sound(self):\n        print(\"Miau!\")\n\ndef print_sound(animal: Animal):\n    animal.sound()\n\nmy_animal = Animal(\"Animal\")\nmy_animal.sound()\nprint_sound(my_animal)\n\nmy_dog = Dog(\"Frida\")\nmy_dog.sound()\nprint_sound(my_dog)\n\nmy_cat = Cat(\"Gordo\")\nmy_cat.sound()\nprint_sound(my_cat)\n\n\n\n\"\"\" Reto extra \"\"\"\n\nclass Employee:\n    def __init__(self, id: int, name: str):\n        self.id = id\n        self.name = name\n        self.employees = []\n\n    def add(self, employee):\n        self.employees.append(employee)\n\n    def print_employees(self):\n        for employee in self.employees:\n            print(employee.name)\n\nclass Manager(Employee):\n    def coordinate_projects(self):\n        print(f\"{self.name} está coordinando todos los proyectos de la empresa.\")\n\nclass ProjectManager(Employee):\n    def __init__(self, id: int, name: str, project: str):\n        super().__init__(id, name)\n        self.project = project\n\n    def coordinate_projects(self):\n        print(f\"{self.name} está coordinando su proyecto.\")\n\nclass Programmer(Employee):\n    def __init__(self, id: int, name: str, language: str):\n        super().__init__(id, name)\n        self.language = language\n\n    def code(self):\n        print(f\"{self.name} está programando en {self.language}.\")\n\n    def add(self, employee: Employee):\n        print(f\"Un programador no tiene empleados a su cargo. {employee.name} no se añadirá.\")\n\nmy_manager = Manager(1, \"Tomu\")\nmy_project_manager1 = ProjectManager(2, \"Jere\", \"Project 1\")\nmy_project_manager2 = ProjectManager(3, \"Cris\", \"Project 2\")\nmy_programer1 = Programmer(4, \"Celeste\", \"CSS\")\nmy_programer2 = Programmer(5, \"Benja\", \"Python\")\nmy_programer3 = Programmer(6, \"Pancho\", \"Java\")\nmy_programer4 = Programmer(7, \"Claudia\", \"C++\")\n\nmy_manager.add(my_project_manager1)\nmy_manager.add(my_project_manager2)\n\nmy_project_manager1.add(my_programer1)\nmy_project_manager1.add(my_programer4)\nmy_project_manager2.add(my_programer2)\nmy_project_manager2.add(my_programer3)\n\nmy_programer4.add(my_programer1)\n\nmy_programer1.code()\nmy_project_manager1.coordinate_projects()\nmy_manager.coordinate_projects()\n\nmy_manager.print_employees()\nmy_project_manager1.print_employees()\nmy_programer4.print_employees()\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/a-mayans.py",
    "content": "# Superclase\nclass Animal:\n  def __init__(self, nombre, onomatopeya):\n    self.nombre = nombre\n    self.onomatopeya = onomatopeya\n\n  def sonido(self):\n    print(f'{self.nombre} está haciendo {self.onomatopeya}')\n\n# Subclase con herencia de la superclase\nclass Perro(Animal):\n  def jugar(self):\n    print(f'El perro que se llama {self.nombre} está jugando y haiendo {self.onomatopeya}')\n\nclass Gato(Animal):\n  def jugar(self):\n    print(f'El gato que se llama {self.nombre} está jugando y haiendo {self.onomatopeya}')\n\nperro = Perro('Sirius', 'Guau!')\nperro.jugar()\ngato = Gato('Obi', 'Miau!')\ngato.jugar()\n\n\n\"\"\" EJERCICIO EXTRA \"\"\"\n\nclass Empleados:\n  def __init__(self, id, nombre):\n    self.id = id\n    self.nombre = nombre\n\n\nclass Gerente(Empleados):\n  def __init__(self, id, nombre, personal):\n    super().__init__(id, nombre)\n    self.personal = personal\n\n  def reunion(self):\n    print(f'El gerente {self.nombre} se ha reunido con sus gerentes de proyectos {self.personal}')\n\n  def gestion_de_personal(self):\n    print(f'{self.nombre} se ha asegurado de que los objetivos se están llevando a cabo')\n\n\nclass GerenteProyectos(Empleados):\n  def __init__(self, id, nombre, equipo):\n    super().__init__(id, nombre)\n    self.equipo = equipo\n\n  def gestion_de_equipo(self):\n    print(f'{self.nombre} está gestionando un equipo para su proyecto')\n\n  def fijar_tareas(self):\n    print(f'{self.nombre} en la reunion con su equipo formado por {self.equipo} ha fijado las tareas individuales y el objetivo grupal')\n\n\nclass Programador(Empleados):\n  def __init__(self, id, nombre, lenguajes):\n    super().__init__(id, nombre)\n    self.lenguajes = lenguajes\n\n  def programar(self):\n    print(f'{self.nombre} está programando en los siguientes lenguajes: {self.lenguajes}')\n\n# casos de uso\n## gerente\ngerente = Gerente(1, 'Toni', ['Gerard', 'Ruben', 'Lucas'])\ngerente.reunion()\ngerente.gestion_de_personal()\n\n## gerente de proyectos\ngerente_proyecto = GerenteProyectos(2, 'Carolina', ['Alberto', 'Laura', 'Rodri'])\ngerente_proyecto.gestion_de_equipo()\ngerente_proyecto.fijar_tareas()\n\n## programador\nprogramador = Programador(3, 'Alex', ['Python', 'JS'])\nprogramador.programar()"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/adolfolozaa.py",
    "content": "'''\r\nEJERCICIO:\r\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\r\n * implemente una superclase Animal y un par de subclases Perro y Gato,\r\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\r\n *\r\n * DIFICULTAD EXTRA (opcional):\r\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\r\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\r\n * Cada empleado tiene un identificador y un nombre.\r\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\r\n * actividad, y almacenan los empleados a su cargo.\r\n '''\r\n\r\nclass Animal:\r\n    def __init__(self, name: str):\r\n        self.name = name\r\n\r\n    def sound(self):\r\n        pass\r\n    def __repr__(self):\r\n        return str(self.__dict__)\r\n\r\nclass Perro(Animal):\r\n    def __init__(self, name: str, age: int, race:str):\r\n        super().__init__(name)\r\n        self.race = race\r\n        self.age = age\r\n\r\n    def sound(self):\r\n        print('Guau')\r\n    \r\nclass Gato(Animal):\r\n    def __init__(self, name: str, age: int, race: str):\r\n        super().__init__(name)\r\n        self.race = race\r\n        self.age = age\r\n\r\n    def sound(self):\r\n        print('Miau')\r\n\r\n\r\ndef print_sound(animal: Animal):\r\n    animal.sound()\r\n\r\nanimal = Animal('Fede')\r\nperro = Perro('Firulais', 5, 'Pastor Aleman')\r\ngato = Gato('Garfield', 3, 'Siames')\r\n\r\nprint(animal.name)\r\nprint_sound(perro)\r\nprint_sound(gato)\r\nprint(perro.name)\r\nprint(gato)\r\n\r\n\r\n'''\r\n * DIFICULTAD EXTRA (opcional):\r\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que pueden ser Gerentes, Gerentes de Proyectos o Programadores.\r\n * Cada empleado tiene un identificador y un nombre.\r\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su actividad, y almacenan los empleados a su cargo.\r\n '''\r\n\r\nclass Empleado:\r\n    def __init__(self, id: int, name: str):\r\n        self.id = id\r\n        self.name = name\r\n        self.employees = []\r\n    def __repr__(self):\r\n        return str(self.__dict__)\r\n    def add(self, employee):\r\n        self.employees.append(employee)\r\n\r\n    def print_employees(self):\r\n        for employee in self.employees:\r\n            print(f'los empleados de {employee.name} son: {employee}')\r\n\r\n\r\nclass Gerente(Empleado):\r\n    def __init__(self, id: int, name: str, area: str):\r\n        super().__init__(id, name)\r\n        self.area = area\r\n\r\n    def coordinate_areas(self):\r\n        print(f'{self.name} esta coordinando las areas {self.area}')\r\n\r\nclass Ger_Proyectos(Empleado):\r\n    def __init__(self, id: int, name: str, project: str):\r\n        super().__init__(id, name)\r\n        self.project = project\r\n\r\n    def coordinate_project(self):\r\n        print(f'{self.name} esta coordinando el proyecto {self.project}')\r\n\r\nclass Programador(Empleado):\r\n    def __init__(self, id: int, name: str, languages: list):\r\n        super().__init__(id, name)\r\n        self.languages = languages\r\n\r\n    def print_languages(self):\r\n        print(f'{self.name} sabe los siguientes lenguajes: {self.languages}')\r\n    def add(self, employee):\r\n        print(f'Un programador no tiene empleados a su cargo. {employee.name} no se añadirá.')\r\n\r\np1 = Programador(1, 'Adolfo', ['Python', 'Java', 'C++'])\r\np2 = Programador(2, 'Pedro', ['Rust', 'Javascript', 'Basic'])\r\np3 = Programador(3, 'Juan', ['C#', 'Ruby', 'Go'])\r\np4 = Programador(4, 'Maria', ['PHP', 'Swift', 'Kotlin'])\r\ng = Gerente(3, 'Juan', 'Gerencia')\r\nproj1 = Ger_Proyectos(4, 'Maria', 'Proyecto 1')\r\nproj2 = Ger_Proyectos(5, 'Carlos', 'Proyecto 2')\r\nprint(p1.name)\r\nprint(p2.name)\r\nprint(g.name)\r\nprint(proj1.name)\r\np1.print_languages()\r\ng.coordinate_areas()\r\nproj1.coordinate_project()\r\nprint(p1)\r\nprint(p2)\r\nprint(g)\r\nprint(proj1)\r\nproj1.add(p1)\r\nproj1.add(p2)\r\nproj2.add(p3)\r\ng.add(proj1)\r\ng.add(proj2) \r\n\r\ng.print_employees()\r\nproj1.print_employees()\r\nproj2.print_employees()\r\n\r\n\r\n'''\r\n * DIFICULTAD EXTRA (opcional):\r\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\r\n * en el ejercicio número 7 de la ruta de estudio)\r\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar, retornar el número de elementos e imprimir todo su contenido.\r\n '''\r\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/adra-dev.py",
    "content": "\"\"\"\nEJERCICIO:\nExplora el concepto de Herencia segun tu lenguaje. Crea un ejemplo \nque implemente una superclase Animal y un par de subclases Perro y \nGato, junto con una función que sirva para imprimir el sonido que \nemite cada Animal.\n\nDIFICULTAD EXTRA (opcional):\n- Implementa la jerarquía de una empresa de desarrollo formada por \nEmpleados que pueden ser Gerentes, Gerentes de Proyectos o \nProgramadores.\n- Cada empleado tiene un identificador y un nombre.\n- Dependiendo de su labor, tienen propiedades y funciones exclusivas \nde su actividad, y almacenan los empleados a su cargo.\n\nby adra-dev.\n\"\"\"\n\n\"\"\"\nHerencia:\n    La herencia permite definir nuevas clases a partir de clases \n    existentes. A la clase de la que se hereda se le denomina \n    <<clase madre>> o <<super clase>>. A la clase que hereda se le \n    denomina <<clase hija>> o <<sub clase>>. La clase hija <<hereda>>\n    todas las propiedades de la clase madre y nos permite redefinir \n    metodos y atributos o anadir nuevos. La ventaja fundamental que \n    aporta el mecanismo de herencia a la programacion es la capacidad\n    de reutilizar el codigo. Asi, un conjunto de clases que comparten\n    atributos y metodos pueden heredar de una superclase donde se \n    definan esos metodos y atributos.\n\"\"\"\n\n# Superclase\n\nclass Animal():\n\n    def __init__(self, name: str, age: int, species: str):\n        self.name = name\n        self.species = species\n        self.age = age\n\n    def sound(self):\n        pass\n\n    def movement(self):\n        pass\n\n    def describe(self):\n        print(\"Soy un Animal del tipo\", type(self).__name__)\n\n# Subclases\n\nclass Dog(Animal):\n\n    def __init__(self, name: str, age:int, breed: str):\n        super().__init__(name, age, species=\"Canis lupus\")\n        self.breed = breed\n\n    def sound(self):\n        print(\"Guau!\") \n\n    def movement(self):\n        print(\"Camina en 4 patas\")\n\n    def describe(self):\n        print(f\"Soy un Animal del tipo {self.species},de la raza {self.breed}\")\n    \n        \nclass Cat(Animal):\n\n    def __init__(self, name: str, age:int, breed: str):\n        super().__init__(name, age, species=\"Felis silvestris catus\")\n        self.breed = breed\n\n    def sound(self):\n        print(\"Miau!\") \n\n    def movement(self):\n        print(\"Camina en 4 patas\")\n\n    def describe(self):\n        print(f\"Soy un Animal del tipo {self.species}, de la raza {self.breed}\")\n\ndef print_sound(animal: Animal):\n    animal.sound()\n\nmy_animal = Animal(\"Bolo\", \"chango\", 11)\nprint_sound(my_animal)\nmy_dog = Dog(\"Cleo\", 7, \"Westie\")\nmy_dog.describe()\nprint_sound(my_dog)\nmy_cat = Cat(\"Silvestre\", 12, \"Spynx\")\nmy_cat.describe()\nprint_sound(my_cat)\n\n\n\"\"\"\nExtra\n\"\"\"\nclass Employee():\n\n    def __init__(self, ID:int, name:str):\n        self.ID = ID\n        self.name = name\n        self.employees = []\n        self.jobtitle = type(self).__name__\n        \n\n    def print(self):\n            mesage = f\"Nombre: {self.name} | ID: {self.ID} | JT: {self.jobtitle} \"\n            print(mesage)\n\n    def add(self, employee):\n        self.employees.append(employee)\n\n    def print_employees(self):\n        for employee in self.employees:\n            print(employee.name)\n\n\nclass Manager(Employee):\n    \n    def coordinate_projects(self):\n        print(f\"{self.name} está coordinando todos los proyectos de la empresa.\")\n\n    def print(self):\n        return super().print()\n\n\nclass ProjectManager(Manager, Employee):\n    \n    def __init__(self, ID: int, name: str, project: str):\n        super().__init__(ID, name)\n        self.project = project\n\n    def coordinate_project(self):\n        print(f\"{self.name} está coordinando su proyecto.\")\n\n\nclass Programmer(Employee):\n\n    def __init__(self, ID:int, name:str, language):\n        super().__init__(ID, name)\n        self.jobtitle = type(self).__name__\n        self.language = language\n\n\n    def code(self):\n        print(f\"{self.name} está programando en {self.language}.\")\n\n    def add(self, employee: Employee):\n        print(\n            f\"Un programador no tiene empleados a su cargo. {employee.name} no se añadirá.\")\n        \n\n       \n    \nprint()\nmy_emp = Programmer(1, \"Adrian\", \"python\")\nmy_emp.print()\nmy_emp.code()\n\nmy_emp2 = ProjectManager(2, \"Fernando\", \"Proyecto1\")\nmy_emp2.print()\nmy_emp2.add(my_emp)\nmy_emp2.coordinate_project()\n\nmy_emp.add(my_emp2)\nmy_emp3 = Manager(3, \"Brais\")\nmy_emp3.print()\nmy_emp3.coordinate_projects()\nmy_emp3.add(my_emp)\nmy_emp3.add(my_emp2)\nmy_emp3.print_employees()"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/agusrosero.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n\"\"\"\n\n# EJERCICIO:\n\n\nclass Animal:\n    def __init__(self, nombre):\n        self.nombre = nombre\n\n    def sonido(self):\n        print(\"zZzZ..\")\n\n\nclass Perro(Animal):\n    def sonido(self):\n        print(\"Guau\")\n\n\nclass Gato(Animal):\n    def sonido(self):\n        print(\"Miau\")\n\n\nanimal = Animal(\"Buho\")\nanimal.sonido()\nperro = Perro(\"Perro\")\nperro.sonido()\ngato = Gato(\"Gato\")\ngato.sonido()\n\n# DIFICULTAD EXTRA:\n\n\nclass Empleado:\n    def __init__(self, id, nombre):\n        self.id = id\n        self.nombre = nombre\n\n    def deber(self):\n        print(\"Trabajo\")\n\n\nclass Gerente(Empleado):\n    def __init__(self, id, nombre, empleados):\n        super().__init__(id, nombre)\n        self.empleados = empleados\n\n    def deber(self):\n        print(\"Gerencia\")\n\n\nclass GerenteDeProyecto(Gerente):\n    def __init__(self, id, nombre, empleados):\n        super().__init__(id, nombre, empleados)\n\n    def deber(self):\n        print(\"Proyecto\")\n\n\nclass Programador(Empleado):\n    def __init__(self, id, nombre):\n        super().__init__(id, nombre)\n\n    def deber(self):\n        print(\"Desarrollo\")\n        super().deber()\n\n\nprogramador = Programador(\"1\", \"Agus\")\nprogramador.deber()\ngerente = Gerente(\"2\", \"Hernan\", [\"1\"])\ngerente.deber()\ngerente_proyecto = GerenteDeProyecto(\"3\", \"Hernan\", [\"1\"])\ngerente_proyecto.deber()\nempleado = Empleado(\"4\", \"Hernan\")\nempleado.deber()\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/alanshakir.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n\"\"\"\n\nclass Animal:\n    def __init__(self, especie, sonido) :\n        self.especie = especie\n        self.sonido = sonido\n    \n    def imprimir_sonido(self):\n        pass\n        #print(f\"el sonido del animal {self.especie} es: {self.sonido}\")\n\nclass Perro(Animal):\n    def imprimir_sonido(self):\n        print(\"Guauuu\")\n\nclass Gato(Animal):\n    def imprimir_sonido(self):\n        print(\"Miauuu\")\n\nmy_dog = Perro(\"mamifero\", \"ladra\")\nmy_dog.imprimir_sonido()\n\nmy_cat = Gato(\"mamifero\", \"aulla\")\nmy_cat.imprimir_sonido()\n\nclass Empleados:\n    def __init__(self, identify, name):\n        self.identify = identify\n        self.name = name\n        self.my_employee = []\n\n    def add_employee(self, employee):\n        self.my_employee.append(employee)\n\n    def printer_employee(self):\n        for n in self.my_employee:\n            print(n.name)\n\nclass Gerente(Empleados):\n    def projects(self):\n        print(f\"{self.name} coordina los proyectos\")\n\n\nclass SubGerente(Empleados):\n    def __init__(self, identify, name, my_projects):\n        super().__init__(identify, name)\n        self.my_projects = my_projects\n    \n    def projects(self):\n        print(f\"{self.name} coordina su proyecto\")\n    \n\n\nclass Programadores(Empleados):\n    def __init__(self, identify, name, language):\n        super().__init__(identify, name)\n        self.language = language\n    \n    def my_language(self):\n        print(f\"{self.name} programa en el lenguaje {self.language}\")\n\nmy_gerente = Gerente(1, \"Alan\")\nmy_gerente2 = Gerente(2, \"Giselle\")\nmy_subgerente =  SubGerente(3, \"Nicolle\", \"pagina web\")\nmy_subgerente2 = SubGerente(4, \"Matheo\", \"servidores\")\nmy_programador = Programadores(5, \"Rodrigo\", \"Go\")\n\n\nmy_gerente.add_employee(my_subgerente)\nmy_gerente2.add_employee(my_subgerente2)\nmy_subgerente.add_employee(my_programador)\n\nmy_gerente.printer_employee()\nmy_gerente2.printer_employee()\nmy_subgerente.printer_employee()\n\nmy_gerente.projects()\nmy_gerente2.projects()\nmy_subgerente.projects()\nmy_subgerente2.projects()\nmy_programador.my_language()\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/alexdevrep.py",
    "content": "'''\n/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n'''\n#Creamos la superclase animal\nclass Animal :\n    def __init__(self):\n        pass\n        \n#Creamos la subclase Perro\nclass Perro(Animal): #Así se heredan los métodos en python\n    def ladrar(self):\n        print(\"Guau\")\n\n#Creamos la clase Gato\nclass Gato(Animal):\n    def maullar(self):\n        print(\"Miau\")\n\n\nmi_Gato=Gato()\nmi_Perro= Perro()\nmi_Perro.ladrar()\nmi_Gato.maullar()\n\n#Dificultad EXTRA\n\nclass Empleado:\n    def __init__(self,id,nombre,equipo):\n        self.id=id\n        self.nombre=nombre\n        self.equipo=equipo or []\n\nclass Programador(Empleado):\n    def desarrollar(self):\n        return f'{self.nombre} con ID {self.id} Está desarollando una aplicación móvil y lleva a cargo a {len(self.equipo)} personas'\n\nclass Gerente_proyecto(Empleado):\n    def supervisar(self):\n        return f'{self.nombre} con ID {self.id} Revisa que el código está libre de bugs y lleva a cargo a {len(self.equipo)} personas'\n\nclass Gerente(Empleado):\n    def dirigir(self):\n        return f'{self.nombre} con ID {self.id} Decide cual es la siguiente característica a añadir a la aplicación móvil y lleva a cargo a {len(self.equipo)} personas'\n        \n#Instanciamos a los empleados de la empresa\nprogramador1=Programador('1','Alexdevrep',[])\nprogramador2=Programador('2','Carlos',[])\ngerente_proyecto1=Gerente_proyecto('3','Brais',[programador1,programador2])\ngerente1=Gerente('4','MoureDev',[gerente_proyecto1])\n\n#Obtenemos los datos\nprint(programador1.desarrollar())\nprint(programador2.desarrollar())\nprint(gerente_proyecto1.supervisar())\nprint(gerente1.dirigir())\n\n\n    "
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/andres54-coder.py",
    "content": "'''\nejercicio\n'''\nclass Animal:\n    \n    def __init__(self, name:str):\n        self.name = name\n        \n    def sound(self):\n        pass\n        \nclass Dog(Animal):\n    \n    def sound(self):\n        print(\"Guau\")\n        \nclass Cat(Animal):\n    \n    def sound(self):\n        print(\"Miau\")       \n        \ndef print_sound(animal: Animal):\n    animal.sound()\n    \n# my_dog = Dog(\"perro\")\n# print_sound(my_dog)\n# my_cat = Cat(\"gato\")\n# print_sound(my_cat)\n\n'''\nExtra\n'''\n\nclass Employee:\n    \n    def __init__(self, id: int, name: str):\n        self.id = id\n        self.name = name\n        self.employees = []\n        \n    def add(self, employee) :\n        \n        self.employees.append(employee)\n        \n    def print_employees(self):\n        for employee in self.employees:\n            print(employee.name)\n                   \n\nclass Manager(Employee):\n    \n    def coordinate_projects(self):\n        print(f\"{self.name} esta coodinando todos los proyectos\")\n    \nclass ProjectManager(Employee):\n    def __init__(self, id: int, name: str, project: str):\n        super().__init__(id,name)\n        self.project = project\n    \n    def coordinate_project(self):\n        print(f\"{self.name} esta coodinando su proyecto {self.project}\")\n    \nclass Programmer(Employee):\n    \n    def __init__(self, id: int, name: str, lenguage: str):\n        super().__init__(id,name)\n        self.lenguage = lenguage\n    \n    def code(self):\n        print(f\"{self.name } esta programando en {self.lenguage}\")\n        \n    def add(self, employee) :\n        \n        pass\n        \n        \nmy_manager = Manager(1,'Andres')\nmy_proyect_manager = ProjectManager(2, \"Andres\", 'Telecoom')\nmy_proyect_manager2 = ProjectManager(3, \"Alejandro\", 'Claro')\nmy_programmer =  Programmer(4,\"satoshi\", \"java\")\nmy_programmer2 =  Programmer(5,\"goru\", \"Swift\")\nmy_programmer3 =  Programmer(6,\"tetop\", \"Dart\")\nmy_programmer4 =  Programmer(7,\"niea\", \"Php\")\n\nmy_manager.add(my_proyect_manager)\nmy_manager.add(my_proyect_manager2)\n\nmy_proyect_manager.add(my_programmer)\nmy_proyect_manager.add(my_programmer2)\n\nmy_proyect_manager2.add(my_programmer3)\nmy_proyect_manager2.add(my_programmer4)\n\nmy_programmer4.code()\nmy_proyect_manager2.coordinate_project()\nmy_manager.coordinate_projects()\nmy_manager.print_employees()\nmy_proyect_manager.print_employees()"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/annnerssv.py",
    "content": "# HERENCIA EN PYTHON\n\nclass Animal():\n    \n    def __init__(self, nombre : str, raza : str):\n        self.nombre = nombre\n        self.raza = raza\n        \n    def emitir_sonido(self):\n        print(\"Mi mascota saluda diciendo...\")\n        \n\nclass Perro(Animal):\n    def emitir_sonido(self):\n        super().emitir_sonido()\n        print(\"Guau Guau!\")\n        \nclass Gato(Animal):\n    def emitir_sonido(self):\n        super().emitir_sonido()\n        print(\"Miau Miau!\")\n        \n        \nmi_perro = Perro(\"Firulais\", \"Pastor Aleman\")\nprint(f\"Mi perro se llama {mi_perro.nombre} y es un {mi_perro.raza}\")\nmi_perro.emitir_sonido()\nprint(\"--------------------------------------------\")\nmi_gato = Gato(\"Pancho\", \"Siames\")\nprint(f\"Mi gato se llama {mi_gato.nombre} y es un {mi_gato.raza}\")\nmi_gato.emitir_sonido()\n\nprint(\"----------------------------------------------------------------------\")\n\n\n#Ejercicio extra\n\n\nclass Empleado:\n    def __init__(self, id : int, name : str, cargo : str):\n        self.id = id\n        self.name = name\n        self.cargo = cargo\n        self.empleado = []\n        \n    \n    def añadir_empleados(self, empleado ):\n        self.empleado.append(empleado)\n        \n    def empleados_a_cargo(self):\n        print(\"Empleados a cargo: \")\n        for empleado in self.empleado:\n            print(empleado.name)\n\n\nclass Gerente(Empleado):\n    def __init__(self, id, name, cargo):\n        super().__init__(id, name, cargo)\n        \n\nclass GerenteProyecto(Empleado):\n    def __init__(self, id, name, cargo, proyecto):\n        super().__init__(id, name, cargo)\n        self.proyecto = proyecto\n\nclass Developer(Empleado):\n    def __init__(self, id, name, cargo, language):\n        super().__init__(id, name, cargo)\n        self.language = language\n    \n    def realizar_proyecto(self):\n        print(f\"Realizando proyecto en: {self.language}\")\n        \n    def añadir_empleados(self, empleado : Empleado):\n        print(f\"El programador no tiene empleados a cargo; {empleado.name} no se añadio\")\n        \n        \n#ASIGNACION DE ROLES       \ngerente = Gerente(1, \"Jose\", \"Gerente de Area\")\n\ngerente_proyecto1 = GerenteProyecto(2, \"Pablo\", \"Gerente de Proyecto 1\", \"Proyecto web\")\ngerente_proyecto2 = GerenteProyecto(3, \"Juanito\", \"Gerente de Proyecto 2\", \"Proyecto de escritorio\")\ngerente_proyecto3 = GerenteProyecto(4, \"Pedro\", \"Gerente de Proyecto 3\", \"Proyecto Movil\")\n\ndev1 = Developer(5, \"Paco\", \"Junior Developer\", \"JavaScript\")\ndev2 = Developer(6, \"Raul\", \"Semi Senior Developer\", \"C#\")\ndev3 = Developer(7, \"Carlos\", \"Senior Developer\", \"Java\")\n\n#JERARQUIA \n\ngerente.añadir_empleados(gerente_proyecto1)\ngerente.añadir_empleados(gerente_proyecto2)\ngerente.añadir_empleados(gerente_proyecto3)\ngerente.empleados_a_cargo()\n\ngerente_proyecto1.añadir_empleados(dev1)\ngerente_proyecto2.añadir_empleados(dev2)\ngerente_proyecto3.añadir_empleados(dev3)\ngerente_proyecto1.empleados_a_cargo()\ngerente_proyecto3.empleados_a_cargo()\ngerente_proyecto2.empleados_a_cargo()\n\ndev1.añadir_empleados(dev2)\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/any7dev.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */ \"\"\"\n\n# EJERCICIO\nclass Animal:\n    def __init__(self, nombre):\n        self.nombre = nombre\n    def sonido(self):\n        pass\n\nclass Perro(Animal):\n    def sonido(self):\n        print(f\"Soy {self.nombre} guau\")\n    \nclass Gato(Animal):\n    def sonido(self):\n        print(f\"Soy {self.nombre} miau\")\n\nmi_perro = Perro(\"Firulais\")\nmi_gato = Gato(\"Peluso\")\nmi_perro.sonido()\nmi_gato.sonido()\n\n    \n\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/avcenal.py",
    "content": "\"\"\"\n* EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n\"\"\"\nclass Animal():\n    def __init__(self) -> None:\n        pass\n\nclass Dog(Animal):\n    def bark(self):\n        print(\"GUAU\")\n\nclass Cat(Animal):\n    def meow(self):\n        print(\"MIAU\")\n\nmy_dog = Dog()\nmy_dog.bark()\n\nmy_cat = Cat()\nmy_cat.meow()\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n\"\"\"\n#Un poquito de humor =)\nclass Empleado():\n    def __init__(self):\n        self.worker = dict()\n        self.worker = {\"name\":\"default\",\"id\":0,\"position\":\"default\"}\n        return None\n    def work():\n        print(\"Estoy trabajando\")\n    \nclass CEO(Empleado):\n    def __init__(self):\n        super().__init__()\n        self.worker[\"name\"] = \"Melon Musk\"\n        self.worker[\"id\"] = 1\n        self.worker[\"position\"] = \"CEO\"\n        self.worker[\"employees\"] = [\"PHILIP\",\"ANDY FENNEL\",\"ANTONIO SANZ\", \"ALEX VALDERRAMA\", \"ALEJANDRO CENALMOR\"]\n        self.worker[\"bonus\"] = [\"coche\",\"seguro privado premium\",\"dietas\"]\n    \n    def work(self):\n        print(\"Estoy gerenciando\")\n\n    def ceos_lunch(self):\n        print(\"Me voy a comer con otros CEOs\")\n\nclass ProjectManager(Empleado):\n    def __init__(self):\n        super().__init__()\n        self.worker[\"name\"] = \"PHILIP\"\n        self.worker[\"id\"] = 3\n        self.worker[\"position\"] = \"PM\"\n        self.worker[\"employees\"] = [\"ALEX VALDERRAMA\", \"ALEJANDRO CENALMOR\"]\n        self.worker[\"bonus\"] = [\"seguro privado normal\",\"dietas\"]\n    \n    def work(self):\n        print(\"Estoy gerenciando proyectos y viendo una peli en KODI\")\n\n    def smoke(self):\n        print(\"Me salgo a fumar\")\n\nclass Programmer(Empleado):\n    def __init__(self):\n        super().__init__()\n        self.worker[\"name\"] = \"Alex Valderrama\"\n        self.worker[\"id\"] = 1231323223\n        self.worker[\"position\"] = \"Umpa Lumpa\"\n    \n    def work(self):\n        print(\"Estoy picando sin parar y cobrando poco\")\n\n    def take_breath(self):\n        print(\"Voy a tomarme 30 segundos para respirar\")\n\nmy_ceo = CEO()\nprint(my_ceo.worker)\nmy_ceo.work()\nmy_ceo.ceos_lunch()\nmy_pm = ProjectManager()\nprint(my_pm.worker)\nmy_pm.work()\nmy_pm.smoke()\nmy_programmer = Programmer()\nprint(my_programmer.worker)\nmy_programmer.work()\nmy_programmer.take_breath()\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/cesar-ch.py",
    "content": "\"\"\"\n    #09 HERENCIA Y POLIMORFISMO\n\"\"\"\n\n\nclass Animal:\n    def __init__(self, name):\n        self.name = name\n\n    def sound(self):\n        print(f\"{self.name} makes a sound.\")\n\n\nclass Dog(Animal):\n    def __init__(self, name):\n        super().__init__(name)\n\n    def sound(self):\n        print(\"Guau, guau!\")\n\n\nclass Cat(Animal):\n    def __init__(self, name):\n        super().__init__(name)\n\n    def sound(self):\n        print(\"Miau, miau!\")\n\n\ndog = Dog(\"Fido\")\ndog.sound()\ncat = Cat(\"Garfield\")\ncat.sound()\n\n\"\"\"\n    DIFICULTAD EXTRA \n\"\"\"\n\n\nclass Empleado:\n    def __init__(self, id, nombre):\n        self.id = id\n        self.nombre = nombre\n        self.empleados_a_cargo = []\n\n    def agregar_empleado(self, empleado):\n        self.empleados_a_cargo.append(empleado)\n\n    def imprimir_empleados(self):\n        print([empleado.nombre for empleado in self.empleados_a_cargo])\n\n\nclass Gerente(Empleado):\n    def __init__(self, id, nombre):\n        super().__init__(id, nombre)\n\n    def actividad(self):\n        print(\"Gerente\")\n\n\nclass GerenteProyecto(Empleado):\n    def __init__(self, id, nombre):\n        super().__init__(id, nombre)\n\n    def actividad(self):\n        print(\"Gerente de Proyecto\")\n\n\nclass Programador(Empleado):\n    def __init__(self, id, nombre):\n        super().__init__(id, nombre)\n\n    def actividad(self):\n        print(\"Programador\")\n\n\ngerente = Gerente(1, \"Juan\")\ngerente_proyecto = GerenteProyecto(2, \"Pedro\")\ngerente_proyecto2 = GerenteProyecto(3, \"Luis\")\nprogramador = Programador(4, \"Maria\")\nprogramador2 = Programador(5, \"Ana\")\nprogramador3 = Programador(6, \"Jorge\")\nprogramador4 = Programador(7, \"Carlos\")\n\ngerente.agregar_empleado(gerente_proyecto)\ngerente.agregar_empleado(gerente_proyecto2)\n\ngerente_proyecto.agregar_empleado(programador)\ngerente_proyecto.agregar_empleado(programador2)\ngerente_proyecto2.agregar_empleado(programador3)\ngerente_proyecto2.agregar_empleado(programador4)\n\ngerente.imprimir_empleados()\ngerente_proyecto.imprimir_empleados()\ngerente_proyecto2.imprimir_empleados()\nprogramador.imprimir_empleados()\n\ngerente.actividad()\ngerente_proyecto.actividad()\nprogramador.actividad()\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/clmiranda.py",
    "content": "# HERENCIA Y POLIMORFISMO\n\n# HERENCIA\nclass Animal:\n    def __init__(self, nombre, edad) -> None:\n        self.nombre = nombre\n        self.edad = edad\n\nclass Perro(Animal):\n    def hace_sonido(self) -> None:\n        print(f\"{self.nombre} de {self.edad} años hace Guau!\")\n\nclass Gato(Animal):\n    def hace_sonido(self) -> None:\n        print(f\"{self.nombre} de {self.edad} años hace Miau!\\n\")\n\n\nperro = Perro(\"Firulais\", 4)\ngato = Gato(\"Manchas\", 3)\n\nperro.hace_sonido()\ngato.hace_sonido()\n\n\n# EJERCICIO - DIFICULTAD EXTRA\n\n# EMPRESA DE DESAROLLO\nclass Empleado:\n    def __init__(self, id: int, nombre: str) -> None:\n        self.id = id\n        self.nombre = nombre\n        self.empleados = []\n\n    def agregar_empleado(self, empleado) -> None:\n        self.empleados.append(empleado)\n\n    def mostrar_empleados(self) -> None:\n        print({f\"Id: {empleado.id}, Nombre: {empleado.nombre}\" for empleado in self.empleados})\n\nclass Gerente(Empleado):\n    def __init__(self, id: int, nombre: str, departamento: str) -> None:\n        super().__init__(id, nombre)\n        self.departamento = departamento\n\n    def cargo_departamento(self):\n        print(f\"El gerente {self.nombre} tiene a cargo el departamento de {self.departamento}\")\n\nclass GerenteProyecto(Empleado):\n    def __init__(self, id: int, nombre: str, proyecto: str) -> None:\n        super().__init__(id, nombre)\n        self.proyecto = proyecto\n        self.equipo_proyecto = []\n\n    def cargo_proyecto(self) -> None:\n        print(f\"El gerente de proyecto {self.nombre} tiene a cargo el proyecto de {self.proyecto}\")\n\n    def add_developer(self, empleado: Empleado) -> None:\n        self.equipo_proyecto.append(empleado.nombre)\n\n    def show_developers(self) -> None:\n        print(f\"El gerente de proyecto {self.nombre} tiene a cargo a los desarrolladores: {', '.join([i for i in self.equipo_proyecto])}\\n\")\n\nclass Programador(Empleado):\n    def __init__(self, id: int, nombre: str, lenguajes: list[str]) -> None:\n        super().__init__(id, nombre)\n        self.lenguaje = lenguajes\n\n    def lenguajes(self) -> None:\n        print(f\"El programador {self.nombre} desarrolla en {\", \".join([i for i in self.lenguaje])}\")\n\n\ngerente = Gerente(1, \"Juan\", \"Ventas\")\ngerente2 = Gerente(2, \"Andres\", \"Diseño y Publicidad\")\n\ngerente_proyecto = GerenteProyecto(3, \"Sergio\", \"Desarrollo Aplicación Móvil\")\ngerente_proyecto2 = GerenteProyecto(4, \"Javier\", \"E-Commerce\")\n\nprogramador = Programador(5, \"Marco Antonio\", [\"Python\", \"C++\", \"Java\"])\nprogramador2 = Programador(6, \"Pablo\", [\"C#\", \"Rust\", \"JavaScript\"])\n\n\ngerente.agregar_empleado(gerente)\ngerente.agregar_empleado(gerente2)\ngerente.cargo_departamento()\ngerente2.cargo_departamento()\n\ngerente_proyecto.agregar_empleado(gerente_proyecto)\ngerente_proyecto.agregar_empleado(gerente_proyecto2)\n\ngerente_proyecto.add_developer(programador)\ngerente_proyecto.add_developer(programador2)\n\ngerente_proyecto.cargo_proyecto()\ngerente_proyecto2.cargo_proyecto()\ngerente_proyecto.show_developers()\n\nprogramador.agregar_empleado(programador)\nprogramador.agregar_empleado(programador2)\nprogramador.lenguajes()\nprogramador2.lenguajes()\n\nprint()\ngerente.mostrar_empleados()\ngerente_proyecto.mostrar_empleados()\nprogramador.mostrar_empleados()"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/cristianfloyd.py",
    "content": "# EJERCICIO:\n# Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n# implemente una superclase Animal y un par de subclases Perro y Gato,\n# junto con una función que sirva para imprimir el sonido que emite cada Animal.\n\n\nclass Animal:\n    def __init__(self, nombre, raza=None):\n        self.nombre = nombre\n        self.raza = raza\n\n    def hacer_sonido(self):\n        raise NotImplementedError(\"Subclase debe implementar este método\")\n\n    def __str__(self):\n        return (\n            f\"Nombre: {self.nombre}, Raza: {self.raza if self.raza else 'Desconocida'}\"\n        )\n\n\nclass Perro(Animal):\n    def __init__(self, nombre, raza=None):\n        super().__init__(nombre, raza)\n\n    def hacer_sonido(self):\n        print(f\"{self.nombre}: Guau!\")\n\n\nclass Gato(Animal):\n    def __init__(self, nombre, raza=None):\n        super().__init__(nombre, raza)\n\n    def hacer_sonido(self):\n        print(f\"{self.nombre}: Miau!\")\n\n\nlaica = Perro(\"Laika\", \"Husky Siberiano\")\nmichi = Gato(\"Michi\", \"Siames\")\n\nlaica.hacer_sonido()\nmichi.hacer_sonido()\n\nprint(laica)\n\n\n#\n# DIFICULTAD EXTRA (opcional):\n# Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n# pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n# Cada empleado tiene un identificador y un nombre.\n# Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n# actividad, y almacenan los empleados a su cargo.\n\n\nclass Empleado:\n    def __init__(self, id, nombre, empleados_a_cargo=None):\n        self.id = id\n        self.nombre = nombre\n        self.empleados_a_cargo = (\n            empleados_a_cargo if empleados_a_cargo is not None else []\n        )\n        print(f\"Empleado creado: {self.nombre} (ID: {self.id})\")\n\n    def trabajar(self):\n        print(f\"{self.nombre} está ejecutando las tareas asignadas.\")\n\n    def add(self, empleado):\n        self.empleados_a_cargo.append(empleado)\n\n\nclass Gerente(Empleado):\n    def __init__(self, id, nombre):\n        super().__init__(id, nombre)\n\n    def agregar_empleado(self, empleado):\n        self.empleados_a_cargo.append(empleado)\n        print(f\"{empleado.nombre} ha sido agregado a los empleados de {self.nombre}.\")\n\n    def mostrar_empleados(self):\n        print(f\"Empleados a cargo de {self.nombre}:\")\n        for emp in self.empleados_a_cargo:\n            print(f\"- {emp.nombre} (ID: {emp.id})\")\n\n    def quitar_empleado(self, empleado):\n        if empleado in self.empleados_a_cargo:\n            self.empleados_a_cargo.remove(empleado)\n\n    def coordinar_proyectos(self):\n        print(f\"{self.nombre} está coordinando todos los proyectos de la empresa.\")\n\n    def trabajar(self):\n        return self.coordinar_proyectos()\n\n\nclass GerenteDeProyectos(Empleado):\n    def __init__(self, id, nombre, proyecto):\n        super().__init__(id, nombre)\n        self.proyecto = proyecto\n\n    def coordinar_proyecto(self):\n        print(f\"{self.nombre} está coordinando el proyecto: {self.proyecto}\")\n        print(\"Con los programadores asignados al proyecto:\")\n        print(\", \".join([emp.nombre for emp in self.empleados_a_cargo]))\n\n    def trabajar(self):\n        return self.coordinar_proyecto()\n\n\nclass Programador(Empleado):\n    def __init__(self, id, nombre: str, lenguaje):\n        super().__init__(id, nombre)\n        self.lenguaje = lenguaje\n\n    def programar(self):\n        print(f\"{self.nombre} está programando en {self.lenguaje}.\")\n\n    def trabajar(self):\n        return self.programar()\n\n\nmanager = Gerente(1, \"Ana\")\npm1 = GerenteDeProyectos(2, \"Luis\", \"Proyecto X\")\ndev1 = Programador(3, \"Cristian\", \"Python\")\n\nmanager.agregar_empleado(pm1)\npm1.add(dev1)\nmanager.mostrar_empleados()\npm1.coordinar_proyecto()\ndev1.programar()\n\npm2 = GerenteDeProyectos(4, \"Sofía\", \"Proyecto Y\")\ndev2 = Programador(5, \"Miguel\", \"JavaScript\")\ndev3 = Programador(6, \"Lucía\", \"Java\")\n\nmanager.agregar_empleado(pm2)\nmanager.mostrar_empleados()\n\npm2.add(dev2)\npm2.add(dev3)\npm2.coordinar_proyecto()\ndev2.programar()\ndev3.programar()\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/danielhdzr.py",
    "content": "# #09 HERENCIA Y POLIMORFISMO\n#### Dificultad: Media | Publicación: 26/02/24 | Corrección: 04/03/24\n\n## Ejercicio\n\n'''  \n* EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n '''\n\ndef main():\n    # Nuestra super clase\n    class animal():\n        def __init__(self, name, sound):\n            self.nombre = name\n            self.sonido = sound\n\n        # metodo para emitir sonido\n        def emite_sonido(self):\n            print(f\"{self.nombre} dice {self.sonido}\") # Accedemos a los parametros mediante las variables\n\n    # sub clase\n    class perro(animal):\n        # Sus parametros\n        def __init__(self, name):\n            # Parametros heredados del padre o super clase\n            super().__init__(name, \"rrrr\") # El name del padre hereda al hijo. Sound es \"rrrr\" por defecto\n            \n    # sub clase\n    class gato(animal):\n        # Sus parametros\n        def __init__(self, name):\n            # Parametros heredados del padre o super clase\n            super().__init__(name, \"miau miau\") # El name del padre hereda al hijo. sound es \"miau miau\" por defecto\n    \n    # Llamo a la sub clase. Ingreso un argumento, el otro se hereda por defecto\n    animal_domestico = gato(\"Mia Colucci\")\n    # Llamo a metodo para emitir sonido, recibe los argumentos de la funcion que acabo de llamar\n    animal_domestico.emite_sonido()\n    # Llamo a la sub clase. Ingreso un argumento, el otro se hereda por defecto\n    animal_domestico = perro(\"Max\")\n    # Llamo a metodo para emitir sonido, recibe los argumentos de la funcion que acabo de llamar\n    animal_domestico.emite_sonido()\n    \"\"\"\n    En terminal se imprime: Max dice rrrr\n    \"\"\"\n\n    print(\"///////\")\n    \"\"\" \n    * DIFICULTAD EXTRA (opcional):\n    * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n    * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n    * Cada empleado tiene un identificador y un nombre.\n    * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n    * actividad, y almacenan los empleados a su cargo.\n    \"\"\"\n\n    class empleado:\n        def __init__(self, identificador, nombre) -> None:\n            self.identificacion = identificador\n            self.nombre = nombre\n\n#//////////////////////\n    class gerente(empleado):\n        def __init__(self, identificador, nombre, departamento):\n            super().__init__(identificador, nombre)\n            self.departamento = departamento\n\n        def placa(self):\n            print(f\"Nombre: {self.nombre}, ID: {self.identificacion}, Departamento: {self.departamento}\")\n#//////////////////////\n    class gerente_proyecto(empleado):\n        def __init__(self, identificador, nombre, departamento, proyecto):\n            super().__init__(identificador, nombre)\n            self.departamento = departamento\n            self.proyectos = proyecto\n\n        def placa(self):\n            print(f\"Nombre: {self.nombre}, ID: {self.identificacion}, Departamento: {self.departamento}, Proyecto: {self.proyectos}\")\n#//////////////////////\n    class programador(empleado):\n        def __init__(self, identificador, nombre, departamento, proyecto, tarea):\n            super().__init__(identificador, nombre)\n            self.departamento = departamento\n            self.proyectos = proyecto\n            self.area_de_trabajo = tarea\n\n        def placa(self):\n            print(f\"Nombre: {self.nombre}, ID: {self.identificacion}, Departamento: {self.departamento}, Proyecto: {self.proyectos}, Tarea: {self.area_de_trabajo}\")\n#//////////////////////\n\n    var_gerente = gerente(\"01\", \"Daniel\", \"Gerencia\")\n    var_gerente_proyecto = gerente_proyecto(\"02\", \"Luis\", \"Gerente de proyecto\", \"Manhattan\")\n    var_programador = programador(\"03\", \"Gloria\", \"Programacion\", \"Manhattan\", \"Resolver bugs\")\n\n    var_gerente.placa()\n    var_gerente_proyecto.placa()\n    var_programador.placa()\n\nif __name__==\"__main__\":\n    main()\n\n\n\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/davidrguez98.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */ \"\"\"\n\n# EJERCICIO\n\nclass animal():\n    def __init__(self, name):\n        self.name = name\n\nclass dog(animal):\n    \n    def sound(self):\n        print(\"Guau\")\n\nclass cat(animal):\n\n    def sound(self):\n        print(\"Miau\")\n\ndef print_sound(animal: animal):\n    animal.sound()\n\nmy_dog = dog(\"Perro\")\nmy_dog.sound()\nmy_cat = cat(\"Gato\")\nmy_cat.sound()\nprint_sound(my_dog)\nprint_sound(my_cat)\n\n\n#DIFICULTAD EXTRA\n\nclass empleados:\n\n    def __init__(self, id: int, name: str):\n        self.id = id\n        self.name = name\n        self.empleado = []\n\n    def añadir(self, empleados):\n        self.empleado.append(empleados)\n        \nclass gerente(empleados):\n\n    def funcion(self):\n        print(f\"{self.name} está a cargo de todos los proyectos de la empresa.\")\n\nclass gerente_proyecto(empleados):\n\n    def __init__(self, id, name, proyecto):\n        super().__init__(id, name)\n        self.proyecto = proyecto\n\n    def funcion(self):\n        print(f\"{self.name} está a cargo del proyecto {self.proyecto}.\")\n\nclass programador(empleados):\n\n    def __init__(self, id, name, lenguaje):\n        super().__init__(id, name)\n        self.lenguaje = lenguaje\n\n    def codigo(self):\n        print(f\"{self.name} está programando en {self.lenguaje}\")\n\nmi_gerente = gerente(1, \"David\")\nmi_gerente_proyecto = gerente_proyecto(2, \"Miguel\", \"X\")\nmi_gerente_proyecto2 = gerente_proyecto(3, \"Juan\", \"Y\")\nmi_programador = programador(4, \"Marcos\", \"Python\")\nmi_programador2 = programador(5, \"Yae\", \"JS\")\nmi_programador3 = programador(6, \"Pedro\", \"Angular\")\nmi_programador4 = programador(7, \"José\", \"React\")\n\nmi_gerente.añadir(mi_gerente_proyecto)\nmi_gerente.añadir(mi_gerente_proyecto2)\nmi_gerente_proyecto.añadir(mi_programador)\nmi_gerente_proyecto.añadir(mi_programador2)\nmi_gerente_proyecto2.añadir(mi_programador3)\nmi_gerente_proyecto2.añadir(mi_programador4)\n\nmi_gerente.funcion()\nmi_gerente_proyecto.funcion()\nmi_gerente_proyecto2.funcion()\nmi_programador.codigo()\nmi_programador2.codigo()\nmi_programador3.codigo()\nmi_programador4.codigo()"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/duendeintemporal.py",
    "content": "#9 { Retos para Programadores } HERENCIA Y POLIMORFISMO\n\"\"\"  \n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n\n\"\"\"\n\n# Bibliography\n# Professional JavaScript for web developers by Matt Frisbie\n# GPT\n\n# In Python, inheritance is a mechanism that allows one class to acquire the properties and methods of another class.\n# This is typically achieved through class inheritance, enabling code reuse and the creation of hierarchical relationships between classes.\n\n# All classes in Python can inherit from other classes, allowing for a prototype chain where a class can access properties and methods from its parent class.\n\nlog = print\n\n# Define the base class Animal\nclass Animal:\n    def __init__(self, name=None, sound=None, animal_type=None):\n        self._name = name if name else 'set no name'\n        self._sound = sound if sound else 'set no sound'\n        self._type = animal_type if animal_type else 'set no type'\n\n    @property\n    def name(self):\n        return self._name\n\n    @name.setter\n    def name(self, name):\n        self._name = name\n\n    def speak(self):\n        log(f\"{self.name} the {self._type} says: {self._sound}!\")\n\n# Define the Dog class that inherits from Animal\nclass Dog(Animal):\n    def __init__(self, name, sound, animal_type):\n        super().__init__(name, sound, animal_type)\n\n    def eat(self, meal):\n        log(f\"{self._name} the {self._type} eats some: {meal}\")\n\n    def move(self):\n        log(f\"The {self._type} moves its tail.\")\n\n# Create an instance of Dog\ncap_dog = Dog('Capitan', 'I guau some pizza', 'Dog')\ncap_dog.speak()  # Capitan the Dog says: I guau some pizza!\ncap_dog.eat('pizza')  # Capitan the Dog eats some: pizza\ncap_dog.move()  # The Dog moves its tail.\n\n# Define the Cat class that inherits from Animal\nclass Cat(Animal):\n    def __init__(self, name, sound, animal_type):\n        super().__init__(name, sound, animal_type)\n\n    def eat(self, meal):\n        log(f\"{self._name} the {self._type} eats some: {meal}\")\n\n    def move(self):\n        log(f\"The {self._type} hunts the rat.\")\n\n# Create an instance of Cat\nblack_jack = Cat('BlackJack', 'Miuauuuu', 'Cat')\nblack_jack.speak()  # BlackJack the Cat says: Miuauuuu!\nblack_jack.eat('rat snack')  # BlackJack the Cat eats some: rat snack\nblack_jack.move()  # The Cat hunts the rat.\n\n# Note: It's interesting to know that we can use variables like key-value pairs assigned to object properties.\n# This also works with functions.\n\ndef make_person(name, age, email):\n    return {'name': name, 'age': age, 'email': email}\n\nperson = make_person('Angy', 28, 'badgirl@greenhouse.net')\nlog(person)  # {'name': 'Angy', 'age': 28, 'email': 'badgirl@greenhouse.net'}\n\n# Using destructuring (unpacking)\nperson_name = person.get('name')\nperson_age = person.get('age')\nperson_email = person.get('email')\nperson_job = person.get('job', 'Web Developer')  # Default value if 'job' is not found\n\nlog(person_age)  # 28\nlog(person_job)  # Web Developer\n\nimport re\n\nimport re  # Make sure to import the re module\n\n# Define the User class\nclass User:\n    def __init__(self, id, name, email, country):\n        try:\n            self._id = self.set_id(id)\n            self._name = self.set_name(name)\n            self._email = self.set_email(email)\n            self._country = self.set_country(country)\n            self.validate_properties()  # Validate properties before freezing or sealing\n        except Exception as error:\n            log('Error creating User:', error)\n\n    @property\n    def id(self):\n        return self._id\n\n    @property\n    def name(self):\n        return self._name\n\n    @property\n    def email(self):\n        return self._email\n\n    @property\n    def country(self):\n        return self._country\n\n    @id.setter\n    def id(self, id):\n        self._id = self.set_id(id)\n\n    @name.setter\n    def name(self, name):\n        self._name = self.set_name(name)\n\n    @email.setter\n    def email(self, email):\n        self._email = self.set_email(email)\n\n    @country.setter\n    def country(self, country):\n        self._country = self.set_country(country)\n\n    def set_id(self, id):  # Corrected to a regular method\n        id_string = str(id)\n        max_length = 15\n\n        if len(id_string) > max_length:\n            raise ValueError(f\"ID must be at most {max_length} characters long.\")\n\n        return id_string\n\n    def set_name(self, name):\n        name_string = str(name)\n        max_length = 35\n\n        if len(name_string) > max_length:\n            raise ValueError(f\"Name must be at most {max_length} characters long.\")\n\n        return name_string\n\n    def set_email(self, email):\n        email_regex = r'^[^\\s@]+@[^\\s@]+\\.[a-zA-Z]{2,}(\\.[a-zA-Z]{2,})?$'\n\n        if not re.match(email_regex, email):\n            raise ValueError('Invalid email address format.')\n\n        return email\n\n    def set_country(self, country):\n        country_string = str(country)\n        max_length = 35\n\n        if len(country_string) > max_length:\n            raise ValueError(f\"Country must be at most {max_length} characters long.\")\n\n        return country_string\n\n    def validate_properties(self):\n        if not self._id or not self._name or not self._email or not self._country:\n            raise ValueError('All properties must be set before freezing the object.')\n\n    def user_data(self):\n        return {'id': self._id, 'name': self._name, 'email': self._email, 'country': self._country}\n\n# Example usage of User class\ntry:\n    sussy = User('0067', 'Sussan', 'sussy45@something.dt', 'Canada')\n    log(sussy.user_data())  # {'id': '0067', 'name': 'Sussan', 'email': 'sussy45@something.dt', 'country': 'Canada'}\nexcept Exception as error:\n    log('Failed to create user:', error)\n\n# Note: If we use a number to set the value for id, '0067' becomes '67' because it is turned to a decimal value.\n\n# Define the SuperUser class that inherits from User\nclass SuperUser(User):\n    def __init__(self, id, name, email, country):\n        super().__init__(id, name, email, country)\n        self.permission = True\n\n    def has_permission(self):\n        return self.permission\n\n    def display_user_info(self):\n        user_info = self.user_data()\n        return f\"{user_info['name']} has permission: {self.has_permission()}\"\n\nclass SuperUser:\n    def __init__(self, user_id, name, email, country):\n        self._id = user_id\n        self.name = name\n        self.email = email\n        self.country = country\n        self.permission = True  # Assuming permission is always true for this example\n\n    def user_data(self):\n        # Returns user data as a dictionary\n        return {\n            \"id\": self._id,\n            \"name\": self.name,\n            \"email\": self.email,\n            \"country\": self.country\n        }\n\n# Creating an instance of SuperUser\nniko = SuperUser('001', 'Niko', 'duendeintemporal@hotmail.com', 'Venezuela')\nniko.country = 'undefined'  # Setting country to 'undefined'\n\n# Logging the outputs\nlog(niko._id)  # 001\nlog(niko.country)  # undefined\nlog(niko.permission)  # True\nlog(niko.user_data())  # {'id': '001', 'name': 'Niko', 'email': 'duendeintemporal@hotmail.com', 'country': 'undefined'}\n\nclass Employed:\n    def __init__(self, user_id, name, occupation):\n        try:\n            self._id = self.set_id(user_id)\n            self._name = self.set_name(name)\n            self._occupation = self.set_occupation(occupation)\n            self.validate_properties()\n        except Exception as error:\n            log('Error creating Employed:', error)\n\n    @property\n    def id(self):\n        return self._id\n\n    @property\n    def name(self):\n        return self._name\n\n    @property\n    def occupation(self):\n        return self._occupation\n\n    @id.setter\n    def id(self, user_id):\n        self._id = self.set_id(user_id)\n\n    @name.setter\n    def name(self, name):\n        self._name = self.set_name(name)\n\n    @occupation.setter\n    def occupation(self, occupation):\n        self._occupation = self.set_occupation(occupation)\n\n    def set_id(self, user_id):\n        id_string = str(user_id)\n        max_length = 15\n\n        if len(id_string) > max_length:\n            raise ValueError(f'ID must be at most {max_length} characters long.')\n\n        return id_string\n\n    def set_name(self, name):\n        name_string = str(name)\n        max_length = 35\n\n        if len(name_string) > max_length:\n            raise ValueError(f'Name must be at most {max_length} characters long.')\n\n        return name_string\n\n    def set_occupation(self, occupation):\n        occupation_str = str(occupation)\n        max_length = 50\n\n        if len(occupation_str) > max_length:\n            raise ValueError(f'Occupation must be at most {max_length} characters long.')\n\n        return occupation_str\n\n    def validate_properties(self):\n        if not self._id or not self._name or not self._occupation:\n            raise ValueError('All properties must be set before freezing the object.')\n\n    def employed_data(self):\n        return {'id': self._id, 'name': self._name, 'occupation': self._occupation}\n\n\nclass Developer(Employed):\n    def __init__(self, user_id, name, occupation, languages, area=None):\n        super().__init__(user_id, name, occupation)\n        self._languages = languages\n        self._area = area\n\n    def functions(self):\n        log(f'Developer ID: {self._id} | Name: {self._name} | Occupation: {self._occupation} | Area: {self._area} | Languages: {\", \".join(self._languages)}')\n\n\nclass Secretary(Employed):\n    def functions(self):\n        log(f'Secretary ID: {self._id} | Name: {self._name} | Occupation: {self._occupation} | Responsibilities: Administrative operations and user attention.')\n\n\nclass Manager(Employed):\n    def __init__(self, user_id, name, occupation, employeds):\n        super().__init__(user_id, name, occupation)\n        self._employeds = employeds  # Expecting a list of employee names\n\n    def functions(self):\n        log(f'Manager ID: {self._id} | Name: {self._name} | Occupation: {self._occupation} | Supervising Employees: {\", \".join(self._employeds)}')\n\n\nclass GeneralManager(Manager):\n    def functions(self):\n        log(f'General Manager ID: {self._id} | Name: {self._name} | Occupation: {self._occupation} | Supervising Employees: {\", \".join(self._employeds)}')\n\n\n# Creating instances\ns1 = Secretary('0023', 'Gabriela Mistral', 'Secretary')\nd12 = Developer('0041', 'Niko Zen', 'Web Developer', ['Python', 'JavaScript', 'Rust', 'Ruby', 'Bash'])\nm3 = Manager('0098', 'Patty Smith', 'Manager', [s1.name, d12.name])\nmg2 = GeneralManager('003', 'Lenny Kravitz', 'General Manager', [m3.name])\n\n\n# Logging the outputs\nlog(s1.employed_data())  \n# Output: {'id': '0023', 'name': 'Gabriela Mistral', 'occupation': 'Secretary'}\n\nd12.functions()  \n# Output: Developer ID: 0041 | Name: Niko Zen | Occupation: Web Developer | Area: None | Languages: Python, JavaScript, Rust, Ruby, Bash\n\nm3.functions()  \n# Output: Manager ID: 0098 | Name: Patty Smith | Occupation: Manager | Supervising Employees: Gabriela Mistral, Niko Zen\n\nmg2.functions()  \n# Output: General Manager ID: 003 | Name: Lenny Kravitz | Occupation: General Manager | Supervising Employees: Patty Smith\n    \n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/elbarbero.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n \"\"\"\n\nclass Animal:\n    def __init__(self, name, sound):\n        self.name = name\n        self.sound = sound\n        \n    def printSound(self):\n        print(f\"El animal llamado {self.name} hace {self.sound}\")\n        \n    \nclass Perro(Animal):\n    def __init__(self, name, sound):\n        super().__init__(name, sound)\n        \n        \nclass Gato(Animal):\n    def __init__(self, name, sound):\n        super().__init__(name, sound)\n        \n\n# DIFICULTAD EXTRA\nclass Empresa:\n    def __init__(self, name, year_creation, employees = []):\n        self.name = name\n        self.year_creation = year_creation\n        self.employees = []\n        if employees is not None:\n            for e in employees:\n                self.employees.append(e)\n    \n    def showEmployees(self):\n        if len(self.employees):\n            print(\"--------LISTA DE EMPLEADOS--------\")\n            print('\\n'.join(str(f\"- {e}\") for e in self.employees))\n        else:\n            print(f\"La empresa {self.name} no tiene empleados\")\n\nclass Empleado:\n    def __init__(self, oid, name, category):\n        self.oid = oid\n        self.name = name\n        self.category = category\n    \n    def __str__(self):\n        return f\"El empleado {self.name} tiene la categoría de {self.category}\"\n\nclass Gerente(Empleado):\n    def __init__(self, oid, name, employees = []):\n        super().__init__(oid, name, \"Gerente\")\n        self.employees = []\n        if employees is not None:\n            for e in employees:\n                self.employees.append(e)\n    \n    def showEmployees(self):\n        if len(self.employees):\n            print(\"--------LISTA DE EMPLEADOS--------\")\n            print('\\n'.join(str(f\"- {e}\") for e in self.employees))\n        else:\n            print(f\"El empleado {self.name} no tiene empleados a su cargo\")\n\nclass GetenteProyectos(Empleado):\n    def __init__(self, oid, name, proyectos = []):\n        super().__init__(oid, name, \"Gerente de proyectos\")\n        self.proyectos = []\n        if proyectos is not None:\n            for p in proyectos:\n                self.proyectos.append(p)\n    \n    def showProyects(self):\n        print(f\"El empleado {self.name} tiene los siguientes proyectos a su cargo:\")\n        print(self.proyectos)\n\n\nclass Programador(Empleado):\n    def __init__(self, oid, name, len_prog):\n        super().__init__(oid, name, \"Programador\")\n        self.leng_prog = len_prog\n    \n    def coding(self):\n        print(f\"El empleado {super().name} ha empezado a picar código en {self.leng_prog}\")\n        \n\nif __name__ == \"__main__\":\n\n    print(\"----------------------CLASE----------------------------\")\n    miPerro = Perro(\"Kala\", \"guau\")\n    miGato = Gato(\"Michi\", \"miau\")\n    \n    miPerro.printSound()\n    miGato.printSound()\n    \n    # DIFICULTAD EXTRA\n    developers = [GetenteProyectos(3, \"Lucia Domingo Anaya\", [\"ERP\", \"Pagina Web\"]), Programador(2, \"Mario Garcia Arnaiz\", \"c#\"), Programador(4, \"Ana Gonzalez Diez\", \"python\")]\n    all_employees = [Gerente(1, \"Juan Lopez Ramirez\", developers)]\n    all_employees.extend(developers)\n    miEMpresa = Empresa(\"PEPITO S.L.\", 2019, all_employees)\n    miEMpresa.showEmployees()\n    print(all_employees[0].showEmployees())\n    print(all_employees[1].showProyects())\n\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/evilpotato04.py",
    "content": "#/*\n# * EJERCICIO:\n# * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n# * implemente una superclase Animal y un par de subclases Perro y Gato,\n# * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n\nclass animal:\n    nombre = \"\"\n    especies = \"\"\n    \n    def add_nombre(self, nombre: str):\n        self.nombre = nombre\n\n    def sonido(self):\n        pass\n\n    def mensaje(self):\n        print(f\"El {self.especies} se llama {self.nombre}\")\n        print(\"Tu sonido es:\")\n        self.sonido()\n\nclass perro(animal):\n    def __init__(self, especies = \"perro\"):\n        self.especies = especies\n\n    def sonido(self):\n        print(\"woof woof\")\n\nclass gato(animal):\n    def __init__(self, especies = \"gato\"):\n        self.especies = especies\n\n    def sonido(self):\n        print(\"meow meow\")\n\nperro = perro()\ngato = gato()\n\nperro.add_nombre(\"Aang\")\ngato.add_nombre(\"Katara\")\n\nperro.mensaje()\ngato.mensaje()\n\n# *\n# * DIFICULTAD EXTRA (opcional):\n# * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n# * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n# * Cada empleado tiene un identificador y un nombre.\n# * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n# * actividad, y almacenan los empleados a su cargo.\n# */\n\nclass empleado:\n    def __init__(self, identificador: str, nombre: str):\n        self.identificador = identificador\n        self.nombre = nombre\n\nclass gerente(empleado):\n    def oprimir_empleado(self, nombre_empleado):\n        print(f\"El {self.cargo} {self.nombre} oprimió al empleado {nombre_empleado}.\")\n    \n    def declararse_en_quiebra(self):\n        print(f\"El {self.cargo} {self.nombre} se declaró en quiebra\")\n\nclass gerente_de_proyecto(gerente):\n    cargo = \"Gerente de Proyecto\"\n\n    def ordenar_desarrollo(self):\n        print(f\"El {self.cargo} {self.nombre} ordenó el desarrollo de una nueva feature\")\n\n    def quejarse_del_proyecto(self, nombre_proyecto):\n        print(f\"El {self.cargo} {self.nombre} se quejó del proyecto {nombre_proyecto}.\")\n\nclass programador(empleado):\n    cargo = \"Programador\"\n    features_desarrolladas = 0\n\n    def desarrollar_feature(self, nombre_feature):\n        print(f\"El {self.cargo} {self.nombre} desarrolló el feature {nombre_feature}.\")\n        self.features_desarrolladas += 1\n\ndef dia_de_trabajo():\n    gerente = gerente_de_proyecto(1, \"Tom Nook\")\n    prog_1 = programador(2, \"Timmy\")\n    prog_2 = programador(3, \"Tommy\")\n    features = 0\n\n    print(\"\\n===== ANIMAL COSSING ENTERPRISE =====\\n\")\n    print(\"Departamento de TI:\")\n    print(f\" -> {gerente.cargo}: {gerente.nombre}\")\n    print(f\" -> {prog_1.cargo}: {prog_1.nombre}\")\n    print(f\" -> {prog_2.cargo}: {prog_2.nombre}\")\n\n    print(\"\\n** Comenzó la jornada laboral **\\n\")\n\n    try:\n        features = int(input(\"¿Cuántos proyectos deberían realizarse hoy? \"))\n    except:\n        print(\"\\nLa cantidad de features no tiene sentido... :(\")\n        gerente.oprimir_empleado(prog_1.nombre)\n        gerente.oprimir_empleado(prog_2.nombre)\n        gerente.declararse_en_quiebra()\n        return\n    \n    while features > 0:\n        print(\"\")\n        gerente.ordenar_desarrollo()\n        prog_1.desarrollar_feature(\"numero \" + str(features+0.1))\n        gerente.oprimir_empleado(prog_1.nombre)\n        print(\"\")\n\n        gerente.ordenar_desarrollo()\n        prog_2.desarrollar_feature(\"numero \" + str(features+0.2))\n        gerente.oprimir_empleado(prog_2.nombre)\n        print(\"\")\n\n        gerente.quejarse_del_proyecto(\"numero \" + str(features))\n        features -= 1\n    \n    print(\"** La jornada laboral ha terminado **\\n\")\n    gerente.declararse_en_quiebra()\n    print(\"\\n\\n\")\n\ndia_de_trabajo()"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/fborjalv.py",
    "content": "\n\nclass Animal: \n    def __init__(self, name: str):\n        self.name = name\n    def make_sound():\n        print(\"Esta clase no hace ruido\")\n\n\nclass Dog(Animal): \n    def make_sound(self):\n        print(\"Guau\")\n        \nclass Cat(Animal):\n\n    def make_sound(self):\n        print(\"miau\")\n\n\nmy_dog = Dog(\"Currito\")\nmy_dog.make_sound()\n\nmy_cat = Cat(\"Don Gato\")\nmy_cat.make_sound()\nprint(my_cat.name)\n\n\n\"\"\"DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n\"\"\"\n\nclass Employee:\n    def __init__(self, id: int, name: str):\n        self.id = id\n        self.name = name\n        self.employees = []\n    \n    def add_employee(self, employees):\n        self.employees.append(employees)\n    def show_employee(self):\n        return self.employees\n\nclass Manager(Employee):\n    def coordinate_projects(self):\n        print(f\"{self.name} está coordinando varios proyectos\")\n\nclass ProjectManager(Employee):\n    def __init__(self, id: int, name: str, project: str):\n        super().__init__(id, name)\n        self.project = project\n\n    def coordinate_project(self):\n        print(f\"{self.name} está coordinando {self.project}\")\n\n\n\nclass Developer(Employee):\n\n    def __init__(self, id: int, name: str, languages: str):\n        super().__init__(id, name)\n        self.language = languages\n    def coding(self):\n        print(f\"{self.name} está programando en {self.language}\")\n\n\n\nmy_manager = Manager(53, \"Loli\")\nmy_manager.coordinate_projects()\n\nmy_project_manager = ProjectManager(2, \"Brais\", \"Data Analysis\")\nmy_project_manager.coordinate_project()\n\nmy_developer = Developer(13, \"Pilar\", \"Pyton\")\nmy_developer.coding()\nprint(my_developer.name)\nprint(my_developer.id)\nprint(my_developer.language)\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/garos01.py",
    "content": "# Herencia\n\n\nclass Animal:\n    def __init__(self, nombre):\n        self.nombre = nombre\n\n    def hacer_sonido(self):\n        pass\n\n\nclass Perro(Animal):\n    def hacer_sonido(self):\n        return \"Guau\"\n\n\nclass Gato(Animal):\n    def hacer_sonido(self):\n        return \"Miau\"\n\n\ndef imprimir_sonido(animal):\n    tipo_animal = type(animal).__name__\n    print(f\"{animal.nombre} mi {tipo_animal} hace: {animal.hacer_sonido()}\")\n\n\nmi_perro = Perro(\"Buddy\")\nmi_gato = Gato(\"Whiskers\")\n\nimprimir_sonido(mi_perro)\nimprimir_sonido(mi_gato)\n\n# Ejercicio extra\n\n\nclass Empleado:\n    def __init__(self, identificador, nombre):\n        self.identificador = identificador\n        self.nombre = nombre\n\n    def realizar_tarea(self):\n        pass\n\n\nclass Gerente(Empleado):\n    def __init__(self, identificador, nombre, departamento):\n        super().__init__(identificador, nombre)\n        self.departamento = departamento\n        self.empleados_a_cargo = []\n\n    def asignar_tarea(self, tarea):\n        print(f\"El gerente {self.nombre} asigna la tarea: {tarea}\")\n\n    def realizar_tarea(self):\n        print(f\"El gerente {self.nombre} está gestionando el departamento.\")\n\n\nclass GerenteProyecto(Gerente):\n    def __init__(self, identificador, nombre, departamento, proyecto):\n        super().__init__(identificador, nombre, departamento)\n        self.proyecto = proyecto\n\n    def realizar_tarea(self):\n        print(\n            f\"El gerente de proyecto {self.nombre} está supervisando el proyecto {self.proyecto}.\"\n        )\n\n\nclass Programador(Empleado):\n    def __init__(self, identificador, nombre, lenguaje):\n        super().__init__(identificador, nombre)\n        self.lenguaje = lenguaje\n\n    def codificar(self):\n        print(f\"El programador {self.nombre} está codificando en {self.lenguaje}.\")\n\n    def realizar_tarea(self):\n        self.codificar()\n\n\ngerente_jefe = Gerente(1, \"Ana\", \"Desarrollo\")\ngerente_proyecto1 = GerenteProyecto(2, \"Carlos\", \"Desarrollo\", \"ProyectoX\")\ngerente_proyecto2 = GerenteProyecto(3, \"Diana\", \"Desarrollo\", \"ProyectoY\")\ngerente_proyecto3 = GerenteProyecto(4, \"Eduardo\", \"QA\", \"ProyectoZ\")\nprogramador1 = Programador(5, \"Fernando\", \"Python\")\nprogramador2 = Programador(6, \"Gabriela\", \"Java\")\nprogramador3 = Programador(7, \"Hugo\", \"C++\")\nprogramador4 = Programador(8, \"Isabel\", \"JavaScript\")\nprogramador5 = Programador(9, \"Javier\", \"Ruby\")\nprogramador6 = Programador(10, \"Karen\", \"Swift\")\n\ngerente_jefe.empleados_a_cargo.extend(\n    [\n        gerente_proyecto1,\n        gerente_proyecto2,\n        gerente_proyecto3,\n        programador1,\n        programador2,\n        programador3,\n        programador4,\n        programador5,\n        programador6,\n    ]\n)\n\ngerente_jefe.asignar_tarea(\"Planificación anual\")\nfor empleado in gerente_jefe.empleados_a_cargo:\n    empleado.realizar_tarea()\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/ggilperez.py",
    "content": "# Problem 09 inheritance\n\nclass Animal:\n\n    def speak(self):\n        raise NotImplementedError()\n\n\nclass Dog(Animal):\n\n    def speak(self):\n        print(\"Goof Goof\")\n\n\nclass Cat(Animal):\n\n    def speak(self):\n        print(\"Meow!\")\n\n\ndog = Dog()\ndog.speak()\n\ncat = Cat()\ncat.speak()\n\n\n# Extra\n\nclass Employee:\n\n    def __init__(self, identifier, name):\n        self.id = identifier\n        self.name = name\n        self.employees = []\n\n    def show_employees(self):\n        print(f\"'{self.name} ({self.id})' employees:\")\n        for employee in self.employees:\n            print(employee.name)\n\n    def add_employee(self, employee):\n        self.employees.append(employee)\n\n\nclass Manager(Employee):\n\n    def __init__(self, identifier, name):\n        super().__init__(identifier, name)\n\n    def current_job(self):\n        print(f\"Manager '{self.name} ({self.id})' in charge of all the projects.\")\n\n\nclass ProjectManager(Employee):\n\n    def __init__(self, identifier, name, project):\n        super().__init__(identifier, name)\n        self.project = project\n\n    def current_job(self):\n        print(f\"PM '{self.name} ({self.id})' in charge of '{self.project}' project.\")\n\n\nclass Developer(Employee):\n\n    def __init__(self, identifier, name, language):\n        super().__init__(identifier, name)\n        self.language = language\n\n    def current_job(self):\n        print(f\"Developer '{self.name} ({self.id})' programs in '{self.language}'.\")\n\n    def show_employees(self):\n        print(\"Developers can have other employees in charge.\")\n\n    def add_employee(self, employee):\n        print(\"Developers can have other employees in charge.\")\n\n\nmanager = Manager(1, \"Foo\")\npm = ProjectManager(2, \"Bar\", \"Proyectito\")\ndev = Developer(3, \"FB\", \"Python\")\n\nmanager.add_employee(pm)\nmanager.add_employee(dev)\nmanager.show_employees()\nmanager.current_job()\n\npm.current_job()\npm.add_employee(dev)\npm.show_employees()\n\ndev.current_job()\ndev.add_employee(pm)\ndev.show_employees()\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/gjbecerrae.py",
    "content": "class animal:\n    def caminar(self):\n        print('camino en 4 patas')\n\nclass perro(animal):\n    def sonido(self):\n        print('hago guau guau')\n\nclass gato(animal):\n    def sonido(self):\n        print('hago miau')\n\n#tobias = perro()\n#tobias.caminar()\n#tobias.sonido()\n\n#matias = gato()\n#matias.sonido()\n\n### Dificultad Extra ###\n        \nclass empleado:\n    def __init__(self, id, name) -> None:\n        self.id = id\n        self.name = name\n\nclass gerente(empleado):\n    region = 'latam'\n    salario = '15000 USD'\n\n    def __init__(self, id, name) -> None:\n        super().__init__(id, name)\n        self.empleadosACargoGerente = []\n\n    def firmar(self):\n        print('Firmo los cheques del pago de los empleados')\n\n    def nuevoEmpleadosCargo(self, nombre):\n        self.empleadosACargoGerente.append(nombre)\n\nclass gerenteDeProyecto(empleado):\n    region = 'Argentina'\n\n    def __init__(self, id, name) -> None:\n        super().__init__(id, name)\n        self.empleadosACargoGerenteDeProyectos = []\n\n    def gant(self):\n        print('se hacer diagramas de gant')\n\n    def nuevoEmpleadosCargo(self, nombre):\n        self.empleadosACargoGerenteDeProyectos.append(nombre)\n\nclass programador(empleado):\n    region = 'Colombia'\n    def __init__(self, id, name, lenguage) -> None:\n        super().__init__(id, name)\n        self.lenguage = lenguage\n\n    def programar(self):\n        print(f'programo en {self.lenguage}')\n\njefe = gerente('1', 'Christian H')\nprint(f'El salario de {jefe.name} es {jefe.salario}')\n\nsegundo = gerenteDeProyecto('2','Joe V')\ndriver = programador('3','Max V','Python')\n\njefe.nuevoEmpleadosCargo('Joe V')\njefe.nuevoEmpleadosCargo('Max V')\nsegundo.nuevoEmpleadosCargo('Max V')\n\nprint(f'Los empleados a cargo de {jefe.name} son {jefe.empleadosACargoGerente[0]} y {jefe.empleadosACargoGerente[1]} ')\n\n\n\n\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/gringoam.py",
    "content": "\"\"\"\nEjercicio\n\n\"\"\"\n\nclass Animal:\n\n    def __init__(self) -> None:\n        pass\n\n    def sonido():\n        pass\n\nclass Perro(Animal):\n\n    def sonido(self):\n        print(\"Guaau\")\n\nclass Gato(Animal):\n\n    def sonido(self):\n        print(\"Miauu\")\n\n\nperro= Perro()\ngato= Gato()\n\ndef sonido_de_aimal(ani:Animal):\n    ani.sonido()\n\nsonido_de_aimal(perro)\nsonido_de_aimal(gato)\n\n\n\"\"\"\nExtra\n\n\"\"\"\n\n#Empleado\n\nclass Empleado:\n\n    def __init__(self, id:int, nombre:str) :\n        self.id=id\n        self.nombre= nombre\n        self.empl_a_cargo=[]\n\n    def agregar_empleado(self, empleado):\n        \n        self.empl_a_cargo.append(empleado)\n\n    def a_cargo(self):\n        for emp in self.empl_a_cargo:\n            print(emp.nombre)\n\n    \n#Gerente\n\nclass Gerente(Empleado):\n     \n     def proyectos(self):\n        print(f\"{self.nombre} está coordinando todos los proyectos\")\n\nclass GerenteDeProyectos(Empleado):\n\n    def __init__(self, id:int, nombre:str, proyecto:str):\n        super().__init__(id, nombre)\n        self.proyecto= proyecto\n\n    def proyect(self):\n        print(f\"{self.nombre} está coordinando su proyecto\")\n\n#Programador\n\nclass Programador(Empleado):\n\n    def __init__(self, id:int, nombre:str, lenguje:str):\n        super().__init__(id, nombre)\n        self.lenguje= lenguje\n\n\n    def lenguaje (self):\n        print(f\"{self.nombre} está programando en {self.lenguje}\")\n\n    def agregar_empleado(self, emp: Empleado):\n        print(f\"Un programador no tiene empleados a cargo {emp.nombre} no se agregara\")\n\n\nmy_manager = Gerente(1, \"Masip\")\nmy_project_manager = GerenteDeProyectos(2, \"Ariel\", \"Proyecto 1\")\nmy_project_manager2 = GerenteDeProyectos(3, \"Diego\", \"Proyecto 2\")\nmy_programmer = Programador(4, \"Ciro\", \"Swift\")\nmy_programmer2 = Programador(5, \"Amadeo\", \"Cobol\")\nmy_programmer3 = Programador(6, \"Sil\", \"Dart\")\nmy_programmer4 = Programador(7, \"Ramona\", \"Python\")\n\nmy_manager.agregar_empleado(my_project_manager)\nmy_manager.agregar_empleado(my_project_manager2)\n\nmy_project_manager.agregar_empleado(my_programmer)\nmy_project_manager.agregar_empleado(my_programmer2)\nmy_project_manager2.agregar_empleado(my_programmer3)\nmy_project_manager2.agregar_empleado(my_programmer4)\n\nmy_programmer.agregar_empleado(my_programmer2)\n\nmy_programmer.lenguaje()\nmy_project_manager.proyect()\nmy_manager.proyectos()\nmy_manager.a_cargo()\nmy_project_manager.a_cargo()\nmy_programmer.a_cargo()\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/haroldAlb.py",
    "content": "# EJERCICIO #\nclass Animal():\n    def __init__(self, nombre, patas, pelo):\n        self.__nombre = nombre\n        self.__patas = patas\n        self.__pelo = pelo\n        \n    def moverse(self):\n        return f\"{self.__nombre} se está moviendo... \"\n    \n    def sonido(self):\n        pass\n\nclass Perro(Animal):\n    def __init__(self, nombre, patas, pelo, cola):\n        super().__init__(nombre, patas, pelo)\n        self.__cola = cola\n\n    def sonido(self):\n        print(\"Guau, guau!!!\")\n\nclass Gato(Animal):\n    def __init__(self, nombre, patas, pelo, uñas):\n        super().__init__(nombre, patas, pelo)\n        self.__uñas = uñas\n\n    def sonido(self):\n        print(\"Miaaaaaaw!!!\")\n\ndef sonido_animal(Animal):\n    Animal.sonido()\n\n# EXTRA #\nclass Empleado:\n    def __init__(self, id: int, nombre: str):\n        self.id = id\n        self.nombre = nombre\n        self.empleados = []\n\n    def añadir_empleado(self, empleado):\n        self.empleados.append(empleado)\n\n    def imprimir_empleados(self):\n        print(f\"Empleados a cargo de {self.nombre}\")\n        for empleado in self.empleados:\n            print(empleado.nombre)\n        \n\nclass Gerente(Empleado):\n    def coordinar(self):\n        print(f\"{self.nombre} está coordinanado todos los proyectos de la empresa.\")\n\nclass GerenteProyecto(Empleado):\n    def __init__(self, id, nombre, proyecto: str):\n        super().__init__(id, nombre)\n        self.proyecto = proyecto\n\n    def coordinar_proyecto(self):\n        print(f\"{self.nombre} está coordinando su proyecto.\")\n\nclass   Programador(Empleado):\n    def __init__(self, id, nombre, lenguaje: str):\n        super().__init__(id, nombre)\n        self.lenguaje = lenguaje\n\n    def programar(self):\n        print(f\"{self.nombre} está programando en {self.lenguaje}\")\n\n    def añadir_empleado(self, empleado: Empleado): # Al parámetro le estamos especificando que debe ser de la clase Empleado y heredará todo lo de este\n        print(f\"Los programadores no tienen empleados a su cargo. {empleado.nombre} no se añadirá.\") # Ahora al poner el parámetro y un atributo de la super clase nos saldrá el nombre que hayamos puesto al hacer la instancia del objeto\n\nif __name__ == \"__main__\":\n\n    # EJERCICIO #\n    print(\"#\"*15 + \" EJERCICIO \" + \"#\"*15)\n\n    perro = Perro(\"Kiwi\", 4, \"Corto\", \"Larga\")\n    gato = Gato(\"Kiko\", 3, \"largo\", True)\n    sonido_animal(perro)\n    sonido_animal(gato)\n\n    # EXTRA #\n    print(\"#\"*15 + \" EXTRA \" + \"#\"*15)\n\n    gerente = Gerente(1, \"Mario\")\n    ger_proyec1 = GerenteProyecto(2, \"Olga\", \"Proyecto1\")\n    ger_proyec2 = GerenteProyecto(3, \"Harold\", \"Proyecto2\")\n    prog1 = Programador(4, \"Ana\", \"Python\")\n    prog2 = Programador(5, \"Cloe\", \"labView\")\n    prog3 = Programador(6, \"Samanta\", \"C#\")\n    prog4 = Programador(7, \"Julia\", \"HTML\")\n\n    gerente.coordinar()\n    ger_proyec1.coordinar_proyecto()\n    ger_proyec2.coordinar_proyecto()\n    prog1.programar()\n    prog2.programar()\n    prog3.programar()\n    prog4.programar()\n\n\n    gerente.añadir_empleado(ger_proyec1)\n    gerente.añadir_empleado(ger_proyec2)\n    ger_proyec1.añadir_empleado(prog1)\n    ger_proyec1.añadir_empleado(prog2)\n    ger_proyec2.añadir_empleado(prog3)\n    ger_proyec2.añadir_empleado(prog4)\n    prog1.añadir_empleado(prog4) # En vez de ejecutar el método de la super clase Empleado, hará el método de la clase hija Programador\n\n    gerente.imprimir_empleados()\n    ger_proyec1.imprimir_empleados()\n    ger_proyec2.imprimir_empleados()\n    prog1.imprimir_empleados() # no se imprimira ningún nombre\n   \n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/hectordbh.py",
    "content": "\"\"\"EJERCICIO\n\"\"\"\nclass Animal():\n    \"\"\"Clase para establecer características comunes\n    de los animales en este ejercicio\n    \"\"\"\n    def __init__(self, paws, condition):\n        self.paws = paws\n        self.condition = condition\n\n    def __str__(self):\n        return f\"Este animal tiene {self.paws} patas, es {self.condition}\"\n\nclass Perro(Animal):\n    \"\"\"Clase que establece alguna característica particular\n    de un perro\n\n    Args:\n        Animal (class): clase padre\n    \"\"\"\n    def sound(self):\n        \"\"\"Método que indica qué sonido hace el perro\n        \"\"\"\n        return \"Guau\"\n\n    def __str__(self):\n        return f\"{super().__str__()} y el sonido que hace es '{self.sound()}'\"\n\nclass Gato(Animal):\n    \"\"\"Clase que establece alguna característica particular\n    de un gato\n\n    Args:\n        Animal (class): clase padre\n    \"\"\"\n    def sound(self):\n        \"\"\"Método que indica qué sonido hace el perro\n        \"\"\"\n        return \"Miau\"\n\n    def __str__(self):\n        return f\"{super().__str__()} y el sonido que hace es '{self.sound()}'\"\n\n# --------------- COMPROBACIONES DEL EJERCICIO --------------\n\npia = Perro(4, \"doméstico\")\nrufus = Gato(4, \"salvaje\")\n\nprint(pia)\nprint(rufus)\n\n# --------------------- DIFICULTAD EXTRA --------------------\nclass Employee():\n    \"\"\"Clase que establece los datos comunes de todos los\n    empleados de la empresa\n    \"\"\"\n    def __init__(self, name, identify):\n        self.name = name\n        self.id = identify\n\n    total = int()\n    organigram = {\"Gerente\": [], \"Gerente de Proyecto\": [], \"Desarrollador\": []}\n\n    \"\"\"Vamos a ver cómo integramos un método para conocer la cantidad de\n    empleados que hay en la empresa\"\"\"\n    @classmethod\n    def add_employee(cls, name, category):\n        \"\"\"Método de clase para añadir el empleado a la empresa cuando se crea\n        la instancia\n        \"\"\"\n        cls.total += 1\n        cls.organigram[category].append(name)\n\n    @classmethod\n    def functions(cls, t):\n        \"\"\"Método para mostrar las funciones del empleado\n\n        Args:\n            t (tuple): tupla con todas las funciones que realiza el empleado\n        \"\"\"\n        for item in t:\n            print(f\"- {item}\")\n\n    @classmethod\n    def advntg(cls, pros):\n        \"\"\"Método (propiedad) que muestra los pros de esta categoría\n        \"\"\"\n        for key, value in pros.items():\n            print(f\"- {key}: {value}\")\n\nclass Manager(Employee):\n    \"\"\"Clase que establece las propiedades y características de los \n    gerentes de la empresa\n\n    Args:\n        Employee (class): clase padre\n    \"\"\"\n    def __init__(self, name, identify):\n        self.category = \"Gerente\"\n        super().__init__(name, identify)\n        Employee.add_employee(name, self.category)\n\n    dicc = {\"Salario\": 3000, \"Coche de empresa\": \"Sí\", \"Dietas\": \"Sí\", \"Pagas\": 14,\n            \"Dividendos\": \"Sí\", \"Vacaciones\": 28, \"Asuntos propios\": 10}\n    tpl = (\"Organizar y planificar\", \"Controlar plazos\", \"Estimular la productividad\",\n           \"Ser un líder\", \"Motivar a su grupo de trabajo\", \"Resolución de problemas\")\n\n    @classmethod\n    def pros(cls):\n        \"\"\"Método (propiedad) que muestra los pros de esta categoría\n        \n        Returns:\n            Las ventajas línea a línea\n        \"\"\"\n        super().advntg(cls.dicc)\n\n    @classmethod\n    def function(cls):\n        \"\"\"Método que muestra las funciones del gerente\n\n        Returns:\n            Las funciones línea a línea\n        \"\"\"\n        super().functions(cls.tpl)\n\n    @classmethod\n    def components(cls):\n        \"\"\"Método de clase para saber los empleados de esta categoría\n        \"\"\"\n        print(\"\\nGERENTES:\")\n        for i in range(len(Employee.organigram[\"Gerente\"])):\n            print(f\"- {Employee.organigram[\"Gerente\"][i]}\")\n\nclass ProjectManager(Employee):\n    \"\"\"Clase que establece las propiedades y características de los \n    Gerentes de proyectos de la empresa\n\n    Args:\n        Employee (class): clase padre\n    \"\"\"\n    def __init__(self, name, identify):\n        self.category = \"Gerente de Proyecto\"\n        super().__init__(name, identify)\n        Employee.add_employee(name, self.category)\n\n    dicc = {\"Salario\": 2200, \"Coche de empresa\": \"No\", \"Dietas\": \"Sí\", \"Pagas\": 14,\n            \"Dividendos\": \"No\", \"Vacaciones\": 26, \"Asuntos propios\": 8}\n    tpl = (\"Realizar estudios de mercado\", \"Controlar plazos y calidades\", \"Estimar recursos\",\n           \"Establecer plan de progreso\", \"Gestión de proveedores\",\n           \"Monitorizar el progreso del proyecto\")\n\n    @classmethod\n    def pros(cls):\n        \"\"\"Método (propiedad) que muestra los pros de esta categoría\n        \n        Returns:\n            Las ventajas línea a línea\n        \"\"\"\n        super().advntg(cls.dicc)\n\n    @classmethod\n    def function(cls):\n        \"\"\"Método que muestra las funciones del gerente\n\n        Returns:\n            Las funciones línea a línea\n        \"\"\"\n        super().functions(cls.tpl)\n\n    @classmethod\n    def components(cls):\n        \"\"\"Método de clase para saber los empleados de esta categoría\n        \"\"\"\n        print(\"\\nGERENTES DE PROYECTO:\")\n        for i in range(len(Employee.organigram[\"Gerente de Proyecto\"])):\n            print(f\"- {Employee.organigram[\"Gerente de Proyecto\"][i]}\")\n\nclass Developer(Employee):\n    \"\"\"Clase que establece las propiedades y características de los \n    Desarrolladores\n\n    Args:\n        Employee (class): clase padre\n    \"\"\"\n    def __init__(self, name, identify):\n        self.category = \"Desarrollador\"\n        super().__init__(name, identify)\n        Employee.add_employee(name, self.category)\n\n    dicc = {\"Salario\": 1700, \"Coche de empresa\": \"No\", \"Dietas\": \"No\", \"Pagas\": 14,\n            \"Dividendos\": \"No\", \"Vacaciones\": 24, \"Asuntos propios\": 8}\n    tpl = (\"Crear programas y sistemas eficientes\", \"Reparar o mejorar software existente\",\n           \"Realizar pruebas\", \"Códigos eficientes y escalables\", \"Trabajar de forma colaborativa\")\n\n    @classmethod\n    def pros(cls):\n        \"\"\"Método (propiedad) que muestra los pros de esta categoría\n        \n        Returns:\n            Las ventajas línea a línea\n        \"\"\"\n        super().advntg(cls.dicc)\n\n    @classmethod\n    def function(cls):\n        \"\"\"Método que muestra las funciones del gerente\n\n        Returns:\n            Las funciones línea a línea\n        \"\"\"\n        super().functions(cls.tpl)\n\n    @classmethod\n    def components(cls):\n        \"\"\"Método de clase para saber los empleados de esta categoría\n        \"\"\"\n        print(\"\\nGERENTES DE PROYECTO:\")\n        for i in range(len(Employee.organigram[\"Desarrollador\"])):\n            print(f\"- {Employee.organigram[\"Desarrollador\"][i]}\")\n\n# -------------- COMPROBACIONES DIFICULTAD EXTRA -------------\n\nemp1 = Manager(\"Raúl\", \"001\")\nemp2 = ProjectManager(\"Malena\", \"002\")\nemp3 = ProjectManager(\"Jose\", \"003\")\nemp4 = ProjectManager(\"Miriam\", \"004\")\nemp5 = Developer(\"Mario\", \"005\")\nemp6 = Developer(\"Rita\", \"006\")\nemp7 = Developer(\"Emilio\", \"007\")\nemp8 = Developer(\"Macarena\", \"008\")\nprint(f\"\\nTOTAL DE EMPLEADOS: {Employee.total}\")\n\n# Gerente\nManager.components()\nprint(\"\\nFUNCIONES:\")\nManager.function()\nprint(\"\\nCONDICIONES:\")\nManager.pros()\nprint()\n\n# Gerentes de Proyecto\nProjectManager.components()\nprint(\"\\nFUNCIONES:\")\nProjectManager.function()\nprint(\"\\nCONDICIONES:\")\nProjectManager.pros()\nprint()\n\n# Desarrolladores\nDeveloper.components()\nprint(\"\\nFUNCIONES:\")\nDeveloper.function()\nprint(\"\\nCONDICIONES:\")\nDeveloper.pros()\nprint()\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/hectorio23.py",
    "content": "# Autor: Héctor Adán \n# GitHub: https://github.com/hectorio23\n\n'''\n/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n'''\n\n\n# Clase base Animal\nclass Animal:\n    def __init__(self, nombre, alimentacion, habitad_natural, edad):\n        self.nombre = nombre\n        self.alimentacion = alimentacion\n        self.habitad_natural = habitad_natural\n        self.edad = edad\n\n    # Método para hacer sonido del animal\n    def hacer_sonido(self):\n        print(\"Sonido de la clase Animal\")\n\n    # Método para mostrar los detalles del animal\n    def get_info(self):\n        print(f\"Nombre: {self.nombre}\")\n        print(f\"Alimentación: {self.alimentacion}\")\n        print(f\"Hábitat: {self.habitad_natural}\")\n        print(f\"Edad: {self.edad}\")\n\n# Clase derivada Perro\nclass Perro(Animal):\n    def __init__(self, nombre, alimentacion, habitad_natural, edad):\n        super().__init__(nombre, alimentacion, habitad_natural, edad)\n\n    # Método para hacer sonido del perro\n    def hacer_sonido(self):\n        print(\"¡Woow Woow!\")\n\n# Clase derivada Gato\nclass Gato(Animal):\n    def __init__(self, nombre, alimentacion, habitad_natural, edad):\n        super().__init__(nombre, alimentacion, habitad_natural, edad)\n\n    # Método para hacer sonido del gato\n    def hacer_sonido(self):\n        print(\"¡Miauu Miauu!\")\n\n# Clase base Empleado\nclass Empleado:\n    def __init__(self, nombre, identificador):\n        self.nombre = nombre\n        self.identificador = identificador\n\n    # Método para mostrar detalles del empleado\n    def mostrar_detalles(self):\n        print(f\"Nombre: {self.nombre}, ID: {self.identificador}\")\n\n# Clase derivada Gerente\nclass Gerente(Empleado):\n    def __init__(self, nombre, identificador):\n        super().__init__(nombre, identificador)\n        self.empleados_a_cargo = []\n\n    # Método para asignar empleado a cargo\n    def asignar_empleado(self, empleado):\n        self.empleados_a_cargo.append(empleado)\n\n    # Método para mostrar detalles del gerente y empleados a cargo\n    def mostrar_detalles(self):\n        print(f\"Gerente - Nombre: {self.nombre}, ID: {self.identificador}\")\n        print(\"Empleados a cargo:\")\n        for empleado in self.empleados_a_cargo:\n            empleado.mostrar_detalles()\n\n# Clase derivada GerenteProyecto\nclass GerenteProyecto(Gerente):\n    def __init__(self, nombre, identificador):\n        super().__init__(nombre, identificador)\n\n    # Método para mostrar detalles del gerente de proyecto\n    def mostrar_detalles(self):\n        print(f\"Gerente de Proyecto - Nombre: {self.nombre}, ID: {self.identificador}\")\n        print(\"Empleados a cargo:\")\n        for empleado in self.empleados_a_cargo:\n            empleado.mostrar_detalles()\n\n# Clase derivada Programador\nclass Programador(Empleado):\n    def __init__(self, nombre, identificador):\n        super().__init__(nombre, identificador)\n\n    # Método para mostrar detalles del programador\n    def mostrar_detalles(self):\n        print(f\"Programador - Nombre: {self.nombre}, ID: {self.identificador}\")\n\n# Programa principal\nif __name__ == \"__main__\":\n    # Creación de un gato\n    print(\"Instancia de la clase GATO:\")\n    g1 = Gato(\"Musides\", \"Omnívoro\", \"Hogar\", 1)\n    g1.hacer_sonido()  # Emite el sonido del gato\n    g1.get_info()  # Muestra los detalles del gato\n\n    print(\"------------------------------------\")\n\n    # Creación de un perro\n    print(\"Instancia de la clase PERRO:\")\n    p1 = Perro(\"Rufus\", \"Carnívoro\", \"Hogar\", 2)\n    p1.hacer_sonido()  # Emite el sonido del perro\n    p1.get_info()  # Muestra los detalles del perro\n\n    print(\"\\n\\n**********************************\\n\\n\")\n\n    # Ejercicio Extra: Creación de empleados y un gerente de proyecto\n    gerente_proyecto = GerenteProyecto(\"Juan\", 1001)\n    programador1 = Programador(\"Pedro\", 2001)\n    programador2 = Programador(\"Maria\", 2002)\n\n    # Asignación de empleados al gerente de proyecto\n    gerente_proyecto.asignar_empleado(programador1)\n    gerente_proyecto.asignar_empleado(programador2)\n\n    # Mostrar detalles del gerente de proyecto y empleados a su cargo\n    gerente_proyecto.mostrar_detalles()\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/hozlucas28.py",
    "content": "\"\"\"\n    Inheritance...\n\"\"\"\n\nfrom dataclasses import dataclass\nfrom typing import Self, Literal\n\n\n@dataclass\nclass Animal:\n    \"\"\"Animal class\"\"\"\n\n    _average_speed: float\n    _average_weight: float\n    _name: str\n    _sound: str | None\n\n    def set_average_speed(self, average_speed: float) -> Self:\n        \"\"\"Set a new average speed\"\"\"\n        self._average_speed = average_speed\n        return self\n\n    def set_average_weight(self, average_weight: float) -> Self:\n        \"\"\"Set a new average weight\"\"\"\n        self._average_weight = average_weight\n        return self\n\n    def set_name(self, name: str) -> Self:\n        \"\"\"Set a new name\"\"\"\n        self._name = name\n        return self\n\n    def set_sound(self, sound: str) -> Self:\n        \"\"\"Set a new sound\"\"\"\n        self._sound = sound\n        return self\n\n    def get_average_speed(self) -> float:\n        \"\"\"Return average speed\"\"\"\n        return self._average_speed\n\n    def get_average_weight(self) -> float:\n        \"\"\"Return average weight\"\"\"\n        return self._average_weight\n\n    def get_name(self) -> str:\n        \"\"\"Return name\"\"\"\n        return self._name\n\n    def get_sound(self) -> str | None:\n        \"\"\"Return sound\"\"\"\n        return self._sound\n\n    def get_attributes(self) -> str:\n        \"\"\"Return all attributes\"\"\"\n        return (\n            f\"Average speed --> {self.get_average_speed()}\"\n            + f\"\\nAverage_weight --> {self.get_average_weight()}\"\n            + f\"\\nName --> {self.get_name()}\"\n        )\n\n    def print_sound(self) -> Self:\n        \"\"\"Print sound\"\"\"\n        print(f\"\\n{self.get_sound()}\")\n        return self\n\n\n@dataclass\nclass Dog(Animal):\n    \"\"\"Dog class\"\"\"\n\n    _owner_name: str\n    _owner_phone: str\n\n    def get_owner_name(self) -> str:\n        \"\"\"Return owner name\"\"\"\n        return self._owner_name\n\n    def get_owner_phone(self) -> str:\n        \"\"\"Return owner phone\"\"\"\n        return self._owner_phone\n\n    def set_owner_name(self, owner_name: str) -> Self:\n        \"\"\"Set a new owner name\"\"\"\n        self._owner_name = owner_name\n        return self\n\n    def set_owner_phone(self, owner_phone: str) -> Self:\n        \"\"\"Set a new owner phone\"\"\"\n        self._owner_phone = owner_phone\n        return self\n\n    def get_attributes(self) -> str:\n        return (\n            super().get_attributes()\n            + f\"\\nOwner name --> {self.get_owner_name()}\"\n            + f\"\\nOwner phone --> {self.get_owner_phone()}\"\n        )\n\n\n@dataclass\nclass Cat(Animal):\n    \"\"\"Cat class\"\"\"\n\n    _owner_name: str\n    _owner_phone: str\n\n    def get_owner_name(self) -> str:\n        \"\"\"Return owner name\"\"\"\n        return self._owner_name\n\n    def get_owner_phone(self) -> str:\n        \"\"\"Return owner phone\"\"\"\n        return self._owner_phone\n\n    def set_owner_name(self, owner_name: str) -> Self:\n        \"\"\"Set a new owner name\"\"\"\n        self._owner_name = owner_name\n        return self\n\n    def set_owner_phone(self, owner_phone: str) -> Self:\n        \"\"\"Set a new owner phone\"\"\"\n        self._owner_phone = owner_phone\n        return self\n\n    def get_attributes(self) -> str:\n        return (\n            super().get_attributes()\n            + f\"\\nOwner name --> {self.get_owner_name()}\"\n            + f\"\\nOwner phone --> {self.get_owner_phone()}\"\n        )\n\n\nprint(\"Inheritance in Python...\")\n\nprint(\n    \"\"\"\\nfrom dataclasses import dataclass\nfrom typing import Self\n\n\n@dataclass\nclass Animal:\n    \\\"\\\"\\\"Animal class\\\"\\\"\\\"\n\n    _average_speed: float\n    _average_weight: float\n    _name: str\n    _sound: str | None\n\n    def set_average_speed(self, average_speed: float) -> Self:\n        \\\"\\\"\\\"Set a new average speed\\\"\\\"\\\"\n        self._average_speed = average_speed\n        return self\n\n    def set_average_weight(self, average_weight: float) -> Self:\n        \\\"\\\"\\\"Set a new average weight\\\"\\\"\\\"\n        self._average_weight = average_weight\n        return self\n\n    def set_name(self, name: str) -> Self:\n        \\\"\\\"\\\"Set a new name\\\"\\\"\\\"\n        self._name = name\n        return self\n\n    def set_sound(self, sound: str) -> Self:\n        \\\"\\\"\\\"Set a new sound\\\"\\\"\\\"\n        self._sound = sound\n        return self\n\n    def get_average_speed(self) -> float:\n        \\\"\\\"\\\"Return average speed\\\"\\\"\\\"\n        return self._average_speed\n\n    def get_average_weight(self) -> float:\n        \\\"\\\"\\\"Return average weight\\\"\\\"\\\"\n        return self._average_weight\n\n    def get_name(self) -> str:\n        \\\"\\\"\\\"Return name\\\"\\\"\\\"\n        return self._name\n\n    def get_sound(self) -> str | None:\n        \\\"\\\"\\\"Return sound\\\"\\\"\\\"\n        return self._sound\n\n    def get_attributes(self) -> str:\n        \\\"\\\"\\\"Return all attributes\\\"\\\"\\\"\n        return (\n            f\\\"Average speed --> {self.get_average_speed()}\\\"\n            + f\\\"\\\\nAverage_weight --> {self.get_average_weight()}\\\"\n            + f\\\"\\\\nName --> {self.get_name()}\\\"\n        )\n\n    def print_sound(self) -> Self:\n        \\\"\\\"\\\"Print sound\\\"\\\"\\\"\n        print(f\\\"\\\\n{self.get_sound()}\\\")\n        return self\n\n\n@dataclass\nclass Dog(Animal):\n    \\\"\\\"\\\"Dog class\\\"\\\"\\\"\n\n    _owner_name: str\n    _owner_phone: str\n\n    def get_owner_name(self) -> str:\n        \\\"\\\"\\\"Return owner name\\\"\\\"\\\"\n        return self._owner_name\n\n    def get_owner_phone(self) -> str:\n        \\\"\\\"\\\"Return owner phone\\\"\\\"\\\"\n        return self._owner_phone\n\n    def set_owner_name(self, owner_name: str) -> Self:\n        \\\"\\\"\\\"Set a new owner name\\\"\\\"\\\"\n        self._owner_name = owner_name\n        return self\n\n    def set_owner_phone(self, owner_phone: str) -> Self:\n        \\\"\\\"\\\"Set a new owner phone\\\"\\\"\\\"\n        self._owner_phone = owner_phone\n        return self\n\n    def get_attributes(self) -> str:\n        return (\n            super().get_attributes()\n            + f\\\"\\\\nOwner name --> {self.get_owner_name()}\\\"\n            + f\\\"\\\\nOwner phone --> {self.get_owner_phone()}\\\"\n        )\n\n\n@dataclass\nclass Cat(Animal):\n    \\\"\\\"\\\"Cat class\\\"\\\"\\\"\n\n    _owner_name: str\n    _owner_phone: str\n\n    def get_owner_name(self) -> str:\n        \\\"\\\"\\\"Return owner name\\\"\\\"\\\"\n        return self._owner_name\n\n    def get_owner_phone(self) -> str:\n        \\\"\\\"\\\"Return owner phone\\\"\\\"\\\"\n        return self._owner_phone\n\n    def set_owner_name(self, owner_name: str) -> Self:\n        \\\"\\\"\\\"Set a new owner name\\\"\\\"\\\"\n        self._owner_name = owner_name\n        return self\n\n    def set_owner_phone(self, owner_phone: str) -> Self:\n        \\\"\\\"\\\"Set a new owner phone\\\"\\\"\\\"\n        self._owner_phone = owner_phone\n        return self\n\n    def get_attributes(self) -> str:\n        return (\n            super().get_attributes()\n            + f\\\"\\\\nOwner name --> {self.get_owner_name()}\\\"\n            + f\\\"\\\\nOwner phone --> {self.get_owner_phone()}\\\"\n        )\"\"\"\n)\n\ndog = Dog(\n    _average_speed=21,\n    _average_weight=28,\n    _name=\"Angela\",\n    _owner_name=\"Lucas Hoz\",\n    _owner_phone=\"1134465758\",\n    _sound=\"Woof\",\n)\n\nprint(\n    \"\"\"\\n\\ndog = Dog(\n    _average_speed=21,\n    _average_weight=28,\n    _name=\\\"Angela\\\",\n    _owner_name=\\\"Lucas Hoz\\\",\n    _owner_phone=\\\"1134465758\\\",\n    _sound=\\\"Woof\\\",\n)\"\"\"\n)\n\nprint(\"\\nDog attributes...\\n\")\nprint(dog.get_attributes())\n\nprint(\"\\nDog sound...\")\ndog.print_sound()\n\ncat = Cat(\n    _average_speed=16,\n    _average_weight=14.68,\n    _name=\"Mini\",\n    _owner_name=\"Martin Gonzales\",\n    _owner_phone=\"1134485978\",\n    _sound=\"Meow\",\n)\n\nprint(\n    \"\"\"\\ncat = Cat(\n    _average_speed=16,\n    _average_weight=14.68,\n    _name=\\\"Mini\\\",\n    _owner_name=\\\"Martin Gonzales\\\",\n    _owner_phone=\\\"1134485978\\\",\n    _sound=\\\"Meow\\\",\n)\"\"\"\n)\n\nprint(\"\\nCat attributes...\\n\")\nprint(cat.get_attributes())\n\nprint(\"\\nCat sound...\")\ncat.print_sound()\n\n\n\"\"\"\n    Additional challenge...\n\"\"\"\n\nprint(\n    \"\\n# ---------------------------------------------------------------------------------- #\\n\"\n)\n\nprint(\"Additional challenge...\")\n\n\n@dataclass\nclass Employee:\n    \"\"\"Employee class\"\"\"\n\n    _first_name: str\n    _id: int\n    _last_name: str\n    _salary: float\n\n    def set_first_name(self, first_name: str) -> Self:\n        \"\"\"Set a new first name\"\"\"\n        self._first_name = first_name\n        return self\n\n    def set_id(self, new_id: int) -> Self:\n        \"\"\"Set a new first name\"\"\"\n        self._id = new_id\n        return self\n\n    def set_last_name(self, last_name: str) -> Self:\n        \"\"\"Set a new first name\"\"\"\n        self._last_name = last_name\n        return self\n\n    def set_salary(self, salary: float) -> Self:\n        \"\"\"Set a new first name\"\"\"\n        self._salary = salary\n        return self\n\n    def get_first_name(self) -> str:\n        \"\"\"Return first name\"\"\"\n        return self._first_name\n\n    def get_id(self) -> int:\n        \"\"\"Return first name\"\"\"\n        return self._id\n\n    def get_last_name(self) -> str:\n        \"\"\"Return first name\"\"\"\n        return self._last_name\n\n    def get_salary(self) -> float:\n        \"\"\"Return first name\"\"\"\n        return self._salary\n\n    def get_attributes(self) -> str:\n        \"\"\"Get all attributes\"\"\"\n        return (\n            f\"First name --> {self._first_name}\"\n            + f\"\\nId --> {self._id}\"\n            + f\"\\nLast name --> {self._last_name}\"\n            + f\"\\nSalary --> {self._salary}\"\n        )\n\n\ntype Side = Literal[\"Backend\", \"Frontend\", \"Full Stack\"]\n\n\n\n\n@dataclass\nclass Programmer(Employee):\n    \"\"\"Programmer class\"\"\"\n\n    _languages: list[str]\n    _side: Side\n\n    def set_languages(self, languages: list[str]) -> Self:\n        \"\"\"Set new languages\"\"\"\n        self._languages = languages\n        return self\n\n    def set_side(self, side: Side) -> Self:\n        \"\"\"Set new side\"\"\"\n        self._side = side\n        return self\n\n    def get_languages(self) -> list[str]:\n        \"\"\"Get languages\"\"\"\n        return self._languages\n\n    def get_side(self) -> Side:\n        \"\"\"Get side\"\"\"\n        return self._side\n\n    def get_attributes(self) -> str:\n        return (\n            super().get_attributes()\n            + f\"\\nLanguages --> {self.get_languages()}\"\n            + f\"\\nSide --> {self.get_side()}\"\n        )\n\n    def write_code(self, language: str) -> str:\n        \"\"\"Write code in the programming language of the programmer\"\"\"\n        return f\"Writing code in {language}\"\n\n\n@dataclass\nclass ProjectManager(Employee):\n    \"\"\"Project manager class\"\"\"\n\n    _functions: list[str]\n    _programmers: list[Programmer]\n\n    def set_functions(self, functions: list[str]) -> Self:\n        \"\"\"Set new functions\"\"\"\n        self._functions = functions\n        return self\n\n    def set_programmers(self, programmers: list[Programmer]) -> Self:\n        \"\"\"Set new programmers\"\"\"\n        self._programmers = programmers\n        return self\n\n    def get_functions(self) -> list[str]:\n        \"\"\"Return functions\"\"\"\n        return self._functions\n\n    def get_programmers(self) -> list[Programmer]:\n        \"\"\"Return programmers\"\"\"\n        return self._programmers\n\n    def get_attributes(self) -> str:\n        return (\n            super().get_attributes()\n            + f\"\\nFunctions --> {self.get_functions()}\"\n            + f\"\\nProgrammers --> {self.get_programmers()}\"\n        )\n\n    def make_management(self) -> str:\n        \"\"\"Make management stuffs\"\"\"\n        return \"Just a project manager doing everything expect programming.\"\n\n\n@dataclass()\nclass Manager(Employee):\n    \"\"\"Manager class\"\"\"\n\n    _department: str\n    _functions: list[str]\n    _project_managers: list[ProjectManager]\n\n    def set_department(self, department: str) -> Self:\n        \"\"\"Set new department\"\"\"\n        self._department = department\n        return self\n\n    def set_functions(self, functions: list[str]) -> Self:\n        \"\"\"Set new functions\"\"\"\n        self._functions = functions\n        return self\n\n    def set_project_managers(self, project_managers: list[ProjectManager]) -> Self:\n        \"\"\"Set new project managers\"\"\"\n        self._project_managers = project_managers\n        return self\n\n    def get_department(self) -> str:\n        \"\"\"Return department\"\"\"\n        return self._department\n\n    def get_functions(self) -> list[str]:\n        \"\"\"Return functions\"\"\"\n        return self._functions\n\n    def get_project_managers(self) -> list[ProjectManager]:\n        \"\"\"Return projects managers\"\"\"\n        return self._project_managers\n\n    def get_attributes(self) -> str:\n        return (\n            super().get_attributes()\n            + f\"\\nFunctions --> {self.get_functions()}\"\n            + f\"\\nProject managers --> {self.get_project_managers()}\"\n        )\n\n    def make_management(self) -> str:\n        \"\"\"Make management stuffs\"\"\"\n        return \"Just a manager doing management things.\"\n\n\nprogrammer = Programmer(\n    _first_name=\"Lucas\",\n    _id=0,\n    _languages=[\"JavaScript\", \"TypeScript\", \"Python\"],\n    _last_name=\"Hoz\",\n    _salary=150000,\n    _side=\"Full Stack\",\n)\n\nprint(\"\\nProgrammer attributes...\\n\")\nprint(programmer.get_attributes())\n\nprint(\"\\nProgrammer methods...\")\nprint(f\"\\nprogrammer.write_code() --> {programmer.write_code(language=\"Python\")}\")\n\nproject_manager = ProjectManager(\n    _first_name=\"Lucas\",\n    _functions=[\"Time management\", \"Team leardership\"],\n    _id=1,\n    _last_name=\"Hoz\",\n    _programmers=[programmer],\n    _salary=150000,\n)\n\nprint(\"\\nProject manager attributes...\\n\")\nprint(project_manager.get_attributes())\n\nprint(\"\\nProject manager methods...\")\nprint(f\"\\nproject_manager.make_management() --> {project_manager.make_management()}\")\n\nmanager = Manager(\n    _department=\"Development\",\n    _first_name=\"Lucas\",\n    _functions=[\"Time management\", \"Financial planning\", \"Department management\"],\n    _id=2,\n    _last_name=\"Hoz\",\n    _project_managers=[project_manager],\n    _salary=150000,\n)\n\nprint(\"\\nManager attributes...\\n\")\nprint(manager.get_attributes())\n\nprint(\"\\nManager methods...\")\nprint(f\"\\nmanager.make_management() --> {manager.make_management()}\")\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/idiegorojas.py",
    "content": "# 09 - Herencias\n\n# Clase padre\nclass Animal:\n\n    def __init__(self, nombre, edad):\n        self.nombre = nombre\n        self.edad = edad\n\n    def sonido(self):\n        print('Algun sonido')\n\n    def presentarse(self):\n        print(f'Hola, soy {self.nombre}, y tengo {self.edad} años.')\n\n# Clase Hija\nclass Perro(Animal):\n\n    def __init__(self, nombre, edad, raza):\n        # Llamamos al constructor de la clase padre\n        super().__init__(nombre, edad)\n        self.raza = raza\n\n    # Sobrescribimos el metodo sonido\n    def sonido(self):\n        print('¡Guau, guau!')\n\n    # Agregamos un metodo especifico del Perrro\n    def perseguir_cola(self):\n        print(f'{self.nombre} esta persiguiendo su cola')\n\nclass Gato(Animal):\n    \n    def __init__(self, nombre, edad, color):\n        # Llamamos al constructor de la clase padre\n        super().__init__(nombre, edad)\n        self.color = color\n\n    # Sobrescribimos el metodo sonido\n    def sonido(self):\n        print('Miau')\n\n    # Agregamos un metodo especifico del Gato\n    def dormir(self):\n        print(f'{self.nombre} esta durmiendo.')\n\n\nmi_perro = Perro('Max', 3, 'Pug')\nmi_perro.presentarse()\nmi_perro.sonido()\nmi_perro.perseguir_cola()\n\nmi_gato = Gato('Luna', 2, 'Negro')\nmi_gato.presentarse()\nmi_gato.sonido()\nmi_gato.dormir()\n\n\n# Extra\n\nclass Empleado:\n\n    def __init__(self, id, nombre, cargo):\n        self.id = id\n        self.nombre = nombre\n        self.cargo = cargo\n        self.empleados = []\n\n    def presentarse(self):\n        print(f'Hola, mi nombre es {self.nombre} y mi cargo es {self.cargo}')\n\n    def agregar_empleado(self, empleados):\n        self.empleados.append(empleados)\n\n    def listar_empleados(self):\n        if len(self.empleados) >= 1:\n            print(f'{self.nombre} tiene a cargo {len(self.empleados)} empleados.')\n        else:\n            print(f'{self.nombre} no tiene empleados a cargo.')\n\n\nclass Gerente(Empleado):\n\n    def __init__(self, id, nombre, cargo):\n        super().__init__(id, nombre, cargo)\n\n    def planifica(self):\n        print(f'Como {self.cargo}, estoy planificando los objetivos del proximo año')\n\n\nclass GerenteProyecto(Empleado):\n    \n    def __init__(self, id, nombre, cargo):\n        super().__init__(id, nombre, cargo)\n\n    def ejecuta(self):\n        print(f'Como {self.cargo}, estoy ejecutando los objetivos de este año')\n\n\nclass Programador(Empleado):\n\n    def __init__(self, id, nombre, cargo):\n        super().__init__(id, nombre, cargo)\n\n    def desarrolla(self):\n        print(f'Como {self.cargo}, estoy desarrollando un programa para alcanzar los objetivos.')\n\n    \ngerente_1 = Gerente(1, 'Jorge', 'Gerente')\ngerente_1.presentarse()\ngerente_1.planifica()\n\ngerente_proyecto_1 = GerenteProyecto(2, 'Felipe', 'Gerente de Proyectos')\ngerente_proyecto_1.presentarse()\ngerente_proyecto_1.ejecuta()\n\nprogramador_1 = Programador(3, 'Raul', 'Programador')\nprogramador_1.presentarse()\nprogramador_1.desarrolla()\n\ngerente_1.agregar_empleado(gerente_proyecto_1)\ngerente_proyecto_1.agregar_empleado(programador_1)\n\ngerente_1.listar_empleados()\ngerente_proyecto_1.listar_empleados()\nprogramador_1.listar_empleados()"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/ignaciovihe.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n\"\"\"\n# Superclase\nclass Animal:\n\n    def __init__(self,name, age, breed = None):\n        self.name = name\n        self.age = age\n        self.breed = breed if breed else \"Unknown\"\n        self.sound = None\n\n    def feed(self):\n        print(f\"{self.name} is fed\")\n\n    def make_sound(self):\n        if self.sound:\n            print(self.sound)\n        else:\n            print(f\"{self.name} makes a sound\")\n\nclass Dog(Animal):\n    def __init__(self, name, age, breed = None):\n        super().__init__(name, age, breed)\n        self.sound = \"Guau\"\n\n\nclass Cat(Animal):\n    def __init__(self, name, age, breed = \"None\"):\n        super().__init__(name, age, breed)\n        self.sound = \"Miau\"\n\nmy_dog = Dog(\"Firulais\", 2)\nmy_cat = Cat(\"Bruma\", 1)\nmy_cow = Animal(\"Campana\", 8, \"lechera\")\n\nmy_dog.feed()\nmy_cat.feed()\nmy_cow.feed()\nmy_dog.make_sound()\nmy_cat.make_sound()\nmy_cow.make_sound()\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n\"\"\"\n\nclass Employee:\n\n    def __init__(self, id: int, name: str):\n        self.id = id\n        self.name = name\n        self.employees =[]\n\n    def add_employee(self, employee):\n        self.employees.append(employee)\n\n    def show_employees(self):\n        print(f\"Employees of {self.id} - {self.name} - {type(self).__name__}:\")\n        for employee in self.employees:\n            print(f\"ID: {employee.id}, Name: {employee.name} - {type(employee).__name__} {(\"- \" + employee.language) if isinstance(employee, Programmer) else \"\"}\")\n\n\nclass Programmer(Employee):\n    \n    def __init__(self, id: int, name: str, language: str):\n        super().__init__(id, name)\n        self.language = language\n\n    def code(self):\n        print(f\"{self.id} - {self.name} programa su aplicación\")\n\n    def add_employee(self, employee : Employee):\n        print(\"Un programador no puede añadir empleados\")\n\n    def show_employees(self):\n        print(\"Los programadores no tienen empleados a su cargo.\")\n\n\nclass Project_manager(Employee):\n\n    def __init__(self, id: int, name: str, project: str):\n        super().__init__(id, name)\n        self.project = project\n\n    def coordinate_project(self):\n        print(f\"{self.id} - {self.name} sicroniza su proyecto {self.project}\")\n\n\nclass Manager(Employee):\n\n    def __init__(self, id: int, name: str):\n        super().__init__(id, name)\n\n    def coordinate_projects(self):\n        print(f\"{self.id} - {self.name} sicroniza los proyectos de la emperesa\")\n\n\nmy_manager = Manager(1,\"Ignacio\")\nmy_project_manager = Project_manager(2, \"Miguel\", \"NOVA\")\nmy_programmer = Programmer(3,\"Pedro\", \"Python\")\nmy_programmer2 = Programmer(4, \"Juan\", \"Kotlin\")\nmy_project_manager2 = Project_manager(5, \"Lorena\", \"MARCA\")\nmy_programmer3 = Programmer(6,\"Sara\", \"GO\")\nmy_programmer4 = Programmer(7, \"Carlos\", \"Rust\")\nmy_programmer5 = Programmer(8,\"Matias\", \"c#\")\nmy_programmer6 = Programmer(9, \"Alvaro\", \"Python\")\nmy_manager.add_employee(my_project_manager)\nmy_manager.add_employee(my_project_manager2)\nmy_project_manager.add_employee(my_programmer)\nmy_project_manager.add_employee(my_programmer2)\nmy_project_manager2.add_employee(my_programmer3)\nmy_project_manager2.add_employee(my_programmer4)\nmy_project_manager2.add_employee(my_programmer5)\nmy_project_manager2.add_employee(my_programmer6)\n\nmy_manager.coordinate_projects()\nmy_manager.show_employees()\nmy_project_manager.coordinate_project()\nmy_project_manager.show_employees()\nmy_programmer.code()\nmy_programmer2.code()\nmy_project_manager2.coordinate_project()\nmy_project_manager2.show_employees()\nmy_programmer3.code()\nmy_programmer4.code()\nmy_programmer5.code()\nmy_programmer6.code()\nmy_programmer.add_employee(my_programmer6)\nmy_programmer.show_employees()"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/ipfabio.py",
    "content": "\"\"\"\nEjercicio\n\"\"\"\n\nclass Animal:\n\n    def __init__(self, nombre) -> None:\n        self.nombre = nombre\n\n    def sonido(self):\n        ...\n\n# Herencia\nclass Perro(Animal):\n    \n    def sonido(self):\n        print(f\"{self.nombre} hace: Guau Guau\")\n\nclass Gato(Animal):\n    \n    def sonido(self):\n        print(f\"{self.nombre} hace: Miaaaaau\")\n\n# Polimorfismo -> Sobrecarga en compilación\ndef print_sound(animal: Animal):\n    animal.sonido()\n\nperro = Perro(\"Perro Lindo\")\nprint_sound(perro)\ngato = Gato(\"Gato Bello\")\nprint_sound(gato)\n\n\"\"\"\nExtra\n\"\"\"\n\nclass Empleado():\n    def __init__(self, id:int, name: str) -> None:\n        self.id = id\n        self.name = name\n        self.employees = []\n    \n    # Toma por defecto employee: Employee\n    def add(self, employee):\n        self.employees.append(employee)\n\n    def print_employees(self):\n        for employee in self.employees:\n            print(employee.name)\n        \n\nclass Manager(Empleado):\n    \n    def coordintae_project(self):\n        print(f\"{self.name} está coordinando todos los proyectos de la empresa.\")\n\nclass ProjectManager(Empleado):\n\n    def __init__(self, id: int, name: str, project: str) -> None:\n        super().__init__(id, name)\n        self.project = project\n    \n    def coordintae_project(self):\n        print(f\"{self.name} está coordinando su proyecto.\")\n\nclass Programmer(Empleado):\n    \n    def __init__(self, id: int, name: str, language: str) -> None:\n        super().__init__(id, name)\n        self.lenguage = language\n    \n    def code(self):\n        print(f\"{self.name} está programando en {self.lenguage}\")\n    \n    def add(self, employee: Empleado):\n        print(f\"Un programador no tiene empleados a su cargo. {employee} no se añadirá.\")\n    \n    def print_employees(self):\n        print(f\"{self.name} no tiene empleados a su cargo.\")\n        \n\nmy_manager = Manager(1, \"Marco\")\nmy_project_manager = ProjectManager(2, \"Polo\", \"Proyecto 1\")\nmy_project_manager_2 = ProjectManager(3, \"Daniel\", \"Proyecto 2\")\nmy_programmer = Programmer(4, \"Kain\", \"C++\")\nmy_programmer2 = Programmer(5, \"Abel\", \"C#\")\nmy_programmer3 = Programmer(6, \"Ron\", \"C\")\nmy_programmer4 = Programmer(7, \"Mon\", \"Python\")\n\nmy_manager.add(my_project_manager)\nmy_manager.add(my_project_manager_2)\n\nmy_project_manager.add(my_programmer)\nmy_project_manager.add(my_programmer2)\n\nmy_project_manager_2.add(my_programmer3)\nmy_project_manager_2.add(my_programmer4)\n\nmy_programmer.add(my_programmer2)\n\nmy_programmer.code()\nmy_project_manager.coordintae_project()\nmy_manager.coordintae_project()\nmy_manager.print_employees()\nmy_project_manager.print_employees()\nmy_programmer.print_employees()\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/isilanes.py",
    "content": "import random\nfrom abc import ABC, abstractmethod\n\n\nclass Animal(ABC):\n    \"\"\"\n    We make this class abstract, because we decided that no entity in our code\n    can be just \"an animal\". It must be SOME animal, of some species (subclass).\n    \"\"\"\n\n    def __init__(self, name: str):\n        self.name = name\n        self.food: int = 0  # amount of food inside the animal\n\n    def eat(self, food: int = 1) -> None:\n        self.food += food\n\n    def poo(self) -> None:\n        self.food -= 1\n\n    @abstractmethod\n    def make_noise(self) -> None:\n        \"\"\"\n        Execute whatever sound the animal makes.\n        \"\"\"\n\n\nclass Perro(Animal):\n\n    @staticmethod\n    def bark() -> None:\n        print(\"Guau!\")\n\n    def poo(self) -> None:\n        \"\"\"\n        Dogs are renowned for how much they shit. Therefore, we override the default method.\n        \"\"\"\n        self.food -= 2\n\n    def make_noise(self) -> None:\n        self.bark()\n\n\nclass Gato(Animal):\n\n    @staticmethod\n    def meow() -> None:\n        print(\"Miauuuu\")\n\n    def make_noise(self) -> None:\n        self.meow()\n\n\nclass Employee:\n    \"\"\"\n    Esta vez no hacemos 'Empleado' abstracta, porque digamos que hemos decidido que podrían\n    existir empleados que no tienen un tipo concreto. La típica gente que no sabes qué hace.\n    \"\"\"\n    def __init__(self, name: str, employee_id: int, minions: list['Employee'] | None = None):\n        self.name = name\n\n        # Esta implementación de ID de empleado debería enviarme directamente a la cárcel.\n        # Obviamente hay dos requisitos que deberían considerarse mínimos, y que esta\n        # implementación no cumple:\n        # - Debería poder asignarse un ID de manera automática, sin pasarlo como argumento\n        # - Debería garantizarse que los IDs son únicos.\n        # Ambos requisitos suelen ser estándar en implementaciones apoyadas en base de datos,\n        # como los modelos en Django (se transfiere la responsabilidad de ello a la db).\n        # Sin base de datos, podríamos implementarlo con UUIDs, o con algún repositorio\n        # central de IDs.\n        self.employee_id = employee_id\n\n        # El enunciado parece sugerir que implementemos la relación one-to-many de manera inversa\n        # a como se haría en una base de datos. En vez de definir un atributo 'dependo de' en\n        # el subalterno, que apunte a su jefe (de forma que \"los subalternos de X\" son \"los elementos\n        # cuyo 'dependo de' apunta a X\"), definimos un atributo ' dependen de mí' en el jefe,\n        # que contiene a los subalternos de ese elemento (de manera que \"los subaltennos de X\" son\n        # directamente \"los elementos en la lista 'dependen de mí' de X\"). Va más allá del alcance de\n        # este ejercicio discutir los méritos de ambas aproximaciones, y por qué la otra es mejor que esta :)\n        self.minions = minions or []\n\n\nclass Engineer(Employee):\n    \"\"\"\n    Los programadores, los IndividualContributors, los machacas, los curritos. Los verdaderos héroes sin capa :D\n    \"\"\"\n\n    def __init__(self, name: str, employee_id: int):\n        super().__init__(name=name, employee_id=employee_id)  # los curritos no tienen minions\n\n    @staticmethod\n    def produce_spaghetti() -> None:\n        print(\"Marchándo una de código infumable...\")\n\n    @staticmethod\n    def guess_deadline() -> float:\n        return random.randrange(1, 1000)\n\n\nclass ProjectManager(Employee):\n    \"\"\"\n    Los Gerentes de Proyecto, o PMs. Los jefes intermedios que te venden que no son jefes intermedios,\n    sino engranajes de tu proyecto ágil al mismo nivel que el resto de miembros, pero que vamos,\n    que son jefes intermedios.\n    \"\"\"\n    def __init__(self, name: str, employee_id: int, minions: list[Engineer] | None = None):\n        super().__init__(name=name, employee_id=employee_id, minions=minions)\n\n    def ask_for_estimations(self, feature: str) -> None:\n        if not self.minions:\n            print(f\"No tengo programadores a mi cargo, no puedo hacer {feature}\")\n            return\n\n        print(f\"{self.name}: Chic@s, decidme cuánto creéis que se tarda en implementar {feature}\")\n        for minion in self.minions:\n            print(f\"{minion.name}: yo creo que {minion.guess_deadline()} días.\")\n\n\nclass CEO(Employee):\n    \"\"\"\n    El Gerente, el jefe, el boss. El CEO es jefe directo de todos los PMs (Gerentes de Proyecto).\n    \"\"\"\n    def __init__(self, name: str, minions: list[ProjectManager] | None = None):\n        super().__init__(name=name, employee_id=0, minions=minions)  # el CEO tiene el ID primigenio\n\n        self.n_yachts = 1\n\n    def park(self) -> None:\n        print(f\"El jefe {self.name} aparca donde le da la gana.\")\n\n    def sail(self) -> None:\n        if self.n_yachts > 1:\n            print(f\"El jefe {self.name} navega en uno de sus {self.n_yachts} yates.\")\n        elif self.n_yachts == 1:\n            print(f\"El jefe {self.name} navega en su yate.\")\n        else:\n            print(\"Nos compramos un yate...\")\n            self.n_yachts += 1\n            self.sail()\n\n    def request_feature(self, feature: str) -> None:\n        for pm in self.minions:\n            print(f\"{self.name}: Oye, {pm.name}, hacedme {feature}\")\n            pm.ask_for_estimations(feature)\n\n\ndef main():\n    print(\"Nuestras clases Perro y Gato heredan de la clase (abstracta) Animal. No puedo instanciar un Animal abstracto:\")\n    print('yo = Animal(name=\"Iñaki\")')\n    try:\n        yo = Animal(name=\"Iñaki\")\n    except TypeError:\n        print(\"Te dije que no se puede.\")\n\n    print(\"\\nSí que podemos instanciar un Gato:\")\n    print('cat = Gato(name=\"Félix\")')\n    cat = Gato(name=\"Félix\")\n    print(\"El gato puede maullar:\")\n    print('cat.meow()')\n    cat.meow()\n    print(\"Como todas las subclases de Animal, un Gato tiene el método make_noise(), que en su caso maullará:\")\n    print('cat.make_noise()')\n    cat.make_noise()\n    print(\"El Gato, como todos los Animales, tiene un nombre, y una cantidad de comida en su estómago:\")\n    print(f\"cat.name == {cat.name}, cat.food == {cat.food}\")\n    print(\"Un Gato puede comer una cantidad arbitraria de unidades de comida:\")\n    print('cat.eat(3)')\n    cat.eat(3)\n    print(\"Ahora tendrá más comida dentro:\")\n    print(f\"cat.food == {cat.food}\")\n    print(\"(No se me escapa que mi chapucera implementación de eat() permite aberraciones,\")\n    print(\"como por ejemplo comer una cantidad negativa de comida)\")\n    print(\"Un gato puede también cagar, lo cual en su caso hace con la cantidad estándar de 1 unidad de comida:\")\n    print('cat.poo()')\n    cat.poo()\n    print(f\"cat.name == {cat.name}, cat.food == {cat.food}\")\n\n    print(\"\\nTambién podemos instanciar un Perro, el cual tiene nombre y cantidad de comida ingerida,\")\n    print(\"como el Gato:\")\n    print('dog = Perro(\"Pluto\")')\n    dog = Perro(\"Pluto\")\n    print(f\"dog.name == {dog.name}, dog.food == {dog.food}\")\n    print(\"Un Perro puede ladrar (bark), y también puede hacer un sonido (make_noise), lo cual,\")\n    print(\"en su caso, corresponde a ladrar:\")\n    print('dog.bark()')\n    dog.bark()\n    print('dog.make_noise()')\n    dog.make_noise()\n    print(\"Un Perro también puede comer y cagar, como cualquier Animal. En su caso, caga más:\")\n    print('dog.eat(3)')\n    dog.eat(3)\n    print(f\"dog.name == {dog.name}, dog.food == {dog.food}\")\n    print('dog.poo()')\n    dog.poo()\n    print(f\"dog.name == {dog.name}, dog.food == {dog.food}\")\n\n    print(\"\\nEl 'duck typing' de Python, unido al uso de una superclase abstracta en este caso,\")\n    print(\"nos permite recorrer una colección de Animales, y hacer que cada uno haga 'su sonido',\")\n    print(\"usando el método make_noise() que sabemos que tienen, y sin preocuparnos de qué\")\n    print(\"subclase concreta de Animal son:\")\n    for animal in (dog, cat):\n        print(f\"El {animal.__class__.__name__} {animal.name} hace...\")\n        animal.make_noise()\n\n\ndef extra():\n    print(\"\\nTenemos una empresa, en la que alguien puede ser un empleado sin oficio ni beneficio:\")\n    print('nobody = Employee(name=\"Santiago\", employee_id=1)')\n    nobody = Employee(name=\"Santiago\", employee_id=1)\n\n    print(\"\\nMás interesantes son los programadores, sustento de la empresa y maravillosos seres de luz:\")\n    print('alice = Engineer(name=\"Alice\", employee_id=2)')\n    print('bob = Engineer(name=\"Robert\", employee_id=3)')\n    print('charlie = Engineer(name=\"Charles\", employee_id=4)')\n    alice = Engineer(name=\"Alice\", employee_id=2)\n    bob = Engineer(name=\"Bob\", employee_id=3)\n    charlie = Engineer(name=\"Charlie\", employee_id=4)\n    print(\"Un programador puede producir bas... código:\")\n    print('alice.produce_spaghetti()')\n    alice.produce_spaghetti()\n    print(\"Todo programador que se precie puede generar estimaciones:\")\n    print(f\"bob.guess_deadline() == {bob.guess_deadline()}\")\n    print(f\"charlie.guess_deadline() == {charlie.guess_deadline()}\")\n    print(f\"charlie.guess_deadline() == {charlie.guess_deadline()}\")\n    print(\"(No dijimos que fueran a ser consistentes)\")\n\n    print(\"\\nUn buen proyecto tendrá un PM, que se encargará de varios Programadores:\")\n    print('michael = ProjectManager(name=\"Scott\", employee_id=5, minions=[alice, bob, charlie])')\n    michael = ProjectManager(name=\"Scott\", employee_id=5, minions=[alice, bob, charlie])\n    print(\"La principal función de un PM es pedir estimaciones:\")\n    print('michael.ask_for_estimations(feature=\"un botón bonito\")')\n    michael.ask_for_estimations(feature=\"un botón bonito\")\n    print(\"Es posible que un PM no tenga empleados a su cargo:\")\n    print('andy = ProjectManager(name=\"Bernard\", employee_id=6)')\n    andy = ProjectManager(name=\"Bernard\", employee_id=6)\n    print(f\"{andy.name} tiene estos subalternos: {andy.minions}\")\n\n    print(\"\\nFinalmente llegamos al Gerente/CEO/jefe. Este tendrá PMs a su cargo:\")\n    print('boss = CEO(name=\"Bruce S.\", minions=[michael, andy])')\n    boss = CEO(name=\"Bruce S.\", minions=[michael, andy])\n    print(\"Un buen CEO puede hacer cosas chachis:\")\n    print('boss.park()')\n    boss.park()\n    print('boss.sail()')\n    boss.sail()\n    print(\"Y si no tenemos yate...\")\n    print('boss.n_yachts = 0')\n    boss.n_yachts = 0\n    print('boss.sail()')\n    boss.sail()\n    print(\"\"\"boss.request_feature(\"una web 'como la de Iberia'\")\"\"\")\n    boss.request_feature(\"una web 'como la de Iberia'\")\n\n\nif __name__ == \"__main__\":\n    main()\n    extra()\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/javierjoyera.py",
    "content": "class Animal:\n    def __init__(self, nombre):\n        self.nombre = nombre\n\n    def emitir_sonido(self):\n        raise NotImplementedError(\"La Subclase debe implementar este método\")\n    \n'''\nLa herencia se define al pasar la superclase como parametro a la definicion de la subclase.\n\nLa superclase Animal tiene un metodo emitir_sonido que no hace nada, pero que debe ser implementado por las subclases.\n'''\n\n##Subclases\nclass Perro(Animal):\n    def emitir_sonido(self):\n        return (\"%s dice: Guau\" % self.nombre)\n    \nclass Gato(Animal):\n    def emitir_sonido(self):\n        return (\"%s dice: Miau\" % self.nombre)\n    \nmy_dog = Perro(\"Bruno\")\nmy_cat = Gato(\"Garfield\")\n\nprint(my_dog.emitir_sonido())\nprint(my_cat.emitir_sonido())\n\n## Ejercicio OPCIONAL\n\nclass Empleado: \n    def __init__(self, id_empleado, nombre):\n        self.id_empleado = id_empleado\n        self.nombre = nombre\n    \n    def __str__(self):\n        return \"El id del empleado %s es %s\" % (self.nombre, self.id_empleado)\n    \n    def mostrar_informacion(self):\n        print(self)\n\n\n#Subclase Gerente\nclass Gerente(Empleado):\n    def __init__(self, id_empleado, nombre):\n        super().__init__(id_empleado, nombre)\n        self.empleados_a_cargo = []\n\n    def agregar_empleado(self, empleado):\n        self.empleados_a_cargo.append(empleado)\n\n    def mostrar_informacion(self):\n        super().mostrar_informacion()\n        print(\"Empleados a cargo:\")\n        for empleado in self.empleados_a_cargo:\n            print(\"- %s\" % empleado)\n\n#Subclase Gerente de proyectos\nclass GerenteProyectos(Gerente):\n    def __init__(self, id_empleado, nombre):\n        super().__init__(id_empleado, nombre)\n        self.proyectos = []\n\n    def agregar_proyecto(self, proyecto):\n        self.proyectos.append(proyecto)\n\n    def mostrar_informacion(self):\n        super().mostrar_informacion()\n        print(\"Proyectos a cargo:\")\n        for proyecto in self.proyectos:\n            print(\"- %s\" % proyecto)\n\nclass Programador(Empleado):\n    def __init__(self, id_empleado, nombre, lenguajes):\n        super().__init__(id_empleado, nombre)\n        self.lenguajes = lenguajes\n\n    def mostrar_informacion(self):\n        super().mostrar_informacion()\n        print(\"Lenguajes:\")\n        for lenguaje in self.lenguajes:\n            print(\"- %s\" % lenguaje)\n\n#creación de Empleados\ngerente_1 = GerenteProyectos(1, \"Lorena\")\ngerente_proyecto_1 = GerenteProyectos(2, \"Pedro\")\ngerente_proyecto_2 = GerenteProyectos(3, \"Maria\")\n\nprogramador_1 = Programador(4, \"Juan\", [\"Python\", \"Java\"])\nprogramador_2 = Programador(5, \"Carlos\", [\"Python\", \"C++\"])\nprogramador_3 = Programador(6, \"Ana\", [\"Python\", \"C++\"])\n\ngerente_1.agregar_empleado(gerente_proyecto_1)\ngerente_1.agregar_empleado(gerente_proyecto_2)\n\ngerente_proyecto_1.agregar_empleado(programador_1)\ngerente_proyecto_1.agregar_empleado(programador_2)\n\ngerente_proyecto_2.agregar_empleado(programador_3)\n\ngerente_proyecto_1.agregar_proyecto(\"Proyecto 1\")\ngerente_proyecto_1.agregar_proyecto(\"Proyecto 2\")\ngerente_proyecto_2.agregar_proyecto(\"Proyecto 3\")\n\nprint(\"Información del Gerente\")\nprint(\"-----------------------------\")\ngerente_1.mostrar_informacion()\nprint(\"-----------------------------\")\nprint(\"Información del Gerente de Proyectos 1\")\nprint(\"-----------------------------\")\ngerente_proyecto_1.mostrar_informacion()\nprint(\"-----------------------------\")\nprint(\"Información del Gerente de Proyectos 2\")\nprint(\"-----------------------------\")\ngerente_proyecto_2.mostrar_informacion()\nprint(\"-----------------------------\")\nprint(\"Información del Programador 1\")\nprint(\"-----------------------------\")\nprogramador_1.mostrar_informacion()\nprint(\"-----------------------------\")\nprint(\"Información del Programador 2\")\nprint(\"-----------------------------\")\nprogramador_2.mostrar_informacion()\nprint(\"-----------------------------\")\nprint(\"Información del Programador 3\")\nprint(\"-----------------------------\")\nprogramador_3.mostrar_informacion()"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/jesusgdev.py",
    "content": "'''\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n   implemente una superclase Animal y un par de subclases Perro y Gato,\n   junto con una función que sirva para imprimir el sonido que emite cada Animal.\n  \n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n   pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n   actividad, y almacenan los empleados a su cargo.\n'''\n\nclass Animal:\n    def __init__(self, name):\n        self.name = name\n    \n    def sound(self):\n        pass\n\n\nclass Dog(Animal):\n    def __init__(self, name):\n        super().__init__(name)\n\n    def sound(self):\n        print(f\"Este es un perro, su nombre es {self.name}, y hace gua,gua!\")\n\ndog = Dog(\"Marcus\")\ndog.sound()\n\nclass Cat(Animal):\n    def __init__(self, name):\n        super().__init__(name)\n\n    def sound(self):\n        print(f\"Este es un gato, su nombre es {self.name}, y hace miau,miau!\")\n\ncat = Cat(\"Snow\")\ncat.sound()\nprint(\"\")\n'''\nExtra\n'''\n\n# Clase base para todos los empleados\nclass Employee:\n    def __init__(self, id, name):\n        # Atributos comunes: identificación y nombre\n        self.id = id\n        self.name = name\n        \n    # Muestra la lista de empleados que han sido contratados\n    def employees_list(self):\n        for employee in self.employees:\n            print(f\"ID: {employee.id} | Empleado: {employee.name}\")\n\n    # Método base para contratar (solo para que exista, lo usaremos en Manager)\n    def hire_employee(self, id, name, position, language):\n        pass\n\n# Clase Manager, hereda de Employee\nclass Manager(Employee):\n    def __init__(self, id, name):\n        super().__init__(id, name)  # Llama al constructor de Employee\n        self.employees = []  # Lista de todos los empleados contratados\n        self.project_name = \"\"  # Nombre del proyecto que administra\n        self.projects_info = {}  # Diccionario {proyecto: director}\n        self.team_projects_info = {}  # Diccionario {proyecto: [empleados]}\n        self.position = \"\"  # Rol del empleado (ProjectManager o Programador)\n        self.projectmanagers = []  # Lista de ProjectManager contratados\n        self.programmers = []  # Lista de programadores contratados\n        self.language = \"\"  # Lenguaje del programador (opcional)\n\n\n    # Contrata a un nuevo empleado según su posición\n    def hire_employee(self, id, name, position, language = None):\n        if position == \"ProjectManager\":\n            # Crea un ProjectManager y lo agrega a las listas\n            new_employee = ProjectManager(id, name)\n            self.employees.append(new_employee)\n            self.projectmanagers.append(new_employee)\n\n        elif position == \"Programador\":\n            # Crea un Programador y lo agrega a las listas\n            new_employee = Programmer(id, name, language)        \n            self.employees.append(new_employee)\n            self.programmers.append(new_employee)\n        \n        print(f\"{name} ha sido contratado/a como {position}\")\n\n    # Muestra los ProjectManager contratados\n    def projectmanagers_list_info(self):\n        if len(self.projectmanagers) == 0:\n            print(\"\\nNo se han contratado directores de proyecto aun\")\n        else:\n            print(\"\\nLista de ProjectManagers contratados:\")\n            for projectmanager in self.projectmanagers:\n                print(f\"ID: {projectmanager.id} | Name: {projectmanager.name}\")\n\n    # Muestra los programadores contratados\n    def programmers_list_info(self):\n        if len(self.programmers) == 0:\n            print(\"\\nNo se han contratado programadores aun\")\n        else:\n            print(\"\\nLista de Programadores contratados:\")\n            for programmer in self.programmers:\n                print(f\"ID: {programmer.id} | Name: {programmer.name} | Language: {programmer.language}\")\n    \n    # Asigna un proyecto a un ProjectManager\n    def assign_project(self, name, project_name):\n        if name not in self.projects_info.values():\n            if project_name not in self.projects_info.keys():\n                self.projects_info[project_name] = name\n                print(f'{name} ha sido asignado a dirigir el proyecto \"{project_name}\"')\n            else:\n                print(f\"El proyecto {project_name} ya fue asignado a otro empleado\")\n        else:\n            print(f\"Ya el empleado {name} tiene un proyecto asignado\")\n\n    # Muestra qué empleado dirige qué proyecto\n    def show_project_info(self):\n            print(\"\")\n            print(\"Informacion actual de Proyectos:\")\n            for project, emplooye in self.projects_info.items():\n                print(f\"{emplooye} esta dirigiendo el proyecto {project}\")\n\n\n    # Asigna programadores a un proyecto\n    def assing_team_project(self, name, project_name):\n        # Verifica si el programador ya está en otro proyecto\n        for project, team in self.team_projects_info.items():\n            if name in team:\n                if project == project_name:\n                    print(f\"{name} ya esta trabajando actualmente en el proyecto {project_name}\")\n                else:\n                    print(f\"{name} ya esta trabajando en otro proyecto ({project})\")\n                return  # Detiene el proceso, no se vuelve a asignar\n\n        # Si no existe el proyecto en el diccionario, se crea\n        if project_name not in self.team_projects_info:\n            self.team_projects_info[project_name] = []\n\n        # Se agrega el programador al proyecto\n        self.team_projects_info[project_name].append(name)\n        print(f\"{name} ha sido asignado a trabajar en el proyecto {project_name}\")\n    \n    # Muestra todos los proyectos con su equipo asignado\n    def show_team_project_info(self):\n        print(\"\")\n        print(\"Informacion de equipos de proyectos:\")\n        for project, emplooyes in self.team_projects_info.items():\n            for emplooye in emplooyes:\n                print(f\"{emplooye} esta trabajando en el proyecto {project}\")\n\n# Clase ProjectManager, hereda de Employee            \nclass ProjectManager(Employee):\n    def __init__(self, id, name):\n        super().__init__(id, name)\n\n# Clase Programmer, hereda de Employee\nclass Programmer(Employee):\n    def __init__(self, id, name, language):\n        super().__init__(id, name)\n        self.language = language\n\n\nmy_manager = Manager(1, \"Jesus\")\n\nmy_manager.hire_employee(2, \"John\", \"ProjectManager\")\nmy_manager.hire_employee(3, \"Andrew\", \"ProjectManager\")\n\nmy_manager.hire_employee(4, \"Sam\", \"Programador\", \"Java\")\nmy_manager.hire_employee(5, \"Laura\", \"Programador\", \"Python\")\nmy_manager.hire_employee(6, \"Michael\", \"Programador\", \"Javascript\")\nmy_manager.hire_employee(7, \"Louis\", \"Programador\", \"C\")\n\n\nmy_manager.projectmanagers_list_info()\nmy_manager.programmers_list_info()\n\nprint(\"\")\n\nmy_manager.assign_project(\"John\", \"Gestor Clinica Santa Maria\")\nmy_manager.assign_project(\"John\", \"Aplicacion Movil Banco Globalbank\")\nmy_manager.assign_project(\"Andrew\", \"Aplicacion Movil Banco Globalbank\")\n\nmy_manager.show_project_info()\n\nmy_projectmanager1 = ProjectManager(\"2\", \"John\")\nmy_projectmanager2 = ProjectManager(\"3\", \"Andrew\")\n\nprint(\"\")\n\nmy_manager.assing_team_project(\"Sam\", \"Gestor Clinica Santa Maria\")\nmy_manager.assing_team_project(\"Laura\", \"Gestor Clinica Santa Maria\")\nmy_manager.assing_team_project(\"Michael\", \"Aplicacion Movil Banco Globalbank\")\nmy_manager.assing_team_project(\"Louis\", \"Aplicacion Movil Banco Globalbank\")\n\nmy_manager.show_team_project_info()\n\nprint(\"\")\n\nmy_manager.employees_list()\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/jesusway69.py",
    "content": "import os\nos.system('clear') #MAC/LINUX\nos.system('cls') #WINDOWS\n\n\"\"\"\n* EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\"\"\"\n\nclass Animal():#Declaramos la clase principal Animal\n    \n    def __init__(self,sonido, animal):#Definimos el método init que recibirá 2 parámetros\n        self.sonido = sonido #Declaramos las variables con self\n        self.animal = animal# para guardar los 2 parámetros recibidos\n    def print(self):#Definimos una función que imprima en base a los argumentos recibidos\n        print(self.animal, self.sonido)# en los 2 parámetros\n\n\nclass Especie(Animal):#Declaramos la clase Especie y entre paréntesis le indicamos de qué clase heredará\n    articulo =\"El\"#Declaramos un artículo definido masculino por defecto \n    def print(self):#Declaramos una función llamada igual que la heredada de la clase padre (no obligatorio)\n        if self.animal.endswith(\"a\"):#Condicionamos para los las especies que se nombran con artículo femenino\n            self.articulo=\"La\"# , en español habitualmente las especies que acaban en \"a\"  \n        print(self.articulo, self.animal, self.sonido)# Llamamos a la función heredada (2 parámetros) y propia\n    # (3 parámetros) en un ejemplo de polimorfismo, en los casos de herencia prevalece la función que se encuentre en la\n    # subclase, si es herencia múltiple también pero se establece una jerarquía según el orden en el que heredemos las clases\n    # de izquierda a derecha como vemos en la clase Programador del ejercicio de abajo\n\nmi_perro = Especie(\"ladra\", \"perro\")\nmi_gato = Especie(\"maulla\", \"gato\")\nmi_vaca = Especie(\"muge\", \"vaca\")\nmi_tigre = Especie(\"ruge\", \"tigre\")\nmi_perro.print()\nmi_gato.print()\nmi_vaca.print()\nmi_tigre.print()\nprint(\"\\n\\n\")\n\n\n\"\"\"\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\"\"\"\n\nclass Empleado():\n \n    def __init__(self):\n       self.finanzas = \"NO\"\n       self.compras = \"NO\"\n       self.proyectos = \"NO\"\n       self.organizacion = \"NO\"\n       self.programacion = \"NO\"\n       self.despliegue = \"NO\"\n   \n    def print_propiedades(self, cargo, id , nombre):\n          self.cargo = cargo\n          self.id = id\n          self.nombre = nombre\n         \n          print (\"\\nid:\", self.id, \"\\nNombre:\",self.nombre,\"\\nCargo:\", self.cargo,\"\\n¿Hace finanzas? =\", \n               self.finanzas,\"\\n¿Hace compras? =\", self.compras, \"\\n¿Planifica proyectos? =\", self.proyectos,\n               \"\\n¿Organiza el trabajo? =\", self.organizacion, \"\\n¿Pica código? =\", self.programacion,\n               \"\\n¿Despliega programas? =\",self.despliegue)\n      \n    def print_empleados(self,list_empleados):\n        print (\"Empleados a su cargo:\", end=' ')\n        print(' , '.join(list_empleados))\n        print(\"\")\n     \nclass Gerente(Empleado):\n      \n      def es_gerente(self, id, nombre,lista_g):\n        self.finanzas=\"SI\"\n        self.compras=\"SI\"\n        self.print_propiedades(\"Gerente\", id ,nombre)\n        self.print_empleados(lista_g)\n\n \nclass Gerente_proyecto(Gerente,Empleado):\n         \n      def es_gerente_proyecto(self, id, nombre,lista_p):\n        self.organizacion=\"SI\"\n        self.proyectos=\"SI\"\n        self.print_propiedades(\"Gerente de proyecto\", id ,nombre)\n        self.print_empleados(lista_p)\n\nclass Programador (Gerente_proyecto,Gerente,Empleado):\n      \n      def es_programador(self, id, nombre):\n        self.programacion=\"SI\"\n        self.despliegue=\"SI\"     \n        self.print_propiedades(\"Programador\", id ,nombre)\n        \n\ngerente = Gerente()\ngerente_proyecto = Gerente_proyecto()\nprogramador = Programador()\n\ndict_empleados = {\n1: \"Miguel\",\n2: \"Sandra\",\n3: \"Carlos\",\n4: \"Rocío\",\n5: \"Pedro\",\n6: \"Lucía\",\n7: \"Steven\",\n8: \"Sara\",\n9: \"Guillermo\",\n10: \"Leire\"\n}\nlist_empleados = []\nlist_proyectos = []\nfor k,v in dict_empleados.items():\n      if  k>2 and k<6:\n          list_empleados.append(v)\n      if k>= 6:\n          list_empleados.append(v)\n          list_proyectos.append(v)\n\nfor k,v in dict_empleados.items():\n\n   if k<=2:\n        gerente.es_gerente(k,v,list_empleados)\n        \n   elif k>2 and k<6:\n        gerente_proyecto.es_gerente_proyecto(k,v,list_proyectos)\n        \n   else:\n        programador.es_programador(k,v)"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/jgutierrez9891.py",
    "content": "#Ejercicio 9: Herencia\n\nclass Animal:\n    def __init__(self, nombre, edad):\n        self.nombre = nombre\n        self.edad = edad\n\n    def hacer_sonido(self):\n        pass\n\nclass Perro(Animal):\n    def hacer_sonido(self):\n        return \"Guau\"\n    \nclass Gato(Animal):\n    def hacer_sonido(self):\n        return \"Miau\"\n    \n# Crear instancias de Perro y Gato\nmi_perro = Perro(\"Rex\", 5)\nmi_gato = Gato(\"Michi\", 3)\n\n# Mostrar los sonidos que hacen\nprint(f\"{mi_perro.nombre} dice: {mi_perro.hacer_sonido()}\")\nprint(f\"{mi_gato.nombre} dice: {mi_gato.hacer_sonido()}\")\n\n\n# DIFICULTAD EXTRA (opcional):\n\nclass empleado:\n    def __init__(self, nombre, identificacion):\n        self.nombre = nombre\n        self.identificacion = identificacion\n\n    def funciones(self):\n        pass\n\n    def empleados_info(self):\n        return f\"Nombre: {self.nombre}, ID: {self.identificacion}, Funciones: {self.funciones()}\"\n\n\nclass gerente(empleado):\n    def funciones(self):\n        return \"Gestiona el equipo y toma decisiones estratégicas.\"\n    \nclass desarrollador(empleado):\n    def funciones(self):\n        return \"Escribe y mantiene el código del software.\"\n    \nclass diseñador(empleado):\n    def funciones(self):\n        return \"Crea diseños visuales y experiencia de usuario.\"\n    \n# Crear instancias de cada tipo de empleado\ngerente1 = gerente(\"Ana\", 101)\ndesarrollador1 = desarrollador(\"Luis\", 102)\ndiseñador1 = diseñador(\"Marta\", 103)\n# Mostrar la información de cada empleado\nprint(gerente1.empleados_info())\nprint(desarrollador1.empleados_info())\nprint(diseñador1.empleados_info())"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/jhoshmc.py",
    "content": "\n\"\"\"\n! EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n\"\"\"\n\nclass Animal:\n  def __init__(self,nombre):\n    self._nombre = nombre\n  def get_sonido(self):\n    print(\"sonido default que se va apisar\")\n\nclass Perro(Animal):\n  def __init__(self, nombre):\n    super().__init__(nombre)\n  def get_sonido(self):\n    print(f\"{self._nombre}: Guau!\")\n\nclass Gato(Animal):\n  def __init__(self, nombre):\n    super().__init__(nombre)\n  def get_sonido(self):\n    print(f\"{self._nombre}: Miau!\")\n\ndef ejercicio():\n  chester= Perro(\"Chester\")\n  lita = Gato(\"Lita\")\n  chester.get_sonido()\n  lita.get_sonido()\n\n# ejercicio()\n# todo extra\n\n\"\"\"\n ! DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n\"\"\"\n\nclass Empleado:\n  #? constructor\n  def __init__(self,id,nombre,cargo):\n    self._id = id\n    self._nombre=nombre\n    self._cargo=cargo\n  #?metodos\n  def get_info_empleado(self):\n    print(f\"Empleado: {self._id}: {self._nombre}  cargo: {self._cargo}\")\n\nclass Gerente(Empleado):\n  #?atributos (herecados y creados en esta clase)\n  def __init__(self, id, nombre, cargo):\n    #?inicializando los atributos heredados\n    super().__init__(id, nombre, cargo)\n    #? atributo propiedo de esta clase\n    self.personal=[]\n  #? metodos de esta clase\n  def set_agregar_personal(self,nuevo_P):\n    self.personal.append(nuevo_P)\n  def get_personal(self):\n    print(f\"Gerente: {self._nombre} con personal a cargo :\\n\")\n    for empleado in self.personal:\n      empleado.get_info_empleado()\n\nclass Gerente_Proyecto(Empleado):\n  def __init__(self, id, nombre, cargo):\n    super().__init__(id, nombre, cargo)\n    self.equipo=[]\n    self.proyectos =[]\n  def set_personal_a_cargo(self,miembro):\n    self.equipo.append(miembro)\n  def set_proyectos(self,nombre_proyecto):\n    self.proyectos.append(nombre_proyecto)\n  def get_equipo(self):\n    print(f\"Gerente de proyectos {self._nombre} con miembors en su equipo: \\n\")\n    for integrante in self.equipo:\n      integrante.get_info_empleado()\n  def get_proyectos(self):\n    print(f\"Gerente de proyectos {self._nombre} con proyectos a cargo: \\n\")\n    for proyecto in self.proyectos:\n      print(proyecto)\n\nclass Programador(Empleado):\n  def __init__(self,id,nombre,cargo):\n    super().__init__(id,nombre,cargo)\n    self._proyecto_en_curso = \"ninguno\"\n  def set_proyecto(self,proyecto):\n    self._proyecto_en_curso = proyecto\n  def get_proyectos_accinados(self):\n    print(f\"Programador: {self._nombre}\")\n    print(f\"proyecto en curso: {self._proyecto_en_curso}\")  \n\n\n\nmanuel = Gerente(\"G989\",\"manuel\",\"Gerente\")\njonas = Gerente_Proyecto(\"G233\", \"Jonas Marques\",\"Gerente de proyectos\")\nroberto= Programador(\"P564\", \"Roberto Hernandez\",\"programador\")\njonas.get_info_empleado()\nroberto.get_info_empleado()\nmanuel.set_agregar_personal(jonas)\nmanuel.set_agregar_personal(roberto)\nmanuel.get_personal()\njonas.set_personal_a_cargo(roberto)\njonas.set_proyectos(\"Cambiar color de boton\")\njonas.set_proyectos(\"Reiniciar la pc\")\njonas.get_equipo()\njonas.get_proyectos()\nroberto.set_proyecto(\"Cambiar color de boton\")\nroberto.get_proyectos_accinados()"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/josealberto13.py",
    "content": "\"\"\" EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\"\"\"\n\nclass Animal:\n    def __init__(self, especie: str):\n        self.especie = especie\n\n    def sonido(self):\n        pass\n\n\nclass Perro(Animal):\n    def sonido(self):\n        print(f\"{self.especie}: Ladra\")\n\n\nclass Gato(Animal):\n    def sonido(self):\n        print(f\"{self.especie}: Maulla\")\n\ndef print_sonido(animal: Animal):\n    animal.sonido()\n\nmy_animal = Animal(\":c\")\nmy_perro = Perro(\"Perro\")\nprint_sonido(my_perro)\n\nmy_gato = Gato(\"Gato\")\nprint_sonido(my_gato)\n\n\n\"\"\" DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cadaepleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo. \"\"\"\n\nclass Empleados:\n    def __init__(self, id: int, nombre: str) :\n        self.nombre = nombre\n        self.id = id\n        self.empleados = []\n\n    def responsabilidades(self):\n        pass\n\n    def add(self, empleado):\n        self.empleados.append(empleado)\n    \n    def print_empleados(self):\n        for empleado in self.empleados:\n            print(empleado.nombre)\n\n\nclass Gerente(Empleados):\n    def responsabilidades(self):\n        print(f\"{self.nombre} Esta a cargo del Departemento de Desarrollo\")\n\n\nclass Manager(Empleados):\n    def responsabilidades(self):\n        print(f\"{self.nombre} Lidera al equipo\")\n\n\nclass Programador(Empleados):\n\n    def __init__(self, id: int, nombre: str, language: str):\n        super().__init__(id, nombre)\n        self.language = language\n\n    def responsabilidades(self):\n        print(f\"{self.nombre} Esta encargado de Programar en {self.language}\")\n\n\ndef responsablidad(empleado: Empleados):\n    empleado.responsabilidades()\n\n\ngerenteTI = Gerente(1, \"José Figueroa\")\nresponsablidad(gerenteTI)\n\nmanagerTI = Manager(121, \"Pepito Alvarez\")\nresponsablidad(managerTI)\n\nprogramador = Programador(131, \"Menganito Rodriguez\", \"Python\")\nresponsablidad(programador)\n\n\nmanagerTI.add(programador)\nmanagerTI.print_empleados()\n\nprogramador.add(managerTI)\nprogramador.print_empleados()"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/josecox13.py",
    "content": "'''\n/*\n * EJERCICIO 9:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n'''\n# Superclase\nclass Animal():\n    def __init__(self, nombre:str) -> None:\n        self.nombre = nombre\n    def sonido(self):\n        print('Sonido no determinado')\n\n#Subclase\n\nclass Perro(Animal):\n    def sonido(self:str):\n        print('Guau')\n\nclass Gato(Animal):\n    def sonido(self:str):\n        print('Miau')\n\nGeneric_Animal = Animal('Animal')\nMisifu = Gato('Misifu')\nTobi = Perro('Tobi')\n\nGeneric_Animal.sonido()\nMisifu.sonido()\nTobi.sonido()\n\n\n\"\"\"\nEjericio extra\n\"\"\"\n\nclass Empleado():\n    def __init__(self, nombre:str, id:int) -> None:\n        self.nombre = nombre\n        self.id = id\n        self.empleados = []\n    def gestionar(self, empleado):\n        self.empleados.append(empleado)\n    def gestionados(self):\n        print(f'{self.nombre} gestiona a los siguientes empleados:')\n        for empleado in self.empleados:\n            print(f'Empleado: {empleado.nombre}')\n    \nclass Programador(Empleado):\n    def __init__(self, nombre:str, id:int, languaje:str) -> None:\n        super().__init__(nombre, id)\n        self.lenguaje = languaje\n        self.cargo = 'Programador'\n    def programar(self):\n        print(f'{self.nombre} programando en {self.lenguaje}')\n    def gestionar(self, empleado):\n        print('Un programador no puede gestionar empleados')\n\nclass Gerente(Empleado):\n    def __init__(self, nombre:str, id:int) -> None:\n        super().__init__(nombre, id)\n        self.cargo = 'Gerente'\n    def coordinar(self):\n        print('Coordinando a {}')\n\nclass Gerente_Proyecto(Empleado):\n    def __init__(self, nombre, id, proyecto:str):\n        super().__init__(nombre, id)\n        self.proyecto = proyecto\n        self.cargo = 'Gerente de Proyecto'\n\n\n    \n    def coordinar(self):\n        print(f'Gestionando el proyecto {self.proyecto}')\n\nGerente_1 = Gerente('Pedro', 4)\nGerente_Proyecto_1 = Gerente_Proyecto('Juan', 5 , 'Proyecto Casas')\nGerente_Proyecto_2 = Gerente_Proyecto('Alvaro', 6 , 'Proyecto Universidad')\nEmpleado_1 = Programador('Luis', 1, 'C++')\nEmpleado_2 = Programador('Maria', 2, 'Python')\nEmpleado_3 = Programador('Ana', 3, 'Java')\n\nGerente_Proyecto_1.gestionar(Empleado_1)\nGerente_Proyecto_1.gestionar(Empleado_2)\nGerente_Proyecto_2.gestionar(Empleado_3)\nGerente_1.gestionar(Gerente_Proyecto_1)\nGerente_1.gestionar(Gerente_Proyecto_2)\n\n\nGerente_1.gestionados()\nEmpleado_1.gestionar(Empleado_2)\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/jptxaya.py",
    "content": "#Herencia\n\nclass Animal:\n    def __init__(self, type, age) -> None:\n        self.type = type\n        self.age = age\n\nclass Perro(Animal):\n    def sonido(self):\n        print(\"Guau\")\n\nclass Gato(Animal):\n    def sonido(self):\n        print(\"Miau\")\n\nperro = Perro(\"Mamifero\",7)\ngato = Gato(\"Mamifero\",5)\n\nperro.sonido()\ngato.sonido()\n\n#Dificultad Extra\nprint(\"Dificultad Extra\"+ \"\\n\")\n\nclass Empleado:\n    def __init__(self,id,nombre) -> None:\n        self.id = id\n        self.nombre = nombre\n\n    def __str__(self) -> str:\n        return \"Empleado id: \" + str(self.id) + \" \" + self.nombre\n    \nclass Gerente(Empleado):\n    def __init__(self, id, nombre,departamento,proyectos) -> None:\n        super().__init__(id, nombre)\n        self.departamento = departamento\n        self.list_proyectos = proyectos\n\n    def list_gerente_proyectos(self) -> str:\n        proyectos = \"\"\n        for elem in self.list_proyectos:\n            proyectos = proyectos + str(elem) + \"\\n\"\n        return proyectos\n\n    def __str__(self) -> str:\n        proyectos = self.list_gerente_proyectos()\n        return \"*Gerente \" + super().__str__() + \" \" + self.departamento + \"\\n\" + proyectos\n    \nclass Gerente_Proyectos(Empleado):\n    def __init__(self, id, nombre,proyecto,programadores) -> None:\n        super().__init__(id, nombre)\n        self.proyecto = proyecto\n        self.list_programadores = programadores\n    \n    def list_programmers(self) -> str:\n        programmes = \"\"\n        for elem in self.list_programadores:\n            programmes = programmes + str(elem) + \"\\n\"\n        return programmes\n\n    def __str__(self) -> str:\n        return \"-Gerente Proyectos \" + super().__str__() + \" \" + self.proyecto + \"\\n\" + self.list_programmers()\n\nclass Programadores(Empleado):\n    def __init__(self, id, nombre, language_program) -> None:\n        super().__init__(id, nombre)\n        self.language_program = language_program\n    def __str__(self) -> str:\n        return \" \".join([\"--Programador\",super().__str__(),\"lenguaje\",self.language_program])\n\n\nprogramador1 = Programadores(6,\"program1\",\"JavaScript\")\nprogramador2 = Programadores(7,\"program2\",\"JavaScript\")\nprogramador3 = Programadores(8,\"program3\",\"React\")\nprogramador4 = Programadores(9,\"program4\",\"React\")\nprogramador5 = Programadores(10,\"program5\",\"Java\")\n\ngerente_pro1 = Gerente_Proyectos(3,\"GPro1\",\"Proyecto1\",[programador1,programador2])\ngerente_pro2 = Gerente_Proyectos(4,\"GPro2\",\"Proyecto2\",[programador3])\ngerente_pro3 = Gerente_Proyectos(5,\"GPro3\",\"Proyecto3\",[programador1,programador2,programador4,programador5])\n\ngerente1 = Gerente(1,\"Gerente1\",\"I+D\",[gerente_pro1,gerente_pro2])\ngerente2 = Gerente(2,\"Gerente2\",\"Finance\",[gerente_pro3])\n\nprint(gerente1)\nprint(gerente2)\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/juanRCoder.py",
    "content": "# Herencia, simplemente una clase extensa o hija de una clase padre.\n# Polimorfismo, se refiere a la coincidencias en los nombres de metodos en las clases pero tienen diferente funcionalidad.\n\n# EXAMPLE:\nclass Padre:\n    def __init__(self, name, lastName):\n        self.name = name\n        self.lastName = lastName\n    \n    def saludar(self): #metodo en la clase Padre\n        return f\"Hola {self.name} {self.lastName}\"\n\n\nclass Hijo(Padre):\n    def __init__(self, name, lastName, age):\n        super().__init__(name, lastName)  # Hereda los atributos de la superclase 'Padre'\n        self.age = age  # inicializando atributo de instancia Hijo\n        \n    def saludar(self): #metodo en la clase Hijo\n        return f\"Soy yo el hijo, {self.name} {self.lastName}, tengo {self.age} anios\"\n        \n        \nheber = Padre('heber', 'ramirez');\nprint(heber.saludar())\n# Hola heber ramirez\n\njuan = Hijo('juan', 'ramirez', 23);\nprint(juan.saludar())\n# Soy yo el hijo, juan ramirez, tengo 23 anios\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n#  * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n#  * Cada empleado tiene un identificador y un nombre.\n#  * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n#  * actividad, y almacenan los empleados a su cargo.\n#  */\n\nclass Empleado:\n    empleados = []\n    \n    def __init__(self, id, name, cargo):\n        self.id = id\n        self.name = name\n        self.cargo = cargo\n        \n    def presentation(self):\n        print(f'ID: {self.id} Nombre: {self.name} Cargo: {self.cargo}')\n        Empleado.empleados.append({\"id\": self.id, \"name\": self.name, \"cargo\": self.cargo})\n    \n    def func_manager(self):\n        return self.empleados\n    \n    def func_projectManager(self):\n        return \"Equipo asignado: Default\"\n    \n    def func_programmer(self):\n        return 'Programando en Default'\n\nclass Manager(Empleado):\n    def func_manager(self):\n        print('Listado de empleados:')\n        return self.empleados\n\nclass ProjectManager(Empleado):\n    def __init__(self, id, name, cargo, equipo):\n        super().__init__(id, name, cargo)\n        self.equipo = equipo\n\n    def func_projectManager(self):\n        return f'Equipo Asignado: {self.equipo}'\n\nclass Programmer(Empleado):\n    def __init__(self, id, name, cargo, language):\n        super().__init__(id, name, cargo)\n        self.language = language\n    \n    def func_programmer(self):\n        return f\"Programando en {self.language}\"\n    \njuan  = Programmer( 12, 'juan', 'web developer', 'python')\nrobert = ProjectManager( 124, 'robert', 'project manager', 'frontend')\nmoure = Manager( 495, 'moureDev', 'CEO')\n\njuan.presentation()\nprint(juan.func_programmer())\n# ID: 12 Nombre: juan Cargo: web developer\n# Programando en python\n\nrobert.presentation()\nprint(robert.func_projectManager())\n# ID: 124 Nombre: robert Cargo: project manager\n# Equipo Asignado: frontend\n\nmoure.presentation()\nprint(moure.func_manager())\n# Listado de empleados:\n# [{'id': 12, 'name': 'juan', 'cargo': 'web developer'}, {'id': 124, 'name': 'robert', 'cargo': 'project manager'}, {'id': 495, 'name': 'moureDev', 'cargo': 'CEO'}]\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/juanchernandezdev.py",
    "content": "### Python Inheritance ###\n\nclass Animal:\n  def __init__(self, name, age):\n    self.name = name\n    self.age = age\n    \nclass Dog(Animal):\n  def __init__(self, name, age):\n    super().__init__(name, age)\n    \n  def sound(self):\n    return f'My dog {self.name} does guauuu'\n    \nclass Cat(Animal):\n  def __init__(self, name, age):\n    super().__init__(name, age)\n    \n  def sound(self):\n    return f'My cat {self.name} does meoww'\n    \nmy_dog = Dog('pucho', 13)\nmy_cat = Cat('steve', 8)\n\nprint(my_dog.sound())\nprint(my_cat.sound())\n\n#! Optional Challenge\n\nclass Employee:\n  def __init__(self, id, name):\n    self.id = id\n    self.name = name\n\nclass Manager(Employee):\n  def __init__(self, id, name):\n    super().__init__(id, name)\n    self.role = 'Manager'\n    \nclass ProjectManager(Employee):\n  def __init__(self, id, name):\n    super().__init__(id, name)\n    self.role = 'Project Manager'\n    \nclass Programmer(Employee):\n  def __init__(self, id, name):\n    super().__init__(id, name)\n    self.role = 'Programmer'\n\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/juandaherrera.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n\"\"\"\n\nfrom __future__ import annotations\n\nimport uuid\nfrom abc import ABC, abstractmethod\nfrom typing import List, Optional, Union\n\n\nclass Animal(ABC):\n    def __init__(self, name: str) -> None:\n        self.name = name\n\n    @abstractmethod\n    def make_sound(self):\n        pass\n\n\nclass Perro(Animal):\n\n    def make_sound(self):\n        print('Guauuu')\n\n\nclass Gato(Animal):\n    def make_sound(self):\n        print('Miauu')\n\n\nfirulais = Perro('Firulais')\nmishi = Gato('Mishi')\n\nfirulais.make_sound()\nmishi.make_sound()\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n\"\"\"\n\n\nclass Employee(ABC):\n\n    def __init__(self, name: str, salary: float, leader: Optional[Employee] = None) -> None:\n        self.id = uuid.uuid4()\n        self.name = name\n        self.salary = salary\n        self.leader = leader\n        self.direct_reports: List[Employee] = []\n\n        if leader:\n            leader.add_direct_report(self)\n\n    def __str__(self) -> str:\n        string = '\\n'.join(\n            (\n                f'ID: {self.id}',\n                f'Nombre: {self.name}',\n                f'Salario: {self.salary:_}',\n                f'Líder: {self.get_leader_name()}',\n                f'Reportes Directos: {self.get_direct_reports_names()}',\n                f'Ejecutando: {self.execute()}',\n            )\n        )\n        return string\n\n    def add_direct_report(self, employee: Employee) -> None:\n        self.direct_reports.append(employee)\n\n    def get_direct_reports_names(self) -> List[str]:\n        return [employee.name for employee in self.direct_reports]\n\n    def get_leader_name(self) -> Union[str, None]:\n        if self.leader and isinstance(self.leader, Employee):\n            return self.leader.name\n        return None\n\n    @abstractmethod\n    def execute(self) -> str:\n        pass\n\n\nclass Manager(Employee):\n    def execute(self):\n        return 'Definiendo estrategía para que la compañía crezca...'\n\n\nclass Projectmanager(Employee):\n\n    def __init__(\n        self, name: str, salary: float, project: str, leader: Optional[Employee] = None\n    ) -> None:\n        super().__init__(name, salary, leader)\n        self.project = project\n\n    def execute(self):\n        return f'Liderando y supervisando el proyecto: {self.project}'\n\n\nclass Developer(Employee):\n    def __init__(self, name: str, salary: float, leader: Optional[Projectmanager] = None) -> None:\n        super().__init__(name, salary, leader)\n        if leader and isinstance(leader, Projectmanager):\n            self.project = leader.project\n        else:\n            self.project = 'sin proyecto'\n\n    def execute(self):\n        return f'Desarrollando en el proyecto: {self.leader.project}'\n\n\nmanager = Manager('Juan David', 35_000_000)\n\nproject_manager_1 = Projectmanager('Esteban', 13_000_000, 'Incentivos', manager)\nproject_manager_2 = Projectmanager('Santiago', 12_500_000, 'Algoritmo', manager)\n\ndeveloper_1 = Developer('Daniel', 8_000_000, project_manager_1)\ndeveloper_2 = Developer('Julian', 8_500_000, project_manager_1)\ndeveloper_3 = Developer('Felipe', 8_000_000, project_manager_1)\ndeveloper_4 = Developer('Duván', 9_000_000, project_manager_2)\ndeveloper_5 = Developer('Brais', 11_000_000, project_manager_2)\n\nprint(manager)\nprint('-' * 25)\nprint(project_manager_1)\nprint('-' * 25)\nprint(project_manager_2)\nprint('-' * 25)\nprint(developer_5)\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/juanmax2.py",
    "content": "\"\"\"\nHerencia\n\"\"\"\n\nclass Animal():\n    def __init__(self, nombre) -> None:\n        self.nombre = nombre\n    \n    def ruido(self):\n        pass\n\nclass Perro(Animal):\n      \n    def ruido(self):\n        print(\"guau\")\n        \nclass Gato(Animal):\n      \n    def ruido(self):\n        print(\"Miau\")\n\ndef hacer_sonido(animal : Animal):\n    animal.ruido()\n    \nanimal1 = Animal(\"James\")\nperro = Perro(\"Peter\")\ngato = Gato(\"Gato\")\n\nperro.ruido()\ngato.ruido()\nprint(\"------------\")\nhacer_sonido(perro)\nprint(\"------------\")\nhacer_sonido(gato)\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n\"\"\"\n\nclass Empleado():\n    def __init__(self, nombre : str, identificador : int):\n        self.nombre = nombre\n        self.identificador = identificador\n        self.empleados = []\n    \n    def add_empleado(self, empleado):\n        self.empleados.append(empleado)\n    \n    def print_empleados(self):\n        for empleado in self.empleados:\n            print(empleado)\n        \n    \nclass Gerente(Empleado):\n    \n    def cordinar_proyecto(self):\n        print(f\"{self.nombre} está coordinando todos los proyectos de la empresa\")\n\nclass GerenteProyecto(Empleado):\n    def __init__(self, nombre, identificador, proyecto):\n        super().__init__(nombre, identificador)\n        self.proyecto = proyecto\n    def cordinar_proyecto(self):\n        print(f\"{self.nombre} está coordinando su proyecto de {self.proyecto}\")    \n\nclass Programador(Empleado):\n    def __init__(self, nombre,  identificador, lenguaje):\n        super().__init__(nombre, identificador)\n        self.lenguaje = lenguaje\n\n    def programar(self):\n        print(f\"{self.nombre} está programando con el lenguaje {self.lenguaje}\")\n\n    def add_empleado(self, empleado : Empleado):\n        print(f\"Un programador no tiene empleados a su cargo, {empleado.nombre} no se añadirá\")\n        \n\n# Caso de uso\ngerente = Gerente(\"Juan\", 1)\ngerente_proyecto = GerenteProyecto(\"Maria\", 2, \"Biomedicina\")\nprogramador = Programador(\"Juanma\", 3, \"Python\")\n\ngerente.add_empleado(gerente_proyecto)\ngerente.cordinar_proyecto()\nprint(\"--------------\")\ngerente_proyecto.add_empleado(programador)\ngerente_proyecto.cordinar_proyecto()\nprint(\"--------------\")\nprogramador.add_empleado(programador)\nprogramador.programar()"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/juanppdev.py",
    "content": "\"\"\"\nEJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n\"\"\"\n#  la herencia es un concepto fundamental en la programación orientada a objetos. Permite que una clase (subclase) herede atributos y métodos de otra clase (superclase).\n\nclass Animal:\n    def __init__(self, nombre):\n        self.nombre = nombre\n\n    def hacer_sonido(self):\n        pass\n\nclass Perro(Animal):\n    def hacer_sonido(self):\n        return \"¡Guau!\"\n\nclass Gato(Animal):\n    def hacer_sonido(self):\n        return \"¡Miau!\"\n\ndef imprimir_sonido(animal):\n    print(f\"{animal.nombre} dice: {animal.hacer_sonido()}\")\n\n# Ejemplo de uso\nmi_perro = Perro(\"Buddy\")\nmi_gato = Gato(\"Whiskers\")\n\nimprimir_sonido(mi_perro)  # Salida: Buddy dice: ¡Guau!\nimprimir_sonido(mi_gato)   # Salida: Whiskers dice: ¡Miau!\n\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n\"\"\"\n\nclass Empleado:\n    def __init__(self, identificador, nombre):\n        self.identificador = identificador\n        self.nombre = nombre\n\n    def trabajar(self):\n        pass\n\nclass Gerente(Empleado):\n    def __init__(self, identificador, nombre, departamento):\n        super().__init__(identificador, nombre)\n        self.departamento = departamento\n        self.empleados_a_cargo = []\n\n    def asignar_empleado(self, empleado):\n        self.empleados_a_cargo.append(empleado)\n\n    def trabajar(self):\n        print(f\"{self.nombre} está supervisando el departamento {self.departamento}\")\n\nclass GerenteProyecto(Gerente):\n    def __init__(self, identificador, nombre, departamento, proyecto):\n        super().__init__(identificador, nombre, departamento)\n        self.proyecto = proyecto\n\n    def trabajar(self):\n        print(f\"{self.nombre} está supervisando el proyecto {self.proyecto}\")\n\nclass Programador(Empleado):\n    def __init__(self, identificador, nombre, lenguaje):\n        super().__init__(identificador, nombre)\n        self.lenguaje = lenguaje\n\n    def codificar(self):\n        print(f\"{self.nombre} está programando en {self.lenguaje}\")\n\n# Ejemplo de uso\ngerente1 = Gerente(1, \"Juan\", \"Desarrollo\")\ngerente2 = GerenteProyecto(2, \"Maria\", \"Desarrollo\", \"Sistema de Gestión\")\nprogramador1 = Programador(3, \"Pedro\", \"Python\")\nprogramador2 = Programador(4, \"Ana\", \"JavaScript\")\n\ngerente1.asignar_empleado(programador1)\ngerente1.asignar_empleado(programador2)\n\ngerente1.trabajar()\nfor empleado in gerente1.empleados_a_cargo:\n    empleado.trabajar()\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/juserdev.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */ \"\"\"\n\n'''\n  ### HERENCIA ###\n  \n  ->  en este ejemplo simplemente crear una clase basica Animal que sirve para darle nombre al animal\n      ademas retorna su nombre\n  ->  cree dos herencias, una para perro y otra para gato\n  ->  se heredan asi\n      ->  class Perro(Aniaml): \n      ->  se debe poner la calse anterior como parametro de la nueva clase\n      ->  cada uno tiene una fucnion clara adentro que retorna el nombre del aniaml y su sonido\n          \n          def perro(self):\n            return f\"mi nombre es {self.nombre} y ladro: Guau!\"\n\n  ->  De esta manera entendemos el concepto de Herencia\n\n  ->  como Programer hereda las funciones de la superclase Employee tambien hereda la funcion add\n      entonces en este caso creamos una funcion add especifica para Programer con el fin que no \n      haga lo que dice que debe hacer la superclase ya que esta es una subclase\n  \n  ->  La manera de heredar en la que las subclases herenda de las superclases basandonos en el ejemplo extra\n      es de esta manera -> Manager(Employee), Manager hereda todas las funciones de Employee\n\n'''\n\nclass Animal:\n  def __init__(self, nombre):\n    self.nombre = nombre\n  \n  def presentarse(self):\n    return f\"Me llamo {self.nombre}\"\n  \nperro_1 = Animal(\"Lucas\")\n\nprint(perro_1.nombre)\nprint(perro_1.presentarse())\n\nclass Perro(Animal):\n  def perro(self):\n    return f\"mi nombre es {self.nombre} y ladro: Guau!\"\n  \nclass Gato(Animal):\n  def gato(self):\n    return f\"mi nombre es {self.nombre} y maullo: Miau!\"\n  \nperro_1 = Perro(\"Lucas\")\ngato = Gato(\"Michi\")\n\nprint(perro_1.perro())\nprint(gato.gato())\n\n### DIFICULTAD EXTRA ###\n\nclass Employee:\n\n  def __init__(self, id: int, name: str):\n    self.id = id\n    self.name = name\n    self.employess = []\n\n  def add(self, employee):\n    self.employess.append(employee)\n\n  def print_employess(self):\n    for employee in self.employess:\n      print(employee.name)\n\nclass Manager(Employee):\n\n  def coordinate_projects(self):\n    print(f\"{self.name} esta coordinando todos los proyectos de la empresa\")\n\nclass ProjectManager(Employee):\n  def __init__(self, id: int, name: str, project: str):\n    super().__init__(id,name)\n    self.project = project\n\n  def coordinate_project(self):\n    print(f\"{self.name} esta coodinando su proyecto\")\n\nclass Programer(Employee):\n  def __init__(self, id: int, name: str, lenguage: str):\n    super().__init__(id, name)\n    self.lenguage = lenguage\n  \n  def code(self):\n    print(f\"{self.name} esta programando en {self.lenguage}\")\n\n  def add(self, employee: Employee):\n    print(f\"Un programador no tiene empleadosa su cargo. {employee.name} no se añadira\")\n\n\nmy_manager = Manager(1, \"Juserdev\")\nmy_project_manager_1 = ProjectManager(2, \"Juan\", \"proyecto 1\")\nmy_project_manager_2 = ProjectManager(3, \"Sebastian\", \"proyecto 2\")\nmy_programer_1 = Programer(4,\"Max\", \"Javascript\")\nmy_programer_2 = Programer(5,\"Laura\", \"Tavascript\")\nmy_programer_3 = Programer(6,\"Carlos\", \"Python\")\nmy_programer_4 = Programer(7,\"Pedro\", \"Java\")\n\nmy_manager.add(my_project_manager_1)\nmy_manager.add(my_project_manager_2)\n\nmy_project_manager_1.add(my_programer_1)\nmy_project_manager_1.add(my_programer_2)\nmy_project_manager_2.add(my_programer_3)\nmy_project_manager_2.add(my_programer_4)\n\nmy_programer_2.add(my_programer_3)\n\nmy_programer_1.code()\nmy_project_manager_1.coordinate_project()\nmy_manager.coordinate_projects()\n\nmy_manager.print_employess()\nmy_project_manager_1.print_employess()\nmy_project_manager_2.print_employess()\nmy_programer_1.print_employess()"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/k-90.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacena los empleados a su cargo.\n */\n\"\"\"\n\n\nclass Animal():\n\n    def __init__(self) -> None:\n        pass\n\nclass Perro(Animal):\n\n    def __init__(self) -> None:\n        super().__init__()\n\n    def sonido(self):\n        print(\"Guau!!!\")\n\nclass Gato(Animal):\n\n    def __init__(self) -> None:\n        super().__init__()\n\n    def sonido(self):\n        print(\"Miau!!!\")\n\nprint(Perro.__bases__)\nprint(Animal.__subclasses__())\nmi_perro = Perro()\nmi_perro.sonido()\n\n\"\"\"\nExtra\n\"\"\"\n\nclass Empleados():\n\n    def __init__(self, id:int, name:str):\n        self.id = id\n        self.name = name\n        self.empleado = []\n\n    def new_empleado(self, empleado):\n        self.empleado.append(empleado)\n\n    def mostrar_empleados(self):\n        for empleado in self.empleado:\n            print (empleado.name)\n\n\n    \nclass Gerente(Empleados):\n\n    def coordinador(self):\n        print(f\"{self.name}, es el coordinador de proyectos.\")\n\n\nclass Gerente_Proyectos(Empleados):\n\n    def __init__(self, id: int, name: str, proyecto: str):\n        super().__init__(id, name)\n        self.proyecto = proyecto\n\n    def coordinador_proyecto(self):\n        print(f\"{self.name}, esta coordinando este proyecto.\")\n\n\nclass Programadores(Empleados):\n\n    def __init__(self, id: int, name: str, lenguaje:str):\n        super().__init__(id, name)\n        self.lenguaje = lenguaje\n        \n\n    def programando(self):\n        print(f\"{self.name}, esta programando en {self.lenguaje}\")\n\n    def añadir(self, empleado:Empleados):\n        print(f\"Un programador no puede añadir nuevos empleados. {empleado.name} no se puede añadir. \")\n\n    \n\n\n\n\n\n\nempleado_1 = Empleados(1107,\"Antonio\")\nprint(empleado_1.id)\nprint(empleado_1.name)\nempleado_2 = Gerente(1108,\"Ezequiel\")\nempleado_2.coordinador()\nempleado_3 = Gerente_Proyectos(1109,\"Miguel\",\"Thermo_1\")\nempleado_3.coordinador_proyecto()\nempleado_4 = Programadores(1215, \"Enrique\",\"Python\")\nempleado_4.programando()"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/kenysdev.py",
    "content": "# ╔══════════════════════════════════════╗\n# ║ Autor:  Kenys Alvarado               ║\n# ║ GitHub: https://github.com/Kenysdev  ║\n# ║ 2024 -  Python                       ║\n# ╚══════════════════════════════════════╝\n\n# ----------------------------------------\n# Herencia\n# ----------------------------------------\n# - Permite definir una clase que hereda atributos y métodos de una \n#   clase existente, para reutilización y organización.\n# - La clase que hereda se conoce como “subclase” o “clase hija”.\n# - La clase de la que hereda se conoce como “superclase” o “clase padre”.\n\n# Polimorfismo:\n# ----------------------------------------\n# - Los objetos de diferentes clases pueden ser accedidos utilizando el \n#   mismo interfaz, mostrando un comportamiento distinto \n#   (tomando diferentes formas) según cómo sean accedidos.\n\n# superclase:\nclass Animal: \n    def __init__(self, name, sound):\n        self.name = name\n        self.sound = sound\n    \n    def make_sound(self):\n        print(f\"{self.name} hace: {self.sound}\")\n\n# subclases:\nclass Dog(Animal):\n    def __init__(self, name):\n        super().__init__(name, \"Woof\")\n\nclass Cat(Animal):\n    def __init__(self, name):\n        super().__init__(name, \"Meow\")\n\n# crear instancias y llamar a sus métodos\ndog = Dog(\"Max\")\ncat = Cat(\"Milo\")\ndog.make_sound()\ncat.make_sound()\n\n#__________________________________________\n# Ejercicio usando herencia y Polimorfismo.\n\"\"\"\n- Implementa la jerarquía de una empresa de desarrollo formada por \n  empleados que pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n- Cada empleado tiene un identificador y un nombre.\n- Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n  actividad, y almacenan los empleados a su cargo.\n\"\"\"\n\nclass Employees:\n    employees: list = []\n    def __init__(self):\n        self.identifier = \"\"\n        self.tasks: tuple = ()\n        self.staff: set = {}\n\n    def add(self, names: tuple):\n        for name in names:\n            self.employees.append([self.identifier, name])\n\n    def println(self):\n        for employee in self.employees:\n            if employee[0] == self.identifier:\n                print(f\"{employee[1]} -> {self.identifier}\")\n\n    def functions(self):\n        print(f\"\\nFunciones de {self.identifier}\")\n        for task in self.tasks:\n            print(task)\n        print(\"--------------------\")\n    \n    def subordinates(self):\n        print(f\"\\nSubordinados de un {self.identifier}\")\n        for employee in self.employees:\n            if employee[0] in self.staff:\n                print(f\"{employee[1]} -> {employee[0]}\")\n        print(\"--------------------\")\n\nclass Manager(Employees):\n    def __init__(self):\n        super().__init__()\n        self.identifier = \"Gerente\"\n        self.tasks: tuple =(\n            \"- Supervisión\", \n            \"- Toma de decisiones\")\n        self.staff: set = {\"Gerente de Proyecto\", \"Programador\"}\n\n\nclass Project_Manager(Employees):\n    def __init__(self):\n        super().__init__()\n        self.identifier = \"Gerente de Proyecto\"\n        self.tasks: tuple =(\n            \"- Planificación\", \n            \"- Coordinación de proyectos\")\n        self.staff: set = {\"Programador\"}\n\nclass Programmer(Employees):\n    def __init__(self):\n        super().__init__()\n        self.identifier = \"Programador\"\n        self.tasks: tuple =(\n            \"- Desarrollo\", \n            \"- Mantenimiento de código\")\n        self.staff = {\"No tiene subordinados\"}\n\n#__________________________________________\nif __name__ == \"__main__\":\n    manager = Manager()\n    project_manager = Project_Manager()\n    programmer = Programmer()\n\n    manager.add((\"Ben\", \"Dan\"))\n    project_manager.add((\"Ray\", \"Joe\"))\n    programmer.add((\"Leo\", \"Sam\", \"Zoe\", \"Ana\"))\n\n    manager.functions()\n    project_manager.functions()\n    programmer.functions()\n\n    manager.subordinates()\n    project_manager.subordinates()\n\n    manager.println()\n    project_manager.println()\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/kuroz00.py",
    "content": "'''\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n'''\n\nclass animal:\n    def __init__(self, nombre, edad):\n        self.nombre = nombre\n        self.edad = edad\n    \nclass perro(animal):\n    def __init__(self, nombre, edad, raza):\n        super().__init__(nombre, edad)\n        self.raza = raza\n    def guau(self):\n        print(f'{self.nombre}: Guau!')\n\nclass gato(animal):\n    def __init__(self, nombre, edad, color):\n        super().__init__(nombre, edad)\n        self.color = color\n    def miau(self):\n        print(f'{self.nombre}: Miau!')\n\npity = perro('Pity', 15, 'Oscuro')\ncroqueta = gato('Croqueta', 9, 'Naranja')\n\npity.guau()\ncroqueta.miau()\n\n'''\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n# \n'''\n\nclass empresa:\n    def __init__(self, nombre_empresa):\n        self.nombre_empresa = nombre_empresa\n\n#Clase base de todos los objetos, la de empresa de momento no tiene mucho que aportar mas que el nombre    \nclass empleado(empresa):\n    def __init__(self, nombre_empresa, id, nombre, ):\n        super().__init__(nombre_empresa)\n        self.id = id\n        self.nombre = nombre\n\n#GERENTE\nclass Gerente(empleado):\n    autorizacion_nvl = 3 #Autorizacion para interactuar con otros objetos, como puertas o acciones dentro de la empresa\n    def __init__(self, nombre_empresa, id, nombre,):\n        super().__init__(nombre_empresa, id, nombre) #Se heredan parametros de \"empleado\"\n\n    def pagar_remuneracion(): #Simple mensaje por pantalla\n        print('El gerente a pagado la remuneracion mensual!')\n\n#Gerente proyectos\nclass gerente_de_proyecto(empleado):\n    autorizacion_nvl = 2\n    def __init__(self, nombre_empresa, id, nombre,):\n        super().__init__(nombre_empresa, id, nombre)\n    \n    def Incentivo():\n        print('El gerente de proyectos ha dado un bono al que termine primero como incentivo!')\n\n#Programador\nclass programador(empleado):\n    autorizacion_nvl = 1\n    def __init__(self, nombre_empresa, id, nombre,):\n        super().__init__(nombre_empresa, id, nombre)\n    \n    def trabajar():\n        print('El programador esta trabajando muy duro!')\n\n###########################################################.-.-.-.-  Instanciar clases para crear los 3 primeros objetos\n\n\njunior1 = programador('Google', '000000000000000001', 'Adan') #se que el id deberia ser numerico, pero me gusta como se ven los \"000000\" en adan xD\nsenior1 = gerente_de_proyecto('Google', 255, 'Jesus')\njefe = Gerente('Google', 0, 'Dios')\n\n###########################################################.-.-.-.-  Haciendo clara referencia a la jerarquia de una empresa, pero con dios xd\n\n\n\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/majinka10.py",
    "content": "from typing import Any\n\n\nclass Animal():\n    def __init__(self, nombre) -> None:\n        self.nombre = nombre\n\n    def emitirSonido(self):\n        print(f\"Hola, soy {self.nombre} y hago algún sonido\")\n\nclass Perro(Animal):\n    def  emitirSonido(self):\n        print(f\"Hola, soy {self.nombre} y hago Guau!\")\n\nclass Gato(Animal):\n    def  emitirSonido(self):\n        print(f\"Hola, soy {self.nombre} y hago Miau!\")\n\nmi_perro = Perro(\"Tony\")\nmi_perro.emitirSonido()\n\nmi_gato = Gato(\"Tom\")\nmi_gato.emitirSonido()\n\n# Ejercicio EXTRA\n\nprint(\"\\nEjercicio con la jerarquía de una empresa de desarrollo.\\n\")\n\nclass Empleado():\n    def __init__(self, nombre: str, ID: str, listaEmpleados: list = None) -> None:\n        self.nombre = nombre\n        self.ID = ID\n        self.listaEmpleados = listaEmpleados\n\n    def funcion(self):\n        print(f\"Hola, soy {self.nombre} con ID {self.ID} y trabajo en esta empresa.\")\n\n    def añadirEmpleadoACargo(self, empleado):\n        self.listaEmpleados.append(empleado)\n\n    def empleadosACargo(self):\n        print(f\"Los empleados a cargo de {self.nombre} son:\")\n        for empleado in self.listaEmpleados:\n            print(empleado.getNombre())\n    \n    def eleminarEmpleadoACargo(self, empleado):\n        self.listaEmpleados.remove(empleado)\n        print(f\"Se ha eliminado al empleado {empleado.getNombre()} de los empleados a cargo de {self.nombre}\")\n\n    def getNombre(self) -> str:\n        return self.nombre\n\nclass Gerente(Empleado):\n    auto = \"Mercedes Benz\"\n    def funcion(self):\n        print(f\"Hola, soy el gerente {self.nombre} con ID {self.ID}, tengo un {self.auto} y administro la empresa.\")\n\nclass ProjectManager(Empleado):\n    bici = \"GW Roja\"\n    def funcion(self):\n        print(f\"Hola, soy el gerente de proyectos {self.nombre} con ID {self.ID}, tengo una {self.bici} y gestiono los proyectos de la empresa.\")\n\nclass Programador(Empleado):\n    patin = \"Xiaomi Electric Scooter 4\"\n    def funcion(self):\n        print(f\"Hola, soy  el programador {self.nombre} con ID {self.ID}, tengo un {self.patin} y escribo código!\")\n\nempleado1 = ProjectManager(\"Juan\", \"102\", [])\nempleado2 = Gerente(\"Pedro\", \"101\", [empleado1])\nempleado3 = Programador(\"Jose\", \"103\")\nempleado4 = Programador(\"Maria\", \"105\")\n\nempleado2.funcion() # Mostrar que hace este empleado.\nempleado2.añadirEmpleadoACargo(empleado4) # Añadir un empleado a sus empleados a cargo.\nempleado2.empleadosACargo() # Mostrar los empleados a su cargo.\nempleado1.añadirEmpleadoACargo(empleado3) # Añadir un empleado a sus empleados a cargo.\nempleado1.funcion() # Mostrar qué hace este empleado.\nempleado1.empleadosACargo() # Mostrar los empleados a su cargo.\nempleado3.funcion() # Mostrar qué hace este empleado.\nempleado2.eleminarEmpleadoACargo(empleado1) # Eliminar un empleado a su cargo.\nempleado2.empleadosACargo() # Mostrar los empleados a su cargo."
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/manjaitan.py",
    "content": "'''\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n '''\n\n# Clase ejemplo animal:\n\nclass Animal:\n    \n    def __init__(self, nombre, sonido) -> None:\n        self.nombre = nombre\n        self.sonido = sonido\n\n    def Sonido (self):\n        print (\n            f\"Sonido: {self.sonido}\")\n\n# Herencia de clase Animal:\n\nclass Perro(Animal):\n    pass\n\nclass Gato(Animal):\n    pass\n\n\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/mariovelascodev.py",
    "content": "class Animal:\n    #Creamos el método constructor de la clase y el atributo del sonido\n    def __init__(self, nombre):\n        self.nombre = nombre\n        self.sonido = \"Sonido que realiza un animal\"\n    \n    def realizar_sonido(self):\n        print(self.sonido)\n\n#Creamos las subclases Perro y Gato que heredaran de la clase Animal\nclass Perro(Animal):\n\n    def __init__(self, nombre):\n        super().__init__(nombre)\n    \n    #Cambiamos el resultado del método realizar_sonido que hace la clase Perro respecto a la clase Animal\n    def realizar_sonido(self):\n        print(\"Guau\")\n\nclass Gato(Animal):\n\n    def __init__(self, nombre):\n        super().__init__(nombre)\n\n    #Cambiamos el resultado del método realizar_sonido que hace la clase Gato respecto a la clase Animal\n    def realizar_sonido(self):\n        print(\"Miau\")\n\nmi_perro = Perro(\"Willie\")\nmi_perro.realizar_sonido()\n\nmi_gato = Gato(\"Lebron\")\nmi_gato.realizar_sonido()\n\n\n#EXTRA\nclass Empleados:\n\n    def __init__(self, identificador, nombre):\n        self.identificador = identificador\n        self.nombre = nombre\n        self.empleados = []\n\n    def add(self, empleado):\n        self.empleados.append(empleado)\n\n    def mostrar_empleados(self):\n        print(\"\\nLos empleados a su cargo son:\")\n        for empleado in self.empleados:\n            print(empleado.nombre)\n\nclass Gerente(Empleados):\n\n    def __init__(self, identificador, nombre):\n        super().__init__(identificador, nombre)\n\n    def coordinar_proyectos(self):\n        print(f\"{self.nombre} esta coordinado los proyectos\")\n\nclass GerenteDeProyectos(Empleados):\n\n    def __init__(self, identificador, nombre):\n        super().__init__(identificador, nombre)\n\n    def coordinar_proyecto(self):\n        print(f\"{self.nombre} está gestionando su proyecto\")\n\nclass Programadores(Empleados):\n\n    def __init__(self, identificador, nombre, lenguaje):\n        super().__init__(identificador, nombre)\n        self.lenguaje = lenguaje\n\n\n    def codigo(self):\n        print(f\"{self.nombre} está programando la app en {self.lenguaje}\")\n\n    def add(self):\n        print(f\"Los programadores no tienen empleados a su cargo.\")\n\nmi_gerente = Gerente(1, \"Manuel\")\nmi_gerente_proyecto = GerenteDeProyectos(2, \"Lucia\")\nmi_programador1 = Programadores(3, \"Mario\", \"Python\")\nmi_programador2 = Programadores(4, \"Marcial\", \"C#\")\nmi_programador3 = Programadores(5, \"Rosa\", \"Python\")\nmi_programador4 = Programadores(6, \"Nuria\", \"Java\")\n\nmi_gerente.add(mi_gerente_proyecto)\nmi_gerente_proyecto.add(mi_programador1)\nmi_gerente_proyecto.add(mi_programador2)\nmi_gerente_proyecto.add(mi_programador3)\nmi_gerente_proyecto.add(mi_programador4)\nmi_programador1.codigo()\nmi_programador2.codigo()\nmi_programador3.codigo()\nmi_programador4.codigo()\n\nmi_gerente.mostrar_empleados()\nmi_gerente_proyecto.mostrar_empleados()"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/mensius87.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n\"\"\"\n\n\nclass Animal:\n\n    def __init__(self, edad, color):\n        self.edad = edad\n        self.color = color\n\n\nclass Perro (Animal):\n\n    def sonido(self):\n\n        print(\"Guau!!!\")\n\n\nclass Gato(Animal):\n\n    def sonido(self):\n        print(\"Miauuuuu!!!\")\n\n\nmissi = Gato(9, \"blanco - negro - marrón\")\n\nmissi.sonido()"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/mhayhem.py",
    "content": "import random\n\n# EJERCICIO:\n# Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n# implemente una superclase Animal y un par de subclases Perro y Gato,\n# junto con una función que sirva para imprimir el sonido que emite cada Animal.\n\nclass Animal:\n    def __init__(self, name):\n        self.name = name.capitalize()\n        def sound():\n            pass\n\nclass Dog(Animal):\n    def sound(self):\n        return f\"{self.name} hace guau!.\"\n\nclass Cat(Animal):\n    def sound(self):\n        return f\"{self.name} hace miau!.\"\n    \n# DIFICULTAD EXTRA (opcional):\n# Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n# pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n# Cada empleado tiene un identificador y un nombre.\n# Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n# actividad, y almacenan los empleados a su cargo.\n\nclass CompanyEmployee:\n    def __init__(self, name:str):\n        self.id = random.randint(100, 999)\n        self.name = name\n        self.employees = []\n        \n    def add_employee(self, employee):\n        self.employees.append(employee)\n        return self.employees\n    \n    def show_employee(self):\n        if self.employees:\n                return [f\"{e.name}: {e.rol}\" for e in self.employees]\n        else:\n            return \"No tiene empleados a su cargo.\"\n    \n    def work(self, project):\n        return f\"{self.name} comienza {project}\"\n    \n    def __str__(self):\n        return f\"{self.name} ({self.id}: {self.rol})\"\n    \n        \nclass Chief(CompanyEmployee):\n    def __init__(self, name, department: str):\n        super().__init__(name)\n        self.rol = \"ceo\"\n        self.department = department\n    \n    def evaluate_employee(self):\n        if self.employees:\n            return [f\"Evaluación del empleado {e.name} con ID {e.id}, ha sido positiva.\" for e in self.employees]\n        else:\n            return \"No hay empleados a cargo.\"\n    \n    def assing_task(self):\n        if self.employees:\n            task_to_do = []\n            for e in self.employees:\n                match e.rol:\n                    case \"developer\":\n                        task_to_do.append(f\"Sr. {e.name} factorice el codigo del producto.\")\n                    case \"project manager\":\n                        task_to_do.append(f\"Sr. {e.name} presente informe del producto.\")\n            return task_to_do\n        else:\n            return f\"No hay empleados a su cargo.\"\n    \nclass ProjectManager(CompanyEmployee):\n    def __init__(self, name, current_project: str):\n        super().__init__(name)\n        self.rol = \"project manager\"\n        self.current_project = current_project\n        \n    def sprint_planning(self):\n        if self.employees:\n            return [f\"{e.name} fecha final del sprint en dos semanas.\" for e in self.employees]\n        else:\n            return \"No hay empleados a cargo.\"\n    \n    def report_progress(self, project: str, percentage: int):\n        return f\"La app '{project}' esta al {percentage} %.\"\n    \n\nclass Developer(CompanyEmployee):\n    def __init__(self, name, level: str):\n        super().__init__(name)\n        self.rol = \"developer\"\n        self.level = level\n        self.languages = []\n        \n    def dev_languages(self, *args):\n        for item in args:\n            self.languages.append(item)\n    \n    def show_languages(self):\n        return f\"Conocimiento de los siguientes lenguajes/frameworks: {self.languages}.\"\n    \n    def click_code(self):\n        return f\"desarrollaror {self.name} empieza a picar código.\""
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/miguelex.py",
    "content": "class Animal:\n    def __init__ (self, nombre):\n        self.nombre = nombre\n        \n    def sonido(self):\n        print(self.nombre + \"hace ruido...\")\n        \nclass Perro(Animal):\n    def sonido(self):\n        print(\"El perro de nombre \" + self.nombre + \" ladra haciendo 'Guau, guau'...\")\n        \nclass Gato(Animal):\n    def sonido(self):\n        print(\"El gato de nombre \" + self.nombre + \" maulla haciendo 'Miau, miau'...\")\n        \nperro = Perro(\"Milu\")\nperro.sonido()\n\ngato = Gato(\"Garfield\")\ngato.sonido()\n\nclass Empleado():\n    def __init__(self, id ,nombre):\n        self.id = id\n        self.nombre = nombre        \n        \nclass Gerente(Empleado):\n    def __init__(self, id, nombre, personas_a_cargo):\n        super().__init__(id, nombre)\n        self.personal = personas_a_cargo\n    \n    def mostrar(self):\n        print(\"Gerente: \", self.nombre, \" con \", self.personal, \" personas a cargo\")\n        \n    def convocar(self):\n        print(\"Reunión con el personal\")\n        for a in self.personal:\n            print(a)\n\nclass GerenteP(Empleado):\n    def __init__(self, id, nombre, personas_a_cargo):\n        super().__init__(id, nombre)\n        self.personal = personas_a_cargo\n    \n    def mostrar(self):\n        print(\"Gerente: \", self.nombre, \" con \", self.personal, \" programadores a cargo\")\n        \n    def convocar(self):\n        print(\"Reunión con el programador\")\n        for a in self.personal:\n            print(a)\nclass Programador(Empleado):\n    def __init__(self, id, nombre, lenguajes):\n        super().__init__(id, nombre)\n        self.lenguajes = lenguajes\n    \n    def mostrar(self):\n        print(\"Programador: \", self.nombre, \" maneja los lenguajes \", self.lenguajes)\n        \n    def programar(self):\n        print(self.nombre + \" programara hoy en: \")\n        for a in self.lenguajes:\n            print(a)\n\ngerente1 = Gerente(1, \"Juan\", [\"Pedro\", \"Luis\", \"Ana\"])\ngerente1.mostrar()\ngerente1.convocar()\n\ngerente2 = Gerente(2, \"Migue\", [\"Jose\", \"Rafa\", \"Maria\"])\ngerente2.mostrar()\ngerente2.convocar()    \n\njefe1 = GerenteP(3, \"Pedro\", [\"Alberto\", \"Pepa\", \"Josefa\"])   \njefe1.mostrar()\njefe1.convocar()\n\njefe2 = GerenteP(4, \"Luis\", [\"Rafael\", \"Miguel\", \"María\"])\njefe2.mostrar()\njefe2.convocar()\n\nprogramador1 = Programador(5, \"Alberto\", [\"Python\", \"Java\", \"C++\"]) \nprogramador2 = Programador(6, \"Pepa\", [\"Pascal\", \"Javascript\", \"C\", \"Python\"])\n\nprogramador1.mostrar()\nprogramador1.programar()\n\nprogramador2.mostrar()\nprogramador2.programar()\n\n            "
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/mikelm2020.py",
    "content": "import uuid\n\n\n# Superclase animal y subclases perro y gato\nclass Animal:\n    def __init__(self, name, breed):\n        self.name = name\n        self.breed = breed\n\n    def sound_of_animal(self):\n        pass\n\n\nclass Dog(Animal):\n    def sound_of_animal(self):\n        return print(\"Guau Guau\")\n\n\nclass Cat(Animal):\n    def sound_of_animal(self):\n        return print(\"Miau Miau\")\n\n\n# Extra\n# Jerarquía\nclass Employees:\n    employees_subordinates = []\n\n    def __init__(self, name):\n        self.id = uuid.uuid4()\n        self.name = name\n\n    def add_subordinate(self, id, name, boss):\n        self.employees_subordinates.append({\"id\": id, \"name\": name, \"boss\": boss})\n\n    def subordinates(self, boss):\n        subordinates_list = [\n            element\n            for element in self.employees_subordinates\n            if element[\"boss\"] == boss\n        ]\n        return print(subordinates_list)\n\n\nclass Managers(Employees):\n    def organize(self):\n        print(\"El Gerente esta organizando una junta...\")\n\n    def hire(self):\n        print(\"El Gerente esta contratando personal\")\n\n    def to_plan(self):\n        print(\"El Gerente esta planificando una estrategía para obtener más clientes\")\n\n\nclass ProjectManagers(Employees):\n    def lead(self):\n        print(\"El Gerente de Proyecto esta dirigiendo al equipo de desarrollo\")\n\n    def define_objectives(self):\n        print(\n            \"El Gerente de Proyecto esta definiendo los objetivos para el backend del proyecto\"\n        )\n\n    def to_motivate(self):\n        print(\"El Gerente de Proyecto esta motivando a los desarrolladores\")\n\n\nclass Developers(Employees):\n    technological_stack = []\n\n    def __init__(self, name, role):\n        super().__init__(name)\n        self.role = role\n\n    def program(self):\n        print(\"El pogramador esta programando en su lenguaje favorito\")\n\n    def add_technology(self, technology):\n        self.technological_stack.append(technology)\n\n    def get_technological_stack(self):\n        print(self.technological_stack)\n\n    def role(self):\n        print(f\"El programador es: {self.role}\")\n\n\nif __name__ == \"__main__\":\n    dog = Dog(name=\"Boby\", breed=\"Pastor aleman\")\n    dog.sound_of_animal()\n    cat = Cat(name=\"Mishi\", breed=\"Siames\")\n    cat.sound_of_animal()\n\n    manager = Managers(\"Raul Jimenez\")\n    project_manager1 = ProjectManagers(\"Saul Najera\")\n    project_manager2 = ProjectManagers(\"Leticia Olmedo\")\n    backend_1 = Developers(\"Miguel Angel López\", \"Desarrollador Backend\")\n    backend_2 = Developers(\"Romina Palafox\", \"Desarrollador Backend\")\n    backend_3 = Developers(\"Alma Benavides\", \"Desarrollador Backend\")\n    frontend_1 = Developers(\"Luis Mendoza\", \"Desarrollador Frontend\")\n    frontend_2 = Developers(\"Ramiro Gutierrez\", \"Desarrollador Frontend\")\n    frontend_3 = Developers(\"Stefania Riquelme\", \"Desarrollador Frontend\")\n    devops_1 = Developers(\"Ramiro Corona\", \"Devops\")\n    devops_2 = Developers(\"Reina Camacho\", \"Devops\")\n\n    manager.add_subordinate(project_manager1.id, project_manager1.name, boss=manager.id)\n    manager.add_subordinate(project_manager2.id, project_manager2.name, boss=manager.id)\n    print(f\"Los subordinados del Gerente {manager.name} son: \")\n    manager.subordinates(manager.id)\n    project_manager1.add_subordinate(\n        backend_3.id,\n        backend_3.name,\n        boss=project_manager1.id,\n    )\n    project_manager1.add_subordinate(\n        frontend_1.id,\n        frontend_1.name,\n        boss=project_manager1.id,\n    )\n    project_manager1.add_subordinate(\n        frontend_2.id,\n        frontend_2.name,\n        boss=project_manager1.id,\n    )\n    project_manager1.add_subordinate(\n        devops_1.id,\n        devops_1.name,\n        boss=project_manager1.id,\n    )\n    print(f\"Los subordinados del Gerente de Proyecto 1 {project_manager1.name} son: \")\n    project_manager1.subordinates(project_manager1.id)\n    project_manager2.add_subordinate(\n        backend_1.id,\n        backend_1.name,\n        boss=project_manager2.id,\n    )\n    project_manager2.add_subordinate(\n        backend_2.id,\n        backend_2.name,\n        boss=project_manager2.id,\n    )\n    project_manager2.add_subordinate(\n        frontend_3.id,\n        frontend_3.name,\n        boss=project_manager2.id,\n    )\n    project_manager2.add_subordinate(\n        devops_2.id,\n        devops_2.name,\n        boss=project_manager2.id,\n    )\n    print(f\"Los subordinados del Gerente de Proyecto 2 {project_manager2.name} son: \")\n    project_manager2.subordinates(project_manager2.id)\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/monicavaquerano.py",
    "content": "# 09 HERENCIA Y POLIMORFISMO\n# Monica Vaquerano\n# https://monicavaquerano.dev\n\n\n\"\"\"\nEJERCICIO:\nExplora el concepto de herencia según tu lenguaje. Crea un ejemplo que\nimplemente una superclase Animal y un par de subclases Perro y Gato,\njunto con una función que sirva para imprimir el sonido que emite cada Animal.\n\"\"\"\nprint(\"Herencia y polimorfismo\\n\")\n# La herencia es un mecanismo que permite que una clase (llamada subclase o clase derivada) herede atributos y métodos de otra clase (llamada superclase o clase base).\n# Esto permite la reutilización de código y la creación de una jerarquía de clases.\n\n\n# Superclase\nclass Animal:\n    def __init__(self, name):\n        self.name = name\n\n    def sound(self):\n        pass  # Método abstracto, será implementado por las subclases\n\n    def make_sound(self):\n        print(f\"{self.name}: {self.sound()}\")\n\n    def __str__(self):\n        return f\"{self.__class__.__name__}: {self.name}\"\n\n\n# Subclases\nclass Perro(Animal):\n    def sound(self):\n        return \"¡Guau!\"\n\n\nclass Gato(Animal):\n    def sound(self):\n        return \"¡Miau!\"\n\n\nprint(\"Instancias de las sublases:\")\n# Crear instancias de las subclases\nsnoopy = Perro(\"Snoopy\")\ngarfield = Gato(\"Garfield\")\n\n# Imprimir el sonido de cada animal\nprint(snoopy)\nprint(garfield)\nsnoopy.make_sound()\ngarfield.make_sound()\n\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\nImplementa la jerarquía de una empresa de desarrollo formada por Empleados que\npueden ser Gerentes, Gerentes de Proyectos o Programadores.\nCada empleado tiene un identificador y un nombre.\nDependiendo de su labor, tienen propiedades y funciones exclusivas de su\nactividad, y almacenan los empleados a su cargo.\n\"\"\"\nprint(\"\\nDIFICULTAD EXTRA (opcional):\")\n\n\nclass Empleado:\n    def __init__(self, id, nombre):\n        self.id = id\n        self.nombre = nombre\n\n    def actividades(self):\n        pass\n\n    def imprimir_informacion(self):\n        print(\n            f\"--- {self.__class__.__name__} ---\\nid: {self.id}\\nnombre: {self.nombre}\"\n        )\n\n    def __str__(self):\n        return f\"{self.__class__.__name__}: {self.nombre} - ID: {self.id}\"\n\n\nclass Gerente(Empleado):\n    def __init__(self, id, nombre, departamento):\n        super().__init__(id, nombre)\n        self.departamento = departamento\n        self.empleados_a_cargo = []\n\n    def agregar_empleado(self, empleado):\n        self.empleados_a_cargo.append(empleado)\n\n    def actividades(self):\n        return f\"Gestionar el departamento de {self.departamento}\"\n\n    def imprimir_informacion(self):\n        super().imprimir_informacion()\n        print(f\"departamento: {self.departamento}\\nactividades: {self.actividades()}\")\n\n    def __str__(self):\n        return super().__str__() + f\", Departamento: {self.departamento}\"\n\n\nclass GerenteProyecto(Gerente):\n    def __init__(self, id, nombre, departamento, proyectos_asignados):\n        super().__init__(id, nombre, departamento)\n        self.proyectos_asignados = proyectos_asignados\n\n    def actividades(self):\n        return f\"Gestionar los proyectos: {', '.join(self.proyectos_asignados)} del departamento de {self.departamento}\"\n\n    def imprimir_informacion(self):\n        super().imprimir_informacion()\n        print(f\"proyectos asignados: {', '.join(self.proyectos_asignados)}\")\n\n    def __str__(self):\n        return (\n            super().__str__()\n            + f\", Proyectos asignados: {', '.join(self.proyectos_asignados)}\"\n        )\n\n\nclass Programador(Empleado):\n    def __init__(self, id, nombre, lenguajes):\n        super().__init__(id, nombre)\n        self.lenguajes = lenguajes\n\n    def actividades(self):\n        return f\"Programar aplicaciones en: {', '.join(self.lenguajes)}\"\n\n    def imprimir_informacion(self):\n        super().imprimir_informacion()\n        print(f\"lenguajes: {', '.join(self.lenguajes)}\")\n\n    def __str__(self):\n        return super().__str__() + f\", Lenguajes: {', '.join(self.lenguajes)}\"\n\n\nalice = Gerente(1, \"Alice\", \"Ventas\")\nbob = GerenteProyecto(2, \"Bob\", \"Ventas\", [\"Proyecto 1\", \"Proyecto 2\", \"Proyecto 3\"])\ncharlie = Programador(3, \"Charlie\", [\"Python\", \"JavaScript\"])\n\nalice.imprimir_informacion()\nbob.imprimir_informacion()\ncharlie.imprimir_informacion()\n\nalice.agregar_empleado(bob)\nalice.agregar_empleado(charlie)\n\nprint(f\"\\n{alice.nombre} tiene a cargo los siguientes empleados:\")\nfor empleado in alice.empleados_a_cargo:\n    print(\"\\t\", empleado)\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/mordevspt.py",
    "content": "\"\"\"\nExplora el concepto de herencia según tu lenguaje. Crea un ejemplo que\nimplemente una superclase Animal y un par de subclases Perro y Gato,\njunto con una función que sirva para imprimir el sonido que emite cada Animal.\n\"\"\"\n\n\"\"\" \nSOLO HERENCIA \n\"\"\"\n\n# Clase Padre\nclass Animalsh:\n    # Declaramos las funciones en la calse padre y no hacemo nada en las clases hija\n    def soundAnimal(self,sound):\n        return print(sound)\n\n# Clases hijas o subclases\nclass Dogsh(Animalsh):\n    pass\n\nclass Catsh(Animalsh):\n    pass\n\n# Probando el código\nperro = Dogsh()\nperro.soundAnimal(\"¡Guau!\")\n\ngato = Catsh()\ngato.soundAnimal(\"¡Miau!\")\n\n\"\"\"\nHERENCIA CON POLIMORFISMO\n\nEl polimorfismo es una técnica en programación que permite a objetos de diferentes \nclases responder a los mismos mensajes (métodos)\n\"\"\"\n\n# Clase Padre\nclass Animal:\n    # Declaramos el método en la clase padere, pero no lo desarrollamos\n    def soundAnimal(self):\n        pass\n\n# Clases hijas o subclases\nclass Dog(Animal):\n    # Sobrecargamos el método, lo especializamos\n    def soundAnimal(self):\n        print(\"¡Guau!\")\n\nclass Cat(Animal):\n    # Sobrecargamos el método, lo especializamos\n    def soundAnimal(self):\n        print(\"¡Miau!\")\n\n# En vez de llamar a cada función de un animal cualquiera,\n# podemos llamar a una función que las llame\ndef petSound(animal: Animal):\n    animal.soundAnimal()\n    \n# Probando el código\nperro = Dog()\n#perro.soundAnimal()\npetSound(perro)\n\ngato = Cat()\n#gato.soundAnimal()\npetSound(gato)\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n Cada empleado tiene un identificador y un nombre.\n Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n actividad, y almacenan los empleados a su cargo.\n\"\"\"\n\nclass Employee():\n    # Contador de instancias\n    instance_count = 0 \n\n    # Incrementamos el contador por instancia\n    @classmethod\n    def increaseInstanceCount(cls):\n        cls.instance_count += 1\n    # Obtenemos el contador, la cantidad de instancias correspondientes\n    @classmethod\n    def getInstanceCount(cls):\n        return cls.instance_count\n        \n    def __init__(self,id:int,name:str):\n        self.increaseInstanceCount() # Aumentamos el contador cada vez que se instancie\n        self.name = name\n        self.id = id\n        self.employees = [] #Lista donde guardaremos a los empleados que agregamos a los cargos\n    \n    # Agregado de empleados\n    def addEmployee(self,employee):\n        self.employees.append(employee)\n        \n    # Obtener los empleados a su cargo\n    def getEmployees(self):\n        # Recorremos la lista\n        for employee in self.employees:\n            print(employee.name)\n        \nclass Manager(Employee):\n    # MÉTODOS\n    def strategy(self):\n        print(f\"{self.name} está definiendo la estrategia empresarial\")\n    def decision(self):\n        print(f\"{self.name} toma decisiones clave en la empresa\")\n    def manage(self):\n        print(f\"{self.name} administra los recursos y presupuestos de la empresa\")\n\nclass Projectmanager(Employee):\n    # Inicializador propio\n    def __init__(self, id:int, name:str, proyect:str):\n        super().__init__(id,name) # Lo que necesitamos de la clase padre (Super)\n        self.proyect = proyect # Propiedad propia de la clase\n        \n    # MÉTODOS\n    def plan_manage_project(self):\n        print(f\"{self.name} está planificando y gestionando sus proyectos\")\n    def budgets(self):\n        print(f\"{self.name} define presupuestos para el proyecto\")\n    def schedule(self):\n        print(f\"{self.name} define los cronogramas del proyecto\")\n    def meeting(self):\n        print(f\"{self.name} liderar las reuniones del proyecto\")\n\nclass Programmer(Employee):        \n    # Inicializador propio\n    def __init__(self, id:int, name:str, language:str):\n        super().__init__(id,name) # Lo que necesitamos de la clase padre (Super)\n        self.language = language # Propiedad propia de la clase\n    \n    # Los progamadores no pueden tener empleados, sobre-escribimos\n    def addEmployee(self, employee):\n        pass\n    \n    # MÉTODOS\n    def code(self):\n        print(f\"{self.name} está programando código en el lenguaje {self.language}\")\n    def test(self):\n        print(f\"{self.name} está testeando el software\")\n    def debugging(self):\n        print(f\"{self.name} está depurando el código en el lenguaje {self.language}\")\n    def delivery(self):\n        print(f\"{self.name} está entrangando el software\")\n\n# Manager\nmanager = Manager(1,\"Sauron\")\nprint(f\"El Manager de la empresa se llama {manager.name} y tiene como identificador el número {manager.id}\")\nmanager.strategy()\n\n# Proyect Manager\npmanager1 = Projectmanager(5,\"Bilbo\",\"Proyect1\")\nprint(f\"El Project Manager de la empresa se llama {pmanager1.name} y tiene como identificador el número {pmanager1.id}\")\npmanager1.budgets()\n\npmanager2 = Projectmanager(7,\"Bolson\",\"Proyect2\")\nprint(f\"El Project Manager de la empresa se llama {pmanager2.name} y tiene como identificador el número {pmanager2.id}\")\npmanager2.schedule()\n\n# Programmer\nprogramer1 = Programmer(11,\"Perry\",\"Python\")\nprogramer2 = Programmer(12,\"Merry\",\"JavaScript\")\nprint(f\"Tienen dos programadores llamados {programer1.name} y {programer2.name}\")\nprogramer1.code()\nprogramer2.test()\n\n# Número de instancias Totales\nprint(f\"Instancias totales: {Manager.getInstanceCount() + Projectmanager.getInstanceCount() + Programmer.getInstanceCount()}\")\n\n# Añanir empleados\nmanager.addEmployee(pmanager1)\nmanager.addEmployee(pmanager2)\npmanager1.addEmployee(programer1)\npmanager2.addEmployee(programer2)\n\n# Mostramos los empleados\nprint(f\"El Manager {manager.name} tiene como emepleados a los Project Manager:\")\nmanager.getEmployees()\nprint(f\"El Project Manager {pmanager1.name} tiene como emepleados a los Programmers:\")\npmanager1.getEmployees()\nprint(f\"El Project Manager {pmanager2.name} tiene como emepleados a los Programmers:\")\npmanager2.getEmployees()"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/mouredev.py",
    "content": "\"\"\"\nEjercicio\n\"\"\"\n\n\n# Superclase\n\nclass Animal:\n\n    def __init__(self, name: str):\n        self.name = name\n\n    def sound(self):\n        pass\n\n# Subclases\n\n\nclass Dog(Animal):\n\n    def sound(self):\n        print(\"Guau!\")\n\n\nclass Cat(Animal):\n\n    def sound(self):\n        print(\"Miau!\")\n\n\ndef print_sound(animal: Animal):\n    animal.sound()\n\n\nmy_animal = Animal(\"Animal\")\nprint_sound(my_animal)\nmy_dog = Dog(\"Perro\")\nprint_sound(my_dog)\nmy_cat = Cat(\"Gato\")\nprint_sound(my_cat)\n\n\"\"\"\nExtra\n\"\"\"\n\n\nclass Employee:\n\n    def __init__(self, id: int, name: str):\n        self.id = id\n        self.name = name\n        self.employees = []\n\n    def add(self, employee):\n        self.employees.append(employee)\n\n    def print_employees(self):\n        for employee in self.employees:\n            print(employee.name)\n\n\nclass Manager(Employee):\n\n    def coordinate_projects(self):\n        print(f\"{self.name} está coordinando todos los proyectos de la empresa.\")\n\n\nclass ProjectManager(Employee):\n\n    def __init__(self, id: int, name: str, project: str):\n        super().__init__(id, name)\n        self.project = project\n\n    def coordinate_project(self):\n        print(f\"{self.name} está coordinando su proyecto.\")\n\n\nclass Programmer(Employee):\n\n    def __init__(self, id: int, name: str, language: str):\n        super().__init__(id, name)\n        self.language = language\n\n    def code(self):\n        print(f\"{self.name} está programando en {self.language}.\")\n\n    def add(self, employee: Employee):\n        print(\n            f\"Un programador no tiene empleados a su cargo. {employee.name} no se añadirá.\")\n\n\nmy_manager = Manager(1, \"MoureDev\")\nmy_project_manager = ProjectManager(2, \"Brais\", \"Proyecto 1\")\nmy_project_manager2 = ProjectManager(3, \"Moure\", \"Proyecto 2\")\nmy_programmer = Programmer(4, \"Kontrol\", \"Swift\")\nmy_programmer2 = Programmer(5, \"Ros\", \"Cobol\")\nmy_programmer3 = Programmer(6, \"Bushi\", \"Dart\")\nmy_programmer4 = Programmer(7, \"Nasos\", \"Python\")\n\nmy_manager.add(my_project_manager)\nmy_manager.add(my_project_manager2)\n\nmy_project_manager.add(my_programmer)\nmy_project_manager.add(my_programmer2)\nmy_project_manager2.add(my_programmer3)\nmy_project_manager2.add(my_programmer4)\n\nmy_programmer.add(my_programmer2)\n\nmy_programmer.code()\nmy_project_manager.coordinate_project()\nmy_manager.coordinate_projects()\nmy_manager.print_employees()\nmy_project_manager.print_employees()\nmy_programmer.print_employees()\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/mrodara.py",
    "content": "###################################### HERENCIA ########################################\n'''\nLa herencia es un mecanismo de la programación orientada a objetos que sirve para crear clases nuevas a partir de clases preexistentes. Se toman (heredan) atributos y métodos de las clases bases y se los modifica para modelar una nueva situación.\n\nLa clase desde la que se hereda se llama clase base y la que se construye a partir de ella es una clase derivada.\n\nSi nuestra clase base es la clase punto que hemos visto antes, puedo crear una nueva clase de la siguiente manera:\n'''\n\nfrom math import sqrt\n\nclass Punto():\n    \n    def __init__(self, x: int = 0, y: int = 0) -> None:\n        self.__x = x # Definición de atributo privado (encapsulación)\n        self.__y = y\n\n    @property\n    def x(self) -> int:\n        print('Imprimiendo coordenada X:')\n        return self.__x\n    \n    @property\n    def y(self) -> int:\n        print('Imprimiendo coordenada y:')\n        return self.__y\n    \n    @x.setter\n    def x(self, x: int = 0) -> None:\n        print('Cambio x')\n        self.__x = x\n        \n    @y.setter\n    def y(self, y: int = 0) -> None:\n        print('Cambio y')\n        self.__y = y\n        \n    def mostrar(self) -> None:\n        return str(self.__x) + \":\" + str(self.__y)\n    \n    def distancia(self, point) -> None:\n        dx = self.__x - point.x\n        dy = self.__y - point.y\n        \n        return sqrt((dx*dy + dy*dy)** 0.5)\n    \nclass Punto3D(Punto):\n    \n    def __init__(self, x:int = 0, y:int = 0, z:int = 0):\n        super().__init__(x, y) # Llamada al constructor de la clase base\n        self.__z = z # Atributo propio de la clase derivada\n        \n    @property\n    def z(self) -> None:\n        print('Imprimiendo coordenada Z:')\n        return self.__z\n    \n    @z.setter\n    def z(self, z) -> None:\n        print('Cambio coordenada Z')\n        self.__z = z\n    \n    # Sobreescritura de métdos\n    def mostrar(self) -> None:\n        return super().mostrar() + \":\" + str(self.__z)\n    \n    def distancia(self, npoint) -> None:\n        '''\n        Devuelve la distancia entre ambos puntos 3D\n        '''\n        \n        dx = self.__x - npoint.x\n        dy = self.__y - npoint.y\n        dz = self.__z - npoint.z\n        \n        return (dx*dx + dy*dy + dz*dz) ** 0.5 \n\n\nclass Animal():\n    \n    def __init__(self, name: str, age: int) -> None:\n        self.__name = name\n        self.__age = age\n        \n    @property\n    def name(self) -> str:\n        return self.__name\n    \n    @property\n    def age(self) -> int:\n        return self.__age\n    \n    @name.setter\n    def name(self, name: str) -> None:\n        print('Cambiando nombre')\n        self.__name = name\n    \n    @age.setter\n    def age(self, age: int) -> None:\n        print('Cambiando nombre')\n        self.__age = age\n        \n# EJERCICIO PRINCIPAL\n      \nclass Dog(Animal):\n    \n    def __init__(self, name: str, age: int, race: str) -> None:\n        super().__init__(name, age)\n        self.__race = race\n        \n    @property\n    def race(self) -> None:\n        return self.__race\n    \n    @race.setter\n    def race(self, race: str) -> None:\n        print('Estableciendo raza.')\n        self.__race = race\n        \n    def talk(self) -> None:\n        print('Woof Woof!!!')\n\nclass Cat(Animal):\n    \n    def __init__(self, name: str, age: int, race: str) -> None:\n        super().__init__(name, age)\n        self.__race = race\n        \n    @property\n    def race(self) -> None:\n        return self.__race\n    \n    @race.setter\n    def race(self, race: str) -> None:\n        print('Estableciendo raza.')\n        self.__race = race\n        \n    def talk(self) -> None:\n        print('Miau Miau!!!') \n        \n\npet1 = Dog(name=\"Coco\", age=5, race=\"Golden Retriever\")\npet2 = Cat(name=\"Perla\", age=7, race=\"Romano\")\n\nprint(pet1.name)\nprint(pet1.age)\nprint(pet1.talk())\nprint(pet2.name)\nprint(pet2.age)\nprint(pet2.talk())\n\n# FIN EJERCICIO PRINCIPAL\n\n# DIFICULTAD EXTRA\n\nclass Employee():\n    def __init__(self, id: str, name: str) -> None:\n        self.__id = id\n        self.__name = name\n    \n    @property\n    def id(self) -> str:\n        return self.__id\n    \n    @id.setter\n    def id(self, id: str) -> None:\n        self.__id = id\n    \n    @property\n    def name(self) -> str:\n        return self.__name\n    \n    @name.setter\n    def name(self, name: str) -> None:\n        self.__name = name\n    \nclass Programmer(Employee):\n    \n    def __init__(self, id, name, languages: list = []):\n        super().__init__(id, name)\n        self.__languages = languages\n        \n    @property\n    def languages(self) -> list:\n        return self.__languages\n    \n    @languages.setter\n    def languages(self, languages: list) -> None:\n        self.__languages = languages\n    \n    def work(self) -> None:\n        print('Coding...')\n\nclass ProyectManager(Employee):\n    \n    def __init__(self, id, name, programmers: list = []):\n        super().__init__(id, name)\n        self.__programmers = programmers\n    \n    @property\n    def programmers(self) -> list:\n        return self.__programmers\n    \n    @programmers.setter\n    def programmers(self, programmers: list) -> None:\n        self.__programmers = programmers\n        \n    def work(self) -> None:\n        print('Managing projects...')\n        \nclass Manager(Employee):\n    \n    def __init__(self, id, name, employees: list = []):\n        super().__init__(id, name)\n        self.__employees = employees\n    \n    @property\n    def employees(self) -> list:\n        return self.__employees\n    \n    @employees.setter\n    def employees(self, employees: list) -> None:\n        self.__employees = employees\n        \n    def work(self) -> None:\n        print('Managing...')\n        \n        \np1 = Programmer(id=\"1\", name=\"Juan\", languages=[\"Python\", \"Java\"])\np2 = Programmer(id=\"2\", name=\"Maria\", languages=[\"C++\", \"C#\"])\np3 = Programmer(id=\"3\", name=\"Pedro\", languages=[\"JavaScript\", \"PHP\"])\np4 = Programmer(id=\"4\", name=\"Ana\", languages=[\"Ruby\", \"Swift\"])\np5 = Programmer(id=\"5\", name=\"Luis\", languages=[\"Go\", \"Kotlin\"])\n\npm1 = ProyectManager(id=\"6\", name=\"Carlos\", programmers=[p1, p2])\npm2 = ProyectManager(id=\"7\", name=\"Laura\", programmers=[p3, p4])\npm3 = ProyectManager(id=\"8\", name=\"Sofia\", programmers=[p5])\n\nm1 = Manager(id=\"9\", name=\"Javier\", employees=[pm1, pm2, pm3])\nm1.work()\npm1.work()\np1.work()\np2.work()\np3.work()\np4.work()\np5.work()\n\n# Listar todos los programdores asignados a un ProjectManager\nfor p in pm1.programmers:\n    print(p.name)\n\n# FIN DIFICULTAD EXTRA\n       \n###################################### FIN HERENCIA ########################################"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/mvidalb.py",
    "content": "'''\nEjercicio\n'''\n# Superclase\n\nclass Animal:\n    \n    def __init__(self, name: str) -> None:\n        self.name = name\n\n    def sound(self):\n        print(\"Este animal emite un sonido no determinado\")\n\n\n#Subclases\n\nclass Dog(Animal):\n    \n    def sound(self):\n        print(\"Guau!\")\n\n\nclass Cat(Animal):\n    \n    def sound(self):\n        print(\"Miau!\")\n\n\ndef print_sound(animal: Animal):\n    animal.sound()\n\n\nmy_animal = Animal(\"Animal\")\nprint_sound(my_animal)\nmy_animal = Dog(\"Perro\")\nprint_sound(my_animal)\nmy_animal = Cat(\"Gato\")\nprint_sound(my_animal)\n\n\n'''\nEjercicio extra\n'''\n\nclass Employee():\n    \n    def __init__(self, id: int, name: str) -> None:\n        self.id = id\n        self.name = name\n        self.employees = []\n\n    def add_employee(self, employee):\n        self.employees.append(employee)\n\n    def print_employees(self):\n        for employee in self.employees:\n            print(employee.name)\n\n\nclass Manager(Employee):\n\n    def coordinate_projects(self):\n        print(f\"{self.name} está coordinando todos los proyectos de la empresa.\")\n\n\nclass ProjectManager(Employee):\n\n    def __init__(self, id: int, name: str, project: str) -> None:\n        super().__init__(id,name)\n        self.project = project\n\n    def coordinate_project(self):\n        print(f\"{self.name} está coordinando  su proyecto.\")\n\n\nclass Programmer(Employee):\n    \n    def __init__(self, id: int, name: str, language: str) -> None:\n        super().__init__(id,name)\n        self.language = language\n\n    def code(self):\n        print(f\"{self.name} está programando en {self.language}.\")\n        \n    def add_employee(self, employee):   # Se crea la función para que este empleado no pueda añadir ninún empleado\n        print(f\"Un programador no tiene empleados a su cargo. {employee.name} no se añadirá.\")\n\n\nmy_manager = Manager(1, \"MarioDev\")\nmy_project_manager = ProjectManager(2, \"Mario\", \"Proyecto 1\")\nmy_project_manager2 = ProjectManager(3, \"Marcos\", \"Proyecto 2\")\nmy_programmer = Programmer(4, \"Mai\", \"Python\")\nmy_programmer2 = Programmer(5, \"Angy\", \"Java\")\nmy_programmer3 = Programmer(6, \"Moure\", \"Python\")\nmy_programmer4 = Programmer(7, \"Jose\", \"C#\")\n\nmy_manager.add_employee(my_project_manager)\nmy_manager.add_employee(my_project_manager2)\n\nmy_project_manager. add_employee(my_programmer)\nmy_project_manager. add_employee(my_programmer2)\nmy_project_manager2. add_employee(my_programmer3)\nmy_project_manager2. add_employee(my_programmer4)\n\nmy_programmer.add_employee(my_programmer2)\n\nmy_programmer.code()\nmy_project_manager.coordinate_project()\nmy_manager.coordinate_projects()\nmy_manager.print_employees()\nmy_project_manager.print_employees()\nmy_programmer.print_employees()\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/neslarra.py",
    "content": "\"\"\"\n EJERCICIO:\n Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n implemente una superclase Animal y un par de subclases Perro y Gato,\n junto con una función que sirva para imprimir el sonido que emite cada Animal.\n\n DIFICULTAD EXTRA (opcional):\n Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n Cada empleado tiene un identificador y un nombre.\n Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n actividad, y almacenan los empleados a su cargo.\n\"\"\"\n\n\nclass Animal:\n    mascotas = 0\n\n    def __init__(self, patas: int, sonido: str, tipo_piel: str, movilidad: str):\n        self.patas = patas\n        self.sonido = sonido\n        self.tipo_piel = tipo_piel\n        self.movilidad = movilidad\n        self.validar()\n        Animal.alta_mascota()\n\n    def validar(self):\n        if not (0 <= self.patas <= 4) or (self.patas % 2 > 0):\n            raise AttributeError(\"Error: Cantidad de patas NO corresponde.\")\n        if self.tipo_piel.lower() not in (\"pelaje\", \"plumas\", \"escamas\"):\n            raise AttributeError(\"Error: Tipo de piel desconocida.\")\n        if self.movilidad.lower() not in (\"camina\", \"repta\", \"vuela\", \"nada\"):\n            raise AttributeError(\"Error: Tipo de movilidad no corresponde.\")\n\n    def comunicacion(self):\n        return f\"Este tipo de animal emite un {self.sonido}.\"\n\n    def __str__(self):\n        if self.patas == 4:\n            detalle = f\"en {self.patas} patas.\"\n        elif self.patas == 2:\n            detalle = f\"con {self.patas} alas.\"\n        elif self.movilidad == \"nada\":\n            detalle = f\"con una aleta caudal, dos pectorales y una (o más) dorsal.\"\n        elif self.movilidad == \"repta\":\n            detalle = f\"con una musculatura adaptada en su parte ventral.\"\n        else:\n            detalle = \"movildad a evaluar.\"\n        return f\"{self.movilidad.capitalize()} {detalle} {self.comunicacion()}\"\n\n    @classmethod\n    def alta_mascota(cls):\n        cls.mascotas += 1\n\n\nclass Perro(Animal):\n    mascotas = 0\n\n    def __init__(self, nombre: str, raza: str, color: str):\n        self.nombre = nombre\n        self.color = color\n        self.raza = raza\n        Perro.alta_mascota()\n        super().__init__(4, \"ladrido\", \"pelaje\", \"camina\")\n\n    def __str__(self):\n        return f\"{self.nombre.capitalize()} es un perro de raza {self.raza.lower()} con {self.tipo_piel.lower() } de color {self.color.lower()}. {super().__str__()}\"\n\n    @classmethod\n    def add_mascota(cls):\n        cls.mascotas += 1\n\n\nclass Gato(Animal):\n    mascotas = 0\n\n    def __init__(self, nombre: str, raza: str, color: str):\n        self.nombre = nombre\n        self.color = color\n        self.raza = raza\n        super().__init__(4, \"maullido\", \"pelaje\", \"camina\")\n        Gato.alta_mascota()\n\n    def __str__(self):\n        return f\"{self.nombre.capitalize()} es un gato de raza {self.raza.lower()} con {self.tipo_piel.lower() } de color {self.color.lower()}. {super().__str__()}\"\n\n    @classmethod\n    def add_mascota(cls):\n        cls.mascotas += 1\n\n\nclass Pajaro(Animal):\n    mascotas = 0\n\n    def __init__(self, especie: str, color: str):\n        self.color = color\n        self.especie = especie\n        super().__init__(2, \"vocalización\", \"plumas\", \"vuela\")\n        Pajaro.alta_mascota()\n\n    @classmethod\n    def add_mascota(cls):\n        cls.mascotas += 1\n\n\nclass Pez(Animal):\n    mascotas = 0\n\n    def __init__(self, color: str, medio: str):\n        self.color = color\n        self.medio = medio\n        super().__init__(0, \"ninguno\", \"escamas\", \"nada\")\n        Pez.alta_mascota()\n\n    def comunicacion(self):\n        return f\"Este tipo de animal NO emite ningún sonido.\"\n\n    @classmethod\n    def add_mascota(cls):\n        cls.mascotas += 1\n\n\nclass Serpiente(Animal):\n    mascotas = 0\n\n    def __init__(self, color: str, veneno: str):\n        self.color = color\n        self.veneno = veneno\n        super().__init__(0, \"ninguno\", \"escamas\", \"repta\")\n        Serpiente.alta_mascota()\n\n    def comunicacion(self):\n        return f\"Este tipo de animal NO emite ningún sonido.\"\n\n    def peligrosidad(self):\n        return f\"Su veneno es potencialmente peligroso\" if self.veneno.lower() == \"si\" else \"NO representa peligro para las personas.\"\n\n    @classmethod\n    def add_mascota(cls):\n        cls.mascotas += 1\n\n\nprint(\"\"\"Cuando distintos objetos tienen algunos atributos en común y otros que los diferencian, se puede abstraer los atributos comunes en una\nclase que luego los pasará a otras clases-hijas que los heredaran y aportarán sus propios atributos y métodos. También podrán modificar los métodos\nheredados para adecuarlos a sus propias necesidades.\nCreamos una Clase (madre) \"Animal\" de la cual heredarán las clases más particulares \"Perro\", \"Gato\", \"Pájaro\", \"Pez\" y \"Serpiente\" las cuales, a su\nvez, agregarán sus propios atributos y métodos e incluso modificarán alguno de los heredados (ya sean de instancia o de clase). \n\"\"\")\n\nluna = Perro(\"Luna\", \"Mestiza\", \"Blanco con parches negros\")\nthompson = Gato(\"Thompson\", \"Mestiza\", \"Negro con vetas blancas\")\npiopio = Pajaro(\"Canario\", \"Amarillo\")\nnemo = Pez(\"Naranja\", \"Agua salada\")\nviper = Serpiente(\"Dorado con diamantes marrones\", \"SI\")\napolo = Perro(\"Apolo\", \"Daschund\", \"Negro\")\naslan = Gato(\"Aslan\", \"Siamés\", \"beige\")\nrocky = Perro(\"Rocky\", \"Caniche Toy\", \"blanco\")\n\nprint(\"La clase Animal es heredada por:\", end=\" \")\nfor clase in Animal.__subclasses__():\n    print(f\"{clase.__name__} con {clase.mascotas} instancias,\", end=\" \")\nprint(f\"\\nEn total heredan {Animal.mascotas} mascotas\", end=\"\\n\\n\")\n\nfor var in [luna, thompson, piopio, nemo, viper, apolo, aslan, rocky]:\n    # print(f\"Clase {var.__class__.__name__} hereda de {var.__class__.__base__.__name__}\", end=\"\\n\\t\")\n    if var.__class__.__name__ == \"Pez\":\n        print(f\"Clase {var.__class__.__name__}. {var} Hereda de {var.__class__.__base__.__name__}. Se lo encuentra en {var.medio}\")\n    else:\n        print(f\"Clase {var.__class__.__name__}. {var} Hereda de {var.__class__.__base__.__name__}.\")\n\n# Dificultad Extra\nprint(f\"\\n{'#' * 50}\\nDificultad Extra\\n{'#' * 50}\", end=\"\\n\\n\")\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n Cada empleado tiene un identificador y un nombre.\n Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n actividad, y almacenan los empleados a su cargo.\n\"\"\"\n\n\nclass Employee:\n    emp = {}\n    employes_ids = list(range(1000, 9999))\n\n    def __init__(self, fullname: str, department: str, job: str, salary: int, project: str = \"\", main_skill: str = \"\"):\n        self.fullname = fullname\n        self.department = department\n        self.job = job\n        self.salary = salary\n        self.employee_id = Employee.get_employee_id()\n        Employee.add_employees(self.employee_id, self.fullname, self.department, self.job, self.salary, project, main_skill)\n\n    def __str__(self):\n        return f\"Employee#: {self.employee_id} / Full Name: {self.fullname} / Department: {self.department} / Job: {self.job} / Salary: {self.salary}\"\n\n    @classmethod\n    def get_employee_id(cls):\n        return Employee.employes_ids.pop(0)\n\n    @classmethod\n    def add_employees(cls, employee_id, fullname, department, job, salary, project, main_skill):\n        cls.emp[employee_id] = {\"Fullname\": fullname, \"Department\": department, \"Job\": job, \"Salary\": salary, \"Project\": project, \"MainSkill\": main_skill}\n\n\nclass Manager(Employee):\n    def __init__(self, fullname: str, department: str):\n        super().__init__(fullname, department, \"Manager\", 10000)\n\n    def get_subordinates(self):\n        subordinates = []\n        for key, value in Employee.emp.items():\n            if key != self.employee_id and Employee.emp[key][\"Department\"] == self.department:\n                subordinates.append(Employee.emp[key][\"Fullname\"] + \" / \" + Employee.emp[key][\"Job\"])\n        return subordinates\n\n\nclass ProjectManager(Employee):\n    def __init__(self, fullname: str, department: str, project: str):\n        self.project = project\n        super().__init__(fullname, department, \"Project Manager\", 7000, project)\n\n    def get_resources(self):\n        resources = []\n        for key, value in Employee.emp.items():\n            if key != self.employee_id and Employee.emp[key][\"Project\"] == self.project:\n                resources.append(Employee.emp[key][\"Fullname\"] + \" / \" + Employee.emp[key][\"Job\"] + \" / \" + Employee.emp[key][\"MainSkill\"])\n        return resources\n\n\nclass Programmer(Employee):\n    def __init__(self, fullname: str, department: str, project: str, main_skill: str):\n        self.project = project\n        self.main_skill = main_skill\n        super().__init__(fullname, department, \"Programmer\", 5000, project, main_skill)\n\n\nTito = Manager(\"Tito Tulio\", \"IT\")\nPaco = ProjectManager(\"Paco Pega\", \"IT\", \"Banco Garca\")\nPepe = Programmer(\"Pepe Botella\", \"IT\", \"Banco Garca\", \"C#\")\nPapo = Programmer(\"Papo Napo\", \"IT\", \"Banco Garca\", \"HTML5\")\n\nprint(f\"{Tito}\\n\\tDependants: {Tito.get_subordinates()}\", end=\"\\n\\n\")\n\nprint(f\"{Paco}\\n\\tProject: {Paco.project}. Resources: {Paco.get_resources()}\", end=\"\\n\\n\")\n\nprint(f\"{Pepe}\\n\\tMain Skill: {Pepe.main_skill} at project {Pepe.project}\", end=\"\\n\\n\")\n\nprint(f\"{Papo}\\n\\tMain Skill: {Papo.main_skill} at project {Papo.project}\", end=\"\\n\\n\")\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/nlarrea.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n\"\"\"\n\n\nclass Animal:\n    def __init__(self, pet_name: str, animal_type: str) -> None:\n        self.name = pet_name\n        self.type = animal_type\n\n    def __str__(self):\n        return f\"This is {self.name}. It is a {self.type}.\"\n\n    def print_sound(self):\n        pass\n\n\nclass Dog(Animal):\n    def print_sound(self):\n        print(\"Guau!\")\n\n\nclass Cat(Animal):\n    def print_sound(self):\n        print(\"Miau!\")\n\n\nmy_dog = Dog(\"Lagun\", \"dog\")\nprint(my_dog)  # This is Lagun. It is a dog.\nmy_dog.print_sound()  # Guau!\n\nmy_cat = Cat(\"Kira\", \"cat\")\nprint(my_cat)  # This is Kira. It is a cat.\nmy_cat.print_sound()  # Miau\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n\"\"\"\n\n\nclass Employee:\n    def __init__(self, id: int, name: str) -> None:\n        self.id = id\n        self.name = name\n        self.employees = []\n\n    def add(self, employee):\n        self.employees.append(employee)\n\n    def print_employees(self):\n        print(f\"\\n{self.name}'s employees:\")\n        for employee in self.employees:\n            print(f\" - {employee.name}\")\n\n\nclass Manager(Employee):\n    def coordinate(self):\n        print(f\"\\n{self.name} is coordinating all of the company's projects\")\n\n\nclass ProjectManager(Employee):\n    def __init__(self, id: int, name: str, project: str) -> None:\n        super().__init__(id, name)\n        self.project = project\n\n    def coordinate(self):\n        print(f\"\\n{self.name} is coordinating: {self.project}\")\n\n\nclass Programmer(Employee):\n    def __init__(self, id: int, name: str, language: str) -> None:\n        super().__init__(id, name)\n        self.language = language\n\n    def code(self):\n        print(f\"\\n{self.name} is programming using {self.language} language\")\n\n    def add(self, employee: Employee):\n        print(\n            f\"\\nA programmer has no employees.\\n{employee.name} won't be added.\"\n        )\n\n\n# Initializing employees\nmy_manager = Manager(1, \"ManagerName\")\nmy_pm1 = ProjectManager(2, \"PM1\", \"Project 1\")\nmy_pm2 = ProjectManager(3, \"PM2\", \"Project 2\")\nmy_programmer1 = Programmer(4, \"P1\", \"Python\")\nmy_programmer2 = Programmer(5, \"P2\", \"React\")\nmy_programmer3 = Programmer(6, \"P3\", \"JavaScript\")\nmy_programmer4 = Programmer(7, \"P4\", \"SQL\")\n\n\n# Adding employees\nmy_manager.add(my_pm1)\nmy_manager.add(my_pm2)\n\nmy_pm1.add(my_programmer1)\nmy_pm1.add(my_programmer2)\n\nmy_pm2.add(my_programmer3)\nmy_pm2.add(my_programmer4)\n\nmy_programmer1.add(my_programmer4)  # won't work\n\"\"\" prints:\nA programmer has no employees.\nP4 won't be added.\n\"\"\"\n\n\n# Tasks\nmy_manager.coordinate()\n# ManagerName is coordinating all of the company's projects\nmy_pm1.coordinate()\n# PM1 is coordinating: Project 1\nmy_programmer1.code()\n# P1 is programming using Python language\nmy_programmer2.code()\n# P2 is programming using React language\nmy_pm1.print_employees()\n\"\"\"\nPM1's employees:\n - P1\n - P2\n\"\"\"\nmy_manager.print_employees()\n\"\"\"\nManagerName's employees:\n - PM1\n - PM2\n \"\"\"\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/oniricoh.py",
    "content": "#Definir clase padre\nclass Animal():   \n    def __init__(self, especie: str, edad: int):\n        self.especie= especie\n        self.edad = edad\n    \n    def __str__(self):\n        msg = f\"Clase de animal: {self.especie.capitalize()}\\nEdad: {self.edad}\"\n        return msg\n\n#Clases Hijas de Animal\nclass Perro(Animal):   \n    def hacer_sonido(self):\n        return \"Guau Guau Guau!!\"\n\n\nclass Gato(Animal):    \n    def hacer_sonido(self):\n        return \"miauuu\"\n\n\n    \nperro = Perro(\"perro\", 14)\nprint(perro)\nprint(perro.hacer_sonido())\n\ngato = Gato(\"siames\", 5)\nprint(gato)\nprint(gato.hacer_sonido())\nprint()\n\n###############################################################################\n## Dificulatad Extra\n###############################################################################\nclass BusinessEmployee:\n    def __init__(self, employee_id: int, name: str):\n        self.employee_id = employee_id\n        self.name = name\n        self._salary = 1000\n\n    def __str__(self):\n        return f\"Employee name: {self.name.capitalize()}\\nIdentifying: {self.employee_id}\\nSalary: {self._salary}\"\n\nclass Manager(BusinessEmployee):\n    def __init__(self, employee_id: int, name: str):\n        super().__init__(employee_id, name)\n        self._salary = 3000\n        self._subordinates = []\n\n    def add_subordinate(self, subordinate):\n        self._subordinates.append(subordinate)\n    \n    def __str__(self):\n        if self._subordinates:\n            subordinates_str = \", \".join(subordinate.name for subordinate in self._subordinates)\n            return super().__str__() + f\"\\nSubordinates: {subordinates_str}\"\n        \n\nclass ProjectManager(BusinessEmployee):\n    def __init__(self, employee_id: int, name: str):\n        super().__init__(employee_id, name)\n        self._salary = 6000\n        self._subordinates = [] \n        \n    def add_subordinate(self, subordinate):\n        self._subordinates.append(subordinate)\n    \n    def __str__(self):\n        if self._subordinates:\n            subordinates_str = \", \".join(subordinate.name for subordinate in self._subordinates)\n            return super().__str__() + f\"\\nSubordinates: {subordinates_str}\"\n\n\nclass Programmer(BusinessEmployee):\n    def __init__(self, employee_id: int, name: str):\n        super().__init__(employee_id, name)\n        self._salary = 1500\n\n\n# Pruebas\nprint()\nemployee_one = BusinessEmployee(1, \"Daniel\")\nprint(employee_one)\nprint()\n\nmanager_one = Manager(2, \"Alice\")\nmanager_one.add_subordinate(employee_one)\nprint(manager_one)\nprint()\n\nprogrammer_one = Programmer(4, \"Charlie\")\nprint(programmer_one)\nprogrammer_two = Programmer(5, \"Eduardo\")\nprint()\n\nproject_manager_one = ProjectManager(3, \"Bob\")\nproject_manager_one.add_subordinate(programmer_one)\nproject_manager_one.add_subordinate(programmer_two)\nprint(project_manager_one)\nprint()\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/oriaj3.py",
    "content": "\"\"\"\t\n09 - HERENCIA\nAutor de la solución: Oriaj3\t\nTeoría:\t\nLa herencia es un concepto fundamental en la programación orientada a objetos.\nPermite crear nuevas clases a partir de clases existentes, reutilizando su\ncódigo y extendiendo su funcionalidad.\n\nLa clase original se conoce como superclase, y la nueva clase se conoce como\nsubclase. La subclase hereda todos los atributos y métodos de la superclase, y\npuede agregar nuevos atributos y métodos, o modificar los existentes.\n\nTambién se pueden llamar hijos y padres a las subclases y superclases. \n\nEn Python, la herencia se especifica en la definición de la clase, pasando la\nsuperclase entre paréntesis después del nombre de la clase.\n\nEjemplo:\nclass Animal:\n    def __init__(self, nombre):\n        self.nombre = nombre\n\n    def hacer_sonido(self):\n        pass\n\nclass Perro(Animal):\n    def __init__(self, nombre, raza):\n        super().__init__(nombre)\n        self.raza = raza\n\n    def hacer_sonido(self):\n        print(\"Guau guau\")\n\"\"\"\n\n# EJEMPLO BÁSICO\n\"\"\"\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n\"\"\"\n\n# Clase base o superclase\nclass Animal:\n\n    def __init__(self, nombre) -> None:\n        self.nombre = nombre\n\n    def rugido(self) -> None:\n        print(\"Rugido de animal!!!\")\n\n# Subclase perro \nclass Perro(Animal):\n    def __init__(self, nombre, raza) -> None:\n        super().__init__(nombre)\n        self.raza = raza\n\n    def rugido(self) -> None:\n        print(\"Guau Guau!!\")\n\n# subclase gato\nclass Gato(Animal):\n    def __init__(self, nombre, color) -> None:\n        super().__init__(\n            nombre,\n        )\n        self.color = color\n\n    def rugido(self) -> None:\n        print(\"Miau Miau!!\")\n\n\n# Crea un vector de animales\nanimales = [Animal(\"Estandar\"), Perro(\"Firulais\", \"Mestiza\"), Gato(\"Mishi\", \"Negro\")]\n\n# Imprime el sonido de cada animal\nfor animal in animales:\n    print(animal.nombre, end=\": \")\n    animal.rugido()\n\nprint(f\"El perro es de raza {animales[1].raza} y el gato es {animales[2].color}\")\n\n# EJERCICIO EXTRA\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n\"\"\"\n\n#clase padre o superclase \nclass Empleado:\n    \n    def __init__(self, nombre, id) -> None:\n        self.nombre = nombre\n        self.id = id\n        self.salario = 1000\n\n\n    def cobrar(self):\n        print(f\"El empleado {self.nombre} va a cobrar {self.salario}\")\n\n    def __str__(self) -> str:\n        return f\"Nombre {self.__class__.__name__}: {self.nombre}, ID: {self.id}, SALARIO: {self.salario}\"\n\n# Clase superclase o padre\nclass Jefe:\n    def __init__(self, listaEmpleados) -> None:\n        self.listaEmpleados = listaEmpleados\n\n    def listarEmpleados(self) -> None:\n        print(f\"Dirigiendo a {self.__class__.__name__}\", end=\": \")\n        for empleado in self.listaEmpleados:\n            print(empleado.id, end=\", \")\n        print(\"\\n\")\n\n# Subclase de Empleado\nclass Programador(Empleado):\n    def __init__(self, nombre, id, lenguaje) -> None:\n        super().__init__(nombre, id)\n        self.lenguaje = lenguaje\n        self.salario = 1300\n\n    def programar(self) -> None:\n        print(f\"El programador {self.nombre} está programando en {self.lenguaje}\")\n\n# Subclase de Empleado y Jefe\nclass Gerente(Empleado, Jefe):\n\n    def __init__(self, nombre, id, listaEmpleados, bonus) -> None:\n        Empleado.__init__(self, nombre, id)\n        Jefe.__init__(self, listaEmpleados)\n        self.bonus = bonus\n        self.salario = 2000 + bonus\n\n# Subclase de Empleado y Jefe\nclass GerenteProyecto(Empleado, Jefe):\n    def __init__(self, nombre, id, listaEmpleados, proyecto) -> None:\n        Empleado.__init__(self, nombre, id)\n        Jefe.__init__(self, listaEmpleados)\n        self.proyecto = proyecto\n        self.salario = 1500\n    \n    def trabajar(self) -> None:\n        print(f\"El gerente de proyecto {self.nombre} está trabajando en el proyecto {self.proyecto}\")\n\n\n##Ejemplo de uso\nempleados = [\n    Empleado(\"Juan\", 1),\n    Programador(\"Pedro\", 2, \"Python\"),\n    Gerente(nombre=\"Carlos\", id=3, listaEmpleados=[Empleado(\"Ana\", 4), Programador(\"Maria\", 5, \"Java\")], bonus=500),\n    GerenteProyecto(\n        \"Luis\", 6, [Empleado(\"Sofia\", 7), Programador(\"Jose\", 8, \"C++\")], \"Proyecto 1\"\n    ),\n]\nprint(\"\\n\\n##### Lista de empleados #####\\n\\n\")\nfor empleado in empleados:\n    print(empleado.__str__())\n    empleado.cobrar()\n\nprint(\"\\n\\n##### Acciones de los empleados #####\\n\\n\")\nfor empleado in empleados:\n    if isinstance(empleado, Gerente):\n        empleado.listarEmpleados()\n    if isinstance(empleado, Programador):\n        empleado.programar()\n    if isinstance(empleado, GerenteProyecto):\n        empleado.trabajar()\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/pakiuh.py",
    "content": "'''EJERCICIO:\r\nExplora el concepto de herencia según tu lenguaje. Crea un ejemplo que\r\nimplemente una superclase Animal y un par de subclases Perro y Gato,\r\njunto con una función que sirva para imprimir el sonido que emite cada Animal.'''\r\n\r\nclass Animal:\r\n    def __init__(self,nombre):\r\n        self.nombre = nombre\r\n    \r\n    def sonido_emiten(self):\r\n        pass\r\n\r\nclass Perro(Animal):\r\n    def __init__(self, nombre):\r\n        super().__init__(nombre)\r\n    def sonido_emiten(self):\r\n        return \"Guau, Guau\"\r\n\r\nclass Gato(Animal):\r\n    def __init__(self, nombre):\r\n        super().__init__(nombre)\r\n    def sonido_emiten(self):\r\n        return \"Miau, Miau\"\r\n\r\npirata = Gato(\"Pirata\")\r\nprint(f\"{pirata.nombre} hace {pirata.sonido_emiten()}\")\r\n\r\ntoby = Perro(\"Toby\")\r\nprint(f\"{toby.nombre} hace {toby.sonido_emiten()}\")\r\n\r\n'''DIFICULTAD EXTRA (opcional):\r\nImplementa la jerarquía de una empresa de desarrollo formada por Empleados que\r\npueden ser Gerentes, Gerentes de Proyectos o Programadores.\r\nCada empleado tiene un identificador y un nombre.\r\nDependiendo de su labor, tienen propiedades y funciones exclusivas de su\r\nactividad, y almacenan los empleados a su cargo.'''\r\n\r\nclass Empleado:\r\n    def __init__(self,id, nombre):\r\n        self.id = id\r\n        self.nombre = nombre\r\n\r\nclass Gerente(Empleado):\r\n    def __init__(self, id, nombre, departamento, numero_subordinados):\r\n        super().__init__(id, nombre)\r\n        self.departamento = departamento\r\n        self.numero_subordinados = numero_subordinados\r\n    \r\n    def contratar(self, contratado):\r\n        return f\"Has contratado un nuevo empleado que se llama {contratado}\"\r\n    \r\n    def despedir(self, despedido):\r\n        return f\"Has despedido a {despedido}\"\r\n\r\nclass Gerente_proyecto(Empleado):\r\n    def __init__(self, id, nombre, proyecto, numero_subordinados):\r\n        super().__init__(id, nombre)\r\n        self.proyecto = proyecto\r\n        self.numero_subordinados = numero_subordinados\r\n    \r\n    def set_plazos(self, fecha):\r\n        return f\"la fecha de finalización del {self.proyecto} es {fecha}\"\r\n    \r\n    def get_numero_empleados(self):\r\n        return self.numero_subordinados\r\n    \r\n\r\nclass Programador(Empleado):\r\n    def __init__(self, id, nombre, gerente_proyecto):\r\n        super().__init__(id, nombre, gerente_proyecto)\r\n    \r\n    def set_proyecto(self,proyecto):\r\n        self.proyecto = proyecto\r\n    \r\n    def get_proyecto(self):\r\n        return self.proyecto\r\n    \r\n\r\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/pguillo02.py",
    "content": "class Animal:\n    \n    def __init__ (self, name, tamaño, peso):\n        self.name = name\n        self.tamaño = tamaño \n        self.peso = peso\n\n    def sound(self):\n        pass\n\nclass Gato(Animal):\n\n    def __init__ (self, name, tamaño, peso, sonido):\n        super().__init__(name, tamaño, peso)\n        self.sonido = sonido\n\n    def sound(self):\n        print(f'El {self.name} suena {self.sonido}')\n\n\ng = Gato(\"Gato\", 22, 22, \"Miau\")\ng.sound()\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/pwrxman.py",
    "content": "\"\"\"\nvideo en  https://youtu.be/PVBs5PWjedA?si=gkpzPPTm0WUjsXAJ\n* EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n\"\"\"\n\nclass Animal:\n    def __init__ (self, grupo: str, categoria: str, alimentacion: str, name: str):\n          self.grupo = grupo        # Vertebrados, Invertebrados\n          self.categoria = categoria    # vertebrados: Aves, Peces, Reptiles, Mamiferos     #invertebrados: Insectos,\n          self.alimentacion = alimentacion      # Omnivoros, Herbivoros, Carnivoeros, Insectivoros\n          self.name = name\n          \n    def sound(self):\n        pass\n\nclass Dog(Animal):\n  \n    def sound(self):\n          print(\"Guau!\")\n\nclass Cat(Animal):\n    def sound(self):\n          print(\"Miau!\")\n\ndef print_sound(animal: Animal):\n  animal.sound()          \n\nanimal = Animal(\"V\", \"M\", \"C\", \"Animal\")\nanimal.sound()\n\ndog = Dog(\"M\", \"M\", \"C\", \"Perro\")\ndog.sound()\n\ncat = Cat(\"M\", \"M\", \"C\", \"Cat\")\ncat.sound()\nprint(\"> > > > > > > > > > >\")\nprint_sound(animal)\nprint_sound(dog)\nprint_sound(cat)\n\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n\"\"\"\nprint(\"DIFICULTAD EXTRA\\n\")\n\nclass Employee:\n    def __init__(self, id: str, name: str):\n        self.id = id\n        self.name = name\n        self.employees = []\n\n    def add(self, employee):\n        self.employees.append(employee)\n\n    def get_employees(self):\n        print(f\"los colabores de {self.name} son:\")\n        for employee in self.employees:\n            print(employee.name)\n\nclass Manager(Employee):\n    def coordina_proyectos(self):\n        print(f\"{self.name} esta coordinando los proyectos\")\n\nclass ProjectManager(Employee):\n\n    def __init__(self, id: str, name: str, project: str):\n        super().__init__(id, name)    # reutiliza el inicialiador de la superclase\n        self.project = project\n\n    def coordina_proyecto(self):\n        print(f\"{self.name} esta coordinando un proyecto\")\n\nclass Programmer(Employee):\n    def __init__(self, id: str, name: str, language: str):\n        super().__init__(id, name)    # reutiliza el inicialiador de la superclase\n        self.language = language\n    \n    def code(self):\n        print(f\"{self.name} esta programando en {self.language}\")\n    \n    def add(self, employee):\n        print(f\"{employee.name} No puede ser añadido porque {self.name} es programador y no puede tener empleados a su cargo\")\n\nmgr = Manager(\"mgr1\", \"Tony\")\nmgr2 = Manager(\"mgr2\", \"Katy\")\n\n\npm = ProjectManager(\"pm1\", \"Chucho\", \"Project 1\")\npm2 = ProjectManager(\"pm2\", \"Vic\", \"Project 2\")\n\nprgmr = Programmer(\"pr1\", \"Gonza\", \"Java\")\nprgmr2 = Programmer(\"pr2\", \"Luis\", \"Python\")\nprgmr3 = Programmer(\"pr3\", \"Vero\", \"C#\")\nprgmr4 = Programmer(\"pr4\", \"Pilar\", \"React\")\nprgmr5 = Programmer(\"pr5\", \"Mary\", \"Python\")\n\nmgr.add(pm)\nmgr2.add(pm2)\n\npm.add(prgmr)\npm.add(prgmr2)\npm2.add(prgmr3)\npm2.add(prgmr4)\npm2.add(prgmr5)\n\nprgmr.add(prgmr3)\n\nprgmr2.code()\n\npm.coordina_proyecto()\n\nmgr.coordina_proyectos()\n\nmgr.get_employees()\nmgr2.get_employees()\n\npm.get_employees()\npm2.get_employees()\n\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/pyramsd.py",
    "content": "class Animal:\n    def __init__(self, nombre) -> None:\n        self.nombre = nombre\n\n    def sonido(self):\n        pass \n\nclass Perro(Animal):\n    def sonido(self):\n        return f'el perro hace ¡Guau, Guau!'\n    \nclass Gato(Animal):\n    def sonido(self):\n        return 'el gato hace ¡Miau!'\n    \nanimal1 = Perro('Alfa')\nprint(f'{animal1.nombre}, {animal1.sonido()}')\n\nanimal2 = Gato('Gary')\nprint(f'{animal2.nombre}, {animal2.sonido()}')\n\nprint()\n\n'''\nEXTRA\n'''\n\nclass Empleados:\n    def __init__(self, id, nombre) -> None:\n        self.nombre = nombre\n        self.id = id\n\n    def deber(self):\n        print('Trabajar')\n\nclass Gerente(Empleados):\n    def __init__(self, id, nombre, empleados) -> None:\n        super().__init__(id, nombre)\n        self.empleados = empleados\n\n    def deber(self):\n        print('Gerente')\n\n    def get_info(self):\n        print(f'el gerente {self.nombre} con el id {self.id} tiene {self.empleados} empledos')\n\nclass Gerente_Proyecto(Empleados):\n    def __init__(self, id, nombre, empleados) -> None:\n        super().__init__(id, nombre)\n        self.empleados = empleados\n\n    def deber(self):\n        print('Gerente de proyectos')\n\n    def get_info(self):\n        print(f'el gerente de proyectos {self.nombre} con el id {self.id} tiene {self.empleados} empledos')\n\nclass Programador(Empleados):\n    def __init__(self, id, nombre, empleados=0) -> None:\n        super().__init__(id, nombre)\n        self.empleados = empleados\n\n    def deber(self):\n        print('Programar')\n\n    def get_info(self):\n        print(f'el programador {self.nombre} con el id {self.id} tiene {self.empleados} empleados')\n\n\nempleado1 = Gerente(1, 'Javier', 5)\nprint(empleado1.id)\nempleado1.deber()\nprint(empleado1.empleados)\nprint(empleado1.nombre)\nempleado1.get_info()\n\nprint()\n\nempleado2 = Gerente_Proyecto(2, 'Milei', 6)\nprint(empleado2.id)\nempleado2.deber()\nprint(empleado2.empleados)\nprint(empleado2.nombre)\nempleado2.get_info()\n\nprint()\n\nempleado3 = Programador(3, 'Sergio')\nprint(empleado3.id)\nempleado3.deber()\nprint(empleado3.empleados)\nprint(empleado3.nombre)\nempleado3.get_info()\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/qwik-zgheib.py",
    "content": "# -- exercise\nclass Animal:\n    def __init__(self, name: str) -> None:\n        self.name = name\n\n    def make_sound(self) -> None:\n        print(\"The animal makes a sound\")\n\n\nclass Dog(Animal):\n    def __init__(self, name: str) -> None:\n        super().__init__(name)\n\n    def make_sound(self) -> None:\n        print(f\"{self.name} does wow wow!\")\n\n\nclass Cat(Animal):\n    def __init__(self, name: str) -> None:\n        super().__init__(name)\n\n    def make_sound(self) -> None:\n        print(f\"{self.name} does meow meow!\")\n\n\ndog: Dog = Dog(\"Firulais\")\ndog.make_sound()\n\ncat: Cat = Cat(\"Silveter\")\ncat.make_sound()\nprint(\"\\n----- extra challenge -----\")\n\n\n# -- extra challenge\nclass Employee:\n    def __init__(self, employee_id: int, name: str):\n        self.employee_id = employee_id\n        self.name = name\n\n    def get_details(self):\n        return f\"ID: {self.employee_id}, Name: {self.name}\"\n\n\nclass Manager(Employee):\n    def __init__(self, employee_id: int, name: str):\n        super().__init__(employee_id, name)\n        self.subordinates = []\n\n    def add_subordinate(self, employee: Employee):\n        self.subordinates.append(employee)\n\n    def remove_subordinate(self, employee: Employee):\n        self.subordinates.remove(employee)\n\n    def list_subordinates(self):\n        return [employee.get_details() for employee in self.subordinates]\n\n\nclass ProjectManager(Manager):\n    def __init__(self, employee_id: int, name: str, project_name: str):\n        super().__init__(employee_id, name)\n        self.project_name = project_name\n\n    def get_project_details(self):\n        return f\"Project: {self.project_name}, Managed by: {self.name}\"\n\n\nclass Developer(Employee):\n    def __init__(self, employee_id: int, name: str, programming_languages: list):\n        super().__init__(employee_id, name)\n        self.programming_languages = programming_languages\n\n    def add_programming_language(self, language: str):\n        if language not in self.programming_languages:\n            self.programming_languages.append(language)\n\n    def list_programming_languages(self):\n        return self.programming_languages\n\n\nclass Company:\n    def __init__(self):\n        self.employees = []\n\n    def add_employee(self, employee: Employee):\n        self.employees.append(employee)\n\n    def remove_employee(self, employee: Employee):\n        self.employees.remove(employee)\n\n    def find_employee_by_id(self, employee_id: int) -> Employee:\n        for employee in self.employees:\n            if employee.employee_id == employee_id:\n                return employee\n        return None\n\n    def list_all_employees(self):\n        return [employee.get_details() for employee in self.employees]\n\n\ndef main():\n    company = Company()\n\n    # Create employees\n    dev1 = Developer(\n        employee_id=1, name=\"Qwik\", programming_languages=[\"Python\", \"Java\"]\n    )\n    dev2 = Developer(\n        employee_id=2, name=\"Rahman\", programming_languages=[\"JavaScript\", \"TypeScript\"]\n    )\n    pm1 = ProjectManager(employee_id=3, name=\"Mohammed\", project_name=\"Project Alpha\")\n    manager1 = Manager(employee_id=4, name=\"Ahmed\")\n\n    # Add employees to company\n    company.add_employee(dev1)\n    company.add_employee(dev2)\n    company.add_employee(pm1)\n    company.add_employee(manager1)\n\n    # Manager assigns subordinates\n    manager1.add_subordinate(dev1)\n    manager1.add_subordinate(dev2)\n    pm1.add_subordinate(manager1)\n\n    # List all employees\n    print(\"All employees in the company:\")\n    for details in company.list_all_employees():\n        print(details)\n\n    # List subordinates for each manager\n    print(\"\\nManager's subordinates:\")\n    for details in manager1.list_subordinates():\n        print(details)\n\n    print(\"\\nProject Manager's subordinates:\")\n    for details in pm1.list_subordinates():\n        print(details)\n\n    # Developer adds a new programming language\n    dev1.add_programming_language(\"Rust\")\n    print(\"\\nDeveloper's programming languages:\")\n    print(dev1.list_programming_languages())\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/rantamhack.py",
    "content": "print(\"\\n\\n=====================================DEFINICION DE HERENCIA=====================================\\n\\n\")\n\n\nprint(\"La herencia en Python es un mecanismo que permite crear nuevas clases a partir de clases existentes.\\nEsto significa que las nuevas clases heredan los atributos y mÃ©todos de las clases de las que se derivan.\")\n\nprint(\"\\n\\n=====================================EJERCICIO=====================================\\n\\n\")\n\n'''\nExplora el concepto de herencia según tu lenguaje. Crea un ejemplo que\nimplemente una superclase Animal y un par de subclases Perro y Gato,\njunto con una función que sirva para imprimir el sonido que emite cada Animal.\n'''\n\nclass Animal:\n  def __init__(self, name):\n    self.name = name\n    \n  def eat(self):\n    print(f\"{self.name} está comiendo\") \n  \n  def drink(self):\n    print(f\"{self.name} está bebiendo\")\n  \n  def sleep(self):\n    print(f\"{self.name} está durmiendo\\n\\n\")\n  \npet = Animal(\"Mi mascota\")\npet.eat()\npet.drink()\npet.sleep()\n\n\nclass Perro(Animal):\n  def __init__(self, name, age, sound, colour):\n    super().__init__(name)\n    self.age = age\n    self.sound = sound\n    self.colour = colour\n    \n  def introduce_my_pet(self):\n    print(f\"Mi perro {self.name} tiene {self.age} años y es de color {self.colour}\")\n    \n  def bark(self):\n    print(f\"mi perro {self.sound} a los desconocidos\")\n   \nmy_dog = Perro(\"kal\", 3, \"ladra\", \"blanco\")\nmy_dog.introduce_my_pet()\nmy_dog.bark()\nmy_dog.eat() \nmy_dog.drink() \nmy_dog.sleep() \n\n    \nclass Gato(Animal):\n  def __init__(self, name, age, sound, colour, climb):\n    super().__init__(name)\n    self.age = age\n    self.sound = sound\n    self.colour = colour\n    self.climb = climb\n    \n  def present_my_pet(self):\n    print(f\"Mi gato se llama {self.name} tiene {self.age} años, es de color {self.colour} y {self.climb} a los árboles\")\n    \n  def meow(self):\n    print(f\"Mi gato {self.sound} cuando quiere comer\")\n    \nmy_cat = Gato(\"Madi\", 2, \"maulla\", \"gris\", \"trepa\")\nmy_cat.present_my_pet()\nmy_cat.meow()\nmy_cat.eat()\nmy_cat.drink()\nmy_cat.sleep()\n\n\nprint(\"\\n\\n=====================================DIFICULTAD EXTRA=====================================\\n\\n\")\n\n'''\nImplementa la jerarquí­a de una empresa de desarrollo formada por Empleados que\npueden ser Gerentes, Gerentes de Proyectos o Programadores.\nCada empleado tiene un identificador y un nombre.\nDependiendo de su labor, tienen propiedades y funciones exclusivas de su\nactividad, y almacenan los empleados a su cargo.\n'''\n\nclass Empleado:\n  def __init__(self, nombre, identificador):\n    self.nombre = nombre\n    self.identificador = identificador\n    \n  def hacer_trabajos(self):\n    pass\n\n    \nclass Gerente(Empleado):\n  def __init__(self, nombre, identificador, funcion, equipos):\n    super().__init__(nombre, identificador)\n    self.funcion = funcion\n    self.equipos = equipos\n  \n  equipos_compañia = [\"Proyectos\", \"Administracion\", \"RRHH\", \"Ventas\", \"Fiscal\"]\n    \n  def hacer_trabajos(self):\n    print(f\"El {self.identificador} es {self.nombre} y su trabajo es {self.funcion} a los diferentes {self.equipos}\")\n    print(f\"El {self.identificador} tambien se ocupa de gestionar la administración de la empresa en todos sus departamentos\")\n    \n  print(f\"Los equipos que dependen del Gerente de la compañí­a son: {equipos_compañia}\\n\")\n\n\n\nclass Gerente_proyecto(Gerente):\n  def __init__(self, nombre, identificador, funcion, equipos, proyecto):\n    super().__init__(nombre, identificador, funcion, equipos)\n    self.proyecto = proyecto\n    \n  equipo_proyecto1 = [\"programador 1A\", \"programador 2A\", \"programador 3A\", \"programador 4A\" ]\n  equipo_proyecto2 = [\"programador 1B\", \"programador 2B\", \"programador 3B\", \"programador 4B\" ]\n  equipo_proyecto3 = [\"programador 1C\", \"programador 2C\", \"programador 3C\", \"programador 4C\" ]\n  \n  def trabajo_gerente_proyecto(self):\n    if self.equipos == \"Equipo 1\":\n      print(f\"El equipo que depende de {self.identificador} es {self.equipo_proyecto1}\")\n    elif self.equipos == \"Equipo 2\":\n      print(f\"El equipo que depende de {self.identificador} es {self.equipo_proyecto2}\")\n    elif self.equipos == \"Equipo 3\":\n      print(f\"El equipo que depende de {self.identificador} es {self.equipo_proyecto3}\")\n        \n    \n    print(f\"{self.nombre} es {self.identificador} y su funcion es {self.funcion} al {self.equipos} para realizar el proyecto {self.proyecto}\\n\")\n    \n   \nclass Programador(Gerente_proyecto):\n  def __init__(self, nombre, identificador, funcion, equipos, proyecto, horario):\n     super().__init__(nombre, identificador, funcion, equipos, proyecto)\n     self.horario = horario\n     \n  def turno(self):\n    print(f\"{self.nombre} es {self.identificador} pertenece al {self.equipos}, está trabajando en el {self.proyecto}, su función es {self.funcion} y trabaja en el {self.horario} de tarde\\n\")  \n    \n   \ngerente = Gerente(\"Rantamplan\", \"gerente\", \"organizar\", \"equipos de proyecto\")\n    \ndirector_proyecto1 = Gerente_proyecto(\"Carlos\", \"Gerente de proyecto 1\", \"seleccionar y organizar\", \"Equipo 1\", \"Proyecto A\")\ndirector_proyecto2 = Gerente_proyecto(\"Miguel\", \"Gerente de proyecto 2\", \"seleccionar y organizar\", \"Equipo 2\", \"Proyecto B\") \ndirector_proyecto3 = Gerente_proyecto(\"Helena\", \"Gerente de proyecto 3\", \"seleccionar y organizar\", \"Equipo 3\", \"Proyecto C\")\n\nprogramador1A = Programador(\"Jose Luis\", \"programador\", \"limpiar código\", \"Equipo 1\", \"proyecto A\",  \"turno\") \nprogramador2A = Programador(\"Marina\", \"programadora\", \"limpiar código\", \"Equipo 2\", \"proyecto B\",  \"turno\") \nprogramador3A = Programador(\"Alex\", \"programadora\", \"limpiar código\", \"Equipo 3\", \"proyecto C\",  \"turno\") \n   \n\ngerente.hacer_trabajos()    \ndirector_proyecto1.trabajo_gerente_proyecto()   \ndirector_proyecto2.trabajo_gerente_proyecto()\ndirector_proyecto3.trabajo_gerente_proyecto()\nprogramador1A.turno()   \nprogramador2A.turno()\nprogramador3A.turno() \n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/raulG91.py",
    "content": "class Animal:\n    def __init__(self,name):\n        self.name = name\n    def sound(self):\n        print(\"General Animal\")\n    def get_name(self):\n        return self.name    \nclass Perro(Animal):\n    def sound(self):\n        print(\"Guau\")\nclass Gato(Animal):\n    def sound(self):\n        print(\"Miau\") \n\nmy_gato = Gato(\"Misifu\")\nmy_gato.sound()   \nprint(my_gato.get_name())                \nmy_perro = Perro(\"Luna\")\nmy_perro.sound()\nprint(my_perro.get_name())\n\n#Extra exercise\n\nclass Empleado:\n    def __init__(self,id,full_name):\n        self.id = id\n        self.full_name = full_name\n    def get_id(self):\n        return self.id\n    def get_name(self):\n        return self.full_name\n\nclass Gerente(Empleado):\n    subordinates = []\n    def addSubordinate(self,empleado:Empleado):\n        self.subordinates.append(empleado)\n    def get_subordinates(self):\n        for item in self.subordinates:\n            print(item.get_name())\n\nclass GerenteProyecto(Empleado): \n    projects = []\n    def addProject(self,project_name):\n        self.projects.append(project_name)\n    def deleteProject(self,project_name):\n        self.projects.remove(project_name)\n    def get_projects(self):\n        return self.projects        \n\nclass Programador(Empleado):\n\n    def drink_cofee(self):\n        print(\"Drinking cofee\")\n    def code(self):\n        print(\"Coding in python\")            \n\nboos = Gerente(1,\"Raul Garcia\")\nproject_manager = GerenteProyecto(2,\"Juan Perez\")\nboos.addSubordinate(project_manager)\nproject_manager.addProject(\"App1\")\nproject_manager.addProject(\"App2\")\nproject_manager.addProject(\"App 3\")\nproject_manager.deleteProject(\"App 3\")\nprogramador1 = Programador(3,\"Mike smith\")\nprogramador1.code()\nboos.addSubordinate(programador1)\nprogramador2 = Programador(4,\"Maria aguilera\")\nprogramador2.code()\nboos.addSubordinate(programador2)\nprint(boos.get_name()+\" 's subordinates \")\nboos.get_subordinates()\nprint(\"Projects for \"+project_manager.get_name())\nprint(project_manager.get_projects())"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/rayn1er.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n#  * implemente una superclase Animal y un par de subclases Perro y Gato,\n#  * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n#  * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n#  * Cada empleado tiene un identificador y un nombre.\n#  * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n#  * actividad, y almacenan los empleados a su cargo.\n#  */\n\nclass Animal:\n\n    def __init__(self,name,age):\n        self.name = name\n        self.age = age\n\n    \n    def greetings(self):\n        return f'Hi, Im {self.name} the {type(self).__name__}, Im {self.age} years old'\n    \n    def communicate():\n        pass\n\nclass Dog(Animal):\n    \n    def communicate(self):\n        return \"Woof!\"\n\n\nclass Cat(Animal):\n\n    def communicate(self):\n        return 'Meow!'\n\n\nyoel = Animal('yoel',3)\nmarko = Dog('marko',5)\nyuri = Cat(\"yuri\",5)\nprint(yoel.greetings())\nprint(marko.greetings())\nprint(yuri.greetings())\nprint(marko.communicate())\nprint(yuri.communicate())\n\n#extra\n\nclass Employee:\n\n    def __init__(self,name,idd):\n        self.name =  name\n        self.id = idd\n        self.employees = []\n    \n    def add_employee(self,employee):\n        self.employees.append(employee)\n\n    def supervising(self):\n        print(f'{self.name} esta supervisando a {self.employees}')\n\n    def print_employees(self):\n        for i in self.employees:\n            print(i.name)\nclass Manager(Employee):\n\n      \n    def coordinate_projects(self):\n        print(f'{self.name} Esta Coordinando los proyectos de la empresa')\n\nclass ProjectManager(Employee):\n\n    def __init__(self, name, id,project):\n        super().__init__(name, id)\n        self.proyect = project\n\n    def coordinate_projects(self):\n        print(f'{self.name} Esta Coordinando sus proyectos')\n\nclass Developer(Employee):\n\n    def __init__(self, name, id,language):\n        super().__init__(name, id)\n        self.language = language\n\n    def code(self):\n        print(f'{self.name} Esta escribiendo codigo en {self.language}')\n\n    def add_employee(self,employee):\n        print(f\"Programador no puede agregar porque no puede tener a empleados a su cargo\")\n\nmanager = Manager('raul',1000)\nproject_manager = ProjectManager(\"carlos\",2000,'project1')\nproject_manager_2 = ProjectManager(\"juan\",3000,'project2')\ndeveloper = Developer(\"yoel\",4000,'java')\ndeveloper_2 = Developer(\"yoel\",5000,'javascript')\nmanager.add_employee(project_manager)\nmanager.add_employee(project_manager_2)\nproject_manager.add_employee(developer)\nproject_manager_2.add_employee(developer_2)\nmanager.supervising()\nmanager.coordinate_projects()\nmanager.print_employees()\nproject_manager.print_employees()\ndeveloper.add_employee(developer_2)"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/raynerpv2022.py",
    "content": "# // /*\n# //  * EJERCICIO:\n# //  * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n# //  * implemente una superclase Animal y un par de subclases Perro y Gato,\n# //  * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n# //  *\n\n\n\n\n\nclass Animal:\n    \n    def __init__(self, nombre) -> None:\n        self.nombre = nombre\n\n\nclass Delfin (Animal):\n     \n    def __init__(self,  ruido, nombre) -> None:\n        super().__init__(nombre)\n        self.ruido = ruido\n\n    def sonido(self):\n        print(f\"Me llamo {self.nombre}, y hago {self.ruido}\")\n\nclass Tiburon (Animal):\n    def __init__(self,  ruido, nombre) -> None:\n        super().__init__(nombre)\n        self.ruido = ruido\n\n    def sonido(self):\n        print(f\"Me llamo {self.nombre}, y hago {self.ruido}\")\n\n\nTibu = Tiburon(\"GHGHGHGHGHGHG\", \"tiburcio\")\nTonina= Delfin(\"jijijijjjiijjjiji\", \"Toninota\")\nTibu.sonido()\nTonina.sonido()\n\n\n# //  * DIFICULTAD EXTRA (opcional):\n# //  * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n# //  * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n# //  * Cada empleado tiene un identificador y un nombre.\n# //  * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n# //  * actividad, y almacenan los empleados a su cargo.\n# //  */\n\nclass Empleado:\n    def __init__(self,id,nombre) -> None:\n        self.id = id\n        self.nombre = nombre\n        self.empleados_acargo = []\n\n    def addE(self, empleado):\n        self.empleados_acargo.append(empleado)\n\n    def mostrarE(self):\n        print(f\"Empleados A CArgo de {self.nombre}\")\n        for i in self.empleados_acargo:\n            print (i.nombre)\n     \n\nclass Gerente( Empleado):\n    def __init__(self, id, nombre) -> None:\n        super().__init__(id, nombre)\n        \n    def gerenciar(self):\n        print(f\"NOmbre : {self.nombre}  ID {self.id} ------ Empleados a Cargo : {len(self.empleados_acargo)}, Coordina todos los Proyectos\")\n\n\n    \nclass GerenteP (Empleado)  :\n    def __init__(self, id, nombre, proyecto) -> None:\n        super().__init__(id, nombre)\n        self.empleados_acargo = [] \n        self.proyecto = proyecto\n\n    def gerenciar(self):\n        print(f\"NOmbre : {self.nombre}  ID {self.id} ------ Empleados a Cargo : {len(self.empleados_acargo)}, Coordina el proyecto {self.proyecto} \")\n\n    def addE(self, empleado: Empleado):\n        self.empleados_acargo.append(empleado)\n\n    \n\n\nclass Programador(Empleado):\n    def __init__(self, id, nombre, language) -> None:\n        super().__init__(id, nombre)\n        self.language = language\n\n    def programar(self):\n        print(f\"NOmbre : {self.nombre}  ID {self.id} ------ programa en {self.language}\")\n    def addE(self, empleado):\n        print(\"No puede Tener empleados a su cargo\")\n\n\nP1 = Programador(99,\"Paco\", [\"Python\",\"C#\"])\nP2 = Programador(98,\"Kuko\",[\"GO\", \"C++\"])\nGP1 = GerenteP(22,\"Cucurella\",\"Web TOR\")\nG1 = Gerente(111,\"Gerente Manolo\")\nG1.addE(GP1)\nGP1.addE(P1)\nGP1.addE(P2)\n\nG1.gerenciar()\nGP1.gerenciar()\nP1.programar()\nP2.programar()\nG1.mostrarE()\nGP1.mostrarE()\nP1.addE(P2)\n\n\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/restevean.py",
    "content": "\"\"\"\nEjercicio 1\n\"\"\"\n\n\n# Superclass\nclass Animal:\n\n    def __init__(self, name: str):\n        self.name = name\n\n    def sound(self):\n        pass\n\n\n# Subclass\nclass Dog(Animal):\n\n    def sound(self):\n        return 'Wof!'\n\n\nclass Cat(Animal):\n\n    def sound(self):\n        return 'Meow!'\n\n\ndef my_animals():\n    print(\"Exercise\")\n    animals = [Dog('Odin'), Cat('Misifu')]\n    for animal in animals:\n        print(f'{animal.name} says {animal.sound()}')\n\n\n\"\"\"\nExtra\n\"\"\"\n\n\nclass Employee:\n\n    def __init__(self, employee_id: int, name: str):\n        self.id = employee_id\n        self.name = name\n        self.employees = []\n\n    def add(self, employee):\n        self.employees.append(employee)\n\n    def print_employees(self):\n        for employee in self.employees:\n            print(employee.name)\n\n\nclass Manager(Employee):\n\n    def coordinate_projects(self):\n        print('The manager is coordinating all projects')\n\n\nclass ProjectManager(Employee):\n\n    def manage_project(self):\n        print('The project manager is coordinating his own project')\n\n\nclass Programmer(Employee):\n\n    def __init__(self, id: int, name: str, language: str):\n        super().__init__(id, name)\n        self.language = language\n\n    def code(self):\n        print(f\"{self.name} is coding using {self.language}.\")\n\n\ndef my_employees():\n    print('Extra')\n    manager = Manager(1, 'John')\n    project_manager = ProjectManager(2, 'Paul')\n    programmer = Programmer(3, 'Ringo', 'Python')\n    manager.add(project_manager)\n    manager.add(programmer)\n    manager.print_employees()\n    project_manager.manage_project()\n    programmer.code()\n    manager.print_employees()\n\n\nif __name__ == '__main__':\n    my_animals()\n    my_employees()\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/rigo93acosta.py",
    "content": "'''\n/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n'''\n\nclass Animal:\n    def __init__(self, nombre: str) -> None:\n        self.nombre = nombre\n\n    def sonido(self):\n        pass\n\n# Subclases\nclass Perro(Animal):\n    def __init__(self, nombre: str) -> None:\n        super().__init__(nombre)\n\n    def sonido(self):\n        return f\"{self.nombre} Guau!\"\n    \nclass Gato(Animal):\n    def __init__(self, nombre: str) -> None:\n        super().__init__(nombre)\n\n    def sonido(self):\n        return f\"{self.nombre} Miau!\"\n\nfloki = Gato(\"Floki\")\nanimal = Animal(\"Animal\")\ndog = Perro(\"Dog\")\nprint(floki.sonido())\n\n# Empleo de Polimorfismo\ndef print_sonido(animal: Animal):\n    print(animal.sonido())\n\nprint_sonido(floki)\nprint_sonido(dog)\nprint_sonido(animal)\n\n'''\nEjercicio Extra\n'''\nclass Empleado: \n    def __init__(self, nombre: str, id: int) -> None:\n        self.nombre = nombre\n        self.id = id\n        self.empleados = []\n\n    def contratar(self, empleado: 'Empleado'):\n        self.empleados.append(empleado)\n    \n    def print_empleados(self):\n        for empleado in self.empleados:\n            print(empleado.nombre)\n\nclass Gerente(Empleado):\n    def __init__(self, nombre: str, id: int) -> None:\n        super().__init__(nombre, id)\n\n    def coordinar_proyecto(self):\n        print(f'{self.nombre} está coordinando todos los proyectos.')\n    \nclass GerenteProyecto(Empleado):\n    def __init__(self, nombre: str, id: int, proyecto: str) -> None:\n        super().__init__(nombre, id)\n        self.empleados = []\n        self.proyecto = proyecto\n\n    def coordinar_proyecto(self):\n        print(f'{self.nombre} está coordinando el proyecto {self.proyecto}.')\n\nclass Programador(Empleado):\n    def __init__(self, nombre: str, id: int, language: str) -> None:\n        super().__init__(nombre, id)\n        self.language = language\n\n    def programar(self):\n        print(f'{self.nombre} está programando en {self.language}.')\n\n    def contratar(self, empleado: Empleado):\n        print(f'No puedes contratar al empleado {empleado.nombre}, {self.nombre}.')\n\ngerente = Gerente(\"Gerente\", 1)\ngerenteProyecto = GerenteProyecto(\"Gerente Proyecto\", 2, 'Proyecto 1')\nprogramador = Programador(\"Programador\", 3, \"Python\")\nprogramador2 = Programador(\"Programador 2\", 4, \"Java\")\n\ngerente.contratar(gerenteProyecto)\ngerenteProyecto.contratar(programador)\nprogramador.contratar(programador2)\n\ngerente.print_empleados()\ngerenteProyecto.print_empleados()\n\nprogramador.programar()\n\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/rikmij.py",
    "content": "class Animal:\n    patas = 4\n    cola = True\n    \n    def talk(self):\n        pass\n\nclass Perro(Animal):\n    def talk(self):\n        return \"<Guau>\"\n\nclass Gato(Animal):\n    def talk(self):\n        return \"<Miau>\"\n\ncanino = Perro()\nprint(canino.talk())\nprint(canino.patas)\n\nmichi = Gato()\nprint(michi.talk())\nprint(michi.cola)\n\n\nprint('\\n', '~'*7, \"EJERCICIO EXTRA\", '~'*7)\n\nclass Employee:\n    def __init__(self, name, id, employment, employee):\n        self.name = name\n        self.id = id\n        self.employment = employment\n        self.employee = employee\n    \n    def meet_employee(self):\n        return f\"{self.name}: id - {self.id}\"\n    \n    def get_employees(self):\n        print(f\"\\n-> {self.name} está a cargo de:\")\n        for employ in self.employee:\n            print(f\"{employ.name} ({employ.employment}): id - {employ.id}\")\n\nclass Programmer(Employee):\n    def __init__(self, name, id, employment, language, employee):\n        super().__init__(name, id, employment, employee)\n        self.language = language\n    \n    def work(self):\n        return f\"{self.name}: Estoy trabajando en {self.language}\"\n\nclass ProjectManager(Employee):\n    def __init__(self, name, id, employment, employee, project):\n        super().__init__(name, id, employment, employee)\n        self.project = project\n    \n    def supervise(self):\n        return f\"{self.name}: Estoy \\\"supervisando\\\" {self.project}. ¿Cómo vais muchachos?\"\n    \nclass Manager(Employee):\n    def __init__(self, name, id, employment, employee, organization):\n        super().__init__(name, id, employment, employee)\n        self.organization = organization\n    \n    def organize(self):\n        return f\"{self.name}: Estoy organizando {self.organization}\"\n    \nvictor = Programmer(\"Víctor\", 11, \"Programador\", \"Python\", [])\njoel = Programmer(\"Joel\", 12, \"Programador\", \"Kotlin\", [])\nprint(victor.work())\nprint(joel.meet_employee())\n\nprogrammer_list = []\nprogrammer_list.append(victor)\nprogrammer_list.append(joel)\n\ngiovanni = ProjectManager(\"Giovanni\", 13, \"Project Manager\", programmer_list, \"COBOL Multiplatform\")\ngiovanni.get_employees()\nprint(giovanni.supervise())\n\nboss_list = []\nfor emp in programmer_list:\n    boss_list.append(emp)\nboss_list.append(giovanni)\n\nguido = Manager(\"Guido Van Rossum\", 14, \"Manager\", boss_list, \"Python\")\nguido.get_employees()\nprint(guido.organize())\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/santiagobailleres.py",
    "content": "'''EJERCICIO:\nExplora el concepto de herencia según tu lenguaje. Crea un ejemplo que\nimplemente una superclase Animal y un par de subclases Perro y Gato,\njunto con una función que sirva para imprimir el sonido que emite cada Animal.\nDIFICULTAD EXTRA (opcional):\nImplementa la jerarquía de una empresa de desarrollo formada por Empleados que\npueden ser Gerentes, Gerentes de Proyectos o Programadores.\nCada empleado tiene un identificador y un nombre.\nDependiendo de su labor, tienen propiedades y funciones exclusivas de su\nactividad, y almacenan los empleados a su cargo.'''\n\n# Superclase: una superclase es una clase de la que se heredan otras clases.\nclass Animal:\n    def __init__(self, nombre):\n        self.nombre = nombre\n\n    def sonido(self): # Método que se hereda a las subclases\n        pass # Este método se define en las subclases. Pass es una palabra clave que no hace nada.\n\n# Subclases: una subclase es una clase que hereda de una superclase.\nclass Dog(Animal):\n    def sonido(self):\n        print('Guau')\n\nclass Cat(Animal):\n    def sonido(self):\n        print('Miau')\n\ndef sonido_animal(animal: Animal): \n    animal.sonido() # Llama al método sonido de la clase animal\n\nmi_animal = Animal('Animal')\nsonido_animal(mi_animal)\nmi_perro = Dog('Perro')\nsonido_animal(mi_perro)\nmi_gato = Cat('Gato')\nsonido_animal(mi_gato)\n\n# EXTRA\nclass Empleado:\n    def __init__(self, id:int, nombre:str):\n        self.id = id\n        self.nombre = nombre\n        self.employees=[]\n    \n    def add_employee(self, employee):\n        self.employees.append(employee)\n    \n    def print_employees(self):\n        for employee in self.employees:\n            print(employee.nombre)\n\nclass Gerente(Empleado):\n    def coordinate_projects(self):\n        print(f\"{self.nombre} está coordinando todos los proyectos de la empresa.\")\n\nclass GerenteProyecto(Empleado):\n    def __init__(self, id:int, nombre:str, project:str):\n        super().__init__(id, nombre)\n        self.project = project\n    \n    def coordinate_project(self):\n        print(f\"{self.nombre} está coordinando el proyecto {self.project}.\")\n\nclass Programador(Empleado):\n    def __init__(self, id:int, nombre:str, lenguaje:str):\n        super().__init__(id, nombre)\n        self.lenguaje = lenguaje\n    \n    def code(self):\n        print(f\"{self.nombre} está programando en {self.lenguaje}.\")\n    \n    def add(self, employee:Empleado):\n        print(f\"Un programador no tiene empleados a su cargo. {employee.nombre} no se añadirá.\")\n\n# Crear empleados\nmi_gerente = Gerente(1, 'Santiago Bailleres')\nmi_project_manager = GerenteProyecto(2, 'Juan Perez', 'Proyecto 1')\nmi_project_manager2 = GerenteProyecto(3, 'Pedro Lopez', 'Proyecto 2')\nmi_programador = Programador(4, 'Maria Garcia', 'Python')\nmi_programador2 = Programador(5, 'Ana Martinez', 'Java')\nmi_programador3 = Programador(6, 'Luis Ramirez', 'C++')\nmi_programador4 = Programador(7, 'Carlos Sanchez', 'JavaScript')\n\nmi_gerente.add_employee(mi_project_manager)\nmi_gerente.add_employee(mi_project_manager2)\n\nmi_project_manager.add_employee(mi_programador)\nmi_project_manager.add_employee(mi_programador2)\nmi_project_manager2.add_employee(mi_programador3)\nmi_project_manager2.add_employee(mi_programador4)\n\nmi_programador.add(mi_programador4)\n\nmi_programador.code()\nmi_project_manager.coordinate_project()\nmi_gerente.coordinate_projects()\nmi_gerente.print_employees()\nmi_project_manager.print_employees()\nmi_programador.print_employees()"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/santyjL.py",
    "content": "#09 - HERENCIA\n\n\"\"\"\n/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n\"\"\"\n\nclass Animal:\n    def __init__(self ,nombre) -> None:\n        self.nombre = nombre\n\n    def sonido (self) -> str:\n        pass\n\n\nclass Perro(Animal):\n    def __init__(self , nombre):\n        super().__init__(nombre)\n\n        self.nombre = nombre\n\n    def sonido(self, sonido):\n        print(f\"el perro {self.nombre} hace {sonido}\")\n\n\nclass Gato(Animal):\n    def __init__(self, nombre) -> None:\n        super().__init__(nombre)\n\n        self.nombre = nombre\n\n    def sonido(self, sonido: str) -> str:\n        print(f\"El gato {self.nombre} hace {sonido}\")\n\n\nperro = Perro(\"Gaston\")\nperro.sonido(\"guau\")\ngato = Gato(\"Cachito\")\ngato.sonido(\"miau\")\n\n###Extra###\nclass Empleado:\n    def __init__(self, nombre, edad):\n        self.nombre = nombre\n        self.edad = edad\n\n    def deber(self):\n        pass\n\n    def sueldo(self):\n        pass\n\n    def __str__(self):\n        return f\"{self.__class__.__name__}: {self.nombre}, Edad: {self.edad}\"\n\n\nclass Gerente(Empleado):\n    def __init__(self, nombre, edad, empleados, salario):\n        super().__init__(nombre, edad)\n        self.empleados = empleados\n        self.salario = salario\n\n    def deber(self):\n        print(f\"El gerente tiene el deber de manejar, controlar y planificar el trabajo de sus empleados que son: {', '.join(self.empleados)}\")\n\n    def sueldo(self):\n        print(f\"El gerente tiene un sueldo de {self.salario}$.\")\n\n\nclass GerenteDeProyecto(Empleado):\n    def __init__(self, nombre, edad, proyectos):\n        super().__init__(nombre, edad)\n        self.proyectos = proyectos\n\n    def deber(self):\n        print(f\"El Gerente de Proyecto tiene el deber de supervisar y coordinar proyectos como: {', '.join(self.proyectos)}\")\n\n    def sueldo(self):\n        print(\"El sueldo del Gerente de Proyecto depende del éxito de los proyectos.\")\n\n\nclass Programador(Empleado):\n    def __init__(self, nombre, edad, lenguajes):\n        super().__init__(nombre, edad)\n        self.lenguajes = lenguajes\n\n    def deber(self):\n        print(f\"El Programador tiene el deber de desarrollar software utilizando los siguientes lenguajes: {', '.join(self.lenguajes)}\")\n\n    def sueldo(self):\n        print(\"El sueldo del Programador se basa en su experiencia y habilidades técnicas.\")\n\n\n# Llamadas en el código principal\n\ngerente = Gerente(\"Julian\", 38, [\"Fernando\", \"Cesar\"], 6000)\nprint(gerente)\ngerente.deber()\ngerente.sueldo()\n\ngerente_proyecto = GerenteDeProyecto(\"Ana\", 32, [\"Proyecto A\", \"Proyecto B\"])\nprint(gerente_proyecto)\ngerente_proyecto.deber()\ngerente_proyecto.sueldo()\n\nprogramador = Programador(\"Carlos\", 25, [\"Python\", \"JavaScript\"])\nprint(programador)\nprogramador.deber()\nprogramador.sueldo()"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/sorubadguy.py",
    "content": "\"\"\"\n*Herencia\n\"\"\"\n\nclass Animal:\n    \n    def __init__(self, patas: int, color_pelo: str, tipo_pelo: str, raza: str) -> None:\n        self.patas = patas\n        self.color_pelo = color_pelo\n        self.tipo_pelo = tipo_pelo\n        self.raza = raza\n    \n    def imprimir_caracteristicas(self):\n        print(self.raza)\n        print(self.color_pelo)\n        print(self.tipo_pelo)\n        print(self.patas)\n\nclass Perro(Animal):\n    \n    def sonido(self, sonido = \"Guau\"):\n        self.sonido = sonido\n\n    def imprimir_sonido(self):\n        print(self.sonido)\n\nclass Gato(Animal):\n\n    def sonido(self, sonido = \"Miau\"):\n        self.sonido = sonido\n\n\n    def imprimir_sonido(self):\n        print(self.sonido)\n\nperro = Perro(4, \"negro\", \"corto\", \"labrador\")\nperro.sonido(\"Guau\")\ngato = Gato(4, \"marron\", \"largo\", \"gato\")\ngato.sonido(\"Miau\")\nperro.imprimir_caracteristicas()\nperro.imprimir_sonido()\ngato.imprimir_caracteristicas()\ngato.imprimir_sonido()\n\n\"\"\"\n!Extra\n\"\"\"\n\nclass Empleado():\n\n    def __init__(self, carga_horaria: int, paga: float, id: int, nombre: str) -> None:\n        self.carga_horaria = carga_horaria\n        self.paga = paga\n        self.nombre = nombre\n        self.id = id\n    \n    def mostrar_datos_base(self):\n        print(f\"id: {self.id}\\nnombre: {self.nombre}\\ncarga horaria: {self.carga_horaria} horas\\npaga: {self.paga}\")\n\nclass Gerente(Empleado):\n\n    def imprimir_tarea(self):\n        print(f\"{self.nombre} es gerente general\")\n\nclass Gerente_Proyecto(Empleado):\n    \n    def agregar_proyecto(self, proyecto: list):\n        self.proyecto = []\n        self.proyecto.append(proyecto)\n\n    def mostrar_proyectos(self):\n        for i in range(0, len(self.proyecto)):\n            print(self.proyecto[i])\n\n\nclass Programador(Empleado):\n\n    def estoy_programando(self):\n        print(f\"{self.nombre} esta programando\")\n\nempleado1 = Empleado(4, 35.5, 1, \"Pedrito\")\nempleado1.mostrar_datos_base()\n\ngerente1 = Gerente(8, 20, 2, \"pancho\")\ngerente1.mostrar_datos_base()\ngerente1.imprimir_tarea()\n\ngerente2 = Gerente_Proyecto(10, 15.4, 3, \"Pablo\")\ngerente2.agregar_proyecto([\"web organizacion\", \"pagos\"])\ngerente2.mostrar_datos_base()\ngerente2.mostrar_proyectos()\n\nprogramador1 = Programador(5, 8, 4, \"Fede\")\nprogramador1.estoy_programando()"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/sperezsa.py",
    "content": "#09 HERENCIA Y POLIMORFISMO\n\n# Superclase\nclass Animal:\n    def __init__(self, name: str):\n        self.name = name\n    \n    def sound(self):\n        pass #personalizado en cada una de las subclases\n\n# Subclases\nclass Dog(Animal):\n    def sound(self):\n        print(f\" {self.name} hace guau!\")\n\nclass Cat(Animal):\n    def sound(self):\n        print(f\" {self.name} hace miau!\")\n\n\nmy_animal = Animal(\"Ferny\")\nmy_animal.sound()\n\nmy_dog = Dog(\"Oddy\")\nmy_dog.sound()\n\nmy_cat = Cat(\"Duchess\")\nmy_cat.sound()\n\n\n\"\"\"\nExtra\n\"\"\"\n\nclass Employee:\n    def __init__(self, id: int, name: str):\n        self.id = id\n        self.name = name\n        self.employees = []\n        \n    def add(self, employee):\n        self.employees.append(employee)\n\n    def count_employees(self):\n        print(f\"{self.name} tiene a su cargo {len(self.employees)} empleados.\")\n        \n\nclass Manager(Employee):\n    def manage(self):\n        print(f\"El manager {self.name} gestiona los proyectos.\")\n\n     \nclass ProjectManager(Employee):\n    def __init__(self, id: int, name: str, project: str):\n        super().__init__(id, name)\n        self.project = project\n    \n    def manage_project(self):\n        print(f\"El PM {self.name} gestiona el proyecto {self.project}.\")\n        \n    \nclass Programmer(Employee):\n    def __init__(self, id: int, name: str, language: str):\n        super().__init__(id, name)\n        self.language = language\n    \n    def coding(self):\n        print(f\"El programador {self.name} codifica en el lenguaje {self.language}.\")\n        \n    def add(self, id: int):\n        print(f\"Programadores no pueden tener personal a su cargo. {id} no asignado.\")\n\n\npg1 = Programmer(1, 'Anne', 'Python')\npg2 = Programmer(2, 'John', 'JS')\npg3 = Programmer(3, 'Morgan', 'Python')\npg4 = Programmer(4, 'Lilly', 'Java')\npg5 = Programmer(5, 'Clark', 'PHP')\npm1 = ProjectManager(6, 'Carl', 'secreto')\npm2 = ProjectManager(7, 'Kevin', 'interno')\nmng = Manager(8, 'Susan')\n\npg1.add(4)\npg1.coding()\npg2.coding()\npg3.coding()\npg4.coding()\npg5.coding()\npm1.add(pg3)\npm1.add(pg2)\npm1.add(pg1)\npm1.manage_project()\npm1.count_employees()\npm2.add(pg4)\npm2.add(pg5)\npm2.manage_project()\npm2.count_employees()\nmng.add(pm1)\nmng.add(pm2)\nmng.manage()\nmng.count_employees()\npg1.count_employees()"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/switchdays.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n\"\"\"\n\n# Superclase:\nclass Animal:\n    def __init__(self, nombre):\n        self.nombre = nombre\n\n    def sonido(self):\n        pass\n\n# Subclases:\nclass Perro(Animal):\n    def sonido(self):\n        print(f\"El perro {self.nombre} hace guau\")\n\nclass Gato(Animal):\n    def sonido(self):\n        print(f\"El gato {self.nombre} hace miau\")\n\nperro = Perro(\"Toby\")\ngato = Gato(\"Michi\")\n\nperro.sonido()\ngato.sonido()\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n\"\"\"\n\nclass Empleado:\n    def __init__(self, id, nombre):\n        self.id = id\n        self.nombre = nombre\n\nclass Gerente(Empleado):\n    def __init__(self, id, nombre, salario):\n        super().__init__(id, nombre)\n        self.salario = salario\n        self.personas_a_cargo = []\n\n    def empleados_a_cargo(self, empleado):\n        self.personas_a_cargo.append(empleado)\n        print(f\"Empleados a cargo de {self.nombre}: {self.personas_a_cargo}\")\n\n\n    def actividad(self):\n        print(f\"El gerente {self.nombre}, con identificador {self.id}, gestiona el departamente correspondiente.\")\n\nclass Gerente_de_proyectos(Empleado):\n    def __init__(self, id, nombre, salario):\n        super().__init__(id, nombre)\n        self.salario = salario\n        self.personas_a_cargo = []\n\n    def empleados_a_cargo(self, empleado):\n        self.personas_a_cargo.append(empleado)\n        print(f\"Empleados a cargo de {self.nombre}: {self.personas_a_cargo}\")\n\n\n    def actividad(self):\n        print(f\"El gerente de proyectos {self.nombre}, con identificador {self.id}, gestiona el departamente de proyectos.\")\n\nclass Programador(Empleado):\n    def __init__(self, id, nombre, salario):\n        super().__init__(id, nombre)\n        self.salario = salario\n        self.personas_a_cargo = []\n\n# El programador no tiene personas a su cargo.\n\n\n    def actividad(self):\n        print(f\"El programador {self.nombre}, con identificador {self.id}, se encarga de desarrollar la web de la empresa.\")\n\ngerente = Gerente(12345, \"Manoleke\", 10000)\ngerente.actividad()\ngerente.empleados_a_cargo(\"Gustavo\")\n\ngerente_de_proyectos = Gerente_de_proyectos(98765, \"Pakito\", 20000)\ngerente_de_proyectos.actividad()\ngerente_de_proyectos.empleados_a_cargo(\"Patricio\")\n\nprogramador = Programador(34567, \"Pepe\", 30000)\nprogramador.actividad()"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/thonys07.py",
    "content": "\"\"\"\n EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n \n\"\"\"\n\nclass Animal:\n    def __init__(self, nombre:str):\n        self.nombre = nombre\n\n    def imprimirSonido(self):\n        pass\n\nclass Perro(Animal):\n    def imprimirSonido(self):\n        print(f\"soy {self.nombre} y hago GUAU\")\n\nclass Gato(Animal):\n    def imprimirSonido(self):\n        print(f\"soy {self.nombre} y hago MIAU\")\n\n\n#Ejemplo:\nperro = Perro('ComoTu')\ngato = Gato('Minino')\nperro.imprimirSonido()\ngato.imprimirSonido()\n\n\n\"\"\" * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\"\"\"\n\nclass Empleado:\n    def __init__(self, identificador:int, nombre:str):\n        self.identificador = identificador\n        self.nombre = nombre\n        self.empleados=[]\n    def add_empleados(self,empleados):\n        self.empleados.append(empleados)\n    def imprimir_empleados(self):\n        for empleado in self.empleados:\n            print(f\"{empleado.nombre} esta bajo ordenes de {self.nombre}\")\n    \nclass Gerente(Empleado):\n    def supervision(self):\n        print(f\"{self.nombre} esta supervisando\")\n\nclass GerenteProyecto(Empleado):\n    def __init__(self, identificador:int, nombre:str, proyecto:str):\n        super().__init__(identificador, nombre)\n        self.proyecto = proyecto\n    def coordinar_proyectos(self):\n        print(f\"{self.nombre} esta coordinado su proyecto {self.proyecto}\")\n\nclass Programador(Empleado):\n    def __init__(self, identificador:int, nombre:str, lenguaje:str, proyecto:str):\n        super().__init__(identificador, nombre)\n        self.lenguaje = lenguaje\n        self.proyecto = proyecto\n    def programar(self):\n        print(f\"{self.nombre} esta programando el proyecto {self.proyecto} en {self.lenguaje}\")\n    def add(self, empleado: Empleado):\n        print(\n            f\"Un programador no tiene empleados a su cargo. {empleado.name} no se añadirá.\")\n\ngerente=Gerente(0, \"Thony\")\ngerente_de_proyectos=GerenteProyecto(1, \"Juan\", \"Proyecto A\")\ngerente_de_proyectos2=GerenteProyecto(2, \"Pedro\", \"Proyecto B\")\nprogramador1=Programador(3, \"Carlos\", \"Python\", \"Proyecto A\")\nprogramador2=Programador(4, \"Luis\", \"Java\", \"Proyecto A\")\nprogramador3=Programador(5, \"Maria\", \"C++\", \"Proyecto B\")\ngerente.add_empleados(gerente_de_proyectos)\ngerente.add_empleados(gerente_de_proyectos2)\ngerente_de_proyectos.add_empleados(programador1)\ngerente_de_proyectos.add_empleados(programador2)\ngerente_de_proyectos2.add_empleados(programador3)\ngerente.imprimir_empleados()\ngerente_de_proyectos.imprimir_empleados()\ngerente_de_proyectos2.imprimir_empleados()\nprogramador1.imprimir_empleados()\nprogramador2.imprimir_empleados()\nprogramador3.imprimir_empleados()\ngerente_de_proyectos.coordinar_proyectos()\ngerente_de_proyectos2.coordinar_proyectos()\nprogramador1.programar()\nprogramador2.programar()\nprogramador3.programar()"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/tito-delpino.py",
    "content": "#  * EJERCICIO:\n#  * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n#  * implemente una superclase Animal y un par de subclases Perro y Gato,\n#  * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n\nclass Animal:\n    def __init__(self, name):\n        self.name = name\n\n    def sonido(self):\n        return \"Cada animal hace un sonido\"\n    \n\nclass Perro(Animal):\n    def sonido(self):\n        return 'Guau'\n    \nclass Gato(Animal):\n    def sonido(self):\n        return 'Miau'\n    \nanimales = [Perro('Tito'), Gato('Liro')]\nfor animal in animales:\n    print(f'{animal.name} hace {animal.sonido()}')\n\nprint(\"/\" * 50)\n#  * DIFICULTAD EXTRA (opcional):\n#  * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n#  * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n#  * Cada empleado tiene un identificador y un nombre.\n#  * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n#  * actividad, y almacenan los empleados a su cargo.\n\n\nclass Empleado():\n    def __init__(self, nombre, id):\n        self.nombre = nombre\n        self.id = id\n        self.empleados = []\n\n    def agregar_empleado(self, empleado):\n        self.empleados.append(empleado)\n\n    def imprimir_empleados(self):\n        for empleado in self.empleados:\n            print(empleado.nombre)\n\n    \nclass Gerentes(Empleado):    \n    def coordinar_proyectos(self):\n        print(f'{self.nombre} coordina todos los proyectos abiertos')\n\n\nclass GerenteProyectos(Empleado):\n    def __init__(self, nombre, id, proyecto):\n        super().__init__(nombre, id)\n        self.proyecto = proyecto\n\n    def coordinar_proyecto(self):\n        print(f'{self.nombre} coodina los proyectos asignados')\n\nclass Programadores(Empleado):   \n    def __init__(self, nombre, id, lenguaje):\n        super().__init__(nombre, id)\n        self.lenguaje = lenguaje\n\n    def programar(self):\n        print(f\"{self.nombre} esta programando en {self.lenguaje}\")\n\n    def agregar_empleado(self, empleado: Empleado):\n        print(f'Los programadores no tienen empleados a cargo, {empleado.nombre} no agregado')\n\n\n# creamos los objetos de clases\nmanager = Gerentes(\"Tito\", 1234)\nproyect_manager = GerenteProyectos(\"Ana\", 4567, 'Proyecto Granada')\nproyect_manager2 = GerenteProyectos(\"Fefi\", 4569, 'Proyecto Motril')\nprogramador = Programadores('Alvaro', 9876, 'Python')\nprogramador2 = Programadores('Pepe', 345, 'C++')\nprogramador3 = Programadores('Juan', 544, 'Java')\nprogramador4 = Programadores('Luis', 765, 'Swift')\n\n# usamos el metodo de agregar a listados de cada objeto\nmanager.agregar_empleado(proyect_manager)\nproyect_manager.agregar_empleado(programador)\nproyect_manager.agregar_empleado(programador2)\nproyect_manager2.agregar_empleado(programador3)\nproyect_manager2.agregar_empleado(programador4)\nprogramador.agregar_empleado(programador2)\n\n# verificamos los demas metodos de subclases\nmanager.coordinar_proyectos()\nproyect_manager.coordinar_proyecto()\nproyect_manager2.coordinar_proyecto()\nprogramador.programar()\nprogramador2.programar()\nprogramador3.programar()\nprogramador4.programar()\n\n# usamos el metodo de impresion de empleados\nmanager.imprimir_empleados()\nproyect_manager.imprimir_empleados()\nproyect_manager2.imprimir_empleados()\nprogramador.agregar_empleado(programador2)\nprogramador.imprimir_empleados() # los programadores no pueden tener empleados a cargo por lo tanto no printea nada"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/victorfer69.py",
    "content": "#HERENCIA\n\n#Superclase\nclass Animal:\n\n    def __init__(self, name:str):\n        self.name = name\n\n    def sound(self):\n        pass\n\n#Subclases\nclass Dog(Animal):\n    \n    def sound(self):\n        print(\"Guau!\")\n\nclass Cat(Animal):\n    \n    def sound(self):\n        print(\"Miau!\")\n\ndef print_sound(animal:Animal):\n    animal.sound()\n\nmy_animal = Animal(\"Animal\")\nmy_animal.sound()\nprint_sound(my_animal)\nmy_dog = Dog(\"Perro\")\nmy_dog.sound()\nprint_sound(my_dog)\nmy_cat = Cat(\"Gato\")\nmy_cat.sound()\nprint_sound(my_cat)\n\n\n#EJERCICIO EXTRA\n\n#Superclase\nclass Empleado():\n\n    def __init__(self, id:str, name:str):\n        self.id = id\n        self.name = name\n        self.empleados = []\n\n    def agregaEmpleado(self, empleado):\n        self.empleados.append(empleado)\n\n    def printEmpleados(self):\n        for i in self.empleados:\n            print(i.name)\n\n#Subclases\nclass Gerente(Empleado):\n    \n    def function(self):\n        print(\"Soy un Gerente\")\n\n\nclass GerenteProyecto(Empleado):\n\n    def __init__(self, id:str, name:str, proyect: str):\n        super().__init__(id, name)\n        self.proyect = proyect\n    \n    def function(self):\n        print(\"Soy un Gerente de Proyectos\")\n\nclass Programador(Empleado):\n\n    def __init__(self, id:str, name:str, language: str):\n        super().__init__(id, name)\n        self.languaje = language\n    \n    def function(self):\n        print(f\"Soy un Programador programando en {self.languaje}\")\n\n    def agregaEmpleado(self, empleado):\n        print(\"El Programador no puede agregar empleados\")\n\nmy_gerente = Gerente(1, \"Victor\")\nmy_gerente_proyecto1 = GerenteProyecto(2, \"Pepe\", \"Proyecto 1\")\nmy_gerente_proyecto2 = GerenteProyecto(3, \"Paco\", \"Proyecto 2\")\nmy_programador1 = Programador(4, \"Control\", \"Java\")\nmy_programador2 = Programador(5, \"Ros\", \"Cobol\")\nmy_programador3 = Programador(6, \"Busi\", \"Python\")\nmy_programador4 = Programador(7, \"Naso\", \"Dart\")\n\nmy_gerente.agregaEmpleado(my_gerente_proyecto1)\nmy_gerente.agregaEmpleado(my_gerente_proyecto2)\n\nmy_gerente_proyecto1.agregaEmpleado(my_programador1)\nmy_gerente_proyecto1.agregaEmpleado(my_programador2)\n\n\nmy_gerente_proyecto2.agregaEmpleado(my_programador3)\nmy_gerente_proyecto2.agregaEmpleado(my_programador4)\n\nmy_programador1.agregaEmpleado(my_programador2)\n\nmy_programador1.function()\nmy_gerente_proyecto1.function()\nmy_gerente.function()\n\nmy_gerente.printEmpleados()"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/warclimb.py",
    "content": "#09 HERENCIA\n#### Dificultad: Media | Publicación: 26/02/24 | Corrección: 04/03/24\n\n## Ejercicio\n\n\n\"\"\"\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n \"\"\"\n\nclass Animal:\n    def __init__(self, nombre, sonido):\n        self._nombre = nombre\n        self._sonido = sonido\n\n    # getters y setters\n    @property\n    def nombre(self):\n        return self._nombre\n    \n    @nombre.setter\n    def nombre(self, nombre):\n        self._nombre = nombre\n    \n    @property\n    def sonido(self):\n        return self._sonido\n    \n    @sonido.setter\n    def sonido(self, sonido):\n        self._sonido = sonido\n\n    def emitir_sonido(self):\n        return self._sonido\n\nclass Perro(Animal):\n    def __init__(self, nombre):\n        super().__init__(nombre, \"AWUUUFFF!\")\n\nclass Gato(Animal):\n    def __init__(self, nombre):\n        super().__init__(nombre, \"Mmmmmmeeeeeoooowww!\")\n\n# Creo un perro y un gato\nperro = Perro(\"Sora\")\ngato = Gato(\"Doña Tecla\")\n\n# Muestro el sonido que emiten\nprint(f\"Hola soy {perro._nombre} escucha esto: {perro.emitir_sonido()}\")\nprint(f\"Hola soy {gato._nombre} escucha esto: {gato.emitir_sonido()}\")\n\n\n# DIFICULTAD EXTRA\nclass Empleado:\n    \"\"\"\n    Clase padre que representa a los empleados\n    args:\n    - id (int): identificador del empleado\n    - nombre (str): nombre del empleado\n    \"\"\"\n    def __init__(self, id, nombre):\n        self._id = id\n        self._nombre = nombre\n\n    # getters y setters\n    @property\n    def id(self):\n        return self._id\n    \n    @id.setter\n    def id(self, id):\n        self._id = id\n    \n    @property\n    def nombre(self):\n        return self._nombre\n    \n    @nombre.setter\n    def nombre(self, nombre):\n        self._nombre = nombre\n\n    def __str__(self):\n        return f\"Empleado: {self._nombre}\"\n\nclass Gerente(Empleado):\n    \"\"\"\n    Clase que representa a un gerente\n    args:\n    - id (int): identificador del empleado\n    - nombre (str): nombre del empleado\n\n    methods:\n    - contratar(empleado): contrata un empleado\n    - despedir(empleado): despide un empleado\n    - mostrar_empleados(): muestra los empleados a cargo\n    \"\"\"\n\n    def __init__(self, id, nombre):\n        super().__init__(id, nombre)\n        print(\"Gerente creado\")\n        self._empleados = []\n\n    def contratar(self, empleado):\n        self._empleados.append(empleado)\n    \n    def despedir(self, empleado):\n        self._empleados.remove(empleado)\n    \n    def mostrar_empleados(self):\n        return self._empleados\n\n    def __str__(self):\n        return f\"Gerente: {self._nombre}\"\n    \nclass GerenteProyecto(Empleado):\n    \"\"\"\n    Clase que representa a un gerente de proyecto\n    args:\n    - id (int): identificador del empleado\n    - nombre (str): nombre del empleado\n\n    methods:\n    - asignar_proyecto(proyecto): asigna un proyecto\n    - mostrar_proyectos(): muestra los proyectos asignados\n    \"\"\"\n\n    def __init__(self, id, nombre):\n        super().__init__(id, nombre)\n        print(\"Gerente de Proyecto creado\")\n        self._proyectos = []\n\n    # getters y setters\n    @property\n    def proyectos(self):\n        return self._proyectos\n\n    @proyectos.setter\n    def proyectos(self, proyectos):\n        self._proyectos = proyectos\n    \n    # metodos\n    def asignar_proyecto(self, proyecto):\n        \"\"\"\n        Asigna un proyecto al gerente de proyecto\n        args:\n        - proyecto (str): proyecto a asignar\n        \"\"\"\n        self._proyectos.append(proyecto)\n    \n    def mostrar_proyectos(self):\n        \"\"\"\n        Muestra los proyectos asignados al gerente de proyecto\n        \"\"\"\n        return self._proyectos\n    \n    def __str__(self):\n        return f\"Gerente de Proyecto: {self._nombre}\"\n\nclass Programador(Empleado):\n    \"\"\"\n    Clase que representa a un programador\n    args:\n    - id (int): identificador del empleado\n    - nombre (str): nombre del empleado\n\n    methods:\n    - asignar_especialidades(especialidad): asigna una especialidad\n    - mostrar_especialidades(): muestra las especialidades asignadas\n    \"\"\"\n\n    def __init__(self, id, nombre):\n        super().__init__(id, nombre)\n        print(\"Programador creado\")\n        self._especialidades = []\n\n    # getters y setters\n    @property\n    def especialidades(self):\n        return self._especialidades\n    \n    @especialidades.setter\n    def especialidades(self, especialidades):\n        self._especialidades = especialidades\n    \n    # métodos\n    def asignar_especialidades(self,especialidad):\n        \"\"\"\n        Asigna una especialidad al programador\n        args:\n        - especialidad (str): especialidad a asignar\n        \"\"\"\n        self._especialidades.append(especialidad)\n        \n        \n    def mostrar_especialidades(self):\n        \"\"\"\n        Muestra las especialidades asignadas al programador\n        \"\"\"\n        return self._especialidades\n    \n    def __str__(self):\n        return f\"Programador: {self._nombre}, especialista en {self._especialidades}\"\n\n# Creamos empleados de diferentes tipos\ngerente = Gerente(1, \"Juan\")\ngerente_proyecto = GerenteProyecto(2, \"Pedro\")\nprogramador_cobol = Programador(3, \"Eutimio\")\n\n# Contratamos empleados\ngerente.contratar(gerente_proyecto)\ngerente_proyecto.asignar_proyecto(\"TPV Bancos\")\n\n# asignamos especialidades al programador\nprogramador_cobol.asignar_especialidades(\"Cobol\")\n\n# Mostramos los empleados a cargo del gerente\nprint(f\"{gerente} tiene a cargo a: {gerente.mostrar_empleados()}\")\nprint(f\"{gerente_proyecto} tiene asignado el proyecto: {gerente_proyecto.mostrar_proyectos()}\")\nprint(f\"{programador_cobol} tiene asignadas las especialidades: {programador_cobol.mostrar_especialidades()}\")\n    \n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/worlion.py",
    "content": "\"\"\"\n    HERENCIA EN PYTHON\n\"\"\"\n# Clase animal (superclase)\nclass Animal:\n    nombre = \"\"\n    sonido = \"\"\n    icono = \"\"\n    \n    def __init__(self, nombre = \"\", sonido=\"\", icono = \"❓\") -> None:\n        self.nombre = nombre\n        self.sonido = sonido\n        self.icono = icono\n\n    def hacer_sonido(self):\n        print(f\"el {self.nombre} hace: {self.sonido} {self.icono}\")        \n\n# Clase perro (subclase)\nclass Perro(Animal):\n    def __init__(self) -> None:\n        super().__init__(\"Perro\", \"guau!\", \"🐶\")\n        \n# Clase gato (subclase)\nclass Gato(Animal):\n    def __init__(self) -> None:\n        super().__init__(\"Gato\", \"miau!\", \"🐱\")\n        \nmyDog = Perro()\nmyDog.hacer_sonido()\n        \nmyCat = Gato()\nmyCat.hacer_sonido()\n\n\"\"\"\nDIFICULTAD EXTRA (opcional): Empleados\n\"\"\"\n\nprint(\"\\n ---- 🌩 DIFICULTAD EXTRA 🌩 ----\\n\")\n\nclass Employee:\n    \n    def __init__(self, id: int, name: str ) -> None:\n        self.id = id\n        self.name = name\n        self.employees_in_charge = []\n    \n    def add_employee(self, employee):\n        if isinstance(employee, Employee):\n            self.employees_in_charge.append(employee)\n        else:\n            print(\"Invalid Employee\")\n        \n    def print_self(self):\n        print(f\" - Empleado: id = {self.id} ; nombre = {self.name} ; empleados a cargo = {len(self.employees_in_charge)}\" )\n        \n    def print_employees(self):\n        if(len(self.employees_in_charge) > 0):\n            print(f\"Empleados a cargo de {self.name}\")\n            for employee in self.employees_in_charge:\n                employee.print_self()\n            print(\"\\n\")\n\nclass Manager(Employee):\n    \n    def print_self(self):\n        print(f\" - Manager 😈: id = {self.id} ; nombre = {self.name} ; empleados a cargo = {len(self.employees_in_charge)}\")\n        \n    def ask_something(self):\n        print(f\"Lo siento, {self.name} es demasiado importante y está demasiado ocupado\")\n\nclass ProyectManager(Employee):\n    \n    proyects: list[str]\n    \n    def __init__(self, id: int, name: str, proyects: list[str] = None) -> None:\n        super().__init__(id, name)\n        if proyects is None:\n            self.proyects = []\n        else:\n            self.proyects = proyects\n    \n    def print_self(self):\n        print(f\" - ProyectManager 🤓: id = {self.id} ; nombre = {self.name} ; empleados a cargo = {len(self.employees_in_charge)} ; proyectos a cargo = {len(self.proyects)}\")\n    \n    def add_proyect(self, proyect: str):\n        self.proyects.append(proyect)\n\nclass Developer(Employee):\n\n    def __init__(self, id: int, name: str, languages: list[str]) -> None:\n        super().__init__(id, name)\n        self.languages = languages\n    \n    def add_language(self,language: str):\n        self.languages.append(language)\n    \n    def print_self(self):\n        print(f\" - Developer 👨‍💻: id = {self.id} ; nombre = {self.name} ; lenguajes: {self.languages}\")\n    \n    def add_employee(self, employee):\n        print(\"Un developer no tiene empleados a cargo\")\n        \nminion1 = Developer(201, \"Kevin\", [\"Python\"])\nminion1.add_language(\"Java\")\nminion1.print_self()\n\nminion2 = Developer(202, \"Stuart\", [\"PHP\", \"Lisp\"])\nminion3 = Developer(203, \"Jerry\", [\"Haskel\", \"Rust\", \"C#\"])\nminion2.print_self()\nminion3.print_self()\n\nlieutenant1 = ProyectManager(101, \"O'Neil\", [\"proyecto caca\"])\nlieutenant1.add_employee(minion1)\nlieutenant1.add_employee(minion2)\nlieutenant1.add_proyect(\"otro\")\nlieutenant2 = ProyectManager(102, \"Ripley\", [\"TOP SECRET\"])\nlieutenant2.add_employee(minion3)\nlieutenant1.print_self()\nlieutenant1.print_employees()\nlieutenant2.print_self()\nlieutenant2.print_employees()\n\nthe_king = Manager(1, \"Jaffe Joffer\")\nthe_king.add_employee(lieutenant1)\nthe_king.add_employee(lieutenant2)\n\nthe_king.print_self()"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/xemita007.py",
    "content": "\"\"\"ejercicio\"\"\"\n\nclass Animal:\n\n    def __init__(self,nombre):\n        self.nombre=nombre\n\n    def sonido(self):\n        print(\"x\")\n\n\nclass Perro(Animal):\n\n\n    def sonido(self):\n        print(\"guau\")\n\n\n\nclass Gato(Animal):\n\n\n    def sonido(self):\n        print(\"Miau\")\n\n\ndef sonidoA(animal: Animal):\n    animal.sonido()\n\n    \n\nanimal =Animal(\"animal\")\n\nsonidoA(animal)\n\nperro=Perro(\"maya\")\nsonidoA(perro)\n\ngato=Gato(\"nala\")\nsonidoA(gato)\n\n\nclass Empleado:\n\n    def __init__(self,id,nombre) :\n        self.id=id\n        self.nombre=nombre\n        self.trabajadores=[]\n\n    def añadirEmpleados(self,trabajador):\n        self.trabajadores.append(trabajador)\n    \n    def imprimirEmpleados(self):\n        for trabajador in self.trabajadores:\n            print(trabajador.nombre)   \n\nclass Gerente(Empleado):\n    \n    def coorProyectos(self):\n        print(f\"el {self.nombre} esta cordinando los proyectos\")\n\n\nclass Gerente_Poryectos(Empleado):\n    def __init__(self, id, nombre,proyectos):\n        super().__init__(id, nombre)\n        self.proyectos = proyectos\n\n    \n    def coorProyecto(self):\n        print(f\" el {self.nombre} esta cordinando el proyecto {self.proyectos} \")\n\nclass Programadores(Empleado):\n    def __init__(self, id, nombre,lenguajes):\n        super().__init__(id, nombre)\n        self.lenguajes=lenguajes\n\n    def lenguaje(self):\n        print(f\"el {self.nombre} utiliza {self.lenguajes} como lenguajes de programación\")\n\n    def añadirEmpleados(self,trabajadores:Empleado):\n        print(f\"el programador no tiene trabajadores a su cargo {trabajadores.nombre} no sera añadido\")\n\n\n\n\n\n\ngerente=Gerente(1,\"chema\")\ngerenteP=Gerente_Poryectos(2,\"antonio\",\"app\")\ngerenteP2=Gerente_Poryectos(3,\"pepe\",\"web\")\nmiProgramador=Programadores(4,\"devChema\",\"python\")\nmiProgramador2=Programadores(4,\"Mouredev\",\"java\")\n\ngerente.añadirEmpleados(gerenteP)\ngerente.añadirEmpleados(gerenteP2)\ngerenteP2.añadirEmpleados(miProgramador)\n\nmiProgramador.añadirEmpleados(miProgramador2)\n\nmiProgramador.lenguaje()\n\ngerente.coorProyectos()\ngerenteP.coorProyecto()\n\ngerente.imprimirEmpleados()\ngerenteP2.imprimirEmpleados()\n\nmiProgramador.imprimirEmpleados()## en este no va tener salida\n\n\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/ycanas.py",
    "content": "# ------ Ejercicio\n\nclass Animal:\n    \n    def __init__(self, age: int, name: str, breed: str):\n        self.age = age\n        self.name = name\n        self.breed = breed\n\n    \n    def sound(self):\n        pass\n        \n\nclass Dog(Animal):\n    \n    def sound(self):\n        print(\"Wouf Wouf!\")\n\n\nclass Cat(Animal):\n    \n    def sound(self):\n        print(\"Mauw Mauw!\")\n\n\nanimal = Animal(10, \"Appa\", \"Bisonte\")\nanimal.sound()\ngato = Cat(12, \"Milo\", \"Siberiano\")\ngato.sound()\nperro = Dog(4, \"Fiona\", \"Bulldog\")\nperro.sound()\n\n\n# ------ Extra\n\nclass Employee:\n\n    def __init__(self, id: int, name: str):\n        self.id = id\n        self.name = name\n        self.employees = []\n\n    \n    def add_employee(self, employee):\n        self.employees.append(employee)\n\n    \n    def print_employees(self):\n        for employee in self.employees:\n            print(employee.name)\n\n\nclass Manager(Employee):\n\n    def coordinate_projects(self):\n        print(f\"{self.name} está coordinando los proyectos de la empresa.\")\n\n\nclass ProjectManager(Employee):\n\n    def __init__(self, id: int, name: str, project: str):\n        super().__init__(id, name)\n        self.project = project\n\n    \n    def coordinate_project(self):\n        print(f\"{self.name} está coordinando el proyecto {self.project}\")\n\n\nclass Programmer(Employee):\n\n    def __init__(self, id: int, name: str, project: str, language: str):\n        super().__init__(id, name)\n        self.project = project\n        self.language = language\n\n\n    def code(self):\n        print(f\"{self.name} está programando en {self.language} en el proyecto {self.project}\")\n\n\n    def add_employee(self, employe: Employee):\n        print(\"Error, un programador no puede tener empleados a su cargo\")\n\n    \n    def print_employees(self):\n        print(\"Error, el programador no tiene empleados a su cargo\")\n\n\nmanager = Manager(1, \"Espedito\")\nproject_manager = ProjectManager(2, \"Rufino\", \"Image Scanner\")\nprogrammer = Programmer(3, \"Facundo\", \"Image Scanner\", \"Python\")\n\nmanager.add_employee(project_manager)\nmanager.add_employee(programmer)\n\nproject_manager.add_employee(programmer)\n\nmanager.coordinate_projects()\nmanager.print_employees()\n\nproject_manager.coordinate_project()\nproject_manager.print_employees()\n\nprogrammer.add_employee(manager)\nprogrammer.print_employees()\nprogrammer.code()\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/yenneralayon142.py",
    "content": "\"\"\"\nHERENCIA Y POLIMORFISMO\n\"\"\"\n\n# SuperClase\n\nclass Animal:\n\n    def __init__(self,name):\n        self.name = name\n    \n    def sound(self):\n        pass\n\n#SubClases\n\nclass Dog(Animal): # Herencia\n    def sound(self):\n        print(\"Guau\") #Polimorfismo\n        \nclass Cat(Animal):\n    def sound(self):\n        print(\"Miau\")\n    \ndef print_Sound(animal: Animal):\n    animal.sound()\n\n\nmy_Dog = Dog(\"Perro\")\nprint_Sound(my_Dog)\n\nmy_Cat = Cat(\"Gato\")\nprint_Sound(my_Cat)\n\n\n\"\"\"\nExtra\n\"\"\"\n\nclass Employees:\n\n    def __init__(self,name:str,identification:int):\n        self.name = name\n        self.identification = identification\n        self.employee = []\n\n    def add(self,employee):\n        self.employee.append(employee)\n\n    def printEmployees(self):\n        for i in self.employee:\n            print(i.name)\n\nclass Manager(Employees):\n    def manager_Coordinate(self):\n        print(f\"{self.name} maneja proyectos\")\n\nclass ProjectManager(Employees):\n\n    def __init__(self, name: str, identification: int, project:str):\n        super().__init__(name, identification)\n        self.project = project\n\n    def project_Coordinate(self):\n        print(f\"{self.name} proyecta a futro los costos\")\n\n\nclass Developers(Employees):\n    \n    def __init__(self,name:str,identification:int,language:str):\n        super().__init__(name,identification)\n        self.language = language\n\n    def programming(self):\n        print(f\"{self.name} Está programando en {self.language}\")\n\n    def add(employee:Employees):\n        print(\n            f\"Un programador no tiene empleados a su cargo{employee.name} no se añadirá\")\n\nmy_manager = Manager(\"Yenner Alayon\", 21)\nmy_projectManager_1 = ProjectManager(\"Lucas\", 22, \"Heladeria\")\nmy_projectManager_2 = ProjectManager(\"David\", 23, \"Panaderia\")\nmy_projectManager_3 = ProjectManager(\"Pedrp\", 24, \"Salchipapa\")\nmy_developer = Developers(\"Pawel Alayon\", 25, \"Kotlin\")\nmy_developer1 = Developers(\"Juan Gomez\", 26, \"Python\")\n\nmy_manager.add(my_projectManager_1)\nmy_manager.add(my_projectManager_2)\n\nmy_projectManager_3.add(my_developer)\n\nmy_developer1.programming()\nmy_projectManager_3.project_Coordinate()\nmy_manager.manager_Coordinate()\n\nmy_manager.printEmployees()\nmy_projectManager_3.printEmployees()"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/zetared92.py",
    "content": "# Reto 09 HERENCIA Y POLIMORFISMO\n\n# SUPERCLASE\n\nclass Animal:\n\n    def __init__(self, name: str):\n        self.name = name\n\n    def sound(self):\n        pass\n\n# SUBCLASES\n\nclass Dog(Animal):\n\n    def sound(self):\n        print(\"Guau!\")\n\nclass Cat(Animal):\n\n    def sound(self):\n        print(\"Miau!\")\n\n\ndef print_sound(animal: Animal):\n    animal.sound()\n\nmy_animal = Animal(\"Pet:\")\nprint_sound(my_animal)\nmy_dog = Dog(\"Dog\")\nprint_sound(my_dog)\nmy_cat = Cat(\"Cat\")\nprint_sound(my_cat)\n\n\n# Extra\n\nprint(\"🧩 DIFICULTAD EXTRA - JERARQUÍA DE EMPRESA 🧩\")\n\nclass Employee:\n\n    def __init__(self, id: int, name: str):\n        self.id = id\n        self.name = name\n        self.employees = []\n\n    def add(self, employee):\n        self.employees.append(employee)\n\n    def print_employees(self):\n        for employee in self.employees:\n            print(employee.name)\n\nclass Manager(Employee):\n\n    def coordinate_projects(self):\n        print(f\"{self.name} is coordinating the projects\")\n\nclass ProjectManager(Employee):\n\n    def __init__(self, id: int, name: str, project: str):\n        super().__init__(id, name)\n        self.project = project\n\n    def coordinate_project(self):\n        print(f\"{self.name} is supervising the projects\")\n\nclass Programmer(Employee):\n\n    def __init__(self, id: int, name: str, program: str):\n        super().__init__(id, name)\n        self.program = program\n\n    def code(self):\n        print(f\"{self.name} is programming in {self.program}\")\n\n    def add(self, employee: Employee):\n        print( f\"A programmer does not have employees under his supervision. {employee.name} not add\")\n\nmy_manager = Manager(1, \"Johnny\")\nmy_project_manager = ProjectManager(2, \"Zeta\", \"Projekt X\")\nmy_project_manager2 = ProjectManager(3, \"V\", \"Projekt Z\")\nmy_programmer = Programmer(4, \"Judy\", \"BrainDance\")\nmy_programmer2 = Programmer(5, \"Panam\", \"Neurostimulus\")\nmy_programmer3 = Programmer(6, \"Alt\", \"Soulkiller\")\nmy_programmer4 = Programmer(7, \"Rache\", \"R.A.B.I.D.S.\")\n\nmy_manager.add(my_project_manager)\nmy_manager.add(my_project_manager2)\n\nmy_project_manager.add(my_programmer)\nmy_project_manager.add(my_programmer2)\nmy_project_manager2.add(my_programmer3)\nmy_project_manager2.add(my_programmer4)\n\nmy_programmer.add(my_programmer2)\n\nmy_programmer.code()\nmy_project_manager.coordinate_project()\nmy_manager.coordinate_projects()\nmy_manager.print_employees()\nmy_project_manager.print_employees()\nmy_programmer.print_employees()"
  },
  {
    "path": "Roadmap/09 - HERENCIA/python/zonnen69.py",
    "content": "\r\n# /*\r\n#  * EJERCICIO:\r\n#  * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\r\n#  * implemente una superclase Animal y un par de subclases Perro y Gato,\r\n#  * junto con una función que sirva para imprimir el sonido que emite cada Animal.\r\n#  *\r\n#  * DIFICULTAD EXTRA (opcional):\r\n#  * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\r\n#  * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\r\n#  * Cada empleado tiene un identificador y un nombre.\r\n#  * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\r\n#  * actividad, y almacenan los empleados a su cargo.\r\n#  */\r\n\r\n\r\nclass Animal:\r\n    def __init__(self, nombre):\r\n        self.nombre = nombre\r\n\r\n    def hacer_sonido(self):\r\n        pass\r\n\r\nclass Perro(Animal):\r\n    def hacer_sonido(self):\r\n        return \"¡Guau!\"\r\n\r\nclass Gato(Animal):\r\n    def hacer_sonido(self):\r\n        return \"¡Miau!\"\r\n\r\ndef imprimir_sonido(animal):\r\n    if isinstance(animal, Animal):\r\n        print(f\"{animal.nombre} hace {animal.hacer_sonido()}\")\r\n    else:\r\n        print(\"Error: El objeto no es una instancia de Animal.\")\r\n\r\n# Ejemplo de uso\r\nmi_perro = Perro(\"Buddy\")\r\nmi_gato = Gato(\"Whiskers\")\r\n\r\nimprimir_sonido(mi_perro)  # Salida: Buddy hace ¡Guau!\r\nimprimir_sonido(mi_gato)   # Salida: Whiskers hace ¡Miau!\r\n\r\n\r\nclass Empleado:\r\n    def __init__(self, identificador, nombre):\r\n        self.identificador = identificador\r\n        self.nombre = nombre\r\n\r\n    def __str__(self):\r\n        return f\"{self.nombre} (ID: {self.identificador})\"\r\n\r\n\r\nclass Gerente(Empleado):\r\n    def __init__(self, identificador, nombre, departamento):\r\n        super().__init__(identificador, nombre)\r\n        self.departamento = departamento\r\n        self.empleados_a_cargo = []\r\n\r\n    def asignar_empleado(self, empleado):\r\n        self.empleados_a_cargo.append(empleado)\r\n\r\n    def listar_empleados(self):\r\n        print(f\"Empleados a cargo de {self.nombre}:\")\r\n        for empleado in self.empleados_a_cargo:\r\n            print(empleado)\r\n\r\n\r\nclass GerenteProyecto(Gerente):\r\n    def __init__(self, identificador, nombre, departamento, proyecto):\r\n        super().__init__(identificador, nombre, departamento)\r\n        self.proyecto = proyecto\r\n\r\n    def asignar_programador(self, programador):\r\n        self.empleados_a_cargo.append(programador)\r\n\r\n\r\nclass Programador(Empleado):\r\n    def __init__(self, identificador, nombre, lenguaje):\r\n        super().__init__(identificador, nombre)\r\n        self.lenguaje = lenguaje\r\n\r\n\r\n# Ejemplo de uso\r\nif __name__ == \"__main__\":\r\n    # Crear empleados\r\n    empleado1 = Programador(1, \"Juan\", \"Python\")\r\n    empleado2 = Programador(2, \"Maria\", \"JavaScript\")\r\n\r\n    gerente_proyecto = GerenteProyecto(3, \"Pedro\", \"Desarrollo\", \"Proyecto X\")\r\n    gerente_proyecto.asignar_empleado(empleado1)\r\n    gerente_proyecto.asignar_empleado(empleado2)\r\n\r\n    print(\"Empleados del gerente de proyecto:\")\r\n    gerente_proyecto.listar_empleados()\r\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/ruby/Elmer125.rb",
    "content": "#  * EJERCICIO:\n#  * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n#  * implemente una superclase Animal y un par de subclases Perro y Gato,\n#  * junto con una función que sirva para imprimir el sonido que emite cada Animal.\nclass Animal\n  def initialize(name)\n    @name = name\n  end\n\n  def sound\n    \"#{@name} says:\"\n  end\nend\n\n\nclass Dog < Animal\n  def sound\n    puts super + \" Woof!\"\n  end\nend\n\nclass Cat < Animal\n  def sound\n    puts super + \" Meow!\"\n  end\nend\n\nclass Pig < Animal\n  def sound\n    puts super + \" Oink!\"\n  end\nend\n\nmy_dog = Dog.new('Firulais')\nmy_dog.sound\nmy_cat = Cat.new('Garfield')\nmy_cat.sound\nmy_pig = Pig.new('Porky')\nmy_pig.sound\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n#  * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n#  * Cada empleado tiene un identificador y un nombre.\n#  * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n#  * actividad, y almacenan los empleados a su cargo.\n\nclass Employee\n  attr_accessor :id, :name\n\n  def initialize(id, name)\n    @id = id\n    @name = name\n    @employees = []\n  end\n\n  def add_employee(employee)\n    @employees << employee\n  end\n\n  def print_employees\n    puts \"Employees of #{name}\"\n    @employees.each do |employee|\n      puts \"Employee: #{employee.id} - #{employee.name}\"\n    end\n  end\nend\n\nclass Manager < Employee\n  def cordinate_project\n    puts \"#{@name} is coordinating the projects\"\n  end\nend\n\nclass ProjectManager < Employee\n  def initialize(id, name, project)\n    super(id, name)\n    @project = project\n  end\n\n  def cordinate_project\n    puts \"#{@name} is coordinating the #{@project} project\"\n  end\nend\n\nclass Programmer < Employee\n  def initialize(id, name, lenguage)\n    super(id, name)\n    @lenguage = lenguage\n  end\n\n  def write_code\n    puts \"#{@name} is writing code in #{@lenguage}\"\n  end\n\n  def add_employee(employee)\n    puts \"Programmers can't add employees #{employee.name}\"\n  end\n\n  def print_employees\n    puts \"Programmers can't have employees\"\n  end\nend\n\nmanager = Manager.new(1, 'John Doe')\nproject_manager = ProjectManager.new(4, 'Jack Doe', 'Alpha')\nprogrammer = Programmer.new(7, 'Jane Doe', 'Ruby')\nprogrammer2 = Programmer.new(8, 'Elmer Doa', 'Python')\n\nmanager.cordinate_project\nmanager.add_employee(project_manager)\n\nproject_manager.cordinate_project\nproject_manager.add_employee(programmer)\nproject_manager.add_employee(programmer2)\n\nprogrammer.write_code\nprogrammer.add_employee(programmer2)\nprogrammer2.write_code\n\nmanager.print_employees\nproject_manager.print_employees\nprogrammer.print_employees"
  },
  {
    "path": "Roadmap/09 - HERENCIA/rust/gabrielmoris.rs",
    "content": "/*\n * EXERCISE:\n * Explore the concept of inheritance in your language. Create an example that\n * implements a superclass Animal and a pair of subclasses Dog and Cat,\n * along with a function that prints the sound each Animal makes.\n */\n\n//  Rust does not have traditional inheritance like in object-oriented languages such as C++, Java, or Python.\n//  Instead, Rust uses trait objects and trait implementations to achieve polymorphism and code reuse.\n// Traits in Rust are similar to interfaces in other languages. They define a set of methods that a type must implement.\n// Types can implement multiple traits, and traits can inherit from other traits (called \"supertrait\" in Rust terminology)\ntrait Sound {\n    fn make_sound(&self) -> &str;\n}\n\nstruct Animal<T: Sound> {\n    name: String,\n    make_sound: T,\n}\n\nimpl<T: Sound> Animal<T> {\n    fn new(name: &str, make_sound: T) -> Self {\n        Animal {\n            name: name.to_string(),\n            make_sound,\n        }\n    }\n\n    fn print_sound(&self) {\n        println!(\"{} says {}\", self.name, self.make_sound.make_sound());\n    }\n}\n\nstruct Dog;\n\nimpl Sound for Dog {\n    fn make_sound(&self) -> &str {\n        \"Guau! Guau!\"\n    }\n}\n\n// Define the `Cat` struct and implement the `Sound` trait\nstruct Cat;\n\nimpl Sound for Cat {\n    fn make_sound(&self) -> &str {\n        \"Marramiau!\"\n    }\n}\n\nfn main() {\n    // EXERCISE\n    let dog = Animal::new(\"Laica\", Dog);\n    let cat = Animal::new(\"Felix\", Cat);\n    dog.print_sound(); // Prints \"Laica says Guau!\"\n    cat.print_sound(); // Prints \"Felix says Marramiau!\"\n\n    // CHALLENGE\n    let mut manager = Employee::new(\"Gabriel\", Manager, \"Manager\");\n    let mut project_manager = Employee::new(\"Jorge\", ProjectManager, \"Project_Manager\");\n    let developer_1 = Employee::new(\"Juan\", Developer, \"Frontend\");\n    let developer_2 = Employee::new(\"Julio\", Developer, \"Backend\");\n\n    project_manager.add_dev(developer_1);\n    project_manager.add_dev(developer_2);\n    project_manager.manage();\n    manager.add_pm(project_manager);\n    manager.manage();\n}\n\n/* EXTRA CHALLENGE (optional):\n * Implement the hierarchy of a development company consisting of Employees who\n * can be Managers, Project Managers, or Programmers.\n * Each employee has an identifier and a name.\n * Depending on their role, they have properties and functions exclusive to their\n * activity, and they store the employees under their supervision.\n */\n\ntrait Work {\n    fn do_work(&self) -> &str;\n}\n\nstruct Employee<T: Work> {\n    name: String,\n    identifier: String,\n    do_work: T,\n    supervise: Vec<Employee<ProjectManager>>,\n    dev_team: Vec<Employee<Developer>>,\n}\n\nimpl<T: Work> Employee<T> {\n    fn new(name: &str, do_work: T, identifier: &str) -> Self {\n        Employee {\n            name: name.to_string(),\n            identifier: identifier.to_string(),\n            do_work,\n            supervise: Vec::new(),\n            dev_team: Vec::new(),\n        }\n    }\n\n    fn show_is_working(&self) -> String {\n        self.do_work.do_work().to_string()\n    }\n\n    fn get_name(&self) -> String {\n        self.name.clone()\n    }\n\n    fn manage(&self) {\n        if self.identifier == \"Manager\" {\n            for n in &self.supervise {\n                for dev in &n.dev_team {\n                    println!(\n                        \"{} asks what is {} doing: he is helping {} {}\",\n                        self.name,\n                        n.get_name(),\n                        dev.get_name(),\n                        n.show_is_working()\n                    );\n                }\n            }\n        } else if self.identifier == \"Project_Manager\" {\n            for n in &self.dev_team {\n                println!(\n                    \"{} tries to help {} with his current task: {}\",\n                    self.name,\n                    n.get_name(),\n                    n.show_is_working()\n                );\n            }\n        }\n    }\n\n    fn add_dev(&mut self, employee: Employee<Developer>) {\n        if self.identifier == \"Project_Manager\" {\n            self.dev_team.push(employee);\n        }\n    }\n\n    fn add_pm(&mut self, employee: Employee<ProjectManager>) {\n        if self.identifier == \"Manager\" {\n            self.supervise.push(employee);\n        }\n    }\n}\n\nstruct Manager;\n\nimpl Work for Manager {\n    fn do_work(&self) -> &str {\n        \"managing\"\n    }\n}\n\nstruct Developer;\n\nimpl Work for Developer {\n    fn do_work(&self) -> &str {\n        \"drinking a coffee\"\n    }\n}\n\nstruct ProjectManager;\n\nimpl Work for ProjectManager {\n    fn do_work(&self) -> &str {\n        \"making his coffee\"\n    }\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/rust/kenysdev.rs",
    "content": "/*\n╔═══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado                ║\n║ GitHub: https://github.com/Kenysdev   ║\n║ 2024 -  Rust                          ║\n╚═══════════════════════════════════════╝\n-----------------------------------------\n* HERENCIA Y POLIMORFISMO\n-----------------------------------------\n- En Rust, no hay clases ni herencia como en lenguajes orientados a objetos tradicionales.\n- Pero se puede lograr un diseño de código que se asemeja a la herencia y el polimorfismo\n  utilizando traits y enums. \n*/\n// Simulando una \"Superclase\"\ntrait Animal {\n    fn make_sound(&self);\n}\n\n// Simulando una \"Subclases\"\nstruct Dog {\n    name: String,\n}\n\nimpl Dog {\n    fn new(name: String) -> Self {\n        Dog { name }\n    }\n}\n\nimpl Animal for Dog {\n    fn make_sound(&self) {\n        println!(\"{} hace: Woof\", self.name);\n    }\n}\n//_________\nstruct Cat {\n  name: String,\n}\n\nimpl Cat {\n    fn new(name: String) -> Self {\n        Cat { name }\n    }\n}\n\nimpl Animal for Cat {\n    fn make_sound(&self) {\n        println!(\"{} hace: Meow\", self.name);\n    }\n}\nfn main() {\n    let dog = Dog::new(\"Max\".to_string());\n    let cat = Cat::new(\"Milo\".to_string());\n\n    dog.make_sound();\n    cat.make_sound();\n\n}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/rust/w00k.rs",
    "content": "\n/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n */\n\ntrait Animal {\n    fn sound(&self) -> &str;\n}\n\nstruct Dog {\n    name: String,\n    breed_of_dog: String,\n    sound: String,\n}\nstruct Cat {\n    name: String,\n    breed_of_cat: String,\n    sound: String,\n}\n\nimpl Animal for Dog {\n    fn sound(&self) -> &str {\n        return &self.sound;\n    }\n}\n\nimpl Animal for Cat {\n    fn sound(&self) -> &str {\n        return &self.sound;\n    }\n}\n\nfn main() {\n    println!(\"Start.\");\n\n    let dog = Dog{\n        name: \"Pepe\".parse().unwrap(),\n        breed_of_dog: \"German Shepherd\".parse().unwrap(),\n        sound: \"Guau\".parse().unwrap(),\n    };\n\n    let cat = Cat{\n        name: \"Lala\".parse().unwrap(),\n        breed_of_cat: \"Domestic Shorthair\".parse().unwrap(),\n        sound: \"Miauuuuuu\".parse().unwrap(),\n    };\n\n    println!(\"type of animal: {}, name: {}, sound: {}\", dog.breed_of_dog, dog.name, dog.sound());\n    println!(\"type of animal: {}, name: {}, sound: {}\", cat.breed_of_cat, cat.name, cat.sound());\n\n    println!(\"End.\");\n}\n\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/sql/Nicojsuarez2.sql",
    "content": "# #09 HERENCIA Y POLIMORFISMO\n> #### Dificultad: Media | Publicación: 26/02/24 | Corrección: 04/03/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/swift/PineroDev.swift",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n\nimport Foundation\n\nclass Animal {\n    var nombre: String\n    \n    init(nombre: String) {\n        self.nombre = nombre\n    }\n    \n    func sonido() -> String {\n        return \"ummmmm\"\n    }\n}\n\nclass Perro: Animal {\n    override func sonido() -> String {\n        return \"guauuuuu\"\n    }\n}\n\nclass Gato: Animal {\n    override func sonido() -> String {\n        return \"miauuuuuu\"\n    }\n}\n\n//func print_sound(animal: Animal) {\n//    animal.sonido()\n//}\n\nlet jacinto = Gato(nombre: \"Jacinto\")\nprint(\"\\(jacinto.nombre) es un animal que hace el sonido \\(jacinto.sonido())\")\n//print_sound(animal: jacinto)\nlet toby = Perro(nombre: \"Toby\")\nprint(\"\\(toby.nombre) es un animal que hace el sonido \\(toby.sonido())\")\n//print_sound(animal: toby)\n\n\n//---------------\n// Extra\n//---------------\n\nclass Employee {\n    var id: Int\n    var nombre: String\n    var employees: [Employee]\n    \n    init(id: Int, nombre: String) {\n        self.id = id\n        self.nombre = nombre\n        self.employees = []\n    }\n    \n    func add(employee:Employee){\n        self.employees.append(employee)\n    }\n    \n    func printEmployees(){\n        print(\"Empleados de \\(self.nombre):\")\n        for employee in self.employees {\n            print(employee.nombre)\n        }\n    }\n}\n\nclass Manager: Employee {\n    \n    func coordinateProjects(){\n        print(\"El manager \\(self.nombre) coordina todos los proyectos.\" )\n    }\n}\n    \nclass ProjectManager: Employee {\n        \n    var project: String\n        \n    init(id: Int, nombre: String, project: String) {\n            self.project = project\n            super.init(id: id, nombre: nombre)\n    }\n    \n    func coordinateProject(){\n        print(\"El project manager \\(self.nombre) coordina el proyecto \\(self.project).\")\n    }\n}\n\n    \nclass Programmer: Employee {\n    var language: String\n        \n    init(id: Int, nombre: String, language: String) {\n            self.language = language\n            super.init(id: id, nombre: nombre)\n    }\n        \n        \n    func code(){\n            print(\"El programador \\(self.nombre) esta programando en \\(language).\")\n    }\n    \n    override func add(employee: Employee) {\n        let name = employee.nombre\n        print(\"El programador no puede tener nadie a cargo. \\(name) no se añadio.\")\n    }\n}\n\nvar my_manager = Manager(id: 1, nombre: \"Pepe\")\nvar my_project_manager = ProjectManager(id: 2, nombre: \"Paco\", project: \"Proyecto 1\")\nvar my_project_manager2 = ProjectManager(id: 3, nombre: \"Juan\", project: \"Proyecto 2\")\nvar my_programmer = Programmer(id: 4, nombre: \"Luis\", language: \"Swift\")\nvar my_programmer2 = Programmer(id: 5, nombre: \"Marcos\", language: \"Java\")\nvar my_programmer3 = Programmer(id: 6, nombre: \"Andrés\", language: \"C++\")\nvar my_programmer4 = Programmer(id: 7, nombre: \"Ricardo\", language: \"Python\")\n\nmy_manager.add(employee: my_project_manager)\nmy_manager.add(employee: my_project_manager2)\n\nmy_project_manager.add(employee: my_programmer)\nmy_project_manager2.add(employee: my_programmer2)\nmy_project_manager2.add(employee: my_programmer3)\nmy_project_manager.add(employee: my_programmer4)\n\nmy_programmer.add(employee: my_programmer2)\n\nmy_programmer.code()\nmy_project_manager.coordinateProject()\nmy_manager.coordinateProjects()\n\nmy_project_manager.printEmployees()\nmy_manager.printEmployees()\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/swift/allbertoMD.swift",
    "content": "import Foundation\n\n\n// Declaración de la calse Animal().\nclass Animal {\n    var breed = \"\" // Propiedas raza.\n}\n\n// Declaración de la clase Cat()\nclass Cat: Animal {\n    var name: String // Propiedad nombre.\n    let sex: String // Propiedad sexo.\n\n    // Definición del inicializar de la clase Cat().\n    init(name: String, sex: String) {\n        self.name = name\n        self.sex = sex\n    }\n\n    // Definición del metodo sonido del gato\n    func catSound() {\n        if sex == \"macho\" { // Si es macho se imprime El gato.\n            print(\"El gato \\(name) hace: MIIAAAAU\")\n        } else if sex == \"hembra\" { // Si es hembra se imprime La gata.\n            print(\"la gata \\(name) hace: MIIAAAAU\")\n        } else { // Sin no se introduce macho o hembra se imprime sexo no valido.\n            print(\"Sexo del gato no valido. escribe hembra, o macho\")\n        }\n    }\n}\n\nprint(\"El Gato\")\n// Creacion del objeto myCat de la classe Cat().\nvar myCat = Cat(name: \"Icee\", sex: \"hembra\")\nmyCat.breed = \"Gato\" // Raza del animal.\nmyCat.catSound() // Llamada al metodo sonido de gato.\n\n\n// Declaración de la clase Dog().\nclass Dog:Animal {\n    var name: String // Propiedas nomber.\n    let sex: String // Propiedad sexo.\n\n    // Definición del inicializador de la clase Dog().\n    init(name: String, sex: String) {\n        self.name = name\n        self.sex = sex\n    }\n\n    // Definición del metodo sonido del perro.\n    func dogSound() {\n        if sex == \"macho\" { // Si el sexo es macho imprime El perro.\n            print(\"El perro \\(name) hace: GUAUU\")\n        } else if sex == \"hembra\" { // Si el sexo es hembra imprime La perra.\n            print(\"La perra \\(name) hace: GUAUU\")\n        } else { // Sin no se introduce macho o hembra se imprime sexo no valido.\n            print(\"Sexo del gato no valido. escribe hembra, o macho\")\n        }\n    }\n}\n\nprint(\"\\nEl Perro\")\n// Creación del objeto myDog de la clase Dog().\nvar myDog = Dog(name: \"Parche\", sex: \"macho\")\nmyDog.breed = \"Perro\" // Raza del animal.\nmyDog.dogSound() // Llama al metodo sonido del perro.\n\n\n\n\n\n// DIFICULTAS EXTRA\n\n\n// Creacion de la clase Employee()\nclass Employee {\n    let id: String // Propiedd ID.\n    var name: String // Propiedad nombre.\n    var job: String // Propiedad puesto de trabajo.\n\n    var information: String { // Propiedad computada con la información de usuario.\n        return \"ID: \\(id)\\nEompleado: \\(name)\\nPuesto de trabajo: \\(job)\"\n    }\n\n    // Inicializador de la clase Employee().\n    init(id: String = UUID().uuidString, name: String, job: String) {\n        self.id = id\n        self.name = name\n        self.job = job\n    }\n}\n\n\n\n// Definición de la clase Developer() que hereda de la super clase Employee().\nclass Developer: Employee {\n    var language: String // Propieda lenguaje de programación.\n    var frontend: Bool // Propiedad si es frontend.\n    var backend: Bool // Propiedad si es backend.\n    var code: String = \"\"\n\n    // Inicializador de la clase Developer() y de la super clase Empoyee().\n    init(id: String = UUID().uuidString, name: String, job: String, language: String, frontend: Bool, backend: Bool) {\n        self.language = language\n        self.frontend = frontend\n        self.backend = backend\n        super.init(id: id, name: name, job: job) // Inicializador de la super clase\n    }\n\n    // Definición del metodo escribir codigo.\n    func typingCode(_ code: String, of userName: String) {\n        print(\"Este es el codigo de \\(userName)\")\n        self.code = code\n        print(code)\n    }\n}\n\n\n\n// Declaración de la clase Manager() que hereda de la super clase Employee().\nclass Manager: Employee {\n    var scheduleMeeting: Bool // Propiedas si creo una reunión.\n\n    // Inicializador de la clase Manager() y de la super clase Employee().\n    init(id: String = UUID().uuidString, name: String, job: String, scheduleMeeting: Bool = false) {\n        self.scheduleMeeting = scheduleMeeting\n        super.init(id: id, name: name, job: job) // Inicializador de la super clase.\n    }\n\n    // Definición del metodo crear una reunion.\n    func makeScheduleMeeting(with members: [(String, String)], week day: String, hour: String) {\n        print(\"La reunion es el \\(day) a las \\(hour) y los mienbros son:\")\n\n        for (person, job) in members {\n            print(\"\\(person) ---- \\(job)\")\n        }\n        scheduleMeeting = true\n    }\n}\n\n\n\n// Declariación de la clase ProyectManager() que  hereda de la super clase Manager().\nclass ProyectManager: Manager {\n    var product: String // Propiedad nombre del proyecto.\n    var numberOfDevelopers: Int // Propiedad numero de desarrolladores.\n    var verifiedCode: Bool // Propiedad si ha verificado el codigo.\n    var developersGroup: [String] = [] // Propiedad de los nombres de los desarrolladores.\n\n    override var information: String { // Propiedad que sobre escribe la propiedad de la super clase Employee().\n        return \"Proyecto: \\(product)\\nGerente: \\(name)\\nNumero de developers: \\(numberOfDevelopers)\"\n    }\n\n    // Definición del inicializador de la clase ProyectManager() y de las super clasees Manger() y Employee().\n    init(id: String = UUID().uuidString, name: String, job: String, scheduleMeeting: Bool = false, product: String, numberOdDevelopers: Int = 0, verifiedCode: Bool = false) {\n        self.product = product\n        self.numberOfDevelopers = numberOdDevelopers\n        self.verifiedCode = verifiedCode\n        super.init(id: id, name: name, job: job, scheduleMeeting: scheduleMeeting) // Inicializador de las super clases.\n    }\n\n    // Definición del metodo añadir desarrollador al proyecto.\n    func addDeveloperToProyect(developer name: String) {\n        developersGroup.append(name)\n        numberOfDevelopers = developersGroup.count\n    }\n}\n\nprint(\"\\nInformación de los desarrolladores.\")\n// Creación de los objetos desarrolladores de la clase Developer().\nvar developer1 = Developer(name: \"Miguel\", job: \"Desarrollador\", language: \"Swift\", frontend: true, backend: false)\nprint(developer1.information)\nvar developer2: Developer = Developer(name: \"Sara\", job: \"Desarrollador\", language: \"Swift\", frontend: true, backend: false)\nprint(developer2.information)\nvar developer3: Developer = Developer(name: \"Raquel\", job: \"Desarrollador\", language: \"Swift\", frontend: false, backend: true)\nprint(developer3.information)\nvar developer4: Developer = Developer(name: \"Carlos\", job: \"Desarrollador\", language: \"Swift\", frontend: false, backend: true)\nprint(developer4.information)\n\n// Creación del objeto gerente de proyecto de la clase ProyectManager().\nvar proyectManager1: ProyectManager = ProyectManager(name: \"Alexa\", job: \"Gerente de Proyecto\", product: \"Semafor App\")\n\n// Creación del objeto manager de la clase Manager().\nvar manager: Manager = Manager(name: \"John\", job: \"Gerente\")\n\n// Lamadas al metod añadir desarrolladores al proyecto.\nproyectManager1.addDeveloperToProyect(developer: developer1.name)\nproyectManager1.addDeveloperToProyect(developer: developer2.name)\nproyectManager1.addDeveloperToProyect(developer: developer3.name)\nproyectManager1.addDeveloperToProyect(developer: developer4.name)\n\nprint(\"\\nInformación de un producto.\")\n// Imprimir la información del proyecto haciendo uso de la propiedad information de la clase ProyectManager().\nprint(proyectManager1.information)\n\nprint(\"\\nCreación y mostrar información de la reunión\")\n// Llamada al metodo crear una reunión de la clase Manager().\nmanager.makeScheduleMeeting(with: [(proyectManager1.name, proyectManager1.job),\n(developer1.name, developer1.job),\n(developer4.name, developer4.job)], week: \"Martes\", hour: \"10:00 am\")"
  },
  {
    "path": "Roadmap/09 - HERENCIA/swift/blackriper.swift",
    "content": "/* la herencia nos permite crear clases que hereden propiedades y métodos de otras clases\n   en swift solo se puede utilizar herencia con las classes no con structs\n */\n\nclass Animal{\n    var name: String\n    init(nam: String) {\n        self.name = nam\n    }\n    func emitSound(){\n         print(\"the animal  \\(name) makes a sound\")\n         \n    }\n  }\n\n\nclass Dog: Animal{\n    var race: String\n    init(rac: String, name: String) {\n        self.race = rac\n        super.init(nam: name)\n    }\n    override func emitSound() {\n        print(\"the dog \\(name) makes guau\")\n    }\n}\n\nclass Cat: Animal{\n    var race: String\n    init(rac: String, name: String) {\n        self.race = rac\n        super.init(nam: name)\n    }\n    override func emitSound() {\n        print(\"the cat \\(name) makes miau\")\n    }\n}\n\nlet dog=Dog(rac: \"labrador\", name: \"Nala\")\nlet cat=Cat(rac: \"persa\", name: \"ONYX\")\ndog.emitSound()\ncat.emitSound()\n\n//ejercicio extra\n\nenum Role{\n     case manager\n     case proyect_manager\n     case developer\n}\n\nstruct Proyect{\n    var name: String  \n    var developerList: [Developer]\n}\n\n\nclass Employee {\n    var id: Int\n    var name: String\n    var role: Role\n    init(id: Int, name: String, role: Role) {\n        self.id = id\n        self.name = name\n        self.role = role\n    }\n}\n\nclass Developer:Employee{\n    private let language: String\n     init(id: Int, name: String, role: Role, language: String) {\n         self.language = language\n         super.init(id: id, name: name, role: role)\n     }\n    func work(){\n        print(\"My name is \\(name) and working on a project using \\(language)\")        \n    } \n}\n\nclass ProyectManager:Employee{\n    private var projectList: [Proyect]\n    init(id: Int, name: String, role: Role, projectList: [Proyect]) {\n        self.projectList = projectList\n        super.init(id: id, name: name, role: role)\n    }\n    func activeProject(){\n        for project in projectList{\n            print(\"Project name: \\(project.name) Developer list: \\(project.developerList)\")\n        }\n    }\n}\n\nclass Manager:Employee{\n   private var teamList: [ProyectManager]\n    init(id: Int, name: String, role: Role, teamList: [ProyectManager]) {\n        self.teamList = teamList\n        super.init(id: id, name: name, role: role)\n    }\n    \n    func greet(){\n        print(\"Hello, my name is \\(name)  I'm a \\(role)\")\n    }\n\n    func activeTeam(){\n        for team in teamList{\n            print(\"Team name: \\(team.name) \")\n        }\n    }\n}\n\n\nlet dev1=Developer(id: 1, name: \"kontroldev\", role: .developer, language: \"Swift\")\nlet dev2=Developer(id: 2, name: \"pguillo02\", role: .developer, language: \"Java\")\nlet dev3=Developer(id: 3, name: \"thegera4\", role: .developer, language: \"Go\")\ndev1.work()\ndev2.work()\ndev3.work()\n\nlet proyect1=Proyect(name: \"App IOS\", developerList: [dev1])\nlet proyect2=Proyect(name: \"App Swing\", developerList: [ dev2])\nlet proyect3=Proyect(name: \"Backend\", developerList: [dev3])\n\nlet team1=ProyectManager(id: 1, name: \"roswell\", role: .proyect_manager, projectList: [proyect1,proyect2])\nlet team2=ProyectManager(id: 2, name: \"blackriper\", role: .proyect_manager, projectList: [proyect3])\nteam1.activeProject()\nteam2.activeProject()\n\nlet manager1=Manager(id: 1, name: \"mouredev\", role: .manager, teamList: [team1,team2])\nmanager1.greet()\nmanager1.activeTeam()\n\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/swift/didacdev.swift",
    "content": "import Foundation\n\nclass Empleado {\n    let identificador: UUID = UUID()\n    var nombre: String\n\n    init(nombre: String) {\n        self.nombre = nombre\n    }\n\n    func getIdentificador() -> UUID {\n        return identificador\n    }\n\n    func getNombre() -> String {\n        return nombre\n    }\n}\n\nclass Gerente: Empleado {\n    var gerentesDeProyectos: [GerentesDeProyectos]\n\n    init(nombre: String, gerentesDeProyectos: [GerentesDeProyectos] = []) {\n        self.gerentesDeProyectos = gerentesDeProyectos\n        super.init(nombre: nombre)\n    }\n\n    func getGerentesDeProyectos() -> [GerentesDeProyectos] {\n        return gerentesDeProyectos\n    }\n\n    func addGerenteDeProyecto(gerenteDeProyecto: GerentesDeProyectos) {\n        gerentesDeProyectos.append(gerenteDeProyecto)\n    }\n}\n\nclass GerentesDeProyectos: Empleado {\n    var programadores: [Programador] \n\n    init(nombre: String, programadores: [Programador] = []) {\n        self.programadores = programadores\n        super.init(nombre: nombre)\n    }\n\n    func getProgramadores() -> [Programador] {\n        return programadores\n    }\n\n    func addProgramador(programador: Programador) {\n        programadores.append(programador)\n    }\n}\n\nclass Programador: Empleado {\n    var lenguajes: [String]\n\n    init(nombre: String, lenguajes: [String]) {\n        self.lenguajes = lenguajes\n        super.init(nombre: nombre)\n    }\n\n    func getLenguajes() -> [String] {\n        return lenguajes\n    }\n\n    func addLenguaje(lenguaje: String) {\n        lenguajes.append(lenguaje)\n    }\n}\n\n\nvar gerente = Gerente(nombre: \"Paco\")\nvar gerenteDeProyectos1 = GerentesDeProyectos(nombre: \"Pedro\")\nvar gerenteDeProyectos2 = GerentesDeProyectos(nombre: \"Ana\")\nvar programador1: Programador = .init(nombre: \"Sandra\", lenguajes: [\"Swift\", \"Java\"])\nvar programador2: Programador = .init(nombre: \"Julian\", lenguajes: [\"Kotlin\"])\nvar programador3: Programador = .init(nombre: \"Jose\", lenguajes: [\"Python\", \"CSS\"])\nvar programador4: Programador = .init(nombre: \"Lisa\", lenguajes: [\"HTML\", \"C\"])\n\ngerenteDeProyectos1.addProgramador(programador: programador1)\ngerenteDeProyectos1.addProgramador(programador: programador2)\ngerenteDeProyectos1.addProgramador(programador: programador3)\ngerenteDeProyectos2.addProgramador(programador: programador4)\n\ngerente.addGerenteDeProyecto(gerenteDeProyecto: gerenteDeProyectos1)\ngerente.addGerenteDeProyecto(gerenteDeProyecto: gerenteDeProyectos2)\n\nprint(\"\\(programador1.getNombre()) sabe programar \\(programador1.getLenguajes())\")\nprint(\"\\(programador2.getNombre()) sabe programar \\(programador2.getLenguajes())\")\nprint(\"\\(programador3.getNombre()) sabe programar \\(programador3.getLenguajes())\")\nprint(\"\\(programador4.getNombre()) sabe programar \\(programador4.getLenguajes())\")   \n\nprint(\"\\(gerenteDeProyectos1.getNombre()) está a cargo de:\")\nfor programador in gerenteDeProyectos1.getProgramadores() {\n    print(programador.getNombre())\n}\nprint(\"\\(gerenteDeProyectos2.getNombre()) está a cargo de:\")\nfor programador in gerenteDeProyectos2.getProgramadores() {\n    print(programador.getNombre())\n}\nprint(\"\\(gerente.getNombre()) manda sobre:\")\nfor gerenteDeProyecto in gerente.getGerentesDeProyectos() {\n    print(gerenteDeProyecto.getNombre())\n}"
  },
  {
    "path": "Roadmap/09 - HERENCIA/swift/gliadev.swift",
    "content": "import Foundation\n\n/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n */\n\n// Superclase Animal\nclass Animal {\n    var nombre: String\n\n    init(nombre: String) {\n        self.nombre = nombre\n    }\n\n    func emitirSonido() -> String {\n        return \"Este animal hace un sonido\"\n    }\n}\n\n// Subclase Perro\nclass Perro: Animal {\n    override func emitirSonido() -> String {\n        return \"Guau\"\n    }\n}\n\n// Subclase Gato\nclass Gato: Animal {\n    override func emitirSonido() -> String {\n        return \"Miau\"\n    }\n}\n\n// Función para imprimir el sonido de un animal\nfunc imprimirSonidoDe(animal: Animal) {\n    print(\"\\(animal.nombre) dice: \\(animal.emitirSonido())\")\n}\n\n// Uso de las clases\nlet miPerro = Perro(nombre: \"Rex\")\nlet miGato = Gato(nombre: \"Whiskers\")\n\nimprimirSonidoDe(animal: miPerro)\nimprimirSonidoDe(animal: miGato)\n\n\n/* DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n\n\n// Clase base Empleado\nclass Empleado {\n    var id: Int\n    var nombre: String\n\n    init(id: Int, nombre: String) {\n        self.id = id\n        self.nombre = nombre\n    }\n\n    func describir() -> String {\n        return \"\\(nombre) (ID: \\(id))\"\n    }\n}\n\n// Subclase Gerente\nclass Gerente: Empleado {\n    var empleadosACargo: [Empleado] = []\n\n    func agregarEmpleado(empleado: Empleado) {\n        empleadosACargo.append(empleado)\n    }\n\n    override func describir() -> String {\n        return super.describir() + \". Gerente con \\(empleadosACargo.count) empleados a cargo.\"\n    }\n}\n\n// Subclase Gerente de Proyectos\nclass GerenteDeProyectos: Gerente {\n    var proyectos: [String] = []\n\n    func agregarProyecto(proyecto: String) {\n        proyectos.append(proyecto)\n    }\n\n    override func describir() -> String {\n        return super.describir() + \" Encargado de los proyectos: \\(proyectos.joined(separator: \", \")).\"\n    }\n}\n\n// Subclase Programador\nclass Programador: Empleado {\n    var lenguajes: [String]\n\n    init(id: Int, nombre: String, lenguajes: [String]) {\n        self.lenguajes = lenguajes\n        super.init(id: id, nombre: nombre)\n    }\n\n    override func describir() -> String {\n        return super.describir() + \". Programador especializado en: \\(lenguajes.joined(separator: \", \")).\"\n    }\n}\n\n// Instancias específicas según el requerimiento\nlet mouredev = Gerente(id: 1, nombre: \"Mouredev\")\nlet gerenteProyectos = GerenteDeProyectos(id: 2, nombre: \"Mouredev\")\nlet gliaDEV = Programador(id: 4, nombre: \"gliaDEV\", lenguajes: [\"Swift\",\"SwiftUI\", \"Objective-C\", \"Kotlin\"])\n\n// Configuración de la jerarquía\nmouredev.agregarEmpleado(empleado: gerenteProyectos)\nmouredev.agregarEmpleado(empleado: gliaDEV)\ngerenteProyectos.agregarProyecto(proyecto: \"Revolución Móvil 2024\")\n\n// Imprimiendo descripciones\nprint(mouredev.describir())\n\n\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/swift/juanppdev.swift",
    "content": "/*\n    Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n */\n\n// Definición de la clase Animal\nclass Animal {\n    var nombre: String\n    \n    init(nombre: String) {\n        self.nombre = nombre\n    }\n    \n    func hacerSonido() {\n        // Método por defecto que no hace nada en la clase base\n    }\n}\n\n// Definición de la subclase Perro\nclass Perro: Animal {\n    override func hacerSonido() {\n        print(\"\\(nombre) dice: ¡Guau!\")\n    }\n}\n\n// Definición de la subclase Gato\nclass Gato: Animal {\n    override func hacerSonido() {\n        print(\"\\(nombre) dice: ¡Miau!\")\n    }\n}\n\n// Función para imprimir el sonido de un Animal\nfunc imprimirSonido(animal: Animal) {\n    animal.hacerSonido()\n}\n\n// Ejemplo de uso\nlet miPerro = Perro(nombre: \"Buddy\")\nlet miGato = Gato(nombre: \"Whiskers\")\n\nimprimirSonido(animal: miPerro) // Salida: Buddy dice: ¡Guau!\nimprimirSonido(animal: miGato)  // Salida: Whiskers dice: ¡Miau!\n\n\n\n/*\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n*/\n\n// Clase base Empleado\nclass Empleado {\n    var identificador: Int\n    var nombre: String\n    \n    init(identificador: Int, nombre: String) {\n        self.identificador = identificador\n        self.nombre = nombre\n    }\n    \n    func trabajar() {\n        // Método por defecto que no hace nada en la clase base\n    }\n}\n\n// Clase Gerente, subclase de Empleado\nclass Gerente: Empleado {\n    var departamento: String\n    var empleadosACargo: [Empleado]\n    \n    init(identificador: Int, nombre: String, departamento: String) {\n        self.departamento = departamento\n        self.empleadosACargo = []\n        super.init(identificador: identificador, nombre: nombre)\n    }\n    \n    func asignarEmpleado(empleado: Empleado) {\n        empleadosACargo.append(empleado)\n    }\n    \n    override func trabajar() {\n        print(\"\\(nombre) está supervisando el departamento \\(departamento)\")\n    }\n}\n\n// Clase GerenteProyecto, subclase de Gerente\nclass GerenteProyecto: Gerente {\n    var proyecto: String\n    \n    init(identificador: Int, nombre: String, departamento: String, proyecto: String) {\n        self.proyecto = proyecto\n        super.init(identificador: identificador, nombre: nombre, departamento: departamento)\n    }\n    \n    override func trabajar() {\n        print(\"\\(nombre) está supervisando el proyecto \\(proyecto)\")\n    }\n}\n\n// Clase Programador, subclase de Empleado\nclass Programador: Empleado {\n    var lenguaje: String\n    \n    init(identificador: Int, nombre: String, lenguaje: String) {\n        self.lenguaje = lenguaje\n        super.init(identificador: identificador, nombre: nombre)\n    }\n    \n    override func trabajar() {\n        print(\"\\(nombre) está programando en \\(lenguaje)\")\n    }\n}\n\n// Ejemplo de uso\nlet gerente = Gerente(identificador: 1, nombre: \"Juan\", departamento: \"Desarrollo\")\nlet gerenteProyecto = GerenteProyecto(identificador: 2, nombre: \"Maria\", departamento: \"Desarrollo\", proyecto: \"Sistema de Gestión\")\nlet programador1 = Programador(identificador: 3, nombre: \"Pedro\", lenguaje: \"Python\")\nlet programador2 = Programador(identificador: 4, nombre: \"Ana\", lenguaje: \"JavaScript\")\n\ngerente.asignarEmpleado(empleado: programador1)\ngerente.asignarEmpleado(empleado: programador2)\n\ngerente.trabajar()\nfor empleado in gerente.empleadosACargo {\n    empleado.trabajar()\n}\n\ngerenteProyecto.trabajar()\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/swift/karys4.swift",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n */\n\nclass Animal {\n    func sonidoAnimalGeneral() {\n        print(\"Sonido General\")\n    }\n}\n\nclass Perro: Animal {\n    func sonidoPerro() {\n        print(\"Guau guau\")\n    }\n}\n\nclass Gato: Animal {\n    func sonidoGato() {\n        print(\"Miau miau\")\n    }\n}\n\nvar perrito = Perro()\nperrito.sonidoAnimalGeneral()\nperrito.sonidoPerro()\n\nvar gatito = Gato()\ngatito.sonidoAnimalGeneral()\ngatito.sonidoGato()\n\n\n/* DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n\nclass Empleado {\n    var id: Int\n    var nombre: String\n    \n    init(id: Int, nombre: String) {\n        self.id = id\n        self.nombre = nombre\n    }\n    \n    func diversasActividades() {\n        print(\"Soy un empleado y puedo realizar actividades diversas\")\n    }\n    \n}\n\nclass Gerente: Empleado {\n    \n    func mandar() {\n        print(\"Soy un gerente y doy instrucciones a empleados\")\n    }\n}\n\nclass GerenteProyecto: Empleado {\n    \n    func darInstrucciones() {\n        print(\"Soy un gerente, especializado en proyectos\")\n    }\n}\n\nclass Programador: Empleado {\n    var lenguaje: String\n    \n        init(id: Int, nombre: String, lenguaje: String) {\n        self.lenguaje = lenguaje\n        super.init(id: id, nombre: nombre)\n    }\n\n    func programar() {\n        print(\"Soy una programadora y haré magia escribiendo código en \\(lenguaje).\")\n    }\n}\n\nvar kary = Programador(id: 1, nombre: \"Karys\", lenguaje: \"Swift\")\nkary.programar()\n\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/swift/kontroldev.swift",
    "content": "import Foundation\n\n/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n\n// Definición de la clase Animal\n// Definición de un protocolo Animal\nprotocol Animal {\n    var nombre: String { get }\n    func hacerSonido()\n}\n\n// Implementación por defecto del protocolo Animal\nextension Animal {\n    func hacerSonido() {\n        print(\"El \\(nombre) hace un sonido.\")\n    }\n}\n\n// Definición de la clase Perro que conforma al protocolo Animal\nclass Perra: Animal {\n    var nombre: String\n    \n    init(nombre: String) {\n        self.nombre = nombre\n    }\n    \n    func hacerSonido() {\n        print(\"La perra \\(nombre) hace guau.\")\n    }\n}\n\n// Definición de la clase Gato que conforma al protocolo Animal\nclass Gato: Animal {\n    var nombre: String\n    \n    init(nombre: String) {\n        self.nombre = nombre\n    }\n    \n    func hacerSonido() {\n        print(\"El gato \\(nombre) hace miau.\")\n    }\n}\n\n// Ejemplo de uso\nlet miPerro = Perra(nombre: \"NALA\")\nlet miGato = Gato(nombre: \"ONYX\")\n\nmiPerro.hacerSonido() // Salida: El perro NALA hace guau.\nmiGato.hacerSonido() // Salida: El gato ONYX hace miau.\n\n\n\n// MARK: - DIFICULTAD EXTRA (opcional):\n// Definición del protocolo Empleado\nclass Employee {\n    var id: Int\n    var name: String\n    var employees: [Employee]\n    \n    init(id: Int, name: String) {\n        self.id = id\n        self.name = name\n        self.employees = []\n    }\n    \n    func add(employee: Employee) {\n        self.employees.append(employee)\n    }\n    \n    func printEmployees() {\n        for employee in self.employees {\n            print(employee.name)\n        }\n    }\n}\n\nclass Manager: Employee {\n    func coordinateProjects() {\n        print(\"\\(self.name) está coordinando todos los proyectos de la empresa.\")\n    }\n}\n\nclass ProjectManager: Employee {\n    var project: String\n    \n    init(id: Int, name: String, project: String) {\n        self.project = project\n        super.init(id: id, name: name)\n    }\n    \n    func coordinateProject() {\n        print(\"\\(self.name) está coordinando su proyecto.\")\n    }\n}\n\nclass Programmer: Employee {\n    var language: String\n    \n    init(id: Int, name: String, language: String) {\n        self.language = language\n        super.init(id: id, name: name)\n    }\n    \n    func code() {\n        print(\"\\(self.name) está programando en \\(self.language).\")\n    }\n    \n    override func add(employee: Employee) {\n        print(\"Un programador no tiene empleados a su cargo. \\(employee.name) no se añadirá.\")\n    }\n}\n\nlet myManager = Manager(id: 1, name: \"MoureDev\")\nlet myProjectManager = ProjectManager(id: 2, name: \"Brais\", project: \"Proyecto 1\")\nlet myProjectManager2 = ProjectManager(id: 3, name: \"Moure\", project: \"Proyecto 2\")\nlet myProgrammer = Programmer(id: 4, name: \"Kontrol\", language: \"Swift\")\nlet myProgrammer2 = Programmer(id: 5, name: \"Roswell\", language: \"Cobol\")\nlet myProgrammer3 = Programmer(id: 6, name: \"Bushi\", language: \"klotin 😜\")\nlet myProgrammer4 = Programmer(id: 7, name: \"lordzzz\", language: \"Python\")\n\nmyManager.add(employee: myProjectManager)\nmyManager.add(employee: myProjectManager2)\n\nmyProjectManager.add(employee: myProgrammer)\nmyProjectManager.add(employee: myProgrammer2)\nmyProjectManager2.add(employee: myProgrammer3)\nmyProjectManager2.add(employee: myProgrammer4)\n\nmyProgrammer.add(employee: myProgrammer2)\n\nmyProgrammer.code()\nmyProjectManager.coordinateProject()\nmyManager.coordinateProjects()\nmyManager.printEmployees()\nmyProjectManager.printEmployees()\nmyProgrammer.printEmployees()\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/swift/lordzzz777.swift",
    "content": "/*\n * 09, EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n */\n\nclass Animal {\n    \n    var patas: Int\n    var boca: Int\n    var reproduccion: String\n    var clase: String\n    var genero: String\n    var comer: String\n    var pelaje: String\n    var nombre: String\n    \n    init(patas: Int, boca: Int, reproduccion: String, clase: String, genero: String, comer: String, pelaje: String, nombre: String) {\n        self.patas = patas\n        self.boca = boca\n        self.reproduccion = reproduccion\n        self.clase = clase\n        self.genero = genero\n        self.comer = comer\n        self.pelaje = pelaje\n        self.nombre = nombre\n    }\n    \n    func nacer(_ formaNacer: String) -> String {\n        return \"Los animales de la clase \\(clase) nacen \\(formaNacer)\"\n    }\n    \n    func comer(_ alimento: String) -> String {\n        return \"Los animales de la clase \\(clase) comen \\(alimento)\"\n    }\n    \n    func duermen(_ formaDe: String) -> String {\n        return \"Los animales de la clase \\(clase) duermen \\(formaDe)\"\n    }\n    \n    func reproducen(_ especie: String) -> String {\n        return \"Los animales de la clase \\(clase) se reproducen mediante \\(reproduccion)\"\n    }\n}\n\nclass Perro: Animal {\n    \n    var sonido: String\n    \n    init(sonido: String, comer: String, pelaje: String, nombre: String) {\n        self.sonido = sonido\n        super.init(patas: 4, boca: 1, reproduccion: \"viviparo\", clase: \"canido\", genero: \"mamifero\", comer: comer, pelaje: pelaje, nombre: nombre)\n    }\n    \n    func emiteSonido() -> String {\n        return \"Mi perro se llama \\(nombre), al detectar ruido \\(sonido)\"\n    }\n}\n\nclass Gato: Animal {\n    \n    var sonido: String\n    \n    init(sonido: String, comer: String, pelaje: String, nombre: String) {\n        self.sonido = sonido\n        super.init(patas: 4, boca: 1, reproduccion: \"viviparo\", clase: \"felino\", genero: \"mamifero\", comer: comer, pelaje: pelaje, nombre: nombre)\n    }\n    \n    func emiteSonido() -> String {\n        return \"Mi gato se llama \\(nombre), y cuando tiene hambre \\(sonido)\"\n    }\n}\n\n// Instanciación de un perro\nlet miPerro = Perro(sonido: \"ladrido\", comer: \"croquetas\", pelaje: \"corto\", nombre: \"Fido\")\n\n// Acceso a propiedades y métodos del perro\nprint(\"Mi perro tiene \\(miPerro.patas) patas y \\(miPerro.boca) boca.\")\nprint(miPerro.nacer(\"de una madre perro\"))\nprint(miPerro.comer(\"huesos\"))\nprint(miPerro.duermen(\"en su cama\"))\nprint(miPerro.emiteSonido())\n\n// Instanciación de un gato\nlet miGato = Gato(sonido: \"maullido\", comer: \"pescado\", pelaje: \"largo\", nombre: \"Misi\")\n\n// Acceso a propiedades y métodos del gato\nprint(\"Mi gato tiene \\(miGato.patas) patas y \\(miGato.boca) boca.\")\nprint(miGato.nacer(\"de una madre gato\"))\nprint(miGato.comer(\"atún\"))\nprint(miGato.duermen(\"en una caja\"))\nprint(miGato.emiteSonido())\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n \n\nclass Empleado {\n    var id: Int\n    var nombre: String\n    \n    init(id: Int, nombre: String) {\n        self.id = id\n        self.nombre = nombre\n    }\n    \n    func trabaja() -> String {\n        return \"\\(nombre) está trabajando\"\n    }\n}\n\nclass Gerente: Empleado {\n    var equipo: [Empleado]\n    init(id:Int,nombre: String, equipo: [Empleado]) {\n        self.equipo = equipo\n        super.init(id: Int, nombre: String)\n    }\n    \n    func asignarTrabajo() -> String{\n        return \"El gerente \\(nombre), está asignando trabajo a su equipo\"\n    }\n}\n\nclass JefeProyecto: Gerente {\n    var proyectos: [String]\n    \n    override init(id: Int, nombre: String, equipo: [Empleado], proyectos: [String]) {\n        self.proyectos = proyectos\n        super.init(id: Int, nombre: String, equipo: [Empleado])\n    }\n    \n    func revisarProyectos() -> String {\n        return \"\\(nombre), está revisando los progreso de los proyectos\"\n    }\n}\n\nclass Programador: Empleado {\n    var lenguaje: String\n    \n    override init(id: Int, nombre: String, lenguaje: String) {\n        self.lenguaje = lenguaje\n        super.init(id: Int, nombre: String)\n    }\n    \n    func picarCodigo() -> String {\n        return \"\\(nombre) esta creando un proyecto en el lenguaje \\(lenguaje)\"\n    }\n}\n\n// Crear empleados\nlet gerente = Gerente(id: 1, nombre: \"Juan\", equipo: [])\nlet gerenteProyecto = JefeProyecto(id: 2, nombre: \"Maria\", equipo: [], proyectos: [\"Proyecto A\", \"Proyecto B\"])\nlet programador = Programador(id: 3, nombre: \"Pedro\", lenguaje: \"Swift\")\n\n// Acceder a propiedades y métodos específicos de cada tipo de empleado\nprint(gerente.asignarTrabajo())\nprint(gerenteProyecto.revisarProyectos())\nprint(programador.picarCodigo())\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/swift/pedroomar23.swift",
    "content": "import Foundation\n\n/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n\nprotocol Animal {\n    var name: String \n    func sound()\n}\n\nextension Animal {\n    func sound() {\n        print(\"Los animales de nombre \\(name) tienen su propio sonido\")\n    }\n}\n\nclass Perro: Animal {\n    var name: String \n\n    init(name: String) {\n        self.name = name \n    }\n\n    func sound() {\n        print(\"Los perros de nombre \\(name) hacen jau jau\")\n    }\n}\n\nvar sing = Perro(name: \"Chams\")\nsing.sound()\n\nclass Gato: Animal {\n    var name: String \n\n    init(name: String) {\n        self.name = name \n    }\n\n    func sound() {\n        print(\"Los gatos de nombre \\(name) hacen miau miau\")\n    }\n}\n\nvar song = Gato(name: \"Champions\")\nsong.sound()\n\n// Extra \nprotocol Empresa {\n    var name: String \n    var id: Int \n\n    func send()\n}\n\nextension Empresa {\n    func send() {\n        print(\"La empresa tiene programadores, gerentes y gerentes de proyectos\")\n    }\n}\n\n// Genrentes\nclass Gerentes: Empresa {\n    var name: String \n    var id: Int \n\n    init(name: String, id: Int) {\n        self.name = name \n        self.id = id \n    }\n\n    func send() {\n        print(\"Los gerentes de nombre \\(name) trabajan en la empresa\")\n        print(\"Los gerentes de id \\(id) trabajan en la empresa\")\n    }\n}\n\nvar sang = Gerentes(name: \"Carlos\", id: 1234567)\nsang.send()\n\n// Gerentes de Proyectos\nclass GerentesP: Empresa {\n    var name: String \n    var id: Int \n\n    init(name: String,, id: Int) {\n        self.name = name \n        self.id = id \n    }\n\n    func send() {\n        print(\"Los gerentes de proyectos de noombre \\(name) trabajan en la empresa\")\n        print(\"Los gerentes de proyectos de id \\(id) trabajan en la empresa\")\n    }\n}\n\nvar sing = GerentesP(name: \"Carlos\", id: 567890)\nsing.send()\n\n// Programadores\nclass Programadores: Empresa {\n    var name: String \n    var id: Int \n\n    init(name: String, id: Int) {\n        self.name = name \n        self.id = id \n    }\n\n    func send() {\n        print(\"Los programadores de nombre \\(name) trabajan en la empresa\")\n        print(\"Los programadores de id \\(id) trabajan en la empresa\")\n    }\n}\n\nvar seng = Programadores(name: \"Charles\", id: 3245678)\nseng.send()\n\n\n\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/swift/zetared92.swift",
    "content": "import Foundation\n// RETO #09 HERENCIA\n\n\nprotocol Animal {\n    var name: String { get }\n    func makeNoise()\n}\n\n\nextension Animal {\n    func makeNoise() {\n        print(\"The \\(name) make some noise.\")\n    }\n}\n\n\nclass Dog: Animal {\n    var name: String\n    \n    init(name: String) {\n        self.name = name\n    }\n    \n    func makeNoise() {\n        print(\"The dog \\(name) barks.\")\n    }\n}\n\n\nclass Cat: Animal {\n    var name: String\n    \n    init(name: String) {\n        self.name = name\n    }\n    \n    func makeNoise() {\n        print(\"The cat \\(name) meows.\")\n    }\n}\n\n\nlet dogName = Dog(name: \"LUKE\")\nlet catName = Cat(name: \"VADER\")\n\ndogName.makeNoise()\ncatName.makeNoise()\n\n// 🧩 DIFICULTAD EXTRA 🧩 - JERARQUÍA DE EMPRESA\nclass Employee {\n    var id: Int\n    var name: String\n    var employees: [Employee]\n\n    init(id: Int, name: String) {\n        self.id = id\n        self.name = name\n        self.employees = []\n    }\n\n    func add(employee: Employee) {\n        self.employees.append(employee)\n    }\n\n    func printEmployees() {\n        for employee in self.employees {\n            print(employee.name)\n        }\n    }\n}\n\nclass Manager: Employee {\n    func coordinateProjects() {\n        print(\"\\(self.name) is coordinating the projects\")\n    }\n}\n\nclass ProjectManager: Employee {\n    var project: String\n\n    init (id: Int, name: String, project: String) {\n        self.project = project\n        super.init(id: id, name: name)\n    }\n\n    func superviseProjects() {\n        print(\"\\(self.name) is supervising the projects\")\n    }\n}\n\nclass Developer: Employee {\n    var program: String\n\n    init(id: Int, name: String, program: String) {\n        self program = program\n        super.init(id: id, name: name)\n    }\n\n    func development() {\n        print(\"\\(self.name) is developing \\(self.program)\")\n    }\n\n    override func add(employee: Employee) {\n        print(\"He's the last monkey\")\n    }\n}\n\nlet theManager = Manager(id: 1, name: \"T-Bug\")\nlet theProjectManager = ProjectManager(id: 2, name: \"Vik Vector\", project: [\"Cibernetic Update v1.0\", \"Biometrical Update v.4.0\"])\nlet theDeveloper = Developer(id: 3, name: \"Zeta\", program: \"health programm update\")\nlet theSecondPDeveloper\n\ntheManager.add(employee: theProjectManager)\n\ntheProjectManager.add(employee: theDeveloper)\n\ntheDeveloper.add(employee: theSecondPDeveloper)\n\ntheManager.coordinateProjects()\ntheManager.printEmployees()\ntheProjectManager.superviseProjects()\ntheProjectManager.printEmployees()\ntheDeveloper.development()\ntheDeveloper.printEmployees()"
  },
  {
    "path": "Roadmap/09 - HERENCIA/typescript/AChapeton.ts",
    "content": "class Animal{\n  constructor(name: string, size: string, isDomestic: Boolean){\n    this.name = name\n    this.size = size\n    this.isDomestic = isDomestic\n  }\n}\n\nclass Dog extends Animal{\n  get makeDogSound(){\n    return this.dogSound()\n  }\n  \n  dogSound() {\n    return 'bark' + ' ' + this.name\n  }\n}\n\nclass Cat extends Animal{\n  get makeCatSound(){\n    return this.catSound()\n  }\n  \n  catSound() {\n    return 'meow' + ' ' + this.name\n  }\n}\n\nconst myDog = new Dog('Dolly', 'small', true)\nconsole.log(myDog.makeDogSound)\n\nconst myCat = new Cat('Snowball', 'small', true)\nconsole.log(myCat.makeCatSound)\n\n\n\n\n/* DIFICULTAD EXTRA */\n\nclass Empleado{\n  constructor(id: string, employeeName: string){\n    this.id = id\n    this.employeeName = employeeName\n  }\n\n  get makePresentation(){\n    return this.presentation()\n  }\n\n  presentation(){\n    return 'Hola, mi nombre es ' + this.employeeName\n  }\n}\n\nclass Gerente extends Empleado{\n  constructor(id: string, employeeName: string, clients: Array<string> = []){\n  super(id, employeeName)\n    this.clients = clients\n  }\n\n  get showClientsList(){\n    return this.clientsList()\n  }\n\n  clientsList(){\n    return this.clients\n  }\n\n  addNewClient(companyName: string){\n    this.clients.push(companyName)\n  }\n\n}\n\nconst newGerente = new Gerente('1', 'Andres')\nconsole.log(newGerente.makePresentation)\nconsole.log(newGerente.showClientsList)\nnewGerente.addNewClient('ITO')\nconsole.log(newGerente.showClientsList)\n\n\nclass GerenteProyecto extends Empleado{\n  constructor(id: string, employeeName: string, projects: Array<string> = []){\n    super(id, employeeName)\n    this.projects = projects\n  }\n\n  get showProjectsList(){\n    return this.projectsList()\n  }\n\n  projectsList(){\n    return this.projects\n  }\n\n  startProject(projectName: string){\n    this.projects.push(projectName)\n  }\n\n  finishProject(projectName: string){\n    this.projects = this.projects.filter(project => project !== projectName)\n  }  \n}\n\n\nconst newGerenteProyecto = new GerenteProyecto('2', 'Edith')\nconsole.log(newGerenteProyecto.makePresentation)\nconsole.log(newGerenteProyecto.showProjectsList)\nnewGerenteProyecto.startProject('Web page')\nnewGerenteProyecto.startProject('Mobile app')\nnewGerenteProyecto.startProject('Logo refresh')\nconsole.log(newGerenteProyecto.showProjectsList)\nnewGerenteProyecto.finishProject('Mobile app')\nconsole.log(newGerenteProyecto.showProjectsList)\n\n\nclass Programador extends Empleado{\n  constructor(id: string, employeeName: string, tasks: Array<string> = []){\n    super(id, employeeName)\n    this.tasks = tasks\n  }\n\n  get showTasksList(){\n    return this.tasksList()\n  }\n\n  tasksList(){\n    return this.tasks\n  }\n\n  startNewTask(newTask: string){\n    this.tasks.push(newTask)\n  }\n\n  finishTask(taskName: string){\n    this.tasks = this.tasks.filter(task => task !== taskName)\n  }\n}\n\nconst newProgramador = new Programador('3', 'Jesus')\nconsole.log(newProgramador.makePresentation)\nconsole.log(newProgramador.showTasksList)\nnewProgramador.startNewTask('refactor sign in function')\nnewProgramador.startNewTask('fix form styles')\nnewProgramador.startNewTask('create props TS interface')\nconsole.log(newProgramador.showTasksList)\nnewProgramador.finishTask('fix form styles')\nconsole.log(newProgramador.showTasksList)"
  },
  {
    "path": "Roadmap/09 - HERENCIA/typescript/Igledev.ts",
    "content": "// 1º Ejercicio \n    // Hacemos un type del tipo de comida que hay\n    type AlimentacionAnimal = 'CARNIVORO' | 'HERVIBORO' | 'OMNIVORO'\n\n    // Creamos la clase Animal donde le incluimos la base de cada animal\n    abstract class Animal{  // La hacemos abstracta para hacer el método que reproduzca el sonido del animal\n        constructor(private _nombre : string,\n        private _especie : string,\n        private _alimentacion  : AlimentacionAnimal)\n        {}\n\n        public set setNombre(nombre : string){\n            this._nombre = nombre;\n        }\n\n        public get getNombre() : string{\n            return this._nombre;\n        }\n\n        public set setEspecie(especie : string){\n            this._especie = especie;\n        }\n\n        public get getEspecie() : string{\n            return this._especie;\n        }\n\n        public set setAlimentacion(alimentacionAnimal : AlimentacionAnimal){\n            this._alimentacion = alimentacionAnimal;\n        }\n\n        public get getAlimentacion() : AlimentacionAnimal{\n            return this._alimentacion;\n        }\n\n        abstract sonido() : string; // Hacemos que devuelva un string que va a ser el sonido \n\n        //Vamos a hacer el método toString()\n        public toString() : string{\n            return `El animal es un/a ${this._especie}, es ${this._alimentacion} y se llama ${this._nombre}`;\n        }\n    }\n\n    // Creamos la clase Perro que extiende de Animal\n    class Perro extends Animal{\n        constructor(_nombre : string,\n            _especie : string,\n            _alimentacion : AlimentacionAnimal,\n            private _raza : string)\n        {super(_nombre, _especie, _alimentacion)}\n\n        public set setRaza(raza : string){\n            this._raza = raza;\n        }\n\n        public get getRaza(){\n            return this._raza;\n        }\n\n        sonido(): string {\n            return 'guau!';\n        }\n\n        public toString(): string {\n            return super.toString() + `. Es un ${this._raza}`;\n        }\n\n    }\n\n    // Creamos la clase Gato que extiende de Animal\n    class Gato extends Animal{\n\n        constructor(_nombre : string,\n            _especie : string,\n            _alimentacion : AlimentacionAnimal,\n            private _color : string)\n        {super(_nombre, _especie, _alimentacion)}\n\n        public set setColor(color : string){\n            this._color = color;\n        }\n\n        public get getColor(){\n            return this._color;\n        }\n\n        sonido(): string {\n            return 'meow!';\n        }\n\n        public toString(): string {\n            return super.toString() + `. Es de color ${this._color}`;\n        }\n\n    }\n\n    // Vamos a crear instancias\n    let perrete = new Perro('Blas', 'Perro', 'OMNIVORO', 'Payeiro');\n    console.log(perrete.toString() + '. Su sonido es: ' + perrete.sonido());\n    let gatete = new Gato('Zelda', 'Gato', 'OMNIVORO', 'Negro');\n    console.log(gatete.toString() + '. Su sonido es: ' + gatete.sonido());\n\n// Ejercicio Extra\n    //Creamos la clase común para todos\n    type tipoEmpleado = 'GERENTE' | 'GERENTE DE PROYECTOS' | 'PROGRAMADORES' \n    abstract class Empleado{\n        constructor(private readonly _id : number, \n            private _nombre : string,\n            private _tipoEmpleado : tipoEmpleado)\n        {}\n\n        public set setNombre(nombre : string){\n            this._nombre = nombre;\n        }\n\n        public get getNombre(){\n            return this._nombre;\n        }\n\n        public set setEmpleado(empleado : tipoEmpleado){\n            this._tipoEmpleado = empleado;\n        }\n\n        public get getEmpleado(){\n            return this._tipoEmpleado;\n        }\n\n        public toString() : string{\n            return `Hola, soy ${this._tipoEmpleado}, mi identificado es: ${this._id} y mi nombre es ${this._nombre}`;\n        }\n    }\n\n    class Gerente extends Empleado{\n        constructor(\n            id : number,\n            nombre : string,\n            tipoEmpleado : tipoEmpleado,\n            private _funciones : string,\n            private _gerentesProyecto : GerentesProyecto[])\n        {super(id, nombre, tipoEmpleado)}\n\n        public set setGerentesProyecto(gerentesProyecto : GerentesProyecto[]){\n            this._gerentesProyecto = gerentesProyecto;\n        }\n\n        public get getGerentesProyecto() : GerentesProyecto[]{\n            return this._gerentesProyecto;\n        }\n\n        public set setFunciones(funciones : string){\n            this._funciones = funciones;\n        }\n\n        public get getFunciones() : string{\n            return this._funciones;\n        }\n\n        public anhadirGerentesProyecto(gerenteProyecto : GerentesProyecto) : void{\n            this._gerentesProyecto.push(gerenteProyecto);\n        }\n\n        public toString(): string {\n            return super.toString() + `. Mi función es ${this._funciones} y tengo a mi cargo ${this._gerentesProyecto.length} Gerentes de Proyecto`;\n        }\n    }\n\n    class GerentesProyecto extends Empleado{\n        constructor(\n            id : number,\n            nombre : string,\n            tipoEmpleado : tipoEmpleado,\n            private _proyectos : number,\n            private _programadores : Programador[])\n        {super(id, nombre, tipoEmpleado)}\n\n        public anhadirProgramadores(programador : Programador) : void{\n            this._programadores.push(programador);\n        }\n\n        public toString(): string {\n            return super.toString() + `. Tengo ${this._proyectos} proyectos a mi cargo y ${this._programadores.length} progamadores detrás`;\n        }\n    }\n\n    type Especialidad = 'FRONT-END' | 'BACK-END' | 'FULL-STACK'\n    class Programador extends Empleado{\n        constructor(\n            id : number,\n            nombre : string,\n            tipoEmpleado : tipoEmpleado,\n            private _especialidad : Especialidad)\n        {super(id, nombre, tipoEmpleado)}\n\n        public set setEspecialidad(especialidad : Especialidad){\n            this._especialidad = especialidad;\n        }\n\n        public get getEspecialidad(){\n            return this._especialidad;\n        }\n\n        public toString(): string {\n            return super.toString() + `. Soy ${this._especialidad}`;\n        }\n    }\n\n    // Vamos a declarar las instancias\n    let gerenteLista : GerentesProyecto[] = [];\n    let programadores : Programador[] = [];\n    let gerente = new Gerente(1,'Adri','GERENTE','Administración', gerenteLista);\n    let gerenteProyecto = new GerentesProyecto(2,'Claudia','GERENTE DE PROYECTOS',8, programadores);\n    let programador1 = new Programador(3 , 'Igledev', 'PROGRAMADORES', 'FRONT-END')\n    let programador2 = new Programador(4 , 'Adrián', 'PROGRAMADORES', 'BACK-END')\n    let programador3 = new Programador(5 , 'Moure', 'PROGRAMADORES', 'FULL-STACK')\n\n    //Añadimos los empleados a sus correspondientes arrays.\n    gerenteProyecto.anhadirProgramadores(programador1);\n    gerenteProyecto.anhadirProgramadores(programador2);\n    gerenteProyecto.anhadirProgramadores(programador3);\n    console.log(gerenteProyecto.toString());\n\n    gerente.anhadirGerentesProyecto(gerenteProyecto);\n    console.log(gerente.toString());"
  },
  {
    "path": "Roadmap/09 - HERENCIA/typescript/RicJDev.ts",
    "content": "//EJERCICIO\nclass Animal {\n  name: string\n  constructor(name: string) {\n    this.name = name\n\n    if (new.target === Animal) {\n      throw new TypeError('unable to instantiate class \"Animal\"')\n    }\n  }\n\n  speak(): void {\n    throw new Error('the method \"speak()\" must be implemented')\n  }\n}\n\nclass Dog extends Animal {\n  constructor(name: string) {\n    super(name)\n  }\n\n  speak(): void {\n    console.log(`${this.name}: woof, woof!`)\n  }\n}\n\nclass Cat extends Animal {\n  constructor(name: string) {\n    super(name)\n  }\n\n  speak(): void {\n    console.log(`${this.name}: meow, meow!`)\n  }\n}\n\nconst charlie = new Dog('Charlie')\ncharlie.speak()\n\nconst mike = new Cat('Mike')\nmike.speak()\n\n//EXTRA\nclass Employee {\n  name: string\n  workerID: number\n  title: string\n\n  constructor(name: string, workerID: number, title: string) {\n    this.name = name\n    this.workerID = workerID\n    this.title = title\n  }\n\n  work(): void {\n    console.log(`${this.name} is working...`)\n  }\n}\n\ninterface hasWorkers {\n  workers: Employee[]\n  addWorker: (worker: Employee) => void\n  displayWorkersList: () => void\n}\n\nclass Manager extends Employee implements hasWorkers {\n  workers: Employee[] = []\n\n  constructor(name: string, workerID: number) {\n    super(name, workerID, 'manager')\n  }\n\n  addWorker(worker: Employee): void {\n    this.workers.push(worker)\n\n    console.log(`${worker.name} is now working for ${this.name}.`)\n  }\n\n  displayWorkersList(): void {\n    console.log(`${this.name}'s workers:`)\n\n    this.workers.forEach((worker) => {\n      console.log(`- ${worker.name}: ${worker.workerID}. ${worker.title}`)\n    })\n  }\n}\n\nclass ProjectManager extends Employee implements hasWorkers {\n  workers: Employee[]\n\n  constructor(name: string, workerID: number) {\n    super(name, workerID, 'Project Manager')\n  }\n\n  addWorker(worker: Employee) {\n    this.workers.push(worker)\n  }\n\n  displayWorkersList(): void {\n    console.log(`${this.name}'s workers:`)\n\n    this.workers.forEach((worker) => {\n      console.log(`- ${worker.name}: ${worker.workerID}. ${worker.title}`)\n    })\n  }\n}\n\nclass Programer extends Employee {}\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/typescript/RobertoAmaroHub.ts",
    "content": "class Animal{\n\n    protected nombre:string;\n    constructor(_nombre:string){\n        this.nombre=_nombre;\n    }\n\n    protected printSound(){\n        console.log(`el ${this.nombre} hace un sonido`);\n    }\n}\n\nclass Perro extends Animal{\n\n    constructor(nombre:string){\n        super(nombre);\n    }\n    printSound(){\n        console.log(`${this.nombre} hace guau!`)\n    }\n}\n\nclass Gato extends Animal{\n\n    constructor(nombre:string){\n        super(nombre);\n    }\n    printSound(){\n        console.log(`${this.nombre} hace miau!`);\n    }\n}\n\nlet perro:Perro= new Perro(\"Kimmy\");\nperro.printSound();\n\nlet gato:Gato= new Gato(\"Mishi\");\ngato.printSound();\n\n//EXTRA\nclass Empleado{\n\n    public id:number;\n    public nombre:string;\n    public puesto:string;\n    constructor(_id:number, _nombre:string, _puesto:string){\n        this.id=_id;\n        this.nombre=_nombre;\n        this.puesto=_puesto;\n    }\n    \n    public verInformacion(){\n        console.log(`\\nInformación del empleado: id: ${this.id}, nombre: ${this.nombre}, Puesto: ${this.puesto}`);\n    }\n    public verLabor(){\n    }\n}\n\nclass Gerente extends Empleado{\n    private empleados:Empleado[];\n    constructor(id:number, nombre:string, _empleados:Empleado[]){\n        super(id,nombre,\"Gerente\")\n        this.empleados=_empleados;\n    }\n\n    verLabor(){\n        super.verInformacion();\n        console.log(`Labor: El gerente tiene la labor de supervisar a los empleados: `)\n        this.empleados.forEach((empleado)=>console.log(empleado.nombre));\n    }\n}\nclass GerenteProyectos extends Empleado{\n    private empleados:Empleado[];\n    private proyectos:string[];\n    constructor(id:number, nombre:string, _empleados:Empleado[], _proyectos:string[]){\n        super(id,nombre,\"Gerente De Proyectos\");\n        this.empleados=_empleados;\n        this.proyectos=_proyectos;\n    }\n\n    verLabor(){\n        super.verInformacion();\n        console.log(`Labor: El gerente de proyectos tiene la labor de supervisar los proyectos: `) \n            console.log(this.proyectos);\n        console.log(`y los empleados a su cargo: `)\n        this.empleados.forEach((empleado)=>console.log(empleado.nombre));\n    }\n}\nclass Programador extends Empleado{\n    private tareas:string[];\n    constructor(id:number, nombre:string, _tareas:string[]){\n        super(id,nombre, \"Programador\")\n        this.tareas=_tareas;\n    }\n\n    verLabor(){\n        super.verInformacion();\n        console.log(`Labor: El programador tiene la labor de trabajar en las tareas que se le tienen asignadas: ${this.tareas}`)\n    }\n}\n\nlet proyectos:string[]=[\"Pro1\",\"Pro2\",\"Pro3\"]\nlet tareas:string[]=[\"tarea1\",\"tarea2\",\"tarea3\"];\nlet programadores:Programador[]=[new Programador(12,\"Edgar\",tareas),new Programador(13,\"Ramiro\",tareas)]\nlet gerentesProyectos:GerenteProyectos[]=[new GerenteProyectos(12,\"Jose\",programadores,proyectos)];\nlet gerentes:Gerente[]=[new Gerente(12, \"Roberto\", gerentesProyectos)]\n\n\ngerentes[0].verLabor();\ngerentesProyectos[0].verLabor();\nprogramadores[0].verLabor();\nprogramadores[1].verLabor();\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/typescript/Sac-Corts.ts",
    "content": "class Animal {\n    constructor(public name: string) {}\n\n    sound(): string {\n        return 'The animal make a sound';\n    }\n}\n\nclass Dog extends Animal {\n    constructor(name: string) {\n        super(name);\n    }\n\n    sound(): string {\n        return 'Woof'; \n    }\n}\n\nclass Cat extends Animal {\n    constructor(name: string) {\n        super(name);\n    }\n\n    sound(): string{\n        return 'Meow';\n    }\n}\n\nfunction printSound(animal: Animal): void {\n    console.log(`${animal.name} say: ${animal.sound()}`);\n}\n\nconst myDog = new Dog(\"Junior\");\nconst myCat = new Cat(\"Mauricio\");\n\nprintSound(myDog);\nprintSound(myCat);\n\n// ** Extra Exercise ** //\nclass Employee {\n    constructor (\n        public id: number,\n        public name: string\n    ) {}\n\n    showDetails(): void {\n        console.log(`Employee ID: ${this.id}, Name: ${this.name}`);\n    }\n}\n\nclass Manager extends Employee {\n    employeesInCharge: Employee[] = [];\n\n    constructor(id: number, name: string) {\n        super(id, name);\n    }\n\n    addEmployeeInCharge(employee: Employee): void {\n        this.employeesInCharge.push(employee);\n    }\n\n    showDetails(): void {\n        super.showDetails();\n        console.log('Manager in charge of:');\n        this.employeesInCharge.forEach(emp => emp.showDetails());\n    }\n}\n\nclass ProjectManager extends Manager {\n    projects: string[] = [];\n\n    constructor(id: number, name: string) {\n        super(id, name);\n    }\n\n    assignProject(project: string): void {\n        this.projects.push(project);\n    }\n\n    showDetails(): void {\n        super.showDetails();\n        console.log(`Assigned projects: ${this.projects.join(', ')}`);\n    }\n}\n\nclass Programmer extends Employee {\n    languages: string[] = [];\n\n    constructor(id: number, name: string, languages: string[]) {\n        super(id, name);\n        this.languages = languages;\n    }\n\n    showDetails(): void {\n        super.showDetails();\n        console.log(`Languages: ${this.languages.join(', ')}`);\n    }\n}\n\nconst programmer1 = new Programmer(1, 'Isaac', [\"JavaScript\", \"Python\", \"TypeScript\"]);\nconst programmer2 = new Programmer(2, 'Mancheco', [\"JavaScript\", \"Python\", \"TypeScript\", \"C++\"]);\n\nconst projectManager = new ProjectManager(3, \"Carlos\");\n\nprojectManager.addEmployeeInCharge(programmer1);\nprojectManager.addEmployeeInCharge(programmer2);\nprojectManager.assignProject(\"Project X\");\nprojectManager.showDetails();"
  },
  {
    "path": "Roadmap/09 - HERENCIA/typescript/david-git-dev.ts",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal\n */\nclass Animal {\n  private _habitat: string;\n  private _dieta: any[];\n  constructor(habitat: string, dieta: any[]) {\n    this._habitat = habitat;\n    this._dieta = dieta;\n  }\n  sonido() {\n    return \"sonido caracteristico de un animal\";\n  }\n}\nclass Perro extends Animal {\n  private _nombre: string;\n  private _especie: string;\n\n  constructor(nombre: string, especie: string, habitat: string, dieta: any[]) {\n    super(habitat, dieta);\n    this._nombre = nombre;\n    this._especie = especie;\n  }\n  sonido() {\n    return \"¡Guau guau!\";\n  }\n}\nclass Gato extends Animal {\n  private _nombre: string;\n  private _especie: string;\n\n  constructor(nombre: string, especie: string, habitat: string, dieta: any[]) {\n    super(habitat, dieta);\n    this._nombre = nombre;\n    this._especie = especie;\n  }\n  sonido() {\n    return \"¡Miau Miau!\";\n  }\n}\nconst chauchau = new Perro(\"canela\", \"canino\", \"casa\", [\n  \"croquetas\",\n  \"pollo\",\n  \"hueso\",\n]);\nchauchau.sonido();\nconst naranja = new Gato(\"sr.tims\", \"felino\", \"casa\", [\n  \"croquetas\",\n  \"pescado\",\n  \"whiskas\",\n]);\nnaranja.sonido();\n/*\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\nclass Empleado{\n  private _identificador:BigInt\n  private _nombre:string\n  private _salario:BigInt\n  private _fechaDeContratacion:Date\n  constructor(identificador:BigInt,nombre:string,salario:BigInt){\n    this._identificador = identificador\nthis._nombre = nombre\n    this._salario = salario\n  }\n}\nclass Gerente extends Empleado{\n  private _usuariosACargo: Array<Empleado>\n  constructor(identificador:BigInt,nombre:string,salario:BigInt,subordinados:Array<Empleado>){\n    super(identificador,nombre,salario)\n    this._usuariosACargo = subordinados\n  }\n  visionEstrategica(){\n\n  }\n  gestionDeRecursos(){}\n  tomaDeDecisiones(){}\n  supervisionGeneral(){}\n  relacionesExternas(){}\n}\nclass GerenteDeProyecto extends Empleado{\n  private _usuariosACargo: Array<Empleado>;\n  private _proyectosAsignados:Array<Proyecto>\n  constructor(identificador:BigInt,nombre:string,salario:BigInt,subordinados:Array<Empleado>,proyectos:Array<Proyecto>){\n    super(identificador,nombre,salario)\n    this._usuariosACargo = subordinados\n    this._proyectosAsignados = proyectos\n  }\n  planificacionDeProyectos(){}\n  gestionDeEquipos(){}\n  controlDePresupuestos(){}\n  seguimientoYReportes(){}\n  resolucionDeProblemas(){}\n}\nclass Programador extends Empleado{\n  private _experiencia:number = 0;\n  private _proyectosAsignados: Array<Proyecto>;\n  constructor(identificador:BigInt,nombre:string,salario:BigInt,experiencia:number,proyectosAsignados:Proyecto[]){\n    super(identificador,nombre,salario)\n    this._experiencia = experiencia\n    this._proyectosAsignados = proyectosAsignados\n  }\n  escribirCodigo(){}\n  depurarCodigo(){}\n  colaborarEnProyectos(){}\n  actualizarConocimientos(){}\n}\n\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/typescript/duendeintemporal.ts",
    "content": "/* #09 { retosparaprogramadores } HERENCIA Y POLIMORFISMO */\n// bibliography\n//Professional JavaScript for web developers by Matt Frisbie [Frisbie, Matt] (z-lib.org)\n//GPT\n\n/* In JavaScript, inheritance is a mechanism that allows one object to acquire the properties and methods of another object. This is typically achieved through prototypes, where an object can inherit from another object's prototype, enabling code reuse and the creation of hierarchical relationships between objects. JavaScript supports both classical inheritance (using constructor functions and the `prototype` property) and modern inheritance (using `class` syntax introduced in ES6).\nAll objects have an internal property called [[Prototype]], which is a reference to another object. This prototype chain allows for inheritance, where an object can access properties and methods from its prototype.\nWhen you create an object using a constructor function, you can set its prototype using the prototype property. \nWith the introduction of ES6, JavaScript introduced class syntax, which is essentially syntactic sugar over the existing prototype-based inheritance. When you define a class, JavaScript still uses prototypes behind the scenes*/\n\n// short for console.log()\nconst log = console.log;\n\n    log('Retosparaprogramadores #9'); // Retosparaprogramadores #9 \n\ninterface IAnimal {\n    name: string;\n    sound: string;\n    type: string;\n    speak(): void;\n}\n\nclass Animal implements IAnimal {\n    protected _name: string;\n    protected _sound: string;\n    protected _type: string;\n\n    constructor(name: string, sound: string, type: string) {\n        this._name = name || 'set no name';\n        this._sound = sound || 'set no sound';\n        this._type = type || 'set no type';\n    }\n\n    get name(): string {\n        return this._name;\n    }\n\n    get sound(): string {\n        return this._sound;\n    }\n\n    get type(): string {\n        return this._type;\n    }\n\n    set name(name: string) {\n        this._name = name;\n    }\n\n    speak(): void {\n        log(`${this.name} the ${this._type} say: ${this._sound}!`);\n    }\n}\n\ninterface IPet extends IAnimal {\n    eat(meal: string): void;\n    move(): void;\n}\n\nclass Dog extends Animal implements IPet {\n    constructor(name: string, sound: string, type: string) {\n        super(name, sound, type);\n    }\n\n    eat(meal: string): void {\n        log(`${this._name} the ${this._type} eat some: ${meal}`);\n    }\n\n    move(): void {\n        log(`the ${this._type} moves it's tail`);\n    }\n}\n\nconst capDog = new Dog('Capitan', 'I guau some pizza', 'Dog');\ncapDog.speak(); // Capitan the Dog say: I guau some pizza!\ncapDog.eat('pizza'); // Capitan the Dog eat some: pizza\ncapDog.move(); // the Dog moves it's tail\n\nclass Cat extends Animal implements IPet {\n    constructor(name: string, sound: string, type: string) {\n        super(name, sound, type);\n    }\n\n    eat(meal: string): void {\n        log(`${this._name} the ${this._type} eat some: ${meal}`);\n    }\n\n    move(): void {\n        log(`the ${this._type} hunt the rat`);\n    }\n}\n\nconst blackJack = new Cat('BlackJack', 'Miuauuuu', 'Cat');\nblackJack.speak(); // BlackJack the Cat say: Miuauuuu!\nblackJack.eat('rat snack'); // BlackJack the Cat eat some: rat snack\nblackJack.move(); // the Cat hunt the rat\n\n//Note: is interesting know that we can use variables like key-value assign to object properties, this also work with functions, see:\n\ninterface IPerson {\n    name: string;\n    age: number;\n    email: string;\n    personJob?: string;\n}\n\nconst makePerson = (name: string, age: number, email: string): IPerson => {\n    return { name, age, email };\n};\nconst person = makePerson('Angy', 28, 'badgirl@greenhouse.net');\nlog(person); // { name: \"Angy\", age: 28, email: \"badgirl@greenhouse.net\" }\n\n//using destructuring\nlet {name: personName, age: personAge, email: personEmail, personJob = 'Web Developer'} = person;\nlog(personAge); // 28\nlog(personJob)// Web Developer\n\n\ninterface IUser {\n    id: string;\n    name: string;\n    email: string;\n    country: string;\n    userData(): IUserData;\n}\n\ninterface IUserData {\n    id: string;\n    name: string;\n    email: string;\n    country: string;\n}\n\nclass User implements IUser {\n    protected _id: string;\n    protected _name: string;\n    protected _email: string;\n    protected _country: string;\n\n    constructor(id: string, name: string, email: string, country: string) {\n        try {\n            this._id = this.setId(id);\n            this._name = this.setName(name);\n            this._email = this.setEmail(email);\n            this._country = this.setCountry(country);\n            this.validateProperties();\n        } catch (error) {\n            console.error('Error creating User:', (error as Error).message);\n            throw error;\n        }\n    }\n\n    get id() {\n        return this._id;\n    }\n\n    get name() {\n        return this._name;\n    }\n\n    get email() {\n        return this._email;\n    }\n\n    get country() {\n        return this._country;\n    }\n\n    set id(id: string) {\n        this._id = this.setId(id);\n    }\n\n    set name(name: string) {\n        this._name = this.setName(name);\n    }\n\n    set email(email: string) {\n        this._email = this.setEmail(email);\n    }\n\n    set country(country: string) {\n        this._country = this.setCountry(country);\n    }\n\n    protected setId(id: string): string {\n        const idString = String(id);\n        const maxLength = 15;\n\n        if (idString.length > maxLength) {\n            throw new Error(`ID must be at most ${maxLength} characters long.`);\n        }\n\n        return idString;\n    }\n\n    protected setName(name: string): string {\n        const nameString = String(name);\n        const maxLength = 35;\n\n        if (nameString.length > maxLength) {\n            throw new Error(`Name must be at most ${maxLength} characters long.`);\n        }\n\n        return nameString;\n    }\n\n    protected setEmail(email: string): string {\n        const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[a-zA-Z]{2,}(\\.[a-zA-Z]{2,})?$/;\n\n        if (!emailRegex.test(email)) {\n            throw new Error('Invalid email address format.');\n        }\n\n        return email;\n    }\n\n    protected setCountry(country: string): string {\n        const countryString = String(country);\n        const maxLength = 35;\n\n        if (countryString.length > maxLength) {\n            throw new Error(`Country must be at most ${maxLength} characters long.`);\n        }\n\n        return countryString;\n    }\n\n    validateProperties() {\n        if (!this._id || !this._name || !this._email || !this._country) {\n            throw new Error('All properties must be set before freezing the object.');\n        }\n    }\n\n    userData(): IUserData {\n        return {\n            id: this._id,\n            name: this._name,\n            email: this._email,\n            country: this._country\n        };\n    }\n}\n\n\ntry {\n    let sussy = new User('0067', 'Sussan', 'sussy45@something.dt', 'Canada');\n    console.log(sussy.userData()); // { id: \"0067\", name: \"Sussan\", email: \"sussy45@something.dt\", country: \"Canada\" }\n} catch (error: unknown) {\n    if (error instanceof Error) {\n        console.error('Failed to create user:', error.message);\n    }\n}\n\n//Note: if we use a number to set the value for id 0067 becomes 55 cause is turned to a decimal value \n\ninterface ISuperUser extends IUser {\n    hasPermission(): boolean;\n    displayUserInfo(): string;\n}\n\nclass SuperUser extends User implements ISuperUser {\n    private _permission: boolean;\n\n    constructor(id: string, name: string, email: string, country: string) {\n        super(id, name, email, country);\n        this._permission = true;\n    }\n\n    hasPermission(): boolean {\n        return this._permission;\n    }\n\n    displayUserInfo(): string {\n        const userInfo = this.userData();\n        return `${userInfo.name} has permission: ${this.hasPermission()}`;\n    }\n}\n\nconst niko = new SuperUser('001', 'Niko', 'duendeintemporal@hotmail.com', 'Venezuela');\nniko.country = 'undefined'; \nlog(niko.id); // 001\nlog(niko.country); // undefined\nlog(niko.hasPermission()); // true\nlog(niko.userData()); // { id: \"001\", name: \"Niko\", email: \"duendeintemporal@hotmail.com\", country: \"undefined\" }\n\n// Extra Exercises\n\n\ninterface IEmployed {\n    id: string;\n    name: string;\n    occupation: string;\n    employedData(): IEmployedData;\n}\n\ninterface IEmployedData {\n    id: string;\n    name: string;\n    occupation: string;\n}\n\nclass Employed implements IEmployed {\n    protected _id: string;\n    protected _name: string;\n    protected _occupation: string;\n\n    constructor(id: string, name: string, occupation: string) {\n        try {\n            this._id = this.setId(id);\n            this._name = this.setName(name);\n            this._occupation = this.setOccupation(occupation);\n            this.validateProperties();\n        } catch (error) {\n            console.error('Error creating Employed:', (error as Error).message);\n            throw error;\n        }\n    }\n\n    get id() {\n        return this._id;\n    }\n\n    get name() {\n        return this._name;\n    }\n\n    get occupation() {\n        return this._occupation;\n    }\n\n    set id(id: string) {\n        this._id = this.setId(id);\n    }\n\n    set name(name: string) {\n        this._name = this.setName(name);\n    }\n\n    set occupation(occupation: string) {\n        this._occupation = this.setOccupation(occupation);\n    }\n\n    protected setId(id: string): string {\n        const idString = String(id);\n        const maxLength = 15;\n\n        if (idString.length > maxLength) {\n            throw new Error(`ID must be at most ${maxLength} characters long.`);\n        }\n\n        return idString;\n    }\n\n    protected setName(name: string): string {\n        const nameString = String(name);\n        const maxLength = 35;\n\n        if (nameString.length > maxLength) {\n            throw new Error(`Name must be at most ${maxLength} characters long.`);\n        }\n\n        return nameString;\n    }\n\n    protected setOccupation(occupation: string): string {\n        const occupationStr = String(occupation);\n        const maxLength = 50;\n\n        if (occupationStr.length > maxLength) {\n            throw new Error(`Occupation must be at most ${maxLength} characters long.`);\n        }\n\n        return occupationStr;\n    }\n\n    validateProperties() {\n        if (!this._id || !this._name || !this._occupation) {\n            throw new Error('All properties must be set before freezing the object.');\n        }\n    }\n\n    employedData(): IEmployedData {\n        return {\n            id: this._id,\n            name: this._name,\n            occupation: this._occupation\n        };\n    }\n}\n\ninterface IDeveloper extends IEmployed {\n    functions(): void;\n}\n\nclass Developer extends Employed implements IDeveloper {\n    private _languages: string[];\n    private _area: string;\n\n    constructor(id: string, name: string, occupation: string, languages: string[], area: string) {\n        super(id, name, occupation);\n        this._languages = languages;\n        this._area = area;\n    }\n\n    functions(): void {\n        log(`Developer ID: ${this._id} | Name: ${this._name} | Occupation: ${this._occupation} | Area: ${this._area} | Languages: ${this._languages.join(', ')}`);\n    }\n}\n\nclass Secretary extends Employed {\n    constructor(id: string, name: string, occupation: string) {\n        super(id, name, occupation);\n    }\n\n    functions(): void {\n        log(`Secretary ID: ${this._id} | Name: ${this._name} | Occupation: ${this._occupation} | Responsibilities: Administrative operations and user attention.`);\n    }\n}\n\nclass Manager extends Employed {\n    protected _employeds: string[];\n\n    constructor(id: string, name: string, occupation: string, employeds: string[]) {\n        super(id, name, occupation);\n        this._employeds = employeds;\n    }\n\n    functions(): void {\n        log(`Manager ID: ${this._id} | Name: ${this._name} | Occupation: ${this._occupation} | Supervising Employees: ${this._employeds.join(', ')}`);\n    }\n}\n\nclass GeneralManager extends Manager {\n    constructor(id: string, name: string, occupation: string, employeds: string[]) {\n        super(id, name, occupation, employeds);\n    }\n\n    functions(): void {\n        log(`General Manager ID: ${this._id} | Name: ${this._name} | Occupation: ${this._occupation} | Supervising Employees: ${this._employeds.join(', ')}`);\n    }\n}\n\nconst s1 = new Secretary('0023', 'Gabriela Mistral', 'Secretary');\nconst d12 = new Developer('0041', 'Niko Zen', 'Web Developer', ['Python', 'JavaScript', 'Rust', 'Ruby', 'Bash'], 'Frontend');\nconst m3 = new Manager('0098', 'Patty Smith', 'Manager', [s1.name, d12.name]);\nconst mg2 = new GeneralManager('003', 'Lenny Kravitz', 'General Manager', [m3.name]);\n\nlog(s1.employedData()); // id: \"0023\", name: \"Gabriela Mistral\", occupation: \"Secretary\"\nlog(d12.functions()); // Developer ID: 0041 | Name: Niko Zen | Occupation: Web Developer | Area: Frontend | Languages: Python, JavaScript, Rust, Ruby, Bash\nlog(m3.functions()); // Manager ID: 0098 | Name: Patty Smith | Occupation: Manager | Supervising Employees: Gabriela Mistral, Niko Zen\nlog(mg2.functions()); // General Manager ID: 003 | Name: Lenny Kravitz | Occupation: General Manager | Supervising Employees: Patty Smith\n\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/typescript/eulogioep.ts",
    "content": "// Ejemplo de implementación del concepto de herencia en TypeScript\n\n// Definición de la clase base (superclase) Animal\nclass Animal {\n    protected especie: string;\n    protected sonido: string;\n  \n    constructor(especie: string, sonido: string) {\n      this.especie = especie;\n      this.sonido = sonido;\n    }\n  \n    // Método que muestra el sonido que hace el animal\n    public hacerSonido(): string {\n      return `El ${this.especie} hace: ${this.sonido}`;\n    }\n  }\n  \n  // Definición de la subclase Perro\n  class Perro extends Animal {\n    private nombre: string;\n  \n    constructor(nombre: string, especie: string, sonido: string) {\n      super(especie, sonido); // Llamada al constructor de la superclase\n      this.nombre = nombre;\n    }\n  \n    // Método exclusivo de la subclase Perro\n    public ladrar(): string {\n      return `${this.nombre} lanza un ladrido`;\n    }\n  }\n  \n  // Definición de la subclase Gato\n  class Gato extends Animal {\n    private nombre: string;\n  \n    constructor(nombre: string, especie: string, sonido: string) {\n      super(especie, sonido); // Llamada al constructor de la superclase\n      this.nombre = nombre;\n    }\n  \n    // Método exclusivo de la subclase Gato\n    public maullar(): string {\n      return `${this.nombre} emite un maullido`;\n    }\n  }\n  \n  // Ejemplo de implementación adicional (dificultad extra)\n  // Definición de la clase base (superclase) Empleado\n  class Empleado {\n    protected id: number;\n    protected nombre: string;\n  \n    constructor(id: number, nombre: string) {\n      this.id = id;\n      this.nombre = nombre;\n    }\n  }\n  \n  // Definición de la subclase Gerente que hereda de Empleado\n  class Gerente extends Empleado {\n    private subordinados: Empleado[];\n  \n    constructor(id: number, nombre: string, subordinados: Empleado[]) {\n      super(id, nombre);\n      this.subordinados = subordinados;\n    }\n  \n    // Método exclusivo de la subclase Gerente\n    public informarSobreSubordinados(): string {\n      let informacion = `El gerente ${this.nombre} tiene a los siguientes subordinados: \\n`;\n      informacion += this.subordinados.map((subordinado) => ` - ${subordinado.nombre}\\n`).join('');\n      return informacion;\n    }\n  }\n  \n  // Definición de la subclase GerenteDeProyectos que hereda de Empleado\n  class GerenteDeProyectos extends Empleado {\n    private proyectos: string[];\n  \n    constructor(id: number, nombre: string, proyectos: string[]) {\n      super(id, nombre);\n      this.proyectos = proyectos;\n    }\n  \n    // Método exclusivo de la subclase GerenteDeProyectos\n    public informarSobreProyectos(): string {\n      let informacion = `El gerente de proyectos ${this.nombre} tiene los siguientes proyectos: \\n`;\n      informacion += this.proyectos.map((proyecto) => ` - ${proyecto}\\n`).join('');\n      return informacion;\n    }\n  }\n  \n  // Definición de la subclase Programador que hereda de Empleado\n  class Programador extends Empleado {\n    private lenguajes: string[];\n  \n    constructor(id: number, nombre: string, lenguajes: string[]) {\n      super(id, nombre);\n      this.lenguajes = lenguajes;\n    }\n  \n    // Método exclusivo de la subclase Programador\n    public informarSobreLenguajes(): string {\n      let informacion = `El programador ${this.nombre} domina los siguientes lenguajes: \\n`;\n      informacion += this.lenguajes.map((lenguaje) => ` - ${lenguaje}\\n`).join('');\n      return informacion;\n    }\n  }\n  \n  // Ejemplo de uso\n  const perro = new Perro(\"Lucky\", \"Perro\", \"Gua\");\n  console.log(perro.hacerSonido()); // El Perro hace: Gua\n  console.log(perro.ladrar()); // Lucky lanza un ladrido\n  \n  const gato = new Gato(\"Whiskers\", \"Gato\", \"Miau\");\n  console.log(gato.hacerSonido()); // El Gato hace: Miau\n  console.log(gato.maullar()); // Whiskers emite un maullido\n  \n  const gerente = new Gerente(1, \"Juan Perez\", [new Programador(2, \"Maria Rodriguez\", [\"JavaScript\", \"TypeScript\"])]);\n  console.log(gerente.informarSobreSubordinados());\n  \n  const gerenteProyectos = new GerenteDeProyectos(3, \"Luis Martinez\", [\"Proyecto A\", \"Proyecto B\"]);\n  console.log(gerenteProyectos.informarSobreProyectos());\n  \n  const programador = new Programador(4, \"Karla Sanchez\", [\"JavaScript\", \"TypeScript\"]);\n  console.log(programador.informarSobreLenguajes());"
  },
  {
    "path": "Roadmap/09 - HERENCIA/typescript/hozlucas28.ts",
    "content": "/*\n    Inheritance...\n*/\n\ntype Feeding = 'carnivorous' | 'herbivorous' | 'omnivores'\n\ntype AnimalAttributes = {\n\taverageSpeed: number\n\taverageWeight: number\n\tfeeding: Feeding\n\tname: string\n\tsound: string\n}\n\nclass Animal {\n\tprotected _averageSpeed: number\n\tprotected _averageWeight: number\n\tprotected _feeding: Feeding\n\tprotected _name: string\n\tprotected _sound: string\n\n\tconstructor({ averageSpeed, averageWeight, feeding, name, sound }: AnimalAttributes) {\n\t\tthis._averageSpeed = averageSpeed\n\t\tthis._averageWeight = averageWeight\n\t\tthis._feeding = feeding\n\t\tthis._name = name\n\t\tthis._sound = sound\n\t}\n\n\tpublic set averageSpeed(averageSpeed) {\n\t\tthis._averageSpeed = averageSpeed\n\t}\n\n\tpublic set averageWeight(averageWeight) {\n\t\tthis._averageWeight = averageWeight\n\t}\n\n\tpublic set feeding(feeding) {\n\t\tthis._feeding = feeding\n\t}\n\n\tpublic set name(name) {\n\t\tthis.name = name\n\t}\n\n\tpublic set sound(sound) {\n\t\tthis.sound = sound\n\t}\n\n\tpublic get averageSpeed() {\n\t\treturn this._averageSpeed\n\t}\n\n\tpublic get averageWeight() {\n\t\treturn this._averageWeight\n\t}\n\n\tpublic get feeding() {\n\t\treturn this._feeding\n\t}\n\n\tpublic get name() {\n\t\treturn this.name\n\t}\n\n\tpublic get sound() {\n\t\treturn this.sound\n\t}\n\n\tpublic getAttributes(): AnimalAttributes {\n\t\treturn {\n\t\t\taverageSpeed: this._averageSpeed,\n\t\t\taverageWeight: this._averageWeight,\n\t\t\tfeeding: this._feeding,\n\t\t\tname: this._name,\n\t\t\tsound: this._sound,\n\t\t}\n\t}\n\n\tpublic printAttributes() {\n\t\tconsole.table(this.getAttributes())\n\t\treturn this\n\t}\n\n\tpublic printSound() {\n\t\tconsole.log(`\\n${this._sound}`)\n\t\treturn this\n\t}\n}\n\ninterface DogAttributes extends AnimalAttributes {\n\townerName: string\n\townerPhone: string\n}\n\nclass Dog extends Animal {\n\tprivate _ownerName: string\n\tprivate _ownerPhone: string\n\n\tconstructor({ ownerName, ownerPhone, ...fatherProps }: DogAttributes) {\n\t\tsuper(fatherProps)\n\t\tthis._ownerName = ownerName\n\t\tthis._ownerPhone = ownerPhone\n\t}\n\n\tpublic set ownerName(ownerName) {\n\t\tthis._ownerName = ownerName\n\t}\n\n\tpublic set ownerPhone(ownerPhone) {\n\t\tthis._ownerPhone = ownerPhone\n\t}\n\n\tpublic get ownerName() {\n\t\treturn this._ownerName\n\t}\n\n\tpublic get ownerPhone() {\n\t\treturn this._ownerPhone\n\t}\n\n\tpublic getAttributes(): DogAttributes {\n\t\treturn {\n\t\t\t...super.getAttributes(),\n\t\t\townerName: this._ownerName,\n\t\t\townerPhone: this._ownerPhone,\n\t\t}\n\t}\n}\n\ninterface CatAttributes extends DogAttributes {}\n\nclass Cat extends Dog {\n\tconstructor({ ...fatherProps }: CatAttributes) {\n\t\tsuper(fatherProps)\n\t}\n}\n\nconsole.log('Inheritance in TypeScript...')\n\nconsole.log(`\\ntype Feeding = 'carnivorous' | 'herbivorous' | 'omnivores'\n\ntype AnimalAttributes = {\n    averageSpeed: number\n    averageWeight: number\n    feeding: Feeding\n    name: string\n    sound: string\n}\n\nclass Animal {\n    protected _averageSpeed: number\n    protected _averageWeight: number\n    protected _feeding: Feeding\n    protected _name: string\n    protected _sound: string\n\n    constructor({ averageSpeed, averageWeight, feeding, name, sound }: AnimalAttributes) {\n        this._averageSpeed = averageSpeed\n        this._averageWeight = averageWeight\n        this._feeding = feeding\n        this._name = name\n        this._sound = sound\n    }\n\n    public set averageSpeed(averageSpeed) {\n        this._averageSpeed = averageSpeed\n    }\n\n    public set averageWeight(averageWeight) {\n        this._averageWeight = averageWeight\n    }\n\n    public set feeding(feeding) {\n        this._feeding = feeding\n    }\n\n    public set name(name) {\n        this.name = name\n    }\n\n    public set sound(sound) {\n        this.sound = sound\n    }\n\n    public get averageSpeed() {\n        return this._averageSpeed\n    }\n\n    public get averageWeight() {\n        return this._averageWeight\n    }\n\n    public get feeding() {\n        return this._feeding\n    }\n\n    public get name() {\n        return this.name\n    }\n\n    public get sound() {\n        return this.sound\n    }\n\n    public getAttributes(): AnimalAttributes {\n        return {\n            averageSpeed: this._averageSpeed,\n            averageWeight: this._averageWeight,\n            feeding: this._feeding,\n            name: this._name,\n            sound: this._sound,\n        }\n    }\n\n    public printAttributes() {\n        console.table(this.getAttributes())\n        return this\n    }\n\n    public printSound() {\n        console.log(\\`\\\\n\\${this._sound}\\`)\n        return this\n    }\n}\n\ninterface DogAttributes extends AnimalAttributes {\n    ownerName: string\n    ownerPhone: string\n}\n\nclass Dog extends Animal {\n    private _ownerName: string\n    private _ownerPhone: string\n\n    constructor({ ownerName, ownerPhone, ...fatherProps }: DogAttributes) {\n        super(fatherProps)\n        this._ownerName = ownerName\n        this._ownerPhone = ownerPhone\n    }\n\n    public set ownerName(ownerName) {\n        this._ownerName = ownerName\n    }\n\n    public set ownerPhone(ownerPhone) {\n        this._ownerPhone = ownerPhone\n    }\n\n    public get ownerName() {\n        return this._ownerName\n    }\n\n    public get ownerPhone() {\n        return this._ownerPhone\n    }\n\n    public getAttributes(): DogAttributes {\n        return {\n            ...super.getAttributes(),\n            ownerName: this._ownerName,\n            ownerPhone: this._ownerPhone,\n        }\n    }\n}\n\ninterface CatAttributes extends DogAttributes {}\n\nclass Cat extends Dog {\n    constructor({ ...fatherProps }: CatAttributes) {\n        super(fatherProps)\n    }\n}`)\n\nconsole.log(`\\nconst dog = new Dog({\n    averageSpeed: 48,\n    averageWeight: 80,\n    feeding: 'carnivorous',\n    name: 'Chop',\n    ownerName: 'Lucas Hoz',\n    ownerPhone: '1158946872',\n    sound: 'Woof',\n})\n\nconsole.log('\\\\nDog attributes...')\ndog.printAttributes()`)\n\nconst dog = new Dog({\n\taverageSpeed: 48,\n\taverageWeight: 80,\n\tfeeding: 'carnivorous',\n\tname: 'Chop',\n\townerName: 'Lucas Hoz',\n\townerPhone: '1158946872',\n\tsound: 'Woof',\n})\n\nconsole.log('\\nDog attributes...')\ndog.printAttributes()\n\nconsole.log(`\\nconst cat = new Cat({\n    averageSpeed: 38,\n    averageWeight: 5,\n    feeding: 'carnivorous',\n    name: 'Fifi',\n    ownerName: 'Nahuel Gonzales',\n    ownerPhone: '1145982657',\n    sound: 'Meow',\n})\n\nconsole.log('\\\\nCat attributes...')\ncat.printAttributes()`)\n\nconst cat = new Cat({\n\taverageSpeed: 38,\n\taverageWeight: 5,\n\tfeeding: 'carnivorous',\n\tname: 'Fifi',\n\townerName: 'Nahuel Gonzales',\n\townerPhone: '1145982657',\n\tsound: 'Meow',\n})\n\nconsole.log('\\nCat attributes...')\ncat.printAttributes()\n\nconsole.log('\\n# ---------------------------------------------------------------------------------- #\\n')\n\n/*\n    Additional challenge...\n*/\n\nconsole.log('Additional challenge...')\n\ntype Gender = 'F' | 'M' | 'N/A'\n\ninterface PersonAttributes {\n\tfirstName: string\n\tlastName: string\n\tphoneNumber: string\n\tage: number\n\tgender: Gender\n}\n\nclass Person {\n\tprivate _age: number\n\tprivate _firstName: string\n\tprivate _gender: Gender\n\tprivate _lastName: string\n\tprivate _phoneNumber: string\n\n\tconstructor({ age, firstName, gender, lastName, phoneNumber }: PersonAttributes) {\n\t\tthis._age = age\n\t\tthis._firstName = firstName\n\t\tthis._gender = gender\n\t\tthis._lastName = lastName\n\t\tthis._phoneNumber = phoneNumber\n\t}\n\n\tpublic set age(age) {\n\t\tthis._age = age\n\t}\n\n\tpublic set firstName(firstName) {\n\t\tthis._firstName = firstName\n\t}\n\n\tpublic set gender(gender) {\n\t\tthis._gender = gender\n\t}\n\n\tpublic set lastName(lastName) {\n\t\tthis._lastName = lastName\n\t}\n\n\tpublic set phoneNumber(phoneNumber) {\n\t\tthis._phoneNumber = phoneNumber\n\t}\n\n\tpublic get age() {\n\t\treturn this._age\n\t}\n\n\tpublic get firstName() {\n\t\treturn this._firstName\n\t}\n\n\tpublic get gender() {\n\t\treturn this._gender\n\t}\n\n\tpublic get lastName() {\n\t\treturn this._lastName\n\t}\n\n\tpublic get phoneNumber() {\n\t\treturn this._phoneNumber\n\t}\n\n\tpublic getAttributes(): PersonAttributes {\n\t\treturn {\n\t\t\tage: this._age,\n\t\t\tfirstName: this._firstName,\n\t\t\tgender: this._gender,\n\t\t\tlastName: this._lastName,\n\t\t\tphoneNumber: this._phoneNumber,\n\t\t}\n\t}\n}\n\ntype Role = 'Manager' | 'Project manager' | 'Programmer'\n\ninterface EmployeeAttributes extends PersonAttributes {\n\tid: number\n\trole: Role\n\tsalary: number\n}\n\nclass Employee extends Person {\n\tprivate _id: number\n\tprivate _role: Role\n\tprivate _salary: number\n\n\tconstructor({ id, role, salary, ...fatherProps }: EmployeeAttributes) {\n\t\tsuper(fatherProps)\n\t\tthis._id = id\n\t\tthis._role = role\n\t\tthis._salary = salary\n\t}\n\n\tpublic set id(id) {\n\t\tthis._id = id\n\t}\n\n\tpublic set role(role) {\n\t\tthis._role = role\n\t}\n\n\tpublic set salary(salary) {\n\t\tthis._salary = salary\n\t}\n\n\tpublic get id() {\n\t\treturn this._id\n\t}\n\n\tpublic get role() {\n\t\treturn this._role\n\t}\n\n\tpublic get salary() {\n\t\treturn this._salary\n\t}\n\n\tpublic getAttributes(): EmployeeAttributes {\n\t\treturn {\n\t\t\t...super.getAttributes(),\n\t\t\tid: this._id,\n\t\t\trole: this._role,\n\t\t\tsalary: this._salary,\n\t\t}\n\t}\n}\n\ninterface ManagerAttributes extends EmployeeAttributes {\n\tfunctions: string[]\n\tprojectManagers: ProjectManager[]\n}\n\nclass Manager extends Employee {\n\tprivate _functions: string[]\n\tprivate _projectManagers: ProjectManager[]\n\n\tconstructor({ functions, projectManagers, ...fatherProps }: ManagerAttributes) {\n\t\tsuper(fatherProps)\n\t\tthis._functions = functions\n\t\tthis._projectManagers = projectManagers\n\t}\n\n\tpublic set functions(functions) {\n\t\tthis._functions = functions\n\t}\n\n\tpublic set projectManagers(projectManagers) {\n\t\tthis._projectManagers = projectManagers\n\t}\n\n\tpublic get functions() {\n\t\treturn this._functions\n\t}\n\n\tpublic get projectManagers() {\n\t\treturn this._projectManagers\n\t}\n\n\tpublic getAttributes(): ManagerAttributes {\n\t\treturn {\n\t\t\t...super.getAttributes(),\n\t\t\tfunctions: this._functions,\n\t\t\tprojectManagers: this._projectManagers,\n\t\t}\n\t}\n\n\tpublic makeManagement(): string {\n\t\treturn 'Just a manager doing management things.'\n\t}\n}\n\ninterface ProjectManagerAttributes extends EmployeeAttributes {\n\tcompletedProjects: number\n\tfunctions: string[]\n\tprogrammers: Programmer<string[]>[]\n\tprojects: string[]\n}\n\nclass ProjectManager extends Employee {\n\tprivate _completedProjects: number\n\tprivate _functions: string[]\n\tprivate _programmers: Programmer<string[]>[]\n\tprivate _projects: string[]\n\n\tconstructor({ completedProjects, functions, programmers, projects, ...fatherProps }: ProjectManagerAttributes) {\n\t\tsuper(fatherProps)\n\t\tthis._completedProjects = completedProjects\n\t\tthis._functions = functions\n\t\tthis._programmers = programmers\n\t\tthis._projects = projects\n\t}\n\n\tpublic set completedProjects(completedProjects) {\n\t\tthis._completedProjects = completedProjects\n\t}\n\n\tpublic set functions(functions) {\n\t\tthis._functions = functions\n\t}\n\n\tpublic set programmers(programmers) {\n\t\tthis._programmers = programmers\n\t}\n\n\tpublic set projects(projects) {\n\t\tthis._projects = projects\n\t}\n\n\tpublic get completedProjects() {\n\t\treturn this._completedProjects\n\t}\n\n\tpublic get functions() {\n\t\treturn this._functions\n\t}\n\n\tpublic get programmers() {\n\t\treturn this._programmers\n\t}\n\n\tpublic get projects() {\n\t\treturn this._projects\n\t}\n\n\tpublic getAttributes(): ProjectManagerAttributes {\n\t\treturn {\n\t\t\t...super.getAttributes(),\n\t\t\tcompletedProjects: this._completedProjects,\n\t\t\tfunctions: this._functions,\n\t\t\tprogrammers: this._programmers,\n\t\t\tprojects: this._projects,\n\t\t}\n\t}\n\n\tpublic makeManagement(): string {\n\t\treturn 'Just a project manager doing everything expect programming.'\n\t}\n}\n\ntype Side = 'Backend' | 'Frontend' | 'Full Stack'\n\ninterface ProgrammerAttributes<T extends string[]> extends EmployeeAttributes {\n\tlanguages: T\n\tside: Side\n}\n\nclass Programmer<T extends string[]> extends Employee {\n\tprivate _languages: T\n\tprivate _side: Side\n\tprivate _yearsOfExperience: number\n\n\tconstructor({ languages, side, ...fatherProps }: ProgrammerAttributes<T>) {\n\t\tsuper(fatherProps)\n\t\tthis._languages = languages\n\t\tthis._side = side\n\t}\n\n\tpublic set languages(languages) {\n\t\tthis._languages = languages\n\t}\n\n\tpublic set side(side) {\n\t\tthis._side = side\n\t}\n\n\tpublic get languages() {\n\t\treturn this._languages\n\t}\n\n\tpublic get side() {\n\t\treturn this._side\n\t}\n\n\tpublic getAttributes(): ProgrammerAttributes<T> {\n\t\treturn {\n\t\t\t...super.getAttributes(),\n\t\t\tlanguages: this._languages,\n\t\t\tside: this._side,\n\t\t}\n\t}\n\n\tpublic writeCode(language: T[number]): string {\n\t\treturn `Writing code in ${language}`\n\t}\n}\n\nconst programmer = new Programmer({\n\tage: 22,\n\tfirstName: 'Lucas',\n\tgender: 'M',\n\tid: 0,\n\tlanguages: ['JavaScript', 'TypeScript', 'Golang', 'Python'] as const,\n\tlastName: 'Hoz',\n\tphoneNumber: '1158746859',\n\trole: 'Programmer',\n\tsalary: 2100,\n\tside: 'Frontend',\n})\n\nconsole.log('\\nProgrammer attributes...')\nconsole.table(programmer.getAttributes())\n\nconsole.log('\\nProgrammer methods...')\nconsole.log(`programmer.writeCode('TypeScript') --> ${programmer.writeCode('TypeScript')}`)\n\nconst projectManager = new ProjectManager({\n\tage: 32,\n\tcompletedProjects: 17,\n\tfirstName: 'Juan',\n\tfunctions: ['Time management'],\n\tgender: 'M',\n\tid: 1,\n\tlastName: 'Gonzales',\n\tphoneNumber: '1157486558',\n\tprogrammers: [programmer],\n\tprojects: ['Mercado Stories', 'Carrefour Delivery'],\n\trole: 'Project manager',\n\tsalary: 3000,\n})\n\nconsole.log('\\nProject manager attributes...')\nconsole.table(projectManager.getAttributes())\n\nconsole.log('\\nProject manager methods...')\nconsole.log(`projectManager.makeManagement() --> ${projectManager.makeManagement()}`)\nconsole.log(`projectManager.programmers[0].writeCode() --> ${projectManager.programmers[0].writeCode('TypeScript')}`)\n\nconst manager = new Manager({\n\tage: 45,\n\tfirstName: 'Maria',\n\tfunctions: ['Financial management', 'Time management', 'General administration'],\n\tgender: 'F',\n\tid: 3,\n\tlastName: 'Nuñez',\n\tphoneNumber: '1124585669',\n\tprojectManagers: [projectManager],\n\trole: 'Manager',\n\tsalary: 4500,\n})\n\nconsole.log('\\nManager attributes...')\nconsole.table(manager.getAttributes())\n\nconsole.log('\\nManager methods...')\nconsole.log(`manager.makeManagement() --> ${manager.makeManagement()}`)\nconsole.log(`manager.projectManagers[0].makeManagement() --> ${manager.projectManagers[0].makeManagement()}`)\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/typescript/ialmontedr0.ts",
    "content": "// Clase Padre: Animal\r\nclass Animal {\r\n  nombre: string;\r\n\r\n  constructor(nombre: string) {\r\n    this.nombre = nombre;\r\n  }\r\n\r\n  // Función virtual que deben implementar las subclases\r\n  sonido() {\r\n    return;\r\n  }\r\n}\r\n\r\n// Clase Hija: Perro\r\nclass Perro extends Animal {\r\n  sonido() {\r\n    console.log(\"GUAUUUU!\");\r\n  }\r\n}\r\n\r\n// Clase Hija: Gato\r\nclass Gato extends Animal {\r\n  sonido() {\r\n    console.log(\"MIAUUU!\");\r\n  }\r\n}\r\n\r\nconst printSound = (animal: Animal) => {\r\n  animal.sonido();\r\n};\r\n\r\n// Clase Hija: Gato\r\nlet miAnimal = new Animal(\"Tobby\");\r\nprintSound.sonido(Perro);\r\nlet miPerro = new Perro(\"Ponky\");\r\nmiPerro.sonido();\r\nlet miGato = new Gato(\"Mishi\");\r\nmiGato.sonido();\r\n\r\n// Ejercicio Extra\r\n// Clase Padre: Empleado\r\nclass Empleado {\r\n  id: number;\r\n  nombre: string;\r\n  empleados: Empleado[];\r\n\r\n  constructor(id: number, nombre: string) {\r\n      this.id = id;\r\n      this.nombre = nombre;\r\n      this.empleados = [];\r\n  }\r\n\r\n  // Métodos específicos de cada clase hija\r\n  agregarEmpleado(empleado: Empleado) {\r\n      this.empleados.push(empleado);\r\n  }\r\n\r\n  // Métodos comunes para cada clase hija\r\n  imprimirEmpleados() {\r\n      this.empleados.forEach((empleado) => {\r\n          console.log(`Empleado: ${empleado.nombre}`);\r\n      })\r\n  }\r\n}\r\n\r\n// Clase Hija: Gerente\r\nclass Gerente extends Empleado {\r\n  constructor(id: number, nombre: string) {\r\n      super(id, nombre);\r\n  }\r\n\r\n  // Métodos específicos de Gerente: imprimirEmpleados y coordinarProyectos\r\n  coordinarProyectos() {\r\n      console.log(`${this.nombre} esta coordinando los proyectos de la empresa`);\r\n  }\r\n}\r\n\r\n// Clase Hija: GerenteProyectos\r\nclass GerenteProyectos extends Empleado {\r\n  proyecto: string;\r\n  constructor(id: number, nombre: string, proyecto: string) {\r\n      super(id, nombre);\r\n      this.proyecto = proyecto;\r\n  }\r\n\r\n  // Métodos específicos de GerenteProyectos: imprimirEmpleados y coordinarProyecto\r\n  coordinarProyecto() {\r\n      console.log(`${this.nombre} esta coordinando su proyecto`);\r\n  }\r\n}\r\n\r\n// Clase Hija: Programador\r\nclass Programador extends Empleado {\r\n  lenguaje: string;\r\n  constructor(id: number, nombre: string, lenguaje: string) {\r\n      super(id, nombre);\r\n      this.lenguaje = lenguaje;\r\n  }\r\n\r\n  // Métodos específicos de Programador: imprimirEmpleados y codificar\r\n  codificar() {\r\n      console.log(`${this.nombre} esta programando en ${this.lenguaje}`);\r\n  }\r\n\r\n  // Métodos específicos de Programador: imprimirEmpleados y agregarEmpleados\r\n  agregarEmpleado(empleado: Empleado) {\r\n      console.log(\r\n          \"Un programador no tiene empleados a su cargo, \" +\r\n          empleado.nombre +\r\n          \" no se agregara\"\r\n      );\r\n  }\r\n}\r\n\r\n// Pruebas: Empleados\r\nlet miManager = new Gerente(1, \"Anthony\");\r\nlet miGerenteProyectos = new GerenteProyectos(2, \"Tony\", \"Proyecto 1\");\r\nlet miGerenteProyectos2 = new GerenteProyectos(3, \"Hector\", \"Proyecto 2\");\r\nlet miProgramador = new Programador(4, \"Anthony\", \"Typescript\");\r\nlet miProgramador2 = new Programador(5, \"Tony\", \"C++\");\r\nlet miProgramador3 = new Programador(6, \"Hector\", \"Javascript\");\r\nlet miProgramador4 = new Programador(7, \"Antonio\", \"Python\");\r\n\r\n// Agregar empleados al gerente\r\nmiManager.agregarEmpleado(miGerenteProyectos);\r\nmiManager.agregarEmpleado(miGerenteProyectos2);\r\n\r\n// Agregar empleados al gerente de proyectos\r\nmiGerenteProyectos.agregarEmpleado(miProgramador);\r\nmiGerenteProyectos.agregarEmpleado(miProgramador2);\r\nmiGerenteProyectos.agregarEmpleado(miProgramador3);\r\nmiGerenteProyectos.agregarEmpleado(miProgramador4);\r\n\r\n// Agregar empleados al programador: no se agregan empleados\r\nmiProgramador.agregarEmpleado(miProgramador2);\r\n\r\n// Codificar programador \r\nmiProgramador.codificar();\r\n\r\n// Coordinar proyectos\r\nmiGerenteProyectos.coordinarProyecto();\r\nmiManager.coordinarProyectos();\r\nmiManager.imprimirEmpleados();\r\n\r\n// Imprimir empleados\r\nmiGerenteProyectos.imprimirEmpleados();\r\nmiProgramador.imprimirEmpleados();\r\n\r\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/typescript/juserdev.ts",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n\nnamespace herencias {\n\n    class Animals{\n        animal: string\n        nombre: string\n\n        constructor(animal: string, nombre: string){\n            this.animal = animal\n            this.nombre = nombre\n        }\n\n        talk():string{\n            return `Soy un ${this.animal} y me llamo ${this.nombre} y emite un sonido no determiando`\n        }\n\n    }\n\n    class Perro extends Animals{\n        sonido: string\n\n        constructor(nombre: string, sonido: string){\n            super(\"perro\", nombre)\n            this.sonido = sonido\n        }\n\n        talk():string{\n            return `Soy un ${this.animal}, me llamo ${this.nombre} y ladro, ${this.sonido}!`\n        }\n    }\n\n    class Gato extends Animals{\n        sonido: string\n        \n        constructor(nombre: string, sonido: string){\n            super(\"gato\", nombre)\n            this.sonido = sonido\n        }\n\n        talk():string{\n            return `Soy un ${this.animal}, me llamo ${this.nombre} y maullo, ${this.sonido}!`\n        }\n    }\n\n    const loro = new Animals(\"loro\", \"theo\")\n    const perro = new Perro(\"Max\", \"guau! guau!\")\n    const gato = new Gato(\"Michi\", \"miau miau!\")\n\n    const emitirSonido = (animal: Animals): string=>{\n        return `${animal.talk()}`\n    }\n\n    console.log(emitirSonido(loro))\n    console.log(emitirSonido(perro))\n    console.log(emitirSonido(gato))\n\n    //! EXTRA\n\n    class Empleado {\n        name: string\n        id: number\n        empleados: Empleado[]\n\n        constructor(name: string, id: number) {\n            this.name = name\n            this.id = id\n            this.empleados = []\n        }\n\n        print(){\n            return `Soy un el empleado ${this.name} con id: ${this.id} sin cargo asignado`\n        }\n        \n        add(empleado: Empleado){\n            this.empleados.push(empleado)\n        }\n\n        imprimirEmpleados(){\n            let empleados: string[] = []\n            for (const empleado of this.empleados) {\n                empleados.push(empleado.name)\n            }\n            return empleados\n        }\n\n    }\n\n\n    class Gerente extends Empleado {\n        gerenciar(){\n            return `${this.name} esta coordinando todos los proyectos de la empresa`\n        }\n\n    }\n\n    class GerenteDeProyectos extends Empleado {\n        proyecto: string\n\n        constructor(name: string, id: number, proyecto: string){\n            super(name, id)\n            this.proyecto = proyecto\n        }\n\n        gerenciarDeProyectos(){\n            return `${this.name} esta coordinando su proyectos`\n        }\n        \n    }\n\n    class Programador extends Empleado {\n        lenguage: string\n\n        constructor(name: string, id: number, lenguage: string){\n            super(name, id)\n            this.lenguage = lenguage\n        }\n\n        programar(){\n            return `${this.name} esta programando en ${this.lenguage}`\n        }\n\n        add(empleado: Empleado): string{\n            return `Un programador no tinene empleados a cargo, ${empleado.name} no se añadira`\n        }\n\n    }\n\n    const miGerente = new Gerente(\"Sebastian\", 1)\n    const miGerenteDeProyectos = new GerenteDeProyectos(\"Laura\", 2, \"Proyecto 1\")\n    const miGerenteDeProyectos2 = new GerenteDeProyectos(\"Daniela\", 3, \"Proyecto 2\")\n    const miProgramador = new Programador(\"Juan\", 4, \"JavaScript\")\n    const miProgramador2 = new Programador(\"JuanSe\", 5, \"TypeScript\")\n    const miProgramador3 = new Programador(\"Sebas\", 6, \"Pyton\")\n    const miProgramador4 = new Programador(\"Michael\", 7, \"Java\")\n\n    miGerente.add(miGerenteDeProyectos)\n    miGerente.add(miGerenteDeProyectos2)\n\n    miGerenteDeProyectos.add(miProgramador)\n    miGerenteDeProyectos.add(miProgramador2)\n    miGerenteDeProyectos2.add(miProgramador3)\n    miGerenteDeProyectos2.add(miProgramador4)\n\n    console.log(miProgramador.add(miProgramador2))\n    console.log(miGerente.print())\n\n    console.log(miProgramador.programar())\n    console.log(miProgramador2.programar())\n    console.log(miProgramador3.programar())\n    console.log(miProgramador4.programar())\n    console.log(miGerenteDeProyectos.gerenciarDeProyectos())\n    console.log(miGerenteDeProyectos2.gerenciarDeProyectos())\n    console.log(miGerente.gerenciar())\n\n    console.log(miGerente.imprimirEmpleados())\n    console.log(miGerenteDeProyectos.imprimirEmpleados())\n    console.log(miGerenteDeProyectos2.imprimirEmpleados())\n    console.log(miProgramador.imprimirEmpleados())\n}"
  },
  {
    "path": "Roadmap/09 - HERENCIA/typescript/marcode24.ts",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n\n// Superclase Animal\nclass Animal {\n  nombre: string;\n\n  constructor(nombre: string) {\n    this.nombre = nombre;\n  }\n\n  // Método para imprimir el sonido del animal\n  hacerSonido(): void {\n    console.log('El animal hace un sonido');\n  }\n}\n\n// Subclase Perro que hereda de Animal\nclass Perro extends Animal {\n  constructor(nombre: string) {\n    super(nombre);\n  }\n\n  // Método para imprimir el ladrido del perro\n  hacerSonido(): void {\n    console.log(`El perro ${this.nombre} hace guau`);\n  }\n}\n\n// Subclase Gato que hereda de Animal\nclass Gato extends Animal {\n  constructor(nombre: string) {\n    super(nombre);\n  }\n\n  // Método para imprimir el maullido del gato\n  hacerSonido(): void {\n    console.log(`El gato ${this.nombre} hace miau`);\n  }\n}\n\n// Crear instancias de Perro y Gato\nconst miPerro: Perro = new Perro('Bobby');\nconst miGato: Gato = new Gato('Whiskers');\n\n// Llamar al método para hacer sonido de cada animal\nmiPerro.hacerSonido(); // Imprime: El perro Bobby hace guau\nmiGato.hacerSonido(); // Imprime: El gato Whiskers hace miau\n\n// Visita mi repo en GitHub para ver y correr los tests de este código --> https://github.com/marcode24/weekly-challenges\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/typescript/miguelex.ts",
    "content": "class Animal {\n    nombre: string;\n    sonido: string;\n\n    constructor(nombre: string, sonido: string) {\n        this.nombre = nombre;\n        this.sonido = sonido;\n    }\n}\n\nclass Perro extends Animal {\n    constructor(nombre: string, sonido: string) {\n        super(nombre, sonido);\n    }\n\n    get Sonido(): string {\n        return `El perro ${this.nombre} hace ${this.sonido}!`;\n    }\n}\n\nclass Gato extends Animal {\n    constructor(nombre: string, sonido: string) {\n        super(nombre, sonido);\n    }\n\n    get Sonido(): string {\n        return `El gato ${this.nombre} hace ${this.sonido}!`;\n    }\n}\n\nconst milu = new Perro('Milu', 'Guau, guau');\nconsole.log(milu.Sonido);\n\nconst garfield = new Gato('Garfield', 'Miauuuu');\nconsole.log(garfield.Sonido);\n\n// Extra\n\nclass Empleado {\n    id: number;\n    nombre: string;\n\n    constructor(id: number, nombre: string) {\n        this.id = id;\n        this.nombre = nombre;\n    }\n}\n\nclass Gerente extends Empleado {\n    empleados: string[];\n\n    constructor(id: number, nombre: string, empleados: string[]) {\n        super(id, nombre);\n        this.empleados = empleados;\n    }\n\n    get gestiona(): string {\n        return `El gerente ${this.nombre} gestiona a ${this.empleados.length} empleados, que son ${this.empleados.join(\", \")}.`;\n    }\n}\n\nclass GerenteP extends Empleado {\n    empleados: string[];\n\n    constructor(id: number, nombre: string, empleados: string[]) {\n        super(id, nombre);\n        this.empleados = empleados;\n    }\n\n    get gestiona(): string {\n        return `El gerente ${this.nombre} gestiona a ${this.empleados.length} empleados, que son ${this.empleados.join(\", \")}.`;\n    }\n}\n\nclass Programador extends Empleado {\n    lenguajes: string[];\n\n    constructor(id: number, nombre: string, lenguajes: string[]) {\n        super(id, nombre);\n        this.lenguajes = lenguajes;\n    }\n\n    get programa(): string {\n        return `El programador ${this.nombre} programa en ${this.lenguajes.join(\", \")}.`;\n    }\n}\n\nconst gerente = new Gerente(1, 'Migue', ['Ana', 'Pedro', 'Luis']);\nconsole.log(gerente.gestiona);\n\nconst gerenteP = new GerenteP(2, 'Ana', ['Rafa', 'Maria', 'Luisa']);\nconsole.log(gerenteP.gestiona);\n\nconst programador = new Programador(3, 'Pedro', ['JavaScript', 'Python', 'Java']);\nconsole.log(programador.programa);\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/typescript/nlarrea.ts",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n * implemente una superclase Animal y un par de subclases Perro y Gato,\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n *\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n\n\nclass Animal {\n    name: string\n\n    constructor(name: string) {\n        this.name = name\n    }\n\n    sound() {\n        console.log('-')\n    }\n}\n\n\nclass Dog extends Animal {\n    sound(): void {\n        console.log('Guau!')\n    }\n}\n\n\nclass Cat extends Animal {\n    sound(): void {\n        console.log('Miau!')\n    }\n}\n\n\nconst myDog = new Dog('Lagun')\nmyDog.sound()  // Guau!\n\nconst myCat = new Cat('Kira')\nmyCat.sound()  // Miau!\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n * Cada empleado tiene un identificador y un nombre.\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n * actividad, y almacenan los empleados a su cargo.\n */\n\n\nclass Employee {\n    id: number\n    name: string\n    employees: any[]\n\n    constructor(id: number, name: string) {\n        this.id = id\n        this.name = name\n        this.employees = []\n    }\n\n    add(employee: ProjectManager | Programmer) {\n        this.employees.push(employee)\n    }\n\n    printEmployees() {\n        if (this.employees.length === 0) {\n            console.log(`${this.name} has no employees.`)\n        } else {\n            console.log(`\\n${this.name}'s employees:`)\n            for (const employee of this.employees) {\n                console.log(` - ${employee.name}`)\n            }\n        }\n    }\n}\n\n\nclass Manager extends Employee {\n    coordinate() {\n        console.log(`\\n${this.name} is coordinating all the company's projects`)\n    }\n}\n\n\nclass ProjectManager extends Employee {\n    project: string\n\n    constructor(id: number, name: string, project: string) {\n        super(id, name)\n        this.project = project\n    }\n\n    coordinate() {\n        console.log(`\\n${this.name} is coordinating: ${this.project}`)\n    }\n}\n\n\nclass Programmer extends Employee {\n    language: string\n\n    constructor(id: number, name: string, language: string) {\n        super(id, name)\n        this.language = language\n    }\n\n    code() {\n        console.log(`\\n${this.name} is programming using ${this.language} language`)\n    }\n\n    add(employee: ProjectManager | Programmer) {\n        console.log('\\nA programmer has no employees.')\n        console.log(`${employee.name} won't be added.`)\n    }\n}\n\n\n// Initializing employees\nconst myManager = new Manager(1, 'ManagerName')\n\nconst myPm1 = new ProjectManager(2, 'PM1', 'Project 1')\nconst myPm2 = new ProjectManager(3, 'PM2', 'Project 2')\n\nconst myProgrammer1 = new Programmer(4, 'P1', 'Python')\nconst myProgrammer2 = new Programmer(5, 'P2', 'JavaScript')\nconst myProgrammer3 = new Programmer(6, 'P3', 'TypeScript')\nconst myProgrammer4 = new Programmer(7, 'P4', 'SQL')\n\n\n// Adding employees\nmyManager.add(myPm1)\nmyManager.add(myPm2)\n\nmyPm1.add(myProgrammer1)\nmyPm1.add(myProgrammer2)\n\nmyPm2.add(myProgrammer3)\nmyPm2.add(myProgrammer4)\n\nmyProgrammer1.add(myProgrammer4)  // won't work\n/**\n * Prints:\n * A programmer has no employees.\n * P4 won't be added.\n */\n\n\n// Tasks\nmyManager.coordinate()\n// ManagerName is coordinating all of the company's projects\n\nmyPm1.coordinate()\n// PM1 is coordinating: Project 1\n\nmyProgrammer1.code()\n// P1 is programming using Python language\nmyProgrammer2.code()\n// P1 is programming using JavaScript language\n\nmyPm1.printEmployees()\n/**\n * Prints:\n * PM1's employees:\n *  - P1\n *  - P2\n */\n\nmyManager.printEmployees()\n/**\n * Prints:\n * ManagerName's employees:\n *  - PM1\n *  - PM2\n */\n\nmyProgrammer1.printEmployees()\n// P1 has no employees"
  },
  {
    "path": "Roadmap/09 - HERENCIA/typescript/qwik-zgheib.ts",
    "content": "/* -- exercise */\nclass Animal {\n  name: string;\n\n  constructor(name: string) {\n    this.name = name;\n  }\n\n  makeSound(): void {\n    console.log(`${this.name} makes a sound.`);\n  }\n}\n\nclass Dog extends Animal {\n  constructor(name: string) {\n    super(name);\n  }\n\n  makeSound(): void {\n    console.log(`${this.name} says: Woof! Woof!`);\n  }\n}\n\nclass Cat extends Animal {\n  constructor(name: string) {\n    super(name);\n  }\n\n  makeSound(): void {\n    console.log(`${this.name} says: Meow! Meow!`);\n  }\n}\n\nfunction printAnimalSound(animal: Animal): void {\n  animal.makeSound();\n}\n\nlet dog = new Dog(\"Firulais\");\nlet cat = new Cat(\"Silvester\");\n\nprintAnimalSound(dog);\nprintAnimalSound(cat);\n\n/* -- extra challenge */\nclass Employee {\n  id: number;\n  name: string;\n\n  constructor(id: number, name: string) {\n    this.id = id;\n    this.name = name;\n  }\n\n  printDetails(): void {\n    console.log(`ID: ${this.id}, Name: ${this.name}`);\n  }\n}\n\nclass Manager extends Employee {\n  employeesInCharge: Employee[];\n\n  constructor(id: number, name: string) {\n    super(id, name);\n    this.employeesInCharge = [];\n  }\n\n  addEmployee(employee: Employee): void {\n    this.employeesInCharge.push(employee);\n  }\n\n  printDetails(): void {\n    super.printDetails();\n    console.log(\"Employees under this manager:\");\n    this.employeesInCharge.forEach((emp) => emp.printDetails());\n  }\n}\n\nclass ProjectManager extends Manager {\n  project: string;\n\n  constructor(id: number, name: string, project: string) {\n    super(id, name);\n    this.project = project;\n  }\n\n  printDetails(): void {\n    super.printDetails();\n    console.log(`Project: ${this.project}`);\n  }\n}\n\nclass Programmer extends Employee {\n  language: string;\n\n  constructor(id: number, name: string, language: string) {\n    super(id, name);\n    this.language = language;\n  }\n\n  printDetails(): void {\n    super.printDetails();\n    console.log(`Programming Language: ${this.language}`);\n  }\n}\n\nlet manager = new Manager(1, \"Alice\");\nlet projectManager = new ProjectManager(2, \"Bob\", \"Project X\");\nlet programmer1 = new Programmer(3, \"Charlie\", \"JavaScript\");\nlet programmer2 = new Programmer(4, \"David\", \"Python\");\n\nmanager.addEmployee(programmer1);\nprojectManager.addEmployee(programmer2);\nmanager.printDetails();\nprojectManager.printDetails();\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/typescript/victor-Casta.ts",
    "content": "/*\n  * EJERCICIO:\n  * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\n  * implemente una superclase Animal y un par de subclases Perro y Gato,\n  * junto con una función que sirva para imprimir el sonido que emite cada Animal.\n*/\n\nabstract class Animal {\n  protected readonly name: string\n  protected readonly age: number\n  protected readonly color: string\n\n  constructor(name: string, age: number, color: string) {\n    this.name = name\n    this.age = age\n    this.color = color\n  }\n\n  abstract sound(): void\n}\n\nclass Cat extends Animal {\n  sound(): void {\n    console.log(`${this.name} el gato hace \"Miau!\"`)\n  }\n}\n\nclass Dog extends Animal {\n  sound(): void {\n    console.log(`${this.name} el perro hace \"Guau!\"`)\n  }\n}\n\nconst dog1: Dog = new Dog('Max', 2, 'café')\ndog1.sound()\n\nconst cat1: Cat = new Cat('Michi', 1, 'negro')\ncat1.sound()\n\n/*\n  * DIFICULTAD EXTRA (opcional):\n  * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\n  * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n  * Cada empleado tiene un identificador y un nombre.\n  * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n  * actividad, y almacenan los empleados a su cargo.\n*/\n\nclass Employee {\n  protected readonly id: number\n  protected name: string\n\n  constructor(id: number, name: string) {\n    this.id = id\n    this.name = name\n  }\n\n  displayInfo(): void {\n    console.log(`ID: ${this.id}, Name: ${this.name}`)\n  }\n}\n\nclass Manager extends Employee {\n  private employees: string[] = []\n\n  constructor(id: number, name: string, employees: string[] = []) {\n    super(id, name)\n    this.employees = employees\n  }\n\n  addEmployee(employee: string): void {\n    this.employees.push(employee)\n  }\n\n  getEmployees(): string[] {\n    return this.employees\n  }\n\n  displayInfo(): void {\n    super.displayInfo()\n    console.log(`Managed Employees: ${this.employees.join(', ') || 'No employees'}`)\n  }\n}\n\nclass ProjectManager extends Employee {\n  private projects: string[] = []\n\n  constructor(id: number, name: string, projects: string[] = []) {\n    super(id, name)\n    this.projects = projects\n  }\n\n  addProject(projectName: string): void {\n    this.projects.push(projectName)\n  }\n\n  getProjects(): string[] {\n    return this.projects\n  }\n\n  displayInfo(): void {\n    super.displayInfo()\n    console.log(`Projects: ${this.projects.join(', ') || 'No projects'}`)\n  }\n}\n\nclass Developer extends Employee {\n  private skills: string[] = []\n\n  constructor(id: number, name: string, skills: string[] = []) {\n    super(id, name)\n    this.skills = skills\n  }\n\n  addSkill(skill: string): void {\n    if (!this.skills.includes(skill)) {\n      this.skills.push(skill)\n    } else {\n      console.log(`${this.name} already has skill: ${skill}`)\n    }\n  }\n\n  getSkills(): string[] {\n    return this.skills\n  }\n\n  displayInfo(): void {\n    super.displayInfo()\n    console.log(`Skills: ${this.skills.join(', ') || 'No skills'}`)\n  }\n}\n\n\nconst manager = new Manager(1, \"Alice\", [\"Bob\", \"Charlie\"])\nmanager.addEmployee(\"Dave\")\nmanager.displayInfo()\n\nconst projectManager = new ProjectManager(2, \"Eve\", [\"Project A\", \"Project B\"])\nprojectManager.addProject(\"Project C\")\nprojectManager.displayInfo()\n\nconst developer = new Developer(3, \"Tom\", [\"JavaScript\", \"TypeScript\"])\ndeveloper.addSkill(\"React\")\ndeveloper.addSkill(\"JavaScript\")\ndeveloper.displayInfo()\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/typescript/victoriaparraf.ts",
    "content": "//Superclase\nclass Animal{\n    //Atributos comunes\n    nombre: string;\n    color: string;\n    //constructor\n    constructor(nombre: string, color: string){\n        this.nombre = nombre;\n        this.color = color;\n    }\n    //Metodo comun\n    emitirSonido(): void{\n        console.log(`${this.nombre} hace un sonido`);\n    }\n}\n// Subclase Perro\nclass Perro extends Animal{\n    // Constructor que llama al constructor de la superclase\n    constructor(nombre: string, color: string){\n        super(nombre,color);\n    }\n    // Sobrescribir el método emitirSonido\n    emitirSonido(): void {\n        console.log(`${this.nombre} dice: Guau`);\n    }\n}\n\n// Subclase Perro\nclass Gato extends Animal{\n    // Constructor que llama al constructor de la superclase\n    constructor(nombre: string, color: string){\n        super(nombre,color);\n    }\n    // Sobrescribir el método emitirSonido\n    emitirSonido(): void {\n        console.log(`${this.nombre} dice: Miau`);\n    }\n}\n\n// Función para imprimir el sonido que emite un Animal\nfunction imprimirSonido(animal: Animal): void {\n    animal.emitirSonido();\n}\n\nlet miPerro = new Perro('Rex','Negro');\nlet miGato = new Gato('Whiskers','Blanco');\n\nimprimirSonido(miPerro); // Rex dice: ¡Guau!\nimprimirSonido(miGato); // Whiskers dice: ¡Miau!\n\n/******************************/\n/*Extra*/\n\nclass Empleado{\n    id: number;\n    nombre: string;\n    apellido: string;\n    telefono: number;\n    empleadoACargo: Empleado[]=[];\n    \n    constructor(id:number,nombre:string,apellido:string,telefono:number){\n        this.id = id;\n        this.nombre =nombre;\n        this.apellido = apellido;\n        this.telefono = telefono;\n    }\n\n    agregarEmpleadoACargo(empleado:Empleado): void{\n        this.empleadoACargo.push(empleado);\n    }\n\n    imprimirDetalles(): void{\n        console.log(`ID: ${this.id}, Nombre: ${this.nombre}, Apellido: ${this.apellido}, Telefono: ${this.telefono}`)\n    }\n}\n\nclass Gerente extends Empleado{\n    departamento: string;\n\n    constructor(id:number,nombre:string,apellido:string,telefono:number,departamento:string){\n        super(id,nombre,apellido,telefono);\n        this.departamento = departamento;\n    }\n\n    imprimirDetalles(): void {\n        super.imprimirDetalles;\n        console.log(`Departamento: ${this.departamento}`);\n        console.log(`Empleados a Cargo: ${this.empleadoACargo.map(e => e.nombre).join(\", \")}`);\n    }\n}\n\nclass GerenteDeProyectos extends Empleado {\n    proyectos: string[];\n    // Constructor\n    constructor(id:number,nombre:string,apellido:string,telefono:number, proyectos: string[]) {\n        super(id,nombre,apellido,telefono);\n        this.proyectos = proyectos;\n    }\n\n    // Método específico del Gerente de Proyectos\n    imprimirDetalles(): void {\n        super.imprimirDetalles();\n        console.log(`Proyectos: ${this.proyectos.join(\", \")}`);\n        console.log(`Empleados a Cargo: ${this.empleadoACargo.map(e => e.nombre).join(\", \")}`);\n    }\n}\n\n// Subclase Programador\nclass Programador extends Empleado {\n    // Propiedades específicas del Programador\n    lenguajes: string[];\n\n    // Constructor\n    constructor(id: number, nombre: string,apellido:string,telefono:number, lenguajes: string[]) {\n        super(id,nombre,apellido,telefono);\n        this.lenguajes = lenguajes;\n    }\n\n    // Método específico del Programador\n    imprimirDetalles(): void {\n        super.imprimirDetalles();\n        console.log(`Lenguajes: ${this.lenguajes.join(\", \")}`);\n    }\n}\n\n// Crear instancias de los empleados\nlet gerente = new Gerente(1,'Carlos','Pereira',4439357, 'Desarrollo');\nlet gerenteDeProyectos = new GerenteDeProyectos(2, 'Ana','Fernandez',9720435, ['Proyecto A', 'Proyecto B']);\nlet programador1 = new Programador(3, 'Juan','Machado',4722585, ['JavaScript', 'TypeScript']);\nlet programador2 = new Programador(4, 'Laura','Martinez',4425157, ['Python', 'Django']);\n\n// Asignar empleados a cargo\ngerente.agregarEmpleadoACargo(gerenteDeProyectos);\ngerenteDeProyectos.agregarEmpleadoACargo(programador1);\ngerenteDeProyectos.agregarEmpleadoACargo(programador2);\n\n// Imprimir detalles de cada empleado\ngerente.imprimirDetalles();\ngerenteDeProyectos.imprimirDetalles();\nprogramador1.imprimirDetalles();\nprogramador2.imprimirDetalles();\n\n\n"
  },
  {
    "path": "Roadmap/09 - HERENCIA/vb.net/kenysdev.vb",
    "content": "' ╔══════════════════════════════════════╗\n' ║ Autor:  Kenys Alvarado               ║\n' ║ GitHub: https://github.com/Kenysdev  ║\n' ║ 2024 -  VB.NET                       ║\n' ╚══════════════════════════════════════╝\nModule Program\n    '------------------------------------------\n    '# Herencia\n    '------------------------------------------\n    '- Permite definir una clase que hereda atributos y métodos de una \n    '  clase existente, para reutilización y organización.\n    '- La clase que hereda se conoce como “subclase” o “clase hija”.\n    '- La clase de la que hereda se conoce como “superclase” o “clase padre”.\n\n    ' Polimorfismo:\n    ' ----------------------------------------\n    ' - Los objetos de diferentes clases pueden ser accedidos utilizando el \n    '   mismo interfaz, mostrando un comportamiento distinto \n    '   (tomando diferentes formas) según cómo sean accedidos. */\n\n    ' SuperClase\n    Public Class Animal\n        Public Property Name As String\n        Public Property Sound As String\n\n        Public Sub New(ByVal name As String, ByVal sound As String)\n            Me.Name = name\n            Me.Sound = sound\n        End Sub\n\n        Public Sub MakeSound()\n            Console.WriteLine($\"{Name} hace: {Sound}\")\n        End Sub\n    End Class\n\n    ' Subclases\n    Public Class Dog\n        Inherits Animal\n        Public Sub New(ByVal name As String)\n            MyBase.New(name, \"Woof\")\n        End Sub\n    End Class\n\n    Public Class Cat\n        Inherits Animal\n        Public Sub New(ByVal name As String)\n            MyBase.New(name, \"Meow\")\n        End Sub\n    End Class\n\n    ''____________________________________________________\n    '* Ejercicio usando herencia y Polimorfismo.\n    '- Implementa la jerarquía de una empresa de desarrollo formada por \n    '  empleados que pueden ser Gerentes, Gerentes de Proyectos o Programadores.\n    '- Cada empleado tiene un identificador y un nombre.\n    '- Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\n    '  actividad, y almacenan los empleados a su cargo. */\n\n    ' Clase Employees\n    Public Class Employees\n        Public Shared employees As New List(Of String())\n        Public identifier As String = \"\"\n        Public tasks As New HashSet(Of String)()\n        Public staff As New HashSet(Of String)()\n\n        Public Sub Add(ParamArray names As String())\n            For Each name In names\n                employees.Add({identifier, name})\n            Next\n        End Sub\n\n        Public Sub Print()\n            For Each employee In employees\n                If employee(0) = identifier Then\n                    Console.WriteLine($\"{employee(1)} -> {identifier}\")\n                End If\n            Next\n        End Sub\n\n        Public Sub Functions()\n            Console.WriteLine(vbCrLf + $\"Funciones de {identifier}\")\n            For Each task In tasks\n                Console.WriteLine(task)\n            Next\n            Console.WriteLine(\"--------------------\")\n        End Sub\n\n        Public Sub Subordinates()\n            Console.WriteLine(vbCrLf + $\"Subordinados de un {identifier}\")\n            For Each employee In employees\n                If staff.Contains(employee(0)) Then\n                    Console.WriteLine($\"{employee(1)} -> {employee(0)}\")\n                End If\n            Next\n            Console.WriteLine(\"--------------------\")\n        End Sub\n    End Class\n\n    ' Subclases de Employees\n    Public Class Manager\n        Inherits Employees\n        Public Sub New()\n            identifier = \"Gerente\"\n            tasks = New HashSet(Of String)({\"- Supervisión\", \"- Toma de decisiones\"})\n            staff = New HashSet(Of String)({\"Gerente de Proyecto\", \"Programador\"})\n        End Sub\n    End Class\n\n    Public Class ProjectManager\n        Inherits Employees\n        Public Sub New()\n            identifier = \"Gerente de Proyecto\"\n            tasks = New HashSet(Of String)({\"- Planificación\", \"- Coordinación de proyectos\"})\n            staff = New HashSet(Of String)({\"Programador\"})\n        End Sub\n    End Class\n\n    Public Class Programmer\n        Inherits Employees\n        Public Sub New()\n            identifier = \"Programador\"\n            tasks = New HashSet(Of String)({\"- Desarrollo\", \"- Mantenimiento de código\"})\n            staff = New HashSet(Of String)({\"No tiene subordinados\"})\n        End Sub\n    End Class\n\n    ''____________________________________________________\n    Sub Main()\n        Dim dog As New Dog(\"Max\")\n        Dim cat As New Cat(\"Milo\")\n        dog.MakeSound()\n        cat.MakeSound()\n\n        Dim manager As New Manager()\n        Dim projectManager As New ProjectManager()\n        Dim programmer As New Programmer()\n\n        manager.Add(\"Ben\", \"Dan\")\n        projectManager.Add(\"Ray\", \"Joe\")\n        programmer.Add(\"Leo\", \"Sam\", \"Zoe\", \"Ana\")\n\n        manager.Functions()\n        projectManager.Functions()\n        programmer.Functions()\n\n        manager.Subordinates()\n        projectManager.Subordinates()\n\n        Console.WriteLine(\"Total:\")\n        manager.Print()\n        projectManager.Print()\n        programmer.Print()\n    End Sub\nEnd Module\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/bash/rantamhack.sh",
    "content": "#!/bin/bash\n\necho -e \"\\n\\n=====================================Â¿QUE ES UNA EXCEPCION?=====================================\\n\\n\"\n\n\necho -e \"Al programar en Bash algunas veces podemos anticipar errores de ejecucion, incluso en un programa sintactica y\\nlogicamente correcto, pueden llegar a haber errores causados por entrada de datos invalidos o inconsistencias predecibles.\"\n\necho -e \"\\n\\n=====================================EJERCICIO=====================================\\n\\n\"\n\n\n# Explora el concepto de manejo de excepciones segun tu lenguaje.\n# Fuerza un error en tu codigo, captura el error, imprime dicho error\n# y evita que el programa se detenga de manera inesperada.\n# Prueba a dividir \"10/0\" o acceder a un i­ndice no existente\n# de un listado para intentar provocar un error \n\n\n\n\nfunction index_error() {\n\n    my_list=(1 2 3 4) \n\n    if [ ${#my_list[@]} -lt 5 ]; then\n        echo -e \"\\nEl elemento no existe en my_list\"\n        echo -e \"\\nEl estado de salida es: ${?}\"\n    else\n        echo ${my_list[4]}\n    fi\n}\n\nindex_error\n\necho -e \"\\nEl programa continua\"\n\necho -e \"\\n\\n=====================================EJERCICIO=====================================\\n\\n\"\n\nfunction division_zero() { \n\n    a=10 \n    b=0 \n\n    if [ ${b} == 0 ]; then\n        echo -e \"\\nDividir por cero no es posible\"\n        echo -e \"\\nEl estado de salida es: ${?}\"\n    else\n        division=$(( a/b ))\n        echo $division\n    fi\n}\n\ndivision_zero\n\necho -e \"\\nEl programa continua\"\n\necho -e \"\\n\\n=====================================DIFICULTAD EXTRA=====================================\\n\\n\"\n\n\n\n# Crea una funcion que sea capaz de procesar parametros, pero que tambien\n# pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n# corresponderse con un tipo de excepcion creada por nosotros de manera\n# personalizada, y debe ser lanzada de manera manual) en caso de error.\n# Captura todas las excepciones desde el lugar donde llamas a la funcion.\n# Imprime el tipo de error.\n# Imprime si no se ha producido ningun error.\n# Imprime que la ejecucion ha finalizado '\n\nfunction process_params(){\n\n    if [ $# -lt 3 ]; then\n        echo -e \"\\nEl numero de elementos de la lista debe ser mayor que dos\"\n        #exit 1\n    elif [ $2 -eq 0 ]; then\n        echo -e \"\\nEl segundo elemento de la lista no puede ser un cero\"\n        #exit 1\n    elif [ -z \"$3\" ]; then\n        echo -e \"\\nEl tercer elemento no puede ser una cadena de texto\"\n        #exit 1\n    else\n        echo -e \"\\No se ha producido ningun error\"\n    fi\n\n    echo $3\n    echo $(($1 / $2))\n    echo $(($3 + 5))\n}\n\nprocess_params 1 2 3 4 || echo -e \"\\nSe ha producido un error inesperado\"\n\necho -e \"\\nEl programa continua\"\n\necho -e \"\\nEl programa ha finalizado\"\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/c#/Andreavzqz.cs",
    "content": "using System;\n\nnamespace ManejoDeExcepciones\n{\n\n    //Excepción personalizada\n    public class ExcepcionPersonalizada : Exception\n    {\n        public ExcepcionPersonalizada(string mensaje) { }\n    }\n\n    class Program\n    {\n        static void Main(string [] args)\n        {\n\n            // Parte 1: Forzar un error dividiendo por cero y capturarlo\n            try\n            {\n                int resultado = 10 / 0;\n            }\n\n            catch (DivideByZeroException ex)\n            {\n                Console.WriteLine($\"Error: {ex.Menssage}\");\n            }\n\n            // Parte 2: Funcion que lanza diferentes excepciones\n            try\n            {\n                ProcesarParametros(0);\n                ProcesarParametros(-1);\n                ProcesarParametros(100);\n            }\n\n            catch (ArgumentOutOfRangeException ex)\n            {\n                Console.WriteLine($\"Error de rango: {ex.Menssage}\");\n            }\n\n            catch (ArgumentException ex)\n            {\n                Console.WriteLine($\"Error de argumento: {ex.Menssage}\");\n            }\n\n            catch (ExcepcionPersonalizada ex)\n            {\n                Console.WriteLine($\"Error personalizado: {ex.Menssage}\");\n            }\n\n            catch (Exception ex)\n            {\n                Console.WriteLine($\"Error desconocido: {ex.Menssage}\");\n            }\n\n            finally\n            {\n                Console.WriteLine(\"La ejecucion ha finalizado.\");\n            }\n        }\n\n        // Funcion que lanza diferentes excepciones\n        static void ProcesarParametros(int valor)\n        {\n            if (valor == 0)\n            {\n                throw new ArgumentOutOfRangeException(nameof(valor), \"El valor no puede ser cero\");\n            }\n\n            else if (valor < 0)\n            {\n                throw new ArgumentException(\"El valor no puede ser negativo.\");\n            }\n\n            else if (valor > 10)\n            {\n                throw new ExcepcionPersonalizada(\"El valor no puede ser mayor que 10.\");\n            }\n\n            else \n            {\n                Console.WriteLine(\"Parametro procesado correctamente.\");\n            }\n        }\n    }\n  /*\n\nExplicación\n\nExcepción personalizada:\nCreamos una clase ExcepcionPersonalizada que hereda de Exception y define un constructor que toma un mensaje de error.\n\nMain:\nParte 1: Intentamos dividir por cero y capturamos la excepción DivideByZeroException.\nParte 2: Llamamos a la función ProcesarParametros con diferentes valores que pueden causar excepciones. Capturamos cada tipo de excepción específica (ArgumentOutOfRangeException, ArgumentException y ExcepcionPersonalizada), así como una excepción general Exception para cualquier otro tipo de error no previsto. Finalmente, usamos un bloque finally para imprimir que la ejecución ha finalizado.\n\nFunción ProcesarParametros:\nLanza una ArgumentOutOfRangeException si el valor es cero.\nLanza una ArgumentException si el valor es negativo.\nLanza una ExcepcionPersonalizada si el valor es mayor que 10.\n\n\n*/\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/c#/charlerodriguez3.cs",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado.\n */\n\n \n\nConsole.WriteLine(\"Vamos a dividir\");\nConsole.WriteLine(\"digita un numero\");\nint num = Convert.ToInt32(Console.ReadLine());\n\nConsole.WriteLine(\"digita otro numero\");\nint num2 = Convert.ToInt32(Console.ReadLine());\n\ntry\n{\n    Console.WriteLine(\"La division es\" + num / num2);\n\n}\ncatch(DivideByZeroException ex)\n{\n    Console.WriteLine(\"No puedes dividir entre cero: \" + ex.Message);\n}\n\nConsole.WriteLine(\"Volvemos a dividir (por defecto 1), Resultado:\" + num / 1);\n\n\n\n\ntry\n{\n    processParametros(new List<int> {-1,1,2,7,4,5,12});\n}\ncatch(InvalidDataException ex)\n{\n    Console.WriteLine(\"El cuarto elemento no puede tener valor de 3: \" + ex.Message);\n}catch(DivideByZeroException ex)\n{\n    Console.WriteLine(\"No puede dividir entre cero: \" + ex.Message);\n}catch(IndexOutOfRangeException ex)\n{\n    Console.WriteLine(\"No puede acceder a una posicion que no existe dentro de la lista: \" + ex.Message);\n}catch(Exception ex)\n{\n    Console.WriteLine(\"Ha ocurrido un error inesperado: \" + ex.Message);\n}\nfinally\n{\n    Console.WriteLine(\"Fin del programa\");\n}\n\n\nstatic void processParametros(List<int> numeros)\n{\n    if (numeros[3] == 3)\n    {\n        throw new InvalidDataException();\n    }else if (numeros[0] == 0)\n    {\n        throw new DivideByZeroException();\n    }else if (numeros[6] == 10)\n    {\n        throw new IndexOutOfRangeException();\n    }\n\n    Console.WriteLine(numeros[3]);\n    Console.WriteLine(numeros[4] /numeros[0]);\n    Console.WriteLine(numeros[1]+numeros[3]);\n\n}"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/c#/devcherry1.py",
    "content": "using System;\nclass Program\n{\n    static void Main()\n    {\n        List<string> nombres = new List<string>() { \"Anna\", \"Carlos\" };\n        try\n        {\n            Console.WriteLine(nombres[2]);\n        }\n        catch (Exception ex)\n        {\n            // Manejo genérico para cualquier excepción.\n            Console.WriteLine($\"Ocurrió un error: {ex.Message}\");\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/c#/estuardodev.cs",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado. \n */\n\n \nusing System.Reflection.Metadata;\n\nnamespace AppParaRetos\n{\n    public class estuardodev\n    {\n        public static void Main(string[] args)\n        {\n            // Ejercicio\n            Console.WriteLine(\"-------------------\");\n            try\n            {\n                Console.WriteLine(\"Ingresa un numero para dividir 10: \");\n                var numero = Convert.ToInt32(Console.ReadLine());\n                Console.WriteLine(10 / numero);\n            }\n            catch(Exception e)\n            {\n                Console.WriteLine(e.Message);\n                Console.WriteLine(\"Siguó el programa luego del error\");\n            }\n            Console.WriteLine(\"-------------------\");\n\n            try\n            {\n                ProcesarParametros(\"parametro\");\n                Console.WriteLine(\"No se ha producido ningún error.\");\n            }\n            catch (ArgumentException ex)\n            {\n                Console.WriteLine(\"Error de argumento: \" + ex.Message);\n            }\n            catch (FormatException ex)\n            {\n                Console.WriteLine(\"Error de formato: \" + ex.Message);\n            }\n            catch (ProcesamientoException ex)\n            {\n                Console.WriteLine(\"Error personalizado: \" + ex.Message);\n            }\n            catch (Exception ex)\n            {\n                Console.WriteLine(\"Error general: \" + ex.Message);\n            }\n\n            Console.WriteLine(\"La ejecucción finalizo.\");\n        }\n\n        // Difucltad Extra\n        public static void ProcesarParametros(string parametro)\n        {\n            if (string.IsNullOrEmpty(parametro))\n            {\n                throw new ArgumentException(\"El parámetro no puede ser nulo ni vacío.\");\n            }\n\n            throw new ProcesamientoException(\"Se ha producido un error personalizado.\");\n        }\n    }\n\n    public class ProcesamientoException : Exception\n    {\n\n        public ProcesamientoException(String mensaje) : base(\"Problema: \" + mensaje)\n        {\n        }\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/c#/hequebo.cs",
    "content": "class Program\n{\n    static void Main(string[] args)\n    {\n        // Excepeciones\n        int[] numeros = new int[10];\n        for (int i = 0; i < numeros.Length; i++)\n        {\n            numeros[i] = i;\n        }\n        int a = new Random().Next(15);\n        int c = new Random().Next(1);\n        try\n        {\n            Console.WriteLine($\"Intentando acceder al índice {a}\");\n            int b = numeros[a];\n            Console.WriteLine($\"Intentando dividir {b} entre {c}\");\n            c = b / c;\n        }\n        catch (IndexOutOfRangeException ex)\n        {\n            Console.WriteLine($\"No fue posible acceder al índice {a}\");\n            Console.WriteLine(ex.Message);\n        }\n        catch (DivideByZeroException ex)\n        {\n            Console.WriteLine(\"No es posible dividir entre 0\");\n            Console.WriteLine(ex.Message);\n        }\n        finally\n        {\n            Console.WriteLine(\"Este es el final del bloque try-catch\");\n        }\n        Console.ReadLine();\n        Console.Clear();\n\n        // Ejercicio extra\n        bool salir = false;\n        do\n        {\n            Console.Clear();\n            List<int> list1 = new List<int>();\n            int longitud = new Random().Next(15);\n            for (int i = 0; i < longitud; i++)\n                list1.Add(new Random().Next(100));\n            try\n            {\n                ProcesarParametros(list1);\n                Console.WriteLine(\"Parámetros correctos\");\n            }\n            catch (ArgumentException ex)\n            {\n                Console.WriteLine(ex.Message);\n            }\n            catch (IndexOutOfRangeException ex)\n            {\n                Console.WriteLine(ex.Message);\n                foreach (int i in list1)\n                    Console.Write($\"{i}, \");\n                Console.WriteLine();\n            }\n            catch (NotEnoughException ex)\n            {\n                Console.WriteLine(ex.Message);\n                Console.WriteLine(list1.Sum());\n            }\n            finally\n            {\n                Console.WriteLine(\"Fin del programa\");\n            }\n\n            Console.WriteLine(\"Deseas intentar de nuevo? S/N\");\n            string respuesta = Console.ReadLine();\n            if (respuesta.ToLower() == \"n\")\n                salir = true;\n        } while(!salir);\n\n\n\n    }\n\n    static void ProcesarParametros(List<int> list)\n    {\n        if (list.Count == 0)\n        {\n            throw new ArgumentException(\"La lista de parámetros no puede estar vacía\");\n        }\n        if (list.Count > 10)\n        {\n            throw new IndexOutOfRangeException(\"La lista no puede contener más de 10 elementos\");\n        }\n        if (list.Sum() < 200)\n        {\n            throw new NotEnoughException(\"La suma de los elementos es menor a 200\");\n        }\n    }\n}\nclass NotEnoughException : Exception\n{\n    public NotEnoughException(string message) : base(message) { }\n}"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/c#/jamerrq.cs",
    "content": "using System;\n\n/*\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado.\n */\n\nnamespace Roadmap10\n{\n    class Extra\n    {\n        public void Process(int a, int b)\n        {\n            if (b == 0)\n            {\n                throw new DivideByZeroException(\"No se puede dividir entre 0.\");\n            }\n            else if (a < 0)\n            {\n                throw new ArgumentOutOfRangeException(\"a\", \"El valor de 'a' no puede ser negativo.\");\n            }\n            else if (a > 10)\n            {\n                throw new Exception(\"El valor de 'a' no puede ser mayor que 10.\");\n            }\n            else\n            {\n                Console.WriteLine(a / b);\n            }\n        }\n    }\n    class Program\n    {\n        void catchExtra()\n        {\n            Extra extra = new Extra();\n            try\n            {\n                extra.Process(10, 0);\n            }\n            catch (DivideByZeroException e)\n            {\n                Console.WriteLine(\"Error: \" + e.Message);\n            }\n            catch (ArgumentOutOfRangeException e)\n            {\n                Console.WriteLine(\"Error: \" + e.Message);\n            }\n            catch (Exception e)\n            {\n                Console.WriteLine(\"Error: \" + e.Message);\n            }\n            finally\n            {\n                Console.WriteLine(\"La ejecución ha finalizado.\");\n            }\n        }\n        static void Main(string[] args)\n        {\n            try\n            {\n                int a = 10;\n                int b = 0;\n                Console.WriteLine(a / b);\n            }\n            catch (DivideByZeroException e)\n            {\n                Console.WriteLine(\"Error: \" + e.Message);\n            }\n            catch (Exception e)\n            {\n                Console.WriteLine(\"Error: \" + e.Message);\n            }\n            finally\n            {\n                Console.WriteLine(\"La ejecución ha finalizado.\");\n            }\n            Console.WriteLine(\"========================================\");\n            Console.WriteLine(\"============== MANEJO DE ERRORES =======\");\n            Console.WriteLine(\"========================================\\n\");\n            Program program = new Program();\n            program.catchExtra();\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/c#/kenysdev.cs",
    "content": "/*\n╔═══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado                ║\n║ GitHub: https://github.com/Kenysdev   ║\n║ 2024 -  C#                            ║\n╚═══════════════════════════════════════╝\n-----------------------------------------------\nEXCEPCIONES \n-----------------------------------------------\n- Representan una forma de controlar el comportamiento de un programa\n  cuando se produce un error.\n- Mas sobre excepciones en: \nlearn.microsoft.com/dotnet/csharp/language-reference/language-specification/exceptions\n*/\n// ___________________________________________\n// Capturar excepción\nusing System.Security.Cryptography.X509Certificates;\n\nint a = 7, b = 0;\ntry{\n    int r = a / b;\n}\ncatch (DivideByZeroException){\n    Console.WriteLine(\"Error de división por cero\");\n}\n\n// ___________________________________________\n// Cuando se desconoce el tipo de excepción\nvar myList = new int[]{ 1, 2, 3 };\ntry{\n    Console.WriteLine(myList[7]);\n}\ncatch (Exception){\n    Console.WriteLine(\"Excepción\");\n}\n\n// ___________________________________________\n// Saber qué excepción ha ocurrido\ntry{\n    int r = int.Parse(\"uno\") + 2;\n}\ncatch (Exception ex){\n    Console.WriteLine($\"Excepción: {ex.GetType()}\");\n}\n\n// ___________________________________________\n// Capturar diferentes excepciones\ntry{\n    // int r = int.Parse(\"uno\") + 2;\n    string r = 7 + \"txt\";\n}\ncatch (FormatException){\n    Console.WriteLine(\"Error al convertir\");\n}\ncatch (Exception){\n    Console.WriteLine(\"Error de tipos\");\n}\n\n// ___________________________________________\n// Uso de finally\n// Se ejecuta siempre, haya o no una excepción.\ntry{\n  int r = a / b;\n}\ncatch (Exception){\n  Console.WriteLine(\"Excepción\");\n}\nfinally{\n  Console.WriteLine(\"Bloque finally\");\n}\n\n// ___________________________________________\n// Uso de throw para ejecutar una excepción\n\n//throw new DivideByZeroException(\"Error de división\");\n//throw new IndexOutOfRangeException();\n//throw new InvalidCastException(\"..\");\n\n// -------------------------------------------\n// Definiendo excepcion personalizada\n// -------------------------------------------\n\ntry{\n  throw new CustomException(\"Mensaje de error personalizado\");\n}\ncatch (CustomException ex){\n  Console.WriteLine($\"Excepción personalizada: {ex.Message}\");\n}\n\n\n/*-------------------------------------------\n   Ejercicio\n  -------------------------------------------\n* Crea una función que sea capaz de procesar parámetros, pero que también\n* pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n* corresponderse con un tipo de excepción creada por nosotros de manera\n* personalizada, y debe ser lanzada de manera manual) en caso de error.\n* - Captura todas las excepciones desde el lugar donde llamas a la función.\n* - Imprime el tipo de error.\n* - Imprime si no se ha producido ningún error.\n* - Imprime que la ejecución ha finalizado. */\n\nConsole.WriteLine(\"\\n___________\\nEjercicio:\");\nOperation(10, \"uno\");\nOperation(10, 0);\nOperation(10, 5);\nOperation(10, 2);\n\nstatic void Division(int a, int b){\n  if (b % 2 != 0){\n    throw new OddNumberError();    \n  }\n  Console.WriteLine($\"\\n- El resultado es: {a / b}\");\n}\n\nstatic void Operation(int a, object b){\n  try{\n    Division(a, (int)b);\n    Console.WriteLine(\"- No hubo errores.\");\n  }\n  catch (InvalidCastException ex){\n    Console.WriteLine($\"\\nError: No se permite texto. -> {ex.GetType()}\");\n  }\n  catch (DivideByZeroException ex){\n    Console.WriteLine($\"\\nError: No es posible dividir entre 0. -> {ex.GetType()}\");\n  }\n  catch (OddNumberError ex){\n    Console.WriteLine($\"\\nError: no dividir entre impares. -> {ex.GetType()}\");\n  }\n  finally{\n    Console.WriteLine(\"- Operación terminada.\");\n  }\n}\n\n// ___________________________________________\n// Heredar clase \nclass CustomException(string message) : Exception(message){\n\n}\n\nclass OddNumberError : Exception{\n  public OddNumberError() : base() { }\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/c#/rxvlc.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace R10___2024\n{\n    internal class Program\n    {\n        static void Main(string[] args)\n        {\n            try\n            {\n                // Código que podría lanzar una excepción\n                int resultado = Dividir(10, 0);\n                Console.WriteLine(\" El resultado es: \" + resultado);\n            }\n            catch (DivideByZeroException ex)\n            {\n                // Manejo de la excepción DivideByZeroException\n                Console.WriteLine(\" Error: División por cero\");\n            }\n            catch (Exception ex)\n            {\n                // Manejo de cualquier otra excepción\n                Console.WriteLine(\" Ocurrió un error: \" + ex.Message);\n            }\n            finally\n            {\n                // Código que se ejecutará siempre\n                Console.WriteLine(\" Finalizando programa...\");\n            }\n\n\n            //Dificultad adicional:\n            ProcesarParams(1, 0); //Error parametro cero\n            ProcesarParams(-7, 7);//Error numero negativo\n            ProcesarParams(1, 1); //Suma normal sin error\n\n            Console.ReadKey();\n\n        }\n\n        static int Dividir(int dividendo, int divisor)\n        {\n            if (divisor == 0)\n            {\n                // Lanzar una excepción si el divisor es cero\n                throw new DivideByZeroException();\n            }\n            return dividendo / divisor;\n        }\n\n        static void ProcesarParams(int p1, int p2)\n        {\n            try\n            {\n                if (!(p1 is int) || !(p2 is int))\n                {\n                    throw new ArgumentException(\" Los parámetros no son números\");\n                }\n                else if (p1 == 0 || p2 == 0)\n                {\n                    throw new ArgumentException(\" Los numeros son cero\");\n                }\n                else if (p1 < 0 || p2 < 0)\n                {\n                    throw new ArgumentException(\" Alguno de los numeros es negativo\");\n                }\n                else\n                {\n                    Console.WriteLine(\" \"+p1 + p2);\n                    Console.Write(\" No se ha producido ningún error\");\n                }\n            }\n            catch (Exception ex)\n            {\n                Console.WriteLine(\" Se ha producido un error: \"+ex.Message);\n            }\n            finally\n            {\n                Console.WriteLine(\" La ejecución ha finalizado\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/c++/Fravelz.cpp",
    "content": "#include <iostream>\n#include <vector>\n\nusing namespace std;\n\n// Error personalizado\nclass MiError : public exception {\npublic:\n    const char* what() const noexcept override {\n        return \"Error personalizado lanzado manualmente.\";\n    }\n};\n\n// Función que puede lanzar varios errores\nvoid probarErrores(int a, int b) {\n    if (b == 0) {\n        throw runtime_error(\"Error: división por cero.\");\n    }\n\n    vector<int> datos = {1, 2, 3};\n    if (a != 42) {\n        // Esto causará un error si a > 2 (índice inválido)\n        cout << \"Elemento del vector: \" << datos.at(a) << endl;\n    \n    } else {\n        throw MiError();  // Lanzamos un error personalizado\n    }\n\n    cout << \"Resultado de la división: \" << a / b << endl;\n}\n\nint main() {\n    try {\n        int numerador = 10, denominador = 0;\n\n        if (denominador == 0) throw 101;\n\n        int num = numerador / denominador;\n        \n        cout << \"\\nLa division da como resultado: \" << num;\n\n    } catch (int error) {\n\n        if (error == 101) {\n            cout << \"\\nError101: El denominador es igual que cero...\";\n        }\n    } \n\n    cout << '\\n';\n\n    // ************** Ejercicio de Dificultad Extra ************** //\n\n    try {\n        probarErrores(10, 0); // Error: Dividir entre cero...\n        probarErrores(42, 2); // Error: \"a\" tiene que ser diferente de 42...\n        probarErrores(10, 1); // Error: \"a\" tiene que ser menor de 3...\n\n        cout << \"\\n> No succedio ningun error...\";\n\n    } catch(const exception& e) {\n        cout << \"\\n> Error: \" << e.what() << '\\n';\n\n    } catch(...) {\n        cout << \"\\n>> Error desconocido...\";\n    } \n\n\n    return 0;\n}"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/c++/N0HagoNada.cpp",
    "content": "#include <iostream>\n#include <vector>\n#include <stdexcept>\n\ndouble division(double a, double b)\n{\n    if (b == 0)\n    {\n        throw std::runtime_error(\"Error: División por cero\");\n    }\n    return a / b;\n}\n\nint obtenerValorIndice(const std::vector<int> &numeros, int indice)\n{\n    if (indice < 0 || indice >= static_cast<int>(numeros.size()))\n    {\n        throw std::out_of_range(\"Error: Índice fuera de rango\");\n    }\n    return numeros[indice];\n}\n\nint main()\n{\n    try\n    {\n        double resultado = division(10, 0);\n        std::cout << \"Resultado: \" << resultado << std::endl;\n    }\n    catch (const std::runtime_error &e)\n    {\n        std::cerr << e.what() << std::endl;\n    }\n\n    try\n    {\n        std::vector<int> numeros = {1, 2, 3};\n        int valor = obtenerValorIndice(numeros, 5);\n        std::cout << \"Valor: \" << valor << std::endl;\n    }\n    catch (const std::out_of_range &e)\n    {\n        std::cerr << e.what() << std::endl;\n    }\n\n    std::cout << \"Fin del programa\" << std::endl;\n    return 0;\n}"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/c++/hectorio23.cpp",
    "content": "// Se incluyen las librerias requeridas para la \n// ejecucion del programa\n#include <cstdlib>\n#include <iostream>\n#include <stdexcept>\n\n/*\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado. \n */\n\n// Función para dividir dos números e intentar forzar un error\nvoid dividir() {\n    // En c++ no se puede directamente dividir <<10 / 0>> ya que \n    // al momento de compilarlo nos lanza un error, por lo tanto\n    // se debe de validar que el divisor sea distinto a 0 \n    try {\n        int divisor = 0;\n        if (divisor == 0) {\n            throw std::invalid_argument(\"División por cero\");\n        }\n        int resultado = 10 / divisor; // Intento de dividir por cero\n        std::cout << \"El resultado de la división es: \" << resultado << std::endl;\n    } catch (const std::exception& e) {\n        std::cerr << \"Se produjo un error: \" << e.what() << std::endl;\n    }\n}\n\n// Función que puede lanzar excepciones personalizadas\nvoid procesarParametro(int parametro) {\n    if (parametro == 0) {\n        throw std::invalid_argument(\"El parámetro no puede ser cero\");\n    } else if (parametro < 0) {\n        throw std::out_of_range(\"El parámetro no puede ser negativo\");\n    } else {\n        std::cout << \"Procesamiento exitoso\" << std::endl;\n    }\n}\n\nint main() {\n    // Forzar un error al dividir por cero\n    dividir();\n\n    // Capturar todas las excepciones desde la llamada a la función procesarParametro\n    try {\n        // Intento de procesar un parámetro\n        procesarParametro(-3); // Se lanzará una excepción de argumento inválido\n    } catch (const std::exception& e) {\n        std::cerr << \"Se produjo un error: \" << e.what() << std::endl;\n    }\n\n    std::cout << \"La ejecución ha finalizado.\" << std::endl;\n    return EXIT_SUCCESS;\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/c++/jchavescaceres.cpp",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado. \n */\n\n#include <vector>\n#include <stack>\n#include <iostream>\n\nclass MyExceptionType : public std::exception\n{\n\tpublic:\n \tvirtual const char* what() const throw();\n};\n\nconst char* MyExceptionType::what() const throw() {\n\n\treturn \"Mi propia excepción\";\n};\n\n/*\n1 throw std::out_of_range& myOutOfRange\n2 throw int exception\n4 throw MyExceptionType\nothers no exception thrown\n*/\nvoid testException (int typeException) {\n\n\tstd::vector<int> myVector;\n\tMyExceptionType myException;\n\t\n\tif (typeException == 1) {\n\n\t\tstd::cout << myVector.at (5) << \"\\n\";\n\n\t} else if (typeException == 2) {\n\n\t\tthrow 2;\n\n\t} else if (typeException == 4) {\n\n\t\tthrow myException;\n\t};\n\n\tstd::cout << \"Fin funcion testException sin errores\\n\";\n};\n\nint main() {\n\n\t//In c++ no exception is thrown in divide by zero\n\t\n\tstd::vector<int> myVector;\n\n\ttry {\n\t\t//Error as vector is empty\n\t\tstd::cout << myVector.at (5) << \"\\n\";\n\t} catch (std::out_of_range& myException) {\n\t\tstd::cout << myException.what() << \"\\n\";\n\t};\n\n\tstd::cout << \"Programa continua\\n\";\n\n\tint typeException = 1;\n\n\tfor (int i = 0; i < 4; i++) {\n\t\ttry {\n\t\t\ttestException (typeException);\n\t\t\tstd::cout << \"Sin error al llamar a testException\\n\";\n\t\t} catch (std::out_of_range& myOutOfRange) {\n\t\t\tstd::cout << myOutOfRange.what() << \"\\n\";\n\t\t} catch (MyExceptionType& myExceptionType) {\n\t\t\tstd::cout << myExceptionType.what() << \"\\n\";\n\t\t} catch (int& i) {\n\t\t\tstd::cout << \"Excepcion int \" << i << \"\\n\";\n\t\t};\n\n\t\ttypeException <<= 1;\n\n\t}\n\n\tstd::cout << \"Fin\\n\";\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/c++/jhoshmc.cpp",
    "content": "//* voy a poner codigo rapido, regresando de trabajar profundizo mas\n#include<iostream>\n#include <stdexcept> // Para excepciones estándar como invalid_argument y out_of_range\nusing namespace std;\nvoid ejercicio();\nvoid extra();\nvoid procesarParametro(int);\nint main(){\n  // ejercicio();\n  extra();\n  return 0;\n}\n\nvoid ejercicio(){\n  /*\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n*/\n  int a, b;\n  float result;\n  a = 10;\n  b = 0;\n\n  try{\n    if (b == 0){\n      throw \"El divisor no puede ser 0\";\n    }\n    result = a / b;\n    cout << \"resultado: \" << result << endl;\n  }catch(const char *error){\n    cout << error << endl;\n  }\n  \n  \n\n}\n/*\n ! DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado. \n \n*/\n//? 1. Definimos una clase de excepción personalizada\n//*Creamos una clase que hereda de exception y sobreescribimos el método what() para mostrar un mensaje personalizado.\nclass CustomException : public exception {\npublic:\n    const char* what() const noexcept override {\n        return \"soy un mensaje de una excepcion personalizada\";\n    }\n};\n//? 2. Función que puede lanzar 3 tipos de excepciones\n/*\n*lanza:\n*invalid_argument si el valor es negativo.\n\n*out_of_range si es mayor a 10.\n\n*CustomException si el valor es exactamente 5 (esto es solo un ejemplo simbólico).\n*/\nvoid procesarParametro(int valor) {\n    if (valor < 0) {\n        throw invalid_argument(\"Valor no puede ser negativo.\");\n    } else if (valor > 10) {\n        throw out_of_range(\"Valor excede el rango permitido (0-10).\");\n    } else if (valor == 5) {\n        throw CustomException(); // Lanzamos nuestra excepción personalizada\n    }\n\n    // Si no hay excepción, mostrar que se procesó correctamente\n    cout << \"Parametro procesado correctamente: \" << valor << endl;\n}\n//? bloque try-catch\n/*\n*Aquí capturamos cada excepción por tipo y mostramos el mensaje asociado usando e.what().\n\n*También imprimimos un mensaje cuando no hay error y cuando finaliza la ejecución, para que quede claro el flujo del programa.\n*/\nvoid extra(){\n  int valor;\n  cout << \"\\ningresa un numero mayor a cero y menor a 10: \";\n  cin >>valor;\n  try {\n        procesarParametro(valor);\n        cout << \"No se ha producido ningun error.\" << endl;\n    }\n    catch (const invalid_argument& e) {\n        cerr << \"Error: \" << e.what() << endl;\n    }\n    catch (const out_of_range& e) {\n        cerr << \"Error: \" << e.what() << endl;\n    }\n    catch (const CustomException& e) {\n        cerr << \"Error: \" << e.what() << endl;\n    }\n    catch (...) {\n        cerr << \"Se produjo una excepcion desconocida.\" << endl;\n    }\n\n    cout << \"La ejecucion ha finalizado.\\n\" << endl;\n\n}\n\n\n\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/dart/bluefeatherdev.dart",
    "content": "/*\n* EJERCICIO:\n* Explora el concepto de manejo de excepciones según tu lenguaje.\n* Fuerza un error en tu código, captura el error, imprime dicho error\n* y evita que el programa se detenga de manera inesperada.\n* Prueba a dividir \"10/0\" o acceder a un índice no existente\n* de un listado para intentar provocar un error.\n*\n* DIFICULTAD EXTRA (opcional):\n* Crea una función que sea capaz de procesar parámetros, pero que también\n* pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n* corresponderse con un tipo de excepción creada por nosotros de manera\n* personalizada, y debe ser lanzada de manera manual) en caso de error.\n* - Captura todas las excepciones desde el lugar donde llamas a la función.\n* - Imprime el tipo de error.\n* - Imprime si no se ha producido ningún error.\n* - Imprime que la ejecución ha finalizado. \n*/\n\n/// 1. [Manejo de excepciones]:\nvoid exceptionExample1() {\n  try {\n    int tryThisDivision = 10 ~/ 0; // Error\n    print('10 ~/ 0 = $tryThisDivision');\n  } catch (e) {\n    print('Exception details:\\n $e');\n  }\n}\n\nvoid exceptionExample2() {\n  try {\n    List<dynamic> myList = [0, 1, 2];\n    print('${myList[3]}'); // Error\n  } catch (e) {\n    print('Exception details:\\n $e');\n  }\n}\n\n/// 2. [DIFICULTAD EXTRA]:\nclass StringTypeError implements Exception {\n  final String message;\n\n  StringTypeError([this.message = 'Must not be String']);\n  \n  @override\n  String toString() => 'StringTypeError: $message';\n}\n\nvoid processParameters(List<dynamic> parameters) {\n  if (parameters.first is String) {\n    throw StringTypeError();  // Excepción personalizada\n  }\n\n  else if (parameters.last == null) {\n    throw ArgumentError.notNull();\n  }\n\n  else if (parameters.length < 6) {\n    throw RangeError.range(parameters.length, 6, null);\n  }\n}\n\nvoid main() {\n  /// 1. [Manejo de excepciones]:\n  exceptionExample1();  // Captura: IntegerDivisionByZeroException\n  exceptionExample2();  // Captura: RangeError (length) ...\n\n  /// 2. [DIFICULTAD EXTRA]:\n  bool noError = false;\n  try {\n    // processParameters(['1', 2, 3, 4, null]); // Lista con todos los errores\n    processParameters([1, 2, 3, 4, null, 'hello']); // Lista sin errores\n    noError = true;\n  } on StringTypeError catch (e) {\n    print('parameters.first no debe ser String:\\n $e');\n  } on RangeError catch (e) {\n    print('parameters.length no es mayor o igual a 6:\\n $e');\n  } on Exception catch (e) {\n    print('parameters.last no debe ser null:\\n $e');\n  } on ArgumentError catch (e) {\n    print('Un error inesperado: $e');\n  } finally {\n    if (noError) print('¡No se ha producido ningún error!');\n    print('¡Programa finalizado sin interrupciones!');\n  }\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/dart/teren91.dart",
    "content": "/*\n  Author: Teren del Agua\n  GitHub: https://github.com/Teren91\n\n  Resources: https://dart.dev/language/error-handling\n\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado.\n */\n\n// Excepciones personalizadas\nclass DivisionPorCeroException implements Exception {}\n\nclass DivisionParesInvalidaException implements Exception {}\n\nvoid main() {\n  try {\n    errorForzado();\n\n    print(dividir(4, 2)); //No hay error devuelve 2.0\n    print(dividir(2, 3)); //Salta error personalizado\n\n\n    //Aserciones -> Se deben ejecutar con el flag --enable-asserts\n    //  Detienen la ejecución si no se cumple la norma.\n    numberFormat(10);\n    numberFormat(0);\n    numberFormat(-1);\n  } catch (e) {\n    print(e);\n  } finally {\n    print('Fin del programa.');\n  }\n}\n\nvoid errorForzado() {\n  try {\n    dynamic foo = true;\n    print(foo++); // Runtime error\n    \n  } on FormatException catch (e) {\n    print('Controlando error de formato: $e');\n  } on NoSuchMethodError catch (e) {\n    print('Controlando error de método: $e');\n  } on Exception catch (e) {\n    print('Cualquier otro error: $e');\n  } finally {\n    print('Fin del método errorForzado.');\n  }\n}\n\nvoid numberFormat(int x) {\n  assert(x.isEven, 'El número debe ser par');\n  assert(x != 0, 'El número no puede ser 0');\n  assert(x > 0, 'El número debe ser positivo');\n}\n\ndouble dividir(int x, int y) {\n  if (y == 0) {\n    throw DivisionPorCeroException();\n  }\n  if (y.isOdd) {\n    throw DivisionParesInvalidaException();\n  }\n\n  return x / y;\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/ejercicio.md",
    "content": "# #10 EXCEPCIONES\n> #### Dificultad: Media | Publicación: 04/03/24 | Corrección: 11/03/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado. \n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/go/AmadorQuispe.go",
    "content": "package main\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"strconv\"\n)\n\n//De manera general, GO representa cualquier tipo de error mediante la interfaz error:\n\nfunc main() {\n\t//División por cero\n\tif res, err := divideTwoNumbers(10, 0); err == nil {\n\t\tfmt.Println(res)\n\t} else {\n\t\tfmt.Println(err)\n\t}\n\n\t//Indice fuera de rango\n\tnumbers := []int{1, 2, 3, 4, 5, 6}\n\tval, err := getElementByIndex(numbers, 6)\n\tif err != nil {\n\t\tfmt.Println(err)\n\t} else {\n\t\tfmt.Println(val)\n\n\t}\n\n\t//Error personalizado\n\tresult, err := divisionPositive(-34, 3)\n\tif err != nil {\n\t\tfmt.Println(err)\n\t} else {\n\t\tfmt.Println(result)\n\t}\n}\n\nfunc divideTwoNumbers(a, b int) (int, error) {\n\tif b == 0 {\n\t\treturn 0, errors.New(\"cannot divide by zero\")\n\t}\n\treturn a / b, nil\n}\n\nfunc getElementByIndex[T any](slice []T, i int) (T, error) {\n\tif len(slice) >= i {\n\t\tvar zeroValue T\n\t\treturn zeroValue, errors.New(\"index of range! it must be less than \" + strconv.Itoa(i))\n\t}\n\treturn slice[i], nil\n}\n\ntype CustomError struct {\n\tmsg string\n}\n\nfunc (ce *CustomError) Error() string {\n\treturn ce.msg\n}\n\nfunc divisionPositive(numerator, denominator int) (int, error) {\n\tif numerator < 0 || denominator < 0 {\n\t\treturn 0, &CustomError{msg: \"not valid numbers negatives\"}\n\t}\n\treturn numerator / denominator, nil\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/go/FreyFonseca117.go",
    "content": "//  * EJERCICIO:\n//  * Explora el concepto de manejo de excepciones según tu lenguaje.\n//  * Fuerza un error en tu código, captura el error, imprime dicho error\n//  * y evita que el programa se detenga de manera inesperada.\n//  * Prueba a dividir \"10/0\" o acceder a un índice no existente\n//  * de un listado para intentar provocar un error.\n//  *\n//  * DIFICULTAD EXTRA (opcional):\n//  * Crea una función que sea capaz de procesar parámetros, pero que también\n//  * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n//  * corresponderse con un tipo de excepción creada por nosotros de manera\n//  * personalizada, y debe ser lanzada de manera manual) en caso de error.\n//  * - Captura todas las excepciones desde el lugar donde llamas a la función.\n//  * - Imprime el tipo de error.\n//  * - Imprime si no se ha producido ningún error.\n//  * - Imprime que la ejecución ha finalizado.\n\npackage main\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n)\n\n// manejo de errores\n\nfunc dividir(a, b float32) (float32, error) {\n\tif b == 0 {\n\t\treturn 0, errors.New(\"Division entre 0\")\n\t}\n\treturn a / b, nil\n\n}\n\n// Actividad opcional\nfunc procesarParametros(a, b float32) (float32, bool, error) {\n\tif b == 0 {\n\t\treturn 0, false, errors.New(\"Divison entre cero\")\n\t} else if a == 0 {\n\t\treturn 0, true, errors.New(\"el numerador es cero\")\n\t} else {\n\t\treturn a / b, true, nil\n\t}\n}\n\nfunc main() {\n\tresult, err := dividir(10, 0)\n\tif err != nil {\n\t\tfmt.Println(\"Se ha producido un error\", err)\n\t} else {\n\t\tfmt.Println(\"El resultado es\", result)\n\t}\n\tresult, err = dividir(10, 4)\n\tif err != nil {\n\t\tfmt.Println(\"Se ha producido un error\", err)\n\t} else {\n\t\tfmt.Println(\"El resultado es\", result)\n\t}\n\tresult, ok, err := procesarParametros(10, 0)\n\tif err != nil {\n\t\tfmt.Println(\"Error en procesarParametros:\", err)\n\t} else {\n\t\tfmt.Println(\"Resultado de procesarParametros:\", result, \"¿Es válido?:\", ok)\n\t}\n\tresult, ok, err = procesarParametros(8, 4)\n\tif err != nil {\n\t\tfmt.Println(\"Error en procesarParametros:\", err)\n\t} else {\n\t\tfmt.Println(\"Resultado de procesarParametros:\", result, \"¿Es válido?:\", ok)\n\t}\n\tfmt.Println(\"Ejecución finalizada.\")\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/go/MiguelP-Dev.go",
    "content": "package main\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"strconv\"\n)\n\n/*\nEn golang no existen las excepciones, pero si existen las funciones de manejo de errores.\n\nLos errores son parte importante de golang porque se decidió desde su diseño inicial, tabajar con ellos\nen vez de excepciones porque estas en la mayoria de los casos no son controladas por el desarrollador\n\nLa idea es que los errores sean controlados apenas se presenten, esta es la razón de que las funciones\ndevuelvan multiples valores. Usualmente las funciones como ultimo argumento devuelven un error, para que\npodamos validar si la función ejecutada genera un error y lo podamos controlar.\n\nControlar los errores e golang es muy cómodo, además saves siempre de donde viene el error si lo haces\ncorrectamente. Para controlar los errores y darle más personalización existe el paquete \"errors\" o\nla función 'errorf' del paquete \"fmt\", además go, cuenta con funciones como \"panic y recover\".\n\nEn golang usamos el ok para comprobar errores (Usamos el operador unario con el ok).\nOk es una variable booleana usada comunmente para verificar si una operación se realizó con éxito,\npremitiendo un manejo más preciso y seguro de los errores y condiciones.\n*/\n\n// val Variable para guardar el valor obtenido de la conversión en la función\nvar val = strToInt(\"24\")\n\n// found Variable que se redefinirá su valor durate los ejercicios y ejemplos\nvar found string\n\n// stringToInt Ejemplo 1 de manejo de errores(Simple)\nfunc strToInt(s string) int {\n\tnum, err := strconv.Atoi(s)\n\tif err != nil {\n\t\tfmt.Println(\"Error: informacion no válida.\", err)\n\t\treturn -1\n\t}\n\treturn num\n}\n\n// errNotFound es una variable que almacena un mensaje personalizado para controlar un error.\nvar errNotFound = errors.New(\"Not Found.\")\n\n// fastFood mapa de comida rápida\nvar fastFood = map[int]string{\n\t24: \"Hamburguesa\", 22: \"Perro Caliente\", 23: \"Arroz Chino\", 25: \"Pizza\",\n}\n\n// search funcion de busqueda por un mapa.\nfunc search(key string) (string, error) {\n\tnum, err := strconv.Atoi(key)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"strconv.Atoi: %w\", err)\n\t}\n\n\tvalue, err := okVariable(num)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn value, nil\n}\n\n// okVariable Usando el ok y el operador unario y se llama desde search()\nfunc okVariable(num int) (string, error) {\n\tvalue, ok := fastFood[num]\n\tif !ok {\n\t\treturn \"\", fmt.Errorf(\"OkVariable(): Valor inexistente\")\n\t}\n\treturn value, nil\n}\n\n// animals mapa de animales\nvar animals = map[int]string{\n\t1: \"Gato\", 2: \"Perro\", 3: \"León\",\n}\n\n// search funcion de busqueda por un mapa.\nfunc searchAnimals(key string) (string, error) {\n\tnumber, err := strconv.Atoi(key)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"strconv.Atoi(): %w\", err)\n\t}\n\tvalue, err := findAnimal(number)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"findAnimal(): %w\", err)\n\t}\n\treturn value, nil\n}\n\nfunc findAnimal(num int) (string, error) {\n\tnumber, ok := animals[num]\n\tif !ok {\n\t\treturn \"\", errNotFound\n\t}\n\treturn number, nil\n}\n\n/*\nEn estos ejercicios simple no se alcanza a ver la complejidad, por tanto es simple controlarlos así, pero para casos más complejos\nhay que llevar un correcto seguimineto de estos errores,sobretodo cuando hay un anidamiento de procedimientos,\npara eso es muy util el paquete format(fmt) con su función errorf, donde aparte\nde poner texto de error personalizado puedo entregar específicamente desde que funcion o método viene el error.\n*/\n\nvar number1 = 12\nvar number2 = 0\n\n// division Funcion de division por cero\nfunc division(n1, n2 int) (int, error) {\n\tif n2 == 0 {\n\t\treturn -1, errNotFound\n\t}\n\tresult := n1 / n2\n\treturn result, nil\n\n}\n\n// Otra opcion que tiene golang para manejar errores sin se que se detenga la aplicación es con panic y recover\n// Panic se usa para generar un panico tras un error y recover para recuperarse de su error y continuar\n// con las operaciones dejando un mensaje de error.\n\n// extraFunction: Es la función creada para el ejercicio extra de la roadmap\nfunc extraFunction(n string, n2 int) (int, error) {\n\t// Con una funcion anónima en una cola de ejecucion con difer, verificamos si se produce un panic y nos recuperamos de él\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tfmt.Println(\"Me recuperé del panic.\")\n\t\t}\n\t}()\n\n\tstr, err := strconv.Atoi(n)\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"strconv.Atoi(): El parámetro no es válido para operar: %w\", err)\n\t}\n\t// Validamos si el divisor es igual a cero\n\tvalidateZero(n2)\n\n\tfmt.Printf(\"No hubo errores, Resultado de dividir %v entre %v: \", str, n2)\n\treturn str / n2, nil\n}\n\nfunc validateZero(n int) {\n\tif n == 0 {\n\t\tpanic(\"No es posible dividir por cero\")\n\t}\n}\n\nfunc main() {\n\t// Primer ejemplo: simple\n\tfmt.Printf(\"Value: %d Tipo de datos: %T\\n\", val, val)\n\n\t// Segúndo ejemplo: manejo con paquete errors (Personalizado.)\n\tfound, err := search(\"22\")\n\tif err != nil {\n\t\tfmt.Println(\"search(): \", err)\n\t\treturn\n\t}\n\tfmt.Println(found)\n\n\t// Tercer ejemplo: comprobación ok con unario. (Uso sin search para buscar el valor directamente)\n\tfound, err = okVariable(val)\n\tif err != nil {\n\t\tfmt.Println(\"okVariable():\", err)\n\t\treturn\n\t}\n\tfmt.Println(found)\n\n\t// Conprobación espesífica de errores\n\tfound, err = searchAnimals(\"4\")\n\tif errors.Is(err, errNotFound) {\n\t\tfmt.Println(\"Pudimos controlar el error.\")\n\t\treturn\n\t}\n\tif err != nil {\n\t\tfmt.Println(\"searchAnimals(): \", err)\n\t\treturn\n\t}\n\tfmt.Println(found)\n\n\t// Divición por cero\n\tdiv, err := division(number1, number2)\n\tif err == errNotFound {\n\t\tfmt.Println(\"No es posible dividir por 0\")\n\t\treturn\n\t}\n\tfmt.Printf(\"Resultado de dividir %d entre %d, es: %d\\n\", number1, number2, div)\n\n\t// Extra\n\tdivisionExtra, err := extraFunction(\"12\", 2)\n\tif err != nil {\n\t\tfmt.Printf(\"Mensaje de error: %s, Tipo: %T\\n\", err, err)\n\t\treturn\n\t}\n\tfmt.Println(divisionExtra)\n\tfmt.Println(\"La Ejecución finalizó.\")\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/go/N0HagoNada.go",
    "content": "package main\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n)\n\ntype CustomError struct {\n\tMessage string\n}\n\nfunc (e *CustomError) Error() string {\n\treturn e.Message\n}\n\nfunc main() {\n\t// Ejemplo 1: División por cero\n\tresult, err := divideNumbers(10, 0)\n\tif err != nil {\n\t\tfmt.Println(\"Error:\", err)\n\t} else {\n\t\tfmt.Println(\"Resultado:\", result)\n\t}\n\n\t// Ejemplo 2: Acceso a índice fuera de rango\n\tnumbers := []int{1, 2, 3}\n\tvalue, err := getValueAtIndex(numbers, 5)\n\tif err != nil {\n\t\tfmt.Println(\"Error:\", err)\n\t} else {\n\t\tfmt.Println(\"Valor:\", value)\n\t}\n\tfmt.Println(\"****************************** Reto ***************************************\")\n\t// Llamada a la función processParams con diferentes casos\n\terr = processParams(10, 2)\n\thandleError(err)\n\n\terr = processParams(0, 5)\n\thandleError(err)\n\n\terr = processParams(10, 0)\n\thandleError(err)\n\n\terr = processParams(-5, 3)\n\thandleError(err)\n\n\terr = processParams(8, 4)\n\thandleError(err)\n\n\tfmt.Println(\"Ejecución finalizada\")\n}\n\nfunc divideNumbers(a, b int) (int, error) {\n\tif b == 0 {\n\t\treturn 0, fmt.Errorf(\"No se puede dividir por cero\")\n\t}\n\treturn a / b, nil\n}\n\nfunc getValueAtIndex(numbers []int, index int) (int, error) {\n\n\tif index < 0 || index >= len(numbers) {\n\t\treturn 0, fmt.Errorf(\"Índice fuera de rango: %d\", index)\n\t}\n\n\treturn numbers[index], nil\n}\n\n// Función que procesa parámetros y puede lanzar diferentes tipos de excepciones\nfunc processParams(a, b int) error {\n\tif a == 0 {\n\t\treturn errors.New(\"No se puede procesar con el valor 'a' igual a cero\")\n\t}\n\n\tif b == 0 {\n\t\treturn fmt.Errorf(\"No se puede procesar con el valor 'b' igual a cero\")\n\t}\n\n\tif a < 0 || b < 0 {\n\t\treturn &CustomError{Message: \"No se pueden procesar valores negativos\"}\n\t}\n\n\t// Procesamiento correcto\n\tresult := a / b\n\tfmt.Printf(\"Resultado: %d\\n\", result)\n\treturn nil\n}\n\nfunc handleError(err error) {\n\tif err != nil {\n\t\tfmt.Println(\"Tipo de error:\", err)\n\t} else {\n\t\tfmt.Println(\"No se ha producido ningún error\")\n\t}\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/go/hozlucas28.go",
    "content": "package main\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n)\n\n/* -------------------------------------------------------------------------- */\n/*                                ERROR (CLASS)                               */\n/* -------------------------------------------------------------------------- */\n\ntype Error struct {\n\terrorMessage  string\n\terrorSeverity string\n}\n\nfunc (error *Error) Error() string {\n\tvar errorSeverity string = fmt.Sprintf(\"Error severity: %s\", error.errorSeverity)\n\tvar errorMessage string = fmt.Sprintf(\"\\nError message: %s\", error.errorMessage)\n\treturn errorSeverity + errorMessage\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                  FUNCTIONS                                 */\n/* -------------------------------------------------------------------------- */\n\nfunc divide(a int, b int) (int, error) {\n\tif b == 0 {\n\t\tvar errorMessage string = fmt.Sprintf(\"Can't divide %d by %d value!\", a, b)\n\t\treturn 0, errors.New(errorMessage)\n\t}\n\n\treturn a / b, nil\n}\n\nfunc at[T any](array *[]T, index int) (T, error) {\n\tvar arrayLength int = len(*array)\n\tif arrayLength <= index {\n\t\tvar emptyValue T\n\t\tvar errorMessage string = fmt.Sprintf(\"Index out of range! It must be less than %d.\", index)\n\t\treturn emptyValue, errors.New(errorMessage)\n\t}\n\n\treturn (*array)[index], nil\n}\n\nfunc fn(a int, b int) (int, error) {\n\tif a == 0 {\n\t\treturn 0, errors.New(\"First parameter mustn't be zero!\")\n\t}\n\n\tif b == 0 {\n\t\treturn 0, errors.New(\"Second parameter mustn't be zero!\")\n\t}\n\n\tif a < 0 || b < 0 {\n\t\treturn 0, &Error{errorMessage: \"First parameter and second parameter must be greater than zero!\", errorSeverity: \"high\"}\n\t}\n\n\treturn a + b, nil\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\nfunc main() {\n\t/*\n\t\tExceptions...\n\t*/\n\n\tfmt.Println(\"Exceptions...\")\n\n\tdivision, divisionError := divide(10, 0)\n\tif divisionError != nil {\n\t\tfmt.Printf(\"\\n%s\\n\", divisionError.Error())\n\t} else {\n\t\tfmt.Printf(\"\\n%d / %d --> %d\\n\", 10, 0, division)\n\t}\n\n\tvar array []string = []string{\"Hello\", \"World\", \"!\"}\n\telement, elementError := at(&array, 3)\n\tif elementError != nil {\n\t\tfmt.Printf(\"\\n%s\\n\", elementError.Error())\n\t} else {\n\t\tfmt.Printf(\"\\narray[3] --> %s\\n\", element)\n\t}\n\n\tfmt.Println(\"\\n# ---------------------------------------------------------------------------------- #\\n\")\n\n\t/*\n\t\tAdditional challenge...\n\t*/\n\n\tfmt.Println(\"Additional challenge...\")\n\n\t// Custom error\n\tresult01, result01Error := fn(-2, -2)\n\tif result01Error != nil {\n\t\tfmt.Printf(\"\\n%s\\n\", result01Error.Error())\n\t} else {\n\t\tfmt.Printf(\"\\nFirst result --> %d\\n\", result01)\n\t}\n\n\t// First parameter error\n\tresult02, result02Error := fn(0, 5)\n\tif result02Error != nil {\n\t\tfmt.Printf(\"\\n%s\\n\", result02Error.Error())\n\t} else {\n\t\tfmt.Printf(\"\\nSecond result --> %d\\n\", result02)\n\t}\n\n\t// No error\n\tresult03, result03Error := fn(5, 10)\n\tif result03Error != nil {\n\t\tfmt.Printf(\"\\n%s\\n\", result03Error.Error())\n\t} else {\n\t\tfmt.Printf(\"\\nThird result --> %d\\n\", result03)\n\t}\n\n\t// Second parameter error\n\tresult04, result04Error := fn(8, 0)\n\tif result04Error != nil {\n\t\tfmt.Printf(\"\\n%s\\n\", result04Error.Error())\n\t} else {\n\t\tfmt.Printf(\"\\nFourth result --> %d\\n\", result04)\n\t}\n\n\tfmt.Println(\"\\nAdditional challenge finished!\")\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/go/kodenook.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n)\n\nfunc main() {\n\tvar err error\n\tx := 4\n\ty := 0\n\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\terr = fmt.Errorf(\"error: %v\", r)\n\t\t\tfmt.Println(err)\n\t\t}\n\t}()\n\tout := x / y\n\tfmt.Println(out)\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/go/miguelex.go",
    "content": "package main\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n)\n\nfunc divide(a int, b int) (int, error) {\n\tif b == 0 {\n\t\tvar errorMessage string = fmt.Sprintf(\"Can't divide %d by %d value!\", a, b)\n\t\treturn 0, errors.New(errorMessage)\n\t}\n\n\treturn a / b, nil\n}\n\nfunc at[T any](array *[]T, index int) (T, error) {\n\tvar arrayLength int = len(*array)\n\tif arrayLength <= index {\n\t\tvar emptyValue T\n\t\tvar errorMessage string = fmt.Sprintf(\"Index out of range! It must be less than %d.\", index)\n\t\treturn emptyValue, errors.New(errorMessage)\n\t}\n\n\treturn (*array)[index], nil\n}\nfunc main() {\n\n\tresult, err := divide(10, 0)\n\tif err != nil {\n\t\tfmt.Println(err)\n\t} else {\n\t\tfmt.Println(result)\n\t}\n\n\t// Ejemplo de acceso fuera de rango\n\tvar array []int = []int{1, 2, 3, 4, 5}\n\tresult, err = at(&array, 10)\n\tif err != nil {\n\t\tfmt.Println(err)\n\t} else {\n\t\tfmt.Println(result)\n\t}\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/go/qwik-zgheib.go",
    "content": "package main\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n)\n\nfunc divide(a, b int) (int, error) {\n\tif b == 0 {\n\t\treturn 0, errors.New(\"cannot divide by zero\")\n\t}\n\treturn a / b, nil\n}\n\nfunc accessElement(arr []int, index int) (int, error) {\n\tif index < 0 || index >= len(arr) {\n\t\treturn 0, fmt.Errorf(\"index %d out of range\", index)\n\t}\n\treturn arr[index], nil\n}\n\n/* extra */\nvar (\n\tErrDivideByZero    = errors.New(\"cannot divide by zero\")\n\tErrIndexOutOfRange = errors.New(\"index out of range\")\n\tErrCustom          = errors.New(\"custom error occurred\")\n)\n\ntype CustomError struct {\n\tMsg string\n}\n\nfunc (e *CustomError) Error() string {\n\treturn e.Msg\n}\n\nfunc process(value int) error {\n\tif value == 0 {\n\t\treturn ErrDivideByZero\n\t} else if value < 0 {\n\t\treturn ErrIndexOutOfRange\n\t} else if value > 100 {\n\t\treturn &CustomError{Msg: \"value exceeds 100\"}\n\t}\n\treturn nil\n}\n\nfunc main() {\n\tresult, err := divide(10, 0)\n\tif err != nil {\n\t\tfmt.Println(\"Error:\", err)\n\t} else {\n\t\tfmt.Println(\"Result:\", result)\n\t}\n\tfmt.Println(\"Execution finished.\")\n\n\tarr := []int{1, 2, 3}\n\telement, err := accessElement(arr, 5)\n\tif err != nil {\n\t\tfmt.Println(\"Error:\", err)\n\t} else {\n\t\tfmt.Println(\"Element:\", element)\n\t}\n\tfmt.Println(\"Execution finished.\")\n\n\t/* extra */\n\tvalues := []int{0, -1, 150, 50}\n\n\tfor _, value := range values {\n\t\terr := process(value)\n\t\tif err != nil {\n\t\t\tswitch err {\n\t\t\tcase ErrDivideByZero:\n\t\t\t\tfmt.Println(\"Caught error:\", err)\n\t\t\tcase ErrIndexOutOfRange:\n\t\t\t\tfmt.Println(\"Caught error:\", err)\n\t\t\tdefault:\n\t\t\t\tif customErr, ok := err.(*CustomError); ok {\n\t\t\t\t\tfmt.Println(\"Caught custom error:\", customErr)\n\t\t\t\t} else {\n\t\t\t\t\tfmt.Println(\"Caught error:\", err)\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tfmt.Println(\"No error occurred for value:\", value)\n\t\t}\n\t\tfmt.Println(\"Execution finished for value:\", value)\n\t}\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/go/raynerpv2022.go",
    "content": "package main\n\nimport \"fmt\"\n\n/*\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n */\n\nfunc DivInteger(a, b int) (div_ab float32, err error) {\n\n\tdefer func() {\n\n\t\tr := recover()\n\t\tif r != nil {\n\t\t\terr = fmt.Errorf(\"Error  como P^$!a : %v \", r)\n\t\t\tdiv_ab = 0\n\t\t}\n\t}()\n\n\tdiv_ab = float32(a) / float32(b)\n\tif b == 0 {\n\t\tpanic(\"B == 0\")\n\t}\n\treturn div_ab, nil\n}\nfunc sliceOutofRange(lista []int, index int) (num int, err error) {\n\tdefer func() {\n\t\tr := recover()\n\t\tif r != nil {\n\t\t\terr = fmt.Errorf(\"Eeeeerrror %v\", r)\n\t\t\tnum = -1\n\t\t}\n\t}()\n\tnum = lista[index]\n\treturn num, nil\n\n}\n\n/* DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado.\n */\n\nfunc CustomError(Index int, list []int) (prom float32, err error) {\n\n\tdefer func() {\n\t\tr := recover()\n\t\tif r != nil {\n\t\t\terr = fmt.Errorf(\"error.. %v\", r)\n\t\t}\n\t}()\n\tLongitud := len(list)\n\t// verifico que el index este entre 0 y max longitud de la cadena\n\tif (Longitud < Index) || (Index < 0) {\n\n\t\tpanic(\" Acceso a valores fuera de rango\")\n\t}\n\n\tif list[Longitud-1] == 10 {\n\t\tpanic(\" el ultimo elemento no puede ser 10\")\n\t}\n\n\tprom = float32(list[Longitud-1]) / float32(list[0])\n\n\t// controlo la division por cero\n\tif float32(list[0]) == 0 {\n\n\t\tpanic(\"Division por cero no permitida\")\n\n\t}\n\treturn prom, nil\n\n}\n\nfunc main() {\n\tfmt.Println(\"Reto #10 Exception\")\n\tvar a, b int\n\n\tfmt.Print(\"Numerador :\")\n\tfmt.Scanln(&a)\n\tfmt.Print(\"Denominador :\")\n\tfmt.Scanln(&b)\n\tdiv_ab, ok := DivInteger(a, b)\n\tif ok == nil {\n\t\tfmt.Println(\"No hay error\")\n\t\tfmt.Printf(\" %v / %v = %v\\n\", a, b, div_ab)\n\t} else {\n\t\tfmt.Printf(\"Error div x 0 is a chaos... %v\\n\", ok)\n\t}\n\n\tindex := 10\n\tnum, e := sliceOutofRange([]int{0, 1, 2, 3}, index)\n\tif e != nil {\n\t\tfmt.Printf(\"Error %v\\n\", e)\n\t} else {\n\t\tfmt.Printf(\"in %v position is %v\\n\", index, num)\n\t}\n\n\tfmt.Println(\"EXTRA\")\n\tfmt.Println()\n\n\tprom, er := CustomError(3, []int{20, 2, 3, 4, 1, 1, 1, 100})\n\tif er != nil {\n\t\tfmt.Println(er)\n\t} else {\n\t\tfmt.Println(\"No se ha producido ningun error\")\n\t\tfmt.Println(\"Promedio es: \", prom)\n\t}\n\n\tfmt.Println(\"El programam ha finalizado\")\n\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/go/thegera4.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"errors\"\n)\n\nfunc main() {\n\n\t// Dividir 10/0\n\t_, err := divide(10, 0)\n\tif err != nil {\n\t\tfmt.Println(\"Error al dividir: \", err)\n\t}\n\n\t// Acceder a un índice no existente de un listado\n\tlist := []int{1, 2, 3}\n\t_, err = iterateList(list)\n\tif err != nil {\n\t\tfmt.Println(\"Error al iterar: \", err)\n\t}\n\n\t// Extra: Procesar parámetros\n\tvalue1, err := process(10, 2)\n\tif err != nil {\n\t\tfmt.Println(\"Error al procesar parámetros: \", err)\n\t} else {\n\t\tfmt.Println(\"Parametros procesados correctamente: \", value1)\n\t}\n\n\tvalue2, err := process(13, 2)\n\tif err != nil {\n\t\tfmt.Println(\"Error al procesar parámetros: \", err)\n\t} else {\n\t\tfmt.Println(\"El resultado es: \", value2)\n\t}\n\n\tfmt.Println(\"El programa continua, no termina inesperadamente al haber errores ya que los estamos manejando...\")\n}\n\nfunc divide(a, b int) (int, error) {\n\tif b == 0 {\n\t\treturn 0, errors.New(\"No se puede dividir por 0\")\n\t}\n\treturn a / b, nil\n}\n\nfunc iterateList(list []int) (int, error) {\n\tfor i := 0; i < len(list)+1; i++ {\n\t\tif i >= len(list) {\n\t\t\treturn 0, errors.New(\"Indice fuera de rango\")\n\t\t}\n\t\tfmt.Println(list[i])\n\t}\n\treturn 0, nil\n}\n\n// Extra:\n\ntype MyError struct {\n\tcode int\n\tmsg string\n}\n\nfunc (e *MyError) Error() string {\n\treturn fmt.Sprintf(\"Error %d: %s\", e.code, e.msg)\n}\n\nfunc process(a, b int) (int, error) {\n\tif a <= 0 {\n\t\treturn 0, errors.New(\"El primer parámetro no puede ser negativo ni 0\")\n\t}\n\tif b <= 0 {\n\t\treturn 0, errors.New(\"El segundo parámetro no puede ser negativo ni 0\")\n\t}\n\tif a == 13 {\n\t\treturn 0, &MyError{code: 13, msg: \"El primer parámetro no puede ser 13\"}\n\t}\n\tif b == 13 {\n\t\treturn 0, &MyError{code: 13, msg: \"El segundo parámetro no puede ser 13\"}\n\t}\n\tfmt.Println(\"Ejecucion finalizada sin errores.\")\n\treturn a + b, nil\n}"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/java/Abel-ADE.java",
    "content": "public class Main {\n    public static int division() throws ArithmeticException {\n        return 10/0;\n    }\n    public static int multiplication() {\n        return 10*10;\n    }\n    public static int errorResult(int number) throws AbelException, ArithmeticException, IllegalArgumentException {\n        if (number < 0) {\n            throw new AbelException(\"El número no puede ser negativo\");\n        } else if (number == 0) {\n            throw new ArithmeticException(\"El número no puede ser igual a 0\");\n        }else if (number >1000) {\n            throw new IllegalArgumentException(\"El número no puede ser mayor de 1000\");\n        }\n        return number;\n    }\n\n    public static void main(String[] args) {\n        try{\n            int div = division();\n            System.out.println(\"Resultado de la division: \" + div);\n        }catch (ArithmeticException ex){\n            System.out.println(\"Error: \" + ex.getMessage());\n        }\n\n        int result = multiplication();\n        System.out.println(\"Resultado de la multiplicación: \" + result);\n\n        /*DIFICULTAD EXTRA*/\n\n        System.out.println(\"\\n----------DIFICULTAD EXTRA-----------\\n\");\n\n        try {\n            int result2 = errorResult(0);\n            System.out.println(\"No se produce ningún error\");\n            System.out.println(\"Resultado del método: \" + result2);\n        } catch (AbelException e) {\n            System.out.println(\"Error personalizado: \" + e.getMessage());\n        } catch (ArithmeticException eA) {\n            System.out.println(\"Error 1: \" + eA.getMessage());\n        } catch (IllegalArgumentException eI) {\n            System.out.println(\"Error 2: \" + eI.getMessage());\n        }finally {\n            System.out.println(\"Fin del programa\");\n        }\n\n    }\n}\n\nclass AbelException extends Exception{\n    /**\n     * Constructs a new exception with the specified detail message.  The\n     * cause is not initialized, and may subsequently be initialized by\n     * a call to {@link #initCause}.\n     *\n     * @param message the detail message. The detail message is saved for\n     *                later retrieval by the {@link #getMessage()} method.\n     */\n    public AbelException(String message) {\n        super(message);\n    }\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/java/AmadorQuispe.java",
    "content": "public class AmadorQuispe {\n    public static void main(String[] args) {\n        // En java esta definido dos tipos de excepción\n        // Checked Exceptions, es obligatoria su manejo ya sea declarando en la firma\n        // del método o usando try-catch\n\n        // Unchecked Exceptions, no es obligatorio su manejo y ocurren en tiempo de\n        // ejecución\n\n        try {\n            // Código que puede generar una excepción\n            int result = 10 / 0; // Esto generará una excepción de división por cero (ArithmeticException)\n            System.out.println(result);\n        } catch (ArithmeticException e) {\n            // Captura de la excepción específica\n            System.out.println(\"Ocurrió una excepción: \" + e.getMessage());\n        }\n\n        try {\n            List<Integer> numbers = new ArrayList<>();\n            numbers.add(2);\n            numbers.add(4);\n            numbers.add(6);\n            numbers.add(8);\n            // intentamos acceder al indice 4, como no tenemos lanza una excepción\n            System.out.println(numbers.get(4));\n        } catch (IndexOutOfBoundsException e) {\n            System.out.println(e.getMessage());\n        }\n        // ArithmeticException y IndexOutOfBoundsException son unchecked exception, no\n        // obliga a manejarlo\n\n        File file = new File(\"not_existing_file.txt\"); // intentamos acceder a un archivo\n        try {\n            FileInputStream stream = new FileInputStream(file);\n        } catch (FileNotFoundException e) {\n            System.out.println(e.getMessage());\n        }\n        // FileNotFoundException es checked exception, por lo cual estamos obligados a\n        // manejarlo\n\n        // EXTRA\n\n        System.out.println(\"Ingresa los números a dividir\");\n        try (Scanner sc = new Scanner(System.in)) {\n            do {\n\n                System.out.print(\"Ingresa el numerado :\");\n                int n1 = sc.nextInt();\n                System.out.print(\"Ingresa el denominador :\");\n                int n2 = sc.nextInt();\n\n                try {\n                    double res = divisionPositive(n1, n2);\n                    System.out.println(String.format(\"El resultado de %d / %d es %s\", n1, n2, res));\n                } catch (NumberNegativeException ne) {\n                    System.out.println(ne.getMessage());\n                } catch (ArithmeticException ae) {\n                    System.out.println(ae.getMessage());\n                } catch (Exception e) {\n                    System.out.println(e.getMessage());\n                } finally {\n                    System.out.println(\"-------------------\");\n                }\n\n            } while (true);\n        }\n    }\n\n    private static double divisionPositive(int numerator, int denominator) {\n        if (numerator < 0 || denominator < 0) {\n            throw new NumberNegativeException(\"No negativos\");\n        }\n        double result = numerator / denominator;\n        return result;\n\n    }\n\n    public static class NumberNegativeException extends RuntimeException {\n\n        public NumberNegativeException(String message) {\n            super(message);\n        }\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/java/AnaLauDB.java",
    "content": "public class AnaLauDB {\n    public static class AnaLauDBException extends Exception {\n        public AnaLauDBException(String message) {\n            super(message);\n        }\n    }\n\n    public static void main(String[] args) throws AnaLauDB.AnaLauDBException {\n        System.out.println(\"Manejo de excepciones en AnaLauDB\");\n\n        try {\n            System.out.println(\"1.-Division de 9 entre 0\");\n            int resultado = 9 / 0;\n        } catch (ArithmeticException e) {\n            System.out.println(\"Error: Division por cero no permitida.\");\n            System.out.println(\"Tipo: \" + e.getClass().getSimpleName());\n            System.out.println(\"Mensaje: \" + e.getMessage() + \"\\n\");\n        }\n\n        try {\n            System.out.println(\"2.- Accediendo a indice fuera de rango\");\n            int[] datos = { 7, 8, 9 };\n            System.out.println(datos[5]);\n        } catch (ArrayIndexOutOfBoundsException e) {\n            System.out.println(\"Error: Indice fuera de rango.\");\n            System.out.println(\"Tipo: \" + e.getClass().getSimpleName());\n            System.out.println(\"Mensaje: \" + e.getMessage() + \"\\n\");\n        }\n\n        System.out.println(\"3.- Probando 'procesar (int a)' con varios casos:\");\n        procesar(5);\n        procesar(-1);\n        procesar(0);\n        procesar(10);\n    }\n\n    // EXTRA\n    public static int procesar(int a) throws AnaLauDBException {\n        // 1) Validación de negocio\n        if (a < 0) {\n            throw new IllegalArgumentException(\"El parámetro no puede ser negativo.\");\n        }\n        // 2) Regla de negocio: valor prohibido\n        if (a == 10) {\n            throw new AnaLauDBException(\"El 10 está prohibido por política interna.\");\n        }\n        // 3) Operación que puede causar ArithmeticException si a == 0\n        int resultado = 100 / a; // Si a == 0, lanza ArithmeticException\n        return resultado;\n    }\n\n    public static void probarProcesar(int a) {\n        System.out.println(\"-> Llamando procesar(\" + a + \")\");\n        try {\n            int r = procesar(a);\n            System.out.println(\"Resultado: \" + r);\n            System.out.println(\"No se ha producido ningún error.\");\n        } catch (AnaLauDBException | IllegalArgumentException | ArithmeticException e) {\n            System.out.println(\"Tipo de error: \" + e.getClass().getSimpleName());\n            System.out.println(\"Mensaje: \" + e.getMessage());\n        } finally {\n            System.out.println(\"Ejecución finalizada.\\n\");\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/java/AndrewCodev.java",
    "content": "public class AndrewCodev {\n\n\tpublic static void main(String[] args) {\n\t\t// EJEMPLO\n\t\tejemploExcepcion();\n\n\t\t// DIFICULTAD EXTRA\n\t\tint[] miArreglo = { 10, 5, 8, 65, 87 };\n\t\tvalidarEdad(5, miArreglo);\n\t}\n\n\tpublic static void ejemploExcepcion() {\n\t\ttry {\n\t\t\t// Intentamos realizar una operación que puede fallar\n\t\t\tint resultado = dividir(10, 0);\n\t\t\tSystem.out.println(\"Resultado: \" + resultado);\n\t\t} catch (ArithmeticException e) {\n\t\t\t// Manejo de una excepción específica\n\t\t\tSystem.out.println(\"Error: \" + e.getMessage());\n\t\t} catch (Exception e) {\n\t\t\t// Manejo de cualquier otra excepción\n\t\t\tSystem.out.println(\"Se produjo un error: \" + e.getMessage());\n\t\t} finally {\n\t\t\t// Esto siempre se ejecuta\n\t\t\tSystem.out.println(\"Operación de división finalizada.\");\n\t\t}\n\t}\n\n\tpublic static int dividir(int a, int b) throws ArithmeticException {\n\t\treturn a / b;\n\t}\n\n\t// DIFICULTAD EXTRA\n\n\t// Función para validar que la edad no sea un número negativo\n\tpublic static void validarEdad(int edad, int[] miArreglo) {\n\t\ttry {\n\t\t\t// Creamos una excepción manual con la palabra reservada throw\n\t\t\tif (edad < 0) {\n\t\t\t\tthrow new IllegalArgumentException(\"La edad debe ser mayor o igual a 18.\");\n\t\t\t} else {\n\t\t\t\tSystem.out.println(\"La edad es: \" + edad);\n\t\t\t}\n\t\t} catch (Exception e) {\n\t\t\t// Manejo de cualquier otra excepción\n\t\t\tSystem.out.println(\"Error: \" + e.getMessage());\n\t\t} finally {\n\t\t\tSystem.out.println(\"Validación edad finalizada\");\n\t\t}\n\n\t\t// acceso a un índice no existente\n\t\ttry {\n\t\t\tint posicion = miArreglo[10];\n\t\t} catch (ArrayIndexOutOfBoundsException e) {\n\t\t\tSystem.out.println(\"El índice no existe\");\n\t\t\te.printStackTrace();\n\t\t}\n\t}\n}"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/java/FranDev200.java",
    "content": "public class FranDev200 {\n\n    static void main() {\n\n        /*\n            EJERCICIO:\n            * Explora el concepto de manejo de excepciones según tu lenguaje.\n            * Fuerza un error en tu código, captura el error, imprime dicho error\n            * y evita que el programa se detenga de manera inesperada.\n            * Prueba a dividir \"10/0\" o acceder a un índice no existente de un listado para intentar provocar un error.\n         */\n\n        String[] miArray = new String[3];\n        miArray[0] = \"Hola\";\n        miArray[1] = \"Mundo\";\n        miArray[2] = \"Java\";\n\n        System.out.println(\"Tamaño de elementos del array: \" + miArray.length);\n        System.out.println(\"Valor numero 1: \" + miArray[0]);\n\n        try {\n            System.out.println(\"Valor numero 4: \" + miArray[3]);\n        } catch (ArrayIndexOutOfBoundsException e) {\n            System.out.println(\"\\nERROR:\");\n            System.out.println(e.getMessage());\n        }\n\n        int a = 20;\n        int b = 4;\n        int c = 0;\n\n        System.out.println(\"\\nCUENTAS MATEMÁTICAS\");\n        System.out.println(\"-------------------\");\n        System.out.println(\"20 + 4 = \" + (20 + 4));\n        System.out.println(\"0 - 4 = \" + (0 - 4));\n        System.out.println(\"20 * 0 = \" + (20 * 0));\n        System.out.println(\"0 / 4 = \" + (0 / 4));\n\n        try {\n            System.out.println(\"20 / 0 = \" + (20 / 0));\n        } catch (ArithmeticException e) {\n            System.out.println(\"\\nERROR:\");\n            System.out.println(e.getMessage());\n        }\n\n        System.out.println(\"\\n----------------------\");\n        System.out.println(\"Finalizando el programa.\");\n\n    /*\n\n        DIFICULTAD EXTRA (opcional):\n        * Crea una función que sea capaz de procesar parámetros, pero que también\n        * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n        * corresponderse con un tipo de excepción creada por nosotros de manera\n        * personalizada, y debe ser lanzada de manera manual) en caso de error.\n        * - Captura todas las excepciones desde el lugar donde llamas a la función.\n        * - Imprime el tipo de error.\n        * - Imprime si no se ha producido ningún error.\n        * - Imprime que la ejecución ha finalizado.\n\n     */\n\n        System.out.println(\"\\n\\nEJERCICIO EXTRA\");\n        System.out.println(\"===============\");\n\n        // EDAD CORRECTA NO SALTAN EXCEPCIONES\n        try {\n\n            if(comprobarMayoriaDeEdad(18)){\n                System.out.println(\"Es mayor de edad\");\n            }else{\n                System.out.println(\"Es menor de edad\");\n            }\n\n        } catch (NullPointerException e) {\n            System.out.println(e.getClass().getSimpleName() + \": \" + e.getMessage());\n            System.out.println(\"Edad no valida\");\n        }catch (IllegalArgumentException e) {\n            System.out.println(e.getClass().getSimpleName() + \": \" + e.getMessage());\n            System.out.println(\"Edad no valida\");\n        }catch (EdadExcesiva e) {\n            System.out.println(e.getClass().getSimpleName() + \": \" + e.getMessage());\n            System.out.println(\"Edad no valida\");\n        }\n\n        System.out.println(\"--------------\\n\");\n        // EDAD ELEVADA SALTA EXCEPCION PERSONALIZADA\n        try {\n\n            if(comprobarMayoriaDeEdad(230)){\n                System.out.println(\"Es mayor de edad\");\n            }else{\n                System.out.println(\"Es menor de edad\");\n            }\n\n        } catch (NullPointerException e) {\n            System.out.println(e.getClass().getSimpleName() + \": \" + e.getMessage());\n            System.out.println(\"Edad no valida\");\n        }catch (IllegalArgumentException e) {\n            System.out.println(e.getClass().getSimpleName() + \": \" + e.getMessage());\n            System.out.println(\"Edad no valida\");\n        }catch (EdadExcesiva e) {\n            System.out.println(e.getClass().getSimpleName() + \": \" + e.getMessage());\n            System.out.println(\"Edad no valida\");\n        }\n\n        System.out.println(\"--------------\\n\");\n        // EDAD NEGATIVA SALTA EXCEPCION DE ILLEGALARGUMENT\n        try {\n\n            if(comprobarMayoriaDeEdad(-20)){\n                System.out.println(\"Es mayor de edad\");\n            }else{\n                System.out.println(\"Es menor de edad\");\n            }\n\n        } catch (NullPointerException e) {\n            System.out.println(e.getClass().getSimpleName() + \": \" + e.getMessage());\n            System.out.println(\"Edad no valida\");\n        }catch (IllegalArgumentException e) {\n            System.out.println(e.getClass().getSimpleName() + \": \" + e.getMessage());\n            System.out.println(\"Edad no valida\");\n        }catch (EdadExcesiva e) {\n            System.out.println(e.getClass().getSimpleName() + \": \" + e.getMessage());\n            System.out.println(\"Edad no valida\");\n        }\n\n        System.out.println(\"--------------\\n\");\n        // EDAD NULL SALTA LA EXCEPCION DE NULLPOINTER\n        try {\n\n            if(comprobarMayoriaDeEdad(null)){\n                System.out.println(\"Es mayor de edad\");\n            }else{\n                System.out.println(\"Es menor de edad\");\n            }\n\n        } catch (NullPointerException e) {\n            System.out.println(e.getClass().getSimpleName() + \": \" + e.getMessage());\n            System.out.println(\"Edad no valida\");\n        }catch (IllegalArgumentException e) {\n            System.out.println(e.getClass().getSimpleName() + \": \" + e.getMessage());\n            System.out.println(\"Edad no valida\");\n        }catch (EdadExcesiva e) {\n            System.out.println(e.getClass().getSimpleName() + \": \" + e.getMessage());\n            System.out.println(\"Edad no valida\");\n        }\n\n        System.out.println(\"--------------\\n\");\n        System.out.println(\"Saliendo del programa...\");\n        System.out.println(\"- - - - \");\n\n    }\n\n    public static boolean comprobarMayoriaDeEdad(Integer edad) {\n\n        boolean resultado = false;\n\n        if( edad == null){\n            throw new NullPointerException(\"La edad no puede ser nula.\");\n        } else if( edad < 0){\n            throw new IllegalArgumentException(\"La edad no puede ser negativa.\");\n        }else if( edad > 120){\n            throw new EdadExcesiva(\"La edad no puede ser mayor a 120.\");\n        }else {\n            resultado = edad >= 18;\n        }\n\n        return resultado;\n\n    }\n\n    static class EdadExcesiva extends RuntimeException {\n\n        public EdadExcesiva(String mensaje) {\n            super(mensaje);\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/java/GlossyPath.java",
    "content": "/*\r\n * EJERCICIO:\r\n * Explora el concepto de manejo de excepciones según tu lenguaje.\r\n * Fuerza un error en tu código, captura el error, imprime dicho error\r\n * y evita que el programa se detenga de manera inesperada.\r\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\r\n * de un listado para intentar provocar un error.\r\n *\r\n * DIFICULTAD EXTRA (opcional):\r\n * Crea una función que sea capaz de procesar parámetros, pero que también\r\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\r\n * corresponderse con un tipo de excepción creada por nosotros de manera\r\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\r\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\r\n * - Imprime el tipo de error.\r\n * - Imprime si no se ha producido ningún error.\r\n * - Imprime que la ejecución ha finalizado.\r\n * \r\n * @author GlossyPath\r\n * \r\n * @version v1.0\r\n * \r\n * @since 09/10/2024\r\n * \r\n */\r\n\r\nclass ExcepcionSigno extends Exception{\r\n\r\n    public ExcepcionSigno (String msg){\r\n        super(msg);\r\n    }\r\n}\r\n\r\n\r\n\r\n\r\npublic class GlossyPath {\r\n\r\n    public static double operacionesAritmeticas(String signo, int num1, int num2) throws ExcepcionSigno, ArithmeticException, IllegalArgumentException{\r\n\r\n        double total;\r\n\r\n        if( !signo.equals(\"+\") && !signo.equals(\"-\") && !signo.equals(\"*\") && !signo.equals(\"/\")) {\r\n            throw new ExcepcionSigno (\"El signo introducido no es valido\");\r\n        }\r\n\r\n        if(signo.equals(\"/\") && num2 == 0 ) {\r\n            throw new ArithmeticException (\"No se puede dividir por 0\");\r\n        }\r\n\r\n        if (num1 < 0 || num2 < 0) {\r\n            throw new IllegalArgumentException(\"Los números no pueden ser negativos\");\r\n        }\r\n\r\n        switch(signo){\r\n\r\n            case(\"+\"):\r\n                return total = num1 + num2;\r\n            \r\n            case(\"-\"):\r\n                return total= num1 - num2;\r\n\r\n            case \"*\":\r\n                return total = num1 * num2;\r\n    \r\n            case \"/\":\r\n                return total = num1 / num2; \r\n        \r\n            default:\r\n                throw new Error(\"Error: Operador no válido.\");\r\n            }   \r\n        }\r\n\r\n\r\n\r\n\r\n    public static void division(double num1, double num2) throws ArithmeticException {\r\n\r\n        double total;\r\n\r\n        if(num2 == 0){\r\n            throw new ArithmeticException (\" No se puede dividir por 0\");\r\n        }\r\n\r\n        total = num1 / num2;\r\n\r\n       System.out.println(\"El resultado es: \" + total); \r\n    }\r\n\r\n\r\n\r\n\r\n    public static void main(String[] args) {\r\n\r\n        double resultadoOperaciones = 0;\r\n        \r\n        boolean errores = false;\r\n\r\n        try {\r\n          division(10, 0);\r\n\r\n        } catch (ArithmeticException e) {\r\n            e.printStackTrace();\r\n        }\r\n\r\n        try {\r\n            //resultadoOperaciones = operacionesAritmeticas(\"+\", 10, 20);\r\n            //resultadoOperaciones = operacionesAritmeticas(\"a\", 10, 20);\r\n            resultadoOperaciones = operacionesAritmeticas(\"/\", 20, 0);\r\n\r\n\r\n        } catch (ExcepcionSigno e) {\r\n            System.err.println(\"Error en el signo: \" + e.getMessage());\r\n            errores = true; \r\n\r\n        } catch (ArithmeticException e) {\r\n            System.err.println(\"Error aritmético: \" + e.getMessage());\r\n            errores = true; \r\n\r\n        } catch (IllegalArgumentException e) {\r\n            System.err.println(\"Error de argumento: \" + e.getMessage());\r\n            errores = true; \r\n\r\n        }\r\n\r\n        if (!errores) {\r\n            System.out.println(\"\\nEl resultado del método operacionesAritmeticas es: \" + resultadoOperaciones);\r\n            System.out.println(\"No se ha producido ningún error.\");\r\n        }\r\n\r\n        System.out.println(\"\\nLa ejecución ha finalizado.\");\r\n\r\n    }\r\n}\r\n\r\n\r\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/java/GustavoGomez19.java",
    "content": "public class GustavoGomez19 {\n    /* MANEJO DE EXCEPCIONES\n     * EJERCICIO:\n     * Explora el concepto de manejo de excepciones según tu lenguaje.\n     * Fuerza un error en tu código, captura el error, imprime dicho error\n     * y evita que el programa se detenga de manera inesperada.\n     * Prueba a dividir \"10/0\" o acceder a un índice no existente\n     * de un listado para intentar provocar un error. */\n    public static void main(String[] args){\n        ArrayList<Integer> array = new ArrayList<>();\n        for (int i = 0; i < 7; i++){\n            array.add(i);\n        }\n        try {\n            array.add(8, 9);\n        } catch (Exception e){\n            System.out.println(\"Indice fuera del rango: \" + e);\n        }\n        System.out.println(array);\n\n        try {\n            int resultado = 10 / 0;\n            System.out.println(\"Resultado: \" + resultado);\n        } catch (Exception e){\n            System.out.println(\"No se puede divir por 0!!!. \" + e);\n        }\n        System.out.println(\"Finalización del programa.\");\n\n        /* DIFICULTAD EXTRA (opcional):\n         * Crea una función que sea capaz de procesar parámetros, pero que también\n         * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n         * corresponderse con un tipo de excepción creada por nosotros de manera\n         * personalizada, y debe ser lanzada de manera manual) en caso de error.\n         * - Captura todas las excepciones desde el lugar donde llamas a la función.\n         * - Imprime el tipo de error.\n         * - Imprime si no se ha producido ningún error.\n         * - Imprime que la ejecución ha finalizado. */\n        try {\n            procesarParametros(-7);\n            procesarParametros(0);\n            procesarParametros(51);\n        } catch (MiExcepcionPersonalizada e){\n            System.out.println(\"Error personalizada: \" + e.getMessage());\n        }\n        finally {\n            System.out.println(\"Ejecución finalzada!.\");\n        }\n\n    }\n    // Extra\n    static class MiExcepcionPersonalizada extends Exception{\n        public MiExcepcionPersonalizada(String mensaje) {\n            super(mensaje);\n        }\n    }\n\n    public static void procesarParametros(int parametro) throws MiExcepcionPersonalizada{\n        try {\n            if (parametro < 0){\n                throw  new IllegalArgumentException(\"El parámetro no puede ser negativo.\");\n            } else if (parametro == 0) {\n                throw new ArithmeticException(\"No se puede dividir por 0.\");\n            } else if (parametro > 50) {\n                throw new MiExcepcionPersonalizada(\"El parámetro es muy grande\");\n            }\n            System.out.println(\"No se ha producido ningún error.\");\n        } catch (IllegalArgumentException e){\n            System.out.println(\"Error: \" + e.getMessage());\n        } catch (ArithmeticException e){\n            System.out.println(\"Error: \" + e.getMessage());\n        }\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/java/Jeigar2.java",
    "content": "public class Jeigar2 {\n    /*\n     * EJERCICIO:\n     * Explora el concepto de manejo de excepciones según tu lenguaje.\n     * Fuerza un error en tu código, captura el error, imprime dicho error\n     * y evita que el programa se detenga de manera inesperada.\n     * Prueba a dividir \"10/0\" o acceder a un índice no existente\n     * de un listado para intentar provocar un error.\n     *\n     * DIFICULTAD EXTRA (opcional):\n     * Crea una función que sea capaz de procesar parámetros, pero que también\n     * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n     * corresponderse con un tipo de excepción creada por nosotros de manera\n     * personalizada, y debe ser lanzada de manera manual) en caso de error.\n     * - Captura todas las excepciones desde el lugar donde llamas a la función.\n     * - Imprime el tipo de error.\n     * - Imprime si no se ha producido ningún error.\n     * - Imprime que la ejecución ha finalizado.\n     */\n\n    public static void main(String[] args) {\n        boolean errores = false;\n        try {\n            int i = 10/0;\n        }catch (ArithmeticException e) {\n            System.out.println(e.toString());\n        }\n\n        try {\n//            recibeParametros(\"123456789\", \"Jorge Lopez Borrego\", \"Texto\");// error de tiempo\n//            recibeParametros(\"123456789\", \"Jorge\", \"23\"); // error de titular no tiene nombre compleo\n//            recibeParametros(\"bb-3456789\", \"Jorge Lopez Borrego\", \"23\"); // error de telefono mal formato\n            recibeParametros(\"123456789\", \"Jorge Lopez Borrego\", \"23\"); // sin errores\n        } catch (NumberFormatException e) {\n            System.err.println(\"el parametro no está bien inicializado \" + e.getMessage());\n            errores = true;\n        } catch (IndexOutOfBoundsException e){\n            System.err.println(\"El valor es demasiado corto debe poner nombre y apellido \" + e.getMessage());\n            errores = true;\n        } catch (TelefonoMalFormadoException e) {\n            System.err.println(\"El telefono está mal expresado \" + e.getMessage());\n            errores = true;\n        }\n        if(!errores) {\n            System.out.println(\"No se ha producido ningun tipo de error\");\n        }\n        System.out.println(\"La ejecución ha finalizado\");\n\n    }\n\n    public static void recibeParametros(String telefono, String titular, String tiempo) throws NumberFormatException, IndexOutOfBoundsException, TelefonoMalFormadoException{\n        int tempo = Integer.parseInt(tiempo);\n        String nombreTroceado[] =  titular.split(\" \");\n        String apellido1 = nombreTroceado[1];\n        if(telefono.length() != 9 || telefono.toUpperCase() != telefono.toLowerCase()){\n            throw new TelefonoMalFormadoException(telefono);\n        }\n\n    }\n\n}\nclass TelefonoMalFormadoException extends Exception {\n    public TelefonoMalFormadoException(){\n        super();\n    }\n    public TelefonoMalFormadoException(String telefono){\n        super(telefono);\n    }\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/java/JesusAntonioEEscamilla.java",
    "content": "import java.util.Arrays;\nimport java.util.List;\n\n/** #10 - Java -> Jesus Antonio Escamilla */\n\npublic class JesusAntonioEEscamilla {\n    public static void main(String[] args) {\n    //---EJERCIÓ---\n        // Division en 10 / 0\n        System.out.println(\"Dividir entre 10\");\n        try {\n            // Código que puede generar una excepción\n            int resultado = divide(10, 0);\n            System.out.println(\"El resultado es: \" + resultado);\n        } catch (ArithmeticException e) {\n            // Manejo de la excepción específica\n            System.out.println(\"Error aritmético: \" + e.getMessage());\n        } catch (Exception e) {\n            // Manejo de la excepción general\n            System.out.println(\"Ocurrió un error: \" + e.getMessage());\n        } finally{\n            // Este bloque siempre se ejecuta\n            System.out.println(\"Operación finalizada\");\n        }\n\n        // Identificar el numero de una lista\n        System.out.println(\"\\nEncontrar un indice a la lista\");\n        try {\n            // Código que puede generar una excepción\n            int newList = getElement(5);\n            System.out.println(\"El valor es : \" + newList);\n        } catch (ArrayIndexOutOfBoundsException e) {\n            // Manejo de la excepción específica\n            System.out.println(\"Error obtener indice: \" + e.getMessage());\n        } catch (Exception e) {\n            // Manejo de la excepción general\n            System.out.println(\"Ocurrió un error: \" + e.getMessage());\n        } finally{\n            // Este bloque siempre se ejecuta\n            System.out.println(\"Operación finalizada\");\n        }\n    //---EXTRA---\n        System.out.println(\"\\nExtra\");\n        // El TRY-CATCH-FINALLY para la ejecución\n        try {\n            procesarParametros(Arrays.asList(1, 2, 3, 4));\n        } catch (Exception e) {\n            System.err.println(\"Ocurrió un error: \" + e.getMessage());\n        } finally {\n            System.out.println(\"Programa Finalizado\");\n        }\n    }\n\n    //---EJERCIÓ---\n    public static int divide(int numerator, int denominator) throws ArithmeticException{\n        if (denominator == 0) {\n            throw new  ArithmeticException(\"No se puede dividir por cero\");\n        }\n        return numerator / denominator;\n    }\n\n    public static int getElement(int index) throws ArrayIndexOutOfBoundsException{\n        int[] number = {1, 2, 3};\n        if (number[index] == index) {\n            throw new ArrayIndexOutOfBoundsException(\"No encuentra el valor\");\n        }\n        return number[index];\n    }\n\n\n\n    /**-----DIFICULTAD EXTRA-----*/\n\n    // Mi excepción Personalizado\n    static class excepciónPersonalizada extends Exception {\n        public excepciónPersonalizada(String message) {\n            super(message);\n        }\n    }\n\n    // La función del programa (Utilize una lista)\n    public static void procesarParametros(List<Object> lista) throws excepciónPersonalizada, IllegalArgumentException {\n        if (lista.size() < 3) {\n            throw new IllegalArgumentException(\"Tiene que ser mas de 3 elementos\");\n        }\n\n        if (!(lista.get(2) instanceof Number)) {\n            throw new IllegalArgumentException(\"Los parámetros tienen que ser del mismo tipo\");\n        }\n\n        if (lista.isEmpty()) {\n            throw new excepciónPersonalizada(\"La lista no es válida\");\n        }\n\n        System.out.println(\"La ejecución ha finalizado sin errores\");\n    }\n\n    /**-----DIFICULTAD EXTRA-----*/\n}"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/java/JimsimroDev.java",
    "content": "import java.util.ArrayList;\nimport java.util.List;\nimport java.util.Scanner;\n\npublic class JimsimroDev {\n\n  public static class JimsimroDevException extends RuntimeException {\n    public JimsimroDevException(String message) {\n      super(message);\n    }\n  }\n\n  static double divide(double numerator, double denominator) {\n    if (denominator == 0) {\n      throw new ArithmeticException(\"No se puede dividir entre 0\");\n    }\n    return numerator / denominator;\n  }\n\n  static void procesarParametros(List<Integer> parametros) {\n    try {\n      System.out.println(parametros.get(2));\n      System.out.println(parametros.get(0) / parametros.get(1));\n    } catch (IndexOutOfBoundsException | ArithmeticException e) {\n      System.out.println(e.getClass().getName() + \" generado: \" + e.getMessage());\n    }\n    System.out.println(\"Finalizando programa...\");\n  }\n\n  static void procesarParametros2(List<Object> parametros) {\n    try {\n      validarParametros(parametros);\n      System.out.println(parametros.get(2));\n      validarParametros(parametros);\n      System.out.println((int) parametros.get(0) / (int) parametros.get(1));\n      validarParametros(parametros);\n      System.out.println((int) parametros.get(2) + 5);\n      validarParametros(parametros);\n\n      // Lanzar un NullPointerException en la list\n      // parametros.set(1, null);\n      // System.out.println(parametros.get(1).toString());\n      System.out.println(\"El programa no tiene errores ...\");\n    } catch (IndexOutOfBoundsException | ArithmeticException | JimsimroDevException e) {\n      System.out.println(e.getClass().getName() + \" generado: \" + e.getMessage());\n    } catch (Exception e) {\n      System.out.println(e.getClass().getName() + \" Error desconocido: \" + e.getMessage());\n    } finally {\n      System.out.println(\"Finalizando el programa...\");\n    }\n  }\n\n  static void validarParametros(List<Object> parametros) {\n    if (parametros.size() < 3) {\n      throw new IndexOutOfBoundsException(\"Se requieren al menos 3 parámetros\");\n    }\n    if ((int) parametros.get(1) == 0) {\n      throw new ArithmeticException(\"No se puede dividir entre 0\");\n    }\n    if (parametros.get(2) instanceof String) {\n      throw new JimsimroDevException(\"El tercer parámetro no puede ser una cadena\");\n    }\n  }\n\n  public static void main(String[] args) {\n    // try con recursos\n    try (Scanner scanner = new Scanner(System.in)) {\n      System.out.println(\"Ingrese el numerador: \");\n      double numerador = scanner.nextDouble();\n      System.out.println(\"Ingrese el denominador: \");\n      double denominador = scanner.nextDouble();\n      System.out\n          .println(String.format(\"Dividir %f/%f: %f\", numerador, denominador, divide(numerador, denominador)));\n    } catch (Exception e) {\n      System.out.println(\"Error aritmético: \" + e.getMessage());\n    }\n\n    // Division 10/0\n    // System.out.println(String.format(\"Dividir 10/0: %f\", divide(10, 0)));\n\n    try {\n      System.out.printf(\"Dividir 10/2: %d\", (10 / 2));\n      System.out.println();\n      // System.out.println(String.format(\"Dividir 10/0: %f\", (10 / 0)));\n\n      List<Integer> list = new ArrayList<>() {\n        {\n          add(1);\n          add(0);\n          add(3);\n          add(4);\n        }\n      };\n\n      System.out.println(list.get(4));\n      procesarParametros(list);\n    } catch (Exception e) {\n      System.out.println(\"Error aritmético: \" + e.getMessage());\n    }\n\n    // DIFICULTAD EXTRA (opcional):\n    List<Object> parametros = new ArrayList<>();\n    parametros.add(1);\n    parametros.add(2);\n    parametros.add(3);\n    procesarParametros2(parametros);\n  }\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/java/Josegs95.java",
    "content": "import java.util.ArrayList;\nimport java.util.List;\n\npublic class Josegs95 {\n    public static void main(String[] args) {\n        //Excepciones\n        try{\n            int a = 10 / 0; //Comentar esta línea para comprobar el caso de abajo\n\n            List<Object> list = new ArrayList<>();\n            list.get(8);\n        } catch (Exception e){\n            System.out.println(\"Se ha producido un error: \" + e.getMessage());\n        }\n\n        //Reto\n        System.out.println(\"\\n\");\n        retoFinal();\n    }\n\n    public static void retoFinal(){\n        Object[] params = {\"git\", \"commit\", \"-m\", \"'#10 - Java'\"};\n        //Object[] params = {\"git\", \"commit\", \"-m\", 85};\n        //Object[] params = {\"ls\", \"commit\", \"-m\", \"'#10 - Java'\"};\n        boolean error = false;\n\n        try{\n\n            processParams(params);\n        } catch (IndexOutOfBoundsException e) {\n            System.out.println(\"El número de parametros debe ser de 4 o mas.\");\n            error = true;\n        } catch (ClassCastException e) {\n            System.out.println(\"El elemento número 4 deber ser una cadena de texto\");\n            error = true;\n        } catch (NotRightCommandException e) {\n            System.out.println(\"El elemento número 1 deber ser el comando 'git'\");\n            error = true;\n        } catch (Exception e) {\n            System.out.println(\"Se ha producido un error inesperado: \" + e.getMessage());\n            error = true;\n        } finally {\n            if (!error)\n                System.out.println(\"El programa no ha tenido ningún error\");\n            System.out.println(\"El programa finaliza.\");\n        }\n\n    }\n\n    private static void processParams(Object[] params) throws Exception{\n        if (params.length < 4)\n            throw new IndexOutOfBoundsException();\n\n        if (!(params[3] instanceof String)){\n            throw new ClassCastException();\n        }\n\n        if (!params[0].toString().toLowerCase().equals(\"git\"))\n            throw new NotRightCommandException();\n\n        String message = (String) params[3];\n        System.out.println(\"El mensaje del commit es: \" + message);\n    }\n\n    public static class NotRightCommandException extends Exception{\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/java/RodrigoGit87.java",
    "content": "\nimport java.util.InputMismatchException;\n\npublic class RodrigoGit87 {\n\n    public static void main(String[] args) {\n\n        try {\n            int dividir = 10 / 0;\n        } catch (ArithmeticException a) { // Excepcion aritmetica\n            System.err.println(\"Error aritmetico: \" + a.getMessage());\n        } finally {\n            System.out.println(\"programa continua... \");\n        }\n        System.out.println(\"\");\n\n        // ------- EXTRA ----------\n        RodrigoGit87.calcularDivision(20, 4); // Division correcta\n        System.out.println(\"\");\n        RodrigoGit87.calcularDivision(20, 0); // Division por 0, debe fallar\n        System.out.println(\"\");\n        RodrigoGit87.calcularDivision(-20, 4); // Division con numero negativo, debe fallar por excepcion personalizada,\n                                               // no por que no se pueda aritmeticamente.\n    }\n\n    public static void calcularDivision(int num1, int num2) {\n        try {\n            if (num1 < 0 || num2 < 0) {\n                throw new ExcepcionPersonalizada(\"No se permite dividir numeros negativos\"); // Excepcion personalizada\n            }\n            int resultado = num1 / num2;\n            System.out.println(\"Resultado: \" + resultado);\n        } catch (InputMismatchException e) { // Excepcion inputmismatch se lanza cuando se introduce un tipo de dato\n                                             // incorrecto\n            System.err.println(\"Error: \" + e.getMessage());\n        } catch (Exception h) { // Excepcion general\n            System.err.println(\"Error: \" + h.getMessage());\n        } finally {\n            System.out.println(\"programa continua... \");\n        }\n    }\n\n    public static class ExcepcionPersonalizada extends Exception {\n        public ExcepcionPersonalizada(String message) {\n            super(message);\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/java/TofeDev.java",
    "content": "public class TofeDev {\n    public static void main(String[] args) throws Exception {\n         \n        int num1= 10, num2 = 0;\n        int resultado;\n\n        try {\n            resultado = num1/num2;\n            System.out.println(resultado);\n        } catch (Exception e) {\n            e.printStackTrace();\n        } finally {\n            System.out.println(\"Se ha realizado la operación\");\n        }\n\n        //Extra\n        Calculadora calculadora = new Calculadora();\n        \n        try {\n            resultado = calculadora.dividir(num1, num2);\n            System.out.println(resultado);\n            System.out.println(\"Se ha realizado la operación con éxito\");\n        } catch (CalcException e) {\n            e.printStackTrace();\n        } finally {\n            System.out.println(\"Programa finalizado\");\n        }\n\n        try {\n            resultado = calculadora.resto(num1, num2);\n            System.out.println(resultado);\n            System.out.println(\"Se ha realizado la operación con éxito\");\n        } catch (CalcException e) {\n            e.printStackTrace();\n        } finally {\n            System.out.println(\"Programa finalizado\");\n        }\n\n        int[] array = new int[5];\n        try {\n            array[7] = 7;\n        } catch (Exception e) {\n            System.out.println(\"Index fuera de rango\");\n        } finally {\n            System.out.println(\"Programa finalizado\");\n        }\n    }\n\n    /* DIFICULTAD EXTRA (opcional):\n    * Crea una función que sea capaz de procesar parámetros, pero que también\n    * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n    * corresponderse con un tipo de excepción creada por nosotros de manera\n    * personalizada, y debe ser lanzada de manera manual) en caso de error.\n    * - Captura todas las excepciones desde el lugar donde llamas a la función.\n    * - Imprime el tipo de error.\n    * - Imprime si no se ha producido ningún error.\n    * - Imprime que la ejecución ha finalizado. \n    */\n\n    public static class Calculadora {\n\n        public int dividir(int dividendo, int divisor) throws CalcException {\n            if (divisor == 0) throw new CalcException(\"No se puede dividir por cero\");\n            return dividendo/divisor;\n        }\n\n        public int resto(int dividendo, int divisor) throws CalcException {\n            if (divisor == 0) throw new CalcException(\"No se puede sacar el resto si el divisor es 0\");\n            return dividendo%divisor;\n        }\n\n    }\n\n    public static class CalcException extends Exception {\n\n        String descripcion;\n        \n        public CalcException(String descripcion) {\n            setDescripcion(descripcion);\n        }\n        \n        @Override\n        public String getMessage() {\n            return getDescripcion();\n        }\n        \n        //Getters y setters\n        public String getDescripcion() {\n            return descripcion;\n        }\n        \n        public void setDescripcion(String descripcion) {\n            this.descripcion = descripcion;\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/java/Worlion.java",
    "content": "import java.util.Arrays;\nimport java.util.List;\n\npublic class Worlion {\n    \n\n    public static final String GREEN = \"\\u001B[32m\";\n    public static final String RED = \"\\u001B[31m\";\n    public static final String RED_BACKGROUND = \"\\u001B[41m\";\n    public static final String ANSI_RESET = \"\\u001B[0m\";\n\n    public static void main(String[] args) {\n        new Worlion().run();\n    }\n\n    public void run() {\n        System.out.println(\"Resultado obtenido: \"+div(7, 0));\n\n        testArray();\n\n        testExtra();\n        \n    }\n/*\n * EJERCICIO: Excepciones en Java\n */\n\n    public int div(int a, int b) {\n        System.out.println(\"\\nDividimos \"+a+\" entre \"+ b+\":\");\n        int result = 0;\n        try {\n            result = a/b;\n        } catch (ArithmeticException e) {\n            System.err.println(RED +\"ERROR:\"+ ANSI_RESET+\" You can not divide by 0\");\n        }\n        return result;\n    }\n\n    public void testArray() {\n        List<String> list = Arrays.asList(new String[]{\"A\", \"B\", \"C\"});\n        System.out.println(\"\\nRecorremos la lista \"+list);\n        try{\n            for(int i = 0; i <= list.size(); i++) {\n                System.out.println(\"Position: \"+i+\" - Value: \"+list.get(i));\n            }\n        }\n        catch (ArrayIndexOutOfBoundsException e) {\n            System.err.println(RED +\"ERROR:\"+ ANSI_RESET + e);\n        }\n        System.out.println(\"Chimpun!\");\n    }\n\n/* DIFICULTAD EXTRA (opcional):\n */\n\n        class myCustomException extends Exception {\n        public myCustomException(String errorMessage) {\n            super(errorMessage);\n        }\n    }\n\n    private boolean isVocal(char c){\n        return c == 'a' ||c == 'e' ||c == 'i' ||c == 'o' ||c == 'u';\n    }\n\n    private char exceptionsFunction(String s, int num) throws Exception {\n    \n\n        if(s.isEmpty()){\n            throw new myCustomException(\"The string must be not empty\");\n        }\n        char c =  s.charAt(num);\n        if(isVocal(c)){\n            throw new Exception(\"Odio las vocales!!\");\n        }\n        return s.charAt(num);\n    }\n\n    private void testExtra() {\n        System.out.println(\" \\n ---- 🌩 DIFICULTAD EXTRA 🌩 ----\\n\");\n\n        String[] strings = {\"\",\"patata\", \"carcamusa\", \"ascapatipucyuelaimepipedo\", \"choripan\"};\n        int[] indexes = {2,-1,20, 11, 2};\n        int errorCount = 0;\n\n        for (int i = 0; i < strings.length; i++) {\n            try {\n                System.out.println(\"Word: \" + strings[i] + \" - Index: \"+ indexes[i] + \" - CharAt: \"+exceptionsFunction(strings[i], indexes[i]));\n            }\n            catch (myCustomException e){\n                System.err.println(RED +\"ERROR - MY CUSTOM EXCEPTION: \"+ ANSI_RESET + e);\n                errorCount++;\n            } \n            catch (StringIndexOutOfBoundsException e){\n                System.err.println(RED +\"ERROR - NOS HEMOS SALIDO :(: \"+ ANSI_RESET + e);\n                errorCount++;\n            } \n            catch (Exception e) {\n                System.err.println(RED +\"ERROR - OTRAS: \"+ ANSI_RESET + e);\n                errorCount++;\n            }\n        }\n        System.out.println(\"Ejecución terminada. Se han producido (y recuperado) \"+errorCount+\" errores\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/java/XhuaSpy.java",
    "content": "import java.util.InputMismatchException;\nimport java.util.Scanner;\n\nclass ParsearStringAEnteroException extends NumberFormatException{\n    public ParsearStringAEnteroException(String mensajito){\n        super(mensajito);\n    }\n}\n\npublic class XhuaSpy {\n    public static void main(String[] args) {\n        try {\n            System.out.println(EncontrarDivisionEnArreglo(\"45\", \"5\", new int[] {1,2,3,4,5,6,7,8,9,10}));\n            //System.out.println(EncontrarDivisionEnArreglo(null, null, new int[] {1,2,3,4,5,6,7,8,9,10}));\n            //System.out.println(EncontrarDivisionEnArreglo(\"1\", \"0\", new int[] {1,2,3,4,5,6,7,8,9,10}));\n            //System.out.println(EncontrarDivisionEnArreglo(\"45\", \"5\", new int[] {}));\n        } catch ( IllegalArgumentException | ArithmeticException | NullPointerException e) {\n            System.out.println(e.getMessage());\n        }\n\n        try {\n            excepcionIngresoDeDatosNumericos();\n        } catch (ArithmeticException | InputMismatchException ae) {\n            System.out.println(ae.getMessage());\n        }\n    }\n\n    //Le pide al usuario dos valores, el divisor debe ser diferente de 0;\n    private static void excepcionIngresoDeDatosNumericos() throws InputMismatchException, ArithmeticException{\n        try (Scanner sc = new Scanner(System.in)) {\n            System.out.print(\"\\nIngresa el dividendo: \");\n            int dividendo = sc.nextInt();\n\n            System.out.print(\"\\nIngresa el divisor: \");\n            int divisor = sc.nextInt();\n\n            System.out.println(\"(dividendo/divisor) = \" + (dividendo / divisor));\n        } catch ( InputMismatchException e) {\n            throw new InputMismatchException(\"Ingresaste un valor no numérico. Intenta de nuevo\");\n        } catch (ArithmeticException ae) {\n            throw new ArithmeticException(\"No se puede dividir por cero\");\n        }\n    }\n\n    /**\n     * Este método se encarga de hacer una división, transformando los números ingresados como strings\n     * y los divide, esa division es buscada en el arreglo.\n     **/\n    public static int EncontrarDivisionEnArreglo(String valorDividendo, String valorDivisor, int[] array) throws\n            IllegalArgumentException, ParsearStringAEnteroException, ArithmeticException, NullPointerException {\n\n        //si el usuario pasa un valor null se devuelve una NullPointerException;\n        if (valorDividendo == null || valorDivisor ==null) throw new NullPointerException(\"Los valores no pueden ser nulos\");\n\n        int valorDividido = getValorDividido(valorDividendo, valorDivisor);\n\n        boolean encontrado = false;\n        for (int entero_array : array) {\n            if (entero_array == valorDividido) {\n                encontrado = true;\n                break;\n            }\n        }\n        \n        if (!encontrado)\n            throw new IllegalArgumentException(\"El número calculado no está presente en el arreglo.\");\n\n        return valorDividido; //Retorna el valor de la división \n    }\n    \n    //Devuelve el valor ya calculado de la división si los valores son enteros. \n    private static int getValorDividido(String valorDividendo, String valorDivisor) throws \n            ParsearStringAEnteroException, ArithmeticException {\n        \n        int dividendo, divisor;\n\n        try {\n            //trata de transformar el string a entero.\n            dividendo = Integer.parseInt(valorDividendo);\n            divisor = Integer.parseInt(valorDivisor);\n        } catch (NumberFormatException e ) {\n            //Lanza la exception personalizada para el fallo al parsear los números.\n            throw new ParsearStringAEnteroException(\"Que malparida cadena, no es un entero coño\");\n        }\n\n        if (divisor == 0)\n            //Lanza una excepción si el divisor es 0.\n            throw new ArithmeticException(\"El numero no puede ser 0 bb\");\n\n        return (dividendo / divisor); \n    }\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/java/alexdevrep.java",
    "content": "package _10_Excepciones;\n\nimport java.util.ArrayList;\n\npublic class _10_Excepciones {\n\n\n\n    /*\n     * EJERCICIO:\n     * Explora el concepto de manejo de excepciones según tu lenguaje.\n     * Fuerza un error en tu código, captura el error, imprime dicho error\n     * y evita que el programa se detenga de manera inesperada.\n     * Prueba a dividir \"10/0\" o acceder a un índice no existente\n     * de un listado para intentar provocar un error.\n     *\n     * DIFICULTAD EXTRA (opcional):\n     * Crea una función que sea capaz de procesar parámetros, pero que también\n     * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n     * corresponderse con un tipo de excepción creada por nosotros de manera\n     * personalizada, y debe ser lanzada de manera manual) en caso de error.\n     * - Captura todas las excepciones desde el lugar donde llamas a la función.\n     * - Imprime el tipo de error.\n     * - Imprime si no se ha producido ningún error.\n     * - Imprime que la ejecución ha finalizado.\n     */\n    public static void main(String[] args){\n        //Declaramos las variables necesarias\n        int numero1= 10;\n        int numero2= 0;\n        //Creamos un listado y le insertamos los objetos que van en el\n        ArrayList<String> listado = new ArrayList<String>();\n        listado.add(\"Hola\");\n        listado.add(\"Java\");\n        listado.add(\"Mundo\");\n        listado.add(\"Alexdevrep\");\n\n        try{\n            //Intentamos dividir ambos numeros\n            int resultado= dividir(numero1,numero2);\n            System.out.println(resultado);\n        }\n        catch(ArithmeticException e){ //Tipo de excepción predefinida para una división por 0\n            System.out.println(\"No se puede dividir un número por cero\");\n        }\n        finally{\n            System.out.println(\"Programa finalizado\");\n        }\n\n        try{\n            //Intentamos acceder a un indice del array que no existe\n            System.out.println(listado.get(5));\n        }\n        catch(IndexOutOfBoundsException e){ //Tipo de excepción predefinida para cuando no existe indice en el array\n            System.out.println(\"Indice no existente\");\n        }\n        finally {\n            System.out.println(\"Cerrando el programa\");\n        }\n\n        //Dificultad EXTRA\n        //Declaramos una varible más\n        int numero3= 2;\n\n        try{\n            int producto=multiplo (numero3);\n\n            if (numero3 < 0) {\n                throw new numeroNegativo(\"El número no puede ser negativo\");\n            }\n            else if (String.valueOf(numero3).length()>1){\n                throw new dosCifras(\"El número no puede tener más de una cifra\");\n            }\n            else{\n                System.out.println(producto);\n            }\n\n        }\n        catch(NumberFormatException e){\n            System.out.println(\"Debe de existir un número obligatorio\");\n\n        }\n        catch(numeroNegativo e){\n            System.out.println(e.getMessage());\n\n        }\n        catch(dosCifras e){\n            System.out.println(e.getMessage());\n        }\n        finally{\n            System.out.println(\"Cerrando el programa\");\n        }\n\n\n\n\n\n\n\n    }\n\n    public static int dividir (int numero1, int numero2) {\n        return numero1 / numero2;\n    }\n    //Dificultad EXTRA\n    public static int multiplo(int numero3){\n        return 5 * numero3;\n    }\n\n    //Vamos a crear excepciones personalizadas\n    static class numeroNegativo extends Exception{\n        public numeroNegativo(String mensaje){\n            super(mensaje);\n        }\n\n    }\n    static class dosCifras extends Exception{\n        public dosCifras(String mensaje1){\n            super(mensaje1);\n        }\n    }\n\n\n\n\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/java/asjordi.java",
    "content": "public class Main {\n\n    /**\n     * Una excepción es un evento que ocurre durante la ejecución de un programa y que interrumpe el flujo normal de las instrucciones.\n     * Existen dos tipos de excepciones: las comprobadas y las no comprobadas.\n     * Las excepciones comprobadas (CHECKED) son aquellas que el compilador obliga a manejar,\n     * mientras que las excepciones no comprobadas (UNCHECKED) son aquellas que el compilador no obliga a manejar.\n     * Generalmente las de tipo Checked estan asociadas a problemas externos al código, como por ejemplo la lectura de un archivo que no existe.\n     * Las de tipo Unchecked estan asociadas a problemas internos del código, como por ejemplo una división por cero.\n     */\n\n    public static void main(String[] args) throws MiExcepcion {\n\n        ejemploExcepcion();\n        procesarParametros(0, new int[]{1, 2, 3, 4, 5});\n\n\n    }\n\n    /**\n     * EJERCICIO:\n     * Explora el concepto de manejo de excepciones según tu lenguaje.\n     * Fuerza un error en tu código, captura el error, imprime dicho error\n     * y evita que el programa se detenga de manera inesperada.\n     * Prueba a dividir \"10/0\" o acceder a un índice no existente\n     * de un listado para intentar provocar un error.\n     */\n    static void ejemploExcepcion() {\n        int a = 10;\n        int b = 0;\n        int c = 0;\n\n        try {\n            c = a / b;\n        } catch (ArithmeticException e) {\n            System.out.println(\"No se puede dividir por cero\");\n            e.printStackTrace();\n        }\n\n        System.out.println(\"El resultado de la división es: \" + c);\n    }\n\n    /**\n     * DIFICULTAD EXTRA (opcional):\n     * Crea una función que sea capaz de procesar parámetros, pero que también\n     * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n     * corresponderse con un tipo de excepción creada por nosotros de manera\n     * personalizada, y debe ser lanzada de manera manual) en caso de error.\n     * - Captura todas las excepciones desde el lugar donde llamas a la función.\n     * - Imprime el tipo de error.\n     * - Imprime si no se ha producido ningún error.\n     * - Imprime que la ejecución ha finalizado.\n     */\n    static class MiExcepcion extends Exception {\n        public MiExcepcion(String mensaje) {\n            super(mensaje);\n        }\n    }\n\n    static void procesarParametros(int a, int[] arr) throws MiExcepcion {\n        // división por cero\n        try {\n            int c = arr[0] / a;\n        } catch (ArithmeticException e) {\n            System.out.println(\"No se puede dividir por cero\");\n            e.printStackTrace();\n        }\n\n        // acceso a un índice no existente\n        try {\n            int d = arr[10];\n        } catch (ArrayIndexOutOfBoundsException e) {\n            System.out.println(\"El índice no existe\");\n            e.printStackTrace();\n        }\n\n        // lanzar excepción personalizada\n        if (a == 0) {\n            throw new MiExcepcion(\"El valor de a no puede ser 0\");\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/java/cesar-ch.java",
    "content": "public class Main {\n    public static void main(String[] args) {\n        try {\n            int resultado = dividePorCero(10, 0);\n            System.out.println(\"El resultado de la división es: \" + resultado);\n        } catch (ArithmeticException e) {\n            System.out.println(\"Error: \" + e.getMessage());\n        } finally {\n            System.out.println(\"La ejecución ha finalizado.\");\n        }\n\n        try {\n            int[] array = {1, 2, 3};\n            System.out.println(\"El elemento en el índice 3 es: \" + array[3]);\n        } catch (ArrayIndexOutOfBoundsException e) {\n            System.out.println(\"Error: \" + e.getMessage());\n        } finally {\n            System.out.println(\"La ejecución ha finalizado.\");\n        }\n\n        try {\n            procesarParametros(\"ERROR\");\n        } catch (CustomException ce) {\n            System.out.println(\"Error personalizado: \" + ce.getMessage());\n        } catch (Exception e) {\n            System.out.println(\"Error: \" + e.getMessage());\n        } finally {\n            System.out.println(\"La ejecución ha finalizado.\");\n        }\n    }\n\n    public static void procesarParametros(String parametro) throws CustomException {\n        if (parametro.equalsIgnoreCase(\"error\")) {\n            throw new CustomException(\"Se ha producido un error personalizado.\");\n        }\n    }\n\n    public static int dividePorCero(int dividendo, int divisor) {\n        return dividendo / divisor;\n    }\n}\n\nclass CustomException extends Exception {\n    public CustomException(String message) {\n        super(message);\n    }\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/java/chartypes.java",
    "content": "public class chartypes {\n\n  public static void main(String[] args) {\n\n    // Exercise\n    try {\n      System.out.println(10 / 0);\n    } catch (ArithmeticException e) {\n      System.out.println(e.getMessage());\n    }\n\n    System.out.println(\"/////////////////EXTRA: ///////////////////////\");\n    // Extra\n\n    int[] numbers = { 2, 3, };\n    int[] numbs = { 1, 3, 2, 3, 0 };\n\n    try {\n      myFunction(numbers, 1.8f);\n      System.out.println(\"1 jejeje\");\n    } catch (ArrayIndexOutOfBoundsException | MyException e) {\n      System.out.println(e.getMessage());\n    }\n\n    try {\n      myFunction(new int[] { 2, 3, 4, 5, 1 }, -1.8f);\n      System.out.println(\"2 jejeje\");\n    } catch (MyException e) {\n      System.out.println(e.getMessage());\n    }\n\n    try {\n      myFunction(numbs, 51.8f);\n      System.out.println(\"Any error has ocurred \");\n    } catch (ArithmeticException | MyException e) {\n      System.out.println(e.getMessage());\n    }\n\n    System.out.println(\"Program finished\");\n  }\n\n  public static void myFunction(int[] numbers, float floatNumber)\n      throws MyException, ArrayIndexOutOfBoundsException, ArithmeticException {\n    int x = numbers[0];\n    int y = numbers[4];\n    int res = x / y;\n\n    if (floatNumber < 0)\n      throw new MyException(\"Number cannot be less than zero\");\n\n    System.out.println(\"end of the function\");\n  }\n\n}\n\nclass MyException extends Exception {\n  public MyException(String message) {\n    super(message);\n  }\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/java/danhingar.java",
    "content": "import java.util.List;\n\npublic class danhingar {\n\n    public static void main(String[] args) {\n        System.out.println(divide(10, 0));\n        List<String> list = List.of(\"A\",\"B\",\"C\");\n        System.out.println(search(list,4));\n\n        try {\n            processParams(List.of(1,4,\"a\"));\n            System.out.println(\"No se ha producido ningún error.\");\n        } catch (IndexOutOfBoundsException e) {\n            System.out.println(\"El número de elementos de la lista debe ser mayor que dos.\");\n        } catch (ArithmeticException e){\n            System.out.println(\"El segundo elemento de la lista no puede ser un cero.\");\n        }catch(StrTypeError e){\n            System.out.println(e);\n        }catch(Exception e){\n            System.out.println(\"Se ha producido un error inesperado: \"+e);\n        }finally{\n            System.out.println(\"El programa finaliza sin detenerse.\");\n        }\n    }\n\n    private static Integer divide(int number1, int number2){\n        try {\n            return number1/number2;\n        } catch (Exception e) {\n            System.out.println(\"No se ha podido realizar la división\");\n            return null;\n        }\n    }\n\n    private static String search(List<String> list,Integer index) {\n        try {\n            return list.get(index);\n        } catch (Exception e) {\n            System.out.println(\"No se ha podido recuperar el elemento del ídice :\"+index);\n            return null;\n        }\n    }\n\n    //EXTRA\n    private static void processParams(List<Object> numbers) throws danhingar.StrTypeError{\n        if(numbers.size()<3){\n            throw new IndexOutOfBoundsException();\n        }else if(numbers.get(1).equals(0)){\n            throw new ArithmeticException();\n        }else if(numbers.get(2).getClass().equals(String.class)){\n            throw new StrTypeError(\"El tercer elemento no puede ser una cadena de texto.\");\n        }\n    }\n\n    private static class StrTypeError extends Exception {\n        \n        public StrTypeError(String message){\n            super(message);\n        }\n        \n    }\n\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/java/davidSorroche.java",
    "content": "public class Excepciones {\n\n\tpublic static void main(String[] args) throws ExcepcionPersonal {\n\n\t\tnew Ejercicio10().manejoExcepciones();\n\t\t\n\t\tSystem.out.println();\n\t\t\n\t\tnew Ejercicio10_DificultadExtra().procesamientoParametros();\n\n\t}\n\n}\n\n/*\n \t* EJERCICIO:\n \t\t* Explora el concepto de manejo de excepciones según tu lenguaje.\n \t\t* Fuerza un error en tu código, captura el error, imprime dicho error\n \t\t* y evita que el programa se detenga de manera inesperada.\n \t\t* Prueba a dividir \"10/0\" o acceder a un índice no existente\n \t\t* de un listado para intentar provocar un error. \n */\n\npublic class Ejercicio10 {\n\t\n\tpublic void manejoExcepciones() {\n\t\t\n\t\ttry {\n\t\t\t\n\t\t\tSystem.out.println(calculoDivision(10, 7));\n\t\t\t\n\t\t\tSystem.out.println(calculoDivision(10, 0));\n\t\t\t\n\t\t} catch (ArithmeticException e) {\n\t\t\t\n\t\t\tSystem.err.println(e.getMessage());\n\t\t\t\n\t\t}\n\t\t\n\t\tSystem.out.println();\n\t\t\n\t\tString[] frase = {\"Haciendo\", \"pruebas\", \"de\", \"manejo\", \"de\", \"excepciones\" };\n\t\t\n\t\ttry {\n\t\t\t\n\t\t\tSystem.out.println(palabraEnArray(frase, frase.length - 1));\n\t\t\t\n\t\t\tSystem.out.println(palabraEnArray(frase, frase.length));\n\t\t\t\n\t\t} catch (ArrayIndexOutOfBoundsException e) {\n\t\t\t\n\t\t\tSystem.err.println(e.getMessage());\n\t\t\t\n\t\t}\n\t\t\n\t\t\n\t} \n\t\n\tprivate double calculoDivision(double numerador, double denominador) {\n\t\t\n\t\tif(denominador == 0) throw new ArithmeticException(\"No está permitida la división entre 0.\");\n\t\t\n\t\treturn numerador / denominador;\n\t\t\n\t}\n\t\n\tprivate String palabraEnArray(String[] frase, int i) {\n\t\t\n\t\tif (i < 0 || i > frase.length - 1) throw new ArrayIndexOutOfBoundsException(\"El índice buscado está fuera de rango del Array.\");\n\t\t\n\t\treturn frase[i];\n\n\t}\n\n}\n\nimport javax.naming.NamingException;\n\n/*\n \t* DIFICULTAD EXTRA (opcional):\n \t\t* Crea una función que sea capaz de procesar parámetros, pero que también\n\t\t* pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n\t\t* corresponderse con un tipo de excepción creada por nosotros de manera\n\t\t* personalizada, y debe ser lanzada de manera manual) en caso de error.\n\t\t\t* - Captura todas las excepciones desde el lugar donde llamas a la función.\n\t\t\t* - Imprime el tipo de error.\n\t\t\t* - Imprime si no se ha producido ningún error.\n\t\t\t* - Imprime que la ejecución ha finalizado. \n */\n\npublic class Ejercicio10_DificultadExtra {\n\t\n\tpublic void procesamientoParametros() {\n\t\t\n\t\tSystem.out.println(imprimirCapturaExcepciones(-5, \"ejercicio10_DificultadExtra\", \"prueba 1\"));\n\t\tSystem.out.println(imprimirCapturaExcepciones(3, \"ejercicio10_Difícil\", \"prueba 2\"));\n\t\tSystem.out.println(imprimirCapturaExcepciones(5, \"ejercicio10_dificultadExtra\", \"\"));\n\t\tSystem.out.println(imprimirCapturaExcepciones(9, \"ejercicio10_dificultadextra\", \"prueba 4\"));\n\t\tSystem.out.println(imprimirCapturaExcepciones(10, \"ejercicio10_dificultadextra\", \"prueba 5\"));\n\t\t\n\t\tSystem.out.println(\"\\nLa ejecución ha finalizado.\");\n\t\t\n\t}\n\t\n\tprivate String imprimirCapturaExcepciones(int i, String nombreClase, String palabra) {\n\t\t\n\t\tString captura;\n\t\t\n\t\ttry {\n\t\t\t\n\t\t\tcaptura =  capturaExcepciones(i, nombreClase, palabra);\n\t\t\t\n\t\t} catch (ArrayIndexOutOfBoundsException | NamingException | ExcepcionPersonal e) {\n\t\t\t\n\t\t\tcaptura = e.getClass().getSimpleName();\n\t\t\t\n\t\t}\n\t\t\n\t\treturn captura;\n\t\t\n\t}\n\t\n\tprivate String capturaExcepciones(int i, String nombreClase, String palabraPersonal) throws NamingException, ExcepcionPersonal {\n\t\t\n\t\tif(i < 0 || i >= 10) throw new ArrayIndexOutOfBoundsException();\n\t\t\n\t\tif(!nombreClase.equalsIgnoreCase(this.getClass().getSimpleName())) throw new NamingException();\n\t\t\n\t\tif(palabraPersonal == null || palabraPersonal.isBlank()) throw new ExcepcionPersonal();\n\t\t\n\t\treturn \"No se ha producido ningún error.\";\n\t\t\n\t}\n\n}\n\npublic class ExcepcionPersonal extends Exception {\n\t\n\tpublic ExcepcionPersonal() {\t\n\t}\n\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/java/eulogioep.java",
    "content": "// Archivo: eulogioep.java\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class eulogioep {\n    public static void main(String[] args) {\n        // Parte 1: Manejo básico de excepciones\n        try {\n            // Intentamos dividir por cero para forzar una excepción\n            int resultado = 10 / 0;\n        } catch (ArithmeticException e) {\n            // Capturamos la excepción y la imprimimos\n            System.out.println(\"Error aritmético: \" + e.getMessage());\n        }\n\n        try {\n            // Intentamos acceder a un índice no existente de una lista\n            List<String> lista = new ArrayList<>();\n            lista.add(\"Elemento\");\n            String elemento = lista.get(5); // Esto lanzará una excepción\n        } catch (IndexOutOfBoundsException e) {\n            // Capturamos la excepción y la imprimimos\n            System.out.println(\"Error de índice: \" + e.getMessage());\n        }\n\n        // Parte 2: Función con múltiples excepciones (DIFICULTAD EXTRA)\n        try {\n            procesarParametro(0); // Probamos con diferentes valores: -1, 0, 5, 15\n            System.out.println(\"No se ha producido ningún error.\");\n        } catch (miExcepcionPersonalizada e) {\n            System.out.println(\"Tipo de error: miExcepcionPersonalizada\");\n            System.out.println(\"Mensaje: \" + e.getMessage());\n        } catch (IllegalArgumentException e) {\n            System.out.println(\"Tipo de error: IllegalArgumentException\");\n            System.out.println(\"Mensaje: \" + e.getMessage());\n        } catch (ArithmeticException e) {\n            System.out.println(\"Tipo de error: ArithmeticException\");\n            System.out.println(\"Mensaje: \" + e.getMessage());\n        } finally {\n            System.out.println(\"La ejecución ha finalizado.\");\n        }\n    }\n\n    // Función que puede lanzar 3 tipos diferentes de excepciones\n    public static void procesarParametro(int parametro) throws miExcepcionPersonalizada {\n        if (parametro < 0) {\n            throw new IllegalArgumentException(\"El parámetro no puede ser negativo\");\n        } else if (parametro == 0) {\n            throw new ArithmeticException(\"No se puede dividir por cero\");\n        } else if (parametro > 10) {\n            throw new miExcepcionPersonalizada(\"El parámetro es demasiado grande\");\n        }\n\n        // Si no hay errores, realizamos alguna operación\n        int resultado = 100 / parametro;\n        System.out.println(\"Resultado: \" + resultado);\n    }\n}\n\n// Definición de nuestra excepción personalizada\nclass miExcepcionPersonalizada extends Exception {\n    public miExcepcionPersonalizada(String mensaje) {\n        super(mensaje);\n    }\n}"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/java/julian98789.java",
    "content": "import java.util.Scanner;\n\nimport javax.swing.undo.CannotRedoException;\n\npublic class reto_10 {\n\n    public static void main(String[] args) {\n        Scanner input = new Scanner(System.in);\n\n        for (int i = 0; i < 1; i++) {\n            try {\n                int div = 10;\n                int divisor = input.nextInt();\n                div /= divisor;\n            } catch (ArithmeticException e) {\n                System.out.println(\"No se puede dividir por 0\");\n            }\n        }\n\n        try {\n            processParams(0, 50);\n        } catch (CustomException e) {\n            System.out.println(\"Error capturado en el método main: \" + e.getMessage());\n        }\n\n        try {\n            processParams(50, -10);\n        } catch (CustomException e) {\n            System.out.println(\"Error capturado en el método main: \" + e.getMessage());\n        }\n\n        try {\n            processParams(60, 50);\n        } catch (CustomException e) {\n            System.out.println(\"Error capturado en el método main: \" + e.getMessage());\n        }\n\n        try {\n            processParams(50, 25);\n        } catch (CustomException e) {\n            System.out.println(\"Error capturado en el método main: \" + e.getMessage());\n        }\n    }\n\n    public static void processParams(int param1, int param2) throws CustomException {\n        try {\n            if (param1 == 0) {\n                throw new IllegalArgumentException(\"El parámetro 'param1' no puede ser 0\");\n            } else if (param2 < 0) {\n                throw new CustomException(\"El parámetro 'param2' no puede ser negativo\");\n            } else if (param1 + param2 > 100) {\n                throw new IllegalStateException(\"La suma de los parámetros no puede ser mayor a 100\");\n            } else {\n                System.out.println(\"Procesamiento de parámetros exitoso\");\n            }\n        } catch (IllegalArgumentException e) {\n            System.out.println(\"Error de tipo IllegalArgumentException: \" + e.getMessage());\n        } catch (CustomException e) {\n            System.out.println(\"Error de tipo CustomException: \" + e.getMessage());\n        } catch (IllegalStateException e) {\n            System.out.println(\"Error de tipo IllegalStateException: \" + e.getMessage());\n        } catch (Exception e) {\n            System.out.println(\"Error inesperado: \" + e.getClass().getName());\n        } finally {\n            System.out.println(\"La ejecución ha finalizado\");\n        }\n    }\n\n    public static class CustomException extends Exception {\n        public CustomException(String message) {\n            super(message);\n        }\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/java/kleyner098.java",
    "content": "import java.util.ArrayList;\nimport java.util.Arrays;\n\npublic class kleyner098 {\n    /*\n     * EJERCICIO:\n     * Explora el concepto de manejo de excepciones según tu lenguaje.\n     * Fuerza un error en tu código, captura el error, imprime dicho error\n     * y evita que el programa se detenga de manera inesperada.\n     * Prueba a dividir \"10/0\" o acceder a un índice no existente\n     * de un listado para intentar provocar un error.\n     */\n\n    public static void main(String[] args) {\n\n        try {\n            int num1 = 10;\n            int num2 = 0;\n            int num3 = num1 / num2;\n            System.out.println(num3);\n        } catch (ArithmeticException e) {\n            System.out.println(\"Error, division entre 0\");\n        }\n\n        try {\n\n            // Mi calculadora solo puede hacer restas si  el primer número es mayor al segundo\n\n            int resultado = calculadora(10, 0, \"+\");\n            // int resultado = calculadora(0, 1, \"-\");      // Excepción IllegalArgumentException\n            // int resultado = calculadora(10, 0, \"/\");     // Excepción ArithmeticException\n            // int resultado = calculadora(10, 0, \"+a\");    // Excepción personalizada MyException\n            System.out.println(\"Operación realizada. El resultado es \" + resultado );\n        } catch (Exception e) {\n            System.out.println(e.getMessage());\n        } finally {\n            System.out.println(\"Ejecución del programa finalizado\");\n        }\n\n    }\n\n    /*\n     * DIFICULTAD EXTRA (opcional):\n     * Crea una función que sea capaz de procesar parámetros, pero que también\n     * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n     * corresponderse con un tipo de excepción creada por nosotros de manera\n     * personalizada, y debe ser lanzada de manera manual) en caso de error.\n     * - Captura todas las excepciones desde el lugar donde llamas a la función.\n     * - Imprime el tipo de error.\n     * - Imprime si no se ha producido ningún error.\n     * - Imprime que la ejecución ha finalizado.\n     */\n\n    static class MyException extends Exception {\n        MyException(String mensaje) {\n            super(mensaje);\n        }\n\n    }\n\n    public static int calculadora(int a, int b, String operacion) throws MyException {\n\n        final String[] operaciones = { \"+\", \"-\", \"*\", \"/\" };\n        int resultado = 0;\n\n        if (!(Arrays.asList(operaciones).contains(operacion))) {\n            throw new MyException(\"Error: Operación incorrecta. Se introdujo \" + operacion);\n        }\n        if (b == 0 && operacion == \"/\") {\n            throw new ArithmeticException(\"Error: División entre 0\");\n        }\n\n        if (a < b  && operacion == \"-\") {\n            throw new IllegalArgumentException(\"Error: \" + a + \" es menor \" + b);\n        }\n\n        switch (operacion) {\n            case \"+\":\n                resultado = a + b;\n                break;\n            case \"-\":\n                resultado = a - b;\n                break;\n            case \"*\":\n                resultado = a * b;\n                break;\n            case \"/\":\n                resultado = a / b;\n                break;\n\n        }\n        return resultado;\n    }\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/java/martinbohorquez.java",
    "content": "import java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\n\npublic class martinbohorquez {\n    public static void main(String[] args) {\n        try {\n//            int num = 10 / 0;\n            List<Integer> lista = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));\n            System.out.println(lista.get(6));\n        } catch (ArithmeticException e) {\n//            e.printStackTrace();\n            System.out.printf(\"No puede dividirse por cero: %s%n\", e.getMessage());\n        } catch (IndexOutOfBoundsException e) {\n            System.out.printf(\"Indice fuera de límites: %s%n\", e.getMessage());\n        }\n        System.out.println(\"Continuando con el programa...!\");\n\n        /*\n         * DIFICULTAD EXTRA\n         */\n        processParams(Arrays.asList(10, 0, 30));\n    }\n\n    private static void processParams(List<Integer> lista) {\n        List<Integer> list = new ArrayList<>(lista);\n        try {\n            System.out.printf(\"La división es: %d%n\", (list.get(2) / list.get(0)));\n            System.out.println(list.get(2));\n            if (list.get(1) == 0) throw new MartinException(\"elemento con valor zero!\");\n        } catch (ArithmeticException e) {\n            System.out.printf(\"No puede dividirse por cero: %s%n\", e.getMessage());\n        } catch (IndexOutOfBoundsException e) {\n            System.out.printf(\"Indice fuera de límites: %s%n\", e.getMessage());\n        } catch (MartinException e) {\n            System.out.printf(\"Se ha producido un error personalizado: %s%n\", e.getMessage());\n        } catch (Exception e) {\n            System.out.printf(\"Se ha producido un error inesperado: %s%n\", e.getMessage());\n        } finally {\n            System.out.println(\"Programa finalizado!\");\n        }\n    }\n\n    private static class MartinException extends Exception {\n        public MartinException(String message) {\n            super(message);\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/java/miguelex.java",
    "content": "public class miguelex {\n    public static void main(String[] args) {\n        try {\n            int a = 5;\n            int b = 0;\n            int c = a / b;\n            System.out.println(c);\n        } catch (ArithmeticException e) {\n            System.out.println(\"No se puede dividir por cero\");\n        }\n\n        // excepcion por indice fuera de rango\n\n        try {\n            int[] array = new int[5];\n            array[10] = 10;\n        } catch (ArrayIndexOutOfBoundsException e) {\n            System.out.println(\"Indice fuera de rango\");\n        }\n\n        try {\n            //System.out.println(extra(\"Java\", 10, \"Miguel\"));\n            // System.out.println(extra(\"Java\", 10));\n            // System.out.println(extra(\"\", 10, \"Miguel\"));\n            // System.out.println(extra(\"Java\", -10, \"Miguel\"));\n            System.out.println(extra(\"Java\", 10, \"Mouredev\"));\n        } catch (IllegalArgumentException e) {\n            System.out.println(\"Error: \" + e.getMessage());\n        }\n    }\n\n    public static String extra(String lenguaje, int reto, String usuario) {\n        // Comprobación de cantidad de parámetros\n        if (lenguaje == null || reto < 0 || usuario == null) {\n            throw new IllegalArgumentException(\"Se deben proporcionar 3 parámetros\");\n        }\n        // Comprobación de primer parámetro\n        if (lenguaje.isEmpty()) {\n            throw new IllegalArgumentException(\"El primer parámetro no puede estar vacío\");\n        }\n        // Comprobación de segundo parámetro\n        if (reto < 0) {\n            throw new IllegalArgumentException(\"El segundo parámetro debe ser un entero no negativo\");\n        }\n        // Comprobación de tercer parámetro\n        if (usuario.equals(\"Mouredev\")) {\n            throw new IllegalArgumentException(\"El tercer parámetro no puede ser 'Mouredev'\");\n        }\n        // Concatenación con formato\n        return \"Reto #\" + reto + \" - \" + lenguaje + \" enviado por \" + usuario;\n    }\n}"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/java/simonguzman.java",
    "content": "import java.util.ArrayList;\nimport java.util.List;\n\npublic class simonguzman{\n    public static void main(String[] args) {\n\n        //Manejo de excepciones basicas\n        try {\n            //Excepcion forzada: Division por cero\n            int result = 10 / 0;\n        } catch (ArithmeticException e) {\n            System.out.println(\"ERROR: Division por cero...\"+e.getMessage());\n        }\n\n        try {\n            //Indice fuera de los limites\n            List<String> list = new ArrayList<>();\n            list.add(\"Simon\");\n            String item = list.get(1);\n        } catch (IndexOutOfBoundsException e) {\n            System.out.println(\"ERROR: Indice fuera de los limites...\"+e.getMessage());\n        }\n\n        //Manejo de excepciones personalizadas\n        try {\n            throw new customException(\"Mensaje personalizado para una excepcion personalizada\");\n        } catch (customException e) {\n            System.out.println(\"Se ha producido una excepcion personalizada...\"+e.getMessage());\n        }\n\n        executeProcessParameters();\n    }\n\n    static void executeProcessParameters(){\n        try {\n            processParameters(10, 2, \"test\");\n        } catch (ArithmeticException e){\n            System.out.println(\"ERROR: Excepcion aritmetica...\"+e.getMessage());\n        } catch(ArrayIndexOutOfBoundsException e){\n            System.out.println(\"ERROR: Indice fuera de los limites...\"+e.getMessage());\n        } catch(customException e){\n            System.out.println(\"ERROR: Excepcion general...\"+e.getMessage());\n        }finally{\n            System.out.println(\"La ejecucion a finalizado.\");\n        }\n    }\n\n    static void processParameters(int num1, int num2, String str) throws ArithmeticException, ArrayIndexOutOfBoundsException, customException{\n        if (num2 == 0){\n            throw new ArithmeticException(\"ERROR: Division por cero\");\n        }\n        int result = num1/num2;\n        System.out.println(\"Resultado: \"+result);\n\n        if(str.length() < 3){\n            throw new ArrayIndexOutOfBoundsException(\"Cadena de texto muy corta\");\n        }\n\n        if(str.equals(\"test\")){\n            throw new customException(\"Cadena no permitida\");\n        }\n\n        System.out.println(\"Parametros procesados correctamente\");\n    }\n\n    static class customException extends Exception {\n        public customException(){\n\n        }\n\n        public customException(String message){\n            super(message);\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/javascript/7R0N1X.js",
    "content": "let array = [1, 2, 3, 4, 5]\n\ntry {\n  console.log(array[6].toString())\n} catch (error) {\n  console.error(`Error: ${error}`)\n} finally {\n  console.log('Fin de ejecución')\n}\n\nconsole.log('El flujo del programa continua')"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/javascript/AChapeton.js",
    "content": "let myArray = ['a', 'b', 'c', 'd']\n\n//TRY - Bloque del codigo que se va a evaluar\n//CATCH - Bloque del codigo que se ejecuta si se encuentra un error en el bloque TRY\n//FINALLY - Bloque de codigo (opcional) que se va a ejecutar una vez haya terminado el bloque TRY, independientemente de su resultado\n\ntry{\n    myArray[8].length\n}catch(error){\n  throw 'No se puede acceder a una posicion que no existe en el array.' + error\n}finally{\n  console.log(myArray.length)\n}\n\n\n\n// DIFICULTAD EXTRA\n\nclass customException extends Error{\n  constructor(message){\n    super(message)\n    this.name = 'Custom Exception'\n  }\n}\n\nconst myFunction = (num1, num2) => {\n  try{\n    if(num1 < 0){\n      throw new Error('El primer valor no puede ser menor a cero.')\n    }\n\n    if((num2 % 2) !== 0){\n      throw new Error('El segundo valor debe ser un numero par.')\n    }\n\n    if((num1 + num2) > 99){\n      throw new customException('La suma de los valores no puede sobrepasar de 100.')\n    }\n  }catch(error){\n    console.log('Tipo de error: ', error instanceof customException ? 'Custom error' : 'Normal error')\n    console.log('Mensaje de error: ', error.message)\n  }finally{\n    console.log('Fin del ejercicio')\n  }\n}\n\nmyFunction(444, 50)"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/javascript/ArticKun.js",
    "content": "\n\n// ⚡ EXCEPCIONES =====================\n\n/*\n\nEn JavaScript, puedes manejar errores o excepciones \nutilizando bloques try, catch, y finally.\nEl Throw permite personalizar un error \nsi se lanza como un tipo error se usa:  throw new Error(')\n\n*/\n\ntry {\n  // Intenta ejecutar el código que podría lanzar un error\n    let resultado = 10 / 0; // Intenta dividir por cero\n    console.log(resultado); // Esto no se ejecutará si se lanza un error\n  } catch (error) {\n  // Captura cualquier error que ocurra en el bloque try\n    console.error('Se ha producido un error:', error);\n  } finally {\n  // Este bloque se ejecutará siempre, ya sea que haya ocurrido un error o no\n    console.log('El bloque try-catch ha terminado de ejecutarse.');\n  }\n  \n//Salida : infinity \n//El bloque try-catch ha terminado de ejecutarse.\n\n/*\n  \n  ⚡ En este ejemplo, si intentas dividir 10 por 0, se lanzará un \n  error de división por cero. Este error será capturado por el bloque \n  catch, donde puedes manejarlo adecuadamente. Además, el bloque finally \n  se ejecutará independientemente de si se produce un error o no, lo que \n  te permite realizar tareas de limpieza o finalización de manera consistente.\n\n*/\n\n/*\n⚡ Si ves \"Infinity\" en la consola cuando divides 10 por 0 en JavaScript, \neso significa que el resultado de la operación es infinito. En JavaScript, \ndividir un número finito por cero resulta en un valor especial llamado \n\"Infinity\". No se produce un error en este caso, sino que JavaScript maneja \nla situación devolviendo este valor especial.\n\nPor lo tanto, si estás intentando capturar un error cuando divides por cero,\ndebes tener en cuenta que JavaScript no lanzará una excepción en este caso. \nSi deseas manejar explícitamente la división por cero como un error, puedes \nhacerlo mediante una condición antes de realizar la operación de división\n\n */\n\ntry {\n    let divisor = 0;\n    if (divisor === 0) {\n      throw new Error('División por cero no permitida');\n    }\n    let resultado = 10 / divisor;\n    console.log(resultado);\n  } catch (error) {\n    console.error('Se ha producido un error:', error);\n  } finally {\n    console.log('El bloque try-catch ha terminado de ejecutarse.');\n  }\n\n  //Con esta modificación, si el divisor es 0, se lanzará una excepción \n  //que puede ser capturada por el bloque catch.\n\n\n  /*\n\n  ⚡ DIFICULTAD EXTRA (opcional) =========================================\n\n     Crea una función que sea capaz de procesar parámetros, pero que también\n     pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n     corresponderse con un tipo de excepción creada por nosotros de manera\n     personalizada, y debe ser lanzada de manera manual) en caso de error.\n     - Captura todas las excepciones desde el lugar donde llamas a la función.\n     - Imprime el tipo de error.\n     - Imprime si no se ha producido ningún error.\n     - Imprime que la ejecución ha finalizado.\n\n  */\n\n\n     function procesarParametros(param1, param2) {\n        try {\n          // Verificamos que se pasen al menos dos parámetros\n          if (arguments.length < 2) {\n            throw 'Error: Se requieren al menos dos parámetros';\n          }\n      \n          // Procesamos los parámetros\n          if (typeof param1 !== 'number' || typeof param2 !== 'number') {\n            throw 'TypeError: Ambos parámetros deben ser números';\n          }\n      \n          if (param1 < 0 || param2 < 0) {\n            throw 'RangeError: Los parámetros no pueden ser números negativos';\n          }\n      \n          // Si no se ha producido ningún error\n          console.log('Los parámetros se han procesado correctamente.');\n        } catch (error) {\n          // Capturamos y manejamos las excepciones\n          console.error('Se ha producido un error:', error);\n        } finally {\n          // Indicamos que la ejecución ha finalizado\n          console.log('La ejecución ha finalizado.');\n        }\n      }\n      \n      // Llamada a la funcion\n      console.log('Intento 1:');\n      procesarParametros(10, 5);\n      \n      console.log('\\nIntento 2:');\n      procesarParametros(-5, 10);\n      \n      console.log('\\nIntento 3:');\n      procesarParametros('Hola', 10);\n      \n      console.log('\\nIntento 4:');\n      procesarParametros(42, 10);\n      \n      console.log('\\nIntento 5:');\n      procesarParametros(2);\n      "
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/javascript/DAVstudy.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado. \n */\n\n// Try - Catch - Finally - Throw\n\ntry {\n    // El bloque try intentara ejecutar al logica\n    // En este caso llamo a una funcion que no existe,\n    callFunction()\n} catch (error) {\n    // el bloque Catcht captura el error para que el codigo pueda seguir ejecutandose fuera de este bloque\n    console.log(error.message);\n    \n} finally {\n    console.log(\"Codigo que se ejecuta siempre\");\n    \n}\n\n// Con Throw podemos generar los tipos de error como tambien alguno de tipo personalizado\n\ntry {\n    throw new Error(\"Error del tipo 'Error'\")\n} catch (error) {\n    console.log(error.message);\n}\n\n// Crear un error personalizado\nconst gifts = {\n    toys: [\"playstation 5\", \"pelota\", \"mochila\"],\n    //books : [\"Harry potter\", \"Percy Jackson\", \"Codigo Limpio\"],\n    sport: [\"shorts\", \"pesas\", \"cuerda de saltar\"],\n  };\n  \n  class CategoryNotFound extends Error {\n    constructor(message) {\n      super(message);\n    }\n  }\n  \n  // 5. Lanza una excepción personalizada.\n  if (!(\"books\" in gifts)) {\n    try {\n      throw new CategoryNotFound(\n        \"Error: No existe la categoria libros en los regalos\"\n      );\n    } catch (error) {\n      console.log(error.message); \n    }\n  }\n\n/*\n  * Crea una función que sea capaz de procesar parámetros, pero que también\n  * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n  * corresponderse con un tipo de excepción creada por nosotros de manera\n  * personalizada, y debe ser lanzada de manera manual) en caso de error.\n  * - Captura todas las excepciones desde el lugar donde llamas a la función.\n  * - Imprime el tipo de error.\n  * - Imprime si no se ha producido ningún error.\n  * - Imprime que la ejecución ha finalizado. \n*/\n\n// Excepción personalizada\nclass CustomError extends Error {\n  constructor(message) {\n    super(message);\n    this.name = \"CustomError\";\n  }\n}\n\n// Función que procesa parámetros y lanza excepciones\nfunction paramProcess(param) {\n  if (param === null || param === undefined) {\n    throw new TypeError(\"El parámetro no puede ser null o undefined\");\n  }\n\n  if (typeof param !== \"number\") {\n    throw new CustomError(\"El parámetro debe ser un número\");\n  }\n\n  if (param < 0) {\n    throw new RangeError(\"El parámetro no puede ser negativo\");\n  }\n\n  // Proceso normal si no hay errores\n  return `El parámetro procesado es: ${param}`;\n}\n\n// Llamada a la función y manejo de excepciones\ntry {\n  console.log(paramProcess(-1)); // Cambia este valor para probar diferentes casos\n  console.log(\"No se ha producido ningún error.\");\n} catch (error) {\n  if (error instanceof CustomError) {\n    console.error(`Error personalizado: ${error.message}`);\n  } else if (error instanceof TypeError) {\n    console.error(`Error de tipo: ${error.message}`);\n  } else if (error instanceof RangeError) {\n    console.error(`Error de rango: ${error.message}`);\n  } else {\n    console.error(`Error desconocido: ${error.message}`);\n  }\n} finally {\n  console.log(\"La ejecución ha finalizado.\");\n}"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/javascript/Dan-Corbo.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado. \n */\n\n\n/* Soluciones */\n\n\nfunction dividir(numero1, numero2) {\n  // Valida los tipos de datos\n  if (typeof numero1 !== \"number\" || typeof numero2 !== \"number\") {\n    throw new TypeError(\"Los números deben ser enteros.\");\n  }\n\n  // Valida la división por cero\n  if (numero2 === 0) {\n    throw new Error(\"No se puede dividir por cero.\");\n  }\n\n  // Valida si el divisor es NaN\n  if (isNaN(numero2)) {\n    throw new Error(\"El divisor no puede ser NaN.\");\n  }\n\n  return numero1 / numero2;\n}\n\n\ntry {\n  // const resultado = dividir(10, \"0\"); // \"Error de tipo de dato: Los números deben ser enteros.\"\n  // const resultado = dividir(10, NaN); // \"Error: El divisor no puede ser NaN.\"\n  const resultado = dividir(10, 0); // \"Error: No se puede dividir por cero.\"\n  console.log(\"El resultado de la división es:\", resultado);\n} catch (error) {\n  if (error instanceof TypeError) {\n    console.error(\"Error de tipo de dato:\", error.message);\n  } else if (error instanceof Error) { // Captura un error genérico\n    console.error(\"Error:\", error.message);\n  } else {\n    console.error(\"Error inesperado:\", error);\n  }\n} finally {\n  console.log(\"Fin del programa.\\n\"); // \"Fin del programa.\"\n}\n\n\n/* Extra - Opcional */\n\n\nfunction discoteca(nombre, edad) {\n  // Valida los tipos de datos\n  if (typeof nombre !== \"string\" && typeof edad !== \"number\" || isNaN(edad)) {\n    throw new Error(\"El nombre debe ser un string y la edad un número.\");\n  }\n  if (typeof nombre !== \"string\") {\n    throw new Error(\"El nombre debe ser un string.\");\n  }\n  if (typeof edad !== \"number\" || isNaN(edad)) {\n    throw new Error(\"La edad debe ser un número.\");\n  }\n\n  // Valida los campos vacíos\n  if (!nombre || !edad) {\n    throw new Error(\"Debes completar ambos campos.\");\n  }\n\n  // Valida la edad del usuario\n  if (edad >= 18) {\n    console.log(`${nombre} puedes ingresar. ¡Bienvenida/o!`); // \"Ana puedes ingresar. ¡Bienvenida/o!\"\n  } else {\n    throw new Error(\"No puedes ingresar por ser menor de edad.\");\n  }\n}\n\nconst nombres = [23, \"Ana\", \"Pedro\", \"\", 0];\nconst edades = [15, 20, 17, 25, \"\"];\n\nfor (let i = 0; i < nombres.length; i++) {\n  try {\n    discoteca(nombres[i], edades[i]);\n  } catch (error) {\n    switch (error.message) {\n      case \"El nombre debe ser un string y la edad un número.\":\n        console.log(\"El nombre y la edad no son válidos.\"); // \"El nombre y la edad no son válidos.\"\n        break;\n      case \"El nombre debe ser un string.\":\n        console.log(\"El nombre no es válido.\"); // \"El nombre no es válido.\"\n        break;\n      case \"La edad debe ser un número.\":\n        console.log(\"La edad no es válida.\");\n        break;\n      case \"Debes completar ambos campos.\":\n        console.log(\"Debes completar los dos campos.\"); // \"Debes completar los dos campos.\"\n        break;\n      case \"No puedes ingresar por ser menor de edad.\":\n        console.log(nombres[i],\"lo siento, no puedes ingresar por ser menor de edad.\"); // \"Pedro lo siento, no puedes ingresar por ser menor de edad.\"\n        break;\n    }\n  } finally {\n    console.log(\"Sigan pasando por favor, las mujeres entran gratis!!!\\n\");\n  }\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/javascript/DavidMoralesDeveloper.js",
    "content": "//TryChach\n\ntry {\n    noexitefuncion()\n} catch (error) {\n    console.log(`${error} estamos en chatch`)\n}finally{\n    console.log('Declare primero la funcion')\n  }\n\n//   console.log('ola k ace , si me ejecuto despues de el error')\n\n//   extra \n// creando error\nclass customError extends Error {\nconstructor(message){\n    super(message)\n    this.name = 'Custom Exception'\n}\n}\n\nfunction funcionCreada (parametro1){\n\ntry {\n\n    if (parametro1.length < 3){\n        throw new Error('El primer valor no puede ser menor a 3.')\n    }else if (parametro1[1] === 0) {\n        console.log('el parametro 1 no puede ser 0')\n    }else if (typeof parametro1 === 'string') {\n       throw new customError('el parametro debe ser un Array')\n    }\n    \n} catch (error) {\n    console.log('Tipo de error: ', error instanceof customError ? 'Custom error' : 'Normal error')\n    console.log('Mensaje de error: ', error.message)\n    \n} finally{\n    console.log('Fin del ejercicio')\n}\n\n}\nfuncionCreada([0, 1])\n// funcionCreada([0, 0, 1, 2, 3])\n// funcionCreada('HOLA')\n\n\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/javascript/Deyvid-10.js",
    "content": "// Excepciones\n\ntry\n{\n    f()\n}\ncatch(err)\n{\n    console.error(err.name, \":\", err.message);\n}\nfinally\n{\n    console.log(\"Se manejo correctamente\");\n}\n\nconsole.log(\"El programa no se detuvo\");"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/javascript/FabianRpv.js",
    "content": "// Excepciones \n\n\nfunction division(num, den){\n\n    let result = num / den\n\n    if (typeof num != 'number' || typeof den != 'number'){\n        throw new Error(\"Las variables deben ser de tipo numerico\");\n    }\n\n    else if(!(isFinite(result))){\n        throw new Error(\"Error al dividir\");\n    }\n\n    else {\n        console.log(result)\n    }\n\n}\n\ntry {\n    division(10, 5)\n} catch (error) {\n    console.log(error.message)\n}\n\n/*\n* DIFICULTAD EXTRA (opcional):\n* Crea una función que sea capaz de procesar parámetros, pero que también\n* pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n* corresponderse con un tipo de excepción creada por nosotros de manera\n* personalizada, y debe ser lanzada de manera manual) en caso de error.\n* - Captura todas las excepciones desde el lugar donde llamas a la función.\n* - Imprime el tipo de error.\n* - Imprime si no se ha producido ningún error.\n* - Imprime que la ejecución ha finalizado.\n*/\n\n// Excepción personalizada\nclass MiExcepcionPersonalizada extends Error {\n    constructor(mensaje) {\n        super(mensaje);\n        this.name = \"MiExcepcionPersonalizada\";\n    }\n}\n\n// Función que procesa parámetros y puede lanzar excepciones\nfunction procesarParametros(parametro) {\n    if (typeof parametro !== \"number\") {\n        throw new TypeError(\"El parámetro debe ser un número\");\n    }\n\n    if (parametro < 0) {\n        throw new RangeError(\"El parámetro no puede ser negativo\");\n    }\n\n    if (parametro === 42) {\n        throw new MiExcepcionPersonalizada(\"El parámetro no puede ser 42\");\n    }\n\n    // Si no hay errores, procesar el parámetro\n    console.log(`Parámetro procesado correctamente: ${parametro}`);\n}\n\n// Captura de excepciones\ntry {\n    procesarParametros(42); // Cambia este valor para probar diferentes casos\n} catch (error) {\n    console.log(`Se ha producido un error: ${error.name}`);\n    console.log(`Mensaje de error: ${error.message}`);\n} finally {\n    console.log(\"La ejecución ha finalizado.\");\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/javascript/Glitzypanic.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado.\n */\n\n// Función para dividir dos números\nfunction dividir() {\n  try {\n    let divisor = 0;\n    if (divisor === 0) {\n      throw new Error(\"No se puede dividir por cero\");\n    }\n    let resultado = 10 / divisor;\n    console.log(`El resultado es: ${resultado}`);\n  } catch (Error) {\n    console.log(\"Se produjo un error:\", Error.message);\n  }\n}\n\nclass ExcepcionPersonalizada extends Error {\n  constructor(message) {\n    super(message);\n    this.name = \"Custom Error: \";\n  }\n}\n\n// Función para registrar un usuario con excepciones\nfunction user(name, age) {\n  if (name === \"\") {\n    throw new Error(\"El nombre no puede estar vacío\");\n  } else if (age < 18) {\n    throw new TypeError(\"Debe ser mayor de edad\");\n  } else if (age > 100) {\n    throw new ExcepcionPersonalizada(\"Debe ser menor de 100\");\n  } else {\n    console.log(\"Usuario registrado correctamente\");\n  }\n}\n\ntry {\n  user(\"Jose\", 25);\n} catch (e) {\n  console.log(`${e.name} ${e.message}`);\n} finally {\n  console.log(\"La ejecucion ha finalizado.\");\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #10 - JavaScript ->Jesus Antonio Escamilla */\n/**\n * Las excepciones son eventos inusuales o errores que pueden ocurrir\n * durante la ejecución de un programa.\n * Cuando se produce una excepción, cuando algo ocurre con la ejecución normal\n * del programa se interrumpe y se busca un bloque de código llamado\n * \"manejado de excepciones\" para manejar la situación.\n */\n\n//-----SINTAXIS-----\n//Se empieza con TRY donde se ejecuta cuando todo sale bien\ntry {\n    //El THROW permite personalizar un error\n    throw new Error(\"Este es un ejemplo de excepción\"); // Lanzar un error de Tipo Error\n    throw expression; // Expresión es el valor personalizado que sera Lanzando\n    throw 17; // Lanzar un error de tipo número\n    throw true; // Lanzar un error de tipo boolean\n    throw {toString:function(){ return \"Error personalizado\";   }   } // Lanzar un error de un tipo Objeto\n\n} catch (error) {   //Se usa CATCH para macar un error si el código no funciona\n    //Aquí se pone el error en mensaje ya sea en consola o a la vista del usuario\n    console.error(\"Se produjo un error:\", error.message);\n}finally{   //Esta excepción es opcional y es FINALLY siempre se ejecuta, ocurra o no el programa\n    //Manda mensaje siempre, ejecutado o no ejecutado el programa\n    console.log(\"Este bloque se ejecuta siempre\");\n}\n\n\n//---EJEMPLOS---\n//  Hacemos un ejemplo de 10/0 para demostrar el try-catch\ntry {\n    //  Vemos la operación ejecución\n    let resultado = 10 / 0;\n    //  Aquí validamos que no se 0\n    if (resultado == 0) {\n        //  Este es un error personalizado\n        throw Error(\"No se puede dividir por 0\");\n    } else {\n        //  Si no es 0 entonces que lo imprima\n        console.log(\"El resultado de la division es:\", resultado);\n    }\n} catch (error) {\n    //Error si algo sale mal en el TRY\n    console.error(\"Ha ocurrido un error:\", error.message);\n}\n\n//  Hacemos con una lista\ntry {\n    // Código que puede generar un error\n    let array = [1, 2, 3];\n    let elemento = array[10];  // Intenta acceder a un índice que está fuera del rango del array\n    if (elemento == undefined) {\n        throw Error(`La lista es de ${array.length}.`)\n    } else {\n        console.log(elemento);\n    }\n} catch (error) {\n    // Captura el error y realiza acciones necesarias\n    console.error(\"Se ha producido un error al acceder al índice:\", error.message);\n} \n\n/**-----DIFICULTAD EXTRA-----*/\n\n// Mi excepción Personalizados\nclass excepciónPersonalizado extends Error{\n    constructor(message){\n        super(message);\n        this.name = 'Mi_Excepción_Personalizada';\n    }\n}\n\n// La función del programa (Utilize una lista)\nfunction procesarParámetros(lista) {\n    if (lista.length < 3) {\n        throw new TypeError(\"Tiene que ser mas de 3 elementos\");\n    }\n    if(typeof lista[2] !== 'number'){\n        throw new Error(\"Los parámetros tiene que ser el mismo tipo\");\n    }\n    if (lista === 'vació') {\n        throw new excepciónPersonalizado(\"La lista no valida\");\n    }\n    console.log('La ejecución ha finalizado sin errores');\n}\n\n// El TRY-CATCH-FINALLY para la ejecución\ntry {\n    procesarParámetros([1, 2, 3, 4]);\n} catch (error) {\n    console.error(\"Ocurrió un error:\", error.message);\n} finally{\n    console.log('Programa Finalizado')\n}\n\n/**-----DIFICULTAD EXTRA-----*/"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/javascript/Pancratzia.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado. \n */\n\n/******************* PARTE 1 *******************/\nconst a = 10;\n\ntry{\n    console.log(a/b);\n} catch(error){\n    console.log(error); //Se mostrará el error, debido a que la variable \"b\" no ha sido declarada\n} finally{\n    console.log(\"La ejecución ha finalizado\");\n}\n\nconsole.log(\"El programa sigue con normalidad\");\n\n/******************* EXTRA *******************/\n\nfunction processParams(param1, param2) {\n    try {\n        if (typeof param1 !== 'number' || typeof param2 !== 'number') {\n            throw new TypeError('Los parámetros deben ser números');\n        }\n\n        if (param1 === 0 || param2 === 0) {\n            throw new Error('Los parámetros no pueden ser cero');\n        }\n\n        if (param1 < 0 || param2 < 0) {\n            throw new Error('Valores negativos no permitidos');\n        }\n\n        console.log('No se ha producido ningún error');\n    } catch (error) {\n        console.error('Tipo de error:', error instanceof Error ? error.name : 'Error personalizado');\n        console.error('Mensaje de error:', error.message || error);\n    }\n}\n\nprocessParams(10, 20); // No se produce ningún error\nprocessParams(0, 30); // Lanza una excepción por división por cero\nprocessParams(-5, 10); // Lanza una excepción personalizada por valores negativos\nprocessParams('abc', 10); // Lanza una excepción por tipo de parámetro incorrecto\n\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/javascript/RaulDoezon.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado. \n*/\n\nconsole.log(\"+++++++++ EJERCICIO +++++++++\");\n\ntry {\n  const arreglo = [1, 2, 3];\n  const division = 10 / 0;\n  variable;\n\n  console.log(\"En JavaScript, al acceder a un índice inexistente no se le considera como un error:\");\n  console.log(arreglo[3]);\n  console.log(\"Tampoco al realizar la división de un número entre cero:\");\n  console.log(division);\n  console.log(variable);\n} catch (error) {\n  console.log(`Se presentó el error: ${error}`);\n}\n\nconsole.log(\"+++++++++ DIFICULTAD EXTRA +++++++++\");\n\nfunction personalInformation(name, age) {\n  try {\n    if (isNaN(name)) {\n      console.log(`Mi nombre es ${name}.`);\n    } else {\n      nameMessage;\n    }\n\n    if (isNaN(age)) {\n      throw new Error(\"El valor ingresado para la edad no es un número.\");\n    } else {\n      if (age > 17) {\n        console.log(`Tengo ${age} años y soy mayor de edad`);\n      } else {\n        age.toUppercase();\n      }\n    }\n\n    console.log(`¡No se produjo ningún error durante la ejecución!`);\n  } catch (error) {\n    console.log(`Se presentó el siguiente problema: ${error}`);\n  } finally {\n    console.log(\"--------- La ejecución ha finalizado ---------\");\n  }\n}\n\npersonalInformation();\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/javascript/RicJDev.js",
    "content": "console.log('\\n---CONTROL DE EXCEPCIONES---');\n\ntry {\n\tconsole.log('\\nIniciando comprobación de errores...');\n\tconsole.log(variableInexistente);\n} catch (error) {\n\t// console.log(`\\nSe ha producido un error:\\n${error.name}`); ---> Nombre del error\n\t// console.log(`\\nSe ha producido un error:\\n${error.message}`); ---> Mensaje con detalles del error\n\t// console.log(`\\nSe ha producido un error:\\n${error.stack}`); ---> Pila de llamadas actual. Utilizado para fines de depuración.\n\tconsole.log(`\\nSe ha producido un error:\\n${error}`);\n} finally {\n\tconsole.log('\\nComprobación de errores terminada :D');\n}\n\nconsole.log('\\nEsta string se muestra porque no se ha detenido el programa');\n\nconsole.log('\\n---PROCESANDO PARÁMETROS---');\n\nclass CustomError extends Error {\n\tconstructor(message) {\n\t\tsuper(message);\n\t\tthis.name = 'Usuario baneado';\n\t}\n}\n\nconst bannedUser = ['Peg Lewack', 'Abby Constantine', 'Richie Trelawney'];\n\nfunction comprueba(user, password) {\n\tconsole.log('\\n* Iniciando comprobación de usuario...');\n\ttry {\n\t\tif (arguments.length < 2) {\n\t\t\tthrow new Error('Debe ingresar un usuario y una contraseña numérica');\n\t\t}\n\t\tif (typeof user !== 'string' || typeof password !== 'number') {\n\t\t\tthrow new Error(\n\t\t\t\t'El primer argumento debe ser una cadena de texto y el segundo debe ser un número'\n\t\t\t);\n\t\t}\n\t\tif (bannedUser.includes(user)) {\n\t\t\tthrow new CustomError(\n\t\t\t\t`${user} ha sido baneado por no cumplir las normas comunitarias`\n\t\t\t);\n\t\t}\n\t\tconsole.log('\\nNo se detectaron errores.');\n\t\tconsole.log(`\\nBienvenido, ${user}!`);\n\t} catch (error) {\n\t\tconsole.log(\n\t\t\t`\\nTipo de error:\\n${\n\t\t\t\terror instanceof CustomError ? 'Custom error' : 'Normal error'\n\t\t\t}`\n\t\t);\n\t\tconsole.log(`\\nSe produjo un error:\\n${error}`);\n\t} finally {\n\t\tconsole.log('\\n* Ha concluido la comprobación :D\\n');\n\t}\n}\nconsole.log('\\nPrueba 1:');\ncomprueba('Peg Lewack', 92344);\n\nconsole.log('\\nPrueba 2:');\ncomprueba(123, 345);\n\nconsole.log('\\nPrueba 3:');\ncomprueba('Damiano', '1234');\n\nconsole.log('\\nPrueba 4:');\ncomprueba('Fred');\n\nconsole.log('\\nPrueba 5:');\ncomprueba('Ric', 2356);\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/javascript/Sac-Corts.js",
    "content": "// Exercise // \nfunction divide(a, b) { \n    try {\n        if (b === 0) {\n            throw new Error(\"Cannot divide by 0.\");\n        } \n        return a / b;\n    } catch (error) {\n        console.error('Error:', error.message);\n    } finally {\n        console.log(\"Division operation completed.\");\n    }\n}\n\ndivide(10, 0);\n\n// Extra Exercise // \nclass CustomError extends Error {\n    constructor(message) {\n        super(message);\n        this.name = \"CustomError\";\n    }\n}\n\nfunction processParameters(param) {\n    try {\n        if (param < 0) {\n            throw new RangeError(\"The parameter must not be negative.\");\n        } \n        if (typeof param !== 'number') {\n            throw new TypeError(\"The parameter must be a number\");\n        } \n        if (param === 0) {\n            throw new CustomError(\"The parameter must no be zero\");\n        }\n        return `The parameter ${param} was processed correctly.`\n    } catch (error) {\n        console.error(`Caught error: ${error.name} - ${error.message}`);\n        throw error;\n    }\n}\n\ntry {\n    let result = processParameters(\"Hi\");\n    console.log(result);\n    console.log(\"No error occurred.\");\n} catch (error) {} finally {\n    console.log(\"The execution ended.\");\n}\n\n\n\n\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/javascript/adrs1166ma.js",
    "content": "/*\nEJERCICIO:\nExplora el concepto de manejo de excepciones según tu lenguaje.\nFuerza un error en tu código, captura el error, imprime dicho error\ny evita que el programa se detenga de manera inesperada.\nPrueba a dividir \"10/0\" o acceder a un índice no existente\nde un listado para intentar provocar un error.\n*\nDIFICULTAD EXTRA (opcional):\nCrea una función que sea capaz de procesar parámetros, pero que también\npueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\ncorresponderse con un tipo de excepción creada por nosotros de manera\npersonalizada, y debe ser lanzada de manera manual) en caso de error.\n- Captura todas las excepciones desde el lugar donde llamas a la función.\n- Imprime el tipo de error.\n- Imprime si no se ha producido ningún error.\n- Imprime que la ejecución ha finalizado. \n*/\n\n// 🔥 Forzar un error: Dividir entre cero\ntry {\n    const resultado = 10 / 0\n    console.log(\"Resultado:\", resultado) // Resultado: Infinity\n} catch (error) {\n    console.error(\"Se produjo un error:\", error.message)\n} finally {\n    console.log(\"La ejecución ha finalizado.\")\n}\n\n// 🔥 Forzar otro error: Acceder a un índice no existente de un array\ntry {\n    const lista = [1, 2, 3]\n    console.log(lista[5])\n} catch (error) {\n    console.error(\"Se produjo un error:\", error.message)\n} finally {\n    console.log(\"La ejecución ha finalizado.\")\n}\n\n// 🔥 Extra\n// Excepción personalizada\nclass MiErrorPersonalizado extends Error {\n    constructor(message) {\n        super(message);\n        this.name = \"MiErrorPersonalizado\";\n    }\n}\n\n// lanzar excepciones\nfunction procesarParametros(parametro) {\n    if (typeof parametro !== \"number\") {\n        throw new TypeError(\"El parámetro debe ser un número.\")\n    }\n\n    if (parametro < 0) {\n        throw new RangeError(\"El parámetro no puede ser negativo.\")\n    }\n\n    if (parametro === 42) {\n        throw new MiErrorPersonalizado(\"El número 42 está prohibido.\")\n    }\n\n    console.log(\"Procesamiento exitoso. Parámetro:\", parametro)\n}\n\n// Casos específicos\nfunction probarCaso(valor) {\n    console.log(`\\nProbando con el valor: ${valor}`)\n    try {\n        procesarParametros(valor)\n        console.log(\"No se ha producido ningún error.\")\n    } catch (error) {\n        console.error(\"Tipo de error:\", error.name)\n        console.error(\"Mensaje:\", error.message)\n    } finally {\n        console.log(\"La ejecución ha finalizado.\")\n    }\n}\n\nprobarCaso(10);       // Caso válido\nprobarCaso(\"texto\");  // Caso inválido (no es un número)\nprobarCaso(-5);       // Caso inválido (número negativo)\nprobarCaso(42);       // Caso inválido (número prohibido)"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/javascript/agusrosero.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado.\n */\n\n// EJERCICIO:\nfunction miError() {\n  try {\n    console.log(10 / 0);\n  } catch (err) {\n    console.log(err);\n  } finally {\n    console.log(\"Fin de la ejecucion...\");\n  }\n}\n\nmiError();\n\n// DIFICULTAD EXTRA:\nclass ErrorPersonalizado extends Error {\n  constructor(message) {\n    super(message);\n    this.name = \"MiError\";\n  }\n}\n\nfunction procesarParametros(param1) {\n  try {\n    if (typeof param1 !== \"number\") {\n      throw new TypeError(\"El dato debe ser un número\");\n    } else if (param1 < 0) {\n      throw new RangeError(\"El dato debe ser mayor a 0\");\n    } else if (param1 === 0) {\n      throw new ErrorPersonalizado(\"El dato no puede ser 0\");\n    }\n  } catch (error) {\n    console.log(error);\n  } finally {\n    console.log(\"Fin de la ejecucion..\");\n  }\n}\n\nconsole.log(procesarParametros(-1));\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/javascript/airesEsteban.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado.\n */\n\n\n// EJERCICIO\n\nfunction myError(){\n    try {\n        console.log(10/0)\n    } catch (error){\n        console.log(error)\n    }\n}\n\nmyError()\n\n// DIFICULTAD EXTRA\n\nclass ErrorCustom extends Error {\n    constructor(message){\n        super(message)\n        this.name = \"MyError\"\n    }\n}\n\nfunction myFunction(param) {\n    try {\n        if (typeof param !== \"number\"){\n            throw new TypeError(\"El dato debe ser un numero\")\n        }else if (param < 0){\n            throw new RangeError(\"El dato debe ser mayor a 0\")\n        }else if (param === 0) {\n            throw new ErrorCustom(\"EL dato no puede ser 0\")\n        }\n    } catch (error) {\n        console.log(error)\n    }\n}\n\nconsole.log(myFunction(-1))"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/javascript/alexdevrep.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado.\n */\n\n//Declaramos las variables necesarias\nlet numero1 = 10\nlet numero2= 0\nlet listado = [\"Hola\",\"Alexdevrep\",\"JavaScript\",\"Mundo\"]\n\n//División\n//Creamos una función que nos imprima el resultado de la división\nfunction dividir (numero1,numero2){\n    resultado= numero1/numero2\n    if (resultado== Infinity){\n        throw\"Infinity no es un número real\" //Lanzamos una excepción personalizada con throw\n    }\n    else{\n        console.log(resultado)\n    }\n}\n\n//Intentamos llamar a la función con el bloque try\ntry{\n    dividir(numero1,numero2)\n}\n\n//Si se produce un error lo capturamos con el bloque catch para que el programa no de error\ncatch(e){\n     console.log(\"ERROR: %s\",e)   \n}\n\n//Finalizamos el programa con finally este bloque se ejecuta haya o no haya excepción\n\nfinally{\n    console.log(\"Programa finalizado\")\n}\n\n//Despues de finalizar el manejo de excepciones el programa continúa en vez de colapsar\n\n//Listado\n//Vamos a iterar el listado para ver sus elementos\nfunction iterarListado(listado){\n    for(i=0;i<5;i++){\n        if (listado[i]===undefined){ //Si hay un elemento que sea undefined lanzamos la excepción\n            throw \"Solo hay 4 elementos en la lista\"\n        }\n        else{\n            console.log(listado[i])\n        }\n    }\n}\n\ntry{\n    iterarListado(listado)\n}\ncatch(e){\n    console.log(\"ERROR: %s\",e)\n}\nfinally{\n    console.log(\"Programa finalizado\")\n}\n\n//Dificultad EXTRA\nconst prompt = require('prompt-sync')()\n//Crearemos un función que multiplique por 5 un número natural de una cifra\nfunction multiplicación(parametro){\n    if(parametro <0){\n        throw \"El número tiene que ser positivo\"\n    }\n    else if(parametro>9){\n        throw \"El número no puede tener más de una cifra\"\n    }\n    else if(parametro===undefined){\n        throw \"El parámetro 2 es obligatorio\"\n    }\n    else{\n        producto= 5*parametro\n        console.log(producto)\n    }\n\n}\n\ntry{\n    parametro=prompt(\"Introduce un número para multiplicarlo por 5: \")\n    multiplicación(parametro)\n}\ncatch(e){\n    console.log(\"ERROR: %s\",e)\n}\nfinally{\n    console.log(\"Programa finalizado\")\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/javascript/bernatcs.js",
    "content": "// ** EJERCICIOS\n\nlet error = 10 / 0\nerror // Infinity. En JavaScript no da error.\n\nlet paraError2 = [0, 1]\nlet error2 = paraError2[2]\nerror2 // Undefined. En JavaScript no da error.\n\nfunction provocarErrores() {\n    try {\n        let obj = undefined; // Intentar acceder a una propiedad de undefined\n        console.log(obj.propiedad);\n    } catch (error) {\n        console.error(`Error capturado: ${error.message}`);\n    }\n\n    try {\n        funcionInexistente(); // Intentar llamar a una función que no existe\n    } catch (error) {\n        console.error(`Error capturado: ${error.message}`);\n    }\n\n    console.log(\"El programa continúa ejecutándose normalmente después de manejar las excepciones.\");\n}\n\n// provocarErrores();\n\n// ** DIFICULTAD EXTRA ** -------------------------------------------------------------------------------------------------------------------------------------------------\n\nfunction funcionErrores (a, b, c) {\n    try {\n        let a = undefined\n        console.log(a.propiedad)\n    } catch (error) {\n        console.error(`Error 1: ${error.message}`)\n        if (!error) {\n            console.error('No se ha producido ningun error')\n        }\n    }\n\n    try {\n        funcionInexistente2(b)\n    } catch (error) {\n        console.error(`Error 2: ${error.message}`)\n        if (!error) {\n            console.error('No se ha producido ningun error')\n        }\n    }\n\n    try {\n        throw Error(`Error 3: Manual`)\n    } catch (error) {\n        console.error(error.message)\n    }\n}\n\nfuncionErrores('a', 'b', 'c')\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/javascript/caterinarodriguezdev.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado.\n */\n\n\ntry {\n    const result = 10/0; // En Javascript no tira un error sino que resulta en Infinity\n    console.log(result);\n\n    const arr = [10, 20, 30];\n    console.log(arr[100]); // En Javascript no tira un error sino que resulta en undefined\n\n    console.log(patata);\n} catch (error) {\n    console.error('ha habio un error', error);\n}\n\n\nconsole.log('----------------------DIFICULTAD EXTRA-----------------------------');\n\n\n\nconst tirarErrores = (funcion, exponencial, equipo) => {\n\n    funcion();\n\n    let num = 2;\n    console.log('num exponencial', num.toExponential(exponencial));\n\n    if (equipo === 'Barça') {\n        console.log('Barça');\n    } else {\n        throw new Error('Equipo incorrecto!')\n    }\n}\n\nconst cate = () => {}\n\ntry {\n    tirarErrores(funcionIntexistente, -2, 'madrid')\n} catch(error) {\n    console.error(error);\n    console.log('---------------------------------------------------');\n}\n\ntry {\n    tirarErrores(cate, -2, 'madrid')\n} catch(error) {\n    console.error(error);\n    console.log('---------------------------------------------------');\n}\n\ntry {\n    tirarErrores(cate, 2, 'madrid')\n} catch(error) {\n    console.error(error);\n}"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/javascript/ceciliarava1.js",
    "content": "function divide(a, b) {\n    // 2- Throw\n    if (a == 0 && b == 0) {\n        throw new MyCustomeError('The numbers are equal to zero', a, b)\n    }\n    if (b == 0) {\n        throw new Error('You can not divide between zero')\n    } if (a == 0) {\n        throw new Error('There is nothing to divide')\n    } else {\n        return a / b\n    }\n}\n\n// try {\n//     divide(1, 0)\n// } catch (error) {\n//     console.log('There was an error:', error.message)\n// } \n\n/* Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado. \n */\n\nfunction errorHandling(a, b) {\n    // 1- try-catch\n    try {\n        console.log(`${a} / ${b} is: ${divide(a, b)}`)\n    } catch (error) {\n        console.log('There was an error:', error.message)\n    } finally {\n        console.log('End of execution')\n    }\n}\n\n// 3- Personalize\nclass MyCustomeError extends Error {\n    constructor (message, a, b) {\n        super(message)\n        this.a = a\n        this.b = b\n    }\n        \n    printNumbers() {\n        console.log(this.a, \"/\", this.b, '= 0')\n    }\n}\n\ntry {\n    console.log(divide(0, 0))\n} catch (error) {\n    console.log('There was a personalized error: ', error.message)\n    error.printNumbers()\n} finally {\n    console.log('End of execution')\n}\n\nerrorHandling(0,0)\nerrorHandling(10,0)\nerrorHandling(0,1)\nerrorHandling(2,1)\n\n\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/javascript/cesar-ch.js",
    "content": "/*\n    #10 EXCEPCIONES\n*/\n\ntry {\n    const x = 10 / 0\n    console.log(`El resultado de la division es: ${x}`)\n} catch (error) {\n    console.log(`Error: ${error.message}`)\n} finally {\n    console.log('Ejecución finalizada')\n}\n\n/*\n    DIFICULTAD EXTRA \n*/\n\nclass ErrorPersonalizado extends Error {\n    constructor(message) {\n        super(message);\n        this.name = 'ErroPersonalizado';\n    }\n}\n\nfunction procesarParametros(parametro1, parametro2) {\n    if (typeof parametro1 !== \"number\" || typeof parametro2 !== \"number\") {\n        throw new ErrorPersonalizado('Los parametros deben ser numericos')\n    }\n    if (parametro2 === 0) {\n        throw new Error('No se puede dividir por cero')\n    }\n    return parametro1 / parametro2\n}\n\ntry {\n    const resultado = procesarParametros(\"10\", 0)\n    console.log(`El resultado de la division es: ${resultado}`)\n} catch (error) {\n    if (error instanceof ErrorPersonalizado) {\n        console.log(`Error: ${error.message}`)\n    } else {\n        console.log(`Error: ${error.message}`)\n    }\n} finally {\n    console.log('Ejecución finalizada')\n}"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/javascript/christian-jfr.js",
    "content": "// #10 EXCEPCIONES\n\n/**\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n */\n// Manejo de excepciones con try/catch + finally (Opcional)\nfunction testProgram() {\n\ttry {\n\t\t// forzar un TypeError\n\t\tconsole.lo('this message will not be displayed due to a TypeError');\n\t} catch (error) {\n\t\tconsole.error(error); // TypeError: Cannot read property 'lo' of undefined\n\t} finally {\n\t\tconsole.log('the \"finally\" block will always be executed');\n\t}\n\t// El programa se sigue ejecutando normalmente\n\tconsole.log('Program continues to run normally');\n}\n\ntestProgram();\n\n/* * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado.\n */\n\nclass InvalidCharacterError extends Error {\n\tconstructor(message) {\n\t\tsuper(message);\n\t\tthis.name = 'Invalid Character in Name';\n\t}\n}\n\nfunction validateUserData(id, name) {\n\t// Validación de tipo de dato\n\tif (typeof id !== 'number' || id <= 0) {\n\t\tthrow new TypeError('ID must be a positive number');\n\t}\n\tif (typeof name !== 'string' || name.length === 0) {\n\t\tthrow new Error('NAME must be a non-empty string');\n\t}\n\n\t// Validación de tipo de caracteres\n\tconst validName = /^([a-zA-Z]+)\\s([a-zA-Z]+)$/.test(name);\n\tif (!validName) {\n\t\tthrow new InvalidCharacterError(\n\t\t\t'NAME must only contain alphabetic characters and spaces'\n\t\t);\n\t}\n\n\t// Si no hay errores, se crea el objeto user\n\tconst user = {\n\t\tid: id,\n\t\tname: name,\n\t};\n\n\treturn user;\n}\n\n// Usos\n\ntry {\n\tconst user1 = validateUserData(1, 'Leia Organa'); // Sin errores\n\tconsole.log('User created:', user1);\n} catch (error) {\n\tconsole.error('Error type:', error.name);\n\tconsole.error('Error message:', error.message);\n} finally {\n\tconsole.log('The execution has ended.');\n}\n\ntry {\n\tconst user2 = validateUserData(true, 'Anakin Skywalker'); // TypeError\n\tconsole.log('User created:', user2);\n} catch (error) {\n\tconsole.error('Error type:', error.name);\n\tconsole.error('Error message:', error.message);\n} finally {\n\tconsole.log('The execution has ended.');\n}\n\ntry {\n\tconst user3 = validateUserData(123, ''); // Error\n\tconsole.log('User created:', user3);\n} catch (error) {\n\tconsole.error('Error type:', error.name);\n\tconsole.error('Error message:', error.message);\n} finally {\n\tconsole.log('The execution has ended.');\n}\n\ntry {\n\tconst user4 = validateUserData(-7, 'Han Solo'); // TypeError\n\tconsole.log('User created:', user4);\n} catch (error) {\n\tconsole.error('Error type:', error.name);\n\tconsole.error('Error message:', error.message);\n} finally {\n\tconsole.log('The execution has ended.');\n}\n\ntry {\n\tconst user5 = validateUserData(10, 'Luke Skywalker.08'); // InvalidCharacterError\n\tconsole.log('User created:', user5);\n} catch (error) {\n\tconsole.error('Error type:', error.name);\n\tconsole.error('Error message:', error.message);\n} finally {\n\tconsole.log('The execution has ended.');\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/javascript/duendeintemporal.js",
    "content": "/* EXCEPCIONES */\n//bibliography reference\n//Secrets of the JavaScript Ninja (John Resig, Bear Bibeault, Josip Maras) (z-lib.org)\n//Professional JavaScript for web developers by Matt Frisbie [Frisbie, Matt] (z-lib.org)\n//JavaScript Notes for Professionals (GoalKicker.com) (Z-Library)\n//GPT\n\n//Short for console.log()\nlet log = console.log;\n\nwindow.addEventListener('load', ()=>{\n    const body = document.querySelector('body');\n    const title = document.createElement('h1');\n    \n    body.style.setProperty('background', '#000');\n    body.style.setProperty('text-align', 'center');\n    \n    title.textContent = 'Retosparaprogramadores #10.';\n    title.style.setProperty('font-size', '3.5vmax');\n    title.style.setProperty('color', '#fff');\n    title.style.setProperty('line-height', '100vh');\n    \n    body.appendChild(title);\n    \n    setTimeout(()=>{\n    alert('Retosparaprogramadores #10. Please open the Browser Developer Tools.');\n    }, 2000);\n    log( 'Retosparaprogramadores #10'); \n});\n\n\n/* Runtime errors in JavaScript are instances of the Error object. The Error object can also be used as-is, or as the base for user-defined exceptions. It's possible to throw any type of value - for example, strings - but you're strongly encouraged to use Error or one of its derivatives to ensure that debugging information -- such as stack traces -- is correctly preserved.\nThe first parameter to the Error constructor is the human-readable error message. You should try to always specify a useful error message of what went wrong, even if additional information can be found elsewhere.\n} */\n\n/* In JavaScript, exception handling is primarily done through the statements try, catch, finally, and throw. Here is a summary of each:\n\n    try: It is used to wrap the code that may throw an exception. If an error occurs within the try block, control is transferred to the catch block.\n    catch: It is used to handle the exception. It receives the error object as an argument.\n    finally: This block executes after the try and catch blocks have completed, regardless of whether an exception was thrown or not.\n    throw: It is used to manually throw an exception.\n */\n\nlet num = 0, result;\n\ntry {\n    if(typeof num === 'number' && num != 0) {\n        result = 10 / num;\n    }else if(num == 0) {\n        throw new Error(\"It seems you've tried to divide by zero, which is not permitted. Please enter a valid non-zero number.\");\n    }else{\n        throw new Error(\"It seems you've tried to divide by a non number value, which is not permitted. Please enter a valid number.\");\n    }\n} catch (error) {\n    log('Something went wrong! ' + error.message);\n}\n\nlog(result); // Something went wrong! It seems you've tried to divide by zero, which is not permitted. Please enter a valid non-zero number.\n\n//Note: Javascript returns infinity for divide any number by 0, so we have to explicity throw and error if we want inform about it.\n\n/* Exceptions are to synchronous code what rejections are to promise-based asynchronous code. If an exception is thrown in a promise handler, its error will be automatically caught and used to reject the promise instead. */\n\nPromise.resolve(102)\n    .then(result => {\n        throw new Error(\"explicitly rejected promise\");\n})\n    .then(result => {\n        console.info(\"Promise resolved: \" + result);\n})\n    .catch(error => {\n        console.error(\"Promise rejected: \" + error);\n}); // Promise rejected: Error: explicitly rejected promise (it will be logged at the end cause the async nature of the promise constructor)\n\n/* There are six specific core error constructors in JavaScript:\nEvalError - creates an instance representing an error that occurs regarding the global function eval().\nInternalError - creates an instance representing an error that occurs when an internal error in the\nJavaScript engine is thrown. E.g. \"too much recursion\". (Supported only by Mozilla Firefox)\nRangeError - creates an instance representing an error that occurs when a numeric variable or parameter is outside of its valid range.\nReferenceError - creates an instance representing an error that occurs when dereferencing an invalid\nreference.\nSyntaxError - creates an instance representing a syntax error that occurs while parsing code in eval().\nTypeError - creates an instance representing an error that occurs when a variable or parameter is not of a valid type.\nURIError - creates an instance representing an error that occurs when encodeURI() or decodeURI() are\npassed invalid parameters.\nIf you are implementing error handling mechanism you can check which kind of error you are catching from code. */\n\nfunction getUserName(user) {\n    try {\n        const name = user.name.toUpperCase();\n        log(`User name: ${name}`);\n    } catch (e) {\n        if (e instanceof Error) {\n            log('Instance of general Error constructor');\n        }\n\n        if (e instanceof TypeError) {\n            log('TypeError: Cannot read property \"name\" of undefined or null');\n        }\n    }\n}\n\ngetUserName({ name: 'Roxy' }); //  User name: Roxy\n\ngetUserName(undefined); // Instance of general Error constructor TypeError: Cannot read property \"name\" of undefined or null\n\n//Extra excercises\n\nconst checkValues = (arr, index)=>{\n    try{\n        if(!Array.isArray(arr)){\n            throw new TypeError('the first parameter most be of type array');\n        }else{\n            if(arr.length < 0 || arr.length == 0) throw new Error('You give a empty array as parameter!');\n\n            if(!arr[index]) throw new ReferenceError(`${index} is not a valid index for the array given`);\n        }\n\n        log(`The position given corresponds to this value: ${arr[index]}`);\n        log(\"There's no errors when executing the function.\")\n\n    }catch(e){\n        log(e.name + \": Ooops! \" + e.message);\n    }finally{\n        log('The process is finished')\n    }\n}\n\ncheckValues([8, 5, 6, 4], 8); // ReferenceError: Ooops! 8 is not a valid index for the array given\n// The process is finished\ncheckValues([], 4); // Error: Ooops! You give a empty array as parameter!\n// The process is finished\ncheckValues([0, 76, 32, 1, 4, 2], 'Kia'); // ReferenceError: Ooops! Kia is not a valid index for the array given\n// The process is finished\ncheckValues('Dev', 5); // TypeError: Ooops! the first parameter most be of type array\n// The process is finished\ncheckValues([4, 5, 3, 18, 22], 3); // The position given corresponds to this value: 18\n// There's no errors when executing the function.\n// The process is finished"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/javascript/emedevelopa.js",
    "content": "function indice () {\n    let myArray = [\"a\", \"b\", \"c\"];\n    console.log(myArray[1]);\n    try {\n        console.log(myArray[3]);\n        throw new Error (\"El indice no existe\")\n    } catch (error) {\n        console.error(error.message);\n    } finally {\n        console.log(\"Fin del programa\")\n    }\n\n}\nindice();\n\n//EXTRA \n//Primero definir el error personalizado\nclass errorPersonalizado extends Error {\n    constructor (message) {\n        super (message);\n        this.name = \"Mi error\"\n    }\n}\n\n//Aquí la función\nfunction numero (num) {\n    try {\n        if (typeof num !== \"number\") {\n            throw new TypeError (\"El dato debe ser un número\");\n        }\n        if (num < 0) {\n            throw new RangeError (\"El dato debe ser mayor a 0\");\n        }\n        if (num === 0) {\n            throw new errorPersonalizado (\"El dato no puede ser 0\");\n        }\n        console.log(\"Dato procesado:\", num);\n        console.log(\"No se ha producido ningún error\");\n    }\n    catch(error) {\n        console.log(\"Tipo de error:\", error.name, error.message);\n    } finally {\n        console.log(\"Programa finalizado\")\n    }\n}\nnumero(-6);\nnumero(6);\nnumero(0);"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/javascript/eulogioep.js",
    "content": "// Parte 1: Manejo básico de excepciones\n\n// Ejemplo 1: División por cero\ntry {\n    // Intentamos dividir por cero para forzar una excepción\n    let resultado = 10 / 0;\n    console.log(resultado); // En JavaScript, esto no lanza una excepción, imprime Infinity\n} catch (error) {\n    console.log(\"Error aritmético:\", error.message);\n}\n\n// Ejemplo 2: Acceso a índice no existente\ntry {\n    // Intentamos acceder a un índice no existente de un array\n    let array = [\"Elemento\"];\n    let elemento = array[5]; // Esto no lanza una excepción en JavaScript, devuelve undefined\n    console.log(elemento);\n    // Para forzar un error, podemos intentar acceder a una propiedad de undefined\n    console.log(elemento.length);\n} catch (error) {\n    console.log(\"Error de acceso:\", error.message);\n}\n\n// Parte 2: Función con múltiples excepciones (DIFICULTAD EXTRA)\n\n// Definimos nuestra excepción personalizada\nclass MiExcepcionPersonalizada extends Error {\n    constructor(mensaje) {\n        super(mensaje);\n        this.name = \"MiExcepcionPersonalizada\";\n    }\n}\n\n// Función que puede lanzar 3 tipos diferentes de excepciones\nfunction procesarParametro(parametro) {\n    if (typeof parametro !== 'number') {\n        throw new TypeError(\"El parámetro debe ser un número\");\n    }\n    if (parametro < 0) {\n        throw new RangeError(\"El parámetro no puede ser negativo\");\n    }\n    if (parametro === 0) {\n        throw new Error(\"No se puede dividir por cero\");\n    }\n    if (parametro > 10) {\n        throw new MiExcepcionPersonalizada(\"El parámetro es demasiado grande\");\n    }\n\n    // Si no hay errores, realizamos alguna operación\n    let resultado = 100 / parametro;\n    console.log(\"Resultado:\", resultado);\n}\n\n// Probamos la función con diferentes valores\nfunction probarProcesarParametro(valor) {\n    try {\n        procesarParametro(valor);\n        console.log(\"No se ha producido ningún error.\");\n    } catch (error) {\n        console.log(\"Tipo de error:\", error.constructor.name);\n        console.log(\"Mensaje:\", error.message);\n    } finally {\n        console.log(\"La ejecución ha finalizado.\");\n    }\n    console.log(\"---\");\n}\n\n// Probamos con diferentes valores\nprobarProcesarParametro(\"no es un número\");\nprobarProcesarParametro(-1);\nprobarProcesarParametro(0);\nprobarProcesarParametro(5);\nprobarProcesarParametro(15);"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/javascript/garos01.js",
    "content": "let a = 5;\nlet b = 0;\n\ntry {\n  // Intenta ejecutar el código que podría generar un error\n  let resultado = a / b; // Intentando dividir por cero\n  console.log(`La división fue exitosa: ${resultado}`);\n} catch (error) {\n  // Captura la excepción específica y maneja el error\n  console.error(`Error: ${error}`);\n} finally {\n  // Este bloque se ejecuta siempre, independientemente de si hubo una excepción o no\n  console.log(\"Fin del manejo de excepciones\");\n}\n\nlet lista = [1, 2, 3];\n\ntry {\n  // Intenta acceder a un índice no existente de una lista\n  let elemento = lista[4]; // Intentando acceder a un índice no existente\n  console.log(`Elemento obtenido: ${elemento}`);\n} catch (error) {\n  // Captura la excepción específica y maneja el error\n  console.error(`Error: ${error}`);\n} finally {\n  // Este bloque se ejecuta siempre, independientemente de si hubo una excepción o no\n  console.log(\"Fin del manejo de excepciones\");\n}\n\n// Ejercicio extra\n\nclass MiErrorPersonalizado extends Error {\n  constructor(message) {\n    super(message);\n    this.name = \"MiErrorPersonalizado\";\n  }\n}\n\nfunction procesarParametros(parametro) {\n  try {\n    if (typeof parametro !== \"number\") {\n      throw new TypeError(\"El parámetro debe ser un número\");\n    }\n\n    if (parametro === 0) {\n      throw new Error(\"El parámetro no puede ser cero\");\n    }\n\n    if (parametro < 0) {\n      throw new MiErrorPersonalizado(\"El parámetro no puede ser negativo\");\n    }\n\n    console.log(\"El parámetro es válido:\", parametro);\n  } catch (error) {\n    console.error(\"Tipo de error:\", error.name);\n    console.error(\"Mensaje de error:\", error.message);\n  } finally {\n    console.log(\"La ejecución ha finalizado\");\n  }\n}\n\ntry {\n  procesarParametros(\"cadena\");\n  procesarParametros(0);\n  procesarParametros(-5);\n  procesarParametros(10);\n} catch (error) {\n  console.error(`Se ha producido un error fuera de la función: ${error}`);\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/javascript/giovanyosorio.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado. \n */\n\nfunction exception(n){\n    try{\n      let res=n/0\n      console.log(res)\n    }catch(error){\n      console.error(\"Ha ocurrido un error:\", error.message);\n    }\n     finally {\n    // Este bloque siempre se ejecuta, haya ocurrido un error o no\n    console.log(\"La ejecución ha finalizado.\");\n  }\n  }\n  exception(10)\n  \n\n  // Excepción personalizada\nclass MiErrorPersonalizado extends Error {\n    constructor(mensaje) {\n      super(mensaje);\n      this.name = \"MiErrorPersonalizado\";\n    }\n  }\n  \n  // Función que puede lanzar diferentes tipos de excepciones\n  function procesar(parametro) {\n    if (typeof parametro !== 'number') {\n      throw new TypeError(\"El parámetro debe ser un número.\");\n    }\n    if (parametro < 0) {\n      throw new RangeError(\"El parámetro no puede ser negativo.\");\n    }\n    if (parametro === 42) {\n      throw new MiErrorPersonalizado(\"¡Oh, no! El parámetro es 42.\");\n    }\n    console.log(\"Parámetro procesado correctamente:\", parametro);\n  }\n  \n  // Llamada a la función dentro de un bloque try-catch\n  try {\n    procesar(\"texto\");  // Provoca un TypeError\n    procesar(-5);       // Provoca un RangeError\n    procesar(42);       // Provoca un MiErrorPersonalizado\n    procesar(10);       // Se ejecuta correctamente\n  } catch (error) {\n    console.error(\"Se ha producido un error:\", error.name, error.message);\n  } finally {\n    console.log(\"La ejecución ha finalizado.\");\n  }\n  \n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/javascript/hectorio23.js",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\n\"use strict\";\n\n\n/*\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado. \n*/\n\n\n// Función para dividir dos números e intentar forzar un error\nfunction dividir() {\n    try {\n        let divisor = 0;\n        if (divisor === 0) {\n            throw new Error(\"División por cero\");\n        }\n        let resultado = 10 / divisor; // Intento de dividir por cero\n        console.log(`El resultado de la división es: ${resultado}`);\n    } catch (error) {\n        console.error(`Se produjo un error: ${error.message}`);\n    }\n}\n\n// Función que puede lanzar excepciones personalizadas\nfunction procesarParametro(parametro) {\n    try {\n        if (parametro === 0) {\n            throw new Error(\"El parámetro no puede ser cero\");\n        } else if (parametro < 0) {\n            throw new Error(\"El parámetro no puede ser negativo\");\n        } else {\n            console.log(\"Procesamiento exitoso\");\n        }\n    } catch (error) {\n        console.error(`Se produjo un error: ${error.message}`);\n    } finally {\n        console.log(\"La ejecución ha finalizado.\");\n    }\n}\n\n// Función principal\n(function main() {\n    // Forzar un error al dividir por cero\n    console.log(\"Intentando dividir por cero:\");\n    dividir();\n\n    console.log(\"\\n---------------------------------------\\n\");\n\n    // Intento de procesar un parámetro\n    console.log(\"Intentando procesar parámetro:\");\n    procesarParametro(-3);\n})();\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/javascript/jeronimocardu.js",
    "content": "try{\n    let nums = [0, 1, 2, 3];\n    let n = 5;\n    if(n > nums.length) throw new Error('Ese indice no existe en este array');\n    else console.log(nums[n]);\n}catch(e){\n    console.log(e.toString())\n}\n\nconsole.log('\\n el programa sigue\\n\\n\\n');\n\n\n/////////////////////////////////////////////////////////\n//                  Extra\nfunction excepciones(param1, param2){\n    if((param1 + param2) <= 0) throw new Error('El resultado es negativo o 0');\n    if(param1 < 0) throw new Error('El primer número es negativo');\n    if(param2 < 0) throw new Error('El segundo número es negativo');\n    console.log('No se ha producido ningun error!');\n}\n\ntry{\n    excepciones(-2, 2);\n    excepciones(-2, 20);\n    excepciones(10, -2);\n    excepciones(10, 2);\n}catch(e){\n    console.log(e.toString());\n}finally{\n    console.log('El programa finalizó');\n}"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/javascript/juandaherrera.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n */\n\ntry {\n    const myVar = 10 / 0;\n    console.log(myVar);\n} catch (e) {\n    console.log(e.toString());\n}\n\ntry {\n    const myVar = [1, 2, 3];\n    console.log(myVar[10]);\n} catch (e) {\n    console.log(e.toString());\n    console.log(`Tipo de excepción: ${e.name}`);\n}\n\nconsole.log(\"-\".repeat(35));\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado.\n */\n\nclass MyException extends Error {\n    constructor(message) {\n        super(message);\n        this.name = \"MyException\";\n    }\n}\n\nfunction myFunction(param1, param2, param3) {\n    if (\n        typeof param1 !== \"number\" ||\n        typeof param2 !== \"number\" ||\n        typeof param3 !== \"string\"\n    ) {\n        throw new TypeError(\n            \"Los parámetros deben ser del tipo específico: number, number, string\"\n        );\n    }\n    if (param1 > 1000) {\n        throw new MyException('El valor de \"param1\" no puede ser mayor a 1000');\n    }\n    if ((param3.match(/ /g) || []).length > 1) {\n        throw new SyntaxError(\n            'El valor del \"param3\" no puede tener más de un espacio en blanco'\n        );\n    }\n    console.log((param3.match(/ /g) || []).length);\n    return [param1, param2, param3];\n}\n\ntry {\n    const testVar1 = myFunction(2500, 10.5, \"avg\");\n    console.log(testVar1);\n} catch (e) {\n    console.log(`${e.name}: ${e.message}`);\n}\n\ntry {\n    const testVar2 = myFunction(1, 10.5, \"avg   \");\n    console.log(testVar2);\n} catch (e) {\n    console.log(`${e.name}: ${e.message}`);\n}\n\ntry {\n    const testVar3 = myFunction(1, 10.5, \"avg\");\n    console.log(testVar3);\n} catch (e) {\n    console.log(`${e.name}: ${e.message}`);\n} finally {\n    console.log(\"Ejecución finalizada\");\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/javascript/juserdev.js",
    "content": "\n/*\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado. \n */\n\nfunction divide(a, b) {\n    if (b === 0) {\n        throw new Error(\"El numero no puede ser diviible entre 0\")\n    }\n    return a / b\n}\n\ntry {\n    divide(10, 0)\n} catch (error) {\n    console.error(\"Error:\", error.message)\n} finally {\n    console.log(\"el codigo sigue corriendo mientras capturo el error\")\n}\n\n\n\nconsole.log(\"---------------------- Dificultad Extra ----------------------\")\n\nclass CustomError extends Error {\n    constructor(message) {\n        super(message)\n        this.name = \"CustomError\"\n    }\n}\n\nfunction errorFunction(a, b, c) {\n    if (typeof a !== \"string\") {\n        throw new TypeError(\"El parametro a no es un String\")\n    } else if (typeof b !== \"number\") {\n        throw new TypeError(\"El parametro b no es un Number\")\n    } else if (!Array.isArray(c)) {\n        throw new CustomError(\"El parametro c no es un Array\")\n    }\n\n    console.log(`a: ${typeof a} - b: ${typeof b} - c: ${typeof c}`)\n}\n\ntry {\n    errorFunction(\"2\", 2, [2])\n} catch (error) {\n    console.error(`${error.name}: ${error.message}`)\n} finally {\n    console.log(\"La ejecucion a terminado\")\n}"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n_______________________________________\n#10 EXCEPCIONES\n---------------------------------------\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado.\n*/\n\n// ________________________________________________________\n// 1: Capturar excepción por división entre 0 (personalizada)\ntry {\n    const a = 7;\n    const b = 0;\n    if (b === 0) {\n        throw new Error(\"No se puede dividir entre cero.\");\n    }\n    const r = a / b;\n    console.log(\"Resultado: \", r);\n} catch (error) {\n    console.error(\"Error capturado: \", error.message);\n}\n\n// 2: Capturar errores de conversión o concatenación\ntry {\n    // Genera un error al intentar sumar un número con una cadena\n    const r = parseInt(\"uno\") + 2; // Aquí \"uno\" no puede convertirse\n    if (isNaN(r)) {\n        throw new TypeError(\"Conversión fallida: el resultado no es un número.\");\n    }\n} catch (error) {\n    console.error(\"Error capturado: \", error.message);\n}\n\n// 3: Capturar múltiples tipos de excepciones\ntry {\n    // Lanza manualmente un error de tipo o rango\n    const value = -1;\n    if (value < 0) {\n        throw new RangeError(\"El valor no puede ser negativo.\");\n    }\n} catch (error) {\n    if (error instanceof RangeError) {\n        console.error(\"Error de rango: \", error.message);\n    } else if (error instanceof TypeError) {\n        console.error(\"Error de tipos: \", error.message);\n    } else {\n        console.error(\"Error desconocido: \", error.message);\n    }\n}\n\n//4: Capturar una excepción genérica\ntry {\n    // Intentar acceder a un índice fuera de rango en un arreglo\n    const myArray = [1, 2, 3];\n    console.log(myArray[10]); // No genera error automáticamente\n    throw new Error(\"Índice fuera de rango.\"); // Lanzamos un error manualmente\n} catch (error) {\n    console.error(\"Error capturado: \", error.message);\n}\n\n// 5: Capturar y mostrar el tipo de excepción\ntry {\n    // Genera un error lanzando un número en lugar de un mensaje (caso extraño)\n    throw 42;\n} catch (error) {\n    console.error(\"Tipo de error: \", typeof error, \" | Valor: \", error);\n}\n\n// 6: Bloque finally (ejecutar siempre)\ntry {\n    // Simula un error de división\n    const a = 5;\n    const b = 0;\n    if (b === 0) {\n        throw new Error(\"No se puede dividir entre cero.\");\n    }\n} catch (error) {\n    console.error(\"Error capturado: \", error.message);\n} finally {\n    console.log(\"Bloque finally ejecutado.\");\n}\n\n// 7: Lanzar una excepción personalizada\nclass CustomException extends Error {\n    constructor(message) {\n        super(message);\n        this.name = \"CustomException\";\n    }\n}\n\ntry {\n    throw new CustomException(\"Este es un error personalizado.\");\n} catch (error) {\n    if (error instanceof CustomException) {\n        console.error(\"Error personalizado capturado: \", error.message);\n    } else {\n        console.error(\"Error desconocido: \", error.message);\n    }\n}\n\n// 8: Pasar un objeto a la excepción\nclass DictionaryException extends Error {\n    constructor(data) {\n        super(\"Excepción con datos adicionales\");\n        this.data = data;\n    }\n}\n\ntry {\n    throw new DictionaryException({ msg: \"Mensaje\", info: \"Información adicional\" });\n} catch (error) {\n    if (error instanceof DictionaryException) {\n        console.error(\"Datos de la excepción: \", error.data);\n    }\n}\n\n\n// ________________________________________________________\n// DIFICULTAD EXTRA\n\nclass OddNumberError extends Error {\n    constructor(msg = \"No dividir entre impares\") {\n        super(msg);\n        this.name = \"OddNumberError\";\n    }\n}\n\nfunction division(a, b) {\n    if (b % 2 !== 0) {\n        throw new OddNumberError();\n    }\n    return a / b;\n}\n\nfunction operation(a, b) {\n    try {\n        console.log(\"Resultado: \", division(a, b));\n    } catch (error) {\n        console.error(\"Error: \", error.constructor.name, error.message);\n    } finally {\n        console.log(\"Operación terminada.\");\n    }\n}\n\nconsole.log(\"\\n___________\\nEjercicio:\");\noperation(10, \"uno\");\noperation(10, 0);\noperation(10, 5);\noperation(10, 2);\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/javascript/miguelex.js",
    "content": "// Ejemplo de excepción por división por cero\nfunction division(a, b) {\n    try {\n        if (b === 0) {\n            throw new Error(\"No se puede dividir por cero\");\n        }\n        return a / b;\n    } catch (error) {\n        return error.message;\n    }\n}\n\nconsole.log(division(10, 0));\nconsole.log(division(5, 3));\n\n// Ejemplo de excepción por índice fuera de rango\nfunction outOfRange(lista, indice) {\n    try {\n        if (indice < 0 || indice >= lista.length) {\n            throw new Error(\"Índice fuera de rango\");\n        }\n        return lista[indice];\n    } catch (error) {\n        return error.message;\n    }\n}\n\nconsole.log(outOfRange([1, 2, 3], 5));\n\nclass MiError extends Error {\n    constructor(valor) {\n        super();\n        this.valor = valor;\n    }\n    toString() {\n        return \"Error: \" + this.valor;\n    }\n}\n\nfunction extra(a, b, c) {\n    if (typeof a !== \"string\" || a.length === 0) {\n        throw new Error(\"El primer parametro debe ser un string y no vacio\");\n    }\n    if (typeof b !== \"number\" || b <= 0) {\n        throw new Error(\"El segundo parametro debe ser un entero y mayor que 0\");\n    }\n    if (typeof c !== \"string\") {\n        throw new Error(\"El tercer parametro debe ser un string\");\n    }\n    if (c === \"Mouredev\") {\n        throw new MiError(\"El tercer parametro no puede ser Mouredev\");\n    }\n    return `Solucion reto ${b} - ${a} del usuario ${c}`;\n}\n\ntry {\n    //console.log(extra(\"Swift\", 10, \"Mouredev\"));\n    //console.log(extra(\"Javascript\", 10, \"Miguelex\"));\n    //console.log(extra(\"PHP\", -5, \"Miguelex\"));\n    console.log(extra(\"\", 10, \"Miguelex\"));\n} catch (error) {\n    console.log(error instanceof MiError ? error.toString() : error.message);\n} finally {\n    console.log(\"Todo ha ido bien\");\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/javascript/nlarrea.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado. \n */\n\n\nconst months = [\n    'January',\n    'February',\n    'March',\n    'April',\n    'May',\n    'June',\n    'July',\n    'August',\n    'September',\n    'October',\n    'November',\n    'December',\n];\n\n\ntry {\n    const myResult = 10 / 0;\n    if (myResult === Infinity) {\n        throw new Error('You can\\'t divide by zero!');\n    }\n\n    const myItem = months[12];\n    if (myItem === undefined) {\n        throw new Error('You tried to access an item out of index.')\n    }\n} catch (error) {\n    console.error(error);\n}\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado. \n */\n\n\nclass UnknownTypeError extends Error {\n    constructor(message) {\n        super(message);\n        this.name = \"UnknownTypeError\";\n    }\n}\n\n\nfunction processParams(...params) {\n    for (let param of params) {\n        if (\n            typeof param !== 'number' &&\n            typeof param !== 'string' &&\n            typeof param !== 'array'\n        ) {\n            throw new UnknownTypeError(\n                'I don\\'t know about this type of data.'\n            );\n        }\n\n        if (typeof param === 'string' && param.length < 10) {\n            throw new SyntaxError('The length of the string is too short.');\n        }\n\n        if (typeof param === 'number' && param > 0 && param < 5) {\n            throw new RangeError('The number must be positive and greater than 5.');\n        }\n    }\n}\n\nprocessParams(3.14, true, 'short', [1, 2, 3]);"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/javascript/ocram1304.js",
    "content": "function dividir(num1,num2){\n\n  if(num2 === 0){\n    throw new Error(\"No se puede dividir entre cero\");\n  }\n  else{\n    return num1/num2;\n  }\n \n}\nfunction Probar(n1,n2){\n    try {\n        dividir(n1,n2);\n        \n    } catch (error) {\n        console.log(\"Erro:\",error);\n    }\n    finally{\n        console.log(\"Intente ingrsar un divisor distinto a 0\");\n    }\n}\nProbar(10,0);\n//Difucultad Extra\n\nfunction exepciones(us,pas){\n    if(pas.length<7){\n        throw new Error (\"La contraseña debe de tener más de 7 caracteres\");\n    }\n    else if(typeof us !== 'string'){\n        throw new Error(\"Solo se permiten caracteres\");\n    }\n    else if(us === \"\" || pas === \"\"){\n        throw new Error (\"Campos vacios\");\n    }\n\n}\nfunction Comprobar(user, password){\n try {\n    exepciones(user,password);\n    console.log(\"No ocurrienron exepciones\",user,password);\n    \n } catch (error) {\n    confirm.log (\"Error\", error);\n }\n finally{\n\n    console.log(\"Ingrese  los datos nuevamente\");\n }\n\n\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/javascript/oleojake.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n */\n\ntry {\n\tconsole.log(myvar);\n} catch (error) {\n\tconsole.error(error);\n} finally {\n\tconsole.log(\"La ejecución ha finalizado.\");\n}\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado.\n */\n\nclass CustomError extends Error {\n  constructor(mensaje) {\n    super(mensaje);\n    this.name = this.constructor.name;\n  }\n}\n\nfunction proccessNumberParam(param) {\n\ttry {\n\t\tif (typeof param !== 'number') {\n\t\t\tthrow new TypeError(\"El parámetro no puede ser undefined\");\n\t\t}\n\n\t\tif (param < 0) {\n\t\t\tthrow new RangeError(\"El parámetro no puede ser negativo\");\n\t\t}\n\n\t\tif (param % 2 !== 0) {\n\t\t\tthrow new CustomError(\"El parámetro no es un número par\");\n\t\t}\n\n\t\tconsole.log(\"El parámetro es correcto y no se ha producido ningún error.\");\n\t} catch (error) {\n\t\tconsole.error(error.constructor.name + \": \" + error.message);\n\t} finally {\n\t\tconsole.log(\"La ejecución ha finalizado.\");\n\t}\n}\n\nproccessNumberParam(10);\nproccessNumberParam(\"10\");\nproccessNumberParam(-10);\nproccessNumberParam(3);\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/javascript/parababire.js",
    "content": "//Provocar error\n\n/*La declaración try...catch detecta el error(forzado) lo registra e imprime el mensage creado*/\ntry {\n  console.lg(\"Hello World\");\n} catch (error) {\n  console.log(error = 'Error de tipeado: console.lg(\"Hello World\") no es una función.');\n} finally {\n  console.log(\"La ejecución ha finalizado\");\n}\n\n//Error personalizado\n\nclass Error_Personalizado extends Error {\n  constructor(message) {\n    super(message);\n    this.name = \"NumberError\";\n  }\n}\n\nfunction evaluarNumero(num) {\n  try {\n    if (typeof num === \"string\") {\n      throw new Error_Personalizado(\"Debe ingresar un número.\");\n    } else  if (typeof num === \"number\") {\n      if (num <= 0) {\n        throw new TypeError(\": Solo números positivos son permitidos.\");\n      } else if (!Number.isInteger(num)) {\n        throw \"Solo números enteros son permitidos.\"\n      }\n      console.log(num + num);\n      console.log(\"Ningún error encontrado\");\n    }\n  } catch (err) {\n    if (err instanceof Error_Personalizado) {\n      console.log(\"Dato ingresado de tipo string: \" + err.message);\n    } else if (err instanceof TypeError) {\n      console.log(err.name + err.message);\n    } else {\n      console.log(err);\n    }\n  } finally {\n    console.log(\"La ejecución ha finalizado\");\n  }\n}\nevaluarNumero(\"Hola\");\nevaluarNumero(\"3\");\nevaluarNumero(-3.3);\nevaluarNumero(3.3);\nevaluarNumero(33);"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/javascript/pedamoci.js",
    "content": "try {\n  // creo un objeto y le hago un push para forzar un error ya que push es un metodo de array\n  const obj = new Object\n  obj.push() \n\n} catch (error) { // capturo el error\n  // imprimo el error completo y despues el nombre (tipo) y el mensaje por separado\n  console.log(error)\n  console.log(error.name)\n  console.log(error.message)\n}\n\n// -------------------------------------- DIFICULTAD EXTRA --------------------------------------\nclass TipoDeDatoErroneo extends Error {  // creo mi propio error sin mensaje (en este ejercicio no hace falta)\n  constructor() {\n    super()\n    this.name = \"TipoDeDatoErroneo\"\n  }\n}\n\n// datos correctos\nlet tipoDato = 'array'\nlet longitud = 4\nlet estructuraBase = []\n\n// datos erroneos\nlet tipoDatoErroneo = 'object'\nlet longitudErronea = -1\nlet longitudNaN = parseInt('g')\nlet longitudUndefined = undefined\nlet estructuraBaseErronea = {}\n\nfunction crear(tipo, longitud, estructuraBase) {\n  try { \n    if (tipo !== 'array') throw new TipoDeDatoErroneo \n    if (isNaN(longitud) || longitud < 0 || longitud === undefined) new Array(-1) // RangeError\n    estructuraBase.push() // TypeError\n    console.log('No ha ocurrido ningún error')\n  } \n  catch (e) { \n    console.log(e.name)\n  } finally {\n    return 'La ejecución ha finalizado'\n  }\n}\n\n// ejecución sin errores\nconsole.log(crear(tipoDato, longitud, estructuraBase))\n\n// ejecución con error propio\nconsole.log(crear(tipoDatoErroneo, longitud, estructuraBase))\n\n// ejecuciones con RangeError\nconsole.log(crear(tipoDato, longitudErronea, estructuraBase))\nconsole.log(crear(tipoDato, longitudNaN, estructuraBase))\nconsole.log(crear(tipoDato, longitudUndefined, estructuraBase))\n\n// ejecución con TypeError  \nconsole.log(crear(tipoDato, longitud, estructuraBaseErronea))"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/javascript/qwik-zgheib.js",
    "content": "/* -- exercise */\ntry {\n  let result = 10 / 0;\n  console.log(\"Result:\", result);\n} catch (error) {\n  console.error(\"Error:\", error.message);\n} finally {\n  console.log(\"Finished\");\n}\n\ntry {\n  let list = [1, 2, 3];\n  console.log(list[5]);\n} catch (error) {\n  console.error(\"Error:\", error.message);\n} finally {\n  console.log(\"Finished\");\n}\n\n/* -- extra challenge */\nfunction processParameters(parameter) {\n  try {\n    if (typeof parameter !== \"number\") throw new TypeError(\"Parameter must be a number\");\n\n    if (parameter === 0) throw new RangeError(\"Parameter cannot be zero\");\n\n    throw new Error(\"This is a custom error\");\n  } catch (error) {\n    console.error(\"Error:\", error.message);\n  } finally {\n    console.log(\"Finished\");\n  }\n}\n\nconsole.log(\"\\nProcessing parameters:\");\nprocessParameters(5);\nprocessParameters(0);\nprocessParameters(\"text\");\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/javascript/raulG91.js",
    "content": "\ntry{    \n   myFunctionUndefined()\n}catch(error){\n    console.log(\"There is an error\")\n    console.log(error.name)\n}\n\nclass CustomError extends Error{\n\n    constructor(){\n\n        super(\"Custom message\");\n    \n    }\n}\n\n\nfunction myFunction(param1,param2){\n    if(param1 <= 3){\n        throw new CustomError();\n    }\n    else if (typeof(param2)!= \"number\"){\n        throw TypeError(\"Int was expected\");  \n    }\n    else if(param2>= 6){\n        throw Error(\"Value bigger than 6\");\n    }\n}\n\ntry{\n        //myFunction(1,4);\n        //myFunction(8,\"ed\");\n        myFunction(8,16);\n\n}catch(err){\n\n    console.log(\"Exception name \", err.name);\n    console.log(\"Exception message \", err.message);\n}\n\nconsole.log(\"Execution finished \")"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/javascript/saicobys.js",
    "content": "/* Manejo de Excepciones */\n\ntry {\n  let resultado = 10 / 0;\n} catch (error) {\n  console.error(\"Error:\", error.message);\n} finally {\n  console.log(\"La ejecucion ha finalizado\");\n}\n\n/* Forzando errores */\n\ntry {\n  let lista = [1, 2, 3];\n  console.log(lista[5]);\n} catch (error) {\n  console.error(\"Error:\", error.message);\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/javascript/seandsun.js",
    "content": "/*\n<-------------- Manejo de excepciones -------------->\nSi no se atrapan los errores en nuestro código, lo que pasará es que el script se morirá inmediatamente e imprimirá un mensaje\ncon el error \"por consola\". Pero, si se atrapa el error con un bloque conocido como \"try\" (intentar) \"catch\" (atrapar), en lugar\nde que el script muera de manera inesperada y solo muestre el error por consola, se puede hacer algo más razonable como por ejemplo,\nmostrar un mensaje que pueda indicar de una manera más clara qué fue lo qué pasó y cómo podría solucionarse.\nEL bloque try...catch permite atrapar errores en \"tiempo de ejecución\".\n*/\n\n// Sintaxis de try...catch\n\ntry {\n\n    // código o script a ejecutar\n\n} catch (err) {  // \"err\" es la variable que va a contener el error, puede tener un nombre diferente a \"err\"\n\n    // manipulación del error\n\n} finally {\n\n    // Este bloque se ejecuta siempre, ponerlo es opcional\n}\n\n\n// Ejecución sin errores\n\ntry {    // Si el try no contiene ningún error, se ignora el catch\n\n    console.log('Hola, no tengo errores.')\n\n    // No hay ningún error\n\n    console.log('Fin de la ejecución del try.')\n\n} catch (err) {   // Si el try contiene algún error, el catch pasa a gestionar el error\n\n    console.log(`El error en el escript es: ${err}`)\n\n}\n\n// Ejecución con errores\n\ntry {   \n\n    console.log(\"Hola, sí tengo errores.\")\n\n    holaLola  // Error, variable no definida\n    \n    console.log('Fin de la ejecución del try (No se llegó hasta aquí).')\n\n} catch (err) {  \n\n    console.log(`El error en el escript es: ${err}`)\n\n    // Propiedades principales del objeto \"err\":\n    console.log(err.name)     // Nombre del error, por ejemplo: ReferenceError\n    console.log(err.message)  // Mensaje con detalles del error\n    console.log(err.stack)    // Pilla de llamadas actual\n\n}\nconsole.log('El error fue atrapado en catch y yo pude ser impreso en consola, sin el try...catch el script se hubiera detenido antes de llegar a mí.')\n\n\n// Operación 10/0 = Infinity\n\nfunction dividirPorCero(x,y) {\n    return x/y\n}\n\ntry {\n\n    let resultado =  dividirPorCero(10,0)\n    console.log(resultado)  // Infinity\n\n\n    if(resultado === Infinity) {\n        throw new Error(`La división no tiene solución, no puede dividir entre 0.`) // Error personalizado: este mensaje es el que va a imprimir \"err\"\n    }\n\n    console.log('No me ejecuto porque el throw actúa como un return que salta directamente al catch.')\n\n} catch (err) {\n    \n    console.log(`Throw me dice: ${err.message}`)\n    \n}\n\n\n// <-------------- Extra -------------->\n\nfunction excepciones(param1, param2) {\n    try {\n        \n        if(param1 === undefined || param2 === undefined) {\n            throw new ReferenceError('variable no definida')\n        }\n\n        if(typeof param1 !== 'number' || typeof param2 !== 'number') {\n            throw new TypeError('tipo de dato incorrecto, ambos datos deben ser números')\n        }\n\n        if (param1 > 100 || param2 > 100 ) {\n            throw new Error('Los valores deben ser números menores a 100')\n        }\n    \n        console.log('No se ha producido ningún error.')\n\n    } catch (err) {\n    \n        if(err instanceof ReferenceError) {\n            console.log(err.name)\n            console.log(err.message)\n        } else if(err instanceof TypeError) {\n            console.log(err.name)\n            console.log(err.message)\n        } else {\n            console.log(err.name)\n            console.log(err.message)\n        }\n    \n        \n    } finally {\n    \n        console.log('La ejecución ha finalizado.')\n    \n    }\n}\n\nexcepciones(50)         // variable no definida\nexcepciones(50, 'diez') // tipo de dato incorrecto, ambos datos deben ser números\nexcepciones(50, 101)    // Los valores deben ser números menores a 100\nexcepciones(50, 10)     // No se ha producido ningún error"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/javascript/victor-Casta.js",
    "content": "//Ejercicio\ntry {\n  connect.mongodb()\n} catch(error) {\n  console.log(error)\n} finally {\n  console.log('saliendo..')\n}\nconsole.log('hola fuera del error')\n\nclass MiErrorPersonalizado extends Error {\n  constructor(mensaje) {\n    super(mensaje);\n    this.name = this.constructor.name;\n  }\n}\n\n//Ejercicio extra\nfunction procesarParametros(parametro) {\n  try {\n    // Verificar si el parámetro es un número\n    if (typeof parametro !== 'number') {\n      throw new TypeError('El parámetro debe ser un número');\n    }\n\n    // Verificar si el parámetro es negativo\n    if (parametro < 0) {\n      throw new RangeError('El parámetro no puede ser negativo');\n    }\n\n    // Lanzar una excepción personalizada manualmente\n    if (parametro === 42) {\n      throw new MiErrorPersonalizado('El parámetro no puede ser 42');\n    }\n\n    // Si no hay errores, imprimir el parámetro\n    console.log('El parámetro es:', parametro);\n    console.log('No se ha producido ningún error');\n\n  } catch (error) {\n    // Capturar y manejar todas las excepciones\n    console.error('Tipo de error:', error.constructor.name);\n    console.error('Mensaje de error:', error.message);\n  } finally {\n    // Imprimir que la ejecución ha finalizado\n    console.log('La ejecución ha finalizado');\n  }\n}\n\n// Ejemplo de llamada a la función con diferentes parámetros\nconsole.log('--- Ejemplo 1 ---');\nprocesarParametros(10); // Sin errores\nconsole.log('--- Ejemplo 2 ---');\nprocesarParametros(-5); // Lanza un RangeError\nconsole.log('--- Ejemplo 3 ---');\nprocesarParametros('texto'); // Lanza un TypeError\nconsole.log('--- Ejemplo 4 ---');\nprocesarParametros(42); // Lanza un MiErrorPersonalizado\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/javascript/wapastorv.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n*/\n/*  Manejo de excepciones en JavaScript:\n    JavaScript tiene un mecanismo de manejo de excepciones que permite\n    capturar errores y manejarlos de forma controlada. Para ello, se\n    utiliza la estructura try-catch-finally, que permite intentar\n    ejecutar un bloque de código, capturar cualquier excepción que\n    se produzca y ejecutar un bloque de código adicional. Por ejemplo:\n*/\nfunction dividir(a, b) {\n    // Intentamos dividir a por b\n    try {\n        var resultado = a / b;\n        console.log('Resultado:', resultado);\n    }\n    catch (error) {\n        // Capturamos cualquier excepción que se produzca\n        console.error('Error:', error);\n    }\n    finally {\n        // Este bloque se ejecuta siempre, haya o no excepciones\n        console.log('Fin de la función');\n    }\n}\n\n// Probamos la función con distintos valores\ndividir(10, 2); // Resultado: 5\ndividir(10, 0); // Error: Infinity\ndividir(10, 'a'); // Error: NaN\ndividir(10); // Error: NaN\ndividir(); // Error: NaN\ndividir(10, 2, 3); // Error: NaN\n// Ejmeplo sin el uso de excepciones\nfunction dividirSinExcepciones(a, b) {\n    if (b === 0) {\n        console.error('Error: División por cero');\n        return;\n    }\n    var resultado = a / b;\n    console.log('Resultado:', resultado);\n    console.log('Fin de la función');\n}\n\n// Probamos la función con distintos valores\ndividirSinExcepciones(10, 2); // Resultado: 5\ndividirSinExcepciones(10, 0); // Error: División por cero\ndividirSinExcepciones(10, 'a'); // Resultado: NaN\n\n/*  En este caso, al intentar dividir 10 por 0, se produce una excepción\n    de tipo \"Infinity\". Esta excepción es capturada por el bloque catch,\n    que imprime un mensaje de error. A continuación, se ejecuta el bloque\n    finally, que imprime un mensaje de fin de programa. De esta forma,\n    el programa no se detiene de forma inesperada y podemos controlar\n    el flujo de ejecución. \n*/\n\n/* DIFICULTAD EXTRA (opcional):\n* Crea una función que sea capaz de procesar parámetros, pero que también\n* pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n* corresponderse con un tipo de excepción creada por nosotros de manera\n* personalizada, y debe ser lanzada de manera manual) en caso de error.\n* - Captura todas las excepciones desde el lugar donde llamas a la función.\n* - Imprime el tipo de error.\n* - Imprime si no se ha producido ningún error.\n* - Imprime que la ejecución ha finalizado. \n*/\n\nfunction procesarParametros(param1, param2) {\n    try {\n        if (param1 === undefined || param2 === undefined) {\n            throw new Error('Error: Parámetros indefinidos');\n        }\n        if (isNaN(param1) || isNaN(param2)) {\n            throw new Error('Error: Parámetros no numéricos');\n        }\n        if (param1 === 0 || param2 === 0) {\n            throw new Error('Error: División por cero');\n        }\n        var resultado = param1 / param2;\n        console.log('Resultado:', resultado);\n    }\n    catch (error) {\n        console.error('Error:', error.message);\n    }\n    finally {\n        console.log('Fin de la función');\n    }\n}\n\n// Probamos la función con distintos valores\nprocesarParametros(10, 2); // Resultado: 5\nprocesarParametros(10, 0); // Error: División por cero\nprocesarParametros(10, 'a'); // Error: Parámetros no numéricos\nprocesarParametros(10); // Error: Parámetros indefinidos\nprocesarParametros(); // Error: Parámetros indefinidos\nprocesarParametros(10, 2, 3); // Resultado: 5\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/kotlin/VincentRodriguezR.kt",
    "content": "import java.lang.IllegalArgumentException\n\nopen class exceptions(var numero1: Int) {\n    open fun excep() {\n        //Manejo de errores, try, catch, finally\n\n        //en try se definen las instrucciones que se controlaran\n        try {\n            var numero2 = 0\n            var resultado = numero1 / numero2\n            //En catch se dedefinen las instrucciones a ejecutar en caso de excepcion, se puede controlar una serie de instrucciones por tipo de excepcion, o si se desean manejar todas las excepciones se puede dejar \"Exception\"\n        } catch (excep: ArithmeticException) {\n            println(\"(Mensaje especifico por tipo de error)No es posible realizar la division, no se puede dividir un numero entre 0, error -> $excep\")\n            //Es posible almacenar el mensaje de error mediante el parametro definido en el catch, en este caso es llamado \"excep\"\n        } catch (excep: Exception) {\n            println(\"(Mensaje  general para todas las excepciones)No es posible realizar la division, no se puede dividir un numero entre 0, error -> $excep\")\n            //Es posible definir varios catch con diferentes tipos de excepciones por si se desea controlarlos de forma diferente dependiendo del tipo de excepcion, pero se ejecutara el primer catch que cumpla con el tipo de error\n            //En este caso se ejecutara el anterior, este no se lograra ejecutar\n        } finally {\n            println(\"Las instrucciones definidas en finally se ejecutan independientemente de si hubo un error o no\")\n        }\n\n        //Ceracion de excepciones propias\n        //El primer paso es crear una calse que herede de la clase Exceptions o de la clase de la excepcion especifica que necesitemos\n        class excepcionPropia(mensaje: String) : Exception(mensaje) {\n            fun showCustom() {\n                println(\"Este es un mensaje personalizado de la excepcion personalizada\")\n            }\n        }\n\n        //try - catch con la excepcion personalizada\n        try {\n            println(\"Prueba de manejo de excepcion personalziada\")\n            //Con throw se puede generar el error si o si independientemente si las sentecias ejecutadas no lo generan, despues del throw se debe colocar el tipo de excepcion y el mensaje que rebotara, en este caso uso la excepcion creada\n            throw excepcionPropia(\"Mensaje controaldo desde excepcion personalizada\")\n        } catch (excep: excepcionPropia) {\n            println(\"A continuacion se mostrara un mensaje de ejemplo que viene desde la excepcion personalizada, se genera el siguiente mensaje de error desde la excepcion personalizada -> $excep\")\n            excep.showCustom()\n        }\n    }\n}\n\n//Ejercicio Extra\nclass customException(message: String): IllegalArgumentException(message) {\n    fun showCustomMessage() {\n        println(\"Se ha producido un error, este error se personaliza tomando como base el tipo de excepcion -> NumberFormatException\")\n    }\n}\n\nfun div(num1: Int?, num2: Int?): Int {\n\n    if(num1 == 0 || num2 == 0){\n        throw ArithmeticException()\n    }else if(num1 == null || num2 == null){\n        throw NullPointerException()\n    }else if(num1 <0 || num2  <0){\n        throw customException(message = \"IllegalArgumentException generado de forma personalizada\")\n    }else{\n        return num1/num2\n    }\n\n}\n\nfun main() {\n    var excepciones = exceptions(100)\n    excepciones.excep()\n\n    //Extra excution\n    var res = 0\n    try{\n        res = div(1, 1)\n    }catch(excep: ArithmeticException){\n        println(\"Se ha producido un error de tipo aritmetico, el error producido fue -> $excep\")\n    }catch(excep: NullPointerException){\n        println(\"Se ha producido un error al enviar un nulo, el error producido fue -> $excep\")\n    }catch(excep: customException){\n        println(\"Se ha producido un error al enviar un string, el error producido fue -> $excep\")\n    }finally {\n        println(\"Ejecuciones con exito\")\n    }\n\n    if (res != 0){\n        println(\"No han habido errores\")\n    }\n}"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/kotlin/blackriper.kt",
    "content": "\r\n/*\r\n los Exception son una opcion de manejo de error que se puede producir en un programa\r\n esto nos ayuda a capturar el error para saber posibles causas y poder solucionarlo asi\r\n como saber que acciones reaizar cuando se produce el mismo.\r\n\r\n En kotlin  todas las excepciones son una subclase de la clase Throwable, cada excepcion\r\n contine  un mensaje que describe la excepcion  un stackTrace  y un opcional cause.\r\n\r\n ejemplo de manejo de excepciones\r\n        try {\r\n            // some code\r\n        } catch (e: SomeException) {\r\n            // handler\r\n        } finally {\r\n            // optional finally block\r\n        }\r\npara crear una excepcion se crear una clase  de la clase Exception\r\nclass MyException(message: String) : Exception(message)\r\n\r\n */\r\n\r\nfun exception() {\r\n    try {\r\n        val c = 10 / 0\r\n    } catch (e: Exception) {\r\n        println(\"Error: ${e.message}\")\r\n    }\r\n}\r\n\r\nfun exceptionWithSpecificCause() {\r\n    try {\r\n        val c = 10 / 0\r\n    } catch (e: ArithmeticException) {\r\n        println(\"Error: ${e.message}\")\r\n    }\r\n}\r\n\r\nfun exceptionWithCustomError(){\r\n    try {\r\n        val c = 10 / 0\r\n    } catch (e: ArithmeticException) {\r\n       println( Error(\"Division by zero is invalid\").message)\r\n    }\r\n}\r\n// ejercicio extra\r\n\r\nfun parseInt(s:String?){\r\n   try {\r\n       val n=notNull(s)\r\n       println(\"No errors detected\")\r\n       println(\"The number is ${n.toInt()}\")\r\n   }catch (e:NumberNullException){\r\n       println(e.message)\r\n   }catch (e: NumberFormatException){\r\n       println(e.message)\r\n   }catch (e:ClassCastException){\r\n       println(e.message)\r\n\r\n   }finally {\r\n       println(\"Execution finished\")\r\n   }\r\n\r\n}\r\n\r\nfun notNull(s:String?):String{\r\n    if (s== null){\r\n        throw NumberNullException(\"s is null\")\r\n    }\r\n    return s\r\n}\r\n\r\nclass NumberNullException(message: String) : Exception(message)\r\n\r\n\r\nfun main() {\r\n    // ejemplo de manejo de excepciones\r\n    exception()\r\n    exceptionWithSpecificCause()\r\n    exceptionWithCustomError()\r\n    //ejercicio extra\r\n    println(\"Prueba 1\")\r\n    parseInt(\"10\")\r\n    println(\"Prueba 2\")\r\n    parseInt(null)\r\n\r\n}"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/kotlin/didacdev.kt",
    "content": "class MyException(message: String): Exception(message)\n\nfun divideBy(numbers: List<Int>, divisor: Int, size: Int) {\n    require(numbers.size != 0) { throw MyException(\"The list is empty\")}\n    require(divisor != 0) { \"El divisor no puede ser cero\" }\n    require(numbers.size == size) { \"El tamaño de la lista no es el esperado\" }\n\n    for (index in 0 until size) {\n        println(numbers[index] / divisor)\n    }\n\n    println(\"No error found\")\n}\n\nfun main() {\n    try {\n        divideBy(listOf(1, 2, 3), 2, 3)\n    } catch(e: MyException) {\n        println(\"${e.message}\")\n    } catch(e: Exception) {\n        println(\"Error $e\")\n    } finally {\n        print(\"Ejecución finalizada\")\n    }\n}"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/kotlin/eulogioep.kt",
    "content": "// Excepción personalizada\nclass MiExcepcionPersonalizada(message: String) : Exception(message)\n\nfun funcionConExcepciones(numero: Int) {\n    when {\n        numero < 0 -> throw IllegalArgumentException(\"El número no puede ser negativo\")\n        numero == 0 -> throw ArithmeticException(\"No se puede dividir por cero\")\n        numero > 100 -> throw MiExcepcionPersonalizada(\"El número es demasiado grande\")\n        else -> println(\"El resultado de 100 / $numero es: ${100 / numero}\")\n    }\n}\n\nfun main() {\n    // Ejercicio principal: Manejo de excepciones básico\n    println(\"Ejercicio principal:\")\n    try {\n        val resultado = 10 / 0\n        println(resultado)\n    } catch (e: ArithmeticException) {\n        println(\"Error capturado: ${e.message}\")\n    }\n\n    val lista = listOf(1, 2, 3)\n    try {\n        val elemento = lista[5]\n        println(elemento)\n    } catch (e: IndexOutOfBoundsException) {\n        println(\"Error capturado: ${e.message}\")\n    }\n\n    // Dificultad extra: Función con múltiples excepciones\n    println(\"\\nDificultad extra:\")\n    val numeros = listOf(-5, 0, 50, 150)\n\n    for (numero in numeros) {\n        try {\n            println(\"Procesando el número: $numero\")\n            funcionConExcepciones(numero)\n            println(\"No se ha producido ningún error para el número $numero\")\n        } catch (e: IllegalArgumentException) {\n            println(\"Error capturado (IllegalArgumentException): ${e.message}\")\n        } catch (e: ArithmeticException) {\n            println(\"Error capturado (ArithmeticException): ${e.message}\")\n        } catch (e: MiExcepcionPersonalizada) {\n            println(\"Error capturado (MiExcepcionPersonalizada): ${e.message}\")\n        } finally {\n            println(\"La ejecución ha finalizado para el número $numero\")\n            println()\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/kotlin/rikmij.kt",
    "content": "class NoInputError(error: String): Exception(error)\n\nfun calculator(n1: Int, n2: Int) {\n    println(\"Tienes los números $n1 y $n2. ¿Qué quieres hacer con ellos?\")\n    println(\"1.- Sumar\\n\" +\n            \"2.- Restar\\n\" +\n            \"3.- Multiplicar\\n\" +\n            \"4.- Dividir\")\n\n    val input = readln()\n\n    try {\n        if (input == \"\"){\n            throw NoInputError(\"Debes ingresar algo\")\n        }\n        val choose = input.toInt()\n        when (choose){\n            1 -> println(n1 + n2)\n            2 -> println(n1 - n2)\n            3 -> println(n1 * n2)\n            4 -> println(n1 / n2)\n            else -> println(\"Este número está fuera del rango. Ingrese un número del 1 al 4\")\n        }\n        println(\"Felicidades, no ha habido ningún error\")\n        \n    }catch (e: ArithmeticException){\n        println(\"Ha habido un fallo con las operaciones. Recuerda que no se puede dividire entre 0\")\n    }\n    catch (e: NoInputError){\n        println(\"No has introducido nada. Debes introducir algo\")\n    }\n    catch (e: NumberFormatException) {\n        println(\"Ingresa un número\")\n    }\n    finally {\n        println(\"Hasta aquí llegó el programa\")\n    }\n}\n\n\nfun main() {\n    try {\n        println(10 / 0)\n    } catch (e: ArithmeticException) {\n        println(\"Estás intentando dividir entre cero. No se puede\")\n    }\n\n    try {\n        val lista = listOf(1, 2, 3, 4)\n        println(lista[5])\n    } catch (e: ArrayIndexOutOfBoundsException){\n        println(\"Esta lista no tiene tantos elementos\")\n    }\n\n    println(\"${\"\\n\" + \"~\".repeat(7)} EJERCICIO EXTRA ${\"~\".repeat(7)}\")\n    calculator(21, 7)\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/ocaml/luishendrix92.ml",
    "content": "open Printf;;\n\nRandom.self_init ()\n\n(*--------------------------------------------------------------------------------------\\\n  |                                                                                     |\n  |                             Error Handling - Exceptions                             |\n  |                                                                                     |\n  |  When evaluation an expression, OCaml may throw pre-defined exceptions matching     |\n  |  the type of failure that happened. Exceptions can also be defined by the user      |\n  |  and they may or may not have a value (of any type) attached to it which serves     |\n  |  as an information provider for the programmer; to let them know what went wrong.   |\n  |    The standard library comes with a small set of exceptions, including a generic   |\n  |  one called [Failure] that can be conveniently thrown with [failwith \"Message\"].    |\n  |  The full set includes the following exceptions and how you may encounter them:     |\n  |                                                                                     |\n  |  - [Failure]: Generic error with great convenience. Carries a [string].             |\n  |  - [Invalid_argument]: Used for invariance checking, meaning, prevents the user     |\n  |    of an API to pass an invalid argument that may produce an undesired result.      |\n  |    Carries a [string], a message to tell the user why the argument is invalid.      |\n  |  - [Not_found]: Thrown when an element we're trying to find in a data structure     |\n  |    is not present. For example, trying to find an element [elt] in an ['a list].    |\n  |  - [Match_failure]: Raised when failing a pattern match in a [match] expression.    |\n  |    Provides a thruple with the file, row, and column of where it happened.          |\n  |    This also only happens if your [match] expressions are non-exhaustive.           |\n  |  - [Sys_error]: Raised during IO operations within the Sys module, such as a        |\n  |    file we're trying to read not existing. Provides a [string] with details.        |\n  |  - [End_of_file]: This is more of a signal than an error, it tells us when we       |\n  |    reached the end of a buffer during an [stdin] read operation.                    |\n  |  - [Division_by_zero]: Integer division by zero raises this, but float division by  |\n  |    zero will yield [infinity] which is of type [float].                             |\n  |  - [Sys_blocked_io]: Raised when a system IO operation is blocked.                  |\n  |  - [Assert_failure]: This is one of the most useful ones, it is the foundation of   |\n  |    testing libraries. It gives us a thruple containing the file, row, and column    |\n  |    where the assertion failure happened. The only way to raise this exception is    |\n  |    through the [assert] expression (it's not technically a function), for example:  |\n  |    [assert false] will raise the exception, but [assert true] won't.                |\n  |  - [Stack_overflow]: Raised when the call-stack is full and the program tries to    |\n  |    push another stack frame (function calls). Happens a lot during recursion.       |\n  |                                                                                     |\n  \\-------------------------------------------------------------------------------------*)\n\nlet () =\n  let sky = \"red\" in\n  try assert (sky = \"blue\") with\n  | Assert_failure (file, line, col) ->\n    printf \"The sky is not blue, it's %s; but who asked?\\n\" sky;\n    printf \"%s did! Where? On line %d and column %d!\\n\" file line col\n;;\n\nlet div_by_zero n =\n  printf \"%d / 0 = \" n;\n  let division = n / 0 in\n  printf \"%d\\n\" division\n;;\n\n(* Output: 10 / 0 = Fatal error: exception Division_by_zero. *)\n(* let () = div_by_zero 10 *)\n\n(* Output: [1,2,3,4][4] = Fatal error: exception\n   Invalid_argument(\"index out of bounds\") *)\n(* let () = *)\n(*   printf \"[1,2,3,4][4] = \"; *)\n(*   let x = Array.get [| 1; 2; 3; 4 |] 4 in *)\n(*   printf \"%d\\n\" x *)\n(* ;; *)\n\n(* A cool feature of OCaml is that exceptions can also be pattern-matched. *)\nlet () =\n  match 5 / 0 with\n  | 0 -> print_endline \"Division by zero? It's just zero :D\"\n  | exception Division_by_zero ->\n    print_endline \"We can't divide by zero? Meh...\"\n  | _ -> print_endline \"Doesn't really matter anyway!\"\n;;\n\n(* The try/with block happens to be an expression, which evaluates to a value.\n   Obviously the [unit] or [()] is also a value but means we just executed a\n   side-effect. This expression does not come with a [finally] clause but it\n   can be achieved by writing some code after the try/with expression.\n\n   There is a pattern in idiomatic OCaml that kept appearing, thus giving birth\n   to the function [Fun.protect] in the standard library. This function runs an\n   imperative function (that returns a value) and regardless of whether this\n   function raised an exception or not, it executes an imperative function\n   (that returns [unit]). It's very useful for resource cleanup. *)\nlet () =\n  let open_db_conn () = print_endline \"Db is connected, ready for queries...\" in\n  let close_db_conn () = print_endline \"Db is closed, goodbye user...\" in\n  let query_that_maybe_fails i =\n    if Random.int 10 < 5\n    then failwith \"Db query failed unexpectedly!\"\n    else printf \"Db query #%d result: %d\\n\" i (Random.int 100)\n  in\n  try\n    open_db_conn ();\n    (* Behind the scenes, [~finally] is run before the value is returned or\n       an exception that happened is re-raised for the user to handle. *)\n    Fun.protect ~finally:close_db_conn (fun () ->\n      for i = 1 to 10 do\n        query_that_maybe_fails i\n      done)\n  with\n  | Failure msg -> print_endline msg\n;;\n\n(*--------------------------------------------------------------------------------------\\\n  |                                                                                     |\n  |                             Dificultad Extra (opcional)                             |\n  |                                                                                     |\n  |  Crea una función que sea capaz de procesar parámetros, pero que también pueda      |\n  |  lanzar 3 tipos diferentes de excepciones (una de ellas tiene que corresponderse    |\n  |  con un tipo de excepción creada por nosotros de manera personalizada, y debe ser   |\n  |  lanzada de manera manual) en caso de error.                                        |\n  |                                                                                     |\n  |  - Captura todas las excepciones desde el lugar donde llamas a la función.          |\n  |  - Imprime el tipo de error.                                                        |\n  |  - Imprime si no se ha producido ningún error.                                      |\n  |  - Imprime que la ejecución ha finalizado.                                          |\n  |                                                                                     |\n  \\-------------------------------------------------------------------------------------*)\n\nexception Blacklisted of string\n\nlet join_dev_club name age =\n  assert (age >= 21);\n  let blacklist = [ \"Aria Richards\"; \"Douglas Crockford\"; \"Terry Davis\" ] in\n  if name = \"\"\n  then raise (Invalid_argument \"Name must not be an empty string.\")\n  else if List.mem name blacklist\n  then raise @@ Blacklisted (name ^ \" is blacklisted from our club.\")\n  else printf \"Welcome to the dev club, %s :)\\n\" name\n;;\n\nlet try_to_join name age =\n  print_endline \"--------------------\";\n  print_endline \"Execution started.\";\n  begin\n    try\n      (* Alternative version:\n\n         {[\n           Fun.protect\n             ~finally:(fun () -> print_endline \"Execution finalized\")\n             (fun () ->\n               join_dev_club name age;\n               print_endline \"No exceptions were thrown!\")\n         ]}\n      *)\n      join_dev_club name age;\n      print_endline \"No exceptions were thrown!\"\n    with\n    | Assert_failure _ ->\n      print_endline\n        \"Exception of type [Assert_failure] was thrown because [age] is NOT \\\n         [>= 21]. Not old enough to join!\"\n    | Invalid_argument msg ->\n      printf\n        \"Exception of type [Invalid_argument] was thrown with message [%s].\\n\"\n        msg\n    | Blacklisted msg ->\n      printf\n        \"Exception of type [Blacklisted] (custom) was thrown with message [%s].\\n\"\n        msg\n  end;\n  print_endline \"Execution finalized.\"\n;;\n\nlet () =\n  try_to_join \"\" 35;\n  try_to_join \"Luis\" 18;\n  try_to_join \"Aria Richards\" 43;\n  try_to_join \"Brais Moure\" 38\n;;\n\n(* Output of [dune exec reto10]:\n\n   The sky is not blue, it's red; but who asked?\n   bin/reto10.ml did! Where? On line 45 and column 6!\n   We can't divide by zero? Meh...\n   Db is connected, ready for queries...\n   Db is closed, goodbye user...\n   Db query failed unexpectedly!\n   --------------------\n   Execution started.\n   Exception of type [Invalid_argument] was thrown with message [Name must not be an empty string.].\n   Execution finalized.\n   --------------------\n   Execution started.\n   Exception of type [Assert_failure] was thrown because [age] is NOT [>= 21]. Not old enough to join!\n   Execution finalized.\n   --------------------\n   Execution started.\n   Exception of type [Blacklisted] (custom) was thrown with message [Aria Richards is blacklisted from our club.].\n   Execution finalized.\n   --------------------\n   Execution started.\n   Welcome to the dev club, Brais Moure :)\n   No exceptions were thrown!\n   Execution finalized.\n*)\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/pascal/miguelex.pas",
    "content": "program miguelex;\n\n{$mode objfpc}\n\nuses \n  SysUtils;\n\nprocedure warning_handler(ErrNo: longint; const ErrStr: string);\nbegin\n  raise Exception.Create(ErrStr);\nend;\n\nfunction ejercicioExtra (nombre: string; reto: integer; lenguaje: string): string;\nvar\n  resultado: string;\nbegin\n  resultado := '';\n  try\n    if not (reto >= 0) then\n      raise Exception.Create('El número debe ser un entero positivo');\n\n    if lenguaje = '' then\n      raise Exception.Create('El lenguaje debe ser una cadena no vacía');\n\n    if nombre = 'Mouredev' then\n      raise Exception.Create('El nombre no puede ser Mouredev');\n\n    resultado := 'Solución reto # ' + IntToStr(reto) + ' - ' + lenguaje + ' del usuario ' + nombre + LineEnding;\n  except\n    on e: Exception do\n      resultado := 'Error: ' + e.Message + LineEnding;\n  end;\n  resultado := resultado + 'La ejecución ha finalizado' + LineEnding;\n  ejercicioExtra := resultado;\nend;\n\nvar\n  result: string;\nbegin\n  try\n    SetErrorHandler(@warning_handler);\n    try\n      result := '';\n      result := result + FloatToStr(10 / 0) + LineEnding;\n    except\n      on e: Exception do\n        result := result + e.Message + LineEnding;\n    end;\n    result := result + 'La ejecución ha finalizado' + LineEnding;\n    \n    try\n      SetLength(result, 0);\n      result := result + IntToStr([1, 2, 3][4]) + LineEnding;\n    except\n      on e: Exception do\n        result := result + 'Error: ' + e.Message + LineEnding;\n    end;\n    result := result + 'La ejecución ha finalizado' + LineEnding;\n    \n    Writeln(result);\n\n    Writeln('EJERCICIO EXTRA');\n    Writeln(ejercicioExtra('Miguelex', 10, 'Pascal'));\n    Writeln(ejercicioExtra('', -5, 'JavaScript'));\n    Writeln(ejercicioExtra('Miguelex', 2, ''));\n    Writeln(ejercicioExtra('Mouredev', 1, 'Python'));\n  finally\n    RestoreErrorHandler;\n  end;\nend.\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/php/eulogioep.php",
    "content": "<?php\n\n// Parte 1: Manejo básico de excepciones\n\n// Ejemplo 1: División por cero\ntry {\n    // Intentamos dividir por cero para forzar una excepción\n    $resultado = 10 / 0;\n} catch (DivisionByZeroError $e) {\n    echo \"Error aritmético: \" . $e->getMessage() . \"\\n\";\n}\n\n// Ejemplo 2: Acceso a índice no existente\ntry {\n    // Intentamos acceder a un índice no existente de un array\n    $array = [\"Elemento\"];\n    $elemento = $array[5];\n} catch (OutOfBoundsException $e) {\n    echo \"Error de acceso: \" . $e->getMessage() . \"\\n\";\n}\n\n// Parte 2: Función con múltiples excepciones (DIFICULTAD EXTRA)\n\n// Definimos nuestra excepción personalizada\nclass MiExcepcionPersonalizada extends Exception {}\n\n// Función que puede lanzar 3 tipos diferentes de excepciones\nfunction procesarParametro($parametro) {\n    if (!is_numeric($parametro)) {\n        throw new InvalidArgumentException(\"El parámetro debe ser un número\");\n    }\n    if ($parametro < 0) {\n        throw new RangeException(\"El parámetro no puede ser negativo\");\n    }\n    if ($parametro == 0) {\n        throw new DivisionByZeroError(\"No se puede dividir por cero\");\n    }\n    if ($parametro > 10) {\n        throw new MiExcepcionPersonalizada(\"El parámetro es demasiado grande\");\n    }\n\n    // Si no hay errores, realizamos alguna operación\n    $resultado = 100 / $parametro;\n    echo \"Resultado: $resultado\\n\";\n}\n\n// Función para probar procesarParametro\nfunction probarProcesarParametro($valor) {\n    try {\n        procesarParametro($valor);\n        echo \"No se ha producido ningún error.\\n\";\n    } catch (Exception $e) {\n        echo \"Tipo de error: \" . get_class($e) . \"\\n\";\n        echo \"Mensaje: \" . $e->getMessage() . \"\\n\";\n    } finally {\n        echo \"La ejecución ha finalizado.\\n\";\n    }\n    echo \"---\\n\";\n}\n\n// Probamos con diferentes valores\nprobarProcesarParametro(\"no es un número\");\nprobarProcesarParametro(-1);\nprobarProcesarParametro(0);\nprobarProcesarParametro(5);\nprobarProcesarParametro(15);\n\n?>"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/php/gabrielmoris.php",
    "content": "<?php\n/*\n* EXERCISE:\n* Explore the concept of exception handling according to your language.\n* Force an error in your code, capture the error, print the error\n* and prevent the program from stopping unexpectedly.\n* Try dividing \"10/0\" or accessing a non-existent index\n* of a list to try to cause an error.\n*/\n\n// I can Customice my error:\nclass CustomException extends Exception\n{\n    public function errorMessage()\n    {\n        //error message\n        $errorMsg = 'What happened here?? It seems that in line ' . $this->getLine() . ' in the file ' . $this->getFile()\n            . ': <b>' . $this->getMessage() . '</b> is not a valid E-Mail address' . \"\\n\";\n        return $errorMsg;\n    }\n}\n\n\n$email = \"someone@example...com\\n\";\n\ntry {\n    //check if\n    if (filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE) {\n        //throw exception if email is not valid\n        throw new CustomException($email);\n    }\n} catch (CustomException $e) {\n    //display custom message\n    echo $e->errorMessage();\n}\n\nfunction divide($numerator, $denominator)\n{\n    if ($denominator == 0) {\n        throw new Exception(\"An error occurred: Division by zero is not allowed.\\n\");\n    }\n    return $numerator / $denominator;\n}\n\ntry {\n    $infinite = divide(10, 0);\n} catch (Exception $e) {\n    $errorMessage = $e->getMessage();\n    echo $errorMessage;\n} finally {\n    // Code to be executed regardless of an exception\n    echo \"This code will always be executed.\\n\";\n}\n\n\n/* EXTRA DIFFICULTY (optional):\n* Create a function that can process parameters, but also\n* can throw 3 different types of exceptions (one of them has to\n* correspond to a custom exception type created by us\n* manually) in case of an error.\n* Capture all exceptions from where you call the function.\n* Print the type of error.\n* Print if no error has occurred.\n* Print that execution has finished.\n*/\n\nfunction error_processor($param1, $param2)\n{\n\n    if (!is_numeric($param1) || !is_numeric($param2)) {\n        throw new InvalidArgumentException((\"OOOOPS!\\n\"));\n    }\n\n    if ($param1 === $param2) {\n        throw new CustomException((\"Vaya vaya!\\n\"));\n    }\n\n    if ($param1 == 0 || $param2 == 0) {\n        throw new OutOfRangeException(\"Parameters cant be 0.\\n\");\n    }\n\n    return $param1 / $param2;\n}\n\ntry {\n    error_processor(1, 2);\n    error_processor(2, 2);\n} catch (InvalidArgumentException $e) {\n    echo \"InvalidArgumentException: \" . $e->getMessage() . \"\\n\";\n} catch (CustomException $e) {\n    echo \"CustomException: \" . $e->getMessage() . \"\\n\";\n} catch (OutOfRangeException $e) {\n    echo \"OutOfRangeException: \" . $e->getMessage() . \"\\n\";\n} finally {\n    echo \"Execution has finished.\\n\";\n}\n\ntry {\n    error_processor(0, 2);\n} catch (InvalidArgumentException $e) {\n    echo \"InvalidArgumentException: \" . $e->getMessage() . \"\\n\";\n} catch (CustomException $e) {\n    echo \"CustomException: \" . $e->getMessage() . \"\\n\";\n} catch (OutOfRangeException $e) {\n    echo \"OutOfRangeException: \" . $e->getMessage() . \"\\n\";\n} finally {\n    echo \"Execution has finished.\\n\";\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/php/miguelex.php",
    "content": "<?php\n\n/**********************************************/\n/*                  IMPORTANTE                */\n/* En php la división por cero no lanza una   */\n/* excepción, sino que muestra un warning.    */\n/* Para evitarlo se utiliza el manejador de   */\n/* errores set_error_handler()                */\n/**********************************************/\n\nset_error_handler(\"warning_handler\", E_WARNING);\n\nfunction warning_handler($errno, $errstr) { \n    throw new \\Exception($errstr, $errno);\n}\n\ntry {\n    $result = 10 / 0;\n    echo $result;\n} catch(Exception $e){\n    echo $e->getMessage().\"\\n\";\n} finally { \n    echo \"La ejecución ha finalizado\\n\";\n}\n\nrestore_error_handler();\n\ntry {\n    $array = [1, 2, 3];\n    echo $array[3];\n} catch (Error $error) {    \n    echo 'Error: ' . $error->getMessage().\"\\n\";\n} finally { \n    echo \"La ejecución ha finalizado\\n\";\n}\n\nclass MyException extends Exception{\n    public function __construct($message, $code = 0, Exception $previous = null) {\n        parent::__construct($message, $code, $previous);\n    }\n    public function __toString() {\n        return __CLASS__ . \": [{$this->code}]: {$this->message}\\n\";\n    }\n}\n\nfunction ejercicioExtra ($nombre, $reto, $lenguaje){\n    $resultado = \"\";\n    try {\n        if (!is_int($reto) || $reto < 0) {\n            throw new InvalidArgumentException(\"El número debe ser un entero positivo\");\n        }\n\n        if (!is_string($lenguaje) || empty($lenguaje)) {\n            throw new InvalidArgumentException(\"El lenguaje debe ser una cadena no vacía\");\n        }\n\n        if ($nombre == \"Mouredev\"){\n            throw new MyException(\"El nombre no puede ser Mouredev\");\n        }\n\n        $resultado = \"Solución reto # $reto - $lenguaje del usuario $nombre\\n\";\n    } catch (InvalidArgumentException $e) {\n        $resultado = \"Error: \" . $e->getMessage().\"\\n\";\n    } catch (Exception $e) {\n        $resultado = \"Error: \" . $e->getMessage().\"\\n\";\n    } catch (MyException $e) {\n        $resultado = \"Error: \" . $e->getMessage().\"\\n\";\n    } finally {\n        $resultado .= \"La ejecución ha finalizado\\n\";\n    }   \n    return $resultado;\n}\n\necho \"\\nEJERCICIO EXTRA\\n\";\necho ejercicioExtra(\"Miguelex\", 10, \"PHP\") . \"\\n\";\necho ejercicioExtra(\"\", -5, \"JavaScript\") . \"\\n\";\necho ejercicioExtra(\"Miguelex\", 2, \"\") . \"\\n\";\necho ejercicioExtra(\"Mouredev\", 1, \"Python\") . \"\\n\";\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/php/rxvlc.php",
    "content": "<?php\n\nfunction dividir($dividendo, $divisor) {\n    if ($divisor == 0) {\n        throw new Exception(\"División por cero\");\n    }\n    return $dividendo / $divisor;\n}\n\nfunction procesarParams($p1, $p2) {\n    try {\n        if (!is_int($p1) || !is_int($p2)) {\n            throw new InvalidArgumentException(\"Los parámetros no son números\");\n        } elseif ($p1 == 0 || $p2 == 0) {\n            throw new InvalidArgumentException(\"Los números son cero\");\n        } elseif ($p1 < 0 || $p2 < 0) {\n            throw new InvalidArgumentException(\"Alguno de los números es negativo\");\n        } else {\n            echo $p1 + $p2 . \"\\n\";\n            echo \"No se ha producido ningún error\\n\";\n        }\n    } catch (Exception $ex) {\n        echo \"Se ha producido un error: \" . $ex->getMessage() . \"\\n\";\n    } finally {\n        echo \"La ejecución ha finalizado\\n\";\n    }\n}\n\ntry {\n    $resultado = dividir(10, 0);\n    echo \"El resultado es: \" . $resultado . \"\\n\";\n} catch (Exception $ex) {\n    echo \"Error: \" . $ex->getMessage() . \"\\n\";\n} finally {\n    echo \"Finalizando programa...\\n\";\n}\n\n//Dificultad adicional:\nprocesarParams(1, 0); // Error parametro cero\nprocesarParams(-7, 7); // Error numero negativo\nprocesarParams(1, 1); // Suma normal sin error\n\n?>"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/php/yablik.php",
    "content": "<?php\n\ntry {\n    // Intenta dividir 10 por 0\n    $resultado = 10 / 0;\n} catch (DivisionByZeroError $e) {\n    // Captura la excepción y muestra el mensaje de error\n    echo \"Se produjo un error: \" . $e->getMessage() . \"\\n\";\n}\n\n// Función para manejar las advertencias como excepciones\nfunction manejarAdvertenciaComoExcepcion($errno, $errstr) {\n    throw new ErrorException($errstr, 0, $errno);\n}\n\n// Configurar el controlador de errores personalizado\nset_error_handler(\"manejarAdvertenciaComoExcepcion\");\n\ntry {\n    // Intenta acceder a un índice no existente en un array\n    $array = array(1, 2, 3);\n    $elemento = $array[5];\n} catch (ErrorException $e) {\n    // Captura la excepción y muestra el mensaje de error\n    echo \"Se produjo un error: \" . $e->getMessage() . \"\\n\";\n}\n\n\n//Dificultad extra\n\n// Define una excepción personalizada\nclass MiExcepcionPersonalizada extends Exception {\n    public function errorMessage() {\n        // Mensaje personalizado\n        return \"Error personalizado: \" . $this->getMessage() . \"\\n\";\n    }\n}\n\n// Función que procesa parámetros y puede lanzar excepciones\nfunction procesarParametros($parametro) {\n    if ($parametro == 0) {\n        throw new InvalidArgumentException(\"El parámetro no puede ser cero.\");\n    } elseif ($parametro < 0) {\n        throw new RuntimeException(\"El parámetro no puede ser negativo.\");\n    } elseif ($parametro > 100) {\n        throw new MiExcepcionPersonalizada(\"El parámetro excede el límite permitido.\");\n    }\n\n    return \"Procesamiento exitoso con el parámetro: $parametro\\n\";\n}\n\n// Llama a la función y captura todas las excepciones\ntry {\n    echo procesarParametros(50) . \"\\n\"; // Llamada exitosa\n} catch (Exception $e) {\n    echo \"Error capturado: \" . $e->getMessage() . \"\\n\";\n} \ntry {\n    echo procesarParametros(0) . \"\\n\";  // Lanzará una excepción de tipo InvalidArgumentException\n} catch (InvalidArgumentException $e) {\n    echo \"Error capturado: \" . $e->getMessage() . \"\\n\";\n}\ntry{\n    echo procesarParametros(-5) . \"\\n\"; // Lanzará una excepción de tipo RuntimeException\n} catch (RuntimeException $e) {\n    echo \"Error capturado: \" . $e->getMessage() . \"\\n\";\n}\ntry{\n    echo procesarParametros(150) . \"\\n\"; //Lanzará una excepción de tipo MiExcepcionPersonalizada\n    echo \"No se han producido errores.\\n\";\n} catch (MiExcepcionPersonalizada $e) {\n    echo \"Error capturado: \" . $e->errorMessage() . \"\\n\";\n}\nfinally {\n    echo \"La ejecución ha finalizado.\\n\";\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/59822.py",
    "content": "''' Try/ Except /Finally\n\n# Try / Except / Finally es una estructura que permite manejar errores \n# en tiempo de ejecución, es decir, cuando el programa ya está en ejecución.\n'''\n\ndef division(x: float, y: float):\n    return x / y\n\ntry:\n    resultado = division(10, 0)\n    print(resultado)\nexcept Exception as e:\n    print(f\"Error: {e}\")\nfinally:\n    print(\"Fin del programa\")\n    \n# Ejemplo\n# En este ejemplo se muestra como se puede manejar un error en tiempo de ejecución\n\ndef saludo(x : str):\n    return \"Hola \" + x\n\ntry:\n    hola = saludo(2)\n    print(hola)\nexcept Exception as e:\n    print(f\"Error: {e}\")\nfinally:\n    print(\"Fin del programa\")\n    \ndef contraseña(x: str):\n    if len(x) < 10:\n        raise ValueError(\"La contraseña debe tener más de 9 caracteres\")\n    \n''' Extra '''\nclass Ortography(Exception):\n    def __init__(self, text: str):\n        self.text = text\n        \ndef oracion(x: str):\n    if x[-1] != \".\":\n        raise Ortography(\"El texto no termina en punto\")\n    if (x.isnumeric):\n        raise Ortography(\"El texto no puede ser un número\")\n    if len(x) < 1:\n        raise Ortography(\"El texto no puede estar vacío\")\n    \ntry:\n    oracion(0/0)\nexcept Exception as e:\n    print(\"Revisar la info del problema\")\nfinally:\n    print(\"Fin del programa\")"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/AChapeton.py",
    "content": "myList = ['a', 'b', 'c', 'd']\n\n#  TRY - Bloque del codigo que se va a evaluar\n\n# EXCEPT - Bloque del codigo que se ejecuta si se encuentra un error en el bloque TRY\n\n# FINALLY - Bloque de codigo (opcional) que se va a ejecutar una vez haya terminado el bloque TRY, independientemente de su resultado\n\n# try:\n#   len(myList[8])\n# except:\n#   print('No se puede acceder a una posiocion que no existe en la lista')\n# finally:\n#   print('Ancho de la lista: ', len(myList))\n\n# try:\n#   result = 10 / 0\n#   print(result)\n# except:\n#   print('No se puede dividir entre 0')\n\n# DIFICULTAD EXTRA\n\nclass customException:\n  def __init__(self, name, message):\n    self.name = name\n    self.message = message\n\n  def showMessage(self):\n    print(f\"{self.name}: {self.message}\")\n\ndef myFunction(num1, num2):\n  try:\n    if(num1 <= 0):\n      print(\"El primer valor no puede ser menor o igual a cero.\")\n\n    if((num2 % 2) != 0):\n      print(\"El segundo valor debe ser un numero par.\")\n    \n    if((num1 + num2) > 99):\n      error = customException('Custom Error', \"La suma de los valores no puede sobrepasar de 100.\")\n      error.showMessage()\n  except:\n    print('Error general.')\n  finally:\n    print('Fin del ejercicio')\n  \nmyFunction(-1, 6)\nmyFunction(10, 5)\nmyFunction(51, 50)\nmyFunction(3, 6)"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/AlainMartz.py",
    "content": "#10 EXCEPCIONES\n\n\"\"\"\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n\"\"\"\n\n# Excepciones con ZeroError y TypeError\n\nclass aritmetica():\n    resultados = []\n    def __init__(self,a,b) -> None:\n        self.a = a\n        self.b = b\n\nclass srmd(aritmetica):\n    def __init__(self, a, b) -> None:\n        super().__init__(a, b)\n    \n    def suma(self):\n        sum = None\n        try:\n            sum = self.a + self.b\n        except TypeError:\n            print(f\"Error!!\\n{self.a}:{type(self.a)} != {self.b}: {type(self.b)}\")\n        finally:\n            print(sum)\n    \n    def resta(self):\n        try:\n            resta = self.a - self.b\n        except TypeError:\n            print(f\"Error!!\\n{self.a}:{type(self.a)} != {self.b}: {type(self.b)}\")\n            resta = None        \n        finally:\n            if resta is not None:\n                print(resta)\n            else:\n                print(\"No se pudo realizar la resta\")\n\n    def multipliacion(self):\n        try:\n            mult = self.a * self.b\n        except TypeError:\n            print(f\"Error!!\\n{self.a}:{type(self.a)} != {self.b}: {type(self.b)}\")\n        else:\n            print(mult)    \n\n    def division(self):\n        try:\n            div = self.a / self.b\n        except ZeroDivisionError:\n            print(\"No se puede dividir por cero\")\n        except TypeError:\n            print(f\"Error!!\\n{self.a}:{type(self.a)} != {self.b}: {type(self.b)}\")            \n        else:\n            print(div)\n            \n\nx = srmd(15,\"1\")\nx.suma()\nx.b = 13\nx.suma()\nx.resta()\nx.multipliacion()\nx.b = 0\nx.division()\nx.b = \"0\"\nx.division()\nx.b = 25\nx.division()\n\n\ndef factorialrec(n):\n    if n == 0 or n == 1:\n        return 1  # Casos base bien definidos\n    try:\n        result = n * factorialrec(n - 1)\n        return result\n    except TypeError:\n        print(\"Error entre tipos de datos, en algún punto la función opera un Int con un None\")\n        return None\n    except RecursionError:\n        print(\"Error de recursión: profundidad máxima excedida\")\n        return None\n# print(factorialrec(1000))\n\n\ndef factorialmult(n):\n    if n < 0:\n        raise ValueError(\"La función no está definido para valores negativos\")\n    if n == 0 or n == 1:\n        return 1\n    try:\n        fact = 1\n        for i in range(1, n + 1):\n            fact *= i\n        return fact\n    except OverflowError:\n        print(\"Se ha alcanzado el límite máximo de tamaño para el cálculo.\")\n        return None\n\ntry:\n    result = factorialmult(77777) \n    print(result)\nexcept ValueError:\n    print(\"Error de valores\")\n\n\ndef ove(n):\n    try:\n        lint = 10 ** n\n        result = float(lint)\n        print(result)\n    except OverflowError:\n        print(\"OverFlowError: El entero es muy grande para convertirlo en flotante\")\n \nove(308)\nove(309)\n\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado. \n\"\"\"\n\nclass Partexc(Exception):\n    def __init__(self, mensaje):\n        super().__init__(mensaje)\n        self.mensaje = mensaje\n\ndef sinceros(a, b):\n \n    # Calcula la suma de las raíces\n    add = a**(1/3) + b**(1/2)\n    if add == 0:\n        raise ValueError(\"El valor de la suma no puede ser Cero\")\n\n    # Realiza la división\n    div = (add + a) / b\n    if div == 0:\n        raise ZeroDivisionError(\"El valor no puede ser Cero\")\n\n    # Calcula la multiplicación\n    mult = add * div\n    if isinstance(mult, int) or mult.is_integer():\n        raise Partexc(\"Has alcanzado el error de dorado!!! ;D\")\n    \n    # Retorna los resultados formateados\n    return (\n        f\"Suma de {a}^(1/3) + {b}^(1/2): {round(add, 2)}\\n\"\n        f\"División de: (({round(add, 2)} + {a})/{b}): {round(div, 2)}\\n\"\n        f\"Multiplicación de: {round(add, 2)} * {round(div, 2)}: {round(mult, 2)}\"\n    )\n\n# Manejo de excepciones\ntry:\n    a = int(input(\"Ingrese un número: \"))\n    b = int(input(\"Ingrese el siguiente número: \"))\n    params = sinceros(a, b)\nexcept (ValueError, ZeroDivisionError, Partexc) as e:\n    print(f\"Error: {e}\")\nexcept Exception as e:\n    print(f\"Error inesperado: {e}\")\nelse:\n    print(params)\nfinally:\n    print(\"Ejecución finalizada.\")\n\n\n# from collections import Counter\n\n# def multi(a,b):\n#     add = a**(1/3) + b**(1/2)\n#     div = (add + a)/b\n#     mult = add * div\n\n#     return mult\n\n# for i in range(1,100):\n#     for j in range(1,100):\n#         result = []\n#         r =multi(i,j)\n\n#         if isinstance(r, int) or r.is_integer():\n#             result.append(r)\n        \n#         for a in range(len(result)):\n#             print(f\"{i} - {j} : {Counter(result)}\")\n\n        \n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/Aldroide.py",
    "content": "\"\"\" Excepciones\n    Prueba a dividir \"10/0\" o acceder a un índice no existente\n    de un listado para intentar provocar un error.\n\"\"\"\n\n# Capturar excepciones\na = 7\nb = 0\n\ntry:\n    100/0\nexcept:\n    print(\"Se produjo un error\")\n\n\ntry:\n    r = a/b\nexcept ZeroDivisionError:\n    print(\"Error no pudes divir entre cero.\")\nfinally:\n    print(\"Trata de nuevo\")\n\n\n\"\"\"\nEjercicio Extra\n\"\"\"\n\n\ndef procesar_errores(parametro):\n    try:\n        if parametro == 1:\n            raise ValueError(\"¡Este es un valor incorrecto!\")\n        elif parametro == 2:\n            raise IndexError(\"¡Índice fuera de rango!\")\n        else:\n            print(\"Parámetro válido:\", parametro)\n    except ValueError as error:\n        print(f\"Error: {error}\")\n    except IndexError as error:\n        print(f\"Error: {error}\")\n    else:\n        print(\"No se ha producido ningún error.\")\n    finally:\n        print(\"La ejecución ha finalizado.\")\n\n\n# Funcion\ntry:\n    procesar_errores(0)\n    procesar_errores(1)\n    procesar_errores(2)\nexcept Exception as e:\n    print(\"Tipo de error:\", type(e).__name__)\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/Aleran07.py",
    "content": "# 10\n\n# Manejo basico de excepciones\ntry:\n    x = 10 / 0\nexcept ZeroDivisionError:\n    print(\"No se puede dividir por cero.\")\n\n# Capturar cualquier tipo de error\ntry:\n    num = int(input(\"Ingresa un número: \"))\nexcept Exception as e:\n    print(\"Hubo un error:\", e)\n\n# Manejo con else\ntry:\n    x = 10 / 2\nexcept ZeroDivisionError:\n    print(\"Error\")\nelse: # solo se ejecuto si no hubo error\n    print(\"Todo salió bien, x es:\", x)\n\n# Manejo con finally\ntry:\n    archivo = open(\"test.txt\")\nexcept FileNotFoundError:\n    print(\"Archivo no encontrado\")\nfinally: # Siempre se ejecuta, haya error o no\n    print(\"Intento de abrir archivo finalizado.\")\n\n\n\"\"\"* Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado.\"\"\"\n\nclass MiPrimerError(Exception):\n    pass # Excepcion creada por mi para mostrar que el saldo es insuficiente\n\nsaldo_en_la_cuenta = 100\n\ndef saldo_insuficiente(saldo):\n    # 1 error saldo negativo\n    if saldo < 0:\n        raise ValueError(\"El saldo no puede ser negativo\")\n    \n    # 2 error saldo no es un numero\n    if not isinstance(saldo, (int, float)):\n        raise TypeError(\"El saldo debe ser un numero\")\n    \n    # 3 error saldo insuficiente\n    if saldo > saldo_en_la_cuenta:\n        raise MiPrimerError(\"El saldo supera al valor de la cuenta\")\n    \n    return saldo + saldo_en_la_cuenta\n\ntry:\n    cuenta = saldo_insuficiente(150)\n    print(\"Nuevo saldo en cuenta: \", cuenta)\nexcept Exception as e:\n    print(\"Se produjo un error de tipo:\", type(e).__name__)\n    print(\"Mensaje del error:\", e)\nelse:\n    print(\"No se produjo ningun error\")\nfinally:\n    print(\"La ejecucion a finalizado\")\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/AllanYSalazarG.py",
    "content": "\"\"\" #10 EXCEPCIONES \"\"\"\n\n# --------------- EJERCICIO -----------------\n\nprint(\"-------------- EJERCICIO --------------\")\n\ntry:\n    # al ingresar una letra, da error ValueError\n    n1 = int(input(\"Ingresa un numero: \"))\n    n2 = int(input(\"Ingresa otro numero: \"))\nexcept ValueError as e:\n    print(\"Debes ingresar un numero\")\n\nprint(\"El programa continua trabajando\")\n\n\ndef division(number1, number2):\n    return number1/number2\n\n\ntry:\n    result = division(n1, n2)\nexcept ZeroDivisionError as e:\n    print(f\"Error inesperado: {e}\")\nexcept NameError as e:\n    print(\"ingresaste letras en la division\")\nelse:\n    print(result)\n\n# ------------------- EXTRA ---------------------\n\nprint(\"-------- EJERCICIO EXTRA -----------\")\n\n\nclass PersonalizedError(Exception):\n    \"\"\" Excepcion personalizada \"\"\"\n\n    def __init__(self, msg, code_error):\n        self.message = msg\n        self.code_error = code_error\n\n\ndef prosessing_params(*params):\n    \"\"\" Prosesando parametros \"\"\"\n    if len(params) < 1:\n        raise PersonalizedError(\"Tu lista no puede estar vacía\", 100)\n    if len(params) > 10:\n        raise PersonalizedError(\n            \"Excediste el limite de articulos de tu lista\", 200)\n\n\ntry:\n    # prosessing_params(\"Leche\", \"Harina\", \"Aceite\")\n    prosessing_params()\nexcept PersonalizedError as e:\n    print(f\"{e.message} - Codigo de error: {e.code_error}\")\nelse:\n    print(\"Tu lista ha sido guardada correctamente\")\nfinally:\n    print(\"Nos vemos pronto\")\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/BrianSilvero.py",
    "content": "\"\"\"\nEjercicio\n\"\"\"\n\ntry:\n    print(10/1)\n    print([1,2,3,4][4])\nexcept Exception as e:\n    print(f\"Se ha producido un error: {e} ({type(e).__name__})\")\n\n\"\"\"\nExtra\n\"\"\"\n\nclass StrTypeError(Exception):\n    pass\n\ndef process_params(parametros: list):\n    if len(parametros) < 3:\n        raise IndexError()\n    elif parametros[1] == 0:\n        raise ZeroDivisionError()\n    elif type(parametros[2]) == str:\n        raise StrTypeError(\"El tercer elemento no puede ser una cadena de texto.\")\n\n    print(parametros[2])\n    print(parametros[0]/parametros[1])\n    print(parametros[2] + 5)\n\ntry:\n    process_params([1,2,3,4])\nexcept IndexError as e:\n    print(\"El numero de elementos de la lista debe ser mayor que dos.\")\nexcept ZeroDivisionError as e:\n    print(\"El segundo elemento de la lista no puede ser cero.\")\nexcept StrTypeError as e:\n    print(f\"{e}\")\nexcept Exception as e:\n    print(f\"Se ha producido un error inesperado: {e}.\")\nelse:\n    print(\"No se ha producido ningun error.\")\nfinally:\n    print(\"El programa finaliza sin detenerse.\")"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/C-Gabs.py",
    "content": "#Reto 10\n\n''' * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado.'''\n\n\ntry:\n    raise ValueError\nexcept ValueError:\n    print(\"El valor del argumento es inapropiado para la operación\")\n\n\n\ntry:\n    print(15/0)\nexcept ZeroDivisionError:\n    print(f\"No puedes dividir entre cero: {ZeroDivisionError}\")\n\nlista =[1,2,3,4,5,6]\ntry:\n    print(lista[8])\nexcept IndexError:\n    print(f\"Se ha producido un error: {IndexError}\")\n\n\n\n#Reto Extra\n\nclass TypeCharError(TypeError):\n    pass\n\ndef procesador_de_parametros(indice, num_1, cadena):\n    lista = [1,2,3,4,5]\n    print(lista[indice])\n    suma = 13 + num_1\n    print(suma)\n    if cadena.isalpha():\n        char_alpha = cadena\n        print(char_alpha)\n    else:\n        raise TypeCharError(\"El caracter debe ser alphabético\")\n    \n\ntry:\n    procesador_de_parametros(7,\"12\",\"ar54\")\nexcept IndexError as error_indice:\n    print(f\"Ocurrio un error: {error_indice}\")\nexcept TypeError as error_tipo:\n    print(f\"Ocurrio un error: {error_tipo}\")\nexcept TypeCharError as error_de_character:\n    print(f\"Ocurrio un error: {error_de_character}\")\nexcept Exception as excepcion:\n    print(f\"Ocurrio un error inesperado: {excepcion}\")\nelse:\n    print(\"No ha ocurrido ningún error\")\nfinally:\n    print(\"La ejecución ha finalizado\")"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/CaveroBrandon.py",
    "content": "\"\"\"EJERCICIO:\nExplora el concepto de manejo de excepciones según tu lenguaje.\nFuerza un error en tu código, captura el error, imprime dicho error\ny evita que el programa se detenga de manera inesperada.\nPrueba a dividir \"10/0\" o acceder a un índice no existente\nde un listado para intentar provocar un error.\"\"\"\n\n\ndef division_by_zero():\n    try:\n        ans = 1 / 0\n        print(ans)\n    except ZeroDivisionError as e:\n        print(f'Division by zero is not possible: {e}')\n        print('****************')\n\n\ndef value_error():\n    try:\n        ans = int('abc')\n        print(ans)\n    except ValueError as e:\n        print(f'Converting a string to int is not possible: {e}')\n        print('****************')\n\n\ndef index_error():\n    try:\n        ans = []\n        print(ans[5])\n    except IndexError as e:\n        print(f'Index not found: {e}')\n        print('****************')\n\n\ninput('Press enter to try a division (1/0) - Division by zero')\ndivision_by_zero()\ninput('Press enter to try convert a string to int')\nvalue_error()\ninput('Press enter to try getting a non existing index')\nindex_error()\n\n\n\"\"\"DIFICULTAD EXTRA (opcional):\nCrea una función que sea capaz de procesar parámetros, pero que también\npueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\ncorresponderse con un tipo de excepción creada por nosotros de manera\npersonalizada, y debe ser lanzada de manera manual) en caso de error.\n- Captura todas las excepciones desde el lugar donde llamas a la función.\n- Imprime el tipo de error.\n- Imprime si no se ha producido ningún error.\n- Imprime que la ejecución ha finalizado.\"\"\"\n\n\nclass CustomError(Exception):\n    def __init__(self, message='Custom Error'):\n        self.message = message\n        super().__init__(self.message)\n\n\ndef division(number):\n    return 10 / number\n\n\nwhile True:\n    try:\n        number = int(input('Enter the value to divide: '))\n        if number < 0:\n            raise CustomError('Negative numbers are not allowed')\n        else:\n            print(f'The function execution is completed, no errors were raised the division is: {division(number)}')\n    except ZeroDivisionError as e:\n        print(f'Division by zero is not allowed: {e}')\n    except ValueError as e:\n        print(f'The value must be a positive integer: {e}')\n    except CustomError as e:\n        print(f'The value cannot be a negative number: {e}')\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/CesarCarmona30.py",
    "content": "'''\n  EJERCICIO\n'''\n\n\ndef divide(dividend, divisor):\n    try:\n        quotient = dividend / divisor\n        print(f'{dividend} / {divisor} = {quotient}')\n    except ZeroDivisionError as e:\n        print(f'Error: {type(e).__name__}, no se puede dividir por cero.')\n\n\ndivide(15, 5)\ndivide(19, 4)\ndivide(321, 0)\n\n\ndef showList(list):\n    try:\n        if not list:\n            raise IndexError\n        print('List items:')\n        for item in list:\n            print(f'-{item}')\n    except IndexError as e:\n        print(f'Error: {type(e).__name__}, la lista esta vacía.')\n\n\nshowList([1, 5, 53, 'Cuatroscientos quince'])\nmy_list = [10, 'str', True]\nshowList(my_list)\nlist_empty = []\nshowList(list_empty)\n\n\n'''\n  EXTRA\n'''\n\n\nclass MyError(Exception):\n    def __init__(self, msg):\n        self.message = msg\n\n\ndef add():\n    num1 = input('Dame un número: ')\n    num2 = input('Dame otro número: ')\n    exceptDetect(num1, num2)\n    print('Ejecución finalizada. ;D')\n\n\ndef exceptDetect(num1, num2):\n    try:\n        if num1.lower() == 'error' or num2.lower() == 'error':\n            raise MyError('Invocaste este error')\n        op1 = int(num1)\n        op2 = int(num2)\n        print(f'{op1} + {op2} = {op1 + op2}')\n        print('No se produjo ningún error')\n    except ValueError as e:\n        print(f'Error: {type(e).__name__}, no introduciste un número válido')\n    except KeyboardInterrupt as e:\n        print(f'Error: {type(e).__name__}, haz interrumpido el programa')\n    except MyError as e:\n        print(f'Error: {type(e).__name__}, {e.message}')\n\n\nadd()\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/Chrisdev00.py",
    "content": "\"\"\"\nEJERCICIO:\nExplora el concepto de manejo de excepciones según tu lenguaje.\nFuerza un error en tu código, captura el error, imprime dicho error\ny evita que el programa se detenga de manera inesperada.\nPrueba a dividir \"10/0\" o acceder a un índice no existente\nde un listado para intentar provocar un error.\n\nDIFICULTAD EXTRA (opcional):\nCrea una función que sea capaz de procesar parámetros, pero que también\npueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\ncorresponderse con un tipo de excepción creada por nosotros de manera\npersonalizada, y debe ser lanzada de manera manual) en caso de error.\n- Captura todas las excepciones desde el lugar donde llamas a la función.\n- Imprime el tipo de error.\n- Imprime si no se ha producido ningún error.\n- Imprime que la ejecución ha finalizado. \n\n\"\"\"\n\n# En Python, el manejo de excepciones es una técnica que te permite lidiar con situaciones excepcionales \n# o errores que pueden ocurrir durante la ejecución de un programa. \n# Las excepciones pueden ser errores de sintaxis, errores de tiempo de ejecución, \n# errores de lógica del programa, entre otros.\n\n# El manejo de excepciones en Python se logra utilizando bloques try, except, finally y, \n# opcionalmente, else.\n\ntry:\n    name = input('Enter your name:')\n    year_born = input('Year you born:')\n    age = 2019 - year_born\n    print(f'You are {name}. And your age is {age}.')\nexcept TypeError:\n    print('Type error occur')\nexcept ValueError:\n    print('Value error occur')\nexcept ZeroDivisionError:\n    print('zero division error occur')\nelse:\n    print('Este bloque se ejecuta si no se lanza ninguna excepcion en el bloque try')\nfinally:\n    print('Esto se ejecuta siempre')\n\n# Dividiendo entre 0\n\ntry:\n    x = 1 / 0  \nexcept ZeroDivisionError as e:    \n    print(\"Ha ocurrido un error:\", e)  \nelse:\n    print(\"No se ha producido ninguna excepción.\")\nfinally:\n    print(\"Esto se ejecuta siempre.\")  # Este bloque se ejecuta siempre, haya excepción o no\n\n# acceder a un índice no existente en una lista para provocar un error y luego maneja esa excepción:\n    \ntry:\n    lista = [1, 2, 3]\n    indice = lista[5]  \nexcept IndexError as e:\n    print(\"Ha ocurrido un error:\", e)  \nelse:\n    print(\"No se ha producido ninguna excepción.\")\nfinally:\n    print(\"Esto se ejecuta siempre.\")  \n\n\n######## ---------------------- EXTRA -------------------------- ###############\n    \n\nclass MiExcepcionPersonalizada(Exception):\n    def __init__(self, mensaje):\n        self.mensaje = mensaje\n\ndef procesar_parametros(parametros):\n    try:\n        if len(parametros) < 3:\n            raise ValueError(\"Se necesitan al menos 3 parámetros\")\n        \n        if not isinstance(parametros[0], int) or not isinstance(parametros[1], int) or not isinstance(parametros[2], int):\n            raise TypeError(\"Los parámetros deben ser enteros\")\n\n        if parametros[0] + parametros[1] <= parametros[2]:\n            raise MiExcepcionPersonalizada(\"La suma de los dos primeros parámetros no es mayor que el tercero\")\n                \n        print(\"No se ha producido ningún error\")\n\n    except ValueError as ve:\n        print(\"Error:\", ve)\n    except TypeError as te:\n        print(\"Error:\", te)\n    except MiExcepcionPersonalizada as mep:\n        print(\"Error personalizado:\", mep.mensaje)\n    except Exception as e:\n        print(\"Error desconocido:\", e)\n    finally:\n        print(\"La ejecución ha finalizado\")\n\n\ntry:\n    parametros = [1, 2, '3']\n    procesar_parametros(parametros)\n    parametros_dos = [1, 4, 8]\n    procesar_parametros(parametros_dos)\n    parametros_tres = [1, \"a\"]\n    procesar_parametros(parametros_tres)\nexcept Exception as e:\n    print(\"Excepción capturada:\", type(e).__name__)\n\n\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/Complex303.py",
    "content": "\"\"\"\nExcepciones\n\"\"\"\n\ntry:\n    print(5/5)\n    my_list = [2,4,6,8]\n    print(my_list[8])\n\n# Si ocurre cualquier excepción en el bloque try. se captura aquí y se guarda en la variable 'e'.  \n# {e} → muestra el mensaje de error específico que generó Python. Por ejemplo: 'list index out of range' si intentaste acceder a una posición inexistente en una lista.\n# {type(e).__name__} → muestra el nombre de la clase de excepción que ocurrió. Por ejemplo: 'IndexError', 'ValueError', 'ZeroDivisionError', etc.\nexcept Exception as e:\n    print(f\"Se ha producido un error: {e} ({type(e).__name__})\") \n    \nprint(\"Hola\") # Esta línea se ejecuta sin importar si hubo error o no\n\n\n\"\"\"* DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado. \"\"\"\n\n\nprint(\"------------------------\")\n\n\n\n# Definimos una excepción personalizada llamada StrTypeError que hereda de Exception\nclass StrTypeError(Exception):\n    pass  # No hace nada extra, solo sirve para identificar un tipo de error propio\n\n# Definimos una función que recibe una lista llamada 'parameters'\ndef process_params(parameters: list):\n\n    # Validación 1: si la lista tiene menos de 3 elementos, lanza IndexError\n    if len(parameters) < 3:\n        raise IndexError()\n    \n    # Validación 2: si el segundo elemento (índice 1) es cero, lanza ZeroDivisionError\n    elif parameters[1] == 0:\n        raise ZeroDivisionError()\n\n    # Validación 3: si el tercer elemento (índice 2) es una cadena, lanza nuestro error personalizado\n    elif type(parameters[2]) == str:\n        raise StrTypeError(\"El tercer elemento de la lista no puede ser una cadena de texto\")\n\n    # Si todo está bien, ejecuta estas operaciones:\n    print(parameters[2])             # Imprime el valor del tercer elemento\n    print(parameters[0] / parameters[1])  # Divide el primer elemento entre el segundo\n    print(parameters[2] + 5)         # Suma 5 al tercer elemento (debe ser un número)\n\n# Aquí empieza el manejo de excepciones\ntry:\n    # Llama a la función con una lista de ejemplo\n    process_params([1,3,6,4])\n    \n# Si ocurre IndexError, entra aquí\nexcept IndexError as e:\n    print(\"El numero de elementos de la lista debe ser mayor que 2\")\n\n# Si ocurre ZeroDivisionError, entra aquí\nexcept ZeroDivisionError as e:\n    print(\"El segundo elemento de la lista no puede ser cero\")\n\n# Si ocurre nuestro error personalizado StrTypeError, entra aquí\nexcept StrTypeError as e:\n    print(e)  # Muestra el mensaje personalizado\n\n# Si ocurre cualquier otro error no previsto, entra aquí\nexcept Exception as e:\n    print(f\"Se ha producido un error inesperado: {e}\")\n\n# Si no se produce ninguna excepción, se ejecuta este bloque\nelse:\n    print(\"No se ha producido ningun error\")\n\n# Este bloque se ejecuta siempre, haya ocurrido o no una excepción\nfinally:\n    print(\"El programa finaliza\")\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/DaniQB99.py",
    "content": "'''\nEJERCICIO:\nExplora el concepto de manejo de excepciones según tu lenguaje.\nFuerza un error en tu código, captura el error, imprime dicho error\ny evita que el programa se detenga de manera inesperada.\nPrueba a dividir \"10/0\" o acceder a un índice no existente\nde un listado para intentar provocar un error.\n'''\n\n#\ntry:\n    print(10/1) # División por cero\n    print([1, 2, 3, 4][5]) # Acceso a un índice no existente\n\n    print('Operacion realizada')\nexcept Exception as e: # Captura todas las excepciones\n    print(f'Se ha producido un error: {e}')\n\n\n'''\nDIFICULTAD EXTRA (opcional):\nCrea una función que sea capaz de procesar parámetros, pero que también\npueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\ncorresponderse con un tipo de excepción creada por nosotros de manera\npersonalizada, y debe ser lanzada de manera manual) en caso de error.\n- Captura todas las excepciones desde el lugar donde llamas a la función.\n- Imprime el tipo de error.\n- Imprime si no se ha producido ningún error.\n- Imprime que la ejecución ha finalizado.\n'''\n\nprint('\\n\\n\\n--- EJERCICIO EXTRA ---\\n')\n\nclass StrTypeError(Exception):\n    pass\n\ndef process_params(parameters: list): \n\n    if len(parameters) < 3: \n        raise IndexError() # Comprueba si el número de elementos es correcto\n    elif parameters[1] == 0:\n        raise ZeroDivisionError() # Lanza un error de división por cero\n    elif type(parameters[2]) == str:\n        raise StrTypeError(\n            \"El segundo elemento no puede ser una cadena de texto.\") # Lanza un error de tipo de dato    \n    \n    print(parameters[4]) \n    print(parameters[0]/parameters[1])\n    print(parameters[2] + 5)\n\ntry:\n    process_params([1, 2, 'DANIEL', 4])\nexcept IndexError as e:\n    print(\"El número de elementos de la lista debe ser mayor que dos.\")\nexcept ZeroDivisionError as e:\n    print(\"El segundo elemento de la lista no puede ser un cero.\")\nexcept StrTypeError as e:\n    print(f\"{e}\")\nexcept Exception as e:\n    print(f\"Se ha producido un error inesperado: {e}\")\nelse:\n    print(\"No se ha producido ningún error.\")\nfinally:\n    print(\"El programa finaliza sin detenerse.\")"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/DataCiriano.py",
    "content": "\"\"\"\n* EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado. \n\"\"\"\n\ndef division():\n\n    try:\n        denominator = int(input(\"Enter a number for the denominator: \"))\n        divider = int(input(\"Enter a number for the divider \"))\n        \n        result = denominator / divider\n        \n        return result\n            \n    except ZeroDivisionError as e:\n        print(f\"Error: {e}\")\n\n    except ValueError as e:\n        print(f\"Error: {e}\")\n        \n        \nprint(division())\n\n#-----EXTRA-----\n\n#Function to calculate the division by 2 of the number 10. If it is not divided by 2, it throws a custom error\n\nclass MyPersonalException(Exception):\n    pass\n\ndef process_parameter(parameter):\n    try:\n        \n        result = 10 / parameter\n        \n        if parameter != 2:\n            raise MyPersonalException(\"Error: The parameter in not 2\")\n        \n        print(\"Successful operation. Result:\", result)\n    \n    except ZeroDivisionError as e:\n        print(\"Error: ZeroDivisionError -\", e)\n    except MyPersonalException as e:\n        print(\"Custom error -\", e)\n    except Exception as e:\n        print(\"General error -\", e)\n    else:\n        print(\"No errors detected.\")\n    finally:\n        print(\"The execution has finished.\")\n\n\ntry:\n    parameter = int(input(\"Enter a number to divide 10: \"))\n    process_parameter(parameter)\nexcept ValueError as e:\n    print(f\"Error: ValueError- {e}\")\n    print(\"Please enter a valid number.\")\nexcept Exception as e:\n    print(\"Calling function error -\", e)\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/Dkp-Dev.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n\"\"\"\n\ntry:\n    print(10/0)\n    print([1, 2, 3, 4][4])\nexcept Exception as e:\n    print(f\"Se ha producido un error: {e} ({type(e).__name__})\")\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado.\n\"\"\"\n\n\nclass StrTypeError(Exception):\n    pass\n\n\ndef process_params(parameters: list):\n\n    if len(parameters) < 3:\n        raise IndexError()\n    elif parameters[1] == 0:\n        raise ZeroDivisionError()\n    elif type(parameters[2]) == str:\n        raise StrTypeError(\n            \"El tercer elemento no puede ser una cadena de texto.\")\n\n    print(parameters[2])\n    print(parameters[0]/parameters[1])\n    print(parameters[2] + 5)\n\n\ntry:\n    process_params([1, 2, 3, 4])\nexcept IndexError as e:\n    print(\"El número de elementos de la lista debe ser mayor que dos.\")\nexcept ZeroDivisionError as e:\n    print(\"El segundo elemento de la lista no puede ser un cero.\")\nexcept StrTypeError as e:\n    print(f\"{e}\")\nexcept Exception as e:\n    print(f\"Se ha producido un error inesperado: {e}\")\nelse:\n    print(\"No se ha producido ningún error.\")\nfinally:\n    print(\"El programa finaliza sin detenerse.\")\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/EmmanuelMMontesinos.py",
    "content": "\"\"\"/*\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n */\"\"\"\n\nprint(\"Ejercicio base:\")\nprint(\"----------------\")\n\n# Excepciones, capturando un KeyError\ndb = {10:\"Excepciones\"}\ndef imprimir_clave(llave):\n    try:\n        dato = db[llave]\n        print(f\"El Ejercicio {llave} es {dato}\")\n    except KeyError as e:\n        print(f\"{llave} no esta en la DB\\nError {e}\")\n\n# Pruebas\nimprimir_clave(2)\nimprimir_clave(10)\nimprimir_clave(2)\nprint(\"----------------\")\n\n\"\"\"* DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado.\"\"\"\n\n\nprint(\"----------------\")\nprint(\"Ejercicio extra\")\nprint(\"----------------\")\n\n# Ecepción Propia\nclass Error_letra(Exception):\n    def __init__(self,letra):\n        self.mensaje = f\"Letra Prohibida: {letra}\"\n        super().__init__(self.mensaje)\n        \ndef analizador(letra):\n    # generar excepción\n    resultado = letra.upper()\n    \n    # 2º excepción\n    second = letra[1]\n    \n    # 3º excepción\n    if second.lower() == \"ñ\":\n        raise Error_letra(letra)\n    print(\"Analizador Exitoso\")\n\n# He necesitado esta función para poder anidar las excepciones y no repetir bucles de try except\ndef check_analizador(letra):\n    try:\n        analizador(letra)\n        \n    except AttributeError as e:\n        print(f\"Error_1: {e}\")\n        \n    except IndexError as e:\n        print(f\"Error_2: {e}\")\n        \n    except Error_letra as e:\n        print(f\"Error_3: {e}\")\n        \n    except Exception as e:\n        print(e)\n        \n    else:\n        print(\"No hubo Errores\")\n        \n    finally:\n        print(\"Proceso Ejecutado\\n\")\n    \n\n# Pruebas\n'''Error_1'''\ncheck_analizador(7)\n    \n'''Error_2'''\ncheck_analizador(\"l\")\n    \n'''Error_3'''\ncheck_analizador(\"uñ\")\n\n'''Correcto'''\ncheck_analizador(\"ul\")\n\nprint(\"----------------\")"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/EricJoel-code.py",
    "content": "## Excepciones\n\ntry:\n    print(10/0)  # Esto generará una excepción de división por cero\n    \n    print([1, 2, 3][5])  # Esto generará una excepción de índice fuera de rango\n    \nexcept Exception as e:\n    print(f\"Se ha producido un error: {e} ({type(e).__name__})\")\n    \n    \n## Extra\n\n\"\"\"\nCrea una función que sea capaz de procesar parámetros, pero que también pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que corresponderse con un tipo de excepción creada por nosotros de manera personalizada, y debe ser lanzada de manera manual) en caso de error.\n- Captura todas las excepciones desde el lugar donde llamas a la función.\n- Imprime el tipo de error.\n- Imprime si no se ha producido ningún error.\n- Imprime que la ejecución ha finalizado.\"\"\" \n\nclass MiExcepcionPersonalizada(Exception):\n    pass\n\ndef procesar_parametros(param):\n    if not isinstance(param, int):\n        raise TypeError(\"El parámetro debe ser un entero.\")\n    if param < 0:\n        raise ValueError(\"El parámetro no puede ser negativo.\")\n    if param == 42:\n        raise MiExcepcionPersonalizada(\"El parámetro no puede ser 42.\")\n    return param * 2 \n\ntry:\n    resultado = procesar_parametros(42)\n    print(f\"Resultado: {resultado}\")\nexcept TypeError as te:\n    print(f\"Error de tipo: {te} ({type(te).__name__})\")\nexcept ValueError as ve:\n    print(f\"Error de valor: {ve} ({type(ve).__name__})\")\nexcept MiExcepcionPersonalizada as me:\n    print(f\"Error personalizado: {me} ({type(me).__name__})\")\nelse:\n    print(\"No se ha producido ningún error.\")\nfinally:\n    print(\"El programa finaliza sin detenerse.\")\n    \n    "
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/FedeAirala.py",
    "content": "# #10 EXCEPCIONES\n\n\"\"\" * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n\"\"\"\n\n# Error de división por cero\nprint (\"-\"*60)\ntry:                \n    div = 10/0  \n\nexcept ZeroDivisionError as zde :                     # Se pasa el error capturado\n    print (zde,\" Error\")\n\n\n# Error de tipo\nprint (\"-\"*60)\n\ntry:                        # Con try se prueba un bloque de código para buscar errores\"Hello\n    x= \"Hello\"\n\n    if not type(x) is int:\n        raise TypeError(\"Error ,esto no es un entero\") # Captura el error\n        \n    else:\n        print (x)\n\nexcept TypeError as zde :                     # Se pasa el error capturado\n    print (zde)\n\n\n\nprint (\"-\"*60)\n\ntry:\n\n    lista = [1,2,3,4]\n    print (lista[5])\n\nexcept IndexError as ide:\n    print (\"Error de tipo:\",ide)\nfinally:                    \n    print (\"Este bloque se ejecuta siempre\")\n\n\nprint (\"-\"*60)\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado. \n\"\"\"\nclass StrError (Exception):\n     pass\n\ndef process_parameters(a:list):\n       \n        if type(a[0])==str or type(a[1])==str:\n             raise StrError(\"Error, no se pueden dividir strings\")\n        elif len(a)>2:\n             raise Exception (\"El programa sólo sirve para dividir 2 números\")\n        elif a[1]==0:\n             raise ZeroDivisionError(\"No se puede dividir por 0\")\n      \n        return (a[0]/a[1])\n\n\n\ntry:\n\n    #print (process_parameters([3,0])) Error de división por 0\n    # print (process_parameters([\"a\",3])) Error no se pueden dividir strings\n    #print (process_parameters([3,2,5])) Error de programa\n    print (process_parameters([10,5])) # El programa corre correctamente\n\nexcept ZeroDivisionError as se:\n    print (\"Error de tipo:\", se)\nexcept StrError as st:\n    print (st)\nexcept Exception as e:\n    print (e)\n\nelse:\n     print (\"No se ha producido ningún error\")\n\nfinally:\n     print (\"La ejecución ha finalizado\")\n\n\n\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/Gallitofast.py",
    "content": "#HELLOWORLD\nprint (\"^\"*100)\ntry:                \n    div = 10/0  \n    print(f\"10 divided by 0 is: {div}\")\n\nexcept ZeroDivisionError as zde:\n    print(zde,\"ERROR!! \")\n\nprint (\"^\"*100)\n#Type error\ntry:\n    var_1= 10\n    if not type(var_1) is str:\n        raise TypeError(\"Tis is NOT A STRING\")\n    else:\n        print (var_1)\n\nexcept TypeError as zde :                    \n    print (zde)\n\n\nprint (\"^\"*100)\n\n\"\"\"EXTRA DIFFICULTY\"\"\"\n\nclass StrError (Exception):\n     pass\n\ndef process_parameters(a:list):\n       \n        if type(a[0])==str or type(a[1])==str:\n             raise StrError(\"Error, You can't divide strings\")\n        elif len(a)>2:\n             raise Exception (\"THE FUNCTION CAN ONLY DIVIDE 2 NUMBERS!\")\n        elif a[1]==0:\n             raise ZeroDivisionError(\"You cant divide by 0!!\")\n      \n        return (a[0]/a[1])\n\n\n\ntry:\n#These are tests that are going to fail so that we can see the exceptions management.\n    print (process_parameters([3,0])) #Division by 0 error\n    #print (process_parameters([\"a\",3])) #Error can't divide strings\n    #print (process_parameters([3,2,5])) #More than 2 nubers\n    \n\nexcept ZeroDivisionError as se:\n    print (\"Error type:\", se)\nexcept StrError as st:\n    print (st)\nexcept Exception as e:\n    print (e)\n\nelse:\n     print (\"There has been no errors\")\n\nfinally:\n     print (\"The execution has been finalized\")\n\n\n\n\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/Gordo-Master.py",
    "content": "\"\"\"\nExcepciones\n\"\"\"\n\ntry:\n    x = 10 / '0'\nexcept ZeroDivisionError:\n    print(\"Error de división con 0\")\nexcept TypeError as ty:\n    print(f\"Error de tipo: {ty}\")\nelse:\n    print(x)\nfinally:\n    print(\"Aquí termina el manejo de las excepciones\")\n\ntry:\n    print(10/1)\n    print([1, 2, 3, 4][4])\nexcept Exception as e:\n    print(f\"Se ha producido un error: {e} ({type(e).__name__})\")\n\n\n\"\"\"\nExtra\n\"\"\"\n### Debe ser entero, positivo y mayor que 0\ndef condition_ver(number):\n    if type(number) is float:\n        raise Exception(f\"No se acepta valores flotantes, [{number}] es un valor flotante\")\n    if not type(number) is int:\n        raise TypeError(f\"El tipo de dato debe ser un int, [{number}] no lo es\")\n    if not number > 0:\n        raise ValueError(\n            f\"El número no puede ser negativo ni 0, [{number}] no cumple con esta condición\"\n            )\n        \n\n\ndef geometric_progression(first_number,reason,position):\n    try:    \n        condition_ver(first_number)\n        condition_ver(reason)\n        condition_ver(position)\n    except TypeError as e:\n        print(f\"{type(e).__name__}: {e}\")\n    except ValueError as e:\n        print(f\"{type(e).__name__}: {e}\")\n    except Exception as e:\n        print(f\"{type(e).__name__}: {e}\")\n    else:\n        s = first_number\n        for i in range(1,position):\n            s *= reason\n        print (f\"El valor en la {position}º de la progresión geometrica, con valor inicial: {first_number}, y razon: {reason} es: {s}\")\n    finally:\n        print(\"Ha terminado el programa\")\n\n\n# geometric_progression(1,0,3)\n\nclass StrTypeError(Exception):\n    pass\n\ndef process_params(parameters: list):\n\n    if len(parameters) < 3:\n        raise IndexError()\n    elif parameters[1] == 0:\n        raise ZeroDivisionError()\n    elif type(parameters[2]) == str:\n        raise StrTypeError(\"El tercer elemento no puede ser un cadena de texto\")\n\n    print(parameters[2])\n    print(parameters[0]/parameters[1])\n    print(parameters[2] + 5)\n\ntry:\n    process_params([1,2,3,4])\nexcept IndexError as e:\n    print(\"El número de elementos de la lista debe ser mayor que dos\")\nexcept ZeroDivisionError as e:\n    print(\"El segundo elemento de la lista no puede ser un cero (0)\")\nexcept StrTypeError as e:\n    print(f\"{type(e).__name__} : {e} \")\nexcept Exception as e:\n    print(f\"Se ha producido un error inesperado: {e} ({type(e).__name__})\")\nelse:\n    print(\"No se ha producido ni un error\")\nfinally:\n    print(\"El programa finaliza sin deterse\")\n\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/Hyromy.py",
    "content": "# sentencia try basica\ntry: # coodigo que pueda fallar\n    print(\"ejecutando codigo\")\n\nexcept: # en caso de haber fallado, actuar en consecunecia\n    print(\"hubo un error\")\n\n\n# capturando un error cualquiera\ntry:\n    print(1 / 0)\n\nexcept Exception as e:\n    print(f\"ocurrio un error: {e}\")\n\n\n# acpturando varios errores\ntry:\n    dividir_0 = False\n    if dividir_0:\n        variable = 10 / 0\n\n    indice = False\n    if indice:\n        lista = [1, 2, 3]\n        lista[10] += 1\n\n    error = True\n    if error:\n        raise KeyError\n\n#el orden importa\nexcept ZeroDivisionError: # acciones para este tipo de exepcion\n    print(\"division entre 0\")\n\nexcept IndexError: # acciones para este tipo de excepcion\n    print(\"indice fuera de rango\")\n\nexcept Exception as e: # acciones para Excepciones en general\n    print(e.__class__)\n\n\n# sentencia try completa\ntry:\n    error = False\n    if error:\n        raise Exception # lanzar una excepcion\n    \nexcept Exception as e: # en caso de que haya un error\n    print(e.__cause__)\n\nelse: # en caso de que todo este bien\n    print(\"no hubo errores\")\n\nfinally: # en caso de errores o no\n    print(\"sentencia try terminada\")\n\nprint(\"\\n\")\n\n# ---- DIFICULTAD EXTRA ----\n\ndef lista_numeros(lista:list, target_index:int, replace_value:int) -> list:\n    for value in lista:\n        if not isinstance(value, int):\n            raise Exception(\"La lista debe de ser de numeros enteros\")\n        \n    if target_index >= len(lista):\n        raise Exception(\"Indice objetivo no valido\")\n    \n    if not isinstance(replace_value, int):\n        raise Exception(\"El valor a reemplazar debe ser entero\")\n    \n    lista[target_index] = replace_value\n    return lista\n\nfor i in range(5):\n    try:\n        if i == 0:\n            lista = lista_numeros([1, \"2\", 3], 1, 5)\n        elif i == 1:\n            lista = lista_numeros([1, 2, 3], 10, 40)\n        elif i == 2:\n            lista = lista_numeros([1, 2, 3], 1, \"7\")\n\n        lista = lista_numeros([1, 2, 3], 1, i)\n        print(lista)\n\n    except Exception as e:\n        print(f\"{e.__class__.__name__}: {e}\")\n\n    else:\n        print(\"no han ocurrido errores\")\n\n    print(\"iteracion terminada\")\n\nelse:\n    print(\"for terminado\")"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/Irenetitor.py",
    "content": "#Exercise\n\ntry:\n    print(13/0)\nexcept ZeroDivisionError:\n    print(\"Cannot divide by zero\")\n\n\n#Extra exercise\n\nclass NegativeNumberError(Exception):\n    \"\"\"Raised when the input number is negative.\"\"\"\n    pass\n\n\ndef div_except(num: int):\n    try:\n        if not isinstance(num, int):\n            raise ValueError(\"Only integers are allowed.\")\n        if num < 0:\n            raise NegativeNumberError(\"Negative numbers are not allowed.\")\n        \n        result = 23 / num\n        print(f\"Result: {result}\")\n\n    except ZeroDivisionError as e:\n        print(\"ZeroDivisionError:\", e)\n    except ValueError as e:\n        print(\"ValueError:\", e)\n    except NegativeNumberError as e:\n        print(\"CustomError:\", e)\n    else:\n        print(\"No error occurred.\")\n    finally:\n        print(\"Execution finished.\\n\")\n\ndiv_except(0)     # ZeroDivisionError\ndiv_except(-3)    # Custom error\ndiv_except(\"a\")   # ValueError\ndiv_except(10)    # Works fine\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/JAFeito.py",
    "content": " # EJERCICIO:\n # Explora el concepto de manejo de excepciones según tu lenguaje.\n # Fuerza un error en tu código, captura el error, imprime dicho error\n # y evita que el programa se detenga de manera inesperada.\n # Prueba a dividir \"10/0\" o acceder a un índice no existente\n # de un listado para intentar provocar un error.\n \n # DIFICULTAD EXTRA (opcional):\n # Crea una función que sea capaz de procesar parámetros, pero que también\n # pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n # corresponderse con un tipo de excepción creada por nosotros de manera\n # personalizada, y debe ser lanzada de manera manual) en caso de error.\n # - Captura todas las excepciones desde el lugar donde llamas a la función.\n # - Imprime el tipo de error.\n # - Imprime si no se ha producido ningún error.\n # - Imprime que la ejecución ha finalizado.\n \n\ntry:\n    #Descomentar una linea para ver su error\n    #print(var)\n    #print(0/0)  \n    #print(1+\"2\")\n    #print([1,2,3,4][4]) \n    #import modulo\n    #from math import po\n    #print(type.uno)  \n    print(int(\"hola\"))\n     \nexcept Exception as error:\n    print(f\"Se ha encontrado un error del tipo: {error}\")\n    \n#Extra\n\nclass ToMuchError(Exception):\n    pass\n\ndef num_func (a,b,c):\n    \n    if(c>3):\n        raise ToMuchError(\"El valor de c es demasiado grande\")\n    print(a+b)\n    print(a/c)\n   \n        \n    \ntry:\n    #num_func (1,2,3)\n    #num_func (1,2,0)\n    #num_func (\"1\",2,3)  \n    num_func (1,2,5)\n      \n    \nexcept ZeroDivisionError:\n    print(\"No se puede dividir por cero\")\n    \nexcept TypeError:\n    print(\"Los datos a y b tienen que ser del tipo int \")\n\nexcept Exception as e:\n    print(f\"Se ha producido un error inesperado: {e}\")\n    \nelse:\n    print(\"El programa a fianlizado sin errores\")\n    \nfinally:\n    print(\"El programa a fianlizado.\")"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/Jav-mol.py",
    "content": "# --- 10-Excepciones ---\n# --- Javier Molina ---\n\n# Capturar un Error\ntry:\n    print(10 / 2)\n    print(10 / 0)\nexcept Exception as e:\n    print(f'Error: [{e}] [{type(e).__name__}]')\n    \n        \n# --- Extra ---\n\nclass NumerosIguales(Exception):\n    pass\n\ntry:\n    a = int(input('Ingrese un numero: '))\n    b = int(input('Ingrese un numero: '))\n\n    if a == b:\n        raise NumerosIguales('Los numeros son iguales')\n    \n    a / b\n    \nexcept Exception as e:\n    print(f'Error: [{e}] [{type(e).__name__}]')\n    "
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/JesusAntonioEEscamilla.py",
    "content": "# #10 - Python -> Jesus Antonio Escamilla\n\n\"\"\"\nEJERCIÓ\n\"\"\"\ndef division_by_zero():    \n    try:\n        print(10/0)\n    except Exception as e:\n        print(f\"Se encontró un error: {e} {(type(e).__name__)}\")\n\ndef access_index_invalid():\n    try:\n        print([1,2,3,4][4])\n    except Exception as e:\n        print(f\"Se encontró un error: {e} {(type(e).__name__)}\")\n\n# Ejemplo\nprint(\"\\nIntentando dividir por cero:\")\ndivision_by_zero()\n    \nprint(\"\\nIntentando acceder a un índice inválido:\")\naccess_index_invalid()\n\n\n\n\"\"\"\nEXTRA\n\"\"\"\nclass exceptionPersonalizada(Exception):\n    def __init__(self, message):\n        self.message = message\n        super().__init__(self.message)\n\ndef procesar_lista(lista):\n    if len(lista) < 3:\n        raise TypeError(\"Tiene que ser mas de 3 elementos\")\n\n    if not all(isinstance(x, (int, float)) for x in lista):\n        raise ValueError(\"Los parámetros tienen que ser del mismo tipo\")\n\n    if not lista:\n        raise exceptionPersonalizada(\"La lista no es válida\")\n\n    print('La ejecución ha finalizado sin errores')\n\nprint(\"\\nExtra\")\ntry:\n    procesar_lista([1, 2, 3, 4])\nexcept Exception as e:\n    print(f\"Ocurrió un error: {e}\")\nfinally:\n    print(\"Programa Finalizado\")"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/JesusWay69.py",
    "content": "import os\nos.system('clear')\n\nprimer_numero = 4\nsegundo_numero = 0\ncero = 0\n\n#Comentar y descomentar la siguiente asignación de segundo_numero para ver cambios\n#segundo_numero = \"5\"\n\n### TRY-EXCEPT\ntry:\n  print(primer_numero + segundo_numero)\n  print(\"operación correcta\\n\")\nexcept:\n    print(\"operación incorrecta\\n\")\nprint(\"\")\n\n### TRY-EXCEPT-ELSE\ntry:\n   print(primer_numero + segundo_numero)\n   print(\"operación correcta\\n\")\nexcept: #Obligatorio para completar try\n    print(\"operación incorrecta\\n\")\nelse: # Opcional para continuar sin excepciones, sólo entrará si la operación dentro de try es correcta\n    print (\"la ejecución continúa\\n\")\nprint(\"\")\n### TRY-EXCEPT-ELSE-FINALLY\n\ntry: \n   print(primer_numero + segundo_numero)\n   print(\"operación correcta\\n\")\nexcept: #Obligatorio para completar try\n    print(\"operación incorrecta\\n\")\nelse: # Opcional para continuar sin excepciones, sólo entrará si la operación dentro de try es correcta\n    print (\"la ejecución contitúa\\n\")\nfinally: #Finally se suele usar si queremos ejecutar algún tipo de acción de limpieza.\n#Si por ejemplo estamos escribiendo datos en un fichero pero ocurre una excepción,\n #tal vez queramos borrar el contenido que hemos escrito con anterioridad, para no dejar datos inconsistenes en el fichero.\n    print(\"la ejecución continúa pero puede haber errores\\n\")\nprint(\"\")\n\n###PREVENCIÓN DE EXCEPCIONES POR TIPO DE DATO\ntry: \n   print(primer_numero + segundo_numero)\n   print(\"operación correcta\\n\")\nexcept TypeError: #TypeError limita la excepción al tipo de dato\n    print(\"tipos de dato incompatibles para esta operación\\n\")\nprint(\"\")\n\n###PREVENCIÓN DE EXCEPCIONES POR DIVISIÓN ENTRE CERO\ntry: \n   print(primer_numero / cero)\n   print(\"operación correcta\\n\")\nexcept ZeroDivisionError: #ZeroDivisionError limita la excepción a un divisor con valor 0\n    print(\"no se puede dividir entre 0\\n\")\nprint(\"\")\n\n###PREVENCIÓN DE EXCEPCIONES POR TIPO DE DATO Y/O POR VALOR\ntry: \n   print(primer_numero + segundo_numero)\n   print(\"operación correcta\")\nexcept ValueError: #ValueError limita la excepción al valor del dato\n    print(\"valores incompatibles con esta operación\")\nexcept TypeError: #TypeError limita la excepción al tipo de dato\n    print(\"tipos de dato incompatibles para esta operación\")\nprint(\"\")\n\n###PREVENCIÓN Y CAPTURA DE FALLO GENÉRICO O CONCRETO\ntry: \n   print(primer_numero / segundo_numero)\n   print(\"operación correcta\")\nexcept Exception as fallo: #Exception nos permite capturar cualquier excepción en una variable\n    print(fallo, \"\\n\")\n\n \n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/JheisonQuiroga.py",
    "content": "\"\"\"Exceptions\"\"\"\n\n# TypeError\n\nn1 = 10\nn2 = \"Pizza\"\ntry:\n\tadd_nums = n1 + n2 # We get a TypeError\nexcept TypeError:\n    print(\"Something Went Wrong\") # Handling the exception\nfinally:\n\tprint(\"The clause Finally always run\")\n    \n# ValueError\n\nmy_str:str = \"10\"\nprint(type(my_str))\nstr_to_int = int(my_str)\nprint(f\"{type(str_to_int)} : {str_to_int}\")\n\nmy_str = \"Duban\"\ntry:\n\tstr_to_int = int(my_str) # ValueError\nexcept ValueError:\n\tprint(\"Cannot cast literal str to int\")\n    \n    \n# ZeroDivisionError\n\ntry:\n\tdiv = 10/0\nexcept ZeroDivisionError:\n\tprint(\"Can not Div by Zero IDIOT!\")\n    \n\n# IndexError\n\nfruits = [\"banana\", \"strawberry\", \"watermelon\"]\ntry:\n\tprint(fruits[3])\nexcept IndexError:\n\tprint(\"The first index is zero my bro, continue studying\")\n    \n    \n# Printting the error\n\nfruits = [\"banana\", \"strawberry\", \"watermelon\"]\ntry:\n\tprint(fruits[3])\nexcept IndexError as e:\n\tprint(\"The first index is zero my bro, continue studying\")\n\tprint(e)\n    \n \n\"\"\" Extra \"\"\"\n\ndef add(n1, n2):\n\treturn n1 + n2\n    \ndef sub(n1, n2):\n\treturn n1 - n2\n    \ndef mul(n1, n2):\n\treturn n1 * n2\n\ndef div(n1, n2):\n\treturn n1 / n2\n    \n\nclass MyException(Exception): # Inherit of superclass Exception\n    pass\n\n \ndef calculator(func, n1: int, n2: int):\n    if n2 == 0:\n        raise ZeroDivisionError(\"The second number cannot be Zero\")\n    elif type(n2) == str:\n        raise TypeError(\"The second number cannot be str\")\n    return func(n1, n2)\n\t\ntry:\n    print(calculator(add, 10, 9))\nexcept TypeError as error:\n    print(\"Cannot do operations without int data type\")\n    print(f\"Error: {type(error).__name__}\") # Error: TypeError\nexcept MyException as e:\n    print(f\"My exception has caught the error: {e}\")\nexcept Exception as e:\n    print(\"Something was wrong\")\n    print(f\"{type(e).__name__}: {e}\")\nelse:\n    print(\"Everithing went well\")\nfinally:\n    print(\"This clause always run\")"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/JuanDAW37.py",
    "content": "\"\"\"* EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado. \"\"\"\n\n#División entre cero\ndef divideByZero():        \n    try:\n        print(10 / 0)        \n    except ZeroDivisionError as e: \n        print(\"Error: No se puede dividir entre cero\", e)        \n    finally:\n        print(\"La ejecución ha finalizado\")        \n\ndivideByZero()\n\n#Acceso a un índice inexistente\nnumeros = [1,2,3,4]\n\ndef listado():\n    try:\n        print(numeros[10])\n    except IndexError as e:\n        print('Error de: ', e)\n\nlistado()\n\n#EXTRA\nprint(\"\\n-----EXTRA-----\\n\")\n\nnumeros2 = [\"pepe\",2,3,4]\n\nclass Excepcion(Exception): #Excepción personalizada que hereda de la superclase Exception\n    pass\n\ndef procParam(parametros: list):    \n    if len(parametros) < 4:\n        raise IndexError(\"No hay suficientes parámetros\")\n    elif parametros[2] == 0:\n        raise ZeroDivisionError(\"No se puede dividir entre cero\")\n    elif type(parametros[0]) is not int:\n        raise Excepcion(\"El primer elemento de la lista no es un entero\")\n            \n    print(parametros[0] + 5)\n    print(parametros[3])\n    print(parametros[1] / parametros[2])    \n    \ntry:\n    procParam(numeros2)\nexcept IndexError as error:\n    print(error)\nexcept ZeroDivisionError as error:\n    print(error)\nexcept Excepcion as error:\n    print(f\"Error de tipo: {type(error).__name__} {error}\")\nelse:\n    print(\"No se han producido errores\")\nfinally:\n    print(\"La ejecución ha finalizado\")\n\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/KevinED11.py",
    "content": "from typing import Callable, NoReturn\nfrom functools import wraps\n\n\ntype Number = float | int\ntype OperationFn = Callable[[Number, Number], Number]\n\n\nclass OnlyNumbersException(Exception):\n    pass\n\n\ndef raise_only_numbers_exception(msg: str) -> NoReturn:\n    raise OnlyNumbersException(msg)\n\n\ndef is_number(n: Number) -> bool:\n    return isinstance(n, (int, float))\n\n\ndef validate_operation(fn: OperationFn) -> OperationFn:\n    @wraps(fn)\n    def wrapper(a: Number, b: Number) -> Number:\n        if not is_number(a) or not is_number(b):\n            raise_only_numbers_exception(\"a y b deben ser números\")\n\n        return fn(a, b)\n\n    return wrapper\n\n\n@validate_operation\ndef division(a: Number, b: Number) -> Number:\n    if b == 0:\n        raise ZeroDivisionError(\"No se puede dividir por cero\")\n\n    return a / b\n\n\n@validate_operation\ndef multiply(a: Number, b: Number) -> Number:\n    return a * b\n\n\ndef main() -> None:\n    try:\n        result = division(10, 0)\n        print(result)\n    except ZeroDivisionError as err:\n        print(repr(err))\n    except Exception as err:\n        print(repr(err), \"error inesperado\")\n    else:\n        print(\"la ejecución ha sido exitosa\")\n    finally:\n        print(\"la ejecución ha finalizado\")\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/LucasRebuffo.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado.\n */ \"\"\"\n\n# try:\n#     print([1].pop())\n#     print([].pop())\n# except Exception as e:\n#     print(e)\n# finally:\n#     print(\"Finaliza la ejecucion ...\")\n\nclass MyException(Exception):\n    pass\n\ndef parametros(parametros: list):\n\n    try:\n        if len(parametros) < 3:\n            raise IndexError\n        elif parametros[1] == 0:\n            raise ZeroDivisionError\n        print(parametros[2])\n        print(parametros[0]/parametros[1])\n\n    except Exception as e:\n        print(f\"Se ha producido un error: {e} ({type(e).__name__})\")\n\n\nparametros([1, 0, 3])\n\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/Lumanet.py",
    "content": "try:\n  print(10/0)\nexcept Exception:\n  print(\"No se puede dividir por cero.\")\n\ntry:\n  print([1, 2, 3, 4][4])\nexcept Exception as e:\n  print(f\"Se ha producido un error: {e} ({type(e).__name__})\")\n  \nprint(\"Fin del programa.\")\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\nCrea una función que sea capaz de procesar parámetros, pero que también\npueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\ncorresponderse con un tipo de excepción creada por nosotros de manera\npersonalizada, y debe ser lanzada de manera manual) en caso de error.\n- Captura todas las excepciones desde el lugar donde llamas a la función.\n- Imprime el tipo de error.\n- Imprime si no se ha producido ningún error.\n- Imprime que la ejecución ha finalizado. \n\"\"\"\n\nclass StrTypeError(Exception): # Creamos una excepción personalizada.\n    pass\n\n\ndef process_params(parameters):\n\n    if len(parameters) < 3: # Si la lista tiene menos de 3 elementos, lanzamos una excepción IndexError.\n        raise IndexError()\n    elif parameters[1] == 0: # Si el segundo elemento de la lista es un cero, lanzamos una excepción ZeroDivisionError.\n        raise ZeroDivisionError()\n    elif type(parameters[2]) == str: # Si el tercer elemento de la lista es una cadena de texto, lanzamos una excepción StrTypeError.\n        raise StrTypeError(\n            \"El tercer elemento no puede ser una cadena de texto.\")\n\n    print(parameters[2])\n    print(parameters[1]/parameters[0])\n    print(parameters[2] * 7)\n\n\ntry:\n    process_params([1, 3, 5, 7])\nexcept IndexError as e:\n    print(\"El número de elementos de la lista debe ser mayor que dos.\")\nexcept ZeroDivisionError as e:\n    print(\"El segundo elemento de la lista no puede ser un cero.\")\nexcept StrTypeError as e:\n    print(f\"{e}\")\nexcept Exception as e:\n    print(f\"Se ha producido un error inesperado: {e}\")\nelse:\n    print(\"No se ha producido ningún error.\")\nfinally:\n    print(\"La ejecución ha finalizado.\")"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/Maanghel.py",
    "content": "\"\"\"\nEJERCICIO:\nExplora el concepto de manejo de excepciones según tu lenguaje.\nFuerza un error en tu código, captura el error, imprime dicho error\n    y evita que el programa se detenga de manera inesperada.\nPrueba a dividir \"10/0\" o acceder a un índice no existente\n    de un listado para intentar provocar un error.\n\nDIFICULTAD EXTRA (opcional):\nCrea una función que sea capaz de procesar parámetros, pero que también\n    pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n    corresponderse con un tipo de excepción creada por nosotros de manera\n    personalizada, y debe ser lanzada de manera manual) en caso de error.\n- Captura todas las excepciones desde el lugar donde llamas a la función.\n- Imprime el tipo de error.\n- Imprime si no se ha producido ningún error.\n- Imprime que la ejecución ha finalizado.\n\"\"\"\n\ndef area_rectangle(base: int, height: int) -> int|None:\n    \"\"\"\n    Calculates the area of a rectangle.\n\n    Parameters:\n    - base (int): The base length of the rectangle.\n    - height (int): The height of the rectangle.\n\n    Returns:\n    - int | None: The area of the rectangle, or None if an error occurs.\n    \"\"\"\n    try:\n        area = base * height\n    except TypeError as e:\n        print(f\"Se ha producido un error. {e}\")\n        return None\n\n    return area\n\ndef divide(dividend: int, divider: int) -> float|None:\n    \"\"\"\n    Divides two numbers.\n\n    Parameters:\n    - dividend (int): The number to be divided.\n    - divider (int): The number to divide by.\n\n    Returns:\n    - float | None: The result of the division, or None if an error occurs.\n    \"\"\"\n    try:\n        result = dividend / divider\n    except ZeroDivisionError as e:\n        print(f\"Se ha producido un error. {e}\")\n        return None\n    except TypeError as e:\n        print(f\"Se ha producido un error. {e}\")\n        return None\n\n    return result\n\n# print(area_rectangle(2, 3))\n# print(area_rectangle(\"2\", \"3\"))\n# print(divide(4, 2))\n# print(divide(4, 0))\n# print(divide(4, \"2\"))\n\n# EXTRA\n\nclass NotIntTypeError(Exception):\n    \"\"\"Custom exception to indicate that not all inputs are integers.\"\"\"\n\ndef parameters_multiplication(args: list[int]):\n    \"\"\"\n    Validates a list of parameters before performing a multiplication.\n\n    Parameters:\n    - args (list[int]): A list of integers to be validated.\n\n    Raises:\n    - IndexError: If the list contains fewer than 2 elements.\n    - ValueError: If any element is zero.\n    - NotIntTypeError: If any element is not an integer.\n    \"\"\"\n    if len(args) < 2:\n        raise IndexError(\"Debe haber al menos dos parametros.\")\n    if any(number == 0 for number in args):\n        raise ValueError(\"No puede haber ceros.\")\n    if not all(isinstance(number, int) for number in args):\n        raise NotIntTypeError(\"Todos los parámetros deben ser enteros.\")\n\n\ntry:\n    parameters_multiplication([1, 2, 3, 4])\n    #parameters_multiplication([1])\n    #parameters_multiplication([1, 0, 3])\n    #parameters_multiplication([\"s\", 2.2, 3])\nexcept IndexError as e:\n    print(f\"Ha ocurrido un error. {e}\")\nexcept ValueError as e:\n    print(f\"Ha ocurrido un error. {e}\")\nexcept NotIntTypeError as e:\n    print(f\"Ha ocurrido un error. {e}\")\nexcept Exception as e:\n    print(f\"Se ha producido un error inesperado. {e}\")\nelse:\n    print(\"No ha ocurrido ningun error.\")\nfinally:\n    print(\"El programa se ha ejecutado con exito.\")\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/MirandaYuber.py",
    "content": "print(\"\"\"\nEXCEPCIONES\n\"\"\")\n\ntry:\n    resultado = 10 / 0\nexcept Exception as e:\n    print(e)\n\ntry:\n    languages = ['PHP', 'Python', 'JavaScript']\n    print(languages[3])\nexcept Exception as e:\n    print(e)\n\ntry:\n    suma = number_1 + 1\n    print(suma)\nexcept Exception as e:\n    print(e)\n\ntry:\n    resta = '2' - 1\n    print(resta)\nexcept Exception as e:\n    print(f'Error: {e} ({type(e).__name__})')\n\nprint(\"\"\"\nEXTRA\n\"\"\")\n\n\nclass NegativeNumberError(Exception):\n    pass\n\n\ndef operaciones_aritmeticas(number_1: int, number_2: int, operation: int):\n    if operation == 4 and number_2 == 0:\n        raise ZeroDivisionError()\n    elif operation > 4 or operation < 1:\n        raise ValueError()\n    resultado = 0\n    match operation:\n        case 1:\n            resultado = number_1 + number_2\n        case 2:\n            resultado = number_1 - number_2\n        case 3:\n            resultado = number_1 * number_2\n        case 4:\n            resultado = number_1 / number_2\n\n    if resultado < 0:\n        raise NegativeNumberError('El resultado de la operación ha sido negativo')\n\n    print()\n    print(f'El resultado de la operación es: {resultado}')\n\n\ntry:\n    print(\"\"\"\n    1. Suma\n    2. Resta\n    3. Multiplicación\n    4. División\n    \"\"\")\n    operation = int(input('Ingrese el número corespondiente a la operación que desea resolver: '))\n    number_1 = int(input('Ingrese el primer número: '))\n    number_2 = int(input('Ingrese el segundo número: '))\n\n    operaciones_aritmeticas(number_1, number_2, operation)\n\nexcept ZeroDivisionError as error:\n    print(f'({type(error).__name__}): El número 2 tiene que ser difente de cero cuando quiera dividir')\n\nexcept ValueError as error:\n    print(f'({type(error).__name__}): Debe ingresar un valor correspondiente a las operaciones disponibles')\n\nexcept NegativeNumberError as error:\n    print(f'({type(error).__name__}): {error}')\n\nexcept Exception as error:\n    print(f'({type(error).__name__}): Error inesperado: {error}')\n\nelse:\n    print('El programa se ejecuto sin ningun problema')\n\nfinally:\n    print('El programa finalizo')\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/NeosV.py",
    "content": "\n\ntry:\n print(10/0)\n\nexcept:\n print(\"error\")\n\ntry:\n lista = [1,2,3,4,5]\n print (lista[4])\nexcept Exception as e:\n print(f\"error {e}\")\n\n\n\n\nclass StrError(Exception):\n   pass \n\n\ndef errores(parameters:list):\n    \n   if len(parameters)<3:\n    raise IndexError()\n   elif parameters[1] == 0:\n    raise ZeroDivisionError()\n   elif type(parameters[2]) == str:\n    raise StrError(\"La lista no puede contener cadenas de texto\")\n\n   print(parameters[2])\n   print (parameters[0]/parameters[1])\n   print (parameters[2] + 5)\n   print(parameters[2])\n \n \n \n \n\ntry:\n errores([1,2,\"carro\",4])\nexcept IndexError as e:\n print(\"Se necesitan al menos 3 parametros\")\nexcept ZeroDivisionError as e:\n print(\"El segundo elemento de la lista no puede ser 0\")    \nexcept StrError as e:\n print(f\"{e}\")\nelse:\n print(\"ejecucion terminada sin errores\")\nfinally:\n print(\"ejecucion finalizada\")\n \n\n\n\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/NicoHeguaburu.py",
    "content": "#EXCEPCIONES\n\n\ntry:      \n    print(nico)\nexcept Exception as e:\n    print(f\"SE A PRODUCIDO UN ERROR {e}\")\n\n\n\n#Ejercicio Extra\n\nclass StrTypeError(Exception):\n    pass\n\ndef procesar_parametros(parametros: list):\n\n    if len(parametros) < 4:\n        raise IndexError()\n    elif parametros[1] == 0:\n        raise ZeroDivisionError()\n    elif type(parametros[2]) == str:\n        raise StrTypeError(\"El segundo elemento no puede ser una cadena de texto\")\n    \n\n    print(parametros[4])\n    print(parametros[0]/parametros[1])\n    print(parametros[2] * 10)\n\n\n\n\n\ntry: \n    procesar_parametros([1,0,\"nico\"])\nexcept IndexError as e:\n    print(\"El numero de elementos de la lista tiene que ser mayor a tres.\")\nexcept ZeroDivisionError as e:\n    print(\"El segundo elemento de la lista no puede ser cero.\")\nexcept StrTypeError as e:\n    print(f\"{e}\")\nexcept Exception as e:\n    print(f\"Se a producido un error inesperado: {e}\")\nelse:\n    print(\"No se han producido errores.\")\nfinally:\n    print(\"Se termino el programa\")\n\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/Nicojsuarez2.py",
    "content": "# #10 EXCEPCIONES\n> #### Dificultad: Media | Publicación: 04/03/24 | Corrección: 11/03/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado. \n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/NightAlchemist.py",
    "content": "'''\nExercise\n'''\n\n#exceptions\n\ntry:\n    print(1/0)\nexcept ZeroDivisionError:\n    print(\"You can't divide by zero!\")\nelse:\n    print(\"Something else went wrong.\")\nfinally:\n    print(\"This always runs on success or failure.\")\n    \n#raise exception\n\ntry:\n    raise ValueError(\"This is an argument\")\nexcept ValueError as e:\n    print(e)\n\n#custom exceptions\n\nclass MyCustomError(Exception):\n    def __init__(self, value):\n        self.value = value\n    \n    def __str__(self):\n        return repr(self.value)\n    \ntry:\n    raise MyCustomError(2*2)\nexcept MyCustomError as e:\n    print(\"My exception occurred, value:\", e.value)\n\n'''\nExtra\n'''\n\n# Custom exception\nclass CustomError(Exception):\n    pass\n\n# Function that processes parameters\ndef process_data(value):\n    if not isinstance(value, int):\n        raise TypeError(\"The value must be an integer.\")\n    if value < 0:\n        raise ValueError(\"The value must be non-negative.\")\n    if value == 13:\n        raise CustomError(\"13 is not an allowed value (unlucky number).\")\n    \n    return value * 2  # some basic processing\n\n# Call the function and handle exceptions\ntry:\n    result = process_data(13)  # Try changing this value to test other cases\nexcept Exception as e:\n    print(f\"An error occurred: {type(e).__name__} - {e}\")\nelse:\n    print(f\"Success! The result is: {result}\")\nfinally:\n    print(\"Execution finished.\")\n\n'''\nExamples You Can Try\nprocess_data(\"a string\") → Raises TypeError\nprocess_data(-5) → Raises ValueError\nprocess_data(13) → Raises CustomError\nprocess_data(10) → Success, prints result\n'''"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/Nightblockchain30.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * Explora el concepto de manejo de excepciones según tu lenguaje.\n#  * Fuerza un error en tu código, captura el error, imprime dicho error\n#  * y evita que el programa se detenga de manera inesperada.\n#  * Prueba a dividir \"10/0\" o acceder a un índice no existente\n#  * de un listado para intentar provocar un error.\n#  */\n\n\n\ntry:\n    print(10/0)\nexcept Exception as e:\n    print(f\"Ha ocurrido un error -> {e} | TYPE:{type(e).__name__}\")\n\n\ntry:\n    lista = [1,2,3,4]\n    print(lista[4])\nexcept Exception as e:\n    print(f\"Ha ocurrido un error -> {e} | TYPE:{type(e).__name__}\")\n\n\n\n\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea una función que sea capaz de procesar parámetros, pero que también\n#  * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n#  * corresponderse con un tipo de excepción creada por nosotros de manera\n#  * personalizada, y debe ser lanzada de manera manual) en caso de error.\n#  * - Captura todas las excepciones desde el lugar donde llamas a la función.\n#  * - Imprime el tipo de error.\n#  * - Imprime si no se ha producido ningún error.\n#  * - Imprime que la ejecución ha finalizado. \n\nclass StrTypeError(Exception):\n    pass\n\ndef processParam(parametros: list):\n    if len(parametros) < 3:\n        raise IndexError\n    elif parametros[1] == 0:\n        raise ZeroDivisionError\n    elif type(parametros[2]) == str:\n        raise StrTypeError (\"El tercer elemento no puede ser un string\")\n    \n    print(parametros[2])\n    print(parametros[0]/parametros[1])\n    print(parametros[2] + 5)\n\n\ntry:\n    processParam([1,4,6,5])\nexcept IndexError as e:\n    print(\"El número de elementos no es suficiente \")\nexcept ZeroDivisionError as e:\n    print(f\"Se ha producido un error -> {e} | TYPE:{type(e).__name__}\")\nexcept StrTypeError as e:\n    print(e)\nexcept Exception:\n    print(\"Se ha producido un error general!\")\nelse:\n    print(\"Código correcto!\")\nfinally:\n    print(\"Fin del programa! \")\n    \n\n\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/Paprikaistkrieg.py",
    "content": "#Manejo de Excepciones\n\n\n\"\"\"\nEl manejo de excepciones en Python se realiza utilizando las palabras clave try, except, else y finally.\nEstas palabras clave permiten manejar errores de manera controlada y evitar que el programa se detenga abruptamente.\nel bloque try contiene el código que puede generar una excepción,\nel bloque except contiene el código que maneja la excepción si ocurre,\nel bloque else contiene el código que se ejecuta si no ocurre ninguna excepción,\ny el bloque finally contiene el código que se ejecuta siempre, haya o no una excepción.\n\"\"\"\nfrom operator import index\n\n\ntry:\n    #numero = int(input(\"Ingresa un número: \")) # Solicita al usuario que ingrese un número\n    resultado = 10 / 0 # Intenta dividir 10 por el número ingresado\n    print(f\"El resultado es: {resultado}\") # Imprime el resultado de la división\n    #mi_lista = [1, 2, 3]\n    print(mi_lista[3])  # Esto generará un IndexError\nexcept ValueError: \n    print(\"Error: Debes ingresar un número válido.\") # Maneja el error si el usuario no ingresa un número válido\nexcept ZeroDivisionError: \n    print(\"Error: No se puede dividir por cero.\") # Maneja el error si el usuario ingresa cero\nexcept Exception as e:\n    print(f\"Ocurrió un error inesperado: {e}\")  # Maneja cualquier otro error inesperado\nelse:\n    print(\"La operación se realizó con éxito.\")  # Se ejecuta si no hubo ninguna excepción\nfinally:\n    print(\"Gracias por usar el programa.\")  # Se ejecuta siempre, haya o no una excepción. Se usa para liberar recursos o realizar tareas de limpieza.\n\n#El bloque finally se ejecuta siempre, haya o no una excepción. Se usa para liberar recursos o realizar tareas de limpieza.\n\n\n\n#XTRAJ\n\nclass StringTypeError(Exception):\n    \"\"\"Excepción personalizada para errores de tipo de cadena.\"\"\"\n    pass\n\ndef process_params(params: list):\n    try:\n        if len(params) < 3:\n            raise IndexError()   # Lanza una excepción si la lista tiene menos de 3 elementos\n        if params[1] == 0:\n            raise ZeroDivisionError()  # Lanza una excepción si el segundo elemento es cero\n        elif type(params[1]) is str:\n            raise StringTypeError(\"el segundo elemento debe ser un número.\")  # Lanza una excepción si el segundo elemento es una cadena\n        print(params[2])  # Imprime el tercer parámetro\n        print(params[0]/params[1])\n        print(params[2] + 5)\n        print(params[4])  # Intenta acceder al quinto elemento de la lista\n    except IndexError as quote:\n        print(\"El número de parámetros debe ser mayor que 3.\")  # Maneja cualquier error que ocurra al acceder al elemento\n    except ZeroDivisionError as zde:\n        print(\"No se puede dividir por cero en el segundo parámetro.\")  # Maneja el error de división por cero\n    except StringTypeError as ste:\n        print(f\"Error: {ste}\")  # Maneja el error de tipo de cadena personalizado\n    except Exception as e:\n        print(f\"Ocurrió un error inesperado: {e}\")\n    else:\n        print(\"Los parámetros se procesaron correctamente.(esto indica que no hubo excepciones o errores)\")  # Se ejecuta si no hubo ninguna excepción\n    finally:\n        print(\"El programa finalizó correctamente.\")  # Se ejecuta siempre, haya o no una excepción. Se usa para liberar recursos o realizar tareas de limpieza.\n\nprocess_params([1, 2, 3, 4, 5])  # Llama a la función con una lista de parámetros válida"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/Paula2409.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado. \n */\n\"\"\"\n\nmy_list = [0,2,6]\n# Try / Except: el programa continua\ntry:\n    my_list[1]/my_list[0]\nexcept ZeroDivisionError as error:\n    print(f\"Error: {error}\")\n# Else: se ejecuta si no hubo error\nelse:\n    print('La division se pudo calcular')\n# Finally: se ejecuta sin importar si hubo o no error\nfinally:\n    print('Programa terminado')\n\ntry:\n    print(my_list[3])\nexcept IndexError:\n    print('No existe ese indice')\n    \n# Raise: el programa se detiene\n# if my_list[0] != 0:\n#     my_list[1]/my_list[0]\n# else:\n#     raise ZeroDivisionError('No se puede dividir por 0')\n\n# if len(my_list) > 3:\n#     print(my_list[3])\n# else:\n#     raise IndexError\n\n# Uso de Exception: clase base de excepciones. Identifica el error por si solo\ntry:\n    print(my_list[3])\nexcept Exception as error:\n    print(f'Error con clase Exception: {error}')\n\n# Jerarquia de clases\nprint(ZeroDivisionError.mro())\n\n# Assert: chequea si una condicion se cumple. Si no es asi, el programa se detiene\na = 10\nb = 15\nassert a+b > 20, 'El resultado debe ser menor a 20'\n\nclass IncorrectType(Exception):\n    def __init__(self, message='Valor incorrecto, ingrese un numero'):\n        self.message = message\n        super().__init__(self.message)\n        \ndef division(a,b):\n    if type(a) != int or type(b) != int:\n        raise IncorrectType()\n    elif b == 0:\n        raise ZeroDivisionError()\n    elif a == '' or b == '':\n        raise TypeError()\n    else:\n        return a/b\n\ntry:\n    dividir = division(5,4)\nexcept IncorrectType as error:\n    print(f'Error propio: {error}')\nexcept ZeroDivisionError as error:\n    print(f'Tipo de error: {type(error)}: {error}')\nexcept TypeError as error:\n    print(f'Tipo de error: {type(error)}: {error}')\nelse:\n    print('La division se pudo realizar')\n    print(dividir)\n\nfinally:\n    print('El programa termino')\n    \n    \n    "
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/RicardiJulio.py",
    "content": "#  * EJERCICIO:\n#  * Explora el concepto de manejo de excepciones según tu lenguaje.\n#  * Fuerza un error en tu código, captura el error, imprime dicho error\n#  * y evita que el programa se detenga de manera inesperada.\n#  * Prueba a dividir \"10/0\" o acceder a un índice no existente\n#  * de un listado para intentar provocar un error.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea una función que sea capaz de procesar parámetros, pero que también\n#  * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n#  * corresponderse con un tipo de excepción creada por nosotros de manera\n#  * personalizada, y debe ser lanzada de manera manual) en caso de error.\n#  * - Captura todas las excepciones desde el lugar donde llamas a la función.\n#  * - Imprime el tipo de error.\n#  * - Imprime si no se ha producido ningún error.\n#  * - Imprime que la ejecución ha finalizado.\n\na = 10\nb = 2\n\ntry:\n    c = a/b\nexcept Exception as ex:\n    print('Ha ocurrido un error del tipo', type(ex))\n    \nlista = [1,2,3]\n\ntry:\n    print(f'{lista[2]}')\nexcept Exception as ex:\n    print('Ha ocurrido un error del tipo', type(ex))\n\n# DIFICULTAD EXTRA:\n\nclass MiExcepion(Exception):\n    \"\"\"Mi excepcion se lanza si una operacion es mayor o igual a 1000\"\"\"\n    def __init__(self,resultado):\n        self.resultado = resultado\n        self.mensaje = f'MiExcepcion {resultado}'\n        super().__init__(self.mensaje)\n        \ndef multiplicar(a,b):\n    resultado = a*b\n    if resultado >= 1000:\n        raise MiExcepion(resultado)\n    return resultado\n\ndef manejo_excepciones(a,b):\n    try:\n        resm = multiplicar(a,b)\n        print(resm)\n        resd = a/b\n        print(resd)\n    except MiExcepion as ex:\n        print(f'Ha ocurrido {ex}')\n    except ZeroDivisionError as ex:\n        print(f'Ha ocurrido {ex}')\n    except TypeError as ex:\n        print(f'Ha ocurrido {ex}')\n    else:\n        print('No ha ocurrido ningun error.')\n    finally:\n        print('Ha terminado la ejecucion.')\n\nmanejo_excepciones(100,2)\nmanejo_excepciones(100,12)\nmanejo_excepciones(10,0)\nmanejo_excepciones(15,'20')\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/Sac-Corts.py",
    "content": "### Ejercicio ###\n\n# Try | Except | Finally\n\ntry:\n    numero1 = int(input(\"Introduce un número: \"))\n    numero2 = int(input(\"Introduce un número: \"))\n    resultado = numero1 + numero2\n    print(resultado)\nexcept:\n    print(\"Solamente puedes ingresar números enteros.\")\nfinally:\n    print(\"Saludos\")\n\n\n### Ejercicio Extra ###\n\n# Definir la excepción personalizada\nclass CustomException(Exception):\n    def __init__(self, message):\n        self.message = message\n        super().__init__(self.message)\n\n# Definir la función que puede lanzar excepciones\ndef procesar_parametros(param):\n    if not isinstance(param, int):\n        raise TypeError(\"El parámetro debe ser un entero\")\n    elif param < 0:\n        raise ValueError(\"El parámetro no puede ser negativo\")\n    elif param == 42:\n        raise CustomException(\"El parámetro no puede ser 42\")\n    else:\n        return f\"El parámetro es {param}\"\n\n# Capturar las excepciones desde el lugar donde se llama a la función\ndef main():\n    parametros = [10, -5, \"string\", 42, 15]\n    \n    for param in parametros:\n        try:\n            resultado = procesar_parametros(param)\n            print(resultado)\n        except TypeError as e:\n            print(f\"Se ha producido un TypeError: {e}\")\n        except ValueError as e:\n            print(f\"Se ha producido un ValueError: {e}\")\n        except CustomException as e:\n            print(f\"Se ha producido una CustomException: {e}\")\n        except Exception as e:\n            print(f\"Se ha producido una excepción inesperada: {e}\")\n        else:\n            print(\"No se ha producido ningún error\")\n        finally:\n            print(\"La ejecución ha finalizado para el parámetro actual\")\n\nprint(main())"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/SaezMD.py",
    "content": "#10 Excepciones\n\"\"\"\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente de un listado para intentar provocar un error.\n \n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado.\n\"\"\"\n#Global exception\ntry: \n    print(10/0)\nexcept Exception as e:\n    print(e)\n\n#handling exceptions in Python\n\ncolors = ['red', 'green', 'blue']\ntry:\n    print(colors[3])\nexcept IndexError as e:\n    print(e)\n    print(f\"There is an error: {e} ({type(e).__name__})\")\n\nprint('Continue to run')\n\n# 2 exceptions in the same line:\nimport math\nx = 1\ny = -2\n \ntry:\n    value = x / y\n    print(math.log(value))\nexcept (ZeroDivisionError, ValueError) as e:\n    print('Got an error:', e)\n\n#Without using except:\n\ndef linux_interaction():\n    import sys\n    if \"linux\" not in sys.platform:\n        #raise RuntimeError(\"Function can only run on Linux systems.\")\n        print('raise RuntimeError(\"Function can only run on Linux systems.\")')\n    print(\"Doing Linux things.\")\n\nlinux_interaction()\n\n#Divide by 0\n(x,y) = (10,0)\n\ntry:\n    z = x/y\n    print(z)\n\nexcept ZeroDivisionError as e:\n    print(f\"divide by zero. Error: {e}\")\nfinally:\n    print(\"let's go\")\n\n\n#Extra\n#type of errors: by 0, negative, not a number\n\n# define Python user-defined exceptions\nclass InvalidNumber(Exception):\n    \"Raised when the value is between 2 and 10\"\n    pass\n\ndef handlingErrors(number1: int, number2: int)-> int:\n    \"\"\"\"function to handle exceptions\"\"\"\n\n    try:\n        solution = number1 / number2\n        if solution <10 and solution >2:\n            raise InvalidNumber\n\n    except ZeroDivisionError:\n        print(\"Impossible to divide by 0.\")\n\n    except IndexError:\n        print(\"Out of place.\")\n\n    except InvalidNumber:\n        print(\"Number not OK.\")\n\n\n    else:\n        print(\"No errors found.\")\n    finally:\n        print(\"Check errors mode off.\")\n\nhandlingErrors(22,2)\n\n\nclass StrTypeException(Exception):\n    pass\n\ndef process_params(parameters: list):\n\n    if len(parameters) < 3:\n        raise IndexError()\n    elif parameters[1] == 0:\n        raise ZeroDivisionError()\n    elif type(parameters[2]) == str:\n        raise StrTypeException(\"The third element of the list can't be a text string.\")\n\n    print(parameters[2])\n    print(parameters[0]/parameters[1])\n    print(parameters[2]+ 5)\n\ntry:\n    process_params([1,2,9,3])\nexcept IndexError as e:\n    print(\"There is an error in the index.\")\nexcept ZeroDivisionError as e:\n    print(\"The second element of the list can't be a 0.\")\nexcept StrTypeException as e:\n    print(e)\nexcept Exception as e:\n    print(f\"Unexpected error! {e}\")\nelse:\n    print(\"No errors found.\")\nfinally:\n    print(\"Program finished OK.\")\n\n\n\n\n\n\n    \n\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/SergioGI99.py",
    "content": "\"\"\"\n-----------\nEXCEPCIONES\n-----------\nEJERCICIO:\nExplora el concepto de manejo de excepciones según tu lenguaje.\nFuerza un error en tu código, captura el error, imprime dicho error\ny evita que el programa se detenga de manera inesperada.\nPrueba a dividir \"10/0\" o acceder a un índice no existente\nde un listado para intentar provocar un error.\n\nDIFICULTAD EXTRA (opcional):\nCrea una función que sea capaz de procesar parámetros, pero que también\npueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\ncorresponderse con un tipo de excepción creada por nosotros de manera\npersonalizada, y debe ser lanzada de manera manual) en caso de error.\n- Captura todas las excepciones desde el lugar donde llamas a la función.\n- Imprime el tipo de error.\n- Imprime si no se ha producido ningún error.\n- Imprime que la ejecución ha finalizado.\n\"\"\"\n\n# Ejercicio\n\nx = 10\ny = 0\n\ntry:\n    z = x / y\nexcept Exception as e:\n    print(f\"Error:{e}\")\n\nprint(\"Hello\")\n    \n# Extra\n\ninp_one = input(\"First input: \")\ninp_two = input(\"Second input: \")\n\nclass MissingInputError(Exception):\n    def __init__(self, info):\n        self.info = info\n\ndef div(x_val, y_val):\n    \n    if x_val == \"\" or y_val == \"\":\n        raise MissingInputError(\"Missing Input\")\n    else:\n        x_val = float(x_val)\n        y_val = float(y_val)\n        result = (f\"{x_val} / {y_val} = {x_val / y_val}\")\n        print(result)\n\ntry:\n    div(inp_one, inp_two)\nexcept Exception as error:\n    print(f\"Error:{error}({type(error).__name__})\")\nelse:\n    print(\"No se ha producido ningún error\")\nfinally:\n    print(\"Final de ejecución\")"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/SooHav.py",
    "content": "# 10 Excepciones\n\n# Ejercicio\n\nfrom datetime import datetime\na = [\"hola\", 7, 2, 3, 6]\nb = []\nc = [7, 2, 3, 6]\n\n\ndef calculos(lista, operacion):\n    if operacion == \"media\":\n        try:\n            media = sum(lista) / len(lista)\n            return media\n        except Exception as e:\n            return f\"Ha habido una excepción: {e}\"\n    elif operacion == \"conteo\":\n        try:\n            contar = len(lista)\n            return contar\n        except Exception as e:\n            return f\"Ha habido una excepción: {e}\"\n    elif operacion == \"division\":\n        try:\n            dividir = len(lista)/lista[4]\n            return dividir\n        except Exception as e:\n            return f\"Ha habido una excepción: {e}\"\n    else:\n        return \"Operación no válida.\"\n\n\nresultado_media_a = calculos(a, \"media\")\nresultado_media_b = calculos(b, \"media\")\nresultado_media_c = calculos(c, \"media\")\n\nresultado_conteo_a = calculos(a, \"conteo\")\nresultado_conteo_b = calculos(b, \"conteo\")\nresultado_conteo_c = calculos(c, \"conteo\")\n\nresultado_division_a = calculos(a, \"division\")\nresultado_division_b = calculos(b, \"division\")\nresultado_division_c = calculos(c, \"division\")\n\nprint(f\"Resultado media a: {resultado_media_a}\")\nprint(f\"Resultado media b: {resultado_media_b}\")\nprint(f\"Resultado media c: {resultado_media_c}\")\n\nprint(f\"Resultado conteo a: {resultado_conteo_a}\")\nprint(f\"Resultado conteo b: {resultado_conteo_b}\")\nprint(f\"Resultado conteo c: {resultado_conteo_c}\")\n\nprint(f\"Resultado division a: {resultado_division_a}\")\nprint(f\"Resultado division b: {resultado_division_b}\")\nprint(f\"Resultado division c: {resultado_division_c}\")\n\n\n# Dificultad Extra\n\nclass PresionArterialError(Exception):\n    pass\n\n\ndef registro_presion_arterial():\n    datos = {}\n    while True:\n        try:\n\n            paciente_id = input(\"ID del paciente: \")\n            if not paciente_id.isdigit():\n                raise TypeError(\"El ID debe ser un número\")\n\n            datos['paciente'] = int(paciente_id)\n            fecha_str = input(\"Fecha (dd-mm-yyyy): \")\n            datos['fecha'] = datetime.strptime(fecha_str, \"%d-%m-%Y\")\n\n            datos['presion_alta'] = int(input(\"Presión arterial alta: \"))\n            if datos['presion_alta'] < 50 or datos['presion_alta'] > 240:\n                raise ValueError(\n                    \"Error en el registro del dato de presion alta\")\n\n            datos['presion_baja'] = int(input(\"Presión arterial baja: \"))\n            if datos['presion_baja'] < 45 or datos['presion_baja'] > 120:\n                raise PresionArterialError(\n                    \"La presión arterial baja debe estar entre 45 y 120\")\n            break\n        except (ValueError, PresionArterialError, TypeError) as e:\n            print(f\"{type(e).__name__}: {e}. Intente nuevamente.\")\n    print(\"Carga de datos finalizada.\")\n    return datos\n\n\ntry:\n    datos = registro_presion_arterial()\n    print(\"\\nDatos del paciente:\")\n    print(f\"ID: {datos['paciente']}\")\n    print(f\"Fecha de la toma: {datos['fecha'].strftime('%d-%m-%Y')}\")\n    print(f\"Presión arterial alta: {datos['presion_alta']}\")\n    print(f\"Presión arterial baja: {datos['presion_baja']}\")\n    print(\"No se ha producido ningún error.\")\nexcept Exception as e:\n    print(f\"{type(e).__name__}: {e}.\")\nfinally:\n    print(\"La ejecución ha finalizado.\")\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/Tomu98.py",
    "content": "\"\"\" Reto 10: Excepciones \"\"\"\n\ntry:\n    print(10/1)\n    print([1, 2, 3, 4][4])\nexcept Exception as e:\n    print(f\"Se ha producido un error: {e}\")\n\n\n\n\"\"\" Reto extra \"\"\"\n\nclass StrTypeError(Exception):\n    pass\n\ndef process_params(parameters: list):\n    if len(parameters) < 3:\n        raise IndexError()\n    elif parameters[1] == 0:\n        raise ZeroDivisionError()\n    elif type(parameters[2]) == str:\n        raise StrTypeError(\"El tercer elemento no puede ser una cadena de texto.\")\n\n    print(parameters[2])\n    print(parameters[0]/parameters[1])\n    print(parameters[2] + 5)\n\ntry:\n    process_params([1, 2, 3, 4])\nexcept IndexError as e:\n    print(\"El número de elementos de la lista debe ser mayor que dos.\")\nexcept ZeroDivisionError as e:\n    print(\"El segundo elemento de la lista no puede ser un cero.\")\nexcept StrTypeError as e:\n    print(f\"{e}\")\nexcept Exception as e:\n    print(f\"Se ha producido un error inesperado: {e}\")\nelse:\n    print(\"No se ha producido ningún error.\")\nfinally:\n    print(\"El programa finaliza\")\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/Zequy40.py",
    "content": "'''\n*EJERCICIO:\n* Explora el concepto de manejo de excepciones según tu lenguaje.\n* Fuerza un error en tu código, captura el error, imprime dicho error\n* y evita que el programa se detenga de manera inesperada.\n* Prueba a dividir \"10/0\" o acceder a un índice no existente\n* de un listado para intentar provocar un error.\n'''\n#Distinto a otros lenguajes que utilizan Try Catch, en Python se usa try except:\n\ntry:\n    # Intentar dividir por cero\n    resultado = 10 / 0\nexcept ZeroDivisionError as e:\n    # Capturar la excepción ZeroDivisionError\n    print(f\"Error: {e}\")\n    resultado = None\n\nprint(\"Después de la excepción. Resultado:\", resultado)\n\n# Intentar acceder a un índice no existente en una lista\nlista = [1, 2, 3]\ntry:\n    elemento = lista[10]\nexcept IndexError as e:\n    # Capturar la excepción IndexError\n    print(f\"Error: {e}\")\n    elemento = None\n\nprint(\"Después de la excepción. Elemento:\", elemento)\n\n\n#Cada bloque except captura la excepción correspondiente, imprime el error y, en este caso, asigna un valor predeterminado es un variable despues del error\n#para que se pueda asignar otro valor (None) para evitar que el programa se detenga abruptamente.\n\n'''\nDIFICULTAD EXTRA:\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado.\n '''\n# Definir una excepción personalizada\nclass MiExcepcionPersonalizada(Exception):\n    pass #Se utiliza pass una funcion en Python que permite que no haga nada, en este paso.\n\ndef procesar_parametros(parametro):\n    try:\n        # Procesar parámetros y lanzar excepciones\n        if not isinstance(parametro, int):\n            raise TypeError(\"El parámetro debe ser un entero\")\n        \n        if parametro == 0:\n            raise ValueError(\"El parámetro no puede ser cero\")\n        \n        if parametro < 0:\n            raise MiExcepcionPersonalizada(\"El parámetro no puede ser negativo\")\n\n        # Simular procesamiento con éxito\n        resultado = parametro * 2\n        print(\"Resultado del procesamiento:\", resultado)\n\n    except TypeError as e:\n        print(f\"Error de tipo: {e}\")\n\n    except ValueError as e:\n        print(f\"Error de valor: {e}\")\n\n    except MiExcepcionPersonalizada as e:\n        print(f\"Error personalizado: {e}\")\n\n    except Exception as e:\n        print(f\"Error inesperado: {e}\")\n\n    finally:\n        print(\"Ejecución finalizada\")\n\n# Ejemplo de uso\ntry:\n    procesar_parametros(5)\n    procesar_parametros(\"cadena\")  # Provocará un TypeError\n    procesar_parametros(0)         # Provocará un ValueError\n    procesar_parametros(-1)        # Provocará un MiExcepcionPersonalizada\n\nexcept Exception as e:\n    print(f\"Se ha producido un error general: {e}\")\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/adolfolozaa.py",
    "content": "'''\r\nEJERCICIO:\r\n * Explora el concepto de herencia según tu lenguaje. Crea un ejemplo que\r\n * implemente una superclase Animal y un par de subclases Perro y Gato,\r\n * junto con una función que sirva para imprimir el sonido que emite cada Animal.\r\n *\r\n * DIFICULTAD EXTRA (opcional):\r\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que\r\n * pueden ser Gerentes, Gerentes de Proyectos o Programadores.\r\n * Cada empleado tiene un identificador y un nombre.\r\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su\r\n * actividad, y almacenan los empleados a su cargo.\r\n '''\r\n\r\nclass Animal:\r\n    def __init__(self, name: str):\r\n        self.name = name\r\n\r\n    def sound(self):\r\n        pass\r\n    def __repr__(self):\r\n        return str(self.__dict__)\r\n\r\nclass Perro(Animal):\r\n    def __init__(self, name: str, age: int, race:str):\r\n        super().__init__(name)\r\n        self.race = race\r\n        self.age = age\r\n\r\n    def sound(self):\r\n        print('Guau')\r\n    \r\nclass Gato(Animal):\r\n    def __init__(self, name: str, age: int, race: str):\r\n        super().__init__(name)\r\n        self.race = race\r\n        self.age = age\r\n\r\n    def sound(self):\r\n        print('Miau')\r\n\r\n\r\ndef print_sound(animal: Animal):\r\n    animal.sound()\r\n\r\nanimal = Animal('Fede')\r\nperro = Perro('Firulais', 5, 'Pastor Aleman')\r\ngato = Gato('Garfield', 3, 'Siames')\r\n\r\nprint(animal.name)\r\nprint_sound(perro)\r\nprint_sound(gato)\r\nprint(perro.name)\r\nprint(gato)\r\n\r\n\r\n'''\r\n * DIFICULTAD EXTRA (opcional):\r\n * Implementa la jerarquía de una empresa de desarrollo formada por Empleados que pueden ser Gerentes, Gerentes de Proyectos o Programadores.\r\n * Cada empleado tiene un identificador y un nombre.\r\n * Dependiendo de su labor, tienen propiedades y funciones exclusivas de su actividad, y almacenan los empleados a su cargo.\r\n '''\r\n\r\nclass Empleado:\r\n    def __init__(self, id: int, name: str):\r\n        self.id = id\r\n        self.name = name\r\n        self.employees = []\r\n    def __repr__(self):\r\n        return str(self.__dict__)\r\n    def add(self, employee):\r\n        self.employees.append(employee)\r\n\r\n    def print_employees(self):\r\n        for employee in self.employees:\r\n            print(f'los empleados de {employee.name} son: {employee}')\r\n\r\n\r\nclass Gerente(Empleado):\r\n    def __init__(self, id: int, name: str, area: str):\r\n        super().__init__(id, name)\r\n        self.area = area\r\n\r\n    def coordinate_areas(self):\r\n        print(f'{self.name} esta coordinando las areas {self.area}')\r\n\r\nclass Ger_Proyectos(Empleado):\r\n    def __init__(self, id: int, name: str, project: str):\r\n        super().__init__(id, name)\r\n        self.project = project\r\n\r\n    def coordinate_project(self):\r\n        print(f'{self.name} esta coordinando el proyecto {self.project}')\r\n\r\nclass Programador(Empleado):\r\n    def __init__(self, id: int, name: str, languages: list):\r\n        super().__init__(id, name)\r\n        self.languages = languages\r\n\r\n    def print_languages(self):\r\n        print(f'{self.name} sabe los siguientes lenguajes: {self.languages}')\r\n    def add(self, employee):\r\n        print(f'Un programador no tiene empleados a su cargo. {employee.name} no se añadirá.')\r\n\r\np1 = Programador(1, 'Adolfo', ['Python', 'Java', 'C++'])\r\np2 = Programador(2, 'Pedro', ['Rust', 'Javascript', 'Basic'])\r\np3 = Programador(3, 'Juan', ['C#', 'Ruby', 'Go'])\r\np4 = Programador(4, 'Maria', ['PHP', 'Swift', 'Kotlin'])\r\ng = Gerente(3, 'Juan', 'Gerencia')\r\nproj1 = Ger_Proyectos(4, 'Maria', 'Proyecto 1')\r\nproj2 = Ger_Proyectos(5, 'Carlos', 'Proyecto 2')\r\nprint(p1.name)\r\nprint(p2.name)\r\nprint(g.name)\r\nprint(proj1.name)\r\np1.print_languages()\r\ng.coordinate_areas()\r\nproj1.coordinate_project()\r\nprint(p1)\r\nprint(p2)\r\nprint(g)\r\nprint(proj1)\r\nproj1.add(p1)\r\nproj1.add(p2)\r\nproj2.add(p3)\r\ng.add(proj1)\r\ng.add(proj2) \r\n\r\ng.print_employees()\r\nproj1.print_employees()\r\nproj2.print_employees()\r\n\r\n\r\n'''\r\n * DIFICULTAD EXTRA (opcional):\r\n * Implementa dos clases que representen las estructuras de Pila y Cola (estudiadas\r\n * en el ejercicio número 7 de la ruta de estudio)\r\n * - Deben poder inicializarse y disponer de operaciones para añadir, eliminar, retornar el número de elementos e imprimir todo su contenido.\r\n '''\r\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/adra-dev.py",
    "content": "\"\"\"\nEJERCICIO:\nExplora el concepto de manejo de excepciones según tu lenguaje.\nFuerza un error en tu código, captura el error, imprime dicho error\ny evita que el programa se detenga de manera inesperada.\nPrueba a dividir \"10/0\" o acceder a un índice no existente\nde un listado para intentar provocar un error.\n\nDIFICULTAD EXTRA (opcional):\nCrea una función que sea capaz de procesar parámetros, pero que también\npueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\ncorresponderse con un tipo de excepción creada por nosotros de manera\npersonalizada, y debe ser lanzada de manera manual) en caso de error.\n- Captura todas las excepciones desde el lugar donde llamas a la función.\n- Imprime el tipo de error.\n- Imprime si no se ha producido ningún error.\n- Imprime que la ejecución ha finalizado.\n\"\"\"\n\n\"\"\"\nExcepciones:\n\nUna excepcion es un error logico que se produce en tiempo de ejecucion.\nLas exepciones van asociadas a distintos tipos, y ese mismo tipo es el \nque se muestra en el mensaje de error.  Todo esto para disponer de \ninformacion suficiente para encontrar el fallo y solucionalro o gestionarlo.\nAlgunos ejemplos son \n    * ZeroDivisionError\n    * NameError\n    * TypeError\n\"\"\"\n\n# a = 0 \n# b = 10 \n# c = b/a\n# print(c)\n\n# a = []\n# print(a[10])\n\n\n\"\"\"\nGestion de excepciones:\n\nLa gestion de excepciones es una tecnica de programacion para \ncontrolar los errores producidos durante la ejecucion de una \naplicacion. Se controlan de una forma parecida a una sentencia \ncondicional. Si no se produce una excepcion (general o especifica), \nque seria el caso normal, la aplicacion continua con las siguientes \ninstrucciones y si se produce una, se ejecutaran las instrucciones \nindicadas por el desarrollador para su tratamiento, que pueden \ncontinuar la aplicacion o detenerla, dependiendo de cada caso.\n\"\"\"\n\ntry:\n    print(10/0)\n    print([1, 2, 3, 4][4])\nexcept Exception as e:\n    print(f\"Se ha producido un error: {e} ({type(e).__name__})\")\n\n\"\"\"\nExtra\n\"\"\"\n\nclass StrTypeError(Exception):\n    pass\n\n\ndef process_params(parameters: list):\n\n    if len(parameters) < 3:\n        raise IndexError()\n    elif parameters[1] == 0:\n        raise ZeroDivisionError()\n    elif type(parameters[2]) == str:\n        raise StrTypeError(\n            \"El tercer elemento no puede ser una cadena de texto.\")\n\n    print(parameters[2])\n    print(parameters[0]/parameters[1])\n    print(parameters[2] + 5)\n\n\ntry:\n    process_params([1, 2, 3, 4])\nexcept IndexError as e:\n    print(\"El número de elementos de la lista debe ser mayor que dos.\")\nexcept ZeroDivisionError as e:\n    print(\"El segundo elemento de la lista no puede ser un cero.\")\nexcept StrTypeError as e:\n    print(f\"{e}\")\nexcept Exception as e:\n    print(f\"Se ha producido un error inesperado: {e}\")\nelse:\n    print(\"No se ha producido ningún error.\")\nfinally:\n    print(\"El programa finaliza sin detenerse.\")"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/agusrosero.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado. \n */\n\"\"\"\n\n# EJERCICIO:\n\nwhile True:\n    try:\n        num1 = int(input('Ingrese un numero: '))\n        num2 = int(input('Ingrese otro numero: '))\n        print(f'{num1} dividido entre {num2} es {num1 / num2}')\n    except ZeroDivisionError as e:\n        print(f'No se puede dividir por cero: {e}, intente de nuevo.')\n\n# DIFICULTAD EXTRA:\n\n\nclass MiException(Exception):\n    def __init__(self, msj):\n        self.msj = msj\n\n\ndef procesar_parametros(param1):\n    if param1 == 1:\n        raise IndexError\n    elif param1 == '':\n        raise TypeError\n    elif param1 < 0:\n        raise ValueError\n    elif param1 == 23:\n        raise MiException('El parametro no puede ser \"23\"')\n\n\ntry:\n    procesar_parametros(23)\nexcept IndexError:\n    print('El parametro debe ser diferente de 1')\nexcept TypeError:\n    print('El parametro no debe ser un string')\nexcept ValueError:\n    print('El parametro no debe ser negativo')\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/alanshakir.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado. \n */\n\"\"\"\n\n#SyntaxError: error de sintaxis\n\n#Excepciones\n\n#ZeroDivisionError\n#NameError\n#TypeError\n#ValueError\n#RuntimeError\n\"\"\"\nFormato de las excepciones:\n    try:\n    \n    except:\n    \n    else:\n    \n    finally:\n    try y except son primordiales\n    else y finally no son tan necesarios, va a depender de lo que se esta buscando\n\"\"\"\n\n#ValueError\nwhile True:\n    try: \n        my_variable = int(input(\"introduzca un valor numerico: \"))\n        break\n    except ValueError:\n        print(\"No ha ingresado un valor numerico\")\n\n#ZeroDivisionError, TypeError, NameError\ntry: \n    my_variable = 10/0\n    #my_variable = 10 + \"20\" #si descomentas ingresa al TypeError\n    #my_variable = 20 + name*2 #si descomentas ingresa al NameError\n    #my_variable_list = [5, 26, \"hola\", \"python\", \"retos programacion\"] #si descomentas ingresa al IndexError\n    #print(my_variable_list[5]) #si descomentas ingresa al IndexError\nexcept ZeroDivisionError:\n    print(\"No se puede dividir entre cero\")\nexcept TypeError:\n    print(\"El tipo de datos no son correctos\")\nexcept NameError:\n    print(\"variable no esta definida\")\nexcept IndexError:\n    print(\"El indice esta fuera de rango\")\n\n#captura el error\ntry:\n    my_variable = 25\n    my_variable_two = \"20\"\n    print(my_variable - my_variable_two)\nexcept Exception as error:\n    print(\"Se ha producido un error: \", type(error))\n\n\n#Extra\n\nclass ErrorPersonalizado(Exception):\n    pass\n\n\n\ndef manejo_except(my_list_param: list):\n    \n    if my_list_param[1] == 0:\n        raise ZeroDivisionError(\"El segundo valor no puede ser Cero(0)\")\n    elif len(my_list_param) < 3:\n        raise IndexError(\"La lista debe contener mas de 3 elementos\")\n    else:\n        if type(my_list_param[0]) == str or type(my_list_param[1]) == str or type(my_list_param[2]) == str:\n                raise ErrorPersonalizado(\"Debe ser una lista numerica\")\n                \n      \ntry:\n    manejo_except([2 , 6, 5])\nexcept Exception as error:\n    print(\"Ha ocurrido un error de tipo: \", type(error))\nelse:\n    print(\"No se ha producido ningun error, la ejecucion continua\")\nfinally:\n    print(\"La ejecucion a finalizado\")\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/alexdevrep.py",
    "content": "'''\n/*\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado.\n */\n'''\n\n#Declaramos las variables necesarias\nnumero1 = 10\nnumero2 = 0\nlistado= [\"Hola\",\"Python\",\"Alexdevrep\",\"Mundo\"]\n\n#División\n\ndef dividir(numero1, numero2):\n    try:\n        resultado = numero1 / numero2\n        print(resultado)\n\n    except ZeroDivisionError: # En este bloque indicamos el error que queremos que capture el programa\n        print(\"No se puede dividir un número por cero\")\n\n    finally:\n        print(\"Finalizando el programa\")\n\ndividir(numero1, numero2)\n\n#Listado\n\ndef iterarLista():\n    try:\n        #Intentamos acceder a un índice que no existe\n        print(listado[6])\n    except:\n        print(\"Índice no existente en la lista\")\n    finally:\n        print(\"Programa finalizado\")\n\niterarLista()\n\n#Dificultad EXTRA\n\n#Vamos a crear una función que multiplique un número natural de una cifra por 5\n\nclass NoneException(Exception):\n    pass #Creamos una excepcion personalizada\n\ndef multiplo(numero3):\n    try:\n        \n        if numero3 is None:\n            raise NoneException(\"Es necesario dar un número para multiplicar\") #Generamos manualmente la excepcion con raise\n        elif 9 < numero3 < 100:\n            raise Exception(\"El número tiene 2 cifras.\")\n        elif numero3 < 0:\n            raise ValueError(\"El número es negativo, no se puede multiplicar.\")\n        else:\n            producto = 5 * numero3\n            print(producto)\n\n    except ValueError as e:\n        print(f'Error: {e}')\n    except NoneException as e:\n        print(f'Error: {e}')\n    except Exception as e:\n        print(f\"Error: {e}\")\n    \n    finally:\n        print(\"Cerrando el programa\")\n\n\nentrada = input(\"Por favor ingrese el número a multiplicar: \")\nnumero3= int(entrada) if entrada else None\nmultiplo(numero3)\n\n\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/any7dev.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * Explora el concepto de manejo de excepciones según tu lenguaje.\n#  * Fuerza un error en tu código, captura el error, imprime dicho error\n#  * y evita que el programa se detenga de manera inesperada.\n#  * Prueba a dividir \"10/0\" o acceder a un índice no existente\n#  * de un listado para intentar provocar un error.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea una función que sea capaz de procesar parámetros, pero que también\n#  * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n#  * corresponderse con un tipo de excepción creada por nosotros de manera\n#  * personalizada, y debe ser lanzada de manera manual) en caso de error.\n#  * - Captura todas las excepciones desde el lugar donde llamas a la función.\n#  * - Imprime el tipo de error.\n#  * - Imprime si no se ha producido ningún error.\n#  * - Imprime que la ejecución ha finalizado. \n#  */\n\n#EJERCICIO\ntry:\n    print(10/0)\nexcept ZeroDivisionError:\n    print(\"No se puede dividir por 0\")\n\nlista = [1, 2, 3, 4, 5]\ntry:\n    print(lista[6])\nexcept IndexError:\n    print(\"No existe dicho índice\")\n\n\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/avcenal.py",
    "content": "\"\"\"\n* EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n\"\"\"\ndef index_exception():\n    try:\n        result = 10/0\n    except ZeroDivisionError as error:\n        print(f\"Vaya parece que ha habido un error del tipo \\\"{error}\\\"\")\n    else:\n        print(f\"El resultado es {result}\")\n\nindex_exception()\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado.\n\"\"\"\n\nclass MyException(Exception):\n    pass\n\ndef exception_function(item_1,item_2,item_3):\n    if item_1 == 1:\n        raise IndexError\n    elif item_3> 5:\n        raise TypeError\n    elif type(item_2) == str:\n        raise MyException(\"Esta es mi excepción personalizada\")\n    \ntry:\n    exception_function(2,\"alex\",5)\nexcept TypeError as error :\n    print(f\"La función ha dado un \\\"{error}\\\"\")\nexcept ValueError as error:\n    print(f\"La función ha dado un \\\"{error}\\\"\")\nexcept MyException as error:\n    print(f\"{error}\")\nexcept:\n    print(\"La función ha dado un error genérico\")\nfinally:\n    print(\"el programa ha finalizado\")\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/barrancus.py",
    "content": "\"#[número] - [lenguaje_utilizado]\"\n# \n# EJERCICIO:\n# Explora el concepto de manejo de excepciones según tu lenguaje.\n# Fuerza un error en tu código, captura el error, imprime dicho error\n# y evita que el programa se detenga de manera inesperada.\n# Prueba a dividir \"10/0\" o acceder a un índice no existente\n# de un listado para intentar provocar un error.\n# \n# DIFICULTAD EXTRA (opcional):\n# Crea una función que sea capaz de procesar parámetros, pero que también\n# pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n# corresponderse con un tipo de excepción creada por nosotros de manera\n# personalizada, y debe ser lanzada de manera manual) en caso de error.\n# - Captura todas las excepciones desde el lugar donde llamas a la función.\n# - Imprime el tipo de error.\n# - Imprime si no se ha producido ningún error.\n# - Imprime que la ejecución ha finalizado.\n# \ndef serparacion(cadena):\n    print('{}'.format(cadena * 20))\n\nfor i in range(5,-6,-1):\n    try:\n        result = 25/i\n        print(f'25 / {i} = {25/i}')\n    except ZeroDivisionError:\n        print(f'No es posible la división ya que no se puede dividir entre {i}')\n\n\nserparacion('-*-')\nlistNumberToPass = [\n        0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10\n]\n\nfor i in range(13):\n    try:\n        print(listNumberToPass[i])\n    except IndexError:\n        print(f'No hay valor en la posición {i} de la lista. {listNumberToPass}')\n\nserparacion('-#-')\nlistNumberToPassb = [\n        0, 2, 6, \"A\",\n]\nclass MyOwnError(Exception):\n    pass\n\ndef parameter_process(arguments):\n    from random import randint\n    numa  = randint(0,7)\n    numb = randint(0,7)\n    if numa == 7:\n        raise MyOwnError\n    return f'{arguments[numa]} / {arguments[numb]} = {arguments[numa] / arguments[numb]}'\n\nfor i in range(20):\n    try:\n        print(parameter_process(listNumberToPassb))\n    except MyOwnError as excep:\n        print(f'Se ha producido el error: {MyOwnError}: {excep}')\n    except IndexError as excep:\n        print(f'Se ha producido el error: {IndexError}: {excep}')\n    except ZeroDivisionError as excep:\n        print(f'Se ha producido el error: {ZeroDivisionError}: {excep}')\n    except Exception as excep:\n        print(f'Se ha producido el error: {Exception}: {excep}')\n    else:\n        print('No ha habido errores.')\n    finally:\n        print(\"Se ha terminado la ejecución\")\n        serparacion('-:-')\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/cesar-ch.py",
    "content": "\"\"\"\n    #10 EXCEPCIONES\n\"\"\"\n\ntry:\n    resultado = 10 / 0\nexcept Exception as e:\n    print(f\"Ocurrió un error: {e}\")\nelse:\n    print(f\"El resultado es: {resultado}\")\nfinally:\n    print(\"La ejecución ha finalizado.\")\n\n\nlista = [\"a\", \"b\", \"c\"]\n\ntry:\n    elemento = lista[4]\nexcept Exception as e:\n    print(f\"Ocurrió un error: {e}\")\nelse:\n    print(f\"El elemento en el índice 4 es: {elemento}\")\nfinally:\n    print(\"La ejecución ha finalizado.\")\n\n\n\"\"\"\n    DIFICULTAD EXTRA (opcional):\n\"\"\"\n\n\nclass MiError(Exception):\n    pass\n\n\ndef procesar_parametros(a, b):\n    if type(a) != int or type(b) != int:\n        raise MiError(\"Los parámetros deben ser enteros.\")\n    return a / b\n\n\ntry:\n    resultado = procesar_parametros(10, \"a\")\nexcept ZeroDivisionError as e:\n    print(f\"Ocurrió un error: {e}\")\n    print(f\"El tipo de error es: {type(e)}\")\nexcept MiError as e:\n    print(f\"Ocurrió un error: {e}\")\n    print(f\"El tipo de error es: {type(e)}\")\nelse:\n    print(f\"El resultado es: {resultado}\")\nfinally:\n    print(\"La ejecución ha finalizado.\")\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/clmiranda.py",
    "content": "# EXCEPCIONES\n\n# Uso de try-except\ntry:\n    name = input(\"Ingresa tu nombre: \")\n    age = int(input(\"Ingresa tu edad: \"))\n    print(f\"Tu nombre es {name} y tienes {age} años\")\nexcept ValueError:\n    print(\"No se ha ingresado un número para la edad\")\n\n\n# División entre 0\ntry:\n    division = 35 / 0\n    print(f\"El resultado es {division}\")\nexcept ZeroDivisionError:\n    print(\"No se puede dividir entre cero\")\nfinally:\n    print(\"Bloque que siempre se ejecuta\")\n\n\n\n# Ejercicio - Dificultad Extra\n\nclass MyOwnException(Exception):\n    def __init__(self, message):\n        self.message = message\n\ndef operations(numbers : list):\n    if len([i for i in numbers if isinstance(i, str)]) >= 1:\n        raise MyOwnException(\"Todos los elementos de la lista deben ser enteros\")\n    if not all(numbers):\n        raise ZeroDivisionError()\n    if len(numbers) < 4:\n        raise ValueError()\n    \n    return sorted(numbers, reverse=True)\n\ntry:\n    print(operations([15, 87, 23, 49, 7]))\nexcept MyOwnException as own:\n    print(own)\nexcept ZeroDivisionError:\n    print(\"Ningun valor de la lista puede ser 0\")\nexcept ValueError:\n    print(\"Se requiere un mínimo de 4 elementos\")\nexcept Exception as e:\n    print(f\"Ha sucedido un error inesperado: {e}\")\nelse:\n    print(\"No ocurrió ningún error en la ejecución\")\nfinally:\n    print(\"La aplicación ha finalizado su ejecución\")"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/cristianfloyd.py",
    "content": "# EJERCICIO:\n# Explora el concepto de manejo de excepciones según tu lenguaje.\n# Fuerza un error en tu código, captura el error, imprime dicho error\n# y evita que el programa se detenga de manera inesperada.\n# Prueba a dividir \"10/0\" o acceder a un índice no existente\n# de un listado para intentar provocar un error.\n\n\ndef divide(a, b):\n    try:\n        result = a / b\n        print(f\"Resultado de {a} / {b} = {result}\")\n    except ZeroDivisionError as e:\n        print(f\"Error: {type(e).__name__}, no se puede dividir por cero.\")\n\n\ndivide(10, 2)\ndivide(10, 0)\ndivide(15, 3)\n\n\ndef buscar_elemento(lista, indice):\n    try:\n        elemento = lista[indice]\n        print(f\"Elemento en el índice {indice}: {elemento}\")\n    except IndexError as e:\n        print(f\"Error: {type(e).__name__}, índice fuera de rango.\")\n\nmi_lista = [1, 2, 3, 4, 5]\nbuscar_elemento(mi_lista, 2)\nbuscar_elemento(mi_lista, 10)\n\n\n#\n# DIFICULTAD EXTRA (opcional):\n# Crea una función que sea capaz de procesar parámetros, pero que también\n# pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n# corresponderse con un tipo de excepción creada por nosotros de manera\n# personalizada, y debe ser lanzada de manera manual) en caso de error.\n# - Captura todas las excepciones desde el lugar donde llamas a la función.\n# - Imprime el tipo de error.\n# - Imprime si no se ha producido ningún error.\n# - Imprime que la ejecución ha finalizado.\n\nclass TypeErrorPersonalizado(Exception):\n    def __init__(self, mensaje):\n        self.mensaje = mensaje\n        super().__init__(self.mensaje)\n\ndef procesar_parametros(parametros):\n    if len(parametros) < 3:\n        raise IndexError(\"La lista debe tener al menos 3 elementos.\")\n    if parametros[1] == 0:\n        raise ZeroDivisionError(\"El segundo elemento no puede ser cero.\")\n    if isinstance(parametros[2], str):\n        raise TypeErrorPersonalizado(\"El tercer elemento no puede ser una cadena.\")\n\n    print(f\"Tercer elemento: {parametros[2]}\")\n    print(f\"División: {parametros[0] / parametros[1]}\")\n    print(f\"Suma: {parametros[2] + 5}\")\n\nprint(\"=\" * 40)\nprint(\"Probando con parámetros correctos:\")\n\n\ntry:\n    procesar_parametros([10, 2, 3])\n    procesar_parametros([10, 1, \"cadena\"])\nexcept IndexError as e:\n    print(f\"Error: {type(e).__name__}, {e}\")\nexcept ZeroDivisionError as e:\n    print(f\"Error: {type(e).__name__}, {e}\")\nexcept TypeErrorPersonalizado as e:\n    print(f\"Error: {type(e).__name__}, {e}\")\nelse:\n    print(\"No se ha producido ningún error.\")\nfinally:\n    print(\"Ejecución finalizada.\")"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/danielhdzr.py",
    "content": "# #10 EXCEPCIONES\n#### Dificultad: Media | Publicación: 04/03/24 | Corrección: 11/03/24\n\n## Ejercicio\n\n\n'''\n* EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n'''\ndef main():\n    while True:\n        print(\"Ingresa dos numeros a dividir\")\n        a = int(input(\"Ingresa un numero: \"))\n        b = int(input(\"Ingresa otro numero: \"))\n        \n        try:\n            resultado = a / b\n            print(resultado)\n            if resultado != 0:\n                break\n        except Exception as e: \n            print(f\"{e}\")\n            print(\"El divisor no puede ser 0\")\n    print(\"Gracias! :D\")\n\n\n    '''\n    * DIFICULTAD EXTRA (opcional):\n    * Crea una función que sea capaz de procesar parámetros, pero que también\n    * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n    * corresponderse con un tipo de excepción creada por nosotros de manera\n    * personalizada, y debe ser lanzada de manera manual) en caso de error.\n    * - Captura todas las excepciones desde el lugar donde llamas a la función.\n    * - Imprime el tipo de error.\n    * - Imprime si no se ha producido ningún error.\n    * - Imprime que la ejecución ha finalizado. `\n    '''\n    # Creamos nuestro propio tipo de error, que hereda el comportamiento de Exception\n    class StrTypeError(Exception):\n        pass\n\n    def my_function(parameters):\n\n        my_list = parameters\n\n        if len(my_list) < 4:\n            raise IndexError()\n    \n        elif my_list[1] == 0:\n            raise ZeroDivisionError()\n        \n        elif type(my_list[2]) == str:\n            raise StrTypeError(\"El tercer elemento no puede ser una cadena de texto.\")\n           \n        \n        print(my_list[3])\n        print(my_list[4]/my_list[1])\n        print(my_list[2] + my_list[4])\n\n    try:\n        my_function([1, 2, 3, 4, 5])\n    except IndexError as e:\n        print(f\"El numero de indices no puede ser menor a 4 ({e})\")\n    except ZeroDivisionError as e:\n        print(f\"El segundo elemento no puede ser cero: ({type(e).__name__})\")\n    except StrTypeError as e:\n        # Nuestro error personalizado ya viene con mensaje\n        print(e)\n    except Exception as e:\n        print(f\"Ha ocurrido un error inesperado ({e}). Trabajamos en ello\")\n    else:\n        print(\"El programa se ejecuto con normalidad\")\n    finally:\n        print(\"Fin del programa\")\n\n    \n\n  \n\n    \n\nif __name__==\"__main__\":\n main()\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/davidrguez98.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado. \n */ \"\"\"\n\n# EJERCICIO\n\ntry:\n    x = 10 / 0\n    print(x)\nexcept Exception as error:\n    print(f\"Se ha producido un error: {error}.\")\n\ntry:\n    y = [1, 2, 3, 4]\n    print(y[4])\nexcept Exception as error:\n    print(f\"Se ha producido un error: {error}.\")\n\n#DIFICULTAD EXTRA\n\nclass StrTypeError(Exception):\n    pass\n\n\ndef process_params(parameters: list):\n\n    if len(parameters) < 3:\n        raise IndexError()\n    elif parameters[1] == 0:\n        raise ZeroDivisionError()\n    elif type(parameters[2]) == str:\n        raise StrTypeError(\n            \"El tercer elemento no puede ser una cadena de texto.\")\n\n    print(parameters[2])\n    print(parameters[0]/parameters[1])\n    print(parameters[2] + 5)\n\n\ntry:\n    process_params([1, 2, 3, 4])\nexcept IndexError as e:\n    print(\"El número de elementos de la lista debe ser mayor que dos.\")\nexcept ZeroDivisionError as e:\n    print(\"El segundo elemento de la lista no puede ser un cero.\")\nexcept StrTypeError as e:\n    print(f\"{e}\")\nexcept Exception as e:\n    print(f\"Se ha producido un error inesperado: {e}\")\nelse:\n    print(\"No se ha producido ningún error.\")\nfinally:\n    print(\"El programa finaliza sin detenerse.\")"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/didacdev.py",
    "content": "class MyException(Exception):\n    message = \"The list is empty\"\n\n\ndef divideBy(numbers: list, divisor: int, size: int):\n\n    if len(numbers) == 0:\n        raise MyException\n    elif divisor == 0:\n        raise ZeroDivisionError\n    elif len(numbers) != size:\n        raise Exception\n\n    for index in range(0, size):\n        print(numbers[index] / divisor)\n\n    print(\"No error found\")\n\n\ntry:\n    divideBy([1, 2, 3, 4], 2, 3)\nexcept (MyException):\n    print(MyException.message)\nexcept (ZeroDivisionError):\n    print(\"Divisor should no be 0\")\nexcept Exception:\n    print(\"Numbers size should be size\")\nfinally:\n    print(\"Ejecución finalizada\")\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/duendeintemporal.py",
    "content": "#10 { Retos para Programadores }  EXCEPCIONES\n\n# Bibliography reference\n#Python Notes for Professionals. 800+ pages of professional hints and tricks (GoalKicker.com) (Z-Library)\n# GPT\n\n\n\"\"\" \n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado.\n\n\"\"\"\n\nlog = print\n\nimport time\n\n# Short for print()\nlog = print\n\n# Simulating window load event\ndef on_load():\n    body_style = {\n        'background': '#000',\n        'text-align': 'center'\n    }\n    \n    title = 'Retosparaprogramadores #10.'\n    title_style = {\n        'font-size': '3.5vmax',\n        'color': '#fff',\n        'line-height': '100vh'\n    }\n    \n    # Simulating setting styles and appending title to body\n    log(f\"Body style: {body_style}\")\n    log(f\"Title: {title} with style: {title_style}\")\n    \n    time.sleep(2)  # Simulating delay\n    log('Retosparaprogramadores #10.')\n\non_load()\n\n# Runtime errors in Python are instances of the Exception class. \n# The Exception class can also be used as-is, or as the base for user-defined exceptions. \n# It's possible to raise any type of value - for example, strings - but you're strongly encouraged to use Exception or one of its derivatives.\n\nnum = 0\nresult = None\n\ntry:\n    if isinstance(num, (int, float)) and num != 0:\n        result = 10 / num\n    elif num == 0:\n        raise ValueError(\"It seems you've tried to divide by zero, which is not permitted. Please enter a valid non-zero number.\")\n    else:\n        raise TypeError(\"It seems you've tried to divide by a non-number value, which is not permitted. Please enter a valid number.\")\nexcept Exception as error:\n    log('Something went wrong! ' + str(error))\n\nlog(result)  # Something went wrong! It seems you've tried to divide by zero, which is not permitted. Please enter a valid non-zero number. & None\n\n# Note: Python raises ZeroDivisionError for division by zero, but we explicitly raise a ValueError to inform about it.\n\n# Example of handling exceptions in a promise-like manner using a function\ndef promise_example():\n    try:\n        result = 102\n        raise Exception(\"explicitly rejected promise\")\n    except Exception as error:\n        log(\"Promise rejected: \" + str(error))\n\npromise_example() # Promise rejected: explicitly rejected promise\n\n# There are several specific core error types in Python:\n# ValueError - raised when a function receives an argument of the right type but inappropriate value.\n# TypeError - raised when an operation or function is applied to an object of inappropriate type.\n# KeyError - raised when a dictionary key is not found.\n# IndexError - raised when a sequence subscript is out of range.\n# SyntaxError - raised when the parser encounters a syntax error.\n# AttributeError - raised when an invalid attribute reference is made.\n\ndef get_user_name(user):\n    try:\n        name = user['name'].upper()\n        log(f\"User name: {name}\")\n    except KeyError:\n        log('KeyError: Cannot read property \"name\" of undefined or null')\n    except Exception as e:\n        log('Instance of general Exception: ' + str(e))\n\nget_user_name({'name': 'Roxy'})  # User name: Roxy\nget_user_name({})  # KeyError: Cannot read property \"name\" of undefined or null\n\n# Extra exercises\ndef check_values(arr, index):\n    try:\n        if not isinstance(arr, list):\n            raise TypeError('The first parameter must be of type list.')\n        elif len(arr) == 0:\n            raise ValueError('You provided an empty array as a parameter!')\n\n        if index >= len(arr) or index < 0:\n            raise IndexError(f\"{index} is not a valid index for the array given.\")\n\n        log(f\"The position given corresponds to this value: {arr[index]}\")\n        log(\"There's no errors when executing the function.\")\n\n    except Exception as e:\n        log(f\"{type(e).__name__}: Ooops! {e}\")\n    finally:\n        log('The process is finished')\n\ncheck_values([8, 5, 6, 4], 8)  # IndexError: Ooops! 8 is not a valid index for the array given & The process is finished\ncheck_values([], 4)  # ValueError: Ooops! You provided an empty array as a parameter! & The process is finished\ncheck_values([0, 76, 32, 1, 4, 2], 'Kia')  # TypeError: Ooops! The first parameter must be of type list. & The process is finished\ncheck_values([4, 5, 3, 18, 22], 3)  # The position given corresponds to this value: 18\n# There's no errors when executing the function.\n# The process is finished                                                                                                                                                                                                                                                                                                                                                                                                                                       "
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/elbarbero.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado.\n \"\"\"\nimport random\n\nclass MyCustomException(Exception):\n    def __init__(self, msg):\n        self.message = msg\n    \n    def __str__(self):\n        return f\"{self.message}\"\n\n\ndef myFunction():\n    try:\n        value = int(input(\"Introduce texto: \"))\n        if value == 0:\n            raise MyCustomException(\"No se puede dividir por cero chaval\")\n        l = [\"a\", 3]\n        r_value = random.choice(l)\n        print(4 + 5 / (value + r_value))\n    except ValueError as ex:\n        print(\"Debe introducir un número\\n\" + str(ex))\n    except TypeError as ex:\n        print(\"Debe introducir un número para realizar la operación\\n\" + str(ex))\n    else:\n        print(\"Ha salido todo bien\")\n    \n\n\nif __name__ == \"__main__\":\n\n    try:\n        print(10/0)\n    except ZeroDivisionError as ex:\n        print(ex)\n    \n    myFunction()\n\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/evilpotato04.py",
    "content": "#/*\n# * EJERCICIO:\n# * Explora el concepto de manejo de excepciones según tu lenguaje.\n# * Fuerza un error en tu código, captura el error, imprime dicho error\n# * y evita que el programa se detenga de manera inesperada.\n# * Prueba a dividir \"10/0\" o acceder a un índice no existente\n# * de un listado para intentar provocar un error.\n\ndef error_conversion():\n    try:\n        texto = \"hola mundo\"\n        numero = int(texto)\n        print(numero)\n    except Exception as ex:\n        print(\"Ocurrió un error: \", ex)\n\ndef error_division():\n    try:\n        valor = 0\n        numero = 10 / valor\n        print(numero)\n    except Exception as ex:\n        print(\"Ocurrió un error: \", ex)\n\ndef error_indice():\n    try:\n        lista = [\"A\", \"B\", \"C\"]\n        letra = lista[4]\n        print(letra)\n    except Exception as ex:\n        print(\"Ocurrió un error: \", ex)\n\nerror_conversion()\nerror_division()\nerror_indice()\n\n# *\n# * DIFICULTAD EXTRA (opcional):\n# * Crea una función que sea capaz de procesar parámetros, pero que también\n# * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n# * corresponderse con un tipo de excepción creada por nosotros de manera\n# * personalizada, y debe ser lanzada de manera manual) en caso de error.\n# * - Captura todas las excepciones desde el lugar donde llamas a la función.\n# * - Imprime el tipo de error.\n# * - Imprime si no se ha producido ningún error.\n# * - Imprime que la ejecución ha finalizado. \n# */\n\nclass ResultadoException(Exception):\n    mensaje = \"El resultado no puede ser mayor que 100\"\n\ndef division_de_dos_numeros(dividendo, divisor):\n    error = None\n    dividendo_int = 0\n    divisor_int = 0\n    resultado = 0\n    \n    try:\n        dividendo_int = int(dividendo)\n        divisor_int = int(divisor)\n    except Exception as ex:\n        print(\"Ocurrió un error: \", ex)\n        return\n    \n    try:\n        resultado = dividendo_int / divisor_int\n        print(f\"{dividendo_int} / {divisor_int} = {resultado}\")\n    except Exception as ex:\n        print(\"Ocurrió un error: \", ex)\n        return\n    \n    try:\n        resultado = dividendo_int / divisor_int\n        if resultado > 100:\n            raise ResultadoException\n    except ResultadoException as ex:\n        print(\"Ocurrió un error: \", ex.mensaje)\n        return\n    \n    print(error) if error != None else print(\"No se ha producido ningún error\")\n    \n    print(\"\\nLa ejecución ha finalizado\\n\")\n\nprint(\"\\n===== Teste 01: error conversión =====\")\ndivision_de_dos_numeros(200, None)\nprint(\"\\n===== Teste 02: error división =====\")\ndivision_de_dos_numeros(200, 0)\nprint(\"\\n===== Teste 03: error personalizado =====\")\ndivision_de_dos_numeros(200, 1)\nprint(\"\\n===== Teste 04: ningún error =====\")\ndivision_de_dos_numeros(200, 3)"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/fborjalv.py",
    "content": "\ntry:\n    print(10/0)\n\nexcept Exception as e:\n\n    print(f\"se ha producido un error: {e}\")\n\n\"\"\"\nPosibles errores: \n- división entre cero\n- operación entre entero y string\n- array fuera de rango\n\"\"\"\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado.\n\"\"\"\n\n# personalizar un error\n\nclass ErrorPersonalizado(Exception):\n    pass\n\ndef my_function(lista: list):\n    if lista[0] == 0:\n        raise ZeroDivisionError\n    if lista[1] == 2:\n        raise ErrorPersonalizado\n\ntry:\n    my_function([0,0,3,4])\nexcept ZeroDivisionError:\n    print(f\"Error en el segundo ejercicio\")\nexcept ErrorPersonalizado:\n    print(f\"Este es mi error personalizado mediante la clase que hereda de Exception\")\nelse: \n    print(\"Este mensaje si no se produce ningún error.\")\nfinally:\n    print(\"Este mensaje se reproduce siempre\")"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/garos01.py",
    "content": "a = 5\nb = 0\ntry:\n    # Intenta ejecutar el código que podría generar un error\n    resultado = a / b  # Intentando dividir por cero\nexcept ZeroDivisionError as error:\n    # Captura la excepción específica y maneja el error\n    print(f\"Error: {error}\")\nelse:\n    # Este bloque se ejecuta si no hay excepciones\n    print(f\"La división fue exitosa: {resultado}\")\nfinally:\n    # Este bloque se ejecuta siempre, independientemente de si hubo una excepción o no\n    print(\"Fin del manejo de excepciones\")\n\n\nlista = [1, 2, 3]\ntry:\n    # Intenta acceder a un índice no existente de una lista\n    elemento = lista[4]  # Intentando acceder a un índice no existente\nexcept IndexError as error:\n    # Captura la excepción específica y maneja el error\n    print(f\"Error: {error}\")\nelse:\n    # Este bloque se ejecuta si no hay excepciones\n    print(f\"Elemento obtenido: {elemento}\")\nfinally:\n    # Este bloque se ejecuta siempre, independientemente de si hubo una excepción o no\n    print(\"Fin del manejo de excepciones\")\n\n\n# Ejercicio extra\n\n\nclass MiExcepcionPersonalizada(Exception):\n    pass\n\n\ndef procesar_parametros(parametro):\n    try:\n        if parametro == 0:\n            raise ValueError(\"El parámetro no puede ser cero.\")\n        elif parametro < 0:\n            raise ValueError(\"El parámetro no puede ser negativo.\")\n        elif parametro > 100:\n            raise MiExcepcionPersonalizada(\"El parámetro es demasiado grande.\")\n        else:\n            print(\"El parámetro es válido.\")\n    except ValueError as error:\n        print(\"Error:\", error)\n    except MiExcepcionPersonalizada as error_personalizado:\n        print(\"Error personalizado:\", error_personalizado)\n    else:\n        print(\"No se ha producido ningún error.\")\n    finally:\n        print(\"La ejecución ha finalizado.\")\n\n\ntry:\n    procesar_parametros(50)\n    print()\n    procesar_parametros(0)\n    print()\n    procesar_parametros(-5)\n    print()\n    procesar_parametros(200)\nexcept Exception as error:\n    print(f\"Error capturado desde el lugar donde se llama a la función: {error}\")\nfinally:\n    print(\"Fin del programa.\")\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/ggilperez.py",
    "content": "# 10 Exceptions\n\n\n# Complete structure\ntry:\n    pass  # Some error may occurs\nexcept Exception:\n    pass  # The error is caught\nelse:\n    pass  # If no error happens, continue with this code\nfinally:\n    pass  # Always execute this code\n\ntry:\n    result = 10 / 0\nexcept ZeroDivisionError:\n    print(\"Can't divide by zero\")\nelse:\n    print(f\"The division is {result}\")\nfinally:\n    print(\"Ending program\")\nprint()\n\n\n# Extra\n\nclass NotKwargsError(Exception): pass\n\n\ndef func(*args, **kwargs):\n    print(args[0])  # May raise IndexError\n\n    print(int(args[0]))  # May raise ValueError\n\n    if not kwargs:\n        raise NotKwargsError(\"Kwargs are mandatory\")  # Custom exception\n\n# 1st Exception\nprint(\"1st Exception\")\ntry:\n    func()\nexcept Exception as e:\n    print(f\"An error occurs: ({e.__class__.__name__}): {e.__str__()}\")\nelse:\n    print(\"Function ended without errors\")\nfinally:\n    print(\"Ending program\")\nprint()\n\n# 2nd Exception\nprint(\"2nd Exception\")\ntry:\n    func(\"foo bar\")\nexcept Exception as e:\n    print(f\"An error occurs: ({e.__class__.__name__}): {e.__str__()}\")\nelse:\n    print(\"Function ended without errors\")\nfinally:\n    print(\"Ending program\")\nprint()\n\n# 3rd Exception (Custom)\nprint(\"3rd Exception (Custom)\")\ntry:\n    func(1)\nexcept Exception as e:\n    print(f\"An error occurs: ({e.__class__.__name__}): {e.__str__()}\")\nelse:\n    print(\"Function ended without errors\")\nfinally:\n    print(\"Ending program\")\nprint()\n\n# All OK\nprint(\"All OK\")\ntry:\n    func(1, one=1)\nexcept Exception as e:\n    print(f\"An error occurs: ({e.__class__.__name__}): {e.__str__()}\")\nelse:\n    print(\"Function ended without errors\")\nfinally:\n    print(\"Ending program\")\nprint()\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/gringoam.py",
    "content": "\"\"\"\nEjercicio\n\"\"\"\n\ntry:\n    print(10/0)\n    print([1, 2, 3, 4][4])\nexcept Exception as e:\n    print(f\"Se ha producido un error: {e} ({type(e).__name__})\")\n\n\"\"\"\nExtra\n\"\"\"\n\nclass StrTypeError(Exception):\n    pass\n\n\ndef process_params(parameters: list):\n\n    if len(parameters) < 3:\n        raise IndexError()\n    elif parameters[1] == 0:\n        raise ZeroDivisionError()\n    elif type(parameters[2]) == str:\n        raise StrTypeError(\n            \"El tercer elemento no puede ser una cadena de texto.\")\n\n    print(parameters[2])\n    print(parameters[0]/parameters[1])\n    print(parameters[2] + 5)\n\n\ntry:\n    process_params([1, 2, 3, 4])\nexcept IndexError as e:\n    print(\"El número de elementos de la lista debe ser mayor que dos.\")\nexcept ZeroDivisionError as e:\n    print(\"El segundo elemento de la lista no puede ser un cero.\")\nexcept StrTypeError as e:\n    print(f\"{e}\")\nexcept Exception as e:\n    print(f\"Se ha producido un error inesperado: {e}\")\nelse:\n    print(\"No se ha producido ningún error.\")\nfinally:\n    print(\"El programa finaliza sin detenerse.\")\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/h4ckxel.py",
    "content": "'''\n/*\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado.\n */\n'''\n\n#Declaramos las variables necesarias\nnumero1 = 10\nnumero2 = 0\nlistado= [\"Hola\",\"Python\",\"Alexdevrep\",\"Mundo\"]\n\n#División\n\ndef dividir(numero1, numero2):\n    try:\n        resultado = numero1 / numero2\n        print(resultado)\n\n    except ZeroDivisionError: # En este bloque indicamos el error que queremos que capture el programa\n        print(\"No se puede dividir un número por cero\")\n\n    finally:\n        print(\"Finalizando el programa\")\n\ndividir(numero1, numero2)\n\n#Listado\n\ndef iterarLista():\n    try:\n        #Intentamos acceder a un índice que no existe\n        print(listado[6])\n    except:\n        print(\"Índice no existente en la lista\")\n    finally:\n        print(\"Programa finalizado\")\n\niterarLista()\n\n#Dificultad EXTRA\n\n#Vamos a crear una función que multiplique un número natural de una cifra por 5\n\nclass NoneException(Exception):\n    pass #Creamos una excepcion personalizada\n\ndef multiplo(numero3):\n    try:\n        \n        if numero3 is None:\n            raise NoneException(\"Es necesario dar un número para multiplicar\") #Generamos manualmente la excepcion con raise\n        elif 9 < numero3 < 100:\n            raise Exception(\"El número tiene 2 cifras.\")\n        elif numero3 < 0:\n            raise ValueError(\"El número es negativo, no se puede multiplicar.\")\n        else:\n            producto = 5 * numero3\n            print(producto)\n\n    except ValueError as e:\n        print(f'Error: {e}')\n    except NoneException as e:\n        print(f'Error: {e}')\n    except Exception as e:\n        print(f\"Error: {e}\")\n    \n    finally:\n        print(\"Cerrando el programa\")\n\n\nentrada = input(\"Por favor ingrese el número a multiplicar: \")\nnumero3= int(entrada) if entrada else None\nmultiplo(numero3)\n\n\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/haroldAlb.py",
    "content": "# EJERCICIO #\nnombres = [\"Greg\", \"Ideafix\", \"Canelo\", \"Kiwi\", \"Pia\"]\n\nfor index, nombre in enumerate(nombres):\n    print(f\"{index}.{nombre}\")\ntry:\n    option = int(input(\"Opción: \"))\n    print(nombres[option])\n\nexcept IndexError:\n    print(\"Indice de lista fuera de rango\")\n\nprint(\"Fin de la ejecución.\")\n\n# EXTRA #\nclass MinimumRangeError(Exception):\n    def __str__(self):\n        return \"El dividendo debe ser mayor que el divisor\" # Sobre escribo el método str para cuando imprima el error\n\n\ndef proceso_parametros(num1, num2):\n    if num1 < num2:\n        raise MinimumRangeError() # Lanzo la excepción que lo recoje el Except de donde se ejecuta el programa\n    \n    print(num1/num2)\n\ntry:\n    proceso_parametros(4, 5)\n\nexcept ZeroDivisionError:\n    print(\"No es posible dividir entre 0.\")\n\nexcept TypeError:\n    print(\"Sólo números enteros\")\n\nexcept Exception as e:\n    print(f\"{e}\")\n\nelse:\n    print(\"ningún error encontrado\") # si no ha ocurrido ningun error se ejecuta el \"else\"\n\nfinally:\n    print(\"Finalización del programa\") # Tanto si se ejecuta lo del try como lo del except, lo del finally se ejecuta siempre"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/hectorio23.py",
    "content": "# Autor: Héctor Adàn\n# GitHub: https://github.com/hectorio23\nimport sys\n\n'''\n/*\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado. \n */\n'''\n\n# Función para dividir dos números e intentar forzar un error\ndef dividir():\n    try:\n        divisor = 0\n        if divisor == 0:\n            raise ValueError(\"División por cero\")\n        resultado = 10 / divisor  # Intento de dividir por cero\n        print(f\"El resultado de la división es: {resultado}\")\n    except Exception as e:\n        print(f\"Se produjo un error: {e}\")\n\n# Función que puede lanzar excepciones personalizadas\ndef procesar_parametro(parametro):\n    try:\n        if parametro == 0:\n            raise ValueError(\"El parámetro no puede ser cero\")\n        elif parametro < 0:\n            raise ValueError(\"El parámetro no puede ser negativo\")\n        else:\n            print(\"Procesamiento exitoso\")\n    except ValueError as ve:\n        print(f\"Se produjo un error: {ve}\")\n    except Exception as e:\n        print(f\"Error inesperado: {e}\")\n    else:\n        print(\"No se produjo ningún error.\")\n    finally:\n        print(\"La ejecución ha finalizado.\")\n\n# Función principal (equivalente a main en C++)\nif __name__ == \"__main__\":\n    # Forzar un error al dividir por cero\n    print(\"Intentando dividir por cero:\")\n    dividir()\n\n    print(\"\\n---------------------------------------\\n\")\n\n    # Intento de procesar un parámetro\n    print(\"Intentando procesar parámetro:\")\n    procesar_parametro(-3)\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/hozlucas28.py",
    "content": "\"\"\"\n    Exceptions...\n\"\"\"\n\nprint(\"Exceptions...\")\n\nprint(\n    \"\"\"\\n# Invalid operation\ntry:\n    operation: float = 10 / 0 # <-- Invalid operation.\n    print(f\"\\\\nOperation --> {operation}\")\nexcept ZeroDivisionError as error:\n    print(f\"\\\\nError --> {error}\")\"\"\"\n)\n\n# Invalid operation\ntry:\n    operation: float = 10 / 0  # <-- Invalid operation.\n    print(f\"\\nOperation --> {operation}\")\nexcept ZeroDivisionError as error:\n    print(f\"\\nError --> {error}\")\n\n\nprint(\n    \"\"\"\\n# Invalid index\ntry:\n    my_list: list[int] = [1, 2, 3]\n    element: int = my_list[3]  # <-- Index three doesn't exist.\n    print(f\"\\\\nElement --> {element}\")\nexcept IndexError as error:\n    print(f\"\\\\nError --> {error}\")\"\"\"\n)\n\n\n# Invalid index\ntry:\n    my_list: list[int] = [1, 2, 3]\n    element: int = my_list[3]  # <-- Index three doesn't exist.\n    print(f\"\\nElement --> {element}\")\nexcept IndexError as error:\n    print(f\"\\nError --> {error}\")\n\nprint(\n    \"\\n# ---------------------------------------------------------------------------------- #\\n\"\n)\n\n\"\"\"\n    Additional challenge...\n\"\"\"\n\n\nprint(\"Additional challenge...\")\n\n\ndef fn(param: float | int | str | list[int]) -> float | int | str | list[int]:\n    \"\"\"Function to test error exceptions.\"\"\"\n    if isinstance(param, int):\n        return param.upper()  # type: ignore\n\n    if isinstance(param, str):\n        return param / 2  # type: ignore\n\n    if isinstance(param, list):\n        raise TypeError(\"My custom error\")\n\n    return param\n\n\n# No error\ntry:\n    result: float | int | str | list[int] = fn(param=1.25)\n    print(f\"\\nResult --> {result}\")\nexcept Exception as error:  # pylint: disable=[broad-exception-caught]\n    print(f\"\\nError --> {error}\")\n\n# Attribute error\ntry:\n    result: float | int | str | list[int] = fn(param=12)\n    print(f\"\\nResult --> {result}\")\nexcept AttributeError as error:\n    print(f\"\\nError --> {error}\")\n\n# Custom error\ntry:\n    result: float | int | str | list[int] = fn(param=[22, 21, 20])\n    print(f\"\\nResult --> {result}\")\nexcept TypeError as error:\n    print(f\"\\nError --> {error}\")\n\n# Type error\ntry:\n    result: float | int | str | list[int] = fn(param=\"Lucas Hoz\")\n    print(f\"\\nResult --> {result}\")\nexcept TypeError as error:\n    print(f\"\\nError --> {error}\")\n\n\nprint(\"\\nAdditional challenge finished!\")\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/idiegorojas.py",
    "content": "# Excepciones\n\n# Tipos de excepciones\n\n# ZeroDivisionError: Ocurre cuando se intenta dividir entre cero.\n# TypeError: Ocurre cuando se realiza una operación con tipos de datos incompatibles.\n# ValueError: Ocurre cuando una función recibe un argumento con el tipo correcto pero un valor inapropiado.\n# FileNotFoundError: Ocurre cuando se intenta abrir un archivo que no existe.\n# IndexError: Ocurre cuando se intenta acceder a un índice fuera de rango en una lista.\n# KeyError: Ocurre cuando se intenta acceder a una clave que no existe en un diccionario.\n\n# Estructura basica\ntry:\n    # Dividir por cero genera la excepcion 'ZeroDivisionError'\n    resultado = 10 / 0\nexcept ZeroDivisionError:\n    # Codigo que se ejecuta si se da la excepcion 'ZeroDivisionError'\n    print('Error: No se puede dividir entre cero.')\nelse:\n    # Codigo que se ejecuta si no hay ninguna excepcion\n    print('La divison se realizo correctamente.')\nfinally:\n    # Codigo que siempre se ejecuta, haya o no excepciones\n    print('Este bloque siempre se ejecuta.')\n\nprint('---------------------')\n\n# Multiples excepciones\ntry:\n    resultado = 10 / 0\nexcept (ZeroDivisionError, TypeError, ValueError) as e:\n    print(f'Error: {e}')\n\n\nprint('---------------------')\n\n\n# Excepciones personalizadas\nclass MiErrorPersonalizado(Exception):\n    pass\n\n\ntry:\n    raise MiErrorPersonalizado('Este es un error personalizado.')\nexcept MiErrorPersonalizado as e:\n    print(e)\n\nprint('---------------------')\n\n\n# Ejemplo:\ndef dividir(a, b):\n    try:\n        resultado = a / b\n    except ZeroDivisionError:\n        print('Error: No se puede dividir entre cero.')\n    except TypeError:\n        print('Error: Los tipos de datos no son validos')\n    else:\n        print(f'El resultado de dividir {a} y {b} es: {resultado}')\n    finally:\n        print('Fin del bloque.')\n\ndividir(3, 4)\ndividir(3, 0)\ndividir(3, 'a')\n\nprint('---------------------')\n\n# Extra\n\nclass ValorInvalidoError(Exception):\n    def __init__(self, mensaje=\"El valor proporcionado no es válido\"):\n        self.mensaje = mensaje\n        super().__init__(self.mensaje)\n\ndef procesar_parametros(numero, texto):\n    if not isinstance(numero, int):\n        raise TypeError(\"El primer parámetro debe ser un número entero\")\n    \n    if not isinstance(texto, str):\n        raise TypeError(\"El segundo parámetro debe ser una cadena de texto\")\n    \n    if numero < 0:\n        raise ValorInvalidoError(\"El número debe ser positivo\")\n    \n    if not texto.strip():\n        raise ValueError(\"El texto no puede estar vacío\")\n    \n    return f\"Número: {numero}, Texto: {texto}\"\n\n\ndef probar_funcion():\n    casos_prueba = [\n        (10, \"Hola\"),          # Caso válido\n        (-5, \"Mundo\"),         # Número negativo\n        (15, \"\"),              # Texto vacío\n        (\"no_numero\", \"Test\"), # Tipo incorrecto\n    ]\n    \n    for numero, texto in casos_prueba:\n        try:\n            resultado = procesar_parametros(numero, texto)\n            print(f\"¡Éxito! {resultado}\")\n        except ValorInvalidoError as e:\n            print(f\"Error personalizado: {e}\")\n        except TypeError as e:\n            print(f\"Error de tipo: {e}\")\n        except ValueError as e:\n            print(f\"Error de valor: {e}\")\n        except Exception as e:\n            print(f\"Error inesperado: {e}\")\n        finally:\n            print(\"La ejecución de este caso ha finalizado\")\n        print(\"-\" * 50)\n\n\nif __name__ == \"__main__\":\n    probar_funcion()"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/ignaciovihe.py",
    "content": "\"\"\"\n* EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n\"\"\"\n\ndef divide(number_1: int, number_2: int)-> float:\n    try:\n        return number_1 / number_2\n    except ZeroDivisionError as error:\n        print (f\"No se puede dividir entre 0: Error = {error}\")\n\ndivide(9, 0)\n\ndef get_by_index(index: int):\n\n    my_list = [\"Python\", \"Rust\", \"c#\", \"Kotlin\"]\n\n    try:\n        return my_list.pop(index)\n    except IndexError as error:\n        print(f\"Índice fuera de rango. Error: {error}\")\n\nprint(get_by_index(4))\n\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado.\n\"\"\"\n\nclass InvalidEmail(Exception):\n    def __init__(self, mensaje):\n        super().__init__(mensaje)\n\n\ndef validate_email(email: str):\n    email = email.split(\"@\")\n    if len(email) != 2:\n        return False\n    email = email[1].split(\".\")\n    if len(email) != 2:\n        return False\n    return True\n\n\ndef sign_up():\n    rewards = [\"Coupon 10€\", \"Coupon 5€\", \"Coupon 20€\"]\n\n    name = input(\"Introduce tu nombre: \")\n    age = int(input(\"Introduce tu edad: \"))\n    email = input(\"Introduce tu email: \")\n    if not validate_email(email):\n        raise InvalidEmail(\"Formato de email incorrecto.\")\n    index = int(input(\"Dame un número del 1 al 3 para conseguir tu premio de bienvenida: \"))\n    if index < 1 or index > len(rewards):\n        raise IndexError(\"Número fuera de rango. Debe estar entre 1 y 3.\")\n    return rewards[index - 1]\n\n\n\ntry:\n    reward = sign_up()\n\nexcept ValueError as error:\n    print(f\"Tipo de error: {type(error).__name__}\")\n    print(f\"La edad debe ser un número entero. Error: {error}\")\n\nexcept IndexError as error:\n    print(f\"Tipo de error: {type(error).__name__}\")\n    print(f\"Debes introducir un índice entre 1 y 3. Error: {error}\")\n\nexcept InvalidEmail as error:\n    print(f\"Tipo de error: {type(error).__name__}\")\n    print(error)\n\nexcept Exception as error:\n    print(f\"Se ha producido un error inesperado: {error}\")\n\nelse:\n    print(f\"Todos los datos correctos. Tu recompensa de bienvenida es {reward} \")\n\nfinally:\n    print(\"Proceso finalizado\")\n\n\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/ipfabio.py",
    "content": "\"\"\"\nEjercicio\n\"\"\"\ntry:\n    result = 10 / 1\n    print(f\"El resultado es: {result}\")\n    print([1, 2, 3, 4][4])\n\nexcept Exception as e:\n    print(f\"Intentalo de nuevo: {e} ({type(e).__name__})\")\n\n\n\"\"\"\nExtra\n\"\"\"\n\nclass StrTypeError(Exception):\n    ...\n\ndef process_params(parameter: list):\n    try:\n        if len(parameter) < 3:\n            raise IndexError()\n        elif parameter[1] == 0:\n            raise ZeroDivisionError()\n        elif type(parameter[2]) == str:\n            raise StrTypeError(\"El tercer elemento no puede ser una cadena de texto.\")\n\n        print(parameter[2])\n        print(parameter[0]/parameter[1])\n        print(parameter[2] + 5)\n    except IndexError as e:\n        print(f\"El número de elementos de la lista debe ser mayor que dos.\")\n    except ZeroDivisionError as e:\n        print(f\"El segundo elementos de la lista no puede ser un cero.\")\n    except StrTypeError as e:\n        print(f\"{e}\")\n    except Exception as e:\n        print(f\"Se ha producido un error inesperado: {e}\")\n    else: # Se ejecuta si no ocurre ningún error.\n        print(\"No se ha producido ningún error\")\n    finally: # Se ejecuta siempre.\n        print(\"El programa finaliza sin detenerse.\")\n\nprocess_params([1, 2, 3, 4])"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/isilanes.py",
    "content": "class NotThreeError(Exception):\n\n    def __init__(self, n: int):\n        msg = f\"Sadly, {n} is not 3, which is the best number.\"\n        super().__init__(msg)\n\n\ndef main():\n    elements = [1, 2, 3, 4]\n    x = None\n    try:\n        index = 10\n        x = elements[index]\n        print(\"Esta línea no será imprimida, por dar la anterior error.\")\n    except IndexError as e:\n        print(f\"No pudimos extraer el elemento {index}, porque 'elements' sólo tiene {len(elements)} elementos.\")\n        print(f\"El error fue: {e}\")\n\n    if x is None:\n        print(\"Pues no, no pudimos extraer x.\")\n\n\ndef extra():\n    value_pairs = (\n        (1, \"a\"),\n        (1.0, 2),\n        (1, 0),\n        (1, 2),\n        (3, 2),\n    )\n\n    for num, dem in value_pairs:\n        try:\n            ret = division(num, dem)\n        except TypeError as e:\n            print(f\"Error (tipo {e.__class__.__name__}) en argumentos ({num}, {dem}): {e}\")\n            continue\n        except ZeroDivisionError as e:\n            print(f\"Error (tipo {e.__class__.__name__}) en denominador ({num}, {dem}): {e}\")\n            continue\n        except NotThreeError as e:\n            print(f\"Error (tipo {e.__class__.__name__}) en numerador ({num}, {dem}): {e}\")\n            continue\n\n        print(f\"Éxito: {num}/{dem} es {ret}\")\n\n    print(\"La ejecución ha finalizado.\")\n\n\ndef division(numerator: int, denominator: int) -> float:\n    if not isinstance(numerator, int) or not isinstance(denominator, int):\n        raise TypeError(\"Qué parte de 'numerator and denominator must be integers' no entendiste?\")\n\n    if denominator == 0:\n        raise ZeroDivisionError(\"Vamos, tío, sabes que no se puede dividir entre cero!\")\n\n    if numerator != 3:\n        raise NotThreeError(numerator)\n\n    return numerator/denominator\n\n\nif __name__ == \"__main__\":\n    main()\n    extra()\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/javierjoyera.py",
    "content": "try:\n    resultado = 10 / 0\nexcept ZeroDivisionError as e:\n    # Este bloque captura la excepción específica ZeroDivisionError\n    print(\"Ha ocurrido un error: %s\" % e)\nexcept Exception as e:\n    # Este bloque captura cualquier otra excepción\n    print(\"Ha ocurrido un error inesperado: %s\" % e)\nelse:\n    # Este bloque se ejecuta si no hay errores\n    print(\"El resultado es %s\" % resultado)\nfinally:\n    # Este bloque se ejecuta siempre\n    print(\"Este bloque se ejecuta siempre\")\n\nlista = [1, 2, 3]\n\ntry:\n    # Intentamos acceder a un índice fuera de rango\n    elemento = lista[5]\nexcept IndexError as e:\n    print(\"Error de índice: %s\" % e)\nelse:\n    print(\"El elemento es %s\" % elemento)\nfinally:\n    print(\"Este bloque se ejecuta siempre 2\")\n\n#EJERCICIO OPCIONAL\nclass ErrorPersonalizado(Exception):\n    \"\"\"Excepción lanzada cuando ocurre un error específico definido por el usuario.\"\"\"\n    pass\n\ndef procesar_parametros(param):\n    if not param:\n        raise ValueError(\"El parámetro no puede estar vacío\")\n    elif not isinstance(param, int):\n        raise TypeError(\"El parámetro debe ser un número entero\")\n    elif param < 0:\n        raise ErrorPersonalizado(\"El parámetro no puede ser negativo\")\n\n    print(\"Procesando el parámetro %s\" % param)\n    return param * 2\n\n# Intentamos llamar a la función y capturamos las excepciones\ntry:\n    #resultado = procesar_parametros(1)\n    #resultado = procesar_parametros(-1)\n    resultado = procesar_parametros(\"hola\")\n    print(\"Resultado: %s\" % resultado)\nexcept ValueError as ve:\n    print(\"Error de valor: %s\" % ve)\nexcept TypeError as te:\n    print(\"Error de tipo: %s\" % te)\nexcept ErrorPersonalizado as ep:\n    print(\"Error personalizado: %s\" % ep)\nexcept Exception as e:\n    print(\"Error inesperado: %s\" % e)\nelse:\n    print(\"No se ha producido ningún error.\")\nfinally:\n    print(\"La ejecución de la función ha finalizado.\")\n\n\n\n# El programa sigue ejecutándose hasta aqui\nprint(\"El programa ha finalizado correctamente.\")"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/jesusgdev.py",
    "content": "\"\"\"\nEJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n   y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n   de un listado para intentar provocar un error.\n\nDIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n   pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n   corresponderse con un tipo de excepción creada por nosotros de manera\n   personalizada, y debe ser lanzada de manera manual) en caso de error.\n *   Captura todas las excepciones desde el lugar donde llamas a la función.\n *   Imprime el tipo de error.\n *   Imprime si no se ha producido ningún error.\n *   Imprime que la ejecución ha finalizado.\n\"\"\"\n\ntry:\n    print(10/0)\n    print([3,4,7][1])\n\nexcept Exception as e:\n    print(f\"Se ha producido un error {e} de tipo: {type(e).__name__}\")\n\nprint(\"\")\n\n'''\nExtra\n'''\n\nclass StrMethodError(Exception):\n    pass\n\ndef process_params(parameters: list):\n    \n    try:\n        num\n    except NameError:\n        raise NameError(\"La variable 'num' no esta definida\")\n    \n    try:\n        exec(parameters[5])\n    except SyntaxError:\n        raise SyntaxError\n    \n    try:\n        int(parameters[4])\n    except ValueError:\n        raise ValueError\n    \n    try:\n        parameters[4].append(\"!\")\n    except AttributeError:\n        raise StrMethodError(\"Solo las listas pueden hacer uso del metodo append()\")\n    \n    print(parameters[1] + num)\n    print(exec(parameters[5]))\n    print(int(parameters[4]))\n\n\ntry:\n    process_params([2, 0, 6, 10, \"hello\", \"x === 5\"])\nexcept NameError as e:\n    print(f\"❌Error: {e} | Tipo de Error: {type(e).__name__}\")\nexcept SyntaxError as e:\n    print(f\"❌Error: {e} | Tipo de Error: {type(e).__name__}\")\nexcept ValueError as e:\n    print(f\"❌Error: {e} | Tipo de Error: {type(e).__name__}\")\nexcept StrMethodError as e:\n    print(f\"❌Error: {e}\")\nexcept Exception as e:\n    print(f\"❌Ha ocurrido un error inesperado. | Error: {e} | Tipo de Error: {type(e).__name__}\")\nelse:\n    print(\"✅No se ha producido ningun error.\")\nfinally:\n    print(\"✅La ejecucion ha finalizado\")"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/jgutierrez9891.py",
    "content": "## Ejercicio\n\nnumbera = int(input(\"Ingrese el primer número: \"))\nnumberb = int(input(\"Ingrese el segundo número: \"))\ntry:\n    resultado = numbera / numberb\n    print(\"El resultado es: \" + str(resultado))\nexcept ZeroDivisionError:\n    print(\"Error: División por cero no está permitida.\")\nexcept Exception as e:\n    print(\"Ocurrió un error: \" + str(e))\nfinally:\n    print(\"Operación finalizada.\")\n\n## Dificultad Extra\nclass CustomError(Exception):\n    def __init__(self, message):\n        self.message = message\n        super().__init__(self.message)\n\ndef check_positive(number):\n    if number < 0:\n        raise CustomError(\"El número no es positivo.\")\n    return True\n\ntry:\n    num = int(input(\"Ingrese un número positivo: \"))\n    if check_positive(num):\n        print(\"El número es positivo.\")\nexcept CustomError as ce:\n    print(\"Error personalizado: \" + ce.message)\nexcept ValueError:\n    print(\"Error: Entrada inválida, por favor ingrese un número entero.\")\nexcept Exception as e:\n    print(\"Ocurrió un error: \" + str(e))\nfinally:\n    print(\"Verificación finalizada.\")\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/josealberto13.py",
    "content": "\"\"\" EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\"\"\"\n\ndef dividir():\n    while True:\n        n1 = int(input(\"Ingresa un numero para dividir: \"))\n        n2 = int(input(\"Ingresa el numero divisor: \"))\n        try:\n            div = n1 / n2\n            return div\n        except:\n            print(\"¡ERROR! No se puede dividir entre 0\")\n\n# print(dividir())\n\n\n\"\"\" Clase de Brais Moure \"\"\"\ntry:\n    print([1,2,3,4][4])\nexcept Exception as error:          # investigar más sobre el manejo de errores\n    print(f\"Se ha producido un error: {error} ({type(error).__name__})\")\n\n\n\"\"\" DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado. \"\"\"\n\nclass strTypeError(Exception):\n    pass\n\ndef process_params(paramteros: list):\n\n    if len(paramteros) < 2:\n        raise IndexError()\n    elif paramteros[1] == 0:\n        raise ZeroDivisionError()\n    elif type(paramteros[2]) == str:\n        raise strTypeError(\"El tercer elemento de la lista no debe ser una cadena de texto\")\n\n    \n    print(paramteros[1])\n    print(paramteros[0]/paramteros[1])\n    print(paramteros[0]/paramteros[2])\n    \n# Manejo de Errores \n\ntry:\n    process_params([2, 4, 6, 8])\nexcept IndexError as error:\n    print(f\"El número de parámetros deben ser más de dos ({type(error).__name__})\")\nexcept ZeroDivisionError as error:\n    print(f\"El segundo parámetro no debe ser igual a cero ({type(error).__name__})\")\nexcept strTypeError as error:\n    print(f\"{error}\")\nexcept Exception as error:\n    print(f\"Se ha producido un error inesperado: ({error})\")\nelse:\n    print(\"El programa se ha ejecutado correctamente\")\nfinally:\n    print(\"El programa finaliza\")\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/jptxaya.py",
    "content": "#Excepciones\n\ntry:\n    print(\"Iniciando ejecucion\")\n    num = 10/0\nexcept Exception as ex:\n    print(f\"Error {ex}\")\nfinally:\n    print(\"Ejecucion finalizada\")\n    \n\n#Dificultad Extra\nprint(\"Dificultad Extra \\n\")\nclass MiExcepcion(Exception):\n    pass\n\ndef genera_excepciones(param1, param2):\n    if int(param1) == 10:\n        raise MiExcepcion(\"1º Valor no puede ser 10 \")\n    num = int(param1) / int(param2)\n    print(f\"Resultado Division:{num}\")\n\n\ntry:\n    num1 = input(\"Introduce el primer valor para hacer la division:\")\n    num2 = input(\"Introduce el segundo valor para hacer la division:\")\n    genera_excepciones(num1,num2)\nexcept MiExcepcion as ex:\n    print(f\"Mi Excepcion {ex}\")\nexcept ValueError as ex:\n    print(f\"Excepcion division 0 {ex}\")\nexcept Exception as ex:\n    print(f\"Excepcion {ex}\")\nfinally:\n    print(\"Ejecucion finalizada\")"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/juanchernandezdev.py",
    "content": "### Python Exceptions ###\n\n#! Zero Division\n\ntry:\n  division = 10/0\nexcept Exception as err:\n  print(f'Can\\'t divide by Zero!!, error info: {err}')\n  \n#! Index Error\n\ntry:\n  my_list = [1, 2, 3, 4]\n  my_list[8]\nexcept Exception as err:\n  print(f'Not a valid index, error info: {err}')\n  \n#! Optional Challenge\nclass FirstElementError(Exception):\n  pass\n\ndef test_func(params: list):\n  if type(params) != list:\n    raise TypeError()\n  elif len(params) > 4:\n    raise IndexError()\n  elif params[2] == 0:\n    raise ZeroDivisionError()\n  elif type(params[0]) == str:\n    raise FirstElementError()\n\n\ntry:\n  test_func(['try', 2, 4])\nexcept TypeError as err:\n  print(f'Param should be of type list.')\nexcept IndexError as err:\n  print(f'The length of the list should be less than 4.')\nexcept ZeroDivisionError as err:\n  print(f'The element at index 2 can\\'t be a 0.')\nexcept FirstElementError as err:\n  print(f'The first element should be of type int.')\nelse:\n  print('Not error was found.')\nfinally:\n  print('Program ends!!')\n  "
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/juandaherrera.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n\"\"\"\n\ntry:\n    my_var = 10 / 0\nexcept ZeroDivisionError as e:\n    print(e)\n\ntry:\n    my_var = [1, 2, 3]\n    print(my_var[10])\nexcept Exception as e:\n    print(e)\n    print(f\"Tipo de excepción: {e.__class__.__name__}\")\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado. \n\"\"\"\n\nprint('-' * 35)\n\n\nclass MyException(Exception):\n    def __init__(self, message):\n        self.message = message\n        super().__init__(message)\n\n\ndef my_function(param_1: int, param_2: float, param_3: str):\n    if (\n        not isinstance(param_1, int)\n        or not isinstance(param_2, float)\n        or not isinstance(param_3, str)\n    ):\n        raise ValueError(\n            'Los valores de cada parámetro deben ser del tipo específicado para cada uno en la documentación'\n        )\n    if param_1 > 1000:\n        raise MyException('El valor de \"param_1\" no puede ser mayor a 1000')\n    if param_3.count(' ') > 1:\n        raise SyntaxError('El valor del \"param_3\" no puede tener más de un espacio en blanco')\n    print(param_3.count(' '))\n    return [param_1, param_2, param_3]\n\n\ntry:\n    test_var = my_function(2500, 10.5, 'avg')\n    test_var = my_function(1, 'hola', 'avg')\n    test_var = my_function(1, 10.5, 'avg   ')\n    test_var = my_function(1, 10.5, 'avg')\nexcept Exception as e:\n    print(f'{e.__class__.__name__}: {e}')\nelse:\n    print(\"No se ha producido ningún error al correr el código\")\n    print(test_var)\nfinally:\n    print('Ejecución finalizada')\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/juanmax2.py",
    "content": "\"\"\"\nExcepciones\n\"\"\"\n\ndef dividir():\n    try:\n        print(10/0)\n        \n        mi_lista = [1, 2, 3]\n        print(mi_lista[3])\n        \n    except Exception as e:\n        print(f\"Error: {e}\")\n\ndividir()\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado. \n\"\"\"\n\nclass StrTypeError(Exception):\n    print(\"El segundo elemento no puede ser una cadena de texto\")\n\ndef procesar_parametro(parametros : list):\n    \n    if len(parametros) < 3:\n        raise IndexError()\n    elif parametros[1] == 0:\n        raise ZeroDivisionError()\n    elif type(parametros[0]) == str:\n        raise StrTypeError()\n    \n    print(parametros[2])\n    print(parametros[0]/parametros[1])    \n    print(parametros[0] + 5)\n    \ntry:    \n    procesar_parametro([1, 3, 2])\nexcept IndexError as e:\n    print(f\"El numero de elementos de la lista debe ser mayor que dos\")\nexcept ZeroDivisionError as e:\n    print(f\"EL segundo elemento de la lista no puede ser un 0\")\nexcept StrTypeError as e:\n    print(f\"{e}\")\nexcept Exception as e:\n    print(f\"Se ha producido un error inesperado: {e}\")\nelse:\n    print(\"No se ha producido ningun erro\")\nfinally:\n    print(\"El programa finaliza\")\n    \n    "
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/juanppdev.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n\"\"\"\n\ndef manejar_excepciones():\n    try:\n        # Forzamos un error de división por cero\n        resultado = 10 / 0\n    except ZeroDivisionError as e:\n        print(f\"Error capturado: {e}\")\n    \n    try:\n        # Forzamos un error de índice fuera de rango\n        lista = [1, 2, 3]\n        elemento = lista[5]\n    except IndexError as e:\n        print(f\"Error capturado: {e}\")\n\n    print(\"El programa continúa ejecutándose sin problemas.\")\n\n# Llamamos a la función para ver el manejo de excepciones en acción\nmanejar_excepciones()\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado. \n\"\"\"\n\n# Definimos una excepción personalizada\nclass CustomError(Exception):\n    pass\n\ndef procesar_parametros(param):\n    if not isinstance(param, int):\n        raise TypeError(\"El parámetro debe ser un entero.\")\n    if param < 0:\n        raise ValueError(\"El parámetro no puede ser negativo.\")\n    if param == 0:\n        raise CustomError(\"El parámetro no puede ser cero.\")\n    return param * 2\n\ndef main():\n    parametros = [10, -5, \"texto\", 0, 5]\n    \n    for param in parametros:\n        try:\n            resultado = procesar_parametros(param)\n            print(f\"Resultado: {resultado}\")\n        except TypeError as e:\n            print(f\"Error de tipo: {e}\")\n        except ValueError as e:\n            print(f\"Error de valor: {e}\")\n        except CustomError as e:\n            print(f\"Error personalizado: {e}\")\n        except Exception as e:\n            print(f\"Error inesperado: {e}\")\n        else:\n            print(\"No se ha producido ningún error.\")\n        finally:\n            print(\"La ejecución ha finalizado.\\n\")\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/juserdev.py",
    "content": "'''\n/*\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado. \n */\n'''\n\n'''\n  ->  para el manejo de excepciones es mejor caputurar los errores en una varia como en el caso\n        -> except ZeroDivisionError as e:\n      de esta manera tenemos capturado el erro en la variable e y asi no se detiene el programa\n      y muestra el error\n        ->  division by zero\n  \n  ->  El bloque try se utiliza para el bloque que puede fallar\n  ->  El bloque except captura y maneja los errores sin detener el programa\n  ->  Es mejor capturar el error con \"as e\" para imprimi detalles del fallo\n'''\n\ndef dividir(a,b):\n  try:\n    print(a/b)\n    print(\"no se ha producido ningun error\")\n  except ZeroDivisionError as e:\n    print(\"Error -> \", e)\n\ndividir(10, 0)\n\nmy_list = [1,2,3,4]\n\ndef get_list(i):\n  try:\n    print(my_list[i])\n  except IndexError as e:\n    print(\"Error -> \", e)\n\nget_list(4)\n\n\n### EXTRA ###\n\nclass StrTypeError(Exception):\n  pass\n\ndef get_errors(params: list):\n  if len(params) < 3:\n   raise IndexError()\n  if params[1] == 0:\n    raise ZeroDivisionError()\n  if type(params[2] == str):\n    raise StrTypeError(\"El tercer elemento no puede ser una cadera de texto\")\n\n  print(params[0])\n  print(params[0]/params[1])\n  print(params[0] + 5)\n\n\ntry:\n  get_errors([1,2,\"str\",4])\nexcept IndexError as e:\n  print(\"El numero de elemtnos de la lista debe ser mayor que tres\")\nexcept ZeroDivisionError:\n  print(\" El segundo elemento de la lista no puede ser cero\")\nexcept StrTypeError as e:\n  print(f\"{e}\")\nexcept Exception as e:\n  print(f\"se ha producido un error inesperado: {e}\")\nelse:\n  print(\"No se ha producido ningun error\")\nfinally:\n  print(\"el programa finalizo sin deneterse\")"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/k-90.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado. \n */\n\"\"\"\n\na = 5\nb = 0\n\ntry:\n    c = a/b\nexcept ZeroDivisionError:\n    print(\"No se puede dividir entre cero\")\n\ntry:\n    print(5/0)\nexcept Exception as e:\n    print(f\"No se puede dividir: {e}({type(e).__name__})\")\n\nmy_list = [0,2,4,6,8]\n\ntry:\n    number = 10\n    if number in my_list:\n        print(number)\n    if number not in my_list:\n        my_list.append(number)\n        print(my_list)\nexcept:\n    print(\"Este número no pertenece a la lista\")\n\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/kenysdev.py",
    "content": "# ╔═════════════════════════════════════╗\n# ║ Autor:  Kenys Alvarado              ║\n# ║ GitHub: https://github.com/Kenysdev ║\n# ║ 2024 -  Python                      ║\n# ╚═════════════════════════════════════╝\n\n# -----------------------------------\n# EXCEPCIONES \n# -----------------------------------\n# - Representan una forma de controlar el comportamiento de un programa\n#   cuando se produce un error.\n# - Lista de excepciones que pueden presentarse: \n#   (https://docs.python.org/3/library/exceptions.html) \n#____________________________________\n# Capturar excepciones\na = 7; b = 0\ntry:\n    r = a/b\nexcept ZeroDivisionError:\n    print(\"Error ..\")\n\n#____________________________________\n# Cpturar diferentes exepciones\ntry:\n    #r = int(\"uno\") + 2\n    r = 7 + \"txt\"\nexcept ValueError:\n    print(\"Error al convertir\")\nexcept TypeError:\n    print(\"Error de tipos.\")\n\n#____________________________________\n# Tratar multiples exepciones en el mismo bloque\ntry:\n    #r = 7/0\n    r =7 + \"txt\"\nexcept (ZeroDivisionError, TypeError):\n    print(\"Error Divicion o de tipos\")\n\n#____________________________________\n# Cuando se desconoce el tipo de excepción\nmy_list = [1,2,3]\ntry:\n    print(my_list[7])\nexcept Exception:\n    print(\"Excepción ..\")\n\n# saber que excepción ha ocurrido\ntry:\n    r = int(\"uno\") + 2\nexcept Exception as ex:\n    print(\"Excepción: \", type(ex))\n\n#NOTA: todas las excepciones heredan de \"Exception\".\n\n#____________________________________\n# Uso de else\nmy_list = [1,2,3]\ntry:\n    print(my_list[2])\n    #print(my_list[7])\nexcept IndexError:\n    print(\"Indice fuera del rango\")\nelse:\n    print(\"No hay excepción\")\n\n#____________________________________\n# Uso de finally\n# - Se ejecuta siempre, haya o no una excepción\ntry:\n    r = 5/0\nexcept:\n    print(\"Excepción\")\nfinally:\n    print(\"bloque finally\")\n\n#____________________________________\n# Uso de raise para ejecutar una excepción\n'''\nraise ZeroDivisionError(\"Error Divicion\")\nraise IndexError\nraise TypeError(\"..\")\n'''\n\n# -----------------------------------\n# Definiendo Excepciones\n# -----------------------------------\n# Para crear una excepción, solamente tenemos que \n# crear una clase que herede de la clase Exception.\n\nclass Custom_Exception(Exception):\n    def __init__(self, msg=\"Error personalizado\"):\n        self.msg = msg\n        super().__init__(self.msg)\n\n# simulando error\ntry:\n    raise Custom_Exception\n    #raise Custom_Exception(\"Error\")\nexcept Custom_Exception as ex:\n    print(type(ex))\n    print(ex.args)\n    print(ex.msg)\n#____________________________________\n# Pasar a la excepción un argumento en forma de diccionario.\nclass MyExeption(Exception):\n    pass\n\ntry:\n    raise MyExeption({\"msg\":\"Mensaje\", \"info\":\"Informacion\"})\nexcept MyExeption as ex:\n    dic = ex.args[0]\n    print(dic)\n    print(dic[\"msg\"])\n    print(dic[\"info\"])\n\n# -----------------------------------\n# Ejercicio:\n# -----------------------------------\n\"\"\"\n* Crea una función que sea capaz de procesar parámetros, pero que también\n* pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n* corresponderse con un tipo de excepción creada por nosotros de manera\n* personalizada, y debe ser lanzada de manera manual) en caso de error.\n* - Captura todas las excepciones desde el lugar donde llamas a la función.\n* - Imprime el tipo de error.\n* - Imprime si no se ha producido ningún error.\n* - Imprime que la ejecución ha finalizado. \n\"\"\"\n\nclass OddNumberError(Exception):\n    pass\n\ndef division(a, b):\n    if b % 2 != 0:\n        raise OddNumberError\n    return (f\"\\n- El resultado es: {a/b}\")\n\ndef operation(a, b):\n    try:\n        print(division(a, b))\n\n    except TypeError as ex:\n        print(\"\\nError: No se permite texto. ->\", type(ex))\n\n    except ZeroDivisionError as ex:\n        print(\"\\nError: No es posible dividir entre 0.->\", type(ex))\n\n    except OddNumberError as ex:\n        print(\"\\nError: no dividir entre impares. ->\", type(ex))\n\n    else:\n        print(\"- No hubo errores.\")\n\n    finally:\n        print(\"- Operación terminada.\")\n\nprint(\"\\n___________\\nEjercicio:\")\noperation(10, \"uno\")\noperation(10, 0)\noperation(10, 5)\noperation(10, 2)\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/kuroz00.py",
    "content": "'''//////\n * Explora \n   el concepto de manejo de excepciones según tu lenguaje./////\n'''\n\n'''\n###Definicion corta\n Se trata de una forma de controlar el comportamiento de\n un programa cuando se produce un error. Salvo que tratemos este error, \n el programa se parará\n '''\na = 5\nb = \"0\"\n#print(a / b) error! \n\n#Usando try except se puede capturar el error en caso de que tire el error de div por 0\ntry:\n    print(a / b)\nexcept ZeroDivisionError:\n    print('No se pueden dividir entre 0...')\nexcept TypeError:\n    print(\"Error de tipo!\")\n\nlistado = [0, 1, 2, 3, 4]\n#print(listado[5]) #IndexError error...\n\ntry:\n    print(listado[5])\nexcept IndexError:\n    print(\"No se puede acceder a dicho indice, quizas porque no existe\")\n\n\n#La dificultad extra la hare despues :( entre el trabajo y la u no me da la cabeza, les he fallado TT_TT\n\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/lesterdavid31.py",
    "content": "\n# while True:\n# n1 = int(input(\"Ingrese Dividendo:\"))\n# n2 = int(input(\"Ingrese Divisor:\"))\n# try:\n#     r= n1 / n2\n#     print(r)\n# except:\n#     print(\"No se puede dividir entre 0\")\n    \n\n\n# frutas = ['mango','bananos','durazno','fresa']\n# try:\n#     print(f'la fresa se encuentra en la posición',frutas[4])\n# except Exception:\n#     print('El indice no existe')\n#     print('intentalo de nuevo')\n\n\n\ndef studentNotes(codigo,materia,notas):\n    lista = []\n    try:\n        try:\n            with open(notas) as file:\n                for line in file:\n                    try:\n                        datos = line.strip().split(',')\n                        #print(datos)\n                        if len(datos) != 3:\n                            raise IndexError(f'La línea no tiene el formato esperado: {line.strip()}') \n\n\n                        estudiante = {'id':int(datos[0]), 'Nombre':datos[1],'Promedio':int(datos[2])}\n                        lista.append(estudiante) \n                    except ValueError:\n                        print(f\"Error de conversión en la línea : {line.strip()}. Se espera un entero en 'id' o 'promedio'.\")\n                    except IndexError as e:\n                        print(e)\n\n        except FileNotFoundError as fnf_error:\n            print(fnf_error)\n            print(f'Explanation: We cannot load the {notas}')\n    except IOError:\n        print(f'Error al abrir el archivo {notas}.Verifica los permisos a la ruta ')\n\n    print(f\"codigo de Materia:{codigo}, Matería: {materia}\")\n    for estudiante in lista:\n        print(estudiante)\n\n\nstudentNotes(43,'Matemáticas','notas.txt')\n\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/m1l0j05.py",
    "content": "# Teoría\n\n# Las excepciones en Python son eventos que ocurren durante la ejecución de un programa y que \n# interrumpen el flujo normal de ejecución. Pueden ser causadas por errores de sintaxis, \n# errores durante la ejecución del programa o condiciones inesperadas que hacen que el \n# programa no pueda continuar su ejecución normal.\n\n# Para controlar las excepciones en Python, se utiliza el bloque `try` junto con uno o más \n# bloques `except`. El código que puede generar una excepción se coloca dentro del bloque \n# `try`, y el código que maneja la excepción se coloca dentro del bloque `except`. Si se \n# produce una excepción dentro del bloque `try`, Python busca un bloque `except` cuyo tipo de \n# excepción coincida con la excepción producida. Si encuentra uno, ejecuta el código dentro de \n# ese bloque `except`. Si no se encuentra ningún bloque `except` adecuado, la excepción se \n# propaga hacia arriba en la pila de llamadas.\n\n#Aquí tienes un ejemplo de cómo se controlan las excepciones en Python:\ndef example():\n    try:\n        # Código que puede generar una excepción\n        numero = int(input(\"Ingrese un número: \"))\n        resultado = 10 / numero\n        print(\"El resultado es:\", resultado)\n\n    except ValueError:\n        # Manejo de la excepción ValueError (cuando se ingresa un valor no válido)\n        print(\"Error: Por favor ingrese un número válido.\")\n\n    except ZeroDivisionError:\n        # Manejo de la excepción ZeroDivisionError (cuando se intenta dividir por cero)\n        print(\"Error: No se puede dividir por cero.\")\n\n    except Exception as e:\n        # Manejo de cualquier otra excepción no especificada\n        print(\"Se produjo un error:\", e)\n\n    else:\n        # Se ejecuta si no se produce ninguna excepción\n        print(\"No se produjeron errores.\")\n\n    finally:\n        # Se ejecuta siempre, sin importar si se produjo una excepción o no\n        print(\"Finalizando programa.\")\n\n# En este ejemplo, el bloque `try` contiene el código que puede generar una excepción \n# (división por cero o conversión de cadena a entero). Los bloques `except` manejan diferentes \n# tipos de excepciones que pueden ocurrir. El bloque `else` se ejecuta si no se produce \n# ninguna excepción, y el bloque `finally` se ejecuta siempre, sin importar si se produce una \n# excepción o no.\n\n\n# Ejercicio\ndef ejercicio_1():\n    mi_lista=[1,2,3]\n\n    try:\n        print('\\n[+] Imprimiendo elemento de la lista:')\n        print(mi_lista[7])\n    except IndexError as error:\n        print(f'[!] Indice incorrecto: {error}')\n    finally:\n        print('[+] Programa finalizado correctamente.\\n')\n\ndef ejercicio_2():\n    try:\n        print('\\n[+] Dividiendo entre 0:')\n        print(10/0)\n    except ZeroDivisionError as error:\n        print(f'[!] No se puede dividir entre 0: {error}')\n    finally:\n        print('[+] Programa finalizado correctamente.\\n')\n\nejercicio_1()\nejercicio_2()\n\n# Extra\nclass MiExcepcionPersonalizada(Exception):\n    pass\n\ndef ejercicio_extra(parametro):\n    try:\n        if not isinstance(parametro, int):\n            raise TypeError('El parametro debe ser un número entero.')\n        elif parametro == 0:\n            raise ValueError('El parametro no puede ser cero.')\n        elif parametro < 0:\n            raise MiExcepcionPersonalizada('El parametro no puede ser negativo.')\n        else:\n            print(\"Procesamiento exitoso.\")\n    \n    except TypeError as error:\n        print(f'[!] Error: {error}')\n    except ValueError as error:\n        print(f'[!] Error: {error}')\n    except Exception as error:\n        print(f'[!] Error: {error}')\n    else:\n        print(\"No se produjeron errores.\")\n    finally:\n        print(\"Finalizando ejecución.\")\n\ntry:\n    ejercicio_extra(\"texto\")\n    print('')\n    ejercicio_extra(0)\n    print('')\n    ejercicio_extra(10)\n    print('')\n    ejercicio_extra(-10)\n    print('')\n\nexcept Exception as e:\n    print(\"Se produjo un error:\", e)\nfinally:\n    print(\"Ejecución finalizada.\")\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/majinka10.py",
    "content": "lista = [3]\n\n# De manera general\ndef removerElemento(lista, elemento):\n    try:\n        lista.remove(elemento)\n        print(f'Se pudo remover el elemento: {elemento}')\n    except Exception as e:\n        print(f'Ha ocurrido: {e}')\n\nremoverElemento(lista, 3)\nremoverElemento(lista, 3)\n    \n# De manera específica\ndef division(a:int, b: int) -> int:\n    try:\n        print(a/b)\n    except ZeroDivisionError:\n        print(f'No se puede dividir entre cero {ZeroDivisionError}')\n    \ndivision(10, 2)\ndivision(5, 0)\n\n# Ejercicio EXTRA\nprint(\"\\nFunción que procesa parámetros o lanza excepciones\\n\")\n\nclass InvalidRoot(Exception):\n    def __init__(self, mensaje = \"InvalidRoot\"):\n        self.mensaje = mensaje\n        super().__init__(self.mensaje)\n\ndef operaciones(numero) -> int:\n    try:\n        if numero < 0:\n            raise InvalidRoot(\"El número no puede ser negativo.\")\n        elif numero == 0:\n            raise ValueError(\"El número no puede ser cero.\")\n        elif isinstance(numero, float):\n            raise ValueError(\"El número no puede ser flotante.\")\n        else:\n            print(\"El parámetro se procesó correctamente.\")\n    except (ValueError, InvalidRoot) as e:\n        print(f'Excepción de valor: {e}')\n    except Exception as e:\n        print(f\"Error inesperado: {e}\")\n    else: \n        print(\"No se produjo ningún error.\")\n    finally:\n        print(\"La ejecución ha finalizado.\\n\")\n\noperaciones(-3.5)\noperaciones(0)\noperaciones(5.7)\noperaciones(3)"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/mariovelascodev.py",
    "content": "#Ejercicio\n\nmi_variable = 2\n\n#Capturamos el tipo de error producido en el codigo\ntry:\n    print(variable)\nexcept Exception as e:\n    print(f\"Se ha producido un error: {e}\")\n\n#Capturamos un tipo de error especifico\ntry:\n    print(10/0)\nexcept ZeroDivisionError:\n    print(\"No se puede dividir por cero\")\n\nmi_lista = [0, 1, 2]\ntry:\n    print(mi_lista[4])\nexcept IndexError:\n    print(\"El indice al que intentas acceder no existe en la lista\")\n\n#Extra\n\n# Creamos una excepción personalizada\nclass MiExcepcionPersonalizada(Exception):\n    pass\n\n\ndef procesa_parametros(parametros: list):\n    if parametros[2] == 0:\n        raise ZeroDivisionError()\n    elif type(parametros[0]) == str:\n        raise MiExcepcionPersonalizada\n    elif len(parametros) < 3:\n        raise IndexError()\n    \n    print(parametros[2] / parametros[1])\n    print(parametros[0])\n    print(parametros[2])\n\ntry:\n    procesa_parametros([1, 2, 3])\nexcept ZeroDivisionError:\n    print(\"El segundo parametro no puede ser 0\")\nexcept MiExcepcionPersonalizada:\n    print(\"El primer elementos no puede ser una cadena\")\nexcept IndexError:\n    print(\"El numero de elementos debe ser mayor que 2\")\nexcept Exception as e:\n    print(f\"Se ha producido un error del tipo: {e}\")\nelse:\n    print(\"No se han producido errores\")\nfinally:\n    print(\"El programa ha finalizado\")\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/mensius87.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado.\n */\n\n\"\"\"\n\nnum1 = 10\nnum2 = 0\n\ntry:\n    print(f\"El resutaldo de {num1}:{num2}={num1/num2}\")\nexcept:\n    print(\"Ha habido un error, revisa que la división sea posible.\")\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/mhayhem.py",
    "content": "# EJERCICIO:\n# Explora el concepto de manejo de excepciones según tu lenguaje.\n# Fuerza un error en tu código, captura el error, imprime dicho error\n# y evita que el programa se detenga de manera inesperada.\n# Prueba a dividir \"10/0\" o acceder a un índice no existente\n# de un listado para intentar provocar un error.\n\ndef sum(n1: int, n2: int):\n    try:\n        return n1 + n2\n    except Exception as e:\n        return f\"Ha habido un error {e}: ({type(e).__name__})\"\n\n\n# DIFICULTAD EXTRA (opcional):\n# Crea una función que sea capaz de procesar parámetros, pero que también\n# pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n# corresponderse con un tipo de excepción creada por nosotros de manera\n# personalizada, y debe ser lanzada de manera manual) en caso de error.\n# - Captura todas las excepciones desde el lugar donde llamas a la función.\n# - Imprime el tipo de error.\n# - Imprime si no se ha producido ningún error.\n# - Imprime que la ejecución ha finalizado. \n\nclass HigherDividendError(Exception):\n    pass\n\ndef catch_errors(array: list):\n    if len(array) < 2:\n        raise IndexError()\n    elif array[1] == 0:\n        raise ZeroDivisionError()\n    elif array[1] > array[0]:\n        raise HigherDividendError(\"EL segundo elemento no puede ser mayor que el primer elemento\")\n    \n    print(array[5])\n    \n    print(array[0] / array[1])\n    \ntry:\n    catch_errors([1])\nexcept IndexError as e:\n    print(f\"El array debe de contener mínimo 2 elementos: {e}.\")\nexcept ZeroDivisionError as e:\n    print(f\"El segundo elemento del array no puede ser cero: {e}.\")\nexcept HigherDividendError as e:\n    print(f\"{e}\")\nexcept Exception as e:\n    print(f\"Se produjo un error inexperado: {e}\")\nelse:\n    print(\"Se ejecuto sin errores\")\nfinally:\n    print(\"Ejecución finalizada\")"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/miguelex.py",
    "content": "# Ejemplo de exepcion por division por cero\n\ndef division(a, b):\n    try:\n        return a / b\n    except ZeroDivisionError:\n        return \"No se puede dividir por cero\"\n    \nprint(division(10, 0))\nprint(division(5, 3))\n\n# Ejemplo de excepcion por indice fuera de rango\n\ndef outOfRange(lista, indice):\n    try:\n        return lista[indice]\n    except IndexError:\n        return \"Indice fuera de rango\"\n    \nprint(outOfRange([1, 2, 3], 5))\n\nclass MiError(Exception):\n    def __init__(self, valor):\n        self.valor = valor\n    def __str__(self):\n        return \"Error: \" + str(self.valor)\n        \ndef extra (a, b, c):\n    if not isinstance(a, str) or not a:\n        raise ValueError(\"El primer parametro debe ser un string y no vacio\")\n    if not isinstance(b, int) or b <= 0:\n        raise ValueError(\"El segundo parametro debe ser un entero y mayor que 0\")\n    if not isinstance(c, str):\n        raise TypeError(\"El tercer parametro debe ser un string\")\n    if c == \"Mouredev\":\n        raise MiError(\"El tercer parametro no puede ser Mouredev\")\n    return f\"Solucion reto {b} - {a} del usuario {c}\"\n\ntry:\n    #print(extra(\"Swift\", 10, \"Mouredev\"))\n    #print(extra(\"Python\", 10, \"Miguelex\"))\n    #print(extra(\"PHP\", -5, \"Miguelex\"))\n    print(extra(\"\", 10, \"Miguelex\"))\nexcept ValueError as e:\n    print(e)\nexcept TypeError as e:\n    print(e)\nexcept MiError as e:\n    print(e)\nelse:\n    print(\"Todo ha ido bien\")\n    \n\n    \n\n\n\n    \n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/mikelm2020.py",
    "content": "def divition(divider: int, dividend: int):\n    try:\n        result = dividend / divider\n        return result\n    except ZeroDivisionError:\n        print(\"Error: La división entre cero no es permitida\")\n    except TypeError:\n        print(\"Error: El Dividendo y el divisor deben ser números enteros.\")\n    except Exception as e:\n        print(\"Un error inesperado ha ocurrido:\", str(e))\n\n\nclass DictTypeError(Exception):\n    pass\n\n\ndef process_parameters(parameters: list):\n    if len(parameters) < 2:\n        raise IndexError(\"La lista debe tener al menos dos elementos.\")\n    elif type(parameters[0]) is not int or type(parameters[1]) is not int:\n        raise DictTypeError(\"Los elementos de la lista deben ser números enteros.\")\n\n    try:\n        result = divition(parameters[0], parameters[1])\n        print(\n            f\"El resultado de dividir {parameters[0]} entre {parameters[1]} es: {result}\"\n        )\n    except Exception as e:\n        print(f\"Ha ocurrido un error inesperado: {e}\")\n\n\nif __name__ == \"__main__\":\n    print(f\"El resultado de dividir 120 entre cero es: {divition(0,120)}\")\n\n    try:\n        process_parameters([2, \"a\"])\n    except IndexError as e:\n        print(f\"{e}\")\n    except ZeroDivisionError as e:\n        print(f\"{e}\")\n    except DictTypeError as e:\n        print(f\"{e}\")\n    except Exception as e:\n        print(f\"{e}\")\n    else:\n        print(\"No se ha producido ningún error.\")\n    finally:\n        print(\"El programa finaliza sin detenerse.\")\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/monicavaquerano.py",
    "content": "# 10 EXCEPCIONES\n# Monica Vaquerano\n# https://monicavaquerano.dev\n\n\"\"\"\nEJERCICIO:\nExplora el concepto de manejo de excepciones según tu lenguaje.\nFuerza un error en tu código, captura el error, imprime dicho error\ny evita que el programa se detenga de manera inesperada.\nPrueba a dividir \"10/0\" o acceder a un índice no existente\nde un listado para intentar provocar un error.\n\"\"\"\n\nprint(\"--- EXCEPCIONES ---\")\n# El manejo de excepciones en Python permite a los programas manejar situaciones inesperadas o errores de manera controlada.\n# Manejo de excepciones\nprint(\"\\n* Manejo de excepciones\")\ntry:\n    a = 10 / 0\n    print(a)\nexcept ZeroDivisionError as error:\n    print(f\"Ha ocurrido un error: {error}\")\n\nprint(\"\\n* Manejo de varias excepciones\")\ntry:\n    print(x)\nexcept ZeroDivisionError as error:\n    print(f\"Ha ocurrido un error: {error}\")\nexcept Exception as error:\n    print(f\"Algo más salió mal: {error}\")\n\nprint(\"\\n* El uso del bloque 'else'\")\ntry:\n    print(\"Todo bien por acá\")\nexcept ZeroDivisionError as error:\n    print(f\"Ha ocurrido un error: {error}\")\nexcept Exception as error:\n    print(f\"Algo más salió mal: {error}\")\nelse:\n    print(\"Esta vez nada puede malir sal.\")\n\nprint(\"\\n* El uso del bloque 'finally'\")\ntry:\n    print(10 / 0)\nexcept ZeroDivisionError as error:\n    print(f\"Ha ocurrido un error: {error}\")\nexcept Exception as error:\n    print(f\"Algo más salió mal: {error}\")\nfinally:\n    print(\"El bloque 'try except' se terminó.\")\n\n\nprint(\"\\n* Levantar o forzar una excepción (raise an exception)\")\nprint(\"x =\", x := -1)\ntry:\n    if x < 0:\n        raise Exception(\"Sorry, no numbers below zero\")\nexcept Exception as error:\n    print(f\"Se levantó la siguiente excepción: {error}\")\n\n\nprint(\"\\nDIFICULTAD EXTRA (opcional):\")\n\"\"\"\nCrea una función que sea capaz de procesar parámetros, pero que también\npueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\ncorresponderse con un tipo de excepción creada por nosotros de manera\npersonalizada, y debe ser lanzada de manera manual) en caso de error.\n- Captura todas las excepciones desde el lugar donde llamas a la función.\n- Imprime el tipo de error.\n- Imprime si no se ha producido ningún error.\n- Imprime que la ejecución ha finalizado. \n\"\"\"\n\n\ndef exceptionHandler(params):\n    print(\"\\nProcesando excepciones...\")\n    if len(params) < 3:\n        raise IndexError\n    elif params[0] == 0:\n        raise ZeroDivisionError\n    elif params[1] != \"monica\":\n        raise NameError\n\n\nlist = [1, \"bob\", 3, 4]\n\ntry:\n    exceptionHandler(list)\nexcept ZeroDivisionError:\n    print(f\"No es posible dividir entre cero\")\nexcept IndexError:\n    print(f\"No es posible accesar a ese indice\")\nexcept NameError:\n    print(f\"Este no es el nombre correcto, variable no esta definida\")\nexcept Exception as e:\n    print(f\"Ha ocurrido el siguiente error: {e}\")\nelse:\n    print(\"Nada ha salido mal\")\nfinally:\n    print(\"La ejecución de la función ha finalizado\")\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/mordevspt.py",
    "content": "\"\"\"\nExplora el concepto de manejo de excepciones según tu lenguaje.\nFuerza un error en tu código, captura el error, imprime dicho error\ny evita que el programa se detenga de manera inesperada.\n\nPrueba a dividir \"10/0\" o acceder a un índice no existente\nde un listado para intentar provocar un error.\n\"\"\"\n# ZeroDivisionError\ndef dividirDosNumeros(numero1:int,numero2:int):\n    try:\n        resultado = numero1/numero2\n        print(resultado)\n    except ZeroDivisionError as e:\n        print(f\"ZeroDivisionError - Se ha producido un error al intentar dividir dos números {numero1}/{numero2}, el error es [{str(e)}]\")\n    finally:\n        print(\"Continuamos con el programa sin que finalice\")\n\ndividirDosNumeros(10,0)\n\n# ValueError - Si no es del tipo ...\n# TypeError  - Si es de tipo ...\ndef solicitar_edad(edad):\n    try:\n        if int(edad) >= 18:\n            print(\"Eres un adulto.\")\n        else:\n            print(\"Aún no eres un adulto.\")\n    except ValueError as ve:\n        print(f\"ValueError - Se ha producido un error [{str(ve)}]\")\n    except TypeError as te:\n        print(f\"TypeError - Se ha producido un error [{str(te)}]\")\n\nsolicitar_edad(\"a\")\nsolicitar_edad([1,2])\n\n# IndexError - Un índice que no existe\nlista_dias_semana = [\"lunes\",\"martes\",\"miércoles\",\"jueves\",\"viernes\",\"sabado\",\"domingo\"]\ndef dias_semana(indice):\n    try:\n        print(lista_dias_semana[indice])\n    except IndexError as e:\n        print(f\"IndexError - Se ha producido un error [{str(e)}]\")\n\ndias_semana(8)\n\n# KeyError - Una clave que no está en el diccionario\nlenguages = {\"Python\": 1991, \"C\": 1972}\ndef request_languages(language):\n    try:\n        print(lenguages[language])\n    except KeyError as e:\n        print(f\"KeyError - Se ha producido un error [{str(e)}]\")\n\nrequest_languages(\"Java\") \n\n# Elevar nuestras propias excepciones\ndef sumar(a, b):\n    if not isinstance(a, int) or not isinstance(b, int):\n        raise TypeError(\"a y b tienen que ser números enteros.\")\n    return a + b\n        \ntry:\n    resultado = sumar(\"1\",5)\n    print(resultado)\nexcept TypeError as e:\n    print(f\"TypeError - Se ha producido un error [{str(e)}]\")\n    \nprint(\"Está línea se ejectuará pase lo que pase.\") \n        \n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\nCrea una función que sea capaz de procesar parámetros, pero que también\npueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\ncorresponderse con un tipo de excepción creada por nosotros de manera\npersonalizada, y debe ser lanzada de manera manual) en caso de error.\n- Captura todas las excepciones desde el lugar donde llamas a la función.\n- Imprime el tipo de error.\n- Imprime si no se ha producido ningún error.\n- Imprime que la ejecución ha finalizado. \n\n\"\"\"\n\nprint(\"\\nEXTRA\\n\")\n\n# Creamos una clase que derive de Exceptions, para crear nuestras propias excepciones\nclass invalidAgeException(Exception):\n    \"Debe ser mayor de edad para comprar su entrada\"\n    pass\n\n# Función de comprobación de compra de entradas\ndef ticketSale(name,age):\n    # Programa\n    minimalAge = 18\n    # Operaciones\n    if not isinstance(age, int):\n        raise ValueError(\"La edad tiene que ser un número entero.\")\n    elif not isinstance(name, str) or len(name) == 0:\n        raise TypeError(\"El nombre tiene que tiene que tener al menos un caracter.\")\n    else:\n        if age < minimalAge:\n            raise invalidAgeException\n        else:\n            return f\"Puede comprar su entrada {name}\"\n        \n# Comprobación\ntry:\n    # Ejecutamos\n    #print(ticketSale(\"\", 16)) # Devuelve un TypeError\n    #print(ticketSale(\"Juan\", \"1\")) # Deuelve un ValueError\n    #print(ticketSale(\"Pepe\", 16)) # Devuelve un invalidAgeException\n    print(ticketSale(\"Jose\", 18)) # OK\nexcept invalidAgeException:\n    print(\"Personalizada - Ha ocurrido una excepción: Eres un menor edad\")\nexcept TypeError as te:\n    print(f\"TypeError - Se ha producido un error [{str(te)}]\")\nexcept ValueError as ve:\n    print(f\"ValueError - Se ha producido un error [{str(ve)}]\")\nexcept Exception as e:\n    print(f\"Exception - Se ha producido un error [{str(e)}]\")\nelse:\n    print(\"No se han producido errores\")\nfinally:\n    print(\"El programa ha finalizado\")"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/mouredev.py",
    "content": "\"\"\"\nEjercicio\n\"\"\"\n\ntry:\n    print(10/0)\n    print([1, 2, 3, 4][4])\nexcept Exception as e:\n    print(f\"Se ha producido un error: {e} ({type(e).__name__})\")\n\n\"\"\"\nExtra\n\"\"\"\n\n\nclass StrTypeError(Exception):\n    pass\n\n\ndef process_params(parameters: list):\n\n    if len(parameters) < 3:\n        raise IndexError()\n    elif parameters[1] == 0:\n        raise ZeroDivisionError()\n    elif type(parameters[2]) == str:\n        raise StrTypeError(\n            \"El tercer elemento no puede ser una cadena de texto.\")\n\n    print(parameters[2])\n    print(parameters[0]/parameters[1])\n    print(parameters[2] + 5)\n\n\ntry:\n    process_params([1, 2, 3, 4])\nexcept IndexError as e:\n    print(\"El número de elementos de la lista debe ser mayor que dos.\")\nexcept ZeroDivisionError as e:\n    print(\"El segundo elemento de la lista no puede ser un cero.\")\nexcept StrTypeError as e:\n    print(f\"{e}\")\nexcept Exception as e:\n    print(f\"Se ha producido un error inesperado: {e}\")\nelse:\n    print(\"No se ha producido ningún error.\")\nfinally:\n    print(\"El programa finaliza sin detenerse.\")\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/mrodara.py",
    "content": "#################### EXCEPCIONES EN PYTHON ############################\n\n'''\nUna excepción o un error de ejecución se produce durante la ejecución del programa. \nLas excepciones se pueden manejar para que no termine el programa.\n'''\n\n# Excepción de división por cero\ntry:\n    a = 10/0\nexcept ZeroDivisionError:\n    print(\"No se puede dividir por cero\")\nfinally:\n    print(\"Finalizó la ejecución\")\n\nmy_list = [i for i in range(5)]\n\ntry:\n    print(my_list[5]) # Genera un IndexError\nexcept IndexError:\n    print(f\"Índice fuera de rango, mostramos el último elemento de la lista: {my_list[-1]}\")\n\n# Definir una excepción propia\n'''\nPara crear un tipo de excepción personalizada en Python, podemos definir una nueva clase que herede \nde la clase base de excepciones. \nEsto permite generar errores específicos para ciertos casos en tu aplicación.\n'''\nclass MyException(Exception):\n    def __init__(self, message: str = \"Error personalizado\") -> None:\n        super().__init__(message)\n        \ntry:\n    raise MyException(\"Este es un error personalizado\")\nexcept MyException as e:\n    print(f\"Captura de la excepción: {e}\")\n    \n#################### FIN EXCEPCIONES EN PYTHON ############################\n\n#################### EXTRA ############################\n\ndef my_exception_managment(value1 : int = 0, value2 : int = 0, value3: tuple = (), boolvalue: bool = True) -> None:\n    try:\n        return value1 / value2\n    except ZeroDivisionError:\n        print(\"No se puede dividir por cero\")\n        \n    try:\n        value2 + value3\n    except TypeError:\n        print(\"No se puede sumar un entero con un string\")\n    \n    try:\n        print(value4)\n    except NameError:\n        print(\"La variable no está definida\")# No se puede acceder a una variable no definida\n    finally:\n        print(\"Finalizó la ejecución\")\n    \nmy_exception_managment(10, 0, (1, 2, 3), True)\n\n#################### FIN EXTRA ############################"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/mvidalb.py",
    "content": "'''\nEjercicio\n'''\n\ntry:\n    print(10/1)\n    print([1, 2, 3, 4][4])\n\nexcept Exception as e:\n    print(f\"Error: {e}\")    #type(e).__name__ para conocer el tipo de error\n\nfinally:\n    print(\"Esto siempre se ejecuta\")\n\n\n'''\nEjercicio extra\n'''\nclass StrTypeError(Exception):\n    pass\n\n\n\ndef process_params(parameters: list):\n\n    if len(parameters) < 3:\n        raise IndexError()\n    elif parameters[1] == 0:\n        raise ZeroDivisionError()\n    elif type(parameters[2])== str:\n        raise StrTypeError(\"El tercer elemento no puede ser una cadena de texto.\")\n\n    print(parameters[2])\n    print(parameters[0]/parameters[1])\n    print(parameters[2] + 5)\n\n\ntry:\n    process_params([1, 2, 3, 4])\nexcept IndexError as e:\n    print(\"El número de elementos de la lista debe ser mayor que dos.\")\nexcept ZeroDivisionError as e:\n    print(\"El segundo elemento de la lista no puede ser un cero.\")\nexcept StrTypeError as e:\n    print(f\"Error: {e}\")\nexcept Exception as e:\n    print(f\"Se ha producido un error inesperado: {e}\")\nelse:       # Se ejecuta cuando no se produce ningún error\n    print(\"No se ha producido ningún error\")\nfinally:    # Se ejecuta siempre\n    print(\"La ejecución ha finalizado.\")\n\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/neslarra.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado.\n\"\"\"\n\nprint(\"\"\"\nUna excepción es un error detectado en tiempo de ejcución, es decir, el programa\npasó OK la revisión sintáctica pero aún así al ejecutar encontró una falla.\nPor ejemplo, tenemos un programa que pide ingresar un divisor:\n...\ndivisor = input(\"Ingrese divisor: \")\nprint(f\"{123 // int(divisor)}\")\n...\nEl programa es sintácticamente correcto, aún así, si ingreso una \"a\" entonces\nme va a devolver un error \"ValueError\", pero sin ingreso un \"0\" el devolverá\nun error \"ZeroDivisionError\" \n\nÉstas son excepciones predefindas en cada clase. Pero puede que tengamos que controlar algún tipo\n\"error lógico\" o \"de regla de negocio\" para lo cual podemos definir excepciones propias.\n\nPor ejemplo, supongamos que el divisor requerido tiene que se rmayor a 3 y menor a 9: creo una\nclase que herede Exception a la cual la invoco con \"raise\" cuando encuentre que esta nueva regla\nno se cumple.\n\nclass FueraDeRangoError(Exception):\n    def __init__(self):\n        self.message = \"Solo valores entre 3 y 9 (exclusive).\"\n\n    def __str__(self):\n        return self.message\n\nProbar \"ingresando\" una letra, un 0, un 2 (o un 10) y luego, para el caso, un 6.\n\n\"\"\")\n\n\nclass FueraDeRangoError(Exception):\n    def __init__(self):\n        self.message = \"Solo valores entre 3 y 9 (exclusive).\"\n\n    def __str__(self):\n        return self.message\n\n\ndef funcion(divisor):\n    resto = 123 // int(divisor)\n    if not (3 < int(divisor) < 9):\n        raise FueraDeRangoError\n    return resto\n\n\nwhile True:\n    try:\n        divisor = input(\"Ingrese divisor: \")\n        resto = funcion(divisor)\n    except Exception as e:\n        print(f\"Te topaste con la excepción {e.__class__.__name__} => {e}\")\n    else:\n        print(f\"Resto = {resto}\")\n        break\n\nprint(f\"\\n{'#' * 50}\\nDificultad Extra\\n{'#' * 50}\", end=\"\\n\\n\")\nprint(f\"Los lineamientos de la dificultad extra están incluídos en el ejemplo de la explicación.\")\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/nlarrea.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado. \n\"\"\"\n\nfrom typing import Iterable, final\n\n\nmonths = [\n    \"January\",\n    \"February\",\n    \"March\",\n    \"April\",\n    \"May\",\n    \"June\",\n    \"July\",\n    \"August\",\n    \"September\",\n    \"October\",\n    \"November\",\n    \"December\",\n]\n\ntry:\n    my_result = 10 / 0  # ZeroDivisionError\n    my_item = months[12]  # IndexError\nexcept Exception as error:\n    print(f\"{type(error).__name__}: {error}\")\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado. \n\"\"\"\n\n\nclass UnknownTypeError(Exception):\n    pass\n\n\ndef process_params(*args):\n    for arg in args:\n        if type(arg) == bool:\n            raise UnknownTypeError(\"I don't know what a bool is..\")\n        if type(arg) == int:\n            arg /= 0\n        if type(arg) == list:\n            print(arg[len(arg)])\n\n        print(arg)\n\n\ntry:\n    process_params(1, True, \"false\", [1, 2, 3])\nexcept UnknownTypeError as e:\n    print(f\"{type(e).__name__}: {e}\")\nexcept ZeroDivisionError:\n    print(\"You can't divide by zero!\")\nexcept IndexError:\n    print(\"The list is smaller than the index used.\")\nelse:\n    print(\"No error has been raised.\")\nfinally:\n    print(\"The program has finished.\")\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/oniricoh.py",
    "content": "\ndef division(x :int, y :int) ->float:\n    try:\n        return x/y\n    except ZeroDivisionError:\n        return \"No se puede dividir entre 0\"\n\nprint(division(10, 0))\n\n\n###############################################################################\n## DIFICULTAD EXTRA\n###############################################################################\n\nclass DividendError(Exception):\n    pass\n\ndef division(x: int, y: int):\n    try:\n        if y == 0:\n            raise ZeroDivisionError(\"No se puede dividir por cero\")\n        elif x < y:\n            raise DividendError(\"El dividendo debe ser mayor al divisor\")\n        result = x / y\n        print(\"Resultado de la división:\", result)\n    except ZeroDivisionError as err:\n        print(\"Error:\", err)\n    except DividendError as err:\n        print(\"Error:\", err)\n    except Exception as e:\n        print(\"Error inesperado:\", e)\n    else:\n        print(\"No se ha producido ningún error.\")\n    finally:\n        print(\"La ejecución ha finalizado.\")\n\nx = int(input(\"Introduce un valor para X: \"))\ny = int(input(\"Introduce un valor para Y: \"))\n\ndivision(x, y)\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/oriaj3.py",
    "content": "\"\"\"\t\n10 -EXCEPCIONES\n\nAutor de la solución: Oriaj3\t\n\nTeoría:\n\nLas excepciones son errores que se producen durante la ejecución de un programa. \nCuando se produce una excepción, el programa se detiene y se genera un mensaje \nde error que indica la causa del problema.\n\nEn Python, las excepciones se manejan con bloques try-except. El código que\npuede generar una excepción se coloca dentro del bloque try\ny el código que maneja la excepción se coloca dentro del bloque except.\n\nLas excepciones se pueden clasificar en dos tipos:\n- Excepciones del sistema: son las que proporciona el propio lenguaje.\n- Excepciones personalizadas: son las que creamos nosotros mismos.\n\nLas excepciones del sistema se pueden capturar de manera individual o todas\njuntas. Si se capturan todas juntas, se debe tener cuidado de no ocultar\nerrores importantes.\n\nLas excepciones personalizadas se crean mediante la herencia de la clase\nException. Esto permite definir un comportamiento específico para cada tipo\nde excepción.\n\nLas excepciones se pueden lanzar de manera manual con la palabra clave raise.\n\nLas excepciones se pueden capturar y manejar de manera anidada, es decir, se\npuede capturar una excepción dentro de otra excepción. Esto es útil para\nproporcionar información adicional sobre el error. \n\"\"\"\n\n\"\"\"\n* EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n\"\"\"\ntry: \n    print(10/0)\n    print([1, 2, 3, 4][4])\nexcept Exception as e:\n    print(f\"Se ha producido un error: {e} ({type(e).__name__})\")\n\nlista = [1, 2, 3, 4]\n\ntry:\n    print(lista[4])\nexcept Exception as e:\n    print(f\"Se ha producido un error: {e} ({type(e).__name__})\")\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado. \n */\n\"\"\"\n\nclass MyNegativeException(Exception):\n    error_type = \"MyNegativeException\"\n\n    def __init__(self, message):\n        self.message = message\n        super().__init__(self.message)\n\n    def __str__(self):\n        return f\"{self.error_type}: {self.message}\"\n    \n\ndef process_params(parameters: list):\n\n    if len(parameters) < 3:\n        raise IndexError()\n    elif parameters[1] == 0:\n        raise ZeroDivisionError()\n    elif type(parameters[2]) == str:\n        raise TypeError(\n            \"El tercer elemento no puede ser una cadena de texto.\")\n    elif parameters[2] < 0:\n        raise MyNegativeException(\"El tercer elemento no puede ser negativo.\")\n\n    print(parameters[2])\n    print(parameters[0]/parameters[1])\n    print(parameters[2] + 5)\n\n#Llamada a la función process_params con diferentes parámetros que producen errores.\ntry: \n    process_params([1, 0, 3])\nexcept IndexError as e:\n    print(f\"Se ha producido un error: {e} ({type(e).__name__})\")\nexcept ZeroDivisionError as e:\n    print(f\"Se ha producido un error: {e} ({type(e).__name__})\")\nexcept MyNegativeException as e:\n    print(f\"Se ha producido un error: {e} ({type(e).__name__})\")\nexcept Exception as e:\n    print(f\"Se ha producido un error: {e} ({type(e).__name__})\")\n#Imprime si no se ha producido ningún error.\nelse:\n    print(\"No se ha producido ningún error.\")\n\nfinally:\n    print(\"La ejecución ha finalizado.\")\n\n#Llamada a la función process_params con parámetros correctos.\ntry: \n    process_params([10, 2, 3])\nexcept IndexError as e:\n    print(f\"Se ha producido un error: {e} ({type(e).__name__})\")\nexcept ZeroDivisionError as e:\n    print(f\"Se ha producido un error: {e} ({type(e).__name__})\")\nexcept MyNegativeException as e:\n    print(f\"Se ha producido un error: {e} ({type(e).__name__})\")\nexcept Exception as e:\n    print(f\"Se ha producido un error: {e} ({type(e).__name__})\")\n#Imprime si no se ha producido ningún error.\nelse:\n    print(\"No se ha producido ningún error.\")\n\nfinally:\n    print(\"La ejecución ha finalizado.\")\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/pguillo02.py",
    "content": "#En python podemos capturar excepciones mediante el bloque try/except\n\ntry:\n    100/0\n\nexcept: \n    print(\"Se ha producido una excepción\")\n\n#Se puede emplear un bloque except específico para una excepción\n    \ntry:\n    100/0\nexcept ZeroDivisionError:\n    print(\"Código específico de la excepción\")\n\n#Al añadir un bloque finally tendremos código que siempre se ejecutará\n    \ntry:\n    100/0\nexcept ZeroDivisionError:\n    print(\"Código de la excepción\")\nfinally:\n    print(\"Código que siempre se ejecutará\")\n\n#Se puede forzar una excepción mediante raise\n    \ni = 12\n\nif i>10:\n    raise ValueError(\"El número a de ser menor que 10\")\n\n#También puedes generar tu propia excepción heredando de la clase exception\nclass MiErrorPersonalizado(Exception):\n    def __init__(self, mensaje=\"Ocurrió un error personalizado\"):\n        self.mensaje = mensaje\n        super().__init__(self.mensaje)\n\n# Uso de la excepción personalizada\nraise MiErrorPersonalizado(\"Error\")\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/pyramsd.py",
    "content": "def div_0():\n    while True:\n        n = int(input('ingrese un numero: '))\n        if n == 0:\n            break\n        try:\n            print(n / 0)\n        except ZeroDivisionError as e: print(f'Error: {e}')\n    \ndiv_0()\n\n\n'''\nEXTRA\n'''\n\n# Definición de una excepción personalizada\nclass MiExcepcionPersonalizada(Exception):\n    def __init__(self, mensaje):\n        super().__init__(mensaje)\n\n\ndef procesar_parametros(parametro):\n    try:\n        if parametro == 1:\n            raise ValueError(\"¡Este es un valor incorrecto!\")\n        elif parametro == 2:\n            raise IndexError(\"¡Índice fuera de rango!\")\n        elif parametro == 3:\n            raise MiExcepcionPersonalizada(\"¡Esto es una excepción personalizada!\")\n        else:\n            print(\"Parámetro válido:\", parametro)\n    except ValueError as ve:\n        print(f\"Error: {ve}\\nTipo: {type(ve).__name__}\")\n    except IndexError as ie:\n        print(f\"Error: {ie}\\nTipo: {type(ie).__name__}\")\n    except MiExcepcionPersonalizada as me:\n        print(f\"Error: {me}\\nTipo: {type(me).__name__}\")\n    else:\n        print(\"No se ha producido ningún error.\")\n    finally:\n        print(\"La ejecución ha finalizado.\")\n\ntry:\n    procesar_parametros(0)\n    procesar_parametros(1)\n    procesar_parametros(2)\n    procesar_parametros(3)\n    procesar_parametros()\nexcept Exception as e:\n    print(\"Tipo de error:\", type(e).__name__)\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/qwik-zghieb.py",
    "content": "# -- exercise\ndef divide(a, b):\n    try:\n        return a / b\n    except ZeroDivisionError as e:\n        return f\"err: {e}\"\n    except Exception as e:\n        return f\"err: {e}\"\n    finally:\n        print(\"the execution has finished\")\n\n\ndef access_list_element(l, i):\n    try:\n        return l[i]\n    except IndexError as e:\n        return f\"err: {e}\"\n    except Exception as e:\n        return f\"err: {e}\"\n    finally:\n        print(\"the execution has finished\")\n\n\nprint(divide(10, 0))\nprint(access_list_element([1, 2, 3], 4))\n\n\n# -- extra challenge\ndef process_parameters(a, b, c):\n    if a < 0:\n        raise ValueError(\"a must be positive\")\n    elif b < 0:\n        raise ValueError(\"b must be positive\")\n    elif c < 0:\n        raise ValueError(\"c must be positive\")\n    return a + b + c\n\n\nprint(\"------ extra challenge ------\")\n\ntry:\n    print(process_parameters(1, 2, 3))\nexcept ValueError as e:\n    print(f\"err: {e}\")\nexcept Exception as e:\n    print(f\"err: {e}\")\nfinally:\n    print(\"the execution has finished\")\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/rantamhack.py",
    "content": "print(\"\\n\\n=====================================¿QUE ES UNA EXCEPCION?=====================================\\n\\n\")\n\n\nprint(\"Al programar en Python algunas veces podemos anticipar errores de ejecucion, incluso en un programa sintactica y\\nlogicamente correcto, puede llegar a haber errores causados por entrada de datos invalidos o inconsistencias predecibles.\")\n\n\nprint(\"\\n\\n=====================================EJERCICIO=====================================\\n\\n\")\n\n'''\n * Explora el concepto de manejo de excepciones segun tu lenguaje.\n * Fuerza un error en tu codigo, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un i­ndice no existente\n * de un listado para intentar provocar un error.\n'''\n\ndef index_error():\n    \n    try:\n        my_list = [1, 2, 3, 4]\n        print(my_list[4])\n    except IndexError as e:\n        print(f\"El elemento no existe en my_list: {e}\")\n        \nindex_error()\n\nprint(\"El programa continua\")\n\nprint(\"\\n\\n==========================================================================\\n\\n\")\n\ndef division_zero():\n    \n    a = 10\n    b = 0\n    \n    try:\n        division = a / b\n        print(division)\n    except ZeroDivisionError as e:\n        print(f\"Dividir por cero no es posible: {e}\")\n        \ndivision_zero()\n\nprint(\"El programa continua\")\n    \n\nprint(\"\\n\\n=====================================DIFICULTAD EXTRA=====================================\\n\\n\")\n\n\n'''\n * Crea una funcion que sea capaz de procesar parmetros, pero que tambien\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepcion creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la funcion.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningun error.\n * - Imprime que la ejecucion ha finalizado\n'''\n\nclass StrTypeError(Exception):\n    pass\n\n\ndef process_params(parameters: list):\n\n    if len(parameters) < 3:\n        raise IndexError()\n    elif parameters[1] == 0:\n        raise ZeroDivisionError()\n    elif type(parameters[2]) == str:\n        raise StrTypeError(\n            \"El tercer elemento no puede ser una cadena de texto.\")\n\n    print(parameters[2])\n    print(parameters[0]/parameters[1])\n    print(parameters[2] + 5)\n\n\ntry:\n    process_params([1, 2, 3, 4])\nexcept IndexError as e:\n    print(\"El numero de elementos de la lista debe ser mayor que dos.\")\nexcept ZeroDivisionError as e:\n    print(\"El segundo elemento de la lista no puede ser un cero.\")\nexcept StrTypeError as e:\n    print(f\"{e}\")\nexcept Exception as e:\n    print(f\"Se ha producido un error inesperado: {e}\")\nelse:\n    print(\"No se ha producido ningun error.\")\nfinally:\n    print(\"El programa finaliza sin detenerse.\")\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/raulG91.py",
    "content": "#Exceptions\n\n#Capturing specific exception\narray = []\ntry:\n    array[2]\nexcept IndexError:\n    print(\"Element out of index\")  \n\n#Capturing generic exception\ntry:\n    10/0\nexcept Exception as e:\n    print(\"Error: \",e,type(e))\n\n\nclass CustomError(Exception):\n    def __ini__(self,message):\n        super.__init__(message)\n\n\ndef function_execption(value:int):\n\n    if value == 0:\n        raise ZeroDivisionError\n    elif value == 1:\n        raise ValueError(\"Incorrect value\")\n    elif value == 3:\n        raise CustomError(\"Custom exception\")\n    \n\ntry:\n    #function_execption(0)\n    #function_execption(1)\n    function_execption(3)\n\nexcept ZeroDivisionError:\n    print(\"Not posible to divide by 0\")\nexcept ValueError:\n    print(\"Incorrect value\")\nexcept CustomError as e:\n    print(e)        \nelse:\n    print(\"No execption\")\nfinally:\n    print(\"Finishing execution\")        \n\n  "
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/rayn1er.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * Explora el concepto de manejo de excepciones según tu lenguaje.\n#  * Fuerza un error en tu código, captura el error, imprime dicho error\n#  * y evita que el programa se detenga de manera inesperada.\n#  * Prueba a dividir \"10/0\" o acceder a un índice no existente\n#  * de un listado para intentar provocar un error.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea una función que sea capaz de procesar parámetros, pero que también\n#  * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n#  * corresponderse con un tipo de excepción creada por nosotros de manera\n#  * personalizada, y debe ser lanzada de manera manual) en caso de error.\n#  * - Captura todas las excepciones desde el lugar donde llamas a la función.\n#  * - Imprime el tipo de error.\n#  * - Imprime si no se ha producido ningún error.\n#  * - Imprime que la ejecución ha finalizado.\n#  */\n\n#las excepciones son herramientas que nos permiten controlar como reacciona el software cuando se produce un error sin que este se detenga, en python contamos con try y except para manejar estos errores\n\nprint (4/2) # si ejecutamos esto el programa se ejecuta sin problemas puesto que podemos dividir\n# print(4/0) sin embargo si ejecutamos esto el programa nos arroja un error, puesto que no podemos dividir entre 0, esto es un error conocido como zerodivisionerror\n# print(2 + \"2\") si ejecutamos esto tambien nos fallara el programa, puesto que no podemos sumar un int con un string\n\n#podemos manejar el error sin problemas utilizando un condicional para verificar si alguno de los numeros es 0 y en base a eso decidir si se realiza la operacion o no\n\ndef division(a, b):\n    if a ==0 or b == 0:\n        return \"Uno de los números es 0, no se puede dividir.\"\n    else:\n        return f'La división es igual a {a / b}'\n\nprint(division(20,0)) \n\n#para hacer lo mismo con try: simplemente escribimos en el nuestro codigo y en el except el codigo que se ejecuta en caso de un error\n\ndef division_try(a,b):\n    try:\n        r = a / b\n        print(r)\n    except:\n        print(f'No se puede divir si uno de los numeros es 0')\n    finally:\n        print(f'Se Ha ejecutado correctamente, has recibido el resultado de una division o un error?')\n\ndivision_try(20,0)\n\ndef list_try(value : list,index = int):\n    try:\n        return value[index]\n    except:\n        print(\"El indice deseado no se encuentra en la lista\")\n\n\nlist_try(['hola','como','estas'],3)\n\n\n\n# extra\n\nclass DictChecker(Exception):\n    pass\n\nmy_dict = {'a' : 1, 'b' : 2}\n\n# if len(my_dict) >= 1:\n#     raise DictChecker(\"Diccionario con mas de dos valores\") # comentado para no romper la ejecucion del sistema\n\n\ndef parameters(a,b):\n    \n\n    try:\n        print(f'{a} + {b} = {a+b}')\n        print(f'{a} - {b} = {a-b}')\n        print(f'{a} * {b} = {a*b}')\n        print(f'{a} / {b} = {a/b}')\n        print(f'{list(a)} + {b} = {a+b}')\n        \n\n    except ZeroDivisionError:\n        \n        print(f\"Uno o ambos valores son 0\")\n    \n    except TypeError:\n        print(f'Uno o ambos valores son un str')\n    \n    \n    else:\n        print(f'El programa se ha ejecutado sin errores')\n    \n\n    finally:\n        \n        print(\"La ejecucion del codigo ha terminado\")\n        \nparameters(20,20)"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/raynerpv2022.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * Explora el concepto de manejo de excepciones según tu lenguaje.\n#  * Fuerza un error en tu código, captura el error, imprime dicho error\n#  * y evita que el programa se detenga de manera inesperada.\n#  * Prueba a dividir \"10/0\" o acceder a un índice no existente\n#  * de un listado para intentar provocar un error.\n#  *\n\n\ndef Div_by_0(a,b):\n    try :\n        result = a/b\n        \n    except ZeroDivisionError as err:\n        print(\"Error Div por 0 no permitida: \", err)\n    else:\n        print(f\" {a} / {b} = {result}\")\n    \n    finally:\n        print(\"terminada la divicion\")\n\ndef Array_out_of_range(lista, index ):\n    try:\n        a= lista[index]\n    except IndexError as err:\n        print(\"Error  : \", err)\n    else:\n        print(f\"{a} is in {index} position\")\n    finally:\n        print(\"Se acabo la jugada\")\n\n\na = 2\nb = 10\nDiv_by_0(a,b)\nlista = [1,2,3,4,5]\nindex = 11\nArray_out_of_range(lista, index)\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea una función que sea capaz de procesar parámetros, pero que también\n#  * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n#  * corresponderse con un tipo de excepción creada por nosotros de manera\n#  * personalizada, y debe ser lanzada de manera manual) en caso de error.\n#  * - Captura todas las excepciones desde el lugar donde llamas a la función.\n#  * - Imprime el tipo de error.\n#  * - Imprime si no se ha producido ningún error.\n#  * - Imprime que la ejecución ha finalizado. \n#  */\n\nclass customError( Exception):\n    pass\n\ndef custom_error():\n    while True:\n        print(\"Que error quieres ver :\")\n        print()\n        print(\"1 - Division por Zero\")\n        print(\"2 - Index fuera de rango\")\n        print(\"3 - Personalizado \")\n        print(\"4 - Salir\")\n        print()\n        op = input()\n        match op:\n            case \"1\":\n                 raise  ZeroDivisionError()\n            case \"2\":\n                 raise   IndexError()\n            case \"3\":\n                print(\"que error quieres mostrar\")\n                a = input()\n                raise   customError(a)\n            case \"4\":\n                break\n            case _:\n                print(\"OPcion invalida...\")\n\n\n\n\n     \n\ntry:\n\n    custom_error()\n    \nexcept ZeroDivisionError as e:\n    print(f\"**** Error 1 ***** : Division por zero\")\nexcept IndexError as e:\n    print(f\"**** Error 2 ***** : error de index\")\nexcept customError as e:\n    print(f\"**** Error 3 ***** : {e}\")\nexcept Exception as e:\n    print(f\"**** Error Inesperado ***** : {e}\")\nelse:\n    print(\"No Error \")\nfinally:\n    print(\"Done...\")\n\n\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/restevean.py",
    "content": "# Exercise\ntry:\n    result = 10 / 0\nexcept ZeroDivisionError as error:\n    print(f\"An error occurred: {error}\")\n\n\ntry:\n    my_list = [1, 2, 3]\n    print(my_list[10])\nexcept IndexError as error:\n    print(f\"An error occurred: {error}\")\n\n\n# Extra\nclass CustomException(Exception):\n    pass\n\n\ndef process(param):\n    if param < 0:\n        raise ValueError(\"Negative value\")\n    elif param > 100:\n        raise OverflowError(\"Value too large\")\n    elif param == 42:\n        raise CustomException(\"Don't like 42\")\n\n\ndef main():\n    try:\n        param = int(input(\"Enter a number: \"))\n        process(param)\n        print(\"No error occurred.\")\n    except ValueError as error_message:\n        print(f\"Caught an error: {error_message}\")\n    except OverflowError as error_message:\n        print(f\"Caught an error: {error_message}\")\n    except CustomException as error_message:\n        print(f\"Caught an error: {error_message}\")\n    finally:\n        print(\"Execution has finished.\")\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/rigo93acosta.py",
    "content": "'''\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado. \n */\n'''\n\n'''\nEjercicio\n'''\ntry:\n    print(10/1)\n    print([1, 2, 3][4])\nexcept Exception as e:  ## Error padre\n    print(f\"Error: {e} -- Tipo de Error: {type(e).__name__}\")\n\nprint(\"Continuando con el programa...\")\n\n'''\nExtra\n'''\nclass StrTypeError(Exception):\n    pass\n\ndef procesar_parametros(parametro: list):\n    \n    if len(parametro) < 3:\n        raise IndexError()\n    elif parametro[1] == 0:\n        raise ZeroDivisionError()\n    elif type(parametro[2]) == str:\n        raise StrTypeError(\"El tercer parametro no puede ser un string.\")\n\n    print(parametro[2])\n    print(parametro[0]/parametro[1])\n    print(parametro[2]+ 5)\ntry:\n    procesar_parametros([1, 2, 3, 4])\nexcept IndexError as e:\n    print(\"El parametro debe tener al menos 3 elementos.\")\nexcept ZeroDivisionError as e:\n    print(\"No se puede dividir por 0.\")\nexcept StrTypeError as e:\n    print(e)\nexcept Exception as e:\n    print(f\"Error inesperado: {type(e).__name__} - {e}\")\nelse: # Cuando no se cumple ninguna excepción\n    print(\"No se ha producido ningún error.\")\nfinally:  # Pase lo que pase se va a ejecutar\n    print(\"La ejecución ha finalizado sin errores.\")"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/rikmij.py",
    "content": "try:\n    print(10/0)\n\nexcept:\n    print(\"Es un ZeroDivisionError, estás intentando dividir entre 0\")\n\ntry:\n    lista = [1, 2, 3, 4]\n    print(lista[5])\nexcept IndexError:\n    print(\"Es un IndexError, intenta acceder a un elemento que no alcanza la lista\")\n\n\nprint('\\n', '~'*7, \"EJERCICIO EXTRA\", '~'*7)\n\nclass NoInputError(Exception):\n    def __init__(self, error = \"No has ingresado nada, debes poner algo\"):\n        self.error = error\n\ndef calculate(n1, n2):\n    #que pueda elegir entre 1 y 4. Si da más, lanza IndexError. Usar match para las opciones\n    try:\n        choose = int(input(f'''Tienes los números {n1} y {n2}\n    Qué quieres hacer??\n    1.- Suma\n    2.- Resta\n    3.- Multiplicar\n    4.- Dividir\\n'''))\n    \n        match choose:\n            case \"\": raise NoInputError\n            case 1: print(\"El resultado es \", n1 + n2)\n            case 2: print(\"El resultado es \", n1 - n2)\n            case 3: print(\"El resultado es \", n1 * n2)\n            case 4: print(\"El resultado es \", n1 / n2)\n            case _: raise IndexError\n    \n    except NoInputError:\n        print(\"Debes ingresar algo\")\n    except ValueError:\n        print(\"Ingresa un número válido\")\n    except ZeroDivisionError:\n        print(\"No se puede dividir entre 0\")\n    except IndexError:\n        print(\"Número no válido. Que sea entre 1 y 4\")\n    \n    else:\n        print(\"Felicidades, no ha habido ningún error\")\n    \n    finally:\n        return \"Hasta aquí llega el programa\"\n\nprint(calculate(3, 7))\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/santiagobailleres.py",
    "content": "'''EJERCICIO:\nExplora el concepto de manejo de excepciones según tu lenguaje.\nFuerza un error en tu código, captura el error, imprime dicho error\ny evita que el programa se detenga de manera inesperada.\nPrueba a dividir \"10/0\" o acceder a un índice no existente\nde un listado para intentar provocar un error.\nDIFICULTAD EXTRA (opcional):\nCrea una función que sea capaz de procesar parámetros, pero que también\npueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\ncorresponderse con un tipo de excepción creada por nosotros de manera\npersonalizada, y debe ser lanzada de manera manual) en caso de error.\n- Captura todas las excepciones desde el lugar donde llamas a la función.\n- Imprime el tipo de error.\n- Imprime si no se ha producido ningún error.\n- Imprime que la ejecución ha finalizado. '''\n\n# Manejo de excepciones en Python\ntry: # try sirve para intentar ejecutar un bloque de código\n    # División por cero\n    print(10/0)\nexcept Exception as e:\n    print(f'Error: {e} ({type(e).__name__})')\n\n# error para acceder a un índice no existente\ntry:\n    lista = [1, 2, 3]\n    print(lista[3])\nexcept Exception as e:\n    print(f'Error: {e} ({type(e).__name__})')\n\n# EXTRA\n# Función que procesa parámetros y lanza excepciones\nclass StrTypeError(Exception): # Excepción personalizada\n    pass\n\ndef process_params(params: list):\n    if len(params) < 3:\n        raise IndexError('La lista debe tener al menos 3 elementos') #raise lanza una excepción manualmente, lo que se pone entre paréntesis es el mensaje de error\n    elif params[1] == 0:\n        raise ZeroDivisionError('No se puede dividir por cero')\n    elif type(params[2]) == str:\n        raise StrTypeError('El tercer elemento no puede ser un string')\n\n    print(params[2])\n    print(params[0]/params[1])\n    print(params[2]+5)\n\ntry:\n    process_params([1, 1, 1])\nexcept IndexError as e:\n    print(f'Error: {e} ({type(e).__name__})')\nexcept ZeroDivisionError as e:\n    print(f'Error: {e} ({type(e).__name__})')\nexcept StrTypeError as e:\n    print(f'Error: {e} ({type(e).__name__})')\nexcept Exception as e:\n    print(f'Error: {e} ({type(e).__name__})')\nelse:\n    print('No se ha producido ningún error')\nfinally:\n    print('La ejecución ha finalizado')"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/santyjl.py",
    "content": "##10 - EXCEPCIONES\n\"\"\"\n/*\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado.\n */\"\"\"\n\n#try para capturar una posible parte de error\ntry :\n    valor = int(input(\"que numero vas a dividir : \"))\n    print(\"el resultado es : \" , valor/0)\n\nexcept ZeroDivisionError as Error : #captura de la excepcion exacta\n    print(\"el error es :\" , Error)\n\n#clase propia de excepcion\nclass MiExcepcion(Exception):\n    def __init__(self, parametro_generico = \"mensaje de error generico\") -> None: #parametro\n        super().__init__(parametro_generico)\n\n        self.parametro_generico = parametro_generico\n\n        #forzando 3 tipos de error\n        if type(parametro_generico) is str :\n            try :\n                parametro_generico + 45.6\n                print(\"no saltare nunca xd\")\n            except Exception as error :         #captura cualquier excepcion\n                print(\"el error es : \", error)\n\n        elif type(parametro_generico) is int:\n\n            try :\n                parametro_generico - \"1234\"\n                print(\"tampoco saltere\")\n\n            except Exception as error :\n                print(\"el error es : \" , error)\n\n        elif type(parametro_generico) is list :\n            try :\n                elementos = len(parametro_generico)\n                print(parametro_generico[elementos + 2])\n\n            except Exception as error :\n                print(\"el error es : \" , error)\n\n        else :\n            print(\"tipo de dato no definido para forzar excepcion\")\n\n\nerror_int = MiExcepcion(123)\nerror_str = MiExcepcion(\"hola mundo\")\nerror_list = MiExcepcion([1 , 2, \"hola mundo\"])\n\n\n\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/sorubadguy.py",
    "content": "\"\"\"\n*Excepciones\n\"\"\"\n\ntry: #?Intenta realizar la/s tarea/s contenidas\n    a = 1#int(input(\"Ingrese un numero: \"))\nexcept Exception as ex:#?Si no las puede llevar a cavo, se ejecuta lo que contenga el except\n    print(\"No es un numero\")\n    print(f\"{ex} \\n{type(ex).__name__}\")\nelse:#?En caso de que el try se exitoso se ejecuta lo que contenga\n    print(a)\nfinally:#?Se ejecuta al final del try, haya sido o no exitoso\n    print(\"fin Try\")\n\n#?Raise\n\na = 2\n\nif a < 0:\n    raise Exception(\"No se admiten numeros menores a 0\")#?Raise invoca la una excepcion y finaliza el programa. se muestran distintos mensajes segun el error invocado\n\n\"\"\"\n!Extra\n\"\"\"\n\ndef parametros(params: list):\n\n    if(len(params) > 3 or len(params) < 1):\n        raise IndexError()\n    elif(type(params[2]) == str):\n        raise TypeError()\n    else:\n        try:\n            print(f\"{params[0]} / {params[1]} = {params[0]/params[1]}\")\n        except Exception as ex:\n            print(f\"Ocurrio un error: {type(ex).__name__}\")\n\n    \n\nparametros([2,0,3])\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/sperezsa.py",
    "content": "#10 - EXCEPCIONES\n\n# Excepción de división entre 0\ndef division(a: int, b: int):\n    try:\n        return a / b\n    except ZeroDivisionError:\n        print(\"No es posible realizar división entre cero\")\n    except:\n        print(\"Se ha producido un error general\")\n    finally:\n        print(\"Ha finalizado el manejo de excepciones en la función división\")\n\n# Excepción de acceso a valor fuera de rango\ndef acceso(c: list):\n    try:\n        return c[0]\n    except IndexError: \n        print(\"No es posible acceder a un valor fuera del rango de la lista\")\n    except:\n        print(\"Se ha producido un error general\")\n    finally:\n        print(\"Ha finalizado el manejo de excepciones en la función acceso\")\n\n               \na = 10\nb = 0\nprint(division(a, b))\nc = []\nprint(acceso(c))\n\n\n\"\"\"\nExtra\n\"\"\"\n\nclass customExceptionError(Exception):\n    def __init__(self):\n        self.msg = 'Personalizada! Los valores enteros no pueden ser pares!'\n\n    def __str__(self):\n        return self.msg\n\n\ndef revisar_pares(d, e): \n    if (d % 2 == 0) or (e % 2 == 0): \n        raise customExceptionError\n    \n# Excepción de error de tipo de operador no soportado\ndef suma(d, e, f):\n    try:\n        revisar_pares(d,e)\n        \n        out = d + e + f[0]\n    except customExceptionError as cee:\n        print(type(cee), cee)\n    except IndexError: \n        print(\"No es posible acceder a un valor fuera del rango de la lista\")\n    except Exception as err:\n        print(type(err), err)\n        print(\"Tipos de operadores no soportados para la suma: 'int' y 'str'\")    \n    else:\n        print(\"Salida sin errores. Resultado\", out)\n    finally:\n        print(\"Ha finalizado el manejo de excepciones en la función suma\") \n\nprint(\"\\n salida 1\")\nprint(suma(3, 3, [1]))\n\nprint(\"\\n salida 2\")\nprint(suma(3, '3', [1]))\n\nprint(\"\\n salida 3\")\nprint(suma(3, 3, []))\n\nprint(\"\\n salida 4\")\nprint(suma(2, 3, [1]))\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/switchdays.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n\"\"\"\n\ndef excepcion(input_str):\n    lista = [10, 20, 30, 40, 50]\n    num = len(lista)\n    input = int(input_str)\n\n    try:\n        division = num/input\n        print(\"División de \", len(lista), \"entre \", input, \"es: \", division)\n        \n    except:\n        print(\"No es posible dividir entre\", input)\n    \n    else:\n        print(\"No ha habido ningún problema.\")\n\n    try:\n        print(\"El elemento de la lista en la posición\", input, \"es:\", lista[input])\n    \n    except:\n        print(\"No hay ningún elemento de la lista en la posición\", input)\n\n\ninput_str = input(\"Introduce un número cualquiera: \")\nexcepcion(input_str)\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado. \n\"\"\"\n\nclass MiExcepcionPersonalizada(Exception):\n    def __init__(self, mensaje=\"Error personalizado\"):\n        self.mensaje = mensaje\n        super().__init__(self.mensaje)\n\ndef procesar_parametros(param1, param2):\n    try:\n        if not isinstance(param1, int) or not isinstance(param2, int):\n            raise ValueError(\"Ambos parámetros deben ser enteros.\")\n        \n        if param2 == 0:\n            raise ZeroDivisionError(\"No se puede dividir entre cero.\")\n\n        # Simulación de un error personalizado\n        if param1 == 42:\n            raise MiExcepcionPersonalizada(\"¡Error personalizado!\")\n\n        resultado = param1 / param2\n        print(\"Resultado:\", resultado)\n\n    except ValueError as ve:\n        print(f\"Error de valor: {ve}\")\n    except ZeroDivisionError as zde:\n        print(f\"Error de división entre cero: {zde}\")\n    except MiExcepcionPersonalizada as mep:\n        print(f\"Error personalizado: {mep}\")\n    except Exception as e:\n        print(f\"Otro tipo de error: {e}\")\n    else:\n        print(\"No se ha producido ningún error.\")\n    finally:\n        print(\"La ejecución ha finalizado.\")\n\n# Ejemplo de uso:\ntry:\n    procesar_parametros(10, 2)\n    procesar_parametros(\"a\", 2)\n    procesar_parametros(42, 5)\nexcept Exception as e:\n    print(f\"Excepción capturada: {e}\")\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/tito-delpino.py",
    "content": "#  * EJERCICIO:\n#  * Explora el concepto de manejo de excepciones según tu lenguaje.\n#  * Fuerza un error en tu código, captura el error, imprime dicho error\n#  * y evita que el programa se detenga de manera inesperada.\n#  * Prueba a dividir \"10/0\" o acceder a un índice no existente\n#  * de un listado para intentar provocar un error.\n\ntry:\n  print(10 / 0)\nexcept Exception as error:\n  print(f\"Se produjo un error: {error}\")\n\nlistado = [\"cabeza\", \"perro\",\"caballo\"]\ntry:\n  print(listado[4])\nexcept Exception as error2:\n  print(f\"Se produjo un error: {error2} ({type(error2).__name__})\")\n\nprint('/' * 50)\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea una función que sea capaz de procesar parámetros, pero que también\n#  * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n#  * corresponderse con un tipo de excepción creada por nosotros de manera\n#  * personalizada, y debe ser lanzada de manera manual) en caso de error.\n#  * - Captura todas las excepciones desde el lugar donde llamas a la función.\n#  * - Imprime el tipo de error.\n#  * - Imprime si no se ha producido ningún error.\n#  * - Imprime que la ejecución ha finalizado.\n\nclass Excepcion_personalizada(Exception):\n  pass\n\ndef procesar_parametros(parametros: list):\n  \n  if len(parametros) < 3:\n    raise IndexError()\n  elif parametros[2] == 0:\n    raise ZeroDivisionError()\n  elif type(parametros[3]) == str:\n    raise Excepcion_personalizada(\"El tercer numero no puede ser un string\")\n\n  print(parametros[4])\n  print(parametros[0]/parametros[1])\n  print(parametros[3] + 6)\n\ntry:\n  procesar_parametros([0,1,2,3,4])\nexcept IndexError as error3:\n  print(f\"Se produjo el error {type(error3).__name__}\")\nexcept ZeroDivisionError as error4:\n  print(f\"El tercer numero de la lista no puede ser un 0\")\nexcept Excepcion_personalizada as error4:\n  print(f\"{error4}\")\nexcept Exception as error5:\n  print(f\"Se produjo un error inesperado: {error5}\")\nelse:\n  print(\"No se produjo ningun error\")\nfinally:\n  print(\"Programa finalizado sin petar\")"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/victorfer69.py",
    "content": "#Excepciones y errores\n\ntry:\n    print(10/1)\n\n    my_list = [1,2,3,4]\n    print(my_list[4])\n\nexcept Exception as e:\n    print(f\"ERROR: {e}\")\n\nprint(\"Hola a todos\")\n\n\n#EJERCICIO EXTRA\n\nclass StrTypeError(Exception):\n    pass\n\ndef extra(param:list):\n\n    if len(param) < 3:\n        raise IndexError()\n    elif param[1] == 0:\n        raise ZeroDivisionError()\n    elif type(param[2]) != str:\n        raise StrTypeError(\"El tercer elemento debe de ser una cadena de texto\")\n\n    print(param[2])\n    print(param[0]/param[1])\n\n\ntry:\n    extra([1,2,\"Hola\"])\nexcept IndexError as e:\n    print(\"ERROR: el numero de elementos de la lista debe ser mayor de 2\")\nexcept ZeroDivisionError as e:\n    print(\"ERROR: el segundo elemento de la lista no puede ser cero\")\nexcept StrTypeError as e:\n    print(f\"ERROR: {e}\")\nexcept Exception as e:\n    print(f\"ERROR inesperado: {e}\")\nfinally:\n    print(\"FIN\")"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/warclimb.py",
    "content": "# #10 EXCEPCIONES\n#### Dificultad: Media | Publicación: 04/03/24 | Corrección: 11/03/24\n\n## Ejercicio\n\n\n''' * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n'''\n\n# Fuerzo error de división por cero\ndef division(num1, num2):\n    try:\n        division = num1/num2\n        print(f'Resultado: {division}')\n\n    except ZeroDivisionError as e:\n        print(\"Error: \", e)\n\n    finally:\n        print(\"Ejecución finalizada\")\n\n# Fuerzo error de índice no existente\ndef no_index(posicion):\n    try:\n        lista = [1,2,3]\n        print(lista[posicion])\n\n    except IndexError as e:\n        print(f\"Error: {e}. No existe el índice en la posicion {posicion}\")\n\n    finally:\n        print(\"Ejecución finalizada\")\n\n''' DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado.''' \n\n# Función que lanza excepciones personalizadas\ndef test_excepciones(param):\n    try:\n        # comprobamos el numero que se pasa por parametro\n        if param == 1:\n            # incluimos un mensaje en el error\n            raise ValueError(\"ValueError: La función espera un valor determinado pero recibe otro.\")\n        elif param == 2:\n            raise TypeError(\"TypeError: El tipo de dato no es el esperado.\")\n        elif param == 3:\n            raise Exception(\"Exception: Error general.\")\n        elif param == 4:\n            raise IndexError(\"IndexError: El índice no existe.\")\n        else:\n            print(\"Todo bien!\")\n\n    # Capturamos los errores\n    except ValueError as e:\n        print(f\"Error! {e}\")\n\n    except TypeError as e:\n        print(f\"Error! {e}\")\n\n    except Exception as e:\n        print(f\"Error! {e}\")\n    \n    except IndexError as e:\n        print(f\"Error! {e}\")\n\n    finally:\n        print(\"Ejecución finalizada\")\n\n# vamos a probar!\nif __name__ == \"__main__\":\n    # Ejercicio manejo de excepciones\n    division(10, 0)\n    no_index(3)\n    \n    # EXTRA\n    test_excepciones(2)"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/worlion.py",
    "content": "\"\"\"\n* EJERCICIO:\n* Explora el concepto de manejo de excepciones según tu lenguaje.\n* Fuerza un error en tu código, captura el error, imprime dicho error\n* y evita que el programa se detenga de manera inesperada.\n* Prueba a dividir \"10/0\" o acceder a un índice no existente\n* de un listado para intentar provocar un error.\n\"\"\"\n\ndef dividir(x: int, y: int):\n    print(f\"vamos a intentar dividir '{x}' entre '{y}'\")\n    try:\n        return x // y;\n    except ZeroDivisionError:\n        print(\"❌ No puedes dividir entre 0, melón! 🍈\")\n        return None\n\na = 10\nb = 0\n\ndividir(a, b)\n\nlista = ['a', 'b','c']\nprint(lista.__len__())\nfor i in range(0, lista.__len__()+1):\n    try:\n        print(f\"pos {i}: {lista[i]}\")\n    except IndexError as e:\n        print(f\"❌ {type(e).__name__}:Te has salidon del array!\")\n\n\n\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n\"\"\"\n\nprint(\"\\n ---- 🌩 DIFICULTAD EXTRA 🌩 ----\\n\")\n\nclass my_exception(Exception):\n    pass\n\ndef process_parameters(parametros: list):\n\n    if not isinstance(parametros[0], int) or not isinstance(parametros[1], int):\n        raise my_exception(\"Los parámetros tienen que ser enteros\")\n    \n    print(f\"division: {parametros[0]} / {parametros[1]} = {parametros[0] / parametros[1]}\")\n    \ndef try_it(lista_parametros):\n    try:\n        print(f\"\\nvamos a intentar procesar: {lista_parametros}\")\n        process_parameters(lista_parametros)\n    \n    except my_exception as e:\n        print(f\"Esta es mi excepcion: {e} ❌\")\n    except ZeroDivisionError as e:\n        print(f\"{e}: Division entre 0 ❌\")\n    except IndexError as e:\n        print(f\"{e}: Nos hemos salido del array ❌\")\n    else:\n        print(\"sin errores... sorprendente! ✅\")\n    finally:\n        print(\"por aqui pasamos siempre... hemos hecho lo que hemos podido\")    \n    \n        \ntry_it([1,2]) # OK\n\ntry_it(['a','b']) # Error: tipo de datos (personalizada)\ntry_it([20,0]) # Error: div by 0\ntry_it([1]) # Error: index out of range"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/yablik.py",
    "content": "try:\n    # Intenta ejecutar código propenso a errores\n    resultado = 10 / 0  # División por cero\n    lista = [1, 2, 3]\n    elemento = lista[5]  # Acceso a un índice no existente\nexcept ZeroDivisionError as error:\n    # Captura y maneja el error de división por cero\n    print(\"Error de división por cero:\", error)\nexcept IndexError as error:\n    # Captura y maneja el error de índice fuera de rango\n    print(\"Error de índice fuera de rango:\", error)\nexcept Exception as error:\n    # Captura y maneja otros errores no específicos\n    print(\"Error inesperado:\", error)\nelse:\n    # Se ejecuta si no se produce ninguna excepción\n    print(\"Operación exitosa.\")\nfinally:\n    # Se ejecuta siempre, independientemente de si se produce una excepción o no\n    print(\"Fin del programa.\")\n\n#Dificultad extra\n\n# Definición de excepción personalizada\nclass MiExcepcionPersonalizada(Exception):\n    def __init__(self, mensaje):\n        super().__init__(mensaje)\n\n# Función que procesa parámetros y lanza excepciones\ndef procesar_parametros(parametro):\n    try:\n        if parametro == 1:\n            raise ValueError(\"¡Este es un valor incorrecto!\")\n        elif parametro == 2:\n            raise IndexError(\"¡Índice fuera de rango!\")\n        elif parametro == 3:\n            raise MiExcepcionPersonalizada(\"¡Esto es una excepción personalizada!\")\n        else:\n            print(\"Parámetro válido:\", parametro)\n    except ValueError as ve:\n        print(\"Error:\", ve)\n    except IndexError as ie:\n        print(\"Error:\", ie)\n    except MiExcepcionPersonalizada as me:\n        print(\"Error:\", me)\n    else:\n        print(\"No se ha producido ningún error.\")\n    finally:\n        print(\"La ejecución ha finalizado.\")\n\n# Llamada a la función con manejo de excepciones\ntry:\n    procesar_parametros(0)\n    procesar_parametros(1)\n    procesar_parametros(2)\n    procesar_parametros(3)\nexcept Exception as e:\n    print(\"Tipo de error:\", type(e).__name__)\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/ycanas.py",
    "content": "# ------ Ejercicio\n\na: int = 10\nb: int = 0\n\ntry:\n    c = a / b\nexcept Exception as e:\n    print(f\"* Error inesperado: {e}, {type(e).__name__}\")\nfinally:\n    c = 0\n\nprint(\"a:\", a, \"b:\", b, \"c:\", c)\n\n\n# ------ Extra\n\nclass MyCustomException(Exception):\n    pass\n\n\ndef exceptions(*params):\n    if not all(isinstance(param, int) for param in params):\n        raise TypeError()\n    \n    if params[1] == 0:\n        raise ZeroDivisionError()\n    \n    if params[2] % 2 == 0:\n        raise MyCustomException(\"El tercer elemento no puede ser par\")\n\n    print(params[0] / params[1])\n    print(int(params[2] / 2) + 1)\n\n\ntry:\n    exceptions(1, 2, 13)\nexcept TypeError as e:\n    print(\"* Error, todos los elementos deben ser números enteros\")\nexcept ZeroDivisionError as e:\n    print(\"* Error, el segundo elemento no puede ser cero\")\nexcept MyCustomException as e:\n    print(\"* Error, el tercer elemento no puede ser par\")\nexcept Exception as e:\n    print(\"* Error inesperado:\", e)\nelse:\n    print(\"* No se presento ninguna excepción\")\nfinally:\n    print(\"* Programa finalizado\")\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/yenneralayon142.py",
    "content": "\"\"\"\nExcepciones\n\"\"\"\ntry:\n    print(10/0)\n    print([10,21,31][5])\nexcept Exception as e:\n    print(f\"Se ha detectado un error: {e}\")\n\n\"\"\"\nExtra\n\"\"\"\nclass StrTypeError(Exception):\n    pass\n\ndef errors(parameters:list):\n    \n    if len(parameters) < 3:\n        raise IndexError\n    elif parameters == 0:\n        raise ZeroDivisionError\n    elif type(parameters[2]) == str:\n        raise StrTypeError(\"El tercer elemento no puede ser una cadena de texto\")\n\n    print(parameters[2])\n    print(parameters[0] / parameters[1])\n    print(parameters[2] + 5)\ntry:\n    errors([1,2,3,4,5,6])\nexcept IndexError as e:\n    print(\"El número de elementos de la lista debe ser mayor a 1\")\nexcept ZeroDivisionError as e:\n    print(\"El segundo elemento de la lista no puede ser un cero\")\nexcept StrTypeError as e:\n    print(f\"{e}\")\nexcept Exception as e:\n    print(f\"Se ha producido un error inesperado: {e}\")\nelse:\n    print(\"No se ha producido ningún error\")\nfinally:\n    print(\"El programa finaliza sin detenerse\")"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/python/zetared92.py",
    "content": "# Reto 10 EXCEPCIONES\n\n\"\"\"\nUna excepción es un evento que ocurre durante la ejecución de un programa \ny que interrumpe el flujo normal del código. \nSucede cuando el programa encuentra una situación que no \npuede manejar, como intentar dividir por cero, \nacceder a un índice fuera de los límites de una lista, \no tratar de abrir un archivo que no existe.\n\"\"\"\n\ntry:\n    print(10/0)\n    print([1, 2, 3, 4][4])\nexcept Exception as e:\n    print(f\"An error has occurred: {e} ({type(e).__name__})\")\n\n\n# Extra\n\nprint(\"🧩 DIFICULTAD EXTRA - FUNCIÓN CON EXCEPCIONES 🧩\")\n\nclass StrTypeError(Exception):\n    pass\n\ndef params(parameters: list):\n\n    if len(parameters) < 4:\n        raise IndexError()\n    elif parameters[1] == 0:\n        raise ZeroDivisionError()\n    elif type(parameters[2]) == str:\n        raise StrTypeError(\n            \"The third parameter cannot be a text string.\")\n    \n    print(parameters[2])\n    print(parameters[0]/parameters[1])\n    print(parameters[2] + 5)\n\n\ntry:    \n    params([1, 2, 3, 4])\nexcept IndexError as e:\n    print(\"The number of items in the list must be greater than three.\")\nexcept ZeroDivisionError as e:\n    print(\"The second element in the list cannot be a zero.\")\nexcept StrTypeError as e:\n    print(f\"{e}\")\nexcept Exception as e:\n    print(f\"Unexpected error: {e}\")\nelse:\n    print(\"No error has occurred.\")\nfinally:\n    print(\"The program ends without stopping.\")"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/ruby/Elmer125.rb",
    "content": "#  * EJERCICIO:\n#  * Explora el concepto de manejo de excepciones según tu lenguaje.\n#  * Fuerza un error en tu código, captura el error, imprime dicho error\n#  * y evita que el programa se detenga de manera inesperada.\n#  * Prueba a dividir \"10/0\" o acceder a un índice no existente\n#  * de un listado para intentar provocar un error.\n# Guide: https://www.honeybadger.io/blog/a-beginner-s-guide-to-exceptions-in-ruby/\n\nbegin\n  #Any exceptions in here...\n  10/0\nrescue\n  #...will be rescued here\n  # do something\nend\n\nbegin\n  10/0\n  #Ruby has a Exception object that can be used to rescue exceptions\nrescue ZeroDivisionError => e\n  puts \"Exception class: #{ e.class.name }\"\n  puts \"Exception message: #{ e.message }\"\n  puts \"Exception backtrace: #{ e.backtrace }\"\nend\n\n#Raising your own exceptions\nbegin\n  # raise an ArgumentError with the message\n  raise ArgumentError.new(\"This is an argument error\")\nrescue ArgumentError => e\n  puts e.message\nend\n\nbegin\n  # raise an RuntimeError with the message\n  # raise RuntimeError, \"This is an error\"\n  raise RuntimeError.new(\"This is a runtime error\")\nrescue RuntimeError => e\n  puts e.message\nend\n\nbegin\n  raise \"Here's the exception\"\n  #This use a StandardError\n  # rescue StandardError => e\nrescue => e\n  puts e\nend\n\nfruit_list = [\"apple\", \"banana\", \"cherry\"]\n\nbegin\n  fruit_list[3]\n  raise RuntimeError.new(\"The fruit is not in the list\")\nrescue RuntimeError => e\n  puts e.message\nend\n\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea una función que sea capaz de procesar parámetros, pero que también\n#  * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n#  * corresponderse con un tipo de excepción creada por nosotros de manera\n#  * personalizada, y debe ser lanzada de manera manual) en caso de error.\n#  * - Captura todas las excepciones desde el lugar donde llamas a la función.\n#  * - Imprime el tipo de error.\n#  * - Imprime si no se ha producido ningún error.\n#  * - Imprime que la ejecución ha finalizado.\n\nclass CustomError < StandardError\n  def initialize(message)\n    super(message)\n  end\nend\n\ndef process_params(param)\n  if param.class != String\n    raise ArgumentError.new(\"The parameter is not a string\")\n  elsif param.length < 5\n    raise RuntimeError.new(\"The string is too short\")\n  elsif param.length > 10\n    raise CustomError.new(\"The string is too long\")\n  end\nend\n\nbegin\n  process_params(\"Hello from Ruby\")\nrescue ArgumentError, RuntimeError, CustomError  => e\n  puts \"Type error: #{e.class.name}\"\n  puts e.message\nelse\n  puts \"No errors\"\nensure\n  puts \"Execution has finished\"\nend\n\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/rust/gabrielmoris.rs",
    "content": "/*\n* EXERCISE:\n* Explore the concept of exception handling according to your language.\n* Force an error in your code, capture the error, print the error\n* and prevent the program from stopping unexpectedly.\n* Try dividing \"10/0\" or accessing a non-existent index\n* of a list to try to cause an error.\n*/\n\nfn main() {\n    recoverable_error();\n    println!(\"Program still works\");\n    let result_error = another_recoverable_err();\n    println!(\"{:?}\", result_error);\n    println!(\"Program still works this second time as well.\");\n    err_handling_clojures();\n    println!(\"Program still works this third time as well.\");\n    println!(\"========= CHALLENGE =========\");\n\n    // It Works Ok(2) The program keeps running\n    let challenge: Result<i32, String> = match parameter_processor(2, 1) {\n        Ok(result) => Ok(result),\n        Err(err) => Err(err),\n    };\n    println!(\"{:?}\", challenge);\n\n    // Returns Err(\"Sorry, x is smaller!\"). because x == 0. The program keeps running\n    let challenge: Result<i32, String> = match parameter_processor(0, 1) {\n        Ok(result) => Ok(result),\n        Err(err) => Err(err),\n    };\n    println!(\"{:?}\", challenge);\n\n    // Returns Err(\"Sorry, x is smaller!\") because  x > y is false. The program keeps running\n    let challenge: Result<i32, String> = match parameter_processor(1, 1) {\n        Ok(result) => Ok(result),\n        Err(err) => Err(err),\n    };\n    println!(\"{:?}\", challenge);\n\n    // Returns This can't be possible because y == 0 is false, panics and stops the program here.\n    let challenge: Result<i32, String> = match parameter_processor(1, 0) {\n        Ok(result) => Ok(result),\n        Err(err) => Err(err),\n    };\n    println!(\"{:?}\", challenge);\n    println!(\"Program stopped wrking before. This Log wont be Printed!\")\n}\n\nfn _example_hard_error() {\n    // This would stop the program at this point.\n    panic!(\"Fire and chaos.\")\n}\n\nfn recoverable_error() {\n    let result = match infinite() {\n        Ok(value) => value,\n        Err(error) => {\n            println!(\"Error: {}\", error);\n            0\n        }\n    };\n    println!(\"{result}\")\n}\n\nfn another_recoverable_err() -> Result<(), String> {\n    let greeting_file = infinite()?;\n    println!(\"{:?}\", greeting_file);\n    Ok(())\n}\n\nfn err_handling_clojures() {\n    let greeting_file = infinite().unwrap_or_else(|error| {\n        if error.to_string() == \"Division by zero\" {\n            println!(\"I break softly:: {}\", error.to_string());\n            return 0;\n        } else {\n            println!(\"It Worked! : {:?}\", infinite());\n            return 0;\n        }\n    });\n\n    println!(\"{greeting_file}\")\n}\n\nfn infinite() -> Result<i32, String> {\n    // I am handling manually the error\n    let denominator = 0;\n    let result = match denominator {\n        0 => Err(\"Division by zero\".to_string()),\n        _ => Ok(10 / denominator),\n    };\n    result\n}\n\n/* EXTRA DIFFICULTY (optional):\n* Create a function that can process parameters, but also\n* can throw 3 different types of exceptions (one of them has to\n* correspond to a custom exception type created by us\n* manually) in case of an error.\n* Capture all exceptions from where you call the function.\n* Print the type of error.\n* Print if no error has occurred.\n* Print that execution has finished.\n*/\n\nfn parameter_processor(x: i32, y: i32) -> Result<i32, String> {\n    if y < 1 {\n        panic!(\"This can't be possible\")\n    }\n\n    let x_must_be_bigger = x_is_smaller(x, y)?;\n\n    fn x_is_smaller(x: i32, y: i32) -> Result<bool, String> {\n        let result = match x > y {\n            false => Err(\"Sorry, x is smaller!\".to_string()),\n            _ => Ok(true),\n        };\n        result\n    }\n\n    let _it_works = match x_must_be_bigger {\n        false => Err(\"Please, x must be a bigger number\".to_string()),\n        true => Ok(true),\n    };\n\n    let division = match x {\n        0 => Err(\"Please, Divide for a bigger number\".to_string()),\n        _ => Ok(x / y),\n    };\n\n    println!(\"this Worked Fine {:?}\", division);\n    return division;\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/rust/kenysdev.rs",
    "content": "/*\n╔═══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado                ║\n║ GitHub: https://github.com/Kenysdev   ║\n║ 2024 -  Rust                          ║\n╚═══════════════════════════════════════╝\n-----------------------------------------\n* EXCEPCIONES \n-----------------------------------------\n- Rust no tiene excepciones. En cambio, tiene el tipo Result<T, E> para errores recuperables y \n  el macro panic! que detiene la ejecución cuando el programa encuentra un error irrecuperable.\n\n- Mas info: https://www.rustlang-es.org/rust-book-es/ch09-00-error-handling.html\n\n* Errores recuperables (Result<T, E>) \n- 'T' representa el tipo del valor que será devuelto en un caso de éxito dentro de la variante Ok\n- 'E' representa el tipo del error que será devuelto en un caso de fallo dentro de la variante Err.\n*/\n\nfn main() {\n    /* ________________________________________________________________________\n    * EJERCICIO 1\n    * Fuerza un error en tu código, captura el error, imprime dicho error\n      y evita que el programa se detenga de manera inesperada.\n    - Prueba a dividir \"10/0\".\n    - Acceder a un índice no existente.\n    */\n    println!(\"EJERCICIO 1\");\n\n    divide(10, 0);\n\n    // _________________\n    let vector = vec![1, 2, 3];\n    match index_access(&vector, 7) {\n        Ok(valor) => println!(\"El valor es: {}\", valor),\n        Err(err) => println!(\"Error: {}\", err),\n    }\n\n    /* ________________________________________________________________________\n    * EJERCICIO 2\n    * Crea una función que sea capaz de procesar parámetros, pero que también\n    * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n    * corresponderse con un tipo de excepción creada por nosotros de manera\n    * personalizada, y debe ser lanzada de manera manual) en caso de error.\n    * - Captura todas las excepciones desde el lugar donde llamas a la función.\n    * - Imprime el tipo de error.\n    * - Imprime si no se ha producido ningún error.\n    * - Imprime que la ejecución ha finalizado. \n    */\n    println!(\"\\nEJERCICIO 2\");\n\n    divide(10, 0);\n    divide(10, 5);\n    divide(10, -2);\n    divide(10, 2);\n\n}\nenum DivisionError {\n    DivisionByZero,\n    OddNumber,\n    NegativeNumber,\n}\n\nfn division(a: i32, b: i32) -> Result<f32, DivisionError> {\n    match b {\n        0 => Err(DivisionError::DivisionByZero),\n        n if n % 2 != 0 => Err(DivisionError::OddNumber),\n        n if n < 0 => Err(DivisionError::NegativeNumber),\n        _ => Ok(a as f32 / b as f32),\n    }\n}\n\nfn index_access(vector: &Vec<i8>, index: usize) -> Result<i8, &'static str> {\n    if index < vector.len() {\n        Ok(vector[index])\n    } else {\n        Err(\"Índice fuera de rango\")\n    }\n}\n\nfn divide(a: i32, b: i32) {\n    match division(a, b) {\n        Ok(resultado) => println!(\"\\n- El resultado es: {} \\n- No ocurrió ningún error.\", resultado),\n        Err(error) => match error {\n            DivisionError::DivisionByZero => println!(\"\\nError: No es posible dividir entre 0.\"),\n            DivisionError::OddNumber => println!(\"\\nError: No dividir entre impares.\"),\n            DivisionError::NegativeNumber => println!(\"\\nError: No se permiten divisores negativos.\"),\n        }\n    }\n    println!(\"- Operación terminada.\");\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/rust/w00k.rs",
    "content": "use std::result;\n\n/* EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n */\n\nfn main() {\n    println!(\"Inicio\");\n\n// OK\ndiv_result(10, 2);\n\n// Error\ndiv_result(10, 0);\n}\n\nfn div_result(first: u32, second: u32) {\n    let result = div(first, second);\n    if result.is_ok() {\n    println!(\"{}\", result.ok().unwrap());\n    } else {\n        println!(\"{}\", result.err().unwrap());\n    }\n}\n\nfn div(first: u32, second: u32) -> Result<u32, &'static str> {\n    if second == 0 {\n        Err(\"El divisor es igual a cero\")\n    } else {\n        Ok(first / second)\n    }\n}"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/sql/Nicojsuarez2.sql",
    "content": "# #10 EXCEPCIONES\n> #### Dificultad: Media | Publicación: 04/03/24 | Corrección: 11/03/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado. \n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/swift/allbertoMD.swift",
    "content": "import Foundation\n\n\n// FUNCIÓN DIVISIÓN\nprint(\"\\nFUNCIÓN DIVISIÓN\")\n\n\n// Representación del error, de la función de la division.\nenum DivisonError: Error {\n    case divisionByZero\n}\n\n// Definicion de la funcion division con la capacidad de lanzar errores.\nfunc division(number1 n1: Float, numner2 n2: Float) throws -> Float {\n    // Lanza el error si el n2 es igual a cero.\n    guard n2 != 0 else {\n        throw DivisonError.divisionByZero\n    }\n    return n1 / n2\n}\n\nprint(\"\\nIntroduce el dividendo:\")\nvar dividend: Float = 0.0\nif let input = readLine(), let n1Float = Float(input) {\n    dividend = n1Float\n}\n\nprint(\"\\nIntroduce el divisor:\")\nvar divisor: Float = 0.0\nif let input = readLine(), let n2Float = Float(input) {\n    divisor = n2Float\n}\n\n// Llama a la función y captura el error.\ndo {\n    let result: Float = try division(number1: dividend, numner2: divisor)\n    print(\"\\n\", result)\n} catch DivisonError.divisionByZero {\n    print(\"\\nERROR -> división entre cero.\")\n}\n\n\n// FUNCIÓN INDICE DEL ARRAY\nprint(\"\\nFUNCIÓN INDICE DEL ARRAY\")\n\n\n// Representa los errores de la función indice del array.\nenum ArrayIndexError: Error {\n    case indesUpper\n    case indexLower\n}\n\n// Declaración de la funcion indice del array con la capacidad de lanzar errores.\nfunc arrayChecker(array arr: [String], index: Int) throws -> String {\n    guard index < arr.count else {\n        throw ArrayIndexError.indesUpper\n    }\n    guard index > 0 else {\n        throw ArrayIndexError.indexLower\n    }\n\n    let value = arr[index]\n    \n    return value\n}\n\nprint(\"\\nIntroduce los elementos del array:\\nIntroduce exit para parar de añadir.\")\nvar array: [String] = []\nwhile true {\n    if let input = readLine() {\n        if input == \"exit\" {\n            break\n        }\n        array.append(input)\n    }\n}\n\nprint(\"\\nIntroduce el indice:\")\nvar arrayIndex = 0\nif let input = readLine(), let indexInt = Int(input) {\n    arrayIndex = indexInt\n}\n\n// Llama a la función y captura los errores.\ndo {\n    let value = try arrayChecker(array: array, index: arrayIndex)\n    print(\"\\n\", value)\n} catch ArrayIndexError.indesUpper {\n    print(\"\\nERROR -> indice alto\")\n} catch ArrayIndexError.indexLower {\n    print(\"\\nERROR -> Indece bajo\")\n}\n\n\n\n// DIFICULTAD EXTRA\nprint(\"\\nDIFICULTAD EXTRA\")\n\n\n// Representa los errores de la función takeCoffe.\nenum BuyCoffeError: Error {\n    case invalidCoffe\n    case insuficientCoins(coinsNeeded: Int)\n    case outOfStock\n}\n\n// Modelo de datos del Coffe.\nstruct Coffe {\n    var price: Int\n    var count: Int\n}\n\n// Define un diccionario con el nombre del cafe y el modelo de datos.\nvar coffesMenu: [String: Coffe] = [\n    \"Capuchino\": Coffe(price: 7, count: 4),\n    \"Late\": Coffe(price: 4, count: 10),\n    \"Mocca\": Coffe(price: 9, count: 0)\n]\n\n// Define la función takeCoffe con la capacidad de lanzar errores.\nfunc takeCoffe(coffeName item: String, coins: Int, amount: Int) throws {\n    let coinsInserted = coins\n\n    guard let coffe = coffesMenu[item] else {\n        throw BuyCoffeError.invalidCoffe\n    }\n    guard coffe.count > amount else {\n        throw BuyCoffeError.outOfStock\n    }\n    guard coffe.price <= coinsInserted else {\n        throw BuyCoffeError.insuficientCoins(coinsNeeded: coffe.price - coins)\n    }\n    var coffeChoosen = coffe\n    coffeChoosen.count -= amount\n    coffesMenu[item] = coffeChoosen\n\n    print(\"Tu \\(item) esta listo.\")\n}\n\nprint(\"\\nQue cafe quieres?\")\nvar coffe = \"\"\nif let input = readLine() {\n    coffe = input\n}\n\nprint(\"\\nCuantos cafes quieres?\")\nvar amount = 0\nif let input = readLine(), let amounttInt = Int(input) {\n    amount = amounttInt\n}\n\nprint(\"\\nIntroduce las monedas.\")\nvar coins = 0\nif let input = readLine(), let coinsInt = Int(input) {\n    coins = coinsInt\n}\n\n// Llama a la función y captura los errores.\ndo {\n    try takeCoffe(coffeName: coffe, coins: coins, amount: amount)\n} catch BuyCoffeError.invalidCoffe {\n    print(\"\\nERROR -> Ese cafe no esta disponible.\")\n} catch BuyCoffeError.insuficientCoins(let coinsNeeded) {\n    print(\"\\nERROR -> Monedas insuficientes, faltan \\(coinsNeeded) monedas.\")\n} catch BuyCoffeError.outOfStock {\n    print(\"\\nERROR -> Cafe agotado.\")\n} catch {\n    print(\"\\nERROR -> \\(error.localizedDescription)\")\n}\n\n\n\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/swift/blackriper.swift",
    "content": "import Foundation\n/* las excepciones se usan para manejar errores  en swift \n   se pueden manejar de la siguiente manera\n   do {\n    \n   } catch error {\n    \n   }\n    las funciones , clases pueden tener excepciones para agregar alguna \n    se hace de la siguiente manera:\n\n    func getResponde() throws  ->String\n\n    esto quiere decir que la funcion puede retornar un error\n\n    para crear uno o mas errores personalizados usamos el enum este debe implementar el protocolo Error\n\n    enum MiError: Error {\n        case ErrorConocido\n    }\n */\n  \nenum ArithmeticError: Error {\n    case divideByZero\n    case moduloByZero\n}\n\nfunc divide(_ dividend: Int, by divisor: Int) throws -> Int {\n    if divisor == 0 {\n        throw ArithmeticError.divideByZero\n    }\n    return dividend / divisor\n}\n\nfunc modulo(_ dividend: Int, by divisor: Int) throws -> Int {\n    if divisor == 0 {\n        throw ArithmeticError.moduloByZero\n    }\n    return dividend % divisor\n}\n\ndo {\n    let result = try divide(10, by: 0)\n    print(result)\n} catch ArithmeticError.divideByZero {\n    print(\"No se puede dividir por 0\")\n}\n\ndo {\n    let result = try modulo(10, by: 0)\n    print(result)\n} catch ArithmeticError.moduloByZero {\n    print(\"No se puede dividir por 0\")\n}\n\n//ejercicio extra\n\nenum ProductError: Error {\n    case outOfStock\n    case notFoundProduct\n    case nillStock\n}\n\nstruct Product {\n    var id :UUID\n    var name: String\n    var stock: Int?\n}\n\nlet products = [\n          Product(id: UUID(), name: \"iPhone15pro\", stock: 10),\n          Product(id: UUID(), name: \"Samsung s24\", stock: 0),\n          Product(id: UUID(), name: \"Xiaomi\", stock: nil)]\n\n\nfunc buy(nom: String,cantity: Int) throws {\n    guard let product = products.first(where: {$0.name==nom}) else {\n        throw ProductError.notFoundProduct\n    }\n    \n    guard let stock = product.stock else {\n        throw ProductError.nillStock\n    }\n    \n    if stock < cantity {\n        throw ProductError.outOfStock\n    }\n    \n}\n\ndo {\n    //try buy(nom: \"Motorola\", cantity: 10)\n    //try buy(nom: \"Samsung s24\", cantity: 10)\n    try buy(nom: \"Xiaomi\", cantity: 14)\n} catch ProductError.outOfStock {\n    print(\"out of stock\")\n} catch ProductError.notFoundProduct {\n    print(\"product not found\")\n} catch ProductError.nillStock {\n    print(\"stock not available\")\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/swift/didacdev.swift",
    "content": "import Foundation\n\nenum MyError: Error {\n    case errorEmptyList\n}\n\nfunc divideBy(numbers: [Int], divisor: Int, size: Int) throws {\n\n    guard numbers.count != 0 else {\n        throw MyError.errorEmptyList\n    }\n\n    guard divisor != 0 else {\n        throw fatalError(\"Divisor can't be 0\")\n    }\n\n    guard numbers.count == size else {\n        throw fatalError(\"Size should be numbers.count\")\n    }\n\n    for index in 0..<size {\n        print(numbers[index] / divisor)\n    }\n\n    print(\"Ejecución finalizada sin errores\")\n}\n\ndo {\n    try divideBy(numbers: [], divisor: 2, size: 4)\n} catch MyError.errorEmptyList{\n    print(\"The list is empty\")\n} catch {\n    print(\"Error \\(error.localizedDescription)\")\n} \ndefer {\n    print(\"Ejecución finalizada\")\n}"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/swift/kontroldev.swift",
    "content": "import Foundation\n\n\n/*\n* EJERCICIO:\n* Explora el concepto de manejo de excepciones según tu lenguaje.\n* Fuerza un error en tu código, captura el error, imprime dicho error\n* y evita que el programa se detenga de manera inesperada.\n* Prueba a dividir \"10/0\" o acceder a un indice no existente\n* de un listado para intentar provocar un error.\n*\n* DIFICULTAD EXTRA (opcional):\n* Crea una función que sea capaz de procesar parámetros, pero que también\n* pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n* corresponderse con un tipo de excepción creada por nosotros de manera\n* personalizada, y debe ser lanzada de manera manual) en caso de error.\n* - Captura todas las excepciones desde el lugar donde llamas a la función.\n* - Imprime el tipo de error.\n* - Imprime si no se ha producido ningún error.\n* - Imprime que la ejecución ha finalizado.\n*/\n\n\nenum CustomError: Error {\n    case divisionByZero\n    case indexOutOfRange\n}\n\nfunc handleExceptions() {\n    do {\n        // División por cero\n        let result = try divide(10, by: 0)\n        print(\"El resultado de la división es:\", result)\n    } catch CustomError.divisionByZero {\n        print(\"Error: División por cero\")\n    } catch {\n        print(\"Se produjo un error inesperado:\", error)\n    }\n\n    do {\n        // Acceder a un índice no existente\n        let array = [1, 2, 3]\n        let value = try getValue(at: 4, from: array)\n        print(\"El valor obtenido es:\", value)\n    } catch CustomError.indexOutOfRange {\n        print(\"Error: Índice fuera de rango\")\n    } catch {\n        print(\"Se produjo un error inesperado:\", error)\n    }\n}\n\nfunc divide(_ dividend: Int, by divisor: Int) throws -> Int {\n    guard divisor != 0 else {\n        throw CustomError.divisionByZero\n    }\n    return dividend / divisor\n}\n\nfunc getValue(at index: Int, from array: [Int]) throws -> Int {\n    guard index >= 0 && index < array.count else {\n        throw CustomError.indexOutOfRange\n    }\n    return array[index]\n}\n\nhandleExceptions()\n\n//MARK: - Extra\nenum StrTypeError: Error {\n    case invalidType\n}\n\nfunc processParams(_ parameters: [Any]) {\n    guard parameters.count >= 3 else {\n        print(\"El número de elementos de la lista debe ser mayor que dos.\")\n        return\n    }\n    \n    guard let divisor = parameters[1] as? Int, divisor != 0 else {\n        print(\"El segundo elemento de la lista no puede ser un cero.\")\n        return\n    }\n    \n    guard !(parameters[2] is String) else {\n        print(\"El tercer elemento no puede ser una cadena de texto.\")\n        return\n    }\n    \n    print(parameters[2])\n    print(parameters[0] as! Int / divisor)\n    print((parameters[2] as! Int) + 5)\n}\n\ndo {\n    try processParams([1, 2, 3, 4])\n} catch StrTypeError.invalidType {\n    print(\"El tercer elemento no puede ser una cadena de texto.\")\n} catch let error as NSError {\n    print(\"Se ha producido un error inesperado: \\(error.localizedDescription)\")\n} catch {\n    print(\"Se ha producido un error inesperado.\")\n} finally {\n    print(\"El programa finaliza sin detenerse.\")\n}\n\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/swift/pedroomar23.swift",
    "content": "import Foundation\n\n/*\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado. \n */\n\nenum sendError: Error {\n    case divideByZero\n    case rangeOutZero\n}\n\nfunc exception() {\n    do {\n        let result = try divide(10, by: 0)\n        print(\"El resultado de la division 10/0 es:\", result)\n    } catch sendError.divideByZero {\n        print(\"No hay errores en la division 10/0\")\n    } catch {\n        print(\"hay un error en la division 10/0\", error)\n    }\n\n    do {\n        let numero = getNumero[1, 2, 3]\n        let numero = try getNumero(at: 4, by: rangeOutZero)\n    } catch sendError.rangeOutZero {\n        print(\"El numero 4 se encuentra en le array\")\n    } catch {\n        print(\"Hubo un error 4 no se encuentra en el array\", error)\n    }\n}\n\nfunc divide(_ divideByZero: Int, dividendo: Int) throws -> Int {\n    guard let != 0 else {\n        throws sendError.divideByZero\n    }\n\n    return divideByZero / dividendo\n}\n\nfunc range(_ rangeOutZero: Int) throws -> Int {\n    guard let numero = getNumero[1, 2, 3] else {\n        throws sendError.rangeOutZero\n    }\n\n    return let numero = getNumero(at: 4, by: rangeOutZero)\n}\n\nexception()"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/typescript/AChapeton.ts",
    "content": "let myArray: Array<string> = ['a', 'b', 'c', 'd']\n\n//TRY - Bloque del codigo que se va a evaluar\n//CATCH - Bloque del codigo que se ejecuta si se encuentra un error en el bloque TRY\n//FINALLY - Bloque de codigo (opcional) que se va a ejecutar una vez haya terminado el bloque TRY, independientemente de su resultado\n\ntry{\n    myArray[8].length\n}catch(error){\n  throw 'No se puede acceder a una posicion que no existe en el array.' + error\n}finally{\n  console.log(myArray.length)\n}\n\n\n\n// DIFICULTAD EXTRA\n\nclass customException extends Error{\n  constructor(message: string){\n    super(message)\n    this.name = 'Custom Exception'\n  }\n}\n\nconst myFunction = (num1: number, num2: number) => {\n  try{\n    if(num1 < 0){\n      throw new Error('El primer valor no puede ser menor a cero.')\n    }\n\n    if((num2 % 2) !== 0){\n      throw new Error('El segundo valor debe ser un numero par.')\n    }\n\n    if((num1 + num2) > 99){\n      throw new customException('La suma de los valores no puede sobrepasar de 100.')\n    }\n  }catch(error){\n    console.log('Tipo de error: ', error instanceof customException ? 'Custom error' : 'Normal error')\n    console.log('Mensaje de error: ', error.message)\n  }finally{\n    console.log('Fin del ejercicio')\n  }\n}\n\nmyFunction(444, 50)"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/typescript/IgleDev.ts",
    "content": "// Ejercicio 1\n    // Por Índice\n        //  EL try catch intenta hacer un trozo de código que le mandemos\n        let lista: Array<number> = [2, 3, 4];\n        try {\n            if (lista.length <= 10) {\n                throw new Error('El índice está fuera del rango del array.');\n            }\n            lista[10] = 0; // Intentamos acceder a un índice que no existe en el array\n        } catch (error) {\n            console.error('Ha ocurrido un error:' + error);\n        } finally {\n            console.log('La ejecución del bloque try-catch ha terminado.');\n        }\n\n\n    //Dividiendo 10/0\n    try {\n        let divisor = 0;\n    \n        if (divisor === 0) {\n            throw new Error('División por cero no está permitida.');\n        }\n    \n        let result = 10 / divisor;\n        console.log('Resultado:' + result);\n    } catch (error) {\n        console.error('Ha ocurrido un error:' + error);\n    } finally {\n        console.log('La ejecución del bloque try-catch ha terminado.');\n    }\n\n\n    // Ejercicio Extra\n    class CustomError extends Error {\n        constructor(message: string) {\n            super(message);\n            this.name = \"CustomError\";\n        }\n    }\n\n    function procesarParametros(param1: number, param2: number): void {\n        try {\n            const resultado = param1 / param2;\n            console.log('Resultado del procesamiento: ' +resultado);\n        } catch (error) {\n            if (error instanceof CustomError) {\n                console.error('Error personalizado: ' + error.message);\n            } else if (error instanceof TypeError) {\n                console.error('Error de tipo: ' + error.message);\n            } else {\n                console.error('Error desconocido: ' + error.message);\n            }\n        } finally {\n            console.log('La ejecución ha finalizado');\n        }\n    }\n\n    // Ejemplo de uso\n    try {\n        procesarParametros(10, 0); // Lanza una excepción personalizada\n        procesarParametros(20, 1); // Lanza una excepción de tipo\n        procesarParametros(30, 5); // No se produce ningún error\n    } catch (error) {\n        console.error('Error capturado fuera de la función: ' + error.message);\n    }"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/typescript/RobertoAmaroHub.ts",
    "content": "function showError(){\n    throw new Error(\"Error en la aplicación\");\n}\n\nfunction iniciarApp(){\n    try{\n        showError();\n    } catch(error){\n        console.error(`${error}`);\n    } finally {\n        console.log(\"Aplicación finalizada\\n\")\n    }\n}\n\niniciarApp();\n\n//EXTRA\ninterface errorObj{\n    errorCode:number,\n    body:string\n}\nconsole.log(\"**************MANEJO DE ERRORES*************\")\nexport abstract class CustomError extends Error{\n    abstract errorCode: number;\n\n    constructor(message: string){\n        super(message);\n        Object.setPrototypeOf(this, new.target.prototype);\n    }\n}\n\nexport class ValidationError extends CustomError{\n    errorCode = 0;\n    constructor(message:string){\n        super(message);\n        this.name=\"ValidationError\"\n    }\n}\nexport class OutOfRange extends CustomError{\n    errorCode = -1;\n    constructor(message:string){\n        super(message);\n        this.name=\"OutOfRange\"\n    }\n}\n\nexport default function handleError(error: any): errorObj {\n    if (error instanceof CustomError) {\n      return {\n        errorCode: error.errorCode,\n        body: JSON.stringify({ message: error.message }),\n      };\n    } else {\n      return {\n        errorCode: 500,\n        body: error,\n      };\n    }\n  }\n\n  function app(numero:number){\n    try{\n        switch(numero){\n            case 1:\n                throw new ValidationError(\"Validación incorrecta, inténtalo de nuevo\");\n            case 2:\n                throw new OutOfRange(\"El número esta fuera del rango permitido\");\n            case 3:\n                let list:string[]=[\"hola\"];\n                let data:number=list[2].length\n                console.log(data);\n                break;\n            default:\n                console.dir(\"No se ha producido ningún error\")\n                break;\n        }\n    } catch(error){\n        const response = handleError(error);\n        console.warn(\"Código de error: \"+response.errorCode)\n        console.error(`ERROR: ${response.errorCode}, ${response.body}`);\n        \n    } finally {\n      console.log(\"Aplicación finalizada\\n\");\n    }\n  }\n  \n  app(1);\n  app(2);\n  app(3);\n  app(4);"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/typescript/Sac-Corts.ts",
    "content": "function safeDivision(a: number, b: number): number | null {\n    try {\n        if (b === 0) {\n            throw new Error(\"Cannot divide by 0\");\n        }\n        return a / b;\n    } catch (error) {\n        console.error(\"Error caught:\", error.message);\n        return null;\n    } finally {\n        console.log(\"Execution completed\");\n    }\n}\n\nconst result = safeDivision(10, 0);\nconsole.log(\"Result:\", result);\n\n// ** Extra Exercise ** //\nclass CustomeError extends Error {\n    constructor(message: string) {\n        super(message);\n        this.name = \"CustomError\";\n    }\n}\n\nfunction processInput(input: any) {\n    try {\n        if (typeof input === \"string\") {\n            throw new TypeError(\"Input cannot be a string\");\n        }\n\n        if (input === null || input === undefined) {\n            throw new ReferenceError(\"Input cannot be null or undefined\");\n        }\n\n        if (input < 0) {\n            throw new CustomeError(\"Input cannot be a negative number\");\n        }\n\n        console.log(\"Processing input:\", input);\n    } catch (error) {\n        throw error;\n    }\n}\n\nfunction execute() {\n    try {\n        processInput(-10);\n        console.log(\"No error has ocurred\");\n    } catch (error) {\n        console.error(`Error caught: ${error.name} - ${error.message}`);\n    } finally {\n        console.log(\"Execution completed\");\n    }\n}\n\nexecute();"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/typescript/david-git-dev.ts",
    "content": "/*\n  EJERCICIO:\n  Explora el concepto de manejo de excepciones según tu lenguaje.\n  Fuerza un error en tu código, captura el error, imprime dicho error\n  y evita que el programa se detenga de manera inesperada.\n  Prueba a dividir \"10/0\" o acceder a un índice no existente\n  de un listado para intentar provocar un error.\n */\n  function isNumeric(x:any) {\n    return [\"number\", \"bigint\"].includes(typeof x);\n  }\n\n  function sum(...values:any[]) {\n    if (!values.every(isNumeric)) {\n      throw new TypeError(\"Can only add numbers\");\n    }\n    return values.reduce((a, b) => a + b);\n  }\n\n  console.log(sum(1, 2, 3)); // 6\n  try {\n    sum(\"1\", \"2\");\n  } catch (e) {\n    if(e instanceof Error)\n    console.error(e); // TypeError: Can only add numbers\n  }\n  /*\n  DIFICULTAD EXTRA (opcional):\n  Crea una función que sea capaz de procesar parámetros, pero que también\n  pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n  corresponderse con un tipo de excepción creada por nosotros de manera\n  personalizada, y debe ser lanzada de manera manual) en caso de error.\n  - Captura todas las excepciones desde el lugar donde llamas a la función.\n  - Imprime el tipo de error.\n  - Imprime si no se ha producido ningún error.\n  - Imprime que la ejecución ha finalizado.\n */\nclass IHateNineNumberError extends Error {\n  constructor(mensaje: string) {\n    super(mensaje);\n    this.name = \"IHateNineNumberError\"; // Establece el nombre del error\n  }\n}\nfunction threeErrorTypes(...args:any[]) {\n  try {\n    //const divByZero = 1n / 0n; error by zero RangeError\n    if (args.some((num) => num === 9))\n      throw new IHateNineNumberError(\"dont use 9! number!!!\");\n    //const res = args[1].content.json; ReferenceError\n    //args[5] error index of bounce RangeError\n  } catch (e) {\n   if(e instanceof Error){\n    switch (e.name) {\n      case \"Error\":\n        console.error(\"Error general\");\n        break;\n      case \"RangeError\":\n        console.error(\"Error de rango\");\n        break;\n      case \"ReferenceError\":\n        console.error(\"Error de referencia\");\n        break;\n      default:\n        console.error(\"Vaya esto es nuevo...\", e);\n        break;\n    }\n   }\n  } finally {\n    console.log(\"Operacion terminada\");\n  }\n}\nthreeErrorTypes(1, 9, \"response\", true);"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/typescript/duendeintemporal.ts",
    "content": "/* #10 { retosparaprogramadores } EXCEPCIONES */\n//bibliography reference\n//Secrets of the JavaScript Ninja (John Resig, Bear Bibeault, Josip Maras) (z-lib.org)\n//Professional JavaScript for web developers by Matt Frisbie [Frisbie, Matt] (z-lib.org)\n//JavaScript Notes for Professionals (GoalKicker.com) (Z-Library)\n//GPT\n\n//Short for console.log()\nlet log = console.log;\n\n    log( 'Retosparaprogramadores #10'); \n\n/* Runtime errors in JavaScript are instances of the Error object. The Error object can also be used as-is, or as the base for user-defined exceptions. It's possible to throw any type of value - for example, strings - but you're strongly encouraged to use Error or one of its derivatives to ensure that debugging information -- such as stack traces -- is correctly preserved.\nThe first parameter to the Error constructor is the human-readable error message. You should try to always specify a useful error message of what went wrong, even if additional information can be found elsewhere.\n} */\n\n/* In JavaScript, exception handling is primarily done through the statements try, catch, finally, and throw. Here is a summary of each:\n\n    try: It is used to wrap the code that may throw an exception. If an error occurs within the try block, control is transferred to the catch block.\n    catch: It is used to handle the exception. It receives the error object as an argument.\n    finally: This block executes after the try and catch blocks have completed, regardless of whether an exception was thrown or not.\n    throw: It is used to manually throw an exception.\n */\n\nlet num: number = 0, result;\n\ntry {\n    if(typeof num === 'number' && num != 0) {\n        result = 10 / num;\n    }else if(num == 0) {\n        throw new Error(\"It seems you've tried to divide by zero, which is not permitted. Please enter a valid non-zero number.\");\n    }else{\n        throw new Error(\"It seems you've tried to divide by a non number value, which is not permitted. Please enter a valid number.\");\n    }\n} catch (error) {\n    log('Something went wrong! ' + (error as Error).message);\n}\n\nlog(result); // Something went wrong! It seems you've tried to divide by zero, which is not permitted. Please enter a valid non-zero number.\n\n//Note: Javascript returns infinity for divide any number by 0, so we have to explicity throw and error if we want inform about it.\n\n/* Exceptions are to synchronous code what rejections are to promise-based asynchronous code. If an exception is thrown in a promise handler, its error will be automatically caught and used to reject the promise instead. */\n\nPromise.resolve(102)\n    .then(result => {\n        throw new Error(\"explicitly rejected promise\" + result);\n})\n    .then(result => {\n        console.info(\"Promise resolved: \" + result);\n})\n    .catch(error => {\n        console.error(\"Promise rejected: \" + error);\n}); // Promise rejected: Error: explicitly rejected promise (it will be logged at the end cause the async nature of the promise constructor)\n\n/* There are six specific core error constructors in JavaScript:\nEvalError - creates an instance representing an error that occurs regarding the global function eval().\nInternalError - creates an instance representing an error that occurs when an internal error in the\nJavaScript engine is thrown. E.g. \"too much recursion\". (Supported only by Mozilla Firefox)\nRangeError - creates an instance representing an error that occurs when a numeric variable or parameter is outside of its valid range.\nReferenceError - creates an instance representing an error that occurs when dereferencing an invalid\nreference.\nSyntaxError - creates an instance representing a syntax error that occurs while parsing code in eval().\nTypeError - creates an instance representing an error that occurs when a variable or parameter is not of a valid type.\nURIError - creates an instance representing an error that occurs when encodeURI() or decodeURI() are\npassed invalid parameters.\nIf you are implementing error handling mechanism you can check which kind of error you are catching from code. */\n\nfunction getUserName(user: {name: string}): void {\n    try {\n        const name: string = user.name.toUpperCase();\n        log(`User name: ${name}`);\n    } catch (e) {\n        if ((e as Error) instanceof Error) {\n            log('Instance of general Error constructor');\n        }\n\n        if ((e as Error) instanceof TypeError) {\n            log('TypeError: Cannot read property \"name\" of undefined or null');\n        }\n    }\n}\n\ngetUserName({ name: 'Roxy' }); //  User name: Roxy\n\n//in Javascript\n//getUserName(undefined); // Instance of general Error constructor TypeError: Cannot read property \"name\" of undefined or null\n\n//in Typescript\n//getUserName(undefined); //Argument of type 'undefined' is not assignable to parameter of type '{ name: string; }'.ts(2345)\n\n//Extra excercises\n\nconst checkValues = (arr: number[], index: number)=>{\n    try{\n        if(!Array.isArray(arr)){\n            throw new TypeError('the first parameter most be of type array');\n        }else{\n            if(arr.length < 0 || arr.length == 0) throw new Error('You give a empty array as parameter!');\n\n            if(!arr[index]) throw new ReferenceError(`${index} is not a valid index for the array given`);\n        }\n\n        log(`The position given corresponds to this value: ${arr[index]}`);\n        log(\"There's no errors when executing the function.\")\n\n    }catch(e){\n        log((e as Error).name + \": Ooops! \" + (e as Error).message);\n    }finally{\n        log('The process is finished')\n    }\n}\n\ncheckValues([8, 5, 6, 4], 8); // ReferenceError: Ooops! 8 is not a valid index for the array given\n// The process is finished\ncheckValues([], 4); // Error: Ooops! You give a empty array as parameter!\n// The process is finished\n//in javascript\n// checkValues([0, 76, 32, 1, 4, 2], 'Kia'); // ReferenceError: Ooops! Kia is not a valid index for the array given\n// The process is finished\n//in typescript\n// checkValues([0, 76, 32, 1, 4, 2], 'Kia'); //Argument of type 'string' is not assignable to parameter of type 'number'.ts(2345)\n//in javascript\n// checkValues('Dev', 5); // TypeError: Ooops! the first parameter most be of type array\n// The process is finished\n//in typescript\n// checkValues('Dev', 5); // Argument of type 'string' is not assignable to parameter of type 'number[]'.ts(2345)\n\ncheckValues([4, 5, 3, 18, 22], 3); // The position given corresponds to this value: 18\n// There's no errors when executing the function.\n// The process is finished"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/typescript/eulogioep.ts",
    "content": "// Parte 1: Manejo básico de excepciones\n\n// Ejemplo 1: División por cero\ntry {\n    // Intentamos dividir por cero\n    const resultado: number = 10 / 0;\n    console.log(resultado); // En TypeScript/JavaScript, esto no lanza una excepción, imprime Infinity\n} catch (error) {\n    console.log(\"Error aritmético:\", (error as Error).message);\n}\n\n// Ejemplo 2: Acceso a índice no existente\ntry {\n    // Intentamos acceder a un índice no existente de un array\n    const array: string[] = [\"Elemento\"];\n    const elemento: string | undefined = array[5];\n    console.log(elemento); // Esto no lanza una excepción, devuelve undefined\n    // Para forzar un error, podemos intentar acceder a una propiedad de undefined\n    console.log(elemento!.length);\n} catch (error) {\n    console.log(\"Error de acceso:\", (error as Error).message);\n}\n\n// Parte 2: Función con múltiples excepciones (DIFICULTAD EXTRA)\n\n// Definimos nuestra excepción personalizada\nclass MiExcepcionPersonalizada extends Error {\n    constructor(mensaje: string) {\n        super(mensaje);\n        this.name = \"MiExcepcionPersonalizada\";\n    }\n}\n\n// Función que puede lanzar 3 tipos diferentes de excepciones\nfunction procesarParametro(parametro: unknown): void {\n    if (typeof parametro !== 'number') {\n        throw new TypeError(\"El parámetro debe ser un número\");\n    }\n    if (parametro < 0) {\n        throw new RangeError(\"El parámetro no puede ser negativo\");\n    }\n    if (parametro === 0) {\n        throw new Error(\"No se puede dividir por cero\");\n    }\n    if (parametro > 10) {\n        throw new MiExcepcionPersonalizada(\"El parámetro es demasiado grande\");\n    }\n\n    // Si no hay errores, realizamos alguna operación\n    const resultado: number = 100 / parametro;\n    console.log(\"Resultado:\", resultado);\n}\n\n// Función para probar procesarParametro\nfunction probarProcesarParametro(valor: unknown): void {\n    try {\n        procesarParametro(valor);\n        console.log(\"No se ha producido ningún error.\");\n    } catch (error) {\n        if (error instanceof Error) {\n            console.log(\"Tipo de error:\", error.constructor.name);\n            console.log(\"Mensaje:\", error.message);\n        } else {\n            console.log(\"Se produjo un error desconocido\");\n        }\n    } finally {\n        console.log(\"La ejecución ha finalizado.\");\n    }\n    console.log(\"---\");\n}\n\n// Probamos con diferentes valores\nprobarProcesarParametro(\"no es un número\");\nprobarProcesarParametro(-1);\nprobarProcesarParametro(0);\nprobarProcesarParametro(5);\nprobarProcesarParametro(15);"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/typescript/hozlucas28.ts",
    "content": "/*\n    Exceptions...\n*/\n\nconsole.log('Exceptions...')\n\nconsole.log(`\\nlet array: number[][] = [\n    [1, 2, 3],\n    [4, 5, 6],\n    [7, 8, 9],\n]\n\ntry {\n    array[3][0] += array[2][0]\n    array[3][1] += array[2][1]\n    array[3][2] += array[2][2]\n} catch (error) {\n    console.error(\\`\\\\n\\${error}\\`)\n}`)\n\nlet array: number[][] = [\n\t[1, 2, 3],\n\t[4, 5, 6],\n\t[7, 8, 9],\n]\n\ntry {\n\tarray[3][0] += array[2][0]\n\tarray[3][1] += array[2][1]\n\tarray[3][2] += array[2][2]\n} catch (error) {\n\tconsole.error(`\\n${error}`)\n}\n\nconsole.log(\n\t'\\n# ---------------------------------------------------------------------------------- #\\n'\n)\n\n/*\n    Additional challenge...\n*/\n\nconsole.log('Additional challenge...')\n\nfunction fn(param: number | string | string[] | Function): string | undefined {\n\tif (typeof param === 'number') throw new Error('My custom error')\n\tif (typeof param === 'function') param()\n\t// @ts-expect-error\n\treturn param.toUpperCase()\n}\n\n// No error\ntry {\n\tconst rtn = fn('Hello World!')\n\tconsole.log(`\\n${rtn}`)\n} catch (error) {\n\tconsole.error(`\\n${error}`)\n}\n\n// Custom error\ntry {\n\tconst rtn = fn(22)\n\tconsole.log(`\\n${rtn}`)\n} catch (error) {\n\tconsole.error(`\\n${error}`)\n}\n\n// Range error\ntry {\n\tconst recursiveFn = () => recursiveFn()\n\tconst rtn = fn(recursiveFn)\n\tconsole.log(`\\n${rtn}`)\n} catch (error) {\n\tconsole.error(`\\n${error}`)\n}\n\n// Type error\ntry {\n\tconst rtn = fn(['Hello World!'])\n\tconsole.log(`\\n${rtn}`)\n} catch (error) {\n\tconsole.error(`\\n${error}`)\n}\n\nconsole.log('\\nAdditional challenge finished!')\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/typescript/ialmontedr0.ts",
    "content": "/*\r\n * EJERCICIO:\r\n * Explora el concepto de manejo de excepciones según tu lenguaje.\r\n * Fuerza un error en tu código, captura el error, imprime dicho error\r\n * y evita que el programa se detenga de manera inesperada.\r\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\r\n * de un listado para intentar provocar un error.\r\n *\r\n * DIFICULTAD EXTRA (opcional):\r\n * Crea una función que sea capaz de procesar parámetros, pero que también\r\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\r\n * corresponderse con un tipo de excepción creada por nosotros de manera\r\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\r\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\r\n * - Imprime el tipo de error.\r\n * - Imprime si no se ha producido ningún error.\r\n * - Imprime que la ejecución ha finalizado.\r\n */\r\n\r\n// Ejercicio: Manejo de excepciones en Typescript\r\ntry {\r\n  // Código que podría generar una excepción\r\n  let arreglo: number[] = [1, 2, 3, 4]; // Aquí podría haber un error de tipo de dato o índice fuera del rango\r\n  let i: number = 3; // Aquí podría haber un error de índice fuera del rango\r\n\r\n  if (!arreglo[i] || arreglo[i] < 0) {\r\n    // Generará un error de índice fuera del rango\r\n    throw new Error(\"Indice no existe o menor que cero\"); // Lanza una excepción personalizada\r\n  } else {\r\n    // Si no hay error, muestra el valor del elemento\r\n    console.log(arreglo[i]); // Imprime el valor del elemento\r\n  }\r\n\r\n  let resultado: number = 10 / 1; // Generará un error de división por cero\r\n  if (resultado === Infinity || resultado === -Infinity) {\r\n    // Generará un error de división por cero\r\n    throw new Error(\"Division por cero\"); // Lanza una excepción personalizada\r\n  }\r\n  console.log(resultado); // Imprime el resultado\r\n} catch (error) {\r\n  // Captura y muestra el error\r\n  console.error(\"Se produjo un error:\", error); // Imprime el error\r\n}\r\n\r\n// Ejercicio: Manejo de excepciones en Typescript (difícultad extra)\r\n\r\n// Definimos las excepciones personalizadas\r\nclass ErrorIndice extends Error {\r\n  constructor(message?: string) {\r\n    super(message);\r\n    this.name = \"IndiceError\";\r\n    this.message =\r\n      \"La longitud de los parametros debe ser al menos de 3 indices\";\r\n  }\r\n}\r\n\r\n// Definimos la excepcion personalizada\r\nclass ErrorDivisionPorCero extends Error {\r\n  constructor(message?: string) {\r\n    super(message);\r\n    this.name = \"DivisionPorCeroError\";\r\n    this.message = \"El segundo elemento de la lista no puede ser un cero\";\r\n  }\r\n}\r\n\r\n// Funcion que procesa los parametros\r\nconst procesarParametros = (parametros: number[]): void => {\r\n  // Validaciones y procesos...\r\n  if (parametros.length < 3) {\r\n    throw new ErrorIndice(); // Lanza una excepcion personalizada\r\n  } else if (parametros[1] === 0) {\r\n    throw new ErrorDivisionPorCero();\r\n  } else {\r\n    console.log(\"No se produjeron errores\");\r\n  }\r\n\r\n  // Imprimimos los valores de los parámetros\r\n  console.log(parametros[2]);\r\n  console.log(parametros[0] / parametros[1]); // Suma los dos primeros parámetros y muestra el resultado\r\n  console.log(parametros[2] + 5);\r\n};\r\n\r\n// LLamar a la funcion\r\ntry {\r\n  procesarParametros([1, 2, 3, 4]);\r\n} catch (error) {\r\n  if (error instanceof ErrorIndice) {\r\n    console.log(\"Se ha producido un error\", error.message);\r\n  } else if (error instanceof ErrorDivisionPorCero) {\r\n    console.log(\"Se produjo un error\", error.message);\r\n  } else if (error instanceof TypeError) {\r\n    console.log(\"Se ha producido un error inesperado\", error.message);\r\n  } else if (error instanceof Error) {\r\n    console.error(\"Se ha producido un error de tipo: \" + error.message);\r\n  }\r\n} finally {\r\n  console.log(\"El programa finaliza sin detenerse\");\r\n}\r\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/typescript/juserdev.ts",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado. \n */\n\nnamespace challenge_10{\n    // const dividir = (a: number, b: number): number =>{\n    //     if (b === 0) {\n    //         throw new Error(\"no se puede dividir entre 0\")\n    //     }\n    //     return a / b\n    // }\n    \n    // try {\n    //     const resultado = dividir(10,0)\n    //     console.log(`Resultado: ${resultado}`)\n    // }\n    // catch(e){\n    //     console.error(\"Se a ocacionado un error: \", (e as Error).message)\n    // }\n    // console.log(\"Hola, que pasa!\") \n\n    class DivisionByZeroError extends Error{\n        constructor(){\n            super(\"No se puede dividir por 0\")\n            this.name = \"DivisionByZeroError\"\n        }\n    }\n    \n    //* Esta la cree para probar mi conocimiento sobre el tema\n\n    class StrTypeError extends Error{ \n        constructor(){\n            super(\"el parametro no puede ser un string\")\n            this.name = \"StrTypeError\"\n        }\n    }\n\n    const process_param = (params: any[])=>{\n        if (params.length < 3) {\n            throw new RangeError(\"El numero de parametros es insuficientes, se esperan al menos 3\")\n        } else if (params[1] === 0){\n            throw new DivisionByZeroError()\n        } else if (typeof params[2] !== \"number\") {\n            // throw new Error(\"No determiamos la causa del error\") -> si ejecuto esta linea de codigo, manda un erro generico\n            throw new StrTypeError()\n        }\n\n        console.log(params)\n        console.log(params[0] / params[1])\n        console.log(params[2] + 5)\n    }\n    try{\n        process_param([1,2,3,4])\n    }\n    catch(e){\n        if (e instanceof RangeError) {\n            console.error(\"Se ha productido el error: \", e.name, \"->\", e.message)\n        } else if (e instanceof DivisionByZeroError) {\n            console.error(\"Se ha productido el error: \", e.name, \"->\", e.message)\n        } else if (e instanceof StrTypeError){ // no esta funcionando debido a que debia cargar un error generico\n            console.error(\"Se ha productido el error: \", e.name, \"->\", e.message)\n        } else if (e instanceof Error) {\n            console.error(\"Se ha productido un error inesperado: \", e)\n        }\n    }\n    finally{\n        console.log(\"El programa ha finalizado\")\n    }\n}\n\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/typescript/miguelex.ts",
    "content": "\nfunction division(a: number, b: number): string {\n    try {\n        if (b === 0) {\n            throw new Error(\"No se puede dividir por cero\");\n        }\n        return (a / b).toString();\n    } catch (error) {\n        return error.message;\n    }\n}\n\nconsole.log(division(10, 0));\nconsole.log(division(5, 3));\n\nfunction outOfRange(lista: any[], indice: number): string {\n    try {\n        if (indice < 0 || indice >= lista.length) {\n            throw new Error(\"Índice fuera de rango\");\n        }\n        return lista[indice];\n    } catch (error) {\n        return error.message;\n    }\n}\n\nconsole.log(outOfRange([1, 2, 3], 5));\n\nclass MiError extends Error {\n    valor: any;\n\n    constructor(valor: any) {\n        super();\n        this.valor = valor;\n    }\n\n    toString(): string {\n        return \"Error: \" + this.valor;\n    }\n}\n\nfunction extra(a: string, b: number, c: string): string {\n    if (typeof a !== \"string\" || a.length === 0) {\n        throw new Error(\"El primer parametro debe ser un string y no vacio\");\n    }\n    if (typeof b !== \"number\" || b <= 0) {\n        throw new Error(\"El segundo parametro debe ser un entero y mayor que 0\");\n    }\n    if (typeof c !== \"string\") {\n        throw new Error(\"El tercer parametro debe ser un string\");\n    }\n    if (c === \"Mouredev\") {\n        throw new MiError(\"El tercer parametro no puede ser Mouredev\");\n    }\n    return `Solucion reto ${b} - ${a} del usuario ${c}`;\n}\n\ntry {\n    //console.log(extra(\"Swift\", 10, \"Mouredev\"));\n    console.log(extra(\"TypeScript\", 10, \"Miguelex\"));\n    //console.log(extra(\"PHP\", -5, \"Miguelex\"));\n    //console.log(extra(\"\", 10, \"Miguelex\"));\n} catch (error) {\n    console.log(error instanceof MiError ? error.toString() : error.message);\n} finally {\n    console.log(\"Todo ha ido bien\");\n}\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/typescript/nlarrea.ts",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de manejo de excepciones según tu lenguaje.\n * Fuerza un error en tu código, captura el error, imprime dicho error\n * y evita que el programa se detenga de manera inesperada.\n * Prueba a dividir \"10/0\" o acceder a un índice no existente\n * de un listado para intentar provocar un error.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado. \n */\n\n\nconst months: string[] = [\n    'January',\n    'February',\n    'March',\n    'April',\n    'May',\n    'June',\n    'July',\n    'August',\n    'September',\n    'October',\n    'November',\n    'December',\n]\n\n\ntry {\n    const wrongResult: number = 10 / 0\n    if (wrongResult === Infinity) {\n        throw new Error('You can\\'t divide by zero!')\n    }\n\n    const myMonth: string = months[12]\n    if (myMonth === undefined) {\n        throw new Error('You tried to access an item out of index.')\n    }\n} catch (error) {\n    console.error(error)\n}\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea una función que sea capaz de procesar parámetros, pero que también\n * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n * corresponderse con un tipo de excepción creada por nosotros de manera\n * personalizada, y debe ser lanzada de manera manual) en caso de error.\n * - Captura todas las excepciones desde el lugar donde llamas a la función.\n * - Imprime el tipo de error.\n * - Imprime si no se ha producido ningún error.\n * - Imprime que la ejecución ha finalizado. \n */\n\n\nclass UnknownTypeError extends Error {\n    constructor(message: string) {\n        super(message)\n        this.name = 'UnknownTypeError'\n    }\n}\n\n\nfunction processParams(...params: any) {\n    const knownTypes: string[] = [\n        'number',\n        'string',\n        'array'\n    ]\n\n    for (const param of params) {\n        if (!knownTypes.includes(typeof param)) {\n            throw new UnknownTypeError(\n                'I don\\'t know about this type of data.'\n            )\n        }\n\n        if (typeof param === 'string' && param.length < 10) {\n            throw new SyntaxError('The length of the string is too short.')\n        }\n\n        if (typeof param === 'number' && param < 5) {\n            throw new RangeError('The number must be positive and greater than 5.')\n        }\n    }\n}\n\n\ntry {\n    processParams(\n        3.14,\n        true,\n        'short',\n        [1, 2, 3]\n    )\n} catch (error) {\n    console.error(error)\n}"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/typescript/qwik-zgheib.ts",
    "content": "/* -- exercise */\ntry {\n  let result: number = 10 / 0;\n  console.log(\"Result:\", result);\n} catch (error) {\n  console.error(\"Error:\", (error as Error).message);\n} finally {\n  console.log(\"Finished\");\n}\n\ntry {\n  let list: number[] = [1, 2, 3];\n  console.log(list[5]);\n} catch (error) {\n  console.error(\"Error:\", (error as Error).message);\n} finally {\n  console.log(\"Finished\");\n}\n\n/* -- extra challenge */\nfunction processParameters(parameter: any): void {\n  try {\n    if (typeof parameter !== \"number\") throw new TypeError(\"Parameter must be a number\");\n\n    if (parameter === 0) throw new RangeError(\"Parameter cannot be zero\");\n\n    throw new Error(\"This is a custom error\");\n  } catch (error) {\n    console.error(\"Error:\", (error as Error).message);\n  } finally {\n    console.log(\"Finished\");\n  }\n}\n\nconsole.log(\"\\nProcessing parameters:\");\nprocessParameters(5);\nprocessParameters(0);\nprocessParameters(\"text\");\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/typescript/victor-Casta.ts",
    "content": "/*\n  * EJERCICIO:\n  * Explora el concepto de manejo de excepciones según tu lenguaje.\n  * Fuerza un error en tu código, captura el error, imprime dicho error\n  * y evita que el programa se detenga de manera inesperada.\n  * Prueba a dividir \"10/0\" o acceder a un índice no existente\n  * de un listado para intentar provocar un error.\n*/\n\ntry {\n  console.log(number[3])\n} catch (err) {\n  console.error(err)\n}\n\nconsole.log(`Fuera de la exepción`)\n\n\n/*\n  * DIFICULTAD EXTRA (opcional):\n  * Crea una función que sea capaz de procesar parámetros, pero que también\n  * pueda lanzar 3 tipos diferentes de excepciones (una de ellas tiene que\n  * corresponderse con un tipo de excepción creada por nosotros de manera\n  * personalizada, y debe ser lanzada de manera manual) en caso de error.\n  * - Captura todas las excepciones desde el lugar donde llamas a la función.\n  * - Imprime el tipo de error.\n  * - Imprime si no se ha producido ningún error.\n  * - Imprime que la ejecución ha finalizado.\n*/\n\nclass MyError extends Error {\n  constructor(message: string) {\n    super(message)\n    this.name = this.constructor.name\n  }\n}\n\nfunction process(param1: number): void {\n  try {\n    if (typeof param1 === 'string') {\n      throw new TypeError('El tipo de dato no puede ser un string')\n    }\n\n    if (param1 > 10) {\n      throw new RangeError('El numero no puede ser mayor que 10')\n    }\n\n    if (param1 === 7) {\n      throw new MyError('El numero no ouede ser igual a 7')\n    }\n\n    console.log('No se han producido errores')\n  } catch (error) {\n    console.error('Tipo de error:', error.constructor.name)\n    console.error('Mensaje de error:', error.message)\n  } finally {\n    console.log('la ejecución ha finalizado')\n  }\n}\n\nprocess(7)"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/typescript/victoriaparraf.ts",
    "content": "//MANEJO DE EXCEPCIONES\nfunction manejarErrores(): void {\n    try {\n        // Forzando una división por cero\n        let resultado = dividir(10, 0);\n        console.log(`Resultado de la división: ${resultado}`);\n    } catch (error) {\n        console.error(`Error capturado: ${error.message}`);\n    } finally {\n        console.log(\"Bloque finally ejecutado después de intentar dividir.\");\n    }\n\n    try {\n        // Acceso a un índice no existente en un array\n        let lista = [1, 2, 3];\n        let elemento = accederIndice(lista, 5);\n        console.log(`Elemento en el índice 5: ${elemento}`);\n    } catch (error) {\n        console.error(`Error capturado: ${error.message}`);\n    } finally {\n        console.log(\"Bloque finally ejecutado después de intentar acceder a un índice.\");\n    }\n}\n\nfunction dividir(a: number, b: number): number {\n    if (b === 0) {\n        throw new Error(\"División por cero no permitida.\");\n    }\n    return a / b;\n}\n\nfunction accederIndice(array: number[], index: number): number {\n    if (index < 0 || index >= array.length) {\n        throw new Error(\"Índice fuera de los límites del array.\");\n    }\n    return array[index];\n}\n\n// Ejecutar el manejo de errores\nmanejarErrores();\n\n\n"
  },
  {
    "path": "Roadmap/10 - EXCEPCIONES/vb.net/kenysdev.vb",
    "content": "' ╔═════════════════════════════════════╗\n' ║ Autor:  Kenys Alvarado              ║\n' ║ GitHub: https://github.com/Kenysdev ║\n' ║ 2024 -  VB.NET                      ║\n' ╚═════════════════════════════════════╝\n'-----------------------------------------------\n'EXCEPCIONES\n'-----------------------------------------------\n'- Representan una forma de controlar el comportamiento de un programa\n'cuando se produce un error.\nModule Program\n    Sub Main()\n        Dim a As Integer = 7\n        Dim b As Integer = 0\n\n        ' Capturar excepción\n        Try\n            Dim r As Integer = a / b\n        Catch ex As System.ArithmeticException\n            Console.WriteLine(\"Error de división por cero\")\n        End Try\n\n        ' Cuando se desconoce el tipo de excepción\n        Dim myList() As Integer = {1, 2, 3}\n        Try\n            Console.WriteLine(myList(7))\n        Catch ex As Exception\n            Console.WriteLine(\"Excepción\")\n        End Try\n\n        ' Saber qué excepción ha ocurrido\n        Try\n            Dim r As Integer = Integer.Parse(\"uno\") + 2\n        Catch ex As Exception\n            Console.WriteLine($\"Excepción: {ex.GetType()}\")\n        End Try\n\n        ' Capturar diferentes excepciones\n        Try\n            'Dim r As Integer = Integer.Parse(\"uno\") + 2\n            Dim r As String = 7 + \"txt\"\n        Catch ex As FormatException\n            Console.WriteLine(\"Error al convertir\")\n        Catch ex As Exception\n            Console.WriteLine(\"Error de tipos\")\n        End Try\n\n        ' Uso de finally\n        ' Se ejecuta siempre, haya o no una excepción.\n        Try\n            Dim r As Double = a \\ b\n        Catch ex As Exception\n            Console.WriteLine(\"Excepción\")\n        Finally\n            Console.WriteLine(\"Bloque finally\")\n        End Try\n\n        ' Uso de throw para ejecutar una excepción\n        'Throw New DivideByZeroException(\"Error de división\")\n        'Throw New IndexOutOfRangeException()\n        'Throw New InvalidCastException(\"..\")\n\n        ' Definiendo excepcion personalizada\n        Try\n            Throw New CustomException(\"Mensaje de error personalizado\")\n        Catch ex As CustomException\n            Console.WriteLine($\"Excepción personalizada: {ex.Message}\")\n        End Try\n\n        ' Ejercicio\n        Console.WriteLine(vbCrLf & \"___________\" & vbCrLf & \"Ejercicio:\")\n        Operation(10, \"uno\")\n        Operation(10, 0)\n        Operation(10, 5)\n        Operation(10, 2)\n    End Sub\n\n    Sub Division(a As Integer, b As Integer)\n        If b Mod 2 <> 0 Then\n            Throw New OddNumberError()\n        Else\n            Dim r As Integer = a / b\n            Console.WriteLine($\"{vbCrLf}- El resultado es: {r}\")\n        End If\n    End Sub\n\n    Sub Operation(a As Integer, b As Object)\n        Try\n            Division(a, CInt(b))\n            Console.WriteLine(\"- No hubo errores.\")\n        Catch ex As InvalidCastException\n            Console.WriteLine($\"{vbCrLf}Error: No se permite texto. -> {ex.GetType()}\")\n        Catch ex As System.ArithmeticException\n            Console.WriteLine($\"{vbCrLf}Error: No es posible dividir entre 0. -> {ex.GetType()}\")\n        Catch ex As OddNumberError\n            Console.WriteLine($\"{vbCrLf}Error: no dividir entre impares. -> {ex.GetType()}\")\n        Finally\n            Console.WriteLine(\"- Operación terminada.\")\n        End Try\n    End Sub\nEnd Module\n' Heredar clase \nClass CustomException\n    Inherits Exception\n    Sub New(message As String)\n        MyBase.New(message)\n    End Sub\nEnd Class\n\nClass OddNumberError\n    Inherits Exception\n    Sub New()\n        MyBase.New()\n    End Sub\nEnd Class\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/bash/h4ckxel.sh",
    "content": "#!/bin/bash\n\n# Crear archivo con información personal\nfunction crear_archivo() {\n    file=\"h4ckxel.txt\"\n    f=(\"Me llamo H4ckxel\" \"Mi edad es de 23 años\" \"Mi lenguaje de programacion favorito es Python/Bash\")\n    printf \"%s\\n\" \"${f[@]}\" > \"$file\"    \n    echo -e \"\\nEl archivo h4ckxel.txt ha sido creado\\n\"\n}\n\n# Leer el contenido del archivo\nfunction leer_archivo() {\n    cat \"h4ckxel.txt\"\n}\n\n# Borrar archivo\nfunction borrar_archivo() { \n    if [ -e \"h4ckxel.txt\" ]; then\n        rm \"h4ckxel.txt\"\n        echo -e \"\\nEl archivo 'h4ckxel.txt' ha sido eliminado\\n\"\n    else\n        echo -e \"\\nEl archivo no existe\\n\"\n    fi\n}\n\ncrear_archivo\nleer_archivo\nborrar_archivo\n\n# Parte extra: Gestión de ventas\nstore=\"sales.txt\"\n\n# Añadir producto\nfunction add_product() {\n    read -p \"Nombre: \" name \n    read -p \"Cantidad vendida: \" quantity\n    read -p \"Precio: \" price\n    echo \"$name, $quantity, $price\" >> \"$store\"\n}\n\n# Consultar producto\nfunction consult_product() {\n    read -p \"Nombre: \" name\n    grep -i \"^$name,\" \"$store\" || echo \"Producto no encontrado\"\n}\n\n# Eliminar producto\nfunction delete_product() {\n    read -p \"Nombre: \" name\n    sed -i \"/^$name,/d\" \"$store\"\n}\n\n# Actualizar producto\nfunction update_product() {\n    delete_product\n    add_product \n}\n\n# Leer archivo completo\nfunction read_file() {\n    cat \"$store\"\n}\n\n# Calcular ventas por producto\nfunction product_sales() {\n    total=0\n    read -p \"Nombre: \" name\n    while IFS=, read -r prod quantity price; do\n        if [[ \"$prod\" == \"$name\" ]]; then\n            total=$(echo \"$quantity * $price\" | bc)\n            echo -e \"\\nEl total de las ventas de $name es: $total\\n\"\n            return\n        fi\n    done < \"$store\"\n    echo \"Producto no encontrado\"\n}\n\n# Calcular ventas totales\nfunction total_sales() {\n    total=0\n    while IFS=, read -r _ quantity price; do\n        total=$(echo \"$total + $quantity * $price\" | bc)\n    done < \"$store\"\n    echo -e \"\\nEl total de las ventas es: $total\\n\"\n}\n\n# Salir y borrar archivo de ventas\nfunction exit_program() {\n    rm -f \"$store\"\n    echo -e \"[!] Archivo 'sales.txt' eliminado. Saliendo del programa...\\n\"\n}\n\n# Menú de opciones\nwhile true; do\n    echo -e \"\\n--- Menú de gestión de ventas ---\"\n    echo \"1) Añadir producto\"\n    echo \"2) Consultar producto\"\n    echo \"3) Eliminar producto\"\n    echo \"4) Actualizar producto\"\n    echo \"5) Consultar archivo completo\"\n    echo \"6) Calcular ventas por producto\"\n    echo \"7) Calcular ventas totales\"\n    echo \"8) Salir\"\n    \n    read -p \"Elige una opción: \" option\n    \n    case $option in\n        1) add_product ;;\n        2) consult_product ;;\n        3) delete_product ;;\n        4) update_product ;;\n        5) read_file ;;\n        6) product_sales ;;\n        7) total_sales ;;\n        8) exit_program; break ;;\n        *) echo \"Opción no válida, intenta de nuevo\" ;;\n    esac\ndone\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/bash/rantamhack.sh",
    "content": "#!/bin/bash\n\n# * IMPORTANTE: Solo debes subir el fichero de codigo como parte del ejercicio.\n# * \n# * EJERCICIO:\n# * Desarrolla un programa capaz de crear un archivo que se llame como\n# * tu usuario de GitHub y tenga la extension .txt.\n# * Añade varias lineas en ese fichero:\n# * - Tu nombre.\n# * - Edad.\n# * - Lenguaje de programacion favorito.\n# * Imprime el contenido.\n# * Borra el fichero.\n\nfunction crear_archivo() {\n\n    file=\"rantamhack.txt\"\n    f=(\"Me llamo Rantam\" \"Mi edad es de 25 años\" \"Mi lenguaje de programacion favorito es bash\")\n    printf \"%s\\n\" \"${f[@]}\" > \"$file\"    \n    echo -e \"\\nEl archivo rantamhack.txt ha sido creado\\n\"\n\n}    \ncrear_archivo\n\nfunction leer_archivo() {\n\n    file=\"rantamhack.txt\"\n    cat $file\n    \n}\nleer_archivo\n\nfunction borrar_archivo() { \n    if [ -e \"rantamhack.txt\" ]; then\n        rm rantamhack.txt\n        echo -e \"\\nEl archivo 'rantamhack.txt' ha sido eliminado\\n\\n\"\n    else\n        echo -e \"\\nEl archivo no existe\\n\"\n    fi\n}\n        \nborrar_archivo\n\n\n# * DIFICULTAD EXTRA (opcional):\n# * Desarrolla un programa de gestion de ventas que almacena sus datos en un \n# * archivo .txt.\n# * - Cada producto se guarda en una linea del arhivo de la siguiente manera:\n# *   [nombre_producto], [cantidad_vendida], [precio].\n# * - Siguiendo ese formato, y mediante terminal, debe permitir aÃ±adir, consultar,\n# *   actualizar, eliminar productos y salir.\n# * - Tambien debe poseer opciones para calcular la venta total y por producto.\n# * - La opcion salir borra el .txt.\n\n\n\nstore=\"sales.txt\"\n\nfunction add_product() {\n\n    read -p \"Nombre: \" name \n    read -p \"Cantidad vendida: \" quantity\n    read -p \"Precio: \" price\n\n    echo  \"$name, $quantity, $price\" >> $store\n\n}\n\n\nfunction consult_product() {\n\n    read -p \"Nombre: \" name\n\n    while IFS= read -r line; do\n        if [[ $(echo \"$line\" | cut -d ',' -f1) == \"$name\" ]]; then\n            echo \"$line\"\n            break            \n        fi\n    done < \"$store\"\n}\n\n\nfunction delete_product() {\n    read -p \"Nombre: \" name\n    while IFS= read -r line; do\n        if [[ $(echo \"$line\" | cut -d',' -f1) != \"$name\" ]]; then\n            sed -i \"/^$name/d\" $store\n        fi\n    done < $store \n\n}\n\n\nfunction update_product() {\n\n    delete_product\n    add_product \n\n}\n\n\nfunction read_file() {\n    \n    cat $store\n\n}\n\n\nfunction product_sales() {\n    total=0\n    read -p \"Nombre: \" name\n\n    while IFS= read -r line; do\n        if [[ $(echo \"$line\" | cut -d ',' -f1) == \"$name\" ]]; then\n            quantity=$(echo \"$line\" | cut -d ',' -f2)\n            price=$(echo \"$line\" | cut -d ',' -f3)\n        fi\n        \n    done < $store\n\n    total=$(echo \"$quantity * $price\" | bc) \n    echo -e \"\\nEl total de las ventas de $name es: $total\\n\"\n}\n\n\nfunction total_sales() {\n    total=0\n    while IFS= read -r line; do\n        quantity=$(echo \"$line\" | cut -d ',' -f2)\n        price=$(echo \"$line\" | cut -d ',' -f3)\n        total=$(bc <<< \"$total + $quantity * $price\")\n    done < $store\n\n    echo -e \"\\nEl total de las ventas es: $total\\n\"\n\n}\n\nfunction exit() {\n\n    echo -e \"Borrando archivo sales.txt\"\n    rm \"sales.txt\"\n    echo -e \"[!] Saliendo del programa ... \\n\"\n\n}\n\n\necho -e \"\\nBienvenido al menu de opciones\\n\"\n\n    echo \"1) AÃ±adir producto\"\n    echo \"2) Consultar producto\"\n    echo \"3) Eliminar producto\"\n    echo \"4) Actualizar producto\"\n    echo \"5) Consultar archivo de productos\"\n    echo \"6) Calculadora de ventas por producto\"\n    echo \"7) Calculadora de ventas totales\"\n    echo \"8) Salir\"\n\nwhile true; do \n\n    read -p \"Elige la opcion que quieres utilizar: \" option\n\n    case $option in\n\n        [1]*) add_product; break;;\n        [2]*) consult_product; break;;\n        [3]*) delete_product; break;;\n        [4]*) update_product; break;;\n        [5]*) read_file; break;;\n        [6]*) product_sales; break;;\n        [7]*) total_sales; break;;\n        [8]*) exit; break;;\n\n    esac   \n\ndone\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/c/N0HagoNada.c",
    "content": "#include <stdio.h>\n#include <windows.h>\n/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n */\nvoid BorrarArchivo(const char *nombreArchivo);\nvoid LeerArchivo(const char *nombreArchivo);\n\nint main()\n{\n    HANDLE hFile;\n    DWORD dwBytesWritten = 0;\n    char data[] = \"Mi nombre es: john \\n Edad: 21 \\n Lenguaje de programción favorito: c\";\n    const char *nombreArchivo = \"N0HagoNada.txt\";\n    hFile = CreateFile(nombreArchivo, // Nombre del archivo\n                       GENERIC_WRITE, // Apertura para escritura\n                       0,\n                       NULL, // Atributos de seguridad predeterminados\n                       CREATE_ALWAYS,\n                       FILE_ATTRIBUTE_NORMAL,\n                       NULL);\n    if (hFile == INVALID_HANDLE_VALUE)\n    {\n        printf(\"Error al crear el archivo\\n\");\n        return 1;\n    }\n\n    // Escribir en el archivo\n    BOOL bErrorFlag = WriteFile(\n        hFile,           // Manejador del archivo\n        data,            // Buffer de datos a escribir\n        strlen(data),    // Número de bytes a escribir\n        &dwBytesWritten, // Número de bytes escritos\n        NULL);           // Sin operación de escritura superpuesta\n\n    if (FALSE == bErrorFlag)\n    {\n        printf(\"Error al escribir en el archivo\\n\");\n    }\n    else\n    {\n        if (dwBytesWritten != strlen(data))\n        {\n            // No se escribieron todos los bytes\n            printf(\"Error: no todos los bytes fueron escritos\\n\");\n        }\n        else\n        {\n            // Escritura exitosa\n            printf(\"Se escribieron %d bytes\\n\", dwBytesWritten);\n        }\n    }\n\n    CloseHandle(hFile);\n\n    LeerArchivo(nombreArchivo);\n\n    // Borrar el archivo.\n    BorrarArchivo(nombreArchivo);\n    return 0;\n}\n\nvoid BorrarArchivo(const char *nombreArchivo)\n{\n    BOOL bErrorFlag = DeleteFileA(nombreArchivo);\n\n    if (!bErrorFlag)\n    {\n        printf(\"No se puede borrar el archivo.\\n\");\n    }\n    else\n    {\n        printf(\"Archivo borrado exitosamente.\\n\");\n    }\n}\nvoid LeerArchivo(const char *nombreArchivo)\n{\n    HANDLE hFile;\n    DWORD dwBytesRead = 0;\n    char buffer[1024] = {0}; // Asumiendo que el archivo es menor que 1024 bytes para simplificar\n\n    hFile = CreateFile(nombreArchivo,\n                       GENERIC_READ,\n                       FILE_SHARE_READ,\n                       NULL,\n                       OPEN_EXISTING,\n                       FILE_ATTRIBUTE_NORMAL,\n                       NULL);\n\n    if (hFile == INVALID_HANDLE_VALUE)\n    {\n        printf(\"No se puede abrir el archivo para leer.\\n\");\n        return;\n    }\n\n    BOOL bErrorFlag = ReadFile(hFile, buffer, 1024, &dwBytesRead, NULL);\n\n    if (!bErrorFlag)\n    {\n        printf(\"No se puede leer el archivo.\\n\");\n    }\n    else\n    {\n        printf(\"Contenido del archivo:\\n%s\\n\", buffer);\n    }\n\n    CloseHandle(hFile);\n}"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/c#/Andreavzqz.cs",
    "content": "using System;\nusing System.IO;\nusing System.Linq;\n\nnamespace ArchivoYGestionDeVentas\n{\n\n    class Program\n    {\n\n        static void Main(string[] args)\n        {\n\n            //Parte 1: Crear, escribir, leer y eliminar un archivo\n            string fileName = \"Andreavzqz.txt\";\n            try\n            {\n\n                //Crear y escribir en el archivo\n                using (StreamWriter sw = new StreamWriter(fileName))\n                {\n                    sw.WriteLine(\"Nombre: Andrea\");\n                    sw.WriteLine(\"Edad: 30\");\n                    sw.WriteLine(\"Lenguaje de programacion favorito: C#\");\n                }\n\n                //Leer e imprimir el contenido del archivo\n                using(StreamReader sr = new StreamReader(fileName))\n                {\n                    string line;\n                    while ((line = sr.ReadLine()) != null)\n                    {\n                        console.WriteLine(line);\n                    }\n                }\n            }\n            finally\n            {\n                //Borrar el archivo\n                if (file.Exists(fileName))\n                {\n                    fileName.Delete(fileName);\n                }\n            }\n\n            //Parte 2: Programa de gestion de ventas\n            string ventasFileName = \"ventas.txt\";\n            bool continuar = true;\n\n            while (continuar)\n            {\n                Console.WriteLine(\"Seleccione una opción\");\n                Console.WriteLine(\"1. Añadir producto\");\n                Console.WriteLine(\"2. Consultar productos\");\n                Console.WriteLine(\"3. Actualizar producto\");\n                Console.WriteLine(\"4. Eliminar producto\");\n                Console.WriteLine(\"5. Calcular venta total\");\n                Console.WriteLine(\"6. Calcular venta por producto\");\n                Console.WriteLine(\"7. Salir\");\n\n                string opcion = Console.ReadLine();\n\n                switch (opcion)\n                {\n                    case \"1\":\n                        AñadirProducto(ventasFileName);\n                        break;\n                    case \"2\":\n                        ConsultarProductos(ventasFileName);\n                        break;\n                    case \"3\":\n                        ActualizarProducto(ventasFileName);\n                        break;\n                    case \"4\";\n                        EliminarProducto(ventasFileName);\n                        break;\n                    case \"5\":\n                        CalcularVentaTolal(ventasFileName);\n                        break;\n                    case \"7\":\n                        continuar = false;\n                        if (fileName.Exists(ventasFileName))\n                        {\n                            fileName.Delete(ventasFileName);\n                        }\n                        Console.WriteLine(\"Archivo eliminado y programa finalizado\");\n                        break;\n                    default:\n                        Console.WriteLine(\"Opción no valida. Intente nuevamnete.\");\n                        break;\n                }\n            }\n        }\n\n        static void AñadirProducto(string fileName)\n        {\n            Console.WriteLine(\"Ingrese el nombre del producto:\");\n            string nombre = Console.ReadLine();\n            Console.WriteLine(\"Ingrese la cantidad vendida:\");\n            int cantidad = int.Parse(Console.ReadLine());\n            Console.WriteLine(\"Inrese el precio:\");\n            decimal precio = decimal.Parse(Console.ReadLine());\n\n            using (StreamWriter sw = new StreamWriter(fileName, true))\n            {\n                sw.WriteLine($\"{nombre}, {cantidad}, {precio}\");\n            }\n        }\n\n        static void ConsultarProductos(string fileName)\n        {\n            if (fileName.Exists(fileName))\n            {\n                using (StreamReader sr = new StreamReader(fileName))\n                {\n                    string line;\n                    while ((line = sr.ReadLine()) != null)\n                    {\n                        console.WriteLine(line);\n                    }\n                }\n            }\n            else\n            {\n                Console.WriteLine(\"No hay productos para mostrar.\");\n            }\n        }\n\n        static void ActualizarProducto(string fileName)\n        {\n            Console.WriteLine(\"Ingrese el nombre del producto a actualizar:\");\n            string nombre = Console.ReadLine();\n            string[] lineas = File.ReadAllLines(fileName);\n            bool productoEncontrado = false;\n\n            for (int i = 0; i < lineas.Length; i++)\n            {\n                if (lineas[i].StarsWith(nombre + \",\"))\n                {\n                    Console.WriteLine(\"Ingrese la nueva cantidad vendida:\");\n                    int cantidad = int.Parse(Console.ReadLine());\n                    Console.WriteLine(\"Ingrese en nuevo precio:\");\n                    decimal precio = decimal.Parse(Console.ReadLine());\n\n                    lineas[i] = $\"{nombre}, {cantidad}, {precio}\";\n                    productoEncontrado = true;\n                    break;\n                }\n            }\n\n            if (productoEncontrado)\n            {\n                fileName.WriteAllLines(fileName, lineas);\n                Console.WriteLine(\"Producto actualizado.\");\n            }\n            else\n            {\n                Console.WriteLine(\"Producto no encontrado.\");\n            }\n        }\n\n        static void EliminarProducto(string fileName)\n        {\n            Console.WriteLine(\"Ingrese el nombre del producto a eliminar:\");\n            string nombre = Console.ReadLine();\n            string[] lineas = fileName.ReadAllLines(fileName);\n            string[] nuevasLineas = lineas.Where(line => !line.StarsWith(nombre + \",\")).ToArray();\n\n            if (nuevasLineas.Length != lineas.Length)\n            {\n                File.WriteAllLines(fileName, nuevasLineas);\n                Console.WriteLine(\"Producto eliminado.\");\n            }\n            else \n            {\n                Console.WriteLine(\"Producto no encontrado.\");\n            }\n        }\n\n        static void CalcularVentaTolal(string fileName)\n        {\n            if (fileName.Exists(fileName))\n            {\n                decimal ventaTotal = 0;\n                using (StreamReader sr = new StreamReader(fileName))\n                {\n                    string line;\n                    while ((line = sr.ReadLine()) !null)\n                    {\n                        var partes = line.Split(\",\");\n                        int cantidad = int.Parse(partes[1]);\n                        decimal precio = decimal.Parse(partes[2]);\n                        ventaTotal += cantidad * precio;\n                    }\n                }\n                Console.WriteLine($\"La venta total es: {ventaTotal}\");\n            }\n            else\n            {\n                Console.WriteLine(\"No hay productos para calcular.\");\n            }\n        }\n        static void ConsultarProductos(string fileName)\n        {\n            if (File.Exists(fileName))\n            {\n                Console.WriteLine(\"Ingrese el nombre del producto:\");\n                string nombre = Console.ReadLine();\n                decimal ventaTotal = 0;\n                bool productoEncontrado = false;\n\n                using (StreamReader sr = new StreamReader(fileName))\n                {\n                    string line;\n                    while ((line = srReadLine()) != null)\n                    {\n                        if (line.StarsWith(nombre + \",\"))\n                        {\n                            var partes = line.Split(\",\");\n                            int cantidad = int.Parse(partes[1]);\n                            decimal precio = decimal.Parse(partes[2]);\n                            ventaTotal += cantidad * precio;\n                            productoEncontrado = true;\n                        }\n                    }\n                }\n\n                if (productoEncontrado)\n                {\n                    Console.WriteLine($\"La venta total para {nombre} es: {ventaTotal}\");\n                }\n                else\n                {\n                    Console.WriteLine(\"Producto no encontrado.\");\n                }\n            }\n            else\n            {\n                Console.WriteLine(\"No hay productos para calcular.\");\n            }\n        }\n    }\n/*\n\n- Explicación\n\nParte 1:\nCrea un archivo llamado Andreavzqz.txt.\nEscribe el nombre, edad y lenguaje de programación favorito en el archivo.\nLee e imprime el contenido del archivo.\nBorra el archivo.\n\nParte 2:\nPrograma de gestión de ventas que permite añadir, consultar, actualizar, eliminar productos y calcular ventas.\nLas operaciones se realizan en un archivo llamado ventas.txt.\nLa opción salir borra el archivo ventas.txt.\n\nDetalles de las funciones\nAñadirProducto: Solicita información del producto y la añade al archivo.\nConsultarProductos: Lee e imprime todos los productos del archivo.\nActualizarProducto: Permite actualizar la información de un producto específico.\nEliminarProducto: Elimina un producto del archivo.\nCalcularVentaTotal: Calcula la venta total de todos los productos.\nCalcularVentaPorProducto: Calcula la venta total de un producto específico.\n*/\n\n}\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/c#/hequebo.cs",
    "content": "class Program\n{\n    static int id = 1;\n    static void Main(string[] args)\n    {\n        #region Ficheros\n        /* Cadena de texto con el nombre del archivo\n         * Al solo especificar el nombre del archivo se genera en bin\\Debug\\net8.0 \n         * dentro de la solución\n         */\n        string path = $\"hequebo.txt\";\n\n        // Creación del archivo\n\n        File.AppendAllText(path, \"Emilio\" + Environment.NewLine);\n        File.AppendAllText(path, \"27 años\" + Environment.NewLine);\n        File.AppendAllText(path, \"C#\" + Environment.NewLine);\n\n        // Lectura del archivo\n        string content = File.ReadAllText(path);\n        Console.WriteLine(content);\n\n        // Eliminación del archivo\n        Thread.Sleep(1000);\n        File.Delete(path);\n        Console.WriteLine(\"Se eliminó el archivo...\");\n        Console.ReadLine();\n        #endregion\n        List<Producto> venta = new List<Producto> ();\n        bool salir = false;\n        do\n        {\n            MostrarMenu();\n            string? opcion = Console.ReadLine();\n            switch (opcion.ToLower())\n            {\n\n                case \"a\":\n                    AgregarProducto(ref venta);\n                    break;\n                case \"b\":\n                    Consultar(venta);\n                    break;\n                case \"c\":\n                    ActualizarProducto(ref venta);\n                    break;\n                case \"d\":\n                    EliminarProducto(ref venta);\n                    break;\n                case \"e\":\n                    salir = true;\n                    Console.WriteLine(\"Hasta la próxima...\");\n                    Thread.Sleep(2000);\n                    break;\n                default:\n                    Console.WriteLine(\"Opción no válida...\");\n                    Thread.Sleep(2000);\n                    break;\n            }\n\n        } while (!salir);\n\n    }\n    static void MostrarMenu()\n    {\n        Console.WriteLine(\"----SISTEMA DE VENTAS----\");\n        Console.WriteLine(\"a.- Agregar  Producto.\");\n        Console.WriteLine(\"b.- Consultar Productos.\");\n        Console.WriteLine(\"c-- Actualizar Producto.\");\n        Console.WriteLine(\"d.- Eliminar Producto.\");\n        Console.WriteLine(\"e.- Terminar venta.\");\n        Console.WriteLine(\"Seleccione operación a realizar:\");\n\n    }\n    static void AgregarProducto(ref List<Producto> venta)\n    {\n        Console.Clear();\n        var producto = new Producto();\n        Console.WriteLine(\"Ingresa el nombre del producto\");\n        producto.Id = id;\n        producto.Nombre = Console.ReadLine();\n        producto.Cantidad = IngresarCantidad();\n        producto.PrecioUnitario = IngresarPrecio();\n        producto.Total = producto.Cantidad * producto.PrecioUnitario;\n\n        venta.Add(producto);\n        Console.WriteLine(\"Producto agregado correctamente\");\n        Console.WriteLine($\"{producto.Id}.- Producto: {producto.Nombre}, Cantidad: {producto.Cantidad}, \" +\n                $\"Precio: {producto.PrecioUnitario}, Total: {producto.Total}\");\n        id++;\n\n    }\n    static bool Consultar(List<Producto> venta)\n    {\n        Console.Clear();\n        if (venta.Count == 0) \n        {\n            Console.WriteLine(\"No hay productos registrados...\");\n            return false;\n        }\n        foreach (var item in venta)\n            Console.WriteLine($\"{item.Id}.- Producto: {item.Nombre}, Cantidad: {item.Cantidad}, \" +\n                $\"Precio: {item.PrecioUnitario}, Total: {item.Total}\");\n        return true;\n    }\n\n    static int IngresarCantidad()\n    {\n        int cantidad = 0;\n        bool esValido = false;\n        do\n        {\n            Console.WriteLine(\"Ingresa la cantidad vendida\");\n            int.TryParse(Console.ReadLine(), out cantidad);\n            if (cantidad != 0)\n                esValido = true;\n            else\n                Console.WriteLine(\"Cantidad no valida...\");\n        } while (!esValido);\n        return cantidad;\n    }\n    static decimal IngresarPrecio()\n    {\n        decimal precio = 0;\n        bool esValido = false;\n        do\n        {\n            Console.WriteLine(\"Ingresa el precio del producto\");\n            decimal.TryParse(Console.ReadLine(), out precio);\n            if (precio != 0)\n                esValido = true;\n            else\n                Console.WriteLine(\"Precio no válido...\");\n        } while (!esValido);\n        return precio;\n    }\n    static void ActualizarProducto(ref List<Producto> venta)\n    {\n        if (!Consultar(venta))\n        {\n            return;\n        }\n        Console.WriteLine(\"Ingresa id de Producto a actualizar\");\n        int id = IngresarId();\n        if (BuscarPorId(id, venta) == 0)\n        {\n            Console.WriteLine($\"No existe el producto con Id {id}...\");\n            return;\n        }\n        var producto = venta.FirstOrDefault(p => p.Id == id);\n        Console.WriteLine(\"Ingresa nombre del producto\");\n        producto.Nombre = Console.ReadLine();\n        producto.Cantidad = IngresarCantidad();\n        producto.PrecioUnitario = IngresarPrecio();\n        producto.Total = producto.Cantidad * producto.PrecioUnitario;\n        Console.WriteLine(\"Producto actualizado correctamente\");\n        Console.WriteLine($\"{producto.Id}.- Producto: {producto.Nombre}, Cantidad: {producto.Cantidad}, \" +\n                $\"Precio: {producto.PrecioUnitario}, Total: {producto.Total}\");\n    }\n    static int IngresarId()\n    {\n        bool esValido = false;\n        int id;\n        do\n        {\n            id = 0;\n            int.TryParse(Console.ReadLine(), out id);\n            if (id != 0)\n                esValido = true;\n            else\n                Console.WriteLine(\"Id no válido...\");\n\n        } while (!esValido);\n\n        return id;\n    }\n    static int BuscarPorId(int id, List<Producto> venta)\n    {\n        return venta.Select(p => p.Id == id).Count();\n    }\n    static void EliminarProducto(ref List<Producto> venta)\n    {\n        if (!Consultar(venta))\n            return;\n        Console.WriteLine(\"Ingresa id de Producto a eliminar\");\n        int id = IngresarId();\n        if (BuscarPorId(id, venta) == 0)\n        {\n            Console.WriteLine($\"No existe el producto con Id {id}...\");\n            return;\n        }\n        var producto = venta.FirstOrDefault(p => p.Id == id);\n        venta.Remove(producto);\n        Console.WriteLine(\"Producto eliminado correctamente\");\n    }\n}\nclass Producto\n{\n    public int Id { get; set; }\n    public string? Nombre { get; set; }\n    public int Cantidad { get; set; }\n    public decimal PrecioUnitario { get; set; }\n    public decimal Total {  get; set; }\n\n}\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/c#/isaacus98.cs",
    "content": "﻿/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n * archivo .txt.\n * - Cada producto se guarda en una línea del arhivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n */\n\nnamespace Roadmap\n{\n    internal class Reto10\n    {\n        static void Main(string[] args)\n        {\n            FileStream file = new(@\"C:\\Users\\\" + Environment.UserName + @\"\\Desktop\\isaacus98.txt\", FileMode.Create);\n            StreamWriter writer = new(file);\n            writer.WriteLine(\"Isaac Morcillo Garcia\");\n            writer.WriteLine(\"26\");\n            writer.WriteLine(\"C#\");\n            writer.Close();\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/c#/jamerrq.cs",
    "content": "/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un\n * archivo .txt.\n * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n */\n\nusing System;\n\nnamespace Roadmap11\n{\n    class ExtraExercise {\n\n        /*\n            * Init method: create the file `ventas.txt` if it doesn't exist\n            * we also print the menu\n        */\n        public static void Init() {\n            string path = \"ventas.txt\";\n            if (!System.IO.File.Exists(path)) {\n                System.IO.File.Create(path);\n            }\n            PrintMenu();\n        }\n\n        /*\n            * PrintMenu method: print the menu\n        */\n        public static void PrintMenu() {\n            Console.WriteLine(\"1. Añadir producto\");\n            Console.WriteLine(\"2. Consultar producto\");\n            Console.WriteLine(\"3. Actualizar producto\");\n            Console.WriteLine(\"4. Eliminar producto\");\n            Console.WriteLine(\"5. Venta total\");\n            Console.WriteLine(\"6. Venta por producto\");\n            Console.WriteLine(\"7. Salir\");\n            Console.WriteLine(\"Seleccione una opción: \");\n            int option = Convert.ToInt32(Console.ReadLine());\n            HandleOption(option);\n        }\n\n        /*\n            * HandleOption method: handle the option selected by the user\n            * @param option: the option selected by the user\n        */\n        public static void HandleOption(int option) {\n            switch (option) {\n                case 1:\n                    AddProduct();\n                    break;\n                case 2:\n                    GetProduct();\n                    break;\n                case 3:\n                    UpdateProduct();\n                    break;\n                case 4:\n                    DeleteProduct();\n                    break;\n                case 5:\n                    TotalSale();\n                    break;\n                case 6:\n                    SaleByProduct();\n                    break;\n                case 7:\n                    DeleteFile();\n                    break;\n                default:\n                    Console.WriteLine(\"Opción no válida.\");\n                    break;\n            }\n        }\n\n        /*\n            * AddProduct method: add a product to the file\n        */\n        public static void AddProduct() {\n            Console.WriteLine(\"Ingrese el nombre del producto: \");\n            string name = Console.ReadLine();\n            Console.WriteLine(\"Ingrese la cantidad vendida: \");\n            int quantity = Convert.ToInt32(Console.ReadLine());\n            Console.WriteLine(\"Ingrese el precio: \");\n            double price = Convert.ToDouble(Console.ReadLine());\n            string path = \"ventas.txt\";\n            string line = $\"{name}, {quantity}, {price}\";\n            System.IO.File.AppendAllText(path, line);\n            Console.WriteLine(\"Producto añadido.\");\n            PrintMenu();\n        }\n\n        /*\n            * GetProduct method: get a product from the file\n        */\n        public static void GetProduct() {\n            Console.WriteLine(\"Ingrese el nombre del producto: \");\n            string name = Console.ReadLine();\n            string path = \"ventas.txt\";\n            string[] lines = System.IO.File.ReadAllLines(path);\n            foreach (string line in lines) {\n                string[] data = line.Split(\",\");\n                if (data[0].Trim() == name) {\n                    Console.WriteLine($\"Producto: {data[0]}\");\n                    Console.WriteLine($\"Cantidad vendida: {data[1]}\");\n                    Console.WriteLine($\"Precio: {data[2]}\");\n                    return;\n                }\n            }\n            Console.WriteLine(\"Producto no encontrado.\");\n            PrintMenu();\n        }\n\n        /*\n            * UpdateProduct method: update a product from the file\n        */\n        public static void UpdateProduct() {\n            Console.WriteLine(\"Ingrese el nombre del producto: \");\n            string name = Console.ReadLine();\n            string path = \"ventas.txt\";\n            string[] lines = System.IO.File.ReadAllLines(path);\n            for (int i = 0; i < lines.Length; i++) {\n                string[] data = lines[i].Split(\",\");\n                if (data[0].Trim() == name) {\n                    Console.WriteLine(\"Ingrese la nueva cantidad vendida: \");\n                    int quantity = Convert.ToInt32(Console.ReadLine());\n                    Console.WriteLine(\"Ingrese el nuevo precio: \");\n                    double price = Convert.ToDouble(Console.ReadLine());\n                    lines[i] = $\"{name}, {quantity}, {price}\";\n                    System.IO.File.WriteAllLines(path, lines);\n                    Console.WriteLine(\"Producto actualizado.\");\n                    PrintMenu();\n                    return;\n                }\n            }\n            Console.WriteLine(\"Producto no encontrado.\");\n            PrintMenu();\n        }\n\n        /*\n            * DeleteProduct method: delete a product from the file\n        */\n        public static void DeleteProduct() {\n            Console.WriteLine(\"Ingrese el nombre del producto: \");\n            string name = Console.ReadLine();\n            string path = \"ventas.txt\";\n            string[] lines = System.IO.File.ReadAllLines(path);\n            for (int i = 0; i < lines.Length; i++) {\n                string[] data = lines[i].Split(\",\");\n                if (data[0].Trim() == name) {\n                    lines[i] = \"\";\n                    System.IO.File.WriteAllLines(path, lines);\n                    Console.WriteLine(\"Producto eliminado.\");\n                    PrintMenu();\n                    return;\n                }\n            }\n            Console.WriteLine(\"Producto no encontrado.\");\n            PrintMenu();\n        }\n\n        /*\n            * TotalSale method: calculate the total sale\n        */\n        public static void TotalSale() {\n            string path = \"ventas.txt\";\n            string[] lines = System.IO.File.ReadAllLines(path);\n            double total = 0;\n            foreach (string line in lines) {\n                string[] data = line.Split(\",\");\n                total += Convert.ToInt32(data[1]) * Convert.ToDouble(data[2]);\n            }\n            Console.WriteLine($\"Venta total: {total}\");\n            PrintMenu();\n        }\n\n        /*\n            * SaleByProduct method: calculate the sale by product\n        */\n        public static void SaleByProduct() {\n            Console.WriteLine(\"Ingrese el nombre del producto: \");\n            string name = Console.ReadLine();\n            string path = \"ventas.txt\";\n            string[] lines = System.IO.File.ReadAllLines(path);\n            foreach (string line in lines) {\n                string[] data = line.Split(\",\");\n                if (data[0].Trim() == name) {\n                    double total = Convert.ToInt32(data[1]) * Convert.ToDouble(data[2]);\n                    Console.WriteLine($\"Venta por producto: {total}\");\n                    PrintMenu();\n                    return;\n                }\n            }\n            Console.WriteLine(\"Producto no encontrado.\");\n            PrintMenu();\n        }\n\n        /*\n            * DeleteFile method: delete the file `ventas.txt`\n        */\n        public static void DeleteFile() {\n            string path = \"ventas.txt\";\n            System.IO.File.Delete(path);\n            Console.WriteLine(\"Archivo eliminado.\");\n        }\n\n\n        public static void Main(string[] args) {\n            Init();\n        }\n    }\n    class FileManagement\n    {\n        public void CreateFile(string username)\n        {\n            string path = username + \".txt\";\n            string nombre = \"Jamer José\";\n            string edad = \"24\";\n            string lenguaje = \"TypeScript\";\n            string[] lines = {\n                $\"Nombre: {nombre}\",\n                $\"Edad: {edad}\",\n                $\"Lenguaje de programación favorito: {lenguaje}\"\n            };\n\n            System.IO.File.WriteAllLines(path, lines);\n        }\n\n        public void DeleteFile(string username)\n        {\n            string path = username + \".txt\";\n            System.IO.File.Delete(path);\n        }\n\n        static void Main(string[] args)\n        {\n            FileManagement fileManagement = new FileManagement();\n            string username = \"jamerrq\";\n\n            fileManagement.CreateFile(username);\n            Console.WriteLine($\"Archivo {username}.txt creado.\");\n\n            string path = username + \".txt\";\n            string[] lines = System.IO.File.ReadAllLines(path);\n\n            foreach (string line in lines)\n            {\n                Console.WriteLine(line);\n            }\n\n            fileManagement.DeleteFile(username);\n            Console.WriteLine($\"El archivo {username}.txt ha sido eliminado.\");\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/c#/kenysdev.cs",
    "content": "/*\n╔═══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado                ║\n║ GitHub: https://github.com/Kenysdev   ║\n║ 2024 -  C#                            ║\n╚═══════════════════════════════════════╝\n-----------------------------------------------\nMANEJO DE FICHEROS\n-----------------------------------------------\n\nFuente: https://imaginaformacion.com/tutoriales/manipulacion-archivos-c-sharp\n*/\nusing System;\nusing System.Diagnostics;\nusing System.IO;\n#pragma warning disable CA1050\npublic class Program {\n    public class FileMg(string path) {\n        public string Path { get; set; } = path;\n\n        public void CreateFile() {\n            try {\n                if (!File.Exists(Path)) {\n                    FileStream archivo = File.Create(Path);\n                    archivo.Close();\n                }\n            } catch (Exception ex) {\n                Console.WriteLine(\"Error->f.CreateFile->\" + ex.Message);\n            }\n        }\n\n        public void AppendLine(string line) {\n            try {\n                using StreamWriter writer = File.AppendText(Path);\n                writer.WriteLine(line);\n\n            } catch (Exception ex) {\n                Console.WriteLine(\"Error->f.AppendLine->\" + ex.Message);\n            }\n        }\n        public void WriteLines(List<string> lines) {\n            try {\n                File.WriteAllLines(Path, lines);\n\n            } catch (Exception ex) {\n                Console.WriteLine(\"Error->f.WriteLines->\" + ex.Message);\n            }\n        }\n\n        public List<string>? ReadLines() {\n            try {\n                List<string> lines = [.. File.ReadAllLines(Path)];\n                return lines;\n\n            } catch (Exception ex) {\n                Console.WriteLine(\"Error->f.ReadLines->\" + ex.Message);\n                return null;\n            }\n        }\n\n        public void Print() {\n            try {\n                string[] lines = File.ReadAllLines(Path);\n                foreach (string line in lines) {\n                    Console.WriteLine(line);\n                }\n            } catch (Exception ex) {\n                Console.WriteLine(\"Error->f.Print->\" + ex.Message);\n            }\n        }\n\n        public int QueryFile(string qry) {\n            try {\n                string[] lines = File.ReadAllLines(Path);\n                int i = 0;\n                foreach (string ln in lines) {\n                    string[] parts = ln.Split(',');\n                    string name = parts[0];\n                    if (name == $\"[{qry}]\") {\n                        Console.WriteLine(ln);\n                        return i;\n                    }\n                    i += 1;\n                }\n                Console.WriteLine(\"No existe.\");\n                return -1;\n                \n            } catch (Exception ex) {\n                Console.WriteLine(\"Error->QueryFile->\" + ex.Message);\n                return -1;\n            }\n        }        \n\n        public void DeleteFile() {\n            try {\n                File.Delete(Path);\n                Console.WriteLine(Path + \"-> Eliminado.\");\n\n            } catch (Exception ex) {\n                Console.WriteLine(\"Error->DeleteFile->\" + ex.Message);\n            }\n        }\n    }\n/*\n* Desarrolla un programa de gestión de ventas que almacena sus datos en un \n* archivo .txt.\n* - Cada producto se guarda en una línea del arhivo de la siguiente manera:\n*   [nombre_producto], [cantidad_vendida], [precio].\n* - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n*   actualizar, eliminar productos y salir.\n* - También debe poseer opciones para calcular la venta total y por producto.\n* - La opción salir borra el .txt.\n*/\n    const string PATH = \"sale_mgt.txt\";\n    const string MSG = @\"\n        Gestión de Ventas:\n╔═════════════════════════════════╗\n║ 1. Agregar        4. Editar     ║  \n║ 2. Consultar      5. Facturar   ║\n║ 3. Eliminar       6. salir.     ║\n╚═════════════════════════════════╝\n\";\n    static string AddProduct(\n    FileMg Sale, string? prod = \"\", string? qty = \"\", string? price = \"\") {\n        while (true) {\n            if (string.IsNullOrWhiteSpace(prod)) {\n                Console.WriteLine(\"Debe ingresar un nombre de producto.\");\n                Console.Write(\"Producto: \");\n                prod = Console.ReadLine();\n\n            } else if (string.IsNullOrWhiteSpace(qty) || !double.TryParse(qty, out _)) {\n                Console.WriteLine(\"Debe ingresar una cantidad.\");\n                Console.Write(\"Cantidad: \");\n                qty = Console.ReadLine();\n\n            } else if (string.IsNullOrWhiteSpace(price) || !double.TryParse(price, out _)) {\n                Console.WriteLine(\"Debe ingresar un precio.\");\n                Console.Write(\"Precio: \");\n                price = Console.ReadLine();\n\n            } else {\n                string line = $\"[{prod}], [{qty}], [{price}]\";\n                Sale.AppendLine(line);\n                Console.WriteLine(\"\\nGuardado\");\n                Console.WriteLine(MSG);\n                return $\"{line}\";\n            }\n        }\n    }\n\n    static void QueryProduct(FileMg Sale, string qry = \"\") {\n        if (qry.Length == 0) {\n            Console.WriteLine(\"\\nConsultar Producto.\");\n            Console.Write(\"Nombre: \");\n            qry = Console.ReadLine()!;\n        }\n        Sale.QueryFile(qry);\n    }\n\n    static void DeleteProduct(FileMg Sale, string qry = \"\") {\n        if (qry.Length == 0) {\n            Console.WriteLine(\"\\nEliminar Producto.\");\n            Console.Write(\"Nombre: \");\n            qry = Console.ReadLine()!;\n        }\n        int numLine = Sale.QueryFile(qry);\n        if (numLine != -1) {\n            List<string> products = [.. Sale.ReadLines()];\n            products.RemoveAt(numLine);\n            Sale.WriteLines(products);\n            Console.WriteLine(\"Producto eliminado\");\n        }\n    }\n\n    static void UpdateProduct(FileMg Sale, string qry = \"\") {\n        if (qry.Length == 0) {\n            Console.WriteLine(\"\\nEditar Producto.\");\n            Console.Write(\"Nombre: \");\n            qry = Console.ReadLine()!;\n        }\n        int numLine = Sale.QueryFile(qry);\n        if (numLine != -1) {\n            List<string> products = [.. Sale.ReadLines()];\n            string line = AddProduct(Sale);\n            products[numLine] = line;\n            Sale.WriteLines(products);\n        }\n    }\n\n    static void Invoice(FileMg Sale) {\n        Console.WriteLine(\"\\nFactura\\n-------------------------\");\n        List<string> lines = Sale.ReadLines()!;\n        double total = 0;\n        foreach (string line in lines) {\n            var a = line.Split(',')[1].Trim();\n            double qty = double.Parse(a.Trim(' ', '[', ']'),\n            System.Globalization.CultureInfo.InvariantCulture);\n\n            var b = line.Split(',')[2].Trim();\n            double price = double.Parse(b.Trim(' ', '[', ']'),\n            System.Globalization.CultureInfo.InvariantCulture);\n\n            var ln = line.Trim('\\n');\n            double subTotal = qty * price;\n            string FsubTotal = $\"${subTotal:0.00}\";\n            Console.WriteLine($\"{ln} -> {FsubTotal}\");\n            total += subTotal;\n        }\n        Console.WriteLine($\"\\nMonto total: ${total:0.00}\");\n    }\n\n    //_________________________________\n    static void Main() {\n        FileMg user = new(\"kenysdev.txt\");\n        user.CreateFile();\n        List<string> lines = [\"Ken\", \"121\"];\n        user.WriteLines(lines);\n        user.AppendLine(\".py\");\n        user.Print();\n        user.DeleteFile();\n\n        //_________________________________\n        FileMg Sale = new(PATH);\n        Sale.CreateFile();\n        Console.WriteLine(MSG);\n\n        while (true) {\n            Console.Write(\"\\nOpción: \");\n            string option = Console.ReadLine()!;\n\n            switch (option) {\n                case \"1\": AddProduct(Sale); break;\n                case \"2\": QueryProduct(Sale); break;  \n                case \"3\": DeleteProduct(Sale); break;    \n                case \"4\": UpdateProduct(Sale); break;\n                case \"5\": Invoice(Sale); break;\n                case \"6\":\n                    Console.WriteLine(\"Adios\");\n                    Sale.DeleteFile(); \n                    return; \n                default:\n                    Console.WriteLine(\"Opción 1 -> 6\");\n                    break;\n            }\n        }\n    }\n}\n\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/c++/Fravelz.cpp",
    "content": "#include <iostream>\n#include <vector>\n#include <string>\n\n#include <fstream>\n#include <cstdio>\n\nusing namespace std;\n\nstruct Producto {\n    string name;\n    string amount;\n    string price;\n};\n\n// Solo guarda informacion, al finalizar el programa se borra el archivo..\nclass Productos { \nprivate:\n    vector<Producto> productos; \n    fstream archivo;\n    \n    bool indice_valido(unsigned int i) {\n        if (!(i < productos.size())) {\n            cout << \" [-] Numero de producto invalido.\";\n            return false;\n        }\n        return true;\n    }\n\n    void leer_archivo(string name, string amount, string price, string msg=\"\") {\n        ofstream archivo(\"fravelz_products.txt\", ios::app);\n\n        if (archivo.is_open()) {\n            archivo << \"\\n > \" << msg << \" ({\" << name << \", \" << amount << \", \" << price << \"})\";\n\n        } else {\n            cout << \"\\n [!] Error al escribir en el archivo.\";\n        }\n    }\n\npublic:\n    Productos(string name = \"\", string amount = \"\", string price = \"\") {\n          archivo.open(\"fravelz_products.txt\", ios::out | ios::app); \n\n        if (!archivo.is_open()) {\n        cout << \"\\nError: no se pudo abrir el archivo fravelz_products.txt\\n\";\n    }\n        if (name != \"\" && amount != \"\" && price != \"\") {\n            agregar(name, amount, price);\n        }\n    }\n\n    ~Productos() {\n        archivo.close();\n        remove(\"fravelz_products.txt\");\n    }\n\n\n    void agregar(string name, string amount, string price) {\n        productos.push_back({name, amount, price});\n        leer_archivo(name, amount, price, (\"Producto Nuevo: \"));\n    };\n\n    void consultar(unsigned int numero_producto = 0) {\n        if (!indice_valido(numero_producto)) return;\n\n        cout << \"\\n > Nombre:   \" << productos[numero_producto].name;\n        cout << \"\\n > Cantidad: \" << productos[numero_producto].amount;\n        cout << \"\\n > Precio:   \" << productos[numero_producto].price;\n\n    };\n\n    void actualizar(\n        unsigned int numero_producto, \n        string name = \"\", string amount = \"\", string price = \"\"\n    ) {\n        if (!indice_valido(numero_producto)) return;\n\n        if (!name.empty())   productos[numero_producto].name = name;\n        if (!amount.empty()) productos[numero_producto].amount = amount;\n        if (!price.empty())   productos[numero_producto].price = price;\n\n        leer_archivo(\n            productos[numero_producto].name,\n            productos[numero_producto].amount,\n            productos[numero_producto].price,\n            \"Producto Actualizado: \"\n        );\n    };\n\n    void eliminar(unsigned int numero_producto) {\n        if (!indice_valido(numero_producto)) return;\n\n        leer_archivo(\n            productos[numero_producto].name, \n            productos[numero_producto].amount,\n            productos[numero_producto].price,\n            \"[!] Producto Eliminado: \"\n        );\n\n        productos.erase(productos.begin() + numero_producto);\n    };\n};\n\n\nint main() {\n    fstream archivo(\"Fravelz.txt\", ios::out);\n\n    string contenido = \"Nombre: Francisco Velez\\nEdad: NULL \\n\";\n    contenido += \"Lenguaje favorito: C++\";\n\n    cout << contenido;\n    archivo << contenido;\n\n    archivo.close();\n\n    cout << \"\\n\\n > Enter para borrar archivo: \"; cin.ignore();\n    remove(\"Fravelz.txt\");\n\n    // *************** Ejercicio DIFICULTAD EXTRA *************** //\n\n    string data; Productos productos(\"\", \"\");\n    \n    while (data != \"5\") {\n        cout << \"\\n===============================================\";\n        cout << \"\\nGestion del Almacen: \";\n        cout << \"\\n\\t1. Agregar.\";\n        cout << \"\\n\\t2. Consultar.\";\n        cout << \"\\n\\t3. actualizar.\";\n        cout << \"\\n\\t4. Eliminar Productos.\";\n        cout << \"\\n\\t5. Salir.\";\n\n        cout << \"\\n\\n > \"; \n        cin >> data; cin.ignore();\n\n        if (data == \"1\") {\n            string name, amount, price;\n\n            cout << \"\\n > Nombre del producto: \"; getline(cin, name);\n            cout << \" > Cantidad del producto: \"; getline(cin, amount);\n            cout << \" > Precio del producto: \"; getline(cin, price);\n\n            productos.agregar(name, amount, price);\n\n        } else if (data == \"2\") {\n            unsigned int number;\n\n            cout << \"\\n > Numero del producto a consultar: \";\n            cin >> number; cin.ignore();\n\n            productos.consultar(number);\n\n        } else if (data == \"3\") {\n            unsigned int number;\n            string name, amount, price;\n\n            cout << \"\\n > Numero del producto a actualizar: \";\n            cin >> number; cin.ignore();\n\n            cout << \" (Deja vacío el campo si no quieres modificarlo)\\n\";\n\n            cout << \" > Nombre nuevo: \"; getline(cin, name);\n            cout << \" > Cantidad nueva: \"; getline(cin, amount);\n            cout << \" > Precio nuevo: \"; getline(cin, price);\n\n            productos.actualizar(number, name, amount, price);\n\n        } else if (data == \"4\") {\n            unsigned int number;\n\n            cout << \"\\n > Numero del producto a eliminar: \";\n            cin >> number; cin.ignore();\n\n            productos.eliminar(number);\n        }\n    }\n\n    cout << \"\\n\\n [+] Al dar enter el archivo sera borrado: \"; \n    cin.ignore();\n\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/c++/dylanb55.cpp",
    "content": "#include<iostream>\n#include<fstream>\n#include<cstdio>\nusing namespace std;\n\nvoid escritura(){\n\tofstream archivo;\n\tstring texto;\n\tarchivo.open(\"dylanb55.txt\",ios::out);\n\t\n\tcout << \"Ingrese su nombre: \" << endl;\n\tgetline(cin,texto);\n\t\n\tarchivo << \"Nombre: \" << texto << endl;\n\t\n\tcout << \"Ingrese su edad: \" << endl;\n\tgetline(cin,texto);\n\t\n\tarchivo << \"Edad: \" << texto << endl;\n\t\n\tcout << \"Ingrese su lenguaje de programacion favorito \" << endl;\n\tgetline(cin,texto);\n\t\n\tarchivo << \"Lenguaje de programacion favorito: \" << texto << endl;\n\t\n\tarchivo.close();\n}\n\nvoid lectura(){\n\tifstream archivo;\n\tstring texto;\n\t\n\tarchivo.open(\"dylanb55.txt\",ios::in);\n\t\n\tcout << \"\\nMostrando Informacion\\n\" << endl;\n\t\n\twhile(archivo.eof() != true){\n\t\tgetline(archivo,texto);\n\t\tcout << texto << endl;\n\t}\n\tarchivo.close();\n\t\n\tint eliminar = remove(\"dylanb55.txt\");\n\t\n\tif(eliminar != 0){\n\t\tcout << \"No se ha eliminado correctamente el fichero\" << endl;\n\t}\n\telse{\n\t\tcout << \"Fichero eliminado correctamente \" << endl;\n\t}\n\t\n}\n\nint main(){\n\tescritura();\n\tlectura();\n}\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/c++/hectorio23.cpp",
    "content": "#include <iostream>\n#include <fstream>\n#include <sstream>\n#include <string>\n#include <vector>\n#include <cstdlib>\n\n/*\n* IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n* \n* EJERCICIO:\n* Desarrolla un programa capaz de crear un archivo que se llame como\n* tu usuario de GitHub y tenga la extensión .txt.\n* Añade varias líneas en ese fichero:\n* - Tu nombre.\n* - Edad.\n* - Lenguaje de programación favorito.\n* Imprime el contenido.\n* Borra el fichero.\n*\n* DIFICULTAD EXTRA (opcional):\n* Desarrolla un programa de gestión de ventas que almacena sus datos en un \n* archivo .txt.\n* - Cada producto se guarda en una línea del arhivo de la siguiente manera:\n*   [nombre_producto], [cantidad_vendida], [precio].\n* - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n*   actualizar, eliminar productos y salir.\n* - También debe poseer opciones para calcular la venta total y por producto.\n* - La opción salir borra el .txt.\n*/\n\n\n// Const zone\nconst std::string nameFile = \"./hectorio23.txt\";\nconst std::string language = \"Python/C++\";\nconst std::string name = \"Héctor Adán\";\nconst int age = 19;\n\n\n// Definiciones de funciones\nvoid actualizarProducto(const std::string& nombre, int cantidad, float precio, std::ifstream& archivo, std::ofstream& temporal);\nvoid agregarProducto(std::ofstream& archivo, const std::string& nombre, int cantidad, float precio);\nvoid eliminarProducto(const std::string& nombre, std::ifstream& archivo, std::ofstream& temporal);\nfloat calcularVentaPorProducto(const std::string& nombre, std::ifstream& archivo);\nfloat calcularVentaTotal(std::ifstream& archivo);\nvoid consultarProductos(std::ifstream& archivo);\nvoid printFileValues();\nvoid writeFile();\nvoid salir();\n\nint main() {\n    // Antes de todo, hay que crear el archivo con los \n    // datos requeridos para la resolucion del ejercicio.  \n    std::cout << \"\\n EjERCICIO \\n\"; \n    std::cout << \"Creado el archivo hectorio23.txt e insertando datos\\n\";\n    writeFile();\n\n    // Ahora imprimimos los valores del Archivi .txt\n    std::cout << \"Imprimiendo los valores contenidos en el archivo hectorio23.txt\\n\";\n    printFileValues();\n\n    std::cout << \"\\n EjERCICIO EXTRA \\n\"; \n\n    std::ifstream archivoEntrada(\"ventas.txt\");\n    std::ofstream archivoSalida(\"temporal.txt\", std::ios::app);\n\n    int opcion;\n    std::string nombreProducto;\n    int cantidad;\n    float precio;\n\n    std::cout << \"===== Gestión de Ventas =====\" << std::endl;\n    std::cout << \"1. Añadir producto\" << std::endl;\n    std::cout << \"2. Consultar productos\" << std::endl;\n    std::cout << \"3. Actualizar producto\" << std::endl;\n    std::cout << \"4. Eliminar producto\" << std::endl;\n    std::cout << \"5. Calcular venta total\" << std::endl;\n    std::cout << \"6. Calcular venta por producto\" << std::endl;\n    std::cout << \"7. Salir\" << std::endl;\n    std::cout << \"Seleccione una opción: \";\n    std::cin >> opcion;\n\n    switch(opcion) {\n        case 1:\n            std::cout << \"Nombre del producto: \";\n            std::cin >> nombreProducto;\n            std::cout << \"Cantidad vendida: \";\n            std::cin >> cantidad;\n            std::cout << \"Precio: \";\n            std::cin >> precio;\n            agregarProducto(archivoSalida, nombreProducto, cantidad, precio);\n            break;\n        case 2:\n            consultarProductos(archivoEntrada);\n            break;\n        case 3:\n            std::cout << \"Nombre del producto a actualizar: \";\n            std::cin >> nombreProducto;\n            std::cout << \"Nueva cantidad vendida: \";\n            std::cin >> cantidad;\n            std::cout << \"Nuevo precio: \";\n            std::cin >> precio;\n            actualizarProducto(nombreProducto, cantidad, precio, archivoEntrada, archivoSalida);\n            break;\n        case 4:\n            std::cout << \"Nombre del producto a eliminar: \";\n            std::cin >> nombreProducto;\n            eliminarProducto(nombreProducto, archivoEntrada, archivoSalida);\n            break;\n        case 5:\n            std::cout << \"Venta total: $\" << calcularVentaTotal(archivoEntrada) << std::endl;\n            break;\n        case 6:\n            std::cout << \"Nombre del producto para calcular venta: \";\n            std::cin >> nombreProducto;\n            std::cout << \"Venta de \" << nombreProducto << \": $\" << calcularVentaPorProducto(nombreProducto, archivoEntrada) << std::endl;\n            break;\n        case 7:\n            salir();\n            break;\n        default:\n            std::cerr << \"Opción no válida\" << std::endl;\n            break;\n    }\n\n    archivoEntrada.close();\n    archivoSalida.close();\n    std::remove(\"ventas.txt\");\n    std::rename(\"temporal.txt\", \"ventas.txt\");\n\n    return EXIT_SUCCESS;\n}\n\n// Funcion qur imprime los valores en pantalla\nvoid printFileValues() {\n    // Se crea un objeto de tipo fstream el cual nos permitirá\n    // acceder a algunos metodos útiles para el manejo de archivos\n    //, es decir, Input Output en Archivos I/O\n    std::fstream myFile;\n\n    // Abre el archivo en modo lectura \n    myFile.open(nameFile, std::ios::in); \n    if (myFile.is_open()) {\n        std::string lines;\n        // Imprime todo el contenido del archivo por lineas\n        // de caracteres hasta que no haya más que imprimir \n        while (std::getline(myFile, lines)) {\n            std::cout << lines << \"\\n\";\n        }\n        myFile.close();\n    }\n}\n\nvoid writeFile() {\n    // Se crea un objeto de tipo fstream el cual nos permitirá\n    // acceder a algunos metodos útiles para el manejo de archivos\n    //, es decir, Input Output en Archivos I/O\n    std::fstream myFile;\n    // LA siguiente instruccion abre un archivo en modo de escritura \n    // Por defecto, en caso de no existir el archivo en la direccion\n    // dada por el programador, el archivo se crea de manera implicita \n    myFile.open(nameFile, std::ios::out);  \n\n    // Las siguientes instrucciones son para escribir el archivo\n    myFile << \"Nombre: \" << name << \"\\n\";\n    myFile << \"Lenjuages favoritos: \" << language << \"\\n\";\n    myFile << \"Edad: \" << age;\n\n    // Se cierra el archivo\n    myFile.close();\n}\n\n// Funciones definidas\nvoid agregarProducto(std::ofstream& archivo, const std::string& nombre, int cantidad, float precio) {\n    archivo << nombre << \", \" << cantidad << \", \" << precio << std::endl;\n}\n\nvoid consultarProductos(std::ifstream& archivo) {\n    std::string linea;\n    while (std::getline(archivo, linea)) {\n        std::cout << linea << std::endl;\n    }\n}\n\nvoid actualizarProducto(const std::string& nombre, int cantidad, float precio, std::ifstream& archivo, std::ofstream& temporal) {\n    std::string linea;\n    while (std::getline(archivo, linea)) {\n        std::stringstream ss(linea);\n        std::string nombreProducto;\n        std::getline(ss, nombreProducto, ',');\n        if (nombreProducto == nombre) {\n            temporal << nombre << \", \" << cantidad << \", \" << precio << std::endl;\n        } else {\n            temporal << linea << std::endl;\n        }\n    }\n}\n\nvoid eliminarProducto(const std::string& nombre, std::ifstream& archivo, std::ofstream& temporal) {\n    std::string linea;\n    while (std::getline(archivo, linea)) {\n        std::stringstream ss(linea);\n        std::string nombreProducto;\n        std::getline(ss, nombreProducto, ',');\n        if (nombreProducto != nombre) {\n            temporal << linea << std::endl;\n        }\n    }\n}\n\nfloat calcularVentaTotal(std::ifstream& archivo) {\n    float total = 0;\n    std::string linea;\n    while (std::getline(archivo, linea)) {\n        std::stringstream ss(linea);\n        std::string cantidadStr, precioStr;\n        std::getline(ss, cantidadStr, ',');\n        std::getline(ss, precioStr, ',');\n        int cantidad = std::stoi(cantidadStr);\n        float precio = std::stof(precioStr);\n        total += cantidad * precio;\n    }\n    return total;\n}\n\nfloat calcularVentaPorProducto(const std::string& nombre, std::ifstream& archivo) {\n    float venta = 0;\n    std::string linea;\n    while (std::getline(archivo, linea)) {\n        std::stringstream ss(linea);\n        std::string nombreProducto, cantidadStr, precioStr;\n        std::getline(ss, nombreProducto, ',');\n        if (nombreProducto == nombre) {\n            std::getline(ss, cantidadStr, ',');\n            std::getline(ss, precioStr, ',');\n            int cantidad = std::stoi(cantidadStr);\n            float precio = std::stof(precioStr);\n            venta = cantidad * precio;\n            break;\n        }\n    }\n    return venta;\n}\n\nvoid salir() {\n    std::remove(\"ventas.txt\");\n    std::cout << \"Archivo borrado. Saliendo del programa...\" << std::endl;\n    exit(0);\n}\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/dart/teren91.dart",
    "content": "/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n * archivo .txt.\n * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n */\n\nimport 'dart:io';\n\nvoid main() async {\n  //exercice11();\n  salesManagment();\n}\n\nvoid exercice11() async {\n  try {\n    final userName = 'Teren91';\n    final age = 32;\n    final lenguage = 'Dart';\n\n    final file = File('$userName.txt');\n\n    await file.create();\n    await file.writeAsString('''\n    Nombre: $userName\n    Edad: $age\n    Lenguaje de programación favorito: $lenguage\n    ''');\n\n    final content = await file.readAsString();\n    print(content);\n    await file.delete();\n  } catch (e) {\n    print(e);\n  }\n}\n\nvoid salesManagment() async {\n  int? option;\n\n  final file = File('Products.txt');\n\n  ProductList productList = new ProductList(file);\n  await productList.createProductsFile(file);\n\n  SalesCalculator salesCalculator = new SalesCalculator();\n\n  UserUI ui = new UserUI(productList, salesCalculator);\n\n  try {\n    do {\n      ui.showMenu();\n      option = int.tryParse(stdin.readLineSync()!);\n\n      await ui.chooseOption(option!);\n    } while (option != 8);\n  } catch (e) {\n    print(e);\n  }\n}\n\nclass UserUI {\n  final ProductList productList;\n  final SalesCalculator salesCalculator;\n\n  UserUI(this.productList, this.salesCalculator);\n\n  void showMenu() {\n    print('''\n      \n      --------------------\n        1. Añadir producto\n        2. Buscar producto\n        3. Ver todos los productos\n        4. Actualizar producto      \n        5. Eliminar producto\n        6. Ver venta total\n        7. Ver venta por producto\n        8. Exit\n      --------------------\n      ''');\n  }\n\n  Future<void> chooseOption(int option) async {\n    try {\n      switch (option) {\n        case 1:\n          await _addProduct();\n        case 2:\n          await _searchProduct();\n        case 3:\n          await _getAllProducts();\n         case 4:\n          await _updateProduct();\n        case 5:\n          await _deleteProduct();\n        case 6:\n          await _calculateTotalSales();\n        case 7:\n          await _calculateProductSales();\n        case 8:\n          await _deleteFile();\n        default:\n          print('Program finished');\n      }\n    } catch (e) {\n      print(e);\n    }\n  }\n\n  Future<void> _addProduct() async {\n    try {\n      print('Introduzca los datos requeridos:');\n      print('Nombre del producto:');\n      final productName = stdin.readLineSync()!;\n\n      print('Cantidad vendida:');\n      final saleAmount = int.tryParse(stdin.readLineSync()!);\n\n      print('Precio del producto:');\n      final price = double.tryParse(stdin.readLineSync()!);\n\n      Product product = new Product(productName, saleAmount!, price!);\n\n      await productList.addProduct(product);\n\n      print('Producto añadido correctamente');\n    } catch (e) {\n      print(e);\n    }\n  }\n\n  Future<void> _getAllProducts() async {\n    final products = await productList.getAllProducts();\n\n    if(products.isNotEmpty)\n      print(products);\n  }\n\n  Future<void> _searchProduct() async {\n    print('Indica el nombre del producto:');\n    final name = stdin.readLineSync();\n\n    final product = await productList.searchProduct(name!);\n\n    print(product);\n  }\n\n  Future<void> _deleteProduct() async {\n    print('Indica el nombre del producto que deseas eliminar:');\n\n    final name = stdin.readLineSync();\n\n    await productList.deleteProduct(name!);\n\n    print('Producto eliminado correctamente!.');\n  }\n\n  Future<void> _updateProduct() async\n  {\n    print('Indica el nombre del producto para actualizar:');\n    final productName = stdin.readLineSync()!;\n\n    print('Indica la nueva cantidad de venta:');\n    final saleAmount = int.tryParse(stdin.readLineSync()!);\n\n    print('Indica el nuevo precio:');\n    final price = double.tryParse(stdin.readLineSync()!);\n\n    Product product = new Product(productName, saleAmount!, price!);\n\n    await productList.updateProduct(product);\n  }\n\n  Future<void> _deleteFile() async\n  {\n    await productList.deleteFile();\n  }\n\n  _calculateTotalSales() async\n  {\n    final products = await productList.getAllProducts();\n\n    print(salesCalculator.totalSales(products));\n\n  }\n\n  _calculateProductSales() async\n  {\n    print('Introduzca el nombre del producto');\n    final productName = stdin.readLineSync()!;\n\n    final products = await productList.getAllProducts().then((products) => products);\n\n    final sales = salesCalculator.productTotalSales(products, productName);\n    \n\n    print(sales);\n\n  }\n\n\n}\n\nclass Product {\n  final String productName;\n  final int saleAmount;\n  final double price;\n\n  Product(this.productName, this.saleAmount, this.price);\n\n  @override\n  String toString() {\n    return '$productName, $saleAmount, $price';\n  }\n}\n\nclass ProductList {\n  final File productsFile;\n\n  ProductList(this.productsFile);\n\n  Future<void> createProductsFile(File file) async {\n  try {\n    await file.create();\n  } catch (e) {\n    print(e);\n  }\n}\n\n  Future<void> addProduct(Product product) async {\n    try {\n      final content = await productsFile.readAsString();\n      final newContent = '$content\\n${product.toString()}';\n\n      await productsFile.writeAsString(newContent);\n    } catch (e) {\n      print(e);\n    }\n  }\n\n  Future<Product> searchProduct(String name) async {\n    final products = await getAllProducts();\n\n    final product =\n        products.firstWhere((element) => element.productName == name);\n\n    return product;\n  }\n\n  Future<List<Product>> getAllProducts() async {\n    List<Product> products = [];\n    try {\n      final content = await productsFile.readAsString();\n\n      if(content.isEmpty)\n      {\n        print('No hay productos disponibles.');\n        return products;\n      }\n      final lines = content.split('\\n');\n\n      for (final line in lines) {\n        final parts = line.split(',');\n        final product =\n            Product(parts[0], int.parse(parts[1]), double.parse(parts[2]));\n        products.add(product);\n      }\n\n      return products;\n    } catch (e) {\n      print(e);\n    } finally {\n      return products;\n    }\n  }\n\n  Future<void> deleteProduct(String name) async {\n    try {\n      final products = await getAllProducts();\n\n      products.removeWhere((element) => element.productName == name);\n      await _saveProducts(products);\n\n    } catch (e) {\n      print(e);\n    }\n  }\n\n  Future<void> updateProduct(Product product) async\n  {\n    final products = await getAllProducts();\n\n    final index = products.indexWhere(\n      (element) => element.productName == product.productName);\n  \n    products[index] = product;\n\n    _saveProducts(products);\n  }\n\n  Future<void> _saveProducts(List<Product> products) async {\n    try {\n      final content = products.map((e) => e.toString()).join('\\n');\n      await productsFile.writeAsString(content);\n    } catch (e) {\n      print(e);\n    }\n  }\n\n  Future<void> deleteFile() async\n  {\n    try {\n      productsFile.delete();\n    } catch (e) {\n      print(e);\n    }\n  }\n\n}\n\nclass SalesCalculator{\n  \n  double totalSales(List<Product> productList)\n  {\n    double total = 0;\n\n    try {\n      \n      for (final product in productList)\n      {\n        total += product.price * product.saleAmount;\n      }\n\n     // return total;\n      \n    } catch (e) {\n      print(e);\n    }\n\n    return total;\n  }\n\n  double productTotalSales(List<Product> productList, String productName)\n  {\n    try {\n\n      final product = productList.firstWhere((element) => element.productName == productName);\n\n       return product.saleAmount * product.price;\n    } catch (e) {\n      print(e);\n    }\n\n      return 0;\n\n   \n  }\n}\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/ejercicio.md",
    "content": "# #11 MANEJO DE FICHEROS\n> #### Dificultad: Media | Publicación: 11/03/24 | Corrección: 18/03/24\n\n## Ejercicio\n\n```\n/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n * \n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n * archivo .txt.\n * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/go/FreyFonseca117.go",
    "content": "/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un\n * archivo .txt.\n * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n */\n\npackage main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n)\n\n// constantes para usar\nconst fichero string = \"FreyFonseca117.txt\"\n\ntype Usuario struct {\n\tnombre   string\n\tedad     int\n\tlenguaje string\n}\n\nfunc crearFichero() {\n\tfile, err := os.Create(fichero) //crear fichero con nombre del git\n\tif err != nil {\n\t\tlog.Fatalf(\"No se pudo crear el archivo: %v\", err) //se usa para terminar el programa\n\t}\n\tdefer file.Close()\n\tfmt.Printf(\"El fichero con nombre %s ha sido creado exitosamente\\n\", file.Name()) // Salto de línea agregado\n}\n\nfunc agregarDatos(u Usuario) {\n\tfile, err := os.OpenFile(fichero, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0600) // Se usa para abrir el fichero o crearlo en caso que no exista y darle los permisos\n\tif err != nil {\n\t\tlog.Fatalf(\"No se pudo agregar los datos al fichero: %v\", err) // Mejor manejo de errores\n\t}\n\tdefer file.Close()\n\n\t// Escribir los datos en el archivo\n\tdatos := fmt.Sprintf(\"nombre:%s\\nedad:%d\\nlenguaje:%s\\n\", u.nombre, u.edad, u.lenguaje)\n\t_, err = file.WriteString(datos)\n\tif err != nil {\n\t\tlog.Fatalf(\"No se pudieron escribir los datos en el archivo: %v\", err) // Mejor manejo de errores\n\t}\n\tfmt.Println(\"Los datos se han agregado correctamente\\n\") // Salto de línea agregado\n}\n\n// imprimir el contenido\nfunc imprimir() {\n\tfile, err := os.ReadFile(fichero)\n\tif err != nil {\n\t\tlog.Fatal(\"no se puedre abrir el fichero\\n\")\n\t}\n\tfmt.Println(string(file))\n}\n\n// Borrar el archivo\nfunc borrar() {\n\terr := os.Remove(fichero)\n\tif err != nil {\n\t\tlog.Fatal(\"No se ha podido borrar el fichero\")\n\t}\n\tfmt.Println(\"se ha borrado el archivo con éxito\")\n}\n\n// Actividad adicional\nconst ventas string = \"ventas.txt\"\n\n// estructura de productos para agregar.\ntype producto struct {\n\tnombreProducto  string\n\tcantidadVendida int\n\tprecio          float64\n}\n\nfunc menu() {\n\tfmt.Println(\"==== REGISTRO DE VENTAS =====\")\n\tfmt.Println(\"==== POR FAVOR SELECCIONE UNA OPCION =====\")\n\tfmt.Println(\"==== 1 PARA CONSULTAR PRODUCTO =====\")\n\tfmt.Println(\"==== 2 PARA AÑADIR PRODUCTO =====\")\n\tfmt.Println(\"==== 3 PARA ACTUALIZAR PRODUCTO =====\")\n\tfmt.Println(\"==== 4 PARA ELIMINAR PRODUCTO =====\")\n\tfmt.Println(\"==== 5 PARA SALIR =====\")\n\n}\n\nfunc main() {\n\tcrearFichero()\n\tu := Usuario{\n\t\tnombre:   \"Jeffrey\",\n\t\tedad:     34,\n\t\tlenguaje: \"GO\",\n\t}\n\tagregarDatos(u)\n\timprimir()\n\tborrar()\n}\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/go/MiguelP-Dev.go",
    "content": "package main\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// Con el paquete \"os\" podemos manejar la apertura, el cierre, la lectura y escritura de archivos,\n// así como la obtención y configuración de atributos de los mismos.\n\nfunc main() {\n\t// filename Constante que contiene el nombre del archivo.\n\tconst fileName = \"MiguelP-Dev.txt\"\n\tmessage := []byte(\"Miguel\\n 31 Años.\\n Golang.\")\n\n\t// Creamos el archivo para su uso\n\tfile, err := os.Create(fileName)\n\tif err != nil {\n\t\tfmt.Println(\"Error al crear el archivo.\", fileName)\n\t\treturn\n\t}\n\n\t// Garanticemos que el archivo se cierre enventualmente\n\tdefer file.Close()\n\n\t// Apertura del archivo con permisos de escritura\n\tfile, err = os.OpenFile(fileName, os.O_RDWR, 0644)\n\tif err != nil {\n\t\tfmt.Println(\"Error abriendo el archivo:\", err)\n\t\treturn\n\t}\n\n\t// Escribir contenido en el archivo\n\t_, writeError := file.Write(message)\n\tif writeError != nil {\n\t\tfmt.Println(\"Error al escribir en el archivo:\", writeError)\n\t\treturn\n\t}\n\n\t// Leer el archivo desde el principio\n\tfile.Seek(0, 0)\n\tbuffer := make([]byte, len(message))\n\t_, readError := file.Read(buffer)\n\tif readError != nil {\n\t\tfmt.Println(\"Error al leer el archivo:\", readError)\n\t\treturn\n\t}\n\tfmt.Println(\"Contenido del archivo:\", string(buffer))\n\n\t// Eliminamos el archivo\n\terr = os.Remove(fileName)\n\tif err != nil {\n\t\tfmt.Println(\"error al eliminar el archivo\")\n\t\treturn\n\t}\n\n\t// Extra\n\t// Creamos el archivo y controlamos el posible error\n\tfile, err = os.OpenFile(productsFile, os.O_APPEND|os.O_CREATE, 0644)\n\tif err != nil {\n\t\tfmt.Println(\"Error al crear el archivo Main():\", err)\n\t\treturn\n\t}\n\n\terr = file.Close()\n\tif err != nil {\n\t\tfmt.Println(\"Error al cerrar el archivo Main(): \", err)\n\t}\n\n\tvar productName string\n\tvar productQuantity string\n\tvar productPrice string\n\tvar option uint\n\n\tfor {\n\t\tfmt.Println(\"Selecciona una de las opciones: \")\n\t\tfmt.Println(\"1. Añadir un Producto\")\n\t\tfmt.Println(\"2. Consultar un producto\")\n\t\tfmt.Println(\"3. Consultar lista de productos\")\n\t\tfmt.Println(\"4. Consultar venta total por producto\")\n\t\tfmt.Println(\"5. Consultar venta total\")\n\t\tfmt.Println(\"6. Actualizar un producto\")\n\t\tfmt.Println(\"7. Eliminar un producto\")\n\t\tfmt.Println(\"8. Salir\")\n\t\tfmt.Scan(&option)\n\n\t\tswitch option {\n\t\tcase 1:\n\t\t\tfmt.Printf(\"Ingresa el nombre del producto: \")\n\t\t\tfmt.Scan(&productName)\n\t\t\tfmt.Printf(\"Ingresa la cantidad: \")\n\t\t\tfmt.Scan(&productQuantity)\n\t\t\tfmt.Printf(\"Ingresa el valor: \")\n\t\t\tfmt.Scan(&productPrice)\n\t\t\terr := pro.AddingProduct(productName, productQuantity, productPrice)\n\t\t\tif err != nil {\n\t\t\t\tfmt.Println(\"Error AddingProduct(): \", err)\n\t\t\t}\n\t\tcase 2:\n\t\t\tfmt.Printf(\"Ingresa el nombre del producto: \")\n\t\t\tfmt.Scan(&productName)\n\t\t\terr := pro.searchProduct(productName)\n\t\t\tif err != nil {\n\t\t\t\tfmt.Println(\"Error searchProduct(): \", err)\n\t\t\t}\n\t\tcase 3:\n\t\t\terr := pro.listOfProducts()\n\t\t\tif err != nil {\n\t\t\t\tfmt.Println(\"Error listOfProducts(): \", err)\n\t\t\t}\n\t\tcase 4:\n\t\t\tfmt.Println(\"Ingresa el nombre del producto: \")\n\t\t\tfmt.Scan(&productName)\n\t\t\terr := pro.totalSaleByProduct(productName)\n\t\t\tif err != nil {\n\t\t\t\tfmt.Println(\"Error totalSaleByProduct(): \", err)\n\t\t\t}\n\t\tcase 5:\n\t\t\terr := pro.totalSaleAmount()\n\t\t\tif err != nil {\n\t\t\t\tfmt.Println(\"Error totalSaleAmount(): \", err)\n\t\t\t}\n\t\tcase 6:\n\t\t\tfmt.Printf(\"Ingresa el nombre del producto: \")\n\t\t\tfmt.Scan(&productName)\n\t\t\tfmt.Printf(\"Ingresa la cantidad: \")\n\t\t\tfmt.Scan(&productQuantity)\n\t\t\tfmt.Printf(\"Ingresa el valor: \")\n\t\t\tfmt.Scan(&productPrice)\n\t\t\terr := pro.updateProduct(productName, productQuantity, productPrice)\n\t\t\tif err != nil {\n\t\t\t\tfmt.Println(\"Error updateProduct(): \", err)\n\t\t\t}\n\t\tcase 7:\n\t\t\tfmt.Println(\"Ingresa el nombre del producto a eliminar: \")\n\t\t\tfmt.Scan(&productName)\n\t\t\tpro.deleteProduct(productName)\n\t\tcase 8:\n\t\t\terr := os.Remove(productsFile)\n\t\t\tif err != nil {\n\t\t\t\tfmt.Println(\"Error al eliminar el archivo:\", err)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tos.Exit(0)\n\t\tdefault:\n\t\t\tfmt.Println(\"Selecciona una opcion correcta\\n\")\n\t\t}\n\t}\n}\n\nvar productsFile = \"Productos.txt\"\nvar tmpFile = \"tmp.txt\"\n\ntype products struct {\n\tname     string\n\tquantity string\n\tprice    string\n}\n\nvar pro = products{}\n\nfunc (p *products) AddingProduct(name, quantity, price string) error {\n\n\tproducts, err := search(productsFile)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\terr = os.Remove(productsFile)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfile, err := os.Create(productsFile)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer file.Close()\n\n\tif len(products) > 0 {\n\t\tfor _, product := range products {\n\t\t\t_, err = file.WriteString(product + \"\\n\")\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\n\tnewProduct := strings.ToLower(name) + \", \" + quantity + \", \" + price + \"\\n\"\n\t_, err = file.WriteString(newProduct)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\terr = file.Sync()\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (p *products) searchProduct(name string) error {\n\tproducts, err := search(productsFile)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfor _, product := range products {\n\t\tsplit := strings.Split(product, \", \")\n\t\tif strings.ToLower(split[0]) == strings.ToLower(name) {\n\t\t\tfmt.Printf(\"Nombre: %s, Cantidad: %s, Valor: %s.\\n\", split[0], split[1], split[2])\n\t\t\treturn nil\n\t\t}\n\t}\n\tfmt.Printf(\"Producto %s no encontrado.\\n\", strings.ToUpper(name))\n\treturn nil\n}\n\nfunc (p *products) listOfProducts() error {\n\tproducts, err := search(productsFile)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfor _, product := range products {\n\t\tsplit := strings.Split(product, \", \")\n\t\tfmt.Printf(\"Nombre: %s, Cantidad: %s, Valor: %s.\\n\", split[0], split[1], split[2])\n\t}\n\treturn nil\n}\n\nfunc (p *products) deleteProduct(name string) error {\n\tproducts, err := search(productsFile)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tvar newProducts = []string{}\n\tfor _, product := range products {\n\t\tsplited := strings.Split(product, \", \")\n\t\tif strings.ToLower(splited[0]) != strings.ToLower(name) {\n\t\t\tnewProducts = append(newProducts, splited[0]+\", \"+splited[1]+\", \"+splited[2])\n\t\t}\n\t}\n\n\terr = os.Remove(productsFile)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfile, err := os.Create(productsFile)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer file.Close()\n\n\tfor i := 0; i <= len(newProducts)-1; i++ {\n\t\tfile.WriteString(newProducts[i] + \"\\n\")\n\t}\n\tfile.Sync()\n\n\treturn nil\n}\n\nfunc (p *products) updateProduct(name, quantity, price string) error {\n\tproducts, err := search(productsFile)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tvar newProducts = []string{}\n\tfor _, product := range products {\n\t\tsplited := strings.Split(product, \", \")\n\t\tif strings.ToLower(splited[0]) != strings.ToLower(name) {\n\t\t\tnewProducts = append(newProducts, splited[0]+\", \"+splited[1]+\", \"+splited[2])\n\t\t} else if strings.ToLower(splited[0]) == strings.ToLower(name) {\n\t\t\tnewProducts = append(newProducts, name+\", \"+quantity+\", \"+price)\n\t\t}\n\t}\n\n\terr = os.Remove(productsFile)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfile, err := os.Create(productsFile)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer file.Close()\n\n\tfor i := 0; i <= len(newProducts)-1; i++ {\n\t\tfile.WriteString(newProducts[i] + \"\\n\")\n\t}\n\tfile.Sync()\n\n\treturn nil\n}\n\nfunc (p *products) totalSaleAmount() error {\n\tproducts, err := search(productsFile)\n\tif err != nil {\n\t\treturn err\n\t}\n\tamounts := []string{}\n\tquantity := 0\n\tfor _, product := range products {\n\t\tsplit := strings.Split(product, \", \")\n\t\tamounts = append(amounts, split[2])\n\t\tnumber, _ := strconv.Atoi(split[1])\n\t\tquantity += number\n\t}\n\n\tvar total float64\n\tfor i := 0; i <= len(amounts)-1; i++ {\n\t\tconversion, err := strconv.ParseFloat(amounts[i], 64)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\ttotal += conversion * float64(quantity)\n\t}\n\tfmt.Printf(\"Total vendido: %v\\n\", total)\n\treturn nil\n}\n\nfunc (p *products) totalSaleByProduct(productName string) error {\n\tproducts, err := search(productsFile)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tvar total float64\n\tfor _, product := range products {\n\t\tsplittedProduct := strings.Split(product, \", \")\n\n\t\tif productName == splittedProduct[0] {\n\n\t\t\tquantity, err := strconv.Atoi(splittedProduct[1])\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tprice, err := strconv.ParseFloat(splittedProduct[2], 64)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\ttotal = price * float64(quantity)\n\t\t}\n\t}\n\n\tfmt.Printf(\"Producto: %s, Venta total: %v\\n\", productName, total)\n\treturn nil\n}\n\nfunc search(filename string) ([]string, error) {\n\tfile, err := os.OpenFile(filename, os.O_RDONLY, 0644)\n\tif err != nil {\n\t\treturn []string{}, err\n\t}\n\tdefer file.Close()\n\n\tvar products = []string{}\n\tscanner := bufio.NewScanner(file)\n\tfor scanner.Scan() {\n\t\tproducts = append(products, scanner.Text())\n\t}\n\n\tif err := scanner.Err(); err != nil {\n\t\treturn []string{}, err\n\t}\n\n\treturn products, nil\n}\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/go/N0HagoNada.go",
    "content": "package main\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"strings\"\n)\n\n/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un\n * archivo .txt.\n * - Cada producto se guarda en una línea del arhivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n */\n\nfunc main() {\n\t// Ejercicio\n\ttempFile, err := os.Create(\"N0HagoNada.txt\")\n\tif err != nil {\n\t\tfmt.Println(err)\n\t\treturn\n\t}\n\tfmt.Println(\"Archivo creado con extio: \", tempFile.Name())\n\terr = tempFile.Close()\n\tif err != nil {\n\t\tfmt.Println(err)\n\t\treturn\n\t}\n\tfile, err := os.OpenFile(\"N0HagoNada.txt\", os.O_APPEND|os.O_WRONLY, 0644)\n\tif err != nil {\n\t\tfmt.Println(err)\n\t\treturn\n\t}\n\t_, err = file.WriteString(\"Nombre: Juan David \\n\")\n\tif err != nil {\n\t\tfmt.Println(err)\n\t\treturn\n\t}\n\t_, err = file.WriteString(\"Edad: 31 \\n\")\n\t_, err = file.WriteString(\"Lenguaje de programación favorito: go\")\n\terr = file.Close()\n\tif err != nil {\n\t\tfmt.Println(err)\n\t\treturn\n\t}\n\tfile, err = os.Open(\"N0HagoNada.txt\")\n\tdata, err := io.ReadAll(file)\n\tif err != nil {\n\t\tfmt.Println(err)\n\t\treturn\n\t}\n\tcontent := string(data)\n\tfmt.Println(content)\n\terr = file.Close()\n\tif err != nil {\n\t\tfmt.Println(err)\n\t\treturn\n\t}\n\terr = os.Remove(tempFile.Name())\n\tif err != nil {\n\t\tfmt.Println(err)\n\t\treturn\n\t}\n\tfmt.Println(\"******************************* RETO *************************************************\")\n\tcuentas, err := os.Create(\"Tienda.txt\")\n\tnombreArchivo := cuentas.Name()\n\tcuentas.Close()\n\tif err != nil {\n\t\tfmt.Println(err)\n\t\treturn\n\t}\n\tscanner := bufio.NewScanner(os.Stdin)\n\tfor {\n\t\tfmt.Println(\"Bienvenido al inventario para la tienda de la esquina\")\n\t\tfmt.Println(\"1. Añadir Producto\")\n\t\tfmt.Println(\"2. Consultar producto por nombre\")\n\t\tfmt.Println(\"3. Actualizar producto\")\n\t\tfmt.Println(\"4. Eliminar producto\")\n\t\tfmt.Println(\"Escribe 'exit' para salir\")\n\t\tfmt.Print(\"Elige una opción: \")\n\t\tscanner.Scan()\n\t\tinput := strings.TrimSpace(scanner.Text())\n\t\tif strings.ToLower(input) == \"exit\" {\n\t\t\terr := os.Remove(nombreArchivo)\n\t\t\tif err != nil {\n\t\t\t\tfmt.Println(err)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t\tswitch input {\n\t\tcase \"1\":\n\t\t\t// Lógica para agregar producto\n\t\t\tvar nombreProducto, cantidadVendiad, precio string\n\t\t\tfmt.Print(\"Ingresa el nombreProducto: \")\n\t\t\tscanner.Scan()\n\t\t\tnombreProducto = scanner.Text()\n\n\t\t\tfmt.Print(\"Ingresa la cantidadVendiad: \")\n\t\t\tscanner.Scan()\n\t\t\tcantidadVendiad = scanner.Text()\n\n\t\t\tfmt.Print(\"Ingresa el precio: \")\n\t\t\tscanner.Scan()\n\t\t\tprecio = scanner.Text()\n\n\t\t\tconstruirLinea := fmt.Sprintf(\"%s, %s, %s \\n\", nombreProducto, cantidadVendiad, precio)\n\t\t\terr = agregarProducto(nombreArchivo, construirLinea)\n\t\t\tif err != nil {\n\t\t\t\tfmt.Println(err)\n\t\t\t\treturn\n\t\t\t}\n\n\t\tcase \"2\":\n\t\t\t// Lógica para consultar\n\t\t\tvar nombreProducto string\n\t\t\tfmt.Print(\"Ingresa el nombreProducto: \")\n\t\t\tscanner.Scan()\n\t\t\tnombreProducto = scanner.Text()\n\t\t\tencontrado, err := consultarProdcuto(nombreArchivo, nombreProducto)\n\t\t\tif err != nil {\n\t\t\t\tfmt.Println(err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tfmt.Println(encontrado)\n\n\t\tcase \"3\":\n\t\t\t// Lógica para actualizar\n\t\t\tvar nombreProducto, cantidadVendiad, precio string\n\t\t\tfmt.Print(\"Ingresa el nombreProducto a actualizar: \")\n\t\t\tscanner.Scan()\n\t\t\tnombreProducto = scanner.Text()\n\t\t\tfmt.Print(\"Ingresa la cantidadVendiad: \")\n\t\t\tscanner.Scan()\n\t\t\tcantidadVendiad = scanner.Text()\n\n\t\t\tfmt.Print(\"Ingresa el precio: \")\n\t\t\tscanner.Scan()\n\t\t\tprecio = scanner.Text()\n\t\t\tconstruirLinea := fmt.Sprintf(\"%s, %s, %s \\n\", nombreProducto, cantidadVendiad, precio)\n\t\t\terr := actualizarlineaEnArchivo(nombreArchivo, nombreProducto, construirLinea)\n\t\t\tif err != nil {\n\t\t\t\tfmt.Println(err)\n\t\t\t\treturn\n\t\t\t}\n\n\t\tcase \"4\":\n\t\t\t// Lógica para eliminar\n\t\t\tvar nombreProducto string\n\t\t\tfmt.Print(\"Ingresa el nombreProducto: \")\n\t\t\tscanner.Scan()\n\t\t\tnombreProducto = scanner.Text()\n\t\t\terr := eliminarLineaenArchivo(nombreArchivo, nombreProducto)\n\t\t\tif err != nil {\n\t\t\t\tfmt.Println(err)\n\t\t\t\treturn\n\t\t\t}\n\n\t\tdefault:\n\t\t\tfmt.Println(\"Opción no válida, por favor intenta de nuevo.\")\n\t\t}\n\t}\n}\n\nfunc agregarProducto(nombre string, linea string) error {\n\tarchivo, err := os.OpenFile(nombre, os.O_APPEND|os.O_WRONLY, 0666)\n\tif err != nil {\n\t\treturn err\n\t}\n\t_, err = archivo.WriteString(linea)\n\tif err != nil {\n\t\t// Manejo del error\n\t\treturn err\n\t}\n\tdefer archivo.Close()\n\treturn nil\n}\nfunc consultarProdcuto(nombre string, producto string) (string, error) {\n\tarchivo, err := os.OpenFile(nombre, os.O_RDONLY, 0666)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tdefer archivo.Close()\n\tscanner := bufio.NewScanner(archivo)\n\tfor scanner.Scan() {\n\t\tlinea := scanner.Text()\n\t\tif strings.Contains(linea, producto) {\n\t\t\treturn linea, nil\n\t\t}\n\t}\n\treturn \"\", fmt.Errorf(\"no se encontro %s\", producto)\n}\nfunc actualizarlineaEnArchivo(nombreArchivo, lineaBuscar, lineaNueva string) error {\n\tarchivo, err := os.OpenFile(nombreArchivo, os.O_RDWR, 0666)\n\tif err != nil {\n\t\treturn err\n\t}\n\t// Crear un archivo temporal\n\ttempArchivo, err := os.CreateTemp(\"\", \"temp\")\n\tif err != nil {\n\t\treturn err\n\t}\n\tscanner := bufio.NewScanner(archivo)\n\tvar lineaActualizada bool\n\n\t// Leer y escribir al archivo temporal\n\tfor scanner.Scan() {\n\t\tlinea := scanner.Text()\n\t\tif strings.Contains(linea, lineaBuscar) && !lineaActualizada {\n\t\t\t_, err = tempArchivo.WriteString(lineaNueva + \"\\n\")\n\t\t\tlineaActualizada = true // Asegura que solo se actualice la primera coincidencia\n\t\t} else {\n\t\t\t_, err = tempArchivo.WriteString(linea + \"\\n\")\n\t\t}\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\t// Verificar errores al leer el archivo\n\tif err := scanner.Err(); err != nil {\n\t\treturn err\n\t}\n\tarchivo.Close()\n\ttempArchivo.Close()\n\t// Reemplazar el archivo original con el archivo temporal\n\terr = os.Rename(tempArchivo.Name(), nombreArchivo)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc eliminarLineaenArchivo(nombreArchivo, lineaBuscar string) error {\n\tarchivo, err := os.OpenFile(nombreArchivo, os.O_RDWR, 0666)\n\tif err != nil {\n\t\treturn err\n\t}\n\t// Crear un archivo temporal\n\ttempArchivo, err := os.CreateTemp(\"\", \"temp\")\n\tif err != nil {\n\t\treturn err\n\t}\n\tscanner := bufio.NewScanner(archivo)\n\n\t// Leer y escribir al archivo temporal\n\tfor scanner.Scan() {\n\t\tlinea := scanner.Text()\n\t\tif strings.Contains(linea, lineaBuscar) {\n\t\t\tcontinue\n\t\t} else {\n\t\t\t_, err = tempArchivo.WriteString(linea + \"\\n\")\n\t\t}\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\t// Verificar errores al leer el archivo\n\tif err := scanner.Err(); err != nil {\n\t\treturn err\n\t}\n\terr = archivo.Close()\n\tif err != nil {\n\t\treturn err\n\t}\n\terr = tempArchivo.Close()\n\tif err != nil {\n\t\treturn err\n\t}\n\t// Reemplazar el archivo original con el archivo temporal\n\terr = os.Rename(tempArchivo.Name(), nombreArchivo)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/go/hozlucas28.go",
    "content": "package main\n\nimport (\n\t\"bufio\"\n\t\"errors\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n)\n\ntype Product struct {\n\tamount int\n\tname   string\n\tprice  float32\n}\n\ntype TotalSales struct {\n\tamount int\n\tprice  float32\n}\n\n/* -------------------------------------------------------------------------- */\n/*                             SALES FILE (CLASS)                             */\n/* -------------------------------------------------------------------------- */\n\ntype SalesFile struct {\n\t__amountOfProducts int\n\t__isDeleted        bool\n\t__path             string\n}\n\nfunc NewSalesFile(path string, initialProducts []Product) (*SalesFile, error) {\n\t_, statErr := os.Stat(path)\n\tif statErr == nil {\n\t\tremoveErr := os.Remove(path)\n\t\tif removeErr != nil {\n\t\t\treturn nil, removeErr\n\t\t}\n\t}\n\n\tfile, createErr := os.Create(path)\n\tif createErr != nil {\n\t\treturn nil, createErr\n\t}\n\n\tcloseErr := file.Close()\n\tif closeErr != nil {\n\t\treturn nil, closeErr\n\t}\n\n\tvar salesFile SalesFile = SalesFile{\n\t\t__amountOfProducts: 0,\n\t\t__isDeleted:        false,\n\t\t__path:             path,\n\t}\n\n\tif len(initialProducts) > 0 {\n\t\tsalesFile.appendProducts(initialProducts)\n\t}\n\n\treturn &salesFile, nil\n}\n\nfunc (salesFile *SalesFile) getProduct(productName string) (Product, error) {\n\tvar productFound Product\n\n\tif salesFile.__isDeleted {\n\t\treturn productFound, errors.New(\"The file was deleted! Invalid operation\")\n\t}\n\n\tproducts, productsErr := salesFile.getProducts()\n\tif productsErr != nil {\n\t\treturn productFound, nil\n\t}\n\n\tfor i := 0; i < len(products); i++ {\n\t\tvar product Product = products[i]\n\t\tif strings.ToUpper(product.name) == strings.ToUpper(productName) {\n\t\t\tproductFound.amount = product.amount\n\t\t\tproductFound.name = product.name\n\t\t\tproductFound.price = product.price\n\t\t\tbreak\n\t\t}\n\t}\n\n\treturn productFound, nil\n}\n\nfunc (salesFile *SalesFile) getProducts() ([]Product, error) {\n\tvar products []Product = []Product{}\n\n\tif salesFile.__isDeleted {\n\t\treturn products, errors.New(\"The file was deleted! Invalid operation\")\n\t}\n\n\tcontent, readErr := os.ReadFile(salesFile.__path)\n\tif readErr != nil {\n\t\treturn products, readErr\n\t}\n\n\tproductArr := strings.Split(string(content), \"\\n\")\n\n\tfor i := 0; i < len(productArr); i++ {\n\t\tvar productInfo []string = strings.Split(productArr[i], \", \")\n\n\t\tproductAmount, atoiErr := strconv.Atoi(productInfo[1])\n\t\tif atoiErr != nil {\n\t\t\treturn products, atoiErr\n\t\t}\n\n\t\tproductPrice, parseFloatErr := strconv.ParseFloat(productInfo[2], 32)\n\t\tif parseFloatErr != nil {\n\t\t\treturn products, parseFloatErr\n\t\t}\n\n\t\tproducts = append(products, Product{\n\t\t\tname:   productInfo[0],\n\t\t\tamount: productAmount,\n\t\t\tprice:  float32(productPrice),\n\t\t})\n\t}\n\n\treturn products, nil\n}\n\nfunc (salesFile *SalesFile) getTotalSales() (TotalSales, error) {\n\tvar totalSales TotalSales\n\n\tif salesFile.__isDeleted {\n\t\treturn totalSales, errors.New(\"The file was deleted! Invalid operation\")\n\t}\n\n\tproducts, productsErr := salesFile.getProducts()\n\tif productsErr != nil {\n\t\treturn totalSales, productsErr\n\t}\n\n\tfor i := 0; i < len(products); i++ {\n\t\tvar product Product = products[i]\n\t\ttotalSales.amount += product.amount\n\t\ttotalSales.price += float32(product.amount) * product.price\n\t}\n\n\treturn totalSales, nil\n}\n\nfunc (salesFile *SalesFile) getProductTotalSales(productName string) (TotalSales, error) {\n\tvar totalSales TotalSales\n\n\tif salesFile.__isDeleted {\n\t\treturn totalSales, errors.New(\"The file was deleted! Invalid operation\")\n\t}\n\n\tproducts, productsErr := salesFile.getProducts()\n\tif productsErr != nil {\n\t\treturn totalSales, productsErr\n\t}\n\n\tfor i := 0; i < len(products); i++ {\n\t\tvar product Product = products[i]\n\t\tif strings.ToUpper(product.name) == strings.ToUpper(productName) {\n\t\t\ttotalSales.amount += product.amount\n\t\t\ttotalSales.price += float32(product.amount) * product.price\n\t\t}\n\t}\n\n\treturn totalSales, nil\n}\n\nfunc (salesFile *SalesFile) appendProducts(products []Product) error {\n\tif salesFile.__isDeleted {\n\t\treturn errors.New(\"The file was deleted! Invalid operation\")\n\t}\n\n\tfile, openErr := os.OpenFile(salesFile.__path, os.O_APPEND, os.ModeAppend)\n\tif openErr != nil {\n\t\treturn openErr\n\t}\n\n\tvar lineBreak string = \"\"\n\tif salesFile.__amountOfProducts > 0 {\n\t\tlineBreak = \"\\n\"\n\t}\n\n\tvar firstProduct Product = products[0]\n\tvar firstProductStr string = fmt.Sprintf(\"%s%s, %d, %.2f\", lineBreak, firstProduct.name, firstProduct.amount, firstProduct.price)\n\n\t_, writeErr := file.WriteString(firstProductStr)\n\tif writeErr != nil {\n\t\treturn writeErr\n\t}\n\n\tsalesFile.__amountOfProducts++\n\n\tfor i := 1; i < len(products); i++ {\n\t\tvar product Product = products[i]\n\t\tvar productStr string = fmt.Sprintf(\"\\n%s, %d, %.2f\", product.name, product.amount, product.price)\n\n\t\t_, writeErr := file.WriteString(productStr)\n\t\tif writeErr != nil {\n\t\t\treturn writeErr\n\t\t}\n\n\t\tsalesFile.__amountOfProducts++\n\t}\n\n\tcloseErr := file.Close()\n\tif closeErr != nil {\n\t\treturn closeErr\n\t}\n\n\treturn nil\n}\n\nfunc (salesFile SalesFile) deleteFile() error {\n\tif salesFile.__isDeleted {\n\t\treturn errors.New(\"The file was deleted! Invalid operation\")\n\t}\n\n\tremoveErr := os.Remove(salesFile.__path)\n\tif removeErr != nil {\n\t\tlog.Fatal(removeErr)\n\t}\n\n\treturn nil\n}\n\nfunc (salesFile *SalesFile) deleteProduct(productName string) error {\n\tif salesFile.__isDeleted {\n\t\treturn errors.New(\"The file was deleted! Invalid operation\")\n\t}\n\n\tproducts, productsErr := salesFile.getProducts()\n\tif productsErr != nil {\n\t\treturn productsErr\n\t}\n\n\tvar sanitizedProducts []Product\n\n\tfor i := 0; i < len(products); i++ {\n\t\tvar product Product = products[i]\n\t\tif strings.ToUpper(product.name) != strings.ToUpper(productName) {\n\t\t\tsanitizedProducts = append(sanitizedProducts, product)\n\t\t}\n\t}\n\n\tnSalesFile, nSalesFileErr := NewSalesFile(salesFile.__path, sanitizedProducts)\n\tif nSalesFileErr != nil {\n\t\treturn nSalesFileErr\n\t}\n\n\tsalesFile = nSalesFile\n\n\treturn nil\n}\n\nfunc (salesFile *SalesFile) updateProduct(productName string, newAmount int, newPrice float32) error {\n\tif salesFile.__isDeleted {\n\t\treturn errors.New(\"The file was deleted! Invalid operation\")\n\t}\n\n\tproducts, productsErr := salesFile.getProducts()\n\tif productsErr != nil {\n\t\treturn productsErr\n\t}\n\n\tfor i := 0; i < len(products); i++ {\n\t\tvar product *Product = &products[i]\n\t\tif strings.ToUpper(product.name) == strings.ToUpper(productName) {\n\t\t\tif newAmount > 0 {\n\t\t\t\tproduct.amount = newAmount\n\t\t\t}\n\n\t\t\tif newPrice > 0 {\n\t\t\t\tproduct.price = newPrice\n\t\t\t}\n\n\t\t}\n\t}\n\n\tnSalesFile, nSalesFileErr := NewSalesFile(salesFile.__path, products)\n\tif nSalesFileErr != nil {\n\t\treturn nSalesFileErr\n\t}\n\n\tsalesFile = nSalesFile\n\n\treturn nil\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\nfunc main() {\n\t/*\n\t\tFiles...\n\t*/\n\n\tfmt.Println(\"Files...\")\n\n\tconst filePath string = \"hozlucas28.txt\"\n\n\tif _, statErr := os.Stat(filePath); statErr == nil {\n\t\tremoveErr := os.Remove(filePath)\n\t\tif removeErr != nil {\n\t\t\tlog.Fatal(removeErr)\n\t\t}\n\t}\n\n\tfile, fileErr := os.Create(filePath)\n\tif fileErr != nil {\n\t\tlog.Fatal(fileErr)\n\t}\n\n\tconst newContent string = \"Lucas Hoz\\n22\\nGo\"\n\t_, writeErr := file.WriteString(newContent)\n\tif writeErr != nil {\n\t\tlog.Fatal(writeErr)\n\t}\n\n\tfile.Close()\n\n\treadContent, readErr := os.ReadFile(filePath)\n\tif readErr != nil {\n\t\tlog.Fatal(readErr)\n\t}\n\n\tfmt.Printf(\"\\n%s\\n\", string(readContent))\n\n\tif _, statErr := os.Stat(filePath); statErr == nil {\n\t\tremoveErr := os.Remove(filePath)\n\t\tif removeErr != nil {\n\t\t\tlog.Fatal(removeErr)\n\t\t}\n\t}\n\n\t/*\n\t\tAdditional challenge...\n\t*/\n\n\tfmt.Println(\"\\n# ---------------------------------------------------------------------------------- #\\n\")\n\n\tfmt.Println(\"Additional challenge...\")\n\n\tconst salesFilePath string = \"sales.txt\"\n\n\tsalesFile, salesFileErr := NewSalesFile(salesFilePath, []Product{\n\t\t{\n\t\t\tamount: 100,\n\t\t\tname:   \"Apple\",\n\t\t\tprice:  199.99,\n\t\t},\n\t})\n\tif salesFileErr != nil {\n\t\tlog.Fatal(salesFileErr)\n\t}\n\n\tvar shouldExit bool\n\treader := bufio.NewReader(os.Stdin)\n\n\tfor !shouldExit {\n\t\tfmt.Print(\"\\nSelect an operation (Add, Delete, Get, Get total sales, Get total sales of a product, Print, Update, or Exit): \")\n\t\toperation, readErr := reader.ReadString('\\n')\n\t\tif readErr != nil {\n\t\t\toperation = \"\"\n\t\t}\n\n\t\tvar operationFmt string = strings.ToUpper(strings.TrimSpace(operation))\n\n\toperationActions:\n\t\tswitch operationFmt {\n\t\tcase \"ADD\":\n\t\t\tvar newProduct Product\n\n\t\t\tfmt.Print(\"\\nProduct name: \")\n\t\t\t_, nameErr := fmt.Scanf(\"%s\\n\", &newProduct.name)\n\t\t\tif nameErr != nil {\n\t\t\t\tfmt.Println(\"\\nInvalid name!\")\n\t\t\t\tbreak operationActions\n\t\t\t}\n\n\t\t\tfmt.Print(\"Product amount: \")\n\t\t\t_, amounErr := fmt.Scanf(\"%d\\n\", &newProduct.amount)\n\t\t\tif amounErr != nil {\n\t\t\t\tfmt.Println(\"\\nInvalid amount!\")\n\t\t\t\tbreak operationActions\n\t\t\t}\n\n\t\t\tfmt.Print(\"Product price: \")\n\t\t\t_, priceErr := fmt.Scanf(\"%f\\n\", &newProduct.price)\n\t\t\tif priceErr != nil {\n\t\t\t\tfmt.Print(\"\\nInvalid price!\")\n\t\t\t\tbreak operationActions\n\t\t\t}\n\n\t\t\tappendErr := salesFile.appendProducts([]Product{newProduct})\n\t\t\tif appendErr != nil {\n\t\t\t\tlog.Fatal(appendErr)\n\t\t\t}\n\n\t\tcase \"DELETE\":\n\t\t\tvar product Product\n\n\t\t\tfmt.Print(\"\\nProduct name: \")\n\t\t\t_, nameErr := fmt.Scanf(\"%s\\n\", &product.name)\n\t\t\tif nameErr != nil {\n\t\t\t\tfmt.Println(\"\\nInvalid name!\")\n\t\t\t\tbreak operationActions\n\t\t\t}\n\n\t\t\tdeleteErr := salesFile.deleteProduct(product.name)\n\t\t\tif deleteErr != nil {\n\t\t\t\tlog.Fatal(deleteErr)\n\t\t\t}\n\n\t\tcase \"GET\":\n\t\t\tvar productName string\n\n\t\t\tfmt.Print(\"\\nProduct name: \")\n\t\t\t_, nameErr := fmt.Scanf(\"%s\\n\", &productName)\n\t\t\tif nameErr != nil {\n\t\t\t\tfmt.Println(\"\\nInvalid name!\")\n\t\t\t\tbreak operationActions\n\t\t\t}\n\n\t\t\tproduct, productErr := salesFile.getProduct(productName)\n\t\t\tif productErr != nil {\n\t\t\t\tlog.Fatal(productErr)\n\t\t\t}\n\n\t\t\tfmt.Printf(\"\\nName: %s\\nAmount: %d\\nPrice: $%.2f\\n\", product.name, product.amount, product.price)\n\n\t\tcase \"GET TOTAL SALES\":\n\t\t\ttotalSales, totalSalesErr := salesFile.getTotalSales()\n\t\t\tif totalSalesErr != nil {\n\t\t\t\tlog.Fatal(totalSalesErr)\n\t\t\t}\n\n\t\t\tfmt.Printf(\"\\nAmount: %d\\nTotal: $%.2f\\n\", totalSales.amount, totalSales.price)\n\n\t\tcase \"GET TOTAL SALES OF A PRODUCT\":\n\t\t\tvar productName string\n\n\t\t\tfmt.Print(\"\\nProduct name: \")\n\t\t\t_, nameErr := fmt.Scanf(\"%s\\n\", &productName)\n\t\t\tif nameErr != nil {\n\t\t\t\tfmt.Println(\"\\nInvalid name!\")\n\t\t\t\tbreak operationActions\n\t\t\t}\n\n\t\t\ttotalSales, totalSalesErr := salesFile.getProductTotalSales(productName)\n\t\t\tif totalSalesErr != nil {\n\t\t\t\tlog.Fatal(totalSalesErr)\n\t\t\t}\n\n\t\t\tfmt.Printf(\"\\nAmount: %d\\nTotal: $%.2f\\n\", totalSales.amount, totalSales.price)\n\n\t\tcase \"PRINT\":\n\t\t\tproducts, productsErr := salesFile.getProducts()\n\t\t\tif productsErr != nil {\n\t\t\t\tlog.Fatal(productsErr)\n\t\t\t}\n\n\t\t\tfor i := 0; i < len(products); i++ {\n\t\t\t\tvar product Product = products[i]\n\t\t\t\tfmt.Printf(\"\\nName: %s\\nAmount: %d\\nPrice: $%.2f\\n\", product.name, product.amount, product.price)\n\t\t\t}\n\n\t\tcase \"UPDATE\":\n\t\t\tvar product Product\n\n\t\t\tfmt.Print(\"\\nProduct name: \")\n\t\t\t_, nameErr := fmt.Scanf(\"%s\\n\", &product.name)\n\t\t\tif nameErr != nil {\n\t\t\t\tfmt.Println(\"\\nInvalid name!\")\n\t\t\t\tbreak operationActions\n\t\t\t}\n\n\t\t\tfmt.Print(\"New amount (optional): \")\n\t\t\tfmt.Scanf(\"%d\\n\", &product.amount)\n\n\t\t\tfmt.Print(\"New price (optional): \")\n\t\t\tfmt.Scanf(\"%f\\n\", &product.price)\n\n\t\t\tupdateErr := salesFile.updateProduct(product.name, product.amount, product.price)\n\t\t\tif updateErr != nil {\n\t\t\t\tlog.Fatal(updateErr)\n\t\t\t}\n\n\t\tcase \"EXIT\":\n\t\t\tdeleteErr := salesFile.deleteFile()\n\t\t\tshouldExit = true\n\n\t\t\tif deleteErr != nil {\n\t\t\t\tlog.Fatal(deleteErr)\n\t\t\t}\n\n\t\tdefault:\n\t\t\tfmt.Println(\"\\nInvalid operation! Try again...\")\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/go/kodenook.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"os\"\n)\n\nfunc main() {\n\tfile, _ := os.Create(\"kodenook.txt\")\n\tdefer file.Close()\n\n\tfile.WriteString(\"richard Ocaranza\\n\")\n\tfile.WriteString(\"27\\n\")\n\tfile.WriteString(\"Golang\")\n\n\tfile.Close()\n\n\tfile, _ = os.Open(file.Name())\n\tdefer file.Close()\n\n\tbuffer := make([]byte, 26)\n\tn, _ := file.Read(buffer)\n\n\tfmt.Println(string(buffer[:n]))\n}\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/go/qwik-zgheib.go",
    "content": "package main\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n/* extra */\nconst filename = \"sales.txt\"\n\ntype Product struct {\n\tName   string\n\tAmount int\n\tPrice  float64\n}\n\nfunc addProduct() {\n\tfmt.Print(\"Enter product name: \")\n\tscanner := bufio.NewScanner(os.Stdin)\n\tscanner.Scan()\n\tname := scanner.Text()\n\n\tfmt.Print(\"Enter amount sold: \")\n\tvar amount int\n\tfmt.Scan(&amount)\n\n\tfmt.Print(\"Enter price: \")\n\tvar price float64\n\tfmt.Scan(&price)\n\n\tproduct := fmt.Sprintf(\"%s, %d, %.2f\\n\", name, amount, price)\n\tfile, err := os.OpenFile(filename, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)\n\tif err != nil {\n\t\tfmt.Println(\"Error adding product:\", err)\n\t\treturn\n\t}\n\tdefer file.Close()\n\n\t_, err = file.WriteString(product)\n\tif err != nil {\n\t\tfmt.Println(\"Error writing to file:\", err)\n\t}\n}\n\nfunc viewProducts() {\n\tfile, err := os.Open(filename)\n\tif err != nil {\n\t\tfmt.Println(\"Error reading file:\", err)\n\t\treturn\n\t}\n\tdefer file.Close()\n\n\tscanner := bufio.NewScanner(file)\n\tfor scanner.Scan() {\n\t\tfmt.Println(scanner.Text())\n\t}\n\n\tif err := scanner.Err(); err != nil {\n\t\tfmt.Println(\"Error scanning file:\", err)\n\t}\n}\n\nfunc updateProduct() {\n\tproducts, err := readProducts()\n\tif err != nil {\n\t\tfmt.Println(\"Error reading products:\", err)\n\t\treturn\n\t}\n\n\tfmt.Print(\"Enter product name to update: \")\n\tscanner := bufio.NewScanner(os.Stdin)\n\tscanner.Scan()\n\tname := scanner.Text()\n\n\tfor i, product := range products {\n\t\tif product.Name == name {\n\t\t\tfmt.Print(\"Enter new amount sold: \")\n\t\t\tvar amount int\n\t\t\tfmt.Scan(&amount)\n\n\t\t\tfmt.Print(\"Enter new price: \")\n\t\t\tvar price float64\n\t\t\tfmt.Scan(&price)\n\n\t\t\tproducts[i].Amount = amount\n\t\t\tproducts[i].Price = price\n\n\t\t\tif err := writeProducts(products); err != nil {\n\t\t\t\tfmt.Println(\"Error updating product:\", err)\n\t\t\t} else {\n\t\t\t\tfmt.Println(\"Product updated successfully.\")\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t}\n\tfmt.Println(\"Product not found.\")\n}\n\nfunc deleteProduct() {\n\tproducts, err := readProducts()\n\tif err != nil {\n\t\tfmt.Println(\"Error reading products:\", err)\n\t\treturn\n\t}\n\n\tfmt.Print(\"Enter product name to delete: \")\n\tscanner := bufio.NewScanner(os.Stdin)\n\tscanner.Scan()\n\tname := scanner.Text()\n\n\tfor i, product := range products {\n\t\tif product.Name == name {\n\t\t\tproducts = append(products[:i], products[i+1:]...)\n\t\t\tif err := writeProducts(products); err != nil {\n\t\t\t\tfmt.Println(\"Error deleting product:\", err)\n\t\t\t} else {\n\t\t\t\tfmt.Println(\"Product deleted successfully.\")\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t}\n\tfmt.Println(\"Product not found.\")\n}\n\nfunc totalSales() {\n\tproducts, err := readProducts()\n\tif err != nil {\n\t\tfmt.Println(\"Error reading products:\", err)\n\t\treturn\n\t}\n\n\tvar total float64\n\tfor _, product := range products {\n\t\ttotal += float64(product.Amount) * product.Price\n\t}\n\tfmt.Printf(\"Total Sales: $%.2f\\n\", total)\n}\n\nfunc salesByProduct() {\n\tproducts, err := readProducts()\n\tif err != nil {\n\t\tfmt.Println(\"Error reading products:\", err)\n\t\treturn\n\t}\n\n\tfor _, product := range products {\n\t\ttotal := float64(product.Amount) * product.Price\n\t\tfmt.Printf(\"%s: $%.2f\\n\", product.Name, total)\n\t}\n}\n\nfunc exitProgram() {\n\terr := os.Remove(filename)\n\tif err != nil {\n\t\tfmt.Println(\"Error deleting file:\", err)\n\t} else {\n\t\tfmt.Println(\"File deleted successfully.\")\n\t}\n}\n\nfunc readProducts() ([]Product, error) {\n\tfile, err := os.Open(filename)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer file.Close()\n\n\tvar products []Product\n\tscanner := bufio.NewScanner(file)\n\tfor scanner.Scan() {\n\t\tline := scanner.Text()\n\t\tparts := strings.Split(line, \", \")\n\t\tif len(parts) != 3 {\n\t\t\tcontinue\n\t\t}\n\n\t\tamount, err := strconv.Atoi(parts[1])\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\n\t\tprice, err := strconv.ParseFloat(parts[2], 64)\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\n\t\tproduct := Product{\n\t\t\tName:   parts[0],\n\t\t\tAmount: amount,\n\t\t\tPrice:  price,\n\t\t}\n\t\tproducts = append(products, product)\n\t}\n\n\tif err := scanner.Err(); err != nil {\n\t\treturn nil, err\n\t}\n\treturn products, nil\n}\n\nfunc writeProducts(products []Product) error {\n\tfile, err := os.OpenFile(filename, os.O_TRUNC|os.O_CREATE|os.O_WRONLY, 0644)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer file.Close()\n\n\tfor _, product := range products {\n\t\tline := fmt.Sprintf(\"%s, %d, %.2f\\n\", product.Name, product.Amount, product.Price)\n\t\t_, err := file.WriteString(line)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc main() {\n\tusername := \"qwik-zgheib\"\n\tfilename := fmt.Sprintf(\"%s.txt\", username)\n\tcontent := \"Name: Isaias\\nAge: 22\\nFavorite Programming Language: Go\\n\"\n\n\terr := os.WriteFile(filename, []byte(content), 0644)\n\tif err != nil {\n\t\tfmt.Println(\"Error creating file:\", err)\n\t\treturn\n\t}\n\n\tdata, err := os.ReadFile(filename)\n\tif err != nil {\n\t\tfmt.Println(\"Error reading file:\", err)\n\t\treturn\n\t}\n\tfmt.Println(\"File Content:\")\n\tfmt.Println(string(data))\n\n\terr = os.Remove(filename)\n\tif err != nil {\n\t\tfmt.Println(\"Error deleting file:\", err)\n\t\treturn\n\t}\n\tfmt.Println(\"File deleted successfully.\")\n\n\t/* extra */\n\tfor {\n\t\tfmt.Println(\"1. Add Product\")\n\t\tfmt.Println(\"2. View Products\")\n\t\tfmt.Println(\"3. Update Product\")\n\t\tfmt.Println(\"4. Delete Product\")\n\t\tfmt.Println(\"5. Total Sales\")\n\t\tfmt.Println(\"6. Sales by Product\")\n\t\tfmt.Println(\"7. Exit\")\n\t\tfmt.Print(\"Choose an option: \")\n\n\t\tvar option int\n\t\tfmt.Scan(&option)\n\n\t\tswitch option {\n\t\tcase 1:\n\t\t\taddProduct()\n\t\tcase 2:\n\t\t\tviewProducts()\n\t\tcase 3:\n\t\t\tupdateProduct()\n\t\tcase 4:\n\t\t\tdeleteProduct()\n\t\tcase 5:\n\t\t\ttotalSales()\n\t\tcase 6:\n\t\t\tsalesByProduct()\n\t\tcase 7:\n\t\t\texitProgram()\n\t\t\treturn\n\t\tdefault:\n\t\t\tfmt.Println(\"Invalid option. Please try again.\")\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/go/raynerpv2022.go",
    "content": "package main\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un\n * archivo .txt.\n * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n */\nfunc CreateFile(name string) {\n\n\tfile, err := os.Create(name)\n\tif err != nil {\n\t\tfmt.Printf(\"Error creando el archivo %v\\n\", name)\n\t\treturn\n\t}\n\tdefer file.Close()\n\n\tfmt.Printf(\"Archivo creado: %v\\n\", file.Name())\n\tfile.WriteString(\"nombre : Rayner\\n\")\n\tfile.WriteString(\"edad : 45\\n\")\n\tfile.WriteString(\"Lenguaje favorito : Python y Go\\n\")\n\n}\n\nfunc ReadFile(name string) {\n\n\tfile, err := os.Open(name)\n\tif err != nil {\n\t\tfmt.Printf(\"Error abriendo el archivo %v\\n  \", name)\n\t\treturn\n\t}\n\tdefer file.Close()\n\tdatos, err := io.ReadAll(file)\n\tif err != nil {\n\t\tfmt.Printf(\"Error leyendo el archivo %v\", file.Name())\n\t}\n\tfmt.Printf(\"Datos del archivo %v\\n\", file.Name())\n\tfmt.Println(string(datos))\n}\n\nfunc RemoveFile(name string) {\n\terr := os.Remove((name))\n\tif err != nil {\n\t\tfmt.Printf(\"Error eliminando el archivo %v\\n\", name)\n\t\treturn\n\t}\n\n\tfmt.Printf(\"Archivo eliminado %v\\n\", name)\n\n}\n\n//                      EXTRA\n\nfunc CrearProducto(name string) {\n\tscanProductos := bufio.NewScanner(os.Stdin)\n\n\tf, err := os.OpenFile(name, os.O_RDWR|os.O_APPEND, 0666)\n\tif err != nil {\n\t\tfmt.Println(err)\n\t\treturn\n\t}\n\tdefer f.Close()\n\n\tfmt.Print(\"Nombre del Producto : \")\n\tscanProductos.Scan()\n\tnameP := scanProductos.Text()\n\n\tfmt.Print(\"Cantidad   : \")\n\tscanProductos.Scan()\n\tamountP := scanProductos.Text()\n\n\tfmt.Print(\"Precio   : \")\n\tscanProductos.Scan()\n\tpriceP := scanProductos.Text()\n\n\t_, err = f.WriteString(fmt.Sprintf(\"%v, %v, %v\\n\", nameP, amountP, priceP))\n\tif err != nil {\n\t\tfmt.Println(err)\n\t}\n\n}\n\nfunc MostrarTodo(name string) {\n\n\tf, err := os.Open(name)\n\tif err != nil {\n\t\tfmt.Println(err)\n\t\treturn\n\t}\n\tdefer f.Close()\n\tscanner := bufio.NewScanner(f)\n\tfor scanner.Scan() {\n\t\tfmt.Println(scanner.Text())\n\t}\n\n}\n\nfunc BUscarProducto(source string, prod string) string {\n\n\tif strings.Contains(source, prod) {\n\t\treturn source\n\n\t} else {\n\t\treturn \"\"\n\t}\n}\n\nfunc ConsultarProducto(name string) {\n\tf, err := os.Open(name)\n\tif err != nil {\n\t\tfmt.Println(err)\n\t\treturn\n\t}\n\tdefer f.Close()\n\n\tscanProductos := bufio.NewScanner(os.Stdin)\n\tfmt.Print(\"Nombre del Producto : \")\n\tscanProductos.Scan()\n\tnameP := scanProductos.Text()\n\n\tscanner := bufio.NewScanner(f)\n\tfor scanner.Scan() {\n\t\tFoundP := BUscarProducto(scanner.Text(), nameP)\n\t\tif FoundP != \"\" {\n\t\t\tfmt.Println(FoundP)\n\t\t\treturn\n\t\t}\n\n\t}\n\tfmt.Println(\"Producto no encontrado\")\n\n}\n\n// misma fun para actualizar y eliminar, opcion 4 es actualizar y 5 eleminar\nfunc ActualizarP(name string, opcion int) {\n\tf1, err := os.Open(name)\n\tif err != nil {\n\t\tfmt.Println(err)\n\t}\n\n\tscanner := bufio.NewScanner(f1)\n\n\tf2, err := os.OpenFile(\"TempF.txt\", os.O_RDWR|os.O_CREATE, 0666)\n\tif err != nil {\n\t\tfmt.Println(err)\n\t\treturn\n\t}\n\n\tscanProductos := bufio.NewScanner(os.Stdin)\n\tfmt.Print(\"Nombre del Producto : \")\n\tscanProductos.Scan()\n\tnameP := scanProductos.Text()\n\tPF := false\n\tfor scanner.Scan() {\n\t\tFoundP := BUscarProducto(scanner.Text(), nameP)\n\t\tif FoundP == \"\" {\n\n\t\t\tf2.WriteString(fmt.Sprintf(\"%v\\n\", scanner.Text()))\n\t\t} else {\n\n\t\t\t// si opcion es 4 actualiza\n\t\t\tif opcion == 4 {\n\n\t\t\t\tPF = true\n\t\t\t\tfmt.Print(\"Cantidad   : \")\n\t\t\t\tscanProductos.Scan()\n\t\t\t\tamountP := scanProductos.Text()\n\n\t\t\t\tfmt.Print(\"Precio   : \")\n\t\t\t\tscanProductos.Scan()\n\t\t\t\tpriceP := scanProductos.Text()\n\n\t\t\t\t_, err = f2.WriteString(fmt.Sprintf(\"%v, %v, %v\\n\", nameP, amountP, priceP))\n\t\t\t\tif err != nil {\n\t\t\t\t\tfmt.Println(err)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// si opcion no es 4 entonces no escribe nada, elimina el que encontro\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t}\n\t}\n\tif !PF {\n\t\tfmt.Println(\"Producto No encontrado\")\n\t}\n\tf1.Close()\n\tf2.Close()\n\n\terr1 := os.Rename(f2.Name(), f1.Name())\n\tif err1 != nil {\n\t\tfmt.Println(err)\n\t}\n}\n\nfunc Ventas(name string) {\n\tf, err := os.Open(name)\n\tif err != nil {\n\t\tfmt.Println(err)\n\t\treturn\n\t}\n\tdefer f.Close()\n\tscanner := bufio.NewScanner(f)\n\ttotal := 0\n\tfor scanner.Scan() {\n\t\tamount, _ := strconv.Atoi(strings.Split(scanner.Text(), \", \")[1])\n\t\tprice, _ := strconv.Atoi(strings.Split(scanner.Text(), \", \")[2])\n\t\ttotal += amount * price\n\n\t}\n\tfmt.Println(\"Ventas totales   : \", total)\n}\n\nfunc VentasP(name string) {\n\tf, err := os.Open(name)\n\tif err != nil {\n\t\tfmt.Println(err)\n\t\treturn\n\t}\n\tdefer f.Close()\n\tscanner := bufio.NewScanner(f)\n\tscanProductos := bufio.NewScanner(os.Stdin)\n\tfmt.Print(\"Nombre del Producto : \")\n\tscanProductos.Scan()\n\tnameP := scanProductos.Text()\n\tfor scanner.Scan() {\n\t\tfound := BUscarProducto(scanner.Text(), nameP)\n\t\tif found != \"\" {\n\t\t\tamount, _ := strconv.Atoi(strings.Split(scanner.Text(), \", \")[1])\n\t\t\tprice, _ := strconv.Atoi(strings.Split(scanner.Text(), \", \")[2])\n\t\t\tfmt.Printf(\"Ventas totales del Producto %v : %v\\n\", nameP, amount*price)\n\t\t\treturn\n\t\t}\n\n\t}\n\tfmt.Println(\"Producto no encontrado\")\n\n}\n\nfunc Gestion() {\n\tname_file := \"gestion.txt\"\n\tfor {\n\n\t\tfmt.Println(\"*********** Gestión de Ventas por Productos ***********\")\n\t\tfmt.Println(\"1 - Añadir\")\n\t\tfmt.Println(\"2 - Consultar un producto\")\n\t\tfmt.Println(\"3 - Mostrar todos\")\n\t\tfmt.Println(\"4 - Actualizar\")\n\t\tfmt.Println(\"5 - Eliminar\")\n\t\tfmt.Println(\"6 - Ventas totales\")\n\t\tfmt.Println(\"7 - Ventas totales por producto\")\n\t\tfmt.Println(\"8 - Salir\")\n\t\tscannerOp := bufio.NewScanner(os.Stdin)\n\t\tscannerOp.Scan()\n\t\top := strings.TrimSpace(scannerOp.Text())\n\t\tswitch op {\n\t\tcase \"1\":\n\t\t\tfmt.Println(\"Añadir producto\")\n\t\t\tfmt.Println()\n\t\t\tCrearProducto(name_file)\n\n\t\tcase \"2\":\n\t\t\tfmt.Println(\"Consultar un producto\")\n\t\t\tfmt.Println()\n\t\t\tConsultarProducto((name_file))\n\n\t\tcase \"3\":\n\t\t\tfmt.Println(\"Mostrar todos\")\n\t\t\tfmt.Println()\n\t\t\tMostrarTodo((name_file))\n\n\t\tcase \"4\":\n\t\t\tfmt.Println(\"Actualizar\")\n\t\t\tfmt.Println()\n\n\t\t\tActualizarP(name_file, 4)\n\n\t\tcase \"5\":\n\t\t\tfmt.Println(\"Eliminar\")\n\t\t\tfmt.Println()\n\t\t\tActualizarP(name_file, 5)\n\n\t\tcase \"6\":\n\t\t\tfmt.Println(\"Ventas totales\")\n\t\t\tfmt.Println()\n\t\t\tVentas(name_file)\n\n\t\tcase \"7\":\n\t\t\tfmt.Println(\"Ventas totales por producto\")\n\t\t\tfmt.Println()\n\t\t\tVentasP(name_file)\n\n\t\tcase \"8\":\n\t\t\tfmt.Println(\"Salir\")\n\t\t\tfmt.Println()\n\t\t\tfmt.Println(\"Se eliminara el archivo creado\")\n\t\t\t// err := os.Remove(name_file)\n\t\t\t// if err != nil {\n\t\t\t// \tfmt.Println(err)\n\n\t\t\t// }\n\n\t\t\treturn\n\t\tdefault:\n\t\t\tfmt.Println(\"Opción inválida, por favor seleccione una opción entre 1 y 8.\")\n\t\t}\n\n\t\tfmt.Println()\n\t}\n\n}\nfunc main() {\n\tfmt.Println(\"EJERCICIO RETO 11, MANEJO ARCHIVOS\")\n\tfmt.Println()\n\tname := \"raynerpv2022.txt\"\n\tCreateFile(name)\n\tReadFile(name)\n\tRemoveFile(name)\n\n\tGestion()\n}\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/go/thegera4.go",
    "content": "package main\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\t\"time\"\n)\n\nfunc main() {\n\n\tcrearLeerBorrarArchivo()\n\n\t//Extra: Programa de gestión de ventas\n\tgestionVentas()\n}\n\nfunc crearLeerBorrarArchivo() {\n\t// Crear el archivo con el nombre de usuario de GitHub\n\tfile, err := os.Create(\"thegera4.txt\")\n\tif err != nil {\n\t\tfmt.Println(\"Error al crear el archivo:\", err)\n\t\treturn\n\t}\n\n\t// Escribimos en el archivo\n\t_, err = file.WriteString(\"Hola, mi nombrer es Gerardo.\\n\")\n\tif err != nil {\n\t\tfmt.Println(\"Error al escribir en el archivo:\", err)\n\t\treturn\n\t}\n\t_, err = file.WriteString(\"Tengo 36 años.\\n\")\n\tif err != nil {\n\t\tfmt.Println(\"Error al escribir en el archivo:\", err)\n\t\treturn\n\t}\n\t_, err = file.WriteString(\"Mi lenguaje favorito al dia de hoy es Go.\\n\")\n\tif err != nil {\n\t\tfmt.Println(\"Error al escribir en el archivo:\", err)\n\t\treturn\n\t}\n\n\tfile.Close() // Cerramos el archivo\n\n\t// Leemos el archivo\n\tfile, err = os.Open(\"thegera4.txt\")\n\tif err != nil {\n\t\tfmt.Println(\"Error al abrir el archivo:\", err)\n\t\treturn\n\t}\n\n\t// Imprimimos el contenido\n\tscanner := bufio.NewScanner(file)\n\tfor scanner.Scan() {\n\t\tfmt.Println(scanner.Text())\n\t}\n\n\tfile.Close() // Cerramos el archivo despues de leerlo y mostrarlo para poder borrarlo, si no lo cerramos no se puede borrar.\n\n\t// Borramos el archivo al teclear una tecla\n\tfmt.Println(\"Pulsa cualquier tecla y luego 'Enter' para borrar el archivo...\")\n\tfmt.Scanln()\n\n\terr = os.Remove(\"thegera4.txt\")\n\tif err != nil {\n\t\tfmt.Println(\"Error al borrar el archivo:\", err)\n\t\treturn\n\t}\n\n\tfmt.Println(\"Archivo borrado con éxito.\")\n\n\t// Esperamos 2 segundos antes de finalizar el programa\n\ttime.Sleep(2 * time.Second)\n\n\tfmt.Println(\"Programa finalizado.\")\n}\n\nfunc gestionVentas() { \n\n\t//si no existe el archivo \"ventas.txt\" lo crea\n\tif _, err := os.Stat(\"ventas.txt\"); os.IsNotExist(err) {\n\t\tcrearArchivoVentas()\n\t}\n\n\tfor{\n\t\tvar opcion int\n\n\t\tfmt.Println(\"Bienvenido al sistema de gestión de ventas. Porfavor selecciona una opción:\")\n\t\tfmt.Println(\"1. Añadir producto\")\n\t\tfmt.Println(\"2. Consultar ventas\")\n\t\tfmt.Println(\"3. Actualizar ventas\")\n\t\tfmt.Println(\"4. Eliminar producto\")\n\t\tfmt.Println(\"5. Venta total\")\n\t\tfmt.Println(\"6. Venta por producto\")\n\t\tfmt.Println(\"7. Salir\")\n\n\t\tfmt.Scanln(&opcion)\n\n\t\tswitch opcion {\n\t\t\t\tcase 1:\n\t\t\t\t\tagregarProducto()\n\t\t\t\tcase 2:\n\t\t\t\t\tconsultarVentas()\n\t\t\t\tcase 3:\n\t\t\t\t\tactualizarVentas()\n\t\t\t\tcase 4:\n\t\t\t\t\tborrarVenta()\n\t\t\t\tcase 5:\n\t\t\t\t\tcalcularVentaTotal()\n\t\t\t\tcase 6:\n\t\t\t\t\tcalcularVentaPorProducto()\n\t\t\t\tcase 7:\n\t\t\t\t\tcerrarBorrarArchivo()\n\t\t\t\tdefault:\n\t\t\t\t\tfmt.Println(\"Opción no válida\")\n\t\t}\n\t}\n}\n\nfunc crearArchivoVentas() {\n\tfile, err := os.Create(\"ventas.txt\")\n\tif err != nil {\n\t\tfmt.Println(\"Error al crear el archivo:\", err)\n\t\treturn\n\t}\n\tfile.Close()\n}\n\nfunc agregarProducto() {\n\tfile, err := os.OpenFile(\"ventas.txt\", os.O_APPEND|os.O_WRONLY, 0644)\n\tif err != nil {\n\t\tfmt.Println(\"Error al abrir el archivo:\", err)\n\t\treturn\n\t}\n\tdefer file.Close()\n\n\tvar nombre string\n\tvar cantidad int\n\tvar precio float64\n\n\tfmt.Println(\"Introduce el nombre del producto:\")\n\tfmt.Scanln(&nombre)\n\n\tfmt.Println(\"Introduce la cantidad vendida:\")\n\tfmt.Scanln(&cantidad)\n\n\tfmt.Println(\"Introduce el precio:\")\n\tfmt.Scanln(&precio)\n\n\t_, err = file.WriteString(fmt.Sprintf(\"%s, %d, %.2f\\n\", nombre, cantidad, precio))\n\tif err != nil {\n\t\tfmt.Println(\"Error al escribir en el archivo:\", err)\n\t\treturn\n\t}\n\n\tfmt.Println(\"Producto añadido con éxito\")\n}\n\nfunc consultarVentas() {\n\tfmt.Println(\"Productos vendidos:\")\n\n\tfile, err := os.Open(\"ventas.txt\")\n\tif err != nil {\n\t\tfmt.Println(\"Error al abrir el archivo:\", err)\n\t\treturn\n\t}\n\tdefer file.Close()\n\n\tscanner := bufio.NewScanner(file)\n\tfor scanner.Scan() {\n\t\tfmt.Println(scanner.Text())\n\t}\n}\n\nfunc actualizarVentas() {\n\tfmt.Println(\"Introduce el nombre del producto a actualizar:\")\n\tvar nombre string\n\tfmt.Scanln(&nombre)\n\n\t// Abrir el archivo para lectura y escritura\n\tfile, err := os.OpenFile(\"ventas.txt\", os.O_RDWR, 0644)\n\tif err != nil {\n\t\tfmt.Println(\"Error al abrir el archivo:\", err)\n\t\treturn\n\t}\n\tdefer file.Close()\n\n\t// Leer todas las líneas y actualizar la línea correspondiente\n\tvar lines []string\n\tscanner := bufio.NewScanner(file)\n\tfor scanner.Scan() {\n\t\tlinea := scanner.Text()\n\t\tdatos := strings.Split(linea, \", \")\n\t\tif len(datos) >= 3 && datos[0] == nombre {\n\t\t\tfmt.Println(\"Venta encontrada:\", linea)\n\n\t\t\tvar cantidad int\n\t\t\tvar precio float64\n\n\t\t\tfmt.Println(\"Introduce la nueva cantidad vendida:\")\n\t\t\tfmt.Scanln(&cantidad)\n\n\t\t\tfmt.Println(\"Introduce el nuevo precio:\")\n\t\t\tfmt.Scanln(&precio)\n\n\t\t\t// Actualizar la línea\n\t\t\tlinea = fmt.Sprintf(\"%s, %d, %.2f\", nombre, cantidad, precio)\n\t\t}\n\t\tlines = append(lines, linea)\n\t}\n\n\t// Rebobinar el archivo y truncar para escribir desde el principio\n\tfile.Seek(0, 0)\n\tfile.Truncate(0)\n\n\t// Escribir todas las líneas actualizadas al archivo\n\tfor _, line := range lines {\n\t\t_, err := file.WriteString(line + \"\\n\")\n\t\tif err != nil {\n\t\t\tfmt.Println(\"Error al escribir en el archivo:\", err)\n\t\t\treturn\n\t\t}\n\t}\n\n\tfmt.Println(\"Venta actualizada con éxito\")\n}\n\nfunc borrarVenta() {\n\tfmt.Println(\"Introduce el nombre del producto:\")\n\tvar nombre string\n\tfmt.Scanln(&nombre)\n\n\t// Abrir el archivo para lectura y escritura\n\tfile, err := os.OpenFile(\"ventas.txt\", os.O_RDWR, 0644)\n\tif err != nil {\n\t\tfmt.Println(\"Error al abrir el archivo:\", err)\n\t\treturn\n\t}\n\tdefer file.Close()\n\n\t// Leer todas las líneas y eliminar la línea correspondiente\n\tvar lines []string\n\tscanner := bufio.NewScanner(file)\n\tfor scanner.Scan() {\n\t\tlinea := scanner.Text()\n\t\tdatos := strings.Split(linea, \", \")\n\t\tif len(datos) >= 3 && datos[0] == nombre {\n\t\t\tfmt.Println(\"Venta encontrada y eliminada:\", linea)\n\t\t\tcontinue\n\t\t}\n\t\tlines = append(lines, linea)\n\t}\n\n\t// Rebobinar el archivo y truncar para escribir desde el principio\n\tfile.Seek(0, 0)\n\tfile.Truncate(0)\n\n\t// Escribir todas las líneas actualizadas al archivo\n\tfor _, line := range lines {\n\t\t_, err := file.WriteString(line + \"\\n\")\n\t\tif err != nil {\n\t\t\tfmt.Println(\"Error al escribir en el archivo:\", err)\n\t\t\treturn\n\t\t}\n\t}\n\n\tfmt.Println(\"Venta eliminada con éxito\")\n}\n\nfunc calcularVentaTotal() {\n\tfile, err := os.Open(\"ventas.txt\")\n\tif err != nil {\n\t\tfmt.Println(\"Error al abrir el archivo:\", err)\n\t\treturn\n\t}\n\tdefer file.Close()\n\n\tvar total float64\n\tscanner := bufio.NewScanner(file)\n\tfor scanner.Scan() {\n\t\tlinea := scanner.Text()\n\t\tdatos := strings.Split(linea, \", \")\n\t\tif len(datos) >= 3 {\n\t\t\tcantidad := 0\n\t\t\tprecio := 0.0\n\t\t\tfmt.Sscanf(datos[1], \"%d\", &cantidad)\n\t\t\tfmt.Sscanf(datos[2], \"%f\", &precio)\n\t\t\ttotal += float64(cantidad) * precio\n\t\t}\n\t}\n\n\tfmt.Printf(\"Venta total actual: %.2f\\n\", total)\n}\n\nfunc calcularVentaPorProducto() {\n\tfmt.Println(\"Introduce el nombre del producto:\")\n\tvar nombre string\n\tfmt.Scanln(&nombre)\n\n\tfile, err := os.Open(\"ventas.txt\")\n\tif err != nil {\n\t\tfmt.Println(\"Error al abrir el archivo:\", err)\n\t\treturn\n\t}\n\tdefer file.Close()\n\n\tscanner := bufio.NewScanner(file)\n\tfor scanner.Scan() {\n\t\tlinea := scanner.Text()\n\t\tdatos := strings.Split(linea, \", \")\n\t\tif len(datos) >= 3 && datos[0] == nombre {\n\t\t\tcantidad := 0\n\t\t\tprecio := 0.0\n\t\t\tfmt.Sscanf(datos[1], \"%d\", &cantidad)\n\t\t\tfmt.Sscanf(datos[2], \"%f\", &precio)\n\t\t\tfmt.Printf(\"Venta de %s: %.2f\\n\", nombre, float64(cantidad) * precio)\n\t\t\treturn\n\t\t}\n\t}\n\n\tfmt.Println(\"Producto no encontrado\")\n}\n\nfunc cerrarBorrarArchivo() {\n\tfmt.Println(\"Estas seguro de que deseas salir? s/n\")\n\n\tvar respuesta string\n\tfmt.Scanln(&respuesta)\n\n\tif respuesta != \"s\" {\n\t\treturn\n\t}\n\n\terr := os.Remove(\"ventas.txt\")\n\tif err != nil {\n\t\tfmt.Println(\"Error al borrar el archivo:\", err)\n\t\treturn\n\t}\n\n\tfmt.Println(\"Archivo borrado con éxito...Cerrando el programa...\")\n\tos.Exit(0)\n}"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/java/Abel-ADE.java",
    "content": "public class Main {\n    public static void main(String[] args) {\n\n        File file = new File(\"src/data.txt\");\n        FileWriter writer;\n        Scanner reader;\n\n        try {\n            //Creamos el fichero\n            file.createNewFile();\n\n            //Escribimos los datos\n            writer = new FileWriter(file);\n\n            writer.append(\"Nombre: Abel\\n\");\n            writer.append(\"Edad: 30\\n\");\n            writer.append(\"Lenguaje de programación: Java\\n\");\n\n            writer.close();\n\n            //Leemos el contenido\n            reader = new Scanner(file);\n\n            System.out.println(\"Contenido del fichero: \");\n\n            while (reader.hasNext()) {\n                String line = reader.nextLine();\n                System.out.println(line);\n            }\n\n            reader.close();\n\n            //Borramos el fichero\n            file.delete();\n\n        } catch (IOException e) {\n            System.out.println(\"Error con el archivo\");\n        }\n\n        System.out.println(\"\\n-------DIFICULTAD EXTRA------\\n\");\n\n        boolean exit = false;\n        Scanner scanner = new Scanner(System.in);\n        File venta = new File(\"src/venta.txt\");\n        try {\n            if (!venta.exists()) {\n                venta.createNewFile();\n            }\n        } catch (IOException e) {\n            System.out.println(\"Error al crear el archivo\\n\");\n        }\n        do {\n            System.out.println(\"Bienvenido al programa de ventas!\\n\");\n            System.out.println(\"¿Qué deseas hacer?\");\n            System.out.println(\"1- Añadir un producto\");\n            System.out.println(\"2- Eliminar un producto\");\n            System.out.println(\"3- Buscar un producto\");\n            System.out.println(\"4- Actualizar un producto\");\n            System.out.println(\"5- Calcular precio de un producto\");\n            System.out.println(\"6- Calcular precio de venta total\");\n            System.out.println(\"7- Salir\\n\");\n\n            System.out.print(\"Introduzca una opcion: \");\n            int option = scanner.nextInt();\n            scanner.nextLine();\n            System.out.println();\n\n            switch (option) {\n                case 1:\n                    try {\n                        System.out.println(\"Vamos a añadir un producto!\\n\");\n                        System.out.print(\"Introduce el nombre: \");\n                        String name = scanner.nextLine();\n\n                        System.out.print(\"Introduce la cantidad vendida: \");\n                        int amount = scanner.nextInt();\n                        scanner.nextLine();\n\n                        System.out.print(\"Introduce el precio: \");\n                        double precio = scanner.nextDouble();\n                        scanner.nextLine();\n\n                        FileWriter writerVenta = new FileWriter(venta, true);\n                        writerVenta.append(name + \", \" + amount + \", \" + precio + \"\\n\");\n                        writerVenta.close();\n                    } catch (IOException e) {\n                        System.out.println(\"Error al escribir el archivo\\n\");\n                    }\n                    break;\n                case 2:\n                    System.out.println(\"Vamos a eliminar un producto!\\n\");\n\n                    System.out.print(\"Introduce el nombre: \");\n                    String nameDelete = scanner.nextLine();\n\n                    ArrayList<String> products = new ArrayList<>();\n                    try {\n                        boolean exist = false;\n                        Scanner readerVenta = new Scanner(venta);\n\n                        while (readerVenta.hasNext()) {\n                            String product = readerVenta.nextLine();\n                            products.add(product);\n                            if (product.contains(nameDelete)) {\n                                exist = true;\n                            }\n                        }\n\n                        if (exist) {\n                            //Eliminamos el producto de la lista\n                            for (int i = 0; i < products.size(); i++) {\n                                if (products.get(i).contains(nameDelete)) {\n                                    products.remove(i);\n                                }\n                            }\n                        } else {\n                            System.out.println(\"No existe el producto\");\n                        }\n\n                        readerVenta.close();\n                    } catch (FileNotFoundException e) {\n                        System.out.println(\"Error al leer el archivo\\n\");\n                    }\n\n                    try {\n                        FileWriter writeProducts = new FileWriter(venta, false);\n                        for (String product : products) {\n                            writeProducts.append(product + \"\\n\");\n                        }\n                        writeProducts.close();\n                    } catch (IOException e) {\n                        System.out.println(\"Error al escribir el archivo\\n\");\n                    }\n                    break;\n                case 3:\n                    System.out.println(\"Vamos a buscar un producto!\\n\");\n\n                    System.out.print(\"Introduce el nombre: \");\n                    String name = scanner.nextLine();\n\n                    try {\n                        boolean exist = false;\n                        Scanner readerVenta = new Scanner(venta);\n                        String line = null;\n                        while (readerVenta.hasNext() && !exist) {\n                            line = readerVenta.nextLine();\n                            if (line.contains(name)) {\n                                exist = true;\n                            }\n                        }\n\n                        if (exist) {\n                            System.out.println(\"\\nEstos son los datos del producto: \");\n                            System.out.println(line + \"\\n\");\n                        } else {\n                            System.out.println(\"No existe el producto\\n\");\n                        }\n                        readerVenta.close();\n                    } catch (FileNotFoundException e) {\n                        System.out.println(\"Error al leer el archivo\\n\");\n                    }\n                    break;\n                case 4:\n                    System.out.println(\"Vamos a actualizar un producto!\\n\");\n\n                    System.out.print(\"Introduce el nombre (original): \");\n                    String lastName = scanner.nextLine();\n\n                    ArrayList<String> productsUpdate = new ArrayList<>();\n                    try {\n                        boolean exist = false;\n                        Scanner readerVenta = new Scanner(venta);\n\n                        while (readerVenta.hasNext()) {\n                            String product = readerVenta.nextLine();\n                            productsUpdate.add(product);\n                            if (product.contains(lastName)) {\n                                exist = true;\n                            }\n                        }\n\n                        if (exist) {\n                            System.out.print(\"Introduce el nombre (nuevo): \");\n                            String nameUpdate = scanner.nextLine();\n\n                            System.out.print(\"Introduce la cantidad (nueva): \");\n                            int amountUpdate = scanner.nextInt();\n                            scanner.nextLine();\n\n                            System.out.print(\"Introduce el nuevo precio (nuevo): \");\n                            double priceUpdate = scanner.nextDouble();\n                            scanner.nextLine();\n\n                            //Actualizamos el producto de la lista\n                            for (int i = 0; i < productsUpdate.size(); i++) {\n                                if (productsUpdate.get(i).contains(lastName)) {\n                                    productsUpdate.set(i,nameUpdate+\", \"+amountUpdate+\", \"+priceUpdate);\n                                }\n                            }\n                        } else {\n                            System.out.println(\"No existe el producto\");\n                        }\n\n                        readerVenta.close();\n                    } catch (FileNotFoundException e) {\n                        System.out.println(\"Error al leer el archivo\\n\");\n                    }\n\n                    try {\n                        FileWriter writeProducts = new FileWriter(venta, false);\n                        for (String product : productsUpdate) {\n                            writeProducts.append(product + \"\\n\");\n                        }\n                        writeProducts.close();\n                    } catch (IOException e) {\n                        System.out.println(\"Error al escribir el archivo\\n\");\n                    }\n                    break;\n                case 5:\n                    System.out.println(\"Vamos a calcular el precio de un producto!\\n\");\n\n                    System.out.print(\"Introduce el nombre: \");\n                    String nameProductPrice = scanner.nextLine();\n\n                    Scanner readProduct = null;\n                    try {\n                        readProduct = new Scanner(venta);\n                    } catch (FileNotFoundException e) {\n                        System.out.println(\"Error al leer el archivo\\n\");\n                    }\n                    String product = \"\";\n                    boolean exist = false;\n                    while (readProduct.hasNext() && !exist) {\n                        product = readProduct.nextLine();\n                        if (product.contains(nameProductPrice)) {\n                            exist = true;\n                        }\n                    }\n\n                    int amountProduct = Integer.parseInt(product.substring((product.indexOf(',')+2),product.lastIndexOf(',')));\n                    Double priceProduct = Double.valueOf(product.substring(product.lastIndexOf(\",\")+2));\n                    System.out.println(\"\\nEl precio total del producto es: \" + (priceProduct*amountProduct)+\"\\n\");\n\n                    break;\n                case 6:\n                    System.out.println(\"Vamos a calcular el precio total!\\n\");\n\n                    Scanner readProductPrice = null;\n                    try {\n                        readProductPrice = new Scanner(venta);\n                    } catch (FileNotFoundException e) {\n                        System.out.println(\"Error al leer el archivo\\n\");\n                    }\n\n                    int sum = 0;\n                    while (readProductPrice.hasNext()) {\n                        String prod = readProductPrice.nextLine();\n                        int amount = Integer.parseInt(prod.substring((prod.indexOf(',')+2),prod.lastIndexOf(',')));\n                        Double price = Double.valueOf(prod.substring(prod.lastIndexOf(\",\")+2));\n                        sum += amount*price;\n                    }\n\n                    System.out.println(\"El precio total de la venta es: \" + sum +\"\\n\");\n\n                    readProductPrice.close();\n                    break;\n                case 7:\n                    if (venta.exists()) {\n                        venta.delete();\n                    }\n                    exit = true;\n                    break;\n                default:\n                    System.out.println(\"Opcion no valida!\\n\");\n            }\n        } while (!exit);\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/java/AmadorQuispe.java",
    "content": "import java.io.IOException;\nimport java.math.BigDecimal;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.StandardOpenOption;\nimport java.text.DecimalFormat;\nimport java.util.List;\nimport java.util.Scanner;\n\npublic class ManagerFile {\n    public static void main(String[] args) {\n        try {\n            basic();\n            extra();\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n\n    }\n\n    /*\n     * EJERCICIO:\n     * Desarrolla un programa capaz de crear un archivo que se llame como\n     * tu usuario de GitHub y tenga la extensión .txt.\n     * Añade varias líneas en ese fichero:\n     * - Tu nombre.\n     * - Edad.\n     * - Lenguaje de programación favorito.\n     * Imprime el contenido.\n     * Borra el fichero.\n     * \n     */\n    private static void basic() throws IOException {\n        Path path = Path.of(\"AmadorQuispe.txt\");\n        if (!Files.exists(path)) {\n            Files.createFile(path);\n        }\n        String content = \"\"\"\n                Nombre                             : Amador Quispe\n                Edad                               : 31 Años\n                Lenguaje de Programación Favorito  : Java\n                \"\"\";\n        Files.writeString(path, content);\n        List<String> data = Files.readAllLines(path);\n        data.forEach(System.out::println);\n        Files.delete(path);\n    }\n\n    /*\n     * DIFICULTAD EXTRA (opcional):\n     * Desarrolla un programa de gestión de ventas que almacena sus datos en un\n     * archivo .txt.\n     * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n     * [nombre_producto], [cantidad_vendida], [precio].\n     * - Siguiendo ese formato, y mediante terminal, debe permitir añadir,\n     * consultar,\n     * actualizar, eliminar productos y salir.\n     * - También debe poseer opciones para calcular la venta total y por producto.\n     * - La opción salir borra el .txt.\n     */\n    private static void extra() throws IOException {\n        Path path = Path.of(\"sales.txt\");\n        if (!Files.exists(path)) {\n            path = Files.createFile(path);\n        }\n\n        SalesManager salesManager = new SalesManager(path);\n        salesManager.init();\n    }\n\n}\n\n/**\n * SalesManager\n */\nclass SalesManager {\n    private Path path;\n    private Scanner scanner;\n    private String regex;\n\n    public SalesManager(Path path) {\n        this.path = path;\n        this.scanner = new Scanner(System.in);\n        this.regex = \"^(\\\\w+)\\\\|(\\\\d+(\\\\.\\\\d+)?)\\\\|(\\\\d+(\\\\.\\\\d+)?)$\";\n    }\n\n    public void init() {\n        boolean exit = false;\n        int opt = 0;\n        while (!exit) {\n            System.out.println(\"--------------------------------\");\n            System.out.println(\"-------------OPCIONES------------\");\n            System.out.println(\"--------------------------------\");\n            System.out.println(\"1 - Mostrar todos los productos\");\n            System.out.println(\"2 - Añadir producto\");\n            System.out.println(\"3 - Consultar producto\");\n            System.out.println(\"4 - Actualizar producto\");\n            System.out.println(\"5 - Eliminar producto\");\n            System.out.println(\"6 - Calcular venta total\");\n            System.out.println(\"7 - Calcular venta total por producto\");\n            System.out.println(\"8 - Salir\");\n            System.out.print(\"\\nElija la operación a realizar: \");\n\n            if (scanner.hasNextInt()) {\n                opt = scanner.nextInt();\n            }\n\n            switch (opt) {\n                case 1:\n                    try (Scanner sc = new Scanner(path)) {\n                        while (sc.hasNext()) {\n                            System.out.println(sc.next());\n                        }\n                    } catch (Exception e) {\n                        e.printStackTrace();\n                    }\n                    break;\n                case 2:\n                    StringBuffer line = new StringBuffer();\n                    System.out.print(\"Ingrese el nombre del producto: \");\n                    line.append(scanner.next()).append(\"|\");\n                    System.out.print(\"Ingrese la cantidad vendida: \");\n                    line.append(scanner.next()).append(\"|\");\n                    System.out.print(\"Ingrese el precio: \");\n                    line.append(scanner.next());\n                    addProduct(line.toString());\n                    break;\n                case 3:\n                    System.out.print(\"Ingrese el nombre del producto a buscar: \");\n                    String search = scanner.next();\n                    searchProduct(search);\n                    break;\n                case 4:\n                    // TODO : En caso no exista\n                    StringBuffer lineUpdate = new StringBuffer();\n                    System.out.print(\"Ingrese el nombre del producto a modificar: \");\n                    String nameProductUpdate = scanner.next();\n                    System.out.print(\"Ingrese el nuevo nombre del producto: \");\n                    lineUpdate.append(scanner.next()).append(\"|\");\n                    System.out.print(\"Ingrese la nueva cantidad vendida: \");\n                    lineUpdate.append(scanner.next()).append(\"|\");\n                    System.out.print(\"Ingrese el nuevo precio: \");\n                    lineUpdate.append(scanner.next());\n                    updateProduct(nameProductUpdate, lineUpdate.toString());\n                    break;\n                case 5:\n                    System.out.print(\"Ingrese el nombre del producto a eliminar: \");\n                    String nameProductDelete = scanner.next();\n                    deleteProduct(nameProductDelete);\n                    break;\n                case 6:\n                    totalSales();\n                    break;\n                case 7:\n                    salesPerProduct();\n                    break;\n                case 8:\n                    exit = true;\n                    destroy();\n                    break;\n                default:\n                    System.out.println(\"\\nNo se reconoce el comando, inténtelo de nuevo\");\n                    init();\n                    break;\n            }\n        }\n    }\n\n    private void addProduct(String line) {\n        try {\n            if (!line.matches(regex)) {\n                System.out.println(\"El formato no es correcto\");\n                return;\n            }\n            Files.writeString(path, line + \"\\n\", StandardOpenOption.APPEND);\n\n        } catch (IOException e) {\n            System.out.println(\"Error al insertar el producto \");\n        }\n    }\n\n    private void searchProduct(String productName) {\n        try (Scanner read = new Scanner(path)) {\n            read.useDelimiter(\"\\n\");\n            while (read.hasNext()) {\n                String next = read.next();\n                String[] parts = next.split(\"\\\\|\");\n                if (parts[0].equalsIgnoreCase(productName)) {\n                    System.out.println(\"\\nProductos encontrados: \" + productName);\n                    System.out.println(\"Nombre producto | Cant. Vendida | Precio\");\n                    System.out.println(\"-> \" + next);\n                }\n            }\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n    }\n\n    private void updateProduct(String productName, String updateLine) {\n        StringBuilder content = new StringBuilder();\n        try (Scanner read = new Scanner(path)) {\n            read.useDelimiter(\"\\n\");\n            while (read.hasNext()) {\n                String next = read.next();\n                String[] parts = next.split(\"\\\\|\");\n                if (parts[0].equals(productName)) {\n                    content.append(updateLine).append(\"\\n\");\n                } else {\n                    content.append(next).append(\"\\n\");\n                }\n            }\n            Files.writeString(path, content.toString());\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n    }\n\n    private void deleteProduct(String productName) {\n        StringBuilder content = new StringBuilder();\n        try (Scanner read = new Scanner(path)) {\n            read.useDelimiter(\"\\n\");\n            while (read.hasNext()) {\n                String next = read.next();\n                String[] parts = next.split(\"\\\\|\");\n                if (!parts[0].equals(productName)) {\n                    content.append(next).append(\"\\n\");\n                }\n            }\n            Files.writeString(path, content.toString());\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n    }\n\n    private void totalSales() {\n        BigDecimal total = new BigDecimal(0);\n        try (Scanner read = new Scanner(path)) {\n            read.useDelimiter(\"\\n\");\n            while (read.hasNext()) {\n                String next = read.next();\n                String[] parts = next.split(\"\\\\|\");\n                double price = Double.parseDouble(parts[2]);\n                int quantity = Integer.parseInt(parts[1]);\n                total = total.add(BigDecimal.valueOf(price * quantity));\n            }\n            System.out.println(\"TOTAL VENTAS :\" + total.doubleValue());\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n    }\n\n    private void salesPerProduct() {\n        try (Scanner read = new Scanner(path)) {\n            read.useDelimiter(\"\\n\");\n            System.out.println(\"--RESUMEN POR PRODUCTO--\");\n            System.out.println(\"Producto | Cant. Vendida | Total $\");\n            while (read.hasNext()) {\n                String next = read.next();\n                String[] parts = next.split(\"\\\\|\");\n                double price = Double.parseDouble(parts[2]);\n                int quantity = Integer.parseInt(parts[1]);\n                DecimalFormat f = new DecimalFormat(\"##.00\");\n                Double total = price * quantity;\n                System.out.println(String.format(\"%s | %s | %s\", parts[0], quantity, f.format(total)));\n            }\n\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n    }\n\n    private void destroy() {\n        scanner.close();\n        try {\n            Files.delete(path);\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/java/AnaLauDB.java",
    "content": "import java.io.*;\nimport java.util.*;\n\npublic class AnaLauDB {\n    private static final String ARCHIVO_USUARIO = \"AnaLauDB.txt\";\n    private static final String ARCHIVO_VENTAS = \"ventas.txt\";\n\n    public static void main(String[] args) {\n        Scanner sc = new Scanner(System.in);\n        int opcion;\n\n        do {\n            System.out.println(\"\\n=== MENÚ PRINCIPAL ===\");\n            System.out.println(\"1. Versión básica (archivo con datos personales)\");\n            System.out.println(\"2. Versión extra (gestor de ventas)\");\n            System.out.println(\"3. Salir\");\n            System.out.print(\"Elige una opción: \");\n            opcion = sc.nextInt();\n            sc.nextLine(); // limpiar buffer\n\n            switch (opcion) {\n                case 1 -> versionBasica();\n                case 2 -> gestorVentas(sc);\n                case 3 -> System.out.println(\"Adiós\");\n                default -> System.out.println(\"Opción no válida.\");\n            }\n        } while (opcion != 3);\n\n        sc.close();\n    }\n\n    // -------------------- VERSIÓN BÁSICA --------------------\n    private static void versionBasica() {\n        try {\n            File file = new File(ARCHIVO_USUARIO);\n\n            // 1. Crear archivo\n            if (file.createNewFile()) {\n                System.out.println(\"Archivo creado: \" + file.getName());\n            } else {\n                System.out.println(\"El archivo ya existía, será sobrescrito.\");\n            }\n\n            // 2. Escribir datos\n            FileWriter writer = new FileWriter(file);\n            writer.write(\"Nombre: Laura Ana\\n\");\n            writer.write(\"Edad: 25\\n\");\n            writer.write(\"Lenguaje favorito: Java\\n\");\n            writer.close();\n\n            // 3. Leer contenido\n            System.out.println(\"\\nContenido del archivo:\");\n            BufferedReader reader = new BufferedReader(new FileReader(file));\n            String linea;\n            while ((linea = reader.readLine()) != null) {\n                System.out.println(linea);\n            }\n            reader.close();\n\n            // 4. Borrar archivo\n            if (file.delete()) {\n                System.out.println(\"\\nArchivo borrado: \" + file.getName());\n            } else {\n                System.out.println(\"No se pudo borrar el archivo.\");\n            }\n\n        } catch (IOException e) {\n            System.out.println(\"Ocurrió un error: \" + e.getMessage());\n        }\n    }\n\n    // -------------------- VERSIÓN EXTRA: GESTOR DE VENTAS --------------------\n    private static void gestorVentas(Scanner sc) {\n        int opcion;\n        do {\n            System.out.println(\"\\n=== GESTOR DE VENTAS ===\");\n            System.out.println(\"1. Añadir producto\");\n            System.out.println(\"2. Consultar productos\");\n            System.out.println(\"3. Actualizar producto\");\n            System.out.println(\"4. Eliminar producto\");\n            System.out.println(\"5. Calcular venta total\");\n            System.out.println(\"6. Calcular venta por producto\");\n            System.out.println(\"7. Salir del gestor (borra archivo)\");\n            System.out.print(\"Elige una opción: \");\n            opcion = sc.nextInt();\n            sc.nextLine(); // limpiar buffer\n\n            switch (opcion) {\n                case 1 -> anadirProducto(sc);\n                case 2 -> consultarProductos();\n                case 3 -> actualizarProducto(sc);\n                case 4 -> eliminarProducto(sc);\n                case 5 -> calcularVentaTotal();\n                case 6 -> calcularVentaPorProducto(sc);\n                case 7 -> salirGestor();\n                default -> System.out.println(\"Opción no válida.\");\n            }\n        } while (opcion != 7);\n    }\n\n    // ---------------- Métodos del gestor ----------------\n    private static void anadirProducto(Scanner sc) {\n        try (FileWriter fw = new FileWriter(ARCHIVO_VENTAS, true)) {\n            System.out.print(\"Nombre producto: \");\n            String nombre = sc.nextLine();\n            System.out.print(\"Cantidad vendida: \");\n            int cantidad = sc.nextInt();\n            System.out.print(\"Precio unitario: \");\n            double precio = sc.nextDouble();\n            sc.nextLine();\n\n            fw.write(nombre + \", \" + cantidad + \", \" + precio + \"\\n\");\n            System.out.println(\"✅ Producto añadido.\");\n        } catch (IOException e) {\n            System.out.println(\" Error al escribir en archivo: \" + e.getMessage());\n        }\n    }\n\n    private static void consultarProductos() {\n        try (BufferedReader br = new BufferedReader(new FileReader(ARCHIVO_VENTAS))) {\n            System.out.println(\"\\n--- Productos ---\");\n            String linea;\n            while ((linea = br.readLine()) != null) {\n                System.out.println(linea);\n            }\n        } catch (IOException e) {\n            System.out.println(\" No hay productos o error leyendo archivo.\");\n        }\n    }\n\n    private static void actualizarProducto(Scanner sc) {\n        System.out.print(\"Nombre del producto a actualizar: \");\n        String nombre = sc.nextLine();\n        List<String> lineas = new ArrayList<>();\n        boolean encontrado = false;\n\n        try (BufferedReader br = new BufferedReader(new FileReader(ARCHIVO_VENTAS))) {\n            String linea;\n            while ((linea = br.readLine()) != null) {\n                if (linea.startsWith(nombre + \",\")) {\n                    encontrado = true;\n                    System.out.print(\"Nueva cantidad: \");\n                    int cantidad = sc.nextInt();\n                    System.out.print(\"Nuevo precio: \");\n                    double precio = sc.nextDouble();\n                    sc.nextLine();\n                    lineas.add(nombre + \", \" + cantidad + \", \" + precio);\n                } else {\n                    lineas.add(linea);\n                }\n            }\n        } catch (IOException e) {\n            System.out.println(\" Error: \" + e.getMessage());\n            return;\n        }\n\n        if (!encontrado) {\n            System.out.println(\" Producto no encontrado.\");\n            return;\n        }\n\n        try (FileWriter fw = new FileWriter(ARCHIVO_VENTAS)) {\n            for (String l : lineas) {\n                fw.write(l + \"\\n\");\n            }\n            System.out.println(\"✅ Producto actualizado.\");\n        } catch (IOException e) {\n            System.out.println(\" Error escribiendo archivo: \" + e.getMessage());\n        }\n    }\n\n    private static void eliminarProducto(Scanner sc) {\n        System.out.print(\"Nombre del producto a eliminar: \");\n        String nombre = sc.nextLine();\n        List<String> lineas = new ArrayList<>();\n        boolean eliminado = false;\n\n        try (BufferedReader br = new BufferedReader(new FileReader(ARCHIVO_VENTAS))) {\n            String linea;\n            while ((linea = br.readLine()) != null) {\n                if (linea.startsWith(nombre + \",\")) {\n                    eliminado = true;\n                } else {\n                    lineas.add(linea);\n                }\n            }\n        } catch (IOException e) {\n            System.out.println(\" Error: \" + e.getMessage());\n            return;\n        }\n\n        if (!eliminado) {\n            System.out.println(\" Producto no encontrado.\");\n            return;\n        }\n\n        try (FileWriter fw = new FileWriter(ARCHIVO_VENTAS)) {\n            for (String l : lineas) {\n                fw.write(l + \"\\n\");\n            }\n            System.out.println(\"✅ Producto eliminado.\");\n        } catch (IOException e) {\n            System.out.println(\" Error escribiendo archivo: \" + e.getMessage());\n        }\n    }\n\n    private static void calcularVentaTotal() {\n        double total = 0;\n        try (BufferedReader br = new BufferedReader(new FileReader(ARCHIVO_VENTAS))) {\n            String linea;\n            while ((linea = br.readLine()) != null) {\n                String[] partes = linea.split(\", \");\n                int cantidad = Integer.parseInt(partes[1]);\n                double precio = Double.parseDouble(partes[2]);\n                total += cantidad * precio;\n            }\n            System.out.println(\"💰 Venta total: \" + total);\n        } catch (IOException e) {\n            System.out.println(\" Error: \" + e.getMessage());\n        }\n    }\n\n    private static void calcularVentaPorProducto(Scanner sc) {\n        System.out.print(\"Nombre del producto: \");\n        String nombre = sc.nextLine();\n        double total = 0;\n        try (BufferedReader br = new BufferedReader(new FileReader(ARCHIVO_VENTAS))) {\n            String linea;\n            while ((linea = br.readLine()) != null) {\n                String[] partes = linea.split(\", \");\n                if (partes[0].equals(nombre)) {\n                    int cantidad = Integer.parseInt(partes[1]);\n                    double precio = Double.parseDouble(partes[2]);\n                    total += cantidad * precio;\n                }\n            }\n            System.out.println(\"💰 Venta total de \" + nombre + \": \" + total);\n        } catch (IOException e) {\n            System.out.println(\" Error: \" + e.getMessage());\n        }\n    }\n\n    private static void salirGestor() {\n        File file = new File(ARCHIVO_VENTAS);\n        if (file.exists() && file.delete()) {\n            System.out.println(\" Archivo de ventas borrado. ¡Hasta pronto!\");\n        } else {\n            System.out.println(\"No había archivo que borrar.\");\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/java/AndrewCodev.java",
    "content": "import java.io.*;\nimport java.nio.file.*;\nimport java.util.*;\nimport java.util.Scanner;\n\npublic class AndrewCodev {\n\tpublic static void main(String[] args) {\n        //Los ejercicios estan separados para seleccionar entre uno y otro comentar y descomentar cada uno.\n\t\t//ejemploManejoArchivos();\n\t\tgestionVentas();\n\t}\n\n\t// DIFICULTAD EXTRA\n\tpublic static void gestionVentas() {\n\t\tString nombreArchivo = \"GestionVentas.txt\";\n\t\tScanner scanner = new Scanner(System.in);\n\t\tList<String> contenidoArchivo;\n\t\ttry {\n\t\t\tcrearArchivo(nombreArchivo);\n\n\t\t\tcontenidoArchivo = new ArrayList<>(Files.readAllLines(Paths.get(nombreArchivo)));\n\n\t\t\tSystem.out.println(\"\\nGESTOR DE VENTAS\\n\");\n\t\t\tSystem.out.println(\"1 AGREGAR PRODUCTO\");\n\t\t\tSystem.out.println(\"2 LEER EL ARCHIVO\");\n\t\t\tSystem.out.println(\"3 MODIFICAR PRODUCTO\");\n\t\t\tSystem.out.println(\"4 CALCULAR TOTAL DE PRECIOS\");\n\t\t\tSystem.out.println(\"5 ELIMINAR PRODRUCTO\");\n\t\t\tSystem.out.println(\"6 CERRAR APLICACIÓN\");\n\n\t\t\tString opcionMenu = recibirScanner(scanner);\n\n\t\t\tswitch (opcionMenu) {\n\t\t\tcase \"1\": {\n\t\t\t\tString detalleProducto = lineaArchivo(scanner, contenidoArchivo, nombreArchivo, \n\t\t\t\t\t\tcontenidoArchivo.size());\n\t\t\t\tanexarArchivo(nombreArchivo, detalleProducto);\n\t\t\t\tgestionVentas();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"2\": {\n\t\t\t\tSystem.out.println(\"\\nDETALLE DE VENTAS\\n\");\n\t\t\t\tleerArchivo(nombreArchivo);\n\t\t\t\t// REVISAR SUBMENU\n\t\t\t\tgestionVentas();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"3\": {\n\t\t\t\t// Pasamos las filas al una lista para modificar\n\t\t\t\ttry {\n\n\t\t\t\t\tleerArchivo(nombreArchivo);\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\tif (contenidoArchivo.size() > 1) {\n\t\t\t\t\t\tSystem.out.println(\n\t\t\t\t\t\t\t\t\"Escribe un número del 0 al \" + (contenidoArchivo.size() - 1) + \" la fila a Modificar\");\n\t\t\t\t\t} else if (contenidoArchivo.size() == 1) {\n\t\t\t\t\t\tSystem.out.println(\n\t\t\t\t\t\t\t\t\"Escribe un número: \" + (contenidoArchivo.size() - 1) + \" para modificar la linea\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\tSystem.out.println(\"El archivo no tiene productos\");\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\tint idEditado = Integer.parseInt(recibirScanner(scanner));\n\n\t\t\t\t\tString detalleProducto = lineaArchivo(scanner, contenidoArchivo, nombreArchivo, \n\t\t\t\t\t\t\tidEditado);\n\t\t\t\t\tleerArchivo(nombreArchivo);\n\n\t\t\t\t\tcontenidoArchivo.set((idEditado), detalleProducto);\n\n\t\t\t\t\tFiles.write(Paths.get(nombreArchivo), contenidoArchivo);\n\t\t\t\t\tgestionVentas();\n\t\t\t\t} catch (IOException e) {\n\t\t\t\t\te.printStackTrace();\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"4\": {\n\t\t\t\tdouble sumTotalPrecios = 0;\n\t\t\t\tString inputString = \"\";\n\t\t\t\tfor (int i = 0; i < contenidoArchivo.size(); i++) {\n\t\t\t\t\tinputString = contenidoArchivo.get(i).replace(\"[\", \"\").replace(\"]\", \"\");\n\t\t\t\t\t\n\t\t\t\t\tString array[] = inputString.split(\",\");\n\t\t\t\t\tsumTotalPrecios = sumTotalPrecios + Double.parseDouble(array[4]);\n\t\t\t\t}\n\t\t\t\tleerArchivo(nombreArchivo);\n\t\t\t\tSystem.out.println(\"PRECIO TOTAL: \" + sumTotalPrecios);\n\t\t\t\tgestionVentas();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"5\": {\n\t\t\t\ttry {\n\t\t\t\t\tleerArchivo(nombreArchivo);\n\t\t\t\t\tif (contenidoArchivo.size() > 1) {\n\t\t\t\t\t\tSystem.out.println(\n\t\t\t\t\t\t\t\t\"Escribe un número del 0 al \" + (contenidoArchivo.size() - 1) + \" la fila a eliminar\");\n\t\t\t\t\t} else if (contenidoArchivo.size() == 1) {\n\t\t\t\t\t\tSystem.out.println(\n\t\t\t\t\t\t\t\t\"Escribe un número: \" + (contenidoArchivo.size() - 1) + \" para eliminar la linea\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\tSystem.out.println(\"El archivo no tiene productos\");\n\t\t\t\t\t}\n\n\t\t\t\t\tint idELiminado = Integer.parseInt(recibirScanner(scanner));\n\n\t\t\t\t\tif (idELiminado >= 0 && idELiminado < contenidoArchivo.size()) {\n\t\t\t\t\t\t// Eliminar la línea específica\n\t\t\t\t\t\tcontenidoArchivo.remove(idELiminado);\n\n\t\t\t\t\t\t// Escribir el contenido modificado de nuevo en el archivo\n\t\t\t\t\t\tFiles.write(Paths.get(nombreArchivo), contenidoArchivo);\n\t\t\t\t\t\tSystem.out.println(\"La línea ha sido eliminada exitosamente.\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\tSystem.out.println(\"Número de línea fuera de rango.\");\n\t\t\t\t\t}\n\n\t\t\t\t\tgestionVentas();\n\t\t\t\t} catch (IOException e) {\n\t\t\t\t\te.printStackTrace();\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"6\": {\n\t\t\t\teliminarArchivo(nombreArchivo);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tSystem.err.println(\"La opción no es valida, intentelo de nuevo\");\n\t\t\t\tgestionVentas();\n\t\t\t}\n\t\t} catch (IOException e) {\n\t\t\te.printStackTrace();\n\t\t}\n\n\t}\n\n\tpublic static String recibirScanner(Scanner scanner) {\n\t\tString dato = scanner.nextLine();\n\t\treturn dato;\n\t}\n\n\tpublic static String lineaArchivo(Scanner scanner, List<String> contenidoArchivo, String nombreArchivo,\n\t\t\tint idProducto) {\n\t\tString lineaArchivo = \"\";\n\t\ttry {\n\t\t\tString nombreproducto;\n\t\t\tint cantidad;\n\t\t\tdouble precio;\n\t\t\tdouble totalPrecio;\n\t\t\t//int idProducto = 0;\n\n\t\t\t//idProducto = contenidoArchivo.size();\n\t\t\tSystem.out.println(\"Ingresa el nombre del producto\");\n\t\t\tnombreproducto = recibirScanner(scanner);\n\t\t\tSystem.out.println(\"Ingresa la cantidad\");\n\t\t\tcantidad = Integer.parseInt(recibirScanner(scanner));\n\t\t\tSystem.out.println(\"Ingresa el precio unidad\");\n\t\t\tprecio = Integer.parseInt(recibirScanner(scanner));\n\t\t\ttotalPrecio = precio * cantidad;\n\t\t\tlineaArchivo = \"[\" + idProducto + \"],\" +\"[\" + nombreproducto + \"],[\" + cantidad + \"],[\" + precio + \"],[\" + totalPrecio + \"]\";\n\t\t\t\n\t\t\treturn lineaArchivo;\n\t\t} catch (Exception e) {\n\t\t\tSystem.err.println(\"La opción no es valida está debe escribir la opción númerica\");\n\t\t}\n\t\treturn lineaArchivo;\n\t}\n\n\tpublic static void ejemploManejoArchivos() {\n\t\tString nombreArchivo = \"AndrewCodev.txt\";\n\n\t\tcrearArchivo(nombreArchivo);\n\n\t\tanexarArchivo(nombreArchivo, \"Nombre: AndrewCodev\");\n\t\tanexarArchivo(nombreArchivo, \"Edad: 30\");\n\t\tanexarArchivo(nombreArchivo, \"Lenguaje: Java\");\n\n\t\tleerArchivo(nombreArchivo);\n\t\teliminarArchivo(nombreArchivo);\n\t}\n\n\t// CREAMOS EL ARCHIVO\n\tpublic static void crearArchivo(String nombreArchivo) {\n\t\tFile archivo = new File(nombreArchivo);\n\n\t\ttry {\n\t\t\tif (!archivo.exists()) {\n\t\t\t\tPrintWriter salida = new PrintWriter(archivo);\n\t\t\t\tsalida.close();\n\t\t\t\tSystem.out.println(\"Se ha creado el archivo: \" + nombreArchivo);\n\t\t\t}\n\t\t} catch (FileNotFoundException e) {\n\t\t\te.printStackTrace();\n\t\t}\n\t}\n\n\t// ESCRIBIR ARCHIVO\n\tpublic static void escribirArchivo(String nombreArchivo, String contenido) {\n\t\tFile archivo = new File(nombreArchivo);\n\n\t\ttry {\n\t\t\tPrintWriter salida = new PrintWriter(archivo);\n\t\t\tsalida.println(contenido);\n\t\t\tsalida.close();\n\t\t\tSystem.out.println(\"Se ha escrito en el archivo: \" + nombreArchivo);\n\t\t} catch (FileNotFoundException e) {\n\t\t\te.printStackTrace();\n\t\t}\n\t}\n\n\t// ANEXAR INFORMACIÓN\n\tpublic static void anexarArchivo(String nombreArchivo, String contenido) {\n\t\tFile archivo = new File(nombreArchivo);\n\n\t\ttry {\n\t\t\tPrintWriter salida = new PrintWriter(new FileWriter(archivo, true));\n\t\t\tsalida.println(contenido);\n\t\t\tsalida.close();\n\t\t\tSystem.out.println(\"Se ha anexado información en el archivo: \" + nombreArchivo);\n\t\t} catch (FileNotFoundException e) {\n\t\t\te.printStackTrace();\n\t\t} catch (IOException e) {\n\t\t\te.printStackTrace();\n\t\t}\n\t}\n\n\t// LEER ARCHIVO\n\tpublic static void leerArchivo(String nombreArchivo) {\n\t\tFile archivo = new File(nombreArchivo);\n\t\tBufferedReader entrada = null;\n\t\ttry {\n\t\t\tentrada = new BufferedReader(new FileReader(archivo));\n\t\t\tString lectura = entrada.readLine();\n\n\t\t\twhile (lectura != null) {\n\t\t\t\tSystem.out.println(lectura);\n\t\t\t\tlectura = entrada.readLine();\n\t\t\t}\n\t\t\t//entrada.close();\n\n\t\t} catch (FileNotFoundException e) {\n\t\t\te.printStackTrace();\n\t\t} catch (IOException e) {\n\t\t\te.printStackTrace();\n\t\t} finally {\n\t\t\t// Cerrar el BufferedReader\n\t\t\tif (entrada != null) {\n\t\t\t\ttry {\n\t\t\t\t\tentrada.close();\n\t\t\t\t} catch (IOException e) {\n\t\t\t\t\te.printStackTrace();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic static void eliminarArchivo(String nombreArchivo) {\n\t\tFile archivo = new File(nombreArchivo);\n\n\t\tPath ruta = Path.of(archivo.getPath());\n\n\t\ttry {\n\t\t\tFiles.delete(ruta);\n\t\t} catch (IOException e) {\n\t\t\te.printStackTrace();\n\t\t}\n\t\tSystem.out.println(\"Archivo eliminado: \" + nombreArchivo);\n\t}\n}\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/java/FranDev200.java",
    "content": "import java.io.*;\nimport java.util.Scanner;\n\npublic class FranDev200 {\n    static File file = new File(\"Almacen.txt\");\n\n    static void main() {\n        /*\n\n            EJERCICIO:\n            * Desarrolla un programa capaz de crear un archivo que se llame como\n            * tu usuario de GitHub y tenga la extensión .txt.\n            * Añade varias líneas en ese fichero:\n            * - Tu nombre.\n            * - Edad.\n            * - Lenguaje de programación favorito.\n            * Imprime el contenido.\n            * Borra el fichero.\n\n         */\n\n        Scanner scan = new Scanner(System.in);\n\n        String usuarioGithub;\n        String nombre;\n        int edad;\n        String lenguajeFavorito;\n\n        System.out.print(\"Introduce el nombre del usuario de Github: \");\n        usuarioGithub = scan.nextLine();\n        System.out.print(\"Ingrese su nombre: \");\n        nombre = scan.nextLine();\n        System.out.print(\"Ingrese su edad: \");\n        edad = Integer.parseInt(scan.nextLine());\n        System.out.print(\"Ingrese lenguaje de programacion favorito: \");\n        lenguajeFavorito = scan.nextLine();\n\n        String nombreFichero = usuarioGithub + \".txt\";\n        File fichero = new File(nombreFichero);\n\n        System.out.println(\"\\nCreando y escribiendo en el fichero...\");\n\n        try{\n            FileWriter fw = new FileWriter(fichero);\n            BufferedWriter bffw = new BufferedWriter(fw);\n            bffw.write(\" - \" + nombre + \"\\n\");\n            bffw.write(\" - \" + edad + \"\\n\");\n            bffw.write(\" - \" + lenguajeFavorito);\n            bffw.close();\n\n        }catch (IOException e){\n            System.out.println(\"ERROR: \" +  e.getMessage());\n        }\n\n        System.out.println(\"Contenido del fichero:\");\n        System.out.println(\"======================\");\n\n        try{\n            FileReader fr = new FileReader(fichero);\n            BufferedReader bffr = new BufferedReader(fr);\n\n            String linea;\n            while ((linea = bffr.readLine()) != null) {\n                System.out.println(linea);\n            }\n\n            fr.close();\n            bffr.close();\n\n        }catch (IOException e){\n            System.out.println(\"ERROR: \" +  e.getMessage());\n        }\n\n        System.out.println(\"ENTER para salir y eliminar el fichero: \");\n        scan.nextLine();\n\n\n        System.out.println(\"Eliminando el fichero...\");\n        fichero.delete();\n\n\n/*\n            DIFICULTAD EXTRA (opcional):\n            * Desarrolla un programa de gestión de ventas que almacena sus datos en un archivo .txt.\n            * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n            *   [nombre_producto], [cantidad_vendida], [precio].\n            * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n            *   actualizar, eliminar productos y salir.\n            * - También debe poseer opciones para calcular la venta total y por producto.\n            * - La opción salir borra el .txt.\n\n         */\n\n        int respuesta;\n\n        while (true) {\n\n            System.out.println(\"GESTIÓN DE VENTAS DEL ALMACEN\");\n            System.out.println(\"=============================\");\n            System.out.println(\"1 - Añadir producto.\");\n            System.out.println(\"2 - Consultar productos totales.\");\n            System.out.println(\"3 - Editar producto.\");\n            System.out.println(\"4 - Eliminar producto.\");\n            System.out.println(\"5 - Salir.\");\n            System.out.println(\"=============================\");\n            System.out.print(\"Respuesta: \");\n\n            try {\n                respuesta = Integer.parseInt(scan.nextLine());\n            } catch (NumberFormatException e) {\n                System.out.println(\"Entrada no válida.\\n\");\n                continue;\n            }\n\n            switch (respuesta) {\n\n                case 1:\n                    aniadirProducto(scan);\n                    break;\n\n                case 2:\n\n                    if (!file.exists()) {\n                        System.out.println(\"El fichero no existe.\\n\");\n                        break;\n                    }\n\n                    try(BufferedReader bufferedReader = new BufferedReader(new FileReader(file))){\n\n                        if(bufferedReader.readLine() == null){\n                            System.out.println(\"No hay productos guardados.\\n\");\n                            break;\n                        }\n                    }catch (IOException e){\n                        System.out.println(\"Error al leer el archivo.\\n\");\n                    }\n\n                    listarProductos();\n                    break;\n\n                case 3:\n\n                    if (!file.exists()) {\n                        System.out.println(\"El fichero no existe\\n\");\n                        break;\n                    }\n\n                    try(BufferedReader bufferedReader = new BufferedReader(new FileReader(file))){\n                        if(bufferedReader.readLine() == null){\n                            System.out.println(\"No hay productos guardados.\\n\");\n                            break;\n                        }\n                    }catch (IOException e){\n                        System.out.println(\"Error al leer el archivo.\\n\");\n                    }\n\n                    listarProductos();\n\n                    System.out.print(\"Número del producto a editar: \");\n                    int idEditar = Integer.parseInt(scan.nextLine());\n                    editarProducto(scan, idEditar);\n                    break;\n\n                case 4:\n\n                    if (!file.exists()) {\n                        System.out.println(\"El fichero no existe.\\n\");\n                        break;\n                    }\n\n                    try(BufferedReader bufferedReader = new BufferedReader(new FileReader(file))){\n                        if(bufferedReader.readLine() == null){\n                            System.out.println(\"No hay productos guardados.\\n\");\n                            break;\n                        }\n                    }catch (IOException e){\n                        System.out.println(\"Error al leer el archivo.\\n\");\n                    }\n\n                    listarProductos();\n\n                    System.out.print(\"Número del producto a eliminar: \");\n                    try {\n                        int idEliminar = Integer.parseInt(scan.nextLine());\n                        eliminarProducto(idEliminar);\n                    }catch (NumberFormatException e){\n                        System.out.println(e.getMessage());\n                    }\n                    break;\n\n                case 5:\n                    scan.close();\n                    file.delete();\n                    System.out.println(\"Saliendo de la base de datos...\");\n                    System.exit(0);\n            }\n        }\n    }\n\n    // ============================\n    // AÑADIR PRODUCTO\n    // ============================\n    private static void aniadirProducto(Scanner scan) {\n\n        try (BufferedWriter bw = new BufferedWriter(new FileWriter(file, true))) {\n\n            System.out.print(\"Nombre del producto: \");\n            String nombre = scan.nextLine();\n\n            System.out.print(\"Cantidad: \");\n            int cantidad = Integer.parseInt(scan.nextLine());\n\n            System.out.print(\"Precio: \");\n            double precio = Double.parseDouble(scan.nextLine());\n\n            bw.write(nombre + \" [ \" + cantidad + \" ud ] --> \" + precio + \" €/ud\");\n            bw.newLine();\n\n            System.out.println(\"Producto guardado correctamente.\\n\");\n\n        } catch (IOException | NumberFormatException e) {\n            System.out.println(\"Error al añadir producto.\\n\");\n        }\n    }\n\n    // ============================\n    // LISTAR PRODUCTOS\n    // ============================\n    private static void listarProductos() {\n\n        try (BufferedReader br = new BufferedReader(new FileReader(file))) {\n\n            String linea;\n            int contador = 1;\n            double ventaTotalProducto = 0;\n            double ventaTotalTodosLosProductos = 0;\n\n            System.out.println(\"\\nLISTADO DE PRODUCTOS\");\n            System.out.println(\"====================\");\n\n            while ((linea = br.readLine()) != null) {\n\n                int cantidad = Integer.parseInt(linea.split(\" \")[2].trim());\n                double precio = Double.parseDouble(linea.split(\" \")[6].trim());\n\n                ventaTotalProducto += cantidad * precio;\n                ventaTotalTodosLosProductos += ventaTotalProducto;\n                System.out.println(contador + \" - \" + linea + \". \\nVENTA TOTAL: \" + ventaTotalProducto + \"€\");\n                contador++;\n            }\n            System.out.println(\"=======================\");\n            System.out.println(\"Precio total de todos los productos: \" +  ventaTotalTodosLosProductos + \"€\");\n            System.out.println();\n\n            if (contador == 1) {\n                System.out.println(\"No hay productos registrados.\\n\");\n            }\n\n        } catch (IOException e) {\n            System.out.println(\"Error al leer el archivo.\\n\");\n        }\n    }\n\n    // ============================\n    // ELIMINAR PRODUCTO\n    // ============================\n    private static void eliminarProducto(int idEliminar) {\n\n        File temp = new File(\"temp.txt\");\n        int contador = 1;\n\n        try (\n                BufferedReader br = new BufferedReader(new FileReader(file));\n                BufferedWriter bw = new BufferedWriter(new FileWriter(temp))\n        ) {\n\n            String linea;\n            while ((linea = br.readLine()) != null) {\n\n                if (contador != idEliminar) {\n                    bw.write(linea);\n                    bw.newLine();\n                }\n                contador++;\n            }\n\n        } catch (IOException e) {\n            System.out.println(\"Error al eliminar producto.\\n\");\n            return;\n        }\n\n        file.delete();\n        temp.renameTo(file);\n        System.out.println(\"Producto eliminado correctamente.\\n\");\n    }\n\n    // ============================\n    // EDITAR PRODUCTO\n    // ============================\n    private static void editarProducto(Scanner scan, int idEditar) {\n\n        System.out.print(\"Cantidad: \");\n        int cantidad = Integer.parseInt(scan.nextLine());\n\n        System.out.print(\"Precio: \");\n        double precio = Double.parseDouble(scan.nextLine());\n\n        File temp = new File(\"temp.txt\");\n        int contador = 1;\n\n        try (\n                BufferedReader br = new BufferedReader(new FileReader(file));\n                BufferedWriter bw = new BufferedWriter(new FileWriter(temp))\n        ) {\n\n            String linea;\n            String nomProducto;\n            while ((linea = br.readLine()) != null) {\n\n                if (contador == idEditar) {\n\n                    nomProducto = linea.toString().split(\" \")[0].toString();\n                    System.out.println(\"Nombre del producto: \" + nomProducto);\n                    linea = nomProducto + \" [ \" + cantidad + \" ud ] --> \" + precio + \" €/ud\";\n\n                    bw.write(linea);\n                    bw.newLine();\n                }else{\n                    bw.write(linea);\n                    bw.newLine();\n                }\n                contador++;\n            }\n\n        } catch (IOException e) {\n            System.out.println(\"Error al editar producto.\\n\");\n            return;\n        }\n\n        file.delete();\n        temp.renameTo(file);\n        System.out.println(\"Producto editado correctamente.\\n\");\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/java/JimsimroDev.java",
    "content": "import java.io.BufferedReader;\nimport java.io.BufferedWriter;\nimport java.io.File;\nimport java.io.FileReader;\nimport java.io.FileWriter;\nimport java.io.IOException;\nimport java.io.PrintWriter;\nimport java.util.Scanner;\n\npublic class JimsimroDev {\n\n  private final static String DIVLINE = \"::::::::::::::::::::::::::::::::::::::::::::::::::::\";\n\n  private static void menu() {\n    String menu = \"\"\"\n            1 ~ Create product\n            2 ~ Consult product\n            3 ~ Update product\n            4 ~ Delete product\n            5 ~ List products\n            6 ~ Calculate total sales\n            7 ~ Calculate product sales\n            8 ~ Exit\n        \"\"\";\n    System.out.println(menu);\n  }\n\n  private static void actions() {\n    Scanner in = new Scanner(System.in);\n    int option = 0;\n    while (option != 8) {\n      menu();\n      System.out.println(\"Choose an option: \");\n      option = in.nextInt();\n      in.nextLine();\n      switch (option) {\n        case 1:\n          System.out.print(\"Name: \");\n          String name = in.nextLine();\n          System.out.print(\"Quantity: \");\n          int quantity = in.nextInt();\n          System.out.print(\"Price: \");\n          int price = in.nextInt();\n          try {\n            createProduct(name, quantity, price);\n          } catch (IOException e) {\n            e.printStackTrace();\n          }\n          break;\n        case 2:\n          System.out.print(\"Name of the product to search: \");\n          String nameToSearch = in.nextLine();\n          consultProduct(nameToSearch);\n          break;\n        case 3:\n          System.out.print(\"Name: \");\n          String nameToUpdate = in.nextLine();\n          System.out.print(\"Quantity: \");\n          int quantityToUpdate = in.nextInt();\n          System.out.print(\"Price: \");\n          int priceToUpdate = in.nextInt();\n          updateProduct(nameToUpdate, quantityToUpdate, priceToUpdate);\n          break;\n        case 4:\n          System.out.print(\"Name of the product to delete: \");\n          String nameToDelete = in.nextLine();\n          deleteProduct(nameToDelete);\n          break;\n        case 5:\n          listProducts();\n          break;\n        case 6:\n          calculateTotalSales();\n          break;\n        case 7:\n          System.out.print(\"Name of the product: \");\n          String productName = in.nextLine();\n          calculateProductSales(productName);\n          break;\n        case 8:\n          deleteFile();\n          break;\n      }\n    }\n    in.close(); // Close the scanner to avoid resource leak\n  }\n\n  private static void createProduct(String name, int quantity, int price) throws IOException {\n    File file = getFileBasedOnOs();\n\n    try (PrintWriter printWriter = new PrintWriter(new FileWriter(file, true))) { // 'true' for appending to the file\n      printWriter.print(name + \", \");\n      printWriter.print(quantity + \", \");\n      printWriter.println(price);\n    } catch (IOException e) {\n      e.printStackTrace();\n    }\n    System.out.println(\"Created successfully\");\n  }\n\n  private static void consultProduct(String name) {\n    File file = getFileBasedOnOs();\n\n    try (BufferedReader bufferedReader = new BufferedReader(new FileReader(file))) {\n      String line;\n      System.out.println(DIVLINE);\n      while ((line = bufferedReader.readLine()) != null) {\n        if (line.contains(name)) {\n          System.out.println(line);\n          break;\n        }\n      }\n      System.out.println(DIVLINE);\n    } catch (IOException e) {\n      e.printStackTrace();\n    }\n  }\n\n  private static void updateProduct(String name, int quantity, int price) {\n    File file = getFileBasedOnOs();\n    File tempFile = new File(file.getAbsolutePath() + \".tmp\");\n    boolean productFound = false;\n\n    try (BufferedReader bufferedReader = new BufferedReader(new FileReader(file));\n        BufferedWriter bw = new BufferedWriter(new FileWriter(tempFile))) {\n\n      String line;\n      while ((line = bufferedReader.readLine()) != null) {\n        if (!line.contains(name)) {\n          bw.write(line);\n          bw.newLine();\n        } else {\n          bw.write(name + \", \");\n          bw.write(quantity + \", \");\n          bw.write(price + \"\\n\");\n          System.out.println(\"Updated successfully\");\n          productFound = true;\n        }\n      }\n    } catch (IOException e) {\n      System.out.println(e.getClass().getName() + \" Error processing the file \" + e.getMessage());\n      e.printStackTrace();\n    }\n    if (!productFound) {\n      System.err.println(\"Product \" + name + \" does not exist in the file \" + file.getName());\n      tempFile.delete();\n      return;\n    }\n    if (!file.delete()) {\n      return;\n    }\n    if (!tempFile.renameTo(file)) {\n      System.err.println(file.getName());\n    }\n  }\n\n  private static void deleteProduct(String name) {\n    File file = getFileBasedOnOs();\n    File tempFile = new File(file.getAbsolutePath() + \".tmp\");\n\n    try (BufferedReader bufferedReader = new BufferedReader(new FileReader(file));\n        BufferedWriter bw = new BufferedWriter(new FileWriter(tempFile))) {\n\n      String line;\n      while ((line = bufferedReader.readLine()) != null) {\n        if (!line.contains(name)) {\n          bw.write(line);\n          bw.newLine();\n        }\n      }\n    } catch (IOException e) {\n      System.out.println(e.getClass().getName() + \" Error processing the file \" + e.getMessage());\n      e.printStackTrace();\n    }\n\n    if (!file.delete()) {\n      return;\n    }\n    if (!tempFile.renameTo(file)) {\n      System.err.println(file.getName());\n    }\n  }\n\n  private static void listProducts() {\n    File file = getFileBasedOnOs();\n\n    try (BufferedReader bufferedReader = new BufferedReader(new FileReader(file))) {\n      String line;\n      System.out.println(DIVLINE);\n      while ((line = bufferedReader.readLine()) != null) {\n        System.out.println(line);\n      }\n      System.out.println(DIVLINE);\n    } catch (IOException e) {\n      e.printStackTrace();\n    }\n  }\n\n  private static void calculateTotalSales() {\n    File file = getFileBasedOnOs();\n\n    try (BufferedReader bufferedReader = new BufferedReader(new FileReader(file))) {\n      String line;\n      int totalSales = 0;\n      System.out.println(DIVLINE);\n      while ((line = bufferedReader.readLine()) != null) {\n        String[] parts = line.split(\", \");\n        int quantity = Integer.parseInt(parts[1]);\n        int price = Integer.parseInt(parts[2]);\n\n        totalSales += (quantity * price);\n      }\n      System.out.printf(\"Total sales: %d\\n\", totalSales);\n      System.out.println(DIVLINE);\n    } catch (IOException e) {\n      e.printStackTrace();\n    }\n  }\n\n  private static void calculateProductSales(String name) {\n    File file = getFileBasedOnOs();\n\n    try (BufferedReader bufferedReader = new BufferedReader(new FileReader(file))) {\n      String line;\n      int totalSales = 0;\n      System.out.println(DIVLINE);\n      while ((line = bufferedReader.readLine()) != null) {\n        if (line.contains(name)) {\n          String[] parts = line.split(\", \");\n          int quantity = Integer.parseInt(parts[1]);\n          int price = Integer.parseInt(parts[2]);\n          totalSales += (quantity * price);\n          break;\n        }\n      }\n      System.out.printf(\"Total sales of %s = %d\\n\", name, totalSales);\n      System.out.println(DIVLINE);\n    } catch (IOException e) {\n      e.printStackTrace();\n    }\n  }\n\n  private static void deleteFile() {\n    File file = getFileBasedOnOs();\n    file.delete();\n  }\n\n  private static File getFileBasedOnOs() {\n    String osName = System.getProperty(\"os.name\").toLowerCase();\n    File file;\n\n    if (osName.contains(\"win\")) {\n      file = new File(\"J:\\\\JimsimroDev.txt\");\n    } else if (osName.contains(\"nix\") || osName.contains(\"nux\")) {\n      file = new File(\"/mnt/j/JimsimroDev.txt\");\n    } else if (osName.contains(\"mac\")) {\n      file = new File(\"/mnt/j/JimsimroDev.txt\");\n    } else {\n      file = new File(\"/mnt/j/JimsimroDev.txt\"); // Operating system not recognized\n    }\n    return file;\n  }\n\n  public static void main(String[] args) throws IOException {\n    actions();\n  }\n}\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/java/Josegs95.java",
    "content": "import java.io.*;\nimport java.nio.charset.StandardCharsets;\nimport java.nio.file.Files;\nimport java.nio.file.StandardOpenOption;\nimport java.util.List;\nimport java.util.Scanner;\n\npublic class Josegs95 {\n    public static void main(String[] args) {\n        //Ficheros\n        File file = new File(\"Josegs95.txt\");\n        try(FileWriter out = new FileWriter(file); Scanner in = new Scanner(file)){\n            //FileWriter crea ya un archivo al crearse el objeto\n            if (file.createNewFile())\n                System.out.println(\"Archivo creado: \" + file.getName());\n            else\n                System.out.println(\"No se ha creado el archivo \" + file.getName() + \" porque ya existía\");\n\n\n            out.write(\"Nombre: Josegs95\" + System.lineSeparator());\n            out.write(\"Edad: 29\" + System.lineSeparator());\n            out.write(\"Lenguaje: Java\" + System.lineSeparator());\n            out.flush();\n\n            while (in.hasNext()){\n                System.out.println(in.nextLine());\n            }\n\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        } finally {\n            if (file.delete())\n                System.out.println(\"Se ha borrado el archivo: \" + file.getName());\n            else\n                System.out.println(\"No se ha podido borrar el archivo: \" + file.getName());\n        }\n\n        //Reto\n        System.out.println(\"\\n\");\n        retoFinal();\n    }\n\n    static File file;\n    public static void retoFinal(){\n        file = new File(\"Ventas.txt\");\n        try(Scanner sc = new Scanner(System.in);\n            FileWriter out = new FileWriter(file, true)){\n\n            loop: while(true){\n                showMenu();\n                System.out.print(\"Seleccione una opción: \");\n                String option = sc.nextLine();\n                switch (option){\n                    case \"1\": //Añadir\n                        addProduct(out, askProductDetails(sc));\n                        break;\n                    case \"2\": //Consultar\n                        showProduct(sc);\n                        break;\n                    case \"3\": //Actualizar\n                        updateProduct(askProductDetails(sc));\n                        break;\n                    case \"4\": //Eliminar\n                        deleteProduct(sc);\n                        break;\n                    case \"5\": //Calculo venta producto\n                        calculateProductSales(sc);\n                        break;\n                    case \"6\": //Calculo venta total\n                        calculateTotalSales();\n                        break;\n                    case \"7\": //Salir\n                        break loop;\n                    default:\n                        System.out.println(\"Error. Debe elegir una opción válida (0-7).\");\n                        break;\n                }\n            }\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        } finally {\n            deleteFile();\n        }\n\n    }\n\n    private static void showMenu(){\n        System.out.println(\"------------------\");\n        System.out.println(\"1- Añadir producto\");\n        System.out.println(\"2- Consultar producto\");\n        System.out.println(\"3- Actualizar producto\");\n        System.out.println(\"4- Eliminar producto\");\n        System.out.println(\"5- Calcular venta producto\");\n        System.out.println(\"6- Calcular venta total\");\n        System.out.println(\"7- Salir\");\n        System.out.println(\"------------------\");\n    }\n\n    private static String[] askProductDetails(Scanner userInput){\n        System.out.print(\"Introduzca el nombre del producto: \");\n        String product = userInput.nextLine().toLowerCase();\n        System.out.print(\"Introduzca la cantidad del producto: \");\n        String quantity = userInput.nextLine().toLowerCase(); //Habría que controlar que es un número\n        System.out.print(\"Introduzca el precio del producto: \");\n        String price = userInput.nextLine().toLowerCase(); //Habría que controlar que es un número\n\n        return new String[]{product, quantity, price};\n    }\n\n    private static void addProduct(FileWriter outFile, String[] product) throws IOException {\n        //Habría que controlar que el producto no existiera ya en el archivo\n        String productLine = product[0] + \", \" + product[1] + \", \" + product[2] + System.lineSeparator();\n\n        outFile.write(productLine);\n        outFile.flush();\n    }\n\n    private static void showProduct(Scanner userInput) throws IOException {\n        System.out.print(\"Introduzca el nombre del producto: \");\n        String product = userInput.nextLine().toLowerCase();\n\n        String[] productDetails;\n\n        List<String> lines = Files.readAllLines(file.toPath());\n        for (String line : lines){\n            productDetails = line.split(\", \");\n            if (productDetails[0].equals(product)){\n                System.out.println(\"Producto: \" + productDetails[0] + \", Cantidad: \" + productDetails[1] + \", Precio: \" + productDetails[2]);\n                return;\n            }\n        }\n\n        System.out.println(\"No está registrado el producto: \" + product);\n    }\n\n    private static void updateProduct(String[] product) throws IOException {\n        String productLine = product[0] + \", \" + product[1] + \", \" + product[2];\n\n        List<String> lines = Files.readAllLines(file.toPath());\n        String[] productDetails;\n        boolean isUpdated = false;\n        for (int i = 0; i < lines.size(); i++){\n            productDetails = lines.get(i).split(\", \");\n            if (productDetails[0].equals(product[0])){\n                lines.set(i, productLine);\n                isUpdated = true;\n                break;\n            }\n        }\n\n        if (isUpdated)\n            System.out.println(\"Se ha actualizado el producto: \" + product[0]);\n        else\n            System.out.println(\"El producto '\" + product[0] + \"' no está registrado.\");\n\n        Files.write(file.toPath(), lines, StandardCharsets.UTF_8);\n    }\n\n    private static void deleteProduct(Scanner userInput) throws IOException {\n        System.out.print(\"Introduzca el nombre del producto: \");\n        String product = userInput.nextLine().toLowerCase();\n\n        String[] productDetails;\n        boolean isRemoved = false;\n\n        List<String> lines = Files.readAllLines(file.toPath());\n        for (int i = 0; i < lines.size(); i++){\n            productDetails = lines.get(i).split(\", \");\n            if (productDetails[0].equals(product)){\n                lines.remove(i);\n                isRemoved = true;\n                break;\n            }\n        }\n\n        if (isRemoved)\n            System.out.println(\"Se ha borrado el producto: \" + product);\n        else\n            System.out.println(\"El producto \" + product + \" no está registrado.\");\n\n        Files.write(file.toPath(), lines, StandardCharsets.UTF_8);\n    }\n\n    private static void calculateProductSales(Scanner userInput) throws IOException{\n        System.out.print(\"Introduzca el nombre del producto: \");\n        String product = userInput.nextLine().toLowerCase();\n\n        List<String> lines = Files.readAllLines(file.toPath());\n        String[] productDetails;\n        Double total = 0.0;\n        for (String line : lines){\n            productDetails = line.split(\", \");\n            if (productDetails[0].equals(product)){\n                Integer quantity = Integer.parseInt(productDetails[1]);\n                Double price = Double.parseDouble(productDetails[2]);\n                total = quantity * price;\n                break;\n            }\n        }\n\n        if (total != 0)\n            System.out.printf(\"Venta del producto %s de %.2f€.%n\", product, total);\n        else\n            System.out.println(\"El producto \" + product + \" no está registrado.\");\n    }\n\n    private static void calculateTotalSales() throws IOException {\n        List<String> lines = Files.readAllLines(file.toPath());\n        String[] productDetails;\n        Double total = 0.0;\n        for (String line : lines){\n            productDetails = line.split(\", \");\n            Integer quantity = Integer.parseInt(productDetails[1]);\n            Double price = Double.parseDouble(productDetails[2]);\n            total += quantity * price;\n        }\n\n        System.out.printf(\"Venta total de %.2f€.%n\", total);\n    }\n\n    private static void deleteFile(){\n        if (file.delete())\n            System.out.println(\"Se ha borrado el archivo: \" + file.getName());\n        else\n            System.out.println(\"No se ha podido borrar el archivo: \" + file.getName());\n    }\n}\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/java/RodrigoGit87.java",
    "content": "import java.io.File;\nimport java.io.FileWriter;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.Scanner;\n\n/* --- CONCEPTOS BÁSICOS EN MANEJO DE FICHEROS ---\n* 1. Crear un archivo; con la clase File\n* 2. Escribir datos; con la clase FileWriter o Files.writeString\n* 3. Leer datos; clase Scanner o Files.readAllLines\n*  4. Borrar datos; función .delete();  \n*/\n\n/*------ EXTRA -------\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n * archivo .txt.\n * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n */\npublic class RodrigoGit87 {\n    public static void main(String[] args) {\n        String seller = \"RodrigoGit87\";\n        File user = new File(seller);\n\n        // -----Selección de opciones del menu --------\n        Scanner sc = new Scanner(System.in);\n        int opcion = 0;\n\n        while (opcion != 6) { // El programa no termina hasta pulsar el 6\n            System.out.println(\"\\n--- GESTIÓN DE VENTAS ---\");\n            System.out.println(\"1 - Añadir productos\");\n            System.out.println(\"2 - Consultar productos\");\n            System.out.println(\"3 - Actualizar productos\"); // Nota: Check case 3 y 4; podrian mejorar la logica, para\n                                                            // establecer todos los productos a .toLowerCase y luego\n                                                            // .contains para que el usuario no tenga q poner el nombre\n                                                            // exacto.\n            System.out.println(\"4 - Eliminar productos\");\n            System.out.println(\"5 - Calcular venta total\");\n            System.out.println(\"6 - SALIR \");\n            System.out.print(\"Seleccione una opción: \");\n\n            opcion = sc.nextInt();\n            sc.nextLine(); // Limpiar el buffer después de leer un número\n\n            // -------- MENU ---------------\n            switch (opcion) {\n                case 1: // lógica de añadir -> nombre_producto, cantidad_prods_vendida, precio\n                    System.out.println(\"Nombre del producto: \");\n                    String name = sc.nextLine();\n                    System.out.println(\"Cantidad de productos vendida: \");\n                    int amount = sc.nextInt();\n                    System.out.println(\"Precio de venta(unitario): \");\n                    double value = sc.nextDouble();\n                    sc.nextLine(); // depurar buffer\n\n                    try (FileWriter writer = new FileWriter(user, true)) { // necesitamos que el programa sea capaz de\n                                                                           // \"añadir\" nuevos\n                        // productos sin borrar los anteriores. La clase FileWriter tiene un constructor\n                        // especial para esto:\n                        // new FileWriter(instanciaDeFile, true); <- en false, elimina y sobreescribe.\n                        writer.write(name + \", \" + amount + \", \" + value + \"\\n\");\n                        System.out.println(\" datos añadidos\");\n\n                    } catch (IOException e) {\n                        System.err.println(\" error ocurrido: \" + e);\n                    }\n                    break;\n                case 2:\n                    System.out.println(\"\\n Consulta de productos \");\n                    // Usamos try-with-resources para que el Scanner se cierre solo\n                    try (Scanner lector = new Scanner(user)) { // Scanner(user) leerá el objeto instanciado user. de la\n                                                               // clase File\n                        while (lector.hasNextLine()) {\n                            String linea = lector.nextLine();\n                            System.out.println(linea);\n                        }\n                    } catch (IOException e) {\n                        System.out.println(\"No se pudo leer el archivo o aún no existe.\");\n                    }\n                    break;\n\n                // Para los cases 3 y 4, necesitamos una forma de pasar el archivo a una\n                // lista. Usaremos ArrayList<String>\n                case 3:\n                    System.out.print(\"Nombre del producto a actualizar: \");\n                    String productoAEditar = sc.nextLine();\n                    ArrayList<String> listaEdicion = new ArrayList<>();\n                    boolean is_Editado = false;\n\n                    try (Scanner lectorEdicion = new Scanner(user)) {\n                        while (lectorEdicion.hasNextLine()) {\n                            String linea = lectorEdicion.nextLine();\n                            String[] datos = linea.split(\", \");\n\n                            if (datos[0].equalsIgnoreCase(productoAEditar)) {\n                                System.out.print(\"Nueva cantidad: \");\n                                int nCant = sc.nextInt();\n                                System.out.print(\"Nuevo precio: \");\n                                double nPrec = sc.nextDouble();\n                                sc.nextLine(); // Limpiar buffer\n\n                                // Añadimos la línea con los datos nuevos\n                                listaEdicion.add(datos[0] + \", \" + nCant + \", \" + nPrec);\n                                is_Editado = true;\n                            } else\n                                listaEdicion.add(linea); // Mantenemos la línea original\n                        }\n                    } catch (IOException e) {\n                        System.err.println(\" error : \" + e.getMessage());\n                    }\n\n                    // Guardar cambios (Sobrescritura)\n                    if (is_Editado) {\n                        try (FileWriter fw = new FileWriter(user, false)) { // Al ponerlo en false (o no poner nada), el\n                                                                            // archivo se vacía por completo antes de\n                                                                            // escribir las líneas de nuestra lista.\n                            for (String l : listaEdicion) // for each elemento en el arrayList, escribir elemento +\n                                                          // salto de linea\n                                fw.write(l + \"\\n\");\n                            System.out.println(\" Producto actualizado.\");\n                        } catch (IOException e) {\n                            System.err.println(\"error al actualizar: \" + e.getMessage());\n                        }\n                    }\n                    break;\n\n                case 4:\n                    System.out.print(\"Nombre del producto a eliminar: \");\n                    String productoAEliminar = sc.nextLine();\n                    ArrayList<String> todasLasLineas = new ArrayList<>();\n                    boolean is_productoEncontrado = false;\n                    // Leer user y añadir a un arrayList lo que no queremos borrar\n                    try (Scanner scan = new Scanner(user)) {\n                        while (scan.hasNextLine()) {\n                            String linea = scan.nextLine();\n                            if (!linea.split(\", \")[0].equalsIgnoreCase(productoAEliminar)) { // ! <-- por que solo\n                                                                                             // queremos añadir al array\n                                                                                             // lo que no coincide con\n                                                                                             // productoAEliminar\n                                todasLasLineas.add(linea);\n                            } else\n                                is_productoEncontrado = true;\n\n                        }\n                    } catch (IOException e) {\n                        System.err.println(\" Error al leer: \" + e.getMessage());\n                    }\n                    // Ya tenemos 'salvaguardado' en el arrayList lo que no queremos borrar (lo que\n                    // sí, está en String productoAEliminar )\n                    // Ahora, sobreescribir el user con el arrayList\n\n                    if (is_productoEncontrado) {\n                        try (FileWriter fw = new FileWriter(user, false)) { // false para eliminar datos y escribir\n                                                                            // desde 0\n                            for (String l : todasLasLineas) {\n                                fw.write(l + \"\\n\");\n                            }\n                            System.out.println(\" Producto eliminado.\");\n                        } catch (IOException e) {\n                            System.out.println(\" Error al guardar cambios.\");\n                        }\n                    } else\n                        System.out.println(\" Producto no encontrado.\");\n                    break;\n\n                case 5:\n                    double totalGeneral = 0;\n                    System.out.println(\" Cálculo de Ventas \");\n                    try (Scanner filelector = new Scanner(user)) {\n                        if (!user.exists()) {\n                            System.out.println(\"No hay ventas regsitradas\");\n                            break;\n                        }\n                        while (filelector.hasNextLine()) {\n                            String line = filelector.nextLine();\n                            String[] parts = line.split(\", \");\n\n                            if (parts.length == 3) {\n                                String nombre = parts[0];\n                                int cantidad = Integer.parseInt(parts[1]);\n                                double precio = Double.parseDouble(parts[2]);\n\n                                double subtotal = (cantidad * precio);\n                                totalGeneral += subtotal;\n\n                                System.out.println(\"Producto: \" + nombre + \" / Subtotal: \" + subtotal);\n                            }\n                            System.out.println(\"----------------------------\");\n                            System.out.println(\"VENTA TOTAL GLOBAL: \" + totalGeneral);\n                        }\n                    } catch (IOException e) {\n                        System.err.println(\" error ocurrido: \" + e.getMessage());\n                    }\n                    break;\n\n                case 6:\n                    // Lógica para borrar archivo y salir\n                    System.out.println(\"Archivo, \" + user + \" eliminado. Hasta la vista, baby !\");\n                    break;\n                default:\n                    System.out.println(\"Opción no válida.\");\n            }\n        }\n\n    }\n}"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/java/Worlion.java",
    "content": "import java.io.File;\nimport java.io.FileWriter;\nimport java.io.IOException;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.Paths;\nimport java.util.List;\nimport java.util.Scanner;\n\n\npublic class Worlion {\n    public static final String GREEN = \"\\u001B[32m\";\n    public static final String RED = \"\\u001B[31m\";\n    public static final String RED_BACKGROUND = \"\\u001B[41m\";\n    public static final String ANSI_RESET = \"\\u001B[0m\";\n\n    public static final String SHOP_ITEMS = \"shop.txt\";\n\n    public static void clearScreen() {\n        System.out.print(\"\\033\\143\");\n    }\n\n    Scanner scanner = new Scanner(System.in);\n\n    public static void main(String[] args) {\n\n        Worlion w = new Worlion();\n\n        w.filesBasics();\n        w.extra();\n    }\n\n    public void filesBasics() {\n        /**\n         * EJERCICIO: Básico\n         */\n\n        String fileName = \"Worlion.txt\";\n\n        StringBuffer fileContain = new StringBuffer();\n        fileContain.append(\"Name: Worlion\\n\");\n        fileContain.append(\"Age: 40\\n\");\n        fileContain.append(\"Favourite language: Java\\n\");\n\n        try {\n            System.out.println(\"Writing file...\");\n            FileWriter fileWriter = new FileWriter(fileName);\n\n            fileWriter.write(fileContain.toString());\n            fileWriter.close();\n            System.out.println(\"File writed.\");\n\n            System.out.println(\"Reading file...\");\n            Path path = Paths.get(fileName);\n            List<String> lines = Files.readAllLines(path);\n            for (String line : lines) {\n                System.out.println(\"\\t\" + line);\n            }\n            System.out.println(\"File ended\");\n\n            System.out.println(\"Deleting file...\");\n            File myObj = new File(fileName);\n            if (myObj.delete()) {\n                System.out.println(\"Deleted the file: \" + myObj.getName());\n            } else {\n                System.out.println(\"Failed to delete the file.\");\n            }\n        } catch (IOException e) {\n            System.out.println(\"An error occurred.\");\n            e.printStackTrace();\n        }\n    }\n\n    public void extra() {\n        /**\n         * DIFICULTAD EXTRA (opcional): Shop stock\n         */\n        clearScreen();\n        System.out.println(\"\\n ---- 🌩 DIFICULTAD EXTRA 🌩 ----\\n\");\n\n        String option = \"\";\n        while (!\"0\".equals(option)) {\n            option = showMenu();\n            processOption(option);\n        }\n\n    }\n\n    private String showMenu() {\n\n        System.out.println(\"\\n¿Qué desea hacer?\\n\");\n        System.out.println(\"\\t1.- Añadir producto\");\n        System.out.println(\"\\t2.- Consultar producto\");\n        System.out.println(\"\\t3.- Actualizar producto\");\n        System.out.println(\"\\t4.- Eliminar producto\");\n        System.out.println(\"\\t5.- Consultar totales\");\n\n        System.out.println(RED + \"\\t0.- SALIR\" + ANSI_RESET);\n\n        return scanner.nextLine().trim();\n    }\n\n    private void processOption(String option) {\n        System.out.println(\"Opción elegida: \" + option);\n        switch (option) {\n            case \"1\": // Añadir producto\n                System.out.println(\"Añadir producto: \");\n                addProduct();\n                break;\n            case \"2\": // Consultar producto\n                System.out.println(\"Consultar producto\");\n                findProduct();\n                break;\n            case \"3\": // Actualizar producto\n                System.out.println(\"Actualizar producto\");\n                updateProduct();\n                break;\n            case \"4\": // Eliminar producto\n                System.out.println(\"Eliminar producto\");\n                deleteProduct();\n                break;\n            case \"5\": // Consultar totales\n                System.out.println(\"Consultar totales\");\n                printTotals();\n                break;\n            case \"0\":\n                System.out.println(\"Hasta pronto...\");\n                System.out.println(\"Deleting file...\");\n                File myObj = new File(SHOP_ITEMS);\n                if (myObj.delete()) {\n                    System.out.println(\"Deleted the file: \" + myObj.getName());\n                } else {\n                    System.out.println(\"Failed to delete the file.\");\n                }\n                break;\n            default:\n                System.out.println(RED + \"Opción no valida. Por favor vuelva a intentarlo.\" + ANSI_RESET);\n                option = null;\n                break;\n        }\n    }\n\n    public void addProduct() {\n        System.out.print(\"Escriba el nombre del producto: \");\n        String name = scanner.nextLine();\n\n        int quantity = 0;\n        System.out.print(\"Cantidad: \");\n        String quantityString = scanner.nextLine();\n        try {\n            quantity = Integer.parseInt(quantityString);\n        } catch (NumberFormatException e) {\n            System.err.println(RED + \"Número no valido\" + ANSI_RESET);\n            return;\n        }\n\n        float price = 0.0f;\n        System.out.print(\"Precio unitario del producto: \");\n        String priceString = scanner.nextLine();\n        try {\n            price = Float.parseFloat(priceString);\n        } catch (NumberFormatException e) {\n            System.err.println(RED + \"Número no valido\" + ANSI_RESET);\n            return;\n        }\n\n        Product product = new Product(name, quantity, price);\n        try {\n            FileWriter fileWriter = new FileWriter(SHOP_ITEMS, true);\n            fileWriter.append(product.toString()+\"\\n\");\n            fileWriter.close();\n        } catch (IOException e) {\n            System.err.println(RED + \"Excepción escribiendo el fichero: \" + ANSI_RESET+ e);\n        }\n    }\n\n    public void findProduct() {\n        System.out.print(\"Escriba el nombre del producto a consultar: \");\n        String name = scanner.nextLine();\n        Product product = finProduct(name);\n        if(product!=null) {\n            System.out.print(\"Producto encontrado:\");\n            System.out.print(product.toString());\n            System.out.print(\"Total: \"+product.getTotal());\n        }\n    }\n\n    private Product finProduct(String name) {\n        try {\n            Path path = Paths.get(SHOP_ITEMS);\n            List<String> lines;\n            lines = Files.readAllLines(path);\n            Product p;\n            for (String line : lines) {\n                p = new Product(line);\n                if(p.name.equals(name)){\n                    System.out.print(\"Encontrado!\");\n                    return p;\n                }\n            }\n            System.out.println(\"Producto no encontrado :(\");\n            return null;\n        } catch (IOException e) {\n            System.err.println(RED + \"Excepción leyendo el fichero: \" + ANSI_RESET+ e);\n            return null;\n        }\n    }\n\n    private void updateProduct() {\n        System.out.print(\"Escriba el nombre del producto a modificar: \");\n        String name = scanner.nextLine();\n        Product product = finProduct(name);\n        if(product!=null) {\n            System.out.print(\"\\nEstado actual: \"+ product);\n            \n            System.out.print(\"\\nEscriba nombre nuevo (o enter para dejarlo igual):\");\n            String newName = scanner.nextLine();\n            if( newName==null || newName.isBlank() ){\n                newName = product.name;\n            }\n\n            System.out.print(\"\\nEscriba la nueva cantidad (o enter para dejarlo igual):\");\n            String q = scanner.nextLine();\n            int newQuantity = product.quantity;\n            if( q!=null && !q.isBlank() ){\n                newQuantity = Integer.parseInt(q);\n            }\n\n            System.out.print(\"\\nEscriba precio nuevo (o enter para dejarlo igual):\");\n            float newPrice = product.price;;\n            String p = scanner.nextLine();\n            if( p!=null && !p.isBlank() ){\n                newPrice = Float.parseFloat(p);\n            }\n\n            Product newProduct = new Product(newName, newQuantity, newPrice);\n\n            updateProduct(name, newProduct);\n\n            System.out.print(product.toString());\n            System.out.print(\"Total: \"+product.getTotal());\n        }\n    }\n\n    private void updateProduct(String oldName, Product value) {\n        StringBuilder s = new StringBuilder();\n\n        Path path = Paths.get(SHOP_ITEMS);\n        List<String> lines;\n        try {\n            lines = Files.readAllLines(path);\n            Product p;\n            for (String line : lines) {\n                p = new Product(line);\n                if(p.name.equals(oldName)){\n                    s.append(value+\"\\n\");\n                }\n                else {\n                    s.append(p+\"\\n\");\n                }\n            }\n        \n            FileWriter fileWriter = new FileWriter(SHOP_ITEMS);\n            fileWriter.write(s.toString());\n            fileWriter.close();\n        } catch (IOException e) {\n            System.err.println(RED + \"Excepción actualizando el fichero: \" + ANSI_RESET+ e);\n        }\n\n    }\n\n    private void deleteProduct() {\n        System.out.print(\"Escriba el nombre del producto a \"+RED_BACKGROUND+\"eliminar: \"+ANSI_RESET);\n        String name = scanner.nextLine();\n        Product product = finProduct(name);\n\n        if(product!=null) {\n            StringBuilder s = new StringBuilder();\n\n            Path path = Paths.get(SHOP_ITEMS);\n            List<String> lines;\n            try {\n                lines = Files.readAllLines(path);\n                Product p;\n                for (String line : lines) {\n                    p = new Product(line);\n                    if(!p.name.equals(product.name)){\n                        s.append(line+\"\\n\");\n                    }\n                }\n            \n                FileWriter fileWriter = new FileWriter(SHOP_ITEMS);\n                fileWriter.write(s.toString());\n                fileWriter.close();\n            } catch (IOException e) {\n                System.err.println(RED + \"Excepción actualizando el fichero: \" + ANSI_RESET+ e);\n            }\n        }\n    \n    }\n    \n    private void printTotals() {\n        double total = 0;\n        try {\n            System.out.println(\"\\tNombre\\tCantidad\\tPrecio\\tTOTAL\");\n            Path path = Paths.get(SHOP_ITEMS);\n            List<String> lines;\n            lines = Files.readAllLines(path);\n            Product p;\n            int i = 0;\n            for (String line : lines) {\n                p = new Product(line);\n                System.out.println(\"\" + ++i + \"\\t\"+ p.toString() + \"\\t\" + p.getTotal());\n                total += p.getTotal();\n            }\n            total = Math.round(total*100)/100.0f;\n            System.out.println(\"\\n\\tTOTAL: \" + total + \" €\");\n        } catch (IOException e) {\n            System.err.println(RED + \"Excepción leyendo el fichero: \" + ANSI_RESET+ e);\n        }\n    }\n}\n    class Product {\n        String name;\n        int quantity;\n        float price;\n\n        public Product(String name, int quantity, float price) {\n            this.name = name;\n            this.quantity = quantity;\n            this.price = (Math.round(price*100)/100.0f);\n        }\n\n        public Product(String fullLine) {\n            String[] values = fullLine.split(\",\\t\");\n            this.name = values[0];\n            this.quantity = Integer.parseInt(values[1]);\n            this.price = (Math.round(Float.parseFloat(values[2])*100)/100.0f);\n        }\n\n        public float getTotal() {\n            float r = this.price*this.quantity;\n            return Math.round(r*100)/100.0f;\n        }\n\n        public String toString() {\n            return this.name + \",\\t\" + this.quantity + \",\\t\" + this.price;\n        }\n    }\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/java/alexdevrep.java",
    "content": "package _11_Manejo_de_ficheros_;\n/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un\n * archivo .txt.\n * - Cada producto se guarda en una línea del arhivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n */\n\n//Importamos las librerías necesarias para el proyecto\nimport java.io.*;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.Objects;\n\npublic class _11_Manejo_de_ficheros {\n    public static void main (String args[]){\n        //Creamos el archivo txt\n        File file = new File(\"alexdevrep.txt\");\n        String contenido =\"Alejandro\\n24\\nJava\\n\";\n        //Añadimos contenido al archivo\n        escribirArchivo(file, contenido, false);\n        //Leemos el archivo\n        System.out.println(\"Contenido del archivo:\\n\" + leerArchivo(file));\n        //Borramos el archivo\n        boolean isDelete = file.delete();\n\n\n    }\n\n    static void escribirArchivo(File file, String content, boolean append) {\n        if (!file.exists()) {\n            try {\n                file.createNewFile();\n            } catch (IOException e) {\n                e.printStackTrace();\n            }\n        }\n\n        try (Writer w = new FileWriter(file, append);\n             BufferedWriter bw = new BufferedWriter(w)) {\n            bw.write(content);\n            bw.flush();\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n    }\n\n    static String leerArchivo(File file) {\n        StringBuilder sb = new StringBuilder();\n\n        try (Reader r = new FileReader(file);\n             BufferedReader br = new BufferedReader(r))  {\n            String linea;\n            while ((linea = br.readLine()) != null) {\n                sb.append(linea).append(\"\\n\");\n            }\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n\n        return sb.toString();\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/java/asjordi.java",
    "content": "import java.io.*;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.Objects;\nimport java.util.Scanner;\n\npublic class Main {\n\n    public static void main(String[] args) throws IOException {\n        File file = new File(\"asjordi.txt\");\n        String contenido = \"Jordi Ayala\\n20\\nJava\\n\";\n\n        escribirArchivo(file, contenido, false);\n\n        System.out.println(\"Contenido del archivo:\\n\" + leerArchivo(file));\n\n        boolean isDelete = file.delete();\n        System.out.println(isDelete ? \"El archivo fue eliminado\" : \"El archivo no fue eliminado\");\n\n        ventas();\n    }\n\n    /**\n     * DIFICULTAD EXTRA (opcional):\n     * Desarrolla un programa de gestión de ventas que almacena sus datos en un archivo .txt.\n     * - Cada producto se guarda en una línea del arhivo de la siguiente manera: [nombre_producto], [cantidad_vendida], [precio].\n     * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n     * actualizar, eliminar productos y salir.\n     * - También debe poseer opciones para calcular la venta total y por producto.\n     * - La opción salir borra el .txt.\n     */\n\n    static class Venta {\n        String nombre;\n        String cantidad;\n        String precio;\n\n        public String getNombre() {\n            return nombre;\n        }\n\n        public void setNombre(String nombre) {\n            this.nombre = nombre;\n        }\n\n        public String getCantidad() {\n            return cantidad;\n        }\n\n        public void setCantidad(String cantidad) {\n            this.cantidad = cantidad;\n        }\n\n        public String getPrecio() {\n            return precio;\n        }\n\n        public void setPrecio(String precio) {\n            this.precio = precio;\n        }\n\n        public String getInfo() {\n            return nombre + \", \" + cantidad + \", \" + precio + \"\\n\";\n        }\n\n        @Override\n        public String toString() {\n            return \"Venta{\" +\n                    \"nombre='\" + nombre + '\\'' +\n                    \", cantidad='\" + cantidad + '\\'' +\n                    \", precio='\" + precio + '\\'' +\n                    '}';\n        }\n    }\n\n    static void ventas() {\n        File file = new File(\"ventas.txt\");\n        Scanner sc = new Scanner(System.in);\n        String opcion = \"\";\n\n        while (!opcion.equals(\"6\")) {\n            mostrarOpciones();\n            opcion = sc.nextLine();\n\n            switch (opcion) {\n                case \"1\":\n                    Venta v = new Venta();\n                    System.out.print(\"Ingrese el nombre del producto: \");\n                    v.setNombre(sc.nextLine());\n                    System.out.print(\"Ingrese la cantidad: \");\n                    v.setCantidad(sc.nextLine());\n                    System.out.print(\"Ingrese el precio: \");\n                    v.setPrecio(sc.nextLine());\n                    escribirArchivo(file, v.getInfo(), true);\n                    break;\n                case \"2\":\n                    System.out.println(\"Ventas registradas:\");\n                    System.out.println(obtenerVentas(file));\n                    break;\n                case \"3\":\n                    System.out.println(\"Actualizar venta\");\n                    Venta venta = new Venta();\n                    System.out.print(\"Ingrese el nombre del producto a actualizar: \");\n                    venta.setNombre(sc.nextLine());\n                    System.out.print(\"Ingrese la cantidad: \");\n                    venta.setCantidad(sc.nextLine());\n                    System.out.print(\"Ingrese el precio: \");\n                    venta.setPrecio(sc.nextLine());\n                    actualizarVenta(file, venta);\n                    break;\n                case \"4\":\n                    System.out.println(\"Eliminar venta\");\n                    System.out.print(\"Ingrese el nombre del producto a eliminar: \");\n                    eliminarVenta(file, sc.nextLine());\n                    break;\n                case \"5\":\n                    calcularTotal(file);\n                    break;\n                case \"6\":\n                    System.out.println(\"Saliendo del sistema de ventas...\");\n                    file.delete();\n                    break;\n                default:\n                    System.out.println(\"Opción no válida\");\n                    break;\n            }\n        }\n    }\n\n    static void calcularTotal(File file) {\n        List<Venta> ventas = obtenerVentas(file);\n        double total = 0;\n\n        for (Venta v : ventas) {\n            total += Double.parseDouble(v.getCantidad()) * Double.parseDouble(v.getPrecio());\n        }\n\n        System.out.println(\"El total de ventas es: \" + total);\n    }\n\n    static void eliminarVenta(File file, String nombre) {\n        List<Venta> ventas = obtenerVentas(file);\n\n        for (Venta v : ventas) {\n            if (v.getNombre().equals(nombre)) {\n                ventas.remove(v);\n                System.out.println(\"Venta eliminada\");\n                break;\n            }\n        }\n\n        file.delete();\n        ventas.forEach(v -> escribirArchivo(file, v.getInfo(), true));\n    }\n\n    static void actualizarVenta(File file, Venta venta) {\n        List<Venta> ventas = obtenerVentas(file);\n\n        for (Venta v : ventas) {\n            if (v.getNombre().equals(venta.getNombre())) {\n                v.setNombre(venta.getNombre());\n                v.setCantidad(venta.getCantidad());\n                v.setPrecio(venta.getPrecio());\n                System.out.println(\"Venta actualizada\");\n                break;\n            }\n        }\n\n        file.delete();\n        ventas.forEach(v -> escribirArchivo(file, v.getInfo(), true));\n    }\n\n    static void mostrarOpciones() {\n        System.out.println(\"Bienvenido al sistema de ventas\");\n        System.out.println(\"Favor de seleccionar una opción:\");\n        System.out.println(\"1- Agregar venta\");\n        System.out.println(\"2- Mostrar ventas\");\n        System.out.println(\"3- Actualizar venta\");\n        System.out.println(\"4- Eliminar venta\");\n        System.out.println(\"5- Calcular total de ventas\");\n        System.out.println(\"6- Salir\");\n    }\n\n    static void escribirArchivo(File file, String content, boolean append) {\n        if (!file.exists()) {\n            try {\n                file.createNewFile();\n            } catch (IOException e) {\n                e.printStackTrace();\n            }\n        }\n\n        try (Writer w = new FileWriter(file, append);\n             BufferedWriter bw = new BufferedWriter(w)) {\n            bw.write(content);\n            bw.flush();\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n    }\n\n    static String leerArchivo(File file) {\n        StringBuilder sb = new StringBuilder();\n\n        try (Reader r = new FileReader(file);\n             BufferedReader br = new BufferedReader(r))  {\n            String linea;\n            while ((linea = br.readLine()) != null) {\n                sb.append(linea).append(\"\\n\");\n            }\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n\n        return sb.toString();\n    }\n\n    static List<Venta> obtenerVentas(File file) {\n        List<Venta> list = new LinkedList<>();\n\n        try (Reader r = new FileReader(file);\n             BufferedReader br = new BufferedReader(r))  {\n            String linea;\n            while ((linea = br.readLine()) != null) {\n                String[] partes = linea.split(\",\");\n                Venta v = new Venta();\n                v.setNombre(partes[0].trim());\n                v.setCantidad(partes[1].trim());\n                v.setPrecio(partes[2].trim());\n                list.add(v);\n            }\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n\n        return list;\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/java/cesar-ch.java",
    "content": "import java.io.BufferedReader;\nimport java.io.FileReader;\nimport java.io.FileWriter;\nimport java.io.IOException;\nimport java.io.InputStreamReader;\n\npublic class Main {\n    public static void main(String[] args) {\n        try {\n            crearArchivo();\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n    }\n\n    /*\n     * #11 MANEJO DE FICHEROS\n     */\n\n    public static void crearArchivo() throws IOException {\n        String nombre = \"cesar-ch\";\n        int edad = 4;\n        String lenguajeFavorito = \"JavaScript\";\n        String contenido = \"Nombre: \" + nombre + \"\\nEdad: \" + edad + \"\\nLenguaje de programación favorito: \"\n                + lenguajeFavorito;\n        FileWriter writer = new FileWriter(nombre + \".txt\");\n        writer.write(contenido);\n        writer.close();\n        System.out.println(\"1. Archivo \" + nombre + \".txt creado exitosamente\");\n        System.out.println(\"2. Contenido añadido al archivo\");\n        leerArchivo(nombre);\n    }\n\n    public static void leerArchivo(String nombre) throws IOException {\n        BufferedReader reader = new BufferedReader(new FileReader(nombre + \".txt\"));\n        System.out.println(\"3. Contenido leído del archivo\");\n        String line;\n        while ((line = reader.readLine()) != null) {\n            System.out.println(line);\n        }\n        reader.close();\n        borrarArchivo(nombre);\n    }\n\n    public static void borrarArchivo(String nombre) {\n        if (new java.io.File(nombre + \".txt\").delete()) {\n            System.out.println(\"4. Archivo eliminado exitosamente\");\n        } else {\n            System.out.println(\"No se pudo eliminar el archivo\");\n        }\n        menu();\n    }\n\n    /*\n     * DIFICULTAD EXTRA\n    */\n\n    public static void menu() {\n        System.out.println(\"\\n=== Gestión de Ventas ===\");\n        System.out.println(\"1. Añadir producto\");\n        System.out.println(\"2. Consultar producto\");\n        System.out.println(\"3. Actualizar producto\");\n        System.out.println(\"4. Eliminar producto\");\n        System.out.println(\"5. Calcular venta total\");\n        System.out.println(\"6. Calcular venta por producto\");\n        System.out.println(\"7. Salir\");\n        System.out.println(\"===========================\");\n        seleccionarOpcion();\n    }\n\n    public static void seleccionarOpcion() {\n        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));\n        try {\n            System.out.print(\"Seleccione una opción: \");\n            String opcion = reader.readLine();\n            switch (opcion) {\n                case \"1\":\n                    añadirProducto();\n                    break;\n                case \"2\":\n                    consultarProducto();\n                    break;\n                case \"3\":\n                    actualizarProducto();\n                    break;\n                case \"4\":\n                    eliminarProducto();\n                    break;\n                case \"5\":\n                    calcularVentaTotal();\n                    break;\n                case \"6\":\n                    calcularVentaPorProducto();\n                    break;\n                case \"7\":\n                    eliminarArchivo();\n                    reader.close();\n                    break;\n                default:\n                    seleccionarOpcion();\n            }\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n    }\n\n    public static void añadirProducto() throws IOException {\n        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));\n        System.out.print(\"Introduce el nombre del producto: \");\n        String nombre = reader.readLine();\n        System.out.print(\"Introduce la cantidad del producto: \");\n        String cantidad = reader.readLine();\n        System.out.print(\"Introduce el precio del producto: \");\n        String precio = reader.readLine();\n        String producto = nombre + \",\" + cantidad + \",\" + precio + \"\\n\";\n        FileWriter writer = new FileWriter(\"productos.txt\", true);\n        writer.write(producto);\n        writer.close();\n        System.out.println(\"Producto añadido correctamente\");\n        menu();\n    }\n\n    public static void consultarProducto() throws IOException {\n        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));\n        System.out.print(\"Introduce el nombre del producto a consultar: \");\n        String nombre = reader.readLine();\n        BufferedReader fileReader = new BufferedReader(new FileReader(\"productos.txt\"));\n        String line;\n        boolean encontrado = false;\n        while ((line = fileReader.readLine()) != null) {\n            String[] parts = line.split(\",\");\n            if (parts[0].equals(nombre)) {\n                System.out.println(\"Producto encontrado: \" + line);\n                encontrado = true;\n                break;\n            }\n        }\n        if (!encontrado) {\n            System.out.println(\"Producto no encontrado\");\n        }\n        fileReader.close();\n        menu();\n    }\n\n    public static void actualizarProducto() throws IOException {\n        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));\n        System.out.print(\"Introduce el nombre del producto a actualizar: \");\n        String nombre = reader.readLine();\n        System.out.print(\"Introduce la nueva cantidad del producto: \");\n        String cantidad = reader.readLine();\n        System.out.print(\"Introduce el nuevo precio del producto: \");\n        String precio = reader.readLine();\n        String nuevoProducto = nombre + \",\" + cantidad + \",\" + precio + \"\\n\";\n        BufferedReader fileReader = new BufferedReader(new FileReader(\"productos.txt\"));\n        StringBuilder fileContent = new StringBuilder();\n        String line;\n        boolean encontrado = false;\n        while ((line = fileReader.readLine()) != null) {\n            String[] parts = line.split(\",\");\n            if (parts[0].equals(nombre)) {\n                fileContent.append(nuevoProducto);\n                encontrado = true;\n            } else {\n                fileContent.append(line).append(\"\\n\");\n            }\n        }\n        fileReader.close();\n        if (encontrado) {\n            FileWriter writer = new FileWriter(\"productos.txt\");\n            writer.write(fileContent.toString());\n            writer.close();\n            System.out.println(\"Producto actualizado correctamente\");\n        } else {\n            System.out.println(\"Producto no encontrado\");\n        }\n        menu();\n    }\n\n    public static void eliminarProducto() throws IOException {\n        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));\n        System.out.print(\"Introduce el nombre del producto a eliminar: \");\n        String nombre = reader.readLine();\n        BufferedReader fileReader = new BufferedReader(new FileReader(\"productos.txt\"));\n        StringBuilder fileContent = new StringBuilder();\n        String line;\n        boolean encontrado = false;\n        while ((line = fileReader.readLine()) != null) {\n            String[] parts = line.split(\",\");\n            if (!parts[0].equals(nombre)) {\n                fileContent.append(line).append(\"\\n\");\n            } else {\n                encontrado = true;\n            }\n        }\n        fileReader.close();\n        if (encontrado) {\n            FileWriter writer = new FileWriter(\"productos.txt\");\n            writer.write(fileContent.toString());\n            writer.close();\n            System.out.println(\"Producto eliminado correctamente\");\n        } else {\n            System.out.println(\"Producto no encontrado\");\n        }\n        menu();\n    }\n\n    public static void calcularVentaTotal() throws IOException {\n        BufferedReader fileReader = new BufferedReader(new FileReader(\"productos.txt\"));\n        String line;\n        double total = 0;\n        while ((line = fileReader.readLine()) != null) {\n            String[] parts = line.split(\",\");\n            total += Integer.parseInt(parts[1]) * Double.parseDouble(parts[2]);\n        }\n        fileReader.close();\n        System.out.println(\"Venta total: \" + total);\n        menu();\n    }\n\n    public static void calcularVentaPorProducto() throws IOException {\n        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));\n        System.out.print(\"Introduce el nombre del producto a consultar: \");\n        String nombre = reader.readLine();\n        BufferedReader fileReader = new BufferedReader(new FileReader(\"productos.txt\"));\n        String line;\n        boolean encontrado = false;\n        while ((line = fileReader.readLine()) != null) {\n            String[] parts = line.split(\",\");\n            if (parts[0].equals(nombre)) {\n                double total = Integer.parseInt(parts[1]) * Double.parseDouble(parts[2]);\n                System.out.println(\"Venta total: \" + total);\n                encontrado = true;\n                break;\n            }\n        }\n        if (!encontrado) {\n            System.out.println(\"Producto no encontrado\");\n        }\n        fileReader.close();\n        menu();\n    }\n\n    public static void eliminarArchivo() {\n        if (new java.io.File(\"productos.txt\").delete()) {\n            System.out.println(\"Archivo eliminado correctamente\");\n        } else {\n            System.out.println(\"No se pudo eliminar el archivo\");\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/java/chartypes.java",
    "content": "\nimport java.io.IOException;\nimport java.nio.file.Files;\nimport java.nio.file.NoSuchFileException;\nimport java.nio.file.Path;\nimport java.nio.file.StandardOpenOption;\nimport java.util.List;\nimport java.util.Scanner;\n\npublic class FileManager {\n  public static void main(String[] args) {\n    try {\n      exercise();\n      extra();\n    } catch (IOException e) {\n      e.getMessage();\n      e.printStackTrace();\n    }\n\n  }\n\n  private static void exercise() throws IOException {\n    Path path = Path.of(\"chartypes.txt\");\n    if (!Files.exists(path))\n      Files.createFile(path);\n\n    String content = \"\"\"\n        Name                        :      Carlos.\n        Age                         :      22.\n        Fav Programming Lenguague   :      Python.\n        \"\"\";\n    Files.writeString(path, content);\n    List<String> data = Files.readAllLines(path);\n    data.forEach(System.out::println);\n    Files.delete(path);\n\n  }\n\n  private static void extra() throws IOException {\n    Path path = Path.of(\"sales.txt\");\n    SalesManager salesManager = new SalesManager(path);\n    salesManager.start();\n\n  }\n}\n\nclass SalesManager {\n  private Path path;\n  private Scanner scanner;\n\n  public SalesManager(Path path) {\n    try {\n      this.path = path;\n      scanner = new Scanner(System.in);\n      Files.writeString(path, \"\");\n    } catch (IOException e) {\n      System.out.println(e);\n    }\n  }\n\n  public void start() {\n    int option = 0;\n    while (true) {\n      System.out.println(\"----------MENU----------\");\n      System.out.println(\"1 - Show all products\");\n      System.out.println(\"2 - Add product\");\n      System.out.println(\"3 - Check product\");\n      System.out.println(\"4 - Update product\");\n      System.out.println(\"5 - Delete product\");\n      System.out.println(\"6 - Calculate Total Sales\");\n      System.out.println(\"7 - Calculate Total Sales per product\");\n      System.out.println(\"8 - Exit\");\n      System.out.print(\"\\nPick an option: \");\n\n      if (scanner.hasNextInt())\n        option = scanner.nextInt();\n\n      switch (option) {\n        case 1:\n          readFile();\n          break;\n        case 2:\n          StringBuffer line = new StringBuffer();\n          System.out.println(\"Product name: \");\n          line.append(scanner.next()).append(\",\");\n          System.out.println(\"Quantity: \");\n          line.append(scanner.next()).append(\",\");\n          System.out.println(\"Price: \");\n          line.append(scanner.next());\n          addProduct(line.toString());\n          break;\n        case 3:\n          System.out.println(\"Product name to look for: \");\n          try {\n            String name = scanner.next();\n            searchProduct(name);\n          } catch (Exception e) {\n            System.out.println(e);\n            System.out.println(\"You must insert a valid name\");\n          }\n          break;\n        case 4:\n          StringBuilder newLine = new StringBuilder();\n          System.out.println(\"Product name: \");\n          String productName = scanner.next();\n          newLine.append(productName).append(\",\");\n          System.out.println(\"Quantity: \");\n          newLine.append(scanner.next()).append(\",\");\n          System.out.println(\"Price: \");\n          newLine.append(scanner.next());\n          updateProduct(productName, newLine.toString());\n          break;\n        case 5:\n          System.out.println(\"Product name to delete: \");\n          String name = scanner.next();\n          deleteProduct(name);\n          break;\n        case 6:\n          totalSales();\n          break;\n        case 7:\n          salesPerProduct();\n          break;\n        case 8:\n          deleteFile();\n          return;\n        default:\n          System.out.println(\"You have to pick a valid option.\");\n          break;\n      }\n\n    }\n  }\n\n  private void readFile() {\n    try (Scanner reader = new Scanner(path)) {\n      while (reader.hasNext())\n        System.out.println(reader.next());\n    } catch (Exception e) {\n      System.out.println(e);\n      System.out.println(\"There was an error trying to read the file\");\n    }\n  }\n\n  private void addProduct(String product) {\n    if (!Services.validateProduct(product)) {\n      System.out.println(\"Please insert the correct values\");\n      return;\n    }\n    try {\n      Files.writeString(path, product + \"\\n\", StandardOpenOption.APPEND);\n      System.out.println(\"Product added successfully\");\n    } catch (IOException e) {\n      System.out.println(e);\n      System.out.println(\"Error trying to insert the product\");\n    }\n\n  }\n\n  private void searchProduct(String productName) {\n    boolean found = false;\n    try (Scanner reader = new Scanner(path)) {\n      reader.useDelimiter(\"\\n\");\n      while (reader.hasNext()) {\n        String product = reader.next();\n        String[] parts = product.split(\",\");\n        if (parts[0].equalsIgnoreCase(productName))\n          found = true;\n        if (found)\n          System.out.println(\"Product found -> \" + product);\n        else {\n          System.out.println(\"Product not found\");\n        }\n\n      }\n    } catch (Exception e) {\n      System.out.println(e);\n      System.out.println(\"Error trying to find the product\");\n    }\n  }\n\n  private void updateProduct(String productName, String newLine) {\n    StringBuilder content = new StringBuilder();\n    try (Scanner reader = new Scanner(path)) {\n      reader.useDelimiter(\"\\n\");\n      while (reader.hasNext()) {\n        String next = reader.next();\n        String[] parts = next.split(\",\");\n        if (parts[0].equalsIgnoreCase(productName))\n          content.append(newLine).append(\"\\n\");\n        else {\n          content.append(next).append(\"\\n\");\n        }\n      }\n      Files.writeString(path, content);\n      System.out.println(\"Product updated successfully\");\n\n    } catch (Exception e) {\n      System.out.println(e);\n      System.out.println(\"We found some issues trying to update your product\");\n    }\n  }\n\n  private void totalSales() {\n    double total = 0;\n    try (Scanner reader = new Scanner(path)) {\n      reader.useDelimiter(\"\\n\");\n      while (reader.hasNext()) {\n        String[] line = reader.next().split(\",\");\n        int quantity = Integer.parseInt(line[1]);\n        double price = Double.parseDouble(line[2]);\n        total = total + (quantity * price);\n      }\n      System.out.println(\"Total sales: \" + total);\n\n    } catch (Exception e) {\n      System.out.println(e);\n      System.out.println(\"We found some issues trying to get the total sales\");\n    }\n\n  }\n\n  private void salesPerProduct() {\n    try (Scanner reader = new Scanner(path)) {\n      reader.useDelimiter(\"\\n\");\n      while (reader.hasNext()) {\n        String[] line = reader.next().split(\",\");\n        String productName = line[0];\n        int quantity = Integer.parseInt(line[1]);\n        double price = Double.parseDouble(line[2]);\n        double total = price * quantity;\n\n        System.out.println(\n            \"Product: \" + productName + \" quantity: \" + quantity + \" price: \" + price + \" Total Sales: \" + total);\n      }\n    } catch (Exception e) {\n      System.out.println(e);\n      System.out.println(\"We found some issues trying to get the total sales of your products\");\n    }\n  }\n\n  private void deleteProduct(String productName) {\n    StringBuilder content = new StringBuilder();\n    try (Scanner reader = new Scanner(path)) {\n      reader.useDelimiter(\"\\n\");\n      while (reader.hasNext()) {\n        String next = reader.next();\n        String[] parts = next.split(\",\");\n        if (!parts[0].equalsIgnoreCase(productName))\n          content.append(next).append(\"\\n\");\n      }\n      Files.writeString(path, content.toString());\n      System.out.println(\"Product deleted successfully\");\n    } catch (Exception e) {\n      System.out.println(e);\n      System.out.println(\"We found some issues trying to delete your product\");\n    }\n  }\n\n  private void deleteFile() {\n    try {\n      Files.delete(path);\n    } catch (IOException e) {\n      e.printStackTrace();\n    }\n  }\n\n}\n\nclass Services {\n  public static String formatingProduct(String productName, int quantity, double price) {\n    String product = String.format(\"%s , %s , %s\", productName, quantity, price);\n    return product;\n  }\n\n  public static boolean validateProduct(String product) {\n    try {\n      String[] parts = product.split(\",\");\n      String productName = parts[0];\n      int quantity = Integer.parseInt(parts[1]);\n      double price = Double.parseDouble(parts[2]);\n    } catch (ArrayIndexOutOfBoundsException | NumberFormatException e) {\n      System.out.println(e);\n      return false;\n    }\n    return true;\n\n  }\n}\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/java/danhingar.java",
    "content": "import java.io.IOException;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.StandardOpenOption;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Scanner;\n\npublic class danhingar {\n\n    public static void main(String[] args) throws IOException {\n        try {\n            String content = \"\"\"\n                    Nombre:   Daniel\n                    Edad:     27\n                    Lenguaje: Java\n                    \"\"\";\n\n            Path path = Path.of(\"danhingar.txt\");\n            Files.writeString(path, content);\n\n            Files.readAllLines(path).forEach(line -> System.out.println(line));\n\n            Files.delete(path);\n        } catch (Exception e) {\n            System.out.println(\"Se ha producido un error\");\n        }\n\n        salesManager();\n    }\n\n    List<Product> products = new ArrayList<>();\n\n    // Extra\n    private static void salesManager() throws IOException {\n        Path path = Path.of(\"stockManager1.txt\");\n        Files.writeString(path, \"\");\n        while (Boolean.TRUE) {\n            Scanner sc = new Scanner(System.in);\n            System.out.println(\"1. Añadir producto\");\n            System.out.println(\"2. Consultar producto\");\n            System.out.println(\"3. Actualizar producto\");\n            System.out.println(\"4. Eliminar producto\");\n            System.out.println(\"5. Mostrar productos\");\n            System.out.println(\"6. Calcular venta total\");\n            System.out.println(\"7. Calcular venta total por producto\");\n            System.out.println(\"8. Salir\");\n            System.out.print(\"Selecciona una opción: \");\n            String option = sc.nextLine();\n            switch (option) {\n                case \"1\":\n                    System.out.print(\"Nombre: \");\n                    String name = sc.nextLine();\n                    System.out.print(\"Cantidad: \");\n                    String quantity = sc.nextLine();\n                    System.out.print(\"Precio: \");\n                    String price = sc.nextLine();\n                    String product = String.format(\"%s, %s, %s \\n\", name, quantity, price);\n                    Files.writeString(path, product, StandardOpenOption.APPEND);\n                    break;\n                case \"2\":\n                    System.out.print(\"Buscar el producto: \");\n                    String searchName = sc.nextLine();\n                    String[] result = Files.readAllLines(path).stream().map(r -> r.trim().split(\",\"))\n                            .filter(array -> array[0].equalsIgnoreCase(searchName)).findFirst().orElse(null);\n                    System.out.println(result != null ? String.format(\"%s,%s,%s\", result[0], result[1], result[2])\n                            : \"No existe el producto \" + searchName);\n                    break;\n                case \"3\":\n                    System.out.print(\"Nombre: \");\n                    String name1 = sc.nextLine();\n                    System.out.print(\"Cantidad: \");\n                    String quantity1 = sc.nextLine();\n                    System.out.print(\"Precio: \");\n                    String price1 = sc.nextLine();\n                    String content = \"\";\n                    for (String line : Files.readAllLines(path)) {\n                        if (line.trim().split(\",\")[0].equalsIgnoreCase(name1)) {\n                            content = content.concat(String.format(\"%s, %s, %s \\n\", name1, quantity1, price1));\n                        } else {\n                            content = content.concat(line + \"\\n\");\n                        }\n                    }\n                    Files.writeString(path, content);\n                    break;\n                case \"4\":\n                    System.out.print(\"Eliminar el producto: \");\n                    String deleteName = sc.nextLine();\n                    String lines = Files.readAllLines(path).stream().map(r -> r.trim().split(\",\"))\n                            .filter(array -> !array[0].equalsIgnoreCase(deleteName))\n                            .map(x -> String.format(\"%s, %s, %s \\n\", x[0], x[1], x[2])).reduce(String::concat)\n                            .orElse(\"\");\n                    Files.writeString(path, lines);\n                    break;\n                case \"5\":\n                    Files.readAllLines(path).forEach(line -> System.out.println(line));\n                    break;\n                case \"6\":\n                    Double totalSales = Files.readAllLines(path).stream().map(l -> l.trim().split(\",\"))\n                            .map(h -> Double.parseDouble(h[1]) * Double.parseDouble(h[2]))\n                            .mapToDouble(Double::doubleValue).sum();\n                    System.out.println(\"Ventas totales: \" + totalSales);\n                    break;\n                case \"7\":\n                    System.out.print(\"Nombre el producto: \");\n                    String nameProduct = sc.nextLine();\n                    Files.readAllLines(path).stream().map(l -> l.trim().split(\",\"))\n                            .filter(array -> array[0].equalsIgnoreCase(nameProduct))\n                            .forEach(element-> System.out.println(\"Ventas totales de \" +nameProduct+\" : \" + Double.parseDouble(element[1]) * Double.parseDouble(element[2])));\n                    break;\n                case \"8\":\n                    sc.close();\n                    Files.delete(path);\n                    System.exit(0);\n                    break;\n\n                default:\n                    System.out.println(\"Opción no válida\");\n                    break;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/java/eulogioep.java",
    "content": "import java.io.*;\nimport java.util.*;\n\npublic class eulogioep {\n    // Constantes para el nombre del archivo y el archivo de ventas\n    private static final String FILENAME = \"eulogioep.txt\";\n    private static final String SALES_FILENAME = \"ventas.txt\";\n\n    public static void main(String[] args) {\n        // Parte 1: Creación y manipulación de archivos\n        crearArchivoPersonal();\n        \n        // Parte 2: Gestión de ventas (DIFICULTAD EXTRA)\n        gestionVentas();\n    }\n\n    // Método para crear y manipular el archivo personal\n    private static void crearArchivoPersonal() {\n        try {\n            // Creación del archivo\n            FileWriter fw = new FileWriter(FILENAME);\n            BufferedWriter bw = new BufferedWriter(fw);\n\n            // Escritura en el archivo\n            bw.write(\"Nombre: Eulogio\");\n            bw.newLine();\n            bw.write(\"Edad: 30\");\n            bw.newLine();\n            bw.write(\"Lenguaje de programación favorito: Java\");\n            bw.close();\n\n            System.out.println(\"Archivo creado y escrito con éxito.\");\n\n            // Lectura y impresión del contenido\n            BufferedReader br = new BufferedReader(new FileReader(FILENAME));\n            String linea;\n            System.out.println(\"Contenido del archivo:\");\n            while ((linea = br.readLine()) != null) {\n                System.out.println(linea);\n            }\n            br.close();\n\n            // Borrado del archivo\n            File file = new File(FILENAME);\n            if (file.delete()) {\n                System.out.println(\"Archivo borrado con éxito.\");\n            } else {\n                System.out.println(\"No se pudo borrar el archivo.\");\n            }\n        } catch (IOException e) {\n            System.out.println(\"Error de E/S: \" + e.getMessage());\n        }\n    }\n\n    // Método para la gestión de ventas\n    private static void gestionVentas() {\n        Scanner scanner = new Scanner(System.in);\n        boolean salir = false;\n\n        while (!salir) {\n            System.out.println(\"\\n--- Gestión de Ventas ---\");\n            System.out.println(\"1. Añadir producto\");\n            System.out.println(\"2. Consultar productos\");\n            System.out.println(\"3. Actualizar producto\");\n            System.out.println(\"4. Eliminar producto\");\n            System.out.println(\"5. Calcular venta total\");\n            System.out.println(\"6. Calcular venta por producto\");\n            System.out.println(\"7. Salir\");\n            System.out.print(\"Seleccione una opción: \");\n\n            int opcion = scanner.nextInt();\n            scanner.nextLine(); // Consumir el salto de línea\n\n            switch (opcion) {\n                case 1:\n                    anadirProducto(scanner);\n                    break;\n                case 2:\n                    consultarProductos();\n                    break;\n                case 3:\n                    actualizarProducto(scanner);\n                    break;\n                case 4:\n                    eliminarProducto(scanner);\n                    break;\n                case 5:\n                    calcularVentaTotal();\n                    break;\n                case 6:\n                    calcularVentaPorProducto(scanner);\n                    break;\n                case 7:\n                    salir = true;\n                    borrarArchivoVentas();\n                    break;\n                default:\n                    System.out.println(\"Opción no válida.\");\n            }\n        }\n        scanner.close();\n    }\n\n    // Método para añadir un producto al archivo de ventas\n    private static void anadirProducto(Scanner scanner) {\n        try {\n            FileWriter fw = new FileWriter(SALES_FILENAME, true);\n            BufferedWriter bw = new BufferedWriter(fw);\n\n            System.out.print(\"Nombre del producto: \");\n            String nombre = scanner.nextLine();\n            System.out.print(\"Cantidad vendida: \");\n            int cantidad = scanner.nextInt();\n            System.out.print(\"Precio: \");\n            double precio = scanner.nextDouble();\n\n            bw.write(String.format(\"%s, %d, %.2f\", nombre, cantidad, precio));\n            bw.newLine();\n            bw.close();\n\n            System.out.println(\"Producto añadido con éxito.\");\n        } catch (IOException e) {\n            System.out.println(\"Error al añadir producto: \" + e.getMessage());\n        }\n    }\n\n    // Método para consultar los productos en el archivo de ventas\n    private static void consultarProductos() {\n        try {\n            BufferedReader br = new BufferedReader(new FileReader(SALES_FILENAME));\n            String linea;\n            System.out.println(\"\\nProductos:\");\n            while ((linea = br.readLine()) != null) {\n                System.out.println(linea);\n            }\n            br.close();\n        } catch (IOException e) {\n            System.out.println(\"Error al consultar productos: \" + e.getMessage());\n        }\n    }\n\n    // Método para actualizar un producto en el archivo de ventas\n    private static void actualizarProducto(Scanner scanner) {\n        try {\n            List<String> lineas = new ArrayList<>();\n            BufferedReader br = new BufferedReader(new FileReader(SALES_FILENAME));\n            String linea;\n            while ((linea = br.readLine()) != null) {\n                lineas.add(linea);\n            }\n            br.close();\n\n            System.out.print(\"Nombre del producto a actualizar: \");\n            String nombreActualizar = scanner.nextLine();\n\n            boolean encontrado = false;\n            for (int i = 0; i < lineas.size(); i++) {\n                String[] partes = lineas.get(i).split(\", \");\n                if (partes[0].equals(nombreActualizar)) {\n                    System.out.print(\"Nueva cantidad vendida: \");\n                    int nuevaCantidad = scanner.nextInt();\n                    System.out.print(\"Nuevo precio: \");\n                    double nuevoPrecio = scanner.nextDouble();\n                    lineas.set(i, String.format(\"%s, %d, %.2f\", nombreActualizar, nuevaCantidad, nuevoPrecio));\n                    encontrado = true;\n                    break;\n                }\n            }\n\n            if (encontrado) {\n                FileWriter fw = new FileWriter(SALES_FILENAME);\n                BufferedWriter bw = new BufferedWriter(fw);\n                for (String l : lineas) {\n                    bw.write(l);\n                    bw.newLine();\n                }\n                bw.close();\n                System.out.println(\"Producto actualizado con éxito.\");\n            } else {\n                System.out.println(\"Producto no encontrado.\");\n            }\n        } catch (IOException e) {\n            System.out.println(\"Error al actualizar producto: \" + e.getMessage());\n        }\n    }\n\n    // Método para eliminar un producto del archivo de ventas\n    private static void eliminarProducto(Scanner scanner) {\n        try {\n            List<String> lineas = new ArrayList<>();\n            BufferedReader br = new BufferedReader(new FileReader(SALES_FILENAME));\n            String linea;\n            while ((linea = br.readLine()) != null) {\n                lineas.add(linea);\n            }\n            br.close();\n\n            System.out.print(\"Nombre del producto a eliminar: \");\n            String nombreEliminar = scanner.nextLine();\n\n            boolean encontrado = false;\n            for (int i = 0; i < lineas.size(); i++) {\n                String[] partes = lineas.get(i).split(\", \");\n                if (partes[0].equals(nombreEliminar)) {\n                    lineas.remove(i);\n                    encontrado = true;\n                    break;\n                }\n            }\n\n            if (encontrado) {\n                FileWriter fw = new FileWriter(SALES_FILENAME);\n                BufferedWriter bw = new BufferedWriter(fw);\n                for (String l : lineas) {\n                    bw.write(l);\n                    bw.newLine();\n                }\n                bw.close();\n                System.out.println(\"Producto eliminado con éxito.\");\n            } else {\n                System.out.println(\"Producto no encontrado.\");\n            }\n        } catch (IOException e) {\n            System.out.println(\"Error al eliminar producto: \" + e.getMessage());\n        }\n    }\n\n    // Método para calcular la venta total\n    private static void calcularVentaTotal() {\n        try {\n            BufferedReader br = new BufferedReader(new FileReader(SALES_FILENAME));\n            String linea;\n            double ventaTotal = 0;\n            while ((linea = br.readLine()) != null) {\n                String[] partes = linea.split(\", \");\n                int cantidad = Integer.parseInt(partes[1]);\n                double precio = Double.parseDouble(partes[2]);\n                ventaTotal += cantidad * precio;\n            }\n            br.close();\n            System.out.printf(\"Venta total: %.2f\\n\", ventaTotal);\n        } catch (IOException e) {\n            System.out.println(\"Error al calcular venta total: \" + e.getMessage());\n        }\n    }\n\n    // Método para calcular la venta por producto\n    private static void calcularVentaPorProducto(Scanner scanner) {\n        try {\n            System.out.print(\"Nombre del producto: \");\n            String nombreProducto = scanner.nextLine();\n\n            BufferedReader br = new BufferedReader(new FileReader(SALES_FILENAME));\n            String linea;\n            boolean encontrado = false;\n            while ((linea = br.readLine()) != null) {\n                String[] partes = linea.split(\", \");\n                if (partes[0].equals(nombreProducto)) {\n                    int cantidad = Integer.parseInt(partes[1]);\n                    double precio = Double.parseDouble(partes[2]);\n                    double ventaProducto = cantidad * precio;\n                    System.out.printf(\"Venta de %s: %.2f\\n\", nombreProducto, ventaProducto);\n                    encontrado = true;\n                    break;\n                }\n            }\n            br.close();\n\n            if (!encontrado) {\n                System.out.println(\"Producto no encontrado.\");\n            }\n        } catch (IOException e) {\n            System.out.println(\"Error al calcular venta por producto: \" + e.getMessage());\n        }\n    }\n\n    // Método para borrar el archivo de ventas al salir\n    private static void borrarArchivoVentas() {\n        File file = new File(SALES_FILENAME);\n        if (file.delete()) {\n            System.out.println(\"Archivo de ventas borrado con éxito.\");\n        } else {\n            System.out.println(\"No se pudo borrar el archivo de ventas.\");\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/java/jmichael39.java",
    "content": "package reto11_2024;\n\nimport java.io.*;\nimport java.util.*;\n\npublic class jmichael39 {\n    static File file;\n    static FileWriter fileWriter;\n    static BufferedReader bufferedReader;\n    static LinkedList<Producto> lista = new LinkedList<>();\n    static Scanner scanner = new Scanner(System.in);\n\n    public static void main(String[] args) {\n        basic();\n        extra.init();\n    }\n\n    private static void basic() {\n        try {\n            file = new File(\"jmichael39.txt\");\n            fileWriter = new FileWriter(file);\n            bufferedReader = new BufferedReader(new FileReader(file));\n\n            fileWriter.write(\"Nombre: John Michael\\n\");\n            fileWriter.write(\"Edad: 31\\n\");\n            fileWriter.write(\"Lenguaje favorito: Java\\n\");\n            fileWriter.close();\n\n            String line;\n            while ((line = bufferedReader.readLine()) != null) {\n                System.out.println(line);\n            }\n\n            bufferedReader.close();\n            System.out.println(file.delete() ? \"The file was successfully deleted\" : \"The file doesn't exist\");\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        }\n    }\n\n    static class extra {\n\n        static File file;\n        static FileWriter fileWriter;\n\n        static {\n            try {\n                file = new File(\"ventas.txt\");\n                fileWriter = new FileWriter(file);\n            } catch (IOException e) {\n                throw new RuntimeException(e);\n            }\n        }\n\n        static String nombre;\n        static int cantidadVendida;\n        static double precio;\n        static int choice = 0;\n\n        static void init() {\n            boolean exit = false;\n            while (!exit) {\n                System.out.println(\"\\n1 - Añadir producto\");\n                System.out.println(\"2 - Consultar productos\");\n                System.out.println(\"3 - Actualizar producto\");\n                System.out.println(\"4 - Eliminar producto\");\n                System.out.println(\"5 - Calcular venta total\");\n                System.out.println(\"6 - Calcular venta por producto\");\n                System.out.println(\"7 - Salir\");\n                System.out.print(\"\\nElija la operación a realizar: \");\n\n                if (scanner.hasNextInt()) {\n                    choice = scanner.nextInt();\n                }\n\n                switch (choice) {\n                    case 1:\n                        addProduct();\n                        break;\n                    case 2:\n                        checkProducts();\n                        break;\n                    case 3:\n                        updateProducts();\n                        break;\n                    case 4:\n                        deleteProduct();\n                        break;\n                    case 5:\n                        totalSales();\n                        break;\n                    case 6:\n                        salesPerProduct();\n                        break;\n                    case 7:\n                        exit = true;\n                        exit();\n                        break;\n                    default:\n                        System.out.println(\"\\nNo se reconoce el comando, intentelo de nuevo\");\n                        init();\n                }\n            }\n        }\n\n        private static void addProduct() {\n            System.out.print(\"\\nNombre del producto a dar de alta: \");\n            nombre = scanner.next();\n            System.out.print(\"Unidades vendidas: \");\n            cantidadVendida = scanner.nextInt();\n            System.out.print(\"Precio del producto: \");\n            precio = Double.parseDouble(scanner.next());\n            lista.add(new Producto(nombre, cantidadVendida, precio));\n\n            try {\n                fileWriter.write(\"Nuevo producto - ID: \" + lista.get(Producto.nextId - 1).getId()\n                        + \" Nombre: \" + lista.get(Producto.nextId - 1).getNombre()\n                        + \" Unidades vendidas: \" + lista.get(Producto.nextId - 1).getCantidadVendida()\n                        + \" Precio:\" + lista.get(Producto.nextId - 1).getPrecio() + \"\\n\");\n                fileWriter.flush();\n            } catch (IOException e) {\n                e.getCause();\n            }\n        }\n\n        private static void checkProducts() {\n            isEmpty();\n\n            System.out.println(\"\\n --- PRODUCTOS DADOS DE ALTA ---\\n\");\n            for (Producto producto : lista) {\n                System.out.println(\"Id: \" + producto.getId()\n                        + \" , Nombre del artículo: \" + producto.getNombre()\n                        + \" , Precio: \" + producto.getPrecio()\n                        + \" , Unidades vendidas: \" + producto.getCantidadVendida());\n            }\n        }\n\n        private static void updateProducts() {\n            isEmpty();\n            int productToUpdate;\n            int fieldToUpdate;\n            String nuevoNombre;\n            double nuevoPrecio;\n            int nuevaCantidadVendida;\n\n            checkProducts();\n            System.out.print(\"\\nSeleccione el id del producto a actualizar: \");\n\n            while (!scanner.hasNextInt()) {\n                System.out.print(\"\\nDebe introducir un número. Seleccione el id del producto a actualizar: \");\n                scanner.next();\n            }\n            productToUpdate = scanner.nextInt() - 1;\n\n            System.out.println(\"\\n1 - Nombre\");\n            System.out.println(\"2 - Precio\");\n            System.out.println(\"3 - Cantidad vendida\");\n            System.out.print(\"\\nCampo que desea actualizar: \");\n\n            while (!scanner.hasNextInt()) {\n                System.out.print(\"\\nDebe introducir un número. Seleccione el campo que desea actualizar: \");\n                scanner.next();\n            }\n            fieldToUpdate = scanner.nextInt();\n\n            switch (fieldToUpdate) {\n                case 1:\n                    System.out.print(\"\\nNuevo nombre del producto: \");\n                    nuevoNombre = scanner.next();\n\n                    try {\n                        fileWriter.write(\"Se ha cambiado el nombre de: \" + lista.get(productToUpdate) + \"\\n\");\n                        lista.get(productToUpdate).setNombre(nuevoNombre);\n                        fileWriter.write(\"Nombre actualizado: \" + lista.get(productToUpdate).getNombre() + \"\\n\");\n                        fileWriter.flush();\n                    } catch (IOException e) {\n                        throw new RuntimeException(e);\n                    }\n                    System.out.println(\"\\nSe ha actualizado el producto: \" + lista.get(productToUpdate));\n                    break;\n                case 2:\n                    System.out.print(\"\\nNuevo precio para el producto: (ACTUAL)\" + lista.get(productToUpdate).getPrecio());\n                    nuevoPrecio = Double.parseDouble(scanner.next());\n\n                    try {\n                        fileWriter.write(\"Se ha cambiado el precio de: \" + lista.get(productToUpdate) + \"\\n\");\n                        lista.get(productToUpdate).setPrecio(nuevoPrecio);\n                        fileWriter.write(\"Precio actualizado: \" + lista.get(productToUpdate).getPrecio() + \"\\n\");\n                        fileWriter.flush();\n                    } catch (IOException e) {\n                        throw new RuntimeException(e);\n                    }\n\n                    System.out.println(\"\\nSe ha actualizado el producto: \" + lista.get(productToUpdate));\n                    break;\n                case 3:\n                    System.out.print(\"Nueva cantidad: \");\n                    nuevaCantidadVendida = scanner.nextInt();\n\n                    try {\n                        fileWriter.write(\"Se han actualizado las ventas de: \" + lista.get(productToUpdate) + \"\\n\");\n                        lista.get(productToUpdate).setCantidadVendida(nuevaCantidadVendida);\n                        fileWriter.write(\"Ventas actualizadas: \" + lista.get(productToUpdate).getCantidadVendida() + \"\\n\");\n                        fileWriter.flush();\n                    } catch (IOException e) {\n                        throw new RuntimeException(e);\n                    }\n\n                    lista.get(productToUpdate).setCantidadVendida(nuevaCantidadVendida);\n                    System.out.println(\"\\nSe ha actualizado el producto: \" + lista.get(productToUpdate));\n                    break;\n                default:\n                    System.out.println(\"\\nError\");\n            }\n        }\n\n        private static void salesPerProduct() {\n            isEmpty();\n            checkProducts();\n            System.out.print(\"\\nSeleccione un ID para calcular el total de ventas de ese producto: \");\n            int product = scanner.nextInt() - 1;\n            double totalPerProduct = lista.get(product).getCantidadVendida() * lista.get(product).getPrecio();\n            System.out.println(\"\\nEl importe de las ventas de \" + lista.get(product) + \" es: \" + totalPerProduct + \"$\");\n        }\n\n        private static void totalSales() {\n            isEmpty();\n            double totalGlobal = 0;\n            for (Producto producto : lista) {\n                totalGlobal += producto.getCantidadVendida() * producto.getPrecio();\n            }\n            System.out.println(\"\\nEl importe total de las ventas es: \" + totalGlobal + \"$\");\n        }\n\n        private static void deleteProduct() {\n            isEmpty();\n            checkProducts();\n            System.out.print(\"Id del producto a eliminar: \"\n                    + \"\\n Pulse 0 si desea volver al menú principal\");\n            if (scanner.nextInt() == 0) init();\n            int id = scanner.nextInt() - 1;\n            System.out.println(\"\\nSe ha eliminado el producto: \" + lista.get(id));\n            lista.remove(id);\n        }\n\n        private static void exit() {\n            try {\n                fileWriter.close();\n                scanner.close();\n            } catch (IOException e) {\n                throw new RuntimeException(e);\n            }\n            System.out.println(file.delete() ? \"\\nArchivo de ventas eliminado\" : \"\\nHa habido un problema borrando el archivo\");\n            System.exit(0);\n        }\n\n        private static void isEmpty() {\n            if (lista.isEmpty()) {\n                System.out.println(\"NO HAY NINGÚN ARTÍCULO DADO DE ALTA\");\n                init();\n            }\n        }\n    }\n\n    static class Producto {\n        static int nextId = 0;\n        int id;\n        String nombre;\n        int cantidadVendida;\n        double precio;\n\n        public Producto(String nombre, int cantidadVendida, double precio) {\n            this.id = ++nextId;\n            this.nombre = nombre;\n            this.cantidadVendida = cantidadVendida;\n            this.precio = precio;\n        }\n\n        public int getId() {\n            return id;\n        }\n\n        public void setNombre(String nombre) {\n            this.nombre = nombre;\n        }\n\n        public String getNombre() {\n            return nombre;\n        }\n\n        public int getCantidadVendida() {\n            return cantidadVendida;\n        }\n\n        public void setCantidadVendida(int cantidadVendida) {\n            this.cantidadVendida = cantidadVendida;\n        }\n\n        public double getPrecio() {\n            return precio;\n        }\n\n        public void setPrecio(double precio) {\n            this.precio = precio;\n        }\n\n        @Override\n        public String toString() {\n            return \"Producto{\" +\n                    \"id= \" + id +\n                    \", nombre='\" + nombre + '\\'' +\n                    \", cantidadVendida=\" + cantidadVendida +\n                    \", precio=\" + precio +\n                    '}';\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/java/julian98789.java",
    "content": "package MauroDevRetos;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Scanner;\nimport java.io.BufferedReader;\nimport java.io.BufferedWriter;\nimport java.io.File;\nimport java.io.FileReader;\nimport java.io.FileWriter;\nimport java.io.IOException;\n\npublic class reto_10 {\n    public static List<productos> listaproductos = new ArrayList<>();\n    public static Scanner input = new Scanner(System.in);\n    public static String fileName2 = \"producto.txt\";\n\n    public static void main(String[] args) {\n\n        String githubUsername = \"julian98789\";\n        String fileName = githubUsername + \".txt\";\n\n        String name = \"julian\";\n        int age = 19;\n        String favoriteProgrammingLanguage = \"Java\";\n\n        // Crear el archivo y escribir en él\n        try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileName))) {\n            writer.write(\"Nombre: \" + name + \"\\n\");\n            writer.write(\"Edad: \" + age + \"\\n\");\n            writer.write(\"Lenguaje de programación favorito: \" + favoriteProgrammingLanguage + \"\\n\");\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n\n        // Leer e imprimir el contenido del archivo\n        File file = new File(fileName);\n        try (java.util.Scanner scanner = new java.util.Scanner(file)) {\n            while (scanner.hasNextLine()) {\n                System.out.println(scanner.nextLine());\n            }\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n\n        // Borrar el archivo\n        if (file.delete()) {\n            System.out.println(\"El archivo \" + fileName + \" ha sido borrado exitosamente.\");\n        } else {\n            System.out.println(\"Error al borrar el archivo \" + fileName);\n        }\n\n        boolean entrar = true;\n        while (entrar) {\n            System.out.println(\"\\n ******* productos *******\\n\");\n            System.out.println(\"1. agregar producto\");\n            System.out.println(\"2. consultar producto\");\n            System.out.println(\"3. actualizar producto\");\n            System.out.println(\"4. eliminar producto\");\n            System.out.println(\"5. calcular venta total \");\n            System.out.println(\"6. salir \\n\");\n\n            int opcion = input.nextInt();\n            switch (opcion) {\n                case 1:\n                    agregarProducto();\n                    break;\n                case 2:\n                    consultarProductos();\n                    break;\n                case 3:\n                    actualizarProducto();\n\n                    break;\n                case 4:\n                    eliminarProducto();\n\n                    break;\n                case 5:\n                    calcularVentaTotal();\n\n                    break;\n                case 6:\n                File file2 = new File(fileName2);\n                if (file2.delete()) {\n                    System.out.println(\"El archivo \" + fileName2 + \" ha sido borrado exitosamente.\");\n                } else {\n                    System.out.println(\"Error al borrar el archivo \" + fileName2);\n                }\n                entrar = false;\n                    break;\n\n                default:\n                    break;\n            }\n        }\n\n    }\n\n   \n  \n\n    private static void agregarProducto() {\n\n        System.out.println(\"Cantidad vendida: \");\n        int cantidad = input.nextInt();\n        input.nextLine();\n\n        System.out.println(\"Nombre del producto: \");\n        String name = input.nextLine();\n\n        System.out.println(\"Precio: \");\n        int precio = input.nextInt();\n        input.nextLine();\n\n        productos agrgarProductos = new productos(name, cantidad, precio);\n        listaproductos.add(agrgarProductos);\n\n        try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileName2, true))) {\n            writer.write(\"Nombre: \" + name + \"\\n\");\n            writer.write(\"Cantidad vendida: \" + cantidad + \"\\n\");\n            writer.write(\"Precio: \" + precio + \"\\n\");\n            writer.write(\"-------------------------\\n\");\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n    }\n\n    private static void consultarProductos() {\n        File file = new File(fileName2);\n        try (java.util.Scanner scanner = new java.util.Scanner(file)) {\n            while (scanner.hasNextLine()) {\n                System.out.println(scanner.nextLine());\n            }\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n    }\n\n    private static void actualizarProducto() {\n        System.out.println(\"Cantidad vendida: \");\n        int cantidad = input.nextInt();\n        input.nextLine();\n\n        System.out.println(\"Nombre del producto: \");\n        String name = input.nextLine();\n\n        System.out.println(\"Precio: \");\n        int precio = input.nextInt();\n        input.nextLine();\n\n        List<String> contenidoActual = new ArrayList<>();\n        try (BufferedReader reader = new BufferedReader(new FileReader(\"fileName\"))) {\n            String linea;\n            while ((linea = reader.readLine()) != null) {\n                contenidoActual.add(linea);\n            }\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n\n        contenidoActual.add(\"Nombre: \" + name);\n        contenidoActual.add(\"Cantidad vendida: \" + cantidad);\n        contenidoActual.add(\"Precio: \" + precio);\n        contenidoActual.add(\"-------------------------\");\n\n        // Escribir el contenido actualizado de nuevo en el archivo\n        try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileName2))) {\n            for (String linea : contenidoActual) {\n                writer.write(linea);\n                writer.newLine();\n            }\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n    }\n    private static void eliminarProducto() {\n        input.nextLine();\n        System.out.println(\"Nombre del producto a eliminar: \");\n        String nombreAEliminar = input.nextLine();\n\n        List<String> contenidoActual = new ArrayList<>();\n        boolean encontrado = false;\n\n        try (BufferedReader reader = new BufferedReader(new FileReader(fileName2))) {\n            String linea;\n            while ((linea = reader.readLine()) != null) {\n                if (linea.startsWith(\"Nombre: \" + nombreAEliminar)) {\n                    encontrado = true;\n                    reader.readLine();\n                    reader.readLine();\n                    reader.readLine();\n                } else {\n                    contenidoActual.add(linea);\n                }\n            }\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n\n        if (encontrado) {\n            try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileName2))) {\n                for (String linea : contenidoActual) {\n                    writer.write(linea);\n                    writer.newLine();\n                }\n            } catch (IOException e) {\n                e.printStackTrace();\n            }\n            System.out.println(\"El producto '\" + nombreAEliminar + \"' ha sido eliminado.\");\n        } else {\n            System.out.println(\"El producto '\" + nombreAEliminar + \"' no fue encontrado.\");\n        }\n    }\n    private static void calcularVentaTotal() {\n        int ventaTotal = 0;\n        int vetaPorProducto = 0;\n\n        try (BufferedReader reader = new BufferedReader(new FileReader(fileName2))) {\n            String linea;\n            while ((linea = reader.readLine()) != null) {\n                if (linea.startsWith(\"Cantidad vendida: \")) {\n                    int cantidad = Integer.parseInt(linea.split(\": \")[1]);\n                    linea = reader.readLine(); // Leer la línea del precio\n                    int precio = Integer.parseInt(linea.split(\": \")[1]);\n                    ventaTotal += cantidad * precio;\n                    vetaPorProducto = cantidad * precio;;\n                    String name = (linea.split(\": \")[1]);\n\n                    System.out.println(\"veta total potr ptoducto: \" + name +\": \" + vetaPorProducto);\n                }\n            }\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n\n        System.out.println(\"La venta total es: \" + ventaTotal);\n    }\n }\n\n\nclass productos {\n    private String name;\n    private int cantidad;\n    private int precio;\n\n    public productos(String name, int cantidad, int precio) {\n        this.name = name;\n        this.cantidad = cantidad;\n        this.precio = precio;\n    }\n}\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/java/lautarorisso.java",
    "content": "import java.io.IOException;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.StandardOpenOption;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Scanner;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\n\npublic class LogicaJava11 {\n    \n    public static void main(String[] args) {\n        // 1.\n        Path path = Path.of(\"lautarorisso.txt\");\n        try {\n            Files.write(path, List.of(\n                    \"Lautaro Risso\",\n                    \"21\",\n                    \"Java\"\n            ));\n        } catch (IOException ex) {\n            Logger.getLogger(LogicaJava11.class.getName()).log(Level.SEVERE, null, ex);\n        }\n\n        List<String> linesPrueba;\n        try {\n            linesPrueba = Files.readAllLines(path);\n            for (String linePrueba : linesPrueba) {\n            System.out.println(linePrueba);\n        }\n        } catch (IOException ex) {\n            Logger.getLogger(LogicaJava11.class.getName()).log(Level.SEVERE, null, ex);\n        }\n        \n        try {\n            Files.delete(path);\n        } catch (IOException ex) {\n            Logger.getLogger(LogicaJava11.class.getName()).log(Level.SEVERE, null, ex);\n        }\n        \n        // EXTRA\n        Scanner t = new Scanner (System.in);\n        \n        while (true) {\n            try {\n                System.out.println(\"1. Añadir Producto\");\n                System.out.println(\"2. Consultar Producto\");\n                System.out.println(\"3. Actualizar Producto\");\n                System.out.println(\"4. Borrar Producto\");\n                System.out.println(\"5. Mostrar todos los productos\");\n                System.out.println(\"6. Calcular venta total\");\n                System.out.println(\"7. Calcular venta por producto\");\n                System.out.println(\"8. Salir\");\n                \n                String file_name = \"ventas.txt\";\n                Path p = Path.of(file_name);\n                \n                System.out.print(\"Seleccione una opción: \");\n                String option = t.nextLine();\n                \n                switch (option) {\n                    case \"1\": {\n                        System.out.print(\"Nombre: \");\n                        String name = t.nextLine();\n                        System.out.print(\"Cantidad: \");\n                        String quantity = t.nextLine();\n                        System.out.print(\"Precio: \");\n                        String price = t.nextLine();\n                        \n                        String line = name + \", \" + quantity + \", \" + price + \"\\n\";\n                            Files.writeString(\n                                    p,\n                                    line,\n                                    StandardOpenOption.CREATE,\n                                    StandardOpenOption.APPEND\n                            );\n                    }\n                        break;\n                    case \"2\": {\n                        System.out.print(\"Nombre: \");\n                        String name = t.nextLine();\n                        List<String> lines = Files.readAllLines(p);\n                            for (String line : lines) {\n                                if (line.split(\", \")[0].equals(name)) {\n                                    System.out.println(line);\n                                }\n                            }\n                    }\n                        break;\n                    case \"3\": {\n                        System.out.print(\"Nombre: \");\n                        String name = t.nextLine(); \n                        System.out.print(\"Cantidad: \");\n                        String quantity = t.nextLine();\n                        System.out.print(\"Precio: \");\n                        String price = t.nextLine();\n                        \n                        Path pat = Path.of(file_name);\n                        \n                        // leemos todo\n                        List<String> lines = Files.readAllLines(p);\n                        List<String> updatedLines = new ArrayList<>();\n                        \n                        for (String line : lines) {\n                            \n                            String[] parts = line.split(\", \");\n                            \n                            if (parts[0].equals(name)) {\n                                // producto actualizado\n                                updatedLines.add(\n                                        name + \", \" + quantity + \", \" + price\n                                );\n                            } else {\n                                // producto intacto\n                                updatedLines.add(line);\n                            }\n                        }\n                        // sobrescribimos el archivo\n                        Files.write(pat, updatedLines);\n                    }\n                        break;\n                    case \"4\": {\n                        System.out.print(\"Nombre: \");\n                        String name = t.nextLine();\n                        Path pat2 = Path.of(file_name);\n\n                        List<String> lines = Files.readAllLines(pat2);\n                        List<String> deleteLine = new ArrayList<>();\n\n                        boolean deleted = false;\n\n                        for (String line : lines) {\n\n                            String[] parts = line.split(\", \");\n\n                            if (parts[0].equals(name)) {\n                                deleted = true;      // no la agregamos → se borra\n                            } else {\n                                deleteLine.add(line);\n                            }\n                        }\n                        // sobrescribimos el archivo\n                        Files.write(pat2, deleteLine);\n                        \n                        if (deleted) {\n                            System.out.println(\"Producto eliminado.\");\n                        } else {\n                            System.out.println(\"Producto no encontrado.\");\n                        } \n                    }\n                        break;\n                    case \"5\": {\n                        List<String>lines = Files.readAllLines(p);\n                        for (String line : lines) {\n                            System.out.println(line);\n                        }\n                    }\n                        break;\n                    case \"6\": {\n                        double total = 0;\n                        List<String >lines = Files.readAllLines(p);\n                            for (String line : lines) {\n                                String[] parts = line.split(\", \");\n                                int quantity = Integer.parseInt(parts[1]);\n                                double price = Double.parseDouble(parts[2]);\n                                total+= quantity*price;\n                        }\n                        System.out.println(total);\n                    }\n                        break;\n                    case \"7\": {\n                        System.out.print(\"Nombre: \");\n                        String name = t.nextLine();\n                        double total = 0;\n                        List<String >lines = Files.readAllLines(p);\n                            for (String line : lines) {\n                                String[] parts = line.split(\", \");\n                                if (parts[0].equals(name)) {\n                                    int quantity = Integer.parseInt(parts[1]);\n                                    double price = Double.parseDouble(parts[2]);\n                                    total+= quantity*price; \n                                }\n                        }\n                        System.out.println(total);\n                    }\n                        break;\n                    case \"8\": {\n                        Files.delete(p);\n                    }\n                        break;\n                    default:\n                        System.out.println(\"Opción inválida\");\n                        return;\n                }\n            } catch (IOException ex) {\n                Logger.getLogger(LogicaJava11.class.getName()).log(Level.SEVERE, null, ex);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/java/martinbohorquez.java",
    "content": "import java.io.*;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.Scanner;\n\nimport static java.lang.Double.parseDouble;\n\n/**\n * #11 MANEJO DE FICHEROS\n *\n * @author martinbohorquez\n */\npublic class martinbohorquez {\n    private static final FileOperation operation = new FileOperation();\n    private static final Scanner scanner = new Scanner(System.in);\n    private static File venta;\n\n    public static void main(String[] args) {\n        String stringFile = \"src/data.txt\";\n        String string = \"\"\"\n                Nombre: Martin\n                Edad: 29\n                Lenguaje de programación: Java\n                \"\"\";\n        testFile(stringFile, string);\n\n        /*\n         * DIFICULTAD EXTRA\n         */\n        String fileString = \"src/venta.txt\";\n        salesManager(fileString);\n    }\n\n    private static void testFile(String stringFile, String string) {\n        File file = operation.create(stringFile);\n        operation.write(file, string);\n        operation.read(file);\n        operation.delete(file);\n    }\n\n    private static void salesManager(String fileString) {\n        boolean flag = true;\n        while (flag) {\n            System.out.print(\"\"\"\n                    =========================================\n                    ***** PROGRAMA DE GESTIÓN DE VENTAS *****\n                    1. Añadir producto\n                    2. Mostar productos\n                    3. Consultar producto\n                    4. Actualizar producto\n                    5. Borrar producto\n                    6. Calcular venta total\n                    7. Calcular venta por producto\n                    8. Salir\n                    \"\"\");\n            System.out.print(\"Selecciona la opción (1, 2, 3, 4, 5, 6, 7, 8): \");\n            String option = scanner.next();\n            Product product = new Product();\n            switch (option) {\n                case \"1\" -> product.add(fileString);\n                case \"2\" -> product.read(venta);\n                case \"3\" -> product.consultar(venta);\n                case \"4\" -> product.update(venta);\n                case \"5\" -> product.delete(venta);\n                case \"6\" -> product.calcularVentaTotal(venta);\n                case \"7\" -> product.calcularVenta(venta);\n                case \"8\" -> {\n                    product.deleteAll(venta);\n                    System.out.println(\"Saliendo del programa de gestión de ventas!\");\n                    flag = false;\n                }\n                default -> System.out.println(\"Debe seleccionar un número de opción válido!\");\n            }\n        }\n    }\n\n    private static void printFileEmpty() {\n        System.out.println(\"El archivo se encuentra vacío, no tiene registros!\");\n    }\n\n    private static void printfException(IOException e, String process) {\n        System.out.printf(\"Error al '%s' en el archivo: '%s'%n\", process, e.getMessage());\n    }\n\n    protected static class FileOperation {\n\n        private File create(String string) {\n            File file = new File(string);\n            if (file.getParentFile() != null) file.getParentFile().mkdirs();// Crear la carpeta si no existe\n            return file;\n        }\n\n        private void write(File file, String string) {\n            try (FileWriter writer = new FileWriter(file, true); Scanner reader = new Scanner(file)) {\n                writer.append(string).append(System.lineSeparator());\n                if (!reader.hasNext()) System.out.printf(\"Archivo '%s' creado!%n\", file);\n                else System.out.printf(\"Archivo '%s' modificado!%n\", file);\n            } catch (IOException e) {\n                printfException(e, \"escribir\");\n            }\n        }\n\n        private void read(File file) {\n            if (file == null || file.length() == 0) printFileEmpty();\n            else {\n                try (Scanner reader = new Scanner(file)) {\n                    System.out.println(\"Contenido del archivo: \");\n                    while (reader.hasNext()) System.out.println(reader.nextLine());\n                } catch (FileNotFoundException e) {\n                    printfException(e, \"leer\");\n                }\n            }\n        }\n\n        private void delete(File file) {\n            if (file != null && file.delete()) {\n                if (file.getParentFile() != null && file.getParentFile().delete())\n                    System.out.printf(\"Folder '\\\\%s' eliminado correctamente!%n\", file.getParentFile().toString());\n                System.out.printf(\"Archivo '%s' eliminado correctamente!%n\", file);\n            }\n        }\n    }\n\n    private static class Product {\n        private String name;\n        private Integer quantity;\n        private Float price;\n\n        private static void printProductNotFind(String name) {\n            System.out.printf(\"El producto '%s' no se encuentra en el registro de ventas!%n\", name);\n        }\n\n        private static void printWrongOperation(String name) {\n            System.out.printf(\"La operación '%s' no es válida en este método!%n\", name);\n        }\n\n        public Float getPrice() {\n            return price;\n        }\n\n        public void setPrice(Float price) {\n            this.price = price;\n        }\n\n        public Integer getQuantity() {\n            return quantity;\n        }\n\n        public void setQuantity(Integer quantity) {\n            this.quantity = quantity;\n        }\n\n        public String getName() {\n            return name;\n        }\n\n        public void setName(String name) {\n            this.name = name;\n        }\n\n        @Override\n        public String toString() {\n            return getName() + \", \" + getQuantity() + \", \" + getPrice();\n        }\n\n        public void add(String fileString) {\n            setNameScanner(\"registrar\");\n            add(fileString, getName());\n        }\n\n        public void add(String fileString, String name) {\n            if (!contains(venta, name)) {\n                if (venta == null) venta = operation.create(fileString);\n                setName(name);\n                setQuantityAndPriceScan();\n                operation.write(venta, toString());\n            } else System.out.printf(\"El producto %s ya está registrado, usar la opción de actualizar!%n\", name);\n        }\n\n        private void read(File venta) {\n            if (venta == null || venta.length() == 0) printFileEmpty();\n            else operation.read(venta);\n        }\n\n        private void consultar(File venta) {\n            if (venta == null || venta.length() == 0) printFileEmpty();\n            else {\n                try (Scanner reader = new Scanner(venta)) {\n                    boolean flag = true;\n                    setNameScanner(\"consultar\");\n                    while (flag && reader.hasNext()) {\n                        String productF = reader.nextLine();\n                        String productNameF = productF.split(\", \")[0];\n                        if (productNameF.equals(getName())) {\n                            System.out.println(productF);\n                            flag = false;\n                        }\n                    }\n                    if (flag) printProductNotFind(getName());\n                } catch (FileNotFoundException e) {\n                    printfException(e, \"consultar\");\n                }\n            }\n        }\n\n        private void update(File venta) {\n            updateOrDelete(venta, \"actualizar\");\n        }\n\n        public void delete(File venta) {\n            updateOrDelete(venta, \"eliminar\");\n        }\n\n        public void calcularVentaTotal(File venta) {\n            if (venta == null || venta.length() == 0) printFileEmpty();\n            else {\n                try (Scanner reader = new Scanner(venta)) {\n                    double calcularTotal = 0.0;\n                    while (reader.hasNext()) {\n                        String[] components = reader.nextLine().split(\", \");\n                        calcularTotal += parseDouble(components[1]) * parseDouble(components[2]);\n                    }\n                    System.out.printf(\"La venta total: %.2f%n\", calcularTotal);\n                } catch (FileNotFoundException e) {\n                    printfException(e, \"calcularVentaTotal\");\n                }\n            }\n        }\n\n        public void calcularVenta(File venta) {\n            if (venta == null || venta.length() == 0) printFileEmpty();\n            else {\n                try (Scanner reader = new Scanner(venta)) {\n                    setNameScanner(\"consultar\");\n                    double calcular = 0.0;\n                    while (reader.hasNext()) {\n                        String[] components = reader.nextLine().split(\", \");\n                        if (components[0].equals(getName()))\n                            calcular = parseDouble(components[1]) * parseDouble(components[2]);\n                    }\n                    System.out.printf(\"La venta total del producto '%s': %.2f%n\", getName(), calcular);\n                } catch (FileNotFoundException e) {\n                    printfException(e, \"calcularVenta\");\n                }\n            }\n        }\n\n        private void deleteAll(File venta) {\n            operation.delete(venta);\n        }\n\n        private void updateOrDelete(File venta, String operation) {\n            boolean operationFlag = operation.matches(\"actualizar|eliminar\");\n            if (!operationFlag) printWrongOperation(operation);\n            if (venta == null || venta.length() == 0) printFileEmpty();\n            if (venta != null && operationFlag) {\n                boolean flag = false;\n                boolean flagUpdate = operation.equals(\"actualizar\");\n                List<String> fileContent = new LinkedList<>();\n                setNameScanner(operation);\n                try (BufferedReader reader = new BufferedReader(new FileReader(venta))) {\n                    String line;\n                    if (flagUpdate) setQuantityAndPriceScan();\n                    while ((line = reader.readLine()) != null) {\n                        String productNameF = line.split(\", \")[0];\n                        if (productNameF.equals(getName())) {\n                            line = flagUpdate ? toString() : null;\n                            flag = true;\n                        }\n                        fileContent.add(line); // Actualizamos la linea de la lista\n                    }\n                } catch (IOException e) {\n                    printfException(e, operation);\n                }\n                if (flag) {\n                    // Reescribimos el archivo con el contenido actualizado\n                    try (BufferedWriter writer = new BufferedWriter(new FileWriter(venta))) {\n                        for (String line : fileContent) {\n                            if (line != null) writer.append(line).append(System.lineSeparator());\n                        }\n                        System.out.printf(\"El producto '%s' se ha '%so' correctamente!%n\",\n                                getName(), operation.substring(0, operation.length() - 2));\n                    } catch (IOException e) {\n                        printfException(e, operation);\n                    }\n                } else printProductNotFind(getName());\n            }\n        }\n\n        private void setNameScanner(String operation) {\n            System.out.printf(\"Introduce el nombre de producto que desea %s: \", operation);\n            setName(scanner.next());\n        }\n\n        private void setQuantityAndPriceScan() {\n            System.out.print(\"Ingresar la cantidad vendida(unidades): \");\n            setQuantity(scanner.nextInt());\n            System.out.print(\"Ingresar el precio unitario de producto($): \");\n            setPrice(scanner.nextFloat());\n        }\n\n        private boolean contains(File venta, String productName) {\n            if (venta == null || venta.length() == 0) return false;\n            try (Scanner reader = new Scanner(venta)) {\n                while (reader.hasNext()) {\n                    String productNameF = reader.nextLine().split(\", \")[0];\n                    if (productNameF.equals(productName)) return true;\n                }\n            } catch (FileNotFoundException e) {\n                printfException(e, \"contains\");\n            }\n            return false;\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/java/simonguzman.java",
    "content": "import java.io.FileWriter;\nimport java.io.FileReader;\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.BufferedReader;\nimport java.io.BufferedWriter;\nimport java.util.Scanner;\nimport java.util.List;\nimport java.util.ArrayList;\n\npublic class simonguzman {\n    \n    public static void main(String[] args) {\n        testFile();\n        salesManager();\n    }\n\n\n    static void salesManager(){\n        Scanner sc = new Scanner(System.in);\n        int opcion;\n        do{\n            menu();\n            System.out.println(\"Ingrese una opcion:\");\n            opcion = sc.nextInt();\n            sc.nextLine();\n            opcionsMenu(opcion, sc);\n        }while(opcion != 5);\n    }\n\n    static void menu(){\n        System.out.println(\"**************** GESTION DE VENTAS ****************\");\n        System.out.println(\"1. Añadir productos\");\n        System.out.println(\"2. Consultar productos\");\n        System.out.println(\"3. Actualizar productos\");\n        System.out.println(\"4. Eliminar productos\");\n        System.out.println(\"5. Salir\");\n    }\n\n    static void opcionsMenu(int opcion, Scanner sc){\n        switch (opcion) {\n            case 1:\n                addProducts(sc);\n                break;\n            case 2:\n                consultProducts();\n                break;\n            case 3:\n                updateProducts(sc);\n                break;\n            case 4:\n                deleteProducts(sc);\n                break;\n            case 5:\n                exit();\n                break;\n            default:\n            System.out.println(\"ERROR: Opcion no valida...\");\n                break;\n        }\n    }\n\n    static void addProducts(Scanner sc){\n        try (BufferedWriter writer = new BufferedWriter(new FileWriter(\"ventas.txt\", true))){\n                System.out.println(\"Ingrese el nombre del producto: \");\n                String nameProduct = sc.next();\n                System.out.println(\"Ingrese la cantidad vendida: \");\n                int cantProduct = sc.nextInt();\n                System.out.println(\"Ingrese el precio del producto: \");\n                double priceProduct = sc.nextDouble();\n                sc.nextLine();\n                writer.write(nameProduct + \" , \"+cantProduct+\" , \"+priceProduct);\n                writer.newLine();\n                System.out.println(\"Producto añadido correctamente\");\n        } catch (IOException e) {\n            System.out.println(\"ERROR: No se ha podido añadir el producto\"+e.getMessage());\n        }\n    }\n\n    static void consultProducts(){\n        try (BufferedReader reader = new BufferedReader(new FileReader(\"ventas.txt\"))){\n            String line;\n            while ((line = reader.readLine()) != null) {\n                System.out.println(line);\n            }\n        } catch (IOException e) {\n            System.out.println(\"ERROR: No se pudo consultar los productos...\"+e.getMessage());\n        }\n    }   \n\n    static void updateProducts(Scanner sc){\n        List<String> products = new ArrayList<>();\n        String line;\n        boolean productFound = false;\n        \n        try (BufferedReader reader = new BufferedReader(new FileReader(\"ventas.txt\"))){\n            while((line = reader.readLine()) != null){\n                products.add(line.trim());\n            }\n        } catch (IOException e) {\n            System.out.println(\"ERROR: No se pudo leer el archivo...\"+e.getMessage());\n            return;\n        }\n\n        System.out.println(\"Ingrese el producto a actualizar: \");\n        String productName = sc.next().trim();\n\n        for(int i = 0; i < products.size(); i++){\n            String[] details = products.get(i).split(\", \");\n            if(details[0].trim().equalsIgnoreCase(productName)){\n                System.out.println(\"Ingrese la nueva cantidad vendida; \");\n                int productCant = sc.nextInt();\n                System.out.println(\"Ingrese el nuevo precio del producto: \");\n                double productPrice = sc.nextDouble();\n                sc.nextLine();\n\n                products.set(i, productName + \" , \"+productCant+\" , \"+productPrice);\n                productFound = true;\n                break;\n            } \n        }\n\n        if(productFound){\n            try (BufferedWriter writer = new BufferedWriter(new FileWriter(\"ventas.txt\"))){\n                for(String product : products){\n                    writer.write(product);\n                    writer.newLine();\n                }\n                System.out.println(\"Producto actualizado correctamente...\");\n            } catch (IOException e) {\n                System.out.println(\"ERROR: No se pudo actualizar el producto...\"+e.getMessage());\n            }\n        }else{\n            System.out.println(\"Producto no encontrado.\");\n        }\n    }\n\n    static void deleteProducts(Scanner sc){\n        List<String> products = new ArrayList<>();\n        String line;\n        boolean productFound = false;\n\n        try (BufferedReader reader = new BufferedReader(new FileReader(\"ventas.txt\"))){\n            while ((line = reader.readLine()) != null) {\n                products.add(line.trim());   \n            }\n        } catch (Exception e) {\n            System.out.println(\"ERROR: No se pudo leer el archivo...\"+e.getMessage());\n            return;\n        }\n\n        System.out.println(\"Ingrese el producto a eliminar: \");\n        String productName = sc.next().trim();\n\n        for (int i = 0; i < products.size(); i++){\n            String[] details = products.get(i).split(\", \");\n            if(details[0].trim().equalsIgnoreCase(productName)){\n                products.remove(i);\n                productFound = true;\n                break;\n            }\n        }\n\n        if (productFound){\n            try (BufferedWriter writer = new BufferedWriter(new FileWriter(\"ventas.txt\"))){\n                for(String product : products){\n                    writer.write(product);\n                    writer.newLine();\n                }\n                System.out.println(\"Producto eliminado correctamente.\");\n            } catch (IOException e) {\n                System.out.println(\"ERROR: El producto no pudo ser eliminado...\"+e.getMessage());\n            }\n        }else{\n            System.out.println(\"No se encontro el producto\");\n        }\n    }\n\n    static void exit(){\n        File file = new File(\"ventas.txt\");\n        if(file.delete()){\n            System.out.println(\"Fichero eliminado.\");\n        }else{\n            System.out.println(\"ERROR: No se pudo eliminar el archivo.\");\n        }\n        System.out.println(\"Saliendo del programa...\");\n    }\n\n    static void testFile(){\n        createAndWriteFile();\n        readFile();\n        deleteFile();\n    }\n\n    //Crear y escribrir el fichero\n    static void createAndWriteFile(){\n        try (FileWriter writer = new FileWriter(\"simonguzman.txt\")){\n            writer.write(\"Nombre: Simon\\n\");\n            writer.write(\"Edad: 22\\n\");\n            writer.write(\"Lenguaje de programacion favorito: Java\\n\");\n        } catch (IOException e) {\n            System.out.println(\"ERROR: No se puede crear o escribir el archivo....\"+e.getMessage());\n        }\n    }\n\n    //Leer el fichero\n    static void readFile(){\n        try (BufferedReader reader = new BufferedReader(new FileReader(\"simonguzman.txt\"))){\n            String line;\n            while ((line = reader.readLine()) != null) {\n                System.out.println(line);\n            }\n        } catch (IOException e) {\n            System.out.println(\"ERROR: No se pudo leer el archivo...\"+e.getMessage());\n        }\n    }\n\n    static void deleteFile(){\n        java.io.File file = new java.io.File(\"simonguzman.txt\");\n        if(file.delete()){\n            System.out.println(\"Archivo eliminado correctamente\");\n        }else{\n            System.out.println(\"ERROR: No se puede eliminar el archivo...\");\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/javascript/7R0N1X.js",
    "content": "const fs = require(\"fs\")\n\nfs.appendFile('7R0N1X.txt', 'Nombre: Eduardo Molina \\nEdad: 24 años \\nLenguaje de programación favorito: JavaScript', (error) => {\n  if (error) throw error\n})\n\nfs.readFile('7R0N1X.txt', (err, data) => {\n  if (err) throw err\n  console.log(data.toString())\n})\n\nfs.unlink('7R0N1X.txt', (err) => {\n  if (err) throw err\n  console.log('Archivo eliminado')\n})"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/javascript/AChapeton.js",
    "content": "\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar fs = require('fs');\nvar readlineSync = require('readline-sync');\n//writeFile permite escribir en un fichero, y tambien lo crea si este aun no existe\nfs.writeFile('achapeton.txt', \"\\n    - Nombre: Andres Chapeton\\n    - Edad: 26\\n    - Lenguaje favorito: TypeScript\\n  \", function (error) {\n    if (error)\n        throw error;\n    console.log('File created');\n});\n//Leer contenido del fichero\nfs.readFile('achapeton.txt', function (error, data) {\n    if (error)\n        throw error;\n    console.log(data.toString());\n});\n//Eliminar un fichero\nfs.unlink('achapeton.txt', function (error) {\n    if (error)\n        throw error;\n    console.log('File deleted');\n});\n// DIFICULTAD EXTRA\nvar guardarVenta = function () {\n    var nombreProducto = readlineSync.question('Nombre del producto ');\n    var cantidadVendida = readlineSync.question('Cantidad vendida: ');\n    var precioTotal = readlineSync.question('Precio: ');\n    fs.appendFile('ventas.txt', \"\".concat(nombreProducto, \", \").concat(cantidadVendida, \", $\").concat(precioTotal, \"]\"), function (error) {\n        if (error)\n            throw error;\n    });\n};\nvar listarVentas = function () {\n    fs.readFile('ventas.txt', function (error, data) {\n        if (error)\n            throw error;\n        console.log(data.toString());\n    });\n};\nvar gestionarVentas = function () {\n    var option = '';\n    var menu = 'MENU: \\n 1. Agregar nueva venta \\n 2. Listar ventas \\n 3. Salir \\n Escoger una opcion: ';\n    while (option !== '3') {\n        option = readlineSync.question(menu);\n        switch (option) {\n            case '1':\n                guardarVenta();\n                break;\n            case '2':\n                listarVentas();\n                break;\n            case '3':\n                fs.unlink('ventas.txt', function (error) {\n                    if (error)\n                        throw error;\n                    console.log('Fichero eliminado');\n                });\n                break;\n            default:\n                console.log('Opcion no valida. Intentar de nuevo.');\n                break;\n        }\n    }\n};\ngestionarVentas();\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/javascript/ArticKun.js",
    "content": "\n\n// MANEJO DE FICHEROS ====================\n\n/*\n\nEn JavaScript se puede manejar ficheros utilizando \nel módulo fs trabajando en Node.js\n\nes un módulo incorporado que proporciona funciones \npara trabajar con el sistema de archivos del sistema \noperativo. La abreviatura \"fs\" significa \"file system\" (sistema de archivos en inglés).\n\nEste módulo fs permite realizar operaciones como leer archivos, \nescribir en archivos, crear directorios, eliminar archivos, entre \notras operaciones relacionadas con el sistema de archivos del servidor \no del sistema donde se esté ejecutando Node.js.\n\nAlgunos de los métodos más comunes que proporciona el módulo fs incluyen:\n\nfs.readFile(): Lee el contenido de un archivo.\nfs.writeFile(): Escribe datos en un archivo.\nfs.appendFile(): Añade datos al final de un archivo.\nfs.unlink(): Borra un archivo.\nfs.readdir(): Lee el contenido de un directorio.\nfs.mkdir(): Crea un nuevo directorio.\n\n*/\n\nconst fs = require('fs');\n\n// Nombre del archivo y contenido a escribir\nconst filename = 'ArticKun.txt';\nconst content = `ArticKun.\\n34\\nJavascript.`;\n\n// Escribir en el archivo\nfs.writeFile(filename, content, (err) => {\n  if (err) {\n    console.error('Error al crear el archivo:', err);\n    return;\n  }\n  console.log(`Archivo '${filename}' creado con éxito.`);\n  \n  // Leer el contenido del archivo\n  fs.readFile(filename, 'utf8', (err, data) => {\n    if (err) {\n      console.error('Error al leer el archivo:', err);\n      return;\n    }\n    console.log(`Contenido del archivo '${filename}':\\n${data}`);\n    \n    // Borrar el archivo\n    fs.unlink(filename, (err) => {\n      if (err) {\n        console.error('Error al borrar el archivo:', err);\n        return;\n      }\n      console.log(`Archivo '${filename}' borrado con éxito.`);\n    });\n  });\n});\n\n\n//EXTRA\n//Pendiente ...."
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/javascript/DAVstudy.js",
    "content": "/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un\n * archivo .txt.\n * - Cada producto se guarda en una línea del arhivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n */\n\n// // Importar modulo\n\nconst fs = require(\"fs\");\nconst readline = require(\"readline\");\nconst read = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout,\n});\n// // Crear archivo\n// fs.writeFile(\"DAVstudy.txt\", \"\", (err) => {\n//   if (err) throw err;\n//   console.log(\"Archivo creado o sobreescrito exitosamente.\");\n// });\n\n// // Escribir en archivo\n// fs.writeFile(\"DAVstudy.txt\", \"Diego Arenas\\n27\\nJavaScript\", (err) => {\n//   if (err) throw err;\n//   console.log(\"Archivo creado o sobreescrito exitosamente.\");\n// });\n\n// // Leer archivo completo\n// fs.readFile(\"DAVstudy.txt\", \"utf8\", (err, data) => {\n//   if (err) throw err;\n//   console.log(\"Contenido del archivo:\");\n//   console.log(data);\n// });\n\n// // Eliminar un archivo\n// fs.unlink(\"DAVstudy.txt\", (err) => {\n//   if (err) throw err;\n//   console.log(\"Archivo eliminado.\");\n// });\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un\n * archivo .txt.\n * - Cada producto se guarda en una línea del arhivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n */\n\nconst myEcommerce = {\n  nameFile: \"\",\n  indexCurrentProduct: 0,\n  currentProduct: \"\",\n  currentQuantitySold: 0,\n  currentPrice: 0,\n  lastLineAdd: \"\",\n  createFile: function (nameFile) {\n    this.nameFile = `${nameFile}.txt`;\n    fs.writeFileSync(this.nameFile, \"nombre_producto,cantidad_vendida,precio\");\n    return \"Archivo Creado\";\n  },\n  addProduct: function (newLine) {\n    fs.appendFileSync(this.nameFile, \"\\n\" + newLine);\n    return \"Nuevo producto agregado\";\n  },\n  updateProduct: function (\n    product,\n    newProduct = \"\",\n    quantitySold = \"\",\n    price = \"\"\n  ) {\n    const dataUpdate = [];\n    const data = fs.readFileSync(this.nameFile, \"utf8\");\n    const lines = data.split(\"\\n\");\n    for (let i = 0; i < lines.length; i++) {\n      const line = lines[i].split(\",\");\n      if (line[0] === product) {\n        if (newProduct !== \"\") {\n          line[0] = newProduct;\n        }\n        if (quantitySold !== \"\") {\n          line[1] = quantitySold;\n        }\n        if (price !== \"\") {\n          line[2] = price;\n        }\n        dataUpdate.push(line.join(\",\"));\n      } else {\n        dataUpdate.push(lines[i]);\n      }\n    }\n    fs.writeFileSync(this.nameFile, dataUpdate.join(\"\\n\"));\n    return \"Archivo actualizado\";\n  },\n  findProduct: function (product) {\n    const data = fs.readFileSync(this.nameFile, \"utf8\");\n    const lines = data.split(\"\\n\");\n    for (let i = 0; i < lines.length; i++) {\n      const line = lines[i].split(\",\");\n      if (line[0] === product) {\n        this.currentProduct = line[0];\n        this.currentQuantitySold = line[1];\n        this.currentPrice = line[2];\n        this.indexCurrentProduct = i;\n        return \"Producto encontrado\";\n      }\n    }\n    return \"El producto no existe\";\n  },\n  deleteProduct: function (product) {\n    const dataUpdate = [];\n    const data = fs.readFileSync(this.nameFile, \"utf8\");\n    const lines = data.split(\"\\n\");\n    for (let i = 0; i < lines.length; i++) {\n      const line = lines[i].split(\",\");\n      if (line[0] === product) {\n        continue;\n      } else {\n        dataUpdate.push(lines[i]);\n      }\n    }\n    fs.writeFileSync(this.nameFile, dataUpdate.join(\"\\n\"));\n    return \"Producto eliminado\";\n  },\n  calculateSells: function (product) {\n    this.findProduct(product);\n    return Number(this.currentQuantitySold) * Number(this.currentPrice);\n  },\n};\n\n// console.log(myEcommerce.createFile(\"product-solds-price\"));\n// console.log(myEcommerce.addProduct(\"\\nToalla,2000,100\"));\n// console.log(myEcommerce.addProduct(\"\\nCartas,400,100\"));\n// console.log(myEcommerce.findProduct(\"toalla\"));\n// console.log(myEcommerce.currentProduct);\n// console.log(myEcommerce.updateProduct(\"Toalla\", \"Toallas\", \"10\", \"100\"));\n// console.log(myEcommerce.deleteProduct(\"Cartas\"));\n// console.log(myEcommerce.calculateSells(\"Toallas\"));\n\n\nmyEcommerce.createFile('data');\napp = () => {\n  \n  read.question(\n    `Ecommerce: \n      1. Agregar producto\n      2. Actualizar producto\n      3. Buscar producto\n      4. Cantidad de ventas de un producto \n      5. Eliminar producto\n      0. Cerrar (elimina el archivo)\n      Ingrese su opcion: `,\n    (option = (option) => {\n      switch (option) {\n        case \"1\":\n          read.question(`Ingrese el nombre del producto: `, (name) => {\n            read.question(`Ingrese la cantidad de ventas: `, (quantitySold) => {\n              read.question(`Ingrese el precio: `, (price) => {\n                const line = [name, quantitySold, price]\n                console.log(myEcommerce.addProduct(line.join(',')))\n                app();\n              });\n            });\n          });\n          break;\n        case \"2\":\n          read.question(\n            `Ingrese el nombre del producto a modificar`,\n            (name) => {\n              read.question(`Desea cambiar el nombre? `, (answer) => {\n                answer.toLowerCase() === \"si\"\n                  ? read.question(`Ingrese el nuevo nombre: `, (newName) =>\n                      read.question(\n                        `Desea cambiar la cantidad de ventas? `,\n                        (answer) => {\n                          answer.toLowerCase() === \"si\"\n                            ? read.question(\n                                `Ingrese la cantidad de ventas: `,\n                                (newQuantity) =>\n                                  read.question(\n                                    `Desea cambiar el precio? `,\n                                    (answer) => {\n                                      answer.toLowerCase() === \"si\"\n                                        ? read.question(\n                                            `Ingrese el precio: `,\n                                            (newPrice) => {\n                                              console.log(\n                                                myEcommerce.updateProduct(\n                                                  name,\n                                                  newName,\n                                                  newQuantity,\n                                                  newPrice\n                                                )\n                                              )\n                                            })\n                                        : console.log(\n                                            myEcommerce.updateProduct(\n                                              name,\n                                              newName,\n                                              newQuantity\n                                            )\n                                          );\n                                    }\n                                  )\n                              )\n                            : read.question(\n                                `Desea cambiar el precio? `,\n                                (answer) => {\n                                  answer.toLowerCase() === \"si\"\n                                    ? read.question(\n                                        `Ingrese el precio: `,\n                                        (newPrice) =>\n                                          console.log(\n                                            myEcommerce.updateProduct(\n                                              name,\n                                              newName,\n                                              \"\",\n                                              newPrice\n                                            )\n                                          )\n                                      )\n                                    : console.log(\n                                        myEcommerce.updateProduct(\n                                          name,\n                                          newName,\n                                          \"\",\n                                          \"\"\n                                        )\n                                      );\n                                }\n                              );\n                        }\n                      )\n                    )\n                  : read.question(\n                      `Desea cambiar la cantidad de ventas? `,\n                      (answer) => {\n                        answer.toLowerCase() === \"si\"\n                          ? read.question(\n                              `Ingrese la cantidad de ventas: `,\n                              (newQuantity) =>\n                                read.question(\n                                  `Desea cambiar el precio? `,\n                                  (answer) => {\n                                    answer.toLowerCase() === \"si\"\n                                      ? read.question(\n                                          `Ingrese el precio: `,\n                                          (newPrice) =>\n                                            console.log(\n                                              myEcommerce.updateProduct(\n                                                name,\n                                                \"\",\n                                                newQuantity,\n                                                newPrice\n                                              )\n                                            )\n                                        )\n                                      : console.log(\n                                          myEcommerce.updateProduct(\n                                            name,\n                                            \"\",\n                                            newQuantity\n                                          )\n                                        );\n                                  }\n                                )\n                            )\n                          : read.question(\n                              `Desea cambiar el precio? `,\n                              (answer) => {\n                                answer.toLowerCase() === \"si\"\n                                  ? read.question(\n                                      `Ingrese el precio: `,\n                                      (newPrice) =>\n                                        console.log(\n                                          myEcommerce.updateProduct(\n                                            name,\n                                            \"\",\n                                            \"\",\n                                            newPrice\n                                          )\n                                        )\n                                    )\n                                  : console.log(\"No hubo ningun cambio\");\n                              }\n                            );\n                      }\n                    );\n              });\n            }\n          );\n          app();\n          break;\n        case '3':\n          read.question(`Ingrese el nombre del producto: `, (name) => {\n            console.log(myEcommerce.findProduct(name))\n            app();\n          });\n          break;\n        case '4':\n            read.question(`Ingrese el nombre del producto: `, (name) => {\n              console.log(myEcommerce.calculateSells(name))\n              app();\n            });\n            break;  \n        case '5':\n          read.question(`Ingrese el nombre del producto: `, (name) => {\n            console.log(myEcommerce.deleteProduct(name))\n            app();\n          });\n          break;\n        case '0':\n            fs.unlinkSync(myEcommerce.nameFile)\n            read.close()\n            break;\n        default:\n          app();      \n          break;\n      }\n    })\n  );\n};\n\napp();\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/javascript/Dan-Corbo.js",
    "content": "/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n * \n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n * archivo .txt.\n * - Cada producto se guarda en una línea del arhivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n */\n\n\n/* Soluciones */\n\n\nconst fs = require('fs');\n\n// Nombre del usuario de GitHub\nconst nombre = \"Dan-Corbo\";\n\n// Nombre del archivo\nconst nombreDelArchivo = `${nombre}.txt`;\n\n// Contenido del archivo\nconst datos = [\n    \"Nombre: Daniel Corbo\",\n    \"Edad: 24\",\n    \"Lenguaje de programación favorito: JavaScript\"\n].join(\"\\n\");\n\n// Escribir el contenido en el archivo\nfs.writeFileSync(nombreDelArchivo, datos);\n\n// Leer el contenido del archivo\nconsole.log(\"Contenido del archivo:\");\nconsole.log(fs.readFileSync(nombreDelArchivo, 'utf8'));\n\n// Borrar el archivo\nfs.unlinkSync(nombreDelArchivo);\nconsole.log(`El archivo ${nombreDelArchivo} ha sido eliminado.`);\n\n\n\n/* Extra - Opcional */\n\n\nconst readline = require('readline');\n\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout\n});\n\nconst fileName = \"ventas.txt\";\n\nfunction agregarProductos() {\n  rl.question('Ingrese el nombre del producto: ', (nombre) => {\n    rl.question('Ingrese la cantidad vendida: ', (cantidad) => {\n      rl.question('Ingrese el precio del producto: ', (precio) => {\n        const data = `${nombre}, ${cantidad}, ${precio}\\n`;\n        fs.appendFileSync(fileName, data);\n        console.log('Producto agregado correctamente.');\n        mostrarMenu();\n      });\n    });\n  });\n}\n\nfunction mostrarTotal() {\n  const data = fs.readFileSync(fileName, 'utf8');\n  const lines = data.split('\\n');\n  let total = 0;\n  for (const line of lines) {\n    const [, cantidad, precio] = line.split(', ');\n    total += parseInt(cantidad) * parseFloat(precio);\n  }\n  console.log(`Venta total: $${total.toFixed(2)}`);\n  mostrarMenu();\n}\n\nfunction mostrarProductos() {\n  const data = fs.readFileSync(fileName, 'utf8');\n  const lines = data.split('\\n');\n  for (const line of lines) {\n    const [nombre, cantidad, precio] = line.split(', ');\n    console.log(`${nombre}: ${cantidad} unidades vendidas a $${precio} c/u`);\n  }\n  mostrarMenu();\n}\n\nfunction borrarProducto() {\n  rl.question('Ingrese el nombre del producto a eliminar: ', (nombre) => {\n    let newData = '';\n    const data = fs.readFileSync(fileName, 'utf8');\n    const lines = data.split('\\n');\n    for (const line of lines) {\n      if (!line.startsWith(nombre)) {\n        newData += line + '\\n';\n      }\n    }\n    fs.writeFileSync(fileName, newData);\n    console.log('Producto eliminado correctamente.');\n    mostrarMenu();\n  });\n}\n\nfunction mostrarMenu() {\n  console.log(\"\\n--- MENÚ ---\");\n  console.log(\"1. Añadir producto\");\n  console.log(\"2. Consultar venta total\");\n  console.log(\"3. Consultar venta por producto\");\n  console.log(\"4. Eliminar producto\");\n  console.log(\"5. Salir\");\n\n  rl.question('Seleccione una opción: ', (option) => {\n    switch (option) {\n      case '1':\n        agregarProductos();\n        break;\n      case '2':\n        mostrarTotal();\n        break;\n      case '3':\n        mostrarProductos();\n        break;\n      case '4':\n        borrarProducto();\n        break;\n      case '5':\n        fs.unlinkSync(fileName);\n        console.log(`El archivo ${fileName} ha sido eliminado.`);\n        rl.close();\n        break;\n      default:\n        console.log('Opción no válida. Por favor, seleccione una opción del menú.');\n        mostrarMenu();\n        break;\n    }\n  });\n}\n\n// Comprobar si el archivo existe\nif (!fs.existsSync(fileName)) {\n  // Si el archivo no existe, crearlo\n  fs.writeFileSync(fileName, '');\n}\n\nmostrarMenu();\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/javascript/DavidMoralesDeveloper.js",
    "content": "// Si quieres ver que es fs y propiedades https://www.w3schools.com/nodejs/nodejs_filesystem.asp\n\nconst fs = require(\"fs\");\n\n// fs.writeFile('DavidMoralesDeveloper.txt', 'Nombre: David \\nEdad: 30 \\nLenguaje : javascript', function(error){\n//     if(error) console.log(error, 'ocurrio un error ')\n//     console.log('Fue creado satisfactoriamente')\n// })\n\n// Imprimir\n\n// fs.readFile('DavidMoralesDeveloper.txt', function ( error, data){\n// if (error) console.log(error + 'algo salio mal')\n// return console.log(data.toString()) //tostring para que me imprima correctamente\n// // me da como respuesta (data) <Buffer 4e 6f 6d 62 72 ...> se corrige con utf8\n// })\n\n// eliminar\n\n// fs.unlink('DavidMoralesDeveloper.txt', function(err){\n//     if (err) throw err;\n//     console.log('documento eliminado')\n// })\n\n// Extra\nconst readline = require(\"readline\");\n\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout,\n});\n\nfunction miTiendita() {\n  function miAcciones(respuesta) {\n    if (respuesta == 1) {\n      rl.question(\"¿cual es el nombre del producto? \", (nombre) => {\n        rl.question(\"¿cual es la cantidad del producto? \", (cantidad) => {\n          rl.question(\"¿cual es el precio de el producto? \", (precio) => {\n            fs.appendFile(\n              \"miTienda.txt\",\n              `${nombre}, ${cantidad}, ${precio}\\n`,\n              (error) => {\n                if (error) throw error;\n                console.log(\"fueron agregados exitosamente: \" + nombre);\n                gestionDeInventario();\n              }\n            );\n          });\n        });\n      });\n    } else if (respuesta == 2) {\n      rl.question(\"Nombre de producto que buscas : \", (producto) => {\n        fs.readFile(\"miTienda.txt\", (error, data) => {\n          if (error) throw error;\n          const allData = data.toString().split(\"\\n\");\n          const resultado = allData.find(\n            (line) => line.split(\",\")[0] === producto\n          );\n          if (resultado) {\n            console.log(`Producto encontrado: ${resultado}`);\n          } else {\n            console.log(`Producto \"${producto}\" no encontrado.`);\n          }\n\n          gestionDeInventario();\n        });\n      });\n    } else if (respuesta == 3) {\n      rl.question(\"Nombre de producto que actualizaras : \", (producto) => {\n        fs.readFile(\"miTienda.txt\", \"utf8\", (error, data) => {\n          if (error) throw error;\n          let lines = data.split(\"\\n\");\n          let lineIndex = lines.findIndex(\n            (line) => line.split(\",\")[0] === producto\n          );\n\n          if (lineIndex !== -1) {\n            rl.question(\"¿Cuál es el nuevo nombre del producto? \", (nombre) => {\n              rl.question(\n                \"¿Cuál es la nueva cantidad del producto? \",\n                (cantidad) => {\n                  rl.question(\n                    \"¿Cuál es el nuevo precio del producto? \",\n                    (precio) => {\n                      lines[lineIndex] = `${nombre}, ${cantidad}, ${precio}`;\n                      const updatedLines = lines.join(\"\\n\");\n                      fs.writeFile(\"miTienda.txt\", updatedLines, (error) => {\n                        if (error) throw error;\n                        console.log(\"El archivo fue actualizado exitosamente.\");\n                        gestionDeInventario();\n                      });\n                    }\n                  );\n                }\n              );\n            });\n          } else {\n            console.log(`Producto \"${producto}\" no encontrado.`);\n          }\n\n          gestionDeInventario();\n        });\n      });\n    } else if (respuesta == 4) {\n      rl.question(\"Nombre de el producto que desea eliminar: \", (producto) => {\n        fs.readFile(\"miTienda.txt\", \"utf8\", (error, data) => {\n          if (error) throw error;\n          const lines = data.split(\"\\n\");\n          const buscar = lines.find((line) => line.split(\",\")[0] === producto);\n          if (buscar) {\n            const upDateLines = lines.filter((line) => {\n              const [name] = line.split(\",\");\n              return name !== producto;\n            });\n            const deleteProduct = upDateLines.join(\"\\n\");\n            fs.writeFile(\"miTienda.txt\", deleteProduct, (error) => {\n              if (error) throw error;\n              console.log(\"se borro exitosamente\");\n              gestionDeInventario();\n            });\n          } else {\n            console.log(`${producto} no encontrado`);\n          }\n          gestionDeInventario();\n        });\n      });\n    } else if (respuesta == 5) {\n      rl.question(\n        \"Producto que desea calcular su valor total: \",\n        (producto) => {\n          fs.readFile(\"miTienda.txt\", \"utf8\", (error, data) => {\n            if (error) throw error;\n            const lines = data.split(\"\\n\");\n            const busquedaDeProduc = lines.find(\n              (line) => line.split(\",\")[0] == producto\n            );\n            if (busquedaDeProduc) {\n              const cantidadDeProducto = busquedaDeProduc.split(\",\")[1];\n              const valorXproduc = busquedaDeProduc.split(\",\")[2];\n              console.log(\n                `El valor total del producto: ${producto} es = ${\n                  cantidadDeProducto * valorXproduc\n                }` \n              );\n\n              gestionDeInventario();\n            } else {\n              console.log(\n                `${producto} no existe intenta denuevo consulta el #8 para ver todos los productos`\n              );\n            }\n            gestionDeInventario();\n          });\n        }\n      );\n    } else if (respuesta == 6) {\n      fs.readFile(\"miTienda.txt\", \"utf8\", (error, data) => {\n        if (error) throw error;\n        const lines = data.split(\"\\n\");\n        const cantidadDeProducto = lines.map(\n          (line) => parseInt(line.split(\",\")[1]) * parseInt(line.split(\",\")[2])\n        );\n        // console.log(cantidadDeProducto)\n        const sumacantidad = cantidadDeProducto.reduce((sum, act) => sum + act);\n        return console.log(`El valor de todos los productos sumados es de ${sumacantidad} `);\n        \n        \n      });\n      gestionDeInventario();\n    } else if (respuesta == 7) {\n      fs.unlink(\"miTienda.txt\", function (err) {\n        if (err) throw err;\n        rl.close();\n        console.log(\"salir y borraer el miTienda.txt\");\n      });\n      \n    } else if (respuesta == 8) {\n      fs.readFile(\"miTienda.txt\", (error, data) => {\n        if (error) throw error;\n        console.log(data.toString());\n        gestionDeInventario();\n      });\n    } else {\n      console.log(\"Seleccione un numero de las acciones permitidas\");\n    }\n  }\n\n  function gestionDeInventario() {\n    rl.question(\n      \" Selecciona un numero: 1. Añadir un producto, 2. Consultar un producto, 3.Actualizar, 4.Eliminar, 5.Calcular Venta Por Producto, 6.Calcular Venta Totla, 7.Salir, 8.Mostrar Productos. - Respuesta: \",\n      (respuesta) => {\n        miAcciones(respuesta);\n        if (respuesta !== 7) {\n          gestionDeInventario();\n        }\n      }\n    );\n  }\n\n  gestionDeInventario();\n}\n\nmiTiendita();\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/javascript/Deyvid-10.js",
    "content": "// Manejo de ficheros\n\nlet fs = require('fs')\n\nlet contenido = \"Deyvid Marmolejo \\n25 anos \\nJavaScript\"\n\n// Crear el archivo .txt\nfs.writeFile('Deyvid-10.txt', contenido, (error) =>\n{\n    if(error)\n    {\n        console.error(\"Se produjo un error al crear el archivo\");        \n    }\n    else\n    {\n        console.log(\"Archivo creado correctamente\");\n    }\n})\n\n// Leer el archivo .txt\nfs.readFile('Deyvid-10.txt', 'utf8', (error, cont) =>\n{\n    if(error)\n    {\n        console.error(\"Se produjo un error al crear el archivo\");        \n    }\n    else\n    {\n        console.log(\"El contenido del archivo es:\\n\", cont);\n    }\n})\n \n// Eliminar el archivo .txt\nfs.unlink('Deyvid-10.txt', (error) =>\n{\n    if(error)\n    {\n        console.error(\"Se produjo un error al crear el archivo\");        \n    }\n    else\n    {\n        console.log(\"Archivo eliminado correctamente correctamente\");\n    }\n})"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/javascript/FabianRpv.js",
    "content": "// Manejo de Ficheros\n\nconst fs = require('fs')\n\n\n// Crear Archivo \n\nfs.writeFile('FabianRpv.txt', 'Hola! Soy Fabian \\nTengo 20 Años \\nMe Gusta JavaScript!', (error) => {\n    if(error){\n        console.log(error);\n    }\n    else {\n        console.log('Archivo creado!')\n    }\n})\n\n\n// Leer Archivo \n\nfs.readFile('FabianRpv.txt', 'utf-8', (error, data) => {\n    if(error){\n        console.log(error)\n    }\n    else {\n        console.log(data)\n    }\n})\n\n\n// Eliminar Archivo \n\nfs.unlink('FabianRpv.txt', (error) => {\n    if(error){\n        console.log(error)\n    }\n    else {\n        console.log('Archivo Eliminado!')\n    }\n})"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/javascript/Glitzypanic.js",
    "content": "/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un\n * archivo .txt.\n * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n */\n\n// Ejercicio 1\nconst fs = require(\"fs\");\n\nconst nombreArchivo = \"Glitzypanic.txt\";\nconst contenido = [\"José Farías\", \"25\", \"javaScript\"];\nconst contenidoFinal = contenido.join(\"\\n\");\n\nfunction errorCrear(err) {\n  if (err) {\n    console.log(\"Error al crear el archivo\");\n    return;\n  } else {\n    console.log(\"Archivo creado\");\n\n    const datos = fs.readFileSync(nombreArchivo, { encoding: \"utf-8\" });\n    console.log(datos);\n\n    fs.unlink(nombreArchivo, errorBorrar);\n  }\n}\n\nfunction errorBorrar(err) {\n  if (err) {\n    console.log(\"Error al borrar el archivo\");\n    return;\n  } else {\n    console.log(\"Archivo eliminado\");\n  }\n}\n\nfunction agregarProducto() {\n  fs.writeFile(nombreArchivo, contenidoFinal, errorCrear);\n}\n\nagregarProducto();\n\n//Ejercicio extra\nconst fs = require(\"fs\");\nconst readline = require(\"readline\");\n\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout,\n});\n\nconst archivo = \"inventario.txt\";\n\nfunction errorCrear(err) {\n  if (err) {\n    console.log(\"Error al crear el archivo\");\n    return;\n  } else {\n    console.log(\"Archivo creado\");\n  }\n}\n\nfunction errorBorrar(err) {\n  if (err) {\n    console.log(\"Error al borrar el archivo\");\n    return;\n  } else {\n    console.log(\"Archivo eliminado\");\n  }\n}\n\nfunction consultarProductos() {\n  if (!fs.existsSync(archivo)) {\n    console.log(\"No hay productos\");\n    menu();\n    return;\n  } else {\n    const datos = fs.readFileSync(archivo, { encoding: \"utf-8\" });\n    console.log(datos);\n    menu();\n  }\n}\n\nfunction agregarProducto() {\n  if (!fs.existsSync(archivo)) {\n    fs.writeFileSync(archivo, \"\", errorCrear);\n  }\n  rl.question(\"Nombre del producto: \", (nombre) => {\n    rl.question(\"Cantidad vendida: \", (cantidad) => {\n      rl.question(\"Precio: \", (precio) => {\n        const cantidadNumero = Number(cantidad);\n        const precioNumero = Number(precio);\n        const producto = `${nombre}, ${cantidadNumero}, ${precioNumero}\\n`;\n        fs.appendFileSync(archivo, producto);\n        menu();\n      });\n    });\n  });\n}\n\nfunction actualizarProducto() {\n  rl.question(\"Nombre del producto a actualizar: \", (nombre) => {\n    const datos = fs.readFileSync(archivo, { encoding: \"utf-8\" });\n    const productos = datos.split(\"\\n\");\n    const producto = productos.find((p) => p.includes(nombre));\n    if (producto) {\n      rl.question(\"Nueva cantidad vendida: \", (cantidad) => {\n        rl.question(\"Nuevo precio: \", (precio) => {\n          const nuevoProducto = `${nombre}, ${cantidad}, ${precio}`;\n          const nuevosProductos = productos.map((p) =>\n            p.includes(nombre) ? nuevoProducto : p\n          );\n          fs.writeFileSync(archivo, nuevosProductos.join(\"\\n\"));\n          menu();\n        });\n      });\n    } else {\n      console.log(\"Producto no encontrado\");\n      menu();\n    }\n  });\n}\n\nfunction eliminarProducto() {\n  rl.question(\"Nombre del producto a eliminar: \", (nombre) => {\n    const datos = fs.readFileSync(archivo, { encoding: \"utf-8\" });\n    const productos = datos.split(\"\\n\");\n    const producto = productos.find((p) => p.includes(nombre));\n    if (producto) {\n      const nuevosProductos = productos.filter((p) => !p.includes(nombre));\n      fs.writeFileSync(archivo, nuevosProductos.join(\"\\n\"));\n    } else {\n      console.log(\"Producto no encontrado\");\n    }\n    menu();\n  });\n}\n\nfunction ventaTotal() {\n  if (!fs.existsSync(archivo)) {\n    console.log(\"No hay productos para calcular la venta total.\");\n    menu();\n    return;\n  }\n\n  const datos = fs.readFileSync(archivo, { encoding: \"utf-8\" });\n  const productos = datos.split(\"\\n\").filter((line) => line.trim() !== \"\"); // Filtrar líneas vacías\n  let total = 0;\n\n  productos.forEach((producto) => {\n    const partes = producto.split(\", \");\n    if (partes.length === 3) {\n      const precio = parseFloat(partes[2]); // Obtener el precio\n      if (!isNaN(precio)) {\n        total += precio; // Sumar el precio al total\n      }\n    }\n  });\n\n  console.log(`La venta total es: $${total.toFixed(2)}`);\n  menu();\n}\n\nfunction salir() {\n  fs.unlink(archivo, errorBorrar);\n  rl.close();\n}\n\nfunction menu() {\n  console.log(\"1. Consultar productos\");\n  console.log(\"2. Agregar producto\");\n  console.log(\"3. Actualizar producto\");\n  console.log(\"4. Eliminar producto\");\n  console.log(\"5. Venta total\");\n  console.log(\"6. Salir\");\n  rl.question(\"Opción: \", (opcion) => {\n    switch (opcion) {\n      case \"1\":\n        consultarProductos();\n        break;\n      case \"2\":\n        agregarProducto();\n        break;\n      case \"3\":\n        actualizarProducto();\n        break;\n      case \"4\":\n        eliminarProducto();\n        break;\n      case \"5\":\n        ventaTotal();\n        break;\n      case \"6\":\n        salir();\n        break;\n      default:\n        console.log(\"Opción no válida\");\n        break;\n    }\n  });\n}\n\nmenu();\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #11 - JavaScript ->Jesus Antonio Escamilla */\n/**\n * Usando Node para poder realizar los ficheros en JavaScript\n */\n\n//---EJERCIÓ SIMPLE---\n// Extension de para realizar el archivo plano\nconst { error } = require('console');\nconst fs = require('fs');\n\n// El contenido del archivo de texto\nconst nombre = \"Jesus Antonio Escamilla Escamilla\";\nconst edad = \"24\";\nconst lenguajeP = \"JavaScript, Python, Java y C#\"\nconst contenido = `Mi nombre es ${nombre} y mi edad es ${edad} y mi lenguaje de programación favorito es: ${lenguajeP}`;\n\n// La Ruta y Nombre del archivo plano\nconst rutaArchivo = 'JesusAntonioEEscamilla.txt';\n\n// Aquí hacemos un try-catch para evitar los errores\ntry {\n    //  Aquí creamos el archivo con el contenido\n    fs.writeFileSync(rutaArchivo, contenido);\n    console.log('Archivo creado exitosamente el archivo plano.');\n    console.log(fs.readFileSync(rutaArchivo, 'utf-8'));\n\n    //  Aquí lo eliminamos el archivo plano\n    fs.unlinkSync(rutaArchivo);\n    console.log('Archivo eliminado correctamente el archivo plano.');\n} catch (error) {\n    console.error('Error al crear el archivo:', error);\n}\n\n\n\n/**-----DIFICULTAD EXTRA-----*/\n\n//  Nuestras Variables que usaremos para leer la consola y para el texto plano\nconst readline = require('readline');\n\n//  El Texto Plano\nconst venta = 'JesusAntonioEEscamilla_Venta.txt';\n\n//  Obtener los datos\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\n\n//  Para agregar en el texto plano\nfunction agregarProducto() {\n    rl.question(\"\\nIngrese el nombre del producto: \", (nombre) => {\n        rl.question(\"Ingrese la cantidad del producto: \", (cantidad) => {\n            rl.question(\"Ingrese el precio del producto: \", (precio) => {\n                const producto = `${nombre}, ${cantidad}, ${precio}\\n`;\n                try {\n                    fs.appendFileSync(venta, producto);\n                    console.log('\\nSe agrego correctamente');\n                    menuVenta();\n                } catch (error) {\n                    console.error('Error, no se puedo agregar:', error);\n                }\n            });\n        });\n    });\n}\n\n//  Consultar producto\nfunction consultarProducto() {\n    rl.question(\"\\nIngrese el nombre del producto: \", (nombre) =>{\n        let data = fs.readFileSync(venta, 'utf-8');\n        let lines = data.split('\\n');\n        for (const producto of lines) {\n            producto.split(', ')[0] === nombre\n                ? console.log(`\\n${producto}`)\n                : false\n        }\n        menuVenta();\n    });\n}\n\n//  Actualizar Producto\nfunction actualizarProducto() {\n    rl.question(\"\\nIngrese el nombre del producto: \", (nombre) => {\n        rl.question(\"Ingrese la cantidad del producto: \", (cantidad) => {\n            rl.question(\"Ingrese el precio del producto: \", (precio) => {\n                let data = fs.readFileSync(venta, 'utf-8');\n                let lines = data.split('\\n');\n                let productoNuevo = '';\n                for (const producto of lines) {\n                    producto.split(', ')[0] === nombre \n                        ? productoNuevo += `${nombre}, ${cantidad}, ${precio}\\n` \n                        : productoNuevo += `${producto}\\n`\n                }\n                fs.writeFileSync(venta, productoNuevo);\n                console.log('\\nSe actualizo correctamente');\n                menuVenta();\n            });\n        });\n    });\n}\n\n//  Borrar el producto\nfunction eliminarProducto() {\n    rl.question(\"\\nIngrese el nombre del producto: \", (nombre) => {\n        let data = fs.readFileSync(venta, 'utf-8');\n        let lines = data.split('\\n');\n        let productoNuevo = '';\n        for (const producto of lines) {\n            if (producto.split(', ') !== nombre) {\n                productoNuevo += `\\n${producto}`\n            }\n        }\n        fs.writeFileSync(venta, productoNuevo, 'utf-8');\n        console.log('\\nSe elimino correctamente');\n        menuVenta();\n    });\n}\n\n//  Calcular la Venta Total\nfunction totalVenta() {\n    let total = 0;\n    let data = fs.readFileSync(venta, 'utf-8');\n    let lines = data.split('\\n');\n    for(const producto of lines){\n        componentes = producto.split(', ');\n        cantidad = parseFloat(componentes[1]);\n        precio = parseFloat(componentes[2]);\n        total += cantidad * precio;\n    }\n    console.log(`\\nVenta Total es: ${total}`);\n    menuVenta();\n}\n\n//  Calcular Venta Producto\nfunction productoVenta() {\n    rl.question('\\nIngrese el nombre del producto: ', (nombre) =>{\n        let total = 0;\n        let data = fs.readFileSync(venta, 'utf-8');\n        let lines = data.split('\\n');\n        for(const producto of lines){\n            componentes = producto.split(', ');\n            cantidad = parseFloat(componentes[1]);\n            precio = parseFloat(componentes[2]);\n            producto.split(', ')[0] === nombre \n                ? total += parseFloat(cantidad) * parseFloat(precio)\n                : console.log('No se puedo calcular')\n        }\n        console.log(`\\nVenta del Producto es: ${total}`);\n        menuVenta();\n    });\n}\n\n//  Se crea la lista del menu\nfunction menuVenta() {\n    console.log(\"\\n--- Gestión de Ventas ---\");\n    console.log(\"1. Agregar producto\");\n    console.log(\"2. Consultar producto\");\n    console.log(\"3. Actualizar producto\");\n    console.log(\"4. Eliminar producto\");\n    console.log(\"5. Consultar todos los productos\")\n    console.log(\"6. Calcular venta total\");\n    console.log(\"7. Calcular venta por producto\");\n    console.log(\"8. Salir\");\n\n    rl.question(\"\\nSelecciona una opción: \", (option) => {\n        switch (option) {\n            case '1':\n                agregarProducto();\n                break;\n            case '2':\n                consultarProducto();\n                break;\n            case '3':\n                actualizarProducto();\n                break;\n            case '4':\n                eliminarProducto();\n                break;\n            case '5':\n                console.log(\"\\nLos productos son los siguientes: \\n\" + fs.readFileSync(venta, 'utf-8'));\n                menuVenta();\n                break;\n            case '6':\n                totalVenta();\n                break;\n            case '7':\n                productoVenta();\n                break;\n            case '8':\n                try {\n                    fs.unlinkSync(venta);\n                    console.log(\"\\nSe elimino correctamente\");\n                    rl.close();\n                } catch (error) {\n                    console.error('Se encontró un error: ', error);\n                }\n                rl.close();\n                break;\n            default:\n                console.log(\"\\nOpción no valida, por favor una opción valida\");\n                menuVenta();\n                break;\n        }\n    });\n}\n\n//Inicia el programa\nmenuVenta();\n\n/**-----DIFICULTAD EXTRA-----*/"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/javascript/Pancratzia.js",
    "content": "/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un\n * archivo .txt.\n * - Cada producto se guarda en una línea del arhivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n */\n\n/* USANDO ES MODULES DE NODE */\n\nimport { writeFileSync, readFileSync, unlinkSync, existsSync, appendFile } from \"fs\";\n\nconst txt = \"Pancratzia.txt\";\nconst content = [\"Pancratzia\", \"24\", \"JavaScript\"];\n\nwriteFileSync(txt, content.join(\"\\n\"));\n\nconst datos = readFileSync(txt, \"utf-8\");\n\nconsole.log(`Datos del archivo ${txt}:`);\nconsole.log(datos);\n\nunlinkSync(txt);\n\n/** SEGUNDA PARTE **/\n\nimport readline from \"readline\";\n\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout,\n});\n\nconst fileName = \"ventas.txt\";\n\nfunction agregarProductos() {\n  rl.question(\"Ingrese el nombre del producto: \", (nombre) => {\n    rl.question(\"Ingrese la cantidad vendida: \", (cantidad) => {\n      rl.question(\"Ingrese el precio del producto: \", (precio) => {\n        const data = `${nombre}, ${cantidad}, ${precio}\\n`;\n        appendFile(fileName, data, (err) => {\n          if (err) {\n            console.log(err);\n            return;\n          }\n        })\n        console.log(\"--------------------------------\");\n        console.log(\"Se agregó el producto: \", data);\n        console.log(\"--------------------------------\");\n        mostrarMenu();\n      });\n    });\n  });\n}\n\nfunction mostrarTotal() {\n  const data = readFileSync(fileName, \"utf8\");\n  let lines = data.split(\"\\n\");\n  lines = lines.filter((line) => line !== \"\");\n  let total = 0;\n  for (const line of lines) {\n    const [, cantidad, precio] = line.split(\", \");\n    total += parseInt(cantidad) * parseFloat(precio);\n  }\n  console.log(`Venta total: $${total.toFixed(2)}`);\n  mostrarMenu();\n}\n\nfunction mostrarProductos() {\n  const data = readFileSync(fileName, \"utf8\");\n  let lines = data.split(\"\\n\");\n  lines = lines.filter((line) => line !== \"\");\n  for (const line of lines) {\n    const [nombre, cantidad, precio] = line.split(\", \");\n    console.log(\n      `Se han vendido ${cantidad} unidades de ${nombre} a ${precio}$. Por lo tanto, el total de la venta es ${parseFloat(\n        (parseInt(cantidad) * parseFloat(precio)).toFixed(2)\n      )}$`\n    );\n  }\n  mostrarMenu();\n}\n\nfunction borrarProducto() {\n  rl.question(\"Ingrese el nombre del producto a eliminar: \", (nombre) => {\n    let newData = \"\";\n    const data = readFileSync(fileName, \"utf8\");\n    const lines = data.split(\"\\n\");\n    for (const line of lines) {\n      if (!line.startsWith(nombre)) {\n        newData += line + \"\\n\";\n      }\n    }\n    writeFileSync(fileName, newData);\n    console.log(\"--------------------------------\");\n    console.log(\"Se elimino el producto\");\n    console.log(\"--------------------------------\");\n    mostrarMenu();\n  });\n}\n\nfunction eliminarArchivo() {\n  unlinkSync(fileName);\n\n  console.log(\"--------------------------------\");\n  console.log(`Se ha eliminado el archivo ${fileName}`);\n  console.log(\"--------------------------------\");\n  console.log(\"¡HASTA PRONTO!\")\n  console.log(\"--------------------------------\");\n}\n\nfunction mostrarMenu() {\n  console.log(\"\\n--- MENÚ ---\");\n  console.log(\"1. Añadir producto\");\n  console.log(\"2. Consultar venta total\");\n  console.log(\"3. Consultar venta por producto\");\n  console.log(\"4. Eliminar producto\");\n  console.log(\"5. Salir\");\n\n  rl.question(\"Seleccione una opción: \", (option) => {\n    switch (option) {\n      case \"1\":\n        agregarProductos();\n        break;\n      case \"2\":\n        mostrarTotal();\n        break;\n      case \"3\":\n        mostrarProductos();\n        break;\n      case \"4\":\n        borrarProducto();\n        break;\n      case \"5\":\n        eliminarArchivo();\n        rl.close();\n        break;\n      default:\n        console.log(\"--------------------------------\");\n        console.log(\"Opción no válida. Seleccione una opción válida.\");\n        console.log(\"--------------------------------\");\n        mostrarMenu();\n        break;\n    }\n  });\n}\n\nfunction inicio() {\n  if (!existsSync(fileName)) {\n    writeFileSync(fileName, \"\");\n  }\n\n  mostrarMenu();\n}\n\ninicio();\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/javascript/RaulDoezon.js",
    "content": "/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n * \n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n * archivo .txt.\n * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n*/\n\nconst createTextFile = () => {\n  let contenido = [\"Raúl\\n32\\nJavaScript\"];\n  const link = document.createElement(\"a\");\n  let archivo = new Blob([contenido], { type: 'text/plain' });\n  const url = URL.createObjectURL(archivo);\n  const textFile = archivo.text();\n\n  console.log(\"contenido del archivo:\");\n  console.log(textFile);\n  link.href = url;\n  link.download = \"RaulDoezon.txt\";\n\n  console.log(\"Nombre del archivo:\");\n  console.log(link.download);\n  // link.click();\n  URL.revokeObjectURL(url);\n}\n\ncreateTextFile()\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/javascript/RicJDev.js",
    "content": "const { error } = require('node:console');\nconst fs = require('node:fs');\n\n\nlet fileName = 'RicMonster.txt';\nlet content = 'Nombre: Ricardo\\nEdad: 21\\nLenguaje favorito: JavaScript';\n\nfs.writeFile(fileName, content, (error) => {\n\tconsole.log('\\n---CREANDO EL FICHERO---');\n\tif (error) {\n\t\tconsole.log(`Error: ${error}`);\n\t}\n\tconsole.log(`${fileName} ha sido creado de manera exitosa!`);\n\t\n\tfs.readFile(fileName, 'utf8', (error, data) => {\n\t\tconsole.log('\\n---LEYENDO EL FICHERO---');\n\t\tif (error) {\n\t\t\tconsole.log(`Error: ${error}`);\n\t\t}\n\t\tconsole.log(`Contenido de ${fileName}:\\n${data}`);\n\t\t\n\t\tfs.unlink(fileName, (error) => {\n\t\t\tconsole.log('\\n---ELIMINANDO EL FICHERO---');\n\t\t\tif (error) {\n\t\t\t\tconsole.log(`Error: ${error}`);\n\t\t\t}\n\t\t\tconsole.log(`${fileName} ha sido eliminado de manera exitosa`);\n\t\t});\n\t});\n});\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/javascript/Sac-Corts.js",
    "content": "// Exercise //\nconst fs = require('fs');\nconst readline = require('readline');\n\nconst userName = \"Sac-Corts\";  \nconst name = \"Isaac\"; \nconst age = 22;  \nconst favoriteLanguage = \"JavaScript\";  \n\nconst fileName = `${userName}.txt`;\n\nfs.writeFileSync(fileName, `Name: ${name}\\n`);\nfs.appendFileSync(fileName, `Age: ${age}\\n`);\nfs.appendFileSync(fileName, `Favorite programming language: ${favoriteLanguage}\\n`);\n\nconst content = fs.readFileSync(fileName, 'utf8');\nconsole.log(content);\n\nfs.unlinkSync(fileName);\n\n// Extra Exercise //\n\nconst file = 'products.txt';\n\nconst readData = () => {\n    try {\n        const data = fs.readFileSync(file, 'utf8');\n        return data.split('\\n').filter(line => line.trim() !== '');\n    } catch (err) {\n        return [];\n    }\n};\n\nconst writeData = (data) => {\n    fs.writeFileSync(file, data.join('\\n'), 'utf8');\n};\n\nconst addProduct = (name, quantity, price) => {\n    const data = readData();\n    data.push(`${name}, ${quantity}, ${price}`);\n    writeData(data);\n    console.log('Product added successfully.');\n};\n\nconst viewProduct = (name) => {\n    const data = readData();\n    const product = data.find(line => line.startsWith(name));\n    if (product) {\n        console.log(`Product found: ${product}`);\n    } else {\n        console.log('Product not found.');\n    }\n};\n\nconst updateProduct = (name, quantity, price) => {\n    const data = readData();\n    const index = data.findIndex(line => line.startsWith(name));\n    if (index !== -1) {\n        data[index] = `${name}, ${quantity}, ${price}`;\n        writeData(data);\n        console.log('Product updated successfully.');\n    } else {\n        console.log('Product not found.');\n    }\n};\n\nconst deleteProduct = (name) => {\n    const data = readData();\n    const newData = data.filter(line => !line.startsWith(name));\n    if (data.length !== newData.length) {\n        writeData(newData);\n        console.log('Product deleted successfully.');\n    } else {\n        console.log('Product not found.');\n    }\n};\n\nconst calculateTotalSales = () => {\n    const data = readData();\n    let total = 0;\n    data.forEach(line => {\n        const [, quantity, price] = line.split(', ');\n        total += parseInt(quantity) * parseFloat(price);\n    });\n    console.log(`Total sales: ${total.toFixed(2)}`);\n};\n\nconst calculateProductSales = (name) => {\n    const data = readData();\n    const product = data.find(line => line.startsWith(name));\n    if (product) {\n        const [, quantity, price] = product.split(', ');\n        const sales = parseInt(quantity) * parseFloat(price);\n        console.log(`Sales for ${name}: ${sales.toFixed(2)}`);\n    } else {\n        console.log('Product not found.');\n    }\n};\n\nconst clearFile = () => {\n    fs.unlinkSync(file);\n    console.log('File cleared.');\n};\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nconst main = () => {\n    rl.question('Choose an option: (add/view/update/delete/total/individual/exit) ', (option) => {\n        switch (option.toLowerCase()) {\n            case 'add':\n                rl.question('Enter product name: ', (name) => {\n                    rl.question('Enter quantity sold: ', (quantity) => {\n                        rl.question('Enter price: ', (price) => {\n                            addProduct(name, quantity, price);\n                            main();\n                        });\n                    });\n                });\n                break;\n            case 'view':\n                rl.question('Enter product name: ', (name) => {\n                    viewProduct(name);\n                    main();\n                });\n                break;\n            case 'update':\n                rl.question('Enter product name: ', (name) => {\n                    rl.question('Enter new quantity sold: ', (quantity) => {\n                        rl.question('Enter new price: ', (price) => {\n                            updateProduct(name, quantity, price);\n                            main();\n                        });\n                    });\n                });\n                break;\n            case 'delete':\n                rl.question('Enter product name: ', (name) => {\n                    deleteProduct(name);\n                    main();\n                });\n                break;\n            case 'total':\n                calculateTotalSales();\n                main();\n                break;\n            case 'individual':\n                rl.question('Enter product name: ', (name) => {\n                    calculateProductSales(name);\n                    main();\n                });\n                break;\n            case 'exit':\n                clearFile();\n                rl.close();\n                break;\n            default:\n                console.log('Invalid option. Please try again.');\n                main();\n                break;\n        }\n    });\n};\n\nmain();"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/javascript/adrs1166ma.js",
    "content": "/*\nIMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n\nEJERCICIO:\nDesarrolla un programa capaz de crear un archivo que se llame como\ntu usuario de GitHub y tenga la extensión .txt.\nAñade varias líneas en ese fichero:\n- Tu nombre.\n- Edad.\n- Lenguaje de programación favorito.\nImprime el contenido.\nBorra el fichero.\n\nDIFICULTAD EXTRA (opcional):\nDesarrolla un programa de gestión de ventas que almacena sus datos en un \narchivo .txt.\n- Cada producto se guarda en una línea del archivo de la siguiente manera:\n[nombre_producto], [cantidad_vendida], [precio].\n- Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\nactualizar, eliminar productos y salir.\n- También debe poseer opciones para calcular la venta total y por producto.\n- La opción salir borra el .txt.\n*/\n\n// 🔥 Crear, escribir, leer y borrar un archivo\nconst fs = require('fs'); // Para el manerjo de archivos\n\n\nconst fileName1 = \"adrs1166ma.txt\"; // Nombre del archivo\n\nfunction crearArchivo() {\n    const contenido = `Nombre: Anderson\\nEdad: 20\\nLenguaje favorito: JavaScript`;\n    fs.writeFile(fileName1, contenido, (e) => {\n        if (e) {\n            console.error(\"Error al crear el archivo:\", e);\n            return;\n        }\n        console.log(`Archivo \"${fileName1}\" creado con éxito.`);\n        leerArchivo();\n    });\n}\n\nfunction leerArchivo() {\n    fs.readFile(fileName1, 'utf8', (e, data) => {\n        if (e) {\n            console.error(\"Error al leer el archivo:\", e);\n            return;\n        }\n        console.log(`Contenido del archivo:\\n${data}`);\n        borrarArchivo();\n    });\n}\n\nfunction borrarArchivo() {\n    fs.unlink(fileName1, (e) => {\n        if (e) {\n            console.error(\"Error al borrar el archivo:\", e);\n            return;\n        }\n        console.log(`Archivo \"${fileName1}\" borrado con éxito.`);\n    });\n}\n\ncrearArchivo();\n\n\n// 🔥 Extra ------------------------------------------------------------------------------------------------------------------------\n\n\nconst fs = require('fs');\nconst readline = require('readline');\n\nconst fileName = \"ventas.txt\";\n\n// Para leer entrada del usuario\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\n// Preguntar algo al usuario\nfunction preguntar(pregunta) {\n    return new Promise((resolve) => {\n        rl.question(pregunta, (respuesta) => resolve(respuesta));\n    });\n}\n\nasync function menu() {\n    while (true) {\n        console.log(\"\\n--- MENÚ DE GESTIÓN DE VENTAS ---\");\n        console.log(\"1. Añadir producto\");\n        console.log(\"2. Consultar productos\");\n        console.log(\"3. Actualizar producto\");\n        console.log(\"4. Eliminar producto\");\n        console.log(\"5. Calcular venta total\");\n        console.log(\"6. Calcular venta por producto\");\n        console.log(\"7. Salir\");\n\n        const opcion = await preguntar(\"Seleccione una opción: \");\n\n        switch (opcion) {\n            case \"1\":\n                await añadirProducto();\n                break;\n            case \"2\":\n                await consultarProductos();\n                break;\n            case \"3\":\n                await actualizarProducto();\n                break;\n            case \"4\":\n                await eliminarProducto();\n                break;\n            case \"5\":\n                await calcularVentaTotal();\n                break;\n            case \"6\":\n                await calcularVentaPorProducto();\n                break;\n            case \"7\":\n                await salir();\n                return;\n            default:\n                console.log(\"Opción no válida. Intente de nuevo.\");\n        }\n    }\n}\n\nasync function añadirProducto() {\n    const nombre = await preguntar(\"Nombre del producto: \");\n    const cantidad = await preguntar(\"Cantidad vendida: \");\n    const precio = await preguntar(\"Precio unitario: \");\n    const linea = `${nombre}, ${cantidad}, ${precio}\\n`;\n\n    fs.appendFile(fileName, linea, (err) => {\n        if (err) {\n            console.error(\"Error al añadir el producto:\", err);\n        } else {\n            console.log(\"Producto añadido con éxito.\");\n        }\n    });\n}\n\nasync function consultarProductos() {\n    fs.readFile(fileName, 'utf8', (err, data) => {\n        if (err) {\n            console.error(\"Error al leer los productos:\", err);\n            return;\n        }\n        if (!data.trim()) {\n            console.log(\"No hay productos registrados.\");\n            return;\n        }\n        console.log(\"Productos registrados:\");\n        console.log(data);\n    });\n}\n\nasync function actualizarProducto() {\n    const nombre = await preguntar(\"Nombre del producto a actualizar: \");\n    const cantidad = await preguntar(\"Nueva cantidad vendida: \");\n    const precio = await preguntar(\"Nuevo precio unitario: \");\n\n    fs.readFile(fileName, 'utf8', (err, data) => {\n        if (err) {\n            console.error(\"Error al leer los productos:\", err);\n            return;\n        }\n\n        const lineas = data.split('\\n').filter(linea => linea.trim());\n        let encontrado = false;\n\n        for (let i = 0; i < lineas.length; i++) {\n            const [producto] = lineas[i].split(',');\n            if (producto.trim() === nombre.trim()) {\n                lineas[i] = `${nombre}, ${cantidad}, ${precio}`;\n                encontrado = true;\n                break;\n            }\n        }\n\n        if (!encontrado) {\n            console.log(\"Producto no encontrado.\");\n            return;\n        }\n\n        fs.writeFile(fileName, lineas.join('\\n'), (err) => {\n            if (err) {\n                console.error(\"Error al actualizar el producto:\", err);\n            } else {\n                console.log(\"Producto actualizado con éxito.\");\n            }\n        });\n    });\n}\n\nasync function eliminarProducto() {\n    const nombre = await preguntar(\"Nombre del producto a eliminar: \");\n\n    fs.readFile(fileName, 'utf8', (err, data) => {\n        if (err) {\n            console.error(\"Error al leer los productos:\", err);\n            return;\n        }\n\n        const lineas = data.split('\\n').filter(linea => linea.trim());\n        const nuevasLineas = lineas.filter(linea => {\n            const [producto] = linea.split(',');\n            return producto.trim() !== nombre.trim();\n        });\n\n        if (lineas.length === nuevasLineas.length) {\n            console.log(\"Producto no encontrado.\");\n            return;\n        }\n\n        fs.writeFile(fileName, nuevasLineas.join('\\n'), (err) => {\n            if (err) {\n                console.error(\"Error al eliminar el producto:\", err);\n            } else {\n                console.log(\"Producto eliminado con éxito.\");\n            }\n        });\n    });\n}\n\nasync function calcularVentaTotal() {\n    fs.readFile(fileName, 'utf8', (err, data) => {\n        if (err) {\n            console.error(\"Error al leer los productos:\", err);\n            return;\n        }\n\n        const lineas = data.split('\\n').filter(linea => linea.trim());\n        let total = 0;\n\n        for (const linea of lineas) {\n            const [, cantidad, precio] = linea.split(',').map(valor => parseFloat(valor.trim()));\n            total += cantidad * precio;\n        }\n\n        console.log(`Venta total: $${total.toFixed(2)}`);\n    });\n}\n\nasync function calcularVentaPorProducto() {\n    const nombre = await preguntar(\"Nombre del producto: \");\n\n    fs.readFile(fileName, 'utf8', (err, data) => {\n        if (err) {\n            console.error(\"Error al leer los productos:\", err);\n            return;\n        }\n\n        const lineas = data.split('\\n').filter(linea => linea.trim());\n        let encontrado = false;\n\n        for (const linea of lineas) {\n            const [producto, cantidad, precio] = linea.split(',').map(valor => valor.trim());\n            if (producto === nombre) {\n                const venta = parseFloat(cantidad) * parseFloat(precio);\n                console.log(`Venta del producto \"${nombre}\": $${venta.toFixed(2)}`);\n                encontrado = true;\n                break;\n            }\n        }\n\n        if (!encontrado) {\n            console.log(\"Producto no encontrado.\");\n        }\n    });\n}\n\nasync function salir() {\n    fs.unlink(fileName, (err) => {\n        if (err && err.code !== 'ENOENT') {\n            console.error(\"Error al borrar el archivo:\", err);\n        } else {\n            console.log(\"Archivo borrado. ¡Hasta luego!\");\n        }\n        rl.close();\n    });\n}\n\nmenu();"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/javascript/agusrosero.js",
    "content": "/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un\n * archivo .txt.\n * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n */\n\n// EJERCICIO:\nconst fs = require(\"node:fs\");\n\n// Contenido\nconst nombre = \"Hernan\";\nconst edad = 23;\nconst lenguajeFavorito = \"Python\";\nconst content = `-${nombre}\\n-${edad}\\n-${lenguajeFavorito}`;\n\nfs.writeFile(\"./agusrosero.txt\", content, (err) => {\n  if (err) {\n    console.log(err);\n  }\n  console.log(content);\n\n  // Eliminamos el archivo\n  fs.unlink(\"./agusrosero.txt\", function (err) {\n    if (err) return console.log(err);\n    console.log(\"Archivo eliminado con exito!\");\n  });\n});\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/javascript/airesEsteban.js",
    "content": "/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un\n * archivo .txt.\n * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n */\n\n\n// EJERCICIO\n\nconst { error } = require('console')\nconst fs = require('fs')\n\nconst fileName = \"airesEsteban.txt\"\n\nfunction crearArchivo(){\nconst contenido =`Nombre: Esteban \\nEdad: 20\\nLenguaje favorito: Javascript`\n    fs.writeFile(fileName, contenido, (e) => {\n        if (e) {\n            console.error(\"Error al crear archivo\", e)\n            return\n        }\n        console.log(`Archivo ${fileName} creado con éxito`)\n        leerArchivo()\n    })\n}\n\nfunction leerArchivo(){\n    fs.readFile(fileName, \"utf-8\", (e,data)=> {\n        if (e) {\n            console.error(\"Error al leer el archivo\", e)\n            return\n        }\n        console.log(`Contenido del archivo: ${data}`)\n        eliminarArchivo()\n    })\n}\n\nfunction eliminarArchivo(){\n    fs.unlink(fileName, (e) => {\n        if (e){\n            console.error(\"Error al borrar el archivo\", e)\n            return\n        }\n        console.log(`Archivo ${fileName} borrado con exito`)\n    })\n}\n\ncrearArchivo()\n\n// EXTRA\nconst readline = require('readline')\n\nconst fileName1 = \"ventas.txt\"\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nfunction preguntar(pregunta) {\n    return new Promise((resolve) => {\n        rl.question(pregunta, (respuesta) => resolve(respuesta))\n    })\n}\n\nasync function menu(){\n    while(true){\n        console.log(\"- MENÚ DE GESTIÓN DE VENTAS -\")\n        console.log(\"1. Añadir producto\")\n        console.log(\"2. Consultar producto\")\n        console.log(\"3. Actualizar producto\")\n        console.log(\"4. Eliminar producto\")\n        console.log(\"5. Calcular venta total\")\n        console.log(\"6. Calcular venta por producto\")\n        console.log(\"7. Salir\")\n\n        const opcion = await preguntar (\"Seleccione una opción\")\n\n        switch(opcion){\n            case \"1\":\n                await añadirProducto()\n                break\n            case \"2\":\n                await consultarProducto()\n                break\n            case \"3\":\n                await actualizarProducto()\n                break\n            case \"4\":\n                await eliminarProducto()\n                break\n            case \"5\":\n                await ventaTotal()\n                break\n            case \"6\":\n                await ventasPorProducto()\n                break\n            case \"7\":\n                await salir()\n                return\n            default:\n                console.log(\"Opción no válida, intente de nuevo\")    \n        }\n    }\n}\n\nasync function añadirProducto() {\n    const nombre = await preguntar(\"Nombre del producto: \")\n    const cantidad = await preguntar(\"Cantidad de unidades vendidas: \")\n    const precio = await preguntar(\"Precio unitario: \")\n    const linea = `${nombre}, ${cantidad}, ${precio}\\n`\n\n    fs.appendFile(fileName1, linea, (error) => {\n        if (error) {\n            console.error(\"Error al añadir producto\", error)\n        } else {\n            console.log(\"Producto añadido con éxito\")\n        }\n    })\n}\n\nasync function actualizarProducto() {\n    const nombre = await preguntar(\"Nombre del producto: \")\n    const cantidad = await preguntar(\"Cantidad de unidades vendidas: \")\n    const precio = await preguntar(\"Precio unitario: \")\n\n    fs.readFile(fileName1, \"utf8\", (error, data) =>{\n        if (error){\n            console.error(\"Error al leer los productos\", error)\n            return\n        }\n        const lineas = data.split(\"\\n\").filter(linea => linea.trim())\n        let encontrado = false\n        for(let i = 0; i < lineas.length; i++){\n            const [producto] = lineas[i].split(\",\")\n            if (producto.trim() === nombre.trim()){\n                lineas[i] = `${nombre}, ${cantidad}, ${precio}`\n                encontrado = true\n                break\n            }\n        }\n        if(!encontrado){\n            console.log(\"El producto no fue encontrado\")\n            return\n        }\n\n        fs.writeFile(fileName1, lineas.join(\"\\n\"), (error)=> {\n            if(error){\n                console.error(\"Error al actualizar el producto:\", error)\n            } else{\n                console.log(\"Producto actualizado con éxito.\")\n            }\n        })\n    }\n    )\n}\n\nasync function consultarProducto() {\n    fs.readFile(fileName1, 'utf8', (error, data) => {\n        if (error) {\n            console.error(\"Error al leer los productos:\", error);\n            return;\n        }\n        if (!data.trim()) {\n            console.log(\"No hay productos registrados.\")\n            return;\n        }\n        console.log(\"Productos registrados:\")\n        console.log(data)\n    });\n}\n\n\nasync function eliminarProducto() {\n    const nombre = await preguntar(\"Nombre del producto a eliminar\")\n\n    fs.readFile(fileName1, 'utf8', (error, data) => {\n        if(error){\n            console.error(\"Error al leer los productos:\", error)\n            return\n        }\n\n        const lineas = data.split(\"\\n\").filter(linea => linea.trim())\n        const nuevasLineas = lineas.filter(linea => {\n            const [producto] = linea.split(\",\")\n            return producto && producto.trim().toLowerCase() !== nombre.trim().toLowerCase()\n        })\n\n        if(lineas.length === nuevasLineas.length){\n            console.log(\"Producto no encontrado\")\n            return\n        }\n        const contenidoFinal = nuevasLineas.join(\"\\n\") + (nuevasLineas.length ? \"\\n\" : \"\")\n\n        fs.writeFile(fileName1, contenidoFinal, (error) => {\n            if (error) {\n                console.error(\"Error al eliminar el producto:\", error);\n            } else {\n                console.log(\"Producto eliminado con éxito.\");\n            }\n        })\n    })\n}\n\nasync function ventaTotal() {\n    fs.readFile(fileName1, \"utf8\", (error ,data)=> {\n        if(error){\n            console.error(\"Error al leer los productos\",error)\n            return\n        }\n\n        const lineas = data.split('\\n').filter(linea => linea.trim())\n        let total = 0\n\n        for(const linea of lineas){\n            const [, cantidad,precio] = linea.split(',').map(valor => parseFloat(valor.trim()))\n            total += cantidad * precio\n        }\n        console.log(`Venta total: ${total.toFixed(2)}`)\n    })\n}\n\nasync function ventasPorProducto() {\n    const nombre = await preguntar(\"Nombre del producto:\")\n\n    fs.readFile(fileName1, \"utf8\", (error ,data)=> {\n        if(error){\n            console.error(\"Error al leer los productos\",error)\n            return\n        }\n\n        const lineas = data.split('\\n').filter(linea => linea.trim())\n        let encontrado = false\n\n        for(const linea of lineas){\n            const [producto, cantidad,precio] = linea.split(',').map(valor => (valor.trim()))\n            if(producto === nombre){\n                const venta = parseFloat(cantidad) * parseFloat(precio)\n                console.log(`Venta del producto: ${nombre}: $${venta.toFixed(2)}`)\n                encontrado = true\n                break\n            }\n        }\n        if(!encontrado){\n            console.log(\"Producto no encontrado.\")\n        }\n    })\n\n}\n\nasync function salir() {\n    fs.unlink(fileName1, (error)=> {\n        if (error && error.code !== \"ENOENT\"){\n            console.error(\"Error al borrarl el archivo\",  error)\n        }else {\n            console.log(\"Archivo borrado\")\n        }\n        rl.close()\n    })\n}\n\nmenu()"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/javascript/alexdevrep.js",
    "content": "/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n * archivo .txt.\n * - Cada producto se guarda en una línea del arhivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n */\n\nconst fs = require('fs')\nconst nombreArchivo = \"alexdevrep.txt\"\nconst contenido = [\"Alejandro\", \"24\", \"JavaScript\"]\nconst contenidoFinal= contenido.join('\\n')\n\n/*\n    Creamos las funciones callback que son requeridas como parámetro obligatorio \n    en las funciones asíncronas writeFile y unlink (para crear y borrar\n    el fichero respectivamente)\n*/\nfunction errorCrear(err){\n    if(err){\n        console.log(\"Error al crear el archivo\", err)\n    }\n    else{\n        console.log(\"Archivo creado exitosamente\")\n    }\n}\n\nfunction errorBorrar(err){\n    if(err){\n        console.log(\"Error al borrar el fichero\",err)\n    }\n    else{\n        console.log(\"Archivo borrado exitosamente\")\n    }\n}\n\n//Creamos un fichero\nfs.writeFile(nombreArchivo, contenidoFinal, errorCrear)\n\n//Imprimimos el fichero\nconst datos=fs.readFileSync('alexdevrep.txt','utf-8')\nconsole.log(datos)\n\n//Borramos el fichero\nfs.unlink(nombreArchivo,errorBorrar)\n\n//Dificultad EXTRA\n\n//Añadimos la función para enviar datos el programa\nconst prompt = require('prompt-sync')()\nconst nombreDocumento= \"gestion_de_ventas.txt\"\n\n//Creamos la función principal del programa\nconst lista= [] \n\nfunction errorCrear(err){\n    if(err){\n        console.log(\"Error al crear el archivo\", err)\n    }\n    else{\n        console.log(\"Archivo creado exitosamente\")\n    }\n}\nfunction erroreliminar(err){\n    if(err){\n        console.log(\"No ha sido posible eliminar el fichero\",err)\n\n    }\n    else{\n        console.log(\"Fichero borrado con éxito\")\n    }\n\n}\n\nfunction gestion(accion){\n    \n    switch(accion){\n        case 'añadir':\n            console.log(\"Añada el producto a la lista\")\n            let nombre_producto = prompt(\"Por favor indique el nombre del producto: \")\n            let cantidad_vendida = prompt(\"Porfavor indique las unidades vendidas: \")\n            let precio = prompt(\"Por favor indique el precio unitario: \")\n            let producto={\n                \"Nombre del producto\": nombre_producto,\n                \"Cantidad_vendida\": cantidad_vendida,\n                \"Precio unitario\":precio\n            }\n            lista.push(producto)\n            break\n        \n        case 'consultar':\n            if (lista.length > 0) {\n                console.log(lista);\n            } else {\n                console.log(\"No hay productos que mostrar en la lista\")\n            }\n            break;\n            \n        case 'actualizar':\n            let actualizar=prompt(\"Ingrese la clave del producto a actualizar: \")\n            let nuevoProducto= lista.findIndex(producto => producto[\"Nombre del producto\"]===actualizar)\n            if (nuevoProducto !==-1){\n                let nombre_producto = prompt(\"Por favor indique el nombre del producto: \")\n                let cantidad_vendida = prompt(\"Porfavor indique las unidades vendidas: \")\n                let precio = prompt(\"Por favor indique el precio unitario: \")\n                let productoNuevo={\n                    \"Nombre del producto\": nombre_producto,\n                    \"Cantidad_vendida\": cantidad_vendida,\n                    \"Precio unitario\":precio\n                }\n                \n                lista.splice(nuevoProducto,1,productoNuevo)\n            }\n            else{\n                console.log(\"No se encuentra el producto\")\n            }\n            break\n        case 'eliminar':\n            let eliminar = prompt(\"Ingrese la clave del producto a eliminar: \")\n            let indice=lista.findIndex(producto => producto[\"Nombre del producto\"]=== eliminar)\n            if (indice !== -1){\n                lista.splice(indice,1)\n                console.log(\"Producto eliminado exitosamente\")\n            }\n            else{\n                console.log(\"No se encuentra el producto\")\n            }\n            break\n        \n            case 'ventaTotal':\n                let ventaTotal = 0\n                for (let i=0; i<lista.length;i++){\n                    let producto = lista[i]\n                    let cantidadVendida= parseFloat(producto[\"Cantidad_vendida\"])\n                    let precioUnitario= parseFloat(producto[\"Precio unitario\"])\n                    if (!isNaN(cantidadVendida) && !isNaN(precioUnitario)) {\n                        ventaTotal += cantidadVendida * precioUnitario;\n                    } else {\n                        console.log(`Advertencia: El producto ${producto[\"Nombre del producto\"]} tiene datos de cantidad o precio no válidos.`)\n                    }\n                }\n                console.log(\"La venta total de todos los productos es: \" ,ventaTotal,\"euros\")\n                break\n            case 'ventaProducto':\n                let ventaProducto =0\n                let venta = prompt(\"Ingrese el producto de que desea sacar la venta unitaria: \")\n                for(let i=0;i<lista.length;i++){\n                    let producto =lista[i]\n                    if(producto[\"Nombre del producto\"]===venta){\n                        let cantidad = parseFloat(producto[\"Cantidad_vendida\"])\n                        let precio = parseFloat(producto[\"Precio unitario\"])\n                        if(!isNaN(cantidad)&& !isNaN(precio)){\n                            ventaProducto = cantidad * precio\n                            console.log(\"La venta unitaria es de \", ventaProducto, \"euros\")\n                        }\n                        else{\n                            console.log(`Advertencia: El producto ${producto[\"Nombre del producto\"]} tiene datos de cantidad o precio no válidos.`)\n                        }\n                    }\n                    \n                    \n                    break\n                }\n        case 'guardar':\n            let contenidoLista = JSON.stringify(lista, null, 2);  // Convierte la lista a una cadena JSON con formato\n            try {\n                fs.writeFileSync(nombreDocumento, contenidoLista)\n                console.log(\"Datos guardados\")\n            } catch (err) {\n            console.error(\"Error al escribir en el archivo\", err)\n            }\n            break\n        \n        case 'salir':\n            fs.unlink(\"gestion_de_ventas.txt\",erroreliminar)\n            break\n                \n\n        default:\n            console.log(\"Opción no válida\")\n            break\n\n    }\n}\nwhile (true){\n    \n    console.log(\"Archivo de la gestión de ventas\")\n    console.log(\"Funciones disponibles: añadir , consultar, actualizar, eliminar, salir, ventaTotal, ventaProducto, guardar, salir\")\n    let accion = prompt(\"Escriba una de las opciones disponibles: \")\n    gestion(accion)\n    \n\n    if (accion == \"salir\"){\n        \n        break\n    }\n}\n\n\n\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/javascript/bernatcs.js",
    "content": "// ** EJERCICIO\n\nconst fs = require('node:fs');\nconst { stringify } = require('node:querystring');\n\nconst contenido = 'Nombre: Bernat\\nEdad: 22\\nLenguaje de progamación favorito: MaxMSP'\n\nconst fileName = 'bernatcs.txt'\n\nfs.writeFile(fileName, contenido, (err) => {\n        if (err) {\n        console.error('Error al escribir el archivo', err);\n        return;\n        }\n        console.log(`El archivo ${fileName} ha sido creado correctamente.`)\n})\n\n// ** DIFICULTAD EXTRA ** -------------------------------------------------------------------------------------------------------------------------------------------------\n\nlet gestionVentas = []\n\nfunction createFile() {\n    fs.writeFile('gestion-ventas.txt', 'Este es el documento de gestion de ventas. A continuación se observan los productos ordenados de la siguiente manera:\\n[nombre_producto], [cantidad_vendida], [precio].', (err) => {\n        if (err) {\n            console.error('Error al escribir el archivo', err);\n            return;\n        }\n    })\n}\n\n// function addProducto(nombre_producto, cantidad_vendida, precio){\n//     gestionVentas.push([nombre_producto, cantidad_vendida, precio])\n    \n// }\n\n// addProducto('Ordenador', 40, 1200)\n\n\nconst readline = require('readline').createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nlet textoInicio = false\n\nfunction gestionVentasInit(){\n    if (!textoInicio) {\n        readline.question('Bienvenido al programa de gestión de ventas que almacena los datos en el archivo gestión-ventas.txt.\\nPodrá ejecutar los siguientes comandos:\\n[nuevo]: Donde debe introducir el nuevo producto, seguidamente, la cantidad vendida y finalmente el precio.\\n[consultar]: Donde puede consultar por nombre del producto las demás características.\\n[actualizar]: Donde podrá actualizar los datos de los productos (incluido el precio completo).\\n[eliminar]: Donde podrá eliminar productos.\\n[total]: Para saber cuál es el precio total.\\n[salir]: Saldrá del programa y el txt se desvanecerá como si nunca hubiera existido.\\nIntroduce el comando: ', (respuesta) => {\n            gestionVentasPreguntas(respuesta)\n        });\n        textoInicio = true\n    } else {\n        readline.question('', (respuesta) => {\n            gestionVentasPreguntas(respuesta)\n        });\n    }\n}\n\nfunction gestionVentasPreguntas(respuesta) {\n    switch (respuesta) {\n        case 'nuevo':\n            readline.question('Introduce el nombre del producto: ', (nombre_producto) => {\n                readline.question('Introduce la cantidad vendida: ', (cantidad_vendida) => {\n                    readline.question('Introduce el precio: ', (precio) => {\n                        gestionVentas.push([nombre_producto, cantidad_vendida, precio]);\n                        fs.appendFile(\"gestion-ventas.txt\", `\\n${gestionVentas[gestionVentas.length-1]}`, (err) => {\n                            if (err) {\n                                console.error(err)\n                            }\n                        })\n                        console.log(`Producto ${nombre_producto} agregado correctamente.`);\n                        gestionVentasInit();\n                    });\n                });\n            });\n            break;\n        case 'consultar':\n            // Lógica para consultar productos\n            console.log('Comando consultar');\n            gestionVentasInit();\n            break;\n\n        case 'actualizar':\n            // Lógica para actualizar productos\n            console.log('Comando actualizar');\n            gestionVentasInit();\n            break;\n\n        case 'eliminar':\n            // Lógica para eliminar productos\n            console.log('Comando eliminar');\n            gestionVentasInit();\n            break;\n\n        case 'total':\n            // let sumaTotal = 0\n            // gestionVentas.forEach(element => {\n            //     sumaTotal += gestionVentas.precio\n            // });\n            // console.log(`La cantidad completa es: ${sumaTotal}`);\n            console.log('Comando total');\n            gestionVentasInit();\n            break;\n\n        case 'salir':\n            fs.unlink('gestion-ventas.txt', (err) => {\n                if (err) {\n                    console.error(`Error al eliminar el archivo 'gestion-ventas.txt':`, err);\n                    return;\n                }\n                console.log(`El archivo 'gestion-ventas.txt' ha sido eliminado correctamente.`);\n                readline.close(); // Cierra la interfaz readline\n            });\n            break;\n\n        default:\n            console.log('Comando no reconocido. Por favor, introduce uno válido.');\n            gestionVentasInit();\n    }\n}\n\n\ncreateFile()\ngestionVentasInit()\n\n\n\n\n// El código se podría mejorar incluyendo validaciones de los datos, pero ya no tenía tiempo ni ganas"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/javascript/brahiams7.js",
    "content": "// * EJERCICIO:\n//  * Desarrolla un programa capaz de crear un archivo que se llame como\n//  * tu usuario de GitHub y tenga la extensión .txt.\n//  * Añade varias líneas en ese fichero:\n//  * - Tu nombre.\n//  * - Edad.\n//  * - Lenguaje de programación favorito.\n//  * Imprime el contenido.\n//  * Borra el fichero.\n\nconst fs = require('fs');\nconst carpeta=\"BrahiamS7.txt\"\nconst contenido=\"Brahiam, 19, Node\"\nconst contenido2=`\\n Barco, 19, Python`\n\nfs.writeFileSync(carpeta,contenido)\nfs.appendFile(carpeta,contenido2,function (err){\n    if (err) throw err;\n})\n\nfs.readFile(carpeta,'utf8',(err,data)=>{\n    if(err){\n        console.log(err);\n    } else {\n        console.log(`El contenido de el archivo es ${data}`);\n        \n    }\n}) \n\n\n\nfs.unlink(carpeta,function (err){\n    if (err) throw err;\n})\n\n// * DIFICULTAD EXTRA (opcional):\n//  * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n//  * archivo .txt.\n//  * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n//  *   [nombre_producto], [cantidad_vendida], [precio].\n//  * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n//  *   actualizar, eliminar productos y salir.\n//  * - También debe poseer opciones para calcular la venta total y por producto.\n//  * - La opción salir borra el .txt.\n//  *\nlet readline = require('readline')\nlet rl = readline.createInterface({ input: process.stdin, output: process.stdout });\nlet carpetaV=\"ventas.txt\"\n\n\nfunction sellings(){\n    if(!fs.existsSync(carpeta)){\n        fs.writeFile(carpeta,`Nuevo sistema de ventas \\n`,(err)=>{\n            if (err) {\n                console.log(err)\n            };\n        })\n    }\n    \n    rl.question(`Ingrese un producto, elige si deseas consultar, actualizar, eliminar o escribe (salir) para salir del programa: \\n`,(answer)=>{\n        let ans=answer.trim().toLowerCase()\n\n        switch (ans) {\n            case 'consultar':\n                fs.readFile(carpetaV,'utf8',(err,data)=>{\n                    if(err){\n                        console.log(err);\n                    } else {\n                        console.log(`Las ventas registradas son: ${data}`);\n                    }\n                })\n                sellings()\n                break;\n            case 'salir':\n                fs.unlink(carpetaV,(err)=>{\n                    if (err) console.log(err);\n                })\n                rl.close()\n                break;\n            default:\n                fs.appendFile('ventas.txt',ans,(err)=>{\n                    if (err) console.log(err);\n                    \n                })\n                sellings()\n                break;\n        }\n\n    })\n\n}\nsellings()"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/javascript/caterinarodriguezdev.js",
    "content": "/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n * archivo .txt.\n * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n */\n\nconst fs = require('fs');\n\nconst crearArchivoTexto = (nombre, edad, lenguaje) => {\n    const contenido = `Mi nombre es ${nombre}, tengo ${edad} años y mi lenguaje de programación favorito es ${lenguaje}`;\n    fs.writeFile(nombre + '.txt', contenido, (error) => {\n        if (error) {\n            console.error('Error al crear el archivo:', error);\n        }\n    });\n}\n\nconst readline = require('readline');\nconst rl = readline.createInterface(process.stdin, process.stdout   );\n\nlet productos = [];\n\nconst gestionDeVentas = () => {\n\n    console.log(`\n        \n        ----------------------------------------------\n        BIENVENIDO AL PROGRAMA DE GESTIÓN DE VENTAS:\n        1. Añadir producto\n        2. Eliminar producto\n        3. Ver productos\n        4. Actualizar producto`);\n\n    rl.question('Elija una opción -> ', (term) => {\n        switch(term) {\n            case '1': \n                addProduct();\n                break;\n            case '2': \n                deleteProduct();\n                break;\n            case '3':\n                listProducts();\n                break;\n            case '4': \n                updateProduct();\n                break;\n            default:\n                gestionDeVentas();\n                break;\n        }\n    })\n}\n\nconst addProduct = () => {\n    rl.question('Nombre del producto -> ', (term) => {\n        const nombre = term;\n\n        rl.question('Cantidad vendida -> ', (term) => {\n            const cantidadVendida = term;\n\n            rl.question('Precio -> ', (term) => {\n                const precio = term;\n\n                const producto = {\n                    nombre,\n                    cantidadVendida,\n                    precio\n                }\n\n                productos.push(producto);\n\n                updateFromProductos();\n\n                console.log('Producto añadido!');\n\n                gestionDeVentas();\n            })\n        })\n    })\n}\n\nconst deleteProduct = () => {\n    rl.question('Nombre del producto que quiere eliminar -> ', (term) => {\n        productos = productos.filter(prod => prod.nombre !== term);\n\n        updateFromProductos();\n        \n        console.log('Producto eliminado!');\n\n        gestionDeVentas();\n    })\n}\n\nconst listProducts = () => {\n    productos.forEach(prod => \n        console.log(`Nombre: ${prod.nombre}, Cantidad Vendida: ${prod.cantidadVendida}, Precio: ${prod.precio}`)\n    );\n    rl.question('Seguir? -> ', (term) => {\n        if (term === 'Si') {\n            gestionDeVentas();\n        } else {\n            rl.close();\n        }\n    })\n}\n\nconst updateProduct = () => {\n    rl.question('¿Qué producto desea actualizar? -> ', (term) => {\n        let prodToUpdate = productos.find(prod => prod.nombre === term);\n        \n        if (!prodToUpdate) {\n            console.log('Producto no encontrado.');\n            return gestionDeVentas();\n        }\n\n        let prodIndex = productos.indexOf(prodToUpdate);\n\n        rl.question('¿Qué desea actualizar? -> ', (term) => {\n\n            switch(term) {\n                case 'nombre': \n                    rl.question('¿Qué nombre desea ponerle? -> ', (term) => {\n                        prodToUpdate.nombre = term;\n                        productos[prodIndex] = prodToUpdate;\n\n                        updateFromProductos();\n                        console.log('Producto actualizado!');\n                        gestionDeVentas();\n                    });\n                    break;\n                case 'cantidad vendida':\n                    rl.question('¿Qué cantidad se ha vendido? -> ', (term) => {\n                        prodToUpdate.cantidadVendida = term;\n                        productos[prodIndex] = prodToUpdate;\n\n                        updateFromProductos();\n                        console.log('Producto actualizado!');\n                        gestionDeVentas();\n                    });\n                    break;\n                case 'precio':\n                    rl.question('¿Qué precio tiene? -> ', (term) => {\n                        prodToUpdate.cantidadVendida = term;\n                        productos[prodIndex] = prodToUpdate;\n\n                        updateFromProductos();\n                        console.log('Producto actualizado!');\n                        gestionDeVentas();\n                    });\n                    break;\n            }\n        })\n    })\n}\n\nconst updateFromProductos = () => {\n    let content = '';\n    productos.forEach(prod => content += `\\n${prod.nombre}, ${prod.cantidadVendida}, ${prod.precio}`);\n    fs.writeFile('gestionProductos.txt', content, (error) => {\n        if (error) {\n            console.error('Error al crear el archivo:', error);\n        }\n});\n}\n\nconst crearArchivoTextoWithReadline = () => {\n    rl.question('Nombre -> ', (term) => {\n        const nombre  = term;\n\n        rl.question('Edad -> ', (term) => {\n            const edad = term;\n\n            rl.question('Lenguaje de programación favorito -> ', (term) => {\n                const lenguaje = term;\n\n                crearArchivoTexto(nombre, edad, lenguaje);\n\n                console.log('Archivo Creado :)');\n\n                entryPoint();\n            })\n        })\n    })\n}\n\nconst entryPoint = () => {\n\n    console.log(` PROGRAMAS \n        1. Crea un archivo de texto\n        2. Controla tus ventas`);\n\n    rl.question('¿Qué programa quiere iniciar? -> ', (term) => {\n        switch(term) {\n            case '1':    \n                crearArchivoTextoWithReadline();\n                break;\n            case '2':\n                gestionDeVentas();\n                break;\n            default:\n                'Por favor, elije un programa existente :,('\n        }\n    })\n}\n\nentryPoint();"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/javascript/ceciliarava1.js",
    "content": "// const writeStream = fs.createWriteStream('ceciliarava1.txt', { flags: 'a' }) // a - Appending data\n\n// const lines = [\"Name: Cecilia Rava\", \"Age: 22 Years old\", \"Favorite programming language: Javascript\"]\n// lines.forEach(line => {\n//     writeStream.write(line + '\\n')\n// })\n// writeStream.end()\n\n// fs.readFile(\"ceciliarava1.txt\", (err, data) => {\n//     if (err) throw err\n//     console.log(data.toString())\n\n//     fs.unlink(\"ceciliarava1.txt\", (err) => {\n//         if (err) throw err\n//         console.log(\"File deleted!\")\n//     })\n// })\n\nconst fs = require(\"fs\")\nconst readline = require(\"readline\")\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout,\n})\n\nclass Product {\n    constructor(name, quantitySold, price) {\n        this.name = name\n        this.quantitySold = quantitySold\n        this.price = price\n    }\n}\n\nlet products = []\nlet totalSales = []\nlet indexes = []\n\nfunction addProduct(name, quantitySold, price) {\n\n    let newProduct = new Product(name, quantitySold, price)\n    products.push(newProduct)\n    sales = quantitySold * price\n    totalSales.push(sales)\n\n    fs.appendFile(\n        \"products.txt\",\n        `Product: ${name}, Quantity sold: ${quantitySold}, Price: ${price} \\n`,\n        (err) => {\n            if (err) throw err\n        }\n    )\n}\n\nfunction showProducts() {\n    fs.readFile(\"products.txt\", (err, data) => {\n        if (err) throw err\n        console.log(data.toString())\n        showMenu()\n    })\n}\n\nfunction deleteProduct(name) {\n    let index = products.findIndex((product) => product.name === name)\n\n    if (index !== -1) {\n        products.splice(index, 1)\n        totalSales.splice(index, 1)\n\n        let fileContent = \"\"\n        products.forEach((product) => {\n            fileContent += `Product: ${product.name}, Quantity sold: ${product.quantitySold}, Price: ${product.price}\\n`\n        })\n\n        fs.writeFile(\"products.txt\", fileContent, (err) => {\n            if (err) throw err\n            console.log(\"Product deleted and file overwritten\")\n            showMenu()\n        })\n\n    } else {\n        console.log(\"Product not found in the array\")\n    }\n}\n\nfunction findProduct(name) {\n    const product = products.find((product) => product.name === name)\n    return product\n}\n\nfunction findIndexOfProduct(name) {\n\n    for (let i = 0; i < products.length; i++) {\n        if (products[i].name === name) {\n            indexes.push(i)\n        }\n    }\n    console.log(indexes)\n    return indexes\n}\n\nfunction exitProgram() {\n    fs.unlink(\"products.txt\", (err) => {\n        if (err) throw err\n        console.log(\"File deleted!\")\n    })\n}\n\nfunction calculateTotalSales() {\n    sales = 0\n    for (let i = 0; i < totalSales.length; i++) {\n        sales += totalSales[i]\n    }\n    console.log(`Total sales: ${sales}`)\n}\n\nfunction calculateTotalSalesPerProduct(name) {\n    sales = 0\n    for (let i = 0; i < indexes.length; i++) {\n        sales += totalSales[indexes[i]]\n    }\n    console.log(`Total sales for ${name}: ${sales}`)\n\n}\n\nfunction updateProduct(name, newQuantitySold, newPrice) {\n    let product = findProduct(name)\n    if (product) {\n        product.quantitySold = newQuantitySold\n        product.price = newPrice\n\n        let fileContent = \"\"\n        products.forEach((product) => {\n            fileContent += `Product: ${product.name}, Quantity sold: ${product.quantitySold}, Price: ${product.price}\\n`\n        })\n\n        fs.writeFile(\"products.txt\", fileContent, (err) => {\n            if (err) throw err\n            console.log(\"Product updated and file overwritten\")\n            showMenu()\n        })\n       \n    } else {\n        console.log(\"Product not found\")\n    }\n}\n\nfunction showMenu() {\n    console.log(\"----------------------------------------------\")\n    console.log(\"0. Show products\")\n    console.log(\"1. Add product\")\n    console.log(\"2. Show product\")\n    console.log(\"3. Update product\")\n    console.log(\"4. Delete product\")\n    console.log(\"5. Calculate total sales\")\n    console.log(\"6. Calculate total sales per product\")\n    console.log(\"7. Exit\")\n\n    rl.question(\"Choose an option: \", (option) => {\n        console.log(\"----------------------------------------------\")\n\n        switch (option) {\n            case \"0\":\n                showProducts()\n                break\n\n            case \"1\":\n                rl.question(\"Product name: \", (name) => {\n                    rl.question(\"Quantity sold: \", (quantitySold) => {\n                        rl.question(\"Product price: \", (price) => {\n                            addProduct(name, quantitySold, price)\n\n                            console.log(\"Product added\")\n                            showMenu()\n                        })\n                    })\n                })\n                break\n\n            case \"2\":\n                rl.question(\"Product name: \", (name) => {\n                    let product = findProduct(name)\n                    if (product) {\n                        console.log(\n                            `Product: ${product.name}, Quantity sold: ${product.quantitySold}, Price: ${product.price}`\n                        )\n                        showMenu()\n                    } else {\n                        console.log(\"Product not found\")\n                        showMenu()\n                    }\n                })\n\n                break\n\n            case \"3\":\n                rl.question(\"Product name to modify: \", (name) => {\n                    let product = findProduct(name)\n                    if (product) {\n                        console.log(\"Product found\")\n\n                        rl.question(\"Quantity sold: \", (newQuantitySold) => {\n                            rl.question(\"Product price: \", (newPrice) => {\n                                updateProduct(name, newQuantitySold, newPrice)\n                            })\n                        }) \n                    } else {\n                        console.log(\"Product not found\")\n                        showMenu()\n                    }\n                })\n                break\n\n            case \"4\":\n                rl.question(\"Product name to delete: \", (name) => {\n                    let product = findProduct(name)\n\n                    if (product) {\n                        console.log(\"Product found\")\n                        deleteProduct(name)\n                    } else {\n                        console.log(\"Product not found\")\n                    }\n                })\n                break\n\n            case \"5\":\n                calculateTotalSales()\n                showMenu()\n                break\n\n            case \"6\":\n                rl.question(\"Product name to calculate sales: \", (name) => {\n                    findIndexOfProduct(name)\n                    calculateTotalSalesPerProduct(name)\n                })\n                showMenu()\n                break\n\n            case \"7\":\n                exitProgram()\n                rl.close()\n                break\n\n            default:\n                console.log(\"Invalid option, type a number between 1-7\")\n                showMenu()\n        }\n    })\n}\n\nshowMenu()\n\n/* \nNO OK:\n- Class SalesManager with functions like methods\n*/\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/javascript/cesar-ch.js",
    "content": "/*\n    * #11 MANEJO DE FICHEROS\n*/\nconst fs = require('fs');\nconst readline = require('readline');\n\nconst nombre = 'cesar-ch'\nconst edad = 4\nconst lenguajeFavorito = 'JavaScript'\nconst contenido = `Nombre: ${nombre}\\nEdad: ${edad}\\nLenguaje de programación favorito: ${lenguajeFavorito}`\n\nfs.writeFile(`${nombre}.txt`, contenido, (err) => {\n    if (err) throw err\n    console.log(`1. Archivo ${nombre}.txt creado exitosamente`)\n    console.log('2. Contenido añadido al archivo')\n    leerArchivo(nombre)\n})\n\nfunction leerArchivo(nombre) {\n    fs.readFile(`${nombre}.txt`, 'utf-8', (err, data) => {\n        if (err) throw err\n        console.log('3. Contenido leído del archivo')\n        console.log(data)\n        borrarArchivo(nombre)\n    })\n}\n\nfunction borrarArchivo(nombre) {\n    fs.unlink(`${nombre}.txt`, (err) => {\n        if (err) throw err\n        console.log('4. Archivo eliminado exitosamente')\n        menu()\n    })\n}\n\n/*\n    * DIFICULTAD EXTRA\n*/\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n})\n\nconst menu = () => {\n    console.log(\"\\n=== Gestión de Ventas ===\");\n    console.log(\"1. Añadir producto\");\n    console.log(\"2. Consultar producto\");\n    console.log(\"3. Actualizar producto\");\n    console.log(\"4. Eliminar producto\");\n    console.log(\"5. Calcular venta total\");\n    console.log(\"6. Calcular venta por producto\");\n    console.log(\"7. Salir\");\n    console.log(\"===========================\");\n\n    seleccionarOpcion();\n}\n\nconst seleccionarOpcion = () => {\n    rl.question('Seleccione una opción: ', (opcion) => {\n        if (opcion === '1') {\n            añadirProducto();\n        } else if (opcion === '2') {\n            consultarProducto();\n        } else if (opcion === '3') {\n            actualizarProducto();\n        } else if (opcion === '4') {\n            eliminarProducto();\n        } else if (opcion === '5') {\n            calcularVentaTotal();\n        } else if (opcion === '6') {\n            calcularVentaPorProducto();\n        } else if (opcion === '7') {\n            eliminarArchivo()\n            rl.close();\n        } else {\n            seleccionarOpcion();\n        }\n    });\n}\n\nconst añadirProducto = () => {\n    rl.question('Introduce el nombre del producto: ', (nombre) => {\n        rl.question('Introduce la cantidad del producto: ', (cantidad) => {\n            rl.question('Introduce el precio del producto: ', (precio) => {\n                const producto = `${nombre},${cantidad},${precio}\\n`;\n                fs.appendFile('productos.txt', producto, (err) => {\n                    if (err) throw err;\n                    console.log('Producto añadido correctamente');\n                    menu()\n                    seleccionarOpcion()\n                });\n            });\n        });\n    });\n}\n\nconst consultarProducto = () => {\n    rl.question('Introduce el nombre del producto a consultar: ', (nombre) => {\n        fs.readFile('productos.txt', 'utf-8', (err, data) => {\n            if (err) throw err;\n            const productos = data.split('\\n');\n            const productoEncontrado = productos.find((producto) => producto.split(',')[0] === nombre);\n            if (productoEncontrado) {\n                console.log(`Producto encontrado: ${productoEncontrado}`);\n            } else {\n                console.log('Producto no encontrado');\n            }\n            menu()\n            seleccionarOpcion()\n        });\n    });\n}\n\nconst actualizarProducto = () => {\n    rl.question('Introduce el nombre del producto a actualizar: ', (nombre) => {\n        rl.question('Introduce la nueva cantidad del producto: ', (cantidad) => {\n            rl.question('Introduce el nuevo precio del producto: ', (precio) => {\n                const producto = `${nombre},${cantidad},${precio}\\n`;\n                fs.readFile('productos.txt', 'utf-8', (err, data) => {\n                    if (err) throw err;\n                    const productos = data.split('\\n');\n                    const productoEncontrado = productos.find((producto) => producto.split(',')[0] === nombre);\n                    if (productoEncontrado) {\n                        const productosFiltrados = productos.filter((producto) => producto.split(',')[0] !== nombre);\n                        const productosString = productosFiltrados.join('\\n');\n                        fs.writeFile('productos.txt', productosString + producto, (err) => {\n                            if (err) throw err;\n                            console.log('Producto actualizado correctamente');\n                        });\n                    } else {\n                        console.log('Producto no encontrado');\n                    }\n                    menu()\n                    seleccionarOpcion()\n                });\n            });\n        });\n    })\n}\n\nconst eliminarProducto = () => {\n    rl.question('Introduce el nombre del producto a eliminar: ', (nombre) => {\n        fs.readFile('productos.txt', 'utf-8', (err, data) => {\n            if (err) throw err;\n            const productos = data.split('\\n');\n            const productoEncontrado = productos.find((producto) => producto.split(',')[0] === nombre);\n            if (productoEncontrado) {\n                const productosFiltrados = productos.filter((producto) => producto.split(',')[0] !== nombre);\n                const productosString = productosFiltrados.join('\\n');\n                fs.writeFile('productos.txt', productosString, (err) => {\n                    if (err) throw err;\n                    console.log('Producto eliminado correctamente');\n\n                });\n            } else {\n                console.log('Producto no encontrado');\n            }\n            menu()\n            seleccionarOpcion()\n        })\n    });\n}\n\nconst calcularVentaTotal = () => {\n    fs.readFile('productos.txt', 'utf-8', (err, data) => {\n        if (err) throw err;\n        const productos = data.split('\\n');\n        let total = 0;\n        productos.slice(0, productos.length - 1).forEach((producto) => {\n            const [nombre, cantidad, precio] = producto.split(',');\n            total += parseInt(cantidad) * parseInt(precio);\n        });\n        console.log(`Venta total: ${total}`);\n        menu()\n        seleccionarOpcion()\n    })\n}\n\nconst calcularVentaPorProducto = () => {\n    rl.question('Introduce el nombre del producto a consultar: ', (nombre) => {\n        fs.readFile('productos.txt', 'utf-8', (err, data) => {\n            const productos = data.split('\\n');\n            const productoEncontrado = productos.find((producto) => producto.split(',')[0] === nombre);\n            if (productoEncontrado) {\n                const [nombre, cantidad, precio] = productoEncontrado.split(',');\n                const total = parseInt(cantidad) * parseFloat(precio);\n                console.log(`Venta total: ${total}`);\n            } else {\n                console.log('Producto no encontrado');\n            }\n            menu()\n            seleccionarOpcion()\n        })\n    })\n}\n\nconst eliminarArchivo = () => {\n    fs.unlink('productos.txt', (err) => {\n        if (err) throw err;\n        console.log('Archivo eliminado correctamente');\n    });\n    rl.close()\n}"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/javascript/christian-jfr.js",
    "content": "//  #11 MANEJO DE FICHEROS\n\n/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n */\n\n// Modulos fs y readline de nodejs\nconst readline = require('node:readline');\nconst fs = require('node:fs');\n\nlet FILE_NAME = 'christian-jfr.txt';\nconst info = {\n\tname: 'Christian',\n\tage: '36',\n\tlanguage: 'JavaScript',\n};\n\nfunction main() {\n\tcreateFile();\n\tsetTimeout(() => {\n\t\tprintFile();\n\t}, 1000);\n\tsetTimeout(() => {\n\t\tdeleteFile();\n\t}, 1500);\n}\n\nfunction createFile() {\n\tlet content = `Name: ${info.name}.\\nAge: ${info.age}\\nFavorite Programming Language: ${info.language}.`;\n\tfs.writeFileSync(FILE_NAME, content, 'utf-8');\n\tconsole.log(`File ${FILE_NAME} successfully created`);\n}\n\nfunction printFile() {\n\tfs.readFile(FILE_NAME, 'utf-8', (err, data) => {\n\t\tif (err) {\n\t\t\tconsole.log('file Not found', err);\n\t\t} else {\n\t\t\tconsole.log(data);\n\t\t}\n\t});\n}\n\nfunction deleteFile() {\n\tfs.unlink(FILE_NAME, (err) => {\n\t\tif (err) {\n\t\t\tconsole.log('file Not found', err);\n\t\t} else {\n\t\t\tconsole.log(`File ${FILE_NAME} successfully deleted`);\n\t\t}\n\t});\n}\n\nmain();\n\n/** DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un\n * archivo .txt.\n * - Cada producto se guarda en una línea del arhivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n */\nconst rl = readline.createInterface({\n\tinput: process.stdin,\n\toutput: process.stdout,\n});\n\nconst SALES_FILE_NAME = 'sales.txt';\n\nfs.writeFileSync(SALES_FILE_NAME, '', 'utf-8');\n\nsalesMain();\n\nfunction salesMain() {\n\tconsole.clear();\n\tconsole.log('Sales Management System');\n\trl.question(\n\t\t'\\nWhat you want to do?\\n 1. Add\\n 2. Consult\\n 3. Update\\n 4. Delete\\n 5. Total sales by product\\n 6. Total sales\\n 7. Exit\\n',\n\t\t(answer) => {\n\t\t\tswitch (answer) {\n\t\t\t\tcase '1':\n\t\t\t\t\taddProduct();\n\t\t\t\t\tbreak;\n\t\t\t\tcase '2':\n\t\t\t\t\tcheckProduct();\n\t\t\t\t\tbreak;\n\t\t\t\tcase '3':\n\t\t\t\t\tupdateProduct();\n\t\t\t\t\tbreak;\n\t\t\t\tcase '4':\n\t\t\t\t\tdeleteProduct();\n\t\t\t\t\tbreak;\n\t\t\t\tcase '5':\n\t\t\t\t\tsalesByProduct();\n\t\t\t\t\tbreak;\n\t\t\t\tcase '6':\n\t\t\t\t\ttotalSales();\n\t\t\t\t\tbreak;\n\t\t\t\tcase '7':\n\t\t\t\t\tendProgram();\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'ALL':\n\t\t\t\t\tallProducts();\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\t\t\t\t\tconsole.log('\\nInvalid option\\n');\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tsalesMain();\n\t\t\t\t\t}, 2000);\n\t\t\t}\n\t\t}\n\t);\n}\n\nfunction toMain() {\n\trl.question('\\nPress enter to continue', () => {\n\t\tsalesMain();\n\t});\n}\n\nfunction endProgram() {\n\tfs.unlink(SALES_FILE_NAME, (err) => {\n\t\tif (err) {\n\t\t\tconsole.log(`\\nFile ${SALES_FILE_NAME} Not found`, err);\n\t\t} else {\n\t\t\tconsole.log(`\\nFile ${SALES_FILE_NAME} successfully deleted`);\n\t\t}\n\t});\n\tsetTimeout(() => {\n\t\trl.close();\n\t}, 2000);\n}\n\nfunction addProduct() {\n\trl.question('Product Name: ', (name) => {\n\t\trl.question('Quantity Sold: ', (quantity) => {\n\t\t\trl.question('Price: ', (price) => {\n\t\t\t\tconst newProduct = `\\n${name}, ${quantity}, $${price}`;\n\n\t\t\t\tfs.appendFile(SALES_FILE_NAME, newProduct, (err) => {\n\t\t\t\t\tif (err) {\n\t\t\t\t\t\tconsole.log(err);\n\t\t\t\t\t\ttoMain();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconsole.log(`\\nProduct ${name} successfully added.`);\n\t\t\t\t\t\ttoMain();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\t});\n}\n\nfunction checkProduct() {\n\tconst productsInfo = fs.readFileSync(SALES_FILE_NAME, 'utf-8');\n\tconst productsArray = productsInfo\n\t\t.split('\\n')\n\t\t.filter((product) => product !== '')\n\t\t.map((product) => product.split(', '));\n\n\tlet foundProduct = null;\n\n\trl.question('Which product do you want to consult?\\n', (productName) => {\n\t\tif (productName === '') {\n\t\t\tconsole.log('Please enter a valid product name');\n\t\t\ttoMain();\n\t\t}\n\n\t\tfor (const product of productsArray) {\n\t\t\tif (product[0].includes(productName)) {\n\t\t\t\tfoundProduct = product;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (!foundProduct) {\n\t\t\tconsole.log(`${productName} not found`);\n\t\t} else {\n\t\t\tconsole.log(foundProduct.join(', '));\n\t\t}\n\t\ttoMain();\n\t});\n}\n\nfunction updateProduct() {\n\tlet productsArray;\n\n\tfs.readFile(SALES_FILE_NAME, 'utf-8', (err, products) => {\n\t\tif (err) {\n\t\t\tconsole.log(err);\n\t\t\treturn toMain();\n\t\t}\n\n\t\tproductsArray = products\n\t\t\t.split('\\n')\n\t\t\t.filter((product) => product !== '')\n\t\t\t.map((product) => product.split(', '));\n\t});\n\n\tlet foundProduct = null;\n\n\trl.question('Which product do you want to update?\\n', (productName) => {\n\t\tif (productName === '') {\n\t\t\tconsole.log('Please enter a valid product name');\n\t\t\ttoMain();\n\t\t}\n\n\t\tfor (const product of productsArray) {\n\t\t\tif (product[0].includes(productName)) {\n\t\t\t\tfoundProduct = product;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (!foundProduct) {\n\t\t\tconsole.log(`${productName} not found`);\n\t\t\ttoMain();\n\t\t} else {\n\t\t\trl.question(`Update ${productName} quantity: `, (newquantity) => {\n\t\t\t\tfoundProduct[1] = newquantity;\n\t\t\t\trl.question(`Update ${productName} price: `, (newprice) => {\n\t\t\t\t\tfoundProduct[2] = `$${newprice}`;\n\n\t\t\t\t\tconst productUpdated = productsArray\n\t\t\t\t\t\t.map((product) => {\n\t\t\t\t\t\t\treturn product === foundProduct\n\t\t\t\t\t\t\t\t? foundProduct.join(', ')\n\t\t\t\t\t\t\t\t: product.join(', ');\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.join('\\n');\n\n\t\t\t\t\tfs.writeFile(SALES_FILE_NAME, productUpdated, (err) => {\n\t\t\t\t\t\tif (err) {\n\t\t\t\t\t\t\tconsole.log(err);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconsole.log(`\\nProduct ${productName} successfully updated.`);\n\t\t\t\t\t\t\ttoMain();\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t});\n\t\t}\n\t});\n}\n\nfunction deleteProduct() {\n\tconst productsInfo = fs.readFileSync(SALES_FILE_NAME, 'utf-8');\n\tconst productsArray = productsInfo\n\t\t.split('\\n')\n\t\t.filter((product) => product !== '')\n\t\t.map((product) => product.split(', '));\n\n\tlet foundProduct = null;\n\n\trl.question('Which product do you want to delete?\\n', (productName) => {\n\t\tif (productName === '') {\n\t\t\tconsole.log('Please enter a valid product name');\n\t\t\treturn toMain();\n\t\t}\n\n\t\tfor (const product of productsArray) {\n\t\t\tif (product[0].includes(productName)) {\n\t\t\t\tfoundProduct = product;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (!foundProduct) {\n\t\t\tconsole.log(`${productName} not found`);\n\t\t\ttoMain();\n\t\t} else {\n\t\t\tconst filteredProducts = productsArray.filter(\n\t\t\t\t(product) => product !== foundProduct\n\t\t\t);\n\n\t\t\tconst productString = filteredProducts.join('\\n');\n\n\t\t\tfs.writeFile(SALES_FILE_NAME, productString, (err) => {\n\t\t\t\tif (err) {\n\t\t\t\t\tconsole.log(err);\n\t\t\t\t} else {\n\t\t\t\t\tconsole.log(`\\nProduct ${productName} successfully deleted.`);\n\t\t\t\t\ttoMain();\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t});\n}\n\nfunction salesByProduct() {\n\tconst productsInfo = fs.readFileSync(SALES_FILE_NAME, 'utf-8');\n\tconst productsArray = productsInfo\n\t\t.split('\\n')\n\t\t.filter((product) => product !== '')\n\t\t.map((product) => product.split(', '));\n\n\tlet foundProduct = null;\n\n\trl.question('Which product do you want to consult?\\n', (productName) => {\n\t\tif (productName === '') {\n\t\t\tconsole.log('Please enter a valid product name');\n\t\t} else {\n\t\t\tfor (const product of productsArray) {\n\t\t\t\tif (product[0].includes(productName)) {\n\t\t\t\t\tfoundProduct = product;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!foundProduct) {\n\t\t\t\tconsole.log(`${productName} not found`);\n\t\t\t} else {\n\t\t\t\tconst quantity = parseInt(foundProduct[1]);\n\t\t\t\tconst price = parseFloat(foundProduct[2].substring(1));\n\t\t\t\tconst totalByProduct = quantity * price;\n\n\t\t\t\tconsole.log(\n\t\t\t\t\t`\\nTotal sales by product ${productName}: $${totalByProduct}`\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\ttoMain();\n\t});\n}\n\nfunction totalSales() {\n\tconst productsInfo = fs.readFileSync(SALES_FILE_NAME, 'utf-8');\n\tconst productsArray = productsInfo\n\t\t.split('\\n')\n\t\t.filter((product) => product !== '')\n\t\t.map((product) => product.split(', '));\n\n\tlet totalSales = 0;\n\n\tfor (const product of productsArray) {\n\t\tconst quantity = parseInt(product[1]);\n\t\tconst price = parseFloat(product[2].substring(1));\n\t\ttotalSales += quantity * price;\n\t}\n\n\tconsole.log(`\\nTotal sales: $${totalSales}`);\n\n\ttoMain();\n}\n\nfunction allProducts() {\n\tconst productsInfo = fs.readFileSync(SALES_FILE_NAME, 'utf-8');\n\tconst productsArray = productsInfo\n\t\t.split('\\n')\n\t\t.filter((product) => product !== '')\n\t\t.map((product) => product.split(', '));\n\n\tfor (const product of productsArray) {\n\t\tconsole.log(product.join(', '));\n\t}\n\n\ttoMain();\n}\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/javascript/duendeintemporal.js",
    "content": "//#11 MANEJO DE FICHEROS\n//Bibliography\n//Professional JavaScript for web developers by Matt Frisbie [Frisbie, Matt] (z-lib.org)\n//GPT\n\n/*  The File Type\nThe File API is still based around the file input field of a form but adds the ability to access the file\ninformation directly. HTML5 adds a files collection to DOM for the file input element. When one\nor more files are selected in the field, the files collection contains a sequence of File objects that\nrepresent each file. Each File object has several read-only properties, including:\n➤➤ name—The file name on the local system.\n➤➤ size—The size of the file in bytes.\nBlob and File APIs ❘ 759\n➤➤ type—A string containing the MIME type of the file.\n➤➤ lastModifiedDate—A string representing the last time the file was modified. This property\nhas been implemented only in Chrome. */\n\n/* The FileReader Type\nThe FileReader type represents an asynchronous file-reading mechanism. You can think of File-\nReader as similar to XMLHttpRequest, only it is used for reading files from the file system as opposed\nto reading data from the server. The FileReader type offers several methods to read in file data:\n➤➤ readAsText(file, encoding)—Reads the file as plain text and stores the text in the\nresult property. The second argument, the encoding type, is optional.\n➤➤ readAsDataURL(file)—Reads the file and stores a data URI representing the files in the\nresult property.\n➤➤ readAsBinaryString(file)—Reads the file and stores a string where each character repre-\nsents a byte in the result property.\n➤➤ readAsArrayBuffer(file)—Reads the file and stores an ArrayBuffer containing the file\ncontents in the result property. */\n\n\n//How ever we will use Node.js to facilitate the files manipulation, so you have to run this file in Node to interact with the console\n\n//short for console.log\nlet log = console.log;\n\nconst fs = require('fs');\nconst path = require('path');\n\nconst githubUser = 'duendeintemporal';\nconst f_path = path.join(__dirname, `${githubUser}.txt`);\n\n// Data to write in the file\nconst name = 'Niko Zen';\nconst age = '41';\nconst favoriteLanguage = 'JavaScript';\n\n// Create and write to the file\nfs.writeFile(f_path, `Name: ${name}\\nAge: ${age}\\nFavoriteLanguage: ${favoriteLanguage}\\n`, (err) => {\n    if (err) {\n        console.error('Error creating the file: ', err);\n        return;\n    }\n    log(`File ${githubUser}.txt created successfully.`);\n\n    // Read the content of the file\n    fs.readFile(f_path, 'utf8', (err, data) => {\n        if (err) {\n            error(`Error reading the file ${githubUser}.txt: `, err);\n            return;\n        }\n        log('Content of the file: ');\n        log(data);\n\n        // Delete the file\n        fs.unlink(f_path, (err) => {\n            if (err) {\n                error(`Error deleting the file ${githubUser}.txt: `, err);\n                return;\n            }\n            log(`File ${githubUser}.txt deleted successfully.`);\n        });\n    });\n});\n\n//Extra Dificulty Exercise\n\nconst readline = require('readline');\n\nconst filePath = 'sales.txt';\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nconst menu = () => {\n    log('\\n--- Sales Management ---');\n    log('1. Add Product');\n    log('2. View Products');\n    log('3. Update Product');\n    log('4. Delete Product');\n    log('5. Calculate Total Sales');\n    log('6. Calculate Sales by Product');\n    log('7. Exit');\n    rl.question('Select an option: ', handleMenuOption);\n};\n\nconst handleMenuOption = (option) => {\n    switch (option) {\n        case '1':\n            addProduct();\n            break;\n        case '2':\n            viewProducts();\n            break;\n        case '3':\n            updateProduct();\n            break;\n        case '4':\n            deleteProduct();\n            break;\n        case '5':\n            calculateTotalSales();\n            break;\n        case '6':\n            calculateSalesByProduct();\n            break;\n        case '7':\n            exitProgram();\n            break;\n        default:\n            log('Invalid option, choose a number between 1 and 7. Please try again.');\n            menu();\n            break;\n    }\n};\n\nconst addProduct = () => {\n    rl.question('Product Name: ', (name) => {\n        rl.question('Quantity Sold: ', (quantity) => {\n            rl.question('Price: ', (price) => {\n                const product = `${name}, ${quantity}, ${price}\\n`;\n                fs.appendFile(filePath, product, (err) => {\n                    if (err) throw err;\n                    log('Product added.');\n                    menu();\n                });\n            });\n        });\n    });\n};\n\nconst viewProducts = () => {\n    fs.readFile(filePath, 'utf8', (err, data) => {\n        if (err) throw err;\n        log('\\nProducts:\\n' + (data || 'No products registered.'));\n        menu();\n    });\n};\n\nconst updateProduct = () => {\n    rl.question('Product Name to Update: ', (name) => {\n        rl.question('New Quantity Sold: ', (newQuantity) => {\n            rl.question('New Price: ', (newPrice) => {\n                fs.readFile(filePath, 'utf8', (err, data) => {\n                    if (err) throw err;\n                    const products = data.split('\\n').map(line => {\n                        if (line.startsWith(name)) {\n                            return `${name}, ${newQuantity}, ${newPrice}`;\n                        }\n                        return line;\n                    }).join('\\n');\n                    fs.writeFile(filePath, products, (err) => {\n                        if (err) throw err;\n                        log('Product updated.');\n                        menu();\n                    });\n                });\n            });\n        });\n    });\n};\n\nconst deleteProduct = () => {\n    rl.question('Product Name to Delete: ', (name) => {\n        fs.readFile(filePath, 'utf8', (err, data) => {\n            if (err) throw err;\n            const products = data.split('\\n').filter(line => !line.startsWith(name)).join('\\n');\n            fs.writeFile(filePath, products, (err) => {\n                if (err) throw err;\n                log('Product deleted.');\n                menu();\n            });\n        });\n    });\n};\n\nconst calculateTotalSales = () => {\n    fs.readFile(filePath, 'utf8', (err, data) => {\n        if (err) throw err;\n        const total = data.split('\\n').reduce((sum, line) => {\n            const parts = line.split(', ');\n            return sum + (parseInt(parts[1] || 0) * parseFloat(parts[2] || 0));\n        }, 0);\n        log(`Total Sales: ${total.toFixed(2)}`);\n        menu();\n    });\n};\n\nconst calculateSalesByProduct = () => {\n    rl.question('Product Name: ', (name) => {\n        fs.readFile(filePath, 'utf8', (err, data) => {\n            if (err) throw err;\n            const total = data.split('\\n').reduce((sum, line) => {\n                const parts = line.split(', ');\n                if (parts[0] === name) {\n                    return sum + (parseInt(parts[1] || 0) * parseFloat(parts[2] || 0));\n                }\n                return sum;\n           \n            }, 0);\n            log(`Total Sales for ${name}: ${total.toFixed(2)}`);\n            menu();\n        });\n    });\n};\n\nconst exitProgram = () => {\n    fs.unlink(filePath, (err) => {\n        if (err) {\n            error('Error deleting the file:', err);\n            return;\n        }\n        log('Exiting the program and deleting the sales data file.');\n        rl.close();\n    });\n};\n\nsetTimeout(()=>{\n    menu();\n}, 1200);\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/javascript/edalmava.js",
    "content": "// En package.json se debe agregar \"type\": \"module\" para usar archivo .js\n\nimport { open, unlink, access, constants } from 'node:fs/promises';\nimport * as readline from 'node:readline/promises';\nimport { stdin as input, stdout as output } from 'node:process';\n\nasync function manageFile() {\n    try {\n        console.log('Creando archivo de texto edalmava.txt...');\n        const filehandle = await open('edalmava.txt', 'a');        \n        await filehandle.appendFile(\"Edalmava\\n\");\n        await filehandle.appendFile(\"30\\n\");\n        await filehandle.appendFile(\"JavaScript\\n\");\n        await filehandle.close();\n\n        console.log('\\nImprimiendo el contenido del archivo edalmava.txt:');\n        const file = await open('edalmava.txt');\n        for await (const line of file.readLines()) {\n            console.log(line);\n        }\n        await file.close();\n\n        console.log('\\nBorrando archivo de texto edalmava.txt...')\n        await unlink('edalmava.txt');\n        console.log('Borrado exitoso del archivo edalmava.txt');\n\n        await retoExtra();\n    } catch (error) {\n        console.error('Ha ocurrido un error:', error.message);\n    }\n}\n\nasync function guardarVenta(rl2) {    \n    try {\n        console.log('Añadir Venta');        \n\n        const nombreProducto = await rl2.question('Nombre Producto: ');\n        const cantidadVendida = await rl2.question('Cantidad Vendida: ');\n        const precio = await rl2.question('Precio Producto: ');\n\n        const producto = [nombreProducto, cantidadVendida, precio, precio * cantidadVendida].join(',')\n\n        const filehandle = await open('ventas.txt', 'a');        \n        await filehandle.appendFile(`${producto}\\n`);\n        await filehandle.close();        \n    } catch(error) {\n        console.error('Ha ocurrido un error:', error.message);\n    }\n}\n\nasync function mostrarProductos() {\n    try {\n        await access('ventas.txt', constants.F_OK);\n        console.log('\\nVentas:\\n');\n        const file = await open('ventas.txt');\n        for await (const line of file.readLines()) {\n            console.log(line);\n        }\n        await file.close();\n    } catch(error) {\n        if (error.code === 'ENOENT') {\n            console.error('Todavía no se han añadido productos al archivo de ventas');\n        } else {\n            console.error('Ha ocurrido un error:', error.message);\n        }        \n    }\n}\n\nasync function retoExtra() {\n    const rl = readline.createInterface({ input, output, terminal: false });\n    try {\n        \n        let opcion = '';\n\n        while (opcion !== '3') {\n            console.log('\\nMenú Principal\\n');\n            opcion = await rl.question('1. Añadir venta\\n2. Consultar Ventas\\n3. Salir\\n\\nEscoja su opción: ');\n            switch (opcion) {\n                case '1':\n                    await guardarVenta(rl);\n                    break;\n                case '2':\n                    await mostrarProductos();\n                    break;\n                case '3':\n                    console.log('Saliendo...')\n                    try {\n                        await access('ventas.txt', constants.F_OK);\n                        await unlink('ventas.txt');\n                        console.log('Archivo de ventas borrado');\n                    } catch(error) {\n                        if (error.code !== 'ENOENT') {\n                            console.error('Error al verificar o borrar el archivo de ventas:', error.message);\n                        }\n                    }\n                    \n                    break;\n                default:\n                    console.log('Opción no válida\\n')\n            }\n        }\n\n        rl.close();\n    } catch (error) {\n        console.error('Ha ocurrido un error:', error.message);\n        rl.close();\n    }\n}\n\nmanageFile();\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/javascript/emedevelopa.js",
    "content": "/*const fs = require(\"fs\"); //Importa el módulo que permite interactuar con el sistema de archivos\n\nconst nombreUsuario = \"emedevelopa\";\nconst contenido = [\n    \"Nombre: María Campos\",\n    \"Edad: 33\",\n    \"Lenguaje de programación: JavaScript\"\n].join(\"\\n\") //lo transforma a string y hace salto de linea.\n\nconst nombreArchivo = `${nombreUsuario}.txt`;\n\n//Escribir contenido en el archivo\nfs.writeFile(nombreArchivo, contenido, (err) => {\n    if (err) {\n        console.error(\"Error al crear el archivo:\", err);\n    } else {\n        console.log(`Archivo '${nombreArchivo}' creado con éxito`);\n\n        //Leer contenido del archivo\n        fs.readFile(nombreArchivo, \"utf8\", (err, data) => {\n            if (err) {\n                console.error(\"Error al leer el archivo:\", err);\n            } else {\n                console.log(`Contenido del archivo '${nombreArchivo}':\\n`, data);\n\n                //Borrar archivo\n                fs.unlink(nombreArchivo, (err) => {\n                    if(err) {\n                        console.error(\"Error al borrar el archivo:\", err);\n                    } else {\n                        console.log(`Archivo '${nombreArchivo}' borrado con éxito`);\n                    }\n                });\n            }\n        });\n    }\n}); */\n\n//EXTRA\nconst fs = require(\"fs\");\nconst { arch } = require(\"os\");\nconst readline = require(\"readline\");\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nconst archivoVentas = \"ventas.txt\";\n\nfunction añadirProductos() {\n        rl.question(\"Nombre del producto: \", (nombre) => {\n            rl.question(\"Cantidad vendida: \", (cantidad) => {\n                rl.question(\"Precio: \", (precio) => {\n                    const linea = `${nombre}, ${cantidad}, ${precio}\\n`;\n                    fs.appendFile(archivoVentas, linea, (err) => {\n                        if(err) {\n                            console.error(\"Ha ocurrido un error\", err);\n                        } else {\n                            console.log(\"Producto añadido con éxito\");\n                        }\n                        mostrarMenu();\n                    });\n                });\n            });\n        });\n    \n}\n\nfunction consultaVentas() {\n    fs.readFile(archivoVentas, \"utf8\", (err,data) => {\n        if (err) {\n            console.error(\"Error al leer el archivo\", err);\n        } else {\n            console.log(\"Ventas:\\n\", data);\n        }\n        mostrarMenu();\n    });\n}\n\nfunction actualizarProductos () {\n    rl.question(\"Añade el nombre del producto que deseas actualizar: \", (nombre) => {\n        fs.readFile(archivoVentas, \"utf8\", (err, data) => {\n            if (err) {\n                console.error(\"Error al leer el archivo:\", err);\n                mostrarMenu();\n                return;\n            }\n            const lineas = data.split(\"\\n\");\n            let productoEncontrado = false;\n            const nuevoContenido = [];\n\n            for (const linea of lineas) {\n                const[nombreProducto, cantidadVendida, precio] = linea.split(', ');\n                if (nombreProducto === nombre) {\n                    rl.question (\"Añade la nueva cantidad vendida: \", (nuevaCantidad) => {\n                        rl.question(\"Añade el nuevo precio: \", (nuevoPrecio) => {\n                            const nuevaLinea = `${nombre}, ${nuevaCantidad}, ${nuevoPrecio}`;\n                            nuevoContenido.push(nuevaLinea);\n                            productoEncontrado = true;\n                            console.log(\"Producto actualizado con éxito.\");\n                            rl.close();\n                        });\n                    });\n                } else {\n                    nuevoContenido.push(linea);\n                }\n            } if (!productoEncontrado) {\n                console.log(\"No se encontró el producto.\");\n                mostrarMenu();\n            } else {\n                fs.writeFile(archivoVentas, nuevoContenido.join('\\n'), (err) => {\n                    if (err) {\n                        console.error(\"Error al escribir el archivo.\", err);\n                    }\n                    mostrarMenu();\n                });\n            }\n        });\n    });\n}\n\nfunction eliminarProducto () {\n    rl.question(\"Añade el nombre del producto que deseas eliminar: \", (nombre) => {\n        fs.readFile(archivoVentas, \"utf8\", (err, data) => {\n            if (err) {\n                console.log(\"Error al leer el archivo.\", err);\n                mostrarMenu();\n                return;\n            }\n            const lineas = data.split('\\n');\n            let productoEncontrado = false;\n            const nuevoContenido = [];\n\n            for (const linea of lineas) {\n                const [nombreProducto] = linea.split(', ');\n                if (nombreProducto === nombre) {\n                    productoEncontrado = true;\n                    console.log(\"Producto eliminado con éxito.\");\n                } else {\n                    nuevoContenido.push(linea);\n                }\n            }\n            if (!productoEncontrado) {\n                console.log(\"No se encontró el producto.\");\n            }\n            fs.writeFile(archivoVentas, nuevoContenido.join('\\n'), (err) => {\n                if (err) {\n                    console.error(\"Error al escribir en el archivo.\", err);\n                }\n                mostrarMenu();\n            });\n        });\n    });\n}\n\nfunction salir () {\n    fs.unlink (archivoVentas, (err) => {\n        if (err) {\n            console.error(\"Error al borrar el archivo:\", err);\n        } else {\n            console.log(\"Archivo borrado con éxito. Saliendo...\");\n        }\n        rl.close();\n    });\n}\n\nfunction mostrarMenu() {\n    console.log('\\n-- MENÚ --');\n    console.log('1. Añadir producto');\n    console.log('2. Actualizar producto');\n    console.log('3. Consultar ventas');\n    console.log('4. Eliminar producto');\n    console.log('5. Salir');\n    rl.question('6. Selecciona una opción: ', (opcion) => {\n        switch (opcion) {\n            case '1':\n                añadirProductos();\n                break;\n            case '2':\n                actualizarProductos();\n                break;\n            case '3':\n                consultaVentas();\n                break;\n            case '4':\n                eliminarProducto();\n                break;\n            case '5':\n                salir();\n                break;\n            default:\n                console.log(\"Opción no válida. Intentalo de nuevo.\");\n                mostrarMenu();\n        }\n    });\n}\nmostrarMenu();"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/javascript/eulogioep.js",
    "content": "const fs = require('fs').promises;\nconst readline = require('readline');\n\n// Constantes para los nombres de archivo\nconst FILENAME = 'info_personal.txt';\nconst SALES_FILENAME = 'ventas.txt';\n\n// Configuración de la interfaz de lectura\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\n// Función para preguntar al usuario\nconst pregunta = (pregunta) => {\n    return new Promise((resolve) => {\n        rl.question(pregunta, resolve);\n    });\n};\n\n// Función principal\nasync function main() {\n    await crearArchivoPersonal();\n    await gestionVentas();\n}\n\n// Función para crear y manipular el archivo personal\nasync function crearArchivoPersonal() {\n    try {\n        // Crear y escribir en el archivo\n        await fs.writeFile(FILENAME, 'Nombre: Juan\\nEdad: 30\\nLenguaje de programación favorito: JavaScript');\n        console.log('Archivo creado y escrito con éxito.');\n\n        // Leer y mostrar el contenido\n        const contenido = await fs.readFile(FILENAME, 'utf8');\n        console.log('Contenido del archivo:');\n        console.log(contenido);\n\n        // Borrar el archivo\n        await fs.unlink(FILENAME);\n        console.log('Archivo borrado con éxito.');\n    } catch (error) {\n        console.error('Error:', error.message);\n    }\n}\n\n// Función para la gestión de ventas\nasync function gestionVentas() {\n    let salir = false;\n\n    while (!salir) {\n        console.log('\\n--- Gestión de Ventas ---');\n        console.log('1. Añadir producto');\n        console.log('2. Consultar productos');\n        console.log('3. Actualizar producto');\n        console.log('4. Eliminar producto');\n        console.log('5. Calcular venta total');\n        console.log('6. Calcular venta por producto');\n        console.log('7. Salir');\n\n        const opcion = await pregunta('Seleccione una opción: ');\n\n        switch (opcion) {\n            case '1':\n                await anadirProducto();\n                break;\n            case '2':\n                await consultarProductos();\n                break;\n            case '3':\n                await actualizarProducto();\n                break;\n            case '4':\n                await eliminarProducto();\n                break;\n            case '5':\n                await calcularVentaTotal();\n                break;\n            case '6':\n                await calcularVentaPorProducto();\n                break;\n            case '7':\n                salir = true;\n                await borrarArchivoVentas();\n                rl.close();\n                break;\n            default:\n                console.log('Opción no válida.');\n        }\n    }\n}\n\n// Función para añadir un producto\nasync function anadirProducto() {\n    const nombre = await pregunta('Nombre del producto: ');\n    const cantidad = await pregunta('Cantidad vendida: ');\n    const precio = await pregunta('Precio: ');\n\n    const linea = `${nombre}, ${cantidad}, ${precio}\\n`;\n    await fs.appendFile(SALES_FILENAME, linea);\n    console.log('Producto añadido con éxito.');\n}\n\n// Función para consultar productos\nasync function consultarProductos() {\n    try {\n        const contenido = await fs.readFile(SALES_FILENAME, 'utf8');\n        console.log('\\nProductos:');\n        console.log(contenido);\n    } catch (error) {\n        if (error.code === 'ENOENT') {\n            console.log('No hay productos registrados.');\n        } else {\n            console.error('Error al consultar productos:', error.message);\n        }\n    }\n}\n\n// Función para actualizar un producto\nasync function actualizarProducto() {\n    const nombreActualizar = await pregunta('Nombre del producto a actualizar: ');\n    const nuevaCantidad = await pregunta('Nueva cantidad vendida: ');\n    const nuevoPrecio = await pregunta('Nuevo precio: ');\n\n    try {\n        let contenido = await fs.readFile(SALES_FILENAME, 'utf8');\n        let lineas = contenido.split('\\n');\n        let encontrado = false;\n\n        lineas = lineas.map(linea => {\n            const [nombre, ...resto] = linea.split(', ');\n            if (nombre === nombreActualizar) {\n                encontrado = true;\n                return `${nombre}, ${nuevaCantidad}, ${nuevoPrecio}`;\n            }\n            return linea;\n        });\n\n        if (encontrado) {\n            await fs.writeFile(SALES_FILENAME, lineas.join('\\n'));\n            console.log('Producto actualizado con éxito.');\n        } else {\n            console.log('Producto no encontrado.');\n        }\n    } catch (error) {\n        console.error('Error al actualizar producto:', error.message);\n    }\n}\n\n// Función para eliminar un producto\nasync function eliminarProducto() {\n    const nombreEliminar = await pregunta('Nombre del producto a eliminar: ');\n\n    try {\n        let contenido = await fs.readFile(SALES_FILENAME, 'utf8');\n        let lineas = contenido.split('\\n');\n        let encontrado = false;\n\n        lineas = lineas.filter(linea => {\n            const [nombre] = linea.split(', ');\n            if (nombre === nombreEliminar) {\n                encontrado = true;\n                return false;\n            }\n            return true;\n        });\n\n        if (encontrado) {\n            await fs.writeFile(SALES_FILENAME, lineas.join('\\n'));\n            console.log('Producto eliminado con éxito.');\n        } else {\n            console.log('Producto no encontrado.');\n        }\n    } catch (error) {\n        console.error('Error al eliminar producto:', error.message);\n    }\n}\n\n// Función para calcular la venta total\nasync function calcularVentaTotal() {\n    try {\n        const contenido = await fs.readFile(SALES_FILENAME, 'utf8');\n        const lineas = contenido.split('\\n');\n        let ventaTotal = 0;\n\n        lineas.forEach(linea => {\n            if (linea.trim() !== '') {\n                const [, cantidad, precio] = linea.split(', ');\n                ventaTotal += parseFloat(cantidad) * parseFloat(precio);\n            }\n        });\n\n        console.log(`Venta total: ${ventaTotal.toFixed(2)}`);\n    } catch (error) {\n        console.error('Error al calcular venta total:', error.message);\n    }\n}\n\n// Función para calcular la venta por producto\nasync function calcularVentaPorProducto() {\n    const nombreProducto = await pregunta('Nombre del producto: ');\n\n    try {\n        const contenido = await fs.readFile(SALES_FILENAME, 'utf8');\n        const lineas = contenido.split('\\n');\n        let encontrado = false;\n\n        lineas.forEach(linea => {\n            if (linea.trim() !== '') {\n                const [nombre, cantidad, precio] = linea.split(', ');\n                if (nombre === nombreProducto) {\n                    const ventaProducto = parseFloat(cantidad) * parseFloat(precio);\n                    console.log(`Venta de ${nombreProducto}: ${ventaProducto.toFixed(2)}`);\n                    encontrado = true;\n                }\n            }\n        });\n\n        if (!encontrado) {\n            console.log('Producto no encontrado.');\n        }\n    } catch (error) {\n        console.error('Error al calcular venta por producto:', error.message);\n    }\n}\n\n// Función para borrar el archivo de ventas\nasync function borrarArchivoVentas() {\n    try {\n        await fs.unlink(SALES_FILENAME);\n        console.log('Archivo de ventas borrado con éxito.');\n    } catch (error) {\n        if (error.code === 'ENOENT') {\n            console.log('El archivo de ventas no existe.');\n        } else {\n            console.error('Error al borrar el archivo de ventas:', error.message);\n        }\n    }\n}\n\n// Ejecutar el programa principal\nmain().catch(console.error);"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/javascript/garos01.js",
    "content": "const fs = require(\"fs\");\n\n// Obtener el nombre de usuario de GitHub\nconst username = \"GAROS01\";\n\n// Crear el nombre del archivo con extensión .txt\nconst filename = `${username}.txt`;\n\n// Contenido a escribir en el archivo\nconst content = `Nombre: Oscar Garzon\\nEdad: 29\\nLenguaje de programación favorito: Python y JavaScript\\n`;\n\n// Escribir en el archivo\nfs.writeFile(filename, content, (err) => {\n  if (err) {\n    console.error(\"Error al escribir en el archivo:\", err);\n    return;\n  }\n  console.log(\"Archivo creado y contenido agregado correctamente.\");\n\n  // Leer el contenido del archivo y mostrarlo\n  fs.readFile(filename, \"utf8\", (err, data) => {\n    if (err) {\n      console.error(\"Error al leer el archivo:\", err);\n      return;\n    }\n    console.log(\"Contenido del archivo:\");\n    console.log(data);\n\n    // Borrar el archivo\n    fs.unlink(filename, (err) => {\n      if (err) {\n        console.error(\"Error al borrar el archivo:\", err);\n        return;\n      }\n      console.log(`El archivo ${filename} ha sido borrado.`);\n    });\n  });\n});\n\n// Ejercicio estra\n\nconst readline = require(\"readline\");\n\nconst archivo = \"ventas.txt\";\n\nfunction leerArchivo() {\n  try {\n    return fs.readFileSync(archivo, \"utf8\").split(\"\\n\");\n  } catch (error) {\n    console.log(\"No hay ventas registradas.\");\n    return [];\n  }\n}\n\nfunction guardarVenta(nombreProducto, cantidad, precio) {\n  fs.appendFileSync(archivo, `${nombreProducto}, ${cantidad}, ${precio}\\n`);\n}\n\nfunction mostrarVentas() {\n  const ventas = leerArchivo();\n  if (ventas.length > 0) {\n    console.log(\"Ventas realizadas:\");\n    ventas.forEach((venta) => console.log(venta.trim()));\n  } else {\n    console.log(\"No hay ventas registradas.\");\n  }\n}\n\nfunction actualizarVenta(nombreProducto, nuevaCantidad, nuevoPrecio) {\n  const ventas = leerArchivo();\n  const nuevasVentas = ventas.map((venta) => {\n    const [producto, cantidad, precio] = venta.split(\", \");\n    if (producto === nombreProducto) {\n      return `${nombreProducto}, ${nuevaCantidad}, ${nuevoPrecio}`;\n    }\n    return venta;\n  });\n  fs.writeFileSync(archivo, nuevasVentas.join(\"\\n\"));\n}\n\nfunction eliminarVenta(nombreProducto) {\n  const ventas = leerArchivo();\n  const nuevasVentas = ventas.filter((venta) => {\n    const [producto] = venta.split(\", \");\n    return producto !== nombreProducto;\n  });\n  fs.writeFileSync(archivo, nuevasVentas.join(\"\\n\"));\n}\n\nfunction calcularVentaTotal() {\n  const ventas = leerArchivo();\n  let total = 0;\n  ventas.forEach((venta) => {\n    const [_, cantidad, precio] = venta.split(\", \");\n    total += parseInt(cantidad) * parseFloat(precio);\n  });\n  console.log(`Venta total: ${total}`);\n}\n\nfunction calcularVentaProducto(nombreProducto) {\n  const ventas = leerArchivo();\n  const ventaProducto = ventas.find((venta) => {\n    const [producto, _, __] = venta.split(\", \");\n    return producto === nombreProducto;\n  });\n  if (ventaProducto) {\n    const [_, cantidad, precio] = ventaProducto.split(\", \");\n    console.log(\n      `Venta de ${nombreProducto}: ${parseInt(cantidad) * parseFloat(precio)}`\n    );\n  } else {\n    console.log(`No se encontró la venta del producto ${nombreProducto}`);\n  }\n}\n\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout,\n});\n\nfunction menu() {\n  console.log(\"\\nMenú:\");\n  console.log(\"1. Añadir venta\");\n  console.log(\"2. Consultar ventas\");\n  console.log(\"3. Actualizar venta\");\n  console.log(\"4. Eliminar venta\");\n  console.log(\"5. Calcular venta total\");\n  console.log(\"6. Calcular venta por producto\");\n  console.log(\"7. Salir y borrar archivo\");\n  rl.question(\"Seleccione una opción: \", function (opcion) {\n    switch (opcion) {\n      case \"1\":\n        rl.question(\n          \"Ingrese el nombre del producto: \",\n          function (nombreProducto) {\n            rl.question(\"Ingrese la cantidad vendida: \", function (cantidad) {\n              rl.question(\"Ingrese el precio unitario: \", function (precio) {\n                guardarVenta(nombreProducto, cantidad, precio);\n                menu();\n              });\n            });\n          }\n        );\n        break;\n      case \"2\":\n        mostrarVentas();\n        menu();\n        break;\n      case \"3\":\n        rl.question(\n          \"Ingrese el nombre del producto a actualizar: \",\n          function (nombreProducto) {\n            rl.question(\n              \"Ingrese la nueva cantidad vendida: \",\n              function (nuevaCantidad) {\n                rl.question(\n                  \"Ingrese el nuevo precio unitario: \",\n                  function (nuevoPrecio) {\n                    actualizarVenta(nombreProducto, nuevaCantidad, nuevoPrecio);\n                    menu();\n                  }\n                );\n              }\n            );\n          }\n        );\n        break;\n      case \"4\":\n        rl.question(\n          \"Ingrese el nombre del producto a eliminar: \",\n          function (nombreProducto) {\n            eliminarVenta(nombreProducto);\n            menu();\n          }\n        );\n        break;\n      case \"5\":\n        calcularVentaTotal();\n        menu();\n        break;\n      case \"6\":\n        rl.question(\n          \"Ingrese el nombre del producto para calcular su venta: \",\n          function (nombreProducto) {\n            calcularVentaProducto(nombreProducto);\n            menu();\n          }\n        );\n        break;\n      case \"7\":\n        fs.unlinkSync(archivo);\n        console.log(\"Archivo borrado. Saliendo del programa.\");\n        rl.close();\n        break;\n      default:\n        console.log(\"Opción no válida. Inténtelo de nuevo.\");\n        menu();\n        break;\n    }\n  });\n}\n\nmenu();\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/javascript/giovanyosorio.js",
    "content": "/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n * \n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n * archivo .txt.\n * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n */\n/*\nconst fs = require('fs');\nconst path = require('path');\n\nconst githubUsername = 'giovanyosorio';\nconst filename = `${githubUsername}.txt`;\nconst filePath = path.join(__dirname, filename);\n\n// Crear y escribir en el archivo\nfs.writeFileSync(filePath, 'Tu nombre\\nEdad\\nLenguaje de programación favorito');\n\n// Leer e imprimir el contenido del archivo\nconst content = fs.readFileSync(filePath, 'utf8');\nconsole.log(content);\n\n// Borrar el archivo\nfs.unlinkSync(filePath);\n\n\nconst fs = require('fs');\nconst readline = require('readline');\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout\n});\n*/\nconst fs = require('fs');\nconst readline = require('readline');\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout\n});\n\nconst filename = 'ventas.txt';\n\nconst addProduct = () => {\n  rl.question('Introduce el nombre del producto: ', (name) => {\n    rl.question('Introduce la cantidad vendida: ', (quantity) => {\n      rl.question('Introduce el precio: ', (price) => {\n        const newProduct = `${name}, ${quantity}, ${price}\\n`;\n        fs.appendFileSync(filename, newProduct);\n        console.log('Producto añadido correctamente.');\n        mainMenu();\n      });\n    });\n  });\n};\n\nconst viewProducts = () => {\n  const data = fs.readFileSync(filename, 'utf8');\n  console.log('\\nProductos:\\n' + data);\n  mainMenu();\n};\n\nconst updateProduct = () => {\n  rl.question('Introduce el nombre del producto a actualizar: ', (name) => {\n    const data = fs.readFileSync(filename, 'utf8');\n    const lines = data.split('\\n');\n    let found = false;\n\n    for (let i = 0; i < lines.length; i++) {\n      if (lines[i].startsWith(name + ',')) {\n        found = true;\n        rl.question('Introduce la nueva cantidad vendida: ', (quantity) => {\n          rl.question('Introduce el nuevo precio: ', (price) => {\n            lines[i] = `${name}, ${quantity}, ${price}`;\n            fs.writeFileSync(filename, lines.join('\\n'));\n            console.log('Producto actualizado correctamente.');\n            mainMenu();\n          });\n        });\n        break;\n      }\n    }\n\n    if (!found) {\n      console.log('Producto no encontrado.');\n      mainMenu();\n    }\n  });\n};\n\nconst deleteProduct = () => {\n  rl.question('Introduce el nombre del producto a eliminar: ', (name) => {\n    const data = fs.readFileSync(filename, 'utf8');\n    const lines = data.split('\\n');\n    const filteredLines = lines.filter(line => !line.startsWith(name + ','));\n\n    if (lines.length !== filteredLines.length) {\n      fs.writeFileSync(filename, filteredLines.join('\\n'));\n      console.log('Producto eliminado correctamente.');\n    } else {\n      console.log('Producto no encontrado.');\n    }\n    mainMenu();\n  });\n};\n\nconst calculateTotalSales = () => {\n  const data = fs.readFileSync(filename, 'utf8');\n  const lines = data.split('\\n');\n  let total = 0;\n\n  lines.forEach(line => {\n    const parts = line.split(', ');\n    if (parts.length === 3) {\n      total += parseInt(parts[1]) * parseFloat(parts[2]);\n    }\n  });\n\n  console.log(`Venta total: ${total}`);\n  mainMenu();\n};\n\nconst calculateSalesByProduct = () => {\n  rl.question('Introduce el nombre del producto: ', (name) => {\n    const data = fs.readFileSync(filename, 'utf8');\n    const lines = data.split('\\n');\n    let found = false;\n\n    lines.forEach(line => {\n      const parts = line.split(', ');\n      if (parts.length === 3 && parts[0] === name) {\n        found = true;\n        const total = parseInt(parts[1]) * parseFloat(parts[2]);\n        console.log(`Venta total para ${name}: ${total}`);\n      }\n    });\n\n    if (!found) {\n      console.log('Producto no encontrado.');\n    }\n    mainMenu();\n  });\n};\n\nconst mainMenu = () => {\n  console.log('\\nGestión de ventas:');\n  console.log('1. Añadir producto');\n  console.log('2. Consultar productos');\n  console.log('3. Actualizar producto');\n  console.log('4. Eliminar producto');\n  console.log('5. Calcular venta total');\n  console.log('6. Calcular venta por producto');\n  console.log('7. Salir');\n  rl.question('Elige una opción: ', (option) => {\n    switch (option) {\n      case '1':\n        addProduct();\n        break;\n      case '2':\n        viewProducts();\n        break;\n      case '3':\n        updateProduct();\n        break;\n      case '4':\n        deleteProduct();\n        break;\n      case '5':\n        calculateTotalSales();\n        break;\n      case '6':\n        calculateSalesByProduct();\n        break;\n      case '7':\n        fs.unlinkSync(filename);\n        rl.close();\n        break;\n      default:\n        console.log('Opción no válida. Inténtalo de nuevo.');\n        mainMenu();\n    }\n  });\n};\n\nmainMenu();\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/javascript/hectorio23.js",
    "content": "\"use strict\";\n\nconst fs = require('fs');\nconst readline = require('readline');\n\n// Definición de las funciones principales del programa\nconst ventas = {\n    archivo: 'ventas.txt',\n\n    async agregarProducto(producto) {\n        await appendToFile(this.archivo, `${producto.nombre}, ${producto.cantidad}, ${producto.precio}\\n`);\n    },\n\n    async consultarProductos() {\n        const data = await readFile(this.archivo);\n        console.log(data);\n    },\n\n    async actualizarProducto(nombre, cantidad, precio) {\n        const tempFile = 'temporal.txt';\n        const readStream = fs.createReadStream(this.archivo);\n        const writeStream = fs.createWriteStream(tempFile);\n        const rl = readline.createInterface({\n            input: readStream,\n            output: writeStream\n        });\n\n        for await (const line of rl) {\n            const [nombreProducto, cantidadStr, precioStr] = line.split(',');\n            if (nombreProducto.trim() === nombre) {\n                writeStream.write(`${nombre}, ${cantidad}, ${precio}\\n`);\n            } else {\n                writeStream.write(`${line}\\n`);\n            }\n        }\n\n        await new Promise(resolve => {\n            readStream.close();\n            writeStream.close();\n            fs.unlink(this.archivo, () => {\n                fs.rename(tempFile, this.archivo, resolve);\n            });\n        });\n    },\n\n    async eliminarProducto(nombre) {\n        const tempFile = 'temporal.txt';\n        const readStream = fs.createReadStream(this.archivo);\n        const writeStream = fs.createWriteStream(tempFile);\n        const rl = readline.createInterface({\n            input: readStream,\n            output: writeStream\n        });\n\n        for await (const line of rl) {\n            const [nombreProducto, , ] = line.split(',');\n            if (nombreProducto.trim() !== nombre) {\n                writeStream.write(`${line}\\n`);\n            }\n        }\n\n        await new Promise(resolve => {\n            readStream.close();\n            writeStream.close();\n            fs.unlink(this.archivo, () => {\n                fs.rename(tempFile, this.archivo, resolve);\n            });\n        });\n    },\n\n    async calcularVentaTotal() {\n        const data = await readFile(this.archivo);\n        const lines = data.split('\\n');\n        let total = 0;\n        for (const line of lines) {\n            const [cantidadStr, precioStr] = line.split(',');\n            const cantidad = parseInt(cantidadStr.trim());\n            const precio = parseFloat(precioStr.trim());\n            total += cantidad * precio;\n        }\n        return total;\n    },\n\n    async calcularVentaPorProducto(nombre) {\n        const data = await readFile(this.archivo);\n        const lines = data.split('\\n');\n        for (const line of lines) {\n            const [nombreProducto, cantidadStr, precioStr] = line.split(',');\n            if (nombreProducto.trim() === nombre) {\n                const cantidad = parseInt(cantidadStr.trim());\n                const precio = parseFloat(precioStr.trim());\n                return cantidad * precio;\n            }\n        }\n        return 0;\n    },\n\n    async salir() {\n        await fs.promises.unlink(this.archivo);\n        console.log(\"Archivo borrado. Saliendo del programa...\");\n        process.exit(0);\n    }\n};\n\n// Funciones de utilidad\nasync function appendToFile(filename, data) {\n    await fs.promises.appendFile(filename, data);\n}\n\nasync function readFile(filename) {\n    return await fs.promises.readFile(filename, 'utf8');\n}\n\n// Lógica principal del programa\nasync function main() {\n    console.log(\"===== Gestión de Ventas =====\");\n    console.log(\"1. Añadir producto\");\n    console.log(\"2. Consultar productos\");\n    console.log(\"3. Actualizar producto\");\n    console.log(\"4. Eliminar producto\");\n    console.log(\"5. Calcular venta total\");\n    console.log(\"6. Calcular venta por producto\");\n    console.log(\"7. Salir\");\n\n    const rl = readline.createInterface({\n        input: process.stdin,\n        output: process.stdout\n    });\n\n    rl.question(\"Seleccione una opción: \", async (opcion) => {\n        switch (opcion) {\n            case '1':\n                const producto = await obtenerDatosProducto();\n                await ventas.agregarProducto(producto);\n                break;\n            case '2':\n                await ventas.consultarProductos();\n                break;\n            case '3':\n                const { nombre, cantidad, precio } = await obtenerDatosProducto();\n                await ventas.actualizarProducto(nombre, cantidad, precio);\n                break;\n            case '4':\n                const nombreProductoEliminar = await obtenerNombreProducto();\n                await ventas.eliminarProducto(nombreProductoEliminar);\n                break;\n            case '5':\n                console.log(\"Venta total: $\" + await ventas.calcularVentaTotal());\n                break;\n            case '6':\n                const nombreProductoVenta = await obtenerNombreProducto();\n                console.log(\"Venta de \" + nombreProductoVenta + \": $\" + await ventas.calcularVentaPorProducto(nombreProductoVenta));\n                break;\n            case '7':\n                await ventas.salir();\n                break;\n            default:\n                console.log(\"Opción no válida\");\n                break;\n        }\n        rl.close();\n    });\n}\n\nasync function obtenerDatosProducto() {\n    return new Promise(resolve => {\n        const producto = {};\n        const rl = readline.createInterface({\n            input: process.stdin,\n            output: process.stdout\n        });\n        rl.question(\"Nombre del producto: \", (nombre) => {\n            rl.question(\"Cantidad vendida: \", (cantidad) => {\n                rl.question(\"Precio: \", (precio) => {\n                    rl.close();\n                    resolve({ nombre, cantidad: parseInt(cantidad), precio: parseFloat(precio) });\n                });\n            });\n        });\n    });\n}\n\nasync function obtenerNombreProducto() {\n    return new Promise(resolve => {\n        const rl = readline.createInterface({\n            input: process.stdin,\n            output: process.stdout\n        });\n        rl.question(\"Nombre del producto: \", (nombre) => {\n            rl.close();\n            resolve(nombre);\n        });\n    });\n}\n\n// Ejecución del programa\nmain().catch(error => console.error(error));\n\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/javascript/jeronimocardu.js",
    "content": "const fs = require('fs');\n\n// let nombre = 'jeronimocardu';\n// let archivo = `${nombre}.txt`;\n\n// let datos = [\n//     \"nombre: Jeronimo Cardu\",\n//     \"edad: 20 años\",\n//     \"lenguaje: JavaScript\"\n//     ].join('\\n');\n\n// // Añado el contenido\n// fs.writeFileSync(archivo, datos);\n\n// // Imprimo el contenido\n// console.log(fs.readFileSync(archivo, 'utf-8'));\n\n// // Borro el archivo\n// fs.unlinkSync(archivo);\n// console.log(`\\n${archivo} ha sido eliminado con exito`);\n\n//////////////////////////////////////////////////////////////\n//          Extra\nlet salesFile = 'ventas.txt';\nlet products = [];\n\nlet readline = require('readline').createInterface({\n    input: process.stdin,\n    output: process.stdout,\n});\n\nfunction addProduct(){\n    readline.question('\\n¿Qué producto desea agregar? ', nameProduct => {\n        for(let i of products){\n            if(i.name === nameProduct){\n                console.log('Este producto ya existe');\n                saveProductsToFile();\n                return;\n            }\n        }\n        readline.question(`\\n¿Cuál es la cantidad de ${nameProduct} que se vendieron? `, soldProducts => {\n            readline.question(`\\n¿Cuál es el precio unitario de cada ${nameProduct}? `, price => {\n                products.unshift({name: nameProduct, sold: parseInt(soldProducts), unitPrice: parseInt(price)});\n                console.log(`\\nLos datos de '${nameProduct}' se han agregado correctamente.`);\n                saveProductsToFile();\n            })\n        })\n    })\n}\nfunction consult(){\n    if(products.length > 0){\n        readline.question('\\nIngrese el nombre del producto que desea ver los datos: ', nameProduct => {\n            for(let i of products){\n                if(i.name === nameProduct){\n                    console.log(`\\nName: ${nameProduct}\\nQuantity Sold: ${i.sold}\\nUnit Price: $${i.unitPrice}`);\n                    saveProductsToFile();\n                    return;\n                }\n            }\n            console.log('\\nProducto no encontrado');\n            saveProductsToFile();\n        })\n    } else console.log('\\nNo hay productos registrados todavia.');\n    saveProductsToFile();\n}\nfunction update(){\n    let = found = false;\n    if(products.length > 0){\n        readline.question('\\n¿Qué producto quiere modificar? ', nameProduct => {\n            for(let i of products){\n                if(i.name === nameProduct){\n                    found = true;\n                    readline.question('\\nIngrese el nombre nuevo del producto (si no lo quiere cambiar presione ENTER): ', newNameProduct => {\n                        for(let i of products){\n                            if(i.name === newNameProduct){\n                                console.log('\\nNombre no disponible');\n                                break;\n                            }\n                        }\n                        if(newNameProduct !== '') i.name = newNameProduct;\n                        readline.question(`\\n¿Qué cantidad de ${i.name} se vendieron? (si no lo quiere cambiar presione ENTER) `, soldProducts => {\n                            if(soldProducts !== '') i.sold = parseInt(soldProducts);\n                            readline.question(`\\n¿Cuál es el precio unitario de cada ${i.name}? (si no lo quiere cambiar presione ENTER) `, price => {\n                                if(price !== '') i.unitPrice = parseInt(price);\n                                console.log('\\nProducto actualizado con exito!');\n                                saveProductsToFile();\n                                return;\n                            })\n                        })\n                    })\n                }\n                break;\n            }\n            if(!found) console.log('\\nProducto no encontrado');\n            saveProductsToFile();\n        })\n    } else console.log('\\nNo hay productos registrados todavia.');\n    saveProductsToFile();\n}\nfunction removeProduct(){\n    if(products.length > 0){\n        readline.question('\\n¿Cuál es el nombre del producto que quiere eliminar? ', nameProduct => {\n            for(let i of products){\n                if(i.name === nameProduct){\n                    found = true;\n                    products.splice(products.indexOf(i), 1);\n                    console.log('\\nProducto eliminado con exito!');\n                    saveProductsToFile();\n                    return;\n                }\n            }\n            console.log('\\nProducto no encontrado');\n            saveProductsToFile();\n        })\n    } else{\n        console.log('\\nNo hay productos registrados todavia.');\n        saveProductsToFile();\n    }\n}\nfunction showProducts(){\n    if(products.length > 0){\n        const content = products.map(i => `Name: ${i.name} | Quantity Sold: ${i.sold} | Unit Price: $${i.unitPrice}`).join('\\n');\n        console.log(content);\n    } else{\n        console.log('\\nNo hay productos registrados todavia.');\n    }\n    saveProductsToFile();\n}\nfunction totalSales(){\n    let suma = 0;\n    if(products.length > 0){\n        for(let i of products){\n            suma += i.sold * i.unitPrice;\n        }\n        console.log('\\nHay una venta total de $',suma);\n    } else console.log('\\nNo hay productos todavia');\n    saveProductsToFile();\n}\nfunction productsSales(){\n    if(products.length > 0){\n        readline.question('\\n¿De que producto deseas ver la venta? ', nameProduct => {\n            let suma = 0;\n            for(let i of products){\n                if(i.name === nameProduct){\n                    suma = i.sold * i.unitPrice;\n                    console.log(`${nameProduct} recaudó en total $${suma}`);\n                    saveProductsToFile();\n                    return;\n                }\n            }\n            console.log('\\nProducto no encontrado');\n        })\n    } else console.log('\\nNo hay productos todavia');\n    saveProductsToFile();\n}\nfunction saveProductsToFile(){\n    const content = products.map(i => `Name: ${i.name} | Quantity Sold: ${i.sold} | Unit Price: $${i.unitPrice}`).join('\\n');\n    fs.writeFileSync(salesFile, content);\n    readline.question('\\nPrecione ENTER para continuar...', tecla => {\n        if(tecla === '') management();\n            else saveProductsToFile();\n    })\n}\nfunction management(){\n    console.clear();\n    console.log(`\n\\t\\t/// INGRESE UNA OPCIÓN ///\\n\n1. Añadir producto.\n2. Consultar datos de productos.\n3. Actualizar datos de productos.\n4. Eliminar productos.\n5. Ver productos.\n6. Ver total.\n7. Ver total de X producto.\n8. Salir ( Elimina el archivo )`);\n    readline.question('\\nIngrese una opción: ', op => {\n        switch (op){\n            case '1':\n                addProduct();\n                break;\n            case '2':\n                consult();\n                break;\n            case '3':\n                update();\n                break;\n            case '4':\n                removeProduct();\n                break;\n            case '5':\n                showProducts();\n                break;\n            case '6':\n                totalSales();\n                break;\n            case '7':\n                productsSales();\n                break;\n            case '8':\n                fs.unlinkSync(salesFile);\n                readline.close();\n                return;\n            default:\n                console.log('\\nOpción no valida');\n                saveProductsToFile();\n        }\n    })\n}\nmanagement();"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n_______________________________________\n#11 MANEJO DE FICHEROS\n---------------------------------------\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un\n * archivo .txt.\n * - Cada producto se guarda en una línea del arhivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n*/\n\n// ________________________________________________________\nconst fs = require(\"fs/promises\");\nconst path = require(\"path\");\n\nclass File {\n    constructor(filePath) {\n        this._path = filePath;\n    }\n\n    async writeLine(line) {\n        try {\n            await fs.appendFile(this._path, line + \"\\n\");\n        } catch (error) {\n            console.error(\"Error -> writeLine ->\", error.message);\n        }\n    }\n\n    async writeLines(lines) {\n        try {\n            await fs.writeFile(this._path, lines.join(\"\\n\"));\n        } catch (error) {\n            console.error(\"Error -> writeLines ->\", error.message);\n        }\n    }\n\n    async readLine() {\n        try {\n            const data = await fs.readFile(this._path, \"utf-8\");\n            const lines = data.split(\"\\n\").filter(Boolean);\n            return lines[lines.length - 1] || null;\n        } catch (error) {\n            console.error(\"Error -> readLine ->\", error.message);\n            return null;\n        }\n    }\n\n    async readLines() {\n        try {\n            const data = await fs.readFile(this._path, \"utf-8\");\n            return [...data.split(\"\\n\").filter(Boolean)];\n        } catch (error) {\n            console.error(\"Error -> readLines ->\", error.message);\n            return [];\n        }\n    }\n\n    async deleteFile() {\n        try {\n            await fs.unlink(this._path);\n            console.log(`${this._path} -> eliminado.`);\n        } catch (error) {\n            console.error(\"Error -> deleteFile ->\", error.message);\n        }\n    }\n\n    async printAll() {\n        try {\n            const data = await fs.readFile(this._path, \"utf-8\");\n            console.log(data);\n        } catch (error) {\n            console.error(\"Error -> printAll ->\", error.message);\n        }\n    }\n\n    async queryFile(query) {\n        try {\n            const lines = await this.readLines();\n            for (let i = 0; i < lines.length; i++) {\n                const line = lines[i];\n                const productName = line.split(\",\")[0].trim();\n                if (productName === `[${query}]`) {\n                    console.log(line);\n                    return i;\n                }\n            }\n            console.log(\"No existe.\");\n            return null;\n        } catch (error) {\n            console.error(\"Error -> queryFile ->\", error.message);\n            return null;\n        }\n    }\n}\n\n// __________________________\nasync function ejmp() {\n    const user = new File(path.resolve(\"kenysdev.txt\"));\n    await user.writeLine(\"Name: ken\");\n    await user.writeLine(\"Age: 121\");\n    await user.writeLine(\"PL: JS\");\n    await user.printAll();\n    const name = await user.readLine()\n    console.log(name);\n    await user.deleteFile();\n}\n\n// ________________________________________________________\n// DIFICULTAD EXTRA\n\nconst sale = new File(path.resolve(\"sale_mgt.txt\"));\n\nasync function addProduct(product = null, qty = null, price = null) {\n    while (true) {\n        if (!product || !/^[a-zA-Z]+$/.test(product)) {\n            console.log(\"Debe ingresar un nombre de producto válido.\");\n            product = await Input(\"Producto: \");\n        } else if (!qty || !/^[0-9]+$/.test(qty)) {\n            console.log(\"Debe ingresar una cantidad válida.\");\n            qty = await Input(\"Cantidad: \");\n        } else if (!price || isNaN(parseFloat(price))) {\n            console.log(\"Debe ingresar un precio válido.\");\n            price = await Input(\"Precio: \");\n        } else {\n            const line = `[${product}], [${qty}], [${price}]`;\n            await sale.writeLine(line);\n            console.log(\"\\nGuardado.\");\n            return;\n        }\n    }\n}\n\nasync function queryProduct(query = \"\") {\n    if (!query) {\n        query = await Input(\"\\nConsultar Producto.\\nNombre: \");\n    }\n    await sale.queryFile(query);\n}\n\nasync function deleteProduct(query = \"\") {\n    if (!query) {\n        query = await Input(\"\\nEliminar Producto.\\nNombre: \");\n    }\n    const lineIndex = await sale.queryFile(query);\n    if (lineIndex !== null) {\n        const lines = await sale.readLines();\n        lines.splice(lineIndex, 1);\n        lines.push('')\n        await sale.writeLines(lines);\n        console.log(\"Producto eliminado\");\n    }\n}\n\nasync function updateProduct(query = \"\") {\n    if (!query) {\n        query = await Input(\"\\nEditar Producto.\\nNombre: \");\n    }\n    const lineIndex = await sale.queryFile(query);\n    if (lineIndex !== null) {\n        const lines = await sale.readLines();\n        console.log(\"Ingrese los nuevos datos del producto:\");\n        await addProduct();\n        lines[lineIndex] = await sale.readLine();\n        lines.push('')\n        await sale.writeLines(lines);\n    }\n}\n\nasync function invoice() {\n    console.log(\"\\nFactura\\n-------------------------\");\n    const lines = await sale.readLines();\n    let totalAmount = 0;\n\n    for (const line of lines) {\n        const [product, qty, price] = line.split(\",\").map(item => item.trim().replace(/\\[|\\]/g, \"\"));\n        const subTotal = parseInt(qty) * parseFloat(price);\n        console.log(`${line} -> $${subTotal.toFixed(2)}`);\n        totalAmount += subTotal;\n    }\n\n    console.log(\"\\nMonto Total -> $\" + totalAmount.toFixed(2));\n}\n\n// __________________________\nconst menu = (`\n        Gestión de Ventas:\n╔═════════════════════════════════╗\n║ 1. Agregar        4. Editar     ║  \n║ 2. Consultar      5. Facturar   ║\n║ 3. Eliminar       6. Salir      ║\n╚═════════════════════════════════╝\n`);\n\nconst readline = require(\"readline\");\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nfunction Input(query) {\n    return new Promise(resolve => rl.question(query, resolve));\n}\n\n(async () => {\n    await ejmp();\n    while (true) {\n        console.log(menu)\n        const option = await Input(\"\\nOpción: \");\n        switch (option) {\n            case \"1\":\n                await addProduct();\n                break;\n            case \"2\":\n                await queryProduct();\n                break;\n            case \"3\":\n                await deleteProduct();\n                break;\n            case \"4\":\n                await updateProduct();\n                break;\n            case \"5\":\n                await invoice();\n                break;\n            case \"6\":\n                console.log(\"Adiós\");\n                await sale.deleteFile();\n                rl.close();\n                return;\n            default:\n                console.log(\"Seleccione una opción entre 1 y 6.\");\n        }\n    }\n})();\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/javascript/nlarrea.js",
    "content": "/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n * \n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n * archivo .txt.\n * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n */\n\n\nconst fs = require('fs');\n\nlet filePath = 'nlarrea.txt';\nconst data = [\n    'Name: Naia',\n    'Age: 25',\n    'Favorite programming language: JavaScript'\n];\n\n// Write data to the file\nfs.writeFileSync(filePath, data.join('\\n'));\nconsole.log('The file has been written successfully!');\n\n// Read the file and print the content\nconst readData = fs.readFileSync(filePath, 'utf-8');\nconsole.log('\\nPrinting read data:');\nconsole.log(readData);\n\n// Remove the file\nfs.unlinkSync(filePath);\nconsole.log('\\nThe file has been removed.');\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n * archivo .txt.\n * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n */\n\n\nconst readline = require('readline');\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n})\n\nfilePath = 'sales.txt';\n\nfunction askOption(options) {\n    console.log('\\nMENU');\n    for (let i = 0; i < options.length; i++) {\n        console.log(`${i}. ${options[i]}`);\n    }\n}\n\n\nfunction run() {\n    const options = [\n        'Exit',\n        'Add products',\n        'See single product',\n        'See all products',\n        'Update products',\n        'Remove products',\n        'Calculate total sales',\n        'Calculate sales by product'\n    ];\n\n    askOption(options);\n    \n    rl.question('What do you want to do?\\n> ', option => {\n        try {\n            // Check if the option is valid\n            if (isNaN(option)) {\n                throw new Error('The selected option must be a number.');\n            }\n            \n            option = parseInt(option);\n            \n            if (option < 0 || option > options.length - 1) {\n                throw new Error(`Chosen option must be a number between 0-${len(options) - 1}!`)\n            }\n\n            // Run\n            console.log('\\nChosen option:', options[option], '\\n');\n    \n            if (option === 0) {\n                // EXIT\n\n                rl.close();\n                fs.unlinkSync(filePath);\n                return;\n\n            } else if (option === 1) {\n                // ADD PRODUCTS\n\n                rl.question('Product name:\\n > ', productName => {\n                    rl.question('Amount sold:\\n > ', amountSold => {\n                        amountSold = parseInt(amountSold);\n                        if (isNaN(amountSold)) {\n                            throw new Error('Amount Sold must be a number.')\n                        }\n\n                        rl.question('Price:\\n > ', price => {\n                            price = parseFloat(price);\n                            if (isNaN(price)) {\n                                throw new Error('Price must be a number.')\n                            }\n                            \n                            const newProduct = `${productName}, ${amountSold}, ${price}\\n`;\n                            fs.appendFileSync(filePath, newProduct);\n\n                            run();\n                        });\n                    });\n                });\n\n            } else if (option === 2) {\n                // SEE SINGLE PRODUCT\n\n                rl.question('Product name:\\n > ', productName => {\n                    const products = fs.readFileSync(filePath, 'utf-8').split('\\n');\n\n                    for (let productData of products) {\n                        const name = productData.split(', ')[0].trim();\n\n                        if (name === productName.trim()) {\n                            console.log('\\n', productData);\n                        }\n                    }\n\n                    run();\n                });\n            } else if (option === 3) {\n                // SEE ALL PRODUCTS\n\n                console.log(fs.readFileSync(filePath, 'utf-8'));\n                run();\n\n            } else if (option === 4) {\n                // UPDATE PRODUCT\n\n                rl.question('Product name:\\n > ', productName => {\n                    rl.question('New amount sold:\\n > ', newAmount => {\n                        newAmount = parseInt(newAmount);\n                        if (isNaN(newAmount)) {\n                            throw new Error('Amount Sold must be a number.')\n                        }\n\n                        rl.question('New price:\\n > ', newPrice => {\n                            newPrice = parseFloat(newPrice);\n                            if (isNaN(newPrice)) {\n                                throw new Error('Price must be a number.')\n                            }\n\n                            const products = fs.readFileSync(filePath, 'utf-8').split('\\n');\n                            fs.unlinkSync(filePath)\n                            for (let productData of products) {\n                                const name = productData.split(', ')[0].trim();\n\n                                if (name === productName.trim()) {\n                                    const updatedData = `${productName}, ${newAmount}, ${newPrice}\\n`\n                                    fs.appendFileSync(filePath, updatedData);\n                                } else {\n                                    fs.appendFileSync(filePath, `${productData.trim()}\\n`);\n                                }\n                            }\n\n                            run();\n                        });\n                    });\n                });\n\n            } else if (option === 5) {\n                // REMOVE PRODUCT\n\n                rl.question('Product name:\\n > ', productName => {\n                    const products = fs.readFileSync(filePath, 'utf-8').split('\\n');\n                    \n                    fs.unlinkSync(filePath);\n                    for (let productData of products) {\n                        const name = productData.split(', ')[0].trim();\n\n                        if (name !== productName.trim()) {\n                            fs.appendFileSync(filePath, `${productData.trim()}\\n`);\n                        }\n                    }\n\n                    run();\n                });\n            } else if (option === 6) {\n                // CALCULATE TOTAL SALES\n\n                const products = fs.readFileSync(filePath, 'utf-8').split('\\n');\n\n                let sales = 0;\n                for (let productData of products) {\n                    const [_, amount, price] = productData.split(', ');\n\n                    if (amount !== undefined && price !== undefined) {\n                        sales += parseInt(amount) * parseFloat(price);\n                    }\n                }\n\n                console.log('Total sales:', sales);\n\n                run();\n            } else if (option === 7) {\n                // CALCULATE SINGLE PRODUCT'S SALES\n\n                rl.question('Product name:\\n > ', productName => {\n                    const products = fs.readFileSync(filePath, 'utf-8').split('\\n');\n\n                    for (let productsData of products) {\n                        const [name, amount, price] = productsData.split(', ');\n\n                        if (name === productName.trim()) {\n                            console.log('Product sales:', parseInt(amount) * parseFloat(price));\n                            break;\n                        }\n                    }\n\n                    run();\n                });\n            } else {\n\n            }\n        } catch (error) {\n            console.error(error);\n\n            rl.question('\\nPress any KEY to continue.', () => {run()});\n        }\n    });\n}\n\nrun();"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/javascript/ocram1304.js",
    "content": "function dividir(num1,num2){\n\n  if(num2 === 0){\n    throw new Error(\"No se puede dividir entre cero\");\n  }\n  else{\n    return num1/num2;\n  }\n \n}\nfunction Probar(n1,n2){\n    try {\n        dividir(n1,n2);\n        \n    } catch (error) {\n        console.log(\"Erro:\",error);\n    }\n    finally{\n        console.log(\"Intente ingrsar un divisor distinto a 0\");\n    }\n}\nProbar(10,0);\n//Difucultad Extra\n\nfunction exepciones(us,pas){\n    if(pas.length<7){\n        throw new Error (\"La contraseña debe de tener más de 7 caracteres\");\n    }\n    else if(typeof us !== 'string'){\n        throw new Error(\"Solo se permiten caracteres\");\n    }\n    else if(us === \"\" || pas === \"\"){\n        throw new Error (\"Campos vacios\");\n    }\n\n}\nfunction Comprobar(user, password){\n try {\n    exepciones(user,password);\n    console.log(\"No ocurrienron exepciones\",user,password);\n    \n } catch (error) {\n    confirm.log (\"Error\", error);\n }\n finally{\n\n    console.log(\"Ingrese  los datos nuevamente\");\n }\n\n\n}\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/javascript/parababire.js",
    "content": "const { File } = require('buffer');\nconst { log } = require('console');\nconst fs = require('fs');\nconst readline = require('readline');\nconst userName = \"parababire\";\nconst fileName = `${userName}.txt`;\nconst fileContent = \"Nombre: Ángel Narváez.\\nEdad: 44 años.\\nLenguaje de programación: Javascript.\"\n\nfs.open(fileName, \"w\", (err, fd) => {\n  if (err) throw err;\n  fs.appendFile(fileName, fileContent, (err) => {\n    if (err) throw err;\n    fs.readFile(fileName, \"utf8\", (err, data) => {\n      if (err) throw err;\n      console.log(data);\n    })\n    console.log(\"Datos agregados\");\n    const borrado = () => {\n      fs.unlink(fileName, err => {\n        if (err) throw err;\n        console.log(\"Archivo borrado\");\n      });\n      rl.close();\n    };\n    setTimeout(borrado, 5000);\n  });\n  console.log(\"archivo abierto\");\n});\n\n//Extra\nlet rl = readline.createInterface(process.stdin, process.stdout);\n\nconst leerArchivo = () => {\n  try {\n    return fs.readFileSync(fileName, \"utf8\").split(\"\\n\");\n  } catch (error) {\n    console.log(\"Archivo no encontrado\");\n    return [];\n  }\n}\n\nconst crearProducto = () => {\n  rl.question(\"Nombre del producto: \", nombre => {\n    rl.question(\"Cantidad del producto: \", cantidad => {\n      rl.question(\"Precio del producto: \", precio => {\n        const producto = `${nombre}, ${cantidad}, ${precio}\\n`;\n        fs.appendFile(fileName, `${producto}`, err => {\n          if (err) throw err;\n          console.log(\"Producto creado\");\n          menu();\n          selecionarOperacion();\n        })\n      });\n    });\n  });\n}\n\nconst consultarProducto = () => {\n  rl.question(\"Producto solicitado: \", (nombre) => {\n    const data = leerArchivo();\n      const productoBuscado = data.find((producto) => producto.split(\",\")[0] === nombre);\n      if (productoBuscado) {\n        console.log(productoBuscado);\n        menu();\n        selecionarOperacion();\n      } else {\n        console.log(\"Producto no encontrado\");\n        menu();\n        selecionarOperacion();\n      }\n  });\n}\n\nconst actualizarProducto = () => {\n  rl.question(\"Nombre del producto: \", nombre => {\n    rl.question(\"Cantidad del producto: \", cantidadNueva => {\n      rl.question(\"Precio del producto: \", precioNuevo => {\n        const inventario = leerArchivo();\n        const productosActualizados = inventario.map(linea => {\n          const [producto, cantidad, precio] = linea.split(\", \");\n          if (producto === nombre) {\n            return `${nombre}, ${cantidadNueva}, ${precioNuevo}`;\n          }\n          return linea;\n        });\n        fs.writeFile(fileName, productosActualizados.join(\"\\n\"), err => {\n          if (err) throw err;\n          console.log(\"Producto actualizado\");\n          menu();\n          selecionarOperacion();\n        });\n      });\n    });\n  });\n}\n\nconst borrarProducto = () => {\n  if (fs.existsSync(fileName)) {\n    rl.question(\"Nombre del producto: \", nombre => {\n      const inventario = leerArchivo();\n      const productosActualizados = inventario.filter(linea => {\n        const [producto, cantidad, precio] = linea.split(\", \");\n        if (producto !== nombre) {\n          return `${linea}\\n`;\n        }\n      });\n      fs.writeFile(fileName, productosActualizados.join(\"\\n\"), err => {\n        if (err) throw err;\n        console.log(\"Producto borrado\");\n        menu();\n        selecionarOperacion();\n      });\n    });\n  } else {\n    console.log(\"Archivo no existe\");\n    menu();\n    selecionarOperacion();\n  }\n}\n\nconst mostrarProductos = () => {\n  const producto = leerArchivo();\n  console.log(producto.join(\"\\n\"));\n  menu();\n  selecionarOperacion();\n}\n\nconst ventaTotal = () => {\n  const ventas = leerArchivo();\n  let total = 0;\n  ventas.forEach((venta) => {\n    const [_, cantidad, precio] = venta.split(\", \");\n    if (cantidad === undefined && precio === undefined) {\n      return 0;\n    } else {\n      total += parseInt(cantidad) * parseFloat(precio);\n    }\n  });\n  console.log(`Venta total: ${total}`);\n  menu();\n  selecionarOperacion();\n}\n\nconst ventaPorProducto = () => {\n  rl.question(\"Producto solicitado: \", (nombre) => {\n    let total = 0;\n    const data = leerArchivo();\n    const productoBuscado = data.find((producto) => producto.split(\",\")[0] === nombre);\n      if (productoBuscado) {\n        total += parseInt(productoBuscado.split(\",\")[1]) * parseFloat(productoBuscado.split(\",\")[2]);\n        console.log(`Total venta producto: ${total}`);\n        menu();\n        selecionarOperacion();\n      } else {\n        console.log(\"Producto no encontrado\");\n        menu();\n        selecionarOperacion();\n      }\n  });\n}\n\nconst cerrarPrograma = () => {\n  fs.unlink(fileName, err => {\n    if (err) console.log(err = \"Archivo no creado\");\n    console.log(\"Saliste del programa\");\n  })\n  rl.close();\n}\n\nconst menu = () => {\n  console.log(\"\");\n  console.log(\"1.- Anadir producto\");\n  console.log(\"2.- Consultar producto\");\n  console.log(\"3.- Actualizar producto\");\n  console.log(\"4.- Borrar producto\");\n  console.log(\"5.- Mostrar productos\");\n  console.log(\"6.- Calcular venta total\");\n  console.log(\"7.- Calcular venta por producto\");\n  console.log(\"8.- Salir\");\n  selecionarOperacion();\n}\n\nconst selecionarOperacion = () => {\n  rl.question(\"Elige una opción \", opcion => {\n    switch (opcion) {\n      case \"1\":\n        crearProducto();\n        break;\n      case \"2\":\n        consultarProducto();\n        break;\n      case \"3\":\n        actualizarProducto();\n        break;\n      case \"4\":\n        borrarProducto();\n        break;\n      case \"5\":\n        mostrarProductos();\n        break;\n      case \"6\":\n        ventaTotal();\n        break;\n      case \"7\":\n        ventaPorProducto();\n        break;\n      case \"8\":\n        cerrarPrograma();\n        break;\n    \n      default:\n        console.log(\"Ingresa una opción valida\");\n        menu();\n        selecionarOperacion();\n        break;\n    }\n  });\n}\nmenu();\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/javascript/pedamoci.js",
    "content": "import fs from 'fs'\nconst info = ['Pedro', 23, 'JavaScript']\n\n\nfunction archivoTxt(operation) {\n  switch (operation) {\n    case 'crearEnUnaLinea':\n      fs.writeFileSync('pedamoci.txt', `Nombre: ${info[0]}\\nEdad: ${info[1]}\\nLenguaje favorito: ${info[2]}`)\n      break;\n    case 'crearEnVariasLineas':\n      fs.writeFileSync('pedamoci.txt', `Nombre: ${info[0]}`)\n      fs.appendFileSync('pedamoci.txt', `\\nEdad: ${info[1]}`)\n      fs.appendFileSync('pedamoci.txt', `\\nLenguaje favorito: ${info[2]}`)\n      break;\n    case 'imprimir':\n      console.log(fs.readFileSync('pedamoci.txt', 'utf8'))\n      break;\n    case 'borrar':\n      fs.unlinkSync('./pedamoci.txt')\n      console.log('Archivo borrado')\n      break;\n    default:\n      break;\n  }\n}\n\narchivoTxt('crearEnUnaLinea')\narchivoTxt('imprimir')\narchivoTxt('borrar')\narchivoTxt('crearEnVariasLineas')\narchivoTxt('imprimir')\narchivoTxt('borrar')\n\n// ---------------------------------------------- DIFICULTAD EXTRA ----------------------------------------------\nimport readline from 'readline' // importe fs arriba\n\nfunction preguntar(pregunta) {\n  const rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n  })\n\n  return new Promise(resolve => {\n    rl.question(pregunta, (respuesta) => {\n      rl.close()\n      resolve(respuesta)\n    })\n  })\n}\n\nfunction actualizarDatos(info) { // borra la base de datos y la vuelve a crear con los estos actualizados\n  let i = 0\n  while (i < info.length) {\n    if (i === 0) {\n      fs.unlinkSync('./productos.txt')\n      fs.writeFileSync('productos.txt', `[${info[i++]}], [${info[i++]}], [${info[i++]}]`) // lo ordena por nombre,cantidad vendida,precio\n    } else {\n      fs.appendFileSync('productos.txt', `\\n[${info[i++]}], [${info[i++]}], [${info[i++]}]`)\n    }\n  }\n}\n\nasync function consultar() {\n  let consultar = await preguntar('Ingrese \"todo\" o el \"nombre de producto\" según lo que quiera consultar: ')\n  if (consultar === 'todo') {\n    console.log(fs.readFileSync('productos.txt', 'utf8').replaceAll('[', '').replaceAll(']', '')) // imprime toda la base de datos\n  } else {\n    let info = fs.readFileSync('productos.txt', 'utf8').replaceAll(\"\\n\", ',').replace(/[\\[\\]\\s]/g, '').split(',') // transforma el string de datos en un array con todos ellos separados\n    console.log(info)\n    if (info.includes(consultar)) {\n      index = info.indexOf(consultar) // busca el index del nombre del producto\n      console.log(`${consultar}, ${info[++index]}, ${info[++index]}`) // al index del producto se le suma 1 para saber la cantidad vendida y 2 para el precio\n    } else console.log('El producto no existe')\n  }\n}\n\nasync function actualizar() {\n  let producto = await preguntar('Ingrese el nombre del producto que desea actualizar: ')\n  let info = fs.readFileSync('productos.txt', 'utf8').replaceAll(\"\\n\", ',').replace(/[\\[\\]\\s]/g, '').split(',') // transforma el string de datos en un array con todos ellos separados\n  if (info.includes(producto)) {\n    let update\n    do {\n      update = await preguntar('Que desea actualizar precio o cantidad?' + \"\\n\")\n      if (update === 'precio') {\n        let precio = await preguntar('Ingrese el nuevo precio: ')\n        info.splice(info.indexOf(producto) + 2, 1, precio) // remplaza el precio viejo por el nuevo\n      } else if (update === 'cantidad') {\n        let cantidad = await preguntar('Ingrese la nueva cantidad de ventas: ')\n        info.splice(info.indexOf(producto) + 1, 1, cantidad)// remplaza la cantidad vendida vieja por la nueva\n      }\n    } while (update !== 'precio' && update !== 'cantidad')\n    console.log(info)\n    actualizarDatos(info)\n    console.log('Producto actualizado')\n  } else console.log('El producto no existe')\n}\n\nasync function borrar() {\n  let producto = await preguntar('Ingrese el nombre del producto que quiere borrar: ')\n  let info = fs.readFileSync('productos.txt', 'utf8').replaceAll(\"\\n\", ',').replace(/[\\[\\]\\s]/g, '').split(',') // transforma el string de datos en un array con todos ellos separados\n  if (info.includes(producto)) {\n    index = info.indexOf(producto)\n    info = info.slice(0,index).concat(info.slice(index + 3)) // al array de productos los separa en dos dejando fuera el producto que se desea eliminar y une las otras dos partes\n    actualizarDatos(info)\n  } else console.log('El producto no existe')\n}\n\nasync function calcular() {\n  let calc = await preguntar('Ingresa:' + '\\n' + 'total --> si queres calcular el total recaudado' + '\\n' + 'producto --> si queres calcular lo recaudado de un producto' + '\\n' + 'cantidad --> si queres calcular toda la cantidad vendida' + \"\\n\")\n  let result = 0\n  let info = fs.readFileSync('productos.txt', 'utf8').replaceAll(\"\\n\", ',').replace(/[\\[\\]\\s]/g, '').split(',') // transforma el string de datos en un array con todos ellos separados\n  if (calc === 'total') {\n    for (let i = 4; i < info.length; i++) { // empieza en 4 ya que los primero 3 valores son palabras y el cuarto es el nombre del primer producto\n      result = result + (parseInt(info[i]) * parseInt(info[++i]))\n      ++i\n    }\n    console.log(`El total recaudado es de: $${result}`)\n  } else if (calc === 'producto') {\n    let producto = await preguntar('Ingrese el nombre del producto: ')\n    if (info.includes(producto)) {\n      let index = info.indexOf(producto)\n      console.log(`Lo recaudado de ${producto} es $${parseInt(info[++index]) * parseInt(info[++index])}`)\n    } else {\n      console.log('El producto no existe')\n    }\n  } else if (calc === 'cantidad') {\n    for (let i = 4; i < info.length; i++) { // empieza en 4 ya que los primero 3 valores son palabras y el cuarto es el nombre del primer producto\n      result = result + parseInt(info[i])\n      i = i + 2\n    }\n    console.log(`Se han vendido ${result} productos`)\n  }\n}\n\nasync function program(operacion) {\n  switch (operacion) {\n    case 'añadir':\n      let addProducto = await preguntar('Ingrese el nombre del producto: ')\n      let addCantidadVendida = await preguntar('Ingrese la cantidad de ventas del producto: ')\n      let addPrecio = await preguntar('Ingrese el precio del producto: ')\n      fs.appendFileSync('productos.txt', `\\n[${addProducto}], [${addCantidadVendida}], [${addPrecio}]`)\n      console.log('El pruducto se ha añadido')\n      break;\n    case 'consultar':\n      await consultar()\n    break;\n    case 'actualizar':\n      await actualizar()\n      break;\n    case 'borrar':\n      await borrar()\n      break;\n    case 'calcular':\n      await calcular()\n      break;\n    case 'salir':\n      fs.unlinkSync('./productos.txt')\n      break;\n    default:\n      console.log('La operacion no existe')\n      break;\n  }\n}\n\nasync function start() {\n  fs.writeFileSync('productos.txt', `[Producto], [Cantidad-Vendida], [Precio]`)\n  let operacion\n  do {\n    operacion = await preguntar('Que operación desea realizar? (añadir, consultar, actualizar, borrar, calcular, salir)' + \"\\n\")\n    await program(operacion)\n  } while (operacion !== 'salir')\n}\n\nstart()"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/javascript/qwik-zgheib.js",
    "content": "/* you need install package readline-sync */\nimport { writeFile, readFile, unlink } from \"fs\";\nimport readline from \"readline-sync\";\n\n/* -- exercise */\nconst createFile = (fileName, content) => {\n  writeFile(fileName, content, (err) => {\n    if (err) {\n      console.error(\"Error writing file:\", err);\n      return;\n    }\n    console.log(\"File created successfully!\");\n  });\n};\n\nconst readFileContent = (fileName) => {\n  readFile(fileName, \"utf8\", (err, data) => {\n    if (err) {\n      console.error(\"Error reading file:\", err);\n      return;\n    }\n    console.log(\"File content:\", data);\n  });\n};\n\nconst deleteFile = (fileName) => {\n  unlink(fileName, (err) => {\n    if (err) {\n      console.error(\"Error deleting file:\", err);\n      return;\n    }\n    console.log(\"File deleted successfully!\");\n  });\n};\n\nconst githubUsername = \"qwik-zgheib\";\n\nconst content = `Name: Qwik Zgheib\\nAge: 22\\nFavorite Programming Language: JavaScript`;\n\nconst fileName = `${githubUsername}.txt`;\n\ncreateFile(fileName, content);\nreadFileContent(fileName);\ndeleteFile(fileName);\n\n/* -- extra challenge */\nimport fs from \"fs\";\nimport path from \"path\";\n\nconst filePath = path.join(process.cwd(), \"sales.txt\");\n\nconst SalesManager = {\n  addProduct: () => {\n    const name = readline.question(\"Enter product name: \");\n    const quantity = readline.questionInt(\"Enter quantity sold: \");\n    const price = readline.questionFloat(\"Enter price: \");\n\n    const productLine = `${name}, ${quantity}, ${price}\\n`;\n    fs.appendFileSync(filePath, productLine);\n    console.log(\"Product added.\");\n  },\n\n  viewProducts: () => {\n    if (!fs.existsSync(filePath)) {\n      console.log(\"No products found.\");\n      return;\n    }\n    const data = fs.readFileSync(filePath, \"utf8\");\n    console.log(\"Current Products:\\n\" + data);\n  },\n\n  updateProduct: () => {\n    if (!fs.existsSync(filePath)) {\n      console.log(\"No products to update.\");\n      return;\n    }\n    const data = fs.readFileSync(filePath, \"utf8\");\n    const products = data.split(\"\\n\").filter((line) => line.trim() !== \"\");\n    const name = readline.question(\"Enter product name to update: \");\n\n    const productIndex = products.findIndex((line) => line.split(\", \")[0] === name);\n    if (productIndex !== -1) {\n      const quantity = readline.questionInt(\"Enter new quantity sold: \");\n      const price = readline.questionFloat(\"Enter new price: \");\n      products[productIndex] = `${name}, ${quantity}, ${price}`;\n      fs.writeFileSync(filePath, products.join(\"\\n\") + \"\\n\");\n      console.log(\"Product updated.\");\n    } else {\n      console.log(\"Product not found.\");\n    }\n  },\n\n  deleteProduct: () => {\n    if (!fs.existsSync(filePath)) {\n      console.log(\"No products to delete.\");\n      return;\n    }\n    const data = fs.readFileSync(filePath, \"utf8\");\n    const products = data.split(\"\\n\").filter((line) => line.trim() !== \"\");\n    const name = readline.question(\"Enter product name to delete: \");\n\n    const newProducts = products.filter((line) => line.split(\", \")[0] !== name);\n    fs.writeFileSync(filePath, newProducts.join(\"\\n\") + \"\\n\");\n    console.log(\"Product deleted.\");\n  },\n\n  calculateTotalSales: () => {\n    if (!fs.existsSync(filePath)) {\n      console.log(\"No sales data found.\");\n      return;\n    }\n    const data = fs.readFileSync(filePath, \"utf8\");\n    const products = data.split(\"\\n\").filter((line) => line.trim() !== \"\");\n\n    let totalSales = 0;\n    products.forEach((line) => {\n      const [, quantity, price] = line.split(\", \");\n      totalSales += parseInt(quantity) * parseFloat(price);\n    });\n    console.log(\"Total Sales: $\" + totalSales.toFixed(2));\n  },\n\n  calculateSalesByProduct: () => {\n    if (!fs.existsSync(filePath)) {\n      console.log(\"No sales data found.\");\n      return;\n    }\n    const data = fs.readFileSync(filePath, \"utf8\");\n    const products = data.split(\"\\n\").filter((line) => line.trim() !== \"\");\n\n    const salesByProduct = {};\n    products.forEach((line) => {\n      const [name, quantity, price] = line.split(\", \");\n      if (!salesByProduct[name]) {\n        salesByProduct[name] = 0;\n      }\n      salesByProduct[name] += parseInt(quantity) * parseFloat(price);\n    });\n\n    for (const [name, total] of Object.entries(salesByProduct)) {\n      console.log(`${name}: $${total.toFixed(2)}`);\n    }\n  },\n\n  exit: () => {\n    if (fs.existsSync(filePath)) {\n      fs.unlinkSync(filePath);\n    }\n    console.log(\"Exiting and deleting sales file.\");\n    process.exit();\n  },\n};\n\nconst mainMenu = () => {\n  while (true) {\n    console.log(\n      \"\\n1. Add Product\\n2. View Products\\n3. Update Product\\n4. Delete Product\\n5. Calculate Total Sales\\n6. Calculate Sales by Product\\n7. Exit\"\n    );\n\n    let choice = readline.questionInt(\"Enter your choice: \");\n\n    while (choice < 1 || choice > 7) {\n      console.log(\"Invalid choice. Please try again.\");\n      choice = readline.questionInt(\"Enter your choice: \");\n    }\n    if (choice === 1) SalesManager.addProduct();\n    if (choice === 2) SalesManager.viewProducts();\n    if (choice === 3) SalesManager.updateProduct();\n    if (choice === 4) SalesManager.deleteProduct();\n    if (choice === 5) SalesManager.calculateTotalSales();\n    if (choice === 6) SalesManager.calculateSalesByProduct();\n    if (choice === 7) SalesManager.exit();\n  }\n};\n\nmainMenu();\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/javascript/raulG91.js",
    "content": "\nconst fs = require('fs').promises;\nconst prompt = require(\"prompt-sync\")()\nconst path = require('path')\n\nasync function createFile(){\n    let current_path = path.join(__dirname,\"raulG91.txt\");\n    let content = \"Raul\\n33\\nJavascript\";\n    await fs.writeFile(current_path,content);\n    await fs.unlink(current_path)\n\n}\n\ncreateFile();\n\nlet finish = false;\nconst  sales_file = path.join(__dirname,\"sales.txt\");\n\nasync function addProduct(name,quantity,price){\n\n    let information = `${name},${quantity},${price}\\n`;\n    await fs.appendFile(sales_file,information);\n    menu();\n\n}\nasync function checkProduct(name){\n\n    let data = await fs.readFile(sales_file);\n    data = String(data);\n    let products = data.split(\"\\n\");\n    let product = products.find((product)=>product.split(\",\")[0] == name);\n    if(product){\n        console.log(product);\n    }\n    else{\n        console.log(\"Producto no existe\")\n    }\n    menu();\n}\n\nasync function deleteProduct(name){\n\n    let data = await fs.readFile(sales_file);\n    data = String(data);\n    let products = data.split(\"\\n\");\n\n   for(let i = 0; i< products.length;i++){\n        product_name = products[i].split(\",\")[0];\n        if(product_name == name){\n            delete(products[i]);\n        }\n   }\n    let products_string = products.join(\"\\n\");\n    await fs.writeFile(sales_file,products_string);\n    menu();\n\n}\nasync function updateProduct(name,new_quantity,new_price){\n    let data = await fs.readFile(sales_file);\n    data = String(data);\n    let products = data.split(\"\\n\");\n    let found = false;\n\n    for(let i=0;i<products.length;i++){\n        product_name = products[i].split(\",\")[0];\n        if(product_name == name){\n            found = true;\n            delete(products[i]);\n            products[i] = `${product_name},${new_quantity},${new_price}`;\n        }        \n    }\n    if(found){\n        let products_string = products.join(\"\\n\")\n        await fs.writeFile(sales_file,products_string);\n    }\n    else{\n        console.log(\"Producto no existe\")\n    }\n    menu();\n\n}\nasync function getTotal(){\n\n    let data = await fs.readFile(sales_file);\n    data = String(data);\n    let products = data.split(\"\\n\");\n    let sum = 0;\n\n    for(let i=0;i<products.length;i++){\n\n        let [name,quantity,price] = products[i].split(\",\");\n        if(name){\n            \n            sum = sum + (parseInt(quantity)*parseFloat(price));\n        }\n    }\n    console.log(\"Suma total es \"+String(sum));\n    menu()\n}\nasync function getTotalProduct(name){\n    let data = await fs.readFile(sales_file);\n    data = String(data);\n    let products = data.split(\"\\n\");\n    let sum = 0;\n\n    let product = products.find((product)=>product.split(',')[0]==name);\n\n    if(product){\n        let[product_name,quantity,price] = product.split(',');\n        sum = quantity*price;\n        console.log(\"Suma product \"+product_name+\" \"+String(sum))\n    }\n    else{\n        console.log(\"Producto no encontrado\");\n    }\n   menu();\n}\n\nfunction menu(){\n\n    console.log(\"Introduzca 1 para añadir producto\");\n    console.log(\"Introduzca 2 para consultar producto\");\n    console.log(\"Introduzca 3 para actualizar producto\");\n    console.log(\"Intorduzca 4 para eliminar producto\");\n    console.log(\"Intorduzca 5 para obtener el total ventas\");\n    console.log(\"Intorduzca 6 para obtener total por producto\");\n    console.log(\"Introduzca 7 para salir\")\n\n    let input = prompt();\n    input = parseInt(input);\n    let name,quantity,price;\n    switch(input){\n\n        case 1: name = prompt(\"Introduzca nombre del producto \");\n                quantity = parseInt(prompt(\"Introduzca la cantidad \"));\n                price = parseFloat(prompt(\"Introduzca el precio \"));\n                try{\n                    addProduct(name,quantity,price);\n                }catch (e){\n                   console.log(\"Error añadiendo producto\");     \n                }\n                break;\n        case 2: name  = prompt(\"Introduzca nombre del producto \");\n                checkProduct(name);\n                break;\n        case 3: name  = prompt(\"Introduzca nombre del producto \");   \n                quantity = parseInt(prompt(\"Introduzca la nueva cantidad \"));\n                price = parseFloat(prompt(\"Introduzca el nuevo precio \"));  \n                updateProduct(name,quantity,price)\n                break;\n                \n        case 4: name = prompt(\"Introduzca nombre del producto a eliminar \");\n                deleteProduct(name);\n                break;  \n        case 5:  getTotal();\n                break;  \n        case 6: name = prompt(\"Introduzca el nombre del producto \");  \n                getTotalProduct(name);\n                break;                   \n\n        case 7: finish = true;\n                fs.unlink(sales_file);\n                break;\n        default: menu();        \n    }\n\n}\n\nmenu()"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/javascript/saicobys.js",
    "content": "const nombreUsuarioGitHub = \"SaicoBys\";\nconst fs = require(\"fs\");\nconst nombreArchivo = `${nombreUsuarioGitHub}.txt`;\n\nfs.writeFileSync(\n  nombreArchivo,\n  `Nombre: Jacob\\nEdad: 24\\nLenguaje de programacion favorito: JavaScript`\n);\n\nconst contenido = fs.readFileSync(nombreArchivo, \"utf-8\");\nconsole.log(contenido);\n\nfs.unlinkSync(nombreArchivo);\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/javascript/seandsun.js",
    "content": "/*\n<-------------- Manejo de ficheros -------------->\nPara manejar ficheros Node.js nos ofrece un módulo conocido como \"fs\" (File System) que nos permite interactuar\ncon los archivos del sistema; este módulo permite realizar procesos como crear archivos, escribir en ellos,\nleerlos, renombrarlos, hacer copias, eliminarlos, etc.\n*/\n\n// Requerimos el módulo \"fs\" de Node.js y lo guardamos en una cosntante\n\nconst fs = require('fs')\n\n// Datos para agregar al nuevo fichero llamado \"seandsun.txt\"\n\nconst datos = [\n  'Nombre: Marisol',\n  'Edad: 26',\n  'Lenguaje de programación favorito: javascript'\n]\n\n// Crear archivo \"seandsun.txt\" y escribir los datos en él\n\nfs.writeFile('seandsun.txt', datos.join('\\n'), (error) => {\n  if(error) {\n    console.log(`Error: ${error}`)\n  } else {\n    console.log('Se ha creado el archivo correctamente')\n  }\n})\n\n// Leer la información del archivo \"seandsun.txt\"\n\nfs.readFile('seandsun.txt', 'utf-8', (error, data) => {\n  if(!error) {\n    console.log(data)\n  } else {\n    console.log(`Error: ${error}`)\n  }\n})\n\n// Eliminar el archivo \"seandsun.txt\"\n\nfs.unlink('seandsun.txt', (error) => {\n  if(error) {\n    console.log(`Error: ${error}`)    \n  } else {\n    console.log('Archivo borrado exitosamente')\n  }\n})"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/javascript/tilordqwerty.js",
    "content": "/*\n* IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n*\n* EJERCICIO:\n* Desarrolla un programa capaz de crear un archivo que se llame como\n* tu usuario de GitHub y tenga la extensión .txt.\n* Añade varias líneas en ese fichero:\n* - Tu nombre.\n* - Edad.\n* - Lenguaje de programación favorito.\n* Imprime el contenido.\n* Borra el fichero.\n*\n* DIFICULTAD EXTRA (opcional):\n* Desarrolla un programa de gestión de ventas que almacena sus datos en un \n* archivo .txt.\n* - Cada producto se guarda en una línea del archivo de la siguiente manera:\n*   [nombre_producto], [cantidad_vendida], [precio].\n* - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n*   actualizar, eliminar productos y salir.\n* - También debe poseer opciones para calcular la venta total y por producto.\n* - La opción salir borra el .txt.\n*/\n\n\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar fs = require('fs')\nvar readlineSync = require('readline-sync');\n\nfs.writeFile('tilordqwerty.txt', '-Nombre: Gabriel\\n-Edad: 18\\nLenguaje favorito: JavaScript', function(err){\n    if (err){\n        return console.log(err)\n    }\n    console.log('El archivo fue creado correctamente');\n});\n\nfs.readFile('tilordqwerty.txt', 'utf8', function(err, data){\n    if (err){\n        return console.log(err)\n    }\n    console.log(data);\n});\n\nfs.unlink('tilordqwerty.txt', function(err){\n    if(err){\n        return console.log(err)\n    }\n    console.log('El archivo fue borrado')\n})\n\n// Extra\n\nconst READLINE = require('readline');\n\nfunction agregarProducto() {\n    let nombreProducto = readlineSync.question('Nombre: ')\n    let cantidadVendida = readlineSync.question('Cantidad: ')\n    let precioTotal = readlineSync.question('Precio: ')  \n    fs.appendFile('ventas.txt',  `-${nombreProducto}\\n -${cantidadVendida}\\n -${precioTotal}`, function(err){\nif (err){\n    return console.log(err);}\n});\n}\n\nfunction listarProductosVentas(){\n    fs.readFile('ventas.txt', 'utf8', function(err, data){\n      if (err){\n        return console.log(err);\n    }\n          console.log(data.toString());\n       });       \n    }\n\nfunction gestionarVentas(){\n    let selectOptions = '';\n    let opciones = \"--- BIENVENIDO --- \\n 1. Agregar producto\\n 2. Mostrar productos\\n 3. Borrar producto\\n 4. Salir\\n Escoge una opcion: \"\n    while(selectOptions !== '3'){\n        selectOptions = readlineSync.question(opciones);\n        switch(selectOptions){\n            case '1':\n                agregarProducto();\n                break;\n            case '2':\n                listarProductosVentas();\n                break;\n            case '3':\n                fs.unlink('ventas.txt', function(err){\n                    if(err){\n                        return console.log(err);\n                    }\n                    console.log('El archivo fue borrado')\n                });\n                break;\n            case '4':\n                console.log('Adios')\n                break;\n            default:\n                console.log('Opcion no valida. Intentar de nuevo.');\n                return;\n        }\n    }\n};\ngestionarVentas();\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/javascript/victor-Casta.js",
    "content": "const fs = require('fs');\nconst readline = require('readline');\n\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout\n});\n\n/*\n  * Desarrolla un programa capaz de crear un archivo que se llame como\n  * tu usuario de GitHub y tenga la extensión .txt.\n  * Añade varias líneas en ese fichero:\n  * - Tu nombre.\n  * - Edad.\n  * - Lenguaje de programación favorito.\n  * Imprime el contenido.\n  * Borra el fichero.\n*/\n\nfs.writeFile('victor-Casta.txt',\n  'Victor\\n21\\nJavascript',\n  (error) => {console.log(error)}\n)\n\nfs.readFile('victor-Casta.txt', 'utf-8', (error, data) => {\n  console.log(data)\n})\n\nfs.unlink('victor-Casta.txt', (error) => {\n  console.log(error)\n})\n\n\n/*\n  * DIFICULTAD EXTRA (opcional):\n  * Desarrolla un programa de gestión de ventas que almacena sus datos en un\n  * archivo .txt.\n  * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n  *   [nombre_producto], [cantidad_vendida], [precio].\n  * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n  *   actualizar, eliminar productos y salir.\n  * - También debe poseer opciones para calcular la venta total y por producto.\n  * - La opción salir borra el .txt.\n*/\n\nasync function getMenu() {\n  let option;\n  do {\n    console.log('1. Añadir producto');\n    console.log('2. Consultar producto');\n    console.log('3. Actualizar producto');\n    console.log('4. Eliminar producto');\n    console.log('5. Calcular venta total');\n    console.log('6. Calcular venta por producto');\n    console.log('7. Salir');\n\n    option = await question('Ingresa una opción del menú: ');\n\n    if (option === '1') {\n      await addProducts();\n    }\n    if (option === '2') {\n      await viewProducts();\n    }\n    if (option === '3') {\n      await updateProducts();\n    }\n    if (option === '4') {\n      await deleteProducts();\n    }\n    if (option === '5') {\n      await totalSales();\n    }\n    if (option === '6') {\n      await productSales();\n    }\n    if (option === '7') {\n      fs.unlinkSync('sales.txt');\n    }\n  } while (option !== '7');\n\n  rl.close();\n}\n\nfunction question(question) {\n  return new Promise((resolve) => {\n    rl.question(question, (answer) => {\n      resolve(answer);\n    });\n  });\n}\n\nasync function addProducts() {\n  const nameProduct = await question('Ingresa el nombre del producto: ');\n  const quantity = await question('Ingresa la cantidad vendida: ');\n  const price = await question('Ingresa el precio del producto: ');\n\n  const data = `${nameProduct}, ${quantity}, ${price}\\n`;\n  fs.appendFileSync('sales.txt', data, 'utf8');\n}\n\nasync function viewProducts() {\n  const userProductName = await question('Ingresa el nombre del producto: ');\n\n  const fileStream = fs.createReadStream('sales.txt');\n  const rl = readline.createInterface({\n    input: fileStream,\n    crlfDelay: Infinity\n  });\n\n  let foundProduct = false;\n\n  for await (const line of rl) {\n    const [productName, quantity, price] = line.split(', ');\n\n    if (productName === userProductName) {\n      console.log(`Nombre: ${productName}`);\n      console.log(`Cantidad: ${quantity}`);\n      console.log(`Precio: ${price}`);\n      foundProduct = true;\n      break;\n    }\n  }\n\n  if (!foundProduct) {\n    console.log('No se encontró el producto');\n  }\n}\n\nasync function updateProducts() {\n  const userNameProduct = await question('Nombre del producto: ');\n  const userQuantity = await question('Ingresa la nueva cantidad vendida: ');\n  const userPrice = await question('Ingresa el nuevo precio del producto: ');\n\n  const fileStream = fs.createReadStream('sales.txt');\n  const rl = readline.createInterface({\n    input: fileStream,\n    crlfDelay: Infinity\n  });\n\n  let updatedLines = [];\n\n  for await (const line of rl) {\n    const [productName, quantity, price] = line.split(', ');\n\n    if (productName === userNameProduct) {\n      updatedLines.push(`${userNameProduct}, ${userQuantity}, ${userPrice}`);\n    } else {\n      updatedLines.push(line);\n    }\n  }\n\n  rl.close();\n  fs.writeFileSync('sales.txt', updatedLines.join('\\n'));\n\n  console.log('Producto actualizado correctamente');\n}\n\nasync function deleteProducts() {\n  const userNameProduct = await question('Nombre del producto: ');\n\n  const fileStream = fs.createReadStream('sales.txt');\n  const rl = readline.createInterface({\n    input: fileStream,\n    crlfDelay: Infinity\n  });\n\n  let updatedLines = [];\n\n  for await (const line of rl) {\n    const [productName, quantity, price] = line.split(', ');\n\n    if (productName!== userNameProduct) {\n      updatedLines.push(line);\n    }\n  }\n\n  rl.close();\n  fs.writeFileSync('sales.txt', updatedLines.join('\\n'));\n\n  console.log('Producto eliminado correctamente');\n}\n\nasync function totalSales() {\n  const fileStream = fs.createReadStream('sales.txt');\n  const rl = readline.createInterface({\n    input: fileStream,\n    crlfDelay: Infinity\n  });\n\n  let total = 0;\n\n  for await (const line of rl) {\n    const [productName, quantity, price] = line.split(', ');\n    total += parseInt(quantity) * parseInt(price);\n  }\n\n  console.log(`El total de ventas es: ${total}`);\n  rl.close();\n}\n\nasync function productSales() {\n  const userNameProduct = await question('Nombre del producto: ');\n\n  const fileStream = fs.createReadStream('sales.txt');\n  const rl = readline.createInterface({\n    input: fileStream,\n    crlfDelay: Infinity\n  });\n\n  let foundProduct = false;\n\n  for await (const line of rl) {\n    const [productName, quantity, price] = line.split(', ');\n\n    if (productName === userNameProduct) {\n      const totalByProduct = parseInt(quantity) * parseInt(price);\n      console.log(`El total de ventas por ${userNameProduct} es: ${totalByProduct}`);\n      foundProduct = true;\n      break;\n    }\n  }\n\n  if (!foundProduct) {\n    console.log('No se encontró el producto');\n  }\n\n  rl.close();\n}\n\ngetMenu();"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/javascript/wapastorv.js",
    "content": "/* IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n * \n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n*/\n\n/*const fs = require('fs');// Importamos el módulo fs para trabajar con ficheros. \nconst fileName = 'wapastorv.txt';// Nombre del archivo que vamos a crear. \nconst content = 'Nombre: William Pastor\\nEdad: 26\\nLenguaje de programación favorito: JavaScript'; // Contenido del archivo que vamos a crear. \n\nfs.writeFile(fileName, content, (err) => { // Creamos el archivo con el contenido. \n  if (err) {\n    console.error('Error al crear el archivo:', err); // Si hay un error, lo mostramos por consola. \n    return;\n  }\n  console.log('Archivo creado correctamente con el contenido:', content);  // Si no hay errores, mostramos un mensaje de éxito.\n    fs.readFile(fileName, 'utf8', (err, data) => { // Leemos el archivo creado. \n        if (err) {\n        console.error('Error al leer el archivo:', err); // Si hay un error, lo mostramos por consola.\n        return;\n        }\n        console.log('Contenido del archivo:', data);// Si no hay errores, mostramos el contenido del archivo. \n        fs.unlink(fileName, (err) => {// Borramos el archivo creado. \n        if (err) {\n            console.error('Error al borrar el archivo:', err);\n            return;\n        }\n        console.log('Archivo borrado correctamente');\n        });\n   \n    });\n});*/\n\n/* DIFICULTAD EXTRA (opcional):\n* Desarrolla un programa de gestión de ventas que almacena sus datos en un \n* archivo .txt.\n* - Cada producto se guarda en una línea del archivo de la siguiente manera:\n*   [nombre_producto], [cantidad_vendida], [precio].\n* - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n*   actualizar, eliminar productos y salir.\n* - También debe poseer opciones para calcular la venta total y por producto.\n* - La opción salir borra el .txt.\n*/\n\n// Código extra aquí...\nconst fs = require('fs'); // Importamos el módulo fs para trabajar con ficheros.\nconst readline = require('readline'); // Importamos el módulo readline para leer la entrada por consola.\nconst rl = readline.createInterface({ // Creamos una interfaz de lectura.\n  input: process.stdin, // Establecemos la entrada estándar.\n  output: process.stdout // Establecemos la salida estándar.\n});\n\nconst fileNameVentas = 'ventas.txt'; // Nombre del archivo que vamos a crear.\nconst menu = `Menú:\n    1. Añadir producto.\n    2. Consultar productos.\n    3. Actualizar producto.\n    4. Eliminar producto.\n    5. Calcular venta total.\n    6. Calcular venta por producto.\n    7. Salir.`; // Menú de opciones.\nconst productos = []; // Array donde almacenaremos los productos\n\nfunction addProduct() { // Función para añadir un producto.\n    rl.question('Introduce el nombre del producto, la cantidad vendida y el precio (separados por comas): ', (answer) => {\n        const [nombre, cantidad, precio] = answer.split(','); // Dividimos la respuesta en un array.\n        productos.push({ nombre, cantidad: parseInt(cantidad), precio: parseFloat(precio) }); // Añadimos el producto al array.\n        rl.question('Producto añadido correctamente. Pulsa cualquier tecla para continuar.', () => showMenu());}); // Mostramos el menú.\n}\n\nfunction showProducts() { // Función para mostrar los productos.\n    console.log('Productos:');\n    productos.forEach((producto) => console.log(`${producto.nombre}, ${producto.cantidad}, ${producto.precio}`)); // Mostramos los productos.\n    rl.question('Pulsa cualquier tecla para continuar.', () => showMenu());\n}\n\nfunction updateProduct() { // Función para actualizar un producto.\n    rl.question('Introduce el nombre del producto a actualizar: ', (nombre) => {\n        const producto = productos.find((producto) => producto.nombre === nombre); // Buscamos el producto.\n        if (!producto) { // Si no existe, mostramos un mensaje de error.\n            console.log('Producto no encontrado.');\n            return rl.question('Pulsa cualquier tecla para continuar.', () => showMenu());\n        }\n        rl.question('Introduce la nueva cantidad vendida y el nuevo precio (separados por comas): ', (answer) => {\n            const [cantidad, precio] = answer.split(','); // Dividimos la respuesta en un array.\n            producto.cantidad = parseInt(cantidad); // Actualizamos la cantidad.\n            producto.precio = parseFloat(precio); // Actualizamos el precio.\n            rl.question('Producto actualizado correctamente. Pulsa cualquier tecla para continuar.', () => showMenu());\n        });\n    });\n}\n\nfunction deleteProduct() { // Función para eliminar un producto.\n    rl.question('Introduce el nombre del producto a eliminar: ', (nombre) => {\n        const index = productos.findIndex((producto) => producto.nombre === nombre); // Buscamos el índice del producto.\n        if (index === -1) { // Si no existe, mostramos un mensaje de error.\n            console.log('Producto no encontrado.');\n            return rl.question('Pulsa cualquier tecla para continuar.', () => showMenu());\n        }\n        productos.splice(index, 1); // Eliminamos el producto.\n        rl.question('Producto eliminado correctamente. Pulsa cualquier tecla para continuar.', () => showMenu());\n    });\n}\n\nfunction totalSale() { // Función para calcular la venta total.\n    const total = productos.reduce((acc, producto) => acc + producto.cantidad * producto.precio, 0); // Calculamos el total.\n    console.log(`Venta total: ${total}`); // Mostramos el total.\n    rl.question('Pulsa cualquier tecla para continuar.', () => showMenu());\n}\n\nfunction saleByProduct() { // Función para calcular la venta por producto.\n    rl.question('Introduce el nombre del producto: ', (nombre) => {\n        const producto = productos.find((producto) => producto.nombre === nombre); // Buscamos el producto.\n        if (!producto) { // Si no existe, mostramos un mensaje de error.\n            console.log('Producto no encontrado.');\n            return rl.question('Pulsa cualquier tecla para continuar.', () => showMenu());\n        }\n        console.log(`Venta por ${producto.nombre}: ${producto.cantidad * producto.precio}`); // Mostramos la venta por producto.\n        rl.question('Pulsa cualquier tecla para continuar.', () => showMenu());\n    });\n}\n\nfunction showMenu() { // Función para mostrar el menú.\n    rl.question(menu, (option) => {\n        switch (option) { // Según la opción seleccionada, llamamos a la función correspondiente.\n            case '1':\n                addProduct();\n                break;\n            case '2':\n                showProducts();\n                break;\n            case '3':\n                updateProduct();\n                break;\n            case '4':\n                deleteProduct();\n                break;\n            case '5':\n                totalSale();\n                break;\n            case '6':\n                saleByProduct();\n                break;\n            case '7':\n                fs.unlink(fileNameVentas, (err) => { // Borramos el archivo creado.\n                    if (err) {\n                        console.error('Error al borrar el archivo:', err);\n                        return;\n                    }\n                    console.log('Archivo borrado correctamente.');\n                    rl.close();\n                });\n                break;\n            default:\n                console.log('Opción no válida.'); // Si la opción no es válida, mostramos un mensaje de error.\n                showMenu();\n        }\n    });\n}\n\nfs.writeFile(fileNameVentas, '', (err) => { // Creamos el archivo.\n    if (err) {\n        console.error('Error al crear el archivo:', err);\n        return;\n    }\n    console.log('Archivo creado correctamente.');\n    showMenu();\n})\n\nrl.on('close', () => console.log('¡Hasta luego!')); // Cuando se cierra la interfaz, mostramos un mensaje\n\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/kotlin/VincentRodriguezR.kt",
    "content": "import java.io.File\nimport java.io.FileWriter\n\nclass archivos(){\n    fun creacionArchivo(){\n        //Definicion de contenido\n        val contenido = listOf(\"Nombre: Vincent Rodriguez\", \"Edad: 24\", \"Lenguaje favorito: Kotlin\")\n\n        //Definicion interna del archivo\n        val archivo = File(\"C:\\\\Users\\\\vdsro\\\\Desktop\\\\VincentRodriguezR.txt\")\n\n        //Validacion de existencia del archivo\n        if(!archivo.exists()){\n            archivo.createNewFile()\n        }\n\n        //Escribir en el archivo\n        val escritor = FileWriter(archivo)\n        contenido.forEach{escritor.write(it + \"\\n\")}\n        escritor.close()\n        println(\"Se ha creado el archivo de forma existosa\")\n\n        //Obtener contenido del archivo\n        val nuevoContenido = archivo.readLines()\n        println(\"Contenido del archivo:\")\n        nuevoContenido.forEach { println(it) }\n\n        //eliminar archivo\n        archivo.delete()\n    }\n}\n\n//Ejercicio Extra\nclass salesManager() {\n\n    var action = \"None\"\n    var file: File = File(\"C:\\\\Users\\\\vdsro\\\\Desktop\\\\ventas.txt\")\n\n    fun showMenu() {\n        if (action == \"None\") {\n            newFile()\n        } else {\n            println(\"Seleccione la opcion que desea realizar\")\n            println(\"1. Agregar producto\")\n            println(\"2. Consultar productos\")\n            println(\"3. Actualizar productos\")\n            println(\"4. Eliminar productos\")\n            println(\"5. calcular venta total\")\n            println(\"6. calcular venta por producto\")\n            println(\"7. Salir\")\n            action = readLine()!!\n            when (action.toInt()) {\n                1 -> addItem()\n                2-> getItems(\"continue\")\n                3-> updateItems()\n                4-> deleteItems()\n                5-> totalSales()\n                6-> itemSales()\n                7->{\n                    file.delete()\n                    return\n                }\n                else -> {\n                    println(\"Selecciono una opcion no valida\")\n                    showMenu()\n                }\n            }\n        }\n    }\n\n    fun newFile() {\n        if (!file.exists()) {\n            file.createNewFile()\n            action = \"with file\"\n        } else {\n            file.delete()\n            showMenu()\n        }\n        println(\"Se ha creado el archivo de forma existosa\")\n        showMenu()\n    }\n\n    fun writeItem(items: List<String>){\n        val writer = FileWriter(file)\n\n        items.forEach{ writer.write(\"$it \\n\") }\n        writer.close()\n    }\n\n    fun addItem(){\n        var content = buildContent()\n        var tempContent = content.toMutableList()\n        var tempList:MutableList<String> = mutableListOf()\n        var tempItem = \"\"\n\n        println(\"Digite el Nombre del producto\")\n        tempItem = readLine()!!\n        tempList.add(\"[$tempItem]\")\n        println(\"Digite la cantidad vendida\")\n        tempItem = readLine()!!\n        tempList.add(\"[$tempItem]\")\n        println(\"Digite el precio\")\n        tempItem = readLine()!!\n        tempList.add(\"[$tempItem]\")\n\n        tempContent.add(tempList.joinToString (\",\"))\n        writeItem(tempContent)\n\n        println(\"Se ha credo exitosamente el registro\")\n        showMenu()\n    }\n\n    fun buildContent(): MutableList<String>{\n        var preContent = file.readLines()\n        var content: MutableList<String> = preContent.toMutableList()\n        return content\n    }\n\n    fun getItems(action: String){\n        var content = buildContent()\n        if(content.size == 0){\n            println(\"No tiene registros creados, por favor cree uno nuevo\")\n            showMenu()\n        }else{\n            println(\"A continuacion se mostraran sus registros:\")\n            content.forEachIndexed{ index, value -> println(\"${index+1}. $value\") }\n        }\n        if(action == \"stop\"){\n            return\n        }else{\n            showMenu()\n        }\n\n    }\n\n    fun updateItems(){\n        var tempIndex = \"\"\n        var content = buildContent()\n        var tempAction = \"\"\n        var tempConstructor: MutableList<String> = mutableListOf()\n        var updatedItem = \"\"\n\n        getItems(\"stop\")\n\n        println(\"Por favor seleccione el numero del item que desea editar\")\n        tempIndex = readLine()!!\n        println(\"Que atributo del item desea actuializar?\")\n        println(\" 1. Nombre\")\n        println(\" 2. Cantidad vendida\")\n        println(\" 3. precio\")\n        tempAction = readLine()!!\n\n        tempConstructor = content[tempIndex.toInt()-1].split(\",\").toMutableList()\n        println(\"Digite el nuevo valor\")\n        updatedItem = readLine()!!\n        tempConstructor[tempAction.toInt()-1] = \"[$updatedItem]\"\n\n        updatedItem = tempConstructor.joinToString(\",\")\n\n        content[tempIndex.toInt()-1] = updatedItem\n\n        action = \"with File\"\n        writeItem(content)\n\n        println(\"Se ha actualizado con exito su registro\")\n\n        showMenu()\n\n    }\n\n    fun deleteItems(){\n        var content = buildContent()\n        var tempIndex = \"\"\n\n        getItems(\"stop\")\n\n        println(\"Seleccione el item que desea eliminar\")\n        tempIndex = readLine()!!\n\n        content.removeAt(tempIndex.toInt()-1)\n        writeItem(content)\n\n        println(\"Se ha eliminado el item con exito\")\n        showMenu()\n    }\n\n    fun totalSales(){\n        var content = buildContent()\n        var total = 0\n\n        for((id, value) in content.withIndex()){\n            var tempList: List<String> = listOf()\n\n            tempList = value.split(\",\").toList()\n            total += tempList[2].replace(\"[\",\"\").replace(\"]\",\"\").replace(\" \",\"\").toInt() * tempList[1].replace(\"[\",\"\").replace(\"]\",\"\").replace(\" \",\"\").toInt()\n        }\n\n        println(\"El total de las ventas de todos los productos es de $$total\")\n        showMenu()\n    }\n\n    fun itemSales(){\n        var content = buildContent()\n        var tempIndex = \"\"\n        var tempList: List<String> = listOf()\n        var total = 0\n\n        getItems(\"stop\")\n        println(\"Selecciona el numero del que deseas obtener el total vendido\")\n        tempIndex = readLine()!!\n\n        tempList = content[tempIndex.toInt()-1].split(\",\")\n        total = tempList[2].replace(\"[\",\"\").replace(\"]\",\"\").replace(\" \",\"\").toInt() * tempList[1].replace(\"[\",\"\").replace(\"]\",\"\").replace(\" \",\"\").toInt()\n        println(\"el item ${tempList[0]} tiene un total de ${tempList[1]} sumando un total de $total vendido\")\n        showMenu()\n    }\n}\n\nfun main(){\n    var inicializador = archivos()\n    inicializador.creacionArchivo()\n\n    //Ejecucion punto extra\n    var init = salesManager()\n    init.showMenu()\n}"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/kotlin/blackriper.kt",
    "content": "import java.io.File\r\nimport java.util.UUID\r\n\r\nfun writeFile(){\r\n    val contentFile=\"\"\"\r\n        Name: blackriper\r\n        Age: 29\r\n    \"\"\".trimIndent()\r\n\r\n    // crear instancia de la clase File con el path donde se guardara el fichero\r\n    val file = File(\"src/main/resources/user.txt\")\r\n    //  escribir contenido en el fichero\r\n    file.writeText(contentFile)\r\n    // leer contenido del fichero\r\n    file.forEachLine {\r\n        println(it)\r\n    }\r\n    // borrar fichero\r\n    val result= file.delete()\r\n\r\n    if (result) {\r\n        println(\"File deleted successfully\")\r\n    } else {\r\n        println(\"Failed to delete the file\")\r\n    }\r\n}\r\n\r\n// ejercicio extra\r\ndata class Product(val sku: UUID,var name: String,var cant: Int, var price: Double)\r\n\r\ninterface Store{\r\n    fun addProduct(product: Product)\r\n    fun removeProduct(name: String)\r\n    fun updateProduct(sku:UUID,product:Product)\r\n    fun showAllProducts()\r\n    fun searchProductByName(name: String):Product\r\n    fun calculateTotalSold()\r\n    fun deleteFile()\r\n}\r\n\r\n\r\n\r\nclass SoldSore:Store{\r\n    private val products= mutableListOf<Product>()\r\n    private val fileProduct=File(\"src/main/resources/products.txt\")\r\n\r\n    override fun addProduct(product: Product) {\r\n        products.add(product)\r\n        saveFile()\r\n    }\r\n\r\n    override fun removeProduct(name: String) {\r\n        val product=products.first { it.name==name }\r\n        val result=products.removeIf{it.sku==product.sku}\r\n        if (result) {\r\n            println(\"Product deleted successfully\")\r\n            saveFile()\r\n        } else {\r\n            println(\"Failed to delete the product\")\r\n        }\r\n    }\r\n\r\n    override fun updateProduct(sku: UUID, product: Product) {\r\n           products.first { it.sku == sku }.apply {\r\n               this.name = product.name\r\n               this.cant = product.cant\r\n               this.price = product.price\r\n           }\r\n           saveFile()\r\n      }\r\n\r\n    override fun showAllProducts() {\r\n        val header=\"\"\"\r\n            -----------------------\r\n            sku   name   cant  price\r\n            -----------------------\r\n        \"\"\".trimIndent()\r\n        println(header)\r\n        fileProduct.forEachLine {\r\n            println(it)\r\n        }\r\n    }\r\n\r\n    override fun searchProductByName(name: String): Product =\r\n        products.first { it.name==name }\r\n\r\n\r\n\r\n    override fun calculateTotalSold() {\r\n        val header=\"\"\"\r\n            ------------------------------------------------------------\r\n            sku               name         cant       price     Subtotal\r\n            -------------------------------------------------------------\r\n        \"\"\".trimIndent()\r\n        println(header)\r\n        products.forEach {\r\n            println(\"${it.sku} ${it.name} ${it.cant} ${it.price} ${\"%.2f\".format(it.cant*it.price)}\")\r\n        }\r\n        val total=products.sumOf { it.cant*it.price }\r\n        println(\"Total sold: $total\")\r\n    }\r\n\r\n    override fun deleteFile() {\r\n        val result=fileProduct.delete()\r\n        if (result) {\r\n            println(\"File deleted successfully\")\r\n        } else {\r\n            println(\"Failed to delete the file\")\r\n        }\r\n    }\r\n\r\n\r\n    private fun  saveFile(){\r\n        val productsContent=products.joinToString(\"\\n\"){\"${it.sku}, ${it.name}, ${it.cant} ,${it.price}\"}\r\n        fileProduct.writeText(productsContent)\r\n    }\r\n\r\n}\r\n\r\nfun oxxoStore(){\r\n   val oxxo=SoldSore()\r\n\r\n    do {\r\n        println(\"1. Add product\")\r\n        println(\"2. Remove product\")\r\n        println(\"3. Update product\")\r\n        println(\"4. Show all products\")\r\n        println(\"5. Search product by name\")\r\n        println(\"6. Calculate total sold\")\r\n        println(\"7. Exit\")\r\n        println(\"Choose an option:\")\r\n        val option = readLine()!!.toInt()\r\n        when (option) {\r\n            1 -> {\r\n                println(\"Enter name:\")\r\n                val name = readLine()!!.lowercase()\r\n                println(\"Enter cant:\")\r\n                val cant = readLine()!!.toInt()\r\n                println(\"Enter price:\")\r\n                val price = readLine()!!.toDouble()\r\n                val sku=UUID.randomUUID()\r\n                val product = Product(sku, name, cant, price)\r\n                oxxo.addProduct(product)\r\n            }\r\n\r\n            2 -> {\r\n                println(\"Enter name:\")\r\n                val name = readLine()!!.lowercase()\r\n                oxxo.removeProduct(name)\r\n            }\r\n\r\n            3 -> {\r\n                println(\"Enter name product:\")\r\n                val oldname = readLine()!!.lowercase()\r\n                val prod=oxxo.searchProductByName(oldname)\r\n\r\n                println(\"update name (${prod.name}):\")\r\n                val name = if (readLine().isNullOrEmpty()) prod.name else readLine()!!.lowercase()\r\n                println(\"update cat (${prod.cant}):\")\r\n                val cant = if (readLine().isNullOrEmpty()) prod.cant else readLine()!!.toInt()\r\n                println(\"update price (${prod.price}):\")\r\n                val price = if (readLine().isNullOrEmpty()) prod.price else readLine()!!.toDouble()\r\n                val product = Product(prod.sku, name, cant, price)\r\n                oxxo.updateProduct(prod.sku, product)\r\n            }\r\n\r\n            4 ->  oxxo.showAllProducts()\r\n\r\n             5 -> {\r\n                println(\"Enter name:\")\r\n                val name = readLine()!!.lowercase()\r\n                val product=oxxo.searchProductByName(name)\r\n                println(\"sku: ${product.sku} name: ${product.name} cant: ${product.cant} price: ${product.price}\")\r\n            }\r\n\r\n            6 ->  oxxo.calculateTotalSold()\r\n\r\n        }\r\n\r\n    } while (option != 7)\r\n\r\n    oxxo.deleteFile()\r\n}\r\n\r\n\r\n\r\n\r\nfun main() {\r\n writeFile()\r\n oxxoStore()\r\n}\r\n\r\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/kotlin/eulogioep.kt",
    "content": "import java.io.File\n\nfun main() {\n    // Nombre del archivo\n    val fileName = \"eulogioep.txt\"\n\n    // Crear el archivo y escribir la información\n    File(fileName).writeText(\n        \"\"\"\n        EulogioEP\n        41\n        Kotlin\n        \"\"\".trimIndent()\n    )\n\n    // Imprimir el contenido\n    println(\"Contenido del archivo:\")\n    File(fileName).forEachLine { println(it) }\n\n    // Borrar el archivo\n    File(fileName).delete()\n    println(\"\\nArchivo borrado.\")\n\n    // DIFICULTAD EXTRA\n    gestionVentas()\n}\n\nfun gestionVentas() {\n    val fileName = \"ventas.txt\"\n    val file = File(fileName)\n\n    while (true) {\n        println(\"\\n--- Gestión de Ventas ---\")\n        println(\"1. Añadir producto\")\n        println(\"2. Consultar productos\")\n        println(\"3. Actualizar producto\")\n        println(\"4. Eliminar producto\")\n        println(\"5. Calcular venta total\")\n        println(\"6. Calcular venta por producto\")\n        println(\"7. Salir\")\n        print(\"Seleccione una opción: \")\n\n        when (readLine()) {\n            \"1\" -> añadirProducto(file)\n            \"2\" -> consultarProductos(file)\n            \"3\" -> actualizarProducto(file)\n            \"4\" -> eliminarProducto(file)\n            \"5\" -> calcularVentaTotal(file)\n            \"6\" -> calcularVentaPorProducto(file)\n            \"7\" -> {\n                file.delete()\n                println(\"Archivo borrado. Saliendo del programa.\")\n                return\n            }\n            else -> println(\"Opción no válida.\")\n        }\n    }\n}\n\nfun añadirProducto(file: File) {\n    print(\"Nombre del producto: \")\n    val nombre = readLine() ?: return\n    print(\"Cantidad vendida: \")\n    val cantidad = readLine()?.toIntOrNull() ?: return\n    print(\"Precio: \")\n    val precio = readLine()?.toDoubleOrNull() ?: return\n\n    file.appendText(\"$nombre, $cantidad, $precio\\n\")\n    println(\"Producto añadido.\")\n}\n\nfun consultarProductos(file: File) {\n    if (!file.exists()) {\n        println(\"No hay productos registrados.\")\n        return\n    }\n    println(\"Lista de productos:\")\n    file.forEachLine { println(it) }\n}\n\nfun actualizarProducto(file: File) {\n    print(\"Nombre del producto a actualizar: \")\n    val nombre = readLine() ?: return\n\n    val tempFile = File(\"temp.txt\")\n    var encontrado = false\n\n    file.useLines { lines ->\n        lines.forEach { line ->\n            val parts = line.split(\", \")\n            if (parts[0] == nombre) {\n                encontrado = true\n                print(\"Nueva cantidad vendida: \")\n                val cantidad = readLine()?.toIntOrNull() ?: return@forEach\n                print(\"Nuevo precio: \")\n                val precio = readLine()?.toDoubleOrNull() ?: return@forEach\n                tempFile.appendText(\"$nombre, $cantidad, $precio\\n\")\n            } else {\n                tempFile.appendText(\"$line\\n\")\n            }\n        }\n    }\n\n    if (encontrado) {\n        file.delete()\n        tempFile.renameTo(file)\n        println(\"Producto actualizado.\")\n    } else {\n        tempFile.delete()\n        println(\"Producto no encontrado.\")\n    }\n}\n\nfun eliminarProducto(file: File) {\n    print(\"Nombre del producto a eliminar: \")\n    val nombre = readLine() ?: return\n\n    val tempFile = File(\"temp.txt\")\n    var eliminado = false\n\n    file.useLines { lines ->\n        lines.forEach { line ->\n            if (line.split(\", \")[0] != nombre) {\n                tempFile.appendText(\"$line\\n\")\n            } else {\n                eliminado = true\n            }\n        }\n    }\n\n    if (eliminado) {\n        file.delete()\n        tempFile.renameTo(file)\n        println(\"Producto eliminado.\")\n    } else {\n        tempFile.delete()\n        println(\"Producto no encontrado.\")\n    }\n}\n\nfun calcularVentaTotal(file: File) {\n    var total = 0.0\n    file.forEachLine { line ->\n        val parts = line.split(\", \")\n        total += parts[1].toInt() * parts[2].toDouble()\n    }\n    println(\"Venta total: $%.2f\".format(total))\n}\n\nfun calcularVentaPorProducto(file: File) {\n    file.forEachLine { line ->\n        val parts = line.split(\", \")\n        val ventaProducto = parts[1].toInt() * parts[2].toDouble()\n        println(\"${parts[0]}: $%.2f\".format(ventaProducto))\n    }\n}"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/lua/edalmava.lua",
    "content": "-- Nombre de usuario de GitHub\nlocal usuario_github = \"edalmava\"\n\n-- Crear el archivo con extensión .txt\nlocal nombre_archivo = usuario_github .. \".txt\"\n\n-- Abrir el archivo en modo escritura\nlocal archivo = io.open(nombre_archivo, \"w\")\nprint(\"Creando y abriendo archivo \" .. nombre_archivo)\n\nif not archivo then\n    print(\"Error al crear el archivo.\")\n    return\nend\n\nprint(\"Escribiendo información en el archivo...\")\n-- Escribir información en el archivo\narchivo:write(\"Edalmava\\n\")\narchivo:write(\"30\\n\")\narchivo:write(\"Lua\\n\")\n\n-- Cerrar el archivo\narchivo:close()\n\n-- Leer y mostrar el contenido del archivo\narchivo = io.open(nombre_archivo, \"r\")\nif not archivo then\n    print(\"Error al abrir el archivo para lectura.\")\n    return\nend\n\nprint(\"Contenido del archivo:\")\nfor linea in archivo:lines() do\n    print(linea)\nend\n\n-- Cerrar el archivo después de leerlo\narchivo:close()\n\n-- Borrar el archivo\nos.remove(nombre_archivo)\nprint(\"El archivo ha sido borrado.\")\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/nasm/evanz2608.s",
    "content": "; https://nasm.us\n\n; =======================================================\n; Ejercicio 11 - MANEJO DE FICHEROS\n; =======================================================\n;\n; Para manejar ficheros en ensamblador, necesitamos hacer una llamada al sistema que lo gestione por nosotros,\n; de manera que será el propio sistema el que creará, abrirá y cerrará el fichero que nosotros queramos.\n; Evidentemente, al ser código dependiente del sistema operativo, el proceso será distinto en linux, windows, mac, etc...\n; como yo estoy en linux de 64 bits, mi código está escrito para esta plataforma, y no funcionará en otros OS ni en linux de 32 bits.\n;\n; Una vez abierto el fichero, el sistema nos devolverá un file descriptor que usaremos para luego poder escribir y leer en él, y una vez\n; hemos terminado, vamos a hacer ótra llamada al sistema para que cierre el fichero.\n; Al momento de abrir un archivo, necesitámos pasarle al sistema el nombre del archivo a abrir, un integer a modo de \"flags\", que le indíca cómo debe de ser\n; abierto el fichero (abrir para sólo lectura, sólo escritura, lectura/escritura, si debe crearlo en caso de no existir, etc..) y por último, el modo (cuando\n; especificámos la flag O_CREAT, el fichero será creado si no existe, y el modo se usa para setear los permisos que tendrá el fichero nuevo. Es ignorado si el fichero\n; existe).\n;\n;   - File descriptor: https://es.wikipedia.org/wiki/Descriptor_de_archivo\n\n\nSYS_read:   equ 0\nSYS_write:  equ 1\nSYS_open:   equ 2\nSYS_close:  equ 3\nSYS_lseek:  equ 8\nSYS_exit:   equ 60\nSYS_unlink: equ 87\nSTDIN:      equ 0\nSTDOUT:     equ 1\nSTDERR:     equ 2\nFLAGS:      equ 0q1102\nMODE:       equ 0q0666\nSEEK_SET:   equ 0\nSEEK_CUR:   equ 1\nSEEK_END:   equ 2\n\n\nglobal _start\nextern printf\nextern memset\nsection .text\n\n_start:\n  call ejercicio\n\n_exit:\n  mov rax, SYS_exit\n  xor rdi, rdi\n  syscall\n\n; ========================\n; Ejercicio\n; ========================\n\nejercicio:\n  mov rax, SYS_open\n  mov rdi, filepath\n  mov rsi, FLAGS\n  mov rdx, MODE\n  syscall\n  cmp rax, 0\n  js .fail_open\n  mov qword [fd], rax\n  mov rax, SYS_write\n  mov rdi, [fd]\n  lea rsi, [content]\n  mov rdx, content_len\n  syscall\n  mov rax, SYS_lseek\n  mov rdi, [fd]\n  mov rsi, 0\n  mov rdx, 0\n  syscall\n  mov rax, SYS_read\n  mov rdi, [fd]\n  lea rsi, [read_buffer]\n  mov rdx, content_len\n  syscall\n  mov rax, SYS_close\n  mov rdi, [fd]\n  syscall\n  lea rdi, [success_msg]\n  lea rsi, [read_buffer]\n  call printf\n  jmp .done\n.fail_open:\n  lea rdi, [fail_msg]\n  lea rsi, [filepath]\n  call printf\n.done:\n  ret\n\nprintstring:\n  mov rbx, rdi\n  xor r12, r12\n.print_char:\n  cmp byte [rbx + r12], 0x00\n  je .print_done\n  mov rax, SYS_write\n  mov rdi, STDOUT\n  lea rsi, [rbx + r12]\n  mov rdx, 1\n  syscall\n  inc r12\n  jmp .print_char\n.print_done:\n  ret\n\nsection .rodata\n  filepath: db \"evanz2608.txt\", 0x00\n\n  content: db \"Franco\", 0x0A, \"31\", 0x0A, \"Ensamblador, C/C++\"\n  content_len: equ $-content\n  fail_msg: db \"Failed to open/create file [%s]\", 0x0A, 0x00\n  success_msg: db \"File content:\", 0x0A, \"%s\", 0x0A, 0x00\n  LF: db 0x0A\n\nsection .bss\n  fd: resq 1\n  read_buffer: resb content_len + 1\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/ocaml/luishendrix92.ml",
    "content": "open Printf\n\n(******************************************************************************)\n(*                                                                            *)\n(*                      File Management - Filesystem IO                       *)\n(*                                                                            *)\n(*  IO operations are sometimes harder in functional programming languages    *)\n(*  but that's not the case in OCaml. The standard library provides modules   *)\n(*  such as [In_channel] and [Out_channel] to handle input and output; the    *)\n(*  [Unix] module to interact with Unix APIs; [Sys] to communicate with the   *)\n(*  operating system; and a utility module [Filename] to make working with    *)\n(*  filenames a little less painful.                                          *)\n(*                                                                            *)\n(*  Built on top of them, libraries such as Lwt, Core, Fileutils, EIO, Riot   *)\n(*  and others provide a better interface to work with the filesystem,        *)\n(*  networking, terminal UIs, concurrency, port comms, and parallelism.       *)\n(*                                                                            *)\n(******************************************************************************)\n\nlet write_file_exercise filename =\n  let lines =\n    [ \"Name: Luis Felipe Lopez G.\"\n    ; \"Age: 31 years.\"\n    ; \"Favourite P.L: Clojure.\"\n    ]\n  in\n  (* Writing a file with the standard library is a very transparent process:\n     1. Open the output channel corresponding to the file\n     2. Print contents into it through functions such as [fprintf].\n     3. Close the channel as good measure and practise. *)\n  let oc = open_out filename in\n  printf \"Attempting to write %s...\\n\" filename;\n  Fun.protect ~finally:(fun () ->\n    (* Closing a channel is very important, this practise also applies for\n       other resource cleanup situations such as open database connections,\n       pending HTTP requests, threads and thread pools, and more. *)\n    close_out oc;\n    print_endline \"Out channel closed.\")\n  @@ fun () ->\n  List.iter (fun line -> fprintf oc \"%s\\n\" line) lines;\n  print_endline \"Successful write!\"\n;;\n\nlet read_file_exercise filename =\n  (* The first way to open a file with the standard library is to read from\n     start [0] to finish [in_channel_length] dumping the file's bytes into a\n     string with [really_input_string] (from the [In_channel] module). *)\n  begin\n    let ic = open_in filename in\n    let contents = In_channel.really_input_string ic (in_channel_length ic) in\n    close_in ic;\n    match contents with\n    | Some contents -> print_string contents\n    | None -> printf \"Reading %s failed!\\n\" filename\n  end;\n  (* The second way involves openning the input channel and reading bytes from\n     it until the reading operation (often prefixed with [input_]) raises an\n     [End_of_file] exception that needs to be handled to resume execution. *)\n  begin\n    let ic = open_in filename in\n    try\n      Fun.protect ~finally:(fun () ->\n        close_in ic;\n        print_endline \"In channel closed.\")\n      @@ fun () ->\n      while true do\n        print_endline (input_line ic)\n      done\n    with\n    | End_of_file -> print_endline \"Reached end of file.\"\n    | _ -> print_endline \"Something went wrong reading the file!\"\n  end\n;;\n\n(* There are actually more ways to read and write to files. OCaml 5.1 gave\n   us more convenience functions in the standard library to deal with file IO\n   but as things stand today, the [Core] library still offers the better\n   interface. I will use some of these functions in the next challenge! *)\n\nlet delete_file_exercise filename =\n  Sys.remove filename;\n  printf \"%s was successfully removed!\\n\" filename\n;;\n\n(******************************************************************************)\n(*                                                                            *)\n(*                        Dificultad Extra (Opcional)                         *)\n(*                                                                            *)\n(*  Desarrolla un programa de gestión de ventas que alamacena sus datos en    *)\n(*  un archivo [.txt].                                                        *)\n(*                                                                            *)\n(*  - Cada producto se gaurda en una línea del archivo de la siguiente        *)\n(*    manera: [nombre_producto, cantidad_vendida, precio].                    *)\n(*  - Siguiendo ese formato, y mediante la terminal, debe permitir añadir,    *)\n(*    consultar, actualizar, eliminar productos y salir del programa.         *)\n(*  - También debe poseer opciones para calcular la venta total y por prod.   *)\n(*  - La opción [salir] borra el archivo [.txt].                              *)\n(*                                                                            *)\n(******************************************************************************)\n\nmodule StoreDb = struct\n  open Core\n\n  type sale =\n    { product_name : string\n    ; qty_sold : int\n    ; unit_price : float\n    }\n  [@@deriving show]\n\n  let filename = \"sales.csv\"\n\n  let deserialize line =\n    let row = Stdlib.String.trim line in\n    match String.split ~on:',' (Stdlib.String.trim row) with\n    | product_name :: qty_sold :: unit_price :: _ ->\n      let qty_sold = Int.of_string qty_sold in\n      let unit_price = Float.of_string unit_price in\n      { product_name; qty_sold; unit_price }\n    | _ -> failwith \"Database row deserialization error.\"\n  ;;\n\n  let serialize { product_name; qty_sold; unit_price } =\n    sprintf \"%s,%d,%f\" product_name qty_sold unit_price\n  ;;\n\n  let create () =\n    let oc = Out_channel.create ~append:true filename in\n    Out_channel.close_no_err oc\n  ;;\n\n  let insert sale =\n    let oc = Out_channel.create ~append:true filename in\n    protect\n      ~finally:(fun () -> Out_channel.close_no_err oc)\n      ~f:(fun () -> fprintf oc \"%s\\n\" (serialize sale))\n  ;;\n\n  let get_all () =\n    let lines = In_channel.read_lines filename in\n    List.map ~f:deserialize lines\n  ;;\n\n  let get_by_name name =\n    List.find ~f:(fun sale -> equal_string name sale.product_name) @@ get_all ()\n  ;;\n\n  let delete_by_name name =\n    get_all ()\n    |> List.filter ~f:(fun sale -> Stdlib.( <> ) name sale.product_name)\n    |> List.map ~f:serialize\n    |> Out_channel.write_lines filename\n  ;;\n\n  let update_by_name ~f name =\n    let sales = get_all () in\n    let target =\n      List.find ~f:(fun sale -> equal_string name sale.product_name) sales\n    in\n    match target with\n    | Some target ->\n      List.filter\n        ~f:(fun sale -> Stdlib.( <> ) target.product_name sale.product_name)\n        sales\n      |> List.cons (f target)\n      |> List.map ~f:serialize\n      |> Out_channel.write_lines filename\n    | None -> failwith @@ sprintf \"There is no product %s to update!\" name\n  ;;\n\n  let destroy () = Stdlib.Sys.remove filename\nend\n\n(* NOTE: 12/03/2024 - I'm writing a terminal user interface library or at the\n   very least, a set of helper functions to make writing TUIs an easier and\n   beautiful experience rather than a repetitive hell. Instead, for now I'm\n   using a set of mock sales to tell a story with print statements. Once the\n   library is ready I will rewrite this and send a pull request. *)\nlet extra () =\n  let open StoreDb in\n  let print_all () =\n    List.iter (fun sale -> print_endline (show_sale sale)) @@ get_all ()\n  in\n  let mock_sales : sale list =\n    [ { product_name = \"Macbook Pro M2 14\\\" 1TB\"\n      ; qty_sold = 3\n      ; unit_price = 44_999.00\n      }\n    ; { product_name = \"Macbook air m3 15\\\" 256gb\"\n      ; qty_sold = 2\n      ; unit_price = 27_999.00\n      }\n    ; { product_name = \"iMac (Blue) M3 512GB\"\n      ; qty_sold = 5\n      ; unit_price = 39_999.00\n      }\n    ; { product_name = \"Mac Mini M2 256GB\"\n      ; qty_sold = 5\n      ; unit_price = 13_499.00\n      }\n    ; { product_name = \"Mac Studio M2 Ultra\"\n      ; qty_sold = 1\n      ; unit_price = 92_999.00\n      }\n    ; { product_name = \"Mac Pro M2 Ultra 1TB\"\n      ; qty_sold = 3\n      ; unit_price = 149_999.00\n      }\n    ]\n  in\n  create ();\n  print_endline \"Apple Store Mexico opened, they have some initial stock:\";\n  List.iter insert mock_sales;\n  print_all ();\n  print_endline\n    \"On black friday, the Macbook Pro sells like crazy, 10 more units!\";\n  update_by_name \"Macbook Pro M2 14\\\" 1TB\" ~f:(fun product ->\n    { product with qty_sold = product.qty_sold + 10 });\n  print_endline\n    \"The manager decided that the Mac Pro never existed, so he deletes it...\";\n  delete_by_name \"Mac Pro M2 Ultra 1TB\";\n  print_endline \"A new product arrives: the M3 mac mini with 512GB of RAM.\";\n  insert\n    { product_name = \"Mac Mini M3 512GB\"; qty_sold = 0; unit_price = 29_999.00 };\n  print_endline \"This is what the report looks like before closing:\";\n  print_all ();\n  let products = get_all () in\n  let total_sales =\n    List.fold_left\n      (fun total { unit_price; qty_sold; _ } ->\n        total +. (float_of_int qty_sold *. unit_price))\n      0.00\n      products\n  in\n  List.iter\n    (fun sale ->\n      printf\n        \"%s | Total sales: $%.2f MXN\\n\"\n        sale.product_name\n        (float_of_int sale.qty_sold *. sale.unit_price))\n    products;\n  printf \"Total sale for all products: $%.2f MXN.\\n\" total_sales;\n  destroy ();\n  print_endline \"The store has closed and the sales report deleted.\"\n;;\n\nlet _ =\n  let filename = \"luishendrix92.txt\" in\n  write_file_exercise filename;\n  print_newline ();\n  read_file_exercise filename;\n  print_newline ();\n  (* If I were to try read the deleted file, an exception would be raised\n     by the [read_in] function which was not properly handled.\n\n     {[\n       read_file_exercise filename\n       #> Fatal error: exception Sys_error\n       #> (\"luishendrix92.txt: No such file or directory\")\n     ]}\n  *)\n  delete_file_exercise filename;\n  print_newline ();\n  extra ()\n;;\n\n(* Output of running [dune exec reto11]\n\n   Attempting to write luishendrix92.txt...\n   Successful write!\n   Out channel closed.\n\n   Name: Luis Felipe Lopez G.\n   Age: 31 years.\n   Favourite P.L: Clojure.\n   Name: Luis Felipe Lopez G.\n   Age: 31 years.\n   Favourite P.L: Clojure.\n   In channel closed.\n   Reached end of file.\n\n   luishendrix92.txt was successfully removed!\n\n   Apple Store Mexico opened, they have some initial stock:\n   { Reto11.StoreDb.product_name = \"Macbook Pro M2 14\\\" 1TB\"; qty_sold = 3;\n     unit_price = 44999. }\n   { Reto11.StoreDb.product_name = \"Macbook air m3 15\\\" 256gb\"; qty_sold = 2;\n     unit_price = 27999. }\n   { Reto11.StoreDb.product_name = \"iMac (Blue) M3 512GB\"; qty_sold = 5;\n     unit_price = 39999. }\n   { Reto11.StoreDb.product_name = \"Mac Mini M2 256GB\"; qty_sold = 5;\n     unit_price = 13499. }\n   { Reto11.StoreDb.product_name = \"Mac Studio M2 Ultra\"; qty_sold = 1;\n     unit_price = 92999. }\n   { Reto11.StoreDb.product_name = \"Mac Pro M2 Ultra 1TB\"; qty_sold = 3;\n     unit_price = 149999. }\n   On black friday, the Macbook Pro sells like crazy, 10 more units!\n   The manager decided that the Mac Pro never existed, so he deletes it...\n   A new product arrives: the M3 mac mini with 512GB of RAM.\n   This is what the report looks like before closing:\n   { Reto11.StoreDb.product_name = \"Macbook Pro M2 14\\\" 1TB\"; qty_sold = 13;\n     unit_price = 44999. }\n   { Reto11.StoreDb.product_name = \"Macbook air m3 15\\\" 256gb\"; qty_sold = 2;\n     unit_price = 27999. }\n   { Reto11.StoreDb.product_name = \"iMac (Blue) M3 512GB\"; qty_sold = 5;\n     unit_price = 39999. }\n   { Reto11.StoreDb.product_name = \"Mac Mini M2 256GB\"; qty_sold = 5;\n     unit_price = 13499. }\n   { Reto11.StoreDb.product_name = \"Mac Studio M2 Ultra\"; qty_sold = 1;\n     unit_price = 92999. }\n   { Reto11.StoreDb.product_name = \"Mac Mini M3 512GB\"; qty_sold = 0;\n     unit_price = 29999. }\n   Macbook Pro M2 14\" 1TB | Total sales: $584987.00 MXN\n   Macbook air m3 15\" 256gb | Total sales: $55998.00 MXN\n   iMac (Blue) M3 512GB | Total sales: $199995.00 MXN\n   Mac Mini M2 256GB | Total sales: $67495.00 MXN\n   Mac Studio M2 Ultra | Total sales: $92999.00 MXN\n   Mac Mini M3 512GB | Total sales: $0.00 MXN\n   Total sale for all products: $1001474.00 MXN.\n   The store has closed and the sales report deleted. *)\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/pascal/edalmava.pas",
    "content": "program Archivos;\n\nuses Crt;\n\nvar\n    f : Text;   // Declaracion de una variable archivo de tipo texto\n    linea : String;\n\nbegin\n\n    ClrScr;\n\n    Assign (f, 'edalmava.txt');   // Asocia la variable de archivo a un nombre de archivo en disco\n    ReWrite (f);                  // Crea un nuevo archivo para operacion de escritura edalmava.txt\n\n    WriteLn (f, 'Edalmava');      // Escribir datos en el archivo de texto\n    WriteLn (f, '30');\n    WriteLn (f, 'PHP');\n\n    Reset (f);                    // Abrir archivo edalmava.txt para lectura\n\n    // Leyendo archivo edalmava.txt\n    While not eof (f) do          // leer linea a linea hasta alcanzar el final del archivo\n    begin\n        ReadLn (f, linea);\n        WriteLn (linea);          // Imprimir linea por consola o pantalla\n    end;\n\n    close (f);                    // Cierra todas las entradas y salidas al archivo f\n\n    {I+}\n    Erase (f);                    // Borra el archivo\n    {I-}\n    if IOResult = 0 then\n        WriteLn ('Se ha borrado el archivo')\n    else\n        WriteLn ('Error al borrar el archivo');\n\nend.\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/php/edalmava.php",
    "content": "<?php    \n    function reto11($archivo, $nombre, $edad, $lenguaje) {\n        echo \"Creando archivo edalmava.txt\\n\\n\";\n\n        file_put_contents($archivo, $nombre, FILE_APPEND);\n        file_put_contents($archivo, $edad, FILE_APPEND);\n        file_put_contents($archivo, $lenguaje, FILE_APPEND);\n\n        $cadena_archivo = file_get_contents($archivo);\n\n        echo \"Contenido del archivo edalmava.txt: \\n\";\n        echo $cadena_archivo;\n\n        echo \"\\n\\nEliminando el archivo edalmava.txt\";\n        unlink($archivo);\n    }\n\n    function agregar_producto($archivo) {\n        echo \"Nombre del Producto: \";\n        fscanf(STDIN, \"%s\\n\", $nombre_producto);\n        echo \"Cantidad Vendida: \";\n        fscanf(STDIN, \"%d\\n\", $cantidad_vendida);\n        echo \"Precio: \";\n        fscanf(STDIN, \"%f\\n\", $precio);\n\n        $linea = \"$nombre_producto, $cantidad_vendida, $precio\\n\";\n\n        file_put_contents($archivo, $linea, FILE_APPEND);\n    }\n\n    function consultar_producto($archivo) {        \n        $gestor = @fopen($archivo, \"r\");\n        if ($gestor) {\n            echo \"Nombre del Producto: \";\n            fscanf(STDIN, \"%s\\n\", $nombre_producto);\n            $encontrado = false;\n            while (($búfer = fgets($gestor)) !== false) {\n                list($nombre, $cantidad, $precio) = explode(\",\", $búfer);\n                if (strtolower($nombre_producto) === strtolower($nombre)) {\n                    echo \"Cantidad Vendida: $cantidad Precio: $precio\\n\";\n                    $encontrado = true;\n                    break;\n                }\n            } \n            if (!$encontrado) {\n                echo \"Producto no encontrado\\n\";\n            }            \n            fclose($gestor);\n        }\n    }\n\n    function total_ventas($archivo) {\n        $gestor = @fopen($archivo, \"r\");\n        if ($gestor) {\n            $total_ventas = 0;\n            while (($búfer = fgets($gestor)) !== false) {\n                list($nombre, $cantidad, $precio) = explode(\",\", $búfer);\n                $total_ventas += $cantidad * $precio;\n            } \n            fclose($gestor);\n\n            return $total_ventas;                      \n        }\n    }\n\n    function opcion($opcion, $archivo) {\n        switch ($opcion) {\n            case 1:\n                echo \"\\nAñadir Producto\\n\";\n                agregar_producto($archivo);\n                break;\n            case 2:\n                if (is_file($archivo)) {\n                    echo \"\\nConsultar Producto\\n\";\n                    consultar_producto($archivo);\n                } else {\n                    echo \"\\nNo se han añadido productos\\n\";\n                }\n                break;\n            case 3:\n                echo \"\\nActualizar Producto\\n\";\n                break;\n            case 4:\n                echo \"\\nEliminar Producto\\n\";\n                break;\n            case 5:\n                if (is_file($archivo)) {\n                    echo \"\\nListando Productos\\n\\n\";\n                    echo file_get_contents($archivo);\n                } else {\n                    echo \"\\nNo se han añadido productos\\n\";\n                }\n                break;\n            case 6:\n                if (is_file($archivo)) {\n                    $total_ventas =  total_ventas($archivo);\n                    echo \"\\nTotal Ventas: $total_ventas\\n\";                   \n                } else {\n                    echo \"\\nNo se han añadido productos\\n\";\n                }\n                break;\n            case 7:                \n                if (is_file($archivo)) {\n                    echo \"\\nEliminando el archivo $archivo\\n\";\n                    unlink($archivo);\n                }                \n                echo \"Saliendo\";\n                break;\n            default:\n                echo \"\\nOpción no válida\\n\";                \n        }\n    }\n\n    function menu($archivo) {\n        do {    \n            $opcion = null;\n            system('cls');\n            echo \"\\n1. Añadir Producto\\n\";\n            echo \"2. Consultar Producto\\n\";\n            echo \"3. Actualizar Producto\\n\";\n            echo \"4. Eliminar Producto\\n\";\n            echo \"5. Listar Productos\\n\";\n            echo \"6. Total de Ventas\\n\";\n            echo \"7. Salir\\n\";\n            echo \"\\nEscoja una opción: \";\n            fscanf(STDIN, \"%d\\n\", $opcion);\n            opcion($opcion, $archivo);\n        } while ($opcion != 7);\n    }\n\n    $archivo = \"edalmava.txt\";\n    $nombre = \"Edalmava\\n\";\n    $edad = \"30\\n\";\n    $lenguaje = \"PHP\";\n\n    reto11($archivo, $nombre, $edad, $lenguaje);\n\n    echo \"\\n\\n*****RETO EXTRA*****\\n\";\n\n    menu(\"ventas.txt\");\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/php/eulogioep.php",
    "content": "<?php\n// Constantes para los nombres de archivo\ndefine('FILENAME', 'info_personal.txt');\ndefine('SALES_FILENAME', 'ventas.txt');\n\n// Función principal\nfunction main() {\n    crearArchivoPersonal();\n    gestionVentas();\n}\n\n// Función para crear y manipular el archivo personal\nfunction crearArchivoPersonal() {\n    // Crear y escribir en el archivo\n    $content = \"Nombre: Juan\\nEdad: 30\\nLenguaje de programación favorito: PHP\";\n    file_put_contents(FILENAME, $content);\n    echo \"Archivo creado y escrito con éxito.\\n\";\n\n    // Leer y mostrar el contenido\n    $contenido = file_get_contents(FILENAME);\n    echo \"Contenido del archivo:\\n$contenido\\n\";\n\n    // Borrar el archivo\n    unlink(FILENAME);\n    echo \"Archivo borrado con éxito.\\n\";\n}\n\n// Función para la gestión de ventas\nfunction gestionVentas() {\n    $salir = false;\n\n    while (!$salir) {\n        echo \"\\n--- Gestión de Ventas ---\\n\";\n        echo \"1. Añadir producto\\n\";\n        echo \"2. Consultar productos\\n\";\n        echo \"3. Actualizar producto\\n\";\n        echo \"4. Eliminar producto\\n\";\n        echo \"5. Calcular venta total\\n\";\n        echo \"6. Calcular venta por producto\\n\";\n        echo \"7. Salir\\n\";\n\n        $opcion = readline(\"Seleccione una opción: \");\n\n        switch ($opcion) {\n            case '1':\n                anadirProducto();\n                break;\n            case '2':\n                consultarProductos();\n                break;\n            case '3':\n                actualizarProducto();\n                break;\n            case '4':\n                eliminarProducto();\n                break;\n            case '5':\n                calcularVentaTotal();\n                break;\n            case '6':\n                calcularVentaPorProducto();\n                break;\n            case '7':\n                $salir = true;\n                borrarArchivoVentas();\n                break;\n            default:\n                echo \"Opción no válida.\\n\";\n        }\n    }\n}\n\n// Función para añadir un producto\nfunction anadirProducto() {\n    $nombre = readline(\"Nombre del producto: \");\n    $cantidad = readline(\"Cantidad vendida: \");\n    $precio = readline(\"Precio: \");\n\n    $linea = \"$nombre, $cantidad, $precio\\n\";\n    file_put_contents(SALES_FILENAME, $linea, FILE_APPEND);\n    echo \"Producto añadido con éxito.\\n\";\n}\n\n// Función para consultar productos\nfunction consultarProductos() {\n    if (file_exists(SALES_FILENAME)) {\n        $contenido = file_get_contents(SALES_FILENAME);\n        echo \"\\nProductos:\\n$contenido\";\n    } else {\n        echo \"No hay productos registrados.\\n\";\n    }\n}\n\n// Función para actualizar un producto\nfunction actualizarProducto() {\n    $nombreActualizar = readline(\"Nombre del producto a actualizar: \");\n    $nuevaCantidad = readline(\"Nueva cantidad vendida: \");\n    $nuevoPrecio = readline(\"Nuevo precio: \");\n\n    $contenido = file(SALES_FILENAME);\n    $encontrado = false;\n\n    foreach ($contenido as $key => $linea) {\n        $datos = explode(', ', $linea);\n        if (trim($datos[0]) === $nombreActualizar) {\n            $contenido[$key] = \"$nombreActualizar, $nuevaCantidad, $nuevoPrecio\\n\";\n            $encontrado = true;\n            break;\n        }\n    }\n\n    if ($encontrado) {\n        file_put_contents(SALES_FILENAME, implode('', $contenido));\n        echo \"Producto actualizado con éxito.\\n\";\n    } else {\n        echo \"Producto no encontrado.\\n\";\n    }\n}\n\n// Función para eliminar un producto\nfunction eliminarProducto() {\n    $nombreEliminar = readline(\"Nombre del producto a eliminar: \");\n\n    $contenido = file(SALES_FILENAME);\n    $encontrado = false;\n\n    foreach ($contenido as $key => $linea) {\n        $datos = explode(', ', $linea);\n        if (trim($datos[0]) === $nombreEliminar) {\n            unset($contenido[$key]);\n            $encontrado = true;\n            break;\n        }\n    }\n\n    if ($encontrado) {\n        file_put_contents(SALES_FILENAME, implode('', $contenido));\n        echo \"Producto eliminado con éxito.\\n\";\n    } else {\n        echo \"Producto no encontrado.\\n\";\n    }\n}\n\n// Función para calcular la venta total\nfunction calcularVentaTotal() {\n    $ventaTotal = 0;\n\n    if (file_exists(SALES_FILENAME)) {\n        $contenido = file(SALES_FILENAME);\n\n        foreach ($contenido as $linea) {\n            $datos = explode(', ', $linea);\n            if (count($datos) === 3) {\n                $ventaTotal += floatval($datos[1]) * floatval($datos[2]);\n            }\n        }\n\n        echo \"Venta total: \" . number_format($ventaTotal, 2) . \"\\n\";\n    } else {\n        echo \"No hay ventas registradas.\\n\";\n    }\n}\n\n// Función para calcular la venta por producto\nfunction calcularVentaPorProducto() {\n    $nombreProducto = readline(\"Nombre del producto: \");\n    $encontrado = false;\n\n    if (file_exists(SALES_FILENAME)) {\n        $contenido = file(SALES_FILENAME);\n\n        foreach ($contenido as $linea) {\n            $datos = explode(', ', $linea);\n            if (trim($datos[0]) === $nombreProducto) {\n                $ventaProducto = floatval($datos[1]) * floatval($datos[2]);\n                echo \"Venta de $nombreProducto: \" . number_format($ventaProducto, 2) . \"\\n\";\n                $encontrado = true;\n                break;\n            }\n        }\n\n        if (!$encontrado) {\n            echo \"Producto no encontrado.\\n\";\n        }\n    } else {\n        echo \"No hay ventas registradas.\\n\";\n    }\n}\n\n// Función para borrar el archivo de ventas\nfunction borrarArchivoVentas() {\n    if (file_exists(SALES_FILENAME)) {\n        unlink(SALES_FILENAME);\n        echo \"Archivo de ventas borrado con éxito.\\n\";\n    } else {\n        echo \"El archivo de ventas no existe.\\n\";\n    }\n}\n\n// Ejecutar el programa principal\nmain();\n?>"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/php/gabrielmoris.php",
    "content": "<?php\n/*\n * IMPORTANT: You should only upload the code file as part of the exercise.\n *\n * EXERCISE:\n * Develop a program capable of creating a file named after\n * your GitHub username and has the .txt extension.\n * Add several lines to that file:\n * - Your name.\n * - Age.\n * - Favorite programming language.\n * Print the content.\n * Delete the file.\n */\n\n\nfunction file_creator($content, $name)\n{\n    $checkedName = \"\";\n\n    if (substr($name, -4) !== '.txt') {\n        $checkedName =  $name . \".txt\";\n    } else {\n        $checkedName = $name;\n    }\n\n    file_put_contents($checkedName, $content, FILE_APPEND | LOCK_EX);\n    echo \"File \" . $checkedName . \" created.\\n\";\n}\n\nfunction file_reader($name)\n{\n    $checkedName = \"\";\n    if (substr($name, -4) !== '.txt') {\n        $checkedName =  $name . \".txt\";\n    } else {\n        $checkedName = $name;\n    }\n\n    $contents = file_get_contents($checkedName);\n    echo $contents . \"\\n\";\n}\n\nfunction file_deleter($name)\n{\n    $checkedName = \"\";\n    if (substr($name, -4) !== '.txt') {\n        $checkedName =  $name . \".txt\";\n    } else {\n        $checkedName = $name;\n    }\n\n    if (file_exists($checkedName)) {\n        if (unlink($checkedName)) {\n            echo \"File \" . $checkedName . \" deleted.\\n\";\n        } else {\n            echo \"File \" . $checkedName . \" couldn't be deleted.\\n\";\n        }\n    } else {\n        echo \"File \" . $checkedName . \" doens't exist.\\n\";\n    }\n}\n\n$content = \"Name: Gabriel Moris \\nAge: 34\\nFavourite programming language: English.\";\n$fileName = 'gabrielmoris.txt';\nfile_creator($content, $fileName);\nfile_reader($fileName);\nfile_deleter($fileName);\n\n\n/* EXTRA DIFFICULTY (optional):\n * Develop a sales management program that stores its data in a\n * .txt file.\n * - Each product is saved on a line of the file in the following way:\n *   [product_name], [quantity_sold], [price].\n * - Following that format, and through terminal, it should allow adding, consulting,\n *   updating, deleting products and exiting.\n * - It should also have options to calculate the total sale and by product.\n * - The exit option deletes the .txt.\n */\n\nfunction sales_management_system()\n{\n    echo \"\n    ===== PRINTER =====\n     1.- New Document \n     2.- Read Document\n     3.- Delete Document\n     4.- Exit\n    ==================\n     \\n\";\n\n    do {\n        $selection = readline(\"Select an option\\n\");\n        switch ($selection) {\n            case 1:\n                new_document();\n                break;\n            case 2:\n                read_document();\n                break;\n            case 3:\n                delete_document();\n                break;\n            case 4:\n                echo \"\\033c\";\n                echo \"Good bye 👋 🌐\\n\";\n                exit;\n            default:\n                echo \"This option doesn't exist.\\n\";\n        }\n    } while (true);\n}\n\nfunction new_document()\n{\n    $name = readline(\"Write the name of the document without extenstion (.txt only):\\n\");\n    $content = readline(\"Write the content of the document without extenstion (.txt only):\\n\");\n    file_creator($content, $name);\n}\n\nfunction read_document()\n{\n    $name = readline(\"Write the name of the document without extenstion (.txt only):\\n\");\n    file_reader($name);\n}\n\nfunction delete_document()\n{\n    $name = readline(\"Write the name of the document without extenstion (.txt only):\\n\");\n    file_deleter($name);\n}\n\nsales_management_system();\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/php/miguelex.php",
    "content": "<?php\n\n    // Crearcion del fichero\n\n    $fichero = fopen(\"miguelex.txt\", \"w\");\n\n    // Escribir en el fichero\n\n    fwrite($fichero, \"Nombre: Miguel Angel\\n\");\n    fwrite($fichero, \"Edad: 48\\n\");\n    fwrite($fichero, \"Lenguaje favorito: PHP\\n\");\n\n    // Cerrar el fichero\n\n    fclose($fichero);\n\n    // Mostrar el contenido del fichero\n\n    echo file_get_contents(\"miguelex.txt\");\n\n    // Borrar el fichero\n\n    unlink(\"miguelex.txt\");\n\n\n    // EJERCICIO EXTRA\n\n\n    $fichero = fopen(\"ventas.txt\", \"w\");\n\n    fwrite($fichero, \"Nombre\\t\\t Cantidad\\t\\t Precio\\n\");\n\n    do {\n        system('cls');\n        echo \"\\nMenú\\n\";\n        echo \"1. Añadir venta\\n\";\n        echo \"2. Ver ventas\\n\";\n        echo \"3. Eliminar producto\\n\";\n        echo \"4. Calcular ventas totales\\n\";\n        echo \"5. Calcular ventas de un producto\\n\";\n        echo \"6. Salir\\n\";\n        echo \"Elige una opción: \";\n        $option = trim(fgets(STDIN));\n\n        switch ($option) {\n            case 1:\n                \n                echo \"Introduce el nombre del producto: \";\n                $nombre = trim(fgets(STDIN));\n                echo \"Introduce la cantidad: \";\n                $cantidad = trim(fgets(STDIN));\n                echo \"Introduce el precio: \";\n                $precio = trim(fgets(STDIN));\n\n                fwrite($fichero, \"$nombre\\t\\t $cantidad\\t\\t $precio\\n\");\n                break;\n            case 2:\n                echo file_get_contents(\"ventas.txt\");\n                break;\n            case 3:\n                echo \"Introduce el nombre del producto a borrar: \";\n                $producto_a_borrar = trim(fgets(STDIN));\n\n                $contenido = file_get_contents(\"ventas.txt\");\n\n                $lineas = explode(\"\\n\", $contenido);\n\n                foreach ($lineas as $indice => $linea) {\n                    if (strpos($linea, $producto_a_borrar) !== false) {\n                        unset($lineas[$indice]); \n                    }\n                }\n\n                file_put_contents(\"ventas.txt\", implode(\"\\n\", $lineas));\n                break;\n            case 4:\n                \n                $contenido = file_get_contents(\"ventas.txt\");\n    \n                \n                $lineas = explode(\"\\n\", $contenido);\n    \n                $total = 0;\n                \n                foreach ($lineas as $linea) {\n                    $columnas = explode(\"\\t\\t\", $linea);\n                    if (count($columnas) == 3) {\n                        $cantidad = intval(trim($columnas[1]));\n                        $precio = floatval(trim($columnas[2]));\n                        $total += $cantidad * $precio;\n                    }\n                }\n    \n                echo \"El total de ventas es: $total\\n\";\n                break;\n            case 5:\n                echo \"Introduce el nombre del producto para calcular el total de ventas: \";\n                $producto_a_buscar = trim(fgets(STDIN));\n            \n                // Leer el contenido actual del archivo\n                $contenido = file_get_contents(\"ventas.txt\");\n            \n                // Separar el contenido por líneas\n                $lineas = explode(\"\\n\", $contenido);\n            \n                $total_producto = 0;\n                // Recorrer todas las líneas y calcular el total de ventas del producto indicado\n                foreach ($lineas as $linea) {\n                    if (strpos($linea, $producto_a_buscar) !== false) {\n                        $columnas = explode(\"\\t\\t\", $linea);\n                        if (count($columnas) == 3) {\n                            $cantidad = intval(trim($columnas[1]));\n                            $precio = floatval(trim($columnas[2]));\n                            $total_producto += $cantidad * $precio;\n                        }\n                    }\n                }\n            \n                echo \"El total de ventas para el producto $producto_a_buscar es: $total_producto\\n\";\n                break;\n            default:\n                    echo \"Opción no válida\\n\";\n                    break;\n        }\n    } while ($option != 6); \n\n    unlink(\"ventas.txt\");"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/Aldroide.py",
    "content": "\"\"\" \n    Ejercicio\n    Desarrollar un programa capaz de crear un archivo con tunombre de github\n    y extensión txt\n    Añade en varias lineas:\n        * Nombre\n        * Edad\n        * Lenguaje de programación\n    Imprime el contenido\n    Borra el fichero\n\"\"\"\n\nimport os\n\nfile_name = \"aldroide.txt\"\n\nwith open(file_name, 'w') as file:\n    file.write(\"Aldo Avila\\n\")\n    file.write(\"36\\n\")\n    file.write(\"Python\")\n\nwith open(file_name, 'r') as file:\n    print(file.read())\n\nos.remove(file_name)\n\n\"\"\"\n    Dificultad Extra\n    Desarrollar un programa de gestión de ventas que almacena sus datos\n    en un archivo txt.\n        * Cada producto se fuarda en una linea del archivo de la siguiente manera:\n        * Nombre, Cantidad, precio\n        * Siguiendo ese formato, y mediante terminal debe permitir añadir, consultar\n        * actualizar, aliminar productos y salir\n    Tambien debe poseer opciones para calcular la venta total y por producto\n    la opcion salir borra el .txt.\n\"\"\"\n\nfile_name = \"Tiendita.txt\"\n\nopen(file_name, \"a\")\n\nwhile True:\n    print(\"1. Añadir producto\")\n    print(\"2. Consultar producto\")\n    print(\"3. Actualizar producto\")\n    print(\"4. Borrar producto\")\n    print(\"5. Mostrar producto\")\n    print(\"6. Calcular venta total\")\n    print(\"7. Calcular venta por producto\")\n    print(\"8. salir\")\n\n    option = input(\"Selecciona una opción: \")\n\n    match option:\n        case \"1\":\n            name = input(\"Nombre: \")\n            quantity = input(\"Cantidad: \")\n            price = input(\"Precio: \")\n            with open(file_name, \"a\") as file:\n                file.write(f\"{name}, {quantity}, {price}\\n\")\n        case \"2\":\n            name = input(\"Nombre: \")\n            with open(file_name, \"r\") as file:\n                for line in file.readlines():\n                    if line.split(\", \")[0] == name:\n                        print(line)\n                        break\n        case \"3\":\n            name = input(\"Nombre: \")\n            quantity = input(\"Cantidad: \")\n            price = input(\"Precio: \")\n            with open(file_name, \"r\") as file:\n                lines = file.readlines()\n            with open(file_name, \"w\") as file:\n                for line in lines:\n                    if line.split(\", \")[0] == name:\n                        file.write(f\"{name}, {quantity}, {price}\\n\")\n                    else:\n                        file.write(line)\n        case \"4\":\n            name = input(\"Nombre: \")\n            with open(file_name, \"r\") as file:\n                lines = file.readlines()\n            with open(file_name, \"w\") as file:\n                for line in lines:\n                    if line.split(\", \")[0] != name:\n                        file.write(line)\n        case \"5\":\n            with open(file_name, \"r\") as file:\n                print(file.read())\n        case \"6\":\n            total = 0\n            with open(file_name, \"r\") as file:\n                for line in file.readlines():\n                    components = line.split(\", \")\n                    quantity = int(components[1])\n                    price = float(components[2])\n                    total += quantity * price\n            print(total)\n        case \"7\":\n            name = input(\"Nombre: \")\n            total = 0\n            with open(file_name, \"r\") as file:\n                for line in file.readlines():\n                    components = line.split(\", \")\n                    if components[0] == name:\n                        quantity = int(components[1])\n                        price = float(components[2])\n                        total += quantity * price\n                        break\n            print(total)\n        case \"8\":\n            os.remove(file_name)\n            break\n        case _:\n            print(\"Selecciona una de las opciones disponibles.\")\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/AllanYSalazarG.py",
    "content": "\"\"\"MANEJO DE FICHEROS\"\"\"\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/BrianSilvero.py",
    "content": "import os\n\n\"\"\"\nEjercicio\n\"\"\"\n\nfile_name = \"briansilvero.txt\"\n\nwith open(file_name, \"w\") as file:\n    file.write(\"Brian Silvero\\n\" )\n    file.write(\"27\\n\")\n    file.write(\"Python\\n\")\n\nwith open(file_name, \"r\") as file:\n    print(file.read())\n\nos.remove(file_name)\n\n\"\"\"\nExtra\n\"\"\"\nfile_name = \"briansilvero_shop.txt\"\nopen(file_name,\"w\")\n\nwhile True:\n    print(\"1.Añadir producto\")\n    print(\"2.Consultar producto\")\n    print(\"3.Actualizar producto\")\n    print(\"4.Borrar producto\")\n    print(\"5.Mostrar producto\")\n    print(\"6.Calcular venta total\")\n    print(\"7.Calcular venta por producto\")\n    print(\"8.Salir\")\n    \n    \"\"\"def insertar_producto(nombre):\n        cantidad = input(\"Cantidad: \").lower()\n        precio = input(\"Precio: \").lower()\n        \"\"\"\n    \n    option = input(\"Seleccione una opcion: \").lower()\n    \n    if option == \"1\":\n        nombre = input(\"Nombre: \").lower()\n        cantidad = input(\"Cantidad: \").lower()\n        precio = input(\"Precio: \").lower()\n        with open(file_name, \"a\") as file:\n            file.write(f\"{nombre},{cantidad},{precio}\\n\")\n    elif option == \"2\":\n        name = input(\"Nombre: \")\n        with open(file_name, \"r\") as file:\n            for line in file.readlines():\n                if line.strip().split(\",\")[0] == name:\n                    print (line)\n                    break\n            else:\n                print(\"No existe este producto\")\n                break\n    elif option == \"3\":\n        nombre = input(\"Nombre: \").lower()\n        cantidad = input(\"Cantidad: \").lower()\n        precio = input(\"Precio: \").lower()\n        with open(file_name, \"r\") as file:\n            lines = file.readlines()\n        with open(file_name, \"w\") as file:\n            for line in lines:\n                if line.split(\",\")[0] == nombre:\n                    file.write(f\"{nombre}, {cantidad},{precio}\\n\")\n                else:\n                    file.write(line)\n    elif option == \"4\":\n        nombre = input(\"Nombre: \").lower()\n        with open(file_name, \"r\") as file:\n            lines = file.readlines()\n        with open(file_name, \"w\") as file:\n            for line in lines:\n                if line.strip().split(\",\")[0] != nombre:\n                    file.write(line)\n    elif option == \"5\":\n        with open(file_name, \"r\") as file:\n            print(file.read())\n    elif option == \"6\":\n        total = 0\n        with open(file_name, \"r\") as file:\n            for line in file.readlines():\n                components = line.strip().split(\",\")\n                cantidad = int(components[1])\n                precio = float(components[2])\n                total += cantidad * precio\n            print(f\"El total de la venta es: {total}\")\n    elif option == \"7\":\n        nombre = input(\"Nombre: \").lower()\n        total = 0\n        with open(file_name, \"r\") as file:\n            for line in file.readlines():\n                components = line.split(\",\")\n                if components[0] == nombre:\n                    cantidad = int(components[1])\n                    precio = float(components[2])\n                    total += cantidad * precio\n                    print(f\"El total de la venta es: {total}\")\n                    break\n    elif option == \"8\":\n        print(\"Saliendo del programa\")\n        os.remove(file_name)\n        break\n    else:\n        print(\"Seleccione una opciones disponibles.\")\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/C-Gabs.py",
    "content": "#Reto 11\n\n''' * Desarrolla un programa capaz de crear un archivo que se llame como\n* tu usuario de GitHub y tenga la extensión .txt.\n* Añade varias líneas en ese fichero:\n* - Tu nombre.\n* - Edad.\n* - Lenguaje de programación favorito.\n* Imprime el contenido.\n* Borra el fichero.\n*\n* DIFICULTAD EXTRA (opcional):\n* Desarrolla un programa de gestión de ventas que almacena sus datos en un \n* archivo .txt.\n* - Cada producto se guarda en una línea del archivo de la siguiente manera:\n*   [nombre_producto], [cantidad_vendida], [precio].\n* - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n*   actualizar, eliminar productos y salir.\n* - También debe poseer opciones para calcular la venta total y por producto.\n* - La opción salir borra el .txt.\n*/'''\n\nimport os\n\ntxt_file = open(\"C-Gabs.txt\",\"w+\")\ntxt_file.write(\"Gabriel\\n35\\nPython\")\ntxt_file.close()\ntxt_file = open(\"C-Gabs.txt\",\"r+\")\nfor line in txt_file.readlines():\n    print(line)\ntxt_file.close()\nos.remove(\"C-Gabs.txt\")\n\n\n#Reto extra\ntry:\n    txt_file = open(\"productos.txt\",\"x\")\n    txt_file.close()\nexcept FileExistsError:\n    print(\"El archivo ya existe\")\n\nwhile True:\n\n    print(\"\")\n    print(\"1. Añadir producto\")\n    print(\"2. Consultar producto\")\n    print(\"3. Actualizar producto\")\n    print(\"4. Eliminar producto\")\n    print(\"5. Calcular venta total\")\n    print(\"6. Calcular venta por producto\")\n    print(\"7. Salir\")\n\n    opcion = input(\"Elija una opción: \")\n    match opcion:\n        case \"1\":\n            with open(\"productos.txt\",\"a\") as txt_file:\n                producto = input(\"Ingrese el nombre del producto: \")\n                cantidad_vendida = input(\"Ingrese la cantidad vendida: \")\n                precio = input(\"Ingrese el precio: \")\n                txt_file.write(f\"{producto}, {cantidad_vendida}, {precio}\\n\")\n        case \"2\":\n            with open(\"productos.txt\",\"r\") as txt_file:\n                producto = input(\"Ingrese el nombre del producto: \")\n                for line in txt_file.readlines():\n                    if producto in line:\n                        print(line)\n                        break\n                    else:\n                        print(\"El producto no figura en el archivo\")\n                else:\n                    print(\"El archivo está vacio\")\n\n        case \"3\":\n            with open(\"productos.txt\",\"r\") as txt_file:\n                producto = input(\"Ingrese el nombre del producto: \")\n                cantidad_vendida = input(\"Ingrese la nueva cantidad vendida: \")\n                precio = input(\"Ingrese el nuevo precio: \")\n                product_list = txt_file.readlines()\n            with open(\"productos.txt\",\"w\") as txt_file:\n                for line in product_list:\n                    if producto in line:\n                        txt_file.write(f\"{producto}, {cantidad_vendida}, {precio}\\n\")\n                    else:\n                        txt_file.write(line)\n        case \"4\":\n            with open(\"productos.txt\",\"r\") as txt_file:\n                producto = input(\"Ingrese el nombre del producto: \")\n                product_list = txt_file.readlines()\n            with open(\"productos.txt\",\"w\") as txt_file:\n                for line in product_list:\n                    if producto not in line:\n                        print(f\"El producto {producto} se ha eliminado\")\n                        txt_file.write(line)\n        case \"5\":\n            with open(\"productos.txt\",\"r\") as txt_file:\n                venta_total = 0\n                for line in txt_file.readlines():\n                    if len(line) > 1:\n                        line = line.replace(\"\\n\",\"\").split(\", \")\n                        venta_total = venta_total + int(line[1])*int(line[2])\n                print(f\"Venta total: {venta_total}\")\n        case \"6\":\n            with open(\"productos.txt\",\"r\") as txt_file:\n                for line in txt_file.readlines():\n                    if len(line) > 1:\n                        line = line.replace(\"\\n\",\"\").split(\",\")\n                        venta_producto = int(line[1])*int(line[2])\n                        print(f\"Venta del producto {line[0]}: {venta_producto}\")\n        case \"7\":\n            os.remove(\"productos.txt\")\n            print(\"Finalizando el programa\")\n            break\n        case _:\n            print(\"Esta opción no es válida\")\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/CaveroBrandon.py",
    "content": "\"\"\"EJERCICIO:\nDesarrolla un programa capaz de crear un archivo que se llame como tu usuario de GitHub y tenga la extensión .txt.\nAñade varias líneas en ese fichero:\n- Tu nombre.\n- Edad.\n- Lenguaje de programación favorito.\nImprime el contenido.\nBorra el fichero.\"\"\"\n\nimport os\n\n\ndef exercise():\n    file_name = 'CaveroBrandon.txt'\n\n    with open(file_name, 'w') as file:\n        file.write('Name: Brandon Cavero\\n')\n        file.write('Age: 29\\n')\n        file.write('Favorite programming language: Python')\n\n    print(f'File {file_name} has been created')\n\n    os.remove(file_name)\n    print(f'File {file_name} was removed')\n\n\"\"\"DIFICULTAD EXTRA (opcional):\nDesarrolla un programa de gestión de ventas que almacena sus datos en un archivo .txt.\n- Cada producto se guarda en una línea del arhivo de la siguiente manera: \n    [nombre_producto], [cantidad_vendida], [precio].\n- Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n    actualizar, eliminar productos y salir.\n- También debe poseer opciones para calcular la venta total y por producto.\n- La opción salir borra el .txt.\"\"\"\n\n\nclass Sales:\n    def __init__(self, file):\n        self.file = file\n\n    def add_item(self) -> None:\n        product_name = input('Product Name: ')\n        try:\n            quantity = int(input('Quantity: '))\n        except ValueError:\n            print('Quantity should be a number, try again')\n            return\n        try:\n            price = int(input('Price: '))\n        except ValueError:\n            print('Price should be a number, try again')\n            return\n\n        with open(self.file, 'a') as file:\n            file.write(f'{product_name}, {quantity}, {price}\\n')\n\n    def search_product(self):\n        search = input('Enter the product to search: ')\n        try:\n            element_found = False\n            with open(self.file, 'r') as sales_report:\n                for line in sales_report:\n                    elements = line.split()\n                    if elements[0].replace(',', '') == search:\n                        print(f'****Product found****\\n'\n                              f'Product Name: {elements[0].replace(\",\", \"\")}\\n'\n                              f'Quantity: {elements[1].replace(\",\", \"\")}\\n'\n                              f'Price: {elements[2]}')\n                        element_found = True\n                if not element_found:\n                    print(f'The product \"{search}\" was not found')\n        except FileNotFoundError:\n            print('No such file or directory to search the element, please try again')\n\n    def update_product(self):\n        product_to_update = input('Enter the product to update: ')\n        product_updated = False\n\n        new_product_name = input('Enter the new product name: ')\n        try:\n            new_quantity = input('Enter the new quantity of the product: ')\n            new_price = int(input('Enter the new product price: '))\n        except ValueError:\n            print('Price and quantity should be a number, try again')\n            return\n\n        with open(self.file, \"r\") as sale_report:\n            products = sale_report.readlines()\n\n        with open(self.file, \"w\") as sale_report:\n            for product in products:\n                if product_to_update in product:\n                    sale_report.write(f\"{new_product_name}, {new_quantity}, {new_price}\\n\")\n                    print(f'Product \"{product_to_update}\" updated successfully')\n                    product_updated = True\n                else:\n                    sale_report.write(product)\n        if not product_updated:\n            print(f'The product \"{product_to_update}\" was not found')\n\n    def remove_product(self):\n        product_to_remove = input('Enter the product to remove: ')\n        try:\n            with open(self.file, \"r\") as sale_report:\n                products = sale_report.readlines()\n\n            with open(self.file, \"w\") as sale_report:\n                for product in products:\n                    if product_to_remove not in product:\n                        sale_report.write(product)\n                    elif product_to_remove in product:\n                        print(f'The product \"{product_to_remove}\" was successfully removed')\n        except FileNotFoundError:\n            print('No such file or directory to search the element, please try again')\n\n    def show_content(self):\n        try:\n            with open(self.file, 'r') as sales_report:\n                print('The actual sales report is:')\n                print(sales_report.read())\n        except FileNotFoundError:\n            print('No such file or directory to shown, try again')\n\n    def total_sales(self):\n        total_sales = 0\n\n        with open(self.file, \"r\") as sales_report:\n            products = sales_report.readlines()\n            for product in products:\n                value = product.split(\",\")\n                total_sales += value[1]\n        print(f'The total is: {total_sales}')\n\n    def exit(self):\n        try:\n            os.remove(self.file)\n            print(f'The file {self.file} was successfully removed')\n        except FileNotFoundError:\n            print('No such file or directory to remove, try again')\n        except Exception as e:\n            print(f'Something went wrong {e}')\n\n\nexercise()\n\nsales = Sales('sales_report')\nwhile True:\n    print('**************************************\\n'\n          'MENU: \\n'\n          '1. Add a new product\\n'\n          '2. Search for a product\\n'\n          '3. Update a product\\n'\n          '4. Remove a product\\n'\n          '5. Show the sales report\\n'\n          '6. Total\\n'\n          '7. Total per product\\n'\n          '8. Exit')\n    try:\n        option = int(input('Select an option: '))\n        if option == 1:\n            sales.add_item()\n        elif option == 2:\n            sales.search_product()\n        elif option == 3:\n            sales.update_product()\n        elif option == 4:\n            sales.remove_product()\n        elif option == 5:\n            sales.show_content()\n        elif option == 6:\n            sales.total_sales()\n        elif option == 7:\n            sales.exit()\n\n    except ValueError:\n        print('Select a correct value')\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/CesarCarmona30.py",
    "content": "import os\n\nuser = 'CesarCarmona30'\ndata = ['César Carmona\\n', '19\\n', 'Python']\n\nwith open(f'{user}.txt', \"w\", encoding='utf-8') as file:\n  file.writelines(data)\n\nwith open(f'{user}.txt', \"r\", encoding='utf-8') as file:\n  content = file.read()\n\nprint(content)\n\nos.remove(f'{user}.txt')\nprint(f'El archivo {user}.txt ha sido eliminado con éxito')\n\nfile_name = 'ventas.txt'\ndef menu():\n  print('\\n\\nGestión de ventas: ')\n  print('1. Añadir producto')\n  print('2. Consultar producto')\n  print('3. Listar productos')\n  print('4. Actualizar producto')\n  print('5. Eliminar producto')\n  print('6. Calcular venta por producto')\n  print('7. Calcular venta total')\n  print('8. Salir')\n\ndef addProduct():\n  product = input(\"Nombre del producto: \")\n  amount = input(\"Cantidad vendida: \")\n  price = input(\"Precio del producto:\")\n  with open(file_name, 'a') as file:\n    file.write(f'{product}, {amount}, {price}')\n  print('Producto añadido correctamente')\n\ndef seeProduct():\n  product_name = input('Nombre del producto a consultar: ')\n  with open(file_name, 'r') as file:\n    lines = file.readlines()\n  for line in lines:\n    data = line.split(', ')\n    if product_name in data:\n      print(f'Nombre: {line[0]}, Cantidad vendida: {line[1]}, Precio: {line[2]}')\n    else:\n      print('Producto no encontrado')\n\ndef seeProducts():\n  with open(file_name, 'r') as file:\n    lines = file.readlines()\n  for line in lines:\n    data = line.split(', ')\n    print(f'Nombre: {line[0]}, Cantidad vendida: {line[1]}, Precio: {line[2]}')\n\ndef updateProduct():\n  product_name = input('Nombre del producto a actualizar: ')\n  new_amount = input('Nueva cantidad vendida: ')\n  with open(file_name, 'r') as file:\n    lines = file.readlines()\n  with open(file_name, 'w') as file:\n    for line in lines:\n      if product_name in line:\n        file.write(f'{product_name}, {new_amount}, {line[2]}')\n      else:\n        file.write(line)\n\ndef deleteProduct():\n  product_name = input('Nombre del producto a eliminar: ')\n  with open(file_name, 'r') as file:\n    lines = file.readlines()\n  with open(file_name, 'w') as file:\n    for line in lines:\n      if product_name not in line:\n        file.write(line)\n    print('Producto eliminado')\n\ndef productSales():\n  product_name = input('Nombre del producto a consultar: ')\n  with open(file_name, 'r') as file:\n    lines = file.readlines()\n  for line in lines:\n    data = line.split(', ')\n    if product_name in data:\n      amount = int(data[1])\n      price = int(data[2])\n      sales = amount * price\n      print(f'Venta del producto: {sales}')\n    else:\n      print('Producto no encontrado')\n\ndef totalSales():\n  with open(file_name, 'r') as file:\n    lines = file.readlines()\n  total_sales = 0  \n  for line in lines:\n    data = line.split(', ')\n    amount = int(data[1])\n    price = int(data[2])\n    total_sales += amount * price\n    print(f'Venta total: {total_sales}')\n\ndef managerSales():\n  while True:\n    menu()\n    option = input('Eliga una opción: ')\n    if option == '1':\n      addProduct()\n    elif option == '2':\n      seeProduct()\n    elif option == '3':\n      seeProducts()\n    elif option == '4':\n      updateProduct()\n    elif option == '5':\n      deleteProduct()\n    elif option == '6':\n      productSales()\n    elif option == '7':\n      totalSales()\n    elif option == '8':  \n      if os.path.exists(file_name):\n        os.remove(file_name)\n      print(\"Saliendo del programa...\")\n      break\n    else:\n      print(\"Opción no válida.\")\n\nmanagerSales()"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/Chrisdev00.py",
    "content": "\"\"\"\n* IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n* \n* EJERCICIO:\n* Desarrolla un programa capaz de crear un archivo que se llame como\n* tu usuario de GitHub y tenga la extensión .txt.\n* Añade varias líneas en ese fichero:\n* - Tu nombre.\n* - Edad.\n* - Lenguaje de programación favorito.\n* Imprime el contenido.\n* Borra el fichero.\n*\n* DIFICULTAD EXTRA (opcional):\n* Desarrolla un programa de gestión de ventas que almacena sus datos en un \n* archivo .txt.\n* - Cada producto se guarda en una línea del arhivo de la siguiente manera:\n*   [nombre_producto], [cantidad_vendida], [precio].\n* - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n*   actualizar, eliminar productos y salir.\n* - También debe poseer opciones para calcular la venta total y por producto.\n* - La opción salir borra el .txt.\n\"\"\"\nimport os\n\ndef crear_archivo(user_github):\n\n    nombre_archivo = f\"{user_github}.txt\"\n\n    lineas = [\n        \"Nombre: Christian\",\n        \"Edad: 30\",\n        \"Lenguaje de programacion favorito: Python\"        \n    ]\n\n    with open(nombre_archivo, \"w\") as file:\n        for linea in lineas:\n            file.write(linea + \"\\n\")\n\n    print(f\"Contenido del archivo {nombre_archivo}:\\n\")\n\n    with open(nombre_archivo, \"r\") as file:\n        for linea in file:\n            print(linea.strip())\n\n    os.remove(nombre_archivo)\n    print(f\"\\nEl archivo {nombre_archivo} ha sido borrado.\")\n\nif __name__==\"__main__\":\n    usuario = \"Chrisdev00\"\n    crear_archivo(usuario)\n\n\n\n########  --------------------------  EXTRA  ------------------------------  ###############\n    \nimport os\n\ndef agregar_producto(archivo):\n\n    nombre = input(\"Nombre del producto: \")\n    cantidad = int(input(\"Cantidad vendida: \"))\n    precio = float(input(\"Precio por unidad: \"))\n\n    with open(archivo, \"a\") as file:\n        file.write(f\"{nombre}, {cantidad}, {precio}\\n\")\n\n    print(\"Producto añadido correctamente.\\n\")\n\ndef consultar_ventas(archivo):\n\n    print(\"ventas registradas:\")\n    with open(archivo, \"r\") as file:\n        for linea in file:\n            print(linea.strip())\n\ndef actualizar_producto (archivo):\n\n    producto_actualizar = input(\"Ingrese el nombre del producto a actualizar: \")\n    nueva_cantidad = int(input(\"Ingrese la nueva cantidad vendida: \"))\n    nuevo_precio = float(input(\"Ingrese el nuevo precio: \"))\n\n    with open(archivo, \"r\") as file:\n        lineas = file.readlines()\n\n    with open(archivo, \"w\") as file:\n        for linea in lineas:\n            producto, cantidad, precio = linea.strip().split(', ')\n            if producto == producto_actualizar:\n                cantidad = str(nueva_cantidad)\n                precio = str(nuevo_precio)\n            file.write(f\"{producto}, {cantidad}, {precio}\\n\")\n\n    print(\"Producto actualizado correctamente.\\n\")\n\ndef eliminar_producto(archivo):\n\n    producto_eliminar = input(\"Ingrese el nombre del producto a eliminar: \")\n\n    with open(archivo, \"r\") as file:\n        lineas = file.readlines()\n\n    with open(archivo, \"w\") as file:\n        for linea in lineas:\n            producto, _, _ = linea.strip().split(', ')\n            if producto != producto_eliminar:\n                file.write(linea)\n\n    print(\"Producto eliminado correctamente.\\n\")\n\ndef venta_total (archivo):\n\n    total = 0\n    with open(archivo, \"r\") as file:\n        for linea in file:\n            _, cantidad, precio = linea.strip().split(', ')\n            total += int(cantidad) * float(precio)\n\n    print(f\"La venta total es: ${total:.2f}\\n\")\n\ndef venta_producto (archivo):\n\n    producto_consultar = input(\"Ingrese el nombre del producto: \")\n\n    with open(archivo, 'r') as file:\n        for linea in file:\n            producto, cantidad, precio = linea.strip().split(', ')\n            if producto == producto_consultar:\n                total = int(cantidad) * float(precio)\n                print(f\"Venta de {producto}: {total:.2f}\\n\")\n                return\n            \n        print(\"Producto no encontrado.\\n\")\n\ndef main():\n\n    archivo = \"ventas.txt\"\n\n    while  True:\n        print(\"======= Gestión de Ventas =======\")\n        print(\"1. Añadir producto\")\n        print(\"2. Consultar ventas\")\n        print(\"3. Actualizar producto\")\n        print(\"4. Eliminar producto\")\n        print(\"5. Venta total\")\n        print(\"6. Venta por producto\")\n        print(\"7. Salir\")\n\n        option = input(\"Seleccione una opcion: \")\n\n        if option == \"1\":\n            agregar_producto(archivo)\n        elif option == \"2\":\n            consultar_ventas(archivo)\n        elif option == \"3\":\n            actualizar_producto(archivo)\n        elif option == \"4\":\n            eliminar_producto(archivo)\n        elif option == \"5\":\n            venta_total(archivo)\n        elif option == \"6\":\n            venta_producto(archivo)\n        elif option == \"7\":\n            os.remove(archivo)\n            print(\"Gracias por utilizar el sistema\")\n            break\n        else:\n            print(\"Opcion invalida. Porfavor seleccione una opcion valida.\\n\")\n\nif __name__== \"__main__\":\n    main()\n\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/Complex303.py",
    "content": "# Importamos el módulo os, que permite interactuar con el sistema operativo (por ejemplo: borrar archivos)\nimport os\n\n\"\"\"\nFicheros\n\"\"\"\nfile_name = \"Complex_303\"  # Definimos el nombre del archivo que se va a crear, leer y luego borrar\n\n# Comentario de ejemplo de cómo se podría abrir un archivo sin 'with'\n# open(file_name, \"w\") # No se cierra automáticamente y es menos seguro\n\n# Aquí abrimos (o creamos) el archivo en modo escritura (\"w\") usando with, que cierra el archivo automáticamente al salir del bloque\nwith open(file_name, \"w\") as file:\n    file.write(\"Complex_303\\n\")  # Escribe la cadena \"Complex_303\" y un salto de línea\n    file.write(\"24\\n\")           # Escribe la cadena \"24\" y un salto de línea\n    file.write(\"Python\")         # Escribe la cadena \"Python\" sin salto de línea\n\n# Ahora volvemos a abrir el mismo archivo, pero en modo lectura (\"r\") para leer su contenido\nwith open(file_name, \"r\") as file:\n    print(file.read())  # Leemos todo el contenido del archivo y lo mostramos por pantalla\n\n# Finalmente, usamos os.remove() para borrar el archivo del sistema\nos.remove(file_name)\n\n\n\"\"\" * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n * archivo .txt.\n * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\"\"\"\n\n\n# Definimos el nombre del archivo donde se almacenarán los productos\nfile_name = \"Complex_303_productos\"\n\n# Creamos (si no existe) el archivo en modo añadir ('a'), y lo cerramos inmediatamente\nopen(file_name, 'a')\n\n# Iniciamos un bucle infinito para mostrar un menú hasta que el usuario decida salir\nwhile True:\n    # Mostramos el menú de opciones en consola\n    print(\"1. Añadir producto\")\n    print(\"2. Consultar producto\")\n    print(\"3. Actualizar producto\")\n    print(\"4. Borrar producto\")\n    print(\"5. Mostrar productos\")\n    print(\"6. Calcular venta total\")\n    print(\"7. Calcular venta por producto\")\n    print(\"8. Salir\")\n\n    # Pedimos al usuario que ingrese una opción del menú\n    option = int(input(\"Seleccione una opcion: \"))\n\n    # OPCIÓN 1: Añadir un producto\n    if option == 1:\n        # Pedimos al usuario los datos del producto\n        name = input(\"Nombre: \")\n        quantity = input(\"Cantidad: \")\n        precio = input(\"Indique el precio: \")\n\n        # Abrimos el archivo en modo añadir ('a') para escribir al final del archivo\n        with open(file_name, \"a\") as file:\n            # Guardamos el producto en una línea con el formato: nombre, cantidad, precio\n            file.write(f\"{name}, {quantity}, {precio}\\n\")\n\n    # OPCIÓN 2: Consultar un producto por su nombre\n    elif option == 2:\n        name = input(\"Nombre: \")\n        found = False  # Variable para saber si se encontró o no el producto\n        with open(file_name, \"r\") as file:\n            for line in file.readlines():  # Leemos todas las líneas una por una\n                if line.split(\", \")[0] == name:  # Comparamos el nombre del producto (que está en la primera posición)\n                    print(line)  # Mostramos la línea completa\n                    found = True\n        if not found:\n            print(\"Producto no encontrado\")  # Solo muestra si no se encontró nada\n\n    # OPCIÓN 3: Actualizar un producto existente\n    elif option == 3:\n        name = input(\"Nombre: \")\n        quantity = input(\"Cantidad: \")\n        precio = input(\"Indique el precio: \")\n\n        # Leemos todas las líneas del archivo\n        with open(file_name, \"r\") as file:\n            lines = file.readlines()\n\n        # Reescribimos el archivo completo\n        with open(file_name, \"w\") as file:\n            for line in lines:\n                if line.split(\", \")[0] == name:\n                    # Si el nombre coincide, escribimos los nuevos datos\n                    file.write(f\"{name}, {quantity}, {precio}\\n\")\n                else:\n                    # Si no coincide, dejamos la línea tal como estaba\n                    file.write(line)\n\n    # OPCIÓN 4: Borrar un producto por su nombre\n    elif option == 4:\n        name = input(\"Nombre: \")\n        found = False  # Variable para indicar si se eliminó algo o no\n\n        # Leemos todas las líneas\n        with open(file_name, \"r\") as file:\n            lines = file.readlines()\n\n        # Reescribimos el archivo sin las líneas del producto a borrar\n        with open(file_name, \"w\") as file:\n            for line in lines:\n                if line.split(\", \")[0] != name:\n                    file.write(line)  # Escribimos las líneas que no coinciden\n                else:\n                    found = True  # Marcamos que se encontró y eliminó\n        if not found:\n            print(\"Producto no encontrado\")  # Mostramos este mensaje solo si no se encontró\n\n    # OPCIÓN 5: Mostrar todos los productos\n    elif option == 5:\n        with open(file_name, \"r\") as file:\n            print(file.read())  # Leemos y mostramos todo el contenido del archivo\n\n    # OPCIÓN 6: Calcular el total de todas las ventas\n    elif option == 6:\n        total = 0  # Inicializamos el total en cero\n        with open(file_name, \"r\") as file:\n            for line in file.readlines():\n                components = line.split(\", \")  # Dividimos cada línea en nombre, cantidad, precio\n                quantity = int(components[1])  # Convertimos la cantidad a entero\n                price = float(components[2])  # Convertimos el precio a decimal\n                total += quantity * price  # Sumamos el total de cada producto (cantidad × precio)\n        print(f\"Total: {total}\")  # Mostramos el total\n\n    # OPCIÓN 7: Calcular la venta total de un producto específico\n    elif option == 7:\n        name = input(\"Nombre: \")\n        total = 0\n        with open(file_name, \"r\") as file:\n            for line in file.readlines():\n                components = line.split(\", \")\n                if components[0] == name:\n                    quantity = int(components[1])\n                    price = float(components[2])\n                    total = quantity * price  # Calculamos el total de ese producto\n                    break  # Ya que el producto se encontró, salimos del bucle\n        print(f\"Total: {total}\")  # Mostramos el total del producto\n\n    # OPCIÓN 8: Salir del programa\n    elif option == 8:\n        os.remove(file_name)  # Eliminamos el archivo antes de salir\n        break  # Rompemos el bucle para terminar el programa\n\n    #Si el usuario ingresa una opción que no existe\n    else:\n        print(\"Elegi una opcion valida\")  # Mostramos mensaje de error\n\n\n\"\"\"\nOtra forma mas optima\n\"\"\"\n\nimport os  # Importamos el módulo os para operaciones con el sistema (como eliminar archivos)\n\n# 📌 Nombre del archivo donde se almacenarán los productos\nfile_name = \"Complex_303_productos\"\n\n# 📌 Si el archivo no existe, lo creamos vacío para evitar errores al intentar abrirlo después\nif not os.path.exists(file_name):\n    open(file_name, 'w').close()\n\n# 📦 Función para cargar todos los productos desde el archivo a una lista en memoria\ndef cargar_productos():\n    productos = []  # Lista vacía para almacenar los productos\n    with open(file_name, \"r\") as file:\n        for line in file:\n            # Cada línea se divide en nombre, cantidad y precio, separados por \", \"\n            name, quantity, price = line.strip().split(\", \")\n            # Se almacena como un diccionario\n            productos.append({\"name\": name, \"quantity\": int(quantity), \"price\": float(price)})\n    return productos\n\n# 💾 Función para guardar todos los productos desde la lista al archivo\ndef guardar_productos(productos):\n    with open(file_name, \"w\") as file:\n        for p in productos:\n            # Cada producto se guarda como una línea en formato: nombre, cantidad, precio\n            file.write(f\"{p['name']}, {p['quantity']}, {p['price']}\\n\")\n\n# 📋 Función para mostrar el menú de opciones\ndef mostrar_menu():\n    print(\"\"\"\n1. Añadir producto\n2. Consultar producto\n3. Actualizar producto\n4. Borrar producto\n5. Mostrar productos\n6. Calcular venta total\n7. Calcular venta por producto\n8. Salir\n\"\"\")\n\n# ➕ Añadir producto nuevo a la lista\ndef añadir_producto(productos):\n    name = input(\"Nombre: \")\n    quantity = int(input(\"Cantidad: \"))\n    price = float(input(\"Precio: \"))\n    # Añadimos el producto como un diccionario a la lista\n    productos.append({\"name\": name, \"quantity\": quantity, \"price\": price})\n    print(\"✅ Producto añadido.\")\n\n# 🔍 Consultar un producto por nombre\ndef consultar_producto(productos):\n    name = input(\"Nombre: \")\n    for p in productos:\n        if p[\"name\"] == name:\n            print(f\"{p['name']}, {p['quantity']}, {p['price']}\")\n            return  # Salimos si se encuentra\n    print(\"❌ Producto no encontrado.\")\n\n# 🛠️ Actualizar datos de un producto existente\ndef actualizar_producto(productos):\n    name = input(\"Nombre: \")\n    for p in productos:\n        if p[\"name\"] == name:\n            # Solicitamos nuevos valores y los actualizamos\n            p[\"quantity\"] = int(input(\"Nueva cantidad: \"))\n            p[\"price\"] = float(input(\"Nuevo precio: \"))\n            print(\"✅ Producto actualizado.\")\n            return\n    print(\"❌ Producto no encontrado.\")\n\n# ❌ Borrar un producto de la lista\ndef borrar_producto(productos):\n    name = input(\"Nombre: \")\n    for p in productos:\n        if p[\"name\"] == name:\n            productos.remove(p)  # Eliminamos el producto de la lista\n            print(\"✅ Producto eliminado.\")\n            return\n    print(\"❌ Producto no encontrado.\")\n\n# 📄 Mostrar todos los productos registrados\ndef mostrar_productos(productos):\n    if not productos:\n        print(\"⚠️ No hay productos registrados.\")\n    else:\n        for p in productos:\n            print(f\"{p['name']}, {p['quantity']}, {p['price']}\")\n\n# 💰 Calcular el total de todas las ventas\ndef calcular_total_ventas(productos):\n    total = sum(p[\"quantity\"] * p[\"price\"] for p in productos)\n    print(f\"💸 Total de ventas: {total}\")\n\n# 💵 Calcular total de venta de un producto específico\ndef calcular_venta_producto(productos):\n    name = input(\"Nombre: \")\n    for p in productos:\n        if p[\"name\"] == name:\n            total = p[\"quantity\"] * p[\"price\"]\n            print(f\"💰 Total de {name}: {total}\")\n            return\n    print(\"❌ Producto no encontrado.\")\n\n# 🚀 Bucle principal del programa\nproductos = cargar_productos()  # Cargamos productos desde el archivo al iniciar\n\n# Mientras no se elija salir\nwhile True:\n    mostrar_menu()  # Mostramos menú de opciones\n\n    try:\n        option = int(input(\"Seleccione una opción: \"))  # Leemos la opción elegida\n    except ValueError:\n        print(\"❌ Debes ingresar un número.\")\n        continue  # Si no es número, vuelve a mostrar el menú\n\n    # Según la opción elegida, ejecutamos la función correspondiente\n    if option == 1:\n        añadir_producto(productos)\n        guardar_productos(productos)\n    elif option == 2:\n        consultar_producto(productos)\n    elif option == 3:\n        actualizar_producto(productos)\n    elif option == 4:\n        borrar_producto(productos)\n    elif option == 5:\n        mostrar_productos(productos)\n    elif option == 6:\n        calcular_total_ventas(productos)\n    elif option == 7:\n        calcular_venta_producto(productos)\n    elif option == 8:\n        # Antes de salir, guardamos los productos actualizados\n        guardar_productos(productos)\n        # Eliminamos el archivo si así se desea\n        os.remove(file_name)\n        print(\"✅ Archivo eliminado y programa cerrado.\")\n        break  # Terminamos el bucle y cerramos programa\n    else:\n        print(\"⚠️ Opción no válida.\")\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/DaniQB99.py",
    "content": "'''\nEJERCICIO:\nDesarrolla un programa capaz de crear un archivo que se llame como tu\nusuario de GitHub y tenga la extension .txt.\n\nAñade varias líneas en ese fichero:\n- Tu nombre.\n- Edad.\n- Lenguaje de programación favorito.\nImprime el contenido.\nBorra el fichero.\n'''\nimport os\n\ndef program_file():\n    \n    file_name = \"DaniQB99.txt\"\n\n    lines = [\"- Dani\\n\", \"- 25\\n\", \"- Python\\n\"]\n    \n    with open(file_name, \"w\") as file: # Escribe en el archivo\n        file.writelines(lines)\n\n    with open(file_name, \"r\") as file: # Lee el archivo\n        print(file.read())\n\n    os.remove(file_name) # Borra el archivo\n\nprogram_file()\n\n'''\nDIFICULTAD EXTRA (opcional):\nDesarrolla un programa de gestión de ventas que almacena sus datos en un \narchivo .txt.\n- Cada producto se guarda en una línea del arhivo de la siguiente manera:\n[nombre_producto], [cantidad_vendida], [precio].\n- Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\nactualizar, eliminar productos y salir.\n- También debe poseer opciones para calcular la venta total y por producto.\n- La opción salir borra el .txt.\n'''\n\ndef program_shop():\n\n    file_name = \"DaniQB99_shop.txt\"\n\n    while True:\n        print(\"1. Añadir producto\")\n        print(\"2. Consultar producto\")\n        print(\"3. Actualizar producto\")\n        print(\"4. Borrar producto\") \n        print(\"5. Mostrar productos\")\n        print(\"6. Calcular venta total\")\n        print(\"7. Calcular venta por producto\")\n        print(\"8. Salir\")\n        \n        option = input(\"Selecciona una opción: \")\n\n        if option == \"1\":\n            name = input(\"Nombre del producto: \")\n            quantity = input(\"Cantidad: \")\n            price = input(\"Precio: \")\n\n            with open(file_name, \"a\") as file:\n                file.write(f\"{name}, {quantity}, {price}\\n\")\n                print(\"Producto añadido con éxito.\")\n\n        elif option == \"2\":\n            name = input(\"Nombre del producto: \")\n\n            with open(file_name, \"r\") as file:\n                for line in file.readlines():\n                    if line.split(\", \")[0] == name:\n                        print(line)\n                        break\n        \n        elif option == \"3\":\n            name = input(\"Nombre del producto: \")\n            quantity = input(\"Nueva cantidad: \")\n            price = input(\"Nuevo precio: \")\n            \n            with open(file_name, \"r\") as file:\n                lines = file.readlines()\n            \n            with open(file_name, \"w\") as file:\n                for line in lines:\n                    if line.split(\", \")[0] == name:\n                        file.write(f\"{name}, {quantity}, {price}\\n\")\n                        print(\"Producto actualizado con éxito.\")\n                    else:\n                        file.write(line)\n                        print(\"Producto no encontrado.\")\n\n        elif option == \"4\":\n            name = input(\"Nombre del producto: \")\n            \n            with open(file_name, \"r\") as file:\n                lines = file.readlines()\n                for line in lines:\n                    if line.split(\", \")[0] != name:\n                        file.write(line)\n                        print(\"Producto eliminado con éxito.\")\n                        break\n                    else:\n                        file.write(line)\n                        print(\"Producto no encontrado.\")\n                        break\n        \n        elif option == \"5\":\n            with open(file_name, \"r\") as file:\n                print(\"Productos almacenados: \\n\")\n                print(file.read())\n        \n        elif option == \"6\":\n            total = 0\n            with open(file_name, \"r\") as file:\n                for line in file.readlines():\n                    components = line.split(\", \")\n                    quantity = int(components[1])\n                    price = float(components[2])\n                    total += quantity * price # += es el acumulador de suma\n            print('El total de la venta es:', total)\n        \n        elif option == \"7\":\n            name = input(\"Nombre del producto: \")\n            total = 0\n            with open(file_name, \"r\") as file:\n                for line in file.readlines():\n                    components = line.split(\", \")\n                    if components[0] == name:\n                        quantity = int(components[1])\n                        price = float(components[2])\n                        total += quantity * price # += es el acumulador de suma\n                        break\n            print('El total de la venta por este producto es:', total)\n        \n        elif option == \"8\":\n            os.remove(file_name)\n            break\n        \n        else:\n            print(\"Selecciona una de las opciones disponibles.\")\n            program_file()\n\nprogram_shop()\n                \n            "
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/DataCiriano.py",
    "content": "\"\"\"\n* IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n* \n* EJERCICIO:\n* Desarrolla un programa capaz de crear un archivo que se llame como\n* tu usuario de GitHub y tenga la extensión .txt.\n* Añade varias líneas en ese fichero:\n* - Tu nombre.\n* - Edad.\n* - Lenguaje de programación favorito.\n* Imprime el contenido.\n* Borra el fichero.\n*\n* DIFICULTAD EXTRA (opcional):\n* Desarrolla un programa de gestión de ventas que almacena sus datos en un \n* archivo .txt.\n* - Cada producto se guarda en una línea del arhivo de la siguiente manera:\n*   [nombre_producto], [cantidad_vendida], [precio].\n* - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n*   actualizar, eliminar productos y salir.\n* - También debe poseer opciones para calcular la venta total y por producto.\n* - La opción salir borra el .txt.\n\"\"\"\nimport os\n\nfile_name = 'DataCiriano.txt'\n\nwith open(file_name, \"w\") as file:\n    file.write(\"Mi usuario de GitHub es: Data Ciriano\\n\")\n    file.write(\"Tengo 33 años\\n\")\n    file.write(\"Mi lenguaje de programación favorito es Python\\n\")\n    \nwith open(file_name, \"r\") as file:\n    print(file.read())\n    \nos.remove(file_name)\n\n\n#-----EXTRA----\n\nfile_name = \"shop.txt\"\n\nwhile True:\n    \n    action = input(\"\"\"Introduzca una de las siguientes opciones:\\n\n                   1- Añadir Producto\\n\n                   2- Consultar Producto\\n3\n                   3- Actualizar Producto\\n\n                   4- Borrar Producto\\n\n                   5- Mostrar Producto\\n\n                   6- Calcular venta total\\n\n                   7- Calcular venta por producto\\n\n                   8- Salir\\n\\n\"\"\")\n    \n    match action:\n        \n        case \"1\":\n            name = input(\"Introduzca el nombre del producto: \")\n            quantity = input(\"Cantidad: \")\n            price = input(\"Price: \")\n            \n            with open(file_name, \"a\") as file:\n                file.write(f\"{name}, {quantity}, {price}\\n\")\n                \n        case \"2\":\n            name = input(\"Introduzca el nombre del archivo que desea consultar: \")\n            \n            with open(file_name, \"r\") as file:\n                for line in file.readlines():\n                    if line.split(\", \")[0] == name:\n                        print(line)\n                else:\n                    print(f\"No existe un producto con el nombre: {name}\")\n                        \n        case \"3\":\n            name = input(\"Introduzca el nombre del producto que desea actualizar: \")\n            quantity = input(\"Introduzca la cantidad de este producto: \")\n            price = input(\"Introduzca el precio del producto: \")\n            \n            with open(file_name, \"r\") as file:\n                lines = file.readlines()\n                \n            with open(file_name, \"w\") as file:\n                for line in lines:\n                    if line.split(\", \")[0] == name:\n                        file.write(f\"{name}, {quantity}, {price}\\n\")\n                    else:\n                        file.write(line)\n                        \n        case \"4\":\n            name = input(\"Introduzca el nombre del producto que desea borrar: \")\n            \n            with open(file_name, \"r\") as file:\n                lines = file.readlines()\n            \n            with open(file_name, \"w\") as file:\n                for line in lines:\n                    if line.split(\", \")[0] != name:\n                        file.write(line)\n                        \n        case \"5\":\n            name = input(\"Introduzca el nombre del producto que desea ver: \")\n            \n            with open(file_name, \"r\") as file:\n                lines = file.readlines()\n                \n                for line in lines:\n                    if line.split(\", \")[0] == name:\n                        print(line)\n                        break\n                else:\n                    print(f\"No existe el producto {name}\")\n                    \n        case \"6\":\n            total = 0\n            \n            with open(file_name, \"r\") as file:\n                for line in file.readlines():\n                    components = line.split(\", \")\n                    quantity = int(components[1])\n                    price = float(components[2])\n                    total += quantity * price\n            \n            print(f\"El total de ventas es: {total}\")\n            \n        case \"7\":\n            name = input(\"Nombre: \")\n            total = 0\n            \n            with open(file_name, \"r\") as file:\n                for line in file.readlines():\n                    components = line.split(\", \")\n                    if components[0] == name:\n                        quantity = int(components[1])\n                        price = float(components[2])\n                        total += quantity * price\n                        break\n            \n            print(f\"Las ventas totales de {name} son: {total}\")\n            \n                \n        case \"8\":\n            os.remove(file_name)\n            print(\"Archivo borrado\")\n            break\n                  \n        case _:\n            print(\"Seleccione una de las opciones disponibles\")\n            "
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/Dkp-Dev.py",
    "content": "import os\n\n\"\"\"\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n\"\"\"\n\nfile_name = \"Dkp-Dev.txt\"\n\nwith open(file_name, \"w\") as file:\n    file.write(\"Dkp Dev\\n\")\n    file.write(\"29\\n\")\n    file.write(\"Python\")\n\nwith open(file_name, \"r\") as file:\n    print(file.read())\n\nos.remove(file_name)\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n * archivo .txt.\n * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n */\n\"\"\"\n\nfile_name = \"Dkp-Dev Shop.txt\"\n\nopen(file_name, \"a\")\n\nwhile True:\n    print(\"1. Añadir producto\")\n    print(\"2. Consultar producto\")\n    print(\"3. Actualizar producto\")\n    print(\"4. Borrar producto\")\n    print(\"5. Mostrar productos\")\n    print(\"6. Calcular venta total\")\n    print(\"7. Calcular venta por producto\")\n    print(\"8. Salir\")\n\n    option = input(\"Selecciona una opción: \")\n\n    if option == \"1\":\n        name = input(\"Nombre: \")\n        quantity = input(\"Cantidad: \")\n        price = input(\"Precio: \")\n        with open(file_name, \"a\") as file:\n            file.write(f\"{name}, {quantity}, {price}\\n\")\n    elif option == \"2\":\n        name = input(\"Nombre: \")\n        with open(file_name, \"r\") as file:\n            for line in file.readlines():\n                if line.split(\", \")[0] == name:\n                    print(line)\n                    break\n    elif option == \"3\":\n        name = input(\"Nombre: \")\n        quantity = input(\"Cantidad: \")\n        price = input(\"Precio: \")\n        with open(file_name, \"r\") as file:\n            lines = file.readlines()\n        with open(file_name, \"w\") as file:\n            for line in lines:\n                if line.split(\", \")[0] == name:\n                    file.write(f\"{name}, {quantity}, {price}\\n\")\n                else:\n                    file.write(line)\n    elif option == \"4\":\n        name = input(\"Nombre: \")\n        with open(file_name, \"r\") as file:\n            lines = file.readlines()\n        with open(file_name, \"w\") as file:\n            for line in lines:\n                if line.split(\", \")[0] != name:\n                    file.write(line)\n    elif option == \"5\":\n        with open(file_name, \"r\") as file:\n            print(file.read())\n    elif option == \"6\":\n        total = 0\n        with open(file_name, \"r\") as file:\n            for line in file.readlines():\n                components = line.split(\", \")\n                quantity = int(components[1])\n                price = float(components[2])\n                total += quantity * price\n        print(total)\n    elif option == \"7\":\n        name = input(\"Nombre: \")\n        total = 0\n        with open(file_name, \"r\") as file:\n            for line in file.readlines():\n                components = line.split(\", \")\n                if components[0] == name:\n                    quantity = int(components[1])\n                    price = float(components[2])\n                    total += quantity * price\n                    break\n        print(total)\n    elif option == \"8\":\n        os.remove(file_name)\n        break\n    else:\n        print(\"Selecciona una de las opciones disponibles.\")\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/EmmanuelMMontesinos.py",
    "content": "\"\"\"/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n * \n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n */\"\"\"\n\nprint(\"Ejercicio Base\")\nprint(\"---------------\")\n\n# Necesito Importar os para borrar el archivo\nimport os\n\ndef crear_archivo(nombre,edad,lenguaje):\n    with open(nombre,\"w\") as archivo:\n        archivo.write(f\"Nombre: {nombre[:-4]}\\n\")\n        archivo.write(f\"Edad: {edad}\\n\")\n        archivo.write(f\"Lenguaje Favorito: {lenguaje}\")\n\ndef imprimir_archivo(nombre):\n    with open(nombre,\"r\") as archivo:\n        for linea in archivo.readlines():\n            print(linea)\n\ndef eliminar_archivo(nombre):\n    try:\n        os.remove(nombre)\n    except FileNotFoundError as e:\n        print(f\"El archivo no existe: {e}\")\n\nnombre = \"EmmanuelMMontesinos.txt\"\n\ncrear_archivo(nombre,\"33\",\"Python\")\nimprimir_archivo(nombre)\neliminar_archivo(nombre)\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n * archivo .txt.\n * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n\"\"\"\n\nclass BaseDatos:\n    def __init__(self,archivo) -> None:\n        self.archivo = archivo\n    \n    def add_compra(self,compra):\n        nombre,cantidad,precio = compra.split(\",\")\n        if type(nombre) == str and type(int(cantidad)) == int and type(float(precio)) == float:\n            with open(self.archivo,\"a\") as archivo:\n                archivo.write(f\"{nombre},{cantidad},{precio}\\n\")\n        else:\n            print(f\"Error, revise los datos: {compra}\")\n    def imprime_compra(self):\n        with open(self.archivo,\"r\") as archivo:\n            ciclo = 1\n            for line in archivo.readlines():\n                print(ciclo,\" - \",line,\"\\n\")\n                ciclo += 1\n    \n    def actualizar_compra(self,id,cambio=None,eliminar=False):\n        nueva_lista = []\n        with open(self.archivo, \"r\") as archivo:\n            contador = 1\n            for line in archivo.readlines():\n                if contador != int(id):\n                    nueva_lista.append(line)\n                else:\n                    if not eliminar:\n                        nueva_lista.append(cambio + \"\\n\")\n                    \n                contador += 1\n        with open(self.archivo, \"w\") as archivo:\n            for line in nueva_lista:\n                archivo.write(line)\n    def salir(self):\n        os.remove(self.archivo)\n                \ndef app():\n    salida = False\n    lista_01 = BaseDatos(\"compra_semanal.txt\")\n    while not salida:\n        accion = input(\"Elija una opcion\\n1-Añadir producto\\n2-Consultar productos\\n3-Actualizar producto\\n4-Eliminar producto\\n5-Salir\\n\")\n        if accion == \"1\":\n            producto = input(\"Añada el producto en el siguiente formato: nombre,cantidad,precio_unidad\\n\")\n            lista_01.add_compra(producto)\n        elif accion == \"2\":\n            lista_01.imprime_compra()\n        elif accion == \"3\":\n            id = input(\"Id que quiere actualizar: \")\n            cambio = input(\"Ingrese el nuevo producto: \")\n            lista_01.actualizar_compra(id,cambio)\n        elif accion == \"4\":\n            id = input(\"Id que quiere eliminar: \")\n            lista_01.actualizar_compra(id,eliminar=True)\n        elif accion == \"5\":\n            print(\"Borrando archivo txt\")\n            lista_01.salir()\n            print(\"Adios!\")\n            salida = True\n\n# Función por terminal\napp()\n\n# Pruebas Automatizadas\n# lista_01 = BaseDatos(\"compra_semanal.txt\")\n# lista_01.add_compra(\"huevos,2,1.5\")\n# lista_01.add_compra(\"cafe,1,1.25\")\n# lista_01.add_compra(\"cocacola,8,2.8\")\n# lista_01.add_compra(\"cubata,4,5.2\")\n# lista_01.imprime_compra()\n# lista_01.actualizar_compra(\"2\",\"leche,7,0.5\")\n# lista_01.imprime_compra()\n# lista_01.actualizar_compra(\"3\",eliminar=True)\n# lista_01.imprime_compra()\n# lista_01.salir()"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/FedeAirala.py",
    "content": "# 11 MANEJO DE FICHEROS\n\n## Ejercicio\n\n\"\"\"\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n\n \"\"\"\n\nimport os\n\nfichero = open(\"FedeAirala.txt\",\"w+\")                           # Se crea un fichero de tipo escritura\nfichero.write(\"Federico Airala \\n43 Años \\nLenguaje: Python\")   # Escribo varias líneas en el fichero\n\nfichero = open(\"FedeAirala.txt\",\"r\")                            # Fichero en modo lectura\nprint (fichero.read())                                          # Imresión por pantalla del fichero\nfichero.close()                                                 # Se cierra el fichero\n\nif os.path.exists(\"FedeAirala.txt\"):                            # Compruebo si existe el fichero\n  os.remove(\"FedeAirala.txt\")                                   # Elimino el fichero si existe\nelse:\n  print(\"El archivo no existe\")                                 # Aviso de fichero inexistente\n\n\"\"\"\n\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n * archivo .txt.\n * - Cada producto se guarda en una línea del arhivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n \n \"\"\"\n\ntry:\n\n  def añadir():\n    nom_prod = input(\"Ingrese nombre del producto: \")\n    cant_venta= int(input(\"Cantidad vendida: \"))\n    precio = float(input(\"Ingrese precio: \"))\n\n    with open(productos, \"a\") as file:                          # abro el fichero y lo etiqueto con file\n      file.write(f\"{nom_prod}, {cant_venta}, {precio}\\n\")       # file.write escribe en el fichero las variables pasadas en el orden establecido\n   \n  def consultar():\n      nom_prod = input(\"Nombre: \")\n      with open(productos, \"r\") as file:                      # se abre el fichero en modo lectura y lo etiqueto con file\n        for line in file.readlines():                         # file.readlines lee la línea del fichero como una lista y recorre esa lista con for\n                if line.split(\", \")[0] == nom_prod:           # line.split convierte la cadena en una lista y pregunto si el elemento 0 es igual al ingresado para consulta\n                    print(line)                               # lo imprime en caso de encontrarlo\n                    break                                     # salgo del bucle en cuando encuentra el nombre, sino se recorre el bucle hasta leer todo el fichero\n        else:\n           print (\"Producto no encontrado\")\n\n           \n  def actualizar():\n    nom_prod = input(\"Nombre: \")                              # Ingreso producto que deseo actualizar\n    cant_venta= input(\"Cantidad: \")\n    precio = input(\"Precio: \")\n    with open(productos, \"r\") as file:                        # se abre fichero productos en modo lectura\n      lines = file.readlines()                                # en variable lines guardo leo y guardo las líneas del fichero\n    with open(productos, \"w\") as file:                        # se abre el fichero en modo escritura\n      for line in lines:                                      # se recorren las líneas \n        if line.split(\", \")[0] == nom_prod:                   # pregunta si la el nombre de la línea leída es igual al nombre a actualizar\n          file.write(f\"{nom_prod}, {cant_venta}, {precio}\\n\") # si es verdadero actuliza la línea\n        else:\n          file.write(line)                                    # sino la agrega\n  \n  def cantidad_total():\n    total = 0                                               # inicio variable para almacenar la suma total\n    with open(productos, \"r\") as file:                      # abro el fichero en modo lectura y lo etiqueto como file\n      for line in file.readlines():                         # se recorre el fichero por cada línea del mismo\n          producto = line.split(\", \")                       # creo una lista por cada línea del fichero\n          cantidad = int(producto[1])                       # a la variable cantidad se le asigna la cantidad leída en cada línea\n          precio = float(producto[2])                       # a la variable precio se le asigna el precio leído en cada línea\n          total += cantidad * precio                        # a la variable total se le va sumando el total de cada línea del fichero\n      print(total)                                          # se imprime la cantidad total de capital \n\n  def cantidad_producto():\n      nom_prod = input(\"Nombre: \")\n      total = 0                                             # inicio variable para almacenar el total del capital por producto\n      with open(productos, \"r\") as file:                    # abro el fichero en modo lectura y lo etiqueto como file\n        for line in file.readlines():                       # se recorre el fichero por cada línea del mismo\n          producto = line.split(\", \")                       # creo una variable en donde se almacena la lista de las líneas leídas del fichero\n          if producto[0] == nom_prod:                       # pregunto si el nombre ingresado es igual al nombre del producto de la línea del fichero\n            cantidad = int(producto[1])                     # si es igual a cantidad le asigno la cantidad leída en el fichero\n            precio = float(producto[2])                     # si es igual a precio le asigno el precio leído en el fichero\n            total += cantidad * precio                      # realizo la operación para saber el capital por el producto\n            break\n        print(total)                                        # se imprime el capital por producto\n\n  def listar_productos():\n    with open(productos, \"r\") as file:                      # se abre fichero productos en modo lectura\n     print(file.read() )                                    # se imprimen las líneas del fichero\n   \n\n  def eliminar():\n    nom_prod = input(\"Nombre: \")                            # Ingreso nombre de producto a eliminar\n    with open(productos, \"r\") as file:                      # leo el fichero en modo lectura\n      lines = file.readlines()                              # asigno a la variable lines la lista de líneas del fichero\n    with open(productos, \"w\") as file:                      # leo el fichero en modo escritura\n      for line in lines:                                    # recorro las líneas del fichero\n        if line.split(\", \")[0] != nom_prod:                 # pregunto si el producto a eliminar se encuantra en la línea\n           file.write(line)                                 # mientras el nombre sea distinto al que quiero eliminar se escribe nuevamente cada línea del fichero\n\n\n  def salir():\n    if os.path.exists(\"productos.txt\"):                     # Compruebo si existe el fichero\n      os.remove(\"productos.txt\")                            # Elimino el fichero si existe\n    else:\n     print(\"El archivo no existe\")                          # Se imprime en el caso de no existir el fichero\n  \n\n  # Creo el fichero\n     \n  productos = \"productos.txt\"\n  open(productos, \"a\")\n\n  while True:\n    accion = input(\"1. Añadir | 2.Consultar | 3.Actualizar | 4.Eliminar | 5.Cantidad vendida total | 6.Cantidad vendida por producto | 7. Listar productos | 8.Salir \")\n\n    if accion.isdigit():\n      accion = int(accion)\n\n      match accion:\n        case 1:\n            añadir()\n        case 2:\n            consultar()\n        case 3:\n            actualizar()\n        case 4:\n            eliminar()\n        case 5:\n            cantidad_total()\n        case 6:\n            cantidad_producto()\n        case 7:\n            listar_productos()\n        case 8:\n            salir()\n            break\n        case _:\n            print (\"La opción no es correcta\")\n\nexcept:\n   print (\"Error en la ejecución del programa\")"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/Gallitofast.py",
    "content": "#Manejo de ficheros\n#  * EJERCICIO:\n#  * Desarrolla un programa capaz de crear un archivo que se llame como\n#  * tu usuario de GitHub y tenga la extensión .txt.\n#  * Añade varias líneas en ese fichero:\n#  * - Tu nombre.\n#  * - Edad.\n#  * - Lenguaje de programación favorito.\n#  * Imprime el contenido.\n#  * Borra el fichero.\nimport os\nfichero = open(\"Gallitolobo.txt\",\"w+\")\nfichero.write(\"Jose Miguel Gallo Zuno\\n 23 años \\lenguaje:Python \")\nfichero = open(\"Gallitolobo.txt\",\"r\")\nprint (fichero.read)\nfichero.close\nif os.path.exists(\"Gallitolobo.txt\"):\n    os.remove(\"Gallitolobo.txt\")\nelse:\n    print(\"El archivo no existe\")\n\"\"\"-------------------------------------------------------\"\"\"\n#Dificultad extra\n\"\"\"\n* Desarrolla un programa de gestión de ventas que almacena sus datos en un \n * archivo .txt.\n * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n\"\"\"\n\n    \ntry:\n    def añadir():\n        nom_prod = input(\"Ingrese nombre del producto: \")\n        cant_venta= int(input(\"Cantidad vendida: \"))\n        precio = float(input(\"Ingrese precio: \"))\n        with open(productos, \"a\") as file:\n          file.write(f\"{nom_prod}, {cant_venta}, {precio}\\n\")       \n    def consultar():\n        nom_prod = input(\"Ingrese el nombre del producto\")\n        with open(productos,\"r\") as file:\n            for line in file.readlines():\n                if line.split(\", \")[0]== nom_prod:\n                    print(line)\n                    break\n                else:\n                    print(\"Producto no encontrado\")\n                            \n    def actualizar():\n        nom_prod = input(\"Ingrese el nombre del producto\")\n        cant_venta = input(\"Ingrese la cantidad vendida:\")\n        precio = input(\"Ingrese el precio\")\n        with open(productos,\"r\")as file:\n            lines= file.readlines\n        with open(productos,\"r\")as file:\n            for line in file.readlines():\n                if line.split(\", \")[0]==nom_prod:\n                    file.write(f\"{nom_prod}\", {cant_venta}, {precio})\n                else:\n                    file.write(line)\n    def cantidad_vendida_total():\n        pass\n        \n    def eliminar():\n        print(\"Eliminar\")\n        nom_prod= input(\"Ingrese el nombre del producto\")\n   \n    def cantidad_vendida_por_producto():\n        pass\n    def listar_prod():\n        pass\n\n    productos = \"productos.txt\"\n    open(productos, \"a\") \n    while True:\n        invar= input(\"1. Añadir | 2.Consultar | 3.Actualizar | 4.Eliminar | 5.Cantidad vendida total | 6.Cantidad vendida por producto | 7. Listar productos | 8.Salir \")\n        if invar.isdigit:\n            invar= int(invar)\n            match invar:\n                case 1:\n                    pass\n                case 2:\n                    pass\n                case 3:\n                    pass\n                case 4:\n                    pass\n                case 5:\n                    pass\n                case 6:\n                    pass\n                case 7:\n                    pass\n                case 8:\n                    break\n        else:\n            print(\"Tiene que ser un numero!!!\")        \nexcept:\n    print(\"Un error ha sucedido\")\n\n            \n    \n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/Gordo-Master.py",
    "content": "\"\"\"\nManejo de ficheros\n\"\"\"\n\nimport os\n\nwith open(\"./Gordo-Master.txt\", 'w') as f:\n    f.write(\"Mi nombre es Gordo-Master\\n\")\n    f.write(\"Tengo 29 años\\n\")\n\nwith open(\"./Gordo-Master.txt\", 'a') as f:\n    f.write(\"¡Mi lenguaje de programación favorito es Python!\")\n\nwith open(\"./Gordo-Master.txt\", 'r') as f:\n    text_1 = f.read()\n    print(text_1)\n\nos.remove(\"./Gordo-Master.txt\")\n\n\"\"\"\nEjercicio extra\n\"\"\"\n\ndef consult(item = \"all_list\", present = False):\n    \n    consult_list = {}  \n\n    with open(\"./ventas.txt\",\"r\") as f:\n\n        sell_list = f.readlines()\n\n        if item == \"all_list\":\n\n            for n,i in enumerate(sell_list):\n                consult_list[n] = i.split(\", \")\n                consult_list[n][2] = consult_list[n][2].rstrip(\"\\n\")\n                present = True\n            \n            if not present:\n                    print(\"No se registraron ventas...\")\n                    return None\n            \n            return consult_list\n        \n        else:\n\n            for n,i in enumerate(sell_list):\n                sell_list[n] = i.split(\", \")\n                if sell_list[n][0] == item:\n                    consult_list[n] = sell_list[n]\n                    consult_list[n][2] = consult_list[n][2].rstrip(\"\\n\")\n                    present = True\n            \n            if not present:\n                    print(\"No se encontro el producto...\")\n                    return None\n            \n            return consult_list\n    \ndef add_to_file(name, count, price):\n    \n    with open(\"./ventas.txt\", \"a\") as f:\n        add = \", \".join([name,count,price]) + \"\\n\"\n        f.write(add)\n\ndef del_item( item):\n    consult_list = consult(item)\n    all_list = consult()\n\n    if consult_list:\n\n        print(\"Elige la opción a eliminar: \")\n        \n        for i in consult_list:\n            print(f\"{i}. {consult_list[i][0]} , cant: {consult_list[i][1]}, pre: {consult_list[i][2]}\")\n\n        item_to_del = int(input(\"Numero: \"))\n        \n        if item_to_del in consult_list:\n            del all_list[item_to_del]\n        \n        else:\n            print(\"Valor invalido\")\n\n    f = open(\"./ventas.txt\", \"w\")\n    f.close()\n    \n    for i in all_list:\n        add_to_file(all_list[i][0],all_list[i][1],all_list[i][2])\n\ndef ref_item(item):\n    consult_list = consult(item)\n    all_list = consult()\n\n    if consult_list:\n\n        print(\"Elige la opción a actualizar: \")\n        \n        for i in consult_list:\n            print(f\"{i}. {consult_list[i][0]} , cant: {consult_list[i][1]}, pre: {consult_list[i][2]}\")\n\n        item_to_ref = int(input(\"Numero: \"))\n        \n        if item_to_ref in consult_list:\n            print(\"Actualizar producto\")\n            name = input(\"Ingrese nuevo nombre_producto: \")\n            count = input(\"Ingrese nueva cantidad_vendida: \")\n            price = input(\"Ingrese nuevo precio: \")\n            all_list[item_to_ref]=[name,count,price]\n\n        \n        else:\n            print(\"Valor invalido\")\n\n    f = open(\"./ventas.txt\", \"w\")\n    f.close()\n    \n    for i in all_list:\n        add_to_file(all_list[i][0],all_list[i][1],all_list[i][2])\n\ndef menu():\n\n    f = open(\"./ventas.txt\", \"w\")\n    f.close()\n\n    while True:\n        print(\"Gestor de ventas\".center(40,\"-\"))\n        print(\"1. Añadir.\".ljust(39),\"|\")\n        print(\"2. Consultar.\".ljust(39),\"|\")\n        print(\"3. Actualizar\".ljust(39),\"|\")\n        print(\"4. Eliminar\".ljust(39),\"|\")\n        print(\"5. Calcular ventas por productos\".ljust(39),\"|\")\n        print(\"6. Calcular ventas totales\".ljust(39),\"|\")\n        print(\"7. Salir\".ljust(39),\"|\")\n        print(\"-\"*40)\n        action = input(\"Opción: \")\n\n# [nombre_producto], [cantidad_vendida], [precio]\n        match action:\n            case '1':\n                print(\"Añadir producto\")\n                name = input(\"Ingrese el nombre_producto: \")\n                count = input(\"Ingrese la cantidad_vendida: \")\n                price = input(\"Ingrese el precio: \")\n                add_to_file(name,count,price)\n                \n            case '2':\n                item = input(\"Indique el producto a buscar: \")\n                consult_list = consult(item)\n                if consult_list:\n                    for i in consult_list:\n                        print(f\"{i}. {consult_list[i][0]} , cant: {consult_list[i][1]}, pre: {consult_list[i][2]}\")\n                \n            case '3':\n                item = input(\"Indique el producto a actualizar: \")\n                ref_item(item)\n                    \n\n            case '4':\n                item = input(\"Indique el producto que quiere eliminar: \")\n                del_item(item)\n\n            case '5':\n                item = input(\"Indique el producto del cual quiere calcular sus ventas totales: \")\n                consult_list = consult(item)\n                venta_totales = 0\n                for i in consult_list:\n                    venta_totales += float(consult_list[i][1]) * float(consult_list[i][2])\n                print(f\"Ventas totales de {item}: {venta_totales}\")\n            \n            case '6':\n                consult_list = consult()\n                venta_totales = 0\n                for i in consult_list:\n                    venta_totales += float(consult_list[i][1]) * float(consult_list[i][2])\n                print(f\"Ventas totales: {venta_totales}\")\n            \n            case '7':\n                print(\"Saliendo del programa...\")\n                os.remove(\"./ventas.txt\")\n                break\n            \n            case _:\n                print(\"Coloque un numero del 1 al 7...\")\n\nmenu()"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/Hyromy.py",
    "content": "nombre = \"Joel\"\nedad = 19\nlenguaje = \"Python\"\n\nlineas = [\n    f\"Nombre: {nombre}\\n\",\n    f\"Edad: {edad}\\n\",\n    f\"Lenguaje Fav: {lenguaje}\\n\"\n]\n\nfile_path = \"Roadmap/11 - MANEJO DE FICHEROS/python/Hyromy.txt\"\n\n# abrimos la ruta con permisos de escritura guardando como variable f\nwith open(file_path, \"w\") as f:\n    f.writelines(lineas) # escribimos las lineas en f\n    del lineas # borramos la variable lista\n\n# abrimos el archivo (por defecto tiene permisos de lectura)\nwith open(file_path) as f:\n    # leemos su contenido\n    data = f.readlines()\n\n# mostramos el contenido de la variable data\nprint(data)\n\nfor i in data: # iteramos cada linea\n    print(i)\n\nimport os\nos.remove(file_path) # eliminamos el archivo\n\n# ---- DIFICULTAD EXTRA ----\n\nclass Ventas:\n    def __init__(self):\n        self.path = \"Roadmap/11 - MANEJO DE FICHEROS/python/venta.txt\"\n        \n        with open(self.path, \"w\") as f:\n            f.write(\"\")\n\n    def create(self, producto:str, cantidad:int, precio:float):\n        with open(self.path, \"a\") as f:\n            f.write(f\"{producto}, {cantidad}, {precio}\\n\")\n\n    def read(self) -> list[str]:\n        with open(self.path) as f:\n            return f.readlines()\n\n    def update(self, producto:str, nuevo_producto:str = None, nueva_cantidad:int = None, nuevo_precio:float = None) -> bool:\n        file = self.read()\n\n        i = 0\n        for product in file:\n            if product[:len(producto)] == producto:\n                items = product.split(\", \")\n\n                if nuevo_producto == \"\":\n                    nuevo_producto = items[0]\n\n                if nueva_cantidad == -1:\n                    nueva_cantidad = items[1]\n                \n                if nuevo_precio == -1:\n                    nuevo_precio = items[2][:-2]\n        \n                break\n\n            i += 1\n\n        else:\n            return False\n        \n        file[i] = f\"{nuevo_producto}, {nueva_cantidad}, {nuevo_precio}\\n\"\n        with open(self.path, \"w\") as f:\n            f.writelines(file)\n\n        return True\n\n    def delete(self, producto) -> bool:\n        file = self.read()\n\n        i = 0\n        for product in file:\n            if product[:len(producto)] == producto:\n                break\n            \n            i += 1\n\n        else:\n            return False\n        \n        file.pop(i)\n        with open(self.path, \"w\") as f:\n            f.writelines(file)\n\n        return True\n    \nprint(\"GESTION DE VENTAS\\n\")\nventas = Ventas()\nwhile True:\n    print(\"(C) Añadir producto\\n\" +\n          \"(R) Consultar productos\\n\" +\n          \"(U) Actualizar producto\\n\" +\n          \"(D) Eliminar producto\\n\" +\n          \"(X) SALIR\")\n    opt = input(\" => \")\n\n    if opt.casefold() == \"c\":\n        nombre = input(\"Nombre del producto => \")\n        cantidad = int(input(f\"Cantidad de {nombre} => \"))\n        precio = float(input(f\"Precio de {nombre} => \"))\n\n        ventas.create(nombre, cantidad, precio)\n\n        print(\"\\nPRODUCTO AGREGADO\\n\")\n\n    elif opt.casefold() == \"r\":\n        items = ventas.read()\n        \n        print()\n        for item in items:\n            print(item[:-1])\n        print()\n    \n    elif opt.casefold() == \"u\":\n        nombre = input(\"Nombre del producto a actualizar => \")\n        nuevo_nombre = input(f\"Nuevo nombre para {nombre} (deja en blanco para no modificarlo) => \")\n\n        if nuevo_nombre == \"\":\n            nuevo_nombre = nombre\n\n        nueva_cantidad = int(input(f\"Nueva cantidad para {nuevo_nombre} (escribe -1 para no modificarlo) => \"))\n        nuevo_precio = float(input(f\"Nuevo precio para {nuevo_nombre} (escribe -1 para no modificarlo) => \"))\n\n        updated = ventas.update(nombre, nuevo_nombre, nueva_cantidad, nuevo_precio)\n        if updated:\n            print(\"\\nPRODUCTO ACTUALIZADO\\n\")\n        else:\n            print(\"\\nno se modifico porque el producto no existe xd\\n\")\n    \n    elif opt.casefold() == \"d\":\n        nombre = input(\"Producto a eliminar => \")\n        eliminado = ventas.delete(nombre)\n\n        if eliminado:\n            print(\"\\nPRODUCTO ELIMINADO\\n\")\n        else:\n            print(\"\\nNO ES POSIBLE ELIMINAR UN PRODUCTO INEXISTENTE\\n\")\n    \n    elif opt.casefold() == \"x\":\n        os.remove(ventas.path)\n        break\n\n    else:\n        print(\"\\nOPCION NO VALIDA\\n\")"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/Irenetitor.py",
    "content": "import os\n\n#Exercise\n\nfile_name = \"Irenetitor.txt\"\n\nwith open(file_name, \"w\") as file:\n    file.write(\"Irene Martin\\n\" + \"I am 33 years old\\n\" + \"My favourite language is Python\")\n\nwith open(file_name, \"r\") as file:\n    print(file.read())\n\nos.remove(file_name)\n\n\n#Extra Exercise\nwhile True:\n    print(\"1. Add product\")\n    print(\"2. View product\")\n    print(\"3. Update product\")\n    print(\"4. Delete product\")\n    print(\"5. Show product\")\n    print(\"6. Calculate total sales\")\n    print(\"7. Calculate sales by product\")\n    print(\"8. Exit\")\n\n    option = input(\"Select an option: \")\n\n    if option == \"1\":\n        name = input(\"Name: \")\n        quantity = input(\"Quantity: \")\n        price = input(\"Price: \")\n        with open(file_name, \"a\") as file:  # use \"a\" to append instead of overwriting\n            file.write(f\"{name}, {quantity}, {price}\\n\")\n    elif option == \"2\":\n        name = input(\"Name: \")\n        with open(file_name, \"r\") as file:\n            for line in file.readlines():\n                if line.split(\", \")[0] == name:\n                    print(line)\n                    break\n    elif option == \"3\":\n        name = input(\"Name: \")\n        quantity = input(\"Quantity: \")\n        price = input(\"Price: \")\n        with open(file_name, \"r\") as file:\n            lines = file.readlines()\n        with open(file_name, \"w\") as file:\n            for line in lines:\n                if line.split(\", \")[0] == name:\n                    file.write(f\"{name}, {quantity}, {price}\\n\")\n                else:\n                    file.write(line)\n    elif option == \"4\":\n        name = input(\"Name: \")\n        with open(file_name, \"r\") as file:\n            lines = file.readlines()\n        with open(file_name, \"w\") as file:\n            for line in lines:\n                if line.split(\", \")[0] == name:\n                    file.write(line)\n    elif option == \"5\":\n        with open(file_name, \"r\") as file:\n            print(file.read())\n    elif option == \"6\":\n        total = 0\n        with open(file_name, \"r\") as file:\n            for line in file.readlines():\n                components = line.split(\", \")[0]\n                quantity = int(components[1])\n                price = float(components[2])\n    elif option == \"7\":\n        pass\n    elif option == \"8\":\n        os.remove(file_name)\n        print(\"Exiting program...\")\n        break  # ⬅️ only break here\n    else:\n        print(\"Select one of the available options\")\n\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/JAFeito.py",
    "content": "\"\"\"\nEJERCICIO:\n Desarrolla un programa capaz de crear un archivo que se llame como\n tu usuario de GitHub y tenga la extensión .txt.\n Añade varias líneas en ese fichero:\n - Tu nombre.\n - Edad.\n - Lenguaje de programación favorito.\n Imprime el contenido.\n Borra el fichero.\n \n DIFICULTAD EXTRA (opcional):\n Desarrolla un programa de gestión de ventas que almacena sus datos en un \n archivo .txt.\n - Cada producto se guarda en una línea del archivo de la siguiente manera:\n   [nombre_producto], [cantidad_vendida], [precio].\n - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n   actualizar, eliminar productos y salir.\n - También debe poseer opciones para calcular la venta total y por producto.\n - La opción salir borra el .txt.\n \"\"\"\n \nimport os\n\nwith open(\"JAFeito.txt\",\"w\") as fichero:\n  fichero.write(\"Jose Angel\\n45\\nPython\")\n  \nwith open(\"JAFeito.txt\",\"r\") as fichero:\n  print(fichero.read())\nos.remove(\"JAFeito.txt\")\n\n#DIFICULTAD EXTRA\n\nopen(\"Archivo.txt\",\"a\")\n\ndef busca_prod(producto):\n  with open(\"Archivo.txt\",\"r\") as archivo:\n      for line in archivo.readlines():\n        if line.split(\", \")[0] == producto:\n          return line\n      return \"El producto no esta en la lista.\"\n    \ndef cargar():\n  with open(\"Archivo.txt\",\"r\") as archivo:\n    buffer = archivo.readlines()\n  return buffer\n\nrepetir = True    \nwhile repetir:\n  eleccion = input(\"\"\"Seleccione la opcion que desee escribiendo el numero correspondiente:\n    1- Añadir producto.\n    2- Consultar producto.\n    3- Actualizar producto.\n    4- Borrar producto.\n    5- Ventas totales.\n    6- Ventas por producto.\n    7- Salir.\\n\"\"\")\n  if eleccion == \"1\":\n    \n    print(\"Introduzca los siguientes datos:\")\n    nombre = input(f\"Nombre del articulo:\")\n    cantidad = input(\"Cantidad:\")\n    precio = input(\"Precio del articulo:\")\n    with open(\"Archivo.txt\",\"a\") as archivo:\n      archivo.write(f\"{nombre}, {cantidad}, {precio}\\n\")\n    \n  elif eleccion == \"2\":\n    \n    producto = input(\"Introduzca el nobre del producto que desea consultar:\")\n    print(busca_prod(producto))\n          \n  elif eleccion == \"3\":\n    \n    producto = input(\"Introduzca el nombre del producto que desea actualizar:\")\n    buffer = cargar()\n    with open(\"Archivo.txt\",\"w\") as archivo:\n      for i in buffer:\n        if i.split(\", \")[0] == producto:\n          print(f\"Introduzca los los nuevos datos para el articulo {producto}:\")\n          nombre = input(\"Nombre del articulo:\")\n          cantidad = input(\"Cantidad:\")\n          precio = input(\"Precio del articulo:\")\n          archivo.write(f\"{nombre}, {cantidad}, {precio}\\n\")\n        else:\n          archivo.write(i)\n      \n    \n  elif eleccion == \"4\":\n    producto = input(\"Introduzca el nombre del producto que desea eliminar:\")\n    buffer = cargar()\n    with open(\"Archivo.txt\",\"w\") as archivo:\n      for i in buffer:\n        if i.split(\", \")[0] != producto:\n          archivo.write(i)\n        \n    \n  elif eleccion == \"5\":\n    total = 0\n    buffer = cargar()\n    for i in buffer:\n      datos = i.split(\", \")\n      cantidad = int(datos[1])\n      precio = float(datos[2])\n      total += cantidad * precio\n    print(f\"{total}€\")\n    \n  elif eleccion == \"6\":\n    producto = input(\"Introduzca el nombre del producto que desea consultar:\")\n    encontrado = busca_prod(producto)\n    print(f\"{int(encontrado.split(\", \")[1]) * float(encontrado.split(\", \")[2])}€\")\n    \n  elif eleccion == \"7\":\n    os.remove(\"Archivo.txt\")\n    repetir = False\n  else:\n    print(\"El valor introducido no es correcto\")\n    \n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/Jav-mol.py",
    "content": "# --- 11-Manejo de Ficheros ---\n# --- Javier Molina ---\n\n# Crear Fichero\nwith open('Jav-mol.txt', 'w') as file:\n    name = input('Ingrese su nombre: ')\n    age = input('Ingrese su edad: ')\n    language = input('Ingrese su lenguaje favorito: ')\n    \n    file.write(f'Name: {name} \\nAge: {age} \\nFavorite Language: {language}')\n    print(f'Name: {name} \\nAge: {age} \\nFavorite Language: {language}')\n\n# Borrar Fichero\nimport os\nfile = 'Jav-mol.txt'\n\nif os.path.exists(file):\n    os.remove(file)\n\n        \n# --- Extra ---\n\nimport os\nindex = None\ncaracteres = lambda:print('-'*25)\n\ndef delete_file():\n    file = 'Jav-mol.txt'\n    if os.path.exists(file):\n        #os.remove(file)\n        pass\n    return True\n\ndef add_product():\n    \n    with open('Jav-mol.txt', 'a+') as file:\n        \n        caracteres()\n        product = input('Ingrese el producto: ')\n        stock = input('Ingrese la cantidad: ')\n        precio = input('Ingrese el precio: ')\n        caracteres()\n        \n        file.write(f'[{product}], [{stock}], [${precio}]' + '\\n')\n\n\ndef listening_product():\n    with open('Jav-mol.txt', 'r') as file:\n        texto = file.read()\n        caracteres()\n        print(texto)\n        caracteres()\n        \nlist_to_str = lambda lista:f'{lista[0]}, {lista[1]}, {lista[2]}'\ndef update_product(products, index, lista):\n        total = input('Ingrese la cantidad vendida: ')\n        products[1] = f'[{total}]'\n        price = input('Ingrese el precio: ')\n        products[2] = f'[${price}]'\n        \n        lista_str_products = list_to_str(products)\n        lista[index] = lista_str_products\n        \n        print(lista_str_products)\n        caracteres() \n        return lista \n        \ndef edit_product():    \n    with open('Jav-mol.txt', 'r') as file:\n        texto = file.read()\n        text_list = texto.split('\\n')\n        lista_final = None\n        \n        caracteres()\n        product = input('Ingrese el producto: ')\n        \n        for num, lista in enumerate(text_list):\n            if product in lista:\n                index = num\n                products = lista.split(', ')\n\n                lista_final = update_product(products, index, text_list)\n            \n        if not lista_final:\n            print('Producto no encontrado')\n            caracteres()\n        else:            \n            with open('Jav-mol.txt', 'w') as file:\n                for produc in lista_final:\n                    if produc == '':\n                        continue\n                    file.write(f'{produc}\\n')\n\ndef delete_product():\n    with open('Jav-mol.txt', 'r') as file:\n        texto = file.read()\n        text_list = texto.split('\\n')\n        product = input('Ingrese el producto: ')\n        \n        for num, lista in enumerate(text_list):\n            if product in lista:\n                index = num\n        \n        if index >= 0:\n            deleted = text_list.pop(index)\n            print(deleted)\n            with open('Jav-mol.txt', 'w') as file:\n                for produc in text_list:\n                    if produc == '':\n                        continue\n                    file.write(f'{produc}\\n')\n            caracteres()\n                    \n        else:\n            print('Producto no encontrado')\n            caracteres()\n\n\ndelete_caract = lambda x: int(x.replace('[', '').replace(']', '').replace('$', ''))\ndef ventas_por_producto():    \n    with open('Jav-mol.txt', 'r') as file:\n        texto = file.read()\n        text_list = texto.split('\\n')\n        \n        caracteres()\n        product = input('Ingrese el producto: ')        \n        \n        for lista in text_list:\n            if product in lista:\n                products = lista.split(', ')\n\n                venta_total = delete_caract(products[1]) * delete_caract(products[2])\n        print(f'${venta_total}')\n        caracteres()\n\n\n\ndef ventas_total():    \n    with open('Jav-mol.txt', 'r') as file:\n        texto = file.read()\n        text_list = texto.split('\\n')\n        venta_total = 0\n        \n        for lista in text_list:\n            if lista:\n                products = lista.split(', ')\n\n                venta_total += delete_caract(products[1]) * delete_caract(products[2])\n\n        caracteres()        \n        print(venta_total)\n        caracteres()\n\nmenu = \"\"\"1-Agregar Producto\n2-Listar Productos\n3-Actualizar Producto\n4-Eliminar Producto\n5-Venta por Producto\n6-Venta Total\n> \"\"\"\n\nfunctions = {\n    '1':add_product,\n    '2':listening_product,\n    '3':edit_product,\n    '4':delete_product,\n    '5':ventas_por_producto,\n    '6':ventas_total\n}\n\nwhile True:\n    options = input(menu)\n    \n    option = functions.get(options, delete_file)\n\n    if option():\n        break"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/JesusWay69.py",
    "content": "import os\nos.system('cls')\n\n\n\"\"\"\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n *\n \n\"\"\"\n\n\n#Asignando a una variable la sentencia open() y pasándole como argumentos el nombre del archivo\n# y la letra \"w\" generamos el mismo y nos permite escribir en él\nfile=open(\"JesusWay69.txt\", \"w\")\nfile.write(\"Jesus\\n\") #Con el método .write escribimos en archivo creado antes de cerrarlo.\nfile.write(\"99\\n\")\nfile.write(\"Python\\n\")\nfile.close()# Con el método .close() cerramos el archivo, si lo volvemos a abrir con \"w\" se vuelve a generar vacío\n# o lo que es lo mismo borra todo el contenido.\n\nfile=open(\"JesusWay69.txt\", \"r\")# Con \"r\" nos permite leer todo el contenido del archivo\nreadfile = file.read()# asignando a una variable el método .read que devuelve el contenido en un string.\nfile.close\nprint(readfile)\n\nwith open(\"JesusWay69.txt\", \"a\") as file:#Abriéndolo con with el archivo se cierra automáticamente \n  file.write(\"linea nueva añadida\\n\")# cuando termine el bloque de código tabulado.\nwith open(\"JesusWay69.txt\", \"r\") as file:\n  readfile = file.read()\nprint(readfile)\n\nfile = open(\"JesusWay69.txt\", \"r+\")#Con \"r+\" nos permite leer y añadir contenido al fichero de una vez\n#También existe el parámetro \"w+\" que nos permite leer y escribir pero al igual que con \"w\" con la llamada\n# a .write() se \"autogenera\" de nuevo el fichero existente borrando el contenido o crea uno nuevo si no existe\n# permitiendo leerlo tambien despues de generarlo y antes de cerrarlo.\nreadfile = file.read()\nfile.write(\"otra linea nueva añadida\\n\")\nreadfile = file.read()\nfile.close\nprint(readfile)\nprint(\"\\n\")\n\n#El método .readline() nos devuelve el contenido de todo el fichero en un string o, si le pasamos\n# un número nos devolverá la línea correspondiente empezando por la 1 y descartando la 0 (dará fallo si la línea está vacía)\n#El método .readlines() nos devolverá una lista de strings conteniendo cada línea como un elemento de la misma.\n\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n * archivo .txt.\n * - Cada producto se guarda en una línea del arhivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n\n\"\"\"\n\ndef create(file):\n    try:\n        file = open (file, \"x\")\n        file.write(\"PRODUCTO , UDS VENDIDAS, PRECIO\\n\")\n        file.close()\n    except:\n        print(f\"El fichero \\\"{file}\\\" ya existe\")\n   \n   \ndef add(file,producto, cantidad, precio):\n    file = open(file,\"a\")\n    file.write(f\"{producto}, {cantidad}, {precio}\\n\")\n    file.close\n\ndef show_all(file): \n     file = open(file, \"r\")\n     content = file.read()\n     \n     print(content)\n\ndef find(file, substring:str):\n    if not substring.isdigit():\n        product_list =[]\n        line_num = 0\n        file =  open(file, 'r+')\n        line = file.readline()\n        for line in file:\n            line_num +=1\n            if substring in line:\n                line = str(line_num) + \"- \" + line\n                product_list.append(line)\n                continue\n            elif substring not in line:\n                continue\n    else:\n        print(\"La búsqueda de un producto no se puede hacer con valores numéricos únicamente\")\n    if len(product_list)>0:\n                  print(f\"Productos encontrados que contienen el nombre \\\"{substring}\\\":\\n\")\n                  for i in product_list:\n                      print(i)\n                  file.close()\n                  return True, product_list\n    else:\n        print(\"Artículo no encontrado\\n\")\n        return False, product_list\n        \n\nprint (\"\"\"\nElija una opción:\n1-Crear nuevo archivo\n2-Mostrar contenido de un archivo por consola\n3-Añadir producto\n4-Editar producto\n5-Calcular ventas totales \n6-Calcular ingresos y ventas por producto\n7-Eliminar producto\n8-Eliminar archivo y salir\n \n       \"\"\")\noption = input(\"Introduzca una opción del 1 al 7: \")\nif option == \"1\":\n    file = input (\"Escriba el nombre del archivo que desea crear con su extensión: \")\n    create(file)\n    print(f\"El fichero \\\"{file}\\\" se ha creado correctamente\")\n\nif option == \"2\":\n    while True:\n        file = input(\"Introduzca el nombre del fichero cuyo contenido quiera ver: \")\n        if not os.path.isfile(file):\n            print(f\"El archivo {file} no existe\")\n        else:\n            print(f\"\\nContenido del fichero \\\"{file}\\\":\\n\")\n        show_all(file)\n        break\n\nif option == \"3\":\n while True:\n    file = input(\"Introduzca el nombre del fichero donde añadir datos: \")\n    if not os.path.isfile(file):\n        print (f\"El archivo {file} no existe\")\n        continue   \n    product = input(\"Introduzca el nombre del producto: \").title()\n    sales = input(\"Introduzca la cantidad de uds vendidas: \")\n    price = input(\"Introduzca el precio por unidad: \")\n    if not sales.isdigit() or not price.isdigit():\n        print(\"ERROR: los campos 'ventas' y 'precio' deben ser valores numéricos, intente de nuevo\")\n    else:\n    \n        add(file, product, sales, price)\n        print(f\"El producto \\\"{product}\\\" con {sales} uds vendidas y valor de {price}€/ud se ha añadido al fichero {file}\")\n        break\n\nif option == \"4\":\n    while True:\n        file = input (\"Escriba el nombre del fichero donde buscar: \")\n        if not os.path.isfile(file):\n            print (f\"El archivo {file} no existe\")\n            continue\n        product = input(\"Escriba la marca y/o el modelo del producto que busca: \").title()\n        if find(file, product):\n          line = int(input(\"Introduzca el número del producto que desea editar: \"))\n          column =int(input(\"Introduzca el número del campo que desea editar, 1-Producto , 2-Uds vendidas o 3-Precio: \"))\n          new_data = input(\"Introduzca el nuevo dato: \")\n          content = []\n          with open(file, 'r+') as file1:\n              content = file1.readlines()\n              columns = content[line].split(\", \")\n              columns[column-1] = new_data\n              content[line] = \", \".join(columns)\n          with open(file, 'w') as file1:\n            file1.writelines(content)\n          break\n\nif option == \"5\":\n    file = input (\"Escriba el nombre del fichero del cual desee calcular las ventas totales: \")\n    with open(file, 'r+') as file:\n            content = file.readlines()\n            acc = 0\n            for i in range (1,(len(content))):\n                element = content[i]\n                column = element.split(\", \")\n                sales = int(column[1])\n                acc += sales\n            print(f\"Las uds totales vendidas de todos los productos es: {acc}\")  \n\nif option == \"6\":\n    file = input (\"Escriba el nombre del fichero sobre el que quiera hacer la consulta: \")\n    product = input(\"Escriba la marca y/o el modelo del producto que busca: \").title()\n    result_tuple = find (file, product)\n    if result_tuple[0] == True:\n        my_elements = result_tuple[1]\n        total,result,total_sales = 0, 0, 0\n        for elements in my_elements:\n            elements = str(elements)\n            columns = elements.split(\", \")\n            quantity = columns[1]\n            unit_price = columns[2]\n            result = int(quantity) * int(unit_price)\n            total_quantity = int(quantity)\n            total_sales += total_quantity\n            total += result        \n        print (f\"El total de artículos vendidos con nombre \\'{product}\\' es de  {total_sales} uds\")\n        print (f\"La suma total de dinero ingresado por las ventas de los productos con nombre \\'{product}\\' es de: {total}€\")\n\n   \n\nif option == \"7\":\n    while True:\n        file = input (\"Escriba el nombre del fichero donde buscar: \")\n        if not os.path.isfile(file):\n            print (f\"El archivo {file} no existe\")\n            continue\n        product = input(\"Escriba la marca y/o el modelo del producto que busca: \").title()\n        result_tuple = find (file, product)\n        if result_tuple[0] == True:\n          try:\n            line = int(input(\"Introduzca el número del producto que desea borrar: \"))\n          except:\n              print(\"Sólo se pueden introducír números\")\n              continue\n      \n        file1 = open(file , \"r+\")\n        lines = file1.readlines()\n        if line <1 or line > len(lines):\n            print(f\"el número {line} no pertenece a ningún producto\")\n        else:\n          line = lines[line]\n          lines.remove(line)\n          line.replace(\"\\n\", \"\")\n          print(f\"El artículo {line} ha sido eliminado\")\n        file1.close()\n        file1 = open (file, \"w\")\n        for line in lines:\n            file1.write(line)\n        break\n\nif option == \"8\":\n    while True:\n        file = input (\"Escriba el nombre del fichero a eliminar o exit para salir sin borrar: \")\n        if os.path.isfile(file):\n            confirmed = input(f\"\"\"¿Seguro que quiere eliminar el fichero \\\"{file}\\\"? \n  pulse enter para confirmar o escriba cualquier cosa para salir sin borrar: \"\"\")\n            if confirmed == \"\":\n                os.remove(file)\n                print(f\"El fichero {file} se ha eliminado con éxito, fin del programa.\")\n                break\n            else:\n                print(\"Fin del programa.\") \n                break\n        elif file == \"exit\":\n            print(\"Fin del programa.\")\n            break\n        else:\n            print(f\"El fichero {file} no existe, pruebe de nuevo\\n\")"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/JheisonQuiroga.py",
    "content": "import os\n\ntext = \"\"\"Jheison Duban Quiroga Quintero\n26\nPython\"\"\"\n\nwith open(\"JheisonQuiroga.txt\", \"w\") as f:\n    f.write(text)\n    \nfile = \"JheisonQuiroga.txt\"\n\nwith open(file) as f:\n    if os.path.exists(\"./JheisonQuiroga.txt\"):\n        text = f.read()\n        print(text)\n    else:\n        print(\"The file is not exists\")\n\n\n\"\"\" Extra \"\"\"\n\nmy_file = \"sells.txt\"\nproducts = []\n\n\ndef add_product(name:str, sell_total:int, price:int):\n    if not os.path.exists(my_file):\n        with open(my_file, \"x\") as file:\n            file.write(f\"{name}, {sell_total}, {price}\\n\")\n            products.append({\n                \"name\": name,\n                \"sell_total\": sell_total,\n                \"price\": price\n            })\n    else:\n        with open(my_file, \"a\") as file:\n            file.write(f\"{name}, {sell_total}, {price}\\n\")\n            products.append({\n                \"name\": name,\n                \"sell_total\": sell_total,\n                \"price\": price\n            })\n\n\ndef get_info():\n    print(\"-\" * 5, \"Inventario\", \"-\" * 5)\n    for dct in products:\n        print(f\"{dct['name']}, {dct['sell_total']}, {dct['price']}\")\n\n\ndef update(name, new_item_sell, new_price):\n    with open(my_file, \"w\") as file:\n        for product in products:\n            if product[\"name\"] == name:\n                product[\"sell_total\"] = new_item_sell\n                product[\"price\"] = new_price\n            file.write(f\"{product[\"name\"]}, {product[\"sell_total\"]}, {product[\"price\"]}\\n\")\n\ndef remove_products(name):\n    global products # Para asegurarme de borrar la lista original\n\n    filter_products = [product for product in products if product[\"name\"] != name]\n\n    products = filter_products\n    # Sobreescribe el archivo con los productos filtrados\n    with open(my_file, \"w\") as file:\n        for product in products:\n            file.write(f\"{product['name']}, {product['sell_total']}, {product['price']}\\n\")\n\ndef get_product():\n    name = input(\"Nombre del producto: \")\n    item_sell = int(input(\"Total de ventas: \"))\n    price = int(input(\"Precio: \"))\n    return name, item_sell, price\n\ndef sales_calculate():\n    global products\n    total_sales = 0\n    for product in products:\n        total_sale_per_product = product[\"sell_total\"] * product[\"price\"]\n        total_sales += total_sale_per_product\n\n    return total_sales\n\ndef remove_file(): # Funcion para borrar archivo al salir\n    if os.path.exists(my_file):\n        os.remove(my_file)\n        print(\"El archivo ha sido borrado!\")\n\n\ndef main():\n\n    while True:\n        option = int(input(\"\"\"----- Sistema de Gestión de ventas -----\n        1. Agregar producto\n        2. Consultar inventario\n        3. Actualizar\n        4. Eliminar producto\n        5. Total ventas\n        6. Venta por producto\n        7. Salir\n        Elige una opcion: \"\"\"))\n\n        match option:\n            case 1:\n                name, item_sell, price = get_product()\n                add_product(name, item_sell, price)\n            case 2:\n                get_info()\n            case 3:\n                name, item_sell, price = get_product()\n                update(name, item_sell, price)\n            case 4:\n                name = input(\"Ingrese el nombre del producto a eliminar\")\n                remove_products(name)\n            case 5:\n                print(sales_calculate())\n            case 6:\n                name = input(\"Nombre del producto: \")\n                with open(my_file, \"r\") as file:\n                    for line in file.readlines():\n                        components = line.split(\", \")\n                        if name == components[0]:\n                            quantity = int(components[1])\n                            price = int(components[2])\n                            total = quantity * price\n                            print(total)\n                            break\n                        \n            case 7:\n                remove_file()\n                print(\"Saliendo del programa...\")\n                return\n\n\nmain()"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/JuanDAW37.py",
    "content": "\"\"\"* IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n * archivo .txt.\n * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\"\"\"\nimport os\n\nfichero = 'JuanDAW37.txt'\n\nf = open(fichero, 'w') # Abro el fichero en modo escritura\nf.write('Juan Jesús Tenreiro Rodríguez\\n56\\nJavaScript')\n\nf = open(fichero) # Abro el fichero en modo lectura, por omisión\nfor linea in f:\n    print(linea, end='')\n\nf.close() #Cierro el flujo de escritura para poder borrar el fichero     \nos.remove(fichero) # Borro el fichero\n\n# EXTRA\n\ndef gestion_ventas():\n    fichero = 'JuanDAW37.txt'        \n    while True:\n        print('\\n********GESTION DE VENTAS*******')\n        print('[A/a]ñadir producto')\n        print('[C/c]onsultar producto')\n        print('[M/m]modificar producto')\n        print('[E/e]liminar producto')\n        print('[T/t]Calcular venta total')\n        print('[P/p]Calcular venta por producto')\n        print('[S/s]alir')\n        print('********************************')\n        opc = str(input('Pulsa en la operación deseada 👉 -> '))\n        match opc:\n            case 'A' | 'a':\n                anadir(fichero)                \n            case 'C' | 'c':\n                consultar(fichero)                \n            case 'M' | 'm':\n                modificar(fichero)                \n            case 'E' | 'e':\n                eliminar(fichero)                \n            case 'T' | 't':\n                ventaTotal(fichero)                \n            case 'P' | 'p':\n                ventaProducto(fichero)\n            case 'S' | 's':                \n                try:\n                    os.remove(fichero)\n                    break\n                except:\n                    print('No se puede eliminar el fichero de ventas porque no existe!!!')\n                    break\n            case _:\n                print('Opción no válida')\n                \ndef anadir(fichero):\n    nombre = str(input('Nombre del producto-> '))\n    cantidad = input('Cantidad de productos-> ')\n    precio = input('Precio del producto-> ')    \n    f = open(fichero, 'a')\n    f.write(f'{nombre}; {cantidad}; {precio}\\n')\n    f.close()\n\ndef consultar(fichero):\n    nombre = str(input('Nombre del producto-> '))\n    for  linea in open(fichero, 'r'):\n        if nombre in linea:\n            print(linea)\n    \ndef modificar(fichero):    \n    nombre = str(input('Nombre del producto-> '))\n    cantidad = input('Precio del producto-> ')\n    precio = input('Precio del producto-> ')\n    with open(fichero, 'r') as f:\n        lineas = f.readlines() # Guardo los datos del fichero\n    with open(fichero, 'w') as f: # Al abrir el fichero en modo escritura, borro el fichero\n        for linea in lineas: # Se recorre todo el fichero, buscando el nombre del producto\n            if linea.split('; ')[0] == nombre:\n                f.write(f'{nombre}; {cantidad}; {precio},\\n') # Si encuentra el nombre, modifica la línra\n            else:\n                f.write(linea) # Si no coincide con el nombre, conserva la línea\n\ndef ventaTotal(fichero):\n    total = 0\n    with open(fichero, 'r') as f:\n        for linea in f.readlines():\n            campos = linea.strip().split('; ')\n            cantidad = campos[1]            \n            precio = campos[2]            \n            total += int(cantidad) * float(precio)\n    print(total)\n\ndef ventaProducto(fichero):\n    nombre = str(input('Nombre del producto-> '))\n    total = 0\n    with open(fichero, 'r') as f:\n        for linea in f.readlines():\n            if nombre in linea:\n                campos = linea.strip().split('; ')\n                cantidad = campos[1]            \n                precio = campos[2]            \n                total += int(cantidad) * float(precio)\n    print(total)\n\ndef eliminar(fichero):\n    nombre = str(input('Nombre del producto-> '))\n    with open(fichero, 'r') as f:\n        lineas = f.readlines() # Guardo los datos del fichero\n    with open(fichero, 'w') as f: # Al abrir el fichero en modo escritura, borro el fichero\n        for linea in lineas: # Se recorre todo el fichero, buscando el nombre del producto\n            if linea.split('; ')[0] != nombre:\n                f.write(linea) # Aquellas líneas que no coincidan con el nombre de producto, las conserva\n\ngestion_ventas()"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/LucasRebuffo.py",
    "content": "\"\"\" /*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n * archivo .txt.\n * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n */ \"\"\"\n\nimport os\n\n\"\"\" Ejercicio \"\"\"\n\n# file_name = \"LucasRebuffo.txt\"\n\n\n# with open(file_name, \"w\") as file:\n#     file.write(f\"Lucas Rebuffo \\n\")\n#     file.write(f\"27 \\n\")\n#     file.write(f\"Python \\n\")\n\n# with open(file_name, \"r\") as file:\n#     print(file.read())\n\n# os.remove(file_name)\n\n\n\"\"\" * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n * archivo .txt.\n * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n */  \"\"\"\n\nfile_name = \"Ventas.txt\"\n\n\nwhile True:\n    print(\"1. Agregar producto\")\n    print(\"2. Comsultar producto\")\n    print(\"3. Actualizar producto\")\n    print(\"4. Eliminar producto\")\n    print(\"5. Mostrar inventario\")\n    print(\"6. Calcular venta total\")\n    print(\"7. Calcular venta por producto\")\n    print(\"8. Salir\")\n    print(\"\")\n\n    operacion = input(\"Elige una opcion\\n\")\n\n    match operacion:\n        case \"1\":\n            name = input(\"Nombre: \")\n            quantity = input(\"Cantidad: \")\n            price = input(\"Precio: \")\n\n            with open(file_name, \"a\") as file:\n                file.write(f\"{name},{quantity},{price}\\n\")\n\n        case \"2\":\n            name = input(\"Nombre: \")\n            with open(file_name, \"r\") as file:\n                for line in file.readlines():\n                    if line.split(sep=\",\")[0] == name:\n                        print(f\"--> {line}\")\n\n        case \"3\":\n            name = input(\"Nombre: \")\n            quantity = input(\"Cantidad: \")\n            price = input(\"Precio: \")\n            with open(file_name, \"r\") as file:\n                lines = file.readlines()\n\n            with open(file_name, \"w\") as file:\n                for line in lines:\n                    if line.split(sep=\",\")[0] == name:\n                        file.write(f\"{name},{quantity},{price}\\n\")\n                    else:\n                        file.write(line)\n\n        case \"4\":\n\n            name = input(\"Nombre: \")\n\n            with open(file_name, \"r\") as file:\n                lines = file.readlines()\n\n            with open(file_name, \"w\") as file:\n                for line in lines:\n                    if line.split(sep=\",\")[0] != name:\n                        file.write(line)\n\n        case \"5\":\n            print(\"---------------------------------------\")\n            with open(file_name, \"r\") as file:\n                print(file.read())\n            print(\"---------------------------------------\\n\")\n        case \"6\":\n\n            with open(file_name, \"r\") as file:\n                lines = file.readlines()\n\n            total: float = 0\n            for line in lines:\n                if line != \"\\n\":\n                    line = line.split(sep=\",\")\n                    total += float(line[1]) * float(line[2])\n\n            print(f\"--> El total de ventas es {total}\\n\")\n\n        case \"7\":\n\n            with open(file_name, \"r\") as file:\n                lines = file.readlines()\n\n            sub_totales: dict = {}\n            for line in lines:\n                if line != \"\\n\":\n                    line = line.split(sep=\",\")\n                    sub_totales[line[0]] = float(line[1]) * float(line[2])\n            print(\"Los subtotales son: \")\n            for (prod,subtotal) in sub_totales.items():\n                print(f\"{prod}: {subtotal}\")\n            print(\"\\n\")\n\n        case \"8\":\n            os.remove(file_name)\n            break\n        case _:\n            print(\"No corresponde a ninguna operacion.\")\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/Lumanet.py",
    "content": "import os\n\nfile_name = \"Lumanet.txt\"\nos.system(\"clear\") # Limpiar terminal\nwith open(file_name, \"w\") as file: # Crear archivo si no existe\n    file.write(\"Marcos\\n\")\n    file.write(\"42\\n\")\n    file.write(\"Python\")\n\nwith open(file_name, \"r\") as file:\n    print(file.read())\n\nos.remove(file_name)\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\nDesarrolla un programa de gestión de ventas que almacena sus datos en un \narchivo .txt.\n- Cada producto se guarda en una línea del archivo de la siguiente manera:\n  [nombre_producto], [cantidad_vendida], [precio].\n- Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n  actualizar, eliminar productos y salir.\n- También debe poseer opciones para calcular la venta total y por producto.\n- La opción salir borra el .txt.\n\"\"\"\nos.system(\"clear\") # Limpiar terminal\nfile_name = \"tienda.txt\"\n\nopen(file_name, \"a\") # Crear archivo si no existe\nos.system(\"clear\") # Limpiar terminal\n\nwhile True:\n    print(\"1. Añadir producto\")\n    print(\"2. Consultar producto\")\n    print(\"3. Actualizar producto\")\n    print(\"4. Borrar producto\")\n    print(\"5. Mostrar productos\")\n    print(\"6. Calcular venta total\")\n    print(\"7. Calcular venta por producto\")\n    print(\"8. Salir\")\n\n    option = input(\"Selecciona una opción: \")\n\n    if option == \"1\":\n        nombre = input(\"Nombre: \")\n        cantidad = input(\"Cantidad: \")\n        precio = input(\"Precio: \")\n        with open(file_name, \"a\") as file:\n            file.write(f\"{nombre}, {cantidad}, {precio}\\n\")\n    elif option == \"2\":\n        nombre = input(\"Nombre: \")\n        with open(file_name, \"r\") as file:\n            for line in file.readlines():\n                if line.split(\", \")[0] == nombre:\n                    print(line)\n                    break\n    elif option == \"3\":\n        nombre = input(\"Nombre: \")\n        cantidad = input(\"Cantidad: \")\n        precio = input(\"Precio: \")\n        with open(file_name, \"r\") as file:\n            lines = file.readlines()\n        with open(file_name, \"w\") as file:\n            for line in lines:\n                if line.split(\", \")[0] == nombre:\n                    file.write(f\"{nombre}, {cantidad}, {precio}\\n\")\n                else:\n                    file.write(line)\n    elif option == \"4\":\n        nombre = input(\"Nombre: \")\n        with open(file_name, \"r\") as file:\n            lines = file.readlines()\n        with open(file_name, \"w\") as file:\n            for line in lines:\n                if line.split(\", \")[0] != nombre:\n                    file.write(line)\n    elif option == \"5\":\n        with open(file_name, \"r\") as file:\n            print(file.read())\n    elif option == \"6\":\n        total = 0\n        with open(file_name, \"r\") as file:\n            for line in file.readlines():\n                elemento = line.split(\", \")\n                cantidad = int(elemento[1])\n                precio = float(elemento[2])\n                total += cantidad * precio\n        print(total)\n    elif option == \"7\":\n        nombre = input(\"Nombre: \")\n        total = 0\n        with open(file_name, \"r\") as file:\n            for line in file.readlines():\n                elemento = line.split(\", \")\n                if elemento[0] == nombre:\n                    cantidad = int(elemento[1])\n                    precio = float(elemento[2])\n                    total += cantidad * precio\n                    break\n        print(total)\n    elif option == \"8\":\n        os.remove(file_name)\n        break\n    else:\n        print(\"Selecciona una de las opciones disponibles.\")\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/NeosV.py",
    "content": "import os\n\nnombre_archivo = \"NeosV.txt\"\n\nwith open(nombre_archivo, \"w\") as file:\n     file.write(\"Andres\\n\")\n     file.write(\"22\\n\")\n     file.write(\"Python\\n\")\n     \n     \nwith open(nombre_archivo, \"r\") as file:\n     print(file.read())\n\n\nos.remove(nombre_archivo)     \n\nnombre_tienda = \"Negocio.txt\"\n\nopen(nombre_tienda, \"a\")\nwhile True:\n          \n          \n          print(\"1. Añadir Producto\")\n          print(\"2. Consultar Producto\")\n          print(\"3. Actualizar Producto\")\n          print(\"4. Borrar Producto\")\n          print(\"5. Calcular Venta Total\")\n          print(\"6. Calcular Venta por Producto\")\n          print(\"7. Mostrar Productos\")\n          print(\"8. Salir\")\n          \n          \n          accion = input(\"Por favor ingrese la accion que desea realizar: \")\n\n\n          if accion == \"1\":\n              \n              nombre = input(\"Ingresa el Nombre del producto: \")\n              cantidad = input(\"Ingresa la cantidad del producto: \")\n              precio = input(\"Ingresa el precio unitario: \")\n\n              with open(nombre_tienda, \"a\") as file:\n                   file.write(f\"{nombre}, {cantidad}, {precio}\\n\")\n               \n          elif accion == \"2\":\n                             \n              nombre = input(\"Ingresa el Nombre del producto: \")\n              with open(nombre_tienda, \"r\") as file:\n                   for line in file.readlines():\n                        if line.split(\", \")[0] == nombre:\n                             print(line)\n                             break\n                           \n          elif accion == \"3\":\n              nombre = input(\"Ingresa el Nombre del producto: \")\n              cantidad = input(\"Ingresa la cantidad del producto: \")\n              precio = input(\"Ingresa el precio unitario: \")\n\n              with open(nombre_tienda, \"r\") as file:\n                   lineas = file.readlines()\n              with open(nombre_tienda, \"w\") as file:\n                   for line in lineas:\n                    if line.split(\", \")[0] == nombre:\n                       file.write(f\"{nombre}, {cantidad}, {precio}\\n\")\n                    else:\n                         file.write(line)      \n          elif accion == \"4\":\n              nombre = input(\"Ingresa el Nombre del producto: \")\n              \n\n              with open(nombre_tienda, \"r\") as file:\n                   lineas = file.readlines()\n              with open(nombre_tienda, \"w\") as file:\n                   for line in lineas:\n                    if line.split(\", \")[0] != nombre:\n                       file.write(file)\n          elif accion == \"5\":\n               total = 0\n               with open(nombre_tienda, \"r\") as file:\n                  for line in file.readlines():\n                      componentes = line.split(\", \")\n                      cantidad = int(componentes[1])\n                      precio = float(componentes [2])\n                      total += cantidad * precio\n               print(total)              \n          elif accion == \"6\":\n                 nombre = input(\"Ingresa el Nombre del producto: \")\n                 total = 0\n                 with open(nombre_tienda, \"r\") as file:\n                   for line in file.readlines():\n                      componentes = line.split(\", \")\n                      if componentes[0] == nombre:\n                       cantidad = int(componentes[1])\n                       precio = float(componentes [2])\n                       total += cantidad * precio\n                       break\n                 print(total)  \n\n          elif accion == \"7\":\n               with open(nombre_tienda, \"r\") as file:\n                   print(file.read())\n               \n          elif accion == \"8\":\n            \n               os.remove(nombre_tienda)          \n               break  \n          else:\n               print(\"Selecciona una de las opciones disponibles\")     \n               \n\n                \n\n\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/NicoHeguaburu.py",
    "content": "#Ficheros\n\nimport os\n\nfile_name = \"NicoHeguaburu.txt\"\n\n\nwith open(file_name, \"w\") as file:\n    file.write(\"Nicolás Heguaburu\\n\")\n    file.write(\"22\\n\")\n    file.write(\"Python\\n\")\n\nwith open(file_name, \"r\") as file:\n    print(file.read())\n\n\nos.remove(file_name)\n\n\n\n#Dificultad extra\n\nfile_name = \"NicoHeguaburuShop.txt\"\n\n\nwhile True:\n    print(\"1------Añadir producto\")\n    print(\"2------Consultar producto\")\n    print(\"3------Actualizar producto\")\n    print(\"4------Eliminar producto\")\n    print(\"5------Calcular la venta total\")\n    print(\"6------Calcular la venta por producto\")\n    print(\"7------Ver todos los productos\")\n    print(\"8------Salir\")\n\n    opcion = input(\"Selecione una opcion...\")\n\n    if opcion == \"1\": \n        nombre = input(\"Nombre:\")\n        cantidad = input(\"Cantidad:\")\n        precio = input(\"Precio:\")\n\n        with open(file_name, \"a\") as file:\n            file.write(f\"{nombre}, {cantidad}, {precio}\\n\")\n\n    elif opcion == \"2\":\n        nombre = input(\"Nombre:\")\n        with open(file_name, \"r\") as file:\n            for linea in file.readlines():\n                if linea.split(\", \")[0] == nombre:\n                    print(linea)\n                    break\n\n        \n    elif opcion == \"3\":\n        nombre = input(\"Nombre:\")\n        cantidad = input(\"Cantidad:\")\n        precio = input(\"Precio:\")\n        with open(file_name, \"r\") as file:\n            lineas = file.readlines()\n\n        with open(file_name, \"w\") as file:\n            for linea in lineas:\n                if linea.split(\", \")[0] == nombre:\n                    file.write(f\"{nombre}, {cantidad}, {precio} \\n\")\n                else:\n                    file.write(linea)\n\n    elif opcion == \"4\":\n        nombre = input(\"Nombre:\")\n        with open(file_name, \"r\") as file:\n            lineas = file.readlines()\n\n        with open(file_name, \"w\") as file:\n            for linea in lineas:\n                if linea.split(\", \")[0] != nombre:\n                    file.write(linea)\n\n        \n    elif opcion == \"5\":\n        with open(file_name, \"r\") as file:\n            lineas = file.readlines()\n            total_venta = 0\n            for linea in lineas:\n                total_venta += int(linea.split(\", \")[1]) * int(linea.split(\", \")[2])\n            print(total_venta)\n\n\n    elif opcion == \"6\":\n        nombre = input(\"Nombre:\")\n        with open(file_name, \"r\") as file:\n            lineas = file.readlines()\n            for linea in lineas:\n                if linea.split(\", \")[0] == nombre:\n                    print(int(linea.split(\", \")[1]) * int(linea.split(\", \")[2]))\n\n    elif opcion == \"7\":\n        with open(file_name, \"r\") as file:\n            print(file.read())\n    else:\n        print(\"seleccione una opcion valida\")\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/Nicojsuarez2.py",
    "content": "# #11 MANEJO DE FICHEROS\n> #### Dificultad: Media | Publicación: 11/03/24 | Corrección: 18/03/24\n\n## Ejercicio\n\n```\n/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n * \n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n * archivo .txt.\n * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/NightAlchemist.py",
    "content": "import os\n\n# 1. Crear el archivo con el nombre de usuario de GitHub y la extensión .txt\nfilename = \"NightAlchemist.txt\"\n\n# 2. Añadir varias líneas al archivo\ncontent = [\n    \"Name = Jhoao\\n\",\n    \"Age = 37\\n\",\n    \"Favorite programming languague = Python\\n\"\n]\n\n# Crear y escribir en el archivo\nwith open(filename, 'w') as file:\n    file.writelines(content)\n\n# 3. Imprimir el contenido del archivo\nwith open(filename, 'r') as file:\n    file_content = file.read()\n\nprint(file_content)\n\n# 4. Borrar el archivo\nos.remove(filename)  # Eliminar el archivo\n\n# Confirmación de eliminación\nfile_exists = os.path.exists(filename)\nprint(\"The file has been deleted:\", not file_exists, \"\\n\")\n\n'''\nExtra\n'''\n\nfilename = \"products.txt\"\n\n# Instructions for the user\ndef sales():\n    \n    while True:\n        \n        print(\n            \"What do you want to do?\\n\\n\"\n            \"1. Add a new product\\n\"\n            \"2. Show a product\\n\"\n            \"3. Update a product\\n\"\n            \"4. Delete a product\\n\"\n            \"5. Show all the products\\n\"\n            \"6. Calculate total sales\\n\"\n            \"7. Calculate sales by product\\n\"\n            \"8. Exit\\n\"\n        )\n\n        option = input(str(\"Pick a number from the options: \"))\n        \n        if option == \"1\":\n            # Option 1: Add a new product\n            name = input(\"Enter the product name: \")\n            quantity = input(\"Enter the quantity sold: \")\n            price = input(\"Enter the price of the product: \")\n\n            try:\n                quantity = int(quantity)\n                price = float(price)\n                \n                with open(filename, 'a') as file:\n                    file.write(f\"{name}, {quantity}, {price}\\n\")\n                print(f\"Product '{name}' added successfully!\")\n            except ValueError:\n                print(\"Invalid input. Please enter valid numbers for quantity and price.\")\n\n        elif option == \"2\":\n            # Option 2: Show a product\n            search_name = input(\"Enter the product name to search for: \")\n            found = False\n            \n            if os.path.exists(filename):\n                with open(filename, 'r') as file:\n                    lines = file.readlines()\n                    for line in lines:\n                        if line.lower().startswith(search_name.lower()):\n                            print(line.strip())  # Show the product info\n                            found = True\n                            break\n                if not found:\n                    print(\"Product not found.\")\n            else:\n                print(\"No information in the file.\")\n\n        elif option == \"3\":\n            # Option 3: Update a product\n            search_name = input(\"Enter the product name to update: \")\n            found = False\n            products = []\n            \n            if os.path.exists(filename):\n                with open(filename, 'r') as file:\n                    lines = file.readlines()\n                    for line in lines:\n                        products.append(line.strip())\n                \n                for i, line in enumerate(products):\n                    if line.lower().startswith(search_name.lower()):\n                        print(f\"Current product info: {line}\")\n                        new_name = input(\"Enter new product name (or press Enter to keep current): \")\n                        new_quantity = input(\"Enter new quantity (or press Enter to keep current): \")\n                        new_price = input(\"Enter new price (or press Enter to keep current): \")\n                        \n                        # Update values if provided, else keep current values\n                        if new_name:\n                            name = new_name\n                        else:\n                            name = line.split(\",\")[0].strip()\n                        \n                        if new_quantity:\n                            quantity = int(new_quantity)\n                        else:\n                            quantity = int(line.split(\",\")[1].strip())\n                        \n                        if new_price:\n                            price = float(new_price)\n                        else:\n                            price = float(line.split(\",\")[2].strip())\n                        \n                        # Update the product entry in the list\n                        products[i] = f\"{name}, {quantity}, {price}\"\n                        found = True\n                        break\n                \n                if found:\n                    with open(filename, 'w') as file:\n                        file.write(\"\\n\".join(products) + \"\\n\")\n                    print(f\"Product '{search_name}' updated successfully!\")\n                else:\n                    print(\"Product not found.\")\n            else:\n                print(\"No information in the file.\")\n\n        elif option == \"4\":\n            # Option 4: Delete a product\n            search_name = input(\"Enter the product name to delete: \")\n            found = False\n            products = []\n            \n            if os.path.exists(filename):\n                with open(filename, 'r') as file:\n                    lines = file.readlines()\n                    for line in lines:\n                        products.append(line.strip())\n                \n                for i, line in enumerate(products):\n                    if line.lower().startswith(search_name.lower()):\n                        print(f\"Product '{line}' will be deleted.\")\n                        del products[i]\n                        found = True\n                        break\n                \n                if found:\n                    with open(filename, 'w') as file:\n                        file.write(\"\\n\".join(products) + \"\\n\")\n                    print(f\"Product '{search_name}' deleted successfully!\")\n                else:\n                    print(\"Product not found.\")\n            else:\n                print(\"No information in the file.\")\n\n        elif option == \"5\":\n            # Option 5: Show all the products\n            if os.path.exists(filename):\n                try:\n                    with open(filename, 'r') as file:\n                        content = file.read()\n                        if content:\n                            print(content)\n                        else:\n                            print(\"The file is empty.\")\n                except Exception as e:\n                    print(f\"An error occurred: {e}\")\n            else:\n                print(\"No information in the file.\")\n\n        elif option == \"6\":\n            # Option 6: Calculate total sales\n            total_sales = 0\n            if os.path.exists(filename):\n                with open(filename, 'r') as file:\n                    lines = file.readlines()\n                    for line in lines:\n                        data = line.strip().split(\", \")\n                        if len(data) == 3:\n                            quantity = int(data[1])\n                            price = float(data[2])\n                            total_sales += quantity * price\n                print(f\"Total sales: {total_sales}\")\n            else:\n                print(\"No information in the file.\")\n\n        elif option == \"7\":\n            # Option 7: Calculate sales by product\n            product_name = input(\"Enter the product name to calculate sales: \")\n            sales_by_product = 0\n            found = False\n            \n            if os.path.exists(filename):\n                with open(filename, 'r') as file:\n                    lines = file.readlines()\n                    for line in lines:\n                        data = line.strip().split(\", \")\n                        if len(data) == 3 and data[0].lower() == product_name.lower():\n                            quantity = int(data[1])\n                            price = float(data[2])\n                            sales_by_product = quantity * price\n                            found = True\n                            break\n                if found:\n                    print(f\"Total sales for '{product_name}': {sales_by_product}\")\n                else:\n                    print(f\"Product '{product_name}' not found.\")\n            else:\n                print(\"No information in the file.\")\n\n        elif option == \"8\":\n            if os.path.exists(filename):\n                os.remove(filename)  # Delete the file if it exists\n                print(\"File deleted successfully.\")\n            return False\n        else:\n            print(\"Please select one option\")\n\nsales()\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/Nightblockchain30.py",
    "content": "# ```\n# /*\n#  * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n#  * \n#  * EJERCICIO:\n#  * Desarrolla un programa capaz de crear un archivo que se llame como\n#  * tu usuario de GitHub y tenga la extensión .txt.\n#  * Añade varias líneas en ese fichero:\n#  * - Tu nombre.\n#  * - Edad.\n#  * - Lenguaje de programación favorito.\n#  * Imprime el contenido.\n#  * Borra el fichero.\n#  */\n\nimport os\n\nfile_name = \"Nightblockchain30.txt\"\n\nwith open(file_name,'w') as file:\n    file.write(\"Alonso\\n\")\n    file.write(\"26\\n\")\n    file.write(\"Python\\n\")\n\nwith open(file_name,'r') as file:\n    print(file.read())\n\nos.remove(file_name)\n\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n#  * archivo .txt.\n#  * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n#  *   [nombre_producto], [cantidad_vendida], [precio].\n#  * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n#  *   actualizar, eliminar productos y salir.\n#  * - También debe poseer opciones para calcular la venta total y por producto.\n#  * - La opción salir borra el .txt.\n\ndef message_option(option):\n    match option:\n        case 1:\n            return \"Agregando...\"\n        case 2:\n            return \"Consultando un producto deseado..\"\n        case 3:\n            return \"Actualizando...\"\n        case 4:\n            return \"Eliminando...\"\n        case 5:\n            return \"Saliendo...\"\n        case 6:\n            return \"Eliminando de forma definitiva el archivo...\"\n        case 7:\n            return \"Mostrando todos los productos...\"\n\nfile_name_shop = \"Nightblockchain30_shop\" \n\nwhile True:\n\n    print(\"1. Agregar producto.\")\n    print(\"2. Consultar producto.\")\n    print(\"3. Actualizar producto.\")\n    print(\"4. Eliminar producto.\")\n    print(\"5. Salir.\")\n    print(\"6. Eliminar el archivo_shop\")\n    print(\"7. Mostrar productos\")\n\n    print(\"\")\n\n    try:\n\n        option = int(input(\"<<< Selecciona la opción que deseas >>>\\n\" ))\n\n        print(message_option(option)) #Call message_option function\n        \n        if option == 1:\n            name = input(\"Introduce el nombre: \\n\")\n            name.lower() #case sensitive\n            quantity = input(\"Introduce la cantidad: \\n\")\n            price = input(\"Introduce el precio: \\n\")\n\n            with open(file_name_shop,\"a\") as file:\n                file.write(f\"{name.capitalize()} | Cantidad: {quantity} | Precio: {price}$\\n\")\n\n        elif option == 2:\n            name = input(\"¿Cuál es el nombre del producto que deseas consultar?\\n\").capitalize()\n\n            with open(file_name_shop,\"r\") as file:\n                contenido = file.read()\n                \n                if name in contenido:\n                    with open(file_name_shop,\"r\") as file:\n                        for line in file.readlines():\n                            if name == line.split(\" | \")[0]:\n                                print(f\"▶ {line}\")\n                                break\n                else:\n                    print(\"❌ Producto no encontrado\")\n\n        elif option == 3:\n            name = input(\"Introduce el nombre: \\n\")\n            quantity = input(\"Introduce la cantidad: \\n\")\n            price = input(\"Introduce el precio: \\n\")\n\n            # Antes de actualizar el producto gaurdo el contenido en un variable\n            with open(file_name_shop,\"r\") as file:\n                contenido = file.readlines()\n\n            with open(file_name_shop,\"w\") as file:\n                for line in contenido:\n                    if name == line.split(\" | \")[0]:\n                        file.write(f\"{name.capitalize()} | Cantidad: {quantity} | Precio: {price}$\\n\")\n                    else:\n                        file.write(line)\n\n            \n        elif option == 4:\n            name = input(\"Introduce el nombre: \\n\")\n            \n            with open(file_name_shop,\"r\") as file:\n                contenido = file.readlines()\n\n            with open(file_name_shop,\"w\") as file:\n                for line in contenido:\n                    if name != line.split(\" | \")[0]:\n                        file.write(line)\n\n\n        elif option == 5:\n            break\n        \n        elif option == 6:\n            os.remove(file_name_shop)\n        \n        elif option == 7:\n            with open(file_name_shop,\"r\") as file:\n                print(\"\")\n                print(\"<<<  Datos Productos Vendidos  >>>  \")\n                print(\" -------------------------------- \")\n                print(file.read())\n\n\n    except Exception as e:\n        print(\"\")\n        print(f\"💥 Ha ocurrido un error: {e} TIPO: {type(e).__name__}\")\n\nprint(\"HASTA PRONTO!\")\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/Paprikaistkrieg.py",
    "content": "#Manejo de Ficheros\n\"\"\"\nEl manejo de ficheros en Python se realiza utilizando las funciones integradas open(), read(), write() y close().\nEstas funciones permiten abrir, leer, escribir y cerrar archivos de manera sencilla.\nEl proceso básico para manejar ficheros en Python es el siguiente:\n1. Abrir el archivo utilizando la función open(). Esta función toma dos argumentos: el nombre del archivo y el modo en que se va a abrir\n(por ejemplo, 'r' para leer, 'w' para escribir, 'a' para añadir, etc.).\n2. Realizar operaciones de lectura o escritura en el archivo utilizando los métodos read(), readline(), readlines() para leer y write(), writelines() para escribir.\n3. Cerrar el archivo utilizando el método close() para liberar los recursos asociados al archivo.\nEs importante cerrar el archivo después de haber terminado de trabajar con él para evitar problemas de memoria y asegurar que los datos se guarden correctamente.\n\"\"\"\n# Abrir un archivo en modo escritura (crea el archivo si no existe)\nimport os\nfile_name = \"Paprikaiskrieg.txt\"\n#with open(file_name, \"w\") as file :  # Crea un archivo vacío (write mode \"w\" crea el archivo si no existe)\n    #file.write(\"Ivan RN\\n\")  # Escribe una línea en el archivo (\\n para nueva línea)\n    #file.write(\"26\\n\")  # Escribe otra línea en el archivo\n    #file.write(\"python\\n\")  # Escribe otra línea en el archivo\n\n#with open(file_name, \"r\") as file :  # Abre el archivo en modo lectura\n      # Lee todo el contenido del archivo\n    #print(file.read())  # Imprime el contenido del archivo\n\n  # Elimina el archivo creado\n\n\n#XTRAJ\n\nwhile True:\n    try:\n        print(\"1.- añadir producto\")\n        print(\"2.- consultar producto\")\n        print(\"3.- actualizar producto\")\n        print(\"4.- eliminar producto\")\n        print(\"5.- calcular venta total\")\n        print(\"6.- calcular venta por producto\")\n        print(\"7.- Mostrar inventario\")\n        print(\"8.- salir\")\n\n        opcion = int(input(\"Seleccione una opción: \"))\n        if opcion == 1:\n            with open(file_name, \"a\") as file:\n                nombre = input(\"Ingrese el nombre del producto: \")\n                precio = float(input(\"Ingrese el precio del producto: \"))\n                cantidad = int(input(\"Ingrese la cantidad del producto: \"))\n                file.write(f\"{nombre},{precio},{cantidad}\\n\")\n                print(\"Producto añadido exitosamente.\")\n        elif opcion == 2:\n            nombre = input(\"Ingrese el nombre del producto a consultar: \")\n            encontrado = False\n            with open(file_name, \"r\") as file:\n                for line in file:\n                    datos = line.strip().split(\",\")\n                    if datos[0] == nombre:\n                        print(f\"Producto: {datos[0]}, Precio: {datos[1]}, Cantidad: {datos[2]}\")\n                        encontrado = True\n                        break\n            if not encontrado:\n                print(\"Producto no encontrado.\")\n        elif opcion == 3:\n            nombre = input(\"Ingrese el nombre del producto: \")\n            precio = float(input(\"Ingrese el precio del producto: \"))\n            cantidad = int(input(\"Ingrese la cantidad del producto: \"))\n            actualizado = False\n            with open(file_name, \"r\") as file:\n                lines = file.readlines()\n            with open(file_name, \"w\") as file:\n                for line in lines:\n                    datos = line.strip().split(\",\")\n                    if datos[0] == nombre:\n                        file.write(f\"{nombre},{precio},{cantidad}\\n\")\n                        actualizado = True\n                    else:\n                        file.write(line)\n            if actualizado:\n                print(\"Producto actualizado exitosamente.\")\n            else:\n                print(\"Producto no encontrado para actualizar.\")\n        elif opcion == 4:\n            nombre = input(\"Ingrese el nombre del producto a eliminar: \")\n            eliminado = False\n            with open(file_name, \"r\") as file:\n                lines = file.readlines()\n            with open(file_name, \"w\") as file:\n                for line in lines:\n                    datos = line.strip().split(\",\")\n                    if datos[0] != nombre:\n                        file.write(line)\n                    else:\n                        eliminado = True\n            if eliminado:\n                print(\"Producto eliminado exitosamente.\")\n            else:\n                print(\"Producto no encontrado para eliminar.\")\n        elif opcion == 5:\n            total_venta = 0\n            with open(file_name, \"r\") as file:\n                for line in file:\n                    datos = line.strip().split(\",\")\n                    if len(datos) == 3:\n                        try:\n                            total_venta += float(datos[1]) * int(datos[2])\n                        except ValueError:\n                            continue\n            print(f\"Venta total: {total_venta}\")\n        elif opcion == 6:\n            nombre = input(\"Ingrese el nombre del producto a consultar: \")\n            encontrado = False\n            with open(file_name, \"r\") as file:\n                for line in file:\n                    datos = line.strip().split(\",\")\n                    if datos[0] == nombre:\n                        try:\n                            venta = float(datos[1]) * int(datos[2])\n                            print(f\"Venta de {nombre}: {venta}\")\n                        except ValueError:\n                            print(\"Datos inválidos para el producto.\")\n                        encontrado = True\n                        break\n            if not encontrado:\n                print(\"Producto no encontrado.\")\n        elif opcion == 7:\n            with open(file_name, \"r\") as file:\n                contenido = file.read()\n                if contenido.strip() == \"\":\n                    print(\"Inventario vacío.\")\n                else:\n                    print(\"Inventario:\\n\" + contenido)\n        elif opcion == 8:\n            if os.path.exists(file_name):\n                os.remove(file_name)\n            print(\"Saliendo del programa.\")\n            break\n        else:\n            print(\"Opción no válida. Intente de nuevo.\")\n    except ValueError:\n        print(\"Error: Entrada no válida. Por favor, ingrese un número.\")\n    except FileNotFoundError:\n        print(\"Error: El archivo no se encontró.\")\n    except Exception as e:\n        print(f\"Ocurrió un error inesperado: {e}\")\n    "
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/Paula2409.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n\"\"\"\n\"\"\"\nLectura y escritura de archivos en Python:\n* 'r' (Read): valor default. Abre un archivo y lo lee. Indica un error si el archivo no existe\n* 'a' (Append): abre un archivo para agregar informacion. Si no existe, lo crea\n* 'w' (Write): abre un archivo para escribir. Si no existe, lo crea.\n* 'x' (Create): crea un archivo con el nombre especificado. Retorna un error si ya existe.\n* 'b' (Binario): abrir en modo binario\n* '+' (Adicional): al agregar este simbolo a un modo ya sea de lectura o escritua puedo combinarlo con otra forma (escritura + lectura)\n\"\"\"\n\"\"\"\nPara tener en cuenta \n* Al leer un archivo cada linea de ejecucion abrira el archivo y lo leera. Es continua la lectura.\n* Si yo imprimo la lectura total del archivo y luego una lectura por cantidad de caracteres, \n* esta ultima no tendra efecto ya que he terminado de leer el archivo por completo.\n\"\"\"\n\"\"\"\nMetodos:\n* read(): lee el fichero. Tambien le puedo pasar como argumento un numero de caracteres a leer.\n* readline(): lee una linea y la devuelve como una cadena.\n* readlines(): lee todas las lineas del fichero y las devuelve como elementos de cadena en una lista, uno para cada linea.\n* write(): escribe una cadena\n* writelines(): escribe varias cadenas al mismo tiempo\n\"\"\"\n\"\"\"\nGestores de contexto (context managers)\n* Contexto: conjunto de datos utilizados por un recurso que deben ser guardados para su posterior reutilizacion. \n* Gestor de contexto: permite aplicar una serie de acciones a la entrada y salida del bloque de codigo que engloba.\n* with: gestor de contexto. Es una clase que contiene los metodos __enter__() y __exit__(). Estos abren y cierran los archivos para manipularlos.\n\"\"\"\n\n# Para borrar el fichero debo importar la libreria 'os' para acceder a los modulos del sistema operativo.\nimport os\n\ndef files():\n    with open('C:/Users/pau87/OneDrive/Documentos/Roadmap 11/file.txt','w+') as file:\n        # Escribir lineas\n        file.write('Paula Adgi Romano\\n')\n        file.write('36\\n')\n        file.write('Python\\n')\n        \n        # Lee archivo completo\n        print(file.read())\n             \n        # Lee una linea\n        print(file.readline())\n        \n        # Lee y genera una lista. Si leyo una linea anteriormente comienza desde donde quedo. Si ya se leyo el archivo completo, retorna una lista vacia.\n        print(file.readlines())\n\n        # Leer lineas. No se ejecuta si el archivo ya fue leido.\n        for line in file:\n            print(line)\n            \n    # Borramos el archivos\n    os.remove('C:/Users/pau87/OneDrive/Documentos/Roadmap 11/file.txt')\n    print('Archivo eliminado')\n            \n#files()\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n * archivo .txt.\n * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n */\n\"\"\"\ndef mi_empresa():\n    while True:\n        print(\"\"\"\n        BIENVENIDO AL SISTEMA DE GESTION DE VENTAS\n        Por favor, ingrese una opcion:\n        1. Agregar producto\n        2. Consultar producto\n        3. Actualizar producto\n        4. Eliminar producto\n        5. Calcular venta total\n        6. calcular venta por producto \n        7. Salir\n        \"\"\")\n        opcion = int(input())\n        if opcion == 1:\n            nombre_producto = input('Ingrese el nombre del producto: ')\n            cantidad_producto = input('Ingrese la cantidad del producto: ')\n            precio_producto = input('Ingrese el precio del producto: ')\n            with open(\"C:/Users/pau87/OneDrive/Documentos/Roadmap 11/ventas.txt\", 'a') as file:\n                file.write(f'{nombre_producto} - {cantidad_producto} - {precio_producto}\\n')\n                print('Producto agregado con exito')\n                continue\n        elif opcion == 2:\n            nombre_a_buscar = input('Ingrese el nombre del producto a consultar: ')\n            with open(\"C:/Users/pau87/OneDrive/Documentos/Roadmap 11/ventas.txt\", 'r') as file:\n                for line in file.readlines():\n                    if line.split(', ')[0] == nombre_a_buscar:\n                        print(line)\n                        break\n        elif opcion == 3:\n            nombre_a_buscar = input('Ingrese el nombre del producto para actualizar: ')\n            nuevo_nombre = input('Ingrese el nuevo nombre: ')\n            nueva_cantidad = input('Ingrese el nuevo nombre: ')\n            nuevo_precio = input('Ingrese el nuevo nombre: ')\n            with open(\"C:/Users/pau87/OneDrive/Documentos/Roadmap 11/ventas.txt\", 'r') as file:\n                lineas = file.readlines()\n                for linea in lineas:\n                    if linea.split(' - ')[0] == nombre_a_buscar:\n                        file.write(f'{nuevo_nombre}, {nueva_cantidad}, {nuevo_precio}\\n')\n                        break\n        elif opcion == 4:\n            nombre_a_buscar = input('Ingrese el nombre del producto a eliminar: ')\n            with open(\"C:/Users/pau87/OneDrive/Documentos/Roadmap 11/ventas.txt\", 'r') as file:\n                lineas = file.readlines()\n            with open(\"C:/Users/pau87/OneDrive/Documentos/Roadmap 11/ventas.txt\", 'w') as file:\n                for linea in lineas:\n                    if linea.split(', ')[0] != nombre_a_buscar:\n                        file.write(linea)\n        elif opcion == 5:\n            venta_total = 0\n            with open(\"C:/Users/pau87/OneDrive/Documentos/Roadmap 11/ventas.txt\", 'r') as file:\n                lineas = file.readlines()\n                for linea in lineas:\n                    venta_total = linea.split(', ')[1] * linea.split(', ')[2]\n            print(f'El total de ventas es de: {venta_total}')\n        elif opcion == 6:\n            nombre_a_buscar = input('Ingrese el nombre del producto que desea calcular: ')\n            venta_producto = 0\n            with open(\"C:/Users/pau87/OneDrive/Documentos/Roadmap 11/ventas.txt\", 'r') as file:\n                lineas = file.readlines()\n                for linea in lineas:\n                    if linea.split(', ')[0] == nombre_a_buscar:\n                        venta_producto = linea.split(', ')[1] * linea.split(' - ')[2]\n            print(f'La venta del producto es de: {venta_producto}')\n        elif opcion == 7:\n            os.remove(\"C:/Users/pau87/OneDrive/Documentos/Roadmap 11/ventas.txt\")\n            print('Archivo eliminado. Programa terminado')            \n        else:\n            print('La opcion no es correcta, por favor, intentelo de nuevo')\n            print(\"\"\"\n            BIENVENIDO AL SISTEMA DE GESTION DE VENTAS\n            Por favor, ingrese una opcion:\n            1. Agregar producto\n            2. Consultar producto\n            3. Actualizar producto\n            4. Eliminar producto\n            5. Calcular venta total\n            6. calcular venta por producto \n            7. Salir\n            \"\"\")\n            opcion = int(input())\n\nmi_empresa()\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/RicardiJulio.py",
    "content": "#  IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n#  *\n#  * EJERCICIO:\n#  * Desarrolla un programa capaz de crear un archivo que se llame como\n#  * tu usuario de GitHub y tenga la extensión .txt.\n#  * Añade varias líneas en ese fichero:\n#  * - Tu nombre.\n#  * - Edad.\n#  * - Lenguaje de programación favorito.\n#  * Imprime el contenido.\n#  * Borra el fichero.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n#  * archivo .txt.\n#  * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n#  *   [nombre_producto], [cantidad_vendida], [precio].\n#  * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n#  *   actualizar, eliminar productos y salir.\n#  * - También debe poseer opciones para calcular la venta total y por producto.\n#  * - La opción salir borra el .txt.\n\n# Formas para abrir un archivo:\n# ‘r’: Por defecto, para leer el fichero.\n# ‘w’: Para escribir en el fichero.\n# ‘x’: Para la creación, fallando si ya existe.\n# ‘a’: Para añadir contenido a un fichero existente.\n# ‘b’: Para abrir en modo binario.\n\nimport os\n\nnombre_fichero = 'RicardiJulio.txt'\nwith open(nombre_fichero,'w') as fichero:\n    fichero.write('Julio Ricardi.\\n')\n    fichero.write('23 años.\\n')\n    fichero.write('Python.')\n    \nwith open(nombre_fichero,'r') as fichero:\n    contenido = fichero.read()\n    print (contenido)        \n    \nos.remove(nombre_fichero)\n\n# DIFICULTAD EXTRA:\ndef crear_archivo(nombre_archivo,titulo):\n    with open(nombre_archivo,'w')as archivo:\n        archivo.write(f'{titulo}\\n')\n        \ndef añadir(archivo,nombre,cantidad,precio):\n    lineas_actualizadas = []\n    with open(archivo,'r')as archivo2:\n        lineas = archivo2.readlines()\n        for linea in lineas:\n            lineas_actualizadas.append(linea)\n    with open(archivo,'w') as archivo3:\n        archivo3.writelines(lineas_actualizadas)\n        archivo3.write(f'[{nombre}],[{cantidad}],[{precio}]\\n')\n        \ndef consultar(archivo,nombre):\n    with open(archivo,'r') as archivo:\n        lineas = archivo.readlines()\n    encontrado = False\n    for linea in lineas:\n        datos = linea.strip().split(',')\n        if datos[0] == str(f'[{nombre}]'):\n            print(f'{datos[0]},{datos[1]},{datos[2]}')\n            encontrado = True\n    if not encontrado:\n        print(f'{nombre} no ha sido encontrado.') \n\ndef actualizar(archivo,nombre_p,nueva_cantidad,nuevo_precio):\n        with open(archivo,'r') as archivo1:\n            lineas = archivo1.readlines()\n        \n        productos_actualizados = []\n        encontrado = False\n        \n        for linea in lineas:\n            datos = linea.strip().split(',')\n            if datos[0] == str(f'[{nombre_p}]'):\n                cantidad = nueva_cantidad if nueva_cantidad is not None else datos[1]\n                precio = nuevo_precio if nuevo_precio is not None else datos[2]\n                nueva_linea = f'[{nombre_p}],[{cantidad}],[{precio}]\\n'\n                productos_actualizados.append(nueva_linea)\n                encontrado = True\n            else:\n                productos_actualizados.append(linea)\n                \n        if not encontrado:\n            print(f'{nombre_p} no ha sido encontrado')\n            \n        with open(archivo,'w')as archivo2:\n            archivo2.writelines(productos_actualizados)\n            \n        print('Producto actualizado correctamente.')\n\ndef eliminar(archivo,nombre):\n    with open(archivo,'r')as archivo1:\n        lineas = archivo1.readlines()\n    \n    productos_actualizados = []\n    encontrado = False\n    \n    for linea in lineas:\n        datos = linea.strip().split(',')\n        if datos[0] == f'[{nombre}]':\n            encontrado = True\n            print(f'{nombre} eliminado correctamente.')\n            pass\n        else:\n            productos_actualizados.append(linea)\n            \n    if not encontrado:\n        print(f'{nombre} no ha sido encontrado')\n            \n    with open(archivo,'w')as archivo2:\n        archivo2.writelines(productos_actualizados)\n    \nprograma = True\ncontador = 0\nwhile programa == True:\n    bienvenida = 'Bienvenido al programa de gestion de ventas.'\n    opciones = '1. Crear base de datos.\\n2. Añadir un producto.\\n3. Consultar un producto.\\n4. Actualizar un producto.\\n5. Eliminar un producto.\\n6. Salir.'\n    if contador == 0:\n        print(bienvenida)\n    print(opciones)\n    entrada = int(input('Indique el numero de opcion que desea: '))\n    hay_archivo = False\n    if entrada == 1 and not hay_archivo:\n        nombre_a = input('Indique el nombre del archivo: ')\n        titulo = 'Productos, ventas y precios.'\n        crear_archivo(nombre_a,titulo)\n        hay_archivo = True\n        print(f'{nombre_a} creado correctamente.')\n    \n    elif entrada == 2:\n        nombre_p = input('Nombre del producto: ')\n        cantidad_p = input('Cantidad del producto: ')\n        precio_p = input('Precio del producto: ')\n        añadir(nombre_a,nombre_p,cantidad_p,precio_p)\n        print(f'{nombre_p} añadido correctamente')\n        \n    elif entrada == 3:\n        nombre_p = input('Nombre del producto: ')\n        consultar(nombre_a,nombre_p)\n    \n    elif entrada == 4:\n        nombre_p = input('Nombre del producto: ')\n        nueva_c = input('Nueva cantidad: ')\n        nuevo_p = input('Nuevo precio: ')\n        actualizar(nombre_a,nombre_p,nueva_c,nuevo_p)\n    \n    elif entrada == 5:\n        nombre_p = input('Nombre del producto: ')\n        eliminar(nombre_a,nombre_p)\n    \n    elif entrada == 6:\n        print('Hasta luego.')\n        programa = False\n    \n    contador =+ 1\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/Sac-Corts.py",
    "content": "### Ejercicio ###\nimport os\n\nuser_github = \"Sac-Corts\"\nname = \"Isaac Cortés\"\nage = 22\nlanguage = \"Python\"\n\nfile_name = f\"{user_github}.txt\"\nfile = open(file_name, \"w\")\n\nfile.write(f\"Nombre: {name}\\n\")\nfile.write(f\"Edad: {age}\\n\")\nfile.write(f\"Lenguaje de programación: {language}\\n\")\n\nfile.close()\n\nwith open(file_name, \"r\") as file:\n    content = file.read()\n    print(\"Contenido del archivo:\")\n    print(content)\n\nos.remove(file_name)\nprint(f\"El archivo '{file_name}' ha sido borrado.\")\n\n\n### Ejercicio Extra ###\n\nfile_name = \"OXXO.txt\"\n\nopen(file_name, \"a\")\n\ndef main():\n    while True:\n        print(\"Menú:\")\n        print(\"1. Añadir producto:\")\n        print(\"2. Consultar producto:\")\n        print(\"3. Actualizar producto:\")\n        print(\"4. Eliminar producto:\")\n        print(\"5. Calcular venta total:\")\n        print(\"6. Calcular venta por producto:\")\n        print(\"7. Salir:\")\n        option = input(\"Ingrese una opción: \")\n\n        if option == \"1\":\n            add_product()\n        elif option == \"2\":\n            consult_product()\n        elif option == \"3\":\n            update_product()\n        elif option == \"4\":\n            delete_product()\n        elif option == \"5\":\n            calculate_total_sale()\n        elif option == \"6\":\n            calculate_sales_product()\n        elif option == \"7\":\n            os.remove(file_name)\n            break\n        else:\n            print(\"Por favor, ingresa una opción correcta.\")\n\ndef add_product():\n    name = input(\"Nombre del producto: \")\n    quantity = input(\"Cantidad vendida: \")\n    price = input(\"Precio: \")\n    with open(file_name, \"a\") as file:\n        file.write(f\"{name}, {quantity}, {price}\\n\") \n\ndef consult_product():\n    name = input(\"Nombre: \")\n    with open(file_name, \"r\") as file:\n        for line in file.readlines():\n            if line.split(\", \")[0] == name:\n                print(line)\n\ndef update_product():\n    name = input(\"Nombre del producto: \")\n    quantity = input(\"Cantidad vendida: \")\n    price = input(\"Precio: \")\n    with open(file_name, \"r\") as file:\n        lines = file.readlines()\n    with open(file_name, \"w\") as file:\n        for line in lines:\n            if line.split(\", \")[0] == name:\n                file.write(f\"{name}, {quantity}, {price}\\n\") \n            else:\n                file.write(line)\n\ndef delete_product():\n    name = input(\"Nombre del producto: \")\n    with open(file_name, \"r\") as file:\n        lines = file.readlines()\n    with open(file_name, \"w\") as file:\n        for line in lines:\n            if line.split(\", \")[0] != name:\n                file.write(line)\n\ndef calculate_total_sale():\n    total = 0\n    with open(file_name, \"r\") as file:\n        for line in file.readlines():\n            components = line.split(\", \")\n            quantity = int(components[1])\n            price = float(components[2])\n            total += quantity * price\n            print(total)\n\ndef calculate_sales_product():\n    name = input(\"Nombre del producto: \")\n    total = 0\n    with open(file_name, \"r\") as file:\n        for line in file.readlines():\n            components = line.split(\", \")\n            if components[0] == name:\n                quantity = int(components[1])\n                price = float(components[2])\n                total += quantity * price\n    print(total)\n            \n\nmain()\n\n\n\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/SaezMD.py",
    "content": "#11 Manejo de ficheros\n\"\"\"\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un archivo .txt.\n * - Cada producto se guarda en una línea del arhivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar, actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n */\n\"\"\"\nimport os\nabspath = os.path.abspath(__file__) #get the file directory\ndname = os.path.dirname(abspath)\nos.chdir(dname) #change to file directory\n\nnameOfFile = \"SaezMD\"\nextension = \".\" + \"txt\"\nmyName = \"Name: Write your name here: **SMM**\"\nmyAge = \"Age: 12\"\nmyFavouriteLanguage = \"Language: Java\" \n\n#write\nwith open(nameOfFile + extension, 'w') as file:\n    file.write(myName + '\\n' + myAge + '\\n' + myFavouriteLanguage)\n\n#read\nwith open(nameOfFile + extension, 'r') as file:\n    myFile = file.read()\n    print(myFile)\n\n#delete file\ninput(\"press enter key to delete the file...\")\nos.remove(nameOfFile + extension)\n\n#EXTRA\n\nfile = open(\"shopFileRecords.txt\",'a')\nfile.write(\"nails\" + \", \" + \"12\" + \", \" + \"6.55\\n\")\nfile.write(\"polish\" + \", \" + \"22\" + \", \" + \"10.6\\n\")\nfile.close()\n\nfile = open(\"shopFileRecords.txt\",'r')\nfileData = file.read().split('\\n')\nfile.close()\nprint(fileData)\n\nwhile True:\n    inputUser = input(\"Select an option [add, showall, search, update, delete, total, psale, exit]: \").lower()\n    if inputUser == \"exit\":\n        file.close()\n        os.remove(\"shopFileRecords.txt\")\n        break\n    elif inputUser == \"add\":\n        inputAdd = input(\"New item: \").lower()\n\n        file = open(\"shopFileRecords.txt\",'r')\n        fileData = file.read()\n\n        if inputAdd in fileData:\n            print(\"Item already exist!\")\n\n        else: \n            inputAddPrice = input(\"New price: \")\n            inputAddQty = input(\"New quantity: \")\n            file = open(\"shopFileRecords.txt\",'a') # append\n            file.write( inputAdd + \", \" + inputAddPrice + \", \" + inputAddQty + \"\\n\")\n   \n        file.close()\n\n    elif inputUser == \"showall\":\n        with open(\"shopFileRecords.txt\",\"r\") as file:\n            for line in file:\n                print(line.rstrip())\n\n    elif inputUser == \"search\":\n        inputSearch = input(\"Search item: \").lower()\n        with open(\"shopFileRecords.txt\",\"r\") as file:\n            for line in file.readlines():\n                if line.split(\", \")[0] == inputSearch:\n                    print(line.rstrip())\n\n    elif inputUser == \"delete\":\n        inputDelete = input(\"Delete item: \").lower()\n\n        try: \n            file = open(\"shopFileRecords.txt\",'r')\n            lines = file.readlines()\n            file.close()\n            \n            with open(\"shopFileRecords.txt\",'w') as file:\n                for line in lines:\n                    if line.find(inputDelete) != -1:  # find() returns -1 if no match is found\n                        pass\n                    else:\n                        file.write(line)\n        except:\n            print(\"Item not found!\")\n    \n    elif inputUser == \"update\":\n        inputUpdate = input(\"Update item: \").lower()\n\n        #Update1: delete line\n        try: \n            file = open(\"shopFileRecords.txt\",'r')\n            lines = file.readlines()\n            file.close()\n            \n            with open(\"shopFileRecords.txt\",'w') as file:\n                for line in lines:\n                    if line.find(inputUpdate) != -1:  # find() returns -1 if no match is found\n                        pass\n                    else:\n                        file.write(line)\n        \n            #Update2: add line\n            inputAddPrice = input(\"New price: \")\n            inputAddQty = input(\"New quantity: \")\n            file = open(\"shopFileRecords.txt\",'a')\n            file.write( inputUpdate + \", \" + inputAddPrice + \", \" + inputAddQty + \"\\n\")\n    \n            file.close()\n        \n        except:\n            print(\"Item not found!\")        \n\n    elif inputUser == \"total\":\n        with open(\"shopFileRecords.txt\",'r') as file:\n            lines = file.readlines()\n            totalAmount = 0\n            for line in lines:\n                list = line.split(\",\")\n                price = list[2].split('\\n')[0]\n                listClean = []\n                listClean.append(list[1].strip())\n                listClean.append(price.strip())\n                #print(listClean)\n                totalAmount += ((int(listClean[0].strip())) * float(listClean[1].strip()))\n    \n        print(f\"Total of sales: {totalAmount}\")\n\n    elif inputUser == \"psale\":\n        inputProductSale = input(\"Subtotal for item: \").lower()\n\n        with open(\"shopFileRecords.txt\",'r') as file:\n            lines = file.readlines()\n            for line in lines:    \n                if line.find(inputProductSale) == -1:  # find() returns -1 if no match is found\n                    pass\n                else:\n                    list = line.split(\",\")\n                    price = list[2].split('\\n')[0]\n                    listClean = []\n                    listClean.append(list[1].strip())\n                    listClean.append(price.strip())\n                    productAmount =((int(listClean[0].strip())) * float(listClean[1].strip()))                    \n                    print(f\"Total for: {inputProductSale} is: {productAmount}\")\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/SergioGI99.py",
    "content": "\"\"\"\n------------------\nMANEJO DE FICHEROS\n------------------\nIMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n\nEJERCICIO:\nDesarrolla un programa capaz de crear un archivo que se llame como\ntu usuario de GitHub y tenga la extensión .txt.\nAñade varias líneas en ese fichero:\n- Tu nombre.\n- Edad.\n- Lenguaje de programación favorito.\nImprime el contenido.\nBorra el fichero.\n\nDIFICULTAD EXTRA (opcional):\nDesarrolla un programa de gestión de ventas que almacena sus datos en un \narchivo .txt.\n- Cada producto se guarda en una línea del arhivo de la siguiente manera:\n  [nombre_producto], [cantidad_vendida], [precio].\n- Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n  actualizar, eliminar productos y salir.\n- También debe poseer opciones para calcular la venta total y por producto.\n- La opción salir borra el .txt.\n\"\"\"\nimport os\n\n# Ejercicio\n\nfile_name = \"SergioGI99.txt\"\n\nwith open(file_name, \"w\") as file:\n    file.write(\"Sergio Garcia\\n\") \n    file.write(\"24 años\\n\")\n    file.write(\"Python\")\n\nwith open(file_name, \"r\") as file:\n    print(file.read())\n\nos.remove(file_name)\n\n# Extra\n\nfile_name = \"sales.txt\"\n\nopen(file_name, \"a\")\n\ndef name_check(name):\n    in_list = False\n    with open(file_name, \"r\") as file:\n        for line in file.readlines():\n            if line.split(\", \")[0] == name:\n                in_list = True\n    if in_list == False:\n        print(\"No se ha encontrado el producto\")\n    \n\ndef check_list():\n    name = input(\"Nombre del producto a buscar: \")\n    name_check(name)\n    with open(file_name, \"r\") as file:\n        for line in file.readlines():\n            if line.split(\", \")[0] == name:\n                print(line)\n    continue_check()\n\ndef add():\n    name = input(\"Nombre del producto: \")\n    amount = input(\"Cantidad vendida: \")\n    price = input(\"Precio: \")\n    with open(file_name, \"a\") as file:\n        file.write(f\"{name}, {amount}, {price}\\n\")\n    print(f\"{name} ha sido añadido.\")\n    continue_check()\n\ndef update():\n    name = input(\"Nombre del producto a actualizar: \")\n    name_check(name)\n    update_value = input(\"Que quieres actualizar?\\n- Nombre\\n- Cantidad\\n- Precio\")\n    with open(file_name, \"r\") as file:\n            lines = file.readlines()\n    with open(file_name, \"w\") as file:\n        for line in lines:\n            if line.split(\", \")[0] == name:\n                if update_value.lower() == \"nombre\":\n                    new_name = input(\"Escribe el nuevo nombre: \")\n                    amount = line.split(\", \")[1]\n                    price = line.split(\", \")[2]\n                    file.write(f\"{new_name}, {amount}, {price}\\n\")\n                elif update_value.lower() == \"cantidad\":\n                    new_amount = input(\"Escribe la cantidad vendida: \")\n                    name = line.split(\", \")[0]\n                    price = line.split(\", \")[2]\n                    file.write(f\"{name}, {new_amount}, {price}\\n\")\n                elif update_value.lower() == \"precio\":\n                    new_price = input(\"Escribe el precio actualizado: \")\n                    name = line.split(\", \")[1]\n                    amount = line.split(\", \")[2]\n                    file.write(f\"{name}, {amount}, {new_price}\\n\")\n                else:\n                    print(\"Opción incorrecta.\")\n                    update()\n            else:\n                file.write(line)\n    continue_check()\n\ndef delete():\n    name = input(\"Nombre del producto a eliminar: \")\n    name_check(name)\n    with open(file_name, \"r\") as file:\n            lines = file.readlines()\n    with open(file_name, \"w\") as file:\n        for line in lines:\n            if line.split(\", \")[0] != name:\n                file.write(line)\n    continue_check()\n\ndef show_list():\n    with open(file_name, \"r\") as file:\n        print(file.read())\n    continue_check()\n\ndef total_sales():\n    total = 0\n    with open(file_name, \"r\") as file:\n        lines = file.readlines()\n        for line in lines:\n            total = total + (int(line.split(\", \")[1]) * int(line.split(\", \")[2]))\n    print(f\"Valor ventas total: {total}\")\n    continue_check()\n\ndef product_sales():\n    name = input(\"Nombre del producto: \")\n    name_check(name)\n    total = 0\n    with open(file_name, \"r\") as file:\n        lines = file.readlines()\n        for line in lines:\n            if line.split(\", \")[0] == name:\n                total = total + (int(line.split(\", \")[1]) * int(line.split(\", \")[2]))\n                print(f\"Valor ventas total: {total}\")\n    continue_check()\n\ndef exit():\n    return None\n\ndef continue_check():\n    input(\"(pulsa enter)\")\n    sales()\n\ninput_list = {\n    \"1\":check_list,\n    \"2\":add,\n    \"3\":update,\n    \"4\":delete,\n    \"5\":show_list,\n    \"6\":total_sales,\n    \"7\":product_sales,\n    \"8\":exit\n}\n\ndef sales():\n    print(\"¿Que operación quieres realizar?\\n1 - Consultar\\n2 - Añadir\\n3 - Actualizar\\n4 - Eliminar\\n5 - Listado\\n6 - Venta total\\n7 - Venta por producto\\n8 - Salir\")\n    user_input = input(\": \" )\n    if user_input.lower() in input_list:\n        input_list[user_input]()\n    else:\n        print(f\"{user_input} no es correcto.\")\n        continue_check()\n\nsales()\n\nos.remove(file_name)"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/SooHav.py",
    "content": "# 11 - MANEJO DE FICHEROS\nimport os\n\n# Ejercicio\n\nnombre_archivo = \"SooHav.txt\"\n\n# Abrimos el fichero\nwith open(nombre_archivo, 'w') as fichero:\n    # Datos\n    lista = [\"Sofia\", \"46\", \"Python\"]\n    # Escribir datos\n    for linea in lista:\n        fichero.write(linea + \"\\n\")\n\n# Leemos  y borramos el fichero\nwith open(nombre_archivo, 'r') as fichero_lectura:\n    print(fichero_lectura.read())\n\ntry:\n    os.remove(nombre_archivo)\n    print(\"Archivo eliminado.\")\nexcept FileNotFoundError:\n    print(\"El archivo no existe.\")\n\n# Dificultad Extra\n# Inventario\n\n\ndef generar_archivo():\n    productos = []\n    # Escribir archivo y agregar productos\n    with open(\"archivo.txt\", 'a') as archivo:\n        while True:\n            producto = {}\n            producto['Nombre'] = input(\"Nombre del producto: \")\n\n            # Verificar si el producto ya existe\n            if any(prod['Nombre'] == producto['Nombre'] for prod in productos):\n                print(\"El producto ya existe. Intente con otro nombre.\")\n                continue\n\n            while True:\n                try:\n                    producto['Cantidad'] = int(input(\"Cantidad: \"))\n                    print(\n                        f\"El número ingresado de productos es {producto['Cantidad']}\")\n                    break\n                except ValueError as e:\n                    print(f\"Error: {e}\")\n\n            while True:\n                try:\n                    producto['Precio'] = float(input(\"Precio unitario: \"))\n                    print(f\"El precio ingresado es {producto['Precio']}\")\n                    break\n                except ValueError as e:\n                    print(f\"Error: {e}\")\n\n            productos.append(producto)\n\n            agregar_otro = input(\"¿Desea agregar otro producto? (s/n): \")\n            if agregar_otro.lower() != 's':\n                break\n\n        for producto in productos:\n            archivo.write(\n                f\"{producto['Nombre']}, {producto['Cantidad']}, {producto['Precio']}\\n\")\n        print(productos)\n    return productos\n\n\ndef leer_archivo(archivo):\n    lista = []\n    with open(archivo, 'r') as archivo:\n        for linea in archivo.readlines():\n            producto = linea.strip().split(', ')\n            lista.append(producto)\n    return lista\n\n\ndef consultar(archivo):\n    # Consultar el archivo\n    while True:\n        try:\n            palabra_clave = input(\n                \"Ingrese la palabra clave para la búsqueda: \")\n            productos = leer_archivo(archivo)  # Leer el archivo nuevamente\n            encontrados = False\n            for producto in productos:\n                # Comparar con el nombre del producto\n                if producto[0].lower() == palabra_clave.lower():\n                    print(producto)\n                    encontrados = True\n            if not encontrados:\n                raise Exception(\n                    \"No se encontraron productos con la palabra clave proporcionada.\")\n        except Exception as e:\n            print(f\"Error al buscar productos: {e}\")\n\n        buscar_otro = input(\"¿Desea buscar otro producto? (s/n): \")\n        if buscar_otro.lower() != 's':\n            break\n\n\ndef actualizar(archivo):\n    while True:\n        productos = leer_archivo(archivo)\n        # Actualizar el archivo\n        try:\n            palabra_clave = input(\n                \"Ingrese la palabra clave para la búsqueda: \")\n            productos_encontrados = []\n            encontrados = False\n            for producto in productos:\n                if producto[0].lower() == palabra_clave.lower():\n                    nuevo_nombre = input(\"Ingrese el nuevo nombre: \")\n                    nueva_cantidad = input(\"Ingrese la nueva cantidad: \")\n                    nuevo_precio = input(\"Ingrese el nuevo precio: \")\n                    producto[0] = nuevo_nombre\n                    producto[1] = nueva_cantidad\n                    producto[2] = nuevo_precio\n                    encontrados = True\n                    # Escribir el contenido corregido de vuelta al archivo\n                    with open(archivo, 'w') as file:\n                        for producto in productos:\n                            file.write(\n                                f\"{producto[0]}, {producto[1]}, {producto[2]}\\n\")\n            if not encontrados:\n                raise Exception(\n                    \"No se encontraron productos con la palabra clave proporcionada.\")\n        except Exception as e:\n            print(f\"Error al buscar productos: {e}\")\n\n        continuar = input(\"¿Desea seguir actualizando productos? (s/n): \")\n        if continuar.lower() != 's':\n            break\n\n\ndef eliminar_producto(archivo, palabra_clave):\n    # Leer el contenido actual del archivo\n    with open(archivo, 'r') as file:\n        productos = file.readlines()\n\n    # Buscar la línea a eliminar\n    with open(archivo, 'w') as file:\n        for producto in productos:\n            if palabra_clave not in producto:\n                file.write(producto)\n\n\n# Uso del inventario\nwhile True:\n    print(\"\\nMenú:\")\n    print(\"1. Generar archivo\")\n    print(\"2. Consultar productos\")\n    print(\"3. Actualizar productos\")\n    print(\"4. Eliminar producto\")\n    print(\"5. Mostrar productos inventariados\")\n    print(\"6. Salir\")\n\n    opcion = input(\"Seleccione una opción: \")\n\n    if opcion == \"1\":\n        generar_archivo()\n    elif opcion == \"2\":\n        consultar(\"archivo.txt\")\n    elif opcion == \"3\":\n        actualizar(\"archivo.txt\")\n    elif opcion == \"4\":\n        palabra_clave = input(\n            \"Ingrese la palabra clave del producto a eliminar: \")\n        eliminar_producto(\"archivo.txt\", palabra_clave)\n    elif opcion == \"5\":\n        with open('archivo.txt', 'r') as archivo:\n            print(archivo.read())\n    elif opcion == \"6\":\n        os.remove(\"archivo.txt\")\n        print(\"Saliendo del programa...\")\n        break\n    else:\n        print(\"Opción no válida. Por favor, seleccione una opción válida.\")\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/Tomu98.py",
    "content": "\"\"\" Reto 11: Manejo de ficheros \"\"\"\n\nimport os\n\nfile_name = \"Tomu98.txt\"\n\nwith open(file_name, \"w\") as file:\n    file.write(\"Abel Tomás\\n\")\n    file.write(\"25\\n\")\n    file.write(\"Python\\n\")\n\nwith open(file_name, \"r\") as file:\n    print(file.read())\n\nos.remove(file_name)\n\n\n\n\"\"\" Reto extra \"\"\"\n\nfile_name = \"Tomu_shop.txt\"\nopen(file_name, \"a\")\n\nwhile True:\n    print(\"1. Añadir producto\")\n    print(\"2. Consultar producto\")\n    print(\"3. Actualizar producto\")\n    print(\"4. Borrar producto\")\n    print(\"5. Mostrar productos\")\n    print(\"6. Calcular venta total\")\n    print(\"7. Calcular venta por producto\")\n    print(\"8. Salir\")\n\n    option = input(\"Selecciona una opción: \")\n\n    match option:\n        case \"1\":\n            name = input(\"Nombre: \")\n            quantity = input(\"Cantidad: \")\n            price = input(\"Precio: \")\n            with open(file_name, \"a\") as file:\n                file.write(f\"{name}, {quantity}, {price}\\n\")\n        case \"2\":\n            name = input(\"Nombre: \")\n            with open(file_name, \"r\") as file:\n                for line in file.readlines():\n                    if line.split(\", \")[0] == name.lower():\n                        print(line)\n                        break\n                    else:\n                        print(\"No se encontró el producto.\\n\")\n                        break\n        case \"3\":\n            name = input(\"Nombre: \")\n            quantity = input(\"Cantidad: \")\n            price = input(\"Precio: \")\n            with open(file_name, \"r\") as file:\n                lines = file.readlines()\n            with open(file_name, \"w\") as file:\n                for line in lines:\n                    if line.split(\", \")[0] == name.lower():\n                        file.write(f\"{name}, {quantity}, {price}\\n\")\n                    else:\n                        file.write(line)\n        case \"4\":\n            name = input(\"Nombre: \")\n            with open(file_name, \"r\") as file:\n                lines = file.readlines()\n            with open(file_name, \"w\") as file:\n                for line in lines:\n                    if line.split(\", \")[0] != name.lower():\n                        file.write(line)\n        case \"5\":\n            with open(file_name, \"r\") as file:\n                print(file.read())\n        case \"6\":\n            total = 0\n            with open(file_name, \"r\") as file:\n                for line in file.readlines():\n                    components = line.split(\", \")\n                    quantity = int(components[1])\n                    price = float(components[2])\n                    total += quantity * price\n            print(f\"Total: {total}\\n\")\n        case \"7\":\n            name = input(\"Nombre: \")\n            total = 0\n            with open(file_name, \"r\") as file:\n                for line in file.readlines():\n                    components = line.split(\", \")\n                    if components[0] == name.lower():\n                        quantity = int(components[1])\n                        price = float(components[2])\n                        total += quantity * price\n                        break\n            print(f\"Total: {total}\\n\")\n        case \"8\":\n            os.remove(file_name)\n            break\n        case _:\n            print(\"Selecciona una de las opciones disponibles.\")\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/Zequy40.py",
    "content": "'''\nDesarrolla un programa capaz de crear un archivo que se llame como\n  tu usuario de GitHub y tenga la extensión .txt.\n  Añade varias líneas en ese fichero:\n  - Tu nombre.\n  - Edad.\n  - Lenguaje de programación favorito.\n  Imprime el contenido.\n  Borra el fichero.\n'''\n\nimport os\n\ndef crear_archivo(usuario):\n    # Crear el archivo con el nombre de usuario.txt\n    nombre_archivo = usuario + \".txt\"\n    with open(nombre_archivo, \"w\") as archivo:\n        archivo.write(\"Nombre: {}\\n\".format(input(\"Introduce tu nombre: \")))\n        archivo.write(\"Edad: {}\\n\".format(input(\"Introduce tu edad: \")))\n        archivo.write(\"Lenguaje de programación favorito: {}\\n\".format(input(\"Introduce tu lenguaje de programación favorito: \")))\n    return nombre_archivo\n\ndef leer_archivo(nombre_archivo):\n    # Leer y mostrar el contenido del archivo\n    with open(nombre_archivo, \"r\") as archivo:\n        contenido = archivo.read()\n        print(\"Contenido del archivo:\")\n        print(contenido)\n\ndef borrar_archivo(nombre_archivo):\n    # Borrar el archivo\n    os.remove(nombre_archivo)\n    print(\"Archivo {} borrado.\".format(nombre_archivo))\n\ndef main():\n    usuario = input(\"Introduce tu nombre de usuario de GitHub: \")\n    nombre_archivo = crear_archivo(usuario)\n    leer_archivo(nombre_archivo)\n    borrar_archivo(nombre_archivo)\n\nif __name__ == \"__main__\":\n    main()\n\n'''\nDIFICULTAD EXTRA (opcional):\n  Desarrolla un programa de gestión de ventas que almacena sus datos en un \n  archivo .txt.\n  - Cada producto se guarda en una línea del archivo de la siguiente manera:\n    [nombre_producto], [cantidad_vendida], [precio].\n  - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n    actualizar, eliminar productos y salir.\n  - También debe poseer opciones para calcular la venta total y por producto.\n  - La opción salir borra el .txt.\n'''\n\nimport os\n\ndef guardar_venta(nombre_archivo, producto, cantidad, precio):\n    # Guardar la venta en el archivo\n    with open(nombre_archivo, \"a\") as archivo:\n        archivo.write(\"{},{},{}\\n\".format(producto, cantidad, precio))\n\ndef consultar_ventas(nombre_archivo):\n    # Consultar todas las ventas en el archivo\n    with open(nombre_archivo, \"r\") as archivo:\n        contenido = archivo.read()\n        print(\"Ventas:\")\n        print(contenido)\n\ndef calcular_venta_total(nombre_archivo):\n    # Calcular la venta total\n    venta_total = 0\n    with open(nombre_archivo, \"r\") as archivo:\n        for linea in archivo:\n            _, cantidad, precio = linea.strip().split(\",\")\n            venta_total += int(cantidad) * float(precio)\n    return venta_total\n\ndef calcular_venta_producto(nombre_archivo, producto):\n    # Calcular la venta total de un producto\n    venta_producto = 0\n    with open(nombre_archivo, \"r\") as archivo:\n        for linea in archivo:\n            nombre, cantidad, precio = linea.strip().split(\",\")\n            if nombre == producto:\n                venta_producto += int(cantidad) * float(precio)\n    return venta_producto\n\ndef actualizar_venta(nombre_archivo, producto, cantidad, precio):\n    # Actualizar una venta existente o añadir una nueva\n    ventas = []\n    with open(nombre_archivo, \"r\") as archivo:\n        for linea in archivo:\n            nombre, _, _ = linea.strip().split(\",\")\n            if nombre == producto:\n                ventas.append(\"{},{},{}\".format(producto, cantidad, precio))\n            else:\n                ventas.append(linea.strip())\n\n    with open(nombre_archivo, \"w\") as archivo:\n        archivo.write(\"\\n\".join(ventas))\n\ndef eliminar_venta(nombre_archivo, producto):\n    # Eliminar una venta\n    ventas = []\n    with open(nombre_archivo, \"r\") as archivo:\n        for linea in archivo:\n            nombre, _, _ = linea.strip().split(\",\")\n            if nombre != producto:\n                ventas.append(linea.strip())\n\n    with open(nombre_archivo, \"w\") as archivo:\n        archivo.write(\"\\n\".join(ventas))\n\ndef main():\n    nombre_archivo = \"ventas.txt\"\n\n    while True:\n        print(\"\\n--- Menú ---\")\n        print(\"1. Añadir venta\")\n        print(\"2. Consultar ventas\")\n        print(\"3. Calcular venta total\")\n        print(\"4. Calcular venta por producto\")\n        print(\"5. Actualizar venta\")\n        print(\"6. Eliminar venta\")\n        print(\"7. Salir\")\n\n        opcion = input(\"Seleccione una opción: \")\n\n        if opcion == \"1\":\n            producto = input(\"Nombre del producto: \")\n            cantidad = input(\"Cantidad vendida: \")\n            precio = input(\"Precio: \")\n            guardar_venta(nombre_archivo, producto, cantidad, precio)\n            print(\"Venta añadida con éxito.\")\n        elif opcion == \"2\":\n            consultar_ventas(nombre_archivo)\n        elif opcion == \"3\":\n            venta_total = calcular_venta_total(nombre_archivo)\n            print(\"Venta total: ${:.2f}\".format(venta_total))\n        elif opcion == \"4\":\n            producto = input(\"Nombre del producto: \")\n            venta_producto = calcular_venta_producto(nombre_archivo, producto)\n            print(\"Venta de {}: ${:.2f}\".format(producto, venta_producto))\n        elif opcion == \"5\":\n            producto = input(\"Nombre del producto a actualizar: \")\n            cantidad = input(\"Nueva cantidad vendida: \")\n            precio = input(\"Nuevo precio: \")\n            actualizar_venta(nombre_archivo, producto, cantidad, precio)\n            print(\"Venta actualizada con éxito.\")\n        elif opcion == \"6\":\n            producto = input(\"Nombre del producto a eliminar: \")\n            eliminar_venta(nombre_archivo, producto)\n            print(\"Venta eliminada con éxito.\")\n        elif opcion == \"7\":\n            # Borrar el archivo y salir\n            os.remove(nombre_archivo)\n            print(\"Archivo {} borrado. ¡Hasta luego!\".format(nombre_archivo))\n            break\n        else:\n            print(\"Opción no válida. Inténtalo de nuevo.\")\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/adolfolozaa.py",
    "content": "''' \r\nIMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\r\n *\r\n * EJERCICIO:\r\n * Desarrolla un programa capaz de crear un archivo que se llame como\r\n * tu usuario de GitHub y tenga la extensión .txt.\r\n * Añade varias líneas en ese fichero:\r\n * - Tu nombre.\r\n * - Edad.\r\n * - Lenguaje de programación favorito.\r\n * Imprime el contenido.\r\n * Borra el fichero.\r\n *\r\n * DIFICULTAD EXTRA (opcional):\r\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un \r\n * archivo .txt.\r\n * - Cada producto se guarda en una línea del archivo de la siguiente manera:\r\n *   [nombre_producto], [cantidad_vendida], [precio].\r\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\r\n *   actualizar, eliminar productos y salir.\r\n * - También debe poseer opciones para calcular la venta total y por producto.\r\n * - La opción salir borra el .txt.'''\r\n\r\nimport os\r\n\r\ndef create_file():\r\n    with open('adolfolozaa.txt', 'w') as file:\r\n        file.write('Adolfo Loza Almeida\\n')\r\n        file.write('Edad: 56\\n')\r\n        file.write('Lenguaje de programación favorito: Python\\n')\r\n\r\n    with open('adolfolozaa.txt', 'r') as file:\r\n        print(file.read())\r\n\r\n    os.remove('adolfolozaa.txt')\r\n\r\ncreate_file()\r\n\r\n\r\n'''\r\nDIFICULTAD EXTRA (opcional):\r\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un archivo .txt.\r\n * - Cada producto se guarda en una línea del archivo de la siguiente manera: [nombre_producto], [cantidad_vendida], [precio].\r\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar, actualizar, eliminar productos y salir.\r\n * - También debe poseer opciones para calcular la venta total y por producto.\r\n - La opción salir borra el .txt.\r\n '''\r\n\r\nimport os\r\nfrom os import path\r\n\r\ndef elim_reg(item):\r\n    with open(\"ventas.txt\", \"r\") as input_file:\r\n        with open(\"temp.txt\", \"w\") as output_file:\r\n            for line in input_file:\r\n                if item not in line.strip(\"\\n\"):\r\n                    output_file.write(line)\r\n    os.replace(\"temp.txt\", \"ventas.txt\")    \r\n\r\ndef ventas():\r\n    while True:\r\n        print('---------------------')\r\n        print('Gestión de ventas')\r\n        print('1. Añadir producto')\r\n        print('2. Consultar producto')\r\n        print('3. Actualizar producto')\r\n        print('4. Eliminar producto')\r\n        print('5. Venta total')\r\n        print('6. Salir')\r\n        print('---------------------')\r\n        action = input('Ingrese la acción deseada: ')\r\n\r\n        if action == '6':           #salir\r\n            print('Saliendo del programa')\r\n            os.remove(file_name)\r\n            break\r\n        elif action == '1':     #anadir\r\n            nombre_producto = input('ingrese el nombre del producto: ')\r\n            cantidad_vendida = input('ingrese la cantidad vendida: ')\r\n            precio = input('Ingrese precio: ')\r\n            with open(file_name, \"a\") as file:\r\n                file.write(nombre_producto + ', ')\r\n                file.write(cantidad_vendida + ', ')\r\n                file.write(precio +'\\n')\r\n\r\n        elif action == '2':     #consulta\r\n            if path.exists(file_name):\r\n\r\n                with open(file_name, \"r\") as file:\r\n                    for linea in file:\r\n                        print(linea)  \r\n                        \r\n            else:\r\n                print('no existen registros aun!!!')\r\n                \r\n\r\n        elif action == '3':         #actualizar\r\n            with open('ventas.txt', 'r') as file:\r\n                print(file.read())\r\n            item = input('Ingrese el producto que desea actualizar: ')\r\n            \r\n            elim_reg(item)\r\n             \r\n            with open(file_name, \"a\") as file:\r\n                cantidad_vendida = input('ingrese la nueva cantidad vendida: ')\r\n                precio = input('Ingrese el nuevo precio: ')\r\n                \r\n                file.write(item + ', ')\r\n                file.write(cantidad_vendida + ', ')\r\n                file.write(precio +'\\n')\r\n            with open('ventas.txt', 'r') as file:\r\n                print(file.read())\r\n\r\n\r\n\r\n        elif action == '4':         #eliminar\r\n            with open('ventas.txt', 'r') as file:\r\n                print(file.read())\r\n            item = input('Ingrese el producto que desea Borar: ')\r\n            elim_reg(item)\r\n\r\n        elif action == '5':         #total\r\n            if path.exists(file_name):\r\n                with open(file_name, \"r\") as file:\r\n                    total = 0\r\n                    for linea in file:\r\n                        linea = linea.split(',')\r\n                        item = linea[0]\r\n                        total1 = int(linea[1]) * int(linea[2]) \r\n                        print(f'EL total del producto {item} es: {total1}')\r\n                        total = total + total1\r\n                    print(f'la venta total es: {total}')\r\n            else:\r\n                print('no existen registros aun!!!')\r\n                \r\n\r\nglobal file_name\r\nfile_name = 'ventas.txt'\r\nventas()\r\n\r\n\r\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/adra-dev.py",
    "content": "\"\"\"\nEJERCICIO:\nDesarrolla un programa capaz de crear un archivo que se llame como tu\nusuario de GitHub y tenga la extension .txt.\n\nAñade varias líneas en ese fichero:\n- Tu nombre.\n- Edad.\n- Lenguaje de programación favorito.\nImprime el contenido.\nBorra el fichero.\n\nDIFICULTAD EXTRA (opcional):\nDesarrolla un programa de gestión de ventas que almacena sus datos en un \narchivo .txt.\n- Cada producto se guarda en una línea del arhivo de la siguiente manera:\n[nombre_producto], [cantidad_vendida], [precio].\n- Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\nactualizar, eliminar productos y salir.\n- También debe poseer opciones para calcular la venta total y por producto.\n- La opción salir borra el .txt.\n\nby adra-dev\n\"\"\"\n\n\"\"\"\nEjercicio\n\"\"\"\nimport os\n\n\ndef program():\n\n    file_name = \"adra-dev.txt\"\n\n    lines = [\"\\t-Adrian\\n\", \"\\t-26 años\\n\", \"\\t-Python\"]\n\n    with open(file_name, \"w\") as file:\n        file.writelines(lines)\n\n    with open(file_name, \"r\") as file:\n        print(file.read())\n        \n    archivo_a_eliminar = \"D:/Programacion/roadmap-retos-programacion/adra-dev.txt\"\n    \n    if os.path.exists(archivo_a_eliminar):\n        os.remove(archivo_a_eliminar)\n        print(\"Archivo eliminado con éxito.\")\n    else:\n        print(\"El archivo no existe.\")\n\n\nprogram()\n\n\n\"\"\"\nExtra\n\"\"\"\n\nfile_name = \"adra-dev_shop.txt\"\n\nopen(file_name, \"a\")\n\nwhile True:\n    print(\"1. Añadir producto\")\n    print(\"2. Consultar producto\")\n    print(\"3. Actualizar producto\")\n    print(\"4. Borrar producto\")\n    print(\"5. Mostrar productos\")\n    print(\"6. Calcular venta total\")\n    print(\"7. Calcular venta por producto\")\n    print(\"8. Salir\")\n\n    option = input(\"Selecciona una opción: \")\n\n    if option == \"1\":\n        name = input(\"Nombre: \")\n        quantity = input(\"Cantidad: \")\n        price = input(\"Precio: \")\n        with open(file_name, \"a\") as file:\n            file.write(f\"{name}, {quantity}, {price}\\n\")\n    elif option == \"2\":\n        name = input(\"Nombre: \")\n        with open(file_name, \"r\") as file:\n            for line in file.readlines():\n                if line.split(\", \")[0] == name:\n                    print(line)\n                    break\n    elif option == \"3\":\n        name = input(\"Nombre: \")\n        quantity = input(\"Cantidad: \")\n        price = input(\"Precio: \")\n        with open(file_name, \"r\") as file:\n            lines = file.readlines()\n        with open(file_name, \"w\") as file:\n            for line in lines:\n                if line.split(\", \")[0] == name:\n                    file.write(f\"{name}, {quantity}, {price}\\n\")\n                else:\n                    file.write(line)\n    elif option == \"4\":\n        name = input(\"Nombre: \")\n        with open(file_name, \"r\") as file:\n            lines = file.readlines()\n        with open(file_name, \"w\") as file:\n            for line in lines:\n                if line.split(\", \")[0] != name:\n                    file.write(line)\n    elif option == \"5\":\n        with open(file_name, \"r\") as file:\n            print(file.read())\n    elif option == \"6\":\n        total = 0\n        with open(file_name, \"r\") as file:\n            for line in file.readlines():\n                components = line.split(\", \")\n                quantity = int(components[1])\n                price = float(components[2])\n                total += quantity * price\n        print(total)\n    elif option == \"7\":\n        name = input(\"Nombre: \")\n        total = 0\n        with open(file_name, \"r\") as file:\n            for line in file.readlines():\n                components = line.split(\", \")\n                if components[0] == name:\n                    quantity = int(components[1])\n                    price = float(components[2])\n                    total += quantity * price\n                    break\n        print(total)\n    elif option == \"8\":\n        os.remove(file_name)\n        break\n    else:\n        print(\"Selecciona una de las opciones disponibles.\")\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/agusrosero.py",
    "content": "# /*\n#  * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n#  *\n#  * EJERCICIO:\n#  * Desarrolla un programa capaz de crear un archivo que se llame como\n#  * tu usuario de GitHub y tenga la extensión .txt.\n#  * Añade varias líneas en ese fichero:\n#  * - Tu nombre.\n#  * - Edad.\n#  * - Lenguaje de programación favorito.\n#  * Imprime el contenido.\n#  * Borra el fichero.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Desarrolla un programa de gestión de ventas que almacena sus datos en un\n#  * archivo .txt.\n#  * - Cada producto se guarda en una línea del arhivo de la siguiente manera:\n#  *   [nombre_producto], [cantidad_vendida], [precio].\n#  * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n#  *   actualizar, eliminar productos y salir.\n#  * - También debe poseer opciones para calcular la venta total y por producto.\n#  * - La opción salir borra el .txt.\n#  */\n\nimport os\n\n# EJERCICIO:\nnombre = 'Hernan\\n'\nedad = '23\\n'\nlenguaje_favorito = 'Python\\n'\n\nwith open('agusrosero.txt', 'r+') as file:\n    file.write(f'Nombre: {nombre}')\n    file.write(f'Edad: {edad}')\n    file.write(f'Lenguaje de programacion favorito: {lenguaje_favorito}')\n    print(file.read())\n    os.remove('agusrosero.txt')\n    file.close()\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/alanshakir.py",
    "content": "\"\"\"\n/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n * \n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n * archivo .txt.\n * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n */\n\"\"\"\nimport os\n\nfichero = open(\"alanshakir.txt\", \"w\")\nfichero.write(\"Mi nombre es: Alan Ramirez\\nEdad: 35 años\\nLenguaje de programacion: Python\")\nfichero.close()\n\nwith open(\"alanshakir.txt\", \"r\") as fichero:\n    print(fichero.read())\n\nos.remove(\"alanshakir.txt\")\n\n#Extra\ngestion_ventas = \"ventas.txt\"\ndef menu():\n    print(\"\\n Programa Gestion de Ventas: \")\n    print(\"1. añadir producto\")\n    print(\"2. consultar producto\")\n    print(\"3. actualizar producto\")\n    print(\"4. eliminar producto\")\n    print(\"5. mostrar productos\")\n    print(\"6. calcular venta total\")\n    print(\"7. calcular total producto\")\n    print(\"8. Salir del programa\")\n    while True:\n        action = int(input(\"Elija un numero entre 1 - 8: \"))\n        if action == 1:\n            name_product = input(\"ingrese el nombre del producto: \")\n            quantity = input(\"ingrese la cantidad vendida: \")\n            price = input(\"ingrese el precio del producto: \")\n            with open(gestion_ventas, \"a\") as fichero:\n                fichero.write(f\"{name_product},{quantity},{price}\\n\")\n        elif action == 2:\n            name_product = input(\"ingrese el nombre del producto: \")\n            with open(gestion_ventas, \"r\") as fichero:\n                for linea in fichero.readlines():\n                    if linea.split(\",\")[0] == name_product:\n                        print(linea)\n                        break   \n                else:\n                    print(\"producto no exite\")          \n        elif action == 3:\n            name_product = input(\"ingrese el nombre del producto: \")\n            quantity = input(\"ingrese la cantidad vendida: \")\n            price = input(\"ingrese el precio del producto: \")\n            with open(gestion_ventas, \"r\") as fichero:\n                lineas = fichero.readlines()\n            with open(gestion_ventas, \"w\") as fichero:\n                for linea in lineas:\n                    if linea.split(\",\")[0] == name_product:\n                        fichero.write(f\"{name_product},{quantity},{price}\\n\")                        \n                else:\n                    fichero.write(linea) \n        elif action == 4:\n            name_product = input(\"ingrese el nombre del producto: \")\n            with open(gestion_ventas, \"r\") as fichero:\n                lineas = fichero.readlines()\n            with open(gestion_ventas, \"w\") as fichero:\n                for linea in lineas:\n                        if linea.split(\",\")[0] != name_product:\n                            fichero.write(linea)\n        elif action == 5:\n            with open(gestion_ventas, \"r\") as fichero:\n                print(fichero.read())\n        elif action == 6:\n            total_ventas = 0\n            with open(gestion_ventas, \"r\") as fichero:\n                for linea in fichero.readlines():\n                    products = linea.split(\",\")\n                    quantity = int(products[1])\n                    price = float(products[2])\n                    total_ventas += quantity + price\n            print(total_ventas)\n        elif action == 7:\n            name_product = input(\"ingrese el nombre del producto: \")\n            total_productos = 0\n            with open(gestion_ventas, \"r\") as fichero:\n                for linea in fichero.readlines():\n                    products = linea.split(\",\")\n                    if products[0] == name_product:\n                        quantity = int(products[1])\n                        price = float(products[2])\n                        total_productos += quantity + price\n                        break\n            print(total_ventas)\n        elif action == 8:\n            os.remove(gestion_ventas)\n            break\n        else:\n            print(\"elija una opcion valida\")\n\n\nmenu()\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/alcaan16.py",
    "content": "\"\"\"\n/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n * archivo .txt.\n * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n */\"\"\"\n\nimport os\n\n\"\"\"\nEjercicio\n\"\"\"\nfile_name=\"alferez.txt\"\n\nwith open(file_name, \"w\")as file:\n    file.write (\"angel\\n\")\n    file.write (\"35\\n\")\n    file.write (\"python\")\n\nwith open(file_name, \"r\") as file:\n    print(file.read())\n\nos.remove(file_name)\n\n\"Extra\"\n\nfile_name=\"tienda.txt\"\nwith open(file_name, \"a\")as file:\n    pass\n\nwhile True:\n\n    print(\"******************\")\n    print(\"1. Añadir producto\")\n    print(\"2. Mostrar producto\")\n    print(\"3. Actualizar producto\")\n    print(\"4. Eliminar producto\")\n    print(\"5. Mostrar todos los productos\")\n    print(\"6. Ventas por producto\")\n    print(\"7. Ventas totales\")\n    print(\"8. Salir\")\n    print(\"******************\")\n\n    opcion = input(\"\\nIntroduce la opcion deseada: \" )\n\n    match opcion:\n        case \"1\":\n            print(\"1. Añadir producto.\")\n            name=input(\"introduce el nombre del producto \")\n            cantidad=input(\"introduce la cantidad \")\n            price=input(\"introduce el precio del producto \")\n                        \n            with open(file_name, \"a\")as file:\n                file.write (f\"{name}, {cantidad}, {price}, \\n\")\n        \n        case \"2\":\n            print(\"2. Mostrar producto\")\n            name=input(\"introduce el nombre del producto: \")\n            flag=0\n            with open(file_name, \"r\") as file:\n                filas = file.readlines()\n                if len(filas) >= 1:\n                    for line in filas:\n                        if line.split(\", \")[0] == name:\n                            print(line)\n                            flag=1\n                            break\n                    if flag==0:\n                        print(\"no hay productos con ese nombre\")                        \n                else:\n                        print(\"no hay productos\")   \n\n        case \"3\":\n            print(\"3. Actualizar producto\")\n            name=input(\"introduce el nombre del producto: \")\n            cantidad=input(\"introduce la cantidad \")\n            price=input(\"introduce el precio del producto \")\n\n            flag=0\n            with open(file_name, \"r\") as file:\n                filas = file.readlines()\n            with open(file_name, \"w\") as file:\n                if len(filas) >= 1:\n                    for line in filas:\n                        if line.split(\", \")[0] == name:\n                            file.write (f\"{name}, {cantidad}, {price}, \\n\")\n                            flag=1\n                        else:\n                            file.write (line)                            \n                    if flag==0:\n                        print(\"no hay productos con ese nombre\")                        \n                else:\n                        print(\"no hay productos\")\n\n        case \"4\":\n            print(\"4. Eliminar producto\")\n            name=input(\"introduce el nombre del producto: \")\n\n            flag=0\n            with open(file_name, \"r\") as file:\n                filas = file.readlines()\n            with open(file_name, \"w\") as file:\n                if len(filas) >= 1:\n                    for line in filas:\n                        if line.split(\", \")[0] != name:\n                            file.write (line)\n                        else:\n                             flag=1\n                             print(f\"producto {name} eliminado\")                           \n                    if flag==0:\n                        print(\"no hay productos con ese nombre\")                        \n                else:\n                        print(\"no hay productos\")\n            \n        \n        case \"5\":\n            print(\"5. Mostrar todos los productos\")\n            with open(file_name, \"r\") as file:\n                print(file.read())\n\n        case \"6\":\n            print(\"6. Ventas por producto\")\n            name=input(\"introduce el nombre del producto: \")\n            suma=0\n            with open(file_name, \"r\") as file:\n                filas = file.readlines()\n                if len(filas) >= 1:\n                    for line in filas:\n                        if line.split(\", \")[0] == name:\n                            print(line.split(\", \")[1])\n                            print(line.split(\", \")[2])\n                            suma = float(line.split(\", \")[1]) * float(line.split(\", \")[2])\n                            print(suma)\n                            flag=1\n                            break\n                    if flag==0:\n                        print(\"no hay productos con ese nombre\")    \n                else:\n                        print(\"no hay productos\")\n\n        case \"7\":\n            print(\"7. Ventas totales\")\n            suma=0\n            with open(file_name, \"r\") as file:\n                filas = file.readlines()\n                if len(filas) >= 1:\n                    for line in filas:\n                        suma += float(line.split(\", \")[1]) * float(line.split(\", \")[2])\n                    print(suma)                                                       \n                else:\n                        print(\"no hay productos\")\n              \n        case \"8\":\n            print(\"8. Salir\")\n            print(\"Saliendo...\")\n            #os.remove(file_name) #descomentar para borrar el archivo al salir\n            break\n\n        case _:\n            print (\"Introduce una opcion valida. Desde el 1 al 8\")\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/alexdevrep.py",
    "content": "'''\n/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n * archivo .txt.\n * - Cada producto se guarda en una línea del arhivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n */\n'''\n\n#Creamos un archivo de texto\narchivo = open(\"alexdevrep.txt\",\"x\")\n\n#Usamos close() para cambiar los modos de acceso a archivos\narchivo.close()\n\n#Abrimos el archivo en modo escritura\narchivo= open(\"alexdevrep.txt\",\"w\")\n\n#Añadimos contenido al archivo\narchivo.writelines([\"Alejandro \\n\", \"24 \\n\", \"Python \\n\"])\narchivo.close()\n\n\n#Abrimos de nuevo el archivo en modo lectura\narchivo= open(\"alexdevrep.txt\",\"r\")\n\n#Imprimimos el archivo en la terminal\nprint(archivo.read())\n\n#Borramos el archivo creado\nimport os #Importamos las librerias necesarias\narchivo= \"alexdevrep.txt\"\nos.remove(archivo)\nprint(\"El archivo ha sido eliminado con éxito\")\n\n\n#Dificultad EXTRA\n\nlista = []\n\ndef gestion(accion):\n    global lista\n    if accion == 'añadir':\n        print(\"Añada el producto a la lista\")\n        nombre_producto = input(\"Por favor indique el nombre del producto: \")\n        cantidad_vendida = input(\"Por favor indique las unidades vendidas: \")\n        precio_unitario = input(\"Por favor indique el precio unitario: \")\n        producto = {\n            \"Nombre del producto\": nombre_producto,\n            \"Cantidad Vendida\": cantidad_vendida,\n            \"Precio unitario\": precio_unitario\n        }\n        lista.append(producto)\n\n    elif accion == 'consultar':\n        print(lista)\n\n    elif accion == 'actualizar':\n        producto_actualizar = input(\"Por favor indique el nombre del producto a actualizar: \")\n        for i, prod in enumerate(lista):\n            if prod[\"Nombre del producto\"] == producto_actualizar:\n                lista.pop(i)\n                print(\"Ingrese la información actualizada del producto\")\n                cantidad_vendida = input(\"Por favor indique las unidades vendidas: \")\n                precio_unitario = input(\"Por favor indique el precio unitario: \")\n                prod[\"Cantidad Vendida\"] = cantidad_vendida\n                prod[\"Precio unitario\"] = precio_unitario\n                lista.append(prod)\n                break\n        else:\n            print(\"El producto no existe\")\n\n    elif accion == 'eliminar':\n        producto_eliminar = input(\"Por favor indique el producto a eliminar: \")\n        lista = [prod for prod in lista if prod[\"Nombre del producto\"] != producto_eliminar]\n\n    elif accion == 'guardar':\n        try:\n            with open(\"gestion_de_ventas.txt\", \"w\") as fichero:\n                for prod in lista:\n                    fichero.write(f\"{prod['Nombre del producto']}, {prod['Cantidad Vendida']}, {prod['Precio unitario']}\\n\")\n            print(\"Datos guardados con éxito.\")\n        except Exception as e:\n            print(f\"Error al guardar datos: {e}\")\n            \n    elif accion == 'salir':\n        try:\n            os.remove(\"gestion_de_ventas.txt\")\n            print(\"Archivo eliminado con éxito\")\n        except FileNotFoundError:\n            print(\"El archivo no existe\")\n\nwhile True:\n    print(\"Archivo de la gestión de ventas\")\n    print(\"Funciones disponibles: añadir, consultar, actualizar, eliminar, guardar, salir\")\n    accion = input(\"Escriba una de las funciones disponibles: \")\n    gestion(accion)\n\n    if accion == 'salir':\n        break\n    \n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/any7dev.py",
    "content": "# /*\n#  * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n#  * \n#  * EJERCICIO:\n#  * Desarrolla un programa capaz de crear un archivo que se llame como\n#  * tu usuario de GitHub y tenga la extensión .txt.\n#  * Añade varias líneas en ese fichero:\n#  * - Tu nombre.\n#  * - Edad.\n#  * - Lenguaje de programación favorito.\n#  * Imprime el contenido.\n#  * Borra el fichero.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n#  * archivo .txt.\n#  * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n#  *   [nombre_producto], [cantidad_vendida], [precio].\n#  * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n#  *   actualizar, eliminar productos y salir.\n#  * - También debe poseer opciones para calcular la venta total y por producto.\n#  * - La opción salir borra el .txt.\n#  */\n\n#EJERCICIO\nimport os\n\ndef crea_archivo(nombre, contenido):\n    if not os.path.exists(nombre): #Para saber si ya existe el archivo\n        with open (nombre, 'w') as archivo: #Crea el archivo abriéndolo y cerrándolo\n            archivo.write(contenido)\n    else:\n        print(\"El archivo ya existe\")\n    if os.path.exists(nombre):\n        with open (nombre, 'r') as archivo: #Abre el archivo abriéndolo y cerrándolo\n            print(archivo.read())\n    else:\n        print(\"El archivo no existe\")\n    os.remove(nombre) #Elimina el archivo.\n\ncrea_archivo(\"any7dev.txt\", \"Ana\\n36\\nPython\")\n\n#DIFICULTAD EXTRA\ndef gestor_ventas():\n    archivo = \"gestion_ventas.txt\"\n    open(archivo, 'w').close()\n    while True:\n        opcion = input(\"\\nDime tu opción: \\n\\t1-Añadir producto vendido \\n\\t2-Consultar archivo \\n\\t3-Actualizar \\n\\t4-Eliminar \\n\\t5-Totales \\n\\ts-Salir \\nOpción--> \")\n        match opcion:\n            case \"1\":\n                añadir(archivo)\n            case \"2\":\n                if os.stat(archivo).st_size == 0:\n                    print(\"El archivo está vacío\")\n                else:\n                    consultar(archivo)\n            case \"3\":\n                if os.stat(archivo).st_size == 0:\n                    print(\"El archivo está vacío\")\n                else:\n                    actualizar(archivo)\n            case \"4\":\n                if os.stat(archivo).st_size == 0:\n                    print(\"El archivo está vacío\")\n                else:\n                    eliminar(archivo)\n            case \"5\":\n                if os.stat(archivo).st_size == 0:\n                    print(\"El archivo está vacío\")\n                else:\n                    totales(archivo)\n            case \"s\":\n                print(\"Saliendo...\")\n                os.remove(archivo)\n                break\n            case _:\n                print(\"Opción incorrecta\")\n\ndef añadir(archivo):\n    producto = \"\"\n    nombre = input(\"Dime el nombre: \")    \n    try:\n        cantidad = int(input(\"Cantidad vendida: \"))\n        precio = float(input(\"Precio: \"))\n        producto = f\"{nombre}, {cantidad}, {precio}\\n\"\n        with open (archivo, 'a') as a:\n            a.write(producto)\n        print(\"Producto añadido\")\n    except ValueError:\n        print(\"La cantidad debe ser un número entero y el precio entero o decimal\")  \n\n\ndef consultar(archivo):\n    with open (archivo, 'r') as a:\n        print(a.read())\n\ndef actualizar(archivo):\n    buscar = input(\"Dime el valor del campo a actualizar: \")\n    cambiar = input(\"Dime lo que quieres poner: \")\n\n    contenido = open(archivo, 'r').read()\n    contenido = contenido.replace(buscar, cambiar)\n\n    with open (archivo, 'w') as a:\n        a.write(contenido)\n    print(\"Cambio realizado\")\n\ndef eliminar(archivo):\n    producto = input(\"Dime el nombre del producto a eliminar: \")\n    encontrado = False\n    contador = 0\n\n    with open (archivo, 'r') as a:\n        for linea in a:\n            if producto in linea:\n                encontrado = True\n                break                \n            else:\n                contador += 1\n    \n    if encontrado:\n        a = open (archivo, 'r')\n        lineas = a.readlines()\n        a.close()\n        with open (archivo, 'w') as a:\n            linea = lineas[contador]\n            lineas.remove(linea)\n            for linea in lineas:\n                a.write(linea)\n        print(\"Producto eliminado\")\n    else:\n        print(\"Producto no encontrado\")\n        \ndef totales(archivo):\n    lista = []\n    suma = 0\n    total = 0\n\n    with open (archivo, 'r') as a:\n        lista = [linea.split(\", \") for linea in a]\n        for linea in lista:\n            suma += float(linea[1]) * float(linea[2]) \n            print(f\"Cantidad ganada con ventas de {linea[0]}: {suma}\")\n            total += suma\n    print(f\"Cantidad total ganada por las ventas: {total}\")       \n\n\ngestor_ventas()"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/avcenal.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n\"\"\"\nfrom time import sleep\nfrom os import remove\n\ndef txt_file():\n    with open(\"avcenal.txt\",\"w+\") as my_file:\n        my_file.writelines(\"Nombre: Alex\\nEdad: 39\\nLenguaje Favorito: Python\")\n\n    my_file.close()\n\n    with open(\"avcenal.txt\",\"r+\") as my_file:\n        for line in my_file.readlines():\n            print(line)\n            \n\n    my_file.close()\n    remove(\"avcenal.txt\")\n\ntxt_file()\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n * archivo .txt.\n * - Cada producto se guarda en una línea del arhivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n\"\"\"\n\ndef add_products(path):\n    product_name = input(\"Dime el nombre del producto: \")\n    product_units_sold = input (\"Dime cuantas unidades has veniddo: \") #podría controlar que sea una cifra con una regex\n    product_price = input (\"Dime el precio del producto: \")\n    with open(path,\"a\") as file:\n        file.write(f\"{product_name}, {product_units_sold}, {product_price}\\n\")\n\n    file.close\n    print(f\"El producto {product_name} ha sido añadido al archivo de ventas\\n\")\n    sleep(1)\n\ndef check_products(path):\n    try:\n        with open(path,\"r\") as file:\n            lines = file.readlines()\n    except FileNotFoundError:\n        print(\"No hay registros de ventas por el momento...\\n\")\n        sleep(1)\n    else:\n        print(\"Estos son los productos que tenemos en el sistema:\\n\")\n        for line in lines:\n            print(line)\n\ndef update_products(path):\n    try:\n        with open(path,\"r\") as file:\n            lines = file.readlines()\n    except FileNotFoundError:\n        print(\"No hay registros de ventas por el momento...\\n\")\n        sleep(1)\n    else:\n        file.close()\n        product = input(\"Dime el nombre producto a actualizar por favor: \")\n        for index in range(0,len(lines)):\n            products = lines[index].split(\",\")\n            if product in products:\n                line_number = index\n                while True:\n                    option = input(\"¿Quieres actualizar las unidades vendidas(U) o el precio(P)?: \").upper()\n                    if option == \"U\":\n                        units = input(\"Perfecto, dime las unidades que has vendido en total: \")\n                        temp_line = lines[line_number].split(\",\")\n                        temp_line[1] = units\n                        lines[line_number] = f\"{temp_line[0]}, {temp_line[1]}, {temp_line[2]}\"\n                        print(f\"El producto {product} ha sido actualizado\\n\")\n                        sleep(1)\n                        break\n                    elif option == \"P\":\n                        price = input(\"Entendido, dime el nuevo precio: \")\n                        temp_line = lines[line_number].split(\",\")\n                        temp_line[2] = price\n                        lines[line_number] = f\"{temp_line[0]}, {temp_line[1]}, {temp_line[2]}\\n\"\n                        print(f\"El producto {product} ha sido actualizado\\n\")\n                        sleep(1)\n                        break\n                    else:\n                        print(\"La opción no es válida, prueba de nuevo...\\n\")\n                        sleep(1)\n                with open(path,\"w\") as file:\n                    file.writelines(lines)\n                file.close()\n                break\n            elif index == len(lines)-1:\n                print(\"El producto indicado no se encuentra en el archivo de ventas\\n\")\n                sleep(1)\n                break\n\ndef erase_products(path):\n    try:\n        with open(path,\"r\") as file:\n            lines = file.readlines()\n    except FileNotFoundError:\n        print(\"No hay registros de ventas por el momento...\\n\")\n        sleep(1)\n    else:\n        file.close()\n        product = input(\"¿Qué producto deseas eliminar?: \")\n        for index in range(0,len(lines)):\n            if product in lines[index].split(\",\"):\n                line_number = index\n                lines.remove(lines[line_number])\n                with open(path,\"w\") as file:\n                    file.writelines(lines)\n\n                print(\"Producto eliminado del archivo de ventas\\n\")\n                sleep(1)\n                break\n        if index == len(lines)-1:\n            print(\"El producto no se encuentra en el archivo de ventas\\n\")\n            sleep(1)\n\ndef total_sales(path):\n    try:\n        with open(path,\"r\") as file:\n            lines = file.readlines()\n    except FileNotFoundError:\n        print(\"No hay registros de ventas por el momento...\\n\")\n        sleep(1)\n    else:\n        file.close()\n        print(\"\\n\")\n        print(\"El total de ventas por producto es:\")\n        for index in range(0,len(lines)):\n            line = lines[index].split(\",\")\n            total = int(line[1]) * int(line[2])\n            print(f\"{line[0]} - total ventas (EUR): {total}\")\n    print(\"\\n\")\n    sleep(1)\n\ndef sales_management():\n    file_path = \"sales.txt\"\n    print(\"Bienvenido/a al programa de gestión de ventas\")\n    while True:\n        option = input(\"¿Qué deseas hacer?\\n A - Añadir Productos\\n C - Consultar Productos\\n U - Actualizar Productos\\n V - Venta total por producto\\n E - Eliminar Productos\\n S - Salir\\n Escribe tu opción ---> \").upper()\n        if option == \"A\":\n            add_products(file_path)\n        elif option == \"C\":\n            check_products(file_path)\n        elif option == \"U\":\n            update_products(file_path)\n        elif option == \"V\":\n            total_sales(file_path)\n        elif option == \"E\":\n            erase_products(file_path)\n        elif option == \"S\":\n            print(\"Gracias por usar nuestro sistema. Hasta pronto\\n\")\n            try:\n                remove(file_path)\n            except:\n                pass\n            break\n        else:\n            print(\"La opcion es incorrecta, prueba de nuevo por favor\\n\")\n            sleep(1)\n        \nsales_management()\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/barrancus.py",
    "content": "\"#[número] - [lenguaje_utilizado]\"\n# \n# IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n# \n# EJERCICIO:\n# Desarrolla un programa capaz de crear un archivo que se llame como\n# tu usuario de GitHub y tenga la extensión .txt.\n# Añade varias líneas en ese fichero:\n# - Tu nombre.\n# - Edad.\n# - Lenguaje de programación favorito.\n# Imprime el contenido.\n# Borra el fichero.\n# \n# DIFICULTAD EXTRA (opcional):\n# Desarrolla un programa de gestión de ventas que almacena sus datos en un \n# archivo .txt.\n# - Cada producto se guarda en una línea del archivo de la siguiente manera:\n#   [nombre_producto], [cantidad_vendida], [precio].\n# - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n#   actualizar, eliminar productos y salir.\n# - También debe poseer opciones para calcular la venta total y por producto.\n# - La opción salir borra el .txt.\n# \nimport os\nfrom random import randint\n\ndef serparacion(cadena):\n    print('{}'.format(cadena * 20))\n\ndef first():\n    bfile = open(file='barrancus.txt', mode='w+', encoding='UTF-8')\n    print(f'Se puede escribir en el archivo {bfile.name}: {bfile.writable()}')\n    print(f'Se puede leer el archivo {bfile.name}: {bfile.readable()}')\n    bfile.write(\"David Miño\\n\")\n    bfile.write(\"47\\n\")\n    bfile.write(\"Python\\n\")\n    if randint(0,1): bfile.close()\n    serparacion('---')\n    if bfile.closed:\n        bfile = open(file='barrancus.txt', mode='r+', encoding='UTF-8')\n        print(f'Se puede escribir en el archivo {bfile.name}: {bfile.writable()}')\n        print(f'Se puede leer el archivo {bfile.name}: {bfile.readable()}')\n        print(bfile.read())\n        bfile.close()\n    else:\n        bfile.seek(0)\n        print(bfile.read())\n        bfile.close()\n    os.remove(bfile.name)\n    serparacion('---')\n\nSTOCK = 'stock.txt'\n\nclass NoProduct(Exception):\n    pass\n\nclass Producto:\n    \n    def __init__(self,*args: list):\n        self.nombre_producto, self.cantidad_vendida, self.precio, *self.trash = args\n        self.nombre_producto = self.nombre_producto.strip()\n        self.cantidad_vendida = int(self.cantidad_vendida)\n        self.precio = float(self.precio)\n        \n    def ventas(self) -> float:\n        return self.cantidad_vendida * self.precio\n    \nclass Archivo:\n\n    def __init__(self, nombre_archivo: str):\n        self.nombre_archivo = nombre_archivo\n        self.stock = \"\"\n        self.stock_dict = {}\n    \n    def file_check(self) -> bool:\n        if self.nombre_archivo in os.listdir():\n            self.stock = open(self.nombre_archivo, 'r+', encoding='UTF-8')\n            self.stock.seek(0)\n            self.file_content()\n            self.stock.close()\n            return False\n        else:\n            return True\n\n    def file_content(self) -> dict:\n        if len(self.stock.read()) != 0:\n            self.stock.seek(0)\n            stock_id = 0\n            for line in self.stock.readlines():\n                self.stock_dict[stock_id] = Producto(*line.split(','))\n                stock_id += 1\n        self.file_print()\n        \n    def file_find(self, product: str) -> list:\n        for fid in self.stock_dict.keys():\n            if product in self.stock_dict[fid].nombre_producto:\n                return self.stock_dict[fid], fid\n        raise NoProduct('No existe el producto en el stock')\n\n    def file_add_update(self, product: str, precio: float, cantidad_vendida: int) -> object:\n        try:\n            objprod, fid = self.file_find(product)\n            del self.stock_dict[fid]\n            if cantidad_vendida != \"\": objprod.cantidad_vendida = int(cantidad_vendida)\n            if precio != \"\": objprod.precio = float(precio)\n\n        except NoProduct:\n            if len(self.stock_dict.keys()) == 0:\n                fid = 0\n            else:\n                fid = 0\n                for keyid in self.stock_dict.keys():\n                    if keyid > fid:\n                        fid = keyid\n                fid = keyid + 1\n            objprod = Producto(product, cantidad_vendida, precio)\n\n        finally:\n            self.stock_dict[fid] = objprod\n            self.file_uptade()\n\n        return self.stock_dict[fid]\n\n    def file_del(self, product) -> bool:\n        try:\n            objprod, fid = self.file_find(product)\n            del self.stock_dict[fid]\n            sorted(self.stock_dict)\n        except NoProduct as baderror:\n            print(f'{NoProduct.__name__}: {baderror}')\n        finally:\n            self.file_uptade()\n\n        return True\n\n    def file_close(self):\n        self.file_uptade()\n        self.stock.close()\n\n    def file_print(self) -> print:\n        for element in self.stock_dict.values():\n            print(f'Producto: {element.nombre_producto}, Ventas: {element.cantidad_vendida}, Precio: {element.precio}')\n\n    def file_uptade(self):\n        self.stock = open(self.nombre_archivo, 'w', encoding='UTF-8')\n        for objprod in self.stock_dict.values():\n            self.stock.write(f'{objprod.nombre_producto}, {objprod.cantidad_vendida}, {objprod.precio}\\n')\n\n    def total_sells(self, products = []) -> float:\n        print(products)\n        print(type(products))\n        print(\"melones\" in products)\n        print(len(products))\n        if len(products) == 0:\n            return sum([objprod.precio * objprod.cantidad_vendida for objprod in self.stock_dict.values()])\n        else:\n            return sum([objprod.precio * objprod.cantidad_vendida for objprod in self.stock_dict.values() if objprod.nombre_producto in products])\n            \n\ndef main():\n    first()\n    my_file = Archivo(STOCK)\n    menu = my_file.file_check()\n    while True:\n        if menu:\n            print('\\nEl archivo se ha creado nuevo.')\n            print('Por favor seleccione una de las siguientes opciones:')\n            menu = False\n        else:\n            print('\\nPor favor seleccione una de las siguientes opciones:')\n        \n        print('1.- Añadir productos al stock.')\n        print('2.- Encontrar productos en stock.')\n        print('3.- Actualizar estado del producto en stock.')\n        print('4.- Eliminar productos del stock.')\n        print('5.- Imprimir stock.')\n        print('6.- Imprimir Ventas Totales.')\n        print('7.- Imprimir Ventas por productos.')\n        print('0.- Salir del programa\\n')\n        option = input('OPCION>')\n\n        match option:\n            case \"1\":\n                while True:\n                    print('\\nSi quiere terminar de introducir productos ingrese salir en el nombre del producto')\n                    product = input('\\nIngrese el nombre del producto: ').lower()\n                    if product == \"salir\": break\n                    productprice = input('Ingrese el precio del producto: ').lower()\n                    productsells = input('Ingrese las ventas del producto: ').lower()\n                    my_file.file_add_update(product, productprice, productsells)\n            case \"2\":\n                product = input('\\nIngrese el producto a buscar: ').lower()\n                try:\n                    answer, ident = my_file.file_find(product)\n                    print(f'\\nEl producto {answer.nombre_producto} tiene un precio de {answer.precio} y se han vendido {answer.cantidad_vendida}', end =\" \")\n                    print(f'con unas ganancias de {answer.ventas():n}€')\n                except NoProduct as baderror:\n                    print(f'{NoProduct.__name__}: {baderror}')\n                finally:\n                    print('\\nContinuamos con las operaciones.')\n            case \"3\":\n                product = input('\\nIngrese el producto a actualizar: ').lower()\n                productprice = input('Ingrese el precio del producto a actualizar: ').lower()\n                productsells = input('Ingrese las ventas del producto a actualizar: ').lower()\n                try:\n                    answer = my_file.file_add_update(product, productprice, productsells)\n                    print(f'\\nEl producto {answer.nombre_producto} tiene un precio de {answer.precio} y se han vendido {answer.cantidad_vendida}', end =\" \")\n                    print(f'con unas ganancias de {answer.ventas():n}€')\n                except NoProduct as baderror:\n                    print(f'{NoProduct.__name__}: {baderror}')\n                finally:\n                    print('\\nContinuamos con las operaciones.')\n            case \"4\":\n                product = input('\\nIngrese el producto a eliminar: ').lower()\n                my_file.file_del(product)\n            case \"5\":\n                my_file.file_print()\n            case \"6\":\n                print(f'\\nVentas totales: {my_file.total_sells():n}€')\n            case \"7\":\n                products = input('\\nIngrese el producto a eliminar, separados por \",\": ').lower()\n                products = products.strip().replace(\", \", \",\").split(\",\")\n                print(f'Ventas totales de {products}: {my_file.total_sells(products):n}€')\n            case \"0\":\n                my_file.file_close()\n                borrar = input('Desea borrar el archivo(yes/no):\\n>').lower()\n                while borrar != 'yes' and borrar != 'no':\n                    borrar = input('Desea borrar el archivo(yes/no):\\n>').lower()\n                    print(borrar != 'yes' and borrar != 'no')\n                if borrar == 'yes': os.remove(STOCK)\n                break\n            case _:\n                print('\\nSeleccione una opción correcta por favor.\\n')\n\nmain()\nserparacion('---')\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/cesar-ch.py",
    "content": "\"\"\"\n    * #11 MANEJO DE FICHEROS\n\"\"\"\n\nimport os\n\n\ndef crear_archivo():\n    nombre = \"cesar-ch\"\n    edad = 4\n    lenguaje_favorito = \"JavaScript\"\n    contenido = f\"Nombre: {nombre}\\nEdad: {edad}\\nLenguaje de programación favorito: {lenguaje_favorito}\"\n    with open(f\"{nombre}.txt\", \"w\") as file:\n        file.write(contenido)\n    print(f\"1. Archivo {nombre}.txt creado exitosamente\")\n    print(\"2. Contenido añadido al archivo\")\n    leer_archivo(nombre)\n\n\ndef leer_archivo(nombre):\n    with open(f\"{nombre}.txt\", \"r\") as file:\n        data = file.read()\n        print(\"3. Contenido leído del archivo\")\n        print(data)\n    borrar_archivo(nombre)\n\n\ndef borrar_archivo(nombre):\n    os.remove(f\"{nombre}.txt\")\n    print(\"4. Archivo eliminado exitosamente\")\n    menu()\n\n\n\"\"\"\n    * DIFICULTAD EXTRA\n\"\"\"\n\n\ndef menu():\n    print(\"\\n=== Gestión de Ventas ===\")\n    print(\"1. Añadir producto\")\n    print(\"2. Consultar producto\")\n    print(\"3. Actualizar producto\")\n    print(\"4. Eliminar producto\")\n    print(\"5. Calcular venta total\")\n    print(\"6. Calcular venta por producto\")\n    print(\"7. Salir\")\n    print(\"===========================\")\n    seleccionar_opcion()\n\n\ndef seleccionar_opcion():\n    opcion = input(\"Seleccione una opción: \")\n    if opcion == \"1\":\n        añadir_producto()\n    elif opcion == \"2\":\n        consultar_producto()\n    elif opcion == \"3\":\n        actualizar_producto()\n    elif opcion == \"4\":\n        eliminar_producto()\n    elif opcion == \"5\":\n        calcular_venta_total()\n    elif opcion == \"6\":\n        calcular_venta_por_producto()\n    elif opcion == \"7\":\n        eliminar_archivo()\n        exit()\n    else:\n        seleccionar_opcion()\n\n\ndef añadir_producto():\n    nombre = input(\"Introduce el nombre del producto: \")\n    cantidad = input(\"Introduce la cantidad del producto: \")\n    precio = input(\"Introduce el precio del producto: \")\n    producto = f\"{nombre},{cantidad},{precio}\\n\"\n    with open(\"productos.txt\", \"a\") as file:\n        file.write(producto)\n    print(\"Producto añadido correctamente\")\n    file.close()\n    menu()\n\n\ndef consultar_producto():\n    nombre = input(\"Introduce el nombre del producto a consultar: \")\n    with open(\"productos.txt\", \"r\") as file:\n        data = file.readlines()\n        for producto in data:\n            if producto.split(\",\")[0] == nombre:\n                print(f\"Producto encontrado: {producto.strip()}\")\n                file.close()\n                menu()\n\n        else:\n            print(\"Producto no encontrado\")\n            menu()\n\n\ndef actualizar_producto():\n    nombre = input(\"Introduce el nombre del producto a actualizar: \")\n    cantidad = input(\"Introduce la nueva cantidad del producto: \")\n    precio = input(\"Introduce el nuevo precio del producto: \")\n    nuevo_producto = f\"{nombre},{cantidad},{precio}\\n\"\n    with open(\"productos.txt\", \"r\") as file:\n        data = file.readlines()\n    with open(\"productos.txt\", \"w\") as file:\n        for producto in data:\n            if producto.split(\",\")[0] == nombre:\n                productosfiltrados = list(\n                    filter(lambda x: x.split(\",\")[0] != nombre, data)\n                )\n                file.writelines(productosfiltrados)\n                file.write(nuevo_producto)\n                print(\"Producto actualizado correctamente\")\n                file.close()\n                menu()\n        else:\n            print(\"Producto no encontrado\")\n            menu()\n\n\ndef eliminar_producto():\n    nombre = input(\"Introduce el nombre del producto a eliminar: \")\n    with open(\"productos.txt\", \"r\") as file:\n        data = file.readlines()\n    with open(\"productos.txt\", \"w\") as file:\n        for producto in data:\n            if producto.split(\",\")[0] != nombre:\n                file.write(producto)\n            else:\n                print(\"Producto eliminado correctamente\")\n    file.close()\n    menu()\n\n\ndef calcular_venta_total():\n    total = 0\n    with open(\"productos.txt\", \"r\") as file:\n        data = file.readlines()\n        for producto in data:\n            nombre, cantidad, precio = producto.split(\",\")\n            total += int(cantidad) * float(precio)\n    print(f\"Venta total: {total}\")\n    file.close()\n    menu()\n\n\ndef calcular_venta_por_producto():\n    nombre = input(\"Introduce el nombre del producto a consultar: \")\n    with open(\"productos.txt\", \"r\") as file:\n        data = file.readlines()\n        for producto in data:\n            if producto.split(\",\")[0] == nombre:\n                nombre, cantidad, precio = producto.split(\",\")\n                total = int(cantidad) * float(precio)\n                print(f\"Venta total: {total}\")\n                file.close()\n                menu()\n        else:\n            print(\"Producto no encontrado\")\n            menu()\n\n\ndef eliminar_archivo():\n    os.remove(\"productos.txt\")\n    print(\"Archivo eliminado correctamente\")\n\n\nif __name__ == \"__main__\":\n    crear_archivo()\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/clmiranda.py",
    "content": "# MANEJO DE FICHEROS\n\nimport os\n\nusername = \"clmiranda.txt\"\n\nwith open(username, \"w\") as f:\n    f.write(\"Cliver\\n\")\n    f.write(\"27 años\\n\")\n    f.write(\"Python\")\n\nwith open(username, \"r\") as f:\n    print(f.read())\n\nos.remove(username)\n\n\n# Ejercicio - Dificultad Extra\n\nstore_file = \"store.txt\"\n\nwhile True:\n    try:\n        option = int(input(\"\"\"\\n1.- Agregar Producto\n2.- Consultar Producto\n3.- Mostrar Todos los Productos\n4.- Actualizar Producto\n5.- Eliminar Producto\n6.- Calcular Venta Total\n7.- Calcular Venta por Producto\n8.- Salir\\n\nElija una opción: \"\"\"))\n        if option not in [1, 2, 3, 4, 5, 6, 7]:\n            raise IndexError\n    except ValueError:\n        print(\"Debe ingresar un entero válido\")\n    except IndexError:\n        print(\"Debe elegir una de las opciones\")\n    \n    match option:\n        case 1:\n            name = input(\"Ingrese el Producto: \")\n            quantity = int(input(\"Ingrese la Cantidad: \"))\n            price = float(input(\"Ingrese el Precio: \"))\n            with open(store_file, \"a\") as file:\n                line = f\"{name}, {quantity}, {price}\\n\"\n                file.write(line)\n        case 2:\n            name = input(\"Ingrese el Nombre del Producto a Consultar: \")\n            with open(store_file, \"r\") as file:\n                for line in file.readlines():\n                    product = line.split(\", \")\n                    if product[0] == name:\n                        print(f\"Producto: {product[0]}, Cantidad: {product[1]}, Precio: {product[2]}\")\n                        break\n        case 3:\n            with open(store_file, \"r\") as file:\n                for line in file.readlines():\n                    product = line.split(\", \")\n                    print(f\"Producto: {product[0]}, Cantidad: {product[1]}, Precio: {product[2]}\")\n        case 4:\n            name = input(\"Ingrese el Producto a Actualizar: \")\n            quantity = int(input(\"Ingrese la Cantidad a Actualizar: \"))\n            price = float(input(\"Ingrese el Precio a Actualizar: \"))\n            with open(store_file, \"w\") as file:\n                for line in file.readlines():\n                    if line.split(\", \")[0] == name:\n                        line = f\"{name}, {quantity}, {price}\\n\"\n                        file.write(line)\n        case 5:\n            name = input(\"Ingrese el Producto a Eliminar: \")\n            with open(store_file, \"w\") as file:\n                for line in file.readlines():\n                    if line.split(\", \")[0] != name:\n                        file.write(line)\n        case 6:\n            total_sale = 0\n            with open(store_file, \"r\") as file:\n                for line in file.readlines():\n                    quantity, price = int(line.split(\", \")[1]), float(line.split(\", \")[2])\n                    total_sale += quantity * price\n            print(total_sale)\n        case 7:\n            name = input(\"Ingrese el Nombre del Producto: \")\n            total_sale = 0\n            with open(store_file, \"r\") as file:\n                for line in file.readlines():\n                    if line.split(\", \")[0] == name:\n                        quantity, price = int(line.split(\", \")[1]), float(line.split(\", \")[2])\n                        total_sale += quantity * price\n                        break\n            print(f\"Las ventas del producto {name} son: {total_sale}\")\n        case 8:\n            os.remove(store_file)\n            print(\"Finalizando la ejecución del programa\")\n            break"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/cristianfloyd.py",
    "content": "# EJERCICIO:\n# Desarrolla un programa capaz de crear un archivo que se llame como\n# tu usuario de GitHub y tenga la extensión .txt.\n# Añade varias líneas en ese fichero:\n# - Tu nombre.\n# - Edad.\n# - Lenguaje de programación favorito.\n# Imprime el contenido.\n# Borra el fichero.\nimport os\n\nuser = \"cristianfloyd\"\nfile_name = f\"{user}.txt\"\n\nwith open(file_name, \"w\") as file:\n    file.write(\"Cristian Floyd\\n\")\n    file.write(\"48\\n\")\n    file.write(\"Python\\n\")\n\nwith open(file_name, \"r\") as file:\n    content = file.read()\n    print(content)\n\nos.remove(file_name)\n\n\n#\n# DIFICULTAD EXTRA (opcional):\n# Desarrolla un programa de gestión de ventas que almacena sus datos en un\n# archivo .txt.\n# - Cada producto se guarda en una línea del archivo de la siguiente manera:\n#   [nombre_producto], [cantidad_vendida], [precio].\n# - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n#   actualizar, eliminar productos y salir.\n# - También debe poseer opciones para calcular la venta total y por producto.\n# - La opción salir borra el .txt.\n\n\nclass Product:\n    \"\"\"\n    Clase que representa un producto.\n    \"\"\"\n    def __init__(self, name: str, quantity: int, price: float):\n        self.name = name.strip()\n        self.quantity = int(quantity)\n        self.price = float(price)\n        self.verificar_parametros()\n\n    def verificar_parametros(self):\n        \"\"\"Valida los parámetros del producto.\"\"\"\n        if not self.name:\n            raise ValueError(\"El nombre del producto no puede estar vacío\")\n        \n        if self.quantity < 0:\n            raise ValueError(\"La cantidad no puede ser negativa\")\n        \n        if self.price < 0:\n            raise ValueError(\"El precio no puede ser negativo\")\n\n    def to_file_format(self):\n        return f\"{self.name}, {self.quantity}, {self.price}\\n\"\n\n    @staticmethod\n    def from_file_line(line: str) -> \"Product\":\n        \"\"\"Desde una linea del archivo, crea un objeto Product.\"\"\"\n        parts = [p.strip() for p in line.strip().split(\",\")]\n        if len(parts) != 3:\n            raise ValueError(f\"Formato inválido en línea: {line}\")\n        return Product(parts[0], int(parts[1]), float(parts[2]))\n    \n    def calcular_total(self) -> float:\n        \"\"\"Calcula el total del producto.\"\"\"\n        return self.quantity * self.price\n\nclass ProductManager:\n    \"\"\"\n    Clase para gestionar productos en un archivo de texto.\n    \"\"\"\n    def __init__(self, file_name) -> None:\n        self.file_name = file_name\n\n    def read_products(self) -> list[Product]:\n        \"\"\"Lee los productos del archivo.\"\"\"\n        products = []\n        if not os.path.exists(self.file_name):\n            return products\n        try:\n            with open(self.file_name, \"r\") as file:\n                for line in file.readlines():\n                    line = line.strip()\n                    products.append(Product.from_file_line(line))\n                return products\n        except FileNotFoundError as e:\n            print(f\"Error al leer el archivo: {e}\")\n            return []\n\n    def write_products(self, products: list[Product]) -> None:\n        \"\"\"Escribe los productos en el archivo.\"\"\"\n        try:\n            with open(self.file_name, \"w\") as file:\n                for product in products:\n                    file.write(product.to_file_format())\n        except FileNotFoundError as e:\n            raise FileNotFoundError(f\"Error al escribir el archivo: {e}\")\n\n    def add_product(self, product: Product) -> None:\n        \"\"\"Añade un producto al archivo.\"\"\"\n        with open(self.file_name, \"a\") as file:\n            file.write(product.to_file_format())\n\n    def get_product(self, name:str) -> Product | None:\n        \"\"\"Obtiene un producto por su nombre.\"\"\"\n        products = self.read_products()\n        for product in products:\n            if product.name == name:\n                return product\n        return None\n\n    def delete_product(self, name:str) -> bool:\n        \"\"\"Elimina un producto por su nombre.\"\"\"\n        products = self.read_products()\n        cantidad_original = len(products)\n        products = [product for product in products if product.name != name]\n        cantidad_final = len(products)\n        if cantidad_original > cantidad_final:\n            self.write_products(products)\n            return True\n        return False\n\n    def update_product(self, product: Product) -> bool:\n        \"\"\"Actualiza un producto en el archivo.\"\"\"\n        productos = self.read_products()\n        for producto in productos:\n            if producto.name == product.name:\n                producto.quantity = product.quantity\n                producto.price = product.price\n                self.write_products(productos)\n                return True\n        return False\n\n    def get_all_products(self) -> list[Product]:\n        \"\"\"Obtiene todos los productos.\"\"\"\n        return self.read_products()\n\n    def calcular_venta_total(self) -> float:\n        \"\"\"Calcula la venta total de los productos.\"\"\"\n        products = self.read_products()\n        return sum([p.calcular_total() for p in products])\n\n    def calcular_venta_por_producto(self, name:str) -> float:\n        \"\"\"Calcula la venta total de un producto.\"\"\"\n        product = self.get_product(name)\n        if product:\n            return product.calcular_total()\n        return 0\n\nclass ShopApp:\n    \"\"\"\n    Clase principal de la aplicación de gestión de productos.\n    \"\"\"\n    def __init__(self, manager: ProductManager) -> None:\n        self.manager = manager\n\n    def run(self):\n        file_name = \"cristianfloyd_shop.txt\"\n\n        open(file_name, \"a\")\n\n        while True:\n            print(\"1. Añadir producto\")\n            print(\"2. Consultar producto\")\n            print(\"3. Actualizar producto\")\n            print(\"4. Borrar producto\")\n            print(\"5. Mostrar productos\")\n            print(\"6. Calcular venta total\")\n            print(\"7. Calcular venta por producto\")\n            print(\"8. Salir\")\n\n            option = input(\"Selecciona una opción: \")\n\n            match option:\n                case \"1\":\n                    self.add_product_flow()\n                case \"2\":\n                    self.buscar_producto_flow()\n                case \"3\":\n                    self.update_product_flow()\n                case \"4\":\n                    self.borrar_producto_flow()\n                case \"5\":\n                    self.mostrar_productos_flow()\n                case \"6\":\n                    self.calcular_venta_total_flow()\n                case \"7\":\n                    self.calcular_venta_por_producto_flow()\n                case \"8\":\n                    self.exit_flow()\n\n    def add_product_flow(self):\n        name = input(\"Nombre: \").strip()\n        quantity = int(input(\"Cantidad: \").strip())\n        price = float(input(\"Precio: \").strip())\n        try:\n            product = Product(name, quantity, price)\n            self.manager.add_product(product)\n            print(\"Producto añadido.\")\n        except ValueError as e:\n            print(f\"Error al añadir producto: {e}\")\n\n    def buscar_producto_flow(self):\n        name = input(\"Nombre: \").strip()\n        producto = self.manager.get_product(name)\n        if producto:\n            print(\"\\nProducto encontrado:\")\n            print(f\"  Nombre: {producto.name}\")\n            print(f\"  Cantidad: {producto.quantity}\")\n            print(f\"  Precio: {producto.price}\")\n            print(f\"  Total: {producto.calcular_total()}\")\n        else:\n            print(f\"Error: Producto '{name}' no encontrado.\")\n\n    def update_product_flow(self):\n        name = input(\"Nombre: \").strip()\n        quantity = int(input(\"Cantidad: \").strip())\n        price = float(input(\"Precio: \").strip())\n\n        producto = Product(name, quantity, price)\n\n        try:\n            self.manager.update_product(producto)\n            print(\"Producto actualizado.\")\n        except ValueError as e:\n            print(f\"Error al actualizar producto: {e}\")\n\n    def borrar_producto_flow(self) -> None:\n        name = input(\"Nombre: \").strip()\n        if self.manager.delete_product(name):\n            print(\"Producto borrado correctamente.\")\n        else:\n            print(f\"Error: Producto '{name}' no encontrado.\")\n\n    def mostrar_productos_flow(self):\n        \"\"\"flujo para mostrar todos los productos.\"\"\"\n        productos = self.manager.get_all_products()\n        if productos:\n            print(\"\\n === Productos: ===\")\n            for producto in productos:\n                print(f\"{producto.name}, {producto.quantity}, {producto.price}\")\n            print(f\"\\nTotal de productos: {len(productos)}\\n\")\n        else:\n            print(\"No hay productos registrados.\")\n\n    def calcular_venta_total_flow(self):\n        \"\"\"flujo para calcular la venta total.\"\"\"\n        total = self.manager.calcular_venta_total()\n        print(f\"La venta total es: {total}\")\n\n    def calcular_venta_por_producto_flow(self):\n        \"\"\"flujo para calcular la venta total de un producto.\"\"\"\n        name = input(\"Nombre: \").strip()\n        total = self.manager.calcular_venta_por_producto(name)\n        print(f\"La venta total de {name} es: {total}\")\n\n    def exit_flow(self):\n        os.remove(self.manager.file_name)\n        print(\"Archivo eliminado. Saliendo...\")\n        exit()\n\n\nif __name__ == \"__main__\":\n    tienda = ShopApp(ProductManager(\"cristianfloyd_shop.txt\"))\n    tienda.run()"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/danielhdzr.py",
    "content": "# #11 MANEJO DE FICHEROS\n#### Dificultad: Media | Publicación: 11/03/24 | Corrección: 18/03/24\n\n## Ejercicio\n\n\n'''\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n *\n \n'''\n \nimport os\nimport re\ndef main():\n    # Directorio donde deseas crear el archivo\n    target_directory = \"C:/Users/Dan/Desktop/Coding/ficheros sin merge en mouredev/11 - MANEJO DE FICHEROS\"\n    # Si no existe se crea\n    if not os.path.exists(target_directory):\n        os.makedirs(target_directory)\n\n    # Directorio de trabajo actual\n    # current_directoy = os.getcwd()\n    # print(f\"Directorio de trabajo actual: {current_directoy}\")\n\n     # Nombre del archivo\n    file_name = \"danielhdzr.txt\"\n\n    # Crear la ruta completa\n    file_path = os.path.join(target_directory, file_name)\n\n    # Crear y escribir en el archivo\n    with open(file_path, \"w\") as file:\n        file.write(\"Daniel\\n\")\n        file.write(\"33\\n\")\n        file.write(\"Python\")\n\n    # Verificar si el archivo existe\n    if os.path.exists(file_path):\n        print(f\"El archivo: '{file_name}' ha sido creado en '{target_directory}'\")\n    else:\n        print(f\"No se pudo crear el archivo '{file_name}'\")\n\n    # Leer y mostrar el contenido del archivo\n    with open(file_path, \"r\") as file:\n        print(file.read())\n\n    # Eliminar el archivo\n    os.remove(file_path)\n    print(f\"Se elimino el archivo {file_name} de {file_path}\")\n\n\n    \n    # ----- Extra -----\n    '''* DIFICULTAD EXTRA (opcional):\n    * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n    * archivo .txt.\n    * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n    *   [nombre_producto], [cantidad_vendida], [precio].\n    * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n    *   actualizar, eliminar productos y salir.\n    * - También debe poseer opciones para calcular la venta total y por producto.\n    * - La opción salir borra el .txt.'''\n\n\n    # Directorio donde deseas crear el archivo\n    target_directory = \"C:/Users/Dan/Desktop/Coding/ficheros sin merge en mouredev/11 - MANEJO DE FICHEROS\"\n    # Si el directorio no existe se crea\n    if not os.path.exists(target_directory):\n        os.makedirs(target_directory)\n\n    # Directorio de trabajo actual\n    # current_directoy = os.getcwd()\n    # print(f\"Directorio de trabajo actual: {current_directoy}\")\n\n     # Nombre del archivo\n    file_name = \"daniel_tienda.txt\"\n\n    # Concatena el archivo a la ruta del directorio\n    # C:/Users/Dan/Desktop/Coding/ficheros sin merge en mouredev/11 - MANEJO DE FICHEROS/ daniel_tienda.txt\n    file_path = os.path.join(target_directory, file_name)\n\n    while True:\n        \n        print(\"1. Agregar producto\")\n        print(\"2. Consultar producto\")\n        print(\"3. Actualizar producto\")\n        print(\"4. Borrar producto\")\n        print(\"5. Calcular venta total\")\n        print(\"6. Calcular venta por producto\")\n        print(\"7. Consultar lista de productos y precios\")\n        print(\"8. Salir\")\n\n        option = int(input(\"Selecciona la opcion que deseas: \"))\n        # Agregar producto\n        if option == 1:\n            print()\n            print(\"Agrega un producto\")\n            product = input(\"Nombre del producto: \")\n            quantity = input(\"Cantidad: \")\n            price = input(\"Precio: \")\n\n           # Escribimos una nueva linea en el archivo txt sin borrar la existente\n                            # \"a\" = append\n            with open(file_path, \"a\") as file:\n                file.write(f\"Producto: {product}, Cantidad: {quantity}, Precio: ${price}\\n\")\n        \n        # Consultar producto\n        elif option == 2:\n            print()\n            product = input(\"Nombre del producto: \")\n            with open(file_path, \"r\") as file:\n                for line in file.readlines():\n                    if product in line:\n                        pro, qua, pri = product, quantity, price\n            print(f\"Nombre: {pro}, Cantidad: {qua}, precio {pri}\")\n\n        # Actualizar producto\n        elif option == 3:\n            print()\n            product = input(\"Nombre del producto: \")\n            quantity = input(\"Cantidad: \")\n            price = input(\"Precio: \")\n            with open(file_path, \"r\") as file:\n                lines = file.readlines()\n            with open(file_path, \"w\") as file:\n                for line in lines:\n                    if product in line:\n                    # Si el producto esta en la linea, escribe el nuevo valor\n                        file.write(f\"Producto: {product}, Cantidad: {quantity}, Precio: ${price}\\n\")\n                    else:\n                    # Si no esta, escribe la linea como estaba\n                        file.write(line)\n\n        # Borrar producto\n        elif option == 4:\n            print()\n            product = input(\"Nombre del producto: \")\n            with open(file_path, \"r\") as file:\n                lines = file.readlines()\n            with open(file_path, \"w\") as file:\n                for line in lines:\n                # Si producto NO ESTA en la linea, se reescribe la linea\n                # Por lo tanto, SI ESTA en la linea, no se reescribe\n                    if product not in line:\n                        file.write(line)\n\n        # Calcular venta total\n        elif option == 5:\n            print()\n            total = 0\n            with open(file_path, \"r\") as file:\n                for line in file.readlines():\n                    # Excluye no numericos\n                    numbers_only = re.findall(r'\\d+', line)\n                    quantity = int(numbers_only[0])\n                    price = float(numbers_only[1])\n                    total += quantity * price\n            print(f\"Total vendido: {total}\")\n            print()\n\n        # Calcular venta por producto\n        elif option == 6:\n            print()\n            product = input(\"Nombre del producto: \")\n            total = 0\n            with open(file_path, \"r\") as file:\n                for line in file.readlines():\n                    if product in line:\n                        # Excluye no numericos\n                        numbers_only = re.findall(r'\\d+', line)\n                quantity = int(numbers_only[0])\n                price = float(numbers_only[1])\n                total += quantity * price\n            \n            print(f\"Total vendido de {product}: {total}\")\n            print()\n\n        # Consultar lista de productos y precios\n        elif option == 7:\n            print()\n            with open(file_path, \"r\") as file:\n                print(file.read())\n            \n        elif option == 8:\n            # os.remove(file_path)\n            break\n        else:\n            print(\"Selecciona una de las opciones disponibles\")\n            \n            \n\n\n    # # Crear y escribir en el archivo\n    # with open(file_path, \"w\") as file:\n    #     file.write(input(\"nombre del producto: \\n\"))\n    #     file.write(input(\"cantidad vendida: \\n\"))\n    #     file.write(input(\"precio: \"))\n\n    # # Verificar si el archivo existe\n    # if os.path.exists(file_path):\n    #     print(f\"El archivo: '{file_name}' ha sido creado en '{target_directory}'\")\n    # else:\n    #     print(f\"No se pudo crear el archivo '{file_name}'\")\n\n    # # Leer y mostrar el contenido del archivo\n    # with open(file_path, \"r\") as file:\n    #     print(file.read())\n\nif __name__==\"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/davidrguez98.py",
    "content": "\"\"\" /*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n * \n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n * archivo .txt.\n * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n */ \"\"\"\n\nimport os\n\n#EJERCICIO\n\nfile_name = \"davidrguez98.txt\"\n\nwith open(file_name, \"w\") as file:\n    file.write(\"David Rodriguez\")\n    file.write(\"\\n26\")\n    file.write(\"\\nPython\")\n\nwith open(file_name, \"r\") as file:\n    print(file.read())\n\nos.remove(file_name)\n\n#DIFICULTAD EXTRA\n\nsale_list = \"sale_list.txt\"\n\nopen(sale_list, \"a\")\n\nwhile True:\n    print(\"1. Añadir producto.\")\n    print(\"2. Consultar producto.\")\n    print(\"3. Actualizar producto.\")\n    print(\"4. Ver lista de productos\")\n    print(\"5. Eliminar producto.\")\n    print(\"6. Calcular la venta total.\")\n    print(\"7. Calcular venta por producto.\")\n    print(\"8. Salir del programa\")\n\n    option = input(\"\\nSelecciona una opción: \")\n\n    match option:\n        case(\"1\"):\n            name_product = input(\"Nombre del producto: \")\n            quantity_product = input(\"Cantidad: \")\n            price_product = input(\"Precio del producto: \")\n\n            with open(sale_list, \"a\") as file:\n                file.write(f\"{name_product}, {quantity_product}, {price_product}\\n\")\n\n        case(\"2\"):\n            name_product = input(\"¿Qué producto quieres consultar?: \")\n            with open(sale_list, \"r\") as file:\n                for line in file.readlines():\n                    if line.split(\", \")[0] == name_product:\n                        print(line)\n                        break\n                else:\n                    print(\"\\nEl producto no se ha encontrado.\\n\")      \n            \n        case(\"3\"):\n            name_product = input(\"¿Qué producto quieres actualizar?: \")\n            quantity_product = input(\"Nueva cantidad: \")\n            price_product = input(\"Nuevo precio: \")\n\n            with open(sale_list, \"r\") as file:\n                lines = file.readlines()\n            with open(sale_list, \"w\") as file:\n                for line in lines:\n                    if line.split(\", \")[0] == name_product:\n                        file.write(f\"{name_product}, {quantity_product}, {price_product}\\n\")\n                    else:\n                        file.write(line)\n\n    \n        case(\"4\"):\n            with open(sale_list, \"r\") as file:\n                print(file.read())\n\n        case(\"5\"):\n            name_product = input(\"¿Qué producto quieres eliminar?: \")\n\n            with open(sale_list, \"r\") as file:\n                lines = file.readlines()\n            with open(sale_list, \"w\") as file:\n                for line in lines:\n                    if line.split(\", \")[0] != name_product:\n                        file.write(line)\n\n        case(\"6\"):\n            total = 0\n            with open(sale_list, \"r\") as file:\n                for line in file.readlines():\n                    products_value = line.split(\", \")\n                    quantity_product = int(products_value[1])\n                    price_product = float(products_value[2])\n                    total += quantity_product * price_product\n            print(total)\n        \n        case(\"7\"): \n            name_product = input(\"¿De que producto quieres saber la venta total?: \")\n\n            with open(sale_list, \"r\") as file:\n                for line in file.readlines():\n                    if line.split(\", \")[0] == name_product:\n                        quantity_product = int(line.split(\", \")[1])\n                        price_product = float(line.split(\", \")[2])\n                        print(quantity_product * price_product)\n                    else:\n                        print(\"El producto no se encuentra en la lista.\")\n        \n        case(\"8\"):\n            os.remove(sale_list)\n            break\n        \n        case(\"9\"):\n            print(\"La opción marcada no es correcta. Escoge un número del 1 al 7.\")\n\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/didacdev.py",
    "content": "# ejecicio 1\nimport os\n\nfile = open(\"didacdev.txt\", \"w\")\n\nfile.write(\"Diego Sánchez Escribano\\n\")\nfile.write(\"28 años\\n\")\nfile.write(\"Python\")\n\nfile.close()\n\nfile = open(\"didacdev.txt\", \"r\")\n\ncontenido = file.read()\nprint(contenido)\n\nfile.close()\n\nos.remove(file.name)\n\n\n# ejercicio 2\ndef start():\n\n    while True:\n\n        print(\"\\nQué desea hacer:\")\n        print(\"1 - Añadir\")\n        print(\"2 - Consultar\")\n        print(\"3 - Actualizar\")\n        print(\"4 - Eliminar\")\n        print(\"5 - Salir\")\n\n        option: int = input(\"> \")\n\n        match option:\n            case \"1\":\n                add()\n            case \"2\":\n                read()\n            case \"3\":\n                update()\n            case \"4\":\n                remove()\n            case \"5\":\n                print(\"Hasta pronto\")\n                break\n            case _:\n                print(\"Opción incorrecta\")\n\n\ndef add():\n    file = open(\"venta.txt\", \"a\")\n\n    product_name = input(\"\\nNombre del producto: \")\n    product_quantity = input(\"Unidades del producto: \")\n    product_price = input(\"Precio del producto: \")\n\n    file.write(f\"{product_name} {product_quantity} {product_price}\\n\")\n\n    file.close()\n\n\ndef read():\n    print(\"\\nProducto | Unidades | Precio\")\n    file = open(\"venta.txt\", \"r\")\n\n    for product_info in file:\n        print(product_info)\n\n    file.close()\n\n\ndef update():\n    contenido = list()\n\n    product_name = input(\"\\nNombre del producto: \")\n    product_quantity = input(\"Unidades del producto: \")\n    product_price = input(\"Precio del producto: \")\n\n    with open(\"venta.txt\", \"r+\") as file:\n        contenido = file.readlines()\n        for product in contenido:\n            name = product.split(\" \")\n\n            if name[0] == product_name:\n                product_info = product_name + \" \" + product_quantity + \" \" + product_price + \"\\n\"\n                contenido[contenido.index(product)] = product_info\n\n    with open(\"venta.txt\", \"w\") as file:\n        file.writelines(contenido)\n\n\ndef remove():\n    contenido = list()\n\n    product_name = input(\"\\nNombre del producto: \")\n\n    with open(\"venta.txt\", \"r+\") as file:\n        contenido = file.readlines()\n        for product in contenido:\n            name = product.split(\" \")\n\n            if name[0] == product_name:\n                contenido.remove(product)\n\n    with open(\"venta.txt\", \"w\") as file:\n        file.writelines(contenido)\n\n\nstart()\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/duendeintemporal.py",
    "content": "#11 { Retos para Programadores } MANEJO DE FICHEROS\n\n# Bibliography reference\n# Professional JavaScript for web developers by Matt Frisbie [Frisbie, Matt] (z-lib.org)\n#Python Notes for Professionals. 800+ pages of professional hints and tricks (GoalKicker.com) (Z-Library)\n# GPT\n\n\"\"\"\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n * archivo .txt.\n * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n\n\"\"\"\n# @by Niko Zen\n\nimport os\nimport json\n\n# Short for print\nlog = print\n\n# File path setup\ngithub_user = 'duendeintemporal'\nfile_path = f\"{github_user}.txt\"\n\n# Data to write in the file\nname = 'Niko Zen'\nage = '41'\nfavorite_language = 'JavaScript'\n\n# Create and write to the file\nwith open(file_path, 'w') as file:\n    file.write(f\"Name: {name}\\nAge: {age}\\nFavoriteLanguage: {favorite_language}\\n\")\n    log(f\"File {github_user}.txt created successfully.\")\n\n# Read the content of the file\ntry:\n    with open(file_path, 'r') as file:\n        data = file.read()\n        log('Content of the file:')\n        log(data)\nexcept Exception as e:\n    log(f'Error reading the file {github_user}.txt: {e}')\n\n# Delete the file\ntry:\n    os.remove(file_path)\n    log(f\"File {github_user}.txt deleted successfully.\")\nexcept Exception as e:\n    log(f'Error deleting the file {github_user}.txt: {e}')\n\n# Extra Difficulty Exercise\ndef menu():\n    log('\\n--- Sales Management ---')\n    log('1. Add Product')\n    log('2. View Products')\n    log('3. Update Product')\n    log('4. Delete Product')\n    log('5. Calculate Total Sales')\n    log('6. Calculate Sales by Product')\n    log('7. Exit')\n    option = input('Select an option: ')\n    handle_menu_option(option)\n\ndef handle_menu_option(option):\n    if option == '1':\n        add_product()\n    elif option == '2':\n        view_products()\n    elif option == '3':\n        update_product()\n    elif option == '4':\n        delete_product()\n    elif option == '5':\n        calculate_total_sales()\n    elif option == '6':\n        calculate_sales_by_product()\n    elif option == '7':\n        exit_program()\n    else:\n        log('Invalid option, choose a number between 1 and 7. Please try again.')\n        menu()\n\ndef add_product():\n    name = input('Product Name: ')\n    quantity = input('Quantity Sold: ')\n    price = input('Price: ')\n    product = f\"{name}, {quantity}, {price}\\n\"\n    with open('sales.txt', 'a') as file:\n        file.write(product)\n    log('Product added.')\n    menu()\n\ndef view_products():\n    try:\n        with open('sales.txt', 'r') as file:\n            data = file.read()\n            log('\\nProducts:\\n' + (data or 'No products registered.'))\n    except Exception as e:\n        log(f'Error reading products: {e}')\n    menu()\n\ndef update_product():\n    name = input('Product Name to Update: ')\n    new_quantity = input('New Quantity Sold: ')\n    new_price = input('New Price: ')\n    \n    try:\n        with open('sales.txt', 'r') as file:\n            data = file.readlines()\n        \n        products = []\n        for line in data:\n            if line.startswith(name):\n                products.append(f\"{name}, {new_quantity}, {new_price}\\n\")\n            else:\n                products.append(line)\n        \n        with open('sales.txt', 'w') as file:\n            file.writelines(products)\n        \n        log('Product updated.')\n    except Exception as e:\n        log(f'Error updating product: {e}')\n    \n    menu()\n\ndef delete_product():\n    name = input('Product Name to Delete: ')\n    \n    try:\n        with open('sales.txt', 'r') as file:\n            data = file.readlines()\n        \n        products = [line for line in data if not line.startswith(name)]\n        \n        with open('sales.txt', 'w') as file:\n            file.writelines(products)\n        \n        log('Product deleted.')\n    except Exception as e:\n        log(f'Error deleting product: {e}')\n    \n    menu()\n\ndef calculate_total_sales():\n    try:\n        with open('sales.txt', 'r') as file:\n            data = file.readlines()\n        \n        total = sum(int(line.split(', ')[1]) * float(line.split(', ')[2]) for line in data if line.strip())\n        log(f'Total Sales: {total:.2f}')\n    except Exception as e:\n        log(f'Error calculating total sales: {e}')\n    \n    menu()\n\ndef calculate_sales_by_product():\n    name = input('Product Name: ')\n    \n    try:\n        with open('sales.txt', 'r') as file:\n            data = file.readlines()\n        \n        total = sum(int(line.split(', ')[1]) * float(line.split(', ')[2]) for line in data if line.startswith(name))\n        log(f'Total Sales for {name}: {total:.2f}')\n    except Exception as e:\n        log(f'Error calculating sales for product: {e}')\n    \n    menu()\n\ndef exit_program():\n    try:\n        os.remove('sales.txt')\n        log('Exiting the program and deleting the sales data file.')\n    except Exception as e:\n        log(f'Error deleting the file: {e}')\n    finally:\n        log('Program terminated.')\n\n# Start the program\nif __name__ == \"__main__\":\n    # Delay before showing the menu\n    import time\n    time.sleep(1.2)\n    menu()\n\n\n\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/edalmava.py",
    "content": "import os\n\ngithub_username = \"edalmava\"\n\nfilename = f\"{github_username}.txt\"\n\nname = \"Edwin Alberto Martinez Vanegas\"\nage = \"30\"\nfavorite_language = \"Python\"\n\n# Crear y escribir en el archivo\nwith open(filename, 'w') as file:\n    file.write(f\"Nombre: {name}\\n\")\n    file.write(f\"Edad: {age}\\n\")\n    file.write(f\"Lenguaje de programación favorito: {favorite_language}\\n\")\n\n# Leer y mostrar el contenido del archivo\nwith open(filename, 'r') as file:\n    content = file.read()\n    print(\"Contenido del archivo:\")\n    print(content)\n\n# Borrar el archivo\nos.remove(filename)\nprint(f\"Archivo '{filename}' ha sido borrado.\")\n\nprint(\"*****RETO EXTRA*****\")\n\n# Define el nombre del archivo\nfilename = \"ventas.txt\"\n\ndef load_products():\n    \"\"\"Carga los productos desde el archivo.\"\"\"\n    products = {}\n    if os.path.exists(filename):\n        with open(filename, 'r') as file:\n            for line in file:\n                if line.strip():  # Verifica que la línea no esté vacía\n                    name, quantity, price = line.strip().split(', ')\n                    products[name] = {'quantity': int(quantity), 'price': float(price)}\n    return products\n\ndef save_products(products):\n    \"\"\"Guarda los productos en el archivo.\"\"\"\n    with open(filename, 'w') as file:\n        for name, details in products.items():\n            file.write(f\"{name}, {details['quantity']}, {details['price']}\\n\")\n\ndef add_product(products):\n    \"\"\"Añade un nuevo producto.\"\"\"\n    name = input(\"Nombre del producto: \")\n    quantity = int(input(\"Cantidad vendida: \"))\n    price = float(input(\"Precio: \"))\n    products[name] = {'quantity': quantity, 'price': price}\n    save_products(products)\n    print(\"Producto añadido.\")\n\ndef view_products(products):\n    \"\"\"Muestra todos los productos.\"\"\"\n    if products:\n        for name, details in products.items():\n            print(f\"{name}: Cantidad - {details['quantity']}, Precio - {details['price']}\")\n    else:\n        print(\"No hay productos.\")\n\ndef update_product(products):\n    \"\"\"Actualiza un producto existente.\"\"\"\n    name = input(\"Nombre del producto a actualizar: \")\n    if name in products:\n        quantity = int(input(\"Nueva cantidad vendida: \"))\n        price = float(input(\"Nuevo precio: \"))\n        products[name] = {'quantity': quantity, 'price': price}\n        save_products(products)\n        print(\"Producto actualizado.\")\n    else:\n        print(\"Producto no encontrado.\")\n\ndef delete_product(products):\n    \"\"\"Elimina un producto.\"\"\"\n    name = input(\"Nombre del producto a eliminar: \")\n    if name in products:\n        del products[name]\n        save_products(products)\n        print(\"Producto eliminado.\")\n    else:\n        print(\"Producto no encontrado.\")\n\ndef total_sales(products):\n    \"\"\"Calcula la venta total.\"\"\"\n    total = sum(details['quantity'] * details['price'] for details in products.values())\n    print(f\"Venta total: {total:.2f}\")\n\ndef sales_by_product(products):\n    \"\"\"Calcula la venta por producto.\"\"\"\n    name = input(\"Nombre del producto: \")\n    if name in products:\n        details = products[name]\n        total = details['quantity'] * details['price']\n        print(f\"Venta del producto '{name}': {total:.2f}\")\n    else:\n        print(\"Producto no encontrado.\")\n\ndef main():\n    products = load_products()\n    \n    while True:\n        print(\"\\nOpciones:\")\n        print(\"1. Añadir producto\")\n        print(\"2. Consultar productos\")\n        print(\"3. Actualizar producto\")\n        print(\"4. Eliminar producto\")\n        print(\"5. Calcular venta total\")\n        print(\"6. Calcular venta por producto\")\n        print(\"7. Salir\")\n\n        choice = input(\"Seleccione una opción (1-7): \")\n\n        if choice == '1':\n            add_product(products)\n        elif choice == '2':\n            view_products(products)\n        elif choice == '3':\n            update_product(products)\n        elif choice == '4':\n            delete_product(products)\n        elif choice == '5':\n            total_sales(products)\n        elif choice == '6':\n            sales_by_product(products)\n        elif choice == '7':\n            os.remove(filename)\n            print(\"Archivo eliminado. Saliendo...\")\n            break\n        else:\n            print(\"Opción no válida. Inténtelo de nuevo.\")\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/elbarbero.py",
    "content": "\"\"\"\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n * archivo .txt.\n * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n \"\"\"\n \nfrom pathlib import Path\nimport os\n    \ndef GetCurrentDirectory():\n    return os.getcwd()\n\ndef CreateFile(path: str, text = []):\n    if len(text) > 0:\n        with open(path, \"w\") as file:\n            for t in text:\n                file.write(str(t)+\"\\n\")\n\ndef ReadFile(path: str):\n    if os.path.exists(path):\n        file = Path(path)\n        texto = file.read_text(\"utf-8\")\n        return texto\n    else:\n        return \"No existe el archivo en la ruta especificada\"\n    \ndef DeleteFlle(path: str):\n    if os.path.exists(path):\n        os.remove(path)\n    else:\n        print(\"No existe el archivo en la ruta especificada\")\n\n\n# EXTRA\nclass  Warehouse:\n    def __init__(self, oid, name, items = []):\n        self.oid = oid\n        self.name = name\n        self.products = []\n        self.products.extend(items)\n    \n    def AddProduct(self, newProduct):\n        self.products.append(newProduct)\n    \n    def UpdateProduct(self, oid, name = None, price = None, quantity = None, soldUnits = None):\n        p = self.GetProduct(oid)\n        if p != None:\n            p.name = name if name != None else p.name\n            p.priceByUnit = price if price != None else p.priceByUnit\n            p.quantity = quantity if quantity != None else p.quantity\n            p.soldUnits = soldUnits if soldUnits != None else p.soldUnits\n        return p\n\n    def GetProduct(self, oid: int):\n        l = list(map(lambda x: x.oid == oid, self.products))\n        index = l.index(True)\n        p = self.products[index]\n        return p\n\n    def GetProducts(self):\n        print(*(p for p in self.products), sep='\\n')\n    \n    def DelteItem(self, oid: int):\n        p = self.GetProduct(oid)\n        if p in self.products: \n            self.products.remove(p)\n        \n\n\nclass Product:\n    def __init__(self, oid, name, priceByUnit, quantity, soldUnits: int = 0):\n        self.oid = oid\n        self.name = name\n        self.priceByUnit = priceByUnit\n        self.quantity = quantity\n        self.soldUnits = soldUnits\n    \n    def __str__(self):\n        return f\"El producto {self.name} tiene un precio de {self.priceByUnit}€ por unidad, en el almacén quedan {self.quantity} unidades y ha vendido {self.soldUnits} unidades.\"\n        \n    \n    \n\n\nif __name__ == \"__main__\":\n    current_directory = GetCurrentDirectory()\n    print(current_directory)\n    CreateFile(f\"{current_directory}\\elbarbero.txt\", [\"Mario Barbero\", 35, \"Python\"])\n    text = ReadFile(f\"{current_directory}\\elbarbero.txt\")\n    print(text)\n    DeleteFlle((f\"{current_directory}\\elbarbero.txt\"))\n    \n    # EXTRA\n    almacen = Warehouse(1, \"Almacen Burgos\", [Product(1, \"Chorizo\", 1.65, 100, 25), Product(2, \"Aceite Oliva 1L\", 7.79, 550), Product(3, \"Yogures\", 1.90, 80), Product(4, \"Pizza\", 2.90, 185)])\n    almacen.UpdateProduct(oid=3, name=\"Nuevo nombre\")\n    print(almacen.GetProduct(1))\n    text = []\n    text.extend(str(p) for p in almacen.products)\n    \n    CreateFile(f\"{current_directory}\\elbarbero.txt\", text)\n    DeleteFlle((f\"{current_directory}\\elbarbero.txt\"))\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/evilpotato04.py",
    "content": "#/*\n# * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n# * \n# * EJERCICIO:\n# * Desarrolla un programa capaz de crear un archivo que se llame como\n# * tu usuario de GitHub y tenga la extensión .txt.\n# * Añade varias líneas en ese fichero:\n# * - Tu nombre.\n# * - Edad.\n# * - Lenguaje de programación favorito.\n# * Imprime el contenido.\n# * Borra el fichero.\n\nimport os\n\nnombre_archivo = \"evilpotato04.txt\"\n\narchivo = open(nombre_archivo, \"w\") # \"w\" = write/overwrite\ntexto = [\"Nombre: Samy\\n\", \"Edad: 19 años\\n\", \"Lenguajes de programación favoritos: Python y C#\\n\"]\narchivo.writelines(texto)\narchivo.write(\"Pasatiempo: jugar videojuegos\")\narchivo.close()\n\narchivo = open(nombre_archivo, \"r\") # \"r\" = read\nprint(archivo.read())\narchivo.close()\n\nif os.path.exists(nombre_archivo):\n    os.remove(nombre_archivo)\nelse:\n    print(f\"no hay ningún archivo llamado {nombre_archivo}\")\n\n# *\n# * DIFICULTAD EXTRA (opcional):\n# * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n# * archivo .txt.\n# * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n# *   [nombre_producto], [cantidad_vendida], [precio].\n# * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n# *   actualizar, eliminar productos y salir.\n# * - También debe poseer opciones para calcular la venta total y por producto.\n# * - La opción salir borra el .txt.\n# */\n\nclass gestion_de_ventas:\n    def iniciar_sistema(self):\n        print(\"\\n===== Empezando el sistema =====\\n\")\n        registro = 1\n        total_cantidad = 0\n        total_precio = 0\n        arc = open(\"reporte_de_ventas.txt\", \"w\")\n        arc.write(\"Nombre, Cantidad, Precio\\n\")\n        arc.write(f\"-----------------------------------------\\n\")\n        \n        while registro == 1:\n            novo_producto = input(\"¿Quieres agregar un nuevo producto? (si/no) \").upper()\n\n            if novo_producto == \"SI\":\n                nombre = input(\"Nombre del nuevo producto: \")\n                cantidad = input(\"Cantidad del nuevo producto: \")\n                precio = input(\"Precio del nuevo producto: \")\n\n                total_cantidad += int(cantidad)\n                total_precio += float(precio) * int(cantidad)\n\n                arc.write(f\"{nombre}, {cantidad}, {precio}\\n\")\n            else:\n                registro = 0\n        \n        arc.close()\n        arc = open(\"reporte_de_ventas.txt\", \"a\")\n        arc.write(f\"-----------------------------------------\\n\")\n        arc.write(f\"Total, {total_cantidad}, {total_precio}\\n\")\n        arc.close()\n\n        print(\"\\n===== Cerrando el sistema =====\\n\")\n        \n\nsistema = gestion_de_ventas()\n\nsistema.iniciar_sistema()\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/fborjalv.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n\"\"\"\n# import os \n\n# file_name = \"fborjalv.txt\"\n\n# with open (file_name, \"w\") as file:\n#     file.write(\"Borja LV\\n\")\n#     file.write(\"32\\n\")\n#     file.write(\"['Python','JavaScript']\")\n# with open (file_name, \"r\") as file: \n#     print(file.read())\n\n# os.remove(\"fborjalv.txt\")\n\n\n\"\"\"\nDesarrolla un programa de gestión de ventas que almacena sus datos en un \n * archivo .txt.\n * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n\"\"\"\nfile_name = \"fborjalv_shop.txt\"\n\nopen(file_name, \"a\")\n\nwhile True: \n    print(\"1. Añadir producto \")\n    print(\"2. Consultar productos \")\n    print(\"3. Actualizar productos \")\n    print(\"4. Eliminar productos \")\n    print(\"5. Calcular la venta total \")\n    print(\"6. Calcular ventas por producto \")\n    print(\"7. Salir \")\n    option = input(\"Introduce una opción \")\n\n    if option == \"1\":\n        product_name = input(\"Nombre del producto: \")\n        amount = input(\"Cantidad: \")\n        product_price = input(\"Precio: \")\n        with open(file_name, \"a\") as file:\n            file.write(f\"{product_name}, {amount}, {product_price}\\n\")\n    elif option == \"2\": \n        print(\"Mostrando todos los productos\")\n        with open(file_name, \"r\") as file:\n            print(file.read())\n    elif option == \"3\":\n        product_update = input(\"Introduce el nombre del producto que deseas actualizar: \")\n        with open(file_name, \"r\") as file:\n            lines = file.readlines()\n        with open(file_name, \"w\") as file: \n            for line in lines:\n                if line.split(\",\")[0] == product_update:\n                    amount_update = input(\"Introduce la cantidad de producto: \")\n                    product_price = input(\"Introduce el precio del producto: \")\n                    file.write(f\"{product_update}, {amount_update}, {product_price}\\n\")\n                else:\n                    file.write(line)                \n    elif option == \"4\": \n        detele_product = input(\"¿Qué producto deseas eliminar?\") # misma lógica comprobar que tenemos en lines y que queremos mantener\n        with open(file_name, \"r\") as file: \n            lines = file.readlines()\n        with open(file_name, \"w\") as file:\n            for item in lines: \n                if detele_product != item.split(\",\")[0]:\n                    file.write(item)\n    elif option == \"5\": \n        total = 0\n        print(total)\n        with open(file_name, \"r\") as file:\n            lines = file.readlines()\n        for item in lines:\n            total += int(item.split(\",\")[1]) * float(item.split(\",\")[2])\n        print(total)\n    elif option == \"6\": \n        product_incomes = input(\"Introduce el nombre de un producto: \")\n        with open(file_name, \"r\") as file: \n            lines = file.readlines()\n        for item in lines: \n            if item.split(\",\")[0] == product_incomes:\n                print(int(item.split(\",\")[1]) * float(item.split(\",\")[2]))\n    elif option == \"7\":\n        print(\"Saliendo del programa\")\n        break\n    else:\n        print(\"Ha seleccionado una opción no válida\")"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/garos01.py",
    "content": "import os\n\n# Obtener el nombre de usuario de GitHub\nusername = \"GAROS01\"\n\n# Crear el archivo con extensión .txt\nfilename = f\"{username}.txt\"\n\n# Escribir en el archivo\nwith open(filename, \"w\") as file:\n    file.write(\"Nombre: Oscar Garzon\\n\")\n    file.write(\"Edad: 29\\n\")\n    file.write(\"Lenguaje de programación favorito: Python y JavaScript\\n\")\n\n# Leer el contenido del archivo y imprimirlo\nwith open(filename, \"r\") as file:\n    content = file.read()\n    print(\"Contenido del archivo:\")\n    print(content)\n\n# Borrar el archivo\nos.remove(filename)\nprint(f\"El archivo {filename} ha sido borrado.\")\n\n\n# Ejercicio extra\n\n\ndef leer_archivo():\n    try:\n        with open(\"ventas.txt\", \"r\") as archivo:\n            return archivo.readlines()\n    except FileNotFoundError:\n        print(\"No hay ventas registradas.\")\n        return []\n\n\ndef guardar_venta(nombre_producto, cantidad, precio):\n    with open(\"ventas.txt\", \"a\") as archivo:\n        archivo.write(f\"{nombre_producto}, {cantidad}, {precio}\\n\")\n\n\ndef mostrar_ventas():\n    ventas = leer_archivo()\n    if ventas:\n        print(\"Ventas realizadas:\")\n        for venta in ventas:\n            print(venta.strip())\n    else:\n        print(\"No hay ventas registradas.\")\n\n\ndef actualizar_venta(nombre_producto, nueva_cantidad, nuevo_precio):\n    ventas = leer_archivo()\n    with open(\"ventas.txt\", \"w\") as archivo:\n        for venta in ventas:\n            producto, cantidad, precio = venta.strip().split(\", \")\n            if producto == nombre_producto:\n                cantidad = nueva_cantidad\n                precio = nuevo_precio\n            archivo.write(f\"{producto}, {cantidad}, {precio}\\n\")\n\n\ndef eliminar_venta(nombre_producto):\n    ventas = leer_archivo()\n    with open(\"ventas.txt\", \"w\") as archivo:\n        for venta in ventas:\n            producto, _, _ = venta.strip().split(\", \")\n            if producto != nombre_producto:\n                archivo.write(venta)\n\n\ndef calcular_venta_total():\n    ventas = leer_archivo()\n    total = 0\n    for venta in ventas:\n        _, cantidad, precio = venta.strip().split(\", \")\n        total += int(cantidad) * float(precio)\n    return total\n\n\ndef calcular_venta_producto(nombre_producto):\n    ventas = leer_archivo()\n    for venta in ventas:\n        producto, cantidad, precio = venta.strip().split(\", \")\n        if producto == nombre_producto:\n            return int(cantidad) * float(precio)\n    return 0\n\n\ndef main():\n    while True:\n        print(\"\\nMenú:\")\n        print(\"1. Añadir venta\")\n        print(\"2. Consultar ventas\")\n        print(\"3. Actualizar venta\")\n        print(\"4. Eliminar venta\")\n        print(\"5. Calcular venta total\")\n        print(\"6. Calcular venta por producto\")\n        print(\"7. Salir y borrar archivo\")\n        opcion = input(\"Seleccione una opción: \")\n\n        if opcion == \"1\":\n            nombre_producto = input(\"Ingrese el nombre del producto: \")\n            cantidad = input(\"Ingrese la cantidad vendida: \")\n            precio = input(\"Ingrese el precio unitario: \")\n            guardar_venta(nombre_producto, cantidad, precio)\n        elif opcion == \"2\":\n            mostrar_ventas()\n        elif opcion == \"3\":\n            nombre_producto = input(\"Ingrese el nombre del producto a actualizar: \")\n            nueva_cantidad = input(\"Ingrese la nueva cantidad vendida: \")\n            nuevo_precio = input(\"Ingrese el nuevo precio unitario: \")\n            actualizar_venta(nombre_producto, nueva_cantidad, nuevo_precio)\n        elif opcion == \"4\":\n            nombre_producto = input(\"Ingrese el nombre del producto a eliminar: \")\n            eliminar_venta(nombre_producto)\n        elif opcion == \"5\":\n            total = calcular_venta_total()\n            print(f\"Venta total: {total}\")\n        elif opcion == \"6\":\n            nombre_producto = input(\n                \"Ingrese el nombre del producto para calcular su venta: \"\n            )\n            venta_producto = calcular_venta_producto(nombre_producto)\n            print(f\"Venta de {nombre_producto}: {venta_producto}\")\n        elif opcion == \"7\":\n\n            os.remove(\"ventas.txt\")\n            print(\"Archivo borrado. Saliendo del programa.\")\n            break\n        else:\n            print(\"Opción no válida. Inténtelo de nuevo.\")\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/ggilperez.py",
    "content": "# 11 Files\nimport os\n\nfilename = \"ggilperez.txt\"\n\n# If no path given, it uses __file__ path\nwith open(filename, \"w\") as file:\n    file.write(\"Name: Guillermo\\n\")\n    file.writelines(\"Age: 31\\n\")\n    file.writelines(\"Favourite language: Python\\n\")\n\nwith open(filename, \"r\") as file:\n    print(file.read())\n\nos.remove(filename)\nif not os.path.exists(filename):\n    print(\"File removed successfully\")\n\n\n# Extra\n\ndef store_logistic():\n    filename = \"inventory.txt\"\n\n    # Create empty file\n    open(filename, 'a').close()\n\n    def show_menu():\n        print(\"1. Insert product\")\n        print(\"2. Search product\")\n        print(\"3. Update product\")\n        print(\"4. Delete product\")\n        print(\"5. Show products\")\n        print(\"6. Profit all products\")\n        print(\"7. Profit product\")\n        print(\"8. Exit\")\n\n    def insert_product():\n        name = input(\"Name: \")\n        quantity = input(\"Quantity: \")\n        price = input(\"Price: \")\n\n        row = f\"{name}, {quantity}, {price}\\n\"\n\n        with open(filename, \"a\") as file:\n            file.write(row)\n\n    def search_product():\n        name_to_search = input(\"Name: \")\n\n        with open(filename, \"r\") as file:\n            for row in file:\n                row = row.strip()  # Remove \\n\n                name, quantity, price = row.split(\", \")\n                if name == name_to_search:\n                    print(f\"Product: {name}\")\n                    print(f\"Quantity: {quantity} ud\")\n                    print(f\"Price: ${price}\")\n                    return\n\n        print(\"Product not found\")\n\n    def update_product():\n        name_to_search = input(\"Name: \")\n\n        with open(filename, \"r\") as file:\n            data = file.readlines()\n\n        # Search\n        found = False\n        for i, row in enumerate(data):\n            row = row.strip()  # Remove \\n\n            name, quantity, price = row.split(\", \")\n            if name == name_to_search:\n                found = True\n                new_quantity = input(\"New quantity: \")\n                new_price = input(\"New price: \")\n\n                row = f\"{name}, {new_quantity}, {new_price}\\n\"\n\n                data[i] = row\n                break\n\n        if not found:\n            # Don't update file if product not found\n            print(\"Product not found\")\n            return\n\n        with open(filename, \"w\") as file:\n            file.write(\"\".join(data))\n\n    def delete_product():\n        name_to_search = input(\"Name: \")\n\n        with open(filename, \"r\") as file:\n            data = file.readlines()\n\n        # Search\n        found = False\n        for i, row in enumerate(data):\n            row = row.strip()  # Remove \\n\n            name, quantity, price = row.split(\", \")\n            if name == name_to_search:\n                found = True\n                data.pop(i)\n                break\n\n        if not found:\n            # Don't update file if product not found\n            print(\"Product not found\")\n            return\n\n        with open(filename, \"w\") as file:\n            file.write(\"\".join(data))\n\n    def show_products():\n        with open(filename, \"r\") as file:\n            print(file.read())\n\n    def profit_all_products():\n        total = 0\n        with open(filename, \"r\") as file:\n            for row in file:\n                row = row.strip()\n                name, quantity, price = row.split(\", \")\n                quantity = int(quantity)\n                price = float(price)\n                total += quantity * price\n        print(total)\n\n    def profit_product():\n        name_to_search = input(\"Name: \")\n        total = 0\n        with open(filename, \"r\") as file:\n            for row in file:\n                row = row.strip()\n                name, quantity, price = row.split(\", \")\n                if name == name_to_search:\n                    quantity = int(quantity)\n                    price = float(price)\n                    total += quantity * price\n                    break\n\n        print(total)\n\n    def exit_program():\n        os.remove(filename)\n        print(\"Ending program\")\n\n    while True:\n        show_menu()\n        option = input(\"Select an option: \")\n\n        if option == \"1\":\n            insert_product()\n        elif option == \"2\":\n            search_product()\n        elif option == \"3\":\n            update_product()\n        elif option == \"4\":\n            delete_product()\n        elif option == \"5\":\n            show_products()\n        elif option == \"6\":\n            profit_all_products()\n        elif option == \"7\":\n            profit_product()\n        elif option == \"8\":\n            exit_program()\n            return\n\n\nstore_logistic()\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/gringoam.py",
    "content": "import os\n\n\"\"\"\nEjercicio\n\"\"\"\n\n\"\"\" file_name = \"mouredev.txt\"\n\nwith open(file_name, \"w\") as file:\n    file.write(\"Brais Moure\\n\")\n    file.write(\"36\\n\")\n    file.write(\"Python\")\n\nwith open(file_name, \"r\") as file:\n    print(file.read())\n\nos.remove(file_name) \"\"\"\n\n\"\"\"\nExtra\n\"\"\"\n\nfile_name = \"gringoam_shop.txt\"\n\nopen(file_name, \"a\")\n\ndef agregar_producto(nombre, cantidad_vendida, precio):\n    with open(file_name, \"a\") as file:\n        file.write(f\"{nombre},{cantidad_vendida},{precio}\\n\")\n\ndef consulta_prod(nombre):\n    encontrado=\"\"\n    with open(file_name, \"r\") as file:\n        for line in file.readlines():\n           \n            if line.split(\",\")[0]== nombre:\n                encontrado=line\n                print(line)\n                break\n        if encontrado==\"\":\n            print(\"no se encontró producto\")\n        else:\n            print(encontrado)\n\ndef actualizar_producto(nombre, cantidad_vendida, precio):\n    with open(file_name, \"r\") as file:\n        lines=file.readlines()\n    with open(file_name,\"w\") as file:\n        for line in lines:\n           if line.split(\",\")[0]== nombre:\n                file.write(f\"{nombre},{cantidad_vendida},{precio}\\n\")\n           else:\n                file.write(line)\n\ndef borrar_producto(nombre):\n    with open(file_name, \"r\") as file:\n        lines=file.readlines()\n    with open(file_name,\"w\") as file:\n        for line in lines:\n           if line.split(\",\")[0]== nombre:\n                print(f\"Producto: {nombre} borrado\\n\")\n           else:\n                file.write(line)\n\ndef mostrar_productos():\n    \n    with open(file_name, \"r\") as file:\n            print(file.read())\n\ndef ventas_totales():\n    total=0\n    with open(file_name, \"r\") as file:\n        for line in file.readline():\n            venta=line.split(\",\")\n            cantidad=int(venta[1])\n            precio=float (venta[2])\n            total+=cantidad * precio\n    print(f\"Total de ventas en pesos: {total}\")                \n\ndef venta_por_producto():\n    pass\n\nwhile True:\n    print(\"1. Añadir producto\")\n    print(\"2. Consultar producto\")\n    print(\"3. Actualizar producto\")\n    print(\"4. Borrar producto\")\n    print(\"5. Mostrar productos\")\n    print(\"6. Calcular venta total\")\n    print(\"7. Calcular venta por producto\")\n    print(\"8. Salir\\n\")\n\n    op = input(\"Selecciona una opción: \")\n    \n    match op:\n        case \"1\":\n            nombre=input(\"Nombre: \")\n            cantidad_vendida=input(\"Catidad vendida: \")\n            precio=input(\"Precio: \\n\")\n            agregar_producto(nombre, cantidad_vendida, precio)\n\n        case \"2\":\n             nombre=input(\"Nombre: \")\n             consulta_prod(nombre)\n\n        case \"3\":\n            nombre=input(\"Nombre: \")\n            cantidad_vendida=input(\"Catidad vendida: \")\n            precio=input(\"Precio: \\n\")\n            actualizar_producto(nombre, cantidad_vendida, precio)\n        case \"4\":\n            nombre=input(\"Nombre: \")\n            borrar_producto(nombre)\n        case \"5\":\n            mostrar_productos()\n\n        case \"6\":\n            ventas_totales()\n        case \"7\":\n            venta_por_producto()\n        case \"8\":\n            os.remove(file_name)\n            break\n\n\n\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/haroldAlb.py",
    "content": "# EJERCICIO MANEJO DE FICHEROS #\nimport os\n\ntry:\n    f = open(\"haroldAlb.txt\", \"a\") # Creamos/abrimos el archivo en modo append\n    f.writelines(\"Harold Albiñana Márquez\\n\") # Escribimos\n    f.writelines(\"45\\n\")\n    f.writelines(\"Python\\n\")\n    f.close()\n\n    f = open(\"haroldAlb.txt\", \"r\")\n    print(f.read())\n    f.close()\n\n    os.remove(\"haroldAlb.txt\")\nexcept Exception as e:\n    print(f\"Ha ocurrido un error: {e} - {type(e).__name__}\")\n\n# EXTRA #\ndef main_menu():\n    # Da a elejir opciones entre el 1 y el 8. Hasta que no introduces una opcion correcta no termina.\n    # Lanza un error controlado si se introduce letra o caracter\n    # Sólo retorna un str numérico entre 1 y 8.\n    isOk = True\n    menu = '''### GESTOR DE VENTAS ###\n    \n    1. AÑADIR ARTÍCULO\n    2. CONSULTAR ARTÍCULO\n    3. ACTUALIZAR ARTÍCULO\n    4. VER TODOS LOS ARTÍCULOS\n    5. BORRAR ARTÍCULO\n    6. CALCULAR VENTAS TOTALES\n    7. VENTAS DE UN ARTÍCULO\n    8. SALIR'''\n    print(menu)\n    while isOk:\n        try:\n            choice = input(\"Elije una opción del 1 al 8: \")\n            if int(choice) >=1 and int(choice) <=8:\n                isOk = False\n                return choice\n        except ValueError as e:\n            print(f\"{e} - Vuelve a elegir una opción válida\")\n\ndef askfor_data():\n    # Pide artículo, cantidad vendida y precio unitario.\n    # Retorna los valores introducidos (str)\n\n    item = input(\"Artículo: \")\n    amount_sold = input(\"Cantidad vendida: \")\n    price = input(\"Precio por unidad: \")\n\n    return item, amount_sold, price\n\ndef add_article(file_name=str, item=str, amount_sold=int, price=float):\n    # Abre un archivo en modo adjuntar y escribe una línea con los valores pedidos.\n\n    with open(file_name, \"a\") as file:\n        file.write(f\"{item}, {amount_sold}, {price}\\n\")\n\ndef read_txt(file_name):\n    # Abre un archivo en modo lectura. Retorna el contenido del archivo\n    if os.path.exists(file_name):\n        with open(file_name, \"r\") as f:\n            return f.read() # Retorna un string con el contenido del archivo\n    else:\n        raise FileNotFoundError(\"No hay ningín artículo. Añada artículos con la opción 1.\")\n    \ndef readlines_txt(file_name):\n    # Abre un archivo txt en modo lectura y retorna una lista con las líneas del archivo.\n\n    with open(file_name, \"r\") as f:\n        return f.readlines() # Retorna una lista donde cada item es una línea\n    \ndef update(file_name, search: str, option_change: str, new_value):\n    \n    lines_file = readlines_txt(file_name)\n    aux_name = \"auxFile.txt\"\n    \n    for line in lines_file:\n\n        with open(aux_name, \"a\") as aux_f:\n            if search in line:\n                line_split = line.split(\", \")\n                line_split[int(option_change) - 1] = new_value\n                new_line = \", \".join(line_split)\n\n                aux_f.write(f\"{new_line}\")\n            else:\n                aux_f.write(f\"{line}\")\n\n    if os.path.exists(file_name): # comprueba que existe el archivo. si el archivo no existe remove() retorna una exceepción\n        os.remove(file_name)\n\n    os.rename(aux_name, file_name)\n\ndef erase(file_name, search):\n    lines_file = readlines_txt(file_name)\n    aux_name = \"auxFile.txt\"\n\n    for line in lines_file:\n        with open(aux_name, \"a\") as aux_f:\n            if search not in line:\n                aux_f.write(line)\n\n    os.remove(file_name)\n    os.rename(aux_name, file_name)\n    \ndef total_sales(file_name):\n    total = 0\n    with open(file_name, \"r\") as f:\n        f_lines = f.readlines()\n\n    for line in f_lines:\n        line_split = line.split(\", \")\n        total += (int(line_split[1]) * float(line_split[2]))\n\n    return total\n \ndef search_item(item: str,lines_file: list):\n    # Busca el artículo especificado en la lista de líneas de un archivo. Cada item (str) de la lista tiene este formato: \"[Articulo], [Cantidad_vendida], [Precio_unitario].\"\n    # Cuando encuentra el artículo en una línea, crea una lista con lo que hay en ella, haciendo la división por las comas ya preestablecidad.\n    for line in lines_file:\n        if item in line:\n            return line.split(\", \") # Divide la cadena en una lista donde cada palabra es un elemento de la lista\n\ndef erase_file(file_name=str):\n    os.remove(file_txt)\n\nif __name__ == \"__main__\":\n    file_txt = \"ventasRoadmap.txt\"\n    while True:\n        choice = main_menu()\n\n        if choice == \"1\":# Añadir\n            item, amount_sold, price = askfor_data()\n            add_article(file_txt, item, amount_sold, price)\n\n        elif choice == \"2\": # Consultar\n            print(\"# CONSULTAR ARTÍCULO #\")\n            item = input(\"Artículo: \")\n            lines_file = readlines_txt(file_txt)\n\n            line_split = search_item(item, lines_file)\n            print(f\"{line_split[0]} | Cantidad vendida: {line_split[1]} | Precio unidad: {line_split[2]}\")\n\n        elif choice == \"3\": # Actualizar\n            search = input(\"Artículo a actualizar: \")\n            print(\"Qué desea modificar del artículo:\\n  1. Nombre\\n  2. Cantidad vendida\\n  3. Precio por unidad\")\n            option = input(\"Elija una opción del 1 al 3: \")\n            new_value = input(\"Introduzca valor nuevo: \")\n\n            if option == \"3\":\n                new_value = new_value + \"\\n\"\n\n            update(file_txt, search, option, new_value)\n\n        elif choice == \"4\": # Ver todo\n            try:\n                print(read_txt(file_txt))\n            except Exception as e:\n                print(f\"{e} | {type(e).__name__}\")\n\n        elif choice == \"5\": # Borrar\n            search = input(\"Artículo a eliminar: \")\n            erase(file_txt, search)\n\n        elif choice == \"6\": # Calcular ventas totales\n            print(\"Las ventas totales son: \" + str(total_sales(file_txt)) + \" Euros\")\n\n        elif choice == \"7\": # Ventas de un artículo\n            item = input(\"Introduce el artículo para saber sus ventas: \")\n            lines_file = readlines_txt(file_txt)\n            line_split = search_item(item, lines_file)\n\n            print(f\"Se han vendido {int(line_split[1])} {line_split[0]}. Hace un total de {int(line_split[1]) * float(line_split[2])} euros\")\n\n        elif choice == \"8\": # Salir\n            if os.path.exists(file_txt): # comprueba que existe el archivo. si el archivo no existe remove() retorna una excepción\n                os.remove(file_txt)\n            break\n            \n        else:\n            print(\"Opción incorrecta. Debe elegir un número entre el 1 y el 8.\")"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/hectorio23.py",
    "content": "# Autor: Héctor Adán\n# GitHub: https://github.com/hectorio23\n\nimport os\n\n# Constantes\nnameFile = \"./hectorio23.txt\"\nlanguage = \"Python/C++\"\nname = \"Héctor Adán\"\nage = 19\n\n# Función para escribir en el archivo\ndef write_file():\n    with open(nameFile, 'w') as file:\n        file.write(f\"Nombre: {name}\\n\")\n        file.write(f\"Lenguajes favoritos: {language}\\n\")\n        file.write(f\"Edad: {age}\\n\")\n\n# Función para imprimir el contenido del archivo\ndef print_file_values():\n    with open(nameFile, 'r') as file:\n        for line in file:\n            print(line, end='')\n\n# Función para agregar un producto al archivo de ventas\ndef agregar_producto(nombre, cantidad, precio):\n    with open(\"ventas.txt\", 'a') as archivo:\n        archivo.write(f\"{nombre}, {cantidad}, {precio}\\n\")\n\n# Función para consultar todos los productos en el archivo de ventas\ndef consultar_productos():\n    with open(\"ventas.txt\", 'r') as archivo:\n        for line in archivo:\n            print(line, end='')\n\n# Función para actualizar un producto en el archivo de ventas\ndef actualizar_producto(nombre, cantidad, precio):\n    with open(\"ventas.txt\", 'r') as archivo, open(\"temporal.txt\", 'w') as temporal:\n        for line in archivo:\n            nombre_producto, cant_actual, precio_actual = line.strip().split(', ')\n            if nombre_producto == nombre:\n                temporal.write(f\"{nombre}, {cantidad}, {precio}\\n\")\n            else:\n                temporal.write(f\"{nombre_producto}, {cant_actual}, {precio_actual}\\n\")\n\n# Función para eliminar un producto del archivo de ventas\ndef eliminar_producto(nombre):\n    with open(\"ventas.txt\", 'r') as archivo, open(\"temporal.txt\", 'w') as temporal:\n        for line in archivo:\n            nombre_producto, cant_actual, precio_actual = line.strip().split(', ')\n            if nombre_producto != nombre:\n                temporal.write(f\"{nombre_producto}, {cant_actual}, {precio_actual}\\n\")\n\n# Función para calcular la venta total del archivo de ventas\ndef calcular_venta_total():\n    total = 0\n    with open(\"ventas.txt\", 'r') as archivo:\n        for line in archivo:\n            nombre_producto, cantidad, precio = line.strip().split(', ')\n            total += int(cantidad) * float(precio)\n    return total\n\n# Función para calcular la venta de un producto específico del archivo de ventas\ndef calcular_venta_por_producto(nombre):\n    with open(\"ventas.txt\", 'r') as archivo:\n        for line in archivo:\n            nombre_producto, cantidad, precio = line.strip().split(', ')\n            if nombre_producto == nombre:\n                return int(cantidad) * float(precio)\n    return 0\n\n# Función para manejar la opción de salir del programa\ndef salir():\n    os.remove(\"ventas.txt\")\n    print(\"Archivo borrado. Saliendo del programa...\")\n    exit(0)\n\n# Función principal\ndef main():\n    # Crear archivo con datos requeridos\n    print(\"\\nEJERCICIO\\n\")\n    print(\"Creando archivo hectorio23.txt e insertando datos\\n\")\n    write_file()\n\n    # Imprimir los valores del archivo\n    print(\"Imprimiendo los valores contenidos en el archivo hectorio23.txt\\n\")\n    print_file_values()\n\n    # Ejercicio Extra - Gestión de Ventas\n    print(\"\\nEJERCICIO EXTRA\\n\")\n\n    while True:\n        print(\"===== Gestión de Ventas =====\")\n        print(\"1. Añadir producto\")\n        print(\"2. Consultar productos\")\n        print(\"3. Actualizar producto\")\n        print(\"4. Eliminar producto\")\n        print(\"5. Calcular venta total\")\n        print(\"6. Calcular venta por producto\")\n        print(\"7. Salir\")\n\n        opcion = int(input(\"Seleccione una opción: \"))\n\n        if opcion == 1:\n            nombre = input(\"Nombre del producto: \")\n            cantidad = int(input(\"Cantidad vendida: \"))\n            precio = float(input(\"Precio: \"))\n            agregar_producto(nombre, cantidad, precio)\n        elif opcion == 2:\n            print(\"Productos registrados:\")\n            consultar_productos()\n        elif opcion == 3:\n            nombre = input(\"Nombre del producto a actualizar: \")\n            cantidad = int(input(\"Nueva cantidad vendida: \"))\n            precio = float(input(\"Nuevo precio: \"))\n            actualizar_producto(nombre, cantidad, precio)\n        elif opcion == 4:\n            nombre = input(\"Nombre del producto a eliminar: \")\n            eliminar_producto(nombre)\n        elif opcion == 5:\n            print(f\"Venta total: ${calcular_venta_total()}\")\n        elif opcion == 6:\n            nombre = input(\"Nombre del producto para calcular venta: \")\n            print(f\"Venta de {nombre}: ${calcular_venta_por_producto(nombre)}\")\n        elif opcion == 7:\n            salir()\n        else:\n            print(\"Opción no válida. Inténtelo de nuevo.\")\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/hozlucas28.py",
    "content": "# pylint: disable=line-too-long\n# pylint: disable=missing-module-docstring\n# pylint: disable=pointless-string-statement\n# pylint: disable=unnecessary-dunder-call\n\n\nimport os\nfrom typing import Self, TypedDict\n\n\"\"\"\n    Files...\n\"\"\"\n\nprint(\"Files...\")\n\nprint(\n    \"\"\"\\nFILE: str = \"hozlucas28.txt\"\n\nif os.path.exists(path=FILE):\n    os.remove(path=FILE)\n\n\nwith open(file=FILE, mode=\"w+t\", encoding=\"utf8\") as file:\n    CONTENT: list[str] = [\"Lucas Hoz\\\\n\", \"22\\\\n\", \"Python\"]\n    file.writelines(CONTENT)\n    file.close()\n\n\nwith open(file=FILE, mode=\"r+t\", encoding=\"utf8\") as file:\n    for LINE in file.readlines():\n        print(LINE, end=\"\")\n    file.close()\n\n\nif os.path.exists(path=FILE):\n    os.remove(path=FILE)\\n\"\"\"\n)\n\nFILE: str = \"hozlucas28.txt\"\n\nif os.path.exists(path=FILE):\n    os.remove(path=FILE)\n\n\nwith open(file=FILE, mode=\"w+t\", encoding=\"utf8\") as file:\n    CONTENT: list[str] = [\"Lucas Hoz\\n\", \"22\\n\", \"Python\"]\n    file.writelines(CONTENT)\n    file.close()\n\n\nwith open(file=FILE, mode=\"r+t\", encoding=\"utf8\") as file:\n    for LINE in file.readlines():\n        print(LINE, end=\"\")\n    file.close()\n\n\nif os.path.exists(path=FILE):\n    os.remove(path=FILE)\n\n\nprint(\n    \"\\n\\n# ---------------------------------------------------------------------------------- #\"\n)\n\n\"\"\"\n    Additional challenge...\n\"\"\"\n\n\nProduct = TypedDict(\"Product\", {\"amount\": int, \"name\": str, \"price\": float})\nTotal = TypedDict(\"Total\", {\"amount\": int, \"total\": float})\n\n\nclass SalesFile:\n    \"\"\"Sales files\"\"\"\n\n    __path: str\n    __deleted: bool = False\n\n    def __init__(self, path: str, _products: None | list[Product] = None) -> None:\n        if _products is None:\n            _products = []\n\n        mapped_products: list[Product] = self.__map_products(_products=_products)\n\n        self.__path = path\n        self.__rewrite_products(_products=mapped_products)\n\n    def __get_product_index(self, _product_name) -> int | None:\n        for i, __product in enumerate(iterable=self.get_products()):\n            if __product[\"name\"].upper() == _product_name.upper():\n                return i\n\n        raise NameError(\"Product doesn't exist\")\n\n    def __is_deleted(self) -> bool | None:\n        if self.__deleted:\n            raise FileNotFoundError()\n\n        return False\n\n    def __map_products(self, _products: list[Product]) -> list[Product]:\n        mapped_products: list[Product] = []\n        products_copy: list[Product] = _products.copy()\n\n        for i, anchor_product in enumerate(iterable=products_copy):\n            for j, next_product in enumerate(iterable=products_copy[i + 1 :]):\n                if anchor_product[\"name\"].upper() == next_product[\"name\"].upper():\n                    anchor_product[\"amount\"] += next_product[\"amount\"]\n                    anchor_product[\"price\"] = max(\n                        anchor_product[\"price\"], next_product[\"price\"]\n                    )\n                    products_copy.pop(j + i + 1)\n                    i -= 1\n\n            mapped_products.append(anchor_product)\n\n        return mapped_products\n\n    def __rewrite_products(self, _products: list[Product]) -> Self:\n        with open(file=self.__path, mode=\"w+t\", encoding=\"utf8\") as _sales_file:\n            if _products:\n                new_products: list[str] = []\n                for _product in _products:\n                    new_products.append(\n                        f\"{_product['name']}, {_product['amount']}, {_product['price']}\\n\"\n                    )\n                new_products[len(new_products) - 1] = new_products[-1][:-1]\n\n                _sales_file.writelines(new_products)\n            _sales_file.close()\n\n        return self\n\n    def get_product(self, _product_name: str) -> None | Product:\n        \"\"\"Return saved product in the file.\"\"\"\n        self.__is_deleted()\n        for __product in self.get_products():\n            if __product[\"name\"].upper() == _product_name.upper():\n                return __product\n\n        raise NameError(\"Product doesn't exist\")\n\n    def get_products(self) -> list[Product]:\n        \"\"\"Return saved products in the file.\"\"\"\n        self.__is_deleted()\n        _products: list[Product] = []\n\n        with open(file=self.__path, mode=\"r+t\", encoding=\"utf8\") as _sales_file:\n            for _product in _sales_file.readlines():\n                [_name, _amount, _price] = _product.split(sep=\", \")\n                _products.append(\n                    {\"amount\": int(_amount), \"name\": _name, \"price\": float(_price)}\n                )\n            _sales_file.close()\n\n        return _products\n\n    def get_total_product(self, _product_name: str) -> None | Total:\n        \"\"\"Return total\"\"\"\n        _product: None | Product = self.get_product(_product_name=_product_name)\n\n        if _product is not None:\n            return {\n                \"amount\": _product[\"amount\"],\n                \"total\": _product[\"price\"] * _product[\"amount\"],\n            }\n\n        raise NameError(\"Product doesn't exist\")\n\n    def get_total(self) -> Total:\n        \"\"\"Return \"amount\" and \"price\" total of the saved products in the file.\"\"\"\n        self.__is_deleted()\n        totals: Total = {\n            \"amount\": 0,\n            \"total\": 0,\n        }\n\n        for _product in self.get_products():\n            totals[\"amount\"] += _product[\"amount\"]\n            totals[\"total\"] += _product[\"price\"] * _product[\"amount\"]\n\n        return totals\n\n    def append_product(self, _product: Product) -> Self:\n        \"\"\"Append products to the file.\"\"\"\n        self.__is_deleted()\n        _products: list[Product] = self.get_products()\n        _products.append(_product)\n\n        _mapped_products: list[Product] = self.__map_products(_products=_products)\n        self.__rewrite_products(_products=_mapped_products)\n\n        return self\n\n    def delete_file(self) -> None:\n        \"\"\"Delete file.\"\"\"\n        self.__is_deleted()\n        os.remove(path=self.__path)\n\n    def delete_product(self, _product_name: str) -> Self:\n        \"\"\"Delete saved product\"\"\"\n        self.__is_deleted()\n        _products: list[Product] = self.get_products()\n        product_index: int | None = self.__get_product_index(\n            _product_name=_product_name\n        )\n\n        print(product_index)\n\n        if product_index is not None:\n            _products.pop(product_index)\n            self.__rewrite_products(_products=_products)\n\n        return self\n\n    def update_product(\n        self,\n        _product_name: str,\n        _amount: int | None = None,\n        _price: float | None = None,\n    ) -> Self:\n        \"\"\"Update saved product\"\"\"\n        self.__is_deleted()\n        _products: list[Product] = self.get_products()\n        product_index: int | None = self.__get_product_index(\n            _product_name=_product_name\n        )\n\n        if product_index is not None:\n            product_to_update: Product = _products[product_index]\n            original_amount: int = product_to_update[\"amount\"]\n            original_name: str = product_to_update[\"name\"]\n            original_price: float = product_to_update[\"price\"]\n\n            _products.__setitem__(\n                product_index,\n                {\n                    \"amount\": _amount if _amount else original_amount,\n                    \"name\": original_name,\n                    \"price\": _price if _price else original_price,\n                },\n            )\n\n            self.__rewrite_products(_products=_products)\n\n        return self\n\n\nsales_file = SalesFile(path=\"sales.txt\")\n\nSHOULD_EXIT: bool = False\nwhile not SHOULD_EXIT:\n    operation: str = input(\n        \"\\nSelect an operation ('Add', 'Delete', 'Print', 'Update', 'Total sales', 'Total sales of a product', or 'Exit'): \"\n    ).upper()\n\n    if operation == \"ADD\":\n        product_information: str = input(\n            \"\\nProduct infomation ([Name], [Amount], [Price]): \"\n        )\n        if not product_information:\n            break\n\n        product: list[str] = product_information.split(sep=\", \")\n\n        if len(product) == 3:\n            sales_file.append_product(\n                _product={\n                    \"amount\": int(product[1]),\n                    \"name\": product[0],\n                    \"price\": float(product[2]),\n                }\n            )\n        else:\n            print(\"\\nInvalid syntax! It should be, for example: Apple, 10, 50.85\")\n\n    elif operation == \"DELETE\":\n        product_name: str = input(\"\\nProduct name to delete: \")\n        if product_name:\n            sales_file.delete_product(_product_name=product_name)\n    elif operation == \"PRINT\":\n        products: list[Product] = sales_file.get_products()\n\n        print()\n        for _product in products:\n            print(f\"{_product['name']}, {_product['amount']}, {_product['price']}\")\n\n    elif operation == \"UPDATE\":\n        product_name: str = input(\"\\nProduct name to update: \")\n        if not product_name:\n            break\n\n        amount: str = input(\"New amount (optional): \")\n        price: str = input(\"New price (optional): \")\n        new_amount: int | None = int(amount) if amount else None\n        new_price: float | None = float(price) if price else None\n\n        sales_file.update_product(\n            _amount=new_amount, _price=new_price, _product_name=product_name\n        )\n    elif operation == \"TOTAL SALES\":\n        total_sales: Total = sales_file.get_total()\n        print(f\"\\nAmount = {total_sales['amount']}\\nTotal = {total_sales['total']}\")\n    elif operation == \"TOTAL SALES OF A PRODUCT\":\n        product_name: str = input(\"\\nProduct name: \")\n        if not product_name:\n            break\n\n        total_product_sales: Total | None = sales_file.get_total_product(\n            _product_name=product_name\n        )\n        if total_product_sales:\n            print(\n                f\"\\nAmount = {total_product_sales['amount']}\\nTotal = {total_product_sales['total']}\"\n            )\n    elif operation == \"EXIT\":\n        sales_file.delete_file()\n        SHOULD_EXIT = True\n    else:\n        print(\"\\nInvalid operation! Try again...\")\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/idiegorojas.py",
    "content": "import os\n\nfile_name = 'idiegorojas.txt'\n\nwith open(file_name, 'w') as file:\n    file.write('Diego 1\\nRojas 2\\n')\n    file.write('28\\n')\n    file.write('Python\\n')\n\nwith open(file_name, 'r') as file:\n    print(file.read())\n\nos.remove(file_name)\n\n\n# Extra\n\nfile_name = 'sales.txt'\n\nopen(file_name, 'a')\n\nwhile True:\n    print('Bienvenido.')\n    print(\"1. Añadir producto\")\n    print(\"2. Consultar producto\")\n    print(\"3. Actualizar producto\")\n    print(\"4. Borrar producto\")\n    print(\"5. Calcular venta total\")\n    print(\"6. Calcular venta por producto\")\n    print(\"7. Salir\")\n\n    option = input(\"Por favor selecciona una opción: \")\n\n    if option == \"1\":\n        name = input(\"Ingresa el nombre del producto: \")\n        quantity = input(\"Ingresa la cantidad vendida: \")\n        price = input(\"Ingresa el precio del producto vendido: \")\n        with open(file_name, \"a\") as file:\n            file.write(f\"{name}, {quantity}, {price}\\n\")\n    elif option == \"2\":\n        name = input(\"Ingresa el nombre del producto a consultar: \")\n        with open(file_name, \"r\") as file:\n            for line in file.readlines():\n                if line.split(\", \")[0] == name:\n                    print(line)\n                    break\n    elif option == \"3\":\n        name = input(\"Nombre: \")\n        quantity = input(\"Cantidad: \")\n        price = input(\"Precio: \")\n        with open(file_name, \"r\") as file:\n            lines = file.readlines()\n        with open(file_name, \"w\") as file:\n            for line in lines:\n                if line.split(\", \")[0] == name:\n                    file.write(f\"{name}, {quantity}, {price}\\n\")\n                else:\n                    file.write(line)\n    elif option == \"4\":\n        name = input(\"Nombre: \")\n        with open(file_name, \"r\") as file:\n            lines = file.readlines()\n        with open(file_name, \"w\") as file:\n            for line in lines:\n                if line.split(\", \")[0] != name:\n                    file.write(line)\n    elif option == \"5\":\n        total = 0\n        with open(file_name, \"r\") as file:\n            for line in file.readlines():\n                components = line.split(\", \")\n                quantity = int(components[1])\n                price = float(components[2])\n                total += quantity * price\n        print(total)\n    elif option == \"6\":\n        name = input(\"Nombre: \")\n        total = 0\n        with open(file_name, \"r\") as file:\n            for line in file.readlines():\n                components = line.split(\", \")\n                if components[0] == name:\n                    quantity = int(components[1])\n                    price = float(components[2])\n                    total += quantity * price\n                    break\n        print(total)\n    elif option == \"7\":\n        os.remove(file_name)\n        break\n    else:\n        print(\"Por favor selecciona una de las opciones disponibles.\")"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/ignaciovihe.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n\"\"\"\n\nfrom pathlib import Path\n\ndef manage_my_file():\n    with open(\"ignaciovihe.txt\",\"a\") as my_file:# Si no existe el archivo lo crea. En este caso modo append.\n        my_file.write(\"Ignacio\\n40\\nPython\\n\")\n\n    try:\n        with open(\"ignaciovihe.txt\", \"r\") as my_file:\n            print(my_file.read())\n    except FileNotFoundError as e:\n        print(e)\n\n    my_file = Path(\"ignaciovihe.txt\")# Borra el archivo\n    if my_file.exists():\n        my_file.unlink()\n\nmanage_my_file()\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n * archivo .txt.\n * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n\"\"\"\n\ndef sells_management():\n\n    file_name = \"sells_resume.txt\"\n\n    def _add_product(product: str, quantity: int, price: float):\n        \"\"\"#Escribe una nueva linea al final del fichero.\"\"\"\n\n        with open(file_name, \"a\") as f:\n            f.write(f\"{product}, {quantity}, {price}\\n\")\n\n    def _write_lines_to_file(lines: list):\n        \"\"\"Escribe las lineas, incluida la modificada, nuevamente en el fichero\"\"\"\n\n        with open(file_name, \"w\") as f:\n            f.writelines(lines)\n\n    def _is_number(param: str)-> bool:\n        \"\"\"Comprueba si el parametro str pasado en númerico.\"\"\"\n\n        try:\n            float(param)\n            return True\n        except ValueError:\n            print(\"Introduce un número.\")\n            return False\n        \n    def _get_product_info(option = False):\n        \"\"\"\n        Pide al usuario los datos del producto.\n        Si se pasa \"True\" como parametro, pide la cantidad y el precio.\n        Si no se pasa parametro, sólo pide el nombre del producto.\n        \"\"\"\n\n        product = input(\"Introduce el nombre de producto: \")\n\n        if option: #Para añadir y actualizar pido la cantidad y precio\n\n            while True:\n                quantity = input(\"Introduce cantidad vendida: \")\n                if not _is_number(quantity):\n                    continue\n                break\n\n            while True:\n                price = input(\"Introduce precio de venta: \")\n                if not _is_number(price):\n                    continue\n                break\n            \n            return product, quantity, price\n        \n        else:\n\n            return product\n\n    def update_product(product: str, quantity: int, price: float):\n        already_in = False\n\n        try:\n            with open(file_name, \"r\") as f:\n                lines = f.readlines()\n                for i,line in enumerate(lines):\n                    parts = line.split(\", \")\n                    if product == parts[0]:\n                        lines[i] = f\"{product}, {quantity}, {price}\\n\"\n                        already_in = True\n                        print(\"Producto actualizado.\")\n                        break\n                if not already_in:\n                    _add_product(product, quantity, price)\n                else:\n                    _write_lines_to_file(lines)\n        except FileNotFoundError:\n            _add_product(product, quantity, price)\n\n    def search(product: str, mode = \"s\"):\n        try:\n            with open(file_name,\"r\") as f:\n                lines = f.readlines()\n\n                for index, line in enumerate(lines):\n                    parts = line.split(\", \")\n                    if product == parts[0]:\n                        if mode == \"s\":\n                            return f\"{parts[0]}, {parts[1]}, {parts[2].strip(\"\\n\")}\"\n                        else:\n                            element = lines.pop(index)\n                            print(f\"Elemento [{element.strip(\"\\n\")}] eliminado\")\n                            _write_lines_to_file(lines)\n                            return True\n                return \"No se encuentra el producto\"\n        except FileNotFoundError:\n            print(\"El archivo no existe.\")\n            return False\n\n    def calculate_total()-> float:\n        with open(file_name,\"r\") as f:\n            lines = f.readlines()\n            total = 0\n            for line in lines:\n                product, quantity, price = line.strip(\"\\n\").split(\", \")\n                total_product = float(quantity) * float(price)\n                print(f\"[{product}] = [{total_product}]\")\n                total += total_product\n            print(f\"[Total de ventas: {total}]\")\n\n    def show_products():\n        try:\n            with open(file_name,\"r\") as f:\n                print(f.read())\n        except FileNotFoundError:\n            print(\"El fichero no existe\")\n\n    def exit():\n        my_file = Path(\"sells_resume.txt\")# Borra el archivo\n        if my_file.exists():\n            my_file.unlink()\n        print(\"Hasta pronto\")\n\n\n\n\n    while True:\n        print(\"SELLS MANAGEMENT\")\n        print(\"1. Añadir producto.\")\n        print(\"2. Actualizar producto.\")\n        print(\"3. Consultar producto.\")\n        print(\"4. Eliminar producto.\")\n        print(\"5. Total ventas.\")\n        print(\"6. Total ventas de un producto.\")\n        print(\"7. Mostrar productos\")\n        print(\"8. Salir.\")\n        option = input(\"Elige una opción: \")\n\n        match option:\n            case \"1\" | \"2\":\n                product, quantity, price = _get_product_info(True)               \n                update_product(product, quantity, price)\n\n            case \"3\":\n                product = _get_product_info()\n                print(f\"[{search(product)}]\")\n\n            case \"4\":\n                product = _get_product_info()\n                search(product,\"d\")\n\n            case \"5\":\n                calculate_total()\n\n            case \"6\":\n                product = _get_product_info()\n                try:\n                    full_product = search(product).split(\", \")\n                    print(f\"Total ventas de {full_product[0]}: {float(full_product[1]) * float(full_product[2])}€\")\n                except IndexError:\n                    print(\"No se encontro el producto. Operación abortada.\")\n                except AttributeError:\n                    print(\"Operación abortada.\")\n\n            case \"7\":\n                show_products()\n\n            case \"8\":\n                exit()\n                break\n\n            case _:\n                print(\"Opcion invalida.\")\n\n\n\n\n\n\nsells_management()\n\n\n\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/ipfabio.py",
    "content": "import os\n\n\"\"\"\nEjercicio\n\"\"\"\n\nfile_name = \"ipfabio.txt\"\n\nwith open(file_name, 'w') as archivo:\n    archivo.write(\"Fabio\\n\")\n    archivo.write(\"40\\n\")\n    archivo.write(\"Python\\n\")\n\nwith open(file_name, \"r\") as archivo_a_leer:\n    contenido = archivo_a_leer.read()\n    print(contenido)\n\nif os.path.exists(file_name):\n    os.remove(file_name)\n    print(f\"El archivo: {file_name} ha sido borrado.\\n\")\nelse:\n    print(f\"El archivo: {file_name} no se encuentra.\\n\")\n\n\"\"\"\nExtra\n\"\"\"\n\nfile_name = \"ipfabio_shop.txt\"\n\nwhile True:\n    print(\"1. Añadir producto\")\n    print(\"2. Consultar producto\")\n    print(\"3. Actualizar producto\")\n    print(\"4. Borrar producto\")\n    print(\"5. Mostrar productos\")\n    print(\"6. Calcular venta total\")\n    print(\"7. Calcular venta por producto\")\n    print(\"8. Salir\")\n    print(\" \")\n    option = input(\"Selecciona una opción: \")\n    \n    match option:\n        case \"1\": # Añadir producto\n            name = input(\"Nombre: \")\n            quantity = input(\"Cantidad: \")\n            price = input(\"Precio: \")\n\n            with open(file_name, 'a') as archivo:\n                archivo.write(f\"{name}, {quantity}, {price}\\n\")\n        case \"2\": # Consultar producto\n            name = input(\"Nombre: \")\n            found = False # Variable para rastrear si se encontró el producto\n            \n            with open(file_name, \"r\") as file:\n                for line in file.readlines():\n                    if line.split(\", \")[0] == name:\n                        print(line)\n                        found = True\n                        break\n            if not found:\n                print(f\"{name} no se encuentra en la lista. Intenta agregandolo\")\n\n        case \"3\": # Actualizar producto\n            name = input(\"Nombre: \")\n            quantity = input(\"Cantidad: \")\n            price = input(\"Precio: \")\n            found = False\n\n            # Leer el archivo y almacernarlo en 'lines' \n            with open(file_name, \"r\") as file:\n                lines = file.readlines()\n\n            # Abrir el archivo para sobreescribir\n            with open(file_name, \"w\") as file:\n                for line in lines: # Usar la lista 'lines' que ya fue leida\n                    if line.split(\", \")[0] == name:\n                        file.write(f\"{name}, {quantity}, {price}\\n\")\n                        found = True # El producto fue encontrado y actualizado\n                    else:\n                        file.write(line)\n\n            if not found:\n                print(f\"Producto {name} no encontrado.\")\n            else:\n                print(f\"Producto: {name}. Actualizado correctamente!\")\n        case \"4\": # Borrar producto\n            name = input(\"Nombre: \")\n\n            with open(file_name, \"r\") as file:\n                lines = file.readlines()\n\n            with open(file_name, \"w\") as file:\n                for line in lines: # Usar la lista 'lines' que ya fue leida\n                    if line.split(\", \")[0] != name:\n                        file.write(line) # Solo me quedo con lo items que no cumplen con el nombre ingresado.\n            print(f\"{name} ha sido borrado.\")\n                    \n        case \"5\": # Mostrar productos\n            if os.path.exists(file_name):\n                with open(file_name, \"r\") as productos_a_mostrar:\n                    print(productos_a_mostrar.read())\n            else:\n                print(\"Todavía no se ha generado la lista de compras. Pruebe agregando productos\\n\")\n        case \"6\": # Calcular venta total\n            total = 0\n             \n            # Leer el archivo y almacernarlo en 'lines' \n            with open(file_name, \"r\") as file:\n                for line in file.readlines():\n                    components = line.split(\", \")\n                    quantity = int(components[1])\n                    price = float(components[2])\n                    total += quantity * price\n            print(f\"Total a pagar: ${total}\")\n\n        case \"7\": # Calcular venta por producto\n            name = input(\"Nombre: \")\n            total = 0\n             \n            # Leer el archivo y almacernarlo en 'lines' \n            with open(file_name, \"r\") as file:\n                for line in file.readlines():\n                    components = line.split(\", \")\n                    if components[0] == name:\n                        quantity = int(components[1])\n                        price = float(components[2])\n                        total += quantity * price\n                        break\n            print(f\"{name} total es: ${total}\")\n\n        case \"8\": # Salir\n            print(\"Saliendo...\")\n            if os.path.exists(file_name):\n                os.remove(file_name)\n                print(f\"El archivo: {file_name} ha sido borrado.\")\n            else:\n                print(f\"El archivo: {file_name} no se encuentra.\")\n            break\n        case _:\n            print(\"No es una opción válida.\\n\")"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/isilanes.py",
    "content": "\"\"\"\nEl enunciado del ejercicio extra es confuso. Parece desearse un listado de ventas, en el que cada\nentrada/línea sea una VENTA. Sin embargo, el enunciado dice \"Cada PRODUCTO se guarda en una línea\ndel arhivo (sic), de la siguiente manera [...]\". Si vendo 2 manzanas un día, y 3 otro, ¿la segunda\nventa debe ir en una línea adicional, o debo actualizar la primera línea, y cambiar el 2 por un 5?\n\nLa respuesta obvia parece ser la primera opción, y asumir que cada línea es una VENTA, no un PRODUCTO.\nSi esto es así, también es confusa la opción de \"eliminar productos\" que menciona el enunciado.\n¿Se refiere a eliminar ventas? ¿O son realmente productos? En el segundo caso habría que borrar todas\nlas líneas con ventas de un determinado producto. Asumo la opción más obvia, que cada línea\nes una venta, y que las entradas añadidas/modificadas/eliminadas son ventas (no productos).\n\"\"\"\nfrom pathlib import Path\n\n\nclass Lock:\n    \"\"\"\n    Class to lock a file, so that multiple concurrent executions do not clash.\n    \"\"\"\n    def __init__(self, file: Path):\n        self.file = file\n\n    @property\n    def lock(self) -> Path:\n        lock_name = f\".{self.file.name}.lock\"\n\n        return self.file.parent.joinpath(lock_name)\n\n    def __enter__(self):\n        if self.lock.exists():  # then someone else acquired the lock already\n            return None\n\n        self.lock.touch()\n\n        return self.lock\n\n    def __exit__(self, *args, **kwargs):\n        self.lock.unlink(missing_ok=True)\n\n\ndef main():\n    file = Path(\"./isilanes.txt\")\n    file.write_text(\"Iñaki Silanes\\n46 años\\nPython\\n\")\n\n    contents = file.read_text()\n    print(contents, end=\"\")\n\n    file.unlink()\n\n\ndef extra():\n    db_file = Path(\"./ventas.txt\")\n\n    while True:\n        # Si no quisiera limitarme a las librerías estándar, recomiendo mucho Questionary,\n        # para interacción por CLI.\n        option = input(\"Selecciona: [a]ñadir, [c]onsultar, ac[t]ualizar, [e]liminar, [v]entas totales, ve[n]tas por producto, [s]alir: \")\n\n        if option == \"a\":\n            add_sale(db_file)\n\n        elif option == \"c\":\n            check_sales(db_file)\n\n        elif option == \"t\":\n            update_sale(db_file)\n\n        elif option == \"e\":\n            remove_sale(db_file)\n\n        elif option == \"v\":\n            print_total_sales(db_file)\n\n        elif option == \"n\":\n            print_sales_per_product(db_file)\n\n        elif option == \"s\":\n            break\n\n    # On exit, delete db file:\n    db_file.unlink(missing_ok=True)\n\n\ndef add_sale(db_file: Path) -> bool:\n    \"\"\"\n    Add the data for one sale.\n\n    Args:\n        db_file (Path):\n            Text file with sales \"database\".\n\n    Returns:\n        True if data insertion was successful, False otherwise.\n    \"\"\"\n    name = input(\"Nombre del producto: \")\n\n    units = input(\"Unidades vendidas: \")\n    try:\n        units = int(units)\n    except ValueError:\n        print(\"Debes introducir un número entero. Abortando...\")\n        return False\n\n    price = input(\"Precio unitario: \")\n    try:\n        price = float(price)\n    except ValueError:\n        print(\"Debes introducir un número. Abortando...\")\n        return False\n\n    with Lock(db_file) as lock:\n        if not lock:\n            print(f\"No pudimos bloquear el fichero '{db_file}'. Algún otro proceso debe de estar usándolo.\")\n            return False\n\n        line = f\"{name}, {units}, {price}\\n\"\n\n        with open(db_file, \"a\", encoding=\"utf-8\") as f:\n            f.write(line)\n\n    return True\n\n\ndef check_sales(db_file: Path) -> None:\n    \"\"\"\n    List all sales so far. In other words, print the contents of the db file.\n    If the db file does not exist, do nothing.\n\n    Args:\n         db_file (Path):\n            Text file with sales \"database\".\n\n    Returns:\n        Nothing.\n    \"\"\"\n    if not db_file.exists():\n        return\n\n    print(\"Ventas recogidas en la base de datos:\")\n    print(db_file.read_text(), end=\"\")\n\n\ndef update_sale(db_file: Path) -> bool:\n    \"\"\"\n    Update an existing sale.\n    If the db file does not exist, do nothing.\n\n    Args:\n         db_file (Path):\n            Text file with sales \"database\".\n\n    Returns:\n        True if update was successful, False otherwise.\n    \"\"\"\n    if not db_file.exists():\n        return False\n\n    with Lock(db_file) as lock:\n        if not lock:\n            print(f\"No pudimos bloquear el fichero '{db_file}'. Algún otro proceso debe de estar usándolo.\")\n            return False\n\n        sales = []\n        with open(db_file, \"r\", encoding=\"utf-8\") as f:\n            for i, line in enumerate(f):\n                print(f\"{i:3d}: {line}\", end=\"\")\n                sales.append(line)\n\n        index = input(\"Escoge una venta a modificar, por índice (Enter sin número para cancelar): \")\n\n        if index == \"\":\n            return False\n\n        try:\n            index = int(index)\n            line = sales[index]\n        except ValueError:\n            print(\"El índice no es un número entero. Abortando...\")\n            return False\n        except IndexError:\n            print(\"Índice fuera de los valores posibles. Abortando...\")\n            return False\n\n        name, units, price = line.split(\",\")\n        units = int(units)\n        price = float(price)\n\n        which = input(\"¿Qué campo quieres modificar? ([n]ombre, [c]antidad, [p]recio): \")\n\n        if which == \"n\":\n            new = input(\"Nuevo nombre del producto: \")\n            name = new\n        elif which == \"c\":\n            new = input(\"Nueva cantidad de producto: \")\n            units = int(new)\n        elif which == \"p\":\n            new = input(\"Nuevo precio del producto: \")\n            price = float(new)\n\n        sales[index] = f\"{name}, {units}, {price}\\n\"\n        with open(db_file, \"w\", encoding=\"utf-8\") as f:\n            for sale in sales:\n                f.write(sale)\n\n    return True\n\n\ndef remove_sale(db_file: Path) -> bool:\n    \"\"\"\n    Remove an existing sale.\n    If the db file does not exist, do nothing.\n\n    Args:\n         db_file (Path):\n            Text file with sales \"database\".\n\n    Returns:\n        True if removal was successful, False otherwise.\n    \"\"\"\n    if not db_file.exists():\n        return False\n\n    with Lock(db_file) as lock:\n        if not lock:\n            print(f\"No pudimos bloquear el fichero '{db_file}'. Algún otro proceso debe de estar usándolo.\")\n            return False\n\n        sales = []\n        with open(db_file, \"r\", encoding=\"utf-8\") as f:\n            for i, line in enumerate(f):\n                print(f\"{i:3d}: {line}\", end=\"\")\n                sales.append(line)\n\n        index = input(\"Escoge una venta a eliminar, por índice (Enter sin número para cancelar): \")\n\n        if index == \"\":\n            return False\n\n        try:\n            index = int(index)\n        except ValueError:\n            print(\"El índice no es un número entero. Abortando...\")\n            return False\n\n        sales = sales[:index] + sales[index+1:]\n        with open(db_file, \"w\", encoding=\"utf-8\") as f:\n            for sale in sales:\n                f.write(sale)\n\n    return True\n\n\ndef print_total_sales(db_file: Path) -> None:\n    \"\"\"\n    Print out the total sales.\n    If the db file does not exist, do nothing.\n\n    Args:\n         db_file (Path):\n            Text file with sales \"database\".\n\n    Returns:\n        Nothing.\n    \"\"\"\n    if not db_file.exists():\n        return\n\n    total_sold = 0\n    with open(db_file, \"r\", encoding=\"utf-8\") as f:\n        for line in f:\n            _, units, price = line.split(\",\")\n            units = int(units)\n            price = float(price)\n            total_sold += units * price\n\n    print(f\"Volumen de ventas total: {total_sold:.2f}\")\n\n\ndef print_sales_per_product(db_file: Path) -> None:\n    \"\"\"\n    Print out the sales per product.\n    If the db file does not exist, do nothing.\n\n    Args:\n         db_file (Path):\n            Text file with sales \"database\".\n\n    Returns:\n        Nothing.\n    \"\"\"\n    if not db_file.exists():\n        return\n\n    sales = {}\n    with open(db_file, \"r\", encoding=\"utf-8\") as f:\n        for line in f:\n            prod, units, price = line.split(\",\")\n            units = int(units)\n            price = float(price)\n            sales[prod] = {\n                \"units\": sales.get(prod, {}).get(\"units\", 0) + units,\n                \"volume\": sales.get(prod, {}).get(\"volume\", 0) + units*price,\n            }\n\n    print(\"Ventas totales por producto:\")\n    for k, v in sales.items():\n        print(f\"{k:10s}: {v.get('units', 0):2d} unidades, {v.get('volume', 0):6.2f} volumen total\")\n\n\nif __name__ == \"__main__\":\n    main()\n    extra()\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/javierjoyera.py",
    "content": "import os\n\nusuario_github = \"javierjoyera\"\nnombre_archivo = (\"%s.txt\") % (usuario_github)\n\n\n# Crear y escribir en el archivo\nwith open(nombre_archivo, 'w') as archivo:\n    archivo.write(\"Nombre: Javier Joyera\\n\")\n    archivo.write(\"Edad: 27\\n\")\n    archivo.write(\"Lenguaje de programación favorito: Python\\n\")\n\n# Leer e imprimir el contenido del archivo\nwith open(nombre_archivo, 'r') as archivo:\n    contenido = archivo.read()\n    print(contenido)\n\n# Borrar el fichero\nos.remove(nombre_archivo)\nprint(\"El archivo %s ha sido eliminado.\" % (nombre_archivo))\n\n\n##Ejercicio Extra\n# Nombre del archivo donde se guardan los datos\narchivo_datos = 'ventas.txt'\ndef mostrar_menu():\n    print(\"\\nMenú de gestión de ventas:\")\n    print(\"1. Añadir producto\")\n    print(\"2. Consultar productos\")\n    print(\"3. Actualizar producto\")\n    print(\"4. Eliminar producto\")\n    print(\"5. Calcular venta total\")\n    print(\"6. Calcular venta por producto\")\n    print(\"7. Salir\")\n\n##Cada producto lo guardaremos como [nombre_producto], [cantidad_vendida], [precio].\ndef añadir_producto():\n    nombre_producto = input(\"Introduce el nombre del producto: \")\n    cantidad_vendida = input(\"Introduce la cantidad vendida: \")\n    precio = input(\"Introduce el precio del producto: \")\n    with open(archivo_datos, 'a') as archivo:\n        archivo.write(\"%s, %s, %s\\n\" % (nombre_producto, cantidad_vendida, precio))\n    print(\"Producto añadido correctamente.\")\n\ndef consultar_productos():\n    #Solamente debemos sacar el nombre del producto\n    with open(archivo_datos, 'r') as archivo:\n        lineas = archivo.readlines()\n    for linea in lineas:\n        partes = linea.split(', ')\n        print(partes[0])\n    \ndef actualizar_producto():\n    nombre_producto = input(\"Introduce el nombre del producto a actualizar: \")\n    nueva_cantidad = input(\"Introduce la nueva cantidad vendida: \")\n    nuevo_precio = input(\"Introduce el nuevo precio: \")\n    with open(archivo_datos, 'r') as archivo:\n        lineas = archivo.readlines()\n    with open(archivo_datos, 'w') as archivo:\n        for linea in lineas:\n            if nombre_producto in linea:\n                archivo.write(\"%s, %s, %s\\n\" % (nombre_producto, nueva_cantidad, nuevo_precio))\n                print(\"Producto actualizado correctamente.\")\n            else:\n                archivo.write(linea)\n\ndef eliminar_producto():\n    nombre_producto = input(\"Introduce el nombre del producto a eliminar: \")\n    with open(archivo_datos, 'r') as archivo:\n        lineas = archivo.readlines()\n    with open(archivo_datos, 'w') as archivo:\n        for linea in lineas:\n            if nombre_producto not in linea:\n                archivo.write(linea)\n        print(\"Producto eliminado correctamente.\")\n\ndef calcular_venta_total():\n    with open(archivo_datos, 'r') as archivo:\n        lineas = archivo.readlines()\n    venta_total = 0\n    for linea in lineas:\n        partes = linea.split(', ')\n        cantidad_vendida = int(partes[1])\n        precio = float(partes[2])\n        venta_total += cantidad_vendida * precio\n    print(\"La venta total es de %.2f\" % venta_total)\n\ndef calcular_venta_producto():\n    nombre_producto = input(\"Introduce el nombre del producto a consultar: \")\n    with open(archivo_datos, 'r') as archivo:\n        lineas = archivo.readlines()\n    for linea in lineas:\n        partes = linea.split(', ')\n        if nombre_producto in partes:\n            cantidad_vendida = int(partes[1])\n            precio = float(partes[2])\n            venta_producto = cantidad_vendida * precio\n            print(\"La venta total del producto %s es de %.2f\" % (nombre_producto, venta_producto))\n            return\n    print(\"Producto no encontrado.\")\n\ndef main():\n    while True:\n        mostrar_menu()\n        opcion = input(\"Elige una opción: \")\n        if opcion == '1':\n            añadir_producto()\n        elif opcion == '2':\n            consultar_productos()\n        elif opcion == '3':\n            actualizar_producto()\n        elif opcion == '4':\n            eliminar_producto()\n        elif opcion == '5':\n            calcular_venta_total()\n        elif opcion == '6':\n            calcular_venta_producto()\n        elif opcion == '7':\n            #Eliminamos el fichero al salir del programa\n            if os.path.exists(archivo_datos):\n                os.remove(archivo_datos)\n            print(\"Saliendo del programa...\")\n            break\n        else:\n            print(\"Opción no válida.\")\n\n\nif __name__ == '__main__':\n    main()"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/jesusgdev.py",
    "content": "'''\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n \n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n   tu usuario de GitHub y tenga la extensión .txt.\n   Añade varias líneas en ese fichero:\n   - Tu nombre.\n   - Edad.\n   - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n \n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n   archivo .txt.\n   - Cada producto se guarda en una línea del archivo de la siguiente manera:\n     [nombre_producto], [cantidad_vendida], [precio].\n   - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n     actualizar, eliminar productos y salir.\n   - También debe poseer opciones para calcular la venta total y por producto.\n   - La opción salir borra el .txt.\n'''\n\nimport os\n\nfile = \"jesusgdev.txt\"\n\nwith open(file, \"w\", encoding=\"utf-8\") as archivo:\n    archivo.write(\"Nombre: Jesus Garcia\\n\" + \"Edad: 41\\n\" + \"Lenguaje favorito: Pyhton\")\n\nwith open(file, \"r\", encoding=\"utf-8\") as archivo:\n    content = archivo.read()\n    print(\"Contenido del archivo:\\n\" + content)\n\nos.remove(file)\nprint(f\"\\nEl archivo '{file}' ha sido eliminado\")\n\n'''\nExtra\n'''\n\n# 📦 Importamos el módulo 'os' que nos permite trabajar con archivos del sistema (como crear, borrar, verificar si existen, etc.)\nimport os\n\n# 🧾 Función principal del programa de gestión de ventas\ndef sales_managment():\n    # 📂 Nombre del archivo donde se almacenarán los productos\n    file = \"sale_managment_book.txt\"\n\n    # 🔁 Iniciamos un bucle infinito que mostrará el menú hasta que el usuario elija salir\n    while True:\n        \n        # 🧭 Menú principal\n        print(\"\\n🛒 GESTOR DE VENTAS\")\n        print(\"1️⃣ Añadir producto\")\n        print(\"2️⃣ Consultar productos\")\n        print(\"3️⃣ Actualizar producto\")\n        print(\"4️⃣ Eliminar producto\")\n        print(\"5️⃣ Ver ventas totales\")\n        print(\"6️⃣ Salir y eliminar archivo\")\n\n        # 🧠 Solicitamos al usuario que seleccione una opción del menú\n        option = input(\"\\n🔽 Seleccione una opción (1-6): \")\n\n        # 🧩 Usamos 'match' para manejar la opción seleccionada (como un menú inteligente)\n        match option:\n\n            # ➕ OPCIÓN 1: Añadir producto\n            case \"1\":\n                product_name = input(\"📌 Ingrese el nombre del producto: \")\n                quantity_units_sold = input(\"📦 Ingrese la cantidad de unidades vendidas: \")\n                unit_price = input(\"💲 Ingrese el precio de venta unitario: \")\n\n                # ✍️ Abrimos el archivo en modo \"agregar\" (append) y escribimos los datos\n                with open(file, \"a\", encoding=\"utf-8\") as archivo:\n                    archivo.write(f\"{product_name},{quantity_units_sold},{unit_price}\\n\")\n                    print(\"✅ Producto agregado exitosamente.\")\n\n            # 📄 OPCIÓN 2: Consultar productos\n            case \"2\":\n                if not os.path.exists(file):\n                    print(\"⚠️ No hay productos registrados aún.\")\n                    return\n\n                with open(file, \"r\", encoding=\"utf-8\") as archivo:\n                    lines = archivo.readlines()\n                    \n                    if len(lines) == 0:\n                        print(\"📭 El archivo está vacío. No hay productos registrados.\")\n                    else:\n                        print(\"\\n📋 LISTA DE PRODUCTOS REGISTRADOS:\")\n                        for line in lines:\n                            product_name, quantity_units_sold, unit_price = line.strip().split(\",\")\n                            print(f\"🔹 Nombre: {product_name} | Unidades: {quantity_units_sold} | Precio Unitario: ${unit_price}\")\n\n            # 🛠️ OPCIÓN 3: Actualizar producto\n            case \"3\":\n                update_name_product = input(\"📝 Ingrese el nombre del producto que desea actualizar: \")\n                updated = False\n\n                if not os.path.exists(file):\n                    print(\"⚠️ No hay productos registrados aún.\")\n                    return\n                \n                with open(file, \"r\", encoding=\"utf-8\") as archivo:\n                    lines = archivo.readlines()\n\n                # 🧽 Reescribimos el archivo con la información actualizada\n                with open(file, \"w\", encoding=\"utf-8\") as archivo:\n                    for line in lines:\n                        product_name, quantity_units_sold, unit_price = line.strip().split(\",\")\n                        if update_name_product == product_name:\n                            update_quantity_units_sold = input(\"🔁 Nueva cantidad de unidades vendidas: \")\n                            update_unit_price = input(\"🔁 Nuevo precio unitario: \")\n                            archivo.write(f\"{product_name},{update_quantity_units_sold},{update_unit_price}\\n\")\n                            updated = True\n                        else:\n                            archivo.write(line)\n                            \n                    if not updated:\n                        print(f\"❌ El producto '{update_name_product}' no fue encontrado. No se realizaron cambios.\")\n\n            # 🗑️ OPCIÓN 4: Eliminar producto\n            case \"4\":\n                remove_name_product = input(\"🗑️ Ingrese el nombre del producto que desea eliminar: \")\n                removed = False\n\n                if not os.path.exists(file):\n                    print(\"⚠️ No hay productos registrados aún.\")\n                    return\n                \n                with open(file, \"r\", encoding=\"utf-8\") as archivo:\n                    lines = archivo.readlines()\n\n                with open(file, \"w\", encoding=\"utf-8\") as archivo:\n                    for line in lines:\n                        product_name, quantity_units_sold, unit_price = line.strip().split(\",\")\n                        if remove_name_product != product_name:\n                            archivo.write(line)\n                        else:\n                            removed = True\n                            print(f\"✅ El producto '{remove_name_product}' ha sido eliminado del registro.\")\n\n                if not removed:\n                    print(f\"❌ El producto '{remove_name_product}' no fue encontrado. No se eliminaron productos.\")\n\n            # 💰 OPCIÓN 5: Ver ventas totales\n            case \"5\":\n                if not os.path.exists(file):\n                    print(\"⚠️ No hay productos registrados aún.\")\n                    return\n\n                with open(file, \"r\", encoding=\"utf-8\") as archivo:\n                    lines = archivo.readlines()\n                    \n                    if len(lines) == 0:\n                        print(\"📭 El archivo está vacío. No hay ventas registradas.\")\n                    else:\n                        print(\"\\n📈 VENTAS TOTALES POR PRODUCTO:\")\n                        quantity_sold = 0\n                        for line in lines:\n                            product_name, quantity_units_sold, unit_price = line.strip().split(\",\")\n                            quantity_sold_per_product = int(quantity_units_sold) * int(unit_price)\n                            quantity_sold += quantity_sold_per_product\n                            print(f\"🔸 {product_name}: ${quantity_sold_per_product}\")\n                        print(f\"\\n💵 TOTAL GENERAL DE VENTAS: ${quantity_sold}\")\n                        return  # Finaliza la función después de mostrar las ventas\n\n            # 🚪 OPCIÓN 6: Salir y eliminar archivo\n            case \"6\":\n                os.remove(file)\n                print(f\"\\n🗃️ El archivo '{file}' ha sido eliminado correctamente. ¡Hasta pronto!\")\n                break  # Salimos del bucle para terminar el programa\n\n# ▶️ Ejecutamos la función\nsales_managment()\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/josealberto13.py",
    "content": "\"\"\"/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n * \n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\"\"\"\n\nimport os\n\nfile_name = \"josealberto13.txt\"\nwith open(file_name, \"w\") as file:\n    file.write(\"Jose Alberto\\n\")\n    file.write(\"26\\n\")\n    file.write(\"Python\")\n    \nwith open(file_name, \"r\") as file:\n    print(file.read())\n\nos.remove(file_name)\n\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n* Desarrolla un programa de gestión de ventas que almacena sus datos en un \n* archivo .txt.\n* - Cada producto se guarda en una línea del archivo de la siguiente manera:\n*   [nombre_producto], [cantidad_vendida], [precio].\n* - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n*   actualizar, eliminar productos y salir.\n* - También debe poseer opciones para calcular la venta total y por producto.\n* - La opción salir borra el .txt.\n*/\"\"\"\nfile_name = \"josealberto13_shop.txt\"\n\nwhile True:\n    print(\"1. Añadir producto\")\n    print(\"2. Consultar productos\")\n    print(\"3. Actualizar producto\")\n    print(\"4. Buscar producto\")\n    print(\"5. Calcular venta total\")\n    print(\"6. Calcular venta por producto\")\n    print(\"7. Eliminar producto\")\n    print(\"8. Eliminar Todo y Salir\")\n    \n    option = input(\"Selecciona una opción: \")\n    \n    match option:\n        case \"1\":\n            name = input(\"Nombre del Producto: \")\n            quantity = input(\"Cantidad: \")\n            price = input(\"Precio: \")\n            with open(file_name, \"a\") as file:\n                file.write(f\"{name}, {quantity}, {price}\\n\")\n        case \"2\":\n            with open(file_name, \"r\") as file:\n                print(file.read())       \n        case \"3\":\n            search = input(\"Nombre del Producto: \")\n            with open(file_name, \"r\") as file:\n                lines = file.readlines()\n# Sobre escribimos todos los elementos guardados en \"lines\" y reemplazmos en el caso que encontremos el producto buscado\n            with open(file_name, \"w\") as file: \n                aux = False\n                for line in lines:\n                    if line.split(\", \")[0] == search:\n                        name = input(\"Nombre del Producto: \")\n                        quantity = input(\"Cantidad: \")\n                        price = input(\"Precio: \")\n                        file.write(f\"{name}, {quantity}, {price}\\n\")\n                        aux = True\n                    else:\n                        file.write(line)\n                if aux == False:\n                    print(\"¡ERROR, El producto no existe!\\n\")\n        case \"4\":\n            search = input(\"Nombre del Producto: \")\n            with open(file_name, \"r\") as file:\n                for line in file.readlines():\n                    if line.split(\", \")[0] == search:\n                        print(line)\n                        break\n                    else:\n                        print(\"¡ERROR, El producto no existe!\\n\")\n                        break\n        case \"5\":\n            total = 0\n            with open(file_name, \"r\") as file:\n                for line in file.readlines():\n# total = quantity[1] * price[2] se transforman a int, ya que son guardados como str, para evitar errores seria mejor transformar a float\n                    total += int(line.split(\", \")[1]) * int(line.split(\", \")[2])\n            print(total)\n        case \"6\":\n            total = 0\n            search = input(\"Nombre del Producto: \")\n            with open(file_name, \"r\") as file:\n                for line in file.readlines():\n                    if line.split(\", \")[0] == search:\n                        total += int(line.split(\", \")[1]) * int(line.split(\", \")[2])\n            print(total)\n        case \"7\":\n            search = input(\"Nombre del Producto: \")\n            with open(file_name, \"r\") as file:\n                lines = file.readlines()\n            with open(file_name, \"w\") as file:\n                for line in lines:\n                    if line.split(\", \")[0] != search:\n                        file.write(line)\n        case \"8\":\n            os.remove(file_name) # Elimina el archivo que hemos creado\n            print(\"Saliste del programa\")\n            break\n        case _:\n            print(\"Selecciona unda de las opciones disponibles!\")"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/jptxaya.py",
    "content": "#MANEJO DE FICHEROS\n\nimport os\n\ntry:\n    #Creacion y escritura\n    with open(\"jptxaya.txt\",\"w+\") as my_fich:\n        my_fich.writelines([\"Jptxaya \\n\",\"45 \\n\"])\n        my_fich.write(\"Java\")\n    #Lectura Fichero\n    with open(\"jptxaya.txt\",\"r\") as my_fich:\n        for line in my_fich:\n            print(line)\n    #Borrado del fichero\n    os.remove(\"jptxaya.txt\")\nexcept Exception as exc:\n    print(f\"Exception {exc}\")\n\n#Dificultad Extra\n    \ndef fich_lines_to_list():\n    with open(\"jptx_ventas.txt\",\"r\") as my_fich:\n        new_list = []\n        for line in my_fich.readlines():\n            lista = line.split(\";\")\n            new_list.append(lista)\n        return new_list\n\ndef list_to_fich(lista):\n    with open(\"jptx_ventas.txt\",\"w\") as my_fich:\n        for elem in lista:\n            line = \";\".join([elem[0],str(elem[1]),str(elem[2]),\"\\n\"])\n            my_fich.write(line)\n    \n        \n\n                \n    \nprint(\"Dificultad Extra\")\nwhile True:\n    print(\"Gestion de Ventas\")\n    print(\"1-Añadir\")\n    print(\"2-Consultar\")\n    print(\"3-Actualizar\")\n    print(\"4-Eliminar\")\n    print(\"5-Venta Total\")\n    print(\"6-Salir\")\n    option = input(\"Selecciona la opcion:\")\n    match option:\n        case \"6\":\n            try:\n                os.remove(\"jptx_ventas.txt\")\n                break\n            except Exception as excep:\n                print(\"Nos se ha podido borrar el fichero porque no existia\")\n        case \"1\":\n            try:\n                nombre_producto = input(\"Introduce el nombre producto:\")\n                cantidad_vendida = int(input(\"Cantidad Vendida:\"))\n                precio = int(input(\"Introducir Precio:\"))\n                with open(\"jptx_ventas.txt\",\"a+\") as my_fich:\n                    line = \";\".join([nombre_producto,str(cantidad_vendida),str(precio),\"\\n\"])\n                    my_fich.write(line)\n            except Exception as exc:\n                print(\"Datos incorrectos introducidos\")\n        case \"2\":\n            lista_total = fich_lines_to_list()\n            count = 1\n            for lista in lista_total:\n                print(f\"Linea {str(count)} Product: {lista[0]} Cantidad:{lista[1]} Precio:{lista[2]}\")\n                count += 1\n        case \"3\":\n            try:\n                lista_total = fich_lines_to_list()\n                count = 1\n                for lista in lista_total:\n                    print(f\"Linea {str(count)} Product: {lista[0]} Cantidad:{lista[1]} Precio:{lista[2]}\")\n                    count += 1    \n                lin_act = int(input(\"Introducir la el número linea a actualizar:\"))\n                if lin_act <= len(lista_total) and lin_act >= 1:\n                    nombre_producto = input(\"Introduce el nombre producto:\")\n                    cantidad_vendida = int(input(\"Cantidad Vendida:\"))\n                    precio = int(input(\"Introducir Precio:\"))\n                    lista_total[lin_act-1] = [nombre_producto,cantidad_vendida,precio]\n                    list_to_fich(lista_total)\n            except Exception as excp:\n                print(f\"Exception {excp}\")\n        case \"4\":\n            try:\n                lista_total = fich_lines_to_list()\n                count = 1\n                for lista in lista_total:\n                    print(f\"Linea {str(count)} Product: {lista[0]} Cantidad:{lista[1]} Precio:{lista[2]}\")\n                    count += 1    \n                lin_act = int(input(\"Introducir el número linea a eliminar:\"))\n                if lin_act <= len(lista_total) and lin_act >= 1:\n                    lista_total.pop(lin_act-1)\n                    list_to_fich(lista_total)\n            except Exception as excp:\n                print(f\"Exception {excp}\")\n        case \"5\":\n            try:\n                lista_total = fich_lines_to_list()\n                my_dict = {}\n                for elem in lista_total:\n                    my_dict[elem[0]] = my_dict.get(elem[0],0) + (int(elem[1]) * int(elem[2]))\n                venta_total = 0\n                for elem in my_dict.keys():\n                    print(f\"Producto {elem} Ventas:{my_dict[elem]}\")\n                    venta_total += int(my_dict[elem])\n                print(f\"Ventas Totales:{venta_total}\")\n            except Exception as excp:\n                print(f\"Exception {excp}\")\n\n\n\n\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/juanchernandezdev.py",
    "content": "### Python File Handling ###\nimport os\n\nfile = 'juanchernandezdev.txt'\n\nwith open(file, 'w') as f:\n  f.write('- Juan Carlos Hernandez.\\n')\n  f.write('- 36.\\n')\n  f.write('- Python and JavaScript.\\n')\n\nwith open(file, 'r') as f_read:\n  print(f_read.read())\n\nos.remove(file)\n\n#! Optional Challenge\n#* Store Sales\ndef product_generator() -> str:\n  name = input('Type the product name : ')\n  quantity = int(input('Type the product quantity: '))\n  price = float(input('Type the product price: $'))\n\n  return f'{name}, {quantity}, {price}\\n'\n\ndef lines_list(filename) -> list:\n  with open(filename, 'r') as f:\n    lines = f.readlines()\n    for i, line in enumerate(lines):\n      print(f'{i + 1} - {line}')\n      \n  return lines\n\ndef create_file(filename):\n  open(filename, 'w')\n    \ndef add_product(filename):\n  with open(filename, 'a') as f:\n    product = product_generator()\n    f.write(product)\n    \ndef store_products(filename):\n  with open(filename, 'r') as f:\n    print('Current Products: ')\n    print(f.read())\n    \ndef update_product(filename):\n  lines = lines_list(filename)\n  line_num = int(input('Type the number of the product you want to update: '))\n  new_product = product_generator()\n  lines[line_num - 1] = new_product\n  print('Product updated.')\n\n  with open(filename, 'w') as f:\n    f.writelines(lines)\n\ndef delete_product(filename):\n  lines = lines_list(filename)\n  line_num = int(input('Type the number of the product you want to delete: '))\n  lines.remove(lines[line_num - 1])\n  print('Product was deleted')\n  \n  with open(filename, 'w') as f:\n    f.writelines(lines)\n    \ndef total_sales(filename):\n  total = 0\n  \n  products = lines_list(filename)\n  for line in products:\n    components = line.split(', ')\n    quantity = int(components[1])\n    price = float(components[2])\n    total += price * quantity\n  \n  print(f'Total sales : ${total}')\n\ndef product_sales(filename):\n  lines = lines_list(filename)\n  line_num = int(input('Type the number of the product you want to see the total sales: '))\n  components = lines[line_num - 1].split(', ')\n  quantity = int(components[1])\n  price = float(components[2])\n  total = price * quantity\n  \n  print(f'The total sales for {components[0]} is: ${total}')\n        \nprint('-----Welcome to your store manager-----')\n\nstore_name = 'mystore.txt'\nopen(store_name, 'w')\nprint('Store Created!!')\n\nwhile True:\n  user_option = input('''\n  Please type an option to manage your store inventory:\n  - \"a\" to add an item.\n  - \"i\" to see your inventory.\n  - \"u\" to update and item.\n  - \"d\" to delete an item.\n  - \"t\" to see the total sales.\n  - \"p\" to see the sales of a product.\n  - \"q\" to quit the program.\n  ''').lower()\n\n  if user_option == 'a':\n    add_product(store_name)\n  elif user_option == 'i':\n    store_products(store_name)\n  elif user_option == 'u':\n    update_product(store_name)\n  elif user_option == 'd':\n    delete_product(store_name)\n  elif user_option == 't':\n    total_sales(store_name)\n  elif user_option == 'p':\n    product_sales(store_name) \n  elif user_option == 'q':\n    os.remove(store_name)\n    break\n  "
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/juandaherrera.py",
    "content": "\"\"\"\n/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n\"\"\"\n\nimport os\n\nfile_name = 'juandaherrera.txt'\n\nwith open(file_name, 'w') as file:\n    file.write('Nombre: Juan David Herrera\\n')\n    file.write('Edad: 24\\n')\n    file.write('Lenguaje favorito: Python\\n')\n\nwith open(file_name, 'r') as file:\n    content = file.read()\n\nprint(content)\n\nif os.path.exists(file_name):\n    os.remove(file_name)\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n * archivo .txt.\n * - Cada producto se guarda en una línea del arhivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n\"\"\"\n\nfrom dataclasses import dataclass, field, fields\nfrom typing import Union\n\n\n@dataclass\nclass Transaction:\n    id: int\n    product: str\n    qty: int\n    price: float\n\n    @property\n    def total(self):\n        return self.qty * self.price\n\n\n@dataclass\nclass DataBase:\n    transaction_list: list[Transaction] = field(default_factory=list)\n    file_name: str = 'juandaherrera_bd.txt'\n\n    def __post_init__(self):\n        self.load_transactions_from_file()\n\n    def load_transactions_from_file(self):\n        if os.path.exists(self.file_name):\n            with open(self.file_name, 'r') as file:\n                for line in file:\n                    id_str, product, qty_str, price_str = line.strip().split(', ')\n\n                    id = int(id_str)\n                    qty = int(qty_str)\n                    price = float(price_str)\n\n                    transaction = Transaction(id=id, product=product, qty=qty, price=price)\n                    self.transaction_list.append(transaction)\n\n    def save_database(self):\n        with open(self.file_name, 'w') as file:\n            for transaction in self.transaction_list:\n                file.write(\n                    f'{transaction.id}, {transaction.product}, {transaction.qty}, {transaction.price}\\n'\n                )\n\n    def search_transaction(self, id) -> Union[int, None]:\n        for index, transaction in enumerate(self.transaction_list):\n            if transaction.id == id:\n                return index\n\n        return None\n\n    def next_id(self) -> int:\n        if len(self.transaction_list) == 0:\n            return 1\n        return max((transaction.id for transaction in self.transaction_list)) + 1\n\n    def add_transaction(self, product: str, qty: int, price: float, id: int = None):\n        if not id or id == '':\n            id = self.next_id()\n        elif self.search_transaction(int(id)):\n            raise ValueError(f'La transacción con id {id} ya existe. Ingrese un id diferente')\n\n        transaction = Transaction(int(id), product, qty, price)\n\n        self.transaction_list.append(transaction)\n        self.save_database()\n\n    def update_transaction(self, id: int, product: str, qty: int, price: float):\n        transaction_index = self.search_transaction(int(id))\n        if transaction_index is None:\n            raise ValueError(f'La transacción con id {id} NO existe. Ingrese un id diferente')\n\n        self.transaction_list[transaction_index] = Transaction(id, product, qty, price)\n        self.save_database()\n\n    def delete_transaction(self, id: int):\n        transaction_index = self.search_transaction(int(id))\n        if not transaction_index:\n            raise ValueError(f'La transacción con id {id} NO existe. Ingrese un id diferente')\n\n        del self.transaction_list[transaction_index]\n        self.save_database()\n\n\ndatabase = DataBase()\n\nprint('-' * 30)\nprint('Opciones')\nprint(\n    '1. Agregar transacción',\n    '2. Editar transacción',\n    '3. Eliminar transacción',\n    '4. Ver transacción',\n    '5. Ver todas las transacciones',\n    '6. Salir',\n    sep='\\n',\n)\nwhile True:\n    print('-' * 30)\n    option = input('Ingrese la opción: ')\n\n    match option:\n        case '1':\n            try:\n                id = input('id: ')\n                product = input('product: ')\n                qty = int(input('qty: '))\n                price = float(input('price: '))\n\n                database.add_transaction(id=id, product=product, qty=qty, price=price)\n            except Exception as e:\n                print('Error:', e)\n        case '2':\n            try:\n                id = input('id: ')\n                product = input('product: ')\n                qty = int(input('qty: '))\n                price = float(input('price: '))\n\n                database.update_transaction(id=id, product=product, qty=qty, price=price)\n            except Exception as e:\n                print('Error:', e)\n        case '3':\n            try:\n                id = input('id: ')\n                database.delete_transaction(id)\n            except Exception as e:\n                print('Error:', e)\n        case '4':\n            try:\n                id = input('id: ')\n                index = database.search_transaction(int(id))\n                print(database.transaction_list[index])\n            except Exception as e:\n                print('Error:', e)\n        case '5':\n            print(database.transaction_list)\n        case '6':\n            if os.path.exists(database.file_name):\n                os.remove(database.file_name)\n            break\n        case _:\n            print('Intenta otra opción')\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/juanmax2.py",
    "content": "\"\"\"\nManejo de ficheros\n\"\"\"\nimport os\n\"\"\"\n\n\nfile_name = \"juanmax2.txt\"\nwith open(file_name, \"w\") as file:\n    file.write(\"Juan Manuel\\n\")\n    file.write(\"32\\n\")\n    file.write(\"Python\")\n\nwith open(file_name, \"r\") as file:\n    print(file.read())\n\nos.remove(file_name)\n\"\"\"\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n * archivo .txt.\n * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n\"\"\"\ncontinuar = True\nnombre_fichero = \"ventas.txt\"\n\nwhile continuar == True:\n    print(\"1. Añadir producto\")\n    print(\"2. Consultar producto\")\n    print(\"3. Actualizar producto\")\n    print(\"4. Borrar producto\")\n    print(\"5. Mostrar todos los productos\")\n    print(\"6. Calcular venta total\")\n    print(\"7. Calcular venta por producto\")\n    print(\"8. Salir\")\n\n    option = input(\"Selecciona una opción: \")\n    \n    if option == \"1\":\n        nombre = input(\"Nombre: \")\n        cantidad = input(\"Cantidad: \")\n        precio = input(\"Precio: \")\n        with open(nombre_fichero, \"a\") as file:\n            file.write(f\"{nombre}, {cantidad}, {precio}\\n\")\n    elif option == \"2\":\n        nombre = input(\"Nombre: \")\n        with open(nombre_fichero, \"r\") as file:\n            for line in file.readlines():\n                if line.split(\", \")[0] == nombre:\n                    print(line)\n    elif option == \"3\":\n        nombre = input(\"Nombre: \")\n        cantidad = input(\"Cantidad: \")\n        precio = input(\"Precio: \")\n        with open(nombre_fichero, \"r\") as file:\n            lines = file.readlines()\n        with open(nombre_fichero, \"w\") as file:\n            for line in lines:\n                if line.split(\", \")[0] == nombre:\n                    file.write(f\"{nombre}, {cantidad}, {precio}\\n\")\n                else:\n                    file.write(line)                \n    elif option == \"4\":\n        nombre = input(\"Nombre: \")\n        with open(nombre_fichero, \"r\") as file:\n            lines = file.readlines()\n        with open(nombre_fichero, \"w\") as file:\n            for line in lines:\n                if line.split(\", \")[0] != nombre:\n                    file.write(line)   \n    elif option == \"5\":\n        with open(nombre_fichero, \"r\") as file:\n            print(file.read())\n    elif option == \"6\":\n        total = 0\n        with open(nombre_fichero, \"r\") as file:\n            for line in file.readlines():\n                componentes = line.split(\", \")\n                cantidad = int(componentes[1])\n                precio = float(componentes[2])\n                total += cantidad * precio\n        print(f\"Total: {total}\")\n    elif option == \"7\":\n        suma = 0\n        nombre = input(\"Nombre: \")\n        with open(nombre_fichero, \"r\") as file:\n            for line in file.readlines():\n                componentes = line.split(\", \")\n                if componentes[0] == nombre:\n                    cantidad = int(componentes[1])\n                    precio = int(componentes[2])\n                    suma = cantidad * precio\n        print(f\"Precio: {suma}\")\n    elif option == \"8\":\n        os.remove(nombre_fichero)\n        continuar = False\n    else:\n        print(\"Selecciona una de las opciones disponibles.\")"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/juanppdev.py",
    "content": "\"\"\"\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n * \n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n\"\"\"\n\nimport os\n\nusuario_github = 'Juanppdev'\nnombre_archivo = f\"{usuario_github}.txt\"\n\nnombre = \"  Juan Pablo\"\nedad = \"25 Años\"\nlenguaje_favorito = \"Python y Kotlin\"\n\ntry:\n    with open(nombre_archivo, 'w') as archivo:\n        archivo.write(f\"Nombre: {nombre}\\n\")\n        archivo.write(f\"Edad: {edad}\\n\")\n        archivo.write(f\"Lenguaje de Programación Favorito: {lenguaje_favorito}\\n\")\n    print(f\"Archivo {nombre_archivo} creado exitosamente.\")\nexcept Exception as e:\n    print(f\"Error al crear el archivo: {e}\")\n\ntry:\n    with open(nombre_archivo, 'r') as archivo:\n        contenido = archivo.read()\n        print(contenido)\nexcept Exception as e:\n    print(f\"Error al leer el archivo: {e}\")\n\n\"\"\"\ntry:\n    os.remove(nombre_archivo)\n    print(f\"Archivo {nombre_archivo} borrado exitosamente.\")\nexcept Exception as e:\n    print(f\"Error al borrar el archivo: {e}\")\n\"\"\"\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n * archivo .txt.\n * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n\"\"\"\n\nimport os\n\nnombre_archivo = 'ventas.txt'\n\ndef agregar_producto():\n    nombre_producto = input(\"Nombre del producto: \")\n    cantidad_vendida = input(\"Cantidad vendida: \")\n    precio = input(\"Precio: \")\n    try:\n        with open(nombre_archivo, 'a') as archivo:\n            archivo.write(f\"{nombre_producto}, {cantidad_vendida}, {precio}\\n\")\n        print(f\"Producto {nombre_producto} agregado exitosamente.\")\n    except Exception as e:\n        print(f\"Error al agregar el producto: {e}\")\n\ndef consultar_productos():\n    try:\n        if os.path.exists(nombre_archivo):\n            with open(nombre_archivo, 'r') as archivo:\n                print(archivo.read())\n        else:\n            print(\"No hay productos registrados.\")\n    except Exception as e:\n        print(f\"Error al consultar los productos: {e}\")\n\ndef actualizar_producto():\n    try:\n        productos = []\n        if os.path.exists(nombre_archivo):\n            with open(nombre_archivo, 'r') as archivo:\n                productos = archivo.readlines()\n            nombre_producto = input(\"Nombre del producto a actualizar: \")\n            for i, producto in enumerate(productos):\n                if producto.startswith(nombre_producto):\n                    cantidad_vendida = input(\"Nueva cantidad vendida: \")\n                    precio = input(\"Nuevo precio: \")\n                    productos[i] = f\"{nombre_producto}, {cantidad_vendida}, {precio}\\n\"\n                    break\n            with open(nombre_archivo, 'w') as archivo:\n                archivo.writelines(productos)\n            print(f\"Producto {nombre_producto} actualizado exitosamente.\")\n        else:\n            print(\"No hay productos registrados.\")\n    except Exception as e:\n        print(f\"Error al actualizar el producto: {e}\")\n\ndef eliminar_producto():\n    try:\n        productos = []\n        if os.path.exists(nombre_archivo):\n            with open(nombre_archivo, 'r') as archivo:\n                productos = archivo.readlines()\n            nombre_producto = input(\"Nombre del producto a eliminar: \")\n            productos = [producto for producto in productos if not producto.startswith(nombre_producto)]\n            with open(nombre_archivo, 'w') as archivo:\n                archivo.writelines(productos)\n            print(f\"Producto {nombre_producto} eliminado exitosamente.\")\n        else:\n            print(\"No hay productos registrados.\")\n    except Exception as e:\n        print(f\"Error al eliminar el producto: {e}\")\n\ndef calcular_venta_total():\n    try:\n        total = 0\n        if os.path.exists(nombre_archivo):\n            with open(nombre_archivo, 'r') as archivo:\n                for linea in archivo:\n                    _, cantidad_vendida, precio = linea.strip().split(', ')\n                    total += int(cantidad_vendida) * float(precio)\n            print(f\"Venta total: {total}\")\n        else:\n            print(\"No hay productos registrados.\")\n    except Exception as e:\n        print(f\"Error al calcular la venta total: {e}\")\n\ndef calcular_venta_por_producto():\n    try:\n        ventas = {}\n        if os.path.exists(nombre_archivo):\n            with open(nombre_archivo, 'r') as archivo:\n                for linea in archivo:\n                    nombre_producto, cantidad_vendida, precio = linea.strip().split(', ')\n                    ventas[nombre_producto] = int(cantidad_vendida) * float(precio)\n            for producto, venta in ventas.items():\n                print(f\"{producto}: {venta}\")\n        else:\n            print(\"No hay productos registrados.\")\n    except Exception as e:\n        print(f\"Error al calcular la venta por producto: {e}\")\n\ndef salir():\n    try:\n        if os.path.exists(nombre_archivo):\n            os.remove(nombre_archivo)\n        print(\"Archivo de ventas eliminado. Saliendo del programa.\")\n    except Exception as e:\n        print(f\"Error al eliminar el archivo: {e}\")\n\ndef menu():\n    while True:\n        print(\"\\nGestión de Ventas\")\n        print(\"1. Añadir producto\")\n        print(\"2. Consultar productos\")\n        print(\"3. Actualizar producto\")\n        print(\"4. Eliminar producto\")\n        print(\"5. Calcular venta total\")\n        print(\"6. Calcular venta por producto\")\n        print(\"7. Salir\")\n        opcion = input(\"Selecciona una opción: \")\n        \n        if opcion == '1':\n            agregar_producto()\n        elif opcion == '2':\n            consultar_productos()\n        elif opcion == '3':\n            actualizar_producto()\n        elif opcion == '4':\n            eliminar_producto()\n        elif opcion == '5':\n            calcular_venta_total()\n        elif opcion == '6':\n            calcular_venta_por_producto()\n        elif opcion == '7':\n            salir()\n            break\n        else:\n            print(\"Opción no válida. Inténtalo de nuevo.\")\n\nmenu()\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/juserdev.py",
    "content": "'''\n/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n * archivo .txt.\n * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n */\n '''\n\nimport os\n\n# txt_file = open(\"./juserdev.txt\", \"w\") # Crea el archivo y lo sobreescribe\n# txt_file.write(\"Nombre: Sebastian\\nEdad: 34\\n\")\n# txt_file = open(\"./juserdev.txt\", \"a\") # De esta manera puedo agregar contenido sin sobreescribir el contenido anterior\n# txt_file.write(\"Lenguaje de programacion favorito: TypeScript\")\n\n# with open(\"./juserdev.txt\", \"r\") as file: # Lee el archivo\n#   contenido = file.read()\n#   print(contenido)\n\n# de esta manera estoy leyendo el contenido del archivo juserdev.txt\n# usando el metodo read() puedo leer el contenido completo del archivo\n\n# with open(\"./juserdev.txt\", \"r+\") as file: # lee y escribe dentro del archivo\n#   contenido = file.read()\n#   print(contenido)\n#   file.write(\"\\nAlias: Juserdev\")\n\n# with open(\"./juserdev.txt\", \"r\") as file:\n#   print(file.read(10)) # lee las 10 primeras posiciones\n#   print(file.readline()) # lee la primera linea\n#   file.close()\n\n# os.remove(\"./juserdev.txt\") # importando el modulo os elimino el archivo conrrespondiente\n\ndef sell():\n  print(\"GESTION DE VENTAS\\n\")\n\n  with open(\"./gestion_de_ventas.txt\", \"w\") as file:\n    file.write(\"### GESTION DE VENTAS ###\\n\\n\")\n    file.write(\"NOMBRE  | CANTIDAD  | PRECIO  | TOTAL\\n\")\n\n  def add_product():\n    product_name = input(\"Cual es el nombre del producto: \")\n    count = input(\"Cual es la cantidad vendida del producto: \")\n    price = input(\"Cual es el precio del producto: \")\n\n    total = int(count) * int(price)\n\n    with open(\"./gestion_de_ventas.txt\", \"a\") as add:\n      add.write(f\"{product_name} | {count} | ${price}  | ${total}\\n\")\n  \n  def read_products():\n    with open(\"./gestion_de_ventas.txt\", \"r\") as reader:\n      print(f\"\\n{reader.read()}\")\n\n  def update_products():\n    with open(\"./gestion_de_ventas.txt\", \"r\") as file:\n      lines = file.readlines()\n      line = input(\"Cual es la linea que quieres modificar: \")\n\n      try:\n        if (int(line) < 4):\n          print(\"\\nlinea invalida, seleccion una linea valida\\n\")\n          return\n        else:\n          product_name = input(\"Cual es el nombre del producto: \")\n          count = input(\"Cual es la cantidad vendida del producto: \")\n          price = input(\"Cual es el precio del producto: \")\n\n          total = int(count) * int(price)\n\n          lines[int(line) -1 ] = f\"{product_name} | {count} | ${price}  | ${total}\\n\"\n\n          with open(\"./gestion_de_ventas.txt\", \"w\") as file:\n            file.writelines(lines)\n          \n      except ValueError as e:\n        print(\"Entrada invalida, asegurate de escribir numeros donde corresponde: \", type(e), e)\n      except IndexError as e:\n        print(\"Numero de linea fuera del rango: \", type(e),e)\n      except Exception as e:\n        print(\"ocurrio un error inesperado: \", type(e),e)\n\n  def delete_product():\n    with open(\"./gestion_de_ventas.txt\", \"r\") as file:\n      lines = file.readlines()\n      line = input(\"Cual es la linea que quieres borrar: \")\n      int_line = int(line) - 1\n      try:\n        if int(line) < 4:\n          print(\"\\nlinea invalida, seleccion una linea valida\\n\")\n          return\n        else:\n          del lines[int_line]\n      \n          with open(\"./gestion_de_ventas.txt\", \"w\") as file:\n            file.writelines(lines)\n\n      except ValueError as e:\n        print(\"Entrada invalida, asegurate de escribir numeros donde corresponde: \", type(e), e)\n      except IndexError as e:\n        print(\"Numero de linea fuera del rango: \", type(e),e)\n      except Exception as e:\n        print(\"ocurrio un error inesperado: \", type(e),e)\n  \n\n  def totalSell():\n    total_general = 0\n\n    with open(\"./gestion_de_ventas.txt\", \"r\") as file:\n      lines = file.readlines()[3:]\n\n      for line in lines:\n        try:\n          parts = line.strip().split(\"|\")\n          total = parts[3].strip().replace(\"$\", \"\")\n          total_general += int(total)\n        except Exception as e:\n          print(\"Ocurrion un error inesperado\", type(e), e)\n    \n    print(f\"\\nEl total en ventas es de -> ${total_general}\")\n\n  def total_per_product():\n    search_product = input(\"Escriba el nombre del producto: \").strip().lower()\n    total_product = 0\n    found = False\n    with open(\"./gestion_de_ventas.txt\", \"r\") as file:\n      lines = file.readlines()[3:]\n\n      for line in lines:\n        parts = line.strip().split(\"|\")\n        name = parts[0].strip().lower()\n        if name == search_product:\n          total = parts[3].strip().replace(\"$\", \"\")\n          total_product += int(total)\n          found = True\n        \n      if found == True:\n        print(f\"\\nVenta total del producto {search_product}: ${total_product}\\n\")\n      else:\n        print(\"\\nProducto no encontrado\\n\")\n\n\n  while True:\n    print(\"1. Añadir producto\")\n    print(\"2. Consultar producto\")\n    print(\"3. Actualizar producto\")\n    print(\"4. Eliminar producto\")\n    print(\"5. Ventas totales\")\n    print(\"6. Ventas totales por producto\")\n    print(\"7. Salir\")\n\n    option = input(\"\\nSeleccione una opcion: \")\n\n    match option:\n      case \"1\":\n        add_product()\n        print(\"\\n -> Producto añadido\\n\")\n      case \"2\":\n        read_products()\n        print(\"\\n -> Producto consultados\\n\")\n      case \"3\":\n        update_products()\n        print(\"\\n -> Producto actualizado\\n\")\n      case \"4\":\n        delete_product()\n        print(\"\\n -> Producto eliminado\\n\")\n      case \"5\":\n        totalSell()\n        print(\"\\n -> Este es el total en ventas\\n\")\n      case \"6\":\n        total_per_product()\n        print(\"\\n -> Este es el total en ventas por producto\\n\")\n      case \"7\":\n        print(\"\\n -> Saliendo del gestor de ventas\\n\")\n        os.remove(\"./gestion_de_ventas.txt\")\n        break\n      case _:\n        print(\"\\n -> Opcion no valida, escribe una opcion valida del 1 al 5.\\n\")\n\n\nsell()\n\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/kenysdev.py",
    "content": "# ╔═════════════════════════════════════╗\n# ║ Autor:  Kenys Alvarado              ║\n# ║ GitHub: https://github.com/Kenysdev ║\n# ║ 2024 -  Python                      ║\n# ╚═════════════════════════════════════╝\n\n# -----------------------------------\n# MANEJO DE FICHEROS \n# -----------------------------------\n# Mas info: https://ellibrodepython.com/ficheros-python\n\nimport os\nclass File(): \n    def __init__(self, path):\n        self._path = path\n\n    def write_line(self, ln):\n        try:\n            # r, w, a, x, b\n            with open(self._path, 'a+') as file:\n                file.write(ln + '\\n')\n        except Exception as ex:\n            print(\"Error -> f.write_line ->\", ex)\n\n    def write_lines(self, lines: list):\n        try:\n            with open(PATH, 'w') as file:\n                file.writelines(lines)\n        except Exception as ex:\n            print(\"Error -> f.write_lines ->\", ex)\n\n    def read_line(self) -> str:\n        try:\n            with open(self._path, 'r') as file:\n                return file.readline()\n        except Exception as ex:\n            print(\"Error -> f.read_line ->\", ex)\n    \n    def read_lines(self) -> list:\n        try:\n            with open(self._path, 'r') as file:\n                return file.readlines()\n        except Exception as ex:\n            print(\"Error -> f.read_line ->\", ex)\n\n    def delete_file(self):\n        try:\n            os.remove(self._path)\n            print(f\"{self._path} -> eliminado.\")\n        except Exception as ex:   \n            print(\"Error -> f.delete ->\", ex)\n\n    def print_all(self):\n        try:\n            with open(self._path, 'r') as file:\n                print(file.read())\n        except Exception as ex:   \n            print(\"Error -> f.print_all ->\", ex)\n\n    def query_file(self, qry) -> int:\n        try:\n            with open(self._path, 'r') as file:\n                for i, line in enumerate(file):\n                    ln = line.split(\",\")[0]\n                    if  ln == f\"[{qry}]\": \n                        print(line)\n                        return i\n                print(\"No existe.\")\n                return None                    \n        except Exception as ex:   \n            print(\"Error ->  f.query_file ->\", ex)\n\n\nuser = File(\"kenysdev.txt\")\nuser.write_line(\"Name: ken\")\nuser.write_line(\"Age: 121\")\nuser.write_line(\"PL: Python\")\nuser.print_all()\nprint(user.read_line())\nuser.delete_file()\n\n# ___________________________________\n'''\n* Desarrolla un programa de gestión de ventas que almacena sus datos en un \n * archivo .txt.\n * - Cada producto se guarda en una línea del arhivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n'''\n\ndef add_product(prod = None, qty = None, price= None) -> str:\n    while True:\n        if not prod or not prod.isalpha():\n            print(\"Debe ingresar un nombre de producto.\")\n            prod = input(\"Producto: \")  \n        elif not qty or not qty.isdigit():\n            print(\"Debe ingresar una cantidad.\")\n            qty = input(\"Cantidad: \")  \n        elif not price or not (price.replace('.', '').isdigit()):\n            print(\"Debe ingresar un precio.\")\n            price = input(\"Precio: \")\n        else:\n            line = f\"[{prod}], [{qty}], [{price}]\"\n            sale.write_line(line)\n            print(\"\\nGuardado\", MSG)\n            return f\"{line}\\n\"\n\ndef query_product(qry = \"\"):\n    if len(qry) == 0: \n        qry = input(\"\\nConsultar Producto.\\nNombre: \")\n    sale.query_file(qry)\n\ndef delete_product(qry = \"\"):\n    if len(qry) == 0: \n        qry = input(\"\\nEliminar Producto.\\nNombre: \")  \n    num_line = sale.query_file(qry)\n    if num_line is not None:\n        lt_products = sale.read_lines()\n        del lt_products[num_line]\n        sale.write_lines(lt_products)\n        print(\"Producto eliminado\") \n\ndef update_product(qry = \"\"):  \n    if len(qry) == 0: \n        qry = input(\"\\nEditar Producto.\\nNombre: \")    \n    num_line = sale.query_file(qry)\n    if num_line is not None:\n        lt_products = sale.read_lines()\n        line = add_product()\n        lt_products[num_line] = line\n        sale.write_lines(lt_products) \n\ndef invoice():\n    print(\"\\nFactura\\n-------------------------\")\n    lt_products = sale.read_lines()\n    monto_total = 0\n    for line in lt_products:\n        a = (line.split(\",\")[1]).strip()\n        qty = int(a.strip('[]'))\n        b = (line.split(\",\")[2]).strip()\n        price = float(b.strip('[]'))\n        ln = line.strip('\\n')\n\n        sub_total = \"${:.2f}\".format(qty * price)\n        print(f\"{ln} -> {sub_total}\")\n        monto_total += (qty * price)\n\n    print(\"\\nMonto Total -> \" + \"${:.2f}\".format(monto_total))\n\nMSG = (\"\"\"\n        Gestión de Ventas:\n╔═════════════════════════════════╗\n║ 1. Agregar        4. Editar     ║  \n║ 2. Consultar      5. Facturar   ║\n║ 3. Eliminar       6. salir.     ║\n╚═════════════════════════════════╝\n\"\"\")\n\nPATH = \"sale_mgt.txt\"\nprint(MSG)\nsale = File(PATH)\n\nwhile True:\n    option = input(\"\\nOpción: \")\n    match option:\n        case \"1\": add_product()\n        case '2': query_product()\n        case '3': delete_product()\n        case '4': update_product()\n        case '5': invoice()\n        case '6': \n            print(\"Adios\")\n            sale.delete_file()\n            break\n        case _: print(\"Opción 1 -> 6\")\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/lesterdavid31.py",
    "content": "import os\n\n# def write_file():\n#     name = 'Lester David'\n#     age = \"25 de edad\"\n#     lenguage = 'python'\n\n#     return f''' Nombre del estudiante: {name} \n#                 Edad: {age}\n#                 lenguaje favorito : {lenguage}'''\n\n# def file(name_file):\n#     file = open(name_file, \"r+\")\n#     #file.write(write_file())\n#     print(file.read())\n#     file.close()\n\n# #file('estudiante.txt')\n\ndef delete_file(name_file):\n    if os.path.exists(name_file):\n        os.remove(name_file) \n    else:\n        print('El archivo no existe')\n\n# delete_file('estudiante.txt')\n\n\n\ndef writeFile(nameFile,product):\n    with open(nameFile,'a') as file:\n        file.write(product)\n\ndef addProduct():\n    name = input('Nombre del producto: ')\n    quantity = int(input('Cantidad vendida: '))\n    price = int(input('Precio del producto: '))\n\n    newProduct = f'Nombre Producto: {name}, Cantidad vendida: {quantity}, Precio Producto: {price} \\n'\n    writeFile('venta.txt',newProduct)\n\n# addProduct()\n\ndef readFile(nameFile):\n    with open(nameFile,'r')as file:\n        print(file.read())\n\n#readFile('venta.txt')\n\ndef update(nameFile,nombre_producto,nuevo_nombre, nueva_cantidad, nuevo_precio):\n    with open(nameFile,'r')as file:\n        lineas = file.readlines()\n        for i, linea in enumerate(lineas):\n            if nombre_producto in linea:\n                partes = linea.split(\", \")\n                partes[0] = f'Nombre: {nuevo_nombre}' \n                partes[1] = f'Cantidad : {nueva_cantidad}'\n                partes[2] = f'Precio: {nuevo_precio}'\n                lineas[i] = \", \".join(partes)\n                break\n    with open(nameFile, 'w') as file:\n        file.writelines(lineas)\n    print(f'producto {nuevo_nombre} actualizado con éxito')\n\n#update('venta.txt')\n\ndef calcularVenta(namefile,productName):\n    \n    with open(namefile, 'r') as file:\n        lineas = file.readlines()\n        \n        for linea in lineas:\n            if productName in linea:\n                partes = linea.split(\", \")\n                \n                # Validamos que las partes tengan el formato correcto\n                if len(partes) == 3:\n                    # Extraer la cantidad\n                    cantidad_str = partes[1].split(\": \")\n                    if len(cantidad_str) == 2:\n                        cantidad = int(cantidad_str[1])  # Convertir a entero\n                    else:\n                        print(\"Formato de cantidad incorrecto en la línea:\", linea)\n                        continue\n                    \n                    # Extraer el precio\n                    precio_str = partes[2].split(\": \")\n                    if len(precio_str) == 2:\n                        precio = float(precio_str[1])  # Convertir a flotante\n                    else:\n                        print(\"Formato de precio incorrecto en la línea:\", linea)\n                        continue\n                    # Calcular el total\n                    resultado = cantidad * precio\n                    return resultado\n    print(f'Producto {productName} no encontrado.')\n\ndef NameProduct(fileName):\n    list_name_products = []\n    with open(fileName, 'r') as file:\n        lineas = file.readlines()\n        \n        for linea in lineas:\n            partes = linea.split(\", \")\n            if len(partes) == 3:\n                productName = partes[0].split(\": \")\n                if len(productName) == 2:\n                    nombres = productName[1]\n                    list_name_products.append(nombres)\n    return list_name_products\n\n\nwhile True:\n    print('\\n')\n    print('1. Añadir producto')\n    print('2. Consultar producto')\n    print('3. Actualizar producto')\n    print('4. calcular venta total por poroducto')\n    print('5. calcular venta total')\n    print('6. Salir')\n    print('\\n')\n\n    try:\n        option = int(input('Ingrese la opción: '))\n        print('\\n')\n\n        if option == 1:\n            addProduct()\n            print('¿Producto agregado exitosamente!')\n        elif option == 2:\n            readFile('venta.txt')\n        elif option == 3:\n            \n            name = input('Nombre del producto a actualizar: ')\n            newName = input('Nombre: ')\n            newQuantity = input('Cantidad: ')\n            newPrice = input('Precio: ')\n            update('venta.txt',name,newName,newQuantity,newPrice)\n\n        elif option == 4:\n            productName = input('Ingrese el nombre del producto a calcular: ')\n            result = calcularVenta('venta.txt',productName)\n            print(f'El total de ventas del producto {productName} es: {result}')\n\n        elif option == 5:\n            nombres = NameProduct(\"venta.txt\")\n            resultado = 0\n            for nombre in nombres:\n                venta_producto = calcularVenta(\"venta.txt\",nombre)\n                resultado += venta_producto \n            print(f'El monto total de los productos vendidos es de: {resultado}')\n\n        elif option == 6:\n            delete_file('venta.txt')\n        else:\n            print('Solo puedes seleccionar las opciones del 1 al 7 por foavor ingrese nuevamente: ')\n    except ValueError as e:\n        print('Ingrese solamente los numeros del 1 - 6')\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/m1l0j05.py",
    "content": "## Ejercicio\n\nimport os\n\ndef ejercicio():\n    texts = ['Mi nombre\\n', 'Mi edad\\n', 'Python\\n']\n    \n    with open('m1l0j05.txt', 'w') as file:\n        file.write('Mi nombre\\n')\n        file.write('Mi edad\\n')\n        file.write('Python\\n')\n        file.write('+++++\\n')\n        file.writelines(texts)\n\n    with open('m1l0j05.txt', 'r') as file:\n        print(file.read())\n\n    os.remove('m1l0j05.txt')\n\n#ejercicio()\n\n# Extra\n\ndef guardar_producto(nombre_archivo, producto):\n    with open(nombre_archivo, 'a') as archivo:\n        archivo.write(producto + '\\n')\n\ndef mostrar_productos(nombre_archivo):\n    with open(nombre_archivo, 'r') as archivo:\n        print('Productos:')\n        print(archivo.read())\n\ndef actualizar_producto(nombre_archivo, indice, nuevo_producto):\n    with open(nombre_archivo, 'r+') as archivo:\n        lineas = archivo.readlines()\n        if indice >= len(lineas):\n            print('Índice fuera de rango.')\n            return\n        lineas[indice] = nuevo_producto + '\\n'\n        archivo.seek(0)\n        archivo.writelines(lineas)\n        archivo.truncate()\n\ndef eliminar_producto(nombre_archivo, indice):\n    with open(nombre_archivo, 'r+') as archivo:\n        lineas = archivo.readlines()\n        if indice >= len(lineas):\n            print('Índice fuera de rango.')\n            return\n        lineas.pop(indice)\n        archivo.seek(0)\n        archivo.writelines(lineas)\n        archivo.truncate()\n\ndef calcular_venta_total(nombre_archivo):\n    venta_total = 0\n    with open(nombre_archivo, 'r') as archivo:\n        for linea in archivo:\n            _, cantidad, precio = linea.strip().split(',')\n            venta_total += int(cantidad) * float(precio)\n    return venta_total\n\ndef calcular_venta_producto(nombre_archivo, producto_buscado):\n    venta_producto = 0\n    with open(nombre_archivo, 'r') as archivo:\n        for linea in archivo:\n            nombre, cantidad, precio = linea.strip().split(',')\n            if nombre == producto_buscado:\n                venta_producto += int(cantidad) * float(precio)\n    return venta_producto\n\ndef ejercicio_extra():\n    nombre_archivo = 'ventas.txt'\n\n    while True:\n        print('\\n1. Añadir producto')\n        print('2. Consultar productos')\n        print('3. Actualizar producto')\n        print('4. Eliminar producto')\n        print('5. Calcular venta total')\n        print('6. Calcular venta por producto')\n        print('7. Salir')\n        opcion = input('Ingrese el número de la opción deseada: ')\n\n        if opcion == '1':\n            producto = input('Ingrese el producto en el formato [nombre_producto], [cantidad_vendida], [precio]: ')\n            guardar_producto(nombre_archivo, producto)\n        elif opcion == '2':\n            mostrar_productos(nombre_archivo)\n        elif opcion == '3':\n            indice = int(input('Ingrese el índice del producto a actualizar: '))\n            nuevo_producto = input('Ingrese el nuevo producto en el formato [nombre_producto], [cantidad_vendida], [precio]: ')\n            actualizar_producto(nombre_archivo, indice, nuevo_producto)\n        elif opcion == '4':\n            indice = int(input('Ingrese el índice del producto a eliminar: '))\n            eliminar_producto(nombre_archivo, indice)\n        elif opcion == '5':\n            venta_total = calcular_venta_total(nombre_archivo)\n            print(f'Venta total: {venta_total}')\n        elif opcion == '6':\n            producto_buscado = input('Ingrese el nombre del producto: ')\n            venta_producto = calcular_venta_producto(nombre_archivo, producto_buscado)\n            print(f'Venta del producto {producto_buscado}: {venta_producto}')\n        elif opcion == '7':\n            import os\n            os.remove(nombre_archivo)\n            print('Archivo borrado. Saliendo...')\n            break\n        else:\n            print('Opción no válida. Por favor, ingrese un número válido.')\n\n\nejercicio_extra()\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/mariovelascodev.py",
    "content": "#Importamos el modulo os para trabajar con el sistema\nimport os\n\n#Función que crea un fichero con la extensión .txt\ndef create_file():\n    #Abrimos el fichero, y le indicamos el nombre con el que se guardara\n    file = open(\"mariovelascodev.txt\", \"w\")\n    \n    #Solicitamos que el usuario nos introduca su nombre, edad, y lenguaje de programación favorito\n    add_data = []\n    name = input(\"Introduce tu nombre: \")\n    age = input(\"Introduce tu edad: \")\n\n    #Añadimos lo datos introducidos por el usuario a una lista\n    add_data.append(name)\n    add_data.append(age)\n    \n    #Solicitamos tantos lenguajes de programción como quiera añadir el usuario\n    while True:\n        favorite_language = input(\"Introduce tu lenguaje de programación favorito(escribe \\\"q\\\" para salir): \")\n        if favorite_language == \"q\":\n            break\n        else:\n            add_data.append(favorite_language)\n    \n    #Recorremos la lista y escribimos los valores en lineas distintas del fichero\n    for line in add_data:\n        file.write(f\"{line.title()}\\n\")\n\n    #Cerramos el fichero\n    file.close()\n\n#Función que lee un fihero\ndef read_file():\n    #Abrimos el fichero y lo leemos\n    file = open(\"mariovelascodev.txt\", \"r\")\n\n    print(\"\\nEl contenido del fichero es:\")\n    print(file.read())\n\n    #Cerramos el fichero\n    file.close() \n\n#Función que elimina un fichero\ndef remove_file():\n    #Nombre del fichero a eliminar\n    file = \"mariovelascodev.txt\"\n\n    #Borrado del fichero indicado\n    os.remove(file)\n\n\ncreate_file()\nread_file()\nremove_file()"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/mhayhem.py",
    "content": "# @Author Mhayhem\n\n# IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n\n# EJERCICIO:\n# Desarrolla un programa capaz de crear un archivo que se llame como\n# tu usuario de GitHub y tenga la extensión .txt.\n# Añade varias líneas en ese fichero:\n# - Tu nombre.\n# - Edad.\n# - Lenguaje de programación favorito.\n# Imprime el contenido.\n# Borra el fichero.\nimport os\n\nwith open(\"mayhem.txt\", \"w+\") as f:\n    f.write(\"Nombre: Daniel\\nEdad: 42\\nLenguaje favorito: Python\")\n\nwith open(\"mayhem.txt\", \"r\") as f:\n    read = f.read()\nprint(read)\n\ntry:\n    os.remove(\"mayhem.txt\")\nexcept FileNotFoundError as e:\n    print(f\"{e}\")\n\n# DIFICULTAD EXTRA (opcional):\n# Desarrolla un programa de gestión de ventas que almacena sus datos en un \n# archivo .txt.\n# - Cada producto se guarda en una línea del archivo de la siguiente manera:\n#   [nombre_producto], [cantidad_vendida], [precio].\n# - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n#   actualizar, eliminar productos y salir.\n# - También debe poseer opciones para calcular la venta total y por producto.\n# - La opción salir borra el .txt\n\ndef eshop(archive: str):\n    \n    while True:\n        print(\"Añadir producto.           [1]\\n\"\n              \"Consultar albarán.         [2]\\n\"\n              \"Actualizar albarán.        [3]\\n\"\n              \"Eliminar producto.         [4]\\n\"\n              \"Precio total pedido.       [5]\\n\"\n              \"Precio total por producto. [6]\\n\"\n              \"Salir                      [7]\")\n        option = input()\n        match option:\n            case \"1\":\n                add_product(archive)\n            case \"2\":\n                consult_delivery_note(archive)                   \n            case \"3\":\n                update_sales_order(archive)\n            case \"4\":\n                remove_product(archive)\n            case \"5\":\n                display_total_amount(archive)\n            case \"6\":\n                display_total_for_product(archive)\n            case \"7\":\n                    os.remove(archive )\n                    break\n            case _:\n                print(\"Opción inválida.\")\n                \ndef add_product(archive):\n    with open(archive , \"a\") as f:\n        product = input(\"Producto ha añadir: \\n\").capitalize()\n        quantity = int(input(\"Cantidad pedida: \\n\"))\n        price = float(input(\"Precio del producto: \\n\"))\n        f.write(f\"{product}, {quantity}, {price}\\n\")\n                    \ndef consult_delivery_note(archive):\n    try:\n        with open(archive , \"r\") as f:\n            consult = f.read()\n            print(consult)\n    except FileNotFoundError as e:\n         print(f\"{e}\")\n\ndef update_sales_order(archive):\n    update_lines = []\n    product_found = False\n    \n    try:\n        product = input(\"¿Que producto quiere modificar?\").capitalize()\n        with open(archive , \"r\") as f:\n            lines = f.readlines()\n            for line in lines:\n                line = line.strip().split(\", \")\n                if line[0] == product:\n                    product_found = True\n                    new_product, quantity, price = line[0], line[1], line[2]\n                    modify = input(\"¿Qué quiere modificar? Producto, cantidad o precio.\").strip().lower()\n                    match modify:\n                        case \"producto\":\n                            new_product = input(\"Producto: \").capitalize()\n                        case \"cantidad\":\n                            quantity = int(input(\"Cantidad: \"))\n                        case \"precio\":\n                            price = float(input(\"Precio: \"))\n                        case _:\n                            print(\"Opción inválida\" )\n                    line = f\"{new_product}, {quantity}, {price}\"\n                    update_lines.append(line)\n                else:\n                    update_lines.append(\", \".join(line))\n                    \n    except FileNotFoundError as e:\n        print(f\"{e}\")\n        return\n    \n    if not product_found:\n        print(\"Producto no encontrado.\")\n        return\n    \n    with open(archive , \"w+\") as f:\n        for line in update_lines:\n            f.write(line.strip() + \"\\n\")\n                \n    modify_again = input(\"¿Quiere actualizar algún producto más? si[1], no [2].\\n\").lower()\n    match modify_again:\n        case \"1\":\n            update_sales_order(archive)\n        case \"2\":\n            print(\"Albarán actualizado.\")\n        case _:\n            print(\"Opción no disponible, actualizaremos albarán igualmente\")\n            \ndef remove_product(archive):\n    deleted_product = input(\"¿Qué producto quiere eliminar?\\n\").capitalize()\n    saved_lines = []\n    product_found = False\n    \n    try:\n        with open(archive, \"r\") as f:\n            lines = f.readlines()\n            for line in lines:\n                line_parts = line.strip().split(\", \")\n                if line_parts[0] == deleted_product:\n                    product_found = True\n                    print(f\"La linea [{', '.join(line_parts)}], se elimino con éxito.\")\n                else:\n                    saved_lines.append(\", \".join(line_parts))\n                    \n    except FileNotFoundError as e:\n        print(f\"{e}\")\n        return\n    \n    if not product_found:\n        print(\"Producto no encontrado.\")\n        return\n    \n    with open(archive, \"w+\") as f:\n        for line in saved_lines:\n            f.write(line + \"\\n\")\n            \ndef display_total_amount(archive):\n    total = 0\n    try:\n        with open(archive, \"r\") as f:\n            for line in f:\n                line = line.strip().split(\", \")\n                quantity, price = int(line[1]) , float(line[2])\n                total += quantity * price\n            if total != 0:    \n                print(f\"El total del albarán es {total:.2f} €.\")\n            else:\n                print(\"El albarán esta vacío.\")\n                \n    except FileNotFoundError as e:\n        print(f\"{e}\")\n    \ndef display_total_for_product(archive):\n    product_total_price = []\n    try:\n        with open(archive) as f:\n            for line in f:\n                line = line.strip().split(\", \")\n                product, quantity, price = line[0], int(line[1]), float(line[2])\n                product_total_price.append(f\"Producto: {product}, total: {quantity * price:.2f} €\")\n            \n            if product_total_price:\n                for item in product_total_price:\n                    print(item)\n            else:\n                print(\"El albarán esta vacío.\")\n                \n    except FileNotFoundError as e:\n        print(f\"{e}\")\n        \nif __name__ == \"__main__\":\n    eshop(\"albaran.txt\")"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/miguelex.py",
    "content": "import os \n\ndef create_file(file_name: str) -> None:\n    with open(file_name, \"w\") as file:\n        print(f\"Fichero {file_name} creado\")\n\ndef add_data(file_name: str, name: str, age: str, language: str) -> None:\n    with open(file_name, \"a\") as file:\n        file.write(f\"{name}, {age}, {language}\\n\")\n        print(f\"Datos guardados en el fichero {file_name}\") \n         \n        \ndef read_data(file_name: str) -> None:\n    with open(file_name, \"r\") as file:\n        for line in file.readlines():\n            print(line)  \n            \ndef erase_file (file_name: str) -> None:\n    os.remove(file_name)\n    print(f\"Fichero {file_name} eliminado\")\n    \ncreate_file(\"miguelex.txt\")\nadd_data(\"miguelex.txt\", \"Miguelex\", \"48\", \"Python\")\nread_data(\"miguelex.txt\")\nerase_file(\"miguelex.txt\")\n\n\n# Extra \n\nfile_name = \"ventas.txt\"\n\nopen(file_name, \"a\")\n\nwhile True: \n    print(\"Menu\")\n    print(\"1. Añadir venta\")\n    print(\"2. Consultar ventas de un producto\")\n    print(\"3. Consultar ventas totales\")\n    print(\"4. Eliminar producto\")\n    print(\"5. Calcular ventas totales\")\n    print(\"6. Calcular ventas de un producto\")\n    print(\"7. Salir\")\n    \n    option = input(\"Selecciona una opción: \")\n    \n    match option:\n        case \"1\":\n            product = input(\"Nombre del producto: \")\n            units = input(\"Unidades vendidas: \")\n            price = input(\"Precio unitario: \")\n            \n            with open(file_name, \"a\") as file:\n                file.write(f\"{product}, {units}, {price}\\n\")\n        case \"2\":\n            product = input(\"Nombre del producto: \")\n            with open(file_name, \"r\") as file:\n                for line in file.readlines():\n                    if line.split(\", \")[0] == product:\n                        print(line)\n        case \"3\":\n            with open(file_name, \"r\") as file:\n                for line in file.readlines():\n                    print(line)\n        case \"4\":\n            product = input(\"Nombre del producto: \")\n            with open(file_name, \"r\") as file:\n                lines = file.readlines()\n            with open(file_name, \"w\") as file:\n                for line in lines:\n                    if line.split(\", \")[0] != product:\n                        file.write(line)\n        case \"5\":\n            with open(file_name, \"r\") as file:\n                total = 0\n                for line in file.readlines():\n                    total += int(line.split(\", \")[1]) * float(line.split(\", \")[2])\n                print(f\"El total de ventas es {total}\")\n        case \"6\":\n            product = input(\"Nombre del producto: \")\n            with open(file_name, \"r\") as file:\n                total = 0\n                for line in file.readlines():\n                    if line.split(\", \")[0] == product:\n                        total += int(line.split(\", \")[1]) * float(line.split(\", \")[2])\n                print(f\"El total de ventas de {product} es {total}\")\n        case \"7\":\n            os.remove(file_name) \n            break\n            \n    \n    "
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/mikelm2020.py",
    "content": "import os\n\n\ndef user_file(data: list):\n    file_name = f\"{data[0]}.txt\"\n\n    with open(file_name, \"w\") as file:\n        file.write(f\"{data[1]}\\n\")\n        file.write(f\"{data[2]}\\n\")\n        file.write(f\"{data[3]}\\n\")\n\n    with open(file_name, \"r\") as file:\n        print(file.read())\n\n    os.remove(file_name)\n\n\ndef sales_manager(file_manager: str):\n    file_name = f\"{file_manager}.txt\"\n    while True:\n        print(\"1. Agregar producto\")\n        print(\"2. Actualizar producto\")\n        print(\"3. Eliminar producto\")\n        print(\"4. Mostrar productos\")\n        print(\"5. Calcular venta total\")\n        print(\"6. Calcular venta por producto\")\n        print(\"7. Salir\")\n\n        option = input(\"Selecciona la opción deseada: \")\n\n        if option == \"1\":\n            product_name, quantity, price = input(\"Producto,cantidad,precio: \").split(\n                \",\"\n            )\n            with open(file_name, \"a\") as file:\n                file.write(f\"{product_name}, {quantity}, {price}\\n\")\n        elif option == \"2\":\n            product_name, quantity, price = input(\"Producto,cantidad,precio: \").split(\n                \",\"\n            )\n            with open(file_name, \"r\") as file:\n                lines = file.readlines()\n            with open(file_name, \"w\") as file:\n                for line in lines:\n                    if line.split(\", \")[0] == product_name:\n                        file.write(f\"{product_name}, {quantity}, {price}\\n\")\n                    else:\n                        file.write(line)\n        elif option == \"3\":\n            product_name = input(\"Producto: \")\n            with open(file_name, \"r\") as file:\n                lines = file.readlines()\n            with open(file_name, \"w\") as file:\n                for line in lines:\n                    if line.split(\", \")[0] != product_name:\n                        file.write(line)\n        elif option == \"4\":\n            with open(file_name, \"r\") as file:\n                print(file.read())\n        elif option == \"5\":\n            total = 0\n            with open(file_name, \"r\") as file:\n                for line in file.readlines():\n                    items = line.split(\", \")\n                    quantity = int(items[1])\n                    price = float(items[2])\n                    total += quantity * price\n            print(total)\n        elif option == \"6\":\n            product_name = input(\"Producto: \")\n            total = 0\n            with open(file_name, \"r\") as file:\n                for line in file.readlines():\n                    items = line.split(\", \")\n                    if items[0] == product_name:\n                        quantity = int(items[1])\n                        price = float(items[2])\n                        total += quantity * price\n                        break\n            print(total)\n        elif option == \"7\":\n            os.remove(file_name)\n            break\n        else:\n            print(\"Selecciona una de las opciones disponibles.\")\n\n\nif __name__ == \"__main__\":\n    user_file([\"mikelm2020\", \"Miguel Angel Lopez\", \"52\", \"Python\"])\n    sales_manager(\"ventas\")\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/monicavaquerano.py",
    "content": "# 11 MANEJO DE FICHEROS\n# Monica Vaquerano\n# https://monicavaquerano.dev\n\n# IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n\"\"\"\nEJERCICIO:\nDesarrolla un programa capaz de crear un archivo que se llame como\ntu usuario de GitHub y tenga la extensión .txt.\nAñade varias líneas en ese fichero:\n- Tu nombre.\n- Edad.\n- Lenguaje de programación favorito.\nImprime el contenido.\nBorra el fichero.\n\"\"\"\nimport os\n\n\ndef crear_archivo(nombre, edad, lenguaje):\n    try:\n        with open(\"monicavaquerano.txt\", \"a+\") as f:\n            texto = f\"{nombre}, {edad}, {lenguaje}\\n\"\n            f.write(texto)\n    except FileNotFoundError as e:\n        print(f\"Error al abrir el archivo: {e}\")\n    except Exception as e:\n        print(f\"Error al guardar la venta: {e}\")\n\n\ndef leer_archivo():\n    try:\n        with open(\"monicavaquerano.txt\") as f:\n            for line in f:\n                nombre, edad, lenguaje = line.strip().split(\", \")\n                print(f\"{nombre:<15}|{edad:^10}| {lenguaje:>10}\")\n    except FileNotFoundError as e:\n        print(f\"Error al abrir el archivo: {e}\")\n    except Exception as e:\n        print(f\"Error al guardar la venta: {e}\")\n\n\ndef eliminar_archivo():\n    try:\n        if os.path.exists(\"monicavaquerano.txt\"):\n            os.remove(\"monicavaquerano.txt\")\n            print(\"Eliminado con éxito\")\n        else:\n            print(\"Este archivo no existe\")\n    except Exception as e:\n        print(f\"Error al eliminar el archivo: {e}\")\n\n\nwhile True:\n    print(\"--- Mi archivo ---\")\n    choice = input(\n        \"¿Qué deseas hacer?:\\n1. Crear o añadir al archivo\\n2. Leer el archivo\\n3. Eliminar el archivo\\n4. Salir a DIFICULTAD EXTRA (opcional)\\n> \"\n    ).strip()\n    if choice == \"1\":\n        os.system(\"clear\")\n        print(\"--- Crear o añadir ---\")\n        nombre = input(\"¿Cuál es tu nombre? > \").strip().lower()\n        edad = input(\"¿Cuál es tu edad? > \").strip().lower()\n        lenguaje = (\n            input(\"¿Cuál es tu lenguaje de pregramación favorito? > \").strip().lower()\n        )\n        crear_archivo(nombre, edad, lenguaje)\n        print()\n    elif choice == \"2\":\n        os.system(\"clear\")\n        print(\"--- Mi archivo ---\")\n        leer_archivo()\n        print()\n    elif choice == \"3\":\n        os.system(\"clear\")\n        print(\"--- Eliminar ---\")\n        eliminar_archivo()\n        print()\n    elif choice == \"4\":\n        print(\"Ciao!\")\n        break\n\nos.system(\"clear\")\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\nDesarrolla un programa de gestión de ventas que almacena sus datos en un \narchivo .txt.\n- Cada producto se guarda en una línea del arhivo de la siguiente manera:\n  [nombre_producto], [cantidad_vendida], [precio].\n- Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n  actualizar, eliminar productos y salir.\n- También debe poseer opciones para calcular la venta total y por producto.\n- La opción salir borra el .txt.\n\"\"\"\n\nimport os\n\n\ndef guardar_venta(nombre_producto, cantidad_vendida, precio):\n    try:\n        with open(\"ventas.txt\", \"a\") as f:\n            venta = f\"{nombre_producto}, {cantidad_vendida}, {precio}\\n\"\n            f.write(venta)\n    except FileNotFoundError as e:\n        print(f\"Error al abrir el archivo: {e}\")\n    except Exception as e:\n        print(f\"Error al guardar la venta: {e}\")\n\n\ndef leer_ventas():\n    try:\n        with open(\"ventas.txt\") as f:\n            for line in f:\n                nombre_producto, cantidad_vendida, precio = line.strip().split(\", \")\n                print(f\"{nombre_producto:<15}|{cantidad_vendida:^10}| ${precio:>10}\")\n    except FileNotFoundError as e:\n        print(f\"Error al abrir el archivo: {e}\")\n    except Exception as e:\n        print(f\"Error al leer las ventas: {e}\")\n\n\ndef eliminar_ventas():\n    try:\n        if os.path.exists(\"ventas.txt\"):\n            os.remove(\"ventas.txt\")\n            print(\"Archivo 'ventas.txt' eliminado con éxito\")\n        else:\n            print(\"Archivo 'ventas.txt' no existe\")\n    except Exception as e:\n        print(f\"Error al eliminar el archivo: {e}\")\n\n\ndef calcular_ventas(producto=None):\n    ventas = []\n    total = 0\n    cantidad = 0\n    try:\n        with open(\"ventas.txt\", \"r\") as f:\n            for line in f:\n                nombre_producto, cantidad_vendida, precio = line.strip().split(\", \")\n                ventas.append([nombre_producto, int(cantidad_vendida), float(precio)])\n    except FileNotFoundError as e:\n        print(f\"Error al abrir el archivo: {e}\")\n        return\n    except Exception as e:\n        print(f\"Error al procesar las ventas: {e}\")\n        return\n\n    if producto:\n        for item in ventas:\n            if producto == item[0]:\n                total += item[1] * item[2]\n                cantidad += item[1]\n        print(f\"Total de ventas de {producto}: $ {total:,.2f} ({cantidad} unidades)\")\n    else:\n        for item in ventas:\n            total += item[1] * item[2]\n        print(f\"Ventas totales: $ {total:,.2f}\")\n\n\ndef actualizar_ventas(producto):\n    ventas_actualizadas = []\n    try:\n        with open(\"ventas.txt\", \"r\") as f:\n            for line in f:\n                nombre_producto, cantidad_vendida, precio = line.strip().split(\", \")\n                if producto == nombre_producto:\n                    nombre_producto = input(\"Nuevo nombre? > \")\n                    cantidad_vendida = int(input(\"Nueva cantidad? > \"))\n                    precio = float(input(\"Nuevo precio? > \"))\n                ventas_actualizadas.append([nombre_producto, cantidad_vendida, precio])\n\n        with open(\"ventas.txt\", \"w\") as f:\n            for item in ventas_actualizadas:\n                f.write(f\"{item[0]}, {item[1]}, {item[2]}\\n\")\n    except FileNotFoundError as e:\n        print(f\"Error al abrir el archivo: {e}\")\n    except Exception as e:\n        print(f\"Error al actualizar las ventas: {e}\")\n\n\nwhile True:\n    print(\"--- Mis Ventas ---\")\n    choice = input(\n        \"¿Qué deseas hacer?:\\n1. Crear o añadir ventas\\n2. Ver ventas\\n3. Calcular ventas\\n4. Actualizar ventas\\n5. Salir\\n> \"\n    ).strip()\n    if choice == \"1\":\n        os.system(\"clear\")\n        print(\"--- Crear o añadir ---\")\n        nombre_producto = input(\"¿Cuál es el nombre del producto? > \").strip().lower()\n        cantidad_vendida = int(input(\"¿Cuál es la cantidad vendida? > \"))\n        precio = float(input(\"¿Cuál es el precio? > \"))\n        guardar_venta(nombre_producto, cantidad_vendida, precio)\n        print()\n    elif choice == \"2\":\n        os.system(\"clear\")\n        print(\"--- Mis ventas ---\")\n        leer_ventas()\n        print()\n    elif choice == \"3\":\n        os.system(\"clear\")\n        print(\"--- Calcular ---\")\n        producto = (\n            input(\n                \"Calcular por:\\n* Producto (ingresa nombre de producto y luego presiona enter)\\n* Total (solo presiona enter)\\n> \"\n            )\n            .strip()\n            .lower()\n        )\n        calcular_ventas(producto)\n        print()\n    elif choice == \"4\":\n        os.system(\"clear\")\n        print(\"--- Actualizar ---\")\n        producto = input(\"Qué producto actualizar?:\\n> \").strip().lower()\n        actualizar_ventas(producto)\n        print()\n    elif choice == \"5\":\n        eliminar_ventas()\n        print(\"Ciao!\")\n        break\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/mouredev.py",
    "content": "import os\n\n\"\"\"\nEjercicio\n\"\"\"\n\nfile_name = \"mouredev.txt\"\n\nwith open(file_name, \"w\") as file:\n    file.write(\"Brais Moure\\n\")\n    file.write(\"36\\n\")\n    file.write(\"Python\")\n\nwith open(file_name, \"r\") as file:\n    print(file.read())\n\nos.remove(file_name)\n\n\"\"\"\nExtra\n\"\"\"\n\nfile_name = \"mouredev_shop.txt\"\n\nopen(file_name, \"a\")\n\nwhile True:\n    print(\"1. Añadir producto\")\n    print(\"2. Consultar producto\")\n    print(\"3. Actualizar producto\")\n    print(\"4. Borrar producto\")\n    print(\"5. Mostrar productos\")\n    print(\"6. Calcular venta total\")\n    print(\"7. Calcular venta por producto\")\n    print(\"8. Salir\")\n\n    option = input(\"Selecciona una opción: \")\n\n    if option == \"1\":\n        name = input(\"Nombre: \")\n        quantity = input(\"Cantidad: \")\n        price = input(\"Precio: \")\n        with open(file_name, \"a\") as file:\n            file.write(f\"{name}, {quantity}, {price}\\n\")\n    elif option == \"2\":\n        name = input(\"Nombre: \")\n        with open(file_name, \"r\") as file:\n            for line in file.readlines():\n                if line.split(\", \")[0] == name:\n                    print(line)\n                    break\n    elif option == \"3\":\n        name = input(\"Nombre: \")\n        quantity = input(\"Cantidad: \")\n        price = input(\"Precio: \")\n        with open(file_name, \"r\") as file:\n            lines = file.readlines()\n        with open(file_name, \"w\") as file:\n            for line in lines:\n                if line.split(\", \")[0] == name:\n                    file.write(f\"{name}, {quantity}, {price}\\n\")\n                else:\n                    file.write(line)\n    elif option == \"4\":\n        name = input(\"Nombre: \")\n        with open(file_name, \"r\") as file:\n            lines = file.readlines()\n        with open(file_name, \"w\") as file:\n            for line in lines:\n                if line.split(\", \")[0] != name:\n                    file.write(line)\n    elif option == \"5\":\n        with open(file_name, \"r\") as file:\n            print(file.read())\n    elif option == \"6\":\n        total = 0\n        with open(file_name, \"r\") as file:\n            for line in file.readlines():\n                components = line.split(\", \")\n                quantity = int(components[1])\n                price = float(components[2])\n                total += quantity * price\n        print(total)\n    elif option == \"7\":\n        name = input(\"Nombre: \")\n        total = 0\n        with open(file_name, \"r\") as file:\n            for line in file.readlines():\n                components = line.split(\", \")\n                if components[0] == name:\n                    quantity = int(components[1])\n                    price = float(components[2])\n                    total += quantity * price\n                    break\n        print(total)\n    elif option == \"8\":\n        os.remove(file_name)\n        break\n    else:\n        print(\"Selecciona una de las opciones disponibles.\")\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/mrodara.py",
    "content": "import os\n\n############################ MANEJO DE FICHEROS EN PYTHON ######################################\n'''\n1. Apertura de ficheros con open()\nEn Python, el método principal para manejar ficheros es open(). \nLa función open() permite abrir un fichero y especificar el modo en el que se va a abrir (lectura, escritura, etc.).\n'''\n\n# Ejemplo de apertura de un fichero en modo lectura\n#try:\n#    my_file = open(\"test.txt\", \"r\")\n#\n#except FileNotFoundError:\n#    print(\"El fichero no exite y este modo no permite crearlo\")\n#finally:\n#    print(\"Creando el fichero...\")\n#    my_file = open(\"test.txt\", \"a\")\n#    print(\"Fichero creado...\")\n\n'''\nModos principales:\n'r' - Leer (por defecto). Da error si el fichero no existe.\n'w' - Escribir. Crea un fichero nuevo o sobreescribe si existe.\n'a' - Añadir. Escribe al final del fichero si existe, o lo crea.\n'r+' - Leer y escribir.\n'''\n\n\n\n'''\n2. Escritura de ficheros con write()\nPara escribir en un fichero, se utiliza el método write().\nPara escribir en un fichero, se usa el modo 'w' o 'a'. \nEl modo 'w' sobreescribirá el contenido, mientras que 'a' añadirá al final.\n'''\n\n# Ejemplo sobreescribir un fichero\n#with open(\"text.txt\", \"w\") as fichero:\n#    fichero.write(\"Hola, mundo!\")\n#    \n## Ejemplo añadiendo contenido nuevo al fichero\n#with open(\"test.txt\", \"a\") as fichero:\n#    fichero.write(\"Esta frase se añade al final del documento \\n\")\n\n'''\n3. Lectura de ficheros con read()\nPython ofrece varios métodos para leer el contenido de un fichero:\n\nread(): Lee todo el contenido del fichero como una cadena.\nreadline(): Lee una sola línea del fichero.\nreadlines(): Lee todas las líneas y devuelve una lista.\n'''\n\n'''\nEl bloque with es la forma recomendada de abrir ficheros en Python, \nya que asegura que el fichero se cierre automáticamente al terminar el bloque.\n'''\n\n# Ejemplo de lectura de un fichero\n#with open(\"test.txt\", \"r\") as file:\n#    content = file.read()\n#    print(content)# Imprime el contenido del fichero\n#\n## Ejemplo de lectura de un fichero línea a línea\n#with open(\"test.txt\", \"r\") as file:\n#    for line in file.readlines():\n#        print(line)# Imprime cdada línea del fichero\n\n\n'''\n4. Borrado y manipulación de archivos con os\nEl módulo 'os' permite realizar operaciones con ficheros como borrar, renombrar o mover.\n'''\n# Renombrar un fichero\n#os.rename(\"test.txt\", \"new_name.txt\")\n\n# Borrar un fichero\n#try:\n#    os.remove(\"test.txt\")\n#except FileNotFoundError:\n#    print(\"El fichero no existe, luego no se puede borrar\")\n    \n\n# EJERCICIO PROPUESTO DEL RETO\n\ntry:\n    os.remove(\"mrodara.txt\")\nexcept FileNotFoundError:\n    pass\n\nwith open(\"mrodara.txt\", \"w\") as file:\n    file.write('Name: Manu \\n')\n    file.write('Age: 44 \\n')\n    file.write('Favourite Programming Language: Python \\n')\n\nprint(\"Lectura del fichero\")\nwith open(\"mrodara.txt\", \"r\") as file:    \n    for line in file.readlines():\n        print(line)\nprint('Fin de fichero')\n    \ntry:\n    os.remove('mrodara.txt')\nexcept FileNotFoundError:\n    print(\"El fichero no existe, luego no se puede borrar\")\nfinally:\n    print(\"El fichero ha sido borrado\")\n\n############################ FIN MANEJO DE FICHEROS EN PYTHON ######################################\n\n############################ EXTRA ######################################\n# Gestión de Ventas\n\ndef show_menu() -> None:\n    print(\"1. Mostrar productos\")\n    print(\"2. Agregar producto\")\n    print(\"3. Eliminar producto\")\n    print(\"4. Buscar producto\")\n    print(\"5. Actualizar producto\")\n    print(\"6. Mostrar venta total por producto\")\n    print(\"7. Mostrar venta total\")\n    print(\"8. Salir\")\n    \ndef get_sales(file: str) -> list:\n    try:\n        with open(file, \"r\") as file:\n            sales = file.readlines()\n        return sales\n    except FileNotFoundError:\n        print(\"Aún no ha registrada ninguna venta...\")\n        return []\n\ndef insert_sale(file: str, name: str, qty: int, price: float) -> None:\n    with open(file, \"a\") as file:\n        file.write(f\"{name}, {qty}, {price}.\\n\")\n    \n    print('Venta registrada correctamente...')\n\ndef delete_sale(file: str, product_name: str) -> None:\n    \n    updated_lines = []\n    \n    lines = get_sales(file)\n        \n    for line in lines:\n        if product_name.lower() not in line.lower():\n            updated_lines.append(line)\n    \n    with open(file, \"w\") as file:\n        file.writelines(updated_lines)\n    \n    print(f\"Linea del producto {product_name} eliminada\")\n\ndef update_sale(file: str, search: str, name: str =\"\", qty: int = 0, price: float = 0.0) -> None:\n    # Localizar la línea a actualizar\n    updated_lines = []\n    \n    lines = get_sales(file)\n    for line in lines:\n        if search.lower() in line.lower():\n            updated_lines.append(f\"{name}, {qty}, {price}\")\n        else:\n            updated_lines.append(line)\n    \n    with open(file, \"w\") as file:\n        file.writelines(updated_lines)\n        \n    print(\"Línea actualizada\")\n\ndef read_sale(file: str, name: str = \"\") -> list:\n    sales = get_sales(file)\n    \n    for line in sales:\n        if name.lower() in line.lower():\n            return line.split(\", \")\n\ndef delete_sales_file(file: str) -> None:\n    try:\n        os.remove(file)\n    except FileNotFoundError:\n        print(\"No existe el fichero de ventas\")\n    except Exception as e:\n        print(f\"Error al eliminar el fichero de ventas: {e}\")\n    finally:\n        print(\"Fichero de ventas eliminado\")\n\ndef get_total_sales_by_product(file: str) -> dict:\n    \n    total_sales = {}\n    \n    sales = get_sales(file)\n    \n    for sale in sales:\n         data = sale.split(\", \")\n         clean_price = float(data[2].strip(\"\\n\").strip(\".\"))\n         total_sales[data[0]] = {\"qty\":data[1], \"price\":data[2], \"total\": int(data[1])*clean_price}\n\n    return total_sales\n\ndef get_total_sales(file: str) -> None:\n    total_sales = 0\n    \n    sales = get_sales(file)\n    \n    for sale in sales:\n        data = sale.split(\", \")\n        total_sales += int(data[1]) * float(data[2].strip(\"\\n\").strip(\".\"))\n    \n    print(f\"El total de ventas de todos los productos es de: {total_sales} €\")\n        \nend = False\n\nwhile not end:\n    show_menu()\n    option = int(input('Indique una opción a realizar: '))\n    \n    if option == 1: # Mostrar todas las ventas\n        sales = get_sales(file=\"sales.txt\")\n        for sale in sales:\n            print(sale)\n    elif option == 2: # Agregar una venta\n        product_name = input(\"Ingrese el nombre del producto: \")\n        quantity = int(input(\"Ingrese la cantidad vendida: \"))\n        price = float(input(\"Ingrese el precio del producto: \"))\n        insert_sale(file=\"sales.txt\", name=product_name, qty=quantity, price=price)\n    elif option == 3: # Eliminar una venta\n        product = input(\"Indica el producto a eliminar: \")\n        delete_sale(file=\"sales.txt\", product_name=product)\n    elif option == 4: # Buscar venta\n        product = input(\"Indica el producto a buscar: \")\n        result = read_sale(file=\"sales.txt\", name=product)\n        if result:\n            print(f'Información de la venta de {product}: {result}')\n    elif option == 5: # Actualizar venta\n        product = input(\"Indica el producto a actualizar: \")\n        result = read_sale(file=\"sales.txt\", name=product)\n        if result:\n            product_name = input(\"Ingrese el nombre del producto: \")\n            quantity = int(input(\"Ingrese la cantidad vendida: \"))\n            price = float(input(\"Ingrese el precio del producto: \"))\n            update_sale(file=\"sales.txt\", search=product, name=product_name, qty=quantity, price=price)\n        else:\n            print(\"No se encontró la venta del producto\") \n    elif option == 6: # Ventas totales por producto\n        result = get_total_sales_by_product(file=\"sales.txt\")\n        if result:\n            for key, value in result.items():\n                print(f'Producto: {key}, Total ventas: {value[\"total\"]}')\n    elif option == 7:\n        get_total_sales(\"sales.txt\")          \n    else: # Salir\n        end = True\n        delete_sales_file(file=\"sales.txt\")\n############################ FIN EXTRA ######################################"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/mvidalb.py",
    "content": "import os\n\n'''\nEjercicio\n'''\nfile_name = \"mvidalb.txt\"\n\nwith open(file_name, \"w\") as file:\n    file.write(\"Mario\\n\")\n    file.write(\"40\\n\")\n    file.write(\"Python\")\n\nwith open(file_name, \"r\") as file:\n    print(file.read())\n\nos.remove(file_name)\n    \n\n'''\nEjercicio extra\n'''\nfile_txt = \"ventas.txt\"\nopen(file_txt, \"a\")     #a = append, seguir añadiendo\n\nwhile True:\n   print(\"¡Bienvenido!\")\n   print(\"1. Añadir producto.\")\n   print(\"2. Consultar producto.\")\n   print(\"3. Actualizar producto.\")\n   print(\"4. Eliminar producto.\")\n   print(\"5. Mostrar productos.\")\n   print(\"6. Calcular venta total.\")\n   print(\"7. Calcular venta por producto.\")\n   print(\"8. Salir.\")\n   accion = input(\"Selecciona la acción a realizar: \")\n\n   match accion:\n        case \"1\":\n            name = input(\"Nombre: \")\n            quantity = input(\"Cantidad: \")\n            price = input(\"Precio: \")\n            with open(file_txt, \"a\",) as file:   #a = append, seguir añadiendo\n                file.write(f\"{name}, {quantity}, {price}\\n\")\n        case \"2\":\n            name = input(\"Nombre: \")\n            with open(file_txt, \"r\") as file:\n                for line in file.readlines():\n                    if line.split(\", \")[0] == name:\n                        print(line)\n                        break\n                print(\"Ese producto no existe!\\n\")\n        case \"3\":\n            name = input(\"Nombre: \")\n            quantity = input(\"Cantidad: \")\n            price = input(\"Precio: \")\n            with open(file_txt, \"r\") as file:   # Copio todas las líneas\n                lines = file.readlines()\n            with open(file_txt, \"w\") as file:  # Escribo todo de nuevo\n                for line in lines:\n                    if line.split(\", \")[0] == name:\n                        file.write(f\"{name}, {quantity}, {price}\\n\")\n                        print(\"Producto actualizado!\\n\")\n                    else:\n                        file.write(line)\n        case \"4\":\n            name = input(\"Nombre: \")\n            with open(file_txt, \"r\") as file:   # Copio todas las líneas\n                lines = file.readlines()\n            with open(file_txt, \"w\") as file:  # Escribo todo de nuevo\n                for line in lines:\n                    if line.split(\", \")[0] != name:\n                        file.write(line)\n                    else:\n                        print(\"Ese producto no existe!\")\n        case \"5\":\n            with open(file_txt, \"r\") as file:\n                print(file.read())\n        case \"6\":\n            total_price = 0\n            with open(file_txt, \"r\") as file:\n                for line in file.readlines():\n                    quantity = int(line.split(\", \")[1])\n                    price = float(line.split(\", \")[2])\n                    total_price += quantity*price\n                print(f\"Venta total: {total_price} €\")\n        case \"7\":\n            name = input(\"Nombre: \")\n            total_product = 0\n            with open(file_txt, \"r\") as file:\n                for line in file.readlines():\n                    components = line.split(\", \")\n                    if components[0] == name:\n                        quantity = int(line.split(\", \")[1])\n                        price = float(line.split(\", \")[2])\n                        total_product += quantity*price\n                        break\n                print(f\"Venta producto {name}: {total_product} €\")\n        case \"8\":\n            print(\"ventas.txt ha sido borrado. ¡Hasta pronto!\")\n            os.remove(file_txt)\n            break\n        case _:\n            print(\"No ha seleccionado ninguna acción entre los números 1 y 5.\")\n\n    "
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/neslarra.py",
    "content": "\"\"\"\n EJERCICIO:\n Desarrolla un programa capaz de crear un archivo que se llame como\n tu usuario de GitHub y tenga la extensión .txt.\n Añade varias líneas en ese fichero:\n - Tu nombre.\n - Edad.\n - Lenguaje de programación favorito.\n Imprime el contenido.\n Borra el fichero.\n\n DIFICULTAD EXTRA (opcional):\n Desarrolla un programa de gestión de ventas que almacena sus datos en un\n archivo .txt.\n - Cada producto se guarda en una línea del arhivo de la siguiente manera:\n   [nombre_producto], [cantidad_vendida], [precio].\n - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n   actualizar, eliminar productos y salir.\n - También debe poseer opciones para calcular la venta total y por producto.\n - La opción salir borra el .txt.\n\"\"\"\nimport os\n\nprint(f\"\\n\\n##  Explicación  {'#' * 40}\", end=\"\\n\\n\")\nprint(f\"\"\"\nPara poder operar con el contenido de un fichero (o generarlo) utilizamos la función 'open' a la \ncual le pasaremos dos argumentos: el nombre del fichero y el modo en que se va a abrir =>\n'r' para lectura, 'w' para [sobre]escritura y 'a' para agregar. Cualquiera de ellos se puede concatenar\na dos modificadores: '+' para indicar que se harán ambas operaciones simultáneamente (read y write)\ny 'b' para indicar que se operará con un stream binario.\nLas operaciones podrán ser 'write', 'writelines', 'read', 'readline' y 'readlines' <= 'write' y 'read'\noperan con cadenas mientras que 'writelines' y 'readlines' operan con listas (IMPORTANTE: en estas dos \núltimas 'lines' NO significa que agregará o leerá un 'linefeed' => solo indica que operará con listas => \nel linefeed, si es necesario, se deberá agregar manualmente). Por último 'readline' también opera con\ncadenas pero las lee fila a fila.\nPara liberar el fichero haremos un 'flush' (fuerza la descarga de datos) y un 'close' para cerrarlo.\n\ndata = '''Ultima operación: creado\nLorem ipsum dolor sit amet.\n'''\nfichero = open(\"reto_11.txt\", \"w\")\nfichero.write(data)\nfichero.flush()\nfichero.close()\n\n_ = input(\"Revisa el fichero y luego apreta cualquier tecla\")\n\nfichero = open(\"reto_11.txt\", \"r+\")\nnum_linea = 0\ndata = \"\"\nwhile True:\n    linea = fichero.readline()\n    if not linea:\n        break\n    if num_linea:\n        data += linea\n    else:\n        data += linea.split(\":\")[0] + \" modificado.\"\"\" + '\\\\n\"' + \"\"\"\n    num_linea += 1\ndata += \"Consectetur adipiscing elit\"\nfichero.seek(0)              # vuelvo al ppio del fichero\nfichero.truncate()           # trunco la data anterior para postear la nueva\nfichero.write(data)\nfichero.flush()\nfichero.close()\n  \n\"\"\")\n\ndata = '''Ultima operación: creado\nLorem ipsum dolor sit amet.\n'''\nfichero = open(\"reto_11.txt\", \"w\")\nfichero.write(data)\nfichero.flush()\nfichero.close()\n\n_ = input(\"Revisa el fichero y luego apreta cualquier tecla\")\n\nfichero = open(\"reto_11.txt\", \"r+\")\nnum_linea = 0\ndata = \"\"\nwhile True:\n    linea = fichero.readline()\n    if not linea:\n        break\n    if num_linea:\n        data += linea\n    else:\n        data += linea.split(\":\")[0] + \" modificado.\\n\"\n    num_linea += 1\ndata += \"Consectetur adipiscing elit\"\nfichero.seek(0)\nfichero.truncate()\nfichero.write(data)\nfichero.flush()\nfichero.close()\n\nprint(f\"\"\"\nPodemos simplificar el uso de un fichero a través del uso de \"context manager\", el cual se encarga de la\noperatoria de abrir el fichero, asignarlo a una variable, descargar los datos y cerrarlo => solo operaremos\ncon los métodos para manupular los datos:\n\ndata = '''Hola Mundo\nPythoneando con ficheros'''\nwith open('reto_11.txt', 'w') as fichero:\n    fichero.write(data)\n\nwith open('reto_11.txt', 'r') as fichero:\n    while True:\n        linea = fichero.readline()\n        if linea:\n            print(linea)\n        else:\n            print(\"\"\" + '\\\\n\"' + \"\"\")\n            break\n\"\"\")\n\n_ = input(\"Revisa el fichero y luego apreta cualquier tecla\")\n\ndata = '''Hola Mundo\nPythoneando con ficheros'''\nwith open('reto_11.txt', 'w') as fichero:\n    fichero.write(data)\n\nwith open('reto_11.txt', 'r') as fichero:\n    while True:\n        linea = fichero.readline()\n        if linea:\n            print(f\"{linea}\", end=\"\")\n        else:\n            print(\"\\n\")\n            break\n\n_ = input(\"Revisa el fichero y luego apreta cualquier tecla\")\n\nos.remove('reto_11.txt')\n\nprint(f\"\\n\\n##  Dificultad Extra  {'#' * 40}\", end=\"\\n\\n\")\n\n\"\"\"\n Desarrolla un programa de gestión de ventas que almacena sus datos en un\n archivo .txt.\n - Cada producto se guarda en una línea del arhivo de la siguiente manera:\n   [nombre_producto], [cantidad_vendida], [precio].\n - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n   actualizar, eliminar productos y salir.\n - También debe poseer opciones para calcular la venta total y por producto.\n - La opción salir borra el .txt.\n\"\"\"\n\nimport os\n\nFILE = \"retos_11_ventas.txt\"\n\nset_de_productos = set()\n\n\ndef cargar_ventas():\n    global set_de_productos\n    data = \"\"\n    print(\"Cargar los tres campos. Control-C para salir\")\n    while True:\n        try:\n            producto = input(\"\\tProducto: \")\n            if producto.lower() in set_de_productos:\n                print(\"\\nEl producto YA existe => cargar otro.\\n\")\n                continue\n            set_de_productos.add(producto.lower())\n            data += producto + \",\"\n            data += input(\"\\tVentas: \") + \",\"\n            data += input(\"\\tPrecio unitario: \") + \",\\n\"\n        except (KeyboardInterrupt, InterruptedError):\n            data = data[0:data.__len__() - 1]                                        # saco el útlimo \"\\n\"\n            if data and not data[0:data.__len__() - 1].split(\",\").__len__() % 3:     # controla que los tres campos estén cargados\n                guardar_fichero(data, \"a\")\n                return\n            print(\"\\nDeben cargarse los tres campos\\n\")\n\n\ndef eliminar_producto() -> None:\n    global set_de_productos\n    producto = seleccionar_producto()\n    nueva_data = \"\"\n    if producto:\n        data = leer_fichero().split(\"\\n\")\n        for fila in data:\n            if fila:\n                col = fila.split(\",\")\n                if col[0].lower() != producto.lower():\n                    nueva_data += fila + \"\\n\"\n                else:\n                    set_de_productos.remove(col[0])\n        nueva_data = nueva_data[0:nueva_data.__len__() - 1]\n        guardar_fichero(nueva_data, \"w\")\n\n\ndef guardar_fichero(data: str, operacion: str) -> None:\n    global FILE\n    with open(FILE, operacion) as fichero:\n        fichero.write(data + \"\\n\")\n\n\ndef leer_fichero() -> str:\n    global set_de_productos\n    data = \"\"\n    try:\n        with open(FILE, 'r') as fichero:\n            while True:\n                linea = fichero.readline()\n                if not linea:\n                    break\n                set_de_productos.add(linea.split(\",\")[0].lower())\n                data += linea\n    except FileNotFoundError:\n        print(\"\\nNo se han cargado datos\\n\")\n    finally:\n        if not data.split(\"\\n\")[-1]:\n            data = data[0:-1]\n        return data\n\n\ndef main():\n    while True:\n        opcion = menu(menues(\"ppal\"))\n        match opcion:\n            case 0:\n                salir()\n            case 1:\n                cargar_ventas()\n            case 2:\n                eliminar_producto()\n            case 3:\n                mostrar_ventas()\n            case 4:\n                modificar_producto()\n\n\ndef menu(menu: tuple) -> int:\n    \"\"\"\n    Arma un menú de selección donde el primer elemento de la tupla es el título, y el último la salida (siempre \"0\")\n    Retorna el número de item seleccionado.\n    \"\"\"\n    while True:\n        for index, item in enumerate(menu):\n            if index == 0:                                                            # Título del menú\n                print(f\"\\n{item}\")\n            else:\n                if index < menu.__len__() - 1:                                        # lista de ítems\"\n                    print(f\"\\t{index}- {item}\")\n                else:                                                                 # Salida\n                    print(f\"\\t0- {item}\")\n        opcion = input(f\"Ingrese una opcion [0-{menu.__len__() - 2}]: \")              # -2 <=> Título y Salida\n        if opcion and opcion.isnumeric() and 0 <= int(opcion) <= menu.__len__() - 2:\n            return int(opcion)\n\n\ndef menues(menu: str) -> tuple:\n    \"\"\"\n    data = {\"nombre_menu\": (\"Títutlo Menu\", \"item1\", \"item2\"..., \"itemN\", \"salida\"),}  donde la \"salida SIEMPRE es 0\n    \"\"\"\n    def enumerar_productos() -> tuple:\n        data = [\"Seleccionar Producto.\"]\n        lista_de_productos = list(set_de_productos)\n        lista_de_productos.sort()\n        for index, producto in enumerate(lista_de_productos):\n            data.append(producto.title())\n        data.append(\"Volver\")\n        return tuple(data)\n\n    data = {\n        \"ppal\": (\"Gestión de ventas.\", \"Alta\", \"Baja\", \"Consulta\", \"Modificación\", \"Salir\"),\n        \"confirmacion\": (\"Confirmar.\", \"Si\", \"No\"),\n        \"productos\": enumerar_productos(),\n    }\n    return data[menu]\n\n\ndef modificar_producto() -> None:\n    producto = seleccionar_producto()\n    nueva_data = \"\"\n    if producto:\n        data = leer_fichero().split(\"\\n\")\n        for index, fila in enumerate(data):\n            if fila:\n                col = fila.split(\",\")\n                if col[0].lower().strip() == producto.lower():\n                    nueva_data += col[0].strip() + \",\"\n                    nueva_data += input(\"\\tVentas: \") + \",\"\n                    nueva_data += input(\"\\tPrecio unitario: \") + \",\\n\"\n                else:\n                    nueva_data += fila + \"\\n\"\n        nueva_data = nueva_data[0:nueva_data.__len__() - 1]                                     # elimino el último \"\\n\"\n        if nueva_data and not nueva_data[0:nueva_data.__len__() - 1].split(\",\").__len__() % 3:  # no cuento la última \",\" para control de tres cols\n            guardar_fichero(nueva_data, \"w\")\n\n\ndef mostrar_ventas():\n    data = leer_fichero().split(\"\\n\")\n    productos = []\n    cantidades = []\n    precios = []\n    for fila in data:\n        if fila:\n            col = fila.split(\",\")\n            productos.append(col[0])\n            cantidades.append(col[1])\n            precios.append(col[2])\n\n    for producto, cantidad, precio in zip(productos, cantidades, precios):\n        print(f\"Nombre: {producto}  /  Cantidad: {cantidad}  /  Precio: {precio}  /  Ventas: ${int(cantidad) * int(precio)}\")\n    return\n\n\ndef salir() -> None:\n    try:\n        os.remove(FILE)\n    except FileNotFoundError:\n        pass\n    quit()\n\n\ndef seleccionar_producto() -> str:\n    opcion = menu(menues(\"productos\"))\n    lista_de_productos = list(set_de_productos)\n    lista_de_productos.sort()\n    return \"\" if opcion == 0 else lista_de_productos[opcion - 1]\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/nlarrea.py",
    "content": "\"\"\"\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n * \n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n * archivo .txt.\n * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n\"\"\"\n\nfile_path = \"nlarrea.txt\"\n\n# Write data to the file\nwith open(file_path, \"w\") as f:\n    f.write(\"Naia\\n\")\n    f.write(\"25\\n\")\n    f.write(\"Python\\n\")\n\n# Read the file and print the content\n# OPTION 1: Read all the content\nprint(\"Print file - Option 1:\")\nwith open(file_path, \"r\") as f:\n    print(f.read())\n\n# OPTION 2: Read line by line\nprint(\"Print file - Option 2:\")\nwith open(file_path, \"r\") as f:\n    for line in f.readlines():\n        print(line.strip())\n\n# Remove the file\nimport os\n\nos.remove(file_path)\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n * archivo .txt.\n * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n\"\"\"\n\n\nfile_path = \"sales.txt\"\n\n\ndef ask_option(options: tuple) -> int:\n    print(\"\\nMENU\")\n    for index, option in enumerate(options):\n        print(f\"{index}. {option}\")\n\n    while True:\n        try:\n            chosen_option = input(\"What do you want to do?\\n> \")\n            if not chosen_option.isnumeric():\n                raise TypeError(f\"Chosen option must be a number!\")\n            elif int(chosen_option) < 0 or int(chosen_option) >= len(options):\n                raise ValueError(\n                    f\"Chosen option must be a number between {0}-{len(options) - 1}!\"\n                )\n        except Exception as error:\n            print(error)\n        else:\n            return int(chosen_option)\n\n\ndef run():\n    while True:\n        options: tuple = (\n            \"Exit\",\n            \"Add products\",\n            \"See single product\",\n            \"See all products\",\n            \"Update products\",\n            \"Remove products\",\n            \"Calculate total sales\",\n            \"Calculate sales by product\",\n        )\n        option = ask_option(options)\n        print(\"\\nChosen option:\", options[int(option)], \"\\n\")\n\n        if option == 0:\n            try:\n                os.remove(file_path)\n            except FileNotFoundError:\n                # If there is no file yet -> nothing happens\n                pass\n\n            return\n\n        try:\n            if option == 1:\n                # ADD PRODUCTS\n                try:\n                    product = input(\"Product name:\\n > \")\n\n                    amount_sold = input(\"Amount sold:\\n > \")\n                    if not amount_sold.replace(\".\", \"\", 1).isnumeric():\n                        raise TypeError(\"Amount must be a number!\")\n\n                    price = input(\"Price:\\n > \")\n                    if not price.replace(\".\", \"\", 1).isnumeric():\n                        raise TypeError(\"Price must be a number!\")\n\n                except Exception as error:\n                    print(f\"{type(error).__name__}: {error}\")\n\n                else:\n                    with open(file_path, \"a\") as f:\n                        f.write(f\"{product}, {amount_sold}, {price}\\n\")\n\n            elif option == 2:\n                # SEE SINGLE PRODUCT\n                product = input(\"Product name:\\n > \")\n\n                with open(file_path, \"r\") as f:\n                    for line in f.readlines():\n                        if line.split(\", \")[0] == product:\n                            print(\"\\n\", line)\n\n            elif option == 3:\n                # SEE ALL PRODUCTS\n                with open(file_path, \"r\") as f:\n                    print(\"\\n\", f.read())\n\n            elif option == 4:\n                # UPDATE PRODUCT\n                try:\n                    product = input(\"Product name:\\n > \")\n\n                    amount_sold = input(\"New amount sold:\\n > \")\n                    if not amount_sold.replace(\".\", \"\", 1).isnumeric():\n                        raise TypeError(\"Amount must be a number!\")\n\n                    price = input(\"New price:\\n > \")\n                    if not price.replace(\".\", \"\", 1).isnumeric():\n                        raise TypeError(\"Price must be a number!\")\n\n                except Exception as error:\n                    print(f\"{type(error).__name__}: {error}\")\n\n                else:\n                    # Read current data\n                    with open(file_path, \"r\") as f:\n                        lines = f.readlines()\n\n                    # Write old and new data\n                    with open(file_path, \"w\") as f:\n                        for line in lines:\n                            if (\n                                line.split(\", \")[0].strip().lower()\n                                == product.strip().lower()\n                            ):\n                                f.write(f\"{product}, {amount_sold}, {price}\\n\")\n                            else:\n                                f.write(line)\n\n            elif option == 5:\n                # REMOVE PRODUCT\n                product = input(\"Product name:\\n > \")\n\n                with open(file_path, \"r\") as f:\n                    lines = f.readlines()\n\n                with open(file_path, \"w\") as f:\n                    for line in lines:\n                        if (\n                            line.split(\", \")[0].strip().lower()\n                            != product.strip().lower()\n                        ):\n                            f.write(line)\n\n            elif option == 6:\n                # CALCULATE TOTAL SALES\n                with open(file_path, \"r\") as f:\n                    lines = f.readlines()\n\n                sales = 0\n                for line in lines:\n                    amount_sold = int(line.split(\", \")[1].strip())\n                    price = float(line.split(\", \")[2].strip())\n                    sales += amount_sold * price\n\n                print(\"Total sales:\", sales)\n\n            elif option == 7:\n                # CALCULATE SINGLE PRODUCT'S SALES\n                product = input(\"Product name:\\n > \")\n\n                with open(file_path, \"r\") as f:\n                    lines = f.readlines()\n\n                for line in lines:\n                    components = line.split(\", \")\n                    if components[0] == product:\n                        amount_sold = int(components[1].strip())\n                        price = float(components[2].strip())\n                        sales = amount_sold * price\n\n                        print(\"Product sales:\", sales)\n                        break\n                else:\n                    print(f\"No '{product}' product has been found.\")\n\n        except FileNotFoundError:\n            print(\"There is no product data yet.\")\n\n\nrun()\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/oniricoh.py",
    "content": "\n#Abrimos archivo en modo escritura\narchivo = open(r\"11 Manejo de ficheros\\archivo.txt\", \"w\")\narchivo.write(\"Nombre: Daniel\\nEdad: 34\\nLenguaje de programación: Python\")\narchivo.close()\n\n#Arbimos archivo en modo lectura\narchivo = open(r\"11 Manejo de ficheros\\archivo.txt\", \"r\")\nprint(archivo.read())\narchivo.close()\n\n#salto de linea\nprint()\n\n#Para escribir en un archivo existente sin borrar su contenido previo\nwith open(r\"11 Manejo de ficheros\\archivo.txt\", \"a\") as archivo:\n    archivo.write(\"\\nEste es un nuevo contenido agregado al final.\")\n\n# No es necesario cerrar el archivo explícitamente aquí, se cerrará automáticamente al salir del bloque 'with'\nwith open(r\"11 Manejo de ficheros\\archivo.txt\", \"r\") as archivo:\n    contenido = archivo.read()\n    print(contenido)\n\n#salto de linea\nprint()\n\n#Leyendo un archivo linea por linea\nwith open(r\"11 Manejo de ficheros\\archivo.txt\", \"r\") as archivo:\n    for linea in archivo:\n        print(linea)\n\nprint()\nprint()\nprint()\n\n###############################################################################\n## DIFICULTAD EXTRA: Programa de ventas\n###############################################################################\n\nclass SalesManagement:\n    \"\"\"Clase para gestionar las ventas y productos.\"\"\"\n    \n    def __init__(self, file) -> None:\n        \"\"\"Inicializa la instancia de SalesManagement.\n        \n        Args:\n            file (str): Ruta del archivo que contiene los datos de los productos.\n        \"\"\"\n        self.file = file\n    \n    def __str__(self) -> str:\n        \"\"\"Devuelve una representación en cadena de los productos y las ventas totales.\"\"\"\n        try:\n            with open(self.file, \"r\") as items:\n                content = items.read()\n                total_sales = self.total_sales(items)\n                string_output = f\"{content}\\nTotal de ventas y beneficios:\\n  - Vendidos: {total_sales['Total vendidos']}\\n  - Beneficios: {total_sales['Total Beneficios']}\"\n                return string_output    \n        except FileNotFoundError:\n            return f\"El archivo {self.file} aún no ha sido creado, agrega algún artículo para comenzar\"\n\n    def add_product(self, product_name, price, quantity_sold=0, profit=0):\n        \"\"\"Añade un nuevo producto al archivo.\n        \n        Args:\n            product_name (str): Nombre del producto.\n            price (float): Precio del producto.\n            quantity_sold (int, optional): Cantidad vendida del producto. Defaults to 0.\n            profit (float, optional): Beneficio del producto. Defaults to 0.\n        \"\"\"\n        lines = self._read_lines()\n        product = f\"Nombre del producto: {product_name}, Precio: {price}, Cantidad vendida: {quantity_sold}, Beneficio: {profit}\\n\"\n        if any(product_name in line for line in lines):\n            print(\"No se puede agregar el producto porque ya ha sido agregado anteriormente.\")\n            return\n        else:\n            lines.append(product)\n        self._write_lines(lines)\n        print(f\"Se ha agregado '{product_name}' al listado de productos.\")\n        \n    def update_product(self, product_name, price, quantity_sold=0, profit=0):\n        \"\"\"Actualiza la información de un producto existente en el archivo.\n        \n        Args:\n            product_name (str): Nombre del producto a actualizar.\n            price (float): Nuevo precio del producto.\n            quantity_sold (int, optional): Cantidad vendida adicional del producto. Defaults to 0.\n            profit (float, optional): Nuevo beneficio del producto. Defaults to 0.\n        \"\"\"\n        lines = self._read_lines()\n        found = False\n        for i, line in enumerate(lines):\n            if product_name in line:\n                product_data = line.split(\", \")\n                product_data[1] = f\"Precio: {price}\"\n                product_data[2] = f\"Cantidad vendida: {int(product_data[2].split(': ')[-1]) + quantity_sold}\"\n                product_data[3] = f\"Beneficio: {float(product_data[1].split(': ')[-1]) * int(product_data[2].split(': ')[-1])}\"\n                lines[i] = \", \".join(product_data) + \"\\n\"\n                found = True\n                break   \n        if not found:\n            print(f\"El producto '{product_name}' no existe o no ha sido creado.\")\n            return\n        self._write_lines(lines)\n        print(f\"Se ha actualizado el producto: {product_name}.\")    \n    \n    def total_sales(self, items):\n        \"\"\"Calcula el total de ventas y beneficios.\n        \n        Args:\n            items (file): Objeto de archivo que contiene los datos de los productos.\n        \n        Returns:\n            dict: Diccionario con el total de ventas y beneficios.\n        \"\"\"\n        lines = items.readlines()\n        total = {\"Total vendidos\": 0, \"Total Beneficios\": 0}\n        for line in lines:\n            product_data = line.split(\", \")\n            total[\"Total vendidos\"] += int(product_data[2].split(\": \")[-1])\n            total[\"Total Beneficios\"] += float(product_data[3].split(\": \")[-1])\n        return total \n\n    def remove_product(self, product_name):\n        \"\"\"Elimina un producto del archivo.\n        \n        Args:\n            product_name (str): Nombre del producto a eliminar.\n        \"\"\"\n        lines = self._read_lines()\n        updated_lines = [line for line in lines if product_name not in line]\n        self._write_lines(updated_lines)\n        if len(lines) != len(updated_lines):\n            print(f\"Se ha eliminado el producto '{product_name}'.\")\n        else:\n            print(f\"El producto '{product_name}' no está registrado\")\n\n    def _read_lines(self):\n        \"\"\"Lee las líneas del archivo de productos.\n        \n        Returns:\n            list: Lista de líneas del archivo.\n        \"\"\"\n        try:\n            with open(self.file, \"r\") as items:\n                return items.readlines()\n        except FileNotFoundError:\n            return []\n\n    def _write_lines(self, lines):\n        \"\"\"Escribe las líneas en el archivo de productos.\n        \n        Args:\n            lines (list): Lista de líneas a escribir en el archivo.\n        \"\"\"\n        with open(self.file, \"w\") as items:\n            items.writelines(lines)\n\n\nclass IncorrectSelection(Exception):\n    \"\"\"Excepción para manejar selecciones incorrectas.\"\"\"\n    pass                \n\ndef main():\n    file = r\"11 Manejo de ficheros\\articulos.txt\"\n    sales = SalesManagement(file)\n    \n    while True:\n        print(\"\\n\\nMenu Principal\")\n        print(\"1.- Añadir un nuevo producto\")\n        print(\"2.- Consultar listado de productos\")\n        print(\"3.- Actualizar un producto\")        \n        print(\"4.- Eliminar un producto\")\n        print(\"5.- Salir del programa\")\n        try:\n            select = int(input(\"\\nSelecciona la opción deseada (1, 2, 3, 4 o 5): \"))\n            \n            if select < 1 or select > 5:\n                raise IncorrectSelection(\"Selecciona una opción válida.\")\n            \n            elif select == 1:\n                print(\"\\n¿Qué producto quieres agregar?\")\n                product = input(\"Nombre del producto: \")\n                price = float(input(\"Precio del producto: \"))\n                sales.add_product(product, price)\n            \n            elif select == 2:\n                print(\"\\nListado de productos:\")\n                print(sales)\n            \n            elif select == 3:\n                print(\"\\n¿Qué producto quieres actualizar?\")\n                product = input(\"Nombre del producto: \")\n                price = float(input(\"Precio del producto: \"))\n                sale = int(input(\"Cantidad vendida: \"))\n                sales.update_product(product, price, sale)\n            \n            elif select == 4:\n                print(\"\\n¿Qué producto quieres eliminar?\")\n                product = input(\"Nombre del producto: \")\n                sales.remove_product(product)\n            \n            elif select == 5:\n                break\n                                        \n        except ValueError:\n            print(\"Error: Por favor, introduce un número válido.\")\n        except IncorrectSelection as err:\n            print(\"Error:\", err)\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/oriaj3.py",
    "content": "\"\"\"\t\n10 - MANEJO DE FICHEROS\n\nAutor de la solución: Oriaj3\t\n\nTeoría:\t\nEl manejo de ficheros es una de las tareas más comunes en la programación.\n\nPython proporciona una serie de funciones y métodos para trabajar con ficheros.\n\nPara abrir un fichero, se utiliza la función open(), que recibe dos parámetros: el nombre del fichero y el modo de apertura.\n\nEl modo de apertura puede ser de lectura (r), escritura (w), o añadir (a). También se puede abrir el fichero en modo binario (b) o en modo texto (t).\n\nEjemplo:\nf = open(\"archivo.txt\", \"r\")\n\nUna vez abierto el fichero, se pueden leer o escribir datos en él utilizando los métodos read(), write(), readline(), readlines(), etc.\n\nEs importante cerrar el fichero una vez que se ha terminado de trabajar con él, para liberar los recursos que utiliza.\n\"\"\" \n\"\"\"\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n\"\"\"\n# Crear un archivo con mi usuario de GitHub\nf = open(\"oriaj3.txt\", \"w\")\nf.write(\"Oriaj3\\n\")\nf.write(\"30\\n\")\nf.write(\"Python\\n\")\nf.close()\n\n# Leer el contenido del archivo\nf = open(\"oriaj3.txt\", \"r\")\nprint(f.read())\nf.close()\n\n# Borrar el archivo\nimport os\nos.remove(\"oriaj3.txt\")\n\n\"\"\"\n/*\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n * archivo .txt.\n * - Cada producto se guarda en una línea del arhivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n */\n\"\"\"\n\n# Clase producto\nclass Producto:\n    def __init__ (self, nombre, cantidad, precio) -> None:\n        self.nombre = nombre\n        self.precio = precio\n        self.cantidad = cantidad\n\n    def __str__(self) -> str:\n        return f\"{self.nombre}, {self.cantidad}, {self.precio}\"\n    \n# Clase gestor de ventas\nclass GestorVentas:\n    def __init__(self) -> None:\n        self.archivo = \"ventas.txt\"\n\n    def anadir_producto(self, producto: Producto) -> None:\n        with open(self.archivo, \"a\") as f:\n            str_producto = producto.__str__()\n            f.write(f\"{str_producto}\\n\")\n\n    def consultar_producto(self, nombre: str) -> Producto:\n        with open(self.archivo, \"r\") as f:\n            for linea in f:\n                nombre_producto, cantidad, precio = linea.split(\", \")\n                if nombre_producto == nombre:\n                    return Producto(nombre_producto, cantidad, precio).__str__()\n            return None\n    def actualizar_producto(self, producto: Producto) -> None:\n        with open(self.archivo, \"r\") as f:\n            lineas = f.readlines()\n        with open(self.archivo, \"w\") as f:\n            for linea in lineas:\n                nombre_producto, cantidad, precio = linea.split(\", \")\n                if nombre_producto == producto.nombre:\n                    str_producto = producto.__str__()\n                    f.write(f\"{str_producto}\\n\")\n                else:\n                    f.write(linea)\n    def eliminar_producto(self, nombre: str) -> None:\n        with open(self.archivo, \"r\") as f:\n            lineas = f.readlines()\n        with open(self.archivo, \"w\") as f:\n            for linea in lineas:\n                nombre_producto, cantidad, precio = linea.split(\", \")\n                if nombre_producto != nombre:\n                    f.write(linea) \n\n    def n_ventas_producto(self, nombre: str) -> int:\n        with open(self.archivo, \"r\") as f:\n            lineas = f.readlines()\n            for linea in lineas:\n                nombre_producto, cantidad, precio = linea.split(\", \")\n                cantidad = int(cantidad)\n                precio = float(precio)\n                if nombre_producto == nombre:\n                    return cantidad * precio\n\n    def n_ventas_total(self) -> int:\n        with open(self.archivo, \"r\") as f:\n            total = 0\n            for linea in f:\n                nombre_producto, cantidad, precio = linea.split(\", \")\n                cantidad = int(cantidad)\n                precio = float(precio)\n                total += cantidad * precio\n            return total\n        \n    def salir(self) -> None:\n        os.remove(self.archivo)\n    \n\n# Prueba de la clase\ngestor = GestorVentas()\nproducto1 = Producto(\"Producto1\", 10, 100)\nproducto2 = Producto(\"Producto2\", 20, 200)\nproducto3 = Producto(\"Producto3\", 30, 300)\nproducto4 = Producto(\"Producto4\", 40, 400)\n\ngestor.anadir_producto(producto1)\ngestor.anadir_producto(producto2)\ngestor.anadir_producto(producto3)\ngestor.anadir_producto(producto4)\n\nprint(gestor.consultar_producto(\"Producto1\"))\nprint(gestor.consultar_producto(\"Producto2\"))\nprint(gestor.consultar_producto(\"Producto3\"))\nprint(gestor.consultar_producto(\"Producto4\"))\n\nproducto1 = Producto(\"Producto1\", 20, 100)\ngestor.actualizar_producto(producto1)\nprint(gestor.consultar_producto(\"Producto1\"))\n\ngestor.eliminar_producto(\"Producto2\")\nprint(gestor.consultar_producto(\"Producto2\"))\n\nprint(gestor.n_ventas_producto(\"Producto1\"))\nprint(gestor.n_ventas_total())\n\ngestor.salir()\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/pakiuh.py",
    "content": "'''\r\nIMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\r\n\r\nEJERCICIO:\r\nDesarrolla un programa capaz de crear un archivo que se llame como\r\ntu usuario de GitHub y tenga la extensión .txt.\r\nAñade varias líneas en ese fichero:\r\n- Tu nombre.\r\n- Edad.\r\n- Lenguaje de programación favorito.\r\nImprime el contenido.\r\nBorra el fichero.'''\r\nimport os\r\n\r\nwith open(\"pakiuh.txt\", \"w\") as archivo_datos:\r\n    archivo_datos.write(f\"Mi nombre es: Francisco Camps\\nEdad: 53 años\\nMi Lenguaje de programación favorito es: Python.\")\r\n\r\nwith open(\"pakiuh.txt\", \"r\") as archivo_datos:\r\n    print(archivo_datos.read())\r\n    print(os.getcwd())\r\n\r\nif os.path.exists(\"pakiuh.txt\"):\r\n    os.remove(\"pakiuh.txt\")\r\n    print(\"archivo eliminado\")\r\nelse:\r\n    print(\"archivo no elimando\")\r\n\r\n'''DIFICULTAD EXTRA (opcional):\r\nDesarrolla un programa de gestión de ventas que almacena sus datos en un \r\narchivo .txt.\r\n- Cada producto se guarda en una línea del archivo de la siguiente manera:\r\n  [nombre_producto], [cantidad_vendida], [precio].\r\n- Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\r\n  actualizar, eliminar productos y salir.\r\n- También debe poseer opciones para calcular la venta total y por producto.\r\n- La opción salir borra el .txt.'''\r\n\r\nproductos = [\r\n    [\"sables_laser\", 20000, 3],\r\n    [\"pistolas_laser\", 50000, 4],\r\n    [\"X-Wing\",100, 20000]\r\n    ]\r\n\r\nwith open(\"gestion_ventas.txt\", \"w\", encoding=\"utf-8\") as gestion_ventas:\r\n\r\n    for producto in productos:\r\n        gestion_ventas.write(f\"nombre artículo: {producto[0]} {producto[1]}udds disponibles {producto[2]}€ cada udd\\n\")\r\n\r\n#Añadimos nuevos elementos\r\ndef añadir():\r\n    print(\"Indica los datos del nuevo producto:\")\r\n    nombre_producto = input(\"Nombre de Producto: \")\r\n    unidades_vendidas = int(input(\"Unidades Vendidas: \"))\r\n    precio_venta = int(input(\"precio de venta: \"))\r\n    productos.append([nombre_producto, unidades_vendidas, precio_venta])\r\n    with open(\"gestion_ventas.txt\", \"a\", encoding=\"utf-8\") as gestion_ventas:\r\n        gestion_ventas.write(f\"nombre artículo: {productos[-1][0]} {productos[-1][1]}udds disponibles {productos[-1][2]}€ cada udd\\n\")\r\n\r\n#Para consultar productos\r\ndef consultar(nombre_producto):\r\n    for i in range(len(productos)):\r\n        if productos[i][0] == nombre_producto:\r\n            print(f\"El producto {productos[i][0]} ha vendido {productos[i][1]} unidades a {productos[i][2]}€ lo que hace un total de venta de {productos[i][1] * productos[i][2]}€\")\r\n\r\n#Actualizar producto\r\ndef actualizar(nombre_producto):\r\n    for i in range(len(productos)):\r\n        if productos[i][0] == nombre_producto:\r\n            producto[i][1] = int(input(\"Indica nueva cantidad de unidades vendidas: \"))\r\n            producto[i][2] = int(input(\"Indica el precio al que se han vendido: \"))\r\n            print(f\"El producto {productos[i][0]} ha vendido {productos[i][1]} unidades a {productos[i][2]}€ lo que hace un total de venta de {productos[i][1] * productos[i][2]}€\")\r\n\r\n#Eliminar producto\r\ndef eliminar(nombre_producto):\r\n    for i in range(len(productos)):\r\n        if productos[i][0] == nombre_producto:\r\n            seguro = input(f\"Vas a eliminar el producto {productos[i][0]} que ha vendido {productos[i][1]} unidades a {productos[i][2]}€ lo que hace un total de venta {productos[i][1] * productos[i][2]}€ ¿Estás seguro? pulsa S para continuar\")\r\n            if seguro == \"S\":\r\n                del productos[i]\r\n\r\n#Calcular el total de las ventas\r\ndef total_ventas():\r\n    ventas = 0\r\n    for i in range(len(productos)):\r\n        ventas += (productos[i][1] * productos[i][2])\r\n    return ventas\r\n            \r\n\r\n#menú para por terminal modificar los elemnentos\r\nprint(f\"Selecciona una de las siguientes opciones:\\n 1. Añadir Nuevo Producto.\\n 2. Consultar Producto\\n 3. Actualiza Producto\\n 4. Elima Producto\\n 5. Calcula la Total Ventas\\n 6. Salir\")\r\n1\r\nmatch int(input(\"Tu número de opción es: \")):\r\n    case 1:\r\n        añadir()\r\n    case 2:\r\n        consulta = input(\"Indica el nombre del producto a consultar: \")\r\n        consultar(consulta)\r\n    case 3:\r\n        actualiza = input(\"Indica el nombre del producto a actualizar: \")\r\n        actualizar(actualiza)\r\n    case 4:\r\n        elimina = input(\"Indica el nombre del producto a eliminar: \")\r\n        eliminar(elimina)\r\n    case 5:\r\n        print(f\"El total de ventas es de {total_ventas()}€\")\r\n    case 6:\r\n        print(\"Adios\")\r\n    case _:\r\n        print(\"opción no válida\")\r\n\r\n\r\n\r\n\r\n\r\n        "
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/pguillo02.py",
    "content": "import os\n\nwith open(\"pguillo02.txt\", \"w\") as f:\n    f.write(\"Pablo Guilló \\n\")\n    f.write(\"21 años \\n\")\n    f.write(\"Python \\n\")\n\nwith open(\"pguillo02.txt\", \"r\") as f:\n    print(f.read())\n\nos.remove(\"pguillo02.txt\")"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/pyramsd.py",
    "content": "import os\n\narchivo_usuario = \"pyramsd.txt\"\n\nif os.path.exists(path=archivo_usuario):\n    os.remove(path=archivo_usuario)\n\nwith open(archivo_usuario, 'w') as archivo:\n    archivo.write(\"Nombre: Sergio Ruiz\\n\")\n    archivo.write(\"Edad: 18\\n\")\n    archivo.write(\"Lenguaje de programación favorito: Python\\n\")\n\nwith open(archivo_usuario, 'r') as archivo:\n    contenido = archivo.read()\n    print(contenido)\n\nos.remove(archivo_usuario)\nprint(\"El archivo %s ha sido eliminado.\" % (archivo_usuario))\n\n\n'''\nEXTRA\n'''\narchivoDeVentas = 'registroDeVentas.txt'\ndef mostrar_menu():\n    print(\"\\nMenú de gestión de ventas:\")\n    print(\"1. Añadir producto\")\n    print(\"2. Consultar productos\")\n    print(\"3. Actualizar producto\")\n    print(\"4. Eliminar producto\")\n    print(\"5. Calcular venta total\")\n    print(\"6. Calcular venta por producto\")\n    print(\"7. Salir\")\n\n\ndef añadir_producto():\n    nombre_producto = input(\"Introduce el nombre del producto: \")\n    cantidad_vendida = input(\"Introduce la cantidad vendida: \")\n    precio = input(\"Introduce el precio del producto: \")\n    with open(archivoDeVentas, 'a') as archivo:\n        archivo.write(\"%s, %s, %s\\n\" % (nombre_producto, cantidad_vendida, precio))\n    print(\"Producto añadido correctamente.\")\n\n\ndef consultar_productos():\n    with open(archivoDeVentas, 'r') as archivo:\n        lineas = archivo.readlines()\n    for linea in lineas:\n        partes = linea.split(', ')\n        print(partes[0])\n    \n\ndef actualizar_producto():\n    nombre_producto = input(\"Introduce el nombre del producto a actualizar: \")\n    nueva_cantidad = input(\"Introduce la nueva cantidad vendida: \")\n    nuevo_precio = input(\"Introduce el nuevo precio: \")\n    with open(archivoDeVentas, 'r') as archivo:\n        lineas = archivo.readlines()\n    with open(archivoDeVentas, 'w') as archivo:\n        for linea in lineas:\n            if nombre_producto in linea:\n                archivo.write(\"%s, %s, %s\\n\" % (nombre_producto, nueva_cantidad, nuevo_precio))\n                print(\"Producto actualizado correctamente.\")\n            else:\n                archivo.write(linea)\n\n\ndef eliminar_producto():\n    nombre_producto = input(\"Introduce el nombre del producto a eliminar: \")\n    with open(archivoDeVentas, 'r') as archivo:\n        lineas = archivo.readlines()\n    with open(archivoDeVentas, 'w') as archivo:\n        for linea in lineas:\n            if nombre_producto not in linea:\n                archivo.write(linea)\n        print(\"Producto eliminado correctamente.\")\n\n\ndef calcular_venta_total():\n    with open(archivoDeVentas, 'r') as archivo:\n        lineas = archivo.readlines()\n    venta_total = 0\n    for linea in lineas:\n        partes = linea.split(', ')\n        cantidad_vendida = int(partes[1])\n        precio = float(partes[2])\n        venta_total += cantidad_vendida * precio\n    print(\"La venta total es de %.2f\" % venta_total)\n\n\ndef calcular_venta_producto():\n    nombre_producto = input(\"Introduce el nombre del producto a consultar: \")\n    with open(archivoDeVentas, 'r') as archivo:\n        lineas = archivo.readlines()\n    for linea in lineas:\n        partes = linea.split(', ')\n        if nombre_producto in partes:\n            cantidad_vendida = int(partes[1])\n            precio = float(partes[2])\n            venta_producto = cantidad_vendida * precio\n            print(\"La venta total del producto %s es de %.2f\" % (nombre_producto, venta_producto))\n            return\n    print(\"Producto no encontrado.\")\n\n\ndef main():\n    while True:\n        mostrar_menu()\n        opcion = input(\"Elige una opción: \")\n        if opcion == '1':\n            añadir_producto()\n        elif opcion == '2':\n            consultar_productos()\n        elif opcion == '3':\n            actualizar_producto()\n        elif opcion == '4':\n            eliminar_producto()\n        elif opcion == '5':\n            calcular_venta_total()\n        elif opcion == '6':\n            calcular_venta_producto()\n        elif opcion == '7':\n            if os.path.exists(archivoDeVentas):\n                os.remove(archivoDeVentas)\n            print(\"Saliendo del programa...\")\n            break\n        else:\n            print(\"Opción no válida.\")\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/qwik-zgheib.py",
    "content": "# -- exercise\nclass FileTest:\n    def __init__(self):\n        self.file_name: str = input(\"enter file name: \")\n\n    def create_file(self) -> None:\n        with open(f\"{self.file_name}.txt\", \"w\") as file:\n            name: str = input(\"enter your name: \")\n            age: int = int(ask_value(\"enter your age: \", \"int\"))\n            fav_lang: str = input(\"enter your favorite programming language: \")\n            content: str = (\n                f\"name: {name}\\nage: {age}\\nfavorite programming language: {fav_lang}\"\n            )\n            file.write(content)\n        print(\"successfully created file\")\n\n    def read_file(self) -> None:\n        try:\n            with open(f\"{self.file_name}.txt\", \"r\") as file:\n                print(file.read())\n        except FileNotFoundError:\n            print(\"file not found\")\n\n    def remove_file(self) -> None:\n        try:\n            import os\n\n            os.remove(f\"{self.file_name}.txt\")\n            print(\"file removed\")\n        except FileNotFoundError:\n            print(\"file not found\")\n\n\ndef check_input(input_value: str, type_check: str) -> bool:\n    if type_check == \"int\":\n        try:\n            int(input_value)\n            return True\n        except ValueError:\n            return False\n    elif type_check == \"float\":\n        try:\n            float(input_value)\n            return True\n        except ValueError:\n            return False\n    return False\n\n\ndef ask_value(description: str, type_check: str) -> str:\n    value: str = input(description)\n    while not check_input(value, type_check):\n        print(\"incorrect value, try again.\")\n        value = input(description)\n    return value\n\n\n# if __name__ == \"__main__\":\n#     file_test = FileTest()\n#     file_test.create_file()\n#     file_test.read_file()\n#     file_test.remove_file()\n\n\n# -- extra challenge\nclass Sales:\n    def __init__(self):\n        self.file_name: str = \"sales\"\n\n    def add_product(self) -> None:\n        with open(f\"{self.file_name}.txt\", \"a\") as file:\n            product_name: str = input(\"enter product name: \")\n            quantity: int = int(ask_value(\"enter quantity sold: \", \"int\"))\n            price: float = float(ask_value(\"enter price: \", \"float\"))\n            content: str = f\"{product_name}, {quantity}, {price}\\n\"\n            file.write(content)\n        print(\"product added successfully\")\n\n    def read_products(self) -> None:\n        try:\n            with open(f\"{self.file_name}.txt\", \"r\") as file:\n                print(file.read())\n        except FileNotFoundError:\n            print(\"file not found\")\n\n    def update_product(self) -> None:\n        try:\n            with open(f\"{self.file_name}.txt\", \"r\") as file:\n                lines: list = file.readlines()\n            product_name: str = input(\"enter product name to update: \")\n            for i, line in enumerate(lines):\n                if product_name in line:\n                    quantity: int = int(ask_value(\"enter quantity sold: \", \"int\"))\n                    price: float = float(ask_value(\"enter price: \", \"float\"))\n                    lines[i] = f\"{product_name}, {quantity}, {price}\\n\"\n                    with open(f\"{self.file_name}.txt\", \"w\") as file:\n                        file.writelines(lines)\n                    print(\"product updated successfully\")\n                    break\n            else:\n                print(\"product not found\")\n        except FileNotFoundError:\n            print(\"file not found\")\n\n    def remove_product(self) -> None:\n        try:\n            with open(f\"{self.file_name}.txt\", \"r\") as file:\n                lines: list = file.readlines()\n            product_name: str = input(\"enter product name to remove: \")\n            for i, line in enumerate(lines):\n                if product_name in line:\n                    del lines[i]\n                    with open(f\"{self.file_name}.txt\", \"w\") as file:\n                        file.writelines(lines)\n                    print(\"product removed successfully\")\n                    break\n            else:\n                print(\"product not found\")\n        except FileNotFoundError:\n            print(\"file not found\")\n\n    def total_sales(self) -> None:\n        try:\n            with open(f\"{self.file_name}.txt\", \"r\") as file:\n                lines: list = file.readlines()\n            total: float = 0\n            for line in lines:\n                quantity, price = line.split(\", \")[1:]\n                total += int(quantity) * float(price)\n            print(f\"total sales: {total}\")\n        except FileNotFoundError:\n            print(\"file not found\")\n            return\n\n    def product_sales(self) -> None:\n        try:\n            with open(f\"{self.file_name}.txt\", \"r\") as file:\n                lines: list = file.readlines()\n            product_name: str = input(\"enter product name to calculate sales: \")\n            for line in lines:\n                if product_name in line:\n                    quantity, price = line.split(\", \")[1:]\n                    total: float = int(quantity) * float(price)\n                    print(f\"total sales of {product_name}: {total}\")\n                    break\n            else:\n                print(\"product not found\")\n        except FileNotFoundError:\n            print(\"file not found\")\n            return\n\n    def remove_file(self) -> None:\n        try:\n            import os\n\n            os.remove(f\"{self.file_name}.txt\")\n            print(\"file removed\")\n        except FileNotFoundError:\n            print(\"file not found\")\n            return\n\n\nif __name__ == \"__main__\":\n    sales = Sales()\n    continue_program: bool = True\n    while continue_program:\n        print(\"---- sales management ----\")\n        print(\"1. add product\")\n        print(\"2. read products\")\n        print(\"3. update product\")\n        print(\"4. remove product\")\n        print(\"5. total sales\")\n        print(\"6. product sales\")\n        print(\"7. exit\")\n        option: int = int(ask_value(\"choose an option: \", \"int\"))\n        if option == 1:\n            sales.add_product()\n        elif option == 2:\n            sales.read_products()\n        elif option == 3:\n            sales.update_product()\n        elif option == 4:\n            sales.remove_product()\n        elif option == 5:\n            sales.total_sales()\n        elif option == 6:\n            sales.product_sales()\n        elif option == 7:\n            sales.remove_file()\n            continue_program = False\n        else:\n            print(\"incorrect option, try again.\")\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/rantamhack.py",
    "content": "'''\n* IMPORTANTE: Solo debes subir el fichero de codigo como parte del ejercicio.\n * \n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extension .txt.\n * Añade varias lineas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programacion favorito.\n * Imprime el contenido.\n * Borra el fichero.\n'''\n\nimport os\n\ndef crear_archivo():\n    file = open(\"rantamhack.txt\", \"w\")\n    f = [\"Me llamo Rantam\\n\", \"Mi edad es de 25 años\\n\", \"Mi lenguaje de programacion favorito es python\\n\"]\n    file.writelines(f)\n    file.close()\n    print(\"\\nEl archivo rantamhack.txt ha sido creado\\n\")\n    \ncrear_archivo()\n    \ndef leer_archivo():\n    file = open(\"rantamhack.txt\", \"r\")\n    print(file.read())\n    file.close()\n    \nleer_archivo()\n\n\ndef borrar_archivo():\n    if os.path.exists(\"rantamhack.txt\"):\n        os.remove(\"rantamhack.txt\")\n        print(\"El archivo rantamhack.txt ha sido eliminado\\n\")\n    else:\n        print(\"El archivo no existe\")\n        \nborrar_archivo()    \n\n'''\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestion de ventas que almacena sus datos en un \n * archivo .txt.\n * - Cada producto se guarda en una linea del arhivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - Tambien debe poseer opciones para calcular la venta total y por producto.\n * - La opcion salir borra el .txt.\n'''\n\nstore = \"sales.txt\"\n\nopen(store, \"a\")\n\ndef add_product():\n    name = input(\"Nombre: \")\n    quantity = input(\"Cantidad vendida: \")\n    price = input(\"Precio: \")\n    with open(store, \"a\") as file:\n        file.write(f\"{name}, {quantity}, {price}\\n\")\n        \ndef consult_product():\n    name = input(\"Nombre: \")\n    with open(store, \"r\") as file:\n        for line in file.readlines():\n            if line.split(\", \")[0] == name:\n                print(line)\n                break\n            \ndef update_product():\n    name = input(\"Nombre: \")\n    quantity = input(\"Cantidad: \")            \n    price = input(\"Precio: \")\n    with open(store, \"r\") as file:\n        lines = file.readlines()\n    with open(store, \"w\") as file:\n        for line in lines:\n            if line.split(\", \")[0] == name:\n                file.write(f\"{name}, {quantity}, {price}\\n\")\n            else:\n                file.write(line)\n                \ndef delete_product():\n    name = input(\"Nombre: \")\n    with open(store, \"r\") as file:\n        lines = file.readlines()\n    with open(store, \"w\") as file:\n        for line in lines:\n            if line.split(\", \")[0] != name:\n                file.write(line)\n                                    \ndef read_file():\n    with open(store, \"r\") as file:\n        print(file.read())\n        \ndef product_sales():\n    total = 0\n    name = input(\"Nombre: \")\n    with open(store, \"r\") as file:\n        for line in file.readlines():\n            if line.split(\", \")[0] == name:\n                quantity = float(line.split(\", \")[1])\n                price = float(line.split(\", \")[2])\n                total = quantity * price\n                break\n    print(f\"\\nEl total de las ventas de {name} es: {total}\\n\")\n              \ndef total_sales():\n    total = 0\n    with open(store, \"r\") as file:\n        for line in file.readlines():\n            quantity = float(line.split(\", \")[1])\n            price = float(line.split(\", \")[2])\n            total += quantity * price\n    print(f\"\\nEl total de las ventas es: {total}\\n\")\n    \n    \n\nwhile True: \n    \n    print(\"\\nBienvenido al menu de opciones\\n\")\n\n    print(\"1) Añadir producto\")\n    print(\"2) Consultar producto\")\n    print(\"3) Actualizar producto\")\n    print(\"4) Eliminar producto\")\n    print(\"5) Consultar archivo de productos\")\n    print(\"6) Calculadora de ventas por producto\")    \n    print(\"7) Calculadora de ventas totales\")\n    print(\"8) Salir\")\n    \n    option = input(\"\\nElige la opcion que quieres hacer: \")     \n    \n    if option == \"1\":\n        add_product()\n    elif option == \"2\":\n        consult_product()\n    elif option == \"3\":\n        update_product()\n    elif option == \"4\":\n        delete_product()\n    elif option == \"5\":\n        read_file()\n    elif option == \"6\":\n        product_sales()\n    elif option == \"7\":\n        total_sales()\n    elif option == \"8\":\n        print(\"\\n[+] Saliendo del programa....\\n\")\n        os.remove(\"sales.txt\")\n        break\n    else:\n        print(\"\\nLa opcion elegida no es correcta\")\n    \n        \n    \n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/raulG91.py",
    "content": "\n# Create .txt with filename your Github repository, with your name, age and favurite progaming language\nimport os\n\npath = os.path.join(os.path.dirname(__file__),\"raulG91.txt\")\n\nwith open(path,\"w\") as file:\n    file.write(\"Raul Garcia\"+\"\\n\")\n    file.write(\"32\"+\"\\n\")\n    file.write(\"Python\"+\"\\n\")\n\nfile.close()\n\n#Read the file that we have created\n\nwith open(path,\"r\") as file:\n    for line in file:\n        print(line)\n\n#Remove the file\nos.remove(path)        \n\ndef check_product_file(product_name:str,file:str)->tuple:\n    product = ()\n    try:\n        with open(file,\"r\")as file:\n            for line in file:\n                name,amount,price = line.split(\",\")\n                if name == product_name:    \n                    return (name,amount,price)\n    except Exception as e:\n        pass\n    return product\ndef delete_product(product_name:str,file:str):\n    try:\n        with open(file,\"r+\") as file:\n            lines = file.readlines()\n            file.seek(0)\n\n            for line in lines:\n                name,amount,price = line.split(\",\")\n                if name != product_name:\n                    file.write(line)\n            file.truncate()          \n    except Exception as e:\n        print(\"Error opening the file\")   \ndef update_product(product_name:str,new_amount:int,new_price:float,file:str):\n    try:\n        with open(file,\"r+\") as file:\n            lines = file.readlines()\n            file.seek(0)\n\n            for line in lines:\n                name,amount,price = line.split(\",\")\n                if name == product_name:\n                    file.write(f'{product_name},{new_amount},{new_price}\\n')\n                else:\n                    file.write(line)    \n            file.truncate()          \n    except Exception as e:\n        print(\"Error opening the file\")   \ndef total_sales(file_name,product_name = \"\"):\n    total_amount = 0\n    total_price = 0\n    lines = []\n    try:\n        with open(file_name,\"r\") as file:\n            lines = file.readlines() \n    except Exception as e:\n        print(\"Error opening the file\")  \n                 \n    for line in lines:\n        name,amount,price = line.split(\",\")\n        if product_name != \"\" and name == product_name:\n            amount = int(amount)\n            price = float(price)\n            total_amount +=amount\n            total_price += (price*amount)\n        elif product_name == \"\":\n            amount = int(amount)\n            price = float(price)\n            total_amount +=amount\n            total_price += (price*amount)               \n\n\n    print(f'Total amount: {total_amount} total price: {total_price}')\n\n                          \nfile = os.path.join(os.path.dirname(__file__),\"sales.txt\")\nwhile True:\n    print(\"Choose option: \")\n    print(\"Press 1: Add product\")\n    print(\"Press 2: Check product\")\n    print(\"Press 3: Update product\")\n    print(\"Press 4: To delete product\")\n    print(\"Press 5: Total sales\")\n    print(\"Press 6: Sales for product\")\n    print(\"Press 7: To exit\")\n    option = int(input())\n\n    if option == 1:\n        name = str(input(\"Insert product name: \"))  \n        product = check_product_file(name,file)\n        if not product:\n            amount = int(input(\"Enter amount: \"))\n            price = float(input(\"Insert price: \"))\n            with open(file,\"a\") as f:\n                f.write(f'{name},{amount},{price}\\n')\n        else:\n            print(\"Product already exist in the file\")        \n    elif option == 2:\n        name = str(input(\"Insert product name: \"))\n        product = check_product_file(name,file)\n        if product:\n            print(f'Product: {product[0]} amount: {product[1]} price: {product[2]}')\n        else:\n            print(\"Product doesn't exist in the file\")\n    elif option == 3:\n        name = str(input(\"Insert product name: \"))\n        product = check_product_file(name,file)\n        if product:\n            new_amount = int(input(\"Enter new amount \"))\n            new_price = float(input(\"Insert new price \"))\n            update_product(name,new_amount,new_price,file)\n        else:\n            print(\"Product doesn't exist in the file\")    \n    elif option == 4:\n        name = str(input(\"Insert product name: \"))\n        product = check_product_file(name,file)\n        if product:\n          delete_product(name,file)\n        else:\n            print(\"Product doesn't exist in the file\")\n    elif option == 5:\n        total_sales(file_name=file)\n    elif option == 6:\n        name = str(input(\"Insert product name: \"))\n        product = check_product_file(name,file)\n        if product:\n            total_sales(file_name=file,product_name=name)\n        else:\n            print(\"Product doesn't exist in the file\")                         \n    elif option == 7:\n        try:\n            os.remove(file)\n        except:\n            print(\"Error removing file\")    \n        break\n    else:\n        print(\"Invalid option\")\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/rayn1er.py",
    "content": "import os \n# /*\n#  * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n#  *\n#  * EJERCICIO:\n#  * Desarrolla un programa capaz de crear un archivo que se llame como\n#  * tu usuario de GitHub y tenga la extensión .txt.\n#  * Añade varias líneas en ese fichero:\n#  * - Tu nombre.\n#  * - Edad.\n#  * - Lenguaje de programación favorito.\n#  * Imprime el contenido.\n#  * Borra el fichero.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n#  * archivo .txt.\n#  * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n#  *   [nombre_producto], [cantidad_vendida], [precio].\n#  * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n#  *   actualizar, eliminar productos y salir.\n#  * - También debe poseer opciones para calcular la venta total y por producto.\n#  * - La opción salir borra el .txt.\n#  */\n\nfile = open('rayn1er.txt','w')\nfile.write(\"Raul\")\nfile.write(\"\\n26\")\nfile.write('\\nPython')\nfile.close()\nfile = open('rayn1er.txt','r')\nprint(file.read())\nfile.close()\nos.remove('rayn1er.txt')\n\n#extra\n\nstore = open('store.txt','w')\nstore.close()\n\nwhile True:\n    print(f'''\n        {\"-\" * 25}\n        Gestor de Ventas\n        {\"-\" * 25}\n        Seleccione una opcion\n        1 - Agregar producto\n        2 - Actualizar producto\n        3 - Consultar producto\n        4 - Eliminar producto\n        5 - Ver productos\n        6 - Ver ventas totales\n        7 - ver ventas por producto\n        8 - Salir del Gestor\n''')\n    option = int(input(\"Seleccione una opcion -> \"))\n\n    if option == 1:\n        product_name = input(\"Ingrese el nombre del producto -> \")\n        product_sold = int(input(\"Ingrese la cantidad de elementos vendidos -> \"))\n        product_price = int(input(\"Ingrese el precio del producto -> \"))\n        with open('store.txt','a') as store:\n            store.write(f'{product_name}, {product_sold}, {product_price}\\n')\n            print(\"Sus elementos han sido agregados a la lista\")\n\n    elif option == 2:\n        product_name = input(\"Ingrese el nombre del producto -> \")\n        product_sold = int(input(\"Ingrese la cantidad de elementos vendidos -> \"))\n        product_price = int(input(\"Ingrese el precio del producto -> \"))\n        with open('store.txt', 'r') as store:\n            lines = store.readlines()\n        with open('store.txt', 'w') as store:\n            for line in lines:\n                if line.split(', ')[0] == product_name:\n                    store.write(f'{product_name}, {product_sold}, {product_price}\\n')\n                else:\n                    store.write(lines)\n    \n    elif option == 3:\n        product_name = input(\"Ingrese el nombre del producto -> \")\n        with open('store.txt','r') as store:\n            for line in store.readlines():\n                if line.split()[0] == product_name:\n                    print(line)\n                    break\n            \n\n    elif option == 4:\n        product_name = input(\"Ingrese el nombre del producto -> \")\n        \n        with open('store.txt', 'r') as store:\n            lines = store.readlines()\n        with open('store.txt', 'w') as store:\n            for line in lines:\n                if line.split(', ')[0] != product_name:\n                    store.write(line)\n\n        \n\n    elif option == 5:\n        with open('store.txt','r') as store:\n            print(\"Elementos en la lista\")\n            print(store.read())\n\n    elif option == 6:\n        total = 0\n        with open('store.txt','r') as store:\n            for line in store.readlines():\n                components = line.split(', ')\n                product_sold = int(components[1])\n                product_price = float(components[2])\n                total += product_sold * product_price\n            print(f\"El total es de ventas es de {total}\")\n\n    elif option == 7:\n        product_name = input(\"Ingrese el nombre del producto -> \")\n        total = 0\n        with open('store.txt','r') as store:\n            for line in store.readlines():\n                components = line.split(', ')\n                if components[0] == product_name:\n                    product_sold = int(components[1])\n                    product_price = float(components[2])\n                    total += product_sold * product_price\n                    break\n            print(f\"El total de ventas de {product_name} es de {total}\")\n\n    elif option == 8:\n        print(\"Cerrando el gestor, hasta luego!\")\n        os.remove('store.txt')\n\n    else:\n        print(\"Seleccione una opcion valida \")\n\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/raynerpv2022.py",
    "content": "# /*\n#  * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n#  *\n#  * EJERCICIO:\n#  * Desarrolla un programa capaz de crear un archivo que se llame como\n#  * tu usuario de GitHub y tenga la extensión .txt.\n#  * Añade varias líneas en ese fichero:\n#  * - Tu nombre.\n#  * - Edad.\n#  * - Lenguaje de programación favorito.\n#  * Imprime el contenido.\n#  * Borra el fichero.\n#  *\n\n\n\n# Usando Pathlib\nfrom pathlib import Path as p\n# Usando open y os\nimport os\nprofile = \"NAme : Rayner\\n\"\nprofile+= \"AGe : 45\\n\"\nprofile += \"Languaje : Python, GO\\n\"\nname= \"raynerpv2022.txt\"\n\ndef CreateFile(name):\n\n    file = p(name)\n    \n    try:\n        file.write_text(profile)\n    except Exception as e:\n        print(\"Ocurrio error inesperado\")\n    else:\n        print(\"Archivo creado con datos del usuario de github\")\n    finally:\n        print(\"Terminada la creacion\")\n    \n\ndef Readfile(name):\n    file = p(name)\n    \n    try:\n        datos = file.read_text()\n    except Exception as e:\n        print(\"Ocurrio error inesperado\")\n    else:\n        print(datos)\n    finally:\n        print( \"FIn de lectura\")\n    \n    \n\ndef RemoveFile(name):\n    file = p(name)\n    try:\n        file.unlink()\n    except Exception as e:\n        print(\"Ocurrio error inesperado\")\n    else:\n        print(\"Archivo eliminado con exito\")\n    finally:\n        print(\"eliminacion concluida\")\n\n\n\ndef ejercicio():\n    # path\n    CreateFile(name)\n    Readfile(name)\n    RemoveFile(name)\n    # os\n    open_CreateFile(name)\n    open_ReadFile(name)\n    open_DeleteFile(name)\n\n\n\n \ndef open_CreateFile(name):\n    try:\n\n        with open(name,\"w+\") as f:\n            f.write(profile)\n    except Exception as e:\n        print(\"Ocurrio error inesperado\")\n    else:\n        print(\"Archivo creado con exito\")\n    finally:\n        print(\"Finalizado CREAR\")\n\n            \n\ndef open_ReadFile(name):\n    try:\n\n        with open(name,\"r\") as f:\n            data = f.read()\n    except Exception as e:\n        print(\"Ocurrio error inesperado\")\n    else:\n        print(data)\n    finally:\n        print(\"Finalizado LEER\")\n\ndef open_DeleteFile(name):\n    try:\n\n        os.remove(name)\n    except Exception as e:\n        print(\"Ocurrio error inesperado\")\n    else:\n        print(\"Archivo eliminado\")\n    finally:\n        print(\"Finalizado ELIMINAR\")\n\n\n\n##  * DIFICULTAD EXTRA (opcional):\n#  * Desarrolla un programa de gestión de ventas que almacena sus datos en un\n#  * archivo .txt.\n#  * - Cada producto se guarda en una línea del arhivo de la siguiente manera:\n#  *   [nombre_producto], [cantidad_vendida], [precio].\n#  * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n#  *   actualizar, eliminar productos y salir.\n#  * - También debe poseer opciones para calcular la venta total y por producto.\n#  * - La opción salir borra el .txt.\n#  */\n\ndef add_prod(name):\n    nombre =  input(\"Nombre : \")\n    cantidad =  input(\"Cantidad vendida : \")\n    precio = input(\"Precio de venta : \")\n    with open(name,\"a\") as f:\n        f.write(f\"{nombre},  {cantidad}, {precio}\\n\")\n         \n    print(\"archivo creado\")\n\ndef exit(name):\n    print(\"Al salir se eleiminara el archivo...si existe\")\n    try:\n        os.remove(name)\n    except:\n        print(\"Archivo no exste\")\n    else:\n        print(\"Archivo eliminado...\")\n    finally:\n        print(\" saliendo ...\")\n\ndef consultar(name):\n    with open(name,\"r\") as f:\n        print(\"Lista de todos los productos\")\n        print(\"Nombre\\tCantidad\\tPrecio\")\n        for linea in f:\n             linea  = linea.strip()\n             print(linea)\n    \n     \ndef buscar_item(name) :\n    prod = input(\"Nombre : \")\n    with open(name,\"r\") as f:\n        lineas = f.readlines()\n        \n    try:\n        pass\n        lista_nombre = [linea.strip().split(\", \")[0] for linea in lineas]\n        index = lista_nombre.index(prod)\n\n        return index, lineas\n    except ValueError:\n        return -1,[]\n\ndef consultar_producto(name):\n     \n    index, lineas = buscar_item(name)\n    if index == -1:\n        print(\"Producto no encontrado\")\n    else:\n        print(lineas[index])\n\n\n\n\n    \n                \ndef actualizar(name):\n  \n            index,lineas = buscar_item(name)\n            if index == -1 :\n                print(\"Producto no encontrado\")\n            else:\n                \n                ncantidad = input(\"Emtre NUeva Cantidad del producto : \")\n                nprecio = input(\"Entre Nuevo precio del producto : \")\n                temp =  f\"{lineas[index].split(\", \")[0]}, {ncantidad}, {nprecio}\\n\"\n                lineas.pop(index)\n                lineas.insert(index,temp)\n                with open(name,\"w\") as f:\n                  f.writelines(lineas)\n                  print(\"Producto actualizado\")\n               \n            \n     \n        \n\n\ndef eliminar(name):\n     \n            index,lineas = buscar_item(name)\n            if index == -1 :\n                print(\"Producto no encontrado\")\n            else:\n                deleteItem = lineas.pop(index)\n                print(f\"{deleteItem} eliminado\")\n            with open(name,\"w\") as f:\n                f.writelines(lineas)\n\n\ndef ventasTotales(name):\n    \n    with open(name,\"r\") as f:\n        lineas = f.readlines()\n        Total = 0\n        for linea in lineas:\n            linea = linea.strip().split(\", \")\n            print(linea) \n            Total+= int(linea[1])*int(linea[2])\n        print(\"Ventas Totales : \", Total)\n\n\n\ndef ventasTotalesProducto(name):\n            print(\" *** Ventas Totales por Producto ***\")\n            index,lineas = buscar_item(name)\n            if index == -1 :\n                print(\"Producto no encontrado\")\n            else:\n                total_p = int(lineas[index].split(\", \")[1])*int(lineas[index].split(\", \")[2])\n                print(f\" Del product {lineas[index].split(\", \")[0]} se vendieron {total_p}\")  \n                          \n\n\ndef Gestion():\n    name_file = \"ventas.txt\"\n    while True:\n        print(\" *********** Gestion de Ventas por Productos***********\")\n        print(\"1 - Anadir\")\n        print(\"2 - Consultar un producto\")\n        print(\"3 - MOstrar todos\")\n        print(\"4 - Actualizar\")\n        print(\"5 - Eliminar\")\n        print(\"6 - Ventas totales\")\n        print(\"7 - Ventas totales por producto\")\n        print(\"8 - Salir\")\n        op = input()\n        match op:\n            case \"1\":\n                add_prod(name_file)\n            case \"2\":\n                consultar_producto(name_file)\n            case \"3\":\n                consultar(name_file)\n            case \"4\":\n                actualizar(name_file)\n            case \"5\":\n                eliminar(name_file)\n            case \"6\":\n                 ventasTotales(name_file)\n            case \"7\":\n                ventasTotalesProducto(name_file)\n            case \"8\":\n                exit(name_file)\n                break\n            case _:\n                print(\"Opcion Invalida 1-5 \")\n\n\n\n\ndef main():\n    while True:\n        print(\"     opcionnes\")  \n        print(\"1- Ejercicio\")      \n        print(\"2- Extra\")  \n        print(\"3 - Salir\")\n        op = input() \n        match op:\n            case \"1\":\n                ejercicio()\n            case \"2\":\n                Gestion()\n            case \"3\":\n               break\n            case _:\n                print(\"Opcion Invalida 1-3 \")\n\nmain()\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/restevean.py",
    "content": "\"\"\"\nExercise:\n\"\"\"\nimport os\n\n\ndef create_txt():\n    with open(\"restevean.txt\", \"w\") as file:\n        file.write(\"Name: Rafael Esteve\\nAge: 51\\nPreferred coding language: Python\")\n        print(\"File created and filled\")\n    with open(\"restevean.txt\", \"r\") as file:\n        print(file.read())\n        file.close()\n\n    os.remove(\"restevean.txt\")\n    print(\"File deleted\")\n\n\n\"\"\"\nExtra\n\"\"\"\n\n\nclass Product:\n    def __init__(self, name, quantity, price):\n        self.name = name\n        self.quantity = quantity\n        self.price = price\n\n\nclass Inventory:\n\n    def __init__(self, filepath):\n        self.filepath = filepath\n        self.current_products = self.load_products()\n        self.added_products = []\n\n    def load_products(self):\n        products = []\n        try:\n            with open(self.filepath, 'r') as file:\n                for line in file:\n                    name, quantity, price = line.strip().split(',')\n                    products.append(Product(name, int(quantity), float(price)))\n        except FileNotFoundError:\n            pass\n\n        return products\n\n    def save_products(self):\n        with open(self.filepath, 'w') as file:\n            for product in self.current_products:\n                file.write(f'{product.name},{product.quantity},{product.price}\\n')\n\n    def delete_file(self):\n        os.remove(self.filepath)\n\n    def add_product(self, name, quantity, price):\n        if not self.get_product(name):  # no permitir productos duplicados\n            new_product = Product(name, quantity, price)\n            self.current_products.append(new_product)\n            self.added_products.append(new_product)\n            self.save_products()\n        else:\n            print(\"This product already exists.\")\n\n    def get_product(self, name):\n        for product in self.current_products:\n            if product.name == name:\n                return product\n\n    def update_product(self, name, quantity, price):\n        product = self.get_product(name)\n        if product is not None:\n            product.quantity = quantity\n            product.price = price\n            self.save_products()\n\n    def delete_product(self, name):\n        product = self.get_product(name)\n        if product:\n            self.current_products.remove(product)\n            if product in self.added_products:\n                self.added_products.remove(product)\n            self.save_products()\n\n    def total_sales(self):\n        return sum([product.quantity * product.price for product in self.current_products])\n\n    def sales_by_product(self, name):\n        product = self.get_product(name)\n        if product is not None:\n            return product.quantity * product.price\n        return 0\n\n\ndef main():\n    inventory = Inventory('sales.txt')\n\n    while True:\n        print('\\n1. Add product')\n        print('2. View products')\n        print('3. Update')\n        print('4. Delete a product')\n        print('5. Total sales')\n        print('6. Product sales')\n        print('7. Exit')\n\n        action = int(input('Choose option: '))\n\n        if action == 1:\n            name = input('Product name: ')\n            while True:\n                try:\n                    quantity = int(input('Quantity sold: '))\n                    break\n                except ValueError:\n                    print(\"You have input an integer for the sold quantity.\")\n            price = float(input('Unit price: ').replace(',', '.'))\n            inventory.add_product(name, quantity, price)\n\n        elif action == 2:  # nueva opción de consulta\n            if inventory.added_products:\n                for product in inventory.added_products:\n                    print(f'Name: {product.name}, Quantity: {product.quantity}, Price: {product.price}')\n            else:\n                print('There are no products added.')\n\n        elif action == 3:\n            name = input('Product name: ')\n            quantity = int(input('New quantity: '))\n            price = float(input('Unit price: ').replace(',', '.'))\n            inventory.update_product(name, quantity, price)\n\n        elif action == 4:\n            name = input('Product name: ')\n            inventory.delete_product(name)\n\n        elif action == 5:\n            print(f'Total sales: ${inventory.total_sales():.2f}')\n\n        elif action == 6:\n            name = input('Product name: ')\n            print(f'{name} sales amount: ${inventory.sales_by_product(name):.2f}')\n\n        elif action == 7:\n            inventory.delete_file()\n            break\n\n        else:\n            print('Invalid option. Try again.')\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/rigo93acosta.py",
    "content": "'''\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n * \n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n * archivo .txt.\n * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n */\n'''\n\n## Libraries\nimport os\n\n'''\nEjercicio\n'''\n\nfilename = 'rigo93acosta.txt'\n\nwith open(filename, 'w') as open_file:\n    open_file.write('Rigo Acosta\\n')\n    open_file.write('30\\n')\n    open_file.write('Python\\n') \n\nwith open(filename, 'r') as open_file:\n    print(open_file.read())\n\nos.remove(filename)\n\n'''\nExtra\n'''\n\nfilename = 'ventas.txt'\nopen(filename, 'a').close()\n\nwhile True:\n    print('1. Añadir producto')\n    print('2. Consultar producto')\n    print('3. Mostrar productos')\n    print('4. Actualizar producto')\n    print('5. Eliminar producto')\n    print('6. Venta total')\n    print('7. Venta por producto')\n    print('8. Salir')\n\n    option = int(input('Opción: '))\n    \n    if option == 1:\n        producto = input('Nombre del producto: ')\n        cantidad = input('Cantidad vendida: ')\n        precio = input('Precio: ')\n        with open(filename, 'a') as open_file:\n            open_file.write(f'{producto}, {cantidad}, {precio}\\n')\n\n    elif option == 2:\n        producto = input('Nombre del producto: ')\n\n        with open(filename, 'r') as open_file:\n            for line in open_file.readlines():\n                if line.split(', ')[0] == producto:\n                    temp = line.split(', ')\n                    print(f'Producto: {temp[0]} - Cantidad: {temp[1]} - Precio: {temp[2]}')     \n    \n    elif option == 3:\n        with open(filename, 'r') as open_file:\n            for line in open_file.readlines():\n                temp = line.split(', ')\n                print(f'Producto: {temp[0]} - Cantidad: {temp[1]} - Precio: {temp[2]}')\n    \n    elif option == 4:\n        producto = input('Nombre del producto: ')\n        cantidad = input('Cantidad vendida: ')\n        precio = input('Precio: ')\n       \n        with open(filename, 'r') as open_file:\n            lines = open_file.readlines()\n        \n        with open(filename, 'w') as open_file:\n            for line in lines:\n                if line.split(', ')[0] == producto:\n                    open_file.write(f'{producto}, {cantidad}, {precio}\\n')\n                else:\n                    open_file.write(line)\n\n    elif option == 5:\n        \n        producto = input('Nombre del producto: ')\n        \n        with open(filename, 'r') as open_file:\n            lines = open_file.readlines()\n        \n        with open(filename, 'w') as open_file:\n            for line in lines:\n                if line.split(', ')[0] != producto:\n                    open_file.write(line)\n\n    elif option == 6:\n        \n        with open(filename, 'r') as open_file:\n            lines = open_file.readlines()\n        total = 0\n        \n        for line in lines:\n            total += int(line.split(', ')[1]) * float(line.split(', ')[2])\n        print(f'Venta total: {total}')\n\n    elif option == 7:\n        \n        producto = input('Nombre del producto: ')\n        \n        with open(filename, 'r') as open_file:\n            lines = open_file.readlines()\n        for line in lines:\n            if line.split(', ')[0] == producto:\n                print(f'Venta de {line.split(\", \")[0]}: {int(line.split(\", \")[1]) * float(line.split(\", \")[2])}')\n\n    elif option == 8:\n        os.remove(filename)\n        break\n    \n    else:\n        print('Opción no válida, intenta de nuevo.')"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/santiagobailleres.py",
    "content": "'''EJERCICIO:\nDesarrolla un programa capaz de crear un archivo que se llame como\ntu usuario de GitHub y tenga la extensión .txt.\nAñade varias líneas en ese fichero:\n- Tu nombre.\n- Edad.\n- Lenguaje de programación favorito.\nImprime el contenido.\nBorra el fichero.\nDIFICULTAD EXTRA (opcional):\nDesarrolla un programa de gestión de ventas que almacena sus datos en un \narchivo .txt.\n- Cada producto se guarda en una línea del archivo de la siguiente manera:\n  [nombre_producto], [cantidad_vendida], [precio].\n- Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n  actualizar, eliminar productos y salir.\n- También debe poseer opciones para calcular la venta total y por producto.\n- La opción salir borra el .txt.'''\n\n# Solución: \nimport os\nfilename = 'santiagobailleres.txt'\nwith open(filename, 'w') as file:\n    file.write('Santiago Bailleres\\n')\n    file.write('25\\n')\n    file.write('Python\\n')\n\nwith open(filename, 'r') as file:\n    print(file.read())\n\nos.remove(filename)\n\n# EXTRA\nfilename = 'ventas.txt'\nopen(filename, 'a') # 'a' para añadir al final del archivo\n\nwhile True:\n    print(\"1. Añadir producto\")\n    print(\"2. Consultar producto\")\n    print(\"3. Actualizar producto\")\n    print(\"4. Eliminar producto\")\n    print(\"5. Mostrar productos\")\n    print(\"6. Calcular venta total\")\n    print(\"7. Calcular venta por producto\")\n    print(\"8. Salir\")\n    \n    option = input(\"Selecciona una opción: \")\n    if option == \"1\": # Añadir producto\n        name = input(\"Nombre del producto: \")\n        quantity = input(\"Cantidad vendida: \")\n        price = input(\"Precio: \")\n        with open(filename, 'a') as file:\n            file.write(f'{name}, {quantity}, {price}\\n')\n    elif option == \"2\": # Consultar producto\n        name = input(\"Nombre del producto: \")\n        with open(filename, 'r') as file:\n            for line in file.readlines(): # Lee todas las lineas\n                if line.split(', ')[0] == name:\n                    print(line)\n                    break\n    elif option == \"3\": # Actualizar producto\n        name = input(\"Nombre del producto: \")\n        quantity = input(\"Cantidad vendida: \")\n        price = input(\"Precio: \")\n        with open(filename, 'r') as file:\n            lines = file.readlines()\n        with open(filename, 'w') as file:\n            for line in lines:\n                if line.split(', ')[0] == name:\n                    file.write(f'{name}, {quantity}, {price}\\n')\n                else:\n                    file.write(line)\n    elif option == \"4\": # Eliminar producto\n        name = input(\"Nombre del producto: \")\n        with open(filename, 'r') as file:\n            lines = file.readlines()\n        with open(filename, 'w') as file:\n            for line in lines:\n                if line.split(', ')[0] != name: # este if es para no escribir la linea que se quiere eliminar\n                    file.write(line) # Escribe todas las lineas menos la que se quiere eliminar\n    elif option == \"5\": # Mostrar productos\n        with open(filename, 'r') as file:\n            print(file.read())\n    elif option == \"6\": # Calcular venta total\n        tot = 0\n        with open(filename, 'r') as file:\n            for line in file.readlines():\n                tot += int(line.split(', ')[1]) * float(line.split(', ')[2])\n        print(f'Venta total: {tot}')\n    elif option == \"7\": # Calcular venta por producto\n        name = input(\"Nombre del producto: \")\n        tot = 0\n        with open(filename, 'r') as file:\n            for line in file.readlines():\n                if line.split(', ')[0] == name:\n                    tot += int(line.split(', ')[1]) * float(line.split(', ')[2])\n                    break\n        print(f'Venta de {name}: {tot}')\n    elif option == \"8\": # Salir\n        os.remove(filename)\n        break\n    else:\n        print(\"Opción no válida\")"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/santyjl.py",
    "content": "\"\"\"\n/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n * \n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n * archivo .txt.\n * - Cada producto se guarda en una línea del arhivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n */\n\"\"\"\n\nimport os\n\nnombre_usuario_github = \"santyjl\"\nnombre_archivo = nombre_usuario_github + \".txt\"\n\nwith open(nombre_archivo, \"w\") as archivo: #with para manejar ficheros , w : escribe en el fichero\n    archivo.write(\"Nombre: Santiago José López Ayala\\n\")\n    archivo.write(\"Edad: 14 años\\n\")\n    archivo.write(\"Lenguaje de programación favorito: Python\\n\")\n\nwith open(nombre_archivo, \"r\") as archivo: # r : lee el archivo\n    contenido = archivo.read()\n\nprint(\"Contenido del archivo:\")\nprint(contenido)\n\nos.remove(nombre_archivo)\nprint(\"El archivo ha sido borrado.\")\n\n###EXTRA###\narchivo_de_ventas = \"venta.txt\"\nprint(\"Hola mundo, tienes las siguientes opciones para ejecutar en 'venta':\")\n\nwhile True:\n    opcion = int(input(\"\"\"\n    1- Añadir producto\n    2- Consultar productos\n    3- Actualizar producto\n    4- Eliminar producto\n    5- Calcular venta total\n    6- Calcular venta por producto\n    7- Salir del programa\n    -- Elija según el índice: \"\"\"))\n\n    if opcion == 1:\n        nombre = input(\"Introduce el nombre del producto: \")\n        precio = float(input(\"Introduce el precio del producto: \"))\n\n        with open(archivo_de_ventas, \"a\") as archivo: #a : añade un texto a al txt\n            archivo.write(f\"{nombre} / {precio}\\n\")\n\n        print(\"Producto añadido\")\n\n    elif opcion == 2:\n        with open(archivo_de_ventas, \"r\") as archivo: #lee el archivo\n            contenido = archivo.read()\n\n        print(contenido)\n\n    elif opcion == 3:\n        nombre = input(\"Introduce el nombre del producto a actualizar: \")\n        nuevo_nombre = input(\"Introduce el nuevo nombre del producto: \")\n        nuevo_precio = float(input(\"Introduce el nuevo precio del producto: \"))\n\n        with open(archivo_de_ventas, \"r\") as archivo:\n            lineas = archivo.readlines() #crea un iterable de las lineas\n\n        with open(archivo_de_ventas, \"w\") as archivo:\n            for linea in lineas:\n                if nombre in linea:\n                    archivo.write(f\"{nuevo_nombre} / {nuevo_precio}\\n\")\n                else:\n                    archivo.write(linea)\n\n        print(\"Producto actualizado\")\n\n    elif opcion == 4:\n        nombre = input(\"Introduce el nombre del producto a eliminar: \")\n\n        with open(archivo_de_ventas, \"r\") as archivo:\n            lineas = archivo.readlines()\n\n        with open(archivo_de_ventas, \"w\") as archivo:\n            for linea in lineas:\n                if nombre not in linea: #si el nombre no esta en el iterable lo vuelce a escribir\n                    archivo.write(linea)\n\n        print(\"Producto eliminado\")\n\n    elif opcion == 5:\n        total_ventas = 0\n\n        with open(archivo_de_ventas, \"r\") as archivo:\n            lineas = archivo.readlines()\n            for linea in lineas:\n                partes = linea.split(\" / \") #el divisor del nombre y el precio es / entonces el segundo elemento es el precio\n                total_ventas += float(partes[1])\n\n        print(f\"La venta total es: {round(total_ventas , 2)}\")\n\n    elif opcion == 6:\n        nombre = input(\"Introduce el nombre del producto para calcular su venta: \")\n        venta_producto = 0\n\n        with open(archivo_de_ventas, \"r\") as archivo:\n            lineas = archivo.readlines()\n            for linea in lineas:\n                partes = linea.split(\" / \")\n                if partes[0] == nombre:\n                    venta_producto += float(partes[1])\n\n        print(f\"La venta del producto {nombre} es: {venta_producto}\")\n\n    elif opcion == 7:\n        print(\"Saliendo del programa...\")\n        os.remove(archivo_de_ventas)\n        break\n\n    else:\n        print(\"Opción inválida. Por favor, elija una opción válida del menú.\")\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/sorubadguy.py",
    "content": "from os import remove\nfrom os import system\n\"\"\"\n*Ficheros\n\"\"\"\n\ntry:\n    archivo = open(\"sorubadguy.txt\", \"x\") #?crea el archivo, de existir, tira error\nexcept:\n    archivo = open(\"sorubadguy.txt\", \"w\")#?sobreescribe un archivo existente, de no existir lo crea\nfinally:\n    print(\"archivo creado\")\n\narchivo.write(\"Sorubadguy\\n\")#?añade contenido al archivo\narchivo.write(\"30\\n\")\narchivo.write(\"Python\\n\")\narchivo.close()\narchivo = open(\"sorubadguy.txt\",\"r\")\nprint(archivo.read())\narchivo.close()\nremove(\"sorubadguy.txt\")\n\ninput(\"pulse Enter para continuar\")\n\"\"\"\n!Extra\n\"\"\"\nnombre_archivo = \"ventas_realizadas.txt\"\n\ntry:\n    archivo = open(nombre_archivo, \"a\")\nexcept:\n    archivo = open(nombre_archivo, \"w\")\nfinally:\n    archivo.close()\n\ndef levantar_datos_archivo(nombre_archivo):\n    productos = {}\n    archivo = open(nombre_archivo, \"r\")\n    prod = archivo.readlines()\n    for i in prod:\n        j = i.split(\",\")\n        productos[j[0]] = [float(j[1]), float(j[2])]\n    archivo.close()\n    return productos\n\ndef ventas(nombre_archivo):\n    \n\n    op = 1\n    while op != \"0\":\n        #os.system(\"cls\")\n        print(\"Ingrese la opcion deseada:\")\n        print(\"1: Añadir Producto\")\n        print(\"2: Consultar Producto\")\n        print(\"3: Consultar Venta Total\")\n        print(\"4: Actualizar Producto\")\n        print(\"5: Eliminar Producto\")\n        print(\"0: Salir\")\n        op = input(\"Opcion: \")\n        match op:\n            case \"1\":\n                producto = []\n                archivo = open(nombre_archivo, \"a\")\n                print(\"Ingrese Los datos del productos:\")\n                producto.append(input(\"Ingrese Nombre del Producto: \"))\n                producto.append(input(\"Ingrese Cantidad Vendida: \"))\n                producto.append(input(\"Ingrese presio: \"))\n                for i in (range(0, len(producto))):\n                    if i == len(producto)-1:\n                        archivo.write(producto[i]+\"\\n\")\n                    else:\n                        archivo.write(producto[i]+\",\")\n                archivo.close()\n            case \"2\":\n                productos = levantar_datos_archivo(nombre_archivo)\n                print(\"Productos: \")\n                for i in productos.keys():\n                    print(i)\n                producto_mostrar = input(\"Que producto desea consultar?: \")\n                os.system(\"cls\")\n                print(f\"{producto_mostrar}: \\n se han vendido {productos[producto_mostrar][0]} unidades a ${productos[producto_mostrar][1]}\\n ganancia: {productos[producto_mostrar][0] * productos[producto_mostrar][1]}\")\n            case \"3\":\n                productos = levantar_datos_archivo(nombre_archivo)\n                ventas_totales = 0\n                for i in productos:\n                    ventas_totales += productos[i][0]*productos[i][1]\n                print(f\"Las ventas totales dan un valor de: ${ventas_totales}\")\n            case \"4\":\n                productos = levantar_datos_archivo(nombre_archivo)\n                print(\"Actualizar\")\n                if productos != {}:\n                    for i in productos:\n                        print(i)\n                    producot_actualizar = input(\"Ingrese el producto a actualizar\")\n                    productos[producot_actualizar][0] += float(input(\"Ingrese nueva cantidad vendida: \"))\n                    productos[producot_actualizar][1] = float(input(\"Ingrese nuevo precio del producto: \"))\n                    archivo = open(nombre_archivo, \"w\")\n                    for i in productos:\n                        archivo.write(f\"{i},{str(productos[i][0])},{str(productos[i][1])}\\n\")\n                    archivo.close()\n                else:\n                    print(\"No hay productos\")\n            case \"4\":\n                productos = levantar_datos_archivo(nombre_archivo)\n                print(\"Eliminar\")\n                if productos != {}:\n                    for i in productos:\n                        print(i)\n                    productos.pop(input(\"Ingrese el elemento a eliminar: \"))\n                    archivo = open(nombre_archivo, \"w\")\n                    for i in productos:\n                        archivo.write(f\"{i},{str(productos[i][0])},{str(productos[i][1])}\\n\")\n                    archivo.close()                    \n            case \"0\":\n                remove(nombre_archivo)\n                print(\"El programa se cerrara, Adios\")\n            case \"_\":\n                print(\"Opcion incorrecta\")\n\n\nventas(nombre_archivo)"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/sperezsa.py",
    "content": "#11 - FICHERO\n\nimport os\n\nfile_name = 'sperezsa.txt'\n\nwith open(file_name, 'w') as f:\n    f.write('Sergio\\n')\n    f.write('44\\n')\n    f.write('Python\\n')\n    \nwith open(file_name, 'r') as f: \n    lineas = f.read()\n    print(lineas)  \n\nos.remove(file_name)\n\n\n\"\"\"\nExtra\n\"\"\"\n\nfile_name = 'ventas.txt'\n\nwhile True:\n    sel = input(\"Opciones: \\n\" \\\n                \"1. Añadir venta \\n\" \\\n                \"2. Consultar venta \\n\" \\\n                \"3. Actualizar venta \\n\" \\\n                \"4. Borrar venta \\n\" \\\n                \"5. Mostrar ventas \\n\" \\\n                \"6. Cálculo venta total \\n\" \\\n                \"7. Cálculo venta por producto \\n\" \\\n                \"8. Salir \\n\" \\\n                \"-> Opción: \")\n    \n    if sel == '1':\n        prod = input(\"Producto: \")\n        cant = input(\"Cantidad: \")\n        prec = input(\"Precio: \")\n        with open(file_name, 'a') as f:\n            f.write(f\"{prod}, {cant}, {prec}\\n\")\n    elif sel == '2':\n        prod = input(\"Producto: \")      \n        with open(file_name, 'r') as f:\n            for line in f.readlines():\n                if line.split(\", \")[0] == prod:\n                    print(line)\n                    break\n    elif sel == '3':\n        prod = input(\"Producto: \")\n        cant = input(\"Cantidad: \")\n        prec = input(\"Precio: \")   \n        with open(file_name, 'r') as f:\n            lines = f.readlines()\n        with open(file_name, 'w') as f:\n            for line in lines:\n                if line.split(\", \")[0] == prod:\n                    f.write(f\"{prod}, {cant}, {prec}\\n\")\n                else:\n                    f.write(line)\n    elif sel == '4': \n        prod = input(\"Producto: \")      \n        with open(file_name, 'r') as f: \n            lines = f.readlines()\n        with open(file_name, 'w') as f:\n           for line in lines:\n               if line.split(\", \")[0] == prod:\n                   f.write(\"\")\n               else:\n                   f.write(line)\n    elif sel == '5': \n        with open(file_name, 'r') as f: \n            print(f.read())\n    elif sel == '6': \n        v_total = 0\n        with open(file_name, 'r') as f: \n            lines = f.readlines()\n            for line in lines:\n                v_total += int(line.split(\", \")[1]) * int(line.split(\", \")[2])\n        print(f\"Ventas totales: {v_total}\")        \n    elif sel == '7': \n        v_producto = {}\n        with open(file_name, 'r') as f: \n            lines = f.readlines()\n            for line in lines:\n                print()\n                if line.split(\", \")[0] in v_producto.keys(): \n                    v_producto[line.split(\", \")[0]] += int(line.split(\", \")[1]) * int(line.split(\", \")[2])\n                else:\n                    v_producto[line.split(\", \")[0]] = int(line.split(\", \")[1]) * int(line.split(\", \")[2])\n        print(f\"Ventas por producto: {v_producto}\")   \n    elif sel == '8': \n        print(\"Salir!\")\n        os.remove(file_name)\n        break\n    else: \n        print(\"Opción no válida. Selecciona otra opción.\")\n        \n        \n        \n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/switchdays.py",
    "content": "\"\"\"\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n\"\"\"\n\nimport os\n\ndef files():\n\n    # Abrir el archivo en modo escritura y lectura\n    with open(\"switchdays.txt\", \"w+\") as my_file:\n\n        # Escribir líneas en el archivo\n        my_file.writelines([\"Nombre: Víctor Meseguer\\n\", \"Edad: 25\\n\", \"Lenguaje favorito: Python\\n\"])\n\n        print(f'El archivo {my_file.name} ha sido creado.')\n\n        # Volver al principio del archivo para leerlo\n        my_file.seek(0)\n\n        # Leer y mostrar las líneas del archivo\n        for line in my_file.readlines():\n            print(line.strip())\n\n    # Eliminar el archivo después de cerrarlo\n    os.remove(\"switchdays.txt\")\n    print(f'El archivo switchdays.txt ha sido eliminado.')\n\nfiles()\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n * archivo .txt.\n * - Cada producto se guarda en una línea del arhivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n\"\"\"\n\nimport os\n\n# Función para añadir un producto al archivo\ndef agregar_producto(archivo):\n    nombre = input(\"Introduce el nombre del producto: \")\n    cantidad = input(\"Introduce la cantidad vendida: \")\n    precio = input(\"Introduce el precio: \")\n    linea = f\"{nombre}, {cantidad}, {precio}\\n\"\n    archivo.write(linea)\n    print(\"Producto añadido correctamente.\")\n\n# Función para consultar todos los productos\ndef consultar_productos(archivo):\n    archivo.seek(0)\n    print(\"Productos:\")\n    for linea in archivo.readlines():\n        print(linea.strip())\n\n# Función para actualizar un producto\ndef actualizar_producto(archivo):\n    nombre_actualizar = input(\"Introduce el nombre del producto a actualizar: \")\n    lineas = archivo.readlines()\n    archivo.seek(0)\n    archivo.truncate()\n    for linea in lineas:\n        if nombre_actualizar not in linea:\n            archivo.write(linea)\n        else:\n            agregar_producto(archivo)\n    print(\"Producto actualizado correctamente.\")\n\n# Función para eliminar un producto\ndef eliminar_producto(archivo):\n    nombre_eliminar = input(\"Introduce el nombre del producto a eliminar: \")\n    lineas = archivo.readlines()\n    archivo.seek(0)\n    archivo.truncate()\n    for linea in lineas:\n        if nombre_eliminar not in linea:\n            archivo.write(linea)\n    print(\"Producto eliminado correctamente.\")\n\n# Función para calcular la venta total\ndef calcular_venta_total(archivo):\n    archivo.seek(0)\n    venta_total = sum([float(linea.split(\", \")[1]) * float(linea.split(\", \")[2]) for linea in archivo.readlines()])\n    print(f\"Venta total: {venta_total}\")\n\n# Función para calcular la venta por producto\ndef calcular_venta_producto(archivo):\n    nombre_producto = input(\"Introduce el nombre del producto: \")\n    archivo.seek(0)\n    for linea in archivo.readlines():\n        if nombre_producto in linea:\n            cantidad = float(linea.split(\", \")[1])\n            precio = float(linea.split(\", \")[2])\n            venta_producto = cantidad * precio\n            print(f\"Venta del producto {nombre_producto}: {venta_producto}\")\n            return\n    print(\"Producto no encontrado.\")\n\n# Función principal\ndef main():\n    archivo = open(\"ventas.txt\", \"a+\")\n    while True:\n        print(\"\\n--- Menú ---\")\n        print(\"1. Añadir producto\")\n        print(\"2. Consultar productos\")\n        print(\"3. Actualizar producto\")\n        print(\"4. Eliminar producto\")\n        print(\"5. Calcular venta total\")\n        print(\"6. Calcular venta por producto\")\n        print(\"7. Salir\")\n\n        opcion = input(\"Selecciona una opción: \")\n\n        if opcion == \"1\":\n            agregar_producto(archivo)\n        elif opcion == \"2\":\n            consultar_productos(archivo)\n        elif opcion == \"3\":\n            actualizar_producto(archivo)\n        elif opcion == \"4\":\n            eliminar_producto(archivo)\n        elif opcion == \"5\":\n            calcular_venta_total(archivo)\n        elif opcion == \"6\":\n            calcular_venta_producto(archivo)\n        elif opcion == \"7\":\n            archivo.close()\n            os.remove(\"ventas.txt\")\n            print(\"Archivo eliminado. ¡Hasta luego!\")\n            break\n        else:\n            print(\"Opción no válida.\")\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/tito-delpino.py",
    "content": "#  * EJERCICIO:\n#  * Desarrolla un programa capaz de crear un archivo que se llame como\n#  * tu usuario de GitHub y tenga la extensión .txt.\n#  * Añade varias líneas en ese fichero:\n#  * - Tu nombre.\n#  * - Edad.\n#  * - Lenguaje de programación favorito.\n#  * Imprime el contenido.\n#  * Borra el fichero.\n\nimport os\n\nfile_name = \"tito-delpino.txt\"\n\nwith open(file_name, \"w\") as file:\n  file.write('Alvaro Del Pino\\n')\n  file.write('37\\n')\n  file.write('Python')\n\nwith open(file_name, \"r\") as file:\n  print(file.read())\n\n  os.remove(file_name)\n\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n#  * archivo .txt.\n#  * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n#  *   [nombre_producto], [cantidad_vendida], [precio].\n#  * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n#  *   actualizar, eliminar productos y salir.\n#  * - También debe poseer opciones para calcular la venta total y por producto.\n#  * - La opción salir borra el .txt.\n\n# 1- agregar producto al listado\ndef agregar_producto(nombre_listado):\n  producto = input(\"Indica el nombre del producto a agregar: \")\n  precio = input(\"Indica el precio unitario: \")\n  vendidos = input(\"Indica la cantidad vendida: \")\n\n  with open(nombre_listado, 'a') as archivo:\n    archivo.write(f\"{producto}, {precio}, {vendidos}\\n\")\n\n# 2- imprimir por pantalla el listado\ndef ver_listado(nombre_listado):\n    with open(nombre_listado, 'r') as archivo:\n      contenido = archivo.read()\n      if contenido == '':\n        print(\"Archivo vacio, agrega un producto\")\n      else:\n        print(f\"-Listado productos-\\n{contenido}\")\n\n# 3- actualizar producto\ndef actualizar_producto(nombre_listado):\n  producto = input(\"Indica el nombre del producto a actualizar: \")\n\n\n  with open(nombre_listado, 'r') as archivo:\n    lineas = archivo.readlines()\n  \n  linea_nueva = []\n  existe = False\n\n  for linea in lineas:\n    nombre, precio, vendidos = linea.strip().split(',')\n    if nombre == producto:\n      precio_nuevo = input(\"Indica el nuevo precio unitario: \")\n      vendidos_nuevo = input(\"Indica la cantidad vendida: \")\n      \n      total_vendidos = int(vendidos) + int(vendidos_nuevo)\n      linea_nueva.append(f'{nombre}, {precio_nuevo}, {total_vendidos}\\n')\n      existe = True\n    else:\n      linea_nueva.append(linea)\n    \n  if not existe:\n    print(\"Producto no existente en el listado\")\n\n  with open(nombre_listado, 'w') as archivo:\n    archivo.writelines(linea_nueva)\n\n# 4- eliminar producto de la lista\ndef eliminar_producto(nombre_listado):\n    producto = input(\"Indica el nombre del producto a eliminar: \")\n\n    with open(nombre_listado, 'r') as archivo:\n      lineas = archivo.readlines()\n    \n    linea_nueva = []\n    existe = False\n\n    for linea in lineas:\n      nombre, precio, vendidos = [x.strip() for x in linea.strip().split(',')]\n      if nombre == producto:\n        existe = True\n      else:\n        linea_nueva.append(linea)\n      \n    if not existe:\n      print(\"Producto no existente en el listado\")\n\n    with open(nombre_listado, 'w') as archivo:\n      archivo.writelines(linea_nueva)\n\n# 5-operaciones de calculo de ventas\ndef calcular_ventas(nombre_listado):\n  print(\"-1: Ventas totales\\n-2: Total ventas de un producto\")\n  opcion = input(\"Selecciona la opcion que desees: \")\n\n  if opcion == '1': # ventas totales\n    ventas = []\n\n    with open(nombre_listado, 'r') as archivo:\n      lineas = archivo.readlines()\n\n    for linea in lineas:\n      nombre, precio, vendidos = [x.strip() for x in linea.strip().split(',')]\n      vendidos_x_producto = int(precio) * int(vendidos)\n      ventas.append(vendidos_x_producto)\n    \n    print(f\"Total vendido en tienda {sum(ventas)} euros\")\n\n  if opcion == '2': # ventas por producto\n    producto = input(\"Indica el nombre del producto a calcular: \")\n\n    with open(nombre_listado, 'r') as archivo:\n      lineas = archivo.readlines()\n    \n    for linea in lineas:\n      nombre, precio, vendidos = [x.strip() for x in linea.strip().split(',')]\n      if nombre == producto:\n        vendido_x_producto = int(precio) * int(vendidos)\n      else:\n        print(\"Producto no existente en el listado\")\n      \n    print(f\"El total vendido de {producto} es {vendido_x_producto} euros\")\n\n\n\n\n# crear listado vacio\nnombre_listado = 'listado-productos.txt'\nopen(nombre_listado, 'a').close()\n\n# main\nwhile True:\n  print('-----------------MENU--------------------')\n  print('-1: Agregar producto\\n-2: Consultar listado\\n-3: Actualizar producto\\n-4: Eliminar producto\\n-5: Calcular Ventas\\n-6: Salir')\n  eleccion = input(\"Selecciona la opcion que desees: \")\n\n  if eleccion == '1':\n    agregar_producto(nombre_listado)\n  \n  elif eleccion == '2':\n    ver_listado(nombre_listado)\n\n  elif eleccion == '3':\n    actualizar_producto(nombre_listado)\n\n  elif eleccion == '4':\n    eliminar_producto(nombre_listado)\n\n  elif eleccion == '5':\n    calcular_ventas(nombre_listado)\n  \n  elif eleccion == '6':\n    print(\"Saliendo del programa...\")\n    os.remove(nombre_listado)\n    break\n\n  else:\n    print(\"Selecciona una de las opciones disponibles\")"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/victorfer69.py",
    "content": "import os\n\n#EJERCICIO\n\nfile_name = \"victorfer69.txt\"\n\n#Escribir en el fichero\nwith open(file_name, \"w\") as file:\n    file.write(\"Victor\\n\")\n    file.write(\"21\\n\")\n    file.write(\"Python\")\n\n#Leer el fichero\nwith open(file_name, \"r\") as file:\n    print(file.read())\n\n#Borrar el fichero\nos.remove(file_name)\n\n\n#EJERCICIO EXTRA\n\ndef gestionDeVentas(file_name:str):\n\n    salir = False\n\n    while not salir:\n        \n        print(\"1. Añadir producto\")\n        print(\"2. Consultar producto\")\n        print(\"3. Actualizar producto\")\n        print(\"4. Borrar producto\")\n        print(\"5. Mostrar productos\")\n        print(\"6. Calcular venta total\")\n        print(\"7. Calcular venta por producto\")\n        print(\"8. Salir\")\n        action = input(\"Seleccione el modo:\")\n\n        match action:\n\n            case \"1\":\n\n                name = input(\"Dame el nombre del producto: \")\n                quantity = int(input(\"Dame la cantidad: \"))\n                price = float(input(\"Dame el precio: \"))\n\n                with open(file_name, \"a\") as file:\n                    if name != None and quantity != None and quantity > 0 and price != None and price > 0:\n                        file.write(f\"{name}, {quantity}, {price}\\n\")\n                    else:\n                        print(\"Algún argumento invalido\")\n                \n            case \"2\":\n\n                product = input(\"¿Que producto quieres consultar?: \")\n                existe = False\n\n                with open(file_name, \"r\") as file:\n                    for line in file.readline():\n                        if line.split(\",\")[0] == product:\n                            print(line)\n                            existe = True\n\n                if not existe:\n                    print(f\"No hay {product}\")   \n\n            case \"3\":\n\n                name = input(\"Dame el nombre del producto: \")\n                quantity = int(input(\"Dame la cantidad: \"))\n                price = float(input(\"Dame el precio: \"))\n\n                with open(file_name, \"r\") as file:\n                    lines = file.readlines()\n\n                with open(file_name, \"w\") as file:\n                    for line in lines:\n                        if line.split(\", \")[0] == name:\n                            file.write(f\"{name}, {quantity}, {price}\\n\")\n                        else:\n                            file.write(line)\n\n            case \"4\":\n                \n                name = input(\"Dame el nombre del producto: \")\n\n                with open(file_name, \"r\") as file:\n                    lines = file.readlines()\n\n                with open(file_name, \"w\") as file:\n                    for line in lines:\n                        if line.split(\", \")[0] != name:\n                            file.write(line)\n\n            case \"5\":\n                \n                with open(file_name, \"r\") as file:\n                    print(file.read())\n\n            case \"6\":\n\n                total = 0\n\n                with open(file_name, \"r\") as file:\n                    for line in file.readlines():\n                        components = line.split(\", \")\n                        quantity = int(components[1])\n                        price = float(components[2])\n                        total += quantity * price\n                \n                print(total)\n\n            case \"7\":\n                \n                name = input(\"Nombre: \")\n                total = 0\n                existe = False\n\n                with open(file_name, \"r\") as file:\n                    for line in file.readlines():\n                        components = line.split(\", \")\n                        if components[0] == name:\n                            quantity = int(components[1])\n                            price = float(components[2])\n                            total += quantity * price\n                            existe = True\n                            break\n\n                if existe:\n                    print(total)\n                else:\n                    print(f\"El producto {name} no existe\")\n\n            case \"8\":\n\n                print(\"Saliendo del programa (borrando fichero)\")\n                os.remove(file_name)\n                salir = True\n\n            case _:\n                \n                print(\"Seleccione una opcion correcta.\")\n\n\n#Fichero inicial\nwith open(\"ventas.txt\", \"a\") as file:\n    file.write(\"Patata, 4, 0.25\\n\")\n    file.write(\"Pan, 5, 0.2\\n\")\n    file.write(\"Sopa, 2, 0.5\\n\")\n    file.write(\"Carne, 1, 1\\n\")\n\ngestionDeVentas(\"ventas.txt\")"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/worlion.py",
    "content": "import os\n\nglobal global_file_path \nglobal_file_path = \"./worlion.txt\"\n\nclass Student:\n    def __init__(self, name: str, age:int, lang: str) -> None:\n        self.name: str = name\n        self.age:int = age\n        self.lang: str = lang\n    \ndef write_student(file_path: str, student: Student):\n    my_file = open(file_path, 'w')\n    my_file.write(f\"\\nName: {student.name}\")\n    my_file.write(f\"\\nAge: {student.age}\")\n    my_file.write(f\"\\nFavourite language: {student.lang}\")\n    my_file.close()\n\ndef read_students(file_path: str, ):\n    my_file_read = open(file_path, 'r')\n    print(my_file_read.read())\n    my_file_read.close()\n\ndef remove_file(file_path: str, ):\n    os.remove(file_path)\n\ndef test_students_in_files():\n    student: Student = Student(\"Worlion\", 40, \"Python\")\n    print(\"\\nEscribiendo en fichero...\")\n    write_student(global_file_path, student)\n    print(\"\\nLeyendo fichero...\")\n    read_students(global_file_path)\n    print(\"\\nBorrando fichero...\")\n    remove_file(global_file_path)\n    \ntest_students_in_files()\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n* Desarrolla un programa de gestión de ventas que almacena sus datos en un \n* archivo .txt.\n* - Cada producto se guarda en una línea del archivo de la siguiente manera:\n*   [nombre_producto], [cantidad_vendida], [precio].\n* - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n*   actualizar, eliminar productos y salir.\n* - También debe poseer opciones para calcular la venta total y por producto.\n* - La opción salir borra el .txt.\n\"\"\"\n\nprint(\"\\n ---- 🌩 DIFICULTAD EXTRA 🌩 ----\\n\")\n\nglobal shop_sales_file\nshop_sales_file = \"shop.txt\"\n\nclass Product():\n    def __init__(self, product_str: str) -> None:\n        split_values = product_str.split(\", \")\n        self.name = split_values[0]\n        self.quantity = int(split_values[1])\n        self.price = float(split_values[2])\n    \n    def to_str(self):\n        return \"{}, {}, {}\".format(self.name, self.quantity, self.price)\n    \n    def total_price(self) -> float:\n        return self.quantity * self.price\n\ndef write_product(product: Product):   \n    with open(shop_sales_file, \"a\") as file:\n        file.write(f\"{product.to_str()}\\n\")\n\ndef find_product(name: str) -> Product:\n    with open(shop_sales_file, \"r\") as file:\n        for product_str in file.readlines():\n            if name == product_str.split(\",\")[0]:\n                return Product(product_str)\n\ndef update_product(name: str, product: Product):\n    with open(shop_sales_file, \"r\") as file:\n        lines = file.readlines()\n    with open(shop_sales_file, \"w\") as file:\n        for line in lines:\n            if line.split(\", \")[0] == name:\n                file.write(f\"{product.to_str()}\\n\")\n            else:\n                file.write(line)\n        \ndef delete_product(product: Product):\n    with open(shop_sales_file, \"r\") as file:\n        lines = file.readlines()\n    with open(shop_sales_file, \"w\") as file:\n        for line in lines:\n            if line.split(\", \")[0] != product.name:\n                file.write(line)\n\ndef totals():\n    total = 0\n    i = 1\n    with open(shop_sales_file, \"r\") as file:\n        print(\"\\t\\tProducto\\tCantidad\\tPrecio\\tTotal\")\n        for line in file.readlines():\n            line_product = Product(line)\n            print(f\"\\t{i}\\t{line_product.name}\\t{line_product.quantity}\\t\\t{line_product.price}\\t{line_product.total_price()} €\")\n            total += line_product.total_price()\n            i+=1\n        print(f\"Total ventas: {total}\")\n\ndef show_menu():\n    print(\"\\n¿Qué desea hacer?\\n\")\n    print(\"\\t1.- Añadir producto\")\n    print(\"\\t2.- Consultar producto\")\n    print(\"\\t3.- Actualizar producto\")\n    print(\"\\t4.- Eliminar producto\")\n    print(\"\\t5.- Consultar totales\")\n    \n    print(\"\\t0.- SALIR\")\n    return input(\"\\nEscriba una opción: \")\n    \ndef process_option(option):\n    print(f\"opcion: {option}\")\n    if   option == \"1\":     # Añadir producto\n        name = input(\"Nombre del producto: \")\n        quantity = int(input(\"Cantidad: \"))\n        price = float(input(\"Precio unitario del producto: \"))\n        product = Product(name +\", \"+ str(quantity) +\", \"+ str(price))\n        \n        write_product(product)\n    \n    elif option == \"2\":     # Consultar producto\n        name = input(\"\\nNombre del producto a consultar: \")\n        product = find_product(name)\n        print(f\"Producto: {product.to_str()}\")\n        print(f'Subtotal: {product.total_price():.2f} €')\n    \n    elif option == \"3\":     # Actualizar producto\n        name = input(\"\\nNombre del producto a actualizar: \")\n        product = find_product(name)\n        new_name = input(f\"\\nNuevo nombre (actual = '{product.name}'): \")\n        new_quantity = input(f\"\\nNueva cantidad (actual = '{product.quantity}'): \")\n        new_price = input(f\"\\nNuevo precio/unidad (actual = '{product.price}'): \")\n        product = Product(new_name +\", \"+ str(new_quantity) +\", \"+ str(new_price))\n        update_product(name, product)  \n    \n    elif option == \"4\":     # Eliminar producto\n        name = input(\"\\nNombre del producto a eliminar: \")\n        product = find_product(name)\n        confirm = input(\"¿Está seguro de que desea ELIMINAR el producto? S/N: \")\n        if(confirm.upper() == \"S\"):\n            delete_product(product)\n            print(\"se ha eliminado el producto\")\n        else:\n            print(\"NO se ha eliminado el producto\")\n            \n    elif option == \"5\":     # Consultar totales\n        totals()\n    \n    elif option == \"0\":     # SALIR\n        print(\"Hasta pronto...\")\n        os.remove(shop_sales_file)\n    \n    else: \n        print(\"Opción no valida\")\n        \ndef shop():\n    print(\"\\n\\nBienvenido a nuestra tienda...\")\n    option = \"\"\n    while option != \"0\":\n        option = show_menu()\n        process_option(option)\n\nshop()\n    "
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/ycanas.py",
    "content": "import os\n\n# ------ Ejercicio\n\nFILENAME = \"ycanas.txt\"\n\nwith open(FILENAME, 'w', encoding=\"utf-8\") as f:\n    f.write(\"Yair Cañas\\n\")\n    f.write(\"24\\n\")\n    f.write(\"Python\")\n\nwith open(FILENAME, 'r') as f:\n    print(f.read())\n\nos.remove(FILENAME)\nprint()\n\n\n# ------ Extra\n\nFILE = \"ventas.txt\"\nOPTIONS = (\n    \"Añadir producto\",\n    \"Consultar producto\",\n    \"Consultar productos\",\n    \"Actualizar producto\",\n    \"Eliminar producto\",\n    \"Calcular precio total\",\n    \"Calcular precio por producto\",\n    \"Salir\"\n)\n\nopen(FILE, 'a')\nprint(\"Bienvenido 👋\")\n\nwhile True:\n    print()\n    for i, option in enumerate(OPTIONS):\n        print(f\"   {i + 1}. {option}\")\n\n    option = input(\"\\n> Ingrese el número correspondiente a la operación deseada: \")\n\n    if not option.isdigit():\n        print(\"\\n* Error, debe ingresar un número entero.\")\n        continue\n\n    option = int(option)\n\n    if option == 1:\n        product_name = input(\"\\n> Nombre: \")\n        product_quantity = input(\"> Cantidad: \")\n        product_price = input(\"> Precio: \")\n\n        with open(FILE, 'a', encoding=\"utf-8\") as f:\n            f.write(f\"{product_name}, {product_quantity}, {product_price}\\n\")\n            print(\"\\n* Producto añadido.\")\n\n        continue\n\n    elif option == 2:\n        product_name = input(\"\\n> Nombre: \")\n\n        with open(FILE, 'r') as f:\n            for line in f:\n                if product_name == line.split(\", \")[0]:\n                    print(\"\\n- \" + line, end='')\n                    break\n            else:\n                print(\"\\n* Producto no encontrado.\")\n        \n        continue\n\n    elif option == 3:\n        with open(FILE, 'r') as f:\n            print()\n\n            for line in f:\n                if line == '':\n                    break\n\n                print('-', line, end='')\n        \n        continue\n\n    elif option == 4:\n        product_name = input(\"\\n> Nombre: \")\n\n        with open(FILE, 'r+', encoding='utf-8') as f:\n            for line in f:\n                data = line.split(\", \")\n\n                if product_name == data[0]:\n                    new_product_name = input(\"\\n> Nombre (enter para no cambiar): \")\n                    new_product_quantity = input(\"> Cantidad (enter para no cambiar): \")\n                    new_product_price = input(\"> Precio (enter para no cambiar): \")\n\n                    if new_product_name == '':\n                        new_product_name = data[0]\n\n                    if new_product_quantity == '':\n                        new_product_quantity = data[1]\n\n                    if new_product_price == '':\n                        new_product_price = data[2]\n\n                    f.write(f\"{new_product_name}, {new_product_quantity}, {new_product_price}\\n\")\n                    print(\"\\n* Producto Actualizado.\")\n                    break\n            else:\n                print(\"\\n* Producto no encontrado.\")\n\n        continue\n\n    elif option == 5:\n        product_name = input(\"\\n> Nombre: \")        \n\n        with open(FILE, 'r') as f:\n            lines = f.readlines()\n\n        for line in lines:\n            if line.split(\", \")[0] == product_name:\n                break\n\n        else:\n            print(\"\\n* Producto no encontrado.\")\n            continue\n\n        with open(FILE, 'w', encoding=\"utf-8\") as f:\n            for line in lines:\n                if line.split(\", \")[0] != product_name:\n                    f.write(line)\n        \n        print(\"\\n* Producto eliminado.\")\n        continue\n\n    elif option == 6:\n        with open(FILE, 'r') as f:\n            total = 0\n\n            for line in f:\n                data = line.split(\", \")\n                quantity = float(data[1])\n                price = float(data[2])\n\n                total += quantity * price\n        \n        print(f\"\\n* Precio total del inventario: {total:,.2f} COP\")\n        continue\n\n    elif option == 7:\n        product_name = input(\"\\n> Nombre: \")\n\n        with open(FILE, 'r') as f:\n            for line in f:\n                data = line.split(\", \")\n                if product_name == data[0]:\n                    quantity = float(data[1])\n                    price = float(data[2])\n\n                    total = quantity * price\n            else:\n                print(\"\\n* Producto no encontrado.\")\n\n        print(f\"\\n* Precio total del inventario del producto: {total:,.2f} COP\")\n        continue\n\n    elif option == 8:\n        os.remove(FILE)\n        print(\"\\nSaliendo...\")\n        break\n\n    else:\n        print(\"\\n* Error, debe ingresar un número entero entre 1 y 7.\")\n        continue\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/yenneralayon142.py",
    "content": "import os\n\n\"\"\"\"\nFicheros\n\"\"\"\n\nfile_name = \"yennerAlayon.txt\"\n\nwith open(file_name, \"w\") as file:\n    file.write(\"Yenner\")\n\nwith open(file_name, \"r\") as file:\n    print(file.read())\n\nos.remove(file_name)\n\n\n\"\"\"\nExtra\n\"\"\"\n\nfile_name = \"yennerShop.txt\"\n\nopen(file_name, \"a\")\n\nwhile True:\n    print(\"1. Añadir producto\")\n    print(\"2. Consultar producto\")\n    print(\"3. Actualizar producto\")\n    print(\"4. Borrar producto\")\n    print(\"5. Mostrar productos\")\n    print(\"6. Calcular venta total\")\n    print(\"7. Calcular venta por producto\")\n    print(\"8. Salir\")\n\n    option = input(\"Selecciona una opción: \")\n\n    if option == \"1\":\n        name = input(\"Nombre: \")\n        quantity = input(\"Cantidad: \")\n        price = input(\"Precio: \")\n        with open(file_name, \"a\") as file:\n            file.write(f\"{name}, {quantity}, {price}\\n\")\n    elif option == \"2\":\n        name = input(\"Nombre: \")\n        with open(file_name, \"r\") as file:\n            for line in file.readlines():\n                if line.split(\", \")[0] == name:\n                    print(line)\n                    break\n    elif option == \"3\":\n        name = input(\"Nombre: \")\n        quantity = input(\"Cantidad: \")\n        price = input(\"Precio: \")\n        with open(file_name, \"r\") as file:\n            lines = file.readlines()\n        with open(file_name, \"w\") as file:\n            for line in lines:\n                if line.split(\", \")[0] == name:\n                    file.write(f\"{name}, {quantity}, {price}\\n\")\n                else:\n                    file.write(line)\n    elif option == \"4\":\n        name = input(\"Nombre: \")\n        with open(file_name, \"r\") as file:\n            lines = file.readlines()\n        with open(file_name, \"w\") as file:\n            for line in lines:\n                if line.split(\", \")[0] != name:\n                    file.write(line)\n    elif option == \"5\":\n        with open(file_name, \"r\") as file:\n            print(file.read())\n    elif option == \"6\":\n        total = 0\n        with open(file_name, \"r\") as file:\n            for line in file.readlines():\n                components = line.split(\", \")\n                quantity = int(components[1])\n                price = float(components[2])\n                total += quantity * price\n        print(total)\n    elif option == \"7\":\n        name = input(\"Nombre: \")\n        total = 0\n        with open(file_name, \"r\") as file:\n            for line in file.readlines():\n                components = line.split(\", \")\n                if components[0] == name:\n                    quantity = int(components[1])\n                    price = float(components[2])\n                    total += quantity * price\n                    break\n        print(total)\n    elif option == \"8\":\n        os.remove(file_name)\n        break\n    else:\n        print(\"Selecciona una de las opciones disponibles.\")"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/python/zetared92.py",
    "content": "# RETO 11 MANEJO DE FICHEROS\nimport os\n\"Crea un programa capaz de crear un archivo txt, imprime el contenido y borra el fichero\"\n\nfile_name = \"zetared92.txt\"\n\nwith open(file_name, \"w\") as file:\n    file.write(\"Zeta Vega\\n\")\n    file.write(\"31\\n\")\n    file.write(\"Python\")\n\nwith open(file_name, \"r\") as file:\n    print(file.read())\n\nos.remove(file_name)\n\n\n# Extra\n\nprint(\"🧩 DIFICULTAD EXTRA - GESTIÓN DE VENTAS 🧩\")\nfile_name = \"zeta_sales.txt\"\n\nopen(file_name, \"a\")\n\nwhile True:\n    print(\"1. Add product\")\n    print(\"2. Check product\")\n    print(\"3. Update product\")\n    print(\"4. Delete product\")\n    print(\"5. Show products\")\n    print(\"6. Calculate total sales\")\n    print(\"7. Calculate sales by product\")\n    print(\"8. Exit\")\n\n    option = input(\"Select an option\")\n\n    if option == \"1\":\n        name = input(\"Name: \")\n        quantity = input(\"Quantity: \")\n        price = input(\"Price: \")\n        with open(file_name, \"a\") as file:\n            file.write(f\"{name}, {quantity}, {price}\\n\")\n    elif option == \"2\":\n        name = input(\"Name: \")\n        with open(file_name, \"r\") as file:\n            for line in file.readlines():\n                if line.split(\", \")[0] == name:\n                    print(line)\n                    break\n    elif option == \"3\":\n        name = input(\"Name: \")\n        quantity = input(\"Quantity: \")\n        price = input(\"Price: \")\n        with open(file_name, \"r\") as file:\n            lines = file.readlines()\n        with open(file_name, \"w\") as file:\n            for line in lines:\n                if line.split(\", \")[0] == name:\n                    file.write(f\"{name}, {quantity}, {price}\\n\")\n                else:\n                    file.write(line)\n    elif option == \"4\":\n        name = input(\"Name: \")\n        with open(file_name, \"r\") as file:\n            lines = file.readlines()\n        with open(file_name, \"w\") as file:\n            for line in lines:\n                if line.split(\", \")[0] != name:\n                    file.write(line)\n    elif option == \"5\":\n        with open(file_name, \"r\") as file:\n            print(file.read())\n    elif option == \"6\":\n        total = 0\n        with open(file_name, \"r\") as file:\n            for line in file.readlines():\n                components = line.split(\", \")\n                quantity = int(components[1])\n                price = float(components[2])\n                total == quantity * price\n        print(total)\n    elif option == \"7\":\n        name = input(\"Name: \")\n        total = 0\n        with open(file_name, \"r\") as file:\n            for line in file.readlines():\n                components = line.split(\", \")\n                if components[0] == name:\n                    quantity = int(components[1])\n                    price = float(components[2])\n                    total += quantity * price\n                    break\n        print(total)\n    elif option == \"8\":\n        os.remove(file_name)\n        break\n    else:\n        print(\"Select one of the available options.1\")"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/ruby/Elmer125.rb",
    "content": "#  * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n#  *\n#  * EJERCICIO:\n#  * Desarrolla un programa capaz de crear un archivo que se llame como\n#  * tu usuario de GitHub y tenga la extensión .txt.\n#  * Añade varias líneas en ese fichero:\n#  * - Tu nombre.\n#  * - Edad.\n#  * - Lenguaje de programación favorito.\n#  * Imprime el contenido.\n#  * Borra el fichero.\n\nfile_name = \"Elmer125.txt\"\n\nFile.open(file_name, \"w\") do |file|\n  file.puts \"Elmer\"\n  file.puts \"28\"\n  file.puts \"Ruby\"\nend\n\nFile.open(file_name, \"r\") do |file|\n  file.each_line do |line|\n    puts line\n  end\nend\n\nFile.delete(file_name)\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Desarrolla un programa de gestión de ventas que almacena sus datos en un\n#  * archivo .txt.\n#  * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n#  *   [nombre_producto], [cantidad_vendida], [precio].\n#  * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n#  *   actualizar, eliminar productos y salir.\n#  * - También debe poseer opciones para calcular la venta total y por producto.\n#  * - La opción salir borra el .txt.\n#  */\n\nshopping_file = \"elmer125_shopping.txt\"\noption = \"\"\n\nwhile option != \"8\"\n  puts \"Introduce una opción: \"\n  puts \"1. Añadir producto\"\n  puts \"2. Consultar producto\"\n  puts \"3. Actualizar producto\"\n  puts \"4. Eliminar producto\"\n  puts \"5. Mostrar productos\"\n  puts \"6. Calcular venta total\"\n  puts \"7. Calcular venta por producto\"\n  puts \"8. Salir\"\n\n  option = gets.chomp\n\n  case option\n  when \"1\"\n    puts \"Introduce el nombre del producto:\"\n    product = \"Nombre: #{gets.chomp}\"\n    puts \"Introduce la cantidad vendida:\"\n    quantity = \"Cantidad: #{gets.chomp}\"\n    puts \"Introduce el precio:\"\n    price = \"Precio: #{gets.chomp}\"\n\n    File.open(shopping_file, \"a\") do |file|\n      file.puts \"#{product}, #{quantity}, #{price}\"\n    end\n  when \"2\"\n    puts \"Introduce el nombre del producto a consultar:\"\n    product = \"Nombre: #{gets.chomp}\"\n    File.open(shopping_file, \"r\") do |file|\n      file.each_line do |line|\n        puts line if line.split(\", \")[0] == product\n      end\n    end\n  when \"3\"\n    puts \"Introduce el nombre del producto a actualizar:\"\n    product = \"Nombre: #{gets.chomp}\"\n    puts \"Introduce la nueva cantidad vendida:\"\n    quantity = \"Cantidad: #{gets.chomp}\"\n    puts \"Introduce el nuevo precio:\"\n    price = \"Precio: #{gets.chomp}\"\n\n    products = File.readlines(shopping_file)\n\n    File.open(shopping_file, \"w\") do |file|\n      products.each do |line|\n        if line.split(\", \")[0] == product\n          file.puts \"#{product}, #{quantity}, #{price}\"\n        else\n          file.puts line\n        end\n      end\n    end\n  when \"4\"\n    puts \"Introduce el nombre del producto a eliminar:\"\n    product = \"Nombre: #{gets.chomp}\"\n\n    products = File.readlines(shopping_file)\n\n    File.open(shopping_file, \"w\") do |file|\n      products.each do |line|\n        file.puts line unless line.split(\",\")[0] == product\n      end\n    end\n  when \"5\"\n    puts \"Productos:\"\n    products = File.readlines(shopping_file)\n    products.each do |line|\n      puts line\n    end\n  when \"6\"\n    products = File.readlines(shopping_file)\n    puts \"Venta total: #{products.map { |line| line.split(\", \")[1].split(\": \")[1].to_i * line.split(\", \")[2].split(\": \")[1].to_f }.sum}\"\n\n  when \"7\"\n    products = File.readlines(shopping_file)\n    puts \"Introduce el nombre del producto a consultar:\"\n    product = \"Nombre: #{gets.chomp}\"\n    puts \"Venta por producto: #{products.select { |line| line.split(\", \")[0] == product }.map { |line| line.split(\", \")[1].split(\": \")[1].to_i * line.split(\", \")[2].split(\": \")[1].to_f }.sum}\"\n  when \"8\"\n    File.delete(shopping_file)\n  else\n    puts \"Opción no válida\"\n  end\nend"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/rust/gabrielmoris.rs",
    "content": "/*\n * IMPORTANT: You should only upload the code file as part of the exercise.\n *\n * EXERCISE:\n * Develop a program capable of creating a file named after\n * your GitHub username and has the .txt extension.\n * Add several lines to that file:\n * - Your name.\n * - Age.\n * - Favorite programming language.\n * Print the content.\n * Delete the file.\n */\n\nuse std::fs::{File, OpenOptions};\nuse std::io::{self, Error, ErrorKind, Read, Write};\n\nfn create_file(filename: &str) -> Result<(), Error> {\n    let file_name = format!(\"{}.txt\", filename);\n\n    if !file_name.is_empty() {\n        let _ = File::create(file_name);\n        Ok(())\n    } else {\n        Err(Error::new(\n            ErrorKind::InvalidInput,\n            \"You must provide a file name\",\n        ))\n    }\n}\n\nfn write_file(filename: &str, contents: &str) -> Result<(), Error> {\n    let file_name = format!(\"{}.txt\", filename);\n    let mut file = OpenOptions::new()\n        .write(true)\n        .append(true)\n        .open(file_name)?;\n\n    file.write_all(contents.as_bytes())?;\n    Ok(())\n}\n\nfn read_file(filename: &str) -> Result<String, Error> {\n    let file_name = format!(\"{}.txt\", filename);\n    let mut file = File::open(file_name)?;\n    let mut contents = String::new();\n    file.read_to_string(&mut contents)?;\n    Ok(contents)\n}\n\nfn delete_file(filename: &str) -> Result<(), Error> {\n    let file_name = format!(\"{}.txt\", filename);\n    std::fs::remove_file(file_name)?;\n    Ok(())\n}\n\n/* EXTRA DIFFICULTY (optional):\n * Develop a sales management program that stores its data in a\n * .txt file.\n * - Each product is saved on a line of the file in the following way:\n *   [product_name], [quantity_sold], [price].\n * - Following that format, and through terminal, it should allow adding, consulting,\n *   updating, deleting products and exiting.\n * - It should also have options to calculate the total sale and by product.\n * - The exit option deletes the .txt.\n */\n\nfn main() {\n    match create_file(\"gabrielcmoris\") {\n        Ok(()) => println!(\"File Created sucessfully\"),\n        Err(err) => println!(\"There was an error: {}\", err),\n    }\n\n    match write_file(\n        \"gabrielcmoris\",\n        \"Name: Gabriel\\nAge: 34\\nFavorite programming language: Assembly\",\n    ) {\n        Ok(()) => println!(\"File writted sucessfully\"),\n        Err(err) => println!(\"There was an error: {}\", err),\n    }\n\n    match read_file(\"gabrielcmoris\") {\n        Ok(file) => println!(\"File contents {:?}\", file),\n        Err(err) => println!(\"There was an error: {}\", err),\n    }\n\n    match delete_file(\"gabrielcmoris\") {\n        Ok(()) => println!(\"File deleted sucessfully\"),\n        Err(err) => println!(\"There was an error: {}\", err),\n    }\n\n    sales_manager();\n}\n\nfn sales_manager() {\n    loop {\n        println!(\n            \"\n            ===========================\n            What would you like to do?\n            1. Add a file\n            2. Delete a file\n            3. Read a file\n            4. Edit a file\n            5. Exit\n            ===========================\n            \"\n        );\n\n        let mut input = String::new();\n        io::stdin()\n            .read_line(&mut input)\n            .expect(\"Failed to read line\");\n\n        let choice: u32 = input.trim().parse().expect(\"Invalid input\");\n\n        match choice {\n            1 => add_doc(),\n            2 => delete_doc(),\n            3 => read_doc(),\n            4 => edit_doc(),\n            5 => {\n                println!(\"📁 Goodbye! 📁\");\n                break;\n            }\n            _ => println!(\"Invalid choice. Please try again.\"),\n        }\n\n        println!();\n    }\n}\n\nfn add_doc() {\n    println!(\"Enter the document Name\");\n    let mut doc_name: String = String::new();\n    io::stdin()\n        .read_line(&mut doc_name)\n        .expect(\"Failed to read name\");\n    let doc_name: String = doc_name.trim().to_string();\n    match create_file(&doc_name) {\n        Ok(()) => println!(\"File Created sucessfully\"),\n        Err(err) => println!(\"There was an error: {}\", err),\n    }\n\n    println!(\"Enter the product Name\");\n    let mut product_name: String = String::new();\n    io::stdin()\n        .read_line(&mut product_name)\n        .expect(\"Failed to read name\");\n    let product_name: String = product_name.trim().to_string();\n\n    println!(\"Enter the sold product amount\");\n    let mut product_amount: String = String::new();\n    io::stdin()\n        .read_line(&mut product_amount)\n        .expect(\"Failed to read amount\");\n    let product_amount: String = product_amount.trim().to_string();\n\n    println!(\"Enter the sold product price\");\n    let mut product_price: String = String::new();\n    io::stdin()\n        .read_line(&mut product_price)\n        .expect(\"Failed to read price\");\n    let product_price: String = product_price.trim().to_string();\n\n    let content = format!(\n        \"Product: {}\\nUnits sold: {}\\nPrice: {}\",\n        product_name, product_amount, product_price\n    );\n\n    match write_file(&doc_name, &content) {\n        Ok(()) => println!(\"File writted sucessfully\"),\n        Err(err) => println!(\"There was an error: {}\", err),\n    }\n}\n\nfn delete_doc() {\n    println!(\"Enter the document Name\");\n    let mut doc_name: String = String::new();\n    io::stdin()\n        .read_line(&mut doc_name)\n        .expect(\"Failed to read name\");\n    let doc_name: String = doc_name.trim().to_string();\n\n    match delete_file(&doc_name) {\n        Ok(()) => println!(\"File deleted sucessfully\"),\n        Err(err) => println!(\"There was an error: {}\", err),\n    }\n}\n\nfn read_doc() {\n    println!(\"Enter the document Name\");\n    let mut product_name: String = String::new();\n    io::stdin()\n        .read_line(&mut product_name)\n        .expect(\"Failed to read name\");\n    let product_name: String = product_name.trim().to_string();\n\n    match read_file(&product_name) {\n        Ok(file) => println!(\"File contents {:?}\", file),\n        Err(err) => println!(\"There was an error: {}\", err),\n    }\n}\n\nfn edit_doc() {\n    println!(\"Enter the document Name\");\n    let mut doc_name: String = String::new();\n    io::stdin()\n        .read_line(&mut doc_name)\n        .expect(\"Failed to read name\");\n    let doc_name: String = doc_name.trim().to_string();\n\n    println!(\"Enter the product Name.\");\n    let mut product_name: String = String::new();\n    io::stdin()\n        .read_line(&mut product_name)\n        .expect(\"Failed to read name\");\n    let product_name: String = product_name.trim().to_string();\n\n    println!(\"Enter the sold product amount.\");\n    let mut product_amount: String = String::new();\n    io::stdin()\n        .read_line(&mut product_amount)\n        .expect(\"Failed to read amount\");\n    let product_amount: String = product_amount.trim().to_string();\n\n    println!(\"Enter the sold product price.\");\n    let mut product_price: String = String::new();\n    io::stdin()\n        .read_line(&mut product_price)\n        .expect(\"Failed to read price\");\n    let product_price: String = product_price.trim().to_string();\n\n    let content = format!(\n        \"Product: {}\\nUnits sold: {}\\nPrice: {}\",\n        product_name, product_amount, product_price\n    );\n\n    match delete_file(&doc_name) {\n        Ok(()) => println!(\"File deleted sucessfully\"),\n        Err(err) => println!(\"There was an error: {}\", err),\n    }\n    match create_file(&doc_name) {\n        Ok(()) => println!(\"File Created sucessfully\"),\n        Err(err) => println!(\"There was an error: {}\", err),\n    }\n\n    match write_file(&doc_name, &content) {\n        Ok(()) => println!(\"File writted sucessfully\"),\n        Err(err) => println!(\"There was an error: {}\", err),\n    }\n}\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/rust/kenysdev.rs",
    "content": "/*\n╔═══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado                ║\n║ GitHub: https://github.com/Kenysdev   ║\n║ 2024 -  Rust                          ║\n╚═══════════════════════════════════════╝\n-----------------------------------------\n* MANEJO DE FICHEROS\n-----------------------------------------\n* EJERCICIO:\n* Desarrolla un programa capaz de crear un archivo que se llame como\n* tu usuario de GitHub y tenga la extensión .txt.\n* Añade varias líneas en ese fichero:\n* - Tu nombre.\n* - Edad.\n* - Lenguaje de programación favorito.\n* Imprime el contenido.\n* Borra el fichero.\n*/\n\nuse std::fs::File;\nuse std::io::prelude::*;\nuse std::path::Path;\nuse std::fs;\n\nfn write_all(the_path: &str, content: &str) {\n    let path = Path::new(the_path);\n    let display = path.display();\n\n    let mut file = match File::create(&path) {\n        Err(why) => panic!(\"No se pude crear {}: {}\", display, why),\n        Ok(file) => file,\n    };\n\n    match file.write_all(content.as_bytes()) {\n        Err(why) => panic!(\"No se pude escribir en {}: {}\", display, why),\n        Ok(_) => println!(\"* Se escribió en {}\", display),\n    }\n}\n\nfn print_all(the_path: &str) {\n    match fs::read_to_string(the_path) {\n        Ok(content) => {\n            println!(\"* Contenido de {}: \\n{}\", the_path, content);\n        }\n        Err(err) => {\n            println!(\"Error al leer el archivo {}: {}\", the_path, err);\n        }\n    }\n}\n\nfn delete_file(the_path: &str) {\n    if let Err(err) = fs::remove_file(the_path) {\n        println!(\"Error al eliminar {}: {}\", the_path, err);\n    } else {\n        println!(\"* {} ha sido eliminado.\", the_path);\n    }\n}\n\nfn main(){\n    write_all(\"kenysdev.txt\", \"- Ken\\n- 121\\n- Python\");\n    print_all(\"kenysdev.txt\");\n    delete_file(\"kenysdev.txt\");    \n}\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/rust/w00k.rs",
    "content": "use std::fs::File;\nuse std::io::Write;\nuse std::fs;\n\nfn main() {\n    // Data you want to write to the file\n    let data = \"Name: w00k.\\nAge: 41 años.\\nFavorite programming language: Java\";\n    let file_name = \"w00k.txt\";\n\n    // Open the file in write mode, creating it if it doesn't exist\n    let mut file = File::create(file_name).expect(\"Error creating file\");\n\n    // Write the data to the file\n    file.write_all(data.as_bytes()).expect(\"Error writing to the file\");\n\n    println!(\"Successfully wrote data to {}\", file_name);\n\n    let contents = fs::read_to_string(file_name)\n        .expect(\"Should have been able to read the file\");\n\n    println!(\"\\nWith text:\\n{contents}\\n\");\n\n    fs::remove_file(file_name).expect(\"File not found\");\n\n    println!(\"Delete file\");\n\n}"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/sql/Nicojsuarez2.sql",
    "content": "# #11 MANEJO DE FICHEROS\n> #### Dificultad: Media | Publicación: 11/03/24 | Corrección: 18/03/24\n\n## Ejercicio\n\n```\n/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n * \n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n * archivo .txt.\n * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/swift/allbertoMD.swift",
    "content": "import Foundation\n\n\nvar path: String = \"\"\nvar name: String = \"\"\nvar age: String = \"\"\nvar programmingLenguage = \"\"\nvar productName = \"\"\nvar soldProduct = \"\"\nvar productPrice: Int = 0\nvar deleteFile: String = \"\"\nvar filePath: URL = URL(filePath: \"\")\n\n\n\nprint(\"Introduce la ruta y el nombre del fichero.\")\nif let fileName = readLine() {\n    \n    filePath = URL(filePath: fileName)\n    path = fileName\n\n    if FileManager.default.fileExists(atPath: path) {\n        print(\"El fichero ya existe.\")\n    }\n\n    do {\n        try fileName.write(to: filePath, atomically: true, encoding: .utf8)\n        print(\"Fichero creado.\")\n    } catch {\n        print(\"Error al crear fichero: \\(error)\")\n    }\n}\n\nprint(\"\\nIntroduce el nombre:\")\nif let nameInput = readLine() {\n    \n    name = nameInput\n\n        if !FileManager.default.fileExists(atPath: path) {\n        print(\"El fichero no existe.\")\n    }\n    if let file = FileHandle(forWritingAtPath: path) {\n        do {\n            try file.seekToEnd()\n        }\n        do {\n            try file.write(contentsOf: \"\\(name)\".data(using: .utf8)!)\n            print(\"Nombre Introducido.\")\n        } catch {\n            print(\"ERROR -> \\(error.localizedDescription)\")\n        }\n        do {\n            try file.close()\n        }\n    }\n}\n\nprint(\"\\nIntroduce la edad:\")\nif let ageInput = readLine() {\n    \n    age = ageInput\n    \n    if !FileManager.default.fileExists(atPath: path) {\n        print(\"El fichero no existe.\")\n    }\n    if let file = FileHandle(forWritingAtPath: path) {\n        do {\n            try file.seekToEnd()\n        }\n        do {\n            try file.write(contentsOf: \"\\n\\(age)\".data(using: .utf8)!)\n            print(\"Edad introducida.\")\n        } catch {\n            print(\"ERROR -> \\(error.localizedDescription)\")\n        }\n        do {\n            try file.close()\n        }\n    }\n}\n\nprint(\"\\nIntroduce el lenguaje de programación:\")\nif let lenguageInput = readLine() {\n    \n    programmingLenguage = lenguageInput\n\n    if !FileManager.default.fileExists(atPath: path) {\n        print(\"El fichero no existe.\")\n    }\n    if let file = FileHandle(forWritingAtPath: path) {\n        do {\n            try file.seekToEnd()\n        }\n        do {\n            try file.write(contentsOf: \"\\n\\(programmingLenguage)\\n\".data(using: .utf8)!)\n            print(\"Lenguaje introducido.\")\n        } catch {\n            print(\"ERROR -> \\(error.localizedDescription)\")\n        }\n        do {\n            try file.close()\n        }\n    }\n}\n\nprint(\"\\nIntroduce el nombre fichero 1ue quieres mostras.\")\nif let showFile = readLine() {\n\n    if !FileManager.default.fileExists(atPath: path) {\n        print(\"El fichero no existe.\")\n    }\n\n    let process = Process()\n    process.launchPath = \"/bin/cat\"\n    process.arguments = [showFile]\n    process.launch()\n    process.waitUntilExit()\n}\n\nprint(\"\\nIntroduce el nombre del fichero que quieres borrar\")\nif let deleteFileInput = readLine() {\n    \n    deleteFile = deleteFileInput\n\n    if !FileManager.default.fileExists(atPath: path) {\n        print(\"El fichero no existe\")\n}\n    do {\n    try FileManager.default.removeItem(atPath: deleteFile)\n    print(\"Archivo eliminado exitosamente\")\n} catch {\n    print(\"Error al eliminar el archivo: \\(error)\")\n}\n}\n\n\n\n\n// DIFICULTAD EXTRA\nprint(\"\\nDIFICULTAS EXTRA\")\n\nprint(\"\\nIntroduce la ruta y el nombre del fichero.\")\ncreateFile()\n\nwhile true {\n    \n    showMenuOptions()\n\n    if let input = readLine() {\n\n        switch input {\n            case \"1\":\n                addProduct()\n            case \"2\":\n                showProductInfo()\n            case \"3\":\n                print(\"Actualizar producto.\")\n            case \"4\":\n                print(\"Eliminar producto.\")\n            case \"exit\":\n                print(\"Saliendo del programa.\")\n                exitProgram()\n            default:\n                print(\"Opción no valida\")\n        }\n    }\n    sleep(2)\n}\n\n\n\n\nfunc showMenuOptions() {\n\n    print(\"\\nElige una opción.\\n\")\n    print(\"[1] - Añadir producto.\")\n    print(\"[2] - Mostrar procucto.\")\n    print(\"[3] - Actualizar producto.\")\n    print(\"[4] - Eliminar producto.\")\n    print(\"[exit] - Salir del programa\")\n}\n\n\n\nfunc createFile() {\n\n    if let fileName = readLine() {\n    \n        filePath = URL(filePath: fileName)\n        path = fileName\n\n        if FileManager.default.fileExists(atPath: path) {\n            print(\"El fichero ya existe.\")\n        }\n\n        do {\n            try name.write(to: filePath, atomically: true, encoding: .utf8)\n            print(\"Fichero creado.\")\n        } catch {\n            print(\"Error al crear fichero: \\(error)\")\n        }\n    }\n}\n\n\n\nfunc addProduct() {\n\n    print(\"\\nIntroduce el nombre del prosucto.\")\n    if let productNameInput = readLine() {\n    \n        productName = productNameInput\n\n        if !FileManager.default.fileExists(atPath: path) {\n            print(\"El fichero no existe.\")\n        }\n        if let file = FileHandle(forWritingAtPath: path) {\n            do {\n                try file.seekToEnd()\n            } catch {\n                print(error.localizedDescription)\n            }\n            do {\n                try file.write(contentsOf: \"Nobre del producto: \\(productNameInput)\".data(using: .utf8)!)\n                print(\"Nombre del producnto introducido.\")\n            } catch {\n                print(\"ERROR -> \\(error.localizedDescription)\")\n            }\n            do {\n                try file.close()\n            } catch {\n                print(error.localizedDescription)\n            }\n        }\n    }\n\n    print(\"\\nIntroduce cuantos productos venfidos.\")\n    if let soldProductInput = readLine() {\n        soldProduct = soldProductInput\n\n        if let file = FileHandle(forWritingAtPath: path) {\n            do {\n                try file.seekToEnd()\n            } catch {\n                print(error.localizedDescription)\n            }\n            do {\n                try file.write(contentsOf: \"\\nProductos vendidos: \\(soldProductInput)\".data(using: .utf8)!)\n                print(\"Cantidad de productos vendidos introducido.\")\n            } catch {\n                print(\"ERROR -> \\(error.localizedDescription)\")\n            }\n            do {\n                try file.close()\n            } catch {\n                print(error.localizedDescription)\n            }\n        }\n        \n\n    }\n\n    print(\"\\nIntroduce el precio de producto\")\n    if let productPriceInput = readLine(), let intProductPriceInput = Int(productPriceInput) {\n        productPrice = intProductPriceInput\n\n        if let file = FileHandle(forWritingAtPath: path) {\n            do {\n                try file.seekToEnd()\n            } catch {\n                print(error.localizedDescription)\n            }\n            do {\n                try file.write(contentsOf: \"\\nPrecio del producto: \\(productPrice)\\n\\n\".data(using: .utf8)!)\n                print(\"Precio del producto introducido.\")\n            } catch {\n                print(\"ERROR -> \\(error.localizedDescription)\")\n            }\n            do {\n                try file.close()\n            } catch {\n                print(error.localizedDescription)\n            }\n        }\n    }\n}\n\n\n\nfunc showProductInfo() {\n\n    print(\"\\nIntroduce el articulo que quieras mostras.\")\n    if let showProductInput = readLine() {\n\n        if !FileManager.default.fileExists(atPath: path) {\n            print(\"El fichero no existe.\")\n        }\n\n        let catProcess = Process()\n        catProcess.launchPath = \"/bin/cat\"\n        catProcess.arguments = [path]\n\n        let grepProcess = Process()\n        grepProcess.launchPath = \"/usr/bin/grep\"\n        grepProcess.arguments = [\"-A\", \"2\", showProductInput]\n\n        let pipe = Pipe()\n        catProcess.standardOutput = pipe\n        grepProcess.standardInput = pipe\n\n        catProcess.launch()\n        grepProcess.launch()\n        catProcess.waitUntilExit()\n        grepProcess.waitUntilExit()\n    }\n}\n\n\n\nfunc exitProgram() {\n    if !FileManager.default.fileExists(atPath: path) {\n        print(\"El fichero no existe\")\n    }\n    do {\n        try FileManager.default.removeItem(atPath: path)\n        print(\"Archivo eliminado exitosamente\")\n    } catch {\n        print(\"Error al eliminar el archivo: \\(error)\")\n    }\n    exit(0)\n}\n\n\n\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/swift/blackriper.swift",
    "content": "import Foundation\n\nstruct User {\n    let name: String\n    let age: Int\n\n    func getUserString() -> String {\n        return \"\"\"\n         Name: \\(name)\n         Age: \\(age)\n        \"\"\"\n    }\n}\n\nfunc WriteFileExample(){\n    let fileManager = FileManager.default\n    let user = User(name: \"blackriper\", age: 29)\n\n    // write file \n     fileManager.createFile(atPath:\"/home/blackriper/Descargas/blackriper.txt\", contents: user.getUserString().data(using: .utf8))\n\n    // read file\n     guard let data = fileManager.contents(atPath: \"/home/blackriper/Descargas/blackriper.txt\") else{\n          print(\"File not found\")\n          return\n    }\n     let string = String(data: data, encoding: .utf8) ?? user.getUserString()\n     print(string)\n     \n    // delete file\n    do {\n        try fileManager.removeItem(atPath: \"/home/blackriper/Descargas/blackriper.txt\")\n    } catch {\n        print(\"Error deleting file: \\(error)\")\n    }\n    \n }\n WriteFileExample()\n\n // ejercicio extra \n\n struct Product {\n    var name: String\n    var cantity: Int\n    var price: Int\n}\n\nstruct FileOperations{\n   private let fileManager = FileManager.default   \n   private let path = \"/home/blackriper/Descargas/products.txt\"\n\n    func createFile(_ contents: Data?) {\n        fileManager.createFile(atPath:self.path,contents: contents)\n    }\n\n    func readFile(defaultValue: String) {\n        guard let data = fileManager.contents(atPath: self.path) else {\n            print(\"File not found\")\n            return\n        }\n        let string = String(data: data, encoding: .utf8) ?? defaultValue\n         print(string)\n    }\n  \n    func deleteFile() {\n        do {\n            try fileManager.removeItem(atPath: self.path)\n        }catch let error{\n            print(\"Error deleting file: \\(error)\")\n       }\n    }\n}\n\n\nclass Cart { \n    private var products: [Product] = []\n    private let fileManager = FileOperations()\n\n    func addProduct(product: Product) {\n        products.append(product)\n        self.saveFile()\n    \n    }\n    func removeProduct(name:String) {\n        products.removeAll(where: { $0.name == name.uppercased() })\n        self.saveFile()\n    }\n\n      func updateProduct(name:String){\n       guard var product=products.first(where: { $0.name == name.uppercased() })else {\n          print(\"Product not found\")\n          return\n       }\n       print(\"update name \\(product.name):\")\n       let newName=readLine() ?? product.name\n\n       print(\"update cantity \\(product.cantity):\")\n       let newCantity = Int(readLine() ?? \"\\(product.cantity)\")\n\n       print(\"update price \\(product.price):\")\n       let newPrice = Int(readLine() ?? \"\\(product.price)\")\n\n       product.name=newName.uppercased()\n       product.cantity=newCantity ?? product.cantity\n       product.price=newPrice ?? product.price\n       saveFile()\n    }\n\n    func listProducts(){\n        let header=\"\"\"\n            Name     | cantity | Price\n          \"\"\"      \n        print(header)  \n        fileManager.readFile(defaultValue:\"No products\")  \n     }\n\n    func totalSold(){\n        let total=products.reduce(0) { $0 + $1.price }\n        let header=\"\"\"\n            Name       |    cantity   |    Price      |   Total Product\n          \"\"\"      \n       print(header)\n       products.forEach { product in\n        print(\"\\(product.name)      |    \\(product.cantity)       |     \\(product.price)  |       \\(product.price*product.cantity)\")\n       }\n       print(\"Total sold: \\(total)\")\n    }\n    \n\n    func exitApp(){\n      fileManager.deleteFile()\n    }\n  \n   private func saveFile() {\n        let contents = products.map { \"\\($0.name), \\($0.cantity), \\($0.price)\" }.joined(separator: \"\\n\")\n        fileManager.createFile(contents.data(using: .utf8))\n   }\n}\n            \n\n func superMarket(){\n     let cart = Cart()\n  marketloop:\n     while true {\n        print(\"1. Add product\")\n        print(\"2. Remove product\")\n        print(\"3. Update product\")\n        print(\"4. List products\")\n        print(\"5. Total sold\")\n        print(\"6. Exit\")\n        let option = Int(readLine() ?? \"0\") ?? 0\n        switch option {\n           case 1:\n              print(\"Name of product:\")\n              let name = readLine() ?? \"\"\n              print(\"Cantity:\")\n              let cantity = Int(readLine() ?? \"0\") ?? 0\n              print(\"Price:\")\n              let price = Int(readLine() ?? \"0\") ?? 0\n              let product=Product(name: name.uppercased(), cantity: cantity, price: price)\n              cart.addProduct(product: product)\n           \n           case 2:\n              print(\"Name of product:\")\n              let name = readLine() ?? \"\"\n              cart.removeProduct(name: name.uppercased())\n\n           case 3: \n              print(\"Name of product:\")\n              let name = readLine() ?? \"\"\n              cart.updateProduct(name: name.uppercased())\n           case 4:\n              cart.listProducts()\n           \n           case 5:\n              cart.totalSold()\n\n           case 6:\n              cart.exitApp()\n              break marketloop\n            \n           default:\n             print(\"Invalid option\")\n        }\n    }    \n }\n\n superMarket()\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/swift/kontroldev.swift",
    "content": "import Foundation\n\n/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un\n * archivo .txt.\n * - Cada producto se guarda en una línea del arhivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n */\n\n\n\n// Reemplaza 'kontroldev' con tu nombre de usuario real de GitHub si es necesario\nlet fileName = \"kontroldev.txt\"\nlet fileURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent(fileName)\n\nlet content = \"\"\"\nTu nombre\nEdad\nLenguaje de programación favorito\n\"\"\"\n\ndo {\n    // Crear el archivo y escribir el contenido\n    try content.write(to: fileURL, atomically: true, encoding: .utf8)\n    \n    // Leer e imprimir el contenido del archivo\n    let fileContent = try String(contentsOf: fileURL, encoding: .utf8)\n    print(fileContent)\n    \n    // Borrar el archivo\n    try FileManager.default.removeItem(at: fileURL)\n    print(\"El archivo \\(fileName) ha sido borrado.\")\n} catch {\n    print(\"Ha ocurrido un error: \\(error)\")\n}\n\n\n//MARK: - Extra\n\nstruct Product {\n    let name: String\n    var quantity: Int\n    let price: Double\n    \n    func display() {\n        print(\"Producto: \\(name), Cantidad vendida: \\(quantity), Precio: \\(price)\")\n    }\n}\n\n// Función para leer productos del archivo\nfunc readProductsFromFile() -> [Product] {\n    var products = [Product]()\n    let fileName = \"ventas.txt\"\n    let fileURL = URL(fileURLWithPath: fileName)\n    \n    do {\n        let content = try String(contentsOf: fileURL)\n        let lines = content.components(separatedBy: .newlines)\n        \n        for line in lines {\n            let components = line.components(separatedBy: \", \")\n            if components.count == 3 {\n                let name = components[0]\n                let quantity = Int(components[1]) ?? 0\n                let price = Double(components[2]) ?? 0.0\n                let product = Product(name: name, quantity: quantity, price: price)\n                products.append(product)\n            }\n        }\n    } catch {\n        print(\"Error al leer el archivo:\", error.localizedDescription)\n    }\n    \n    return products\n}\n\n// Función para escribir productos en el archivo\nfunc writeProductsToFile(products: [Product]) {\n    let fileName = \"ventas.txt\"\n    let fileURL = URL(fileURLWithPath: fileName)\n    var lines = [String]()\n    \n    for product in products {\n        let line = \"\\(product.name), \\(product.quantity), \\(product.price)\"\n        lines.append(line)\n    }\n    \n    let content = lines.joined(separator: \"\\n\")\n    \n    do {\n        try content.write(to: fileURL, atomically: true, encoding: .utf8)\n    } catch {\n        print(\"Error al escribir en el archivo:\", error.localizedDescription)\n    }\n}\n\n// Función para añadir un producto\nfunc addProduct() -> Product {\n    print(\"Ingrese el nombre del producto:\")\n    let name = readLine() ?? \"\"\n    \n    print(\"Ingrese la cantidad vendida:\")\n    let quantity = Int(readLine() ?? \"0\") ?? 0\n    \n    print(\"Ingrese el precio:\")\n    let price = Double(readLine() ?? \"0.0\") ?? 0.0\n    \n    return Product(name: name, quantity: quantity, price: price)\n}\n\n// Función para consultar todos los productos\nfunc displayAllProducts(products: [Product]) {\n    for product in products {\n        product.display()\n    }\n}\n\n// Función para calcular la venta total\nfunc totalSale(products: [Product]) -> Double {\n    var total: Double = 0.0\n    for product in products {\n        total += Double(product.quantity) * product.price\n    }\n    return total\n}\n\n// Función principal\nfunc main() {\n    var products = readProductsFromFile()\n    \n    var choice: Int = 0\n    repeat {\n        print(\"\\n--- Menú ---\")\n        print(\"1. Añadir producto\")\n        print(\"2. Consultar todos los productos\")\n        print(\"3. Calcular venta total\")\n        print(\"4. Salir\")\n        print(\"Ingrese su opción:\")\n        \n        if let input = readLine(), let option = Int(input) {\n            choice = option\n            \n            switch choice {\n            case 1:\n                let newProduct = addProduct()\n                products.append(newProduct)\n                writeProductsToFile(products: products)\n                print(\"Producto añadido exitosamente.\")\n            case 2:\n                displayAllProducts(products: products)\n            case 3:\n                let total = totalSale(products: products)\n                print(\"Venta total: \\(total)\")\n            case 4:\n                // Borrar el archivo antes de salir\n                let fileName = \"ventas.txt\"\n                let fileURL = URL(fileURLWithPath: fileName)\n                do {\n                    try FileManager.default.removeItem(at: fileURL)\n                    print(\"El archivo se ha borrado exitosamente.\")\n                } catch {\n                    print(\"Error al borrar el archivo:\", error.localizedDescription)\n                }\n            default:\n                print(\"Opción no válida.\")\n            }\n        } else {\n            print(\"Entrada no válida. Inténtelo de nuevo.\")\n        }\n    } while choice != 4\n}\n\n// Ejecutar el programa\nmain()\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/swift/pedroomar23.swift",
    "content": "import Foundation\n\n/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n * \n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo que se llame como\n * tu usuario de GitHub y tenga la extensión .txt.\n * Añade varias líneas en ese fichero:\n * - Tu nombre.\n * - Edad.\n * - Lenguaje de programación favorito.\n * Imprime el contenido.\n * Borra el fichero.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un programa de gestión de ventas que almacena sus datos en un \n * archivo .txt.\n * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n *   [nombre_producto], [cantidad_vendida], [precio].\n * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n *   actualizar, eliminar productos y salir.\n * - También debe poseer opciones para calcular la venta total y por producto.\n * - La opción salir borra el .txt.\n */\n\nlet file = \"pedroomar23.text\"\nlet fileUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent(file)\nlet fileContent = \"\"\"\n    nombre: Pedro Omar\n    edad: 25\n    lenguaje favorito: Swift\n\"\"\"\n\nfunc startFile() {\n    do {\n        try fileContent.write(to: fileUrl, atomically: true, encoding: .utf8)\n        let content = try? String(contentsOf: fileUrl, encoding: .utf8)\n        print(content ?? \"Error al convertir el archivo txt a String\" )\n        \n        try FileManager.default.removeItem(atPath: file)\n    } catch {\n        print(\"Se encontraron varios errores \\(error.localizedDescription)\")\n    }\n}\n\n\n\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/typescript/AChapeton.ts",
    "content": "import { error } from \"console\"\n\nconst fs = require('fs')\nconst readlineSync = require('readline-sync');\n\n//writeFile permite escribir en un fichero, y tambien lo crea si este aun no existe\nfs.writeFile(\n  'achapeton.txt', \n  `\n    - Nombre: Andres Chapeton\n    - Edad: 26\n    - Lenguaje favorito: TypeScript\n  `, \n  (error:  NodeJS.ErrnoException | null) => {\n  if(error) throw error\n  console.log('File created')\n})\n\n//Leer contenido del fichero\nfs.readFile('achapeton.txt', (error:  NodeJS.ErrnoException | null, data: any) => {\n  if(error) throw error\n  console.log(data.toString())\n})\n\n//Eliminar un fichero\nfs.unlink('achapeton.txt', (error:  NodeJS.ErrnoException | null) => {\n  if(error) throw error\n  console.log('File deleted')\n})\n\n\n\n// DIFICULTAD EXTRA\n\nconst guardarVenta = () => {\n  const nombreProducto: string = readlineSync.question('Nombre del producto ');\n  const cantidadVendida: number = readlineSync.question('Cantidad vendida: ');\n  const precioTotal: string = readlineSync.question('Precio: ');\n  fs.appendFile(\n    'ventas.txt', \n    `${nombreProducto}, ${cantidadVendida}, $${precioTotal}]`\n    , \n    (error:  NodeJS.ErrnoException | null) => {\n    if(error) throw error\n  })\n}\nconst listarVentas = () => {\n  fs.readFile('ventas.txt', (error:  NodeJS.ErrnoException | null, data: any) => {\n    if(error) throw error\n    console.log(data.toString())\n  })\n}\n\nconst gestionarVentas = () => {\n  let option: string | null = ''\n  const menu: string = 'MENU: \\n 1. Agregar nueva venta \\n 2. Listar ventas \\n 3. Salir \\n Escoger una opcion: '\n\n  while (option !== '3') {\n    option = readlineSync.question(menu)\n\n    switch (option) {\n      case '1':\n        guardarVenta()\n        break;\n      case '2':\n        listarVentas()\n        break;\n      case '3':\n        fs.unlink('ventas.txt', (error:  NodeJS.ErrnoException | null) => {\n          if(error) throw error\n          console.log('Fichero eliminado')\n        })\n        break;\n      default:\n        console.log('Opcion no valida. Intentar de nuevo.')\n        break;\n    }\n  }\n}\n\ngestionarVentas()"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/typescript/Igledev.ts",
    "content": "//  1º Ejercicio\n    import * as fs from 'fs/promises';\n    import { writeFile, readFile, unlink } from 'fs/promises'; //Utilizamos esto para poder manejar ficheros.\n\n    let nickname : string = 'Igledev';  //Ponemos nuestro nombre de GitHub\n\n    // Creamos el contenido de nuestro archivo\n    let msg : string = `\n        Nombre : Adrián\n        Edad : 19\n        Lenguaje de programación favorito : TypeScript\n    `\n\n    let nombre_archivo = `${nickname}.txt` //  Llamamos al archivo como nuestro nombre de Github\n\n    writeFile(nombre_archivo, msg)\n    .then(() => {\n        // Leemos el contenido de nuestro archivo.\n        return readFile(nombre_archivo, 'utf8');\n    })\n    .then(msg => {\n        // Mostramos el archivo\n        console.log(`Contenido del archivo ${msg}`)\n\n        // Borramos el archivo\n        return unlink(nombre_archivo);\n    })\n    .then(() => {\n        console.log(`Archivo borrado ${nombre_archivo}`)\n    })\n    .catch((error) => {\n        throw new Error(`Fallo en el archivo: ${error}`);\n    });\n\n// Ejercicio Extra\n    let nombreArchivo = 'ventas.txt';\n\n    // Función para mostrar el menú\n    function mostrarMenu() {\n        console.log('\\n--- Menú ---');\n        console.log('1. Añadir producto');\n        console.log('2. Consultar producto');\n        console.log('3. Actualizar producto');\n        console.log('4. Eliminar producto');\n        console.log('5. Calcular venta total');\n        console.log('6. Calcular venta por producto');\n        console.log('7. Salir');\n    }\n\n    // Función para añadir un producto\n    async function agregarProducto() {\n        let nombreProducto = await obtenerInput('Nombre del producto:');\n        let cantidadVendida = parseFloat(await obtenerInput('Cantidad vendida:'));\n        let precio = parseFloat(await obtenerInput('Precio:'));\n        let linea = `${nombreProducto}, ${cantidadVendida}, ${precio}\\n`;\n\n        await fs.appendFile(nombreArchivo, linea);\n        console.log('Producto agregado correctamente.');\n    }\n\n    // Función para consultar un producto\n    async function consultarProducto() {\n        let nombreProducto = await obtenerInput('Nombre del producto:');\n        try {\n            let contenido = await fs.readFile(nombreArchivo, 'utf-8');\n            let lineas = contenido.split('\\n');\n            let producto = lineas.find(linea => linea.startsWith(nombreProducto));\n            if (producto) {\n                console.log('Datos del producto:', producto);\n            } else {\n                console.log('Producto no encontrado.');\n            }\n        } catch (error) {\n            console.error('Error al leer el archivo:', error);\n        }\n    }\n\n    // Función para actualizar un producto\n    async function actualizarProducto() {\n        let nombreProducto = await obtenerInput('Nombre del producto:');\n        let nuevaCantidad = parseFloat(await obtenerInput('Nueva cantidad vendida:'));\n        let nuevoPrecio = parseFloat(await obtenerInput('Nuevo precio:'));\n\n        try {\n            let contenido = await fs.readFile(nombreArchivo, 'utf-8');\n            let lineas = contenido.split('\\n');\n            let indice = lineas.findIndex(linea => linea.startsWith(nombreProducto));\n            if (indice !== -1) {\n                lineas[indice] = `${nombreProducto}, ${nuevaCantidad}, ${nuevoPrecio}`;\n                await fs.writeFile(nombreArchivo, lineas.join('\\n'));\n                console.log('Producto actualizado correctamente.');\n            } else {\n                console.log('Producto no encontrado.');\n            }\n        } catch (error) {\n            console.error('Error al leer/escribir el archivo:', error);\n        }\n    }\n\n    // Función para eliminar un producto\n    async function eliminarProducto() {\n        let nombreProducto = await obtenerInput('Nombre del producto a eliminar:');\n        try {\n            let contenido = await fs.readFile(nombreArchivo, 'utf-8');\n            let lineas = contenido.split('\\n');\n            let filtradas = lineas.filter(linea => !linea.startsWith(nombreProducto));\n            await fs.writeFile(nombreArchivo, filtradas.join('\\n'));\n            console.log('Producto eliminado correctamente.');\n        } catch (error) {\n            console.error('Error al leer/escribir el archivo:', error);\n        }\n    }\n\n    // Función para calcular la venta total\n    async function calcularVentaTotal() {\n        try {\n            let contenido = await fs.readFile(nombreArchivo, 'utf-8');\n            let lineas = contenido.split('\\n');\n            let ventaTotal = 0;\n            for (let linea of lineas) {\n                let [, cantidadVendida, precio] = linea.split(',').map(parseFloat);\n                ventaTotal += cantidadVendida * precio;\n            }\n            console.log('Venta total:', ventaTotal.toFixed(2));\n        } catch (error) {\n            console.error('Error al leer el archivo:', error);\n        }\n    }\n\n    // Función para calcular la venta por producto\n    async function calcularVentaPorProducto() {\n        let nombreProducto = await obtenerInput('Nombre del producto:');\n        try {\n            let contenido = await fs.readFile(nombreArchivo, 'utf-8');\n            let lineas = contenido.split('\\n');\n            let producto = lineas.find(linea => linea.startsWith(nombreProducto));\n            if (producto) {\n                let [, cantidadVendida, precio] = producto.split(',').map(parseFloat);\n                console.log('Venta por producto:', (cantidadVendida * precio).toFixed(2));\n            } else {\n                console.log('Producto no encontrado.');\n            }\n        } catch (error) {\n            console.error('Error al leer el archivo:', error);\n        }\n    }\n\n    // Función para obtener input del usuario\n    async function obtenerInput(mensaje: string): Promise<string> {\n        process.stdout.write(`${mensaje} `);\n        return new Promise(resolve => {\n            process.stdin.once('data', data => {\n                resolve(data.toString().trim());\n            });\n        });\n    }\n\n    // Función para salir y borrar el archivo\n    async function salir() {\n        try {\n            await fs.unlink(nombreArchivo);\n            console.log('Archivo borrado. Saliendo del programa.');\n            process.exit();\n        } catch (error) {\n            console.error('Error al borrar el archivo:', error);\n        }\n    }\n\n    // Función principal\n    async function main() {\n        try {\n            // Mostrar el menú\n            mostrarMenu();\n\n            // Esperar la selección del usuario\n            let opcion = parseInt(await obtenerInput('Selecciona una opción:'));\n\n            // Realizar la operación correspondiente\n            switch (opcion) {\n                case 1:\n                    await agregarProducto();\n                    break;\n                case 2:\n                    await consultarProducto();\n                    break;\n                case 3:\n                    await actualizarProducto();\n                    break;\n                case 4:\n                    await eliminarProducto();\n                    break;\n                case 5:\n                    await calcularVentaTotal();\n                    break;\n                case 6:\n                    await calcularVentaPorProducto();\n                    break;\n                case 7:\n                    await salir();\n                    break;\n                default:\n                    console.log('Opción inválida.');\n            }\n\n            // Volver a mostrar el menú\n            main();\n        } catch (error) {\n            console.error('Error en el programa:', error);\n        }\n    }\n\n    // Iniciar el programa\n    main();"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/typescript/Sac-Corts.ts",
    "content": "import * as fs from 'fs';\nimport * as readline from 'readline';\n\nconst githubUser = 'Sac-Corts';\nconst fileName = `${githubUser}.txt`;\nconst data = `Name: Isaac\\nAge: 22\\nProgramming Language: TypeScript`;\n\nfs.writeFileSync(fileName, data, 'utf8');\nconsole.log('File created and data written');\n\nconst fileContent = fs.readFileSync(fileName, 'utf8');\nconsole.log('File content:');\nconsole.log(fileContent);\n\nfs.unlinkSync(fileName);\nconsole.log(`File ${fileName} deleted`);\n\n// ** Extra Exercise ** //\nconst file = 'products.txt';\n\nconst readData = (): string[] => {\n    try {\n        const data = fs.readFileSync(file, 'utf8');\n        return data.split('\\n').filter(line => line.trim() !== '');\n    } catch (err) {\n        return [];\n    }\n};\n\nconst writeData = (data: string[]): void => {\n    fs.writeFileSync(file, data.join('\\n'), 'utf8');\n};\n\nconst addProduct = (name: string, quantity: string, price: string): void => {\n    const data = readData();\n    data.push(`${name}, ${quantity}, ${price}`);\n    writeData(data);\n    console.log('Product added successfully.');\n};\n\nconst viewProduct = (name: string): void => {\n    const data = readData();\n    const product = data.find(line => line.startsWith(name));\n    if (product) {\n        console.log(`Product found: ${product}`);\n    } else {\n        console.log('Product not found.');\n    }\n};\n\nconst updateProduct = (name: string, quantity: string, price: string): void => {\n    const data = readData();\n    const index = data.findIndex(line => line.startsWith(name));\n    if (index !== -1) {\n        data[index] = `${name}, ${quantity}, ${price}`;\n        writeData(data);\n        console.log('Product updated successfully.');\n    } else {\n        console.log('Product not found.');\n    }\n};\n\nconst deleteProduct = (name: string): void => {\n    const data = readData();\n    const newData = data.filter(line => !line.startsWith(name));\n    if (data.length !== newData.length) {\n        writeData(newData);\n        console.log('Product deleted successfully.');\n    } else {\n        console.log('Product not found.');\n    }\n};\n\nconst calculateTotalSales = (): void => {\n    const data = readData();\n    let total = 0;\n    data.forEach(line => {\n        const [, quantity, price] = line.split(', ');\n        total += parseInt(quantity) * parseFloat(price);\n    });\n    console.log(`Total sales: ${total.toFixed(2)}`);\n};\n\nconst calculateProductSales = (name: string): void => {\n    const data = readData();\n    const product = data.find(line => line.startsWith(name));\n    if (product) {\n        const [, quantity, price] = product.split(', ');\n        const sales = parseInt(quantity) * parseFloat(price);\n        console.log(`Sales for ${name}: ${sales.toFixed(2)}`);\n    } else {\n        console.log('Product not found.');\n    }\n};\n\nconst clearFile = (): void => {\n    if (fs.existsSync(file)) {\n        fs.unlinkSync(file);\n        console.log('File cleared.');\n    } else {\n        console.log('File does not exist.');\n    }\n};\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nconst main = (): void => {\n    rl.question('Choose an option: (add/view/update/delete/total/individual/exit) ', (option) => {\n        switch (option.toLowerCase()) {\n            case 'add':\n                rl.question('Enter product name: ', (name) => {\n                    rl.question('Enter quantity sold: ', (quantity) => {\n                        rl.question('Enter price: ', (price) => {\n                            addProduct(name, quantity, price);\n                            main();\n                        });\n                    });\n                });\n                break;\n            case 'view':\n                rl.question('Enter product name: ', (name) => {\n                    viewProduct(name);\n                    main();\n                });\n                break;\n            case 'update':\n                rl.question('Enter product name: ', (name) => {\n                    rl.question('Enter new quantity sold: ', (quantity) => {\n                        rl.question('Enter new price: ', (price) => {\n                            updateProduct(name, quantity, price);\n                            main();\n                        });\n                    });\n                });\n                break;\n            case 'delete':\n                rl.question('Enter product name: ', (name) => {\n                    deleteProduct(name);\n                    main();\n                });\n                break;\n            case 'total':\n                calculateTotalSales();\n                main();\n                break;\n            case 'individual':\n                rl.question('Enter product name: ', (name) => {\n                    calculateProductSales(name);\n                    main();\n                });\n                break;\n            case 'exit':\n                clearFile();\n                rl.close();\n                break;\n            default:\n                console.log('Invalid option. Please try again.');\n                main();\n                break;\n        }\n    });\n};\n\nmain();"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/typescript/david-git-dev.ts",
    "content": "import { randomUUID } from 'crypto';\nimport * as fs from 'fs';\nimport * as path from 'path';\n\n\nconst rutaArchivo = path.resolve('david-git-dev.txt');\n\nfs.appendFileSync(rutaArchivo,'Nombre: David\\n');\nfs.appendFileSync(rutaArchivo,'Edad: 25 años\\n',);\nfs.appendFileSync(rutaArchivo,'Lenguajes de programacion favoritos: Javascript , Typescript,PHP,Flutter,Java\\n',);//agregando datos\nconst data = fs.readFileSync(rutaArchivo,'utf8')//leyendo archivo\nconsole.log(`Archivo creado en: ${rutaArchivo}\\n con el contenido: \\n ${data}`);\nfs.unlinkSync(rutaArchivo) // borrando el archivo\n//DIFICULTAD EXTRA\ntype Product ={\n  name:string\n  price:number\n  qty:number\n}\nclass SalesManager{\n  private _db:{\n   [key:string]:Product\n  } = {\n    product1:{\n      name:'coca cola espuma',\n      price:100,\n      qty:10\n    },\n    product2:{\n      name:'coca cola lata',\n      price:300,\n      qty:30\n    }\n  }\n  constructor(){}\n  add(data:{name:string,price:string,qty:string}){\n    try{\n        if(Number(data.qty)){\n      const product:Product={\n      name: data.name,\n      price: Number(data.price),\n      qty: Number(data.qty)\n      }\n      this._db[self.crypto.randomUUID()] = product;\n      alert('Producto Agregado')\n      }\n\n\n      }catch(e){\n      if(e instanceof Error) console.log(e.name,e.message)\n      }\n   // this._db.product!.id = self.crypto.randomUUID();\n    //this._db.product = product\n  }\n  getProducts(){\n     console.log(this._db)\n     alert(JSON.stringify(this._db))\n  }\n  update(id:string,name:string,price:string,qty:string){\n\n    try{\n    this._db[id].name = name\n    this._db[id].price = Number(price)\n    this._db[id].qty = Number(qty)\n    alert('Producto actualizado')\n    }catch(e){\n    if(e instanceof Error) console.log(e.name,e.message)\n    }\n    }\n  delete(id:string){\n        delete this._db[id]\n  }\n  getTotal(){\n     let total = Object.values(this._db).reduce((total,product)=>{\n      return total + (product.price * product.qty)\n     },0)\n    alert(`Total en caja:${total}`)\n  }\n  getTotalByProduct(id:string){\ntry{\n  alert(`Total de ${this._db[id].name} -> ${this._db[id].price * this._db[id].qty}`)\n\n}catch(e){\n  if(e instanceof Error) console.log(e.name,e.message)\n}\n  }\n  get data(){\n    return this._db;\n  }\n}\nlet option: string | null\nconst sales = new SalesManager();\n do {\n  alert('Bienvenido a tu gestor de ventas digital!!!');\n  option = prompt(`\n    ¿Que quieres hacer hoy?\n    1-Agregar producto.\n    2-consultar productos.\n    3-Actualizar productos.\n    4-Eliminar productos.\n    5-calcular venta total\n    6-calcular venta por producto.\n    *-Salir del programa.\n    `)\n    option ??='5';\n  let name\n  let price\n  let qty\n    switch(option){\n        case '1':\n         {\n              name = prompt('dame el nombre del producto')\n              price = prompt('dame el precio del producto')\n              qty = prompt('dame la cantidad del producto')\n\n          if(name&&price&&qty) sales.add({name:name!,price:price!,qty:qty!})\n        }\n\n\n        break;\n        case '2':\n        sales.getProducts()\n        break;\n        case '3':\n        {\n        let id = prompt('dame el id del producto')\n            name = prompt('dame el nombre del producto')\n            price = prompt('dame el precio del producto')\n            qty = prompt('dame la cantidad del producto')\n          if(id&&name&&price&&qty) sales.update(id,name,price,qty)\n        }\n\n        break;\n        case '4':\n        {\n        let id = prompt('dame el id del producto')\n        if(id) sales.delete(id)\n        }\n        break;\n        case '5':\n        sales.getTotal()\n        break;\n        case '6':\n        {\n          let id = prompt('dame el id del producto')\n          if(id) sales.getTotalByProduct(id)\n        }\n        break;\n        default:\n        break;\n    }\n    sales.getProducts()\n} while (option);\nconst ruta = path.resolve('db.txt');\nlet json = \"producto,cantidad,precio\\n\";\nObject.values(sales.data).forEach((product) => {\n  json += `${product.name},${product.qty},${product.price}\\n`\n});\nfs.writeFileSync(ruta,json)\n\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/typescript/duendeintemporal.ts",
    "content": "// #11 { retosparaprogramadores } Manejo de Ficheros (File Handling in TypeScript)\n// Bibliography:\n// Professional JavaScript for Web Developers by Matt Frisbie [Frisbie, Matt] (z-lib.org)\n// GPT & Deepseek\n\n/**\n * The File Type\n * The File API is based around the file input field of a form but adds the ability to access file information directly.\n * HTML5 adds a `files` collection to the DOM for the file input element. When one or more files are selected,\n * the `files` collection contains a sequence of `File` objects representing each file. Each `File` object has several\n * read-only properties, including:\n * - `name`: The file name on the local system.\n * - `size`: The size of the file in bytes.\n * - `type`: A string containing the MIME type of the file.\n * - `lastModifiedDate`: A string representing the last time the file was modified (implemented only in Chrome).\n */\n\n/**\n * The FileReader Type\n * The `FileReader` type represents an asynchronous file-reading mechanism. It is similar to `XMLHttpRequest`,\n * but it is used for reading files from the file system instead of reading data from a server. The `FileReader`\n * type offers several methods to read file data:\n * - `readAsText(file, encoding)`: Reads the file as plain text and stores the text in the `result` property.\n * - `readAsDataURL(file)`: Reads the file and stores a data URI representing the file in the `result` property.\n * - `readAsBinaryString(file)`: Reads the file and stores a string where each character represents a byte in the `result` property.\n * - `readAsArrayBuffer(file)`: Reads the file and stores an `ArrayBuffer` containing the file contents in the `result` property.\n */\n\n// We will use Node.js to facilitate file manipulation. Run this file in Node to interact with the console.\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as readline from 'readline';\n\n// Short for console.log\nconst log = console.log;\n\nconst githubUser: string = 'duendeintemporal';\nconst f_path: string = path.join(__dirname, `${githubUser}.txt`);\n\n// Data to write in the file\nconst name: string = 'Niko Zen';\nconst age: string = '41';\nconst favoriteLanguage: string = 'JavaScript';\n\n// Create and write to the file\nfs.writeFile(f_path, `Name: ${name}\\nAge: ${age}\\nFavoriteLanguage: ${favoriteLanguage}\\n`, (err: NodeJS.ErrnoException | null) => {\n    if (err) {\n        console.error('Error creating the file: ', err);\n        return;\n    }\n    log(`File ${githubUser}.txt created successfully.`);\n\n    // Read the content of the file\n    fs.readFile(f_path, 'utf8', (err: NodeJS.ErrnoException | null, data: string) => {\n        if (err) {\n            console.error(`Error reading the file ${githubUser}.txt: `, err);\n            return;\n        }\n        log('Content of the file: ');\n        log(data);\n\n        // Delete the file\n        fs.unlink(f_path, (err: NodeJS.ErrnoException | null) => {\n            if (err) {\n                console.error(`Error deleting the file ${githubUser}.txt: `, err);\n                return;\n            }\n            log(`File ${githubUser}.txt deleted successfully.`);\n        });\n    });\n});\n\n// Extra Difficulty Exercise: Sales Management System\n\nconst filePath: string = 'sales.txt';\n\nconst rl: readline.Interface = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nconst menu = (): void => {\n    log('\\n--- Sales Management ---');\n    log('1. Add Product');\n    log('2. View Products');\n    log('3. Update Product');\n    log('4. Delete Product');\n    log('5. Calculate Total Sales');\n    log('6. Calculate Sales by Product');\n    log('7. Exit');\n    rl.question('Select an option: ', handleMenuOption);\n};\n\nconst handleMenuOption = (option: string): void => {\n    switch (option) {\n        case '1':\n            addProduct();\n            break;\n        case '2':\n            viewProducts();\n            break;\n        case '3':\n            updateProduct();\n            break;\n        case '4':\n            deleteProduct();\n            break;\n        case '5':\n            calculateTotalSales();\n            break;\n        case '6':\n            calculateSalesByProduct();\n            break;\n        case '7':\n            exitProgram();\n            break;\n        default:\n            log('Invalid option, choose a number between 1 and 7. Please try again.');\n            menu();\n            break;\n    }\n};\n\nconst addProduct = (): void => {\n    rl.question('Product Name: ', (name: string) => {\n        rl.question('Quantity Sold: ', (quantity: string) => {\n            rl.question('Price: ', (price: string) => {\n                const product: string = `${name}, ${quantity}, ${price}\\n`;\n                fs.appendFile(filePath, product, (err: NodeJS.ErrnoException | null) => {\n                    if (err) throw err;\n                    log('Product added.');\n                    menu();\n                });\n            });\n        });\n    });\n};\n\nconst viewProducts = (): void => {\n    fs.readFile(filePath, 'utf8', (err: NodeJS.ErrnoException | null, data: string) => {\n        if (err) throw err;\n        log('\\nProducts:\\n' + (data || 'No products registered.'));\n        menu();\n    });\n};\n\nconst updateProduct = (): void => {\n    rl.question('Product Name to Update: ', (name: string) => {\n        rl.question('New Quantity Sold: ', (newQuantity: string) => {\n            rl.question('New Price: ', (newPrice: string) => {\n                fs.readFile(filePath, 'utf8', (err: NodeJS.ErrnoException | null, data: string) => {\n                    if (err) throw err;\n                    const products: string = data.split('\\n').map(line => {\n                        if (line.startsWith(name)) {\n                            return `${name}, ${newQuantity}, ${newPrice}`;\n                        }\n                        return line;\n                    }).join('\\n');\n                    fs.writeFile(filePath, products, (err: NodeJS.ErrnoException | null) => {\n                        if (err) throw err;\n                        log('Product updated.');\n                        menu();\n                    });\n                });\n            });\n        });\n    });\n};\n\nconst deleteProduct = (): void => {\n    rl.question('Product Name to Delete: ', (name: string) => {\n        fs.readFile(filePath, 'utf8', (err: NodeJS.ErrnoException | null, data: string) => {\n            if (err) throw err;\n            const products: string = data.split('\\n').filter(line => !line.startsWith(name)).join('\\n');\n            fs.writeFile(filePath, products, (err: NodeJS.ErrnoException | null) => {\n                if (err) throw err;\n                log('Product deleted.');\n                menu();\n            });\n        });\n    });\n};\n\nconst calculateTotalSales = (): void => {\n    fs.readFile(filePath, 'utf8', (err: NodeJS.ErrnoException | null, data: string) => {\n        if (err) throw err;\n        const total: number = data.split('\\n').reduce((sum: number, line: string) => {\n            const parts: string[] = line.split(', ');\n            return sum + (parseInt(parts[1] || '0') * parseFloat(parts[2] || '0'));\n        }, 0);\n        log(`Total Sales: ${total.toFixed(2)}`);\n        menu();\n    });\n};\n\nconst calculateSalesByProduct = (): void => {\n    rl.question('Product Name: ', (name: string) => {\n        fs.readFile(filePath, 'utf8', (err: NodeJS.ErrnoException | null, data: string) => {\n            if (err) throw err;\n            const total: number = data.split('\\n').reduce((sum: number, line: string) => {\n                const parts: string[] = line.split(', ');\n                if (parts[0] === name) {\n                    return sum + (parseInt(parts[1] || '0') * parseFloat(parts[2] || '0'));\n                }\n                return sum;\n            }, 0);\n            log(`Total Sales for ${name}: ${total.toFixed(2)}`);\n            menu();\n        });\n    });\n};\n\nconst exitProgram = (): void => {\n    fs.unlink(filePath, (err: NodeJS.ErrnoException | null) => {\n        if (err) {\n            console.error('Error deleting the file:', err);\n            return;\n        }\n        log('Exiting the program and deleting the sales data file.');\n        rl.close();\n    });\n};\n\nsetTimeout(() => {\n    menu();\n}, 1200);"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/typescript/eulogioep.ts",
    "content": "import * as fs from 'fs/promises';\nimport * as readline from 'readline';\n\n// Constantes para los nombres de archivo\nconst FILENAME: string = 'info_personal.txt';\nconst SALES_FILENAME: string = 'ventas.txt';\n\n// Interfaz para la estructura de un producto\ninterface Producto {\n    nombre: string;\n    cantidad: number;\n    precio: number;\n}\n\n// Configuración de la interfaz de lectura\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\n// Función para preguntar al usuario\nfunction pregunta(pregunta: string): Promise<string> {\n    return new Promise((resolve) => {\n        rl.question(pregunta, resolve);\n    });\n}\n\n// Función principal\nasync function main(): Promise<void> {\n    await crearArchivoPersonal();\n    await gestionVentas();\n}\n\n// Función para crear y manipular el archivo personal\nasync function crearArchivoPersonal(): Promise<void> {\n    try {\n        // Crear y escribir en el archivo\n        await fs.writeFile(FILENAME, 'Nombre: Juan\\nEdad: 30\\nLenguaje de programación favorito: TypeScript');\n        console.log('Archivo creado y escrito con éxito.');\n\n        // Leer y mostrar el contenido\n        const contenido = await fs.readFile(FILENAME, 'utf8');\n        console.log('Contenido del archivo:');\n        console.log(contenido);\n\n        // Borrar el archivo\n        await fs.unlink(FILENAME);\n        console.log('Archivo borrado con éxito.');\n    } catch (error) {\n        console.error('Error:', (error as Error).message);\n    }\n}\n\n// Función para la gestión de ventas\nasync function gestionVentas(): Promise<void> {\n    let salir = false;\n\n    while (!salir) {\n        console.log('\\n--- Gestión de Ventas ---');\n        console.log('1. Añadir producto');\n        console.log('2. Consultar productos');\n        console.log('3. Actualizar producto');\n        console.log('4. Eliminar producto');\n        console.log('5. Calcular venta total');\n        console.log('6. Calcular venta por producto');\n        console.log('7. Salir');\n\n        const opcion = await pregunta('Seleccione una opción: ');\n\n        switch (opcion) {\n            case '1':\n                await anadirProducto();\n                break;\n            case '2':\n                await consultarProductos();\n                break;\n            case '3':\n                await actualizarProducto();\n                break;\n            case '4':\n                await eliminarProducto();\n                break;\n            case '5':\n                await calcularVentaTotal();\n                break;\n            case '6':\n                await calcularVentaPorProducto();\n                break;\n            case '7':\n                salir = true;\n                await borrarArchivoVentas();\n                rl.close();\n                break;\n            default:\n                console.log('Opción no válida.');\n        }\n    }\n}\n\n// Función para añadir un producto\nasync function anadirProducto(): Promise<void> {\n    const nombre = await pregunta('Nombre del producto: ');\n    const cantidad = parseInt(await pregunta('Cantidad vendida: '));\n    const precio = parseFloat(await pregunta('Precio: '));\n\n    const producto: Producto = { nombre, cantidad, precio };\n    const linea = `${producto.nombre}, ${producto.cantidad}, ${producto.precio}\\n`;\n    await fs.appendFile(SALES_FILENAME, linea);\n    console.log('Producto añadido con éxito.');\n}\n\n// Función para consultar productos\nasync function consultarProductos(): Promise<void> {\n    try {\n        const contenido = await fs.readFile(SALES_FILENAME, 'utf8');\n        console.log('\\nProductos:');\n        console.log(contenido);\n    } catch (error) {\n        if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n            console.log('No hay productos registrados.');\n        } else {\n            console.error('Error al consultar productos:', (error as Error).message);\n        }\n    }\n}\n\n// Función para actualizar un producto\nasync function actualizarProducto(): Promise<void> {\n    const nombreActualizar = await pregunta('Nombre del producto a actualizar: ');\n    const nuevaCantidad = parseInt(await pregunta('Nueva cantidad vendida: '));\n    const nuevoPrecio = parseFloat(await pregunta('Nuevo precio: '));\n\n    try {\n        let contenido = await fs.readFile(SALES_FILENAME, 'utf8');\n        let lineas = contenido.split('\\n');\n        let encontrado = false;\n\n        lineas = lineas.map(linea => {\n            const [nombre, ...resto] = linea.split(', ');\n            if (nombre === nombreActualizar) {\n                encontrado = true;\n                return `${nombre}, ${nuevaCantidad}, ${nuevoPrecio}`;\n            }\n            return linea;\n        });\n\n        if (encontrado) {\n            await fs.writeFile(SALES_FILENAME, lineas.join('\\n'));\n            console.log('Producto actualizado con éxito.');\n        } else {\n            console.log('Producto no encontrado.');\n        }\n    } catch (error) {\n        console.error('Error al actualizar producto:', (error as Error).message);\n    }\n}\n\n// Función para eliminar un producto\nasync function eliminarProducto(): Promise<void> {\n    const nombreEliminar = await pregunta('Nombre del producto a eliminar: ');\n\n    try {\n        let contenido = await fs.readFile(SALES_FILENAME, 'utf8');\n        let lineas = contenido.split('\\n');\n        let encontrado = false;\n\n        lineas = lineas.filter(linea => {\n            const [nombre] = linea.split(', ');\n            if (nombre === nombreEliminar) {\n                encontrado = true;\n                return false;\n            }\n            return true;\n        });\n\n        if (encontrado) {\n            await fs.writeFile(SALES_FILENAME, lineas.join('\\n'));\n            console.log('Producto eliminado con éxito.');\n        } else {\n            console.log('Producto no encontrado.');\n        }\n    } catch (error) {\n        console.error('Error al eliminar producto:', (error as Error).message);\n    }\n}\n\n// Función para calcular la venta total\nasync function calcularVentaTotal(): Promise<void> {\n    try {\n        const contenido = await fs.readFile(SALES_FILENAME, 'utf8');\n        const lineas = contenido.split('\\n');\n        let ventaTotal = 0;\n\n        lineas.forEach(linea => {\n            if (linea.trim() !== '') {\n                const [, cantidad, precio] = linea.split(', ');\n                ventaTotal += parseFloat(cantidad) * parseFloat(precio);\n            }\n        });\n\n        console.log(`Venta total: ${ventaTotal.toFixed(2)}`);\n    } catch (error) {\n        console.error('Error al calcular venta total:', (error as Error).message);\n    }\n}\n\n// Función para calcular la venta por producto\nasync function calcularVentaPorProducto(): Promise<void> {\n    const nombreProducto = await pregunta('Nombre del producto: ');\n\n    try {\n        const contenido = await fs.readFile(SALES_FILENAME, 'utf8');\n        const lineas = contenido.split('\\n');\n        let encontrado = false;\n\n        lineas.forEach(linea => {\n            if (linea.trim() !== '') {\n                const [nombre, cantidad, precio] = linea.split(', ');\n                if (nombre === nombreProducto) {\n                    const ventaProducto = parseFloat(cantidad) * parseFloat(precio);\n                    console.log(`Venta de ${nombreProducto}: ${ventaProducto.toFixed(2)}`);\n                    encontrado = true;\n                }\n            }\n        });\n\n        if (!encontrado) {\n            console.log('Producto no encontrado.');\n        }\n    } catch (error) {\n        console.error('Error al calcular venta por producto:', (error as Error).message);\n    }\n}\n\n// Función para borrar el archivo de ventas\nasync function borrarArchivoVentas(): Promise<void> {\n    try {\n        await fs.unlink(SALES_FILENAME);\n        console.log('Archivo de ventas borrado con éxito.');\n    } catch (error) {\n        if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n            console.log('El archivo de ventas no existe.');\n        } else {\n            console.error('Error al borrar el archivo de ventas:', (error as Error).message);\n        }\n    }\n}\n\n// Ejecutar el programa principal\nmain().catch(console.error);"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/typescript/hozlucas28.ts",
    "content": "import * as fs from 'node:fs'\nimport * as readline from 'readline-sync'\n\n/*\n    Files...\n*/\n\nconsole.log('Files...')\n\nconst FILE_PATH: string = 'hozlucas28.txt'\n\nconsole.log(`\\n// Delete file if exist\nif (fs.existsSync(FILE_PATH)) fs.rmSync(FILE_PATH)\n\n// Create file with content\nconst fileContent: string = ['Lucas Hoz', '22', 'TypeScript'].join('\\\\n')\nfs.writeFileSync(FILE_PATH, fileContent, { encoding: 'utf-8' })\n\n// Print file content\nconst data: string = fs.readFileSync(FILE_PATH, { encoding: 'utf-8' })\nconsole.log(data)\n\n// Delete file\nfs.rmSync(FILE_PATH)\\n`)\n\n// Delete file if exist\nif (fs.existsSync(FILE_PATH)) fs.rmSync(FILE_PATH)\n\n// Create file with content\nconst fileContent: string = ['Lucas Hoz', '22', 'TypeScript'].join('\\n')\nfs.writeFileSync(FILE_PATH, fileContent, { encoding: 'utf-8' })\n\n// Print file content\nconst data: string = fs.readFileSync(FILE_PATH, { encoding: 'utf-8' })\nconsole.log(data)\n\n// Delete file\nfs.rmSync(FILE_PATH)\n\nconsole.log(\n\t'\\n# ---------------------------------------------------------------------------------- #\\n'\n)\n\n/*\n    Additional challenge...\n*/\n\ntype Operation = Uppercase<\n\t| 'add'\n\t| 'delete'\n\t| 'print'\n\t| 'total sales by product'\n\t| 'total sales'\n\t| 'update'\n\t| 'exit'\n>\n\ntype Product = {\n\tamount: number\n\tname: string\n\tprice: number\n\ttotal: number\n}\n\ntype Constructor = {\n\tfilePath: string\n\tproducts?: Omit<Product, 'total'>[]\n}\n\nclass SalesFile {\n\tprivate _fileDeleted: boolean\n\tprivate _filePath: string\n\tprivate _products: Product[]\n\n\tconstructor({ products = [], filePath }: Constructor) {\n\t\tconst mappedProducts: Product[] = this.mapProducts(products)\n\n\t\tthis._fileDeleted = false\n\t\tthis._filePath = filePath\n\t\tthis._products = mappedProducts\n\n\t\tthis.writeFile()\n\t}\n\n\tpublic get products(): Product[] {\n\t\treturn this._products\n\t}\n\n\tprivate set products(products: Omit<Product, 'total'>[]) {\n\t\tconst mappedProducts = this.mapProducts(products)\n\t\tthis._products = mappedProducts\n\t\tthis.writeFile()\n\t}\n\n\tpublic getProductByName(productName: string): {\n\t\tindex: number\n\t} & Product {\n\t\tlet productIndex: number = -1\n\t\tconst product: undefined | Product = this._products.find(\n\t\t\t(product, index) => {\n\t\t\t\tif (product.name.toUpperCase() === productName.toUpperCase()) {\n\t\t\t\t\tproductIndex = index\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t}\n\t\t)\n\t\tif (!product) throw new Error(\"Product name doesn't exist\")\n\n\t\treturn {\n\t\t\tamount: product.amount,\n\t\t\tindex: productIndex,\n\t\t\tname: product.name,\n\t\t\tprice: product.price,\n\t\t\ttotal: product.total,\n\t\t}\n\t}\n\n\tpublic getTotalSales(): { amount: number; total: number } {\n\t\treturn this._products.reduce(\n\t\t\t(prev, current) => ({\n\t\t\t\tamount: prev.amount + current.amount,\n\t\t\t\ttotal: prev.total + current.total,\n\t\t\t}),\n\t\t\t{ amount: 0, total: 0 }\n\t\t)\n\t}\n\n\tprivate joinProducts(products: Product[]): Product[] {\n\t\tconst joinedProducts: Product[] = []\n\n\t\tfor (let i = 0; i < products.length; i++) {\n\t\t\tlet { amount, name, price, total } = products[i]\n\n\t\t\tfor (let j = i + 1; j < products.length; j++) {\n\t\t\t\tconst {\n\t\t\t\t\tamount: nextAmount,\n\t\t\t\t\tname: nextName,\n\t\t\t\t\tprice: nextPrice,\n\t\t\t\t} = products[j]\n\t\t\t\tif (name.toUpperCase() === nextName.toUpperCase()) {\n\t\t\t\t\tamount += nextAmount\n\t\t\t\t\tprice = Math.max(price, nextPrice)\n\t\t\t\t\ttotal = price * amount\n\t\t\t\t\tproducts.splice(j, 1)\n\t\t\t\t}\n\t\t\t}\n\t\t\tjoinedProducts.push({ amount, name, price, total })\n\t\t}\n\n\t\treturn joinedProducts\n\t}\n\n\tprivate mapProducts(products: Omit<Product, 'total'>[]): Product[] {\n\t\tlet mappedProducts: Product[] = products.map((product) => ({\n\t\t\t...product,\n\t\t\ttotal: product.price * product.amount,\n\t\t}))\n\t\tmappedProducts = this.joinProducts(mappedProducts)\n\n\t\treturn mappedProducts\n\t}\n\n\tprivate parseProducts(products = this._products): string {\n\t\treturn products.reduce((prevParsedProd, currentProd) => {\n\t\t\tconst { amount, name, price } = currentProd\n\t\t\tconst parsedProduct: string = `${name}, ${amount}, ${price}`\n\t\t\treturn `${prevParsedProd}\\n${parsedProduct}`.trim()\n\t\t}, '')\n\t}\n\n\tprivate shouldMethodFail(): never | void {\n\t\tif (this._fileDeleted)\n\t\t\tthrow new Error(\n\t\t\t\t'The file was deleted! You should not try any method of this class instance'\n\t\t\t)\n\t}\n\n\tprivate writeFile(): void {\n\t\tfs.writeFileSync(this._filePath, this.parseProducts(this._products), {\n\t\t\tencoding: 'utf-8',\n\t\t})\n\t}\n\n\tpublic appendProducts(products: Omit<Product, 'total'>[]): this | never {\n\t\tthis.shouldMethodFail()\n\t\tthis.products = [...this._products, ...products]\n\t\treturn this\n\t}\n\n\tpublic deleteFile(): void {\n\t\tthis.shouldMethodFail()\n\n\t\tfs.rmSync(this._filePath)\n\t\tthis._fileDeleted = true\n\t}\n\n\tpublic deleteProduct(productName: string): this | never {\n\t\tthis.shouldMethodFail()\n\n\t\tconst { index } = this.getProductByName(productName)\n\n\t\tthis.products = [\n\t\t\t...this._products.slice(0, index),\n\t\t\t...this._products.slice(index + 1),\n\t\t]\n\t\treturn this\n\t}\n\n\tpublic updateProduct({\n\t\tamount,\n\t\tname,\n\t\tprice,\n\t}: {\n\t\tamount?: number\n\t\tname: string\n\t\tprice?: number\n\t}): this | never {\n\t\tthis.shouldMethodFail()\n\n\t\tconst originalProduct = this.getProductByName(name)\n\t\tamount ??= originalProduct.amount\n\t\tprice ??= originalProduct.price\n\n\t\tconst updatedProduct = Object.assign<Product, Partial<Product>>(\n\t\t\t{\n\t\t\t\tamount: originalProduct.amount,\n\t\t\t\tname: originalProduct.name,\n\t\t\t\tprice: originalProduct.price,\n\t\t\t\ttotal: originalProduct.total,\n\t\t\t},\n\t\t\t{\n\t\t\t\tamount,\n\t\t\t\tprice,\n\t\t\t\ttotal: price * amount,\n\t\t\t}\n\t\t)\n\n\t\tthis.products = [\n\t\t\t...this._products.slice(0, originalProduct.index),\n\t\t\tupdatedProduct,\n\t\t\t...this._products.slice(originalProduct.index + 1),\n\t\t]\n\t\treturn this\n\t}\n}\n\nconst salesFile: SalesFile = new SalesFile({ filePath: 'sells.txt' })\n\nlet userInput: Operation\n\ndo {\n\tuserInput = readline\n\t\t.question(\n\t\t\t\"Write an operation ('Add', 'Delete', 'Print', 'Total sales by product', 'Total sales', 'Update', or 'Exit'): \"\n\t\t)\n\t\t.toUpperCase() as Operation\n\n\tswitch (userInput) {\n\t\tcase 'ADD':\n\t\t\tconst newProductName = readline.question('Product name: ')\n\t\t\tif (!newProductName) continue\n\n\t\t\tconst newProductAmount = readline.questionInt('Product amount: ')\n\t\t\tconst newProductPrice = readline.questionInt('Product price: ')\n\n\t\t\tsalesFile.appendProducts([\n\t\t\t\t{\n\t\t\t\t\tname: newProductName,\n\t\t\t\t\tamount: newProductAmount,\n\t\t\t\t\tprice: newProductPrice,\n\t\t\t\t},\n\t\t\t])\n\t\t\tbreak\n\n\t\tcase 'DELETE':\n\t\t\tconst productNameToDelete = readline.question('Product name to delete: ')\n\t\t\tif (!productNameToDelete) continue\n\n\t\t\tsalesFile.deleteProduct(productNameToDelete)\n\t\t\tbreak\n\n\t\tcase 'PRINT':\n\t\t\tconsole.table(salesFile.products)\n\t\t\tbreak\n\n\t\tcase 'TOTAL SALES BY PRODUCT':\n\t\t\tconst productNameToGetTotalSales = readline.question(\n\t\t\t\t'Product name to get total sales: '\n\t\t\t)\n\t\t\tif (!productNameToGetTotalSales) continue\n\n\t\t\tconst product = salesFile.getProductByName(productNameToGetTotalSales)\n\t\t\tconsole.table({\n\t\t\t\tamount: product.amount,\n\t\t\t\tprice: product.price,\n\t\t\t\ttotal: product.total,\n\t\t\t})\n\t\t\tbreak\n\n\t\tcase 'TOTAL SALES':\n\t\t\tconst { amount, total }: { amount: number; total: number } =\n\t\t\t\tsalesFile.getTotalSales()\n\t\t\tconsole.table({ amount, total })\n\t\t\tbreak\n\n\t\tcase 'UPDATE':\n\t\t\tconst productNameToUpdate = readline.question('Product name to update: ')\n\t\t\tif (!productNameToUpdate) continue\n\n\t\t\tconst newAmount = readline.questionInt('New amount for the product: ')\n\t\t\tconst newPrice = readline.questionFloat('New price for the product: ')\n\n\t\t\tsalesFile.updateProduct({\n\t\t\t\tamount: newAmount,\n\t\t\t\tname: productNameToUpdate,\n\t\t\t\tprice: newPrice,\n\t\t\t})\n\t\t\tbreak\n\n\t\tcase 'EXIT':\n\t\t\tsalesFile.deleteFile()\n\t\t\tbreak\n\n\t\tdefault:\n\t\t\tconsole.log('Invalid operation! Try again...')\n\t}\n} while (userInput !== 'EXIT')\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/typescript/ialmontedr0.ts",
    "content": "// Ejercicio 1: Crear un archivo con datos personales y leerlo\r\nimport * as fs from \"fs\";\r\n\r\nconst userName = \"ialmontedr0\";\r\nconst fileName = `${userName}.txt`;\r\n\r\nlet myData: {\r\n  nombre: string;\r\n  edad: number;\r\n  lenguajeFavorito: string;\r\n} = {\r\n  nombre: \"Anthony Almonte\",\r\n  edad: 26,\r\n  lenguajeFavorito: \"TypeScript\",\r\n};\r\n\r\n// Escribimos en el archivo\r\nfs.writeFile(\r\n  fileName,\r\n  `Nombre: ${myData.nombre}\\nEdad: ${myData.edad}\\nLenguaje Favorito: ${myData.lenguajeFavorito}`,\r\n  (err) => {\r\n    if (err) throw err;\r\n    console.log(`El archivo \"${fileName}\" ha sido creado con éxito.`);\r\n\r\n    // Lectura del archivo\r\n    fs.readFile(fileName, \"utf8\", (err, data) => {\r\n      if (err) throw err;\r\n      console.log(`Contenido del archivo \"${fileName}\":\\n${data}`);\r\n      console.log(data);\r\n\r\n      // Eliminar el archivo\r\n      fs.unlink(fileName, (err) => {\r\n        if (err) throw err;\r\n        console.log(`El archivo \"${fileName}\" ha sido eliminado con éxito.`);\r\n      });\r\n    });\r\n  }\r\n);\r\n\r\n// Ejercio 2: Crear archivo archivo.txt\r\n\r\nimport * as fs from \"fs\"; // Importa el módulo fs para operaciones de sistema de archivos\r\nimport * as readline from \"readline\"; // Importa el módulo readline para manejo de entrada y salida en la terminal\r\n\r\nconst salesFileName: string = \"sales.txt\"; // Nombre del archivo que almacenará los datos de ventas\r\n\r\n// Crea una interfaz de readline para la entrada y salida de terminal\r\nconst rl: readline.Interface = readline.createInterface({\r\n  input: process.stdin,\r\n  output: process.stdout,\r\n});\r\n\r\n// Función para añadir un producto al archivo\r\nfunction addProduct(): void {\r\n  rl.question(\"Nombre del producto: \", (name: string) => {\r\n    rl.question(\"Cantidad vendida: \", (quantity: string) => {\r\n      rl.question(\"Precio: \", (price: string) => {\r\n        const productLine: string = `${name}, ${quantity}, ${price}\\n`; // Formato de la línea del producto\r\n        fs.appendFileSync(salesFileName, productLine); // Añade la línea al archivo\r\n        console.log(\"Producto añadido.\");\r\n        mainMenu(); // Regresa al menú principal\r\n      });\r\n    });\r\n  });\r\n}\r\n\r\n// Función para consultar productos en el archivo\r\nfunction viewProducts(): void {\r\n  if (fs.existsSync(salesFileName)) {\r\n    // Verifica si el archivo existe\r\n    const data: string = fs.readFileSync(salesFileName, \"utf8\"); // Lee el contenido del archivo\r\n    console.log(\"Productos:\\n\" + data); // Imprime los productos\r\n  } else {\r\n    console.log(\"No hay productos para mostrar.\");\r\n  }\r\n  mainMenu(); // Regresa al menú principal\r\n}\r\n\r\n// Función para actualizar un producto en el archivo\r\nfunction updateProduct(): void {\r\n  if (!fs.existsSync(salesFileName)) {\r\n    // Verifica si el archivo existe\r\n    console.log(\"No hay productos para actualizar.\");\r\n    return mainMenu(); // Regresa al menú principal si no hay productos\r\n  }\r\n\r\n  const data: string[] = fs.readFileSync(salesFileName, \"utf8\").split(\"\\n\"); // Lee y divide el contenido del archivo en líneas\r\n\r\n  rl.question(\"Nombre del producto a actualizar: \", (name: string) => {\r\n    const index: number = data.findIndex((line) => line.startsWith(`${name},`)); // Encuentra el índice del producto\r\n    if (index === -1) {\r\n      console.log(\"Producto no encontrado.\");\r\n      return mainMenu(); // Regresa al menú principal si el producto no se encuentra\r\n    }\r\n\r\n    rl.question(\"Nueva cantidad vendida: \", (newQuantity: string) => {\r\n      rl.question(\"Nuevo precio: \", (newPrice: string) => {\r\n        data[index] = `${name}, ${newQuantity}, ${newPrice}`; // Actualiza la línea del producto\r\n        fs.writeFileSync(salesFileName, data.join(\"\\n\")); // Escribe los cambios en el archivo\r\n        console.log(\"Producto actualizado.\");\r\n        mainMenu(); // Regresa al menú principal\r\n      });\r\n    });\r\n  });\r\n}\r\n\r\n// Función para eliminar un producto del archivo\r\nfunction deleteProduct(): void {\r\n  if (!fs.existsSync(salesFileName)) {\r\n    // Verifica si el archivo existe\r\n    console.log(\"No hay productos para eliminar.\");\r\n    return mainMenu(); // Regresa al menú principal si no hay productos\r\n  }\r\n\r\n  const data: string[] = fs.readFileSync(salesFileName, \"utf8\").split(\"\\n\"); // Lee y divide el contenido del archivo en líneas\r\n\r\n  rl.question(\"Nombre del producto a eliminar: \", (name: string) => {\r\n    const index: number = data.findIndex((line) => line.startsWith(`${name},`)); // Encuentra el índice del producto\r\n    if (index === -1) {\r\n      console.log(\"Producto no encontrado.\");\r\n      return mainMenu(); // Regresa al menú principal si el producto no se encuentra\r\n    }\r\n\r\n    data.splice(index, 1); // Elimina la línea del producto\r\n    fs.writeFileSync(salesFileName, data.join(\"\\n\")); // Escribe los cambios en el archivo\r\n    console.log(\"Producto eliminado.\");\r\n    mainMenu(); // Regresa al menú principal\r\n  });\r\n}\r\n\r\n// Función para calcular la venta total y por producto\r\nfunction calculateSales(): void {\r\n  if (!fs.existsSync(salesFileName)) {\r\n    // Verifica si el archivo existe\r\n    console.log(\"No hay productos para calcular.\");\r\n    return mainMenu(); // Regresa al menú principal si no hay productos\r\n  }\r\n\r\n  const data: string[] = fs.readFileSync(salesFileName, \"utf8\").split(\"\\n\"); // Lee y divide el contenido del archivo en líneas\r\n\r\n  let totalSales: number = 0;\r\n  const salesByProduct: Record<string, number> = {};\r\n\r\n  data.forEach((line) => {\r\n    if (line.trim() === \"\") return; // Ignora líneas vacías\r\n    const [name, quantity, price] = line.split(\", \");\r\n    const sale: number = parseInt(quantity) * parseFloat(price); // Calcula la venta de cada producto\r\n    totalSales += sale;\r\n    if (!salesByProduct[name]) {\r\n      salesByProduct[name] = 0;\r\n    }\r\n    salesByProduct[name] += sale; // Acumula la venta por producto\r\n  });\r\n\r\n  console.log(\"Venta total:\", totalSales.toFixed(2)); // Imprime la venta total\r\n  console.log(\"Venta por producto:\");\r\n  for (const [name, sale] of Object.entries(salesByProduct)) {\r\n    console.log(`${name}: ${sale.toFixed(2)}`); // Imprime la venta por cada producto\r\n  }\r\n\r\n  mainMenu(); // Regresa al menú principal\r\n}\r\n\r\n// Función para salir y borrar el archivo\r\nfunction exitProgram(): void {\r\n  if (fs.existsSync(salesFileName)) {\r\n    fs.unlinkSync(salesFileName); // Elimina el archivo si existe\r\n    console.log(`Archivo ${salesFileName} borrado.`);\r\n  }\r\n  rl.close(); // Cierra la interfaz de readline\r\n}\r\n\r\n// Menú principal\r\nfunction mainMenu(): void {\r\n  console.log(`\r\n    1. Añadir producto\r\n    2. Consultar productos\r\n    3. Actualizar producto\r\n    4. Eliminar producto\r\n    5. Calcular ventas\r\n    6. Salir\r\n    `);\r\n\r\n  rl.question(\"Elige una opción: \", (option: string) => {\r\n    switch (option) {\r\n      case \"1\":\r\n        addProduct();\r\n        break;\r\n      case \"2\":\r\n        viewProducts();\r\n        break;\r\n      case \"3\":\r\n        updateProduct();\r\n        break;\r\n      case \"4\":\r\n        deleteProduct();\r\n        break;\r\n      case \"5\":\r\n        calculateSales();\r\n        break;\r\n      case \"6\":\r\n        exitProgram();\r\n        break;\r\n      default:\r\n        console.log(\"Opción no válida.\");\r\n        mainMenu();\r\n        break;\r\n    }\r\n  });\r\n}\r\n\r\n// Inicia el programa mostrando el menú principal\r\nmainMenu();\r\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/typescript/qwik-zgheib.ts",
    "content": "import readline from \"readline-sync\";\nimport fs from \"fs\";\nimport path from \"path\";\n\nconst createFile = (fileName: string, content: string): void => {\n  fs.writeFile(fileName, content, (err) => {\n    if (err) {\n      console.error(\"Error writing file:\", err);\n      return;\n    }\n    console.log(\"File created successfully!\");\n  });\n};\n\nconst readFileContent = (fileName: string): void => {\n  fs.readFile(fileName, \"utf8\", (err, data) => {\n    if (err) {\n      console.error(\"Error reading file:\", err);\n      return;\n    }\n    console.log(\"File content:\", data);\n  });\n};\n\nconst deleteFile = (fileName: string): void => {\n  fs.unlink(fileName, (err) => {\n    if (err) {\n      console.error(\"Error deleting file:\", err);\n      return;\n    }\n    console.log(\"File deleted successfully!\");\n  });\n};\n\nconst githubUsername: string = \"qwik-zgheib\";\n\nconst content: string = `Name: Qwik Zgheib\\nAge: 22\\nFavorite Programming Language: JavaScript`;\n\nconst fileName: string = `${githubUsername}.txt`;\n\ncreateFile(fileName, content);\nreadFileContent(fileName);\ndeleteFile(fileName);\n\n/* -- extra challenge */\nconst filePath: string = path.join(process.cwd(), \"sales.txt\");\n\ninterface SalesManagerType {\n  addProduct: () => void;\n  viewProducts: () => void;\n  updateProduct: () => void;\n  deleteProduct: () => void;\n  calculateTotalSales: () => void;\n  calculateSalesByProduct: () => void;\n  exit: () => void;\n}\n\nconst SalesManager: SalesManagerType = {\n  addProduct: (): void => {\n    const name: string = readline.question(\"Enter product name: \");\n    const quantity: number = readline.questionInt(\"Enter quantity sold: \");\n    const price: number = readline.questionFloat(\"Enter price: \");\n\n    const productLine: string = `${name}, ${quantity}, ${price}\\n`;\n    fs.appendFileSync(filePath, productLine);\n    console.log(\"Product added.\");\n  },\n\n  viewProducts: (): void => {\n    if (!fs.existsSync(filePath)) {\n      console.log(\"No products found.\");\n      return;\n    }\n    const data: string = fs.readFileSync(filePath, \"utf8\");\n    console.log(\"Current Products:\\n\" + data);\n  },\n\n  updateProduct: (): void => {\n    if (!fs.existsSync(filePath)) {\n      console.log(\"No products to update.\");\n      return;\n    }\n    const data: string = fs.readFileSync(filePath, \"utf8\");\n    const products: string[] = data.split(\"\\n\").filter((line) => line.trim() !== \"\");\n    const name: string = readline.question(\"Enter product name to update: \");\n\n    const productIndex: number = products.findIndex((line) => line.split(\", \")[0] === name);\n    if (productIndex !== -1) {\n      const quantity: number = readline.questionInt(\"Enter new quantity sold: \");\n      const price: number = readline.questionFloat(\"Enter new price: \");\n      products[productIndex] = `${name}, ${quantity}, ${price}`;\n      fs.writeFileSync(filePath, products.join(\"\\n\") + \"\\n\");\n      console.log(\"Product updated.\");\n    } else {\n      console.log(\"Product not found.\");\n    }\n  },\n\n  deleteProduct: (): void => {\n    if (!fs.existsSync(filePath)) {\n      console.log(\"No products to delete.\");\n      return;\n    }\n    const data: string = fs.readFileSync(filePath, \"utf8\");\n    const products: string[] = data.split(\"\\n\").filter((line) => line.trim() !== \"\");\n    const name: string = readline.question(\"Enter product name to delete: \");\n\n    const newProducts: string[] = products.filter((line) => line.split(\", \")[0] !== name);\n    fs.writeFileSync(filePath, newProducts.join(\"\\n\") + \"\\n\");\n    console.log(\"Product deleted.\");\n  },\n\n  calculateTotalSales: (): void => {\n    if (!fs.existsSync(filePath)) {\n      console.log(\"No sales data found.\");\n      return;\n    }\n    const data: string = fs.readFileSync(filePath, \"utf8\");\n    const products: string[] = data.split(\"\\n\").filter((line) => line.trim() !== \"\");\n\n    let totalSales: number = 0;\n    products.forEach((line) => {\n      const [, quantity, price] = line.split(\", \");\n      totalSales += parseInt(quantity) * parseFloat(price);\n    });\n    console.log(\"Total Sales: $\" + totalSales.toFixed(2));\n  },\n\n  calculateSalesByProduct: (): void => {\n    if (!fs.existsSync(filePath)) {\n      console.log(\"No sales data found.\");\n      return;\n    }\n    const data: string = fs.readFileSync(filePath, \"utf8\");\n    const products: string[] = data.split(\"\\n\").filter((line) => line.trim() !== \"\");\n\n    const salesByProduct: Record<string, number> = {};\n    products.forEach((line) => {\n      const [name, quantity, price] = line.split(\", \");\n      if (!salesByProduct[name]) {\n        salesByProduct[name] = 0;\n      }\n      salesByProduct[name] += parseInt(quantity) * parseFloat(price);\n    });\n\n    for (const [name, total] of Object.entries(salesByProduct)) {\n      console.log(`${name}: $${total.toFixed(2)}`);\n    }\n  },\n\n  exit: (): void => {\n    if (fs.existsSync(filePath)) {\n      fs.unlinkSync(filePath);\n    }\n    console.log(\"Exiting and deleting sales file.\");\n    process.exit();\n  },\n};\n\nconst mainMenu = (): void => {\n  while (true) {\n    console.log(\n      \"\\n1. Add Product\\n2. View Products\\n3. Update Product\\n4. Delete Product\\n5. Calculate Total Sales\\n6. Calculate Sales by Product\\n7. Exit\"\n    );\n\n    let choice: number = readline.questionInt(\"Enter your choice: \");\n\n    while (choice < 1 || choice > 7) {\n      console.log(\"Invalid choice. Please try again.\");\n      choice = readline.questionInt(\"Enter your choice: \");\n    }\n    if (choice === 1) SalesManager.addProduct();\n    if (choice === 2) SalesManager.viewProducts();\n    if (choice === 3) SalesManager.updateProduct();\n    if (choice === 4) SalesManager.deleteProduct();\n    if (choice === 5) SalesManager.calculateTotalSales();\n    if (choice === 6) SalesManager.calculateSalesByProduct();\n    if (choice === 7) SalesManager.exit();\n  }\n};\n\nmainMenu();\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/typescript/victor-Casta.ts",
    "content": "const fs = require('fs')\nconst readline = require('readline')\n\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout\n})\n\n/*\n  * EJERCICIO:\n  * Desarrolla un programa capaz de crear un archivo que se llame como\n  * tu usuario de GitHub y tenga la extensión .txt.\n  * Añade varias líneas en ese fichero:\n  * - Tu nombre.\n  * - Edad.\n  * - Lenguaje de programación favorito.\n  * Imprime el contenido.\n  * Borra el fichero.\n*/\n\nfs.writeFileSync('victor-Casta.txt', 'Victor\\n21\\nJavaScript', 'utf8')\nconsole.log(fs.readFileSync('victor-Casta.txt', 'utf8'))\nfs.unlinkSync('victor-Casta.txt')\n\n/*\n  * DIFICULTAD EXTRA (opcional):\n  * Desarrolla un programa de gestión de ventas que almacena sus datos en un\n  * archivo .txt.\n  * - Cada producto se guarda en una línea del archivo de la siguiente manera:\n  *   [nombre_producto], [cantidad_vendida], [precio].\n  * - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n  *   actualizar, eliminar productos y salir.\n  * - También debe poseer opciones para calcular la venta total y por producto.\n  * - La opción salir borra el .txt.\n*/\n\nfunction promptInput(question: string): Promise<string> {\n  return new Promise((resolve) => rl.question(question, (input) => resolve(input.trim())))\n}\n\nasync function addProduct(): Promise<void> {\n  const name = await promptInput('Nombre del producto: ')\n  const quantity = await promptInput('Cantidad vendida: ')\n  const price = await promptInput('Precio: ')\n\n  fs.appendFileSync('sales.txt', `${name}, ${quantity}, ${price}\\n`, 'utf8')\n  console.log('✅ Producto añadido correctamente.')\n  salesManagement()\n}\n\nasync function consult(): Promise<void> {\n  const name = await promptInput('Ingresa el nombre del producto a consultar: ')\n\n  if (!fs.existsSync('sales.txt')) {\n    console.log('⚠️ Archivo de ventas no encontrado.')\n    return salesManagement()\n  }\n\n  const lines = fs.readFileSync('sales.txt', 'utf8').trim().split('\\n')\n  const foundProducts = lines.filter(line => line.toLowerCase().includes(name.toLowerCase()))\n\n  if (foundProducts.length === 0) {\n    console.log('❌ Producto no encontrado en la lista.')\n  } else {\n    foundProducts.forEach(product => {\n      const [productName, quantity, price] = product.split(', ')\n      console.log(`\\nNombre: ${productName}\\nCantidad vendida: ${quantity}\\nPrecio: ${price}`)\n    })\n  }\n  salesManagement()\n}\n\nasync function updateProduct(): Promise<void> {\n  const name = await promptInput('Nombre del producto a actualizar: ')\n\n  if (!fs.existsSync('sales.txt')) {\n    console.log('⚠️ Archivo de ventas no encontrado.')\n    return salesManagement()\n  }\n\n  const lines = fs.readFileSync('sales.txt', 'utf8').trim().split('\\n')\n  const productIndex = lines.findIndex(line => line.toLowerCase().includes(name.toLowerCase()))\n\n  if (productIndex === -1) {\n    console.log('❌ Producto no encontrado para actualizar.')\n    return salesManagement()\n  }\n\n  const newQuantity = await promptInput('Nueva cantidad vendida: ')\n  const newPrice = await promptInput('Nuevo precio: ')\n  lines[productIndex] = `${name}, ${newQuantity}, ${newPrice}`\n\n  fs.writeFileSync('sales.txt', lines.join('\\n'), 'utf8')\n  console.log('✅ Producto actualizado correctamente.')\n  salesManagement()\n}\n\nasync function deleteProduct(): Promise<void> {\n  const name = await promptInput('Ingresa el nombre del producto a eliminar: ')\n\n  if (!fs.existsSync('sales.txt')) {\n    console.log('⚠️ Archivo de ventas no encontrado.')\n    return salesManagement()\n  }\n\n  const lines = fs.readFileSync('sales.txt', 'utf8').trim().split('\\n')\n  const filteredProducts = lines.filter(line => !line.toLowerCase().includes(name.toLowerCase()))\n\n  if (filteredProducts.length === lines.length) {\n    console.log('❌ Producto no encontrado en la lista.')\n  } else {\n    fs.writeFileSync('sales.txt', filteredProducts.join('\\n'), 'utf8')\n    console.log('✅ Producto eliminado correctamente.')\n  }\n  salesManagement()\n}\n\nfunction displayMenu(): void {\n  console.log('\\n--- Gestión de Ventas ---')\n  console.log('1 - Añadir Producto')\n  console.log('2 - Consultar Producto')\n  console.log('3 - Actualizar Producto')\n  console.log('4 - Eliminar Producto')\n  console.log('0 - Salir')\n}\n\nasync function salesManagement(): Promise<void> {\n  displayMenu()\n\n  const option = await promptInput('Seleccione una opción: ')\n  switch (option) {\n    case '1':\n      await addProduct()\n      break\n    case '2':\n      await consult()\n      break\n    case '3':\n      await updateProduct()\n      break\n    case '4':\n      await deleteProduct()\n      break\n    case '0':\n      console.log('Saliendo del programa...')\n      rl.close()\n      fs.unlinkSync('sales.txt')\n      break\n    default:\n      console.log('⚠️ Opción no válida. Intente nuevamente.')\n      salesManagement()\n  }\n}\n\nsalesManagement()"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/typescript/victoriaparraf.ts",
    "content": "import * as fs from 'fs';\nconst filename = 'victoriaparraf.txt';\n\n// Paso 1: Crear el archivo y añadir varias líneas\nconst data = `Nombre: Victoria Parra\nEdad: 25\nLenguaje de programación favorito: TypeScript`;\n\n// Escribir en el archivo\nfs.writeFileSync(filename, data, 'utf8');\n\n// Paso 2: Leer e imprimir el contenido del archivo\nconst fileContent = fs.readFileSync(filename, 'utf8');\nconsole.log('Contenido del archivo:');\nconsole.log(fileContent);\n\n// Paso 3: Borrar el archivo\nfs.unlinkSync(filename);\nconsole.log(`El archivo ${filename} ha sido borrado.`);\n"
  },
  {
    "path": "Roadmap/11 - MANEJO DE FICHEROS/vb.net/kenysdev.vb",
    "content": "' ╔══════════════════════════════════════╗\n' ║ Autor:  Kenys Alvarado               ║\n' ║ GitHub: https://github.com/Kenysdev  ║\n' ║ 2024 -  VB.NET                       ║\n' ╚══════════════════════════════════════╝\n'-----------------------------------------------\n'MANEJO DE FICHEROS \n'-----------------------------------------------\nImports System.IO\nModule Program\n    Public Class FileMg\n        Public Property _path As String\n\n        Public Sub New(path As String)\n            Me._path = path\n        End Sub\n\n        Public Sub CreateFile()\n            Try\n                If Not File.Exists(_path) Then\n                    Dim archivo As FileStream = File.Create(_path)\n                    archivo.Close()\n                End If\n            Catch ex As Exception\n                Console.WriteLine(\"Error->f.CreateFile->\" & ex.Message)\n            End Try\n        End Sub\n\n        Public Sub AppendLine(line As String)\n            Try\n                Using writer As StreamWriter = File.AppendText(_path)\n                    writer.WriteLine(line)\n                End Using\n            Catch ex As Exception\n                Console.WriteLine(\"Error->f.AppendLine->\" & ex.Message)\n            End Try\n        End Sub\n\n        Public Sub WriteLines(lines As List(Of String))\n            Try\n                File.WriteAllLines(_path, lines)\n            Catch ex As Exception\n                Console.WriteLine(\"Error->f.WriteLines->\" & ex.Message)\n            End Try\n        End Sub\n\n        Public Function ReadLines() As List(Of String)\n            Try\n                Dim lines As List(Of String) = New List(Of String)(File.ReadAllLines(_path))\n                Return lines\n            Catch ex As Exception\n                Console.WriteLine(\"Error->f.ReadLines->\" & ex.Message)\n                Return Nothing\n            End Try\n        End Function\n\n        Public Sub Print()\n            Try\n                Dim lines As String() = File.ReadAllLines(_path)\n                For Each line As String In lines\n                    Console.WriteLine(line)\n                Next\n            Catch ex As Exception\n                Console.WriteLine(\"Error->f.Print->\" & ex.Message)\n            End Try\n        End Sub\n\n        Public Function QueryFile(qry As String) As Integer\n            Try\n                Dim lines As String() = File.ReadAllLines(_path)\n                Dim i As Integer = 0\n                For Each ln As String In lines\n                    Dim parts As String() = ln.Split(\",\"c)\n                    Dim name As String = parts(0)\n                    If name = $\"[{qry}]\" Then\n                        Console.WriteLine(ln)\n                        Return i\n                    End If\n                    i += 1\n                Next\n                Console.WriteLine(\"No existe.\")\n                Return -1\n            Catch ex As Exception\n                Console.WriteLine(\"Error->QueryFile->\" & ex.Message)\n                Return -1\n            End Try\n        End Function\n\n        Public Sub DeleteFile()\n            Try\n                File.Delete(_path)\n                Console.WriteLine(_path & \"-> Eliminado.\")\n            Catch ex As Exception\n                Console.WriteLine(\"Error->DeleteFile->\" & ex.Message)\n            End Try\n        End Sub\n    End Class\n\n    '* Desarrolla un programa de gestión de ventas que almacena sus datos en un \n    '* archivo .txt.\n    '* - Cada producto se guarda en una línea del arhivo de la siguiente manera:\n    '*   [nombre_producto], [cantidad_vendida], [precio].\n    '* - Siguiendo ese formato, y mediante terminal, debe permitir añadir, consultar,\n    '*   actualizar, eliminar productos y salir.\n    '* - También debe poseer opciones para calcular la venta total y por producto.\n    '* - La opción salir borra el .txt.\n\n    Const PATH As String = \"sale_mgt.txt\"\n    Const MSG As String = \"\n        Gestión de Ventas:\n╔═════════════════════════════════╗\n║ 1. Agregar        4. Editar     ║  \n║ 2. Consultar      5. Facturar   ║\n║ 3. Eliminar       6. salir.     ║\n╚═════════════════════════════════╝\n\"\n\n    Public Function AddProduct(Sale As FileMg, Optional prod As String = \"\", Optional qty As String = \"\",\n                               Optional price As String = \"\") As String\n        While True\n            If String.IsNullOrWhiteSpace(prod) Then\n                Console.WriteLine(\"Debe ingresar un nombre de producto.\")\n                Console.Write(\"Producto: \")\n                prod = Console.ReadLine()\n            ElseIf String.IsNullOrWhiteSpace(qty) OrElse Not Double.TryParse(qty, 0) Then\n                Console.WriteLine(\"Debe ingresar una cantidad.\")\n                Console.Write(\"Cantidad: \")\n                qty = Console.ReadLine()\n            ElseIf String.IsNullOrWhiteSpace(price) OrElse Not Double.TryParse(price, 0) Then\n                Console.WriteLine(\"Debe ingresar un precio.\")\n                Console.Write(\"Precio: \")\n                price = Console.ReadLine()\n            Else\n                Dim line As String = $\"[{prod}], [{qty}], [{price}]\"\n                Sale.AppendLine(line)\n                Console.WriteLine($\"{vbCrLf}Guardado\")\n                Console.WriteLine(MSG)\n                Return $\"{line}\"\n            End If\n        End While\n        Return \"\"\n    End Function\n\n    Public Sub QueryProduct(Sale As FileMg, Optional qry As String = \"\")\n        If qry.Length = 0 Then\n            Console.WriteLine(vbLf & \"Consultar Producto.\")\n            Console.Write(\"Nombre: \")\n            qry = Console.ReadLine()\n        End If\n        Sale.QueryFile(qry)\n    End Sub\n\n    Public Sub DeleteProduct(Sale As FileMg, Optional qry As String = \"\")\n        If qry.Length = 0 Then\n            Console.WriteLine(vbCrLf & \"Eliminar Producto.\")\n            Console.Write(\"Nombre: \")\n            qry = Console.ReadLine()\n        End If\n        Dim numLine As Integer = Sale.QueryFile(qry)\n        If numLine <> -1 Then\n            Dim products As List(Of String) = New List(Of String)(Sale.ReadLines())\n            products.RemoveAt(numLine)\n            Sale.WriteLines(products)\n            Console.WriteLine(\"Producto eliminado\")\n        End If\n    End Sub\n\n    Public Sub UpdateProduct(Sale As FileMg, Optional qry As String = \"\")\n        If qry.Length = 0 Then\n            Console.WriteLine(vbCrLf & \"Editar Producto.\")\n            Console.Write(\"Nombre: \")\n            qry = Console.ReadLine()\n        End If\n\n        Dim numLine As Integer = Sale.QueryFile(qry)\n\n        If numLine <> -1 Then\n            Dim products As List(Of String) = New List(Of String)(Sale.ReadLines())\n            Dim line As String = AddProduct(Sale)\n            products(numLine) = line\n            Sale.WriteLines(products)\n        End If\n    End Sub\n\n    Public Sub Invoice(Sale As FileMg)\n        Console.WriteLine(vbLf & \"Factura\" & vbLf & \"---------------------------\")\n        Dim lines As List(Of String) = Sale.ReadLines()\n        Dim total As Double = 0\n        For Each line As String In lines\n            Dim a = line.Split(\",\"c)(1).Trim()\n            Dim qty As Double = Double.Parse(a.Trim(\" \"c, \"[\"c, \"]\"c), System.Globalization.CultureInfo.InvariantCulture)\n\n            Dim b = line.Split(\",\"c)(2).Trim()\n            Dim price As Double = Double.Parse(b.Trim(\" \"c, \"[\"c, \"]\"c), System.Globalization.CultureInfo.InvariantCulture)\n\n            Dim ln = line.Trim(ControlChars.Lf)\n            Dim subTotal As Double = qty * price\n            Dim FsubTotal As String = $\"${subTotal:0.00}\"\n            Console.WriteLine($\"{ln} -> {FsubTotal}\")\n            total += subTotal\n        Next\n        Console.WriteLine(vbLf & $\"Monto total: ${total:0.00}\")\n    End Sub\n\n    Sub Main()\n        Dim user As New FileMg(\"kenysdev.txt\")\n        user.CreateFile()\n        Dim lines As New List(Of String) From {\"Ken\", \"121\"}\n        user.WriteLines(lines)\n        user.AppendLine(\".py\")\n        user.Print()\n        user.DeleteFile()\n\n        '_________________________________\n        Dim Sale As New FileMg(PATH)\n        Sale.CreateFile()\n        Console.WriteLine(MSG)\n\n        While True\n            Console.Write(vbCrLf & \"Opción: \")\n            Dim theoption As String = Console.ReadLine()\n\n            Select Case theoption\n                Case \"1\"\n                    AddProduct(Sale)\n                Case \"2\"\n                    QueryProduct(Sale)\n                Case \"3\"\n                    DeleteProduct(Sale)\n                Case \"4\"\n                    UpdateProduct(Sale)\n                Case \"5\"\n                    Invoice(Sale)\n                Case \"6\"\n                    Console.WriteLine(\"Adios\")\n                    Sale.DeleteFile()\n                    Return\n                Case Else\n                    Console.WriteLine(\"Opción 1 -> 6\")\n            End Select\n        End While\n    End Sub\nEnd Module\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/arduino/santyjl.ino",
    "content": "///12 JSON Y XML///\n\n/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu \n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n */\n\n\n#include <ArduinoJson.h>  // Incluimos la librería ArduinoJson necesaria para manipular objetos JSON\n\nvoid setup() {\n  Serial.begin(9600);  // Inicializamos la comunicación serial a 9600 baudios\n  while (!Serial) continue;  // Esperamos a que la comunicación serial esté lista\n\n  StaticJsonDocument<200> doc;  // Creamos un documento JSON estático con capacidad para 200 bytes\n\n  // A continuación, agregamos datos al documento JSON\n  doc[\"Formato\"] = \"Json\";  // Agregamos una clave \"Formato\" con el valor \"Json\"\n  doc[\"Nombre\"] = \"Santiago\";  \n  doc[\"Edad\"] = 14;  \n  doc[\"Fecha de nacimiento\"] = \"20/01/2010\";  \n  doc[\"Lenguajes de programacion\"] = \"arduino y python\";\n\n  serializeJsonPretty(doc, Serial);  // Serializamos el documento JSON de manera legible y lo enviamos por el puerto serial\n  Serial.println();  // Imprimimos una nueva línea después del documento JSON para mayor claridad\n}\n // no se como hacerle para el xml , perdon\nvoid loop() {\n\n}\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/bash/rantamhack.sh",
    "content": "#!/bin/bash\n\n# * IMPORTANTE: Solo debes subir el fichero de codigo como parte del ejercicio.\n# * \n# * EJERCICIO:\n# * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n# * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n# * - Nombre\n# * - Edad\n# * - Fecha de nacimiento\n# * - Listado de lenguajes de programacion\n# * Muestra el contenido de los archivos.\n# * Borra los archivos.\n#!/bin/bash\n\n\n# Archivo json\n\n    read -p \"Por favor indica tu nombre: \" name\n    read -p \"Indica tu nick de usuario: \" username\n    read -p \"Confirma tu edad: \" age\n    read -p \"Enumera los lenguajes de programacion que conoces: \" -a languages\n\necho \"{ \n    'user1':{\n        'name':'$name'\n        'username':'$username'\n        'age':'$age'\n        'languages':['${languages[*]}']\n    }\n}\" > datos.json\n\ncat datos.json      # Imprime el archivo en varias lineas\n\ndata=$(cat datos.json)       # Imprime el archivo en una soloa linea\necho $data\n\nif [ -f datos.json ]; then\n    rm datos.json\n    echo -e \"\\n[!] El archivo datos.json se ha borrado ....\\n\"\nelse\n    echo -e \"\\n[!] El archivo no existe ....\\n\"\nfi\n\n\n# Archivo XML\n\nread -p \"Por favor indica tu nombre: \" name\nread -p \"Indica tu nick de usuario: \" username\nread -p \"Confirma tu edad: \" age\nread -p \"Enumera los lenguajes de programacion que conoces: \" -a languages\n\n\necho \"<name>$name</name>\" > datos.xml\necho \"<nick>$username</nick>\" >> datos.xml\necho \"<age>$age</age>\" >> datos.xml\necho \"<languages>[${languages[*]}]</languages>\" >> datos.xml\n\ncat datos.xml       # Escribiendo el fichero en distintas lineas\n\ndata=$(cat datos.xml)       # Escribiendo el fichero en una sola linea\necho $data\n\nif [ -f datos.xml ]; then\n    rm datos.xml\n    echo -e \"\\n[!] El archivo datos.xml se ha borrado ....\\n\"\nelse\n    echo -e \"\\n[!] El archivo no existe ....\\n\"\nfi\n\n\n\n# * DIFICULTAD EXTRA (opcional):\n# * Utilizando la logica de creacion de los archivos anteriores, crea un\n# * programa capaz de leer y transformar en una misma clase custom de tu \n# * lenguaje los datos almacenados en el XML y el JSON.\n# * Borra los archivos.\n\nfunction create_json() {\n\n    user2='{\n        \"name\": \"Juan\",\n        \"nick\": \"rantamplan\",\n        \"age\": \"61\",\n        \"languages\": [\"python\", \"bash\", \"java\"]\n    }'\n    \n    echo $user2 > file_json\n\n    echo -e \"\\n\"\n\n    data=$(cat file_json)       \n    echo $data\n\n    if [ -f file_json ]; then\n        rm file_json\n        echo -e \"\\n[!] El archivo file_json se ha borrado ....\\n\"\n    else\n        echo -e \"\\n[!] El archivo no existe ....\\n\"\n    fi\n}\n\n\n        \n        \nfunction create_xml() {\n    \n    \n    echo '<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n        <file_xml>\n            \"<name>Jose</name\" \n            \"<nick>rantamplan</nick>\" \n            \"<age>28</age>\" \n            \"<languages>[java, python, bash]</languages>\" \n        </file_xml>' >> file_xml\n\n    echo -e \"\\n\"\n\n    cat file_xml       \n\n    echo -e \"\\n\"\n\n    data=$(cat file_xml)       \n    echo $data\n\n    if [ -f file_xml ]; then\n        rm file_xml\n        echo -e \"\\n[!] El archivo file_xml se ha borrado ....\\n\"\n    else\n        echo -e \"\\n[!] El archivo no existe ....\\n\"\n    fi\n    \n} \n\n\ncreate_json\ncreate_xml\n\n\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/c#/Andreavzqz.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Xml.Linq;\nusing Newtonsoft.Json;\n\nnamespace ArchivosXmlJson\n{\n    class Program\n    {\n        public class Persona\n        {\n            public string Nombre { get; set; }\n            public int Edad { get; set; }\n            public DateTime FechaNacimiento { get; set; }\n            public List<string> LenguajesProgramacion { get; set; }\n        }\n\n        static void Main(string[] args)\n        {\n            // Datos a guardar\n            Persona persona = new Persona\n            {\n                Nombre = \"Andrea\",\n                Edad = 30,\n                FechaNacimiento = new DateTime(1994, 5, 13),\n                LenguajesProgramacion = new List<string> {\"C#\", \"JavaScript\", \"Python\" }\n            };\n\n            //Archivos\n            string xmlFileName = \"persona.xml\";\n            string jsonFileName = \"persona.json\";\n\n            try\n            {\n                // Crear y guardar XML\n                XElement personaXml = new XElement(\"Persona\",\n                    new XElement(\"Nombre\", persona.Nombre),\n                    new XElement(\"Edad\", persona.Edad),\n                    new XElement(\"FechaNacimiento\", persona.FechaNacimiento.ToString(\"dd-MM-yyy\")),\n                    new XElement(\"LenguajeProgramacion\",\n                        new XElement(\"Lenguaje\", persona.LenguajesProgramacion[0]),\n                        new XElement(\"Lenguaje\", persona.LenguajesProgramacion[1]),\n                        new XElement(\"Lenguaje\", persona.LenguajesProgramacion[2])\n                    )\n                );\n\n                personaXml.Save(xmlFileName);\n\n                //Crear y guardar JSON\n                string personaJson = JsonConvert.SerializeObject(persona, Formatting.Indented);\n                File.WriteAllText(jsonFileName, perosnaJson);\n\n                //Mostrar contenido de los archivos \n                Console.WriteLine(\"Contenido del archivo XML:\");\n                Console.WriteLine(File.ReadAllText(jsonFileName));\n\n                Console.WriteLine(\"\\nContenido del archivo JSON:\");\n                Console.WriteLine(File.ReadAllText(jsonFileName));\n\n                //Dificultad extra: Leer y transformar en clase personalizada\n                Persona personaDesdeXml = LeerDesdeXml(xmlFileName);\n                Persona personaDesdeJson = LeerDesdeJson(jsonFileName);\n\n                //Mostrar datos de la clase personalizada\n                Console.WriteLine(\"\\nDatos leídos desde XML:\");\n                MostrarDatos(personaDesdeXml);\n\n                Console.WriteLine(\"\\nDatos leídos desde JSON:\");\n                MostrarDatos(personaDesdeJson);\n            }\n            finally\n            {\n                // Borrar archivos\n                if (File.Exists(xmlFileName))\n                {\n                    File.Delete(xmlFileName);\n                }\n\n                if (File.Exists(jsonFileName));\n                {\n                    File.Delete(jsonFileName);\n                }\n\n                Console.WriteLine(\"\\Archivos eliminados.\");\n            }\n        }\n\n        static Persona LeerDesdeXml(string fileName)\n        {\n            XElement personaXml = XElement.Load(fileName);\n            Persona persona = new Persona\n            {\n                Nombre = personaXml.Element(\"Nombre\")?.Value,\n                Edad = int.Parse(personaXml.Element(\"Edad\")?.Value),\n                FechaNacimiento = DateTime.Parse(personaXml.Element(\"FechaNacimiento\")?.Value),\n                LenguajesProgramacion = new List<string>()\n            };\n\n            foreach(XElement lenguaje in personaXml.Element(\"LenguajesProgramacion\").Element(\"Lenguaje\"))\n            {\n                persona.LenguajesProgramacion.Add(lenguaje.Value);\n            }\n\n            return persona;\n        }\n\n        static Persona LeerDesdeJson(string fileName)\n        {\n            string personaJson = File.ReadAllText(fileName);\n            return JsonCovert.DeserializeObject<Persona>(personaJson);\n        }\n        \n        static void MostrarDatos(Persona persona)\n        {\n            Console.WriteLine($\"Nombre: {persona.Nombre}\");\n            Console.WriteLine($\"Edad: {persona.Edad}\");\n            Console.WriteLine($\"Fecha de nacimiento: {persona.FechaNacimiento:dd-MM-yyyy}\");\n            Console.WriteLine($\"Lenguajes de programacion: \"+ string.Join(\",\", persona.LenguajesProgramacion));\n        }\n    }\n\n  /*\n\n\n\n- Explicación\nClase Persona:\nRepresenta la estructura de los datos que queremos almacenar, con propiedades para nombre, edad, fecha de nacimiento y un listado de lenguajes de programación.\n\n-Main:\nCreación de XML:\nSe crea un objeto XElement que representa la estructura XML de Persona y se guarda en el archivo persona.xml.\n\nCreación de JSON:\nSe convierte el objeto persona a JSON usando JsonConvert.SerializeObject y se guarda en persona.json.\n\nMostrar contenido de los archivos:\nSe leen y muestran los contenidos de los archivos XML y JSON creados.\n\nLeer desde XML y JSON:\nSe implementan métodos para leer desde XML (LeerDesdeXml) y JSON (LeerDesdeJson) y transformar los datos en instancias de la clase Persona.\n\nMostrar datos de la clase personalizada:\nSe imprimen los datos de las instancias de Persona obtenidas desde XML y JSON.\n\nBorrar archivos:\nSe eliminan los archivos XML y JSON al final.\n\n-Métodos Auxiliares:\n\nLeerDesdeXml: Carga y deserializa los datos desde un archivo XML en un objeto Persona.\nLeerDesdeJson: Carga y deserializa los datos desde un archivo JSON en un objeto Persona.\nMostrarDatos: Muestra los datos de una instancia de Persona.\n\n*/\n}\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/c#/hequebo.cs",
    "content": "using System.Text.Json;\nusing System.Xml;\nusing System.Xml.Linq;\n\nclass Program\n{\n    static void Main(string[] args)\n    {\n        // JSON y XML\n\n        //XML\n        /*\n         * Se puede crear un xml a partir usando la clase XElement\n         */\n        XElement xmlDoc = new XElement(\"XMLDoc\",\n            new XElement(\"Nombre\", \"Emilio Quezada\"),\n            new XElement(\"Edad\", 27),\n            new XElement(\"FechaNacimiento\", new DateTime(1997, 07, 28).ToShortDateString()),\n            new XElement(\"Lenguajes\",\n                new XElement(\"Lenguaje\", \"C#\"),\n                new XElement(\"Lenguaje\", \"Typescript\"),\n                new XElement(\"Lenguaje\", \"VB\")));\n        Console.WriteLine(\"---XML generado---\");\n        Console.WriteLine(xmlDoc);\n        string ruta = \"doc.xml\";\n        /*\n         * La clase XElemento cuenta con el método Save()\n        */\n        xmlDoc.Save(ruta);\n\n        // JSON\n        /*\n         * Se puede generar un JSON con la clase JsonSerializer\n         * y el método Serialize()\n         */\n        var doc = new Persona\n        {\n            Nombre = \"Emilio Quezada\",\n            Edad = 27,\n            FechaNacimiento = new DateTime(1997, 07, 28).ToShortDateString(),\n            Lenguajes = new List<string> { \"C#\", \"TypeScript\", \"VB\" }\n        };\n        ruta = \"doc.json\";\n\n        string jsonDoc = JsonSerializer.Serialize(doc);\n        Console.WriteLine(\"---JSON generado---\");\n        Console.WriteLine(jsonDoc);\n        File.WriteAllText(ruta, jsonDoc);\n\n        // Ejercicio Extra\n        /*\n         * La clase XElement cuenta con el método Load()\n         * para leer un archivo xml y guardarlo como un XElement\n         */\n        ruta = \"doc.xml\";\n        var personaXML = new Persona();\n        xmlDoc = XElement.Load(ruta);\n        /*\n         * Para acceder a los nodos utilizamos el método Element()\n         * y la propiedad Value\n         */\n        personaXML.Nombre = xmlDoc.Element(\"Nombre\")?.Value;\n        personaXML.Edad = int.Parse(xmlDoc.Element(\"Edad\").Value);\n        personaXML.FechaNacimiento = xmlDoc.Element(\"FechaNacimiento\").Value;\n        personaXML.Lenguajes = new List<string>();\n        var lenguajes = xmlDoc.Elements(\"Lenguaje\");\n        /*\n         * Podemos recorrer una lista de elementos dentro de un nodo utilizando\n         * el método Elements() lo cual nos devuelve una colección IEnumerable\n         * que puede ser iterada en un bucle foreach\n         */\n        foreach (var lenguaje in xmlDoc.Element(\"Lenguajes\").Elements(\"Lenguaje\"))\n            personaXML.Lenguajes.Add(lenguaje.Value);\n        Console.WriteLine(\"---Persona leída desde XML---\");\n        Console.WriteLine(personaXML.ToString());\n        /*\n         * Si el archivo existe lo eliminamos\n         */\n        if (File.Exists(ruta))\n            File.Delete(ruta);\n\n        ruta = \"doc.json\";\n        /*\n         * Utilizamos la clase StreamReader para poder\n         * abrir un documento json\n         */\n        StreamReader jsonReader = File.OpenText(ruta);\n        /*\n         * Usamos el método ReadToEnd() para leer el archivo\n         * y guardar el resultado en una variable string\n         */\n        var json = jsonReader.ReadToEnd();\n        /*\n         * La clase JsonSerializer cuenta también con el método\n         * Deserializae<>() en el cual podemos indicar detro de\n         * los símbolos <> la clase a la que queremos que transforme\n         * los datos\n         */\n        var personaJSON = JsonSerializer.Deserialize<Persona>(json);\n        Console.WriteLine(\"---Persona leída desde JSON---\");\n        Console.WriteLine(personaJSON.ToString());\n        /*\n         * Por último cerramos el StreamReader para poder\n         * eliminar el archivo\n         */\n        jsonReader.Close();\n        if (File.Exists(ruta))\n            File.Delete(ruta);\n    }\n\n    \n}\nclass Persona\n{\n    public string Nombre { get; set; }\n    public int Edad { get; set; }\n    public string FechaNacimiento { get; set; }\n    public List<string> Lenguajes { get; set; }\n\n    /*\n     * Sobreescribimos el método ToString()\n     * para poder darle el formato que queremos\n     */\n\n    public override string ToString()\n    {\n        return $\"Nombre: {Nombre}, Edad: {Edad}, Fecha Nacimiento: {FechaNacimiento},\" +\n            $\" Lenguajes: {string.Join(\", \", Lenguajes)}\";\n        /*\n         * string.Join(\", \", Lenguajes) => Utilizamos el método Join para\n         * convertir nuestra lista de strings en un solo string\n         */\n    }\n}"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/c#/isaacus98.cs",
    "content": "﻿/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu \n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n */\n\n\nusing Newtonsoft.Json;\nusing Newtonsoft.Json.Linq;\nusing System.Xml;\n\nnamespace Roadmap\n{\n    internal class Reto11\n    {\n        static void Main(string[] args)\n        {\n            // JSON\n            WriteJson();\n            ReadJson();\n\n            // XML\n            Console.WriteLine();\n            WriteXML();\n            ReadXML();\n\n            // Reto extra\n            XMLToClass();\n            JsonToClass();\n\n            File.Delete(@\"C:\\Users\\\" + Environment.UserName + @\"\\Desktop\\programmer.xml\");\n            File.Delete(@\"C:\\Users\\\" + Environment.UserName + @\"\\Desktop\\programmer.json\");\n        }\n\n        private static void ReadXML()\n        {\n            List<string> languages = new List<string>();\n            using (XmlReader reader = XmlReader.Create(@\"C:\\Users\\\" + Environment.UserName + @\"\\Desktop\\programmer.xml\"))\n            {\n                while (reader.Read())\n                {\n                    if (reader.Name.ToString() == \"Name\")\n                        Console.WriteLine($\"Name: {reader.ReadString()}\");\n\n                    if (reader.Name.ToString() == \"Age\")\n                        Console.WriteLine($\"Age: {reader.ReadString()}\");\n\n                    if (reader.Name.ToString() == \"Birthdate\")\n                        Console.WriteLine($\"Birthdate: {reader.ReadString()}\");\n\n                    if (reader.Name.ToString() == \"Language\")\n                        languages.Add(reader.ReadString());\n                }\n\n                Console.WriteLine($\"Languages: {string.Join(\", \", languages)}\");\n            }\n        }\n\n        private static void WriteXML()\n        {\n            using (XmlWriter writer = XmlWriter.Create(@\"C:\\Users\\\" + Environment.UserName + @\"\\Desktop\\programmer.xml\"))\n            {\n                writer.WriteStartElement(\"Programmer\");\n                writer.WriteElementString(\"Name\", \"Isaac\");\n                writer.WriteElementString(\"Age\", \"26\");\n                writer.WriteElementString(\"Birthdate\", \"1998-02-13\");\n                writer.WriteStartElement(\"ProgrammingLanguages\");\n                writer.WriteElementString(\"Language\", \"C#\");\n                writer.WriteElementString(\"Language\", \"Kotlin\");\n                writer.WriteEndElement();\n                writer.WriteEndElement();\n                writer.Flush();\n            }\n        }\n\n        private static void ReadJson()\n        {\n            JObject o1 = JObject.Parse(File.ReadAllText(@\"C:\\Users\\\" + Environment.UserName + @\"\\Desktop\\programmer.json\"));\n            Console.WriteLine($\"Name: {o1.Value<string>(\"Name\")}\");\n            Console.WriteLine($\"Age: {o1.Value<int>(\"Age\")}\");\n            Console.WriteLine($\"Birthdate: {o1.Value<string>(\"Birthdate\")}\");\n            Console.WriteLine($\"Language: {o1.Value<JArray>(\"Language\")}\");\n        }\n\n        private static void WriteJson()\n        {\n            JObject programmer = new JObject(new JProperty(\"Name\", \"Isaac\"), new JProperty(\"Age\", 26), new JProperty(\"Birthdate\", \"1998-02-13\"), new JProperty(\"Language\", \"C#\", \"Kotlin\"));\n            File.WriteAllText(@\"C:\\Users\\\" + Environment.UserName + @\"\\Desktop\\programmer.json\", programmer.ToString());\n        }\n\n        // Reto extra\n\n        private static void XMLToClass()\n        {\n            Console.WriteLine();\n            Console.WriteLine(\"XML deserialized to objet Programmer\");\n\n            string name = \"\";\n            int age = 0;\n            string birthdate = \"\";\n            List<string> languages = new List<string>();\n\n            using (XmlReader reader = XmlReader.Create(@\"C:\\Users\\\" + Environment.UserName + @\"\\Desktop\\programmer.xml\"))\n            {\n                while (reader.Read())\n                {\n                    if (reader.Name.ToString() == \"Name\")\n                        name = reader.ReadString();\n\n                    if (reader.Name.ToString() == \"Age\")\n                        age = int.Parse(reader.ReadString());\n\n                    if (reader.Name.ToString() == \"Birthdate\")\n                        birthdate = reader.ReadString();\n\n                    if (reader.Name.ToString() == \"Language\")\n                        languages.Add(reader.ReadString());\n                }\n            }\n\n            Programmer programmer = new(name, age, birthdate, languages.ToArray());\n            Console.WriteLine(programmer.ToString());\n        }\n\n        private static void JsonToClass()\n        {\n            Console.WriteLine();\n            Console.WriteLine(\"Json deserialized to objet Programmer\");\n\n            // Deserialize JSON to object\n            Programmer programmer = JsonConvert.DeserializeObject<Programmer>(File.ReadAllText(@\"C:\\Users\\\" + Environment.UserName + @\"\\Desktop\\programmer.json\"));\n            Console.WriteLine(programmer.ToString());\n        }\n    }\n\n    public class Programmer\n    {\n        public string Name;\n        public int Age;\n        public string Birthdate;\n        public string[] Language;\n\n        public Programmer(string name, int age, string birthdate, string[] languages)\n        {\n            Name = name;\n            Age = age;\n            Birthdate = birthdate;\n            Language = languages;\n        }\n\n        public override string ToString()\n        {\n            return $\"Name: {Name}\" + Environment.NewLine + $\"Age: {Age}\" + Environment.NewLine + $\"Date: {Birthdate}\" + Environment.NewLine + $\"Languages: {string.Join(\", \", Language)}\";\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/c#/jamerrq.cs",
    "content": "/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu\n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n */\n\nusing System;\n\nnamespace Roadmap12\n{\n    class JsonAndXML\n    {\n        static void createFile (string extension) {\n            string path = \"datos.\" + extension;\n            if (!System.IO.File.Exists(path)) {\n                System.IO.File.Create(path);\n            }\n        }\n\n        static void writeToFile (string extension) {\n            string path = \"datos.\" + extension;\n            if (extension == \"xml\") {\n                System.IO.File.WriteAllText(path, \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\\n\");\n                System.IO.File.AppendAllText(path, \"<datos>\\n\");\n                System.IO.File.AppendAllText(path, \"    <nombre>Jamerrq</nombre>\\n\");\n                System.IO.File.AppendAllText(path, \"    <edad>25</edad>\\n\");\n                System.IO.File.AppendAllText(path, \"    <fecha_nacimiento>1996-01-01</fecha_nacimiento>\\n\");\n                System.IO.File.AppendAllText(path, \"    <lenguajes>\\n\");\n                System.IO.File.AppendAllText(path, \"        <lenguaje>C#</lenguaje>\\n\");\n                System.IO.File.AppendAllText(path, \"        <lenguaje>JavaScript</lenguaje>\\n\");\n                System.IO.File.AppendAllText(path, \"    </lenguajes>\\n\");\n                System.IO.File.AppendAllText(path, \"</datos>\");\n            } else if (extension == \"json\") {\n                System.IO.File.WriteAllText(path, \"{\\n\");\n                System.IO.File.AppendAllText(path, \"    \\\"nombre\\\": \\\"Jamerrq\\\",\\n\");\n                System.IO.File.AppendAllText(path, \"    \\\"edad\\\": 25,\\n\");\n                System.IO.File.AppendAllText(path, \"    \\\"fecha_nacimiento\\\": \\\"1996-01-01\\\",\\n\");\n                System.IO.File.AppendAllText(path, \"    \\\"lenguajes\\\": [\\n\");\n                System.IO.File.AppendAllText(path, \"        \\\"C#\\\",\\n\");\n                System.IO.File.AppendAllText(path, \"        \\\"JavaScript\\\"\\n\");\n                System.IO.File.AppendAllText(path, \"    ]\\n\");\n                System.IO.File.AppendAllText(path, \"}\");\n            }\n        }\n\n        static void readAndPrintFile (string extension) {\n            string path = \"datos.\" + extension;\n            if (System.IO.File.Exists(path)) {\n                string content = System.IO.File.ReadAllText(path);\n                Console.WriteLine(content);\n            }\n        }\n\n        static void deleteFile (string extension) {\n            string path = \"datos.\" + extension;\n            if (System.IO.File.Exists(path)) {\n                System.IO.File.Delete(path);\n            }\n        }\n\n        static int printMenu () {\n            Console.WriteLine(\"1. Crear archivo XML\");\n            Console.WriteLine(\"2. Crear archivo JSON\");\n            Console.WriteLine(\"3. Mostrar contenido del archivo XML\");\n            Console.WriteLine(\"4. Mostrar contenido del archivo JSON\");\n            Console.WriteLine(\"5. Borrar archivos\");\n            Console.WriteLine(\"6. Salir\");\n            Console.WriteLine(\"Seleccione una opción: \");\n            return Convert.ToInt32(Console.ReadLine());\n        }\n\n        static void Main(string[] args)\n        {\n            int option = 0;\n            do {\n                option = printMenu();\n                switch (option) {\n                    case 1:\n                        createFile(\"xml\");\n                        writeToFile(\"xml\");\n                        break;\n                    case 2:\n                        createFile(\"json\");\n                        writeToFile(\"json\");\n                        break;\n                    case 3:\n                        readAndPrintFile(\"xml\");\n                        break;\n                    case 4:\n                        readAndPrintFile(\"json\");\n                        break;\n                    case 5:\n                        deleteFile(\"xml\");\n                        deleteFile(\"json\");\n                        break;\n                    case 6:\n                        break;\n                    default:\n                        Console.WriteLine(\"Opción no válida.\");\n                        break;\n                }\n            } while (option != 6);\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/c#/kenysdev.cs",
    "content": "/*\n╔═══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado                ║\n║ GitHub: https://github.com/Kenysdev   ║\n║ 2024 -  C#                            ║\n╚═══════════════════════════════════════╝\n-----------------------------------------------\n* JSON Y XML\n-----------------------------------------------\n- son formatos de intercambio de datos que estructuran información.\n- JSON (JavaScript Object Notation) y XML (eXtensible Markup Language)\n*/\nusing System.IO;\nusing System.Text.Json;\nusing System.Xml;\nusing System.Xml.Linq;\n#pragma warning disable CA1050\npublic class Program {\n    static void Main() {\n\n        var userDic = new Dictionary<string, object> {\n            {\"name\", \"Ken\"},\n            {\"age\", 121},\n            {\"dob\", \"1903-03-19\"},\n            {\"prog_langs\", new List<string> { \"cs\", \"py\", \"vb\", \"rs\", \"js\" }}\n        };\n        // _______________________________________________\n        // * JSON\n        // serializar\n        var options = new JsonSerializerOptions {\n            WriteIndented = true\n        };\n\n        string json = JsonSerializer.Serialize(userDic, options);\n        File.WriteAllText(\"user.json\", json);\n\n        // Deserializar\n        string readJson = File.ReadAllText(\"user.json\");\n        var DesUserJson = JsonSerializer.Deserialize<Dictionary<string, object>>(readJson);\n        Console.WriteLine(DesUserJson[\"name\"]);\n\n        // _______________________________________________\n        // * XML\n        // serializar\n        userDic[\"prog_langs\"] = \"cs,py,vb,rs,js\";\n        using (XmlTextWriter writer = new XmlTextWriter(\"user.xml\", null)) {\n            writer.Formatting = Formatting.Indented;\n            writer.WriteStartDocument();\n            writer.WriteStartElement(\"user\");\n\n            foreach (var pair in userDic) {\n                writer.WriteStartElement(pair.Key);\n                writer.WriteValue(pair.Value);\n                writer.WriteEndElement();\n            }\n\n            writer.WriteEndElement();\n            writer.WriteEndDocument();\n        }\n        \n        // Deserializar\n        XDocument doc = XDocument.Load(\"user.xml\");\n        XElement userElement = doc.Root;\n        string name = userElement.Element(\"name\").Value;                                \n        Console.WriteLine(name);\n        \n        /* _______________________________________________\n         * EJERCICIO\n         * Utilizando la lógica de creación de los archivos anteriores, crea un\n         * programa capaz de leer y transformar en una misma clase custom de tu \n         * lenguaje los datos almacenados en el XML y el JSON.\n         * Borra los archivos.\n        */  \n        var theFile = new XmlOrJson(\"user.json\");\n        var dicUser = theFile.AsDictionary();\n        Console.WriteLine(\"\\nDocumento JSON\");\n        foreach (var kv in dicUser) {\n            if (kv.Key != \"prog_langs\") {\n                Console.WriteLine($\"{kv.Key}: {kv.Value}\");\n            }\n        }\n        var progLangs = (List<string>)dicUser[\"prog_langs\"];\n        Console.WriteLine(string.Join(\", \", progLangs));\n\n        //_________\n        var theFile2 = new XmlOrJson(\"user.xml\");\n        var dicUser2 = theFile2.AsDictionary();\n        Console.WriteLine(\"\\nDocumento XML\");\n        foreach (var kv in dicUser2) {\n            if (kv.Key != \"prog_langs\") {\n                Console.WriteLine($\"{kv.Key}: {kv.Value}\");\n            }\n        }\n        var progLangs2 = (List<string>)dicUser2[\"prog_langs\"];\n        Console.WriteLine(string.Join(\", \", progLangs2));\n\n        //_________\n        Console.WriteLine(\"\\nAcceder a sus propiedades\");\n        Console.WriteLine(theFile2.name);\n        Console.WriteLine(theFile2.age);\n        Console.WriteLine(theFile2.dob);\n        File.Delete(\"user.json\");\n        File.Delete(\"user.xml\");\n    }\n\n    public class XmlOrJson {\n        private string path;\n        private string extension;\n        private Dictionary<string, object> dicUser;\n        public string name;\n        public int age;\n        public string dob;\n        public List<string> langs;\n        \n        public XmlOrJson(string path) {\n            this.path = path;\n            this.extension = Path.GetExtension(path).ToLower();\n            this.dicUser = new Dictionary<string, object>();\n            this.name = string.Empty;\n            this.age = 0;\n            this.dob = string.Empty;\n            this.langs = new List<string>();\n        }\n\n        private void addToDic() {\n            dicUser[\"name\"] = name;\n            dicUser[\"age\"] = age;\n            dicUser[\"dob\"] = dob;\n            dicUser[\"prog_langs\"] = langs;\n        }\n        public Dictionary<string, object> AsDictionary() {\n            try {\n                if (extension == \".json\") {\n                    string readJson = File.ReadAllText(path);\n                    using (var document = JsonDocument.Parse(readJson)) {\n                        var root = document.RootElement;\n                        name = root.GetProperty(\"name\").GetString();\n                        age = root.GetProperty(\"age\").GetInt32();\n                        dob = root.GetProperty(\"dob\").GetString();\n                        foreach (JsonElement lang in root.GetProperty(\"prog_langs\").EnumerateArray()) {\n                            langs.Add(lang.GetString());\n                        }\n                        addToDic();\n                        return dicUser;\n                    }                    \n\n                } else if (extension == \".xml\") {\n                    var doc = XDocument.Load(\"user.xml\");\n                    var userElement = doc.Root;\n                    name = userElement.Element(\"name\").Value;\n                    age = int.Parse(userElement.Element(\"age\").Value);\n                    dob = userElement.Element(\"dob\").Value;\n                    langs = userElement.Element(\"prog_langs\").Value.Split(',').ToList();\n                    \n                    addToDic();\n                    return dicUser;\n                } else {\n                    Console.WriteLine(\"Archivo no compatible.\");\n                    return null;\n                }\n            }\n            catch (Exception ex) {\n                Console.WriteLine($\"Exception: {ex.GetType()}\");\n                return null;\n            }\n        }\n    }    \n}\n\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/c++/hectorio23.cpp",
    "content": "#include <iostream>\n#include <fstream>\n#include <json/json.h>\n// #include <libxml2/libxml/tree.h>  \n// sudo pacman -S libxml2\n// la anterior libreria podria importarse simplemente como #include <libxml/tree.h>,\n// sin embargo, por alguna razon me da un error, por esta razon lo importo llamando\n// libxm12\n// #include <libxm12/libxml/xmlwriter.h>\n\n/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu\n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n */\n\n// // Función para crear un archivo XML con los datos proporcionados\n// void createXML(std::string name, int age, std::string dob, std::vector<std::string> languages) {\n//     // Crear un nuevo documento XML\n//     xmlDocPtr doc = xmlNewDoc(BAD_CAST \"1.0\");\n//     xmlNodePtr root = xmlNewNode(NULL, BAD_CAST \"Person\");\n//     xmlDocSetRootElement(doc, root);\n\n//     // Crear nodos para cada dato y agregarlos al árbol XML\n//     xmlNodePtr nameNode = xmlNewChild(root, NULL, BAD_CAST \"Name\", BAD_CAST name.c_str());\n//     xmlNodePtr ageNode = xmlNewChild(root, NULL, BAD_CAST \"Age\", BAD_CAST std::to_string(age).c_str());\n//     xmlNodePtr dobNode = xmlNewChild(root, NULL, BAD_CAST \"DateOfBirth\", BAD_CAST dob.c_str());\n\n//     xmlNodePtr langListNode = xmlNewChild(root, NULL, BAD_CAST \"ProgrammingLanguages\", NULL);\n//     for (const auto& lang : languages) {\n//         xmlNodePtr langNode = xmlNewTextChild(langListNode, NULL, BAD_CAST \"Language\", BAD_CAST lang.c_str());\n//     }\n\n//     // Guardar el documento XML en un archivo\n//     xmlSaveFormatFileEnc(\"./Person.xml\", doc, \"UTF-8\", 1);\n//     xmlFreeDoc(doc); // Liberar memoria\n// }\n\n// Función para crear un archivo JSON con los datos proporcionados\n// Función para crear un archivo JSON con los datos proporcionados\nvoid createJSON(std::string name, int age, std::string dob, std::vector<std::string> languages) {\n    Json::Value root;\n    root[\"Name\"] = name;\n    root[\"Age\"] = age;\n    root[\"DateOfBirth\"] = dob;\n\n    Json::Value langList(Json::arrayValue);\n    for (const auto& lang : languages) {\n        langList.append(lang);\n    }\n    root[\"ProgrammingLanguages\"] = langList;\n\n    std::ofstream jsonFile(\"./Person.json\");\n    jsonFile << root;\n}\n\n// Función para mostrar el contenido de un archivo\nvoid displayFileContents(const std::string& filename) {\n    std::ifstream file(filename);\n    if (file.is_open()) {\n        std::cout << \"Contents of \" << filename << \":\\n\";\n        std::cout << file.rdbuf();\n        std::cout << \"\\n\";\n        file.close();\n    } else {\n        std::cerr << \"Unable to open file: \" << filename << std::endl;\n    }\n}\n\n// Función para borrar los archivos generados\nvoid deleteFiles() {\n    std::remove(\"./Person.json\");\n}\n\nint main() {\n    std::string name = \"Hector Adan\";\n    int age = 19;\n    std::string dob = \"2004-06-28\";\n    std::vector<std::string> languages = {\"C++\", \"Python\", \"JavaScript\"};\n\n    // Crear archivos XML y JSON con los datos proporcionados\n    // createXML(name, age, dob, languages);\n    createJSON(name, age, dob, languages);\n\n    // Mostrar el contenido de los archivos creados\n    displayFileContents(\"./Person.json\");\n\n    // Borrar los archivos generados\n    deleteFiles();\n\n    return EXIT_SUCCESS;\n}\n\n// TODO:  g++ hectorio23.cpp -ljsoncpp\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/ejercicio.md",
    "content": "# #12 JSON Y XML\n> #### Dificultad: Difícil | Publicación: 18/03/24 | Corrección: 25/03/24\n\n## Ejercicio\n\n```\n/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n * \n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu \n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/12 - JSON Y XML/elixir/boterop.ex",
    "content": "defmodule Boterop.JSON do\n  @type json :: String.t()\n\n  @spec encode(map :: map()) :: json()\n  def encode(%{} = map) do\n    json =\n      map\n      |> Map.from_struct()\n      |> Enum.map(fn {k, v} -> format(k, v) end)\n      |> Enum.join(\"\\n\\t\")\n      |> String.slice(0..-2//1)\n\n    \"{\\n\\t#{json}\\n}\"\n  end\n\n  @spec decode(json_string :: json()) :: map()\n  def decode(json_string) do\n    json_string\n    |> String.split(\"\\n\")\n    |> Enum.map(fn v -> Regex.replace(~r/\\\\|\\n|\\t|\\\"|,+$/, v, \"\") end)\n    |> List.delete_at(0)\n    |> List.delete_at(-1)\n    |> to_map()\n  end\n\n  @spec to_map(list :: list(String.t()), map :: map()) :: map()\n  defp to_map(list, map \\\\ %{})\n  defp to_map([], map), do: map\n\n  defp to_map([head | tail], map) do\n    [key | [value]] = String.split(head, \":\")\n    key = String.to_atom(key)\n    value = value |> String.trim() |> format_value()\n    new_map = Map.put(map, key, value)\n\n    to_map(tail, new_map)\n  end\n\n  @spec format_value(text :: String.t()) :: String.t() | integer()\n  defp format_value(\"[\" <> text) do\n    text\n    |> String.replace(\"]\", \"\")\n    |> String.split(\",\")\n    |> Enum.map(fn v -> v |> String.trim() end)\n  end\n\n  defp format_value(text) do\n    case Integer.parse(text) do\n      :error -> text\n      {num, \"\"} -> num\n      {_num, _decimals} -> text\n    end\n  end\n\n  @spec format(k :: String.t(), list(String.t()) | Date.t() | String.t()) :: String.t()\n  defp format(k, [_head | _tail] = list),\n    do: \"#{format_key(k)}: [\\\"#{Enum.join(list, \"\\\", \\\"\")}\\\"],\"\n\n  defp format(k, text), do: \"#{format_key(k)}: \\\"#{text}\\\",\"\n\n  @spec format_key(k :: String.t()) :: String.t()\n  defp format_key(k), do: \"\\\"#{k}\\\"\"\nend\n\ndefmodule Boterop.XML do\n  @type xml :: String.t()\n\n  @spec encode(map :: map()) :: xml()\n  def encode(%{} = map) do\n    xml =\n      map\n      |> Map.from_struct()\n      |> Enum.map(fn {k, v} -> format(k, v) end)\n      |> Enum.join(\"\\n\")\n\n    xml_start = ~S(<?xml version=\"1.0\" encoding=\"UTF-8\"?>)\n    xml_start <> \"\\n#{create_block(\"item\", xml, \"\\n\")}\"\n  end\n\n  @spec decode(xml_string :: xml()) :: map()\n  def decode(xml_string) do\n    map =\n      xml_string\n      |> String.split(\"\\n\")\n      |> List.delete_at(0)\n      |> List.delete_at(0)\n      |> List.delete_at(-1)\n      |> List.delete_at(-1)\n      |> Enum.map(fn v -> Regex.replace(~r/<\\/[a-zA-Z_]+>/, v, \"\") end)\n      |> Enum.map(fn v -> Regex.replace(~r/<item>|\\t/, v, \"\") end)\n      |> Enum.map(fn v -> Regex.replace(~r/</, v, \"\") end)\n      |> Enum.map(fn v -> Regex.replace(~r/>/, v, \":\") end)\n\n    lists =\n      map\n      |> Enum.filter(fn v -> Regex.match?(~r/.*:$/, v) end)\n      |> Enum.map(fn v -> Regex.replace(~r/:/, v, \"\") end)\n      |> Enum.map(fn v -> singularize(v) end)\n\n    map\n    |> Enum.filter(fn v -> not Regex.match?(~r/.*:$/, v) end)\n    |> Enum.map(fn v -> String.trim(v) end)\n    |> join_lists(lists)\n    |> to_map()\n  end\n\n  @spec join_lists(list :: list(String.t()), list(String.t())) :: list(String.t())\n  defp join_lists(list, []), do: list\n\n  defp join_lists(list, [head | tail]) do\n    plural_k = head <> \"s\"\n\n    list_data =\n      list\n      |> Enum.filter(fn v -> String.contains?(v, head) end)\n      |> Enum.map(fn v -> Regex.replace(~r/^.*?:/, v, \"\") end)\n      |> Enum.join(\", \")\n\n    list\n    |> Enum.filter(fn v -> not String.contains?(v, head) end)\n    |> Enum.concat([\"#{plural_k}: [#{list_data}]\"])\n    |> join_lists(tail)\n  end\n\n  @spec to_map(list :: list(String.t()), map :: map()) :: map()\n  defp to_map(list, map \\\\ %{})\n  defp to_map([], map), do: map\n\n  defp to_map([head | tail], map) do\n    [key | [value]] = String.split(head, \":\")\n    key = String.to_atom(key)\n    value = value |> String.trim() |> format_value()\n    new_map = Map.put(map, key, value)\n\n    to_map(tail, new_map)\n  end\n\n  @spec format_value(text :: String.t()) :: String.t() | integer()\n  defp format_value(\"[\" <> text) do\n    text\n    |> String.replace(\"]\", \"\")\n    |> String.split(\",\")\n    |> Enum.map(fn v -> v |> String.trim() end)\n  end\n\n  defp format_value(text) do\n    case Integer.parse(text) do\n      :error -> text\n      {num, \"\"} -> num\n      {_num, _decimals} -> text\n    end\n  end\n\n  @spec format(k :: String.t(), list(String.t()) | Date.t() | String.t()) :: String.t()\n  defp format(k, [_head | _tail] = list) do\n    singular_k =\n      k\n      |> Atom.to_string()\n      |> singularize()\n\n    list_block = create_block(singular_k, list)\n    create_block(k, list_block, \"\\n\")\n  end\n\n  defp format(k, text), do: create_block(k, text)\n\n  @spec create_block(\n          k :: String.t(),\n          v :: String.t(),\n          separator :: String.t()\n        ) :: String.t()\n  defp create_block(k, list, separator \\\\ \"\")\n\n  defp create_block(k, list, _separator) when is_list(list) do\n    block =\n      list\n      |> Enum.join(\"#{format_end_key(k)}\\n\\t#{format_key(k)}\")\n\n    \"\\t#{format_key(k)}#{block}#{format_end_key(k)}\"\n  end\n\n  defp create_block(k, v, separator) do\n    block =\n      v\n      |> to_string()\n      |> String.contains?(\"\\n\")\n      |> if do\n        v\n        |> String.split(\"\\n\")\n        |> Enum.map(fn value -> \"\\t#{value}\" end)\n        |> Enum.join(\"\\n\")\n      else\n        v\n      end\n\n    \"#{format_key(k)}#{separator}#{block}#{separator}#{format_end_key(k)}\"\n  end\n\n  @spec singularize(text :: String.t()) :: String.t()\n  defp singularize(text), do: Regex.replace(~r/s$/, text, \"\")\n\n  @spec format_key(k :: String.t()) :: String.t()\n  defp format_key(k), do: \"<#{k}>\"\n\n  @spec format_end_key(k :: String.t()) :: String.t()\n  defp format_end_key(k), do: \"</#{k}>\"\nend\n\ndefmodule Boterop.User do\n  @type t :: %__MODULE__{\n          name: String.t(),\n          age: integer(),\n          birth_date: Date.t(),\n          programming_languages: list(atom())\n        }\n\n  defstruct [:name, :age, :birth_date, :programming_languages]\n\n  @spec new(\n          name :: String.t(),\n          age :: integer(),\n          birth_date :: Date.t() | [day: integer(), month: integer(), year: integer()],\n          programming_languages :: list(atom())\n        ) :: __MODULE__.t()\n  def new(name, age, birth_date, programming_languages) when is_list(birth_date) do\n    day = Keyword.get(birth_date, :day)\n    month = Keyword.get(birth_date, :month)\n    year = Keyword.get(birth_date, :year)\n\n    %__MODULE__{\n      name: name,\n      age: age,\n      birth_date: Date.new!(year, month, day),\n      programming_languages: programming_languages\n    }\n  end\n\n  def new(name, age, birth_date, programming_languages) do\n    %__MODULE__{\n      name: name,\n      age: age,\n      birth_date: birth_date,\n      programming_languages: programming_languages\n    }\n  end\n\n  @spec from_map(map :: map()) :: __MODULE__.t()\n  def from_map(%{} = map) do\n    __MODULE__\n    |> struct(map)\n    |> format_date()\n  end\n\n  @spec format_date(user :: __MODULE__.t()) :: __MODULE__.t()\n  defp format_date(%__MODULE__{birth_date: text} = user) do\n    [year | [month | [day]]] =\n      text\n      |> String.split(\"-\")\n      |> Enum.map(fn text -> String.to_integer(text) end)\n\n    date = Date.new!(year, month, day)\n    %__MODULE__{user | birth_date: date}\n  end\nend\n\nuser = Boterop.User.new(\"boterop\", 24, [day: 9, month: 10, year: 1999], [:elixir, :python])\n\npath = Regex.replace(~r/\\/[^\\/]+$/, __ENV__.file, \"\")\n\n# Write user.json file\nuser\n|> Boterop.JSON.encode()\n|> (&File.write(\"#{path}/user.json\", &1)).()\n\n# Write user.xml file\nuser\n|> Boterop.XML.encode()\n|> (&File.write(\"#{path}/user.xml\", &1)).()\n\n# Extra\n\n# Read user.json and print the %User{} info\n\"#{path}/user.json\"\n|> File.read!()\n|> Boterop.JSON.decode()\n|> Boterop.User.from_map()\n|> IO.inspect()\n\n# Read user.xml and print the %User{} info\n\"#{path}/user.xml\"\n|> File.read!()\n|> Boterop.XML.decode()\n|> Boterop.User.from_map()\n|> IO.inspect()\n\n# Remove files\nFile.rm_rf(\"#{path}/user.json\")\nFile.rm_rf(\"#{path}/user.xml\")\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/go/FreyFonseca117.go",
    "content": "/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu\n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n */\npackage main\n\nfunc main() {\n\n}\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/go/MiguelP-Dev.go",
    "content": "package main\n\nimport (\n\t\"encoding/json\"\n\t\"encoding/xml\"\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n)\n\nvar errorDecode = errors.New(\"Error: no se pudo decodificar el archivo\")\nvar errorOpen = errors.New(\"Error: no se pudo abrir el archivo\")\nvar errorCreate = errors.New(\"Error: no se pudo crear el archivo\")\nvar errorDelete = errors.New(\"Error: no se pudo eliminar el archivo\")\n\n// En go, tenemos el paquete \"encoding\", para tranajar con archivos como:\n// encoding/xml: Codificación y decodificación en XML.\n// encoding/json: Codificación y decodificación en JSON.\n// encoding/base64: Codificación y decodificación en Base64.\n// encoding/csv: Lectura y escritura de archivos CSV.\n// encoding/gob: Codificación y decodificación en formato GOB de go.\n// encoding/hex: Codificación y decodificación en formato hexadecimal.\n// encoding/ascii85: Codificación y decodificación en formato ASCII85\n// cada uno de estos subpaquetes proporciona herraientas para manejar distintos formatos en go.\n\ntype People struct {\n\tXMLName xml.Name `xml:\"people\"`\n\tPeople  []Person `xml:\"person\" json:\"person\"`\n}\n\ntype Person struct {\n\tName                 string   `xml:\"name\" json:\"name\"`\n\tAge                  uint8    `xml:\"age\" json:\"age\"`\n\tBirthDate            string   `xml:\"birthDate\" json:\"birthDate\"`\n\tProgrammingLanguajes []string `xml:\"proLang\" json:\"proLang\"`\n}\n\nvar xmlFile = \"MiguelP-Dev.xml\"\nvar jsonFile = \"MiguelP-Dev.json\"\n\nvar data = Person{Name: \"Miguel\", Age: uint8(31), BirthDate: \"13/10/1993\", ProgrammingLanguajes: []string{\"Go\", \"JavaScript\"}}\n\nfunc main() {\n\tmakeFile(xmlFile)\n\tmakeFile(jsonFile)\n\tviewFile(jsonFile)\n\tviewFile(xmlFile)\n\n\t// Extra\n\tmakeFile(xmlFile)\n\tmakeFile(jsonFile)\n\n\tjson := NewPerson(jsonFile)\n\txml := NewPerson(xmlFile)\n\n\tfmt.Println(\"Json Class\", json)\n\tfmt.Println(\"Xml Class\", xml)\n\n}\n\nfunc makeFile(filename string) {\n\tfile, err := os.Create(filename)\n\tif err != nil {\n\t\tfmt.Println(\"Error al crear el archivo:\", err)\n\t\treturn\n\t}\n\tdefer file.Close()\n\n\tcreatedFileMessage := \"Archivo creado con éxito: \" + filename\n\n\tif strings.HasSuffix(filename, \".json\") {\n\t\tpeople := []Person{\n\t\t\tdata,\n\t\t}\n\n\t\tencoderJson := json.NewEncoder(file)\n\t\tencoderJson.SetIndent(\"\", \"\t\")\n\t\tif err := encoderJson.Encode(people); err != nil {\n\t\t\tfmt.Println(\"Error al codificar el archivo:\", err)\n\t\t\treturn\n\t\t}\n\n\t\tfmt.Println(createdFileMessage)\n\n\t} else if strings.HasSuffix(filename, \".xml\") {\n\t\tpeople := People{\n\t\t\tPeople: []Person{\n\t\t\t\tdata,\n\t\t\t}}\n\n\t\tencoder := xml.NewEncoder(file)\n\t\tencoder.Indent(\"\", \"\t\")\n\t\tif err = encoder.Encode(people); err != nil {\n\t\t\tfmt.Println(\"Error al codificar el archivo: \", err)\n\t\t\treturn\n\t\t}\n\n\t\tfmt.Println(createdFileMessage)\n\t} else {\n\t\terr := os.Remove(filename)\n\t\tif err != nil {\n\t\t\tfmt.Println(\"Error al eliminar el archivo: \", err)\n\t\t\treturn\n\t\t}\n\t\treturn\n\t}\n\n}\n\nfunc viewFile(filename string) {\n\tfile, err := os.Open(filename)\n\tif err != nil {\n\t\tfmt.Println(errorOpen, err)\n\t\treturn\n\t}\n\tdefer file.Close()\n\n\tif strings.HasSuffix(filename, \".xml\") {\n\t\tvar people People\n\t\tdecoder := xml.NewDecoder(file)\n\t\tif err := decoder.Decode(&people); err != nil {\n\t\t\tfmt.Println(errorDecode, err)\n\t\t\treturn\n\t\t}\n\n\t\tfor _, person := range people.People {\n\t\t\tfmt.Printf(\"Name: %s, Age: %v, BirthDate: %s, Languajes: %s\\n\", person.Name, person.Age, person.BirthDate, person.ProgrammingLanguajes)\n\t\t\terr := os.Remove(filename)\n\t\t\tif err != nil {\n\t\t\t\tfmt.Println(errorDelete, err)\n\t\t\t}\n\t\t}\n\n\t} else if strings.HasSuffix(filename, \".json\") {\n\t\tvar people []Person\n\t\tdecoder := json.NewDecoder(file)\n\t\tif err := decoder.Decode(&people); err != nil {\n\t\t\tfmt.Println(errorDecode, err)\n\t\t}\n\n\t\tfor _, person := range people {\n\t\t\tfmt.Printf(\"Name: %s, Age: %v, BirthDate: %s, Languajes: %s\\n\", person.Name, person.Age, person.BirthDate, person.ProgrammingLanguajes)\n\t\t\terr := os.Remove(filename)\n\t\t\tif err != nil {\n\t\t\t\tfmt.Println(errorDelete, err)\n\t\t\t}\n\t\t}\n\n\t} else {\n\t\terr := os.Remove(filename)\n\t\tif err != nil {\n\t\t\tfmt.Println(errorDelete, err)\n\t\t\treturn\n\t\t}\n\t}\n\treturn\n}\n\n// Extra\n/*\n DIFICULTAD EXTRA (opcional):\n Utilizando la lógica de creación de los archivos anteriores, crea un\n programa capaz de leer y transformar en una misma clase custom de tu\n lenguaje los datos almacenados en el XML y el JSON.\n Borra los archivos.\n*/\n\nfunc NewPerson(file string) []Person {\n\tf, err := os.Open(file)\n\tif err != nil {\n\t\tfmt.Println(errorOpen, err)\n\t\treturn []Person{}\n\t}\n\n\tdefer f.Close()\n\n\tvar data []Person\n\n\tif strings.HasSuffix(file, \".json\") {\n\t\tdecoder := json.NewDecoder(f)\n\t\tif err := decoder.Decode(&data); err != nil {\n\t\t\tfmt.Println(errorDecode, err)\n\t\t}\n\t} else if strings.HasSuffix(file, \".xml\") {\n\t\tvar people People\n\t\tdecoder := xml.NewDecoder(f)\n\t\tif err := decoder.Decode(&people); err != nil {\n\t\t\tfmt.Println(errorDecode, err)\n\t\t}\n\n\t\tfor _, person := range people.People {\n\t\t\tdata = append(data, person)\n\t\t}\n\n\t} else {\n\t\treturn []Person{}\n\t}\n\terr = os.Remove(file)\n\tif err != nil {\n\t\tfmt.Println(errorDelete, err)\n\t\treturn []Person{}\n\t}\n\treturn data\n\n}\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/go/N0HagoNada.go",
    "content": "package main\n\nimport (\n\t\"encoding/json\"\n\t\"encoding/xml\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n)\n\ntype Person struct {\n\tName               string   `json:\"name\" xml:\"name\"`\n\tAge                int      `json:\"age\" xml:\"age\"`\n\tDateBorn           string   `json:\"date\" xml:\"date\"`\n\tProgramingLanguage []string `json:\"languages\" xml:\"languages\"`\n}\n\nfunc main() {\n\t// Escribir JSON\n\tp := Person{Name: \"John Doe\", Age: 30, DateBorn: \"09-12-2023\", ProgramingLanguage: []string{\"go\", \"c\", \"asm\"}}\n\tfileJSON, _ := os.Create(\"person.json\")\n\n\terr := json.NewEncoder(fileJSON).Encode(p)\n\tif err != nil {\n\t\tprint(err.Error())\n\t}\n\tfileJSON.Close()\n\t// Escribir XML\n\tfilexml, _ := os.Create(\"person.xml\")\n\n\tencoder := xml.NewEncoder(filexml)\n\tencoder.Indent(\"\", \"  \")\n\terr = encoder.Encode(p)\n\tif err != nil {\n\t\tprint(err.Error())\n\t}\n\tfilexml.Close()\n\tjsonFile := \"person.json\"\n\txmlFile := \"person.xml\"\n\t// Leer y decodificar JSON\n\tvar personFromJson Person\n\treadAndDecode(jsonFile, &personFromJson, \"json\")\n\n\t// Leer y decodificar XML\n\tvar personFromXml Person\n\treadAndDecode(xmlFile, &personFromXml, \"xml\")\n\n\t// Opcional: imprimir los datos leídos para verificación\n\tfmt.Println(\"Datos desde JSON:\", personFromJson)\n\tfmt.Println(\"Datos desde XML:\", personFromXml)\n\n\t// Eliminar archivos\n\terr = os.Remove(jsonFile)\n\tif err != nil {\n\t\tprint(err.Error())\n\t}\n\terr = os.Remove(xmlFile)\n\tif err != nil {\n\t\tprint(err.Error())\n\t}\n\n}\nfunc readAndDecode(fileName string, person *Person, fileType string) {\n\tfile, err := os.Open(fileName)\n\tif err != nil {\n\t\tfmt.Println(\"Error abriendo el archivo:\", err)\n\t\treturn\n\t}\n\tdefer file.Close()\n\n\tdata, _ := io.ReadAll(file)\n\n\tswitch fileType {\n\tcase \"json\":\n\t\terr := json.Unmarshal(data, person)\n\t\tif err != nil {\n\t\t\tprint(err.Error())\n\t\t}\n\tcase \"xml\":\n\t\terr := xml.Unmarshal(data, person)\n\t\tif err != nil {\n\t\t\tprint(err.Error())\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/go/hozlucas28.go",
    "content": "package main\n\nimport (\n\t\"bufio\"\n\t\"encoding/json\"\n\t\"encoding/xml\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n)\n\ntype JsonAuthor struct {\n\tAge                  int8      `json:\"age\"`\n\tBornDate             time.Time `json:\"bornDate\"`\n\tName                 string    `json:\"name\"`\n\tProgrammingLanguages []string  `json:\"programmingLanguages\"`\n}\n\ntype XmlAuthor struct {\n\tXMLName              xml.Name  `xml:\"author\"`\n\tAge                  int8      `xml:\"age\"`\n\tBornDate             time.Time `xml:\"born-date\"`\n\tName                 string    `xml:\"name\"`\n\tProgrammingLanguages []string  `xml:\"programming-languages>programming-language\"`\n}\n\n/* -------------------------------------------------------------------------- */\n/*                              JSON FILE (CLASS)                             */\n/* -------------------------------------------------------------------------- */\n\ntype JsonFile struct {\n\tpath      string\n\tisDeleted bool\n}\n\nfunc newJsonFile(path string, initialContent JsonAuthor) (*JsonFile, error) {\n\tvar jsonFile JsonFile = JsonFile{path: path, isDeleted: false}\n\n\tfile, createErr := os.Create(jsonFile.path)\n\tif createErr != nil {\n\t\treturn nil, createErr\n\t}\n\n\tfile.Close()\n\tjsonFile.writeContent(initialContent)\n\n\treturn &jsonFile, nil\n}\n\nfunc (jsonFile *JsonFile) getContent() (JsonAuthor, error) {\n\tcontent, openErr := os.ReadFile(jsonFile.path)\n\tif openErr != nil {\n\t\treturn JsonAuthor{}, openErr\n\t}\n\n\tvar jsonAuthor JsonAuthor\n\tunmarshalErr := json.Unmarshal(content, &jsonAuthor)\n\tif unmarshalErr != nil {\n\t\treturn JsonAuthor{}, unmarshalErr\n\t}\n\n\treturn jsonAuthor, nil\n}\n\nfunc (jsonFile *JsonFile) appendLanguage(programmingLanguage string) error {\n\tcontent, contentErr := jsonFile.getContent()\n\tif contentErr != nil {\n\t\treturn contentErr\n\t}\n\n\tcontent.ProgrammingLanguages = append(content.ProgrammingLanguages, programmingLanguage)\n\n\tvar writeErr error = jsonFile.writeContent(content)\n\tif writeErr != nil {\n\t\treturn writeErr\n\t}\n\n\treturn nil\n}\n\nfunc (jsonFile *JsonFile) deleteFile() error {\n\tvar removeErr error = os.Remove(jsonFile.path)\n\tif removeErr != nil {\n\t\treturn removeErr\n\t}\n\tjsonFile.isDeleted = true\n\n\treturn nil\n}\n\nfunc (jsonFile *JsonFile) removeLanguage(programmingLanguage string) error {\n\tvar sanitizedProgrammingLanguage string = strings.ToUpper(programmingLanguage)\n\n\tcontent, contentErr := jsonFile.getContent()\n\tif contentErr != nil {\n\t\treturn contentErr\n\t}\n\n\tvar sanitizedProgrammingLanguages []string = []string{}\n\tfor _, language := range content.ProgrammingLanguages {\n\t\tif strings.ToUpper(language) != sanitizedProgrammingLanguage {\n\t\t\tsanitizedProgrammingLanguages = append(sanitizedProgrammingLanguages, language)\n\t\t}\n\t}\n\tcontent.ProgrammingLanguages = sanitizedProgrammingLanguages\n\n\tvar writeErr error = jsonFile.writeContent(content)\n\tif writeErr != nil {\n\t\treturn writeErr\n\t}\n\n\treturn nil\n}\n\nfunc (jsonFile *JsonFile) updateAge(age int8) error {\n\tcontent, contentErr := jsonFile.getContent()\n\tif contentErr != nil {\n\t\treturn contentErr\n\t}\n\n\tcontent.Age = age\n\tjsonFile.writeContent(content)\n\n\treturn nil\n}\n\nfunc (jsonFile *JsonFile) updateBornDate(bornDate time.Time) error {\n\tcontent, contentErr := jsonFile.getContent()\n\tif contentErr != nil {\n\t\treturn contentErr\n\t}\n\n\tcontent.BornDate = bornDate\n\tjsonFile.writeContent(content)\n\n\treturn nil\n}\n\nfunc (jsonFile *JsonFile) updateName(name string) error {\n\tcontent, contentErr := jsonFile.getContent()\n\tif contentErr != nil {\n\t\treturn contentErr\n\t}\n\n\tcontent.Name = name\n\tjsonFile.writeContent(content)\n\n\treturn nil\n}\n\nfunc (jsonFile *JsonFile) writeContent(content JsonAuthor) error {\n\tstringifiedContent, marshalIndentErr := json.MarshalIndent(content, \"\", \"\\t\")\n\tif marshalIndentErr != nil {\n\t\treturn marshalIndentErr\n\t}\n\n\tvar writeErr error = os.WriteFile(jsonFile.path, stringifiedContent, os.ModeAppend)\n\tif writeErr != nil {\n\t\treturn writeErr\n\t}\n\n\treturn nil\n}\n\n/* -------------------------------------------------------------------------- */\n/*                              XML FILE (CLASS)                              */\n/* -------------------------------------------------------------------------- */\n\ntype XmlFile struct {\n\tpath      string\n\tisDeleted bool\n}\n\nfunc newXmlFile(path string, initialContent XmlAuthor) (*XmlFile, error) {\n\tvar xmlFile XmlFile = XmlFile{path: path, isDeleted: false}\n\n\tfile, createErr := os.Create(xmlFile.path)\n\tif createErr != nil {\n\t\treturn nil, createErr\n\t}\n\n\tfile.Close()\n\txmlFile.writeContent(initialContent)\n\n\treturn &xmlFile, nil\n}\n\nfunc (xmlFile *XmlFile) getContent() (XmlAuthor, error) {\n\tcontent, openErr := os.ReadFile(xmlFile.path)\n\tif openErr != nil {\n\t\treturn XmlAuthor{}, openErr\n\t}\n\n\tfmt.Printf(\"\\n%s\\n\", string(content))\n\n\tvar xmlAuthor XmlAuthor\n\tunmarshalErr := xml.Unmarshal(content, &xmlAuthor)\n\tif unmarshalErr != nil {\n\t\treturn XmlAuthor{}, unmarshalErr\n\t}\n\n\tfmt.Printf(\"\\n%v\\n\", xmlAuthor)\n\n\treturn xmlAuthor, nil\n}\n\nfunc (xmlFile *XmlFile) appendLanguage(programmingLanguage string) error {\n\tcontent, contentErr := xmlFile.getContent()\n\tif contentErr != nil {\n\t\treturn contentErr\n\t}\n\n\tcontent.ProgrammingLanguages = append(content.ProgrammingLanguages, programmingLanguage)\n\n\tvar writeErr error = xmlFile.writeContent(content)\n\tif writeErr != nil {\n\t\treturn writeErr\n\t}\n\n\treturn nil\n}\n\nfunc (xmlFile *XmlFile) deleteFile() error {\n\tvar removeErr error = os.Remove(xmlFile.path)\n\tif removeErr != nil {\n\t\treturn removeErr\n\t}\n\txmlFile.isDeleted = true\n\n\treturn nil\n}\n\nfunc (xmlFile *XmlFile) removeLanguage(programmingLanguage string) error {\n\tcontent, contentErr := xmlFile.getContent()\n\tif contentErr != nil {\n\t\treturn contentErr\n\t}\n\n\tvar sanitizedProgrammingLanguages []string = []string{}\n\tfor _, language := range content.ProgrammingLanguages {\n\t\tif strings.ToUpper(language) != strings.ToUpper(programmingLanguage) {\n\t\t\tsanitizedProgrammingLanguages = append(sanitizedProgrammingLanguages, language)\n\t\t}\n\t}\n\tcontent.ProgrammingLanguages = sanitizedProgrammingLanguages\n\n\tvar writeErr error = xmlFile.writeContent(content)\n\tif writeErr != nil {\n\t\treturn writeErr\n\t}\n\n\treturn nil\n}\n\nfunc (xmlFile *XmlFile) updateAge(age int8) error {\n\tcontent, contentErr := xmlFile.getContent()\n\tif contentErr != nil {\n\t\treturn contentErr\n\t}\n\n\tcontent.Age = age\n\txmlFile.writeContent(content)\n\n\treturn nil\n}\n\nfunc (xmlFile *XmlFile) updateBornDate(bornDate time.Time) error {\n\tcontent, contentErr := xmlFile.getContent()\n\tif contentErr != nil {\n\t\treturn contentErr\n\t}\n\n\tcontent.BornDate = bornDate\n\txmlFile.writeContent(content)\n\n\treturn nil\n}\n\nfunc (xmlFile *XmlFile) updateName(name string) error {\n\tcontent, contentErr := xmlFile.getContent()\n\tif contentErr != nil {\n\t\treturn contentErr\n\t}\n\n\tcontent.Name = name\n\txmlFile.writeContent(content)\n\n\treturn nil\n}\n\nfunc (xmlFile *XmlFile) writeContent(content XmlAuthor) error {\n\tstringifiedContent, marshalIndentErr := xml.MarshalIndent(content, \"\", \"\\t\")\n\tif marshalIndentErr != nil {\n\t\treturn marshalIndentErr\n\t}\n\n\tvar writeErr error = os.WriteFile(xmlFile.path, stringifiedContent, os.ModeAppend)\n\tif writeErr != nil {\n\t\treturn writeErr\n\t}\n\n\treturn nil\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\nfunc main() {\n\t/*\n\t\tJSON and XML files...\n\t*/\n\n\tfmt.Println(\"JSON and XML files...\")\n\n\tconst jsonFilePath string = \"author.json\"\n\tconst xmlFilePath string = \"author.xml\"\n\n\t// Delete files if exist\n\tif _, err := os.Stat(jsonFilePath); err != nil {\n\t\tif removeErr := os.Remove(jsonFilePath); removeErr == nil {\n\t\t\tlog.Fatal(removeErr)\n\t\t}\n\t}\n\n\tif _, err := os.Stat(xmlFilePath); err != nil {\n\t\tif removeErr := os.Remove(xmlFilePath); removeErr == nil {\n\t\t\tlog.Fatal(removeErr)\n\t\t}\n\t}\n\n\t// Create files and append content\n\tjsonFile, jsonCreateErr := os.Create(jsonFilePath)\n\tif jsonCreateErr != nil {\n\t\tlog.Fatal(jsonCreateErr)\n\t}\n\n\txmlFile, xmlCreateErr := os.Create(xmlFilePath)\n\tif xmlCreateErr != nil {\n\t\tlog.Fatal(xmlCreateErr)\n\t}\n\n\tauthorJsonData := JsonAuthor{\n\t\tAge:                  22,\n\t\tBornDate:             time.Date(2002, time.February, 20, 0, 0, 0, 0, time.UTC),\n\t\tName:                 \"Lucas\",\n\t\tProgrammingLanguages: []string{\"TypeScript\", \"Python\", \"Go\"},\n\t}\n\n\tvar authorXmlData XmlAuthor = XmlAuthor{\n\t\tAge:                  22,\n\t\tBornDate:             time.Date(2002, time.February, 20, 0, 0, 0, 0, time.UTC),\n\t\tName:                 \"Lucas\",\n\t\tProgrammingLanguages: []string{\"TypeScript\"},\n\t}\n\n\tjsonFileNewContent, jsonFileNewContentErr := json.MarshalIndent(authorJsonData, \"\", \"\\t\")\n\tif jsonFileNewContentErr != nil {\n\t\tlog.Fatal(jsonFileNewContentErr)\n\t}\n\n\txmlFileNewContent, xmlFileNewContentErr := xml.MarshalIndent(authorXmlData, \"\", \"\\t\")\n\tif xmlFileNewContentErr != nil {\n\t\tlog.Fatal(xmlFileNewContentErr)\n\t}\n\n\tjsonFile.Write(jsonFileNewContent)\n\txmlFile.Write(xmlFileNewContent)\n\n\tjsonFile.Close()\n\txmlFile.Close()\n\n\t// Print files content\n\tjsonFileContent, jsonFileContentErr := os.ReadFile(jsonFilePath)\n\tif jsonFileContentErr != nil {\n\t\tlog.Fatal(jsonFileContentErr)\n\t}\n\n\txmlFileContent, xmlFileContentErr := os.ReadFile(xmlFilePath)\n\tif xmlFileContentErr != nil {\n\t\tlog.Fatal(xmlFileContentErr)\n\t}\n\n\tfmt.Printf(\"\\n%s\\n\", string(jsonFileContent))\n\tfmt.Printf(\"\\n%s\\n\", string(xmlFileContent))\n\n\t// Delete files\n\tos.Remove(jsonFilePath)\n\tos.Remove(xmlFilePath)\n\n\tfmt.Println(\"\\n# ---------------------------------------------------------------------------------- #\\n\")\n\n\t/*\n\t\tAdditional files...\n\t*/\n\n\tfmt.Println(\"Additional files...\")\n\n\tvar jsonInitialContent JsonAuthor = JsonAuthor{\n\t\tAge:                  22,\n\t\tBornDate:             time.Date(2002, time.February, 20, 0, 0, 0, 0, time.UTC),\n\t\tName:                 \"Lucas\",\n\t\tProgrammingLanguages: []string{\"Go\"},\n\t}\n\n\tjsonFileObj, jsonFileErr := newJsonFile(\"additional-challenge.json\", jsonInitialContent)\n\tif jsonFileErr != nil {\n\t\tlog.Fatal(jsonFileErr)\n\t}\n\n\tvar shouldExit bool = false\n\treader := bufio.NewReader(os.Stdin)\n\n\tfor !shouldExit {\n\t\tfmt.Print(\"\\nSelect an operation ('Append language', 'Print', 'Remove language', 'Update age', 'Update born date', 'Update name', or 'Exit'): \")\n\t\toperation, readErr := reader.ReadString('\\n')\n\t\tif readErr != nil {\n\t\t\toperation = \"\"\n\t\t}\n\n\t\tvar operationFmt string = strings.ToUpper(strings.TrimSpace(operation))\n\n\tjsonActions:\n\t\tswitch operationFmt {\n\t\tcase \"APPEND LANGUAGE\":\n\t\t\tfmt.Print(\"\\nNew programming language: \")\n\t\t\tprogrammingLanguage, readErr := reader.ReadString('\\n')\n\t\t\tif readErr != nil {\n\t\t\t\tbreak jsonActions\n\t\t\t}\n\n\t\t\tprogrammingLanguage = strings.TrimSpace(programmingLanguage)\n\t\t\tjsonFileObj.appendLanguage(programmingLanguage)\n\n\t\tcase \"PRINT\":\n\t\t\tcontent, contentErr := jsonFileObj.getContent()\n\t\t\tif contentErr != nil {\n\t\t\t\tlog.Fatal(contentErr)\n\t\t\t}\n\n\t\t\tfmt.Printf(\"\\nAge: %d\", content.Age)\n\t\t\tfmt.Printf(\"\\nBorn date: %s\", content.BornDate)\n\t\t\tfmt.Printf(\"\\nName: %s\", content.Name)\n\t\t\tfmt.Printf(\"\\nProgramming languages: %s\\n\", content.ProgrammingLanguages)\n\n\t\tcase \"REMOVE LANGUAGE\":\n\t\t\tfmt.Print(\"\\nProgramming language: \")\n\t\t\tprogrammingLanguage, readErr := reader.ReadString('\\n')\n\t\t\tif readErr != nil {\n\t\t\t\tbreak jsonActions\n\t\t\t}\n\n\t\t\tprogrammingLanguage = strings.TrimSpace(programmingLanguage)\n\t\t\tjsonFileObj.removeLanguage(programmingLanguage)\n\n\t\tcase \"UPDATE AGE\":\n\t\t\tvar newAge int8\n\n\t\t\tfmt.Print(\"\\nNew age: \")\n\t\t\t_, scanErr := fmt.Scanf(\"%d\\n\", &newAge)\n\t\t\tif scanErr != nil {\n\t\t\t\tbreak jsonActions\n\t\t\t}\n\n\t\t\tjsonFileObj.updateAge(newAge)\n\n\t\tcase \"UPDATE BORN DATE\":\n\t\t\tfmt.Print(\"\\nNew born date (year-month-day): \")\n\t\t\tnewBornDate, readErr := reader.ReadString('\\n')\n\t\t\tif readErr != nil {\n\t\t\t\tbreak jsonActions\n\t\t\t}\n\n\t\t\tnewBornDate = strings.TrimSpace(newBornDate)\n\n\t\t\tvar dateInfo []string = strings.Split(newBornDate, \"-\")\n\t\t\tif len(dateInfo) != 3 {\n\t\t\t\tbreak jsonActions\n\t\t\t}\n\n\t\t\tyear, atoiErr := strconv.Atoi(dateInfo[0])\n\t\t\tif atoiErr != nil {\n\t\t\t\tbreak jsonActions\n\t\t\t}\n\n\t\t\tmonth, atoiErr := strconv.Atoi(dateInfo[1])\n\t\t\tif atoiErr != nil {\n\t\t\t\tbreak jsonActions\n\t\t\t}\n\n\t\t\tday, atoiErr := strconv.Atoi(dateInfo[2])\n\t\t\tif atoiErr != nil {\n\t\t\t\tbreak jsonActions\n\t\t\t}\n\n\t\t\tjsonFileObj.updateBornDate(time.Date(year, time.Month(month), day, 0, 0, 0, 0, time.UTC))\n\n\t\tcase \"UPDATE NAME\":\n\t\t\tfmt.Print(\"\\nNew name: \")\n\t\t\tnewName, readErr := reader.ReadString('\\n')\n\t\t\tif readErr != nil {\n\t\t\t\tbreak jsonActions\n\t\t\t}\n\n\t\t\tnewName = strings.TrimSpace(newName)\n\t\t\tjsonFileObj.updateName(newName)\n\n\t\tcase \"EXIT\":\n\t\t\tvar deleteFileErr error = jsonFileObj.deleteFile()\n\t\t\tif deleteFileErr != nil {\n\t\t\t\tlog.Fatal(deleteFileErr)\n\t\t\t}\n\n\t\t\tshouldExit = true\n\n\t\tdefault:\n\t\t\tfmt.Println(\"\\nInvalid operation! Try again...\")\n\t\t}\n\t}\n\n\tvar xmlInitialContent XmlAuthor = XmlAuthor{\n\t\tAge:                  22,\n\t\tBornDate:             time.Date(2002, time.February, 20, 0, 0, 0, 0, time.UTC),\n\t\tName:                 \"Lucas\",\n\t\tProgrammingLanguages: []string{\"Go (Golang)\"},\n\t}\n\n\txmlFileObj, xmlFileErr := newXmlFile(\"additional-challenge.xml\", xmlInitialContent)\n\tif xmlFileErr != nil {\n\t\tlog.Fatal(xmlFileErr)\n\t}\n\n\tshouldExit = false\n\n\tfor !shouldExit {\n\t\tfmt.Print(\"\\nSelect an operation ('Append language', 'Print', 'Remove language', 'Update age', 'Update born date', 'Update name', or 'Exit'): \")\n\t\toperation, readErr := reader.ReadString('\\n')\n\t\tif readErr != nil {\n\t\t\toperation = \"\"\n\t\t}\n\n\t\tvar operationFmt string = strings.ToUpper(strings.TrimSpace(operation))\n\n\txmlActions:\n\t\tswitch operationFmt {\n\t\tcase \"APPEND LANGUAGE\":\n\t\t\tfmt.Print(\"\\nNew programming language: \")\n\t\t\tprogrammingLanguage, readErr := reader.ReadString('\\n')\n\t\t\tif readErr != nil {\n\t\t\t\tbreak xmlActions\n\t\t\t}\n\n\t\t\tprogrammingLanguage = strings.TrimSpace(programmingLanguage)\n\t\t\txmlFileObj.appendLanguage(programmingLanguage)\n\n\t\tcase \"PRINT\":\n\t\t\tcontent, contentErr := xmlFileObj.getContent()\n\t\t\tif contentErr != nil {\n\t\t\t\tlog.Fatal(contentErr)\n\t\t\t}\n\n\t\t\tfmt.Printf(\"\\nAge: %d\", content.Age)\n\t\t\tfmt.Printf(\"\\nBorn date: %s\", content.BornDate)\n\t\t\tfmt.Printf(\"\\nName: %s\", content.Name)\n\t\t\tfmt.Printf(\"\\nProgramming languages: %s\\n\", content.ProgrammingLanguages)\n\n\t\tcase \"REMOVE LANGUAGE\":\n\t\t\tfmt.Print(\"\\nProgramming language: \")\n\t\t\tprogrammingLanguage, readErr := reader.ReadString('\\n')\n\t\t\tif readErr != nil {\n\t\t\t\tbreak xmlActions\n\t\t\t}\n\n\t\t\tprogrammingLanguage = strings.TrimSpace(programmingLanguage)\n\t\t\txmlFileObj.removeLanguage(programmingLanguage)\n\n\t\tcase \"UPDATE AGE\":\n\t\t\tvar newAge int8\n\n\t\t\tfmt.Print(\"\\nNew age: \")\n\t\t\t_, scanErr := fmt.Scanf(\"%d\\n\", &newAge)\n\t\t\tif scanErr != nil {\n\t\t\t\tbreak xmlActions\n\t\t\t}\n\n\t\t\txmlFileObj.updateAge(newAge)\n\n\t\tcase \"UPDATE BORN DATE\":\n\t\t\tfmt.Print(\"\\nNew born date (year-month-day): \")\n\t\t\tnewBornDate, readErr := reader.ReadString('\\n')\n\t\t\tif readErr != nil {\n\t\t\t\tbreak xmlActions\n\t\t\t}\n\n\t\t\tnewBornDate = strings.TrimSpace(newBornDate)\n\n\t\t\tvar dateInfo []string = strings.Split(newBornDate, \"-\")\n\t\t\tif len(dateInfo) != 3 {\n\t\t\t\tbreak xmlActions\n\t\t\t}\n\n\t\t\tyear, atoiErr := strconv.Atoi(dateInfo[0])\n\t\t\tif atoiErr != nil {\n\t\t\t\tbreak xmlActions\n\t\t\t}\n\n\t\t\tmonth, atoiErr := strconv.Atoi(dateInfo[1])\n\t\t\tif atoiErr != nil {\n\t\t\t\tbreak xmlActions\n\t\t\t}\n\n\t\t\tday, atoiErr := strconv.Atoi(dateInfo[2])\n\t\t\tif atoiErr != nil {\n\t\t\t\tbreak xmlActions\n\t\t\t}\n\n\t\t\txmlFileObj.updateBornDate(time.Date(year, time.Month(month), day, 0, 0, 0, 0, time.UTC))\n\n\t\tcase \"UPDATE NAME\":\n\t\t\tfmt.Print(\"\\nNew name: \")\n\t\t\tnewName, readErr := reader.ReadString('\\n')\n\t\t\tif readErr != nil {\n\t\t\t\tbreak xmlActions\n\t\t\t}\n\n\t\t\tnewName = strings.TrimSpace(newName)\n\t\t\txmlFileObj.updateName(newName)\n\n\t\tcase \"EXIT\":\n\t\t\tvar deleteFileErr error = xmlFileObj.deleteFile()\n\t\t\tif deleteFileErr != nil {\n\t\t\t\tlog.Fatal(deleteFileErr)\n\t\t\t}\n\n\t\t\tshouldExit = true\n\n\t\tdefault:\n\t\t\tfmt.Println(\"\\nInvalid operation! Try again...\")\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/go/kodenook.go",
    "content": "package main\n\nimport (\n\t\"encoding/json\"\n\t\"encoding/xml\"\n\t\"fmt\"\n\t\"os\"\n)\n\nfunc main() {\n\tu := Person{\"kodenook\", 27, \"27-07\", []string{\"go\", \"rust\"}}\n\tdata, _ := json.MarshalIndent(u, \"\", \"\\t\")\n\n\terr := os.WriteFile(\"person.json\", data, 0644)\n\tif err != nil {\n\t\tfmt.Println(\"Error al escribir el archivo JSON:\", err)\n\t\treturn\n\t}\n\n\tfmt.Println(string(data))\n\n\tdata2, _ := xml.MarshalIndent(u, \"\", \"\\t\")\n\n\terr = os.WriteFile(\"person.xml\", data2, 0644)\n\tif err != nil {\n\t\tfmt.Println(\"Error al escribir el archivo XML:\", err)\n\t\treturn\n\t}\n\n\tfmt.Println(string(data2))\n\tos.Remove(\"person.json\")\n\tos.Remove(\"person.xml\")\n}\n\ntype Person struct {\n\tName                 string\n\tAge                  uint\n\tBirthdate            string\n\tProgrammingLenguages []string\n}\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/go/qwik-zgheib.go",
    "content": "package main\n\nimport (\n\t\"encoding/json\"\n\t\"encoding/xml\"\n\t\"fmt\"\n\t\"os\"\n)\n\ntype Person struct {\n\tName                 string\n\tAge                  int\n\tBirthDate            string\n\tProgrammingLanguages []string\n}\n\n// Serializer interface\ntype Serializer interface {\n\tSerialize(data Person, filename string) error\n\tDeserialize(filename string) (Person, error)\n}\n\n// JSONSerializer struct implementing Serializer interface\ntype JSONSerializer struct{}\n\nfunc (js JSONSerializer) Serialize(data Person, filename string) error {\n\tfile, err := json.MarshalIndent(data, \"\", \"  \")\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn os.WriteFile(filename, file, 0644)\n}\n\nfunc (js JSONSerializer) Deserialize(filename string) (Person, error) {\n\tvar person Person\n\tfile, err := os.ReadFile(filename)\n\tif err != nil {\n\t\treturn person, err\n\t}\n\terr = json.Unmarshal(file, &person)\n\treturn person, err\n}\n\n// XMLSerializer struct implementing Serializer interface\ntype XMLSerializer struct{}\n\nfunc (xs XMLSerializer) Serialize(data Person, filename string) error {\n\tfile, err := xml.MarshalIndent(data, \"\", \"  \")\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn os.WriteFile(filename, file, 0644)\n}\n\nfunc (xs XMLSerializer) Deserialize(filename string) (Person, error) {\n\tvar person Person\n\tfile, err := os.ReadFile(filename)\n\tif err != nil {\n\t\treturn person, err\n\t}\n\terr = xml.Unmarshal(file, &person)\n\treturn person, err\n}\n\ntype SerializerFactory struct{}\n\nfunc (sf SerializerFactory) GetSerializer(format string) Serializer {\n\tswitch format {\n\tcase \"json\":\n\t\treturn JSONSerializer{}\n\tcase \"xml\":\n\t\treturn XMLSerializer{}\n\tdefault:\n\t\treturn nil\n\t}\n}\n\nfunc main() {\n\tperson := Person{\n\t\tName:                 \"Qwik zgheib\",\n\t\tAge:                  30,\n\t\tBirthDate:            \"2002-11-09\",\n\t\tProgrammingLanguages: []string{\"Go\", \"Java\", \"Python\"},\n\t}\n\n\tfactory := SerializerFactory{}\n\n\tjsonSerializer := factory.GetSerializer(\"json\")\n\txmlSerializer := factory.GetSerializer(\"xml\")\n\n\tjsonFile := \"qwik-zgheib.json\"\n\txmlFile := \"qwik-zgheib.xml\"\n\n\t// Serialize to JSON\n\terr := jsonSerializer.Serialize(person, jsonFile)\n\tif err != nil {\n\t\tfmt.Println(\"Err serializing to JSON:\", err)\n\t}\n\n\t// Serialize to XML\n\terr = xmlSerializer.Serialize(person, xmlFile)\n\tif err != nil {\n\t\tfmt.Println(\"Err serializing to XML:\", err)\n\t}\n\n\t// Deserialize from JSON\n\tjsonPerson, err := jsonSerializer.Deserialize(jsonFile)\n\tif err != nil {\n\t\tfmt.Println(\"Err deserializing JSON:\", err)\n\t} else {\n\t\tfmt.Println(\"JSON deserialized:\", jsonPerson)\n\t}\n\n\t// Deserialize from XML\n\txmlPerson, err := xmlSerializer.Deserialize(xmlFile)\n\tif err != nil {\n\t\tfmt.Println(\"Err deserializing XML:\", err)\n\t} else {\n\t\tfmt.Println(\"XML deserialized:\", xmlPerson)\n\t}\n\n\t// Delete the JSON file\n\terr = os.Remove(jsonFile)\n\tif err != nil {\n\t\tfmt.Println(\"Err deleting JSON file:\", err)\n\t}\n\n\t// Delete the XML file\n\terr = os.Remove(xmlFile)\n\tif err != nil {\n\t\tfmt.Println(\"Err deleting XML file:\", err)\n\t}\n}\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/go/raynerpv2022.go",
    "content": "package main\n\nimport (\n\t\"encoding/json\"\n\t\"encoding/xml\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n)\n\n// # * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n// #  *\n// #  * EJERCICIO:\n// #  * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n// #  * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n// #  * - Nombre\n// #  * - Edad\n// #  * - Fecha de nacimiento\n// #  * - Listado de lenguajes de programación\n// #  * Muestra el contenido de los archivos.\n// #  * Borrarlo despues\n\n// # XML\n\ntype Languages struct {\n\tItem []string `xml: \"item\"`\n}\n\ntype Programer struct {\n\tXMLName  xml.Name  `xml: \"Programer\"`\n\tName     string    `xml:\"name\"`\n\tAge      string    `xml:\"age\"`\n\tCumple   string    `xml:\"cumple\"`\n\tLanguage Languages `xml:\"language\"`\n}\n\nfunc ReadXML(fileName string) *Programer {\n\tfile, _ := os.Open(fileName)\n\tdefer file.Close()\n\treader, _ := io.ReadAll(file)\n\tvar programer *Programer\n\txml.Unmarshal(reader, &programer)\n\treturn programer\n\n}\n\nfunc WriteXML(fileName string, programer Programer) {\n\n\tfile, _ := os.Create(fileName)\n\tdefer file.Close()\n\toutput, e := xml.MarshalIndent(programer, \"\", \" \")\n\tif e != nil {\n\t\tfmt.Println(e)\n\t}\n\tfile.Write([]byte(xml.Header))\n\tfile.Write(output)\n\n}\n\n//JSON\n\ntype LanguagesJ struct {\n\tItem []string `json: \"item\"`\n}\n\ntype ProgramerJ struct {\n\tName     string    `json:\"name\"`\n\tAge      string    `json:\"age\"`\n\tCumple   string    `json:\"cumple\"`\n\tLanguage Languages `json:\"language\"`\n}\n\nfunc ReadJson(file string) *ProgramerJ {\n\tf, _ := os.Open(file)\n\treader, _ := io.ReadAll(f)\n\tdefer f.Close()\n\tvar programer *ProgramerJ\n\tjson.Unmarshal(reader, &programer)\n\treturn programer\n\n}\n\nfunc WriteJson(file string, programer *ProgramerJ) {\n\tf, _ := os.Create(file)\n\tdefer f.Close()\n\tsalida, _ := json.MarshalIndent(programer, \"\", \" \")\n\t_, err := f.Write(salida)\n\tif err != nil {\n\t\tfmt.Println((err))\n\t}\n}\n\nfunc main() {\n\tfileName := \"programer.xml\"\n\tfileNamej := \"programer.json\"\n\tprogramer := Programer{\n\t\tName:   \"juana\",\n\t\tAge:    \"23\",\n\t\tCumple: \"1.1.1900\",\n\t\tLanguage: Languages{\n\t\t\t[]string{\"Python\", \"GO\", \"HTML\"},\n\t\t},\n\t}\n\tprogramerj := ProgramerJ{\n\t\tName:   \"Petra\",\n\t\tAge:    \"23\",\n\t\tCumple: \"1.1.1900\",\n\t\tLanguage: Languages{\n\t\t\t[]string{\"Python\", \"PASCAL\", \"JAVA\"},\n\t\t},\n\t}\n\n\tWriteXML(fileName, programer)\n\tvar NewProgramer *Programer\n\tNewProgramer = ReadXML(fileName)\n\tfmt.Printf(\"XML NAME : %v, \\n Nombre : %v \\n Edad : %v\\n Cumle : %v\\n Language :  %v\\n\", NewProgramer.XMLName, NewProgramer.Name, NewProgramer.Age, NewProgramer.Cumple, NewProgramer.Language)\n\tWriteJson(fileNamej, &programerj)\n\tvar NewProgramerj *ProgramerJ\n\tNewProgramerj = ReadJson(fileNamej)\n\tfmt.Printf(\"JSON FILE  \\n Nombre : %v \\n Edad : %v\\n Cumple : %v\\n Language :  %v\\n\", NewProgramerj.Name, NewProgramerj.Age, NewProgramerj.Cumple, NewProgramerj.Language)\n\n}\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/go/thegera4.go",
    "content": "package main\n\nimport (\t\n\t\"encoding/json\"\n\t\"encoding/xml\"\n\t\"fmt\"\n\t\"os\"\n\t\"time\"\n)\n\ntype Datos struct {\n\tNombre string\n\tEdad int\n\tFechaNacimiento time.Time\n\tLenguajes []string\n}\n\nvar datosGerardo = Datos{\n\tNombre: \"Gerardo\",\n\tEdad: 36,\n\tFechaNacimiento: time.Date(1987, time.July, 3, 0, 0, 0, 0, time.UTC),\n\tLenguajes: []string{\"Go\", \"Python\", \"JavaScript\", \"Java\", \"TypeScript\", \"Kotlin\", \"Dart\"},\n}\n\nvar datosJuan = Datos{\n\tNombre: \"Juan\",\n\tEdad: 37,\n\tFechaNacimiento: time.Date(1986, time.July, 3, 0, 0, 0, 0, time.UTC),\n\tLenguajes: []string{\"Rust\", \"C\", \"C++\", \"C#\", \"Swift\", \"Objective-C\", \"Ruby\"},\n}\n\nfunc main() {\n\tif _, err := os.Stat(\"thegera4.xml\"); err == nil {\n\n\t\tfile, err := os.Open(\"thegera4.xml\")\n\t\tif err != nil {\n\t\t\tfmt.Println(\"Error al abrir el archivo:\", err)\n\t\t\treturn\n\t\t}\n\n\t\treadAndShowXML(file)\n\n\t\tfile.Close()\n\n\t\terr = os.Remove(\"thegera4.xml\")\n\t\tif err != nil {\n\t\t\tfmt.Println(\"Error al borrar el archivo:\", err)\n\t\t\treturn\n\t\t}\n\n\t\treturn\n\t}\n\n\tfile := createFile(\"thegera4.xml\")\n\n\terr := writeToXML(file, datosGerardo)\n\tif err != nil { \n\t\tfmt.Println(\"Error al escribir en el archivo:\", err)\n\t\treturn\n\t}\n\n\terr = writeToXML(file, datosJuan)\n\tif err != nil {\n\t\tfmt.Println(\"Error al escribir en el archivo:\", err)\n\t\treturn\n\t}\n\t\n\tfile.Close()\n\n\tfile, err = os.Open(\"thegera4.xml\")\n\tif err != nil {\n\t\tfmt.Println(\"Error al abrir el archivo:\", err)\n\t\treturn\n\t}\n\treadAndShowXML(file)\n\tfile.Close()\n\n\ttime.Sleep(2 * time.Second)\n\terr = os.Remove(\"thegera4.xml\")\n\tif err != nil {\n\t\tfmt.Println(\"Error al borrar el archivo:\", err)\n\t\treturn\n\t}\n\n\t// Dificultad extra\n\tif _, err := os.Stat(\"thegera4.json\"); err == nil {\n\n\t\tfile, err := os.Open(\"thegera4.json\")\n\t\tif err != nil {\n\t\t\tfmt.Println(\"Error al abrir el archivo:\", err)\n\t\t\treturn\n\t\t}\n\n\t\treadAndShowJSON(file)\n\n\t\tfile.Close()\n\n\t\terr = os.Remove(\"thegera4.json\")\n\t\tif err != nil {\n\t\t\tfmt.Println(\"Error al borrar el archivo:\", err)\n\t\t\treturn\n\t\t}\n\n\t\treturn\n\t}\n\n\tdatos := []Datos{datosGerardo, datosJuan}\n\t\n\tfile = createFile(\"thegera4.json\")\n\n\terr = writeToJSON(file, datos)\n\tif err != nil {\n\t\tfmt.Println(\"Error al escribir en el archivo:\", err)\n\t\treturn\n\t}\n\n\tfile.Close()\n\n\tfile, err = os.Open(\"thegera4.json\")\n\tif err != nil {\n\t\tfmt.Println(\"Error al abrir el archivo:\", err)\n\t\treturn\n\t}\n\n\treadAndShowJSON(file)\n\tfile.Close()\n\n\ttime.Sleep(2 * time.Second)\n\terr = os.Remove(\"thegera4.json\")\n\tif err != nil {\n\t\tfmt.Println(\"Error al borrar el archivo:\", err)\n\t\treturn\n\t}\n\n}\n\nfunc createFile(name string) *os.File {\n\tfile, err := os.Create(name)\n\tif err != nil {\n\t\tfmt.Println(\"Error al crear el archivo:\", err)\n\t\treturn nil\n\t}\n\treturn file\n}\n\nfunc writeToXML(file *os.File, data Datos) error {\n\txmlData, err := xml.MarshalIndent(data, \"\", \"    \")\n\tif err != nil {\n\t\tfmt.Println(\"Error al convertir a XML:\", err)\n\t\treturn err\n\t}\n\n\t_, err = file.Write(xmlData)\n\tif err != nil {\n\t\tfmt.Println(\"Error al escribir en el archivo:\", err)\n\t\treturn err\n\t}\n\n\t_, err = file.WriteString(\"\\n\")\n\tif err != nil {\n\t\tfmt.Println(\"Error al escribir en el archivo:\", err)\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc writeToJSON(file *os.File, data []Datos) error {\n\tjsonData, err := json.MarshalIndent(data, \"\", \"    \")\n\tif err != nil {\n\t\tfmt.Println(\"Error al convertir a JSON:\", err)\n\t\treturn err\n\t}\n\n\t_, err = file.Write(jsonData)\n\tif err != nil {\n\t\tfmt.Println(\"Error al escribir en el archivo:\", err)\n\t\treturn err\n\t}\n\n\t_, err = file.WriteString(\"\\n\")\n\tif err != nil {\n\t\tfmt.Println(\"Error al escribir en el archivo:\", err)\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc readAndShowXML(file *os.File) {\n\tfileInfo, err := file.Stat()\n\tif err != nil {\n\t\tfmt.Println(\"Error al obtener información del archivo:\", err)\n\t\treturn\n\t}\n\n\tfileData := make([]byte, fileInfo.Size())\n\t_, err = file.Read(fileData)\n\tif err != nil {\n\t\tfmt.Println(\"Error al leer el archivo:\", err)\n\t\treturn\n\t}\n\n\tfmt.Println(string(fileData))\n\tfile.Close()\n}\n\nfunc readAndShowJSON(file *os.File) {\n\tfileInfo, err := file.Stat()\n\tif err != nil {\n\t\tfmt.Println(\"Error al obtener información del archivo:\", err)\n\t\treturn\n\t}\n\n\tfileData := make([]byte, fileInfo.Size())\n\t_, err = file.Read(fileData)\n\tif err != nil {\n\t\tfmt.Println(\"Error al leer el archivo:\", err)\n\t\treturn\n\t}\n\n\tvar datos []Datos\n\terr = json.Unmarshal(fileData, &datos)\n\tif err != nil {\n\t\tfmt.Println(\"Error al convertir de JSON:\", err)\n\t\treturn\n\t}\n\n\tfor _, dato := range datos {\n\t\tfmt.Println(\"Nombre:\", dato.Nombre)\n\t\tfmt.Println(\"Edad:\", dato.Edad)\n\t\tfmt.Println(\"Fecha de nacimiento:\", dato.FechaNacimiento)\n\t\tfmt.Println(\"Lenguajes:\")\n\t\tfor _, lenguaje := range dato.Lenguajes {\n\t\t\tfmt.Println(\"    -\", lenguaje)\n\t\t}\n\t}\n\tfile.Close()\n}"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/java/AbelADE.java",
    "content": "import com.github.cliftonlabs.json_simple.JsonArray;\nimport com.github.cliftonlabs.json_simple.JsonException;\nimport com.github.cliftonlabs.json_simple.JsonObject;\nimport com.github.cliftonlabs.json_simple.Jsoner;\nimport org.w3c.dom.Document;\nimport org.w3c.dom.Element;\nimport org.w3c.dom.NodeList;\n\nimport javax.xml.parsers.DocumentBuilder;\nimport javax.xml.parsers.DocumentBuilderFactory;\nimport javax.xml.parsers.ParserConfigurationException;\nimport javax.xml.transform.*;\nimport javax.xml.transform.dom.DOMSource;\nimport javax.xml.transform.stream.StreamResult;\nimport java.io.*;\nimport java.text.DateFormat;\nimport java.text.ParseException;\nimport java.text.SimpleDateFormat;\nimport java.util.*;\n\n/*\n    <dependencies>\n        <dependency>\n            <groupId>com.github.cliftonlabs</groupId>\n            <artifactId>json-simple</artifactId>\n            <version>3.1.0</version>\n        </dependency>\n    </dependencies>\n*/\n\npublic class Main {\n    public static void main(String[] args) {\n        //Datos a introducir en los documentos\n        String name = \"Abel\";\n        int age = 20;\n        Date birthday = new GregorianCalendar(1994, Calendar.JUNE, 16).getTime();\n        String[] lenguages = new String[]{\"Java\", \"PHP\", \"JavaScript\"};\n\n        //Para formatear la fecha\n        DateFormat formatter = new SimpleDateFormat(\"dd-MM-yyyy\");\n\n        /*XML*/\n        // Creamos una factoría para crear el documento\n        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();\n        DocumentBuilder builder;\n        Document doc = null;\n        try {\n            builder = factory.newDocumentBuilder();\n            doc = builder.newDocument();\n            //Creamos el elemento root y lo añadimos al documento xml\n            Element rootElement = doc.createElement(\"programador\");\n            doc.appendChild(rootElement);\n\n            //Añadimos en nombre\n            Element nameElement = doc.createElement(\"name\");\n            nameElement.setTextContent(name);\n            rootElement.appendChild(nameElement);\n\n            //Añadimos la edad\n            Element ageElement = doc.createElement(\"age\");\n            ageElement.setTextContent(Integer.toString(age));\n            rootElement.appendChild(ageElement);\n\n            //Añadimos la fecha de cumpleaños\n            Element birthdayElement = doc.createElement(\"birthday\");\n            birthdayElement.setTextContent(formatter.format(birthday));\n            rootElement.appendChild(birthdayElement);\n\n            //Añadimos un elemento que englobará los lenguajes\n            Element languagesElement = doc.createElement(\"languages\");\n            for (String language : lenguages) {\n                Element languageElement = doc.createElement(\"language\");\n                languageElement.setTextContent(language);\n                languagesElement.appendChild(languageElement);\n            }\n            rootElement.appendChild(languagesElement);\n\n            //Asocio el source con el Document\n            Source source = new DOMSource(doc);\n\n            //Creo el Result, indicando que fichero se va a crear\n            Result result = new StreamResult(new File(\"abel.xml\"));\n\n            //Creo un transformer, se crea el fichero XML\n            Transformer transformer = TransformerFactory.newInstance().newTransformer();\n            transformer.transform(source, result);\n\n            System.out.println(\"XML creado satisfactoriamente\");\n\n        } catch (ParserConfigurationException | TransformerException e) {\n            System.out.println(\"Error: \" + e.getMessage());\n        }\n\n        /*JSON*/\n        JsonObject json = new JsonObject();\n\n        json.put(\"name\", name);\n        json.put(\"age\", String.valueOf(age));\n        json.put(\"birthday\", formatter.format(birthday));\n\n        JsonArray langs = new JsonArray();\n        for (String language : lenguages) {\n            langs.add(language);\n        }\n        json.put(\"languages\", langs);\n\n        File jsonFile = new File(\"abel.json\");\n        try {\n            if (!jsonFile.exists()) {\n                jsonFile.createNewFile();\n            }\n\n            FileWriter fileWriter = new FileWriter(jsonFile);\n            fileWriter.write(json.toJson());\n            fileWriter.close();\n\n            System.out.println(\"JSON creado satisfactoriamente\");\n        } catch (IOException e) {\n            System.out.println(\"Error: \" + e.getMessage());\n        }\n\n        /*DIFICULTAD EXTRA -- CREAR CLASES A PARTIR DE DOCUMENTOS*/\n\n        /*Crear clase a partir de XML*/\n        String nameXML = null;\n        int ageXML = 0;\n        Date birthdayXML = null;\n        String[] lenguagesXML = null;\n\n        //Recupero datos del archivo\n        if (doc != null) {\n            NodeList programador = doc.getDocumentElement().getChildNodes();\n            for (int i = 0; i < programador.getLength(); i++) {\n                Element element = (Element) programador.item(i);\n                switch (element.getTagName()) {\n                    case \"name\":\n                        nameXML = element.getTextContent();\n                        break;\n                    case \"age\":\n                        ageXML = Integer.parseInt(element.getTextContent());\n                        break;\n                    case \"birthday\":\n                        try {\n                            birthdayXML = formatter.parse(element.getTextContent());\n                        } catch (ParseException e) {\n                            System.out.println(\"Error: \" + e.getMessage());\n                        }\n                        break;\n                    case \"languages\":\n                        NodeList languages = element.getChildNodes();\n                        lenguagesXML = new String[languages.getLength()];\n                        for (int j = 0; j < languages.getLength(); j++) {\n                            Element language = (Element) languages.item(j);\n                            lenguagesXML[j] = language.getTextContent();\n                        }\n                        break;\n                }\n            }\n        }\n\n        //Creo el objeto programador\n        Programmer programmer = new Programmer(nameXML, ageXML, birthdayXML, lenguagesXML);\n\n        //Muestro sus datos por consola\n        System.out.println(programmer);\n        System.out.println(\"Lenguajes de programación: \");\n        for (String language : lenguagesXML) {\n            System.out.println(language);\n        }\n\n        //Elimino el documento\n        File xmlFile = new File(\"abel.xml\");\n        xmlFile.delete();\n\n        /*Crear clase a partir de JSON*/\n        String nameJSON = null;\n        int ageJSON = 0;\n        Date birthdayJSON = null;\n        String[] lenguagesJSON = null;\n\n        try {\n            //Recupero datos del archivo\n            FileReader fileReader = new FileReader(\"abel.json\");\n            HashMap<String, Object> map = (HashMap<String, Object>) Jsoner.deserialize(fileReader);\n            nameJSON = (String) map.get(\"name\");\n            ageJSON = Integer.parseInt((String) map.get(\"age\"));\n            birthdayJSON = formatter.parse((String) map.get(\"birthday\"));\n            String array = map.get(\"languages\").toString();\n            array = array.replace('[', ' ').replace(']', ' ').trim();\n            lenguagesJSON = array.split(\", \");\n\n            //Creo el objeto programador\n            Programmer programmer1 = new Programmer(nameJSON, ageJSON, birthdayJSON, lenguagesJSON);\n\n            //Muestro sus datos por consola\n            System.out.println(programmer1);\n            System.out.println(\"Lenguajes de programación: \");\n            for (String language : lenguagesJSON) {\n                System.out.println(language);\n            }\n\n            //Elimino el documento\n            jsonFile.delete();\n\n        } catch (FileNotFoundException | ParseException | JsonException e) {\n            System.out.println(\"Error: \" + e.getMessage());\n        }\n    }\n}\n\nclass Programmer {\n    String name;\n    int age;\n    Date birthday;\n    String[] lenguages;\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public int getAge() {\n        return age;\n    }\n\n    public void setAge(int age) {\n        this.age = age;\n    }\n\n    public Date getBirthday() {\n        return birthday;\n    }\n\n    public void setBirthday(Date birthday) {\n        this.birthday = birthday;\n    }\n\n    public String[] getLenguages() {\n        return lenguages;\n    }\n\n    public void setLenguages(String[] lenguages) {\n        this.lenguages = lenguages;\n    }\n\n    public Programmer(String name, int age, Date birthday, String[] lenguages) {\n        this.name = name;\n        this.age = age;\n        this.birthday = birthday;\n        this.lenguages = lenguages;\n    }\n\n    @Override\n    public String toString() {\n        return \"Soy \" + name + \", con edad: \" + age + \".\";\n    }\n}\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/java/AmadorQuispe.java",
    "content": "package com.amsoft;\n\nimport java.io.IOException;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.time.LocalDate;\nimport java.util.Set;\n\nimport com.amsoft.jsonandxml.LocalDateTypeAdapter;\nimport com.fasterxml.jackson.core.type.TypeReference;\nimport com.fasterxml.jackson.databind.SerializationFeature;\nimport com.fasterxml.jackson.dataformat.xml.XmlMapper;\nimport com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;\nimport com.google.gson.Gson;\nimport com.google.gson.GsonBuilder;\nimport com.google.gson.reflect.TypeToken;\n\n/*\n *    --- dependencies----\n *     <dependency>\n            <groupId>com.fasterxml.jackson.dataformat</groupId>\n            <artifactId>jackson-dataformat-xml</artifactId>\n            <version>2.11.1</version>\n        </dependency>\n        <dependency>\n            <groupId>com.fasterxml.jackson.datatype</groupId>\n            <artifactId>jackson-datatype-jsr310</artifactId>\n            <version>2.14.1</version>\n        </dependency>\n        <dependency>\n            <groupId>com.google.code.gson</groupId>\n            <artifactId>gson</artifactId>\n            <version>2.10.1</version>\n        </dependency>\n */\n\npublic class Main {\n    public static void main(String[] args) throws IOException {\n        // Creación de objetos.\n        Programmer programmer = new Programmer();\n        programmer.setName(\"Amador Quispe Huaycho\");\n        programmer.setAge(31);\n        programmer.setBirthDate(LocalDate.of(1992, 7, 13));\n        programmer.setLanguages(Set.of(\"Go\", \"Java\"));\n\n        // JSON\n        Path pathJson = Path.of(\"AmadorQuispe.json\");\n        if (!Files.exists(pathJson)) {\n            Files.createFile(pathJson);\n        }\n        JSONManage<Programmer> jsonManage = new JSONManage<>(pathJson);\n        jsonManage.serialize(programmer);\n        Programmer programmerFromJson = jsonManage.deserialize(TypeToken.get(Programmer.class));\n        System.out.println(programmerFromJson);\n        Files.delete(pathJson);\n\n        // XML\n        Path pathXml = Path.of(\"AmadorQuispe.xml\");\n        if (!Files.exists(pathXml)) {\n            Files.createFile(pathXml);\n        }\n        XMLManager<Programmer> xmlManager = new XMLManager<>(pathXml);\n        TypeReference<Programmer> typeReference = new TypeReference<Programmer>() {\n        };\n        xmlManager.serialize(programmer);\n        Programmer programmerFromXml = xmlManager.deserialize(typeReference);\n        System.out.println(programmerFromXml);\n        Files.delete(pathXml);\n    }\n}\n\nclass Programmer {\n    private String name;\n    private Integer age;\n    private LocalDate birthDate;\n    private Set<String> languages;\n\n    public Programmer() {\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public Integer getAge() {\n        return age;\n    }\n\n    public void setAge(Integer age) {\n        this.age = age;\n    }\n\n    public LocalDate getBirthDate() {\n        return birthDate;\n    }\n\n    public void setBirthDate(LocalDate birthDate) {\n        this.birthDate = birthDate;\n    }\n\n    public Set<String> getLanguages() {\n        return languages;\n    }\n\n    public void setLanguages(Set<String> languages) {\n        this.languages = languages;\n    }\n\n    @Override\n    public String toString() {\n        return \"Programmer : [name=\" + name + \", age=\" + age + \", birthDate=\" + birthDate + \", languages=\" + languages\n                + \"]\";\n    }\n\n}\n\nclass XMLManager<T> {\n    private XmlMapper xmlMapper;\n    private Path path;\n\n    public XMLManager(Path path) {\n        this.path = path;\n        this.xmlMapper = XmlMapper.builder()\n                .enable(SerializationFeature.INDENT_OUTPUT)\n                .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)\n                .build();\n        xmlMapper.registerModule(new JavaTimeModule());\n    }\n\n    public void serialize(T object) {\n        try {\n            this.xmlMapper.writeValue(this.path.toFile(), object);\n        } catch (Exception e) {\n            e.printStackTrace(System.out);\n        }\n    }\n\n    public T deserialize(TypeReference<T> typeReference) {\n        try {\n            T objectDeserialize = this.xmlMapper.readValue(this.path.toFile(), typeReference);\n            return objectDeserialize;\n        } catch (Exception e) {\n            e.printStackTrace(System.out);\n        }\n        return null;\n    }\n}\n\nclass JSONManage<T> {\n    private Path path;\n    private Gson gson;\n\n    public JSONManage(Path path) {\n        this.path = path;\n        this.gson = new GsonBuilder()\n                .registerTypeAdapter(LocalDate.class, new LocalDateTypeAdapter())\n                .create();\n    }\n\n    public void serialize(T object) {\n\n        try {\n            String jsonString = gson.toJson(object);\n            Files.writeString(path, jsonString);\n        } catch (IOException e) {\n            e.printStackTrace(System.out);\n        }\n    }\n\n    public T deserialize(TypeToken<T> typeToken) {\n        try {\n            byte[] data = Files.readAllBytes(path);\n            T object = gson.fromJson(new String(data), typeToken.getType());\n            return object;\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n        return null;\n    }\n\n}"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/java/AnaLauDB.java",
    "content": "import java.io.*;\nimport java.nio.file.*;\nimport java.util.*;\nimport java.util.regex.*;\nimport javax.xml.parsers.*;\nimport javax.xml.transform.*;\nimport javax.xml.transform.dom.*;\nimport javax.xml.transform.stream.*;\nimport org.w3c.dom.*;\n\npublic class AnaLauDB {\n\n    // Nombres de archivo\n    private static final String ARCHIVO_XML = \"AnaLauDB_data.xml\";\n    private static final String ARCHIVO_JSON = \"AnaLauDB_data.json\";\n\n    public static void main(String[] args) {\n        try {\n\n            Persona p = new Persona(\n                    \"Ana Laura Doroteo Barrientos\",\n                    23,\n                    \"09-05-2002\",\n                    Arrays.asList(\"Java\", \"Python\", \"JavaScript\", \"C\", \"CSS\"));\n\n            // 1) Crear archivos\n            crearXML(p, ARCHIVO_XML);\n            crearJSON(p, ARCHIVO_JSON);\n\n            // 2) Mostrar contenidos crudos\n            System.out.println(\"=== Contenido XML creado ===\");\n            imprimirArchivo(ARCHIVO_XML);\n            System.out.println(\"\\n=== Contenido JSON creado ===\");\n            imprimirArchivo(ARCHIVO_JSON);\n\n            // 3) Leer y transformar en la misma clase Persona\n            System.out.println(\"\\n=== Convirtiendo XML a Persona ===\");\n            Persona desdeXml = leerXML(ARCHIVO_XML);\n            System.out.println(desdeXml);\n\n            System.out.println(\"\\n=== Convirtiendo JSON a Persona ===\");\n            Persona desdeJson = leerJSON(ARCHIVO_JSON);\n            System.out.println(desdeJson);\n\n            // 4) Borrar archivos\n            borrarArchivo(ARCHIVO_XML);\n            borrarArchivo(ARCHIVO_JSON);\n            System.out.println(\"\\nArchivos borrados. Fin de la ejecución.\");\n\n        } catch (Exception e) {\n            // Capturamos todo de forma segura para que no se caiga el programa\n            System.out.println(\"Ocurrió un error: \" + e.getClass().getSimpleName() + \" - \" + e.getMessage());\n            e.printStackTrace();\n        }\n    }\n\n    // ==========================\n    // Métodos para crear archivos\n    // ==========================\n    private static void crearXML(Persona p, String ruta) throws Exception {\n        // Build DOM\n        DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();\n        DocumentBuilder docBuilder = docFactory.newDocumentBuilder();\n\n        // Documento\n        Document doc = docBuilder.newDocument();\n        Element rootElement = doc.createElement(\"persona\");\n        doc.appendChild(rootElement);\n\n        // Nombre\n        Element nombre = doc.createElement(\"nombre\");\n        nombre.appendChild(doc.createTextNode(p.nombre));\n        rootElement.appendChild(nombre);\n\n        // Edad\n        Element edad = doc.createElement(\"edad\");\n        edad.appendChild(doc.createTextNode(String.valueOf(p.edad)));\n        rootElement.appendChild(edad);\n\n        // Fecha de nacimiento\n        Element dob = doc.createElement(\"fechaNacimiento\");\n        dob.appendChild(doc.createTextNode(p.fechaNacimiento));\n        rootElement.appendChild(dob);\n\n        // Lenguajes\n        Element lenguajes = doc.createElement(\"lenguajes\");\n        for (String lang : p.lenguajes) {\n            Element langElem = doc.createElement(\"lenguaje\");\n            langElem.appendChild(doc.createTextNode(lang));\n            lenguajes.appendChild(langElem);\n        }\n        rootElement.appendChild(lenguajes);\n\n        // Escribir a archivo\n        TransformerFactory transformerFactory = TransformerFactory.newInstance();\n        Transformer transformer = transformerFactory.newTransformer();\n        // Opcional: formato legible\n        transformer.setOutputProperty(OutputKeys.INDENT, \"yes\");\n        transformer.setOutputProperty(\"{http://xml.apache.org/xslt}indent-amount\", \"2\");\n\n        DOMSource source = new DOMSource(doc);\n        StreamResult result = new StreamResult(new File(ruta));\n        transformer.transform(source, result);\n    }\n\n    private static void crearJSON(Persona p, String ruta) throws IOException {\n        // Generamos JSON manualmente (formato controlado)\n        StringBuilder sb = new StringBuilder();\n        sb.append(\"{\\n\");\n        sb.append(\"  \\\"nombre\\\": \").append(escapeJson(p.nombre)).append(\",\\n\");\n        sb.append(\"  \\\"edad\\\": \").append(p.edad).append(\",\\n\");\n        sb.append(\"  \\\"fechaNacimiento\\\": \").append(escapeJson(p.fechaNacimiento)).append(\",\\n\");\n        sb.append(\"  \\\"lenguajes\\\": [\\n\");\n        for (int i = 0; i < p.lenguajes.size(); i++) {\n            sb.append(\"    \").append(escapeJson(p.lenguajes.get(i)));\n            if (i < p.lenguajes.size() - 1)\n                sb.append(\",\");\n            sb.append(\"\\n\");\n        }\n        sb.append(\"  ]\\n\");\n        sb.append(\"}\\n\");\n\n        Files.write(Paths.get(ruta), sb.toString().getBytes());\n    }\n\n    // Simple helper to wrap strings as JSON string with escaping of\n    // quotes/backslashes\n    private static String escapeJson(String s) {\n        String escaped = s.replace(\"\\\\\", \"\\\\\\\\\").replace(\"\\\"\", \"\\\\\\\"\");\n        return \"\\\"\" + escaped + \"\\\"\";\n    }\n\n    // ==========================\n    // Mostrar archivo por consola\n    // ==========================\n    private static void imprimirArchivo(String ruta) {\n        try {\n            List<String> lines = Files.readAllLines(Paths.get(ruta));\n            for (String l : lines)\n                System.out.println(l);\n        } catch (IOException e) {\n            System.out.println(\"No se pudo leer \" + ruta + \": \" + e.getMessage());\n        }\n    }\n\n    // ==========================\n    // Parseo XML -> Persona\n    // ==========================\n    private static Persona leerXML(String ruta) {\n        try {\n            File fXmlFile = new File(ruta);\n            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();\n            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();\n            Document doc = dBuilder.parse(fXmlFile);\n            doc.getDocumentElement().normalize();\n\n            String nombre = getTagValue(\"nombre\", doc.getDocumentElement());\n            int edad = Integer.parseInt(getTagValue(\"edad\", doc.getDocumentElement()));\n            String fecha = getTagValue(\"fechaNacimiento\", doc.getDocumentElement());\n\n            List<String> langs = new ArrayList<>();\n            NodeList nl = doc.getElementsByTagName(\"lenguaje\");\n            for (int i = 0; i < nl.getLength(); i++) {\n                Node node = nl.item(i);\n                if (node.getNodeType() == Node.ELEMENT_NODE) {\n                    langs.add(node.getTextContent());\n                }\n            }\n            return new Persona(nombre, edad, fecha, langs);\n        } catch (Exception e) {\n            System.out.println(\"Error leyendo XML: \" + e.getMessage());\n            return null;\n        }\n    }\n\n    private static String getTagValue(String tag, Element element) {\n        NodeList nodeList = element.getElementsByTagName(tag);\n        if (nodeList != null && nodeList.getLength() > 0) {\n            Node node = nodeList.item(0);\n            return node.getTextContent();\n        }\n        return \"\";\n    }\n\n    // ==========================\n    // Parseo JSON -> Persona (parsing simple y controlado)\n    // ==========================\n    private static Persona leerJSON(String ruta) {\n        try {\n            String content = new String(Files.readAllBytes(Paths.get(ruta)));\n\n            // Extraer nombre\n            String nombre = extractJsonString(content, \"\\\"nombre\\\"\\\\s*:\\\\s*\\\"([^\\\"]*)\\\"\");\n            // Extraer edad (número)\n            String edadStr = extractJsonString(content, \"\\\"edad\\\"\\\\s*:\\\\s*(\\\\d+)\");\n            int edad = edadStr.isEmpty() ? 0 : Integer.parseInt(edadStr);\n            // Extraer fecha\n            String fecha = extractJsonString(content, \"\\\"fechaNacimiento\\\"\\\\s*:\\\\s*\\\"([^\\\"]*)\\\"\");\n            // Extraer lenguajes (lista)\n            List<String> langs = new ArrayList<>();\n            // Buscamos el array completo entre \"lenguajes\": [ ... ]\n            Pattern p = Pattern.compile(\"\\\"lenguajes\\\"\\\\s*:\\\\s*\\\\[(.*?)\\\\]\", Pattern.DOTALL);\n            Matcher m = p.matcher(content);\n            if (m.find()) {\n                String inside = m.group(1); // contenido entre corchetes\n                // Buscar strings entre comillas dentro\n                Pattern strPat = Pattern.compile(\"\\\"([^\\\"]*)\\\"\");\n                Matcher mm = strPat.matcher(inside);\n                while (mm.find()) {\n                    langs.add(mm.group(1));\n                }\n            }\n\n            return new Persona(nombre, edad, fecha, langs);\n        } catch (IOException e) {\n            System.out.println(\"Error leyendo JSON: \" + e.getMessage());\n            return null;\n        }\n    }\n\n    // Helper regex extractor: devuelve primer grupo si encuentra, sino \"\"\n    private static String extractJsonString(String text, String regex) {\n        Pattern p = Pattern.compile(regex);\n        Matcher m = p.matcher(text);\n        if (m.find()) {\n            return m.group(1);\n        }\n        return \"\";\n    }\n\n    // ==========================\n    // Borrar archivo\n    // ==========================\n    private static void borrarArchivo(String ruta) {\n        try {\n            Files.deleteIfExists(Paths.get(ruta));\n            System.out.println(\"Archivo borrado: \" + ruta);\n        } catch (IOException e) {\n            System.out.println(\"No se pudo borrar \" + ruta + \": \" + e.getMessage());\n        }\n    }\n\n    // ==========================\n    // Clase Persona (custom)\n    // ==========================\n    public static class Persona {\n        public String nombre;\n        public int edad;\n        public String fechaNacimiento;\n        public List<String> lenguajes;\n\n        public Persona(String nombre, int edad, String fechaNacimiento, List<String> lenguajes) {\n            this.nombre = nombre;\n            this.edad = edad;\n            this.fechaNacimiento = fechaNacimiento;\n            this.lenguajes = new ArrayList<>(lenguajes);\n        }\n\n        @Override\n        public String toString() {\n            return \"Persona{\" +\n                    \"nombre='\" + nombre + '\\'' +\n                    \", edad=\" + edad +\n                    \", fechaNacimiento='\" + fechaNacimiento + '\\'' +\n                    \", lenguajes=\" + lenguajes +\n                    '}';\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/java/FranDev200.java",
    "content": "import javax.xml.parsers.DocumentBuilder;\nimport javax.xml.parsers.DocumentBuilderFactory;\nimport javax.xml.parsers.ParserConfigurationException;\nimport javax.xml.transform.*;\nimport javax.xml.transform.dom.DOMSource;\nimport javax.xml.transform.stream.StreamResult;\n\nimport com.google.gson.*;\nimport org.w3c.dom.*;\nimport org.xml.sax.SAXException;\n\nimport java.io.File;\nimport java.io.FileReader;\nimport java.io.FileWriter;\nimport java.io.IOException;\nimport java.util.ArrayList;\n\npublic class FranDev200 {\n\n    // PARA EL APARTADO DE JSON, USO EL .jar DE GSON\n\n    static int contador = 0;\n\n    static void main(String[] args) {\n\n        /*\n         * EJERCICIO:\n         * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n         * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n         * - Nombre\n         * - Edad\n         * - Fecha de nacimiento\n         * - Listado de lenguajes de programación\n         * Muestra el contenido de los archivos.\n         * Borra los archivos.\n\n         */\n\n        if (crearXML()) return;\n\n        if (leerXML()) return;\n\n        File fileJson = crearJson();\n        if (fileJson == null) return;\n\n        leerJson(fileJson);\n\n        /*\n\n         * DIFICULTAD EXTRA (opcional):\n         * Utilizando la lógica de creación de los archivos anteriores, crea un\n         * programa capaz de leer y transformar en una misma clase custom de tu\n         * lenguaje los datos almacenados en el XML y el JSON.\n         * Borra los archivos.\n\n         */\n\n        System.out.println(\"\\n\\n===============\");\n        System.out.println(\"EJERCICIO EXTRA\");\n        System.out.println(\"===============\\n\");\n\n        crearXML();\n\n        ArrayList<Alumno> listaAlumnos = new ArrayList<>();\n\n        leerXML(listaAlumnos);\n\n        System.out.println(\"INFORMACION DE LOS ALUMNOS DEL INSTITUTO\");\n        System.out.println(\"[Información obtenida a partir de un XML]\");\n        System.out.println(\"========================================\");\n        System.out.println(\"Numero de alumnos: \" +  listaAlumnos.size());\n        System.out.println(\"- - - - - - - - - - - -\");\n        for(Alumno a : listaAlumnos){\n            a.infoAlumno();\n        }\n\n        listaAlumnos.clear();\n\n        fileJson = crearJson();\n        if (fileJson == null) return;\n\n        leerJson(fileJson, listaAlumnos);\n\n        System.out.println(\"INFORMACION DE LOS ALUMNOS DEL INSTITUTO\");\n        System.out.println(\"[Información obtenida a partir de un Json]\");\n        System.out.println(\"========================================\");\n        System.out.println(\"Numero de alumnos: \" +  listaAlumnos.size());\n        System.out.println(\"- - - - - - - - - - - -\");\n        for(Alumno a : listaAlumnos){\n            a.infoAlumno();\n        }\n\n    }\n\n    static class Alumno{\n        private int id;\n        private String nombre;\n        private int edad;\n        private String fechaNacimiento;\n        private ArrayList<String> lenguajes = new ArrayList<>();\n\n        Alumno(){\n            contador++;\n            this.id = contador;\n        }\n\n        public String getNombre() {\n            return nombre;\n        }\n\n        public void setNombre(String nombre) {\n            this.nombre = nombre;\n        }\n\n        public int getEdad() {\n            return edad;\n        }\n\n        public void setEdad(int edad) {\n            this.edad = edad;\n        }\n\n        public String getFechaNacimiento() {\n            return fechaNacimiento;\n        }\n\n        public void setFechaNacimiento(String fechaNacimiento) {\n            this.fechaNacimiento = fechaNacimiento;\n        }\n\n        public ArrayList<String> getLenguajes() {\n            return lenguajes;\n        }\n\n        public void setLenguajes(ArrayList<String> lenguajes) {\n            this.lenguajes = lenguajes;\n        }\n\n        public void infoAlumno() {\n\n            System.out.println(\"============\");\n            System.out.println(\" - Alumno \" + id);\n            System.out.println(\"------------\");\n            System.out.println(\"   Nombre: \" + getNombre());\n            System.out.println(\"   Edad: \" + getEdad());\n            System.out.println(\"   FechaNacimiento: \" + getFechaNacimiento());\n            System.out.println(\"   Lenguajes favoritos:\");\n            for (String l: getLenguajes()){\n                System.out.println(\"\\t - \" + l);\n            }\n\n        }\n    }\n\n    // EJERCICIO EXTRA\n    private static boolean leerXML(ArrayList<Alumno> alumnosArrayList) {\n        // LEER EL DOCUMENTO XML\n\n        Alumno a = null;\n\n        File file = new  File(\"Alumnos.xml\");\n\n        try {\n\n            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();\n            DocumentBuilder db = dbf.newDocumentBuilder();\n            Document doc = db.parse(file);\n\n            doc.getDocumentElement().normalize();\n\n            NodeList alumnos = doc.getElementsByTagName(\"Alumno\");\n\n            for(int i = 0; i < alumnos.getLength(); i++){\n\n                a = new Alumno();\n\n                Element alumno = (Element) alumnos.item(i);\n\n                String nombre = alumno.getElementsByTagName(\"Nombre\").item(0).getTextContent();\n                int idAlumno = Integer.parseInt(alumno.getAttribute(\"ID\"));\n                int edad  = Integer.parseInt(alumno.getElementsByTagName(\"Edad\").item(0).getTextContent());\n                String fecha = alumno.getElementsByTagName(\"FechaNacimiento\").item(0).getTextContent();\n                ArrayList<String> leng = new ArrayList<>();\n\n                NodeList lenguajes = alumno.getElementsByTagName(\"Lenguaje\");\n\n                for(int j = 0; j < lenguajes.getLength(); j++){\n                    Element l = (Element) lenguajes.item(j);\n\n                    String lenguaje = l.getTextContent();\n                    leng.add(lenguaje);\n\n                }\n\n                a.setNombre(nombre);\n                a.setEdad(edad);\n                a.setFechaNacimiento(fecha);\n                a.setLenguajes(leng);\n\n                alumnosArrayList.add(a);\n\n            }\n\n            file.delete();\n\n        }catch (ParserConfigurationException e){\n            e.printStackTrace();\n            return true;\n        }catch (IOException e){\n            e.printStackTrace();\n            return true;\n        }catch (SAXException e){\n            e.printStackTrace();\n            return true;\n        }\n        return false;\n    }\n\n    // EJERCICIO EXTRA\n    private static void leerJson(File fileJson, ArrayList<Alumno> alumnosArrayList) {\n\n        Alumno a = null;\n\n        try(FileReader fr = new FileReader(fileJson)){\n\n            JsonObject raiz = JsonParser.parseReader(fr).getAsJsonObject();\n\n            JsonArray alumnosLeer = raiz.getAsJsonArray(\"Alumnos\");\n\n            for(JsonElement alumnoElem: alumnosLeer){\n\n                a  = new Alumno();\n\n                JsonObject alum =  alumnoElem.getAsJsonObject();\n\n                String nombre = alum.get(\"Nombre\").getAsString();\n                int edad = alum.get(\"Edad\").getAsInt();\n                String fecha = alum.get(\"FechaNacimiento\").getAsString();\n                ArrayList<String> leng = new ArrayList<>();\n\n                JsonArray lenguajesLeer = alum.get(\"Lenguaje\").getAsJsonArray();\n\n                for(JsonElement lenguajeElem: lenguajesLeer){\n\n                    leng.add(lenguajeElem.getAsString());\n                }\n\n                a.setNombre(nombre);\n                a.setEdad(edad);\n                a.setFechaNacimiento(fecha);\n                a.setLenguajes(leng);\n\n                alumnosArrayList.add(a);\n\n            }\n\n            fileJson.deleteOnExit();\n\n        }catch (IOException e){\n            e.printStackTrace();\n        }\n    }\n\n    private static void leerJson(File fileJson) {\n        try(FileReader fr = new FileReader(fileJson)){\n\n            System.out.println(\"\\nINFORMACION DE LOS ALUMNOS\");\n            System.out.println(\"=========================\");\n\n            JsonObject raiz = JsonParser.parseReader(fr).getAsJsonObject();\n\n            JsonArray alumnosLeer = raiz.getAsJsonArray(\"Alumnos\");\n\n            int contador = 1;\n\n            for(JsonElement alumnoElem: alumnosLeer){\n\n                JsonObject alum =  alumnoElem.getAsJsonObject();\n\n                String nombre = alum.get(\"Nombre\").getAsString();\n                int edad = alum.get(\"Edad\").getAsInt();\n                String fecha = alum.get(\"FechaNacimiento\").getAsString();\n\n                System.out.println(\"============\");\n                System.out.println(\" - Alumno \" + contador);\n                System.out.println(\"------------\");\n                System.out.println(\"   Nombre: \" + nombre);\n                System.out.println(\"   Edad: \" + edad);\n                System.out.println(\"   FechaNacimiento: \" + fecha);\n                System.out.println(\"   Lenguajes favoritos:\");\n\n                JsonArray lenguajesLeer = alum.get(\"Lenguaje\").getAsJsonArray();\n\n                for(JsonElement lenguajeElem: lenguajesLeer){\n\n                    System.out.println(\"\\t - \" + lenguajeElem.toString());\n                }\n\n                contador++;\n            }\n\n            fileJson.deleteOnExit();\n\n        }catch (IOException e){\n            e.printStackTrace();\n        }\n    }\n\n    private static File crearJson() {\n        // CREAR EL DOCUMENTO JSON\n\n        JsonObject json = new JsonObject();\n        JsonArray alumnos = new JsonArray();\n        JsonObject alumno = new JsonObject();\n        JsonArray lenguajes =  new JsonArray();\n\n        // Alumno 1\n        alumno.addProperty(\"Nombre\", \"Inmaculada\");\n        alumno.addProperty(\"Edad\", \"18\");\n        alumno.addProperty(\"FechaNacimiento\", \"05-04-2007\");\n\n        lenguajes.add(\"Java\");\n        lenguajes.add(\"CSS\");\n        lenguajes.add(\"C++\");\n\n        alumno.add(\"Lenguaje\", lenguajes);\n        alumnos.add(alumno);\n\n        // Alumno 2\n        alumno =  new JsonObject(); // Para \"reiniciar\" el objeto del alumno\n        lenguajes =  new JsonArray(); // Para \"reiniciar\" el array de los lenguajes\n        alumno.addProperty(\"Nombre\", \"Zaira\");\n        alumno.addProperty(\"Edad\", \"17\");\n        alumno.addProperty(\"FechaNacimiento\", \"07-03-2007\");\n\n        lenguajes.add(\"Go\");\n        lenguajes.add(\"Angular\");\n        lenguajes.add(\"React\");\n\n        alumno.add(\"Lenguaje\", lenguajes);\n        alumnos.add(alumno);\n\n        json.add(\"Alumnos\", alumnos);\n\n        Gson gson = new GsonBuilder().setPrettyPrinting().create();\n\n        File fileJson = new  File(\"Alumnos.json\");\n        try (FileWriter fw = new FileWriter(fileJson);){\n\n            gson.toJson(json, fw);\n\n        }catch (IOException e){\n            e.printStackTrace();\n            return null;\n        }\n\n        System.out.println(\"\\n\\nDocumento JSON creado con exito.\");\n        return fileJson;\n    }\n\n    private static boolean leerXML() {\n        // LEER EL DOCUMENTO XML\n\n        File file = new  File(\"Alumnos.xml\");\n\n        try {\n\n            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();\n            DocumentBuilder db = dbf.newDocumentBuilder();\n            Document doc = db.parse(file);\n\n            doc.getDocumentElement().normalize();\n\n            NodeList alumnos = doc.getElementsByTagName(\"Alumno\");\n\n            System.out.println(\"\\nINFORMACION DE LOS ALUMNOS\");\n            System.out.println(\"==========================\");\n\n            for(int i = 0; i < alumnos.getLength(); i++){\n\n                Element alumno = (Element) alumnos.item(i);\n\n                String nombre = alumno.getElementsByTagName(\"Nombre\").item(0).getTextContent();\n                int idAlumno = Integer.parseInt(alumno.getAttribute(\"ID\"));\n                int edad  = Integer.parseInt(alumno.getElementsByTagName(\"Edad\").item(0).getTextContent());\n                String fecha = alumno.getElementsByTagName(\"FechaNacimiento\").item(0).getTextContent();\n\n                System.out.println(\"============\");\n                System.out.println(\" - Alumno \" + idAlumno);\n                System.out.println(\"------------\");\n                System.out.println(\"   Nombre: \" + nombre);\n                System.out.println(\"   Edad: \" + edad);\n                System.out.println(\"   FechaNacimiento: \" + fecha);\n                System.out.println(\"   Lenguajes favoritos:\");\n\n                NodeList lenguajes = alumno.getElementsByTagName(\"Lenguaje\");\n\n                for(int j = 0; j < lenguajes.getLength(); j++){\n                    Element l = (Element) lenguajes.item(j);\n\n                    String lenguaje = l.getTextContent();\n\n                    System.out.println(\"\\t - \" + lenguaje);\n                }\n\n            }\n\n            file.delete();\n\n        }catch (ParserConfigurationException e){\n            e.printStackTrace();\n            return true;\n        }catch (IOException e){\n            e.printStackTrace();\n            return true;\n        }catch (SAXException e){\n            e.printStackTrace();\n            return true;\n        }\n        return false;\n    }\n\n    private static boolean crearXML() {\n        try{\n\n            // CREAR EL DOCUMENTO XML\n\n            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();\n            DocumentBuilder db = dbf.newDocumentBuilder();\n            Document doc = db.newDocument();\n\n            Element raiz = doc.createElement(\"Alumnos\");\n            doc.appendChild(raiz);\n\n            // ALUMNO 1\n            Element alumno = doc.createElement(\"Alumno\");\n            alumno.setAttribute(\"ID\", \"1\");\n            raiz.appendChild(alumno);\n\n            Element nombre = doc.createElement(\"Nombre\");\n            nombre.setTextContent(\"Francisco\");\n            alumno.appendChild(nombre);\n\n            Element edad = doc.createElement(\"Edad\");\n            edad.setTextContent(\"20\");\n            alumno.appendChild(edad);\n\n            Element fchNacimiento = doc.createElement(\"FechaNacimiento\");\n            fchNacimiento.setTextContent(\"13-12-2005\");\n            alumno.appendChild(fchNacimiento);\n\n            Element lenguajes = doc.createElement(\"Lenguajes\");\n            alumno.appendChild(lenguajes);\n\n            Element java =  doc.createElement(\"Lenguaje\");\n            java.setTextContent(\"Java\");\n            lenguajes.appendChild(java);\n            Element python = doc.createElement(\"Lenguaje\");\n            python.setTextContent(\"Python\");\n            lenguajes.appendChild(python);\n            Element sql = doc.createElement(\"Lenguaje\");\n            sql.setTextContent(\"SQL\");\n            lenguajes.appendChild(sql);\n            Element html = doc.createElement(\"Lenguaje\");\n            html.setTextContent(\"HTML\");\n            lenguajes.appendChild(html);\n\n            // ALUMNO 2\n            alumno = doc.createElement(\"Alumno\");\n            alumno.setAttribute(\"ID\", \"2\");\n            raiz.appendChild(alumno);\n\n            nombre = doc.createElement(\"Nombre\");\n            nombre.setTextContent(\"David\");\n            alumno.appendChild(nombre);\n\n            edad = doc.createElement(\"Edad\");\n            edad.setTextContent(\"17\");\n            alumno.appendChild(edad);\n\n            fchNacimiento = doc.createElement(\"FechaNacimiento\");\n            fchNacimiento.setTextContent(\"20-04-2008\");\n            alumno.appendChild(fchNacimiento);\n\n            lenguajes = doc.createElement(\"Lenguajes\");\n            alumno.appendChild(lenguajes);\n\n            Element kotlin =  doc.createElement(\"Lenguaje\");\n            kotlin.setTextContent(\"Kotlin\");\n            lenguajes.appendChild(kotlin);\n            python = doc.createElement(\"Lenguaje\");\n            python.setTextContent(\"Python\");\n            lenguajes.appendChild(python);\n            Element php = doc.createElement(\"Lenguaje\");\n            php.setTextContent(\"PHP\");\n            lenguajes.appendChild(php);\n            Element css = doc.createElement(\"Lenguaje\");\n            css.setTextContent(\"CSS\");\n            lenguajes.appendChild(css);\n\n            Transformer transformer = TransformerFactory.newInstance().newTransformer();\n            transformer.setOutputProperty(OutputKeys.INDENT, \"yes\");\n            transformer.setOutputProperty(\"{http://xml.apache.org/xslt}indent-amount\", \"4\");\n            transformer.transform(\n                    new DOMSource(doc),\n                    new StreamResult(new File(\"Alumnos.xml\"))\n            );\n\n        }catch (ParserConfigurationException e){\n            e.printStackTrace();\n            return true;\n        }catch (TransformerException e){\n            e.printStackTrace();\n            return true;\n        }\n\n        System.out.println(\"Documento XML creado con exito\\n\");\n        return false;\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/java/JimsimroDev.java",
    "content": "import java.io.BufferedReader;\nimport java.io.BufferedWriter;\nimport java.io.File;\nimport java.io.FileNotFoundException;\nimport java.io.FileReader;\nimport java.io.FileWriter;\nimport java.io.IOException;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.Paths;\nimport java.time.LocalDate;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Iterator;\nimport java.util.List;\n\nimport javax.xml.parsers.DocumentBuilder;\nimport javax.xml.parsers.DocumentBuilderFactory;\nimport javax.xml.stream.XMLOutputFactory;\nimport javax.xml.stream.XMLStreamException;\nimport javax.xml.stream.XMLStreamWriter;\n\nimport org.w3c.dom.Document;\nimport org.w3c.dom.NodeList;\n\npublic class JimsimroDev {\n  // Nombres de los archivos XML y JSON\n  private final static String XML_FILENAME = \"backendDeveloper.xml\";\n  private final static String JSON_FILENAME = \"backendDeveloper.json\";\n\n  // Record para almacenar datos\n  public static record MyTuple(\n      String name,\n      int age,\n      LocalDate birthDate,\n      List<String> programmingLanguages) {\n  }\n\n  // Clase para manejar los datos\n  public static class Data {\n    private String name;\n    private int age;\n    private LocalDate birthDate;\n    List<String> programmingLanguages;\n\n    public Data(String name, int age, LocalDate birthDate, List<String> programmingLanguages) {\n      this.name = name;\n      this.age = age;\n      this.birthDate = birthDate;\n      this.programmingLanguages = programmingLanguages;\n    }\n\n    public String getName() {\n      return this.name;\n    }\n\n    public void setName(String name) {\n      this.name = name;\n    }\n\n    public int getAge() {\n      return this.age;\n    }\n\n    public void setAge(int age) {\n      this.age = age;\n    }\n\n    public LocalDate getBirthDate() {\n      return this.birthDate;\n    }\n\n    public void setBirthDate(LocalDate birthDate) {\n      this.birthDate = birthDate;\n    }\n\n    public List<String> getProgrammingLanguages() {\n      return this.programmingLanguages;\n    }\n\n    public void setProgrammingLanguages(List<String> programmingLanguages) {\n      this.programmingLanguages = programmingLanguages;\n    }\n  }\n\n  // Método para crear un archivo XML\n  private static void createXML(MyTuple data, String xmlFilename) throws IOException, XMLStreamException {\n    XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();\n    XMLStreamWriter writer = outputFactory.createXMLStreamWriter(new FileWriter(xmlFilename));\n\n    writer.writeStartDocument(\"UTF-8\", \"1.0\");\n    writer.writeStartElement(\"data\");\n\n    writer.writeStartElement(\"name\");\n    writer.writeCharacters(data.name());\n    writer.writeEndElement();\n\n    writer.writeStartElement(\"age\");\n    writer.writeCharacters(String.valueOf(data.age()));\n    writer.writeEndElement();\n\n    writer.writeStartElement(\"birthDate\");\n    writer.writeCharacters(data.birthDate().toString());\n    writer.writeEndElement();\n\n    writer.writeStartElement(\"programmingLanguages\");\n    Iterator<String> it = data.programmingLanguages().iterator();\n    while (it.hasNext()) {\n      String item = it.next();\n      writer.writeStartElement(\"item\");\n      writer.writeCharacters(item);\n      writer.writeEndElement();\n    }\n\n    writer.writeEndElement();\n\n    writer.writeEndElement();\n    writer.writeEndDocument();\n\n    writer.flush();\n    writer.close();\n    System.out.println(\"XML file created successfully.\");\n    getFile(xmlFilename);\n    // deleteFile(xmlFilename);\n  }\n\n  // Método para crear un archivo JSON\n  private static void createJson(MyTuple data) throws IOException {\n    File jsonFile = new File(JSON_FILENAME);\n\n    StringBuilder json = new StringBuilder();\n    json.append(\"{\\n\");\n    json.append(\" \\\"name\\\": \\\"\" + data.name() + \"\\\",\\n\");\n    json.append(\" \\\"age\\\": \" + data.age() + \",\\n\");\n    json.append(\" \\\"birthDate\\\": \\\"\" + data.birthDate() + \"\\\",\\n\");\n\n    json.append(\" \\\"programmingLanguages\\\": [\\n\");\n    for (int i = 0; i < data.programmingLanguages.size(); i++) {\n      json.append(\"     \\\"\" + data.programmingLanguages.get(i) + \"\\\"\");\n      if (i < data.programmingLanguages.size() - 1) {\n        json.append(\",\");\n      }\n      json.append(\"\\n\");\n    }\n    json.append(\"  ]\");\n    json.append(\"\\n}\");\n\n    System.out.println(\"JSON file created successfully.\");\n\n    // Escribir el archivo JSON\n    try (BufferedWriter br = new BufferedWriter(new FileWriter(jsonFile))) {\n      br.write(json.toString());\n    }\n    getFile(JSON_FILENAME);\n    // deleteFile(JSON_FILENAME);\n  }\n\n  // Método para leer un archivo y mostrar su contenido\n  private static void getFile(String fileName) throws IOException, FileNotFoundException {\n    FileReader file = new FileReader(fileName);\n    try (BufferedReader bf = new BufferedReader(file)) {\n      String line = \"\";\n      while ((line = bf.readLine()) != null) {\n        System.out.println(line);\n      }\n    }\n  }\n\n  // Método para parsear un JSON a un objeto Data\n  private static Data parseJsonToData(String jsonString) {\n    try {\n      String name = jsonString.split(\"\\\"name\\\"\\\\s*:\\\\s*\\\"\")[1].split(\"\\\"\")[0];\n      int age = Integer.parseInt(jsonString.split(\"\\\"age\\\"\\\\s*:\\\\s*\")[1].split(\",\")[0]);\n      String birthDate = jsonString.split(\"\\\"birthDate\\\"\\\\s*:\\\\s*\\\"\")[1].split(\"\\\"\")[0];\n      String languagesString = jsonString.split(\"\\\"programmingLanguages\\\"\\\\s*:\\\\s*\\\\[\")[1].split(\"\\\\]\")[0];\n      List<String> programmingLanguages = new ArrayList<>();\n      for (String lang : languagesString.split(\",\")) {\n        programmingLanguages.add(lang.replace(\"\\\"\", \"\").trim());\n      }\n      return new Data(name, age, LocalDate.parse(birthDate), programmingLanguages);\n    } catch (ArrayIndexOutOfBoundsException e) {\n      System.err.println(\"Error parsing JSON: \" + e.getMessage());\n      e.printStackTrace();\n      return null;\n    }\n  }\n\n  // Método para eliminar un archivo\n  private static void deleteFile(String file) {\n    Path path = Paths.get(file);\n    try {\n      Files.delete(path);\n    } catch (IOException e) {\n      System.out.println(e.getClass().getName() + \" generated: \" + e.getMessage());\n      e.printStackTrace();\n    }\n  }\n\n  // Método principal\n  public static void main(String[] args) throws Exception, IOException, XMLStreamException {\n    // Datos de ejemplo\n    String name = \"Jimmis Jhaon\";\n    int age = 29;\n    LocalDate birthDate = LocalDate.of(1995, 07, 28);\n    String[] languages = { \"Java\", \"Kotlin\", \"Elixir\", \"Lua\" };\n    List<String> programmingLanguages = Arrays.asList(languages);\n\n    MyTuple data = new MyTuple(name, age, birthDate, programmingLanguages);\n\n    // Crear archivos XML y JSON\n    createXML(data, XML_FILENAME);\n    createJson(data);\n\n    // Leer y parsear el archivo JSON\n    FileReader file = new FileReader(JSON_FILENAME);\n    try (BufferedReader bf = new BufferedReader(file)) {\n      StringBuilder jsonBuilder = new StringBuilder();\n      String line = \"\";\n      while ((line = bf.readLine()) != null) {\n        jsonBuilder.append(line);\n      }\n      String jsonString = jsonBuilder.toString();\n      Data jsonData = parseJsonToData(jsonString);\n      System.out.println(\"Name: \" + jsonData.getName());\n      System.out.println(\"Age: \" + jsonData.getAge());\n      System.out.println(\"BirthDate: \" + jsonData.getBirthDate());\n      System.out.println(\"Languages: \" + jsonData.getProgrammingLanguages());\n    }\n\n    // Leer y parsear el archivo XML\n    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();\n    DocumentBuilder builder = factory.newDocumentBuilder();\n    Document document = builder.parse(new File(XML_FILENAME));\n\n    NodeList nodeList = document.getDocumentElement().getChildNodes();\n    String name1 = nodeList.item(0).getTextContent(); // Obtener el nombre del nodo\n    int age1 = Integer.parseInt(nodeList.item(1).getTextContent()); // Obtener la edad del nodo\n    LocalDate birthDate1 = LocalDate.parse(nodeList.item(2).getTextContent()); // Obtener la fecha de nacimiento del\n                                                                               // nodo\n\n    NodeList languages1 = nodeList.item(3).getChildNodes(); // Obtener los lenguajes de programación del nodo\n    List<String> languagesList = new ArrayList<>(); // Convertir a lista\n    for (int i = 0; i < languages1.getLength(); i++) {\n      languagesList.add(languages1.item(i).getTextContent());\n    }\n\n    Data xmlData = new Data(name1, age1, birthDate1, languagesList);\n\n    System.out.println(\"Name: \" + xmlData.getName());\n    System.out.println(\"Age: \" + xmlData.getAge());\n    System.out.println(\"BirthDate: \" + xmlData.getBirthDate());\n    System.out.println(\"Languages: \" + String.join(\", \", xmlData.getProgrammingLanguages()));\n\n    // Eliminar archivos creados\n    deleteFile(XML_FILENAME);\n    deleteFile(JSON_FILENAME);\n  }\n}\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/java/Josegs95.java",
    "content": "import com.fasterxml.jackson.core.JsonProcessingException;\nimport com.fasterxml.jackson.databind.ObjectMapper;\nimport org.w3c.dom.Document;\nimport org.w3c.dom.Element;\nimport org.w3c.dom.Node;\nimport org.w3c.dom.NodeList;\nimport org.xml.sax.SAXException;\n\nimport javax.xml.parsers.DocumentBuilder;\nimport javax.xml.parsers.DocumentBuilderFactory;\nimport javax.xml.parsers.ParserConfigurationException;\nimport javax.xml.transform.*;\nimport javax.xml.transform.dom.DOMSource;\nimport javax.xml.transform.stream.StreamResult;\nimport java.io.File;\nimport java.io.IOException;\nimport java.nio.file.Files;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\npublic class Josegs95 {\n\n    private static final String XML_FILENAME = \"Josegs95.xml\";\n    private static final String JSON_FILENAME = \"Josegs95.json\";\n\n    public static void main(String[] args) {\n        String name = \"Jose\";\n        String age = \"29\";\n        String birthdate = \"28-02-1995\";\n\n        List<String> languageList = new ArrayList<>();\n        languageList.add(\"Java\");\n        languageList.add(\"Python\");\n\n        Map<String, Object> dataMap = new HashMap<>();\n        dataMap.put(\"name\", name);\n        dataMap.put(\"age\", age);\n        dataMap.put(\"birthdate\", birthdate);\n        dataMap.put(\"language_list\", languageList);\n\n        //El reto usa los archivos de los ejercicios XML y JSON, por eso la línea que borra\n        //los ficheros está comentada.\n\n        //XML\n        exerciseXML(dataMap);\n\n        //JSON\n        exerciseJSON(dataMap);\n\n        //Reto\n        System.out.println(\"\\n\");\n        retoFinal();\n    }\n\n    private static void exerciseXML(Map<String, Object> dataMap){\n        try {\n            //Creo el builder\n            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();\n            DocumentBuilder builder = factory.newDocumentBuilder();\n\n            //Obtengo el documento\n            Document document = builder.newDocument();\n\n            //Creo el elemento raiz\n            Element root = document.createElement(\"datos\");\n            document.appendChild(root);\n\n            //Creo los elementos para insertar los datos y los coloco bajo el elemento raiz\n\n            for (Map.Entry<String, Object> entry : dataMap.entrySet()){\n                Element element = document.createElement(entry.getKey());\n                Object value = entry.getValue();\n                if (value instanceof String)\n                    element.appendChild(document.createTextNode((String) value));\n                else if (value instanceof List<?>){\n                    for (String itemText : ((List<String>) value)){\n                        Element itemElement = document.createElement(\"language\");\n                        itemElement.appendChild(document.createTextNode(itemText));\n                        element.appendChild(itemElement);\n                    }\n                } else\n                    continue;\n\n                root.appendChild(element);\n            }\n\n            //Creo el objeto transformer y lo preparo para escribir el documento con el que hemos trabajado\n            TransformerFactory transformerFactory = TransformerFactory.newInstance();\n            Transformer transformer = transformerFactory.newTransformer();\n            //transformer.setOutputProperty(OutputKeys.INDENT, \"yes\"); //Para ver de forma mas clara el XML\n            DOMSource source = new DOMSource(document);\n\n            //Escribo en el archivo con la ruta especificada\n            File xmlFile = new File(XML_FILENAME);\n            StreamResult result = new StreamResult(xmlFile);\n            transformer.transform(source, result);\n\n            //Leer el XML\n\n            //Leemos el archivo de forma normal\n            String xmlString = new String(Files.readAllBytes(xmlFile.toPath()));\n            System.out.println(xmlString);\n\n            //deleteFile(new File (XML_FILENAME));\n        } catch (ParserConfigurationException e) {\n            throw new RuntimeException(e);\n        } catch (TransformerConfigurationException e) {\n            throw new RuntimeException(e);\n        } catch (TransformerException e) {\n            throw new RuntimeException(e);\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        }\n    }\n\n    private static void exerciseJSON(Map<String, Object> dataMap){\n        try {\n            File jsonFile = new File (JSON_FILENAME);\n            ObjectMapper objectMapper = new ObjectMapper();\n\n            //Escribir en el fichero un mapa en formato JSON\n            //objectMapper.writeValue(jsonFile, dataMap);\n            objectMapper.writerWithDefaultPrettyPrinter().writeValue(jsonFile, dataMap);\n\n            //Recuperar los datos de un JSON y meterlos en un mapa\n            Map<String, Object> newDataMap = new HashMap<>();\n            newDataMap = objectMapper.readValue(jsonFile, newDataMap.getClass());\n            System.out.println(newDataMap);\n\n            //deleteFile(jsonFile);\n        } catch (JsonProcessingException e) {\n            throw new RuntimeException(e);\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        }\n    }\n\n    private static void retoFinal(){\n        //XML\n        File xmlFile = new File(XML_FILENAME);\n        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();\n        try {\n            DocumentBuilder builder = factory.newDocumentBuilder();\n            Document document = builder.parse(xmlFile);\n\n            //document.getDocumentElement().normalize();\n            String name = document.getElementsByTagName(\"name\").item(0).getTextContent();\n            String age = document.getElementsByTagName(\"age\").item(0).getTextContent();\n            String birthdate = document.getElementsByTagName(\"birthdate\").item(0).getTextContent();\n            List<String> languageList = new ArrayList<>();\n\n            Node languagesNode = document.getElementsByTagName(\"language_list\").item(0);\n            NodeList languagesNodeList = languagesNode.getChildNodes();\n            for (int i = 0; i < languagesNodeList.getLength(); i++){\n                Node node = languagesNodeList.item(i);\n                languageList.add(node.getTextContent());\n            }\n\n            Person personFromXML = new Person(name, age, birthdate, languageList);\n            System.out.println(\"Persona XML = \" + personFromXML);\n        } catch (ParserConfigurationException e) {\n            throw new RuntimeException(e);\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        } catch (SAXException e) {\n            throw new RuntimeException(e);\n        }\n\n        //JSON\n        File jsonFile = new File (JSON_FILENAME);\n        ObjectMapper objectMapper = new ObjectMapper();\n\n        try {\n            Map<String, Object> dataMap = new HashMap<>();\n            dataMap = objectMapper.readValue(jsonFile, dataMap.getClass());\n\n            String name = (String) dataMap.get(\"name\");\n            String age = (String) dataMap.get(\"age\");\n            String birthdate = (String) dataMap.get(\"birthdate\");\n            List<String> languageList = (List<String>) dataMap.get(\"language_list\");\n            Person personFromJSON = new Person(name, age, birthdate, languageList);\n\n            System.out.println(\"Persona JSOM = \" + personFromJSON);\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        }\n\n        deleteFile(xmlFile);\n        deleteFile(jsonFile);\n    }\n\n    private static void deleteFile(File file){\n        if (file.delete())\n                System.out.println(\"Se ha borrado el archivo con éxito.\");\n            else\n                System.out.println(\"No se ha podido borrar el archivo.\");\n    }\n\n    public static class Person{\n        private String name;\n        private String age;\n        private String birthdate;\n        private List<String> languageList;\n\n        public Person(String name, String age, String birthdate, List<String> languageList) {\n            this.name = name;\n            this.age = age;\n            this.birthdate = birthdate;\n            this.languageList = languageList;\n        }\n\n        public Person(){}\n\n        public String getName() {\n            return name;\n        }\n\n        public void setName(String name) {\n            this.name = name;\n        }\n\n        public String getAge() {\n            return age;\n        }\n\n        public void setAge(String age) {\n            this.age = age;\n        }\n\n        public String getBirthdate() {\n            return birthdate;\n        }\n\n        public void setBirthdate(String birthdate) {\n            this.birthdate = birthdate;\n        }\n\n        public List<String> getLanguageList() {\n            return languageList;\n        }\n\n        public void setLanguageList(List<String> languageList) {\n            this.languageList = languageList;\n        }\n\n        @Override\n        public String toString() {\n            return \"Nombre: \" + name +\n                    \", Edad: \" + age +\n                    \", Fecha de nacimiento: \" + birthdate +\n                    \", Lista de lenguajes: \" + languageList;\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/java/RodrigoGit87.java",
    "content": "import java.io.IOException;\nimport java.nio.file.*;\nimport java.util.*;\n\npublic class RodrigoGit87 {\n    private static final String ARCHIVO_JSON = \"RodrigoGit87.json\";\n    private static final String ARCHIVO_XML = \"RodrigoGit87.xml\";\n\n    public static void main(String[] args){\n        Usuario nuevoUsuario;\n        nuevoUsuario = new Usuario(\"Rodrigo\", 38, \"24-05-1987\",\n                List.of(\n                \"java\",\n                \"javascript\",\n                \"HTML\",\n                \"CSS\",\n                \"SQL\"));\n\n        // Crear builders\n        StringBuilder json = new StringBuilder();\n        StringBuilder xml = new StringBuilder();\n\n        //Añadir el texto en JSON\n        json.append(\"{\\n\");\n        json.append(\"  \\\"nombre\\\": \\\"\").append(nuevoUsuario.getNombre()).append(\"\\\",\\n\");\n        json.append(\" \\\"edad\\\": \").append(nuevoUsuario.getEdad()).append(\",\\n\");\n        json.append(\" \\\"fecha_nacimiento\\\": \\\"\").append(nuevoUsuario.getFecha_nacimiento()).append(\"\\\",\\n \");\n        json.append(\"\\\"lenguajes\\\": [ \\\"\");\n        json.append(String.join(\"\\\", \\\"\",nuevoUsuario.getLenguajes()));\n        json.append(\"\\\" ]\\n\");\n        json.append(\"}\\n\");\n\n        System.out.println(json.toString());\n\n\n        //Añadir el texto en XML\n        xml.append(\"<usuario>\\n\");\n        xml.append(\" <nombre>\"+nuevoUsuario.getNombre()+\"</nombre>\\n\");\n        xml.append(\" <edad>\"+nuevoUsuario.getEdad()+\"</edad>\\n\");\n        xml.append(\" <fecha_nacimiento>\"+nuevoUsuario.getFecha_nacimiento()+\"</fecha_nacimiento>\\n\");\n        xml.append(\" <lenguajes>\");\n        for (String key: nuevoUsuario.getLenguajes()) xml.append(\" <lenguaje>\").append(key).append(\"</lenguaje>\\n\");\n        xml.append(\" </lenguajes>\\n\");\n        xml.append(\"</usuario>\\n\");\n\n\n        //RUTAS\n        Path rutaJson = Paths.get(ARCHIVO_JSON);\n        Path rutaXML = Paths.get(ARCHIVO_XML);\n\n        //ESCRIBIR LOS DATOS EN UN ARCHIVO\n        try {\n            Files.writeString(rutaJson, json.toString());\n            Files.writeString(rutaXML, xml.toString());\n            System.out.println(\"Archivos creados\\n\");\n        } catch (Exception e) {\n            System.err.println (\"Error al crear ficheros: \"+ e.getMessage()+\"\\n\");\n        }\n\n        //MOSTRAR CONTENIDO\n        try {\n            System.out.println(\" - ARCHIVO JSON-\\n\"+Files.readString(rutaJson));\n        } catch (IOException e) {\n            System.err.println (\"Error al leer archivo de rutaJSON: \"+ e.getMessage()+\"\\n\");\n        }\n        try {\n            System.out.println(\"- ARCHIVO XML -\\n\" + Files.readString(rutaXML));\n        } catch (IOException e) {\n            System.err.println (\"Error al leer archivo de ruta XML: \"+ e.getMessage()+\"\\n\");\n        }\n\n        // BORRAR CONTENIDO\n        try {\n            Files.deleteIfExists(rutaJson);\n            System.out.println(\"JSON eliminado\\n\");\n        } catch (IOException e) {\n            System.err.println(\"Error al eliminar archivo de rutaJSON: \"+ e.getMessage()+\"\\n\");\n        }\n\n        try {\n            Files.deleteIfExists(rutaXML);\n            System.out.println(\"XML eliminado\\n\");\n        } catch (IOException e) {\n            System.err.println(\"Error al eliminar archivo de ruta XML: \"+ e.getMessage()+\"\\n\");\n        }\n    }\n\n\n\n        // ----------------------\n        // Clase User\n        //---------------------\n        static class Usuario {\n            private String nombre;\n            private int edad;\n            private String fecha_nacimiento;\n            private List<String> lenguajes;\n\n            public Usuario(String nombre, int edad, String fecha_nacimiento, List<String> lenguajes) {\n                this.nombre = nombre;\n                this.edad = edad;\n                this.fecha_nacimiento = fecha_nacimiento;\n                this.lenguajes = lenguajes;\n            }\n\n            @Override\n            public String toString() {\n                return \"Usuario{\" +\n                        \"nombre='\" + nombre + '\\'' +\n                        \", edad='\" + edad + '\\'' +\n                        \", fecha_nacimiento='\" + fecha_nacimiento + '\\'' +\n                        \", lenguajes=\" + lenguajes +\n                        '}';\n            }\n\n            //Getters & Setters\n            public String getNombre() {\n                return nombre;\n            }\n\n            public void setNombre(String nombre) {\n                this.nombre = nombre;\n            }\n\n            public int getEdad() {\n                return edad;\n            }\n\n            public void setEdad(int edad) {\n                this.edad = edad;\n            }\n\n            public String getFecha_nacimiento() {\n                return fecha_nacimiento;\n            }\n\n            public void setFecha_nacimiento(String fecha_nacimiento) {\n                this.fecha_nacimiento = fecha_nacimiento;\n            }\n\n            public List<String> getLenguajes() {\n                return lenguajes;\n            }\n\n            public void setLenguajes(List<String> lenguajes) {\n                this.lenguajes = lenguajes;\n            }\n        }\n}"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/java/asjordi.java",
    "content": "import com.fasterxml.jackson.core.JsonProcessingException;\nimport com.fasterxml.jackson.databind.ObjectMapper;\nimport com.fasterxml.jackson.databind.SerializationFeature;\nimport com.fasterxml.jackson.dataformat.xml.XmlMapper;\nimport com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.time.LocalDate;\nimport java.util.List;\n\npublic class Main {\n\n    public static void main(String[] args) throws IOException {\n        crearJson();\n        leerJson();\n        crearXml();\n        leerXml();\n    }\n\n    record Pojo(String nombre, Integer edad, LocalDate fechaNacimiento, List<String> lenguajes) {}\n\n    static void crearJson() {\n        Pojo pojo = new Pojo(\"Jordi\", 25, LocalDate.of(1995, 8, 1), List.of(\"Java\", \"Kotlin\", \"Scala\"));\n\n        ObjectMapper mapper = new ObjectMapper();\n        mapper.registerModule(new JavaTimeModule());\n\n        try {\n            mapper.writeValue(new File(\"pojo.json\"), pojo);\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n    }\n\n    static void leerJson() {\n        ObjectMapper mapper = new ObjectMapper();\n        mapper.registerModule(new JavaTimeModule());\n        File jsonFile = new File(\"pojo.json\");\n\n        try {\n            var pojo = mapper.readValue(jsonFile, Pojo.class);\n            System.out.println(pojo);\n            jsonFile.delete();\n            System.out.println(\"Fichero eliminado\");\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n    }\n\n    static void crearXml() {\n        Pojo pojo = new Pojo(\"Jordi\", 25, LocalDate.of(1995, 8, 1), List.of(\"Java\", \"Kotlin\", \"Scala\"));\n        ObjectMapper xmlMapper = new XmlMapper();\n        xmlMapper.registerModule(new JavaTimeModule());\n        xmlMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);\n\n        try {\n            xmlMapper.writeValue(new File(\"pojo.xml\"), pojo);\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n    }\n\n    static void leerXml() {\n        ObjectMapper xmlMapper = new XmlMapper();\n        xmlMapper.registerModule(new JavaTimeModule());\n        File xmlFile = new File(\"pojo.xml\");\n\n        try {\n            var pojo = xmlMapper.readValue(xmlFile, Pojo.class);\n            System.out.println(pojo);\n            xmlFile.delete();\n            System.out.println(\"Fichero eliminado\");\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n    }\n\n    /**\n     * Maven dependencies:\n     * jackson-databind\n     * jackson-datatype-jsr310\n     * jackson-dataformat-xml\n     */\n\n}\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/java/danhingar.java",
    "content": "\nimport java.io.BufferedReader;\nimport java.io.ByteArrayInputStream;\nimport java.io.File;\nimport java.io.FileReader;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.text.ParseException;\nimport java.text.SimpleDateFormat;\nimport java.util.ArrayList;\nimport java.util.Date;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport javax.xml.parsers.DocumentBuilder;\nimport javax.xml.parsers.DocumentBuilderFactory;\nimport javax.xml.transform.Transformer;\nimport javax.xml.transform.TransformerFactory;\nimport javax.xml.transform.dom.DOMSource;\nimport javax.xml.transform.stream.StreamResult;\n\nimport org.w3c.dom.Document;\nimport org.w3c.dom.Element;\nimport org.w3c.dom.NodeList;\n\npublic class danhingar {\n\n    public static void main(String[] args) throws Exception {\n        createJSON();\n        createXML();\n        readJson(\"danhingar.json\");\n        readXML(\"danhingar.xml\");\n\n        Files.delete(Path.of(\"danhingar.json\"));\n        Files.delete(Path.of(\"danhingar.xml\"));\n        loadDataFromJson();\n        loadDataFromXML();\n    }\n\n    private static void readJson(String path) {\n        try {\n            Path path2 = Path.of(path);\n            Files.readAllLines(path2).stream().forEach(line -> System.out.println(line));\n        } catch (Exception e) {\n            System.out.println(\"Error al leer el fichero JSON\");\n        }\n    }\n\n    private static void readXML(String filename) throws Exception {\n        DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();\n        Document doc = builder.parse(new File(filename));\n        DOMSource dom = new DOMSource(doc);\n\n        Transformer transformer = TransformerFactory.newInstance().newTransformer();\n        transformer.transform(dom, new StreamResult(System.out));\n        System.out.println(\"\");\n    }\n\n    private static void createXML() {\n        try {\n            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();\n            DocumentBuilder builder;\n            Document doc = null;\n            builder = factory.newDocumentBuilder();\n            doc = builder.newDocument();\n            Element root = doc.createElement(\"user\");\n            doc.appendChild(root);\n\n            Element name = doc.createElement(\"name\");\n            name.appendChild(doc.createTextNode(\"Daniel\"));\n            root.appendChild(name);\n\n            Element age = doc.createElement(\"age\");\n            age.appendChild(doc.createTextNode(\"27\"));\n            root.appendChild(age);\n\n            Element birthDate = doc.createElement(\"birthDate\");\n            birthDate.appendChild(doc.createTextNode(\"29-04-1997\"));\n            root.appendChild(birthDate);\n\n            Element lenguages = doc.createElement(\"programmingLanguages\");\n            for (String language : List.of(\"Java\", \"Dart\", \"Swift\")) {\n                Element languageItem = doc.createElement(\"language\");\n                languageItem.setTextContent(language);\n                lenguages.appendChild(languageItem);\n            }\n\n            root.appendChild(lenguages);\n\n            DOMSource dom = new DOMSource(doc);\n            Transformer transformer = TransformerFactory.newInstance()\n                    .newTransformer();\n\n            StreamResult result = new StreamResult(new File(\"danhingar.xml\"));\n            transformer.transform(dom, result);\n        } catch (Exception e) {\n            System.out.println(\"Error al crear el fichero XML\");\n        }\n    }\n\n    private static void createJSON() {\n        String jsonContent = \"{\\n\" +\n                \"    \\\"name\\\": \\\"Daniel\\\",\\n\" +\n                \"    \\\"age\\\": 27,\\n\" +\n                \"    \\\"birthDate\\\": \\\"29-04-1997\\\",\\n\" +\n                \"    \\\"programmingLanguages\\\": [\\\"Java\\\", \\\"Dart\\\", \\\"Swift\\\"]\\n\" +\n                \"}\";\n\n        try {\n            Path path = Path.of(\"danhingar.json\");\n            Files.writeString(path, jsonContent);\n        } catch (IOException e) {\n            System.out.println(\"Error al crear el archivo JSON: \" + e.getMessage());\n        }\n    }\n\n    // Extra\n    private static void loadDataFromJson() {\n        createJSON();\n        try {\n            Path path2 = Path.of(\"danhingar.json\");\n            List<String> lines = Files.readAllLines(path2);\n            Map<String, Object> properties = new HashMap<>();\n            for (int i = 1; i < lines.size() - 1; i++) {\n                String[] keyValue = lines.get(i).split(\":\");\n                String key = keyValue[0].trim().replaceAll(\"\\\"\", \"\");\n                String value = keyValue[1].trim().replaceAll(\"\\\"\", \"\");\n                properties.put(key, value);\n            }\n\n            String name = properties.get(\"name\").toString().replaceAll(\",\", \"\");\n            Integer age = Integer.parseInt(properties.get(\"age\").toString().replaceAll(\",\", \"\"));\n            Date birthDate = toDate(properties.get(\"birthDate\").toString().replaceAll(\",\", \"\"));\n            String[] languages = properties.get(\"programmingLanguages\").toString().split(\",\");\n            List<String> languagesList = List.of(languages);\n\n            Data data = new Data(name, age, birthDate, languagesList);\n\n            System.out.println(data.toString());\n        } catch (Exception e) {\n            System.out.println(\"Error al crear la clase Data desde el fichero JSON\");\n        }\n    }\n\n    private static void loadDataFromXML() {\n        createXML();\n        try {\n            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();\n            DocumentBuilder builder = factory.newDocumentBuilder();\n            StringBuilder contenido = new StringBuilder();\n\n            try (BufferedReader br = new BufferedReader(new FileReader(\"danhingar.xml\"))) {\n                String linea;\n\n                while ((linea = br.readLine()) != null) {\n                    contenido.append(linea).append(\"\\n\");\n                }\n            }\n            InputStream is = new ByteArrayInputStream(contenido.toString().getBytes(\"UTF-8\"));\n            Document document = builder.parse(is);\n\n            Element root = document.getDocumentElement();\n\n            String name = root.getElementsByTagName(\"name\").item(0).getTextContent();\n            Integer age = Integer.parseInt(root.getElementsByTagName(\"age\").item(0).getTextContent());\n            Date birthDate = toDate(root.getElementsByTagName(\"birthDate\").item(0).getTextContent());\n            NodeList languages = root.getElementsByTagName(\"language\");\n            List<String> languagesList = new ArrayList<>();\n            for (int i = 0; i < languages.getLength(); i++) {\n                languagesList.add(languages.item(i).getTextContent());\n            }\n\n            Data data = new Data(name, age, birthDate, languagesList);\n\n            System.out.println(data.toString());\n\n        } catch (Exception e) {\n            System.out.println(\"Error al crear la clase Data desde el fichero XML\");\n        }\n\n    }\n\n    public static class Data {\n        private String name;\n        private Integer age;\n        private Date birthDate;\n        private List<String> programmingLanguages;\n\n        public Data(String name, Integer age, Date birthDate, List<String> programmingLanguages) {\n            this.name = name;\n            this.age = age;\n            this.birthDate = birthDate;\n            this.programmingLanguages = programmingLanguages;\n        }\n\n        public String getName() {\n            return name;\n        }\n\n        public void setName(String name) {\n            this.name = name;\n        }\n\n        public Integer getAge() {\n            return age;\n        }\n\n        public void setAge(Integer age) {\n            this.age = age;\n        }\n\n        public Date getBirthDate() {\n            return birthDate;\n        }\n\n        public void setBirthDate(Date birthDate) {\n            this.birthDate = birthDate;\n        }\n\n        public List<String> getProgrammingLanguages() {\n            return programmingLanguages;\n        }\n\n        public void setProgrammingLanguages(List<String> programmingLanguages) {\n            this.programmingLanguages = programmingLanguages;\n        }\n\n        @Override\n        public String toString() {\n            return \"Data [name=\" + name + \", age=\" + age + \", birthDate=\" + birthDate + \", programmingLanguages=\"\n                    + programmingLanguages + \"]\";\n        }\n    }\n\n    private static Date toDate(String dateString) {\n        SimpleDateFormat dateFormat = new SimpleDateFormat(\"yyyy-MM-dd\");\n\n        try {\n            Date date = dateFormat.parse(dateString);\n            return date;\n        } catch (ParseException e) {\n            System.err.println(\"Invalid date format: \" + e.getMessage());\n            return null;\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/java/eulogioep.java",
    "content": "import java.io.*;\nimport java.util.*;\nimport javax.xml.parsers.*;\nimport javax.xml.transform.*;\nimport javax.xml.transform.dom.*;\nimport javax.xml.transform.stream.*;\nimport org.w3c.dom.*;\nimport org.json.simple.*;\nimport org.json.simple.parser.*;\n\npublic class eulogioep {\n    public static void main(String[] args) {\n        // Datos de ejemplo\n        String nombre = \"Juan\";\n        int edad = 30;\n        String fechaNacimiento = \"1993-05-15\";\n        List<String> lenguajesProgramacion = Arrays.asList(\"Java\", \"Python\", \"JavaScript\");\n\n        // Crear y mostrar archivo XML\n        crearArchivoXML(nombre, edad, fechaNacimiento, lenguajesProgramacion);\n        System.out.println(\"Contenido del archivo XML:\");\n        mostrarContenidoArchivo(\"datos.xml\");\n\n        // Crear y mostrar archivo JSON\n        crearArchivoJSON(nombre, edad, fechaNacimiento, lenguajesProgramacion);\n        System.out.println(\"\\nContenido del archivo JSON:\");\n        mostrarContenidoArchivo(\"datos.json\");\n\n        // Borrar archivos\n        borrarArchivo(\"datos.xml\");\n        borrarArchivo(\"datos.json\");\n\n        // DIFICULTAD EXTRA\n        // Crear archivos nuevamente para la lectura\n        crearArchivoXML(nombre, edad, fechaNacimiento, lenguajesProgramacion);\n        crearArchivoJSON(nombre, edad, fechaNacimiento, lenguajesProgramacion);\n\n        // Leer y transformar datos\n        Persona personaXML = leerXML(\"datos.xml\");\n        Persona personaJSON = leerJSON(\"datos.json\");\n\n        System.out.println(\"\\nDatos leídos del XML:\");\n        System.out.println(personaXML);\n        System.out.println(\"\\nDatos leídos del JSON:\");\n        System.out.println(personaJSON);\n\n        // Borrar archivos nuevamente\n        borrarArchivo(\"datos.xml\");\n        borrarArchivo(\"datos.json\");\n    }\n\n    // Método para crear el archivo XML\n    public static void crearArchivoXML(String nombre, int edad, String fechaNacimiento, List<String> lenguajesProgramacion) {\n        try {\n            DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();\n            DocumentBuilder docBuilder = docFactory.newDocumentBuilder();\n\n            // Crear el elemento raíz\n            Document doc = docBuilder.newDocument();\n            Element rootElement = doc.createElement(\"persona\");\n            doc.appendChild(rootElement);\n\n            // Agregar elementos hijos\n            Element nombreElement = doc.createElement(\"nombre\");\n            nombreElement.setTextContent(nombre);\n            rootElement.appendChild(nombreElement);\n\n            Element edadElement = doc.createElement(\"edad\");\n            edadElement.setTextContent(String.valueOf(edad));\n            rootElement.appendChild(edadElement);\n\n            Element fechaNacimientoElement = doc.createElement(\"fechaNacimiento\");\n            fechaNacimientoElement.setTextContent(fechaNacimiento);\n            rootElement.appendChild(fechaNacimientoElement);\n\n            Element lenguajesElement = doc.createElement(\"lenguajesProgramacion\");\n            for (String lenguaje : lenguajesProgramacion) {\n                Element lenguajeElement = doc.createElement(\"lenguaje\");\n                lenguajeElement.setTextContent(lenguaje);\n                lenguajesElement.appendChild(lenguajeElement);\n            }\n            rootElement.appendChild(lenguajesElement);\n\n            // Escribir el contenido en un archivo XML\n            TransformerFactory transformerFactory = TransformerFactory.newInstance();\n            Transformer transformer = transformerFactory.newTransformer();\n            DOMSource source = new DOMSource(doc);\n            StreamResult result = new StreamResult(new File(\"datos.xml\"));\n            transformer.transform(source, result);\n\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n    }\n\n    // Método para crear el archivo JSON\n    @SuppressWarnings(\"unchecked\")\n    public static void crearArchivoJSON(String nombre, int edad, String fechaNacimiento, List<String> lenguajesProgramacion) {\n        JSONObject jsonObject = new JSONObject();\n        jsonObject.put(\"nombre\", nombre);\n        jsonObject.put(\"edad\", edad);\n        jsonObject.put(\"fechaNacimiento\", fechaNacimiento);\n        jsonObject.put(\"lenguajesProgramacion\", lenguajesProgramacion);\n\n        try (FileWriter file = new FileWriter(\"datos.json\")) {\n            file.write(jsonObject.toJSONString());\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n    }\n\n    // Método para mostrar el contenido de un archivo\n    public static void mostrarContenidoArchivo(String nombreArchivo) {\n        try (BufferedReader br = new BufferedReader(new FileReader(nombreArchivo))) {\n            String linea;\n            while ((linea = br.readLine()) != null) {\n                System.out.println(linea);\n            }\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n    }\n\n    // Método para borrar un archivo\n    public static void borrarArchivo(String nombreArchivo) {\n        File archivo = new File(nombreArchivo);\n        if (archivo.delete()) {\n            System.out.println(\"El archivo \" + nombreArchivo + \" ha sido borrado.\");\n        } else {\n            System.out.println(\"No se pudo borrar el archivo \" + nombreArchivo);\n        }\n    }\n\n    // DIFICULTAD EXTRA\n\n    // Clase personalizada para almacenar los datos\n    static class Persona {\n        String nombre;\n        int edad;\n        String fechaNacimiento;\n        List<String> lenguajesProgramacion;\n\n        @Override\n        public String toString() {\n            return \"Persona{\" +\n                    \"nombre='\" + nombre + '\\'' +\n                    \", edad=\" + edad +\n                    \", fechaNacimiento='\" + fechaNacimiento + '\\'' +\n                    \", lenguajesProgramacion=\" + lenguajesProgramacion +\n                    '}';\n        }\n    }\n\n    // Método para leer el archivo XML y convertirlo a la clase Persona\n    public static Persona leerXML(String nombreArchivo) {\n        Persona persona = new Persona();\n        try {\n            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();\n            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();\n            Document doc = dBuilder.parse(new File(nombreArchivo));\n            doc.getDocumentElement().normalize();\n\n            persona.nombre = doc.getElementsByTagName(\"nombre\").item(0).getTextContent();\n            persona.edad = Integer.parseInt(doc.getElementsByTagName(\"edad\").item(0).getTextContent());\n            persona.fechaNacimiento = doc.getElementsByTagName(\"fechaNacimiento\").item(0).getTextContent();\n\n            persona.lenguajesProgramacion = new ArrayList<>();\n            NodeList lenguajesList = doc.getElementsByTagName(\"lenguaje\");\n            for (int i = 0; i < lenguajesList.getLength(); i++) {\n                persona.lenguajesProgramacion.add(lenguajesList.item(i).getTextContent());\n            }\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n        return persona;\n    }\n\n    // Método para leer el archivo JSON y convertirlo a la clase Persona\n    public static Persona leerJSON(String nombreArchivo) {\n        Persona persona = new Persona();\n        JSONParser parser = new JSONParser();\n\n        try (FileReader reader = new FileReader(nombreArchivo)) {\n            JSONObject jsonObject = (JSONObject) parser.parse(reader);\n\n            persona.nombre = (String) jsonObject.get(\"nombre\");\n            persona.edad = ((Long) jsonObject.get(\"edad\")).intValue();\n            persona.fechaNacimiento = (String) jsonObject.get(\"fechaNacimiento\");\n            persona.lenguajesProgramacion = (List<String>) jsonObject.get(\"lenguajesProgramacion\");\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n        return persona;\n    }\n}"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/java/julian98789.java",
    "content": "package org.example;\n\nimport com.fasterxml.jackson.annotation.JsonFormat;\nimport com.fasterxml.jackson.databind.ObjectMapper;\nimport com.fasterxml.jackson.dataformat.xml.XmlMapper;\nimport com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.time.LocalDate;\nimport java.time.format.DateTimeFormatter;\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class Main {\n    public static void main(String[] args) {\n        // Datos de prueba\n        List<String> lenguajesProgramacion = new ArrayList<>();\n        lenguajesProgramacion.add(\"C++\");\n        lenguajesProgramacion.add(\"Java\");\n        lenguajesProgramacion.add(\"JavaScript\");\n        lenguajesProgramacion.add(\"Python\");\n\n        Persona persona = new Persona(\"Julian\", 19, \"12/11/2000\", lenguajesProgramacion);\n\n\n        crearArchivoJSON(persona, \"persona.json\");\n        crearArchivoXML(persona, \"persona.xml\");\n\n        Persona personaDesdeJSON = leerArchivoJSON(\"persona.json\");\n        Persona personaDesdeXML = leerArchivoXML(\"persona.xml\");\n\n        System.out.println(\"Datos leídos desde JSON:\");\n        System.out.println(personaDesdeJSON);\n        System.out.println(\"Datos leídos desde XML:\");\n        System.out.println(personaDesdeXML);\n\n        borrarArchivo(\"persona.json\");\n        borrarArchivo(\"persona.xml\");\n    }\n\n    public static void crearArchivoJSON(Persona persona, String fileName) {\n        ObjectMapper objectMapper = new ObjectMapper();\n        objectMapper.registerModule(new JavaTimeModule());\n\n        try {\n            objectMapper.writeValue(new File(fileName), persona);\n            System.out.println(\"Archivo JSON creado exitosamente.\");\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n    }\n\n    public static void crearArchivoXML(Persona persona, String fileName) {\n        XmlMapper xmlMapper = new XmlMapper();\n        xmlMapper.registerModule(new JavaTimeModule());\n\n        try {\n            xmlMapper.writeValue(new File(fileName), persona);\n            System.out.println(\"Archivo XML creado exitosamente.\");\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n    }\n\n    public static Persona leerArchivoJSON(String fileName) {\n        ObjectMapper objectMapper = new ObjectMapper();\n        objectMapper.registerModule(new JavaTimeModule());\n\n        try {\n            return objectMapper.readValue(new File(fileName), Persona.class);\n        } catch (IOException e) {\n            e.printStackTrace();\n            return null;\n        }\n    }\n\n    public static Persona leerArchivoXML(String fileName) {\n        XmlMapper xmlMapper = new XmlMapper();\n        xmlMapper.registerModule(new JavaTimeModule());\n\n        try {\n            return xmlMapper.readValue(new File(fileName), Persona.class);\n        } catch (IOException e) {\n            e.printStackTrace();\n            return null;\n        }\n    }\n\n    public static void borrarArchivo(String fileName) {\n        File file = new File(fileName);\n        if (file.exists()) {\n            boolean deleted = file.delete();\n            if (deleted) {\n                System.out.println(\"Archivo \" + fileName + \" borrado exitosamente.\");\n            } else {\n                System.out.println(\"No se pudo borrar el archivo \" + fileName + \".\");\n            }\n        } else {\n            System.out.println(\"El archivo \" + fileName + \" no existe.\");\n        }\n    }\n\n    public static class Persona {\n        private String nombre;\n        private int edad;\n\n        @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = \"dd/MM/yyyy\")\n        private LocalDate fechaNacimiento;\n\n        private List<String> lenguajesProgramacion;\n\n        public Persona() {}\n\n        public Persona(String nombre, int edad, String fechaNacimiento, List<String> lenguajesProgramacion) {\n            this.nombre = nombre;\n            this.edad = edad;\n            DateTimeFormatter formatter = DateTimeFormatter.ofPattern(\"dd/MM/yyyy\");\n            this.fechaNacimiento = LocalDate.parse(fechaNacimiento, formatter);\n            this.lenguajesProgramacion = lenguajesProgramacion;\n        }\n\n        public String getNombre() {\n            return nombre;\n        }\n\n        public void setNombre(String nombre) {\n            this.nombre = nombre;\n        }\n\n        public int getEdad() {\n            return edad;\n        }\n\n        public void setEdad(int edad) {\n            this.edad = edad;\n        }\n\n        public LocalDate getFechaNacimiento() {\n            return fechaNacimiento;\n        }\n\n        public void setFechaNacimiento(LocalDate fechaNacimiento) {\n            this.fechaNacimiento = fechaNacimiento;\n        }\n\n        public List<String> getLenguajesProgramacion() {\n            return lenguajesProgramacion;\n        }\n\n        public void setLenguajesProgramacion(List<String> lenguajesProgramacion) {\n            this.lenguajesProgramacion = lenguajesProgramacion;\n        }\n\n        @Override\n        public String toString() {\n            return \"Persona{\" +\n                    \"nombre='\" + nombre + '\\'' +\n                    \", edad=\" + edad +\n                    \", fechaNacimiento=\" + fechaNacimiento +\n                    \", lenguajesProgramacion=\" + lenguajesProgramacion +\n                    '}';\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/java/lautarorisso.java",
    "content": "import java.io.IOException;\nimport java.nio.file.Path;\nimport java.util.List;\nimport java.nio.file.*;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\n\npublic class LogicaJava12 {\n\n    public static void main(String[] args) {\n\n        // XML\n        \n        String nombre = \"Lautaro\";\n        int edad = 21;\n        String fechaNacimiento = \"2004-11-11\";\n        List<String> lenguajes = List.of(\"Java\", \"Python\", \"Go\");\n\n        Path xmlPath = Path.of(\"persona.xml\");\n\n        String xml =\n                \"\"\"\n                <?xml version=\"1.0\" encoding=\"UTF-8\"?>\n                <data>\n                  <nombre>\"\"\" + nombre + \"</nombre>\\n\" +\n                \"  <edad>\" + edad + \"</edad>\\n\" +\n                \"  <fechaNacimiento>\" + fechaNacimiento + \"</fechaNacimiento>\\n\" +\n                \"  <lenguajes>\\n\";\n\n        for (String lang : lenguajes) {\n            xml += \"    <lenguaje>\" + lang + \"</lenguaje>\\n\";\n        }\n\n        xml +=\n                \"\"\"\n                  </lenguajes>\n                </data>\"\"\";\n\n        try {\n            Files.writeString(xmlPath, xml);\n        } catch (IOException ex) {\n            Logger.getLogger(LogicaJava12.class.getName()).log(Level.SEVERE, null, ex);\n        }\n        \n        System.out.println(\"=== XML ===\");\n        try {\n            Files.readAllLines(xmlPath).forEach(System.out::println);\n        } catch (IOException ex) {\n            Logger.getLogger(LogicaJava12.class.getName()).log(Level.SEVERE, null, ex);\n        }\n        \n        try {\n            Files.delete(xmlPath);\n        } catch (IOException ex) {\n            Logger.getLogger(LogicaJava12.class.getName()).log(Level.SEVERE, null, ex);\n        }\n        \n        // JSON\n                Path jsonPath = Path.of(\"persona.json\");\n\n        String json =\n                \"{\\n\" +\n                \"  \\\"nombre\\\": \\\"\" + nombre + \"\\\",\\n\" +\n                \"  \\\"edad\\\": \" + edad + \",\\n\" +\n                \"  \\\"fechaNacimiento\\\": \\\"\" + fechaNacimiento + \"\\\",\\n\" +\n                \"  \\\"lenguajes\\\": [\\n\";\n\n        for (int i = 0; i < lenguajes.size(); i++) {\n            json += \"    \\\"\" + lenguajes.get(i) + \"\\\"\";\n            if (i < lenguajes.size() - 1) json += \",\";\n            json += \"\\n\";\n        }\n\n        json +=\n                \"  ]\\n\" +\n                \"}\";\n\n        try {\n            Files.writeString(jsonPath, json);\n        } catch (IOException ex) {\n            Logger.getLogger(LogicaJava12.class.getName()).log(Level.SEVERE, null, ex);\n        }\n\n        System.out.println(\"\\n=== JSON ===\");\n        try {\n            Files.readAllLines(jsonPath).forEach(System.out::println);\n        } catch (IOException ex) {\n            Logger.getLogger(LogicaJava12.class.getName()).log(Level.SEVERE, null, ex);\n        }\n        \n        try {\n            Files.delete(jsonPath);\n        } catch (IOException ex) {\n            Logger.getLogger(LogicaJava12.class.getName()).log(Level.SEVERE, null, ex);\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/java/martinbohorquez.java",
    "content": "import com.fasterxml.jackson.core.type.TypeReference;\nimport com.fasterxml.jackson.databind.SerializationFeature;\nimport com.fasterxml.jackson.dataformat.xml.XmlMapper;\nimport com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;\nimport com.google.gson.Gson;\nimport com.google.gson.GsonBuilder;\nimport com.google.gson.TypeAdapter;\nimport com.google.gson.reflect.TypeToken;\nimport com.google.gson.stream.JsonReader;\nimport com.google.gson.stream.JsonWriter;\n\nimport java.io.File;\nimport java.io.FileNotFoundException;\nimport java.io.FileWriter;\nimport java.io.IOException;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.time.LocalDate;\nimport java.time.format.DateTimeFormatter;\nimport java.util.Arrays;\nimport java.util.HashSet;\nimport java.util.Scanner;\nimport java.util.Set;\n\n/**\n * #12 JSON Y XML\n * <dependencies>\n * <dependency>\n * <groupId>com.fasterxml.jackson.dataformat</groupId>\n * <artifactId>jackson-dataformat-xml</artifactId>\n * <version>2.17.2</version>\n * </dependency>\n * <dependency>\n * <groupId>com.fasterxml.jackson.datatype</groupId>\n * <artifactId>jackson-datatype-jsr310</artifactId>\n * <version>2.17.2</version>\n * </dependency>\n * <dependency>\n * <groupId>com.google.code.gson</groupId>\n * <artifactId>gson</artifactId>\n * <version>2.10.1</version>\n * </dependency>\n * </dependencies>\n *\n * @author martinbohorquez\n */\npublic class martinbohorquez {\n\n    private static final FileOperation operation = new FileOperation();\n\n    public static void main(String[] args) {\n        // Creación de objetos.\n        Programmer programmer = new Programmer();\n        programmer.setName(\"Martin B\");\n        programmer.setAge(29);\n        programmer.setBirthDate(LocalDate.of(1994, 9, 26));\n        programmer.setLanguages(new HashSet<>(Arrays.asList(\"Java\", \"Typescript\", \"Python\")));\n\n        // XML\n        String stringXml = \"data/martinDev.xml\";\n        File fileXml = operation.create(stringXml);\n        // Serialización\n        XMLManager<Programmer> xmlManager = new XMLManager<>(fileXml.toPath());\n        xmlManager.serialize(programmer);\n        // Deserialización\n        TypeReference<Programmer> typeReference = new TypeReference<>() {\n        };\n        Programmer programmerFromXml = xmlManager.deserialize(typeReference);\n        System.out.println(programmerFromXml);\n//        operation.delete(fileXml);\n\n        //JSON\n        String stringJson = \"data/martinDev.json\";\n        File fileJson = operation.create(stringJson);\n        // Serialización\n        JSONManager<Programmer> jsonManage = new JSONManager<>(fileJson.toPath());\n        jsonManage.serialize(programmer);\n        // Deserialización\n        Programmer programmerFromJson = jsonManage.deserialize(TypeToken.get(Programmer.class));\n        System.out.println(programmerFromJson);\n//        operation.delete(fileJson);\n    }\n\n    private static class FileOperation {\n\n        private static void printFileEmpty() {\n            System.out.println(\"El archivo se encuentra vacío, no tiene registros!\");\n        }\n\n        private static void printfException(IOException e, String process) {\n            System.out.printf(\"Error al '%s' en el archivo: '%s'%n\", process, e.getMessage());\n        }\n\n        private File create(String string) {\n            File file = new File(string);\n            if (file.getParentFile() != null) file.getParentFile().mkdirs();// Crear la carpeta si no existe\n            return file;\n        }\n\n        private void write(File file, String string) {\n            try (FileWriter writer = new FileWriter(file, true); Scanner reader = new Scanner(file)) {\n                writer.append(string).append(System.lineSeparator());\n                if (!reader.hasNext()) System.out.printf(\"Archivo '%s' creado!%n\", file);\n                else System.out.printf(\"Archivo '%s' modificado!%n\", file);\n            } catch (IOException e) {\n                printfException(e, \"escribir\");\n            }\n        }\n\n        private void read(File file) {\n            if (file == null || file.length() == 0) printFileEmpty();\n            else {\n                try (Scanner reader = new Scanner(file)) {\n                    System.out.println(\"Contenido del archivo: \");\n                    while (reader.hasNext()) System.out.println(reader.nextLine());\n                } catch (FileNotFoundException e) {\n                    printfException(e, \"leer\");\n                }\n            }\n        }\n\n        private void delete(File file) {\n            if (file != null && file.delete()) {\n                if (file.getParentFile() != null && file.getParentFile().delete())\n                    System.out.printf(\"Folder '\\\\%s' eliminado correctamente!%n\", file.getParentFile().toString());\n                System.out.printf(\"Archivo '%s' eliminado correctamente!%n\", file);\n            }\n        }\n    }\n\n    private static class Programmer {\n        private String name;\n        private Integer age;\n        private LocalDate birthDate;\n        private Set<String> languages;\n\n        public String getName() {\n            return name;\n        }\n\n        public void setName(String name) {\n            this.name = name;\n        }\n\n        public Integer getAge() {\n            return age;\n        }\n\n        public void setAge(Integer age) {\n            this.age = age;\n        }\n\n        public LocalDate getBirthDate() {\n            return birthDate;\n        }\n\n        public void setBirthDate(LocalDate birthDate) {\n            this.birthDate = birthDate;\n        }\n\n        public Set<String> getLanguages() {\n            return languages;\n        }\n\n        public void setLanguages(Set<String> languages) {\n            this.languages = languages;\n        }\n\n        @Override\n        public String toString() {\n            return \"Programmer : [name=\" + name + \", age=\" + age + \", birthDate=\" + birthDate + \", languages=\" + languages\n                    + \"]\";\n        }\n    }\n\n    private static class XMLManager<T> {\n        private XmlMapper xmlMapper;\n        private Path path;\n\n        public XMLManager(Path path) {\n            this.path = path;\n            this.xmlMapper = XmlMapper.builder()\n                    .enable(SerializationFeature.INDENT_OUTPUT)\n                    .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)\n                    .build();\n            xmlMapper.registerModule(new JavaTimeModule());\n        }\n\n        public void serialize(T object) {\n            try {\n                this.xmlMapper.writeValue(this.path.toFile(), object);\n            } catch (Exception e) {\n                e.printStackTrace(System.out);\n            }\n        }\n\n        public T deserialize(TypeReference<T> typeReference) {\n            try {\n                T objectDeserialize = this.xmlMapper.readValue(this.path.toFile(), typeReference);\n                return objectDeserialize;\n            } catch (Exception e) {\n                e.printStackTrace(System.out);\n            }\n            return null;\n        }\n    }\n\n    private static class JSONManager<T> {\n        private Path path;\n        private Gson gson;\n\n        public JSONManager(Path path) {\n            this.path = path;\n            this.gson = new GsonBuilder()\n                    .setPrettyPrinting() // This enables pretty printing\n                    .registerTypeAdapter(LocalDate.class, new LocalDateTypeAdapter())\n                    .create();\n        }\n\n        public void serialize(T object) {\n            try {\n                String jsonString = gson.toJson(object);\n                Files.writeString(path, jsonString);\n            } catch (IOException e) {\n                e.printStackTrace(System.out);\n            }\n        }\n\n        public T deserialize(TypeToken<T> typeToken) {\n            try {\n                byte[] data = Files.readAllBytes(path);\n                T object = gson.fromJson(new String(data), typeToken.getType());\n                return object;\n            } catch (IOException e) {\n                e.printStackTrace();\n            }\n            return null;\n        }\n    }\n\n    // Type Adapter for LocalDate\n    private static class LocalDateTypeAdapter extends TypeAdapter<LocalDate> {\n        private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ISO_LOCAL_DATE;\n\n        @Override\n        public LocalDate read(JsonReader jsonReader) throws IOException {\n            if (jsonReader.peek() == com.google.gson.stream.JsonToken.NULL) {\n                jsonReader.nextNull();\n                return null;\n            } else {\n                return LocalDate.parse(jsonReader.nextString(), FORMATTER);\n            }\n        }\n\n        @Override\n        public void write(JsonWriter jsonWriter, LocalDate localDate) throws IOException {\n            if (localDate == null) {\n                jsonWriter.nullValue();\n            } else {\n                jsonWriter.value(localDate.format(FORMATTER));\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/java/simonguzman.java",
    "content": "import java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Properties;\nimport javax.xml.parsers.DocumentBuilder;\nimport javax.xml.parsers.DocumentBuilderFactory;\nimport javax.xml.transform.OutputKeys;\nimport javax.xml.transform.Transformer;\nimport javax.xml.transform.TransformerFactory;\nimport javax.xml.transform.dom.DOMSource;\nimport javax.xml.transform.stream.StreamResult;\nimport org.w3c.dom.Document;\nimport org.w3c.dom.Element;\nimport org.w3c.dom.Node;\nimport org.w3c.dom.NodeList;\n\npublic class simonguzman {\n\n    public static void main(String[] args) {\n        createXMLFile();\n        readXMLFile();\n        deleteXMLFile();\n        createPropertiesFile();\n        readPropertiesFile();\n        deletePropertiesFile();\n\n        //Ejercicio adicional\n        createXMLFileExtra();\n        createPropertiesFileExtra();\n\n        Persona personaDesdeXML = readXMLFileExtra();\n        Persona personaDesdeProperties = readPropertiesFileExtra();\n\n        System.out.println(\"Datos: leidos desde XML\");\n        personaDesdeXML.mostrarInformacion();\n        System.out.println(\"\\nDatos leídos desde JSON simulado (properties):\");\n        personaDesdeProperties.mostrarInformacion();\n\n        deleteXMLFileExtra();\n        deletePropertiesFileExtra();\n    }\n\n    static void createXMLFile(){\n        try {\n            DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();\n            DocumentBuilder docBuilder = docFactory.newDocumentBuilder();\n            \n            //Raiz\n            Document doc = docBuilder.newDocument();\n            Element rootElement = doc.createElement(\"Persona\");\n            doc.appendChild(rootElement);\n\n            //Nombre\n            Element name = doc.createElement(\"Nombre\");\n            name.appendChild(doc.createTextNode(\"Simon\"));\n            rootElement.appendChild(name);\n\n            //Edad\n            Element age = doc.createElement(\"Edad\");\n            age.appendChild(doc.createTextNode(\"22\"));\n            rootElement.appendChild(age);\n\n            //Fecha de nacimiento\n            Element dateBirth = doc.createElement(\"Fecha_de_nacimiento\");\n            dateBirth.appendChild(doc.createTextNode(\"2001-11-28\"));\n            rootElement.appendChild(dateBirth);\n\n            //Listado de lenguajes\n            Element languajes = doc.createElement(\"Lenguajes\");\n            Element languaje1 = doc.createElement(\"Lenguaje\");\n            languaje1.appendChild(doc.createTextNode(\"Java\"));\n            languajes.appendChild(languaje1);\n            Element languaje2 = doc.createElement(\"Lenguaje\");\n            languaje2.appendChild(doc.createTextNode(\"Python\"));\n            languajes.appendChild(languaje2);\n            rootElement.appendChild(languajes);\n\n            TransformerFactory transformerFactory = TransformerFactory.newInstance();\n            Transformer transformer = transformerFactory.newTransformer();\n            transformer.setOutputProperty(OutputKeys.INDENT, \"yes\");\n            transformer.setOutputProperty(\"{http://xml.apache.org/xslt}indent-amount\", \"4\");\n            DOMSource source = new DOMSource(doc);\n            StreamResult result = new  StreamResult(new File(\"datos.xml\"));\n            transformer.transform(source, result);\n\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n        \n    }\n\n    static void readXMLFile(){\n        try {\n            File inputFile = new File(\"datos.xml\");\n            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();\n            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();\n            Document doc = dBuilder.parse(inputFile);\n            doc.getDocumentElement().normalize();\n\n            //Leer nombre\n            NodeList nList = doc.getElementsByTagName(\"Persona\");\n            Node nNode = nList.item(0);\n            Element eElement = (Element) nNode;\n\n            System.out.println(\"Nombre: \" + eElement.getElementsByTagName(\"Nombre\").item(0).getTextContent());\n            System.out.println(\"Edad: \" + eElement.getElementsByTagName(\"Edad\").item(0).getTextContent());\n            System.out.println(\"Fecha de nacimiento: \" + eElement.getElementsByTagName(\"Fecha_de_nacimiento\").item(0).getTextContent());\n\n            NodeList languajes = eElement.getElementsByTagName(\"Lenguaje\");\n            for (int temp = 0; temp < languajes.getLength(); temp++) {\n                System.out.println(\"Lenguaje: \"+languajes.item(temp).getTextContent());\n            }\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n    }\n\n    static void deleteXMLFile(){\n        File file = new File(\"datos.xml\");\n        if(file.delete()){\n            System.out.println(\"Archivo XML borrado correctamente.\");\n        }else{\n            System.out.println(\"ERROR: No se pudo borrar el archivo XML.\");\n        }\n    }\n\n    static void createPropertiesFile(){\n        Properties properties = new Properties();\n\n        properties.setProperty(\"nombre\", \"Simon\");\n        properties.setProperty(\"edad\", \"22\");\n        properties.setProperty(\"fecha_de_nacimiento\", \"2001-11-28\");\n\n        properties.setProperty(\"lenguajes\", \"Java,Python\");\n\n        try (FileOutputStream output = new FileOutputStream(\"datos.properties\")){\n            properties.store(output, \"Datos del usuario en formato JSON simulado\");\n            System.out.println(\"Archivo 'datos.properties' creado\");\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n    }\n\n    static void readPropertiesFile(){\n        Properties properties = new Properties();\n        try (FileInputStream input = new FileInputStream(\"datos.properties\")){\n            properties.load(input);\n\n            System.out.println(\"Nombre: \" + properties.getProperty(\"nombre\"));\n            System.out.println(\"Edad: \" + properties.getProperty(\"edad\"));\n            System.out.println(\"Fecha de nacimiento: \" + properties.getProperty(\"fecha_de_nacimiento\"));\n\n            String[] lenguajes = properties.getProperty(\"lenguajes\").split(\",\");\n            System.out.println(\"Lenguajes:\");\n            for (String lenguaje : lenguajes) {\n                System.out.println(\"- \" + lenguaje);\n            }\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n    }\n\n    static void deletePropertiesFile(){\n        File file = new File(\"datos.properties\");\n        if(file.delete()){\n            System.out.println(\"Archivo JSON simulado fue eliminado.\");\n        }else{\n            System.out.println(\"ERROR: No se pudo eliminar el archivo.\");\n        }\n\n    }\n\n    static class Persona{\n        private String nombre;\n        private int edad;\n        private String fechaDeNacimiento;\n        private List<String> lenguajes;\n\n        // Constructor\n        public Persona(String nombre, int edad, String fechaDeNacimiento, List<String> lenguajes) {\n            this.nombre = nombre;\n            this.edad = edad;\n            this.fechaDeNacimiento = fechaDeNacimiento;\n            this.lenguajes = lenguajes;\n        }\n\n        // Getters\n        public String getNombre() {\n            return nombre;\n        }\n\n        public int getEdad() {\n            return edad;\n        }\n\n        public String getFechaDeNacimiento() {\n            return fechaDeNacimiento;\n        }\n\n        public List<String> getLenguajes() {\n            return lenguajes;\n        }\n\n        // Método para mostrar los datos\n        public void mostrarInformacion() {\n            System.out.println(\"Nombre: \" + nombre);\n            System.out.println(\"Edad: \" + edad);\n            System.out.println(\"Fecha de nacimiento: \" + fechaDeNacimiento);\n            System.out.println(\"Lenguajes: \");\n            for (String lenguaje : lenguajes) {\n                System.out.println(\"- \" + lenguaje);\n            }\n        }\n    }\n\n    static void createXMLFileExtra(){\n        try {\n            DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();\n            DocumentBuilder docBuilder = docFactory.newDocumentBuilder();\n            \n            //Raiz\n            Document doc = docBuilder.newDocument();\n            Element rootElement = doc.createElement(\"Persona\");\n            doc.appendChild(rootElement);\n\n            //Nombre\n            Element name = doc.createElement(\"Nombre\");\n            name.appendChild(doc.createTextNode(\"Simon\"));\n            rootElement.appendChild(name);\n\n            //Edad\n            Element age = doc.createElement(\"Edad\");\n            age.appendChild(doc.createTextNode(\"22\"));\n            rootElement.appendChild(age);\n\n            //Fecha de nacimiento\n            Element dateBirth = doc.createElement(\"Fecha_de_nacimiento\");\n            dateBirth.appendChild(doc.createTextNode(\"2001-11-28\"));\n            rootElement.appendChild(dateBirth);\n\n            //Listado de lenguajes\n            Element languajes = doc.createElement(\"Lenguajes\");\n            Element languaje1 = doc.createElement(\"Lenguaje\");\n            languaje1.appendChild(doc.createTextNode(\"Java\"));\n            languajes.appendChild(languaje1);\n            Element languaje2 = doc.createElement(\"Lenguaje\");\n            languaje2.appendChild(doc.createTextNode(\"Python\"));\n            languajes.appendChild(languaje2);\n            rootElement.appendChild(languajes);\n\n            TransformerFactory transformerFactory = TransformerFactory.newInstance();\n            Transformer transformer = transformerFactory.newTransformer();\n            transformer.setOutputProperty(OutputKeys.INDENT, \"yes\");\n            transformer.setOutputProperty(\"{http://xml.apache.org/xslt}indent-amount\", \"4\");\n            DOMSource source = new DOMSource(doc);\n            StreamResult result = new  StreamResult(new File(\"datos.xml\"));\n            transformer.transform(source, result);\n\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n        \n    }\n\n    static Persona readXMLFileExtra(){\n        try {\n            File inputFile = new File(\"datos.xml\");\n            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();\n            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();\n            Document doc = dBuilder.parse(inputFile);\n            doc.getDocumentElement().normalize();\n\n            //Leer nombre\n            NodeList nList = doc.getElementsByTagName(\"Persona\");\n            Node nNode = nList.item(0);\n            Element eElement = (Element) nNode;\n\n            String nombre = eElement.getElementsByTagName(\"Nombre\").item(0).getTextContent();\n            int edad = Integer.parseInt(eElement.getElementsByTagName(\"Edad\").item(0).getTextContent());\n            String fechaDeNacimiento = eElement.getElementsByTagName(\"Fecha_de_nacimiento\").item(0).getTextContent();\n\n            NodeList lenguajesNodeList = eElement.getElementsByTagName(\"Lenguaje\");\n            List<String> lenguajes = new ArrayList<>();\n            for (int temp = 0; temp < lenguajesNodeList.getLength(); temp++) {\n                lenguajes.add(lenguajesNodeList.item(temp).getTextContent());\n            }\n\n            return new Persona(nombre, edad, fechaDeNacimiento, lenguajes);\n        } catch (Exception e) {\n            e.printStackTrace();\n            return null;\n        }\n    }\n\n    static void deleteXMLFileExtra(){\n        File file = new File(\"datos.xml\");\n        if(file.delete()){\n            System.out.println(\"Archivo XML borrado correctamente.\");\n        }else{\n            System.out.println(\"ERROR: No se pudo borrar el archivo XML.\");\n        }\n    }\n\n    static void createPropertiesFileExtra(){\n        Properties properties = new Properties();\n\n        properties.setProperty(\"nombre\", \"Simon\");\n        properties.setProperty(\"edad\", \"22\");\n        properties.setProperty(\"fecha_de_nacimiento\", \"2001-11-28\");\n\n        properties.setProperty(\"lenguajes\", \"Java,Python\");\n\n        try (FileOutputStream output = new FileOutputStream(\"datos.properties\")){\n            properties.store(output, \"Datos del usuario en formato JSON simulado\");\n            System.out.println(\"Archivo 'datos.properties' creado\");\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n    }\n\n    static Persona readPropertiesFileExtra(){\n        Properties properties = new Properties();\n        try (FileInputStream input = new FileInputStream(\"datos.properties\")){\n            properties.load(input);\n\n            String nombre = properties.getProperty(\"nombre\");\n            int edad = Integer.parseInt(properties.getProperty(\"edad\"));\n            String fechaDeNacimiento = properties.getProperty(\"fecha_de_nacimiento\");\n\n            String[] lenguajesArray = properties.getProperty(\"lenguajes\").split(\",\");\n            List<String> lenguajes = new ArrayList<>();\n            for (String lenguaje : lenguajesArray) {\n                lenguajes.add(lenguaje);\n            }\n\n            return new Persona(nombre, edad, fechaDeNacimiento, lenguajes);\n        } catch (IOException e) {\n            e.printStackTrace();\n            return null;\n        }\n    }\n\n    static void deletePropertiesFileExtra(){\n        File file = new File(\"datos.properties\");\n        if(file.delete()){\n            System.out.println(\"Archivo JSON simulado fue eliminado.\");\n        }else{\n            System.out.println(\"ERROR: No se pudo eliminar el archivo.\");\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/javascript/7R0N1X.js",
    "content": "const fs = require('fs');\nconst xml2js = require('xml2js');\n\nconst datos = {\n  nombre: 'Eduardo Molina',\n  edad: 25,\n  fechaNacimiento: '30-08-1999',\n  lenguajes: ['JavaScript', 'Python', 'Java']\n};\n\nconst crearJSON = () => {\n  fs.writeFileSync('datos.json', JSON.stringify(datos, null, 2), 'utf-8');\n  console.log('Archivo JSON creado:\\n', fs.readFileSync('datos.json', 'utf-8'));\n};\n\nconst crearXML = () => {\n  const builder = new xml2js.Builder({ headless: true, rootName: 'persona' });\n  const xml = builder.buildObject({\n    nombre: datos.nombre,\n    edad: datos.edad,\n    fechaNacimiento: datos.fechaNacimiento,\n    lenguajes: { lenguaje: datos.lenguajes }\n  });\n  fs.writeFileSync('datos.xml', xml, 'utf-8');\n  console.log('Archivo XML creado:\\n', fs.readFileSync('datos.xml', 'utf-8'));\n};\n\n\nclass Persona {\n\n  constructor(nombre, edad, fechaNacimiento, lenguajes) {\n    this.nombre = nombre;\n    this.edad = edad;\n    this.fechaNacimiento = fechaNacimiento;\n    this.lenguajes = lenguajes;\n  }\n\n  mostrarDatos() {\n    console.log(`Nombre: ${this.nombre}`);\n    console.log(`Edad: ${this.edad}`);\n    console.log(`Fecha de Nacimiento: ${this.fechaNacimiento}`);\n    console.log(`Lenguajes: ${this.lenguajes.join(', ')}`);\n  }\n}\n\nconst leerYTransformarJSON = () => {\n  const dataJSON = fs.readFileSync('datos.json', 'utf-8');\n  const datosJSON = JSON.parse(dataJSON);\n  const personaJSON = new Persona(\n    datosJSON.nombre,\n    datosJSON.edad,\n    datosJSON.fechaNacimiento,\n    datosJSON.lenguajes\n  );\n  console.log('\\nDatos leídos del archivo JSON:');\n  personaJSON.mostrarDatos();\n};\n\nconst leerYTransformarXML = () => {\n  const dataXML = fs.readFileSync('datos.xml', 'utf-8');\n  xml2js.parseString(dataXML, (err, result) => {\n    if (err) throw err;\n    const datosXML = result.persona;\n    const personaXML = new Persona(\n      datosXML.nombre[0],\n      datosXML.edad[0],\n      datosXML.fechaNacimiento[0],\n      datosXML.lenguajes[0].lenguaje\n    );\n    console.log('\\nDatos leídos del archivo XML:');\n    personaXML.mostrarDatos();\n  });\n};\n\nconst borrarArchivos = () => {\n  fs.unlinkSync('datos.json');\n  fs.unlinkSync('datos.xml');\n  console.log('\\nArchivos borrados.');\n};\n\ncrearJSON();\ncrearXML();\nleerYTransformarJSON();\nleerYTransformarXML();\nborrarArchivos();"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/javascript/AChapeton.js",
    "content": "var fs = require('fs');\nvar readlineSync = require('readline-sync');\nvar _a = require('xmldom'), ImplementationDOM = _a.DOMImplementation, SerializeXML = _a.XMLSerializer;\nvar jsonContent = {\n    nombre: 'Andres Chapeton',\n    edad: 26,\n    fecha_de_nacimiento: '02/06/1997',\n    lista_lenguajes: ['TypeScript', 'JavaScript', 'Python', 'C#']\n};\nfs.writeFile('data.json', JSON.stringify(jsonContent), function (error) {\n    if (error)\n        throw error;\n    console.log('JSON file created');\n});\n//Leer contenido del fichero JSON\nfs.readFile('data.json', function (error, data) {\n    if (error)\n        throw error;\n    console.log(data.toString());\n});\n//Eliminar fichero JSON\nfs.unlink('data.json', function (error) {\n    if (error)\n        throw error;\n    console.log('JSON file deleted');\n});\n// PARA CREAR ARCHIVO XML\n// Crear un objeto DOMImplementation\nvar domImplementation = new ImplementationDOM();\n//Crear un objeto XML Document\nvar xmlBaseDoc = domImplementation.createDocument(null, 'root');\n//Crear elementos y atributos\nvar main = xmlBaseDoc.createElement('main');\nvar full_name = xmlBaseDoc.createAttribute('full_name');\nvar age = xmlBaseDoc.createAttribute('age');\nvar birth = xmlBaseDoc.createAttribute('birth');\nvar list = xmlBaseDoc.createAttribute('list');\n//Agregar valures\nfull_name.value = 'Andres Chapeton';\nage.value = '26';\nbirth.value = '02/06/1997';\nlist.value = 'TypeScript, JavaScript, Python, C#';\n//Agregar elementos al documento\nmain.setAttributeNode(full_name);\nmain.setAttributeNode(age);\nmain.setAttributeNode(birth);\nmain.setAttributeNode(list);\nmain.textContent = 'Datos';\nxmlBaseDoc.documentElement.appendChild(main);\n//Convertir documento XML en cadena de texto\nvar xmlString = new SerializeXML().serializeToString(xmlBaseDoc);\n//Crear fichero XML\nfs.writeFile('data.xml', xmlString, function (error) {\n    if (error)\n        throw error;\n    console.log('XML file created');\n});\n//Leer contenido del fichero XML\nfs.readFile('data.xml', function (error, data) {\n    if (error)\n        throw error;\n    var xmlString = data.toString();\n    console.log(xmlString);\n});\n//Eliminar fichero XML\nfs.unlink('data.xml', function (error) {\n    if (error)\n        throw error;\n    console.log('JSON file deleted');\n});\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/javascript/Airesesteban.js",
    "content": "/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu\n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n */\n\n// EJERCICIO\n\nconst fs = require('fs')\n\n\n\nconst datos = {\n    nombre: \"Esteban\",\n    edad: 30,\n    fechaNacimiento: \"01/05/1987\",\n    lenguajes: [\"Javascript\", \"Python\", \"Java\"]\n}\n\n//JSON\nfunction crearArchivoJSON(){\n    const jsonContent = JSON.stringify(datos, null, 2)\n    fs.writeFile(\"datos.json\", jsonContent, (error) => {\n        if(error){\n            console.error(\"Error al cerar el archivo JSON:\", error)\n            return\n        }\n        console.log(\"Archivo JSON creado con exito\")\n        leerArchivoJson()\n    })\n}\nfunction leerArchivoJson(){\n    fs.readFile(\"datos.json\", \"utf8\", (error, data)=> {\n        if(error){\n            console.error(\"Error al cerar el archivo JSON:\", error)\n            return\n        }\n        console.log(\"Data:\")\n        console.log(data)\n    })\n\n}\nfunction borrarJSON(){\n    fs.unlink(\"datos,json\", (error) => {\n        if (error && error.code !== 'ENOENT') {\n            console.error(\"Error al borrar el archivo JSON:\", error);\n        } else {\n            console.log(\"Archivo JSON borrado con éxito\");\n        }\n    })\n}\n\n\n//XML\n\nfunction crearArchivoXML(){\n    const xmlContent = `\n<datos>\n    <nombre>${datos.nombre}</nombre>\n    <edad>${datos.edad}</edad>\n    <fechaNacimiento>${datos.fechaNacimiento}</fechaNacimiento>\n    <lenguajes>\n        ${datos.lenguajes.map(lenguaje => `        <lenguaje>${lenguaje}</lenguaje>`).join(\"\\n\")}\n    </lenguajes>\n</datos>`\n    fs.writeFile(\"datos.xml\", xmlContent, (error) => {\n       if (error) {\n            console.error(\"Error al crear el archivo XML:\", error)\n            return\n        } \n        console.log(\"Archivo XML creado con éxito\")\n        leerArchivoXML()\n    })\n}\nfunction leerArchivoXML(){\n    fs.readFile(\"datos.xml\", \"utf8\", (error,data)=> {\n        if (error) {\n            console.error(\"Error al crear el archivo XML:\", error)\n            return\n        } \n        console.log(\"Datos: \")\n        console.log(data)\n    })\n}\nfunction borrarXML(){\n    fs.unlink(\"datos.xml\", (error)=> {\n        if (error && error.code !== 'ENOENT') {\n            console.error(\"✖️ Error al borrar el archivo XML:\", error)\n        } else {\n            console.log(\"Archivo XML borrado con éxito\")\n        }\n    })\n}\n\ncrearArchivoJSON()\ncrearArchivoXML()\nborrarJSON()\nborrarXML()\n\n// EXTRA\n\nconst xml2js = require('xml2js')\n\nclass Persona {\n    constructor(nombre, edad, fechaNacimiento, lenguajes) {\n        this.nombre = nombre\n        this.edad = edad\n        this.fechaNacimiento = fechaNacimiento\n        this.lenguajes = lenguajes\n    }\n\n    mostrarDatos() {\n        console.log(\"Datos de la persona:\")\n        console.log(`Nombre: ${this.nombre}`)\n        console.log(`Edad: ${this.edad}`)\n        console.log(`Fecha de nacimiento: ${this.fechaNacimiento}`)\n        console.log(`Lenguajes: ${this.lenguajes.join(\", \")}`)\n    }\n}\n\nfunction crearArchivos() {\n    const datos = {\n        nombre: \"Tu Nombre\",\n        edad: 25,\n        fechaNacimiento: \"01/01/1998\",\n        lenguajes: [\"JavaScript\", \"Python\", \"Java\"]\n    };\n\n    fs.writeFile(\"datos.json\", JSON.stringify(datos, null, 2), (err) => {\n        if (err) {\n            console.error(\"Error al crear el archivo JSON:\", err);\n            return;\n        }\n        console.log(\"Archivo JSON creado con éxito.\");\n    });\n\n    const xmlContent = `\n<datos>\n    <nombre>${datos.nombre}</nombre>\n    <edad>${datos.edad}</edad>\n    <fechaNacimiento>${datos.fechaNacimiento}</fechaNacimiento>\n    <lenguajes>\n        ${datos.lenguajes.map(lenguaje => `        <lenguaje>${lenguaje}</lenguaje>`).join(\"\\n\")}\n    </lenguajes>\n</datos>`;\n    fs.writeFile(\"datos.xml\", xmlContent, (err) => {\n        if (err) {\n            console.error(\"Error al crear el archivo XML:\", err);\n            return;\n        }\n        console.log(\"Archivo XML creado con éxito.\");\n        leerArchivos();\n    });\n}\n\nfunction leerArchivos() {\n    fs.readFile(\"datos.json\", 'utf8', (err, jsonData) => {\n        if (err) {\n            console.error(\"Error al leer el archivo JSON:\", err);\n            return;\n        }\n\n        const datosJSON = JSON.parse(jsonData);\n\n        fs.readFile(\"datos.xml\", 'utf8', (err, xmlData) => {\n            if (err) {\n                console.error(\"Error al leer el archivo XML:\", err);\n                return;\n            }\n\n            const parser = new xml2js.Parser({ explicitArray: false });\n            parser.parseString(xmlData, (err, result) => {\n                if (err) {\n                    console.error(\"Error al parsear el archivo XML:\", err);\n                    return;\n                }\n\n                const datosXML = {\n                    nombre: result.datos.nombre,\n                    edad: parseInt(result.datos.edad),\n                    fechaNacimiento: result.datos.fechaNacimiento,\n                    lenguajes: Array.isArray(result.datos.lenguajes.lenguaje)\n                        ? result.datos.lenguajes.lenguaje\n                        : [result.datos.lenguajes.lenguaje]\n                };\n\n                console.log(\"\\nDatos del archivo JSON:\");\n                const personaJSON = new Persona(\n                    datosJSON.nombre,\n                    datosJSON.edad,\n                    datosJSON.fechaNacimiento,\n                    datosJSON.lenguajes\n                );\n                personaJSON.mostrarDatos();\n\n                console.log(\"\\nDatos del archivo XML:\");\n                const personaXML = new Persona(\n                    datosXML.nombre,\n                    datosXML.edad,\n                    datosXML.fechaNacimiento,\n                    datosXML.lenguajes\n                );\n                personaXML.mostrarDatos();\n\n                borrarArchivos();\n            });\n        });\n    });\n}\n\nfunction borrarArchivos() {\n    fs.unlink(\"datos.json\", (err) => {\n        if (err && err.code !== 'ENOENT') {\n            console.error(\"Error al borrar el archivo JSON:\", err);\n        } else {\n            console.log(\"Archivo JSON borrado con éxito.\");\n        }\n    });\n\n    fs.unlink(\"datos.xml\", (err) => {\n        if (err && err.code !== 'ENOENT') {\n            console.error(\"Error al borrar el archivo XML:\", err);\n        } else {\n            console.log(\"Archivo XML borrado con éxito.\");\n        }\n    });\n}\n\ncrearArchivos();\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/javascript/Dan-Corbo.js",
    "content": "/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n * \n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu \n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n */\n\n\n/* Solucion */\n\n// Importamos el módulo 'fs' para manejar archivos en Node.js\nconst fs = require('fs');\n\n// Función para crear un perfil con los datos proporcionados\nfunction crearPerfil(nombre, edad, nacimiento, lenguajes) {\n  // Definición de la clase Perfil\n  class Perfil {\n    constructor(nombre, edad, nacimiento, lenguajes) {\n        this.nombre = nombre;\n        this.edad = edad;\n        this.nacimiento = nacimiento;\n        this.lenguajes = lenguajes;\n    }\n  }\n  \n  // Creamos y retornamos una nueva instancia de Perfil con los datos proporcionados\n  return new Perfil(nombre, edad, nacimiento, lenguajes);\n}\n\n// Función para mostrar la información del perfil\nfunction mostrarPerfil(variable) {\n  // Formateamos los lenguajes en una cadena legible\n  let elemento = \"\";\n  if (variable.lenguajes.length === 1) {\n    elemento = variable.lenguajes[0];\n  } else if (variable.lenguajes.length === 2) {\n    elemento = `${variable.lenguajes[0]} y ${variable.lenguajes[1]}`;\n  } else {\n    for (let i = 0; i < variable.lenguajes.length - 1; i++) {\n      elemento += `${variable.lenguajes[i]}, `;\n    }\n    elemento += `y ${variable.lenguajes[variable.lenguajes.length - 1]}`;\n  }\n\n  // Construimos y retornamos la información del perfil formateada\n  let mostrar = `\n  Mi nombre es ${variable.nombre}, tengo ${variable.edad} años, \n  nací el ${variable.nacimiento} y los lenguajes que conozco \n  son ${elemento}.`;\n  \n  return mostrar;\n}\n\n// Función para convertir un objeto Perfil a formato XML\nfunction convertirAXml(objeto) {\n  let xml = '<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n';\n  xml += '<persona>\\n';\n  xml += '\\t<nombre>' + objeto.nombre + '</nombre>\\n';\n  xml += '\\t<edad>' + objeto.edad + '</edad>\\n';\n  xml += '\\t<nacimiento>' + objeto.nacimiento + '</nacimiento>\\n';\n  xml += '\\t<lenguajes>\\n';\n  // Iteramos sobre los lenguajes para añadirlos al XML\n  objeto.lenguajes.forEach(lenguaje => {\n    xml += `\\t\\t<lenguaje>${lenguaje}</lenguaje>\\n`;\n  });\n  xml += '\\t</lenguajes>\\n';\n  xml += '</persona>';\n  return xml;\n}\n\n// Creamos un perfil de ejemplo\nlet perfil = crearPerfil(\"Daniel\", 24, \"23/10/1999\", [\"Javascript\", \"Python\", \"Java\", \"C++\", \"Kotlin\"]);\n\n// Convertir el objeto a XML e Imprimirlo\nconst xmlData = convertirAXml(perfil);\nconsole.log(`Archivo XML: \\n${xmlData}\\n`);\n\n// Guardar archivo XML\nfs.writeFile('perfil.xml', xmlData, (err) => {\n  if (err) throw err;\n  console.log('Archivo XML guardado correctamente.');\n});\n\n// Convertir el objeto a JSON e Imprimirlo\nconst jsonData = JSON.stringify(perfil);\nconsole.log(`Archivo JSON: \\n${jsonData}\\n`);\nfs.writeFile('perfil.json', jsonData, (err) => {\n  if (err) throw err;\n  console.log('Archivo JSON guardado correctamente.');\n});\n\n// Mostrar la información del perfil\nconsole.log(`Perfil:${mostrarPerfil(perfil)}\\n`);\n\n\n// Borrar los archivos\nfs.unlink('perfil.xml', (err) => {\n  if (err) throw err;\n  console.log('Archivo XML eliminado correctamente.');\n});\n\nfs.unlink('perfil.json', (err) => {\n  if (err) throw err;\n  console.log('Archivo JSON eliminado correctamente.');\n});\n\n\n/* Extra - Opcional */\n\n//Requiere Node.Js para funcionar\n\n// Definir la clase custom\n/*class Perfil {\n  constructor(nombre, edad, nacimiento, lenguajes) {\n    this.nombre = nombre;\n    this.edad = edad;\n    this.nacimiento = nacimiento;\n    this.lenguajes = lenguajes;\n  }\n\n  // Método para mostrar la información del perfil\n  mostrarPerfil() {\n    let elemento = \"\";\n    // Formatear los lenguajes en una cadena legible\n    if (this.lenguajes.length === 1) {\n      elemento = this.lenguajes[0];\n    } else if (this.lenguajes.length === 2) {\n      elemento = `${this.lenguajes[0]} y ${this.lenguajes[1]}`;\n    } else {\n      for (let i = 0; i < this.lenguajes.length - 1; i++) {\n        elemento += `${this.lenguajes[i]}, `;\n      }\n      elemento += `y ${this.lenguajes[this.lenguajes.length - 1]}`;\n    }\n\n    // Construir y retornar la información del perfil formateada\n    let mostrar = `\n    Mi nombre es ${this.nombre}, tengo ${this.edad} años, \n    nací el ${this.nacimiento} y los lenguajes que conozco \n    son ${elemento}.`;\n    \n    return mostrar;\n  }\n}\n\n// Función para leer el archivo XML y transformarlo en un objeto Perfil\nfunction leerXml(filePath) {\n  // Leer el contenido del archivo XML\n  const data = fs.readFileSync(filePath, 'utf-8');\n\n  // Analizar el XML utilizando el módulo xml2js\n  const parseString = require('xml2js').parseString;\n  let parsedData;\n  parseString(data, (err, result) => {\n    if (err) throw err;\n    parsedData = result.persona;\n  });\n\n  // Extraer los datos del objeto XML y crear un nuevo objeto Perfil\n  const nombre = parsedData.nombre[0];\n  const edad = parseInt(parsedData.edad[0]);\n  const nacimiento = parsedData.nacimiento[0];\n  const lenguajes = parsedData.lenguajes[0].lenguaje;\n\n  return new Perfil(nombre, edad, nacimiento, lenguajes);\n}\n\n// Función para leer el archivo JSON y transformarlo en un objeto Perfil\nfunction leerJson(filePath) {\n  // Leer el contenido del archivo JSON\n  const data = fs.readFileSync(filePath, 'utf-8');\n  \n  // Parsear el JSON y crear un nuevo objeto Perfil\n  const jsonData = JSON.parse(data);\n  return new Perfil(jsonData.nombre, jsonData.edad, jsonData.nacimiento, jsonData.lenguajes);\n}\n\n// Ruta de los archivos XML y JSON\nconst xmlFilePath = 'perfil.xml';\nconst jsonFilePath = 'perfil.json';\n\n// Leer archivos y crear objetos Perfil\nconst perfilFromXml = leerXml(xmlFilePath);\nconst perfilFromJson = leerJson(jsonFilePath);\n\n// Mostrar la información de los perfiles\nconsole.log(\"Perfil desde XML:\");\nconsole.log(perfilFromXml.mostrarPerfil());\n\nconsole.log(\"\\nPerfil desde JSON:\");\nconsole.log(perfilFromJson.mostrarPerfil());*/\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/javascript/Deyvid-10.js",
    "content": "// XML y JSON\n\nlet fs = require('fs')\n\n// Crear el archivo .json\nfunction crearJSON()\n{\n    let contenido = {Nombre: 'Deyvid Marmolejo', Edad: 25, Nacimiento: '06-12-98', Lenguajes: ['JavaScript', 'Python']}\n    let contenidoJSON = JSON.stringify(contenido, null, 2)  \n\n    fs.writeFileSync('./#12/Deyvid-10.json', contenidoJSON, 'utf8')\n    \n    console.log(\"Archivo .json creado correctamente\")\n}\n\ncrearJSON()\n\n// Leer el archivo .json\nfunction leerJSON()\n{\n    let cont = JSON.parse(fs.readFileSync('./#12/Deyvid-10.json', 'utf8'))\n   \n    console.log(\"El contenido del archivo es:\\n\", cont);  \n\n    return cont\n}\n\nleerJSON()\n\n// Eliminar el archivo .json\nfunction eliminarJSON()\n{\n    fs.unlinkSync('./#12/Deyvid-10.json')\n\n    console.log(\"Archivo .json eliminado correctamente\");\n}\n\neliminarJSON()\n\n// Crear el archivo .xml\n\nlet xml2js = require('xml2js')\n\nfunction crearXML()\n{\n    let contenido2 = {root: {Nombre: 'Deyvid Marmolejo', Edad: 25, Nacimiento: '06-12-98', Lenguajes: ['JavaScript', 'Python']}}\n    let xml = new xml2js.Builder()\n    let contenidoXML = xml.buildObject(contenido2)\n\n    fs.writeFileSync('./#12/Deyvid-10.xml', contenidoXML, 'utf8')\n\n    console.log(\"Archivo .xml creado correctamente\");\n}\n\ncrearXML()\n\n// Leer el archivo .xml\nfunction leerXML()\n{\n    let objCont = \"\"\n\n    let leer = fs.readFileSync('./#12/Deyvid-10.xml', 'utf8')\n    let objetoXML = new xml2js.Parser()\n    \n    objetoXML.parseString(leer, (error, cont) => {\n    if(error)\n    {\n        console.log(\"Error encontrado: \", error);\n    }\n    else\n    {\n        console.log(\"Contenido del archivo:\\n\", cont);\n        objCont = cont\n    }\n    })\n\n    return objCont\n}\n\nleerXML()\n\n// Eliminar el archivo .xml\nfunction eliminarXML()\n{\n    fs.unlinkSync('./#12/Deyvid-10.xml')\n\n    console.log(\"Archivo .xml eliminado correctamente\");\n}\n\neliminarXML()\n\n// DIFICULTAD EXTRA\n\nclass Extra\n{\n    constructor(nombre, edad, nacimiento, lenguajes)\n    {\n        this.contenido = nombre\n        this.edad = edad\n        this.nacimiento = nacimiento\n        this.lenguajes = lenguajes\n    }\n}\n\ncrearJSON()\ncrearXML()\n\nlet json = leerJSON()\nlet extraJson = new Extra(json.Nombre, json.Edad, json.Nacimiento, json.Lenguajes)\neliminarJSON()\n\nlet xml = leerXML().root\nlet extraXml = new Extra(xml.Nombre[0], xml.Edad[0], xml.Nacimiento[0], xml.Lenguajes)\neliminarXML()\n\nconsole.log(extraJson);\nconsole.log(extraXml);"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/javascript/FabianRpv.js",
    "content": "// JSON Y XML\n\n// Archivo JSON \n\nconst fs = require('fs');\n\nconst datos = {\n    nombre: \"Fabian\",\n    edad: 20,\n    fecha: \"10-11-2004\",\n    lenguajes: [\"JavaScript\", \"PHP\", \"C++\"] \n}\n\nconst dataJson = JSON.stringify(datos, null, 2) \n\nfs.writeFile('Data.json', dataJson, (error) => {\n    if(error){\n        console.log(error)\n    }\n    else {\n        console.log('.json Creado')\n    }\n})\n\nfs.readFile('Data.json', 'utf8', (error, data) => {\n    if(error){\n        console.log(error);\n    }\n    else {\n        console.log(JSON.parse(data))\n    }\n})\n\nfs.unlink('Data.json', (error) => {\n    if(error){\n        console.log(error)\n    }\n    else {\n        console.log('.json Eliminado')\n    }\n})\n\n\n// Archivo XML\n\nconst {  Builder } = require ('xml2js')\n\n\nconst builder = new Builder();\n\nconst xml = builder.buildObject(datos)\n\nfs.writeFile('Data.xml', xml, (error) => {\n    if(error){\n        console.log(error)\n    }\n    else {\n        console.log(\".xml Creado\")\n    }\n})\n\nfs.readFile('Data.xml', 'utf8', (error, data) => {\n    if(error){\n        console.log(error)\n    }\n    else{\n        console.log(data)\n    }\n})\n\nfs.unlink('Data.xml', (error) => {\n    if(error){\n        console.log(error)\n    }\n    else{\n        console.log('.xml Eliminado')\n    }\n})"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/javascript/Glitzypanic.js",
    "content": "/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu\n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n */\n\nconst fs = require(\"fs/promises\");\n\nasync function main() {\n  const data = {\n    nombre: \"Juan\",\n    edad: 30,\n    fechaNacimiento: \"1994-05-15\",\n    lenguajes: [\"JavaScript\", \"Python\", \"Java\"],\n  };\n\n  try {\n    // Crear JSON\n    const jsonData = JSON.stringify(data, null, 2);\n    await fs.writeFile(\"datos.json\", jsonData);\n\n    // Crear XML\n    const xmlData = `\n<persona>\n    <nombre>${data.nombre}</nombre>\n    <edad>${data.edad}</edad>\n    <fechaNacimiento>${data.fechaNacimiento}</fechaNacimiento>\n    <lenguajes>\n        ${data.lenguajes.map((lang) => `<lenguaje>${lang}</lenguaje>`).join(\"\")}\n    </lenguajes>\n</persona>`;\n    await fs.writeFile(\"datos.xml\", xmlData);\n\n    // Leer y mostrar contenido\n    const readJsonData = await fs.readFile(\"datos.json\", \"utf-8\");\n    console.log(\"Contenido del archivo JSON:\", readJsonData);\n\n    const readXmlData = await fs.readFile(\"datos.xml\", \"utf-8\");\n    console.log(\"Contenido del archivo XML:\", readXmlData);\n\n    // Borrar archivos\n    await fs.unlink(\"datos.json\");\n    await fs.unlink(\"datos.xml\");\n    console.log(\"Archivos borrados con éxito.\");\n  } catch (error) {\n    console.error(\"Error:\", error);\n  }\n}\n\nmain();\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #12 - JavaScript ->Jesus Antonio Escamilla */\n/**\n * XML (Extensible Markup Lenguaje), es similar a HTML pero con etiquetas personalizadas.\n * XML tiene una sintaxis estandarizada, lo que permite que los datos compartidos o transmitidos a través de sistemas o plataformas puedan ser analizados por el destinatario.\n * JSON (JavaScript Object Notation), es un formato de texto para datos estructurados en aplicaciones web.\n * El artículo proporciona información sobre cómo trabajar con JSON utilizando JavaScript, incluido el análisis de JSON para acceder a los datos y la creación de JSON.\n */\n\n\n// Extension para crear los ficheros XML y JSON\nconst fs = require('fs');\n\n// Expresión del objeto sin estructurar\nconst dataXML_JSON = {\n    'nombre': 'Fatima',\n    'edad': 21,\n    'fecha_Nacimiento': '30-01-2000',\n    'programación_Lenguaje': ['JavaScript', 'Python']\n};\n\n\n//---EJERCIÓ SIMPLE XML ESTRUCTURADO---\n\n// Nombre y Ruta del XML\nxmlFile = 'JesusAntonioEEscamilla.xml';\n\n// Creando XML a mano\nconst xmlObjeto = `\n<data>\n    <nombre>Jesus Antonio Escamilla Escamilla</nombre>\n    <edad>24</edad>\n    <fecha_Nacimiento>22-12-1999</fecha_Nacimiento>\n    <programación_Lenguaje>\n        <item>JavaScript</item>\n        <item>Python</item>\n        <item>Java</item>\n        <item>PHP</item>\n    </programación_Lenguaje>\n</data>\n`;\n\n// Guardar el XML\ntry {\n    // Se crea el fichero XML\n    fs.writeFileSync(xmlFile, xmlObjeto);\n\n    // Se lee el fichero XML\n    const leerXML = fs.readFileSync(xmlFile, 'utf-8');\n    console.log(leerXML);\n\n    // Se elimina el fichero XML\n    fs.unlinkSync(xmlFile);\n} catch (error) {\n    console.error('Se encontró un error en el XML: ', error);\n}\n\n\n//---EJERCIÓ SIMPLE XML NO ESTRUCTURADO---\n\nconst convertToXML = (obj, data = 'data') => {\n    let xml = `<${data}>`;\n    for (let key in obj){\n        if (typeof obj[key] === 'object'){\n            xml += convertToXML(obj[key], key);\n        } else {\n            xml += `<${key}>${obj[key]}</${key}>`;\n        }\n    }\n    xml += `<${data}>`;\n    return xml;\n};\n\n// Convertir en objeto a XML\nconst xmlData = convertToXML(dataXML_JSON);\n\n// Crea fichero XML\nfs.writeFileSync('Faty.xml', xmlData);\n\n// Se elimina\nfs.unlinkSync('Faty.xml');\n\n\n\n//---EJERCIÓ SIMPLE JSON ESTRUCTURADO---\n\n// Nombre y Ruta del XML\njsonFile = 'JesusAntonioEEscamilla.json';\n\n// Creando el JSON\nconst jsonObjeto = {\n    data: {\n        nombre: 'Jesus Antonio Escamilla Escamilla',\n        edad: 24,\n        fecha_Nacimiento: 22-12-1999,\n        programación_Lenguaje: ['JavaScript', 'Python', 'Java', 'PHP']\n    }\n};\n\n// Convertir en formato JSON\nconst JsonData = JSON.stringify(jsonObjeto, null, 2);\n\ntry {\n    // Se crea el fichero JSON\n    fs.writeFileSync(jsonFile, JsonData);\n\n    // Se lee en consola\n    const leerJSON = fs.readFileSync(jsonFile, 'utf-8');\n    console.log(leerJSON);\n\n    // Se elimina el fichero JSON\n    fs.unlinkSync(jsonFile);\n} catch (error) {\n    console.error('Se encontró un error en el JSON: ', error);\n}\n\n\n//---EJERCIÓ SIMPLE JSON NO ESTRUCTURADO---\n\n// Convertir el objeto a JSON\nconst jsonData = JSON.stringify(dataXML_JSON, null, 2);\n\n// Se crea el fichero JSON\nfs.writeFileSync('Faty.json', jsonData);\n\n// Se elimina el fichero JSON\nfs.unlinkSync('Faty.json');\n\n\n\n/**-----DIFICULTAD EXTRA-----*/\n\n//  Se utiliza una librería de XML\nconst xml2js = require('xml2js');\n\n//  Se crea la clase de transformación de XML y JSON\nclass dataTransformer{\n    constructor(xmlObjeto, jsonObjeto){\n        this.xmlObjeto = xmlObjeto,\n        this.jsonObjeto = jsonObjeto\n    }\n\n    // Se crea una transformación de XML\n    transformFromXML() {\n        const xmlDoc = this._parseXmlString(this.xmlObjeto);\n        const dataNode = xmlDoc.getElementsByTagName('data')[0];\n\n        const nombre = dataNode.getElementsByTagName('nombre')[0].textContent;\n        const edad = parseInt(dataNode.getElementsByTagName('edad')[0].textContent);\n        const fechaNacimiento = dataNode.getElementsByTagName('fecha_Nacimiento')[0].textContent;\n\n        const lenguajesNode = dataNode.getElementsByTagName('programación_Lenguaje')[0];\n        const lenguajes = Array.from(lenguajesNode.getElementsByTagName('item')).map(item => item.textContent);\n\n        return { nombre, edad, fechaNacimiento, lenguajes };\n    }\n\n    // Se hace la transformación\n    _parseXmlString(xmlString) {\n        const parser = new DOMParser();\n        return parser.parseFromString(xmlString, 'text/xml');\n    }\n\n    // Se crea una transformación de JSON\n    transformJSON() {\n        return JSON.parse(this.jsonObjeto.data);\n    }\n}\n\n// Crear una instancia de la clase DataTransformer\nconst transformer = new dataTransformer(xmlData, JSON.stringify(jsonData));\n\n// Transformar y mostrar los datos\nconsole.log(\"Datos transformados desde XML:\");\nconsole.log(transformer.transformXML());\n\nconsole.log(\"\\nDatos transformados desde JSON:\");\nconsole.log(transformer.transformJSON());\n\n/**-----DIFICULTAD EXTRA-----*/"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/javascript/RaulDoezon.js",
    "content": "/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n * \n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu \n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n*/\n\nconst fs = require('node:fs');\n\nconsole.log(\"+++++++++ JSON +++++++++\");\n\nconst myObject = {\n  name: \"Raúl\",\n  age: 70,\n  birthdate: \"13/06/1954\",\n  programming_languages: {\n    frontend: \"JavaScript\",\n    backend: \"Python\"\n  }\n}\n\nconst myJSON = JSON.stringify(myObject);\n\ntry {\n  fs.writeFileSync('./RaulDoezon.json', myJSON);\n\n  console.log(\"¡El archivo JSON fue creado!\\n\");\n} catch (writeJSONError) {\n  console.log(writeJSONError);\n}\n\ntry {\n  const jsonData = fs.readFileSync('./RaulDoezon.json', 'utf8');\n\n  console.log(JSON.parse(jsonData));\n} catch (readJSONError) {\n  console.log(readJSONError);\n}\n\nsetTimeout(() => {\n  try {\n    fs.unlinkSync('./RaulDoezon.json');\n\n    console.log(\"\\n¡Se eliminó el archivo JSON!\");\n  } catch (unlinkJSONError) {\n    console.log(unlinkJSONError);\n  }\n}, 2000);\n\nconsole.log(\"\\n+++++++++ XML +++++++++\");\n\nconst myXML = `<?xml version=\"1.0\"?>\n<information>\n  <name>Raúl</name>\n  <age>70</age>\n  <birthdate>13/06/1954</birthdate>\n  <programming_languages>\n    <frontend>JavaScript</frontend>\n    <backend>Python\"</backend>\n  </programming_languages>\n</information>`;\n\ntry {\n  fs.writeFileSync('./RaulDoezon.xml', myXML);\n\n  console.log(\"\\n¡Fue creado el archivo XML!\\n\");\n} catch (XMLWriteError) {\n  console.log(XMLWriteError);\n}\n\ntry {\n  const xmlData = fs.readFileSync('./RaulDoezon.xml', 'utf8');\n\n  console.log(xmlData);\n} catch (readXMLError) {\n  console.log(readXMLError);\n}\n\nsetTimeout(() => {\n  try {\n    fs.unlinkSync('./RaulDoezon.xml');\n\n    console.log(\"\\n¡Se eliminó el archivo XML!\");\n  } catch (unlinkXMLError) {\n    console.log(unlinkXMLError);\n  }\n}, 2000);\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/javascript/RicJDev.js",
    "content": "//EJERCICIO\nconst { error } = require('node:console');\nconst fs = require('node:fs');\nconst { stringify } = require('node:querystring');\nconst { create } = require('xmlbuilder2');\nconst { pd } = require('pretty-data');\n\nlet fileName1 = 'myJSON.json';\n\nconst personData = {\n\tname: 'Ric',\n\tage: 21,\n\tbirhtDate: '22/09/2002',\n\tlanguages: ['JavaScript', 'HTML'],\n};\n\nfs.writeFile(fileName1, JSON.stringify(personData), (error) => {\n\tconsole.log('\\n---CREANDO JSON---');\n\tif (error) {\n\t\tconsole.log(`Se produjo un error: ${error}`);\n\t}\n\tconsole.log('Fichero creado!');\n\tfs.readFile(fileName1, 'utf8', (error, data) => {\n\t\tconsole.log('\\n---LEYENDO JSON---');\n\t\tif (error) {\n\t\t\tconsole.log(`Se produjo un error: ${error}`);\n\t\t}\n\t\tconsole.log(data);\n\t\tfs.unlink(fileName1, (error) => {\n\t\t\tconsole.log('\\n---ELIMINANDO JSON---');\n\t\t\tif (error) {\n\t\t\t\tconsole.log(`Se produjo un error: ${error}`);\n\t\t\t}\n\t\t\tconsole.log('Fichero eliminado!');\n\t\t});\n\t});\n});\n\nlet fileName2 = 'myXML.xml';\n\nconst xml = create({\n\tencoding: 'utf8',\n\tversion: '1.0',\n})\n\t.ele('raiz')\n\t.ele('Nombre', 'Ric')\n\t.up()\n\t.ele('Edad', 'Veintiuno')\n\t.up()\n\t.ele('Lenguajes', 'JavaScript')\n\t.end({ prettyPrint: true });\n\nlet xmlContent = pd.xml(xml);\n\nfs.writeFile(fileName2, xmlContent, (error) => {\n\tconsole.log('\\n---CREANDO XML---');\n\tif (error) {\n\t\tconsole.log(`Se produjo un error: ${error}`);\n\t}\n\tconsole.log('Fichero creado!');\n\tfs.readFile(fileName2, 'utf8', (error, data) => {\n\t\tconsole.log('\\n---LEYENDO XML---');\n\t\tif (error) {\n\t\t\tconsole.log(`Se produjo un error: ${error}`);\n\t\t}\n\t\tconsole.log(data);\n\t\tfs.unlink(fileName2, (error) => {\n\t\t\tconsole.log('\\n---ELIMINANDO XML---');\n\t\t\tif (error) {\n\t\t\t\tconsole.log(`Se produjo un error: ${error}`);\n\t\t\t}\n\t\t\tconsole.log('Fichero eliminado!');\n\t\t});\n\t});\n});\n\n//TODO: dificultad extra."
  },
  {
    "path": "Roadmap/12 - JSON Y XML/javascript/Sac-Corts.js",
    "content": "const fs = require('fs');\n\nconst data = {\n    name: 'Isaac Cortés',\n    age: 22,\n    birthdate: \"2001-10-21\",\n    programmingLanguage: [\"JavaScript\", \"Python\"]\n};\n\nfs.writeFileSync('data.json', JSON.stringify(data, null, 4));\n\nlet xmlData2 = `<?xml version =\"1.0\" encoding=\"UTF-8\"?>\n<person>\n    <name>${data.name}</name>\n    <age>${data.age}</age>\n    <birthdate>${data.birthdate}</birthdate>\n    <programmingLanguage>${data.programmingLanguage.map(lang => `<language>${lang}</language>`).join('\\n     ')}</programmingLanguage>\n</person>`;\n\nfs.writeFileSync('data.xml', xmlData2);\n\nconsole.log(\"Content of data.json:\");\nconsole.log(fs.readFileSync('data.json', 'utf8'));\n\nconsole.log(\"\\nContent of data.xml:\");\nconsole.log(fs.readFileSync('data.xml', 'utf8'));\n\n// fs.unlinkSync('data.json');\n// fs.unlinkSync('data.xml');\n// console.log(\"\\nDeleted Files.\");\n\n\n// Extra Exercise //\n\nclass Person {\n    constructor(name, age, birthdate, programmingLanguage) {\n        this.name = name;\n        this.age = age;\n        this.birthdate = birthdate;\n        this.programmingLanguage = programmingLanguage;\n    }\n\n    showData() {\n        console.log(`Name: ${this.name}`);\n        console.log(`Age: ${this.age}`);\n        console.log(`Birthdate: ${this.birthdate}`);\n        console.log(`Programming Language: ${this.programmingLanguage.join(', ')}`);\n\n    }\n}\n\n// Read JSON and XML file\nconst jsonContent = fs.readFileSync('data.json', 'utf-8');\nconst xmlContent = fs.readFileSync('data.xml', 'utf-8');\n\n// Parse JSON and XML in JavaScript\nconst jsonData = JSON.parse(jsonContent);\n\nfunction parseXML(xml) {\n    const name = xml.match(/<name>(.*?)<\\/name>/)[1];\n    const age = parseInt(xml.match(/<age>(.*?)<\\/age>/)[1], 10);\n    const birthdate = xml.match(/<birthdate>(.*?)<\\/birthdate>/)[1];\n    const languagesMatches = xml.match(/<language>(.*?)<\\/language>/g);\n    const programmingLanguage = languagesMatches.map(lang => lang.replace(/<\\/?language>/g,  ''));\n\n    return {\n        name,\n        age,\n        birthdate,\n        programmingLanguage\n    };\n}\n\nconst xmlData = parseXML(xmlContent);\n\n// Create instances of the class with the read data\nconst personFromJson = new Person(\n    jsonData.name,\n    jsonData.age,\n    jsonData.birthdate,\n    jsonData.programmingLanguage\n);\n\nconst personFromXml = new Person(\n    xmlData.name,\n    xmlData.age,\n    xmlData.birthdate,\n    xmlData.programmingLanguage\n);\n\n// Show data for class instances\nconsole.log(\"Data from JSON:\");\npersonFromJson.showData();\n\nconsole.log(\"\\nData from XML:\");\npersonFromXml.showData();\n\n// Delete the files\nfs.unlinkSync('data.json');\nfs.unlinkSync('data.xml');\nconsole.log(\"\\nDeleted files.\");"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/javascript/adrs1166ma.js",
    "content": "/*\nIMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n\nEJERCICIO:\nDesarrolla un programa capaz de crear un archivo XML y JSON que guarde los\nsiguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n- Nombre\n- Edad\n- Fecha de nacimiento\n- Listado de lenguajes de programación\nMuestra el contenido de los archivos.\nBorra los archivos.\n\nDIFICULTAD EXTRA (opcional):\nUtilizando la lógica de creación de los archivos anteriores, crea un\nprograma capaz de leer y transformar en una misma clase custom de tu \nlenguaje los datos almacenados en el XML y el JSON.\nBorra los archivos.\n*/\n\nconst fs = require('fs');\n\nconst datos = {\n    nombre: \"Anderson\",\n    edad: 20,\n    fechaNacimiento: \"01/01/2005\",\n    lenguajes: [\"JavaScript\", \"Python\", \"Java\"]\n};\n\n// 🔥 JSON\nfunction crearArchivoJSON() {\n    const jsonContent = JSON.stringify(datos, null, 2); // Convertir a JSON con formato legible\n    fs.writeFile(\"datos.json\", jsonContent, (err) => {\n        if (err) {\n            console.error(\"Error al crear el archivo JSON:\", err);\n            return;\n        }\n        console.log(\"Archivo JSON creado con éxito. ✅\");\n        leerArchivoJSON();\n    });\n}\n\n// 🔥 Leer\nfunction leerArchivoJSON() {\n    fs.readFile(\"datos.json\", 'utf8', (err, data) => {\n        if (err) {\n            console.error(\"Error al leer el archivo JSON:\", err);\n            return;\n        }\n        console.log(\"Contenido del archivo JSON:\");\n        console.log(data);\n        crearArchivoXML(); // Continuar con la creación del archivo XML\n    });\n}\n\n// 🔥 Crear XML\nfunction crearArchivoXML() {\n    const xmlContent = `\n<datos>\n    <nombre>${datos.nombre}</nombre>\n    <edad>${datos.edad}</edad>\n    <fechaNacimiento>${datos.fechaNacimiento}</fechaNacimiento>\n    <lenguajes>\n        ${datos.lenguajes.map(lenguaje => `        <lenguaje>${lenguaje}</lenguaje>`).join(\"\\n\")}\n    </lenguajes>\n</datos>`;\n    fs.writeFile(\"datos.xml\", xmlContent, (err) => {\n        if (err) {\n            console.error(\"Error al crear el archivo XML:\", err);\n            return;\n        }\n        console.log(\"Archivo XML creado con éxito. ✅\");\n        leerArchivoXML();\n    });\n}\n\n// 🔥 Leer XML\nfunction leerArchivoXML() {\n    fs.readFile(\"datos.xml\", 'utf8', (err, data) => {\n        if (err) {\n            console.error(\"Error al leer el archivo XML:\", err);\n            return;\n        }\n        console.log(\"Contenido del archivo XML:\");\n        console.log(data);\n        borrarArchivos(); // Borrar ambos archivos\n    });\n}\n\n// 🔥 Borrar archivos\nfunction borrarArchivos() {\n    fs.unlink(\"datos.json\", (err) => {\n        if (err && err.code !== 'ENOENT') {\n            console.error(\"Error al borrar el archivo JSON:\", err);\n        } else {\n            console.log(\"Archivo JSON borrado con éxito. ✅\");\n        }\n    });\n\n    fs.unlink(\"datos.xml\", (err) => {\n        if (err && err.code !== 'ENOENT') {\n            console.error(\"✖️ Error al borrar el archivo XML:\", err);\n        } else {\n            console.log(\"Archivo XML borrado con éxito. ✅\");\n        }\n    });\n}\n\ncrearArchivoJSON();\n\n\n// 🔥 Etra\n// para iniciar el programa es necesario hacer:\n// npm install xml2js\n\nconst fs = require('fs');\nconst xml2js = require('xml2js'); // Módulo para parsear XML\n\nclass Persona {\n    constructor(nombre, edad, fechaNacimiento, lenguajes) {\n        this.nombre = nombre\n        this.edad = edad\n        this.fechaNacimiento = fechaNacimiento\n        this.lenguajes = lenguajes\n    }\n\n    mostrarDatos() {\n        console.log(\"Datos de la persona:\")\n        console.log(`Nombre: ${this.nombre}`)\n        console.log(`Edad: ${this.edad}`)\n        console.log(`Fecha de nacimiento: ${this.fechaNacimiento}`)\n        console.log(`Lenguajes: ${this.lenguajes.join(\", \")}`)\n    }\n}\n\n// Crear archivos iniciales\nfunction crearArchivos() {\n    const datos = {\n        nombre: \"Tu Nombre\",\n        edad: 25,\n        fechaNacimiento: \"01/01/1998\",\n        lenguajes: [\"JavaScript\", \"Python\", \"Java\"]\n    };\n\n    // Crear archivo JSON\n    fs.writeFile(\"datos.json\", JSON.stringify(datos, null, 2), (err) => {\n        if (err) {\n            console.error(\"Error al crear el archivo JSON:\", err);\n            return;\n        }\n        console.log(\"Archivo JSON creado con éxito.\");\n    });\n\n    // Crear archivo XML\n    const xmlContent = `\n<datos>\n    <nombre>${datos.nombre}</nombre>\n    <edad>${datos.edad}</edad>\n    <fechaNacimiento>${datos.fechaNacimiento}</fechaNacimiento>\n    <lenguajes>\n        ${datos.lenguajes.map(lenguaje => `        <lenguaje>${lenguaje}</lenguaje>`).join(\"\\n\")}\n    </lenguajes>\n</datos>`;\n    fs.writeFile(\"datos.xml\", xmlContent, (err) => {\n        if (err) {\n            console.error(\"Error al crear el archivo XML:\", err);\n            return;\n        }\n        console.log(\"Archivo XML creado con éxito.\");\n        leerArchivos();\n    });\n}\n\n// Leer archivos y transformar en clase\nfunction leerArchivos() {\n    // Leer archivo JSON\n    fs.readFile(\"datos.json\", 'utf8', (err, jsonData) => {\n        if (err) {\n            console.error(\"Error al leer el archivo JSON:\", err);\n            return;\n        }\n\n        // Parsear JSON\n        const datosJSON = JSON.parse(jsonData);\n\n        // Leer archivo XML\n        fs.readFile(\"datos.xml\", 'utf8', (err, xmlData) => {\n            if (err) {\n                console.error(\"Error al leer el archivo XML:\", err);\n                return;\n            }\n\n            // Parsear XML\n            const parser = new xml2js.Parser({ explicitArray: false });\n            parser.parseString(xmlData, (err, result) => {\n                if (err) {\n                    console.error(\"Error al parsear el archivo XML:\", err);\n                    return;\n                }\n\n                const datosXML = {\n                    nombre: result.datos.nombre,\n                    edad: parseInt(result.datos.edad),\n                    fechaNacimiento: result.datos.fechaNacimiento,\n                    lenguajes: Array.isArray(result.datos.lenguajes.lenguaje)\n                        ? result.datos.lenguajes.lenguaje\n                        : [result.datos.lenguajes.lenguaje]\n                };\n\n                // Mostrar datos transformados\n                console.log(\"\\nDatos del archivo JSON:\");\n                const personaJSON = new Persona(\n                    datosJSON.nombre,\n                    datosJSON.edad,\n                    datosJSON.fechaNacimiento,\n                    datosJSON.lenguajes\n                );\n                personaJSON.mostrarDatos();\n\n                console.log(\"\\nDatos del archivo XML:\");\n                const personaXML = new Persona(\n                    datosXML.nombre,\n                    datosXML.edad,\n                    datosXML.fechaNacimiento,\n                    datosXML.lenguajes\n                );\n                personaXML.mostrarDatos();\n\n                // Borrar archivos\n                borrarArchivos();\n            });\n        });\n    });\n}\n\n// Borrar archivos\nfunction borrarArchivos() {\n    fs.unlink(\"datos.json\", (err) => {\n        if (err && err.code !== 'ENOENT') {\n            console.error(\"Error al borrar el archivo JSON:\", err);\n        } else {\n            console.log(\"Archivo JSON borrado con éxito.\");\n        }\n    });\n\n    fs.unlink(\"datos.xml\", (err) => {\n        if (err && err.code !== 'ENOENT') {\n            console.error(\"Error al borrar el archivo XML:\", err);\n        } else {\n            console.log(\"Archivo XML borrado con éxito.\");\n        }\n    });\n}\n\ncrearArchivos();"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/javascript/agusrosero.js",
    "content": "/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu\n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n */\n\n// EJERCICIO:\n\nconst fs = require(\"node:fs\");\n\nconst content = {\n  nombre: \"Hernan\",\n  edad: 23,\n  fechaNacimiento: \"03-08-00\",\n  lenguajes: \"Python, Javascript\",\n};\n\n// XML\nfs.writeFile(\"test.xml\", JSON.stringify(content), (err) => {\n  if (err) {\n    console.error(err);\n  }\n  console.log(\"El archivo fue guardado..\");\n\n  fs.readFile(\"test.xml\", \"utf-8\", (error, data) => {\n    if (error) {\n      console.log(\"Error al leer el archivo.\");\n      return;\n    }\n    console.log(\"Contenido del archivo:\", data);\n  });\n\n  fs.unlink(\"test.xml\", (error) => {\n    if (error) {\n      console.log(\"Error al borrar el archivo\", error);\n    }\n    console.log(\"Archivo borrado correctamente\");\n  });\n});\n\n// JSON\nfs.writeFile(\"test.json\", JSON.stringify(content), (err) => {\n  if (err) {\n    console.error(err);\n  }\n  console.log(\"El archivo fue guardado..\");\n\n  fs.readFile(\"test.json\", \"utf-8\", (error, data) => {\n    if (error) {\n      console.log(\"Error al leer el archivo.\");\n      return;\n    }\n    console.log(\"Contenido del archivo:\", data);\n  });\n\n  fs.unlink(\"test.json\", (error) => {\n    if (error) {\n      console.log(\"Error al borrar el archivo\", error);\n    }\n    console.log(\"Archivo borrado correctamente\");\n  });\n});\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/javascript/alexdevrep.js",
    "content": "/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu \n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n */\n\n//Importamos las librerías necesarias\n\nconst fs = require('fs')\n/*\n    La función create es exportada por el módulo y esta función crea y retorna un nodo de documento XML en blanco.\n\n    Un nodo de documento XML es el contenedor principal que organiza y estructura todos los elementos\n    de un documento XML\n*/\nconst { create } = require('xmlbuilder') \n\n\n//Creamos el documento XML\n\nconst xmlDoc = create({ version: '1.0' })\n  .ele('raiz') //La función ele crea y devuelve un nodo\n    .ele('Nombre', 'Alejandro').up()  //La función up devuelve el nodo de elemento elemento padre\n    .ele('Edad', '24') .up()\n    .ele('Lenguajes','javaScript')\n    \n  .end({ prettyPrint: true }) //End convierte el documento XML en su representación de cadena\n\n//Especificamos el nombre del documento XML\nconst filePath = 'prueba.xml'\n\n// Escribir el contenido en el archivo XML\nfs.writeFile(filePath, xmlDoc, function (err) {\n    if (err) {\n      console.error('Error al escribir el archivo XML:', err)\n    } else {\n      console.log('El archivo XML ha sido creado correctamente en:', filePath)\n    }\n  \n  \n  })\n\n//Mostramos el contenido del archivo XML\nconsole.log(xmlDoc)\n\n//Creamos el documento JSON\nconst jsonObject={\n    nombre: 'Alejandro',\n    edad: 24,\n    lenguajes: ['JavaScript']\n}\n\nconst jsonString= JSON.stringify(jsonObject,null,2)\n\nconst archivo = 'prueba.json'\n\n// Escribir el contenido en el archivo json\nfs.writeFile(archivo, jsonString, function (err) {\n    if (err) {\n      console.error('Error al escribir el archivo json:', err)\n    } else {\n      console.log('El archivo json ha sido creado correctamente en:', archivo)\n    }\n  \n  \n  })\n\n//Mostramos el contenido del archivo JSON\nconsole.log(jsonObject)\n\n//Borramos los ficheros creados\nfunction errorBorrar(err){\n    if(err){\n        console.log(\"Error al borrar el fichero\",err)\n    }\n    else{\n        console.log(\"Archivo borrado exitosamente\")\n    }\n}\n//Borramos el archivo Json\nfs.unlink(archivo,errorBorrar)\n//Borramos el archivo XML \nfs.unlink(filePath,errorBorrar)"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/javascript/bernatcs.js",
    "content": "// ** EJERCICIO\n\nconst fs = require('node:fs').promises\nconst { parse } = require('node:path')\nconst xmlbuilder = require('xmlbuilder')\nconst { DOMParser } = require('xmldom');\n\n\nconst data = {\n    Nombre: 'Bernat',\n    Edad: '29',\n    FechaDeNacimiento: '29.02.1995',\n    ListadoDeLenguajes: ['MaxMSP', 'JS', 'SwiftUI']\n}\n\n// JSON\n\nconst dataDocument = JSON.stringify(data, null, 2)\n\nfs.writeFile('datos.json', dataDocument, (err) => {\n    if (err) {\n        console.error('Error al guardar el archivo JSON', err)\n    } else {\n        // console.log('Se ha guadado correctamente el archivo JSON')\n    }\n})\n\n// XML\n\nconst xml = xmlbuilder.create('persona')\n    .ele('nombre', data.Nombre).up()\n    .ele('edad', data.Edad).up()\n    .ele('fechadenacimiento', data.FechaDeNacimiento).up()\n    .ele('listadodelenguajes')\n        .ele('listadodelenguajes', data.ListadoDeLenguajes[0]).up()\n        .ele('listadodelenguajes', data.ListadoDeLenguajes[1]).up()\n        .ele('listadodelenguajes', data.ListadoDeLenguajes[2]).up()\n        .ele('listadodelenguajes', data.ListadoDeLenguajes[3]).up()\n    .end({ pretty: true });\n\nfs.writeFile('datos.xml', xml, (err) => {\n    if (err) {\n        console.error('Error al guardar el archivo XML:', err)\n    } else {\n        // console.log('Se ha guadado correctamente el archivo XML')\n    }\n});\n\n// ** DIFICULTAD EXTRA ** ----------------------------------------------------------------------------------------------------------------------------------------------------\n\n// JSON\n\nasync function leerJSON(ruta_al_archivo) {\n    try {\n        const data = await fs.readFile(ruta_al_archivo, 'utf8');\n        return JSON.parse(data);\n    } catch (err) {\n        console.error('Error al leer o parsear el archivo JSON:', err);\n        throw err;\n    }\n}\n\nasync function guardarJSON(ruta_al_archivo, array) {\n    try {\n        const jsonData = await leerJSON(ruta_al_archivo);\n        array.push(jsonData);\n        console.log('Los archivos del JSON han sido guardados correctamente');\n    } catch (error) {\n        console.error('No ha sido posible guardar los archivos', error);\n    }\n}\n\nlet jsonData = []\n\nguardarJSON('datos.json', jsonData).then(() => {\n    console.log(jsonData);\n}).catch(err => {\n    console.error('Error al ejecutar guardarJSON:', err);\n});\n\n\n// XML --> Hay un problema a la hora de instalar las librerías de lectura y guardado de xml, por eso da error.\n\nasync function leerXML(ruta_al_archivo) {\n    try {\n        const xmlString = await fs.readFile(ruta_al_archivo, 'utf8');\n        const parser = new DOMParser();\n        const xmlDoc = parser.parseFromString(xmlString, 'text/xml');\n\n        // Verificar si se encontraron elementos 'persona'\n        const personas = xmlDoc.getElementsByTagName('persona');\n        if (personas.length === 0) {\n            console.error('No se encontraron elementos <persona> en el archivo XML.');\n            return [];  // Devolver un array vacío en caso de no encontrar elementos\n        }\n\n        const XMLData = [];\n\n        for (let persona of personas) {\n            const nombre = persona.getElementsByTagName('nombre')[0].textContent;\n            const edad = persona.getElementsByTagName('edad')[0].textContent;\n            const fechaDeNacimiento = persona.getElementsByTagName('fechadenacimiento')[0].textContent;\n\n            const listadoDeLenguajes = [];\n            const lenguajes = persona.getElementsByTagName('listadodelenguajes')[0].getElementsByTagName('listadodelenguajes');\n            for (let lenguaje of lenguajes) {\n                listadoDeLenguajes.push(lenguaje.textContent);\n            }\n\n            XMLData.push({\n                nombre,\n                edad,\n                fechaDeNacimiento,\n                listadoDeLenguajes\n            });\n        }\n\n        return XMLData;\n\n    } catch (err) {\n        console.error('Error al leer o parsear el archivo XML:', err);\n        throw err;\n    }\n}\n\nasync function guardarXML(ruta_al_archivo, array) {\n    try {\n        const jsonData = await leerXML(ruta_al_archivo);\n        array.push(...jsonData); // Utilizamos spread operator para añadir los elementos individuales\n        console.log('Los datos del XML han sido guardados correctamente');\n    } catch (error) {\n        console.error('No ha sido posible guardar los datos del XML', error);\n    }\n}\n\nlet XMLData = [];\n\nconst archivoXML = 'datos.xml';\n\nguardarXML(archivoXML, XMLData)\n    .then(() => {\n        console.log('Datos finales del XML:', XMLData);\n    })\n    .catch(err => {\n        console.error('Error al ejecutar guardarXML:', err);\n    });"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/javascript/brahiams7.js",
    "content": "// * EJERCICIO:\n//  * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n//  * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n//  * - Nombre\n//  * - Edad\n//  * - Fecha de nacimiento\n//  * - Listado de lenguajes de programación\n//  * Muestra el contenido de los archivos.\n//  * Borra los archivos.\n\nconst builder = require('xmlbuilder');\nconst fs = require('fs');\nconst xml2js = require('xml2js');\n\n// CREAR UN ARCHIVO JSON\n    const carpeta=\"brahiams7.json\"\nconst crearJSON=()=>{\n    const data={\n        name:\"Brahiam\",\n        age:19,\n        birthDate:\"05-08-2005\",\n        programmingLenguages:\"SQL, Python, Node\"\n    }\n    jsonData=JSON.stringify(data,null,2);\n    fs.writeFile(carpeta,jsonData,\"utf-8\",(err)=>{\n        if (err) console.log(err);\n        \n    })\n}\n\n// CREAR UN ARCHIVO XML\nconst crearXML=()=>{\n    const xmlData=builder.create('usuario')\n    .ele('name','Brahiam').up()\n    .ele('age','19').up()\n    .ele('birthDate','05-08-2005').up()\n    .ele('programmingLenguages','SQL, Python, Node').up()\n    .end({pretty:true})\n    fs.writeFile(\"brahiams7.xml\",xmlData,\"utf-8\",(err)=>{\n    if (err) console.log(err);\n    })\n}\n\n\n\n// CREANDO LA CLASE\n\n    class Usuario {\n    constructor(name,age,birthDate,programmingLenguages){\n        this.name=name,\n        this.age=age,\n        this.birthDate=birthDate,\n        this.programmingLenguages=programmingLenguages\n    }\n    mostrarDatos(){\n        console.log(`Nombre: ${this.name}`);\n        console.log(`age: ${this.age}`);\n        console.log(`birthDate: ${this.birthDate}`);\n        console.log(`programmingLenguages: ${this.programmingLenguages}\\n`);\n    }\n}\n\nconst showJSON = ()=>{\n        fs.readFile(carpeta,'utf-8',(err,result)=>{\n        const datosJSON=JSON.parse(result)\n        const usuarioJson = new Usuario(\n        datosJSON.name,\n        datosJSON.age,\n        datosJSON.birthDate,\n        datosJSON.programmingLenguages\n    )\n    usuarioJson.mostrarDatos();\n    })\n    \n}\n\nconst showXML = ()=>{\n    const dataXML=fs.readFileSync('brahiams7.xml','utf-8')\n    xml2js.parseString(dataXML,(err,result)=>{\n        if (err) throw err;\n        const datosXML=result.usuario\n        const usuarioXML= new Usuario (\n            datosXML.name[0],\n            datosXML.age[0],\n            datosXML.birthDate[0],\n            datosXML.programmingLenguages[0]\n        )\n        usuarioXML.mostrarDatos()\n    })\n}\nconst deleteData=()=>{\n    fs.unlink(carpeta,(err)=>{\n        if(err) console.log(err);\n    })\n    fs.unlink('brahiams7.xml',(err)=>{\n        if(err) console.log(err);\n    })\n}\n\nshowJSON();\nshowXML();\ndeleteData()\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/javascript/caterinarodriguezdev.js",
    "content": "/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu \n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n */\n\nconst fs = require('fs');\n\nconst data = {\n    nombre: 'Caterina Rodríguez',\n    edad: 25,\n    fechaNacimiento: '12-08-1999',\n    lenguajes: ['JavaScript', 'Python', 'Java']\n};\n\nconst crearJSON = (data) => {\n    const jsonContent = JSON.stringify(data);\n    console.log(jsonContent);\n    fs.writeFileSync(\"miJson.json\", jsonContent);\n}\n\nconst crearXML = (data) => {\n    let xmlContent = '<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n';\n    xmlContent += '<persona>\\n';\n    xmlContent += '\\t<nombre>' + data.nombre + '</nombre>\\n';\n    xmlContent += '\\t<edad>' + data.edad + '</edad>\\n';\n    xmlContent += '\\t<fechaNacimiento>' + data.fechaNacimiento + '</nacimiento>\\n';\n    xmlContent += '\\t<lenguajes>\\n';\n    data.lenguajes.forEach(lenguaje => {\n        xmlContent += `\\t\\t<lenguaje>${lenguaje}</lenguaje>\\n`;\n    });\n    xmlContent += '\\t</lenguajes>\\n';\n    xmlContent += '</persona>';\n    console.log(xmlContent);\n    fs.writeFileSync('miXML.xml', xmlContent);\n}\n\ncrearJSON(data);\ncrearXML(data);"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/javascript/ceciliarava1.js",
    "content": "/*\n Desarrolla un programa capaz de crear un archivo XML y JSON que guarde\n - Nombre\n - Edad\n - Fecha de nacimiento\n - Listado de lenguajes de programación\n Muestra el contenido de los archivos.\n Borra los archivos.\n */\n\nconst fs = require(\"fs\")\nconst readline = require(\"readline\")\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout,\n})\n\nfunction createFile(name, age, dateOfBirth, programmingLanguages, extension) {\n    if (extension == 'XML' || extension == 'JSON'){\n        fs.appendFile(\n            `person.${extension}`,\n            `Name: ${name} \\nAge: ${age} \\nDate of birth: ${dateOfBirth} \\nProgramming languages: ${programmingLanguages}`,\n            (err) => {\n                if (err) throw err\n            }\n        )\n    } else {\n        console.log('Type of extension not supported')\n    }\n}\n\nfunction deleteFile(extension) {\n    fs.unlink(`person.${extension}`, (err) => {\n        if (err) throw err\n        console.log(`File ${extension} deleted!`)\n    })\n}\n\nfunction showFile(extension) {\n    fs.readFile(`person.${extension}`, (err, data) => {\n        if (err) throw err\n        console.log(data.toString())\n        deleteFile('XML')\n        rl.close()\n    })\n}\n\ncreateFile(\"Lia\", 22, \"13/09/20\", \"python, rust\", 'XML')\nshowFile('XML')\n\n\n/*\n Utilizando la lógica de creación de los archivos anteriores, crea un\n programa capaz de leer y transformar en una misma clase custom de tu \n lenguaje los datos almacenados en el XML y el JSON.\n Borra los archivos.\n */\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/javascript/cesar-ch.js",
    "content": "/*\n  *  #12 JSON Y XML\n*/\n\nconst fs = require('fs').promises;\n\n// Datos a guardar\nconst datos = {\n    nombre: 'cesar-ch',\n    edad: 3,\n    fechaNacimiento: '2021-02-03',\n    lenguajes: ['JavaScript', 'Python', 'Java']\n};\n\nasync function main() {\n    // Guardar en archivo XML\n    const datosXML = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n    <datos>\n      <nombre>${datos.nombre}</nombre>\n      <edad>${datos.edad}</edad>\n      <fechaNacimiento>${datos.fechaNacimiento}</fechaNacimiento>\n      <lenguajes>${datos.lenguajes.join(',')}</lenguajes>\n    </datos>`;\n    await fs.writeFile('datos.xml', datosXML);\n    console.log('Archivo XML creado');\n\n    // Guardar en archivo JSON\n    const datosJSON = JSON.stringify(datos, null, 2);\n    await fs.writeFile('datos.json', datosJSON);\n    console.log('Archivo JSON creado');\n\n    /*\n       * DIFICULTAD EXTRA\n    */\n\n    // Leer archivo XML\n    const xmlData = await fs.readFile('datos.xml', 'utf8');\n    console.log('Contenido del archivo XML:', xmlData);\n\n    // Leer archivo JSON\n    const jsonData = await fs.readFile('datos.json', 'utf8');\n    console.log('Contenido del archivo JSON:', jsonData);\n\n    // Borrar archivo XML\n    await fs.unlink('datos.xml');\n    console.log('Archivo XML eliminado');\n\n    // Borrar archivo JSON\n    await fs.unlink('datos.json');\n    console.log('Archivo JSON eliminado');\n}\nmain();"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/javascript/christian-jfr.js",
    "content": "// #12 JSON Y XML\n\n/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n */\n\nconst fs = require('node:fs');\n\nconst dataJSON = {\n\tname: 'Christian',\n\tage: 21,\n\tbirthdate: {\n\t\tday: 1,\n\t\tmonth: 5,\n\t\tyear: 2003,\n\t},\n\tprogrammingLanguages: ['JavaScript', 'Python', 'C#', 'Java', 'C++'],\n};\nconst dataXML = `\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<data>\n    <name>${dataJSON.name}</name>\n    <age>${dataJSON.age}</age>\n    <birthdate>\n      <day>${dataJSON.birthdate.day}</day>\n      <month>${dataJSON.birthdate.month}</month>\n      <year>${dataJSON.birthdate.year}</year>\n    </birthdate>\n    <programmingLanguages>\n      <language>${dataJSON.programmingLanguages[0]}</language>\n      <language>${dataJSON.programmingLanguages[1]}</language>\n      <language>${dataJSON.programmingLanguages[2]}</language>\n      <language>${dataJSON.programmingLanguages[3]}</language>\n      <language>${dataJSON.programmingLanguages[4]}</language>\n    </programmingLanguages>\n</data>\n`;\n\nmain();\n\nfunction main() {\n\tsetTimeout(createJSONFile, 1000, dataJSON);\n\tsetTimeout(createXMLFile, 1500, dataXML);\n\t// setTimeout(deleteFiles, 2000);\n}\n\nfunction createJSONFile(data) {\n\tconst toJSON = JSON.stringify(data);\n\tfs.writeFile('data.json', toJSON, (err) => {\n\t\tif (err) {\n\t\t\tconsole.error(err);\n\t\t} else {\n\t\t\tconsole.log('\\n✅ JSON file has been created:\\n');\n\n\t\t\tfs.readFile('data.json', 'utf8', (err, data) => {\n\t\t\t\tif (err) {\n\t\t\t\t\tconsole.error(err);\n\t\t\t\t} else {\n\t\t\t\t\tconsole.log(data);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t});\n}\n\nfunction createXMLFile(data) {\n\tfs.writeFile('data.xml', data, (err) => {\n\t\tif (err) {\n\t\t\tconsole.error(err);\n\t\t} else {\n\t\t\tconsole.log('\\n✅ XML file has been created:');\n\n\t\t\tfs.readFile('data.xml', 'utf8', (err, data) => {\n\t\t\t\tif (err) {\n\t\t\t\t\tconsole.error(err);\n\t\t\t\t} else {\n\t\t\t\t\tconsole.log(data);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t});\n}\n\nfunction deleteFiles() {\n\tfs.unlink('data.json', (err) => {\n\t\tif (err) {\n\t\t\tconsole.error(err);\n\t\t} else {\n\t\t\tconsole.log('⚠️ JSON file has been deleted');\n\t\t}\n\t});\n\tfs.unlink('data.xml', (err) => {\n\t\tif (err) {\n\t\t\tconsole.error(err);\n\t\t} else {\n\t\t\tconsole.log('⚠️ XML file has been deleted');\n\t\t}\n\t});\n}\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu\n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n */\n\nclass Data {\n\tconstructor(name, age, birthdate, programmingLanguages) {\n\t\tthis.name = name;\n\t\tthis.age = age;\n\t\tthis.birthdate = birthdate;\n\t\tthis.programmingLanguages = programmingLanguages;\n\t}\n}\n\nsetTimeout(() => {\n\tfs.readFile('data.json', 'utf8', (err, data) => {\n\t\tif (err) {\n\t\t\tconsole.error(err);\n\t\t} else {\n\t\t\ttry {\n\t\t\t\tconst jsonData = JSON.parse(data);\n\n\t\t\t\tconst jsonClass = new Data(\n\t\t\t\t\tjsonData.name,\n\t\t\t\t\tjsonData.age,\n\t\t\t\t\tjsonData.birthdate,\n\t\t\t\t\tjsonData.programmingLanguages\n\t\t\t\t);\n\n\t\t\t\tconsole.log('JSON to Class:\\n', jsonClass);\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(error);\n\t\t\t}\n\t\t}\n\t});\n}, 2000);\n\nsetTimeout(() => {\n\tfs.readFile('data.xml', 'utf8', (err, data) => {\n\t\tif (err) {\n\t\t\tconsole.error(err);\n\t\t} else {\n\t\t\ttry {\n\t\t\t\tconst matchName = data.match(/<name>(.*?)<\\/name>/);\n\t\t\t\tconst name = matchName ? matchName[1] : '';\n\n\t\t\t\tconst matchAge = data.match(/<age>(.*?)<\\/age>/);\n\t\t\t\tconst age = matchAge ? parseInt(matchAge[1]) : 0;\n\n\t\t\t\tconst matchBirthdate = data.match(\n\t\t\t\t\t/<birthdate>\\s*<day>(\\d+)<\\/day>\\s*<month>(\\d+)<\\/month>\\s*<year>(\\d+)<\\/year>\\s*<\\/birthdate>/\n\t\t\t\t);\n\t\t\t\tconst birthdate = matchBirthdate\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tday: parseInt(matchBirthdate[1]),\n\t\t\t\t\t\t\tmonth: parseInt(matchBirthdate[2]),\n\t\t\t\t\t\t\tyear: parseInt(matchBirthdate[3]),\n\t\t\t\t\t  }\n\t\t\t\t\t: {};\n\n\t\t\t\tconst matchLanguages = data.match(\n\t\t\t\t\t/<programmingLanguages>([\\s\\S]*?)<\\/programmingLanguages>/\n\t\t\t\t);\n\t\t\t\tconst programmingLanguages = matchLanguages\n\t\t\t\t\t? matchLanguages[1]\n\t\t\t\t\t\t\t.match(/<language>(.*?)<\\/language>/g)\n\t\t\t\t\t\t\t.map(\n\t\t\t\t\t\t\t\t(language) => language.match(/<language>(.*?)<\\/language>/)[1]\n\t\t\t\t\t\t\t)\n\t\t\t\t\t: [];\n\n\t\t\t\tconst xmlCLass = new Data(name, age, birthdate, programmingLanguages);\n\t\t\t\tconsole.log('XML to Class:\\n', xmlCLass);\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(error);\n\t\t\t}\n\t\t}\n\t});\n}, 2500);\n\nsetTimeout(deleteFiles, 3000);\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/javascript/duendeintemporal.js",
    "content": "/* #12 JSON Y XML */\n//bibliography reference\n//Secrets of the JavaScript Ninja (John Resig, Bear Bibeault, Josip Maras) (z-lib.org)\n//Professional JavaScript for web developers by Matt Frisbie [Frisbie, Matt] (z-lib.org)\n//JavaScript Notes for Professionals (GoalKicker.com) (Z-Library)\n//GPT\n\n//Note: We will use Node.js and the xmldom and node-fetch libraries: you can do npm instal xmldom \n\n//JSON \n/*  JSON stands for \"JavaScript Object Notation\", but it's not JavaScript. Think of it as just a data serialization format that happens to be directly usable as a JavaScript literal. However, it is not advisable to directly run (i.e. through eval()) JSON that is fetched from an external source. Functionally, JSON isn't very different from XML or YAML – some confusion can be avoided if JSON is just imagined as some serialization format that looks very much like JavaScript.*/\n/* Even though the name implies just objects, and even though the majority of use cases through some kind of API always happen to be objects and arrays, JSON is not for just objects or arrays.  */\n\n/* JSON.parse Parse a JSON string\nreviver(function) Prescribes a transformation for the input JSON string.\nJSON.stringify Serialize a serializable value\nreplacer(function or String[] or Number[]) Selectively includes certain properties of the value object.\nspace(String or Number) If a number is provided, then space number of whitespaces will be\ninserted of readability. If a string is provided, the string (first 10 characters) will be used as whitespaces. */\n\n// JSON versus JavaScript literals\n/*While some JSON is also valid JavaScript and some JavaScript is also valid JSON, there are some subtle differences between both languages and neither language is a subset of the other. */\n//JSON\n//{\"nickname\": \"mytic.dragon\"}\n\n//short for console.log\nlet log = console.log\n\n//This can be directly inserted into JavaScript. It will be syntactically valid and will yield the correct value:\nconst nickname = {\"nickname\": \"mytic.dragon\"};\n\n//However, we know that \"nickname\" is a valid identifier name and the quotes around the property name can be omitted:\n\n//const nickname = {nickname: \"mytic.dragon\"};\n\n//We also know that we can use single quotes instead of double quotes:\n\n//const nickname = {'nickname': 'mytic.dragon'};\n\n//But, if we were to take both of these literals and treat them as JSON, neither will be syntactically valid JSON:\n\n//{nickname: \"mytic.dragon\"}\n//{'nickname': 'mytic.dragon'}\n\n/*JSON strictly requires all property names to be double quoted and string values to be double quoted as well.\n It's common for newcomers to JSON to attempt to use JavaScript object literals as JSON,\n leading to syntax errors when using a JSON parser.*/\n\n //You will need to add a extension to allow Cross-Origin Resourse Sharing(CORS)\n  //  Node.js doesn't implement the fetch API natively. You can install it using: npm install node-fetch. I will coment the next code to avoid conflicts\n\n//  let numberOfParagraphs = 2;\n//  let url = `https://baconipsum.com/api/?type=meat-and-filler&paras=${numberOfParagraphs}`;\n \n//  fetch(url)\n//      .then(response => {\n//          if (!response.ok) {\n//              throw new Error(`HTTP error! status: ${response.status}`);\n//          }\n//          return response.json();\n//      })\n//      .then(loremIpsumTextArray => {\n//          log(loremIpsumTextArray); \n//      })\n//      .catch(error => {\n//          console.error(error); \n//      });\n \n/*In the above example, response is a JSON string that is returned by some API. JSON stops at the HTTP response domain.  (could be an object, an array, or even a simple number!)  */\n\n\n/* Developers often use the phrase \"JSON object,\" which can lead to confusion. \n   A more accurate term is \"JSON string,\" as it refers to the serialized format. \n   After parsing, you end up with a JavaScript value (object, array, etc.). \n   Just like \"XML string\" or \"YAML string,\" you get a string, parse it, and obtain a value. */\n\n// Parsing with a reviver function. A reviver function can be used to filter or transform the value being parsed.\n\n/*var jsonString = '[{\"name\":\"Kox\",\"age\":51},{\"name\":\"Fanny\",\"age\":17}]';\nvar data = JSON.parse(jsonString, function reviver(key, value) {\nreturn key === 'name' ? value.toUpperCase() : value;\n});*/\n\n//or with arrow functions\n\nconst jsonString = '[{\"name\":\"Kox\",\"age\":51},{\"name\":\"Fanny\",\"age\":17}]';\nconst data = JSON.parse(jsonString, (key, value) => key === 'name' ? value.toUpperCase() : value );\nlog(data); // [{name:\"KOX\", age:51},{name:\"FANNY\", age:17}]\n\n/*This is particularly useful when data must be sent that needs to be serialized/encoded when being transmitted with JSON, but one wants to access it deserialized/decoded. In the following example, a date was encoded to its ISO 8601 representation. We use the reviver function to parse this in a JavaScript Date.*/\n\nconst jsonString2 = '{\"date\":\"2024-10-12T12:28:40.143Z\"}';\nconst data2 = JSON.parse(jsonString2, (key, value) => key === 'date' ? new Date(value) : value);\nlog(data2); // {date: 2024-10-12T12:28:40.143Z}\n\n/*It is important to make sure the reviver function returns a useful value at the end of each iteration. If the reviver function returns undefined, no value or the execution falls off towards the end of the function, the property is deleted from the object. Otherwise, the property is redefined to be the return value.*/\n\n//A JavaScript value can be converted to a JSON string using the JSON.stringify function.\n//JSON.stringify(value[, replacer[, space]])\n\n/* Boolean */\nlog(JSON.stringify(true)); // 'true'\n/* Number */ \nlog(JSON.stringify(154)); // '154'\n/* String */ \nlog(JSON.stringify('roadmap')); // '\"roadmap\"'\n/* Object */ \nlog(JSON.stringify({})); // '{}'\nlog(JSON.stringify({name: 'Any'})); // '{\"name\": \"Any\"}'\n/* Array */ \nlog(JSON.stringify([41, true, 'System Ingeniering'])); // '[41, true, \"System Ingeniering\"]'\n/* Date */ \nlog(JSON.stringify(new Date())); // '\"2016-08-06T17:25:23.588Z\"'\n/* Symbol */ \nlog(JSON.stringify({x:Symbol()})); // '{}'\n\n/*replacer A function that alters the behaviour of the stringification process or an array of String and Number2. objects that serve as a whitelist for filtering the properties of the value object to be included in the JSON string. If this value is null or is not provided, all properties of the object are included in the resulting JSON string. */\n// replacer as a function\nfunction notStrValues (key, value) {\n    if (typeof value === \"string\") {\n        return\n    } \n    return value\n}\n\nlet crew = { background: \"Retosparaprogramadores\", model: \"weekly\", week: 12, language: \"javascript\", month: 3 }\nlog(JSON.stringify(crew, notStrValues)); //  '{\"week\": 45, \"month\": 7}'\n\n// replacer as an array\nlog(JSON.stringify(crew, ['background', 'week', 'month'])); //  '{\"background\": \"Retosparaprogramadores\", \"week\": 12, \"month\": 3}'\n// only the `background`, `week`, and `month` properties are kept\n\n// indentation may be specified as the third parameter.\nlog(JSON.stringify({x: 4, y: 4}, null, 2)); // 2 space characters will be used for indentation\n/* output:\n{\n  'x': 4,\n  'y': 4\n}\n*/\n//Alternatively, a string value can be provided to use for indentation. For example, passing '\\t' will cause the tab character to be used for indentation.\nlog(JSON.stringify({x: 4, y: 4}, null, '\\t'));\n/* output:\n{\n    'x': 4,\n    'y': 4\n}\n*/\n\n//Exercises\nconst fs = require('fs');\nconst path = require('path');\nconst { DOMParser } = require('xmldom'); // you need to do a: npm install xmldom\n\n//Note: DOMParser API doesn't have natively implementation on Node.js]\n\n// Data to storage\nconst data1 = {\n    name: \"Niko Zen\",\n    age: 30,\n    birthDate: \"1983-08-08\",\n    languages: [\"JavaScript\", \"Python\", \"Ruby\", \"Rust\", \"Bash\"]\n};\n\n// Function to create a JSON file\nfunction createJSON(data) {\n    const jsonData = JSON.stringify(data, null, 2);\n    fs.writeFileSync(path.join(__dirname, 'data.json'), jsonData);\n    log(\"Content of the JSON file:\");\n    log(jsonData);\n}\n\n// Function to create an XML file\nfunction createXML(data) {\n    const xmlData = `\n<person>\n    <name>${data.name}</name>\n    <age>${data.age}</age>\n    <birthDate>${data.birthDate}</birthDate>\n    <languages>\n        ${data.languages.map(lang => `<language>${lang}</language>`).join('')}\n    </languages>\n</person>`;\n    fs.writeFileSync(path.join(__dirname, 'data.xml'), xmlData);\n    log(\"Content of the XML file:\");\n    log(xmlData);\n}\n\n// Function to delete files\nfunction deleteFiles() {\n    fs.unlinkSync(path.join(__dirname, 'data.json'));\n    fs.unlinkSync(path.join(__dirname, 'data.xml'));\n    log(\"Files deleted.\");\n}\n\n// Custom class\nclass Person {\n    constructor(name, age, birthDate, languages) {\n        this.name = name;\n        this.age = age;\n        this.birthDate = birthDate;\n        this.languages = languages;\n    }\n}\n\n// Function to read and transform data\nfunction readAndTransform() {\n    const jsonData = JSON.parse(fs.readFileSync(path.join(__dirname, 'data.json')));\n    const xmlData = fs.readFileSync(path.join(__dirname, 'data.xml'), 'utf-8');\n\n    // Transform XML to object\n    const parser = new DOMParser();\n    const xmlDoc = parser.parseFromString(xmlData, \"text/xml\");\n    const name = xmlDoc.getElementsByTagName(\"name\")[0].textContent;\n    const age = parseInt(xmlDoc.getElementsByTagName(\"age\")[0].textContent);\n    const birthDate = xmlDoc.getElementsByTagName(\"birthDate\")[0].textContent;\n    const languages = Array.from(xmlDoc.getElementsByTagName(\"language\")).map(lang => lang.textContent);\n\n    // Create an instance of Person\n    const person = new Person(name, age, birthDate, languages);\n    log(\"Data transformed to Person class:\");\n    log(person);\n}\n\n// Program execution\ncreateJSON(data1);\ncreateXML(data1);\nreadAndTransform();\ndeleteFiles();\n\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/javascript/emedevelopa.js",
    "content": "const fs = require (\"fs\");\n\n//Creación de datos para almacenar\nconst datos = {\n    nombre: \"Maria\",\n    edad: 33,\n    fechaNacimiento: \"8/12/1990\",\n    lenguajes: [\"HTML\", \"CSS\", \"JavaScript\"]\n};\n\n//Funciones para crear ambos archivos\nfunction escribirXML (datos) {\n    const xmlDatos = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n    <datos>\n        <nombre>${datos.nombre}</nombre>\n        <edad>${datos.edad}</edad>\n        <fechaNacimiento>${datos.fechaNacimiento}</fechaNacimiento>\n        <lenguajes>\n        ${datos.lenguajes.map(lenguaje => `<lenguaje>${lenguaje}</lenguaje>`).join(\"\\n    \")}\n        </lenguajes>\n    </datos>`;\n\n    fs.writeFileSync(\"datos.xml\", xmlDatos);\n    console.log(\"Archivo XML creado.\");\n}\n\nfunction escribirJSON (datos) {\n    fs.writeFileSync(\"datos.json\", JSON.stringify(datos, null, 2));\n    console.log(\"Archivo JSON creado.\")\n}\n\nescribirJSON(datos);\nescribirXML(datos);\n\n//Funciones para leer y mostrar el contenido de los archivos\nfunction mostrarXML() {\n    const xmlDatos = fs.readFileSync(\"datos.xml\", \"utf-8\");\n    console.log(\"Contenido del archivo XML: \" + xmlDatos);\n\n}\n\nfunction mostrarJSON () {\n    const jsonDatos = fs.readFileSync(\"datos.json\", \"utf-8\");\n    console.log(\"Contenido del archivo JSON: \" + jsonDatos);\n}\n\nmostrarXML();\nmostrarJSON();\n\n//Funciones para borrar archivos\nfunction borrarArchivos () {\n    fs.unlinkSync(\"datos.xml\");\n    fs.unlinkSync(\"datos.json\");\n    console.log(\"Archivos borrados con éxito.\")\n}\n\nborrarArchivos();"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/javascript/eulogioep.js",
    "content": "const fs = require('fs');\nconst xml2js = require('xml2js');\n\n// Datos de ejemplo\nconst persona = {\n    nombre: \"Juan\",\n    edad: 30,\n    fechaNacimiento: \"1993-05-15\",\n    lenguajesProgramacion: [\"JavaScript\", \"Python\", \"Ruby\"]\n};\n\n// Función para crear el archivo XML\nfunction crearArchivoXML(datos) {\n    const builder = new xml2js.Builder();\n    const xml = builder.buildObject({ persona: datos });\n    fs.writeFileSync('datos.xml', xml);\n    console.log(\"Archivo XML creado.\");\n}\n\n// Función para crear el archivo JSON\nfunction crearArchivoJSON(datos) {\n    fs.writeFileSync('datos.json', JSON.stringify(datos, null, 2));\n    console.log(\"Archivo JSON creado.\");\n}\n\n// Función para mostrar el contenido de un archivo\nfunction mostrarContenidoArchivo(nombreArchivo) {\n    console.log(`Contenido del archivo ${nombreArchivo}:`);\n    console.log(fs.readFileSync(nombreArchivo, 'utf8'));\n}\n\n// Función para borrar un archivo\nfunction borrarArchivo(nombreArchivo) {\n    fs.unlinkSync(nombreArchivo);\n    console.log(`El archivo ${nombreArchivo} ha sido borrado.`);\n}\n\n// Función para leer el archivo XML\nfunction leerXML(nombreArchivo) {\n    const xmlData = fs.readFileSync(nombreArchivo, 'utf8');\n    return new Promise((resolve, reject) => {\n        xml2js.parseString(xmlData, (err, result) => {\n            if (err) {\n                reject(err);\n            } else {\n                resolve(result.persona);\n            }\n        });\n    });\n}\n\n// Función para leer el archivo JSON\nfunction leerJSON(nombreArchivo) {\n    const jsonData = fs.readFileSync(nombreArchivo, 'utf8');\n    return JSON.parse(jsonData);\n}\n\n// Función principal asíncrona\nasync function main() {\n    // Crear y mostrar archivo XML\n    crearArchivoXML(persona);\n    mostrarContenidoArchivo('datos.xml');\n\n    // Crear y mostrar archivo JSON\n    crearArchivoJSON(persona);\n    mostrarContenidoArchivo('datos.json');\n\n    // Borrar archivos\n    borrarArchivo('datos.xml');\n    borrarArchivo('datos.json');\n\n    // DIFICULTAD EXTRA\n    // Crear archivos nuevamente para la lectura\n    crearArchivoXML(persona);\n    crearArchivoJSON(persona);\n\n    // Leer y transformar datos\n    try {\n        const personaXML = await leerXML('datos.xml');\n        const personaJSON = leerJSON('datos.json');\n\n        console.log(\"\\nDatos leídos del XML:\");\n        console.log(personaXML);\n        console.log(\"\\nDatos leídos del JSON:\");\n        console.log(personaJSON);\n    } catch (error) {\n        console.error(\"Error al leer los archivos:\", error);\n    }\n\n    // Borrar archivos nuevamente\n    borrarArchivo('datos.xml');\n    borrarArchivo('datos.json');\n}\n\n// Ejecutar la función principal\nmain().catch(console.error);"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/javascript/garos01.js",
    "content": "const fs = require(\"fs\");\n\n// Datos a guardar\nconst datos = {\n  nombre: \"Oscar\",\n  edad: 29,\n  fechaNacimiento: \"11-09-1994\",\n  lenguajes: [\"JavaScript\", \"Python\"],\n};\n\n// Convertir datos a XML\nconst convertirAXML = (datos) => {\n  let xml = '<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n';\n  xml += \"<persona>\\n\";\n  for (const key in datos) {\n    if (Array.isArray(datos[key])) {\n      xml += `<${key}>\\n`;\n      datos[key].forEach((item) => {\n        xml += `<lenguaje>${item}</lenguaje>\\n`;\n      });\n      xml += `</${key}>\\n`;\n    } else {\n      xml += `<${key}>${datos[key]}</${key}>\\n`;\n    }\n  }\n  xml += \"</persona>\";\n  return xml;\n};\n\n// Convertir datos a JSON\nconst convertirAJSON = (datos) => {\n  return JSON.stringify(datos, null, 2);\n};\n\n// Crear archivos XML y JSON\nfs.writeFileSync(\"datos.xml\", convertirAXML(datos), \"utf-8\");\nfs.writeFileSync(\"datos.json\", convertirAJSON(datos), \"utf-8\");\n\n// Mostrar contenido de archivos\nconsole.log(\"Contenido de datos.xml:\");\nconsole.log(fs.readFileSync(\"datos.xml\", \"utf-8\"));\n\nconsole.log(\"\\nContenido de datos.json:\");\nconsole.log(fs.readFileSync(\"datos.json\", \"utf-8\"));\n\n// Borrar archivos\nfs.unlinkSync(\"datos.xml\");\nfs.unlinkSync(\"datos.json\");\n\nconsole.log(\"\\nArchivos borrados.\");\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/javascript/hectorio23.js",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n \n\"use strict\";\n\nconst fs = require('fs');\n\n// Función para crear un archivo JSON con los datos proporcionados\nfunction createJSON(name, age, dob, languages) {\n    const data = {\n        Name: name,\n        Age: age,\n        DateOfBirth: dob,\n        ProgrammingLanguages: languages\n    };\n\n    fs.writeFileSync('./Person.json', JSON.stringify(data, null, 4));\n}\n\n// Función para mostrar el contenido de un archivo\nfunction displayFileContents(filename) {\n    try {\n        const content = fs.readFileSync(filename, 'utf8');\n        console.log(`Contents of ${filename}:`);\n        console.log(content);\n    } catch (error) {\n        console.error(`Unable to read file: ${filename}`, error);\n    }\n}\n\n// Función para borrar los archivos generados\nfunction deleteFiles() {\n    try {\n        fs.unlinkSync('./Person.json');\n    } catch (error) {\n        console.error(`Unable to delete file: ./Person.json`, error);\n    }\n}\n\nfunction main() {\n    const name = \"Héctor Adán\";\n    const age = 19;\n    const dob = \"2004-06-28\";\n    const languages = [\"C++\", \"Python\", \"JavaScript\"];\n\n    // Crear archivo JSON con los datos proporcionados\n    createJSON(name, age, dob, languages);\n\n    // Mostrar el contenido del archivo creado\n    displayFileContents('./Person.json');\n\n    // Borrar el archivo generado\n    deleteFiles();\n}\n\nmain();\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n_______________________________________\n#12 JSON Y XML\n---------------------------------------\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu\n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n*/\n\n// ________________________________________________________\nimport { writeFile, readFile, unlink } from \"fs/promises\";\nimport { extname } from \"path\";\nimport { parseStringPromise, Builder } from \"xml2js\";\n\n// Datos iniciales\nconst dictUser = {\n    name: \"Ken\",\n    age: 121,\n    dob: \"1903-03-19\",\n    prog_langs: [\"cs\", \"py\", \"vb\", \"rs\", \"js\"],\n};\n\n(async () => {\n    try {``\n        //____________________________________\n        // * JSON\n\n        // Serialización: Convertir objeto a JSON\n        const jsonUser = JSON.stringify(dictUser, null, 4);\n\n        // Crear archivo JSON\n        await writeFile(\"user.json\", jsonUser, \"utf8\");\n        console.log(\"Archivo JSON creado.\");\n\n        // Deserialización: Leer y convertir JSON a objeto\n        const jsonData = await readFile(\"user.json\", \"utf8\");\n        const parsedJson = JSON.parse(jsonData);\n        console.log(\"Objeto cargado desde JSON:\", parsedJson);\n\n        //____________________________________\n        // * XML\n\n        // Serialización: Crear XML a partir de objeto\n        const builder = new Builder();\n        const xmlUser = builder.buildObject({ user: dictUser });\n\n        // Crear archivo XML\n        await writeFile(\"user.xml\", xmlUser, \"utf8\");\n        console.log(\"Archivo XML creado.\");\n\n        // Deserialización: Leer y convertir XML a objeto\n        const xmlData = await readFile(\"user.xml\", \"utf8\");\n        const parsedXml = await parseStringPromise(xmlData);\n        console.log(\"Objeto cargado desde XML:\", parsedXml.user);\n\n        //____________________________________\n        // DIFICULTAD EXTRA\n\n        class XmlOrJson {\n            constructor(filePath) {\n                this.filePath = filePath;\n                this.extension = extname(filePath).toLowerCase();\n                this.data = {};\n            }\n\n            async asDict() {\n                try {\n                    if (this.extension === \".json\") {\n                        const jsonContent = await readFile(this.filePath, \"utf8\");\n                        this.data = JSON.parse(jsonContent);\n                        console.log(\"Archivo JSON cargado correctamente.\");\n                    } else if (this.extension === \".xml\") {\n                        const xmlContent = await readFile(this.filePath, \"utf8\");\n                        const parsedXml = await parseStringPromise(xmlContent);\n                        this.data = parsedXml.user;\n                        console.log(\"Archivo XML cargado correctamente.\");\n                    } else {\n                        throw new Error(\"Extensión de archivo no soportada.\");\n                    }\n                    return this.data;\n                } catch (error) {\n                    console.error(\"Error al cargar archivo:\", error.message);\n                }\n            }\n        }\n\n        //____________________________________\n        console.log(\"\\nDIFICULTAD EXTRA\\n\");\n\n        // Leer JSON\n        const jsonFile = new XmlOrJson(\"user.json\");\n        const jsonDict = await jsonFile.asDict();\n        console.log(\"Datos desde JSON:\", jsonDict);\n\n        // Leer XML\n        const xmlFile = new XmlOrJson(\"user.xml\");\n        const xmlDict = await xmlFile.asDict();\n        console.log(\"Datos desde XML:\", xmlDict);\n\n        // Eliminar archivos\n        await unlink(\"user.json\");\n        await unlink(\"user.xml\");\n        console.log(\"Archivos eliminados.\");\n    } catch (error) {\n        console.error(\"Error general:\", error.message);\n    }\n})();\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/javascript/ocram1304.js",
    "content": "//JSON\nconst fs = require(\"fs\");\n\n// Definir el nombre del archivo de texto\nconst fileNameTxt = \"fileNameTXT.txt\";\n\n// Objeto JSON\nconst objetoJson = {\n    nombre: \"ocram1304\",\n    edad: 24,\n    fechaCumple: \"13/04/2000\",\n    lenguajes: ['JavaScript']\n};\n\n// Convertir el objeto a una cadena de texto JSON\nconst txtString = JSON.stringify(objetoJson,null,2);\n\n// Escribir la cadena de texto en el archivo\nfs.writeFileSync(fileNameTxt, txtString, (err) => {\n    if (err) throw err;\n    console.log(\"El archivo de texto ha sido creado correctamente\");\n});\n\n// Leer los datos del archivo de texto\nconst datosTxt = fs.readFileSync(fileNameTxt, \"utf-8\");\n\n// Mostrar los datos de texto en la consola\nconsole.log(datosTxt);\n\n\n\n//XML\n\nconst xmlbuilder = require(\"xmlbuilder\");\n\n// Definir el nombre del archivo XML\nconst fileNameXml = \"fileNameXML.txt\"; \n\n// Crear el documento XML con xmlbuilder\nconst xmlDoc = xmlbuilder.create({ version: '1.0' })\n  .ele('root')\n    .ele('Nombre', 'ocram1304').up()\n    .ele('Edad', '24').up()\n    .ele('FechaCumple','13/04/2000').up()\n    .ele('Lenguajes','JavaScript')\n  .end({ prettyPrint: true });\n\n// Escribir los datos XML en el archivo\nfs.writeFileSync(fileNameXml, xmlDoc, (err) => {\n    if (err) throw err;\n    console.log(\"El archivo XML ha sido creado correctamente\");\n});\n\n// Leer los datos del archivo XML\nconst datosXml = fs.readFileSync(fileNameXml, \"utf-8\");\n\n// Mostrar los datos XML en la consola\nconsole.log(datosXml);\n\n\n\n\n//Difucultad extra\n\nclass JSONYXML {\n    nombre;\n    edad; \n    fechaCumple;\n    lenguajes;\n\n    constructor(nombre,edad,fechaCumple,lenguajes){\n       this.nombre = nombre;\n       this.edad = edad;\n       this.fechaCumple = fechaCumple;\n       this.lenguajes = lenguajes;\n    }\n\n    \n    transformarJSON(){\n       const recursoJSON =  fs.readFileSync(fileNameTxt,\"utf-8\");\n       const objetoJson = JSON.parse(recursoJSON);\n       this.nombre = objetoJson.nombre;\n       this.edad = objetoJson.edad;\n       this.fechaCumple = objetoJson.fechaCumple;\n       this.lenguajes = objetoJson.lenguajes;\n       \n    }\n    transformarXML() {\n        const xml2js = require(\"xml2js\");\n    \n        return new Promise((resolve, reject) => {\n            const recursoXML = fs.readFileSync(fileNameXml, \"utf-8\");\n            xml2js.parseString(recursoXML, (err, res) => {\n                if (err) {\n                    console.error(\"Error al analizar el XML:\", err);\n                    reject(err);\n                } else {\n                    resolve(res);\n                }\n            });\n        }).then(objXML => {\n            // Verificar si objXML es un objeto válido\n            if (objXML && typeof objXML === \"object\") {\n                this.nombre = objXML.root.Nombre;\n                this.edad = objXML.root.Edad;\n                this.fechaCumple = objXML.root.FechaCumple;\n                this.lenguajes = objXML.root.Lenguajes;\n            } else {\n                console.error(\"El objeto XML no es válido.\");\n            }\n        }).catch(error => {\n            console.error(\"Error al transformar el XML:\", error);\n        });\n    }\n    \n\n    Mostrardatos(){\n\n        if(this.nombre !== undefined || this.edad !== undefined || this.fechaCumple !== undefined || this.lenguajes !== undefined){\n           const objMuestra = {\n            nombre: this.nombre,\n            edad: this.edad,\n            fechaCumple: this.fechaCumple,\n            lenguajes: this.lenguajes\n\n        };\n        console.log(objMuestra); \n        }\n        else{\n            console.log(\"No hay datos disponibles para mostrar\");\n        }\n    }\n    borrrarJSON(){\n        fs.unlink(fileNameTxt);\n    }\n    borrarXML(){\n        fs.unlink(fileNameXml);\n    }\n}\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/javascript/parababire.js",
    "content": "const fs = require(\"fs\");\nconst xml2js = require(\"xml2js\");\nconst parseString = require(\"xml2js\").parseString;\nconst {Builder} = require(\"xml2js\");\nconst xmlFile = \"parababire.xml\";\nconst jsonFile = \"parababire.json\";\n\nconst persona = {\n  nombre: \"Ángel\",\n  edad: 44,\n  fechaNacimiento: \"16-09-1979\",\n  lenguajes: {\n    item: [\n        \"JavaScript\",\n        \"Python\"\n    ]\n}\n}\n\n//Convirtiendo un objeto en un fichero.xml\n\nfunction guardarXml() {\n  const builder = new Builder();\n  const xml = builder.buildObject(persona);\n\n  fs.writeFileSync(xmlFile, xml);\n}\nguardarXml();\n\nconst xmlData = fs.readFileSync(xmlFile, \"utf8\");\nconsole.log(xmlData);\n\nfs.unlink(xmlFile, err => {\n  if (err) throw err;\n  console.log(\"Archivo borrado\");\n});\n\n//Convirtiendo un objeto a JSON\n\nfunction crearJson() {\n  const string = JSON.stringify(persona);\n  fs.writeFileSync(jsonFile, string);\n}\ncrearJson();\n\nconst data = fs.readFileSync(jsonFile, \"utf8\");\nconsole.log(data);\n\nfs.unlink(jsonFile, err => {\n  if (err) throw err;\n  console.log(\"Archivo borrado\");\n});\n\n\n//Extra\nguardarXml();\ncrearJson();\n\nconst parser = new xml2js.Parser();\nconst objDataFromXml = parseString(xmlData, function (err, result) {\n  console.dir(result);\n});\n\nconst objDataFromJson = JSON.parse(data);\nconsole.log(objDataFromJson);"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/javascript/pedamoci.js",
    "content": "import  fs  from \"fs\"\nimport  readline  from \"readline\";\n\nfunction preguntar(pregunta) {\n  const rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n  })\n\n  return new Promise(resolve => {\n    rl.question(pregunta, (respuesta) => {\n      rl.close()\n      resolve(respuesta)\n    })\n  })\n}\n\n\nasync function crearArchivo(tipo) {\n  if (tipo === 'JSON') {\n    let nombre = await preguntar('Ingrese su nombre: ')\n    let edad = await preguntar('Ingrese su edad: ')\n    let fechaNacimiento = await preguntar('Ingrese su fecha de nacimiento (xx/xx/xx): ')\n    let lenguajesProgramacion = await preguntar('Ingrese los lenguajes de programación (lenguaje1, lenguaje2, ...): ')\n    fs.writeFileSync('archivo.json', `{ \"usuario\": {` + \n                                                    `\\n    \"nombre\": \"${nombre}\",` + \n                                                    `\\n    \"edad\": \"${edad}\",` +\n                                                    `\\n    \"fechaDeNacimiento\": \"${fechaNacimiento}\",` +\n                                                    `\\n    \"lenguajes\": {`)\n    lenguajesProgramacion = lenguajesProgramacion.split(', ')\n    for (let i = 0; i < lenguajesProgramacion.length; i++) {\n      if (i === lenguajesProgramacion.length - 1) fs.appendFileSync('archivo.json', `\\n      \"lenguaje${i + 1}\": \"${lenguajesProgramacion[i]}\"`)\n      else fs.appendFileSync('archivo.json', `\\n      \"lenguaje${i + 1}\": \"${lenguajesProgramacion[i]}\",`)\n    }\n    fs.appendFileSync('archivo.json', `\\n    }` +\n                                      `\\n  }` +\n                                      `\\n}`)\n    console.log(fs.readFileSync('archivo.json', 'utf-8'))\n    fs.unlinkSync('./archivo.json')\n  } else if (tipo === 'XML') {\n    let nombre = await preguntar('Ingrese su nombre: ')\n    let edad = await preguntar('Ingrese su edad: ')\n    let fechaNacimiento = await preguntar('Ingrese su fecha de nacimiento (xx/xx/xx): ')\n    let lenguajesProgramacion = await preguntar('Ingrese los lenguajes de programación (lenguaje1, lenguaje2, ...): ')\n    fs.writeFileSync('archivo.xml', `<?xml version=\"1.0\" encoding=\"UTF-8\"?>` + \n                                                    `\\n<usuario>` + \n                                                    `\\n  <nombre>${nombre}</nombre>` + \n                                                    `\\n  <edad>${edad}</edad>` +\n                                                    `\\n  <fechaDeNacimiento>${fechaNacimiento}</fechaDeNacimiento>` +\n                                                    `\\n  <lenguajes>`)\n    lenguajesProgramacion = lenguajesProgramacion.split(', ')\n    for (let i = 0; i < lenguajesProgramacion.length; i++) {\n      fs.appendFileSync('archivo.xml', `\\n    <lenguaje${i + 1}>${lenguajesProgramacion[i]}</lenguaje${i + 1}>`)\n    }\n    fs.appendFileSync('archivo.xml', `\\n  </lenguajes>` +\n                                      `\\n</usuario>`)\n    console.log(fs.readFileSync('archivo.xml', 'utf-8'))\n    fs.unlinkSync('./archivo.xml')\n  }\n}\n\nlet tipo = await preguntar('Quieres crear el archivo en \"XML\" o \"JSON\"')\ntipo = tipo.toUpperCase()\ncrearArchivo(tipo)\n\n// ------------------------------------- DIFICULTAD EXTRA -------------------------------------\n// los imports de fs y readline estan arriba\nclass Persona {\n  constructor(nombre, edad, fechaNacimiento, lenguajes) {\n    this.nombre = nombre\n    this.edad = edad\n    this.fechaNacimiento = fechaNacimiento\n    this.lenguajes = lenguajes\n  }\n\n  mostrarDatos() {\n    console.log(`nombre: ${this.nombre}`)\n    console.log(`edad: ${this.edad}`)\n    console.log(`fechaDeNacimiento: ${this.fechaNacimiento}`)\n    console.log(`lenguajes: ${this.lenguajes.join(', ')}`)\n  }\n}\n\nfunction transformar(nombreArchivo) {\n  if (nombreArchivo.endsWith('.json')) {\n    let archivo = fs.readFileSync(`${nombreArchivo}`, 'utf-8')\n    let datos = JSON.parse(archivo)\n    let lenguajes = Object.values(datos.usuario.lenguajes)\n    const persona = new Persona (datos.usuario.nombre, datos.usuario.edad, datos.usuario.fechaDeNacimiento, lenguajes)\n    persona.mostrarDatos()\n    fs.unlinkSync(`./${nombreArchivo}`)\n  } else if (nombreArchivo.endsWith('.xml')) {\n    let archivo = fs.readFileSync(`${nombreArchivo}`, 'utf-8')\n    let nombre = archivo.match(/<nombre>([^<]+)<\\/nombre>/)[1] // busca las etiquetas <nombre></nombre> y devuelve lo que haya en el medio\n    let edad = archivo.match(/<edad>([^<]+)<\\/edad>/)[1]  // busca las etiquetas <edad></edad> y devuelve lo que haya en el medio\n    let fecha = archivo.match(/<fechaDeNacimiento>([^<]+)<\\/fechaDeNacimiento>/)[1] // busca las etiquetas <fechaDeNacimiento></fechaDeNacimiento> y devuelve lo que haya en el medio\n    let lenguajes = archivo.match(/<lenguajes>([\\s\\S]*?)<\\/lenguajes>/)[1] // busca las etiquetas <lenguajes></lenguajes> y devuelve lo que haya en el medio\n    lenguajes = lenguajes.replace(/<\\/?[^>]+>/g, '') // remplaza '<', '/', '>' y lo que haya entre medio de '<' y '>' junto con lo que esta entre '</' y '>'\n    lenguajes = lenguajes.match(/(?<![\\w#+])([\\w#+]+)(?![\\w#+])/g) // busca todas las palabras que tengan un salto de line o espacio antes y despues\n    const persona = new Persona (nombre, edad, fecha, lenguajes)\n    persona.mostrarDatos()\n    fs.unlinkSync(`./${nombreArchivo}`)\n  }\n}\ntransformar(await preguntar('Ingrese el nombre del archivo con la extension (\".json\" o \".xml\")'))"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/javascript/qwik-zgheib.js",
    "content": "/* -- exercise */\nimport fs from \"fs\";\n\nconst content = {\n  name: \"Qwik Zgheib\",\n  age: 22,\n  birthdate: \"2002-11-09\",\n  programmingLanguages: [\"JavaScript\", \"Typescript\", \"Python\"],\n};\n\nconst exerciseMain = {\n  createfile: (filename, content, type = \"json\") => {\n    try {\n      const jsonContent = JSON.stringify(content);\n      if (type === \"json\") fs.writeFileSync(`${filename}.json`, jsonContent);\n      if (type === \"xml\") {\n        const xmlContent = `<data>\n          <name>${content.name}</name>\n          <age>${content.age}</age>\n          <birthdate>${content.birthdate}</birthdate>\n          <programmingLanguages>\n            ${content.programmingLanguages.map((lang) => `<language>${lang}</language>`).join(\"\")}\n          </programmingLanguages>\n        </data>`;\n        fs.writeFileSync(`${filename}.xml`, xmlContent);\n      }\n    } catch (error) {\n      console.error(error);\n    }\n  },\n  readFile: (filename) => {\n    try {\n      const jsonContent = fs.readFileSync(`${filename}.json`, \"utf-8\");\n      const xmlContent = fs.readFileSync(`${filename}.xml`, \"utf-8\");\n      console.log(`Reading ${filename}.json\\n`, jsonContent);\n      console.log(`\\nReading ${filename}.xml\\n`, xmlContent);\n    } catch (error) {\n      console.error(error);\n    }\n  },\n  deleteFile: (filename) => {\n    try {\n      console.log(\"Deleting files...\");\n      fs.unlinkSync(`${filename}.json`);\n      fs.unlinkSync(`${filename}.xml`);\n    } catch (error) {\n      console.error(error);\n    }\n  },\n};\n\nexerciseMain.createfile(\"data\", content, \"json\");\nexerciseMain.createfile(\"data\", content, \"xml\");\n\nexerciseMain.readFile(\"data\");\nexerciseMain.deleteFile(\"data\");\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/javascript/raulG91.js",
    "content": "const fs = require('fs').promises\nconst path = require('path')\nconst xml2js = require('xml2js')\n\n\nlet json_data = {\n    \"name\": \"Raul\",\n    \"age\": 33,\n    \"birth_date\": \"11/09/1991\",\n    \"languages\": [\"Python\", \"Javascript\", \"Abap\"]\n};\n\nasync function createJSONFile(filename, data) {\n\n    path_file = path.join(__dirname, filename);\n    await fs.writeFile(path_file, JSON.stringify(data))\n\n}\nasync function readJSONFile(filename) {\n\n    let path_file = path.join(__dirname, filename);\n    let data = await fs.readFile(path_file);\n    object = JSON.parse(String(data))\n    return object;\n}\nasync function deleteFile(filename) {\n\n    let path_file = path.join(__dirname, filename);\n    await fs.unlink(path_file);\n}\n\nasync function createXMLfile(filename, data) {\n\n    let path_file = path.join(__dirname, filename);\n    await fs.writeFile(path_file, data);\n    \n}\n\nasync function readXMLFile(filename){\n\n    let parser = new xml2js.Parser();\n    let path_file = path.join(__dirname, filename);\n    let data = await fs.readFile(path_file);\n    parser.parseString(data, function (err, result) {\n        result_object = Object(result)\n        console.log(result_object.Root.name);\n    \n    });\n\n}\n\n//Create the file\ncreateJSONFile(\"file.json\", json_data).then(function (result) {\n    //Read the file once it is created\n    readJSONFile(\"file.json\").then(\n        function (result) {\n            console.log(result)\n            //Delete JSON file \n            deleteFile(\"file.json\").then((result) => console.log(\"JSON file was deleted\"),\n                (error) => console.log(\"Error deleting JSON file\"));\n        }, error => console.log(\"Error opening JSON file\"));\n\n}, error => console.log(\"Error creating JSON file\"));\n\n\nlet xml_data = `<Root>\n                    <name>Raul</name>\n                    <age>33</age>\n                    <birth_date>11/09/1991</birth_date>\n                    <languages>\n                        <language>\n                            <name>Python</name>\n                        </language>\n                        <language>\n                            <name>Javascript</name>\n                        </language>     \n                        <language>\n                            <name>Abap</name>\n                        </language>                                            \n                    </languages>\n                </Root>`;\ncreateXMLfile(\"file.xml\", xml_data).then(function(result){\n    readXMLFile(\"file.xml\").then(function(result){\n        deleteFile(\"file.xml\").then(result=>console.log(\"XML file deleted\"),\n                                    error => console.log(\"Error deleting xml file\"));\n    })\n}, error => console.log(\"Error creating XML file\"));\n   \n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/javascript/seandsun.js",
    "content": "// <-------------- json -------------->\n\n// Requerimos el módulo \"fs\" de Node.js y lo guardamos en una cosntante\nconst fs = require('fs')\n\n// Datos para agregar al nuevo fichero llamado \"seandsun.json\"\nconst datos = {\n  nombre: \"Marisol\",\n  edad: 26,\n  fechaDeNacimiento: \"11/07/98\",\n  lenguajesDeProgramacion: [\n    \"javascript\", \"python\", \"java\"\n  ]\n}\n\n// Convertir objeto tipo js a objeto json\nlet jsonDatos = JSON.stringify(datos)\n\n// Crear archivo \"seandsun.json\" y escribir los datos en él\nconst jsonPath = './seandsun.json'\n\nfs.writeFile(jsonPath, jsonDatos, (error) => {\n  if(error) {\n    console.log(`Error al crear el archivo: ${error}`)\n  } else {\n    console.log('Se ha creado el archivo .json correctamente')\n  }\n})\n\n// Leer la información del archivo \"seandsun.json\"\nlet data = fs.readFileSync('seandsun.json')\n\n// Convertir objeto tipo json a objeto js\nlet dataParseada = JSON.parse(data)\nconsole.log(dataParseada)\n\n// Eliminar el archivo \"seandsun.json\"\nfs.unlink(jsonPath, (error) => {\n  if(error) {\n    console.log(`Error al eliminar el archivo .json: ${error}`)    \n  } else {\n    console.log('Archivo .json borrado exitosamente')\n  }\n})\n\n\n// <-------------- xml -------------->\n\n// Datos para agregar al nuevo fichero llamado \"seandsun.xml\"\nconst xmlDatos = `\n<datos>\n  <nombre>Marisol</nombre>\n  <edad>26</edad>\n  <fechaDeNacimiento>11/07/98</>\n  <lenguajesDeProgramacion>\n    <lenguaje>javascript</lenguaje>\n    <lenguaje>python</lenguaje>\n    <lenguaje>java</lenguaje>\n  </lenguajesDeProgramacion>\n</datos>\n`\n\n// Crear archivo \"seandsun.xml\" y escribir los datos en él\nconst xmlPath = './seandsun.xml'\n\nfs.writeFile(xmlPath, xmlDatos, (error) => {\n  if(error) {\n    console.log(`Error al crear el archivo: ${error}`)\n  } else {\n    console.log('Se ha creado el archivo .xml correctamente')\n  }\n})\n\n// Leer la información del archivo \"seandsun.xml\"\nfs.readFile(xmlPath, 'utf-8', (error, data) => {\n  if(!error) {\n    console.log(data)\n  } else {\n    console.log(`Error al leer el archivo: ${error}`)\n  }\n})\n\n// Eliminar el archivo \"seandsun.xml\"\nfs.unlink(xmlPath, (error) => {\n  if(error) {\n    console.log(`Error al eliminar el archivo .xml: ${error}`)    \n  } else {\n    console.log('Archivo .xml borrado exitosamente')\n  }\n})"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/javascript/victor-Casta.js",
    "content": "/*\n  *Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n  * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n  * - Nombre\n  * - Edad\n  * - Fecha de nacimiento\n  * - Listado de lenguajes de programación\n  * Muestra el contenido de los archivos.\n  * Borra los archivos.\n*/\n\n// XML\n\nconst fs = require('fs')\n\nconst data = {\n  name: 'Victor',\n  age: 21,\n  birthdate: '17-12-2002',\n  languages: ['Javascript', 'TypeScript', 'Python']\n}\n\nfs.writeFileSync('victor-Casta.xml', `\n  <root>\n    <name>${data.name}</name>\n    <age>${data.age}</age>\n    <birthdate>${data.birthdate}</birthdate>\n    <languages>${\n      data.languages.map((item) => `<item>${item}</item>`).join('')\n    }</languages>\n  </root>\n`)\n\nconsole.log(fs.readFileSync('victor-Casta.xml', 'utf8'))\n\n\n\n// JSON\n\nfs.writeFileSync('victor-Casta.json', JSON.stringify(data))\nconsole.log(fs.readFileSync('victor-Casta.json', 'utf-8'))\n\n\n/*\n   * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu\n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n*/\n\nclass xmlData {\n  constructor(name, age, birthdate, programmingLanguages) {\n    this.name = name;\n    this.age = age;\n    this.birthdate = birthdate;\n    this.programmingLanguages = [programmingLanguages];\n  }\n\n  getData() {\n    console.log(\n      `{\n        name: ${this.name},\n        age: ${this.age},\n        birthdate: ${this.birthdate},\n        programmingLanguages: ${this.programmingLanguages}\n      }`\n    )\n  }\n}\n\nconst xmlContent = fs.readFileSync('victor-Casta.xml', 'utf-8');\nconst nameMatch = xmlContent.match(/<name>([^<]+)<\\/name>/);\nconst ageMatch = xmlContent.match(/<age>([^<]+)<\\/age>/);\nconst birthdateMatch = xmlContent.match(/<birthdate>([^<]+)<\\/birthdate>/);\nconst languagesMatch = xmlContent.match(/<languages>([\\s\\S]*?)<\\/languages>/);\nconst languagesContent = languagesMatch[1];\nlet lenguajesList = [];\nconst items = [...languagesContent.matchAll(/<item>([^<]+)<\\/item>/g)];\nitems.forEach(item => lenguajesList.push(item[1]));\n\nconst xml = new xmlData(nameMatch[1], ageMatch[1], birthdateMatch[1], lenguajesList);\nxml.getData();\n\n\nclass jsonData {\n  constructor(name, age, birthdate, programmingLanguages) {\n    this.name = name;\n    this.age = age;\n    this.birthdate = birthdate;\n    this.programmingLanguages = programmingLanguages;\n  }\n  getData() {\n    let rta = {\n      name: this.name,\n      age: this.age,\n      birthdate: this.birthdate,\n      programmingLanguages: this.programmingLanguages\n    }\n    console.log(rta);\n  }\n}\n\nconst jsonContent = fs.readFileSync('victor-Casta.json', 'utf-8');\nconst formatJson = JSON.parse(jsonContent);\n\nconst jsonRta = new jsonData(formatJson.name, formatJson.age, formatJson.birthdate, formatJson.languages)\njsonRta.getData();\n\nfs.unlinkSync('victor-Casta.xml')\nfs.unlinkSync('victor-Casta.json')"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/javascript/wapastorv.js",
    "content": "/*\n* IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n* \n* EJERCICIO:\n* Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n* siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n* - Nombre\n* - Edad\n* - Fecha de nacimiento\n* - Listado de lenguajes de programación\n* Muestra el contenido de los archivos.\n* Borra los archivos.\n*/\nconst fs = require('fs');\n\n// Datos para el archivo XML\nconst data ={\n    nombre: \"William Pastor\",\n    ciudad: \"Madrid\",\n    edad: 18,\n    fechaDeNacimiento: \"13-12-1993\",\n    listadoDeLenguajesProgramacion : ['JavaScript', 'Python']\n}\n\n// Datos para el archivo XML\n// Convertir el objeto a una cadena XML (simplificado)\nconst xmlString = `<persona>\n    <nombre>${data.nombre}</nombre>\n    <edad>${data.edad}</edad>\n    <ciudad>${data.ciudad}</ciudad>\n    <fechaDeNacimiento>${data.fechaDeNacimiento}</fechaDeNacimiento>\n    <listadoDeLenguajesProgramacion>${data.listadoDeLenguajesProgramacion.join(',')}</listadoDeLenguajesProgramacion>\n</persona>`;\n\n// Crear el archivo XML\nfs.writeFile('persona.xml', xmlString, (err) => {\n    if (err) {\n        console.error(err);\n    } else {\n        console.log('Archivo XML creado exitosamente');\n    }\n});\n\nfs.readFile('persona.xml', 'utf8', (err, data) => {\n    if (err) {\n        console.error(err);\n    } else {\n        console.log(data); // Imprime el contenido del archivo XML\n    }\n});\n// Convertir el objeto a una cadena JSON\nconst jsonString = JSON.stringify(data);\n\n// Crear el archivo JSON\nfs.writeFile('persona.json', jsonString, (err) => {\n    if (err) {\n        console.error(err);\n    } else {\n        console.log('Archivo JSON creado exitosamente');\n    }\n});\n// Leer archivo JSON\nfs.readFile('persona.json', 'utf8', (err, data) => {\n    if (err) {\n        console.error(err);\n    } else {\n        const jsonData = JSON.parse(data);\n        console.log(jsonData); // Imprime el contenido del archivo JSON como un objeto\n    }\n});\n\n/* DIFICULTAD EXTRA (opcional):\n* Utilizando la lógica de creación de los archivos anteriores, crea un\n* programa capaz de leer y transformar en una misma clase custom de tu \n* lenguaje los datos almacenados en el XML y el JSON.\n* Borra los archivos.\n*/\n\n// Clase Persona\nclass Persona {\n    constructor(nombre, edad, ciudad, fechaDeNacimiento, listadoDeLenguajesProgramacion) {\n        this.nombre = nombre;\n        this.edad = edad;\n        this.ciudad = ciudad;\n        this.fechaDeNacimiento = fechaDeNacimiento;\n        this.listadoDeLenguajesProgramacion = listadoDeLenguajesProgramacion;\n    }\n}\n\n// Leer el archivo XML\n\nfs.readFile('persona.xml', 'utf8', (err, data) => {\n    if (err) {\n        console.error(err);\n    } else {\n        // Convertir XML a JSON\n        const xml2js = require('xml2js');\n        xml2js.parseString(data, (err, result) => {\n            if (err) {\n                console.error(err);\n            } else {\n                const personaXml = result.persona;\n                const persona = new Persona(\n                    personaXml.nombre[0],\n                    parseInt(personaXml.edad[0]),\n                    personaXml.ciudad[0],\n                    personaXml.fechaDeNacimiento[0],\n                    personaXml.listadoDeLenguajesProgramacion[0].split(',')\n                );\n                console.log(persona);\n            }\n        });\n    }\n});\n\n// Leer el archivo JSON\nfs.readFile('persona.json', 'utf8', (err, data) => {\n    if (err) {\n        console.error(err);\n    } else {\n        const jsonData = JSON.parse(data);\n        const persona = new Persona(\n            jsonData.nombre,\n            jsonData.edad,\n            jsonData.ciudad,\n            jsonData.fechaDeNacimiento,\n            jsonData.listadoDeLenguajesProgramacion\n        );\n        console.log(persona);\n    }\n});\n\n// Borrar los archivos (opcional)\nfs.unlink('persona.xml', (err) => {\n    if (err) {\n        console.error(err);\n    } else {\n        console.log('Archivo XML eliminado');\n    }\n});\nfs.unlink('persona.json', (err) => {\n    if (err) {\n        console.error(err);\n    } else {\n        console.log('Archivo JSON eliminado');\n    }\n});\n\n// Otra forma de hacerlo\n\n\n/*\nconst fs = require('fs');\nconst xml2js = require('xml2js');\n\nclass Persona {\n    constructor(nombre, edad, hobbies, ciudad, pais) {\n        this.nombre = nombre;\n        this.edad = edad;\n        this.hobbies = hobbies;\n        this.ciudad = ciudad;\n        this.pais = pais;\n    }\n}\n\nfunction unificarDatos(xmlData, jsonData) {\n    const personaXml = new Persona(\n        xmlData.persona.nombre[0],\n        parseInt(xmlData.persona.edad[0]),\n        xmlData.persona.hobbies[0].hobby\n    );\n    const personaJson = new Persona(    \n        jsonData.nombre,\n        jsonData.edad,\n        [], // Inicializamos hobbies como un array vacío\n        jsonData.ciudad,\n        jsonData.pais\n    );\n\n    // Combinar hobbies:\n    personaUnificada = { ...personaXml, ...personaJson };\n    personaUnificada.hobbies = [...personaXml.hobbies, ...personaJson.hobbies];\n\n    return personaUnificada;\n}\n\n// Leer el archivo XML\nfs.readFile('persona.xml', 'utf8', (err, xmlData) => {\n    if (err) throw err;\n\n    // Convertir XML a JSON\n    xml2js.parseString(xmlData, (err, result) => {\n        if (err) throw err;\n\n        // Leer el archivo JSON\n        fs.readFile('persona.json', 'utf8', (err, jsonData) => {\n            if (err) throw err;\n\n            jsonData = JSON.parse(jsonData);\n\n            // Unificar los datos\n            const personaUnificada = unificarDatos(result, jsonData);\n            console.log(personaUnificada);\n\n            // Borrar los archivos (opcional)\n            /*fs.unlink('persona.xml', (err) => {\n                if (err) throw err;\n                console.log('Archivo XML eliminado');\n            });\n            fs.unlink('persona.json', (err) => {\n                if (err) throw err;\n                console.log('Archivo JSON eliminado');\n            });\n        });\n    });\n});\n*/"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/kotlin/VincentRodriguezR.kt",
    "content": "//Importante ageragar en las dependencias de gradle \"implementation(\"com.google.code.gson:gson:2.8.8\")\"\nimport com.google.gson.Gson\nimport java.io.File\nimport javax.xml.bind.annotation.XmlRootElement\nimport javax.xml.bind.JAXBContext\nimport javax.xml.bind.Marshaller\nimport org.w3c.dom.Document\nimport javax.xml.parsers.DocumentBuilderFactory\n\n//JSON\n//el ejercicio incluye ya la dificultad extra\ndata class programadorJson(val nombre: String, val edad: Int, val fechaNacimiento: String, val lenguajes: List<String>){\n    fun mainProgramador(){\n\n        //Iniciar objeto programador\n        val dev = programadorJson(nombre, edad, fechaNacimiento, lenguajes)\n\n        //Iniciar objeto Json de la libreria GSON\n        val objetoGson = Gson()\n\n        //Transorformar objeto Dev a Json\n        val jsonDev = objetoGson.toJson(dev)\n\n        //Creacion del archivo\n        val archivo = File(\"C:\\\\Users\\\\vdsro\\\\Desktop\\\\dev.json\")\n        archivo.writeText(jsonDev)\n        println(\"Se ha creado el archivo\")\n\n        //Mostrar informacion del archivo\n        //Leer contenido del archivo\n        val contenido = File(\"C:\\\\Users\\\\vdsro\\\\Desktop\\\\dev.json\").readText()\n\n        //Creacion del objeto Json con GSON\n        val lecturaArchivo = Gson()\n\n        //Convertir el archivo JSON al objeto \"Programador\"\n        val lecturaDev = lecturaArchivo.fromJson(contenido, programadorJson::class.java)\n\n        //Impresion\n        println(\"Nombre: ${lecturaDev.nombre}\")\n        println(\"Edad: ${lecturaDev.edad}\")\n        println(\"Fecha de nacimiento: ${lecturaDev.fechaNacimiento}\")\n        println(\"Lenguajes de programacion: ${lecturaDev.lenguajes}\")\n\n        //Borrar archivo\n        archivo.delete()\n    }\n}\n@XmlRootElement //Importante agregar esta sentencia ya que es la que indica que la siguiente clase es un objeto XML\nclass programadorXml{\n    var nombre: String = \"\"\n    var edad: Int = 0\n    var fechaNacimiento:String = \"\"\n    var lenguajes: List<String> = listOf()\n}\n\nfun mainProgramadorXml(nombre: String, edad: Int, fechaNacimiento: String, lenguajes: List<String>){\n    //Definicion de objeto\n    val dev = programadorXml()\n    dev.nombre = nombre\n    dev.edad = edad\n    dev. fechaNacimiento = fechaNacimiento\n    dev.lenguajes = lenguajes\n\n    //Creacion de objeto XML\n    val contexto = JAXBContext.newInstance((programadorXml::class.java))\n\n    //Crear objeto marshall -> marshall = describe el proceso de convertir datos en un fotmato que se pueda transmitir eje: de clase a XML\n    val marshaller = contexto.createMarshaller()\n    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true)\n\n    //Escribir en archivo XML\n    val archivoXml = File(\"C:\\\\Users\\\\vdsro\\\\Desktop\\\\dev.xml\")\n    marshaller.marshal(dev, archivoXml)\n\n    println(\"Archivo XML creado de forma correcta\")\n\n    //Mostrar contenido del archivo\n    val contenido = archivoXml.path\n    val documento = convertirXml(contenido)\n    if(documento != null){\n        println(\"Contendio file XML\")\n        println(documento.documentElement.textContent.trim())\n    }else{\n        println(\"No hay archivo\")\n    }\n    archivoXml.delete()\n\n}\n\nfun convertirXml(ruta:String): Document?{\n    //creacion de la instancia para convertir el archivo\n    val conversor = DocumentBuilderFactory.newInstance()\n    try{\n        val constructor = conversor.newDocumentBuilder()\n        return constructor.parse(ruta)\n    } catch(excep: Exception){\n        excep.printStackTrace()\n    }\n    return null\n}\n\nfun main(){\n    val lenguajesProgram = listOf(\"Kotlin\", \"Java\", \"Python\")\n    val ejemploJson = programadorJson(\"Vincent\", 24, \"23/10/99\", lenguajesProgram)\n\n    ejemploJson.mainProgramador()\n    mainProgramadorXml(\"Vincent\", 24, \"23/10/99\", lenguajesProgram)\n\n}"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/kotlin/blackriper.kt",
    "content": "import kotlinx.serialization.ExperimentalSerializationApi\r\nimport kotlinx.serialization.KSerializer\r\nimport kotlinx.serialization.Serializable\r\nimport kotlinx.serialization.descriptors.PrimitiveKind\r\nimport kotlinx.serialization.descriptors.PrimitiveSerialDescriptor\r\nimport kotlinx.serialization.encodeToString\r\nimport kotlinx.serialization.encoding.Decoder\r\nimport kotlinx.serialization.encoding.Encoder\r\nimport kotlinx.serialization.json.Json\r\nimport nl.adaptivity.xmlutil.serialization.XML\r\nimport java.io.File\r\nimport java.io.FileWriter\r\nimport java.io.PrintWriter\r\nimport java.util.*\r\n\r\n/*\r\nAl proceso de convertir la informacion  en un cierto formato se le conoce como serializacion\r\nesto nos permite convertir alguna estructura  de kotlin en un formato de salida (json, xml, etc).\r\n\r\npara sealizar kotlin utiliza una libreria auxilar llamada kotlinx.serialization.\r\neste tambien nos provee de un modulo para poder serializar xml.\r\n\r\nSerializar: proceso de convertir un objeto de kotlin a un formato de salida json o xml\r\n\r\nDesializar: proceso de convertir un formato json o xml a un objeto de kotlin\r\n\r\npara mas informacion visita:\r\nhttps://kotlinlang.org/docs/serialization.html\r\nhttps://github.com/rharter/kotlinx-serialization-xml\r\n\r\n*/\r\n\r\n\r\n\r\n@OptIn(ExperimentalSerializationApi::class)\r\nfun jsonFile(){\r\nval src=\"src/main/resources/blackriper.json\"\r\n// crear clase para serializar y deserealizar\r\n@Serializable\r\ndata class User(val name: String, val age: Int, val birdday: String,val programingLenguages: List<String>)\r\n\r\n// escribir file json\r\nPrintWriter(FileWriter(src)).use {\r\n    val prettyJson = Json {\r\n        prettyPrint = true\r\n        prettyPrintIndent = \" \"\r\n    }\r\n    val user=User(\"Rodolfo\", 29, \"20/05/1994\", listOf(\"kotlin\",\"go\",\"python\"))\r\n    it.write(prettyJson.encodeToString(user))\r\n}\r\n\r\n// leer fichero json\r\nFile(src).readText().let {\r\n    val user = Json.decodeFromString<User>(it)\r\n    println(user)\r\n}\r\n\r\n// borrar fichero\r\nFile(src).delete()\r\n\r\n}\r\n\r\nfun xmlFile() {\r\n  val src=\"src/main/resources/blackriper.xml\"\r\n  // crear data class\r\n  @Serializable\r\n  data class User(val name: String, val age: Int, val birdday: String,val programingLenguages: List<String>)\r\n  // crear fichero xml\r\n   PrintWriter(FileWriter(src)).use {\r\n       val user=User(\"Rodolfo\", 29, \"20/05/1994\", listOf(\"kotlin\",\"go\",\"swift\"))\r\n       it.write(XML.encodeToString(user))\r\n    }\r\n\r\n  // leer fichero xml\r\n  File(src).readText().let {\r\n      val user = XML.decodeFromString<User>(it)\r\n      println(user)\r\n  }\r\n\r\n  // borrar fichero\r\n  File(src).delete()\r\n\r\n}\r\n\r\n// reto extra con json  y xml\r\n\r\n// crear custom serializer para UUID\r\nobject UUIDSerializer : KSerializer<UUID> {\r\n    override val descriptor = PrimitiveSerialDescriptor(\"UUID\", PrimitiveKind.STRING)\r\n\r\n    override fun deserialize(decoder: Decoder): UUID {\r\n        return UUID.fromString(decoder.decodeString())\r\n    }\r\n\r\n    override fun serialize(encoder: Encoder, value: UUID) {\r\n        encoder.encodeString(value.toString())\r\n    }\r\n}\r\n\r\n\r\n@Serializable\r\ndata class Product(\r\n    @Serializable(with = UUIDSerializer::class)\r\n    val sku: UUID,\r\n    var name: String,\r\n    var cant: Int,\r\n    var price: Double)\r\n\r\n@Serializable\r\ndata class StoreProducts(val products: List<Product>)\r\n\r\nenum class FileType {\r\n    JSON,\r\n    XML\r\n}\r\n\r\ninterface Store{\r\n    fun addProduct(product: Product)\r\n    fun removeProduct(name: String)\r\n    fun updateProduct(sku: UUID, product:Product)\r\n    fun showAllProducts()\r\n    fun searchProductByName(name: String):Product\r\n    fun calculateTotalSold()\r\n    fun deleteFile()\r\n}\r\n\r\nclass SoldSore(private val fileName:String,private val type:FileType):Store{\r\n    private val products= mutableListOf<Product>()\r\n    private val fileProduct=File(\"src/main/resources/$fileName\")\r\n    private val src=\"src/main/resources/$fileName\"\r\n\r\n    init {\r\n        if (fileProduct.exists()){\r\n           when(type){\r\n               FileType.JSON -> fileProduct.readText().let {\r\n                   val productsFile = Json.decodeFromString<StoreProducts>(it)\r\n                   productsFile.products.forEach { product ->\r\n                       products.add(product)\r\n                   }\r\n               }\r\n               FileType.XML -> fileProduct.readText().let {\r\n                   val productsFile = XML.decodeFromString<StoreProducts>(it)\r\n                   productsFile.products.forEach { product ->\r\n                       products.add(product)\r\n                   }\r\n               }\r\n           }\r\n\r\n        }\r\n    }\r\n\r\n    override fun addProduct(product: Product) {\r\n        products.add(product)\r\n        saveFile()\r\n    }\r\n\r\n    override fun removeProduct(name: String) {\r\n        val product=products.first { it.name==name }\r\n        val result=products.removeIf{it.sku==product.sku}\r\n        if (result) {\r\n            println(\"Product deleted successfully\")\r\n            saveFile()\r\n        } else {\r\n            println(\"Failed to delete the product\")\r\n        }\r\n    }\r\n\r\n    override fun updateProduct(sku: UUID, product: Product) {\r\n        products.first { it.sku == sku }.apply {\r\n            this.name = product.name\r\n            this.cant = product.cant\r\n            this.price = product.price\r\n        }\r\n        saveFile()\r\n    }\r\n\r\n    override fun showAllProducts() {\r\n        val header=\"\"\"\r\n            -----------------------\r\n            sku   name   cant  price\r\n            -----------------------\r\n        \"\"\".trimIndent()\r\n        println(header)\r\n        when(type){\r\n            FileType.JSON -> {\r\n                File(src).readText().let {\r\n                    val products = Json.decodeFromString<StoreProducts>(it)\r\n                    for (product in products.products) {\r\n                        println(\"${product.sku} ${product.name} ${product.cant} ${product.price}\")\r\n                    }\r\n                }\r\n            }\r\n            FileType.XML -> {\r\n                File(src).readText().let {\r\n                    val products = XML.decodeFromString<StoreProducts>(it)\r\n                    for (product in products.products) {\r\n                        println(\"${product.sku} ${product.name} ${product.cant} ${product.price}\")\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n\r\n    }\r\n\r\n    override fun searchProductByName(name: String): Product =\r\n        products.first { it.name==name }\r\n\r\n    override fun calculateTotalSold() {\r\n        val header=\"\"\"\r\n            ------------------------------------------------------------\r\n            sku               name         cant       price     Subtotal\r\n            -------------------------------------------------------------\r\n        \"\"\".trimIndent()\r\n        println(header)\r\n        products.forEach {\r\n            println(\"${it.sku} ${it.name} ${it.cant} ${it.price} ${\"%.2f\".format(it.cant*it.price)}\")\r\n        }\r\n        val total=products.sumOf { it.cant*it.price }\r\n        println(\"Total sold: $total\")\r\n    }\r\n\r\n    override fun deleteFile() {\r\n       val result= File(src).delete()\r\n        if (result) {\r\n            println(\"File deleted successfully\")\r\n        }else {\r\n            println(\"Failed to delete the file\")\r\n        }\r\n    }\r\n\r\n    @OptIn(ExperimentalSerializationApi::class)\r\n    private fun  saveFile(){\r\n      when(type){\r\n          FileType.JSON -> {\r\n              PrintWriter(FileWriter(fileProduct)).use {\r\n                  val prettyJson = Json {\r\n                      prettyPrint = true\r\n                      prettyPrintIndent = \" \"\r\n                  }\r\n                  val store=StoreProducts(products)\r\n                  it.write(prettyJson.encodeToString(store))\r\n              }\r\n          }\r\n          FileType.XML -> {\r\n              PrintWriter(FileWriter(fileProduct)).use {\r\n                  val store=StoreProducts(products)\r\n                  it.write(XML.encodeToString(store))\r\n              }\r\n          }\r\n      }\r\n    }\r\n\r\n}\r\n\r\nfun oxxoStore() {\r\n    // modificar si se quiere usar json o xml\r\n    val oxxo = SoldSore(\"products.xml\", FileType.XML)\r\n\r\n    do {\r\n        println(\"1. Add product\")\r\n        println(\"2. Remove product\")\r\n        println(\"3. Update product\")\r\n        println(\"4. Show all products\")\r\n        println(\"5. Search product by name\")\r\n        println(\"6. Calculate total sold\")\r\n        println(\"7. Exit\")\r\n        println(\"Choose an option:\")\r\n        val option = readLine()!!.toInt()\r\n        when (option) {\r\n            1 -> {\r\n                println(\"Enter name:\")\r\n                val name = readLine()!!.lowercase()\r\n                println(\"Enter cant:\")\r\n                val cant = readLine()!!.toInt()\r\n                println(\"Enter price:\")\r\n                val price = readLine()!!.toDouble()\r\n                val sku = UUID.randomUUID()\r\n                val product = Product(sku, name, cant, price)\r\n                oxxo.addProduct(product)\r\n            }\r\n\r\n            2 -> {\r\n                println(\"Enter name:\")\r\n                val name = readLine()!!.lowercase()\r\n                oxxo.removeProduct(name)\r\n            }\r\n\r\n            3 -> {\r\n                println(\"Enter name product:\")\r\n                val oldname = readLine()!!.lowercase()\r\n                val prod = oxxo.searchProductByName(oldname)\r\n                println(\"update name (${prod.name}):\")\r\n                val name = if (readLine().isNullOrEmpty()) prod.name else readLine()!!.lowercase()\r\n                println(\"update cat (${prod.cant}):\")\r\n                val cant = if (readLine().isNullOrEmpty()) prod.cant else readLine()!!.toInt()\r\n                println(\"update price (${prod.price}):\")\r\n                val price = if (readLine().isNullOrEmpty()) prod.price else readLine()!!.toDouble()\r\n                val product = Product(prod.sku, name, cant, price)\r\n                oxxo.updateProduct(prod.sku, product)\r\n            }\r\n\r\n            4 -> oxxo.showAllProducts()\r\n\r\n            5 -> {\r\n                println(\"Enter name:\")\r\n                val name = readLine()!!.lowercase()\r\n                val product = oxxo.searchProductByName(name)\r\n                println(\"sku: ${product.sku} name: ${product.name} cant: ${product.cant} price: ${product.price}\")\r\n            }\r\n\r\n            6 -> oxxo.calculateTotalSold()\r\n\r\n        }\r\n    } while (option != 7)\r\n\r\n    oxxo.deleteFile()\r\n}\r\n\r\n\r\n    fun main() {\r\n    //jsonFile()\r\n    //xmlFile()\r\n    oxxoStore()\r\n}"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/kotlin/eulogioep.kt",
    "content": "import org.json.JSONArray\nimport org.json.JSONObject\nimport java.io.File\nimport javax.xml.parsers.DocumentBuilderFactory\nimport javax.xml.transform.TransformerFactory\nimport javax.xml.transform.dom.DOMSource\nimport javax.xml.transform.stream.StreamResult\nimport org.w3c.dom.Document\n\ndata class Person(\n    val name: String,\n    val age: Int,\n    val birthDate: String,\n    val programmingLanguages: List<String>\n)\n\nfun main() {\n    val person = Person(\"EulogioEP\", 41, \"1981-05-07\", listOf(\"Kotlin\", \"Java\", \"Python\"))\n\n    createXMLFile(person)\n    createJSONFile(person)\n\n    println(\"XML content:\")\n    println(File(\"person.xml\").readText())\n    \n    println(\"\\nJSON content:\")\n    println(File(\"person.json\").readText())\n\n    // Delete files\n    File(\"person.xml\").delete()\n    File(\"person.json\").delete()\n\n    println(\"\\nFiles deleted.\")\n\n    // Extra challenge\n    val xmlPerson = readXMLFile(\"person.xml\")\n    val jsonPerson = readJSONFile(\"person.json\")\n\n    println(\"\\nPerson from XML: $xmlPerson\")\n    println(\"Person from JSON: $jsonPerson\")\n}\n\nfun createXMLFile(person: Person) {\n    val docFactory = DocumentBuilderFactory.newInstance()\n    val docBuilder = docFactory.newDocumentBuilder()\n    val doc: Document = docBuilder.newDocument()\n\n    val rootElement = doc.createElement(\"person\")\n    doc.appendChild(rootElement)\n\n    val name = doc.createElement(\"name\")\n    name.appendChild(doc.createTextNode(person.name))\n    rootElement.appendChild(name)\n\n    val age = doc.createElement(\"age\")\n    age.appendChild(doc.createTextNode(person.age.toString()))\n    rootElement.appendChild(age)\n\n    val birthDate = doc.createElement(\"birthDate\")\n    birthDate.appendChild(doc.createTextNode(person.birthDate))\n    rootElement.appendChild(birthDate)\n\n    val languages = doc.createElement(\"programmingLanguages\")\n    person.programmingLanguages.forEach {\n        val lang = doc.createElement(\"language\")\n        lang.appendChild(doc.createTextNode(it))\n        languages.appendChild(lang)\n    }\n    rootElement.appendChild(languages)\n\n    val transformerFactory = TransformerFactory.newInstance()\n    val transformer = transformerFactory.newTransformer()\n    val source = DOMSource(doc)\n    val result = StreamResult(File(\"person.xml\"))\n    transformer.transform(source, result)\n}\n\nfun createJSONFile(person: Person) {\n    val json = JSONObject()\n    json.put(\"name\", person.name)\n    json.put(\"age\", person.age)\n    json.put(\"birthDate\", person.birthDate)\n    json.put(\"programmingLanguages\", JSONArray(person.programmingLanguages))\n\n    File(\"person.json\").writeText(json.toString(2))\n}\n\nfun readXMLFile(filename: String): Person {\n    val file = File(filename)\n    val dbFactory = DocumentBuilderFactory.newInstance()\n    val dBuilder = dbFactory.newDocumentBuilder()\n    val doc = dBuilder.parse(file)\n    doc.documentElement.normalize()\n\n    val name = doc.getElementsByTagName(\"name\").item(0).textContent\n    val age = doc.getElementsByTagName(\"age\").item(0).textContent.toInt()\n    val birthDate = doc.getElementsByTagName(\"birthDate\").item(0).textContent\n    val languagesNodes = doc.getElementsByTagName(\"language\")\n    val languages = (0 until languagesNodes.length).map { languagesNodes.item(it).textContent }\n\n    return Person(name, age, birthDate, languages)\n}\n\nfun readJSONFile(filename: String): Person {\n    val jsonString = File(filename).readText()\n    val json = JSONObject(jsonString)\n\n    val name = json.getString(\"name\")\n    val age = json.getInt(\"age\")\n    val birthDate = json.getString(\"birthDate\")\n    val languages = json.getJSONArray(\"programmingLanguages\").let {\n        (0 until it.length()).map { i -> it.getString(i) }\n    }\n\n    return Person(name, age, birthDate, languages)\n}"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/ocaml/luishendrix92.ml",
    "content": "module Programmer = struct\n  open Yojson.Safe\n  open Xml\n\n  type t =\n    { name : string\n    ; age : int\n    ; birth_date : string\n    ; languages : string list\n    }\n  [@@deriving yojson]\n\n  type ts = t list [@@deriving yojson]\n\n  class c name age birth_date languages =\n    object\n      val name : string = name\n      val age : int = age\n      val birth_date : string = birth_date\n      val languages : string list = languages\n\n      method introduce =\n        Printf.printf\n          \"Hello, my name is %s and I'm a %d year old developer! My Favourite \\\n           languages are: %s.\\n\"\n          name\n          age\n          (String.concat \", \" languages)\n    end\n\n  let list_to_json l = ts_to_yojson l |> pretty_to_string\n\n  let to_xml programmer =\n    Element\n      ( \"programmer\"\n      , []\n      , [ Element (\"name\", [], [ PCData programmer.name ])\n        ; Element (\"age\", [], [ PCData (string_of_int programmer.age) ])\n        ; Element (\"birth_date\", [], [ PCData programmer.birth_date ])\n        ; Element\n            ( \"languages\"\n            , []\n            , List.map\n                (fun language ->\n                  Xml.Element (\"language\", [], [ PCData language ]))\n                programmer.languages )\n        ] )\n  ;;\n\n  let list_to_xml l =\n    let body = Element (\"employees\", [], List.map to_xml l) |> to_string_fmt in\n    let xml_header = {|<?xml version=\"1.0\" encoding=\"UTF-8\"?>|} in\n    xml_header ^ \"\\n\" ^ body\n  ;;\n\n  let of_xml = function\n    | Element\n        ( \"programmer\"\n        , []\n        , [ Element (\"name\", [], [ PCData name ])\n          ; Element (\"age\", [], [ PCData age ])\n          ; Element (\"birth_date\", [], [ PCData birth_date ])\n          ; Element (\"languages\", [], langs)\n          ] ) ->\n      let age = int_of_string age in\n      let languages =\n        List.map (fun lang -> children lang |> List.hd |> pcdata) langs\n      in\n      new c name age birth_date languages\n    | _ -> failwith \"Programmer Entity XML Malformed\"\n  ;;\n\n  let list_of_json fname = from_file fname |> ts_of_yojson |> Result.get_ok\n\n  let list_of_xml fname =\n    match parse_file fname with\n    | Element (\"employees\", [], programmers) -> List.map of_xml programmers\n    | _ -> failwith \"XML File Parsing Failed\"\n  ;;\nend\n\nlet mock_data : Programmer.ts =\n  [ { name = \"Luis Lopez\"\n    ; age = 32\n    ; birth_date = \"09/04/1992\"\n    ; languages = [ \"Typescript\"; \"Clojure\"; \"OCaml\"; \"Elixir\" ]\n    }\n  ; { name = \"John Doe\"\n    ; age = 24\n    ; birth_date = \"24/12/2000\"\n    ; languages = [ \"C#\"; \"Java\"; \"Python\"; \"C++\"; \"Lua\" ]\n    }\n  ; { name = \"Jane Marsh\"\n    ; age = 50\n    ; birth_date = \"05/09/1976\"\n    ; languages = [ \"Kotlin\"; \"Rust\"; \"Zig\"; \"SQL\"; \"Haskell\" ]\n    }\n  ]\n;;\n\nlet create_files () =\n  let open Core.Out_channel in\n  write_all \"db.json\" ~data:(Programmer.list_to_json mock_data);\n  write_all \"db.xml\" ~data:(Programmer.list_to_xml mock_data)\n;;\n\nlet delete_files () =\n  Sys.remove \"db.json\";\n  Sys.remove \"db.xml\"\n;;\n\nlet () =\n  let open Core.In_channel in\n  create_files ();\n  print_endline \"Contents of the JSON File:\";\n  print_endline \"--------------------------\";\n  read_all \"db.json\" |> print_endline;\n  print_endline \"Contents of the XML File:\";\n  print_endline \"--------------------------\";\n  read_all \"db.xml\" |> print_endline;\n  delete_files ()\n;;\n\n(*****************************************************************************)\n(*                                                                           *)\n(*                        Dificultad Extra (Opcional)                        *)\n(*                                                                           *)\n(*  Utilizando la lógica de creación de los archivos anteriores, crea un     *)\n(*  programa capaz de leer y transformar en una misma clase custom de tu     *)\n(*  lenguaje los datos almacenados en el XML y el JSON. Borra los archivos.  *)\n(*                                                                           *)\n(*****************************************************************************)\n\nlet () =\n  create_files ();\n  print_endline \"Deserializing from JSON file...\";\n  Programmer.list_of_json \"db.json\"\n  |> List.map (fun (p : Programmer.t) ->\n    new Programmer.c p.name p.age p.birth_date p.languages)\n  |> List.iter (fun programmer -> programmer#introduce);\n  print_endline \"Deserializing from XML file...\";\n  Programmer.list_of_xml \"db.xml\"\n  |> List.iter (fun programmer -> programmer#introduce);\n  delete_files ()\n;;\n\n(* Output of `dune exec reto12`\n\n   Contents of the JSON File:\n   --------------------------\n   [\n    {\n      \"name\": \"Luis Lopez\",\n      \"age\": 32,\n      \"birth_date\": \"09/04/1992\",\n      \"languages\": [ \"Typescript\", \"Clojure\", \"OCaml\", \"Elixir\" ]\n    },\n    {\n      \"name\": \"John Doe\",\n      \"age\": 24,\n      \"birth_date\": \"24/12/2000\",\n      \"languages\": [ \"C#\", \"Java\", \"Python\", \"C++\", \"Lua\" ]\n    },\n    {\n      \"name\": \"Jane Marsh\",\n      \"age\": 50,\n      \"birth_date\": \"05/09/1976\",\n      \"languages\": [ \"Kotlin\", \"Rust\", \"Zig\", \"SQL\", \"Haskell\" ]\n    }\n  ]\n   Contents of the XML File:\n   --------------------------\n   <?xml version=\"1.0\" encoding=\"UTF-8\"?>\n   <employees>\n   <programmer>\n   <name>Luis Lopez</name>\n   <age>32</age>\n   <birth_date>09/04/1992</birth_date>\n   <languages>\n   <language>Typescript</language>\n   <language>Clojure</language>\n   <language>OCaml</language>\n   <language>Elixir</language>\n   </languages>\n   </programmer>\n   <programmer>\n   <name>John Doe</name>\n   <age>24</age>\n   <birth_date>24/12/2000</birth_date>\n   <languages>\n   <language>C#</language>\n   <language>Java</language>\n   <language>Python</language>\n   <language>C++</language>\n   <language>Lua</language>\n   </languages>\n   </programmer>\n   <programmer>\n   <name>Jane Marsh</name>\n   <age>50</age>\n   <birth_date>05/09/1976</birth_date>\n   <languages>\n   <language>Kotlin</language>\n   <language>Rust</language>\n   <language>Zig</language>\n   <language>SQL</language>\n   <language>Haskell</language>\n   </languages>\n   </programmer>\n   </employees>\n   Deserializing from JSON file...\n   Hello, my name is Luis Lopez and I'm a 32 year old developer! My Favourite languages are: Typescript, Clojure, OCaml, Elixir.\n   Hello, my name is John Doe and I'm a 24 year old developer! My Favourite languages are: C#, Java, Python, C++, Lua.\n   Hello, my name is Jane Marsh and I'm a 50 year old developer! My Favourite languages are: Kotlin, Rust, Zig, SQL, Haskell.\n   Deserializing from XML file...\n   Hello, my name is Luis Lopez and I'm a 32 year old developer! My Favourite languages are: Typescript, Clojure, OCaml, Elixir.\n   Hello, my name is John Doe and I'm a 24 year old developer! My Favourite languages are: C#, Java, Python, C++, Lua.\n   Hello, my name is Jane Marsh and I'm a 50 year old developer! My Favourite languages are: Kotlin, Rust, Zig, SQL, Haskell.\n*)\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/pascal/edalmava.pas",
    "content": "program json;\nuses Crt, SysUtils;\nvar\n    xmlFile, jsonFile: Text;\n    name, birthdate, linea: string;\n    age: Integer;\n    languages: array[1..3] of string;\n\nbegin\n    ClrScr;\n\n    name := 'Edwin Alberto Martinez Vanegas';\n    age := 30;\n    birthdate := '1994-08-11';\n    languages[1] := 'Pascal';\n    languages[2] := 'Python';\n    languages[3] := 'JavaScript';\n\n    // Crear archivo XML\n    Assign(xmlFile, 'data.xml');\n    Rewrite(xmlFile);\n    Writeln(xmlFile, '<?xml version=\"1.0\" encoding=\"UTF-8\"?>');\n    Writeln(xmlFile, '<person>');\n    Writeln(xmlFile, '  <name>', name, '</name>');\n    Writeln(xmlFile, '  <age>', age, '</age>');\n    Writeln(xmlFile, '  <birthdate>', birthdate, '</birthdate>');\n    Writeln(xmlFile, '  <languages>');\n    Writeln(xmlFile, '    <language>', languages[1], '</language>');\n    Writeln(xmlFile, '    <language>', languages[2], '</language>');\n    Writeln(xmlFile, '    <language>', languages[3], '</language>');\n    Writeln(xmlFile, '  </languages>');\n    Writeln(xmlFile, '</person>');\n\n    // Crear archivo JSON\n    Assign(jsonFile, 'data.json');\n    Rewrite(jsonFile);\n    Writeln(jsonFile, '{');\n    Writeln(jsonFile, '  \"name\": \"', name, '\",');\n    Writeln(jsonFile, '  \"age\": ', age, ',');\n    Writeln(jsonFile, '  \"birthdate\": \"', birthdate, '\",');\n    Writeln(jsonFile, '  \"languages\": [');\n    Writeln(jsonFile, '    \"', languages[1], '\",');\n    Writeln(jsonFile, '    \"', languages[2], '\",');\n    Writeln(jsonFile, '    \"', languages[3], '\"');\n    Writeln(jsonFile, '  ]');\n    Writeln(jsonFile, '}');\n\n    // Mostrar contenido de los archivos\n\n    Reset(xmlFile);\n    Writeln('Contenido del archivo XML:');\n    while not Eof(xmlFile) do\n    begin\n        Readln(xmlFile, linea);\n        Writeln(linea);\n    end;\n    Close(xmlFile);\n\n    Reset(jsonFile);\n    Writeln('Contenido del archivo JSON:');\n    while not Eof(jsonFile) do\n    begin\n        Readln(jsonFile, linea);\n        Writeln(linea);\n    end;\n    Close(jsonFile);\n\n    // Borrar los archivos\n    {I+}\n    Erase(xmlFile);\n    {I-}\n    if IOResult = 0 then\n        Writeln('Archivo XML borrado con exito.')\n    else\n        Writeln('Error al borrar el archivo XML.');\n\n    {I+}\n    Erase(jsonFile);\n    {I-}\n    if IOResult = 0 then\n        Writeln('Archivo JSON borrado con exito.')\n    else\n        Writeln('Error al borrar el archivo JSON.');\nend.\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/php/eulogioep.php",
    "content": "<?php\n\n// Datos de ejemplo\n$persona = [\n    'nombre' => 'Juan',\n    'edad' => 30,\n    'fechaNacimiento' => '1993-05-15',\n    'lenguajesProgramacion' => ['PHP', 'JavaScript', 'Python']\n];\n\n// Función para crear el archivo XML\nfunction crearArchivoXML($datos) {\n    $xml = new SimpleXMLElement('<persona></persona>');\n    array_walk_recursive($datos, function($value, $key) use ($xml) {\n        if (is_array($value)) {\n            $child = $xml->addChild($key);\n            foreach ($value as $subvalue) {\n                $child->addChild('lenguaje', $subvalue);\n            }\n        } else {\n            $xml->addChild($key, $value);\n        }\n    });\n    $xml->asXML('datos.xml');\n    echo \"Archivo XML creado.\\n\";\n}\n\n// Función para crear el archivo JSON\nfunction crearArchivoJSON($datos) {\n    file_put_contents('datos.json', json_encode($datos, JSON_PRETTY_PRINT));\n    echo \"Archivo JSON creado.\\n\";\n}\n\n// Función para mostrar el contenido de un archivo\nfunction mostrarContenidoArchivo($nombreArchivo) {\n    echo \"Contenido del archivo $nombreArchivo:\\n\";\n    echo file_get_contents($nombreArchivo) . \"\\n\";\n}\n\n// Función para borrar un archivo\nfunction borrarArchivo($nombreArchivo) {\n    if (unlink($nombreArchivo)) {\n        echo \"El archivo $nombreArchivo ha sido borrado.\\n\";\n    } else {\n        echo \"No se pudo borrar el archivo $nombreArchivo.\\n\";\n    }\n}\n\n// Función para leer el archivo XML\nfunction leerXML($nombreArchivo) {\n    $xml = simplexml_load_file($nombreArchivo);\n    $datos = json_decode(json_encode($xml), true);\n    return $datos;\n}\n\n// Función para leer el archivo JSON\nfunction leerJSON($nombreArchivo) {\n    $jsonData = file_get_contents($nombreArchivo);\n    return json_decode($jsonData, true);\n}\n\n// Función principal\nfunction main() {\n    global $persona;\n\n    // Crear y mostrar archivo XML\n    crearArchivoXML($persona);\n    mostrarContenidoArchivo('datos.xml');\n\n    // Crear y mostrar archivo JSON\n    crearArchivoJSON($persona);\n    mostrarContenidoArchivo('datos.json');\n\n    // Borrar archivos\n    borrarArchivo('datos.xml');\n    borrarArchivo('datos.json');\n\n    // DIFICULTAD EXTRA\n    // Crear archivos nuevamente para la lectura\n    crearArchivoXML($persona);\n    crearArchivoJSON($persona);\n\n    // Leer y transformar datos\n    $personaXML = leerXML('datos.xml');\n    $personaJSON = leerJSON('datos.json');\n\n    echo \"\\nDatos leídos del XML:\\n\";\n    print_r($personaXML);\n    echo \"\\nDatos leídos del JSON:\\n\";\n    print_r($personaJSON);\n\n    // Borrar archivos nuevamente\n    borrarArchivo('datos.xml');\n    borrarArchivo('datos.json');\n}\n\n// Ejecutar la función principal\nmain();\n\n?>"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/php/gabrielmoris.php",
    "content": "<?php\necho \"\\033c\";\n/*\n* IMPORTANT: You should only upload the code file as part of the exercise.\n*\n* EXERCISE:\n* Develop a program capable of creating an XML and JSON file that saves the\n* following data (using the correct syntax in each case):\n* - Name\n* - Age\n* - Date of birth\n* - List of programming languages\n* Display the content of the files.\n* Delete the files.\n*/\n\n//············ JSON ············\nfunction json_creator($array)\n{\n\n    try {\n        $json = json_encode($array, JSON_PRETTY_PRINT);\n        file_put_contents('gabrielmoris.json', $json);\n        echo \"File has been created\\n\";\n    } catch (Exception $e) {\n        echo \" There was an error creating the JSON file: \" .  $e . \"\\n\";\n    }\n}\n\nfunction json_reader()\n{\n    try {\n        if (file_exists('gabrielmoris.json')) {\n            $json_file = file_get_contents('gabrielmoris.json');\n            $data = json_decode($json_file, true);\n            echo $json_file . \"\\n\";\n            return $data;\n        } else {\n            throw new Exception(\"The JSON file 'gabrielmoris.json' does not exist.\");\n        }\n    } catch (Exception $e) {\n        echo \"Error trying to read the JSON file \" . $e . \"\\n\";\n    }\n}\n\nfunction json_deleter()\n{\n    try {\n        unlink('gabrielmoris.json');\n        echo \"JSON Deleted\\n\";\n    } catch (Exception $e) {\n        echo \"There was an error deleting the JSON file: \" .  $e . \"\\n\";\n    }\n}\n\n//············ XML ············\nfunction xml_creator($array)\n{\n    try {\n        $dom = new DOMDocument('1.0', 'UTF-8');\n        $dom->formatOutput = true; // It will format the output\n        $root = $dom->createElement('gabrielmoris');\n        $dom->appendChild($root);\n\n        foreach ($array as $key => $value) {\n            $element = $dom->createElement($key);\n            $root->appendChild($element);\n\n            if (is_array($value)) {\n                foreach ($value as $language) {\n                    $languageElement = $dom->createElement('list', $language);\n                    $element->appendChild($languageElement);\n                }\n            } else {\n                $element->textContent = $value;\n            }\n        }\n\n        $dom->save('gabrielmoris.xml');\n        echo \"File has been created\\n\";\n    } catch (Exception $e) {\n        echo \"There was an error creating the XML file: \" .  $e . \"\\n\";\n    }\n}\n\nfunction xml_reader()\n{\n    try {\n        if (file_exists('gabrielmoris.xml')) {\n            $xml_file = file_get_contents('gabrielmoris.xml');\n            $xml = simplexml_load_string($xml_file);\n            // This function (below) Will iterate over the XML and create an array.\n            $array = simpleXmlToArray($xml);\n            echo $xml_file . \"\\n\";\n            return $array;\n        } else {\n            throw new Exception(\"The XML file 'gabrielmoris.xml' does not exist.\");\n        }\n    } catch (Exception $e) {\n        echo \"Error trying to read the XML file: \" . $e->getMessage() . \"\\n\";\n    }\n}\n\nfunction simpleXmlToArray($simpleXml)\n{\n    $array = [];\n    foreach ($simpleXml->children() as $child) {\n        $childName = $child->getName();\n        if ($child->count() > 0) { // Child is gonnna be a List and I have to iterate only if I find a key with a list of values\n            $array[$childName] = [];\n            foreach ($child->children() as $language) {\n                $array[$childName][] = (string) $language;\n            }\n        } else {\n            $array[$childName] = (string) $child;\n        }\n    }\n    return $array;\n}\n\nfunction xml_deleter()\n{\n    try {\n        unlink('gabrielmoris.xml');\n        echo \"XML Deleted\\n\";\n    } catch (Exception $e) {\n        echo \"There was an error deleting the XML file: \" .  $e . \"\\n\";\n    }\n}\n\n/* EXTRA DIFFICULTY (optional):\n* Using the logic of creating the previous files, create a\n* program capable of reading and transforming into a custom class of your\n* language the data stored in the XML and JSON.\n* Delete the files.\n*/\n\nclass Person\n{\n    public $name;\n    public $age;\n    public $birthDate;\n    public $programming_languages;\n    public $source;\n\n    public function __construct($data, $source)\n    {\n        $this->name = $data['name'];\n        $this->age = $data['age'];\n        $this->birthDate = $data['birthdate'];\n        $this->programming_languages = [];\n        $this->source = $source;\n\n        foreach ($data[\"programming_languages\"] as $pm) {\n            $this->programming_languages[] = $pm;\n        }\n    }\n\n    public function toString()\n    {\n        echo \"\\n\\n\\n====== FROM \" . $this->source . \" ======\\n\";\n        echo \"Name: \" . $this->name . \"\\n\" . \"Age: \" . $this->age . \"\\n\" . \"Birthday: \" . $this->birthDate . \"\\n\" . \"Programming Languages:\\n\";\n        foreach ($this->programming_languages as $pm) {\n            echo \"  - \" . $pm . \"\\n\";\n        }\n        echo \"======================\\n\\n\\n\";\n    }\n}\n\nfunction class_from_json_creator($array)\n{\n    json_creator($array);\n    $json = json_reader();\n    json_deleter();\n\n    if ($json !== null) {\n        return new Person($json, \"JSON\");\n    }\n    return null;\n}\n\nfunction class_from_xml_creator($array)\n{\n    xml_creator($array);\n    $xml = xml_reader();\n    xml_deleter();\n\n    if ($xml !== null) {\n        return new Person($xml, \"XML\");\n    }\n    return null;\n}\n\n$array = [\"name\" => \"Gabrielcmoris\", \"age\" => 34, \"birthdate\" => \"15.12.1989\", \"programming_languages\" => [\"Javascript\", \"Typescript\", \"php\", \"rust\"]];\n$json_person = class_from_json_creator($array);\n$json_person->toString();\n$xml_person = class_from_xml_creator($array);\n$xml_person->toString();\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/php/miguelex.php",
    "content": "<?php \n\n$datos = array(\n    'nombre' => 'Miguelex',\n    'edad' => 48,\n    'fechanacimiento' => '1975-09-13',\n    'Lenguajes' => ['php', 'javascript', 'python', 'c#', 'java', 'pascal']\n);\n\necho \"\\n\\n\";\n\necho \"json\" . \"\\n\\n\";\n\n$json = json_encode($datos, JSON_PRETTY_PRINT);\n\nfile_put_contents('miguelex.json', $json);\n\n$datos_json = file_get_contents('miguelex.json');\n\necho $datos_json;\n\necho \"\\n\\n\";\n\necho \"xml\" . \"\\n\\n\";\n\n$xml = new SimpleXMLElement('<root/>');\n\nforeach($datos as $key => $value){\n    if(is_array($value)){\n        $subnode = $xml->addChild($key);\n        foreach($value as $k => $v){\n            $subnode->addChild(\"lenguaje\", $v);\n        }\n    } else {\n        $xml->addChild($key, $value);\n    }\n}\n\n$dom = dom_import_simplexml($xml)->ownerDocument;\n$dom->formatOutput = true; \n\nfile_put_contents('miguelex.xml', $dom->saveXML());\n\necho $dom->saveXML();\n\n// Extra\n\nclass Miguelex {\n    public $nombre;\n    public $edad;\n    public $fecha_nacimiento;\n    public $lenguajes;\n\n    public function fromJson(){\n        $datos = json_decode(file_get_contents('miguelex.json'), true);\n        $this->nombre = $datos['nombre'];\n        $this->edad = $datos['edad'];\n        $this->fecha_nacimiento = $datos['fecha nacimiento'];\n        $this->lenguajes = $datos['Lenguajes'];\n\n        unlink('miguelex.json');\n    }\n\n    public function fromXml(){\n        $xml_content = file_get_contents('miguelex.xml');\n    \n    // Verificamos si se cargó correctamente\n    if ($xml_content !== false) {\n        // Intentamos convertir la cadena XML en un objeto SimpleXMLElement\n        $xml = simplexml_load_string($xml_content);\n        \n        // Verificamos si se pudo cargar correctamente\n        if ($xml !== false) {\n            // Asignamos los valores de los elementos XML a los atributos de la clase\n            $this->nombre = (string) $xml->nombre;\n            $this->edad = (int) $xml->edad;\n            $this->fecha_nacimiento = (string) $xml->{'fecha nacimiento'};\n\n            // Recorremos los elementos 'lenguaje' dentro de 'Lenguajes'\n            $this->lenguajes = [];\n            foreach ($xml->Lenguajes->lenguaje as $lenguaje) {\n                $this->lenguajes[] = (string) $lenguaje;\n            }\n\n            // Eliminamos el archivo XML después de leerlo\n            unlink('miguelex.xml');\n        } else {\n            // Manejar el caso en que ocurra un error al cargar el archivo XML\n            echo \"Error: No se pudo cargar el archivo XML.\";\n        }\n    } else {\n        // Manejar el caso en que ocurra un error al leer el contenido del archivo XML\n        echo \"Error: No se pudo leer el contenido del archivo XML.\";\n    }\n    }\n\n    public function __toString(){\n        return \"Nombre: $this->nombre\\nEdad: $this->edad\\nFecha de nacimiento: $this->fecha_nacimiento\\nLenguajes: \" . implode(', ', $this->lenguajes);\n    }\n}\n\necho \"\\n\\n\";\n\necho \"De json a clase\\n\";\n\n$miguelex = new Miguelex();\n\n$miguelex->fromJson();\n\necho $miguelex;\n\necho \"\\n\\n\";\n\necho \"De xml a clase\\n\";\n\n$miguelex2 = new Miguelex();\n\n$miguelex2->fromXml();\n\necho $miguelex2;\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/Aldroide.py",
    "content": "\"\"\"\n    EJERCICIO:\n    Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n    siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n        - Nombre\n        - Edad\n        - Fecha de nacimiento\n        - Listado de lenguajes de programación\n    Muestra el contenido de los archivos.\n    Borra los archivos\n\"\"\"\n\nimport json\nimport xml.etree.ElementTree as ET\nimport os\n\n# Datos para crear los archivos JSON y XML\ndata = {\n    \"nombre\": \"Aldroide\",\n    \"edad\": 40,\n    \"fecha_nacimiento\": \"1983-09-24\",\n    \"lenguajes_programacion\": [\"Python\", \"C\", \"C++\"]\n}\n\n# Creamos el archivo JSON\nwith open(\"datos.json\", \"w\") as json_file:\n    json.dump(data, json_file, indent=4)\n\n# Creamos el archivo XML\nroot = ET.Element(\"datos\")\nfor key, value in data.items():\n    if isinstance(value, list):\n        subelement = ET.SubElement(root, key)\n        for item in value:\n            ET.SubElement(subelement, \"lenguaje\").text = item\n    else:\n        ET.SubElement(root, key).text = str(value)\n\ntree = ET.ElementTree(root)\ntree.write(\"datos.xml\")\n\n# Imprimir los archivos que se han creado\nwith open(\"datos.json\", \"r\") as json_file:\n    print(\"Contenido de datos.json:\")\n    print(json_file.read())\n\nwith open(\"datos.xml\", \"r\") as xml_file:\n    print(\"\\nContenido de datos.xml:\")\n    print(xml_file.read())\n\n# Borrar los archivos\n# os.remove(\"datos.json\")\n# os.remove(\"datos.xml\") Se comentan estas lineas para que funcione el codigo siguinte sin replicar el anterior\n\n\"\"\"\n    Utilizando la lógica de creación de los archivos anteriores, crea un\n    programa capaz de leer y transformar en una misma clase custom de tu \n    lenguaje los datos almacenados en el XML y el JSON.\n\"\"\"\n\n\nclass UserData:\n    def __init__(self, nombre, edad, fecha_nacimiento, lenguajes_programacion):\n        self.nombre = nombre\n        self.edad = edad\n        self.fecha_nacimiento = fecha_nacimiento\n        self.lenguajes_programacion = lenguajes_programacion\n\n    @classmethod\n    def read_json(usr_data, na_file):\n        # Leer archivo JSON\n        with open(\"datos.json\", \"r\") as json_file:\n            json_data = json.load(json_file)\n            # Crear instancia de UserData con los datos del JSON\n            return usr_data(\n                json_data[\"nombre\"],\n                json_data[\"edad\"],\n                json_data[\"fecha_nacimiento\"],\n                json_data[\"lenguajes_programacion\"])\n\n    @classmethod\n    def read_xml(usr_data, na_file):\n        # Leer archivo XML\n        tree = ET.parse(\"datos.xml\")\n        root = tree.getroot()\n        # Extraer datos del XML\n        nombre = root.find(\"nombre\").text\n        edad = int(root.find(\"edad\").text)\n        fecha_nacimiento = root.find(\"fecha_nacimiento\").text\n        lenguajes_programacion = [\n            elem.text for elem in root.find(\"lenguajes_programacion\")]\n        # Crear instancia de UserData con los datos del XML\n        return usr_data(\n            nombre, edad, fecha_nacimiento, lenguajes_programacion)\n\n    def __str__(self):\n        return f\"Nombre: {self.nombre}\\nEdad: {self.edad}\\nFecha de nacimiento: {self.fecha_nacimiento}\\nLenguajes de programación: {', '.join(self.lenguajes_programacion)}\"\n\n\n# Mostrar datos de ambas instancias\nprint(\"\\nDatos del JSON:\")\nprint(UserData.read_json(\"datos.json\"))\n\nprint(\"\\nDatos del XML:\")\nprint(UserData.read_xml(\"datos.xml\"))\n\n\nos.remove(\"datos.json\")\nos.remove(\"datos.xml\")\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/CaveroBrandon.py",
    "content": "\"\"\"EJERCICIO:\nDesarrolla un programa capaz de crear un archivo XML y JSON que guarde los\nsiguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n- Nombre\n- Edad\n- Fecha de nacimiento\n- Listado de lenguajes de programación\nMuestra el contenido de los archivos.\nBorra los archivos.\"\"\"\n\nimport json\nimport os\nimport xml.etree.ElementTree as ET\n\n\nclass JsonFile:\n    def __init__(self, path):\n        self.file_path = f'{path}.json'\n\n    def create_json(self):\n        data = {\n            'name': \"Brandon\",\n            'age': 20,\n            'dob': \"05/20/1994\",\n            'language': ['Python', 'Matlab', 'C#']\n        }\n        with open(self.file_path, \"w\") as json_file:\n            json.dump(data, json_file, indent=4)\n\n    def show_json(self):\n        with open(self.file_path, \"r\") as json_file:\n            data = json.load(json_file)\n        print(json.dumps(data, indent=4))\n\n    def remove_json(self):\n        if os.path.exists(self.file_path):\n            os.remove(self.file_path)\n            print(f\"The file '{self.file_path}' has been removed.\")\n        else:\n            print(f\"The file '{self.file_path}' does not exist.\")\n\n\nclass XmlFile:\n    def __init__(self, path):\n        self.file_path = f'{path}.xml'\n\n    def create_xml(self):\n        root = ET.Element('data')\n\n        name = ET.SubElement(root, 'name')\n        name.text = 'Brandon'\n        age = ET.SubElement(root,'age')\n        age.text = '29'\n        dob = ET.SubElement(root, 'dob')\n        dob.text = '05/20/1994'\n        language = ET.SubElement(root, 'language')\n        language.text = str(['Python', 'Matlab', 'C#'])\n\n        tree = ET.ElementTree(root)\n\n        tree.write(self.file_path, encoding=\"utf-8\", xml_declaration=True)\n\n    def show_xml(self):\n        tree = ET.parse(self.file_path)\n\n        root = tree.getroot()\n\n        for child in root:\n            print(f'{child.tag}: {child.text}')\n\n    def remove_xml(self):\n        if os.path.exists(self.file_path):\n            os.remove(self.file_path)\n            print(f\"The file '{self.file_path}' has been removed.\")\n        else:\n            print(f\"The file '{self.file_path}' does not exist.\")\n\n\"\"\"DIFICULTAD EXTRA (opcional):\nUtilizando la lógica de creación de los archivos anteriores, crea un\nprograma capaz de leer y transformar en una misma clase custom de tu \nlenguaje los datos almacenados en el XML y el JSON.\nBorra los archivos.\"\"\"\n\n\ndef print_transformed_information(name, age, dob, language):\n    print(f'Name: {name}\\n'\n          f'Age: {age}\\n'\n          f'Date of Birth: {dob}\\n'\n          f'Language: {language}')\n\n\ndef read_transform_json(path):\n    file_path = f'{path}.json'\n\n    with open(file_path, 'r') as json_file:\n        data = json.load(json_file)\n\n    name = data['name']\n    age = data['age']\n    dob = data['dob']\n    languages = data['language']\n    print_transformed_information(name, age, dob, languages)\n\n\ndef read_transform_xml(path):\n    file_path = f'{path}.xml'\n    tree = ET.parse(file_path)\n    root = tree.getroot()\n\n    name = root.find('name').text\n    age = root.find('age').text\n    dob = root.find('dob').text\n    language = root.find('language').text\n    print_transformed_information(name, age, dob, language)\n\n\njson_path = 'myjson'\nxml_path = 'myxml'\n\nprint('******** JSON ********')\n\njson_file = JsonFile(json_path)\njson_file.create_json()\nprint('\\n**** Transformed values from the JSON file ****')\nread_transform_json(json_path)\nprint('\\n**** JSON File ****')\njson_file.show_json()\njson_file.remove_json()\n\nprint('\\n******** XML ********')\n\nxml_file = XmlFile(xml_path)\nxml_file.create_xml()\nprint('\\n**** Transformed values from the XML file ****')\nread_transform_xml(xml_path)\nprint('\\n**** XML File ****')\nxml_file.show_xml()\nxml_file.remove_xml()\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/CesarCarmona30.py",
    "content": "'''\n  EJERCICIO\n'''\n\nimport json\nimport os\nimport xml.etree.ElementTree as ET\n\nuser_data = {\n  'name': 'César',\n  'age': 19,\n  'birthDate': '30-07-2004',\n  'progLanguages': ['Java', 'C++', 'Python', 'JavaScript']\n}\n\njson_name = \"CesarCarmona30.json\"\n\nwith open(json_name, \"w\", encoding=\"UTF-8\") as file:\n  json.dump(user_data, file, indent=2, ensure_ascii=False)\n\nwith open(json_name, \"r\", encoding=\"UTF-8\") as file:\n  json_data = json.load(file)\n\nprint(json_data)\n\nos.remove(json_name)\n\nxml_name = \"CesarCarmona30.xml\"\nroot = ET.Element(\"userData\")\n\nname = ET.SubElement(root, \"name\")\nname.text = \"César\"\n\nage = ET.SubElement(root, \"age\")\nage.text = \"19\"\n\nbirth_date = ET.SubElement(root, \"birthDate\")\nbirth_date.text = \"30-07-2004\"\n\nprog_languages = ET.SubElement(root, \"progLanguages\")\n\nlang_1 = ET.SubElement(prog_languages, \"Language\")\nlang_1.text = \"Java\"\n\nlang_2 = ET.SubElement(prog_languages, \"Language\")\nlang_2.text = \"C++\"\n\nlang_3 = ET.SubElement(prog_languages, \"Language\")\nlang_3.text = \"Python\"\n\nlang_4 = ET.SubElement(prog_languages, \"Language\")\nlang_4.text = \"JavaScript\"\n\ntree= ET.ElementTree(root)\ntree.write(xml_name, \"utf-8\", True)\n\nxml_data = ET.parse(xml_name)\nroot_data= xml_data.getroot()\nfor data in root_data:\n  if data.tag == \"progLanguages\":\n    print(f'{data.tag}:')\n    for lang in data.findall('Language'):\n      print(f\"\\t{lang.tag}: {lang.text}\")\n  else:\n    print(f'{data.tag}: {data.text}')\n\nos.remove(xml_name)\n\n'''\n  EXTRA\n'''\n\nclass UserData:\n    def __init__(self, name, age, birth_date, prog_languages):\n        self.name = name\n        self.age = age\n        self.birth_date = birth_date\n        self.prog_languages = prog_languages\n\n    @classmethod\n    def from_json(cls, json_data):\n        return cls(json_data['name'], json_data['age'], json_data['birthDate'], json_data['progLanguages'])\n\n    @classmethod\n    def from_xml(cls, xml_data):\n        name = xml_data.find('name').text\n        age = int(xml_data.find('age').text)\n        birth_date = xml_data.find('birthDate').text\n        prog_languages = [lang.text for lang in xml_data.find('progLanguages')]\n        return cls(name, age, birth_date, prog_languages)\n\n    def display(self):\n        print(f'Name: {self.name}')\n        print(f'Age: {self.age}')\n        print(f'Birth Date: {self.birth_date}')\n        print('Programming Languages:')\n        for lang in self.prog_languages:\n            print(f'\\t- {lang}')\n\nfile_name = \"user\"\n\nwith open(f'{file_name}.json', 'w', encoding='utf-8') as json_file:\n    json.dump(user_data, json_file, indent=2, ensure_ascii=False)\n\nwith open(f'{file_name}.json', 'r', encoding='utf-8') as json_file:\n    json_data = json.load(json_file)\n    user_from_json = UserData.from_json(json_data)\n    print('\\nData from JSON:')\n    user_from_json.display()\n\ntree.write(f'{file_name}.xml', \"utf-8\", True)\n\nxml_data = ET.parse(f'{file_name}.xml').getroot()\nuser_from_xml = UserData.from_xml(xml_data)\nprint('\\nData from XML:')\nuser_from_xml.display()\n\nos.remove(f'{file_name}.json')\nos.remove(f'{file_name}.xml')"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/Chrisdev00.py",
    "content": "\"\"\"\n* IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n* \n* EJERCICIO:\n* Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n* siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n* - Nombre\n* - Edad\n* - Fecha de nacimiento\n* - Listado de lenguajes de programación\n* Muestra el contenido de los archivos.\n* Borra los archivos.\n*\n* DIFICULTAD EXTRA (opcional):\n* Utilizando la lógica de creación de los archivos anteriores, crea un\n* programa capaz de leer y transformar en una misma clase custom de tu \n* lenguaje los datos almacenados en el XML y el JSON.\n* Borra los archivos.\n\"\"\"\n\nimport json\nimport os\n\n# Crear archivo json\n\ndatos_json = {\n    \"Nombre\": \"Christian\",\n    \"Edad\": \"30\",\n    \"Fecha de nacimiento\": \"01/05/1994\",\n    \"Listado de lenguajes\": [\"Python\", \"JavaScript\", \"React\"]\n}\n\nfile_name = \"Chrisdev00.json\"\n\nwith open(file_name, \"w\") as file_json:\n    json.dump(datos_json, file_json, indent=4) # (ident=) para que el archivo json tenga una apariencia mas legible con identaciones\n\n# Mostrar el contenido\n    \nwith open(file_name, \"r\") as file_json:\n    lista_datos = json.load(file_json)\n\nprint(\"Datos en el archivo JSON\")\nfor clave, valor in lista_datos.items():\n    print(f\"{clave}: {valor}\")\n\n# Borrar el archivo\n\nif os.path.exists(file_name):\n    #os.remove(file_name)  comentamos esta parte para que el ejercicio extra no de error\n    pass\nelse:\n    print(\"El archivo no existe\")\n\n\n# Crear archivo XML\n    \nimport xml.etree.ElementTree as ET\n\nroot = ET.Element(\"datos\")\n\nnombre = ET.SubElement(root, \"nombre\")\nnombre.text = \"Christian\"\n\nedad = ET.SubElement(root, \"edad\")\nedad.text = \"30\"\n\nfecha_nacimiento = ET.SubElement(root, \"fecha_nacimiento\")\nfecha_nacimiento.text = \"01/05/1994\"\n\nlenguajes = ET.SubElement(root, \"Listado_de_lenguajes\")\nlenguajes.text = \"Python, JavaScript, React\"\n\ntree_xml = ET.ElementTree(root)\nfile_name_xml = \"Chrisdev00.xml\"\n\ntree_xml.write(file_name_xml, encoding=\"utf-8\", xml_declaration=True)\n\n# mostrar datos\n\ntree_xml = ET.parse(file_name_xml)\n\nraiz = tree_xml.getroot()\n\nprint(\"Datos en el archivo XML\")\nfor elemento in raiz:\n    print(f\"{elemento.tag}: {elemento.text}\")\n\n# borrar archivo\n    \n#os.remove(file_name_xml) comentamos esta parte para que funcione el ejercicio extra\n\n\n##### -------------------------------- EXTRA -------------------------------------------- ########\n\n\n\nclass DatosPersonales:\n\n    def __init__(self, nombre, edad, fecha_nacimiento, lenguajes):\n        self.nombre = nombre\n        self.edad = edad\n        self.fecha_nacimiento = fecha_nacimiento\n        self.lenguajes = lenguajes\n    \n    @classmethod\n    def leer_json (cls, nombre_archivo_json):\n        with open(nombre_archivo_json, \"r\") as file:\n            datos_jso = json.load(file)\n            return cls(\n                datos_jso[\"Nombre\"],\n                datos_jso[\"Edad\"],\n                datos_jso[\"Fecha de nacimiento\"],\n                datos_jso[\"Listado de lenguajes\"],\n            )\n    \n    @classmethod\n    def leer_xml (cls, nombre_archivo_xml):\n        tree_xml = ET.parse(nombre_archivo_xml)\n        raiz = tree_xml.getroot()\n        nombre = raiz.find(\"nombre\").text\n        edad = raiz.find(\"edad\").text\n        fecha_nacimiento = raiz.find(\"fecha_nacimiento\").text\n        lenguajes_str = raiz.find(\"Listado_de_lenguajes\").text\n        lenguajes = lenguajes_str.split(\", \")\n        #lenguajes = [lenguaje.text for lenguaje in raiz.find(\"Listado_de_lenguajes\")]\n        return cls(nombre, edad, fecha_nacimiento, lenguajes)\n    \n    def __str__(self):\n        return f\"Nombre: {self.nombre}\\nEdad: {self.edad}\\nFecha de nacimiento: {self.fecha_nacimiento}\\nLenguajes: {', '.join(self.lenguajes)}\"\n\ndesde_json = DatosPersonales.leer_json(\"Chrisdev00.json\")\ndesde_xml = DatosPersonales.leer_xml(\"Chrisdev00.xml\")\n\nprint(\"\\nDatos desde JSON:\")\nprint(desde_json)\nprint(\"\\nDatos desde XML:\")\nprint(desde_xml)\n\n\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/Complex303.py",
    "content": "import os\nimport xml.etree.ElementTree as xml # 📦 Módulo para trabajar con XML\nimport json\n\"\"\"\nJSON Y XML\n\"\"\"\n\n#JSON: Formato ligero de texto para almacenar datos usando llaves {} y corchetes [].\n#XML: Formato de texto para almacenar datos usando etiquetas <etiqueta> </etiqueta>.\n\n#ALT + SHIFT + F\n\n# Diccionario de datos con diferentes tipos de valores\ndata = {\n    \"name\": \"Complex_303\",\n    \"age\": 24,\n    \"birth_date\": \"01-01-2001\",\n    \"programming_languages\": [\"Python\", \"SQL\", \"C#\"]\n}\n\n\n#XML\n# Nombre del archivo XML que se va a crear\nxml_file = \"Complex_303.xml\"\n\n# 📌 Definir función para guardar los datos en formato XML\ndef create_xml():\n\n    # Crear elemento raíz del XML llamado <data>\n    root = xml.Element(\"data\")\n\n    # Recorrer el diccionario data clave-valor\n    for key, value in data.items():\n        # Crear un subelemento para cada clave (ej. <name>, <age>, etc.)\n        child = xml.SubElement(root, key)\n\n        # Si el valor es una lista (ej. lista de lenguajes de programación)\n        if isinstance(value, list):\n            # Por cada elemento en la lista, crear un subelemento <item> y asignarle su valor\n            for item in value:\n                xml.SubElement(child, \"item\").text = item\n        else:\n            # Si no es lista, se asigna directamente el valor como texto\n            child.text = str(value)\n\n    # Crear árbol XML a partir del elemento raíz\n    tree = xml.ElementTree(root)\n\n    # Escribir el árbol en un archivo XML\n    tree.write(xml_file)\n\n# 📌 Llamar a la función para generar el archivo\ncreate_xml()\n\n#Abril el archivo y leerlo\nwith open(xml_file, \"r\") as xml_data: \n    print(xml_data.read())\n\n#os.remove(xml_file) #borrarlo\n\n\n#JSON\njson_file = \"Complex_303.json\"\n\n\ndef create_json():\n\n# 📌 Abrimos (o creamos) el archivo en modo escritura (\"w\")\n# con el nombre json_file, y lo llamamos json_data dentro del bloque\n    with open(json_file, \"w\") as json_data:\n        # Convertimos un diccionario (o cualquier estructura válida) a JSON \n        # y lo escribimos en el archivo abierto\n        json.dump(data, json_data)\n\ncreate_json()\n\n# Ahora abrimos el mismo archivo pero en modo lectura (\"r\")\nwith open(json_file, \"r\") as json_data: \n    # Leemos todo el contenido del archivo JSON y lo mostramos por pantalla\n    print(json_data.read())\n\n# Finalmente eliminamos el archivo JSON que creamos\n#os.remove(json_file)\n\n\n\"\"\" DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu \n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\"\"\"\n\n\n# Definimos una clase llamada Data para almacenar información estructurada\nclass Data:\n    # Método constructor que se ejecuta al crear una instancia de Data\n    def __init__(self, name, age, birth_date, programming_languages):\n        # Guardamos los valores recibidos en atributos de la clase\n        self.name = name\n        self.age = age\n        self.birth_date = birth_date\n        self.programming_language = programming_languages\n\n\n# Abrimos el archivo XML en modo lectura\nwith open(\"Complex_303.xml\", \"r\") as xml_data:\n    # Leemos y convertimos el contenido XML en una estructura de árbol\n    root = xml.fromstring(xml_data.read())\n    \n    # Buscamos y extraemos el texto de cada etiqueta usando find()\n    name = root.find(\"name\").text\n    age = root.find(\"age\").text\n    birth_date = root.find(\"birth_date\").text\n    \n    # Creamos una lista vacía para almacenar los lenguajes de programación\n    programming_languages = []\n    # Iteramos sobre los elementos <item> dentro de <programming_languages>\n    for item in root.find(\"programming_languages\"):\n        programming_languages.append(item.text)\n    \n    # Creamos una instancia de la clase Data usando los valores extraídos del XML\n    xml_class = Data(name, age, birth_date, programming_languages)\n    # Imprimimos los atributos de esa instancia en forma de diccionario\n    print(xml_class.__dict__)\n\n\n# Abrimos el archivo JSON en modo lectura\nwith open(\"Complex_303.json\", \"r\") as json_data:\n    # Cargamos el contenido JSON y lo convertimos en diccionario de Python\n    json_dict = json.load(json_data)\n    \n    #Creamos una instancia de la clase Data usando los valores extraídos del JSON\n    json_class = Data(\n        json_dict[\"name\"], \n        json_dict[\"age\"], \n        json_dict[\"birth_date\"], \n        json_dict[\"programming_languages\"]\n    )\n    \n    #Imprimimos los atributos de esa instancia en forma de diccionario\n    print(json_class.__dict__)\n\n\n# Eliminamos los archivos XML y JSON que habíamos usado\nos.remove(\"Complex_303.xml\")\nos.remove(\"Complex_303.json\")\n\n\n\n\n\n# fromstring()\tConvierte texto XML en árbol DOM\n# find()\tBusca una etiqueta XML específica\n# for item in ...\tItera sobre subetiquetas <item> dentro de una lista XML\n# json.load()\tCarga un JSON desde archivo a diccionario\n# __dict__\tDevuelve los atributos de una instancia como diccionario\n# os.remove()\tBorra archivos físicos del sistema\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/DaniQB99.py",
    "content": "'''\nEJERCICIO:\nDesarrolla un programa capaz de crear un archivo XML y JSON que guarde\nlos siguientes datos (hacindo uso de la sintaxis correcta en cada caso):\n\n- Nombre\n- Edad\n- Fecha de nacimiento\n- Listado de Lenguajes de programación\nMuestra el contenido de los archivos.\nBorra los archivos.\n'''\n\nimport xml.etree.ElementTree as xml\nimport json\nimport os\n\n# OBJETO\ndata = {\n    \"name\" : \"Dani\",\n    \"age\" : \"25\",\n    \"birth_date\" : \"26-07-1999\",\n    \"programming_languages\" : ['Python', 'Java', 'HTML', 'CSS']\n}\n\nxml_file = \"DaniQB99.xml\"\n\n# XML\n\n# ESCRIBIR XML\ndef save_xml():\n    \n    with open(xml_file, \"w\") as file:\n        root = xml.Element(\"data\")\n    \n        for key, value in data.items(): \n            child = xml.SubElement(root, key)\n            if isinstance(value, list):\n                for item in value: \n                    xml.SubElement(child, \"item\").text = item\n            else:\n                child.text = str(value)\n        \n        tree = xml.ElementTree(root)\n        tree.write(xml_file)\n\nsave_xml()\n\n# LEER XML\ndef read_xml():\n    \n    with open(xml_file, \"r\") as xml_data:\n        print('XML')\n        print(xml_data.read())\n        \n\n        \nread_xml()\n\n# BORRAR XML\nos.remove(xml_file)\n\n# JSON\n\njson_file = \"DaniQB99.json\"\n\n# ESCRIBIR JSON\ndef save_json():\n\n    with open(json_file, \"w\") as json_data:\n        json.dump(data, json_data)\n\nsave_json()\n\n# LEER JSON\ndef read_json():\n\n    with open(json_file, \"r\") as json_data:\n        print('JSON')\n        print(json_data.read())\n        \nread_json()\n\n# BORRAR JSON\nos.remove(json_file)\n\n'''\nDIFICULTAD EXTRA (opcional):\nUtilizando la lógica de creación de los archivos anteriores, crea un\nprograma capaz de leer y transformar en una misma clase custom de tu \nlenguaje los datos almacenados en el XML y el JSON.\nBorra los archivos.\n'''\n\nprint(\"\\nEJERCICIO EXTRA\\n\")\n\nsave_xml()\nsave_json()\n\n# CLASE CUSTOM\nclass Data():       \n    def __init__(self, name, age, birth_date, programming_languages) -> None:\n        self.name = name\n        self.age = age\n        self.birth_date = birth_date\n        self.programming_languages = programming_languages  \n        \n\n# CLASE XML\nwith open (xml_file, 'r') as xml_data:\n    \n    root = xml.fromstring(xml_data.read()) # xml.fromstring() es un metodo de xml para leer el xml\n    name = root.find(\"name\").text\n    age =root.find(\"age\").text\n    birth_date = root.find(\"birth_date\").text\n    programming_languages = []\n    for item in root.find(\"programming_languages\"):\n        programming_languages.append(item.text)\n     \n    xml_class = Data(name, age, birth_date, programming_languages)\n    print('XML')\n    print(xml_class.__dict__)\n\n\n# ClASE JSON\nwith open (json_file, 'r') as json_data:\n\n    json_dict = json.load(json_data) # json.load() es un metodo de json para leer el diccionario\n    json_class = Data(\n        json_dict['name'],\n        json_dict['age'],\n        json_dict['birth_date'],\n        json_dict['programming_languages']\n    )\n    print('JSON')\n    print(json_class.__dict__)\n        \nos.remove(xml_file)\nos.remove(json_file)"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/Dkp-Dev.py",
    "content": "import os\nimport xml.etree.ElementTree as xml\nimport json\n\ndata = {\n    \"name\": \"Dkp Dev\",\n    \"age\": 29,\n    \"birth_date\": \"11-01-1995\",\n    \"programming_languages\": [\"Python\", \"Kotlin\", \"Java\"]\n}\n\nxml_file = \"dkp-dev.xml\"\njson_file = \"dkp-dev.json\"\n\n\"\"\"\nEJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n\"\"\"\n\n# XML\n\n\ndef create_xml():\n\n    root = xml.Element(\"data\")\n\n    for key, value in data.items():\n        child = xml.SubElement(root, key)\n        if isinstance(value, list):\n            for item in value:\n                xml.SubElement(child, \"item\").text = item\n        else:\n            child.text = str(value)\n\n    tree = xml.ElementTree(root)\n    tree.write(xml_file)\n\n\ncreate_xml()\n\nwith open(xml_file, \"r\") as xml_data:\n    print(xml_data.read())\n\nos.remove(xml_file)\n\n# JSON\n\n\ndef create_json():\n    with open(json_file, \"w\") as json_data:\n        json.dump(data, json_data)\n\n\ncreate_json()\n\nwith open(json_file, \"r\") as json_data:\n    print(json_data.read())\n\nos.remove(json_file)\n\n\"\"\"\n DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu \n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n\"\"\"\n\ncreate_xml()\ncreate_json()\n\n\nclass Data:\n\n    def __init__(self, name, age, birth_date, programming_languages) -> None:\n        self.name = name\n        self.age = age\n        self.birth_date = birth_date\n        self.programming_languages = programming_languages\n\n\nwith open(xml_file, \"r\") as xml_data:\n\n    root = xml.fromstring(xml_data.read())\n    name = root.find(\"name\").text\n    age = root.find(\"age\").text\n    birth_date = root.find(\"birth_date\").text\n    programming_languages = []\n    for item in root.find(\"programming_languages\"):\n        programming_languages.append(item.text)\n\n    xml_class = Data(name, age, birth_date, programming_languages)\n    print(xml_class.__dict__)\n\n\nwith open(json_file, \"r\") as json_data:\n    json_dict = json.load(json_data)\n    json_class = Data(\n        json_dict[\"name\"],\n        json_dict[\"age\"],\n        json_dict[\"birth_date\"],\n        json_dict[\"programming_languages\"]\n    )\n    print(json_class.__dict__)\n\nos.remove(xml_file)\nos.remove(json_file)\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/EmmanuelMMontesinos.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n */\n\"\"\"\n\n# Ejercicio Base\n\n# Super Clase Custom\nclass Custom:\n    def delete(self,archivo_custom):\n        os.remove(archivo_custom)\n\n\n'''JSON'''\n\n# Necesito el modulo os para borrar los archivos\nimport os\nimport json\n\nclass CustomJson(Custom):\n    archivo_json = \"emmanuelmmontesinos.json\"\n    def add_json(self,nombre,edad,fecha,lenguajes):\n        datos = {\n            \"nombre\":nombre,\n            \"edad\":edad,\n            \"fecha\":fecha,\n            \"lenguajes\":lenguajes    \n        }\n        \n        with open(CustomJson.archivo_json,\"w\") as archivo:\n            json.dump(datos,archivo, indent= 4)\n    \n    def show(self):\n        with open(CustomJson.archivo_json,\"r\") as archivo:\n            print(json.load(archivo))\n    \n    def delete(self):\n        return super().delete(CustomJson.archivo_json)\n    \n\n# Pruebas Json\nprueba = CustomJson()\nprueba.add_json(\"Emmanuel\",33,\"17/05/999\",[\"Python\",\"Bash\"])\nprueba.show()\nprueba.delete()\n\n'''XML'''\n\nimport xml.etree.ElementTree as ET\n\nclass CustomXml(Custom):\n    archivo_xml = \"emmanuelmmontesinos.xml\"\n    ficha = ET.Element(\"Ficha\")\n    ficha.text = \"Ficha\"\n    def add_xml(self,nombre,edad,fecha,lenguajes):\n        nombre_root = ET.SubElement(CustomXml.ficha,\"nombre\")\n        nombre_root.text = nombre\n        \n        edad_root = ET.SubElement(CustomXml.ficha,\"edad\")\n        edad_root.text = edad\n        \n        fecha_root = ET.SubElement(CustomXml.ficha,\"fecha\")\n        fecha_root.text = fecha\n        \n        lenguajes_root = ET.SubElement(CustomXml.ficha,\"lenguajes\")\n        lenguajes_root.text = \",\".join(lenguajes)\n        tree = ET.ElementTree(CustomXml.ficha)\n        tree.write(file_or_filename=CustomXml.archivo_xml,encoding=\"utf-8\",xml_declaration=True)\n    def show_xml(self):\n        ficha = ET.parse(CustomXml.archivo_xml)\n        root = ficha.getroot()\n        ET.dump(root)\n    def delete(self):\n        super().delete(CustomXml.archivo_xml)\n        \nprueba_xml = CustomXml()\nprueba_xml.add_xml(\"emmanuel\",\"33\",\"17/05/999\",[\"Python\",\"Bash\"])\nprueba_xml.show_xml()\nprueba_xml.delete()\n\n# Ejercicio Extra\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu \n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n\"\"\"\nclass CustomClass:\n    def __init__(self,archivo:str) -> None:\n        self.archivo = archivo\n        if archivo.endswith(\".xml\"):\n            ficha = ET.parse(archivo)\n            root = ficha.getroot()\n            self.tipo = \"XML\"\n            self.nombre = root.find('nombre').text\n            self.edad = root.find('edad').text\n            self.fecha = root.find('fecha').text\n            lenguajes_elem = root.find('lenguajes')\n            self.lenguajes = lenguajes_elem.text.split(\",\")\n        elif archivo.endswith(\".json\"):\n            with open(archivo,\"r\") as importado:\n                datos = json.load(importado)\n            self.tipo = \"JSON\"\n            self.nombre = datos[\"nombre\"]\n            self.edad = datos[\"edad\"]\n            self.fecha = datos[\"fecha\"]\n            self.lenguajes = datos[\"lenguajes\"]\n            pass\n    def mostrar(self):\n        print(f\"Tipo: {self.tipo}\")\n        print(f\"Nombre: {self.nombre}\")\n        print(f\"Edad: {self.edad}\")\n        print(f\"Fecha: {self.fecha}\")\n        print(f\"Lenguajes: {self.lenguajes}\")\n    \n    def delete(self):\n        os.remove(self.archivo)\n        print(\"Archivo eliminado\")\n        \n# prueba_clase = CustomClass(\"prueba.xml\")\n# prueba_clase.mostrar()\nprueba_clase = CustomClass(\"prueba.json\")\nprueba_clase.mostrar()\nprueba_clase.delete()"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/FedeAirala.py",
    "content": "# Reto 12 JSON Y XML\n\n\"\"\"\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n * \n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n \"\"\"\n\nimport xml.etree.ElementTree as ET\nimport os\nimport json\n\n# Datos con los que trabajaremos\n\ndata = {\n    \"name\": \"Fede Airala\",\n    \"age\": 43,\n    \"birth_day\": \"25/06/1980\",\n    \"programming_languages\": [\"Python\", \"MySql\",\"Java\"]\n}\n\ndata2 = {\n    \"name\": \"Juan Perez\",\n    \"age\": 25,\n    \"birth_day\": \"03/08/1970\",\n    \"programming_languages\": [\"Javascript\", \"MySql\"]\n}\n\nxml_file = \"new_data.xml\"\njson_file = \"new_data.json\"\n\n\n\n\n# Creación de archivo xml\n\ndef create_xml():                                         # Función para crear archivos xml\n\n    datos = ET.Element(\"datos\")                           # Se crea un elemento tipo xml de nombre datos\n\n    for key,value in data.items():                        # Se recorre los datos del diccionario creado data\n        eDatos = ET.SubElement(datos,key)                 # Le asignamos a una variable un sub elemento  del elemento datos antes creado y le pasamos la llave del dicc\n        if isinstance(value,list):                        # Preguntamos si el tipo de valor es una lista\n            for i in value:                               # Si es una lista, la recorremos\n                ET.SubElement(eDatos,\"item\").text = i     # y escribimos por cada subelemento el valor\n        else:                                             # Si no es una lista\n            eDatos.text = str(value)                      # se escribe directamente el valor\n    \n    tree = ET.ElementTree(datos)                          # Se crea un árbol de los elementos antes creados\n    tree.write(xml_file)                                  \n\ncreate_xml()\n\nwith open(xml_file, \"r\") as file:                         # Abre el archivo xml de tipo lectura\n    print(file.read())                                    # Imprime por pantalla el archivo xml\n\nos.remove(\"new_data.xml\")                                 # Elimina el fichero creado\n\nprint (\"-\"*60)\n\n# Creación de archivo json\n\ndef create_json():                                        # Función para crear archivos json\n\n    with open (json_file, \"w\") as file:                   # Abre el archivo tipo escritura\n        json.dump(data2,file,indent=4)                    # Se pasan los datos a crear tipo de archivo json\n\ncreate_json()\n\nwith open(json_file, \"r\") as file:                       # Abre el archivo json de tipo lectura\n    print(file.read())                                   # Imprime por pantalla el archivo json\n\nos.remove(\"new_data.json\")                               # Elimina el fichero creado\n\nprint (\"-\"*60)\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu \n * lenguaje los datos almacenados en el XML y el JSON.\n\"\"\"\ntry:\n    create_xml()\n\n\n    class Data:\n        def __init__(self,name,age,birthday,languages) -> None:\n            self.name = name\n            self.age = age\n            self.birthday =birthday\n            self.languages = languages\n        \n        def print (self):\n            print (f\"Nombre y Apellido: {self.name}\")\n            print (f\"Edad: {self.age}\")\n            print (f\"Fecha de Nacimiento: {self.birthday}\")\n            print (f\"Lenguages: {self.languages}\")\n\n\n    with open (xml_file, \"r\") as file:\n    \n        raiz = ET.fromstring(file.read())\n        name = raiz.find(\"name\").text   \n        age = raiz.find(\"age\").text   \n        birth_day = raiz.find(\"birth_day\").text \n        languages = []\n        for i in raiz.find(\"programming_languages\"):\n            languages.append(i.text)\n        xml_class = Data(name,age,birth_day,languages)\n        print (\"xml a Clase Custom\")\n        xml_class.print()\n    create_json()\n\n    print (\"-\"*60)\n\n    with open(json_file, \"r\") as file:\n        json_data = json.load(file)\n        json_class = Data(\n            json_data[\"name\"],\n            json_data[\"age\"],\n            json_data[\"birth_day\"],\n            json_data[\"programming_languages\"])\n        print (\"Json a Clase Custom\")\n        json_class.print()\n\nexcept Exception as e:\n    print(\"Error \",e)\n\nfinally:\n    os.remove(\"new_data.xml\") \n    os.remove(\"new_data.json\")     \n\n\n\n    \n\n\n\n\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/Gallitofast.py",
    "content": "#JSON & XML\n\"\"\" EJERCICIO:\n  Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n  siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n  - Nombre\n  - Edad\n  - Fecha de nacimiento\n  - Listado de lenguajes de programación\n  Muestra el contenido de los archivos.\n  Borra los archivos.\"\"\"\nimport json\nimport os\nimport xml.etree.ElementTree as ET\n\ndicc_json = {\"Nombre\":\"Jose\",\"Edad\":\"24\",\"Fecha_de_nacimiento\": \"02/04/2002\",\"Lista_de_lenguajes\": [\"Python\",\"Typescript\"]}\ndicc_xml = {\"Nombre\":\"Miguel\",\"Edad\":\"24\",\"Fecha_de_nacimiento\": \"02/04/2002\",\"Lista_de_lenguajes\": [\"Typescript\",\"Python\"]}\n\nxml_file = \"new_data.xml\"\njson_file = \"new_data.json\"\n\n#XML \ndef create_xml():\n    datos = ET.Element(\"datos\")\n    for key,value in dicc_xml.items():\n        eDatos = ET.SubElement(datos,key)  \n        if isinstance(value,list):\n            for i in value: \n                ET.SubElement(eDatos,\"item\").text = i\n        else: \n            eDatos.text = str(value)   \n    tree = ET.ElementTree(datos)     \n    ET.indent(tree, space=\"    \")\n    tree.write(xml_file)    \n\ncreate_xml()\nwith open(xml_file, \"r\") as file: \n    print(file.read())\nos.remove(\"new_data.xml\")  \n\n\n#JSON\n\nprint (\"-\"*60)\ndef create_json():\n    with open(json_file,\"w\") as file:\n        json.dump(dicc_json,file,indent=4)\n\n\ncreate_json()\nwith open(json_file,\"r\") as file:\n    print(file.read())\n\nos.remove(\"new_data.json\")\nprint (\"-\"*60)\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu \n * lenguaje los datos almacenados en el XML y el JSON.\n\"\"\"\n\ntry:\n    #XML\n    create_xml()\n\n    class Data():\n        def __init__(self,name,age,birthday,languages) -> None:\n            self.name = name\n            self.age = age\n            self.birthday =birthday\n            self.languages= languages\n        \n        def print (self):\n            print(f\"Nombre y apellido: {self.name}\")\n            print(f\"Edad: {self.age}\")\n            print(f\"Fecha de nacimiento: {self.birthday}\")\n            print(f\"Lenguajes de programacion: {self.languages}\")\n        \n    with open(xml_file,\"r\") as file:\n        raiz = ET.fromstring(file.read())\n        name = raiz.find(\"Nombre\").text\n        age = raiz.find(\"Edad\").text\n        birthday = raiz.find(\"Fecha_de_nacimiento\").text\n        languages = []\n        for i in raiz.find(\"Lista_de_lenguajes\"):\n            languages.append(i.text)\n        \n        xml_class= Data(name,age,birthday,languages)\n        print(\"xml a Clase custom\")\n        xml_class.print()\n    #Clase json\n    \n    create_json()\n    print(\"-\"*60)\n    with open(json_file,\"r\") as file:\n        json_data = json.load(file)\n        json_class = Data(\n            json_data[\"Nombre\"],\n            json_data[\"Edad\"],\n            json_data[\"Fecha_de_nacimiento\"],\n            json_data[\"Lista_de_lenguajes\"])\n        print(\"Json a Clase custom\")\n        json_class.print()\n\n\n\nexcept Exception as e:\n    print(\"Error\",e)\nfinally:\n    os.remove(\"new_data.xml\")\n    os.remove(\"new_data.json\")"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/Gordo-Master.py",
    "content": "### 12 - JSON y XML\nimport os\nimport xml.etree.ElementTree as xml\nimport json\n\n\nfile_name_1 = \"./xml_file.xml\"\nfile_name_2 = \"./json_file.json\"\n\n\ndef to_xml(name, age, date, languagues):\n\n    x = \"\"\n    for i in languagues:\n        x += f'\\n{\" \"*8}<languague>{i}</languague>'\n    \n    file = f'<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n<data>\\n{\" \"*4}<name>{name}</name>\\n{\" \"*4}<age>{age}</age>\\n{\" \"*4}<date>{date}</date>\\n{\" \"*4}<languagues>{x}\\n{\" \"*4}</languagues>\\n</data>'\n    with open(file_name_1,\"w\") as f:\n        f.write(file)\n\n\ndef to_json(name, age, date, languagues):\n\n    x = f'[\"{'\",\"'.join(languagues)}\"]'\n\n    file = f'{{\\n{\" \"*4}\"name\":\"{name}\",\\n{\" \"*4}\"age\":\"{age}\",\\n{\" \"*4}\"date\":\"{date}\",\\n{\" \"*4}\"languagues\":{x}\\n}}'\n    \n    with open(file_name_2,\"w\") as f:\n        f.write(file)\n\ndef to_print(file_name):\n    print()\n    with open (file_name, \"r\") as f:\n        \n        x = f.readlines()\n\n        for i in x:\n            if not i.startswith(\"<?\"):\n                print (i,end=\"\")\n\n\nto_xml(\"Gordo\",\"Master\",\"08-05-1995\",[\"C++\",\"Python\"])\nto_json(\"Gordo\",\"Master\",\"08-05-1995\",[\"C++\",\"Python\"])\n\n\nto_print(file_name_1)\nto_print(file_name_2)\n\n\nos.remove(file_name_1)\nos.remove(file_name_2)\n\n#############################################################################################\n#Forma numero 2#\n#############################################################################################\n\nfile_name_3 = \"./xml_file_v2.xml\"\nfile_name_4 = \"./json_file_v2.json\"\n\ndata = {\n        \"name\" : \"Gordo\",\n        \"age\" : \"29\",\n        \"date\" : \"08-05-1995\",\n        \"languagues\" : [\"C++\",\"Python\"]\n    }\n\ndef to_xml_v2():\n    \n    root = xml.Element(\"data\")\n\n    for key, value in data.items():\n        \n        child = xml.SubElement(root,key)\n\n        if isinstance(value, list):\n            for item in value:\n                xml.SubElement(child,\"item\").text = item\n        \n        else:\n            child.text = str(value)\n    \n    tree = xml.ElementTree(root)\n    tree.write(file_name_3)\n\n\n\ndef to_json_v2():\n\n    file = json.dumps(data,indent=4)\n\n    with open(file_name_4,\"w\") as f:\n            f.write(file)\n\nto_xml_v2()\nto_json_v2()\n\nto_print(file_name_3)\nto_print(file_name_4)\n\n\n### Ejercicio Extra ###\n\nclass Data():\n\n    def __init__(self, name, age, date, languagues) -> None:\n        self.name = name\n        self.age = age\n        self.date = date\n        self.languagues = languagues\n\n\nwith open(file_name_3,\"r\") as xml_data:\n\n    root = xml.fromstring(xml_data.read())\n    name = root.find(\"name\").text\n    age = root.find(\"age\").text\n    date = root.find(\"date\").text\n    languagues = []\n    for i in root.find(\"languagues\"):\n        languagues.append(i.text)\n\n    xml_class = Data(name,age,date,languagues)\n    print(xml_class.__dict__)\n\nwith open(file_name_4,\"r\") as json_data:\n\n    json_dict = json.load(json_data)\n    json_class = Data(\n        json_dict[\"name\"],\n        json_dict[\"age\"],\n        json_dict[\"date\"],\n        json_dict[\"languagues\"]\n    )\n    print(json_class.__dict__)\n\nos.remove(file_name_3)\nos.remove(file_name_4)\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/Hyromy.py",
    "content": "import os\nimport xml.etree.ElementTree as ET\nimport json\n\n# ---- xml ----\nroot = ET.Element(\"root\") # Crear el nodo raíz\n\nnombre = ET.SubElement(root, \"nombre\") # Crear un nodo hijo\nnombre.text = \"Hyromy\" # Asignar un valor al nodo hijo\n\nedad = ET.SubElement(root, \"edad\")\nedad.text = \"20\"\n\nfecha_nacimiento = ET.SubElement(root, \"fecha_nacimiento\")\nfecha_nacimiento.text = \"2004-12-04\"\n\nlenguajes = ET.SubElement(root, \"lenguajes\")\nlenguajes_list = [\"Java\", \"PHP\", \"C#\", \"Python\", \"JavaScript\"]\nfor lenguaje in lenguajes_list:\n    lenguaje_node = ET.SubElement(lenguajes, \"item\")\n    lenguaje_node.text = lenguaje\n\nxml_file_name = __file__[:-3] + \".xml\"\ntree = ET.ElementTree(root)\ntree.write(xml_file_name, encoding = \"utf-8\", xml_declaration = True)\ndel tree\ndel root\n\ntree = ET.parse(xml_file_name)\nroot = tree.getroot()\n\ndef read_xml(root : ET.Element, ident = 0):\n    for child in root:\n        if not len(child):\n            print(f\"{'\\t' * ident}<{child.tag}>{child.text}</{child.tag}>\")\n        else:\n                print(f\"{'\\t' * ident}<{child.tag}>\")\n                read_xml(child, ident + 1)\n                print(f\"{'\\t' * ident}</{child.tag}>\")\n\nread_xml(root)\nos.remove(xml_file_name)\n\nprint(\"\\n\\n\")\n\n# ---- json ----\njson_data = {\n    \"nombre\": \"Hyromy\",\n    \"edad\": 20,\n    \"fecha_nacimiento\": \"2004-12-04\",\n    \"lenguajes\": [\n        \"Java\",\n        \"PHP\",\n        \"C#\",\n        \"Python\",\n        \"JavaScript\"\n    ],\n}\n\njson_file_name = __file__[:-3] + \".json\"\n\nwith open(json_file_name, \"w\", encoding = \"utf-8\") as f:\n    json.dump(json_data, f, indent = 4)\ndel json_data\n\nwith open(json_file_name, \"r\", encoding = \"utf-8\") as f:\n    json_data = json.load(f)\nprint(json_data)\n\nos.remove(json_file_name)"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/Irenetitor.py",
    "content": "#import os\nimport xml.etree.ElementTree as xml\nimport json\n\nxml_file = \"Irenetitor.xml\"\njson_file = \"Irenetitor.json\"\n\nuser = {\n  \"name\": \"Ana\",\n  \"age\": 25,\n  \"birth_date\": \"23-02-2000\",\n  \"languages\": [\"Python\", \"JavaScript\", \"Java\"]\n}\n\n#XML\n\ndef save_xml():\n    \n    root = xml.Element(\"user\")\n\n    for key, value in user.items():\n        child = xml.SubElement(root, key)\n        if isinstance(value, list):\n            for language in value:\n                xml.SubElement(child, \"language\").text = language\n        else:\n            child.text = str(value)\n\n    # ✔ Write the file inside the function\n    tree = xml.ElementTree(root)\n    tree.write(xml_file)\n\n\nsave_xml()\n\nwith open(xml_file) as xml_user:\n    print(xml_user.read())\n\n#os.remove(xml_file)\n\n\n'''\n<data>\n    <name>Ana</name>\n    <age>25</age>\n    <birth_date>23-02-2000</birth_date>\n    <languages>\n        <language>Python</language>\n        <language>JavaScript</language>\n        <language>Java</language>\n    </languages>\n</data>\n\n'''\n\n#JSON\n\nwith open(json_file, \"w\") as json_user:\n    json.dump(user, json_user)\n\nwith open(json_file, \"r\") as json_user:\n    print(json_user.read())\n\n#os.remove(json_file)\n\n'''\n{\n  \"name\": \"Ana\",\n  \"age\": 25,\n  \"birth_date\": \"23-02-2000\",\n  \"languages\": [\"Python\", \"JavaScript\", \"Java\"]\n}\n'''\n\n#EXTRA EXERCISE\n\nxml_file = \"user_parsed.xml\"\njson_file = \"user_parsed.json\"\n\nuser_data = {\n    \"name\": \"Juan\",\n    \"age\": 29,\n    \"birth_date\": \"23-02-1996\",\n    \"languages\": [\"Python\", \"JavaScript\", \"Java\"]\n}\n\n# Save data as XML\n\ndef save_xml(data: dict, filename: str) -> None:\n    root = xml.Element(\"user\")  # <user> ... </user>\n\n    for key, value in data.items():\n        child = xml.SubElement(root, key)\n\n        if isinstance(value, list):\n            # For lists -> create \"<language>\" for each item\n            for language in value:\n                xml.SubElement(child, \"language\").text = language\n        else:\n            # Simple values -> just put text\n            child.text = str(value)\n\n    tree = xml.ElementTree(root)\n    tree.write(filename, encoding=\"utf-8\", xml_declaration=True)\n\n# Save data as JSON\n\ndef save_json(data: dict, filename: str) -> None:\n    with open(filename, \"w\", encoding=\"utf-8\") as json_user:\n        json.dump(data, json_user, indent=4)\n\n\n# USER CLASS\n\nclass User:\n    def __init__(self, name, age, birth_date, languages):\n        self.name = name\n        self.age = age\n        self.birth_date = birth_date\n        self.languages = languages\n\n    def __repr__(self):\n        return (\n            f\"User(name={self.name!r}, age={self.age}, \"\n            f\"birth_date={self.birth_date!r}, languages={self.languages!r})\"\n        )\n\n    @classmethod\n    def from_json(cls, filename: str):\n        \"\"\"Create a User object from a JSON file.\"\"\"\n        with open(filename, \"r\", encoding=\"utf-8\") as f:\n            data = json.load(f)\n\n        return cls(\n            name=data[\"name\"],\n            age=data[\"age\"],\n            birth_date=data[\"birth_date\"],\n            languages=data[\"languages\"],\n        )\n\n    @classmethod\n    def from_xml(cls, filename: str):\n        \"\"\"Create a User object from an XML file.\"\"\"\n        tree = xml.parse(filename)\n        root = tree.getroot()\n\n        # Simple elements\n        name = root.find(\"name\").text\n        age = int(root.find(\"age\").text)\n        birth_date = root.find(\"birth_date\").text\n\n        # Languages (list)\n        languages = []\n        langs_node = root.find(\"languages\")\n        if langs_node is not None:\n            for lang_tag in langs_node.findall(\"language\"):\n                languages.append(lang_tag.text)\n\n        return cls(name, age, birth_date, languages)\n\n\n# RUN THE FULL FLOW\n\nsave_xml(user_data, xml_file)\nsave_json(user_data, json_file)\n\nprint(\"\\n--- XML FILE CONTENT ---\")\nwith open(xml_file, \"r\", encoding=\"utf-8\") as xml_user:\n    print(xml_user.read())\n\nprint(\"\\n--- JSON FILE CONTENT ---\")\nwith open(json_file, \"r\", encoding=\"utf-8\") as json_user:\n    print(json_user.read())\n\n# Create User objects\nuser_from_xml = User.from_xml(xml_file)\nuser_from_json = User.from_json(json_file)\n\nprint(\"\\n--- USER OBJECTS ---\")\nprint(\"From XML: \", user_from_xml)\nprint(\"From JSON:\", user_from_json)\n\n# Optional delete:\n# os.remove(xml_file)\n# os.remove(json_file)\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/JAFeito.py",
    "content": "\"\"\"\n IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n\n EJERCICIO:\n Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n - Nombre\n - Edad\n - Fecha de nacimiento\n - Listado de lenguajes de programación\n Muestra el contenido de los archivos.\n Borra los archivos.\n\n DIFICULTAD EXTRA (opcional):\n Utilizando la lógica de creación de los archivos anteriores, crea un\n programa capaz de leer y transformar en una misma clase custom de tu \n lenguaje los datos almacenados en el XML y el JSON.\n Borra los archivos.\n\"\"\"\nimport os\nimport xml.etree.ElementTree as xml\nimport json\n# XML\ndatos = {\n    \"nombre\":\"Jose\",\n    \"edad\":45,\n    \"nacido\":\"01/03/79\", \n    \"aficiones\":[\"videojuego\", \"anime\", \"programar\"]\n    }\n\ndef crear_xml():\n    root = xml.Element(\"datos\")\n    for key, value in datos.items():\n        child = xml.SubElement(root, key)\n        if isinstance(value,list):\n            for item in value:\n               xml.SubElement(child, \"item\").text = item\n        else:\n            child.text = str(value)\n    tree = xml.ElementTree(root)\n    tree.write (\"JAFeito.xml\")\ncrear_xml()\nwith open(\"JAFeito.xml\", \"r\") as archivo:\n    print(archivo.read())\nos.remove(\"JAFeito.xml\")\n#JSON\ndef crear_json():\n    with open (\"JAFeito.json\", \"w\") as archivo:\n        json.dump(datos, archivo)\ncrear_json()\nwith open (\"JAFeito.json\", \"r\") as archivo:    \n    print(archivo.read())\nos.remove(\"JAFeito.json\")\n#EXTRA\ncrear_xml()\ncrear_json()\n\nclass Datos:\n    def __init__ (self, nombre, edad, fecha_nacimiento, aficiones) -> None:\n        self.nombre = nombre\n        self.edad = edad\n        self.fecha_nacimiento = fecha_nacimiento\n        self.aficiones = aficiones\n        \n#XML\n\nwith open(\"JAFeito.xml\", \"r\") as archivo:\n    root = xml.fromstring(archivo.read())\n    nombre = root.find(\"nombre\").text\n    edad = root.find(\"edad\").text\n    fecha_nacimiento = root.find(\"nacido\").text\n    aficiones = []\n    for item in root.find(\"aficiones\"):\n        aficiones.append(item.text)\n\ndatos_xml = Datos( nombre, edad, fecha_nacimiento, aficiones)\nprint(datos_xml.__dict__)\n#JSON\nwith open(\"JAFeito.json\", \"r\") as archivo:\n    dic_json = json.load(archivo)\n    nombre = dic_json[\"nombre\"]\n    edad = dic_json[\"edad\"]\n    fecha_nacimiento = dic_json[\"nacido\"] \n    aciciones = dic_json[\"aficiones\"]\n    datos_json = Datos(nombre, edad, fecha_nacimiento, aficiones)   \nprint(datos_json.__dict__)\nos.remove(\"JAFeito.xml\")\nos.remove(\"JAFeito.json\")"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/Jav-mol.py",
    "content": "# --- 12 JSON Y XML ---\n# --- Javier Molina ---\n\nname = input(\"Ingrese su nombre: \")\nage = input(\"Ingrese su edad: \")\ndate_birth = input(\"Ingrese su fecha de nacimiento: \")\ndev_leng = input(\"Ingrese sus lenguajes de programacion separedos por una coma: \").replace(\" \",\"\").split(\",\")\n \n# --- Json ---\nimport json\nwith open('Jav-mol.json', 'w') as file:\n    \n    files = {'name':name, 'age':age, \"date of birth\": date_birth,'dev-lenguages':dev_leng}    \n    arch_json = json.dumps(files, indent=4)\n    file.write(arch_json)\n\nwith open('Jav-mol.json') as file:\n    data = file.read()\n    print()\n    print(\" Json \".center(20, \"-\"))\n    print(data)\n\n\n# --- Xml ---\nwith open('Jav-mol.xml', 'w') as file:\n    \n    file.write(f'<name>{name}</name>\\n')\n    file.write(f'<age>{age}</age>\\n')\n    file.write(f'<date-birth>{date_birth}</date-birth>\\n')\n    file.write(f'<dev-leng>{dev_leng}</dev-leng>')\n\nwith open('Jav-mol.xml') as file:\n    data = file.read()\n    print()\n    print(\" Xml \".center(20,\"-\"))\n    print(data)\n\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/JesusWay69.py",
    "content": "import os, json\nimport xml.etree.cElementTree as ET\nfrom xml.dom import minidom\nfrom datetime import datetime as date\nos.system('cls')\n\"\"\"\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n *\n\"\"\"\n\n\t\n#ruta = r\"C:\\Users\\jesus\\Documents\\Python3project\\roadmap_python\\#12\\\\\"\n\n\nnacimiento = 1975\nedad = date.now().year - nacimiento\n\nempresa = ET.Element(\"EMPRESA\")\n\nprogramador = ET.SubElement(empresa, \"PROGRAMADOR\")\nET.SubElement(programador, \"NOMBRE\").text = \"Jesus\"\nET.SubElement(programador, \"LENGUAJES\").text = \"[Python, Java, PhP]\"\nET.SubElement(programador, \"NACIMIENTO\").text = str(nacimiento)\nET.SubElement(programador, \"EDAD\").text = str(edad)\nprogramador = ET.SubElement(empresa, \"PROGRAMADOR\")\nET.SubElement(programador, \"NOMBRE\").text = \"Sandra\"\nET.SubElement(programador, \"LENGUAJES\").text = \"[Javascript, HTML, CSS]\"\nET.SubElement(programador, \"NACIMIENTO\").text = \"1991\"\nET.SubElement(programador, \"EDAD\").text = str(date.now().year - 1991)\n\nfile = ET.ElementTree(empresa)\nfile.write(\"empresa.xml\") #file.write(ruta + \"empresa.xml\") si queremos incluir la ruta\n\njson_file = '''{\n \"nombre\": \"Jesus\",\n \"fecha de nacimiento\": \"1975\",\n \"lenguages\": [\"python\", \"java\", \"php\"] \n}\n'''\n#string\n\nyo = json.loads(json_file)#Transforma un string con formato json en un objeto diccionario python\nprint(yo)\nprint(type(yo))#dict\n\npython_dict = {\n \"nombre\": \"Jesus\",\n \"fecha de nacimiento\": \"1975\",\n \"lenguajes\": [\"python\", \"java\", \"php\"]\n}#dict\n\nyo = json.dumps(python_dict)#Transforma un objeto diccionario python en un string\nprint(yo)\nprint(type(yo))#str\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu \n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n\"\"\"\n\nclass Programador:\n    def __init__(self):\n      self.primary_list = []\n\n\n    def create_file_json(self,filename:str):\n        self.filename = filename\n        self.file = self.filename+'.json'\n        with open(self.file, 'w') as create_json:\n           json.dump(self.file,create_json, indent=4, sort_keys=False)\n\n    def create_file_xml(self,filename:str, rootname:str):\n        self.filename = filename\n        self.rootname = rootname\n        self.file = self.filename+'.xml'\n        root = ET.Element(rootname)\n        tree = ET.ElementTree(root)\n        tree.write(self.file)\n\n    def create_dict(self, name:str, birth_year:int, languages:list)->dict:\n        self.name = name\n        self.birth_year = birth_year\n        self.languages = languages\n        dict = {\"Name\":self.name,\n                \"Birth_year\":self.birth_year,\n                \"Age\": date.now().year - self.birth_year, \n                \"Languages\": self.languages}\n        return dict\n\n    def add_dict_json(self,file:str,dict:dict):\n        self.file = file\n        self.dict = dict\n        self.primary_list.append(self.dict)\n        with open(self.file , 'w') as write_json:\n            json.dump(self.primary_list, write_json , indent=4, sort_keys=False)\n        \n\n    def print_json_contain(self, file:str):\n        with open(file) as contains:\n            payload = json.load(contains)\n        for element in  payload:\n            print(element)\n\n    def print_xml_contain(self,root:object):\n        rough_string = ET.tostring(root, 'utf-8')\n        reparsed = minidom.parseString(rough_string)\n        print (reparsed.toprettyxml(indent=\"  \", newl=\"\\n\"))\n\n    def add_dict_xml(self,subroot:str,file:str, python_dict:dict):\n        self.python_dict = python_dict\n        self.file = file\n        self.subroot = subroot\n        tree = ET.parse(file)\n        root = tree.getroot()\n        subroot = ET.SubElement(root,self.subroot)\n        for key, value in self.python_dict.items():\n            programador = ET.SubElement(subroot, key)\n            if isinstance(value, list):\n                for element in value:\n                    ET.SubElement(programador, \"language\").text = element\n            else:\n                programador.text = str(value)\n      \n        tree.write(file)\n\n\nprogramador = Programador()\nprogramador.create_file_json('programadores')\nprogramador.add_dict_json(\"programadores.json\",programador.create_dict(\"Jesus\", 1975, [\"python\", \"java\", \"php\"]))\nprogramador.add_dict_json(\"programadores.json\",programador.create_dict(\"Sandra\", 1991, [\"HTML\", \"CSS\", \"Javascript\"]))\nprogramador.add_dict_json(\"programadores.json\",programador.create_dict(\"Pepe\", 1980, [\"C#\", \"C\", \"Assembly\"]))\nprogramador.add_dict_json(\"programadores.json\",programador.create_dict(\"Brais\", 1988, [\"Swift\", \"Kotlin\", \"Python\"]))\nprogramador.print_json_contain(\"programadores.json\")\nprint()\n\n\nprogramador.create_file_xml(\"empresa\", \"EMPRESA\")\nprogramador.add_dict_xml(\"Programador\",\"empresa.xml\",programador.create_dict(\"Jesus\", 1975, [\"Java\",\"Python\",\"PhP\"]))\nprogramador.add_dict_xml(\"Programador\",\"empresa.xml\",programador.create_dict(\"Sandra\", 1991, [\"HTML\", \"CSS\", \"Javascript\"]))\nprogramador.add_dict_xml(\"Programador\",\"empresa.xml\",programador.create_dict(\"Pepe\", 1980, [\"C#\", \"C\", \"Assembly\"]))\nprogramador.add_dict_xml(\"Programador\",\"empresa.xml\",programador.create_dict(\"Brais\", 1988, [\"Swift\", \"Kotlin\", \"Python\"]))\nprogramador.print_xml_contain(ET.parse(\"empresa.xml\").getroot())\n\n\n\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/JheisonQuiroga.py",
    "content": "import json\nimport os\nimport xml.etree.ElementTree as ET\n\n# json extension\n\ndct = {\n    \"firstname\": \"Duban\",\n    \"lastname\": \"Quiroga\",\n    \"country\": \"Colombia\",\n    \"skills\": [\n        \"Python\", \"Java\"\n    ]\n}\n\ndef file_creates_and_read(path:str, dct:dict) -> str:\n    \n    with open(\"./jsonfile.json\", \"w\") as file:\n        json.dump(dct, file, indent=4)\n        \n\n    #with open(\"./jsonfile.json\") as file:\n    #    content = json.load(file)\n    #os.remove(path)\n    #return json.dumps(content, indent=4)\n    \n\nprint(file_creates_and_read(\"jsonfile.json\", dct))\n\n# XML extension\n\ndef create_file():\n    # Crear el elemento raiz\n    root = ET.Element(\"person\")\n\n    # Añadir subelementos\n    firstname = ET.SubElement(root, \"firstname\")\n    firstname.text = \"Duban\"\n\n    lastname = ET.SubElement(root, \"lastname\")\n    lastname.text = \"Quiroga\"\n\n    country = ET.SubElement(root, \"country\")\n    country.text = \"Colombia\"\n\n    # Se crea un subelemento para los skills con una lista de lenguajes\n    skills = ET.SubElement(root, \"skills\")\n    skill1 = ET.SubElement(skills, \"skill\")\n    skill1.text = \"Python\"\n    skill2 = ET.SubElement(skills, \"skill\")\n    skill2.text = \"Java\"\n\n    # Se guarda el archivo\n    tree = ET.ElementTree(root)\n    with open(\"person.xml\", \"wb\") as f:\n        tree.write(f)\n\ndef show_content():\n    #Mostrar el contenido del archivo\n    print(\"-\" * 5, \"Contenido del archivo XML\", \"-\" * 5)\n    tree = ET.parse(\"person.xml\")\n    root = tree.getroot()\n    for element in root:\n        if element.tag == \"skills\":\n            print(\"Skills: \", [skill.text for skill in element])\n        else:\n            print(f\"{element.tag.capitalize()}: {element.text}\")\n\ndef remove_file():\n    # Eliminar archivo\n    if os.path.exists(\"person.xml\"):\n        os.remove(\"person.xml\")\n    else:\n        print(\"El archivo no existe\")\n\n\n\"\"\" Extra \"\"\"\n\ncreate_file()\n\n\nclass Custom:\n\n    def __init__(self, fname, lname, country, skills):\n        self.fname = fname\n        self.lname = lname\n        self.country = country\n        self.skills = skills\n\nfile_name = \"jsonfile.json\"\nxml_file = \"person.xml\"\n\nwith open(file_name) as file:\n    content = file.read()\n    data_json = json.loads(content)\n    person_json = Custom(data_json[\"firstname\"], data_json[\"lastname\"], data_json[\"country\"], data_json[\"skills\"])\n\n\nprint(person_json.__dict__)\n\nwith open(xml_file, \"r\") as file:\n    data = file.read()\n    root = ET.fromstring(data)\n    fname = root.find(\"firstname\").text\n    lname = root.find(\"lastname\").text\n    country = root.find(\"country\").text\n    skills = []\n    for skill in root.find(\"skills\"):\n        skills.append(skill.text)\n\n    person_xml = Custom(fname, lname, country, skills)\n    print(person_xml.__dict__) # Datos en formato diccionario\n\nos.remove(file_name)\nos.remove(xml_file)"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/JuanDAW37.py",
    "content": "\"\"\"* IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu \n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\"\"\"\n\nimport os\n\nfichero_xml ='JuanDAW37.xml'\nfichero_json ='JuanDAW37.json'\n\nnombre ='Juan Jesús Tenreiro Rodríguez'\nedad = 56\nfecha_nacimiento = '01-05-1968'\nlenguajes = ['JavaScript', 'Java', 'Python', 'PHP', 'Cobol']\n\ndef datosXml(fich_xml):    \n    fich_xml.write('<persona>\\n')\n    fich_xml.write(f'<nombre> {nombre} </nombre>\\n')\n    fich_xml.write(f'<edad> {edad} </edad>\\n')\n    fich_xml.write(f'<fecha_nacimiento> {fecha_nacimiento} </fecha_nacimiento>\\n')\n    fich_xml.write('<Lenguajes>\\n')\n    for lenguaje in lenguajes:\n        fich_xml.write(f'<lenguaje> {lenguaje} </lenguaje>\\n')\n    fich_xml.write('</Lenguajes>\\n')\n    fich_xml.write('</persona>\\n')\n    \ndef datosJson(fich_xml):    \n    fich_xml.write('{\\n')\n    fich_xml.write(f'\"nombre\":\"{nombre}\",\\n')\n    fich_xml.write(f'\"edad\":{edad},\\n')\n    fich_xml.write(f'\"fecha_nacimiento\":\"{fecha_nacimiento}\",\\n')\n    fich_xml.write('\"lenguajes\":[\\n')\n    for i,lenguaje in enumerate(lenguajes):\n        fich_xml.write('{')\n        fich_xml.write(f'\"lenguaje\":\"{lenguaje}\"')\n        if i == len(lenguajes) - 1:        \n            fich_xml.write('}\\n')\n            fich_xml.write(']\\n')\n        else:\n            fich_xml.write('},\\n')        \n    fich_xml.write('}\\n')    \n\n#Fichero XML\nif os.path.isfile(fichero_xml):\n    with open(fichero_xml, 'r') as fich_xml:\n        lineas = fich_xml.readlines()\n        for  linea in lineas:                        \n            if '</Personas>' in linea:\n                lineas.remove('</Personas>')                \n                with open(fichero_xml, 'w') as fich_xml:                    \n                    for linea in lineas:                                            \n                        fich_xml.write(linea)                    \n                    datosXml(fich_xml)                    \n                    fich_xml.write('</Personas>')\nelse:\n    with open(fichero_xml, 'w') as fich_xml:\n        fich_xml.write('<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n')\n        fich_xml.write('<Personas>\\n')\n        datosXml(fich_xml)\n        fich_xml.write('</Personas>')\n        \n#Fichero JSON\nif os.path.isfile(fichero_json):\n    with open(fichero_json, 'r') as fich_json:\n        lineas = fich_json.readlines()\n        for linea in lineas:                        \n            if ']' in linea:\n                lineas.remove(']')                \n                with open(fichero_json, 'w') as fich_json:                    \n                    for linea in lineas:                                            \n                        fich_json.write(linea)                    \n                    fich_json.write('\\n,')\n                    datosJson(fich_json)                    \n                    fich_json.write(']')\nelse:\n    with open(fichero_json, 'w') as fich_json:\n        fich_json.write('[\\n')\n        datosJson(fich_json)\n        fich_json.write(']')\n        \nos.remove(fichero_xml)\nos.remove(fichero_json)\n        \n# EXTRA\nclass Persona:\n    nombre:str = ''\n    fecha_nacimiento:str = ''\n    edad:int = 0\n    lenguajes:list = []\n    \n    def __init__(self):\n        pass\n    \n    def setNombre(self, nombre:str):\n        self.nombre = nombre\n    \n    def setEdad(self, edad:int):\n        self.edad = edad\n    \n    def setFechaNacimiento(self, fecha_nacimiento:str):\n        self.fecha_nacimiento = fecha_nacimiento\n    \n    def setlenguajes(self, lenguajes:list):\n        self.lenguajes = lenguajes\n        \n    def imprimeDatosPersona(self):\n        print(f'Nombre: {self.nombre}, Fecha de nacimiento: {self.fecha_nacimiento}, edad: {self.edad}') \n        if len(self.lenguajes) > 0:\n            print('Lenguajes:')\n            for lenguaje in self.lenguajes:\n                print(f'- {lenguaje}')\n    \ndef leerXML():\n    nombre,  fecha_nacimiento, edad, lenguajes = '', '', 0, []\n    persona = Persona()\n    try:\n        with open(fichero_xml, 'w') as fich_xml:\n            datosXml(fich_xml)\n        archivo = open(fichero_xml, 'r')        \n        for linea in archivo:            \n            lista = linea.split(' ')            \n            if len(lista) > 1:\n                if '<nombre>' in lista:\n                    if len(lista)== 6:\n                        nombre = lista[1] + ' ' + lista[2]+ ' ' + lista[3] + ' ' + lista[4]\n                    elif len(lista) == 5:\n                        nombre = lista[1] + ' ' + lista[2]+ ' ' + lista[3]\n                    elif len(lista) == 4:\n                        nombre = lista[1] + ' ' + lista[2]\n                    persona.setNombre(nombre)\n                elif '<edad>' in lista:\n                    edad = int(lista[1])\n                    persona.setEdad(edad) \n                elif '<fecha_nacimiento>' in lista:\n                    fecha_nacimiento = lista[1]                    \n                    persona.setFechaNacimiento(fecha_nacimiento)\n                elif '<lenguaje>' in lista:\n                    lenguajes.append(lista[1])\n        persona.setlenguajes(lenguajes)\n        print('******DATOS OBJETO DE TIPO PERSONA EXTRAIDOS DEL XML******')\n        persona.imprimeDatosPersona()\n        archivo.close()\n        os.remove(fichero_xml)\n    except FileExistsError as error:\n        print(f'Error de acceso al archivo {error}')\n        \ndef leerJSON():\n    nombre,  fecha_nacimiento, edad, lenguajes = '', '', 0, []\n    comillas ='\"'\n    coma = ','\n    llave = '}'\n    persona = Persona()\n    try:\n        with open(fichero_json, 'w') as fich_json:\n            datosJson(fich_json)\n        archivo = open(fichero_json, 'r')        \n        for linea in archivo:                        \n            if '\"nombre\":' in linea:\n                nombre = linea.split(':')[1].strip()                \n                nombre = nombre.replace(comillas, '')\n                nombre = nombre.replace(coma, '')\n                persona.setNombre(nombre)\n            elif '\"edad\":' in linea:\n                edad = linea.split(':')[1].strip()\n                edad = edad.replace(comillas, '')\n                edad = edad.replace(coma, '')\n                persona.setEdad(edad)\n            elif '\"fecha_nacimiento\":' in linea:\n                fecha_nacimiento = linea.split(':')[1].strip()\n                fecha_nacimiento = fecha_nacimiento.replace(comillas,'')\n                fecha_nacimiento = fecha_nacimiento.replace(coma,'')\n                persona.setFechaNacimiento(fecha_nacimiento)\n            elif '\"lenguaje\":' in linea:\n                lenguaje = linea.split(':')[1].strip()\n                lenguaje = lenguaje.replace(comillas, '')\n                lenguaje = lenguaje.replace(coma, '')\n                lenguaje = lenguaje.replace(llave, '')\n                lenguajes.append(lenguaje)\n            persona.setlenguajes(lenguajes)            \n        print('******DATOS OBJETO DE TIPO PERSONA OBTENIDOS DEL JSON******')\n        persona.imprimeDatosPersona()\n        archivo.close()\n        os.remove(fichero_json)\n        \n    except FileExistsError as error:\n        print(f'Error de acceso al archivo {error}')\n\nleerXML()\n\nleerJSON()"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/Juanppdev.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n\"\"\"\n\nimport json\nimport xml.etree.ElementTree as ET\nimport os\n\n# Datos a guardar\ndatos = {\n    \"Nombre\": \"Juan Pablo\",\n    \"Edad\": 25,\n    \"Fecha de nacimiento\": \"1998-09-24\",\n    \"Lenguajes de programación\": [\"Python\", \"Kotlin\", \"C++\"]\n}\n\n# Crear archivo JSON\nwith open(\"datos.json\", \"w\") as json_file:\n    json.dump(datos, json_file, indent=4)\n\n# Crear archivo XML\nroot = ET.Element(\"Persona\")\nET.SubElement(root, \"Nombre\").text = datos[\"Nombre\"]\nET.SubElement(root, \"Edad\").text = str(datos[\"Edad\"])\nET.SubElement(root, \"Fecha_de_nacimiento\").text = datos[\"Fecha de nacimiento\"]\nlenguajes = ET.SubElement(root, \"Lenguajes_de_programacion\")\nfor lenguaje in datos[\"Lenguajes de programación\"]:\n    ET.SubElement(lenguajes, \"Lenguaje\").text = lenguaje\n\ntree = ET.ElementTree(root)\nwith open(\"datos.xml\", \"wb\") as xml_file:\n    tree.write(xml_file)\n\n# Mostrar contenido de los archivos\nwith open(\"datos.json\", \"r\") as json_file:\n    print(\"Contenido de datos.json:\")\n    print(json_file.read())\n\nwith open(\"datos.xml\", \"r\") as xml_file:\n    print(\"\\nContenido de datos.xml:\")\n    print(xml_file.read())\n\n# Borrar los archivos\n# os.remove(\"datos.json\")\n# os.remove(\"datos.xml\")\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu \n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n\"\"\"\n\nimport json\nimport xml.etree.ElementTree as ET\nimport os\n\nclass Persona:\n    def __init__(self, nombre, edad, fecha_nacimiento, lenguajes):\n        self.nombre = nombre\n        self.edad = edad\n        self.fecha_nacimiento = fecha_nacimiento\n        self.lenguajes = lenguajes\n\n    def __str__(self):\n        return f\"Nombre: {self.nombre}, Edad: {self.edad}, Fecha de nacimiento: {self.fecha_nacimiento}, Lenguajes de programación: {', '.join(self.lenguajes)}\"\n\n# Función para leer datos desde JSON\ndef leer_json(file_path):\n    with open(file_path, \"r\") as json_file:\n        datos = json.load(json_file)\n    return Persona(datos[\"Nombre\"], datos[\"Edad\"], datos[\"Fecha de nacimiento\"], datos[\"Lenguajes de programación\"])\n\n# Función para leer datos desde XML\ndef leer_xml(file_path):\n    tree = ET.parse(file_path)\n    root = tree.getroot()\n    nombre = root.find(\"Nombre\").text\n    edad = int(root.find(\"Edad\").text)\n    fecha_nacimiento = root.find(\"Fecha_de_nacimiento\").text\n    lenguajes = [lenguaje.text for lenguaje in root.find(\"Lenguajes_de_programacion\")]\n    return Persona(nombre, edad, fecha_nacimiento, lenguajes)\n\n# Crear archivos JSON y XML (como en el ejercicio anterior)\ndatos = {\n    \"Nombre\": \"Juan Pablo\",\n    \"Edad\": 25,\n    \"Fecha de nacimiento\": \"1998-09-24\",\n    \"Lenguajes de programación\": [\"Python\", \"Java\", \"C++\"]\n}\n\nwith open(\"datos.json\", \"w\") as json_file:\n    json.dump(datos, json_file, indent=4)\n\nroot = ET.Element(\"Persona\")\nET.SubElement(root, \"Nombre\").text = datos[\"Nombre\"]\nET.SubElement(root, \"Edad\").text = str(datos[\"Edad\"])\nET.SubElement(root, \"Fecha_de_nacimiento\").text = datos[\"Fecha de nacimiento\"]\nlenguajes = ET.SubElement(root, \"Lenguajes_de_programacion\")\nfor lenguaje in datos[\"Lenguajes de programación\"]:\n    ET.SubElement(lenguajes, \"Lenguaje\").text = lenguaje\n\ntree = ET.ElementTree(root)\nwith open(\"datos.xml\", \"wb\") as xml_file:\n    tree.write(xml_file)\n\n# Leer y transformar los datos en una clase custom\npersona_desde_json = leer_json(\"datos.json\")\npersona_desde_xml = leer_xml(\"datos.xml\")\n\nprint(\"Datos desde JSON:\")\nprint(persona_desde_json)\n\nprint(\"\\nDatos desde XML:\")\nprint(persona_desde_xml)\n\n# Borrar los archivos\n# os.remove(\"datos.json\")\n# os.remove(\"datos.xml\")\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/LucasRebuffo.py",
    "content": "\"\"\" /*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu \n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n */\n \"\"\"\n\nimport os\nimport xml.etree.ElementTree as xml\n\nprogramador = {\n    \"nombre\": \"Lucas Rebuffo\",\n    \"edad\": 27,\n    \"fecha_nac\": \"10-02-1997\",\n    \"lenguajes_de_programacion\": [\"python\", \"javascript\", \"java\"],\n}\n\n\nxml_file = \"LucasRebuffo.xml\"\n\n\ndef guardar_xml():\n\n    raiz = xml.Element(\"data\")\n\n    for key, value in programador.items():\n        hijo = xml.SubElement(raiz, key)\n        if isinstance(value, list):\n            for item in value:\n                xml.SubElement(hijo, \"item\").text = str(item)\n        else:\n            hijo.text = str(value)\n\n    tree = xml.ElementTree(raiz)\n    tree.write(xml_file)\n\n\nguardar_xml()\n\nwith open(xml_file, \"r\") as xml_data:\n    print(xml_data.read())\n\n# os.remove(xml_file)\n\nprint(\"\\n\")\n\nimport json\n\njson_file = \"LucasRebuffo.json\"\n\n\nwith open(json_file, \"w\") as json_data:\n    json.dump(programador, json_data)\n\nwith open(json_file, \"r\") as json_data:\n    print(json_data.read())\n\n# os.remove(json_file)\n\n\nprint(\"\\n\")\n\"\"\"  * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu \n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n */ \"\"\"\n\n\nclass Programador:\n\n    def __init__(\n        self, nombre: str, edad: int, fecha_nac: str, lenguajes_de_programacion: list\n    ) -> None:\n        self.nombre = nombre\n        self.edad = edad\n        self.fecha_nac = fecha_nac\n        self.lenguajes_de_programacion = lenguajes_de_programacion\n\n    def __str__(self) -> str:\n        return f\"Nombre: {self.nombre} | Edad: {self.edad} | Fecha de nacimiento: {self.fecha_nac} | Lenguajes: {self.lenguajes_de_programacion}\"\n\n\nwith open(xml_file, \"r\") as xml_data:\n\n    root = xml.fromstring(xml_data.read())\n    nombre = root.find(\"nombre\").text\n    edad = root.find(\"edad\").text\n    fecha_nac = root.find(\"fecha_nac\").text\n    lenguajes_de_programacion = []\n    for item in root.find(\"lenguajes_de_programacion\"):\n        lenguajes_de_programacion.append(item.text)\n\ndata = Programador(nombre, edad, fecha_nac, lenguajes_de_programacion)\n\nprint(data)\nprint(\"\\n\")\n\n\nwith open(json_file, \"r\") as json_data:\n\n    json_dict = json.load(json_data)\n\n    json_class = Programador(\n        json_dict[\"nombre\"],\n        int(json_dict[\"edad\"]),\n        json_dict[\"fecha_nac\"],\n        json_dict[\"lenguajes_de_programacion\"],\n    )\n\n\nprint(json_class)\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/LuisM95.py",
    "content": "\"\"\"\r\nEjercicio\r\n\"\"\"\r\n\r\nimport xml.etree.ElementTree as xml\r\nimport xml.dom.minidom as minidom\r\nimport os\r\n\r\ndata = {\r\n    \"name\" : \"Luis\",\r\n    \"age\" : 25,\r\n    \"birthday\" : \"1995-09-19\",\r\n    \"programming_languages\" : [\"Python\", \"HTML\", \"JavaScript\"]\r\n}\r\n\r\ndef create_xml():\r\n    root = xml.Element(\"data\")\r\n\r\n    for key, value in data.items():\r\n\r\n        child = xml.SubElement(root, key)\r\n        if isinstance(value, list):\r\n            for item in value:\r\n                xml.SubElement(child, \"Item\").text = item\r\n        else:\r\n            child.text = str(value)\r\n\r\n        tree = xml.ElementTree(root)\r\n        tree.write(\"programador.xml\")\r\n\r\n        #Convert the tree to a string\r\n        xml_str = xml.tostring(root, encoding='unicode')\r\n\r\n        #Parse the string using a minidom for pretty printing\r\n        dom = minidom.parseString(xml_str)\r\n        pretty_xml_as_string = dom.toprettyxml()\r\n\r\n        with open(\"programador.xml\", \"w\") as f:\r\n            f.write(pretty_xml_as_string)\r\n\r\ncreate_xml()\r\n\r\nwith open(\"programador.xml\", 'r') as xml_data:\r\n    print(xml_data.read())\r\n\r\n#os.remove(\"programador.xml\")\r\n\r\n\r\n\"\"\"\r\nJson\r\n\"\"\"\r\n\r\nimport json\r\n\r\njson_file = \"programador1.json\"\r\n\r\ndef create_json():\r\n    with open(json_file, \"w\") as f:\r\n        json.dump(data, f, indent=4)\r\n\r\ncreate_json()\r\n\r\nwith open(json_file, \"r\") as f:\r\n    print(f.read())\r\n\r\n#os.remove(json_file)\r\n\r\n\"\"\"\r\nExtra\r\n\"\"\"\r\n\r\ncreate_xml()\r\ncreate_json()\r\n\r\nclass Data:\r\n    \r\n    def __init__(self, name, age, birthday, programming_languages) -> None:\r\n        self.name = name\r\n        self.age = age\r\n        self.birthday = birthday\r\n        self.programming_languages = programming_languages\r\n\r\n\r\nwith open(\"programador.xml\", \"r\") as f:\r\n    root = xml.fromstring(f.read())\r\n    name = root.find(\"name\").text\r\n    age = root.find(\"age\").text\r\n    birthday = root.find(\"birthday\").text\r\n    programming_languages = []\r\n    for item in root.find(\"programming_languages\"):\r\n        programming_languages.append(item.text)\r\n\r\n    data_class = Data(name, age, birthday, programming_languages)\r\n    print(data_class.__dict__)\r\n\r\n\r\n#json\r\n\r\nwith open(json_file, \"r\") as f:\r\n    json_dict = json.load(f)\r\n    json_class = Data(\r\n        json_dict[\"name\"], \r\n        json_dict[\"age\"], \r\n        json_dict[\"birthday\"], \r\n        json_dict[\"programming_languages\"]\r\n        )\r\n    print(json_class.__dict__)\r\n\r\n\r\nos.remove(\"programador.xml\")\r\nos.remove(json_file)\r\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/Lumanet.py",
    "content": "import os\nimport xml.etree.ElementTree as xml\nimport json\n\nos.system(\"clear\")\n\ndata = {\n    \"nombre\": \"Marcos Robles\",\n    \"edad\": 42,\n    \"fecha_nacimiento\": \"20-02-1982\",\n    \"lenguajes\": [\"Python\", \"Javascript\", \"PHP\"]\n}\n\nxml_file = \"Lumanet.xml\"\njson_file = \"Lumanet.json\"\n\n# XML\n\ndef create_xml():\n\n    root = xml.Element(\"data\")\n\n    for key, value in data.items():\n        child = xml.SubElement(root, key)\n        if isinstance(value, list):\n            for item in value:\n                xml.SubElement(child, \"item\").text = item\n        else:\n            child.text = str(value)\n\n    tree = xml.ElementTree(root)\n    tree.write(xml_file)\n\ncreate_xml()\n\nwith open(xml_file, \"r\") as xml_data:\n    print(xml_data.read())\n\nos.remove(xml_file)\n\n# JSON\n\ndef create_json():\n    with open(json_file, \"w\") as json_data:\n        json.dump(data, json_data)\n\ncreate_json()\n\nwith open(json_file, \"r\") as json_data:\n    print(json_data.read())\n\nos.remove(json_file)\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\nUtilizando la lógica de creación de los archivos anteriores, crea un\nprograma capaz de leer y transformar en una misma clase custom de tu \nlenguaje los datos almacenados en el XML y el JSON.\nBorra los archivos.\n\"\"\"\n\nclass Custom:\n    def __init__(self, file) -> None:\n        self.file = file\n\n    def write_json(self, datas):\n        with open(self.file, \"w\") as f:\n            json.dump(datas, f, indent=4)\n\n    def read_json(self):\n        with open(self.file, \"r\") as f:\n            load = json.load(f)\n            print(load)\n\n    def write_xml(self, datas):\n        root = xml.Element(\"Informacion\")\n        information = xml.SubElement(root, \"Datos\")\n\n        information.set(\"id\", \"1\")\n        nombre = xml.SubElement(information, \"nombre\")\n        nombre.text = datas[\"nombre\"]\n        age = xml.SubElement(information, \"edad\")\n        age.text = str(datas[\"edad\"])\n        birth_date = xml.SubElement(information, \"fecha_nacimiento\")\n        birth_date.text = datas[\"fecha_nacimiento\"]\n        languages = xml.SubElement(information, \"lenguajes\")\n        for lang in datas[\"lenguajes\"]:\n            xml.SubElement(languages, \"lenguaje\").text = lang\n\n        tree = xml.ElementTree(root)\n        tree.write(self.file)\n\n    def read_xml(self):\n      with open(self.file, \"r\") as xml_data:\n        print(xml_data.read())\n\n    def delete_file(self):\n        os.remove(self.file)\n        print(\"\\nArchivos borrados exitosamente.\")\n\n# Ejemplo de uso\ndatos = {\n    \"nombre\": \"Marcos\",\n    \"edad\": 42,\n    \"fecha_nacimiento\": \"1982-02-20\",\n    \"lenguajes\": [\"Python\", \"PHP\", \"Javascript\"]\n}\n\ncustom_instance = Custom(\"Lumanet.xml\")\ncustom_instance.write_xml(datos)\ncustom_instance.read_xml()\n#custom_instance.delete_file()\n\ncustom_instance = Custom(\"Lumanet.json\")\ncustom_instance.write_json(datos)\ncustom_instance.read_json()\n#custom_instance.delete_file()\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/NeosV.py",
    "content": "import xml.etree.ElementTree as xml\nimport json\nimport os\n\ndatos = {\n    \"nombre\" : \"Andres\",\n    \"edad\" : 21,\n    \"nacimiento\" : \"16-02-2002\",\n    \"lista_programas\" : [\"python\", \"javascript\", \"appscript\"]\n}\n\nname_archivo = \"datos.xml\"\nname_archivo2 = \"datos.json\"\n\ndef save_xml():\n\n    root = xml.Element(\"datos\")\n\n    for key, value in datos.items():\n       \n         child = xml.SubElement(root, key)\n\n         if isinstance(value, list):\n          for item in value:\n             xml.SubElement(child,\"programa\").text = item\n         else:\n          child.text = str(value)\n\n    tree = xml.ElementTree(root)\n    tree.write(name_archivo)\n\n   \nsave_xml()    \n\nwith open(name_archivo, \"r\") as xml_print:\n   print(xml_print.read())\n\n#os.remove(name_archivo)\n\n#JSON \n\ndef save_json():\n   with open(name_archivo2, \"w\") as json_data:\n    json.dump(datos, json_data)\n\nsave_json()\n\nwith open(name_archivo2, \"r\") as json_data:   \n   print(json_data.read())\n\n#os.remove(name_archivo2)\n\n\nclass datos:\n   \n   def __init__(self, nombre, edad, nacimiento, lista_programas) -> None:\n      self.nombre = nombre\n      self.edad = edad\n      self.nacimiento = nacimiento\n      self.lista_programas = lista_programas \n\n\nwith open(name_archivo, \"r\") as xml_print:\n\n  root = xml.fromstring(xml_print.read())  \n  nombre = root.find(\"nombre\").text\n  edad = root.find(\"edad\").text\n  nacimiento = root.find(\"nacimiento\").text\n  lista_programas = []\n  for item in root.find(\"lista_programas\"):\n     lista_programas.append(item.text)\n\n\n\n\n  datos_class_xml = datos(nombre, edad, nacimiento, lista_programas) \n  print(datos_class_xml.__dict__)\n\n\n\n  with open (name_archivo2, \"r\") as json_data:\n     json_dict = json.load(json_data)\n     json_class = datos(json_dict[\"nombre\"],json_dict[\"edad\"],json_dict[\"nacimiento\"],json_dict[\"lista_programas\"])\n     print(json_class.__dict__)\n\n   \n  os.remove(name_archivo)\n  os.remove(name_archivo2)\n\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/Nicojsuarez2.py",
    "content": "# #12 JSON Y XML\n> #### Dificultad: Difícil | Publicación: 18/03/24 | Corrección: 25/03/24\n\n## Ejercicio\n\n```\n/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n * \n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu \n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/Nightblockchain30.py",
    "content": "\"\"\"\n* IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n* \n* EJERCICIO:\n* Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n* siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n* - Nombre\n* - Edad\n* - Fecha de nacimiento\n* - Listado de lenguajes de programación\n* Muestra el contenido de los archivos.\n* Borra los archivos.\n\"\"\"\nimport json\nimport os\nimport time\nimport xml.etree.ElementTree as xml\n\nxml_file = \"Nightblockchain30.xml\"\njson_file = \"Nightblockchain30.json\"\n\n\n# <<<< XML >>>>\ndatos = {\n    \"Nombre\": \"Alonso\",\n    \"Edad\": \"26\",\n    \"Fecha_nacimiento\": \"10/05/1997\",\n    \"Listado_de_lenguajes\": [\"Python\", \"JavaScript\", \"CSS\"]\n}\n\n# SAVE DATA\ndef create_xml():\n    root = xml.Element(\"Parent_Node\")\n\n    #print(type(root))  # -> class 'xml.etree.ElementTree.Element'\n\n    for key,value in datos.items():\n        child = xml.SubElement(root, key)\n        if isinstance(value,list):\n            for item in value:\n                xml.SubElement(child,\"item\").text = item\n        else:\n            child.text = str(value)\n\n    tree = xml.ElementTree(root)\n    #print(type(tree)) # <class 'xml.etree.ElementTree.ElementTree'>\n    tree.write(xml_file)\n\n\ncreate_xml()\n\n\n#READ DATA\nwith open(xml_file, \"r\") as file:\n    print(file.read())\n\n#time.sleep(2)\n\n# Borramos el archivo XML\nif os.path.exists(xml_file):\n    os.remove(xml_file)\nelse:\n    print(\"El arhivo XML no existe\")\n\n\n# <<<< JSON >>>>\n\njson_data = {\n    \"Nombre\": \"Alonso\",\n    \"Edad\": \"26\",\n    \"Fecha_nacimiento\": \"10/05/1997\",\n    \"Listado_de_lenguajes\": [\"Python\", \"JavaScript\", \"CSS\"]\n}\n\n\n# Guardamos los datos usando DUMP\ndef create_json():\n    with open(json_file,\"w\") as file:\n        json.dump(json_data,file,indent=4)\n\ncreate_json()\n\n\n# Mostramos el contenido usando LOAD\nwith open(json_file,\"r\") as file:\n    contenido = json.load(file) # type(contenido) -> LIST\n    for clave , valor in contenido.items():\n        print(f\"Clave:{clave} - Valor:{valor}\")\n\n\n#time.sleep(2) # compruebo como se crea y se borra el documento\n\n# Borramos el archivo JSON\nif os.path.exists(json_file):\n    os.remove(json_file)\nelse:\n    print(\"El arhivo JSON no existe\")\n\n\nprint(\"<<<< EXTRA >>>>\")\n\n'''\n* DIFICULTAD EXTRA (opcional):\n* Utilizando la lógica de creación de los archivos anteriores, crea un\n* programa capaz de leer y transformar en una misma clase custom de tu \n* lenguaje los datos almacenados en el XML y el JSON.\n* Borra los archivos.\n'''\ncreate_xml()\ncreate_json()\n\n\nclass Data():\n\n    def __init__(self, Nombre, Edad, Fecha_nacimiento, Listado_de_lenguajes) -> None:\n        self.Nombre = Nombre\n        self.Edad = Edad\n        self.Fecha_nacimiento = Fecha_nacimiento\n        self.Listado_de_lenguajes = Listado_de_lenguajes\n\nwith open(json_file, \"r\") as json_data:\n    string_data = json.load(json_data)\n    custom_class_json = Data(string_data[\"Nombre\"],string_data[\"Edad\"],string_data[\"Fecha_nacimiento\"],string_data[\"Listado_de_lenguajes\"])\n\n    print(custom_class_json.__dict__)\n\n\nwith open(xml_file, \"r\") as xml_data:\n\n    root = xml.fromstring(xml_data.read())\n    \n    Nombre = root.find(\"Nombre\").text\n    Edad = root.find(\"Edad\").text\n    Fecha_nacimiento = root.find(\"Fecha_nacimiento\").text\n\n    Listado_de_lenguajes = []\n    for item in root.find(\"Listado_de_lenguajes\"):\n        Listado_de_lenguajes.append(item.text)\n\n    custom_class_xml = Data(Nombre,Edad,Fecha_nacimiento,Listado_de_lenguajes)\n    print(custom_class_xml.__dict__)\n\n\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/Paprikaistkrieg.py",
    "content": "#Json y XML\n\"\"\"\nJSON (JavaScript Object Notation) y XML (eXtensible Markup Language) son formatos de datos ampliamente utilizados para el intercambio de información entre sistemas. \nAmbos formatos permiten estructurar datos de manera que sean legibles tanto para humanos como para máquinas, pero tienen diferencias significativas en su sintaxis y uso.\n\nJSON: es un formato de texto ligero y fácil de leer que se utiliza para representar datos estructurados. \nSe basa en una sintaxis de pares clave-valor y es ampliamente utilizado en aplicaciones web para el intercambio de datos entre el cliente y el servidor. \nJSON es compatible con muchos lenguajes de programación y se puede analizar fácilmente en objetos nativos.\n\nXML: es un formato de texto más complejo que utiliza etiquetas para definir la estructura de los datos. Es más verboso que JSON y se utiliza en una variedad de aplicaciones, \nincluyendo servicios web, configuración de software y almacenamiento de datos. \nXML permite definir esquemas para validar la estructura de los datos, lo que puede ser útil en aplicaciones que requieren una validación estricta.\nPython proporciona bibliotecas integradas para trabajar con ambos formatos:\n\n- json: para trabajar con JSON, permite convertir entre cadenas JSON y objetos de Python (como diccionarios y listas).\n- xml.etree.ElementTree: para trabajar con XML, permite analizar y crear documentos XML de\nmanera sencilla.\nA continuación, se presentan ejemplos básicos de cómo utilizar estas bibliotecas en Python:\n\"\"\"\nfrom logging import root\nimport os\nimport json\nimport xml\nimport xml.etree.ElementTree as XML\n# Ejemplo de JSON\n# Crear un diccionario de Python\ndata = {\n    \"nombre\": \"Juan\",\n    \"edad\": 30,\n    \"lenguajes_de_programacion\": [\"Python\"],\n    \"fecha_de_nacimiento\": \"1993-01-01\"\n}\n\n# Convertir el diccionario a una cadena JSON\njson_file_path = \"Paprikaistkrieg.json\" # Nombre del archivo JSON\nwith open(json_file_path, \"w\") as jf: # Guardar la cadena JSON en un archivo\n    json.dump(data, jf) # Escribir el diccionario en el archivo como JSON\n# Leer y analizar un archivo JSON\nwith open(json_file_path, \"r\") as jf: # Abrir el archivo JSON en modo lectura\n    data_loaded = json.load(jf) # Cargar el contenido del archivo JSON en un diccionario de Python\n    print(data_loaded) # Imprimir el diccionario cargado desde el archivo JSON\n\nxml_file = \"Paprikaistkrieg.xml\"\n# Ejemplo de XML\n# Crear un elemento raíz \ndef save_XML(): # funcion para guardar en XML\n    root = XML.Element(\"data\") # Crear el elemento raíz\n    for key, value in data.items(): # Iterar sobre los pares clave-valor del diccionario\n        child = XML.SubElement(root, key) # Crear un subelemento para cada clave\n        if isinstance(value, list): # Verificar si el valor es una lista\n            for item in value: # Iterar sobre los elementos de la lista\n                item_element = XML.SubElement(child, \"item\") # Crear un subelemento para cada ítem\n                item_element.text = str(item) # Asignar el valor del ítem como texto\n        else: # Si el valor no es una lista\n            child.text = str(value) # Asignar el valor como texto\n    tree = XML.ElementTree(root) # Crear un árbol XML a partir del elemento raíz\n    tree.write(\"Paprikaistkrieg.xml\") # Guardar el árbol XML en un archivo\n\nsave_XML() # Llamar a la función para guardar en XML\n\n# Leer y analizar un archivo XML\nwith open (xml_file) as xml_data: # Abrir el archivo XML en modo lectura\n    print(xml_data.read()) # Imprimir el contenido del archivo XML\n\nos.remove(xml_file) # Eliminar el archivo XML creado\nos.remove(json_file_path) # Eliminar el archivo JSON creado\n\n\n#XtraJ\n\ndef save_JSON(): # funcion para guardar en JSON\n    with open(\"Paprikaistkrieg.json\", \"w\") as jf: # Abrir el archivo JSON en modo escritura\n        json.dump(data, jf) # Escribir el diccionario en el archivo como JSON\n\n\nsave_JSON() # Llamar a la función para guardar en JSON\n\nsave_XML() # Llamar a la función para guardar en XML\n\nclass Data:\n    def __init__(self, name, age, birth_date, programming_languages):\n        self.name = name\n        self.age = age\n        self.birth_date = birth_date\n        self.programming_languages = programming_languages\n\n# Leer y analizar el archivo JSON y crear una instancia de Data\nif os.path.exists(json_file_path):\n    with open(json_file_path, \"r\", encoding=\"utf-8\") as json_data:\n        data_json = json.load(json_data)\n        data_class_JSON = Data(\n            data_json[\"nombre\"],\n            data_json[\"edad\"],\n            data_json[\"fecha_de_nacimiento\"],\n            data_json[\"lenguajes_de_programacion\"],\n        )\n        print(data_class_JSON.__dict__) # Imprime el diccionario de atributos del objeto\n\n# Leer y analizar el archivo XML y crear una instancia de Data\nif os.path.exists(xml_file):\n    with open(xml_file, \"r\", encoding=\"utf-8\") as xml_data:\n        xml_data_content = xml_data.read()\n        root = XML.fromstring(xml_data_content)\n        name = root.find(\"nombre\").text\n        age = root.find(\"edad\").text\n        birth_date = root.find(\"fecha_de_nacimiento\").text\n        programming_languages = []\n        for item in root.findall(\"lenguajes_de_programacion/item\"):\n            programming_languages.append(item.text)\n\n        data_class_XML = Data(name, age, birth_date, programming_languages)\n        print(data_class_XML.__dict__) # Imprime el diccionario de atributos del objeto\n\nos.remove(xml_file) # Eliminar el archivo XML creado\nos.remove(json_file_path) # Eliminar el archivo JSON creado\n\n\n\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/Paula2409.py",
    "content": "\"\"\"\n/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n * \n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n *\n\"\"\"\nimport json\nimport xml.etree.ElementTree\nimport os\n\ndata = {\n    'name': 'Paula Adgi Romano', \n    'age': 36, 'birth': '24/09/1987', \n    'languages': ['Python', 'Javascript', 'Java']\n}\n\n\"\"\" JSON: Javascript Object Notation \"\"\"\n\n# Create\ndef create_json():\n    with open(\"C:/Users/pau87/OneDrive/Documentos/Roadmap/data.json\", 'w') as file_json:\n        read = json.dump(data,file_json)\n\n# Read\ndef read_json():\n    with open(\"C:/Users/pau87/OneDrive/Documentos/Roadmap/data.json\", 'r') as file_json:\n        print(file_json.read())\n\ncreate_json()\nread_json()\n\n# Delete\nos.remove(\"C:/Users/pau87/OneDrive/Documentos/Roadmap/data.json\")\n\n\"\"\" XML: Extensible Markup Language \"\"\"\n\n# Create\ntree = xml.etree.ElementTree.parse(\"C:/Users/pau87/OneDrive/Documentos/Roadmap/data.xml\")\nroot = tree.getroot()\nprint(root.tag)\nprint(root.attrib)\n\n# Read\nfor node in root:\n    print(node.tag, node.attrib)\nprint(root[0].text)\nprint(root[1].text)\nprint(root[2].text)\n\n# Delete \nos.remove(\"C:/Users/pau87/OneDrive/Documentos/Roadmap/data.xml\")"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/RicardiJulio.py",
    "content": "#  * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n#  *\n#  * EJERCICIO:\n#  * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n#  * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n#  * - Nombre\n#  * - Edad\n#  * - Fecha de nacimiento\n#  * - Listado de lenguajes de programación\n#  * Muestra el contenido de los archivos.\n#  * Borra los archivos.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Utilizando la lógica de creación de los archivos anteriores, crea un\n#  * programa capaz de leer y transformar en una misma clase custom de tu \n#  * lenguaje los datos almacenados en el XML y el JSON.\n#  * Borra los archivos.\n\nimport json\nimport os \nimport xml.etree.ElementTree as ET\n\ndef indent(elem, level=0):\n    # Función para aplicar indentación recursiva\n    i = \"\\n\" + level * \"  \"\n    if len(elem):\n        if not elem.text or not elem.text.strip():\n            elem.text = i + \"  \"\n        for e in elem:\n            indent(e, level + 1)\n        if not e.tail or not e.tail.strip():\n            e.tail = i\n    else:\n        if level and (not elem.tail or not elem.tail.strip()):\n            elem.tail = i\n\ndata = {'nombre':'Julio',\n        'edad': 23,\n        'fecha_de_nacimiento':'04/02/2002',\n        'listado_de_lenguajes':'python'}\n\n# Creacion del archivo .json\nnombre_a = 'my_data.json'\nwith open(nombre_a,'w') as j:\n    json.dump(data,j) # Agregado de los datos al archivo\nwith open(nombre_a,'r') as j:\n    datos = j.read()\n    # print(datos) # Lectura e impresion de los archivos\n\n# Crear el elemento raiz del archivo .xml\nroot = ET.Element('Datos_personales')\n\n# Agregar los datos\ndatos = ET.SubElement(root,'datos')\nET.SubElement(datos,'nombre').text = 'Julio'\nET.SubElement(datos,'edad').text = '23'\nET.SubElement(datos,'fecha_de_nacimiento').text = '04/02/2002'\nET.SubElement(datos,'listado_de_lenguajes').text = 'Python'\n\nindent(root)\n\n# Crear un arbol XML\narbol = ET.ElementTree(root)\nnombre_ax = 'my_data.xml'\n# Guardar en un archivo\narbol.write(nombre_ax, encoding = \"utf-8\", xml_declaration = True)\n\nwith open(nombre_ax,'r') as d:\n    info = d.read()\n    print(info)\n\n# DIFICULTAD EXTRA:\n\nclass Persona: # Creando clase custom\n    def __init__(self,nombre,edad,fdn,ldl):\n        self.nombre = nombre\n        self.edad = edad\n        self.fdn = fdn\n        self.ldl = ldl\n    \n    def saludar(self):\n        print (f'Hola mi nombre es {self.nombre} y tengo {self.edad}')\n\ntree = ET.parse(nombre_ax) # Extrayendo informacio del archivo\nroot = tree.getroot()\n\nfor persona in root.findall('datos'):\n    nombre = persona.find('nombre').text\n    edad = persona.find('edad').text\n    fdn = persona.find('fecha_de_nacimiento').text\n    ldl = persona.find('listado_de_lenguajes').text\n    \npersona1 = Persona(nombre,edad,fdn,ldl) # Creando primer objeto\n\nwith open(nombre_a,'r') as on:\n    info_json = json.load(on) # Extrayendo informaciond del archivo\n    nombre2 = info_json['nombre']\n    edad2 = info_json['edad']\n    fdn2 = info_json['fecha_de_nacimiento']\n    ldl2 = info_json['listado_de_lenguajes']\n    \npersona2 = Persona(nombre2,edad2,fdn2,ldl2) # Creando segundo objeto\n\npersona1.saludar()\npersona2.saludar() \n\nos.remove(nombre_a) # Eliminando los archivos\nos.remove(nombre_ax)\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/Sac-Corts.py",
    "content": "### Ejercicio ###\nimport json\nimport xml.etree.ElementTree as xml\nimport os\n\n\ndata = {\n    \"name\": \"Isaac\",\n    \"age\": 22,\n    \"birth_date\": \"21-10-2001\",\n    \"programming_languages\": [\"Python\", \"JavaScript\", \"Java\"]\n}\n\nxml_file = \"sac.xml\"\njson_file = \"sac.json\"\n\n\n# XML\n\ndef create_xml():\n\n    root = xml.Element(\"data\")\n\n    for key, value in data.items():\n        child = xml.SubElement(root, key)\n        if isinstance(value, list):\n            for item in value:\n                xml.SubElement(child, \"item\").text = item\n        else:\n            child.text = str(value)\n\n    tree = xml.ElementTree(root)\n    tree.write(xml_file)\n\n\ncreate_xml()\n\nwith open(xml_file, \"r\") as xml_data:\n    print(xml_data.read())\n\nos.remove(xml_file)\n\n# JSON\n\ndef create_json():\n    with open(json_file, \"w\") as json_data:\n        json.dump(data, json_data)\n\n\ncreate_json()\n\nwith open(json_file, \"r\") as json_data:\n    print(json_data.read())\n\nos.remove(json_file)\n\n\n### Ejercicio Extra ###\n\ncreate_xml()\ncreate_json()\n\nclass Data:\n\n    def __init__(self, name, age, birth_date, programming_languages) -> None:\n        self.name = name\n        self.age = age\n        self.birth_date = birth_date\n        self.programming_languages = programming_languages\n\n\nwith open(xml_file, \"r\") as xml_data:\n\n    root = xml.fromstring(xml_data.read())\n    name = root.find(\"name\").text\n    age = root.find(\"age\").text\n    birth_date = root.find(\"birth_date\").text\n    programming_languages = []\n    for item in root.find(\"programming_languages\"):\n        programming_languages.append(item.text)\n\n    xml_class = Data(name, age, birth_date, programming_languages)\n    print(xml_class.__dict__)\n\n\nwith open(json_file, \"r\") as json_data:\n    json_dict = json.load(json_data)\n    json_class = Data(\n        json_dict[\"name\"],\n        json_dict[\"age\"],\n        json_dict[\"birth_date\"],\n        json_dict[\"programming_languages\"]\n    )\n    print(json_class.__dict__)\n\nos.remove(xml_file)\nos.remove(json_file)"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/SaezMD.py",
    "content": "#12 JSON & XML\n\"\"\"\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un programa capaz de leer y transformar en una misma clase custom de tu \n lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n\"\"\"\n\nimport xml.etree.ElementTree as ET\nimport os\n\nabspath = os.path.abspath(__file__) #get the file directory\ndname = os.path.dirname(abspath)\nos.chdir(dname) #change to file directory\n\n#Create XML file\nroot = ET.Element(\"ContactsXML\")\ncontact = ET.SubElement(root, \"Contact\")\nname = ET.SubElement(contact, \"Name\")\nname.text = \"Saul\"\nage = ET.SubElement(contact, \"Age\")\nage.text = \"25\"\nbirthdate = ET.SubElement(contact, \"Birthdate\")\nbirthdate.text = \"02/12/2010\"\ncoddingList = ET.SubElement(contact, \"Coddinglist\")\ncoddingList.text = \"Pyhton, VBA, GOlang, JavaScript\"\n\n#Write to XML file\ntree = ET.ElementTree(root)\ntree.write(\"contacts.xml\")\n\n#Print XML as string\nxml_string = ET.tostring(root)\nprint(xml_string)\n\n#Remove file XML\nos.remove(\"contacts.xml\")\n\n\n#XML \nxml_file = \"contacts002.xml\"\n\ndata = {\n    \"name\" : \"SSM\",\n    \"age\" : 22,\n    \"birth_date\" : \"22/12/2010\",\n    \"programming_languages\" : [\"Pyhton\", \"VBA\", \"GOlang\", \"JavaScript\"]\n}\n\ndef save_xml():\n\n    root = ET.Element(\"data\")\n\n    for key, value in data.items():\n        child = ET.SubElement(root, key)\n        if isinstance(value, list):\n            for item in value:\n                ET.SubElement(child, \"item\").text = item\n        else:\n            child.text = str(value)\n\n    tree = ET.ElementTree(root)\n    tree.write(xml_file)\n\nsave_xml()\n\nwith open(xml_file, \"r\") as xml_data:\n    print(xml_data.read())\n\nos.remove(xml_file)\n\n#Create JOSN file\nimport json\n\nfilename = 'contacts.json'\nisFile = os.path.isfile(filename)\n \nperson = {\"contactsJSON\" :[{\"Name\": \"Saul Saez\", \"Age\": \"22\", \"BirthDate\":\"02/12/2010\", \"Coddinglist\":\"Pyhton, VBA, GOlang, JavaScript\"}, \n                     ]}\n\n#Save JSON as file\nwith open(filename, 'w') as fp:\n    json.dump(person, fp, indent=4)\n\n#Print JSON as string\nprint(person)\n\n#Delete JSON\nos.remove(\"contacts.json\")\n\n\n#JSON\njson_file = \"contacts002.json\"\n\ndef save_json():\n    with open(json_file, \"w\") as json_data:\n        json.dump(data, json_data, indent=4)\n\nsave_json()\n\nwith open(json_file, \"r\") as json_data:\n    print(json_data.read())\n\nos.remove(json_file)\n\n##EXTRA:\n\nsave_xml()\nsave_json()\n\nclass Data:\n    \n    def __init__(self, name, age, birth_date, programming_languages) -> None:\n        self.name = name\n        self.age = age\n        self.birth_date = birth_date\n        self.programming_languages = programming_languages\n\nwith open(xml_file, \"r\") as xml_data:\n\n    root = ET.fromstring(xml_data.read())\n    name = root.find(\"name\").text\n    age = root.find(\"age\").text\n    birth_date = root.find(\"birth_date\").text\n    programming_languages = []\n    for item in root.find(\"programming_languages\"):\n        programming_languages.append(item.text)\n\n    data_from_xml = Data(name, age, birth_date, programming_languages)\n    print(data_from_xml.__dict__)\n\nwith open(json_file, \"r\") as json_data:\n    json_dict = json.load(json_data)\n    json_class = Data(\n        json_dict[\"name\"],\n        json_dict[\"age\"],\n        json_dict[\"birth_date\"], \n        json_dict[\"programming_languages\"]\n    )\n    print(json_class.__dict__)\n\nos.remove(xml_file)\nos.remove(json_file)\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/SergioGI99.py",
    "content": "\"\"\"\n----------\nJSON Y XML\n----------\nIMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n\nEJERCICIO:\nDesarrolla un programa capaz de crear un archivo XML y JSON que guarde los\nsiguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n- Nombre\n- Edad\n- Fecha de nacimiento\n- Listado de lenguajes de programación\nMuestra el contenido de los archivos.\nBorra los archivos.\n\nDIFICULTAD EXTRA (opcional):\nUtilizando la lógica de creación de los archivos anteriores, crea un\nprograma capaz de leer y transformar en una misma clase custom de tu \nlenguaje los datos almacenados en el XML y el JSON.\nBorra los archivos.\n\"\"\"\n# Ejercicio\n\n# JSON\n\nimport json, os\n\nfilename_json = \"myinfo.json\"\n\nmyinfo = {\n    \"name\": \"Sergio\",\n    \"age\": \"24\",\n    \"birthdate\": \"04/05/1999\",\n    \"languages\": [\n        \"Python\",\n        \"CSS\",\n        \"JavaScript\"\n    ]\n}\n\nwith open(filename_json, \"w\") as write_json:\n    json.dump(myinfo, write_json)\nwrite_json.close\n\nwith open(filename_json, \"r\") as read_json:\n    json_data = json.load(read_json)\n    print(json_data)\n\n# XML\n\nimport xml.etree.ElementTree as ET\n\nfilename_xml = \"myinfo.xml\"\n\nroot = ET.Element(\"info\")\n\nET.SubElement(root, \"name\").text=\"David\"\nET.SubElement(root, \"age\").text=\"33\"\nET.SubElement(root, \"birthdate\").text=\"07/03/1991\"\nlang = ET.SubElement(root, \"languages\")\nET.SubElement(lang, \"language\").text=\"Python\"\nET.SubElement(lang, \"language\").text=\"CSS\"\nET.SubElement(lang, \"language\").text=\"JavaScript\"\n\nxml_file = ET.ElementTree(root)\nxml_file.write(filename_xml)\n\nwith open(filename_xml, \"r\") as read_xml:\n    print(read_xml.read())\n\n# Extra\n\nclass Persona:\n    def __init__(self, name=None, age=None, birth=None, lang=[]):\n        self.__name = name\n        self.__age = age\n        self.__birth = birth\n        self.__lang = lang\n    def show_info(self):\n        print(f\"{self.__name}\\n{self.__age}\\n{self.__birth}\\n{self.__lang}\")      \n\nprint(\"\\nClase con json:\\n---------------\")\n\nwith open(filename_json, \"r\") as read_json:\n    info_json = json.load(read_json)\n\nname = info_json[\"name\"]\nage = info_json[\"age\"]\nbirth = info_json[\"birthdate\"]\nlang = info_json[\"languages\"]\n\nsergio = Persona(name, age, birth, lang)\n\nsergio.show_info()\n\nprint(\"\\nClase con XML:\\n--------------\")\n\ninfo_xml = ET.parse(filename_xml)\n\nname = info_xml.find(\"name\").text\nage = info_xml.find(\"age\").text\nbirth = info_xml.find(\"birthdate\").text\nlanguages = []\nfor item in info_xml.find(\"languages\"):\n    languages.append(item.text)\n\ndavid = Persona(name, age, birth, languages)\n\ndavid.show_info()\n    \nos.remove(filename_json)\nos.remove(filename_xml)"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/SooHav.py",
    "content": "# 12 - JSON y XML\nimport xml.etree.ElementTree as ET\nimport json\nimport os\n# Ejercicio\n# Json\n\n\ndef generar_archivo_json(diccionario: dict):\n    with open('SooHav.json', 'w') as file:\n        json.dump(diccionario, file, indent=4)\n\n# XML\n\n\ndef generar_archivo_xml(etiqueta, diccionario):\n    elemento = ET.Element(etiqueta)\n    for clave, valor in diccionario.items():\n        if clave == 'lenguajes':\n            lenguajes = ET.SubElement(elemento, clave)\n            for lenguaje in valor:\n                l = ET.SubElement(lenguajes, 'lenguaje')\n                l.text = lenguaje\n        else:\n            hijo = ET.SubElement(elemento, clave)\n            # Aquí se agrega el valor como texto del elemento\n            hijo.text = str(valor)\n    ET.ElementTree(elemento).write('SooHav.xml', encoding='utf8')\n\n# Ejercicio Extra\n\n\nclass Datos:\n    def __init__(self, nombre, edad, fecha_nacimiento, lenguajes) -> None:\n        self.nombre = nombre\n        self.edad = edad\n        self.fecha_nacimiento = fecha_nacimiento\n        self.lenguajes = lenguajes\n\n    def __str__(self):\n        return f\"Nombre: {self.nombre}\\nEdad: {self.edad}\\nFecha de Nacimiento: {self.fecha_nacimiento}\\nLenguajes: {', '.join(self.lenguajes)}\"\n\n    @staticmethod\n    def cargar_desde_archivo(archivo):\n        if archivo.endswith('.json'):\n            with open(archivo, 'r') as file:\n                informacion = json.load(file)\n                return Datos(informacion['nombre'], informacion['edad'], informacion['fecha_nacimiento'], informacion['lenguajes'])\n        # leyendo desde un archivo y extrayendo la info\n        elif archivo.endswith('.xml'):\n            tree = ET.parse(archivo)\n            root = tree.getroot()\n            nombre = root.find('nombre').text\n            edad = int(root.find('edad').text)\n            fecha_nacimiento = root.find('fecha_nacimiento').text\n            lenguajes = [elem.text for elem in root.find(\n                'lenguajes').findall('lenguaje')]\n            return Datos(nombre, edad, fecha_nacimiento, lenguajes)\n        else:\n            raise ValueError(\"Formato de archivo no válido.\")\n\n\n# Uso de las funciones creadas\ninfo = {\n    \"nombre\": \"Sofia\",\n    \"edad\": 46,\n    \"fecha_nacimiento\": \"26-02-1978\",\n    \"lenguajes\": [\"Python\", \"R\"]\n}\n\nif __name__ == \"__main__\":\n    while True:\n        print(\"\\nMenú:\")\n        print(\"1. Generar archivo JSON\")\n        print(\"2. Consultar archivo JSON\")\n        print(\"3. Generar archivo XML\")\n        print(\"4. Consultar archivo XML\")\n        print(\"5. Leer y transformar en clase custom\")\n        print(\"6. Salir\")\n\n        opcion = input(\"Seleccione una opción: \")\n\n        if opcion == \"1\":\n            generar_archivo_json(info)\n            print(\"Archivo JSON generado exitosamente.\\n\")\n\n        elif opcion == \"2\":\n            try:\n                with open('SooHav.json', 'r') as file:\n                    archivo = json.load(file)\n                    print(archivo)\n            except FileNotFoundError:\n                print(\"El archivo JSON no existe.\")\n\n        elif opcion == \"3\":\n            archivo_xml = generar_archivo_xml('informacion', info)\n            print(\"Archivo XML generado exitosamente.\\n\")\n\n        elif opcion == \"4\":\n            try:\n                with open('SooHav.xml', 'r') as file:\n                    archivo = file.read()\n                    print(archivo)\n            except FileNotFoundError:\n                print(\"El archivo XML no existe.\")\n\n        elif opcion == \"5\":\n            archivo = input(\n                \"Ingrese el nombre del archivo (incluyendo la extensión .json o .xml): \")\n            try:\n                datos = Datos.cargar_desde_archivo(archivo)\n                print(\"Datos cargados exitosamente:\")\n                print(datos.__dict__)\n            except FileNotFoundError:\n                print(f\"El archivo '{archivo}' no existe.\")\n            except ValueError as e:\n                print(e)\n\n        elif opcion == \"6\":\n            if os.path.exists(\"SooHav.json\"):\n                os.remove(\"SooHav.json\")\n            if os.path.exists(\"SooHav.xml\"):\n                os.remove(\"SooHav.xml\")\n            print(\"Saliendo del programa...\")\n            break\n\n        else:\n            print(\"Opción no válida. Por favor, seleccione una opción válida.\")\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/Tomu98.py",
    "content": "\"\"\" Reto 12: JSON y XML \"\"\"\n\nimport os\nimport xml.etree.ElementTree as xml\nimport json\n\ndata = {\n    \"name\": \"Abel Tomas\",\n    \"age\": 25,\n    \"birth_date\": \"11-02-1998\",\n    \"programming_languages\": [\"Python\", \"Java\", \"SQL\"]\n}\n\nxml_file = \"tomu98.xml\"\njson_file = \"tomu98.json\"\n\n\n# XML\ndef create_xml():\n    root = xml.Element(\"data\")\n\n    for key, value in data.items():\n        child = xml.SubElement(root, key)\n        if isinstance(value, list):\n            for item in value:\n                xml.SubElement(child, \"item\").text = item\n        else:\n            child.text = str(value)\n\n    tree = xml.ElementTree(root)\n    tree.write(\"tomu98.xml\")\n\ncreate_xml()\n\nwith open(xml_file, \"r\") as xml_data:\n    print(xml_data.read())\n\nos.remove(xml_file)\n\n\n# JSON\ndef create_json():\n    with open(json_file, \"w\") as json_data:\n        json.dump(data, json_data)\n\ncreate_json()\n\nwith open(json_file, \"r\") as json_data:\n    print(json_data.read())\n\nos.remove(json_file)\n\n\n\n\"\"\" Reto extra \"\"\"\n\ncreate_xml()\ncreate_json()\n\nclass Data:\n    def __init__(self, name, age, birth_date, programming_languages):\n        self.name = name\n        self.age = age\n        self.birth_date = birth_date\n        self.programming_languages = programming_languages\n\nwith open(xml_file, \"r\") as xml_data:\n    root = xml.fromstring(xml_data.read())\n    name = root.find(\"name\").text\n    age = root.find(\"age\").text\n    birth_date = root.find(\"birth_date\").text\n    programming_languages = []\n    for item in root.find(\"programming_languages\"):\n        programming_languages.append(item.text)\n\n    xml_class = Data(name, age, birth_date, programming_languages)\n    print(xml_class.__dict__)\n\nwith open(json_file, \"r\") as json_data:\n    json_dict = json.load(json_data)\n    json_class = Data(\n        json_dict[\"name\"],\n        json_dict[\"age\"],\n        json_dict[\"birth_date\"],\n        json_dict[\"programming_languages\"]\n    )\n    print(json_class.__dict__)\n\nos.remove(xml_file)\nos.remove(json_file)\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/Zequy40.py",
    "content": "  '''\n  EJERCICIO:\n  Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n  siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n  - Nombre\n  - Edad\n  - Fecha de nacimiento\n  - Listado de lenguajes de programación\n  Muestra el contenido de los archivos.\n  Borra los archivos.\n'''\nimport json\nimport xml.etree.ElementTree as ET\nimport os\n\n# Datos a guardar\ndatos = {\n    \"nombre\": \"Juan\",\n    \"edad\": 35,\n    \"fecha_nacimiento\": \"1989-05-24\",\n    \"lenguajes_programacion\": [\"Python\", \"JavaScript\", \"PhP\"]\n}\n\n# Guardar datos en formato JSON\nwith open('datos.json', 'w') as json_file: #Aquí su utiliza la 'w' para poder escribir el archivo.\n    json.dump(datos, json_file, indent=4)\n\n# Guardar datos en formato XML\nroot = ET.Element(\"datos\")\nfor key, value in datos.items():\n    if isinstance(value, list):\n        subelement = ET.SubElement(root, key)\n        for item in value:\n            ET.SubElement(subelement, \"lenguaje\").text = item\n    else:\n        ET.SubElement(root, key).text = str(value)\n\ntree = ET.ElementTree(root)\ntree.write('datos.xml')\n\n# Mostrar contenido de los archivos\nwith open('datos.json', 'r') as json_file: #En este caso la 'r' es la que permite de leer el archivo a diferencia de la 'w'\n\n    print(\"Contenido de datos.json:\")\n    print(json_file.read())\n\nprint(\"\\n\")\n\nwith open('datos.xml', 'r') as xml_file:\n    print(\"Contenido de datos.xml:\")\n    print(xml_file.read())\n\n# Borra los archivos\nos.remove('datos.json') # Es la biblioteca de os que permite de borrar el contenido que sale en la consola\nos.remove('datos.xml')\n\n\n'''\n  DIFICULTAD EXTRA (opcional):\n  Utilizando la lógica de creación de los archivos anteriores, crea un\n  programa capaz de leer y transformar en una misma clase custom de tu \n  lenguaje los datos almacenados en el XML y el JSON.\n  Borra los archivos.\n'''\nimport json\nimport xml.etree.ElementTree as ET\nimport os\n\nclass Datos:\n    def __init__(self, nombre='', edad=0, fecha_nacimiento='', lenguajes_programacion=[]):\n        self.nombre = nombre\n        self.edad = edad\n        self.fecha_nacimiento = fecha_nacimiento\n        self.lenguajes_programacion = lenguajes_programacion\n\n    @classmethod\n    def desde_json(cls, json_file):\n        with open(json_file, 'r') as file:\n            datos_json = json.load(file)\n            return cls(**datos_json)\n\n    @classmethod\n    def desde_xml(cls, xml_file):\n        tree = ET.parse(xml_file)\n        root = tree.getroot()\n        datos_xml = {}\n        for child in root:\n            if child.tag == 'lenguajes_programacion':\n                lenguajes = [lang.text for lang in child]\n                datos_xml[child.tag] = lenguajes\n            else:\n                datos_xml[child.tag] = child.text\n        return cls(**datos_xml)\n\n# Rutas de los archivos tanto en json como xml\nruta_json = 'datos.json'\nruta_xml = 'datos.xml'\n\n# Crear instancia de Datos desde archivos\ndatos_desde_json = Datos.desde_json(ruta_json)\ndatos_desde_xml = Datos.desde_xml(ruta_xml)\n\n# Mostrar los datos\nprint(\"Datos desde JSON:\")\nprint(datos_desde_json.__dict__)\nprint()\n\nprint(\"Datos desde XML:\")\nprint(datos_desde_xml.__dict__)\n\n# Borra los archivos gracias a la biblioteca de os\nos.remove(ruta_json)\nos.remove(ruta_xml)\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/adolfolozaa.py",
    "content": "'''\r\nIMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\r\n *\r\n * EJERCICIO:\r\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\r\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\r\n * - Nombre\r\n * - Edad\r\n * - Fecha de nacimiento\r\n * - Listado de lenguajes de programación\r\n * Muestra el contenido de los archivos.\r\n * Borra los archivos.\r\n *\r\n * DIFICULTAD EXTRA (opcional):\r\n * Utilizando la lógica de creación de los archivos anteriores, crea un programa capaz de leer y transformar en una misma clase custom de tu lenguaje los datos almacenados en el XML y el JSON.\r\n * Borra los archivos.\r\n '''\r\n\r\nimport xml.etree.ElementTree as xml\r\nimport os\r\n\r\n#creamos un diccionario\r\ndata = {\r\n    'name': 'Adolfo Loza',\r\n    'edad': 56,\r\n    'birth_date': '12-07-1968',\r\n    'languages':['Pyhton', 'Basic', 'C']\r\n}\r\n\r\nxml_file = 'adolfolozaa.xml'\r\n#xml\r\ndef save_xml():\r\n\r\n    root = xml.Element('data')\r\n    for key, value in data.items():\r\n        child = xml.SubElement(root, key)\r\n        if isinstance(value, list):\r\n            for item in value:\r\n                xml.SubElement(child, 'item').text = item\r\n        else:\r\n            child.text = str(value)\r\n\r\n    tree = xml.ElementTree(root)\r\n    tree.write(xml_file)\r\n\r\n\r\nsave_xml()\r\n\r\n#leer el archivo\r\n'''with open(xml_file) as xml_data:\r\n    print(xml_data.read())\r\n'''\r\n\r\n\r\n#JSON\r\nimport json\r\n\r\nprint('------------------')\r\n\r\njson_file = 'data.json'\r\n# convert into JSON\r\ndef create_json():\r\n    y = json.dumps(data)\r\n\r\n    #print(y)\r\n    with open(json_file, 'w') as f:\r\n        json.dump(data, f)\r\n\r\ncreate_json()\r\n\r\n'''with open('data.json') as data_json:\r\n    print(data_json.read())'''\r\n\r\n'''\r\n * DIFICULTAD EXTRA (opcional):\r\n * Utilizando la lógica de creación de los archivos anteriores, crea un\r\n * programa capaz de leer y transformar en una misma clase custom de tu \r\n * lenguaje los datos almacenados en el XML y el JSON.\r\n * Borra los archivos.\r\n'''\r\n\r\n\r\n\r\n#leer \r\n\r\nclass Data:\r\n    def __init__(self, name, age, birth_date, language) -> None:\r\n        self.name = name\r\n        self.age = age\r\n        self.birth_date = birth_date\r\n        self.language = language\r\n\r\nwith open(xml_file, 'r') as xml_data:\r\n    root = xml.fromstring(xml_data.read())\r\n    name = root.find('name').text\r\n    age = root.find('edad').text\r\n    birth_date =root.find('birth_date').text\r\n    languages = []\r\n    for item in root.find('languages'):\r\n        languages.append(item.text)\r\n\r\n    xml_class = Data(name, age, birth_date, languages)\r\n    print('From XML -----------')\r\n    print(xml_class.__dict__)\r\n\r\n    #From JSON\r\n\r\nwith open(json_file, 'r') as json_data:\r\n    print('From JSON -----------')\r\n    json_dict = json.load(json_data)\r\n    json_class = Data(\r\n        json_dict['name'], \r\n        json_dict['edad'], \r\n        json_dict['birth_date'], \r\n        json_dict['languages'])\r\n    print(json_class.__dict__)\r\n\r\n\r\nos.remove(xml_file)\r\nos.remove(json_file)\r\n\r\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/adra-dev.py",
    "content": "\"\"\"\nEJERCICIO:\nDesarrolla un programa capaz de crear un archivo XML y JSON que guarde\nlos siguientes datos (hacindo uso de la sintaxis correcta en cada caso):\n\n- Nombre\n- Edad\n- Fecha de nacimiento\n- Listado de Lenguajes de programación\nMuestra el contenido de los archivos.\nBorra los archivos.\n\nDIFICULTAD EXTRA (opcional):\nUtilizando la lógica de creación de los archivos anteriores, crea un\nprograma capaz de leer y transformar en una misma clase custom de tu \nlenguaje los datos almacenados en el XML y el JSON.\nBorra los archivos.\n\nby adra-dev\n\"\"\"\n\n\"\"\"\nEjercicio:\n\"\"\"\n\n\n\"\"\"\nXML:\nXML es el acrónimo de Extensible Markup Language, es decir, es un \nlenguaje de marcado que define un conjunto de reglas para la \ncodificación de documentos. \n\nUn archivo XML se divide en dos partes: prolog y body. La parte \nprolog consiste en metadatos administrativos, como declaración XML, \ninstrucción de procesamiento opcional, declaración de tipo de \ndocumento y comentarios. La parte del body se compone de dos partes: \nestructural y de contenido (presente en los textos simples).\n\"\"\"\nimport os\nimport xml.etree.ElementTree as xml\n\ndata = {\n\"name\" : \"Adrian Rodriguez\",\n\"age\" : \"26\",\n\"birth_date\" : \"12-02-1998\",\n\"programing_languages\" : ['Python', 'Rust']\n}\n\nxml_file = \"adra-dev.xml\"\n\n# XML\n\ndef create_xml():\n\n    root = xml.Element(\"data\")\n\n    for key, value in data.items():\n        child = xml.SubElement(root, key)\n        if isinstance(value, list):\n            for item in value:\n                xml.SubElement(child, \"item\").text = item\n        else:\n            child.text = str(value)\n    \n    tree = xml.ElementTree(root)\n    tree.write(xml_file)\n\ncreate_xml()\n\nwith open(xml_file) as xml_data:\n    print(xml_data.read())\n    \nos.remove(xml_file)\n\n\n\"\"\"\nJSON: \nEs un formato omnipresente en el que se usa un esquema de documento \njerárquico para definir entidades de datos (objetos) que tienen \nvarios atributos. Cada atributo puede ser un objeto (o una colección \nde objetos ), lo que hace de JSON un formato flexible adecuado tanto \npara datos estructurados como semiestructurados.\n\"\"\"\n\n# JSON\n\nimport json\n\njson_file = \"adra-dev.json\"\n\ndef create_json():\n\n    with open(json_file, \"w\") as json_data:\n        json.dump(data, json_data)\n\n\ncreate_json()\n\nwith open(json_file, \"r\") as json_data:\n    print(json_data.read())\n\nos.remove(json_file)\n\n\"\"\"\nExtra\n\"\"\"\n\ncreate_xml()\ncreate_json()\n\nclass Data():\n\n    def __init__(self, name, age, birth_date, programing_languages) -> None:\n        self.name = name\n        self.age = age\n        self.birth_date = birth_date\n        self.programing_languages = programing_languages\n\n\nwith open(xml_file, \"r\") as xml_data:\n\n    root = xml.fromstring(xml_data.read())\n    name = root.find(\"name\").text\n    age = root.find(\"age\").text\n    birth_date = root.find(\"birth_date\").text\n    programing_languages = []\n    for item in root.find(\"programing_languages\"):\n        programing_languages.append(item.text)\n\n    xml_class = Data(name, age, birth_date, programing_languages)\n    print(xml_class.__dict__)\n\n\nwith open(json_file, \"r\") as json_data:\n    json_dict = json.load(json_data)\n    json_class = Data(\n        json_dict[\"name\"],\n        json_dict[\"age\"],\n        json_dict[\"birth_date\"],\n        json_dict[\"programing_languages\"]\n    )\n    print(json_class.__dict__)\n\nos.remove(xml_file)\nos.remove(json_file)"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/agusrosero.py",
    "content": "\"\"\"\n/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n * \n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu \n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n */\n\"\"\"\nimport xml.etree.ElementTree as ET\nimport json\n\n\n# Archivo XML:\nroot = ET.Element('root')\n\nchild1 = ET.SubElement(root, 'child1')\nchild1.text = 'Nombre: Hernan'\n\nchild2 = ET.SubElement(root, 'child2')\nchild2.text = 'Edad: 23 años'\n\nchild3 = ET.SubElement(root, 'child3')\nchild3.text = 'Fecha de nacimiento: 03-08-00'\n\nchild4 = ET.SubElement(root, 'child4')\nchild4.text = 'Listado de lenguajes de programacion: Python, JavaScript'\n\ntree = ET.ElementTree(root)\ntree.write('archivo.xml')\n\nwith open('archivo.xml', 'r') as file:\n    contenido = file.read()\n    print(contenido)\n\n# Archivo JSON:\ndatos = {\n    'nombre': 'Hernan',\n    'edad': 23,\n    'fecha_nacimiento': '03-08-00',\n    'lenguajes_programacion': ['python', 'javascript']\n}\n\nnombre_archivo = \"datos.json\"\n\nwith open(nombre_archivo, \"w\") as archivo:\n    json.dump(datos, archivo)\n\nwith open(nombre_archivo, 'r') as file:\n    contenido = file.read()\n    print(contenido)\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/alanshakir.py",
    "content": "\"\"\"\n/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n * \n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu \n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n */\n\"\"\"\nimport xml.etree.ElementTree as ET\nimport json\nimport os\n\n\nmy_file_xml = \"alanshakir.xml\"\nroot = ET.Element(\"person_xml\")\nname = ET.SubElement(root, \"name\")\nname.text = \"Alan Ramirez\"\n\nage = ET.SubElement(root, \"age\")\nage.text= \"39\"\n\nbirthdate = ET.SubElement(root, \"birthdate\")\nbirthdate.text = \"1985-01-20\"\n\nlanguages =ET.SubElement(root, \"languages\")\nlanguages_1 = ET.SubElement(languages, \"Language\")\nlanguages_1.text = \"Python\"\nlanguages_2 = ET.SubElement(languages, \"Language\")\nlanguages_2.text = \"Java\"\nlanguages_3 = ET.SubElement(languages, \"Language\")\nlanguages_3.text = \"SQL\"\n\ntree = ET.ElementTree(root)\ntree.write(my_file_xml, \"utf-8\", True)\n\nwith open(my_file_xml, \"r\") as xml_data:\n    print(xml_data.read())\n\n#os.remove(my_file_xml)\n\nperson_json = {\"name\":\"Alan Ramirez\",\n               \"age\":\"39\",\n               \"birthdate\": \"1985-01-20\",\n               \"language\":[\"Python\", \"Java\", \"SQL\"]}\n\nwith open(\"alanshakir.json\", \"w+\") as my_file_json:\n    json.dump(person_json, my_file_json, indent=2)\n\nwith open(\"alanshakir.json\", \"r\") as file:\n    print(file.read())\n\n#os.remove(\"alanshakir.json\")\n\n\n#Extra\n\n\nclass Custom:\n    def __init__(self, name, age, birthdate, languages):\n        self.name = name\n        self.age = age\n        self.birthdate = birthdate\n        self.languages = languages\n\nwith open(\"alanshakir.xml\", \"r\") as my_file_xml:\n        root = ET.fromstring(my_file_xml.read())\n        name = root.find(\"name\").text\n        age = root.find(\"age\").text\n        birthdate = root.find(\"birthdate\").text\n        languages = []\n        for element in root.find(\"languages\"):\n            languages.append(element.text)\n        \n        xml_class = Custom(name, age, birthdate, languages)\n        print(xml_class.__dict__)\n\nwith open(\"alanshakir.json\", \"r\") as my_file_json:\n     json_dict = json.load(my_file_json)\n     json_class = Custom(\n          json_dict[\"name\"],\n          json_dict[\"age\"],\n          json_dict[\"birthdate\"],\n          json_dict[\"language\"]\n     )\n     print(json_class.__dict__)\n\nos.remove(\"alanshakir.xml\")\nos.remove(\"alanshakir.json\")\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/alcaan16.py",
    "content": "\"\"\"/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu \n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n */\"\"\"\n\nimport xml.etree.ElementTree as xml #libreria para los xml\nimport os #libreria del sistema\nimport json #libreria de json\n\ndata={\n\"name\" : \"angel\",\n\"age\" : \"35\",\n\"birth_date\" : \"16/11/1989\",\n\"programming_languages\" : [\"Python\",\"Javascrip\", \"Css\"]\n}\n\n#xml\n\nxml_file=\"angel_xml.xml\"\n\ndef save_xml():\n    \n    root = xml.Element(\"data\") #creamos el directorio raiz\n\n    for key, value in data.items(): #recorremos los valores y los vamos añadiendo al xml\n        child = xml.SubElement(root,key) #creamos un hijo por cada clave dependiente del root\n        if isinstance(value, list): #si es una instancia creamos un sub valor\n            for item in value:\n                xml.SubElement(child,\"item\").text = item\n        else:\n            child.text = str(value)\n    \n    tree = xml.ElementTree(root) #creamos el arbol\n    tree.write(xml_file) #escribimos el arbol\n\nsave_xml()\n\nwith open(xml_file) as xml_data:\n    print(\"**Mostrando el archivo xml\")\n    print(xml_data.read())\n\n#os.remove(xml_file) #descomentar para borrar el archivo al salir\n\n#JSON\n\njson_file=\"angel_json.json\"\n\ndef save_json():\n    with open(json_file, \"w\") as json_data: #abrimos el archivo con escitura\n        json.dump(data, json_data) #añadimos los datos\n\nsave_json()\n\nwith open(json_file, \"r\") as json_data:\n    print(\"**Mostrando el archivo json\")\n    print(json_data.read()) #leemos los datos\n\n#os.remove(json_file) #descomentar para borrar el archivo al salir\n\n#Extra\n\n#**XML**\nclass Data:\n\n    def __init__(self, name, age, birth_date, programming_languages) ->None: #creacion de clase\n        self.name = name\n        self.age = age\n        self.birth_date = birth_date\n        self.programming_languages = programming_languages\n    \nwith open(xml_file, \"r\") as xml_data:\n    \n    root = xml.fromstring(xml_data.read())\n    name = root.find(\"name\").text\n    age = root.find(\"age\").text\n    birth_date = root.find(\"birth_date\").text\n    programming_languages= []\n    for item in root.find(\"programming_languages\"):\n        programming_languages.append(item.text)\n\n    data_from_xml = Data(name, age, birth_date, programming_languages) \n    print(\"**Mostrando la clase desde el archivo xml\")\n    print(data_from_xml.__dict__)\n\n#**json\n\nwith open(json_file, \"r\") as json_data:\n    json_dict = json.load(json_data)\n    json_data = Data(json_dict[\"name\"], \n         json_dict[\"age\"], \n         json_dict[\"birth_date\"],\n         json_dict[\"programming_languages\"]\n         )\n    print(\"de json a clase\")\n    print(json_data.__dict__)\n\n#os.remove(xml_file) #descomentar para borrar el archivo al salir"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/alexdevrep.py",
    "content": "'''\n/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu \n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n */\n'''\n#Importamos las librerías necesarias\nimport json\nimport xml.etree.ElementTree as ET\nimport os\n\n#Creamos una función con un diccinario con los datos\n\ndef crear_datos():\n    datos = {\n        \"Nombre\": \"Alejandro\",\n        \"Edad\": 24,\n        \"Fecha de nacimiento\": \"22-07-1999\",\n        \"Lenguajes de programacion\": [\"Python\",\"Java\",\"JavaScript\"]\n    }\n    return datos\n#Creamos el fichero XML\ndef guardar_xml(datos):\n    #Creamos un nuevo elemento en la estructura de árbol XML\n    root=ET.Element(\"Datos\")\n    #Iteramos tanto las claves como los valores del diccionario\n    for key, value in datos.items():\n        #Si el valor es una lista (para el apartado de lenguajes de programacion que es una lista)\n        if isinstance (value,list):\n            #Creamos un elemento secundario dentro del principal que es root\n            sub_element = ET.SubElement(root, key) #Key es el nombre del elemento secundario\n            #Iteramos cada objeto en la lista value\n            for item in value:\n                #Creamos un elemento llamado lenguaje que es elemento secundario de Key\n                ET.SubElement(sub_element, \"lenguaje\").text = item #Establecemos el texto de este elemento como el valor de item\n        else:\n            # Si el valor no es una lista, creamos un elemento secundario\n            # del elemento principal 'root' y establecemos su texto como una cadena de texto\n            ET.SubElement(root, key).text = str(value)\n\n    #Creamos un nuevo elemento que representa el arbol completo   \n    tree = ET.ElementTree(root)\n    #Escribimos el contenido del arbol en un archivo externo llamado datos.xml\n    tree.write(\"datos.xml\")\n\n#Creamos el archivo JSON\ndef guardar_json(datos):\n    #usamos with para asegurarnos que los recursos son liberados adecuadamente al salir del bloque de codigo\n    with open(\"datos.json\",\"w\") as json_file:\n        #tomamos los datos que deseamos escribir en formato JSON y los escribimos en un archivo .JSON\n        json.dump(datos, json_file, indent=4)\n\ndef main():\n    datos = crear_datos()\n    guardar_xml(datos)\n    guardar_json(datos)\n    print(\"Datos guardados correctamente\")\n    #Borramos los archivos\n    os.remove(\"datos.xml\")\n    print(\"Archivo borrado exitosamente\")\n    os.remove(\"datos.json\")\n    print(\"Archivo json borrado exitosamente\")\n    \nif __name__ == \"__main__\":\n    main()\n\n\n\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/any7dev.py",
    "content": "\"\"\" /*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n * \n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu \n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n */ \"\"\"\n\n#EJERCICIO\nimport json\nimport xml.etree.ElementTree as ET\nimport os\n\n#JSON\ncontenido = {\n    \"Nombre\": \"Ana\",\n    \"Edad\": 36,\n    \"Fecha Nacimiento\": \"11/03/1988\",\n    \"Lenguajes\": [\"Cobol\", \"Python\"]\n}\n\nwith open (\"archivo.json\", 'w') as archivo:\n    json.dump(contenido, archivo, indent=3)\n\nwith open (\"archivo.json\", 'r') as archivo:\n    print(json.load(archivo))\n\nos.remove(\"archivo.json\")\n\n#XML\narchivo = \"archivo.xml\"\n\n#Creamos el árbol con los datos\ncontenido = ET.Element(\"contenido\")\ndatos = ET.SubElement(contenido, \"datos\")\nET.SubElement(datos, \"Nombre\").text = \"Ana\"\nET.SubElement(datos, \"Edad\").text = \"36\"\nET.SubElement(datos, \"Fecha_Nacimiento\").text = \"11/03/1988\"\nET.SubElement(datos, \"Lenguajes\").text = \"Cobol, Python\"\n\n#Creamos el fichero\nET.indent(contenido)\net = ET.ElementTree(contenido)\net.write(archivo, xml_declaration=True, encoding=\"UTF-8\")\n\nwith open (archivo, 'r') as a:\n    print(a.read())\n\nos.remove(\"archivo.xml\")\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/avcenal.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n\"\"\"\nimport re\nimport xml.etree.ElementTree as ET\nfrom xml.dom import minidom\nimport json\nfrom os import remove\n\ndef get_data():\n    name_pattern = r\"^[a-zA-ZÁ-Úá-ú]+(?:[\\ |-]*[a-zA-ZÁ-Úá-ú]*)*$\"\n    date_pattern = r\"^(?:[0-2][0-9]|3[0-1])\\/(?:0[1-9]|1[0-2])\\/(?:19[0-9]{2}|200[0-6])$\"\n    age_pattern = r\"^(?:[2-9][0-9]|1[8-9])$\"\n    languages_pattern = r\"^[a-zA-Z]+(?:[\\ ]*,[\\ ]*[a-zA-Z]+)*$\"\n    name = input(\"Dime el nombre: \")\n    while True:\n        match_name = re.match(name_pattern,name)\n        if match_name != None:\n            break\n        else:\n            name = input(\"Ups... parece que tu nombre no tiene un formato válido. Prueba de nuevo: \")\n\n    age = input(\"Ahora dime la edad(se admitirán edades desde los 18 hasta los 99 años): \")\n    while True:\n        try:\n            int(age)\n        except:\n            age = input(\"Por favor introduce un número dentro del rango 18-99: \")\n        else:\n            match_age = re.match(age_pattern,age)\n            if match_age != None:\n                break\n            else:\n                age = input(\"La edad no está en el rango de 18-99 años. Prueba de nuevo: \")\n    date = input(\"A continuación dime la fecha de nacimiento (usa el formato DD/MM/AAAA): \")\n    while True:\n        match_date = re.match(date_pattern,date)\n        if match_date != None:\n            break\n        else:\n            date = input(\"Vaya, parece que la fecha no tiene un formato correcto. Prueba de nuevo: \")\n\n    languages = input(\"Y por último dime qué lenguajes de programación son tus favoritos (escríbelos separados por coma): \")\n    while True:\n        match_languages = re.match(languages_pattern,languages)\n        if match_languages != None:\n            break\n        else:\n            languages = input (\"Ups... revisa como has introducido la información. Debes separar cada lenguaje con una coma. Prueba de nuevo: \")\n    languages = languages.replace(\" \",\"\")\n    return name,age,date,languages\n\ndef format_xml(element):\n    unformatted_string = ET.tostring(element,'utf-8',method='xml').decode('utf-8')\n    reparsed = minidom.parseString(unformatted_string)\n    return reparsed.toprettyxml(indent=\"  \")\n\ndef generate_archives():\n    name,age,date,languages = get_data()\n    birth_date = date.split(\"/\")\n\n#GENERACIÓN DEL XML\n    person = ET.Element(\"person\")\n    ET.SubElement(person,\"name\").text = name\n    ET.SubElement (person,\"age\").text = age\n    ET.SubElement(person, \"birth_date\").text = date\n    languages_array = languages.split(\",\")\n    xml_languages = ET.SubElement(person,\"languages\")\n    for element in languages_array:\n        ET.SubElement(xml_languages,\"language\").text = element\n    ET.indent(person)\n    et = ET.ElementTree(person)\n    et.write(\"data.xml\",xml_declaration=True)\n\n#GENERACIÓN DEL JSON\n    person_dict = dict()\n    person_dict[\"name\"] = name\n    person_dict[\"age\"] = age\n    person_dict[\"birth_date\"] = date\n    person_dict[\"languages\"] = languages.split(\",\")\n    with open(\"data.json\",\"w+\") as json_file:\n        json.dump(person_dict,json_file,indent=2)\n    json_file.close()\n\n#LECTURA DEL XML\n#para presentar datos por terminal tal y como aparecen en el fichero\n    with open(\"data.xml\",\"r+\") as xml_file:\n        xml_lines = xml_file.readlines()\n    print(\"\\n\")\n    xml_file.close()\n    for line in xml_lines:\n        print (line)\n    print(\"\\n\")\n#lectura y almacenamiento del XML - uso también un diccionario para poder retornar los valores de una manera eficiente\n    xml_dict = dict()\n    root = ET.parse(\"data.xml\")\n    root_node = root.getroot()\n    for child in root_node:\n        if child.tag == \"name\":\n            xml_dict[\"name\"] = child.text\n        elif child.tag == \"age\":\n            xml_dict[\"age\"] = child.text\n        elif child.tag == \"birth_date\":\n            xml_dict[\"birth_date\"] = child.text\n        elif child.tag == \"languages\":\n            xml_dict[\"languages\"] = list()\n            for sub_child in child:\n                xml_dict[\"languages\"].append(sub_child.text)\n\n    \n\n#LECTURA DEL JSON\n    new_person_dict = dict()\n    new_person_dict = json.load(open(\"data.json\"))\n    print(new_person_dict)\n    json_file.close()\n\n    return new_person_dict, xml_dict\n\n    #remove(\"data.xml\")\n    #remove(\"data.json\")\n\n#generate_archives()\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu \n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n\"\"\"\n#declarar una clase persona y dos persona_json y persona_xml que heredan\n\nclass Person():\n    def __init__(self,name,age,date,languages) -> None:\n        self.name = name\n        self.age = age\n        self.date = date\n        self.languages = languages\n\nclass XML_Person(Person):\n    pass\n\nclass JSON_Person(Person):\n    pass\njson_person_dict = dict()\nxml_person_dict = dict()\njson_person_dict, xml_person_dict = generate_archives()\n\n#Creo JSON_Person con los datos del JSON\njson_person = JSON_Person(json_person_dict[\"name\"],json_person_dict[\"age\"],json_person_dict[\"birth_date\"],json_person_dict[\"languages\"])\n#Creo XML_Person con los datos del XML guardados en un diccionario previamente\nxml_person = XML_Person(xml_person_dict[\"name\"],xml_person_dict[\"age\"],xml_person_dict[\"birth_date\"],xml_person_dict[\"languages\"])\n\nprint(json_person.date)\nprint(xml_person.languages)\n\nremove(\"data.xml\")\nremove(\"data.json\")\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/barrancus.py",
    "content": "\"#[número] - [lenguaje_utilizado]\"\n# \n# IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n# \n# EJERCICIO:\n# Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n# siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n# - Nombre\n# - Edad\n# - Fecha de nacimiento\n# - Listado de lenguajes de programación\n# Muestra el contenido de los archivos.\n# Borra los archivos.\n# \n# DIFICULTAD EXTRA (opcional):\n# Utilizando la lógica de creación de los archivos anteriores, crea un\n# programa capaz de leer y transformar en una misma clase custom de tu \n# lenguaje los datos almacenados en el XML y el JSON.\n# Borra los archivos.\n# \n\nimport os\nfrom random import randint\nfrom random import choice\nfrom datetime import date\nfrom datetime import datetime\n\ndef serparacion(cadena):\n    print('{}'.format(cadena * 20))\n\nimport json as jsonlib\nimport xml.etree.ElementTree as xmllib\n\nlenguajes_programacion = [\n    \"Python\",\n    \"JavaScript\",\n    \"Java\",\n    \"C#\",\n    \"C++\",\n    \"C\",\n    \"TypeScript\",\n    \"Ruby\",\n    \"PHP\",\n    \"Swift\",\n    \"Kotlin\",\n    \"Go\",\n    \"Rust\",\n    \"SQL\",\n    \"Perl\",\n    \"Scala\",\n    \"Lua\",\n    \"R\",\n    \"Dart\",\n    \"Haskell\"\n]\n\npersonajes_clasicos = [\n    # Looney Tunes / Merrie Melodies\n    \"Bugs Bunny\",\n    \"Pato Lucas\",\n    \"Porky\",\n    \"Silvestre\",\n    \"Piolín\",\n    \"Correcaminos\",\n    \"Wile E. Coyote\",\n    \"Sam Bigotes\",\n    \"Elmer Gruñón\",\n    \n    # Hanna-Barbera\n    \"Pedro Picapiedra\",\n    \"Pablo Mármol\",\n    \"Scooby-Doo\",\n    \"Shaggy Rogers\",\n    \"Oso Yogui\",\n    \"Bubu\",\n    \"Don Gato\",\n    \"Benito Bodoque\",\n    \"Tiro Loco McGraw\",\n    \"Supersónico\", # (George Jetson)\n    \n    # MGM / Fleischer / Varios\n    \"Tom\",\n    \"Jerry\",\n    \"Popeye\",\n    \"Olivia Olivo\",\n    \"Brutus\",\n    \"La Pantera Rosa\",\n    \"Pájaro Loco\", # (Woody Woodpecker)\n    \"Félix el Gato\",\n    \n    # Disney (Clásicos)\n    \"Mickey Mouse\",\n    \"Pato Donald\",\n    \"Goofy\"\n]\n\n\nclass Persona:\n\n    def __init__(self, name: str, program_lenguages: list, birth_date=None, age=None):\n        self.name = name\n        self.program_lenguages = program_lenguages\n        self.birth_date = birth_date\n        self.age = age\n        if self.birth_date == None or self.age == None: self.create_date()\n\n    def __str__(self) -> str:\n        return f'Nombre: {self.name}, Birth: {self.date_spain()}, Age: {self.age}, Program lenguages: {self.program_lenguages}'\n\n    def date_spain(self) -> str:\n        return f'{self.birth_date.day:02}/{self.birth_date.month:02}/{self.birth_date.year:04}'\n\n    def create_date(self) -> tuple[date, int]:\n        self.syear = randint(1900, 2025)\n        self.smonth = randint(1, 12)\n        if self.smonth == 2 and self.syear % 4 == 0:\n            self.sday = randint(1, 29)\n        elif self.smonth == 2:\n            self.sday = randint(1, 28)\n        elif self.smonth in [1, 3, 5, 7, 8, 10, 12]:\n            self.sday = randint(1, 31)\n        elif self.smonth in [4, 6, 9, 11]:\n            self.sday = randint(1, 30)\n        self.birth_date = date(self.syear, self.smonth, self.sday)\n        self.age = (2025 - self.syear)\n\ndef create_json_xml():\n    students = []\n    for indxstu in range(randint(7,20)):\n        lenguage = []\n        for indxlg in range(randint(1,5)):\n            while True:\n                lg = choice(lenguajes_programacion)\n                if lg not in lenguage:\n                    lenguage.append(lg)\n                    break\n        namecho = choice(personajes_clasicos)\n        personajes_clasicos.remove(namecho)\n        students.append(Persona(namecho, lenguage))\n\n    with open(\"barrancus.json\", mode=\"w\", encoding=\"utf-8\") as write_file:\n        write_file.write('[\\n')\n        counter = 0\n        for student in students:\n            counter += 1\n            x = {\n                \"Nombre\": student.name,\n                \"Edad\": student.age,\n                \"Nacimiento\": student.date_spain(),\n                \"Lenguajes\": student.program_lenguages\n            }\n            jsonlib.dump(x, write_file, indent=4)\n            if counter != len(students): write_file.write(',\\n')\n        write_file.write('\\n]')\n\n    with open(\"barrancus.json\", \"r\") as json_file:\n        # loading json file data to variable data\n        data = jsonlib.load(json_file)\n        \n    # Building the root element of the xml file\n    root = xmllib.Element(\"Estudiantes\")\n    root.tag = \"Estudiantes\"\n    root.text = '\\n\\t'\n    countline = 0\n    for line in data:\n        countline += 1\n        stud = xmllib.SubElement(root, \"Estudiante\")\n        stud.text = '\\n\\t\\t'\n        if len(students) == countline:\n            stud.tail = '\\n'\n        else:\n            stud.tail = '\\n\\t'\n        name = xmllib.SubElement(stud, \"Nombre\")\n        name.text = f'{line[\"Nombre\"]}'\n        name.tail = '\\n\\t\\t'\n        age = xmllib.SubElement(stud, \"Edad\")\n        age.text = str(line[\"Edad\"])\n        age.tail = '\\n\\t\\t'\n        birthday = xmllib.SubElement(stud, \"Nacimiento\")\n        birthday.text = str(line[\"Nacimiento\"])\n        birthday.tail = '\\n\\t\\t'\n        lenguages = xmllib.SubElement(stud, \"Lenguajes\")\n        lenguages.text = str(line[\"Lenguajes\"])\n        lenguages.tail = '\\n\\t'\n\n    tree = xmllib.ElementTree(root)\n    tree.write(\"barrancus.xml\", encoding= \"UTF-8\", method= 'xml')\n\ndef obtaintopersona():\n    personas_json = []\n    with open(\"barrancus.json\", \"r\") as json_file:\n        # loading json file data to variable data\n        data_json = jsonlib.load(json_file)\n\n    for line in data_json:\n        birth = datetime.strptime(line[\"Nacimiento\"], \"%d/%m/%Y\")\n        personas_json.append(Persona(str(line[\"Nombre\"]), line[\"Lenguajes\"], birth, line[\"Edad\"]))\n\n    for persona in personas_json:\n        print(persona)\n\n    serparacion('-----')\n    personas_xml = []\n    data_xml = xmllib.parse(\"barrancus.xml\")\n    root = data_xml.getroot()\n    for child in root:\n        estudent_xml=[subchild.text for subchild in child]\n        personas_xml.append(Persona(\n            estudent_xml[0],\n            estudent_xml[3],\n            datetime.strptime(estudent_xml[2], \"%d/%m/%Y\"),\n            int(estudent_xml[1])\n            )\n        )\n    for personita in personas_xml:\n        print(personita)\n        \ndef main():\n    create_json_xml()\n    obtaintopersona()\n    os.remove(\"barrancus.json\")\n    os.remove(\"barrancus.xml\")\n\nmain()\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/cesar-ch.py",
    "content": "\"\"\"\n    #12 JSON Y XML\n\"\"\"\n\nimport json\nimport os\n\n# Datos a guardar\ndatos = {\n    \"nombre\": \"cesar-ch\",\n    \"edad\": 3,\n    \"fechaNacimiento\": \"2021-02-03\",\n    \"lenguajes\": [\"JavaScript\", \"Python\", \"Java\"],\n}\n\n# Guardar en archivo XML\ndatosXML = f\"\"\"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<datos>\n  <nombre>{datos[\"nombre\"]}</nombre>\n  <edad>{datos[\"edad\"]}</edad>\n  <fechaNacimiento>{datos[\"fechaNacimiento\"]}</fechaNacimiento>\n  <lenguajes>{\",\".join(datos[\"lenguajes\"])}</lenguajes>\n</datos>\"\"\"\n\nwith open(\"datos.xml\", \"w\") as file:\n    file.write(datosXML)\n    print(\"Archivo XML creado\")\n\n# Guardar en archivo JSON\nwith open(\"datos.json\", \"w\") as file:\n    json.dump(datos, file, indent=2)\n    print(\"Archivo JSON creado\")\n\n\"\"\"\n    DIFICULTAD EXTRA\n\"\"\"\n\n# Leer archivo XML\nwith open(\"datos.xml\", \"r\") as file:\n    data = file.read()\n    print(data)\n\n# Leer archivo JSON\nwith open(\"datos.json\", \"r\") as file:\n    data = file.read()\n    print(data)\n\n# Borrar archivo XML\nos.remove(\"datos.xml\")\nprint(\"Archivo XML eliminado\")\n\n# Borrar archivo JSON\nos.remove(\"datos.json\")\nprint(\"Archivo JSON eliminado\")\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/cristianfloyd.py",
    "content": "# EJERCICIO:\n# Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n# siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n# - Nombre\n# - Edad\n# - Fecha de nacimiento\n# - Listado de lenguajes de programación\n# Muestra el contenido de los archivos.\n# Borra los archivos.\n\nimport json\nimport os\nimport xml.etree.ElementTree as xml\n\nname = \"Cristian\"\nage = 48\nbirth_date = \"1978-01-01\"\nprogramming_languages = [\"Python\", \"Java\", \"PHP\"]\n\nxml_file = \"cristianfloyd.xml\"\njson_file = \"cristianfloyd.json\"\n\n# XML\n\ndata = {\n    \"name\": name,\n    \"age\": age,\n    \"birth_date\": birth_date,\n    \"programming_languages\": programming_languages,\n}\n\n\ndef create_xml():\n    root = xml.Element(\"data\")\n    for key, value in data.items():\n        child = xml.SubElement(root, key)\n        if isinstance(value, list):\n            for item in value:\n                xml.SubElement(child, \"item\").text = item\n        else:\n            child.text = str(value)\n\n    tree = xml.ElementTree(root)\n    tree.write(xml_file)\n\n\ndef read_xml():\n    with open(xml_file, \"r\") as file:\n        print(file.read())\n\n\ndef delete_xml():\n    os.remove(xml_file)\n\n\ncreate_xml()\nread_xml()\ndelete_xml()\n\n# JSON\n\n\ndef create_json():\n    with open(json_file, \"w\") as file:\n        json.dump(data, file)\n\n\ndef read_json():\n    with open(json_file, \"r\") as file:\n        print(file.read())\n\n\ndef delete_json():\n    os.remove(json_file)\n\n\ncreate_json()\nread_json()\ndelete_json()\n\n\n#\n# DIFICULTAD EXTRA (opcional):\n# Utilizando la lógica de creación de los archivos anteriores, crea un\n# programa capaz de leer y transformar en una misma clase custom de tu\n# lenguaje los datos almacenados en el XML y el JSON.\n# Borra los archivos.\n\ncreate_xml()\nread_xml()\n\n\nclass UserData:\n    def __init__(self, name: str, age, birth_date, programming_languages) -> None:\n        self.name = name\n        self.age = age\n        self.birth_date = birth_date\n        self.programming_languages = programming_languages\n\n    def display(self):\n        print(f\"Nombre: {self.name}\")\n        print(f\"Edad: {self.age}\")\n        print(f\"Fecha de nacimiento: {self.birth_date}\")\n        print(f\"Lenguajes de programación: {self.programming_languages}\")\n\n    @classmethod\n    def from_xml(cls, xml_data):\n        name = xml_data.find(\"name\").text\n        age = xml_data.find(\"age\").text\n        birth_date = xml_data.find(\"birth_date\").text\n        programming_languages = []\n        for item in xml_data.find(\"programming_languages\"):\n            programming_languages.append(item.text)\n        return cls(name, age, birth_date, programming_languages)\n\n    @classmethod\n    def from_json(cls, json_data):\n        return cls(\n            name=json_data[\"name\"],\n            age=json_data[\"age\"],\n            birth_date=json_data[\"birth_date\"],\n            programming_languages=json_data[\"programming_languages\"],\n        )\n\n\ndef my_app(json_file, xml_file):\n\n    with open(xml_file, \"r\") as file:\n        root = xml.fromstring(file.read())\n        xml_class = UserData.from_xml(root)\n        print(\"XML desde clase custom\")\n        xml_class.display()\n\n    with open(json_file, \"r\") as file:\n        json_data = json.load(file)\n        json_class = UserData.from_json(json_data)\n        print(\"JSON desde clase custom\")\n        json_class.display()\n        \ncreate_json()\ncreate_xml()\nmy_app(json_file, xml_file)\ndelete_xml()\ndelete_json()"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/danielhdzr.py",
    "content": "# #12 JSON Y XML\n#### Dificultad: Difícil | Publicación: 18/03/24 | Corrección: 25/03/24\n\n## Ejercicio\n\n\n'''\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n * \n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu \n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n '''\n\nimport os\nimport xml.etree.ElementTree as xml\nimport json\n\ndata = {\n'name' : 'Daniel',\n'age' : 33,\n'birth_date' : '19-11-1990',\n'languages' : ['python', 'sql'],\n'countries' : {\n    'live_in' : 'Mexico', 'lived_in' : 'USA'\n    }\n}\n\nxml_file = 'Daniel.xml'\njson_file = 'Daniel.json'\n\ndef create_xml():\n    # nombre de la raiz\n    root = xml.Element('programmer')\n\n    # Extraemos el key y value en data\n    for key, value in data.items():\n        '''Creamos un child\n        root es el padre y key es el tag (nombre del sub elemento)\n        Aqui el tag toma el nombre de los keys o sub elementos'''\n        child = xml.SubElement(root, key)\n        \n        # Si el value es una instancia de la clase lista (['python', 'sql']):\n        if isinstance(value, list):\n            # Se itera entre los elementos de value (lista)\n            for item in value:\n                \n                '''se crea un sub elemento.\n                child es el padre e 'item' el nombre de los tags.\n                cada tag es decir, cada 'item' contendra un elemento de la lista en formato str\n                (text)\n                .text en un elemento XML se utiliza para asignar o recuperar el contenido de texto de ese elemento\n                '''\n                xml.SubElement(child, 'item').text = item\n\n        # Creo un sub-sub elemento 'grand_child' \n        elif isinstance(value, dict):\n            for sub_key, sub_value in value.items():\n                grand_child = xml.SubElement(child, 'item')\n                xml.SubElement(grand_child, sub_key).text = sub_value\n        \n        # Muestra el value como tal en formato string\n        else:\n            child.text = str(value)\n\n    tree = xml.ElementTree(root)\n    tree.write(xml_file)\n\ncreate_xml()\n#Lo abro y lo leo\nwith open(xml_file, 'r') as xml_data:\n    print(xml_data.read())\n\n#os.remove(xml_file)\n\n# JSON\ndef create_json():\n    with open(json_file, 'w') as json_data: \n        # Tomo el dicc data, lo convierto a json y lo guardo en json_data\n        json.dump(data, json_data)\ncreate_json()\n\nwith open(json_file, 'r') as json_data:\n    print(json_data.read())\n\n#os.remove(json_file)\n\n\n\n'''Extra'''\n\ncreate_xml()\ncreate_json()\n\nclass modify:\n    def __init__(self, name, age, birth_date, languages, countries) -> None:\n        self.name = name\n        self.age = age\n        self.birth_date = birth_date\n        self.languages = languages\n        self.countries = countries\nwith open(xml_file, 'r') as xml_data:\n    # Obtengo y guardo el texto de mi archivo\n    root = xml.fromstring(xml_data.read())\n    # Encuentra el tag y guarda su contenido (en este caso texto)\n    name = root.find('name').text\n    age = root.find('age').text\n    birth_date = root.find('birth_date').text\n    # languages = root.find('languages').text\n    languages = []\n    for item in root.find('languages'):\n        languages.append(item.text)\n    countries = root.find('countries').text\n\ndata_from_xml = modify(name, age, birth_date, languages, countries)\nprint(data_from_xml.__dict__)\n\nwith open(json_file, 'r') as json_data:\n    json_dict = json.load(json_data)\n    json_class = modify(\n        json_dict['name'],\n        json_dict['age'],\n        json_dict['birth_date'],\n        json_dict['languages'],\n        json_dict['countries']\n    )\n    print(json_class.__dict__)\n\nos.remove(xml_file)\nos.remove(json_file)\n    \n\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/davidrguez98.py",
    "content": "\n\"\"\" /*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n * \n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu \n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n */ \"\"\"\n\n#EJERCICIO\n\nimport os\n\n#XML\n\nimport xml.etree.ElementTree as xml\n\ndata = {\n    \"name\" : \"David\",\n    \"age\" : 26,\n    \"birth_date\" : \"10/03/1998\",\n    \"languages\" : [\"Python\", \"HTML\", \"CSS\"]\n}\n\nxml_file = \"davidrguez98.xml\"\n\ndef save_xml():\n\n    root = xml.Element(\"data\")\n\n    for key, value in data.items():\n        child = xml.SubElement(root, key)\n        if isinstance(value, list):\n            for item in value:\n                xml.SubElement(child, \"item\").text = item\n        else:\n            child.text = str(value)\n    \n    tree = xml.ElementTree(root)\n    tree.write(xml_file)\n\nsave_xml()\n\nwith open(xml_file, \"r\") as xml_data:\n    print(xml_data.read())\n\nos.remove(xml_file)\n\n#JSON\n\nimport json\n\njson_file = \"davidrguez98.json\"\n\ndef save_json():\n    with open(json_file, \"w\") as json_data:\n        json.dump(data, json_data)\n\nsave_json()\n\nwith open(json_file, \"r\") as json_data:\n    print(json_data.read())\n\nos.remove(json_file)\n\n#DIFICULTAD EXTRA\n\nsave_xml()\n\nclass Data():\n\n    def __init__(self, name, age, birth_date, languages):\n        self.name = name\n        self.age = age\n        self.birth_date = birth_date\n        self.languages = languages\n\nwith open(xml_file, \"r\") as xml_data:\n    root = xml.fromstring(xml_data.read())\n    name = root.find(\"name\").text\n    age = root.find(\"age\").text\n    birth_date = root.find(\"birth_date\").text\n    languages = []\n    for item in root.find(\"languages\"):\n        languages.append(item.text)\n    \n    xml_class = Data(name, age, birth_date, languages)\n    print(xml_class.__dict__)\n\nos.remove(xml_file)\n\nsave_json()\n\nwith open(json_file, \"r\") as json_data:\n    json_dict = json.load(json_data)\n    json_class = Data(json_dict[\"name\"], json_dict[\"age\"], json_dict[\"birth_date\"], json_dict[\"languages\"])\n\n    print(json_class.__dict__)\n\nos.remove(json_file)"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/didacdev.py",
    "content": "import json\nimport xml.etree.ElementTree as ET\nimport os\n\nfrom xml.etree.ElementTree import parse\n\n\nclass Programmer:\n\n    def __init__(self, name: str, age: int, birth: str, languages: list):\n\n        self.name = name\n        self.age = age\n        self.birth = birth\n        self.languages = languages\n\n    def to_json(self):\n        data = {\n            'name': self.name,\n            'age': self.age,\n            'birth': self.birth,\n            'languages': self.languages\n        }\n\n        with open(f'{self.name}.json', 'w') as json_file:\n            json.dump(data, json_file)\n\n    def to_xml(self):\n        programmer = ET.Element(self.name)\n\n        name = ET.SubElement(programmer, 'name')\n        name.text = self.name\n\n        age = ET.SubElement(programmer, 'age')\n        age.text = str(self.age)\n\n        birth = ET.SubElement(programmer, 'birth')\n        birth.text = self.birth\n\n        languages = ET.SubElement(programmer, 'languages')\n        for language in self.languages:\n            lang = ET.SubElement(languages, 'language')\n            lang.text = language\n\n        with open(f'{self.name}.xml', 'w') as xml_file:\n            xml_file.write(ET.tostring(programmer, encoding='unicode'))\n\n    @classmethod\n    def from_json(cls, json_file):\n        with open(json_file, 'r') as file:\n            data = json.load(file)\n\n        name = data['name']\n        age = data['age']\n        birth = data['birth']\n        languages = data['languages']\n\n        if os.path.exists(json_file):\n            os.remove(json_file)\n        else:\n            print(f\"El fichero {json_file} no existe\")\n\n        return cls(name, age, birth, languages)\n\n    @classmethod\n    def from_xml(cls, xml_file):\n        tree = parse(xml_file)\n        root = tree.getroot()\n\n        name = root.find('name').text\n        age = int(root.find('age').text)\n        birth = root.find('birth').text\n        languages = [lang.text for lang in root.find('languages')]\n\n        if os.path.exists(xml_file):\n            os.remove(xml_file)\n        else:\n            print(f\"El fichero {xml_file} no existe\")\n\n        return cls(name, age, birth, languages)\n\n\nif __name__ == \"__main__\":\n    programmer = Programmer(name=\"Diego\", age=28, birth=\"10-03-1996\",\n                            languages=[\"Python\", \"Java\", \"Kotlin\", \"Swift\"])\n\n    programmer.to_json()\n    programmer.to_xml()\n\n    programmer2 = Programmer.from_json(\"Diego.json\")\n\n    programmer3 = Programmer.from_xml(\"Diego.xml\")\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/duendeintemporal.py",
    "content": "#12 { Retos para Programadores } JSON Y XML\n\n''' \n* IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu \n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos. \n \n '''\n\n# Bibliography reference\n# Professional JavaScript for web developers by Matt Frisbie [Frisbie, Matt] (z-lib.org)\n#Python Notes for Professionals. 800+ pages of professional hints and tricks (GoalKicker.com) (Z-Library)\n# GPT\n\n# JSON\n# JSON stands for \"JavaScript Object Notation\", but it's not JavaScript. \n# Think of it as just a data serialization format that happens to be directly usable as a JavaScript literal. \n# However, it is not advisable to directly run (i.e. through eval()) JSON that is fetched from an external source. \n# Functionally, JSON isn't very different from XML or YAML – some confusion can be avoided if JSON is just imagined as some serialization format that looks very much like JavaScript.\n\nimport json\nimport os\nimport xml.etree.ElementTree as ET\nfrom xml.dom import minidom\nfrom datetime import datetime\n\n# Short for print\nlog = print\n\n# JSON string example\njson_string = '[{\"name\":\"Kox\",\"age\":51},{\"name\":\"Fanny\",\"age\":17}]'\ndata = json.loads(json_string, object_hook=lambda d: {k: v.upper() if k == 'name' else v for k, v in d.items()})\nlog(data)  # [{'name': 'KOX', 'age': 51}, {'name': 'FANNY', 'age': 17}]\n\n# Parsing with a reviver function for date\njson_string2 = '{\"date\":\"2024-10-12T12:28:40.143Z\"}'\ndata2 = json.loads(json_string2, object_hook=lambda d: {k: (datetime.fromisoformat(v[:-1]) if k == 'date' else v) for k, v in d.items()})\nlog(data2)  # {'date': datetime.datetime(2024, 10, 12, 12, 28, 40, 143000)}\n\n# JSON.stringify equivalent in Python\nlog(json.dumps(True))  # 'true'\nlog(json.dumps(154))  # '154'\nlog(json.dumps('roadmap'))  # '\"roadmap\"'\nlog(json.dumps({}))  # '{}'\nlog(json.dumps({'name': 'Any'}))  # '{\"name\": \"Any\"}'\nlog(json.dumps([41, True, 'System Engineering']))  # '[41, true, \"System Engineering\"]'\nlog(json.dumps({\"x\": 4, \"y\": 4}, indent=2))  # Pretty print with indentation:\n''' \n{\n  \"x\": 4,\n  \"y\": 4\n} \n\n'''\n\n# Data to save\ndata1 = {\n    \"name\": \"Niko Zen\",\n    \"age\": 30,\n    \"birthDate\": \"1983-08-08\",\n    \"languages\": [\"JavaScript\", \"Python\", \"Ruby\", \"Rust\", \"Bash\"]\n}\n\n# Function to create a JSON file\ndef create_json(data):\n    json_data = json.dumps(data, indent=2)\n    with open('data.json', 'w') as json_file:\n        json_file.write(json_data)\n    log(\"Content of the JSON file:\") # Content of the JSON file:\n    log(json_data)\n\n    ''' \n{\n  \"name\": \"Niko Zen\",\n  \"age\": 30,\n  \"birthDate\": \"1983-08-08\",\n  \"languages\": [\n    \"JavaScript\",\n    \"Python\",\n    \"Ruby\",\n    \"Rust\",\n    \"Bash\"\n  ]\n}\n\n '''\n\n# Function to create an XML file\ndef create_xml(data):\n    person = ET.Element(\"person\")\n    ET.SubElement(person, \"name\").text = data[\"name\"]\n    ET.SubElement(person, \"age\").text = str(data[\"age\"])\n    ET.SubElement(person, \"birthDate\").text = data[\"birthDate\"]\n    languages = ET.SubElement(person, \"languages\")\n    for lang in data[\"languages\"]:\n        ET.SubElement(languages, \"language\").text = lang\n\n    # Convert the ElementTree to a string\n    xml_data = ET.tostring(person, encoding='unicode')\n\n    # Use minidom to pretty-print the XML\n    pretty_xml = minidom.parseString(xml_data).toprettyxml(indent=\"  \")\n\n    # Write the pretty-printed XML to a file\n    with open('data.xml', 'w') as xml_file:\n        xml_file.write(pretty_xml)\n\n    log(\"Content of the XML file:\") # Content of the XML file:\n    log(pretty_xml)\n    ''' \n<?xml version=\"1.0\" ?>\n<person>\n  <name>Niko Zen</name>\n  <age>30</age>\n  <birthDate>1983-08-08</birthDate>\n  <languages>\n    <language>JavaScript</language>\n    <language>Python</language>\n    <language>Ruby</language>\n    <language>Rust</language>\n    <language>Bash</language>\n  </languages>\n</person>\n '''\n\n# Function to delete files\ndef delete_files():\n    os.remove('data.json')\n    os.remove('data.xml')\n    log(\"Files deleted.\")\n\n# Custom class\nclass Person:\n    def __init__(self, name, age, birth_date, languages):\n        self.name = name\n        self.age = age\n        self.birth_date = birth_date\n        self.languages = languages\n\n# Function to read and transform data\ndef read_and_transform():\n    with open('data.json', 'r') as json_file:\n        json_data = json.load(json_file)\n\n    with open('data.xml', 'r') as xml_file:\n        xml_data = xml_file.read()\n\n    # Transform XML to object\n    xml_doc = ET.fromstring(xml_data)\n    name = xml_doc.find(\"name\").text\n    age = int(xml_doc.find(\"age\").text)\n    birth_date = xml_doc.find(\"birthDate\").text\n    languages = [lang.text for lang in xml_doc.find(\"languages\").findall(\"language\")]\n\n    # Create an instance of Person\n    person = Person(name, age, birth_date, languages)\n    log(\"Data transformed to Person class:\") # Data transformed to Person class:\n    log(person.__dict__)  # {'name': 'Niko Zen', 'age': 30, 'birth_date': '1983-08-08', 'languages': ['JavaScript', 'Python', 'Ruby', 'Rust', 'Bash']}\n\nif __name__ == \"__main__\":\n    create_json(data1)\n    create_xml(data1)\n    read_and_transform()\n    delete_files()  #Files deleted.\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/edalmava.py",
    "content": "import os\nimport json\nimport xml.etree.ElementTree as ET\n\n# Datos\nname = \"Edwin Alberto Martinez Vanegas\"\nage = 30\nbirthdate = \"1994-08-11\"\nlanguages = [\"Python\", \"Pascal\", \"JavaScript\"]\n\n# Crear archivo XML\nperson = ET.Element(\"person\")\n\nname_element = ET.SubElement(person, \"name\")\nname_element.text = name\n\nage_element = ET.SubElement(person, \"age\")\nage_element.text = str(age)\n\nbirthdate_element = ET.SubElement(person, \"birthdate\")\nbirthdate_element.text = birthdate\n\nlanguages_element = ET.SubElement(person, \"languages\")\nfor lang in languages:\n    language_element = ET.SubElement(languages_element, \"language\")\n    language_element.text = lang\n\ntree = ET.ElementTree(person)\ntree.write(\"data.xml\", encoding=\"utf-8\", xml_declaration=True)\n\n# Crear archivo JSON\ndata = {\n    \"name\": name,\n    \"age\": age,\n    \"birthdate\": birthdate,\n    \"languages\": languages\n}\n\nwith open(\"data.json\", \"w\", encoding=\"utf-8\") as json_file:\n    json.dump(data, json_file, ensure_ascii=False, indent=4)\n\n# Mostrar contenido de los archivos\nprint(\"Contenido del archivo XML:\")\nwith open(\"data.xml\", \"r\", encoding=\"utf-8\") as xml_file:\n    print(xml_file.read())\n\nprint(\"\\nContenido del archivo JSON:\")\nwith open(\"data.json\", \"r\", encoding=\"utf-8\") as json_file:\n    print(json_file.read())\n\n# Borrar los archivos\nif os.path.exists(\"data.xml\"):\n    os.remove(\"data.xml\")\n    print(\"\\nArchivo XML borrado con éxito.\")\nelse:\n    print(\"\\nError al borrar el archivo XML.\")\n\nif os.path.exists(\"data.json\"):\n    os.remove(\"data.json\")\n    print(\"Archivo JSON borrado con éxito.\")\nelse:\n    print(\"Error al borrar el archivo JSON.\")\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/evilpotato04.py",
    "content": "#/*\n# * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n# * \n# * EJERCICIO:\n# * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n# * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n# * - Nombre\n# * - Edad\n# * - Fecha de nacimiento\n# * - Listado de lenguajes de programación\n# * Muestra el contenido de los archivos.\n# * Borra los archivos.\n\nimport json\nimport os\nimport xml.etree.ElementTree as ET\n\ndef crear_archivo(extension: str):\n    if extension == \"json\":\n        with open(f\"archivo.json\", \"w\") as arc:\n            contenido = {\n                \"Nombre\": \"Samy\",\n                \"Edad\": \"19\",\n                \"FechaNacimiento\": \"10/04/2004\",\n                \"Lenguajes\": [\"Python\", \"C#\", \"Javascript\", \"Java\", \"PHP\"]\n            }\n            json.dump(contenido, arc)\n    elif extension == \"xml\":\n        contenido = ET.Element(\"contenido\")\n        ET.SubElement(contenido, \"Nombre\").text = \"Samy\"\n        ET.SubElement(contenido, \"Edad\").text = \"19\"\n        ET.SubElement(contenido, \"FechaNacimiento\").text = \"10/04/2004\"\n        ET.SubElement(contenido, \"Lenguajes\").text = \"Python, C#, Javascript, Java, PHP\"\n\n        xml = ET.ElementTree(contenido)\n        xml.write(\"archivo.xml\" , encoding=\"UTF-8\" , xml_declaration=True)\n    else:\n        print(\"Extención no válida\")\n\ncrear_archivo(\"json\")\ncrear_archivo(\"xml\")\ncrear_archivo(\"samy\")\n\nwith open(\"archivo.json\", \"r\") as arc:\n    print(arc.read())\nwith open(\"archivo.xml\", \"r\") as arc:\n    print(arc.read())\n\nos.remove(\"archivo.json\")\nos.remove(\"archivo.xml\")\n\n# *\n# * DIFICULTAD EXTRA (opcional):\n# * Utilizando la lógica de creación de los archivos anteriores, crea un\n# * programa capaz de leer y transformar en una misma clase custom de tu \n# * lenguaje los datos almacenados en el XML y el JSON.\n# * Borra los archivos.\n# */\n\nclass fabrica_de_archivos:\n    def __init__(self, nombre_archivo: str, extension: str, datos: dict):\n        self.nombre_archivo = nombre_archivo\n        self.extension = extension\n        self.datos = datos\n        \n    def crear_json(self):\n        with open(f\"{self.nombre_archivo}.json\", \"w\") as arc:\n            json.dump(self.datos, arc)\n    \n    def crear_xml(self):\n        xml = ET.Element(\"datos\")\n        for llave, valor in self.datos.items():\n            ET.SubElement(xml, llave).text = valor\n        arc = ET.ElementTree(xml)\n        arc.write(f\"{self.nombre_archivo}.xml\" , encoding=\"UTF-8\" , xml_declaration=True)\n    \n    def crear_archivo(self):\n        match self.extension:\n            case \"json\":\n                self.crear_json()\n            case \"xml\":\n                self.crear_xml()\n            case _:\n                print(\"Extención na válida\")\n    \n    def leer_archivo(self):\n        with open(f\"{self.nombre_archivo}.{self.extension}\", \"r\") as arc:\n            print(arc.read())\n\n    def borrar_archivo(self):\n        os.remove(f\"{self.nombre_archivo}.{self.extension}\")\n\ndef programa():\n    diccionario = {\n        \"Nombre\": \"Samy\",\n        \"Edad\": \"19\",\n        \"FechaNacimiento\": \"10/04/2004\",\n        \"Lenguajes\": \"Python, C#, Javascript, Java, PHP\"\n    }\n\n    fabrica_json = fabrica_de_archivos(\"evilpotato04\", \"json\", diccionario)\n    fabrica_json.crear_archivo()\n    fabrica_json.leer_archivo()\n    fabrica_json.borrar_archivo()\n\n    fabrica_xml = fabrica_de_archivos(\"evilpotato04\", \"xml\", diccionario)\n    fabrica_xml.crear_archivo()\n    fabrica_xml.leer_archivo()\n    fabrica_xml.borrar_archivo()\n\nprograma()"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/fborjalv.py",
    "content": "import xml.etree.ElementTree as xml\nimport json\nimport os\n\ndata = {\n    \"nombre\": \"Borja\",\n    \"edad\": 32,\n    \"fecha_nacimiento\": \"29/04/1992\",\n    \"lenguajes_programacion\": ['Python', 'JavaScript']\n}\n\n# JSON\n\njson_file = \"fborjalv.json\"\n\nwith open(json_file, \"w\") as file:\n    json.dump(data, file)\n\nwith open(json_file, \"r\") as file:\n    print(file.read())\n\n#os.remove(json_file)\n\n\n# XML\nxml_file = \"fborjalv.xml\"\n\nroot = xml.Element(\"data\")\n\nfor key, value in data.items():\n    child = xml.SubElement(root, key)\n    if isinstance(value, list):\n        for item in value: \n            xml.SubElement(child, \"item\").text = item\n    else:\n        child.text = str(value)\n\ntree = xml.ElementTree(root)\ntree.write(xml_file)\n\n\nwith open(xml_file, \"r\") as xml_data:\n    print(xml_data.read())\n\n\n# ejercicio \n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu \n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n */\n\n\"\"\"\n\nclass User:\n    def __init__(self, nombre, edad, fecha_nacimiento, lenguajes_programacion) -> None:\n        self.nombre = nombre\n        self.edad = edad\n        self.fecha_nacimiento = fecha_nacimiento\n        self.lenguajes_programación = lenguajes_programacion\n\n\n\nwith open(json_file ,\"r\") as json_data: \n    json_dict = json.load(json_data)\n    my_user = User(json_dict[\"nombre\"],\n                    json_dict[\"edad\"],\n                    json_dict[\"fecha_nacimiento\"],\n                    json_dict[\"lenguajes_programacion\"])\n    print(my_user.__dict__)"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/garos01.py",
    "content": "import json\nimport xml.etree.ElementTree as ET\nimport os\n\n\ndef crear_archivo_xml(datos):\n    root = ET.Element(\"persona\")\n    for key, value in datos.items():\n        if key == \"lenguajes\":\n            lenguajes = ET.SubElement(root, \"lenguajes\")\n            for lenguaje in value:\n                ET.SubElement(lenguajes, \"lenguaje\").text = lenguaje\n        else:\n            ET.SubElement(root, key).text = str(value)\n\n    tree = ET.ElementTree(root)\n    tree.write(\"datos.xml\")\n\n\ndef crear_archivo_json(datos):\n    with open(\"datos.json\", \"w\") as json_file:\n        json.dump(datos, json_file, indent=4)\n\n\ndef mostrar_contenido_archivos():\n    with open(\"datos.xml\", \"r\") as xml_file:\n        print(\"Contenido del archivo XML:\")\n        print(xml_file.read())\n\n    with open(\"datos.json\", \"r\") as json_file:\n        print(\"\\nContenido del archivo JSON:\")\n        print(json_file.read())\n\n\ndef borrar_archivos():\n    os.remove(\"datos.xml\")\n    os.remove(\"datos.json\")\n    print(\"Archivos borrados exitosamente.\")\n\n\n# Datos\ndatos = {\n    \"nombre\": \"Oscar\",\n    \"edad\": 29,\n    \"fecha_nacimiento\": \"11-09-1994\",\n    \"lenguajes\": [\"Python\", \"JavaScript\"],\n}\n\n# Crear archivos XML y JSON\ncrear_archivo_xml(datos)\ncrear_archivo_json(datos)\n\n# Mostrar contenido de los archivos\nmostrar_contenido_archivos()\n\n# Borrar archivos\nborrar_archivos()\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/ggilperez.py",
    "content": "# 12 JSON & XML\nimport json\nimport os\nimport xml.etree.cElementTree as ET\nfrom dataclasses import dataclass\n\njson_file = \"freddy.json\"\nxml_file = \"data.xml\"\n\ndata = {\n    \"name\": \"Guillermo\",\n    \"age\": \"31\",\n    \"birth_date\": \"4/6/1993\",\n    \"languages\": [\"Python\"]\n}\n\n# JSON\n\n# Write file\ndef write_json_file():\n    with open(json_file, \"w\") as file:\n        json.dump(data, file)\n\nwrite_json_file()\n\n# Read file\nwith open(json_file, \"r\") as file:\n    print(json.load(file))\n\n# Remove file\nos.remove(json_file)\n\n# XML\n\n# Write file\ndef write_xml_file():\n    root = ET.Element(\"data\")\n    for key, value in data.items():\n        child = ET.SubElement(root, key)\n        if isinstance(value, list):\n            for item in value:\n                ET.SubElement(child, \"lang\").text = item\n        else:\n            child.text = value\n\n    tree = ET.ElementTree(root)\n    tree.write(xml_file)\n\nwrite_xml_file()\n\n# Read file\nwith open(xml_file, \"r\") as file:\n    print(file.read())\n\n# Remove file\nos.remove(xml_file)\n\n# Extra\n\n@dataclass\nclass Data:\n    name: str\n    age: int\n    birth_date: str\n    languages: list\n\nwrite_json_file()\nwrite_xml_file()\n\n# Transform from JSON\nwith open(json_file, \"r\") as file:\n    data = json.load(file)\n    obj_data = Data(**data)\n    print(obj_data)\n\n# Transform from XML\nwith open(xml_file, \"r\") as file:\n    data = file.read()\n    xml_data = ET.fromstring(data)\n\n    name = xml_data.find(\"name\").text\n    age = xml_data.find(\"age\").text\n    birth_date = xml_data.find(\"birth_date\").text\n    languages = []\n    for item in xml_data.find(\"languages\"):\n        languages.append(item.text)\n\n    obj_data = Data(name, age, birth_date, languages)\n    print(obj_data)\n\n\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/gringoam.py",
    "content": "import os\nimport xml.etree.ElementTree as xml\nimport json\n\ndata = {\n    \"name\": \"Brais Moure\",\n    \"age\": 36,\n    \"birth_date\": \"29-04-1987\",\n    \"programming_languages\": [\"Python\", \"Kotlin\", \"Swift\"]\n}\n\nxml_file=\"gringoam.xml\"\n\n\n#XML\n\ndef create_xml():\n    root=xml.Element(\"data\")\n    for llave, valor in data.items():\n        hijo=xml.SubElement(root, llave)\n        if isinstance(valor, list):\n            for item in valor:\n                  xml.SubElement(hijo, \"item\").text=item\n\n        else:\n            hijo.text= str(valor)\n\n    tree=xml.ElementTree(root)\n    tree.write(xml_file)\n    \n\ncreate_xml()\nwith open(xml_file, \"r\") as file:\n    print(file.read())\nos.remove(xml_file)\n\n#JSON\njson_file=\"gringoam.json\"\ndef create_jason():\n    with open(json_file, \"w\")as file:\n        json.dump(data, file)\n\ncreate_jason()\n\nwith open(json_file, \"r\") as file:\n    print(file.read())\n\n\nos.remove(json_file)\n\n\"\"\"\nExtra\n\"\"\"\ncreate_xml()\ncreate_jason()\nclass Data:\n\n    def __init__(self, name, age, birth_date, programming_language ) -> None:\n        self.name= name\n        self.age= age \n        self.birth_date= birth_date\n        self.programming_language= programming_language\n\nwith open(xml_file, \"r\") as xml_data:\n        root= xml.fromstring(xml_data.read())\n\n        name= root.find(\"name\").text    \n        age= root.find(\"age\").text\n        birth_date= root.find(\"birth_date\").text\n        programming_language= []\n\n        for item in root.find(\"programming_languages\"):\n           programming_language.append(item.text)\n    \n        xml_calss= Data(name, age, birth_date, programming_language)\n        print(xml_calss.__dict__)\n\n\nwith open(json_file, \"r\") as json_data:\n    dicc=json.load(json_data)\n    json_class= Data(\n        dicc[\"name\"],\n        dicc[\"age\"],\n        dicc[\"birth_date\"],\n        dicc[\"programming_languages\"]\n    )\n\n    print(json_class.__dict__)\n\n    os.remove(json_file)\n    os.remove(xml_file)\n\n    "
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/h4ckxel.py",
    "content": "\"\"\"Operation system module\"\"\"\n\nfrom typing import TypedDict, Self\nimport datetime\nimport json\nimport os\nimport xml.etree.ElementTree as xmlTree\n\n\n\"\"\"\n    JSON and XML files...\n\"\"\"\n\nprint(\"JSON and XML files...\\n\")\n\nJsonContent = TypedDict(\n    \"JsonContent\",\n    {\"age\": int, \"bornDate\": str, \"name\": str, \"programmingLanguages\": list[str]},\n)\n\nXmlContent = TypedDict(\n    \"XmlContent\",\n    {\n        \"age\": int,\n        \"born-date\": str,\n        \"name\": str,\n        \"programming-languages\": dict[str, str],\n    },\n)\n\nJSON_FILE_PATH: str = \"author.json\"\nXML_FILE_PATH: str = \"author.xml\"\n\n# Delete files if exist\nif os.path.exists(path=JSON_FILE_PATH):\n    os.remove(path=JSON_FILE_PATH)\n\nif os.path.exists(path=XML_FILE_PATH):\n    os.remove(path=XML_FILE_PATH)\n\n# Create files and write content\nborn_date = datetime.datetime(year=2002, month=2, day=20)\n\nwith open(file=JSON_FILE_PATH, mode=\"w\", encoding=\"utf8\") as __file:\n    json_content: JsonContent = {\n        \"age\": 22,\n        \"bornDate\": born_date.strftime(format=\"%d/%m/%Y, %H:%M:%S\"),\n        \"name\": \"Lucas\",\n        \"programmingLanguages\": [\"TypeScript\", \"Python\", \"Go (Golang)\"],\n    }\n\n    stringified_json: str = json.dumps(obj=json_content, indent=4, sort_keys=True)\n    __file.writelines(stringified_json)\n    __file.close()\n\n\ndef dict_to_xml(\n    dictionary: dict, parent: None | xmlTree.Element = None\n) -> xmlTree.Element:\n    \"\"\"Transform a dictionary to a XML tree\"\"\"\n    root: xmlTree.Element = xmlTree.Element(\"root\") if parent is None else parent\n\n    for key, value in dictionary.items():\n        line: xmlTree.Element = xmlTree.SubElement(root, key)\n        if isinstance(value, dict):\n            line: xmlTree.Element = dict_to_xml(dictionary=value, parent=line)\n            continue\n\n        line.text = str(object=value)\n\n    return root\n\n\nwith open(file=XML_FILE_PATH, mode=\"w\", encoding=\"utf8\") as __file:\n    xml_content: XmlContent = {\n        \"age\": 22,\n        \"born-date\": born_date.strftime(format=\"%d/%m/%Y, %H:%M:%S\"),\n        \"name\": \"Lucas\",\n        \"programming-languages\": {\n            \"typescript\": \"TypeScript\",\n            \"python\": \"Python\",\n            \"go\": \"Go (Golang)\",\n        },\n    }\n\n    xml: xmlTree.Element = dict_to_xml(dictionary=dict(xml_content))\n\n    stringified_xml: str = xmlTree.tostring(element=xml).decode(encoding=\"utf8\")\n    __file.write(stringified_xml)\n    __file.close()\n\n\n# Print files content\nwith open(file=JSON_FILE_PATH, mode=\"r\", encoding=\"utf8\") as __file:\n    for __line in __file.readlines():\n        print(__line.replace(\"\\n\", \"\"))\n    __file.close()\n\nprint()\n\n\nwith open(file=XML_FILE_PATH, mode=\"r\", encoding=\"utf8\") as __file:\n    for __line in __file.readlines():\n        print(__line)\n    __file.close()\n\n# Delete files\nos.remove(path=JSON_FILE_PATH)\nos.remove(path=XML_FILE_PATH)\n\nprint(\n    \"\\n# ---------------------------------------------------------------------------------- #\\n\"\n)\n\n\"\"\"\n    Additional challenge...\n\"\"\"\n\nprint(\"Additional challenge...\")\n\n\nclass JsonFile:\n    \"\"\"JSON file class\"\"\"\n\n    __path: str\n    __is_deleted: bool\n\n    def __init__(self, path, initial_content: JsonContent) -> None:\n        self.__path = path\n        self.__is_deleted = False\n        self.__write_content(content=initial_content)\n\n    def get_content(self) -> JsonContent:\n        \"\"\"Return file content\"\"\"\n        self.__validate()\n\n        with open(file=self.__path, mode=\"r\", encoding=\"utf8\") as __file:\n            __content: JsonContent = json.load(fp=__file)\n            __file.close()\n\n        return __content\n\n    def __validate(self) -> None:\n        if self.__is_deleted:\n            raise FileNotFoundError\n\n    def __write_content(self, content: JsonContent) -> Self:\n        __stringified_content: str = json.dumps(obj=content, indent=4, sort_keys=True)\n\n        with open(file=self.__path, mode=\"w\", encoding=\"utf8\") as __file:\n            __file.write(__stringified_content)\n            __file.close()\n\n        return self\n\n    def append_language(self, __programming_language: str) -> Self:\n        \"\"\"Append programming language to \"programmingLanguages\" key\"\"\"\n        self.__validate()\n\n        __content: JsonContent = self.get_content()\n        __content[\"programmingLanguages\"].append(__programming_language)\n        self.__write_content(content=__content)\n\n        return self\n\n    def delete_file(self) -> None:\n        \"\"\"Delete file\"\"\"\n        self.__validate()\n        os.remove(path=self.__path)\n        self.__is_deleted = True\n\n    def remove_language(self, __programming_language: str) -> Self:\n        \"\"\"Delete programming language inside \"programmingLanguages\" key\"\"\"\n        self.__validate()\n\n        __content: JsonContent = self.get_content()\n\n        try:\n            for _, __language in enumerate(iterable=__content[\"programmingLanguages\"]):\n                if __language.upper() == __programming_language.upper():\n                    __content[\"programmingLanguages\"].remove(__language)\n        except ValueError:\n            pass\n\n        self.__write_content(content=__content)\n\n        return self\n\n    def update_age(self, __age: int) -> Self:\n        \"\"\"Update age\"\"\"\n        self.__validate()\n\n        __content: JsonContent = self.get_content()\n        __content[\"age\"] = __age\n        self.__write_content(content=__content)\n\n        return self\n\n    def update_born_date(self, __born_date: datetime.date) -> Self:\n        \"\"\"Update born date\"\"\"\n        self.__validate()\n\n        __content: JsonContent = self.get_content()\n        __content[\"bornDate\"] = __born_date.strftime(format=\"%d/%m/%Y, %H:%M:%S\")\n        self.__write_content(content=__content)\n\n        return self\n\n    def update_name(self, __name: str) -> Self:\n        \"\"\"Update name\"\"\"\n        self.__validate()\n\n        __content: JsonContent = self.get_content()\n        __content[\"name\"] = __name\n        self.__write_content(content=__content)\n\n        return self\n\n\nclass XmlFile:\n    \"\"\"XML file class\"\"\"\n\n    __path: str\n    __is_deleted: bool\n\n    def __init__(self, path, initial_content: XmlContent) -> None:\n        self.__path = path\n        self.__is_deleted = False\n        self.__write_content(content=initial_content)\n\n    def get_content(self) -> XmlContent:\n        \"\"\"Return file content\"\"\"\n        self.__validate()\n\n        __content: XmlContent = {\n            \"age\": 0,\n            \"born-date\": \"\",\n            \"name\": \"\",\n            \"programming-languages\": {},\n        }\n        __xml: xmlTree.ElementTree = xmlTree.parse(self.__path)\n\n        __age: xmlTree.Element | None = __xml.find(\"age\")\n        __born_date: xmlTree.Element | None = __xml.find(\"born-date\")\n        __name: xmlTree.Element | None = __xml.find(\"name\")\n        __programming_languages: xmlTree.Element | None = __xml.find(\n            \"programming-languages\"\n        )\n\n        if __age is not None:\n            __value: str | int = __age.text or __content[\"age\"]\n            __content[\"age\"] = int(__value)\n\n        if __name is not None:\n            __content[\"name\"] = __name.text or __content[\"name\"]\n\n        if __born_date is not None:\n            __content[\"born-date\"] = __born_date.text or __content[\"born-date\"]\n\n        if __programming_languages is not None:\n            for __language in __programming_languages.iter():\n                if __language.tag is not None and __language.text is not None:\n                    __content[\"programming-languages\"][\n                        __language.tag.lower()\n                    ] = __language.text\n\n        return __content\n\n    def __validate(self) -> None:\n        if self.__is_deleted:\n            raise FileNotFoundError\n\n    def __write_content(self, content: XmlContent) -> Self:\n        __xml: xmlTree.Element = dict_to_xml(dictionary=dict(content))\n        __stringified_content: str = xmlTree.tostring(element=__xml).decode(\n            encoding=\"utf8\"\n        )\n\n        with open(file=self.__path, mode=\"w\", encoding=\"utf8\") as __file:\n            __file.write(__stringified_content)\n            __file.close()\n\n        return self\n\n    def append_language(self, __programming_language: str) -> Self:\n        \"\"\"Append programming language to \"programmingLanguages\" key\"\"\"\n        self.__validate()\n\n        __content: XmlContent = self.get_content()\n        __content[\"programming-languages\"][\n            __programming_language\n        ] = __programming_language\n        self.__write_content(content=__content)\n\n        return self\n\n    def delete_file(self) -> None:\n        \"\"\"Delete file\"\"\"\n        self.__validate()\n        os.remove(path=self.__path)\n        self.__is_deleted = True\n\n    def remove_language(self, __programming_language: str) -> Self:\n        \"\"\"Delete programming language inside \"programmingLanguages\" key\"\"\"\n        self.__validate()\n\n        __content: XmlContent = self.get_content()\n        __sanitized_content: XmlContent = __content.copy()\n        __sanitized_content[\"programming-languages\"].clear()\n\n        try:\n            for __key, __value in __content[\"programming-languages\"].items():\n                if __key.upper() != __programming_language.upper():\n                    __sanitized_content[\"programming-languages\"][__key] = __value\n        except ValueError:\n            pass\n\n        self.__write_content(content=__sanitized_content)\n\n        return self\n\n    def update_age(self, __age: int) -> Self:\n        \"\"\"Update age\"\"\"\n        self.__validate()\n\n        __content: XmlContent = self.get_content()\n        __content[\"age\"] = __age\n        self.__write_content(content=__content)\n\n        return self\n\n    def update_born_date(self, __born_date: datetime.date) -> Self:\n        \"\"\"Update born date\"\"\"\n        self.__validate()\n\n        __content: XmlContent = self.get_content()\n        __content[\"born-date\"] = __born_date.strftime(format=\"%d/%m/%Y, %H:%M:%S\")\n        self.__write_content(content=__content)\n\n        return self\n\n    def update_name(self, __name: str) -> Self:\n        \"\"\"Update name\"\"\"\n        self.__validate()\n\n        __content: XmlContent = self.get_content()\n        __content[\"name\"] = __name\n        self.__write_content(content=__content)\n\n        return self\n\n\njson_file: JsonFile = JsonFile(\n    path=\"additional-challenge.json\",\n    initial_content={\n        \"age\": 22,\n        \"bornDate\": datetime.datetime(day=20, month=2, year=2002).strftime(\n            format=\"%d/%m/%Y, %H:%M:%S\"\n        ),\n        \"name\": \"Lucas\",\n        \"programmingLanguages\": [\"Python\"],\n    },\n)\n\nSHOULD_EXIT: bool = False\nwhile not SHOULD_EXIT:\n    # pylint: disable=line-too-long\n    operation: str = input(\n        \"\\nSelect an operation ('append language', 'print', 'remove language', 'update age', 'update born date', 'update name', or 'exit'): \"\n    ).upper()\n\n    if operation == \"APPEND LANGUAGE\":\n        programming_language: str = input(\"\\nNew programming language: \")\n        json_file.append_language(programming_language)\n\n    elif operation == \"PRINT\":\n        print(f\"\\n{json_file.get_content()}\", end=\"\")\n\n    elif operation == \"REMOVE LANGUAGE\":\n        programming_language: str = input(\"\\nNew programming language: \")\n        json_file.remove_language(programming_language)\n\n    elif operation == \"UPDATE AGE\":\n        age: str = input(\"\\nNew age: \")\n        json_file.update_age(int(age))\n\n    elif operation == \"UPDATE BORN DATE\":\n        __born_date: str = input(\"\\nNew born date (year-month-day): \")\n        json_file.update_born_date(datetime.datetime.fromisoformat(__born_date))\n\n    elif operation == \"UPDATE NAME\":\n        name: str = input(\"\\nNew name: \")\n        json_file.update_name(name)\n\n    elif operation == \"EXIT\":\n        json_file.delete_file()\n        SHOULD_EXIT = True\n\n    else:\n        print(\"\\nInvalid operation! Try again...\")\n\nxml_file: XmlFile = XmlFile(\n    path=\"additional-challenge.xml\",\n    initial_content={\n        \"age\": 22,\n        \"born-date\": datetime.datetime(day=20, month=2, year=2002).strftime(\n            format=\"%d/%m/%Y, %H:%M:%S\"\n        ),\n        \"name\": \"Lucas\",\n        \"programming-languages\": {\"python\": \"Python\"},\n    },\n)\n\nSHOULD_EXIT = False\nwhile not SHOULD_EXIT:\n    # pylint: disable=line-too-long\n    operation: str = input(\n        \"\\nSelect an operation ('append language', 'print', 'remove language', 'update age', 'update born date', 'update name', or 'exit'): \"\n    ).upper()\n\n    if operation == \"APPEND LANGUAGE\":\n        programming_language: str = input(\"\\nNew programming language: \")\n        xml_file.append_language(programming_language)\n\n    elif operation == \"PRINT\":\n        print(f\"\\n{xml_file.get_content()}\\n\", end=\"\")\n\n    elif operation == \"REMOVE LANGUAGE\":\n        programming_language: str = input(\"\\nNew programming language: \")\n        xml_file.remove_language(programming_language)\n\n    elif operation == \"UPDATE AGE\":\n        age: str = input(\"\\nNew age: \")\n        xml_file.update_age(int(age))\n\n    elif operation == \"UPDATE BORN DATE\":\n        __born_date: str = input(\"\\nNew born date (year-month-day): \")\n        xml_file.update_born_date(datetime.datetime.fromisoformat(__born_date))\n\n    elif operation == \"UPDATE NAME\":\n        name: str = input(\"\\nNew name: \")\n        xml_file.update_name(name)\n\n    elif operation == \"EXIT\":\n        xml_file.delete_file()\n        SHOULD_EXIT = True\n\n    else:\n        print(\"\\nInvalid operation! Try again...\")\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/hectorio23.py",
    "content": "# Autor: Héctor Adán\n# GitHub: https://github.com/hectorio23\n\nimport json\nimport os\nimport xml.etree.ElementTree as ET\n\n# Función para crear un archivo XML con los datos proporcionados\ndef create_xml(name, age, dob, languages):\n    root = ET.Element(\"Person\")\n    ET.SubElement(root, \"Name\").text = name\n    ET.SubElement(root, \"Age\").text = str(age)\n    ET.SubElement(root, \"DateOfBirth\").text = dob\n    lang_list = ET.SubElement(root, \"ProgrammingLanguages\")\n    for lang in languages:\n        ET.SubElement(lang_list, \"Language\").text = lang\n\n    tree = ET.ElementTree(root)\n    tree.write(\"./Person.xml\")\n\n# Función para crear un archivo JSON con los datos proporcionados\ndef create_json(name, age, dob, languages):\n    data = {\n        \"Name\": name,\n        \"Age\": age,\n        \"DateOfBirth\": dob,\n        \"ProgrammingLanguages\": languages\n    }\n    with open(\"./Person.json\", 'w') as json_file:\n        json.dump(data, json_file, indent=4)\n\n# Función para mostrar el contenido de un archivo\ndef display_file_contents(filename):\n    try:\n        with open(filename, 'r') as file:\n            print(f\"Contents of {filename}:\")\n            print(file.read())\n    except FileNotFoundError:\n        print(f\"File not found: {filename}\")\n\n# Función para borrar los archivos generados\ndef delete_files():\n    try:\n        os.remove(\"./Person.xml\")\n        os.remove(\"./Person.json\")\n    except FileNotFoundError:\n        pass\n\ndef main():\n    name = \"Héctor Adán\"\n    age = 19\n    dob = \"2004-06-28\"\n    languages = [\"C++\", \"Python\", \"JavaScript\"]\n\n    # Crear archivos XML y JSON con los datos proporcionados\n    create_xml(name, age, dob, languages)\n    create_json(name, age, dob, languages)\n\n    # Mostrar el contenido de los archivos creados\n    display_file_contents(\"./Person.xml\")\n    display_file_contents(\"./Person.json\")\n\n    # Borrar los archivos generados\n    delete_files()\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/hozlucas28.py",
    "content": "\"\"\"Operation system module\"\"\"\n\nfrom typing import TypedDict, Self\nimport datetime\nimport json\nimport os\nimport xml.etree.ElementTree as xmlTree\n\n\n\"\"\"\n    JSON and XML files...\n\"\"\"\n\nprint(\"JSON and XML files...\\n\")\n\nJsonContent = TypedDict(\n    \"JsonContent\",\n    {\"age\": int, \"bornDate\": str, \"name\": str, \"programmingLanguages\": list[str]},\n)\n\nXmlContent = TypedDict(\n    \"XmlContent\",\n    {\n        \"age\": int,\n        \"born-date\": str,\n        \"name\": str,\n        \"programming-languages\": dict[str, str],\n    },\n)\n\nJSON_FILE_PATH: str = \"author.json\"\nXML_FILE_PATH: str = \"author.xml\"\n\n# Delete files if exist\nif os.path.exists(path=JSON_FILE_PATH):\n    os.remove(path=JSON_FILE_PATH)\n\nif os.path.exists(path=XML_FILE_PATH):\n    os.remove(path=XML_FILE_PATH)\n\n# Create files and write content\nborn_date = datetime.datetime(year=2002, month=2, day=20)\n\nwith open(file=JSON_FILE_PATH, mode=\"w\", encoding=\"utf8\") as __file:\n    json_content: JsonContent = {\n        \"age\": 22,\n        \"bornDate\": born_date.strftime(format=\"%d/%m/%Y, %H:%M:%S\"),\n        \"name\": \"Lucas\",\n        \"programmingLanguages\": [\"TypeScript\", \"Python\", \"Go (Golang)\"],\n    }\n\n    stringified_json: str = json.dumps(obj=json_content, indent=4, sort_keys=True)\n    __file.writelines(stringified_json)\n    __file.close()\n\n\ndef dict_to_xml(\n    dictionary: dict, parent: None | xmlTree.Element = None\n) -> xmlTree.Element:\n    \"\"\"Transform a dictionary to a XML tree\"\"\"\n    root: xmlTree.Element = xmlTree.Element(\"root\") if parent is None else parent\n\n    for key, value in dictionary.items():\n        line: xmlTree.Element = xmlTree.SubElement(root, key)\n        if isinstance(value, dict):\n            line: xmlTree.Element = dict_to_xml(dictionary=value, parent=line)\n            continue\n\n        line.text = str(object=value)\n\n    return root\n\n\nwith open(file=XML_FILE_PATH, mode=\"w\", encoding=\"utf8\") as __file:\n    xml_content: XmlContent = {\n        \"age\": 22,\n        \"born-date\": born_date.strftime(format=\"%d/%m/%Y, %H:%M:%S\"),\n        \"name\": \"Lucas\",\n        \"programming-languages\": {\n            \"typescript\": \"TypeScript\",\n            \"python\": \"Python\",\n            \"go\": \"Go (Golang)\",\n        },\n    }\n\n    xml: xmlTree.Element = dict_to_xml(dictionary=dict(xml_content))\n\n    stringified_xml: str = xmlTree.tostring(element=xml).decode(encoding=\"utf8\")\n    __file.write(stringified_xml)\n    __file.close()\n\n\n# Print files content\nwith open(file=JSON_FILE_PATH, mode=\"r\", encoding=\"utf8\") as __file:\n    for __line in __file.readlines():\n        print(__line.replace(\"\\n\", \"\"))\n    __file.close()\n\nprint()\n\n\nwith open(file=XML_FILE_PATH, mode=\"r\", encoding=\"utf8\") as __file:\n    for __line in __file.readlines():\n        print(__line)\n    __file.close()\n\n# Delete files\nos.remove(path=JSON_FILE_PATH)\nos.remove(path=XML_FILE_PATH)\n\nprint(\n    \"\\n# ---------------------------------------------------------------------------------- #\\n\"\n)\n\n\"\"\"\n    Additional challenge...\n\"\"\"\n\nprint(\"Additional challenge...\")\n\n\nclass JsonFile:\n    \"\"\"JSON file class\"\"\"\n\n    __path: str\n    __is_deleted: bool\n\n    def __init__(self, path, initial_content: JsonContent) -> None:\n        self.__path = path\n        self.__is_deleted = False\n        self.__write_content(content=initial_content)\n\n    def get_content(self) -> JsonContent:\n        \"\"\"Return file content\"\"\"\n        self.__validate()\n\n        with open(file=self.__path, mode=\"r\", encoding=\"utf8\") as __file:\n            __content: JsonContent = json.load(fp=__file)\n            __file.close()\n\n        return __content\n\n    def __validate(self) -> None:\n        if self.__is_deleted:\n            raise FileNotFoundError\n\n    def __write_content(self, content: JsonContent) -> Self:\n        __stringified_content: str = json.dumps(obj=content, indent=4, sort_keys=True)\n\n        with open(file=self.__path, mode=\"w\", encoding=\"utf8\") as __file:\n            __file.write(__stringified_content)\n            __file.close()\n\n        return self\n\n    def append_language(self, __programming_language: str) -> Self:\n        \"\"\"Append programming language to \"programmingLanguages\" key\"\"\"\n        self.__validate()\n\n        __content: JsonContent = self.get_content()\n        __content[\"programmingLanguages\"].append(__programming_language)\n        self.__write_content(content=__content)\n\n        return self\n\n    def delete_file(self) -> None:\n        \"\"\"Delete file\"\"\"\n        self.__validate()\n        os.remove(path=self.__path)\n        self.__is_deleted = True\n\n    def remove_language(self, __programming_language: str) -> Self:\n        \"\"\"Delete programming language inside \"programmingLanguages\" key\"\"\"\n        self.__validate()\n\n        __content: JsonContent = self.get_content()\n\n        try:\n            for _, __language in enumerate(iterable=__content[\"programmingLanguages\"]):\n                if __language.upper() == __programming_language.upper():\n                    __content[\"programmingLanguages\"].remove(__language)\n        except ValueError:\n            pass\n\n        self.__write_content(content=__content)\n\n        return self\n\n    def update_age(self, __age: int) -> Self:\n        \"\"\"Update age\"\"\"\n        self.__validate()\n\n        __content: JsonContent = self.get_content()\n        __content[\"age\"] = __age\n        self.__write_content(content=__content)\n\n        return self\n\n    def update_born_date(self, __born_date: datetime.date) -> Self:\n        \"\"\"Update born date\"\"\"\n        self.__validate()\n\n        __content: JsonContent = self.get_content()\n        __content[\"bornDate\"] = __born_date.strftime(format=\"%d/%m/%Y, %H:%M:%S\")\n        self.__write_content(content=__content)\n\n        return self\n\n    def update_name(self, __name: str) -> Self:\n        \"\"\"Update name\"\"\"\n        self.__validate()\n\n        __content: JsonContent = self.get_content()\n        __content[\"name\"] = __name\n        self.__write_content(content=__content)\n\n        return self\n\n\nclass XmlFile:\n    \"\"\"XML file class\"\"\"\n\n    __path: str\n    __is_deleted: bool\n\n    def __init__(self, path, initial_content: XmlContent) -> None:\n        self.__path = path\n        self.__is_deleted = False\n        self.__write_content(content=initial_content)\n\n    def get_content(self) -> XmlContent:\n        \"\"\"Return file content\"\"\"\n        self.__validate()\n\n        __content: XmlContent = {\n            \"age\": 0,\n            \"born-date\": \"\",\n            \"name\": \"\",\n            \"programming-languages\": {},\n        }\n        __xml: xmlTree.ElementTree = xmlTree.parse(self.__path)\n\n        __age: xmlTree.Element | None = __xml.find(\"age\")\n        __born_date: xmlTree.Element | None = __xml.find(\"born-date\")\n        __name: xmlTree.Element | None = __xml.find(\"name\")\n        __programming_languages: xmlTree.Element | None = __xml.find(\n            \"programming-languages\"\n        )\n\n        if __age is not None:\n            __value: str | int = __age.text or __content[\"age\"]\n            __content[\"age\"] = int(__value)\n\n        if __name is not None:\n            __content[\"name\"] = __name.text or __content[\"name\"]\n\n        if __born_date is not None:\n            __content[\"born-date\"] = __born_date.text or __content[\"born-date\"]\n\n        if __programming_languages is not None:\n            for __language in __programming_languages.iter():\n                if __language.tag is not None and __language.text is not None:\n                    __content[\"programming-languages\"][\n                        __language.tag.lower()\n                    ] = __language.text\n\n        return __content\n\n    def __validate(self) -> None:\n        if self.__is_deleted:\n            raise FileNotFoundError\n\n    def __write_content(self, content: XmlContent) -> Self:\n        __xml: xmlTree.Element = dict_to_xml(dictionary=dict(content))\n        __stringified_content: str = xmlTree.tostring(element=__xml).decode(\n            encoding=\"utf8\"\n        )\n\n        with open(file=self.__path, mode=\"w\", encoding=\"utf8\") as __file:\n            __file.write(__stringified_content)\n            __file.close()\n\n        return self\n\n    def append_language(self, __programming_language: str) -> Self:\n        \"\"\"Append programming language to \"programmingLanguages\" key\"\"\"\n        self.__validate()\n\n        __content: XmlContent = self.get_content()\n        __content[\"programming-languages\"][\n            __programming_language\n        ] = __programming_language\n        self.__write_content(content=__content)\n\n        return self\n\n    def delete_file(self) -> None:\n        \"\"\"Delete file\"\"\"\n        self.__validate()\n        os.remove(path=self.__path)\n        self.__is_deleted = True\n\n    def remove_language(self, __programming_language: str) -> Self:\n        \"\"\"Delete programming language inside \"programmingLanguages\" key\"\"\"\n        self.__validate()\n\n        __content: XmlContent = self.get_content()\n        __sanitized_content: XmlContent = __content.copy()\n        __sanitized_content[\"programming-languages\"].clear()\n\n        try:\n            for __key, __value in __content[\"programming-languages\"].items():\n                if __key.upper() != __programming_language.upper():\n                    __sanitized_content[\"programming-languages\"][__key] = __value\n        except ValueError:\n            pass\n\n        self.__write_content(content=__sanitized_content)\n\n        return self\n\n    def update_age(self, __age: int) -> Self:\n        \"\"\"Update age\"\"\"\n        self.__validate()\n\n        __content: XmlContent = self.get_content()\n        __content[\"age\"] = __age\n        self.__write_content(content=__content)\n\n        return self\n\n    def update_born_date(self, __born_date: datetime.date) -> Self:\n        \"\"\"Update born date\"\"\"\n        self.__validate()\n\n        __content: XmlContent = self.get_content()\n        __content[\"born-date\"] = __born_date.strftime(format=\"%d/%m/%Y, %H:%M:%S\")\n        self.__write_content(content=__content)\n\n        return self\n\n    def update_name(self, __name: str) -> Self:\n        \"\"\"Update name\"\"\"\n        self.__validate()\n\n        __content: XmlContent = self.get_content()\n        __content[\"name\"] = __name\n        self.__write_content(content=__content)\n\n        return self\n\n\njson_file: JsonFile = JsonFile(\n    path=\"additional-challenge.json\",\n    initial_content={\n        \"age\": 22,\n        \"bornDate\": datetime.datetime(day=20, month=2, year=2002).strftime(\n            format=\"%d/%m/%Y, %H:%M:%S\"\n        ),\n        \"name\": \"Lucas\",\n        \"programmingLanguages\": [\"Python\"],\n    },\n)\n\nSHOULD_EXIT: bool = False\nwhile not SHOULD_EXIT:\n    # pylint: disable=line-too-long\n    operation: str = input(\n        \"\\nSelect an operation ('append language', 'print', 'remove language', 'update age', 'update born date', 'update name', or 'exit'): \"\n    ).upper()\n\n    if operation == \"APPEND LANGUAGE\":\n        programming_language: str = input(\"\\nNew programming language: \")\n        json_file.append_language(programming_language)\n\n    elif operation == \"PRINT\":\n        print(f\"\\n{json_file.get_content()}\", end=\"\")\n\n    elif operation == \"REMOVE LANGUAGE\":\n        programming_language: str = input(\"\\nNew programming language: \")\n        json_file.remove_language(programming_language)\n\n    elif operation == \"UPDATE AGE\":\n        age: str = input(\"\\nNew age: \")\n        json_file.update_age(int(age))\n\n    elif operation == \"UPDATE BORN DATE\":\n        __born_date: str = input(\"\\nNew born date (year-month-day): \")\n        json_file.update_born_date(datetime.datetime.fromisoformat(__born_date))\n\n    elif operation == \"UPDATE NAME\":\n        name: str = input(\"\\nNew name: \")\n        json_file.update_name(name)\n\n    elif operation == \"EXIT\":\n        json_file.delete_file()\n        SHOULD_EXIT = True\n\n    else:\n        print(\"\\nInvalid operation! Try again...\")\n\nxml_file: XmlFile = XmlFile(\n    path=\"additional-challenge.xml\",\n    initial_content={\n        \"age\": 22,\n        \"born-date\": datetime.datetime(day=20, month=2, year=2002).strftime(\n            format=\"%d/%m/%Y, %H:%M:%S\"\n        ),\n        \"name\": \"Lucas\",\n        \"programming-languages\": {\"python\": \"Python\"},\n    },\n)\n\nSHOULD_EXIT = False\nwhile not SHOULD_EXIT:\n    # pylint: disable=line-too-long\n    operation: str = input(\n        \"\\nSelect an operation ('append language', 'print', 'remove language', 'update age', 'update born date', 'update name', or 'exit'): \"\n    ).upper()\n\n    if operation == \"APPEND LANGUAGE\":\n        programming_language: str = input(\"\\nNew programming language: \")\n        xml_file.append_language(programming_language)\n\n    elif operation == \"PRINT\":\n        print(f\"\\n{xml_file.get_content()}\\n\", end=\"\")\n\n    elif operation == \"REMOVE LANGUAGE\":\n        programming_language: str = input(\"\\nNew programming language: \")\n        xml_file.remove_language(programming_language)\n\n    elif operation == \"UPDATE AGE\":\n        age: str = input(\"\\nNew age: \")\n        xml_file.update_age(int(age))\n\n    elif operation == \"UPDATE BORN DATE\":\n        __born_date: str = input(\"\\nNew born date (year-month-day): \")\n        xml_file.update_born_date(datetime.datetime.fromisoformat(__born_date))\n\n    elif operation == \"UPDATE NAME\":\n        name: str = input(\"\\nNew name: \")\n        xml_file.update_name(name)\n\n    elif operation == \"EXIT\":\n        xml_file.delete_file()\n        SHOULD_EXIT = True\n\n    else:\n        print(\"\\nInvalid operation! Try again...\")\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/idiegorojas.py",
    "content": "import json\nimport xml.etree.cElementTree as ET\nimport os\n\n# Crear un diccionario\ndata = {\n    'nombre': 'Diego',\n    'edad': 28,\n    'fecha_nacimiento': '1996-11-08',\n    'lenguajes_programacion': ['Python', 'Javascript', 'Swift']\n}\n\n# JSON\n# Definimos el nombre del archivo que se va a crear\njson_file = 'idiegorojas.json'\n\n# Convertir el diccionario a JSON\njson_data = json.dumps(data, indent=4)\n\n# Guardar JSON en un archivo\nwith open(json_file, 'w') as file:\n    json.dump(data, file, indent=4)\n\n# Leer JSON\nwith open(json_file, 'r') as file:\n    datos_guardados = json.load(file)\n    print('Datos cargados:', datos_guardados)\n\n# XML\n# Definir el nombre del archivo que se va a crear\nxml_file = 'idiegorojas.xml'\n\n# Se define la funcion que crea la estructura del xml\ndef create_xml():\n\n    # Se crea el elmento raiz del XML\n    root = ET.Element('data')\n\n    # Iterar sobre el dict 'data' para cada par clave valor\n    for clave, valor in data.items():\n        # Crear un subelemento con el nombre de la clave\n        elemento_hija = ET.SubElement(root, clave.replace(' ', '_'))\n        # Si el elemnto es una lista crear un elemento 'item' para cada elemento\n        if isinstance (valor, list):\n            for item in valor:\n                ET.SubElement(elemento_hija, 'item').text = item\n        # Si no es una lista se asigna el elemento como un texto\n        else:\n            elemento_hija.text = str(valor)\n\n    # Guardamos el archivo\n    # Creamos un arbol xml con la estructura creada.\n    tree = ET.ElementTree(root)\n    # Guardamos el arbol en el archivo especificado\n    tree.write(xml_file)\n\n# Llamamos a nuestra funcion\ncreate_xml()\n\n# Leemos el xml\nwith open(xml_file, 'r') as file:\n    print(file.read())\n\n\n\n\n\n# Extra\n\nclass Data:\n\n    def __init__(self, nombre, edad, fecha_nacimiento, lenguajes_programacion) -> None:\n        self.nombre = nombre\n        self.edad = edad\n        self.fecha_nacimiento = fecha_nacimiento\n        self.lenguajes_programacion = lenguajes_programacion\n\n# Crear nuevamente los archivos JSON y XML para leerlos en la clase Data\nwith open(json_file, 'w') as file:\n    json.dump(data, file, indent=4)\n\ncreate_xml()\n\nwith open(xml_file, \"r\") as file:\n    root = ET.fromstring(file.read())\n    nombre = root.find(\"nombre\").text\n    edad = root.find(\"edad\").text\n    fecha_nacimiento = root.find(\"fecha_nacimiento\").text\n    lenguajes_programacion = []\n    for item in root.find(\"lenguajes_programacion\"):\n        lenguajes_programacion.append(item.text)\n\n    xml_class = Data(nombre, edad, fecha_nacimiento, lenguajes_programacion)\n    print(xml_class.__dict__)\n\nwith open(json_file, \"r\") as json_data:\n    json_dict = json.load(json_data)\n    json_class = Data(\n        json_dict[\"nombre\"],\n        json_dict[\"edad\"],\n        json_dict[\"fecha_nacimiento\"],\n        json_dict[\"lenguajes_programacion\"]\n    )\n    print(json_class.__dict__)\n\nos.remove(xml_file)\nos.remove(json_file)"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/ignaciovihe.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n\"\"\"\n\nfrom pathlib import Path\nimport xml.etree.ElementTree as XML\nimport json\n\nxml_file = \"ignaciovihe.xml\"\njson_file = \"ignaciovihe.json\"\n\nprogrammer = {\n    \"name\": \"ignacio\",\n    \"age\": \"40\",\n    \"date_of_birth\": \"23/02/1985\",\n    \"languages\": [\"python\", \"Javascript\", \"GO\"]\n}\n\n\ndef create_xml():\n\n    #Creo la estructura XML\n    root = XML.Element(\"programmer\")# Creo el elemento raiz <programmer>\n\n    #Crear los subelementos\n    for key, value in programmer.items():\n        child = XML.SubElement(root, key)\n        if isinstance(value, list):\n            for language in value:\n                XML.SubElement(child, \"language\").text = language\n        else:\n            child.text = value\n\n    tree = XML.ElementTree(root) # Convertimos la estructura en un árbol XML\n    tree.write(xml_file, encoding=\"utf-8\", xml_declaration=True) # Guardamos el XML en un archivo.\n\ndef print_xml():\n\n    # Cargar el archivo XML\n    tree = XML.parse(xml_file) # Abre y analiza el archivo XML\n    root = tree.getroot()  # Obtiene el elemento raíz del XML (<programmer> en este caso)\n\n    # Recorrer los elementos 'libro' y extraer información\n    for child in root:\n        if len(child) == 0:\n            print(f\"{child.tag}: {child.text}\")\n        else:\n            languages = \"\"\n            for language in child:\n                languages += (language.text + \", \")\n            print(f\"{child.tag}: {languages.strip(\", \")}\")\n\ndef delete_file(file_name):\n\n    file = Path(file_name)\n    if file.exists():\n        file.unlink()\n\ncreate_xml()\nprint_xml()\ndelete_file(xml_file)\n\n\ndef create_json():\n    with open(json_file, \"w\") as file:\n        json.dump(programmer, file, indent=4) # Le paso un diccionario(programmer)\n\ndef print_json():\n    with open(json_file,\"r\") as file:\n        data = json.load(file) # me devulve un diccionario(data)\n\n    for key, value in data.items():\n        if isinstance(value, list):\n            print(f\"{key}: {\" \".join(value)}\")\n        else:\n            print(f\"{key}: {value}\")\n\ncreate_json()\nprint_json()\ndelete_file(json_file)\n\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu \n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n\"\"\"\n\nclass Programmer:\n    def __init__(self,):\n        self.name = None\n        self.age = None\n        self.date = None\n        self.languages = None\n\n    def set_attribute(self, key:str, value):\n        setattr(self, key, value)\n\n    def print_data(self):\n        print(f\"Name: {self.name}\\nAge: {self.age}\\nDate of birth: {self.date}\\nLanguajes:\")\n        for language in self.languages:\n            print(f\"\\t{language}\")\n\ndef read_xml():\n\n    tree = XML.parse(xml_file)\n    root = tree.getroot()\n\n    my_programmer = Programmer()\n\n    for child in root:\n        if len(child) == 0:\n            my_programmer.set_attribute(child.tag, child.text)\n        else:\n            languages = [language.text for language in child]\n            my_programmer.set_attribute(child.tag, languages)\n    return my_programmer\n\n\ndef read_json():\n    with open(json_file, \"r\") as file:\n        data = json.load(file)\n\n    my_programmer = Programmer()\n    for key, value in data.items():\n        my_programmer.set_attribute(key, value)\n    \n    return my_programmer\n\nprint(\"-------Lee XML-------\")\ncreate_xml()\nmy_programmer = read_xml()\nmy_programmer.print_data()\ndelete_file(xml_file)\n\nprint(\"-----Lee JSON-----\")\ncreate_json()\nmy_programmer = read_json()\nmy_programmer.print_data()\ndelete_file(json_file)"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/isilanes.py",
    "content": "import json\nfrom datetime import datetime\nfrom pathlib import Path\nimport xml.etree.ElementTree as tree\nfrom typing import Optional\n\n\ndef main(data: dict) -> None:\n    json_file = Path(\"data.json\")\n    run_json(data, json_file)\n\n    xml_file = Path(\"data.xml\")\n    run_xml(data, xml_file)\n\n\ndef run_json(data: dict, json_file: Path, only_create: bool = False) -> None:\n    json_str = json.dumps(data, ensure_ascii=False, indent=4)\n\n    # Crear fichero:\n    json_file.write_text(json_str, encoding=\"utf-8\")\n\n    if only_create:\n        return\n\n    # Mostrar fichero:\n    print(json_file.read_text())\n\n    # Borrar fichero:\n    json_file.unlink()\n\n\ndef run_xml(data: dict, xml_file: Path, only_create: bool = False) -> None:\n    root = tree.Element(\"persona\")\n\n    for k, v in data.items():\n        element = tree.SubElement(root, k)\n        if isinstance(v, list):\n            for sub in v:\n                sub_element = tree.SubElement(element, \"item\")\n                sub_element.text = sub\n        else:\n            element.text = str(v)\n\n    tree.indent(root)  # for pretty output\n    xml_str = tree.tostring(root, encoding=\"utf-8\")\n\n    # Crear fichero:\n    xml_file.write_bytes(xml_str)\n\n    if only_create:\n        return\n\n    # Mostrar fichero:\n    print(xml_file.read_text())\n\n    # Borrar fichero:\n    xml_file.unlink()\n\n\ndef extra(data: dict):\n\n    for file_format in (\"json\", \"xml\"):\n        file = Path(f\"data.{file_format}\")\n        parser = JsonAndXML(file, file_format=file_format)\n        parser.write_file(data)\n        parser.read_file()\n        parser.modify_data()\n        parser.write_file()\n        print(parser.file.read_text(encoding=\"utf-8\"))\n        parser.file.unlink()\n\n\nclass JsonAndXML:\n\n    def __init__(self, file: Path, file_format: str = \"json\"):\n        self.file = file\n        self.file_format = file_format\n        self.data = None\n\n    def write_file(self, data: Optional[dict] = None, file_format: Optional[str] = None) -> None:\n        data = data or self.data\n        file_format = file_format or self.file_format\n\n        if file_format == \"json\":\n            run_json(data, self.file, only_create=True)\n        elif file_format == \"xml\":\n            run_xml(data, self.file, only_create=True)\n        else:\n            raise ValueError(f\"No conozco el formato {file_format}\")\n\n    def read_file(self, file_format: Optional[str] = None) -> None:\n        file_format = file_format or self.file_format\n\n        if not self.file.is_file():\n            print(f\"No pudimos leer el fichero '{self.file}'. No existe.\")\n            return\n\n        if file_format == \"json\":\n            self.data = json.loads(self.file.read_text(encoding=\"utf-8\"))\n        elif file_format == \"xml\":\n            root = tree.parse(self.file).getroot()\n\n            self.data = {}\n            for child in root:\n                self.data[child.tag] = child.text\n                values = [c.text for c in child]\n                if values:\n                    self.data[child.tag] = values\n        else:\n            raise ValueError(f\"No conozco el formato {file_format}\")\n\n    def modify_data(self):\n        if not self.data:\n            return\n        self.data[\"nombre\"] = \"Henry Cavill\"\n\n\nif __name__ == \"__main__\":\n    persona = {\n        \"nombre\": \"Iñaki Silanes\",\n        \"edad\": 46,\n        \"fecha_de_nacimiento\": datetime(1977, 6, 11, 9, 0).isoformat(),\n        \"lenguajes_de_programación\": [\"python\", \"bash\", \"perl\", \"fortran\", \"javascript\"],\n    }\n\n    main(data=persona)\n    extra(data=persona)\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/jesusgdev.py",
    "content": "'''\nIMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n \n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n   siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n   - Nombre\n   - Edad\n   - Fecha de nacimiento\n   - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n  \n * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n   programa capaz de leer y transformar en una misma clase custom de tu \n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n'''\n\nimport xml.etree.ElementTree as ET\nimport xml.dom.minidom\nimport json\nimport os\n\n# 📌 Datos de ejemplo\ndata = {\n    \"name\": \"Jesús García\",\n    \"age\": 41,\n    \"birth_date\": \"1984-03-25\",\n    \"programming_languages\": [\"Python\", \"JavaScript\", \"Java\"]\n}\n\n# 🗂️ Archivos\nxml_file = \"jesusgdev.xml\"\njson_file = \"jesusgdev.json\"\n\n# 🛠️ Crear XML\ndef create_xml():\n    root = ET.Element(\"data\")\n    for key, value in data.items():\n        child = ET.SubElement(root, key)\n        if isinstance(value, list):\n            for item in value:\n                ET.SubElement(child, \"item\").text = item\n        else:\n            child.text = str(value)\n\n    raw_xml = ET.tostring(root, encoding=\"utf-8\")\n    pretty_xml = xml.dom.minidom.parseString(raw_xml).toprettyxml(indent=\"  \")\n\n    with open(xml_file, \"w\", encoding=\"utf-8\") as f:\n        f.write(pretty_xml)\n        print(f\"✅ Archivo XML creado: {xml_file}\")\n\n# 🛠️ Crear JSON\ndef create_json():\n    with open(json_file, \"w\", encoding=\"utf-8\") as f:\n        json.dump(data, f, indent=4, ensure_ascii=False)\n        print(f\"✅ Archivo JSON creado: {json_file}\")\n\n# 🧹 Borrar archivos\ndef delete_file(file_name):\n    if os.path.exists(file_name):\n        os.remove(file_name)\n        print(f\"🗑️ Archivo eliminado: {file_name}\")\n    else:\n        print(f\"⚠️ Archivo no encontrado: {file_name}\")\n\n# 🔽 Crear archivos\ncreate_xml()\ncreate_json()\n\n# 📄 Mostrar contenido XML\nprint(\"\\n📄 Contenido del archivo XML:\\n\")\nwith open(xml_file, \"r\", encoding=\"utf-8\") as f:\n    print(f.read())\n\n# 📄 Mostrar contenido JSON\nprint(\"\\n📄 Contenido del archivo JSON:\\n\")\nwith open(json_file, \"r\", encoding=\"utf-8\") as f:\n    print(f.read())\n\n# 🧹 Eliminar archivos\nprint(\"\\n🧹 Eliminando archivos...\")\ndelete_file(xml_file)\ndelete_file(json_file)\n\n# 🧪 Extra: Crear objetos desde XML y JSON (simulación)\nprint(\"\\n🧪 Extra: Conversión a objetos en Python\")\n\n# 🧱 Clase contenedora\nclass Data:\n    def __init__(self, name, age, birth_date, programming_languages):\n        self.name = name\n        self.age = age\n        self.birth_date = birth_date\n        self.programming_languages = programming_languages\n\n# ✨ Recrear archivos temporalmente para la prueba\ncreate_xml()\ncreate_json()\n\n# 📤 Leer XML y mostrar como texto XML\nwith open(xml_file, \"r\", encoding=\"utf-8\") as f:\n    xml_content = f.read()\n    print(\"\\n📤 Datos convertidos desde XML (formato XML):\\n\")\n    print(xml_content)\n\n# 📦 Convertir XML a objeto\nroot = ET.fromstring(xml_content)\nname = root.find(\"name\").text\nage = root.find(\"age\").text\nbirth_date = root.find(\"birth_date\").text\nlanguages = [item.text for item in root.find(\"programming_languages\")]\nxml_obj = Data(name, age, birth_date, languages)\n\n# 📦 Leer JSON y convertir a objeto\nwith open(json_file, \"r\", encoding=\"utf-8\") as f:\n    json_dict = json.load(f)\n    json_obj = Data(\n        json_dict[\"name\"],\n        json_dict[\"age\"],\n        json_dict[\"birth_date\"],\n        json_dict[\"programming_languages\"]\n    )\n\n# 📋 Imprimir contenido como diccionario\nprint(\"\\n📤 Datos convertidos desde JSON (formato diccionario):\")\nprint(json.dumps(json_obj.__dict__, indent=4, ensure_ascii=False))\n\n# 🧹 Eliminar archivos\nprint(\"\\n🧹 Eliminando archivos...\")\ndelete_file(xml_file)\ndelete_file(json_file)\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/jptxaya.py",
    "content": "#JSON AND XML\n\n#Creacion de fichero XML\n\ndatos = {\"nombre\": \"jptxaya\",\n         \"edad\": \"45\",\n         \"fecha_nacimiento\": \"19/03/1979\",\n         \"lenguajes\": [\"python\",\"java\",\"react\"]}\n\n#XML\n\n#Creacion de fichero XML\nimport xml.etree.ElementTree as gfg\nimport os\nimport json\n\n\ntry:\n    root = gfg.Element(\"Datos\")\n    for key,value in datos.items():\n        elem = gfg.SubElement(root,key)\n        if isinstance(value,list):\n            i = 0\n            for value_list in value:\n                lang = gfg.SubElement(elem,\"lenguaje_\" + str(i))\n                lang.text = value_list\n                i += 1\n        else:\n           elem.text = value\n    tree = gfg.ElementTree(root)\n    tree.write(\"newxml.xml\", encoding=\"UTF-8\", xml_declaration=True)\n\n\n# Read from XML file\n    with open(\"newxml.xml\", \"r\") as xml_read:\n        root = gfg.fromstring(xml_read.read())\n        nombre = root.find(\"nombre\").text\n        edad = root.find(\"edad\").text\n        birth = root.find(\"fecha_nacimiento\").text\n        lenguajes = []\n        for language in root.find(\"lenguajes\"):\n            lenguajes.append(language.text)\n\n        print(f\"Nombre: {nombre} Edad:{edad} Fecha Nac:{birth}\")\n        print(\"Lenguajes:\")\n        for leng in lenguajes:\n            print(leng)\n\n#Borrado fichero xml\n#    os.remove(\"newxml.xml\")\n\nexcept Exception as exc:\n    print(f\"Exception {exc}\")\n\n#JSON\n\ntry:\n#Creacion de Fichero json\n    json_object = json.dumps(datos,indent=4)\n    with open(\"newjson.json\",\"w\") as new_json:\n        new_json.write(json_object)\n\n#Read File json\n    with open(\"newjson.json\",\"r\") as new_json:\n        json_string = new_json.read()\n        json_object = json.loads(json_string)\n\n        \n        nombre = json_object[\"nombre\"]\n        edad = json_object[\"edad\"]\n        birth = json_object[\"fecha_nacimiento\"]\n        lenguajes = []\n        for language in json_object[\"lenguajes\"]:\n            lenguajes.append(language)\n\n        print(f\"Nombre: {nombre} Edad:{edad} Fecha Nac:{birth}\")\n        print(\"Lenguajes:\")\n        for leng in lenguajes:\n            print(leng)\n\n#Borrado fichero json\n#    os.remove(\"newjson.json\") \n        \nexcept Exception as exc:\n    print(f\"Exception {exc}\")\n\n\n#Dificultad Extra\n\nprint (\"#######Dificultad extra\")\n\nclass Persona:\n\n    def __init__(self,file) -> None:\n        datos = self.read_file(file)\n        self.name = datos[\"name\"]\n        self.age = datos[\"age\"]\n        self.birth = datos[\"birth\"]\n        self.languages = datos[\"languages\"]\n\n\n    def read_file(self, file):\n        datos = {}\n        if file.endswith(\".xml\"):\n           with open(file, \"r\") as xml_read:\n            root = gfg.fromstring(xml_read.read())\n            nombre = root.find(\"nombre\").text\n            edad = root.find(\"edad\").text\n            birth = root.find(\"fecha_nacimiento\").text\n            lenguajes = []\n            for language in root.find(\"lenguajes\"):\n                lenguajes.append(language.text)\n            datos  = {\"name\": nombre, \"age\": edad, \"birth\": birth, \"languages\": lenguajes}\n\n        else:\n             with open(file,\"r\") as new_json:\n                json_string = new_json.read()\n                json_object = json.loads(json_string)\n                datos  = {\"name\": json_object[\"nombre\"], \"age\": json_object[\"edad\"], \"birth\": json_object[\"fecha_nacimiento\"], \"languages\": json_object[\"lenguajes\"]}\n        return datos\n    \n    def __str__(self) -> str:\n        part1 = \"Nombre:\" + self.name + \" Edad:\" + self.age + \" Fecha Nacimiento:\" + self.birth + \"\\n\" + \"Lenguages\"\n        part2 = \"\"\n        for leng in self.languages:\n            part2 = part2 + \",\" + leng \n        return part1 + part2\n\ntry:\n    print(\"File xml\")\n    person1 = Persona(\"newxml.xml\")\n    print(str(person1))\n    print(\"File json\")\n    person2 = Persona(\"newjson.json\")\n    print(str(person2))\nexcept Exception as ex:\n    print(\"File not support or  format not correct\")\n\nos.remove(\"newxml.xml\")\nos.remove(\"newjson.json\")\n\n\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/juanchernandezdev.py",
    "content": "### JSON, XML Files ###\nimport json\nimport xml.etree.ElementTree as xml\nimport os\n\ninfo = {\n  'name': 'Mark Doe',\n  'age': 38,\n  'birth_date': '15/18/1965',\n  'languages': ['python', 'javascript', 'java']\n  \n}\n\n#* JSON\nfilename_json = 'myjson.json'\n\nwith open(filename_json, 'w') as json_file:\n  json.dump(info, json_file, indent=2)\n  \nwith open(filename_json, 'r') as json_file:\n  print(json_file.read())\n  \n#* XML\nfilename_xml = 'myxml.xml'\n\nroot = xml.Element('info')\n\nfor key,value in info.items():\n  child = xml.SubElement(root, key)\n  if isinstance(value, list):\n    for item in value:\n      xml.SubElement(child, 'item').text = item\n  else:\n    child.text = str(value)\n\ntree = xml.ElementTree(root)\ntree.write(filename_xml)\n\nwith open(filename_xml, 'r') as xml_file:\n  print(xml_file.read())\n  \n#! Optional Challenge\n\nclass Data:\n  def __init__(self, name, age, birth_date, languages) -> None:\n    self.name = name\n    self.age = age\n    self.birth_date = birth_date\n    self.languages = languages\n    \nwith open(filename_xml, 'r') as xml_file:\n  root = xml.fromstring(xml_file.read())\n  name = root.find('name').text\n  age = root.find('age').text\n  birth_date = root.find('birth_date').text\n  languages = []\n  for item in root.find('languages'):\n    languages.append(item.text)\n    \n  my_data = Data(name, age, birth_date, languages)\n  print(my_data.__dict__)\n    \n    \nwith open(filename_json, 'r') as json_file:\n  info = json.load(json_file)\n  my_info = Data(info['name'], info['age'], info['birth_date'], info['languages'])\n  print(my_info.__dict__)\n  \nos.remove(filename_xml)\nos.remove(filename_json)\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/juandaherrera.py",
    "content": "\"\"\"\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n * \n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n\"\"\"\n\nimport json\nimport logging\nimport os\nimport xml.etree.ElementTree as ET\n\nlogging.basicConfig(level=logging.INFO)\n\nfile_name = 'juandaherrera'\n\ndata = {\n    'name': 'Juan David Herrera',\n    'age': '24',\n    'birth_date': '1999-12-05',\n    'programming_languages': ['python', 'javascript', 'visual basic', 'bash', 'html', 'css'],\n}\n\n# Json\nwith open(f'{file_name}.json', 'w') as file:\n    logging.info('Guardando archivo como .json')\n    json.dump(data, file)\n\n# XML\nroot = ET.Element('person')\n\nET.SubElement(root, 'name').text = data['name']\nET.SubElement(root, 'age').text = data['age']\nET.SubElement(root, 'birth_date').text = data['birth_date']\n\nprogramming_languages = ET.SubElement(root, 'programming_languages')\nfor lang in data['programming_languages']:\n    ET.SubElement(programming_languages, 'language').text = lang\n\n# Crear el árbol de ElementTree y escribirlo a un archivo XML\ntree = ET.ElementTree(root)\nwith open(f'{file_name}.xml', 'wb') as archivo:\n    logging.info('Guardando archivo como .xml')\n    tree.write(archivo, encoding='utf-8', xml_declaration=True)\n\n\nlogging.info('Leyendo archivos')\nwith open(f'{file_name}.json', 'r') as file:\n    json_data = json.load(file)\n\ntree = ET.parse(f'{file_name}.xml')\nroot = tree.getroot()\n\nprint('-' * 15, 'JSON', '-' * 15)\nprint(json_data)\nprint('-' * 15, 'XML', '-' * 15)\nprint(root)\nprint('-' * 40)\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu \n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n\"\"\"\nfrom abc import ABC, abstractmethod\n\n\nclass FileReader(ABC):\n\n    @abstractmethod\n    def read() -> list[dict] | dict:\n        pass\n\n\nclass JsonReader(FileReader):\n\n    @staticmethod\n    def read(file_path: str) -> list[dict] | dict:\n        with open(file_path, 'r') as file:\n            data = json.load(file)\n        return data\n\n\nclass XmlReader(FileReader):\n\n    @staticmethod\n    def xml_to_dict(element):\n        \"\"\"Convierte un elemento XML y sus hijos en un diccionario de Python.\"\"\"\n        if not list(element):\n            return element.text\n        dicc = {}\n        for child in element:\n            if len(element.findall(child.tag)) > 1:\n                if child.tag not in dicc:\n                    dicc[child.tag] = []\n                dicc[child.tag].append(XmlReader.xml_to_dict(child))\n            else:\n                dicc[child.tag] = XmlReader.xml_to_dict(child)\n        return dicc\n\n    @staticmethod\n    def read(file_path: str) -> dict:\n        tree = ET.parse(file_path)\n        root = tree.getroot()\n        return XmlReader.xml_to_dict(root)\n\n\nclass Person:\n    name = None\n    age = None\n    birth_date = None\n    lenguages = None\n\n    def __init__(self, file_path: str = None) -> None:\n        self.file_path = file_path\n\n    def __str__(self) -> str:\n        return f'{self.name = }, {self.age = }, {self.birth_date = }, {self.lenguages = }'\n\n    def file_type(self) -> str:\n        return os.path.splitext(self.file_path)[1]\n\n    def read_file(self, reader: FileReader) -> list[dict] | dict:\n        return reader.read(self.file_path)\n\n    def read_and_load_file(self, reader: FileReader) -> None:\n        data = self.read_file(reader)\n        self.name = data.get('name', None)\n        self.age = data.get('age', None)\n        self.birth_date = data.get('birth_date', None)\n        self.lenguages = data.get('programming_languages', None)\n\n\njson_person = Person('juandaherrera.json')\nprint(json_person)\njson_person.read_and_load_file(JsonReader)\nprint(json_person)\n\nprint('-' * 25, 'XML', '-' * 25)\n\nxml_person = Person('juandaherrera.xml')\nprint(xml_person)\nxml_person.read_and_load_file(XmlReader)\nprint(xml_person)\n\nif os.path.exists(f'{file_name}.json'):\n    os.remove(f'{file_name}.json')\n\nif os.path.exists(f'{file_name}.xml'):\n    os.remove(f'{file_name}.xml')\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/juanmax2.py",
    "content": "import xml.etree.ElementTree as xml\nimport os\nimport json\nxml_file = \"juanma.xml\"\n\ndata = {\n    \"name\" : \"Juanma\",\n    \"edad\" : 32,\n    \"fecha_nacimiento\" : \"13-11-1992\",\n    \"lenguajes_programacion\" : [\"Python\", \"HTML\"]      \n    \n}\n# XML\n\ndef save_xml():\n    \n    root = xml.Element(\"data\")\n    \n    for key, value in data.items():\n        child = xml.SubElement(root, key)\n        if isinstance(value, list):\n            for item in value:\n                xml.SubElement(child, \"item\").text = item\n        else:\n            child.text = str(value)\n    \n    tree = xml.ElementTree(root)\n    tree.write(xml_file)\n    \nsave_xml()\n\nwith open(xml_file, \"r\") as xml_data:\n    print(xml_data.read())\n\nos.remove(xml_file)\n\n# JSON\n\njson_file = \"juanma.json\"\ndef save_json():\n    with open(json_file, \"w\") as json_data:\n        json.dump(data, json_data)\nsave_json()\n\nwith open(json_file, \"r\") as json_data:\n    print(json_data.read())\nos.remove(json_file)\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu \n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n\"\"\"\nsave_xml()\nsave_json()\n\nclass Data:\n    \n    def __init__(self, name, edad, fecha_nacimiento, lenguajes_programacion : list):\n        self.name = name\n        self.edad = edad\n        self.fecha_nacimiento = fecha_nacimiento\n        self.lenguajes_programacion = lenguajes_programacion\n\nwith open(xml_file, \"r\") as xml_data:\n    \n    root = xml.fromstring(xml_data.read())\n    name = root.find(\"name\").text\n    edad = root.find(\"edad\").text\n    fecha_nacimiento = root.find(\"fecha_nacimiento\").text\n    lenguajes_programacion = []\n    for item in root.find(\"lenguajes_programacion\"):\n        lenguajes_programacion.append(item.text)\n        \n    data_from_xml = Data(name, edad, fecha_nacimiento, lenguajes_programacion)\n    print(data_from_xml.__dict__)\n    \nwith open(json_file, \"r\") as json_data:\n    json_dict = json.load(json_data)\n    json_class = Data(json_dict[\"name\"], json_dict[\"edad\"], json_dict[\"fecha_nacimiento\"], json_dict[\"lenguajes_programacion\"])\n    print(json_class.__dict__)\n\nos.remove(xml_file)\nos.remove(json_file)"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/juserdev.py",
    "content": "\"\"\" /*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n * \n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu \n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n */ \"\"\"\n\nimport json\nimport os\nimport xml.etree.ElementTree as xml # este es un modulo que permite manejar xml de manera mas simple\n\nxml_file = \"juserdev.xml\"\njson_path = \"./data.json\"\n\ndata = {\n  \"name\": \"Juan\",\n  \"age\": 34,\n  \"birth_date\": \"09-03-1991\",\n  \"lenguages\": [\"Python\", \"TypeScript\"]\n}\n\n# XML\n\ndef save_xml():\n  root = xml.Element(\"data\")\n\n  for key, value in data.items():\n    child = xml.SubElement(root, key)\n    if isinstance(value, list):\n      for item in value:\n        xml.SubElement(child, \"item\").text = item\n\n    else:\n      child.text = str(value)\n\n  tree = xml.ElementTree(root)\n  tree.write(xml_file)\n\nsave_xml()\n  \nwith open(xml_file) as xml_data:\n  print(xml_data.read())\n\n# os.remove(xml_file)\n\n# JSON\n\ndef create_data():\n  with open(json_path, \"w\") as file:\n    json.dump(data, file, indent=2)\n    print(\"Documento creado correctamente\\n\")\n  \n\ncreate_data()\n\nwith open(json_path, \"r\") as file:\n  print(file.read())\n\n# os.remove(json_path)\n\n### EXTRA ###\n\nclass Data:\n  def __init__(self, name: str, age: int,birth_date: str, lenguages: list):\n    self.name = name\n    self.age = age\n    self.birth_date = birth_date\n    self.lenguages = lenguages\n\nwith open(xml_file, \"r\") as xml_data:\n  root = xml.fromstring(xml_data.read())\n  name = root.find(\"name\").text\n  age = root.find(\"age\").text\n  birth_date = root.find(\"birth_date\").text\n  lenguages = []\n  for item in root.find(\"lenguages\"):\n    lenguages.append(item.text)\n\ndata_from_xml = Data(name,age, birth_date, lenguages)\nprint(data_from_xml.__dict__) # de esta manera lo imprime en formato diccionario\n\n\nwith open(json_path, \"r\") as json_data:\n  data = json.load(json_data) # importante tener en cuenta que de esta manera si imprime un dict\n  data_from_json = Data(\n    data[\"name\"], \n    data[\"age\"], \n    data[\"birth_date\"],\n    data[\"lenguages\"]\n    )\n  \n  print(data_from_json.__dict__)\n\nos.remove(json_path)\nos.remove(xml_file)\n\n'''\n  Para este ejercicio creamos el archivo.xml y el archivo.json\n  luego creamos una clase con la estructura del json o el xml\n  \n      class Data:\n      def __init__(self, name: str, age: int,birth_date: str, lenguages: list):\n        self.name = name\n        self.age = age\n        self.birth_date = birth_date\n        self.lenguages = lenguages\n    \n  luego abrimos el archivo en modo lectura y lo leemos\n  ya en este punto podemos crear las variables con los datos que se ajustan a la estructura\n  y luego creamos el objeto con la clase Data()\n\n  al momento de imprimir el objeto print(data_from_xml.__dict__)\n  usamos data_from_xml.__dict__ para imprimir en formato diccionario\n\n  para trabajar con json es mas facil y rapido que con un archivo xml ya que su lectura es mucho mas simple \n  y requiere menos pasos para acceder a su imformacion\n  con el simple hecho de abrir el documento en modo lectura y dale estructura con el metodo json.load()\n  podemos conseguir leer los datos\n  posteriormente podemos crear directamente la clase sin pasos añadidos en la clase\n'''"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/kenysdev.py",
    "content": "# ╔═════════════════════════════════════╗\n# ║ Autor:  Kenys Alvarado              ║\n# ║ GitHub: https://github.com/Kenysdev ║\n# ║ 2024 -  Python                      ║\n# ╚═════════════════════════════════════╝\n\n# -----------------------------------\n# * JSON Y XML\n# -----------------------------------\n# - son formatos de intercambio de datos que estructuran información.\n# - JSON (JavaScript Object Notation) y XML (eXtensible Markup Language)\n\nimport os\nimport ast\nimport json\nimport xml.dom.minidom\n\n#____________________________________\n# * JSON\ndict_user = {\n    \"name\": \"Ken\",\n    \"age\": 121,\n    \"dob\": \"1903-03-19\",\n    \"prog_langs\": [\"cs\", \"py\", \"vb\", \"rs\", \"js\"]\n}\n\n# _______________\n# Serialización: el proceso de convertir un objeto a una \n# cadena de caracteres en formato JSON.\njson_user = json.dumps(dict_user)\n# {\"name\": \"Ken\", \"age\": 121, \"dob\": \"1903-03-19\", ....}\n\n# Con indentación.\njson_user = json.dumps(dict_user, indent=4)\n\n# Crear fichero\nwith open(\"user.json\", 'w') as file:\n    json.dump(dict_user, file, indent=4)\n\n# _______________\n# Deserialización: convertir una cadena de caracteres JSON a un objeto.\nwith open(\"user.json\", 'r') as file:\n    data = json.load(file)\nprint(\"Objeto cargado\\n\", data, \"\\n\")\n\nformat_json = json.dumps(data, indent=4)\nprint(\"Objeto a formato json\\n\",format_json, \"\\n\")\n\n#____________________________________\n# * XML\n\n# Serialización\ndoc = xml.dom.minidom.Document()\nroot = doc.createElement(\"user\")\ndoc.appendChild(root)\n\nfor key, value in dict_user.items():\n    elem = doc.createElement(key)\n    text = doc.createTextNode(str(value))\n    elem.appendChild(text)\n    root.appendChild(elem)\n\n# Guardar\nwith open(\"user.xml\", \"w\") as f:\n    f.write(doc.toprettyxml())\n\n# _______________\n# cargar\nwith open(\"user.xml\", \"r\") as f:\n    xml_content = f.read()\n    print(\"Cargar documento\\n\", xml_content, \"\\n\")\n\n# cargar un elemento especifico.\ndoc = xml.dom.minidom.parse(\"user.xml\")\nage_value = doc.getElementsByTagName(\"age\")[0]\nage = age_value.firstChild.data\nprint(\"Edad: \", age)\n\n#____________________________________\n# EJERCICIO\n\"\"\"\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu \n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n\"\"\"\n\nclass Xml_or_json:\n    def __init__(self, path):\n        file_name, file_extension = os.path.splitext(path)\n        self.path = path\n        self.extension = file_extension.lower()\n        self.dic_user = {}\n\n    def as_dict(self) -> list:\n        try:\n            if self.extension == \".json\":\n                with open(self.path, 'r') as file:\n                    self.dic_user = json.load(file)\n                    print(\"Archivo .json cargado\")\n                    return self.dic_user\n\n            elif self.extension == \".xml\":\n                def _get_value(key: str) -> str:\n                    doc = xml.dom.minidom.parse(self.path)\n                    value = doc.getElementsByTagName(key)[0]\n                    value_str = value.firstChild.data\n                    return value_str\n\n                self.dic_user[\"name\"] = _get_value(\"name\")\n                self.dic_user[\"age\"] = int(_get_value(\"age\"))\n                self.dic_user[\"dob\"] = _get_value(\"dob\")\n                self.dic_user[\"prog_langs\"] = ast.literal_eval(_get_value(\"prog_langs\"))\n\n                print(\"Archivo .xml cargado\")\n                return self.dic_user\n                \n            else:\n                print(\"Archivo no compatible.\")\n\n        except Exception as ex:\n            print(\"Error -> \", ex)\n\nprint(\"\\nEJERCICIO\\n\")\n#__________\nfile = Xml_or_json(\"user.json\")\ndic_user: dict = file.as_dict()\nprint(dic_user)\n#__________\nfile = Xml_or_json(\"user.xml\")\ndic_user: dict = file.as_dict()\nprint(dic_user)\n\n# eliminar\nos.remove(\"user.xml\")\nos.remove(\"user.json\")\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/m1l0j05.py",
    "content": "## Ejercicio\nimport os\nimport json\nimport xml.etree.ElementTree as xml\n\ndata = {\n    'name' : 'Nombre Apellido',\n    'age' : 24,\n    'birth_date' : '01/01/2000',\n    'programming_languages' : [\n        'Python',\n        'JavaScript',\n        'Bash'\n    ]\n}\n\nxml_file = 'ejercicio.xml'\njson_file = 'ejercicio.json'\n\ndef xml_create(data, file):\n    print('[+] Iniciando creacion de archivo xml')\n    \n    # Creamos el elemento raíz\n    print('[+] Creando elemento raiz')\n    root = xml.Element('person')\n\n    # Para cada clave y valor en el diccionario data\n    for key, value in data.items():\n        # Creamos un elemento hijo con el nombre de la clave y el valor como su texto\n        print('[+] Creando elemento hijo')\n        child = xml.SubElement(root, key)\n\n        # Si el valor es una lista, creamos elementos para cada elemento de la lista\n        if isinstance(value, list):\n            for item in value:\n                print('[+] Creando subelemento hijo')\n                subelement = xml.SubElement(child, 'language')\n                subelement.text = item\n        else:\n            child.text = str(value)  # Convertimos el valor a cadena si es necesario\n    \n    # Creamos un objeto ElementTree con el elemento raíz\n    print('[+] Creando arbol de elmentos')\n    tree = xml.ElementTree(root)\n\n    # Escribimos el contenido del ElementTree en un archivo XML\n    print('[+] Creando archivo con los elementos del arbol')\n    tree.write(file)\n    \n    with open(file, 'r') as f:\n        print('[+] Leyendo e imprimiendo archivo creado')\n        print(f.read())\n\n    #print('[+] Borrando archivo creado')\n    #os.remove(file)\n\ndef json_create(data :dict, file :str):\n    print('\\n[+] Iniciando creacion de archivo json')\n\n    print('[+] Creando archivo json')\n    with open(file, 'w') as f:\n        json.dump(data, f,  indent=4)\n    \n    print('[+] Leyendo e imprimiendo archivo json')\n    with open(file, 'r') as f:\n        print(json.load(f))\n    \n    #print('[+] Borrando archivo json')\n    #os.remove(file)\n\nxml_create(data=data, file=xml_file)\njson_create(data=data, file=json_file)\n\n\n# Extra\n\nclass Datos:\n    def __init__(self):\n        self.name = None\n        self.age = None\n        self.birth_date = None\n        self.programming_languages = []\n\n    def cargar_desde_xml(self, archivo):\n        tree = xml.parse(archivo)\n        root = tree.getroot()\n        \n        self.name = root.find('name').text\n        self.age = int(root.find('age').text)\n        self.birth_date = root.find('birth_date').text\n        \n        languages = root.find('programming_languages')\n        if languages:\n            self.programming_languages = [language.text for language in languages.findall('language')]\n\n    def cargar_desde_json(self, archivo):\n        with open(archivo, 'r') as f:\n            data = json.load(f)\n            self.name = data['name']\n            self.age = data['age']\n            self.birth_date = data['birth_date']\n            self.programming_languages = data['programming_languages']\n\n# Crear instancia de la clase Datos\ndatos = Datos()\n\n# Cargar datos desde el archivo XML y JSON\ndatos.cargar_desde_xml(xml_file)\ndatos.cargar_desde_json(json_file)\n\n# Imprimir los datos cargados\nprint('\\n[+] Datos cargados desde el archivo:')\nprint('[+] Nombre:', datos.name)\nprint('[+] Edad:', datos.age)\nprint('[+] Fecha de nacimiento:', datos.birth_date)\nprint('[+] Lenguajes de programación:', datos.programming_languages)\n\n# Borrar los archivos XML y JSON\nos.remove(xml_file)\nos.remove(json_file)\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/mhayhem.py",
    "content": "# EJERCICIO:\n# Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n# siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n# - Nombre\n# - Edad\n# - Fecha de nacimiento\n# - Listado de lenguajes de programación\n# Muestra el contenido de los archivos.\n# Borra los archivos.\n\nimport os\nimport json\nimport xml.etree.ElementTree as et\n\ndef create_info() -> dict:\n    name = input(\"Intriduzca su nombre: \\n\").capitalize()\n    age = int(input(\"Introduzca su edad : \\n\"))\n    birth_date = input(\"Introduzca su fecha de nacimiento (dd/mm/aaaa): \\n\")\n    programing_languages = input(\"Introduzca sus lenguajes de programación (separados por comas): \\n\").split(\", \")\n    personal_info = {\n        \"nombre\": name,\n        \"edad\": age,\n        \"fecha_de_nacimiento\": birth_date,\n        \"lenguajes_de_programacion\": programing_languages,\n        }\n    return personal_info\n\ndef create_json_file_and_remove(data: dict):\n    with open(\"mhayhem.json\", \"w\") as f:\n        json.dump(data, f, indent=4, ensure_ascii=False)\n    with open(\"mhayhem.json\", \"r\", encoding=\"utf-8\") as f:\n        print(f.read())\n        print()\n    \n    #os.remove(\"mhayhem.json\")\n\ndef create_xml_file_and_remove(data: dict):\n    root = et.Element(\"mhayhem\")\n    \n    for key, value in data.items():\n        if isinstance(value, list):\n            child = et.SubElement(root, key)\n            for item in value:\n                et.SubElement(child, \"item\").text = item\n        else:\n            child = et.SubElement(root, key).text = str(value)\n    \n    tree = et.ElementTree(root)\n    tree.write(\"mhayhem.xml\", encoding=\"utf-8\", xml_declaration=True)\n    \n        \n    #os.remove(\"mhayhem.xml\")\n \ncreate_xml_file_and_remove(create_info())\n\n#os.remove(\"mhayhem.xml\")\n\n\n# DIFICULTAD EXTRA (opcional):\n# Utilizando la lógica de creación de los archivos anteriores, crea un\n# programa capaz de leer y transformar en una misma clase custom de tu \n# lenguaje los datos almacenados en el XML y el JSON.\n# Borra los archivos.\nclass DeveloperInfo:\n    def __init__(self, name: str, age: int, birth_date : str, languages: list):\n        self.name = name\n        self.age = age\n        self.birth_date = birth_date\n        self.languages = languages\n    \n    def __repr__(self) -> str:\n        return f\"DeveloperInfo(name={self.name}, age={self.age}, birth_date ={self.birth_date}, lanfuages={self.languages})\"\n    \n\ndef json_to_class(json_file: str):\n    with open(json_file, \"r\", encoding=\"utf-8\") as f:\n        data = json.load(f)\n        return DeveloperInfo(data[\"nombre\"], data[\"edad\"], data[\"fecha_de_nacimiento\"], data[\"lenguajes_de_programacion\"])\n\ndef xml_to_class(xml_file: str):\n    tree = et.parse(xml_file)\n    root = tree.getroot()\n    return DeveloperInfo(\n        root.find(\"nombre\").text,\n        int(root.find(\"edad\").text),\n        root.find(\"fecha_de_nacimiento\").text,\n        [item.text for item in root.find(\"lenguajes_de_programacion\").findall(\"item\")]\n    )\n\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/miguelex.py",
    "content": "import json\nimport xml.etree.ElementTree as ET\nimport xml.dom.minidom\n\ndatos = {\n    'nombre': 'Miguelex',\n    'edad': 48,\n    'fechanacimiento': '1975-09-13',\n    'Lenguajes': ['php', 'javascript', 'python', 'c#', 'java', 'pascal']\n}\n\n# Generar archivo JSON\nwith open('miguelex.json', 'w') as file:\n    json.dump(datos, file, indent=4)\n\n# Mostrar contenido del archivo JSON\nwith open('miguelex.json', 'r') as file:\n    datos_json = file.read()\n    print(\"JSON:\")\n    print(datos_json)\n\n# Generar archivo XML\nroot = ET.Element('root')\nfor key, value in datos.items():\n    if isinstance(value, list):\n        lenguajes = ET.SubElement(root, key)\n        for lenguaje in value:\n            ET.SubElement(lenguajes, 'lenguaje').text = lenguaje\n    else:\n        ET.SubElement(root, key).text = str(value)\n\ntree = ET.ElementTree(root)\n\n# Guardar archivo XML con formato ordenado\nxml_str = ET.tostring(root, encoding='utf-8')\ndom = xml.dom.minidom.parseString(xml_str)\npretty_xml_str = dom.toprettyxml(indent=\"  \")\n\nwith open('miguelex.xml', 'w', encoding='utf-8') as file:\n    file.write(pretty_xml_str)\n\n\n# Mostrar contenido del archivo XML\nwith open('miguelex.xml', 'r') as file:\n    datos_xml = file.read()\n    print(\"XML:\")\n    print(datos_xml)\n\n# Extra\n\nclass Miguelex:\n    def __init__(self, nombre, edad, fecha_nacimiento, lenguajes):\n        self.nombre = nombre\n        self.edad = edad\n        self.fecha_nacimiento = fecha_nacimiento\n        self.lenguajes = lenguajes\n\n    @classmethod\n    def from_json(cls):\n        with open('miguelex.json', 'r') as file:\n            data = json.load(file)\n            return cls(data['nombre'], data['edad'], data['fechanacimiento'], data['Lenguajes'])\n\n    @classmethod\n    def from_xml(cls):\n        tree = ET.parse('miguelex.xml')\n        root = tree.getroot()\n        nombre = root.find('nombre').text\n        edad = int(root.find('edad').text)\n        fecha_nacimiento = root.find('fechanacimiento').text\n        lenguajes = [lenguaje.text for lenguaje in root.find('Lenguajes')]\n        return cls(nombre, edad, fecha_nacimiento, lenguajes)\n\n    def __str__(self):\n        return f\"Nombre: {self.nombre}\\nEdad: {self.edad}\\nFecha de nacimiento: {self.fecha_nacimiento}\\nLenguajes: {', '.join(self.lenguajes)}\"\n\nprint(\"\\n\\nDe JSON a clase:\\n\")\nmiguelex_from_json = Miguelex.from_json()\nprint(miguelex_from_json)\n\nprint(\"\\n\\nDe XML a clase:\\n\")\nmiguelex_from_xml = Miguelex.from_xml()\nprint(miguelex_from_xml)\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/monicavaquerano.py",
    "content": "# 12 JSON Y XML\n# Monica Vaquerano\n# https://monicavaquerano.dev\n\n# IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n\"\"\"\n* EJERCICIO:\n* Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n* siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n* - Nombre\n* - Edad\n* - Fecha de nacimiento\n* - Listado de lenguajes de programación\n* Muestra el contenido de los archivos.\n* Borra los archivos.\n\"\"\"\n# --------------------------------\n# XML (Extensible Markup Language)\n# --------------------------------\n# XML es un lenguaje de marcado que se utiliza para almacenar y transportar datos de forma legible tanto por humanos como por máquinas.\n# Utiliza etiquetas para definir la estructura y el significado de los datos.\n# En Python se puede trabajar con XML utilizando la biblioteca xml.etree.ElementTree.\n\n# --------------------\n# Crear un archivo XML:\n# --------------------\n\nimport os, xml.etree.ElementTree as ET\n\n# Crear el elemento raíz\nroot = ET.Element(\"data\")\n\n# Añadir subelementos\nchild1 = ET.SubElement(root, \"item\")\nchild1.text = \"Contenido del item 1\"\n\nchild2 = ET.SubElement(root, \"item\")\nchild2.text = \"Contenido del item 2\"\n\n# Crear el árbol XML\ntree = ET.ElementTree(root)\n\n# Guardar el árbol en un archivo\ntree.write(\"archivo.xml\")\n\n# --------------------\n# Leer un archivo XML:\n# --------------------\n\n# Parsear el archivo XML\ntree = ET.parse(\"archivo.xml\")\n\n# Obtener el elemento raíz\nroot = tree.getroot()\n\n# Iterar sobre los elementos\nfor child in root:\n    print(child.tag, child.text)\n\n# ----------------------\n# Editar un archivo XML:\n# ----------------------\n\n# Parsear el archivo XML\ntree = ET.parse(\"archivo.xml\")\n\n# Obtener el elemento raíz\nroot = tree.getroot()\n\n# Editar un elemento existente\nroot[0].text = \"Nuevo contenido del item 1\"\n\n# Guardar los cambios\ntree.write(\"archivo.xml\")\n\n# ----------------------\n# Editar un archivo XML:\n# ----------------------\n\n# Eliminar el archivo\nos.remove(\"archivo.xml\")\n\n# ---------------------------------\n# JSON (JavaScript Object Notation)\n# ---------------------------------\n# JSON es un formato de intercambio de datos ligero y fácil de leer que se utiliza ampliamente para transmitir datos estructurados entre un servidor y un cliente.\n# En Python se puede trabajar con JSON utilizando el módulo json.\n\n# ----------------------\n# Crear un archivo JSON:\n# ----------------------\nimport json\n\n# Datos en forma de diccionario\ndata = {\"nombre\": \"Juan\", \"edad\": 30, \"ciudad\": \"Berlin\"}\n\n# Guardar los datos en un archivo JSON\nwith open(\"archivo.json\", \"w\") as f:\n    json.dump(data, f)\n\n# ----------------------\n# Leer un archivo JSON:\n# ----------------------\n\n# Leer datos desde un archivo JSON\nwith open(\"archivo.json\", \"r\") as f:\n    data = json.load(f)\n\n# Imprimir los datos\nprint(data)\n\n# ----------------------\n# Editar un archivo JSON:\n# ----------------------\n\n# Leer datos desde un archivo JSON\nwith open(\"archivo.json\", \"r\") as f:\n    data = json.load(f)\n\n# Modificar los datos\ndata[\"ciudad\"] = \"Stuttgart\"\n\n# Guardar los cambios\nwith open(\"archivo.json\", \"w\") as f:\n    json.dump(data, f)\n\n# -------------------------\n# Formatear los resultados:\n# -------------------------\n# El método json.dumps() tiene parametros que facilitan la lectura de los resultados.\n\n# Aquí usa 4 espacios de indentación para facilitar la lectura:\nprint(\"json.dumps(json.dumps(data, indent=4)) =>\")\nprint(json.dumps(data, indent=4))\n\n# Aquí . y espacio para separar los objetos, y un espacio, un = y un espacio para separar las keys de sus valores.\n# Además de ordenar en orden alfabético las llaves:\nprint(\"json.dumps(data, indent=4, separators=('. ', ' = ')) =>\")\nprint(json.dumps(data, indent=4, separators=(\". \", \" = \"), sort_keys=True))\n\n# -------------------------\n# Eliminar un archivo JSON:\n# -------------------------\n\n# Eliminar el archivo\nos.remove(\"archivo.json\")\n\n# Es importante manejar adecuadamente los errores y excepciones al trabajar con archivos para garantizar un comportamiento robusto de tu aplicación.\n# -------------------------\n\n\ndef create_XML(name, age, dob, languages_list):\n    # Create root element\n    root = ET.Element(\"info\")\n\n    # Add subelements\n    name_se = ET.SubElement(root, \"name\")\n    name_se.text = name\n\n    age_se = ET.SubElement(root, \"age\")\n    age_se.text = age\n\n    dob_se = ET.SubElement(root, \"date_of_birth\")\n    dob_se.text = dob\n\n    languages_list_se = ET.SubElement(root, \"programming_languages_list\")\n    languages_list_se.text = languages_list\n\n    # Create the XML tree\n    tree = ET.ElementTree(root)\n\n    # Save the tree in a file\n    tree.write(\"info.xml\")\n\n\ndef create_JSON(name, age, dob, languages_list):\n    info = {\n        \"name\": name,\n        \"age\": age,\n        \"date of birth\": dob,\n        \"programming languages list\": languages_list,\n    }\n\n    # Saves the data in a JSON file\n    with open(\"info.json\", \"w\") as f:\n        json.dump(info, f)\n\n\ndef read_XML(file):\n    # Parse the XML file\n    tree = ET.parse(file)\n\n    # Get root element\n    root = tree.getroot()\n\n    # Iterate over the elements\n    for child in root:\n        print(child.tag, \"=\", child.text)\n\n\ndef read_JSON(file):\n    # Reads the data from a JSON file\n    with open(file, \"r\") as f:\n        data = json.load(f)\n\n    # Print the data\n    print(json.dumps(data, indent=4))\n\n\ndef eliminate_files(files):\n    for file in files:\n        try:\n            # Eliminates any file\n            os.remove(file)\n        except FileNotFoundError:\n            print(f\"Archivo '{file}' no existe\")\n\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n* Utilizando la lógica de creación de los archivos anteriores, crea un\n* programa capaz de leer y transformar en una misma clase custom de tu \n* lenguaje los datos almacenados en el XML y el JSON.\n* Borra los archivos.\n\"\"\"\n\n\nclass FileCreator:\n    def __init__(self, fname, ext):\n        self.fname = fname\n        self.ext = \".\" + ext\n        self.file = f\"{self.fname}{self.ext}\"\n\n    def input_info(self, name, age, dob, languages_list):\n        self.name, self.age, self.dob, self.languages_list = (\n            name,\n            age,\n            dob,\n            languages_list,\n        )\n        if self.ext == \".json\":\n            info = {\n                \"name\": name,\n                \"age\": age,\n                \"date of birth\": dob,\n                \"programming languages list\": languages_list,\n            }\n            # Saves the data in a JSON file\n            with open(self.file, \"w\") as f:\n                json.dump(info, f)\n        elif self.ext == \".xml\":\n            # Create root element\n            root = ET.Element(\"info\")\n            # Add subelements\n            name_se = ET.SubElement(root, \"name\")\n            name_se.text = self.name\n            age_se = ET.SubElement(root, \"age\")\n            age_se.text = str(self.age)\n            dob_se = ET.SubElement(root, \"date_of_birth\")\n            dob_se.text = self.dob\n            languages_list_se = ET.SubElement(root, \"programming_languages_list\")\n            languages_list_se.text = self.languages_list\n            # Create the XML tree\n            tree = ET.ElementTree(root)\n            # Save the tree in a file\n            tree.write(self.file)\n        else:\n            print(\"Archivo no compatible\")\n\n    def edit_info(self, key, new_value):\n        if self.ext == \".json\":\n            try:\n                # Leer datos desde un archivo JSON\n                with open(self.file, \"r\") as f:\n                    data = json.load(f)\n                # Modificar los datos\n                data[key] = new_value\n                # Guardar los cambios\n                with open(self.file, \"w\") as f:\n                    json.dump(data, f)\n            except FileNotFoundError as e:\n                print(e)\n            except Exception as e:\n                print(e)\n        elif self.ext == \".xml\":\n            try:\n                # Parse XML file\n                tree = ET.parse(self.file)\n                # Get root element\n                root = tree.getroot()\n                # Get key\n                for child in root:\n                    if child.tag == key:\n                        # Edit an existin element\n                        child.text = new_value\n                        break\n                # Guardar los cambios\n                tree.write(self.file)\n            except FileNotFoundError as e:\n                print(e)\n            except Exception as e:\n                print(e)\n        else:\n            print(\"Archivo no compatible\")\n\n    def print_file(self):\n        if self.ext == \".json\":\n            try:\n                # Reads the data from a JSON file\n                with open(self.file, \"r\") as f:\n                    data = json.load(f)\n                # Print the data\n                print(json.dumps(data, indent=4))\n            except FileNotFoundError as e:\n                print(e)\n        elif self.ext == \".xml\":\n            try:\n                # Parse the XML file\n                tree = ET.parse(self.file)\n                # Get root element\n                root = tree.getroot()\n                # Iterate over the elements\n                for child in root:\n                    print(child.tag, \"=\", child.text)\n            except FileNotFoundError as e:\n                print(e)\n        else:\n            print(\"Este archivo no es compatible\")\n\n    def __str__(self) -> str:\n        return self.file\n\n\nwhile True:\n    print(\"\\n--- Ejercicios ---\")\n    choice = input(\"1. Ejercicio\\n2. DIFICULTAD EXTRA (opcional)\\n3. Salir\\n> \")\n    if choice == \"1\":\n        os.system(\"clear\")\n        print(\"--- Creación de un archivo XML y JSON ---\")\n        # Prompt info\n        name = input(\"Ingresa tu nombre: > \").lower().strip()\n        age = input(\"Ingresa tu edad: > \")\n        dob = input(\"Ingresa tu fecha de nacimiento: > \")\n        languages_list = input(\"Ingresa tus lenguajes de programación preferidos: > \")\n        # Create files\n        create_XML(name, age, dob, languages_list)\n        create_JSON(name, age, dob, list(languages_list.split(\", \")))\n        # Read files\n        try:\n            print(\"\\nXML File:\")\n            read_XML(\"info.xml\")\n            print(\"\\nJSON File:\")\n            read_JSON(\"info.json\")\n            # Eliminate files\n            eliminate_files([\"info.xml\", \"info.json\"])\n        except FileNotFoundError as e:\n            print(f\"El archivo no existe: {e}\")\n        except Exception as e:\n            print(f\"Ha ocurrido un error: {e}\")\n\n    elif choice == \"2\":\n        os.system(\"clear\")\n        soyJSON = FileCreator(\"soyJSON\", \"json\")\n        soyJSON.input_info(\"Alice\", 88, \"10/10/88\", \"python, javascript, php\")\n        print(soyJSON)\n        print(\"\\nJSON File:\")\n        soyJSON.print_file()\n        soyJSON.edit_info(\"name\", \"Bob\")\n        print(\"\\nJSON File:\")\n        soyJSON.print_file()\n\n        soyXML = FileCreator(\"soyXML\", \"xml\")\n        soyXML.input_info(\"Charlie\", 88, \"10/10/88\", \"python, javascript, php\")\n        print(soyXML)\n        print(\"\\nXML File:\")\n        soyXML.print_file()\n        soyXML.edit_info(\"name\", \"Dan\")\n        print(\"\\nXML File:\")\n        soyXML.print_file()\n\n        eliminate_files([\"soyJSON.json\", \"soyXML.xml\"])\n    elif choice == \"3\":\n        print(\"\\nAdiós\")\n        break\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/mouredev.py",
    "content": "import os\nimport xml.etree.ElementTree as xml\nimport json\n\ndata = {\n    \"name\": \"Brais Moure\",\n    \"age\": 36,\n    \"birth_date\": \"29-04-1987\",\n    \"programming_languages\": [\"Python\", \"Kotlin\", \"Swift\"]\n}\n\nxml_file = \"mouredev.xml\"\njson_file = \"mouredev.json\"\n\n\"\"\"\nEjercicio\n\"\"\"\n\n# XML\n\n\ndef create_xml():\n\n    root = xml.Element(\"data\")\n\n    for key, value in data.items():\n        child = xml.SubElement(root, key)\n        if isinstance(value, list):\n            for item in value:\n                xml.SubElement(child, \"item\").text = item\n        else:\n            child.text = str(value)\n\n    tree = xml.ElementTree(root)\n    tree.write(xml_file)\n\n\ncreate_xml()\n\nwith open(xml_file, \"r\") as xml_data:\n    print(xml_data.read())\n\nos.remove(xml_file)\n\n# JSON\n\n\ndef create_json():\n    with open(json_file, \"w\") as json_data:\n        json.dump(data, json_data)\n\n\ncreate_json()\n\nwith open(json_file, \"r\") as json_data:\n    print(json_data.read())\n\nos.remove(json_file)\n\n\"\"\"\nExtra\n\"\"\"\n\ncreate_xml()\ncreate_json()\n\n\nclass Data:\n\n    def __init__(self, name, age, birth_date, programming_languages) -> None:\n        self.name = name\n        self.age = age\n        self.birth_date = birth_date\n        self.programming_languages = programming_languages\n\n\nwith open(xml_file, \"r\") as xml_data:\n\n    root = xml.fromstring(xml_data.read())\n    name = root.find(\"name\").text\n    age = root.find(\"age\").text\n    birth_date = root.find(\"birth_date\").text\n    programming_languages = []\n    for item in root.find(\"programming_languages\"):\n        programming_languages.append(item.text)\n\n    xml_class = Data(name, age, birth_date, programming_languages)\n    print(xml_class.__dict__)\n\n\nwith open(json_file, \"r\") as json_data:\n    json_dict = json.load(json_data)\n    json_class = Data(\n        json_dict[\"name\"],\n        json_dict[\"age\"],\n        json_dict[\"birth_date\"],\n        json_dict[\"programming_languages\"]\n    )\n    print(json_class.__dict__)\n\nos.remove(xml_file)\nos.remove(json_file)\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/mrodara.py",
    "content": "#############################  JSON Y XML CON PYTHON  ######################################\n\n\n### TEORÍA MANEJO DE FICHEROS JSON CON PYTHON\n'''\nJSON (JavaScript Object Notation) es un formato de intercambio de datos muy utilizado por su sencillez y legibilidad. \nPython ofrece el módulo estándar json para trabajar con este formato.\n'''\n#import json\n#\n## Creación de un fichero json con datos\n#data = {\n#    \"name\" : \"manu\",\n#    \"age\" : 44,\n#    \"teacher\" : True,\n#    \"subjects\" : [\"PIA\", \"SRI\", \"IAW\"],\n#    \"detail\" : {\n#        \"high_school\" : \"IES Al-Andalus\",\n#        \"year\" : 2024\n#    }\n#}\n#\n#with open(\"data.json\", \"w\", encoding=\"utf-8\") as file:\n#    json.dump(data, file, indent=4, ensure_ascii=False)\n#    \n#print(\"Archivo json generado con éxito\")\n#\n## Leer un fichero json\n#with open(\"data.json\", \"r\", encoding=\"utf-8\") as file:\n#    content = json.load(file)\n#\n#print(type(content))\n#print(content)\n#\n## Añadir una nueva clave al diccionario a partir del contenido descargado\n#content[\"detail\"][\"experience\"] = 7\n#\n#with open(\"data.json\", \"w\", encoding=\"utf-8\") as file:\n#    json.dump(content, file, indent=4, ensure_ascii=False)\n#\n#print(\"Fichero actualizado desde el volcado\")\n#\n#### FIN TEORÍA MANEJO DE FICHEROS JSON CON PYTHON\n#\n#### TEORÍA MANEJO DE FICHEROS XML CON PYTHON\n#'''\n#XML (eXtensible Markup Language) es un formato estructurado y extensible usado principalmente para datos jerárquicos. \n#Python ofrece el módulo xml.etree.ElementTree para trabajar con este formato.\n#'''\n#\n### Crear un archivo xml con python\n#import xml.etree.ElementTree as ET\n#\n## Crear el elemento raíz\n#raiz = ET.Element(\"curso\")\n#\n## Añadir subelementos\n#ET.SubElement(raiz, \"nombre\").text = \"Servicios de Red e Internet\"\n#ET.SubElement(raiz, \"profesor\").text = \"Manuel Jesús Rodríguez Arabi\"\n#ET.SubElement(raiz, \"año\").text = \"2024\"\n#\n## Añadir un subelemento con atributos\n#materias = ET.SubElement(raiz, \"materias\")\n#materias.set(\"tipo\", \"obligatorias\")\n#ET.SubElement(materias, \"materia\").text = \"Python\"\n#ET.SubElement(materias, \"materia\").text = \"IA\"\n#\n## Crear un árbol y guardar el archivo\n#arbol = ET.ElementTree(raiz)\n#arbol.write(\"datos.xml\", encoding=\"utf-8\", xml_declaration=True)\n#\n#print(\"Archivo XML creado con éxito.\")\n#\n## Leer un archivo XML\n#arbol = ET.parse(\"datos.xml\")\n#raiz = arbol.getroot()\n#\n## Recorrer los elementos\n#print(\"Contenido del archivo XML:\")\n#for elem in raiz:\n#    print(f\"{elem.tag}: {elem.text}\")\n#\n## Añadir un nuevo subelemento\n#nuevo_campo = ET.SubElement(raiz, \"duración\")\n#nuevo_campo.text = \"100 horas\"\n#\n## Guardar los cambios\n#arbol.write(\"datos_actualizados.xml\", encoding=\"utf-8\", xml_declaration=True)\n#\n#print(\"Archivo XML actualizado.\")\n\n### FIN TEORÍA MANEJO DE FICHEROS XML CON PYTHON\n\n## EJERCICIO PROPUESTO\nimport json\nimport os\nfrom os.path import exists\n\nif exists(\"user_data.json\"):\n    os.remove(\"user_data.json\")\nif exists(\"user_data.xml\"):\n    os.remove(\"user_data.xml\")\n\nuser_data = {\n    \"name\" : \"Manuel J. Rodríguez\",\n    \"age\" : 44,\n    \"birthday\" : \"03/01/1980\",\n    \"programming-lamgs\" : [\"Python\", \"PHP\", \"C++\", \"Java\"]\n}\n\nwith open(\"user_data.json\", \"w\", encoding=\"utf-8\") as file:\n    json.dump(user_data, file, indent=4, ensure_ascii=False)\n\nprint(f\"Fichero {file.name} creado con éxito!!!\")\n\nprint()\n\nprint(\"Mostrando datos almacenados\")\n\nwith open(\"user_data.json\", \"r\", encoding=\"utf-8\") as file:\n    content = json.load(file)\n\nprint(type(content))\n\nprint(\"Fin del contenido del fichero JSON\")\n\nprint()\n\nprint(\"Inicio de borrado del fichero JSON\")\n#os.remove(\"user_data.json\")\nprint(\"Fichero eliminado con éxito!!!\")\n\nimport xml.etree.ElementTree as ET\n\nroot = ET.Element(\"user_data\")\n\nET.SubElement(root, \"name\").text = \"Manuel J. Rodríguez\"\nET.SubElement(root, \"age\").text = \"44\"\nET.SubElement(root, \"birthdate\").text = \"03/01/1980\"\n\nlanguages = ET.SubElement(root, \"languages\")\nlang1 = ET.SubElement(languages, \"language\")\nlang1.text = \"Python\"\nlang2 = ET.SubElement(languages, \"language\")\nlang2.text = \"PHP\"\nlang3 = ET.SubElement(languages, \"language\")\nlang3.text = \"Java\"\nlang4 = ET.SubElement(languages, \"language\")\nlang4.text = \"C++\"\n\n\ntree = ET.ElementTree(root)\ntree.write(\"user_data.xml\", encoding=\"utf-8\", xml_declaration=True)\n\nprint(\"Archivo XML creado con éxito.\")\nprint()\nprint(\"Lectura del fichero\")\nread_tree = ET.parse(\"user_data.xml\")\nread_root = read_tree.getroot()\n\nfor data in read_root:\n    if data.tag != \"languages\":\n        print(f\"Etiqueta: {data.tag}, texto: {data.text}\")\n    else:\n        for lang in data:\n            print(f\"Etiqueta: {lang.tag}, texto: {lang.text}\")\n\nprint(\"Fin de lectura del fichero\")\nprint()\nprint(\"Borrado del fichero\")\n#os.remove(\"user_data.xml\")\nprint(\"Fichero eliminado con éxito!!!\")\n\n#############################  EJERCICIO EXTRA  ######################################\n\n# Usaremos los ejemplos creados en el anterior ejercicio.\n\njson_to_dict = {}\nxml_to_dict = {}\nusers = []\n\nwith open ('user_data.json', \"r\", encoding=\"utf-8\") as file:\n    json_to_dict = json.load(file) # Devuelve un diccionario\n\nmy_tree = ET.parse(\"user_data.xml\")\nmy_root = my_tree.getroot()\n#xml_to_dict = {data.tag : data.text for data in my_root} #Generamos el diccionario\ni = 1\nfor data in my_tree.getroot():\n    if data.tag != \"languages\":\n        xml_to_dict[data.tag] = data.text\n    else:\n        for lang in data:\n            xml_to_dict[lang.tag + str(i)] = lang.text\n            i += 1\n\nprint(json_to_dict)\nprint()\nprint(xml_to_dict)\nusers.append(json_to_dict)\nusers.append(xml_to_dict)\nprint(users)\nos.remove(\"user_data.json\")\nos.remove(\"user_data.xml\")\n    \n\n#############################  FIN EJERCICIO EXTRA  ######################################\n\n\n\n\n\n\n\n\n############################# FIN JSON Y XML CON PYTHON  ######################################"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/mvidalb.py",
    "content": "import json\nimport os\nimport xml.etree.ElementTree as xml\n\ndata = {\n    \"name\" : \"Mario\",\n    \"age\" : 40,\n    \"birth_date\" : \"01/01/2000\",\n    \"programming_languages\" : [\"Python\", \"C#\"]\n}\n\n# XML\nxml_file = \"mvidalb.xml\"\n\ndef create_xml():\n\n    root = xml.Element(\"data\")\n\n    for key, value in data.items():\n        child = xml.SubElement(root, key)\n        if isinstance(value, list):\n            for item in value:\n                child_child = xml.SubElement(child, \"item\")\n                child_child.text = item\n        else:\n            child.text = str(value)\n\n    tree = xml.ElementTree(root)\n    tree.write(xml_file)\n\ncreate_xml()\n\nwith open(xml_file, \"r\") as xml_data:\n    print(\"XML file:\")\n    print(xml_data.read())\n\nos.remove(xml_file)\n\n\n# JSON\njson_file = \"mvidalb.json\"\n\ndef create_json():\n    with open(json_file, \"w\") as json_data:\n        json.dump(data, json_data)\n\ncreate_json()\n\n# Shift + Alt + F para formatear el archivo a formato JSON!\n\nwith open(json_file, \"r\") as json_data:\n    print(\"JSON file:\")\n    print(json_data.read())\n\nos.remove(json_file)\n\n\n'''\nEjercicio extra\n'''\ncreate_xml()\ncreate_json()\n\nclass Data:\n\n    def __init__(self, name, age, birth_date, programming_languages) -> None:\n        self.name = name\n        self.age = age\n        self.birth_date = birth_date\n        self.programming_languages = programming_languages\n\ndef extract_xml():\n    with open(xml_file, \"r\") as xml_data:\n\n        root = xml.fromstring(xml_data.read())\n        name = root.find(\"name\").text\n        age = root.find(\"age\").text\n        birth_date = root.find(\"birth_date\").text\n        \n        programming_languages = []\n        for item in  root.find(\"programming_languages\"):\n            programming_languages.append(item.text)\n\n        xml_class = Data(name, age, birth_date, programming_languages)\n        print(\"DATA CLASS: XML FILE\")\n        print(xml_class.__dict__)\n\ndef extract_json():\n    with open(json_file, \"r\") as json_data:\n\n        json_dict = json.load(json_data)\n        \n        name = json_dict[\"name\"]\n        age = json_dict[\"age\"]\n        birth_date = json_dict[\"birth_date\"]\n        programming_languages = json_dict[\"programming_languages\"]\n\n        json_class = Data(name, age, birth_date, programming_languages)\n        print(\"DATA CLASS: JSON FILE\")\n        print(json_class.__dict__)\n\nextract_xml()\nextract_json()\n\nos.remove(xml_file)\nos.remove(json_file)\n\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/neslarra.py",
    "content": "\"\"\"\n EJERCICIO:\n Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n - Nombre\n - Edad\n - Fecha de nacimiento\n - Listado de lenguajes de programación\n Muestra el contenido de los archivos.\n Borra los archivos.\n\n DIFICULTAD EXTRA (opcional):\n Utilizando la lógica de creación de los archivos anteriores, crea un\n programa capaz de leer y transformar en una misma clase custom de tu\n lenguaje los datos almacenados en el XML y el JSON.\n Borra los archivos.\n\"\"\"\n\nimport json\nimport csv\nimport os\nimport xml.etree.ElementTree as xml\n\nprint(f\"\\n## Explicación {'#' * 30}\\n\")\n\nprint(\"\"\"\nJSON nos da la posiblidad de tomar un objeto y serializarlo de manera de darle persistencia guardando \nsus propiedades en un fichero de texto:\nEl objeto:\n    mesas = {\"luis_xv\": {\"madera\": \"roble\", \"forma\": \"rectangular\", \"lugares\": 12, \"tamaño\": [1.80, 1.20, 75]},\n             \"rustica\": {\"madera\": \"algarrobo\", \"forma\": \"redonda\", \"lugares\": 8, \"tamaño\": [1.20, 0, 75]},\n             \"de cafe\": {\"madera\": \"cedro\", \"forma\": \"rectangular\", \"lugares\": 0, \"tamaño\": [1.00, 0.50, 40]}}\nLo guardo:\n    with open(\"mesas.json\", \"w\") as fichero:\n        json.dump(mesas, fichero, indent=4, sort_keys=True)\nPara recuperarlo:\n    with open(\"mesas.json\", \"r\") as fichero:\n        mesas_json = json.load(fichero)\nY así tenemos nuestro objeto cargado nuevamente.\n\n\nXML\nEl objeto:\nmesas = [\n        {\"modelo\": \"luis_xv\", \"madera\": \"roble\", \"forma\": \"rectangular\", \"lugares\": 12, \"tamanio\": [1.80, 1.20, 75.0]},\n        {\"modelo\": \"rustica\", \"madera\": \"algarrobo\", \"forma\": \"redonda\", \"lugares\": 8, \"tamanio\": [1.20, 0.0, 75.0]},\n        {\"modelo\": \"de cafe\", \"madera\": \"cedro\", \"forma\": \"rectangular\", \"lugares\": 0, \"tamanio\": [1.00, 0.50, 40.0]}\n        ]\nLo guardo:\nroot = xml.Element(\"mesas\")\nfor item in mesas:\n    for key, value in item.items():\n        child = xml.SubElement(root, key)\n        if isinstance(value, list):\n            tamanio = [\"largo\", \"ancho\", \"alto\"]\n            for list_item, nombre in zip(value, tamanio):\n                xml.SubElement(child, nombre).text = str(list_item)\n        else:\n            child.text = str(value)\n\n    tree = xml.ElementTree(root)\n    xml.indent(tree, '    ')\n    tree.write(\"reto_12_data.xml\")\nPara recuperarlo:\nlista_mesas = []\ndict_ = {}\ntamanio = []\nwith open(\"reto_12_data.xml\", \"r\") as xml_data:\n    root = list(xml.iterparse(xml_data))\n    for item in root:\n        tag = item[1].tag.strip()\n        value = item[1].text.strip()\n        if tag in (\"largo\", \"ancho\", \"alto\"):\n            tamanio.append(float(value))\n        elif tag == \"lugares\":\n            dict_[\"lugares\"] = int(value)\n        elif tag == \"tamanio\":\n            dict_[\"tamanio\"] = tamanio.copy()\n            lista_mesas.append(dict_.copy())\n            dict_.clear()\n            tamanio.clear()\n        elif tag == \"mesas\":\n            continue\n        else:\n            dict_[tag] = value\n\n\nCSV es un formato de fichero cuya particularidad es guardar las tuplas de manera tabular en donde la \",\" separa las\ncolumnas y el salto de línea separa la filas:\nEl objeto:\n    mesas = {\"luis_xv\": {\"madera\": \"roble\", \"forma\": \"rectangular\", \"lugares\": 12, \"tamaño\": [1.80, 1.20, 75]},\n             \"rustica\": {\"madera\": \"algarrobo\", \"forma\": \"redonda\", \"lugares\": 8, \"tamaño\": [1.20, 0, 75]},\n             \"de cafe\": {\"madera\": \"cedro\", \"forma\": \"rectangular\", \"lugares\": 0, \"tamaño\": [1.00, 0.50, 40]}}\nLo guardo:\n    with open(\"mesas.csv\", \"w\", newline=\"\") as fichero:\n        guardar = csv.writer(fichero, delimiter=\",\")\n        guardar.writerow([\"modelo\", \"madera\", \"forma\", \"lugares\", \"tamaño\"])     # headers\n        for modelo, datos in mesas.items():\n            guardar.writerow([modelo, datos[\"madera\"], datos[\"forma\"], datos[\"lugares\"], datos[\"tamaño\"]])\nPara recuperarlo:\n    mesas_csv = {}\n    with open(\"mesas.csv\", \"r\") as fichero_csv:\n        filas = csv.reader(fichero_csv,  delimiter=\",\")\n        for columnas in filas:\n            if filas.line_num == 1:\n                headers = columnas\n                continue\n            mesas_csv[columnas[0]] = {headers[1]: columnas[1], headers[2]: columnas[2], headers[3]: int(columnas[3])}\n            tamanios = []\n            # importante: en el fichero csv la lista \"tamaño\" es una cadena!!! = \"[1.20, 0.50, 6]\" => hay que convertirla a lista de floats.\n            for tamanio in columnas[4][1: -1].split(\",\"):\n                tamanios.append(float(tamanio.strip()))\n            mesas_csv[columnas[0]][headers[4]] = tamanios\n            \n\"\"\")\n\nprint(f\"\\n## Dificultad extra {'#' * 30}\\n\")\n\n\nclass Programadores:\n    programadores = {}\n    tipo_fichero = \"xml\"    # probar con csv, xml o con json\n\n    def __init__(self, nombre: str, edad: int, fecha_nacimiento: str, lenguajes: list):\n        self.nombre = nombre\n        self.edad = edad\n        self.fecha_nacimiento = fecha_nacimiento\n        self.lenguajes = lenguajes\n        if not Programadores.programadores:\n            Programadores.cargar_programadores()\n        self.guardar_programador()\n\n    def __str__(self):\n        return f\"{self.nombre}   /  {self.edad}  /  {self.fecha_nacimiento}  /  {self.lenguajes}\"\n\n    def guardar_programador(self):\n        if not Programadores.existe_programador(self.nombre):\n            Programadores.programadores[self.nombre] = {\"edad\": self.edad, \"fecha_nacimiento\": self.fecha_nacimiento, \"lenguajes\": self.lenguajes}\n        else:\n            self.edad = Programadores.programadores[self.nombre][\"edad\"]\n            self.fecha_nacimiento = Programadores.programadores[self.nombre][\"fecha_nacimiento\"]\n            self.lenguajes = Programadores.programadores[self.nombre][\"lenguajes\"]\n\n    def eliminar_programador(self) -> str:\n        del (Programadores.programadores[self.nombre])\n        return \"\"\n\n    def modificar_programador_edad(self, edad: int):\n        self.edad = edad\n        Programadores.programadores[self.nombre][\"edad\"] = edad\n\n    def modificar_programador_fecha_nacimiento(self, fecha_nacimiento: str):\n        self.fecha_nacimiento = fecha_nacimiento\n        Programadores.programadores[self.nombre][\"fecha_nacimiento\"] = fecha_nacimiento\n\n    def modificar_programador_lenguajes(self, lenguajes: list):\n        self.lenguajes = lenguajes\n        Programadores.programadores[self.nombre][\"lenguajes\"] = lenguajes\n\n    @classmethod\n    def lista_programadores(cls) -> str:\n        cls.cargar_programadores()\n        lista_completa = \"\"\n        if cls.programadores:\n            for nombre, datos in cls.programadores.items():\n                lista_completa += f\"\\nNombre: {nombre} / Edad: {datos['edad']}, / Fecha Nacimiento: {datos['fecha_nacimiento']}\"\n                lenguajes = \"\"\n                if datos['lenguajes']:\n                    for lenguaje in datos['lenguajes']:\n                        lenguajes += lenguaje + \", \"\n                lista_completa += f\"\\n\\tLenguajes: {lenguajes[0:-2]}\"\n        return lista_completa\n\n    @classmethod\n    def existe_programador(cls, nombre: str):\n        return nombre in cls.programadores.keys()\n\n    @classmethod\n    def cargar_programadores(cls):\n        if not cls.programadores:\n            try:\n                if cls.tipo_fichero == \"json\":\n                    with open(\"reto_12_data.json\", \"r\") as fichero:\n                        cls.programadores = json.load(fichero)\n                elif cls.tipo_fichero == \"csv\":\n                    with open(\"reto_12_data.csv\", \"r\") as fichero:\n                        filas = csv.reader(fichero, delimiter=\",\")\n                        for columnas in filas:\n                            if filas.line_num == 1:\n                                headers = columnas\n                                continue\n                            cls.programadores = {columnas[0]: {headers[1]: columnas[1], headers[2]: columnas[2]}}\n                            lenguajes = \"\"\n                            for lenguaje in columnas[3][1:-1].replace(\"'\", \"\").split(\",\"):\n                                lenguajes += lenguaje + \", \"\n                            cls.programadores[columnas[0]][\"lenguajes\"] = lenguajes\n                elif cls.tipo_fichero == \"xml\":\n                    dict_ = {}\n                    lenguajes = []\n                    with open(\"reto_12_data.xml\", \"r\") as xml_data:\n                        root = list(xml.iterparse(xml_data))\n                        for item in root:\n                            tag = item[1].tag.strip()\n                            value = item[1].text.strip()\n                            if tag in (\"largo\", \"ancho\", \"alto\"):\n                                lenguajes.append(float(value))\n                            elif tag == \"lugares\":\n                                dict_[\"lugares\"] = int(value)\n                            elif tag == \"tamanio\":\n                                dict_[\"lenguajes\"] = lenguajes.copy()\n                                cls.programadores = dict_.copy()\n                                dict_.clear()\n                                lenguajes.clear()\n                            elif tag == \"mesas\":\n                                continue\n                            else:\n                                dict_[tag] = value\n                else:\n                    print(f\"Formato {cls.tipo_fichero} no reconocido.\")\n                    quit()\n            except FileNotFoundError:\n                pass\n\n    @classmethod\n    def programadores_to_file(cls):\n        if cls.tipo_fichero == \"json\":\n            with open(\"reto_12_data.json\", \"w\") as fichero:\n                json.dump(cls.programadores, fichero, indent=4, sort_keys=True)\n        elif cls.tipo_fichero == \"csv\":\n            with open(\"reto_12_data.csv\", \"w\", newline=\"\") as fichero:\n                guardar = csv.writer(fichero, delimiter=\",\")\n                guardar.writerow([\"nombre\", \"edad\", \"fecha_nacimiento\", \"lenguajes\"])  # headers\n                for nombre, datos in Programadores.programadores.items():\n                    guardar.writerow([nombre, datos[\"edad\"], datos[\"fecha_nacimiento\"], datos[\"lenguajes\"]])\n        elif cls.tipo_fichero == \"xml\":\n            root = xml.Element(\"programdores\")\n            for key, value in cls.programadores.items():\n                child = xml.SubElement(root, key)\n                if isinstance(value, list):\n                    for list_item in value:\n                        xml.SubElement(child, \"lenguaje\").text = str(list_item)\n                else:\n                    child.text = str(value)\n\n                tree = xml.ElementTree(root)\n                xml.indent(tree, '    ')\n                tree.write(\"reto_12_data.xml\")\n        else:\n            print(f\"Formato {cls.tipo_fichero} no reconocido.\")\n\n\ndef indicar_tipo_fichero() -> str:\n    tipo_fichero = \"\"\n    while tipo_fichero not in (\"json\", \"xml\", \"csv\"):\n        tipo_fichero = input(\"Ingresar el tipo de fichero a probar (json, xml, csv): \").lower()\n    return tipo_fichero\n\n\nProgramadores.tipo_fichero =  indicar_tipo_fichero()\n\nprint(\"\\nCargo programadores\")\nprogi1 = Programadores(\"neslarra\", 59, \"23-marzo-1965\", [\"python\", \"ruby\", \"bash\", \"plsql\", \"sql\", \"awk\", \"java\", \"javascript\"])\nprint(f\"progi1 = {progi1}\")\nprogi2 = Programadores(\"tele tuby\", 12, \"20-marzo-2012\", [\"cobol\", \"BASIC\"])\nprint(f\"progi2 = {progi2}\")\nprogi3 = Programadores(\"tito livio\", 89, \"12-agosto-1934\", [\"kotlin\", \"go\"])\nprint(f\"progi3 = {progi3}\")\nprogi4 = Programadores(\"lola mora\", 40, \"4-febrero-1984\", [\"pascal\", \"cobol\", \"smalltalk\", \"assembler\"])\nprint(f\"progi4 = {progi4}\")\nprint(f\"\\nCantidad de programadores: {Programadores.programadores.__len__()}\")\nprint(f\"\\nLista de programadores: {Programadores.lista_programadores()}\")\n\nprint(\"\\nGuardo las altas en JSON, XML o CSV (según la variable de clase -cambiarla para probar uno u otro-)\")\nProgramadores.programadores_to_file()\n\n_ = input(\"Revisar los ficheros y dar Enter (se van a modificar)!!!\")\n\nprint(\"\\nElimino programador\")\nprogi3 = progi3.eliminar_programador()\nprint(f\"progi3 = {progi3}\")\nprint(f\"\\nCantidad de programadores: {Programadores.programadores.__len__()}\")\nprint(f\"\\nLista de programadores: {Programadores.lista_programadores()}\")\n\nprint(\"\\nModifico programador\")\nprogi1.modificar_programador_fecha_nacimiento(\"20-febrero-2001\")\nprint(f\"progi1 = {progi1}\")\nprogi1.modificar_programador_edad(23)\nprint(f\"progi1 = {progi1}\")\nnueva_lista_lenguajes = progi1.lenguajes\n_ = nueva_lista_lenguajes.pop()\n_ = nueva_lista_lenguajes.pop(0)\nnueva_lista_lenguajes.append(\"a-go-go\")\nprogi1.modificar_programador_lenguajes(nueva_lista_lenguajes)\nprint(f\"progi1 = {progi1}\")\nprint(f\"\\nCantidad de programadores: {Programadores.programadores.__len__()}\")\nprint(f\"\\nLista de programadores: {Programadores.lista_programadores()}\")\n\nprint(\"\\nGuardo los cambios en JSON, XML o CSV (según la variable de clase -cambiarla para probar uno u otro-)\")\nProgramadores.programadores_to_file()\n\n_ = input(\"Revisar los fichero y dar Enter (se van a borrar)!!!\")\n\ntry:\n    os.remove(\"reto_12_data.json\")\nexcept FileNotFoundError as e:\n    pass\nexcept PermissionError as e:\n    print(str(e))\ntry:\n    os.remove(\"reto_12_data.csv\")\nexcept FileNotFoundError as e:\n    pass\nexcept PermissionError as e:\n    print(str(e))\n\ntry:\n    os.remove(\"reto_12_data.xml\")\nexcept FileNotFoundError as e:\n    pass\nexcept PermissionError as e:\n    print(str(e))\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/nlarrea.py",
    "content": "\"\"\"\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n * \n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu \n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n\"\"\"\n\nimport os\nimport json\nimport xml.etree.ElementTree as et\n\n\nMY_DATA = {\n    \"name\": \"Naia\",\n    \"age\": 25,\n    \"bday\": \"1998-07-25\",\n    \"languages\": [\n        \"Python\",\n        \"JavaScript\",\n        \"C++\",\n    ],\n}\n\nXML_FILEPATH = \"nlarrea.xml\"\nJSON_FILEPATH = \"nlarrea.json\"\n\n\ndef write_xml_tags() -> None:\n    root = et.Element(\"data\")\n\n    for k, v in MY_DATA.items():\n        node = et.SubElement(root, k)\n\n        if isinstance(v, list):\n            for item in v:\n                et.SubElement(node, k.rstrip(\"s\")).text = item\n\n        else:\n            node.text = str(v)\n\n    tree = et.ElementTree(root)\n    tree.write(XML_FILEPATH)\n\n\nwrite_xml_tags()\n\nwith open(XML_FILEPATH, \"r\") as json_f:\n    print(json_f.read())\n\n# os.remove(XML_FILEPATH)\n\n\ndef write_json() -> None:\n    with open(JSON_FILEPATH, \"w\") as f:\n        json.dump(MY_DATA, f, indent=4)\n\n\nwrite_json()\n\nwith open(JSON_FILEPATH, \"r\") as json_f:\n    print(json_f.read())\n\n# os.remove(JSON_FILEPATH)\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu \n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n\"\"\"\n\n\nclass Data:\n    def __init__(self, name, age, bday, languages) -> None:\n        self.name = name\n        self.age = age\n        self.bday = bday\n        self.languages = languages\n\n\n# Read from XML file\nwith open(XML_FILEPATH, \"r\") as xml_f:\n    root = et.fromstring(xml_f.read())\n\n    name = root.find(\"name\").text\n    age = root.find(\"age\").text\n    bday = root.find(\"bday\").text\n    languages = []\n    for language in root.find(\"languages\"):\n        languages.append(language.text)\n\n    xml_data = Data(name, age, bday, languages)\n    print(xml_data.__dict__)\n\n\n# Read from json\nwith open(JSON_FILEPATH, \"r\") as json_f:\n    json_dict = json.load(json_f)\n    json_data = Data(**json_dict)\n    print(json_data.__dict__)\n\n\nos.remove(XML_FILEPATH)\nos.remove(JSON_FILEPATH)\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/oniricoh.py",
    "content": "from datetime import datetime as dt\nimport json\nimport os\nimport xml.etree.ElementTree as ET\n\n\n\ndatas = {\n    \"name\": \"Daniel\",\n    \"age\": 34,\n    \"birthdate\": dt(1989, 4, 4).strftime(\"%d/%m/%Y\"),\n    \"languages\": [\"python\", \"html\", \"sql\"],\n}\n\nfile = \"datas.json\"\n\n# Escribir datos en el archivo\nwith open(file, \"w\") as f:\n    json.dump(datas, f)\n\n# Leer datos del archivo\nwith open(file, \"r\") as f:\n    load = json.load(f)\n    print(load)\n\n# Cerrar el archivo antes de intentar eliminarlo\nos.remove(file)\n\n\n\n# Crear el elemento raíz del archivo XML\nroot = ET.Element(\"Informacion\")\n\n# Paso 2: Agregar datos al archivo XML\ninformation = ET.SubElement(root, \"Datos\")\ninformation.set(\"id\", \"1\")\nname = ET.SubElement(information, \"nombre\")\nname.text = datas[\"name\"]\nage = ET.SubElement(information, \"edad\")\nage.text = str(datas[\"age\"])\nbirthday = ET.SubElement(information, \"birthday\")\nbirthday.text = str(datas[\"birthdate\"])\nlanguages = ET.SubElement(information, \"lenguaje\")\nlanguages.text = str(datas[\"languages\"])\n\n# Guardar el árbol en un archivo XML\ntree = ET.ElementTree(root)\ntree.write(\"datas.xml\")\n\n# Paso 3: Leer los datos del archivo XML\ntree = ET.parse(\"datas.xml\")\nroot = tree.getroot()\n\nfor data in root:\n    print(\"ID:\", data.get(\"id\"))\n    print(\"Nombre:\", data.find(\"nombre\").text)\n    print(\"Edad:\", data.find(\"edad\").text)\n    print(\"Cumpleaño:\", data.find(\"birthday\").text)\n    print(\"Lenguajes:\", data.find(\"lenguaje\").text)\n    print()\n    \n# Paso 4: Borrar el archivo XML\nos.remove(\"datas.xml\")\n\n\n\n###############################################################################\n## DIFICULTAD EXTRA\n###############################################################################\nimport json\nimport xml.etree.ElementTree as ET\nimport os\n\nclass Custom:\n    def __init__(self, file) -> None:\n        self.file = file\n\n    def write_json(self, datas):\n        with open(self.file, \"w\") as f:\n            json.dump(datas, f, indent=4)\n\n    def read_json(self):\n        with open(self.file, \"r\") as f:\n            load = json.load(f)\n            print(load)\n\n    def write_xml(self, datas):\n        root = ET.Element(\"Informacion\")\n        information = ET.SubElement(root, \"Datos\")\n\n        information.set(\"id\", \"1\")\n        name = ET.SubElement(information, \"nombre\")\n        name.text = datas[\"name\"]\n        age = ET.SubElement(information, \"edad\")\n        age.text = str(datas[\"edad\"])\n        birth_date = ET.SubElement(information, \"fecha_nacimiento\")\n        birth_date.text = datas[\"fecha_nacimiento\"]\n        languages = ET.SubElement(information, \"lenguajes\")\n        for lang in datas[\"lenguajes\"]:\n            ET.SubElement(languages, \"lenguaje\").text = lang\n\n        tree = ET.ElementTree(root)\n        tree.write(self.file)\n\n    def read_xml(self):\n        tree = ET.parse(self.file)\n        root = tree.getroot()\n        data = {\n            \"name\": root.find(\"Datos/nombre\").text,\n            \"edad\": int(root.find(\"Datos/edad\").text),\n            \"fecha_nacimiento\": root.find(\"Datos/fecha_nacimiento\").text,\n            \"lenguajes\": [lang.text for lang in root.find(\"Datos/lenguajes\")]\n        }\n        print(data)\n\n    def delete_file(self):\n        os.remove(self.file)\n        print(\"\\nArchivos borrados exitosamente.\")\n\n# Ejemplo de uso\ndatos = {\n    \"name\": \"Juan\",\n    \"edad\": 30,\n    \"fecha_nacimiento\": \"1994-05-20\",\n    \"lenguajes\": [\"Python\", \"JavaScript\", \"Java\"]\n}\n\ncustom_instance = Custom(\"datos.xml\")\ncustom_instance.write_xml(datos)\ncustom_instance.read_xml()\ncustom_instance.delete_file()\n\ncustom_instance = Custom(\"datos.json\")\ncustom_instance.write_json(datos)\ncustom_instance.read_json()\ncustom_instance.delete_file()\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/oriaj3.py",
    "content": "\"\"\"\t\n12 - JSON Y XML\nAutor de la solución: Oriaj3\t\nTeoría:\t\nJSON (JavaScript Object Notation) y XML (eXtensible Markup Language) son dos\nformatos de texto utilizados para el intercambio de datos entre aplicaciones.\n\nJSON es un formato ligero y fácil de leer, basado en JavaScript. Se utiliza\ncomúnmente en aplicaciones web y servicios web para enviar y recibir datos.\n\nXML es un formato más complejo y flexible, basado en etiquetas. Se utiliza en\naplicaciones más antiguas y en servicios web SOAP.\n\nEn Python, se pueden leer y escribir datos en formato JSON y XML utilizando\nlas bibliotecas json y xml.etree.ElementTree, respectivamente.\n\"\"\"\nimport json\nimport xml.etree.ElementTree as ET\nimport os\n\n\"\"\"\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n *\n\"\"\"\n\n# Datos\ndatos = {\n    \"nombre\": \"Juan\",\n    \"edad\": 25,\n    \"fecha_nacimiento\": \"01/01/1996\",\n    \"lenguajes\": [\"Python\", \"JavaScript\", \"Java\"]\n}\n\n# Crear archivo JSON\nwith open(\"datos.json\", \"w\") as f:\n    json.dump(datos, f, indent=4) # indent=4 para dar formato\n    \n# Mostrar contenido del archivo JSON\nwith open(\"datos.json\", \"r\") as f:\n    print(f.read())\n\n# Crear archivo XML\nroot = ET.Element(\"datos\")\nfor key, value in datos.items():\n    if isinstance(value, list):\n        subroot = ET.SubElement(root, key)\n        for item in value:\n            ET.SubElement(subroot, \"lenguaje\").text = item\n    else:\n        ET.SubElement(root, key).text = str(value)\ntree = ET.ElementTree(root)\n\ntree.write(\"datos.xml\")\n\n# Mostrar contenido del archivo XML\nwith open(\"datos.xml\", \"r\") as f:\n    print(f.read())\n\n \n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu \n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n\"\"\"\n\nclass Datos():\n    def __init__(self, nombre, edad, fecha_nacimiento, lenguajes) -> None:\n        self.nombre = nombre\n        self.edad = edad\n        self.fecha_nacimiento = fecha_nacimiento\n        self.lenguajes = lenguajes\n\n    def __str__(self) -> str:\n        return f\"Nombre: {self.nombre}, Edad: {self.edad}, Fecha de nacimiento: {self.fecha_nacimiento}, Lenguajes: {self.lenguajes}\"\n    \n    @staticmethod\n    def from_json(json_file):\n        with open(json_file, \"r\") as f:\n            datos = json.load(f)\n        return Datos(datos[\"nombre\"], datos[\"edad\"], datos[\"fecha_nacimiento\"], datos[\"lenguajes\"])\n    \n    @staticmethod\n    def from_xml(xml_file):\n        datos = {}\n        tree = ET.parse(xml_file)\n        root = tree.getroot()\n        for child in root:\n            if child.tag == \"lenguajes\":\n                datos[child.tag] = [lenguaje.text for lenguaje in child]\n            else:\n                datos[child.tag] = child.text\n        return Datos(datos[\"nombre\"], datos[\"edad\"], datos[\"fecha_nacimiento\"], datos[\"lenguajes\"])\n    \n    def to_json(self, json_file):\n        with open(json_file, \"w\") as f:\n            json.dump(self.__dict__, f, indent=4)\n    \n    def to_xml(self, xml_file):\n        root = ET.Element(\"datos\")\n        for key, value in self.__dict__.items():\n            if key == \"lenguajes\":\n                subroot = ET.SubElement(root, key)\n                for item in value:\n                    ET.SubElement(subroot, \"lenguaje\").text = item\n            else:\n                ET.SubElement(root, key).text = str(value)\n        tree = ET.ElementTree(root)\n        tree.write(xml_file)\n        \n# Crear objeto Datos a partir de JSON\ndatos_json = Datos.from_json(\"datos.json\")\nprint(datos_json)\n\n# Crear objeto Datos a partir de XML\ndatos_xml = Datos.from_xml(\"datos.xml\")\nprint(datos_xml)\n\n# Borrar archivos\nos.remove(\"datos.json\")\nos.remove(\"datos.xml\")\nprint(\"Archivos borrados\")\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/pyramsd.py",
    "content": "import xml.etree.ElementTree as ET\nimport os\nimport json\n\nclass ArchivoXML:\n    def __init__(self, path):\n        self.archivo = f'{path}.xml'\n\n    def create_xml(self):\n        root = ET.Element('data')\n\n        nombre = ET.SubElement(root, 'nombre')\n        nombre.text = 'Sergio'\n        edad = ET.SubElement(root,'edad')\n        edad.text = '18'\n        nacimiento = ET.SubElement(root, 'nacimiento')\n        nacimiento.text = '12/07/2005'\n        languages = ET.SubElement(root, 'languages')\n        languages.text = str(['Python', 'Javascript', 'C#', 'C++'])\n\n        tree = ET.ElementTree(root)\n\n        tree.write(self.archivo, encoding=\"utf-8\", xml_declaration=True)\n\n    def showXML(self):\n        tree = ET.parse(self.archivo)\n        root = tree.getroot()\n\n        for i in root:\n            print(f'{i.tag}: {i.text}')\n\n    def remove_xml(self):\n        if os.path.exists(self.archivo):\n            os.remove(self.archivo)\n            print(f\"El archivo '{self.archivo}' ha sido eliminado.\")\n        else:\n            print(f\"El archivo '{self.archivo}' no existe.\")\n\n\nclass ArchivoJSON:\n    def __init__(self, path):\n        self.archivo = f'{path}.json'\n\n    def create_json(self):\n        data = {\n            'nombre': 'Sergio',\n            'edad': 18,\n            'nacimiento': '12/07/2005',\n            'languages': ['Python', 'Javascript', 'C#', 'C++']\n        }\n        with open(self.archivo, \"w\") as json_file:\n            json.dump(data, json_file, indent=4)\n\n    def showjson(self):\n        with open(self.archivo, \"r\") as json_file:\n            data = json.load(json_file)\n        print(json.dumps(data, indent=4))\n\n    def remove_json(self):\n        if os.path.exists(self.archivo):\n            os.remove(self.archivo)\n            print(f'El archivo \"{self.archivo}\" ha sido eliminado.')\n        else:\n            print(f'El archivo \"{self.archivo}\" no existe.')\n\n'''\nEXTRA\n'''\ndef trans_information(nombre, edad, nacimiento, lenguajes):\n    print(f'nombre: {nombre}\\n'\n        f'edad: {edad}\\n'\n        f'nacimiento: {nacimiento}\\n'\n        f'lenguajes: {lenguajes}')\n\n\ndef read_transform_json(path):\n    file_path = f'{path}.json'\n\n    with open(file_path, 'r') as json_file:\n        data = json.load(json_file)\n\n    nombre = data['nombre']\n    edad = data['edad']\n    nacimiento = data['nacimiento']\n    languages = data['languages']\n    trans_information(nombre, edad, nacimiento, languages)\n\n\ndef read_transform_xml(path):\n    file_path = f'{path}.xml'\n    tree = ET.parse(file_path)\n    root = tree.getroot()\n\n    nombre = root.find('nombre').text\n    edad = root.find('edad').text\n    nacimiento = root.find('nacimiento').text\n    language = root.find('languages').text\n    trans_information(nombre, edad, nacimiento, language)\n\nprint('\\nXML')\nnombrefilexml = 'dataXML'\narchivoXML = ArchivoXML(nombrefilexml)\narchivoXML.create_xml()\nprint('\\n**** Transformed values from the XML file ****')\nread_transform_xml(nombrefilexml)\nprint('\\n**** XML File ****')\narchivoXML.showXML()\narchivoXML.remove_xml()\n\nprint('\\nJSON')\nnombrefilejson = 'dataJSON'\narchivoXML = ArchivoJSON(nombrefilejson)\narchivoXML.create_json()\nprint('\\n**** Transformed values from the JSON file ****')\nread_transform_json(nombrefilejson)\nprint('\\n**** JSON File ****')\narchivoXML.showjson()\narchivoXML.remove_json()\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/qwik-zgheib.py",
    "content": "# -- exersice\nclass Data:\n    def __init__(\n        self, name: str, age: int, birth_date: str, programming_languages: list[str]\n    ) -> None:\n        self.name = name\n        self.age = age\n        self.birth_date = birth_date\n        self.programming_languages = programming_languages\n\n\ndata: Data = Data(\n    \"qwik\", 22, \"2002-11-09\", [\"Python\", \"JavaScript\", \"Typescript\", \"go\"]\n)\nfile_name: str = \"data\"\n\n\ndef create_xml(data: Data, file_name: str) -> None:\n    with open(f\"{file_name}.xml\", \"w\") as file:\n        file.write(\n            f\"\"\"<?xml version=\"1.0\"?>\n                <data>\n                    <name>{data.name}</name>\n                    <age>{data.age}</age>\n                    <birth_date>{data.birth_date}</birth_date>\n                    <programming_languages>\n                        <language>{data.programming_languages[0]}</language>\n                        <language>{data.programming_languages[1]}</language>\n                        <language>{data.programming_languages[2]}</language>\n                        <language>{data.programming_languages[3]}</language>\n                    </programming_languages>\n                </data>\"\"\"\n        )\n        print(f\"{file_name}.xml created\")\n\n\ndef create_json(data: Data, file_name: str) -> None:\n    with open(f\"{file_name}.json\", \"w\") as file:\n        file.write(\n            f\"\"\"{{\n                \"name\": \"{data.name}\",\n                \"age\": {data.age},\n                \"birth_date\": \"{data.birth_date}\",\n                \"programming_languages\": [\n                    \"{data.programming_languages[0]}\",\n                    \"{data.programming_languages[1]}\",\n                    \"{data.programming_languages[2]}\",\n                    \"{data.programming_languages[3]}\"\n                ]\n            }}\"\"\"\n        )\n        print(f\"{file_name}.json created\")\n\n\ndef read_file(file_name: str, extension: str) -> None:\n    with open(f\"{file_name}.{extension}\", \"r\") as file:\n        print(file.read())\n\n\ndef delete_file(file_name: str, extension: str) -> None:\n    import os\n\n    os.remove(f\"{file_name}.{extension}\")\n    print(f\"{file_name}.{extension} deleted\")\n\n\ncreate_xml(data, file_name)\nread_file(file_name, \"xml\")\ndelete_file(file_name, \"xml\")\ncreate_json(data, file_name)\nread_file(file_name, \"json\")\ndelete_file(file_name, \"json\")\n\n\n# -- extra challenge\nclass CustomData:\n    def __init__(\n        self, name: str, age: int, birth_date: str, programming_languages: list[str]\n    ) -> None:\n        self.name = name\n        self.age = age\n        self.birth_date = birth_date\n        self.programming_languages = programming_languages\n\n    def __str__(self) -> str:\n        return f\"{self.name} {self.age} {self.birth_date} {self.programming_languages}\"\n\n    @staticmethod\n    def from_xml(file_name: str) -> \"CustomData\":\n        import xml.etree.ElementTree as ET\n\n        tree = ET.parse(f\"{file_name}.xml\")\n        root = tree.getroot()\n\n        name = root.find(\"name\").text\n        age = int(root.find(\"age\").text)\n        birth_date = root.find(\"birth_date\").text\n        programming_languages = [\n            language.text for language in root.find(\"programming_languages\")\n        ]\n\n        return CustomData(name, age, birth_date, programming_languages)\n\n    @staticmethod\n    def from_json(file_name: str) -> \"CustomData\":\n        import json\n\n        with open(f\"{file_name}.json\", \"r\") as file:\n            data = json.load(file)\n\n        return CustomData(\n            data[\"name\"], data[\"age\"], data[\"birth_date\"], data[\"programming_languages\"]\n        )\n\n    def to_xml(self, file_name: str) -> None:\n        with open(f\"{file_name}.xml\", \"w\") as file:\n            file.write(\n                f\"\"\"<?xml version=\"1.0\"?>\n                    <data>\n                        <name>{self.name}</name>\n                        <age>{self.age}</age>\n                        <birth_date>{self.birth_date}</birth_date>\n                        <programming_languages>\n                            <language>{self.programming_languages[0]}</language>\n                            <language>{self.programming_languages[1]}</language>\n                            <language>{self.programming_languages[2]}</language>\n                            <language>{self.programming_languages[3]}</language>\n                        </programming_languages>\n                    </data>\"\"\"\n            )\n            print(f\"{file_name}.xml created\")\n\n    def to_json(self, file_name: str) -> None:\n        with open(f\"{file_name}.json\", \"w\") as file:\n            file.write(\n                f\"\"\"{{\n                    \"name\": \"{self.name}\",\n                    \"age\": {self.age},\n                    \"birth_date\": \"{self.birth_date}\",\n                    \"programming_languages\": [\n                        \"{self.programming_languages[0]}\",\n                        \"{self.programming_languages[1]}\",\n                        \"{self.programming_languages[2]}\",\n                        \"{self.programming_languages[3]}\"\n                    ]\n                }}\"\"\"\n            )\n            print(f\"{file_name}.json created\")\n\n\ncreate_json(data, file_name)\ncustom_data = CustomData.from_json(file_name)\nprint(custom_data)\ncustom_data.to_xml(file_name)\nread_file(file_name, \"xml\")\ndelete_file(file_name, \"xml\")\ncustom_data.to_json(file_name)\nread_file(file_name, \"json\")\ndelete_file(file_name, \"json\")\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/rantamhack.py",
    "content": "'''\n * IMPORTANTE: Solo debes subir el fichero de codigo como parte del ejercicio.\n * \n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programacion\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n'''\n\nimport json\nimport xml.etree.ElementTree as ET\nimport os\n\n# Archivo json\n\nuser = {\n    \"name\": input(str(\"Por favor indica tu nombre: \")),\n    \"nick\": input(str(\"Indica tu nick de usuario: \")),\n    \"age\": input(str(\"Confirma tu edad: \")),\n    \"languages\": [input(str(\"Enumera los lenguajes de programacion que conoces: \" ))]\n}\n\nwith open(\"datos.json\", \"w\") as file:\n    json.dump(user, file)\n    \nwith open(\"datos.json\", \"r\") as file:\n    data = json.load(file)\n    print(data)\n    \nwith open(\"datos.json\", \"r\") as file:\n    data = json.load(file)\n    print(data[\"name\"]) # Para imprimir solo un elemento del archivo (en este caso el nombre)\n    \nif os.path.exists(\"datos.json\"):\n    os.remove(\"datos.json\")\n    print(\"[+] El archivo 'datos.json' ha sido eliminado ....\")\nelse:\n    print(\"[!] El archivo no existe ....\" )\n\n       \n# Archivo XML\n\nroot = ET.Element(\"datos.xml\")\n\nname = ET.SubElement(root, \"Luis\")\nnick = ET.SubElement(root, \"rantamplan\")\nage = ET.SubElement(root, \"88\")\nlanguages = ET.SubElement(root, \"python, bash, java\")\n\ntree = ET.ElementTree(root)\ntree.write(\"datos.xml\")\n\n    \nwith open(\"datos.xml\", \"r\") as file:\n    data = file.read()\n    print(data)\n\n\n\nif os.path.exists(\"datos.xml\"):\n    os.remove(\"datos.xml\")\n    print(\"[+] El archivo 'datos.json' ha sido eliminado ....\")\nelse:\n    print(\"[!] El archivo no existe ....\" )\n\n\n\n'''\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la logica de creacion de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu \n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n'''\n2\nclass Archivos:\n    def __init__(self, file_json, file_xml):\n        self.file_json = file_json\n        self.file_xml = file_xml\n        \ndef create_json():\n    user2 = {\n        \"name\": str(\"Juan\"),\n        \"nick\": str(\"rantamplan\"),\n        \"age\": str(\"61\"),\n        \"languages\": [\"python, bash, java\"]\n    }\n    with open(\"file_json\", \"w\") as file:\n        json.dump(user2, file)\n    \n    with open(\"file_json\", \"r\") as file:\n        data = json.load(file)\n        print(data)\n        \n    os.remove(\"file_json\")\n    print(\"[!] El archivo 'file_json' ha sido eliminado ....\")\n        \n        \ndef create_xml():\n    \n    root = ET.Element(\"file_xml\")\n    \n    name = ET.SubElement(root, \"Luis\")\n    nick = ET.SubElement(root, \"rantam\")\n    age = ET.SubElement(root, \"92\")\n    languages = ET.SubElement(root, \"python, bash, java\")\n\n    tree = ET.ElementTree(root)\n    tree.write(\"file_xml\")\n\n        \n    with open(\"file_xml\", \"r\") as file:\n        data = file.read()\n    print(data)\n    \n    os.remove(\"file_xml\")\n    print(\"[!] El archivo 'file_xml' ha sido eliminado ....\")\n    \n        \n        \ncreate_json()\ncreate_xml()\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/raulG91.py",
    "content": "import json\nimport os\nimport xml.etree.ElementTree as ET\n\n\n#JSON file \ndata = {\n\n    \"nombre\":\"raul\",\n    \"edad\": \"32\",\n    \"fecha_nacimiento\": \"11/09/1991\",\n    \"lenguajes\": [\"Python\",\"Javascript\",\"Abap\"]\n}\n\n#Parse dictionay to JSON\ndata_json = json.dumps(data)\n\npath = os.path.join(os.path.dirname(__file__),\"fichero.json\")\n\nwith open(path,\"w\") as file:\n    file.write(data_json)\n\ndata_file = \"\"\nwith open(path,\"r\") as file:\n    data_file = file.read()\n\n#Parse document into dictionay \ndecoder_info = json.JSONDecoder().decode(s=data_file)\n\n#Remove file\nos.remove(path)\n\n\n#XML \npath_xml = \"\"\n\npath_xml = os.path.join(os.path.dirname(__file__),\"fichero.xml\")\n\n#Create xml\n\nroot = ET.Element(\"data\")\nname = ET.SubElement(root,\"name\")\nname.text = \"Raul\"\nage = ET.SubElement(root,\"age\")\nage.text = \"33\"\nbirthDate = ET.SubElement(root,\"birth_date\")\nbirthDate.text = \"11/0971991\"\nlanguages = ET.SubElement(root,\"languages\")\nitem1 = ET.SubElement(languages,\"item\")\npython = ET.SubElement(item1,\"language\")\npython.text = \"python\"\nitem2 = ET.SubElement(languages,\"item\")\nabap  = ET.SubElement(item2,\"language\")\nabap.text = \"abap\"\nitem3 = ET.SubElement(languages,\"item\")\njavascript = ET.SubElement(item3,\"language\")\njavascript.text = \"javascript\"\n\n#Build xml tree\ntree = ET.ElementTree(root)\n#Write xml tree to file\ntree.write(path_xml,encoding=\"UTF-8\")\n\n#Read XML \n\ntree = ET.parse(source=path_xml)\n\nroot = tree.getroot()\n\n#Iterate over elements\nfor element in root:\n    print(f'{element.tag}: {element.text}')\n\nos.remove(path_xml)\n\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/rayn1er.py",
    "content": "import os\nimport xml.etree.ElementTree as xml\nimport json\n# /*\n#  * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n#  *\n#  * EJERCICIO:\n#  * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n#  * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n#  * - Nombre\n#  * - Edad\n#  * - Fecha de nacimiento\n#  * - Listado de lenguajes de programación\n#  * Muestra el contenido de los archivos.\n#  * Borra los archivos.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Utilizando la lógica de creación de los archivos anteriores, crea un\n#  * programa capaz de leer y transformar en una misma clase custom de tu \n#  * lenguaje los datos almacenados en el XML y el JSON.\n#  * Borra los archivos.\n#  */\n\n\ndata = {\n    'name' : 'rayn1er',\n    'age' : 26,\n    'birth_date' : '05-04-1999',\n    'programming_languages' : ['python','javascript']\n}\n#creando xml \n\ndef save_xml():\n\n    root = xml.Element('data')\n    \n    for key,value in data.items():\n        \n        child = xml.SubElement(root,key)\n        if isinstance(value,list):\n            for item in value:\n                xml.SubElement(child,'item').text = item\n        else:\n            child.text = str(value)\n\n    tree = xml.ElementTree(root)\n    tree.write(\"rayn1er.xml\")\n\nsave_xml()\n\nwith open('rayn1er.xml','r') as xml_data:\n    print(xml_data.read())\n\n# os.remove('rayn1er.xml')\n\n#Json\n\ndef save_json():\n    with open('rayn1er.json','w') as json_data:\n        json.dump(data, json_data)\n\nsave_json()\n\nwith open('rayn1er.json','r') as json_data:\n    print(json_data.read())\n\n# os.remove('rayn1er.json')\n\n#extra \n\nclass Data:\n\n    def __init__(self,name,age,birthday,languages):\n        self.name = name\n        self.age = age\n        self.birthday = birthday\n        self.languages = languages\n\n\nwith open('rayn1er.xml','r') as xml_data:\n    \n    root = xml.fromstring(xml_data.read())\n    name = root.find('name').text\n    age = root.find('age').text\n    birthday = root.find('birth_date').text\n    programming_languages = []\n    for item in root.find(\"programming_languages\"):\n        programming_languages.append(item.text)\n        \n    xml_class = Data(name,age,birthday,programming_languages)\n    print(xml_class.__dict__)\n\n\nwith open('rayn1er.json','r') as json_data:\n\n    json_dict = json.load(json_data)\n    json_class = Data(json_dict['name'],json_dict['age'],json_dict['birth_date'],json_dict['programming_languages'])\n    print(json_class.__dict__)\n\nos.remove('rayn1er.xml')\nos.remove(\"rayn1er.json\")"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/raynerpv2022.py",
    "content": "import xml.etree.ElementTree as ET \nimport os\n\n\n# * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n#  * \n#  * EJERCICIO:\n#  * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n#  * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n#  * - Nombre\n#  * - Edad\n#  * - Fecha de nacimiento\n#  * - Listado de lenguajes de programación\n#  * Muestra el contenido de los archivos.\n#  * Borrarlo despues\n\n# XML\n\nprint(\" ****  XML ****\")\n\npersonal_data = {\n    \"Nombre\":\"resba\", \n    \"Edad\":\"45\",\n    \"Fcha \":\"1.1.79\"\n    ,\"Language\":[\"Python\",\" go\"]\n}\n\nroot  = ET.Element(\"Personal Data\")\n\nfor k,v in personal_data.items():\n\n    item = ET.SubElement(root, k)\n    if isinstance(v,list) :\n        for i in v:\n            l = ET.SubElement(item,\"Language\")\n            l.text = i\n    else:\n        item.text = str(v)\n\n\ntree = ET.ElementTree(root)\ntree.write(\"file.xml\")\n\nwith open(\"file.xml\") as f:\n    print(f.read())\n\n# os.remove(\"file.xml\")\n \n\nprint(\" ****  JSON ****\")\nimport json\npersonal_data = {\"Nombre\":\"resba\", \"Edad\":45,\"Fcha \":\"1.1.79\",\"Language\":\"Python,go\"}\nwith open(\"file.json\",\"w\") as f:\n    json.dump(personal_data,f,ensure_ascii=False, indent=4)\n\nwith open(\"file.json\", \"r\") as f:\n    data = json.load(f)\n\nprint(data)\n# os.remove(\"file.json\")\n\n# EXTRA \n\n\n# * DIFICULTAD EXTRA (opcional):\n#  * Utilizando la lógica de creación de los archivos anteriores, crea un\n#  * programa capaz de leer y transformar en una misma clase custom de tu \n#  * lenguaje los datos almacenados en el XML y el JSON.\n#  * Borra los archivos.\n# #  */\n\nclass DAta :\n    def __init__(self, name, age, cumple, languaje,f) -> None:\n        self.name = name\n        self.age = age \n        self.cumple = cumple\n        self.language = languaje\n        self.modified = False\n        self.file = f\n\n    def read_json_data(self):\n        with open(self.file,\"r\") as f:\n            data = json.load(f)\n         \n\n        self.name = data[\"name\"]\n        self.age = str(int(data[\"age\"])+1)\n        self.cumple = data[\"cumple\"]\n        self.language = data[\"language\"]\n        self.modified= True\n    \n  \n\n    def write_json(self):\n        with open(self.file,\"w\") as f:\n            json.dump(self.get_data_json(),f, ensure_ascii=False, indent=4)\n\n    def get_data_json(self):\n        return   {\n            \"name\":self.name, \n            \"age\":self.age,\n            \"cumple\": self.cumple,\n            \"language\":self.language\n            }\n    \n    def Print_data(self):\n        if self.modified :\n            print(f\"{self.name} ha cumplido annos\")\n        print(self.get_data_json())\n\n    def remove_file(self):\n        os.remove(self.file)\n    \n     \n        \n    \n\nprint(\"Datos del PAciente\")\nprint()\nn= input(\"Nombre :\")\ne = input(\"Edad :\")\nfn = input(\"Fecha nacimiento :\")\nl = input(\"Languages (separados por espacio):\")\nl = l.split()\nfile = \"satochi.json\"\npersonal = DAta(n,e,fn,l, file)\n\npersonal.write_json()\npersonal.read_json_data()\n\npersonal.Print_data()\npersonal.remove_file()\n\n\n\n\n\n    "
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/restevean.py",
    "content": "import xml.etree.ElementTree as ElT\nimport json\nimport os\n\n\n# Sample data for demonstration\nsample_data = {\n    \"Name\": \"Laura Gomez\",\n    \"Age\": 28,\n    \"Date of birth\": \"1995-08-23\",\n    \"Programming languages\": [\"JavaScript\", \"Ruby\", \"Go\"]\n}\n\n# Creating the XML file\nroot_demo = ElT.Element(\"Person\")\nfor key, value in sample_data.items():\n    sanitized_key = key.replace(\" \", \"_\")\n    if isinstance(value, list):\n        subelement = ElT.SubElement(root_demo, sanitized_key)\n        for item in value:\n            ElT.SubElement(subelement, \"Language\").text = item\n    else:\n        ElT.SubElement(root_demo, sanitized_key).text = str(value)\ntree_demo = ElT.ElementTree(root_demo)\ntree_demo.write(\"demo_data.xml\", encoding=\"utf-8\")\n\n# Creating the JSON file\nwith open(\"demo_data.json\", \"w\") as json_file_demo:\n    json.dump(sample_data, json_file_demo, indent=4)\n\n\nclass PersonalData:\n    def __init__(self):\n        self.name = \"\"\n        self.age = 0\n        self.birth_date = \"\"\n        self.programming_languages = []\n\n    def load_from_json(self, file_path):\n        with open(file_path, \"r\") as file:\n            data = json.load(file)\n        self._assign_data(data)\n\n    def load_from_xml(self, file_path):\n        tree = ElT.parse(file_path)\n        root = tree.getroot()\n        data = {child.tag.replace(\"_\", \" \"): child.text for child in root if not list(child)}\n        languages = [elem.text for elem in root.find(\"Programming_languages\")]\n        if languages:\n            # Convert the list to a string to match the expected type\n            data[\"Programming languages\"] = \", \".join(filter(None, languages))\n        self._assign_data(data)\n\n    def _assign_data(self, data):\n        self.name = data.get(\"Name\", \"\")\n        self.age = int(data.get(\"Age\", 0))\n        self.birth_date = data.get(\"Date of birth\", \"\")\n        self.programming_languages = data.get(\"Programming languages\", \"\")\n\n\n# Using the class to load the data from the files\nperson_from_json = PersonalData()\nperson_from_json.load_from_json(\"demo_data.json\")\n\nperson_from_xml = PersonalData()\nperson_from_xml.load_from_xml(\"demo_data.xml\")\n\n# Cleaning up by deleting the files\nos.remove(\"demo_data.xml\")\nos.remove(\"demo_data.json\")\n\nprint(\"Data loaded from JSON:\", vars(person_from_json))\nprint(\"Data loaded from XML:\", vars(person_from_xml))\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/rigo93acosta.py",
    "content": "'''\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n * \n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu \n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n'''\nimport xml.etree.ElementTree as ET\nimport json\nimport os\n\ndata = {\n    \"name\" : 'Rigoberto Acosta',\n    \"age\" : 30,\n    \"birth_date\" : '25-05-1993',\n    \"programming_languages\" : ['Python', 'C++', 'Matlab']\n}\n\n## XML\n\ndef create_xml():\n\n    root = ET.Element('data')\n    \n    for key, value in data.items():\n        child = ET.SubElement(root, key)\n        if isinstance(value, list):\n            for item in value:\n                ET.SubElement(child, 'item').text = item\n        else:\n            child.text = str(value)\n\n    tree = ET.ElementTree(root)\n    tree.write('data.xml')\n\ncreate_xml()\n\ndef read_xml():\n    tree = ET.parse('data.xml')\n    root = tree.getroot()\n\n    data = {}\n    for child in root:\n        if child.tag == 'programming_languages':\n            data[child.tag] = [item.text for item in child]\n        else:\n            data[child.tag] = child.text\n\n    return data\n\nprint(read_xml())\n\nos.remove('data.xml')\n\n## JSON\n\ndef create_json():\n    with open('data.json', 'w') as file:\n        json.dump(data, file)\n\ndef read_json():\n    with open('data.json', 'r') as file:\n        return json.load(file)\n\ncreate_json()\nprint(read_json())\n\nos.remove('data.json')\n\n'''\nExtra\n'''\n\ncreate_xml()\ncreate_json()\n\nclass CustomData:\n    def __init__(self, name, age, birth_date, programming_languages) -> None:\n        self.name = name\n        self.age = age\n        self.birth_date = birth_date\n        self.programming_languages = programming_languages\n\n    def __str__(self):\n        return f'Name: {self.name}\\nAge: {self.age}\\nBirth Date: {self.birth_date}\\nProgramming Languages: {\", \".join(self.programming_languages)}'\n    \n\nwith open('data.xml', 'r') as file:\n\n    print(\"\\nXML\")\n    root = ET.fromstring(file.read())\n    name = root.find('name').text\n    age = int(root.find('age').text)\n    birth_date = root.find('birth_date').text\n    programming_languages = [item.text for item in root.find('programming_languages')]\n\n    custom_data = CustomData(name, age, birth_date, programming_languages)\n\n    print(custom_data)\n\nwith open('data.json', 'r') as file:\n    print(\"\\nJSON\")\n    data = json.load(file)\n    custom_data = CustomData(data['name'], data['age'], data['birth_date'], data['programming_languages'])\n    print(custom_data)"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/roswer13.py",
    "content": "\"\"\"\nIMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n\nEJERCICIO:\nDesarrolla un programa capaz de crear un archivo XML y JSON que guarde los\nsiguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n- Nombre\n- Edad\n- Fecha de nacimiento\n- Listado de lenguajes de programación\nMuestra el contenido de los archivos.\nBorra los archivos.\n\nDIFICULTAD EXTRA (opcional):\nUtilizando la lógica de creación de los archivos anteriores, crea un\nprograma capaz de leer y transformar en una misma clase custom de tu \nlenguaje los datos almacenados en el XML y el JSON.\nBorra los archivos.\n\"\"\"\nfrom abc import ABC, abstractmethod\n\nfile_name = \"roswer13.txt\"\n\nclass Transformation(ABC):\n    @abstractmethod\n    def generate(self) -> str:\n        pass\n\nclass XML(Transformation):\n    def __init__(self, data: dict):\n        self.data = data\n\n    def generate(self) -> str:\n        xml = \"<data>\\n\"\n        for key, value in self.data.items():\n            xml += f\"\\t<{key}>{value}</{key}>\\n\"\n        xml += \"</data>\"\n        return xml\n    \nclass JSON(Transformation):\n    def __init__(self, data: dict):\n        self.data = data\n\n    def generate(self) -> str:\n        import json\n        return json.dumps(self.data)\n    \nclass FileOperation:\n    def __init__(self, file_name: str):\n        self.file_name = file_name\n\n    def write(self, data: Transformation):\n        with open(self.file_name, \"w\") as file:\n            file.write(data.generate())\n\n    def read(self):\n        with open(self.file_name, \"r\") as file:\n            print(file.read())\n\n    def delete(self):\n        import os\n        os.remove(self.file_name)\n\nif __name__ == \"__main__\":\n    try:\n        name = input(\"Nombre: \")\n        age = int(input(\"Edad: \"))\n        birth_date = input(\"Fecha de nacimiento: \")\n        languages = input(\"Listado de lenguajes de programación: \").split(\",\")\n        data = {\n            \"name\": name,\n            \"age\": age,\n            \"birth_date\": birth_date,\n            \"languages\": languages\n        }\n        print(\"-\" * 50)\n        # Write and read XML file.\n        xml = XML(data=data)\n        file = FileOperation(file_name=f\"{file_name}.xml\")\n        file.write(data=xml)\n        file.read()\n        file.delete()\n        print(\"-\" * 50)\n        # Write and read JSON file.\n        json = JSON(data=data)\n        file = FileOperation(file_name=f\"{file_name}.json\")\n        file.write(data=json)\n        file.read()\n        file.delete()\n        print(\"-\" * 50)\n    except ValueError:\n        print(\"Error al ingresar la información.\")"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/santiagobailleres.py",
    "content": "'''EJERCICIO:\nDesarrolla un programa capaz de crear un archivo XML y JSON que guarde los\nsiguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n- Nombre\n- Edad\n- Fecha de nacimiento\n- Listado de lenguajes de programación\nMuestra el contenido de los archivos.\nBorra los archivos.\nDIFICULTAD EXTRA (opcional):\nUtilizando la lógica de creación de los archivos anteriores, crea un\nprograma capaz de leer y transformar en una misma clase custom de tu \nlenguaje los datos almacenados en el XML y el JSON.\nBorra los archivos.'''\n\nimport json\nimport xml.etree.ElementTree as xml\nimport os\n\ndata = {\n    'name': 'Santiago Bailleres',\n    'age': 25,\n    'birth_date': '25-06-1999',\n    'programming_languages': ['Python', 'JavaScript', 'Java']\n}\n\nxml_file = 'santiagobailleres.xml'\njson_file = 'santiagobailleres.json'\n\n# Crear archivo XML\ndef create_xml():\n    root = xml.Element('data') # Crear elemento raíz\n    \n    for key, value in data.items(): # Recorrer diccionario\n        child = xml.SubElement(root, key) # Crear elemento hijo para cada par clave-valor\n        if isinstance(value, list): # isinstance() devuelve True si el objeto es una instancia de la clase especificada\n            for item in value: # Si el valor es una lista, recorrerla\n                xml.SubElement(child, 'item').text = item # Crear un elemento hijo para cada item de la lista\n        else:\n            child.text = str(value) # Si no es una lista, asignar el valor como texto del elemento hijo\n    tree = xml.ElementTree(root) # Crear árbol XML. un arbol XML es un objeto que representa la estructura de un documento XML\n    tree.write(xml_file) # Escribir árbol XML en archivo\n\ncreate_xml()\n\nwith open(xml_file, 'r') as xml_data:\n    print(xml_data.read())\n\nos.remove(xml_file)\n\n# Crear archivo JSON\ndef create_json():\n    with open(json_file, 'w') as json_data:\n        json.dump(data, json_data) # json.dump() escribe un objeto JSON en un archivo\n\ncreate_json()\n\nwith open(json_file, 'r') as json_data:\n    print(json_data.read())\n\nos.remove(json_file)\n\n# la libreria os permite interactuar con el sistema operativo, en este caso se utiliza para borrar los archivos creados\n\n# EXTRA\n\ncreate_json()\ncreate_xml()\n\nclass Data:\n    def __init__(self, name, age, birth_date, programming_languages):\n        self.name = name\n        self.age = age\n        self.birth_date = birth_date\n        self.programming_languages = programming_languages\n\nwith open(xml_file, 'r') as xml_data:\n    root = xml.fromstring(xml_data.read()) # fromstring() convierte una cadena XML en un objeto Element\n    name = root.find('name').text\n    age = int(root.find('age').text)\n    birth_date = root.find('birth_date').text\n    programming_languages = [item.text for item in root.find('programming_languages')] # Recorrer los elementos hijos de la lista y guardar su texto en una lista\n    \n    xml_class = Data(name, age, birth_date, programming_languages) \n    print(xml_class.__dict__) # __dict__ devuelve un diccionario que contiene los atributos de la clase\n\nwith open(json_file, 'r') as json_data:\n    json_class = Data(**json.load(json_data)) # **kwargs desempaqueta el diccionario y pasa sus elementos como argumentos a la clase\n    print(json_class.__dict__)\n\nos.remove(xml_file)\nos.remove(json_file)"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/santyjl44.py",
    "content": "\"\"\"\n/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu\n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n */\n\"\"\"\n\nimport json\nimport os\nimport xml.etree.ElementTree as ET\n\narchivo_json = \"santyjl.json\"\narchivo_xml = \"santyjl.xml\"\n\n#json\nwith open(archivo_json , \"w\" ) as archivo :\n    datos = {\n        \"nombre\" :\"Santiago\" ,\n        \"edad\" :14 ,\n        \"fecha_de_nacimiento\" :\"20/01/2010\" ,\n        \"lenguajes_de_programacion\" : [\"python\" , \"arduino\"]\n        }\n\n    json.dump(datos , archivo) #escribe archivos python y lo combierte a json\n\n#xml\nraiz = ET.Element(\"Datos-Personales\")\n\nnombre = ET.SubElement(raiz , \"nombre\")\nedad = ET.SubElement(raiz , \"edad\")\nfecha_de_nacimiento = ET.SubElement(raiz , \"fecha-de-nacimiento\")\nlenguajes_de_programacion = ET.SubElement(raiz , \"lenguajes\")\n\nnombre.text = \"santiago\"\nedad.text = \"14\"\nfecha_de_nacimiento.text = \"20/01/2010\"\nlenguajes_de_programacion.text = \"python & arduino\"\n\n#creando archivo xml\nxml = ET.ElementTree(raiz)\nxml.write(archivo_xml , encoding=\"UTF-8\" , xml_declaration=True)\n\n#clase para leer archivos xml y json\nclass ManejadorArchivos:\n    def __init__(self, archivo_json, archivo_xml):\n        self.archivo_json = archivo_json\n        self.archivo_xml = archivo_xml\n\n    def leer_json(self):\n        with open(self.archivo_json, \"r\") as archivo:\n            return json.load(archivo)\n\n    def leer_xml(self):\n        parseo = ET.parse(self.archivo_xml)\n        raiz = parseo.getroot()\n        datos = {}\n\n        for dato in raiz:\n            datos[dato.tag] = dato.text\n        return datos\n\n    def eliminar_archivo_json(self):\n        os.remove(self.archivo_json)\n\n    def eliminar_archivo_xml(self):\n        os.remove(self.archivo_xml)\n\n\n# Crear instancia de la clase\nmanejador = ManejadorArchivos(archivo_json=\"santyjl.json\", archivo_xml=\"santyjl.xml\")\ndatos_json = manejador.leer_json()\ndatos_xml = manejador.leer_xml()\nprint(datos_json)\nprint(datos_xml)\n\n# Eliminar archivo JSON\nmanejador.eliminar_archivo_json()\nmanejador.eliminar_archivo_xml()"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/sorubadguy.py",
    "content": "\"\"\"\n*JSON y XML\n\"\"\"\nimport json\nfrom xml.dom.minidom import Element\nimport xml.etree.ElementTree as xml\nfrom os import remove\n\n#!Json\n#?persona es un objeto de python (diccionario)\npersona = {\n    \"nombre\" : \"sorubadguy\",\n    \"edad\" : \"30\",\n    \"f_nac\" : \"27/03/94\",\n    \"leng_progra\" : \"python\"\n}\n\n#?convierto a persona en un JSON\ndef crear_json(persona):\n    with open(\"archivo.json\", \"w\") as j:\n        json.dump(persona, j)\n\n    #?leer y mostrar el archivo.json\n    with open(\"archivo.json\", \"r\") as j:\n        #?Leo el archivo Json\n        objson = json.load(j)\n\n    print(objson)\n    print(type(objson))\n\n    remove(\"archivo.json\")\n\n#!XML\n\ndef crear_xml(persona):\n    pers = xml.Element(\"informacion\")\n    nombre = xml.SubElement(pers, \"nombre\").text = persona[\"nombre\"]\n    edad = xml.SubElement(pers, \"edad\").text = persona[\"edad\"]\n    nacimiento = xml.SubElement(pers, \"fecha_nacimiento\").text = persona[\"f_nac\"]\n    progra = xml.SubElement(pers, \"Lenguaje_programacion\").text = persona[\"leng_progra\"]\n    \n    xml.dump(pers)\n    datos = xml.ElementTree(pers)\n    datos.write(\"persona.xml\")\n    \ncrear_xml(persona)\n\nwith open(\"persona.xml\", \"r\") as datos_xml:\n    print(datos_xml.read())\nremove(\"persona.xml\")\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/sperezsa.py",
    "content": "#12 - JSON Y XML\n\n#  * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n#  * \n#  * EJERCICIO:\n#  * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n#  * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n#  * - Nombre\n#  * - Edad\n#  * - Fecha de nacimiento\n#  * - Listado de lenguajes de programación\n#  * Muestra el contenido de los archivos.\n#  * Borra los archivos.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Utilizando la lógica de creación de los archivos anteriores, crea un\n#  * programa capaz de leer y transformar en una misma clase custom de tu \n#  * lenguaje los datos almacenados en el XML y el JSON.\n#  * Borra los archivos.\n\n\nimport xml.etree.ElementTree as ET\nimport json \nimport os \n\n#XML\nxml_file = \"archivo.xml\"\n\nroot = ET.Element(\"root\")\n\ncampo_texto1 = ET.SubElement(root, \"nombre\")\ncampo_texto1.text = \"Sergio\"\n\ncampo_texto2 = ET.SubElement(root, \"edad\")\ncampo_texto2.text = \"44\"\n\ncampo_texto3 = ET.SubElement(root, \"fx_nacimiento\")\ncampo_texto3.text = \"08/09/1979\"\n\ncampo_lista = ET.SubElement(root, \"lenguajes\")\n\nitem1 = ET.SubElement(campo_lista, \"item\")\nitem1.text = \"Python\"\n\nitem2 = ET.SubElement(campo_lista, \"item\")\nitem2.text = \"Java\"\n\nitem3 = ET.SubElement(campo_lista, \"item\")\nitem3.text = \"JavaScript\"\n\ntree = ET.ElementTree(root)\ntree.write(xml_file)\n\n\nwith open(xml_file, \"r\") as file:\n    print(file.read())\n\nos.remove(xml_file)\n\n#JSON\njson_file = \"archivo.json\"\n\ndatos = {\n    \"nombre\": \"Sergio\",\n    \"edad\": 44,\n    \"fx_nacimiento\": \"08/09/1979\",\n    \"lenguajes\": [\"Python\", \"Java\", \"JavaScript\"]\n    }\n\n\nwith open(json_file, \"w\") as archivo:\n  json.dump(datos, archivo)\n\nwith open(json_file, \"r\") as file:\n    print(file.read())\n\nos.remove(json_file)\n\n\n\"\"\"\nExtra\n\"\"\"\nclass Developer():\n    def __init__(self, nombre, edad, fx_nacimiento, lenguajes) -> None:\n        self.nombre = nombre\n        self.edad =  edad\n        self.fx_nacimiento = fx_nacimiento\n        self.lenguajes = lenguajes\n    \nwith open(json_file, \"r\") as file:\n    dic = json.load(file)\n    json_class = Developer(\n        dic[\"nombre\"],\n        dic[\"edad\"],\n        dic[\"fx_nacimiento\"],\n        dic[\"lenguajes\"]\n    )\n    print(json_class.__dict__)\n        \n\nwith open(xml_file, \"r\") as file:\n    root = ET.fromstring(file.read())\n    nombre = root.find(\"nombre\").text\n    edad = root.find(\"edad\").text\n    fx_nacimiento = root.find(\"fx_nacimiento\").text\n    lenguajes = []\n    for item in root.find(\"lenguajes\"):\n        lenguajes.append(item.text)\n    xml_class = Developer(nombre, edad, fx_nacimiento, lenguajes)\n    print(xml_class.__dict__)\n    \nos.remove(xml_file)\nos.remove(json_file)\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/tito-delpino.py",
    "content": "#  * EJERCICIO:\n#  * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n#  * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n#  * - Nombre\n#  * - Edad\n#  * - Fecha de nacimiento\n#  * - Listado de lenguajes de programación\n#  * Muestra el contenido de los archivos.\n#  * Borra los archivos.\n\nimport xml.etree.ElementTree as ET\nimport json\nimport os\n\n\ndef crear_mostrar_xml():\n    \"\"\"CREAR\"\"\"\n    root = ET.Element(\"persona\")\n    print(f\"Elemento raiz '{root.tag}' creado\")\n\n    # subelementos\n    name = ET.SubElement(root, \"name\")\n    name.text = \"tito\"\n    age = ET.SubElement(root, \"age\")\n    age.text = \"38\"\n    birth_date = ET.SubElement(root, \"birth-date\")\n    birth_date.text = \"26-03-1988\"\n    # lista de lenguajes\n    languages_element = ET.SubElement(root, \"languages\")\n    for lang in programming_languages:\n        lang_element = ET.SubElement(languages_element, \"language\")\n        lang_element.text = lang\n\n    # guardar XML en el archivo\n    tree = ET.ElementTree(root)  # creamos objeto\n    tree.write(\"personaXML.xml\")  # guardamos el archivo\n    print(\"Archivo creado y guardado\")\n\n    \"\"\"MOSTRAR\"\"\"\n    tree = ET.parse(\"personaXML.xml\")  # leer el archivo\n    root = tree.getroot()  # obtener la raíz\n\n    print(\"----Contenido del archivo .xml:\")\n    for child in root:\n        if child.tag == \"languages\":\n            print(f\"{child.tag} :\")\n            for lang in child:\n                print(f\"- {lang.text}\")\n        else:\n            print(f\"{child.tag} : {child.text}\")\n\n\ndef crear_mostrar_json():\n    \"\"\"CREAR\"\"\"\n    # datos\n    persona = {\n        \"name\": \"pepe\",\n        \"age\": 35,\n        \"birth-date\": \"14-07-1995\",\n        \"languages\": programming_languages,\n    }\n\n    \"\"\"GUARDAR\"\"\"\n    with open(\"personaJSON.json\", \"w\") as file:\n        json.dump(persona, file)  # datos del diccionario agregados a un json nuevo\n        print(\"Archivo .json creado y relleno\")\n\n    \"\"\"MOSTRAR\"\"\"\n    with open(\"personaJSON.json\", \"r\") as file:\n        datos = json.load(file)\n        print(\"----Contenido del archivo .json:\")\n        for clave, valor in datos.items():\n            print(f\"{clave} - {valor}\")\n\n\nprogramming_languages = [\"python\", \"html\"]\n\ncrear_mostrar_xml()\nprint(\"/\" * 60)\ncrear_mostrar_json()\n\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Utilizando la lógica de creación de los archivos anteriores, crea un\n#  * programa capaz de leer y transformar en una misma clase custom de tu\n#  * lenguaje los datos almacenados en el XML y el JSON.\n#  * Borra los archivos.\n\n\nclass Persona:\n    def __init__(self, name, age, birth_date, languages):\n        self.name = name\n        self.age = age\n        self.birth_date = birth_date\n        self.languages = languages\n\n    @classmethod\n    def from_xml(cls, filename):\n        root = ET.parse(filename).getroot()\n        name = root.find(\"name\").text # type: ignore\n        age = int(root.find(\"age\").text) # type: ignore\n        birth_date = root.find(\"birth-date\").text # type: ignore\n        languages = [lang.text for lang in root.find(\"languages\")] # type: ignore\n        return cls(name, age, birth_date, languages)\n\n    @classmethod\n    def from_json(cls, filename):\n        data = json.load(open(filename))\n        return cls(data[\"name\"], data[\"age\"], data[\"birth-date\"], data[\"languages\"])\n\n    def __str__(self):\n        return f\"{self.name}, {self.age} años, nacido el {self.birth_date}, lenguajes: {', '.join(self.languages)}\"\n\nprint(\"/\" * 60)\npersona_xml = Persona.from_xml(\"personaXML.xml\")\npersona_json = Persona.from_json(\"personaJSON.json\")\n\nprint(\"Objeto desde XML:\", persona_xml)\nprint(\"Objeto desde JSON:\", persona_json)\n\n\nprint(\"/\" * 60)\n\"\"\"BORRAR ARCHIVOS\"\"\"\nos.remove(\"personaXML.xml\")\nprint(f\"Archivo XML borrado del directorio\")\nos.remove(\"personaJSON.json\")\nprint(f\"Archivo .json borrado del directorio\")\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/victorfer69.py",
    "content": "import os\nimport xml.etree.ElementTree as xml\nimport json\n\n#EJERCICIO\n\ndata = {\n    \"name\" : \"Victor\",\n    \"age\" : 21,\n    \"birthday\" : \"06-09-2003\",\n    \"languages\" : [\"Python\", \"Java\", \"Swift\"]\n}\n\nxml_file = \"victorfer69.xml\"\njson_file = \"victorfer69.json\"\n\n\n#XML\ndef save_xml():\n\n    root = xml.Element(\"data\")\n\n    for key, value in data.items():\n        child = xml.SubElement(root, key)\n        if isinstance(value, list):\n            for item in value:\n                child2 = xml.SubElement(child, \"item\").text = item\n        else:\n            child.text = str(value)\n    \n    tree = xml.ElementTree(root)\n    tree.write(xml_file)\n\nsave_xml()\n\nwith open(xml_file, \"r\") as xml_data:\n    print (xml_data.read())\n\nos.remove(xml_file)\n\n\n#JSON\ndef save_json():\n    with open(json_file, \"w\") as json_data:\n        json.dump(data, json_data)\n\nsave_json()\n\nwith open(json_file, \"r\") as json_data:\n    print(json_data.read())\n\nos.remove(json_file)\n\n\n#EJERCICIO EXTRA\n\nsave_xml()\nsave_json()\n\nclass Data:\n    \n    def __init__(self, name, age, birthday, languages):\n        self.name = name\n        self.age = age\n        self.birthday = birthday\n        self.languages = languages\n\n\nwith open(xml_file, \"r\") as xml_data:\n\n    root = xml.fromstring(xml_data.read())\n    name = root.find(\"name\").text\n    age = root.find(\"age\").text\n    birth_date = root.find(\"birthday\").text\n    programming_languages = []\n    for item in root.find(\"languages\"):\n        programming_languages.append(item.text)\n\n    xml_class = Data(name, age, birth_date, programming_languages)\n    print(f\"XML: {xml_class.__dict__}\")\n\n\nwith open(json_file, \"r\") as json_data:\n    json_dict = json.load(json_data)\n    json_class = Data(\n        json_dict[\"name\"],\n        json_dict[\"age\"],\n        json_dict[\"birthday\"],\n        json_dict[\"languages\"]\n    )\n    print(f\"JSON: {json_class.__dict__}\")\n\nos.remove(xml_file)\nos.remove(json_file)"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/worlion.py",
    "content": "import json\nimport os\nimport xml.etree.ElementTree as ET\n\n\"\"\"\n    EJERCICIO: XML y JSON\n\"\"\"\n\ndeveloper = {\n    \"Nombre\": \"Imanol\",\n    \"Edad\" : 40,\n    \"Fecha_de_nacimiento\" : \"20/04/1984\",\n    \"lenguajes\" : [\"Java\", \"Python\", \"Ada\", \"C#\", \"C/C++\"]\n}\n\nxml_file = \"developer.xml\"\njson_file = \"developer.json\"\n\ndef write_xml_file(dicionary: dict, file_path: str):\n    root = ET.Element(\"root\")\n    \n    for key, value in dicionary.items():\n        print(f\"k:{key} - v:{value}\")\n        child = ET.SubElement(root, key)\n        if isinstance(value, list):\n            for item in value:\n                ET.SubElement(child, \"item\").text = item\n        else:\n            child.text = str(value)\n            \n    print(f\"\\nwriting XML file in {file_path}...\")\n    tree = ET.ElementTree(root)\n    ET.indent(tree, space=\"\\t\", level=0)\n    tree.write(file_path)\n\ndef read_xml_file(file_path:str) -> str:\n    print(f\"\\nreading XML from {file_path}:\")\n    with open(file_path , \"r\") as xfile:\n        return  xfile.read()\n\nwrite_xml_file(developer, xml_file)\nprint(read_xml_file(xml_file))\nos.remove(xml_file)\n\ndef write_json_file(dicionary: dict, file_path: str):\n    print(f\"\\nwriting JOSN file in {file_path}...\")\n    with open(file_path, \"w\") as jfile:\n        json.dump(dicionary, jfile, indent=\"\\t\")\n\ndef read_json_file(file_path: str) -> str:\n    print(f\"\\nreading JOSN from {file_path}...\")\n    with open(file_path, \"r\") as jfile:\n        return jfile.read()\n\nwrite_json_file(developer, json_file)\nprint(read_json_file(json_file))\nos.remove(json_file)\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n\"\"\"\n\nprint(\"\\n ---- 🌩 DIFICULTAD EXTRA 🌩 ----\\n\")\n\n# Developer Class\nclass Developer:\n    def __init__(self, name: str, age: int, birth_date: str, languajes: list) -> None:\n        self.name = name\n        self.age = age\n        self.birth_date = birth_date\n        self.languajes = languajes\n    \n    def __str__(self) -> str:\n        str_self = \"Developer:\"\n        str_self += f\"\\n\\t-Name = {self.name}\"\n        str_self += f\"\\n\\t-Age = {self.age}\"\n        str_self += f\"\\n\\t-Birth_date = {self.birth_date}\"\n        str_self += f\"\\n\\t-Languages = {self.languajes}\"\n        return str_self\n        \n\ndef test_load_dev_from_xml():\n    write_xml_file(developer, xml_file)\n    tree = ET.parse(xml_file)\n    root = tree.getroot()\n\n    name = root.find(\"Nombre\").text\n    age = root.find(\"Edad\").text\n    birth_date = root.find(\"Fecha_de_nacimiento\").text\n    languajes = []\n    for lang in root.find(\"lenguajes\"):\n        print(f\"lang: {lang.text}\")\n        languajes.append(lang.text)\n\n    my_developer_1 = Developer(name, age, birth_date, languajes)\n    \n    print(f\"My developer from XML:\\n{str(my_developer_1)}\")\n    print(f\"num of languages: {len(my_developer_1.languajes)}\")\n    \n    os.remove(xml_file)\n    \ntest_load_dev_from_xml()\n    \n    \n\ndef test_load_dev_from_json():\n    write_json_file(developer, json_file)\n    \n    with open(json_file, \"r\") as json_data:\n        my_json = json.load(json_data)\n        my_developer_2 = Developer(\n            my_json[\"Nombre\"],\n            my_json[\"Edad\"],\n            my_json[\"Fecha_de_nacimiento\"],\n            my_json[\"lenguajes\"])\n    \n    print(f\"My developer from JSON:\\n{str(my_developer_2)}\")\n    print(f\"num of languages: {len(my_developer_2.languajes)}\")\n    \n    os.remove(json_file)\n    \ntest_load_dev_from_json()"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/ycanas.py",
    "content": "import os\nimport json\nimport xml.etree.ElementTree as ET\n\n# ------ Ejercicio\n\nJSONFILE = \"data.json\"\nXMLFILE = \"data.xml\"\n\nmy_dict = {\n    \"name\": \"Yair Canas\",\n    \"age\": 24,\n    \"birth\": \"03/01/2000\",\n    \"languages\": [\"Python\", \"C\", \"C++\", \"Java\", \"Matlab\"]\n}\n\n# I. json\n\nwith open(JSONFILE, 'w') as f:\n    json.dump(my_dict, f)\n\nwith open(JSONFILE, 'r') as f:\n    print(json.load(f))\n\n# II. xml\n\np = ET.Element(\"data\")\n\nfor key, value in my_dict.items():\n    c = ET.SubElement(p, key)\n    \n    if isinstance(value, list):\n        for item in value:\n            ET.SubElement(c, \"item\").text = item\n\n    else:\n        c.text = str(value)\n\ntree = ET.ElementTree(p)\ntree.write(XMLFILE)\n\nwith open(XMLFILE, \"r\") as f:\n    print(f.read())\n\n\n# ------ Extra\n\nclass DataTransform:\n\n    extension: str = \"\"\n\n    def __init__(self, file: str):\n        self.file = file\n        self.extension = self.file.split('.')\n\n    \n    def read(self) -> dict:\n        data = dict()\n        if self.extension[1] == \"json\":\n            with open(JSONFILE, 'r') as f:\n                data = json.load(f)\n\n        else:\n            tree = ET.parse(XMLFILE)\n            root = tree.getroot()\n\n            for item in root:\n                if len(item) == 0:\n                    data[item.tag] = int(item.text) if item.text.isdigit() else item.text\n\n                else:\n                    data[item.tag] = [attrib.text for attrib in item]\n\n        return data\n\n\ndata = DataTransform(XMLFILE)\nprint(data.read())\n\nos.remove(JSONFILE)\nos.remove(XMLFILE)\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/yenneralayon142.py",
    "content": "import xml.etree.ElementTree as xml\nimport os\nimport json\n\n\"\"\"\nJSON Y XML\n\"\"\"\n\ndata = {\n    \"name\" : \"Yenner Alayon\",\n    \"age\" : 21,\n    \"happy_date\" : \"30/05/2003\",\n    \"languages\" : [\"PYTHON\", \"CSHARP\"]\n}\n\nxml_file = \"yenneralayon.xml\"\njson_file = \"yenneralayon.json\"\n\n\n#XML\ndef create_xml():  \n    root = xml.Element(\"data\")\n    for key, value in data.items():\n        child = xml.SubElement(root,key)\n        if isinstance(value,list):\n            for item in value:\n                xml.SubElement(child, \"item\").text = item\n        else:\n            child.text = str(value)\n    tree = xml.ElementTree(root)\n    tree.write(xml_file)\n\ncreate_xml()\n\n#Leer Fichero XML\nwith open(xml_file, \"r\") as data_xml:\n    print(data_xml.read())\n#Eliminar  Fichero XML\n#os.remove(xml_file)\n\n#JSON\n\ndef create_json():\n    with open(json_file, \"w\") as data_json:\n         json.dump(data, data_json)\ncreate_json()\n\nwith open(json_file, \"r\") as data_json:\n    print(data_json.read())\n\n#os.remove(json_file)\n\n\"\"\"\nExtra\n\"\"\"\nclass Data:\n\n    def __init__(self, name:str, age:int, happy_date:str,languages:list):\n        self.name = name\n        self.age = age\n        self.happy_date = happy_date\n        self.languages = languages\n\n# Trabajando con fichero XML desde una clase\nwith open(xml_file, \"r\") as xml_data:\n    root = xml.fromstring(xml_data.read())\n    name = root.find(\"name\").text\n    age = root.find(\"age\").text\n    happydate = root.find(\"happy_date\").text\n    languages = []\n    for item in root.find(\"languages\"):\n        languages.append(item.text)\n    xml_class = Data(name,age,happydate,languages)\n    print(xml_class.__dict__)        \n\n# Trabajando con Fichero Json desde una clase\nwith open(json_file, \"r\") as json_data:\n    json_dict = json.load(json_data)\n    json_class = Data(\n        json_dict[\"name\"],\n        json_dict[\"age\"],\n        json_dict[\"happy_date\"],\n        json_dict[\"languages\"],\n    )\n    print(data_json.__dict__)\n\nos.remove(xml_file)\nos.remove(json_file)"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/zebenpixel.py",
    "content": "\"\"\"\nEJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n\n Declaración XML\n*  xml_declaration=True  Linea 56\n\n * Zebenpixel 2025 *******************************************************\n\"\"\"\n\nimport json\nimport xml.etree.ElementTree as ET\nimport os\n\ndef crear_datos():\n    \"\"\"\n    Crea un diccionario con los datos personales que se desean guardar.\n    \"\"\"\n    return {\n        \"Nombre\": \"ZEBEN\",\n        \"Edad\": 99,\n        \"FechaNacimiento\": \"1900-01-01\",\n        \"LenguajesDeProgramacion\": [\"Python\", \"Java\", \"GO\", \"C#\"]\n    }\n\ndef guardar_json(datos, nombre_archivo=\"datos.json\"):\n    \"\"\"\n    Guarda los datos en formato JSON.\n    \"\"\"\n    with open(nombre_archivo, \"w\", encoding=\"utf-8\") as f:\n        json.dump(datos, f, indent=4, ensure_ascii=False)\n    print(f\"Archivo JSON '{nombre_archivo}' creado correctamente.\")\n\ndef guardar_xml(datos, nombre_archivo=\"datos.xml\"):\n    \"\"\"\n    Guarda los datos en formato XML.\n    \"\"\"\n    root = ET.Element(\"Datos\")\n\n    for clave, valor in datos.items():\n        if isinstance(valor, list):\n            lista_elemento = ET.SubElement(root, clave)\n            for item in valor:\n                ET.SubElement(lista_elemento, \"Lenguaje\").text = item\n        else:\n            ET.SubElement(root, clave).text = str(valor)\n\n    arbol = ET.ElementTree(root)\n    arbol.write(nombre_archivo, encoding=\"utf-8\", xml_declaration=True) \n    print(f\"Archivo XML '{nombre_archivo}' creado correctamente.\")\n\ndef mostrar_contenido(archivo):\n    \"\"\"\n    Muestra el contenido de un archivo de texto si existe.\n    \"\"\"\n    try:\n        with open(archivo, \"r\", encoding=\"utf-8\") as f:\n            print(f\"\\nContenido de '{archivo}':\")\n            print(f.read())\n    except FileNotFoundError:\n        print(f\"No se pudo abrir el archivo '{archivo}' porque no existe.\")\n\ndef borrar_archivo(archivo):\n    \"\"\"\n    Elimina un archivo si existe.\n    \"\"\"\n    if os.path.exists(archivo):\n        os.remove(archivo)\n        print(f\"Archivo '{archivo}' eliminado exitosamente.\")\n    else:\n        print(f\"El archivo '{archivo}' no existe o ya fue eliminado.\")\n\ndef main():\n    # Crear datos\n    datos = crear_datos()\n\n    # Guardar en archivos\n    print(\"+++ Guardando los Archcivos\")\n    guardar_json(datos)\n    guardar_xml(datos)\n\n    # Mostrar contenido de los archivos\n    print(\"+++ Mostrando los Archivos\")\n    mostrar_contenido(\"datos.json\")\n    mostrar_contenido(\"datos.xml\")\n\n    # Eliminar archivos\n    #print(\"+++ Eliminando los Archivos\")\n    #borrar_archivo(\"datos.json\")\n    #borrar_archivo(\"datos.xml\")\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/python/zetared92.py",
    "content": "# RETO 12 JSON Y XML\n\nimport os\nimport xml.etree.ElementTree as xml\nimport json\n\n\"Desarrolla un programa para crear archivo XML y JSON\"\n\ndata = {\n    \"name\": \"Zeta Vega\",\n    \"age\": 31,\n    \"birth_date\": \"03-12-1992\",\n    \"languages\": [\"Python\", \"Swift\", \"Rust\"]\n}\n\nxml_file = \"zetared.xml\"\njson_file = \"zetared.json\"\n\n\"\"\"\nEJERCICIO\n\"\"\"\n\n# XML\n\ndef create_xml():\n\n    root = xml.Element(\"data\")\n\n    for key, value in data.items():\n        child = xml.SubElement(root, key)\n        if isinstance(value, list):\n            for item in value:\n                xml.SubElement(child, \"item\").text = item\n        else:\n            child.text = str(value)\n\n    tree = xml.ElementTree(root)\n    tree.write(xml_file)\n\ncreate_xml()\n\nwith open(xml_file, \"r\") as xml_data:\n    print(xml_data.read())\n\nos.remove(xml_file)\n\n# JSON\n\ndef create_json():\n    with open(json_file, \"w\") as json_data:\n        json.dump(data, json_data)\n\n\ncreate_json()\n\nwith open(json_file, \"r\") as json_data:\n    print(json_data.read())\n\nos.remove(json_file)\n\n\n# Extra\n\nprint(\"🧩 DIFICULTAD EXTRA - ARCHIVOS 🧩\")\n\ncreate_xml()\ncreate_json()\n\nclass Data:\n\n    def __init__(self, name, age, birth_date, languages) -> None:\n        self.name = name\n        self.age = age\n        self.birth_date = birth_date\n        self.languages = languages\n\nwith open(xml_file, \"r\") as xml_data:\n\n    root = xml.fromstring(xml_data.read())\n    name = root.find(\"name\").text\n    age = root.find(\"age\").text\n    birth_date = root.find(\"birth_date\").text\n    languages = []\n    for item in root.find(\"languages\"):\n        languages.append(item.text)\n    \n    xml_class = Data(name, age, birth_date, languages)\n    print(xml_class.__dict__)\n\nwith open(json_file, \"r\") as json_data:\n    json_dict = json.load(json_data)\n    json_class = Data(\n        json_dict[\"name\"],\n        json_dict[\"age\"],\n        json_dict[\"birth_date\"],\n        json_dict[\"languages\"]\n    )\n    print(json_class.__dict__)\n\nos.remove(xml_file)\nos.remove(json_file)"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/ruby/Elmer125.rb",
    "content": "#  * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n#  *\n#  * EJERCICIO:\n#  * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n#  * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n#  * - Nombre\n#  * - Edad\n#  * - Fecha de nacimiento\n#  * - Listado de lenguajes de programación\n#  * Muestra el contenido de los archivos.\n#  * Borra los archivos.\nrequire 'nokogiri'\nrequire 'json'\n\ndata = {\n  name: \"John Doe\",\n  age: 30,\n  birth_date: \"07-07-1994\",\n  languages: [\"Ruby\", \"Kotlin\", \"JavaScript\"]\n}\n\n\nclass FileHandler\n  def initialize(file)\n    @file = file\n  end\n\n  def show_file_content\n    puts File.read(@file)\n  end\n\n  def delete_file\n    File.delete(@file)\n  end\nend\n\n###XML file###\n# def create_xml(file, data)\n#   File.open(file, \"w\") do |file|\n#     file.puts \"<user>\"\n#     data.each do |key, value|\n#       file.puts \"  <#{key}>#{value}</#{key}>\"\n#     end\n#     file.puts \"</user>\"\n#   end\n# end\n\n# Using the Nokogiri gem\nxml_file = \"elmer125.xml\"\ndef create_xml(file, data)\n  builder = Nokogiri::XML::Builder.new do |xml|\n    xml.user {\n      xml.name data[:name]\n      xml.age data[:age]\n      xml.birth_date data[:birth_date]\n      xml.languages {\n        data[:languages].each do |language|\n          xml.language language\n        end\n      }\n    }\n  end\n\n  File.write(file, builder.to_xml)\nend\n\ncreate_xml(xml_file, data)\nxml_handler = FileHandler.new(xml_file)\nputs \"XML file content:\"\nxml_handler.show_file_content\nxml_handler.delete_file\n\n###JSON file###\njson_file = \"elmer125.json\"\n\n# Create JSON file\ndef create_json(file, content)\n  File.write(file, content)\nend\njson_content = data.to_json\ncreate_json(json_file, json_content)\njson_handler = FileHandler.new(json_file)\nputs \"JSON file content:\"\njson_handler.show_file_content\njson_handler.delete_file\n\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Utilizando la lógica de creación de los archivos anteriores, crea un\n#  * programa capaz de leer y transformar en una misma clase custom de tu\n#  * lenguaje los datos almacenados en el XML y el JSON.\n#  * Borra los archivos.\n#  */\n\n\ncreate_xml(xml_file, data)\ncreate_json(json_file, data.to_json)\n\nclass Data\n  attr_accessor :name, :age, :birth_date, :languages\n\n  def initialize(name, age, birth_date, languages)\n    @name = name\n    @age = age\n    @birth_date = birth_date\n    @languages = languages\n  end\n\n  def self.xml_file(file)\n    xml = Nokogiri::XML(File.read(file))\n    name = xml.xpath(\"//name\").text\n    age = xml.xpath(\"//age\").text.to_i\n    birth_date = xml.xpath(\"//birth_date\").text\n    languages = xml.xpath(\"//languages/language\").map(&:text)\n    new(name, age, birth_date, languages)\n  end\n\n  def self.json_file(file)\n    data = JSON.parse(File.read(file))\n    new(data[\"name\"], data[\"age\"], data[\"birth_date\"], data[\"languages\"])\n  end\n\n  def delete_file(file)\n    File.delete(file)\n  end\n\n  def show_data\n    puts \"#\"*10\n    puts \"Name: #{@name}\"\n    puts \"Age: #{@age}\"\n    puts \"Birth date: #{@birth_date}\"\n    puts \"Languages: #{@languages.join(\", \")}\"\n  end\nend\n\nxml = Data.xml_file(xml_file)\njson = Data.json_file(json_file)\n\nxml.show_data\njson.show_data\n\nxml.delete_file(xml_file)\njson.delete_file(json_file)\n\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/rust/kenysdev.rs",
    "content": "/*\n╔═══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado                ║\n║ GitHub: https://github.com/Kenysdev   ║\n║ 2024 -  Rust                          ║\n╚═══════════════════════════════════════╝\n-----------------------------------------\n* JSON Y XML\n-----------------------------------------\n- son formatos de intercambio de datos que estructuran información.\n- JSON (JavaScript Object Notation) y XML (Extensible Markup Language)\n\n- Agregar biblioteca -> cargo add serde\n                        cargo add serde-json\n                        cargo add serde-xml-rs\n[dependencies]\nserde = { version = \"1.0.197\", features = [\"derive\"] }\nserde_json = \"1.0.115\"\nserde-xml-rs = \"0.6.0\"\n____________________________________\n* JSON (https://crates.io/crates/serde_json)\n\n*/\nuse serde::{Deserialize, Serialize};\nuse std::fs::File;\nuse std::io::prelude::*;\nuse std::io::Result;\nuse std::io::{self, Error, ErrorKind};\n\n#[derive(Debug, Serialize, Deserialize)]\npub struct User {\n    name: String,\n    age: u32,\n    dob: String,\n    prog_langs: Vec<String>,\n}\n\nfn write_json(user: &User) -> Result<()> {\n    let json_data = serde_json::to_string_pretty(&user)?;\n    let mut file = File::create(\"user.json\")?;\n    file.write_all(json_data.as_bytes())?;\n    println!(\"JSON creado\");\n    Ok(())\n}\n\npub fn read_json() -> Result<User> {\n    let mut file = File::open(\"user.json\")?;\n    let mut json_data = String::new();\n    file.read_to_string(&mut json_data)?;\n    let user: User = serde_json::from_str(&json_data)?;\n    Ok(user)\n}\n\n/* ____________________________________\n* XML (https://crates.io/crates/serde-xml-rs)\n*/\n\nfn write_xml(user: &User) -> io::Result<()> {\n    let xml_data = serde_xml_rs::to_string(user)\n        .map_err(|e| Error::new(ErrorKind::Other, e))?;\n    \n    let mut file = File::create(\"user.xml\")?;\n    file.write_all(xml_data.as_bytes())?;\n    println!(\"XML creado con éxito.\");\n    Ok(())\n}\n\nfn read_xml() -> io::Result<User> {\n    let mut file = File::open(\"user.xml\")?;\n    let mut xml_data = String::new();\n    file.read_to_string(&mut xml_data)?;\n\n    let user: User = serde_xml_rs::from_str(&xml_data)\n        .map_err(|e| Error::new(ErrorKind::Other, e))?;\n\n    Ok(user)\n}\n\nfn delete_file(the_path: &str) {\n    if let Err(err) = std::fs::remove_file(the_path) {\n        println!(\"Error al eliminar {}: {}\", the_path, err);\n    } else {\n        println!(\"* {} ha sido eliminado.\", the_path);\n    }\n}\n\nfn main(){\n    let default_user = User {\n        name: \"Ken\".to_string(),\n        age: 121,\n        dob: \"1903-03-19\".to_string(),\n        prog_langs: vec![\"cs\", \"py\", \"vb\", \"rs\", \"js\"]\n            .iter()\n            .map(|s| s.to_string())\n            .collect(),\n    };\n\n    //___________________________\n    if let Err(e) = write_json(&default_user) {\n        eprintln!(\"Error al escribir JSON: {}\", e);\n    }\n\n    match read_json() {\n        Ok(user) => println!(\"datos en el JSON deserializados:\\n{:?}\", user),\n        Err(e) => eprintln!(\"Error al deserializar JSON: {}\", e),\n        /*\n        Ok(user) => {\n            println!(\"Nombre: {}\", user.name);\n            println!(\"Edad: {}\", user.age);\n            ...\n        */\n    }\n\n    //___________________________\n    if let Err(e) = write_xml(&default_user) {\n        eprintln!(\"Error al escribir XML: {}\", e);\n    }\n\n    match read_xml() {\n        Ok(user) => println!(\"datos en el XML deserializados:\\n{:?}\", user),\n        Err(e) => eprintln!(\"Error al deserializar XML: {}\", e),\n    }\n\n    //___________________________\n    delete_file(\"user.json\");\n    delete_file(\"user.xml\");\n\n}\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/rust/w00k.rs",
    "content": "/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n */\n\nuse std::fs;\nuse std::fs::File;\nuse std::io::Write;\n\n// Struct base\n#[derive(Debug)]\nstruct DevData {\n    name: String,\n    age: u8,\n    birth_date: String,\n    programming_languages_list: Vec<String>,\n}\n\n// Implementación de funciones json and xml\nimpl DevData {\n    // Transforma el struct en string con formato json\n    fn json(&self) -> String {\n        let mut json = String::from(\"{\");\n        let end = String::from(\"}\");\n        let end_line = &*String::from(\",\");\n        let quotes = &*String::from(\"\\\"\");\n\n        let name = String::from(\"\\\"name\\\":\") + quotes + &*self.name + quotes + end_line;\n        let age = String::from(\"\\\"age\\\":\") + &*self.age.to_string() + end_line;\n        let birth_date = String::from(\"\\\"birth_date\\\":\") + quotes + &*self.birth_date + quotes + end_line;\n        let programming_languages_list = String::from(\"\\\"programming_languages\\\":\") + &*json_list(self.programming_languages_list.clone());\n\n        json += &*(name + &*age + &*birth_date + &*programming_languages_list + &*end);\n        return json;\n    }\n    // Transforma el struct en string con formato xml\n    fn xml(&self) -> String {\n        let mut xml = String::from(\"<data_dev>\");\n        let end_xml = String::from(\"</data_dev>\");\n\n        let name = \"<name>\".to_owned() + &*self.name + \"</name>\";\n        let age = \"<age>\".to_owned() + &*self.age.to_string() + \"</age>\";\n        let birth_date = \"<birth_date>\".to_owned() + &*self.birth_date + \"</birth_date>\";\n        let programming_languages_list = xml_list(self.programming_languages_list.clone());\n\n        xml += &*(name + &*age + &*birth_date + &*programming_languages_list + &*end_xml);\n\n        return xml;\n    }\n}\n\n// Utilidad para transformar el vector programming_languages en array json\nfn json_list(dev_data_list: Vec<String>) -> String {\n    let mut list = String::from(\"[\");\n    let end = &*String::from(\"]\");\n    let end_line = &*String::from(\",\");\n    let quotes = &*String::from(\"\\\"\");\n\n    for (index, language) in dev_data_list.iter().enumerate() {\n        if index == dev_data_list.len() -1 { // determino el último elemento,  por la coma al final\n            list += &*(quotes.to_owned() + &*language.to_owned() + &*quotes);\n        } else {\n            list += &*(quotes.to_owned() + &*language.to_owned() + &*quotes + end_line);\n        }\n\n    }\n\n    list += end;\n    return list;\n}\n\n// Utilidad para transformar el vector programming_languages en array xml\nfn xml_list(dev_data_list: Vec<String>) -> String {\n    let mut xml = String::from(\"<programming_languages>\");\n    let end_xml = String::from(\"</programming_languages>\");\n\n    for language in dev_data_list {\n        xml += &*(\"<language>\".to_owned() + &*language.to_owned() + \"</language>\");\n    }\n\n    xml += &*end_xml;\n    return xml;\n}\n\n// Utilidad para crear el archivo con data, nombre y extensión\nfn create_file(data: String, file_name: &str, extension: &str) {\n    let output_file_name = file_name.to_owned() + extension; // nombre del archivo con extensión\n    let mut file = File::create(output_file_name.clone()).expect(\"Error creating file\");\n\n    file.write_all(data.as_bytes()).expect(\"Error writing to the file\");\n    println!(\"Successfully wrote data to {}\", output_file_name);\n\n    let contents = fs::read_to_string(output_file_name.as_str()).expect(\"Should have been able to read the file\");\n    println!(\"With text:{contents}\");\n\n    fs::remove_file(output_file_name.as_str()).expect(\"File not found\");\n    println!(\"Delete file\\n\");\n}\n\nfn main() {\n    println!(\"Start\");\n\n    // nombre del archivo\n    let file_name = \"w00k\";\n\n    // extensiones\n    let xml_extension = \".xml\";\n    let json_extension = \".json\";\n\n    let dev_data = DevData{\n        name: String::from(\"w00k\"),\n        age: 41,\n        birth_date: String::from(\"07/08/1982\"), //mm/dd/yyyy\n        programming_languages_list: vec![String::from(\"Java\"), String::from(\"Go\"), String::from(\"Rust\")],\n    };\n\n    // imprimo el contenido del struct\n    println!(\"dev data: {:?} \\n\", dev_data);\n\n    create_file(dev_data.json(), file_name, json_extension);\n\n    create_file(dev_data.xml(), file_name, xml_extension);\n\n    println!(\"End\");\n\n}\n\n\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/sql/Nicojsuarez2.sql",
    "content": "# #12 JSON Y XML\n> #### Dificultad: Difícil | Publicación: 18/03/24 | Corrección: 25/03/24\n\n## Ejercicio\n\n```\n/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n * \n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu \n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/swift/allbertoMD.swift",
    "content": "import Foundation\n\n\n// PROGRAMA QUE CREA UN JSON Y UN XML\nprint(\"\\nPROGRAMA QUE CREA UN JSON Y UN XML.\")\n\n\n\n// Diccionario donde estaran los datos solicitados al usuario contenidos.\nvar dictionary: [String:Any] = [:]\nvar lenguagesArray: [String] = []\nvar jsonPath: String = \"\"\nvar xmlPath: String = \"\"\nvar jsonURL: URL = URL(filePath: \"\")\nvar xmlURL: URL = URL(filePath: \"\")\n\n\n// Pide el nombre al usuario.\nprint(\"\\nIntroduce tu nombre:\")\nif let name = readLine() {\n    dictionary[\"name\"] = name\n}\n\n// Pide la edad al usuario.\nprint(\"\\nIntroduce tu edad:\")\nif let age: String = readLine(), let ageInt: Int = Int(age) {\n    dictionary[\"age\"] = ageInt\n}\n\n// Pide la fecha de nacimiento al usuario.\nprint(\"\\nIntroduce tu fecha de nacimiento, (dd/mm/yyyy):\")\nif let birthdate: String = readLine() {\n    dictionary[\"birthdate\"] = birthdate\n}\n\n// Pide los lenguajes de programación al usuario.\nprint(\"\\nIntroduce tus lenguajes de programación:\")\n// El usuario puede ingresar lenguajes hasta que ponga la palabre exit.\nwhile true {\n    // Comprueba que el usuario pone exit para salir del bucle y guardar el array en el campo \"lenguages\"\n    if let lenguage = readLine() {\n        if lenguage == \"exit\" {\n        dictionary[\"lenguages\"] = lenguagesArray\n        break\n        }\n        lenguagesArray.append(lenguage)\n    }\n    print(\"Para terminar introduce \\\"exit\\\"\")\n}\n\n// Pide al usuario el nombre y ruta del fichero JSON.\nprint(\"\\nIntroduce la ruta y el nombre del fichero JSON.\")\nif let fileName = readLine() {\n\n    jsonPath = fileName\n    jsonURL = URL(filePath: fileName)\n\n    if FileManager.default.fileExists(atPath: fileName) {\n        print(\"El fichero ya existe.\")\n    \n    } else {\n\n        do {\n            let jsonData = try JSONSerialization.data(withJSONObject: dictionary, options: .prettyPrinted)\n    \n            // Escribir el JSON en el fichero.\n            try jsonData.write(to: jsonURL)\n    \n            print(\"Archivo JSON creado en: \\(jsonURL)\")\n        } catch {\n            print(\"Error al crear el archivo JSON: \\(error.localizedDescription)\")\n        }\n    }  \n}\n\n\n\n\n// Crea un string con la cabecera del xml.\nvar xmlString = \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\\n\"\nxmlString.append(\"<data>\\n\")\n\n// Itera en las claves y valores del diccionario.\nfor (key, value) in dictionary {\n    // Pone como etiqueta xml la clave del dicionario.\n    xmlString.append(\"\\t<\\(key)>\")\n\n    // Detecta si alguno de los valores del diccionario es un array de string.\n    if let arrayValue = value as? [String] {\n        // Si algun valor es un array itera en el.\n        for item in arrayValue {\n            // Crea el tag item añadiendo cada valor del array.\n            xmlString.append(\"\\n\\t\\t<item>\\(item)</item>\")\n        }\n    } else {\n        // Si no hay un array añade la clave como tag xml.\n        xmlString.append(\"\\(value)\")\n    }\n    // Pone como valor de la tag el valor de cada clave del dicionario.\n    xmlString.append(\"</\\(key)>\\n\")\n}\n// Cierra la cabecera del xml.\nxmlString.append(\"</data>\")\n\n// Pide al usuario la ruta y el nombre del xml.\nprint(\"\\nIntroduce la ruta y el nombre del fichero XML:\")\nif let fileName = readLine() {\n\n    xmlPath = fileName\n    xmlURL = URL(filePath: fileName)\n\n    if FileManager.default.fileExists(atPath: fileName) {\n        print(\"El fichero ya existe.\")\n    \n    } else {\n        do {\n            // Escribe el xml en un fichero.\n            try xmlString.write(to: xmlURL, atomically: true, encoding: .utf8)\n        \n            print(\"Archivo XML creado en: \\(xmlURL)\")\n        } catch {\n            print(\"Error al crear el archivo XML: \\(error.localizedDescription)\")\n        }\n    }\n}\n\nsleep(4)\n\n\n\n\n// Muestra por consola el fichero JSON.\nprint(\"\\nFichero JSON.\")\nvar processToShowJsonFile = Process()\nprocessToShowJsonFile.launchPath = \"/bin/cat\"\nprocessToShowJsonFile.arguments = [jsonPath]\nprocessToShowJsonFile.launch()\nprocessToShowJsonFile.waitUntilExit()\n\n\n\n\n// Muestra por consola el fichero XML.\nprint(\"\\n\\nFichero XML.\")\nvar processToShowXmlFile = Process()\nprocessToShowXmlFile.launchPath = \"/bin/cat\"\nprocessToShowXmlFile.arguments = [xmlPath]\nprocessToShowXmlFile.launch()\nprocessToShowXmlFile.waitUntilExit()\n\nsleep(4)\n\n\n\n\n// DIFICULTAD EXTRA\nprint(\"\\nDIFICULTAD EXTRA.\")\n\n\n\n\n// Clase que almacenara los datos del fichero JSON.\nclass JsonFile: Decodable {\n    var name: String\n    var age: Int\n    var birthdate: String\n    var lenguages: [String]\n}\n\n// Obtiene el Path del fichero JSON.\njsonPath = FileManager.default.currentDirectoryPath + \"/data.json\"\n\n// Si Si el fihero tiene datos los almacena el la variable data.\nif let data = FileManager.default.contents(atPath: jsonPath) {\n    do {\n        // Decodifica los datos del JSON en la clase JsonFile.\n        let jsonFile = try JSONDecoder().decode(JsonFile.self, from: data)\n        \n        print(\"\\n\\nDatos del fichero JSON.\")\n        // Imprime los datos de la clase JsonFile.\n        print(\"Nombre: \\(jsonFile.name)\")\n        print(\"Edad: \\(jsonFile.age)\")\n        print(\"Fecha de nacimiento: \\(jsonFile.birthdate)\")\n        print(\"Lenguajes: \\(jsonFile.lenguages)\")\n    } catch {\n        print(error.localizedDescription)\n    }\n} else {\n    print(\"No se puedo leer el fichero JSON.\")\n}\n\n\n\n\n// Clase que almacenara los datos del fichero XML.\nclass XmlFile {\n    var name: String = \"\"\n    var age: Int = 0\n    var birthdate: String = \"\"\n    var languages: [String] = []\n}\n\n// Obtiene el Path del fichero XML.\nxmlPath = FileManager.default.currentDirectoryPath + \"/data.xml\"\n\n// Si el fichero tiene datos los almacene en la bariable data.\nif let data = FileManager.default.contents(atPath: xmlPath) {\n    // Crea un objeto de la clase XMLParser() y le pasa los datos del fichero.\n    let parser = XMLParser(data: data)\n    // Objeto de la clase XmlHandler.\n    let xmlHandler = XmlHandler()\n    // Usa la clase XmlHandler como delegado del objeto parser.\n    parser.delegate = xmlHandler\n\n    // Si el parser encuentra datos.\n    if parser.parse() {\n        // Decodifica los datos del fichero en la en la clase XmlFile().\n        let xmlFile = xmlHandler.xmlFile\n        \n        print(\"\\nDatos del fichero XML.\")\n        // Imprime los datos de la clase XmlFile.\n        print(\"Nombre: \\(xmlFile.name)\")\n        print(\"Edad: \\(xmlFile.age)\")\n        print(\"Fecha de nacimiento: \\(xmlFile.birthdate)\")\n        print(\"Languajes: \\(xmlFile.languages)\")\n    } else {\n        print(\"Error parsing XML.\")\n    }\n} else {\n    print(\"No se pudo leer el archivo XML.\")\n}\n\n// Crea la clase que se usara como delegado en el parser.\nclass XmlHandler: NSObject, XMLParserDelegate {\n    var xmlFile = XmlFile()\n    var currentElement = \"\"\n    var currentLanguage = \"\"\n\n    func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) {\n        currentElement = elementName\n        if elementName == \"lenguages\" {\n            xmlFile.languages = []\n        }\n    }\n\n    func parser(_ parser: XMLParser, foundCharacters string: String) {\n        let trimmedString = string.trimmingCharacters(in: .whitespacesAndNewlines)\n        if !trimmedString.isEmpty {\n            switch currentElement {\n            case \"name\":\n                xmlFile.name = trimmedString\n            case \"age\":\n                if let age = Int(trimmedString) {\n                    xmlFile.age = age\n                }\n            case \"birthdate\":\n                xmlFile.birthdate = trimmedString\n            case \"item\":\n                currentLanguage = trimmedString\n            default:\n                break\n            }\n        }\n    }\n\n    func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {\n        if elementName == \"item\" {\n            xmlFile.languages.append(currentLanguage)\n        }\n    }\n}\n\nsleep(4)\n\n\n\n\n// Elimina el fichero JSON.\ndo {\n    try FileManager.default.removeItem(at: jsonURL)\n    print(\"\\n\\nFichero JSON borado.\")\n} catch {\n    print(error.localizedDescription)\n}\n\n\n\n\n// Elimina el fichero XML.\ndo {\n    try FileManager.default.removeItem(at: xmlURL)\n    print(\"\\nFichero XML borrado.\")\n} catch {\n    print(error.localizedDescription)\n}\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/swift/blackriper.swift",
    "content": "import Foundation\nimport XMLCoder\n\n/*\n Al proceso de convertir un objeto swift a un formato json o Xml \n se le conoce como serialización.\n \n anteriormente se usaba la opcion JSONSerialization.dataWithJSONObject para serializar un objeto swift\n pero desde swift 4.0  se creo  un protocolo Codable para serializar un objeto swift.\n\n Codable es una composición de dos protocolos:  Encodable y Decodable\n\n Encondable: Permite serializar un objeto swift a un formato json o Xml\n Decodable: Permite deserializar un objeto json o Xml a un objeto swift\n\n codable por defecto no soporta xml por lo cual hay que agregar una libreria para ello \n https://github.com/CoreOffice/XMLCoder\n\n */\n struct Person:Codable{\n     let name:String\n     let age:Int\n     let birthDate:String\n     let programmingLanguage:[String]\n    }\n\n\nfunc exampleWorkingWithJson(){\n   let fileManager=FileManager.default\n   let encoder=JSONEncoder()\n   encoder.outputFormatting = .prettyPrinted\n   \n   // crear fichero\n   let person=Person(name:\"Rodolfo\",age: 29,birthDate: \"20/05/1994\",programmingLanguage: [\"swift\",\"kotlin\",\"go\",\"python\",\"typescript\",\"java\"])\n   guard let encoded = try? encoder.encode(person)else{\n        print(\"error to encode \")\n        return \n    }\n   fileManager.createFile(atPath: \"/home/blackriper/Descargas/person.json\", contents:encoded, attributes: nil)\n\n   // leer fichero\n   if let jsonData=fileManager.contents(atPath: \"/home/blackriper/Descargas/person.json\"){\n        guard let decoded = try? JSONDecoder().decode(Person.self, from: jsonData)else{\n                print(\"error to decode\")\n                return\n            }\n        let gretting=\"\"\"\n        Hello my name is \\(decoded.name) and I am \\(decoded.age) years old.\n        I was born on \\(decoded.birthDate) and \n        I am learning \\(decoded.programmingLanguage)\n        \"\"\"\n        print(gretting)\n    }\n    \n    // borrar fichero\n    do{\n      try fileManager.removeItem(atPath: \"/home/blackriper/Descargas/person.json\")\n    }catch{\n        print(\"error to delete\")\n    } \n\n}\n\nexampleWorkingWithJson()\n\nfunc exampleWorkingWithXml(){\n    let fileManager=FileManager.default\n    let person=Person(name:\"Rodolfo\",age: 29,birthDate: \"20/05/1994\",programmingLanguage: [\"swift\",\"kotlin\",\"go\",\"python\",\"typescript\",\"java\"])\n\n    // crear fichero\n    if let xmlDoc = try? XMLEncoder().encode(person,withRootKey: \"person\") {\n      fileManager.createFile(atPath: \"/home/blackriper/Descargas/person.xml\", contents:xmlDoc, attributes: nil)\n    }\n\n    // leer fichero \n    if let xmlData=fileManager.contents(atPath: \"/home/blackriper/Descargas/person.xml\"){\n        guard let decoded = try? XMLDecoder().decode(Person.self, from: xmlData)else{\n                print(\"error to decode\")\n                return \n        }\n        let gretting=\"\"\"\n        Hello my name is \\(decoded.name) and I am \\(decoded.age) years old.\n        I was born on \\(decoded.birthDate) and \n        I am learning \\(decoded.programmingLanguage)\n        \"\"\"\n        print(gretting)\n\n    }\n\n    // borrar fichero\n    do{\n      try fileManager.removeItem(atPath: \"/home/blackriper/Descargas/person.xml\")\n    }catch{\n        print(\"error to delete\")\n    } \n }\n\nexampleWorkingWithXml()\n\n// ejercicio extra \n\n struct Product:Codable {\n    var name: String\n    var cantity: Int\n    var price: Int\n}\n\n enum Formats {\n    case xml\n    case json\n }\n\nstruct FileOperations{\n   let path: String \n   private let fileManager = FileManager.default   \n    \n\n    func createFile(_ contents: Data?) {\n        fileManager.createFile(atPath:self.path,contents: contents)\n    }\n\n    func readFile(format: Formats) {\n        guard let data = fileManager.contents(atPath: self.path) else {\n            print(\"File not found\")\n            return\n        }\n       switch format{\n        case .xml:\n            if let xmlDoc = try? XMLDecoder().decode([Product].self, from: data) {\n              xmlDoc.forEach{ product in\n                print(\"\\(product.name)      |    \\(product.cantity)       |     \\(product.price)  |       \\(product.price*product.cantity)\")\n              }\n\n                }\n            \n        case .json:\n            if let jsonData = try? JSONDecoder().decode([Product].self, from: data) {\n              jsonData.forEach{ product in\n                print(\"\\(product.name)      |    \\(product.cantity)       |     \\(product.price)  |       \\(product.price*product.cantity)\")\n            }\n        }\n       }  \n    }\n   \n    func deleteFile() {\n        do {\n            try fileManager.removeItem(atPath: self.path)\n        }catch let error{\n            print(\"Error deleting file: \\(error)\")\n       }\n    }\n}\n\n\nclass Cart { \n    private var products: [Product] = []\n    let fileManager:FileOperations\n    let format:Formats\n\n    init(src:String,fmt:Formats) {\n        self.fileManager = FileOperations(path: src)\n        self.format = fmt\n    }\n\n    func addProduct(product: Product) {\n        products.append(product)\n        self.saveFile()\n    \n    }\n    func removeProduct(name:String) {\n        products.removeAll(where: { $0.name == name.uppercased() })\n        self.saveFile()\n    }\n\n      func updateProduct(name:String){\n       guard var product=products.first(where: { $0.name == name.uppercased() })else {\n          print(\"Product not found\")\n          return\n       }\n       print(\"update name \\(product.name):\")\n       let newName=readLine() ?? product.name\n\n       print(\"update cantity \\(product.cantity):\")\n       let newCantity = Int(readLine() ?? \"\\(product.cantity)\")\n\n       print(\"update price \\(product.price):\")\n       let newPrice = Int(readLine() ?? \"\\(product.price)\")\n\n       product.name=newName.uppercased()\n       product.cantity=newCantity ?? product.cantity\n       product.price=newPrice ?? product.price\n       saveFile()\n    }\n\n    func listProducts(){\n        let header=\"\"\"\n            Name     | cantity | Price\n          \"\"\"      \n        print(header)  \n        fileManager.readFile(format: format)   \n     }\n\n    func totalSold(){\n        let total=products.reduce(0) { $0 + $1.price }\n        let header=\"\"\"\n            Name       |    cantity   |    Price      |   Total Product\n          \"\"\"      \n       print(header)\n       products.forEach { product in\n        print(\"\\(product.name)      |    \\(product.cantity)       |     \\(product.price)  |       \\(product.price*product.cantity)\")\n       }\n       print(\"Total sold: \\(total)\")\n    }\n    \n\n    func exitApp(){\n      fileManager.deleteFile()\n    }\n  \n   private func saveFile() {\n       switch format {\n           case .xml:\n           if let xmlDoc = try? XMLEncoder().encode(products,withRootKey: \"products\") {\n              fileManager.createFile(xmlDoc)\n           }\n           case .json:\n           if let jsonData = try? JSONEncoder().encode(products) {\n              fileManager.createFile(jsonData)\n           }\n       } \n   }\n}\n            \n\n            \n\n func marketPlace(format:Formats) {\n   let src = switch format {\n      case .xml:\n         \"/home/blackriper/Descargas/products.xml\"\n      case .json:\n         \"/home/blackriper/Descargas/products.json\"   \n    }\n     let cart = Cart(src: src, fmt: format)\n  marketloop:\n     while true {\n        print(\"1. Add product\")\n        print(\"2. Remove product\")\n        print(\"3. Update product\")\n        print(\"4. List products\")\n        print(\"5. Total sold\")\n        print(\"6. Exit\")\n        let option = Int(readLine() ?? \"0\") ?? 0\n        switch option {\n           case 1:\n              print(\"Name of product:\")\n              let name = readLine() ?? \"\"\n              print(\"Cantity:\")\n              let cantity = Int(readLine() ?? \"0\") ?? 0\n              print(\"Price:\")\n              let price = Int(readLine() ?? \"0\") ?? 0\n              let product=Product(name: name.uppercased(), cantity: cantity, price: price)\n              cart.addProduct(product: product)\n           \n           case 2:\n              print(\"Name of product:\")\n              let name = readLine() ?? \"\"\n              cart.removeProduct(name: name.uppercased())\n\n           case 3: \n              print(\"Name of product:\")\n              let name = readLine() ?? \"\"\n              cart.updateProduct(name: name.uppercased())\n           case 4:\n              cart.listProducts()\n           \n           case 5:\n              cart.totalSold()\n\n           case 6:\n              cart.exitApp()\n              break marketloop\n            \n           default:\n             print(\"Invalid option\")\n        }\n    }    \n }\n\n marketPlace(format: Formats.json)\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/swift/kontroldev.swift",
    "content": "import Foundation\n\n/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu\n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n */\n\n\n// Definición de la clase personalizada\nclass Persona: Codable {\n    var nombre: String\n    var edad: Int\n    var fechaNacimiento: Date\n    var lenguajesProgramacion: [String]\n\n    init(nombre: String, edad: Int, fechaNacimiento: Date, lenguajesProgramacion: [String]) {\n        self.nombre = nombre\n        self.edad = edad\n        self.fechaNacimiento = fechaNacimiento\n        self.lenguajesProgramacion = lenguajesProgramacion\n    }\n}\n\n// Creación de una instancia de la clase Persona\nlet persona = Persona(nombre: \"Juan\", edad: 30, fechaNacimiento: Date(), lenguajesProgramacion: [\"Swift\", \"Python\", \"JavaScript\"])\n\n// Creación del archivo JSON\nif let url = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent(\"persona.json\"),\n   let data = try? JSONEncoder().encode(persona) {\n    try? data.write(to: url)\n    print(String(data: data, encoding: .utf8) ?? \"Error al convertir a String\")\n}\n\n// Creación del archivo XML\nif let url = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent(\"persona.xml\"),\n   let data = try? PropertyListEncoder().encode(persona) {\n    try? data.write(to: url)\n    print(String(data: data, encoding: .utf8) ?? \"Error al convertir a String\")\n}\n\n// Lectura y transformación de los datos almacenados en el XML y el JSON\nif let urlJSON = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent(\"persona.json\"),\n   let urlXML = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent(\"persona.xml\"),\n   let dataJSON = try? Data(contentsOf: urlJSON),\n   let dataXML = try? Data(contentsOf: urlXML),\n   let personaDesdeJSON = try? JSONDecoder().decode(Persona.self, from: dataJSON),\n   let personaDesdeXML = try? PropertyListDecoder().decode(Persona.self, from: dataXML) {\n    print(personaDesdeJSON)\n    print(personaDesdeXML)\n}\n\n// Borrado de los archivos\ndo {\n    let urlJSON = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent(\"persona.json\")\n    let urlXML = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent(\"persona.xml\")\n    try FileManager.default.removeItem(at: urlJSON!)\n    try FileManager.default.removeItem(at: urlXML!)\n} catch {\n    print(\"Error al borrar los archivos\")\n}\n\n\n/// **Ejercicios Extra\n\nimport Foundation\n\nclass Person: Codable {\n    var name: String\n    var age: Int\n    var email: String\n\n    // Inicialización a partir de JSON\n    init(fromJSON data: Data) throws {\n        let decoder = JSONDecoder()\n        let person = try decoder.decode(Person.self, from: data)\n        self.name = person.name\n        self.age = person.age\n        self.email = person.email\n    }\n\n    // Inicialización a partir de XML\n    init(fromXML data: Data) throws {\n        let parser = XMLParser(data: data)\n        let delegate = PersonXMLParserDelegate()\n        parser.delegate = delegate\n        parser.parse()\n\n        guard let person = delegate.person else {\n            throw NSError(domain: \"XMLParsingError\", code: 0, userInfo: nil)\n        }\n        self.name = person.name\n        self.age = person.age\n        self.email = person.email\n    }\n}\n\n// Clase auxiliar para parsear XML\nclass PersonXMLParserDelegate: NSObject, XMLParserDelegate {\n    var person: Person?\n    var currentElement = \"\"\n    var currentName = \"\"\n    var currentAge = 0\n    var currentEmail = \"\"\n\n    func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) {\n        currentElement = elementName\n    }\n\n    func parser(_ parser: XMLParser, foundCharacters string: String) {\n        let trimmedString = string.trimmingCharacters(in: .whitespacesAndNewlines)\n        if !trimmedString.isEmpty {\n            switch currentElement {\n            case \"name\":\n                currentName += trimmedString\n            case \"age\":\n                if let age = Int(trimmedString) {\n                    currentAge = age\n                }\n            case \"email\":\n                currentEmail += trimmedString\n            default:\n                break\n            }\n        }\n    }\n\n    func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {\n        if elementName == \"person\" {\n            person = Person(name: currentName, age: currentAge, email: currentEmail)\n        }\n    }\n}\n\n/// *Paso 2: Leer y transformar los datos\n\nfunc readData(fromFile path: String) throws -> Data {\n    return try Data(contentsOf: URL(fileURLWithPath: path))\n}\n\nfunc createPerson(fromFile path: String) throws -> Person {\n    let data = try readData(fromFile: path)\n    if path.hasSuffix(\".json\") {\n        return try Person(fromJSON: data)\n    } else if path.hasSuffix(\".xml\") {\n        return try Person(fromXML: data)\n    } else {\n        throw NSError(domain: \"UnsupportedFileType\", code: 0, userInfo: nil)\n    }\n}\n\n/// *Paso 3: Borrar los archivos después de procesarlos\n\nfunc deleteFile(atPath path: String) throws {\n    try FileManager.default.removeItem(atPath: path)\n}\n\nfunc processAndDeleteFile(atPath path: String) {\n    do {\n        let person = try createPerson(fromFile: path)\n        print(\"Person created: \\(person)\")\n        try deleteFile(atPath: path)\n        print(\"File deleted: \\(path)\")\n    } catch {\n        print(\"Error processing file: \\(error)\")\n    }\n}\n\nlet jsonFilePath = \"path/to/your/file.json\"\nlet xmlFilePath = \"path/to/your/file.xml\"\n\nprocessAndDeleteFile(atPath: jsonFilePath)\nprocessAndDeleteFile(atPath: xmlFilePath)\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/swift/pedroomar23.swift",
    "content": "import Foundation\n\n/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n * \n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu \n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n */\n\nclass Perfil: Codable {\n    let nombre: String\n    let edad: Int\n    let nacimiento: String\n    let lenguajes: [String]\n    \n    init(nombre: String, edad: Int, nacimiento: String, lenguajes: [String]) {\n        self.nombre = nombre\n        self.edad = edad\n        self.nacimiento = nacimiento\n        self.lenguajes = lenguajes\n    }\n}\n\nfunc json() {\n    let person = Perfil(nombre: \"James\", edad: 35, nacimiento: \"20/03/1998\", lenguajes: [\"Swift\", \"Kotlin\", \"Java\"])\n    let encoder = JSONEncoder()\n    \n    if let url = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent(\"person.json\"),\n       let data = try? encoder.encode(person) {\n        try? data.write(to: url)\n        print(String(data: data, encoding: .utf8) ?? \"Error al convertir el json a String\")\n    }\n    \n    let personContent = \"\"\"\n        nombre: James\n        edad: 35\n        nacimiento: 20/03/1989\n        lenguajes: Swift, Kotlin, Java\n    \"\"\"\n    print(personContent)\n    \n    do {\n        try FileManager.default.removeItem(atPath: \"person.json\")\n    } catch {\n        print(\"Error el intantar borrar el archivo json \\(error.localizedDescription)\")\n    }\n}\n\nfunc xml() {\n    let person = Perfil(nombre: \"James\", edad: 35, nacimiento: \"20/03/1989\", lenguajes: [\"Swift\", \"Java\", \"Kotlin\"])\n    let encoder = JSONEncoder()\n    \n    if let url = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent(\"person.xml\"),\n       let data = try? encoder.encode(person) {\n        try? data.write(to: url)\n        print(String(data: data, encoding: .utf8) ?? \"Error al convertir el archivo a XML\")\n    }\n    \n    let personContent = \"\"\"\n        nombre: James\n        edad: 35\n        nacimiento: 20/03/1989\n        lenguajes: Swift, Java, Kotlin\n    \"\"\"\n    print(personContent)\n    \n    do {\n        try FileManager.default.removeItem(atPath: \"person.xml\")\n    } catch {\n        print(\"Error al intentar eliminar el archivo xml \\(error.localizedDescription)\")\n    }\n}\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/typescript/AChapeton.ts",
    "content": "const fs = require('fs')\nconst readlineSync = require('readline-sync');\nconst { DOMImplementation: ImplementationDOM, XMLSerializer: SerializeXML } = require('xmldom');\n\n// PARA CREAR ARCHIVO JSON\n\ninterface Content {\n  nombre: string,\n  edad: number,\n  fecha_de_nacimiento: string,\n  lista_lenguajes: Array<string>\n}\n\nlet jsonContent: Content = {\n  nombre: 'Andres Chapeton', \n  edad: 26, \n  fecha_de_nacimiento: '02/06/1997',\n  lista_lenguajes: ['TypeScript', 'JavaScript', 'Python', 'C#']\n} \n\nfs.writeFile(\n  'data.json', \n  JSON.stringify(jsonContent), \n  (error:  NodeJS.ErrnoException | null) => {\n  if(error) throw error\n  console.log('JSON file created')\n})\n\n//Leer contenido del fichero JSON\nfs.readFile('data.json', (error:  NodeJS.ErrnoException | null, data: any) => {\n  if(error) throw error\n  console.log(data.toString())\n})\n\n//Eliminar fichero JSON\nfs.unlink('data.json', (error:  NodeJS.ErrnoException | null) => {\n  if(error) throw error\n  console.log('JSON file deleted')\n})\n\n\n\n// PARA CREAR ARCHIVO XML\n\n// Crear un objeto DOMImplementation\nconst domImplementation = new ImplementationDOM();\n\n//Crear un objeto XML Document\nconst xmlBaseDoc: XMLDocument = domImplementation.createDocument(null, 'root')\n\n//Crear elementos y atributos\nconst main: HTMLElement = xmlBaseDoc.createElement('main')\nconst full_name: Attr = xmlBaseDoc.createAttribute('full_name')\nconst age: Attr = xmlBaseDoc.createAttribute('age')\nconst birth: Attr = xmlBaseDoc.createAttribute('birth')\nconst list: Attr = xmlBaseDoc.createAttribute('list')\n\n//Agregar valures\nfull_name.value = 'Andres Chapeton'\nage.value = '26'\nbirth.value = '02/06/1997'\nlist.value = 'TypeScript, JavaScript, Python, C#'\n\n//Agregar elementos al documento\nmain.setAttributeNode(full_name)\nmain.setAttributeNode(age)\nmain.setAttributeNode(birth)\nmain.setAttributeNode(list)\nmain.textContent = 'Datos'\nxmlBaseDoc.documentElement.appendChild(main)\n\n//Convertir documento XML en cadena de texto\nconst xmlString: string = new SerializeXML().serializeToString(xmlBaseDoc)\n\n\n//Crear fichero XML\nfs.writeFile(\n  'data.xml', \n  xmlString, \n  (error:  NodeJS.ErrnoException | null) => {\n  if(error) throw error\n  console.log('XML file created')\n})\n\n//Leer contenido del fichero XML\nfs.readFile('data.xml', (error:  NodeJS.ErrnoException | null, data: any) => {\n  if(error) throw error\n  const xmlString: string = data.toString()\n  console.log(xmlString)\n})\n\n//Eliminar fichero XML\nfs.unlink('data.xml', (error:  NodeJS.ErrnoException | null) => {\n  if(error) throw error\n  console.log('JSON file deleted')\n})"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/typescript/IgleDev.ts",
    "content": "//  1º Ejercicio\n    let fs = require('fs')\n    let readlineSync = require('readline-sync');\n    let { DOMImplementation: ImplementationDOM, XMLSerializer: SerializeXML } = require('xmldom');\n\n    // Para poder crear el archivo \n\n    interface Contenido {\n      nombre: string,\n      edad: number,\n      fecha_nacimiento: string,\n      lenguajes: Array<string>\n    }\n\n    let json: Contenido = {\n      nombre: 'Adrián Iglesias', \n      edad: 19, \n      fecha_nacimiento: '03/11/2004',\n      lenguajes: ['TypeScript', 'JavaScript', 'HTML', 'CSS']\n    } \n\n    fs.writeFile(\n      'info.json', \n      JSON.stringify(json), \n      (error:  NodeJS.ErrnoException | null) => {\n      if(error) throw error\n      console.log('JSON creado!')\n    })\n\n    //Leer contenido del fichero JSON\n    fs.readFile('info.json', (error:  NodeJS.ErrnoException | null, data: any) => {\n      if(error) throw error\n      console.log(data.toString())\n    })\n\n    //Eliminar fichero JSON\n    fs.unlink('info.json', (error:  NodeJS.ErrnoException | null) => {\n      if(error) throw error\n      console.log('JSON borrado!')\n    })\n\n\n\n    // PARA CREAR ARCHIVO XML\n\n    // Crear un objeto DOMImplementation\n    let domImplementation = new ImplementationDOM();\n\n    //Crear un objeto XML Document\n    let xmlBaseDoc: XMLDocument = domImplementation.createDocument(null, 'root');\n\n    //Crear elementos y atributos\n    let main: HTMLElement = xmlBaseDoc.createElement('main');\n    let nombre: Attr = xmlBaseDoc.createAttribute('nombre');\n    let edad: Attr = xmlBaseDoc.createAttribute('edad');\n    let fecha_nacimiento: Attr = xmlBaseDoc.createAttribute('fecha_nacimiento');\n    let lenguajes: Attr = xmlBaseDoc.createAttribute('lenguajes');\n\n    //Agregamos los valores\n    nombre.value = 'Adrián Iglesias'\n    edad.value = '19'\n    fecha_nacimiento.value = '03/11/2004'\n    lenguajes.value = 'TypeScript, JavaScript, HTML, CSS'\n\n    //Agregar elementos al documento\n    main.setAttributeNode(nombre)\n    main.setAttributeNode(edad)\n    main.setAttributeNode(fecha_nacimiento)\n    main.setAttributeNode(lenguajes)\n    main.textContent = 'Informacion'\n    xmlBaseDoc.documentElement.appendChild(main)\n\n    //Convertir documento XML en cadena de texto\n    let xmlString: string = new SerializeXML().serializeToString(xmlBaseDoc)\n\n\n    //Crear fichero XML\n    fs.writeFile(\n      'info.xml', \n      xmlString, \n      (error:  NodeJS.ErrnoException | null) => {\n      if(error) throw error\n      console.log('XML creado!')\n    })\n\n    //Leer contenido del fichero XML\n    fs.readFile('info.xml', (error:  NodeJS.ErrnoException | null, data: any) => {\n      if(error) throw error\n      let xmlString: string = data.toString()\n      console.log(xmlString)\n    })\n\n    //Eliminar fichero XML\n    fs.unlink('info.xml', (error:  NodeJS.ErrnoException | null) => {\n      if(error) throw error\n      console.log('JSON borrado')\n    })"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/typescript/Sac-Corts.ts",
    "content": "import * as fs from 'fs';\n\ninterface PersonData {\n    name: string;\n    age: number;\n    birthdate: string;\n    programmingLanguage: string[];\n}\n\nconst data: PersonData = {\n    name: 'Isaac Cortés',\n    age: 22,\n    birthdate: \"2001-10-21\",\n    programmingLanguage: [\"JavaScript\", \"Python\"]\n};\n\nfs.writeFileSync('data.json', JSON.stringify(data, null, 4));\n\nlet xmlData2 = `<?xml version =\"1.0\" encoding=\"UTF-8\"?>\n<person>\n    <name>${data.name}</name>\n    <age>${data.age}</age>\n    <birthdate>${data.birthdate}</birthdate>\n    <programmingLanguage>${data.programmingLanguage.map(lang => `<language>${lang}</language>`).join('\\n     ')}</programmingLanguage>\n</person>`;\n\nfs.writeFileSync('data.xml', xmlData2);\n\nconsole.log(\"Content of data.json:\");\nconsole.log(fs.readFileSync('data.json', 'utf8'));\n\nconsole.log(\"\\nContent of data.xml:\");\nconsole.log(fs.readFileSync('data.xml', 'utf8'));\n\n// ** Extra Exercise ** //\n\nclass Person {\n    name: string;\n    age: number;\n    birthdate: string;\n    programmingLanguage: string[];\n\n    constructor(name: string, age: number, birthdate: string, programmingLanguage: string[]) {\n        this.name = name;\n        this.age = age;\n        this.birthdate = birthdate;\n        this.programmingLanguage = programmingLanguage;\n    }\n\n    showData(): void {\n        console.log(`Name: ${this.name}`);\n        console.log(`Age: ${this.age}`);\n        console.log(`Birthdate: ${this.birthdate}`);\n        console.log(`Programming Language: ${this.programmingLanguage.join(', ')}`);\n    }\n}\n\n// Read JSON and XML file\nconst jsonContent: string = fs.readFileSync('data.json', 'utf-8');\nconst xmlContent: string = fs.readFileSync('data.xml', 'utf-8');\n\n// Parse JSON and XML in JavaScript\nconst jsonData: PersonData = JSON.parse(jsonContent);\n\nfunction parseXML(xml: string): PersonData {\n    const name = xml.match(/<name>(.*?)<\\/name>/)![1];\n    const age = parseInt(xml.match(/<age>(.*?)<\\/age>/)![1], 10);\n    const birthdate = xml.match(/<birthdate>(.*?)<\\/birthdate>/)![1];\n    const languagesMatches = xml.match(/<language>(.*?)<\\/language>/g);\n    const programmingLanguage = languagesMatches!.map(lang => lang.replace(/<\\/?language>/g,  ''));\n\n    return {\n        name,\n        age,\n        birthdate,\n        programmingLanguage\n    };\n}\n\nconst xmlData: PersonData = parseXML(xmlContent);\n\n// Create instances of the class with the read data\nconst personFromJson = new Person(\n    jsonData.name,\n    jsonData.age,\n    jsonData.birthdate,\n    jsonData.programmingLanguage\n);\n\nconst personFromXml = new Person(\n    xmlData.name,\n    xmlData.age,\n    xmlData.birthdate,\n    xmlData.programmingLanguage\n);\n\n// Show data for class instances\nconsole.log(\"Data from JSON:\");\npersonFromJson.showData();\n\nconsole.log(\"\\nData from XML:\");\npersonFromXml.showData();\n\n// Delete the files\nfs.unlinkSync('data.json');\nfs.unlinkSync('data.xml');\nconsole.log(\"\\nDeleted files.\");\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/typescript/david-git-dev.ts",
    "content": "import * as fs from 'fs';\nimport * as path from 'path';\nimport * as xmlbuilder from 'xmlbuilder';\nimport { parseString } from 'xml2js';\n/*\nconst rutaArchivo = path.resolve('david-git-dev.txt');\n\nfs.appendFileSync(rutaArchivo,'Nombre: David\\n');\nfs.appendFileSync(rutaArchivo,'Edad: 25 años\\n',);\nfs.appendFileSync(rutaArchivo,'Lenguajes de programacion favoritos: Javascript , Typescript,PHP,Flutter,Java\\n',);//agregando datos\nconst data = fs.readFileSync(rutaArchivo,'utf8')//leyendo archivo\nconsole.log(`Archivo creado en: ${rutaArchivo}\\n con el contenido: \\n ${data}`);\nfs.unlinkSync(rutaArchivo) // borrando el archivo\n//fs.writeFileSync(ruta,json) */\n/*\n * IMPORTANTE: Sólo debes subir el fichero de código como parte del ejercicio.\n *\n * EJERCICIO:\n * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n * - Nombre\n * - Edad\n * - Fecha de nacimiento\n * - Listado de lenguajes de programación\n * Muestra el contenido de los archivos.\n * Borra los archivos.\n*/\nclass Ejercicio{\n  private _data= {\n    nombre: \"david\",\n    edad: 25,\n    fechaDeNacimiento: new Date(1999, 5, 13).toLocaleDateString(),\n    lenguages: [\"javascript\", \"php\", \"java\"],\n  };\ncreateXML(){\n  // let xml ='<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n';\n  const xml = xmlbuilder.create('persona')\n  .ele('nombre', this._data.nombre).up()\n  .ele('edad', this._data.edad).up()\n  .ele('fechaDeNacimiento', this._data.fechaDeNacimiento).up()\n  .ele('lenguajesDeProgramacion')\n    .ele('lenguaje', this._data.lenguages[0] as string).up()\n    .ele('lenguaje', this._data.lenguages[1]).up()\n    .ele('lenguaje', this._data.lenguages[2]).up()\n  .end({ pretty: true });\n\nfs.writeFileSync('data.xml', xml);\nconst filePath = path.resolve('data.xml')\nconst data = fs.readFileSync(filePath,'utf8')\nconsole.log(data)\nfs.unlinkSync(filePath)\n}\ncreateJSON(){\n  const url = path.resolve('data.json')\n  fs.writeFileSync(url,JSON.stringify(this._data))\n  const data = fs.readFileSync(url,'utf8')\n  console.log(data)\n  fs.unlinkSync(url)\n}\n}\nconst ejercicio = new Ejercicio();\nejercicio.createJSON()\nejercicio.createXML()\n\n/*DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu\n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n * */\nclass Custom {\n  private _data= {\n    nombre: \"david\",\n    edad: 25,\n    fechaDeNacimiento: new Date(1999, 5, 13).toLocaleDateString(),\n    lenguages: [\"javascript\", \"php\", \"java\"],\n  };\n  private _filePath: string;\n  constructor(path:string){\n    this._filePath = path\n  }\n  createXML(){\n    // let xml ='<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n';\n    const xml = xmlbuilder.create('persona')\n    .ele('nombre', this._data.nombre).up()\n    .ele('edad', this._data.edad).up()\n    .ele('fechaDeNacimiento', this._data.fechaDeNacimiento).up()\n    .ele('lenguajesDeProgramacion')\n      .ele('lenguaje', this._data.lenguages[0] as string).up()\n      .ele('lenguaje', this._data.lenguages[1]).up()\n      .ele('lenguaje', this._data.lenguages[2]).up()\n    .end({ pretty: true });\n\n  fs.writeFileSync('data.xml', xml);\n  const filePath = path.resolve('data.xml')\n  const data = fs.readFileSync(filePath,'utf8')\n  console.log(data)\n//fs.unlinkSync(filePath)\n  }\n  createJSON(){\n    const filePath = path.resolve('data.json')\n    fs.writeFileSync(filePath,JSON.stringify(this._data))\n    const data = fs.readFileSync(filePath,'utf8')\n    console.log(data)\n//fs.unlinkSync(filePath)\n  }\n  transformJSON() {\n    const filePath = path.resolve('data.json');\n    const data = fs.readFileSync(filePath,'utf-8');\n    console.log (JSON.stringify(JSON.parse(data)))\n    fs.unlinkSync(filePath)\n  }\ntransformXML(){\n  const filePath = path.resolve(this._filePath);\n  const xml = fs.readFileSync(filePath)\n  parseString(xml, (err:any, result:any) => {\n    if (err) {\n      console.error('Error parsing XML:', err);\n      return;\n    }\n    console.log(JSON.stringify(result, null, 2));\n  });\n  fs.unlinkSync(filePath)\n}\n}\nconst transform = new Custom('data.xml');\ntransform.createJSON()\ntransform.createXML()\ntransform.transformXML()\ntransform.transformJSON()"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/typescript/duendeintemporal.ts",
    "content": "/**\n * #12 { retosparaprogramadores } JSON and XML Handling in TypeScript\n * \n * Bibliography:\n * - Secrets of the JavaScript Ninja (John Resig, Bear Bibeault, Josip Maras) (z-lib.org)\n * - Professional JavaScript for Web Developers by Matt Frisbie [Frisbie, Matt] (z-lib.org)\n * - JavaScript Notes for Professionals (GoalKicker.com) (Z-Library)\n * - GPT & Deepseek\n * \n * Note: We will use Node.js and the `xmldom` and `node-fetch` libraries.\n * You can install them using:\n * npm install xmldom\n * npm install node-fetch\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { DOMParser } from 'xmldom';\n\n// Short for console.log\nconst log = console.log;\n\n/**\n * JSON (JavaScript Object Notation)\n * \n * JSON is a data serialization format that resembles JavaScript object literals.\n * However, it is not JavaScript and should not be directly executed (e.g., using `eval()`).\n * JSON is functionally similar to XML or YAML but is more lightweight and easier to parse.\n * \n * Key Points:\n * - JSON strictly requires double quotes for property names and string values.\n * - JSON is not limited to objects or arrays; it can represent any serializable value.\n */\n\n/**\n * JSON.parse\n * Parses a JSON string into a JavaScript value.\n * \n * @param text - The JSON string to parse.\n * @param reviver - A function to transform the parsed value.\n * @returns The parsed JavaScript value.\n */\n\n/**\n * JSON.stringify\n * Serializes a JavaScript value into a JSON string.\n * \n * @param value - The value to serialize.\n * @param replacer - A function or array to filter or transform properties.\n * @param space - Controls indentation in the output string.\n * @returns The JSON string representation of the value.\n */\n\n// Example: JSON vs JavaScript Literals\nconst nickname = { \"nickname\": \"mytic.dragon\" }; // Valid JSON and JavaScript\n// const nickname = { nickname: \"mytic.dragon\" }; // Valid JavaScript, invalid JSON\n// const nickname = { 'nickname': 'mytic.dragon' }; // Valid JavaScript, invalid JSON\n\n/**\n * Parsing JSON with a Reviver Function\n * A reviver function can filter or transform the parsed value.\n */\nconst jsonString = '[{\"name\":\"Kox\",\"age\":51},{\"name\":\"Fanny\",\"age\":17}]';\nconst data = JSON.parse(jsonString, (key, value) => key === 'name' ? value.toUpperCase() : value);\nlog(data); // [{name: \"KOX\", age: 51}, {name: \"FANNY\", age: 17}]\n\n/**\n * Parsing Dates in JSON\n * Dates are often serialized as ISO 8601 strings. Use a reviver to parse them into Date objects.\n */\nconst jsonString2 = '{\"date\":\"2024-10-12T12:28:40.143Z\"}';\nconst data2 = JSON.parse(jsonString2, (key, value) => key === 'date' ? new Date(value) : value);\nlog(data2); // { date: 2024-10-12T12:28:40.143Z }\n\n/**\n * JSON.stringify Examples\n */\nlog(JSON.stringify(true)); // 'true'\nlog(JSON.stringify(154)); // '154'\nlog(JSON.stringify('roadmap')); // '\"roadmap\"'\nlog(JSON.stringify({})); // '{}'\nlog(JSON.stringify({ name: 'Any' })); // '{\"name\": \"Any\"}'\nlog(JSON.stringify([41, true, 'System Engineering'])); // '[41, true, \"System Engineering\"]'\nlog(JSON.stringify(new Date())); // possible output: '\"2025-02-24T09:59:25.526Z\"'\nlog(JSON.stringify({ x: Symbol() })); // '{}'\n\n/**\n * Replacer Function\n * Filters or transforms properties during stringification.\n */\nfunction notStrValues(key: string, value: any): any {\n    if (typeof value === \"string\") {\n        return undefined; // Exclude string values\n    }\n    return value;\n}\n\nconst crew = { background: \"Retosparaprogramadores\", model: \"weekly\", week: 12, language: \"javascript\", month: 3 };\nlog(JSON.stringify(crew, notStrValues)); // '{\"week\": 12, \"month\": 3}'\n\n/**\n * Replacer as an Array\n * Whitelists specific properties for stringification.\n */\nlog(JSON.stringify(crew, ['background', 'week', 'month'])); // '{\"background\": \"Retosparaprogramadores\", \"week\": 12, \"month\": 3}'\n\n/**\n * Indentation in JSON.stringify\n */\nlog(JSON.stringify({ x: 4, y: 4 }, null, 2)); // Indents with 2 spaces\nlog(JSON.stringify({ x: 4, y: 4 }, null, '\\t')); // Indents with tabs\n\n/*\n{\n  \"x\": 4,\n  \"y\": 4\n}\n{\n        \"x\": 4,\n        \"y\": 4\n}\n*/\n/**\n * Exercises: JSON and XML File Handling\n */\n\n// Data to save\nconst data1 = {\n    name: \"Niko Zen\",\n    age: 30,\n    birthDate: \"1983-08-08\",\n    languages: [\"JavaScript\", \"Python\", \"Ruby\", \"Rust\", \"Bash\"]\n};\n\n/**\n * Creates a JSON file from the given data.\n * @param data - The data to serialize into JSON.\n */\nfunction createJSON(data: any): void {\n    const jsonData = JSON.stringify(data, null, 2);\n    fs.writeFileSync(path.join(__dirname, 'data.json'), jsonData);\n    log(\"Content of the JSON file:\");\n    log(jsonData);\n}\n\n/**\n * Creates an XML file from the given data.\n * @param data - The data to serialize into XML.\n */\nfunction createXML(data: any): void {\n    const xmlData = `\n<person>\n    <name>${data.name}</name>\n    <age>${data.age}</age>\n    <birthDate>${data.birthDate}</birthDate>\n    <languages>\n        ${data.languages.map((lang: string) => `<language>${lang}</language>`).join('')}\n    </languages>\n</person>`;\n    fs.writeFileSync(path.join(__dirname, 'data.xml'), xmlData);\n    log(\"Content of the XML file:\");\n    log(xmlData);\n}\n\n/**\n * Deletes the JSON and XML files.\n */\nfunction deleteFiles(): void {\n    fs.unlinkSync(path.join(__dirname, 'data.json'));\n    fs.unlinkSync(path.join(__dirname, 'data.xml'));\n    log(\"Files deleted.\");\n}\n\n/**\n * Custom Person Class\n */\nclass Person {\n    constructor(\n        public name: string,\n        public age: number,\n        public birthDate: string,\n        public languages: string[]\n    ) {}\n}\n\n/**\n * Reads and transforms data from JSON and XML files.\n */\nfunction readAndTransform(): void {\n    const jsonData = JSON.parse(fs.readFileSync(path.join(__dirname, 'data.json'), 'utf-8'));\n    const xmlData = fs.readFileSync(path.join(__dirname, 'data.xml'), 'utf-8');\n\n    // Transform XML to object\n    const parser = new DOMParser();\n    const xmlDoc = parser.parseFromString(xmlData, \"text/xml\");\n    const name = xmlDoc.getElementsByTagName(\"name\")[0].textContent || \"\";\n    const age = parseInt(xmlDoc.getElementsByTagName(\"age\")[0].textContent || \"0\");\n    const birthDate = xmlDoc.getElementsByTagName(\"birthDate\")[0].textContent || \"\";\n    const languages = Array.from(xmlDoc.getElementsByTagName(\"language\")).map(lang => lang.textContent || \"\");\n\n    // Create an instance of Person\n    const person = new Person(name, age, birthDate, languages);\n    log(\"Data transformed to Person class:\");\n    log(person);\n}\n\n// Program execution\ncreateJSON(data1);\ncreateXML(data1);\nreadAndTransform();\ndeleteFiles();\n\n/* Output:\nContent of the JSON file:\n{\n  \"name\": \"Niko Zen\",\n  \"age\": 30,\n  \"birthDate\": \"1983-08-08\",\n  \"languages\": [\n    \"JavaScript\",\n    \"Python\",\n    \"Ruby\",\n    \"Rust\",\n    \"Bash\"\n  ]\n}\nContent of the XML file:\n\n<person>\n    <name>Niko Zen</name>\n    <age>30</age>\n    <birthDate>1983-08-08</birthDate>\n    <languages>\n        <language>JavaScript</language><language>Python</language><language>Ruby</language><language>Rust</language><language>Bash</language>\n    </languages>\n</person>\nData transformed to Person class:\nPerson {\n  name: 'Niko Zen',\n  age: 30,\n  birthDate: '1983-08-08',\n  languages: [ 'JavaScript', 'Python', 'Ruby', 'Rust', 'Bash' ]\n}\nFiles deleted. */"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/typescript/eulogioep.ts",
    "content": "import * as fs from 'fs';\nimport * as xml2js from 'xml2js';\n\n// Definición de la interfaz para la estructura de datos de la persona\ninterface Persona {\n    nombre: string;\n    edad: number;\n    fechaNacimiento: string;\n    lenguajesProgramacion: string[];\n}\n\n// Datos de ejemplo\nconst persona: Persona = {\n    nombre: \"Juan\",\n    edad: 30,\n    fechaNacimiento: \"1993-05-15\",\n    lenguajesProgramacion: [\"TypeScript\", \"JavaScript\", \"Python\"]\n};\n\n// Función para crear el archivo XML\nfunction crearArchivoXML(datos: Persona): void {\n    const builder = new xml2js.Builder();\n    const xml = builder.buildObject({ persona: datos });\n    fs.writeFileSync('datos.xml', xml);\n    console.log(\"Archivo XML creado.\");\n}\n\n// Función para crear el archivo JSON\nfunction crearArchivoJSON(datos: Persona): void {\n    fs.writeFileSync('datos.json', JSON.stringify(datos, null, 2));\n    console.log(\"Archivo JSON creado.\");\n}\n\n// Función para mostrar el contenido de un archivo\nfunction mostrarContenidoArchivo(nombreArchivo: string): void {\n    console.log(`Contenido del archivo ${nombreArchivo}:`);\n    console.log(fs.readFileSync(nombreArchivo, 'utf8'));\n}\n\n// Función para borrar un archivo\nfunction borrarArchivo(nombreArchivo: string): void {\n    fs.unlinkSync(nombreArchivo);\n    console.log(`El archivo ${nombreArchivo} ha sido borrado.`);\n}\n\n// Función para leer el archivo XML\nasync function leerXML(nombreArchivo: string): Promise<Persona> {\n    const xmlData = fs.readFileSync(nombreArchivo, 'utf8');\n    return new Promise((resolve, reject) => {\n        xml2js.parseString(xmlData, (err, result) => {\n            if (err) {\n                reject(err);\n            } else {\n                resolve(result.persona as Persona);\n            }\n        });\n    });\n}\n\n// Función para leer el archivo JSON\nfunction leerJSON(nombreArchivo: string): Persona {\n    const jsonData = fs.readFileSync(nombreArchivo, 'utf8');\n    return JSON.parse(jsonData) as Persona;\n}\n\n// Función principal asíncrona\nasync function main(): Promise<void> {\n    // Crear y mostrar archivo XML\n    crearArchivoXML(persona);\n    mostrarContenidoArchivo('datos.xml');\n\n    // Crear y mostrar archivo JSON\n    crearArchivoJSON(persona);\n    mostrarContenidoArchivo('datos.json');\n\n    // Borrar archivos\n    borrarArchivo('datos.xml');\n    borrarArchivo('datos.json');\n\n    // DIFICULTAD EXTRA\n    // Crear archivos nuevamente para la lectura\n    crearArchivoXML(persona);\n    crearArchivoJSON(persona);\n\n    try {\n        // Leer y transformar datos\n        const personaXML = await leerXML('datos.xml');\n        const personaJSON = leerJSON('datos.json');\n\n        console.log(\"\\nDatos leídos del XML:\");\n        console.log(personaXML);\n        console.log(\"\\nDatos leídos del JSON:\");\n        console.log(personaJSON);\n    } catch (error) {\n        console.error(\"Error al leer los archivos:\", error);\n    }\n\n    // Borrar archivos nuevamente\n    borrarArchivo('datos.xml');\n    borrarArchivo('datos.json');\n}\n\n// Ejecutar la función principal\nmain().catch(console.error);"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/typescript/hozlucas28.ts",
    "content": "import * as fs from 'node:fs'\nimport * as readline from 'readline-sync'\n\n/*\n    JSON and XML files...\n*/\n\nconsole.log('JSON and XML files...')\n\nconsole.log(`type FileBasename = \\`\\${string}.\\${string}\\`\n\ntype Content<AsXML extends boolean = false> = AsXML extends true\n    ? {\n            age: number\n            name: string\n            'born-date': Date\n            'programming-languages': Record<string, string>\n      }\n    : {\n            age: number\n            bornDate: Date\n            name: string\n            programmingLanguages: string[]\n      }\n\nfunction stringifyXml<T extends Record<string, unknown>>(\n    content: T,\n    forceLineBreak: boolean = false\n) {\n    let stringifiedContent: string = ''\n\n    for (const key of Object.keys(content)) {\n        const line =\n            typeof content[key] === 'object' && !(content[key] instanceof Date)\n                ? stringifyXml(content[key] as Record<string, unknown>, true)\n                : content[key]\n        const lineBreak =\n            forceLineBreak || stringifiedContent.length > 0 ? '\\\\n' : ''\n        stringifiedContent += \\`\\${lineBreak}<\\${key}>\\${line}</\\${key}>\\`\n    }\n\n    return stringifiedContent\n}\n\nconst jsonFilePath: FileBasename = 'author.json'\nconst xmlFilePath: FileBasename = 'author.xml'\n\n// Delete files if exist\nif (fs.existsSync(jsonFilePath)) fs.rmSync(jsonFilePath)\nif (fs.existsSync(xmlFilePath)) fs.rmSync(xmlFilePath)\n\n// Format contents\nconst jsonNewContent: Content = {\n    age: 22,\n    bornDate: new Date(2002, 1, 20),\n    name: 'Lucas',\n    programmingLanguages: ['TypeScript', 'Python', 'Go (Golang)'],\n}\n\nconst xmlNewContent: Content<true> = {\n    age: 22,\n    name: 'Lucas',\n    'born-date': new Date(2002, 1, 20),\n    'programming-languages': {\n        typescript: 'TypeScript',\n        python: 'Python',\n        go: 'Go (Golang)',\n    },\n}\n\n// Write files\nconst stringifiedJsonContent: string = JSON.stringify(jsonNewContent)\nconst stringifiedXmlContent: string = stringifyXml(xmlNewContent)\n\nfs.writeFileSync(jsonFilePath, stringifiedJsonContent, { encoding: 'utf-8' })\nfs.writeFileSync(xmlFilePath, stringifiedXmlContent, { encoding: 'utf-8' })\n\n// Print files content\nconst jsonContent = fs.readFileSync(jsonFilePath, { encoding: 'utf-8' })\nconst xmlContent = fs.readFileSync(xmlFilePath, { encoding: 'utf-8' })\n\nconsole.log(\\`\\\\n\\${jsonContent}\\`)\nconsole.log(\\`\\\\n\\${xmlContent}\\`)\n\n// Delete files\nfs.rmSync(xmlFilePath)\nfs.rmSync(jsonFilePath)`)\n\ntype FileBasename = `${string}.${string}`\n\ntype Content<AsXML extends boolean = false> = AsXML extends true\n\t? {\n\t\t\tage: number\n\t\t\tname: string\n\t\t\t'born-date': Date\n\t\t\t'programming-languages': Record<string, string>\n\t  }\n\t: {\n\t\t\tage: number\n\t\t\tbornDate: Date\n\t\t\tname: string\n\t\t\tprogrammingLanguages: string[]\n\t  }\n\nfunction stringifyXml<T extends Record<string, unknown>>(\n\tcontent: T,\n\tforceLineBreak: boolean = false\n) {\n\tlet stringifiedContent: string = ''\n\n\tfor (const key of Object.keys(content)) {\n\t\tconst line =\n\t\t\ttypeof content[key] === 'object' && !(content[key] instanceof Date)\n\t\t\t\t? stringifyXml(content[key] as Record<string, unknown>, true)\n\t\t\t\t: content[key]\n\t\tconst lineBreak =\n\t\t\tforceLineBreak || stringifiedContent.length > 0 ? '\\n' : ''\n\t\tstringifiedContent += `${lineBreak}<${key}>${line}</${key}>`\n\t}\n\n\treturn stringifiedContent\n}\n\nconst jsonFilePath: FileBasename = 'author.json'\nconst xmlFilePath: FileBasename = 'author.xml'\n\n// Delete files if exist\nif (fs.existsSync(jsonFilePath)) fs.rmSync(jsonFilePath)\nif (fs.existsSync(xmlFilePath)) fs.rmSync(xmlFilePath)\n\n// Format contents\nconst jsonNewContent: Content = {\n\tage: 22,\n\tbornDate: new Date(2002, 1, 20),\n\tname: 'Lucas',\n\tprogrammingLanguages: ['TypeScript', 'Python', 'Go (Golang)'],\n}\n\nconst xmlNewContent: Content<true> = {\n\tage: 22,\n\tname: 'Lucas',\n\t'born-date': new Date(2002, 1, 20),\n\t'programming-languages': {\n\t\ttypescript: 'TypeScript',\n\t\tpython: 'Python',\n\t\tgo: 'Go (Golang)',\n\t},\n}\n\n// Write files\nconst stringifiedJsonContent: string = JSON.stringify(jsonNewContent)\nconst stringifiedXmlContent: string = stringifyXml(xmlNewContent)\n\nfs.writeFileSync(jsonFilePath, stringifiedJsonContent, { encoding: 'utf-8' })\nfs.writeFileSync(xmlFilePath, stringifiedXmlContent, { encoding: 'utf-8' })\n\n// Print files content\nconst jsonContent = fs.readFileSync(jsonFilePath, { encoding: 'utf-8' })\nconst xmlContent = fs.readFileSync(xmlFilePath, { encoding: 'utf-8' })\n\nconsole.log(`\\n${jsonContent}`)\nconsole.log(`\\n${xmlContent}`)\n\n// Delete files\nfs.rmSync(xmlFilePath)\nfs.rmSync(jsonFilePath)\n\nconsole.log(\n\t'\\n# ---------------------------------------------------------------------------------- #\\n'\n)\n\n/*\n    Additional challenge...\n*/\n\nconsole.log('Additional challenge...')\n\nclass JsonFile {\n\tprivate path: string\n\tprivate isDeleted: boolean\n\n\tconstructor(path: string, initialContent: Content) {\n\t\tthis.path = `${path}.json`\n\t\tthis.isDeleted = false\n\t\tthis.rewriteContent(initialContent)\n\t}\n\n\tpublic getContent(): Content {\n\t\tthis.validate()\n\t\tconst content: string = fs.readFileSync(this.path, { encoding: 'utf-8' })\n\t\tconst parsedContent: Content = JSON.parse(content)\n\t\treturn parsedContent\n\t}\n\n\tprivate rewriteContent(content: Content): this {\n\t\tconst stringifiedContent = JSON.stringify(content)\n\t\tfs.writeFileSync(this.path, stringifiedContent, {\n\t\t\tencoding: 'utf-8',\n\t\t})\n\n\t\treturn this\n\t}\n\n\tprivate validate(): never | void {\n\t\tif (this.isDeleted) throw new Error('The file was deleted!')\n\t}\n\n\tpublic appendProgrammingLanguage(programmingLanguage: string): this {\n\t\tthis.validate()\n\n\t\tconst content: Content = this.getContent()\n\t\tif (\n\t\t\t!content.programmingLanguages.some(\n\t\t\t\t(language) =>\n\t\t\t\t\tlanguage.toUpperCase() === programmingLanguage.toUpperCase()\n\t\t\t)\n\t\t) {\n\t\t\tcontent.programmingLanguages.push(programmingLanguage)\n\t\t\tthis.rewriteContent(content)\n\t\t}\n\n\t\treturn this\n\t}\n\n\tpublic deleteFile(): void {\n\t\tthis.validate()\n\n\t\tthis.isDeleted = true\n\t\tfs.rmSync(this.path)\n\t}\n\n\tpublic removeProgrammingLanguage(programmingLanguage: string): this {\n\t\tthis.validate()\n\n\t\tconst content: Content = this.getContent()\n\t\tcontent.programmingLanguages = content.programmingLanguages.filter(\n\t\t\t(language) => language.toUpperCase() !== programmingLanguage.toUpperCase()\n\t\t)\n\t\tthis.rewriteContent(content)\n\t\treturn this\n\t}\n\n\tpublic updateAge(newAge: number): this {\n\t\tthis.validate()\n\n\t\tconst content: Content = this.getContent()\n\t\tcontent.age = newAge\n\t\tthis.rewriteContent(content)\n\t\treturn this\n\t}\n\n\tpublic updateName(newName: string): this {\n\t\tthis.validate()\n\n\t\tconst content: Content = this.getContent()\n\t\tcontent.name = newName\n\t\tthis.rewriteContent(content)\n\t\treturn this\n\t}\n\n\tpublic updateBornDate(newDate: Date): this {\n\t\tthis.validate()\n\n\t\tconst content: Content = this.getContent()\n\t\tcontent.bornDate = newDate\n\t\tthis.rewriteContent(content)\n\t\treturn this\n\t}\n}\n\nclass XmlFile {\n\tprivate path: string\n\tprivate isDeleted: boolean\n\n\tconstructor(path: string, initialContent: Content<true>) {\n\t\tthis.path = `${path}.xml`\n\t\tthis.isDeleted = false\n\t\tthis.rewriteContent(initialContent)\n\t}\n\n\tpublic getContent(): Content<true> {\n\t\tthis.validate()\n\n\t\tconst content: string = fs.readFileSync(this.path, { encoding: 'utf-8' })\n\t\tconst parsedContent: Content<true> = this.parseContent(content)\n\t\treturn parsedContent\n\t}\n\n\tprivate parseContent(content: string): Content<true> {\n\t\tconst parsedContent: Content<true> = {\n\t\t\tage: 0,\n\t\t\tname: '',\n\t\t\t'programming-languages': {},\n\t\t\t'born-date': new Date(),\n\t\t}\n\n\t\tfor (const line of content.split('\\n')) {\n\t\t\tconst match = line.match(/<([\\w|-]*)>(.*)</)\n\t\t\tif (!match) continue\n\n\t\t\tconst [, tag, content] = match as [string, keyof Content<true>, string]\n\n\t\t\tif (tag === 'age') {\n\t\t\t\tparsedContent.age = parseInt(content)\n\t\t\t} else if (tag === 'name') {\n\t\t\t\tparsedContent.name = content\n\t\t\t} else if (tag === 'born-date') {\n\t\t\t\t// @ts-expect-error\n\t\t\t\tparsedContent['born-date'] = content\n\t\t\t} else {\n\t\t\t\tparsedContent['programming-languages'] = {\n\t\t\t\t\t...parsedContent['programming-languages'],\n\t\t\t\t\t[tag]: content,\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn parsedContent\n\t}\n\n\tprivate rewriteContent(content: Content<true>): this {\n\t\tconst stringifiedContent: string = this.stringifiedContent(content)\n\t\tfs.writeFileSync(this.path, stringifiedContent, { encoding: 'utf-8' })\n\t\treturn this\n\t}\n\n\tprivate stringifiedContent(\n\t\tcontent: Content<true> | Content<true>['programming-languages'],\n\t\tstartLineBreak: boolean = false,\n\t\tendLineBreak: boolean = false\n\t): string {\n\t\tlet stringifiedContent: string = ''\n\n\t\tfor (const key of Object.keys(content) as (keyof typeof content)[]) {\n\t\t\tconst lineBreak = startLineBreak || stringifiedContent ? '\\n' : ''\n\t\t\tconst lineBreakEnd = endLineBreak ? '\\n' : ''\n\n\t\t\tconst line =\n\t\t\t\ttypeof content[key] === 'object' && !(content[key] instanceof Date)\n\t\t\t\t\t? this.stringifiedContent(\n\t\t\t\t\t\t\tcontent[key] as Content<true>['programming-languages'],\n\t\t\t\t\t\t\ttrue,\n\t\t\t\t\t\t\ttrue\n\t\t\t\t\t  )\n\t\t\t\t\t: content[key]\n\t\t\tstringifiedContent += `${lineBreak}<${key}>${line}</${key}>${lineBreakEnd}`\n\t\t}\n\n\t\treturn stringifiedContent\n\t}\n\n\tprivate validate(): never | void {\n\t\tif (this.isDeleted) {\n\t\t\tthrow new Error('The file was deleted!')\n\t\t}\n\t}\n\n\tpublic appendProgrammingLanguage(programmingLanguage: string): this {\n\t\tconst content: Content<true> = this.getContent()\n\n\t\tObject.assign<Content<true>, Partial<Content<true>>>(content, {\n\t\t\t'programming-languages': {\n\t\t\t\t...content['programming-languages'],\n\t\t\t\t[programmingLanguage.toLowerCase()]: programmingLanguage,\n\t\t\t},\n\t\t})\n\t\tthis.rewriteContent(content)\n\n\t\treturn this\n\t}\n\n\tpublic deleteFile(): void {\n\t\tthis.validate()\n\n\t\tthis.isDeleted = true\n\t\tfs.rmSync(this.path)\n\t}\n\n\tpublic removeProgrammingLanguage(programmingLanguage: string): this {\n\t\tconst content: Content<true> = this.getContent()\n\t\tlet sanitizedProgrammingLanguages: Content<true>['programming-languages'] =\n\t\t\t{}\n\n\t\tfor (const key of Object.keys(content['programming-languages'])) {\n\t\t\tif (key.toLowerCase() !== programmingLanguage.toLowerCase()) {\n\t\t\t\tsanitizedProgrammingLanguages = {\n\t\t\t\t\t...sanitizedProgrammingLanguages,\n\t\t\t\t\t[key]: content['programming-languages'][key],\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tcontent['programming-languages'] = sanitizedProgrammingLanguages\n\t\tthis.rewriteContent(content)\n\n\t\treturn this\n\t}\n\n\tpublic updateAge(newAge: number): this {\n\t\tconst content: Content<true> = this.getContent()\n\t\tcontent.age = newAge\n\t\tthis.rewriteContent(content)\n\t\treturn this\n\t}\n\n\tpublic updateName(newName: string): this {\n\t\tconst content: Content<true> = this.getContent()\n\t\tcontent.name = newName\n\t\tthis.rewriteContent(content)\n\t\treturn this\n\t}\n\n\tpublic updateBornDate(newBornDate: Date): this {\n\t\tconst content: Content<true> = this.getContent()\n\t\tcontent['born-date'] = newBornDate\n\t\tthis.rewriteContent(content)\n\t\treturn this\n\t}\n}\n\ntype Operation = Uppercase<\n\t| 'append language'\n\t| 'print'\n\t| 'remove language'\n\t| 'update age'\n\t| 'update born date'\n\t| 'update name'\n\t| 'exit'\n>\n\nconst jsonFile: JsonFile = new JsonFile('additional-challenge', {\n\tage: 22,\n\tbornDate: new Date(2002, 1, 20),\n\tname: 'Lucas',\n\tprogrammingLanguages: ['TypeScript'],\n})\n\nlet exit: boolean = false\ndo {\n\tconst input = readline\n\t\t.question(\n\t\t\t\"\\nWrite an operation ('append language', 'print', 'remove language', 'update age', 'update born date', 'update name', or 'exit'): \"\n\t\t)\n\t\t.trim()\n\t\t.toUpperCase() as Operation\n\n\tswitch (input) {\n\t\tcase 'APPEND LANGUAGE':\n\t\t\tconst newProgrammingLanguage: string = readline.question(\n\t\t\t\t'\\nNew programming language: '\n\t\t\t)\n\t\t\tjsonFile.appendProgrammingLanguage(newProgrammingLanguage)\n\t\t\tbreak\n\n\t\tcase 'PRINT':\n\t\t\tconst content: Content = jsonFile.getContent()\n\t\t\tconsole.log()\n\t\t\tconsole.table(content)\n\t\t\tbreak\n\n\t\tcase 'REMOVE LANGUAGE':\n\t\t\tconst programmingLanguageToDelete: string = readline.question(\n\t\t\t\t'\\nProgramming language to delete: '\n\t\t\t)\n\t\t\tjsonFile.removeProgrammingLanguage(programmingLanguageToDelete)\n\t\t\tbreak\n\n\t\tcase 'UPDATE AGE':\n\t\t\tconst newAge: number = parseInt(readline.question('\\nNew age: '))\n\t\t\tjsonFile.updateAge(newAge)\n\t\t\tbreak\n\n\t\tcase 'UPDATE BORN DATE':\n\t\t\tconst newBornDate: string = readline.question(\n\t\t\t\t'\\nNew born date (year-month-day): '\n\t\t\t)\n\t\t\tjsonFile.updateBornDate(new Date(newBornDate))\n\t\t\tbreak\n\n\t\tcase 'UPDATE NAME':\n\t\t\tconst newName: string = readline.question('\\nNew name: ')\n\t\t\tjsonFile.updateName(newName)\n\t\t\tbreak\n\n\t\tcase 'EXIT':\n\t\t\texit = true\n\t\t\tjsonFile.deleteFile()\n\t\t\tbreak\n\n\t\tdefault:\n\t\t\tconsole.log('\\nInvalid operation! Try again...')\n\t}\n} while (!exit)\n\nconst xmlFile: XmlFile = new XmlFile('additional-challenge', {\n\tage: 22,\n\tname: 'Lucas',\n\t'born-date': new Date(2002, 1, 20),\n\t'programming-languages': {\n\t\ttypescript: 'TypeScript',\n\t},\n})\n\nexit = false\ndo {\n\tconst input = readline\n\t\t.question(\n\t\t\t\"\\nWrite an operation ('append language', 'print', 'remove language', 'update age', 'update born date', 'update name', or 'exit'): \"\n\t\t)\n\t\t.trim()\n\t\t.toUpperCase() as Operation\n\n\tswitch (input) {\n\t\tcase 'APPEND LANGUAGE':\n\t\t\tconst newProgrammingLanguage: string = readline.question(\n\t\t\t\t'\\nNew programming language: '\n\t\t\t)\n\t\t\txmlFile.appendProgrammingLanguage(newProgrammingLanguage)\n\t\t\tbreak\n\n\t\tcase 'PRINT':\n\t\t\tconst content: Content<true> = xmlFile.getContent()\n\t\t\tconsole.log()\n\t\t\tconsole.table(content)\n\t\t\tbreak\n\n\t\tcase 'REMOVE LANGUAGE':\n\t\t\tconst programmingLanguageToDelete: string = readline.question(\n\t\t\t\t'\\nProgramming language to delete: '\n\t\t\t)\n\t\t\txmlFile.removeProgrammingLanguage(programmingLanguageToDelete)\n\t\t\tbreak\n\n\t\tcase 'UPDATE AGE':\n\t\t\tconst newAge: number = parseInt(readline.question('\\nNew age: '))\n\t\t\txmlFile.updateAge(newAge)\n\t\t\tbreak\n\n\t\tcase 'UPDATE BORN DATE':\n\t\t\tconst newBornDate: string = readline.question(\n\t\t\t\t'\\nNew born date (year-month-day): '\n\t\t\t)\n\t\t\txmlFile.updateBornDate(new Date(newBornDate))\n\t\t\tbreak\n\n\t\tcase 'UPDATE NAME':\n\t\t\tconst newName: string = readline.question('\\nNew name: ')\n\t\t\txmlFile.updateName(newName)\n\t\t\tbreak\n\n\t\tcase 'EXIT':\n\t\t\texit = true\n\t\t\txmlFile.deleteFile()\n\t\t\tbreak\n\n\t\tdefault:\n\t\t\tconsole.log('\\nInvalid operation! Try again...')\n\t}\n} while (!exit)\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/typescript/qwik-zgheib.ts",
    "content": "/* -- exercise */\nimport fs from \"fs\";\n\ninterface Content {\n  name: string;\n  age: number;\n  birthdate: string;\n  programmingLanguages: string[];\n}\n\nconst content: Content = {\n  name: \"Qwik Zgheib\",\n  age: 22,\n  birthdate: \"2002-11-09\",\n  programmingLanguages: [\"JavaScript\", \"Typescript\", \"Python\"],\n};\n\ntype FileType = \"json\" | \"xml\";\n\nconst exerciseMain = {\n  createfile: (filename: string, content: Content, type: FileType = \"json\"): void => {\n    try {\n      const jsonContent: string = JSON.stringify(content);\n      if (type === \"json\") fs.writeFileSync(`${filename}.json`, jsonContent);\n      if (type === \"xml\") {\n        const xmlContent: string = `<data>\n          <name>${content.name}</name>\n          <age>${content.age}</age>\n          <birthdate>${content.birthdate}</birthdate>\n          <programmingLanguages>\n            ${content.programmingLanguages.map((lang) => `<language>${lang}</language>`).join(\"\")}\n          </programmingLanguages>\n        </data>`;\n        fs.writeFileSync(`${filename}.xml`, xmlContent);\n      }\n    } catch (error) {\n      console.error(error);\n    }\n  },\n  readFile: (filename: string): void => {\n    try {\n      const jsonContent: string = fs.readFileSync(`${filename}.json`, \"utf-8\");\n      const xmlContent: string = fs.readFileSync(`${filename}.xml`, \"utf-8\");\n      console.log(`Reading ${filename}.json\\n`, jsonContent);\n      console.log(`\\nReading ${filename}.xml\\n`, xmlContent);\n    } catch (error) {\n      console.error(error);\n    }\n  },\n  deleteFile: (filename: string): void => {\n    try {\n      console.log(\"Deleting files...\");\n      fs.unlinkSync(`${filename}.json`);\n      fs.unlinkSync(`${filename}.xml`);\n    } catch (error) {\n      console.error(error);\n    }\n  },\n};\n\nexerciseMain.createfile(\"data\", content, \"json\");\nexerciseMain.createfile(\"data\", content, \"xml\");\n\nexerciseMain.readFile(\"data\");\nexerciseMain.deleteFile(\"data\");\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/typescript/victor-Casta.ts",
    "content": "const fs = require('fs')\nconst path = require('path')\n\n/*\n  * EJERCICIO:\n  * Desarrolla un programa capaz de crear un archivo XML y JSON que guarde los\n  * siguientes datos (haciendo uso de la sintaxis correcta en cada caso):\n  * - Nombre\n  * - Edad\n  * - Fecha de nacimiento\n  * - Listado de lenguajes de programación\n  * Muestra el contenido de los archivos.\n  * Borra los archivos.\n*/\n\nasync function saveData(): Promise<void> {\n  const JSONdata = {\n    name: 'Victor',\n    age: 21,\n    dateOfBirth: new Date(2002, 11, 17).toDateString(),\n    programmingLanguages: ['JavaScript', 'TypeScript', 'Python', 'PHP']\n  }\n\n  const xmlData = `\n  <root>\n    <name>Victor</name>\n    <age>21</age>\n    <dateOfBirth>2002-11-17</dateOfBirth>\n    <programmingLanguages>\n      <language>JavaScript</language>\n      <language>TypeScript</language>\n      <language>Python</language>\n      <language>PHP</language>\n    </programmingLanguages>\n  </root>`\n\n\n  await fs.writeFileSync('data.json', JSON.stringify(JSONdata))\n  fs.writeFileSync('data.xml', xmlData, 'utf8')\n  console.log(fs.readFileSync('data.xml', 'utf8'))\n  console.log(fs.readFileSync('data.json', 'utf8'))\n  // fs.unlinkSync('data.json')\n  // fs.unlinkSync('data.xml')\n}\n\nsaveData()\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la lógica de creación de los archivos anteriores, crea un\n * programa capaz de leer y transformar en una misma clase custom de tu\n * lenguaje los datos almacenados en el XML y el JSON.\n * Borra los archivos.\n*/\n\nclass customData {\n  file: string\n  constructor(file: string) {\n    this.file = file\n  }\n\n  async readData(): Promise<any> {\n    if (path.extname(this.file) === '.json') {\n      return JSON.parse(fs.readFileSync(this.file, 'utf8'))\n    }\n  }\n\n  async updateData(): Promise<any> {\n    if (path.extname(this.file) === '.xml') {\n      return fs.readFileSync('data.xml', 'utf8')\n    }\n  }\n\n  async deleteFile(): Promise<void> {\n    fs.unlinkSync(this.file)\n  }\n}\n\nconst dataJson = new customData('data.json')\nconsole.log(dataJson.readData())\n\nconst dataXml = new customData('data.xml')\nconsole.log(dataXml.updateData())\n\ndataJson.deleteFile()\ndataXml.deleteFile()"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/typescript/victoriaparraf.ts",
    "content": "import * as fs from 'fs';\nimport { create } from 'xmlbuilder2';\n\n// Datos a guardar\nconst data = {\n    nombre: 'Victoria Parra',\n    edad: 25,\n    fechaDeNacimiento: '1999-05-15',\n    lenguajesDeProgramacion: ['TypeScript', 'JavaScript', 'Python', 'Java']\n};\n\n// Función para crear archivo JSON\nfunction crearArchivoJSON(filename: string, data: object): void {\n    const jsonData = JSON.stringify(data, null, 2);\n    fs.writeFileSync(filename, jsonData, 'utf8');\n    console.log(`Archivo JSON ${filename} creado.`);\n}\n\n// Función para crear archivo XML\nfunction crearArchivoXML(filename: string, data: any): void {\n    const doc = create({ version: '1.0' })\n        .ele('datos')\n        .ele('nombre').txt(data.nombre).up()\n        .ele('edad').txt(data.edad.toString()).up()\n        .ele('fechaDeNacimiento').txt(data.fechaDeNacimiento).up()\n        .ele('lenguajesDeProgramacion');\n    \n    data.lenguajesDeProgramacion.forEach((lenguaje: string) => {\n        doc.ele('lenguaje').txt(lenguaje).up();\n    });\n\n    doc.up();\n    const xmlData = doc.end({ prettyPrint: true });\n    fs.writeFileSync(filename, xmlData, 'utf8');\n    console.log(`Archivo XML ${filename} creado.`);\n}\n\n// Crear archivos JSON y XML\nconst jsonFilename = 'victoriaparraf.json';\nconst xmlFilename = 'victoriaparraf.xml';\n\ncrearArchivoJSON(jsonFilename, data);\ncrearArchivoXML(xmlFilename, data);\n\n// Leer e imprimir el contenido de los archivos\nfunction leerArchivo(filename: string): void {\n    const content = fs.readFileSync(filename, 'utf8');\n    console.log(`Contenido de ${filename}:`);\n    console.log(content);\n}\n\nleerArchivo(jsonFilename);\nleerArchivo(xmlFilename);\n\n// Borrar archivos\nfunction borrarArchivo(filename: string): void {\n    fs.unlinkSync(filename);\n    console.log(`Archivo ${filename} borrado.`);\n}\n\nborrarArchivo(jsonFilename);\nborrarArchivo(xmlFilename);\n"
  },
  {
    "path": "Roadmap/12 - JSON Y XML/vb.net/kenysdev.vb",
    "content": "' ╔══════════════════════════════════════╗\n' ║ Autor:  Kenys Alvarado               ║\n' ║ GitHub: https://github.com/Kenysdev  ║\n' ║ 2024 -  VB.NET                       ║\n' ╚══════════════════════════════════════╝\n'-----------------------------------------------\n'* JSON Y XML\n'-----------------------------------------------\n'- son formatos de intercambio de datos que estructuran información.\n'- JSON (JavaScript Object Notation) y XML (eXtensible Markup Language)\nImports System.IO\nImports System.Text.Json\nImports System.Xml\nImports System.Xml.Linq\n\nModule Program\n    Sub Main()\n        Dim userDic As New Dictionary(Of String, Object) From {\n            {\"name\", \"Ken\"},\n            {\"age\", 121},\n            {\"dob\", \"1903-03-19\"},\n            {\"prog_langs\", New List(Of String) From {\"cs\", \"py\", \"vb\", \"rs\", \"js\"}}\n        }\n\n        ' _______________________________________________\n        ' * JSON\n        ' serializar\n        Dim options = New JsonSerializerOptions With {\n            .WriteIndented = True\n        }\n\n        Dim json As String = JsonSerializer.Serialize(userDic, options)\n        File.WriteAllText(\"user.json\", json)\n\n        ' Deserializar\n        Dim readJson = File.ReadAllText(\"user.json\")\n        Dim DesUserJson = JsonSerializer.Deserialize(Of Dictionary(Of String, Object))(readJson)\n        Console.WriteLine(DesUserJson(\"name\"))\n\n        ' _______________________________________________\n        ' * XML\n        ' serializar\n        userDic(\"prog_langs\") = \"cs,py,vb,rs,js\"\n        Using writer As New XmlTextWriter(\"user.xml\", Nothing)\n            writer.Formatting = Formatting.Indented\n            writer.WriteStartDocument()\n            writer.WriteStartElement(\"user\")\n\n            For Each pair In userDic\n                writer.WriteStartElement(pair.Key)\n                writer.WriteValue(pair.Value)\n                writer.WriteEndElement()\n            Next\n\n            writer.WriteEndElement()\n            writer.WriteEndDocument()\n        End Using\n\n        ' Deserializar\n        Dim doc = XDocument.Load(\"user.xml\")\n        Dim userElement = doc.Root\n        Dim name = userElement.Element(\"name\").Value\n        Console.WriteLine(name)\n\n        ' _______________________________________________\n        ' * EJERCICIO\n        ' * Utilizando la lógica de creación de los archivos anteriores, crea un\n        ' * programa capaz de leer y transformar en una misma clase custom de tu \n        ' * lenguaje los datos almacenados en el XML y el JSON.\n        ' * Borra los archivos.\n\n        Dim theFile As New XmlOrJson(\"user.json\")\n        Dim dicUser = theFile.AsDictionary()\n        Console.WriteLine(vbLf & \"Documento JSON\")\n        For Each kv In dicUser\n            If kv.Key <> \"prog_langs\" Then\n                Console.WriteLine($\"{kv.Key}: {kv.Value}\")\n            End If\n        Next\n        Dim progLangs As List(Of String) = DirectCast(dicUser(\"prog_langs\"), List(Of String))\n        Console.WriteLine(String.Join(\", \", progLangs))\n\n        '_________\n        Dim theFile2 As New XmlOrJson(\"user.xml\")\n        Dim dicUser2 As Dictionary(Of String, Object) = theFile2.AsDictionary()\n        Console.WriteLine(vbLf & \"Documento XML\")\n        For Each kv In dicUser2\n            If kv.Key <> \"prog_langs\" Then\n                Console.WriteLine($\"{kv.Key}: {kv.Value}\")\n            End If\n        Next\n        Dim progLangs2 As List(Of String) = DirectCast(dicUser2(\"prog_langs\"), List(Of String))\n        Console.WriteLine(String.Join(\", \", progLangs2))\n\n        '_________\n        Console.WriteLine(vbLf & \"Acceder directamente\")\n        Console.WriteLine(theFile2.name)\n        Console.WriteLine(theFile2.age)\n        Console.WriteLine(theFile2.dob)\n        File.Delete(\"user.json\")\n        File.Delete(\"user.xml\")\n\n    End Sub\n\n    Public Class XmlOrJson\n        Private path As String\n        Private extension As String\n        Private dicUser As Dictionary(Of String, Object)\n        Public name As String\n        Public age As Integer\n        Public dob As String\n        Public langs As List(Of String)\n\n        Public Sub New(ByVal path As String)\n            If path Is Nothing Then\n                Throw New ArgumentNullException(\"path\", \"Debe proporcionar una ruta.\")\n            End If\n            Me.path = path\n            Me.extension = path.Split(\".\"c).LastOrDefault()\n            Me.dicUser = New Dictionary(Of String, Object)()\n            Me.name = String.Empty\n            Me.age = 0\n            Me.dob = String.Empty\n            Me.langs = New List(Of String)()\n        End Sub\n\n        Private Sub AddToDic()\n            dicUser(\"name\") = name\n            dicUser(\"age\") = age\n            dicUser(\"dob\") = dob\n            dicUser(\"prog_langs\") = langs\n        End Sub\n\n        Public Function AsDictionary() As Dictionary(Of String, Object)\n            Try\n                If extension = \"json\" Then\n                    Dim readJson As String = File.ReadAllText(path)\n                    Using document = JsonDocument.Parse(readJson)\n                        Dim root = document.RootElement\n                        name = root.GetProperty(\"name\").GetString()\n                        age = root.GetProperty(\"age\").GetInt32()\n                        dob = root.GetProperty(\"dob\").GetString()\n                        For Each lang In root.GetProperty(\"prog_langs\").EnumerateArray()\n                            langs.Add(lang.GetString())\n                        Next\n                        AddToDic()\n                        Return dicUser\n                    End Using\n\n                ElseIf extension = \"xml\" Then\n                    Dim doc = XDocument.Load(path)\n                    Dim userElement = doc.Root\n                    name = userElement.Element(\"name\").Value\n                    age = Integer.Parse(userElement.Element(\"age\").Value)\n                    dob = userElement.Element(\"dob\").Value\n                    langs = userElement.Element(\"prog_langs\").Value.Split(\",\"c).ToList()\n                    AddToDic()\n                    Return dicUser\n                Else\n                    Console.WriteLine(\"Archivo no compatible.\")\n                    Return Nothing\n                End If\n            Catch ex As Exception\n                Console.WriteLine($\"Exception: {ex.GetType()}\")\n                Return Nothing\n            End Try\n        End Function\n    End Class\nEnd Module\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/bash/rantamhack.sh",
    "content": "#!/bin/bash\n\n#  EJERCICIO:\n#  Crea una funcion que se encargue de sumar dos numeros y retornar\n#  su resultado.\n#  Crea un test, utilizando las herramientas de tu lenguaje, que sea\n#  capaz de determinar si esa funcion se ejecuta correctamente.\n\n\n# PARA REALIZAR LOS TEST UNITARIOS CON BASHUNIT HAY QUE PASAR ESTE SCRIPT POR  EL SCRIPT BASHUNIT QUEDARIA ASI:\n\n# ./lib/bashunit ./13-Pruebas_unitarias.sh\n\n# bashunit - 0.11.0\n# Test case 1 passed\n# Test case 2 passed\n# Test case 3 passed\n# Test case 4 passed\n# Running ./prueba.sh\n# Test case 1 passed\n# Test case 2 passed\n# Test case 3 passed\n# Test case 4 passed\n#âœ“ Passed: Sum\n\n# Tests:      1 passed, 1 total\n# Assertions: 0 passed, 0 total\n\n#  All tests passed \n#  Time taken: 344 ms\n\n\nsum() {\n    local num1=$1\n    local num2=$2\n    echo $(($num1 + $num2))\n}\n\n\ntest_sum() {\n    local result=$(sum 4 2)\n    if [ $result -eq 6 ]; then\n        echo \"Test case 1 passed\"\n    else\n        echo \"Test case 1 failed\"\n    fi\n\n    result=$(sum -4 2)\n    if [ $result -eq -2 ]; then\n        echo \"Test case 2 passed\"\n    else\n        echo \"Test case 2 failed\"\n    fi\n\n    result=$(sum 4 -2)\n    if [ $result -eq 2 ]; then\n        echo \"Test case 3 passed\"\n    else\n        echo \"Test case 3 failed\"\n    fi\n\n    result=$(sum 2,3 4,7)\n    if [ $(echo \"$result == 7.0\" | bc -l) -eq 1 ]; then\n        echo \"Test case 4 passed\"\n    else\n        echo \"Test case 4 failed\"\n    fi\n}\n\ntest_sum\n\n\n# * DIFICULTAD EXTRA (opcional):\n# * Crea un diccionario con las siguientes claves y valores:\n# * \"name\": \"Tu nombre\"\n# * \"age\": \"Tu edad\"\n# * \"birth_date\": \"Tu fecha de nacimiento\"\n# * \"programming_languages\": [\"Listado de lenguajes de programacion\"]\n# * Crea dos test:\n# * - Un primero que determine que existen todos los campos.\n# * - Un segundo que determine que los datos introducidos son correctos.\n\n\n\n#!/bin/bash\n\ndata=(\n    \"name=rantam\"\n    \"age=15\"\n    \"birth_date=15-04\"\n    \"programming_languages=Python,Bash,Java\"\n)\n\n# Test fields\nfor field in \"name\" \"age\" \"birth_date\" \"programming_languages\"; do\n    found=false\n    for item in \"${data[@]}\"; do\n        if [[ \"$item\" == \"$field=\"* ]]; then\n            found=true\n            echo \"Field $field exists\"\n            break\n        fi\n    done\n    if ! $found; then\n        echo \"Field $field not found\"\n    fi\ndone\n\n# Test data types\nfor item in \"${data[@]}\"; do\n    field=\"${item%%=*}\"\n    value=\"${item#*=}\"\n    case \"$field\" in\n        \"name\")\n            if [[ ! \"$value\" =~ ^[a-zA-Z]+$ ]]; then\n                echo \"Invalid data type for field $field\"\n            else\n                echo \"The value of the field '$field' is a string\"\n            fi\n            ;;\n        \"age\")\n            if [[ ! \"$value\" =~ ^[0-9]+$ ]]; then\n                echo \"Invalid data type for field $field\"\n            else\n                echo \"The value of the field '$field' is a integer\"\n            fi\n            ;;\n        \"birth_date\")\n            if [[ ! \"$value\" =~ ^[0-9]{2}-[0-9]{2}$ ]]; then\n                echo \"Invalid data type for field $field\"\n            else\n                echo \"The value of the field '$field' is a integer\"\n            fi\n            ;;\n        \"programming_languages\")\n            if [[ ! \"$value\" =~ ^[a-zA-Z,]+$ ]]; then\n                echo \"Invalid data type for field $field\"\n            else\n                echo \"The value of the field '$field' is a string\"\n            fi\n            ;;\n        *)\n            echo \"Unknown field $field\"\n            ;;\n    esac\ndone\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/c#/Andreavzqz.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing Xunit;\n\nnamespace EjercicioSuma\n{\n    public class Program\n    {\n        public static int sumar(int a, int b)\n        {\n            return a + b; \n        }\n\n        public static Dictionary<string, object> CrearDiccionario()\n        {\n            return new Dictionary<string, object>\n            {\n                { \"name\", \"Andrea\" },\n                { \"age\", 30 },\n                {\"birth_date\", new DateTime(1994, 5, 13)},\n                {\"programming_languages\", new List<string>{\"C#\", \"JavaScript\", \"Python\"}}\n            };\n        }\n    }\n\n    public class PruebasUnitarias\n    {\n        [Fact]\n        public void TestSumaCorrecta()\n        {\n            int resultado = Program.sumar(3, 4);\n            Assert.Equal(7, resultado);\n        }\n\n        [Fact]\n        public void TestDiccionarioCamposExisten()\n        {\n            var diccionario = Program.CrearDiccionario();\n\n            Assert.True(diccionario.ContainsKey(\"name\"));\n            Assert.True(diccionario.ContainsKey(\"age\"));\n            Assert.True(diccionario.ContainsKey(\"birth_date\"));\n            Assert.True(diccionario.ContainsKey(\"programming_languages\"));\n        }\n\n        [Fact]\n        public void TestDiccionarioCamposCorrectos()\n        {\n            \n            var diccionario = Program.CrearDiccionario();\n\n            Assert.Equal(\"Andrea\", diccionario[\"name\"]);\n            Assert.Equal(30, diccionario[\"age\"]);\n            Assert.Equal(new DateTime(1994, 5, 13), diccionario[\"birth_date\"]);\n            Assert.Equal(new List<string> {\"C#\", \"JavaScrip\", \"Python\" }, diccionario[\"programming_languages\"]);\n        }\n    }\n\n  /*\n\n-Explicación\n\nFunción Sumar:\nEsta función toma dos números enteros como argumentos y retorna su suma.\n\nFunción CrearDiccionario:\nCrea y retorna un diccionario con claves y valores que incluyen nombre, edad, fecha de nacimiento y una lista de lenguajes de programación.\n\nClase PruebasUnitarias:\nTestSumaCorrecta: Verifica que la función Sumar retorna el resultado correcto al sumar dos números.\nTestDiccionarioCamposExisten: Verifica que el diccionario creado por CrearDiccionario contiene todas las claves esperadas.\nTestDiccionarioDatosCorrectos: Verifica que los valores del diccionario coinciden con los datos esperados.\n\n*/\n}\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/c#/hequebo.cs",
    "content": "using Microsoft.VisualStudio.TestTools.UnitTesting;\n\nclass Program\n{\n    static void Main(string[] args)\n    {\n        // Pruebas unitarias Suma\n        Console.WriteLine(\"---Pruebas Unitarias Sumas---\");\n        var opTest = new OperacionesTest();\n        try\n        {\n            opTest.PruebaSumas();\n            Console.WriteLine(\"Las pruebas se completaron correctamente\");\n        }\n        catch (Exception ex)\n        {\n            Console.WriteLine(\"Las pruebas fallaron...\");\n            Console.WriteLine(ex.Message);\n        }\n        finally\n        {\n            Console.WriteLine(\"Aquí terminan las pruebas unitarios de Sumas\");\n        }\n        Console.ReadLine();\n        Console.Clear();\n        // Ejercicio Extra\n        Console.WriteLine(\"---Pruebas unitarias Diccionario\");\n        var personaTest = new PersonaTest();\n        try\n        {\n            personaTest.PruebaExistenValores();\n            personaTest.PruebaValoresCorrectos();\n            Console.WriteLine(\"Las pruebas se completaron correctamente\");\n        }\n        catch (Exception ex)\n        {\n            Console.WriteLine(\"Las pruebas fallaron...\");\n            Console.WriteLine(ex.Message);\n        }\n        finally\n        {\n            Console.WriteLine(\"Aquí terminan las pruebas unitarios de Diccionarios\");\n        }\n    }\n}\nclass Operaciones\n{\n    public int Suma(int a, int b)\n    {\n        return a + b;\n    }\n}\n\n[TestClass]\nclass OperacionesTest\n{\n    \n    [TestMethod]\n    public void PruebaSumas()\n    {\n        var operaciones = new Operaciones();\n        Assert.AreEqual(7, operaciones.Suma(5, 2));\n        Assert.AreEqual(0, operaciones.Suma(5, -5));\n        Assert.AreEqual(-7, operaciones.Suma(-5, -2));\n        Assert.AreEqual(-3, operaciones.Suma(-5, 2));\n    }\n}\nclass Persona\n{\n    public Dictionary<string, object> persona = new Dictionary<string, object>\n    {\n        {\"name\", \"Emilio Quezada\" },\n        {\"age\", \"27\"},\n        {\"birth_date\", new DateTime(1997, 07, 28)},\n        {\"programming_languages\", new List<string>{\"C#\", \"Typescript\", \"VB\"} }\n    };\n}\n[TestClass]\nclass PersonaTest\n{\n    [TestMethod]\n    public void PruebaExistenValores()\n    {\n        var personaPrueba = new Persona();\n        Assert.IsTrue(personaPrueba.persona.ContainsKey(\"name\"));\n        Assert.IsTrue(personaPrueba.persona.ContainsKey(\"age\"));\n        Assert.IsTrue(personaPrueba.persona.ContainsKey(\"birth_date\"));\n        Assert.IsTrue(personaPrueba.persona.ContainsKey(\"programming_languages\"));\n    }\n    [TestMethod]\n    public void PruebaValoresCorrectos()\n    {\n        var personaPrueba = new Persona();\n        Assert.IsInstanceOfType(personaPrueba.persona[\"name\"], typeof(String));\n        Assert.IsInstanceOfType(personaPrueba.persona[\"age\"], typeof(Int32));\n        Assert.IsInstanceOfType(personaPrueba.persona[\"birth_date\"], typeof(DateTime));\n        Assert.IsInstanceOfType(personaPrueba.persona[\"programming_languages\"], typeof(List<string>));\n    }\n}\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/c#/isaacus98.cs",
    "content": "﻿/*\n * EJERCICIO:\n * Crea una función que se encargue de sumar dos números y retornar\n * su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n * capaz de determinar si esa función se ejecuta correctamente.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\n */\n\nusing Microsoft.VisualStudio.TestTools.UnitTesting;\n\nnamespace Roadmap\n{\n    public class Reto13\n    {\n        public Dictionary<string, string> Programmer = new Dictionary<string, string>()\n        {\n            {\"name\", \"Isaac\" },\n            {\"age\", \"26\" },\n            {\"birth_date\", \"13-02-1998\" },\n            {\"programming_languages\", \"C#, VB.Net, Kotlin\"}\n        };\n\n        public int Suma(int num1, int num2)\n        {\n            return num1 + num2;\n        }\n    }\n\n    [TestClass]\n    public class Reto13Test\n    {\n        [TestMethod]\n        public void SumaTest()\n        {\n            Reto13 reto = new();\n            int result = reto.Suma(1, 2);\n            Assert.AreEqual(3, result);\n        }\n\n        [TestMethod]\n        public void DictionaryTest()\n        {\n            Reto13 reto = new();\n            Assert.IsTrue(reto.Programmer.ContainsKey(\"name\"));\n            Assert.IsTrue(reto.Programmer.ContainsKey(\"age\"));\n            Assert.IsTrue(reto.Programmer.ContainsKey(\"birth_date\"));\n            Assert.IsTrue(reto.Programmer.ContainsKey(\"programming_languages\"));\n        }\n\n        [TestMethod]\n        public void DictionaryValuesTest()\n        {\n            Reto13 reto = new();\n            Assert.AreEqual(\"Isaac\", reto.Programmer[\"name\"]);\n            Assert.AreEqual(\"26\", reto.Programmer[\"age\"]);\n            Assert.AreEqual(\"13-02-1998\", reto.Programmer[\"birth_date\"]);\n            Assert.AreEqual(\"C#, VB.Net, Kotlin\", reto.Programmer[\"programming_languages\"]);\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/c#/jamerrq.cs",
    "content": "/*\n * EJERCICIO:\n * Crea una función que se encargue de sumar dos números y retornar\n * su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n * capaz de determinar si esa función se ejecuta correctamente.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\n */\n\nusing System;\nusing Microsoft.VisualStudio.TestTools.UnitTesting;\n\nclass Testing\n{\n    public int Suma(int num1, int num2)\n    {\n        return num1 + num2;\n    }\n\n    public Dictionary<string, string> Programmer = new Dictionary<string, string>()\n    {\n        {\"name\", \"Jamer\" },\n        {\"age\", \"24\" },\n        {\"birth_date\", \"21-02-2000\" },\n        {\"programming_languages\", [\"C#\", \"TypeScript\", \"Bash\", \"Python\"] }\n    };\n\n    [TestClass]\n    public class TestingTest\n    {\n        [TestMethod]\n        public void SumaTest()\n        {\n            Testing test = new();\n            int result = test.Suma(1, 2);\n            Assert.AreEqual(3, result);\n        }\n\n        [TestMethod]\n        public void DictionaryTest()\n        {\n            Testing test = new();\n            Assert.IsTrue(test.Programmer.ContainsKey(\"name\"));\n            Assert.IsTrue(test.Programmer.ContainsKey(\"age\"));\n            Assert.IsTrue(test.Programmer.ContainsKey(\"birth_date\"));\n            Assert.IsTrue(test.Programmer.ContainsKey(\"programming_languages\"));\n        }\n    }\n\n    static void Main()\n    {\n        Testing test = new();\n        int result = test.Suma(1, 2);\n        Console.WriteLine(result);\n\n        Console.WriteLine(test.Programmer[\"name\"]);\n        Console.WriteLine(test.Programmer[\"age\"]);\n        Console.WriteLine(test.Programmer[\"birth_date\"]);\n        foreach (string language in test.Programmer[\"programming_languages\"])\n        {\n            Console.WriteLine(language);\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/c#/kenysdev.cs",
    "content": "/*\n╔═══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado                ║\n║ GitHub: https://github.com/Kenysdev   ║\n║ 2024 -  C#                            ║\n╚═══════════════════════════════════════╝\n-----------------------------------------------\n* PRUEBAS UNITARIAS\n-----------------------------------------------\n# - Verifican que las unidades individuales de código (como \n#   funciones, métodos o clases) funcionen como se espera.\n# - Mas info: https://www.netmentor.es/entrada/unit-testing\n*/\n#pragma warning disable CA1050\nusing Microsoft.VisualStudio.TestTools.UnitTesting;\n\n/* ____________________________________\n * EJERCICIO #1\n * Crea una función que se encargue de sumar dos números y retornar\n   su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n   capaz de determinar si esa función se ejecuta correctamente.\n*/\npublic class FunSum {\n    public static double Sum(double a, double b) {\n        return a + b;\n    } \n}\n\n[TestClass]\npublic class TestSum {\n    [TestMethod]\n    public void TestSumCorrect() {\n        Assert.AreEqual(FunSum.Sum(5, 2), 7);\n        Assert.AreEqual(FunSum.Sum(2.50, 1.25), 3.75);\n        Assert.AreEqual(FunSum.Sum(-2, 1), -1);\n    }\n\n    [TestMethod]\n    public void TestSumIncorrect() {\n        Assert.AreNotEqual(FunSum.Sum(1, 3), 5);\n    }\n}\n\n/* ____________________________________\n * EJERCICIO #2\n * Crea un diccionario con las siguientes claves y valores:\n   - \"name\": \"Tu nombre\"\n   - \"age\": \"Tu edad\"\n   - \"birth_date\": \"Tu fecha de nacimiento\"\n   - \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n   - Un primero que determine que existen todos los campos.\n   - Un segundo que determine que los datos introducidos son correctos.\n*/\n\n[TestClass]\npublic class TestDict {\n    readonly Dictionary<string, object> dictUser = new() {\n        { \"name\", \"Ken\" },\n        { \"age\", 121 },\n        { \"birth_date\", \"1903-03-19\" },\n        { \"prog_langs\", new List<string> { \"cs\", \"py\", \"vb\", \"rs\", \"js\" } }\n    };\n\n    [TestMethod]\n    public void TestDicKeyExistence() {\n        Assert.IsTrue(dictUser.ContainsKey(\"name\"));\n        Assert.IsTrue(dictUser.ContainsKey(\"age\"));\n        Assert.IsTrue(dictUser.ContainsKey(\"birth_date\"));\n        Assert.IsTrue(dictUser.ContainsKey(\"prog_langs\"));\n    }\n\n    [TestMethod]\n    public void TestDicValueTypes() {\n        Assert.IsInstanceOfType(dictUser[\"name\"], typeof(string));\n        Assert.IsInstanceOfType(dictUser[\"age\"], typeof(int));\n        Assert.IsInstanceOfType(dictUser[\"birth_date\"], typeof(string));\n        Assert.IsInstanceOfType(dictUser[\"prog_langs\"], typeof(List<string>));\n    }\n\n    [TestMethod]\n    public void TestDicValueContent() {\n        Assert.AreEqual(dictUser[\"name\"], \"Ken\");\n        Assert.AreEqual(dictUser[\"age\"], 121);\n        Assert.AreEqual(dictUser[\"birth_date\"], \"1903-03-19\");\n        CollectionAssert.AreEqual(\n            (List<string>)dictUser[\"prog_langs\"],\n            new List<string> { \"cs\", \"py\", \"vb\", \"rs\", \"js\" }\n        );\n    }\n}\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/c++/hectorio23.cpp",
    "content": "// Autor: Héctor Adàn\n// GitHub: https://github.com/hectorio23 \n\n#include <cstdlib>    // Librería estándar de C para usar EXIT_SUCCESS, por elegancia :)\n#include <iostream>   // Librería estándar de C++ para entrada/salida\n#include <cassert>    // Librería estándar de C para aserciones\n#include <ctime>      // Librería estándar de C para manipulación de tiempo\n\n#define assertm(expresion, msg) assert(((void)0, expresion)); // Macro para aserciones con mensajes personalizados\n\n// Función que implementa el juego de adivinanzas\nvoid miniGame() {\n    // Inicializar la semilla del generador de números aleatorios\n    srand(time(0)); \n\n    std::cout << \"Bienvenido al juego de adivinanzas!\" << std::endl;\n    std::cout << \"Estoy pensando en un número entre 1 y 100. Adivina cuál es!\" << std::endl;\n\n    // Generar número aleatorio entre 1 y 100\n    int numeroAleatorio = rand() % 100 + 1; \n    int intentos = 0;\n    int intentoUsuario;\n\n    do {\n        std::cout << \"Ingresa tu intento: \";\n        std::cin >> intentoUsuario;\n\n        // Verificar que el número esté en el rango válido\n        assert(intentoUsuario >= 1 && intentoUsuario <= 100); \n        intentos++;\n\n        if (intentoUsuario < numeroAleatorio) {\n            std::cout << \"El número que estoy pensando es mayor.\" << std::endl;\n        } else if (intentoUsuario > numeroAleatorio) {\n            std::cout << \"El número que estoy pensando es menor.\" << std::endl;\n        } else {\n            std::cout << \"¡Felicidades! Has adivinado el número en \" << intentos << \" intentos.\" << std::endl;\n        }\n    } while (intentoUsuario != numeroAleatorio);\n\n    char continuar;\n    std::cout << \"¿Quieres jugar de nuevo? (s/n): \";\n    std::cin >> continuar;\n\n    if (continuar == 's' || continuar == 'S') {\n        // Reiniciar el juego en caso de que el usuario lo haya\n        // seleccionado\n        miniGame(); \n    } else {\n        std::cout << \"Gracias por jugar. ¡Hasta luego!\\n\" << std::endl;\n    }\n}\n\nint main() {\n    // Primer aserción sin mensaje personalizado\n    assert(2 + 2 == 4);\n    std::cout << \"Checkpoint #1\\n\";\n \n    // Segunda aserción con mensaje personalizado\n    assert((void(\"void helps to avoid 'unused value' warning\"), 2 * 2 == 4));\n    std::cout << \"Checkpoint #2\\n\";\n \n    // Tercera aserción con mensaje personalizado y en base octal\n    assert((010 + 010 == 16) && \"Yet another way to add an assert message\");\n    std::cout << \"Checkpoint #3\\n\";\n \n    // Cuarta aserción con mensaje personalizado utilizando la macro assertm\n    assertm((2 + 2) % 3 == 1, \"Success\");\n    std::cout << \"Checkpoint #4\\n\";\n\n    // Llamada a la función que implementa el juego de adivinanzas\n    miniGame();\n \n    // Quinta aserción con mensaje personalizado utilizando la macro assertm (falla la aserción)\n    assertm(2 + 2 == 5, \"Failed\");\n    std::cout << \"Execution continues past the last assert\\n\"; // No output\n\n    return EXIT_SUCCESS; // Indicar que el programa finalizó correctamente\n} "
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/dart/teren91.dart",
    "content": "/*\n * EJERCICIO:\n * Crea una función que se encargue de sumar dos números y retornar\n * su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n * capaz de determinar si esa función se ejecuta correctamente.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\n */\n\n/*\n  NOTA: Para que este código funcione es necesario crear un archivo pubspec.yaml\n    y añadir la dependencia siguiente:\n\n    dev_dependencies:\n      test: ^1.25.2\n\n*/\n\nimport 'package:test/test.dart';\n\nvoid main() {\n \n\n  testData(data);\n  testSum(2, 3);\n}\n\nint sum(int i, int j) {\n  return i + j;\n}\n\nMap<String, dynamic> data = {\n  \"name\": \"Teren\",\n  \"age\": 32,\n  \"birth_date\": DateTime(1991, 9, 14),\n  \"programming_lenguages\": [\"Dart\", \"C#\", \"TSQL\", \"C++\"]\n};\n\nvoid testSum(int x, int y)\n{\n   test('Test function sum', () {\n   \n    expect(sum(x, y), equals(x+y));\n  });\n}\n\nvoid testData(Map<String, dynamic> data) {\n  group('Test del diccionario', () {\n    test('Test de la primera clave: name', () {\n      expect(data.containsKey(\"name\"), true);\n    });\n    test('Test de la segunda clave: age', () {\n      expect(data.containsKey(\"age\"), true);\n    });\n    test('Test de la tercera clave: birth_date', () {\n      expect(data.containsKey(\"birth_date\"), true);\n    });\n    test('Test de la cuarte clave: programming_lenguages', () {\n      expect(data.containsKey(\"programming_lenguages\"), true);\n    });\n  });\n\n   group('Test del diccionario - tipo de datos', () {\n    test('Test de la primera clave debe ser String: name', () {\n      expect(data.values.first is String , true);\n    });\n    test('Test de la segunda clave: age', () {\n      expect(data.values.elementAt(1) is int, true);\n    });\n    test('Test de la tercera clave: birth_date', () {\n      expect(data.values.elementAt(2) is DateTime, true);\n    });\n    test('Test de la cuarte clave: programming_lenguages', () {\n      expect(data.values.last is List, true);\n    });\n  });\n}\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/ejercicio.md",
    "content": "# #13 PRUEBAS UNITARIAS\n> #### Dificultad: Fácil | Publicación: 25/03/24 | Corrección: 01/04/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Crea una función que se encargue de sumar dos números y retornar\n * su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n * capaz de determinar si esa función se ejecuta correctamente.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/elixir/boterop.exs",
    "content": "defmodule Boterop.Calculator do\n  @spec sum(num1 :: number(), num2 :: number()) :: number()\n  def sum(num1, num2) when is_number(num1) and is_number(num2) do\n    num1 + num2\n  end\n\n  def sum(_num1, _num2), do: {:error, \"Wrong input\"}\nend\n\ndefmodule Boterop.User do\n  @type t :: %__MODULE__{\n          name: String.t(),\n          age: integer(),\n          birth_date: Date.t(),\n          programming_languages: list(atom())\n        }\n\n  defstruct [:name, :age, :birth_date, :programming_languages]\n\n  def new(name, age, birth_date, programming_languages) when is_list(birth_date) do\n    day = Keyword.get(birth_date, :day)\n    month = Keyword.get(birth_date, :month)\n    year = Keyword.get(birth_date, :year)\n\n    %__MODULE__{\n      name: name,\n      age: age,\n      birth_date: Date.new(year, month, day),\n      programming_languages: programming_languages\n    }\n  end\n\n  def new(name, age, birth_date, programming_languages) do\n    %__MODULE__{\n      name: name,\n      age: age,\n      birth_date: birth_date,\n      programming_languages: programming_languages\n    }\n  end\nend\n\nExUnit.start()\n\ndefmodule Boterop.UnitTest do\n  use ExUnit.Case\n\n  alias Boterop.Calculator\n  alias Boterop.User\n\n  describe \"calculator\" do\n    test \"sum/2 with valid numbers\" do\n      num1 = 5\n      num2 = 45\n      expected_result = 50\n      result = Calculator.sum(num1, num2)\n\n      assert expected_result == result\n    end\n\n    test \"sum/2 with invalid params\" do\n      num1 = 5\n      wrong_num2 = \"Hi\"\n      {:error, _message} = Calculator.sum(num1, wrong_num2)\n    end\n  end\n\n  describe \"extra\" do\n    setup do\n      %{\n        user_struct: %User{},\n        user: %User{\n          name: \"Botero P\",\n          age: 24,\n          birth_date: [day: 9, month: 10, year: 1999],\n          programming_languages: [:elixir, :python, :java]\n        }\n      }\n    end\n\n    test \"all fields exist\", %{user_struct: user} do\n      assert Map.has_key?(user, :name)\n      assert Map.has_key?(user, :age)\n      assert Map.has_key?(user, :birth_date)\n      assert Map.has_key?(user, :programming_languages)\n    end\n\n    test \"compare created user\", %{user: user} do\n      expected_name = \"Botero P\"\n      expected_age = 24\n      expected_birth_date = [day: 9, month: 10, year: 1999]\n      expected_programming_languages = [:elixir, :python, :java]\n\n      %{\n        name: ^expected_name,\n        age: ^expected_age,\n        birth_date: ^expected_birth_date,\n        programming_languages: ^expected_programming_languages\n      } = user\n    end\n\n    test \"with wright data\", %{user: user} do\n      expected_user = %User{\n        name: \"Botero P\",\n        age: 24,\n        birth_date: [day: 9, month: 10, year: 1999],\n        programming_languages: [:elixir, :python, :java]\n      }\n\n      user_map = Map.from_struct(user)\n      expected_user_map = Map.from_struct(expected_user)\n      assert Map.equal?(user_map, expected_user_map)\n      assert Map.equal?(user, expected_user)\n    end\n\n    test \"with wrong data\", %{user: user} do\n      expected_user = %User{\n        name: \"Botero\",\n        age: 23,\n        birth_date: [day: 9, month: 10, year: 1999],\n        programming_languages: [:elixir, :python, :java]\n      }\n\n      user_map = Map.from_struct(user)\n      refute Map.equal?(user_map, expected_user)\n    end\n  end\nend\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/go/MiguelP-Dev.go",
    "content": "package main\n\nimport (\n\t\"slices\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n)\n\nfunc Sum(a, b float64) float64 {\n\ttotal := a + b\n\treturn total\n}\n\n// Nota: En go los test se hacen mediante archivos con el mismo nombre del archivo a testear con el sufijo \"_test.go\"\n// Test Simple\nfunc TestSum(t *testing.T) {\n\tresult := Sum(23, 24)\n\tspected := 47\n\n\tif result != float64(spected) {\n\t\tt.Errorf(\"Resultado incorrecto: obtuve %v, esperaba: %v\", result, spected)\n\t}\n}\n\n// Go permite organizar los tests en subtests\n// y usar un enfoque basado en tablas para probar\n// múltiples casos con menos código repetitivo.\nfunc TestSum2(t *testing.T) {\n\ttype casesTemplate []struct {\n\t\tname          string\n\t\ta, b, spected float64\n\t}\n\n\tcases := casesTemplate{{\"NegativeAndPositive\", 15, -12, 3}, {\"TwoTypes\", 12.2, 12, 24.2}, {\"Positive\", 3, 4, 7}, {\"Negative\", -1, -2, -3}}\n\n\tfor _, testCase := range cases {\n\t\tt.Run(testCase.name, func(t *testing.T) {\n\t\t\tresult := Sum(testCase.a, testCase.b)\n\t\t\tif result != testCase.spected {\n\t\t\t\tt.Errorf(\"Para: %s, obtuve: %v, esperaba: %v\", testCase.name, result, testCase.spected)\n\t\t\t}\n\t\t})\n\t}\n}\n\n// Extra\n\nvar Dictionary = map[string]any{\n\t\"name\":                  \"Miguel\",\n\t\"age\":                   31,\n\t\"birth_date\":            time.Date(1993, 10, 13, 0, 0, 0, 0, time.UTC),\n\t\"Programming_languajes\": []string{\"Go\", \"Python\"},\n}\n\nfunc testExistsFieldsDict(t *testing.T) {\n\tfieldsSpected := []string{\"name\", \"age\", \"Programming_languajes\", \"birth_date\"}\n\tfieldsObtained := []string{}\n\n\tfor field, _ := range Dictionary {\n\t\tfieldsObtained = append(fieldsObtained, field)\n\t}\n\n\tslices.Sort(fieldsSpected)\n\tslices.Sort(fieldsObtained)\n\n\tt.Run(\"TestExistsFieldsDict\", func(t *testing.T) {\n\t\tfor i := 0; i <= len(fieldsSpected)-1; i++ {\n\t\t\tif !strings.Contains(fieldsObtained[i], fieldsSpected[i]) {\n\t\t\t\tt.Errorf(\"El campo %s no existe en el diccionario\", fieldsSpected[i])\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t})\n}\n\nfunc testCorrectDataDict(t *testing.T) {\n\ttype casesTemplate []struct {\n\t\tname    string\n\t\tspected any\n\t}\n\n\tcases := casesTemplate{\n\t\t{\"Name\", \"Miguel\"},\n\t\t{\"Age\", 31},\n\t\t{\"Programming_languajes\", []string{\"Go\", \"Python\"}},\n\t\t{\"Birth_date\", time.Date(1993, 10, 13, 0, 0, 0, 0, time.UTC)},\n\t}\n\n\tfor _, testCase := range cases {\n\t\tt.Run(testCase.name, func(t *testing.T) {\n\t\t\tresult := Dictionary[testCase.name]\n\t\t\tif result != testCase.spected {\n\t\t\t\tt.Errorf(\"Para: %s, obtuve: %v, esperaba: %v\", testCase.name, result, testCase.spected)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/go/N0HagoNada.go",
    "content": "package main\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n\t\"time\"\n)\n\nfunc sum(a, b int) int {\n\treturn a + b\n}\n\nfunc TestSum(t *testing.T) {\n\ttestCases := []struct {\n\t\ta, b     int\n\t\texpected int\n\t}{\n\t\t{1, 2, 3},\n\t\t{5, 7, 12},\n\t\t{-3, 3, 0},\n\t\t{0, 0, 0},\n\t}\n\n\tfor _, tc := range testCases {\n\t\tresult := sum(tc.a, tc.b)\n\t\tif result != tc.expected {\n\t\t\tt.Errorf(\"sum(%d, %d) = %d; expected %d\", tc.a, tc.b, result, tc.expected)\n\t\t}\n\t}\n}\n\n/************************************** RETO ******************************************************/\nfunc TestPersonDictionary(t *testing.T) {\n\tperson := map[string]interface{}{\n\t\t\"name\":                  \"John Doe\",\n\t\t\"age\":                   30,\n\t\t\"birth_date\":            \"1990-01-01\",\n\t\t\"programming_languages\": []string{\"Go\", \"Python\", \"JavaScript\"},\n\t}\n\n\t// Primer test: verificar la existencia de todos los campos\n\texpectedFields := []string{\"name\", \"age\", \"birth_date\", \"programming_languages\"}\n\tfor _, field := range expectedFields {\n\t\tif _, exists := person[field]; !exists {\n\t\t\tt.Errorf(\"El campo '%s' no existe en el diccionario\", field)\n\t\t}\n\t}\n\n\t// Segundo test: verificar que los datos introducidos son correctos\n\tif name, ok := person[\"name\"].(string); !ok || name == \"\" {\n\t\tt.Error(\"El campo 'name' no es una cadena válida\")\n\t}\n\n\tif age, ok := person[\"age\"].(int); !ok || age <= 0 {\n\t\tt.Error(\"El campo 'age' no es un entero válido\")\n\t}\n\n\tif birthDate, ok := person[\"birth_date\"].(string); !ok {\n\t\tt.Error(\"El campo 'birth_date' no es una cadena\")\n\t} else {\n\t\t_, err := time.Parse(\"2006-01-02\", birthDate)\n\t\tif err != nil {\n\t\t\tt.Error(\"El campo 'birth_date' no tiene un formato válido (YYYY-MM-DD)\")\n\t\t}\n\t}\n\n\tif languages, ok := person[\"programming_languages\"].([]string); !ok {\n\t\tt.Error(\"El campo 'programming_languages' no es un slice de cadenas\")\n\t} else if len(languages) == 0 {\n\t\tt.Error(\"El campo 'programming_languages' está vacío\")\n\t}\n}\n\nfunc TestPersonDictionaryValues(t *testing.T) {\n\tperson := map[string]interface{}{\n\t\t\"name\":                  \"John Doe\",\n\t\t\"age\":                   30,\n\t\t\"birth_date\":            \"1990-01-01\",\n\t\t\"programming_languages\": []string{\"Go\", \"Python\", \"JavaScript\"},\n\t}\n\n\texpectedPerson := map[string]interface{}{\n\t\t\"name\":                  \"John Doe\",\n\t\t\"age\":                   30,\n\t\t\"birth_date\":            \"1990-01-01\",\n\t\t\"programming_languages\": []string{\"Go\", \"Python\", \"JavaScript\"},\n\t}\n\n\tif !reflect.DeepEqual(person, expectedPerson) {\n\t\tt.Errorf(\"Los valores del diccionario no coinciden con los esperados\")\n\t}\n}\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/go/hozlucas28.go",
    "content": "package main\n\nimport (\n\t\"reflect\"\n\t\"strings\"\n\t\"testing\"\n)\n\n/*\n\tTests...\n*/\n\nfunc add(a int, b int) int {\n\treturn a + b\n}\n\n/*\n\tAdditional challenge...\n*/\n\nvar author map[string]interface{} = map[string]interface{}{\n\t\"name\":                  \"Lucas\",\n\t\"age\":                   \"22\",\n\t\"born_date\":             \"2002-02-20\",\n\t\"programming_languages\": []string{\"TypeScript\", \"Python\", \"Go (Golang)\"},\n}\n\n/*\n\tToda declaración, debajo del presente comentario, debe ser extraida a un archivo con el mismo nombre\n\tque el actual, pero finalizando con `*_test.go`, por ejemplo: `hozlucas28_test.go`. Caso contrario los\n\ttests no podrán ejecutarse.\n*/\n\n/*\n\tTests...\n*/\n\nfunc TestAddWithPositiveArguments(test *testing.T) {\n\tvar result int = add(1, 8)\n\tvar expected int = 9\n\n\tif result != expected {\n\t\ttest.Errorf(\"Test failed! add(1, 8) = %d, but expected to be %d\", result, expected)\n\t}\n}\n\nfunc TestAddWithNegativeArguments(test *testing.T) {\n\tvar result int = add(-5, -5)\n\tvar expected int = -10\n\n\tif result != expected {\n\t\ttest.Errorf(\"Test failed! add(-5, -5) = %d, but expected to be %d\", result, expected)\n\t}\n}\n\n/*\n\tAdditional challenge...\n*/\n\nfunc TestAuthorSchema(test *testing.T) {\n\t_, hasAge := author[\"age\"]\n\t_, hasBornDate := author[\"born_date\"]\n\t_, hasName := author[\"name\"]\n\t_, hasProgrammingLanguages := author[\"programming_languages\"]\n\n\tvar errorMessage []string = []string{}\n\n\tif !hasAge {\n\t\terrorMessage = append(errorMessage, \"age\")\n\t}\n\n\tif !hasBornDate {\n\t\terrorMessage = append(errorMessage, \"born_date\")\n\t}\n\n\tif !hasName {\n\t\terrorMessage = append(errorMessage, \"name\")\n\t}\n\n\tif !hasProgrammingLanguages {\n\t\terrorMessage = append(errorMessage, \"programming_languages\")\n\t}\n\n\tif len(errorMessage) > 0 {\n\t\tvar message string = strings.Join(errorMessage, \", \")\n\t\ttest.Errorf(\"Author schema is invalid! The following properties are missing: %s\", message)\n\t}\n}\n\nfunc TestAuthorDataTypes(test *testing.T) {\n\tisValidAge := reflect.ValueOf(author[\"age\"]).Kind() == reflect.String\n\tisValidBornDate := reflect.ValueOf(author[\"born_date\"]).Kind() == reflect.String\n\tisValidName := reflect.ValueOf(author[\"name\"]).Kind() == reflect.String\n\tisValidProgrammingLanguages := reflect.ValueOf(author[\"programming_languages\"]).Kind() == reflect.Slice\n\n\tvar errorMessage []string = []string{}\n\n\tif !isValidAge {\n\t\terrorMessage = append(errorMessage, \"age: string\")\n\t}\n\n\tif !isValidBornDate {\n\t\terrorMessage = append(errorMessage, \"born_date: string\")\n\t}\n\n\tif !isValidName {\n\t\terrorMessage = append(errorMessage, \"name: string\")\n\t}\n\n\tif !isValidProgrammingLanguages {\n\t\terrorMessage = append(errorMessage, \"programming_languages: []string\")\n\t}\n\n\tif len(errorMessage) > 0 {\n\t\tvar message string = strings.Join(errorMessage, \", \")\n\t\ttest.Errorf(\"Data types of the properties inside author are invalid! Data types of the properties should be: { %s }\", message)\n\t}\n\n}\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/go/kodenook.go",
    "content": "package main\n\nimport (\n\t\"testing\"\n)\n\nfunc Addition(num1, num2 uint8) uint8 {\n\treturn num1 + num2\n}\n\nfunc TestAddition(t *testing.T) {\n\tvar expected uint8 = 5\n\n\tgot := Addition(3, 2)\n\tif got != expected {\n\t\tt.Errorf(\"Expected: %v, got: %v\", expected, got)\n\t}\n}\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/go/qwik-zgheib.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n\t\"testing\"\n)\n\ntype BasicCalculator struct{}\n\nfunc (bc BasicCalculator) Sum(a, b int) int {\n\treturn a + b\n}\n\ntype Profile struct {\n\tName                 string\n\tAge                  int\n\tBirthDate            string\n\tProgrammingLanguages []string\n}\n\nfunc CreateProfile() Profile {\n\treturn Profile{\n\t\tName:                 \"Isaias Ramos López\",\n\t\tAge:                  21,\n\t\tBirthDate:            \"2002-11-09\",\n\t\tProgrammingLanguages: []string{\"Go\", \"Java\", \"Python\"},\n\t}\n}\n\nfunc main() {\n\tcalculator := BasicCalculator{}\n\tresult := calculator.Sum(3, 4)\n\tfmt.Println(\"Sum: \", result)\n\n\tprofile := CreateProfile()\n\tfmt.Println(\"Profile Name: \", profile.Name)\n\tfmt.Println(\"Profile Age: \", profile.Age)\n\tfmt.Println(\"Profile BirthDate: \", profile.BirthDate)\n\tfmt.Println(\"Profile ProgrammingLanguages: \", profile.ProgrammingLanguages)\n}\n\n/* - Create a new file named qwik-zgheib_test.go for the test */\n/* - import this packages: \"reflect\", \"testing\" */\n\n// test for exercise:\nfunc TestBasicCalculator_Sum(t *testing.T) {\n\tcalculator := BasicCalculator{}\n\n\ttests := []struct {\n\t\tname string\n\t\ta, b int\n\t\twant int\n\t}{\n\t\t{\"Sum of 1 and 1\", 1, 1, 2},\n\t\t{\"Sum of -1 and 1\", -1, 1, 0},\n\t\t{\"Sum of 0 and 0\", 0, 0, 0},\n\t\t{\"Sum of 100 and 200\", 100, 200, 300},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tif got := calculator.Sum(tt.a, tt.b); got != tt.want {\n\t\t\t\tt.Errorf(\"Sum(%d, %d) = %d; want %d\", tt.a, tt.b, got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\n// text for extra i\nfunc TestProfileFieldsExist(t *testing.T) {\n\tprofile := CreateProfile()\n\n\tif profile.Name == \"\" {\n\t\tt.Error(\"Expected field 'Name' to be present\")\n\t}\n\tif profile.Age == 0 {\n\t\tt.Error(\"Expected field 'Age' to be present\")\n\t}\n\tif profile.BirthDate == \"\" {\n\t\tt.Error(\"Expected field 'BirthDate' to be present\")\n\t}\n\tif len(profile.ProgrammingLanguages) == 0 {\n\t\tt.Error(\"Expected field 'ProgrammingLanguages' to be present\")\n\t}\n}\n\n// test for extra ii\nfunc TestProfileDataCorrectness(t *testing.T) {\n\texpectedProfile := Profile{\n\t\tName:                 \"Isaias Ramos López\",\n\t\tAge:                  21,\n\t\tBirthDate:            \"2002-11-09\",\n\t\tProgrammingLanguages: []string{\"Go\", \"Java\", \"Python\"},\n\t}\n\n\tprofile := CreateProfile()\n\n\tif profile.Name != expectedProfile.Name {\n\t\tt.Errorf(\"Expected Name to be %v, got %v\", expectedProfile.Name, profile.Name)\n\t}\n\tif profile.Age != expectedProfile.Age {\n\t\tt.Errorf(\"Expected Age to be %v, got %v\", expectedProfile.Age, profile.Age)\n\t}\n\tif profile.BirthDate != expectedProfile.BirthDate {\n\t\tt.Errorf(\"Expected BirthDate to be %v, got %v\", expectedProfile.BirthDate, profile.BirthDate)\n\t}\n\tif !reflect.DeepEqual(profile.ProgrammingLanguages, expectedProfile.ProgrammingLanguages) {\n\t\tt.Errorf(\"Expected ProgrammingLanguages to be %v, got %v\", expectedProfile.ProgrammingLanguages, profile.ProgrammingLanguages)\n\t}\n}\n\n/* run all test with go test -v*/\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/go/raynerpv2022.go",
    "content": "package main\n\nimport (\n\t\"testing\"\n)\n\n/*\n * EJERCICIO:\n * Crea una función que se encargue de sumar dos números y retornar\n * su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n * capaz de determinar si esa función se ejecuta correctamente.\n *\n */\n\nfunc SumaValue(a, b int) int {\n\treturn a + b\n}\n\nfunc TestSumaValue(t *testing.T) {\n\tresult := SumaValue(12, 2)\n\n\texpected := 14\n\tif result != expected {\n\t\tt.Errorf(\"SumeValue(12, 2) = %d; want %d\", result, expected)\n\t}\n}\n\nfunc TestSumaVAleustruct(t *testing.T) {\n\tsume := []struct {\n\t\ta int\n\t\tb int\n\t\tr int\n\t}{\n\t\t{2, 3, 5},\n\t\t{3, 5, 8},\n\t\t{89, 10, 99},\n\t\t{-1, 0, -1},\n\t}\n\tfor _, i := range sume {\n\t\tresult := SumaValue(i.a, i.b)\n\t\tif result != i.r {\n\t\t\tt.Errorf(\"SumeValue(%d, %d) = %d; want %d\", i.a, i.b, result, i.r)\n\t\t}\n\t}\n\n}\n\n/*\n* DIFICULTAD EXTRA (opcional):\n* Crea un diccionario con las siguientes claves y valores:\n* \"name\": \"Tu nombre\"\n* \"age\": \"Tu edad\"\n* \"birth_date\": \"Tu fecha de nacimiento\"\n* \"programming_languages\": [\"Listado de lenguajes de programación\"]\n* Crea dos test:\n* - Un primero que determine que existen todos los campos.\n* - Un segundo que determine que los datos introducidos son correctos.\n */\n\nvar dev = []map[string]interface{}{\n\t{\n\t\t\"name\":                  \"Alice\",\n\t\t\"age\":                   25,\n\t\t\"birth_date\":            \"15-06-1997\",\n\t\t\"programming_languages\": []string{\"Python\", \"C++\", \"Rust\"},\n\t},\n\t{\n\t\t\"name\":                  \"Bob\",\n\t\t\"age\":                   30,\n\t\t\"birth_date\":            \"15-06-1997\",\n\t\t\"programming_languages\": []string{\"JavaScript\", \"Ruby\"},\n\t},\n\t{\n\t\t\"name\":                  \"Charlie\",\n\t\t\"age\":                   22,\n\t\t\"birth_date\":            \"15-06-1997\",\n\t\t\"programming_languages\": []string{},\n\t},\n}\nvar field = []string{\"name\", \"age\", \"birth_date\", \"programming_languages\"}\n\nfunc TestField(t *testing.T) {\n\n\tfor i, d := range dev {\n\t\tfor _, k := range field {\n\t\t\tif _, isPresent := d[k]; !isPresent {\n\t\t\t\tt.Errorf(\"falta field %v en caso %v\\n\", k, i+1)\n\t\t\t}\n\t\t}\n\t}\n\n}\n\nfunc TestValue(t *testing.T) {\n\tfor i, d := range dev {\n\t\tif _, ok := d[\"name\"].(string); !ok {\n\t\t\tt.Errorf(\"en case %v, el field `name` no tiene valor valido para string\", i+1)\n\n\t\t}\n\t\tif _, ok := d[\"age\"].(int); !ok {\n\t\t\tt.Errorf(\"en case %v, el field `age` no tiene valor valido para Int\", i+1)\n\n\t\t}\n\t\tif _, ok := d[\"birth_date\"].(string); !ok {\n\t\t\tt.Errorf(\"en case %v, el field `birth_date` no tiene valor valido para string\", +1)\n\n\t\t}\n\t\tif _, ok := d[\"programming_languages\"].([]string); !ok {\n\t\t\tt.Errorf(\"en case %v, el field `programming_languages` no tiene valor valido para slice de string\", i+1)\n\n\t\t}\n\n\t}\n}\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/go/thegera4.go",
    "content": "package main\n\nimport (\n\t\"testing\"\n\t\"errors\"\n\t\"fmt\"\n)\n\ntype T interface{}\n\n// Función que recibe dos parámetros de tipo T (int o float) y devuelve la suma de los mismos\nfunc Suma(a, b T) (T, error) {\n\tswitch a.(type) {\n\t\tcase int:\n\t\t\tswitch b.(type) {\n\t\t\tcase int:\n\t\t\t\treturn a.(int) + b.(int), nil\n\t\t\tcase float64:\n\t\t\t\treturn float64(a.(int)) + b.(float64), nil\n\t\t\t}\n\t\tcase float64:\n\t\t\tswitch b.(type) {\n\t\t\tcase int:\n\t\t\t\treturn a.(float64) + float64(b.(int)), nil\n\t\t\tcase float64:\n\t\t\t\treturn a.(float64) + b.(float64), nil\n\t\t\t}\n\t\t}\n\t\treturn 0, errors.New(\"error: al menos uno de los parametros recibidos no es un numero\")\n}\n\nfunc main() {\n\t\n\tres, err := Suma(1,2)\n\tif err == nil { fmt.Println(res) } else { fmt.Println(err) }\n\n\tres, err = Suma(5.5, 4.3)\n\tif err == nil { fmt.Println(res) } else { fmt.Println(err)}\n\n\tres, err = Suma(5.5, 4)\n\tif err == nil { fmt.Println(res) } else { fmt.Println(err) }\n\n\tres, err = Suma(\"1\", 2)\n\tif err == nil { fmt.Println(res) } else { fmt.Println(err) }\n}\n\n// Los tests en go deben de ir en otro archivo separado (ver info en internet), se agrega aqui el test para efectos practicos\nfunc TestSuma(t *testing.T) {\n\t// Caso de prueba 1: Suma de dos enteros\n\tresultado, err := Suma(1, 2)\n\tif err != nil {\n\t\tt.Errorf(\"Error inesperado: %v\", err)\n\t}\n\texpected := 3\n\tif resultado != expected {\n\t\tt.Errorf(\"Suma(1, 2) = %v; esperado %v\", resultado, expected)\n\t}\n\n\t// Caso de prueba 2: Suma de dos números de punto flotante\n\tresultado, err = Suma(5.5, 4.3)\n\tif err != nil {\n\t\tt.Errorf(\"Error inesperado: %v\", err)\n\t}\n\texpectedFloat := 9.8\n\tif resultado != expectedFloat {\n\t\tt.Errorf(\"Suma(5.5, 4.3) = %v; esperado %v\", resultado, expectedFloat)\n\t}\n\n\t// Caso de prueba 3: Suma de un número de punto flotante y un entero\n\tresultado, err = Suma(5.5, 4)\n\tif err != nil {\n\t\tt.Errorf(\"Error inesperado: %v\", err)\n\t}\n\tif resultado != expectedFloat {\n\t\tt.Errorf(\"Suma(5.5, 4) = %v; esperado %v\", resultado, expectedFloat)\n\t}\n\n\t// Caso de prueba 4: Suma con un parámetro no numérico\n\t_, err = Suma(\"1\", 2)\n\texpectedError := \"error: al menos uno de los parametros recibidos no es un numero\"\n\tif err == nil || err.Error() != expectedError {\n\t\tt.Errorf(\"Error inesperado: %v; esperado %v\", err, expectedError)\n\t}\n}\n\n// Extra\n\n//Creamos una estructura para almacenar los datos\ntype Persona struct {\n\tName \t\tstring\n\tAge \t\tint\n\tBirthDate \tstring\n\tLanguages\t[]string\n}\n\n//Creamos una funcion que recibe un string y un slice de strings y verifica si el string esta en el slice\nfunc TestPersona(t *testing.T) {\n\tp := Persona{\n\t\tName:                 \"Gerardo\",\n\t\tAge:                  30,\n\t\tBirthDate:            \"03/07/1987\",\n\t\tLanguages: \t\t\t\t[]string{\"Go\", \"Python\", \"JavaScript\"},\n\t}\n\n\t// Prueba 1: Verificar que todos los campos existen\n\tif p.Name == \"\" || p.Age == 0 || p.BirthDate == \"\" || len(p.Languages) == 0 {\n\t\tt.Errorf(\"No todos los campos existen\")\n\t}\n\n\t// Prueba 2: Verificar que los datos introducidos son correctos\n\tif p.Name != \"Gerardo\" || p.Age != 30 || p.BirthDate != \"03/07/1987\" || !contains(p.Languages, \"Go\") {\n\t\tt.Errorf(\"Los datos introducidos no son correctos\")\n\t}\n}\n\nfunc contains(s []string, str string) bool {\n\tfor _, v := range s {\n\t\tif v == str {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/java/AmadorQuispe.java",
    "content": "public class ExampleUnitTesting {\n    public static int addition(int... numbers) throws Exception {\n        if (numbers.length == 0)\n            throw new Exception();\n        int result = Arrays.stream(numbers).reduce((cum, num) -> cum + num).getAsInt();\n\n        return result;\n    }\n\n    public static Map<String, String> myData() {\n        Map<String, String> data = new HashMap<>();\n        data.put(\"name\", \"Amador\");\n        data.put(\"age\", \"31\");\n        data.put(\"birth_date\", \"1992-07-13\");\n        data.put(\"programming_languages\", \"Java, Go, JavaScript\");\n        data.put(\"web\", \"amsoft.dev\");\n        return data;\n    }\n\n}\n\n//Dependecia para test\n/*\n<dependency>\n\t<groupId>org.junit.jupiter</groupId>\n\t<artifactId>junit-jupiter-engine</artifactId>\n\t<version>5.10.2</version>\n\t<scope>test</scope>\n</dependency>\n*/\n\n// Clase test\n\npublic class ExampleUnitTest {\n    @Test\n    void additionWithNumbers() {\n        try {\n            assertEquals(6, ExampleUnitTesting.addition(1, 2, 3));\n            assertEquals(20, ExampleUnitTesting.addition(20));\n            assertEquals(7, ExampleUnitTesting.addition(-1, 5, 3));\n            assertEquals(-3, ExampleUnitTesting.addition(-1, -5, 3));\n        } catch (Exception e) {\n            fail(\"No se debe lanzar una excepción para una entrada válida\");\n        }\n    }\n\n    @Test\n    void additionWithNoNumbers() {\n        assertThrows(Exception.class, () -> {\n            ExampleUnitTesting.addition();\n        });\n    }\n\n    Map<String, String> data = ExampleUnitTesting.myData();\n\n    @Test\n    void testKeysExist() {\n        assertEquals(5, data.size());\n        assertTrue(data.containsKey(\"name\"));\n        assertTrue(data.containsKey(\"age\"));\n        assertTrue(data.containsKey(\"birth_date\"));\n        assertTrue(data.containsKey(\"programming_languages\"));\n        assertTrue(data.containsKey(\"web\"));\n    }\n\n    @Test\n    void testMyDataCorrect() {\n        assertTrue(data.get(\"name\").equals(\"Amador\"));\n        assertTrue(data.get(\"age\").equals(\"31\"));\n        assertTrue(data.get(\"birth_date\").equals(\"1992-07-13\"));\n        assertTrue(data.get(\"programming_languages\").equals(\"Java, Go, JavaScript\"));\n        assertTrue(data.get(\"web\").equals(\"amsoft.dev\"));\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/java/AnaLauDB.java",
    "content": "import java.util.*;\n\npublic class AnaLauDB {\n\n    // Función para sumar\n    public static int sumar(int a, int b) {\n        return a + b;\n    }\n\n    // Diccionario con tus datos\n    public static Map<String, Object> crearDiccionario() {\n        Map<String, Object> datos = new HashMap<>();\n        datos.put(\"name\", \"Ana Laura\");\n        datos.put(\"age\", 28);\n        datos.put(\"birth_date\", \"1997-05-20\");\n        datos.put(\"programming_languages\", Arrays.asList(\"Java\", \"Python\", \"JavaScript\"));\n        return datos;\n    }\n\n    // Función que simula los tests\n    public static void ejecutarTests() {\n        System.out.println(\"=== Test función sumar ===\");\n        System.out.println(\"2 + 3 = \" + (sumar(2, 3) == 5 ? \"PASÓ\" : \"FALLÓ\"));\n        System.out.println(\"-2 + 2 = \" + (sumar(-2, 2) == 0 ? \"PASÓ\" : \"FALLÓ\"));\n        System.out.println(\"-3 + -4 = \" + (sumar(-3, -4) == -7 ? \"PASÓ\" : \"FALLÓ\"));\n\n        System.out.println(\"\\n=== Test diccionario ===\");\n        Map<String, Object> datos = crearDiccionario();\n        boolean camposOk = datos.containsKey(\"name\") && datos.containsKey(\"age\") &&\n                datos.containsKey(\"birth_date\") && datos.containsKey(\"programming_languages\");\n        System.out.println(\"Campos existentes: \" + (camposOk ? \"PASÓ\" : \"FALLÓ\"));\n\n        boolean valoresOk = datos.get(\"name\").equals(\"Ana Laura\") &&\n                (int) datos.get(\"age\") == 28 &&\n                datos.get(\"birth_date\").equals(\"1997-05-20\");\n        System.out.println(\"Valores correctos: \" + (valoresOk ? \"PASÓ\" : \"FALLÓ\"));\n    }\n\n    public static void main(String[] args) {\n        ejecutarTests();\n    }\n}\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/java/AstrarothDLCXVI.java",
    "content": "public class Astra {\n\n\t/*\n\t * Funcion que devuelve la suma de 2 numeros enteros*/\n\tpublic int sumar(int num1, int num2) {\n\t\tint sol = 0;\n\t\t\n\t\tsol = num1 + num2;\n\t\tSystem.out.println(sol);\n\t\treturn sol;\n\t}\n}\n\n\n\n//Test\n\nimport static org.junit.jupiter.api.Assertions.*;\nimport org.junit.jupiter.api.Test;\n\nclass SumarTest {\n\n\t@Test\n\tvoid testSumar() {\n\t\tAstra llamar = new Astra();\n\t\t\n\t\t/*numero positivo en los 2 numeros*/\n\t\tassertEquals(20, llamar.sumar(10, 10));\n\t\t/*numero positivo y negativo en los 2 con resultado positivo*/\n\t\tassertEquals(2, llamar.sumar(5, -3));\n\t\tassertEquals(5, llamar.sumar(-5, 10));\n\t\t/*numero positivo y negativo en los 2 con resultado negativo*/\n\t\tassertEquals(-8, llamar.sumar(-10, 2));\n\t\tassertEquals(-8, llamar.sumar(2, -10));\n\t}\n\n}\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/java/FranDev200.java",
    "content": "import org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\n\n/*\n    ------ POM.xml ------ [Partes añadidas]\n    <dependencies>\n\n        <!-- JUnit 5 -->\n        <dependency>\n            <groupId>org.junit.jupiter</groupId>\n            <artifactId>junit-jupiter</artifactId>\n            <version>5.10.1</version>\n            <scope>test</scope>\n        </dependency>\n\n    </dependencies>\n\n    <build>\n        <plugins>\n\n            <!-- Plugin necesario para ejecutar JUnit 5 -->\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-surefire-plugin</artifactId>\n                <version>3.2.5</version>\n            </plugin>\n\n        </plugins>\n    </build>\n\n\n */\n\npublic class FranDev200 {\n\n    /*\n\n    Crea una función que se encargue de sumar dos números y retornar su resultado.\n    * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n    * capaz de determinar si esa función se ejecuta correctamente.\n\n     */\n    public static int Sumar(int a, int b){\n\n        int resultado = a + b;\n        return resultado;\n\n    }\n\n    @Test\n    public void testSumar(){\n        int sumar = Sumar(1,2);\n        Assertions.assertEquals(sumar,1); // Da ERROR\n        Assertions.assertEquals(sumar,3); // No da ERROR\n        Assertions.assertEquals(sumar,2); // Da ERROR\n    }\n\n    /*\n\n    DIFICULTAD EXTRA (opcional):\n    * Crea un diccionario con las siguientes claves y valores:\n    * \"name\": \"Tu nombre\"\n    * \"age\": \"Tu edad\"\n    * \"birth_date\": \"Tu fecha de nacimiento\"\n    * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n    * Crea dos test:\n    * - Un primero que determine que existen todos los campos.\n    * - Un segundo que determine que los datos introducidos son correctos.\n\n     */\n\n    public static HashMap<String,Object> crearPersona(){\n\n        ArrayList<String> lenguajesProgramacion = new ArrayList<>();\n        lenguajesProgramacion.add(\"Java\");\n        lenguajesProgramacion.add(\"Python\");\n        lenguajesProgramacion.add(\"SQL\");\n        lenguajesProgramacion.add(\"C#\");\n\n        HashMap<String,Object> persona = new HashMap<>();\n        persona.put(\"name\",\"Fran\");\n        persona.put(\"age\", 20);\n        persona.put(\"birth_date\", \"13-12-2005\");\n        persona.put(\"programming_languages\", lenguajesProgramacion);\n\n        return persona;\n\n    }\n\n    @Test\n    public void todosLosCampos(){\n\n        HashMap<String,Object> persona = crearPersona();\n        Assertions.assertTrue(persona.containsKey(\"name\"));\n        Assertions.assertTrue(persona.containsKey(\"age\"));\n        Assertions.assertTrue(persona.containsKey(\"birth_date\"));\n        Assertions.assertTrue(persona.containsKey(\"programming_languages\"));\n\n        System.out.println(\"Todos los campos están incluidos. [Test 1]\");\n\n    }\n\n    @Test\n    public void verificarDatos(){\n\n        String nombre = \"Fran\";\n        int edad = 20;\n        String fechaNacimiento = \"13-12-2005\";\n        ArrayList<String> lenguajesProgramacion = new ArrayList<>();\n        lenguajesProgramacion.add(\"Java\");\n        lenguajesProgramacion.add(\"Python\");\n        lenguajesProgramacion.add(\"SQL\");\n        lenguajesProgramacion.add(\"C#\");\n\n        HashMap<String,Object> persona = crearPersona();\n\n        Assertions.assertEquals(nombre,persona.get(\"name\"));\n        Assertions.assertEquals(edad,persona.get(\"age\"));\n        Assertions.assertEquals(fechaNacimiento,persona.get(\"birth_date\"));\n        Assertions.assertEquals(lenguajesProgramacion,persona.get(\"programming_languages\"));\n\n        System.out.println(\"Todos los campos coinciden. [Test 2]\");\n\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/java/JimsimroDev.java",
    "content": "/*\nInstallar JUnit para las pruebas unitarias en\nhttps://github.com/junit-team/junit4/wiki/Download-and-Install\nSe puede usar el .jar para proyectos creados con ant\nPara proyectos creados con Maven se puede usar el plugin\n<dependency>\n  <groupId>junit</groupId>\n  <artifactId>junit</artifactId>\n  <version>4.13</version>\n  <scope>test</scope>\n</dependency>\nAgregando esto a las dependencias del proyecto en el pom.xml\n*/\n\npackage com.jimsimrodev;\n\nimport java.util.Arrays;\nimport java.util.Collection;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.Parameterized;\nimport java.time.LocalDate;\nimport static java.time.format.DateTimeFormatter.ofPattern;\nimport static com.jimsimrodev.Suma.suma;\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertFalse;\nimport static org.junit.Assert.assertNotNull;\n\nimport static java.time.format.DateTimeFormatter.ofPattern;\n\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.time.LocalDate;\n\n/**\n * Suma\n */\npublic class Suma {\n  public static double suma(double a, double b) {\n    return a + b;\n  }\n\n  /**\n   * @return\n   */\n  public static Collection<String[]> data() {\n    return Arrays.asList(\n        new String[][] {\n            { \"Name: \", \"JimsimroDev\" },\n            { \"age: \", \"28\" },\n            { \"birthDate: \", LocalDate.now().format(ofPattern(\"dd/MM/yyyy\")) },\n            { \"programinLenguages: \", \"Java, Python, C++, C#\" },\n        });\n  }\n\n  public static void print(double resultado) {\n    System.out.printf(\"La suma es: %s%n\", resultado);\n  }\n\n  // Esta clase debe ir en el paquete de pruebas unitarias\n\n  @RunWith(Parameterized.class)\n  public class SumaTest {\n    private final String key;\n    private final String value;\n\n    public SumaTest(String key, String value) {\n      this.key = key;\n      this.value = value;\n    }\n\n    @Test\n    public void sumaTest() {\n\n      // Para operaciones con decimales\n      Assertions.assertEquals(6.0, suma(4.0, 2.0), 0.0001);\n      assertEquals(-2.0, suma(5.0, -7.0), 0.0001);\n      assertEquals(0.0, suma(0.0, 0.0), 0.0001);\n      assertEquals(4.6, suma(2.5, 2.1), 0.0001);\n      assertEquals(4.1, suma(2.1, 2.0), 0.0001);\n      assertEquals(5.0, suma(2.5, 2.5), 0.0001);\n      assertEquals(4.5, suma(2, 2.5), 0.0001);\n      // assertEquals(5.0, suma(\"2.5\", 2.5), 0.0001);//error\n    }\n\n    // Pruebas parametrizables\n    @Parameterized.Parameters\n    public static Collection<String[]> data() {\n      return Arrays.asList(\n          new String[][] {\n              { \"name: \", \"jimsimrodev\" },\n              { \"age: \", \"28\" },\n              { \"birthDate: \", LocalDate.now().format(ofPattern(\"dd/MM/yyyy\")) },\n              { \"programinlenguages: \", \"java, python, c++, c#\" },\n          });\n    }\n\n    @Test\n    public void testfieldsexist() {\n      assertNotNull(\"La clave no debe ser nula\", key);\n      assertFalse(\"La clave no debe estar vacía\", key.trim().isEmpty());\n      assertNotNull(\"El valor no debe ser nulo\", value);\n      assertFalse(\"El valor no debe estar vacío\", value.trim().isEmpty());\n\n    }\n\n  }\n\n  public static void main(String[] args) {\n    print(suma(4, 2));\n    print(suma(-4.0, 2.0));\n\n    for (String[] data : data()) {\n      for (String string : data) {\n        System.out.print(string);\n      }\n      System.out.println(\" \");\n    }\n  }\n}\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/java/Josegs95.java",
    "content": "import org.junit.BeforeClass;\nimport org.junit.Test;\n\nimport java.util.*;\n\nimport static org.junit.Assert.*;\n\npublic class Josegs95 {\n    public static void main(String[] args) {}\n\n    //Ejercicio\n\n    public static int sum(int n1, int n2){\n        return n1 + n2;\n    }\n\n    @Test\n    public void testSumMethod(){\n        assertEquals(\"Comprobación suma estandar\", 10, sum(3, 7));\n        assertEquals(\"Comprobación suma con números negativos\", 2, sum(8, -6));\n        assertEquals(\"Comprobación suma con ceros\", 5, sum(5, 0));\n    }\n\n    //Reto\n\n    static Map<String, Object> data;\n\n    @BeforeClass\n    public static void initData(){\n        data = new HashMap<>();\n\n        data.put(\"name\", \"Jose\");\n        data.put(\"age\", 29);\n        data.put(\"birth_date\", \"28-02-1995\");\n        data.put(\"programming_languages\", Arrays.asList(\"Java\", \"Python\"));\n    }\n\n    @Test\n    public void testDataExistence(){\n        assertNotNull(\"¿Campo name es nulo?\", data.get(\"name\"));\n        assertNotNull(\"¿Campo age es nulo?\", data.get(\"age\"));\n        assertNotNull(\"¿Campo birth_date es nulo?\", data.get(\"birth_date\"));\n        assertNotNull(\"¿Campo programming_languages es nulo?\", data.get(\"programming_languages\"));\n    }\n\n    @Test\n    public void testDataCorrectValues(){\n        assertEquals(\"Valor de name\", String.class, data.get(\"name\").getClass());\n        assertEquals(\"Valor de age\", Integer.class, data.get(\"age\").getClass());\n        assertTrue(\"Valor de birth_date\", data.get(\"birth_date\") instanceof String);\n        assertTrue(\"Valor de programming_languages\", data.get(\"programming_languages\") instanceof List);\n    }\n}\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/java/asjordi.java",
    "content": "import java.util.HashMap;\nimport java.util.Map;\n\npublic class EjemploPruebasUnitarias {\n\n    /**\n     * Función que suma dos números enteros y devuelve el resultado.\n     */\n    public static int sumar(int a, int b) {\n\t\treturn a + b;\n    }\n\n    /**\n     * Test para la función sumar\n     */\n\n//    @Test\n//    void testSumar() {\n//        assertEquals(5, EjemploPruebasUnitarias.sumar(2, 3), \"2 + 3 = 5\");\n//        assertEquals(0, EjemploPruebasUnitarias.sumar(-2, 2), \"-2 + 2 = 0\");\n//        assertEquals(0, EjemploPruebasUnitarias.sumar(0, 0), \"0 + 0 = 0\");\n//    }\n\n    /**\n     * Función que devuelve un Map con datos de ejemplo.\n     */\n    public static Map<String, String> obtenerDatos() {\n        Map<String, String> datos = new HashMap<>();\n        datos.put(\"name\", \"Jordi\");\n        datos.put(\"age\", \"20\");\n        datos.put(\"birth_date\", \"2000-01-01\");\n        datos.put(\"programming_languages\", \"Java, Python, JavaScript\");\n        return datos;\n    }\n\n    /**\n     * Test para la función obtenerDatos\n     */\n\n//    @Nested\n//    @DisplayName(\"Test para la función obtenerDatos\")\n//    class ObtenerDatosTest {\n//\n//        Map<String, String> datos = EjemploPruebasUnitarias.obtenerDatos();\n//\n//        @Test\n//        void testContieneTodosLosCampos() {\n//            assertEquals(4, datos.size());\n//            assertTrue(datos.containsKey(\"name\"));\n//            assertTrue(datos.containsKey(\"age\"));\n//            assertTrue(datos.containsKey(\"birth_date\"));\n//            assertTrue(datos.containsKey(\"programming_languages\"));\n//        }\n//\n//        @Test\n//        void testCampoName() {\n//            assertEquals(\"Jordi\", datos.get(\"name\"));\n//        }\n//\n//        @Test\n//        void testCampoAge() {\n//            assertEquals(\"20\", datos.get(\"age\"));\n//        }\n//\n//        @Test\n//        void testCampoBirthDate() {\n//            assertEquals(\"2000-01-01\", datos.get(\"birth_date\"));\n//        }\n//\n//        @Test\n//        void testCampoProgrammingLanguages() {\n//            assertEquals(\"Java, Python, JavaScript\", datos.get(\"programming_languages\"));\n//        }\n//\n//    }\n\n    /**\n     * Maven dependency for JUnit 5:\n     * <dependency>\n     *     <groupId>org.junit.jupiter</groupId>\n     *     <artifactId>junit-jupiter</artifactId>\n     *     <version>5.10.2</version>\n     *     <scope>test</scope>\n     * </dependency>\n     */\n\n}\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/java/cesar-ch.java",
    "content": "/*\n    * #13 PRUEBAS UNITARIAS \n*/\nimport java.util.Arrays;\n\npublic class Main13 {\n    public static void main(String[] args) {\n        int result1 = sum(2, 3);\n        if (result1 == 5) {\n            System.out.println(\"Test passed\");\n        } else {\n            System.err.println(\"Error: The sum of 2 and 3 is not equal to 5\");\n        }\n\n        Person person = new Person(\"cesar-ch\", 3, \"2021-02-03\", new String[]{\"Javascript\", \"Python\", \"Java\"});\n\n        String[] expectedKeys = {\"name\", \"age\", \"birthDate\", \"programmingLanguages\"};\n        boolean allKeysExist = Arrays.stream(expectedKeys).allMatch(person::containsKey);\n        if (allKeysExist) {\n            System.out.println(\"Test passed\");\n        } else {\n            System.err.println(\"Error: The person object does not have the expected keys\");\n        }\n\n        if (!(person.getName() instanceof String)) {\n            System.err.println(\"Error: The name field is not a string\");\n        }\n\n        if (person.getAge() < 0) {\n            System.err.println(\"Error: Age must be a positive number\");\n        }\n\n        if (!person.getBirthDate().matches(\"\\\\d{4}-\\\\d{2}-\\\\d{2}\")) {\n            System.err.println(\"Error: Birth date is not in the expected format\");\n        }\n\n        if (!(person.getProgrammingLanguages() instanceof String[])) {\n            System.err.println(\"Error: Programming languages is not an array\");\n        }\n    }\n\n    public static int sum(int num1, int num2) {\n        return num1 + num2;\n    }\n}\n\n/*\n    * DIFICULTAD EXTRA\n*/\n\nclass Person {\n    private String name;\n    private int age;\n    private String birthDate;\n    private String[] programmingLanguages;\n\n    public Person(String name, int age, String birthDate, String[] programmingLanguages) {\n        this.name = name;\n        this.age = age;\n        this.birthDate = birthDate;\n        this.programmingLanguages = programmingLanguages;\n    }\n\n    public boolean containsKey(String key) {\n        switch (key) {\n            case \"name\":\n                return name != null;\n            case \"age\":\n                return true; // age is always present\n            case \"birthDate\":\n                return birthDate != null;\n            case \"programmingLanguages\":\n                return programmingLanguages != null;\n            default:\n                return false;\n        }\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public int getAge() {\n        return age;\n    }\n\n    public String getBirthDate() {\n        return birthDate;\n    }\n\n    public String[] getProgrammingLanguages() {\n        return programmingLanguages;\n    }\n}\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/java/chartypes.java",
    "content": "import static org.junit.Assert.assertEquals;\nimport org.junit.Test;\n\npublic class chartypes {\n\n    public static void main(String[] args) {\n        Tests.addSumCorrectly();\n    }\n\n    // Exercise\n    public static int add(int x, int y) {\n        return x + y;\n    }\n}\n\nclass Tests {\n    @Test\n    static void addSumCorrectly() {\n        assertEquals(4, chartypes.add(2, 2));\n        assertEquals(5, chartypes.add(3, 2));\n        assertEquals(0, chartypes.add(0, 0));\n        assertEquals(100, chartypes.add(99, 1));\n        assertEquals(1, chartypes.add(0, 1));\n    }\n}"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/java/eulogioep.java",
    "content": "import java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.Map;\nimport org.junit.jupiter.api.Test;\nimport static org.junit.jupiter.api.Assertions.*;\n\n/**\n * Clase principal que contiene la función de suma y el diccionario de datos personales.\n */\npublic class eulogioep {\n\n    /**\n     * Función que suma dos números y retorna el resultado.\n     * @param a Primer número a sumar.\n     * @param b Segundo número a sumar.\n     * @return La suma de a y b.\n     */\n    public static int suma(int a, int b) {\n        return a + b;\n    }\n\n    /**\n     * Crea y retorna un diccionario (Map en Java) con datos personales.\n     * @return Map con datos personales.\n     */\n    public static Map<String, Object> crearDiccionario() {\n        Map<String, Object> diccionario = new HashMap<>();\n        diccionario.put(\"name\", \"Tu nombre\");\n        diccionario.put(\"age\", 30);\n        diccionario.put(\"birth_date\", \"1993-01-01\");\n        diccionario.put(\"programming_languages\", Arrays.asList(\"Java\", \"Python\", \"JavaScript\"));\n        return diccionario;\n    }\n\n    /**\n     * Clase interna para las pruebas unitarias.\n     */\n    public static class Tests {\n\n        @Test\n        public void testSuma() {\n            assertEquals(5, suma(2, 3), \"La suma de 2 y 3 debería ser 5\");\n            assertEquals(0, suma(-1, 1), \"La suma de -1 y 1 debería ser 0\");\n            assertEquals(-5, suma(-2, -3), \"La suma de -2 y -3 debería ser -5\");\n        }\n\n        @Test\n        public void testExistenciaCamposDiccionario() {\n            Map<String, Object> diccionario = crearDiccionario();\n            assertTrue(diccionario.containsKey(\"name\"), \"El diccionario debe contener la clave 'name'\");\n            assertTrue(diccionario.containsKey(\"age\"), \"El diccionario debe contener la clave 'age'\");\n            assertTrue(diccionario.containsKey(\"birth_date\"), \"El diccionario debe contener la clave 'birth_date'\");\n            assertTrue(diccionario.containsKey(\"programming_languages\"), \"El diccionario debe contener la clave 'programming_languages'\");\n        }\n\n        @Test\n        public void testDatosCorrectosDiccionario() {\n            Map<String, Object> diccionario = crearDiccionario();\n            assertEquals(\"Tu nombre\", diccionario.get(\"name\"), \"El nombre debe ser 'Tu nombre'\");\n            assertTrue(diccionario.get(\"age\") instanceof Integer, \"La edad debe ser un entero\");\n            assertTrue(((String) diccionario.get(\"birth_date\")).matches(\"\\\\d{4}-\\\\d{2}-\\\\d{2}\"), \"La fecha de nacimiento debe tener el formato YYYY-MM-DD\");\n            assertTrue(diccionario.get(\"programming_languages\") instanceof java.util.List, \"Los lenguajes de programación deben ser una lista\");\n            assertTrue(((java.util.List<?>) diccionario.get(\"programming_languages\")).size() > 0, \"La lista de lenguajes de programación no debe estar vacía\");\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/java/jmichael39.java",
    "content": "import java.util.HashMap;\n\npublic class PruebasJUNIT {\n    HashMap<String, String> map = new HashMap<>();\n\n    public int sumar(int num1, int num2) {\n        return num1 + num2;\n    }\n\n    public void setMap() {\n        map.put(\"name\", \"Michael\");\n        map.put(\"age\", \"31\");\n        map.put(\"birth_date\", \"06/02/1993\");\n        map.put(\"programming_languages\", \"JAVA\");\n    }\n}\n\n// TESTS\n\nimport org.junit.Before;\nimport org.junit.Test;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertTrue;\n\npublic class TestJUNIT {\n    private PruebasJUNIT pruebasJUNIT;\n\n    @Before\n    public void setUp() {\n        pruebasJUNIT = new PruebasJUNIT();\n        pruebasJUNIT.setMap();\n    }\n\n    @Test\n    public void testSum() {\n        assertEquals(5, pruebasJUNIT.sumar(2, 3));\n    }\n\n    @Test\n    public void testMapKeys() {\n        assertTrue(pruebasJUNIT.map.containsKey(\"name\"));\n        assertTrue(pruebasJUNIT.map.containsKey(\"age\"));\n        assertTrue(pruebasJUNIT.map.containsKey(\"birth_date\"));\n        assertTrue(pruebasJUNIT.map.containsKey(\"programming_languages\"));\n    }\n\n    @Test\n    public void testMapValues() {\n        assertTrue(pruebasJUNIT.map.containsValue(\"Michael\"));\n        assertTrue(pruebasJUNIT.map.containsValue(\"31\"));\n        assertTrue(pruebasJUNIT.map.containsValue(\"06/02/1993\"));\n        assertTrue(pruebasJUNIT.map.containsValue(\"JAVA\"));\n    }\n}"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/java/martinbohorquez.java",
    "content": "import org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Nested;\nimport org.junit.jupiter.api.Test;\n\nimport java.time.LocalDate;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport static org.junit.jupiter.api.Assertions.*;\n\n/**\n * #13 PRUEBAS UNITARIAS\n * <dependencies>\n * <dependency>\n * <groupId>org.junit.jupiter</groupId>\n * <artifactId>junit-jupiter</artifactId>\n * <version>5.10.3</version>\n * </dependency>\n * </dependencies>\n *\n * @author martinbohorquez\n */\npublic class martinbohorquez {\n    public static void main(String[] args) throws Exception {\n        System.out.println(sum(23, 19));\n    }\n\n    private static Object sum(Object a, Object b) throws Exception {\n        if (!(a instanceof Integer) || !(b instanceof Integer))\n            throw new Exception(\"Los argumentos deben ser enteros positivos!\");\n        return ((Integer) a) + ((Integer) b);\n    }\n\n    /*\n     * DIFICULTAD EXTRA\n     */\n    private static Map<String, String> programmer() {\n        Map<String, String> programmer = new HashMap<>();\n        programmer.put(\"name\", \"Martin\");\n        Integer age = 29;\n        programmer.put(\"age\", String.valueOf(age));\n        LocalDate birthDate = LocalDate.of(1994, 9, 26);\n        programmer.put(\"birthDate\", String.valueOf(birthDate));\n        ArrayList<String> programmingLanguage = new ArrayList<>(Arrays.asList(\"Java\", \"Typescript\", \"Python\"));\n        programmer.put(\"programmingLanguage\", String.valueOf(programmingLanguage));\n        return programmer;\n    }\n\n    @Nested\n    class TestMain {\n\n        Map<String, String> data;\n        Map<String, String> programmer = programmer();\n\n        @BeforeEach\n        void setUp() {\n            data = new HashMap<>();\n            data.put(\"name\", \"Martin\");\n            Integer age = 29;\n            data.put(\"age\", String.valueOf(age));\n            LocalDate birthDate = LocalDate.of(1994, 9, 26);\n            data.put(\"birthDate\", String.valueOf(birthDate));\n            ArrayList<String> programmingLanguage = new ArrayList<>(Arrays.asList(\"Java\", \"Typescript\", \"Python\"));\n            data.put(\"programmingLanguage\", String.valueOf(programmingLanguage));\n        }\n\n        @Test\n        void testSum() throws Exception {\n            assertEquals(37, sum(14, 23));\n            assertEquals(10, sum(15, -5));\n            assertEquals(25, sum(-10, 35));\n            assertEquals(-15, sum(-20, 5));\n            assertEquals(-5, sum(20, -25));\n            assertEquals(-20, sum(-15, -5));\n        }\n\n        @Test\n        void testSumTypes() throws Exception {\n            String esperado = \"Los argumentos deben ser enteros positivos!\";\n            Exception exceptionDouble = assertThrows(Exception.class, () -> sum(5, 2.5));\n            String actual = exceptionDouble.getMessage();\n            assertEquals(esperado, actual);\n            Exception exceptionString = assertThrows(Exception.class, () -> sum(\"5\", 2));\n            actual = exceptionString.getMessage();\n            assertEquals(esperado, actual);\n        }\n\n        @Test\n        void testMapSize() {\n            assertEquals(programmer.size(), data.size());\n        }\n\n        @Test\n        void testKeysExist() {\n            programmer.keySet().forEach(key -> assertTrue(data.containsKey(key)));\n        }\n\n        @Test\n        void testValuesCorrect() {\n            programmer.keySet().forEach(key -> assertEquals(programmer.get(key), data.get(key)));\n        }\n\n        @Test\n        void testValuesInstance() {\n            programmer.keySet().forEach(key -> assertInstanceOf(programmer.get(key).getClass(), data.get(key)));\n        }\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/java/simonguzman.java",
    "content": "\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\npublic class simonguzman {\n    public static void main(String[] args) {\n        assert sumar(10, 5) == 15;\n        assert sumar(-10, 5) == -5;\n        assert sumar(0, 0) == 0;\n\n        assert Math.abs(sumar(10.5, 5.5) - 16.0) < 0.0001;\n        assert Math.abs(sumar(-10.5, 5.5) - (-5.0)) < 0.0001;\n        assert Math.abs(sumar(0.0, 0.0)) < 0.0001;\n\n        String numStr1 = \"10\";\n        int num1 = Integer.parseInt(numStr1);\n        int resultado1 = sumar(num1, 5);\n        assert resultado1 == 15;\n\n        String numStr2 = \"10.5\";\n        double num2 = Double.parseDouble(numStr2);\n        double resultado2 = sumar(num2, 5.5);\n        assert Math.abs(resultado2 - 16.0) < 0.0001;\n\n        String numStrInvalido = \"abc\";\n        try {\n            int numInvalido = Integer.parseInt(numStrInvalido);\n            assert false; \n        } catch (NumberFormatException e) {\n            assert true;\n        }\n        System.out.println(\"Todas las pruebas pasaron correctamente. \");\n        pruebaDiccionario();\n    }    \n\n    public static int sumar(int num1, int num2){\n        return num1 + num2;\n    }\n\n    \n    public static double sumar(double num1, double num2){\n        return num1 + num2;\n    }\n\n    static void pruebaDiccionario(){\n        Map<String, Object> datosPersona = new HashMap<>();\n        datosPersona.put(\"name\", \"Simon Guzman\");\n        datosPersona.put(\"age\", 22);\n        datosPersona.put(\"birth_date\", \"28-11-2001\");\n        datosPersona.put(\"programming_languages\", Arrays.asList(\"Java\", \"Python\",\"C++\"));\n\n        try {\n            verificarExistenciaDatos(datosPersona);\n            verificarValidezDatos(datosPersona);    \n            System.out.println(\"Todos los datos son validos\");\n        } catch (AssertionError e) {\n            System.out.println(\"Validacion fallida: \"+e.getMessage());\n        }\n        \n    }\n\n    static void verificarExistenciaDatos(Map<String, Object> datos){\n        assert datos.containsKey(\"name\") : \"El campo 'name' no existe en el diccionario.\";\n        assert datos.containsKey(\"age\") : \"El campo 'age' no existe en el diccionario.\";\n        assert datos.containsKey(\"birth_date\") : \"El campo 'birth_date' no existe en el diccionario.\";;\n        assert datos.containsKey(\"programming_languages\"): \"El campo 'programming_languages' no existe en el diccionario.\";;\n\n        System.out.println(\"Todos los campos existen en el diccionario.\");\n    }\n\n    static void verificarValidezDatos(Map<String, Object> datos){\n        assert datos.get(\"name\").equals(\"Simon Guzman\") : \"El valor del campo 'name' no es válido.\";\n        assert datos.get(\"age\").equals(22) : \"El valor del campo 'age' no es válido.\";\n        assert datos.get(\"birth_date\").equals(\"28-11-2001\") : \"El valor del campo 'birth_date' no es válido.\";\n\n        List<String> lenguajes = (List<String>) datos.get(\"programming_languages\");\n        assert lenguajes.contains(\"Java\") : \"El lenguaje 'Java' no está en la lista.\";\n        assert lenguajes.contains(\"Python\") : \"El lenguaje 'Python' no está en la lista.\";\n        assert lenguajes.contains(\"C++\") : \"El lenguaje 'C++' no está en la lista.\";\n\n        System.out.println(\"Todos los datos son validos.\");\n    }\n}\n\n\n\n\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/javascript/7R0N1X.js",
    "content": "const sumar = (n1, n2) => n1 + n2\n\n// Pruebas manuales\nconsole.log(sumar(2, 3) === 5); // true\nconsole.log(sumar(-1, 1) === 0); // true\nconsole.log(sumar(0, 0) === 0); // true\n\n\n// Testing Automatizado (sin framework)\nconst assert = (description, result) => {\n  if (result) {\n    console.log(`✔️  ${description}`);\n  } else {\n    console.error(`❌  ${description}`);\n  }\n};\n\nconst tests = () => {\n  assert(\"Suma de 2 y 3 es 5\", sumar(2, 3) === 5);\n  assert(\"Suma de -1 y 1 es 0\", sumar(-1, 1) === 0);\n  assert(\"Suma de 0 y 0 es 0\", sumar(0, 0) === 0);\n};\n\ntests();\n\n\n// Dificultad extra\nconst persona = {\n  name: \"7R0N1X\",\n  age: \"25\",\n  birth_date: \"30-08-1999\",\n  programming_languages: [\"HTML\", \"CSS\", \"JS\"]\n};\n\nconst testCamposExistentes = (persona) => {\n  const expectedFields = [\"name\", \"age\", \"birth_date\", \"programming_languages\"];\n  return expectedFields.every(field => field in persona);\n};\n\n// Test\nconsole.log(testCamposExistentes(persona) ? \"✔️ Todos los campos existen\" : \"❌ Faltan campos\");\n\n\nconst testDatosCorrectos = (persona) => {\n  return (\n    persona.name === \"7R0N1X\" &&\n    persona.age === \"25\" &&\n    persona.birth_date === \"30-08-1999\" &&\n    Array.isArray(persona.programming_languages) &&\n    persona.programming_languages.length > 0\n  );\n};\n\n// Test\nconsole.log(testDatosCorrectos(persona) ? \"✔️ Los datos son correctos\" : \"❌ Los datos no son correctos\");\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/javascript/AChapeton.js",
    "content": "// ! NOTA: El archivo utiliza la libreria Jest. Para utilizarlo, seguir los siguientes pasos:\n// 1. Se debe de ejecutar el comando \"npm i --save-dev jest\"\n// 2. En la lista de scripts dentro de package.json, incluir \"test\": \"jest\"\n// 3. Cambiar el nombre del archivo a \"AChapeton.test.js\"\n\nconst sum = (a, b) => {\n  return a + b\n}\n\ndescribe('Funcion Sum', () => {\n  test('Debe de sumar dos numeros', () => {\n    expect(sum(1, 2)).toBe(3)\n  })\n})\n\n// DIFICULTAD EXTRA\n\nconst diccionario = {\n  name: \"Andres\", \n  age: 26,\n  birth_date: '02/06/1997',\n  programming_languages: [\n    \"TypeScript\", \"JavaScript\", \"Python\"\n  ]\n}\n\ndescribe('Diccionario', () => {\n  test('Deben de existir los 4 campos', () => {\n    const keys = Object.keys(diccionario)\n    expect(keys).toContain('name')\n    expect(keys).toContain('age')\n    expect(keys).toContain('birth_date')\n    expect(keys).toContain('programming_languages')\n  })\n\n  test('Los datos deben de ser correctos', () => {\n    const values = Object.values(diccionario)\n    expect(values).toContain('Andres')\n    expect(values).toContain(26)\n    expect(values).toContain('02/06/1997')\n    expect(values[3]).toEqual([\n      \"TypeScript\", \"JavaScript\", \"Python\"\n    ])\n  })\n})"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/javascript/DavidMoralesDeveloper.js",
    "content": "// Crea una función que se encargue de sumar dos números y retornar\n// * su resultado.\n// * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n// * capaz de determinar si esa función se ejecuta correctamente.\n\nconst assert = require('assert');\n\n// Función a probar\nfunction suma(a, b) {\n    return a + b;\n  }\n \n  \n  // Prueba para sumar 5 + 5\n  function pruebasumar5y5() {\n    const resultado = suma(5, 5);\n    const esperado = 10;\n    assert.strictEqual(resultado, esperado, '5 + 5 debería ser 10');\n    console.log('Prueba sumar 5 + 5 pasó correctamente');\n  }\n  \n  // Ejecutar la prueba\n  pruebasumar5y5();\n\n//   ---------------------\n\n  //sumar cualquier numero con suma y resultado como argumento\n  \n\n  \n  console.log('Todas las pruebas completadas');\n\n  let suma1 = suma(7, 4)\n  let resultado = 11\n  let clg = '7 + 4 = 11'\n  let suma2 = suma(8, 8)\n  // let resultado2 = 16\n  let clg1 = '8 + 8 = 16'\n//   let suma3 = suma(2, 4)\n//   let resultado3 = 5 //error forzado\n//   let clg2 = '2 + 4 = 5, el resultado deberia ser 6' //crea un error y se cierra el programma\n  \n  function cuaquierSuma(suma, resultado, clg){\n    assert.strictEqual(suma, resultado, 'son iguales')\n    console.log(clg)\n  }\n\n  cuaquierSuma(suma1, resultado, clg)\n  cuaquierSuma(suma2, 16, clg1)\n//   cuaquierSuma(suma3, resultado3, clg2)\n\n  //Ejercicio\n\n\nconst diccionario = {\n    name : 'David',\n    age : 30,\n    birth_date : new Date(\"1987-04-29\"),\n    programming_languages : ['javaScript', 'Python', 'typeScript']\n\n}\n\nconsole.log(Object.values(diccionario))\nconsole.log(Object.keys(diccionario))\n\n//  * Crea dos test:\n//  * - Un primero que determine que existen todos los campos.\n//  * - Un segundo que determine que los datos introducidos son correctos.\n\n\n\n// primer intento xd -----------------\n// function test1 (valores1) {\n//     const resultados = Object.values(valores1)\n//     const respuestas = ['David', 30, '05 / 05 /92', [ 'javaScript', 'Python', 'typeScript' ]]\n//     assert.strictEqual(resultados, respuestas)\n//     console.log('son iguales' )\n// }\n// test1(diccionario)\n\nfunction campos (obj) {\n    const arr = Object.keys(obj)\n    console.log( 'incluye name?' + arr.includes('name'))\n    assert.strictEqual(arr[0], 'name')\n    console.log('test pasado de name')\n    console.log( 'incluye age?' + arr.includes('age'))\n    assert.strictEqual(arr[1], 'age')\n    console.log('test pasado de age')\n    console.log( 'incluye birth_date?' + arr.includes('birth_date'))\n    assert.strictEqual(arr[2], 'birth_date')\n    console.log('test pasado de birth_date')\n    console.log( 'incluye programming_languages?' + arr.includes('programming_languages'))\n    assert.strictEqual(arr[3], 'programming_languages')\n    console.log('test pasado de programming_languages')\n    console.log('fin de el test 1')\n}\n\ncampos(diccionario)\n\n// test2 datos son correctos- -----------------------\n// primer intento , debe estar en un bucle para que pueda ir preguntando cada que valor cambie de valor, por que sino entra en la primer if y despues se cierra el profeama (bucle for valor[i])\n\n\n// function datos (obj){\n//   const key = Object.keys(obj)\n//   const valor = Object.values(obj)\n//   if(key[0] === 'name' ){\n//     if(typeof key[0] === 'string' ){\n//       console.log('name es un string')\n//     }else{\n//       console.log('debes introducir un estring en name')\n//     }\n//   }else if(key[1] === 'age' ){\n//     console.log('es toy en age')\n//   }\n// }\n\n// datos(diccionario)\n\n\nfunction datos1 (obj){\n  const key = Object.keys(obj)\n  const valor = Object.values(obj)\n  console.log(  'el valor de ' + key[0] + ' debe ser un string : ' + typeof valor[0])\n  assert.strictEqual(typeof valor[0], 'string')\n    console.log('test pasado de string')\n  console.log( 'el valor de ' + key[1] + ' debe ser un number : ' + typeof valor[1])\n  assert.strictEqual(typeof valor[1], 'number')\n    console.log('test pasado de number')\n  console.log( 'el valor de ' + key[2] + ' debe ser un fecha : ' + (valor[2] instanceof Date))\n  assert.strictEqual(typeof valor[2], 'object')\n    console.log('test pasado de date')\n  console.log( 'el valor de ' + key[3] + ' debe ser un array : ' +  Array.isArray(valor[3]) )\n  assert.strictEqual(typeof valor[3], 'object')\n    console.log('test pasado de array')\n    console.log('fin de el test 2')\n}\n\ndatos1(diccionario)\n\n\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/javascript/Deyvid-10.js",
    "content": "// Pruebas unitarias\n\nfunction suma(num1, num2)\n{\n    return num1 + num2\n}\n\nfunction test()\n{\n    let comprobar = suma(1, 2)\n\n    if(typeof(comprobar) == \"number\")\n    {\n        console.log(\"La funcion se ejecuto correctamente\");\n    }\n    else\n    {\n        console.log(\"La funcion no se ejecuto correctamente\");\n    }\n}\n\ntest()\n\n// DIFICULTAD EXTRA\n\nlet datos = {name: \"Deyvid\", age: 25, birth_date: \"06-12-98\", programming_languages: ['JavaScript', 'Python']}\n\nfunction testCampos()\n{\n    let arrayTest = [ 'name', 'age', 'birth_date', 'programming_languages' ]\n\n    for (let i = 0; i < Object.keys(datos).length; i++) \n    {\n        if(Object.keys(datos)[i] == arrayTest[i])\n        {\n            console.log(\"test aprobado\");\n        }\n    }\n}\n\ntestCampos()\n\nfunction testDatos()\n{\n    let arrayTest = [ 'Deyvid', 25, '06-12-98', ['JavaScript', 'Python'] ]\n    \n    for (let i = 0; i < Object.values(datos).length; i++) \n    {\n        if(Object.values(datos)[i] == arrayTest[i])\n        {\n            console.log(\"test aprobado\");\n        }\n        else if(typeof(Object.values(datos)[i]) == 'object')\n        {\n            for (let a = 0; a < Object.values(datos)[i].length; a++) \n            {\n                if(Object.values(datos)[i][a] == arrayTest[i][a])\n                {\n                    console.log(\"test aprobado\");\n                }\n            }\n        }\n    }\n}\n\ntestDatos()"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/javascript/FabianRpv.js",
    "content": "// Pruebas Unitarias \n\n// Una funcion Sumar en un archivo math.js\n\nfunction sumar(a, b) {\n    return a + b;\n  }\n  \nmodule.exports = sumar;\n\n\n// La prueba unitaria de dicha funcion se hara en un archivo separado llamado math.test.js\n\nconst sumar = require('./math');\n\ntest('sumar 1 + 2 debe ser igual a 3', () => {\n  expect(sumar(1, 2)).toBe(3);\n});\n\ntest('sumar -1 + 1 debe ser igual a 0', () => {\n  expect(sumar(-1, 1)).toBe(0);\n});\n\n// Para ejecutar la prueba en Jest se utiliza el comando  npx jest"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/javascript/Glitzypanic.js",
    "content": "/*\n * EJERCICIO:\n * Crea una función que se encargue de sumar dos números y retornar\n * su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n * capaz de determinar si esa función se ejecuta correctamente.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\n */\n\nfunction sum(a, b) {\n  return a + b;\n}\n\nfunction sumTest() {\n  const resultado = sum(3, 5);\n  const esperado = 8;\n\n  if (resultado !== esperado) {\n    throw new Error(`Error: ${resultado} es distinto de ${esperado}`);\n  } else {\n    console.log(\"!Test OK\");\n  }\n}\n\ntry {\n  sumTest();\n} catch (error) {\n  console.error(error.message);\n}\n\nconst user = {\n  name: \"Jose\",\n  age: 25,\n  birth_date: \"05/11/98\",\n  programming_languages: [\"javaScript\", \"Python\", \"Go\", \"C#\"],\n};\n\nfunction userTest() {\n  const userDate = [\"name\", \"age\", \"birth_date\", \"programming_languages\"];\n\n  userDate.forEach((element) => {\n    if (!(element in user)) {\n      throw new Error(`Error: El campo ${element} no existe en el objeto user`);\n    }\n\n    console.log(\"Todos los campos existen en el objeto user!\");\n  });\n}\n\nfunction dataTest() {\n  if (typeof user.name !== \"string\" || user.name.trim() === \"\") {\n    throw new Error(\n      `Error: el campo ${user.name} deber ser un string no vacio.`\n    );\n  }\n\n  if (typeof user.age !== \"number\" || user.age < 0) {\n    throw new Error(`Error: el campo ${user.age} debe ser un numero valido`);\n  }\n\n  if (typeof user.birth_date !== \"string\" || user.name.trim() === \"\") {\n    throw new Error(\n      `Error: el campo ${user.birth_date} deber ser un string no vacio.`\n    );\n  }\n\n  if (!Array.isArray(user.programming_languages)) {\n    throw new Error(\n      `Error: el campo ${user.programming_languages} debe ser un array.`\n    );\n  }\n\n  user.programming_languages.forEach((language) => {\n    if (typeof language !== \"string\") {\n      throw new Error(\n        `Error: Cada lenguaje en ${user.programming_languages} debe ser un string`\n      );\n    }\n  });\n\n  console.log(\"Datos correctos\");\n}\n\ntry {\n  userTest();\n  dataTest();\n} catch (err) {\n  console.error(err.message);\n}\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #13 - JavaScript ->Jesus Antonio Escamilla */\n//---EJERCIÓ---\n\n// Función de suma\nfunction sumar(num1, num2) {\n    return num1 + num2;\n}\n\n// Función TEST\nfunction test_Suma() {\n    const resultado = sumar(3, 7);\n    console.log(resultado === 10\n        ? 'El test funciona'\n        : 'Algo fallo en el test');\n}\n\n// Se Ejecuta el test y la suma\ntest_Suma();\n\n\n\n/**-----DIFICULTAD EXTRA-----*/\n\n//  Se crea un el diccionario de la claves y valores\nconst informaciónPersonal = {\n    'name': 'Jesus Antonio Escamilla',\n    'age': 24,\n    'birth_date': 22-12-1999,\n    'programming_languages': ['JavaScript', 'Python', 'Java', 'PHP']\n}\n\n//  Se crea un test para checa los campos del diccionario\nfunction test_ExisteCampos() {\n    const camposEsperado = [\"name\", \"age\", \"birth_date\", \"programming_languages\"];\n    const camposExisten = Object.keys(informaciónPersonal);\n\n    let todosLosCamposPresentes = true;\n    camposEsperado.forEach(campo => {\n        if (!camposExisten.includes(campo)) {\n        console.error(`Campo faltante: ${campo}`);\n        todosLosCamposPresentes = false;\n        }\n    });\n\n    console.log(todosLosCamposPresentes \n        ? \"Test de campos: CORRECTO\" \n        : \"Test de campos: FALLO\");\n}\n\n//  Se crea un test para checa que si son correctos los campos del diccionario\nfunction test_DatosCorrectos() {\n    const nombreEsperado = 'Jesus Antonio Escamilla';\n    const edadEsperado = 24;\n    const fechaNacimientoEsperado = 22-12-1999;\n    const lenguajesEsperados = ['JavaScript', 'Python', 'Java', 'PHP'];\n\n    const nombre = informaciónPersonal.name;\n    const edad = informaciónPersonal.age;\n    const fechaNacimiento = informaciónPersonal.birth_date;\n    const lenguajes = informaciónPersonal.programming_languages;\n\n    const datosCorrectos = \n        nombre === nombreEsperado &&\n        edad === edadEsperado &&\n        fechaNacimiento === fechaNacimientoEsperado &&\n        JSON.stringify(lenguajes) === JSON.stringify(lenguajesEsperados);\n\n    console.log(datosCorrectos \n        ? \"Test de datos correctos: CORRECTOS\"\n        : \"Test de datos correctos: FALLO\");\n\n}\n\n// Se utiliza los test aquí\ntest_ExisteCampos()\ntest_DatosCorrectos()\n\n/**-----DIFICULTAD EXTRA-----*/"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/javascript/RaulDoezon.js",
    "content": "/*\n * EJERCICIO:\n * Crea una función que se encargue de sumar dos números y retornar\n * su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n * capaz de determinar si esa función se ejecuta correctamente.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\n*/\n\n// +++++++++ EJERCICIO +++++++++\n// UTILIZANDO JEST, PRIMERO SE CREA EL ARCHIVO PARA EL EJEMPLO:\nfunction addition(a, b) {\n  return a + b;\n}\n\nmodule.exports = addition;\n// EJEMPLO USANDO JEST\n\n// SE CREA EL ARCHIVO DE PRUEBA:\ntest('Description', () => {\n  expect(functionName(args)).toBe(result);\n});\n\n// SE PONE A PRUEBA EL EJEMPLO EN UNA FUNCIÓN DE PRUEBA:\nconst addition = require('../src/addition');\n\ntest('testing simple additions', () => {\n  expect(doSomeMath(1, 1)).toBe(2);\n  expect(doSomeMath(2, 2)).toBe(4);\n});\n\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/javascript/RicJDev.js",
    "content": "/*\n---PRUEBAS UNITARIAS CON JEST---\n\n1. Instalar Jest (npm):\n  npm i --save-dev jest\n  npm i jest -D\n\n2. Crear un package json:\n  npm init --yes\n\n3. En el package.json cambiar esto:\n\n{\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n  },\n}\n\nPor esto: \n\n{\n  \"scripts\": {\n    \"test\": \"jest\"\n  },\n}\n\n4. Crear fichero con la extensión .test.js para escribir los test. Ejemplo: pruebasUnitarias.test.js\n\n5. Ejecutar los test:\n  npm run test\n  npm test\n  jest\n\n* Nota: para este ejercicio usé el mismo fichero para las pruebas. Es necesario agregar la extensión .test.js al archivo para testear este código.\n*/\n\nfunction sum(a, b) {\n\treturn a + b;\n}\n\nconst myself = {\n\tname: 'Ric',\n\tage: 21,\n\tbirthDate: '22/09/2002',\n\tprogrammingLanguages: ['JavaScript', 'HTML'],\n};\n\n//---EJERCICIO---\n\ndescribe('Test de suma', () => {\n\ttest('First test', () => {\n\t\texpect(sum(4, 5)).toBe(9);\n\t});\n\ttest('Second test', () => {\n\t\texpect(sum(67, 23)).toBe(90);\n\t});\n\ttest('Third test', () => {\n\t\texpect(sum(-20, 23)).toBe(3);\n\t});\n});\n\n//---EXTRA---\n\ndescribe('Primer test de diccionario', () => {\n\ttest('Check elements', () => {\n    expect(Object.keys(myself).length).toBe(4)\n  });\n});\n\ndescribe('Segundo test de diccionario', () => {\n\ttest('Check name', () => {\n\t\texpect(myself.name).toBe('Ric');\n\t});\n\ttest('Check age', () => {\n\t\texpect(myself.age).toBe(21);\n\t});\n\ttest('Check birth date', () => {\n\t\texpect(myself.birthDate).toBe('22/09/2002');\n\t});\n\ttest('Check programming languages', () => {\n\t\texpect(myself.programmingLanguages).toStrictEqual(['JavaScript', 'HTML']);\n\t});\n});\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/javascript/Sac-Corts.js",
    "content": "// npm install --save-dev jest\n// We name the file with the ending .test.js\n\nfunction addition(a, b) {\n    return a + b;\n}\n\ntest('addition 1 + 2 should be 3', () => {\n    expect(addition(1, 2)).toBe(3);\n});\n\ntest('addition 3 + 7 should be 10', () => {\n    expect(addition(3, 7)).toBe(10);\n});\n\n// To run the program: npx jest .\\Sac-Corts.test.js\n\n// Extra Exercise\n\nconst data = {\n    name: \"Isaac\",\n    age: \"22\",\n    birthdate: \"2001-10-21\",\n    programmingLanguages: [\"JavaScript\", \"Python\"]\n}\n\ntest('It should have all the necessary keys', () => {\n    expect(data).toHaveProperty('name');\n    expect(data).toHaveProperty('age');\n    expect(data).toHaveProperty('birthdate');\n    expect(data).toHaveProperty('programmingLanguages');\n});\n\ntest('It should have the correct data', () => {\n    expect(data.name).toBe(\"Isaac\");\n    expect(data.age).toBe(\"22\");\n    expect(data.birthdate).toBe(\"2001-10-21\");\n    expect(data.programmingLanguages).toEqual([\"JavaScript\", \"Python\"]);\n});"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/javascript/adrs1166ma.js",
    "content": "/* 🔥🔥 EJERCICIO: =======================================================\nCrea una función que se encargue de sumar dos números y retornar\nsu resultado.\n*/\n\n// Instalar `npm install --save-dev jest`\n\n// * file as 'sumar.js' ------------------------------------------------------\nfunction sumar(a, b) {\n    if (typeof a !== 'number' || typeof b !== 'number') {\n        throw new Error('Deben ser números.');\n    }\n    return a + b;\n}\nmodule.exports = sumar;\n/*\nDictionary📗 = {\n    typeof : \"¿Qué tipo eres?\"\n    throw : \"¡Alto! Aquí hay un problema\"\n    new Error(\"...\") : \"Quiero un nuevo objeto de tipo Error con este mensaje\"\n}\n*/\n\n// * file as 'sumar.test.js' ------------------------------------------------------\n/* 🔥🔥\nCrea un test, utilizando las herramientas de tu lenguaje, que sea\ncapaz de determinar si esa función se ejecuta correctamente.\n*/\nconst sumar = require('./sumar');\n\ntest('suma de dos números', () => {\n    expect(sumar(2, 3)).toBe(5);\n});\ntest('lanza error si los parámetros no son números', () => {\n    expect(() => sumar(\"2\", 3)).toThrow('Deben ser números.');\n});\n/*\nDictionary📗 = {\n    expect : \"Verifica que algo sea correcto\",\n    .toBe : \"Espera que el resultado sea exactamente esto\"\n    .toThrow : \"Espera que se lance un error con este mensaje\"\n}\n*/\n\n/* 🔥🔥🔥 DIFICULTAD EXTRA (opcional): =======================================================\nCrea un diccionario con las siguientes claves y valores:\n\"name\": \"Tu nombre\"\n\"age\": \"Tu edad\"\n\"birth_date\": \"Tu fecha de nacimiento\"\n\"programming_languages\": [\"Listado de lenguajes de programación\"]\n*/\n// * file as 'datos.js' ------------------------------------------------------\nconst datos = {\n    name: \"Anderson\",\n    age: 20,\n    birth_date: \"01/01/2005\",\n    programming_languages: [\"JavaScript\", \"Python\", \"Java\"]\n};\nmodule.exports = datos;\n\n// * file as 'datos.test.js' ------------------------------------------------------\n/* 🔥🔥🔥 Crea dos test:\n- Un primero que determine que existen todos los campos.\n- Un segundo que determine que los datos introducidos son correctos.\n*/\nconst datos = require('./datos');\n\n// Test 1: Verificar que existen todos los campos\ntest('todos los campos existen', () => {\n    const clavesEsperadas = ['name', 'age', 'birth_date', 'programming_languages'];\n    const clavesActuales = Object.keys(datos)\n    expect(clavesActuales.sort()).toEqual(clavesEsperadas.sort())\n});\n\n// Test 2: Verificar que los datos introducidos son correctos\ntest('los datos introducidos son correctos', () => {\n    expect(typeof datos.name).toBe('string')\n    expect(typeof datos.age).toBe('number')\n    expect(typeof datos.birth_date).toBe('string')\n    expect(Array.isArray(datos.programming_languages)).toBe(true)\n    expect(datos.programming_languages.every(lang => typeof lang === 'string')).toBe(true)\n});\n\n\n// ! Al ejecutar `npm test`\n\n/*\nnpm test\n\n> test\n> jest\n\n PASS  js/sumar.test.js\n PASS  js/datos.test.js\n\nTest Suites: 2 passed, 2 total\nTests:       4 passed, 4 total\nSnapshots:   0 total\nTime:        2.064 s\nRan all test suites.\n*/"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/javascript/agusrosero.js",
    "content": "/*\n * EJERCICIO:\n * Crea una función que se encargue de sumar dos números y retornar\n * su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n * capaz de determinar si esa función se ejecuta correctamente.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\n */\n\n// EJERCICIO:\nconst suma = (a, b) => {\n  return a + b;\n};\n\nresult = suma(10, 5);\nif (result === 15) {\n  console.log(\"El resultado es correcto!\");\n} else {\n  console.log(\"El resultado no es el esperado.\");\n}\n\n// DIFICULTAD EXTRA:\nmiDiccionario = {\n  name: \"Hernan\",\n  age: 23,\n  birthDate: \"03-08-00\",\n  programmingLanguages: [\"Python\", \"Javascript\"],\n};\n\nfunction testCampos() {\n  const campos = [\"name\", \"age\", \"birthDate\", \"programmingLanguages\"];\n  for (const campo of campos) {\n    if (campo in miDiccionario) {\n      console.log(\"Todos los campos estan en el diccionario\");\n      return true;\n    }\n  }\n  console.log(\"Error uno de los campos no se encuentra en miDiccionario.\");\n  return false;\n}\n\ntestCampos();\n\nfunction isDateValid(dateString) {\n  const datePattern = /^\\d{2}-\\d{2}-\\d{2}$/;\n  return datePattern.test(dateString);\n}\n\nfunction isProgrammingLanguagesValid(languages) {\n  return (\n    Array.isArray(languages) &&\n    languages.every((lang) => typeof lang === \"string\")\n  );\n}\n\nfunction validarDiccionario(diccionario) {\n  if (typeof diccionario.name !== \"string\" || diccionario.name.trim() === \"\") {\n    console.log(\"Nombre invalido\");\n    return false;\n  }\n\n  if (typeof diccionario.age !== \"number\" || diccionario.age <= 0) {\n    console.log(\"Edad invalida\");\n    return false;\n  }\n\n  if (!isDateValid(diccionario.birthDate)) {\n    console.log(\"Fecha invalida\");\n    return false;\n  }\n\n  if (!isProgrammingLanguagesValid(diccionario.programmingLanguages)) {\n    console.log(\"Lenguaje de programacion invalido\");\n    return false;\n  }\n\n  return true;\n}\n\nif (validarDiccionario(miDiccionario)) {\n  console.log(\"Todos los datos son correctos.\");\n} else {\n  console.log(\"Hay datos incorrectos en el diccionario.\");\n}\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/javascript/alexdevrep.js",
    "content": "/*\n * EJERCICIO:\n * Crea una función que se encargue de sumar dos números y retornar\n * su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n * capaz de determinar si esa función se ejecuta correctamente.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\n */\n\n//Creamos la función \nfunction suma (numero1,numero2){\n    return numero1 + numero2\n}\n\n\n//Hacemos las pruebas de la función\ntest('sumar 1 + 2 debería dar 3', () => {\n    expect(suma(1, 2)).toBe(3);\n  })\n\n//Dificultad EXTRA \n\n// Definimos el mapa\nlet alexdevrep = new Map()\nalexdevrep.set(\"Nombre\",\"Alejandro\")\nalexdevrep.set(\"Edad\", \"24\")\nalexdevrep.set(\"Fecha de nacimiento\",\"22-07-1999\")\nalexdevrep.set(\"Lenguajes de programación\",[\"Python\", \"JavaScript\", \"Java\"])\n\n// Creamos la función para obtener las claves del mapa\nfunction clave() {\n    let clave_array = []\n    for (let key of alexdevrep.keys()) {\n        clave_array.push(key)\n    }\n    return clave_array\n}\n\nfunction valor (){\n    let valor_array = []\n    for (let valor of alexdevrep.values()){\n        valor_array.push(valor)\n    }\n    return valor_array\n}\n\n// Realizamos las pruebas del test\ntest('Prueba de obtener las claves del mapa', () => {\n    expect(clave()).toEqual([\"Nombre\", \"Edad\", \"Fecha de nacimiento\", \"Lenguajes de programación\"])\n})\n\ntest('Prueba de obtener los valores del mapa',()=>{\n    expect(valor()).toEqual([\"Alejandro\", \"24\",\"22-07-1999\",[\"Python\",\"JavaScript\",\"Java\"]])\n})\n\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/javascript/bernatcs.js",
    "content": "// ** EJERCICIO\n\nfunction sum(num1, num2) {\n    try {\n        if (typeof num1 === 'number' && isFinite(num1) && typeof num2 === 'number' && isFinite(num2)) {\n            return num1 + num2;\n        } else {\n            console.error('Introduzca un número válido');\n            return null;\n        }\n    } catch (err) {\n        console.error('No se ha podido realizar la suma', err);\n        return null;\n    }\n}\n\n\n// ** DIFICULTAD EXTRA ** ----------------------------------------------------------------------------------------------------------------------------------------------------\n\nlet diccionario = {\n    name: 'Bernat',\n    age: 88,\n    birth_date: '2000-01-01',\n    programming_languages: ['List1', 'List2', 'List3']\n}\n\nfunction test1() {\n    if ('name' in diccionario && 'age' in diccionario && 'birth_date' in diccionario && 'programming_languages' in diccionario) {\n        console.log('Diccionario completo')\n    } else {\n        console.log('Diccionario incompleto')\n    }\n}\n\ntest1()\n\nfunction test2() {\n    if (\n        typeof(diccionario.name) === 'string' && \n        typeof(diccionario.age) === 'number' && \n        /^\\d{4}-\\d{2}-\\d{2}$/.test(diccionario.birth_date) && \n        Array.isArray(diccionario.programming_languages)\n    ) {\n        console.log('Los datos son correctos')\n    } else {\n        console.log('Los datos NO son correctos')\n    }\n}\n\ntest2()"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/javascript/caterinarodriguezdev.js",
    "content": "/*\n * EJERCICIO:\n * Crea una función que se encargue de sumar dos números y retornar\n * su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n * capaz de determinar si esa función se ejecuta correctamente.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\n */\n\nconst sum = (num1, num2) => {\n    return num1 + num2;\n}\n\nconst testSum = () => {\n\n    const result1 = sum(1, 4);\n    const expected1 = 5;\n\n    const result2 = sum(-3, 4);\n    const expected2 = 1;\n\n    if (result1 !== expected1) {\n        console.log('Test fallado');\n        return;\n    } else {\n        console.log('✅ Test 1 pasado');\n    }\n\n    if (result2 !== expected2) {\n        console.log('Test fallado');\n    } else {\n        console.log('✅ Test 2 pasado');\n    }\n}\n\ntestSum();\n\nconst persona = {\n    name: 'Ada Lovelace',\n    age: 208,\n    birth_date: '10/12/1815',\n    programming_languages: ['Ada']\n}\n\nconst existenTodosLosCamposTest = () => {\n\n    const campos = ['name', 'age', 'birth_date', 'programming_languages'];\n\n    campos.every(campo => campo in persona) ? console.log('✅ Test existenTodosLosCamposTest pasado') : console.log('Test existenTodosLosCamposTest fallado');\n}\n\nconst checkCamposSonCorrectosTest = () => {\n\n    if (typeof persona.name !== 'string') {\n        console.log('Test checkCamposSonCorrectosTest fallado: el campo name debe ser una string');\n        return;\n    }\n\n    if (persona.age < 0) {\n        console.log('Test checkCamposSonCorrectosTest fallado: el campo age no puede ser negativo');\n        return;\n    }\n\n    const formatoFecha = /^\\d{2}\\/\\d{2}\\/\\d{4}$/;\n    if (!formatoFecha.test(persona.birth_date)) {\n        console.log('Test checkCamposSonCorrectosTest fallado: el campo birth_date tiene un formato incorrecto');\n        return;\n    }\n\n    const lenguajesDeProgramacionAceptados = ['Javascript', 'Ada', 'Python', 'Java'];\n\n    if (persona.programming_languages.some(lenguaje => !lenguajesDeProgramacionAceptados.includes(lenguaje))) {\n        console.log('Test checkCamposSonCorrectosTest fallado: el lenguaje de programación no es aceptado');\n        return;\n    }\n\n    console.log('✅ Test checkCamposSonCorrectosTest pasado');\n}\n\nexistenTodosLosCamposTest();\ncheckCamposSonCorrectosTest();"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/javascript/cesar-ch.js",
    "content": "/*\n    * #13 PRUEBAS UNITARIAS\n*/\n\nconst sum = (num1, num2) => num1 + num2\n\n// test\nconst result1 = sum(2, 3)\nif (result1 === 5) {\n    console.log('Test passed')\n} else {\n    console.error('Error: The sum of 2 and 3 is 5')\n}\n\n/*\n    * DIFICULTAD EXTRA\n*/\n\nconst person = {\n    name: 'cesar-ch',\n    age: 3,\n    birthDate: '2021-02-03',\n    programmingLanguages: [\"Javascript\", \"Python\", \"Java\"]\n}\n\n// test for existence of fields\nconst expectedKeys = [\"name\", \"age\", \"birthDate\", \"programmingLanguages\"]\nconst allKeysExist = expectedKeys.every(key => key in person)\nif (allKeysExist) {\n    console.log('Test passed')\n} else {\n    console.error('Error: The person object has the expected keys')\n}\n\n// test to verify field data\nif (typeof person.name !== \"string\") {\n    console.error('Error: The name field is not string')\n}\n\nif (isNaN(person.age) || person.age < 0) {\n    console.error('Error: Age must be a positive number')\n}\n\nconst regexDate = /^\\d{4}-\\d{2}-\\d{2}$/\n\nif (!regexDate.test(person.birthDate)) {\n    console.error('Error: Birth date is not in the expected format')\n}\n\nif (!Array.isArray(person.programmingLanguages)) {\n    console.error('Error: Programming languages is not an array')\n}\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/javascript/christian-jfr.js",
    "content": "// #13 PRUEBAS UNITARIAS\n\n/*\n * EJERCICIO:\n * Crea una función que se encargue de sumar dos números y retornar\n * su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n * capaz de determinar si esa función se ejecuta correctamente.\n */\n\n// Funciones para hacer las pruebas test() y assert()\nfunction test(desc, fn) {\n\ttry {\n\t\tfn();\n\t\tconsole.log('\\x1b[32m%s\\x1b[0m', '\\u2714 ' + desc + ' PASSED');\n\t} catch (error) {\n\t\tconsole.log('\\n');\n\t\tconsole.log('\\x1b[31m%s\\x1b[0m', '\\u2718 ' + desc + ' FAILED');\n\t\tconsole.error(error);\n\t}\n}\n\nfunction assert(isTrue) {\n\tif (!isTrue) {\n\t\tthrow new Error();\n\t}\n}\n\nfunction add(num1, num2) {\n\tif (typeof num1 !== 'number' || typeof num2 !== 'number') {\n\t\treturn 'You must provide two numbers';\n\t} else {\n\t\tlet result = Number((num1 + num2).toFixed(2));\n\t\treturn result;\n\t}\n}\n\n// test que deberia pasar\ntest('add two numbers', function () {\n\tassert(add(1, 2) === 3);\n});\n\n// test que deberia fallar\ntest('add two numbers', function () {\n\tassert(add(1, 2) !== 3);\n});\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\n */\n\nconst student = {\n\tname: 'Christian',\n\tage: 21,\n\tbirth_date: {\n\t\tday: 1,\n\t\tmonth: 5,\n\t\tyear: 2003,\n\t},\n\tprogramming_languages: ['JavaScript', 'Python', 'C++'],\n};\n\nconst testFields = () => {\n\tif (\n\t\tstudent.name &&\n\t\tstudent.age &&\n\t\tstudent.birth_date &&\n\t\tstudent.birth_date.day &&\n\t\tstudent.birth_date.month &&\n\t\tstudent.birth_date.year &&\n\t\tstudent.programming_languages\n\t) {\n\t\treturn true;\n\t} else {\n\t\treturn false;\n\t}\n};\n\nconst testValues = () => {\n\tif (\n\t\ttypeof (student.name === 'string') &&\n\t\ttypeof (\n\t\t\tstudent.age === 'number' &&\n\t\t\tNumber.isInteger(student.age) &&\n\t\t\tstudent.age > 0\n\t\t) &&\n\t\ttypeof (student.birth_date === 'object') &&\n\t\ttypeof (\n\t\t\tstudent.birth_date.day === 'number' &&\n\t\t\tNumber.isInteger(student.birth_date.day) &&\n\t\t\tstudent.birth_date.day > 0 &&\n\t\t\tstudent.birth_date.day < 32\n\t\t) &&\n\t\ttypeof (\n\t\t\tstudent.birth_date.month === 'number' &&\n\t\t\tNumber.isInteger(student.birth_date.month) &&\n\t\t\tstudent.birth_date.month > 0 &&\n\t\t\tstudent.birth_date.month < 13\n\t\t) &&\n\t\ttypeof (\n\t\t\tstudent.birth_date.year === 'number' &&\n\t\t\tNumber.isInteger(student.birth_date.year) &&\n\t\t\tstudent.birth_date.year > 0\n\t\t) &&\n\t\ttypeof (student.programming_languages === 'object')\n\t) {\n\t\treturn true;\n\t} else {\n\t\treturn false;\n\t}\n};\n\ntest('fields exist?', function () {\n\tassert(testFields());\n});\n\ntest('values are correct?', function () {\n\tassert(testValues());\n});\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/javascript/duendeintemporal.js",
    "content": "/* { RETOS DE PROGRAMACIÓN }  #13 PRUEBAS UNITARIAS */\n// I refer to \"JavaScript Notes for Professionals\" from the people of Stack Overflow. https://goalkicker.com/JavaScriptBook\n// Additionally, I use GPT as a reference and sometimes to correct or generate proper comments.\n\n//short for console.log\nlet log = console.log;\n\nwindow.addEventListener('load', ()=>{\n    const body = document.querySelector('body');\n    const title = document.createElement('h1');\n    \n    body.style.setProperty('background', '#000');\n    body.style.setProperty('text-align', 'center');\n    \n    title.textContent = 'Retosparaprogramadores #13.';\n    title.style.setProperty('font-size', '3.5vmax');\n    title.style.setProperty('color', '#fff');\n    title.style.setProperty('line-height', '100vh');\n    \n    body.appendChild(title);\n    \n    setTimeout(()=>{\n    alert('Retosparaprogramadores #13. Please open the Browser Developer Tools.');\n    }, 2000);\n    log( 'Retosparaprogramadores #13'); \n});\n\n/* GoalKicker.com – JavaScript® Notes for Professionals 219\nSection 30.9: Debugging with assertions - console.assert() Writes an error message to the console if the assertion is false. Otherwise, if the assertion is true, this does nothing. */\n\nconsole.assert('one' === 1); // Assertion failed:\n//Note there's no message cause we didn't specify no one\n\n//Multiple arguments can be provided after the assertion–these can be strings or other objects–that will only be printed if the assertion is false:\n\nconsole.assert(true , 'Testing assertion...', null, undefined, Object); \n\nconsole.assert(false , 'Testing assertion...', null, undefined, Object); \n// Assertion failed: Testing assertion... NaN undefined funstion Object() { [native code] }\n\n\n/*console.assert does not throw an AssertionError (except in Node.js), meaning that this method is incompatible with most testing frameworks and that code execution will not break on a failed assertion.  */\n\n// Custom assert function that logs an error instead of throwing\nconst assert = (condition, message, errors) => {\n    if (!condition) {\n        console.error(message);\n        errors.push(message); // Collect the error message\n    }\n};\n\nconst sum = (a, b) => {\n    if (typeof a !== 'number' || typeof b !== 'number') {\n        throw new TypeError('Both arguments must be numbers');\n    }\n    return a + b;\n};\n\nconst testSum = (errors) => {\n    assert(sum(2, 3) === 5, 'Error: 2 + 3 should be 5', errors);\n    assert(sum(-1, 1) === 0, 'Error: -1 + 1 should be 0', errors);\n    assert(sum(0, 0) === 0, 'Error: 0 + 0 should be 0', errors);\n    \n    try {\n        sum(2, '3'); // This should throw an error\n    } catch (e) {\n        console.log('Caught an error:', e); // Log the caught error\n        assert(e instanceof TypeError, 'Error: Invalid argument type not handled', errors);\n        assert(e.message === 'Both arguments must be numbers', 'Error: Argument type mismatch', errors);\n    }\n\n    console.log('All sum tests have been executed.');\n};\n\nconst personalInfo = {\n    name: \"Niko Zen\",\n    age: 41,\n    birth_date: \"1983/08/08\",\n    programming_languages: [\"JavaScript\", \"Python\", \"Rust\", \"Ruby\", \"Java\"] \n};\n\nconst testPersonalInfo = (obj, errors) => {\n    if (Object.keys(obj).length === 0) {\n        log('The obj is empty, skipping personal info tests.');\n        return; \n    }\n\n    // Check that all fields exist\n    assert(obj.hasOwnProperty('name'), 'Missing field \"name\"', errors);\n    assert(obj.hasOwnProperty('age'), 'Missing field \"age\"', errors);\n    assert(obj.hasOwnProperty('birth_date'), 'Missing field \"birth_date\"', errors);\n    assert(obj.hasOwnProperty('programming_languages'), 'Missing field \"programming_languages\"', errors);\n\n    // Check data types\n    assert(typeof obj.name === 'string', '\"name\" must be a string', errors);\n    assert(typeof obj.age === 'number', '\"age\" must be a number', errors);\n    \n    // Check if birth_date is a valid date\n    const birthDate = new Date(obj.birth_date);\n    assert(!isNaN(birthDate.getTime()), '\"birth_date\" must be a valid Date', errors);\n    \n    assert(Array.isArray(obj.programming_languages), '\"programming_languages\" is not an array', errors);\n\n    // Validate each programming language\n    obj.programming_languages.forEach(lang => assert(typeof lang === 'string', 'Each language must be a string', errors));\n\n    // Check fields are not empty\n    assert(obj.name.length > 0, '\"name\" cannot be empty', errors);\n    assert(obj.age > 0, '\"age\" must be greater than 0', errors);\n    assert(obj.birth_date.length > 0, '\"birth_date\" cannot be empty', errors);\n    assert(obj.programming_languages.length > 0, '\"programming_languages\" should have at least one language', errors);\n\n    log('All personal info tests have been executed.');\n};\n\n/*Note: \n    The getTime() method returns the number of milliseconds since January 1, 1970, 00:00:00 UTC for the Date object.\n    If the date is invalid (e.g., if the input string is not a valid date format), getTime() will return NaN.\n    The isNaN() function checks if the value is NaN. Therefore, !isNaN(birthDate.getTime()) will be true if the date is valid and false if it is not.\n */ \n\n\nconst nikitaInfo = {};\n\nconst errors = [];\ntestSum(errors);\ntestPersonalInfo(personalInfo, errors); // Should pass\ntestPersonalInfo(nikitaInfo, errors); // Should fail\n\n// Log all collected errors at the end\nif (errors.length > 0) {\n    log('Errors encountered during tests:');\n    errors.forEach(error => log(error));\n} else {\n    log('No errors encountered during tests.');\n}\n\n/* Assertion failed: \nAssertion failed: Testing assertion... null undefined \nfunction Object()\n\nCaught an error: TypeError: Both arguments must be numbers\nAll sum tests have been executed. \nAll personal info tests have been executed. \nThe obj is empty, skipping personal info tests. \nNo errors encountered during tests. \nRetosparaprogramadores #13   \n */\n\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/javascript/emedevelopa.js",
    "content": "function suma (a, b) {\n    return a + b\n}\n\n//Test\nfunction testSuma(){\n        const resultado1 = suma(2, 2);\n        console.log(resultado1 === 4 ? \"Funciona\" : \"No funciona\");\n}\ntestSuma();\n\n//EXTRA\nconst misDatos = {};\n\nmisDatos[\"name\"] = \"Maria\";\nmisDatos[\"age\"] = 33;\nmisDatos[\"birth_date\"] = \"8 de Diciembre de 1990\";\nmisDatos[\"programming_languages\"] = [\"HTML\", \"CSS\", \"JavaScript\"];\n\nfunction testCampos() {\n    const campos = [\"name\", \"age\", \"birth_date\", \"programming_languages\"];\n    for(let campo of campos) {\n        if (!(campo in misDatos)) {\n            console.log(`Falta el campo \"${campo}\" en el diccionario.`);\n            return false;\n        }\n    }\n    console.log(\"Todos los campos existen en el diccionario.\");\n    return true;\n}\n\nfunction testDatos() {\n    if (typeof misDatos.name !== \"string\" || misDatos.name === \"\") {\n        console.error(\"El nombre no es válido.\");\n        return false;\n    }\n    if (isNaN(misDatos.age) || misDatos.age === \"\") {\n        console.error(\"Edad no válida\");\n    }\n    if (typeof misDatos.birth_date !== \"string\" || misDatos.birth_date === \"\") {\n        console.error(\"Fecha no válida\");\n    }\n    if (!Array.isArray(misDatos.programming_languages) || misDatos.programming_languages.length === 0) {\n        console.error(\"Lenguajes no válidos\");\n        return false;\n    }\n    console.log(\"Datos correctos\")\n    return true;\n}\n\ntestCampos();\ntestDatos();"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/javascript/eulogioep.js",
    "content": "// Importamos la biblioteca de pruebas Jest\nconst assert = require('assert');\n\n/**\n * Función que suma dos números y retorna el resultado.\n * @param {number} a Primer número a sumar.\n * @param {number} b Segundo número a sumar.\n * @return {number} La suma de a y b.\n */\nfunction suma(a, b) {\n    return a + b;\n}\n\n/**\n * Crea y retorna un objeto con datos personales.\n * @return {Object} Objeto con datos personales.\n */\nfunction crearObjeto() {\n    return {\n        name: \"Tu nombre\",\n        age: 30,\n        birth_date: \"1993-01-01\",\n        programming_languages: [\"JavaScript\", \"Python\", \"Java\"]\n    };\n}\n\n// Pruebas unitarias\ndescribe('Pruebas de la función suma', () => {\n    test('Suma de 2 y 3 debería ser 5', () => {\n        assert.strictEqual(suma(2, 3), 5);\n    });\n\n    test('Suma de -1 y 1 debería ser 0', () => {\n        assert.strictEqual(suma(-1, 1), 0);\n    });\n\n    test('Suma de -2 y -3 debería ser -5', () => {\n        assert.strictEqual(suma(-2, -3), -5);\n    });\n});\n\ndescribe('Pruebas del objeto de datos personales', () => {\n    const objeto = crearObjeto();\n\n    test('El objeto debe contener todas las claves requeridas', () => {\n        assert(objeto.hasOwnProperty('name'), \"El objeto debe contener la clave 'name'\");\n        assert(objeto.hasOwnProperty('age'), \"El objeto debe contener la clave 'age'\");\n        assert(objeto.hasOwnProperty('birth_date'), \"El objeto debe contener la clave 'birth_date'\");\n        assert(objeto.hasOwnProperty('programming_languages'), \"El objeto debe contener la clave 'programming_languages'\");\n    });\n\n    test('Los datos en el objeto deben ser correctos', () => {\n        assert.strictEqual(objeto.name, \"Tu nombre\", \"El nombre debe ser 'Tu nombre'\");\n        assert(typeof objeto.age === 'number', \"La edad debe ser un número\");\n        assert(/^\\d{4}-\\d{2}-\\d{2}$/.test(objeto.birth_date), \"La fecha de nacimiento debe tener el formato YYYY-MM-DD\");\n        assert(Array.isArray(objeto.programming_languages), \"Los lenguajes de programación deben ser un array\");\n        assert(objeto.programming_languages.length > 0, \"La lista de lenguajes de programación no debe estar vacía\");\n    });\n});"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/javascript/garos01.js",
    "content": "// Función para sumar dos números\nfunction sumar(a, b) {\n  return a + b;\n}\n\n// Función para realizar pruebas\nfunction testSuma() {\n  // Caso de prueba 1\n  const num1 = 5;\n  const num2 = 3;\n  const expected = 8;\n  const result = sumar(num1, num2);\n  if (result === expected) {\n    console.log(\"Caso de prueba 1: Éxito\");\n  } else {\n    console.error(\"Caso de prueba 1: Falló\");\n  }\n\n  // Caso de prueba 2\n  const num3 = -2;\n  const num4 = 10;\n  const expected2 = 8;\n  const result2 = sumar(num3, num4);\n  if (result2 === expected2) {\n    console.log(\"Caso de prueba 2: Éxito\");\n  } else {\n    console.error(\"Caso de prueba 2: Falló\");\n  }\n}\n\n// Ejecutar las pruebas\ntestSuma();\n\n// Ejercicio extra\n\nconst miPerfil = {\n  name: \"Oscar Garzon\",\n  age: 29,\n  birth_date: \"11-09-1994\",\n  programming_languages: [\"JavaScript\", \"Python\"],\n};\n\n// Test para verificar si todos los campos existen\nfunction testExistenciaCampos() {\n  const camposRequeridos = [\n    \"name\",\n    \"age\",\n    \"birth_date\",\n    \"programming_languages\",\n  ];\n  let todosPresentes = true;\n\n  camposRequeridos.forEach((campos) => {\n    if (!(campos in miPerfil)) {\n      console.error(`Campo ${campos} no encontrado.`);\n      todosPresentes = false;\n    }\n  });\n\n  if (todosPresentes) {\n    console.log(\"Todos los campos están presentes.\");\n  } else {\n    console.error(\"No se encontraron todos los campos.\");\n  }\n}\n\n// Test para verificar si los datos son correctos\nfunction testDatosCorrectos() {\n  let datosCorrectos = true;\n\n  // Verificar edad\n  if (typeof miPerfil.age !== \"number\" || miPerfil.age <= 0) {\n    console.error(\"La edad no es un número válido.\");\n    datosCorrectos = false;\n  }\n\n  // Verificar fecha de nacimiento (formato simplificado)\n  const fechaNacimiento = new Date(miPerfil.birth_date);\n  if (isNaN(fechaNacimiento.getTime())) {\n    console.error(\"Fecha de nacimiento no válida.\");\n    datosCorrectos = false;\n  }\n\n  // Verificar si el listado de lenguajes de programación es un array\n  if (\n    !Array.isArray(miPerfil.programming_languages) ||\n    miPerfil.programming_languages.length === 0\n  ) {\n    console.error(\"Listado de lenguajes de programación no válido.\");\n    datosCorrectos = false;\n  }\n\n  if (datosCorrectos) {\n    console.log(\"Los datos son correctos.\");\n  } else {\n    console.error(\"Algunos datos no son correctos.\");\n  }\n}\n\n// Ejecutar los tests\ntestExistenciaCampos();\ntestDatosCorrectos();\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/javascript/hectorio23.js",
    "content": "const readline = require('readline');\n\n// Función que implementa el juego de adivinanzas\nfunction miniGame() {\n    // Inicializar la semilla del generador de números aleatorios\n    Math.seedrandom(new Date().toISOString());\n\n    console.log(\"Bienvenido al juego de adivinanzas!\");\n    console.log(\"Estoy pensando en un número entre 1 y 100. Adivina cuál es!\");\n\n    // Generar número aleatorio entre 1 y 100\n    const numeroAleatorio = Math.floor(Math.random() * 100) + 1;\n    let intentos = 0;\n    let intentoUsuario;\n\n    const rl = readline.createInterface({\n        input: process.stdin,\n        output: process.stdout\n    });\n\n    rl.question('Ingresa tu intento: ', (answer) => {\n        intentoUsuario = parseInt(answer);\n\n        // Verificar que el número esté en el rango válido\n        if (intentoUsuario >= 1 && intentoUsuario <= 100) {\n            intentos++;\n\n            if (intentoUsuario < numeroAleatorio) {\n                console.log(\"El número que estoy pensando es mayor.\");\n            } else if (intentoUsuario > numeroAleatorio) {\n                console.log(\"El número que estoy pensando es menor.\");\n            } else {\n                console.log(`¡Felicidades! Has adivinado el número en ${intentos} intentos.`);\n                rl.close();\n                playAgain();\n                return;\n            }\n        } else {\n            console.log(\"El número debe estar entre 1 y 100.\");\n        }\n\n        rl.close();\n        miniGame();\n    });\n}\n\n// Función para preguntar si desea jugar de nuevo\nfunction playAgain() {\n    const rl = readline.createInterface({\n        input: process.stdin,\n        output: process.stdout\n    });\n\n    rl.question('¿Quieres jugar de nuevo? (s/n): ', (answer) => {\n        if (answer.toLowerCase() === 's') {\n            rl.close();\n            miniGame();\n        } else {\n            console.log(\"Gracias por jugar. ¡Hasta luego!\");\n            rl.close();\n        }\n    });\n}\n\n// Ejemplos de aserciones en JavaScript\nconsole.assert(2 + 2 === 4);\nconsole.log(\"Checkpoint #1\");\n\nconsole.assert(2 * 2 === 4, \"Mensaje personalizado de aserción\");\nconsole.log(\"Checkpoint #2\");\n\nconsole.assert(0o10 + 0o10 === 16, \"Otra forma de agregar un mensaje de aserción\");\nconsole.log(\"Checkpoint #3\");\n\nconsole.assert(2 + 2 % 3 === 1, \"Success\");\nconsole.log(\"Checkpoint #4\");\n\n// Llamada a la función que implementa el juego de adivinanzas\nminiGame();\n\nconsole.assert(2 + 2 === 5, \"Failed\");\nconsole.log(\"La ejecución continúa después de la última aserción\");\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/javascript/juandaherrera.js",
    "content": "/*\n * EJERCICIO:\n * Crea una función que se encargue de sumar dos números y retornar\n * su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n * capaz de determinar si esa función se ejecuta correctamente.\n */\n\nfunction customSum(num1, num2) {\n    return num1 + num2;\n}\n\nconst { describe, it, expect } = require(\"@jest/globals\");\n\ndescribe(\"customSum\", () => {\n    it(\"should sum two positive numbers correctly\", () => {\n        expect(customSum(5, 6)).toBe(11);\n    });\n\n    it(\"should sum two negative numbers correctly\", () => {\n        expect(customSum(-5, -6)).toBe(-11);\n    });\n\n    it(\"should sum a positive and a negative number correctly\", () => {\n        expect(customSum(-5, 6)).toBe(1);\n    });\n});\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\n */\n\nconst myDict = {\n    name: \"Juan David Herrera\",\n    age: \"24\",\n    birthDate: \"1999-12-05\",\n    programmingLanguages: [\"Python\", \"Javascript\", \"VBA\", \"Bash\"],\n};\n\ndescribe(\"myDict\", () => {\n    it(\"should have all required fields\", () => {\n        const requiredFields = [\n            \"name\",\n            \"age\",\n            \"birthDate\",\n            \"programmingLanguages\",\n        ];\n        requiredFields.forEach((field) => {\n            expect(myDict).toHaveProperty(field);\n        });\n    });\n\n    it(\"should contain the correct data\", () => {\n        const correctData = {\n            name: \"Juan David Herrera\",\n            age: \"24\",\n            birthDate: \"1999-12-05\",\n            programmingLanguages: [\"Python\", \"Javascript\", \"VBA\", \"Bash\"],\n        };\n        expect(myDict).toEqual(correctData);\n    });\n});\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n_______________________________________\n#13 PRUEBAS UNITARIAS\n---------------------------------------\n * EJERCICIO:\n * Crea una función que se encargue de sumar dos números y retornar\n * su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n * capaz de determinar si esa función se ejecuta correctamente.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\n\n________________________________________________________\n// Instala Jest en tu proyecto\nnpm install --save-dev jest\n\n// package.json\n{\n  \"scripts\": {\n    \"test\": \"jest\"\n  }\n}\n\n// Ejecuta las pruebas:\nnpm test\nnpm test -- --verbose\n________________________________________________________\n*/\n\n// src/sum.js\nfunction sum(a, b) {\n    if (arguments.length < 2) {\n        throw new TypeError(\"Se requieren dos argumentos\");\n    }\n\n    if (typeof a === \"number\" && typeof b === \"number\") {\n        return a + b;\n    } else {\n        return null;\n    }\n}\n\n// module.exports = sum;\n\n// _____________________________\n// Pruebas unitarias\n// tests/sum.test.js\n// const sum = require(\"../src/sum\");\ndescribe(\"Test para función suma\", () => {\n    test(\"Debe devolver la suma correcta\", () => {\n        expect(sum(5, 2)).toBe(7);\n        expect(sum(2.5, 1.25)).toBe(3.75);\n        expect(sum(-2, 1)).toBe(-1);\n        expect(sum(0, 0)).toBe(0);\n    });\n\n    test(\"Debería devolver nulo para entradas no válidas\", () => {\n        expect(sum(1, \"2\")).toBeNull();\n        expect(sum(\"a\", \"b\")).toBeNull();\n    });\n\n    test(\"No debería devolver sumas incorrectas\", () => {\n        expect(sum(1, 3)).not.toBe(5);\n    });\n\n    test(\"Debería lanzar TypeError si faltan argumentos\", () => {\n        expect(() => sum(10)).toThrow(TypeError);\n    });\n});\n\n// ________________________________________________________\n// DIFICULTAD EXTRA\n\n// src/dictUser.js\nconst dictUser = {\n    name: \"Ken\",\n    age: 121,\n    birth_date: \"1903-03-19\",\n    prog_langs: [\"cs\", \"py\", \"vb\", \"rs\", \"js\"],\n};\n\n// module.exports = dictUser;\n\n// _____________________________\n// Pruebas unitarias\n// tests/dictUser.test.js\n\n// const dictUser = require(\"../src/dictUser\");\ndescribe(\"Pruebas para dictUser\", () => {\n    test(\"Verificar la existencia de las claves en dictUser\", () => {\n        expect(dictUser).toHaveProperty(\"name\");\n        expect(dictUser).toHaveProperty(\"age\");\n        expect(dictUser).toHaveProperty(\"birth_date\");\n        expect(dictUser).toHaveProperty(\"prog_langs\");\n    });\n\n    test(\"Verificar los tipos de los valores en dictUser\", () => {\n        expect(typeof dictUser.name).toBe(\"string\");\n        expect(typeof dictUser.age).toBe(\"number\");\n        expect(typeof dictUser.birth_date).toBe(\"string\");\n        expect(Array.isArray(dictUser.prog_langs)).toBe(true);\n    });\n\n    test(\"Verificar el contenido de los valores en dictUser\", () => {\n        expect(dictUser.name).toBe(\"Ken\");\n        expect(dictUser.age).toBe(121);\n        expect(dictUser.birth_date).toBe(\"1903-03-19\");\n        expect(dictUser.prog_langs).toEqual([\"cs\", \"py\", \"vb\", \"rs\", \"js\"]);\n    });\n});\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/javascript/parababire.js",
    "content": "import { describe, expect, it } from 'vitest'\n\nconst sumaDosNumeros = (num1, num2) => {\n  if (typeof num1 !== 'number' || typeof num2 !== 'number') throw new Error('Los parámetros ingresados deben ser números')\n  if (Number.isNaN(num1) || Number.isNaN(num2)) throw new Error('Los parámetros ingresados deben ser números')\n  const suma = num1 + num2\n  return suma\n}\n\ndescribe('sumaDosNumeros', () => {\n  it('Deberia ser una funcion', () => {\n    expect(typeof sumaDosNumeros).toBe('function')\n  })\n  it('Deberia throw si los parámetros ingresados no son números', () => {\n    expect(() => sumaDosNumeros()).toThrow()\n  })\n  it('Deberia throw un error específico si los parámetros ingresados no son números', () => {\n    expect(() => sumaDosNumeros()).toThrow('Los parámetros ingresados deben ser números')\n  })\n  it('Deberia throw un error específico si un NaN es ingresado como parámetro', () => {\n    expect(() => sumaDosNumeros(NaN, NaN)).toThrow('Los parámetros ingresados deben ser números')\n  })\n  it('Deberia return una suma', () => {\n    expect(sumaDosNumeros(1, 1)).toBe(2)\n  })\n})\n\n//Extra\n\nconst diccionario = {\n  name: 'Ángel',\n  age: 44,\n  birth_date: '16/09/1979',\n  programming_languages: ['html', 'css', 'javascript']\n}\n\ndescribe('diccionario', () => {\n  it('Sí el diccionario existe', () => {\n    expect(diccionario).toBeTruthy()\n  })\n  it('Sí diccionario es un objeto', () => {\n    expect(typeof diccionario).toBe('object')\n  })\n  it('El diccionario debería tener las claves name, age, birth_date y programming_languages', () => {\n    const keysFromDiccionario = Object.keys(diccionario)\n    const keysBuscadas = ['name', 'age', 'birth_date', 'programming_languages']\n    expect(keysFromDiccionario.some(e => keysBuscadas.includes(e))).toBe(true)\n  })\n  it('Shuld have no other property', () => {\n    const result = Object.prototype.hasOwnProperty.call(diccionario, 'casado')\n    expect(result).toBeFalsy()\n  })\n  it('La propiedad name deberia ser Ángel', () => {\n    const result = diccionario.name\n    expect(result).toBe('Ángel')\n  })\n  it('La propiedad age deberia ser 44', () => {\n    const result = diccionario.age\n    expect(result).toBe(44)\n  })\n  it('La propiedad birth_date deberia ser 16/09/1979', () => {\n    const result = diccionario.birth_date\n    expect(result).toBe('16/09/1979')\n  })\n  it('La propiedad programming_languages deberia contener los lenguajes html, css y javascript', () => {\n    const lenguajes = diccionario.programming_languages\n    const lenguajesBuscados = ['html', 'css', 'javascript']\n    expect(lenguajes.some(e => lenguajesBuscados.includes(e))).toBe(true)\n  })\n})"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/javascript/pedamoci.js",
    "content": "const arrTest = [123, 0, -42]\nconst arrTestError = [123, 0, -42, 'string'] // hace falta comentar el if que corrobora que son números\n\nconst sumar = (a,b) => {\n  return a + b\n}\n\nfunction testSumar(arr) { // test sin librerias externas\n  let i = 0\n  try {\n    do {\n      for (let index = i; index < arr.length; index++) {\n        if (typeof arr[i] === 'number' && typeof arr[index] === 'number') { // iría donde ingresan los datos pero en este ejercicio no existe eso\n          if (typeof sumar(arr[i], arr[index]) !== 'number') throw new Error(\"La función NO funciona correctamente\");\n        }\n      }\n      i++\n    } while (i < arr.length)\n  } catch (e) {\n    console.log(e.message)\n  }\n}\n\ntestSumar(arrTest)\n\n// ------------------------------------------ DIFICULTAD EXTRA ------------------------------------------\nconst arrLenguajes = [\"C\", \"Java\", \"Python\", \"C++\", \"C#\", \"JavaScript\", \"PHP\", \"R\", \"Swift\", \"Rust\", \"Go (Golang)\", \"Kotlin\", \"Ruby\", \"Julia\", \"Nim\", \"Perl\", \"Vala\", \"SAS\", \"Scratch\", \"D\", \"Dart\", \"PL/SQL\", \"Logo\", \"COBOL\", \"Tcl\", \"Smalltalk\", \"ABC\", \"Algol\", \"APL\", \"Bash\", \"Carbon\", \"CFML\", \"CHILL\", \"CLIPS\", \"Forth\", \"TypeScript\", \"HTML/CSS\", \"Razor\", \"Elixir\", \"Erlang\", \"ASP.NET\", \"Zig\", \"M4\"]\nconst requiredKeys = new Set([\"name\", \"age\", \"birth_date\", \"programming_languages\"])\n\nconst diccionario = {\n  name: 'Pedro',\n  age: 23,\n  // birth_date: '-03-04-22',\n  birth_date: '03/04/22',\n  programming_languages: ['JavaScript', 'C#', 'M4'],\n  // asd: 'asd'\n}\n\nfunction testCampos(dic) {\n  let keys = Object.keys(dic)\n  if (keys.length === requiredKeys.size && keys.every(k => requiredKeys.has(k))) {\n    testDatos(dic)\n  } else console.log('Los campos del diccionario son incorrectos')\n}\n\nfunction testDatos(dic) {\n  const date = new Date\n  let values = Object.values(dic)\n  let correctName = values[0].length <= 0 || (/\\d|\\W/g).test(values[0])\n  let correctAge = values[1].length <= 0 || values[1].length >= 125\n  const correctLanguages = () => {\n    for (let i = 0; i < values[3].length; i++) {\n      if (!(arrLenguajes.includes(values[3][i]))) { // revisa que el lenguaje ingresado este en el listado de arriba, ya que hacer un regex me parecio muy dificil\n        return true\n      }\n    } return false\n  }\n  let correctBirthDate\n  if (!(/[^\\d]-|-\\d+[^\\d-]|[a-zA-Z]|(-\\d+){3}/g).test(values[2])) { // detecta si hay un número negativo o una letra\n    let [day, month, year] = values[2].split(/\\W/g).map(Number)\n    correctBirthDate = \n    day <= 0 || day > 31 ||\n    month <= 0 || month > 12 ||\n    (year <= 100\n      ? false // ya se verifica en el regex\n      : year < (date.getFullYear() -125)  ||  year > date.getFullYear())\n  } else correctBirthDate = true\n  if (correctName || correctAge || correctLanguages() || correctBirthDate) { // si algún dato es incorrecto la variable o función devuelve/es  true\n    console.log('Los datos introducidos son INCORRECTOS')\n  } else console.log('Los campos y los datos son CORRECTOS')\n}\n\ntestCampos(diccionario)"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/javascript/qwik-zgheib.js",
    "content": "import assert from \"assert\";\nexport const sum = (a, b) => a + b;\n\nfunction test(description, fn) {\n  try {\n    fn();\n    console.log(`✔️  ${description}`);\n  } catch (error) {\n    console.log(`❌  ${description}`);\n    console.error(error);\n  }\n}\n\ntest(\"adds 1 + 2 to equal 3\", () => {\n  assert.strictEqual(sum(1, 2), 3);\n});\n\ntest(\"adds 1 + 1 to equal 2\", () => {\n  assert.strictEqual(sum(1, 1), 2);\n});\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/javascript/raulG91.js",
    "content": "function suma(a,b){\n    return a+b;\n}\n\ntest(\"Sum 2 + 2 equal 4\",()=>{\n    expect(suma.suma(2,2)).toBe(4)\n});\n\n\nlet my_dict = {\n\n    \"name\": \"Raul\",\n    \"age\": \"32\",\n    \"birth_date\": \"11/09/1991\",\n    \"programming_languages\": [\"Python\",\"Javascript\",\"Abap\"]\n};\ntest(\"Keys in object\",()=>{\n\n    expect(\"name\" in suma.my_dict).toBeTruthy();\n    expect(\"age\" in suma.my_dict).toBeTruthy();\n    expect(\"birth_date\" in suma.my_dict).toBeTruthy();\n    expect(\"programming_languages\" in suma.my_dict).toBeTruthy();\n\n});\n\ntest(\"Values for keys in object\",()=>{\n\n    expect(typeof(suma.my_dict[\"name\"])).toBe(\"string\");\n    expect(typeof(suma.my_dict[\"age\"])).toBe(\"string\");\n    expect(typeof(suma.my_dict[\"birth_date\"])).toBe(\"string\");\n    expect(typeof(suma.my_dict[\"programming_languages\"])).toBe(\"object\")\n\n});"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/javascript/seandsun.js",
    "content": "/* <-------------- Pruebas unitarias con jest -------------->\n1 - El archivo donde se escriben los test debe llevar la extensión .test.js así: pruebas.test.js\n2 - Crear un package json: npm init --yes\n3 - Instalar jest: npm i --save-dev jest o npm i jest -D\n4 - En el package.json cambiar ésto: \"scripts\": { \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\" }\n    Por estó: \"scripts\": { \"test\": \"jest\" }\n5 - Para ejecutar los test, ejecutar el comando: npm run test\n*/\n\nfunction suma(x,y) {\n    return x + y\n}\n\ndescribe('Test de sumas', () => {\n    // Pasa la prueba porque está bien escrito\n    test('3 + 5', () => {\n        const resultado = suma(3,5)\n\n        expect(resultado).toBe(8)\n    })\n    \n    // No pasa la prueba porque el resultado recibido es diferente al especificado\n    test('2 + 4', () => {\n        const resultado = suma(2,4)\n\n        expect(resultado).toBe(7)\n    })\n})\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/javascript/victor-Casta.js",
    "content": "/*\n  * Crea una función que se encargue de sumar dos números y retornar\n  * su resultado.\n  * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n  * capaz de determinar si esa función se ejecuta correctamente.\n*/\nconst assert = require('assert')\n\nfunction additionNumbers(a, b) {\n  return a + b\n}\n\nfunction runTests() {\n  try {\n    assert.equal(additionNumbers(5, 5), 10)\n    console.log('Test passed: additionNumbers(5, 5) === 10')\n  } catch (error) {\n    console.error('Test failed: additionNumbers(5, 5) !== 10')\n    console.error(error)\n  }\n\n  try {\n    assert.equal(additionNumbers(1, 9), 10)\n    console.log('Test passed: additionNumbers(1, 9) === 10')\n  } catch (error) {\n    console.error('Test failed: additionNumbers(1, 9) !== 10')\n    console.error(error)\n  }\n\n  try {\n    assert.equal(additionNumbers(0, 0), 0)\n    console.log('Test passed: additionNumbers(0, 0) === 0')\n  } catch (error) {\n    console.error('Test failed: additionNumbers(0, 0) !== 0')\n    console.error(error)\n  }\n\n  try {\n    assert.equal(additionNumbers(-1, -1), -2)\n    console.log('Test passed: additionNumbers(-1, -1) === -2')\n  } catch (error) {\n    console.error('Test failed: additionNumbers(-1, -1) !== -2')\n    console.error(error)\n  }\n\n  try {\n    assert.equal(additionNumbers(1, 2), 1)\n  } catch (error) {\n    console.error('Test failed: additionNumbers(1, 2) !== 1')\n    console.error(error)\n  }\n}\n\n// runTests()\n\n/*\n  * DIFICULTAD EXTRA (opcional):\n  * Crea un diccionario con las siguientes claves y valores:\n  * \"name\": \"Tu nombre\"\n  * \"age\": \"Tu edad\"\n  * \"birth_date\": \"Tu fecha de nacimiento\"\n  * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n  * Crea dos test:\n  * - Un primero que determine que existen todos los campos.\n  * - Un segundo que determine que los datos introducidos son correctos.\n*/\n\nlet dictionary = {\n  name: 'Victor',\n  age : 21,\n  birth_date: '17-12-2002',\n  programming_languages: ['JavaScript', 'TypeScript', 'Python']\n}\n\nfunction hasAllFields(obj, fields) {\n  for (const field of fields) {\n    if (!obj.hasOwnProperty(field)) {\n      return false;\n    }\n  }\n  return true;\n}\n\n\nconst requireItems = ['name', 'age', 'birth_date', 'programming_languages']\n\nfunction dictionaryTest() {\n  try {\n    assert.strictEqual(hasAllFields(dictionary, requireItems), true)\n    console.log('test passed: complete dictionary')\n  }catch (err) {\n    console.error('test failed: incomplete dictionary')\n    console.error(err)\n  }\n\n  try {\n    assert.strictEqual(typeof dictionary.name, 'string', 'el nombre debe ser un string')\n    assert.strictEqual(typeof dictionary.age, 'number', 'La edad debe ser un number')\n    assert.strictEqual(typeof dictionary.birth_date, 'string', 'La fecha debe ser tipo string')\n    assert.strictEqual(typeof dictionary.programming_languages, 'object', 'Debe ser una lista de lenguajes')\n  } catch (error) {\n    console.error(error)\n  }\n\n}\n\ndictionaryTest()"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/javascript/wapastorv.js",
    "content": "/*\n * EJERCICIO:\n * Crea una función que se encargue de sumar dos números y retornar\n * su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n * capaz de determinar si esa función se ejecuta correctamente.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\n */\n\n/* Los Mecanismos de Pruebas Unitarias en JavaScript son muy variados:\n    1. Pruebas unitarias: Las pruebas unitarias verifican que una parte específica del código funcione como se espera. para ello se utilizan frameworks de pruebas unitarias:\n        * Mocha (flexible y extensible).\n        * Jasmine (sin dependencias externas).\n        * Jest (Popular en proyectos con Node.js o React)..\n        * QUnit (usado principalmente con jQuery).\n        * Vitest (Alternativa moderna de Jest).\n    \n    2. Pruebas de integración: Las pruebas de integración verifican que los componentes del sistema funcionen correctamente juntos. \n        se puden usar los mismo frameworks de pruebas unitarias, pero enfocádos en esenarios que involucran varios componentes.\n\n    3. Pruebas end-to-end: Las pruebas end-to-end verifican que todo el sistema funcione correctamente. Los frameworks más populares son:\n        * Selenium (para pruebas web).\n        * Puppeteer (controla navegadores como Chrome mediante scripts).\n        * Cypress (para pruebas web).\n        * TestCafe (para pruebas web).\n        * playwright (para pruebas web).\n    \n    4. Pruebas manuales con console.assert(): La función console.assert() de JavaScript permite realizar pruebas manuales.\n        console.assert(2 + 2 === 4, 'Error: 2 + 2 debería ser 4'); // No se mostrará nada en la consola porque la condición es verdadera.\n        console.assert(2 + 2 === 5, 'Error: 2 + 2 debería ser 4'); // Se mostrará un mensaje de error en la consola porque la condición es falsa.\n    \n\n*/\nfunction sumar(a, b) {\n    if (typeof a !== 'number' || typeof b !== 'number') {\n        throw new Error('Ambos argumentos deben ser números');\n    }\n    return a + b;\n}\nfunction testSumar(){\n    console.log('Iniciando pruebas para la función `suma`....');\n\n    // Caso 1: Sumar dos numeros positivos\n    console.assert(sumar(3, 5) === 8, 'Error: suma(3, 5) deberia devolver 8');\n\n    // Caso 2: Sumar un numero positivo y un numero negativo\n    console.assert(sumar(10, -4) === 6, 'Error: suma(10, -4) deberia devolver');\n\n    // Caso 3: Sumar dos numeros negativos\n    console.assert(sumar(-10, -4) === -14, 'Error: suma(-10, -4) deberia devolver -14');\n\n    // Caso 4: Sumar dos numeros decimales\n    console.assert(sumar(3.5, 2.5) === 6, 'Error: suma(3.5, 2.5) deberia devolver 6');\n\n    // Caso 5: Sumar un numero y cero\n    console.assert(sumar(3, 0) === 3, 'Error: suma(3, 0) deberia devolver 3');\n\n    // Caso 6: Sumar ceros\n    console.assert(sumar(0, 0) === 0, 'Error: suma(0, 0) deberia devolver 0');\n\n    console.log('Pruebas para la función `suma` finalizadas, todas las pruebas pasaron correctamente.');\n}\n\ntestSumar();\n\nconst persona = {\n    nombre: 'Walter',\n    apellido: 'Pastor',\n    edad: 25,\n    fechaNacimiento: new Date('1995-01-01'),\n    lenguajesProgramacion: ['JavaScript', 'Python', 'Java']\n}\n\nfunction testObjetoPersona(){\n    console.log('Iniciando pruebas para el objeto `persona`....');\n\n    // Caso 1: Verificar que el objeto `persona` tenga las propiedades correctas\n    console.assert(persona.hasOwnProperty('nombre'), 'Error: persona deberia tener la propiedad \"nombre\"');\n    console.assert(persona.hasOwnProperty('apellido'), 'Error: persona deberia tener la propiedad \"apellido\"');\n    console.assert(persona.hasOwnProperty('edad'), 'Error: persona deberia tener la propiedad \"edad\"');\n    console.assert(persona.hasOwnProperty('fechaNacimiento'), 'Error: persona deberia tener la propiedad \"fechaNacimiento\"');\n    console.assert(persona.hasOwnProperty('lenguajesProgramacion'), 'Error: persona deberia tener la propiedad \"lenguajesProgramacion\"');\n\n    // Caso 2: Verificar que las propiedades del objeto `persona` tengan los valores correctos\n    console.assert(typeof persona.nombre === 'string', 'Error: persona.nombre deberia ser un string');\n    console.assert(typeof persona.apellido === 'string', 'Error: persona.apellido deberia ser un string');\n    console.assert(typeof persona.edad === 'number', 'Error: persona.edad deberia ser un número');\n    console.assert(persona.fechaNacimiento instanceof Date, 'Error: persona.fechaNacimiento deberia ser una instancia de Date');\n    console.assert(Array.isArray(persona.lenguajesProgramacion), 'Error: persona.lenguajesProgramacion deberia ser un array');\n\n    // Caso 3: Verificar que el objeto `persona` tenga los métodos correctos (opcional)\n    console.assert(persona.hasOwnProperty('saludar'), 'Error: persona deberia tener el método \"saludar\"');\n    console.assert(typeof persona.saludar === 'function', 'Error: persona.saludar deberia ser una función');\n\n    // Caso 4: Verificar que el método `saludar` del objeto `persona` funcione correctamente\n\n\n    \n    console.log('Pruebas para el objeto `persona` finalizadas, todas las pruebas pasaron correctamente.');\n}\n\ntestObjetoPersona();\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/kotlin/VincentRodriguezR.kt",
    "content": "//Estos imports deben ir en el archivo del test\nimport org.junit.Test\nimport org.junit.Assert.*\n\n//Clases que debe de ir en un archivo en la carpeta main\nclass calculadora(){\n    fun sum(num1:Int, num2:Int): Int{\n        var res = num1 + num2\n        return  res\n    }\n}\n\n//Ejercicio Extra\nclass developer(){\n    fun androidDeveloper(name:String, age: Int, birthDate: String, programmingLanguages: List<String>): MutableMap<String, String>{\n        val developerMap: MutableMap<String, String> = mutableMapOf()\n\n        developerMap.put(\"Name\", name)\n        developerMap.put(\"Age\", age.toString())\n        developerMap.put(\"BirthDate\", birthDate)\n        developerMap.put(\"ProgramminLanguages\", programmingLanguages.joinToString(\", \"))\n\n        return  developerMap\n    }\n}\n\n//Clases que deben ir en unarchivo en la carpeta de test\nclass calculadoraTest(){\n\n    val testeo = calculadora()\n\n    @Test\n    fun sumTest(){\n        val resultado = testeo.sum(2,3)\n        assertEquals(5,resultado)\n    }\n}\n\n//Dificultad Extra\nclass developerTest(){\n    val developerTest = developer()\n\n    @Test\n    fun androidDeveloperTest(){\n        val languages = listOf(\"Kotlin\", \"Java\", \"Python\")\n\n        val developerMap: MutableMap<String, String> = mutableMapOf()\n        developerMap.put(\"Name\", \"Vincent Rodriguez\")\n        developerMap.put(\"Age\", \"24\")\n        developerMap.put(\"BirthDate\", \"23/10/99\")\n        developerMap.put(\"ProgramminLanguages\", languages.joinToString (\", \"))\n\n        val res = developerTest.androidDeveloper(\"Vincent Rodriguez\", 24, \"23/10/99\", languages)\n        assertEquals(developerMap, res)\n    }\n\n    @Test\n    fun androidDeveloperTestNullValidation(){\n        val languages = listOf(\"Kotlin\", \"Java\", \"Python\")\n        var nullValidator = false\n\n        val developerMap: MutableMap<String, String> = mutableMapOf()\n        developerMap.put(\"Name\", \"Vincent Rodriguez\")\n        developerMap.put(\"Age\", \"24\")\n        developerMap.put(\"BirthDate\", \"23/10/99\")\n        developerMap.put(\"ProgramminLanguages\", languages.joinToString (\", \"))\n\n        for(i in developerMap){\n            if(i == null){\n                nullValidator = true\n            }\n        }\n\n        val res = developerTest.androidDeveloper(\"Vincent Rodriguez\", 24, \"23/10/99\", languages)\n        assertEquals(false, nullValidator)\n    }\n}"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/kotlin/annaviper.kt",
    "content": "package main\n\nimport org.testng.AssertJUnit.assertEquals\nimport org.testng.annotations.Test\n\n/*\n* SUM\n*/\n\nfun sum(num1: Int, num2: Int): Int {\n    return num1 + num2\n}\n\nclass SumTest {\n    @Test\n    fun testSum() {\n        assertEquals(42, sum(40, 2))\n    }\n}\n\n\n/*\n* DICTIONARY\n* */\n\nval data = mapOf(\n    \"name\" to \"Anna\",\n    \"age\" to \"36\",\n    \"birth_date\" to  \"13 de octubre\",\n    \"programming_languages\" to listOf(\"Python\", \"Kotlin\")\n)\n\nclass DictionaryTest {\n    @Test\n    fun testAllKeysExist() {\n        val correctKeys = setOf(\"name\", \"age\", \"birth_date\", \"programming_languages\")\n        assertEquals(data.keys, correctKeys)\n    }\n}"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/kotlin/blackriper.kt",
    "content": "\r\n/*\r\nEl testing nos ayuda a probar diferentes partes de nuestro codigo para comprobar que los resultados\r\nobtenidos son correctos de acuerdo a los parametros que configuramos\r\n\r\nPara poder realizar pruebas unitarias en kotlin se usa kotlintest\r\nhttps://kotlinlang.org/api/latest/kotlin.test/\r\n\r\nLos test deben ir en la carpeta src\\test\\kotlin en intellij para que se puedan ejecutar\r\nlos ejemplos que se muestran solo son ejemplos de pruebas unitarios.\r\n\r\nel metodo assert nos sirve para indicar que resultado se espera y el resultado real es evaluado\r\npara saber si es correcto o no ademas de evaluar que el resultado sea el esperado tambien puedes evaluar\r\nque el resultado no sea el esperado\r\n*/\r\n\r\n// operacion a testear\r\nclass Operations{\r\n    fun sum(a: Int, b: Int): Int = a + b\r\n}\r\n\r\n/*\r\n clase que testea la operacion suma\r\n\r\n import kotlin.test.Test\r\n import kotlin.test.assertEquals\r\n\r\n class SumTest {\r\n    @Test\r\n    fun testSum() {\r\n        val operations = Operations()\r\n        assertEquals(10,operations.sum(5,5))\r\n    }\r\n}\r\n\r\n */\r\n\r\nclass Backdev{\r\n    private val programingLanguajes = listOf(\"Java\",\"Kotlin\",\"Python\",\"go\",\"swift\")\r\n    val dataDev= mapOf(\"name\" to \"blackriper\", \"age\" to 29,\"birth_date\" to \"20/05/1994\", \"programing_languages\" to programingLanguajes)\r\n}\r\n\r\n/*\r\nclase para testear el mapa\r\n\r\nimport kotlin.test.Test\r\nimport kotlin.test.assertContains\r\nimport kotlin.test.assertFalse\r\nimport kotlin.test.assertTrue\r\n\r\n\r\nclass DevTest {\r\n\r\n    @Test\r\n    fun testDev() {\r\n      val backdev = Backdev()\r\n      val mockdev = mapOf(\"name\" to \"blackriper\", \"age\" to 29,\"birth_date\" to \"20/05/1994\", \"programing_languages\" to listOf(\"Java\",\"Kotlin\",\"Python\",\"go\",\"swift\"))\r\n      val mockdevError = mapOf(\"nombre\" to \"blackriper\", \"age\" to 29,\"birth_date\" to \"20/05/1994\")\r\n     // comprobar que los datos de  mockdev es igual a backdev.dataDev\r\n     assertTrue { mockdev == backdev.dataDev }\r\n     assertFalse { mockdevError == backdev.dataDev }\r\n     // comprobar campos\r\n      assertTrue { backdev.dataDev.entries.containsAll(mockdev.entries) }\r\n      assertFalse { backdev.dataDev.entries.containsAll(mockdevError.entries) }\r\n\r\n    }\r\n}\r\n\r\n*/"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/kotlin/eulogioep.kt",
    "content": "import org.junit.jupiter.api.Assertions.*\nimport org.junit.jupiter.api.Test\n\n// Función para sumar dos números\nfun suma(a: Int, b: Int): Int {\n    return a + b\n}\n\n// Diccionario con información personal\nval personalInfo = mapOf(\n    \"name\" to \"Eulogio EP\",\n    \"age\" to \"41\",\n    \"birth_date\" to \"1981-05-12\",\n    \"programming_languages\" to listOf(\"Kotlin\", \"Java\", \"Python\")\n)\n\nclass EjercicioTest {\n\n    @Test\n    fun testSuma() {\n        assertEquals(5, suma(2, 3))\n        assertEquals(0, suma(-1, 1))\n        assertEquals(-5, suma(-2, -3))\n    }\n\n    @Test\n    fun testDiccionarioTieneTodosLosCampos() {\n        val camposRequeridos = listOf(\"name\", \"age\", \"birth_date\", \"programming_languages\")\n        camposRequeridos.forEach { campo ->\n            assertTrue(personalInfo.containsKey(campo), \"El diccionario no contiene el campo: $campo\")\n        }\n    }\n\n    @Test\n    fun testDatosDiccionarioSonCorrectos() {\n        assertEquals(\"Eulogio EP\", personalInfo[\"name\"])\n        assertEquals(\"41\", personalInfo[\"age\"])\n        assertEquals(\"1981-05-12\", personalInfo[\"birth_date\"])\n        \n        val lenguajes = personalInfo[\"programming_languages\"] as? List<String>\n        assertNotNull(lenguajes)\n        assertTrue(lenguajes!!.containsAll(listOf(\"Kotlin\", \"Java\", \"Python\")))\n    }\n}"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/ocaml/luishendrix92.ml",
    "content": "open OUnit2\n\n(*****************************************************************************)\n(*                                                                           *)\n(*                                Unit Testing                               *)\n(*                                                                           *)\n(*  There are 2 main ways of testing in OCaml: using inline tests with pre-  *)\n(*  processors which live in the same file as the code we want to test,      *)\n(*  leveraging the power of testing frameworks such as OUnit, Alcotest, and  *)\n(*  QCheck; combined with a build system like Dune.                          *)\n(*                                                                           *)\n(*    For this example, I'm using OUnit2 in the same executable as the code  *)\n(*  file that contains the code I want to test which should normally live    *)\n(*  in a separate file. It is the most endorsed testing framework in OCaml   *)\n(*  and is very similar other familiar frameworks: you can group tests,      *)\n(*  assert different things, describe tests, skip them, mock, and more!      *)\n(*                                                                           *)\n(*****************************************************************************)\n\nmodule StringMap = Map.Make (String)\n\nmodule Testable : sig\n  (** [Testable] contains code that should be otherwise consumed in a separate\n      test file and should only expose the functions that the client of the\n      library we are writing is concerned with. We can achieve this level of\n      encapsulation through signatures, thus {b sealing} the module. *)\n\n  val add : int -> int -> int\n  (** [add a b] is the sum of integers [a] and [b]. *)\n\n  val create_programmer\n    :  string\n    -> int\n    -> string\n    -> string list\n    -> string StringMap.t\n  (** [create_programmer name age birth_date programming_languages] creates an\n      immutable map/dictionary with 4 string keys corresponding to a programmer\n      with a name, age, birth date and favourite programming languages.\n\n      Due to type constraints, all values of the map once created are of type\n      [string], so the integer and list values need to be converted to their\n      respective original types [int] and [string list] (comma separated) in\n      order to use them properly. *)\nend = struct\n  (* Alternative to a [Map], the way we define custom domain types in OCaml\n     is through [records] but since the extra challenge requires a dictionary,\n     I'm using a [Map] instead which slightly restricts the type system. *)\n\n  let add = ( + )\n\n  let create_programmer name age birth_date programming_languages =\n    StringMap.(\n      empty\n      |> add \"name\" name\n      |> add \"age\" (string_of_int age)\n      |> add \"birth_date\" birth_date\n      |> add \"programming_languages\" (String.concat \",\" programming_languages))\n  ;;\nend\n\nlet exercise_tests =\n  \"Exercise #13 Test Suite\"\n  >::: [ (\"addition of two positive integers\"\n          >:: fun _ -> assert_equal 15 (Testable.add 5 10))\n       ; (\"addition of two negative integers\"\n          >:: fun _ -> assert_equal (-90) (Testable.add (-40) (-50)))\n       ; (\"addition of negative and positive integers\"\n          >:: fun _ ->\n          (* This test fails, but without the [printer] named argument set, it\n             would print [not equal]. To improve the output, the argument needs\n             to be set to a function that knows how to transform the type of\n             the two compared values to [string]; in this case, [string_of_int]\n             allows the test framework to output the following report:\n\n             {[\n               Error: Exercise #13 Test Suite:2:\n               addition of negative and positive integers.\n\n               <SOME EXTRA INFO I OMITTED>\n\n               expected: 1 but got: 0\n               ---------------------------------------------------------------\n               Ran: 3 tests in: 0.10 seconds.\n               FAIL: Cases: 3 Tried: 3 Errors: 0 Failures: 1 Skip:  0 Todo: 0.\n             ]}\n\n             The real output contains extra information such as the file where\n             the assertion failure happened, the line and column, along with a\n             small stack trace of which function call produced the failure. *)\n          assert_equal 0 (Testable.add 9 (-9));\n          assert_equal ~printer:string_of_int 1 (Testable.add (-3) 3))\n       ]\n;;\n\nlet _ = run_test_tt_main exercise_tests\n\n(**************************************************************************)\n(*                                                                        *)\n(*                       Dificultad Extra (Opcional)                      *)\n(*                                                                        *)\n(*  Crea un diccionario con las siguientes claves y valores:              *)\n(*  - [name]: Tu nombre                                                   *)\n(*  - [age]: Tu edad                                                      *)\n(*  - [birth_date]: Tu fecha de nacimiento                                *)\n(*  - [programming_languages]: Listado de lenguajes de programación       *)\n(*                                                                        *)\n(*  Crea dos test:                                                        *)\n(*  - Un primero que determine que existen todos los campos.              *)\n(*  - Un segundo que determine que los datos introducidos son correctos.  *)\n(*                                                                        *)\n(**************************************************************************)\n\nmodule DateValidator = struct\n  open Core\n\n  let years_of_date date_str =\n    let today = Date.today ~zone:Time_float.Zone.utc in\n    let date = Core.Date.of_string date_str in\n    Date.diff today date / 365\n  ;;\n\n  let validate_date_str date_str =\n    let year, month, day =\n      match String.split ~on:'/' date_str with\n      | year :: month :: day :: _ ->\n        int_of_string year, int_of_string month, int_of_string day\n      | _ -> failwith \"Date parsing failed\"\n    in\n    year > 0 && month >= 1 && month <= 12 && day >= 1 && day <= 31\n  ;;\nend\n\nlet challenge_tests =\n  let mock =\n    Testable.create_programmer\n      \"Luis Lopez\"\n      32\n      \"1992/04/09\"\n      [ \"Haskell\"\n      ; \"Clojure\"\n      ; \"Typescript\"\n      ; \"OCaml\"\n      ; \"Elixir\"\n      ; \"Java\"\n      ; \"Python\"\n      ]\n  in\n  let open Testable in\n  \"Optional Challenge #13 Test Suite\"\n  >::: [ (\"a mock programmer map has all fields set\"\n          >:: fun _ ->\n          assert_bool \"[name] field absent\" (StringMap.mem \"name\" mock);\n          assert_bool \"[age] field absent\" (StringMap.mem \"age\" mock);\n          assert_bool\n            \"[birth_date] field absent\"\n            (StringMap.mem \"birth_date\" mock);\n          assert_bool\n            \"[programming_languages] exists\"\n            (StringMap.mem \"programming_languages\" mock))\n       ; (\"a mock programmer map has is valid and has the correct data\"\n          >:: fun _ ->\n          let name = StringMap.find \"name\" mock in\n          let age = int_of_string @@ StringMap.find \"age\" mock in\n          let birth_date = StringMap.find \"birth_date\" mock in\n          let programming_languages =\n            StringMap.find \"programming_languages\" mock\n            |> String.split_on_char ','\n          in\n          assert_bool \"[name] field is empty\" (name <> \"\");\n          assert_equal \"Luis Lopez\" name;\n          assert_bool \"[age] field is not greater than 0\" (age > 0);\n          assert_equal 32 age;\n          assert_bool \"[birth_date] is empty\" (birth_date <> \"\");\n          assert_bool\n            \"[birth_date] is invalid\"\n            (DateValidator.validate_date_str birth_date);\n          assert_bool\n            \"[birth_date] conflicts with [age]\"\n            (DateValidator.years_of_date birth_date = 32);\n          assert_equal \"1992/04/09\" birth_date;\n          assert_equal\n            programming_languages\n            [ \"Haskell\"\n            ; \"Clojure\"\n            ; \"Typescript\"\n            ; \"OCaml\"\n            ; \"Elixir\"\n            ; \"Java\"\n            ; \"Python\"\n            ])\n       ]\n;;\n\nlet _ = run_test_tt_main challenge_tests\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/php/eulogioep.php",
    "content": "<?php\n\n/**\n * Función que suma dos números y retorna el resultado.\n * @param int|float $a Primer número a sumar.\n * @param int|float $b Segundo número a sumar.\n * @return int|float La suma de a y b.\n */\nfunction suma($a, $b) {\n    return $a + $b;\n}\n\n/**\n * Crea y retorna un array asociativo con datos personales.\n * @return array Array asociativo con datos personales.\n */\nfunction crearArrayAsociativo() {\n    return [\n        \"name\" => \"Tu nombre\",\n        \"age\" => 30,\n        \"birth_date\" => \"1993-01-01\",\n        \"programming_languages\" => [\"PHP\", \"JavaScript\", \"Python\"]\n    ];\n}\n\n// Incluimos PHPUnit para las pruebas\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * Clase de pruebas unitarias para las funciones suma y crearArrayAsociativo.\n */\nclass PruebasUnitarias extends TestCase\n{\n    /**\n     * Prueba la función suma con varios casos.\n     */\n    public function testSuma()\n    {\n        $this->assertEquals(5, suma(2, 3), \"La suma de 2 y 3 debería ser 5\");\n        $this->assertEquals(0, suma(-1, 1), \"La suma de -1 y 1 debería ser 0\");\n        $this->assertEquals(-5, suma(-2, -3), \"La suma de -2 y -3 debería ser -5\");\n    }\n\n    /**\n     * Prueba la existencia de todas las claves en el array asociativo.\n     */\n    public function testExistenciaClaves()\n    {\n        $array = crearArrayAsociativo();\n        $this->assertArrayHasKey('name', $array, \"El array debe contener la clave 'name'\");\n        $this->assertArrayHasKey('age', $array, \"El array debe contener la clave 'age'\");\n        $this->assertArrayHasKey('birth_date', $array, \"El array debe contener la clave 'birth_date'\");\n        $this->assertArrayHasKey('programming_languages', $array, \"El array debe contener la clave 'programming_languages'\");\n    }\n\n    /**\n     * Prueba que los datos en el array asociativo son correctos.\n     */\n    public function testDatosCorrectos()\n    {\n        $array = crearArrayAsociativo();\n        $this->assertEquals(\"Tu nombre\", $array['name'], \"El nombre debe ser 'Tu nombre'\");\n        $this->assertIsInt($array['age'], \"La edad debe ser un entero\");\n        $this->assertMatchesRegularExpression('/^\\d{4}-\\d{2}-\\d{2}$/', $array['birth_date'], \"La fecha de nacimiento debe tener el formato YYYY-MM-DD\");\n        $this->assertIsArray($array['programming_languages'], \"Los lenguajes de programación deben ser un array\");\n        $this->assertNotEmpty($array['programming_languages'], \"La lista de lenguajes de programación no debe estar vacía\");\n    }\n}\n\n?>"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/php/gabrielmoris.php",
    "content": "<?php\n/*\n* EXERCISE:\n* Create a function that is responsible for adding two numbers and returning\n* its result.\n* Create a test, using the tools of your language, that is\n* able to determine if that function is executing correctly.\n*/\n\n// There are several libraries available for unit testing. I will create my own Tests.\nfunction sum($num1, $num2)\n{\n\n    // I mock an error\n    if ($num1 > 5) {\n        $num1 = $num1 + 10;\n    }\n\n    return $num1 + $num2;\n}\n\nclass Test\n{\n    public function expects($callback, $result, $message = \"\", ...$args)\n    {\n        if (is_string($callback)) {\n            $callback = function (...$args) use ($callback) {\n                return $callback(...$args);\n            };\n        }\n\n        $actualResult = $callback(...$args);\n\n        if (empty($message)) {\n            return $actualResult === $result;\n        }\n\n        if ($actualResult !== $result) {\n            return $message;\n        }\n    }\n\n    public function assertEquals($val1, $val2, $message = \"\")\n    {\n        if (empty($message)) {\n            return $val1 === $val2;\n        }\n\n        if ($val1 !== $val2) {\n            return $message;\n        }\n    }\n\n    public function assertNotEquals($val1, $val2, $message = \"\")\n    {\n        if (empty($message)) {\n            return $val1 !== $val2;\n        }\n\n        if ($val1 === $val2) {\n            return $message;\n        }\n    }\n\n    public function assertFalse($condition, $message = '')\n    {\n        if (empty($message)) {\n            return $condition === false;\n        }\n\n        if ($condition !== false) {\n            return $message;\n        }\n    }\n\n    public function assertNull($value, $message = '')\n    {\n        if (empty($message)) {\n            return $value === null;\n        }\n\n        if ($value !== null) {\n            return $message;\n        }\n    }\n\n    public function has_all_keys($object, $keys)\n    {\n        foreach ($keys as $key) {\n            if (!property_exists($object, $key)) {\n                echo \"Property \" . $key . \" is not in this Object\\n\";\n                return false;\n            }\n        }\n\n        return true;\n    }\n}\n\n$test = new Test();\n$result = $test->expects('sum', 7, '', 3, 4);\nvar_dump($result);\n$result = $test->expects('sum', 9, '', 6, 3);\necho $result ? 'Test Case 2 Passed' : 'Test Case 2 Failed';\necho \"\\n\";\n\n\n\n/* \n* EXTRA DIFFICULTY (optional):\n* Create a dictionary with the following keys and values:\n* \"name\": \"Your name\"\n* \"age\": \"Your age\"\n* \"birth_date\": \"Your date of birth\"\n* \"programming_languages\": [\"List of programming languages\"]\n* Create two tests:\n* A first one that determines that all fields exist.\n* A second one that determines that the data entered is correct.\n*/\n\n$dictionary = (object) [\"name\" => \"Gabrielmoris\", \"age\" => 34, \"birthday\" => \"15.18.1986\", \"programming_languages\" => [\"Javascript\", \"Typescript\", \"PHP\", \"Rust\"]];\n\necho $test->has_all_keys($dictionary, [\"name\", \"age\", \"birthday\", \"programming_languages\"]) ?  \"It has all properties\\n\" :  \"Error\\n\";\necho $test->has_all_keys($dictionary, [\"failure\"]) ?  \"It has all properties\\n\" :  \"Error\\n\";\n\necho $test->assertEquals($dictionary->name, \"Gabrielmoris\") ? \"Name correct\\n\" : \"Not my name\\n\";\necho $test->assertEquals($dictionary->age, 34) ? \"Age correct\\n\" : \"Not my age\\n\";\necho $test->assertEquals($dictionary->birthday, \"15.18.1986\") ? \"Birthday correct\\n\" : \"Not my birthday\\n\";\necho $test->assertEquals($dictionary->programming_languages, [\"Javascript\", \"Typescript\", \"PHP\", \"Rust\"]) ? \"Programming languages correct\\n\" : \"Not my Programming languages\\n\";\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/php/miguelex.php",
    "content": "<?php \n\nfunction sumar($a, $b){\n    return $a + $b;\n}\n\nglobal $dict;\n\n$dict = [\n    \"name\" => \"Miguel\",\n    \"age\" => 48,\n    \"birth_date\" => \"1975-09-03\",\n    \"programming_languages\" => [\"Python\", \"PHP\", \"JavaScript\"]\n];\n\n?>\n\n<?php \nrequire_once 'miguelex.php';\n\n\n// Tests - Deben ir en u nfichero aparte de nombre miguelexTest.php\n\nuse PHPUnit\\Framework\\TestCase;\n\nclass MiguelexTest extends TestCase {\n    public function testSum() {\n        $this->assertEquals(4, sumar(2, 2));\n        $this->assertEquals(10, sumar(5, 5));\n    }\n\n    public function testDictionaryFields() {\n        global $dict;\n\n        $this->assertArrayHasKey('name', $dict);\n        $this->assertArrayHasKey('age', $dict);\n        $this->assertArrayHasKey('birth_date', $dict);\n        $this->assertArrayHasKey('programming_languages', $dict);\n    }\n\n    public function testDictionaryValues() {\n        global $dict;\n\n        $this->assertIsString($dict['name']);\n        $this->assertIsInt($dict['age']);\n        $this->assertMatchesRegularExpression('/^\\d{4}-\\d{2}-\\d{2}$/', $dict['birth_date']);\n        $this->assertIsArray($dict['programming_languages']);\n    }\n}"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/php/thaishdz.php",
    "content": "<?php\n\n/*\n    * Esta es solo la parte EXTRA, la hice como si se tratase de testear \n    * los datos de un estudiante.\n    *Student.php y StudentTest.php son dos ficheros independientes.\n*/\n\n\n// Student.php -----------------------------------------------------------------\n\nnamespace App;\n\n\nclass Student\n{\n    private $studentData; \n\n    public function __construct()\n    {\n        $this->studentData = [\n            \"name\" => \"Benedicto el Sabio\",\n            \"age\"  => 24,\n            \"birth_date\" => new \\DateTime(\"2000-11-10\"),\n            \"programming_languages\" => [\"php\", \"python\", \"javascript\"]\n        ];\n    }\n\n    public function studentData() : array \n    {\n        return $this->studentData;\n    }\n}\n\n// StudentTest.php -----------------------------------------------------------------\n\nuse PHPUnit\\Framework\\TestCase;\nuse App\\Student;\n\n\nclass StudentTest extends TestCase\n{\n    protected $student;\n\n    protected function setUp(): void\n    {\n        $this->student = new Student();\n    }\n\n    public function testStudentDataFieldsExist()\n    {\n        $this->assertArrayHasKey(\"name\", $this->student->studentData());\n        $this->assertArrayHasKey(\"age\", $this->student->studentData());\n        $this->assertArrayHasKey(\"birth_date\", $this->student->studentData());\n        $this->assertArrayHasKey(\"programming_languages\", $this->student->studentData());\n    }\n\n    // 2 ways of defining an assertion\n\n    function testStudentDataIsCorrect() \n    {\n        self::assertIsString($this->student->studentData()[\"name\"]);\n        self::assertIsInt($this->student->studentData()[\"age\"]);\n        self::assertInstanceOf(\\DateTime::class, $this->student->studentData()[\"birth_date\"]);\n        self::assertIsArray($this->student->studentData()[\"programming_languages\"]);\n    }\n    \n}"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/AChapeton.py",
    "content": "import unittest\n\ndef sumar(num1, num2):\n  return num1 + num2\n\nclass TestSum(unittest.TestCase):\n  def test_1(self):\n    resultado = sumar(1, 2)\n    self.assertEqual(resultado, 3)\n\n# DIFICULTAD EXTRA\n\nuser = {\n    \"name\": \"Chape\",\n    \"age\": 27,\n    \"birth_date\": \"1997-06-02\",\n    \"programming_languages\": [\"js\", \"ts\", \"py\"]\n}\n\nclass TestDict(unittest.TestCase):\n    def test_check_all_keys(self):\n        self.assertIn(\"name\", user)\n        self.assertIn(\"age\", user)\n        self.assertIn(\"birth_date\", user)\n        self.assertIn(\"programming_languages\", user)\n    \n    def test_check_values(self):\n        self.assertEqual(user[\"name\"], \"Andres\")\n        self.assertEqual(user[\"age\"], 27)\n        self.assertEqual(user[\"birth_date\"], \"1997-06-02\",)\n        self.assertEqual(user[\"programming_languages\"], [\"js\", \"ts\", \"py\"])\n\n\nif __name__ == '__main__':\n    unittest.main()\n\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/Aldroide.py",
    "content": "import unittest\nfrom datetime import datetime, date\n\n\"\"\"Ejercicio\"\"\"\n\n\ndef sum(a, b):\n    if not isinstance(a, (int, float)) or not isinstance(b, (int, float)):\n        raise ValueError(\"Los argumentos deben ser numeros reales\")\n    return a + b\n\n# Funcion para hacer el test\n\n\nclass TestSum(unittest.TestCase):\n\n    def test_sum(self):\n        self.assertEqual(sum(5, 7), 12)\n        self.assertEqual(sum(5, -7), -2)\n        self.assertEqual(sum(0, 0), 0)\n        self.assertEqual(sum(2.5, 2.1), 4.6)\n        self.assertEqual(sum(2.1, 2), 4.1)\n        self.assertEqual(sum(2.5, 2.5), 5)\n\n    def test_sum_type(self):\n        with self.assertRaises(ValueError):\n            sum(\"5\", 7)\n        with self.assertRaises(ValueError):\n            sum(5, \"7\")\n        with self.assertRaises(ValueError):\n            sum(\"5\", \"7\")\n        with self.assertRaises(ValueError):\n            sum(\"a\", 7.1)\n\n\n\"\"\"Ejercicio Extra\"\"\"\n\n\nclass TestData(unittest.TestCase):\n\n    def setUp(self) -> None:\n        self.data = {\n            \"name\": \"Aldo Avila\",\n            \"Age\": 40,\n            \"birth_date\": datetime.strptime(\"24-09-83\", \"%d-%m-%y\").date(),\n            \"Programming_languages\": [\"Python\", \"C++\"]\n        }\n\n    def test_field_exist(self):\n        self.assertIn(\"name\", self.data)\n        self.assertIn(\"Age\", self.data)\n        self.assertIn(\"birth_date\", self.data)\n        self.assertIn(\"Programming_languages\", self.data)\n\n    def test_data_is_correct(self):\n        self.assertIsInstance(self.data[\"name\"], str)\n        self.assertIsInstance(self.data[\"Age\"], int)\n        self.assertIsInstance(self.data[\"birth_date\"], date)\n        self.assertIsInstance(self.data[\"Programming_languages\"], list)\n\n\nunittest.main()\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/C-Gabs.py",
    "content": "#Reto 13\n\n'''Crea una función que se encargue de sumar dos números y retornar\n * su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n * capaz de determinar si esa función se ejecuta correctamente.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.'''\n\nimport unittest\n\ndef suma(num_1,num_2):\n    return num_1 + num_2\n\nclass TestOperations(unittest.TestCase):\n    \n    def test_suma(self):\n        self.assertEqual(suma(2,5),7)\n\n#Reto extra\n\nfrom datetime import date\n#Reto extra\ndatos = {\n\"name\": \"Gabriel\",\n\"age\": 24,\n\"birth_date\": date.fromisoformat(\"2000-03-30\"),\n\"programming_languages\": [\"Python\",\"SQL\"]\n}\n\nclass TestDictValues(unittest.TestCase):\n\n    def test_campos(self):\n        for key in datos.keys():\n            self.assertIn(key,(\"name\",\"age\",\"birth_date\",\"programming_languages\"))\n\n    def test_datos(self):\n        self.assertTrue(datos[\"name\"].isalpha())\n        self.assertTrue(type(datos[\"age\"]) == int)\n        self.assertIsInstance(datos[\"birth_date\"],date)\n        self.assertTrue(type(datos[\"programming_languages\"]) == list)\n\nif __name__ == '__main__':\n    unittest.main()\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/CaveroBrandon.py",
    "content": "\"\"\"EJERCICIO:\nCrea una función que se encargue de sumar dos números y retornar su resultado.\nCrea un test, utilizando las herramientas de tu lenguaje, que sea\ncapaz de determinar si esa función se ejecuta correctamente.\"\"\"\n\nimport unittest\n\n\ndef basic_sum(num_a, num_b):\n    return num_a + num_b\n\n\nclass TestBasicSum(unittest.TestCase):\n    def test_positive_integers_can_be_added(self):\n        # Verify that two positive integers can be added\n        self.assertEqual(basic_sum(3, 5), 8)\n\n    def test_negative_integers_can_be_added(self):\n        # Verify that two negative numbers can be added\n        self.assertEqual(basic_sum(-3, -2), -5)\n\n    def test_positive_and_negative_numbers_can_be_added(self):\n        # Verify that a positive number and a negative number can be added\n        self.assertEqual(basic_sum(5, -3), 2)\n\n    def test_zeros_can_be_added(self):\n        # Verify that the sum of two zeros is zero\n        self.assertEqual(basic_sum(0, 0), 0)\n\n\n\"\"\"DIFICULTAD EXTRA (opcional):\nCrea un diccionario con las siguientes claves y valores:\n - \"name\": \"Tu nombre\"\n - \"age\": \"Tu edad\"\n - \"birth_date\": \"Tu fecha de nacimiento\"\n - \"programming_languages\": [\"Listado de lenguajes de programación\"]\nCrea dos test:\n - Un primero que determine que existen todos los campos.\n - Un segundo que determine que los datos introducidos son correctos.\"\"\"\n\n\ndef create_personal_information_dictionary():\n    personal_information = {\n        'name': 'Brandon Cavero',\n        'age': 29,\n        'dob': '05/20/1994',\n        'programing_languages': ['Python', 'Matlab', 'C#']\n    }\n    return personal_information\n\n\nclass TestCreatePersonalInformation(unittest.TestCase):\n    def test_that_none_of_the_values_in_dictionary_is_none(self):\n        personal_information = create_personal_information_dictionary()\n        for key in personal_information:\n            self.assertIsNotNone(personal_information.get(key))\n\n    def test_the_information_in_dictionary_is_expected(self):\n        personal_information = create_personal_information_dictionary()\n        name = personal_information.get('name')\n        age = personal_information.get('age')\n        dob = personal_information.get('dob')\n        programing_languages = personal_information.get('programing_languages')\n\n        # Verify that the type of each value is expected\n        self.assertEqual(type(name), str)\n        self.assertEqual(type(age), int)\n        self.assertEqual(type(dob), str)\n        self.assertEqual(type(programing_languages), list)\n\n        # Verify that the created data is expected\n        self.assertEqual(name, 'Brandon Cavero')\n        self.assertEqual(age, 29)\n        self.assertEqual(dob, '05/20/1994')\n        self.assertEqual(programing_languages, ['Python', 'Matlab', 'C#'])\n\n\nif __name__ == '__main__':\n    unittest.main(verbosity=2)\n\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/CesarCarmona30.py",
    "content": "'''\n  EJERCICIO\n\n  Pruebas elaboradas con el modulo doctest\n  Ejecutado en terminal con python -m doctest -v file.py\n'''\n\ndef suma(num1, num2):\n  '''\n  Función que suma dos números\n  y retorna su valor\n\n  >>> suma(10, 20)\n  30\n\n  >>> suma(324, 562)\n  886\n\n  >>> suma(432, 'hola')\n  'Error: Valor no númerico recibido.'\n\n  >>> suma(1e312, 1)\n  'Error: Exceso del valor númerico.'\n  \n  '''\n  try:\n    result = num1 + num2\n    if result == float('inf'):\n      raise OverflowError\n    return result\n  except TypeError:\n    return f'Error: Valor no númerico recibido.'\n  except OverflowError:\n    return f'Error: Exceso del valor númerico.'\n  \n'''\n  EXTRA\n'''\n\n\ndef createData(name = None, age = None, birth_date = None, languages = None):\n  '''\n  Función que crea un diccionario\n  con los datos proporcionados\n\n  >>> name, age, birth_date, languages = 'César', 19, '30-07-2004', ['Java', 'Python', 'C++', 'JavaScript']\n  >>> data = createData(name, age, birth_date, languages)\n  >>> validateFields(data)\n  True\n  >>> validateData(data)\n  True\n  >>> name_2, age_2, birth_date_2 = 'Ale', '22', '01-11-01'\n  >>> createData(name_2, age_2, birth_date_2)\n  'Algunos argumentos no se introdujeron.'\n  >>> data_3 = createData(name_2, age_2, birth_date_2, ['JavaScript', 'C'])\n  >>> validateData(data_3)\n  False\n  >>> data_4 = { \"name\": \"Diego\", \"age\": 15 }\n  >>> validateFields(data_4)\n  False\n  '''\n\n  if None in (name, age, birth_date, languages):\n    return 'Algunos argumentos no se introdujeron.'\n  return {\n    \"name\": name,\n    \"age\": age,\n    \"birth_date\": birth_date,\n    \"programming_languages\": languages\n  }\n\ndef validateFields(data_dict):\n  return all(key in data_dict for key in [\"name\", \"age\", \"birth_date\", \"programming_languages\"])\n\ndef validateData(data):\n  return all([\n    isinstance(data.get('name'), str),\n    isinstance(data.get('age'), int),\n    isinstance(data.get('birth_date'), str),\n    isinstance(data.get('programming_languages'), list)\n  ])"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/Chrisdev00.py",
    "content": "\"\"\"\n* EJERCICIO:\n* Crea una función que se encargue de sumar dos números y retornar\n* su resultado.\n* Crea un test, utilizando las herramientas de tu lenguaje, que sea\n* capaz de determinar si esa función se ejecuta correctamente.\n*\n* DIFICULTAD EXTRA (opcional):\n* Crea un diccionario con las siguientes claves y valores:\n* \"name\": \"Tu nombre\"\n* \"age\": \"Tu edad\"\n* \"birth_date\": \"Tu fecha de nacimiento\"\n* \"programming_languages\": [\"Listado de lenguajes de programación\"]\n* Crea dos test:\n* - Un primero que determine que existen todos los campos.\n* - Un segundo que determine que los datos introducidos son correctos.\n\n\"\"\"\n\nimport unittest\n\ndef suma(a, b):\n    return a + b\n\nclass TestPrueba(unittest.TestCase):\n\n    def test_suma(self):\n        self.assertEqual(suma(1,2), 3)\n        self.assertEqual(suma(-1,1), 0)\n        self.assertEqual(suma(-1,-1), -2)\n        self.assertNotEqual(suma(4,3), 5)        # Verifica que suma no sea igual a 5\n        self.assertTrue(suma(0,0) == 0)          # Verifica que suma sea True (0 igual a 0)\n        self.assertIsInstance(suma(6,9), int)    # Verifica que el resultado sea un int\n        #self.assertIsNone(suma(0,0))    # Comentamos el ultimo porque Verifica que suma(0, 0) sea None (esto fallará)\n\nif __name__ == '__main__':\n    unittest.main()\n\n\n######### -------------------------- EXTRA -------------------------------------  #################\n\n\nmy_dict = {\n    \"name\": \"Chris\",\n    \"age\": 23,\n    \"birth_date\": \"01/08/1994\",\n    \"programming_languages\": [\"Python\", \"JavaScript\", \"HTML\"]\n}\n\nclass DictionaryTest(unittest.TestCase):\n\n    def test_first (self):\n        expected_keys = [\"name\", \"age\", \"birth_date\", \"programming_languages\"]\n        for key in expected_keys:\n            self.assertIn(key, my_dict, f'{key} esta clave esta faltando en my_dict')\n\n    def test_second (self):\n        self.assertIsInstance(my_dict[\"name\"], str)\n        self.assertIsInstance(my_dict[\"age\"], int)\n        self.assertIsInstance(my_dict[\"birth_date\"], str)\n        self.assertIsInstance(my_dict[\"programming_languages\"], list)\n        for language in my_dict[\"programming_languages\"]:\n            self.assertIsInstance(language, str)\n\n\nif __name__ == '__main__':\n    unittest.main()"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/Complex303.py",
    "content": "\"\"\"\nPruebas Unitarias\n\"\"\"\n# Pruebas unitarias: Son pruebas que se aplican a funciones o métodos individuales de un programa para verificar que funcionan correctamente de manera aislada.\n\nimport unittest  # Librería estándar de Python para pruebas unitarias.\nfrom datetime import datetime, date # Importamos datetime y date para trabajar con fechas\n\n\ndef sumar(a, b):\n    # Verificamos que ambos argumentos sean números (int o float)\n    if not isinstance(a, (int, float)) or not isinstance(b, (int, float)):\n        raise ValueError(\"Los argumentos deben ser números\")\n    # Retornamos la suma de a y b\n    return a + b\n\n# Definimos una clase de prueba que hereda de unittest.TestCase\n# Esta clase contendrá nuestros métodos de prueba \n# nota:  En unittest, cualquier método dentro de una clase que herede de unittest.TestCase será reconocido como un test solo si su nombre comienza con test_. Si no usa ese prefijo, unittest lo ignorará y no lo ejecutará.\nclass TestSum(unittest.TestCase):\n\n        def test_sum(self):\n            # Comprobamos que sumar(5,4) devuelve 9\n            self.assertEqual(sumar(5, 4), 9)\n            # Otros casos de prueba con diferentes combinaciones\n            self.assertEqual(sumar(-2, 1), -1)\n            self.assertEqual(sumar(0, 0), 0)\n            self.assertEqual(sumar(-1, -1), -2)\n            self.assertEqual(sumar(1.5, 2.5), 4.0)\n            self.assertEqual(sumar(1, -1), 0)\n\n            \n        # Comprobamos que la función devuelve un error si los argumentos no son números\n        # En este caso, usamos assertRaises para verificar que se lanza una excepción ValueError\n        def test_sum_invalid(self):\n            # Verificamos que si se pasan valores inválidos, se lance ValueError\n            with self.assertRaises(ValueError):\n                sumar(\"5\", 3)\n            with self.assertRaises(ValueError):\n                sumar(5, \"3\")\n            with self.assertRaises(ValueError):\n                sumar(\"5\", \"3\")\n            with self.assertRaises(ValueError):\n                sumar(None, 3)\n            with self.assertRaises(ValueError):\n                sumar(5, None)\n            with self.assertRaises(ValueError):\n                sumar(None, None)\n            with self.assertRaises(ValueError):\n                sumar(\"a\", 3)\n            with self.assertRaises(ValueError): \n                sumar(5, \"b\")\n#Se usa assertEqual para comparar resultados y assertRaises para validar excepciones esperadas.\n\n#Esto permite que los tests solo se ejecuten cuando el script se corre directamente y no si se importa desde otro archivo.            \n# if __name__ == '__main__':\n#     unittest.main()\n\n\n\n\n\"\"\"* DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\"\"\"\n\n\n\n\n\n# Creamos una clase de prueba que hereda de unittest.TestCase\nclass TestData(unittest.TestCase):\n\n    # Este método se ejecuta antes de cada test, para preparar datos comunes\n    def setUp(self): \n        # Creamos un diccionario con datos ficticios de ejemplo\n        self.data = {\n            \"name\": \"Complex303\",  # Cadena\n            \"age\": 2,  # Entero\n            # Convertimos la cadena \"01-01-16\" a objeto date usando strptime y date()\n            \"birth_date\": datetime.strptime(\"01-01-16\", \"%d-%m-%y\").date(),\n            # Lista de lenguajes de programación\n            \"programming_languages\": [\"Python\", \"Java\", \"C#\"]\n        }\n        \n    # Primer test: verifica que las claves existan en el diccionario\n    def test_fields_exist(self):\n        self.assertIn(\"name\", self.data)  # Verifica que \"name\" exista en self.data\n        self.assertIn(\"age\", self.data)   # Verifica que \"age\" exista en self.data\n        self.assertIn(\"birth_date\", self.data)  # Verifica que \"birth_date\" exista\n        self.assertIn(\"programming_languages\", self.data)  # Verifica que \"programming_languages\" exista\n\n    # Segundo test: valida que cada valor tenga el tipo de dato correcto\n    def test_data_is_correct(self):\n        self.assertIsInstance(self.data[\"name\"], str)  # Que \"name\" sea cadena\n        self.assertIsInstance(self.data[\"age\"], int)  # Que \"age\" sea entero\n        self.assertIsInstance(self.data[\"birth_date\"], date)  # Que \"birth_date\" sea un objeto date\n        self.assertIsInstance(self.data[\"programming_languages\"], list)  # Que \"programming_languages\" sea lista\n\n\nunittest.main()\n\n\n# setUp(self): se ejecuta antes de cada test. Aquí inicializas los datos de prueba.\n\n# assertIn(clave, diccionario): verifica que la clave exista en el diccionario.\n\n# assertIsInstance(valor, tipo): verifica que el valor sea de un tipo específico.\n\n# unittest.main(): ejecuta todos los métodos que comienzan con test_."
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/DaniQB99.py",
    "content": "'''\nEJERCICIO:\nCrea una funcion que se encargue de sumar dos numeros y retornar su \nresultado.\n\nCrea un test, utilizando las herramientas de tu lenguaje, que sea \ncapaz de determinar si esa funcion se ejecuta correctamente.\n'''\n\nimport unittest\n\n\ndef sum(a, b):\n    \n    if not isinstance(a, (int, float)) or not isinstance(b, (int, float)):\n        raise ValueError(\"Los argumentos deben ser enteros o decimales.\")\n    return a + b\n\nclass TestSum(unittest.TestCase):\n    \n    \n    def test_sum(self):\n        \n        self.assertEqual(sum(1, 1), 2)\n        self.assertEqual(sum(2, 2), 4)\n        self.assertEqual(sum(3, 3), 6)\n        self.assertEqual(sum(2.5, 2.5), 5)\n        self.assertEqual(sum(2.5, 2.1), 4.6)\n        self.assertEqual(sum(-2, 2), 0)\n    \n    def test_sum_type(self):\n        \n        with self.assertRaises(ValueError):\n            sum(\"4\", 7)\n        with self.assertRaises(ValueError):\n            sum(\"4\", \"7\")\n        with self.assertRaises(ValueError):\n            sum(4, \"7\")\n        with self.assertRaises(ValueError): \n            sum(\"a\", 7)\n        with self.assertRaises(ValueError):\n            sum(None, 7)\n\n\n'''\nDIFICULTAD EXTRA (opcional):\nCrea un diccionario con las siguientes claves y valores:\n\"name\": \"Tu nombre\"\n\"age\": \"Tu edad\"\n\"birth_date\": \"Tu fecha de nacimiento\"\n\"programming_languages\": [\"Listado de lenguajes de\nprogramacion\"]\n\nCrea dos test:\n- Un primero que determine que existen todos los campos.\n- Un segundo que determine que los datos introducios son correctos.\n'''\n\nprint(\"\\nEJERCICIO EXTRA\\n\")\n\nfrom datetime import date, datetime\n\nclass TestData(unittest.TestCase):\n    \n    # Funcion para crear un diccionario con los datos\n    def setUp(self) -> None:\n        self.data = {\n            \"name\": \"Dani\",\n            \"age\": 25,\n            \"birth_date\": datetime.strptime(\"26-07-99\", \"%d-%m-%y\").date(),\n            \"programming_languages\": [\"Python\", \"Java\", \"HTML\", \"CSS\"]\n        }\n        \n    # Funcion para comprobar que los campos existen\n    def test_friends_exists(self):\n        \n        self.assertIn(\"name\", self.data)\n        self.assertIn(\"age\", self.data)\n        self.assertIn(\"birth_date\", self.data)\n        self.assertIn(\"programming_languages\", self.data)\n      \n    def test_data_is_correct(self):\n        self.assertIsInstance(self.data[\"name\"], str)\n        self.assertIsInstance(self.data[\"age\"], int)    \n        self.assertIsInstance(self.data[\"birth_date\"], date)    \n        self.assertIsInstance(self.data[\"programming_languages\"], list)\n        \nunittest.main()\n    "
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/Dkp-Dev.py",
    "content": "import unittest\n\n# No importe date ni datetime porque daba error \n\n\"\"\"\nEJERCICIO:\n * Crea una función que se encargue de sumar dos números y retornar\n * su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n * capaz de determinar si esa función se ejecuta correctamente.\n\"\"\"\n\n\ndef sum(a, b):\n    if not isinstance(a, (int, float)) or not isinstance(b, (int, float)):\n        raise ValueError(\"Los argumentos deben ser enteros o decimales.\")\n    return a + b\n\n\nclass TestSum(unittest.TestCase):\n\n    def test_sum(self):\n        self.assertEqual(sum(5, 7), 12)\n        self.assertEqual(sum(5, -7), -2)\n        self.assertEqual(sum(0, 0), 0)\n        self.assertEqual(sum(2.5, 2.1), 4.6)\n        self.assertEqual(sum(2, 2.1), 4.1)\n        self.assertEqual(sum(2.5, 2.5), 5)\n\n    def test_sum_type(self):\n        with self.assertRaises(ValueError):\n            sum(\"5\", 7)\n        with self.assertRaises(ValueError):\n            sum(5, \"7\")\n        with self.assertRaises(ValueError):\n            sum(\"5\", \"7\")\n        with self.assertRaises(ValueError):\n            sum(\"a\", 7)\n        with self.assertRaises(ValueError):\n            sum(None, 7)\n\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\n\"\"\"\n\n\nclass TestData(unittest.TestCase):\n\n    def setUp(self) -> None:\n        self.data = {\n            \"name\": \"Dkp-Dev\",\n            \"age\": 29,\n            \"birth_date\":\"11-01-1995\",\n            \"programming_languages\": [\"Python\", \"Java\"]\n        }\n\n    def test_fields_exist(self):\n        self.assertIn(\"name\", self.data)\n        self.assertIn(\"age\", self.data)\n        self.assertIn(\"birth_date\", self.data)      # Lo cambie a str porque me daba error unu\n        self.assertIn(\"programming_languages\", self.data)\n\n    def test_data_is_correct(self):\n        self.assertIsInstance(self.data[\"name\"], str)\n        self.assertIsInstance(self.data[\"age\"], int)\n        self.assertIsInstance(self.data[\"birth_date\"], str)\n        self.assertIsInstance(self.data[\"programming_languages\"], list)\n\n\nunittest.main()\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/EmmanuelMMontesinos.py",
    "content": "\"\"\"/*\n * EJERCICIO:\n * Crea una función que se encargue de sumar dos números y retornar\n * su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n * capaz de determinar si esa función se ejecuta correctamente.\n */\"\"\"\n\n# Ejercico Base\n\ndef suma(a,b):\n    return a + b\n\ndef test(funcion,resultado):\n    if resultado == funcion:\n        print(\"Suma: Correcto\")\n    else:\n        print(f\"Suma Error: {funcion} != {resultado}\")\n        \n# Prueba\ntest(suma(2,2),4)\ntest(suma(2,2),5)\n\n# Ejercicio Extra\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\n\"\"\"\n\ndiccionario = {\n    \"name\":\"Emmanuel\",\n    \"age\" : 33,\n    \"birth_date\" : \"17/05/999\",\n    \"programming_languages\" : [\"Python\",\"Bash\"]\n    }\n\ndef test_campos(dic:dict):\n    keys = list(dic.keys())\n    campos = [\"name\",\"age\",\"birth_date\",\"programming_languages\"]\n    if keys == campos:\n        print(\"Campos: Correcto\")\n        \n    else:\n        for n in range(len(campos)):\n            if keys[n] != campos[n]:\n                print(f\"Error Campos: {keys[n]} != {campos[n]}\")\n        \ndef test_datos(dic:dict):\n    values = list(dic.values())\n    campos = [\"Emmanuel\",33,\"17/05/999\",[\"Python\",\"Bash\"]]\n    if values == campos:\n        print(\"Datos: Correcto\")\n        \n    else:\n        for n in range(len(campos)):\n            if values[n] != campos[n]:\n                print(f\"Error Datos: {values[n]} != {campos[n]}\")\n    \n\n# Pruebas\ntest_campos(diccionario)\ntest_datos(diccionario)"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/FedeAirala.py",
    "content": "# #13 PRUEBAS UNITARIAS\n\n\n\"\"\"\n * EJERCICIO:\n * Crea una función que se encargue de sumar dos números y retornar\n * su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n * capaz de determinar si esa función se ejecuta correctamente.\n\"\"\"\n\nimport unittest \n\ndef sum(number1,number2):\n    if not isinstance(number1, (int)) or not isinstance(number2, (int)):\n        raise ValueError(\"Error en la entrada de datos\")\n    return number1 + number2\n\n\nclass TestSum(unittest.TestCase):\n    def test_sum(self):\n        self.assertEqual(sum(5,4),9)\n        self.assertEqual(sum(5,-2),3)\n        self.assertEqual(sum(5,7),12)\n        self.assertEqual(sum(1,2),3)\n    \n    def test_raises(self):\n        with self.assertRaises(ValueError):\n            sum(\"1\", 8)\n        with self.assertRaises(ValueError):\n            sum(2, \"b\")\n        with self.assertRaises(ValueError):\n            sum(\"a\", \"b\")\n       \n\n\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\n\n\"\"\"\nclass Person():\n    def __init__(self,name,age,birthday,languages) -> None:\n        self.name = name\n        self.age = age\n        self.birthday = birthday\n        self.languages = languages\n    \ndef dictionary(persona):\n\n    person = {\"name\":\"Fede\",\"age\":persona.age,\"birth_day\":persona.birthday,\"program_languages\":persona.languages}\n    return person\n    \nperson1 = Person(\"Fede\",43,\"25/6/80\",[])\n\ntest_person = dictionary(person1)\n\nprint (test_person)\n\n\nclass TestDictionaryPerson(unittest.TestCase):\n\n    def setUp(self) -> None:\n        self.data = test_person\n    \n\n    def test_empty(self):\n        self.assertIn(\"name\", test_person)\n        self.assertIn(\"age\", test_person)\n        self.assertIn(\"birth_day\", test_person)\n        self.assertIn(\"program_languages\", test_person)\n    \n    def test_data_is_correct(self):\n        self.assertIsInstance(self.data[\"name\"], str)\n        self.assertIsInstance(self.data[\"age\"], int)\n        self.assertIsInstance(self.data[\"birth_day\"],str)\n        self.assertIsInstance(self.data[\"program_languages\"], list)\n\n\nunittest.main(verbosity=3)\n\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/Gallitofast.py",
    "content": "import unittest\nfrom datetime import datetime, date\ndef sumar(num1, num2):\n    if not isinstance(num1, (int,float)) or not isinstance(num2, (int,float)):\n        raise ValueError(\"Error en la entrada de datos\")\n    return num1 + num2\n\nclass TestSumar(unittest.TestCase):\n    def test_suma_enteros_positivos(self):\n        self.assertEqual(sumar(1, 4), 5)\n        self.assertEqual(sumar(9, 4), 13)\n        self.assertEqual(sumar(7, 7), 14)\n        self.assertEqual(sumar(16, 3), 19)\n        self.assertEqual(sumar(1, 2), 3)\n        self.assertEqual(sumar(1, 1), 2)\n    \n    def test_suma_negativos(self):\n        self.assertEqual(sumar(-1, -2), -3)\n        self.assertEqual(sumar(-5, 5), 0)\n    \n    def test_suma_cero(self):\n        self.assertEqual(sumar(0, 0), 0)\n    \n    def test_raises_tipos_invalidos(self):\n        with self.assertRaises(ValueError):\n            sumar(\"1\", 8)  # Cadena\n        with self.assertRaises(ValueError):\n            sumar(2, \"x\")  # Cadena\n        with self.assertRaises(ValueError):\n            sumar(\"m\", \"t\")  # Cadena\n        with self.assertRaises(ValueError):\n            sumar(None, 2)  # None\n\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n* Crea un diccionario con las siguientes claves y valores:\n* \"name\": \"Tu nombre\"\n* \"age\": \"Tu edad\"\n* \"birth_date\": \"Tu fecha de nacimiento\"\n* \"programming_languages\": [\"Listado de lenguajes de programación\"]\n* Crea dos test:\n* - Un primero que determine que existen todos los campos.\n* - Un segundo que determine que los datos introducidos son correctos.\n\"\"\" \n\n\n\nclass Testdata(unittest.TestCase):\n    def setUp(self) -> None:\n        self.data = {\n            \"Name\":\"Jose\",\n            \"Age\":\"24\",\n            \"Birth_date\": datetime.strptime(\"02-04-02\", \"%d-%m-%y\").date(),\n            \"Programming_Languages\":[\"Python\",\"Typescript\"]\n        }\n    \n    def test_fields_exist(self):\n        self.assertIn(\"Name\",self.data)\n        self.assertIn(\"Age\",self.data)\n        self.assertIn(\"Birth_date\",self.data)\n        self.assertIn(\"Programming_Languages\",self.data)\n    \n    def test_iscorrect(self):\n        self.assertIsInstance(self.data[\"Name\"],str)\n        self.assertIsInstance(self.data[\"Age\"],int)\n        self.assertIsInstance(self.data[\"Birth_date\"],date)\n        self.assertIsInstance(self.data[\"Programming_Languages\"],list)\n\n\n\n\n\n\nunittest.main()\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/Gordo-Master.py",
    "content": "# 13 - PRUEBAS UNITARIAS\n\nimport unittest\nfrom datetime import datetime, date\n\ndef suma(a,b):\n    if isinstance(a,(int,float)) and isinstance(b,(int,float)):\n        return a+b\n    else:\n        raise(ValueError(\"Los valores deben ser enteros o flotantes!\"))\n\nclass TestSum(unittest.TestCase):\n\n    def test_result(self):\n        self.assertEqual(suma(4.5,3),7.5)\n        self.assertEqual(suma(5,3),8)\n\n    def test_sum_type(self):\n        with self.assertRaises(ValueError):\n            suma(\"5\",7)\n        with self.assertRaises(ValueError):\n            suma(5,\"7\")\n        with self.assertRaises(ValueError):\n            suma(\"5\",\"7\")\n        with self.assertRaises(ValueError):\n            suma(\"a\", 7)\n        with self.assertRaises(ValueError):\n            suma(None, 7)\n\n\n\n\"\"\"\nEjercicio Extra\n\"\"\"\n\n\nclass TestData(unittest.TestCase):\n\n    def setUp(self) -> None:\n        self.data = {\n            \"name\": \"Gordo-Master\",\n            \"age\" : 29,\n            \"birth_date\": datetime.strptime(\"08-05-1995\",\"%d-%m-%Y\").date(),\n            \"programming_languages\": [\"C++\",\"Python\"]\n        }\n    \n    def test_all_fill(self):\n        for value in self.data.values():\n            self.assertIsNotNone(value)\n    \n    def test_field_exists(self):\n        self.assertIn(\"name\", self.data)\n        self.assertIn(\"age\", self.data)\n        self.assertIn(\"birth_date\", self.data)\n        self.assertIn(\"programming_languages\", self.data)\n    \n    def test_data_is_correct(self):\n        self.assertIsInstance(self.data[\"name\"],str)\n        self.assertIsInstance(self.data[\"age\"],int)\n        self.assertIsInstance(self.data[\"birth_date\"], date)\n        self.assertIsInstance(self.data[\"programming_languages\"],list)\n\n\nif __name__ == '__main__':\n    unittest.main()"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/Hyromy.py",
    "content": "import unittest # libreria para test\n\ndef sumar(x, y):\n    number = (int, float)\n    if not isinstance(x, number) or not isinstance(y, number):\n        raise TypeError(\"Los parametros deben ser numeros\")\n\n    return x + y\n\n\"\"\" class Test(unittest.TestCase): # clase para pruebas\n    def test_sum_int(self): # caso de prueba\n        self.assertEqual(sumar(0, 0), 0) # prueba\n        self.assertEqual(sumar(5, 6), 11) # otra prueba\n        self.assertEqual(sumar(-7, 2), -5)\n        self.assertEqual(sumar(6, -2), 4)\n        self.assertEqual(sumar(-5, -7), -12)\n\n    def test_sum_float(self): # otro caso de prueba\n        self.assertEqual(sumar(4.3, 0.46), 4.76)\n        self.assertEqual(sumar(346.0, 4), 350.0)\n        self.assertEqual(sumar(43, 43.4), 86.4)\n\n    #pruebas negativas\n    def test_sum_negative(self):\n        with self.assertRaises(TypeError): # esperando que la prueba falle\n            sumar(\"7\", 5)\n        with self.assertRaises(TypeError):\n            sumar(7, \"5.7\")\n        with self.assertRaises(TypeError):\n            sumar(\"a\", \"5.7\")\n \"\"\"\n#unittest.main() # ejecutar las pruebas\n\n# ---- DIFICULTAD EXTRA ----\ndiccionario = {\n    \"name\": \"Hyromy\",\n    \"age\": 19,\n    \"birth_date\": \"04/12/2004\",\n    \"programming_languages\": [\n        \"JavaScript\",\n        \"Java\",\n        \"PHP\",\n        \"Python\"\n    ]\n}\n\ndef check_keys(data:dict):\n    keys = [\"name\", \"age\", \"birth_date\", \"programming_languages\"]\n    for i in data:\n        if i not in keys:\n            raise KeyError(f\"Clave {i} no existe\")\n    \ndef check_values(data:dict):\n    if not isinstance(data[\"name\"], str):\n        raise ValueError(\"Valor de clave 'name' no valida\")\n    \n    if not isinstance(data[\"age\"], int):\n        raise ValueError(\"Valor de clave 'age' no valida\")\n\n    date_data = data[\"birth_date\"].split(\"/\")\n    try:\n        for i in date_data:\n            i = int(i)\n            if not isinstance(i, int) or i < 0:\n                raise ValueError(\"Valor de clave 'birth_date' no valida\")\n    except:\n        raise ValueError(\"Valor de clave 'birth_date' no valida\")\n\n    for i in data[\"programming_languages\"]:\n        if not isinstance(i, str) or len(i) == 0:\n            raise ValueError(\"Valor de clave 'programming_languages' no valida\")\n\nclass Extra(unittest.TestCase):\n    def test_check_keys_positive(self):\n        self.assertEqual(check_keys(diccionario), None)\n\n    def test_check_values_positive(self):\n        self.assertEqual(check_values(diccionario), None)\n\n    def test_check_keys_negative(self):\n        with self.assertRaises(KeyError):\n            check_keys({\"hola\":\"xd\"})\n\n    def test_check_values_negative(self):\n        with self.assertRaises(ValueError):\n            data_test = diccionario.copy()\n            data_test[\"birth_date\"] = \"20/may/2343\"\n            check_values(data_test)\n\nunittest.main()"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/Irenetitor.py",
    "content": "from datetime import datetime, date\nimport unittest\n\n\n#Exercise\n\n\n\ndef add(a, b):\n    if not isinstance(a, (int, float)) or not isinstance(b, (int, float)):\n        raise TypeError(\"The arguments must be of type int or float.\")\n    return a + b\n\nclass TestAdd(unittest.TestCase):\n    def test_add(self):\n        self.assertEqual(add(2, 3), 5)\n        self.assertEqual(add(-1, -1), -2)\n        self.assertEqual(add(0, 0), 0)\n        self.assertEqual(add(-1, 9), 8)\n        self.assertEqual(add(2.6, 4.5), 7.1)\n        self.assertEqual(add(6.4, 2), 8.4)\n\n    def test_type_add(self):\n        with self.assertRaises(TypeError):\n            add(\"3\", 7)\n        with self.assertRaises(TypeError):\n            add(5, \"6\")\n        with self.assertRaises(TypeError):\n            add(\"9\", \"8\")\n\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n\n#Extra Exercise\n\n\n\nclass testUser_data(unittest.TestCase):\n    def setUp(self) -> None:\n        self.user_data = {\n            \"name\": \"Juan\",\n            \"age\": 29,\n            \"birth_date\": datetime.strptime(\"23-02-1996\", \"%d-%m-%y\").date(),\n            \"languages\": [\"Python\", \"JavaScript\", \"Java\"]\n        }\n\n    def test_exist_fields(self):\n        self.assertIn(\"name\", self.user_data)\n        self.assertIn(\"age\", self.user_data)\n        self.assertIn(\"birth_date\", self.user_data)\n        self.assertIn(\"languages\", self.user_data)\n\n    def test_user_gitdata_correct(self):\n        self.assertIsInstance(self.user_data[\"name\"], str)\n        self.assertIsInstance(self.user_data[\"age\"], int)\n        self.assertIsInstance(self.user_data[\"birth_date\"], date)\n        self.assertIsInstance(self.user_data[\"languages\"], list)\n\n\nif __name__ == \"__main__\":\n    unittest.main()"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/JAFeito.py",
    "content": "\"\"\"\n EJERCICIO:\n Crea una función que se encargue de sumar dos números y retornar\n su resultado.\n Crea un test, utilizando las herramientas de tu lenguaje, que sea\n capaz de determinar si esa función se ejecuta correctamente.\n\n DIFICULTAD EXTRA (opcional):\n Crea un diccionario con las siguientes claves y valores:\n \"name\": \"Tu nombre\"\n \"age\": \"Tu edad\"\n \"birth_date\": \"Tu fecha de nacimiento\"\n \"programming_languages\": [\"Listado de lenguajes de programación\"]\n Crea dos test:\n - Un primero que determine que existen todos los campos.\n - Un segundo que determine que los datos introducidos son correctos.\n\"\"\"\nimport unittest\n\ndef suma (num_1,num_2):\n    if not isinstance (num_1,(int,float)) or not isinstance(num_2,(int,float)):\n        raise ValueError(\"Los argumenteos deben ser enteros o decimales\")\n    \n    return num_1 + num_2\n\nclass Test_suma(unittest.TestCase):\n    def test_suma(self):\n        self.assertEqual(suma(5,7),12) \n        \n    def test_tipo_suma(self):\n        with self.assertRaises(ValueError):\n            suma(\"5\",7)\n        with self.assertRaises(ValueError):\n            suma(5,\"7\")\n#EXTRA\n        \ndiccionario = {\"Nombre\": \"Jose\",\"Edad\": 45, \"Fecha_nacimiento\": \"01/03/1979\", \"Lenguajes\": [\"Python\",\"Java\",\"C++\"]}\n\nclass Test_dic (unittest.TestCase):\n\n    def test_campo_vacio(self):\n        self.assertIn(\"Nombre\", diccionario) \n        self.assertIn(\"Edad\", diccionario) \n        self.assertIn(\"Fecha_nacimiento\", diccionario) \n        self.assertIn(\"Lenguajes\", diccionario) \n        \n    def test_datos_correctos(self):\n        self.assertIsInstance(diccionario[\"Nombre\"],str)\n        self.assertIsInstance(diccionario[\"Edad\"],int)\n        self.assertIsInstance(diccionario[\"Fecha_nacimiento\"],str)\n        self.assertIsInstance(diccionario[\"Lenguajes\"],list)\n\nunittest.main()\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/Jav-mol.py",
    "content": "# --- 13-Pruebas Unitarias ---\n# --- Javier Molina ---\n\n# --- Pruebas Unitarias ---\nimport unittest\ndef suma(a: int, b: int):\n    return a + b\n\nclass TestSuma(unittest.TestCase):\n    \n    def test_suma(self):\n        self.assertEqual(suma(3, 5), 8)\n        self.assertEqual(suma(1, 1), 2)\n        self.assertEqual(suma(0, 0), 0)\n        self.assertEqual(suma(-4, 2), -2)\n\n# --- Ejercicio Extra ---\n\ndata = {\n    \"name\": \"Javier\",\n    \"age\": 22,\n    \"birth_date\": \"2001-10-20\",\n    \"programming_languages\": [\"Python, JavaScript\"]\n    }\n\nclass TestDictionary(unittest.TestCase):\n\n    def test_dict_fields(self):\n        self.assertIn(\"name\", data)\n        self.assertIn(\"age\", data)\n        self.assertIn(\"birth_date\", data)\n        self.assertIn(\"programming_languages\", data)\n        \n    def test_dict_values(self):\n        self.assertEqual(data[\"name\"], \"Javier\")\n        self.assertEqual(data[\"age\"], 22)\n        self.assertEqual(data[\"birth_date\"], \"2001-10-20\")\n        self.assertEqual(data[\"programming_languages\"], [\"Python, JavaScript\"])\n        \n    \nif __name__ == '__main__':\n    unittest.main()"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/JesusWay69.py",
    "content": "import os, unittest\nos.system('cls')\n#os.system('clear')\nfrom datetime import date\n\"\"\"\n * EJERCICIO:\n * Crea una función que se encargue de sumar dos números y retornar\n * su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n * capaz de determinar si esa función se ejecuta correctamente.\n *\n\"\"\"\n\n\ndef sum_two_numbers(num1:int,num2:int)->int:\n    return num1+num2\nprint(sum_two_numbers(15,85))\n\nclass TestSum(unittest.TestCase):\n    def test_positive_sum(self):\n        self.assertEqual(sum_two_numbers(3, 9), 12) # Verifica si la suma de 3 y 5 es igual a 8\n\n    def test_negative_sum(self):\n        self.assertFalse(sum_two_numbers(-1, 1), 0) #En la mayoría de los casos se puede usar indistintamente asserEqual o assertTrue\n# pero en este caso concreto al ser cero el resultado propuesto para la operación dará fallo y habrá que testearlo con assertEqual o assertFalse\n\n    def test_float_sum(self):\n        self.assertTrue(sum_two_numbers(2.5,7.3),9.8)\n    \n    def test_type_int_return(self):\n        self.assertEqual(type(sum_two_numbers(0,0)), int)#Tambien se puede testear si el tipo de dato que devuelve es el correcto\n    \n    def test_type_float_return(self):\n        self.assertEqual(type(sum_two_numbers(0.0,0.0)), float)\n    \n\n# if __name__ == '__main__': \n#     unittest.main() #Con este condicional ejecutamos los test anteriores al mismo y termina la ejecución de todo el programa\n\n\"\"\" * DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\"\"\"\nprint(type(date(1974,12,26)))\n\nmy_personal_dict = {\n   \"name\": \"Jesus\",\n   \"age\": 49,\n   \"birth_date\": date(1974,12,26),\n   \"programming_languages\": [\"Python\", \"Java\", \"Javascript\"]\n}\n\ndef check_values(dict:dict):\n    my_list = []\n    [my_list.append(v) for v in dict.values()]\n    return my_list\n\n\nclass TestDict(unittest.TestCase):\n    def test_exist_items(self):\n        self.assertTrue(len(my_personal_dict),4)\n\n    def test_type_values(self):\n        self.assertEqual(type(check_values(my_personal_dict)), list)\n        self.assertEqual(type(check_values(my_personal_dict)[0]), str)\n        self.assertEqual(type(check_values(my_personal_dict)[1]), int)\n        self.assertEqual(type(check_values(my_personal_dict)[2]), date)\n        self.assertEqual(type(check_values(my_personal_dict)[3]), list)\n        self.assertEqual(type(check_values(my_personal_dict)[3][0]), str)\n        self.assertEqual(type(check_values(my_personal_dict)[3][1]), str)\n        self.assertEqual(type(check_values(my_personal_dict)[3][2]), str)\n         \n\nif __name__ == '__main__':\n    unittest.main()\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n# class TestEjemplos(unittest.TestCase):\n#     def setUp(self):\n#         print(\"Entra setUp\")\n#     def tearDown(self):\n#         print(\"Entra tearDown\")\n\n#     def test_1(self):\n#         print(\"Test: test_1\")\n#     def test_2(self):\n#         print(\"Test: test_2\")\n# if __name__ == '__main__':\n#     unittest.main()\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/JheisonQuiroga.py",
    "content": "import unittest\n\"\"\"\n * EJERCICIO:\n * Crea una función que se encargue de sumar dos números y retornar\n * su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n * capaz de determinar si esa función se ejecuta correctamente.\n\"\"\"\n\ndef add(n1, n2):\n    if not isinstance(n1, (int, float)) or not isinstance(n2, (int, float)):\n        raise TypeError(\"Args must be integer or float numbers\")\n    return n1 + n2\n\n\nclass TestAddMethod(unittest.TestCase):\n    def test_postivite(self):\n        self.assertEqual(add(10, 2), 12)\n        self.assertEqual(add(5, 3), 8)\n        self.assertEqual(add(5, -3), 2)\n\n    \n    def test_negative(self):\n        self.assertEqual(add(-2, -3), -5)\n        self.assertEqual(add(-5, 3), -2)\n\n    def test_str(self):\n        with self.assertRaises(TypeError):\n            add(\"5\", 2)\n        with self.assertRaises(TypeError):\n            add(5, \"2\")\n        with self.assertRaises(TypeError):\n            add(\"5\", \"2\")\n\n# if __name__ == \"__main__\":\n#     unittest.main()\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\n\"\"\"\n\ninfo = dict(name=\"duban\", age=25, birth_date=\"unknown\", \n            programming_languages=[\"Python\", \"Java\"])\n\n\nclass TestDictValues(unittest.TestCase):\n\n    def setUp(self):\n        \"\"\"\n        Setting before each proof.\n        Create the dictionary 'info' with the proof data\n        \"\"\"\n\n        self.info = dict(\n            name=\"duban\",\n            age=25,\n            birth_date=\"unknown\",\n            programming_languages=[\"Python\", \"Java\"]\n        )\n\n    def tearDown(self):\n        \"\"\"\n        Clean after each proof.\n        Reset the dictionary (optional in this case but util that we need release space)\n        \"\"\"\n        self.info = None\n    \n\n    def test_keys_required(self):\n        \"\"\"\n        Verify that dictionary info contain the required keys\n        \"\"\"\n        keys_required = {\"name\", \"age\", \"birth_date\", \"programming_languages\"}\n        self.assertTrue(keys_required.issubset(self.info.keys()))\n\n    def test_data_types(self):\n        \"\"\"\n        Verify that dictionary values are correct \n        \"\"\"\n        self.assertIsInstance(self.info[\"name\"], str, \"The name must be string\")\n        self.assertIsInstance(self.info[\"age\"], int, \"The age must be integer\")\n        self.assertIsInstance(self.info[\"birth_date\"], str, \"The birth date must be string\")\n        self.assertIsInstance(self.info[\"programming_languages\"], list, \"The programming languages must be list\")\n\n    def test_programming_languages_noempty(self):\n        \"\"\"\n        Verify that list is not empty\n        \"\"\"\n        self.assertGreater(len(self.info[\"programming_languages\"]), 0, \"The programming languages\" +\n                        \"list must contain values\")\n        \n    def test_programming_lang_content(self):\n        \"\"\"\n        Verify the content of programming languages list\n        \"\"\"\n        for language in self.info[\"programming_languages\"]:\n            self.assertIsInstance(language, str, f\"The language {language} is not string\")\n\n    def test_data_correct(self):\n        \"\"\"\n        Verify that each dictionary values are correct \n        \"\"\"\n        self.assertEqual(self.info[\"name\"], \"duban\", \"The name is not correct\")\n        self.assertEqual(self.info[\"age\"], 25, \"The age is not correct\")\n        self.assertEqual(self.info[\"birth_date\"], \"unknown\", \"The birth date is not correct\")\n        self.assertEqual(self.info[\"programming_languages\"], [\"Python\", \"Java\"], \n                        \"The programming languages are not correct\")\n\n\nif __name__ == \"__main__\":\n    unittest.main()"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/JuanDAW37.py",
    "content": "\"\"\"* EJERCICIO:\n * Crea una función que se encargue de sumar dos números y retornar\n * su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n * capaz de determinar si esa función se ejecuta correctamente.\n * DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\n\"\"\"\n#Librería para testing\nimport  unittest\nfrom datetime import datetime, date \n\n#Función a testear\ndef sumar(a , b):\n    if not isinstance(a, (int, float)) or not isinstance(b, (int, float)):\n        raise ValueError('Se recibe algo que no es entero o decimal')\n    return a + b \n\nclass TestSumar(unittest.TestCase): #Clase obligatoria para que se ejecuten los test\n    #Para crear una función de test, debemos crear una función en la que su nombre debe comenzar por test\n    def test_sumar(self):        \n        self.assertEqual(sumar(5, 5), 10) #Función assert para testing y pruebas        \n        self.assertEqual(sumar(4, 5), 9)\n        self.assertEqual(sumar(-5, -5), -10)\n        \n    def test_sumar_tipos(self):        \n        with self.assertRaises(ValueError): # Test para el tipado de los argumentos\n            sumar(\"2\", 5)\n        \n        with self.assertRaises(ValueError):\n            sumar(2, \"5\")\n        \n        with self.assertRaises(ValueError):\n            sumar(\"2\", \"5\")\n\n#EXTRA\n\nclass TestDatos(unittest.TestCase):\n    \n    def setUp(self): #Función perteneciente a la clase unittest que permite almacenar valores para usarlos posteriomente en los tests\n        self.datos = {\n            'name':'Juan Jesús Tenreiro Rodríguez',\n            'age': 56,\n            'birth_date':datetime.strptime(\"01-05-1968\", \"%d-%m-%Y\").date(),\n            'programming_languajes':['Python', 'Java', 'JavaScript', 'PHP', 'Cobol']\n        }  \n    \n    def test_existe_todos_los_campos(self):\n        self.assertIn('name', self.datos)\n        self.assertIn('age', self.datos)\n        self.assertIn('birth_date', self.datos)\n        self.assertIn('programming_languajes', self.datos)\n        \n    def test_datos_correctos(self):\n        self.assertIsInstance(self.datos['name'], str)\n        self.assertIsInstance(self.datos['age'], int)\n        self.assertIsInstance(self.datos['birth_date'], date)\n        self.assertIsInstance(self.datos['programming_languajes'], list)\n        \nunittest.main() #ejecuta todos los test_ "
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/KevinED11.py",
    "content": "from functools import lru_cache, partial, wraps\nfrom typing import TypeAlias, TypeVar, Protocol, NamedTuple, Iterable, Union\nimport pytest\n\n\nNumber: TypeAlias = Union[int, float]\n\n\nT = TypeVar(\"T\", bound=Number)\n\n\nclass OperationFn(Protocol):\n    def __call__(self, a: T, b: T) -> T:\n        ...\n\n\ndef validate_operation(fn: OperationFn) -> OperationFn:\n    @wraps(fn)\n    def wrapper(a: T, b: T) -> T:\n        if not isinstance(a, (int, float)) or not isinstance(b, (int, float)):\n            raise TypeError(\"a and b must be numbers\")\n\n        return fn(a, b)\n\n    return wrapper\n\n\n@validate_operation\ndef add(a: T, b: T) -> T:\n    return a + b\n\n\n@validate_operation\ndef multiply(a: T, b: T) -> T:\n    return a * b\n\n\ndef execute_operation(operation: OperationFn, a: T, b: T) -> T:\n    return operation(a, b)\n\n\nclass Case(NamedTuple):\n    a: Number\n    b: Number\n    expected: Number\n\n\ndef test_add_valid_cases() -> None:\n    cases = [\n        Case(1, 2, 3),\n        Case(1, 2.2, 3.2),\n        Case(1.1, 2, 3.1),\n        Case(1, 2, 3),\n        Case(4, 6, 10),\n        Case(-2, -3, -5),\n    ]\n\n    for case in cases:\n        result = add(case.a, case.b)\n        assert result == case.expected, f\"{case} failed\"\n        assert isinstance(result, (int, float)), f\"{case} failed\"\n        print(f\"{case} passed\")\n\n\ndef test_add_invalid_cases() -> None:\n    cases = [Case(\"a\", 2, 3), Case(1, \"b\", 4), Case(3, 5, 9)]\n\n    for case in cases:\n        a_is_int_or_float = isinstance(case.a, (int, float))\n        b_is_int_or_float = isinstance(case.b, (int, float))\n\n        if not a_is_int_or_float or not b_is_int_or_float:\n            with pytest.raises(TypeError):\n                add(case.a, case.b)\n\n        if a_is_int_or_float and b_is_int_or_float:\n            result = add(case.a, case.b)\n            assert result != case.expected\n\n\ndef create_programmer(\n    name: str, age: int, birth_date: str, programming_languages: Iterable[str]\n) -> dict:\n    return dict(\n        name=name,\n        age=age,\n        birth_date=birth_date,\n        programming_languages=programming_languages,\n    )\n\n\nkevin_programmer = partial(\n    create_programmer,\n    name=\"kevin\",\n    age=23,\n    birth_date=\"01/01/2000\",\n    programming_languages=[\"python\", \"go\", \"javascript\", \"typescript\"],\n)\n\n\n@lru_cache(maxsize=None)\ndef object_fields():\n    return [\"name\", \"age\", \"birth_date\", \"programming_languages\"]\n\n\ndef test_field_exist() -> None:\n    kevin = kevin_programmer()\n    for field in object_fields():\n        assert field in kevin, f\"{field} does not exist\"\n\n\ndef test_field_type() -> None:\n    kevin = kevin_programmer()\n    for field in object_fields():\n        assert isinstance(\n            kevin[field], (str, int, list)\n        ), f\"{field} is not a valid type\"\n\n\ndef main() -> None:\n    ...\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/LucasRebuffo.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Crea una función que se encargue de sumar dos números y retornar\n * su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n * capaz de determinar si esa función se ejecuta correctamente.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\n */ \"\"\"\n\nimport unittest\n\n\ndef es_multiplo(num: int, multilpo_de: int):\n    return num % multilpo_de == 0\n\n\nclass Test(unittest.TestCase):\n\n    def test_es_multiplo(self):\n        self.assertTrue(es_multiplo(4, 2))\n        self.assertFalse(es_multiplo(5, 2))\n\n    def test_zero_error(self):\n\n        with self.assertRaises(ZeroDivisionError):\n            es_multiplo(0, 0)\n            es_multiplo(5, 0)\n\n\nfrom datetime import date, datetime\n\n\"\"\" \n* DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\n */ \"\"\"\n\n\nclass TestInfo(unittest.TestCase):\n    def setUp(self):\n        self.info = {\n            \"name\": \"Lucas\",\n            \"age\": 27,\n            \"birth_date\": datetime.strptime(\"10-02-97\", \"%d-%m-%y\"),\n            \"programming_languages\": [\"python\", \"java\", \"javascript\"],\n        }\n\n    def test_fields_exists(self):\n\n        self.assertIn(\"name\", self.info)\n        self.assertIn(\"age\", self.info)\n        self.assertIn(\"birth_date\", self.info)\n        self.assertIn(\"programming_languages\", self.info)\n\n    def test_correct_fields(self):\n        self.assertIsInstance(self.info[\"name\"],str)\n        self.assertIsInstance(self.info[\"age\"],int)\n        self.assertIsInstance(self.info[\"birth_date\"],date)\n        self.assertIsInstance(self.info[\"programming_languages\"],list)\n\n\nunittest.main()\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/Lumanet.py",
    "content": "import unittest \n\ndef suma(a, b):\n  return a + b\n\nclass TestSuma(unittest.TestCase): # Heredamos de unittest.TestCase para poder hacer las pruebas\n  def test_suma(self): # Creamos un método que empiece por test para que sea detectado\n    self.assertEqual(suma(5, 7), 12) # Comprobamos que 5 + 7 = 12\n    self.assertEqual(suma(5, -7), -2)\n    self.assertEqual(suma(0, 0), 0)\n    self.assertEqual(suma(3.5, 2.1), 5.6)\n    self.assertEqual(suma(2, 2.1), 4.1)\n    self.assertEqual(suma(2.5, 2.5), 5)\n    \n# if __name__ == '__main__':\n#     unittest.main()\n    \n\"\"\"\nDIFICULTAD EXTRA (opcional):\nCrea un diccionario con las siguientes claves y valores:\n\"name\": \"Tu nombre\"\n\"age\": \"Tu edad\"\n\"birth_date\": \"Tu fecha de nacimiento\"\n\"programming_languages\": [\"Listado de lenguajes de programación\"]\nCrea dos test:\n- Un primero que determine que existen todos los campos.\n- Un segundo que determine que los datos introducidos son correctos.\n\"\"\"\nimport unittest\n\nusuario = {\n    \"name\": \"Marcos\",\n    \"age\": 42,\n    \"birth_date\": \"02-20-1982\",\n    \"programming_languages\": [\"Python\", \"PHP\", \"CSS\", \"JavaScript\"]\n}    \n\nclass Tests(unittest.TestCase):\n    def test_campos(self):\n        self.assertEqual(True if usuario[\"name\"] else False, True) # Si el campo name existe, devolverá True\n        self.assertEqual(True if usuario[\"age\"] else False, True)\n        self.assertEqual(True if usuario[\"birth_date\"] else False, True)\n        self.assertEqual(True if usuario[\"programming_languages\"] else False, True)\n        \n    def test_tipo(self):\n        self.assertEqual(type(usuario[\"name\"]), str) # Comprobamos que el tipo de dato es el correcto\n        self.assertEqual(type(usuario[\"age\"]), int)\n        self.assertEqual(type(usuario[\"birth_date\"]), str)\n        self.assertEqual(type(usuario[\"programming_languages\"]), list)\n\nif __name__ == '__main__': # Si ejecutamos el script directamente, se ejecutarán las pruebas\n    unittest.main() # Ejecutamos las pruebas\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/Nicojsuarez2.py",
    "content": "# #13 PRUEBAS UNITARIAS\n> #### Dificultad: Fácil | Publicación: 25/03/24 | Corrección: 01/04/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Crea una función que se encargue de sumar dos números y retornar\n * su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n * capaz de determinar si esa función se ejecuta correctamente.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/Nightblockchain30.py",
    "content": "import unittest\nfrom datetime import datetime,date\n\n# EJERCICIO:\n# Crea una función que se encargue de sumar dos números y retornar\n# su resultado.\n# Crea un test, utilizando las herramientas de tu lenguaje, que sea\n# capaz de determinar si esa función se ejecuta correctamente.\n\ndef sumar(a , b):\n    if not isinstance(a,(int,float)) or not isinstance(b,(int,float)):\n        raise ValueError(\"Los argumentos deben de ser INT or FLOAT\")\n    return a + b\n\nclass TestClass(unittest.TestCase):\n    # Batería de testing\n    def test_sumar(self):\n        self.assertEqual(sumar(1,2),3)\n        self.assertEqual(sumar(2.2,2.2),4.4)\n        self.assertEqual(sumar(2,2.2),4.2)\n        self.assertEqual(sumar(-10,10),0)\n    \n    def test_type_sum(self):\n        with self.assertRaises(TypeError):\n            sum(\"5\",5)\n        with self.assertRaises(TypeError):\n            sum(3,\"5\")\n        with self.assertRaises(TypeError):\n            sum(2,\"f\")\n        with self.assertRaises(TypeError):\n            sum(\"f\",4)\n        with self.assertRaises(TypeError):\n            sum(\"f\",\"f\")\n        \n\n\n\n\n\n# DIFICULTAD EXTRA (opcional):\n# Crea un diccionario con las siguientes claves y valores:\n# \"name\": \"Tu nombre\"\n# \"age\": \"Tu edad\"\n# \"birth_date\": \"Tu fecha de nacimiento\"\n# \"programming_languages\": [\"Listado de lenguajes de programación\"]\n# Crea dos test:\n# - Un primero que determine que existen todos los campos.\n# - Un segundo que determine que los datos introducidos son correctos.\n\ndatos = {\n    \"Nombre\": \"Alonso\",\n    \"Edad\": 26,\n    \"fecha_cumpleaños\": datetime.strptime(\"10-05-97\",\"%d-%m-%y\").date(),\n    \"Listado_de_lenguajes\": [\"Python\", \"JavaScript\", \"CSS\"]\n}\n\n\nclass TestDatos(unittest.TestCase):\n    \n    def setUp(self):\n        self.datos = {\n                \"Nombre\": \"Alonso\",\n                \"Edad\": 26,\n                \"fecha_cumpleaños\": datetime.strptime(\"10-05-97\",\"%d-%m-%y\").date(),\n                \"Listado_de_lenguajes\": [\"Python\", \"JavaScript\", \"CSS\"]\n            }\n    \n    def test_fields_exists(self):\n        self.assertIn(\"Nombre\", self.datos)\n        self.assertIn(\"Edad\", self.datos)\n        self.assertIn(\"fecha_cumpleaños\", self.datos)\n        self.assertIn(\"Listado_de_lenguajes\", self.datos)\n\n    def test_typedata_iscorrect(self):\n        self.assertIsInstance(self.datos[\"Nombre\"],str)\n        self.assertIsInstance(self.datos[\"Edad\"],int)\n        self.assertIsInstance(self.datos[\"fecha_cumpleaños\"],date)\n        self.assertIsInstance(self.datos[\"Listado_de_lenguajes\"],list)\n\n\nunittest.main()"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/Paula2409.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Crea una función que se encargue de sumar dos números y retornar\n * su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n * capaz de determinar si esa función se ejecuta correctamente.\n */\n\"\"\"\nimport unittest\n\ndef sum_numbers(a,b):\n    if type(a) != int or type(b) != int:\n        raise ValueError('Los numeros deben ser enteros')    \n    return a + b\n\n# Utilizando assert para verificar expectativas\ndef test_sum_numbers():\n    assert sum_numbers(5,6) == 11, \"El valor no es correcto\"\n\n# Utilizando clase con Unittest\nclass TestSumNumbers(unittest.TestCase):\n    def test_sum_numbers(self):\n        self.assertEqual(sum_numbers(5,8),13, \"No es correcto\")\n        self.assertEqual(sum_numbers(5,2),7, \"No es correcto\")\n        self.assertEqual(sum_numbers(5,9),13, \"No es correcto\")\n        self.assertEqual(sum_numbers(1,8),10, \"No es correcto\")\n        self.assertEqual(sum_numbers(2,79),0, \"No es correcto\")\n        \n    def test_sum_numbers_instance(self):\n        self.assertIsInstance(5, int)\n    \n    def test_sum_numbers_type(self):\n        with self.assertRaises(ValueError):\n            sum_numbers('4',8)\n        with self.assertRaises(ValueError):\n            sum_numbers(2,'6')\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\n\"\"\"\nmy_dict = {\n    'name': 'Paula',\n    'age': 36,\n    'birth_date': '24/09/1987',\n    'programming_languages': ['Python', 'Javascript']\n    }\n\nclass TestData(unittest.TestCase):\n    \n    def test_exists(self):\n        self.assertIn('name',my_dict)\n        self.assertIn('age',my_dict)\n        self.assertIn('birth_date',my_dict)\n        self.assertIn('programming_languages',my_dict)\n        \n    def test_is_correct(self):\n        self.assertEqual(my_dict['name'],'Paula')\n        self.assertEqual(my_dict['age'],'36')\n        self.assertEqual(my_dict['birth_date'],'24/09/1987')\n        self.assertEqual(my_dict['programming_languages'],\"['Python', 'Javascript']\")\n        \nunittest.main()\n\n        "
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/RicardiJulio.py",
    "content": "#  * EJERCICIO:\n#  * Crea una función que se encargue de sumar dos números y retornar\n#  * su resultado.\n#  * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n#  * capaz de determinar si esa función se ejecuta correctamente.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea un diccionario con las siguientes claves y valores:\n#  * \"name\": \"Tu nombre\"\n#  * \"age\": \"Tu edad\"\n#  * \"birth_date\": \"Tu fecha de nacimiento\"\n#  * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n#  * Crea dos test:\n#  * - Un primero que determine que existen todos los campos.\n#  * - Un segundo que determine que los datos introducidos son correctos.\n\n# Creacion de la funcion que suma \ndef sumar(a,b):\n    return a+b\n\nprint(sumar(20,50))\n\nimport unittest\n\n# Clase que corre los test para sumar\nclass TestSumar(unittest.TestCase):\n    def test_suma_correcta(self):\n        self.assertEqual(sumar(3,2),5) # Introduccion de la funcion sumar y el resultado esperado\n        self.assertEqual(sumar(-1,1),0)\n        self.assertEqual(sumar(0,0),0)\n\n\n# DIFICULTAD EXTRA:\n\nmi_dicc = {'name':'Julio',\n           'age':'23',\n           'birth_date':'04/02/2002',\n           'programming_languajes':'Python'}\n\nclass Testdicc(unittest.TestCase):\n    def test_todos_existen(self): # ---> Recordatorio importante: Todas las funciones deben llevar\n        self.assertNotEqual(mi_dicc['name'],'') # \"test_\" en el nombre para que se ejecuten\n        self.assertNotEqual(mi_dicc['age'],'')\n        self.assertNotEqual(mi_dicc['birth_date'],'')\n        self.assertNotEqual(mi_dicc['programming_languajes'],'')\n    \n    def test_todos_correctos(self):\n        self.assertEqual(mi_dicc['name'],'Julio')\n        self.assertEqual(mi_dicc['age'],'23')\n        self.assertEqual(mi_dicc['birth_date'],'04/02/2002')\n        self.assertEqual(mi_dicc['programming_languajes'],'Python')\n        \nif __name__ ==\"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/Sac-Corts.py",
    "content": "### Ejercicio ###\nimport unittest\n\ndef sumar(a, b):\n    return a + b\n\nclass TestSumar(unittest.TestCase):\n    \n    def test_sumar(self):\n        self.assertEqual(sumar(2, 3), 5)\n\n#unittest.main()\n\n### Ejercicio Extra ###\n\ndata = {\n    \"name\" : \"Isaac Cortés\",\n    \"age\" : 22,\n    \"birth_date\" : 21/10/2001,\n    \"programming_languages\" : [\"Python\", \"JavaScript\", \"Java\"]\n}\n\nclass TestData(unittest.TestCase):\n\n    def test_field(self):\n        self.assertIn(\"name\", data)\n        self.assertIn(\"age\", data)\n        self.assertIn(\"birth_date\", data)\n        self.assertIn(\"programming_languages\", data)\n\n    def test_correct_data(self):\n        self.assertEqual(data[\"name\"], \"Isaac Cortés\")\n        self.assertEqual(data[\"age\"], 22)\n        self.assertEqual(data[\"birth_date\"], 21/10/2001)\n        self.assertListEqual(data[\"programming_languages\"], [\"Python\", \"JavaScript\", \"Java\"])\n\nunittest.main()\n\n\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/SaezMD.py",
    "content": "#13 - Pruebas unitarias\n\"\"\"\n * EJERCICIO:\n * Crea una función que se encargue de sumar dos números y retornar su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea capaz de determinar si esa función se ejecuta correctamente.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\n */\n\"\"\"\n\ndef sum_numbers(num1:float, num2:float)-> float:\n    if not isinstance(num1,(int, float)) or not isinstance(num2,(int, float)):\n        raise ValueError(\"The arguments have to be integers or floats\")\n\n    total = num1 + num2\n    return total\n\nprint(sum_numbers(1,2))\n\nassert sum_numbers(7,0) == 7, f\"sum is correct\"\nassert sum_numbers(7,13) == 20, f\"sum is correct\"\n#assert sum_numbers(7,33) == 7, f\"sum is NOT correct, the correct is: 40\"\n\nimport unittest\n\nclass TestSum(unittest.TestCase):\n\n    def test_sum(self):\n        self.assertEqual(sum_numbers(5,7),12)\n        self.assertEqual(sum_numbers(10,7),17)\n        self.assertEqual(sum_numbers(10,-17),-7)\n        self.assertEqual(sum_numbers(0,0),0)\n        self.assertEqual(sum_numbers(2,2.1),4.1)\n        #self.assertEqual(sum_numbers(\"4\",0),4)\n\n    def test_sum_type(self):\n        with self.assertRaises(ValueError):\n            sum_numbers(\"5\", 7)\n        with self.assertRaises(ValueError):\n            sum_numbers(5, \"7\")\n        with self.assertRaises(ValueError):\n            sum_numbers(\"5\", \"7\")     \n\n\n\n#EXTRA\nfrom datetime import datetime, date\n\ndictPersonal = {\"name\": \"Saul Saez\",\n                \"age\": 12,            \n                \"birth_date\": \"20/12/2013\",\n                \"programming_languages\": [\"Python\", \"Golang\", \"VBA\", \"JavaScript\"]              \n                 }\n\ncountKeys = 0 \n\nfor key, value in dictPersonal.items():\n    assert value != \"\", f\"The key: {key} is empty.\"\n    countKeys += 1\n\nassert countKeys == 4, \"Keys should be 4.\"\nassert len(dictPersonal) == 4, \"Keys should be 4.\"\n\nassert type(dictPersonal[\"name\"]) == str, f\"Name should be a: str\"\nassert type(dictPersonal[\"age\"]) == int, f\"Age should be an: int\"\nassert type(dictPersonal[\"birth_date\"]) == str, f\"Birth_date should be a: str\"\nassert type(dictPersonal[\"programming_languages\"]) == list, f\"Programming_languages should be a: list\"\n\n\nclass TestData(unittest.TestCase):\n\n    def setUp(self) -> None:\n        self.data = {\n                \"name\": \"Saul Saez\",\n                \"age\": 12,            \n                \"birth_date\": datetime.strptime(\"20/12/2013\", \"%d/%m/%Y\").date(),\n                \"programming_languages\": [\"Python\", \"Golang\", \"VBA\", \"JavaScript\"]              \n            }\n\n    def test_fields_exist(self):\n        self.assertIn(\"name\", self.data)\n        self.assertIn(\"age\", self.data)\n        self.assertIn(\"birth_date\", self.data)\n        self.assertIn(\"programming_languages\", self.data)\n\n    def test_is_correct_data(self):\n        self.assertIsInstance(self.data[\"name\"], str)\n        self.assertIsInstance(self.data[\"age\"], int)\n        self.assertIsInstance(self.data[\"birth_date\"], date)\n        self.assertIsInstance(self.data[\"programming_languages\"], list)\n        \n\nunittest.main()\n\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/SergioGI99.py",
    "content": "\"\"\"\nEJERCICIO:\nCrea una función que se encargue de sumar dos números y retornar\nsu resultado.\nCrea un test, utilizando las herramientas de tu lenguaje, que sea\ncapaz de determinar si esa función se ejecuta correctamente.\n\nDIFICULTAD EXTRA (opcional):\nCrea un diccionario con las siguientes claves y valores:\n\"name\": \"Tu nombre\"\n\"age\": \"Tu edad\"\n\"birth_date\": \"Tu fecha de nacimiento\"\n\"programming_languages\": [\"Listado de lenguajes de programación\"]\nCrea dos test:\n- Un primero que determine que existen todos los campos.\n- Un segundo que determine que los datos introducidos son correctos.\n\"\"\"\nimport unittest\n\n#EJERCICIO\n\ndef sum(x, y):\n    z = x + y\n    return z\n\nresult = sum(1, 2)\n\nprint(result)\n\nclass TestSum(unittest.TestCase):\n    def test_sum(self):\n        self.assertEqual(sum(1, 2), 3)\n\n#EXTRA\nmyDict = {\n    \"name\": \"Sergio\",\n    \"age\": 24,\n    \"birth_date\": \"24-05-1999\",\n    \"programming_languages\": [\"Python, JavaScript\"]\n}\n\nmyDictKeys = [\"name\", \"age\", \"birth_date\", \"programming_languages\"]\nclass test_dict(unittest.TestCase):\n    def test_dict_inputs(self):\n        for info in myDictKeys:\n            self.assertIn(info, myDict)\n\n    def test_dict_values(self):\n        self.assertIsInstance(myDict[\"name\"], str)\n        self.assertIsInstance(myDict[\"age\"], int)\n        self.assertIsInstance(myDict[\"birth_date\"], str)\n        self.assertIsInstance(myDict[\"programming_languages\"], list)\n\nif __name__ == \"main\":\n    unittest.main()"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/SooHav.py",
    "content": "# 13 - PRUEBAS UNITARIAS\nimport unittest\nfrom datetime import datetime as dt\n# SooHav.py\n# python -m unittest -v tests\n\n# Ejercicio\n\n\ndef suma(a: float, b: float) -> float:\n    return a + b\n\n\nresultado1 = suma(3, 4)\nresultado2 = suma(3.5, 4.5)\nresultado3 = suma(3, 4.5)\n\nprint(resultado1)\nprint(resultado2)\nprint(resultado3)\n\n# Forma simple de testear\nassert (suma(3, 4) == 7.0)\nassert (suma(3.5, 4.5) == 8.0)\nassert (suma(3, 4.5) == 7.5)\n\n\nclass TestSuma(unittest.TestCase):\n\n    def test_suma_enteros(self):\n        # Verifica que la suma de 1 y 2 sea igual a 3\n        self.assertEqual(suma(1, 2), 3.0)\n        # Verifica que la suma de -1 y 1 sea igual a 0\n        self.assertEqual(suma(-1, 1), 0.0)\n        # Verifica que la suma de 0 y 0 sea igual a 0\n        self.assertEqual(suma(0, 0), 0.0)\n\n    def test_suma_decimales(self):\n        # Verifica que la suma de 1.5 y 2.5 sea igual a 4.0\n        self.assertAlmostEqual(suma(1.5, 2.5), 4.0)\n        self.assertAlmostEqual(suma(-1.5, 1.5), 0.0)\n\n\n# Difiicultad Extra\ndef crear_diccionario(nombre, edad, fecha_nacimiento, lenguajes):\n    info = {\n        \"nombre\": nombre,\n        \"edad\": edad,\n        \"fecha_nacimiento\": fecha_nacimiento,\n        \"lenguajes\": lenguajes\n    }\n    return info\n\n\ninfo = crear_diccionario(\"Sofia\", 46, \"26-02-1978\", [\"Python\", \"R\"])\nprint(info)\n\n\nclass TestCrearDiccionario(unittest.TestCase):\n\n    def test_crear_diccionario(self):\n        nombre = \"Sofia\"\n        edad = 46\n        fecha_nacimiento = \"26-02-1978\"\n        lenguajes = [\"Python\", \"R\"]\n        info = crear_diccionario(nombre, edad, fecha_nacimiento, lenguajes)\n        # Verifica que el resultado es un diccionario\n        self.assertIsInstance(info, dict)\n\n    def test_existencia_campos(self):\n        nombre = \"Sofia\"\n        edad = 46\n        fecha_nacimiento = \"26-02-1978\"\n        lenguajes = [\"Python\", \"R\"]\n        info = crear_diccionario(nombre, edad, fecha_nacimiento, lenguajes)\n        # Verifica que 'nombre' está presente en el diccionario\n        self.assertIn(\"nombre\", info)\n        self.assertIn(\"edad\", info)\n        self.assertIn(\"fecha_nacimiento\", info)\n        self.assertIn(\"lenguajes\", info)\n\n    def test_datos_correctos(self):\n        nombre = \"Sofia\"\n        edad = 46\n        fecha_nacimiento = \"26-02-1978\"\n        lenguajes = [\"Python\", \"R\"]\n        info = crear_diccionario(nombre, edad, fecha_nacimiento, lenguajes)\n        self.assertIsInstance(info[\"nombre\"], str)\n        self.assertIsInstance(info[\"edad\"], int)\n        self.assertIsInstance(dt.strptime(\n            info[\"fecha_nacimiento\"], \"%d-%m-%Y\"), dt)\n        self.assertIsInstance(info[\"lenguajes\"], list)\n\n\n# Ejecucion de pruebas\nif __name__ == '__main__':\n    unittest.main(argv=[''], verbosity=2, exit=False)\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/adolfolozaa.py",
    "content": "'''\r\nEJERCICIO:\r\n * Crea una función que se encargue de sumar dos números y retornar\r\n * su resultado.\r\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\r\n * capaz de determinar si esa función se ejecuta correctamente.\r\n'''\r\nimport unittest\r\n\r\ndef sum(a, b):\r\n    if not isinstance(a, (int, float)) or not isinstance(b, (int, float)):\r\n        raise ValueError(\"Los argumentos deben ser enteros o decimales.\")\r\n    return a + b\r\n\r\n\r\nclass TestSum(unittest.TestCase):\r\n\r\n    def test_sum(self):\r\n        self.assertEqual(sum(5, 7), 12)\r\n        self.assertEqual(sum(5, -7), -2)\r\n        self.assertEqual(sum(0, 0), 0)\r\n        self.assertEqual(sum(2.5, 2.1), 4.6)\r\n        self.assertEqual(sum(2, 2.1), 4.1)\r\n        self.assertEqual(sum(2.5, 2.5), 5)\r\n\r\n    def test_sum_type(self):\r\n        with self.assertRaises(ValueError):\r\n            sum(\"5\", 7)\r\n        with self.assertRaises(ValueError):\r\n            sum(5, \"7\")\r\n        with self.assertRaises(ValueError):\r\n            sum(\"5\", \"7\")\r\n        with self.assertRaises(ValueError):\r\n            sum(\"a\", 7)\r\n        with self.assertRaises(ValueError):\r\n            sum(None, 7)\r\n#unittest.main()\r\n\r\n\r\n'''\r\n * DIFICULTAD EXTRA (opcional):\r\n * Crea un diccionario con las siguientes claves y valores:\r\n * \"name\": \"Tu nombre\"\r\n * \"age\": \"Tu edad\"\r\n * \"birth_date\": \"Tu fecha de nacimiento\"\r\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\r\n * Crea dos test:\r\n * - Un primero que determine que existen todos los campos.\r\n * - Un segundo que determine que los datos introducidos son correctos.'''\r\n\r\nfrom datetime import datetime, date\r\n\r\n\r\nclass TestData(unittest.TestCase):\r\n\r\n    def setUp(self) -> None:\r\n        self.data = {\r\n            'name': 'Adolfo',\r\n            'age': 56,\r\n            \"birth_date\": datetime.strptime(\"29-04-87\", \"%d-%m-%y\").date(),\r\n            'programing_languages': ['Python', 'Basic', 'C']\r\n        }\r\n\r\n    def test_fields_exist(self):\r\n        self.assertIn(\"name\", self.data)\r\n        self.assertIn(\"age\", self.data)\r\n        self.assertIn(\"birth_date\", self.data)\r\n        self.assertIn(\"programing_languages\", self.data)\r\n\r\n    def test_data_is_correct(self):\r\n        self.assertIsInstance(self.data[\"name\"], str)\r\n        self.assertIsInstance(self.data[\"age\"], int)\r\n        self.assertIsInstance(self.data[\"birth_date\"], date)\r\n        self.assertIsInstance(self.data[\"programing_languages\"], list)\r\n\r\n\r\nunittest.main()\r\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/adra-dev.py",
    "content": "\"\"\"\nEJERCICIO:\nCrea una funcion que se encargue de sumar dos numeros y retornar su \nresultado.\n\nCrea un test, utilizando las herramientas de tu lenguaje, que sea \ncapaz de determinar si esa funcion se ejecuta correctamente.\n\nDIFICULTAD EXTRA (opcional):\nCrea un diccionario con las siguientes claves y valores:\n\"name\": \"Tu nombre\"\n\"age\": \"Tu edad\"\n\"birth_date\": \"Tu fecha de nacimiento\"\n\"programming_languages\": [\"Listado de lenguajes de\nprogramacion\"]\n\nCrea dos test:\n- Un primero que determine que existen todos los campos.\n- Un segundo que determine que los datos introducios son correctos.\n\nby adra-dev\n\"\"\"\n\n\"\"\"\nEjercicio\n\"\"\"\n\n\"\"\"\nTest unitarios:\n\nEn programacion, las pruebas o test unitarios son una forma de \ncomprobar el correcto funcionamiento de una unidad de codigo. Son \npruebas que debe superar el codigo para verificar su correcto \nfuncionamiento.\n\nLa instruccion assert permite llevar a cabo estas pruebas. Si el \nresultado de la condicion booleana es True, el resultado del test es\npositivo, mientras que si es False, se generara un a excepcion \nAssertionError indicando cual es la prueba que ha fallado\n\n\"\"\"\n\ndef sum(a, b):\n    if not isinstance(a, (int, float)) or not isinstance(b, (int, float)):\n        raise ValueError(\"Los argumentos deben ser enteros o decimales.\")\n    return a + b\n\nresultado = sum(3, 4)\nassert resultado == 7\n\nresultado = sum(3, -4)\nassert resultado == -1\n\n# resultado = sum(-3,+4)\n# assert resultado == 0\n\n\n\"\"\"\nTest unitarios con unittest:\nEl uso de assert para comprobar nuestro codigo no suele ser muy \nefficiente, pues el programa parara en cuanto una de las condiciones\nno se satisfaga. Esto obliga a ir corrigiendo cada problema antes de \ncontinuar con el resto de comprobaciones. Existen soluciones mas \nsofisticadas para la elaboracion de pruebas de unidad. La biblioteca \nunittest ofrece utilidades para la construccion de pruebas de unidad\ncomo la automatizacion, desactivacion y configuracion de test, entre \notras funcionalidades.\n\"\"\"\nimport unittest\n\nclass TestSum(unittest.TestCase):\n\n    def test_sum(self):\n        self.assertEqual(sum(5, 7), 12)\n        self.assertEqual(sum(5, -7), -2)\n        self.assertEqual(sum(0, 0), 0)\n        self.assertEqual(sum(2.5, 2.1), 4.6)\n        self.assertEqual(sum(2.5, 2.5), 5)\n\n    def test_sum_type(self):\n        with self.assertRaises(ValueError):\n            sum(\"5\", 7)\n        with self.assertRaises(ValueError):\n            sum(5, \"7\")\n        with self.assertRaises(ValueError):\n            sum(\"5\", \"7\")\n        with self.assertRaises(ValueError):\n            sum(\"a\", 7)\n        with self.assertRaises(ValueError):\n            sum(None, 7)    \n\n\n\"\"\"\nEXTRA\n\"\"\"\nfrom datetime import datetime, date\n\n\nclass TestData(unittest.TestCase):\n\n    def setUp(self) -> None:\n        self.data = {\n                    \"name\": \"Adrian Rodriguez\",\n                    \"age\": 26,\n                    \"birth_date\": datetime.strptime(\"12-02-98\", \"%d-%m-%y\").date(),\n                    \"programming_languages\": [\"Python\", \"Rust\"],\n                }\n\n\n    def data_fields(self):\n        self.assertIn(\"name\", self.data)\n        self.assertIn(\"age\", self.data)\n        self.assertIn(\"birth_date\", self.data)\n        self.assertIn(\"programming_languages\", self.data)\n    \n    def test_data_is_correct(self):\n        self.assertIsInstance(self.data[\"name\"], str)\n        self.assertIsInstance(self.data[\"age\"], int)\n        self.assertIsInstance(self.data[\"birth_date\"], date)\n        self.assertIsInstance(self.data[\"programming_languages\"], list)\n\nunittest.main()"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/agusrosero.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Crea una función que se encargue de sumar dos números y retornar\n * su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n * capaz de determinar si esa función se ejecuta correctamente.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\n */\n\"\"\"\nimport unittest\n\n\ndef sumar(num1, num2):\n    return num1 + num2\n\n\nclass TestSuma(unittest.TestCase):\n    def test_sumar(self):\n        self.assertEqual(sumar(7, 5), 12)\n        self.assertEqual(sumar(5, 5), 10)\n        self.assertEqual(sumar(10, 3), 13)\n\n\n\"\"\"DIFICULTAD EXTRA\"\"\"\nmi_diccionario = {\n    \"name\": \"Hernan\",\n    \"age\": 23,\n    \"birth_date\": \"03/08/00\",\n    \"programming_languages\": [\"Python\", \"Javascript\"]\n}\n\n\nclass TestVacio(unittest.TestCase):\n    def test_vacio(self):\n        longitud = len(mi_diccionario)\n        self.assertEqual(longitud, 4)\n\n    def test_datos(self):\n        self.assertEqual(mi_diccionario, {\n            \"name\": \"Hernan\",\n            \"age\": 23,\n            \"birth_date\": \"03/08/00\",\n            \"programming_languages\": [\"Python\", \"Javascript\"]\n        })\n\n\nif __name__ == '__main__':\n    unittest.main()\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/alanshakir.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Crea una función que se encargue de sumar dos números y retornar\n * su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n * capaz de determinar si esa función se ejecuta correctamente.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\n */\n\"\"\"\nimport unittest\n\ndef sumar_valores(valor_a, valor_b):\n    return(valor_a + valor_b)\n\nclass TestPruebas(unittest.TestCase):\n    def test_1(self):\n        resultado = sumar_valores(3, 8)\n        self.assertEqual(resultado, 11)\n        \n\n#Extra\n\nmy_dict = {\"name\": \"alan ramirez\",\n           \"age\": 39,\n           \"birth_date\": \"20-01-1985\",\n           \"programming_languages\": [\"Python\", \"Java\", \"C\"]\n}\n\nclass TestDict(unittest.TestCase):\n    def test_all_values(self):\n        self.assertIn(\"name\", my_dict)\n        self.assertIn(\"age\", my_dict)\n        self.assertIn(\"birth_date\", my_dict)\n        self.assertIn(\"programming_languages\", my_dict)\n    \n    def test_is_corect(self):\n        self.assertIsInstance(my_dict[\"name\"], str)\n        self.assertIsInstance(my_dict[\"age\"], int)\n        self.assertIsInstance(my_dict[\"birth_date\"], str)\n        self.assertIsInstance(my_dict[\"programming_languages\"], list)\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/alexdevrep.py",
    "content": "'''\n/*\n * EJERCICIO:\n * Crea una función que se encargue de sumar dos números y retornar\n * su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n * capaz de determinar si esa función se ejecuta correctamente.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\n */\n'''\n#Importamos la librería necesaria para hacer el test\nimport unittest\n\n#Creamos la función suma \ndef suma (numero1, numero2):\n    return numero1 + numero2\n\n#Creamos la clase de prueba que hereda de unittest.TestCase\nclass TestSuma(unittest.TestCase):\n    #Definimos los métodos deben de empezar por \"test_\"\n    def test_suma_positiva(self):\n        numero1 = 3\n        numero2 = 2\n\n        resultado= suma(numero1,numero2)\n        #Utilizamos afirmaciones (asertions) para verificar el valor esperado \"5\"\n        self.assertEqual(resultado,5)\n\n\n#Ejecutamos las pruebas\nif __name__ == '__main__': #Verificamos si el script se está ejecutando como un programa principal\n    unittest.main()\n\n\n#Dificultad EXTRA\n\n#Creamos el diccionario\nalexdevrep = {\n    \"nombre\": \"Alejandro\",\n    \"edad\": \"24\",\n    \"Fecha de nacimiento\": \"22-07-1999\",\n    \"Lenguajes de programación\": [\"Python\",\"JavaScript\",\"Java\"]\n}\n\n#Creamos la función que nos comprueba las claves\ndef claves():\n    claves_list =[]\n    for clave in alexdevrep:\n        claves_list.append(clave)\n    return claves_list\n    \n#Creamos la función que nos devuelve los valores\ndef valor ():\n    valor_list=[]\n    for clave in alexdevrep:\n        valor = alexdevrep[clave]\n        valor_list.append(valor)\n    return valor_list\n    \n#Creamos los test unitarios \nclass Test(unittest.TestCase):\n    def test_campos(self):\n        claves_dict= claves()\n        self.assertEqual(claves_dict,['nombre', 'edad', 'Fecha de nacimiento', 'Lenguajes de programación'])\n        \n        \n    \n    def test_datos(self):\n        datos_dict=valor()\n        self.assertEqual(datos_dict,['Alejandro', '24', '22-07-1999', ['Python', 'JavaScript', 'Java']])\n        \n#Ejecutamos los test\nif __name__ == '__main__':\n    unittest.main()\n\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/annaviper.py",
    "content": "import pytest\n\n\"\"\"EJERCICIO\"\"\"\n\n\ndef sum_two_numbers(num1: int, num2: int) -> int:\n\tif isinstance(num1, int) & isinstance(num2, int):\n\t\treturn num1 + num2\n\traise ValueError(\"Numbers have to be integers.\")\n\n\nclass TestSum:\n\t@pytest.mark.parametrize(\"num1,num2,expected\", [\n\t\t(0, 1, 1),\n\t\t(5, 5, 10),\n\t\t(3, -1, 2)\n\t])\n\tdef test_sum_two_numbers(self, num1, num2, expected):\n\t\tassert sum_two_numbers(num1, num2) == expected\n\n\tdef test_raises_value_error(self):\n\t\twith pytest.raises(ValueError):\n\t\t\tsum_two_numbers(\"\", 3)\n\n\n\"\"\"DIFICULTAD EXTRA\"\"\"\n\ndata = {\n\t'name': 'anna',\n\t'age': 36,\n\t'birth_date': \"13 de octubre\",\n\t'programming_languages': ['Python', 'Kotlin']\n}\n\n\nclass TestDictionary:\n\tdef test_all_keys_exist(self):\n\t\t# using set instead of list so the order doesn't matter\n\t\tkeys = {'name', 'age', 'birth_date', 'programming_languages'}\n\t\tassert set(data.keys()) == keys\n\n\tdef test_values_are_correct(self):\n\t\tvalues = ['anna', 36, '13 de octubre', ['Python', 'Kotlin']]\n\t\tassert list(data.values()) == values\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/any7dev.py",
    "content": "\"\"\" /*\n* EJERCICIO:\n* Crea una función que se encargue de sumar dos números y retornar\n* su resultado.\n* Crea un test, utilizando las herramientas de tu lenguaje, que sea\n* capaz de determinar si esa función se ejecuta correctamente.\n*\n* DIFICULTAD EXTRA (opcional):\n* Crea un diccionario con las siguientes claves y valores:\n* \"name\": \"Tu nombre\"\n* \"age\": \"Tu edad\"\n* \"birth_date\": \"Tu fecha de nacimiento\"\n* \"programming_languages\": [\"Listado de lenguajes de programación\"]\n* Crea dos test:\n* - Un primero que determine que existen todos los campos.\n* - Un segundo que determine que los datos introducidos son correctos.\n*/ \"\"\"\n\n#EJERCICIO\nimport unittest\nfrom assertpy import assert_that\n\ndef suma (num1, num2):\n    return num1+num2\n\nclass TestSuma(unittest.TestCase):\n    def test(self):\n        resultado = suma (2, 3)\n        assert_that(resultado).is_instance_of(int)"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/avcenal.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Crea una función que se encargue de sumar dos números y retornar\n * su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n * capaz de determinar si esa función se ejecuta correctamente.\n\"\"\"\nimport unittest\n\ndef sum_two_numbers(number_1,number_2):\n    return number_1 + number_2\n\nclass TestSumNumbers(unittest.TestCase):\n    def test_1(self):\n        result = sum_two_numbers(5,7)\n        self.assertEqual(result,12)\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\n\"\"\"\n\ndef dict_creation():\n    my_dict = {\n        \"name\": \"Alex\",\n        \"age\": \"39\",\n        \"birth_date\": \"19/12/1984\",\n        \"programing_languages\": [\"Python\",\"Javascript\",\"Swift\"]\n    }\n    return my_dict\n\nclass TestDicts(unittest.TestCase):\n    def test_dict_longitude(self):\n        longitude = len(dict_creation())\n        self.assertEqual(longitude,4)\n\n    def test_type_data(self):\n        one_dict = dict_creation()\n        for key in one_dict:\n            if type(one_dict[key]) == list:\n                for element in one_dict[key]:\n                    self.assertIsInstance(element,str)\n            else:\n                self.assertIsInstance(one_dict[key],str)\n\nif __name__ == '__main__':\n    unittest.main()\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/cesar-ch.py",
    "content": "import unittest\nfrom datetime import datetime, date\n\n\"\"\"\n  #13 PRUEBAS UNITARIAS\n\"\"\"\n\n\ndef sumar_numeros(a, b):\n    return a + b\n\n\nclass TestSumarNumeros(unittest.TestCase):\n\n    def test_suma_numeros(self):\n        resultado = sumar_numeros(2, 3)\n        self.assertEqual(resultado, 5)\n        resultado2 = sumar_numeros(-2, -3)\n        self.assertEqual(resultado2, -5)\n        resultado3 = sumar_numeros(2, -3)\n        self.assertEqual(resultado3, -1)\n\n\n\"\"\"\n  DIFICULTAD EXTRA\n\"\"\"\n\npersonal_info = {\n    \"name\": \"cesar-ch\",\n    \"age\": 3,\n    \"birth_date\": datetime.strptime(\"2021-02-03\", \"%Y-%m-%d\").date(),\n    \"programming_languages\": [\"Javascript\", \"Python\", \"Java\"],\n}\n\n\nclass TestInformacionPersonal(unittest.TestCase):\n\n    # Test para verificar la existencia de las claves:\n    def test_claves(self):\n\n        claves_esperadas = [\"name\", \"age\", \"birth_date\", \"programming_languages\"]\n        for campo in claves_esperadas:\n            self.assertIn(campo, personal_info)\n\n    # Test para verificar la corrección de los datos (ejemplo):\n    def test_datos_correctos(self):\n        self.assertIsInstance(personal_info[\"name\"], str)\n        self.assertIsInstance(personal_info[\"age\"], int)\n        self.assertIsInstance(personal_info[\"birth_date\"], date)\n        self.assertIsInstance(personal_info[\"programming_languages\"], list)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/cristianfloyd.py",
    "content": "# EJERCICIO:\n# Crea una función que se encargue de sumar dos números y retornar\n# su resultado.\n# Crea un test, utilizando las herramientas de tu lenguaje, que sea\n# capaz de determinar si esa función se ejecuta correctamente.\nimport unittest\nfrom datetime import date, datetime\n\n\ndef sumar(num_a: int | float, num_b: int | float) -> int | float:\n    if not isinstance(num_a, (int, float)) or not isinstance(num_b, (int, float)):\n        raise ValueError(\"Los argumentos deben ser enteros o decimales.\")\n    resultado = num_a + num_b\n    print(f\"Sumando {num_a} y {num_b} = {resultado}\")\n    return resultado\n\n\nclass TestSumar(unittest.TestCase):\n    def test_sumar(self):\n        self.assertEqual(sumar(1, 1), 2)\n        self.assertEqual(sumar(1, -1), 0)\n        self.assertEqual(sumar(-1, -1), -2)\n        self.assertEqual(sumar(1.5, 0.5), 2)\n        self.assertEqual(sumar(1, -1.5), -0.5)\n\n    def test_sumar_tipos(self):\n        with self.assertRaises(ValueError):\n            sumar(\"1\", 1)\n        with self.assertRaises(ValueError):\n            sumar(1, \"1\")\n        with self.assertRaises(ValueError):\n            sumar(\"1\", \"1\")\n        with self.assertRaises(ValueError):\n            sumar(\"\", 1)\n\n\n# unittest.main()\n\n#\n# DIFICULTAD EXTRA (opcional):\n# Crea un diccionario con las siguientes claves y valores:\n# \"name\": \"Tu nombre\"\n# \"age\": \"Tu edad\"\n# \"birth_date\": \"Tu fecha de nacimiento\"\n# \"programming_languages\": [\"Listado de lenguajes de programación\"]\n# Crea dos test:\n# - Un primero que determine que existen todos los campos.\n# - Un segundo que determine que los datos introducidos son correctos.\n\n\nclass TestData(unittest.TestCase):\n    def setUp(self) -> None:\n        self.data = {\n            \"name\": \"Cristian\",\n            \"age\": 21,\n            \"birth_date\": datetime.strptime(\"01/01/2000\", \"%d/%m/%Y\").date(),\n            \"programming_languages\": [\"Python\", \"JavaScript\", \"Java\"],\n        }\n\n    def test_data(self):\n        self.assertIn(\"name\", self.data)\n        self.assertIn(\"age\", self.data)\n        self.assertIn(\"birth_date\", self.data)\n        self.assertIn(\"programming_languages\", self.data)\n\n    def test_data_types(self):\n        self.assertIsInstance(self.data[\"name\"], str)\n        self.assertIsInstance(self.data[\"age\"], int)\n        self.assertIsInstance(self.data[\"birth_date\"], date)\n        self.assertIsInstance(self.data[\"programming_languages\"], list)\n\n\nunittest.main()\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/danielhdzr.py",
    "content": "# #13 PRUEBAS UNITARIAS\n#### Dificultad: Fácil | Publicación: 25/03/24 | Corrección: 01/04/24\n\n\n'''EJERCICIO:\n * Crea una función que se encargue de sumar dos números y retornar\n * su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n * capaz de determinar si esa función se ejecuta correctamente.\n'''\n\n# Library for testing\nimport unittest\nfrom datetime import datetime, date\n\ndef sum2_numbers(x, y):\n        if not isinstance(x, (int, float)) or not isinstance(y, (int, float)):\n            raise ValueError('Arguments must be ints or floats')\n        return x + y\n    \n# Tests must be within a class\nclass TestSum(unittest.TestCase):\n# Declare the correct output for the given cases\n# Test functions must begin with the word 'test'\n# Test 1\n        def test_sum(self):\n            self.assertEqual(sum2_numbers(5, 7), 12)\n            self.assertEqual(sum2_numbers(5, -7), -2)\n            self.assertEqual(sum2_numbers(0, 0), 0)\n            self.assertEqual(sum2_numbers(2.5, 2.1), 4.6)\n            self.assertEqual(sum2_numbers(2, 2.1), 4.1)\n            self.assertEqual(sum2_numbers(2.5, 2.5), 5)\n# Declare the posible typed errors\n# Test 2\n        def test_sum_type(self):\n            with self.assertRaises(ValueError):\n                sum2_numbers('5', 7)\n            with self.assertRaises(ValueError):\n                sum2_numbers(5, '7')\n            with self.assertRaises(ValueError):\n                sum2_numbers('5', '7')\n            with self.assertRaises(ValueError):\n                sum2_numbers('a', 7)\n            with self.assertRaises(ValueError):\n                sum2_numbers(None, 7)\n\n    \n\n\n    \n'''\nEXTRA\n * Crea un diccionario con las siguientes claves y valores:\n * 'name': 'Tu nombre'\n * 'age': 'Tu edad'\n * 'birth_date': 'Tu fecha de nacimiento'\n * 'programming_languages': ['Listado de lenguajes de programación']\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\n'''\n\n\n\n# Tests must be within a class\nclass TestDict(unittest.TestCase):\n    # Data the tests will work with\n    def setUp(self) -> None:\n        self.my_dict = { \n            'name': 'Daniel',\n            'age': 33,\n            # In date format. Take only the date, not seconds or anything else\n            'birth_date': datetime.strptime('19-11-90', '%d-%m-%y').date(),\n            'programming_languages': ['Python, SQL'] \n            }\n\n    # Test functions must begin with the word 'test'\n    def test_fields_exist(self):\n        # Check if the field 'name' exists in my dict\n        self.assertIn('name', self.my_dict)\n        self.assertIn('age', self.my_dict)\n        self.assertIn('birth_date', self.my_dict)\n        self.assertIn('programming_languages', self.my_dict)\n\n    # Check if the data type is correct\n    def test_data_is_correct(self):\n        self.assertIsInstance(self.my_dict['name'], str)\n        self.assertIsInstance(self.my_dict['age'], int)\n        self.assertIsInstance(self.my_dict['birth_date'], date)\n        self.assertIsInstance(self.my_dict['programming_languages'], list)\n\n\n# Run tests\nunittest.main()\n         \n\n        \n\n    "
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/davidrguez98.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Crea una función que se encargue de sumar dos números y retornar\n * su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n * capaz de determinar si esa función se ejecuta correctamente.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\n */\"\"\"  \"\"\" \"\"\"\n\n#EJERCICIO\n\nimport unittest\nfrom datetime import datetime, date\n\ndef sumar(a, b):\n    if not isinstance(a, (int, float)) or not isinstance(b, (int,float)):\n        raise ValueError(\"Los argumentos deben de ser enteros o decimales.\")\n    return a + b\n\nclass TestSumar(unittest.TestCase):\n    def test_sumar(self):\n        self.assertEqual(sumar(5, 7), 12)\n        self.assertEqual(sumar(5, -7), -2)\n        self.assertEqual(sumar(0, 0), 0)\n        self.assertEqual(sumar(2.5, 2.1), 4.6)\n\n    def test_sumar_type(self):    \n        with self.assertRaises(ValueError):\n            sumar(\"5\", 7)\n        with self.assertRaises(ValueError):\n            sumar(5, \"a\")\n\n#DIFICULTAD EXTRA\n\ndata = {\n    \"name\" : \"David\",\n    \"age\" : 26,\n    \"birth_date\" : datetime.strptime(\"10-03-98\", \"%d-%m-%y\").date(),\n    \"programming_languages\" : [\"Python\", \"HTML\", \"CSS\"] \n}\n\nclass TestData(unittest.TestCase):\n\n    def setUp(self):\n        self.data = {\n            \"name\" : \"David\",\n            \"age\" : 26,\n            \"birth_date\" : datetime.strptime(\"10-03-98\", \"%d-%m-%y\").date(),\n            \"programming_languages\" : [\"Python\", \"HTML\", \"CSS\"] \n        }\n\n    def test_fields_exist(self):\n        self.assertIn(\"name\", self.data)\n        self.assertIn(\"age\", self.data)\n        self.assertIn(\"birth_date\", self.data)\n        self.assertIn(\"programming_languages\", self.data)\n\n    def test_data_is_correct(self):\n        self.assertIsInstance(self.data[\"name\"], str)\n        self.assertIsInstance(self.data[\"age\"], int)\n        self.assertIsInstance(self.data[\"birth_date\"], date)\n        self.assertIsInstance(self.data[\"programming_languages\"], list)\n\nunittest.main()"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/didacdev.py",
    "content": "import unittest\n\ndata = {\n    \"name\": \"Diego\",\n    \"age\": \"28\",\n    \"birth_date\": \"10-03-1996\",\n    \"programming_language\": \"Python\",\n}\n\n\ndef add(number1: float, number2: float):\n    return number1 + number2\n\n\nclass TestAdd(unittest.TestCase):\n    def test_suma(self):\n        number1 = 2\n        number2 = 3\n\n        result = number1 + number2\n\n        self.assertEqual(result, 5)\n\n\nclass TestData(unittest.TestCase):\n    def test_fields(self):\n\n        keys = data.keys()\n\n        self.assertFalse(\"name\" not in keys)\n        self.assertFalse(\"age\" not in keys)\n        self.assertFalse(\"birth_date\" not in keys)\n        self.assertFalse(\"programming_language\" not in keys)\n\n    def test_data(self):\n        self.assertEqual(data[\"name\"], \"Diego\")\n        self.assertEqual(data[\"age\"], \"28\")\n        self.assertEqual(data[\"birth_date\"], \"10-03-1996\")\n        self.assertEqual(data[\"programming_language\"], \"Python\")\n\n\nif __name__ == '__main__':\n    unittest.main()\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/duendeintemporal.py",
    "content": "#13 { Retos para Programadores } PRUEBAS UNITARIAS\n\n# Bibliography reference\n# Professional JavaScript for web developers by Matt Frisbie [Frisbie, Matt] (z-lib.org)\n#Python Notes for Professionals. 800+ pages of professional hints and tricks (GoalKicker.com) (Z-Library)\n# Additionally, I use GPT as a reference and sometimes to correct or generate proper comments.\n\n\"\"\"  \n* EJERCICIO:\n * Crea una función que se encargue de sumar dos números y retornar\n * su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n * capaz de determinar si esa función se ejecuta correctamente.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos. \n \n \"\"\"\n\nfrom datetime import datetime\n\n# Short for print\nlog = print\n\ndef assert_condition(condition, message, errors):\n    \"\"\"Custom assert function that logs an error instead of throwing.\"\"\"\n    if not condition:\n        log(message)\n        errors.append(message)  # Collect the error message\n\ndef sum_numbers(a, b):\n    \"\"\"Returns the sum of two numbers, raises TypeError if arguments are not numbers.\"\"\"\n    if not isinstance(a, (int, float)) or not isinstance(b, (int, float)):\n        raise TypeError('Both arguments must be numbers')\n    return a + b\n\ndef test_sum(errors):\n    \"\"\"Tests the sum_numbers function.\"\"\"\n    assert_condition(sum_numbers(2, 3) == 5, 'Error: 2 + 3 should be 5', errors)\n    assert_condition(sum_numbers(-1, 1) == 0, 'Error: -1 + 1 should be 0', errors)\n    assert_condition(sum_numbers(0, 0) == 0, 'Error: 0 + 0 should be 0', errors)\n\n    try:\n        sum_numbers(2, '3')  # Caught an error: Both arguments must be numbers\n    except Exception as e:\n        log('Caught an error:', e)  # Log the caught error\n        assert_condition(isinstance(e, TypeError), 'Error: Invalid argument type not handled', errors)\n        assert_condition(str(e) == 'Both arguments must be numbers', 'Error: Argument type mismatch', errors)\n\n    log('All sum tests have been executed.') # All sum tests have been executed.\n\npersonal_info = {\n    \"name\": \"Niko Zen\",\n    \"age\": 41,\n    \"birth_date\": \"1983/08/08\",\n    \"programming_languages\": [\"JavaScript\", \"Python\", \"Rust\", \"Ruby\", \"Java\"]\n}\n\ndef test_personal_info(obj, errors):\n    \"\"\"Tests the personal information object.\"\"\"\n    if not obj:\n        log('The obj is empty, skipping personal info tests.')\n        return\n\n    # Check that all fields exist\n    assert_condition('name' in obj, 'Missing field \"name\"', errors)\n    assert_condition('age' in obj, 'Missing field \"age\"', errors)\n    assert_condition('birth_date' in obj, 'Missing field \"birth_date\"', errors)\n    assert_condition('programming_languages' in obj, 'Missing field \"programming_languages\"', errors)\n\n    # Check data types\n    assert_condition(isinstance(obj['name'], str), '\"name\" must be a string', errors)\n    assert_condition(isinstance(obj['age'], (int, float)), '\"age\" must be a number', errors)\n\n    # Check if birth_date is a valid date\n    try:\n        birth_date = datetime.strptime(obj['birth_date'], '%Y/%m/%d')\n        assert_condition(birth_date is not None, '\"birth_date\" must be a valid Date', errors)\n    except ValueError:\n        assert_condition(False, '\"birth_date\" must be a valid Date', errors)\n\n    assert_condition(isinstance(obj['programming_languages'], list), '\"programming_languages\" is not an array', errors)\n\n    # Validate each programming language\n    for lang in obj['programming_languages']:\n        assert_condition(isinstance(lang, str), 'Each language must be a string', errors)\n\n    # Check fields are not empty\n    assert_condition(len(obj['name']) > 0, '\"name\" cannot be empty', errors)\n    assert_condition(obj['age'] > 0, '\"age\" must be greater than 0', errors)\n    assert_condition(len(obj['birth_date']) > 0, '\"birth_date\" cannot be empty', errors)\n    assert_condition(len(obj['programming_languages']) > 0, '\"programming_languages\" should have at least one language', errors)\n\n    log('All personal info tests have been executed.') # All personal info tests have been executed.\n\nnikita_info = {}\n\nerrors = []\ntest_sum(errors)\ntest_personal_info(personal_info, errors)  # Should pass\ntest_personal_info(nikita_info, errors)  # The obj is empty, skipping personal info tests.\n\n# Log all collected errors at the end\nif errors:\n    log('Errors encountered during tests:')\n    for error in errors:\n        log(error)\nelse:\n    log('No errors encountered during tests.') # No errors encountered during tests.\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/eduhumanes91.py",
    "content": "import unittest\nfrom datetime import datetime, date\n\n#Ejercicio\n\ndef sumar(a,b):\n   return a+b\n\nclass TestSumar(unittest.TestCase):\n\n   def testSumar(self):\n      self.assertEqual(sumar(1,2),3)\n      self.assertEqual(sumar(2.0,3.0),5.0)\n\n#Extra\n\nmy_dict = {\n   \"name\": \"Eduardo\",\n   \"age\": 33,\n   \"birth_date\": datetime.strptime(\"13-05-1991\", \"%d-%m-%Y\").date(),\n   \"programming_languages\": [\"Python\", \"Java\", \"JavaScript\"],\n}\n\nclass TestDict(unittest.TestCase):\n\n   def setUp(self) -> None:\n      self.my_dict = {\n         \"name\": \"Eduardo\",\n         \"age\": 33,\n         \"birth_date\": datetime.strptime(\"13-05-1991\", \"%d-%m-%Y\").date(),\n         \"programming_languages\": [\"Python\", \"Java\", \"JavaScript\"],\n      }\n\n   def test_fields_exists(self):\n      self.assertIn(\"name\", self.my_dict)\n      self.assertIn(\"age\", self.my_dict)\n      self.assertIn(\"birth_date\", self.my_dict)\n      self.assertIn(\"programming_languages\", self.my_dict)\n   \n   def test_data_is_correct(self):\n      self.assertIsInstance(self.my_dict[\"name\"], str)\n      self.assertIsInstance(self.my_dict[\"age\"], int)\n      self.assertIsInstance(self.my_dict[\"birth_date\"], date)\n      self.assertIsInstance(self.my_dict[\"programming_languages\"], list)\n\n\nunittest.main()"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/fborjalv.py",
    "content": "import unittest\nfrom datetime import date, datetime\n\ndef sumar(a,b):\n    if not isinstance(a, (int, float)) or not isinstance(b, (int, float)):\n        raise ValueError(\"No se pueden sumar cadenas de texto y números\")\n    return a + b\n\nclass TestSumar(unittest.TestCase):\n    \n    def test_sumar_cero(self):\n        self.assertEqual(sumar(0, 0), 0)\n        self.assertEqual(sumar(10, 0),10)\n\n    def test_sumar_types(self):\n        with self.assertRaises(ValueError):\n            sumar(\"5\", 7)\n\n#unittest.main()\n\n\n\n\nclass TestCheckData(unittest.TestCase):\n\n    def setUp(self): # estipulado por librería unnitest\n        self.data = {\n            \"name\": \"Borja\",\n            \"age\": 32,\n            \"birth_date\" : datetime.strptime(\"29-04-92\",\"%d-%m-%y\").date(),\n            \"programming_lenguages\": [\"Python\", \"JavaScript\"]\n            }\n\n    def test_check_exist_data(self):\n        self.assertIn(\"name\", self.data)\n        self.assertIn(\"age\", self.data)\n        self.assertIn(\"birth_date\", self.data)\n        self.assertIn(\"programming_lenguages\", self.data)\n\n    def test_check_types(self):\n        self.assertIsInstance(self.data[\"name\"], str)\n        self.assertIsInstance(self.data[\"age\"], int)\n        self.assertIsInstance(self.data[\"birth_date\"], date)\n        self.assertIsInstance(self.data[\"programming_lenguages\"], list)\n        \nunittest.main()\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/garos01.py",
    "content": "import unittest\n\n\ndef suma(a, b):\n\n    return a + b\n\n\nclass TestSuma(unittest.TestCase):\n    def test_suma(self):\n        self.assertEqual(suma(2, 3), 5)\n        self.assertEqual(suma(-1, 1), 0)\n        self.assertEqual(suma(-5, -3), -8)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n\n# Ejercicio ectra\n\n\ndatos_personales = {\n    \"name\": \"Oscar Garzon\",\n    \"age\": 29,\n    \"birth_date\": \"11-09-1994\",\n    \"programming_languages\": [\"Python\", \"JavaScript\"],\n}\n\n\nclass TestDatosPersonales(unittest.TestCase):\n    def test_campos_existen(self):\n        self.assertIn(\"name\", datos_personales)\n        self.assertIn(\"age\", datos_personales)\n        self.assertIn(\"birth_date\", datos_personales)\n        self.assertIn(\"programming_languages\", datos_personales)\n\n    def test_datos_correctos(self):\n        self.assertIsInstance(datos_personales[\"name\"], str)\n        self.assertIsInstance(datos_personales[\"age\"], int)\n        self.assertIsInstance(datos_personales[\"birth_date\"], str)\n        self.assertIsInstance(datos_personales[\"programming_languages\"], list)\n        for lang in datos_personales[\"programming_languages\"]:\n            self.assertIsInstance(lang, str)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/ggilperez.py",
    "content": "# 13 Unit Tests\nimport doctest\nimport unittest\nfrom datetime import datetime, date\n\n\ndef sum(num_1: int, num_2: int) -> int:\n    \"\"\"\n    Doctest\n    >>> sum(1,2)\n    3\n    \"\"\"\n\n    # Check types\n    if not isinstance(num_1, int | float) or not isinstance(num_2, int | float):\n        raise ValueError(\"Params must be int or float\")\n\n    return num_1 + num_2\n\n\n# Run doctest\ndoctest.testmod()\n\n\n# Using unittest\nclass TestSum(unittest.TestCase):\n\n    def test_sum_positive(self):\n        expected_result = 7\n        result = sum(3, 4)\n\n        self.assertEqual(expected_result, result)\n\n    def test_sum_negative(self):\n        expected_result = -4\n        result = sum(-1, -3)\n\n        self.assertEqual(expected_result, result)\n\n    def test_sum_type(self):\n        with self.assertRaises(ValueError):\n            sum(\"1\", \"2\")\n\n# Run unittest\nunittest.main()\n\n# Extra\nclass TestData(unittest.TestCase):\n\n    def setUp(self):\n        self.data = {\n            \"name\": \"Guillermo\",\n            \"age\": 31,\n            \"birth_date\": datetime.strptime(\"14/06/1993\", \"%d/%m/%Y\").date(),\n            \"programming_languages\": [\"Python\", \"C#\", \"C++\"]\n        }\n\n    def test_fields(self):\n        self.assertIn(\"name\", self.data)\n        self.assertIn(\"age\", self.data)\n        self.assertIn(\"birth_date\", self.data)\n        self.assertIn(\"programming_languages\", self.data)\n\n    def test_fields_types(self):\n        self.assertIsInstance(self.data[\"name\"], str)\n        self.assertIsInstance(self.data[\"age\"], str)\n        self.assertIsInstance(self.data[\"birth_date\"], date)\n        self.assertIsInstance(self.data[\"programming_languages\"], list)\n\n# Run unittest\nunittest.main()"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/h4ckxel.py",
    "content": "# #13 PRUEBAS UNITARIAS\n\n\n\"\"\"\n * EJERCICIO:\n * Crea una función que se encargue de sumar dos números y retornar\n * su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n * capaz de determinar si esa función se ejecuta correctamente.\n\"\"\"\n\nimport unittest \n\ndef sum(number1,number2):\n    if not isinstance(number1, (int)) or not isinstance(number2, (int)):\n        raise ValueError(\"Error en la entrada de datos\")\n    return number1 + number2\n\n\nclass TestSum(unittest.TestCase):\n    def test_sum(self):\n        self.assertEqual(sum(5,4),9)\n        self.assertEqual(sum(5,-2),3)\n        self.assertEqual(sum(5,7),12)\n        self.assertEqual(sum(1,2),3)\n    \n    def test_raises(self):\n        with self.assertRaises(ValueError):\n            sum(\"1\", 8)\n        with self.assertRaises(ValueError):\n            sum(2, \"b\")\n        with self.assertRaises(ValueError):\n            sum(\"a\", \"b\")\n       \n\n\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\n\n\"\"\"\nclass Person():\n    def __init__(self,name,age,birthday,languages) -> None:\n        self.name = name\n        self.age = age\n        self.birthday = birthday\n        self.languages = languages\n    \ndef dictionary(persona):\n\n    person = {\"name\":\"Fede\",\"age\":persona.age,\"birth_day\":persona.birthday,\"program_languages\":persona.languages}\n    return person\n    \nperson1 = Person(\"Fede\",43,\"25/6/80\",[])\n\ntest_person = dictionary(person1)\n\nprint (test_person)\n\n\nclass TestDictionaryPerson(unittest.TestCase):\n\n    def setUp(self) -> None:\n        self.data = test_person\n    \n\n    def test_empty(self):\n        self.assertIn(\"name\", test_person)\n        self.assertIn(\"age\", test_person)\n        self.assertIn(\"birth_day\", test_person)\n        self.assertIn(\"program_languages\", test_person)\n    \n    def test_data_is_correct(self):\n        self.assertIsInstance(self.data[\"name\"], str)\n        self.assertIsInstance(self.data[\"age\"], int)\n        self.assertIsInstance(self.data[\"birth_day\"],str)\n        self.assertIsInstance(self.data[\"program_languages\"], list)\n\n\nunittest.main(verbosity=3)\n\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/hectorio23.py",
    "content": "# Autor: Héctor Adán \n# GitHub: https://github.com/hectorio23 \n\nimport random\nimport sys\n\n# Función que implementa el juego de adivinanzas\ndef mini_game():\n    # Inicializar la semilla del generador de números aleatorios\n    random.seed()\n\n    print(\"Bienvenido al juego de adivinanzas!\")\n    print(\"Estoy pensando en un número entre 1 y 100. Adivina cuál es!\")\n\n    # Generar número aleatorio entre 1 y 100\n    numero_aleatorio = random.randint(1, 100)\n    intentos = 0\n    intento_usuario = 0\n\n    while intento_usuario != numero_aleatorio:\n        try:\n            intento_usuario = int(input(\"Ingresa tu intento: \"))\n            assert 1 <= intento_usuario <= 100, \"El número debe estar entre 1 y 100\"\n            intentos += 1\n\n            if intento_usuario < numero_aleatorio:\n                print(\"El número que estoy pensando es mayor.\")\n            elif intento_usuario > numero_aleatorio:\n                print(\"El número que estoy pensando es menor.\")\n            else:\n                print(f\"¡Felicidades! Has adivinado el número en {intentos} intentos.\")\n\n        except ValueError:\n            print(\"Debes ingresar un número válido.\")\n        except AssertionError as e:\n            print(e)\n\n    continuar = input(\"¿Quieres jugar de nuevo? (s/n): \").lower()\n    if continuar == 's':\n        mini_game()\n    else:\n        print(\"Gracias por jugar. ¡Hasta luego!\")\n\nif __name__ == \"__main__\":\n    # Ejemplos de aserciones en Python\n    assert 2 + 2 == 4\n    print(\"Checkpoint #1\")\n\n    assert 2 * 2 == 4, \"Mensaje personalizado de aserción\"\n    print(\"Checkpoint #2\")\n\n    assert 0o10 + 0o10 == 16, \"Otra forma de agregar un mensaje de aserción\"\n    print(\"Checkpoint #3\")\n\n    assert (2 + 2) % 3 == 1, \"Success\"\n    print(\"Checkpoint #4\")\n\n    # Llamada a la función que implementa el juego de adivinanzas\n    mini_game()\n\n    assert (2 + 2) == 5, \"Failed\"\n    print(\"La ejecución continúa después de la última aserción\")\n\n    sys.exit(0)  # Indicar que el programa finalizó correctamente\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/hozlucas28.py",
    "content": "import unittest\nfrom typing import TypeVar, TypedDict\n\n\n\"\"\"\n    Tests...\n\"\"\"\n\nprint(\"Tests...\")\n\nprint(\n    \"\"\"\\nParameters = TypeVar(\"Parameters\", int, float)\n\n\ndef add(a: Parameters, b: Parameters) -> Parameters:\n    \\\"\\\"\\\"Add two numbers\\\"\\\"\\\"\n    if not isinstance(a, (int, float)) or not isinstance(b, (int, float)):\n        raise TypeError(\"Invalid arguments! Both of them should be integers, or floats\")\n\n    return a + b\n\n\nclass TestAdd(unittest.TestCase):\n    \\\"\\\"\\\"Tests of \\\"add\\\" (function).\\\"\\\"\\\"\n\n    def test_add_integers(self) -> None:\n        \\\"\\\"\\\"Test if \\\"add\\\" (function) can be executed with integer parameters.\\\"\\\"\\\"\n        result: int = add(a=1, b=4)\n        self.assertEqual(first=result, second=5)\n\n    def test_add_floats(self) -> None:\n        \\\"\\\"\\\"Test if \\\"add\\\" (function) can be executed with float parameters.\\\"\\\"\\\"\n        result: float = add(a=1.75, b=5.25)\n        self.assertEqual(first=result, second=7)\n\n    def test_add_strings(self) -> None:\n        \\\"\\\"\\\"Test if \\\"add\\\" (function) throw an error if it receive string parameters.\\\"\\\"\\\"\n\n        with self.assertRaises(expected_exception=TypeError):\n            add(a=\\\"4\\\", b=\\\"4\\\")\"\"\"\n)\n\nParameters = TypeVar(\"Parameters\", int, float)\n\n\ndef add(a: Parameters, b: Parameters) -> Parameters:\n    \"\"\"Add two numbers\"\"\"\n    if not isinstance(a, (int, float)) or not isinstance(b, (int, float)):\n        raise TypeError(\"Invalid arguments! Both of them should be integers, or floats\")\n\n    return a + b\n\n\nclass TestAdd(unittest.TestCase):\n    \"\"\"Tests of \"add\" (function).\"\"\"\n\n    def test_add_integers(self) -> None:\n        \"\"\"Test if \"add\" (function) can be executed with integer parameters.\"\"\"\n        result: int = add(a=1, b=4)\n        self.assertEqual(first=result, second=5)\n\n    def test_add_floats(self) -> None:\n        \"\"\"Test if \"add\" (function) can be executed with float parameters.\"\"\"\n        result: float = add(a=1.75, b=5.25)\n        self.assertEqual(first=result, second=7)\n\n    def test_add_strings(self) -> None:\n        \"\"\"Test if \"add\" (function) throw an error if it receive string parameters.\"\"\"\n\n        with self.assertRaises(expected_exception=TypeError):\n            add(a=\"4\", b=\"4\")\n\n\nprint(\n    \"\\n# ---------------------------------------------------------------------------------- #\\n\"\n)\n\n\"\"\"\n    Additional challenge...\n\"\"\"\n\nprint(\"Additional challenge...\\n\")\n\nAuthor = TypedDict(\n    \"Author\",\n    {\"name\": str, \"age\": str, \"birth_date\": str, \"programming_languages\": list[str]},\n)\n\nAUTHOR: Author = {\n    \"age\": \"22\",\n    \"birth_date\": \"2002-02-20\",\n    \"name\": \"Lucas\",\n    \"programming_languages\": [\"TypeScript\", \"Python\", \"Go (Golang)\"],\n}\n\n\nclass TestAuthor(unittest.TestCase):\n    \"\"\"Tests of \"AUTHOR\" (constant).\"\"\"\n\n    def test_schema(self) -> None:\n        \"\"\"Test \"AUTHOR\" (constant) schema.\"\"\"\n        author_schema: Author = {\n            \"age\": \"0\",\n            \"birth_date\": \"0000-00-00\",\n            \"name\": \"\",\n            \"programming_languages\": [],\n        }\n\n        self.assertIn(member=\"age\", container=author_schema)\n        self.assertIn(member=\"birth_date\", container=author_schema)\n        self.assertIn(member=\"name\", container=author_schema)\n        self.assertIn(member=\"programming_languages\", container=author_schema)\n\n    def test_data_types(self) -> None:\n        \"\"\"Test the data types of \"AUTHOR\" (constant) properties.\"\"\"\n        expected_author: Author = {\n            \"age\": \"22\",\n            \"birth_date\": \"2002-02-20\",\n            \"name\": \"Lucas\",\n            \"programming_languages\": [\"TypeScript\", \"Python\", \"Go (Golang)\"],\n        }\n\n        self.assertDictEqual(d1=expected_author, d2=AUTHOR)\n\n\nunittest.main()\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/idiegorojas.py",
    "content": "def sum(a, b):\n    return a + b\n\ndata = {\n    'name': 'Diego',\n    'age': 28,\n    'birth_day': '1996-11-08',\n    'programming_languages': ['Python', 'Javascript', 'Swift']\n}\n\nimport unittest\nfrom idiegorojas import sum\n\n'''\n    * unittest.TestCase: Es la clase base para crear pruebas. Cada método que comienza con test_ es una prueba individual.\n    * self.assertEqual: Es un método que verifica si dos valores son iguales. Si no lo son, la prueba falla.\n    * unittest.main(): Ejecuta todas las pruebas definidas en la clase.\n'''\n\n\nclass TestSumar(unittest.TestCase):\n    def test_sumar_numeros_positivos(self):\n        self.assertEqual(sum(2, 3), 5)\n        self.assertEqual(sum(-1, -1), -2)\n        self.assertEqual(sum(0, 0), 0)\n\n    def test_sumar_tipo(self):\n        with self.assertRaises(ValueError):\n            sum(\"5\", 7)\n        with self.assertRaises(ValueError):\n            sum(5, \"7\")\n        with self.assertRaises(ValueError):\n            sum(\"5\", \"7\")\n        with self.assertRaises(ValueError):\n            sum(\"a\", 7)\n        with self.assertRaises(ValueError):\n            sum(None, 7)\n\n\nif __name__ == '__main__':\n    unittest.main()\n\n\n# Extra\n\nimport unittest\nfrom idiegorojas import data\n\nclass TestDict(unittest.TestCase):\n\n    def test_existe_campos(self):\n        campos_requerido = ['name', 'age', 'birth_day', 'programming_languages']\n        for field in campos_requerido:\n            self.assertIn(field, data)\n    \n    def test_tipo_dato_correcto(self):\n        self.assertIsInstance(data['name'], str)\n        self.assertIsInstance(data['age'], int)\n        self.assertIsInstance(data['birth_day'], str)\n        self.assertIsInstance(data['programming_languages'], list)\n\n    def test_valores_correctos(self):\n        self.assertEqual(data['name'], 'Diego')\n        self.assertEqual(data['age'], 28)\n        self.assertEqual(data['birth_day'], '1996-11-08')\n        self.assertIn('Python', data['programming_languages'])\n        self.assertIn('Javascript', data['programming_languages'])\n        self.assertIn('Swift', data['programming_languages'])\n\n\nif __name__ =='__main__':\n    unittest.main()"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/ignaciovihe.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Crea una función que se encargue de sumar dos números y retornar\n * su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n * capaz de determinar si esa función se ejecuta correctamente.\n\"\"\"\nimport unittest\nfrom datetime import datetime, date\n\ndef sumar(a, b) ->int :\n    if not isinstance(a,(int, float)) or not isinstance(b, (int, float)):\n        raise ValueError(\"Los números deben ser enetros o decimales.\")\n    return a + b\n\n\n\nclass TestSuma(unittest.TestCase):\n\n    def test_suma(self):\n        self.assertEqual(sumar(2,6), 8)\n        self.assertEqual(sumar(-2,-5), -7)\n        self.assertEqual(sumar(-2,5), 3)\n        self.assertEqual(sumar(2.3,5), 7.3)\n        self.assertEqual(sumar(2.5,2.5), 5)\n        self.assertEqual(sumar(0,0), 0)\n\n    def test_type_operators(self):\n        with self.assertRaises(ValueError):\n            sumar(\"3\",\"2\")\n        with self.assertRaises(ValueError):\n            sumar(\"2\",2)\n        with self.assertRaises(ValueError):\n            sumar(3,\"2\")\n        with self.assertRaises(ValueError):\n            sumar(\"r\",2)\n        with self.assertRaises(ValueError):\n            sumar(3,None)\n\n\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\n\"\"\"\n\nclass TestDict(unittest.TestCase):\n\n    def setUp(self)-> None:\n        self.my_dict ={\n            \"name\": \"Pedro\",\n            \"age\": 40,\n            \"birth_date\": datetime.strptime(\"29-10-1985\",\"%d-%m-%Y\").date(),\n            \"programming_languages\": [\"python\", \"Javascript\", \"Java\"]\n        }\n    \n    def test_fields_exist_and_no_empty(self):\n        necessaty_keys = [\"name\", \"age\", \"birth_date\", \"programming_languages\"]\n        for key in necessaty_keys:\n            self.assertIn(key, self.my_dict) #Comprueba que la clave esta presente\n            self.assertTrue(bool(self.my_dict[key])) #Comprueba que las claves no esten vacias.\n\n    def test_correct_data(self):\n        self.assertIsInstance(self.my_dict[\"name\"], str)\n        self.assertIsInstance(self.my_dict[\"age\"], int)\n        self.assertIsInstance(self.my_dict[\"birth_date\"],date)\n        self.assertIsInstance(self.my_dict[\"programming_languages\"], list)\n        #Comprueba que todos los elementos de languages sean str\n        self.assertTrue(all(isinstance(item, str) for item in self.my_dict[\"programming_languages\"]))\n\n    \n\n\nif __name__ == \"__main__\":\n    unittest.main()\n\n\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/isilanes.py",
    "content": "from datetime import datetime\n\n\ndef add_two_numbers(a: int, b: int) -> int:\n    return a + b\n\n\ndef test_add_two_numbers():\n    \"\"\"\n    GIVEN two numbers\n    WHEN we add them\n    THEN we get the sum\n    \"\"\"\n    assert add_two_numbers(1, 2) == 3\n\n\ndef test_commutative():\n    \"\"\"\n    GIVEN two numbers\n    AND they are provided in any order\n    WHEN we add them\n    THEN the result does not depend on the order\n    \"\"\"\n    assert add_two_numbers(2, 3) == add_two_numbers(3, 2)\n\n\ndef test_negative():\n    \"\"\"\n    GIVEN two negative numbers\n    WHEN we add them\n    THEN we get the proper sum\n    \"\"\"\n    assert add_two_numbers(-1, -3) == -4\n\n\ndef main():\n    # Obviamente en un entorno real usaría Pytest, los test estarían\n    # en un fichero separado, etc.\n    test_add_two_numbers()\n    test_commutative()\n    test_negative()\n    print(\"All main tests pass\")\n\n\ndef test_person_has_all_fields(person: dict):\n    \"\"\"\n    GIVEN a 'person' dictionary, containing personal info\n    THEN it contains all the required fields\n    \"\"\"\n    required_fields = [\"name\", \"age\", \"birth_date\", \"programming_languages\"]\n    for field in required_fields:\n        assert field in person, f\"Person lacks required field '{field}'\"\n\n\ndef test_person_data_is_congruent(person: dict):\n    \"\"\"\n    GIVEN a 'person' dictionary, containing personal info\n    THEN the name field is a string\n    AND the age is an integer\n    AND the birth_date is a date in ISO format\n    AND the age matches the birth_date\n    AND the programming_languages is a list of strings\n    \"\"\"\n    assert isinstance(person[\"name\"], str), \"Person name must be a string\"\n    assert isinstance(person[\"age\"], int), \"Person age must be an integer\"\n    birth = datetime.strptime(person[\"birth_date\"], \"%Y-%m-%d\")\n    expected_age = get_age(birth)\n    assert person[\"age\"] == expected_age, f\"Person's age {person['age']} does not match expected age {expected_age}\"\n    langs = person[\"programming_languages\"]\n    assert isinstance(langs, (list, tuple)), \"Person's programming languages are not a list or tuple\"\n    assert len(langs) >= 1, \"Person should know at least 1 programming language\"\n    for lang in langs:\n        assert isinstance(lang, str), f\"Language '{lang}' is not a valid programming language\"\n\n\ndef get_age(birth: datetime) -> int:\n    \"\"\"Dates are a nasty thing.\"\"\"\n    now = datetime.now()\n    delta_years = now.year - birth.year\n\n    if (now.month, now.day) < (birth.month, birth.day):\n        delta_years -= 1\n\n    return delta_years\n\n\ndef extra():\n    person = {\n        \"name\": \"Iñaki\",\n        \"age\": 46,\n        \"birth_date\": \"1977-06-11\",\n        \"programming_languages\": [\"Python\", \"Bash\", \"Fortran\"],\n    }\n    test_person_has_all_fields(person)\n    test_person_data_is_congruent(person)\n    print(\"All extra tests pass\")\n\n\nif __name__ == \"__main__\":\n    main()\n    extra()\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/jesusgdev.py",
    "content": "'''\n* EJERCICIO:\n * Crea una función que se encargue de sumar dos números y retornar\n   su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n   capaz de determinar si esa función se ejecuta correctamente.\n  \n * DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n   - \"name\": \"Tu nombre\"\n   - \"age\": \"Tu edad\"\n   - \"birth_date\": \"Tu fecha de nacimiento\"\n   - \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n   - Un primero que determine que existen todos los campos.\n   - Un segundo que determine que los datos introducidos son correctos.\n'''\n\n\nimport unittest  # 🧪 Módulo para hacer pruebas automáticas\nfrom datetime import datetime, date  # 📆 Para manejar fechas de forma segura\n\n\n# 📦 Diccionario con los datos personales\ndata = {\n    \"name\": \"Jesús García\",\n    \"age\": 41,\n    \"birth_date\": \"1984-03-25\",\n    \"programming_languages\": [\"Python\", \"JavaScript\", \"Java\"]\n}\n\n\n# ➕ Función que suma dos números y valida que sean correctos\ndef sum(a, b):\n    # ⚠️ Verifica si ambos valores son números enteros o decimales\n    if not isinstance(a, (int, float)) or not isinstance(b, (int, float)):\n        raise ValueError(\"Los argumentos deben ser enteros o decimales.\")\n    \n    # ✅ Si todo está bien, retorna la suma\n    return a + b\n\n\n# 🧪 Clase de pruebas para la función sum\nclass TestSumar(unittest.TestCase):\n\n    def test_sum(self):\n        # ✅ Pruebas con valores válidos\n        self.assertEqual(sum(2, 3), 5)           # 2 + 3 = 5\n        self.assertEqual(sum(-1, -4), -5)        # -1 + (-4) = -5\n        self.assertEqual(sum(-2, 5), 3)          # -2 + 5 = 3\n        self.assertEqual(sum(2.5, 3.4), 5.9)     # 2.5 + 3.4 = 5.9\n\n    def test_sum_types(self):\n        # ❌ Pruebas con valores incorrectos: deben lanzar error\n        with self.assertRaises(ValueError): sum(\"5\", 4)\n        with self.assertRaises(ValueError): sum(4, \"5\")\n        with self.assertRaises(ValueError): sum(\"4\", \"5\")\n        with self.assertRaises(ValueError): sum(4, \"a\")\n        with self.assertRaises(ValueError): sum(None, 5)\n\n'''\nExtra\n'''\n\n# ✅ Clase para comprobar la existencia de los campos y valores en nuestra data\nclass TestData(unittest.TestCase):\n\n    # 🔧 Este método se ejecuta antes de cada test\n    def setUp(self):\n        self.data = {\n            \"name\": \"Jesús García\",\n            \"age\": 41,\n            \"birth_date\": datetime.strptime(\"1984-03-25\", \"%Y-%m-%d\").date(),\n            \"programming_languages\": [\"Python\", \"JavaScript\", \"Java\"]\n        }\n\n    def test_if_data_field_exist(self):\n        # 🔍 Verifica si cada campo existe en el diccionario\n        self.assertIn(\"name\", self.data)\n        self.assertIn(\"age\", self.data)\n        self.assertIn(\"birth_date\", self.data)\n        self.assertIn(\"programming_languages\", self.data)\n\n    def test_if_data_value_is_correct(self):\n        # ✅ Verifica que cada campo tenga el tipo correcto\n        self.assertIsInstance(self.data[\"name\"], str)                # 👤 Nombre: texto\n        self.assertIsInstance(self.data[\"age\"], int)                 # 🔢 Edad: entero\n        self.assertIsInstance(self.data[\"birth_date\"], date)         # 📅 Fecha: tipo date\n        self.assertIsInstance(self.data[\"programming_languages\"], list)  # 💻 Lista de lenguajes\n\n\n# ▶️ Ejecuta todas las pruebas cuando se ejecuta el archivo directamente\nif __name__ == \"__main__\":\n    unittest.main()\n\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/jptxaya.py",
    "content": "# #13 PRUEBAS UNITARIAS\n## Ejercicio\n\n\n\"\"\" /*\n * EJERCICIO:\n * Crea una función que se encargue de sumar dos números y retornar\n * su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n * capaz de determinar si esa función se ejecuta correctamente.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\n */ \"\"\"\n\n\nfrom datetime import datetime\nimport unittest\n\ndef suma(num1, num2):\n    if not num1 or not num2:\n        raise ValueError(\"Los valores deben de tener valor\")\n    elif  not isinstance(num1,(int,float)) or not isinstance(num2,(int,float)):\n        raise ValueError(\"Los valores deben de ser enteros o float\")\n    return num1 + num2\n\nclass Suma(unittest.TestCase):\n    def test_suma(self):\n        self.assertEqual(suma(5,2),7)\n        self.assertEqual(suma(3,2.5),5.5)\n    \n    def test_inst_suma(self):\n        with self.assertRaises(ValueError):\n            suma(7,\"d\")\n        with self.assertRaises(ValueError):\n            suma(\"a\", 7)\n\n\n#Dificultad Extra\nclass TestExtra(unittest.TestCase):\n\n    def setUp(self):\n        self.my_dict = {\"name\": \"jptxaya\",\"age\":45,\"birth_date\":datetime(1975,4,3),\"programming_languages\":[\"react\",\"python\",\"java\"]}\n\n    def test_all_keys(self):\n        dic_keys = [\"name\",\"age\",\"birth_date\",\"programming_languages\"]\n        for dic_key in dic_keys:\n            self.assertIn(dic_key, self.my_dict.keys(),\"La clave {dic_key} no esta en el diccionario\")\n        \n    def test_correct_values(self):\n        self.assertIsInstance(self.my_dict.get(\"name\"),str,\"Tipo de dato no valido\")\n        self.assertIsInstance(self.my_dict.get(\"age\"),int,\"Tipo de dato no valido\")\n        self.assertIsInstance(self.my_dict.get(\"birth_date\"),datetime,\"Tipo de dato no valido\")\n        self.assertIsInstance(self.my_dict.get(\"programming_languages\"),list,\"Tipo de dato no valido\")\n        for language in self.my_dict.get(\"programming_languages\"):\n            self.assertIsInstance(language,str,\"Tipo de dato no valido\")\n\n\nif __name__ == '__main__':\n   unittest.main(verbosity=3)\n\n\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/juanchernandezdev.py",
    "content": "### Python Unit Testing ###\\\nimport unittest\n  \ndef sum(num1, num2):\n  return num1 + num2\n\n\nclass TestAddFunction(unittest.TestCase):\n  \n  def test_add(self):\n    self.assertEqual(sum(5, 5), 10)\n    self.assertEqual(sum(5, 3), 8)\n    self.assertEqual(sum(2, 2), 4)\n    self.assertEqual(sum(10, 45), 55)\n    self.assertEqual(sum(5, -5), 0)\n\n  def test_add_large_numbers(self):\n    self.assertEqual(sum(45000, 20000), 65000)\n\n    \n#! Optional Challenge\nmy_info = {\n  'name': 'John',\n  'age': 37,\n  'birth_date': '23/12/1986',\n  'programming_languages': ['JavaScript', 'Python']\n}\n\ndef get_info(info):\n  return info\n\nclass TestMyInfoDict(unittest.TestCase):\n  \n  def test_dict_fields(self):\n    fields = ['name', 'age', 'birth_date', 'programming_languages']\n    result = get_info(my_info)\n    \n    for field in fields:\n      self.assertTrue(field in result, f'Missing field: {field}')\n      \n  def test_dict_fields(self):\n    values = ['John', 37, '23/12/1986', ['JavaScript', 'Python']]\n    result = get_info(my_info)\n    for value in values:\n      self.assertTrue(value in result.values(), f'Value is not correct: {value}')\n    \nif __name__ == '__main__':\n    unittest.main()\n    "
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/juandaherrera.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Crea una función que se encargue de sumar dos números y retornar\n * su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n * capaz de determinar si esa función se ejecuta correctamente.\n\"\"\"\n\nimport unittest\nfrom typing import Union\n\n\ndef custom_sum(num1: Union[int, float], num2: Union[int, float]) -> Union[int, float]:\n    return num1 + num2\n\n\nclass TestCustomSum(unittest.TestCase):\n    def test_sum_positive_numbers(self):\n        result = custom_sum(5, 6)\n        self.assertEqual(result, 11)\n\n    def test_sum_negative_numbers(self):\n        result = custom_sum(-5, -6)\n        self.assertEqual(result, -11)\n\n    def test_sum_positive_and_negative_numbers(self):\n        result = custom_sum(-5, 6)\n        self.assertEqual(result, 1)\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\n\"\"\"\n\nmy_dict = {\n    \"name\": \"Juan David Herrera\",\n    \"age\": \"24\",\n    \"birth_date\": \"1999-12-05\",\n    \"programming_languages\": [\"Python\", \"Javascript\", \"VBA\", \"Bash\"],\n}\n\n\nclass TestCustomDict(unittest.TestCase):\n    def test_all_fields_exist(self):\n        required_fields = {\"name\", \"age\", \"birth_date\", \"programming_languages\"}\n        for field in required_fields:\n            self.assertTrue(\n                field in my_dict, f\"The custom dict has not have the required field: {field}\"\n            )\n\n    def test_correct_data(self):\n        correct_data = {\n            \"name\": \"Juan David Herrera\",\n            \"age\": \"24\",\n            \"birth_date\": \"1999-12-05\",\n            \"programming_languages\": [\"Python\", \"Javascript\", \"VBA\", \"Bash\"],\n        }\n        for key, item in correct_data.items():\n            self.assertEqual(\n                my_dict[key],\n                item,\n                f\"The value of {key} should be {item}. Your current value is: {my_dict[key]}\",\n            )\n\n\nif __name__ == '__main__':\n    unittest.main()\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/juanmax2.py",
    "content": "import unittest\nfrom datetime import datetime, date\n\"\"\"\nPruebas unitarias\n\"\"\"\n\n\ndef sumar(num1 : float, num2 : float):\n    if not isinstance(num1, (int, float)) or not isinstance(num2, (int, float)):\n        raise ValueError(\"Los argumentos deben ser enteros o decimales\")\n    return num1 + num2\n\nclass TestSumar(unittest.TestCase):\n\n\n    def test_sumar(self):\n        self.assertEqual(sumar(5, 7), 12)\n        self.assertEqual(sumar(5, -7), -2)\n        self.assertEqual(sumar(0, 0), 0)\n        self.assertEqual(sumar(2.5, 2.5), 5)\n        \n        with self.assertRaises(ValueError):\n            sumar(\"5\", 7)\n        with self.assertRaises(ValueError):\n            sumar(5, \"7\")\n        with self.assertRaises(ValueError):\n            sumar(\"5\", \"7\")\n\n# unittest.main()\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\n\"\"\"\n\nmy_dict = {\n    \"name\" : \"Juanma\",\n    \"age\" : 32,\n    \"birth_date\" : datetime.strptime(\"13-11-92\", \"%d-%m-%y\").date(),\n    \"programing_lenguages\" : [\"Python\", \"HTML\"]\n}\n\nclass TestData(unittest.TestCase):\n    \n    def setUp(self) -> None:\n        self.my_dict = {\n    \"name\" : \"Juanma\",\n    \"age\" : 32,\n    \"birth_date\" : datetime.strptime(\"13-11-92\", \"%d-%m-%y\").date(),\n    \"programing_lenguages\" : [\"Python\", \"HTML\"]\n}\n    def test_fields_exist(self):\n        self.assertIn(\"name\", self.my_dict)\n        self.assertIn(\"age\", self.my_dict)\n        self.assertIn(\"birth_date\", self.my_dict)\n        self.assertIn(\"programing_lenguages\", self.my_dict)\n        \n    def test_data_is_correct(self):\n        self.assertIsInstance(self.my_dict[\"name\"], str)\n        self.assertIsInstance(self.my_dict[\"age\"], int)\n        self.assertIsInstance(self.my_dict[\"birth_date\"], date)\n        self.assertIsInstance(self.my_dict[\"programing_lenguages\"], list)\n        \nunittest.main()"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/juanppdev.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Crea una función que se encargue de sumar dos números y retornar\n * su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n * capaz de determinar si esa función se ejecuta correctamente.\n\"\"\"\n\ndef sumar(a, b):\n    return a + b\n\nimport unittest\n\nclass TestSumar(unittest.TestCase):\n    def test_suma(self):\n        self.assertEqual(sumar(2, 3), 5)\n        self.assertEqual(sumar(-1, 1), 0)\n        self.assertEqual(sumar(0, 0), 0)\n\nif __name__ == '__main__':\n    unittest.main()\n\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\n\"\"\"\n\nimport unittest\n\ndatos_personales = {\n    \"name\": \"Juan Pablo\",\n    \"age\": 25,\n    \"birth_date\": \"1998-09-24\",\n    \"programming_languages\": [\"Python\", \"JavaScript\", \"C++\"]\n}\n\n\nclass TestDatosPersonales(unittest.TestCase):\n    def test_campos_existen(self):\n        self.assertIn(\"name\", datos_personales)\n        self.assertIn(\"age\", datos_personales)\n        self.assertIn(\"birth_date\", datos_personales)\n        self.assertIn(\"programming_languages\", datos_personales)\n\n    def test_datos_correctos(self):\n        self.assertEqual(datos_personales[\"name\"], \"Juan Pablo\")\n        self.assertEqual(datos_personales[\"age\"], 25)\n        self.assertEqual(datos_personales[\"birth_date\"], \"1998-09-24\")\n        self.assertEqual(datos_personales[\"programming_languages\"], [\"Python\", \"JavaScript\", \"C++\"])\n\nif __name__ == '__main__':\n    unittest.main()\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/juxxon23.py",
    "content": "'''\n ╔═════════════════════════════════════╗\n ║ Autor:  Juxxon23                    ║\n ║ GitHub: https://github.com/juxxon23 ║\n ║ Python - 2024                       ║\n ║ Reto 13 - PRUEBAS UNITARIAS         ║\n ╚═════════════════════════════════════╝\n'''\nimport unittest\nfrom datetime import date\n\n# ------------------------------------ Ejercicio 1 ------------------------------------\ndef sum(a, b):\n    '''\n    Crea una función que se encargue de sumar dos números y retornar su resultado.\n    '''\n    numtypes = (int, float)\n    res = a+b if isinstance(a,numtypes) and isinstance(b,numtypes) else None\n    return res\n\n\nclass TestSum(unittest.TestCase):\n    '''\n    Crea un test, utilizando las herramientas de tu lenguaje, que sea\n    capaz de determinar si esa función se ejecuta correctamente.\n    '''\n    def test_correct_sum(self):\n        # positive numbers\n        self.assertEqual(sum(2,5),7)\n        self.assertAlmostEqual(sum(4.3,8.1),12.4)\n        # positive and negative numbers\n        self.assertEqual(sum(-12,5),-7)\n        self.assertEqual(sum(8,-25),-17)\n        # negative numbers\n        self.assertEqual(sum(-3,-11),-14)\n        # zero numbers\n        self.assertTrue(sum(0,0) == 0)\n\n    def test_incorrect_sum(self):\n        self.assertNotEqual(sum(5, 5), 30)\n        self.assertNotEqual(sum(3, 4), 8)\n        self.assertNotEqual(sum(-1, 2), -10)\n        # boolean is a subclass of int\n        self.assertNotEqual(sum(True,17), None)\n        self.assertNotEqual(sum(3,False), None)\n        self.assertNotEqual(sum(True,True), None)\n    \n    def test_none_sum(self):\n        # string\n        self.assertIsNone(sum(\"a\",2))\n        self.assertIsNone(sum(25,\"+\"))\n        self.assertIsNone(sum(\"@\",\"v\"))\n\n# ------------------------------------ Ejercicio 2 ------------------------------------\ncharacter_details = {\n    \"name\": \"Juxxon23\",\n    \"age\": 28,\n    \"birth_date\": date(1995,5,14),\n    \"programming_languages\": [\"Python\", \"JavaScript\", \"Kotlin\", \"C-Lisp\", \"C\", \"C++\", \"Java\"]\n}\n\n\nclass TestCharacter(unittest.TestCase):\n    '''        \n    Crea dos test:\n    - Un primero que determine que existen todos los campos.\n    - Un segundo que determine que los datos introducidos son correctos.\n    '''\n    def  test_fields_exist(self):\n        character_fields = [\"name\", \"age\", \"birth_date\", \"programming_languages\"]\n        for field in character_fields:\n            self.assertIn(field, character_details, f'El campo {field} no se encuentra en los detalles del personaje')\n    \n    def test_correct_data(self):\n        self.assertIsInstance(character_details[\"name\"], str)\n        self.assertIsInstance(character_details[\"age\"], int)\n        self.assertIsInstance(character_details[\"birth_date\"], date)\n        self.assertIsInstance(character_details[\"programming_languages\"], list)\n        for lang in character_details[\"programming_languages\"]:\n            self.assertIsInstance(lang, str)\n\n    def test_correct_details(self):\n        self.assertEqual(character_details[\"name\"], \"Juxxon23\")\n        self.assertEqual(character_details[\"age\"], 28)\n        self.assertEqual(character_details[\"birth_date\"], date(1995,5,14))\n        self.assertListEqual(character_details[\"programming_languages\"], [\"Python\", \"JavaScript\", \"Kotlin\", \"C-Lisp\", \"C\", \"C++\", \"Java\"])\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/kenysdev.py",
    "content": "# ╔═════════════════════════════════════╗\n# ║ Autor:  Kenys Alvarado              ║\n# ║ GitHub: https://github.com/Kenysdev ║\n# ║ 2024 -  Python                      ║\n# ╚═════════════════════════════════════╝\n\n# -----------------------------------\n# * PRUEBAS UNITARIAS\n# -----------------------------------\n# - Verifican que las unidades individuales de código (como \n#   funciones, métodos o clases) funcionen como se espera.\n# - Mas info: https://ellibrodepython.com/python-testing\n\n#____________________________________\n# * EJERCICIO #1\n\"\"\"\n* Crea una función que se encargue de sumar dos números y retornar\n  su resultado.\n* Crea un test, utilizando las herramientas de tu lenguaje, que sea\n  capaz de determinar si esa función se ejecuta correctamente.\n\"\"\"\n\nimport unittest\n\ndef sum(a: float, b: float) -> float:\n    if isinstance(a, (int, float)) and isinstance(b, (int, float)):\n        return (a + b)\n    else:\n        return(None)\n    \nclass TestSum(unittest.TestCase):\n    def test_sum_correct(self):\n        self.assertEqual(sum(5, 2), 7)\n        self.assertEqual(sum(2.50, 1.25), 3.75)\n        self.assertEqual(sum(-2, 1), -1)\n        self.assertEqual(sum(0, 0), 0)\n\n    def test_sum_isNone(self):\n        self.assertIsNone(sum(1, \"2\"))\n        self.assertIsNone(sum(\"a\", \"b\"))\n\n    def test_sum_incorrect(self):\n        self.assertNotEqual(sum(1, 3), 5)\n\n    def test_sum_error_handling(self):\n        with self.assertRaises(TypeError):\n            sum(10)\n\n#____________________________________\n# * EJERCICIO #2\n\"\"\"\n* Crea un diccionario con las siguientes claves y valores:\n  - \"name\": \"Tu nombre\"\n  - \"age\": \"Tu edad\"\n  - \"birth_date\": \"Tu fecha de nacimiento\"\n  - \"programming_languages\": [\"Listado de lenguajes de programación\"]\n* Crea dos test:\n  - Un primero que determine que existen todos los campos.\n  - Un segundo que determine que los datos introducidos son correctos.\n\"\"\"    \n\ndict_user = {\n    \"name\": \"Ken\",\n    \"age\": 121,\n    \"birth_date\": \"1903-03-19\",\n    \"prog_langs\": [\"cs\", \"py\", \"vb\", \"rs\", \"js\"]\n}\n\nclass TestDict(unittest.TestCase):\n    def test_dic_key_existence(self):\n        self.assertIn(\"name\", dict_user)\n        self.assertIn(\"age\", dict_user)\n        self.assertIn(\"birth_date\", dict_user)\n        self.assertIn(\"prog_langs\", dict_user)\n    \n    def test_dic_value_types(self):\n        self.assertIsInstance(dict_user[\"name\"], str)\n        self.assertIsInstance(dict_user[\"age\"], int)\n        self.assertIsInstance(dict_user[\"birth_date\"], str)\n        self.assertIsInstance(dict_user[\"prog_langs\"], list)\n\n    def test_dic_value_content(self):\n        self.assertEqual(dict_user[\"name\"], \"Ken\")\n        self.assertEqual(dict_user[\"age\"], 121)\n        self.assertEqual(dict_user[\"birth_date\"], \"1903-03-19\")\n        self.assertListEqual(\n            dict_user[\"prog_langs\"], \n            [\"cs\", \"py\", \"vb\", \"rs\", \"js\"]\n        )\n        \nif __name__ == '__main__':\n    unittest.main(verbosity=2)\n\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/mhayhem.py",
    "content": "# @author: Mhayhem\n\nimport unittest\n\n# EJERCICIO:\n# Crea una función que se encargue de sumar dos números y retornar\n# su resultado.\n# Crea un test, utilizando las herramientas de tu lenguaje, que sea\n# capaz de determinar si esa función se ejecuta correctamente.\n\n\"\"\"fuction to sum two values and return the result\nargs: n1: int, n2: int\nreturns: int\n\"\"\"\ndef sum(n1, n2):\n    return n1 + n2\n\nclass TestAddition(unittest.TestCase):\n    def test_sum_func(self):\n        cases = [\n            (2, 3, 5),\n            (-2, 4, 2),\n            (-5, -6, -11),\n            (0.2, 0.3, 0.5)\n        ]\n        for n1, n2, expected in cases:\n            with self.subTest(n1=n1, n2=n2, expected=expected):\n                self.assertEqual(sum(n1, n2), expected)\n\n  \n\n\n# DIFICULTAD EXTRA (opcional):\n# Crea un diccionario con las siguientes claves y valores:\n# \"name\": \"Tu nombre\"\n# \"age\": \"Tu edad\"\n# \"birth_date\": \"Tu fecha de nacimiento\"\n# \"programming_languages\": [\"Listado de lenguajes de programación\"]\n# Crea dos test:\n# - Un primero que determine que existen todos los campos.\n# - Un segundo que determine que los datos introducidos son correctos.\n\nmy_dict = {\n    \"name\": \"Dany\",\n    \"age\": 42,\n    \"birth_date\": \"15/07/83\",\n    \"programing_languages\": [\"python\", \"javascript\"]\n}\n\nclass TestDict(unittest.TestCase):\n    def setUp(self):\n        self.my_dict = {\n            \"name\": \"Dany\",\n            \"age\": 42,\n            \"birth_date\": \"15/07/83\",\n            \"programing_languages\": [\"python\", \"javascript\"]\n        }\n    \n    def test_dict(self): \n        self.assertIn(\"name\", self.my_dict)\n        self.assertIn(\"age\",self.my_dict)\n        self.assertIn(\"birth_date\", self.my_dict)\n        self.assertIn(\"programing_languages\", self.my_dict)\n    \n    def test_correct_type(self):\n        self.assertIsInstance(self.my_dict[\"name\"], str) \n        self.assertIsInstance(self.my_dict[\"age\"], int)\n        self.assertIsInstance(self.my_dict[\"birth_date\"], str)\n        self.assertIsInstance(self.my_dict[\"programing_languages\"], list)\n\nunittest.main()"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/miguelex.py",
    "content": "from datetime import datetime, date\nimport unittest\n\ndef sum(a, b):\n    return a + b\n\nclass TestSum(unittest.TestCase):\n    def test_sum(self):\n        self.assertEqual(sum(5, 7), 12)\n        self.assertEqual(sum(5, -7), -2)\n        self.assertEqual(sum(0, 0), 0)\n        self.assertEqual(sum(2.5, 2.1), 4.6)\n        self.assertEqual(sum(2, 2.1), 4.1)\n        self.assertEqual(sum(2.5, 2.5), 5)\n\nclass TestData(unittest.TestCase):\n    def setUp (self):\n        self.data = {\n            \"name\": \"Miguelex\",\n            \"age\": 39,\n            \"birthdate\": datetime.strptime(\"03-09-75\", \"%d-%m-%y\").date(),\n            \"languages\": [\"PHP\", \"Javascript\", \"Java\"]\n        }\n        \n    def test_fields(self):\n        self.assertIn(\"name\", self.data)\n        self.assertIn(\"age\", self.data)\n        self.assertIn(\"birthdate\", self.data)\n        self.assertIn(\"languages\", self.data)\n      \n    def test_types(self):\n        self.assertIsInstance(self.data[\"name\"], str)\n        self.assertIsInstance(self.data[\"age\"], int)\n        self.assertIsInstance(self.data[\"birthdate\"], date)\n        self.assertIsInstance(self.data[\"languages\"], list)  \n          \nunittest.main()"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/mikelm2020.py",
    "content": "import unittest\nfrom datetime import date, datetime\n\n# Ejercicio\n\n\ndef sum(a: float, b: float):\n    if not isinstance(a, (float)) or not isinstance(b, (float)):\n        raise ValueError(\"Los argumentos deben ser decimales.\")\n    return a + b\n\n\nclass TestSum(unittest.TestCase):\n    def test_sum(self):\n        self.assertEqual(sum(3.7686, 9.10866), 12.87726)\n\n    def test_sum_type(self):\n        with self.assertRaises(ValueError):\n            sum(\"3.767\", 3.0)\n        with self.assertRaises(ValueError):\n            sum(6.456, \"1.23\")\n        with self.assertRaises(ValueError):\n            sum(\"2.894\", \"5.369\")\n        with self.assertRaises(ValueError):\n            sum(\"a\", 3.657)\n        with self.assertRaises(ValueError):\n            sum(None, 2.879)\n\n\n# Dificultad extra (opcional)\n\n\nclass TestData(unittest.TestCase):\n    def setUp(self) -> None:\n        self.professional_data = {\n            \"name\": \"Miguel Angel López Monroy\",\n            \"age\": 51,\n            \"birth_date\": datetime.strptime(\"28-09-1972\", \"%d-%m-%Y\").date(),\n            \"programming_languages\": [\"Python\", \"JavaScript\", \"C\"],\n        }\n\n    def test_fields_exist(self):\n        self.assertIn(\"name\", self.professional_data)\n        self.assertIn(\"age\", self.professional_data)\n        self.assertIn(\"birth_date\", self.professional_data)\n        self.assertIn(\"programming_languages\", self.professional_data)\n\n    def test_data_is_correct(self):\n        self.assertIsInstance(self.professional_data[\"name\"], str)\n        self.assertIsInstance(self.professional_data[\"age\"], int)\n        self.assertIsInstance(self.professional_data[\"birth_date\"], date)\n        self.assertIsInstance(self.professional_data[\"programming_languages\"], list)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/monicavaquerano.py",
    "content": "# 13 PRUEBAS UNITARIAS\n# Monica Vaquerano\n# https://monicavaquerano.dev\n\n\"\"\"\n * EJERCICIO:\n * Crea una función que se encargue de sumar dos números y retornar\n * su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n * capaz de determinar si esa función se ejecuta correctamente.\n\"\"\"\nimport unittest\nfrom datetime import datetime, date\n\n\ndef sumOfTwo(num1, num2):\n    if not isinstance(num1, (int, float)) or not isinstance(num2, (int, float)):\n        raise ValueError(\"Arguments must be a integers or decimals\")\n    return num1 + num2\n\n\nprint(sumOfTwo(2, 2))\n\n\nclass TestSumOfTwo(unittest.TestCase):\n    def test_sumOfTwo(self):\n        self.assertEqual(sumOfTwo(2, 2), 4)\n        self.assertEqual(sumOfTwo(-2, 5), 3)\n        self.assertEqual(sumOfTwo(0, 0), 0)\n        self.assertEqual(sumOfTwo(2.5, 2.5), 5)\n        self.assertEqual(sumOfTwo(5.5, 10), 15.5)\n\n    def test_sumOfTwo_type(self):\n        with self.assertRaises(ValueError):\n            sumOfTwo(\"5\", 5)\n        with self.assertRaises(ValueError):\n            sumOfTwo(2, \"5\")\n        with self.assertRaises(ValueError):\n            sumOfTwo(\"2\", \"5\")\n        with self.assertRaises(ValueError):\n            sumOfTwo(\"a\", 8)\n        with self.assertRaises(ValueError):\n            sumOfTwo(7, None)\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\n */\n\"\"\"\n\ndata = {\n    \"name\": \"Monica Vaquerano\",\n    \"age\": 35,\n    \"birth_date\": datetime.strptime(\"01-01-01\", \"%d-%m-%y\").date(),  # date object\n    \"programming_languages\": [\"python\", \"javascript\", \"php\"],\n}\n\n\nclass TestData(unittest.TestCase):\n\n    def setUp(self) -> None:\n        self.data = {\n            \"name\": \"Monica Vaquerano\",\n            \"age\": 35,\n            \"birth_date\": datetime.strptime(\n                \"01-01-01\", \"%d-%m-%y\"\n            ).date(),  # date object\n            \"programming_languages\": [\"python\", \"javascript\", \"php\"],\n        }\n\n    def test_fields_exist(self):\n        self.assertIn(\"name\", self.data)\n        self.assertIn(\"age\", self.data)\n        self.assertIn(\"birth_date\", self.data)\n        self.assertIn(\"programming_languages\", self.data)\n\n    def test_data_is_correct(self):\n        self.assertIsInstance(self.data[\"name\"], str)\n        self.assertIsInstance(self.data[\"age\"], int)\n        self.assertIsInstance(self.data[\"birth_date\"], date)\n        self.assertIsInstance(self.data[\"programming_languages\"], list)\n\n\nunittest.main()\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/mouredev.py",
    "content": "import unittest\nfrom datetime import datetime, date\n\n\"\"\"\nEjercicio\n\"\"\"\n\n\ndef sum(a, b):\n    if not isinstance(a, (int, float)) or not isinstance(b, (int, float)):\n        raise ValueError(\"Los argumentos deben ser enteros o decimales.\")\n    return a + b\n\n\nclass TestSum(unittest.TestCase):\n\n    def test_sum(self):\n        self.assertEqual(sum(5, 7), 12)\n        self.assertEqual(sum(5, -7), -2)\n        self.assertEqual(sum(0, 0), 0)\n        self.assertEqual(sum(2.5, 2.1), 4.6)\n        self.assertEqual(sum(2, 2.1), 4.1)\n        self.assertEqual(sum(2.5, 2.5), 5)\n\n    def test_sum_type(self):\n        with self.assertRaises(ValueError):\n            sum(\"5\", 7)\n        with self.assertRaises(ValueError):\n            sum(5, \"7\")\n        with self.assertRaises(ValueError):\n            sum(\"5\", \"7\")\n        with self.assertRaises(ValueError):\n            sum(\"a\", 7)\n        with self.assertRaises(ValueError):\n            sum(None, 7)\n\n\n\"\"\"\nExtra\n\"\"\"\n\n\nclass TestData(unittest.TestCase):\n\n    def setUp(self) -> None:\n        self.data = {\n            \"name\": \"Brais Moure\",\n            \"age\": 36,\n            \"birth_date\": datetime.strptime(\"29-04-87\", \"%d-%m-%y\").date(),\n            \"programming_languages\": [\"Python\", \"Kotlin\", \"Swift\"]\n        }\n\n    def test_fields_exist(self):\n        self.assertIn(\"name\", self.data)\n        self.assertIn(\"age\", self.data)\n        self.assertIn(\"birth_date\", self.data)\n        self.assertIn(\"programming_languages\", self.data)\n\n    def test_data_is_correct(self):\n        self.assertIsInstance(self.data[\"name\"], str)\n        self.assertIsInstance(self.data[\"age\"], int)\n        self.assertIsInstance(self.data[\"birth_date\"], date)\n        self.assertIsInstance(self.data[\"programming_languages\"], list)\n\n\nunittest.main()\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/mrodara.py",
    "content": "###################################  TESTS UNITARIOS  #############################################\n\n'''\nEl módulo unittest ofrece una estructura sencilla para definir casos de prueba. \nUn caso de prueba es una pequeña unidad de verificación (normalmente una función) \nque evalúa si una porción del código se comporta como se espera.\n'''\n\n'''\nEstructura básica de una prueba unitaria.\n 1.Importar el módulo unittest.\n 2.Crear una clase que herede de unittest.TestCase.\n 3.Escribir métodos de prueba dentro de esta clase.\n 4.Ejecutar las pruebas utilizando unittest.main().\n'''\n\nimport unittest #1\n\ndef suma (a: int = 0, b:int = 0):\n    \n    if not isinstance(a, (int, float)) or not isinstance(b, (int, float)):\n        raise ValueError(\"Los parámetros de entrada deben ser enteros o decimales\")\n    \n    return a + b\n\nclass test_suma(unittest.TestCase): #2\n    \n    def test_suma(self): #3\n        self.assertEqual(suma(2,3),5)\n        self.assertEqual(suma(-1,1), 0)\n        self.assertEqual(suma(1.1, 1.1), 2.2)\n    \n    def test_suma_type(self):\n        with self.assertRaises(ValueError):\n            suma('3', 1)\n        with self.assertRaises(ValueError):\n            suma(1, '4')\n        with self.assertRaises(ValueError):\n            suma('3', '4')\n        with self.assertRaises(ValueError):\n            suma(None, 1)\n        with self.assertRaises(ValueError):\n            suma(1, None)\n                \n        \n\nif __name__ == \"__main__\":\n    unittest.main() #4\n    \n    \n###################################  EJERCICIO EXTRA  #############################################\n\nimport unittest\nfrom datetime import datetime, date\n\nuser = {\n    \"name\" : \"Manuel J. Rodríguez\",\n    \"age\" : 44,\n    \"birth_date\" : \"03/01/1980\",\n    \"programming_languages\" : [\"Python\", \"PHP\", \"Java\", \"C++\"]\n}\n\nmy_list = [data for data in user.keys()]\n\nclass test_dict(unittest.TestCase):\n    \n    def test_dict_keys(self):\n        data_keys = [\"name\", \"age\", \"birth_date\", \"programming_languages\"]\n        self.assertListEqual(list(user.keys()), data_keys)\n    \n    def test_dict_data(self):\n        self.assertIsInstance(user['name'], str)\n        self.assertIsInstance(user['age'], int)\n        self.assertIsInstance(user['birth_date'], str)\n        self.assertIsInstance(user['programming_languages'], list)\n        \nif __name__ == \"__main__\":\n    unittest.main()\n###################################  FIN EJERCICIO EXTRA  #############################################\n    \n\n###################################  FIN TESTS UNITARIOS  #############################################"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/mvidalb.py",
    "content": "import unittest\nfrom datetime import datetime, date\n\n'''\nEjercicio\n'''\n\ndef suma(a, b) -> float:\n    if not isinstance(a, (int, float)) or not isinstance(b, (int, float)):\n        raise ValueError(\"Los argumentos deben ser enteros o decimales.\")\n    return a + b\n\n\nclass TestSum(unittest.TestCase):\n\n    def test_sum(self):  # 'test_' es imprescindible\n        self.assertEqual(suma(5, 5), 10)\n        self.assertEqual(suma(5, -7), -2)\n        self.assertEqual(suma(0, 0), 0)\n        self.assertEqual(suma(2.5, 2.1), 4.6)\n        self.assertEqual(suma(2, 2.1), 4.1)\n        self.assertEqual(suma(2.5, 2.5), 5)\n    \n    def test_sum_type(self):  # 'test_' es imprescindible\n        with self.assertRaises(ValueError):\n            suma(\"5\", 2)\n        with self.assertRaises(ValueError):\n            suma(5, \"7\")\n        with self.assertRaises(ValueError):\n            suma(\"5\", \"7\")\n        with self.assertRaises(ValueError):\n            suma(None, 7)\n        with self.assertRaises(ValueError):\n            suma(\"a\", 2)\n\n\n'''\nEjercicio extra\n'''\n\nclass TestData(unittest.TestCase):\n\n    def setUp(self) -> None:  # Función específica para preparar lo que se va a testar\n        self.data ={\n            \"name\": \"Mario\",\n            \"age\" : 40,\n            \"birth_date\" : datetime.strptime(\"01-01-20\", \"%d-%m-%y\").date(),\n            \"programming_langues\":[\"Python\", \"#C\"]\n        }\n\n    def test_fields_exist(self):   # 'test_' es imprescindible\n        self.assertIn(\"name\", self.data)\n        self.assertIn(\"age\", self.data)\n        self.assertIn(\"birth_date\", self.data)\n        self.assertIn(\"programming_langues\", self.data)\n\n    def test_data_is_correct(self):  # 'test_' es imprescindible\n        self.assertIsInstance(self.data[\"name\"], str)\n        self.assertIsInstance(self.data[\"age\"], int)\n        self.assertIsInstance(self.data[\"birth_date\"], date)\n        self.assertIsInstance(self.data[\"programming_langues\"],list)\n\n\nunittest.main()  # Ejecuta todos los métodos que comienzan por 'test_' (necesita estar dentro de una clase)\n\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/neslarra.py",
    "content": "\"\"\"\n Crea una función que se encargue de sumar dos números y retornar\n su resultado.\n Crea un test, utilizando las herramientas de tu lenguaje, que sea\n capaz de determinar si esa función se ejecuta correctamente.\n\n DIFICULTAD EXTRA (opcional):\n Crea un diccionario con las siguientes claves y valores:\n \"name\": \"Tu nombre\"\n \"age\": \"Tu edad\"\n \"birth_date\": \"Tu fecha de nacimiento\"\n \"programming_languages\": [\"Listado de lenguajes de programación\"]\n Crea dos test:\n - Un primero que determine que existen todos los campos.\n - Un segundo que determine que los datos introducidos son correctos.\n\"\"\"\n\nprint(f\"== Explicación {'=' * 30}\\n\")\n\nprint(f\"\"\"\nimport unittest\nfrom datetime import datetime\n\n# Creo una función sumar que suma dos números PERO devuelve \"raise\" si alguna de las entradas NO es numérica.\ndef sumar(num1, num2):\n    if not all([bool(x.__class__.__name__ in ('int', 'float')) for x in (num1, num2)]):\n        raise ValueError(\"Todos los argumentos deben ser numéricos.\")\n    return num1 + num2\n\n# Creo una clase TestSumar (\"Test\" DEBE ser el prefijo) la cual hereda de unitest.TestCase\nclass TestSumar(unittest.TestCase):\n\n    # Creo una función que realice los test que deben salir OK (\"test_\" DEBE ser el prefijo).\n    def test_sumar_returns(self):\n        self.assertEqual(sumar(1, 1), 2)\n        self.assertEqual(sumar(1, -1), 0)\n        self.assertEqual(sumar(-1, -1), -2)\n        self.assertEqual(sumar(1.5, 0.5), 2)\n        self.assertEqual(sumar(1, -1.5), -0.5)\n\n    # Creo una función que realice los test que salen por \"raise\" (\"test_\" DEBE ser el prefijo).\n    def test_sumar_raises(self):\n        with self.assertRaises(ValueError):\n            sumar(\"a\", 1)\n        with self.assertRaises(ValueError):\n            sumar(\"1\", 1)\n        with self.assertRaises(ValueError):\n            sumar(\"1\", \"1\")\n        with self.assertRaises(ValueError):\n            sumar(\"\", 1)\n\n# Ejecuto unitest.main() que automáticamente correrá todas los tests declaradas.\nif __name__ == '__main__':\n    unittest.main()\n\n# Devuelve\nRan 2 tests in 0.009s\n\nOK\n\nSi alguno de los test no ejecutara OK, entonces devolvería AssertionError indicando cuál falló.\n\n\"\"\")\n\nprint(f\"== Dificultad Extra {'=' * 30}\\n\")\n\nimport unittest\nfrom datetime import datetime\n\nmi_data = {\"nombre\": \"neslarra\", \"edad\": 59, \"fecha_nacimiento\": datetime(1965, 3, 23), \"lenguajes\": [\"python\", \"sql\", \"bash\"]}\n\n\nclass TestMiData(unittest.TestCase):\n\n    def test_keys(self):\n        claves = mi_data.keys()\n        self.assertTrue(\"nombre\" in claves)\n        self.assertTrue(\"edad\" in claves)\n        self.assertTrue(\"fecha_nacimiento\" in claves)\n        self.assertTrue(\"lenguajes\" in claves)\n\n    def test_values_type(self):\n        self.assertIsInstance(mi_data[\"nombre\"], str)\n        self.assertIsInstance(mi_data[\"edad\"], int)\n        self.assertIsInstance(mi_data[\"fecha_nacimiento\"], datetime)\n        self.assertIsInstance(mi_data[\"lenguajes\"], list)\n\n# Ejecuto unitest.main() que automáticamente correrá todas los tests declaradas.\nif __name__ == '__main__':\n    unittest.main()\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/nlarrea.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Crea una función que se encargue de sumar dos números y retornar\n * su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n * capaz de determinar si esa función se ejecuta correctamente.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\n\"\"\"\n\nimport unittest\n\n\ndef sum_two_numbers(num_one, num_two):\n    if not num_one or not num_two:\n        raise ValueError(\"You must enter two numbers.\")\n\n    if not isinstance(num_one, (int, float)) or not isinstance(\n        num_two, (int, float)\n    ):\n        raise TypeError(\"The received numbers must be integers or floats.\")\n\n    return num_one + num_two\n\n\nclass TestSumTwoNumbers(unittest.TestCase):\n    def test_return_value(self):\n        self.assertEqual(sum_two_numbers(2, 3), 5)\n        self.assertEqual(sum_two_numbers(2, -3), -1)\n\n    def test_return_type(self):\n        self.assertIsInstance(sum_two_numbers(2, 3), int)\n        self.assertIsInstance(sum_two_numbers(3, 0.14), float)\n\n    def test_raising_errors(self):\n        with self.assertRaises(TypeError):\n            sum_two_numbers(2, \"3\")\n        with self.assertRaises(TypeError):\n            sum_two_numbers(\"2\", 3)\n        with self.assertRaises(ValueError):\n            sum_two_numbers(None, 5)\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\n\"\"\"\n\n\nfrom datetime import datetime, date\n\n\nclass TestDictionary(unittest.TestCase):\n    def setUp(self) -> None:\n        self.my_dict = {\n            \"name\": \"Naia\",\n            \"age\": 25,\n            \"birth_date\": datetime.strptime(\"1994-02-09\", \"%Y-%m-%d\").date(),\n            \"programming_languages\": [\"Python\", \"JavaScript\", \"C++\"],\n        }\n\n    def test_dict_keys(self):\n        self.assertEqual(len(self.my_dict), 4)\n        self.assertIn(\"name\", self.my_dict)\n        self.assertIn(\"age\", self.my_dict)\n        self.assertIn(\"birth_date\", self.my_dict)\n        self.assertIn(\"programming_languages\", self.my_dict)\n\n    def test_dict_data(self):\n        self.assertIsInstance(self.my_dict[\"name\"], str)\n        self.assertIsInstance(self.my_dict[\"age\"], int)\n        self.assertIsInstance(self.my_dict[\"birth_date\"], date)\n        self.assertIsInstance(self.my_dict[\"programming_languages\"], list)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/oniricoh.py",
    "content": "###############################################################################\n## EJERCICIO\n###############################################################################\nimport unittest\n\n\ndef add(x:int, y:int) ->int:\n    return x + y\n\n\nclass tests(unittest.TestCase):\n    def test_add(self):\n        result = add(3,2)\n        self.assertEqual(result, 5)\n    def test_add2(self):\n        result = add(3,3)\n        self.assertEqual(result, 6)\n\nif __name__ == '__main__':\n    unittest.main()\n    \n\n\n###############################################################################\n## DIFICULTAD EXTRA\n###############################################################################\nimport unittest\n\ndictionary = {\n    \"name\": \"Daniel San\",\n    \"age\": 35,\n    \"birth_date\": \"04-04-1989\",\n    \"programming_languages\": [\"Python\", \"SQL\", \"CSS\", \"JavaScript\"]\n}\n       \n\nclass Tests(unittest.TestCase):\n    def test_every_field(self):\n        self.assertEqual(True if dictionary[\"name\"] else False, True)\n        self.assertEqual(True if dictionary[\"age\"] else False, True)\n        self.assertEqual(True if dictionary[\"birth_date\"] else False, True)\n        self.assertEqual(True if dictionary[\"programming_languages\"] else False, True)\n        \n    def test_type_field(self):\n        self.assertEqual(type(dictionary[\"name\"]), str)\n        self.assertEqual(type(dictionary[\"age\"]), int)\n        self.assertEqual(type(dictionary[\"birth_date\"]), str)\n        self.assertEqual(type(dictionary[\"programming_languages\"]), list)\n\n\nif __name__ == '__main__':\n    unittest.main()\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/oriaj3.py",
    "content": "\"\"\"\t\n13 - PRUEBAS UNITARIAS\nAutor de la solución: Oriaj3\t\nTeoría:\t\nLas pruebas unitarias son una técnica de programación que consiste en crear\npequeños fragmentos de código que verifican el correcto funcionamiento de\notro fragmento de código. Estos fragmentos de código se conocen como tests.\n\nLas pruebas unitarias son una parte fundamental de la metodología de\ndesarrollo ágil, ya que permiten detectar errores de forma temprana y\nasegurar que los cambios realizados en el código no afecten su funcionamiento.\n\nEn la mayoría de los lenguajes de programación, existen herramientas y\nbibliotecas que facilitan la creación y ejecución de pruebas unitarias.\nEstas herramientas permiten definir los tests, ejecutarlos y verificar\nque el código se comporta como se espera.\n\nEn Python, una de las bibliotecas más utilizadas para realizar pruebas\nunitarias es unittest. Esta biblioteca proporciona una serie de clases\ny métodos que permiten crear y ejecutar tests de forma sencilla.\n\"\"\"\nimport unittest\nfrom datetime import datetime, date\n\n\"\"\"\n/*\n * EJERCICIO:\n * Crea una función que se encargue de sumar dos números y retornar\n * su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n * capaz de determinar si esa función se ejecuta correctamente.\n *\n\"\"\"\ndef sumar2(a: int, b: int) -> int:\n    \"\"\"\n    Suma dos números y devuelve el resultado.\n    \"\"\"\n    return a + b\n\n# Clase de pruebas unitarias para la función sumar2\nclass TestSumar(unittest.TestCase):\n    \n        # Prueba para verificar la suma de números positivos\n        def test_suma_positiva(self):\n            \"\"\"\n            Prueba la suma de números positivos.\n            \"\"\"\n            self.assertEqual(sumar2(5, 5), 10)\n    \n        # Prueba para verificar la suma de números positivos y negativos\n        def test_sume_negativa(self):\n            \"\"\"\n            Prueba la suma de un número positivo y otro negativo.\n            \"\"\"\n            self.assertEqual(sumar2(-1, -5), -6)\n            \n        # Prueba para verficiar la suma de un número positivo y otro negativo\n        def test_suma_positiva_negativa(self):\n            \"\"\"\n            Prueba la suma de un número positivo y otro negativo.\n            \"\"\"\n            self.assertEqual(sumar2(5, -5), 0)\n        \n        # Prueba para verificar la suma de 0 con 0 \n        \n        \n\"\"\" \n * DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\n */\n\"\"\"\n\n# Diccionario con los datos personales\ndatos_personales = {\n    \"name\": \"Jairo\",\n    \"age\": 24,\n    \"birth_date\": datetime.strptime(\"01-03-93\", \"%d-%m-%y\").date(),\n    \"programming_languages\": [\"Python\", \"Java\", \"C++\"],\n}\n\n# Clase de pruebas unitarias para los datos personales\nclass TestDatosPersonales(unittest.TestCase):\n    #Prueba para verificar que existen todos los campos\n    def test_campos(self):\n        \"\"\"\n        Prueba que existen todos los campos en el diccionario.\n        \"\"\"\n        self.assertIn(\"name\", datos_personales)\n        self.assertIn(\"age\", datos_personales)\n        self.assertIn(\"birth_date\", datos_personales)\n        self.assertIn(\"programming_languages\", datos_personales)\n    \n    def test_datos_correctos(self):\n        \"\"\"\n        Prueba que los datos introducidos son correctos.\n        \"\"\"\n        self.assertIsInstance(datos_personales[\"name\"], str)\n        self.assertIsInstance(datos_personales[\"age\"], int)\n        self.assertIsInstance(datos_personales[\"birth_date\"], date)\n        self.assertIsInstance(datos_personales[\"programming_languages\"], list)\n        for language in datos_personales[\"programming_languages\"]:\n            self.assertIsInstance(language, str)\n        \n# Ejecutar las pruebas unitarias\nif __name__ == '__main__':\n    unittest.main()"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/pyramsd.py",
    "content": "# Correr en consola:\n# pytest pyramsd.py\n\ndef suma_nums(a, b):\n    return a + b\n\n\ndef test_sumas():\n        assert suma_nums(1, 2) == 3\n        assert suma_nums(-1, 4) == 3\n        assert suma_nums(4, -7) == -3\n        assert suma_nums(-4, -3) == -7\n        assert suma_nums(1.5, 1.5) == 3\n\n\n'''\nEXTRA\n'''\n\ndef diccionario(name, age, birth_date, programming_languages):\n      return dict(name=name, age=age, birth_date=birth_date, programming_languages=programming_languages)\n\n\ndef test_existen_campos():\n      datos = diccionario('Sergio', 18, '07/12/2005', ['Python', 'Java', 'C++'])\n      assert 'name' in datos\n      assert 'age' in datos\n      assert 'birth_date' in datos\n      assert 'programming_languages' in datos\n\ndef test_datos_correctos():\n      name = 'Sergio'\n      age = 18\n      birth_date = '07/12/2005'\n      programming_languages = ['Python', 'Java', 'C++']\n      datos = diccionario('Sergio', 18, '07/12/2005', ['Python', 'Java', 'C++'])\n      assert datos['name'] == name\n      assert datos['age'] == age\n      assert datos['birth_date'] == birth_date\n      assert datos['programming_languages'] == programming_languages\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/qwik-zgheib.py",
    "content": "# -- exercise\ndef sum_numbers(a: int, b: int) -> int:\n    return a + b\n\n\n# -- extra challenge\nclass DataDict:\n    def __init__(\n        self,\n        name: str,\n        age: int,\n        birth_date: str,\n        programming_languages: list[str] = [],\n    ) -> None:\n        self.name = name\n        self.age = age\n        self.birth_date = birth_date\n        self.programming_languages = programming_languages\n\n    def get_values_dict(self) -> dict:\n        return {\n            \"name\": self.name,\n            \"age\": self.age,\n            \"birth_date\": self.birth_date,\n            \"programming_languages\": self.programming_languages,\n        }\n\n\n# -- test\n\"\"\"\ncrate a file named tests.py and add the following code\nrun the tests by executing `python tests.py` or `python -m unittest tests.py`\n\"\"\"\nfrom main import sum_numbers, DataDict\nimport unittest\n\n\nclass TestSumNumbers(unittest.TestCase):\n    def test_sum_numbers(self):\n        self.assertEqual(sum_numbers(1, 2), 3)\n        self.assertEqual(sum_numbers(2, 2), 4)\n        self.assertEqual(sum_numbers(3, 3), 6)\n        self.assertEqual(sum_numbers(4, 4), 8)\n        self.assertEqual(sum_numbers(5, 5), 10)\n\n\nclass TestDataDict(unittest.TestCase):\n    data = DataDict(\n        name=\"qwik\",\n        age=22,\n        birth_date=\"00/11/2002\",\n        programming_languages=[\"Python\", \"JavaScript\", \"TypeScript\"],\n    )\n\n    def test_data_dict(self):\n        self.assertEqual(\n            self.data.get_values_dict(),\n            {\n                \"name\": \"qwik\",\n                \"age\": 22,\n                \"birth_date\": \"00/11/2002\",\n                \"programming_languages\": [\"Python\", \"JavaScript\", \"TypeScript\"],\n            },\n        )\n\n    def test_data_dict_values(self):\n        self.assertEqual(self.data.name, \"qwik\")\n        self.assertEqual(self.data.age, 22)\n        self.assertEqual(self.data.birth_date, \"00/11/2002\")\n        self.assertEqual(\n            self.data.programming_languages, [\"Python\", \"JavaScript\", \"TypeScript\"]\n        )\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/rantamhack.py",
    "content": "'''\n * EJERCICIO:\n * Crea una funcion que se encargue de sumar dos numeros y retornar\n * su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n * capaz de determinar si esa funcion se ejecuta correctamente.\n '''\n\nimport unittest\n\ndef sum(num1, num2):\n    return num1 + num2\n\nclass TestSum(unittest.TestCase):\n\n    def test_sum(self):\n        self.assertEqual(sum(4, 2), 6)\n        self.assertEqual(sum(-4, 2), -2)\n        self.assertEqual(sum(4, -2), 2)\n        self.assertEqual(sum(2.3, 4.7), 7.0)\n\n#unittest.main()\n\n\n'''\n * DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programaciÃ³n\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\n'''\n\ndata = {\"name\" : \"rantam\",\n           \"age\" : 15,\n           \"birth_date\" : \"15-04\",\n           \"programming_languages\" : [\"Python\", \"Bash\", \"Java\"]\n           }\n\nclass TestData(unittest.TestCase):\n    \n    def setUp(self) -> None:\n        self.data = { \n            \"name\" : \"rantam\",\n            \"age\" : 15,\n            \"birth_date\" : \"15-04\",\n            \"programming_languages\" : [\"Python\", \"Bash\", \"Java\"]\n           }\n        \n    \n    def test_fields(self):\n        self.assertIn(\"name\", self.data)\n        self.assertIn(\"age\", self.data)\n        self.assertIn(\"birth_date\", self.data)\n        self.assertIn(\"programming_languages\", self.data)\n        \n    def test_data(self):\n        self.assertIsInstance(self.data[\"name\"], str)\n        self.assertIsInstance(self.data[\"age\"], int)\n        self.assertIsInstance(self.data[\"birth_date\"], str)\n        self.assertIsInstance(self.data[\"programming_languages\"], list)\n        \n    \n    \nif __name__ == '__main__':\n    unittest.main()\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/raulG91.py",
    "content": "import unittest\n\n\ndef sumar(a,b):\n    return a+b\n\nclass TestSumar(unittest.TestCase):\n\n    def testSumar(self):\n        self.assertEqual(sumar(1,2),3)\n        self.assertEqual(sumar(2.0,3.0),5.0)\n\n#Extra\n        \nmy_dict = {\n    \"name\":\"Raul\",\n    \"age\": 32,\n    \"birth_date\":\"11/09/1991\",\n    \"programming_languages\":[\"Python\",\"Javascript\",\"Abap\"]\n}\n\nclass TestDictionary(unittest.TestCase):\n\n    def testKeys(self):\n        self.assertIn(\"name\",my_dict.keys())\n        self.assertIn(\"age\",my_dict.keys())\n        self.assertIn(\"birth_date\",my_dict.keys())\n        self.assertIn(\"programming_languages\",my_dict.keys())\n        self.assertNotIn(\"email\",my_dict.keys())\n    def testData(self):\n        self.assertTrue(type(my_dict[\"name\"])== str)\n        self.assertTrue(type(my_dict[\"age\"]) == int)\n        self.assertTrue(type(my_dict[\"birth_date\"])==str)\n        self.assertTrue(type(my_dict[\"programming_languages\"])==list)\n\nif __name__ == \"__main__\":\n    unittest.main()        "
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/raynerpv2022.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * Crea una función que se encargue de sumar dos números y retornar\n#  * su resultado.\n#  * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n#  * capaz de determinar si esa función se ejecuta correctamente.\n#  *\n\n\n\nimport unittest \nimport datetime\n \ndef sum_number(a,b):\n    return a+b\n\nclass TestSUma(unittest.TestCase):\n\n    def test_suma_mia1(self):\n        self.assertEqual(sum_number(12,2),14)\n\n    def test_suma_mia2(self):\n        self.assertEqual(sum_number(2.1,1),3.1)\n    \n    def test_suma_mia3(self):\n        self.assertEqual(sum_number(-30,1),-29)\n\n\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea un diccionario con las siguientes claves y valores:\n#  * \"name\": \"Tu nombre\"\n#  * \"age\": \"Tu edad\"\n#  * \"birth_date\": \"Tu fecha de nacimiento\"\n#  * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n#  * Crea dos test:\n#  * - Un primero que determine que existen todos los campos.\n#  * - Un segundo que determine que los datos introducidos son correctos.\n#  */\n\n \n\n\nclass TestDev(unittest.TestCase):\n   \n    def setUp(self):\n         self.case = [\n    {\n        \"name\": \"Alice\",\n        \"age\": 25,\n        \"birth_date\": datetime.datetime.strptime(\"15-06-1997\",\"%d-%m-%Y\").date(),\n        \"programming_languages\": [\"Python\", \"C++\", \"Rust\"]\n    },\n    {\n        \"name\": \"Bob\",\n        \"age\": 30,\n        \"birth_date\": datetime.datetime.strptime(\"15-06-1997\",\"%d-%m-%Y\").date(),\n        \"programming_languages\": [\"JavaScript\", \"Ruby\"]\n    },\n    {\n        \"name\": \"Charlie\",\n        \"age\": 22,\n        \"birth_date\": datetime.datetime.strptime(\"15-06-1997\",\"%d-%m-%Y\").date(),\n        \"programming_languages\": []\n    }\n]\n         \n         self.keys = [\"name\",\"age\", \"birth_date\", \"programming_languages\"]\n         \n   \n    \n    def test_fields(self):\n        \n        for dev  in self.case:\n            for k in self.keys:\n                self.assertIn(k,dev,\"f{k} not Present in Dict\")\n\n    def test_validate_field(self):\n            for dev  in self.case:\n                self.assertIsInstance(dev[\"name\"],str)\n                self.assertIsInstance(dev[\"age\"],int)\n                self.assertIsInstance(dev[\"birth_date\"],datetime.date)\n                self.assertIsInstance(dev[\"programming_languages\"],list)\n                for l in dev[\"programming_languages\"]:\n                    self.assertIsInstance(l, str)\n\n\nunittest.main()"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/restevean.py",
    "content": "\"\"\"\nEjercicio\n\"\"\"\nimport unittest\n\n\ndef my_sum(a: int, b: int) -> int:\n    return a + b\n\n\nclass TestSumFunction(unittest.TestCase):\n    def test_sum_two_positives(self):\n        self.assertEqual(my_sum(3, 2), 5, \"Should be 5\")\n\n    def test_sum_two_negatives(self):\n        self.assertEqual(my_sum(-1, -1), -2, \"Should be -2\")\n\n    def test_sum_positive_and_negative(self):\n        self.assertEqual(my_sum(-5, 5), 0, \"Should be 0\")\n\n    def test_sum_with_zero(self):\n        self.assertEqual(my_sum(0, 5), 5, \"Should be 5\")\n        self.assertEqual(my_sum(0, -5), -5, \"Should be -5\")\n\n\n\"\"\"\nExtra\n\"\"\"\n\n\n# Define el diccionario con los datos personales\npersonal_info = {\n    \"name\": \"John\",\n    \"age\": \"35\",\n    \"birth_date\": \"20/05/1990\",\n    \"programming_languages\": [\"Python\", \"Clipper 5.2\"]\n}\n\n\n# Clase para los tests unitarios\nclass TestPersonalInfo(unittest.TestCase):\n    # Test para verificar la existencia de todos los campos\n    def test_fields_existence(self):\n        self.assertIn(\"name\", personal_info)\n        self.assertIn(\"age\", personal_info)\n        self.assertIn(\"birth_date\", personal_info)\n        self.assertIn(\"programming_languages\", personal_info)\n\n    # Test para verificar que los datos son correctos\n    def test_data_correctness(self):\n        self.assertEqual(personal_info[\"name\"], \"John\")\n        self.assertEqual(personal_info[\"age\"], \"35\")\n        self.assertEqual(personal_info[\"birth_date\"], \"20/05/1990\")\n        self.assertListEqual(personal_info[\"programming_languages\"], [\"Python\", \"Clipper 5.2\"])\n\n\n# Ejecutar los tests si se ejecuta el script directamente\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/rigo93acosta.py",
    "content": "'''\n * EJERCICIO:\n * Crea una función que se encargue de sumar dos números y retornar\n * su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n * capaz de determinar si esa función se ejecuta correctamente.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\n'''\nimport unittest\n\n'''\nEjercicio\n'''\n\ndef suma(a, b):\n    if not isinstance(a, (int, float)) or not isinstance(b, (int, float)):\n        raise ValueError(\"Los valores deben ser numéricos.\")\n    return a + b\n\nclass TestSuma(unittest.TestCase):\n    \n    def test_suma(self):\n        self.assertEqual(suma(1, 2), 3)\n        self.assertEqual(suma(2, 3), 5)\n        self.assertEqual(suma(3.2, 4), 7.2)\n    \n    def test_suma_type(self):\n        with self.assertRaises(ValueError):\n            suma(\"5\", 2)\n        with self.assertRaises(ValueError):\n            suma(5, \"2\")\n        with self.assertRaises(ValueError):\n            suma(\"5\", \"2\")\n        with self.assertRaises(ValueError):\n            suma('a', 2)\n\n# unittest.main()\n\n\n'''\nExtra\n'''\nfrom datetime import datetime, date\ndata = {\n    \"name\": \"Rigoberto Acosta\",\n    \"age\": 30,\n    \"birth_date\": datetime.strptime(\"25-05-93\", \"%d-%m-%y\").date(),\n    \"programming_languages\": [\"Python\", \"C++\", \"C\"]\n}\n\nclass TestData(unittest.TestCase):\n\n    def setUp(self) -> None:\n        self.data = {\n        \"name\": \"Rigoberto Acosta\",\n        \"age\": 30,\n        \"birth_date\": datetime.strptime(\"25-05-93\", \"%d-%m-%y\").date(),\n        \"programming_languages\": [\"Python\", \"C++\", \"C\"]\n    }\n    \n    def test_fields_exist(self):\n\n        self.assertIn(\"name\", self.data)\n        self.assertIn(\"age\", self.data)\n        self.assertIn(\"birth_date\", self.data)\n        self.assertIn(\"programming_languages\", self.data)\n    \n    def test_data_is_correct(self):\n\n        self.assertIsInstance(self.data[\"name\"], str)\n        self.assertIsInstance(self.data[\"age\"], int)\n        self.assertIsInstance(self.data[\"birth_date\"], date)\n        self.assertIsInstance(self.data[\"programming_languages\"], list)\n        \n        # Info Directamente\n        # self.assertEqual(self.data[\"name\"], \"Rigoberto Acosta\")\n        # self.assertEqual(self.data[\"age\"], 30)\n        # self.assertEqual(self.data[\"birth_date\"], datetime.strptime(\"25-05-93\", \"%d-%m-%y\").date())\n        # self.assertEqual(self.data[\"programming_languages\"], [\"Python\", \"C++\", \"C\"])\n\nunittest.main()"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/rikmij.py",
    "content": "import unittest\n\ndef suma(n1, n2):\n    return n1 + n2\n\nclass ProbarSuma(unittest.TestCase):\n    def test_suma(self):\n        prueba = suma(3, 7)\n        self.assertEqual(prueba, 10)\n\n# \"\\n\", \"*\"*9, \" EJERCICIO EXTRA \", \"*\"*9\n\ndicc_presentarse = {\"name\":\"Rick\", \"age\":\"26\", \"birth_date\":\"21/07/1997\", \"programming languages\":[\"Python, Kotlin\"]}\n\nclass TestDicc(unittest.TestCase):\n    def test_all_fills(self):\n        self.assertIn(\"Rick\", dicc_presentarse[\"name\"])\n        self.assertIn(\"26\", dicc_presentarse[\"age\"])\n        self.assertIn(\"21/07/1997\", dicc_presentarse[\"birth_date\"])\n        self.assertIn(\"Python, Kotlin\", dicc_presentarse[\"programming languages\"])\n    \n    def test_correct_datas(self):\n        self.assertIs(type(dicc_presentarse[\"name\"]), str)\n        self.assertIs(type(dicc_presentarse[\"age\"]), str)\n        self.assertIs(type(dicc_presentarse[\"birth_date\"]), str)\n        self.assertIs(type(dicc_presentarse[\"programming languages\"]), list)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/roswer13.py",
    "content": "\nimport unittest\nfrom abc import ABC, abstractmethod\n\n# EJERCICIO:\n# Crea una función que se encargue de sumar dos números y retornar\n# su resultado.\n# Crea un test, utilizando las herramientas de tu lenguaje, que sea\n# capaz de determinar si esa función se ejecuta correctamente.\nclass Operation(ABC):\n    @abstractmethod\n    def calculate(self, a: int, b: int) -> int:\n        pass\n    \n    \nclass Sum(Operation):\n    def calculate(self, a: int, b: int) -> int:\n        return a + b\n    \n\nclass TestSum(unittest.TestCase):\n    def setUp(self):\n        self.sum = Sum()\n\n    def test_sum_number_possitive(self):\n        # Arrange\n        value1 = 1\n        value2 = 2\n        # Act\n        expected = value1 + value2\n        # Assert\n        self.assertEqual(self.sum.calculate(value1, value2), expected)\n    \n    def test_sum_number_negative(self):\n        # Arrange\n        value1 = -1\n        value2 = -2\n        # Act\n        expected = value1 + value2\n        # Assert\n        self.assertEqual(self.sum.calculate(value1, value2), expected)\n    \n    def test_sum_number_mixed(self):\n        # Arrange\n        value1 = -1\n        value2 = 2\n        # Act\n        expected = value1 + value2\n        # Assert\n        self.assertEqual(self.sum.calculate(value1, value2), expected)\n    \n    def test_sum_float_number(self):\n        # Arrange\n        value1 = 1.5\n        value2 = 2.5\n        # Act\n        expected = value1 + value2\n        # Assert\n        self.assertEqual(self.sum.calculate(value1, value2), expected)\n\n    def test_sum_no_number(self):\n        # Arrange\n        value1 = \"1\"\n        value2 = 2\n        # Act\n        # Assert\n        self.assertRaises(TypeError, self.sum.calculate)\n\n\n# DIFICULTAD EXTRA (opcional):\n# Crea un diccionario con las siguientes claves y valores:\n# \"name\": \"Tu nombre\"\n# \"age\": \"Tu edad\"\n# \"birth_date\": \"Tu fecha de nacimiento\"\n# \"programming_languages\": [\"Listado de lenguajes de programación\"]\n# Crea dos test:\n# - Un primero que determine que existen todos los campos.\n# - Un segundo que determine que los datos introducidos son correctos.\nclass TestUserData(unittest.TestCase):\n    def setUp(self):\n        self.key_name = \"name\"\n        self.key_age = \"age\"\n        self.key_birth_date = \"birth_date\"\n        self.key_programming_languages = \"programming_languages\"\n\n        self.data = {\n            \"name\": \"Roswer\",\n            \"age\": 31,\n            \"birth_date\": \"1993-06-30\",\n            \"programming_languages\": [\"Python\", \"Kotlin\", \"Dart\"]\n        }\n\n    def test_check_if_exits_all_keys(self):\n        # Arrange\n        keys_to_check = [self.key_name, self.key_age, self.key_birth_date, self.key_programming_languages]\n        keys = self.data.keys()\n        # Act\n        # Assert\n        self.assertTrue(all(key in keys for key in keys_to_check))\n        self.assertTrue(len(keys) == len(keys_to_check))\n    \n    def test_check_if_exits_all_keys_one_more(self):\n        # Arrange\n        self.data[\"extra_key\"] = \"Extra value\"\n        keys_to_check = [self.key_name, self.key_age, self.key_birth_date, self.key_programming_languages]\n        keys = self.data.keys()\n        # Act\n        # Assert\n        self.assertTrue(all(key in keys for key in keys_to_check))\n        self.assertFalse(len(keys) == len(keys_to_check))\n\n    def test_check_type_data(self):\n        # Arrange\n        # Act\n        # Assert\n        self.assertTrue(type(self.data[self.key_name]) == str)\n        self.assertTrue(type(self.data[self.key_age]) == int)\n        self.assertTrue(type(self.data[self.key_birth_date]) == str)\n        self.assertTrue(type(self.data[self.key_programming_languages]) == list)\n    \nif __name__ == '__main__':\n    unittest.main()"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/santyjl.py",
    "content": "#13 PRUEBAS UNITARIAS\n\"\"\"\n/*\n * EJERCICIO:\n * Crea una función que se encargue de sumar dos números y retornar\n * su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n * capaz de determinar si esa función se ejecuta correctamente.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"nombre\": \"Tu nombre\"\n * \"edad\": \"Tu edad\"\n * \"fecha_de_nacimiento\": \"Tu fecha de nacimiento\"\n * \"lenguajes_de_programacion\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\n */\n\"\"\"\nimport unittest\n\n\n# Función que suma dos números y devuelve el resultado\ndef suma_2(a: int, b: int) -> int:\n    \"\"\"\n    Suma dos números y devuelve el resultado.\n    \"\"\"\n    return a + b\n\n# Clase de pruebas unitarias para la función suma_2\nclass TestSuma(unittest.TestCase):\n\n    # Prueba para verificar la suma de números positivos\n    def test_suma_positiva(self):\n        \"\"\"\n        Prueba la suma de números positivos.\n        \"\"\"\n        self.assertEqual(suma_2(5, 5), 10)\n\n    # Prueba para verificar la suma de números positivos y negativos\n    def test_sume_negativa(self):\n        \"\"\"\n        Prueba la suma de un número positivo y otro negativo.\n        \"\"\"\n        self.assertEqual(suma_2(-1, -5), -6)\n\n# Función que crea un diccionario con información personal\ndef crear_diccionario(nombre, edad, fecha_nacimiento, lenguajes_de_programacion):\n    \"\"\"\n    Crea un diccionario con información personal.\n    \"\"\"\n    return {\n        \"nombre\": nombre,\n        \"edad\": edad,\n        \"fecha_de_nacimiento\": fecha_nacimiento,\n        \"lenguajes_de_programacion\": lenguajes_de_programacion\n    }\n\n# Clase de pruebas unitarias para la función crear_diccionario\nclass TestDatosPersonales(unittest.TestCase):\n\n    # Prueba para verificar la existencia de todos los campos en el diccionario\n    def test_existencia_campos(self):\n        \"\"\"\n        Prueba la existencia de todos los campos en el diccionario.\n        \"\"\"\n        datos = crear_diccionario(\"Santiago\", 14, \"2010-01-20\", [\"Python\", \"Arduino\"])\n        self.assertTrue(\"nombre\" in datos)\n        self.assertTrue(\"edad\" in datos)\n        self.assertTrue(\"fecha_de_nacimiento\" in datos)\n        self.assertTrue(\"lenguajes_de_programacion\" in datos)\n\n    # Prueba para verificar los tipos de datos de los campos en el diccionario\n    def test_campos_correctos(self):\n        \"\"\"\n        Prueba los tipos de datos de los campos en el diccionario.\n        \"\"\"\n        datos = crear_diccionario(\"Santiago\", 14, \"2009-03-26\", [\"Python\", \"Arduino\"])\n        self.assertIsInstance(datos[\"nombre\"], str)\n        self.assertIsInstance(datos[\"edad\"], int)\n        self.assertIsInstance(datos[\"fecha_de_nacimiento\"], str)\n        self.assertIsInstance(datos[\"lenguajes_de_programacion\"], list)\n        # Aquí podrías validar también los tipos de datos dentro de la lista de lenguajes de programación\n\nif __name__ == '__main__':\n    unittest.main()"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/sorubadguy.py",
    "content": "import unittest\nimport datetime\n\n#Suma\ndef suma(num1: float, num2: float)-> float:\n    return num1 + num2\ndef suma(num1: int, num2: int)-> int:\n    return num1 + num2\n\nprint(suma(3, 2.5))\n\nclass TestSuma(unittest.TestCase):\n    def test_suma(self):\n        self.assertEqual(suma(2, 3), 5)\n        self.assertEqual(suma(-2, 3), 1)\n        self.assertEqual(suma(2,-3), -1)\n        self.assertEqual(suma(-2, -3), -5)\n    \n    def tipos_suma(self):\n        with self.assertRaises(ValueError):\n            suma(\"3\",5)\n        with self.assertRaises(ValueError):\n            suma(\"3\",\"5\")\n        with self.assertRaises(ValueError):\n            suma(3,\"5\")\n        with self.assertRaises(ValueError):\n            suma(\"a\",5)\n        with self.assertRaises(ValueError):\n            suma(\"a\",\"b\")\n        with self.assertRaises(ValueError):\n            suma(None,5)  \n \n#!Extra\n\npersona = {\n    \"name\" : \"Sorubadguy\",\n    \"age\" : \"30\",\n    \"birth_date\" : datetime.date(1994, 3, 27),\n    \"programming_languages\" : [\"python\", \"php\", \"javaScript\"]\n}\nprint(type(persona[\"age\"]))\n\nclass TestPersona(unittest.TestCase):\n    \n    def persona_existe(self):\n        self.assertEquals(persona.keys, \"name\")\n        self.assertEquals(persona.keys, \"age\")\n        self.assertEquals(persona.keys, \"birth_date\")\n        self.assertEquals(persona.keys, \"programming_languages\")\n        \n    def persona_datos(self):\n        self.assertEquals(type(persona[\"age\"]), int)\n        self.assertEquals(type(persona[\"name\"]), str)\n        self.assertEquals(type(persona[\"birth_date\"]), datetime.date)\n        self.assertEquals(type(persona[\"programming_languages\"]), list)\n        \n        \nunittest.main()"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/sperezsa.py",
    "content": "#13 - PRUEBAS UNITARIAS\n\ndef sum(a,b):\n    assert(type(a) == int)\n    assert(type(b) == int)\n    return a+b\n\ndef test_sum_invalid_type_number():\n    sum(3,'c')\n\ndef test_sum_invalid_result():\n    assert(sum(3,2)==6)\n\n# test OK \nprint(sum(2,3))\n\n# test KOs\ntest_sum_invalid_type_number()\ntest_sum_invalid_result()\n\n\n\"\"\"\nExtra\n\"\"\"\n\ndatos = {\n    \"nombres\": \"Sergio\",\n    \"edad\": 44,\n    \"fx_nacimiento\": \"08/09/1979\",\n    \"lenguajes\": [\"Python\", \"Java\", \"JavaScript\"]\n    }\n\ndef test_exist_fields(datos): \n    claves = [\"nombre\", \"edad\", \"fx_nacimiento\", \"lenguajes\"]\n    for clave in claves:\n      if clave not in datos:\n        return False\n    return True\n\ndef test_exist_data():\n    assert not (datos[\"nombre\"] is None)\n    assert not (datos[\"edad\"] is None)\n    assert not (datos[\"fx_nacimiento\"] is None)\n    assert not (datos[\"lenguajes\"] == [])\n\ndef test_correct_type_data():\n    assert (isinstance(datos[\"nombre\"], str))\n    assert (isinstance(datos[\"edad\"], int))\n    assert (isinstance(datos[\"fx_nacimiento\"], str))    \n    assert (isinstance(datos[\"lenguajes\"], list))\n\n\n# test para revisar si las claves están presentes en el diccionario\nassert (test_exist_fields(datos))\n\n# test para revisar que los campos no están vacíos\nassert not (test_exist_data())\n\n# test para revisar que los campos tienen el tipo de dato correcto\nassert not (test_correct_type_data())\n    \n\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/victorfer69.py",
    "content": "import unittest\nfrom datetime import datetime, date\n\n\"\"\"\nEjercicio\n\"\"\"\n\n\ndef sum(a, b):\n    if not isinstance(a, (int, float)) or not isinstance(b, (int, float)):\n        return ValueError(\"Los argumentos deben de ser enteros o decimales.\")\n    return a + b\n\n\nclass TestSum(unittest.TestCase):\n\n    def test_sum(self):\n        self.assertEqual(sum(5, 7), 12)\n        self.assertEqual(sum(5, -7), -2)\n        self.assertEqual(sum(0, 0), 0)\n        self.assertEqual(sum(5.1, 7.1), 12.2)\n\n    def test_sum_type(self):\n        with self.assertRaises(ValueError):\n            sum(\"5\", 7)\n        with self.assertRaises(ValueError):\n            sum(5, \"7\")\n        with self.assertRaises(ValueError):\n            sum(\"5\", \"7\")\n\n\n#EJERCIICO EXTRA\ndicc = {\n    \"name\": \"Victor\",\n    \"age\": 21,\n    \"birth_date\": \"06-09-2003\",\n    \"programming_languages\": [\"Python\", \"Java\", \"C\"]\n}\n\nclass TestSum(unittest.TestCase):\n\n    def test_all_param(self):\n        self.assertIn(\"name\", dicc)\n        self.assertIn(\"age\", dicc)\n        self.assertIn(\"birth_date\", dicc)\n        self.assertIn(\"programming_languages\", dicc)\n\n    def test_correct_data(self):\n        self.assertIsInstance(dicc[\"name\"], str)\n        self.assertIsInstance(dicc[\"age\"], int)\n        self.assertIsInstance(dicc[\"birth_date\"], str)\n        self.assertIsInstance(dicc[\"programming_languages\"], list)\n\nunittest.main()"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/worlion.py",
    "content": "import unittest\n# from test import support\n\n\"\"\"\nEJERCICIO: Testing\n\"\"\"\n\ndef suma(a: int, b:int) -> int:\n    return a+b\n\nclass TestSuma(unittest.TestCase):\n    \n    def test_suma(self):\n        self.assertEqual(suma(2,3), 5)\n        self.assertEqual(suma(50,25), 75)\n        self.assertEqual(suma(2,-3), -1)\n        \n    def test_suma_type_error(self):\n        with self.assertRaises(TypeError):\n            suma(2,\"papas\")\n    \n# unittest.main() \n\n\"\"\"\n    DIFICULTAD EXTRA (opcional):\n\"\"\"\n\nprint(\"\\n ---- 🌩 DIFICULTAD EXTRA 🌩 ----\\n\")\n\n# Diccionario con los datos\nmy_self = {\n    \"name\": \"Imanol\",\n    \"age\" : 40,\n    \"birth_date\" : \"20/04/1984\",\n    \"programming_languages\" : [\"Java\", \"Python\", \"Ada\", \"C#\", \"C/C++\"]\n}\n\nclass TestMySelfDict(unittest.TestCase):\n    \n    # Test que comprueba la existencia de todos los campos\n    def test_fields_exist(self):\n        self.assertIn(\"name\", my_self)\n        self.assertIn(\"age\", my_self)\n        self.assertIn(\"birth_date\", my_self)\n        self.assertIn(\"programming_languages\", my_self)\n    \n    # Test que comprueba que el tipo de todos los campos sea el correcto\n    def test_right_type(self):\n        self.assertIsInstance(my_self[\"name\"], str)\n        self.assertIsInstance(my_self[\"age\"], int)\n        self.assertIsInstance(my_self[\"birth_date\"], str)\n        self.assertIsInstance(my_self[\"programming_languages\"], list)\n    \n    # Test que comprueba que el valor de todos los campos sea el correcto\n    def test_right_values(self):\n        self.assertEqual(my_self[\"name\"], \"Imanol\")\n        self.assertEqual(my_self[\"age\"],  40)\n        self.assertEqual(my_self[\"birth_date\"],  \"20/04/1984\")\n        self.assertEqual(my_self[\"programming_languages\"],  [\"Java\", \"Python\", \"Ada\", \"C#\", \"C/C++\"])\n\nunittest.main() "
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/ycanas.py",
    "content": "import unittest\n\n# ------ Ejercicio\n\ndef sum(a: int, b: int) -> int:\n    if not isinstance(a, (int, float)) or not isinstance(b, (int, float)):\n        raise TypeError(\"Los argumentos deben ser números enteros o decimales\")    \n    \n    return a + b\n\n\nclass TestSum(unittest.TestCase):\n\n    def test_sum(self):\n        self.assertEqual(sum(3, 4), 7)\n        self.assertEqual(sum(-3, 4), 1)\n        self.assertEqual(sum(3, -4), -1)\n        self.assertEqual(sum(8.9, 12.1), 21)\n        self.assertEqual(sum(15, 91.9), 106.9)\n        self.assertEqual(sum(-8, -12), -20)\n\n\n    def test_sum_type(self):\n        with self.assertRaises(TypeError):\n            sum(\"2\", 6)\n\n        with self.assertRaises(TypeError):\n            sum(2, \"6\")\n\n        with self.assertRaises(TypeError):\n            sum(None, 6)\n\n        with self.assertRaises(TypeError):\n            sum(6, None)\n\n        with self.assertRaises(TypeError):\n            sum([], ())\n\n\n# ------ Extra\n\nmy_dict = {\n    \"name\": \"Yair Cañas\",\n    \"age\": 24,\n    \"birth_date\": \"03/01/2000\",\n    \"programming_languages\": [\"Python\", \"C\", \"C++\", \"Java\", \"Matlab\"]\n}\n\n\nclass TestDict(unittest.TestCase):\n\n    def test_keys(self):\n        self.assertIn(\"name\", my_dict)\n        self.assertIn(\"age\", my_dict)\n        self.assertIn(\"birth_date\", my_dict)\n        self.assertIn(\"programming_languages\", my_dict)\n\n\n    def test_values(self):\n        self.assertIsInstance(my_dict[\"name\"], str)\n        self.assertIsInstance(my_dict[\"age\"], int)\n        self.assertIsInstance(my_dict[\"birth_date\"], str)\n        self.assertIsInstance(my_dict[\"programming_languages\"], list)\n\n\nunittest.main()\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/yenneralayon142.py",
    "content": "import unittest\nfrom datetime import datetime, date\n\ndef sun(a,b):\n    if not isinstance(a,(int,float)) or not isinstance(b,(int,float)):\n        raise ValueError(\"Los argumentos deben ser enteros o decimales\")\n    return a + b\n\nclass TestSum(unittest.TestCase):\n\n    def  test_Sum(self):\n        self.assertEqual(sun(5, 7),12)\n        self.assertEqual(sun(10, 12), 22)\n        self.assertEqual(sun(-15, 10), -5)\n\n    def test_Sum_Type(self):\n        with self.assertRaises(ValueError):\n            sun(\"5\", 7)\n        with self.assertRaises(ValueError):\n            sun(\"a\",2)\n        with self.assertRaises(ValueError):\n            sun(\"5\",\"5\")\n\n\nclass TestData(unittest.TestCase):\n\n    def setUp(self) -> None:  #Preparamos el contexto\n        self.data = {\n            \"name\" : \"Yenner\",\n            \"age\" : 21,\n            \"birth_Date\" : datetime.strptime(\"30-05-03\",\"%d-%m-%y\").date(),\n            \"programming_languages\" : [\"Python\",\"CSharp\"]\n        }\n\n    def test_Field_Exist(self): #Probamos si los campos si existen \n        self.assertIn(\"name\", self.data)\n        self.assertIn(\"age\", self.data)\n        self.assertIn(\"birth_Date\", self.data)\n        self.assertIn(\"programming_languages\", self.data)\n\n    def test_Data_Is_Correct(self):\n        self.assertIsInstance(self.data[\"name\"],str)\n        self.assertIsInstance(self.data[\"age\"],int)\n        self.assertIsInstance(self.data[\"birth_Date\"],date)\n        self.assertIsInstance(self.data[\"programming_languages\"],list)\n    \nunittest.main()\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/python/zetared92.py",
    "content": "# RETO 13 PRUEBAS UNITARIAS\n\nimport unittest\nfrom datetime import datetime, date \n\n\"\"\"\nCrea una función que sume dos números y retorne el resultado.\nCrea un test capaz de determinar si esa funcion se ejecuta bien\n\"\"\"\n\ndef sum(a, b):\n    if not isinstance(a, (int, float)) or not isinstance(b, (int, float)):\n        raise ValueError(\"Arguments must be integers or decimals.\")\n    return a + b\n\n\nclass TestSum(unittest.TestCase):\n\n    def test_sum(self):\n        self.assertEqual(sum(5, 7), 12)\n        self.assertEqual(sum(5, -7), -2)\n        self.assertEqual(sum(0, 0), 0)\n        self.assertEqual(sum(2.5, 2.1), 4.6)\n        self.assertEqual(sum(2, 2.1), 4.1)\n        self.assertEqual(sum(2.5, 2.5), 5)\n\n    def test_sum_type(self):\n        with self.assertRaises(ValueError):\n            sum(\"5\", 7)\n        with self.assertRaises(ValueError):\n            sum(5, \"7\")\n        with self.assertRaises(ValueError):\n            sum(\"5\", \"7\")\n        with self.assertRaises(ValueError):\n            sum(\"a\", 7)\n        with self.assertRaises(ValueError):\n            sum(None, 7)\n\n\n# Extra\n\nprint(\"🧩 DIFICULTAD EXTRA - DICCIONARIO 🧩\")\n\nclass TestData(unittest.TestCase):\n\n    def setUp(self) -> None:\n        self.data = {\n            \"name\": \"Zeta Vega\",\n            \"age\": 31,\n            \"birth_date\": datetime.strptime(\"03-12-92\", \"%d-%m-%y\").date(),\n            \"languages\": [\"Python\", \"Rust\", \"Swift\"]\n        }\n\n    def test_fields_exist(self):\n        self.assertIn(\"name\", self.data)\n        self.assertIn(\"age\", self.data)\n        self.assertIn(\"birth_date\", self.data)\n        self.assertIn(\"languages\", self.data)\n\n    def test_data_is_correct(self):\n        self.assertIsInstance(self.data[\"name\"], str)\n        self.assertIsInstance(self.data[\"age\"], int)\n        self.assertIsInstance(self.data[\"birth_date\"], date)\n        self.assertIsInstance(self.data[\"languages\"], list)\n\n\nunittest.main()\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/ruby/Elmer125.rb",
    "content": "#  * EJERCICIO:\n#  * Crea una función que se encargue de sumar dos números y retornar\n#  * su resultado.\n#  * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n#  * capaz de determinar si esa función se ejecuta correctamente.\ndef sum(a, b)\n  a + b\nend\n\nrequire 'test/unit'\nclass TestMethod < Test::Unit::TestCase\n  def test_sum\n    assert_equal(4, sum(2, 2))\n  end\n\n  def test_fail\n    assert_equal(5, sum(2, 2))\n  end\nend\n\nrequire 'minitest/autorun'\n\nclass TestSum < Minitest::Test\n  def test_suma\n    assert_equal 5, sum(2, 3)\n    assert_equal 0, sum(-1, 1)\n    assert_equal 0, sum(0, 0)\n    assert_equal 10, sum(3, 3)\n  end\nend\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea un diccionario con las siguientes claves y valores:\n#  * \"name\": \"Tu nombre\"\n#  * \"age\": \"Tu edad\"\n#  * \"birth_date\": \"Tu fecha de nacimiento\"\n#  * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n#  * Crea dos test:\n#  * - Un primero que determine que existen todos los campos.\n#  * - Un segundo que determine que los datos introducidos son correctos.\n\n# Doc MiniTest: https://www.rubydoc.info/github/seattlerb/minitest/Minitest/Assertions\n\nrequire 'date'\nclass TestPersonalInformation < Minitest::Test\n  def setup\n    @personal_information = { name: \"Joen Doe\",\n                              age: 28,\n                              birth_date: Date.parse(\"01-01-1995\"),\n                              programming_languages: [\"Ruby\", \"Python\", \"JavaScript\"] }\n  end\n\n  def test_information_exists\n    assert_includes @personal_information, :name\n    assert_includes @personal_information, :age\n    assert_includes @personal_information, :birth_date\n    assert_includes @personal_information, :programming_languages\n  end\n\n  def test_information_is_correct\n    assert_instance_of String, @personal_information[:name]\n    assert_instance_of Integer, @personal_information[:age]\n    assert_instance_of Date, @personal_information[:birth_date]\n    assert_instance_of Array, @personal_information[:programming_languages]\n  end\nend\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/rust/kenysdev.rs",
    "content": "#![allow(dead_code)]\n/*\n╔═══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado                ║\n║ GitHub: https://github.com/Kenysdev   ║\n║ 2024 -  Rust                          ║\n╚═══════════════════════════════════════╝\n-----------------------------------------\n* PRUEBAS UNITARIAS\n-----------------------------------------\nMas info: https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html\n_______________\n* EJERCICIO #1\n* Crea una función que se encargue de sumar dos números y retornar\n  su resultado.\n* Crea un test, utilizando las herramientas de tu lenguaje, que sea\n  capaz de determinar si esa función se ejecuta correctamente.\n\n_______________\n* EJERCICIO #2\n* Crea un diccionario con las siguientes claves y valores:\n  - \"name\": \"Tu nombre\"\n  - \"age\": \"Tu edad\"\n  - \"birth_date\": \"Tu fecha de nacimiento\"\n  - \"programming_languages\": [\"Listado de lenguajes de programación\"]\n* Crea dos test:\n  - Un primero que determine que existen todos los campos.\n  - Un segundo que determine que los datos introducidos son correctos.\n*/\n\nfn sum(a: i32, b: i32) -> i32 {\n    a + b\n}\n\nuse std::collections::HashMap;\nuse std::any::Any;\n\nfn get_dict_user() -> HashMap<&'static str, Box<dyn Any>> {\n    let mut dict_user: HashMap<&'static str, Box<dyn Any>> = HashMap::new();\n\n    dict_user.insert(\"name\", Box::new(\"Ken\"));\n    dict_user.insert(\"age\", Box::new(121));\n    dict_user.insert(\"birth_date\", Box::new(\"1903-03-19\"));\n    dict_user.insert(\"prog_langs\", Box::new(vec![\"cs\", \"py\", \"vb\", \"rs\", \"js\"]));\n\n    return dict_user\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn test_sum() {\n        assert_eq!(sum(5, 2), 7);\n        assert_eq!(sum(-2, 1), -1);\n        assert_eq!(sum(0, 0), 0);\n    }\n\n    #[test]\n    fn test_dict_key_existence() {\n        let dict_user = get_dict_user();\n\n        assert!(dict_user.contains_key(\"name\"));\n        assert!(dict_user.contains_key(\"age\"));\n        assert!(dict_user.contains_key(\"birth_date\"));\n        assert!(dict_user.contains_key(\"prog_langs\"));\n    }\n\n    #[test]\n    fn test_dict_value_types() {\n        let dict_user = get_dict_user();\n\n        assert!(dict_user[\"name\"].is::<&str>());\n        assert!(dict_user[\"age\"].is::<i32>());\n        assert!(dict_user[\"birth_date\"].is::<&str>());\n        assert!(dict_user[\"prog_langs\"].is::<Vec<&str>>());\n    }\n}\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/rust/w00k.rs",
    "content": "/*\n * EJERCICIO:\n * Crea una función que se encargue de sumar dos números y retornar\n * su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n * capaz de determinar si esa función se ejecuta correctamente.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\n */\n\nuse std::collections::HashMap;\n\n//suma numeros\nfn add_numbers(number1: u32, number2: u32) -> u32 {\n    number1 + number2\n}\n\n//genera el HashMap -> clave valor\nfn get_hashmap() -> HashMap<&'static str, &'static str> {\n    let mut data = HashMap::new();\n    data.insert(\"name\", \"w00k\");\n    data.insert(\"age\", \"41\");\n    data.insert(\"birth_date\", \"08/07/1982\");\n    data.insert(\"programming_languages\", \"Java, Go, Rust\");\n    return data;\n}\n\nfn main() {\n    println!(\"Inicio\");\n    println!(\"{}\", add_numbers(1, 2));\n    println!(\"Fin\");\n\n    println!(\"\\nDIFICULTAD EXTRA\");\n    let hash_map = get_hashmap();\n    let iterator = hash_map.iter().count(); //cantidad de elementos del hash\n    println!(\"The hash_map size equals {:?}\", &iterator);\n    for (key, value) in &hash_map { //imprimo el HashMap\n        println!(\"{key}: {value}\");\n    }\n\n}\n\n//test\n#[cfg(test)]\nmod test {\n    use crate::{add_numbers, get_hashmap};\n\n    //test utilitario\n    fn valid_key(value: &str) -> bool {\n        if value.eq(\"name\")\n            || value.eq(\"age\")\n            || value.eq(\"birth_date\")\n            || value.eq(\"programming_languages\") {\n            return true;\n        }\n        return false;\n    }\n\n    //testcase\n    #[test]\n    fn it_works() {\n        assert_eq!(add_numbers(2,2), 4);\n    }\n    #[test]\n    fn other_works(){\n        assert_eq!(add_numbers(1,1000000000), 1000000001);\n    }\n    //testcase DIFICULTAD EXTRA\n    //valido datos no vacios\n    #[test]\n    fn validate_not_empty() {\n        let hash = get_hashmap();\n        let count = hash.iter().count();\n        for (key, value) in &hash {\n            assert_eq!(true, valid_key(&key));\n            assert_ne!(0, value.len());\n        }\n        assert_eq!(4, count);\n    }\n    //valido nombre\n    #[test]\n    fn validate_name(){\n        let hash = get_hashmap();\n        let name = hash.get(\"name\");\n        match name {\n            None => assert_eq!(\"none\", \"\"),\n            Some(&value) => assert_eq!(\"w00k\", value),\n        }\n    }\n    //valido edad\n    #[test]\n    fn validate_age(){\n        let hash = get_hashmap();\n        let age = hash.get(\"age\");\n        match age {\n            None => assert_eq!(\"none\",\"\"),\n            Some(&value) => {\n                assert_ne!(0, value.len());\n                assert_eq!(\"41\", value);\n            },\n        }\n    }\n    //valido fecha nacimiento\n    #[test]\n    fn validate_birth_date(){\n        let hash = get_hashmap();\n        let birth_date = hash.get(\"birth_date\");\n        match birth_date {\n            None => assert_eq!(\"none\", \"\"),\n            Some(&value) => assert_eq!(\"08/07/1982\", value),\n        }\n    }\n    //valido lenguajes de programación\n    #[test]\n    fn validate_languages(){\n        let hash = get_hashmap();\n        let lang = hash.get(\"programming_languages\");\n        match lang {\n            None => assert_eq!(\"none\", \"\"),\n            Some(&value) => assert_eq!(\"Java, Go, Rust\", value)\n        }\n    }\n}\n\n\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/sql/Nicojsuarez2.sql",
    "content": "# #13 PRUEBAS UNITARIAS\n> #### Dificultad: Fácil | Publicación: 25/03/24 | Corrección: 01/04/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Crea una función que se encargue de sumar dos números y retornar\n * su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n * capaz de determinar si esa función se ejecuta correctamente.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/swift/allbertoMD.swift",
    "content": "import Foundation\n\n\n// FUNCION DE SUMA\nprint(\"\\nFUNCION DE SUMA\")\n\nfunc addTwoInts(addEnd1 n1: Int, addEnd2 n2: Int) -> Int {\n    n1 + n2\n}\n\nfunc testAddTwoIntsFunction() {\n\n    let result1 = addTwoInts(addEnd1: 2, addEnd2: 2) == 4\n    \n    assert(result1, \"El resultado deveria ser: 4\")\n    \n    print(\"Test de la funcion de suma pasado.\")\n}\ntestAddTwoIntsFunction()\n\n\n\n\n// DIFICULTAD EXTRA\nprint(\"\\nDIFICULTAD EXTRA.\")\n\nvar dictionary: [String : Any] = [\n    \"name\" : \"alberto\",\n    \"age\" : 39,\n    \"birthDate\" : \"04/07/1984\",\n    \"programmingLenguages\" : [\"Swift\", \"Python\", \"Bash\"]\n]\n\nfunc testDictionaryKeys() {\n\n    let nameChecker = dictionary.keys.contains(\"name\")\n    let ageChecker = dictionary.keys.contains(\"age\")\n    let birthDateChecker = dictionary.keys.contains(\"birthDate\")\n    let programmingLenguagesChecker = dictionary.keys.contains(\"programmingLenguages\")\n\n    assert(nameChecker, \"El campo name no existe.\")\n    assert(ageChecker, \"El campo age no existe.\")\n    assert(birthDateChecker, \"El campo birthDate no existe.\")\n    assert(programmingLenguagesChecker, \"El campo programmingLenguages no existe.\")\n\n    print(\"Test de campos del diccionario pasado.\")\n\n}\ntestDictionaryKeys()\n\nfunc testDictionaryValues() {\n\n    let nameValueChercker = dictionary[\"name\"] as? String == \"alberto\"\n    let ageValueChecker = dictionary[\"age\"] as? Int == 39\n    let birthDateValueChecker = dictionary[\"birthDate\"] as? String == \"04/07/1984\"\n    let programmingLenguagesValueChecker = dictionary[\"programmingLenguages\"] as? [String] == [\"Swift\", \"Python\", \"Bash\"]\n\n    assert(nameValueChercker, \"El valor de name no es alberto\")\n    assert(ageValueChecker, \"El valor de age no es 39\")\n    assert(birthDateValueChecker, \"El valor de birthDate no es 04/07/1984\")\n    assert(programmingLenguagesValueChecker, \"Los valores de programmingLenguages no es [Swift, Python, Bash]\")\n\n    print(\"Test del los valores del diccionario pasado.\")\n}\ntestDictionaryValues()"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/swift/blackriper.swift",
    "content": "import Foundation\nimport XCTest\n/*\n El testing es la manera de probar diferentes fragmentos de codigo\n para ver si el resultado es el que se esperaba.\n\nen swift se realiza el testing mediante la libreria XCTest\npara probar los diferentes test se debe contar con el package.swift \n\nasi que aqui solo se muestran los ejemplos de testing \n\n */\n\nstruct Calculator{\n    let num1 : Int \n    let num2 : Int\n\n    func add() -> Int{\n        return num1 + num2\n    }\n  }\n\n typealias DictProgrammer = [String:Any]\n\n  struct Programmer{\n      let name:String\n      let age : Int\n      let birthDate:String\n      let programmingLanguage: [String]\n\n     static func toDictionary(programmer: Programmer) -> DictProgrammer {\n          return [\n              \"name\": programmer.name,\n              \"age\": programmer.age,\n              \"birthDate\":programmer.birthDate,\n              \"programmingLanguage\": programmer.programmingLanguage\n          ]\n      }\n\n    }\n\n// ejemplo clase testing  al tenerla en el folder test correr el comando swift test \n\n//nombre de la libreria donde esta el codigo a probar\n//@testable import testing\n\n\nfinal class testingTests: XCTestCase {\n     func testAdd(){\n        let calculator = Calculator(num1: 1, num2: 2)\n        XCTAssertEqual(calculator.add(), 3)\n    }\n\n    func testProgrammerSucessCases(){\n        let black = Programmer(name: \"blackiper\", age: 30, birthDate: \"20/05/1994\", programmingLanguage: [\"swift\", \"go\"])\n        let dictionary = Programmer.toDictionary(programmer: black )\n        let dictionaryMock: [String:Any] = [\n            \"name\": \"blackiper\",\n            \"age\": 30,\n            \"birthDate\": \"20/05/1994\",\n            \"programmingLanguage\": [\"swift\", \"go\"]\n        ]\n\n       // comparar campos de diccionario \n       XCTAssertTrue(dictionary.keys == dictionaryMock.keys) \n\n      \n      // comprobrar tipos de dictionary  pendiente ver si es la mejor forma\n       XCTAssertTrue(dictionary[\"name\"] as! String == dictionaryMock[\"name\"] as! String)\n       XCTAssertTrue(dictionary[\"age\"] as! Int == dictionaryMock[\"age\"] as! Int) \n       XCTAssertTrue(dictionary[\"birthDate\"] as! String == dictionaryMock[\"birthDate\"] as! String) \n       XCTAssertTrue(dictionary[\"programmingLanguage\"] as! [String] == dictionaryMock[\"programmingLanguage\"] as! [String])\n   \n    }\n\n   func testProgrammerErrorCases(){\n       let black = Programmer(name: \"blackiper\", age: 30, birthDate: \"20/05/1994\", programmingLanguage: [\"swift\", \"go\"])\n       let dictionary = Programmer.toDictionary(programmer: black )\n       let dictionaryMockError: [String:Any] = [\n           \"age\": 30,\n           \"birthDate\": \"20/05/1994\",\n           \"programmingLanguage\": [\"swift\"]\n       ]\n\n       XCTAssertFalse(dictionary.keys == dictionaryMockError.keys)\n\n       XCTAssertFalse(dictionary[\"programmingLanguage\"] as! [String] == dictionaryMockError[\"programmingLanguage\"] as! [String])\n\n   }\n\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/swift/kontroldev.swift",
    "content": "import Foundation\n\n/*\n * EJERCICIO:\n * Crea una función que se encargue de sumar dos números y retornar\n * su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n * capaz de determinar si esa función se ejecuta correctamente.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\n */\n\n\nimport Foundation\nimport XCTest\n\n// Definición de la función sumar\nfunc sumar(_ a: Int, _ b: Int) -> Int {\n    return a + b\n}\n\n// Clase de prueba para la función sumar\nclass SumarTests: XCTestCase {\n    \n    func testSumar() {\n        // Caso de prueba 1: 2 + 3 = 5\n        XCTAssertEqual(sumar(2, 3), 5)\n        \n        // Caso de prueba 2: -1 + 1 = 0\n        XCTAssertEqual(sumar(-1, 1), 0)\n        \n        // Caso de prueba 3: 0 + 0 = 0\n        XCTAssertEqual(sumar(0, 0), 0)\n        \n        // Caso de prueba 4: 123 + 456 = 579\n        XCTAssertEqual(sumar(123, 456), 579)\n        \n        // Caso de prueba 5: -123 + (-456) = -579\n        XCTAssertEqual(sumar(-123, -456), -579)\n    }\n}\n\n// Ejecutar las pruebas\nSumarTests.defaultTestSuite.run()\n\n\n/// **Dificultad EXTRA**\n\n\n// Definición del diccionario con los datos requeridos\nlet myInfo: [String: Any] = [\n    \"name\": \"Tu nombre\",\n    \"age\": \"Tu edad\",\n    \"birth_date\": \"Tu fecha de nacimiento\",\n    \"programming_languages\": [\"Swift\", \"Python\", \"JavaScript\"] // Ejemplo de lenguajes de programación\n]\n\n// Clase de prueba para el diccionario\nclass MyInfoTests: XCTestCase {\n    \n    func testFieldsExistence() {\n        // Verificar que existen todas las claves\n        XCTAssertNotNil(myInfo[\"name\"])\n        XCTAssertNotNil(myInfo[\"age\"])\n        XCTAssertNotNil(myInfo[\"birth_date\"])\n        XCTAssertNotNil(myInfo[\"programming_languages\"])\n    }\n    \n    func testCorrectData() {\n        // Verificar que los valores de las claves son correctos\n        XCTAssertEqual(myInfo[\"name\"] as? String, \"Tu nombre\")\n        XCTAssertEqual(myInfo[\"age\"] as? String, \"Tu edad\")\n        XCTAssertEqual(myInfo[\"birth_date\"] as? String, \"Tu fecha de nacimiento\")\n        \n        // Verificar que los lenguajes de programación son correctos\n        let expectedLanguages = [\"Swift\", \"Python\", \"JavaScript\"]\n        XCTAssertEqual(myInfo[\"programming_languages\"] as? [String], expectedLanguages)\n    }\n}\n\n// Ejecutar las pruebas\nMyInfoTests.defaultTestSuite.run()\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/swift/pedroomar23.swift",
    "content": "import Foundation\n\n/*\n * EJERCICIO:\n * Crea una función que se encargue de sumar dos números y retornar\n * su resultado.\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n * capaz de determinar si esa función se ejecuta correctamente.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un diccionario con las siguientes claves y valores:\n * \"name\": \"Tu nombre\"\n * \"age\": \"Tu edad\"\n * \"birth_date\": \"Tu fecha de nacimiento\"\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n * Crea dos test:\n * - Un primero que determine que existen todos los campos.\n * - Un segundo que determine que los datos introducidos son correctos.\n */\n\n// Suma \n func suma(a: Int, b: Int) -> Int {\n    return a + b \n }\n\nprint(\"El resultado de la suma 5 + 5 es: \\(suma(a: 5, b: 5))\")\n\n// Test\nfunc sumaTwoInts() {\n    let result = suma(a: 5, b: 5) == 10\n    assert(result, \"El resultado de la suma de 5 + 5 deberia ser 10\")\n    print(\"El test del resultado de la suma de 5 + 5 ha pasado satisfactoriamente\")\n}\n\nsumaTwoInts()"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/typescript/AChapeton.ts",
    "content": "// ! NOTA: El archivo utiliza la libreria Jest. Para utilizarlo, seguir los siguientes pasos:\n// 1. Se debe de ejecutar el comando \"npm i --save-dev jest\"\n// 2. En la lista de scripts dentro de package.json, incluir \"test\": \"jest\"\n// 3. Cambiar el nombre del archivo a \"AChapeton.test.ts\"\n\nconst sum = (a, b) => {\n  return a + b\n}\n\ndescribe('Funcion Sum', () => {\n  test('Debe de sumar dos numeros', () => {\n    expect(sum(1, 2)).toBe(3)\n  })\n})\n\n// DIFICULTAD EXTRA\n\nconst diccionario = {\n  name: \"Andres\", \n  age: 26,\n  birth_date: '02/06/1997',\n  programming_languages: [\n    \"TypeScript\", \"JavaScript\", \"Python\"\n  ]\n}\n\ndescribe('Diccionario', () => {\n  test('Deben de existir los 4 campos', () => {\n    const keys = Object.keys(diccionario)\n    expect(keys).toContain('name')\n    expect(keys).toContain('age')\n    expect(keys).toContain('birth_date')\n    expect(keys).toContain('programming_languages')\n  })\n\n  test('Los datos deben de ser correctos', () => {\n    const values = Object.values(diccionario)\n    expect(values).toContain('Andres')\n    expect(values).toContain(26)\n    expect(values).toContain('02/06/1997')\n    expect(values[3]).toEqual([\n      \"TypeScript\", \"JavaScript\", \"Python\"\n    ])\n  })\n})"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/typescript/IgleDev.ts",
    "content": "// El archivo utiliza Jest. Su uso:\n// 1º Se debe de ejecutar el comando \"npm i --save-dev jest\"\n// 2º En la lista de scripts dentro de package-lock.json, incluir \"test\": \"jest\"\n// 3º Para probar los test, cambiar el nombre del archivo a \"IgleDev.test.ts\".\n// 4º Para ejecutar el test ejecutar el siguiente comando: \"npm test\"\n    \n// 1º Ejercicio\n    let suma = (a, b) => {  // En jest no podemos indicar el tipo que es debido a que el ':' no lo reconoce\n        return a + b\n    }\n\n    test('Función suma', () => {\n        expect(suma(5, 5)).toBe(10);\n    });\n\n// DIFICULTAD EXTRA\n    let diccionario = {\n        name: 'Adrián', \n        age: 19,\n        birth_date: '03/11/2004',\n        programming_languages: [\n          'TypeScript', 'JavaScript', 'HTML', 'CSS'\n        ]\n    };\n\n    test('Existen los campos', () => {\n        let keys = Object.keys(diccionario);\n        expect(keys).toContain('name');\n        expect(keys).toContain('age');\n        expect(keys).toContain('birth_date');\n        expect(keys).toContain('programming_languages');\n    });\n\n    test('Datos introducidos correctos', () =>{\n        let datos = Object.values(diccionario);\n        expect(datos).toContain('Adrián');\n        expect(datos).toContain(19);\n        expect(datos).toContain('03/11/2004');\n        expect(datos[3]).toEqual([\n            'TypeScript', 'JavaScript', 'HTML', 'CSS'\n        ]);\n    });"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/typescript/Sac-Corts.ts",
    "content": "// npm install --save-dev jest\n// We name the file with the ending .test.js\n// To run the program: npx jest .\\Sac-Corts.test.js\n\nfunction addition(a: number, b: number): number {\n    return a + b;\n}\n\ntest('addition 1 + 2 should be 3', () => {\n    expect(addition(1, 2)).toBe(3);\n});\n\ntest('addition 3 + 7 should be 10', () => {\n    expect(addition(3, 7)).toBe(10);\n});\n\n// ** Extra Exercise ** //\ninterface Data {\n    name: string;\n    age: string;\n    birthdate: string;\n    programmingLanguages: string[];\n}\n\nconst data: Data = {\n    name: \"Isaac\",\n    age: \"22\",\n    birthdate: \"2001-10-21\",\n    programmingLanguages: [\"JavaScript\", \"Python\"]\n};\n\ntest('It should have all the necessary keys', () => {\n    expect(data).toHaveProperty('name');\n    expect(data).toHaveProperty('age');\n    expect(data).toHaveProperty('birthdate');\n    expect(data).toHaveProperty('programmingLanguages');\n});\n\ntest('It should have the correct data', () => {\n    expect(data.name).toBe(\"Isaac\");\n    expect(data.age).toBe(\"22\");\n    expect(data.birthdate).toBe(\"2001-10-21\");\n    expect(data.programmingLanguages).toEqual([\"JavaScript\", \"Python\"]);\n});\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/typescript/david-git-dev.ts",
    "content": "import { assert,test } from 'poku'; //libreria usada para el testing\nfunction sum(x:number,y:number):number {\n  if(typeof x !=='number'|| typeof y !=='number' ){\n   return assert.fail('they not are numbers...')\n  }\n  return x + y\n}\nclass TestSum{\n  constructor(){}\n   trySumTest(sum:(x:any,y:any)=>number){\n    test('Testing \"sum\" method', () => {\n      assert.strictEqual(sum(0, 0), 0, 'should return zero');\n      assert.strictEqual(sum(0, 1), 1, 'should return one');\n      assert.strictEqual(sum(1, 1), 2, 'should return two');\n      assert.strictEqual(sum(1, '1a'), 2, 'should return two');//con esto comprobamos errores de tipo\n    });\n  }\n}\n const tester = new TestSum();//aqui mandamos llamar a la clase y hacemos pruebas->\n tester.trySumTest(sum)\nclass TesterExtra{\n  private _data :{[key: string]: any}={}\n  constructor(name?:any,age?:any,birth_date?:any,programming_languages?:any){\n    this._data.name = name\n    this._data.age = Number(age)\n    this._data.birth_date = new Date(birth_date)\n    this._data.programming_languages = programming_languages\n  }\n  ifAllExistTest(){\n    test('All exist?', () => {\n      assert.equal(true, Object.hasOwn(this._data,'name'),'test has name ok!');\n      assert.equal(true, Object.hasOwn(this._data,'age'),'test has age ok!');\n      assert.equal(true, Object.hasOwn(this._data,'birth_date'),'test has date ok!');\n      assert.equal(true, Object.hasOwn(this._data,'programming_languages'),'test has languages ok!');\n    });\n  }\n  typesAreOkTest(){\n    test('All types ok?', () => {\n      assert.equal(typeof this._data.name, 'string','test name is string?');\n      assert.equal(!isNaN(this._data.age),true,'test age is number?');\n      assert.equal(!isNaN(this._data.birth_date.getTime()), true,'test birth_date is date?');\n      assert.equal(Array.isArray(this._data.programming_languages),true,'test languages is Array?');\n    });\n  }\n  toString(){\n    console.log(this._data)\n  }\n}\nconst testerExtra = new TesterExtra('david','24','2024-12-31',['js','typescript','react'])\ntesterExtra.toString()\ntesterExtra.ifAllExistTest()\ntesterExtra.typesAreOkTest()\n\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/typescript/duendeintemporal.ts",
    "content": "/* { RETOS DE PROGRAMACIÓN }  #13 PRUEBAS UNITARIAS */\n// I refer to \"JavaScript Notes for Professionals\" from the people of Stack Overflow. https://goalkicker.com/JavaScriptBook\n// Additionally, I use GPT as a reference and sometimes to correct or generate proper comments.\n\n// Short for console.log\nlet log = console.log;\n\n// Welcome message\nlog('Welcome to the road of unit testing and error handling!');\n// Welcome to the road of unit testing and error handling!\n\n// Conditional check for browser environment\nif (typeof window !== 'undefined') {\n    window.addEventListener('load', () => {\n        const body: HTMLBodyElement | null = document.querySelector('body');\n        const title = document.createElement('h1');\n\n        body?.style.setProperty('background', '#000');\n        body?.style.setProperty('text-align', 'center');\n\n        title.textContent = 'Retosparaprogramadores #13.';\n        title.style.setProperty('font-size', '3.5vmax');\n        title.style.setProperty('color', '#fff');\n        title.style.setProperty('line-height', '100vh');\n\n        body?.appendChild(title);\n\n        setTimeout(() => {\n            alert('Retosparaprogramadores #13. Please open the Browser Developer Tools.');\n        }, 2000);\n        log('Retosparaprogramadores #13');\n    });\n} else {\n    log('This code is designed to run in a browser environment. Skipping window-related code.');\n    // This code is designed to run in a browser environment. Skipping window-related code.\n    log('Retosparaprogramadores #13');  // Retosparaprogramadores #13\n}\n\n/* GoalKicker.com – JavaScript® Notes for Professionals 219\nSection 30.9: Debugging with assertions - console.assert() Writes an error message to the console if the assertion is false. Otherwise, if the assertion is true, this does nothing. */\n\n// Demonstrate console.assert with intentional type mismatch\nconsole.assert('one' === String(1), 'Assertion failed: \"one\" is not equal to \"1\"');\n// Assertion failed: Assertion failed: \"one\" is not equal to \"1\"\n\n// Multiple arguments can be provided after the assertion–these can be strings or other objects–that will only be printed if the assertion is false:\nconsole.assert(true, 'Testing assertion...', null, undefined, Object);\n// Assertion failed: Testing assertion... null undefined [Function: Object]\n\nconsole.assert(false, 'Testing assertion...', null, undefined, Object);\n// Assertion failed: Testing assertion... NaN undefined function Object() { [native code] }\n\n/* console.assert does not throw an AssertionError (except in Node.js), meaning that this method is incompatible with most testing frameworks and that code execution will not break on a failed assertion. */\n\n// Custom assert function that logs an error instead of throwing\nconst assert = (condition: boolean, message: string, errors: string[]): void => {\n    if (!condition) {\n        console.error(message);\n        errors.push(message);\n    }\n};\n\n// Function to test\nconst sum = (a: number, b: number): number => {\n    if (typeof a !== 'number' || typeof b !== 'number') {\n        throw new TypeError('Both arguments must be numbers');\n    }\n    return a + b;\n};\n\n// Test cases for the sum function\nconst testSum = (errors: string[]): void => {\n    try {\n        assert(sum(2, 3) === 5, `Error: Expected 5 but got ${sum(2, 3)}`, errors);\n        assert(sum(-1, 1) === 0, `Error: Expected 0 but got ${sum(-1, 1)}`, errors);\n        assert(sum(0, 0) === 0, `Error: Expected 0 but got ${sum(0, 0)}`, errors);\n        assert(sum(1.1, 2.2) === 3.3, `Error: Expected 3.3 but got ${sum(1.1, 2.2)}`, errors);\n        assert(sum(Infinity, 1) === Infinity, `Error: Expected Infinity but got ${sum(Infinity, 1)}`, errors);\n        assert(isNaN(sum(NaN, 1)), `Error: Expected NaN but got ${sum(NaN, 1)}`, errors);\n\n        // Intentionally trigger an error (commented out to avoid crashing)\n        // sum(2, '3'); // Uncommenting this will throw a TypeError: Both arguments must be numbers\n    } catch (e: unknown) {\n        if (e instanceof TypeError) {\n            console.error('Caught an error:', e.message);\n            assert(e instanceof TypeError, 'Error: Invalid argument type not handled', errors);\n            assert(e.message === 'Both arguments must be numbers', 'Error: Argument type mismatch', errors);\n        }\n    }\n\n    log('All sum tests have been executed.');\n};\n\n// Define a type for the personalInfo object\ninterface PersonalInfo {\n    name: string;\n    age: number;\n    birth_date: string;\n    programming_languages: string[];\n}\n\n// Object to test\nconst personalInfo: PersonalInfo = {\n    name: \"Niko Zen\",\n    age: 41,\n    birth_date: \"1983/08/08\",\n    programming_languages: [\"JavaScript\", \"Python\", \"Rust\", \"Ruby\", \"Java\"]\n};\n\n// Test cases for the personalInfo object\nconst testPersonalInfo = (obj: PersonalInfo, errors: string[]): void => {\n    if (Object.keys(obj).length === 0) {\n        log('The obj is empty, skipping personal info tests.');\n        return;\n    }\n\n    try {\n        // Check that all fields exist\n        assert(obj.hasOwnProperty('name'), 'Missing field \"name\"', errors);\n        assert(obj.hasOwnProperty('age'), 'Missing field \"age\"', errors);\n        assert(obj.hasOwnProperty('birth_date'), 'Missing field \"birth_date\"', errors);\n        assert(obj.hasOwnProperty('programming_languages'), 'Missing field \"programming_languages\"', errors);\n\n        // Check data types\n        assert(typeof obj.name === 'string', `\"name\" must be a string but got ${typeof obj.name}`, errors);\n        assert(typeof obj.age === 'number', `\"age\" must be a number but got ${typeof obj.age}`, errors);\n\n        // Check if birth_date is a valid date\n        const birthDate = new Date(obj.birth_date);\n        assert(!isNaN(birthDate.getTime()), `\"birth_date\" must be a valid Date but got ${obj.birth_date}`, errors);\n\n        assert(Array.isArray(obj.programming_languages), `\"programming_languages\" is not an array but got ${typeof obj.programming_languages}`, errors);\n\n        // Validate each programming language\n        obj.programming_languages.forEach(lang => assert(typeof lang === 'string', `Each language must be a string but got ${typeof lang}`, errors));\n\n        // Check fields are not empty\n        assert(obj.name.length > 0, '\"name\" cannot be empty', errors);\n        assert(obj.age > 0, `\"age\" must be greater than 0 but got ${obj.age}`, errors);\n        assert(obj.birth_date.length > 0, '\"birth_date\" cannot be empty', errors);\n        assert(obj.programming_languages.length > 0, '\"programming_languages\" should have at least one language', errors);\n    } catch (e: unknown) {\n        if (e instanceof Error) {\n            console.error('Caught an error during personal info tests:', e.message); // Log the caught error\n        }\n    }\n\n    log('All personal info tests have been executed.');\n};\n\n// Empty object for testing\nconst nikitaInfo: PersonalInfo = {\n    name: \"\",\n    age: 0,\n    birth_date: \"\",\n    programming_languages: []\n};\n\n// Run tests\nconst errors: string[] = [];\ntestSum(errors);\ntestPersonalInfo(personalInfo, errors); // Should pass\ntestPersonalInfo(nikitaInfo, errors); // Should fail\n\n// Log all collected errors at the end\nif (errors.length > 0) {\n    log('Errors encountered during tests:');\n    errors.forEach(error => log(error));\n} else {\n    log('No errors encountered during tests.');\n}\n\n/* Final General Output:\nWelcome to the road of unit testing and error handling!\nThis code is designed to run in a browser environment. Skipping window-related code.\nAssertion failed: \"one\" is not equal to \"1\"\nAssertion failed: Testing assertion... null undefined function Object() { [native code] }\nAll sum tests have been executed.\nAll personal info tests have been executed.\nThe obj is empty, skipping personal info tests.\nErrors encountered during tests:\nError: Expected 3.3 but got 3.3000000000000003\nError: \"name\" cannot be empty\nError: \"age\" must be greater than 0 but got 0\nError: \"birth_date\" cannot be empty\nError: \"programming_languages\" should have at least one language\n*/"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/typescript/eulogioep.ts",
    "content": "// Definimos un tipo para las funciones matemáticas\ntype MathFunction = (a: number, b: number) => number;\n\n/**\n * Función que suma dos números y retorna el resultado.\n * @param a Primer número a sumar.\n * @param b Segundo número a sumar.\n * @returns La suma de a y b.\n */\nconst suma: MathFunction = (a, b) => {\n    return a + b;\n};\n\n/**\n * Enum para los lenguajes de programación\n */\nenum ProgrammingLanguage {\n    TypeScript = \"TypeScript\",\n    JavaScript = \"JavaScript\",\n    Python = \"Python\"\n}\n\n/**\n * Interfaz que define la estructura del objeto de datos personales.\n */\ninterface DatosPersonales {\n    readonly name: string;\n    age: number;\n    birth_date: string;\n    programming_languages: ProgrammingLanguage[];\n}\n\n/**\n * Crea y retorna un objeto con datos personales.\n * @returns Objeto con datos personales.\n */\nfunction crearObjeto(): DatosPersonales {\n    return {\n        name: \"Tu nombre\",\n        age: 30,\n        birth_date: \"1993-01-01\",\n        programming_languages: [ProgrammingLanguage.TypeScript, ProgrammingLanguage.JavaScript, ProgrammingLanguage.Python]\n    };\n}\n\n// Pruebas unitarias (usando una sintaxis similar a Jest, pero sin importar la librería)\ndescribe('Pruebas de la función suma', () => {\n    test('Suma de 2 y 3 debería ser 5', () => {\n        expect(suma(2, 3)).toBe(5);\n    });\n\n    test('Suma de -1 y 1 debería ser 0', () => {\n        expect(suma(-1, 1)).toBe(0);\n    });\n\n    test('Suma de -2 y -3 debería ser -5', () => {\n        expect(suma(-2, -3)).toBe(-5);\n    });\n});\n\ndescribe('Pruebas del objeto de datos personales', () => {\n    const objeto: DatosPersonales = crearObjeto();\n\n    test('El objeto debe contener todas las propiedades requeridas', () => {\n        expect(objeto).toHaveProperty('name');\n        expect(objeto).toHaveProperty('age');\n        expect(objeto).toHaveProperty('birth_date');\n        expect(objeto).toHaveProperty('programming_languages');\n    });\n\n    test('Los datos en el objeto deben ser correctos', () => {\n        expect(objeto.name).toBe(\"Tu nombre\");\n        expect(typeof objeto.age).toBe('number');\n        expect(objeto.birth_date).toMatch(/^\\d{4}-\\d{2}-\\d{2}$/);\n        expect(Array.isArray(objeto.programming_languages)).toBe(true);\n        expect(objeto.programming_languages.length).toBeGreaterThan(0);\n        expect(objeto.programming_languages).toContain(ProgrammingLanguage.TypeScript);\n    });\n});\n\n// Nota: Las funciones 'describe', 'test', 'expect', etc. no están definidas aquí.\n// En un entorno real, necesitarías importar estas funciones de una biblioteca de pruebas."
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/typescript/hozlucas28.ts",
    "content": "/*\n    Tests...\n*/\n\nconsole.log('Tests...')\n\nfunction add(a: number, b: number): number {\n\tif (typeof a !== 'number' || typeof b !== 'number') {\n\t\tthrow new Error('Invalid arguments! Both of them should be numbers')\n\t}\n\treturn a + b\n}\n\nconsole.log(`\\nfunction add(a: number, b: number): number {\n    if (typeof a !== 'number' || typeof b !== 'number') {\n        throw new Error('Invalid arguments! Both of them should be numbers')\n    }\n    return a + b\n}`)\n\nconsole.log(\n\t'\\n# ---------------------------------------------------------------------------------- #\\n'\n)\n\n/*\n    Additional challenge...\n*/\n\nconsole.log('Additional challenge...')\n\ntype Author = Readonly<{\n\tage: string\n\tbirth_date: string\n\tname: string\n\tprogramming_languages: string[]\n}>\n\nconst author: Author = {\n\tage: '22',\n\tbirth_date: '2002-02-20',\n\tname: 'Lucas',\n\tprogramming_languages: ['TypeScript', 'Python', 'Go (Golang)'],\n}\n\nconsole.log(`\\ntype Author = Readonly<{\n    age: string\n    birth_date: string\n    name: string\n    programming_languages: string[]\n}>\n\nconst author: Author = {\n    age: '22',\n    birth_date: '2002-02-20',\n    name: 'Lucas',\n    programming_languages: ['TypeScript', 'Python', 'Go (Golang)'],\n}`)\n\nexport type { Author }\n\nexport { add, author }\n\n/*\n\tToda declaración, debajo del presente comentario, debe ser extraída a un archivo con el mismo nombre\n\tque el actual, pero finalizando con `*.spec.ts`, por ejemplo: `hozlucas28.spec.ts`. Caso contrario los\n\ttests no se ejecutaran correctamente.\n*/\n\n/*\n    Tests...\n*/\n\ndescribe('Addition', () => {\n\tit('Numbers', () => {\n\t\tconst result: number = add(1, 4)\n\t\tconst expectedResult: number = 5\n\t\texpect(result).toBe<number>(expectedResult)\n\t})\n\n\tit('Floats', () => {\n\t\tconst result: number = add(2.25, 6.75)\n\t\tconst expectedResult: number = 9\n\t\texpect(result).toBe<number>(expectedResult)\n\t})\n\n\tit('Strings', () => {\n\t\t// @ts-expect-error\n\t\texpect(() => add('1', '4')).toThrow()\n\t})\n})\n\n/*\n    Additional challenge...\n*/\n\ndescribe('Dictionary', () => {\n\tit('Schema', () => {\n\t\tconst expectedResult: Author = {\n\t\t\tage: expect.any(String),\n\t\t\tbirth_date: expect.any(String),\n\t\t\tname: expect.any(String),\n\t\t\tprogramming_languages: expect.any(Array),\n\t\t}\n\n\t\texpect(author).toMatchObject(expectedResult)\n\t})\n\n\tit('Data types', () => {\n\t\tconst expectedResult: Author = {\n\t\t\tage: '22',\n\t\t\tbirth_date: '2002-02-20',\n\t\t\tname: 'Lucas',\n\t\t\tprogramming_languages: ['TypeScript', 'Python', 'Go (Golang)'],\n\t\t}\n\n\t\texpect(author).toStrictEqual(expectedResult)\n\t})\n})\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/typescript/marialunatito.ts",
    "content": "/**\n * Steps for test\n * 1. Copy tests in other file called `marialunatito.test.ts`\n * 2. Install npm init\n * 3. Install npm i jest\n * 4. Install npm i --save-dev @types/jest for run test\n * 5. in package.json set this script \"test\": \"jest\"\n * 6. descomment the import\n *  - `import { addition } from './marialunatito'`\n *  - `import { generateUser } from './marialunatito'`\n * 4. run command `npm run test marialunatito.test.ts`\n */\n\n///////////////////////// EJERCICIO DE SUMA /////////////////////////\n\nexport function addition(a: number, b: number) {\n  return a + b;\n}\n\n// import { addition } from './marialunatito'\n\ndescribe(\"Addition\", () => {\n  it(\"Should calculate of addition successful\", () => {\n    const mockA = Math.random() * 10;\n    const mockB = Math.random() * 10;\n\n    const result = addition(mockA, mockB);\n\n    expect(result).toEqual(result);\n  });\n});\n\n///////////////////////// DIFICULTAD EXTRA /////////////////////////\n\ninterface User {\n  name: string;\n  age: number;\n  birth_date: Date;\n  programming_languages: string[];\n}\n\nexport function generateUser(user: User) {\n  return user;\n}\n\n// import { generateUser } from './marialunatito'\n\ndescribe(\"Validate dictionary\", () => {\n  it(\"Should validate all fields exist\", () => {\n    const mockUser = {\n      name: \"Maria\",\n      age: 32,\n      birth_date: new Date(\"02/04/1992\"),\n      programming_languages: [\n        \"C#\",\n        \"C++\",\n        \"Go\",\n        \"Java\",\n        \"Javascript\",\n        \"Python\",\n        \"Ruby\",\n      ],\n    };\n\n    const user = generateUser(mockUser);\n    expect(user.name).toBeDefined();\n    expect(user.age).toBeDefined();\n    expect(user.birth_date).toBeDefined();\n    expect(user.programming_languages).toBeDefined();\n  });\n\n  it(\"Should validate successful all fields of dictionary are correctly\", () => {\n    const mockUser = {\n      name: \"Maria\",\n      age: 32,\n      birth_date: new Date(\"02/04/1992\"),\n      programming_languages: [\n        \"C#\",\n        \"C++\",\n        \"Go\",\n        \"Java\",\n        \"Javascript\",\n        \"Python\",\n        \"Ruby\",\n      ],\n    };\n\n    const user = generateUser(mockUser);\n    expect(user).toBe(mockUser);\n  });\n});\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/typescript/qwik-zgheib.ts",
    "content": "import assert from \"assert\";\n\nexport const sum = (a: number, b: number): number => a + b;\n\nfunction test(description: string, fn: () => void): void {\n  try {\n    fn();\n    console.log(`✔️  ${description}`);\n  } catch (error) {\n    console.log(`❌  ${description}`);\n    console.error(error);\n  }\n}\n\ntest(\"adds 1 + 2 to equal 3\", () => {\n  assert.strictEqual(sum(1, 2), 3);\n});\n\ntest(\"adds 1 + 1 to equal 2\", () => {\n  assert.strictEqual(sum(1, 1), 2);\n});\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/typescript/victor-Casta.ts",
    "content": "const assert = require('assert')\n/*\n  * EJERCICIO:\n  * Crea una función que se encargue de sumar dos números y retornar\n  * su resultado.\n  * Crea un test, utilizando las herramientas de tu lenguaje, que sea\n  * capaz de determinar si esa función se ejecuta correctamente.\n*/\n\nfunction addition(a: number, b: number): number {\n  return a + b\n}\n\ntry {\n  assert.equal(addition(1, 2), 3)\n  console.log(`Test 1: pasó. Resultado de la suma: ${addition(1, 2)}`)\n} catch (error) {\n  console.error(`Test 1: falló. Error: ${error.message}`)\n}\n\n/*\n  * Crea un diccionario con las siguientes claves y valores:\n  * \"name\": \"Tu nombre\"\n  * \"age\": \"Tu edad\"\n  * \"birth_date\": \"Tu fecha de nacimiento\"\n  * \"programming_languages\": [\"Listado de lenguajes de programación\"]\n  * Crea dos test:\n  * - Un primero que determine que existen todos los campos.\n  * - Un segundo que determine que los datos introducidos son correctos.\n*/\n\ninterface Person {\n  name: string;\n  age: number;\n  birthDate: Date;\n  programmingLanguages: string[];\n}\n\nconst person: Person = {\n  name: 'Victor',\n  age: 21,\n  birthDate: new Date(2002, 11, 17),\n  programmingLanguages: ['TypeScript', 'JavaScript', 'Python']\n};\n\nfunction validateStructure(expected: Person, actual: Person): void {\n  const expectedKeys = Object.keys(expected);\n  const actualKeys = Object.keys(actual);\n  assert.strictEqual(expectedKeys.length, actualKeys.length, 'Las estructuras no tienen el mismo número de claves.');\n  expectedKeys.forEach(key => {\n    assert.ok(actual.hasOwnProperty(key), `La propiedad \"${key}\" falta en el objeto real.`);\n  });\n}\n\nfunction validateValues(expected: Person, actual: Person): void {\n  const expectedKeys = Object.keys(expected);\n  expectedKeys.forEach(key => {\n    assert.strictEqual(typeof actual[key], typeof expected[key], `El tipo de la propiedad \"${key}\" no coincide.`);\n  });\n}\n\ntry {\n  validateStructure({\n    name: '',\n    age: 0,\n    birthDate: new Date(2002, 11, 17),\n    programmingLanguages: ['']\n  }, person);\n  console.log('Test 1: pasó. La estructura es correcta.');\n} catch (error) {\n  console.error('Test 1: falló. Error: ', error.message);\n}\n\ntry {\n  validateValues({\n    name: '',\n    age: 0,\n    birthDate: new Date(2002, 11, 17),\n    programmingLanguages: ['']\n  }, person);\n  console.log('Test 2: pasó. Los tipos son correctos.');\n} catch (error) {\n  console.error('Test 2: falló. Error: ', error.message);\n}"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/typescript/victoriaparraf.ts",
    "content": "//Se instala Jest y las dependencias necesarias\n//Se Configura Jest para TypeScript: Crea un archivo de configuración de Jest jest.config.js:\n/*\n\nmodule.exports = {\n    preset: 'ts-jest',\n    testEnvironment: 'node',\n};\n\n*/\n\nexport function sum(a: number, b: number): number {\n    return a + b;\n}\n\n//Crea el test para la función en un archivo llamado sum.test.ts:\n\n/*\nimport { sum } from './sum';\n\ntest('sums two numbers correctly', () => {\n    expect(sum(1, 2)).toBe(3);\n    expect(sum(-1, 1)).toBe(0);\n    expect(sum(0, 0)).toBe(0);\n    expect(sum(2.5, 2.5)).toBe(5);\n});\n\n*/\n\n//Ejecución de los Tests\n//Para ejecutar los tests, añade un script en el archivo package.json:\n\n/*\n\"scripts\": {\n    \"test\": \"jest\"\n}\n\n*/\n\n"
  },
  {
    "path": "Roadmap/13 - PRUEBAS UNITARIAS/vb.net/kenysdev.vb",
    "content": "' ╔══════════════════════════════════════╗\n' ║ Autor:  Kenys Alvarado               ║\n' ║ GitHub: https://github.com/Kenysdev  ║\n' ║ 2024 -  VB.NET                       ║\n' ╚══════════════════════════════════════╝\n'-----------------------------------------------\n'* PRUEBAS UNITARIAS\n'-----------------------------------------------\n' - Verifican que las unidades individuales de código (como \n'   funciones, métodos o clases) funcionen como se espera.\n' - Mas info: https://learn.microsoft.com/en-us/dotnet/core/testing/unit-testing-visual-basic-with-mstest\n\nImports Microsoft.VisualStudio.TestTools.UnitTesting\n\n' _________________________________________________________________________\n'* EJERCICIO #1\n'* Crea una función que se encargue de sumar dos números y retornar\n'  su resultado.\n'* Crea un test, utilizando las herramientas de tu lenguaje, que sea\n'  capaz de determinar si esa función se ejecuta correctamente.\n\nPublic Class FunSum\n    Public Shared Function Sum(a As Double, b As Double) As Double\n        Return a + b\n    End Function\nEnd Class\n\n<TestClass>\nPublic Class TestSum\n    <TestMethod>\n    Public Sub TestSumCorrect()\n        Assert.AreEqual(FunSum.Sum(5, 2), 7)\n        Assert.AreEqual(FunSum.Sum(2.5, 1.25), 3.75)\n        Assert.AreEqual(FunSum.Sum(-2, 1), -1)\n    End Sub\n\n    <TestMethod>\n    Public Sub TestSumIncorrect()\n        Assert.AreNotEqual(FunSum.Sum(1, 3), 5)\n    End Sub\nEnd Class\n\n' _________________________________________________________________________\n'* EJERCICIO #2\n'* Crea un diccionario con las siguientes claves y valores:\n'  - \"name\" \"Tu nombre\"\n'  - \"age\": \"Tu edad\"\n'  - \"birth_date\": \"Tu fecha de nacimiento\"\n'  - \"programming_languages\": [\"Listado de lenguajes de programación\"]\n'* Crea dos test:\n'  - Un primero que determine que existen todos los campos.\n'  - Un segundo que determine que los datos introducidos son correctos.\n\n<TestClass>\nPublic Class TestDict\n    ReadOnly dictUser As New Dictionary(Of String, Object) From {\n        {\"name\", \"Ken\"},\n        {\"age\", 121},\n        {\"birth_date\", \"1903-03-19\"},\n        {\"prog_langs\", New List(Of String) From {\"cs\", \"py\", \"vb\", \"rs\", \"js\"}}\n    }\n\n    <TestMethod>\n    Public Sub TestDicKeyExistence()\n        Assert.IsTrue(dictUser.ContainsKey(\"name\"))\n        Assert.IsTrue(dictUser.ContainsKey(\"age\"))\n        Assert.IsTrue(dictUser.ContainsKey(\"birth_date\"))\n        Assert.IsTrue(dictUser.ContainsKey(\"prog_langs\"))\n    End Sub\n\n    <TestMethod>\n    Public Sub TestDicValueTypes()\n        Assert.IsInstanceOfType(dictUser(\"name\"), GetType(String))\n        Assert.IsInstanceOfType(dictUser(\"age\"), GetType(Integer))\n        Assert.IsInstanceOfType(dictUser(\"birth_date\"), GetType(String))\n        Assert.IsInstanceOfType(dictUser(\"prog_langs\"), GetType(List(Of String)))\n    End Sub\n\n    <TestMethod>\n    Public Sub TestDicValueContent()\n        Assert.AreEqual(dictUser(\"name\"), \"Ken\")\n        Assert.AreEqual(dictUser(\"age\"), 121)\n        Assert.AreEqual(dictUser(\"birth_date\"), \"1903-03-19\")\n        CollectionAssert.AreEqual(\n            DirectCast(dictUser(\"prog_langs\"), List(Of String)),\n            New List(Of String) From {\"cs\", \"py\", \"vb\", \"rs\", \"js\"}\n        )\n    End Sub\nEnd Class\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/bash/arturonavas.sh",
    "content": "#!/usr/bin/bash\n: '\n/*\n * EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n */\n'\n\n# variables de fecha\nnow=$(date '+%Y-%m-%d %H:%M:%S')\nbirth='2004-11-20 12:00:00'\n\n#los datos son falsos!!!!\n\n# calculo de edad en años exactos\ncurrent_year=$(date '+%Y')\ncurrent_md=$(date '+%m%d')\nbirth_year=2004\nbirth_md=$(date -d \"$birth\" '+%m%d')\n\nage=$(( current_year - birth_year - 1))\n\n\necho \"::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\"\necho \"fecha actual:            $now\"\necho \"fecha nacimiento:        $birth\"\necho \"años transcurridos:      $age\"\necho \"::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\"\n\n# dificultad extra: 10 formatos distintos de la fecha de nacimiento\necho \"formato 1 (dd-mm-yyyy):          $(date -d \"$birth\" '+%d-%m-%Y')\"\necho \"formato 2 (hh:MM:ss):            $(date -d \"$birth\" '+%H:%M:%S')\"\necho \"formato 3 (dia del ano):         $(date -d \"$birth\" '+%j')\"\necho \"formato 4 (dia de la semana):    $(date -d \"$birth\" '+%A')\"\necho \"formato 5 (nomrbe del mes):      $(date -d \"$birth\" '+%B')\"\necho \"formato 6 (mes abreviado):       $(date -d \"$birth\" '+%b')\"\necho \"formato 7 (numero dia semana):   $(date -d \"$birth\" '+%u')\"\necho \"formato 8 (numero semana ano):   $(date -d \"$birth\" '+%V')\"\necho \"formato 9 (iso completo):        $(date -d \"$birth\" '+%Y-%m-%dT%H:%M:%S%z')\"\necho \"formato 10 (rfc):                $(date -d \"$birth\" '+%a, %d %b %Y %H:%M:%S %z')\"\necho \"::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\""
  },
  {
    "path": "Roadmap/14 - FECHAS/bash/rantamhack.sh",
    "content": "#!/bin/bash\n\n# * EJERCICIO:\n# * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n# * - Una primera que represente la fecha (di­a, mes, año, hora, minuto, segundo) actual.\n# * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n# * Calcula cuantos años han transcurrido entre ambas fechas.\n\n\necho -e \"\\n\\n=======================================EJERCICIO=======================================\\n\\n\"\n\nnow=$(date +\"%Y-%m-%d  %H:%M:%S\")\necho -e \"\\nLa fecha en el momento actual es: $now\"\n\nbirth_date=$(date -d \"1962-07-09 19:15:00\" +\"%Y-%m-%d %H:%M:%S\")\necho -e \"\\nLa fecha de nacimiento de Rantam fue: $birth_date\"\n\nfunction edad(){\n    current_year=$(date +\"%Y\")\n    birth_year=$(date -d \"$birth_date\" +\"%Y\")\n    age=$((current_year - birth_year))\n\n    echo -e \"\\nLa edad actual de rantam es: $age\"\n}\n\nedad\n\n\n \n\n# * DIFICULTAD EXTRA (opcional):\n# * Utilizando la fecha de tu cumpleaños, formateala y muestra su resultado de\n# * 10 maneras diferentes. Por ejemplo:\n# * - Dia, mes y año.\n# * - Hora, minuto y segundo.\n# * - Di­a del año.\n# * - Dia de la semana.\n# * - Nombre del mes.\n# * (lo que se te ocurra...)\n\n\necho -e \"\\n\\n=======================================DIFICULTAD EXTRA=======================================\\n\\n\"\n\n\necho -e \"\\nLa fecha de nacimiento de Rantam fue: \\n\"\n\necho -e \"\\n\\t 1.- Usando el formato por defecto de  ('AÑO-MES-DIA  HORA-MINUTO-SEGUNDO'): $birth_date\"\necho -e \"\\n\\t 2.- usando formato con textos: $(date -d \"$birth_date\" +\"%a %b %d %T %Y\")\"\necho -e \"\\n\\t 3.- Usando dia, mes y año: $(date -d \"$birth_date\" +\"%d/%m/%Y\")\"\necho -e \"\\n\\t 4.- Usando hora, minuto y segundo: $(date -d \"$birth_date\" +\"%H:%M:%S\")\"\necho -e \"\\n\\t 5.- Dia del año: $(date -d \"$birth_date\" +\"%j\")\"\necho -e \"\\n\\t 6.- Dia de la semana: $(date -d \"$birth_date\" +\"%A\")\"\necho -e \"\\n\\t 7.- Mes de nacimiento: $(date -d \"$birth_date\" +\"%B\")\"\necho -e \"\\n\\t 8.- Numero de semana del año: $(date -d \"$birth_date\" +\"%U\")\"\necho -e \"\\n\\t 9.- Dia de la semana, mes, dia,  numero de semana y año en texto: $(date -d \"$birth_date\" +\"%A, %d de %B, semana %U, del año %Y\")\"\necho -e \"\\n\\t10.- Hora de nacimiento en formato 12 horas: $(date -d \"$birth_date\" +\"%I:%M:%S%p\") PM\"\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/c#/Andreavzqz.cs",
    "content": "using System;\nusing System.Globalization;\n\nnamespace EjercicioFechas\n{\n    class Program\n    {\n        static void Main(string[] args)\n        {\n\n            //Fecha actual\n            DateTime fechaActual = DateTime.Now;\n\n            //Fecha de nacimiento\n            DateTime fechaNacimiento = new DateTime(1994, 05, 13, 14, 30, 0);\n\n            //Calcular años trasncurridos\n            int edad = fechaActual.Year - fechaNacimiento.Year;\n            if(fechaActual < fechaNacimiento.AddYears(edad))\n            {\n                edad--;\n            }\n            Console.WriteLine($\"Años transcurridos: {edad}\");\n\n\n            //Dificualtad extra formateo de la fecha de nacimiento de 10 maneras diferentes\n            Console.WriteLine(\"\\nFormatos de fechas de nacimiento:\");\n            Console.WriteLine($\"1. Dia, mes y año: {fechaNacimiento.ToString(dd/MM/yyy)}\");\n            Console.WriteLine($\"2. Hora, minuto y segundo: {fechaNacimiento.ToString(\"HH:mm:ss\")}\");\n            Console.WriteLine($\"3. Dia del año: {fechaNacimiento.DayOfWeek}\");\n            Console.WriteLine($\"4. Dia de la semana: {fechaNacimiento.DayOfWeek0}\");\n            Console.WriteLine($\"5. Nombre del mes: {fechaNacimiento.ToString(\"MMM\", CultureInfo.InvariantCulture)}\");\n            Console.WriteLine($\"6. Fecha completa corta: {fechaNacimiento.ToString(\"g\")}\");\n            Console.WriteLine($\"7. Fecha completa larga: {fechaNacimiento.ToString(\"F\")}\");\n            Console.WriteLine($\"8. Solo mes y año: {fechaNacimiento.ToString(\"MM/yyyy\")}\");\n            Console.WriteLine($\"9. Año en dos digitos: {fechaNacimiento.ToString(\"yy\")}\");\n            Console.WriteLine($\"10. Mes y nombre del dia: {fechaNacimiento.ToString(\"MMM dd\")}\");\n\n\n            // Formato personalizao\n            Console.WriteLine($\"\\nFecha actual: {fechaActual.ToString(\"ddd, dd MMM yyyy HH:mm:ss \")}\");\n        }\n    }\n\n/*\n\n- Explicación\n\nFecha Actual:\nSe obtiene utilizando DateTime.Now, que proporciona la fecha y hora actuales del sistema.\n\nFecha de Nacimiento:\nSe establece utilizando el constructor de DateTime con los parámetros año, mes, día, hora, minuto y segundo.\n\nCálculo de Años Transcurridos:\nSe calcula restando los años de ambas fechas. Si la fecha actual aún no ha alcanzado el día de cumpleaños en el año actual, se resta un año adicional.\n\n-Dificultad Extra: Formateo de Fecha de Nacimiento: \nSe muestran 10 formatos diferentes de la fecha de nacimiento utilizando el método ToString de DateTime con diferentes especificadores de formato:\nFormato \"dd/MM/yyyy\": Día, mes y año.\nFormato \"HH:mm\n\": Hora, minuto y segundo.\nDayOfYear: Día del año.\nDayOfWeek: Día de la semana.\nFormato \"MMMM\": Nombre del mes completo.\nFormato \"g\": Fecha completa corta.\nFormato \"F\": Fecha completa larga.\nFormato \"MM/yyyy\": Solo mes y año.\nFormato \"yy\": Año en dos dígitos.\nFormato \"MMMM dd\": Mes y nombre del día.\n\n*/\n\n}\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/c#/hequebo.cs",
    "content": "class Program\n{\n    static void Main(string[] args)\n    {\n        /*\n         * Para obtener la fecha actual se puede utilizar\n         * la propiedad UtcNow o Now de la clase DateTime\n         * la cual devuelve un objeto de tipo DateTime\n         */\n        var fechaActual = DateTime.UtcNow;\n        Console.WriteLine($\"Fecha Actual: {fechaActual}\");\n        /*\n         * Para crear una fecha personalizada se puede instanciar\n         * un objeto de la clase DateTime y a su constructor le\n         * podemos envíar varias combinaciones de parámetros\n         * una de ellas siendo (año, mes, día, hora, minutos y segundos)\n         */\n        var fechaNacimiento = new DateTime(1997, 07, 28, 8, 15, 3);\n        Console.WriteLine($\"Fecha de Nacimiento: {fechaNacimiento}\");\n        /*\n         * Para calcular la edad restamos la propiedad Year de nuestras\n         * fechas y si en la fecha actual no se ha cumplido años se\n         * ajusta restando un año a la edad\n         */\n        int edad = (fechaActual.Year - fechaNacimiento.Year);\n        if (fechaActual < fechaNacimiento.AddYears(edad))\n            edad--;\n        Console.WriteLine($\"La edad es de {edad} años\");\n\n        // Ejercicio extra\n        Console.WriteLine($\"1. Día del mes: {fechaNacimiento.ToString(\"dd\")}\");\n        Console.WriteLine($\"2. Día de la semana: {fechaNacimiento.ToString(\"dddd\")}\");\n        Console.WriteLine($\"3. Fecha corta: {fechaNacimiento.ToString(\"d\")}\");\n        Console.WriteLine($\"4. Fecha larga: {fechaNacimiento.ToString(\"D\")}\");\n        Console.WriteLine($\"5. Día y mes: {fechaNacimiento.ToString(\"M\")}\");\n        Console.WriteLine($\"6. Mes en dos dígitos: {fechaNacimiento.ToString(\"MM\")}\");\n        Console.WriteLine($\"7. Nombre del mes: {fechaNacimiento.ToString(\"MMMM\")}\");\n        Console.WriteLine($\"8. Hora minutos y segundos {fechaNacimiento.ToString(\"hh:m:ss\")}\");\n        Console.WriteLine($\"9. Año a dos dígitos: {fechaNacimiento.ToString(\"yy\")}\");\n        Console.WriteLine($\"10. Año a cuatro dígitos: {fechaNacimiento.ToString(\"yyyy\")}\");\n    }   \n}"
  },
  {
    "path": "Roadmap/14 - FECHAS/c#/isaacus98.cs",
    "content": "﻿/*\n * EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n */\n\nnamespace Roadmap\n{\n    internal class Program\n    {\n        static void Main(string[] args)\n        {\n            DateTime today = DateTime.Now;\n            DateTime birthdate = new DateTime(1998, 02, 13, 07, 00, 00, 00);\n            Console.WriteLine($\"Han transcurrido {today.AddYears(-birthdate.Year).Year} años\");\n\n            // reto extra\n            Console.WriteLine(\"Dia del año: \" + birthdate.DayOfYear);\n            Console.WriteLine(\"Dia de la semana: \" + birthdate.ToString(\"dddd\"));\n            Console.WriteLine(\"Fecha corta: \" + birthdate.ToString(\"d\"));\n            Console.WriteLine(\"Fecha larga: \" + birthdate.ToString(\"D\"));\n            Console.WriteLine(\"Nombre del mes: \" + birthdate.ToString(\"MMMM\"));\n            Console.WriteLine(\"Dia del mes: \" + birthdate.ToString(\"M\"));\n            Console.WriteLine(\"Hora, minuto, segundo: \" + birthdate.ToString(\"HH:mm:ss\"));\n            Console.WriteLine(\"Era: \" + birthdate.ToString(\"gg\"));\n            Console.WriteLine(\"Mes del año: \" + birthdate.ToString(\"Y\"));\n            Console.WriteLine(\"Fecha y hora en formato largo: \" + birthdate.ToString(\"F\"));\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/c#/jamerrq.cs",
    "content": "/*\n * EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n */\n\nusing System;\nusing System.Globalization;\n\nclass Dates\n{\n    static void Main(string[] args)\n    {\n        DateTime today = DateTime.Now;\n        DateTime birthDate = new DateTime(2000, 02, 21, 12, 00, 00, 00);\n        Console.WriteLine($\"Han transcurrido {today.AddYears(-birthDate.Year).Year} años\");\n        Console.WriteLine(\"#1 Dia del año: \" + birthDate.DayOfYear);\n        Console.WriteLine(\"#2 Dia de la semana: \" + birthDate.ToString(\"dddd\"));\n        Console.WriteLine(\"#3 Fecha corta: \" + birthDate.ToString(\"d\"));\n        Console.WriteLine(\"#4 Fecha larga: \" + birthDate.ToString(\"D\"));\n        Console.WriteLine(\"#5 Nombre del mes: \" + birthDate.ToString(\"MMMM\"));\n        Console.WriteLine(\"#6 Dia del mes: \" + birthDate.ToString(\"M\"));\n        Console.WriteLine(\"#7 Hora, minuto, segundo: \" + birthDate.ToString(\"HH:mm:ss\"));\n        Console.WriteLine(\"#8 Era: \" + birthDate.ToString(\"gg\"));\n        Console.WriteLine(\"#9 Mes del año: \" + birthDate.ToString(\"Y\"));\n        Console.WriteLine(\"#10 Fecha y hora en formato largo: \" + birthDate.ToString(\"F\"));\n    }\n}\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/c#/kenysdev.cs",
    "content": "/*\n╔═══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado                ║\n║ GitHub: https://github.com/Kenysdev   ║\n║ 2024 -  C#                            ║\n╚═══════════════════════════════════════╝\n-----------------------------------------------\n* FECHAS\n-----------------------------------------------\n- Mas info: \nhttps://www.netmentor.es/entrada/trabajando-con-fechas\nhttps://learn.microsoft.com/en-us/dotnet/api/system.datetime?view=net-8.0\n\n_______________________________________________\n* EJERCICIO 1\n* Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n* - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n* - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n* Calcula cuántos años han transcurrido entre ambas fechas.\n\"\"\"\n*/\nusing System.Globalization;\n\nDateTime currentDateTime = DateTime.Now;\nDateTime birthDate = new DateTime(1995, 10, 20, 2, 30, 0);\n\nTimeSpan difference = currentDateTime - birthDate;\nint years = difference.Days / 365;\nint months = (difference.Days % 365) / 30;\nint days = (difference.Days % 365) % 30;\n\nConsole.WriteLine(@$\"\nJuanito tiene: \n{years} años,\n{months} meses y\n{days} días.\");\n\n/* ____________________________________________\n# EJERCICIO 2\n* Utilizando la fecha de tu cumpleaños, formatéala y muestra su \n  resultado de 10 maneras diferentes.\n*/\n\nConsole.WriteLine($@\"\n1. Predeterminado -> {birthDate}\n2. Fecha larga    -> {birthDate.ToString(\"D\")}\n3. dd-MM-yyyy     -> {birthDate.ToString(\"dd-MM-yyyy\")}\n4. Nombre del mes -> {birthDate.ToString(\"MMMM\")}\n5. Mes abreviado  -> {birthDate.ToString(\"MMM\")}\n6. Nombre del día -> {birthDate.ToString(\"dddd\")}\n7. Día abreviado  -> {birthDate.ToString(\"ddd\")}\n8. Hora(24 horas) -> {birthDate.ToString(\"HH:mm:ss\")}\n9. Hora(12 horas) -> {birthDate.ToString(\n    \"hh:mm tt\", CultureInfo.InvariantCulture)}\n0. Personalizado  -> {birthDate.ToString(\n    \"Born on dddd, dd'th of' MMMM yyyy 'at' hh:mm:ss tt\")}\n\");\n\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/c++/hectorio23.cpp",
    "content": "#include <iostream>\n#include <chrono>\n#include <string>\n#include <ctime>\n\n/*\n* EJERCICIO:\n* Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n* - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n* - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n* Calcula cuántos años han transcurrido entre ambas fechas.\n*\n* DIFICULTAD EXTRA (opcional):\n* Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n* 10 maneras diferentes. Por ejemplo:\n* - Día, mes y año.\n* - Hora, minuto y segundo.\n* - Día de año.\n* - Día de la semana.\n* - Nombre del mes.\n* (lo que se te ocurra...)\n*/\n\n/*************************************************************\n********************* ZONA DE FUNCIONES **********************\n*************************************************************/\nstd::string currenTime() {\n    std::time_t t = std::time(nullptr);\n    std::tm* now = std::localtime(&t); \n\n    char buffer[128];\n    std::strftime(buffer, std::size(buffer), \"%d/%m/%Y %X\" ,now);\n\n    return buffer;\n};\n\nstd::string formatDate(const char* fmt, std::tm* date) {\n    char buffer[80];\n    std::strftime(buffer, std::size(buffer), fmt, date);\n\n    return buffer;\n}\n\n// FUNCION PRINCIPAL \nint main() {\n    // La siguiente instruccion imprime la fecha actual a la hora \n    // de ejecutar el código\n    std::cout << \"Tiempo actual: [ \" << currenTime() << \" ]\\n\";\n\n    // Creacion de una estructura customDate\n    struct tm customDate = { }; \n    customDate.tm_year = 2004 - 1900; // Año de mi nacimiento \n    customDate.tm_mon = 5; // Mes de mi nacimiento: Junio - 05\n    customDate.tm_mday = 28; // Dia de nacimiento\n    customDate.tm_hour = 12; // Hora de nacimiento\n    customDate.tm_min = 59; // Minuto de nacimiento\n\n    // Se crea una varlable de tipo buffer para almacenar la fecha ya formateada \n    char buffer[80];\n    std::strftime(buffer, std::size(buffer), \"%d/%m/%Y %X %P\", &customDate);\n\n    // De imprime la fecha\n    std::cout << \"Fecha de nacimiento: [ \" << buffer << \" ]\\n\";\n\n    // Convertir la fecha personalizada a un punto en el tiempo desde el epoch (1 de enero de 1970)\n    std::time_t customTime = std::mktime(&customDate);\n\n    // Crear un objeto de tiempo con la fecha personalizada\n    std::chrono::system_clock::time_point customPoint = std::chrono::system_clock::from_time_t(customTime);\n\n    // Obtener el tiempo actual\n    std::chrono::system_clock::time_point now = std::chrono::system_clock::now();\n\n    // Calcular la diferencia entre la fecha personalizada y el tiempo actual\n    auto difference = std::chrono::duration_cast<std::chrono::hours>(now - customPoint);\n\n    // Imprimir la diferencia en días\n    std::cout << \"Diferencia en años: \" << (float)difference.count() / 8760.0 << std::endl;\n\n\n    /**************************************************************************************\n    ************* IMPRESION DE LA FECHA DE NACIMIENTO EN DISTINTOS FORMATOS ***************\n    ***************************************************************************************/\n    std::cout << \"\\n************ FORMATO DE FECHA DE NACIMIENTO **********\\n\";\n    std::tm* localTime = std::localtime(&customTime);\n    std::cout << \"Formato 1: \" << formatDate(\"%d/%m/%Y\", localTime) << std::endl; // Formato: día/mes/año\n    std::cout << \"Formato 2: \" << formatDate(\"%m/%d/%Y\", localTime) << std::endl; // Formato: mes/día/año\n    std::cout << \"Formato 3: \" << formatDate(\"%Y-%m-%d\", localTime) << std::endl; // Formato: año-mes-día\n    std::cout << \"Formato 4: \" << formatDate(\"%d %b %Y\", localTime) << std::endl; // Formato: día abreviado mes año (ejemplo: 01 Jan 2024)\n    std::cout << \"Formato 5: \" << formatDate(\"%A, %d de %B de %Y\", localTime) << std::endl; // Formato: día de semana, día de mes de año (ejemplo: viernes, 01 de enero de 2024)\n    std::cout << \"Formato 6: \" << formatDate(\"%H:%M:%S\", localTime) << std::endl; // Formato: hora:minuto:segundo\n    std::cout << \"Formato 7: \" << formatDate(\"%I:%M:%S %p\", localTime) << std::endl; // Formato: hora:minuto:segundo AM/PM (ejemplo: 05:30:15 PM)\n    std::cout << \"Formato 8: \" << formatDate(\"%Y-%m-%d %H:%M:%S\", localTime) << std::endl; // Formato: año-mes-día hora:minuto:segundo\n    std::cout << \"Formato 9: \" << formatDate(\"%Y%m%d%H%M%S\", localTime) << std::endl; // Formato: año mes día hora minuto segundo (ejemplo: 20240101233000)\n    std::cout << \"Formato 10: \" << formatDate(\"%Y-%m-%dT%H:%M:%SZ\", localTime) << std::endl; // Formato: año-mes-díaThora:minuto:segundoZ (ejemplo: 2024-01-01T23:30:00Z)\n\n\n    return 0;\n}\n\n// std::string currentTime() {\n//     std::time_t t = std::time(nullptr);\n//     std::tm* now = std::localtime(&t); \n\n//     char buffer[128];\n//     std::strftime(buffer, std::size(buffer), \"%d/%m/%Y %X\" ,now);\n\n//     return buffer;\n// }"
  },
  {
    "path": "Roadmap/14 - FECHAS/c++/yeisonagm.cpp",
    "content": "/* EJERCICIO #14: FECHAS\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n */\n#include <iostream>\n#include <ctime>\n\nusing namespace std;\n\n// Crea un fecha personalizada\ntm createCustomDate(int day, int month, int year, int hour, int minute, int second) {\n    // Crea una estructura tm con los valores de la fecha\n    struct tm timeInfo = {0};\n    timeInfo.tm_mday = day;\n    timeInfo.tm_mon = month - 1;\n    timeInfo.tm_year = year - 1900;\n    timeInfo.tm_hour = hour;\n    timeInfo.tm_min = minute;\n    timeInfo.tm_sec = second;\n\n    return timeInfo;\n}\n\n// Formatea un fecha\nstd::string formatDate(const tm timeInfo, const string &format) {\n    char buffer[80];\n\n    // Formatea la fecha\n    strftime(buffer, 80, format.c_str(), &timeInfo);\n    return buffer;\n}\n\nint main() {\n    cout << \"EJERCICIO #14: FECHAS\" << endl;\n\n    // Fecha actual\n    time_t now = time(nullptr);\n    char *dt = ctime(&now);\n    cout << \"Hora actual: \" << dt << endl;\n\n    // Fecha de mi nacimiento\n    tm dateOfBirth = createCustomDate(16, 4, 2001, 17, 25, 10);\n    cout << \"Fecha de nacimiento: \" << formatDate(dateOfBirth, string(\"%Y-%m-%d %H:%M:%S\")) << endl;\n\n    // Calcula la diferencia de años\n    double diffSeconds = difftime(now, mktime(&dateOfBirth));\n    cout << \"Diferencia en segundos: \" << diffSeconds << endl;\n    double diffYears = diffSeconds / (60 * 60 * 24 * 365.25);\n    cout << \"Años transcurridos: \" << diffYears << endl;\n\n    // Dificultad extra\n    cout << \"\\nFecha de nacimiento (Formas diferentes):\" << endl;\n    cout << \"Día, mes y año: \" << formatDate(dateOfBirth, string(\"%d-%m-%Y\")) << endl;\n    cout << \"Hora, minuto y segundo: \" << formatDate(dateOfBirth, string(\"%H:%M:%S\")) << endl;\n    cout << \"Hora, minuto y segundo (Formato 12 horas): \" << formatDate(dateOfBirth, string(\"%I:%M:%S %p\")) << endl;\n    cout << \"Día de año: \" << formatDate(dateOfBirth, string(\"%j\")) << endl;\n    cout << \"Día de la semana: \" << formatDate(dateOfBirth, string(\"%A\")) << endl;\n    cout << \"Día de la semana (abreviado): \" << formatDate(dateOfBirth, string(\"%a\")) << endl;\n    cout << \"Nombre del mes: \" << formatDate(dateOfBirth, string(\"%B\")) << endl;\n    cout << \"Nombre del mes (abreviado): \" << formatDate(dateOfBirth, string(\"%b\")) << endl;\n    cout << \"Mes, número de dia, año: \" << formatDate(dateOfBirth, string(\"%B %d, %Y\")) << endl;\n    cout << \"Dia th, mes, año: \" << formatDate(dateOfBirth, string(\"%dth %B, %Y\")) << endl;\n    cout << \"Dia, mes y año (Formato largo): \" << formatDate(dateOfBirth, string(\"%A %d of %B del %Y\")) << endl;\n\n    return 0;\n}"
  },
  {
    "path": "Roadmap/14 - FECHAS/dart/teren91.dart",
    "content": "\nimport 'package:intl/intl.dart';\n\n/*\n * EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n */\n\n\nvoid main()\n{\n  DateTime date = DateTime.now();\n  DateTime birthDay = DateTime(1991, 9, 14, 1, 0, 0);\n  DateFormat dateFormatter = DateFormat('dd/MM/yyyy hh:mm');\n  Duration dateDifference = date.difference(birthDay);\n\n  print('Fecha actual: ' + dateFormatter.format(date));\n  print('Cumple      : ' + dateFormatter.format(birthDay));\n  print('Transcurrido: ${(dateDifference.inDays / 365).floor().toString()} años');\n\n  //Dificultad extra\n\n  DateFormat dateFormatter_ddMMyyyy = DateFormat('dd/MM/yyyy');\n  DateFormat dateFormatter_hhmmss = DateFormat('hh:mm:ss');\n  DateFormat dateFormatter_Completa = DateFormat('EEEE, dd MMMM, yyyy');\n  DateFormat dateFormatter_diaSemana = DateFormat('EEEE');\n  DateFormat dateFormatter_Mes = DateFormat('MMMM');\n\n  print('Cumple      : ' + dateFormatter_ddMMyyyy.format(birthDay));\n  print('Cumple      : ' + dateFormatter_hhmmss.format(birthDay));\n  print('Cumple      : ' + dateFormatter_Completa.format(birthDay));\n  print('Cumple      : ' + dateFormatter_diaSemana.format(birthDay));\n  print('Cumple      : ' + dateFormatter_Mes.format(birthDay));\n}"
  },
  {
    "path": "Roadmap/14 - FECHAS/ejercicio.md",
    "content": "# #14 FECHAS\n> #### Dificultad: Fácil | Publicación: 01/04/24 | Corrección: 08/04/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/14 - FECHAS/elixir/boterop.ex",
    "content": "defmodule Boterop.Dates do\n  @zone_abbr \"UTC\"\n  @utc_offset 3600\n  @std_offset 0\n  @time_zone \"Etc/UTC\"\n\n  def get_age(args) do\n    current_date = DateTime.now!(@time_zone)\n    date = to_date(args)\n\n    current_date\n    |> DateTime.diff(date, :day)\n    |> Kernel./(360)\n    |> trunc()\n  end\n\n  def inspect_age(args) do\n    args\n    |> get_age()\n    |> IO.inspect()\n\n    args\n  end\n\n  def format(args, format_str) do\n    args\n    |> to_date()\n    |> Calendar.strftime(format_str)\n  end\n\n  def inspect_format(args, format_str) do\n    args\n    |> format(format_str)\n    |> IO.inspect()\n\n    args\n  end\n\n  defp to_date(args) do\n    {day, month, year} = get_keys(args)\n\n    %DateTime{\n      day: day,\n      month: month,\n      year: year,\n      hour: 14,\n      minute: 30,\n      second: 15,\n      zone_abbr: @zone_abbr,\n      utc_offset: @utc_offset,\n      std_offset: @std_offset,\n      time_zone: @time_zone\n    }\n  end\n\n  defp get_keys(args) do\n    day = Keyword.get(args, :day, 1)\n    month = Keyword.get(args, :month, 1)\n    year = Keyword.get(args, :year, 2000)\n    {day, month, year}\n  end\nend\n\nbirth_date = [day: 09, month: 10, year: 1999]\n\nbirth_date\n|> Boterop.Dates.inspect_age()\n|> Boterop.Dates.inspect_format(\"%d/%m/%y\")\n|> Boterop.Dates.inspect_format(\"%I:%M:%S %p\")\n|> Boterop.Dates.inspect_format(\"%j\")\n|> Boterop.Dates.inspect_format(\"%A\")\n|> Boterop.Dates.inspect_format(\"%B\")\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/go/DaFi02.go",
    "content": "package main\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n)\n\nfunc main() {\n\tvar date_actual string\n\n\tdate_actual = time.Now().Format(\"2006-01-02 15:04:05\")\n\tfmt.Println(\"Fecha actual: \", date_actual)\n\tfmt.Printf(\"Inserte su fecha de nacimiento con el siguiente formato (yyyy-mm-dd HH:MM:SS): \")\n\n\treader := bufio.NewReader(os.Stdin)\n\tdate_birth, _ := reader.ReadString('\\n')\n\n\tdate_birth = strings.TrimSuffix(date_birth, \"\\n\")\n\n\tage_actual := date_actual[:4] + date_actual[5:7] + date_actual[8:10] + date_actual[11:13] + date_actual[14:16] + date_actual[17:19]\n\tage_birth := date_birth[:4] + date_birth[5:7] + date_birth[8:10] + date_birth[11:13] + date_birth[14:16] + date_birth[17:19]\n\n\tage_actual_number, _ := strconv.Atoi(age_actual)\n\tage_bith_number, _ := strconv.Atoi(age_birth)\n\toperation := age_actual_number - age_bith_number\n\tage_result := strconv.Itoa(operation)\n\n\tfmt.Println(\"La cantidad de años entre ambas fechas es tu edad por lo tanto ...\")\n\tfmt.Println(\"Edad:\", age_result[:2])\n\n\t// Dificultad extra (OPCIONAL)\n\t// Formatear las fechas de cumpleaños :3\n\tfmt.Println(\"--------------------\")\n\tfmt.Println(\"A continuación daremos diferentes maneras de presentar los datos :D \")\n\tfmt.Printf(\"Tu naciste el día '%s', del mes '%s' y del año '%s'\\n\", date_birth[8:10], know_month(date_birth[5:7]), date_birth[:4])\n\tfmt.Printf(\"Tu naciste a a las '%s' con minutos '%s' con '%s' segundos XD\\n\", date_birth[11:13], date_birth[14:16], date_birth[17:19])\n\tfmt.Printf(\"Tu naciste en el mes de: '%s'\\n\", know_month(date_birth[5:7]))\n\tfmt.Printf(know_leap_year(date_birth[:4]) + \"\\n\")\n\tfmt.Printf(\"Naciste el día '%s' del mes '%s' a las '%s' horas\\n\", date_birth[8:10], know_month(date_birth[5:7]), date_birth[11:13])\n\tfmt.Printf(know_day(date_birth[11:13]) + \"\\n\")\n\tfmt.Printf(\"Tu signo zodiacal es: '%s'\\n\", know_star_sing(date_birth[5:7]+date_birth[8:10]))\n\tfmt.Printf(\"Naciste en el año chino de: '%s', que es el año: '%s'\\n\", know_chino(date_birth[:4]), date_birth[:4])\n\tfmt.Printf(\"Ahora pondremos en otro orden tu fecha de nacimiento de: dd-mm-yyyy: '%s-%s-%s'\\n\", date_birth[8:10], date_birth[5:7], date_birth[:4])\n\tfmt.Printf(\"Naciste en el año: '%s' el día '%s' a las '%s' horas\\n\", date_birth[:4], date_birth[8:10], date_birth[11:13])\n}\n\nfunc know_month(month string) string {\n\tname_month := map[string]string{\n\t\t\"01\": \"January\",\n\t\t\"02\": \"February\",\n\t\t\"03\": \"March\",\n\t\t\"04\": \"April\",\n\t\t\"05\": \"May\",\n\t\t\"06\": \"June\",\n\t\t\"07\": \"July\",\n\t\t\"08\": \"August\",\n\t\t\"09\": \"September\",\n\t\t\"10\": \"October\",\n\t\t\"11\": \"November\",\n\t\t\"12\": \"December\",\n\t}\n\n\treturn name_month[month]\n}\nfunc know_leap_year(age string) string {\n\tage_int, _ := strconv.Atoi(age)\n\n\tif age_int%4 == 0 && age_int%100 != 0 {\n\t\treturn \"Naciste En un año Bisiesto\"\n\t}\n\treturn \"No naciste en un año bisiesto :c\"\n}\n\nfunc know_day(hour string) string {\n\thour_int, _ := strconv.Atoi(hour)\n\n\tif hour_int >= 6 && hour_int <= 12 {\n\t\treturn \"Naciste en la mañana\"\n\t} else if hour_int >= 13 && hour_int <= 19 {\n\t\treturn \"Naciste en la tarde\"\n\t} else if hour_int >= 20 && hour_int <= 23 {\n\t\treturn \"Naciste en la noche\"\n\t} else {\n\t\treturn \"Naciste en la madrugada\"\n\t}\n}\n\nfunc know_star_sing(month_day string) string {\n\tmonth_day_int, _ := strconv.Atoi(month_day)\n\n\tif month_day_int >= 321 && month_day_int <= 419 {\n\t\treturn \"Aries\"\n\t} else if (month_day_int >= 420 && month_day_int <= 520) || (month_day_int >= 219 && month_day_int <= 320) {\n\t\treturn \"Tauro\"\n\t} else if (month_day_int >= 521 && month_day_int <= 620) || (month_day_int >= 321 && month_day_int <= 420) {\n\t\treturn \"Géminis\"\n\t} else if (month_day_int >= 621 && month_day_int <= 722) || (month_day_int >= 421 && month_day_int <= 520) {\n\t\treturn \"Cáncer\"\n\t} else if (month_day_int >= 723 && month_day_int <= 822) || (month_day_int >= 521 && month_day_int <= 621) {\n\t\treturn \"Leo\"\n\t} else if (month_day_int >= 823 && month_day_int <= 922) || (month_day_int >= 622 && month_day_int <= 722) {\n\t\treturn \"Virgo\"\n\t} else if (month_day_int >= 923 && month_day_int <= 1022) || (month_day_int >= 723 && month_day_int <= 822) {\n\t\treturn \"Libra\"\n\t} else if (month_day_int >= 1023 && month_day_int <= 1121) || (month_day_int >= 823 && month_day_int <= 922) {\n\t\treturn \"Escorpio\"\n\t} else if (month_day_int >= 1122 && month_day_int <= 1221) || (month_day_int >= 923 && month_day_int <= 1022) {\n\t\treturn \"Sagitario\"\n\t} else if (month_day_int >= 1222 || month_day_int <= 119) || (month_day_int >= 1023 && month_day_int <= 1121) {\n\t\treturn \"Capricornio\"\n\t} else if (month_day_int >= 120 && month_day_int <= 218) || (month_day_int >= 1122 && month_day_int <= 1221) {\n\t\treturn \"Acuario\"\n\t} else {\n\t\treturn \"Piscis\"\n\t}\n}\n\nfunc know_chino(age string) string {\n\tage_int, _ := strconv.Atoi(age)\n\n\tif age_int%12 == 0 {\n\t\treturn \"Mono\"\n\t} else if age_int%12 == 1 {\n\t\treturn \"Gallo\"\n\t} else if age_int%12 == 2 {\n\t\treturn \"Perro\"\n\t} else if age_int%12 == 3 {\n\t\treturn \"Cerdo\"\n\t} else if age_int%12 == 4 {\n\t\treturn \"Rata\"\n\t} else if age_int%12 == 5 {\n\t\treturn \"Buey\"\n\t} else if age_int%12 == 6 {\n\t\treturn \"Tigre\"\n\t} else if age_int%12 == 7 {\n\t\treturn \"Conejo\"\n\t} else if age_int%12 == 8 {\n\t\treturn \"Dragón\"\n\t} else if age_int%12 == 9 {\n\t\treturn \"Serpiente\"\n\t} else if age_int%12 == 10 {\n\t\treturn \"Caballo\"\n\t}\n\treturn \"Cabra\"\n}\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/go/MiguelP-Dev.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"time\"\n)\n\n// now Hora actual\nvar now = time.Now()\n\n// birthDate Fecha de naciemiento\nvar birthDate = time.Date(1993, 10, 13, 14, 35, 50, 0, time.UTC)\n\n// datePassed Tiempo trasncurrido entre ambas fechas.\nvar datePassed = now.Sub(birthDate)\n\nfunc main() {\n\tfmt.Printf(\"Horas Transcurridas: %v, Minutos Trasncurridos: %v, Tipo de dato: %T.\\n\", datePassed.Hours(), datePassed.Minutes(), datePassed)\n\n\t// Extra\n\t// \"2006-01-02 15:04:05\" Esta es la fecha de nacimiento de golang y es la fecha que se usa como\n\t//  una plantilla a la hora de dar formato a las fechas.\n\n\texampleOne := now.Format(\"2006/01/02\")\n\tfmt.Println(\"Date formatted in reversed order:\", exampleOne)\n\n\texampleTwo := now.Format(\"02/01/2006\")\n\tfmt.Println(\"Date formatted with slash as separators:\", exampleTwo)\n\n\texampleThree := now.Format(\"15:04:05\")\n\tfmt.Println(\"Formatted Time Clock:\", exampleThree)\n\n\texampleFour := now.Year()\n\tfmt.Println(\"Actual Year:\", exampleFour)\n\n\tMadrid, _ := time.LoadLocation(\"Europe/Madrid\")\n\texampleFive := now.In(Madrid)\n\tfmt.Println(\"Time in Spesific Location(Madrid):\", exampleFive)\n\n\texampleSix := now.YearDay()\n\tfmt.Println(\"Day of the year:\", exampleSix)\n\n\texampleSeven := now.Month()\n\tfmt.Println(\"Month of year:\", exampleSeven)\n\n\texampleEith, week := now.ISOWeek()\n\tfmt.Printf(\"ISO 8601 formatted year: %v, and week number: %v\\n\", exampleEith, week)\n\n\texampleNine, integer := now.Zone()\n\tfmt.Println(\"exampleNine: \", exampleNine, integer)\n\n\texampleTen := now.Location()\n\tfmt.Println(\"Location returns the time zone information: \", exampleTen)\n\n\t// Obtengo los valores de Now por separado Primero con la fecha y luego con el reloj\n\tyear, month, day := now.Date()\n\thour, minute, second := now.Clock()\n\tfmt.Printf(\"Day: %v, Month: %v, Year: %v\\n\", day, month, year)\n\tfmt.Printf(\"Hour: %v, Minute: %v, Second: %v\\n\", hour, minute, second)\n\n\ttwoHoursLater := now.Add(2 * time.Hour)\n\tfmt.Println(\"Adding two hours to actual date hour\", twoHoursLater)\n\n\tfromHoursBefore := now.Add(-2 * time.Hour)\n\tfmt.Println(\"Substracting two hours to actual date hour\", fromHoursBefore)\n\n}\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/go/N0HagoNada.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"time\"\n)\n\nfunc main() {\n\t// Fecha actual\n\tfechaActual := time.Now()\n\n\t// Fecha de nacimiento (ejemplo: 1 de enero de 1990 a las 10:30 AM)\n\tfechaNacimiento := time.Date(1990, time.January, 1, 10, 30, 0, 0, time.Local)\n\n\t// Cálculo de la diferencia entre las fechas\n\tdiferencia := fechaActual.Sub(fechaNacimiento)\n\tyears := int(diferencia.Hours() / 24 / 365)\n\n\tfmt.Printf(\"Fecha actual: %s\\n\", fechaActual.Format(\"2006-01-02 15:04:05\"))\n\tfmt.Printf(\"Fecha de nacimiento: %s\\n\", fechaNacimiento.Format(\"2006-01-02 15:04:05\"))\n\tfmt.Printf(\"Años transcurridos: %d\\n\", years)\n\n\t/***************************** RETO ************************************************/\n\t// Formatos diferentes para la fecha de nacimiento\n\tfmt.Println(\"\\nFormatos diferentes para la fecha de nacimiento:\")\n\tfmt.Printf(\"1. Día, mes y año: %d-%d-%d\\n\", fechaNacimiento.Day(), fechaNacimiento.Month(), fechaNacimiento.Year())\n\tfmt.Printf(\"2. Hora, minuto y segundo: %02d:%02d:%02d\\n\", fechaNacimiento.Hour(), fechaNacimiento.Minute(), fechaNacimiento.Second())\n\tfmt.Printf(\"3. Día del año: %d\\n\", fechaNacimiento.YearDay())\n\tfmt.Printf(\"4. Día de la semana: %s\\n\", fechaNacimiento.Weekday())\n\tfmt.Printf(\"5. Nombre del mes: %s\\n\", fechaNacimiento.Month().String())\n\tfmt.Printf(\"6. Formato personalizado: %d/%d/%d %02d:%02d\\n\", fechaNacimiento.Day(), int(fechaNacimiento.Month()), fechaNacimiento.Year(), fechaNacimiento.Hour(), fechaNacimiento.Minute())\n\tfmt.Printf(\"7. RFC 3339: %s\\n\", fechaNacimiento.Format(time.RFC3339))\n\tfmt.Printf(\"8. RFC 1123: %s\\n\", fechaNacimiento.Format(time.RFC1123))\n\tfmt.Printf(\"9. RFC 822: %s\\n\", fechaNacimiento.Format(time.RFC822))\n\tfmt.Printf(\"10. Stamp: %d\\n\", fechaNacimiento.Unix())\n}\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/go/hozlucas28.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"time\"\n)\n\nfunc main() {\n\t/*\n\t\tDates...\n\t*/\n\n\tfmt.Println(\"Dates...\")\n\n\tvar today time.Time = time.Now()\n\tvar bornDate time.Time = time.Date(2002, time.February, 20, 0, 0, 0, 0, time.UTC)\n\n\tfmt.Printf(\"\\nToday is: %v\\n\", today)\n\tfmt.Printf(\"\\nLucas Hoz born date: %v\\n\", bornDate)\n\n\tvar yearsBetweenDates int = today.Year() - bornDate.Year()\n\tfmt.Printf(\"\\nYears between today and born date: %d years\\n\", yearsBetweenDates)\n\n\tfmt.Println(\"\\n# ---------------------------------------------------------------------------------- #\")\n\n\t/*\n\t\tAdditional challenge...\n\t*/\n\n\tfmt.Println(\"\\nAdditional challenge...\")\n\n\tfmt.Printf(\"\\nDay, month, and year: %d, %d, and %d\\n\", bornDate.Day(), bornDate.Month(), bornDate.Year())\n\n\tfmt.Printf(\"\\nHours, minutes, and seconds: %d hours, %d minutes, and %d seconds\\n\", bornDate.Hour(), bornDate.Minute(), bornDate.Second())\n\n\tfmt.Printf(\"\\nDay of the year: %d\\n\", bornDate.YearDay())\n\n\tfmt.Printf(\"\\nDay of the week (weeks starts on sunday): %d\\n\", bornDate.Weekday()+1)\n\n\tfmt.Printf(\"\\nMonth name: %s\\n\", bornDate.Local().Month())\n}\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/go/kodenook.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"time\"\n)\n\nfunc main() {\n\tbirthday := time.Date(1996, 7, 27, 14, 30, 0, 0, time.Local)\n\tdiff := time.Now().Sub(birthday)\n\n\tfmt.Printf(\"difference: %.2f years\", diff.Hours()/24/365)\n}\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/go/qwik-zgheib.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"time\"\n)\n\ntype DateOperations interface {\n\tYearsBetween(date1, date2 time.Time) int\n\tFormatDate(date time.Time, format string) string\n}\n\ntype DateService struct{}\n\nfunc NewDateService() *DateService {\n\treturn &DateService{}\n}\n\nfunc (d *DateService) YearsBetween(date1, date2 time.Time) int {\n\tyears := date2.Year() - date1.Year()\n\tif date2.YearDay() < date1.YearDay() {\n\t\tyears--\n\t}\n\treturn years\n}\n\nfunc (d *DateService) FormatDate(date time.Time, format string) string {\n\treturn date.Format(format)\n}\n\nfunc main() {\n\tvar dateService DateOperations = NewDateService()\n\n\tcurrentDate := time.Now()\n\tbirthDate := time.Date(2002, time.November, 9, 10, 0, 0, 0, time.UTC)\n\n\tyears := dateService.YearsBetween(birthDate, currentDate)\n\tfmt.Printf(\"Years between %v and %v: %d\\n\", birthDate, currentDate, years)\n\n\t// extra challenge\n\tformats := []string{\n\t\t\"02-01-2006\",\n\t\t\"15:04:05\",\n\t\t\"02 January 2006\",\n\t\t\"Monday, 02 Jan 2006\",\n\t\t\"2006-01-02 15:04:05\",\n\t\t\"02\",\n\t\t\"01\",\n\t\t\"2006\",\n\t\t\"02-01\",\n\t\t\"01-2006\",\n\t}\n\n\tdescriptions := []string{\n\t\t\"Day-Month-Year\",\n\t\t\"Hour:Minute:Second\",\n\t\t\"Day Month Year\",\n\t\t\"Weekday, Day Month Year\",\n\t\t\"ISO format\",\n\t\t\"Day\",\n\t\t\"Month\",\n\t\t\"Year\",\n\t\t\"Day-Month\",\n\t\t\"Month-Year\",\n\t}\n\n\tfor i, format := range formats {\n\t\tformattedDate := dateService.FormatDate(birthDate, format)\n\t\tfmt.Printf(\"%s: %s\\n\", descriptions[i], formattedDate)\n\t}\n}\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/go/raynerpv2022.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"time\"\n)\n\n// /*\n//  * EJERCICIO:\n//  * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n//  * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n//  * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n//  * Calcula cuántos años han transcurrido entre ambas fechas.\n//  *\n\nfunc main() {\n\tnow := time.Now()\n\tfmt.Printf(\"Date of today %v:\\n\", now)\n\tbirthDate := time.Date(1979, time.December, 26, 19, 00, 00, 00, time.UTC)\n\tfmt.Printf(\"Date of my Birthday %v:\\n\", birthDate)\n\tdif := now.Year() - birthDate.Year()\n\tfmt.Printf(\"How many years since I was born %v:\\n\", dif)\n\n\t//  * DIFICULTAD EXTRA (opcional):\n\t//  * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n\t//  * 10 maneras diferentes. Por ejemplo:\n\t//  * - Día, mes y año.\n\t//  * - Hora, minuto y segundo.\n\t//  * - Día de año.\n\t//  * - Día de la semana.\n\t//  * - Nombre del mes.\n\t//  * (lo que se te ocurra...)\n\t//  */\n\n\t// date := birthDate.Format(\"Dia/Mes/Ano\")\n\tfmt.Printf(\" Date : %v/%v/%v \\n\", birthDate.Day(), birthDate.Month(), birthDate.Year())\n\tfmt.Printf(\" Time : %v:%v:%v \\n\", birthDate.Hour(), birthDate.Minute(), birthDate.Second())\n\tfmt.Printf(\" Date of the year: %v \\n\", birthDate.YearDay())\n\tfmt.Printf(\" MOnth: %v \\n\", birthDate.Month())\n\n}\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/go/thegera4.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"time\"\n)\n\nfunc main() {\n\ttoday := time.Now()\n\tbirthDate := time.Date(1987, time.July, 3, 12, 38, 45, 0, time.UTC)\n\tpassedYears := today.Year() - birthDate.Year()\n\n\tif today.YearDay() < birthDate.YearDay() {\n\t\tpassedYears--\n\t}\n\tfmt.Printf(\"Han transcurrido %d años desde mi nacimiento\\n\", passedYears)\n\n\t// Extra: Formateo de la fecha de nacimiento\n\tfmt.Printf(\"Fecha de nacimiento 1: %s\\n\", birthDate.Format(\"02/01/2006 15:04:05\"))\n\tfmt.Printf(\"Fecha de nacimiento 2: %s\\n\", birthDate.Format(\"02/01/2006 03:04:05 PM\"))\n\tfmt.Printf(\"Fecha de nacimiento 3: %s\\n\", birthDate.Format(\"2 de julio de 2006 a las 15:04:05\"))\n\tfmt.Printf(\"Fecha de nacimiento 4: %s\\n\", birthDate.Format(\"viernes 2 de julio de 2006\"))\n\tfmt.Printf(\"Fecha de nacimiento 5: %s\\n\", birthDate.Format(\"2/julio/2006\"))\n\tfmt.Printf(\"Fecha de nacimiento 6: %s\\n\", birthDate.Format(\"02-01-2006\"))\n\tfmt.Printf(\"Fecha de nacimiento 7: %s\\n\", birthDate.Format(\"02-01-06\"))\n\tfmt.Printf(\"Fecha de nacimiento 8: %s\\n\", birthDate.Format(\"02-01-06 15:04:05\"))\n\tfmt.Printf(\"Fecha de nacimiento 9: %s\\n\", birthDate.Format(\"02-01-06 03:04:05 PM\"))\n\tfmt.Printf(\"Fecha de nacimiento 10: %s\\n\", birthDate.Format(\"02-01-06 03:04 PM\"))\n}"
  },
  {
    "path": "Roadmap/14 - FECHAS/java/AmadorQuispe.java",
    "content": "public class ExampleFechas {\n    public static void main(String[] args) {\n        LocalDateTime actual = LocalDateTime.now();\n        LocalDateTime birthDate = LocalDateTime.of(1992, 07, 13, 01, 52, 35);\n        Period period = Period.between(birthDate.toLocalDate(), actual.toLocalDate());\n        System.out.println(period.getYears() + \" años\");\n        System.out.println(period.getMonths() + \" meses\");\n        System.out.println(period.getDays() + \" días\");\n\n    }\n\n}"
  },
  {
    "path": "Roadmap/14 - FECHAS/java/AnaLauDB.java",
    "content": "import java.time.LocalDateTime;\nimport java.time.LocalDate;\nimport java.time.Period;\nimport java.time.format.DateTimeFormatter;\nimport java.time.DayOfWeek;\nimport java.time.Month;\n\npublic class AnaLauDB {\n    public static void main(String[] args) {\n\n        // 1. Fecha y hora actual\n        LocalDateTime ahora = LocalDateTime.now();\n        System.out.println(\"Fecha y hora actual: \" + ahora);\n\n        // 2. Fecha de nacimiento\n        LocalDateTime nacimiento = LocalDateTime.of(2002, 5, 9, 15, 30, 15);\n        System.out.println(\"Fecha de nacimiento: \" + nacimiento);\n\n        // 3. Calcular años transcurridos\n        LocalDate hoy = LocalDate.now();\n        LocalDate cumple = nacimiento.toLocalDate();\n        Period periodo = Period.between(cumple, hoy);\n        System.out.println(\"Años transcurridos: \" + periodo.getYears());\n\n        // DIFICULTAD EXTRA: 10 formatos diferentes\n        System.out.println(\"\\nFormatos de la fecha de nacimiento:\");\n        // 1. Día, mes y año\n        System.out.println(\"1. Día/Mes/Año: \" + nacimiento.format(DateTimeFormatter.ofPattern(\"dd/MM/yyyy\")));\n        // 2. Hora, minuto y segundo\n        System.out.println(\"2. Hora:Minuto:Segundo: \" + nacimiento.format(DateTimeFormatter.ofPattern(\"HH:mm:ss\")));\n        // 3. Día de la semana\n        DayOfWeek diaSemana = nacimiento.getDayOfWeek();\n        System.out.println(\"3. Día de la semana: \" + diaSemana);\n        // 4. Día del año\n        System.out.println(\"4. Día del año: \" + nacimiento.getDayOfYear());\n        // 5. Nombre del mes\n        Month mes = nacimiento.getMonth();\n        System.out.println(\"5. Nombre del mes: \" + mes);\n        // 6. Fecha larga\n        System.out.println(\n                \"6. Fecha larga: \" + nacimiento.format(DateTimeFormatter.ofPattern(\"EEEE, d 'de' MMMM 'de' yyyy\")));\n        // 7. Fecha y hora ISO\n        System.out.println(\"7. ISO: \" + nacimiento.toString());\n        // 8. Año y mes\n        System.out.println(\"8. Año y mes: \" + nacimiento.format(DateTimeFormatter.ofPattern(\"yyyy-MM\")));\n        // 9. Solo año\n        System.out.println(\"9. Solo año: \" + nacimiento.getYear());\n        // 10. Fecha y hora personalizada\n        System.out.println(\n                \"10. Personalizado: \" + nacimiento.format(DateTimeFormatter.ofPattern(\"dd MMM yyyy, hh:mm a\")));\n    }\n}\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/java/FranDev200.java",
    "content": "package _14_Fechas;\n\nimport java.time.Duration;\nimport java.time.LocalDateTime;\nimport java.time.Period;\nimport java.time.format.DateTimeFormatter;\nimport java.util.Locale;\n\npublic class FranDev200 {\n\n    static void main() {\n        /*\n\n             EJERCICIO:\n             * Crea dos variables utilizando los objetos fechaActual (date, o semejante) de tu lenguaje:\n             * - Una primera que represente la fechaActual (día, mes, año, hora, minuto, segundo) actual.\n             * - Una segunda que represente tu fechaActual de nacimiento (te puedes inventar la hora).\n             * Calcula cuántos años han transcurrido entre ambas fechas.\n\n         */\n\n    DateTimeFormatter formatter = DateTimeFormatter.ofPattern(\"dd/MM/yyyy HH:mm:ss\");\n\n    LocalDateTime fechaActual = LocalDateTime.now();\n        System.out.println(\"Fecha actual: \" + formatter.format(fechaActual));\n\n    LocalDateTime fechaNacimiento = LocalDateTime.of(2005, 12, 13, 15, 40, 34);\n        System.out.println(\"Fecha nacimiento: \" + formatter.format(fechaNacimiento));\n\n    Period diferenciaFechas = Period.between(fechaNacimiento.toLocalDate(), fechaActual.toLocalDate());\n\n    int anios = diferenciaFechas.getYears();\n    int mes = diferenciaFechas.getMonths();\n    int dia = diferenciaFechas.getDays();\n\n    Duration diferenciaFechasTiempo = Duration.between(fechaNacimiento, fechaActual);\n\n    long segundosTotales = diferenciaFechasTiempo.getSeconds();\n    long horas = segundosTotales / 3600;\n    long minutos = (segundosTotales % 3600) / 60;\n    long segundos = segundosTotales % 60;\n\n        System.out.println(\"Tiempo transcurrido desde mi fecha de nacimiento\");\n        System.out.println(\"================================================\");\n        System.out.println(\"Años: \" + anios);\n        System.out.println(\"Meses: \" + mes);\n        System.out.println(\"Dias: \" + dia);\n        System.out.println(\"----------------\");\n        System.out.println(\"Horas: \" + horas);\n        System.out.println(\"Minutos: \" + minutos);\n        System.out.println(\"Segundos: \" + segundos);\n\n        /*\n\n        DIFICULTAD EXTRA (opcional):\n         * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n         * 10 maneras diferentes. Por ejemplo:\n         * - Día, mes y año.\n         * - Hora, minuto y segundo.\n         * - Día de año.\n         * - Día de la semana.\n         * - Nombre del mes.\n         * (lo que se te ocurra...)\n\n         */\n\n    LocalDateTime fechaCumpleanios = LocalDateTime.of(2005, 12, 13, 15, 40, 34);\n\n    DateTimeFormatter formato1 = DateTimeFormatter.ofPattern(\"dd/MM/yyyy\");\n    DateTimeFormatter formato2 = DateTimeFormatter.ofPattern(\"dd/MM/yyyy HH:mm:ss\");\n    DateTimeFormatter formato3 = DateTimeFormatter.ofPattern(\"DD\");\n    DateTimeFormatter formato4 = DateTimeFormatter.ofPattern(\"dd 'de' MMMM 'de' yyyy\", new Locale(\"es\", \"ES\"));\n    DateTimeFormatter formato5 = DateTimeFormatter.ofPattern(\"dd 'de' MM 'de' yyyy\");\n    DateTimeFormatter formato6 = DateTimeFormatter.ofPattern(\"MM/dd/yyyy HH:mm:ss\");\n    DateTimeFormatter formato7 = DateTimeFormatter.ofPattern(\"dd 'de' MMMM 'de' yyyy\", new Locale(\"en\", \"USA\"));\n    DateTimeFormatter formato8 = DateTimeFormatter.ofPattern(\"EEEE, dd 'de' MMMM 'de' yyyy\", new Locale(\"en\", \"USA\"));\n    DateTimeFormatter formato9 = DateTimeFormatter.ofPattern(\"EEEE, dd 'de' MMMM 'de' yyyy\", new Locale(\"es\", \"ES\"));\n    DateTimeFormatter formato10 = DateTimeFormatter.ofPattern(\"EE, dd 'de' MMM 'de' yyyy\", new Locale(\"es\", \"ES\"));\n\n        System.out.println(\"\\nEJERCICIO EXTRA\");\n        System.out.println(\"===============\");\n\n        System.out.println(formato1.format(fechaCumpleanios));\n        System.out.println(formato2.format(fechaCumpleanios));\n        System.out.println(\"Dia del año: \" + formato3.format(fechaCumpleanios));\n        System.out.println(formato4.format(fechaCumpleanios));\n        System.out.println(formato5.format(fechaCumpleanios));\n        System.out.println(formato6.format(fechaCumpleanios));\n        System.out.println(formato7.format(fechaCumpleanios));\n        System.out.println(formato8.format(fechaCumpleanios));\n        System.out.println(formato9.format(fechaCumpleanios));\n        System.out.println(formato10.format(fechaCumpleanios));\n}\n\n\n}\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/java/Javosss.java",
    "content": "import java.time.*; // Se utiliza la libreria time de JAVA\n\npublic class Main {\n    public static void main(String[] args) {\n        /*\n         * EJERCICIO:\n         * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n         * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n         * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n         * Calcula cuántos años han transcurrido entre ambas fechas.\n         */\n\n\n        // Ejemplo de utilizacion de los objetos segun la documentacion\n        LocalDate diaActual = LocalDate.now(); // Representa la fecha actual\n        LocalTime horaLocal = LocalTime.now(); // Representa la hora actual\n        LocalDateTime horaDia = LocalDateTime.now(); // Representa las dos anteriores juntas\n\n        System.out.println(diaActual); // 2024-04-18\n        System.out.println(horaLocal); // 20:43:58.236592100\n        System.out.println(horaDia); // 2024-04-18T20:43:58.236592100\n\n\n        // Creacion de variables\n        LocalDateTime fechaActual = LocalDateTime.now(); // Variable de la fecha actual\n        System.out.println(\"La fecha actual es: \" + fechaActual);\n\n        LocalDateTime fechaNacimiento = LocalDateTime.of(1900,1,1,12,12); // Variable de la fecha de nacimiento inventada\n        System.out.println(\"Mi fecha de nacimiento es: \" + fechaNacimiento);\n\n        // Calculo de la diferencia\n        int difAnos = (fechaActual.getYear() - fechaNacimiento.getYear());\n        System.out.println(\"Hay una diferencia de \"+difAnos +\" años \" + \" entre: \" +fechaActual.getYear() +\" y \" +fechaNacimiento.getYear()); // 124\n\n        // Formatos de las fechas:\n        /*\n         * - Día, mes y año.\n         * - Hora, minuto y segundo.\n         * - Día de año.\n         * - Día de la semana.\n         * - Nombre del mes. */\n\n        System.out.println(\"Formato Dia-Mes-Año:     \" +fechaActual.getDayOfMonth() +\"-\" + fechaActual.getMonthValue() +\"-\" + fechaActual.getYear()); // Formato Dia-Mes-Año:     18-4-2024\n        System.out.println(\"Formato Hora-Minuto-Segundo:    \" + fechaActual.getHour() +\"horas \" + fechaActual.getMinute() +\"minutos \" + fechaActual.getSecond() +\"segundos\"); // Formato Hora-Minuto-Segundo:    23horas 6minutos 35segundos\n        System.out.println(\"Formato Día del año: \" + fechaActual.getDayOfYear()); // Formato Día del año: 109\n        System.out.println(\"Formato Día de la semana:  \"  + fechaActual.getDayOfWeek()); // Formato Día de la semana:  THURSDAY\n        System.out.println(\"Formato Nombre del mes: \" + fechaActual.getMonthValue() +\"--->\" + fechaActual.getMonth()); // Formato Nombre del mes: 4--->APRIL\n        System.out.println(\"Formato al revés  :\" + fechaActual.getSecond() +\"segundos \" + fechaActual.getMinute() + \"minutos \" + fechaActual.getHour() + \"horas \" + fechaActual.getYear() +\" \" + fechaActual.getMonthValue() +\" \" + fechaActual.getDayOfMonth()); // Formato al revés  :35segundos 6minutos 23horas 2024 4 18\n        \n        }\n}\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/java/JesusWay69.java",
    "content": "package ejercicio14;\n\nimport java.time.LocalDate;\nimport java.time.LocalDateTime;\nimport java.time.Instant;\nimport java.time.LocalTime;\nimport java.time.Month;\nimport java.time.ZonedDateTime;\nimport java.time.format.DateTimeFormatter;\nimport java.time.temporal.ChronoUnit;\nimport java.time.temporal.TemporalUnit;\nimport java.util.Locale;\nimport java.util.Scanner;\n\n\n/*\n* EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n */\npublic class JesusWay69 {\n\n    public static void main(String[] args) {\n\n        LocalDate my_birth_date = LocalDate.of(1974, Month.DECEMBER, 26);\n        LocalTime my_birth_time = LocalTime.of(7, 30);\n        LocalDate current_date = LocalDate.now();\n        LocalTime current_time = LocalTime.now();\n        int current_hour = current_time.getHour();\n        int current_minute = current_time.getMinute();\n        int current_second = current_time.getSecond();\n        String[] week_days = {\"Lunes\", \"Martes\", \"Miércoles\", \"Jueves\", \"Viernes\", \"Sábado\", \"Domingo\"};\n        String[] months = {\"Enero\", \"Febrero\", \"Marzo\", \"Abril\", \"Mayo\", \"Junio\", \"Julio\", \"Agosto\", \"Septiembre\", \"Octubre\", \"Noviembre\", \"Diciembre\"};\n        LocalDateTime current_datetime = LocalDateTime.now();\n        Instant current_gmt_datetime = Instant.now();\n        ZonedDateTime current_location_datetime = ZonedDateTime.now();\n        DateTimeFormatter esDateFormat = DateTimeFormatter.ofPattern(\"dd/MM/yyyy hh:mm:ss\").localizedBy(Locale.ITALY);\n\n        System.out.println(\"La fecha actual es: \" + current_date);\n        System.out.println(\"La hora actual es: \" + current_time);\n        System.out.println(\"Son las \" + current_hour + \" horas con \" + current_minute + \" minutos y \" + current_second + \" segundos.\");\n        System.out.println(\"La fecha y hora actual es: \" + current_datetime);\n        System.out.println(\"La fecha y hora GMT o UTC actual es: \" + current_gmt_datetime);\n        System.out.println(\"La fecha y hora actuales en mi ubicación son: \" + current_location_datetime);\n        System.out.println(\"Fecha de mi cumpleaños: \" + my_birth_date);\n        System.out.println(\"Fecha y hora de mi cumpleaños: \" + my_birth_date.atTime(my_birth_time));\n        System.out.println(\"Fecha y hora de mi cumpleaños2: \"\n                + my_birth_date.getDayOfWeek()\n                + \" -> \" + my_birth_date.getDayOfMonth()\n                + \"/\" + months[my_birth_date.getMonthValue() - 1]\n                + \"/\" + my_birth_date.getYear()\n                + \" -> \" + my_birth_time.getHour()\n                + \":\" + my_birth_time.getMinute());\n        System.out.println(\"Día de la semana que nací: \" + my_birth_date.getDayOfWeek());\n        System.out.println(\"Día de la semana que nací en español: \" + week_days[my_birth_date.getDayOfWeek().getValue() - 1]);\n        System.out.println(\"Día del año que nací: \" + my_birth_date.getDayOfYear());\n        System.out.println(esDateFormat);\n        System.out.println(\"\\n\\n\\n\");\n\n        show_data(input_data(), week_days, months);\n\n    }\n\n    public static LocalDate input_data() {\n        Scanner sc = new Scanner(System.in);\n        String[] thirdy_days_months = {\"\", \"\", \"\", \"Abril\", \"\", \"Junio\", \"\", \"\", \"Septiembre\", \"\", \"Noviembre\", \"\"};\n        while (true) {\n            System.out.print(\"\\nEscriba su AÑO de nacimiento: \");\n            String year = sc.next();\n            if (year.length() > 4 || !year.matches(\"[0-9]{4}\")) {\n                System.out.println(\"ERROR: El año debe ser numérico de 4 cifras\");\n                continue;\n            } else if (Integer.parseInt(year) < 1900) {\n                System.out.println(\"Aunque seas demasiado viejo no creo que hayas nacido antes de 1900, intenta con otro año posterior\");\n                continue;\n            } else if (Integer.parseInt(year) > LocalDate.now().getYear()) {\n                System.out.println(\"A no ser que vengas del futuro no puedes poner un año al que todavía no hemos llegado, intenta de nuevo\");\n                continue;\n            } else if (Integer.parseInt(year) >= LocalDate.now().getYear() - 3 && Integer.parseInt(year) <= LocalDate.now().getYear()) {\n                System.out.println(\"Te has debido equivocar de año porque un bebé no sabe teclear en un ordenador, intenta de nuevo\");\n                continue;\n            }\n            while (true) {\n                System.out.print(\"\\nEscriba el número de su MES de nacimiento: \");\n                String month = sc.next();\n                if (!month.matches(\"[1-9]{1,2}\") || month.length() > 2 || month.length() <= 0) {\n                    System.out.println(\"ERROR: El mes debe ser numérico de 1 o 2 cifras\");\n                    continue;\n                } else if (Integer.parseInt(month) < 1 || Integer.parseInt(month) > 12) {\n                    System.out.println(\"ERROR: El mes no puede ser menor a 0 ni mayor a 12\");\n                    continue;\n                }\n\n                while (true) {\n                    System.out.print(\"\\nEscriba el DÍA de su nacimiento: \");\n                    String day = sc.next();\n                    if (!day.matches(\"[0-9]{1,2}\") || day.length() > 2 || day.length() < 1) {\n                        System.out.println(\"ERROR: El día debe ser numérico de 1 o 2 cifras\");\n                        continue;\n                    } else if ((\"4\".equals(month) || \"6\".equals(month) || \"9\".equals(month) || \"11\".equals(month)) && Integer.parseInt(day)>30) {\n                        System.out.println(\"El mes de \" + thirdy_days_months[Integer.parseInt(month)-1] + \" no puede tener más de 30 días\");\n                        continue;\n                    } else if (Integer.parseInt(day) < 1 || Integer.parseInt(day) > 31) {\n                        System.out.println(\"ERROR: El día no puede ser menor a 0 ni mayor a 31\");\n                        continue;\n                    }\n                    if ((Integer.parseInt(year) % 4 != 0 && Integer.parseInt(year) % 100 == 0) || (Integer.parseInt(year) % 400 != 0 && Integer.parseInt(month) == 2 && Integer.parseInt(day) > 28)) {\n                        System.out.println(\"El año \" + year + \" no fue bisiesto y Febrero no puede tener más de 28 días\");\n                        break;\n\n                    }\n                    return LocalDate.of(Integer.parseInt(year), Integer.parseInt(month), Integer.parseInt(day));\n                }\n            }\n\n        }\n\n    }\n\n    public static void show_data(LocalDate date_object, String[] week_days, String[] months) {\n        String day = Integer.toString(date_object.getDayOfMonth());\n        String year = Integer.toString(date_object.getYear());\n        long my_age = ChronoUnit.YEARS.between(date_object, LocalDate.now());\n        int days_passed = LocalDate.now().getDayOfYear();\n        int weeks_passed = LocalDate.now().getDayOfYear() / 7 + 1;\n        String current_week_day = week_days[LocalDate.now().getDayOfWeek().getValue() - 1];\n        String current_month = months[LocalDate.now().getMonthValue() - 1];\n\n        System.out.println(\"\\nHoy es \" + current_week_day + \" día \" + LocalDate.now().getDayOfMonth() + \" de \" + current_month + \" de \" + LocalDate.now().getYear());\n        System.out.println(\"\\nY son las \" + LocalTime.now().getHour() + \" horas y \" + LocalTime.now().getMinute() + \" munutos.\");\n        System.out.println(\"\\nEstamos en la semana \" + weeks_passed + \" y en el día \" + days_passed + \" de \" + LocalDate.now().getYear());\n\n        if (LocalTime.now().getHour() > 6 && LocalTime.now().getHour() < 12) {\n            System.out.println(\"¡¡Buenos Días!!!\");\n        } else if (LocalTime.now().getHour() >= 12 && LocalTime.now().getHour() <= 20) {\n            System.out.println(\"¡¡Buenas Tardes!!!\");\n        } else {\n            System.out.println(\"¡¡Buenas Noches!!!\");\n        }\n\n        System.out.println(\"\\nComo has indicado que naciste el día \" + day + \" de \" + months[date_object.getMonthValue() - 1] + \" de \" + year);\n        System.out.println(\"(Por cierto naciste un \" + week_days[date_object.getDayOfWeek().getValue() - 1] + \"...)\");\n\n        if (LocalDate.now().getMonthValue() == date_object.getMonthValue() && LocalDate.now().getDayOfMonth() == date_object.getDayOfMonth()) {\n            System.out.println(\"¡¡¡FELICIDADES!!! , hoy cumples \" + my_age + \" años, casi nada\");\n        } else {\n            System.out.println(\"...tienes \" + my_age + \" años.\");\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/java/JimsimroDev.java",
    "content": "import java.time.LocalDate;\nimport java.time.LocalDateTime;\nimport java.time.format.DateTimeFormatter;\nimport java.util.Calendar;\nimport java.util.Locale;\n\npublic class JimsimroDev {\n  private final static DateTimeFormatter FORMATO = DateTimeFormatter.ISO_LOCAL_DATE;\n\n  /**\n   * @param args\n   */\n  public static void main(String[] args) {\n\n    //API de java con la clase Calendar\n    Calendar fecha = Calendar.getInstance();\n    int year = fecha.get(Calendar.YEAR);\n    int month = fecha.get(Calendar.MONTH) + 1; // Los meses empiezan desde 0\n    int day = fecha.get(Calendar.DATE);\n    int hour = fecha.get(Calendar.HOUR_OF_DAY);\n    int minute = fecha.get(Calendar.MINUTE);\n    int second = fecha.get(Calendar.SECOND);\n    System.out.printf(\"Fecha y hora actual: %d:%d:%d %02d:%02d:%02d%n\", year, month, day, hour, minute, second);\n\n    // Fecha actual: con la clase LocalDateTime\n    LocalDateTime fechaActual = LocalDateTime.now();\n    System.out.println(\"Fecha actual: \" + fechaActual);\n\n    LocalDate fechaNacimiento = LocalDate.of(1995, 07, 28);//Mi fecha de nacimiento con LocalDate\n    System.out.println(\"Fecha de nacimiento: \" + fechaNacimiento);\n    // Calcular la edad con LocalDate\n    int anoNacimiento = fechaNacimiento.getYear();\n    var anosTranscurridos = year - anoNacimiento;\n    if (month < fechaNacimiento.getMonthValue()) {\n      anosTranscurridos--;\n    } else if (month == fechaNacimiento.getMonthValue() && day < fechaNacimiento.getDayOfMonth()) {\n      anosTranscurridos--;\n    }\n    System.out.println(String.format(\"Tengo %s años.\", anosTranscurridos));\n\n    // Calcular la edad con Calendar\n    fecha.add(Calendar.YEAR,- fechaNacimiento.getYear());\n    System.out.printf(\"Edad actual: %d%n \",fecha.get(Calendar.YEAR));\n\n    //Extra\n    DateTimeFormatter formatearFechas = DateTimeFormatter.ofPattern(\"dd/MM/yyyy\");// Formato dd/MM/yyyy  -> 28/07/1995\n    DateTimeFormatter formatearFechas1 = DateTimeFormatter.ofPattern(\"D-MM-Y\");// Formato D-MM-Y -> 209-07-1995\n    DateTimeFormatter formatearFechas2 = DateTimeFormatter.ofPattern(\"dd-MMMM-y\"); // Formato dd-MMMM-y -> 28-julio-1995\n    DateTimeFormatter formatearFechas3 = DateTimeFormatter.ofPattern(\"dd-MMM-y\");// Formato dd-MMM-y -> 28-jul-1995\n    DateTimeFormatter formatearFechas4 = DateTimeFormatter.ofPattern(\"E-MMM-y\");// Formato dd-MMM-y -> Fri-jul-1995\n    DateTimeFormatter formatearFechas5 = DateTimeFormatter.ofPattern(\"EEEE-MMM-y\");// Formato dd-MMM-y -> Friday-jul-1995\n    DateTimeFormatter formatearFechas6 = DateTimeFormatter.ofPattern(\"EEEE-MMMM-y\");// Formato dd-MMM-y -> Friday-julio-1995\n    DateTimeFormatter formatearFechas7 = DateTimeFormatter.ofPattern(\"EEEE-MMMM-d-y\");// Formato dd-MMM-y -> Friday-julio-28-1995\n    DateTimeFormatter formatearFechas8 = DateTimeFormatter.ofPattern(\"EEEE-MMMM-w-d-y\");// Formato EEEE-MMMM-w-d-y -> Friday-julio-30-28-1995\n    DateTimeFormatter formatearFechas9 = DateTimeFormatter.ofPattern(\"w-d\");// Formato w-d muestra la semana y el día del mes -> 30-28\n    DateTimeFormatter formatearFechas10 = DateTimeFormatter.ofPattern(\"Q\");// Formato Q muestra el trimestre del año -> 3\n    DateTimeFormatter personalizado = DateTimeFormatter.ofPattern(\"dd 'de' MMMM 'de' yyyy\", new Locale(\"es\", \"CO\"));// Formato personalizado en español -> 28 de julio de 1995\n    System.out.println(\"Fecha de nacimiento con formato ISO: \" + fechaNacimiento.format(FORMATO));// formato ISO -> 1995-07-28\n    System.out.println(\"Fecha de nacimiento: \" + fechaNacimiento.format(formatearFechas));\n    System.out.println(\"Fecha de nacimiento con formato bonito: \" + fechaNacimiento.format(formatearFechas1));\n    System.out.println(\"Fecha de nacimiento con formato bonito: \" + fechaNacimiento.format(formatearFechas2));\n    System.out.println(\"Fecha de nacimiento con formato bonito: \" + fechaNacimiento.format(formatearFechas3));\n    System.out.println(\"Fecha de nacimiento con formato bonito: \" + fechaNacimiento.format(formatearFechas4));\n    System.out.println(\"Fecha de nacimiento con formato bonito: \" + fechaNacimiento.format(formatearFechas5));\n    System.out.println(\"Fecha de nacimiento con formato bonito: \" + fechaNacimiento.format(formatearFechas6));\n    System.out.println(\"Fecha de nacimiento con formato bonito: \" + fechaNacimiento.format(formatearFechas7));\n    System.out.println(\"Fecha de nacimiento con formato bonito: \" + fechaNacimiento.format(formatearFechas8));\n    System.out.println(\"Fecha de nacimiento con formato bonito: \" + fechaNacimiento.format(formatearFechas9));\n    System.out.println(\"Fecha de nacimiento con formato bonito: \" + fechaNacimiento.format(formatearFechas10));\n    System.out.println(\"Fecha de nacimiento con formato bonito: \" + fechaNacimiento.format(personalizado));\n\n\n  }\n}\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/java/Josegs95.java",
    "content": "import java.time.LocalDateTime;\nimport java.time.format.DateTimeFormatter;\nimport java.time.temporal.ChronoUnit;\nimport java.time.temporal.TemporalUnit;\n\npublic class Josegs95 {\n    public static void main(String[] args) {\n        //Ejercicio\n        LocalDateTime nowTime = LocalDateTime.now();\n        LocalDateTime birthdayTime = LocalDateTime.of(1995, 02, 28, 17, 30, 0);\n        System.out.println(\"Fecha y hora actual: \" + nowTime);\n        System.out.println(\"Fecha y hora cuando nací: \" + birthdayTime);\n\n        System.out.println(\"Años entre mi nacimiento y ahora: \" + birthdayTime.until(nowTime, ChronoUnit.YEARS));\n        //Reto\n        System.out.println(\"\\n\");\n        retoFinal(birthdayTime);\n    }\n\n    public static void retoFinal(LocalDateTime birthdayTime){\n        System.out.println(\"Mi fecha de nacimiento en diferentes formatos: \");\n        //Estándar\n        System.out.println(birthdayTime);\n        //Dia-mes-año\n        System.out.println(birthdayTime.format(DateTimeFormatter.ofPattern(\"dd-MM-YYYY\")));\n        //Hora-minuto-segundo\n        System.out.println(birthdayTime.format(DateTimeFormatter.ofPattern(\"kk:mm:ss\")));\n        //Dia del año\n        System.out.println(birthdayTime.format(DateTimeFormatter.ofPattern(\"DDD\")));\n        //Dia de la semana\n        System.out.println(birthdayTime.format(DateTimeFormatter.ofPattern(\"EEEE\")));\n        //Nombre del mes\n        System.out.println(birthdayTime.format(DateTimeFormatter.ofPattern(\"LLLL\")));\n        //Quadrimestre\n        System.out.println(birthdayTime.format(DateTimeFormatter.ofPattern(\"QQ\")));\n        //Semana del año\n        System.out.println(birthdayTime.format(DateTimeFormatter.ofPattern(\"ww\")));\n        //Semana del mes\n        System.out.println(birthdayTime.format(DateTimeFormatter.ofPattern(\"W\")));\n        //Hora-minuto AM/PM\n        System.out.println(birthdayTime.format(DateTimeFormatter.ofPattern(\"hh:mm a\")));\n        //Dia de la semana, Dia-mes-año, hora:minuto\n        System.out.println(birthdayTime.format(DateTimeFormatter.ofPattern(\"EEEE, dd-MM-YYYY 'a las' kk:mm\")));\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/java/Vecinacoo.java",
    "content": "import java.time.Duration;\nimport java.time.LocalDate;\nimport java.time.LocalDateTime;\nimport java.time.LocalTime;\nimport java.time.temporal.ChronoUnit;\n\npublic class P14 {\n\n\tpublic static void main(String[] args) {\n\n\t\t// Mostrando agnos pasados desde la fecha de nacimiento hasta ahora\n\t\tLocalDateTime fechaAhora = LocalDateTime.of(LocalDate.now(), LocalTime.now());\n\n\t\tLocalDateTime fechaNacimiento = LocalDateTime.of(LocalDate.of(2005, 10, 31), LocalTime.of(10, 30));\n\n\t\tDuration duration = Duration.between(fechaNacimiento, fechaAhora);\n\n\t\tlong agnos = ChronoUnit.YEARS.between(LocalDateTime.now(), LocalDateTime.now().plus(duration));\n\n\t\tSystem.out.println(agnos);\n\n\t\t// OPCIONAL\n\t\tmostrandoFechaCumpleagnos(fechaNacimiento);\n\n\t}\n\n\tprivate static void mostrandoFechaCumpleagnos(LocalDateTime n) {\n\n\t\tSystem.out.println(n.getDayOfMonth() + \" \" + n.getMonth() + n.getYear());\n\n\t\tSystem.out.println(n.getHour() + \":\" + n.getMinute() + \":\" + n.getSecond());\n\n\t\tSystem.out.println(\"Dia \" + n.getDayOfYear() + \" del agno\");\n\n\t\tSystem.out.println(\"Dia \" + n.getDayOfWeek() + \" de la semana\");\n\n\t}\n\n}\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/java/alexdevrep.java",
    "content": "package _14_Fechas;\n/*\n * EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n */\n\nimport java.time.Duration;\nimport java.time.LocalDate;\nimport java.time.LocalDateTime;\nimport java.time.Period;\nimport java.time.format.DateTimeFormatter;\npublic class _14_Fechas {\n    public static void main (String[] args){\n        //Imprimimos la fecha actual\n        LocalDateTime fechaActual= LocalDateTime.now();\n        System.out.println(fechaActual);\n\n        //Imprimimos la fecha de mi cumpleaños\n        LocalDateTime fechaCumpleaños = LocalDateTime.of(1999,7,22,10,00);\n        System.out.println(fechaCumpleaños);\n\n        //Diferencia entre fechas\n\n        // Calculamos la diferencia entre las fechas\n        Period edad = Period.between(fechaCumpleaños.toLocalDate(), fechaActual.toLocalDate());\n\n        // Mostramos la diferencia en años, meses y días\n        System.out.println(\"Edad: \" + edad.getYears() + \" años, \" +\n                edad.getMonths() + \" meses, \" +\n                edad.getDays() + \" días.\");\n\n        //Dificultad EXTRA\n        DateTimeFormatter formato1 = DateTimeFormatter.ofPattern(\"dd-MM-yyyy HH:mm:ss\");\n        String cumpleaños1 = fechaCumpleaños.format(formato1);\n        System.out.println(cumpleaños1);\n        DateTimeFormatter formato2 = DateTimeFormatter.ofPattern(\"HH:mm:ss\");\n        String cumpleaños2 = fechaCumpleaños.format(formato2);\n        System.out.println(cumpleaños2);\n        DateTimeFormatter formato3 = DateTimeFormatter.ofPattern(\"EEEE\");\n        String cumpleaños3 = fechaCumpleaños.format(formato3);\n        System.out.println(cumpleaños3);\n        DateTimeFormatter formato4 = DateTimeFormatter.ofPattern(\"a\");\n        String cumpleaños4 = fechaCumpleaños.format(formato4);\n        System.out.println(cumpleaños4);\n        DateTimeFormatter formato5 = DateTimeFormatter.ofPattern(\"E\");\n        String cumpleaños5 = fechaCumpleaños.format(formato5);\n        System.out.println(cumpleaños5);\n        DateTimeFormatter formato6 = DateTimeFormatter.ofPattern(\"yyyy\");\n        String cumpleaños6 = fechaCumpleaños.format(formato6);\n        System.out.println(cumpleaños6);\n        DateTimeFormatter formato7 = DateTimeFormatter.ofPattern(\"dd\");\n        String cumpleaños7 = fechaCumpleaños.format(formato7);\n        System.out.println(cumpleaños7);\n        DateTimeFormatter formato8 = DateTimeFormatter.ofPattern(\"h\");\n        String cumpleaños8 = fechaCumpleaños.format(formato8);\n        System.out.println(cumpleaños8);\n        DateTimeFormatter formato9 = DateTimeFormatter.ofPattern(\"EEEE-hh-mm\");\n        String cumpleaños9 = fechaCumpleaños.format(formato9);\n        System.out.println(cumpleaños9);\n        DateTimeFormatter formato10 = DateTimeFormatter.ofPattern(\"yyyy-MM-SSSS\");\n        String cumpleaños10 = fechaCumpleaños.format(formato10);\n        System.out.println(cumpleaños10);\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/java/asjordi.java",
    "content": "import java.time.LocalDateTime;\nimport java.time.Period;\nimport java.time.format.DateTimeFormatter;\nimport java.time.format.FormatStyle;\n\npublic class Main {\n\n    public static void main(String[] args) {\n        calculateYears();\n        dateFormat();\n    }\n\n    /**\n     * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n     * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n     * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n     * Calcula cuántos años han transcurrido entre ambas fechas.\n     */\n    static void calculateYears() {\n        LocalDateTime currentDate = LocalDateTime.now();\n        LocalDateTime birthDate = LocalDateTime.of(1999, 1, 10, 9, 30, 5);\n        Period p = Period.between(birthDate.toLocalDate(), currentDate.toLocalDate());\n        System.out.println(\"Years: \" + p.getYears());\n    }\n\n    /**\n     * DIFICULTAD EXTRA (opcional):\n     * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n     * 10 maneras diferentes. Por ejemplo:\n     * - Día, mes y año.\n     * - Hora, minuto y segundo.\n     * - Día de año.\n     * - Día de la semana.\n     * - Nombre del mes.\n     */\n    static void dateFormat() {\n        LocalDateTime date = LocalDateTime.of(1999, 1, 10, 9, 30, 5);\n        System.out.println(\"yyyy-MM-dd HH:mm:ss: -> \" + date.format(DateTimeFormatter.ofPattern(\"yyyy-MM-dd HH:mm:ss\")));\n        System.out.println(\"dd/MM/yyyy HH:mm:ss: -> \" + date.format(DateTimeFormatter.ofPattern(\"dd/MM/yyyy HH:mm:ss\")));\n        System.out.println(\"dd/MM/yyyy -> \" + date.format(DateTimeFormatter.ofPattern(\"dd/MM/yyyy\")));\n        System.out.println(\"dd/MM/yyyy HH:mm: -> \" + date.format(DateTimeFormatter.ofPattern(\"dd/MM/yyyy HH:mm\")));\n        System.out.println(\"hh:mm:ss a -> \" + date.format(DateTimeFormatter.ofPattern(\"hh:mm:ss a\")));\n        System.out.println(\"HH:mm:ss -> \" + date.format(DateTimeFormatter.ofPattern(\"HH:mm:ss\")));\n        System.out.println(\"yyyy-MM-dd -> \" + date.format(DateTimeFormatter.ofPattern(\"yyyy-MM-dd\")));\n        System.out.println(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL).format(date));\n        System.out.println(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).format(date));\n        System.out.println(DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT).format(date));\n        System.out.println(\"u -> \" + date.format(DateTimeFormatter.ofPattern(\"u\")));\n        System.out.println(\"M -> \" + date.format(DateTimeFormatter.ofPattern(\"M\")));\n        System.out.println(\"d -> \" + date.format(DateTimeFormatter.ofPattern(\"d\")));\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/java/cesar-ch.java",
    "content": "/*\n     * #14 FECHAS \n*/\n\nimport java.time.*;\nimport java.time.format.DateTimeFormatter;\nimport java.time.temporal.ChronoUnit;\n\npublic class Main {\n\n    public static void main(String[] args) {\n        // Fecha actual\n        LocalDate fechaActual = LocalDate.now();\n        // Fecha de nacimiento\n        LocalDate fechaNacimiento = LocalDate.of(2005, 4, 15);\n\n        // Calculando la diferencia en años\n        long añosTranscurridos = ChronoUnit.YEARS.between(fechaNacimiento, fechaActual);\n        System.out.println(\"Han transcurrido \" + añosTranscurridos + \" años desde mi nacimiento.\");\n\n        /*\n         * DIFICULTAD EXTRA \n        */ \n        System.out.println(\"1. Día, mes y año: \" + fechaNacimiento.getDayOfMonth() + \"/\"\n                + fechaNacimiento.getMonthValue() + \"/\" + fechaNacimiento.getYear());\n\n        System.out.println(\"2. Hora, minuto y segundo: \" + fechaNacimiento.atTime(LocalTime.NOON).getHour() + \":\"\n                + fechaNacimiento.atTime(LocalTime.NOON).getMinute() + \":\"\n                + fechaNacimiento.atTime(LocalTime.NOON).getSecond());\n\n        System.out.println(\"3. Día de año: \" + fechaNacimiento.getDayOfYear());\n\n        System.out.println(\"4. Día de la semana: \" + fechaNacimiento.getDayOfWeek());\n\n        System.out.println(\"5. Nombre del mes: \" + fechaNacimiento.getMonth());\n\n        System.out.println(\"6. Mes abreviado y año: \" + fechaNacimiento.getMonth().name().substring(0, 3) + \" \"\n                + fechaNacimiento.getYear());\n\n        System.out.println(\"7. Hora en formato de 12 horas: \"\n                + DateTimeFormatter.ofPattern(\"hh:mm:ss a\").format(fechaNacimiento.atTime(LocalTime.NOON)));\n\n        System.out.println(\"8. Edad en días: \" + ChronoUnit.DAYS.between(fechaNacimiento, fechaActual));\n\n        System.out.println(\"9. Edad en meses: \" + ChronoUnit.MONTHS.between(fechaNacimiento, fechaActual));\n\n        System.out.println(\"10. Día de la semana abreviado, día de mes y año: \"\n                + fechaNacimiento.getDayOfWeek().name().substring(0, 3) + \", \" + fechaNacimiento.getDayOfMonth()\n                + \" de \" + fechaNacimiento.getMonth() + \" de \" + fechaNacimiento.getYear());\n    }\n}\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/java/danhingar.java",
    "content": "\nimport java.time.LocalDateTime;\nimport java.time.Month;\nimport java.time.format.DateTimeFormatter;\nimport java.time.temporal.ChronoUnit;\n\npublic class danhingar {\n    public static void main(String[] args) {\n\n        LocalDateTime now = LocalDateTime.now();\n        LocalDateTime birthdate = LocalDateTime.of(1997, 3, 2, 16, 30, 10);\n\n        Long years = birthdate.until(now, ChronoUnit.YEARS);\n\n        System.out.println(\"Años transcurridos \" + years);\n\n        // Extra\n        DateTimeFormatter format1 = DateTimeFormatter.ofPattern(\"dd-MM-yyyy\");\n        DateTimeFormatter format2 = DateTimeFormatter.ofPattern(\"HH:mm:ss\");\n        DateTimeFormatter format3 = DateTimeFormatter.ofPattern(\"dd/MM/YYYY\");\n        DateTimeFormatter format4 = DateTimeFormatter.ofPattern(\"YYYY/MM/dd\");\n        DateTimeFormatter format5 = DateTimeFormatter.ofPattern(\"YYYY-MM-dd\");\n        DateTimeFormatter format6 = DateTimeFormatter.ofPattern(\"YYYY-MM-dd hh:mm:ss a\");\n        System.out.println(birthdate.format(format1));\n        System.out.println(birthdate.format(format2));\n        System.out.println(birthdate.format(format3));\n        System.out.println(birthdate.format(format4));\n        System.out.println(birthdate.format(format5));\n        System.out.println(birthdate.getDayOfYear());\n        System.out.println(birthdate.getDayOfWeek());\n        System.out.println(birthdate.getDayOfMonth());\n        System.out.println(Month.of(birthdate.getMonthValue()));\n        System.out.println(birthdate.format(format6));\n    \n\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/java/eulogioep.java",
    "content": "import java.time.LocalDateTime;\nimport java.time.format.DateTimeFormatter;\nimport java.time.temporal.ChronoUnit;\nimport java.time.Month;\nimport java.time.DayOfWeek;\n\npublic class eulogioep {\n    public static void main(String[] args) {\n        // PARTE 1: Crear variables de fecha y calcular años transcurridos\n        \n        // Creamos la fecha actual usando LocalDateTime.now()\n        LocalDateTime fechaActual = LocalDateTime.now();\n        \n        // Creamos una fecha de nacimiento (ejemplo)\n        LocalDateTime fechaNacimiento = LocalDateTime.of(1990, 5, 15, 14, 30, 0);\n        \n        // Calculamos los años transcurridos entre ambas fechas\n        long añosTranscurridos = ChronoUnit.YEARS.between(fechaNacimiento, fechaActual);\n        \n        System.out.println(\"Fecha actual: \" + fechaActual);\n        System.out.println(\"Fecha de nacimiento: \" + fechaNacimiento);\n        System.out.println(\"Años transcurridos: \" + añosTranscurridos);\n        \n        // PARTE 2: DIFICULTAD EXTRA - Formatear la fecha de 10 maneras diferentes\n        \n        System.out.println(\"\\nDIFERENTES FORMATOS DE FECHA:\");\n        \n        // 1. Día, mes y año\n        DateTimeFormatter fmt1 = DateTimeFormatter.ofPattern(\"dd/MM/yyyy\");\n        System.out.println(\"1. Día, mes y año: \" + fechaNacimiento.format(fmt1));\n        \n        // 2. Hora, minuto y segundo\n        DateTimeFormatter fmt2 = DateTimeFormatter.ofPattern(\"HH:mm:ss\");\n        System.out.println(\"2. Hora, minuto y segundo: \" + fechaNacimiento.format(fmt2));\n        \n        // 3. Día del año\n        System.out.println(\"3. Día del año: \" + fechaNacimiento.getDayOfYear());\n        \n        // 4. Día de la semana\n        System.out.println(\"4. Día de la semana: \" + fechaNacimiento.getDayOfWeek());\n        \n        // 5. Nombre del mes\n        System.out.println(\"5. Nombre del mes: \" + fechaNacimiento.getMonth());\n        \n        // 6. Formato largo con día de la semana\n        DateTimeFormatter fmt6 = DateTimeFormatter.ofPattern(\"EEEE, d 'de' MMMM 'de' yyyy\");\n        System.out.println(\"6. Formato largo: \" + fechaNacimiento.format(fmt6));\n        \n        // 7. Formato corto de 12 horas\n        DateTimeFormatter fmt7 = DateTimeFormatter.ofPattern(\"dd-MM-yy hh:mm a\");\n        System.out.println(\"7. Formato 12 horas: \" + fechaNacimiento.format(fmt7));\n        \n        // 8. Semana del año\n        System.out.println(\"8. Semana del año: \" + (fechaNacimiento.getDayOfYear() / 7 + 1));\n        \n        // 9. Trimestre del año\n        System.out.println(\"9. Trimestre del año: \" + ((fechaNacimiento.getMonthValue() - 1) / 3 + 1));\n        \n        // 10. ISO fecha y hora\n        System.out.println(\"10. Formato ISO: \" + fechaNacimiento.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));\n    }\n}"
  },
  {
    "path": "Roadmap/14 - FECHAS/java/h4ckxel.java",
    "content": "import java.time.*;\nimport java.time.format.DateTimeFormatter;\nimport java.time.temporal.ChronoUnit;\n\npublic class Main {\n\npublic static void main(String[] args) {\n        // Fecha actual\n        LocalDate fechaActual = LocalDate.now();\n        // Fecha de nacimiento\n        LocalDate fechaNacimiento = LocalDate.of(2005, 4, 15);\n\n        // Calculando la diferencia en años\n        long añosTranscurridos = ChronoUnit.YEARS.between(fechaNacimiento, fechaActual);\n        System.out.println(\"Han transcurrido \" + añosTranscurridos + \" años desde mi nacimiento.\");\n\n        /*\n         * DIFICULTAD EXTRA \n        */ \n        System.out.println(\"1. Día, mes y año: \" + fechaNacimiento.getDayOfMonth() + \"/\"\n                + fechaNacimiento.getMonthValue() + \"/\" + fechaNacimiento.getYear());\n\n        System.out.println(\"2. Hora, minuto y segundo: \" + fechaNacimiento.atTime(LocalTime.NOON).getHour() + \":\"\n                + fechaNacimiento.atTime(LocalTime.NOON).getMinute() + \":\"\n                + fechaNacimiento.atTime(LocalTime.NOON).getSecond());\n\n        System.out.println(\"3. Día de año: \" + fechaNacimiento.getDayOfYear());\n\n        System.out.println(\"4. Día de la semana: \" + fechaNacimiento.getDayOfWeek());\n\n        System.out.println(\"5. Nombre del mes: \" + fechaNacimiento.getMonth());\n\n        System.out.println(\"6. Mes abreviado y año: \" + fechaNacimiento.getMonth().name().substring(0, 3) + \" \"\n                + fechaNacimiento.getYear());\n\n        System.out.println(\"7. Hora en formato de 12 horas: \"\n                + DateTimeFormatter.ofPattern(\"hh:mm:ss a\").format(fechaNacimiento.atTime(LocalTime.NOON)));\n\n        System.out.println(\"8. Edad en días: \" + ChronoUnit.DAYS.between(fechaNacimiento, fechaActual));\n\n        System.out.println(\"9. Edad en meses: \" + ChronoUnit.MONTHS.between(fechaNacimiento, fechaActual));\n\n        System.out.println(\"10. Día de la semana abreviado, día de mes y año: \"\n                + fechaNacimiento.getDayOfWeek().name().substring(0, 3) + \", \" + fechaNacimiento.getDayOfMonth()\n                + \" de \" + fechaNacimiento.getMonth() + \" de \" + fechaNacimiento.getYear());\n        }\n}\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/java/isaacus98.java",
    "content": "import java.time.LocalDateTime;\nimport java.time.Month;\nimport java.time.format.DateTimeFormatter;\nimport java.time.format.FormatStyle;\n\n/*\n * EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n */\n\npublic class Main {\n    public static void main(String[] args) {\n        LocalDateTime date = LocalDateTime.now();\n        LocalDateTime birthdate = LocalDateTime.of(1998, Month.FEBRUARY, 13, 07, 00,00);\n\n        System.out.println(\"Han transcurrido \" + date.minusYears(birthdate.getYear()).getYear() + \" años\");\n\n        // reto extra\n        System.out.println(\"Dia del año: \" + birthdate.getDayOfYear());\n        System.out.println(\"Dia de la semana: \" + birthdate.getDayOfWeek());\n        System.out.println(\"Fecha corta: \" + birthdate.format(DateTimeFormatter.ofPattern(\"dd/MM/yyyy\")));\n        System.out.println(\"Semana del año: \" + birthdate.format(DateTimeFormatter.ofPattern(\"w\")));\n        System.out.println(\"Hora, minuto, segundo: \" + birthdate.format(DateTimeFormatter.ofPattern(\"HH:mm:ss\")));\n        System.out.println(\"Nombre del mes: \" + birthdate.format(DateTimeFormatter.ofPattern(\"MMMM\")));\n        System.out.println(\"Era: \" + birthdate.format(DateTimeFormatter.ofPattern(\"G\")));\n        System.out.println(\"Semana del mes: \" + birthdate.format(DateTimeFormatter.ofPattern(\"F\")));\n        System.out.println(\"Trimestre del año: \" + birthdate.format(DateTimeFormatter.ofPattern(\"qqqq\")));\n        System.out.println(\"Fecha año-mes-dia: \" + birthdate.format(DateTimeFormatter.ofPattern(\"yyyy-MM-dd\")));\n    }\n}"
  },
  {
    "path": "Roadmap/14 - FECHAS/java/martinbohorquez.java",
    "content": "import java.time.LocalDateTime;\nimport java.time.Period;\nimport java.time.format.DateTimeFormatter;\n\n/**\n * #14 FECHAS\n *\n * @author martinbohorquez\n */\npublic class martinbohorquez {\n\n    public static void main(String[] args) {\n        LocalDateTime now = LocalDateTime.now();\n        LocalDateTime birthDate = LocalDateTime.of(1994, 9, 26,\n                18, 30, 45);\n        System.out.printf(\"La fecha actual es: %s%n\", now);\n        System.out.printf(\"La fecha de nacimiento es: %s%n\", birthDate);\n\n        System.out.printf(\"La edad es: %s%n\", Period.between(birthDate.toLocalDate(),\n                now.toLocalDate()));\n        System.out.printf(\"La edad es: %s%n\", Period.between(birthDate.toLocalDate(),\n                now.toLocalDate()).getYears());\n        System.out.printf(\"Los meses son: %s%n\", Period.between(birthDate.toLocalDate(),\n                now.toLocalDate()).getMonths());\n        System.out.printf(\"Los días son: %s%n\", Period.between(birthDate.toLocalDate(),\n                now.toLocalDate()).getDays());\n\n        /*\n         * DIFICULTAD EXTRA\n         */\n        // Día, mes y año.\n        DateTimeFormatter f = DateTimeFormatter.ofPattern(\"dd/MM/yyyy\");\n        System.out.printf(\"La fecha de nacimiento (Día, mes y año) es: %s%n\",\n                birthDate.toLocalDate().format(f));\n        // Hora, minuto y segundo.\n        f = DateTimeFormatter.ofPattern(\"HH:mm:ss\");\n        System.out.printf(\"La hora de nacimiento (Hora, mínuto y segundo) es: %s%n\",\n                birthDate.toLocalTime().format(f));\n        // Día del año.\n        System.out.printf(\"La día del año de la fecha nacimiento es: %s%n\",\n                birthDate.getDayOfYear());\n        // Día del mes.\n        System.out.printf(\"El día del mes de la fecha nacimiento es: %s%n\",\n                birthDate.getDayOfMonth());\n        // Día de la semana.\n        System.out.printf(\"El día de la semana de la fecha de nacimiento (Día, mes y año) es: %s%n\",\n                birthDate.getDayOfWeek().getValue());\n        // Nombre del mes.\n        System.out.printf(\"El nombre del mes de la fecha nacimiento es: %s%n\",\n                birthDate.getMonth().name());\n        // Nombre del día de la semana.\n        System.out.printf(\"El nombre del día de la semana de la fecha de nacimiento es: %s%n\",\n                birthDate.getDayOfWeek().name());\n\n        f = DateTimeFormatter.ofPattern(\"EE MMM dd HH:mm:ss yyyy\");\n\n        System.out.printf(\"La fecha de nacimiento (Día, mes y año) es: %s%n\",\n                birthDate.format(f).toUpperCase());\n    }\n}\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/java/simonguzman.java",
    "content": "\nimport java.time.LocalDateTime;\nimport java.time.Period;\nimport java.time.format.DateTimeFormatter;\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class simonguzman {\n    public static void main(String[] args) {\n        ejercicioPrincipal();\n        ejercicioAdicional();\n    }\n\n    static void ejercicioPrincipal(){\n        LocalDateTime fechaActual = LocalDateTime.now();\n        System.out.println(fechaActual);\n        LocalDateTime fechaNacimiento = LocalDateTime.of(2001, 11, 28, 9, 45, 0);\n        System.out.println(fechaNacimiento);\n\n        Period periodo = Period.between(fechaNacimiento.toLocalDate(), fechaActual.toLocalDate());\n        int aniosTranscurridos = periodo.getYears();\n        System.out.println(aniosTranscurridos);\n    }\n\n    static void ejercicioAdicional(){\n\n        LocalDateTime fechaNacimiento = LocalDateTime.of(2001, 11, 28, 9, 45, 0);\n\n        List<DateTimeFormatter> formatos = new ArrayList<>();\n        formatos.add(DateTimeFormatter.ofPattern(\"dd/MM/yyyy\"));\n        formatos.add(DateTimeFormatter.ofPattern(\"HH:mm:ss\"));\n        formatos.add(DateTimeFormatter.ofPattern(\"DDD\"));\n        formatos.add(DateTimeFormatter.ofPattern(\"EEEE\"));\n        formatos.add(DateTimeFormatter.ofPattern(\"MMMM\"));\n        formatos.add(DateTimeFormatter.ofPattern(\"dd MMMM yyyy\"));\n        formatos.add(DateTimeFormatter.ofPattern(\"yyyy/MM/dd HH:mm\"));\n        formatos.add(DateTimeFormatter.ofPattern(\"dd-MM-yyyy HH:mm:ss\"));\n        formatos.add(DateTimeFormatter.ofPattern(\"EEEE, MMM dd, yyyy\"));\n   \n        aplicarFormatos(fechaNacimiento, formatos);\n    }\n\n    static void aplicarFormatos(LocalDateTime fecha, List<DateTimeFormatter> formatos){\n        for (DateTimeFormatter formato:formatos){\n            String fechaFormateada = fecha.format(formato);\n            System.out.println(\"Formato: \"+formato+\" -> \"+fechaFormateada);\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/javascript/7R0N1X.js",
    "content": "const currentDate = new Date();\nconsole.log(currentDate);\n\nconst dateOfBirth = new Date(1999, 7, 30, 5, 51, 30)\nconsole.log(dateOfBirth);\n\nfunction calculateElapsedYears(date1, date2) {\n  return date1.getFullYear() - date2.getFullYear();\n}\n\nconsole.log(`De ${dateOfBirth.getFullYear()} a ${currentDate.getFullYear()} han transcurrido ${calculateElapsedYears(currentDate, dateOfBirth)} años.`);\n\nconst days = [\"Domingo\", \"Lunes\", \"Martes\", \"Miércoles\", \"Jueves\", \"Viernes\", \"Sábado\"];\nconst months = [\"Enero\", \"Febrero\", \"Marzo\", \"Abril\", \"Mayo\", \"Junio\", \"Julio\", \"Agosto\", \"Septiembre\", \"Octubre\", \"Noviembre\", \"Diciembre\"];\n\nfunction formatDate(date) {\n  const dayMonthYear = `${days[date.getDay()]} ${date.getDate()} de ${months[date.getMonth()]} de ${date.getFullYear()}`\n  const hourMinuteSecond = `Hora: ${date.getHours()} Minuto: ${date.getMinutes()} Segundo: ${date.getSeconds()}`\n  const dayOfYear = `Día del año: ${date.getDate()}`\n  const dayOfWeek = `Día de la semana: ${days[date.getDay()]}`\n  const nameOfMonth = `Mes: ${months[date.getMonth()]}`\n\n  return {\n    dayMonthYear,\n    hourMinuteSecond,\n    dayOfYear,\n    dayOfWeek,\n    nameOfMonth\n  }\n}\n\nconst data = formatDate(dateOfBirth);\n\nfor(const value in data){\n  console.log(data[value]);\n}"
  },
  {
    "path": "Roadmap/14 - FECHAS/javascript/AChapeton.js",
    "content": "const currentDate = new Date();\nconsole.log(currentDate);\n\nconst birthDate = new Date(1997, 5, 2, 13, 30, 0);\nconsole.log(birthDate);\n\nconst getYearsBetweenDates = function (birthDate, currentDate) {\n    if (currentDate === void 0) { currentDate = new Date(); }\n    const birthTime = new Date(birthDate).getTime();\n    const currentTime = new Date(currentDate).getTime();\n    const age = (currentTime - birthTime) / (365 * 24 * 60 * 60 * 1000);\n    return Math.floor(age);\n};\n\nconsole.log(getYearsBetweenDates(birthDate));\n\n\nconst days = ['Domingo', 'Lunes', 'Martes', 'Miercoles', 'Jueves', 'Viernes', 'Sabado'];\nconst months = ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'];\nconst isLeapYear = function (y) { return y % 4 === 0 && y % 100 !== 0 || y % 400 === 0; };\nconst daysInAYear = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\n\n// DIFICULTAD EXTRA\nconsole.log('Dia, mes, y año: ', birthDate.getDay() + 1, '/', months[birthDate.getMonth()], '/', birthDate.getFullYear());\nconsole.log('Hora, minuto y segundo: ', 'Hora: ', birthDate.getHours(), ' Minutos: ', birthDate.getMinutes(), ' Segundos: ', birthDate.getSeconds());\nconsole.log('Dia de la semana: ', (birthDate.getDay() > 7) ? days[birthDate.getDay() - 7] : days[birthDate.getDay()]);\nconsole.log('Nombre del mes: ', months[birthDate.getMonth()]);\nconsole.log('Año: ', birthDate.getFullYear());\nconsole.log('Version ingles: ', birthDate.toDateString());\nfunction dayOfYear(date) {\n    const d = new Date(date);\n    const daysGiven = d.getDate();\n    const month = d.getMonth();\n    const year = d.getFullYear();\n    if (isLeapYear(year) && month > 1) {\n        return daysInAYear.slice(0, month).reduce(function (a, c) { return a + c; }, 0) + 1 + daysGiven;\n    }\n    else {\n        return daysInAYear.slice(0, month).reduce(function (a, c) { return a + 1; }, 0) + daysGiven;\n    }\n}\nconsole.log('Dia de año: ', dayOfYear(\"06/02/2020\"));\nconsole.log('Fecha completa: ', birthDate.getDay() + 1, ' de ', months[birthDate.getMonth()], ' de ', birthDate.getFullYear());\nconsole.log('Mes/Dia/Año: ', birthDate.toLocaleDateString());\nconsole.log('Formato Tiempo 12 horas: ', birthDate.toLocaleTimeString());\nconsole.log('Formato Tiempo 24 horas: ', birthDate.toTimeString());\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/javascript/DavidMoralesDeveloper.js",
    "content": "// * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n//  * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n//  * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n//  * Calcula cuántos años han transcurrido entre ambas fechas.\n\nconst fechaNow = new Date()\nconsole.log(fechaNow)\nconst añoNow = fechaNow.getFullYear()\nconsole.log(añoNow)\n\nconst fechaBD = new Date(\"1987-04-29:10:15:00z\")\nconsole.log(fechaBD)\nconst añoBD = fechaBD.getFullYear()\nconsole.log(añoBD)\n\nfunction calculadoraDeAños( añoN, añoB ){\n    return añoN - añoB\n}\n\nconsole.log(calculadoraDeAños(añoNow, añoBD) + ' trascurridos desde que naciste')\n\n\n\n// Extra \n// Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n//  * 10 maneras diferentes. Por ejemplo:\n//  * - Día, mes y año.\n//  * - Hora, minuto y segundo.\n//  * - Día de año.\n//  * - Día de la semana.\n//  * - Nombre del mes.\n//  * (lo que se te ocurra...)\n\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date\n\n\nconsole.log( 'fecha normal' +fechaNow.getFullYear() ,fechaNow.getMonth(), fechaNow.getDay())\nconsole.log(fechaNow.toDateString() +'datostring')\nconsole.log( 'hora ' +fechaNow.getHours() ,fechaNow.getMinutes(), fechaNow.getSeconds())\nconsole.log(fechaNow.toTimeString())\nconsole.log(fechaNow[Symbol.toPrimitive]('string'))\nconsole.log(fechaNow.toISOString()+ 'iso')\nconsole.log(fechaNow.toTimeString())\nconst [mes, dia, año] = [\n    fechaBD.getMonth(),\n    fechaBD.getDay(),\n    fechaBD.getFullYear()\n]\nconsole.log(mes, dia, año)\n\nconst [hour, minutes, seconds] = [\n    fechaBD.getHours(),\n    fechaBD.getMinutes(),\n    fechaBD.getSeconds(),\n  ];\n  console.log(hour, minutes, seconds)"
  },
  {
    "path": "Roadmap/14 - FECHAS/javascript/Deyvid-10.js",
    "content": "// Fechas\n\nlet fechaActual = new Date()\nlet fechaNacimiento = new Date(1999, 10, 10, 2, 0)\n\nconsole.log(`La fecha actual es: ${fechaActual.getDate()}-${fechaActual.getMonth() + 1}-${fechaActual.getFullYear()}\\nLa hora es: ${fechaActual.getHours()}:${fechaActual.getMinutes()}`);\nconsole.log(`La fecha de nacimiento es: ${fechaNacimiento.getDate()}-${fechaNacimiento.getMonth() + 1}-${fechaNacimiento.getFullYear()}\\nLa hora de nacimineto es: ${fechaNacimiento.getHours()}:${fechaNacimiento.getMinutes()}`);\n\nlet diferencia = fechaActual.getTime() - fechaNacimiento.getTime()\n\nlet difMin = diferencia / (1000 * 60)\nlet difHoras = difMin / 60\nlet difDias = difHoras / 24\nlet difMes = difDias / 30.4375\nlet difAnio = difMes / 12\n\nconsole.log(`Han pasado ${Math.floor(difAnio)} anios`); // Diferencia de anios\n\n// DIFICULTAD EXTRA\n\nlet arrayMeses = ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio',\n'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre']\n\nlet arrayDiaSemana = ['Lunes', 'Martes', 'Miercoles', 'Jueves', 'Viernes', 'Sabado', 'Domingo']\n\nlet ampm = fechaNacimiento.toLocaleTimeString()\nlet fecha = fechaNacimiento.toLocaleDateString()\nlet segundos = fechaNacimiento.getSeconds()\nlet min = fechaNacimiento.getMinutes()\nlet hora = fechaNacimiento.getHours()\nlet diaSemana = fechaNacimiento.getDay()\nlet dia = fechaNacimiento.getDate()\nlet mes = fechaNacimiento.getMonth()\nlet anio = fechaNacimiento.getFullYear()\n\nconsole.log(`La fecha completa: ${fechaNacimiento}`); // Fecha y hora completa\nconsole.log(`Fecha: ${fecha}`); // Formato DD/MM/AAAA\nconsole.log(`Hora: ${hora}:${min}:${segundos}`); // Formato HH:MM:SS\nconsole.log(`El nombre del mes: ${arrayMeses[mes]}`); // Nombre del mes\nconsole.log(`El dia de la semana es: ${arrayDiaSemana[diaSemana]}`); // Dia de la semana\nconsole.log(`Dia ${dia} de ${arrayMeses[mes]} del ${anio}`); // Fecha con nombre del mes\nconsole.log(`Hora: ${hora}:${min}`);// Formato HH:MM\nconsole.log(`Hora: ${ampm}`); // Formato AM/PM\nconsole.log(`Mi anio de nacimiento es: ${anio}`); // Solo el anio\nconsole.log(`Naci a las ${hora} horas con ${min} minutos`); // Hora de nacimineto"
  },
  {
    "path": "Roadmap/14 - FECHAS/javascript/FabianRpv.js",
    "content": "// Fechas \n\nconst fechaFormat = (fecha) => {\n\n    format = fecha.toLocaleString()\n    return format\n\n}\n\n// Fecha Actual \n\nconst fechaActual = new Date()\nconsole.log(fechaActual)\n\nconst fechaActualFormat = fechaFormat(fechaActual)\nconsole.log(fechaActualFormat)\n\n\nconst year = fechaActual.getFullYear();\nconst month = String(fechaActual.getMonth() + 1).padStart(2, '0');\nconst day = String(fechaActual.getDate()).padStart(2, '0');\nconst hour = String(fechaActual.getHours()).padStart(2, '0');\nconst minute = String(fechaActual.getMinutes()).padStart(2, '0');\nconst second = String(fechaActual.getSeconds()).padStart(2, '0');\n\nconsole.log(`${day}-${month}-${year}  ${hour}:${minute}:${second}`)\n\n\n// Fecha Nacimiento\n\nconst fechaNacimiento = new Date(2004, 10, 10, 15, 20)\n\nconst fechaNacimientoFormat = fechaFormat(fechaNacimiento)\n\nconsole.log(fechaNacimientoFormat)\n\n\n// Diferencia entre fechas\n\nconst diferencia = fechaActual - fechaNacimiento;\nconst diferenciaDias = Math.round(diferencia / (3.154e+10))\n\nconsole.log(diferenciaDias)\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/javascript/Glitzypanic.js",
    "content": "/*\n * EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n */\n\n// Ejercicio 1\nconst fechaActual = new Date();\nconsole.log(fechaActual);\n\nconst fechaNacimiento = new Date(1998, 10, 5, 1, 0, 0);\nconsole.log(fechaNacimiento);\n\nconst tiempoTranscurrido =\n  fechaActual.getFullYear() - fechaNacimiento.getFullYear();\nconsole.log(`\\nHan transcurrido ${tiempoTranscurrido} años.`);\n\n// Ejercicio extra\nconst nacimiento = new Date(\"1998-11-05T04:05:12Z\");\n\nconst year = nacimiento.getFullYear();\nconst day = nacimiento.getDay();\nconst month = nacimiento.getMonth();\n\nconst hour = nacimiento.getHours();\nconst minutes = nacimiento.getMinutes();\nconst seconds = nacimiento.getSeconds();\n\nconst daysOfWeek = [\n  \"Domingo\",\n  \"Lunes\",\n  \"Martes\",\n  \"Miércoles\",\n  \"Jueves\",\n  \"Viernes\",\n  \"Sábado\",\n];\nconst monthsOfYear = [\n  \"Enero\",\n  \"Febrero\",\n  \"Marzo\",\n  \"Abril\",\n  \"Mayo\",\n  \"Junio\",\n  \"Julio\",\n  \"Agosto\",\n  \"Septiembre\",\n  \"Octubre\",\n  \"Noviembre\",\n  \"Diciembre\",\n];\nconst dayOfWeek = daysOfWeek[nacimiento.getDay()];\nconst monthOfYear = monthsOfYear[nacimiento.getMonth()];\n\nconst startOfYear = new Date(nacimiento.getFullYear(), 0, 1);\nconst diffInTime = nacimiento - startOfYear;\nconst dayOfYear = Math.floor(diffInTime / (1000 * 60 * 60 * 24)) + 1;\n\nconsole.log(`\\n${day}/${month}/${year}`);\nconsole.log(`0${hour}:0${minutes}:${seconds}`);\nconsole.log(`${dayOfYear}`);\nconsole.log(`${dayOfWeek}`);\nconsole.log(`${monthOfYear}`);\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #14 - JavaScript ->Jesus Antonio Escamilla */\n/**\n * Los objetos Date representan en JavaScript un momento fijo en el tiempo en un formato independiente.\n*/\n\n//---EJERCIÓ---\n\n// Asi se representa las fechas en JavaScript\n// Variable de la fecha actual (Hora Central)\nconst fecha = new Date();\nconsole.log(fecha);\n\n// Fecha en Mexico\nconsole.log(fecha.toLocaleString());\n\n\n// Variable de fecha de nacimiento\n// Aquí se pone la fecha de nacimiento\nconst fecha_Nacimiento = new Date(1999, 11, 22, 20, 20, 0); // Le quito 1 dígito al mes para que este correctamente la fecha de nacimiento.\nconst diferenciaFechas = Date.now() - fecha_Nacimiento.getTime();\nconst añosTranscurridos = Math.floor(diferenciaFechas/ (365.25 * 24 * 60 * 60 * 1000));\nconsole.log(añosTranscurridos);\n\n\n\n/**-----DIFICULTAD EXTRA-----*/\n\n//  Las variables de escritura\nconst days = ['Domingo', 'Lunes', 'Martes', 'Miércoles', 'Jueves', 'Viernes', 'Sábado'];\nconst months = ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'];\n\n\n//  10 maneras diferentes de mostrar la fecha de nacimiento\n\nconsole.log('1-. Dia, Mes, y Año de nacimiento', fecha_Nacimiento.toLocaleDateString());\nconsole.log('2-. Dia de año', fecha_Nacimiento.getDate());\nconsole.log('3-. Hora, Minutos y Segundos', fecha_Nacimiento.toLocaleTimeString());\nconsole.log('4-. Mes de año', fecha_Nacimiento.getMonth() + 1); // Aquí le agrego 1 mas para que me el mes correcto.\nconsole.log('5-. Dia de la semana' , (fecha_Nacimiento.getDay() > 7 \n                ? days[fecha_Nacimiento.getDay() - 7 ] \n                : days[fecha_Nacimiento.getDay()]));\nconsole.log('6-. Año de nacimiento', fecha_Nacimiento.getFullYear());\nconsole.log('7-. Nombre del Mes de año', months[fecha_Nacimiento.getMonth()]);\nconsole.log('8-. Fecha en Ingles', fecha_Nacimiento.toDateString());\nconsole.log('9-. Tiempo en 24 horas', fecha_Nacimiento.toLocaleTimeString());\nconsole.log('10-. Fecha Completa', fecha_Nacimiento.getDate(), 'de', months[fecha_Nacimiento.getMonth()], 'de', fecha_Nacimiento.getFullYear());\n\n/**-----DIFICULTAD EXTRA-----*/"
  },
  {
    "path": "Roadmap/14 - FECHAS/javascript/RaulDoezon.js",
    "content": "/*\n * EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n*/\n\nconsole.log(\"+++++++++ EJERCICIO +++++++++\");\nvar today = new Date();\nvar birthday = new Date(1992, 2, 31, 7, 30, 0, 999);\nvar msPerYear = 24 * 60 * 60 * 365 * 1000;\nvar years = (today.getTime() - birthday.getTime()) / msPerYear;\n\nconsole.log(`Fecha actual: ${today}`);\nconsole.log(`Fecha de nacimiento: ${birthday}`);\nconsole.log(`Años transcurridos: ${years}`);\n\nconsole.log(\"\\n+++++++++ DIFICULTAD EXTRA +++++++++\");\nconsole.log(`DÍA: ${birthday.getDate()}`);\nconsole.log(`MES: ${birthday.getMonth() + 1}`);\nconsole.log(`AÑO: ${birthday.getFullYear()}`);\nconsole.log(`DÍA DE LA SEMANA: ${birthday.getDay()}`);\nconsole.log(`HORAS: ${birthday.getHours()}`);\nconsole.log(`MINUTOS: ${birthday.getMinutes()}`);\nconsole.log(`SEGUNDOS: ${birthday.getSeconds()}`);\nconsole.log(`MILISEGUNDOS: ${birthday.getMilliseconds()}`);\nconsole.log(`FECHA: ${birthday.getDate()}/${birthday.getMonth() + 1}/${birthday.getFullYear()}`);\nconsole.log(`HORA: ${birthday.getHours()}:${birthday.getMinutes()}:${birthday.getSeconds()}`);\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/javascript/RicJDev.js",
    "content": "/*\n * EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n */\n\nconst monthArr = [\n\t'Enero',\n\t'Febrero',\n\t'Marzo',\n\t'Abril',\n\t'Mayo',\n\t'Junio',\n\t'Julio',\n\t'Agosto',\n\t'Septiembre',\n\t'Octubre',\n\t'Noviembre',\n\t'Diciembre',\n];\n\nconst daysArr = [\n\t'Domingo',\n\t'Lunes',\n\t'Martes',\n\t'Miércoles',\n\t'Jueves',\n\t'Viernes',\n\t'Sábado',\n];\n\n//EJERCICIO\nconsole.log('\\nFecha actual:');\nlet now = new Date();\nconsole.log(now);\n\nconsole.log('\\nFecha de nacimiento:');\nlet birthDate = new Date(2002, 8, 22, 12, 0, 34, 676);\nconsole.log(birthDate);\n\nlet age = Math.floor(\n\t(now.getTime() - birthDate.getTime()) / (365 * 24 * 60 * 60 * 1000)\n);\n\nconsole.log(`\\nTengo ${age} años de edad`);\n\n//EXTRA\nconsole.log('\\nFecha de nacimiento con distintos formatos:');\n\nconsole.log(\n\t`\\nDía, mes y año: ${birthDate.getDate()}.${\n\t\tbirthDate.getMonth() + 1\n\t}.${birthDate.getFullYear()}`\n);\n\nconsole.log(\n\t`\\nHora, minuto y segundo: ${birthDate.getHours()}:${birthDate.getMinutes()}.${birthDate.getSeconds()}`\n);\n\ndayAtTheYear = Math.floor(\n\t(birthDate - new Date(birthDate.getFullYear(), 0, 0)) / (24 * 60 * 60 * 1000)\n);\nconsole.log(`\\nDía del año: ${dayAtTheYear}`);\n\nconsole.log(\n\t`\\nDía de la semana: ${daysArr[birthDate.getDay()]} ${birthDate.getDate()}`\n);\n\nconsole.log(`\\nNombre del mes: ${monthArr[birthDate.getMonth()]}`);\n\nconsole.log(`\\nEn inglés: ${birthDate.toDateString()}`);\n\nconsole.log(`\\nHora local: ${birthDate.toLocaleTimeString()}`);\n\nlet UnixTimeYears = Math.floor(\n\tbirthDate.getTime() / (365 * 24 * 60 * 60 * 1000)\n);\nconsole.log(\n\t`\\nContando los años desde el 1 de enero de 1970 hasta esa fecha: ${UnixTimeYears} años`\n);\n\nlet UnixTimeDays = Math.floor(birthDate.getTime() / (24 * 60 * 60 * 1000));\nconsole.log(\n\t`\\nContando los días desde el 1 de enero de 1970 hasta esa fecha: ${UnixTimeDays} días`\n);\n\nlet myMomBirthDate = new Date(1978, 11, 25, 21, 15);\nlet diference = Math.floor(\n\t(birthDate.getTime() - myMomBirthDate.getTime()) / (365 * 24 * 60 * 60 * 1000)\n);\nconsole.log(`\\nContando los años desde el nacimiento de mi mamá: ${diference} años`);\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/javascript/Sac-Corts.js",
    "content": "const currentDate = new Date();\nconst birthdate = new Date('2001-10-21T08:30:00');\n\nfunction calculateAge(currentDate, birthdate) {\n    let age = currentDate.getFullYear() - birthdate.getFullYear();\n    const month = currentDate.getMonth() - birthdate.getMonth();\n\n    if (month < 0 || (month === 0 && currentDate.getDate() < birthdate.getDate())) {\n        age--;\n    }\n\n    return age;\n}\n\nconst age = calculateAge(currentDate, birthdate);\nconsole.log(`${age} years have passed since the date of birth`);\n\n// Extra Exercise //\nconst dayMonthYear = birthdate.toLocaleDateString('es-ES');\n\nconst hourMinuteSecond = birthdate.toLocaleTimeString('es-ES');\n\nconst startYear = new Date(birthdate.getFullYear(), 0, 0);\nconst difference = birthdate - startYear;\nconst oneDay = 1000 * 60 * 60 * 24;\nconst dayOfTheYear = Math.floor(difference / oneDay);\n\nconst dayOfTheWeek = birthdate.toLocaleDateString('es-ES', { weekday: 'long' });\n\nconst nameMonth = birthdate.toLocaleDateString('es-ES', { month: 'long' });\n\nconst longDate = birthdate.toLocaleDateString('es-ES', { year: 'numeric', month: 'long', day: 'numeric' });\n\nconst formatISO = birthdate.toISOString();\n\nconst formatUTC = birthdate.toUTCString();\n\nconst timeUnix = birthdate.getTime();\n\nconst abbreviatedDate = birthdate.toLocaleDateString('es-ES', { weekday: 'short', month: 'short', day: 'numeric' });\n\nconsole.log('Day, month and year:', dayMonthYear);\nconsole.log('Hour, minute and second:', hourMinuteSecond);\nconsole.log('Day of the year:', dayOfTheYear);\nconsole.log('Day of the week:', dayOfTheWeek);\nconsole.log('Name of the month:', nameMonth);\nconsole.log('Long date:', longDate);\nconsole.log('Format ISO:', formatISO);\nconsole.log('Format UTC:', formatUTC);\nconsole.log('Time in milliseconds since 1970:', timeUnix);\nconsole.log('Abbreviated date:', abbreviatedDate);"
  },
  {
    "path": "Roadmap/14 - FECHAS/javascript/adrs1166ma.js",
    "content": "/* 🔥 EJERCICIO:\nCrea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n- Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n- Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\nCalcula cuántos años han transcurrido entre ambas fechas.\n*/\nconst fechaActual = new Date()\n// Fecha de nacimiento : 1 de agosto de 2004, a las 01:30:00.\nconst fechaNacimiento = new Date(2004, 7, 1, 1, 30, 0)\n\nfunction calcularEdad(fechaNac) {\n    const diffMs = fechaActual - fechaNac\n    const diffYears = diffMs / (1000 * 60 * 60 * 24 * 365.25)\n    return Math.floor(diffYears)\n}\nconsole.log(`Han transcurrido ${calcularEdad(fechaNacimiento)} años desde tu fecha de nacimiento.`)\n/* Dictionary 📗 = {\n    Math.floor : \"Redondea un número hacia abajo al entero más cercano\"\n    Date : \"Meses en JavaScript son base 0 (7 = agosto) y este maneja milisegundos\"\n    \"(1000 * 60 * 60 * 24 * 365.25)\" : \"Convierte milisegundos en años, considerando años bisiestos\"\n}\n*/\n\n/*----------------------------------------------------------------------------------------------------------------------\n🔥 DIFICULTAD EXTRA (opcional):\nUtilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n10 maneras diferentes. Por ejemplo:\n- Día, mes y año.\n- Hora, minuto y segundo.\n- Día de año.\n- Día de la semana.\n- Nombre del mes.\n(lo que se te ocurra...)\n*/\n// ! 10 maneras diferentes\nfunction formatearFecha(fecha) {\n    const opciones = {\n        weekday: 'long', // Nombre del día de la semana\n        year: 'numeric', // Año completo\n        month: 'long',   // Nombre del mes\n        day: 'numeric',  // Día del mes\n        hour: '2-digit', // Hora en formato de 2 dígitos\n        minute: '2-digit', // Minutos en formato de 2 dígitos\n        second: '2-digit'  // Segundos en formato de 2 dígitos\n    };\n\n    console.log(\"1. Día, mes y año:\", fecha.toLocaleDateString())\n    console.log(\"2. Hora, minuto y segundo:\", fecha.toLocaleTimeString())\n    console.log(\"3. Día del año:\", obtenerDiaDelAño(fecha))\n    console.log(\"4. Día de la semana:\", fecha.toLocaleDateString('es-ES', { weekday: 'long' }))\n    console.log(\"5. Nombre del mes:\", fecha.toLocaleDateString('es-ES', { month: 'long' }))\n    console.log(\"6. Fecha completa:\", fecha.toLocaleString('es-ES', opciones))\n    console.log(\"7. Año:\", fecha.getFullYear())\n    console.log(\"8. Mes (número):\", fecha.getMonth() + 1)\n    console.log(\"9. Fecha en formato ISO:\", fecha.toISOString())\n    console.log(\"10. Tiempo en milisegundos desde 1970:\", fecha.getTime())\n}\n// ! For 3. Día del año:\nfunction obtenerDiaDelAño(fecha) {\n    const inicioAño = new Date(fecha.getFullYear(), 0, 1)\n    const diffMs = fecha - inicioAño\n    return Math.floor(diffMs / (1000 * 60 * 60 * 24)) + 1\n}\n\nformatearFecha(fechaNacimiento);"
  },
  {
    "path": "Roadmap/14 - FECHAS/javascript/agusrosero.js",
    "content": "/*\n * EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n */\n\n// EJERCICIO:\nconst date = new Date();\nconst options = {\n  year: \"numeric\",\n  month: \"2-digit\",\n  day: \"2-digit\",\n  hour: \"2-digit\",\n  minute: \"2-digit\",\n  second: \"2-digit\",\n};\n\n// Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\nconst fechaActual = date.toLocaleString(\"es-AR\", options);\nconsole.log(fechaActual);\n\n// Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\nconst fechaNacimiento = new Date(2000, 7, 3, 7, 30, 10);\nconsole.log(fechaNacimiento);\n\n// Calcula cuántos años han transcurrido entre ambas fechas.\nfunction aniosTranscurridos(fechaNac) {\n  const hoy = new Date();\n  const nacimiento = new Date(fechaNac);\n\n  let edad = hoy.getFullYear() - nacimiento.getFullYear();\n  let mes = hoy.getMonth() - nacimiento.getMonth();\n  if (mes < 0 || (mes === 0 && hoy.getDate() < nacimiento.getDate())) {\n    edad--;\n  }\n  return edad;\n}\n\nconst fechaNac = \"2000-08-03\";\nconsole.log(`Años transcurridos: ${aniosTranscurridos(fechaNac)}`);\n\n// DIFICULTAD EXTRA:\n// 1\nconsole.log(fechaNacimiento.toLocaleString(\"es-AR\"));\n// 2\nconsole.log(fechaNacimiento.toLocaleDateString(\"es-AR\"));\n// 3\nconsole.log(fechaNacimiento.toLocaleTimeString(\"es-AR\"));\n// 4\nconsole.log(fechaNacimiento.toISOString());\n// 5\nconsole.log(fechaNacimiento.toUTCString());\n// 6\nconst optionsMonthYear = { year: \"numeric\", month: \"long\" };\nconsole.log(fechaNacimiento.toLocaleString(\"es-AR\", optionsMonthYear));\n// 7\nconst option = {\n  year: \"numeric\",\n  month: \"long\",\n  day: \"numeric\",\n  weekday: \"long\",\n  hour: \"numeric\",\n  minute: \"numeric\",\n  second: \"numeric\",\n};\nconsole.log(fechaNacimiento.toLocaleString(\"es-AR\", option));\n// 8\nconst optionsDayMonth = { day: \"numeric\", month: \"long\" };\nconsole.log(fechaNacimiento.toLocaleString(\"es-AR\", optionsDayMonth));\n// 9\nconst year = fechaNacimiento.getFullYear();\nconst month = String(fechaNacimiento.getMonth() + 1).padStart(2, \"0\");\nconst day = String(fechaNacimiento.getDate()).padStart(2, \"0\");\nconsole.log(`${year}-${month}-${day}`);\n// 10\nconst hours = String(fechaNacimiento.getHours()).padStart(2, \"0\");\nconst minutes = String(fechaNacimiento.getMinutes()).padStart(2, \"0\");\nconst seconds = String(fechaNacimiento.getSeconds()).padStart(2, \"0\");\nconsole.log(`${hours}:${minutes}:${seconds}`);\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/javascript/alexdevrep.js",
    "content": "/*\n * EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n */\n\n//Fecha actual\nlet fecha = new Date()\nconsole.log(fecha)\n\n//Fecha de nacimiento\nlet nacimiento = new Date()\nnacimiento.setUTCFullYear(1999)\nnacimiento.getUTCFullYear()\nnacimiento.setMonth(6) //Los meses en JavaScript van de 0 (enero) a 11 (diciembre)\nnacimiento.getMonth()\nnacimiento.setDate(22)\nnacimiento.getDate()\nconsole.log(nacimiento)\n\n//Calculamos el tiempo transcurrido entre ambas fechas\nlet edad = fecha -nacimiento //Edad en milisegundos\nconsole.log(edad)\n\n\n\n\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/javascript/bernatcs.js",
    "content": "// ** EJERCICIO\n\nlet fechaActual = new Date\nlet fechaNacimiento = new Date(2001, 9, 16, 20, 22, 22)\n\nnew Date()\n\nlet restaAños = fechaActual.getFullYear() - fechaNacimiento.getFullYear() + ' años'\nrestaAños // '23 años'\n\n\n// ** DIFICULTAD EXTRA ** -----------------------------------------------------------------------------------------------------------------------------------------------\n\nlet diaMesAño = fechaNacimiento.getDate() + ' - ' + fechaNacimiento.getMonth() + ' - ' + fechaNacimiento.getFullYear()\ndiaMesAño // '1 - 1 - 2000'\n\n\nlet horaMinutoSegundo = fechaNacimiento.getHours() + ':' + fechaNacimiento.getMinutes() + ':' + fechaNacimiento.getSeconds()\nhoraMinutoSegundo // '20:22:22'\n\n\nfunction diaDeAño(date) {\n    let fechaInicioAño = new Date(Date.UTC(date.getFullYear(), 0, 1))\n    console.log(Math.floor((fechaNacimiento.getTime() - fechaInicioAño.getTime())/1000/60/60/24) + ' días')\n}\n\ndiaDeAño(fechaNacimiento)\n\n\nlet semanas = ['Lunes', 'Martes', 'Miércoles', 'Jueves', 'Viernes', 'Sábado', 'Domingo']\nlet nombreDeLaSemana = semanas[fechaNacimiento.getDay()-1]\nnombreDeLaSemana\n\n\nlet meses = ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre']\nlet nombreDelMes = meses[fechaNacimiento.getMonth()-1]\nnombreDelMes"
  },
  {
    "path": "Roadmap/14 - FECHAS/javascript/caterinarodriguezdev.js",
    "content": "/*\n * EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n */\n\nconst currentDate = new Date();\nconst myBirthDate = new Date(1999, 7, 12, 7, 30, 12);\n\nconsole.log(`Han transcurrido ${currentDate.getFullYear() - myBirthDate.getFullYear()} años`);\n\nconst format1 = { day: 'numeric', month: 'numeric',  year: 'numeric' };\nconst format2 = { year: '2-digit', month: '2-digit', day: '2-digit' };\nconst format3 = { year: 'numeric', month: 'long', day: 'numeric' };\nconst format4 = { weekday: 'short', month: 'short'};\nconst format5 = { weekday: 'long', month: 'long', day: 'numeric' };\nconst format6 = { weekday: 'short', day: 'numeric', month: 'short' };\nconst format7 = { month: 'long', year: 'numeric' };\nconst format8 = { day: 'numeric', month: 'numeric' };\nconst format9 = { month: 'long'};\nconst format10 = { weekday: 'long'};\n\nconsole.log(myBirthDate.toLocaleDateString('es-ES', format1));\nconsole.log(`${myBirthDate.getHours()} horas, ${myBirthDate.getMinutes()} minutos y ${myBirthDate.getSeconds()} segundos`);\nconsole.log(myBirthDate.toLocaleDateString('es-ES', format3));\nconsole.log(myBirthDate.toLocaleDateString('es-ES', format4));\nconsole.log(myBirthDate.toLocaleDateString('es-ES', format5));\nconsole.log(myBirthDate.toLocaleDateString('es-ES', format6));\nconsole.log(myBirthDate.toLocaleDateString('es-ES', format7));\nconsole.log(myBirthDate.toLocaleDateString('es-ES', format8));\nconsole.log(myBirthDate.toLocaleDateString('es-ES', format9));\nconsole.log(myBirthDate.toLocaleDateString('es-ES', format10));"
  },
  {
    "path": "Roadmap/14 - FECHAS/javascript/cesar-ch.js",
    "content": "/*\n    * #14 FECHAS\n*/\n\nlet fechaActual = new Date();\nlet fechaNacimiento = new Date(\"2005-04-15T12:00:00\");\n\nlet diferenciaMilisegundos = fechaActual - fechaNacimiento;\nlet añosTranscurridos = Math.floor(diferenciaMilisegundos / (1000 * 60 * 60 * 24 * 365.25));\nconsole.log(\"Han transcurrido \" + añosTranscurridos + \" años desde mi nacimiento.\");\n\n/*\n    * DIFICULTAD EXTRA\n*/\n\nconsole.log(\"1. Día, mes y año: \" + fechaNacimiento.getDate() + \"/\" + (fechaNacimiento.getMonth() + 1) + \"/\" + fechaNacimiento.getFullYear())\n\nconsole.log(\"2. Hora, minuto y segundo: \" + fechaNacimiento.getHours() + \":\" + fechaNacimiento.getMinutes() + \":\" + fechaNacimiento.getSeconds())\n\nconsole.log(\"3. Día de año: \" + (Math.floor((fechaNacimiento - new Date(fechaNacimiento.getFullYear(), 0, 0)) / 86400000)))\n\nconsole.log(\"4. Día de la semana: \" + fechaNacimiento.toLocaleString('es', { weekday: 'long' }))\n\nconsole.log(\"5. Nombre del mes: \" + fechaNacimiento.toLocaleString('es', { month: 'long' }))\n\nconsole.log(\"6. Mes abreviado y año: \" + fechaNacimiento.toLocaleString('es', { month: 'short' }) + \" \" + fechaNacimiento.getFullYear())\n\nconsole.log(\"7. Hora en formato de 12 horas: \" + ((fechaNacimiento.getHours() % 12) || 12) + \":\" + fechaNacimiento.getMinutes() + \":\" + fechaNacimiento.getSeconds() + \" \" + (fechaNacimiento.getHours() >= 12 ? 'PM' : 'AM'))\n\nconsole.log(\"8. Edad en días: \" + Math.floor((fechaActual - fechaNacimiento) / (1000 * 60 * 60 * 24)))\n\nconsole.log(\"9. Edad en meses: \" + Math.floor((fechaActual - fechaNacimiento) / (1000 * 60 * 60 * 24 * 30.44)))\n\nconsole.log(\"10. Día de la semana abreviado, día de mes y año: \" + fechaNacimiento.toLocaleString('es', { weekday: 'short' }) + \", \" + fechaNacimiento.getDate() + \" de \" + fechaNacimiento.toLocaleString('es', { month: 'long' }) + \" de \" + fechaNacimiento.getFullYear())\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/javascript/christian-jfr.js",
    "content": "// #14 FECHAS\n\n/*\n * EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n */\n\nlet currentDate = new Date();\nconst birthDate = new Date('1987-09-26T03:15:00');\n\nconst millisecondsInYear = 1000 * 60 * 60 * 24 * 365;\n\nlet howManyYearsHavePassed = (currentDate - birthDate) / millisecondsInYear;\nlet yearsPassed = howManyYearsHavePassed.toFixed(2);\n\nconsole.log(yearsPassed);\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n */\n\n// 1\nconst birthDateFormated1 = birthDate.toDateString();\nconsole.log(birthDateFormated1); // Sat Sep 26 1987\n\n// 2\nconst birthDateFormated2 = birthDate.toLocaleDateString('es-CO', {\n\tweekday: 'long',\n\tyear: 'numeric',\n\tmonth: 'long',\n\tday: 'numeric',\n});\nconsole.log(birthDateFormated2); // sábado, 26 de septiembre de 1987\n\n// 3\nconst birthDateFormated3 = birthDate.toLocaleDateString('es-CO', {\n\tweekday: 'short',\n\tyear: 'numeric',\n\tmonth: 'numeric',\n\tday: 'numeric',\n});\nconsole.log(birthDateFormated3); // sáb, 26/9/1987\n\n// 4\nconsole.log(birthDate.toLocaleTimeString()); // 03:15:00 AM\n\n// 5\nconsole.log(birthDate.getDate()); // 26\n\n// 6\nconst dayNames = [\n\t'Sunday',\n\t'Monday',\n\t'Tuesday',\n\t'Wednesday',\n\t'Thursday',\n\t'Friday',\n\t'Saturday',\n];\n\nconsole.log(dayNames[birthDate.getDay()]); // Saturday\n\n// 7\nconst months = [\n\t'January',\n\t'February',\n\t'March',\n\t'April',\n\t'May',\n\t'June',\n\t'July',\n\t'August',\n\t'September',\n\t'October',\n\t'November',\n\t'December',\n];\n\nconsole.log(months[birthDate.getMonth()]); // September\n\n// 8\nconst timePassed = Date.now() - birthDate.getTime();\n\nconst seconds = Math.floor(timePassed / 1000);\nconst minutes = Math.floor(seconds / 60);\nconst hours = Math.floor(minutes / 60);\nconst days = Math.floor(hours / 24);\n\nconsole.log(\n\t`has been ${days} days, ${hours % 24} hours, ${minutes % 60} minutes and ${\n\t\tseconds % 60\n\t} seconds`\n);\n\n// 9\nconst january_1 = new Date(birthDate.getFullYear(), 0, 1);\n\nconst differenceInMilliseconds = birthDate.getTime() - january_1.getTime();\n\nconst dayOfYear =\n\tMath.floor(differenceInMilliseconds / (1000 * 60 * 60 * 24)) + 1;\n\nconsole.log(`September 26, 1987 was the ${dayOfYear} day of the year.`);\n\n// 10\nconsole.log(birthDate.getFullYear()); // 1987\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/javascript/duendeintemporal.js",
    "content": "/*\n * EJERCICIO #14 FECHAS:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n */\n\n// bibliography\n//Professional JavaScript for web developers by Matt Frisbie [Frisbie, Matt] (z-lib.org)\n//GPT\n\n\n// short for console.log()\nlet log = console.log;\n\nwindow.addEventListener('load', ()=>{\n    const body = document.querySelector('body');\n    const title = document.createElement('h1');\n    \n    body.style.setProperty('background', '#000');\n    body.style.setProperty('text-align', 'center');\n    \n    title.textContent = 'Retosparaprogramadores #14.';\n    title.style.setProperty('font-size', '3.5vmax');\n    title.style.setProperty('color', '#fff');\n    title.style.setProperty('line-height', '100vh');\n    \n    body.appendChild(title);\n    \n    setTimeout(()=>{\n    alert('Retosparaprogramadores #14. Please open the Browser Developer Tools.');\n    }, 2000);\n    log( 'Retosparaprogramadores #14'); \n});\n\n\nlet today = new Date()\nlog(today); // Date Fri Oct 18 2024 10:24:48 GMT-0400 (Venezuela Time)\nlog(today.toDateString()); // Fri Oct 18 2024\nlet myBirthday = new Date(Date.parse(\"1983-08-08T08:30:00\"));\nlog(myBirthday); // Date Mon Aug 08 1983 08:30:00 GMT-0400 (Venezuela Time)\nlog(myBirthday.toLocaleDateString()); // 8/8/1983\nlog(myBirthday.toLocaleString()); // 8/8/1983, 8:30:00 AM\n\nconst calcYearsBetween = (date1, date2) => {\n    if (date1 < date2) {\n        [date1, date2] = [date2, date1]; // Swap if date1 is earlier\n    }\n\n    const differenceInMilliseconds = date1.getTime() - date2.getTime();\n\n    const years = differenceInMilliseconds / (1000 * 60 * 60 * 24 * 365.25);\n\n    let fullYears = Math.floor(years);\n\n    // Check if the anniversary has not yet occurred this year\n    if (\n        date1.getMonth() < date2.getMonth() ||\n        (date1.getMonth() === date2.getMonth() && date1.getDate() < date2.getDate())\n    ) {\n        fullYears--;\n    }    \n    return years; \n};\n\n// Note: By incorporating the anniversary check, the function provides a more accurate representation of the year difference.\n\n\n// Note: Using 365.25 rather than 365 allows for greater precision because it accounts for leap years.\n\nconst yearsBetween = calcYearsBetween(today, myBirthday);\nlog(`Years between: ${yearsBetween.toFixed(2)}`); // 41.20\n\n\n//or just\nconst calcYearsBetween2 = (date1, date2) => {\n    if (date1 < date2) {\n        [date1, date2] = [date2, date1]; // Swap if date1 is earlier\n    }\n    const years = date1.getFullYear() - date2.getFullYear();  \n    \n    if (\n        date1.getMonth() < date2.getMonth() ||\n        (date1.getMonth() === date2.getMonth() && date1.getDate() < date2.getDate())\n    ) {\n        years--; \n    }\n\n    return years; \n }; \n\nlog(calcYearsBetween2(today, myBirthday)); // 41\n\n\n\nconst calcDateDifference = (date1, date2) => {\n    // Ensure date1 is the later date\n    if (date1 < date2) {\n        [date1, date2] = [date2, date1]; // Swap if date1 is earlier\n    }\n\n    // Calculate the difference in milliseconds\n    const differenceInMilliseconds = date1.getTime() - date2.getTime();\n\n    // Calculate total seconds\n    const totalSeconds = Math.floor(differenceInMilliseconds / 1000);\n    \n    // Calculate total minutes\n    const totalMinutes = Math.floor(totalSeconds / 60);\n    \n    // Calculate total hours\n    const totalHours = Math.floor(totalMinutes / 60);\n    \n    // Calculate total days\n    const totalDays = Math.floor(totalHours / 24);\n    \n    // Calculate years, months, weeks, and remaining days\n    const years = date1.getFullYear() - date2.getFullYear();\n    const months = date1.getMonth() - date2.getMonth() + (years * 12);\n    const weeks = Math.floor(totalDays / 7);\n    const days = totalDays % 7;\n\n    // Calculate remaining hours, minutes, and seconds\n    const remainingHours = totalHours % 24;\n    const remainingMinutes = totalMinutes % 60;\n    const remainingSeconds = totalSeconds % 60;\n\n    return {\n        years,\n        months,\n        weeks,\n        days,\n        hours: remainingHours,\n        minutes: remainingMinutes,\n        seconds: remainingSeconds\n    };\n};\n\n\nconst difference = calcDateDifference(today, myBirthday);\nlog(`Difference: \n${difference.years} years, \n${difference.months} months, \n${difference.weeks} weeks, \n${difference.days} days, \n${difference.hours} hours, \n${difference.minutes} minutes, \n${difference.seconds} seconds`);\n\n/* Difference: \n41 years, \n494 months, \n2149 weeks, \n4 days, \n6 hours, \n28 minutes, \n38 seconds */\n\n\n// Extra dificulty Exercise\n\nconst formatBirthday = (birthday) => {\n    const date = new Date(birthday);\n\n    const dayMonthYear = date.toLocaleDateString('en-US', { day: 'numeric', month: 'long', year: 'numeric' });\n    \n    const time = date.toLocaleTimeString('es-ES', { hour: 'numeric', minute: 'numeric', second: 'numeric' });\n    \n    const dayOfYear = Math.floor((date - new Date(date.getFullYear(), 0, 0)) / 1000 / 60 / 60 / 24);\n    \n    const dayOfWeek = date.toLocaleDateString('en-US', { weekday: 'long' });\n    \n    const monthName = date.toLocaleDateString('en-US', { month: 'long' });\n    \n    const isoFormat = date.toISOString();\n    \n    const shortFormat = date.toLocaleDateString('en-US');\n    \n    const longFormat = date.toLocaleDateString('en-US', { weekday: 'long', day: 'numeric', month: 'long', year: 'numeric' });\n    \n    const time12Hour = date.toLocaleString('en-US', { hour: 'numeric', minute: 'numeric', second: 'numeric', hour12: true });\n    \n    const timeWithTimezone = date.toLocaleString('es-ES', { timeZoneName: 'short' });\n\n   log(\"1. I was born on:\", dayMonthYear);\n   log(\"2. at:\", time + ' AM');\n   log(\"3. the day:\", dayOfYear + ' of the year ' + date.getFullYear());\n   log(\"4. on:\", dayOfWeek);\n   log(\"5. one special day of:\", monthName);\n   log(\"6. isoFormat:\", isoFormat);\n   log(\"7. shortFormat:\", shortFormat);\n   log(\"8. longFormat:\", longFormat);\n   log(\"9. time12hour:\", time12Hour);\n   log(\"10. timeWithTimezone:\", timeWithTimezone);\n};\n\nformatBirthday(myBirthday);\n/* \n1. I was born on: August 8, 1983 \n2. at: 8:30:00 AM \n3. the day: 220 of the year 1983 \n4. on: Monday \n5. one special day of: August \n6. isoFormat: 1983-08-08T12:30:00.000Z \n7. shortFormat: 8/8/1983 \n8. longFormat: Monday, August 8, 1983 \n9. time12hour: 8:30:00 AM \n10. timeWithTimezone: 8/8/1983, 8:30:00 GMT-4 */\n\n\n\n//REFERENCE INFORMATION:\n\n\n/* Date-Formatting Methods\nThere are several Date type methods used specifically to format the date as a string. They are\nas follows:\n➤➤ toDateString()—Displays the date’s day of the week, month, day of the month, and year in\nan implementation-specific format.\n➤➤ toTimeString()—Displays the date’s hours, minutes, seconds, and time zone in an imple-\nmentation-specific format.\n➤➤ toLocaleDateString()—Displays the date’s day of the week, month, day of the month, and\nyear in an implementation- and locale-specific format.\n➤➤ toLocaleTimeString()—Displays the date’s hours, minutes, and seconds in an implementa-\ntion-specific format.\n➤➤ toUTCString()—Displays the complete UTC date in an implementation-specific format.\nThe output of these methods, as with toLocaleString() and toString(), varies widely from\nbrowser to browser and therefore can’t be employed in a user interface for consistent display of a date.\n\nNOTE There is also a method called toGMTString(), which is equivalent to toUTCString() and is provided for backwards compatibility. However, the specification recommends that new code use toUTCString() exclusively.\n\nDate/Time Component Methods\nThe remaining methods of the Date type (listed in the following table) deal directly with getting and\nsetting specific parts of the date value. Note that references to a UTC date mean the date value when\ninterpreted without a time-zone offset (the date when converted to GMT).\nMETHOD DESCRIPTION\ngetTime() Returns the milliseconds representation of the date; same as\nvalueOf().\nsetTime(milliseconds) Sets the milliseconds representation of the date, thus changing the entire date.\ngetFullYear() Returns the four-digit year (2019 instead of just 19).\ngetUTCFullYear() Returns the four-digit year of the UTC date value.\nsetFullYear(year) Sets the year of the date. The year must be given with four digits (2019 instead of just 19).\nsetUTCFullYear(year) Sets the year of the UTC date. The year must be given with four digits (2019 instead of just 19).\ngetMonth() Returns the month of the date, where 0 represents January and 11 represents December.\ngetUTCMonth() Returns the month of the UTC date, where 0 represents January and 11 represents December.\nsetMonth(month) Sets the month of the date, which is any number 0 or greater. Numbers greater than 11 add years.\nsetUTCMonth(month) Sets the month of the UTC date, which is any number 0 or greater. Numbers greater than 11 add years.\ngetDate() Returns the day of the month (1 through 31) for the date.\ngetUTCDate() Returns the day of the month (1 through 31) for the UTC date.\nsetDate(date) Sets the day of the month for the date. If the date is greater\nthan the number of days in the month, the month value also\ngets increased.\nsetUTCDate(date) Sets the day of the month for the UTC date. If the date is greater than the number of days in the month, the month value also gets increased.\ngetDay() Returns the date’s day of the week as a number (where 0 represents Sunday and 6 represents Saturday).\ngetUTCDay() Returns the UTC date’s day of the week as a number (where 0 represents Sunday and 6 represents Saturday).\ngetHours() Returns the date’s hours as a number between 0 and 23.\ngetUTCHours() Returns the UTC date’s hours as a number between 0 and 23.\nsetHours(hours) Sets the date’s hours. Setting the hours to a number greater than 23 also increments the day of the month.\nsetUTCHours(hours) Sets the UTC date’s hours. Setting the hours to a number greater than 23 also increments the day of the month.\ngetMinutes() Returns the date’s minutes as a number between 0 and 59.\ngetUTCMinutes() Returns the UTC date’s minutes as a number between 0 and 59.\nsetMinutes(minutes) Sets the date’s minutes. Setting the minutes to a number greater than 59 also increments the hour.\nsetUTCMinutes(minutes) Sets the UTC date’s minutes. Setting the minutes to a number greater than 59 also increments the hour.\ngetSeconds() Returns the date’s seconds as a number between 0 and 59.\ngetUTCSeconds() Returns the UTC date’s seconds as a number between 0 and 59.\nsetSeconds(seconds) Sets the date’s seconds. Setting the seconds to a number greater than 59 also increments the minutes.\nsetUTCSeconds(seconds) Sets the UTC date’s seconds. Setting the seconds to a number greater than 59 also increments the minutes.\ngetMilliseconds() Returns the date’s milliseconds.\ngetUTCMilliseconds() Returns the UTC date’s milliseconds.\nsetMilliseconds(milliseconds) Sets the date’s milliseconds.\nsetUTCMilliseconds(milliseconds) Sets the UTC date’s milliseconds.\ngetTimezoneOffset() Returns the number of minutes that the local time zone is offset from UTC. For example, Eastern Standard Time returns 300. This value changes when an area goes into Daylight Saving Time. */"
  },
  {
    "path": "Roadmap/14 - FECHAS/javascript/emedevelopa.js",
    "content": "let fecha = new Date();\nconsole.log(fecha);\n\nlet miFecha = new Date(1990, 11, 8, 4, 11, 11);\nconsole.log(miFecha);\n\n\nfunction años (fecha, miFecha) {\n    let tiempoEnMs = fecha - miFecha;\n    let tiempoPasado = tiempoEnMs / (1000 * 60 * 60 * 24 * 365);\n    tiempoPasado = Math.floor(tiempoPasado);\n    return tiempoPasado;\n}\n\nconsole.log(años(fecha, miFecha));\n\n//EXTRA\nconsole.log(\"Día, mes y año:\", miFecha.getDate(), \"/\" + (miFecha.getMonth() + 1), \"/\" + miFecha.getFullYear());\nconsole.log(\"Hora, minutos y segundos:\", miFecha.getHours() + \":\" + miFecha.getMinutes() + \":\" + miFecha.getSeconds());\nconsole.log(\"Día de año:\", Math.floor((miFecha - new Date(miFecha.getFullYear(), 0, 0)) / (1000 * 60 * 60 * 24)));\nlet diaSemana = [\"Domingo\", \"Lunes\", \"Martes\", \"Miercoles\", \"Jueves\", \"Viernes\", \"Sábado\"]\nconsole.log(\"Día de la semana:\", diaSemana[miFecha.getDay()]);\nlet nombreMes = [\"Enero\", \"Febrero\", \"Marzo\", \"Abril\", \"Mayo\", \"Junio\", \"Julio\", \"Agosto\", \"Septiembre\", \"Octubre\", \"Noviembre\", \"Diciembre\"]\nconsole.log(\"Mes de año:\" , nombreMes[miFecha.getMonth()])\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/javascript/eugeniasoria.js",
    "content": "/*\r\n * EJERCICIO:\r\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\r\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\r\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\r\n * Calcula cuántos años han transcurrido entre ambas fechas.\r\n *\r\n * DIFICULTAD EXTRA (opcional):\r\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\r\n * 10 maneras diferentes. Por ejemplo:\r\n * - Día, mes y año.\r\n * - Hora, minuto y segundo.\r\n * - Día de año.\r\n * - Día de la semana.\r\n * - Nombre del mes.\r\n * (lo que se te ocurra...)\r\n */\r\n\r\n//Calcular años desde el nacimiento\r\nfunction calculateYearsSinceBirthday(birthDay) {\r\n  console.log(\"EJERCICIO\");\r\n  let currentDate = new Date();\r\n  let resultado = \"\";\r\n  //La fecha de nacimiento no puede ser mayor que la fecha actual\r\n  if (birthDay > currentDate) {\r\n    console.log(\r\n      \"La fecha de nacimiento no puede ser mayor que la fecha actual\"\r\n    );\r\n    return;\r\n  }\r\n\r\n  //Comparar la fecha dia/mes para saber si ya pasó o no en este año\r\n  let fecha = new Date(currentDate.getFullYear(), birthDay.getMonth(), birthDay.getDate(), birthDay.getHours())\r\n\r\nif (fecha <= currentDate)\r\n  resultado = currentDate.getFullYear() - birthDay.getFullYear();\r\nelse\r\n  resultado = currentDate.getFullYear() - birthDay.getFullYear() - 1; \r\n  console.log(`Han transcurrido ${resultado} años desde tu nacimiento`);\r\n}\r\n\r\n//Mostrar la fecha de nacimiento en 10 formatos diferentes\r\nfunction showDateInDifferentFormats(yourDate) {\r\n  console.log(\"\\n10 Formas de ver la fecha de nacimiento\");\r\n  console.log(\"1\", yourDate);\r\n  console.log(\"2\", yourDate.toDateString());\r\n  console.log(\"3\", yourDate.toISOString());\r\n  console.log(\"4\", yourDate.toUTCString());\r\n  console.log(\"5\", yourDate.toLocaleDateString());\r\n  console.log(\"6\", yourDate.toLocaleString());\r\n  console.log(\"7\", yourDate.getDay());\r\n  console.log(\"8\", yourDate.getHours());\r\n  console.log(\"9\", yourDate.toTimeString());\r\n  console.log(\r\n    \"10\",\r\n    `Año: ${yourDate.getFullYear()}, Mes: ${\r\n      yourDate.getMonth() + 1\r\n    }, Dia: ${yourDate.getDate()}`\r\n  );\r\n}\r\n\r\n//Ejecucion\r\nlet birthDay = new Date(1980, 5, 13, 6); //13  de Junio de 1980 a las 6am\r\ncalculateYearsSinceBirthday(birthDay);\r\nshowDateInDifferentFormats(birthDay);\r\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/javascript/eulogioep.js",
    "content": "// Ejercicio de manejo de fechas en JavaScript\n\n// PARTE 1: Crear variables de fecha y calcular años transcurridos\n\n// Creamos la fecha actual\nconst fechaActual = new Date();\n\n// Creamos una fecha de nacimiento (ejemplo)\nconst fechaNacimiento = new Date(1990, 4, 15, 14, 30, 0); // Mes 4 es Mayo (0-11)\n\n// Calculamos los años transcurridos\nconst añosTranscurridos = fechaActual.getFullYear() - fechaNacimiento.getFullYear();\n\n// Ajustamos si aún no hemos llegado al mes y día de nacimiento este año\nif (\n    fechaActual.getMonth() < fechaNacimiento.getMonth() || \n    (fechaActual.getMonth() === fechaNacimiento.getMonth() && \n     fechaActual.getDate() < fechaNacimiento.getDate())\n) {\n    añosTranscurridos--;\n}\n\nconsole.log(\"Fecha actual:\", fechaActual.toLocaleString());\nconsole.log(\"Fecha de nacimiento:\", fechaNacimiento.toLocaleString());\nconsole.log(\"Años transcurridos:\", añosTranscurridos);\n\n// PARTE 2: DIFICULTAD EXTRA - Formatear la fecha de 10 maneras diferentes\n\nconsole.log(\"\\nDIFERENTES FORMATOS DE FECHA:\");\n\n// 1. Día, mes y año\nconsole.log(\"1. Día, mes y año:\", fechaNacimiento.toLocaleDateString());\n\n// 2. Hora, minuto y segundo\nconsole.log(\"2. Hora, minuto y segundo:\", fechaNacimiento.toLocaleTimeString());\n\n// 3. Día del año\nconst inicioDeLAño = new Date(fechaNacimiento.getFullYear(), 0, 0);\nconst diff = fechaNacimiento - inicioDeLAño;\nconst unDiaEnMs = 1000 * 60 * 60 * 24;\nconst diaDelAño = Math.floor(diff / unDiaEnMs);\nconsole.log(\"3. Día del año:\", diaDelAño);\n\n// 4. Día de la semana\nconst diasSemana = ['Domingo', 'Lunes', 'Martes', 'Miércoles', 'Jueves', 'Viernes', 'Sábado'];\nconsole.log(\"4. Día de la semana:\", diasSemana[fechaNacimiento.getDay()]);\n\n// 5. Nombre del mes\nconst meses = ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'];\nconsole.log(\"5. Nombre del mes:\", meses[fechaNacimiento.getMonth()]);\n\n// 6. Formato largo personalizado\nconsole.log(\"6. Formato largo:\", `${diasSemana[fechaNacimiento.getDay()]}, ${fechaNacimiento.getDate()} de ${meses[fechaNacimiento.getMonth()]} de ${fechaNacimiento.getFullYear()}`);\n\n// 7. Formato ISO\nconsole.log(\"7. Formato ISO:\", fechaNacimiento.toISOString());\n\n// 8. Formato de 12 horas\nconsole.log(\"8. Formato 12 horas:\", fechaNacimiento.toLocaleTimeString('es-ES', { hour12: true }));\n\n// 9. Timestamp Unix\nconsole.log(\"9. Timestamp Unix:\", Math.floor(fechaNacimiento.getTime() / 1000));\n\n// 10. Trimestre del año\nconst trimestre = Math.floor(fechaNacimiento.getMonth() / 3) + 1;\nconsole.log(\"10. Trimestre del año:\", trimestre);\n\n// Función auxiliar para formatear números con ceros iniciales\nfunction padZero(num) {\n    return num.toString().padStart(2, '0');\n}"
  },
  {
    "path": "Roadmap/14 - FECHAS/javascript/garos01.js",
    "content": "// Obteniendo la fecha actual\nvar fechaActual = new Date();\n\n// Especificando la fecha de nacimiento\nvar fechaNacimiento = new Date(\"1994-09-11T13:40:03\");\n\n// Calculando la diferencia de tiempo en milisegundos\nvar diferenciaTiempo = fechaActual - fechaNacimiento;\n\n// Convirtiendo la diferencia de tiempo en años\nvar añosTranscurridos = Math.floor(\n  diferenciaTiempo / (1000 * 60 * 60 * 24 * 365)\n);\n\n// Imprimiendo el resultado\nconsole.log(\n  \"Han transcurrido \" +\n    añosTranscurridos +\n    \" años desde mi fecha de nacimiento.\"\n);\n\n// Ejercicio extra\n\nconsole.log(\n  \"1. Día, mes y año:\",\n  fechaNacimiento.getDate(),\n  fechaNacimiento.getMonth() + 1,\n  fechaNacimiento.getFullYear()\n);\nconsole.log(\n  \"2. Hora, minuto y segundo:\",\n  fechaNacimiento.getHours(),\n  fechaNacimiento.getMinutes(),\n  fechaNacimiento.getSeconds()\n);\nconsole.log(\n  \"3. Día de año:\",\n  Math.ceil(\n    (fechaNacimiento - new Date(fechaNacimiento.getFullYear(), 0, 0)) / 86400000\n  )\n);\nconsole.log(\"4. Día de la semana:\", fechaNacimiento.getDay());\nconsole.log(\"5. Nombre del mes:\", obtenerNombreMes(fechaNacimiento.getMonth()));\n\n// Función para obtener el nombre del mes\nfunction obtenerNombreMes(numeroMes) {\n  var meses = [\n    \"Enero\",\n    \"Febrero\",\n    \"Marzo\",\n    \"Abril\",\n    \"Mayo\",\n    \"Junio\",\n    \"Julio\",\n    \"Agosto\",\n    \"Septiembre\",\n    \"Octubre\",\n    \"Noviembre\",\n    \"Diciembre\",\n  ];\n  return meses[numeroMes];\n}\n\n// Formatos adicionales\nconsole.log(\"6. Día del mes:\", fechaNacimiento.getDate());\nconsole.log(\"7. Año:\", fechaNacimiento.getFullYear());\nconsole.log(\"8. Hora:\", fechaNacimiento.getHours());\nconsole.log(\"9. Minuto:\", fechaNacimiento.getMinutes());\nconsole.log(\"10. Segundo:\", fechaNacimiento.getSeconds());\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/javascript/giovanyosorio.js",
    "content": "/*\n * EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n */\n\n// Fecha actual\nconst fechaActual = new Date();\n\nconst fechaNacimiento = new Date(1995, 9, 3, 12, 0, 0);\n\n\nconst edad = Math.floor((fechaActual - fechaNacimiento) / (1000 * 60 * 60 * 24 * 365));\n\nconsole.log(`Mi edad es: ${edad} años.`);\n\n// DIFICULTAD EXTRA\nconsole.log(`Fecha de nacimiento: ${fechaNacimiento.toLocaleDateString()}`);\nconsole.log(`Hora de nacimiento: ${fechaNacimiento.toLocaleTimeString()}`);\nconsole.log(`Día del año: ${Math.floor((fechaNacimiento - new Date(fechaNacimiento.getFullYear(), 0, 0)) / (1000 * 60 * 60 * 24))}`); \nconsole.log(`Día de la semana: ${fechaNacimiento.toLocaleString('es-ES', { weekday: 'long' })}`); \nconsole.log(`Nombre del mes: ${fechaNacimiento.toLocaleString('es-ES', { month: 'long' })}`); \nconsole.log(`Año: ${fechaNacimiento.getFullYear()}`); \nconsole.log(`Mes (número): ${fechaNacimiento.getMonth() + 1}`); \nconsole.log(`Día del mes: ${fechaNacimiento.getDate()}`); \nconsole.log(`Hora: ${fechaNacimiento.getHours()}`);\nconsole.log(`Minuto: ${fechaNacimiento.getMinutes()}`); "
  },
  {
    "path": "Roadmap/14 - FECHAS/javascript/hectorio23.js",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23 \n\n\"use strict\";\n\n// npm install luxon\nconst { DateTime } = require('luxon');\n\n/**\n * EJERCICIO:\n * Crea dos variables utilizando los objetos de fecha de tu lenguaje:\n * - Una primera que represente la fecha y hora actual.\n * - Una segunda que represente tu fecha de nacimiento (puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n * \n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatea y muestra su resultado de\n * 10 maneras diferentes.\n */\n\n// Variables con la fecha actual y la fecha de nacimiento\nconst now = DateTime.now();\nconst birthDate = DateTime.fromObject({ year: 2004, month: 6, day: 28, hour: 12, minute: 59, second: 0 });\n\n// Calculando la diferencia en años\nconst diffYears = now.diff(birthDate, 'years').toObject().years;\n\n// Imprimiendo resultados del ejercicio básico\nconsole.log(`Fecha actual: ${now.toFormat('dd/MM/yyyy  hh:mm:ss a')}`);\nconsole.log(`Fecha de nacimiento: ${birthDate.toFormat('dd/MM/yyyy  hh:mm:ss a')}`);\nconsole.log(`Han pasado aproximadamente ${diffYears.toFixed(2)} años desde tu nacimiento.`);\n\n// Función para mostrar el resultado en 10 formas diferentes (ejercicio extra)\nfunction showFormattedBirthDate() {\n    console.log(\"\\n**** Formateando la fecha de nacimiento en 10 formas distintas ****\\n\");\n    console.log(`Fecha de nacimiento (dd/MM/yyyy): ${birthDate.toFormat('dd/MM/yyyy')}`);\n    console.log(`Fecha de nacimiento (MM-dd-yyyy): ${birthDate.toFormat('MM-dd-yyyy')}`);\n    console.log(`Fecha de nacimiento (dd-MM-yyyy): ${birthDate.toFormat('dd-MM-yyyy')}`);\n    console.log(`Fecha de nacimiento (yyyy/MM/dd): ${birthDate.toFormat('yyyy/MM/dd')}`);\n    console.log(`Fecha de nacimiento (dd/MM/yy): ${birthDate.toFormat('dd/MM/yy')}`);\n    console.log(`Fecha de nacimiento (yy/MM/dd): ${birthDate.toFormat('yy/MM/dd')}`);\n    console.log(`Fecha de nacimiento (hh:mm:ss): ${birthDate.toFormat('HH:mm:ss')}`);\n    console.log(`Fecha de nacimiento (hh:mm): ${birthDate.toFormat('HH:mm')}`);\n    console.log(`Fecha de nacimiento (mes dd, yyyy): ${birthDate.toFormat('MMMM dd, yyyy')}`);\n    console.log(`Fecha de nacimiento (dd de mes de yyyy): ${birthDate.toFormat('dd \\'de\\' MMMM \\'de\\' yyyy')}`);\n}\n\n// Mostrar el resultado en 10 formas diferentes\nshowFormattedBirthDate();\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n_______________________________________\n#14 FECHAS\n---------------------------------------\n* EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n*/\n// ________________________________________________________\nconst { DateTime } = require(\"luxon\");\n\nconst birthDate = DateTime.fromISO(\"1995-10-20T02:30:00\");\nconst currentDate = DateTime.now();\n\n// Diferencia precisa\nconst diff = currentDate.diff(birthDate, [\"years\", \"months\", \"days\"]);\n\nconsole.log(`\nJuanito tiene:\n${Math.floor(diff.years)} años,\n${Math.floor(diff.months)} meses y\n${Math.floor(diff.days)} días.\n`);\n\n// ________________________________________________________\n// DIFICULTAD EXTRA\n\nconsole.log(`\n    1. Predeterminado -> ${birthDate.toString()}\n    2. dd/mm/yyyy     -> ${birthDate.toFormat(\"dd/MM/yyyy\")}\n    3. dd-mm-yyyy     -> ${birthDate.toFormat(\"dd-MM-yyyy\")}\n    4. Nombre del mes -> ${birthDate.toFormat(\"MMMM\")}\n    5. Mes abreviado  -> ${birthDate.toFormat(\"MMM\")}\n    6. Nombre dia     -> ${birthDate.toFormat(\"cccc\")}\n    7. Dia abreviado  -> ${birthDate.toFormat(\"ccc\")}\n    8. Hora(12 horas) -> ${birthDate.toFormat(\"hh:mm:ss a\")}\n    9. Hora(24 horas) -> ${birthDate.toFormat(\"HH:mm:ss\")}\n    0. personalizado  -> Born on ${birthDate.toFormat(\"cccc, dd 'of' MMMM yyyy at hh:mm:ss a\")}\n`);\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/javascript/monicavaquerano.js",
    "content": "// 14 FECHAS\n// Monica Vaquerano\n//  https://monicavaquerano.dev\n\n\n/*\n * EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n *\n */\n\n// Now\nlet now = new Date();\n\n// Day of Birth\nlet dob = new Date(1988, 9, 9, 19, 33);\n\n// Difference\nlet dif = Math.abs(now - dob);\nlet days = dif / (1000 * 60 * 60 * 24);\nlet years = Math.floor(days / 365)\n\nconsole.log(`Difference (Age) => ${years}`)\n\n// Date Output - JavaScript Get Date Methods\n// In JavaScript, date objects are created with new Date().\n// new Date() returns a date object with the current date and time.\n\nconst MONTHS = [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"];\nconst WEEKDAYS = [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"];\n\nconsole.log(\"Now: weekday, full version =>\", WEEKDAYS[now.getDay()]);\nconsole.log(\"Now: year =>\", now.getFullYear())\nconsole.log(\"DOB: day =>\", dob.getDate())\nconsole.log(\"DOB: month =>\", dob.getMonth() + 1)\nconsole.log(\"DOB: month name =>\", MONTHS[dob.getMonth()])\nconsole.log(\"DOB: year =>\", dob.getFullYear())\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n */\n\nlet fullYear = dob.getFullYear();\t// Get year as a four digit number (yyyy)\nlet year = fullYear.toString().slice(2); // Get year as a two digit number (yy)\nlet month = dob.getMonth() + 1;\t// Get month as a number (0-11)\nlet monthName = MONTHS[dob.getMonth()];\t// Get month fullname\nlet date = dob.getDate();\t// Get day as a number (1-31)\nlet weekday = dob.getDay();\t// Get weekday as a number (0-6)\nlet weekdayName = WEEKDAYS[dob.getDay()];\t// Get weekday fullname\nlet hour = dob.getHours();\t// Get hour (0-23)\nlet minutes = dob.getMinutes(); // Get minute (0-59)\nminutes = minutes < 10 ? \"0\" + minutes : minutes;\t// Adds a \"0\" if minutes is less than 10\nlet seconds = dob.getSeconds();\t// Get second (0-59)\nseconds = seconds < 10 ? \"0\" + seconds : seconds;\t// Adds a \"0\" if seconds is less than 10\nlet milliseconds = dob.getMilliseconds(); // Get millisecond (0-999)\nlet time = dob.getTime(); // Get time (milliseconds since January 1, 1970)\n\n// # - Día, mes y año.\nconsole.log(\"Día, mes y año =>\\t\", `${date} ${monthName} ${year}`)\nconsole.log(\"Día, mes y año =>\\t\", `${date}/${month}/${year}`)\nconsole.log(\"Día, mes y año =>\\t\", `${date}/${month}/${fullYear}`)\n\n// # - Hora, minuto y segundo.\nconsole.log(\"Hora, minuto y segundo =>\\t\", `${hour}:${minutes}:${seconds}`)\n\nfunction getTimeAMPM(dt) {\n    let hours = dt.getHours();\n    let minutes = dt.getMinutes();\n    let seconds = dt.getSeconds();\n\n    // PM or AM?\n    let meridian = hours >= 12 ? \"PM\" : \"AM\";\n\n    // 12-Hours Format\n    hours = hours % 12;\n    hours = hours ? hours : 12;\n\n    // Adds a \"0\" if minutes or seconds are less than 10\n    minutes = minutes < 10 ? \"0\" + minutes : minutes;\n    seconds = seconds < 10 ? \"0\" + seconds : seconds;\n\n    let format = `${hours}:${minutes}:${seconds} ${meridian}`\n    return format\n}\n\nconsole.log(\"Hora, minuto y segundo =>\\t\", getTimeAMPM(dob))\n\n// # - Día de año.\nfunction getDayOfYear(dt) {\n    // First day of that year\n    let startOfYear = new Date(dt.getFullYear(), 0, 0);\n\n    // Difference between date and start of that year\n    let diff = dt - startOfYear;\n\n    // Divide the difference between the milliseconds of a day (86400000)\n    let dayOfYear = Math.floor(diff / 86400000);\n\n    return dayOfYear;\n}\n\nconsole.log(\"Día del año =>\\t\", getDayOfYear(dob))\n\n// # - Día de la semana.\nconsole.log(\"Día de la semana =>\\t\", weekday)\nconsole.log(\"Día de la semana =>\\t\", weekdayName.slice(0, 3))\nconsole.log(\"Día de la semana =>\\t\", weekdayName)\n\n\n// # - Nombre del mes.\nconsole.log(\"Nombre del mes =>\\t\", month)\nconsole.log(\"Nombre del mes =>\\t\", monthName.slice(0, 3))\nconsole.log(\"Nombre del mes =>\\t\", monthName)\n\n// # - (lo que se te ocurra...)\nconsole.log(dob.toJSON()); // Returns the date as a string, formatted as a JSON date\nconsole.log(dob.toString()); // Converts a Date object to a string\nconsole.log(dob.toLocaleString()); // Converts a Date object to a string, using locale conventions\nconsole.log(dob.toDateString()); // Converts the date portion of a Date object into a readable string\nconsole.log(dob.toUTCString()); // Converts a Date object to a string, according to universal time\nconsole.log(dob.toISOString()); // Returns the date as a string, using the ISO standard\n\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/javascript/nlarrea.js",
    "content": "/*\n * EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n */\n\nconst currentDate = new Date();\nconst bdayDate = new Date('1998-06-29 09:25:00');\n\nconst diffYears = (dateOne, dateTwo) => {\n    let newestYear, oldestYear;\n    if (dateOne > dateTwo) {\n        newestYear = dateOne.getFullYear();\n        oldestYear = dateTwo.getFullYear();\n    } else {\n        newestYear = dateTwo.getFullYear();\n        oldestYear = dateOne.getFullYear();\n    }\n\n    return newestYear - oldestYear;\n};\nconsole.log(diffYears(currentDate, bdayDate));\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n */\n\nconst weekDays = {\n    0: 'Sunday',\n    1: 'Monday',\n    2: 'Tuesday',\n    3: 'Wednesday',\n    4: 'Thursday',\n    5: 'Friday',\n    6: 'Saturday'\n};\n\nconst months = {\n    0: 'January',\n    1: 'February',\n    2: 'March',\n    3: 'April',\n    4: 'May',\n    5: 'June',\n    6: 'July',\n    7: 'August',\n    8: 'September',\n    9: 'October',\n    10: 'November',\n    11: 'December'\n};\n\nconsole.log(`1. ${bdayDate.toDateString()}`);\nconsole.log(`2. ${bdayDate.toLocaleDateString()}`);\nconsole.log(`3. ${bdayDate.toLocaleString()}`);\nconsole.log(`4. ${bdayDate.getHours()}:${bdayDate.getMinutes()}:${bdayDate.getSeconds()}`);\nconsole.log(`5. ${bdayDate.toLocaleTimeString()}`);\nconsole.log(`6. ${bdayDate.getDay()}`);\nconsole.log(`7. ${weekDays[bdayDate.getDay()]}`);\nconsole.log(`8. ${bdayDate.getMonth() + 1}`);\nconsole.log(`9. ${months[bdayDate.getMonth()]}`);\nconsole.log(`10. ${bdayDate.toJSON()}`);"
  },
  {
    "path": "Roadmap/14 - FECHAS/javascript/parababire.js",
    "content": "const birthDate = new Date(1979, 8, 16, 7, 30, 15);\nconst currentDate = new Date();\n\n//Retorna edad\nconst añosTranscurridos = currentDate.getFullYear() - birthDate.getFullYear();\n\n//Retorna fecha de nacimiento\nconst diaMesAñoNacimiento = birthDate.toLocaleDateString('es-es', {day: 'numeric', month: 'numeric', year: 'numeric'});\n\n//Retorna hora del nacimiento\nconst horaMinutoSegundoNacimiento = birthDate.toLocaleTimeString('es-es', {hour: 'numeric', minute: 'numeric', second: 'numeric'});\n\n//Retorna año de nacimiento\nconst añoNacimiento = birthDate.getFullYear();\n\n//Retorna día de la semana del nacimiento\nconst diaNacimiento = birthDate.toLocaleDateString('es-es', {weekday: 'long'});\n\n//Retorna mes del año del nacimiento\nconst mesNacimiento = birthDate.toLocaleDateString('es-es', {month: 'long'});\n\n//Retorna fecha y hora\nconst horaLocal = birthDate.toLocaleString();\n\n//Día del año\nconst inicioAño = new Date(birthDate.getFullYear(), 0, 0);\nconst diferencia = birthDate - inicioAño;\nconst dia = 86400000;\nconst diaAño = Math.floor(diferencia / dia);\n\n\nconsole.log(añosTranscurridos);\nconsole.log(diaMesAñoNacimiento);\nconsole.log(horaMinutoSegundoNacimiento);\nconsole.log(añoNacimiento);\nconsole.log(diaNacimiento);\nconsole.log(birthDate.getDate());\nconsole.log(mesNacimiento);\nconsole.log(horaLocal);\nconsole.log(diaAño);\nconsole.log(birthDate.toISOString());\nconsole.log(birthDate.toUTCString());"
  },
  {
    "path": "Roadmap/14 - FECHAS/javascript/pedamoci.js",
    "content": "let date = new Date\ndate = date.toLocaleString(\"es-AR\", { hour12: false})\n\nlet birthDate = new Date(\"July 03, 2002 11:30:00\")\n\nconsole.log(parseInt(date.match(/\\W(\\d+)\\,/)[1]) - birthDate.getFullYear())\n\n// ----------------------------------------- DIFICULTAD EXTRA -----------------------------------------\nconst nowDate = new Date\n// recupero año, mes, dia, hora, minutos, segundo, milisegundo de la fecha actual\nconst nowYear = nowDate.getFullYear(); const nowMonth = nowDate.getMonth(); const nowDay = nowDate.getDate();\nlet birthDatePassed = (nowMonth - birthDate.getMonth() > 0)\nlet years = nowYear - birthDate.getFullYear()\nlet months = nowMonth - birthDate.getMonth()\nlet monthDays = (30.41 * nowMonth) + nowDay\n\nconsole.log(`Han pasado ${birthDatePassed ? (years) * 12 + (months) \n                                          : (years - 1) * 12 + nowMonth} meses desde que nací`)\n\nconsole.log(`Han pasado ${birthDatePassed ? (years) * 12 * 4 + 4 * (months) + Math.floor(nowDay / 7) \n                                          : (years - 1) * 12 * 4 +  4 * nowMonth + Math.floor(nowDay / 7)} semanas desde que nací`)\n\nconsole.log(`Han pasado ${birthDatePassed ? Math.floor((years) * 12 * 30.41 + 30.41 * (months) + nowDay) \n                                          : Math.floor((years - 1) * 12 * 30.41 + monthDays)} días desde que nací`)\n\nconsole.log(`Han pasado ${birthDatePassed ? Math.floor(((years) * 12 * 30.41 + 30.41 * (months) + nowDay) * 24) \n                                          : Math.floor(((years - 1) * 12 * 30.41 + monthDays) * 24)} horas desde que nací`)\n\nconsole.log(`Han pasado ${birthDatePassed ? Math.floor(((years) * 12 * 30.41 + 30.41 * (months) + nowDay) * 24 * 60)\n                                          : Math.floor(((years - 1) * 12 * 30.41 + monthDays) * 24 * 60)} minutos desde que nací`)\n\nconsole.log(`Han pasado ${birthDatePassed ? Math.floor(((years) * 12 * 30.41 + 30.41 * (months) + nowDay) * 24 * 60 * 60)\n                                          : Math.floor(((years - 1) * 12 * 30.41 + monthDays) * 24 * 60 * 60)} segundos desde que nací`)\n\nconsole.log(`Han pasado ${birthDatePassed ? Math.floor(((years) * 12 * 30.41 + 30.41 * (months) + nowDay) * 24 * 60 * 60 * 100)\n                                          : Math.floor(((years - 1) * 12 * 30.41 + monthDays) * 24 * 60 * 60 * 100)} milisegundos desde que nací`)\n\nconsole.log(`Una persona pudo recorre ${birthDatePassed ? Math.floor(((years) * 12 * 30.41 + 30.41 * (months) + nowDay) * 24) * 5 \n                                                        : Math.floor(((years - 1) * 12 * 30.41 + monthDays) * 24) * 5} kilometros desde que nací`)\n\nconsole.log(`Una persona pudo haber dado ${birthDatePassed ? ((Math.floor(((years) * 12 * 30.41 + 30.41 * (months) + nowDay) * 24) * 5) / 12728).toFixed(2)\n                                                            : ((Math.floor(((years - 1) * 12 * 30.41 + monthDays) * 24) * 5) / 12728).toFixed(2)} vueltas a la tierra desde que nací`)\n\n\nconsole.log(`Una totuga pudo haber dado ${birthDatePassed ? ((Math.floor(((years) * 12 * 30.41 + 30.41 * (months) + nowDay) * 24) * 0.29) / 12728).toFixed(2)\n                                                          : ((Math.floor(((years - 1) * 12 * 30.41 + monthDays) * 24) * 0.29) / 12728).toFixed(2)} vueltas a la tierra desde que nací`)"
  },
  {
    "path": "Roadmap/14 - FECHAS/javascript/raulG91.js",
    "content": "\nlet birth_day = new Date(1991,8,11,15,0,0,0);\nlet now = new Date();\nconsole.log(birth_day);\nconsole.log(now);\n\nlet dif = now.getFullYear() - birth_day.getFullYear();\nconsole.log(`Diference in year is ${dif}`);\n\n/*Extra*/\n\n//Day of the week\nconst formatter_day = new Intl.DateTimeFormat('en', { weekday: 'long' });\nday_name = formatter_day.format(birth_day);\nconsole.log(`Day of the week for birth date was: ${day_name}`);\n\n//Name of the month\nconst formatter = new Intl.DateTimeFormat('en', { month: 'long' });\nmonth_name = formatter.format(birth_day);\nconsole.log(`Month for birth date was ${month_name}`);\n\n//Format date Spanish format\nconsole.log('Formatting date in Spanish version: ',new Intl.DateTimeFormat('es').format(birth_day));\n\n//Format date USA format\nconsole.log('Formatting date in USA version: ',new Intl.DateTimeFormat('en-US').format(birth_day));\n\n// Format date HH:MM:SS\nconsole.log(`Formating HH:MM:SS: ${birth_day.getHours()}:${birth_day.getMinutes()}:${birth_day.getSeconds()}`)\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/javascript/seandsun.js",
    "content": "// <-------------- Objeto Date() -------------->\n\nconst fechaActual = new Date()\n\nconst fechaDeNacimiento = new Date(1998, 0, 12, 3, 23, 8)\n\nconst diferenciaMilisegundos = fechaActual - fechaDeNacimiento\nconst diferenciaAnios = Math.floor(diferenciaMilisegundos / (1000 * 60 * 60 * 24 * 365))\n\nconsole.log(`Entre ambas fechas han transcurrido ${diferenciaAnios} años.`)\n\n\n// <-------------- Extra -------------->\n\nconst semana = ['Domingo', 'Lunes', 'Martes', 'Miercoles', 'Jueves', 'Viernes', 'Sabado']\nconst meses = ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre']\n\nlet anio = fechaDeNacimiento.getFullYear()\nlet mes = fechaDeNacimiento.getMonth()\nlet mes_formateado = ('0' + (mes + 1)).slice(-2)\nlet dia = fechaDeNacimiento.getDate()\nlet diaSemana = fechaDeNacimiento.getDay()\nlet horas = fechaDeNacimiento.getHours()\nhoras = ('0' + horas).slice(-2)\nlet minutos = fechaDeNacimiento.getMinutes()\nminutos = ('0' + minutos).slice(-2)\nlet segundos = fechaDeNacimiento.getSeconds()\nsegundos = ('0' + segundos).slice(-2)\n\nconsole.log(`${anio}-${mes_formateado}-${dia}`) // 1998-01-12\nconsole.log(`${meses[mes]} ${dia} de ${anio}`) // Enero 12 de 1998\nconsole.log(`${horas} horas / ${minutos} minutos / ${segundos} segundos`) // 03 horas / 23 minutos / 08 segundos\nconsole.log(`${horas}:${minutos}:${segundos}`) // 03:23:08\nconsole.log(`${semana[diaSemana]} de ${anio}`) // Lunes de 1998\nconsole.log(`${meses[mes]}`) // Enero\nconsole.log(`${semana[diaSemana]} ${dia} de ${meses[mes]} de ${anio}`) // Lunes 12 de Enero de 1998"
  },
  {
    "path": "Roadmap/14 - FECHAS/javascript/ssanjua.js",
    "content": "\nconst fechaActual = new Date();\nconst fechaNacimiento = new Date(\"1991-04-15T16:30:00\"); \n\nconst diferenciaEnMilisegundos = fechaActual - fechaNacimiento;\nconst diferenciaEnAños = diferenciaEnMilisegundos / (1000 * 60 * 60 * 24 * 365.25); \n\n// Día, mes y año\nconsole.log(`mi nacimiento fue: ${fechaNacimiento.getDate()}/${fechaNacimiento.getMonth() + 1}/${fechaNacimiento.getFullYear()}`);\n\n// Hora, minuto y segundo\nconsole.log(`la hora de mi nacimiento fue: ${fechaNacimiento.getHours()}:${fechaNacimiento.getMinutes()}:${fechaNacimiento.getSeconds()}`);\n\n// Día del año\nconst inicioAño = new Date(fechaNacimiento.getFullYear(), 0, 0);\nconst diferencia = fechaNacimiento - inicioAño;\nconst unDia = 1000 * 60 * 60 * 24;\nconst diaDelAño = Math.floor(diferencia / unDia);\nconsole.log(`pasaron ${diaDelAño} del año 1991 y nací`);\n\n// Día de la semana\nconst diasDeLaSemana = [\"Domingo\", \"Lunes\", \"Martes\", \"Miércoles\", \"Jueves\", \"Viernes\", \"Sábado\"];\nconsole.log(diasDeLaSemana[fechaNacimiento.getDay()]);\n\n// Nombre del mes\nconst mesesDelAño = [\"Enero\", \"Febrero\", \"Marzo\", \"Abril\", \"Mayo\", \"Junio\", \"Julio\", \"Agosto\", \"Septiembre\", \"Octubre\", \"Noviembre\", \"Diciembre\"];\nconsole.log(`nací un ${diasDeLaSemana[fechaNacimiento.getDay()]}.`);\n\n// - Año en formato de dos dígitos\nconsole.log(`soy modelo ${fechaNacimiento.getFullYear().toString().slice(-2)}`);\n\n// - Fecha en formato ISO\nconsole.log(`formato ISO: ${fechaNacimiento.toISOString()}`);\n\n// - Fecha larga\nconsole.log(fechaNacimiento.toLocaleDateString(\"es-ES\", {weekday: 'long', year: 'numeric', month: 'long', day: 'numeric'}));\n\n// - Hora en formato 12 horas\nconst horas = fechaNacimiento.getHours();\nconst minutos = fechaNacimiento.getMinutes();\nconsole.log(`${horas % 12 || 12}:${minutos < 10 ? '0' + minutos : minutos} ${horas < 12 ? 'AM' : 'PM'}`);\n\n// - Marca de tiempo UNIX\nconsole.log(`desde el 1 de enero de 1970 pasaron ${Math.floor(fechaNacimiento.getTime() / 1000)} segundos`);"
  },
  {
    "path": "Roadmap/14 - FECHAS/javascript/victor-Casta.js",
    "content": "/*\n  * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n  * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n  * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n  * Calcula cuántos años han transcurrido entre ambas fechas.\n*/\n\n// Obtenemos la fecha actual y la fecha de nacimiento usando el objeto Date proporcionado por JavaScript\nconst actualDate = new Date(); // Fecha actual\nconst birthday = new Date('2002-12-17'); // Fecha de nacimiento\n\n// Calculamos la edad restando el año de la fecha de nacimiento del año de la fecha actual\nlet age = actualDate.getFullYear() - birthday.getFullYear();\n\n// Ajustamos la edad si el cumpleaños de este año aún no ha ocurrido\n// Calculamos la diferencia de meses entre la fecha actual y la fecha de nacimiento\nconst monthDiff = actualDate.getMonth() - birthday.getMonth();\n\n// Si la diferencia de meses es negativa, significa que aún no ha pasado el cumpleaños este año\n// Si la diferencia de meses es cero, verificamos si el día del mes actual es menor que el día del cumpleaños\n// Si cualquiera de las condiciones es verdadera, restamos 1 de la edad calculada previamente\nif (monthDiff < 0 || (monthDiff === 0 && actualDate.getDate() < birthday.getDate())) {\n  age--;\n}\n\nconsole.log(`Han transcurrido: ${age} años, desde ${birthday.getFullYear()} hasta ${actualDate.getFullYear()}`);\n\n\n/*\n  * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n  * 10 maneras diferentes. Por ejemplo:\n  * - Día, mes y año.\n  * - Hora, minuto y segundo.\n  * - Día de año.\n  * - Día de la semana.\n  * - Nombre del mes.\n  * (lo que se te ocurra...)\n*/\n\n// 1. DD/MM/YYYY\nconst format1 = `${String(birthday.getDate() + 1).padStart(2, '0')}/${String(birthday.getMonth() + 1).padStart(2, '0')}/${birthday.getFullYear()}`;\nconsole.log(`DD/MM/YYYY: ${format1}`);\n\n// 2. HH:MM:SS (hora, minuto y segundo)\nconst format2 = `${String(birthday.getHours()).padStart(2, '0')}:${String(birthday.getMinutes()).padStart(2, '0')}:${String(birthday.getSeconds()).padStart(2, '0')}`;\nconsole.log(`HH:MM:SS: ${format2}`);\n\n// 3. YYYY-MM-DD (formato ISO)\nconst format3 = birthday.toISOString().split('T')[0];\nconsole.log(`YYYY-MM-DD: ${format3}`);\n\n// 4. Día de la semana\nconst daysOfWeek = ['Domingo', 'Lunes', 'Martes', 'Miércoles', 'Jueves', 'Viernes', 'Sábado'];\nconst format4 = daysOfWeek[birthday.getDay() + 1];\nconsole.log(`Día de la semana: ${format4}`);\n\n// 5. Nombre del mes\nconst monthsOfYear = ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'];\nconst format5 = monthsOfYear[birthday.getMonth()];\nconsole.log(`Nombre del mes: ${format5}`);\n\n// 6. Día del año\nconst startOfYear = new Date(birthday.getFullYear(), 0, 1);\nconst dayOfYear = Math.floor((birthday - startOfYear) / (1000 * 60 * 60 * 24)) + 1;\nconst format6 = dayOfYear;\nconsole.log(`Día del año: ${format6}`);\n\n// 7. MM/DD/YYYY\nconst format7 = `${String(birthday.getMonth() + 1).padStart(2, '0')}/${String(birthday.getDate() + 1).padStart(2, '0')}/${birthday.getFullYear()}`;\nconsole.log(`MM/DD/YYYY: ${format7}`);\n\n// 8. DD Month YYYY\nconst format8 = `${String(birthday.getDate() + 1).padStart(2, '0')} ${monthsOfYear[birthday.getMonth()]} ${birthday.getFullYear()}`;\nconsole.log(`DD Month YYYY: ${format8}`);\n\n// 9. Día, Nombre del mes, Año\nconst format9 = `${daysOfWeek[birthday.getDay() + 1]}, ${birthday.getDate() + 1} de ${monthsOfYear[birthday.getMonth()]} de ${birthday.getFullYear()}`;\nconsole.log(`Día, Nombre del mes, Año: ${format9}`);\n\n// 10. Timestamp\nconst format10 = birthday.getTime();\nconsole.log(`Timestamp: ${format10}`);\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/javascript/wapastorv.js",
    "content": "/*\n * EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n */\n\nconst dateNow = new Date();\nconsole.log(\"Fecha Actual: \",dateNow);\n\nconst dateOfBirth = new Date(1993, 6, 21, 10, 30, 0, 0);\nconsole.log(\"Fecha de Nacimiento: \",dateOfBirth)\n\n\nconst añosTranscurridos = dateNow.getFullYear() - dateOfBirth.getFullYear();\n/*const mesesTranscurridos = dateNow.getMonth() - dateOfBrith.getMonth();\nconst diasTranscurridos = dateNow.getDate() - dateOfBrith.getDate();\nconst horasTranscurridas = dateNow.getHours() - dateOfBrith.getHours();\nconst minutosTranscurridos = dateNow.getMinutes() - dateOfBrith.getMinutes();\nconst segundosTranscurridos = dateNow.getSeconds() - dateOfBrith.getSeconds();*/\n\nconsole.log(\"Años Transcurridos: \",añosTranscurridos);\n/*console.log(\"Meses Transcurridos: \",mesesTranscurridos);\nconsole.log(\"Días Transcurridos: \",diasTranscurridos);\nconsole.log(\"Horas Transcurridas: \",horasTranscurridas);\nconsole.log(\"Minutos Transcurridos: \",minutosTranscurridos);\nconsole.log(\"Segundos Transcurridos: \",segundosTranscurridos);*/\n\n\n\n/*console.log(\"Datos de la fecha actual:\")\nconsole.log(\"Año:\", dateNow.getFullYear());      // Año actual\nconsole.log(\"Mes:\", dateNow.getMonth());         // Mes (0 a 11)\nconsole.log(\"Día:\", dateNow.getDate());          // Día del mes\nconsole.log(\"Día de la semana:\", dateNow.getDay());  // Día de la semana (0 a 6)\nconsole.log(\"Hora:\", dateNow.getHours());        // Hora\nconsole.log(\"Minutos:\", dateNow.getMinutes());   // Minutos\nconsole.log(\"Segundos:\", dateNow.getSeconds());  // Segundos\nconsole.log(\"Milisegundos:\", dateNow.getMilliseconds());  // Milisegundos\nconsole.log(\"Timestamp:\", dateNow.getTime());    // Milisegundos desde 1970\n\nconsole.log(\"Datos de la fecha de nacimiento:\")\nconsole.log(\"Año:\", dateOfBrith.getFullYear());      // Año actual\nconsole.log(\"Mes:\", dateOfBrith.getMonth());         // Mes (0 a 11)\nconsole.log(\"Día:\", dateOfBrith.getDate());          // Día del mes\nconsole.log(\"Día de la semana:\", dateOfBrith.getDay());  // Día de la semana (0 a 6)\nconsole.log(\"Hora:\", dateOfBrith.getHours());        // Hora\nconsole.log(\"Minutos:\", dateOfBrith.getMinutes());   // Minutos\nconsole.log(\"Segundos:\", dateOfBrith.getSeconds());  // Segundos\nconsole.log(\"Milisegundos:\", dateOfBrith.getMilliseconds());  // Milisegundos\nconsole.log(\"Timestamp:\", dateOfBrith.getTime());    // Milisegundos desde 1970\n\n\nconst fechaModificable = new Date();\n\nfechaModificable.setFullYear(2025);       // Cambiar el año\nfechaModificable.setMonth(5);             // Cambiar el mes (junio)\nfechaModificable.setDate(15);             // Cambiar el día\nfechaModificable.setHours(12);            // Cambiar la hora\nfechaModificable.setMinutes(45);          // Cambiar los minutos\nfechaModificable.setSeconds(30);          // Cambiar los segundos\n\nconsole.log(\"Fecha Modificada:\", fechaModificable);\n\n\nconst fechaFormateada = new Date();\n\nconsole.log(\"ISO:\", fechaFormateada.toISOString());  // Formato ISO\nconsole.log(\"Fecha Local:\", fechaFormateada.toLocaleDateString());  // Fecha local\nconsole.log(\"Hora Local:\", fechaFormateada.toLocaleTimeString());  // Hora local\nconsole.log(\"Fecha y Hora Local:\", fechaFormateada.toLocaleString());  // Todo en uno*/\n\n\n//Formato ISO (Internacional)\nconsole.log(\"ISO:\", dateOfBirth.toISOString()); \n// Resultado: 1993-07-21T10:30:00.000Z\n\n//Fecha Local (Idioma del Sistema)\nconsole.log(\"Fecha Local:\", dateOfBirth.toLocaleDateString()); \n\n//Hora Local\nconsole.log(\"Hora Local:\", dateOfBirth.toLocaleTimeString()); \n\n//Fecha y Hora Local\nconsole.log(\"Fecha y Hora Local:\", dateOfBirth.toLocaleString());\n\n//Fecha en Formato Personalizado (Manual)\nconst dia = dateOfBirth.getDate();\nconst mes = dateOfBirth.getMonth() + 1; \nconst anio = dateOfBirth.getFullYear();\nconsole.log(`Fecha Personalizada: ${dia}-${mes}-${anio}`); \n\n//Día de la Semana y Fecha Completa (en Inglés)\nconst opciones = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' };\nconsole.log(\"Día y Fecha Completa:\", dateOfBirth.toLocaleDateString('en-US', opciones));\n\n//Solo el Mes y el Año\nconsole.log(\"Mes y Año:\", `${dateOfBirth.getMonth() + 1}/${dateOfBirth.getFullYear()}`); \n\n//Formato UTC\nconsole.log(\"UTC:\", dateOfBirth.toUTCString()); \n\n//Timestamp (Milisegundos desde 1970)\nconsole.log(\"Timestamp:\", dateOfBirth.getTime()); \n\n//Día, Mes y Año en Cadena de Texto\nconst nombresMeses = [\"Enero\", \"Febrero\", \"Marzo\", \"Abril\", \"Mayo\", \"Junio\", \"Julio\", \"Agosto\", \"Septiembre\", \"Octubre\", \"Noviembre\", \"Diciembre\"];\nconsole.log(`Día, Mes y Año en Texto: ${dia} de ${nombresMeses[mes - 1]} de ${anio}`); \n"
  },
  {
    "path": "Roadmap/14 - FECHAS/kotlin/blackriper.kt",
    "content": "import java.text.SimpleDateFormat\r\nimport java.time.LocalDateTime\r\nimport java.time.ZoneId\r\nimport java.time.format.DateTimeFormatter\r\nimport java.time.temporal.ChronoUnit\r\nimport java.util.*\r\nimport java.util.concurrent.TimeUnit\r\n\r\n/*\r\n En kotlin al igual que java se pueden utilizar  tres objetos principales para\r\n trabajar con fechas y tiempo:\r\n\r\n - Date\r\n - Calendar\r\n - LocalDateTime\r\n\r\n*/\r\n\r\n\r\n\r\n\r\nfun exampleWithDate(bornDay : Date) {\r\n    val formatter = SimpleDateFormat(\"dd/MM/yyyy hh:mm:ss\")\r\n    println(\"working with date\")\r\n    val today = Date()\r\n    println(\"Today is ${formatter.format(today)}\")\r\n    println(\"birthday  is ${formatter.format(bornDay)}\")\r\n\r\n    // obtener la diferencia de tiempo entre dos fechas\r\n    val diff = today.time - bornDay.time\r\n    val years = TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS) / 365\r\n    println(\"I am $years years old\")\r\n}\r\n\r\nfun exampleWithCalendar(bornDay: Date) {\r\n    println(\"working with calendar\")\r\n    val today = Calendar.getInstance()\r\n    val born = Calendar.getInstance().apply { this.time = bornDay }\r\n    val years = today.get(Calendar.YEAR) - born.get(Calendar.YEAR)\r\n    println(\"I am $years years old\")\r\n}\r\n\r\nfun exampleWithLocalDateTime(bornDay: Date) {\r\n    println(\"working with LocalDateTime\")\r\n    val today = LocalDateTime.now()\r\n    val born = LocalDateTime.ofInstant(bornDay.toInstant(), ZoneId.systemDefault())\r\n    val years = ChronoUnit.YEARS.between(born, today)\r\n    println(\"I am $years years old\")\r\n}\r\n\r\nfun formatWithDateAndCalendar(bornDay: Date) {\r\n    val formatter = SimpleDateFormat(\"dd/MM/yyyy\")\r\n    println(formatter.format(bornDay))\r\n    formatter.applyPattern(\"HH:mm:ss\")\r\n    println(formatter.format(bornDay))\r\n\r\n    val born = Calendar.getInstance().apply { this.time = bornDay }\r\n    println(\"day of year ${born.get(Calendar.DAY_OF_YEAR)}\")\r\n    println(\"day of week ${born.get(Calendar.DAY_OF_WEEK)}\")\r\n    println(\"name of month ${born.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.getDefault())}\")\r\n\r\n}\r\nfun formatWithLocalDateTime(bornDay: Date) {\r\n    val formatter = DateTimeFormatter.ofPattern(\"dd/MM/yyyy \")\r\n    val born = LocalDateTime.ofInstant(bornDay.toInstant(), ZoneId.systemDefault())\r\n    println(formatter.format(born))\r\n    val formatter2 = DateTimeFormatter.ofPattern(\"HH:mm:ss\")\r\n    println(formatter2.format(born))\r\n\r\n    println(\"day of year ${born.dayOfYear}\")\r\n    println(\"day of week ${born.dayOfWeek}\")\r\n    println(\"name of month ${born.month}\")\r\n}\r\n\r\n\r\nfun main() {\r\n // dar formato ala fecha en este caso  dia , mes , año y hora con minuto y segundo\r\n val formatter = SimpleDateFormat(\"dd/MM/yyyy HH:mm:ss\")\r\n val birthday= \"20/05/1994 15:30:00\"\r\n    // convertir fecha string a Date\r\n val bornDay = formatter.parse(birthday)\r\n exampleWithDate(bornDay)\r\n exampleWithCalendar(bornDay)\r\n exampleWithLocalDateTime(bornDay)\r\n formatWithDateAndCalendar(bornDay)\r\n formatWithLocalDateTime(bornDay)\r\n}"
  },
  {
    "path": "Roadmap/14 - FECHAS/kotlin/eulogioep.kt",
    "content": "import java.time.*\nimport java.time.format.DateTimeFormatter\nimport java.time.temporal.ChronoUnit\n\nfun main() {\n    // Fecha actual\n    val fechaActual = LocalDateTime.now()\n    \n    // Fecha de nacimiento (ejemplo)\n    val fechaNacimiento = LocalDateTime.of(1990, 5, 15, 14, 30, 0)\n    \n    // Cálculo de años transcurridos\n    val añosTranscurridos = ChronoUnit.YEARS.between(fechaNacimiento, fechaActual)\n    \n    println(\"Años transcurridos: $añosTranscurridos\")\n    \n    // DIFICULTAD EXTRA: Formatear la fecha de nacimiento de 10 maneras diferentes\n    val formatters = listOf(\n        DateTimeFormatter.ofPattern(\"dd/MM/yyyy\"),\n        DateTimeFormatter.ofPattern(\"HH:mm:ss\"),\n        DateTimeFormatter.ofPattern(\"D\"),\n        DateTimeFormatter.ofPattern(\"EEEE\"),\n        DateTimeFormatter.ofPattern(\"MMMM\"),\n        DateTimeFormatter.ofPattern(\"yyyy 'semana' w\"),\n        DateTimeFormatter.ofPattern(\"dd MMMM yyyy, HH:mm\"),\n        DateTimeFormatter.ISO_LOCAL_DATE_TIME,\n        DateTimeFormatter.ofPattern(\"yyyy-MM-dd'T'HH:mm:ss\"),\n        DateTimeFormatter.ofPattern(\"EEEE, MMMM d, yyyy 'a las' hh:mm a\")\n    )\n    \n    println(\"\\nFormatos de fecha de nacimiento:\")\n    formatters.forEachIndexed { index, formatter ->\n        println(\"${index + 1}. ${fechaNacimiento.format(formatter)}\")\n    }\n}"
  },
  {
    "path": "Roadmap/14 - FECHAS/ocaml/luishendrix92.ml",
    "content": "open Printf\nopen Core\n\n(*****************************************************************************)\n(*                                                                           *)\n(*                        Working with Dates and Time                        *)\n(*                                                                           *)\n(*  The standard library does not provide a Date or DateTime module but it   *)\n(*  leverages the Unix module to work with dates and timestamps. The [Unix]  *)\n(*  module provides a set of time functions and a specific record type that  *)\n(*  represents wallclock and calendar time (it's called [tm]).               *)\n(*                                                                           *)\n(*  Thankfully, the popular library [Core] offers two different modules:     *)\n(*  1. [Date]: Type and functions to work with calendar dates.               *)\n(*  2. [Time_float]: Type and functions to work with raw time. It also has   *)\n(*     a submodule [Zone] needed for when a function requires a timezone     *)\n(*     argument. The most used time zone is [Core.Time_float.Zone.utc].      *)\n(*                                                                           *)\n(*****************************************************************************)\n\nmodule Exercise = struct\n  let my_birthday =\n    let date = Date.create_exn ~y:1992 ~m:Month.Apr ~d:9 in\n    let time = Time_float.Ofday.of_string \"10:36:15\" in\n    Time_float.of_date_ofday ~zone:Time_float.Zone.utc date time\n  ;;\n\n  let today = Time_float.now ()\n\n  let run () =\n    let living_days =\n      Time_float.Span.to_day @@ Time_float.abs_diff today my_birthday\n    in\n    let living_years = living_days /. 365.0 in\n    printf \"%f years have passed since I was born.\\n\" living_years\n  ;;\nend\n\n(*****************************************************************************)\n(*                                                                           *)\n(*                        Dificultad Extra (Opcional)                        *)\n(*                                                                           *)\n(*  Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado  *)\n(*  de 10 maneras diferentes. Por ejemplo:                                   *)\n(*                                                                           *)\n(*  - Día, mes y año.                                                        *)\n(*  - Hora, minuto y segundo.                                                *)\n(*  - Día del año.                                                           *)\n(*  - Día de la semana.                                                      *)\n(*  - Nombre del mes.                                                        *)\n(*  (lo que se te ocurra...)                                                 *)\n(*                                                                           *)\n(*****************************************************************************)\n\nmodule Challenge = struct\n  let pst = Time_float.Zone.of_utc_offset ~hours:(-8)\n  let my_birthday = Exercise.my_birthday\n  let bday_as_date = Time_float.to_date ~zone:pst my_birthday\n\n  let run () =\n    print_endline \"My birthday formatted in 10 different times:\";\n    printf \"%s\\n\" @@ Time_float.to_string_utc my_birthday;\n    printf \"%s\\n\" @@ Time_float.to_sec_string_with_zone ~zone:pst my_birthday;\n    printf \"%s\\n\" @@ Time_float.to_filename_string ~zone:pst my_birthday;\n    printf \"%s\\n\" @@ Date.to_string_american bday_as_date;\n    printf \"%s\\n\" @@ Date.to_string_iso8601_basic bday_as_date;\n    printf \"Day %d\\n\" @@ Date.day bday_as_date;\n    printf \"%s\\n\" (Date.day_of_week bday_as_date |> Day_of_week.to_string_long);\n    printf \"%s\\n\" (Date.month bday_as_date |> Month.to_string);\n    printf\n      \"Unix Timestamp (ms): %d\\n\"\n      (Time_float.to_span_since_epoch my_birthday\n       |> Time_float.Span.to_sec\n       |> int_of_float);\n    Time_float.to_string_abs_parts ~zone:pst my_birthday\n    |> List.iter ~f:print_endline\n  ;;\nend\n\nlet _ =\n  Exercise.run ();\n  Challenge.run ()\n;;\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/php/eulogioep.php",
    "content": "<?php\n/**\n * Ejercicio de manejo de fechas en PHP\n * Este script demuestra diferentes operaciones y formatos con fechas\n */\n\n// PARTE 1: Crear variables de fecha y calcular años transcurridos\n\n// Creamos la fecha actual\n$fechaActual = new DateTime();\n\n// Creamos una fecha de nacimiento (ejemplo)\n$fechaNacimiento = new DateTime('1990-05-15 14:30:00');\n\n// Calculamos la diferencia entre las fechas\n$diferencia = $fechaActual->diff($fechaNacimiento);\n\necho \"Fecha actual: \" . $fechaActual->format('Y-m-d H:i:s') . \"\\n\";\necho \"Fecha de nacimiento: \" . $fechaNacimiento->format('Y-m-d H:i:s') . \"\\n\";\necho \"Años transcurridos: \" . $diferencia->y . \"\\n\\n\";\n\n// PARTE 2: DIFICULTAD EXTRA - Formatear la fecha de 10 maneras diferentes\n\necho \"DIFERENTES FORMATOS DE FECHA:\\n\";\n\n// 1. Día, mes y año\necho \"1. Día, mes y año: \" . $fechaNacimiento->format('d/m/Y') . \"\\n\";\n\n// 2. Hora, minuto y segundo\necho \"2. Hora, minuto y segundo: \" . $fechaNacimiento->format('H:i:s') . \"\\n\";\n\n// 3. Día del año\necho \"3. Día del año: \" . $fechaNacimiento->format('z') . \" (comenzando desde 0)\\n\";\n\n// 4. Día de la semana\n$diasSemana = ['Domingo', 'Lunes', 'Martes', 'Miércoles', 'Jueves', 'Viernes', 'Sábado'];\necho \"4. Día de la semana: \" . $diasSemana[$fechaNacimiento->format('w')] . \"\\n\";\n\n// 5. Nombre del mes\n$meses = ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', \n          'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'];\necho \"5. Nombre del mes: \" . $meses[$fechaNacimiento->format('n') - 1] . \"\\n\";\n\n// 6. Formato largo personalizado\nsetlocale(LC_TIME, 'es_ES.UTF-8');\necho \"6. Formato largo: \" . strftime('%A, %d de %B de %Y', $fechaNacimiento->getTimestamp()) . \"\\n\";\n\n// 7. Formato ISO 8601\necho \"7. Formato ISO 8601: \" . $fechaNacimiento->format('c') . \"\\n\";\n\n// 8. Semana del año\necho \"8. Semana del año: \" . $fechaNacimiento->format('W') . \"\\n\";\n\n// 9. Trimestre del año\n$trimestre = ceil($fechaNacimiento->format('n') / 3);\necho \"9. Trimestre del año: \" . $trimestre . \"\\n\";\n\n// 10. Timestamp Unix\necho \"10. Timestamp Unix: \" . $fechaNacimiento->getTimestamp() . \"\\n\";\n\n// Funciones auxiliares de ejemplo\nfunction obtenerEdad($fechaNacimiento) {\n    $hoy = new DateTime();\n    $edad = $hoy->diff($fechaNacimiento);\n    return $edad->y;\n}\n\nfunction esBisiesto($año) {\n    return date('L', strtotime(\"$año-01-01\")) == 1;\n}\n\n// Ejemplo de uso de funciones auxiliares\necho \"\\nFUNCIONES AUXILIARES:\\n\";\necho \"Edad calculada: \" . obtenerEdad($fechaNacimiento) . \" años\\n\";\necho \"¿El año de nacimiento es bisiesto? \" . \n     (esBisiesto($fechaNacimiento->format('Y')) ? \"Sí\" : \"No\") . \"\\n\";\n?>"
  },
  {
    "path": "Roadmap/14 - FECHAS/php/gabrielmoris.php",
    "content": "<?php\n/*\n* EXERCISE:\n* Create two variables using the date objects (date, or similar) of your language:\n* A first one representing the current date (day, month, year, hour, minute, second).\n* A second one representing your date of birth (you can make up the time).\n* Calculate how many years have passed between the two dates.\n*/\n\n\ndate_default_timezone_set('Europe/Berlin'); // This will set the date zone in general\necho date(DATE_RSS) . \"\\n\"; // Output: Mon, 22 May 2023 15:02:34 +0000\necho date(DATE_ATOM) . \"\\n\"; // Output: 2023-05-22T15:02:34+00:00\n$count = 0;\ndo {\n    echo \"\\033c\";\n    $currentDateTime = date('D d.m.Y H:i:s');\n    echo \"Current date and time: \" . $currentDateTime . \"\\n\";\n    $BDDateTime = new DateTime('1989-09-17 03:45:00');\n    $formatedBD = $BDDateTime->format(\"D d.m.Y H:i:s\");\n    echo  \"I born \" . $formatedBD . \"\\n\";\n    echo \"\\n\\n\";\n    $currDate = new DateTime($currentDateTime);\n    $timedifference = $BDDateTime->diff($currDate);\n\n    echo \"I am \" . round($timedifference->days / 365, 1) . \" years old.\\n\";\n\n    $count += 1;\n    sleep(1);\n} while ($count < 5);\n\n\n/* EXTRA DIFFICULTY (optional):\n* Using your birthday date, format it and display its result in\n* 10 different ways. For example:\n* Day, month and year.\n* Hour, minute and second.\n* Day of year.\n* Day of the week.\n* Name of the month.\n* (whatever you can think of...)\n*/\n\necho \"My BD in different formats:\\n\";\n\n$BDDateTime = new DateTime('1989-09-17 03:45:00');\necho \"Date \" . $BDDateTime->format('d.m.Y') . \"\\n\";\necho \"Hour \" . $BDDateTime->format('H:i:s') . \"\\n\";\necho \"Day of the Year \" . $BDDateTime->format('z') . \"\\n\";\necho \"Day of the week \" . $BDDateTime->format('l') . \"\\n\";\necho \"Name of the Month \" . $BDDateTime->format('F') . \"\\n\";\necho \"ISO format \" . $BDDateTime->format('c') . \"\\n\";\n$now = new DateTime();\n$interval = $BDDateTime->diff($now);\necho \"Time Passed: \" . floor($interval->format('%R%a') / 365) . \" Years \\n\";\necho \"I born a \" . $BDDateTime->format('l, jS F Y \\a\\t g:ia') . \"\\n\";\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/php/miguelex.php",
    "content": "<?php\n    $now = date(\"d/m/Y H:i:s\");\n\n    $birth = date(\"09/03/1975 09:40:25\");\n\n    $now = strtotime($now);\n    $birth = strtotime($birth);\n\n    $diff = $now - $birth;\n    echo \"Hoy es el \".date(\"d/m/Y H:i:s\", $now).\"\\n\";\n    echo \"Naci el \".date(\"d/m/Y H:i:s\", $birth).\"\\n\";\n\n    $diff = $now - $birth;\n    $years = floor($diff / (60 * 60 * 24 * 365));\n    $months = floor(($diff - $years * 60 * 60 * 24 * 365) / (60 * 60 * 24 * 30));\n    $days = floor(($diff - $years * 60 * 60 * 24 * 365 - $months * 60 * 60 * 24 * 30) / (60 * 60 * 24));\n    $hours = floor(($diff - $years * 60 * 60 * 24 * 365 - $months * 60 * 60 * 24 * 30 - $days * 60 * 60 * 24) / (60 * 60));\n    $minutes = floor(($diff - $years * 60 * 60 * 24 * 365 - $months * 60 * 60 * 24 * 30 - $days * 60 * 60 * 24 - $hours * 60 * 60) / 60);\n    $seconds = floor($diff - $years * 60 * 60 * 24 * 365 - $months * 60 * 60 * 24 * 30 - $days * 60 * 60 * 24 - $hours * 60 * 60 - $minutes * 60);\n\n    echo \"\\n\\nHan pasado \".$years.\" años, \".$months.\" meses, \".$days.\" días, \".$hours.\" horas, \".$minutes.\" minutos y \".$seconds.\" segundos desde que nací\\n\";\n\n    // Extra\n\n    // Muestra la fecha de naciemnteo por patntalla en formato dd/mm/yyyy\n    echo date(\"d/m/Y\", $birth).\"\\n\";\n\n    // Muestra la fecha de naciemnteo por patntalla en formato dd/mm/yy\n\n    echo date(\"d/m/y\", $birth).\"\\n\";\n\n    // Muestra la fecha de naciemnteo por patntalla en formato dd de mm de yyyy con el mes en letra (foramto español)\n    echo date(\"d \\\\d\\\\e F \\\\d\\\\e Y\", $birth).\"\\n\";\n\n    // Muestra el dia de la fema que fue el dia de la fecha de nacimeinto\n\n    echo \"Naci un \".date(\"l\", $birth).\"\\n\";\n\n    // Muestra que dia del año fue la fecha de nacimiento\n\n    echo \"El día de mi nacimiento era el \".date(\"z\", $birth).\" dia del año\\n\";\n\n    // Muestra que semana del año fue la fecha de nacimiento\n    echo \"La fecha de mi nacimiento estaba en la semana \".date(\"W\", $birth).\"\\n\";\n\n    // Muestra si el año de la fecha de nacimiento es bisiesto\n    echo \"Mi año de nacimiento \".(date(\"L\", $birth) ? \"es\" : \"no es\").\" bisiesto\\n\";\n\n    // Muestra el nombre del mes de la fecha de nacimiento\n    echo \"Nací en \".date(\"F\", $birth).\"\\n\";\n\n    // Muestra el nombre del mes de la fecha de nacimiento en 3 letras\n    echo \"Nací en \".date(\"M\", $birth).\"\\n\";\n\n    // Muestra en que decada naci\n    echo \"Nací en la decada de los \".substr(date(\"Y\", $birth), 2, 1).\"0\\n\";\n\n    // Muestra en que siglo naci\n    $century = intval(substr(date(\"Y\", $birth), 0, 2)) +1;\n    echo \"Nací en el siglo \".$century.\"\\n\";\n\n    // Hora de nacimiento en formato 24 horas\n    echo \"Nací a las \".date(\"H:i:s\", $birth).\"\\n\";\n\n    // Hora de nacimiento en formato 12 horas\n    echo \"Nací a las \".date(\"h:i:s a\", $birth).\"\\n\";\n\n    \n\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/AChapeton.py",
    "content": "from datetime import datetime\n\ntoday = datetime.now()\nprint('today: ', today)\n\nbirth = datetime(1997, 6, 2, 15, 30, 00)\nprint('birth: ', birth)\n\n# DIFICULTAD EXTRA\n\nprint('Dia, mes y año: ', birth.strftime(\"%d/%m/%y\"))\nprint('Dia, mes y año completo: ', birth.strftime(\"%d/%m/%Y\"))\nprint('Hora formato 12, minuto y segundos: ', birth.strftime(\"%I:%M:%S\"))\nprint('Hora formato 24, minuto y segundos: ', birth.strftime(\"%H:%M:%S\"))\nprint('Dia del año: ', birth.strftime(\"%j\"))\nprint('Semana del año: ', birth.strftime(\"%U\"))\nprint('Mes del año abreviado: ', birth.strftime(\"%h\"))\nprint('Mes del año: ', birth.strftime(\"%B\"))\nprint('Dia de la semana: ', birth.strftime(\"%A\"))\nprint('Representacion horaria: ', birth.strftime(\"%p\"))"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/Aldroide.py",
    "content": "# Ejercicio:\n\"\"\"\n    Crea dos variables utilizando los objetos fecha (date o semejante) de tu lenguaje:\n        *La primera que represente la fecha (dia, mes, año, hora, minuto, segundo)\n        *La segunda que represente tu fecha de nacimiento \n    Calcular cuántod años han transcurrido entre ambas fechas\n\"\"\"\n\nimport datetime\n\ntoday = datetime.datetime.now()\nborn_date = datetime.datetime.strptime(\n    \"1983-09-24 06:26:00\", \"%Y-%m-%d %H:%M:%S\")\n\n\nprint(f\"\\n Today is: {today}\")\nprint(f\"\\n Aldroide was born in: {born_date}\")\n\nyear = today.year - born_date.year\nprint(f\"\\n Aldroide is {year} years old\")\n\n\n# Dificultad Extra\n\"\"\"\n    Utilizando la fecha de cumpleaños formateala y muestra su resulado \n    de 10 maneras distintas:\n        - Día, mes y año.\n        - Hora, minuto y segundo.\n        - Día de año.\n        - Día de la semana.\n        - Nombre del mes.\n        - (lo que se te ocurra...)\n\"\"\"\nprint(\"\\nDificultad Extra\")\nprint(f\"\"\"\\n\nDiffents date formats\n1. Year-Month-Day Hrs:Min:Sec   =   {born_date}\n2. Day/Month/Year               =   {born_date.strftime(\"%d/%m/%Y\")}\n3. Month/Day/Year               =   {born_date.strftime(\"%m/%d/%Y\")}\n4. Day/MonthName/Year           =   {born_date.strftime(\"%d/%B/%Y\")}\n5. DayName-Dat/MonthName/Year   =   {born_date.strftime(\"%A-%d/%B/%Y\")}\n6. Abbreviated                  =   {born_date.strftime(\"%a-%d-%b-%Y\")}\n7. DayName-Day-MonthName        =   {born_date.strftime(\"%a-%d-%b\")}\n8. Day of the year              =   {born_date.strftime(\"%j\")}\n9. Hour(12 format)              =   {born_date.strftime(\"%I:%M:%S %p\")}\n10. Hour(24 format)             =   {born_date.strftime(\"%H:%M:%S\")}\n11. {born_date.strftime(\"%A, %dth of %B %Y at %I:%M:%S %p\")}\n\"\"\")\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/CaveroBrandon.py",
    "content": "\"\"\"EJERCICIO:\nCrea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n- Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n- Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\nCalcula cuántos años han transcurrido entre ambas fechas.\"\"\"\n\nimport datetime\nfrom dateutil.relativedelta import relativedelta\n\n\ndef calculate_how_many_years_since_dob():\n    print(f'**** Current Date ****\\n'\n          f'Date: {current_date.date()}\\n'\n          f'Time: {current_date.time()}\\n')\n\n    print(f'**** My birthday ****\\n'\n          f'Date: {dob_date.date()}\\n'\n          f'Time: {dob_date.time()}\\n')\n\n    total_years = relativedelta(current_date, dob_date)\n    print(f'Years that has passed: {total_years.years} years\\n')\n\n\n\"\"\" DIFICULTAD EXTRA (opcional):\nUtilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de 10 maneras diferentes. Por ejemplo:\n- Día, mes y año.\n- Hora, minuto y segundo.\n- Día de año.\n- Día de la semana.\n- Nombre del mes.\n- Otros\"\"\"\n\n\ndef formatting_dob():\n    print(f'1. YYYY/DD/MM: {dob_date.strftime(\"%Y/%d/%m\")}')\n    print(f'2. YYYY/MM/DD: {dob_date.strftime(\"%Y/%m/%d\")}')\n    print(f'3. DD/MM/YY: {dob_date.strftime(\"%d/%m/%y\")}')\n    print(f'4. MM/DD/YY: {dob_date.strftime(\"%m/%d/%y\")}')\n    print(f'5. Month day, year: {dob_date.strftime(\"%B %d, %Y\")}')\n    print(f'6. Month DD, HH:MM : {dob_date.strftime(\"%B %d, %H:%M\")}')\n    print(f'7. Day of the year YYYY: {dob_date.strftime(\"Day %j of %Y\")}')\n    print(f'8. HH hours and MM minutes of MM the DD: {dob_date.strftime(\"%H hours and %M minutes of %B the %d\")}')\n    print(f'9. DD-MM-YY HH:MM:SS: {dob_date.strftime(\"%d-%m-%y %H:%M:%S\")}')\n    print(f'10. --Day and Time--\\n'\n          f'{dob_date.strftime(\"Date: %A, %d\")}\\n'\n          f'{dob_date.strftime(\"Time: %H:%M:%S\")}')\n\n\ncurrent_date = datetime.datetime.now().replace(microsecond=0)\ndob_date = datetime.datetime(year=1994, month=5, day=20, hour=10, minute=30, second=15, microsecond=0)\n\ncalculate_how_many_years_since_dob()\nprint('****************')\nformatting_dob()\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/CesarCarmona30.py",
    "content": "import datetime\n\n# Variable para fecha actual\ncurrent_datetime = datetime.datetime.now()\n\ndatebirth_str = \"30-07-2004 02:28:00 AM\"\nformat_str = \"%d-%m-%Y %I:%M:%S %p\"\n\n# Variable para mi fecha de nacimiento\nbirth_datetime = datetime.datetime.strptime(datebirth_str, format_str)\n\n# Cálculo de tiempo entre fechas\ndifference_datetime = current_datetime - birth_datetime\nyears = difference_datetime.days // 365\nremaining_days = difference_datetime.days % 365\nmonths = remaining_days // 30\nremaining_days %= 30\ndays = remaining_days\nhours = difference_datetime.seconds // 3600\nminutes =(difference_datetime.seconds % 3600) // 60\nseconds = difference_datetime.seconds % 60\n\nprint(f'''Hi, I'm César and i have:\n  {years} years, {months} months, {days} days, with\n  {hours} hours, {minutes} minutes and {seconds} seconds \n''')\n\nprint(f\"\"\"\n1. Year-Month-Day Hrs:Min:Sec = {birth_datetime}\n2. Day/Month/Year = {birth_datetime.strftime(\"%d/%m/%Y\")}\n3. Month/Day/Year = {birth_datetime.strftime(\"%m/%d/%Y\")}\n4. Day/MonthName/Year = {birth_datetime.strftime(\"%d/%B/%Y\")}\n5. DayName-Dat/MonthName/Year = {birth_datetime.strftime(\"%A-%d/%B/%Y\")}\n6. Abbreviated = {birth_datetime.strftime(\"%a-%d-%b-%Y\")}\n7. DayName-Day-MonthNameAbbr = {birth_datetime.strftime(\"%a-%d-%b\")}\n8. Day of the year = {birth_datetime.strftime(\"%j\")}\n9. Hour(12 format) = {birth_datetime.strftime(\"%I:%M:%S %p\")}\n10. Hour(24 format) = {birth_datetime.strftime(\"%H:%M:%S\")}\n11. {birth_datetime.strftime(\"%A, %dth of %B %Y at %I:%M:%S %p\")}\n\"\"\")"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/Chrisdev00.py",
    "content": "\"\"\"\n* EJERCICIO:\n* Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n* - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n* - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n* Calcula cuántos años han transcurrido entre ambas fechas.\n*\n* DIFICULTAD EXTRA (opcional):\n* Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n* 10 maneras diferentes. Por ejemplo:\n* - Día, mes y año.\n* - Hora, minuto y segundo.\n* - Día de año.\n* - Día de la semana.\n* - Nombre del mes.\n* (lo que se te ocurra...)\n\"\"\"\n\nfrom datetime import datetime\n\ndate_now = datetime.now()\nbirth_date = datetime(1994, 8, 1, 18, 33, 45)\n\ndifference = date_now - birth_date\n\nprint(\"Fecha actual:\",date_now)\nprint(\"Fecha de nacimiento:\",birth_date)\n\nprint(\"Años transcurridos entre las dos fechas:\", difference.days // 365, \"años\")\n\n\n################# --------------------- EXTRA ------------------------------- ###################\n\nbirth_date = datetime(1994, 8, 1, 18, 33, 45)\n\nprint(f'1. Dia, mes y año: {birth_date.strftime(\"%d de %B de %Y\")}')\n\nprint(f'2. Hora, minutos, segundos: {birth_date.strftime(\"%H:%M:%S\")}')\n\nprint(f\"3. Dia del año: {birth_date.timetuple().tm_yday}\")\n\nprint(f\"4. Dia de la semana: {birth_date.strftime('%A')}\")\n\nprint(f\"5. Nombre del mes: {birth_date.strftime('%B')}\")\n\nprint(f\"6. Semana del año: {birth_date.strftime('%U')}\")\n\nprint(f\"7. Formato mes en letras cortas: {birth_date.strftime('%b')}\")\n\nprint(f\"8. Formato mm-dd-YYYY: {birth_date.strftime('%m-%d-%Y')}\")\n\nprint(f\"9. Formato personalizado: {birth_date.strftime('Born on %A, %dth of %B %Y at %I:%M:%S %p')}\")\n\ndef obtener_estacion(fecha):\n    mes = fecha.month\n\n    if 3 <= mes <= 5:\n        return \"Otoño\"\n    elif 6 <= mes <= 8:\n        return \"Invierno\"\n    elif 9 <= mes <= 11:\n        return \"Primavera\"\n    else:\n        return \"Verano\"\n\nestacion_nacimiento = obtener_estacion(birth_date)\nprint(f\"10. Estacion del año: Naciste en la estación de {estacion_nacimiento}\")"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/Complex303.py",
    "content": "\"\"\"\nFECHAS\n\"\"\"\n\n# Importamos la clase datetime del módulo datetime\nfrom datetime import datetime\n\n# Obtenemos la fecha y hora actual del sistema\nnow = datetime.now()\n\n# Creamos un objeto datetime con una fecha y hora específica: 16 de febrero de 2001 a la 1:34:00 AM\nbirth_date = datetime(2001, 2, 16, 1, 34, 0)\n\n# Mostramos en pantalla la fecha y hora actual\nprint(f\"Fecha actual: {now}\")\n\n# Mostramos en pantalla la fecha y hora de nacimiento\nprint(f\"Fecha de cumpleaños:  {birth_date}\")\n\n# Calculamos la diferencia entre la fecha actual y la fecha de nacimiento\ndifferencia = now - birth_date\n\n# Imprimimos el tipo de dato que devuelve esa resta (es un objeto 'timedelta')\nprint(type(differencia))  # <class 'datetime.timedelta'>\n\n# Mostramos los años cumplidos dividiendo los días transcurridos entre 365\n# (Nota: esto es una aproximación porque no toma en cuenta los años bisiestos)\nprint(f\"Tengo {differencia.days // 365} años\")\n\n\n#Para bases de datos y programación: YYYY-MM-DD\n#Para mostrar a usuarios hispanohablantes: DD/MM/YYYY\n\n\"\"\" * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\"\"\"\n\n# Día-Mes-Año (año en dos dígitos)\nprint(birth_date.strftime(\"%d-%m-%y\"))  # Ej: 16-02-01\n\n# Día-Mes-Año (año en cuatro dígitos)\nprint(birth_date.strftime(\"%d-%m-%Y\"))  # Ej: 16-02-2001\n\n# Horas, minutos y segundos en formato de 24 horas\nprint(birth_date.strftime(\"%H:%M:%S\"))  # Ej: 01:34:00\n\n# Día del año (número de 001 a 366)\nprint(birth_date.strftime(\"%j\"))        # Ej: 047 (porque 16 de febrero es el día 47 del año)\n\n# Día de la semana completo\nprint(birth_date.strftime(\"%A\"))        # Ej: Friday\n\n# Día de la semana abreviado\nprint(birth_date.strftime(\"%a\"))        # Ej: Fri\n\n# Nombre del mes abreviado\nprint(birth_date.strftime(\"%h\"))        # Ej: Feb\n\n# Nombre completo del mes\nprint(birth_date.strftime(\"%B\"))        # Ej: February\n\n# Representación local por defecto (fecha y hora completa en formato regional)\nprint(now.strftime(\"%c\"))               # Ej: Thu May 15 22:30:00 2025\n\n# Solo la fecha en formato local\nprint(birth_date.strftime(\"%x\"))        # Ej: 02/16/01 (depende de la configuración regional)\n\n# Solo la hora en formato local\nprint(now.strftime(\"%X\"))               # Ej: 22:30:00\n\n# AM o PM\nprint(now.strftime(\"%p\"))               # Ej: PM\n\n\n# Año solo (dos dígitos)\nprint(birth_date.strftime(\"%y\"))  # Ej: 01\n\n# Año solo (cuatro dígitos)\nprint(birth_date.strftime(\"%Y\"))  # Ej: 2001\n\n# Mes solo (número)\nprint(birth_date.strftime(\"%m\"))  # Ej: 02\n\n# Día del mes (número)\nprint(birth_date.strftime(\"%d\"))  # Ej: 16\n\n# Hora en formato 12 horas\nprint(birth_date.strftime(\"%I:%M %p\"))  # Ej: 01:34 AM\n\n# Hora en formato 24 horas\nprint(birth_date.strftime(\"%H:%M\"))     # Ej: 01:34\n\n# Nombre corto del mes\nprint(birth_date.strftime(\"%b\"))        # Ej: Feb\n\n# Número de la semana del año (domingo como primer día de la semana)\nprint(birth_date.strftime(\"%U\"))        # Ej: 06\n\n# Número de la semana del año (lunes como primer día de la semana)\nprint(birth_date.strftime(\"%W\"))        # Ej: 07\n\n\n#strftime (string format time) convierte un objeto datetime a un string con el formato que tú le indiques.\n#strptime (string parse time) convierte un string con una fecha y hora a un objeto datetime, usando el formato que tú le indiques\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/DaniQB99.py",
    "content": "'''\nEJERCICIO:\nCrea dos variables utilizando los objetos fecha(date, o semejante) de\ntu lenguaje:\n- Una primera que represente la fecha (día, mes, año, hora, minuto, \nsegundo) actual.\n- Una segunda que represente tu fecha de nacimiento (te puedes \ninventar la hora).\nCalcula cuántos años han transcurrido entre ambas fechas.\n'''\nfrom datetime import datetime\n\nnow = datetime.now()\nbirthday = datetime(1999, 7, 26, 9, 00, 00)\n\nprint(now)\nprint(birthday)\n\ndifference = now - birthday\nprint(type(difference))\n\nprint(f\"Tengo {difference.days // 365} años\")\n\n\n\n'''\nDIFICULTAD EXTRA (opcional):\nUtilizando la fecha de tu cumpleaños, formatéala y muestra su \nresultado de 10 maneras diferentes. Por ejemplo:\n- Día, mes y año.\n- Hora, minuto y segundo.\n- Día de año.\n- Día de la semana.\n- Nombre del mes.\n(lo que se te ocurra...)\n'''\n\nprint(\"\\n\\nDIFICULTAD EXTRA\\n\")\n\n# Dia, mes y año\n\nprint(birthday.strftime(\"%d/%m/%y\"))\nprint(birthday.strftime(\"%d/%m/%Y\"))\nprint(birthday.strftime(\"%d %B %Y\\n\"))\n\n# Hora, minuto y segundo\nprint(birthday.strftime(\"%H:%M:%S\\n\"))\n\n\n# Dia del año\nprint(birthday.strftime(\"%j\\n\"))\n\n# Dia de la semana\nprint(birthday.strftime(\"%A\"))\nprint(birthday.strftime(\"%a\\n\"))\n\n# Nombre del mes\nprint(birthday.strftime(\"%B\"))  \nprint(birthday.strftime(\"%b\\n\"))    \n\n# Representación de la fecha en formato de texto\nprint(birthday.strftime(\"%c\"))      # Día, mes, día de la semana, día del mes, día del año, hora, minuto y segundo\nprint(birthday.strftime(\"%x\"))      # Día de la semana, día del mes, día del año\nprint(birthday.strftime(\"%X\\n\"))    # Hora, minuto y segundo\n\n# AM/PM\nprint(birthday.strftime(\"%p\\n\"))    # AM/PM"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/Dkp-Dev.py",
    "content": "from datetime import datetime\n\n\"\"\"\n * EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n\"\"\"\n\nnow = datetime.now()\nbirth_date = datetime(1995, 1, 11, 12, 30, 0)\n\nprint(now)\nprint(birth_date)\n\ndifference = now - birth_date\nprint(type(difference))\n\nprint(f\"Tengo {difference.days // 365} años.\")\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n\"\"\"\n\n# Día, mes y año\nprint(birth_date.strftime(\"%d/%m/%y\"))\nprint(birth_date.strftime(\"%d/%m/%Y\"))\n\n# Horas, minutos y segundos\nprint(birth_date.strftime(\"%H:%M:%S\"))\n\n# Día del año\nprint(birth_date.strftime(\"%j\"))\n\n# Día de la semana\nprint(birth_date.strftime(\"%A\"))\n\n# Nombre del mes\nprint(birth_date.strftime(\"%h\"))\nprint(birth_date.strftime(\"%B\"))\n\n# Representación por defecto del locale\nprint(birth_date.strftime(\"%c\"))\nprint(birth_date.strftime(\"%x\"))\nprint(birth_date.strftime(\"%X\"))\n\n# AM/PM\nprint(birth_date.strftime(\"%p\"))\n\n# Mi dia de nacimiento\nprint(birth_date.strftime(\"%d/%B/%Y %H:%M %p\"))\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/EmmanuelMMontesinos.py",
    "content": "\"\"\"/*\n * EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n */\"\"\"\n\n# Ejercicio Base\n\nfrom datetime import datetime\n\nfecha_actual = datetime.now()\nfecha_cumple = datetime.strptime(\"17/05/1991\",\"%d/%m/%Y\")\ntiempo_pasado = fecha_actual - fecha_cumple\n\nprint(f\"Fecha Actual: {fecha_actual}\")\nprint(f\"Fecha Cumpleaños: {fecha_cumple}\")\nprint(f\"Tiempo pasado: {tiempo_pasado}\")\n\n# Ejercicio Extra\n\n'''\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n'''\n\nfecha_1 = fecha_cumple.day\nfecha_2 = fecha_cumple.year\nfecha_3 = fecha_cumple.month\nfecha_4 = fecha_cumple.second\nfecha_5 = fecha_cumple.minute\nfecha_6 = fecha_cumple.hour\nfecha_7 = f\"{fecha_cumple.day}/{fecha_cumple.month}/{fecha_cumple.year}\"\nfecha_8 = f\"{fecha_cumple.hour}:{fecha_cumple.minute}:{fecha_cumple.second}\"\nfecha_9 = f\"{fecha_cumple.month}/{fecha_cumple.day}/{fecha_cumple.year}\"\nfecha_10 = f\"{fecha_cumple.day}/{fecha_cumple.month}/{fecha_cumple.year} - {fecha_cumple.hour}:{fecha_cumple.minute}:{fecha_cumple.second}\"\n\nprint(fecha_1)\nprint(fecha_2)\nprint(fecha_3)\nprint(fecha_4)\nprint(fecha_5)\nprint(fecha_6)\nprint(fecha_7)\nprint(fecha_8)\nprint(fecha_9)\nprint(fecha_10)"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/FedeAirala.py",
    "content": "# Reto 14 - FECHAS\n\n\"\"\"\n * EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n\"\"\"\n\nimport datetime\n\ncurrent_day = datetime.datetime.now()\nbirthdate = datetime.datetime (1980,6,25,9,30,25)\n\nprint (f\"La fecha actual es: {current_day}\")\nprint (f\"La fecha de mi nacimiento es: {birthdate} \")\n\ntime_elapsed_year = current_day.year - birthdate.year\ntime_elapsed_day = current_day - birthdate\n\nprint (f\"Entre la fecha actual y mi fecha de nacimiento pasaron {time_elapsed_year} años\")\nprint (f\"Que son nada más y nada menos que {time_elapsed_day.days} días\")\n\n\"\"\"\n*\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n */\n\"\"\"\nprint (\"\\n\")\nprint (\"-\"*60)\n\nprint (\"DATOS CON MI FECHA DE NACIMIENTO\")\nprint (\"\")\nprint (f\"La fecha de mi nacimiento es el {birthdate.day} del {birthdate.month} de {birthdate.year}\")\nprint (f\"Día, mes y año de nacimiento:  {datetime.datetime.strftime(birthdate,'%d / %m / %Y')}\")\nprint (f\"Horario de nacimiento {datetime.datetime.strftime(birthdate,'%H : %M : %S')} hs. \")\nprint (f\"Año de Nacimiento {birthdate.year}\")\nprint (f\"Mes de nacimiento {datetime.datetime.strftime(birthdate, '%B')}\")\nprint (f\"Día de nacimiento  {datetime.datetime.strftime(birthdate, '%a')}\")\nprint (f\"Nací en la semana {datetime.datetime.strftime(birthdate, '%W')} del año {birthdate.year}\")\nprint (f\"Día número {datetime.datetime.strftime(birthdate, '%j')}\")\n\n\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/Gallitofast.py",
    "content": "import datetime\nfecha_actual= datetime.datetime.now()\nfecha_nacimiento = datetime.datetime(2002, 4, 2, 10, 24)  \ndiferencia = fecha_actual-fecha_nacimiento\nprint(f\"La fech actual es:{fecha_actual}\")\nprint(f\"Mi fecha de nacimiento es: {fecha_nacimiento}\")\nprint(f\"He vivido: {diferencia.days//365} años\")\n\n\n\"\"\"Dificultad extra\nUtilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n \"\"\"\n\nprint(f\"De mi fecha de nacimiento, el dia es el dia {fecha_nacimiento.day}, del mes {fecha_nacimiento.hour}, y el año fue {fecha_nacimiento.year} \")\nprint(f\"La hora fue a las {fecha_nacimiento.hour} : {fecha_nacimiento.minute} con {fecha_nacimiento.minute} minutos\")\nprint (f\"Horario de nacimiento {datetime.datetime.strftime(fecha_nacimiento,'%H : %M : %S')} hs. \") \nprint(f\"Día de nacimiento: {fecha_nacimiento.strftime('%A')}\")\nprint (f\"Día número {datetime.datetime.strftime(fecha_nacimiento, '%j')}\")\nprint (f\"Nací en la semana {datetime.datetime.strftime(fecha_nacimiento, '%W')} del año {fecha_nacimiento.year}\")\nprint (f\"Mes de nacimiento {datetime.datetime.strftime(fecha_nacimiento, '%B')}\")"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/Gordo-Master.py",
    "content": "# 14 - Fechas\n\nfrom datetime import datetime, date, time\n\nnow = datetime.now()\nbirthday = datetime(1995,5,8,12,35,17)\n\nage = (now - birthday).days // 365\n\nprint(now)\nprint(birthday)\nprint(f\"Pasaron : {age} años\")\n\n\"\"\"\nEjercicio extra\n\"\"\"\n\nprint(birthday.strftime(f\"%A, %d de %B de %Y\"))\nprint(birthday.strftime(f\"%c\"))\nprint(birthday.strftime(f\"%x\"))\nprint(birthday.strftime(f\"%X\"))\nprint(birthday.strftime(f\"%d / %m / %Y\"))\nprint(birthday.strftime(f\"%Y / %m / %d\"))\nprint(birthday.strftime(f\"%H horas, %M minutos, %S segundos, %p\"))\nprint(birthday.strftime(f\"%j día del año %Y\"))\nprint(birthday.strftime(f\"%Uº semana del año %Y\"))\nprint(birthday.strftime(f\"%Wº semana del año %Y\"))\nprint(birthday.strftime(f\"%Vº semana del año %Y\"))"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/Hyromy.py",
    "content": "import datetime # modulo para fecha y hora\n\nfecha_actual = datetime.datetime.now() # obtener fecha y hora actuales\n\nprint(fecha_actual)\n\nprint(f\"Dia: {fecha_actual.day}\")\nprint(f\"Mes: {fecha_actual.month}\")\nprint(f\"Año: {fecha_actual.year}\")\nprint(f\"Hora: {fecha_actual.hour}\")\nprint(f\"Minutos: {fecha_actual.minute}\")\nprint(f\"Segundos: {fecha_actual.second}\")\nprint()\n\nimport random\n\n# construir una fecha especifica\nnacimiento = datetime.datetime(year = 2004, \n                               month = 12,\n                               day = 4,\n                               hour = random.randint(0, 23))\n\nprint(f\"fecha de nacimiento: {nacimiento}\")\n\ndiferencia = fecha_actual - nacimiento # diferencia entre ambas fechas\n\nprint(f\"han pasado {diferencia.days // 365} años\")\nprint()\n\n# ---- DIFICULTAD EXTRA ----\nimport calendar\nnacimiento = datetime.date(year = 2004,\n                           month = 12,\n                           day = 4)\n\nyear_days = nacimiento - datetime.date(year = nacimiento.year,\n                                        month = 1,\n                                        day = 1)\n\nbisiesto = calendar.isleap(nacimiento.year)\n\nprint(f\"Año: {nacimiento.year}\")\nprint(f\"N. Mes: {nacimiento.month}\")\nprint(f\"Mes: {nacimiento.strftime(\"%B\")}\")\nprint(f\"Dia: {nacimiento.day}\")\nprint(f\"Nombre dia: {nacimiento.strftime(\"%A\")}\")\nprint(f\"Dia semana: {nacimiento.weekday() + 1}\")\nprint(f\"Dias del año: {year_days.days}\")\nprint(f\"Año biciesto: {bisiesto}\")\nprint(f\"Fecha (dd/mm/aaaa): {nacimiento.strftime(\"%d/%m/%Y\")}\")\nprint(f\"Año: (yyyy/mm/dd): {nacimiento.strftime(\"%Y/%m/%d\")}\")"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/Irenetitor.py",
    "content": "from datetime import datetime, timedelta\n\n#Exercise\n\nnow = datetime.now()\n\nbirth_date = datetime(1991, 12, 21, 9, 30, 46)\nprint(now)\nprint(birth_date)\n\nyears = now - birth_date\nprint(f\"I am {years.days // 365} years old\")\n\n#Extra exercise\n\n#Day, month, year\n\nprint(birth_date.strftime(\"%d-%m-%y\"))\nprint(birth_date.strftime(\"%d %m %Y\"))\n\n#Hours, minutes, seconds\nprint(birth_date.strftime(\"%H:%M:%S\"))\n\n#Day of the week name\nprint(birth_date.strftime(\"%A\"))\n\n#Month name\nprint(birth_date.strftime(\"%B\"))\n\n#My birthday + 10 days\nprint(birth_date + timedelta(days=10))\n\n#My birthday - 9 hours\nprint(birth_date - timedelta(hours=9))\n\n#Abbreviated month name\nprint(birth_date.strftime(\"%h\"))\n\n#Full month name\nprint(birth_date.strftime(\"%B\"))\n\n#Formatted according to your system’s locale.\nprint(birth_date.strftime(\"%c\"))\nprint(birth_date.strftime(\"%x\"))\nprint(birth_date.strftime(\"%X\"))\n\n#AM/PM\nprint(birth_date.strftime(\"%p\"))\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/JAFeito.py",
    "content": "\n\"\"\"\n EJERCICIO:\n Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n Calcula cuántos años han transcurrido entre ambas fechas.\n\n DIFICULTAD EXTRA (opcional):\n Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n 10 maneras diferentes. Por ejemplo:\n - Día, mes y año.\n - Hora, minuto y segundo.\n - Día de año.\n - Día de la semana.\n - Nombre del mes.\n (lo que se te ocurra...)\n\"\"\"\nfrom datetime import datetime\nimport locale\nahora = datetime.now()\nnacido = datetime(1979,3,1,12,50,15)\n\ndiferencia = ahora - nacido\naños = diferencia.days // 365\nprint (f\"Tengo {int(años)} años\")\n\n#EXTRA\n\nprint(nacido.strftime(\"%d/%m/%y\"))# Dia, mes y año\nprint(nacido.strftime(\"%d/%m/%Y\"))# Dia, mes y año con 4 digitos\nprint(nacido.strftime(\"%j\"))#Dia del año\nprint(nacido.strftime(\"%A\"))#Dia de la semana en ingles\nprint(nacido.strftime(\"%c\"))#Formato ingles\nlocale.setlocale(locale.LC_TIME, 'es_ES')\nprint(nacido.strftime(\"%A\"))#Dia de la semana en español\nprint(nacido.strftime(\"%d/%h/%y\"))# Dia, mes abreviado y año\nprint(nacido.strftime(\"%d/%B/%y\"))# Dia, mes completo y año\nprint(nacido.strftime(\"%c\"))#Formato español\nprint(nacido.strftime(\"%B/%d/%Y\"))# Mes completo, dia y año"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/JesusWay69.py",
    "content": "import os\nos.system('cls')\nfrom datetime import datetime as DT\nfrom datetime import date as D\nfrom datetime import timedelta as TD\nfrom datetime import timezone as TZ\n\n\n\n\n\"\"\" * EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\"\"\"\n\n\nweek_days = [\"Lunes\",\"Martes\",\"Miércoles\",\"Jueves\",\"Viernes\",\"Sábado\",\"Domingo\"]\nmonths =[\"Enero\",\"Febrero\",\"Marzo\",\"Abril\",\"Mayo\",\"Junio\",\"Julio\",\"Agosto\",\"Septiembre\",\"Octubre\",\"Noviembre\",\"Diciembre\"]\ncurrent_datetime = DT.now()#Con .now sobre datetime generamos un objeto datetime con la fecha y hora actual del sistema\nutc_spain_timezone = TZ(TD(hours=+2))# Con el módulo timezone podemos definir una zona horaria uct concreta\nsillicon_valley_time = current_datetime.astimezone(TZ(TD(hours=-7)))#Con .astimezone le pasamos el objeto timezone con la diferencia horaria definida\n                                                                    # en un timedelta \ncurrent_date = D.today()#Con .today sobre date generamos un objeto date con la fecha actual del sistema (similar a .now sobre datetime)\nformat_current_date = D.today().strftime('%A, %d-%B-%Y')#Con .strftime sobre date generamos un string formateado \"a la carta\"\nformat_manual_time = DT.strptime('20-05-1998 22:15:30', '%d-%m-%Y %H:%M:%S')#Con .strptime generamos un objeto datetime a partir de un string\nformat_manual_time2 = 'Formateo desde datetime: {}/{}/{}'.format(DT.now().day,DT.now().month,DT.now().year)\nformat_manual_time3 = 'Formateo desde date: {}/{}/{}'.format(D.today().day,D.today().month,D.today().year)\n#Con .format a partir de una combinación de objetos datetime o date generamos la fecha, hora o ambas en string\nweek_day = week_days[format_manual_time.weekday()] #Con .weekday nos devuelve un número que corresponde al día de la semana donde 1 es el lunes..\ncurrent_week_day = week_days[current_date.weekday()]# Aplicando ese número como índice de una lista con los días podemos generar el día en texto\n\ncurrent_year = current_date.year #Cada objeto date nos permite acceder indivudualmente a cada componente de la fecha\ncurrent_month = months[current_date.month-1]# Como cada componente lo devuelve en un int podemos usarlo como índice de una lista\ncurrent_day = current_date.day\ncurrent_hour = current_datetime.hour# Con los objetos datetime tambien podemos acceder a cada componente de fecha y hora\ncurrent_minute = current_datetime.minute\ncurrent_second = current_datetime.second\nmy_age = current_datetime - format_manual_time#Podemos operar con 2 objetos datetime que nos devuelve la operación en un objeto timedelta\nmy_age_years = int(my_age.days//365.25)# El timedelta nos devuelve un objeto con el total del intervalo temporal en días, horas,minutos y segundos con decimales\n#Los objetos timedelta tambien proveen de métodos para separar solo los días (.days) o la franja sobrante de tiempo en segundos (.seconds)\n\n\nprint(\"Fecha y hora en España:\",current_datetime,\"\\n\",\n    \"Fecha y hora en Sillicon Valley (USA):\", sillicon_valley_time,\"\\n\",\n        current_hour, \":\",\n        current_minute, \":\",\n        current_second, \"\\n\",\n        format_current_date, \"\\n\",\n        format_manual_time, week_day, \"\\n\",\n        format_manual_time2 , \"\\n\",\n        format_manual_time3 , \"\\n\",\n        my_age_years, \"años\\n\",\n        \"Objeto timedelta completo: \",my_age, '\\n',\n        my_age.days, \"días\\n\",\n        \n        \"Zona horaria España:\", utc_spain_timezone , \"\\n\",        \n        \"\\n\\n\\n\"\n        )\nos.system('pause')\n\n\ndef input_data()->D:\n    while True:\n        year = input(\"Escriba su año de nacimiento: \")\n        if not year.isdigit or len(year)!=4:\n            print (\"ERROR: El año debe ser numérico de 4 cifras\")\n            continue\n        elif int(year)<1900:\n            print (\"Aunque seas demasiado viejo no creo que hayas nacido antes de 1900, intenta otro año posterior\")\n            continue\n        elif int(year)>=D.today().year -3 and int(year)<= D.today().year:\n            print(\"Te has debido equivocar de año porque un bebé no sabe teclear en un ordenador, intenta de nuevo\")\n            continue\n        elif int(year)>D.today().year:\n            print(\"A no ser que vengas del futuro no puedes poner un año que aun no ha llegado, intenta de nuevo\")\n            continue\n        while True:\n            month = input(\"Escriba el mes de nacimiento: \")\n            if  not month.isdigit or len(month)>2 or len(month)<=0:\n                print (\"ERROR: El mes debe ser numérico de 1 o 2 cifras\")\n                continue\n            elif int(month)<1 or int(month)>12:\n                print (\"ERROR: El mes no debe ser menor a 0 ni mayor a 12\")\n                continue\n            while True:\n                day = input(\"Escriba el día de nacimiento: \")\n                if not day.isdigit or len(day)>2 or len(day)<=0:\n                   print (\"ERROR: El día debe ser numérico de 1 o 2 cifras\")\n                   continue\n                elif int(month)==4 or int(month)==6 or int(month)==9 or int(month)==11 and int(day)>30:\n                    print (f\"El mes de {months[int(month)-1]} no puede tener más de 30 días\") \n                    continue\n                elif int(day)<1 or int(day)>31:\n                   print (\"ERROR: El día no debe ser menor a 0 ni mayor a 31\")\n                   continue\n                if ((int(year) % 4 != 0) and ((int(year) % 100 == 0) or (int(year) % 400 != 0)) and int(month)==2 and int(day)>28):\n                    print (f\"El año {year} no fue bisiesto y febrero no puede tener más de 28 días\")\n                    break\n                return D(int(year),int(month),int(day))\n  \n\ndef show_data(date_object:D):\n    str_date = str(f\"{date_object.day}-{date_object.month}-{date_object.year}\")\n    format_date = DT.strptime(str_date, '%d-%m-%Y')\n    my_age = DT.now() - format_date\n    my_age_years = int(my_age.days//365.25)\n    beginning_year = D(D.today().year,1,1)\n    days_passed = D.today() - beginning_year\n    weeks_passed = days_passed.days//7+1\n\n    print(f\"\\nHoy es {current_week_day} día {DT.now().day} de {current_month} de {DT.now().year}\")\n    print(f\"Y son las {DT.now().hour} horas y {DT.now().minute} minutos\\n\")\n    print(f\"Estamos en la semana {weeks_passed} y en el día {days_passed.days+1} de {D.today().year}\\n\")\n    if DT.now().hour>=6 and DT.now().hour<12:\n      print(\"¡¡Buenos días!!\\n\")\n    elif DT.now().hour>=12 and DT.now().hour<=20:\n        print(\"¡¡Buenas tardes!!\\n\")\n    else:\n        print(\"¡¡Buenas noches!!\\n\")\n\n    print(f\"Como has indicado que naciste el día {date_object.day} de {months[date_object.month-1]} de {date_object.year} ...\\n\")\n    print(\"... (por cierto naciste un\", week_days[format_date.weekday()],\")\\n\")\n    if DT.now().day == date_object.day and DT.now().month == date_object.month:\n            print(f\"¡¡¡FELICIDADES!!! hoy cumples {my_age_years} años, casi nada\\n\")\n    else:\n            print(f\"...tienes {my_age_years} años\")\n\nshow_data(input_data())\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/JheisonQuiroga.py",
    "content": "from datetime import datetime, timedelta\n\n\"\"\"\n/*\n * EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n\"\"\"\n\nnow = datetime.now()\nprint(now) # 2025-01-25 11:53:25.911556\n\nmy_birthdate = datetime(1998, 6, 19, 12, 0, 0)\ndifference = now - my_birthdate\nyears = difference.days / 365\n\nprint(\"La diferencia en años es de: %.2f\" %years) # La diferencia en años es de: 26.62\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n */\n\"\"\"\n\n# Dia, mes y año\nprint(my_birthdate)\nprint(\"Dia, mes y año:\", my_birthdate.strftime(\"%d, %m, %Y\"))\n# Hora, minuto y segundo\nprint(\"Hora, minuto y segundo:\", my_birthdate.strftime(\"%H - %M - %S\"))\n# Dia de año\nprint(\"Dia de año:\", my_birthdate.strftime(\"%j\")) # 170\n# Dia de la semana\nprint(\"Dia de la semana:\", my_birthdate.strftime(\"%A\")) # Friday\nprint(\"Dia de la semana:\" , my_birthdate.strftime(\"%w\")) # 5\n# Nombre del mes\nprint(\"Nombre del mes:\", my_birthdate.strftime(\"%B\")) # June\n\n# Hora\nprint(\"Hora:\", my_birthdate.strftime(\"%I:%M:%S %p\")) # 12:00 PM\n\n# Semana del año\nprint(\"Semana del año:\", my_birthdate.strftime(\"%U\")) # 24\n\n# Fecha-Hora local\nprint(\"Hora local:\", my_birthdate.strftime(\"%c\")) # Fri Jun 19 12:00:00 1998\n\n# Fecha local\nprint(\"Fecha local:\", my_birthdate.strftime(\"%x\")) # 06/19/98"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/JuanDAW37.py",
    "content": "\"\"\"* EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\"\"\"\n\nfrom datetime import datetime\nimport locale\n\nhoy = datetime.now()\nfecha_de_nacimiento = datetime(1968,5,1,15,30,0)\nanios = ((hoy - fecha_de_nacimiento).days) // 365\n\nprint(f'Hoy-> {hoy}')\nprint(f'Fecha de nacimiento-> {fecha_de_nacimiento}')\nprint(f'Tengo {anios} años')\n\n#EXTRA\n\n# Locale\nlocale.setlocale(locale.LC_ALL, 'es-ES')\n\n# Día, mes y año\nprint(f'Día de mi cumpleaños: {fecha_de_nacimiento.day}/{fecha_de_nacimiento.month}/{fecha_de_nacimiento.year}')\nprint(fecha_de_nacimiento.strftime('%d-%m-%Y'))\n\n# Horas, minutos y segundos\nprint(f'Horas, minutos y segundos: {fecha_de_nacimiento.hour}:{fecha_de_nacimiento.minute}:{fecha_de_nacimiento.second}')\nprint(fecha_de_nacimiento.strftime('%H:%M:%S'))\nprint(fecha_de_nacimiento.strftime('%H:%m %p'))\n\n# Día del año\nprint(f'Día del año: {fecha_de_nacimiento.timetuple().tm_yday}')\nprint(fecha_de_nacimiento.strftime('%j'))\n\n# Día de la semana\nprint(f'Día de la semana: {fecha_de_nacimiento.strftime(\"%A\")}')\n\n# Nombre del mes\nprint(f'Nombre del mes: {fecha_de_nacimiento.strftime(\"%B\")}')"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/KevinED11.py",
    "content": "from datetime import datetime\nimport random\nimport functools\nfrom typing import Iterable, Final\n\n\ndef date_format(date: datetime, format: str = \"%A, %d de %B de %Y - %I:%M %p\") -> str:\n    return f\"{date:{format}}\"\n\n\ndef date_formats(date: datetime, formats: Iterable[str]) -> list[str]:\n    return [date_format(date=date, format=format) for format in formats]\n\n\ndef calculate_year_difference(date1: datetime, date2: datetime) -> int:\n    return abs((date1 - date2).days) // 365\n\n\n@functools.lru_cache(maxsize=25)\ndef available_date_formats() -> list[str]:\n    return [\n        \"%Y-%m-%d\",  # Año-Mes-Día\n        \"%d/%m/%Y\",  # Día/Mes/Año\n        \"%B %d, %Y\",  # Mes Nombre Día, Año\n        \"%A, %d %B %Y\",  # Día de la semana, Día Mes Nombre Año\n        \"%Y-%m-%d %H:%M:%S\",  # Año-Mes-Día Hora:Minuto:Segundo\n        \"%d-%m-%Y %H:%M\",  # Día-Mes-Año Hora:Minuto\n        \"%Y/%m/%d %H:%M:%S\",  # Año/Mes/Día Hora:Minuto:Segundo\n        \"%A, %d de %B de %Y\",  # Día de la semana, Día de Mes Nombre Año\n        \"%d/%m/%Y %H:%M:%S\",  # Día/Mes/Año Hora:Minuto:Segundo\n        \"%Y-%m-%d %H:%M:%S.%f\",  # Año-Mes-Día Hora:Minuto:Segundo.Microsegundos\n    ]\n\n\ndef choice_random_elements[T](elements: Iterable[T], quantity: int) -> list[T]:\n    return random.sample(population=elements, k=quantity)\n\n\ndef display_formatted_date_in_various_ways(date: datetime, quantity: int = 10) -> None:\n    MAXIMUM_ALLOWED_FORMATS: Final[int] = 10\n\n    if quantity > MAXIMUM_ALLOWED_FORMATS:\n        print(\"la cantidad maxima de fechas a imprimir es 10\")\n\n    quantity = min(quantity, MAXIMUM_ALLOWED_FORMATS)\n    available_formats = available_date_formats()\n    display_random_formats = choice_random_elements(\n        elements=available_formats, quantity=quantity\n    )\n\n    final_representation = date_formats(date=date, formats=display_random_formats)\n\n    print(*final_representation, sep=\"\\n\")\n\n\ndef main() -> None:\n    current_date = datetime.now()\n    BIRTH_DATE = datetime(\n        year=2001, month=2, day=11, hour=5, minute=10, second=30, microsecond=0\n    )\n    print(date_format(date=current_date))\n    print(date_format(date=BIRTH_DATE))\n    print(calculate_year_difference(date1=current_date, date2=BIRTH_DATE))\n    display_formatted_date_in_various_ways(date=BIRTH_DATE, quantity=20)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/LucasRebuffo.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n */ \"\"\"\n\n\nfrom datetime import datetime\n\nnow = datetime.now()\nprint(now)\nbirth_date = datetime.strptime(\"10-02-1997 10:00:02\", \"%d-%m-%Y %H:%M:%S\" )\nprint(birth_date)\n\ndiff_dates = now - birth_date\nprint(diff_dates)\n\n\n\"\"\" * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n */  \"\"\"\n\nprint(birth_date.strftime(\"%d-%m-%Y\"))\nprint(birth_date.strftime(\"%H:%M:%S\"))\nprint(birth_date.strftime(\"%-j\"))\nprint(birth_date.strftime(\"%B\"))\nprint(birth_date.strftime(\"%x\"))\nprint(birth_date.strftime(\"%A\"))\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/Lumanet.py",
    "content": "from datetime import datetime\nhoy = datetime.now()\nprint(hoy)\nfecha_nacimiento = datetime(1982, 2, 20, 20, 30, 23)\n\naños = hoy - fecha_nacimiento\n\nprint(f\"Tengo {años.days // 365} años.\")\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\nUtilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n10 maneras diferentes. Por ejemplo:\n- Día, mes y año.\n- Hora, minuto y segundo.\n- Día de año.\n- Día de la semana.\n- Nombre del mes.\n(lo que se te ocurra...)\n\"\"\"\n\nprint(fecha_nacimiento.strftime(\"%d/%m/%y\")) # 20/02/82\nprint(fecha_nacimiento.strftime(\"%d/%m/%Y\")) # 20/02/1982\nprint(fecha_nacimiento.strftime(\"%d/%B/%Y\")) # 20/February/1982\nprint(fecha_nacimiento.strftime(\"%H:%M:%S\")) # 20:30:23\nprint(fecha_nacimiento.strftime(\"%j\")) # 051 (día del año)\nprint(fecha_nacimiento.strftime(\"%A\")) # Saturday (nombre del día de la semana)\nprint(fecha_nacimiento.strftime(\"%h\")) # Feb (nombre del mes)\nprint(fecha_nacimiento.strftime(\"%B\")) # February (nombre del mes)\nprint(fecha_nacimiento.strftime(\"%p\")) # February (nombre del mes)\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/Nicojsuarez2.py",
    "content": "# #14 FECHAS\n> #### Dificultad: Fácil | Publicación: 01/04/24 | Corrección: 08/04/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/Nightblockchain30.py",
    "content": "#  * EJERCICIO:\n#  * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n#  * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n#  * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n#  * Calcula cuántos años han transcurrido entre ambas fechas.\n\nfrom datetime import datetime\n\ncurrent_date = datetime.now()\nbirthday_date = datetime(1997,5,10,16,30,0)\n\nprint(current_date)\nprint(birthday_date)\n\ndifference = current_date - birthday_date\nprint(difference.days)\n\nyears = (difference.days // 365)\nprint(f\"I´m {years} old \")\n\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n#  * 10 maneras diferentes. Por ejemplo:\n#  * - Día, mes y año.\n#  * - Hora, minuto y segundo.\n#  * - Día de año.\n#  * - Día de la semana.\n#  * - Nombre del mes.\n#  * (lo que se te ocurra...)\n\n\nformat1 = birthday_date.strftime(\"%d-%m-%y\")\nprint(format1)\nformat2 = birthday_date.strftime(\"%d-%m-%Y\")\nprint(format2)\nformat3 = birthday_date.strftime(\"%a-%B-%Y\")\nprint(format3)\nformat4 = birthday_date.strftime(\"%Y-%m-%d\")\nprint(format4)\nformat5 = birthday_date.strftime(\"%d-%m-%Y T%H:%M:%S\")\nprint(format5)\nformat6 = birthday_date.strftime(\"%A-%B-%Y\")\nprint(format6)\nformat7 = birthday_date.strftime(\"%d-%m-%Y %H:%M:%S %p\")\nprint(format7)\nformat8 = birthday_date.strftime(\"%A-%B-%Y %p\")\nprint(format8)\nformat9 = birthday_date.strftime(\"%f\")\nprint(format9)\nformat10 = birthday_date.strftime(\"%j\")\nprint(format10)\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/Sac-Corts.py",
    "content": "### Ejercicio ###\nfrom datetime import datetime\n\nnow = datetime.now()\nprint(now)\n\nmy_birthday = datetime(2001, 10, 21, 5, 30, 15)\nprint(my_birthday)\n\ndifference = now - my_birthday\nprint(difference)\n\n### Ejercicio Extra ###\n\nprint(my_birthday.strftime(\"%d/%m/%Y\"))\nprint(my_birthday.strftime(\"%d-%m-%Y\"))\nprint(my_birthday.strftime(\"%B %d, %Y\"))\nprint(my_birthday.strftime(\"%H:%M:%S %p\"))\nprint(my_birthday.strftime(\"%X %p\"))\nprint(my_birthday.strftime(\"%c\"))\nprint(my_birthday.strftime(\"%x\"))\nprint(my_birthday.strftime(\"%A\"))\nprint(my_birthday.strftime(\"%j\"))\n\nmy_next_birthday = datetime(2024, 10, 21)\ntime_left = my_next_birthday - now\ndays = time_left.days\nprint(f\"¡Faltan {days} días para mi cumpleaños!\")"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/SaezMD.py",
    "content": "#14 - Fechas\n\"\"\"\n * EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n\"\"\"\n\nfrom datetime import datetime, date\n\ntoday = datetime.today()\ntodayDatef = datetime.today().strftime('%d/%m/%Y %H:%M:%S')\nprint(todayDatef)\n\nbirthdayDate = datetime(2012, 12, 22,13,22,5)\nbirthdayDatef = birthdayDate.strftime('%d/%m/%Y %H:%M:%S')\nprint(birthdayDatef)\n\ndiffYears = today - birthdayDate\n\nprint(f\"Diff of dates: {int((diffYears.days/365))} years.\")\n\n\n#EXTRA\nprint(\"EXTRA, more formats:\")\nprint(birthdayDate.strftime('%H:%M:%S'))\nprint(birthdayDate.strftime('%a'))\nprint(birthdayDate.strftime('%A'))\nprint(birthdayDate.strftime('%b'))\nprint(birthdayDate.strftime('%B'))\nprint(birthdayDate.strftime('%w'))\nprint(birthdayDate.strftime('%H:%M:%S %p'))\nprint(birthdayDate.strftime('%j'))\nprint(birthdayDate.strftime('%U'))\nprint(birthdayDate.strftime('%c'))\n\n\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/SooHav.py",
    "content": "# 14 - Fechas\n\n# Ejercicio\n\nfrom datetime import datetime, date\nimport locale\n# print(locale.locale_alias)\n\n# Día actual\nprint(\"Fecha actual:\")\ntoday = date.today()\n# Fecha actual\nnow = datetime.now()\nprint(today)\nprint(now)\n\nprint()\nprint(\"Fecha de mi cumpleaños:\")\n# Fecha cumpleaños\nfecha_cumpleaños = date(1978, 2, 26)\nfecha_cumpleaños_hora = datetime(1978, 2, 26, 12, 10)\nprint(fecha_cumpleaños)\nprint(fecha_cumpleaños_hora)\nprint(fecha_cumpleaños_hora.isoformat())\nprint(fecha_cumpleaños_hora.strftime(\"%Y-%m-%d %H:%M:%S\"))\n\n# Ejercicio Extra\nprint()\nprint(\"Otras variantes de mi cumpleaños:\")\nprint(fecha_cumpleaños_hora.strftime(\"%d-%m-%Y\"))\nprint(fecha_cumpleaños_hora.strftime(\"%d/%m/%Y\"))\nprint(fecha_cumpleaños_hora.strftime(\"%d-%m-%Y %I:%M %p\"))\nprint(fecha_cumpleaños_hora.strftime(\"%Y/%m/%d %H:%M:%S\"))\nprint(fecha_cumpleaños_hora.strftime(\"%d %B %Y\"))\nprint(fecha_cumpleaños_hora.strftime(\"%A %d %B %Y %I:%M\"))\nprint(fecha_cumpleaños_hora.strftime(\"%A %d %B %Y\"))\nprint(fecha_cumpleaños_hora.strftime(\"%a, %d %b %Y\"))\nprint(fecha_cumpleaños_hora.strftime(\"%A, %d %b %Y %H:%M:%S\"))\nprint(fecha_cumpleaños_hora.strftime(\"Fecha: %d-%m-%Y, Hora: %H:%M:%S\"))\n# Cambiar a configuración regional española\nlocale.setlocale(locale.LC_ALL, 'es_AR.utf8')\nprint(fecha_cumpleaños_hora.strftime(\"%A %d %B %Y %I:%M\"))\nprint(fecha_cumpleaños_hora.strftime(\"%A %d de %B de %Y - %H:%M\"))\nprint(fecha_cumpleaños_hora.strftime(\"%A, %d de %B de %Y\"))\nprint()\nprint(\"Otros formatos de la fecha cumpleaños:\")\n# Calcular el día juliano\ndia_juliano = fecha_cumpleaños_hora.timetuple().tm_yday\n# Mostrar la fecha en días julianos\nprint(f\"Mi cumple en días Juliano es el: {dia_juliano}\")\nprint(\"¿Cuándo es tu cumpleaños?\")\nprint(f\"Cumplo el {fecha_cumpleaños_hora.strftime('%d de %B')}\")\n\n\"\"\"\nAyuda:\n%a\tDía de la semana abreviado:\tlu., ma., …\n%A\tDía de la semana completo:\tlunes, martes, …\n%w\tDía de la semana como número decimal:\t0, 1, … 6\n%d\tDía del mes como número decimal con cero:\t01, 02, …, 31\n%b\tMes abreviado:\tene., feb., …\n%B\tMes completo:\tenero, febrero, …\n%m\tMes como número decimal con cero:\t01, 02, …12\n%Y\tAño en formato de cuatro dígitos:\t0001, 0002, …, 2020, 2021, …\n%H\tHora en formato 24h. con dos dígitos:\t00, 01, …, 23\n%I\tHora en formato 12h. con dos dígitos:\t01, 02, …, 12\n%M\tMinutos en formato de dos dígitos:\t00, 01, …, 59\n%S\tSegundos en formato de dos dígitos:\t00, 01, …, 59\n\"\"\"\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/a-mayans.py",
    "content": "from datetime import datetime\n\n# Variables de tipo date\ncurrent_date = datetime.now()\nbirth_date = datetime(1993, 10, 13, 23, 00, 00)\n\n# Cálculo del tiempo transcurrido entre ambas fechas\ndifference = current_date - birth_date\nyears_elapsed = difference.days // 365\nprint(f'Los años transcurridos desde tu nacimiento hasta hoy son un total de: {years_elapsed}')\n\n# ------------------\n## DIFICULTAD EXTRA\n# ------------------\n\nformatting = [\n    \"%d/%m/%Y\",                # Día, mes y año\n    \"%H:%M:%S\",                # Hora, minuto y segundo\n    \"%j\",                      # Día de año\n    \"%A\",                      # Día de la semana\n    \"%B\",                      # Nombre del mes\n    \"%Y-%m-%d\",                # Año-mes-día\n    \"%I:%M %p\",                # Hora en formato 12 horas con AM/PM\n    \"%Y-%m-%d %H:%M:%S\",       # Año-mes-día Hora:minuto:segundo\n    \"%b %d, %Y\",               # Abreviatura del mes, día, año (May 25, 2000)\n    \"%A, %d %B %Y %I:%M %p\"    # Día de la semana, día, nombre del mes, año, hora en formato 12 horas con AM/PM\n]\n\nfor format in formatting:\n  print(birth_date.strftime(format))\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/adolfolozaa.py",
    "content": "'''\r\nEJERCICIO:\r\n * Crea una función que se encargue de sumar dos números y retornar\r\n * su resultado.\r\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\r\n * capaz de determinar si esa función se ejecuta correctamente.\r\n'''\r\nimport unittest\r\n\r\ndef sum(a, b):\r\n    if not isinstance(a, (int, float)) or not isinstance(b, (int, float)):\r\n        raise ValueError(\"Los argumentos deben ser enteros o decimales.\")\r\n    return a + b\r\n\r\n\r\nclass TestSum(unittest.TestCase):\r\n\r\n    def test_sum(self):\r\n        self.assertEqual(sum(5, 7), 12)\r\n        self.assertEqual(sum(5, -7), -2)\r\n        self.assertEqual(sum(0, 0), 0)\r\n        self.assertEqual(sum(2.5, 2.1), 4.6)\r\n        self.assertEqual(sum(2, 2.1), 4.1)\r\n        self.assertEqual(sum(2.5, 2.5), 5)\r\n\r\n    def test_sum_type(self):\r\n        with self.assertRaises(ValueError):\r\n            sum(\"5\", 7)\r\n        with self.assertRaises(ValueError):\r\n            sum(5, \"7\")\r\n        with self.assertRaises(ValueError):\r\n            sum(\"5\", \"7\")\r\n        with self.assertRaises(ValueError):\r\n            sum(\"a\", 7)\r\n        with self.assertRaises(ValueError):\r\n            sum(None, 7)\r\n#unittest.main()\r\n\r\n\r\n'''\r\n * DIFICULTAD EXTRA (opcional):\r\n * Crea un diccionario con las siguientes claves y valores:\r\n * \"name\": \"Tu nombre\"\r\n * \"age\": \"Tu edad\"\r\n * \"birth_date\": \"Tu fecha de nacimiento\"\r\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\r\n * Crea dos test:\r\n * - Un primero que determine que existen todos los campos.\r\n * - Un segundo que determine que los datos introducidos son correctos.'''\r\n\r\nfrom datetime import datetime, date\r\n\r\n\r\nclass TestData(unittest.TestCase):\r\n\r\n    def setUp(self) -> None:\r\n        self.data = {\r\n            'name': 'Adolfo',\r\n            'age': 56,\r\n            \"birth_date\": datetime.strptime(\"29-04-87\", \"%d-%m-%y\").date(),\r\n            'programing_languages': ['Python', 'Basic', 'C']\r\n        }\r\n\r\n    def test_fields_exist(self):\r\n        self.assertIn(\"name\", self.data)\r\n        self.assertIn(\"age\", self.data)\r\n        self.assertIn(\"birth_date\", self.data)\r\n        self.assertIn(\"programing_languages\", self.data)\r\n\r\n    def test_data_is_correct(self):\r\n        self.assertIsInstance(self.data[\"name\"], str)\r\n        self.assertIsInstance(self.data[\"age\"], int)\r\n        self.assertIsInstance(self.data[\"birth_date\"], date)\r\n        self.assertIsInstance(self.data[\"programing_languages\"], list)\r\n\r\n\r\nunittest.main()\r\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/adra-dev.py",
    "content": "\"\"\"\nEJERCICIO:\nCrea dos variables utilizando los objetos fecha(date, o semejante) de\ntu lenguaje:\n- Una primera que represente la fecha (día, mes, año, hora, minuto, \nsegundo) actual.\n- Una segunda que represente tu fecha de nacimiento (te puedes \ninventar la hora).\nCalcula cuántos años han transcurrido entre ambas fechas.\n\nDIFICULTAD EXTRA (opcional):\nUtilizando la fecha de tu cumpleaños, formatéala y muestra su \nresultado de 10 maneras diferentes. Por ejemplo:\n- Día, mes y año.\n- Hora, minuto y segundo.\n- Día de año.\n- Día de la semana.\n- Nombre del mes.\n(lo que se te ocurra...)\n\nby adra-dev\n\"\"\"\n\n\"\"\"\nEjercicio\n\"\"\"\n \n\"\"\"\nFechas:\nUna fecha en python no es un tipo de dato por si solo, pero podemos \nimportar un modulo llamado datetime para trabajar con fechas como \nobjetos tipo fecha. El modulo date tiem tiene muchos metehodos para \ndevolver informaicon acerca del objeto fecha. puedes consultarlos en\nla documentacion https://docs.python.org/3/library/datetime.html o\nen https://www.w3schools.com/python/python_datetime.asp\n\"\"\"\nimport datetime \n\ntoday = datetime.datetime.now()\nbirthday_day = datetime.datetime(1998, 2, 12, 12, 00, 00)\n\ndef years():\n    return today.year - birthday_day.year\n\n\ninterval = years()\n\nprint(interval)\n\n\n\"\"\"\nExtra\n\"\"\"\n\n\"\"\"\nLos objetos datetime cuentan con un metodo para otorgarles el formato\nstring de una manera legible. el metodo se llama strftime() y toma un\nparametro, format, para especificar el formato en el que se devuelve\ndicho string.\n\nTip:\nEsto es epecialmente util conocerlo en el Analisis de Datos ya que \nmuchas veces se trabaja con este formato, librerias como pandas o \npolars incluyen sus propios estandares para representar y trabajar \ncon fechas pero suelen ser muy similares a los objetos datetime.\n\"\"\"\n\nprint()\nprint(\"Extra\")\nprint(\"Dia de la semana version corta: \", birthday_day.strftime( \"%a\"))      \nprint(\"Dia de la semana completa: \", birthday_day.strftime(\"%A\"))      \nprint(\"Dia de la semana como numero: \",birthday_day.strftime(\"%w\"))\nprint(\"Dia del mes: \", birthday_day.strftime(\"%d\")) \nprint(\"Nombre del mes corto: \", birthday_day.strftime(\"%b\"))\nprint(\"Nombre del mes completo: \", birthday_day.strftime(\"%B\"))\nprint(\"Mes como numero: \", birthday_day.strftime(\"%m\"))\nprint(\"Año version corta sin siglo: \", birthday_day.strftime(\"%y\"))\nprint(\"Año version completa: \", birthday_day.strftime(\"%Y\"))\nprint(\"Hora: \", birthday_day.strftime(\"%H\"))\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/agusrosero.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n */\n\"\"\"\nimport datetime\n\n# EJERCICIO:\nfecha_actual = datetime.datetime.now().strftime('%d-%m-%Y %H:%M:%S')\nfecha_formateada_datetime = datetime.datetime.strptime(\n    fecha_actual, '%d-%m-%Y %H:%M:%S')\n\nfecha_nacimiento = datetime.datetime(2000, 8, 3, 7, 30)\n\n# Calcular la diferencia\ndiferencia = fecha_formateada_datetime - fecha_nacimiento\n\n# Obtener la diferencia en años\ndias = diferencia.days\nprint(f'Años transcurridos: {dias // 365}')\n\n# DIFICULTAD EXTRA:\nprint('Día, mes y año:', fecha_nacimiento.strftime('%d-%m-%Y'))\nprint('Hora, minuto y segundo:', fecha_nacimiento.strftime('%H:%M:%S'))\nprint('Día de año:', fecha_nacimiento.timetuple().tm_yday)\nprint('Día de la semana:', fecha_nacimiento.strftime('%A'))\nprint('Nombre del mes:', fecha_nacimiento.strftime('%B'))\nprint('Semana del año:', fecha_nacimiento.strftime('%U'))\nprint('Hora completa:', fecha_nacimiento.strftime('%T'))\nprint('Año:', fecha_nacimiento.strftime('%Y'))\nprint('Año-mes-dia hora-minuto-segundos-milisegundos:',\n      fecha_nacimiento.strftime('%Y-%m-%d %H:%M:%S.%f'))\nprint('Hora, minuto, segundos, am/pm:',\n      fecha_nacimiento.strftime('%H:%M:%S %p'))\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/alanshakir.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n */\n\"\"\"\nfrom datetime import datetime\nnow = datetime.now()\nbirth_date = datetime(1985, 1, 20, 15, 10, 33)\nprint(now)\nprint(birth_date)\n\nyear = now - birth_date\nprint(f\"Han transcurrido {year.days//365} años\")\n\n#Extra\n\n#1 Día, mes y año.\nprint(birth_date.strftime(\"%d/%m/%Y\"))\n#2 Hora, minuto y segundo.\nprint(birth_date.strftime(\"%H:%M:%S\"))\n#3 Día de año.\nprint(birth_date.strftime(\"%j\"))\n#4 Día de la semana.\nprint(birth_date.strftime(\"%A\"))\n#5 Nombre del mes.\nprint(birth_date.strftime(\"%B\"))\n#6 semana del año\nprint(birth_date.strftime(\"%U\"))\n#7 nombre del mes abreviado\nprint(birth_date.strftime(\"%a\"))\n#8 hora en formato 00-12\nprint(birth_date.strftime(\"%I\"))\n#9 Nombre del mes (corto)\nprint(birth_date.strftime(\"%b\"))\n#10 AM/PM\nprint(birth_date.strftime(\"%p\"))\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/alcaan16.py",
    "content": "\"\"\"/*\n * EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n */\"\"\"\nfrom datetime import datetime\n#from datetime import timedelta\n\nnow = datetime.now()# momento actual\n\nprint(now)\n\nbirth_date = datetime(1989,11,16,16,21) #indicamos una fecha en concreto\n\nprint(birth_date)\n\ndiferencia = now-birth_date #diferencia entre fechas en dias \n\nprint(diferencia)\n\nprint(f\"tengo {diferencia.days // 365} años\")#IMPORTANTE!! ponemos doble // para poner valor absoluto sin decimales\n\n\n# EXTRA\n\nprint(birth_date.strftime(\"%d %m %y\")) #formato español de fecha\nprint(birth_date.strftime(\"%d %m %Y\")) #formato año 4 digitos\nprint(birth_date.strftime(\"%a\")) #formato dia de la semana\nprint(birth_date.strftime(\"%j\")) #formato dia del año\nprint(birth_date.strftime(\"%B\")) #formato del mes\nprint(birth_date.strftime(\"%c\")) #formato completo ingles\nprint(birth_date.strftime(\"%x\")) #formato local\nprint(birth_date.strftime(\"%X\")) #formato local"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/alexdevrep.py",
    "content": "'''\n/*\n * EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n */\n'''\n#Importamos las librerías necesarias\nfrom datetime import datetime\n\n\n#Variable con la fecha actual\nhoy = datetime.now()\nprint(hoy)\n\n#Variable con la fecha de mi cumpleaños\nfecha_nacimiento= datetime(1999,7,22,10,30,22,00000)\nprint(fecha_nacimiento)\n\n#Comprobamos cuanto tiempo ha transcurrido\nedad= hoy - fecha_nacimiento\nprint(edad)\n\n#Dificultad EXTRA\nformato1=fecha_nacimiento.strftime('%d/%m/%Y') #Día mes año\nformato2=fecha_nacimiento.strftime('%H/%M/%S') #Horas minutos segundos\nformato3=fecha_nacimiento.strftime('%j') #Día del año\nformato4=fecha_nacimiento.strftime('%A') #Nombre del día de la semana\nformato5=fecha_nacimiento.strftime('%B') #Nombre completo del mes\nformato6=fecha_nacimiento.strftime('%p') #AM o PM\nformato7=fecha_nacimiento.strftime('%U') #Semana del año\nformato8=fecha_nacimiento.strftime('%w') #Día de la semana en número\nformato9=fecha_nacimiento.strftime('%a') #Nombre abreviado del día de la semana \nformato10=fecha_nacimiento.strftime('%y') #Año con dos dígitos\n\nprint(formato1)\nprint(formato2)\nprint(formato3)\nprint(formato4)\nprint(formato5)\nprint(formato6)\nprint(formato7)\nprint(formato8)\nprint(formato9)\nprint(formato10)\n\n\n\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/any7dev.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n */ \"\"\"\n\n#EJERCICIO\nimport datetime \n\nfecha_actual = datetime.datetime.now()\nfecha_nacimiento = datetime.datetime(1988, 3, 11, 15, 0, 0)\nprint(fecha_actual.year - fecha_nacimiento.year)\n\n#DIFICULTAD EXTRA\nprint(fecha_nacimiento.strftime(\"%d-%m-%y\")) #1\nprint(fecha_nacimiento.strftime(\"%H:%M:%S\")) #2\nprint(fecha_nacimiento.timetuple()[7])#3\nprint(fecha_nacimiento.isoweekday())#4\nprint(fecha_nacimiento.strftime(\"%B\"))#5\nprint(fecha_nacimiento.ctime())#6\nprint(fecha_nacimiento.strftime(\"%A, %d. %B %Y %I:%M%p\"))#7\nprint(fecha_nacimiento.isocalendar()[1]) #8 Número de la semana\nprint(fecha_nacimiento.strftime(\"%d %m %Y\")) #9\nprint(fecha_nacimiento.toordinal())#10 Ordinal gregoriano proléptico de la fecha\n\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/avcenal.py",
    "content": "\"\"\"\nEJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n\"\"\"\nfrom datetime import datetime,date\n\nnow = datetime.now()\nbirthdate = datetime(day=19,month=12,year=1984,hour=23,minute=50,second=00)#también se puede hacer datetime(1984,12,19,23,50,00)\ndiff = abs(now-birthdate)\nprint(f\"La diferencia entre la fecha actual y mi compleaños es: {diff}\")\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n\"\"\"\nweekdays = [\"Lunes\",\"Martes\",\"Miércoles\",\"Jueves\",\"Viernes\",\"Sábado\",\"Domingo\"]\nmonths = [\"none\",\"Enero\",\"Febrero\",\"Marzo\",\"Abril\",\"Mayo\",\"Junio\",\"Julio\",\"Agosto\",\"Septiembre\",\"Octubre\",\"Noviembre\",\"Diciembre\"]\n\nprint(f\"FECHA: {birthdate.day}/{birthdate.month}/{birthdate.year}\")\nprint(f\"HORA: {birthdate.timetz()}\")\nprint(f\"DÍA DEL AÑO: {birthdate.timetuple()[7]}\")\nprint(f\"DÍA DE LA SEMANA: {weekdays[birthdate.weekday()]}\")\nprint(f\"MES: {months[birthdate.month]}\")\nprint(f\"EN MILISEGUNDOS: {birthdate.timestamp()}\")\nprint(f\"INDICANDO LA ZONA HORARIA LOCAL(+1:00 H EN MADRID): {birthdate.astimezone()}\")\nprint(f\"EN FORMATO ISO: {birthdate.isoformat()}\")\nprint(f\"CADENBA EN LOCAL TIME: {birthdate.ctime()}\")\nprint(f\"ORDINAL DESDE EL 1 DE ENERO DEL AÑO 1: {birthdate.toordinal()}\")\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/barrancus.py",
    "content": "#\n#EJERCICIO:\n#Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n#- Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n#- Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n#Calcula cuántos años han transcurrido entre ambas fechas.\n#\n#DIFICULTAD EXTRA (opcional):\n#Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n#10 maneras diferentes. Por ejemplo:\n#- Día, mes y año.\n#- Hora, minuto y segundo.\n#- Día de año.\n#- Día de la semana.\n#- Nombre del mes.\n#(lo que se te ocurra...)\n#\nfrom datetime import datetime, date\n\nnow = datetime.now()\nbirth = datetime.strptime(\"25/05/1978 09:13:27\", \"%d/%m/%Y %H:%M:%S\")\ntime_elapsed = now.year - birth.year\nprint(f\"Desde {birth} hasta {now} han pasado {time_elapsed} años.\")\nprint(f\"{datetime.strftime(birth, \"%d/%m/%Y\")}\")\nprint(f\"{datetime.strftime(birth, \"%H/%M/%S\")}\")\nprint(f\"{datetime.isocalendar(birth)}\")\nprint(f\"{datetime.timestamp(birth)}\")\nprint(f\"{datetime.timetz(birth)}\")\nprint(f\"{datetime.timetuple(birth)}\")\nprint(f'{datetime.astimezone(birth)}')\nprint(f'{datetime.dst(birth)}')\nprint(f'{datetime.isoformat(birth, \"H\", 'minutes')}')\nprint(f'{datetime.toordinal(birth)}')\nprint(f'{datetime.weekday(birth)}')\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/cesar-ch.py",
    "content": "\"\"\"\n    #14 FECHAS\n\"\"\"\n\nfrom datetime import datetime\n\nfecha_actual = datetime.now()\nprint(fecha_actual.strftime(\"%d/%m/%Y %H:%M:%S\"))\n\nfecha_nacimiento = datetime(year=2005, month=4, day=15, hour=12, minute=00, second=00)\n\ndiferencia_dias = fecha_actual - fecha_nacimiento\n\naños_transcurridos = diferencia_dias.days // 365.25\n\nprint(f\"Han transcurrido {años_transcurridos} años.\")\n\n\"\"\"\n    DIFICULTAD EXTRA\n\"\"\"\n\n# 1. Día, mes y año\nday_month_year = fecha_nacimiento.strftime(\"%d/%m/%Y\")\nprint(f\"1. Día, mes y año: {day_month_year}\")\n\n# 2. Hora, minuto y segundo\nhora_minuto_segundo = fecha_nacimiento.strftime(\"%H:%M:%S\")\nprint(f\"2. Hora, minuto y segundo: {hora_minuto_segundo}\")\n\n# 3. Día del año\nday_year = fecha_nacimiento.strftime(\"%j\")\nprint(f\"3. Día del año: {day_year}\")\n\n# 4. Día de la semana\ndia_semana = fecha_nacimiento.strftime(\"%A\")\nprint(f\"4. Día de la semana: {dia_semana}\")\n\n# 5. Nombre del mes\nnombre_mes = fecha_nacimiento.strftime(\"%B\")\nprint(f\"5. Nombre del mes: {nombre_mes}\")\n\n# 6. Semana del año\nsemana_año = fecha_nacimiento.strftime(\"%W\")\nprint(f\"6. Semana del año: {semana_año}\")\n\n# 7. Fecha completa con formato ISO\nfecha_formateada7 = fecha_nacimiento.isoformat()\nprint(f\"7. Fecha completa con formato ISO: {fecha_formateada7}\")\n\n# 8. Fecha y hora\nfecha_formateada8 = fecha_nacimiento.strftime(\"%d de %B de %Y a las %H:%M:%S\")\nprint(f\"8. Fecha y hora: {fecha_formateada8}\")\n\n# 9. Hora con formato de 12 horas\nfecha_formateada9 = fecha_nacimiento.strftime(\"%I:%M:%S %p\")\nprint(f\"9. Hora con formato de 12 horas: {fecha_formateada9}\")\n\n# 10. Fecha y hora\nfecha_formateada10 = fecha_nacimiento.strftime(\"%d/%m/%Y %H:%M:%S\")\nprint(f\"10. Fecha y hora: {fecha_formateada10}\")\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/cristianfloyd.py",
    "content": "# EJERCICIO:\n# Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n# - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n# - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n# Calcula cuántos años han transcurrido entre ambas fechas.\nfrom datetime import datetime, timezone, timedelta\n\nutc_minus_3 = timezone(timedelta(hours=-3))\nahora = datetime.now(tz=utc_minus_3)\nbirth_date = datetime(1987, 12, 31 , 6, 6, 10, tzinfo=utc_minus_3)\n\nprint(ahora)\nprint(f\"birth_date: {birth_date}\")\n\nanios_transcurridos = ahora.year - birth_date.year\nprint(f\"Años transcurridos (edad): {anios_transcurridos}\")\n\ndias = ahora - birth_date\nprint(f\"Dias transcurridos: {dias}\")\n\nprint(f\"type of dias: {type(dias.days)}\")\nprint(f\"Años: {(dias.days // 365)}\")\n\n\n#\n# DIFICULTAD EXTRA (opcional):\n# Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n# 10 maneras diferentes. Por ejemplo:\n# - Día, mes y año.\n# - Hora, minuto y segundo.\n# - Día de año.\n# - Día de la semana.\n# - Nombre del mes.\n# (lo que se te ocurra...)\n\n\n# dia, mes y año\nprint(f\"# dia, mes y año: {birth_date.strftime(format='%d/%m/%Y')}\")\nprint(f\"# hora, minuto y segundo: {birth_date.strftime(format='%H:%M:%S')}\")\n\n# dia del año\nprint(f\"# dia del año: {birth_date.strftime(format='%j')}\")\n\n# dia de la semana\nprint(f\"# dia de la semana: {birth_date.strftime(format='%A')}\")\nprint(f\"# dia de la semana: {birth_date.strftime(format='%w')}\")\n\n# nombre del mes\nprint(f\"# nombre del mes: {birth_date.strftime(format='%B')}\")\nprint(f\"# numero del mes: {birth_date.strftime(format='%m')}\")\n\n# semana del año\nprint(f\"# semana del año: {birth_date.strftime(format='%U')}\")\n\n# hora en formato 12 horas\nprint(f\"# hora en formato 12 horas: {birth_date.strftime(format='%I:%M:%S %p')}\")\n\n# hora en formato 24 horas\nprint(f\"# hora en formato 24 horas: {birth_date.strftime(format='%H:%M:%S')}\")\n\n# nombre del mes abreviado\nprint(f\"# nombre del mes abreviado: {birth_date.strftime(format='%b')}\")\n\n# nombre del dia, dia, nombre del mes y año\nprint(f\"# nombre del dia, dia, nombre del mes y año: {birth_date.strftime(format='%A %d %B %Y')}\")\n\n# fecha completa con formato ISO\nprint(f\"# fecha completa con formato ISO: {birth_date.isoformat()}\")\n\n# fecha y hora\nprint(f\"# fecha y hora: {birth_date.strftime(format='%d/%m/%Y %H:%M:%S')}\")\n\n# fecha local\nprint(f\"# fecha local: {birth_date.strftime(format='%x')}\")\n\n# hora local\nprint(f\"# hora local: {birth_date.strftime(format='%X')}\")\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/danielhdzr.py",
    "content": "# #14 FECHAS\n# #### Dificultad: Fácil | Publicación: 01/04/24 | Corrección: 08/04/24\n\n## Ejercicio\n\n\n\n''' * EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n */'''\n\nfrom datetime import date, datetime\n\nfecha_actual = datetime.today()\n\nfecha_nacimiento = datetime(1990, 11, 19, 23, 30)\n\nprint(fecha_actual)\nprint(fecha_nacimiento)\n\ndiferecia_fechas = fecha_actual - fecha_nacimiento\nprint(diferecia_fechas)\nanios = diferecia_fechas.days / 365\nprint(f'Tengo {anios}')\nprint()\n\n#***********EXTRA***********\n\n\nprint(f'Dia, mes y anio: {fecha_nacimiento.strftime('%d-%m-%Y')}')\nprint(f'Horas, min, y seg: {fecha_nacimiento.strftime('%H:%M:%S')}')\nprint(f'Dia del anio: {fecha_nacimiento.strftime('%j')}')\nprint(f'Dia de la semana: {fecha_nacimiento.strftime('%A')}')\nprint(f'Nobre corto del mes: {fecha_nacimiento.strftime('\"%h\"')}')\nprint(f'Nobre completo del mes: {fecha_nacimiento.strftime('%B')}')\nprint(f'Fecha completa por defecto: {fecha_nacimiento.strftime('%c')}')\nprint(f'Fecha corta por defecto: {fecha_nacimiento.strftime('%x')}')\nprint(f'Hora por defecto: {fecha_nacimiento.strftime('%X')}')\nprint(f'AM/PM: {fecha_nacimiento.strftime('%p')}')"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/davidrguez98.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n */ \"\"\"\n\n#EJERCICIO\n\nfrom datetime import datetime\n\nnow = datetime.now()\nbirth_date = datetime(1998, 3, 10, 12, 0, 0)\n\ni = now - birth_date\n\nprint(f\"Tengo {int(i.days / 365)} años.\")\n\n#DIFICULTAD EXTRA\n\nprint(birth_date.day, birth_date.month, birth_date.year)\nprint(birth_date.strftime(\"%d %m %y\"))\nprint(birth_date.hour, birth_date.minute, birth_date.second)\nprint(birth_date.strftime(\"%j\"))\nprint(birth_date.strftime(\"%A\"))\nprint(birth_date.strftime(\"%h\"))\nprint(birth_date.strftime(\"%B\"))\nprint(birth_date.strftime(\"%c\"))\nprint(birth_date.strftime(\"%x\"))\nprint(birth_date.strftime(\"%X\"))\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/didacdev.py",
    "content": "from datetime import datetime, date\n\ndate = datetime.now()\nbirth = datetime(1996, 3, 10, 20, 0)\n\nyears = int((date - birth).total_seconds() // (365.25*24*60*60))\nprint(f\"{years} años\")\n\nprint(f\"{birth.day}-{birth.month}-{birth.year}\")\nprint(f\"{birth.hour}h {birth.minute}min {birth.second}s\")\n\nweek_day = birth.weekday()\n\nmatch week_day:\n    case 0:\n        print(\"Lunes\")\n    case 1:\n        print(\"Martes\")\n    case 2:\n        print(\"Miércoles\")\n    case 3:\n        print(\"Jueves\")\n    case 4:\n        print(\"Viernes\")\n    case 5:\n        print(\"Sábado\")\n    case 6:\n        print(\"Domingo\")\n\nmonth = birth.month\n\nmatch month:\n    case 1:\n        print(\"Enero\")\n    case 2:\n        print(\"Febrero\")\n    case 3:\n        print(\"Marzo\")\n    case 4:\n        print(\"Abril\")\n    case 5:\n        print(\"Mayo\")\n    case 6:\n        print(\"Junio\")\n    case 7:\n        print(\"Julio\")\n    case 8:\n        print(\"Agosto\")\n    case 9:\n        print(\"Septiembre\")\n    case 10:\n        print(\"Octubre\")\n    case 11:\n        print(\"Noviembre\")\n    case 12:\n        print(\"Diciembre\")\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/duendeintemporal.py",
    "content": "#14 { Retos para Programadores } FECHAS\n\n# Bibliography reference\n# Professional JavaScript for web developers by Matt Frisbie [Frisbie, Matt] (z-lib.org)\n#Python Notes for Professionals. 800+ pages of professional hints and tricks (GoalKicker.com) (Z-Library)\n# Additionally, I use GPT as a reference and sometimes to correct or generate proper comments.\n\n\"\"\" \n* EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...) \n \n \"\"\"\n\nfrom datetime import datetime, timedelta\n\n# Short for print\nlog = print\n\n# Simulating the window load event\ndef on_load():\n    body_style = {\n        'background': '#000',\n        'text-align': 'center'\n    }\n    \n    title = 'Retosparaprogramadores #14.'\n    title_style = {\n        'font-size': '3.5vmax',\n        'color': '#fff',\n        'line-height': '100vh'\n    }\n    \n    # Simulating setting styles (not applicable in console)\n    log(f\"Body styles: {body_style}\")\n    log(f\"Title: {title} with styles: {title_style}\")\n    \n    # Simulating alert after 2 seconds\n    log(\"Retosparaprogramadores #14\")\n\n# Call the on_load function to simulate the window load event\non_load()\n\n# Current date\ntoday = datetime.now()\nlog(today)  # Current date and time // 2024-12-25 06:22:05.153585\nlog(today.date())  # Current date // 2024-12-25\nmy_birthday = datetime(1983, 8, 8, 8, 30)  # Birthday\nlog(my_birthday)  # Birthday date and time // 1983-08-08 08:30:00\nlog(my_birthday.date())  # Birthday date // 1983-08-08 \nlog(my_birthday.strftime(\"%Y-%m-%d %I:%M:%S %p\"))  # Birthday in a specific format // 1983-08-08 08:30:00 AM\n\ndef calc_years_between(date1, date2):\n    \"\"\"Calculate the years between two dates.\"\"\"\n    if date1 < date2:\n        date1, date2 = date2, date1  # Swap if date1 is earlier\n\n    difference_in_days = (date1 - date2).days\n    years = difference_in_days / 365.25  # Using 365.25 for leap years\n    full_years = int(years)\n\n    # Check if the anniversary has not yet occurred this year\n    if (date1.month < date2.month) or (date1.month == date2.month and date1.day < date2.day):\n        full_years -= 1\n\n    return years\n\nyears_between = calc_years_between(today, my_birthday)\nlog(f\"Years between: {years_between:.2f}\")  # Display years with two decimal places // Years between: 41.38\n\ndef calc_years_between_simple(date1, date2):\n    \"\"\"Calculate the simple year difference between two dates.\"\"\"\n    if date1 < date2:\n        date1, date2 = date2, date1  # Swap if date1 is earlier\n\n    years = date1.year - date2.year\n    if (date1.month < date2.month) or (date1.month == date2.month and date1.day < date2.day):\n        years -= 1\n\n    return years\n\nlog(calc_years_between_simple(today, my_birthday))  # Simple year difference // 41\n\ndef calc_date_difference(date1, date2):\n    \"\"\"Calculate the difference between two dates.\"\"\"\n    if date1 < date2:\n        date1, date2 = date2, date1  # Swap if date1 is earlier\n\n    difference = date1 - date2\n\n    # Calculate total seconds\n    total_seconds = difference.total_seconds()\n    \n    # Calculate total days, weeks, months, and years\n    total_days = difference.days\n    years = date1.year - date2.year\n    months = (date1.month - date2.month) + (years * 12)\n    weeks = total_days // 7\n    days = total_days % 7\n\n    # Calculate remaining hours, minutes, and seconds\n    remaining_hours = (total_seconds // 3600) % 24\n    remaining_minutes = (total_seconds // 60) % 60\n    remaining_seconds = total_seconds % 60\n\n    return {\n        'years': years,\n        'months': months,\n        'weeks': weeks,\n        'days': days,\n        'hours': remaining_hours,\n        'minutes': remaining_minutes,\n        'seconds': remaining_seconds\n    }\n\ndifference = calc_date_difference(today, my_birthday)\nlog(f\"Difference: \\n{difference['years']} years, \\n{difference['months']} months, \\n{difference['weeks']} weeks, \\n{difference['days']} days, \\n{difference['hours']} hours, \\n{difference['minutes']} minutes, \\n{difference['seconds']} seconds\")\n\"\"\"  \nDifference:\n41 years,\n496 months,\n2159 weeks,\n1 days,\n21.0 hours,\n52.0 minutes,\n5.153584957122803 seconds\n\n\"\"\"\n\ndef format_birthday(birthday):\n    \"\"\"Format birthday information.\"\"\"\n    day_month_year = birthday.strftime(\"%B %d, %Y\")\n    time = birthday.strftime(\"%I:%M:%S %p\")\n    day_of_year = (birthday - datetime(birthday.year, 1, 1)).days + 1\n    day_of_week = birthday.strftime(\"%A\")\n    month_name = birthday.strftime(\"%B\")\n    iso_format = birthday.isoformat()\n    short_format = birthday.strftime(\"%m/%d/%Y\")\n    long_format = birthday.strftime(\"%A, %B %d, %Y\")\n    time_12_hour = birthday.strftime(\"%I:%M:%S %p\")\n    time_with_timezone = birthday.strftime(\"%m/%d/%Y, %I:%M:%S %p\")  # Simulating timezone display\n\n    log(\"1. I was born on:\", day_month_year) # 1. I was born on: August 08, 1983\n    log(\"2. at:\", time) # 2. at: 08:30:00 AM\n    log(\"3. the day:\", day_of_year, \"of the year\", birthday.year) # 3. the day: 220 of the year 1983\n    log(\"4. on:\", day_of_week) #  4. on: Monday\n    log(\"5. one special day of:\", month_name) # 5. one special day of: August\n    log(\"6. isoFormat:\", iso_format) # 6. isoFormat: 1983-08-08T08:30:00\n    log(\"7. shortFormat:\", short_format) # 7. shortFormat: 08/08/1983\n    log(\"8. longFormat:\", long_format) # 8. longFormat: Monday, August 08, 1983\n    log(\"9. time12hour:\", time_12_hour) # 9. time12hour: 08:30:00 AM\n    log(\"10. timeWithTimezone:\", time_with_timezone) # 10. timeWithTimezone: 08/08/1983, 08:30:00 AM\n\n# Call the format_birthday function with my_birthday\nformat_birthday(my_birthday)\n\n# Note: The timezone information is not directly available in the datetime object without additional libraries.\n# The time_with_timezone output is simulated for demonstration purposes.\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/fborjalv.py",
    "content": "\"\"\"\n* EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n\"\"\"\n\nfrom datetime import date, datetime\n\ncurrent_date = datetime.now()\n\nbirth_date = datetime(1992, 4, 29, 13, 0, 0)\n\ndate_result =current_date - birth_date\n\nprint(date_result.days / 365)\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n\n\"\"\"\n\n\nprint(f\"formato 1: {birth_date}\")\nprint(f\"formato 2: {birth_date.strftime('%x-%X')}\")\nprint(f\"formato 3: {birth_date.strftime('%d-%m-%y')}\")\nprint(f\"formato 4: {birth_date.strftime('%H-%M-%S')}\")\nprint(f\"formato 5: {birth_date.strftime('%A')}\")\nprint(f\"formato 6: {birth_date.strftime('%B')}\")\nprint(f\"formato 7: {birth_date.strftime('%d-%B')}\")\nprint(f\"formato 8: {birth_date.strftime('%j')}\")\nprint(f\"formato 9: {birth_date.strftime('%C')}\")\nprint(f\"formato 10: {birth_date.strftime('%c')}\")\n\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/garos01.py",
    "content": "from datetime import datetime\n\n# Fecha actual\nfecha_actual = datetime.now()\n\n# Tu fecha de nacimiento (puedes modificar los valores)\nfecha_nacimiento = datetime(year=1994, month=9, day=11, hour=13, minute=40, second=3)\n\n# Calculando la diferencia de años\ndiferencia = fecha_actual.year - fecha_nacimiento.year\n\n# Ajustando la diferencia si aún no ha pasado tu cumpleaños este año\nif (fecha_actual.month, fecha_actual.day) < (\n    fecha_nacimiento.month,\n    fecha_nacimiento.day,\n):\n    diferencia -= 1\n\nprint(\"Han transcurrido {} años desde tu fecha de nacimiento.\".format(diferencia))\n\n# Ejercicio extra\n\n\nformatos = [\n    \"%d/%m/%Y\",  # Día, mes y año\n    \"%H:%M:%S\",  # Hora, minuto y segundo\n    \"%j\",  # Día de año\n    \"%A\",  # Día de la semana\n    \"%B\",  # Nombre del mes\n    \"%d de %B del %Y\",  # Día de la semana completo\n    \"%m/%d/%y\",  # Fecha en formato corto\n    \"%Y-%m-%d %H:%M:%S\",  # Fecha y hora en formato ISO\n    \"%d/%m/%Y %H:%M:%S\",  # Fecha y hora en formato personalizado\n    \"%I:%M %p\",  # Hora en formato 12 horas con AM/PM\n]\n\n# Mostrar la fecha de nacimiento en los diferentes formatos\nprint(\"Fecha de nacimiento:\")\nfor formato in formatos:\n    print(fecha_nacimiento.strftime(formato))\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/ggilperez.py",
    "content": "# 14 Datetime\nfrom datetime import datetime\n\nutc_now = datetime.utcnow()\nbirth_datetime = datetime.strptime(\"14/06/1993 12:13:14\", \"%d/%m/%Y %H:%M:%S\")\n\nprint(f\"{utc_now = }\")\nprint(f\"{birth_datetime = }\")\nprint(f\"Time elapse between dates: {(utc_now - birth_datetime).days / 365 :.0f} years\")\nprint()\n\n# Extra\nprint(\"Extra\")\n\n# List of format types in: https://docs.python.org/3/library/datetime.html\nprint(f\"1.  {birth_datetime.strftime('%d-%m-%y')}\")  # ESP\nprint(f\"2.  {birth_datetime.strftime('%m-%d-%y')}\")  # US\nprint(f\"3.  {birth_datetime.strftime('%d-%m-%y %H:%M:%S')}\")  # With time\nprint(f\"4.  {birth_datetime.strftime('%d-%B-%y')}\")  # ESP\nprint(f\"5.  {birth_datetime.strftime('%B-%d-%y')}\")  # US\nprint(f\"6.  {birth_datetime.strftime('%d-%m-%Y')}\")  # With full year\nprint(f\"7.  {birth_datetime.strftime('%Y-%m-%dT%H:%M:%S %Z')}\")  # UTC ISO manual\nprint(f\"8.  {birth_datetime.isoformat()}\")  # ISO auto\nprint(f\"9.  {birth_datetime.strftime('%d-%m-%Y %I:%M:%S %p')}\")  # With 12 am/pm hour\nprint(f\"10. {birth_datetime.strftime('%a-%b-%y')}\")  # With day/month names\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/gringoam.py",
    "content": "from  datetime  import datetime\nfrom datetime import timezone \nimport zoneinfo\n\n\"\"\"\nEjercicio\n\"\"\"\n\n#argentina=zoneinfo.ZoneInfo(\"America/BuenosAires\")\n#argentina= timezone.tzname()\nahora= datetime.now()\nprint(ahora.strftime(\"%c\"))\n\n\ncumpleaños= datetime(1981, 6, 9, 4, 30)\nprint(cumpleaños)\n\nedad= ahora - cumpleaños\n\nprint(f\"Tengo {edad.days //365} años\")\n\n\"\"\"\nextra\n\"\"\"\n\n#Dia, mes, año\nprint(cumpleaños.strftime(\"%d %m %y\"))\nprint(cumpleaños.strftime(\"%d %m %Y\"))\n\n#Hora, minutos, segundos\nprint(cumpleaños.strftime(\"%H %M %S\"))\n\n#dia del año\nprint(cumpleaños.strftime(\"%j\"))\n\n#dia del año\nprint(cumpleaños.strftime(\"%A \"))\n\nprint(cumpleaños.strftime(\"%c\"))"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/hectorio23.py",
    "content": "# Author: Héctor Adán\n# https://github.com/hectorio23\n# /bin/python3.11\nimport datetime\n\n'''\nEJERCICIO:\nCrea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n- Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n- Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\nCalcula cuántos años han transcurrido entre ambas fechas.\nDIFICULTAD EXTRA (opcional):\nUtilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n10 maneras diferentes. Por ejemplo:\n- Día, mes y año.\n- Hora, minuto y segundo.\n- Día de año.\n- Día de la semana.\n- Nombre del mes.\n(lo que se te ocurra...)\n'''\n\n###################################################\n################## EJERCICIO 1 ####################\n###################################################\n\ncurrent_time = datetime.datetime.now()\nnacimiento = datetime.datetime(2004, 6, 28, 12, 59, 0)\n\ndelta = current_time - nacimiento\n\nprint(f\"Fecha actual (dd/mm/yy): { current_time.strftime('%d - %m - %Y  %P') }\")\nprint(f\"Fecha de nacimiento (dd/mm/yy): { nacimiento.strftime('%d - %m - %Y  %P') }\")\n\nprint(\"Delta entre la fecha de nacimiento y la fecha actual {0} -> {1:.2f} años\".format(delta, delta.days / 365))\n\n###################################################\n############### EJERCICIO EXTRA ###################\n###################################################\n\nprint(\"\\n**** Formateando la fecha mi fecha de nacimiento en 10 formas distintas ******\\n\")\nprint(f\"Fecha de nacimiento (dd/mm/yyyy): {nacimiento.strftime('%d/%m/%Y')}\")\nprint(f\"Fecha de nacimiento (mm-dd-yyyy): {nacimiento.strftime('%m-%d-%Y')}\")\nprint(f\"Fecha de nacimiento (dd-mm-yyyy): {nacimiento.strftime('%d-%m-%Y')}\")\nprint(f\"Fecha de nacimiento (yyyy/mm/dd): {nacimiento.strftime('%Y/%m/%d')}\")\nprint(f\"Fecha de nacimiento (dd/mm/yy): {nacimiento.strftime('%d/%m/%y')}\")\nprint(f\"Fecha de nacimiento (yy/mm/dd): {nacimiento.strftime('%y/%m/%d')}\")\nprint(f\"Fecha de nacimiento (hh:mm:ss): {nacimiento.strftime('%H:%M:%S')}\")\nprint(f\"Fecha de nacimiento (hh:mm): {nacimiento.strftime('%H:%M')}\")\nprint(f\"Fecha de nacimiento (mes dd, yyyy): {nacimiento.strftime('%B %d, %Y')}\")\nprint(f\"Fecha de nacimiento (dd de mes de yyyy): {nacimiento.strftime('%d de %B de %Y')}\")\n\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/hozlucas28.py",
    "content": "import datetime\n\nfrom typing import TypedDict\n\n\"\"\"\n    Dates...\n\"\"\"\n\nprint(\"Dates...\")\n\ntoday: datetime.date = datetime.datetime.today()\nborn_date: datetime.date = datetime.datetime(year=2002, month=2, day=20)\n\nprint(f\"\\nToday is: {today}\")\nprint(f\"\\nLucas Hoz born date: {born_date}\")\n\nyears_between_dates: int = today.year - born_date.year\nprint(f\"\\nYears between today and born date: {years_between_dates} years\")\n\nprint(\n    \"\\n# ---------------------------------------------------------------------------------- #\\n\"\n)\n\n\"\"\"\n    Additional challenge...\n\"\"\"\n\nprint(\"Additional challenge...\")\n\nprint(\n    f\"\\nDay, month, and year: {born_date.day}, {born_date.month}, and {born_date.year}\"\n)\n\nprint(\n    f\"\\nHours, minutes, and seconds: {born_date.hour} hours, \"\n    + f\"{born_date.minute} minutes, and {born_date.second} seconds\"\n)\n\nprint(f\"\\nDay of the year: {born_date.timetuple().tm_yday}\")\n\nprint(f\"\\nDay of the week: {born_date.weekday() + 1}\")\n\nprint(f\"\\nMonth name: {born_date.strftime(format=\"%B\")}\")\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/idiegorojas.py",
    "content": "# Fechas\n\n# Crear una fecha\nfrom datetime import date\n\nhoy = date.today()\nprint(f'Hoy es: {hoy}')\n\n# Crear una fecha especifica\nfecha = date(2024, 2, 18)\nprint(f'La fecha es: {fecha}')\n\n# Obtener partes de una fecha\nhoy = date.today()\nprint('Año: ', hoy.year)\nprint('Mes: ', hoy.month)\nprint('Dia: ', hoy.day)\n\n# Manejar fechas con timedelta\nfrom datetime import timedelta\n\nhoy = date.today()\nmañana = hoy + timedelta(days=1)\nprint(f'Mañana sera: {mañana}')\n\n# Fecha y hora con datetime\nfrom datetime import datetime\n\nahora = datetime.now()\nprint(f'Ahora es: {ahora}')\n\n# Fortmatear fechas\nfrom datetime import datetime\nahora = datetime.now()\nformato = ahora.strftime('%d-%m-%y %H:%M:%S')\nprint(f'Fecha y hora formateada: {formato}')\n\n\n# Convertir una cadena de texto en un objeto datetime\nfrom datetime import datetime\ncadena = '2024-2-18 19:50:00'\nformato = \"%Y-%m-%d %H:%M:%S\"\nfecha = datetime.strptime(cadena, formato)\nprint(f'Fecha convertida: {fecha}')\n\n\n# Ejercicio\nfrom datetime import datetime\nfrom datetime import timedelta\n\nhoy = datetime.now()\n\ncadena_nacimiento = '1996-11-8 20:00:00'\nformato_nacimiento = '%Y-%m-%d %H:%M:%S'\nnacimiento = datetime.strptime(cadena_nacimiento, formato_nacimiento)\n\nano_actual = hoy.year\nano_nacimiento = nacimiento.year\n\ntiempo_transcurrido = ano_actual - ano_nacimiento\nprint(f'Han transcurrido: {tiempo_transcurrido} años.')\n\n\n\n# Extra\n\nprint(f'Dia: {nacimiento.day}, Mes: {nacimiento.month}, Año: {nacimiento.year}')\nprint(f'Hora: {nacimiento.hour}, Minuto: {nacimiento.minute}, Segundo: {nacimiento.second}')\nprint(f'Dia {nacimiento.day} del año {nacimiento.year}')\nnombre_mes = nacimiento.strftime('%B')\nprint(f'Mes de nacimiento: {nombre_mes}')\nnombre_dia = nacimiento.strftime('%A')\nprint(f'Naci el {nombre_dia} {nacimiento.day} de {nombre_mes} de {nacimiento.year}')"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/ignaciovihe.py",
    "content": "\"\"\"\n* EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n\"\"\"\n\nfrom datetime import datetime, date, timedelta\nfrom dateutil.relativedelta import relativedelta\nimport calendar\nimport pytz\n\nnow = datetime.now()\nprint(now)\nmy_birth_date = datetime.strptime(\"23-02-1985 3:00:00\",\"%d-%m-%Y %H:%M:%S\")\nprint(my_birth_date)\n\nage =relativedelta(now, my_birth_date)\nprint(f\"Años: {age.years}\")\nprint(f\"Meses: {age.months}\")\nprint(f\"Días: {age.days}\")\nprint(f\"Horas: {age.hours}\")\nprint(f\"Minutos: {age.minutes}\")\nprint(f\"Segundos: {age.seconds}\")\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n\"\"\"\nweek_days = list(calendar.day_name)\nmonth_names = list(calendar.month_name)\nmy_birth_date = datetime.strptime(\"27-08-2000 13:01:05\",\"%d-%m-%Y %H:%M:%S\")\ntime_tuple = my_birth_date.timetuple() # Crea una especie de tupla con toda la info de una fecha en concreto\n\n# Se puede acceder a la tupla de info o formatear directamente el datetime:\nprint(f\"1: DD-MM-YYYY: {my_birth_date.strftime(\"%d-%m-%Y\")}\")\nprint(f\"2: HH:MM:SS: {my_birth_date.strftime(\"%H:%M:%S\")}\")\nprint(f\"3: Formated defined by country: {my_birth_date.ctime()}\")\nprint(f\"3: Formated defined by country: {my_birth_date.strftime(\"%c\")}\")\nprint(f\"3: Formated defined by country. Only date: {my_birth_date.strftime(\"%x\")}\")\nprint(f\"3: Formated defined by country. Only time: {my_birth_date.strftime(\"%X\")}\")\nprint(f\"4: Day of the year: {time_tuple.tm_yday}\")\nprint(f\"4: Day of the year: {my_birth_date.strftime(\"%j\")}\")\nprint(f\"5: Day of the week: {week_days[time_tuple.tm_wday]}\")\nprint(f\"5: Day of the week. Normal name: {my_birth_date.strftime(\"%A\")}\")\nprint(f\"5: Day of the week. Short name: {my_birth_date.strftime(\"%a\")}\")\nprint(f\"6: Day of month: {time_tuple.tm_mday}\")\nprint(f\"7: Name of month: {month_names[time_tuple.tm_mon]}\")\nprint(f\"7: Name of month: {my_birth_date.strftime(\"%h\")}\")\nprint(f\"7: Name of month. Normal name: {my_birth_date.strftime(\"%B\")}\")\nprint(f\"7: Name of month. Short name: {my_birth_date.strftime(\"%b\")}\")\nprint(f\"8: Year: {time_tuple.tm_year}\")\nprint(f\"9: {time_tuple.tm_year} was leap? : {calendar.isleap(time_tuple.tm_year)}\")\nprint(f\"10: Hour: {time_tuple.tm_hour}\")\nprint(f\"10: Hour 24h format: {my_birth_date.strftime(\"%H\")}\")\nprint(f\"10: Hour 12h format: {my_birth_date.strftime(\"%I\")}\")\nprint(f\"11: Minute: {time_tuple.tm_min}\")\nprint(f\"11: Minute 2 digits: {my_birth_date.strftime(\"%M\")}\")\nprint(f\"12: Seconds: {time_tuple.tm_sec}\")\nprint(f\"12: Seconds 2 digits: {my_birth_date.strftime(\"%S\")}\")\nprint(f\"13: Microseconds: {my_birth_date.strftime(\"%f\")}\")\nprint(f\"14: AM / PM: {my_birth_date.strftime(\"%p\")}\")\n\n\n# Definir un huso horario (por ejemplo, UTC+2)\ntimezone = pytz.timezone(\"Europe/Madrid\")\n# Obtener la hora local con ese huso horario\nnow = datetime.now(timezone)\n# Mostrar el desplazamiento y el nombre del huso horario\nprint(\"Con huso horario (Madrid):\", now.strftime(\"%X %z\"), now.strftime(\"%Z\"))"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/isilanes.py",
    "content": "from datetime import datetime\nimport locale\n\n\ndef main():\n    now = datetime.now()\n    birth = datetime(1977, 6, 11, 9, 0)\n    delta_years = now.year - birth.year\n\n    if (now.month, now.day) < (birth.month, birth.day):\n        delta_years -= 1\n\n    print(f\"Mi edad es {delta_years} años\")\n\n\ndef extra():\n    \"\"\"\n    Fun fact: en mi actual trabajo tenemos un cliente cuyos emails (presuntamente generados automáticamente),\n    parseamos automáticamente. Estos emails contienen fechas que queremos extraer. No exagero si en los últimos\n    100 emails, han usado mínimo 25 formatos DIFERENTES de fechas. Ni queriendo soy yo capaz de inventarme\n    tantos formatos diferentes. Este ejercicio me trae flashes de Vietnam :)\n    \"\"\"\n    locale.setlocale(locale.LC_ALL, \"es_ES.utf8\")\n    birth = datetime(1977, 6, 11, 21, 0)\n    print(f\"Nací el {birth.strftime('%Y/%m/%d')}\")\n    print(f\"Nací el {birth.isoformat()}\")\n    print(f\"Nací el {birth.strftime('%d de %B de %Y')}\")\n    print(f\"Nací el {birth.strftime('%Y-%b-%d')}\")\n    print(f\"Nací un {birth.strftime('%A %d de %B')}\")\n    print(f\"Nací a las {birth.strftime('%H:%M')}\")\n    ampm = \"PM\" if birth.hour > 12 else \"AM\"  # por alguna razón la directiva %p no me hace esto\n    print(f\"Nací a las {birth.strftime(f'%I:%M:%S {ampm}')}\")\n    print(f\"Nací a los {birth.minute} minutos tras las {birth.hour}h\")\n    print(f\"Nací el {birth.strftime('%m/%d/%y')} (ahora adivina cuál es més y cuál es día)\")\n    print(f\"Nací un {birth.strftime('%A')} de {birth.year}, el mes de {birth.strftime('%B')}\")\n\n\nif __name__ == \"__main__\":\n    main()\n    extra()\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/jesusgdev.py",
    "content": "'''\nEJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n   - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n   - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n  \n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n   10 maneras diferentes. Por ejemplo:\n   - Día, mes y año.\n   - Hora, minuto y segundo.\n   - Día de año.\n   - Día de la semana.\n   - Nombre del mes.\n   (lo que se te ocurra...)\n'''\n\nfrom datetime import datetime\n\nactual_date = datetime.now()\nprint(\"Fecha actual: \", actual_date)\n\nbirth_date = datetime(1984, 3, 25, 14, 30, 0)\nprint(\"Fecha de nacimiento: \", birth_date)\n\nyears = actual_date.year - birth_date.year\n\nif (actual_date.month, actual_date.day) < (birth_date.month, birth_date.day):\n    years -= 1\n\nprint(f\"Han pasado {years} años desde tu nacimiento\")\n\n'''\nExtra\n'''\n\nfrom datetime import datetime\n\n# 🎂 Tu cumpleaños con fecha y hora completa\nbirth_date = datetime(1984, 3, 25, 14, 30, 0)\n\nprint(\"🎉 Mostrando la fecha de cumpleaños en 10 formatos distintos:\\n\")\n\n# 1️⃣ Día, mes y año (formato corto)\nprint(\"📆 Día-Mes-Año: \", birth_date.strftime(\"%d-%m-%Y\"))\n\n# 2️⃣ Día, mes y año (formato largo)\nprint(\"📆 Día de Mes de Año: \", birth_date.strftime(\"%d de %B de %Y\"))\n\n# 3️⃣ Hora, minuto y segundo\nprint(\"⏰ Hora-Minuto-Segundo: \", birth_date.strftime(\"%H:%M:%S\"))\n\n# 4️⃣ Día de la semana (nombre completo)\nprint(\"📅 Día de la semana: \", birth_date.strftime(\"%A\"))\n\n# 5️⃣ Día del año (1 al 366)\nprint(\"📅 Día del año: \", birth_date.strftime(\"%j\"))\n\n# 6️⃣ Semana del año (número de semana)\nprint(\"🗓️ Semana del año: \", birth_date.strftime(\"%U\"))\n\n# 7️⃣ Nombre del mes\nprint(\"🗓️ Mes (nombre): \", birth_date.strftime(\"%B\"))\n\n# 8️⃣ Día con nombre corto del mes\nprint(\"📆 Día/Mes corto: \", birth_date.strftime(\"%d/%b\"))\n\n# 9️⃣ Fecha y hora juntas (formato completo)\nprint(\"🕰️ Fecha y hora completas: \", birth_date.strftime(\"%c\"))\n\n# 🔟 Formato ISO (internacional)\nprint(\"🌐 Formato ISO 8601: \", birth_date.isoformat())\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/jptxaya.py",
    "content": "#14 FECHAS\n\n\"\"\"\n/*\n * EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n */\n \"\"\"\nfrom datetime import datetime\ndate_actual = datetime.now()\nprint(f\"Fecha actual:{date_actual}\")\nbirth_date = datetime(1979,3,10,17,15,00,00)\nprint(f\"Fecha Nacimiento:{birth_date}\")\ndiference_days = date_actual - birth_date\ndiference_years = diference_days // 365\nprint(f\"Años transcurridos {diference_years.days}\")\n\n\n#Dificultad Extra\nprint(\"\\nDificultad Extra\\n\")\nprint(f\"Year: {birth_date.strftime(\"%Y\")}\")\nprint(f\"Month: {birth_date.strftime(\"%m\")}\")\nprint(f\"Month Name: {birth_date.strftime(\"%B\")}\")\nprint(f\"Day: {birth_date.strftime(\"%d\")}\")\nprint(f\"Week Day: {birth_date.strftime(\"%A\")}\")\nprint(f\"Time: {birth_date.strftime(\"%H:%M:%S\")}\")\nprint(f\"Time AM/PM: {birth_date.strftime(\"%I:%M %p\")}\")\nprint(f\"Days of year: {birth_date.strftime(\"%-j\")}\")\nprint(f\"Week Number of year: {birth_date.strftime(\"%-W\")}\")\nprint(f\"Locale Date: {birth_date.strftime(\"%c\")}\")"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/juanchernandezdev.py",
    "content": "### Python Dates ###\nfrom datetime import datetime\n\ncurrent_time = datetime.now()\nbirth_time = datetime(1987, 12, 23, 4, 45, 8)\nprint(current_time, birth_time)\n\nyears_passed = current_time - birth_time\nprint(years_passed)\n\n#! Optional Challenge\nformat_one = birth_time.strftime('%Y/%d/%m')\nprint(format_one)\nformat_two = birth_time.strftime('%B-%d-%Y')\nprint(format_two)\nformat_three = birth_time.strftime('%a-%d-%B-%y')\nprint(format_three)\nformat_four = birth_time.strftime('%a-%d-%B-%y')\nprint(format_three)\nformat_five= birth_time.strftime('%d-%B-%y-%H')\nprint(format_five)\nformat_six = birth_time.strftime('%d-%a-%B-%Y-%H')\nprint(format_six)\nformat_seven = birth_time.strftime('%d-%a-%B-%Y-%I%p')\nprint(format_seven)\nformat_eighth = birth_time.strftime('%d-%a-%B-%y-%I%p-00:%M')\nprint(format_eighth)\nformat_nine = birth_time.strftime('%d-%a-%B-%y-%I%p-00:%M-00:%S')\nprint(format_nine)\nformat_ten = birth_time.strftime('%d-%a/%B/%y/ %I:%M:%S %p')\nprint(format_ten)\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/juandaherrera.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n\"\"\"\n\nfrom datetime import datetime\n\ncurrent_date = datetime.now()\nbirth_date = datetime(1999, 12, 5, 19, 34, 16)\n\nprint(\"Fecha actual:\", current_date)\nprint(\"Fecha de nacimiento: \", birth_date)\n\nprint(\"Tiempo transcurrido entre ambas fechas:\", current_date - birth_date)\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n\"\"\"\nprint(f\"{'Formatos':-^80}\")\ndate_formats = [\n    \"%d-%m-%Y\",  # día, mes y año\n    \"%H-%M-%S\",  # Hora, minuto, segundo\n    \"%j\",  # Día del año (de 001 a 366)\n    \"%w\",  # Dow. 0 es domingo y 6 es sábado\n    \"%B\",  # Nombre completo del mes\n    \"%a, %d %b %Y\",\n    \"%Y-%m-%d\",\n    \"%c\",  # Representación apropiada de fecha y hora localmente\n    \"%X\",\n    \"%A, %d %B %Y\",\n]\n\nfor index, date_format in enumerate(date_formats):\n    print(f\"{index + 1}. \", birth_date.strftime(date_format))\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/juanmax2.py",
    "content": "\"\"\"\nFechas\n\"\"\"\n\nfrom datetime import datetime, date\n\nnow = datetime.now()\n\nprint(now)\n\nbirthdate = datetime(1992, 11, 13, 5, 45, 0)\n\nprint(birthdate)\n\nresultado = now - birthdate\n\nprint(f\"Tengo {resultado.days // 365} años\")\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n */\n\"\"\"\n\n# Dia, mes, año\nprint(birthdate.strftime(\"%d - %m - %y\"))\nprint(birthdate.strftime(\"%d - %m - %Y\"))\n\n# Horas, minutos y segundos\nprint(birthdate.strftime(\"%H : %M : %S\"))\n\n# Dia del año\nprint(birthdate.strftime(\"%j\"))\n\n# Dia de la semana\nprint(birthdate.strftime(\"%A\"))\n\n# Nombre del mes\nprint(birthdate.strftime(\"%B\"))\n\n# Nombre del mes abreviado\nprint(birthdate.strftime(\"%h\"))\n\n# Representación por defecto del locale\nprint(birthdate.strftime(\"%c\"))\nprint(birthdate.strftime(\"%x\"))\nprint(birthdate.strftime(\"%X\"))\n\n# AP/PM\nprint(birthdate.strftime(\"%p\"))\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/juanppdev.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n\"\"\"\n\nfrom datetime import datetime\n\n# Fecha actual\nfecha_actual = datetime.now()\n\n# Fecha de nacimiento (puedes cambiarla por la tuya)\nfecha_nacimiento = datetime(1990, 8, 9, 12, 0, 0)  # Año, mes, día, hora, minuto, segundo\n\n# Cálculo de la diferencia en años\ndiferencia = fecha_actual.year - fecha_nacimiento.year\n\n# Ajuste si la fecha de nacimiento aún no ha ocurrido este año\nif (fecha_actual.month, fecha_actual.day) < (fecha_nacimiento.month, fecha_nacimiento.day):\n    diferencia -= 1\n\nprint(f\"Han transcurrido {diferencia} años.\")\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n\"\"\"\n\nfrom datetime import datetime\n\n# Fecha de nacimiento (puedes cambiarla por la tuya)\nfecha_nacimiento = datetime(1998, 9, 24, 12, 0, 0)  # Año, mes, día, hora, minuto, segundo\n\n# Formateos diferentes\nformatos = [\n    fecha_nacimiento.strftime(\"%d/%m/%Y\"),  # Día, mes y año\n    fecha_nacimiento.strftime(\"%H:%M:%S\"),  # Hora, minuto y segundo\n    fecha_nacimiento.strftime(\"%j\"),        # Día del año\n    fecha_nacimiento.strftime(\"%A\"),        # Día de la semana\n    fecha_nacimiento.strftime(\"%B\"),        # Nombre del mes\n    fecha_nacimiento.strftime(\"%d-%m-%Y %H:%M:%S\"),  # Día, mes, año, hora, minuto y segundo\n    fecha_nacimiento.strftime(\"%Y-%m-%d\"),  # Año, mes y día\n    fecha_nacimiento.strftime(\"%I:%M %p\"),  # Hora en formato 12 horas con AM/PM\n    fecha_nacimiento.strftime(\"%U\"),        # Número de semana del año (domingo como primer día de la semana)\n    fecha_nacimiento.strftime(\"%W\")         # Número de semana del año (lunes como primer día de la semana)\n]\n\n# Mostrar los resultados\nfor i, formato in enumerate(formatos, 1):\n    print(f\"Formato {i}: {formato}\")\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/juxxon23.py",
    "content": "from datetime import datetime\n\n# Ejercicio 1\ncurrent_date = datetime.now().strftime(\"%d/%m/%Y, %H:%M:%S\")\ncurrent_date_obj = datetime.strptime(current_date, \"%d/%m/%Y, %H:%M:%S\")\n\nbirth_date = \"17/05/1998, 03:25:32\"\nbirth_date_obj = datetime.strptime(birth_date, \"%d/%m/%Y, %H:%M:%S\")\n\nyears_passed = current_date_obj - birth_date_obj\n\nprint(f\"Birth date: {birth_date_obj} \\nCurrent date: {current_date_obj}\")\nprint(f\"{years_passed.days//365} years have passed.\")\n\n\n# Ejercicio Extra\nprint(f\"\"\"\nDates Formatting - 10 different ways: \n1) [day month year, hour AM/PM] -> {birth_date_obj.strftime(\"%A %B %Y, %-I %p\")} \n2) [day-month-year] -> {birth_date_obj.strftime(\"%a-%b-%Y\")} \n3) [day day moth, week week_year of year] -> {birth_date_obj.strftime(\"%A %d %B, week %W of %Y\")} \n4) [day/month/year, hours:minutes:seconds AM/PM] -> {birth_date_obj.strftime(\"%-d/%-m/%y, %I:%-M:%-S %p\")} \n5) [hour AM/PM, year/month/day] -> {birth_date_obj.strftime(\"%-H %p, %Y/%B/%d\")} \n6) [day, day of month year] -> {birth_date_obj.strftime(\"%A, %-d of %B %Y\")} \n7) [hour AM/PM - month day year] -> {birth_date_obj.strftime(\"%-H %p - %B %A %Y\")} \n8) [month/day/year] -> {birth_date_obj.strftime(\"%b/%d/%Y\")} \n9) [month.day.year] -> {birth_date_obj.strftime(\"%m.%d.%y\")} \n10) [day, year.month.day ; hours:minutes:seconds] -> {birth_date_obj.strftime(\"%A, %y.%m.%d ; %H:%M:%S\")}\"\"\")"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/kenysdev.py",
    "content": "# ╔═════════════════════════════════════╗\n# ║ Autor:  Kenys Alvarado              ║\n# ║ GitHub: https://github.com/Kenysdev ║\n# ║ 2024 -  Python                      ║\n# ╚═════════════════════════════════════╝\n\n# -----------------------------------\n# * FECHAS\n# -----------------------------------\n# Mas info: https://docs.python.org/3/library/datetime.html\n\n\"\"\"\n# EJERCICIO 1\n* Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n* - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n* - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n* Calcula cuántos años han transcurrido entre ambas fechas.\n\"\"\"\n\nimport datetime\ncurrent_date_time = datetime.datetime.now()\nbirth_date = datetime.datetime.strptime(\n    \"1995-10-20 02:30:00\", \"%Y-%m-%d %H:%M:%S\")\n\ndifference = current_date_time - birth_date\nyears = difference.days // 365\nmonths = (difference.days % 365) // 30\ndays = (difference.days % 365) % 30\n\nprint(f\"\"\"\nJuanito tiene:\n{years} años,\n{months} meses y\n{days} dias.\n\"\"\")\n\n# ___________________________________\n\"\"\"\n# EJERCICIO 2\n* Utilizando la fecha de tu cumpleaños, formatéala y muestra su \n  resultado de 10 maneras diferentes.\n\"\"\"\n\nprint(f\"\"\"\n1. Predeterminado -> {birth_date}\n2. dd/mm/yyyy     -> {birth_date.strftime(\"%d/%m/%Y\")}\n3. dd-mm-yyyy     -> {birth_date.strftime(\"%d-%m-%Y\")}\n4. Nombre del mes -> {birth_date.strftime(\"%B\")}\n5. Mes abreviado  -> {birth_date.strftime(\"%b\")}\n6. Nombre dia     -> {birth_date.strftime(\"%A\")}\n7. Dia abreviado  -> {birth_date.strftime(\"%a\")}\n8. Hora(12 horas) -> {birth_date.strftime(\"%I:%M:%S %p\")}\n9. Hora(24 horas) -> {birth_date.strftime(\"%H:%M:%S\")}\n0. personalizado  -> {birth_date.strftime(\n    \"Born on %A, %dth of %B %Y at %I:%M:%S %p\")}\n\"\"\")\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/mariovelascodev.py",
    "content": "from datetime import datetime\n\ncurrent_date = datetime.now()\nborn_date = datetime(1990, 2, 7, 5, 30, 00)\n\n#Calcular los años que han pasado entre ambas fechas\ndays_passed = current_date - born_date\nyears_passed = days_passed.days // 365\n\nprint(f\"Entre ambas fechas han transcurrido {years_passed} años\")\n\n#EXTRA\nprint(\"---------------------\")\nprint(\"\\nDía, mes y año\")\nprint(born_date.strftime('%d-%m-%Y'))\nprint(\"\\nHora, minuto y segundo\")\nprint(born_date.strftime('%H:%M:%S'))\nprint(\"\\nDía de la semana (versión corta)\")\nprint(born_date.strftime('%a'))\nprint(\"\\nDía de la semana (versión larga)\")\nprint(born_date.strftime('%A'))\nprint(\"\\nDía del mes (0-6) donde el 0 es Domingo\")\nprint(born_date.strftime('%w'))\nprint(\"\\nHora local AM o PM\")\nprint(born_date.strftime('%H:%M:%S %p'))\nprint(\"\\nFecha con hora en formato 12 horas\")\nprint(born_date.strftime('%x %I %p'))\nprint(\"\\nDía de la semana y minuto\")\nprint(born_date.strftime('%A - Minuto: %M'))\nprint(\"\\nDía de la semana y año (versión corta)\")\nprint(born_date.strftime('%A - Año: %y'))\nprint(\"\\nDía del mes\")\nprint(born_date.strftime('%d'))"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/mhayhem.py",
    "content": "from datetime import datetime, date, time, timedelta, tzinfo\n\n# EJERCICIO:\n# Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n# - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n# - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n# Calcula cuántos años han transcurrido entre ambas fechas.\n\ncurrent_date = datetime.today()\n\nmy_birthday = datetime(1983, 7, 15, 18, 32, 12)\n\npassed_time = current_date - my_birthday\n\nprint(f\"Fecha actual: {current_date}.\")\n\nprint(f\"Fecha de nacimiento: {my_birthday}.\")\n\nprint(f\"Tiempo transcurrido entre esas fechas: {passed_time.days // 365} años.\")\n\n\n# DIFICULTAD EXTRA (opcional):\n# Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n# 10 maneras diferentes. Por ejemplo:\n# - Día, mes y año.\n# - Hora, minuto y segundo.\n# - Día de año.\n# - Día de la semana.\n# - Nombre del mes.\n# (lo que se te ocurra...)\n\nday_name = my_birthday.strftime(\"%A\")\nmonth_name = my_birthday.strftime(\"%B\")\nprint(f\"fecha completa: {my_birthday.ctime()}.\")\nprint(f\"Día: {my_birthday.day}\")\nprint(f\"Mes: {my_birthday.month}\")\nprint(f\"Año: {my_birthday.year}\")\nprint(f\"Número de dia de la semana: {my_birthday.isoweekday()}\")\nprint(f\"Fecha solo en sin hora: {my_birthday.date()}\")\nprint(f\"Segundos que llevo viviendo: {int(my_birthday.timestamp())}\")\nprint(f\"Fecha: {my_birthday.date()}\")\nprint(f\"Fecha formateada: {my_birthday.strftime(\"\")}\")\nprint(f\"nombre del día de nacimiento: {day_name}\")\nprint(f\"Nombre del mes: {month_name}\")"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/miguelex.py",
    "content": "from datetime import datetime\n\nnow = datetime.now()\n\nbirth = datetime.strptime(\"03/09/1975 09:40:25\", \"%d/%m/%Y %H:%M:%S\")\n\ndiff = now - birth\n\nyears = diff.days // 365\nmonths = (diff.days % 365) // 30\ndays = diff.days % 30\nhours = diff.seconds // 3600\nminutes = (diff.seconds % 3600) // 60\nseconds = diff.seconds % 60\n\nprint(\"Hoy es el\", now.strftime(\"%d/%m/%Y %H:%M:%S\"))\nprint(\"Nací el\", birth.strftime(\"%d/%m/%Y %H:%M:%S\"))\nprint(\"\\nHan pasado\", years, \"años,\", months, \"meses,\", days, \"días,\", hours, \"horas,\", minutes, \"minutos y\", seconds, \"segundos desde que nací\")\n\n# Extras\n\nprint(birth.strftime(\"%d/%m/%Y\"))\n\nprint(birth.strftime(\"%d/%m/%y\"))\n\nprint(birth.strftime(\"%d de %B de %Y\"))\n\nprint(\"Nací un\", birth.strftime(\"%A\"))\n\nprint(\"El día de mi nacimiento era el\", birth.strftime(\"%j\"), \"día del año\")\n\nprint(\"La fecha de mi nacimiento estaba en la semana\", birth.strftime(\"%U\"))\n\nprint(\"Mi año de nacimiento\", \"es\" if birth.year % 4 == 0 and (birth.year % 100 != 0 or birth.year % 400 == 0) else \"no es\", \"bisiesto\")\n\nprint(\"Nací en\", birth.strftime(\"%B\"))\n\nprint(\"Nací en\", birth.strftime(\"%b\"))\n\nprint(\"Nací en la década de los\", birth.strftime(\"%Y\")[2], \"0\")\n\ncentury = birth.year // 100 + 1\nprint(\"Nací en el siglo\", century)\n\nprint(\"Nací a las\", birth.strftime(\"%H:%M:%S\"))\n\nprint(\"Nací a las\", birth.strftime(\"%I:%M:%S %p\"))\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/mikelm2020.py",
    "content": "import datetime\n\n# Ejercicio\ncurrent_date = datetime.datetime.now()\nbirth_date = datetime.datetime(1972, 9, 28, 10, 20, 0)\n\n\ndef calculate_age(birth_date: datetime, current_date: datetime) -> int:\n    age: int = current_date.year - birth_date.year\n    if current_date.month < birth_date.month or (\n        current_date.month == birth_date.month and current_date.day < birth_date.day\n    ):\n        age -= 1\n    return age\n\n\n# Dificultad Extra\n# mostrar de 10 maneras distintas\ndef show_formats_of_birth_date() -> None:\n    print(birth_date.strftime(\"%d/%m/%Y, %H:%M:%S\"))\n    print(birth_date.strftime(\"%a-%b-%Y\"))\n    print(birth_date.strftime(\"%A, %d of %B %Y\"))\n    print(birth_date.strftime(\"%-d/%-m/%y, %I:%-M:%-S %p\"))\n    print(birth_date.strftime(\"%-H %p, %Y/%B/%d\"))\n    print(birth_date.strftime(\"%A, %-d of %B %Y\"))\n    print(birth_date.strftime(\"%-H %p - %B %A %Y\"))\n    print(birth_date.strftime(\"%b/%d/%Y\"))\n    print(birth_date.strftime(\"%m.%d.%y\"))\n    print(birth_date.strftime(\"%A, %y.%m.%d ; %H:%M:%S\"))\n\n\nif __name__ == \"__main__\":\n    print(f\"Current date: {current_date}\")\n    print(f\"Binary date: {birth_date}\")\n    print(f\"Years: {calculate_age(birth_date, current_date)}\")\n\n    print(\"Muestra mi fecha de nacimiento de 10 maneras distintas\")\n    show_formats_of_birth_date()\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/monicavaquerano.py",
    "content": "# 14 FECHAS\n# Monica Vaquerano\n# https://monicavaquerano.dev\n\n\n\"\"\"\n * EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n *\n\"\"\"\nfrom datetime import datetime\n\n# Now\nnow = datetime.now()\n\n# Day of Birth\ndob = datetime(1988, 10, 9, 19, 59, 59)\n\n# Difference\ndif = now - dob\n\n# Date Output\n# The strftime() Method\n# The datetime object has a method for formatting date objects into readable strings.\n# The method is called strftime(), and takes one parameter, format, to specify the format of the returned string:\n\nprint(\"Now: year =>\", now.year)\nprint(\"Now: weekday, full version =>\", now.strftime(\"%A\"))  # Weekday, full version\n\nprint(\"DOB: day =>\", dob.day)\nprint(\"DOB: year =>\", dob.year)\nprint(\n    \"DOB: month name, full version =>\", dob.strftime(\"%B\")\n)  # Month name, full version\n\nprint(\"Difference (Age) =>\", dif.days // 365)\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n\"\"\"\n# - Día, mes y año.\nprint(\"Día, mes y año =>\\t\", dob.strftime(\"%d %B %Y\"))\nprint(\"Día, mes y año =>\\t\", dob.strftime(\"%d/%m/%y\"))\nprint(\"Día, mes y año =>\\t\", dob.strftime(\"%d/%m/%Y\"))\n\n# - Hora, minuto y segundo.\nprint(\"Hora, minuto y segundo =>\\t\", dob.strftime(\"%H: %M: %S\"))\nprint(\"Hora, minuto y segundo =>\\t\", dob.strftime(\"%I: %M: %S %p\"))\n\n# - Día de año.\nprint(\"Día del año =>\\t\", dob.strftime(\"%A, %d %B %Y. Day %jth of that year\"))\nprint(\"Día del año =>\\t\", dob.strftime(\"Day %jth of that year\"))\n\n# - Día de la semana.\nprint(\"Día de la semana =>\\t\", dob.strftime(\"%a\"))\nprint(\"Día de la semana =>\\t\", dob.strftime(\"%A\"))\nprint(\"Día de la semana =>\\t\", dob.strftime(\"%w\"))\n\n# - Nombre del mes.\nprint(\"Nombre del mes =>\\t\", dob.strftime(\"%b\"))\nprint(\"Nombre del mes =>\\t\", dob.strftime(\"%B\"))\nprint(\"Nombre del mes =>\\t\", dob.strftime(\"%m\"))\n\n# - (lo que se te ocurra...)\nprint(\"Local version of date and time =>\\t\", dob.strftime(\"%c\"))\nprint(\"Century =>\\t\", dob.strftime(\"%C\"))\nprint(\"Local version of date =>\\t\", dob.strftime(\"%x\"))\nprint(\"Local version of time =>\\t\", dob.strftime(\"%X\"))\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/mouredev.py",
    "content": "from datetime import datetime\n\n\"\"\"\nEjercicio\n\"\"\"\n\nnow = datetime.now()\nbirth_date = datetime(1987, 4, 29, 12, 0, 0)\n\nprint(now)\nprint(birth_date)\n\ndifference = now - birth_date\nprint(type(difference))\n\nprint(f\"Tengo {difference.days // 365} años.\")\n\n\"\"\"\nExtra\n\"\"\"\n\n# Día, mes y año\nprint(birth_date.strftime(\"%d/%m/%y\"))\nprint(birth_date.strftime(\"%d/%m/%Y\"))\n\n# Horas, minutos y segundos\nprint(birth_date.strftime(\"%H:%M:%S\"))\n\n# Día del año\nprint(birth_date.strftime(\"%j\"))\n\n# Día de la semana\nprint(birth_date.strftime(\"%A\"))\n\n# Nombre del mes\nprint(birth_date.strftime(\"%h\"))\nprint(birth_date.strftime(\"%B\"))\n\n# Representación por defecto del locale\nprint(birth_date.strftime(\"%c\"))\nprint(birth_date.strftime(\"%x\"))\nprint(birth_date.strftime(\"%X\"))\n\n# AM/PM\nprint(birth_date.strftime(\"%p\"))\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/mrodara.py",
    "content": "#################################  FECHAS  ####################################################\n\nfrom datetime import datetime, timedelta, date, time\n\ntime_now = datetime.now()\n\nmy_birthdate = datetime(year=1980, month=1, day=3, hour=8, minute=0, second=0)\n\ndifference = time_now - my_birthdate\n\nprint(difference.days // 365)\n\n#########################################  EXTRA  #######################################################\n\nprint(my_birthdate.day)\nprint(my_birthdate.month)\nprint(my_birthdate.year)\nprint(my_birthdate.hour)\nprint(my_birthdate.minute)\nprint(my_birthdate.second)\nprint(my_birthdate.weekday())  # 0 = Monday, 1 = Tuesday,\nprint(my_birthdate.isoweekday())  # 1 = Monday, 2 = Tuesday\nprint(my_birthdate.strftime(\"%A\"))  # Full weekday name\nprint(my_birthdate.strftime(\"%a\"))  # Abbreviated weekday name\nprint(my_birthdate.strftime(\"%B\"))  # Full month name\nprint(my_birthdate.strftime(\"%b\"))  # Abbreviated month name\nprint(my_birthdate.strftime(\"%Y\"))  # Year with century as a decimal number\nprint(my_birthdate.strftime(\"%y\"))  # Year without century as a zero-padded decimal number\nprint(my_birthdate.strftime(\"%m\"))  # Month as a zero-padded decimal number\nprint(my_birthdate.strftime(\"%d\"))  # Day of the month as a zero-padded decimal\nprint(my_birthdate.strftime(\"%H\"))  # Hour (24-hour clock) as a zero-p\nprint(my_birthdate.strftime(\"%I\"))  # Hour (12-hour clock) as a zero-p\nprint(my_birthdate.strftime(\"%M\"))  # Minute as a zero-padded decimal number\nprint(my_birthdate.strftime(\"%S\"))  # Second as a zero-padded decimal number\nprint(my_birthdate.strftime(\"%f\"))  # Microsecond as a decimal number, zero-padded\nprint(my_birthdate.strftime(\"%p\"))  # Locale’s equivalent of either AM or PM\nprint(my_birthdate.strftime(\"%j\"))  # Day of the year as a zero-padded decimal\n\n\n\n#########################################  FIN EXTRA  #######################################################\n\n#################################  FIN FECHAS  ####################################################"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/mvidalb.py",
    "content": "from datetime import datetime\n\n'''\nEjercicio\n'''\n# Fecha (día, mes, año, hora, minuto, segundo) actual\ncurrent_date = datetime.now()\ncurrent_date_formatted = current_date.strftime(\"%d-%m-%Y %H:%M:%S\")  # datetime to str\nprint(current_date_formatted)\nprint(type(current_date_formatted)) \n\nbirth_date = datetime.strptime(\"10-10-1993 04:02:03\", \"%d-%m-%Y %H:%M:%S\")  # str to datetime\nprint(birth_date)\nprint(type(birth_date))\n\n\n'''\nEjercicio extra\n'''\n# Día, mes y año\nprint(\"Día, mes y año: \" + birth_date.strftime(\"%d-%m-%Y\"))\n# Hora, minuto y segundo\nprint(\"Hora, minuto y segundo: \" + birth_date.strftime(\"%H:%M:%S\"))\n# Día de año\nprint(\"Día del año: \" + str(birth_date.timetuple().tm_yday))  #timetuple() para acceder a distintos datos: año, mes, día, hora, etc.\n# Día de la semana\nprint(\"Día de la semana: \" + str(birth_date.timetuple().tm_wday) + \", \" + str(birth_date.strftime(\"%A\")))\n# Nombre del mes\nprint(\"Nombre del mes: \" + str(birth_date.strftime(\"%B\")))\n\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/neslarra.py",
    "content": "\"\"\"\n EJERCICIO:\n Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n - Calcular el tiempo transcurrido en segundos entre el comienzo y fin de una tarea.\n Calcula cuántos años han transcurrido entre ambas fechas.\n\n DIFICULTAD EXTRA (opcional):\n - Me salgo del ejercicio propuesto y muestro un manejo de fechas real hecho para organizar backups.\n\"\"\"\nimport locale\nimport time\nfrom datetime import datetime, timedelta\nfrom dateutil.relativedelta import relativedelta\nfrom random import randint\nlocale.setlocale(locale.LC_TIME, 'es_ES')\n\n\nprint(f\"\"\"## Explicación {'#' * 30}\"\"\")\n\nprint(\"\"\"\nVoy a usar \"time\" cuando necesite saber tiempos pero NO necesariamente fechas (por ejemplo: calcular el tiempo de ejecución).\nVoy a usar \"datetime\" cuando necesite operar con fechas concretas (por ejemplo: en que día cae la primavera).\n\nfrom datetime import datetime, timedelta\nimport time\nimport locale\nlocale.setlocale(locale.LC_TIME, 'es_ES')\n\n\nt1 = time.time()\n\ntime.sleep(3)\n\nprint(f\"La operación tardó {(time.time() - t1).__round__(4)} segundos.\")\n\nfor m in range(1, 13):\n    dia_uno_este_anio = datetime(2024, m, 1)\n    dia_uno_anio_anterior = (dia_uno_este_anio - timedelta(days=364)).replace(day=1)\n    dia_uno_anio_proximo = (dia_uno_este_anio + timedelta(days=367)).replace(day=1)\n\n    print(f\"El primero de {dia_uno_este_anio.strftime('%B')} de {dia_uno_este_anio.strftime('%Y')} cae en {dia_uno_este_anio.strftime('%A')}\")\n    print(f\"El primero de {dia_uno_anio_anterior.strftime('%B')} de {dia_uno_anio_anterior.strftime('%Y')} cae en {dia_uno_anio_anterior.strftime('%A')}\")\n    print(f\"El primero de {dia_uno_anio_proximo.strftime('%B')} de {dia_uno_anio_proximo.strftime('%Y')} cae en {dia_uno_anio_proximo.strftime('%A')}\")\n\n    if m == 9:\n        primavera_este_anio = dia_uno_este_anio.replace(day=21, month=9)\n        print(f\"La PRIMAVERA de {primavera_este_anio.strftime('%Y')} empieza en {primavera_este_anio.strftime('%A')}\")\n\n        primavera_anio_anterior = dia_uno_anio_anterior.replace(day=21, month=9)\n        print(f\"La PRIMAVERA de {primavera_anio_anterior.strftime('%Y')} empieza en {primavera_anio_anterior.strftime('%A')}\")\n\n        primavera_anio_proximo = dia_uno_anio_proximo.replace(day=21, month=9)\n        print(f\"La PRIMAVERA de {primavera_anio_proximo.strftime('%Y')} empieza en {primavera_anio_proximo.strftime('%A')}\")\n\nVa a mostrar:\n\n\"\"\")\nt1 = time.time()\n\ntime.sleep(3)\n\nprint(f\"La operación tardó {(time.time() - t1).__round__(4)} segundos.\")\n\nfor m in range(1, 13):\n    dia_uno_este_anio = datetime(2024, m, 1)\n    dia_uno_anio_anterior = (dia_uno_este_anio - timedelta(days=364)).replace(day=1)\n    dia_uno_anio_proximo = (dia_uno_este_anio + timedelta(days=367)).replace(day=1)\n\n    print(f\"El primero de {dia_uno_este_anio.strftime('%B')} de {dia_uno_este_anio.strftime('%Y')} cae en {dia_uno_este_anio.strftime('%A')}\")\n    print(f\"El primero de {dia_uno_anio_anterior.strftime('%B')} de {dia_uno_anio_anterior.strftime('%Y')} cae en {dia_uno_anio_anterior.strftime('%A')}\")\n    print(f\"El primero de {dia_uno_anio_proximo.strftime('%B')} de {dia_uno_anio_proximo.strftime('%Y')} cae en {dia_uno_anio_proximo.strftime('%A')}\")\n\n    if m == 9:\n        primavera_este_anio = dia_uno_este_anio.replace(day=21, month=9)\n        print(f\"La PRIMAVERA de {primavera_este_anio.strftime('%Y')} empieza en {primavera_este_anio.strftime('%A')}\")\n\n        primavera_anio_anterior = dia_uno_anio_anterior.replace(day=21, month=9)\n        print(f\"La PRIMAVERA de {primavera_anio_anterior.strftime('%Y')} empieza en {primavera_anio_anterior.strftime('%A')}\")\n\n        primavera_anio_proximo = dia_uno_anio_proximo.replace(day=21, month=9)\n        print(f\"La PRIMAVERA de {primavera_anio_proximo.strftime('%Y')} empieza en {primavera_anio_proximo.strftime('%A')}\")\n\nprint(f\"\\n\\n## Dificultad extra  {'#' * 30}\", end=\"\\n\\n\")\n\n\ndef log_task(funcion):\n    def wrapper(*args, **kwargs):\n        argumentos = \"\"\n        for arg in args:\n            argumentos += arg + \" \"\n        print(f\"BEGIN {funcion.__name__} - {argumentos} - Lanzado a las {datetime.now().strftime('%H:%M:%S')}\", end=\"\\n\\t\")\n        inicio = time.time()\n        funcion(*args, **kwargs)\n        duracion = (time.time() - inicio).__round__(2)\n        print(f\"END {funcion.__name__} - {argumentos} / duró: {duracion} segundos - Terminó a las {datetime.now().strftime('%H:%M:%S')}\", end=\"\\n\\n\")\n\n    return wrapper\n\n\n@log_task\ndef mi_funcion(mensaje: str):\n    print(mensaje)\n    time.sleep(randint(1, 10))\n\n\ndef calcula_fechas_backup(fecha_ultima_ejecucion: datetime, tipo_backup: str):\n    # Calcula las fechas de habiilitación/deshabilitación de backup de tipo MENSUAL / DIARIO\n\n    dia_referencia = (datetime.now() + timedelta(days=1)).replace(hour=0, minute=0, second=0)\n\n    # los backup están divididos en dos grupos: \"expira jueves = 0\" y \"expira viernes = 1\"\n    grupo = 0\n    if fecha_ultima_ejecucion.strftime('%a') in ['Fri', 'Vie']:\n        grupo = 1\n\n    fecha_primero_de_mes = (fecha_ultima_ejecucion.replace(day=1) + timedelta(days=32)).replace(day=1, hour=0, minute=0, second=0)\n    dia_primero_de_mes = fecha_primero_de_mes.strftime('%A').capitalize()\n    fecha_primero_de_mes_prox = (fecha_ultima_ejecucion.replace(day=1) + timedelta(days=64)).replace(day=1, hour=0, minute=0, second=0)\n    dia_primero_de_mes_prox = fecha_primero_de_mes_prox.strftime('%A').capitalize()\n    fecha_habilitar = dia_referencia\n    fecha_deshabilitar = dia_referencia\n\n    # la regla es moverse al viernes anterior al proximo primero de mes (y sumar el valor de grupo)\n    # el backup DIARIO debe estar deshabilitado durante el período de corrida del MENSUAL\n    # proximo primero de mes = [mensual habilita viernes anterior al primero de mes siguiente,\n    #                           mensual deshabilita jueves siguiente,\n    #                           diario habilita viernes post mensual,\n    #                           diario deshabilita jueves anterior al primero de mes subsiguiente]\n    offsets = {\n        \"Monday\":    [-3, 3, 4, -4], \"Lunes\":     [-3, 3, 3, -3],\n        \"Tuesday\":   [-4, 2, 3, -5], \"Martes\":    [-4, 2, 2, -4],\n        \"Wednesday\": [-5, 1, 2, -6], \"Miercoles\": [-5, 1, 1, -5], \"Miércoles\": [-5, 1, 1, -5],\n        \"Thursday\":  [-6, 0, 1, -7], \"Jueves\":    [-6, 0, 0, -6],\n        \"Friday\":    [0, 6, 7, -1],  \"Viernes\":   [0, 6, 6,  0],\n        \"Saturday\":  [-1, 5, 6, -2], \"Sabado\":    [-1, 5, 5, -1], \"Sábado\":    [-1, 5, 5, -1],\n        \"Sunday\":    [-2, 4, 5, -3], \"Domingo\":   [-2, 4, 4, -2]\n    }\n\n    if tipo_backup == 'MENSUAL':\n        fecha_habilitar = fecha_primero_de_mes + timedelta(days=offsets[dia_primero_de_mes][0] + grupo)\n        fecha_deshabilitar = fecha_primero_de_mes + timedelta(days=offsets[dia_primero_de_mes][1] + grupo)\n    elif tipo_backup == 'DIARIO':\n        fecha_habilitar = fecha_primero_de_mes + timedelta(days=offsets[dia_primero_de_mes][2] + grupo)\n        fecha_deshabilitar = fecha_primero_de_mes_prox + timedelta(days=offsets[dia_primero_de_mes_prox][3] + grupo)\n\n    return fecha_habilitar, fecha_deshabilitar\n\n\nprint(\"Calculo mi edad al día de hoy:\")\ndia_nacimiento = datetime.strptime(\"23031965141547\", \"%d%m%Y%H%M%S\")\nprint(f\"Nací un {dia_nacimiento.strftime('%A %d de %B de %Y a las %H:%M:%S')}\", end=\". \")\nprint(f\"Tengo {((datetime.now() - dia_nacimiento).days/365).__trunc__()} años.\")\nprint(f\"Si me jubilo a los 70 años será {(dia_nacimiento + relativedelta(years=70)).strftime('%A %d de %B de %Y')}\", end=\"\\n\\n\")\n\nprint(\"Calculo el tiempo de ejecución de un par de tareas:\")\nmi_funcion(\"Mandando algo primero\")\nmi_funcion(\"Mandando otra cosa después\")\n\nprint(\"Calculo los días de habilitación/deshabilitación de backups:\")\ntipo_backup = \"MENSUAL\"\nfecha_expiracion_anterior = datetime.strptime(\"20240404\", \"%Y%m%d\")\nfechas_backup = calcula_fechas_backup(fecha_expiracion_anterior, tipo_backup)\nprint(f\"Expiración anterior del {tipo_backup}: {fecha_expiracion_anterior.strftime('%A %d-%m-%Y')}\")\nprint(f\"Habilito el {tipo_backup} {fechas_backup[0].strftime('%A %c')}  -  Deshabilito el día {fechas_backup[1].strftime('%A %d de %B del %y a las %H:%M:%S')}\")\n\ntipo_backup = \"DIARIO\"\nfecha_expiracion_anterior -= timedelta(days=7)\nfechas_backup = calcula_fechas_backup(fecha_expiracion_anterior, tipo_backup)\nprint(f\"Expiración anterior del {tipo_backup}: {fecha_expiracion_anterior.strftime('%A %d-%m-%Y')}\")\nprint(f\"Habilito el {tipo_backup} {fechas_backup[0].strftime('%A %c')}  -  Deshabilito el día {fechas_backup[1].strftime('%A %d de %B del %y a las %H:%M:%S')}\", end=\"\\n\\n\")\n\ntipo_backup = \"MENSUAL\"\nfecha_expiracion_anterior = datetime.strptime(\"20240502\", \"%Y%m%d\")\nfechas_backup = calcula_fechas_backup(fecha_expiracion_anterior, tipo_backup)\nprint(f\"Expiración anterior del {tipo_backup}: {fecha_expiracion_anterior.strftime('%A %d-%m-%Y')}\")\nprint(f\"Habilito el {tipo_backup} {fechas_backup[0].strftime('%A %c')}  -  Deshabilito el día {fechas_backup[1].strftime('%A %d de %B del %y a las %H:%M:%S')}\")\n\ntipo_backup = \"DIARIO\"\nfecha_expiracion_anterior -= timedelta(days=7)\nfechas_backup = calcula_fechas_backup(fecha_expiracion_anterior, tipo_backup)\nprint(f\"Expiración anterior del {tipo_backup}: {fecha_expiracion_anterior.strftime('%A %d-%m-%Y')}\")\nprint(f\"Habilito el {tipo_backup} {fechas_backup[0].strftime('%A %c')}  -  Deshabilito el día {fechas_backup[1].strftime('%A %d de %B del %y a las %H:%M:%S')}\")\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/nlarrea.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n\"\"\"\n\nfrom datetime import datetime, date\n\ncurrent_date = datetime.now().date()\nbday_date = datetime.strptime(\"1998-06-29 09:25:00\", \"%Y-%m-%d %H:%M:%S\")\n\n\ndef diffYears(date_one: date, date_two: date):\n    return abs(date_one.year - date_two.year)\n\n\nprint(diffYears(current_date, bday_date))\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n\"\"\"\n\nWEEK_DAYS = {\n    0: \"Monday\",\n    1: \"Tuesday\",\n    2: \"Wednesday\",\n    3: \"Thursday\",\n    4: \"Friday\",\n    5: \"Saturday\",\n    6: \"Sunday\",\n}\n\nMONTH_NAMES = {\n    1: \"January\",\n    2: \"February\",\n    3: \"March\",\n    4: \"April\",\n    5: \"May\",\n    6: \"June\",\n    7: \"July\",\n    8: \"August\",\n    9: \"September\",\n    10: \"October\",\n    11: \"November\",\n    12: \"December\",\n}\n\nprint(f\"1. {bday_date.ctime()}\")\nprint(f\"2. {bday_date.date()}\")\nprint(f\"3. {bday_date.isoformat()}\")\nprint(f\"4. {bday_date.hour}:{bday_date.minute}:{bday_date.second}\")\nprint(f\"5. {bday_date.isocalendar()}\")\nprint(f\"6. {bday_date.day}\")\nprint(f\"7. {WEEK_DAYS[bday_date.weekday()]}\")\nprint(f\"8. {bday_date.month}\")\nprint(f\"9. {MONTH_NAMES[bday_date.month]}\")\nprint(f\"10. {bday_date.time()}\")\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/oniricoh.py",
    "content": "###############################################################################\n## EJERCICIO\n###############################################################################\nimport datetime as dt\n\nactual_date = dt.datetime.now()\nformat_actual_date = actual_date.strftime(\"%d/%m/%Y %H:%M:%S\")\nprint(\"Fecha Actual:\", format_actual_date)\n\nbirth_date = dt.datetime(1989, 4, 4, 18, 30, 00)\nformat_birth_date = birth_date.strftime(\"%d/%m/%Y %H:%M:%S\")\nprint(\"Fecha nacimiento:\",format_birth_date)\n\ntime_elapsed = actual_date - birth_date\nprint(\"Tiempo transcurrido: \", time_elapsed)\n\n\n\n###############################################################################\n## DIFICULTAD EXTRA\n###############################################################################\nb_format1 = birth_date.strftime(\"%d, %m, %Y\")\nb_format2 = birth_date.strftime(\"%H, %M, %S\")\nb_format3 = birth_date.strftime(\"%j\")\nb_format4 = birth_date.strftime(\"%A\")\nb_format5 = birth_date.strftime(\"%B\")\nb_format6 = birth_date.strftime(\"%A,%B,%Y\")\n\nfechas = [b_format1, b_format2, b_format3, b_format4, b_format5, b_format6]\n\nfor fecha in fechas:\n    print(fecha)\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/oriaj3.py",
    "content": "\"\"\"\t\n14 - FECHAS\nAutor de la solución: Oriaj3\t\nTeoría:\t\nLas fechas son un tipo de dato muy común en la programación, ya que permiten\nrepresentar y manipular información relacionada con el tiempo. En Python, las\nfechas se pueden representar utilizando el módulo datetime, que proporciona\nuna serie de clases y métodos para trabajar con fechas y horas.\n\nPara crear una fecha en Python, se puede utilizar la clase date del módulo\ndatetime. Esta clase permite crear objetos que representan una fecha en\nformato año-mes-día. Por ejemplo, la siguiente instrucción crea un objeto\ndate que representa la fecha 1 de enero de 2020:\n\nfecha = date(2020, 1, 1)\n\n#strftime() es un método que permite formatear una fecha en una cadena de texto\n#con un formato específico. Tiene los siguientes parámetros:\n\n#%d: día del mes (01-31)\n#%m: mes (01-12)\n#%Y: año (cuatro dígitos)\n\n#%H: hora (00-23)\n#%M: minuto (00-59)\n#%S: segundo (00-59)\n\n#%A: nombre completo del día de la semana\n#%j: día del año (001-366)\n#%B: nombre completo del mes\n\n#%W: número de la semana del año\n\n\"\"\" \n\n\"\"\"\n * EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n\"\"\"\n\nimport datetime as dt\n\n# Fecha actual\nfecha_actual = dt.datetime.now()\n\n# Fecha de nacimiento\nfecha_nacimiento = dt.datetime(1993, 4, 1, 17, 30, 0)\n\n# Cálculo de años transcurridos\ndiferencia = fecha_actual - fecha_nacimiento\n\n# Mostrar años transcurridos\nprint(diferencia.days // 365)\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n\"\"\"\n\n# Formatear fecha de nacimiento.\n# Forma 1 - Día, mes y año - hora, minuto y segundo\nprint(fecha_nacimiento.strftime(\"%d/%m/%Y %H:%M:%S\"))\n\n# Forma 2 - Día, mes y año \nprint(fecha_nacimiento.strftime(\"%d/%m/%Y\")) \n\n# Forma 3 - Hora, minuto y segundo\nprint(fecha_nacimiento.strftime(\"%H:%M:%S\"))\n\n# Forma 4 - Día de la semana\nprint(fecha_nacimiento.strftime(\"%A\")) #%A es el día de la semana\n\n# Forma 5 - Día de año\nprint(fecha_nacimiento.strftime(\"%j\")) #%j es el día del año\n\n# Forma 6 - Nombre del mes\nprint(fecha_nacimiento.strftime(\"%B\")) #%B es el nombre del mes\n\n# Forma 7 - Es año bisiesto \nprint(fecha_nacimiento.strftime(\"%Y\")) #%Y es el año\n\n# Forma 8 - Semana del año\nprint(fecha_nacimiento.strftime(\"%W\")) #%W es la semana del año\n\n# Forma 9 - Día de la semana abreviado\nprint(fecha_nacimiento.strftime(\"%a\")) #%a es el día de la semana abreviado\n\n# Forma 10 - Mes abreviado\nprint(fecha_nacimiento.strftime(\"%b\")) #%b es el mes abreviado\n\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/pyramsd.py",
    "content": "import datetime\n\ncurrent_date = datetime.datetime.now()\nbirthday = datetime.datetime(day=12, month=7, year=2005, hour=15, minute=30, second=0)\n\nprint(current_date.year - birthday.year)\n\n'''\nEXTRA\n'''\n\nprint(birthday.strftime('%a / %b / %y'))\nprint(birthday.strftime('%A / %B / %Y'))\nprint(birthday.strftime('Semana %w / %B /%Y'))\nprint(birthday.strftime('Semana %W del %Y'))\nprint(birthday.strftime('%y / %b / %a'))\nprint(birthday.strftime('Semana %W a las %H horas'))\nprint(birthday.strftime('Semana %w a las %H:%S de %B del %Y'))\nprint(birthday.strftime('%d de %B del %Y'))\nprint(birthday.strftime('El día %d de la semana %w de %B del %Y'))\nprint(birthday.strftime('%D'))\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/qwik-zgheib.py",
    "content": "# -- exercice\nimport datetime\n\n\ndef calculate_age(birth_date: datetime, current_date: datetime) -> int:\n    age: int = current_date.year - birth_date.year\n    if current_date.month < birth_date.month or (\n        current_date.month == birth_date.month and current_date.day < birth_date.day\n    ):\n        age -= 1\n    return age\n\n\ncurrent_date: datetime = datetime.datetime.now()\nbirth_date: datetime = datetime.datetime(2002, 11, 9, 8, 20, 0)\n\nprint(f\"Current date: {current_date}\")\nprint(f\"Binary date: {birth_date}\")\nprint(f\"Years: {calculate_age(birth_date, current_date)}\")\n\n\n# -- extra challenge\ndef format_date(date: datetime) -> None:\n    print(f\"Date: {date}\")\n    print(f\"Date: {date.strftime('%d/%m/%Y')}\")\n    print(f\"Date: {date.strftime('%H:%M:%S')}\")\n    print(f\"Date: {date.strftime('%j')}\")\n    print(f\"Date: {date.strftime('%A')}\")\n    print(f\"Date: {date.strftime('%B')}\")\n    print(f\"Date: {date.strftime('%d/%m/%Y %H:%M:%S')}\")\n    print(f\"Date: {date.strftime('%d/%m/%Y %H:%M:%S %j')}\")\n    print(f\"Date: {date.strftime('%A %B')}\")\n    print(f\"Date: {date.strftime('%A %B %d')}\")\n    print(f\"Date: {date.strftime('%A %B %d %H:%M:%S')}\")\n\n\nformat_date(birth_date)\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/rantamhack.py",
    "content": "'''\n * EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (dia, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuantos años han transcurrido entre ambas fechas.\n'''\n\nprint(\"\\n\\n=======================================EJERCICIO=======================================\\n\\n\")\n\nfrom datetime import datetime\n\nnow = datetime.now()\nprint(f\"\\nLa fecha en el momento actual es: {now}\")\n\nbirth_date = datetime(1962, 7, 9, 19, 15, 00)\nprint(f\"\\nLa fecha de nacimiento de Rantam fue: {birth_date}\")\n\ndef edad():\n    age = now.year - birth_date.year\n    print(f\"\\n La edad actual de rantam es: {age}\")\n    \nedad() \n\n\n \n'''\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formateala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Dia, mes y año.\n * - Hora, minuto y segundo.\n * - Dia de año.\n * - Dia de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n'''\n\nprint(\"\\n\\n=======================================DIFICULTAD EXTRA=======================================\\n\\n\")\n\n\nprint(f\"\\nLa fecha de nacimiento de Rantam fue:\")\n\nprint(f\"\\n\\t 1.- Usando el formato por defecto de  ('AÑO-MES-DIA  HORA-MINUTO-SEGUNDO'): {birth_date}\")\nprint(f\"\\n\\t 2.- usando formato con textos: {birth_date.ctime()}\")\nprint(f\"\\n\\t 3.- Usando dia, mes y año: {birth_date.strftime('%d/%m/%Y')}\")\nprint(f\"\\n\\t 4.- Usando hora, minuto y segundo: {birth_date.strftime('%H:%M:%S')}\")\nprint(f\"\\n\\t 5.- Dia del año: {birth_date.strftime('%j')}\")\nprint(f\"\\n\\t 6.- Dia de la semana: {birth_date.strftime('%A')}\")\nprint(f\"\\n\\t 7.- Mes de nacimiento: {birth_date.strftime('%B')}\")\nprint(f\"\\n\\t 8.- Numero de semana del año: {birth_date.strftime('%U')}\")\nprint(f\"\\n\\t 9.- Dia de la semana, mes, dia,  numero de semana y año en texto: {birth_date.strftime('%A, %B %d, week %U of the year %Y')}\")\nprint(f\"\\n\\t10.- Hora de nacimiento en formato 12 horas: {birth_date.strftime('%I:%M:%S%p')}\")\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/raulG91.py",
    "content": "from datetime import datetime as d\n\ntoday = d.today()\nbirth_day = d(1991,9,11,15,00,00)\nprint(today.isoformat(sep=' ',timespec='seconds'))\nprint(birth_day.isoformat(sep=' ',timespec='seconds'))\n\ndiff = today -birth_day\nprint(diff)\n\n#Extra\nprint(\"Extra\")\n#Format DD-MM-YYYY\nprint(f'{birth_day.day}-{birth_day.month}-{birth_day.year}')\n\n#Format HH:mm:ss\nprint(f'{birth_day.hour}:{birth_day.minute}:{birth_day.second}')\n\n#Week of the month\ncalendar_data = birth_day.isocalendar()\nprint(f'{calendar_data[1]}')\n\n#Day of the week\nday_week = birth_day.weekday()\nif day_week == 0:\n    day_week =\"Monday\"\nelif day_week == 1:\n    day_week = \"Tuesday\"\nelif day_week == 2:\n    day_week = \"Wednesday\"\nelif day_week == 3:\n    day_week = \"Thursday\"\nelif day_week == 4:\n    day_week = \"Friday\" \nelif day_week == 5:\n    day_week = \"Satruday\" \nelif day_week == 6:\n    day_week = \"Sunday\"\n\nprint(day_week)                      \n\n#Month name \nprint(birth_day.strftime(\"%B\"))\n\n#Day name + month name\nprint(birth_day.strftime(\"%A %d. %B %Y\"))\n\n#Extract day of the month \ntuple = birth_day.timetuple()\nprint(tuple[7])"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/raynerpv2022.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n#  * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n#  * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n#  * Calcula cuántos años han transcurrido entre ambas fechas.\n#  *\n\nimport datetime\n\nnow_date = datetime.datetime.now()\nbith_date = datetime.datetime(1979,10,26,19,00,00,00)\nprint(now_date)\nprint(bith_date)\ndif = now_date.year - bith_date.year\n\nprint(f\"Han pasado {dif} annos\" )\n\n\n\n\n\n\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n#  * 10 maneras diferentes. Por ejemplo:\n#  * - Día, mes y año.\n#  * - Hora, minuto y segundo.\n#  * - Día de año.\n#  * - Día de la semana.\n#  * - Nombre del mes.\n#  * (lo que se te ocurra...)\n#  */\n\nprint(f\" Date {bith_date.date()}\")\nprint(f\" Date {bith_date.strftime(\"%d %m %y\")}\")\nprint(f\" Time {bith_date.strftime(\"%H %M %S\")}\")\nprint(f\" Time {bith_date.time()}\")\nprint(f\" Day of the week  {bith_date.strftime(\"%A\")}\")\nprint(f\" Name of Month {bith_date.strftime(\"%B\")}\")\nprint(f\" day of the years {bith_date.strftime(\"%j\")}\")"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/restevean.py",
    "content": "\"\"\"\nEjercicio\n\"\"\"\nfrom datetime import datetime\n\ncurrent_date = datetime.now()\nbirthdate = datetime(1990, 4, 15, 0, 0, 0)\n\n\ndef calculate_age(current, birth):\n    age = current.year - birth.year - ((current.month, current.day) < (birth.month, birth.day))\n    return age\n\n\n\"\"\"\nExtra\n\"\"\"\nformats = {\n    \"1. Día, mes y año\": birthdate.strftime(\"%d/%m/%Y\"),\n    \"2. Hora, minuto y segundo\": birthdate.strftime(\"%H:%M:%S\"),\n    \"3. Día del año\": birthdate.strftime(\"%j\"),\n    \"4. Día de la semana\": birthdate.strftime(\"%A\"),\n    \"5. Nombre del mes\": birthdate.strftime(\"%B\"),\n    \"6. Fecha en formato ISO\": birthdate.isoformat(),\n    \"7. Fecha larga con nombre del día\": birthdate.strftime(\"%A, %d de %B de %Y\"),\n    \"8. Fecha corta\": birthdate.strftime(\"%d/%m/%y\"),\n    \"9. Fecha con nombre del mes y día de la semana\": birthdate.strftime(\"%A, %d de %B\"),\n    \"10. Tiempo UNIX\": int(birthdate.timestamp())\n}\n\n\nif __name__ == \"__main__\":\n    print( \"La edad es:\", calculate_age(current_date, birthdate))\n    for name, format_example in formats.items():\n        print(f\"{name}: {format_example}\")\n\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/rigo93acosta.py",
    "content": "'''\n * EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n'''\n\n'''\nEjercicio\n'''\n\nfrom datetime import datetime\n\nnow = datetime.now()\nbirthday = datetime(1993, 5, 25, 0, 0, 0)\n\nif now.month < birthday.month or (now.month == birthday.month and now.day < birthday.day):\n    years = now.year - birthday.year - 1\nelse:\n    years = now.year - birthday.year\n\nprint(f\"Han pasado {years} años desde mi nacimiento\")\n\n'''\nExtra\n'''\n\n# Día, mes y año\nprint(f'{birthday.strftime(\"%d/%m/%y\")}')\nprint(f'{birthday.strftime(\"%d/%m/%Y\")}')\n\n# Hora, minuto y segundo\nprint(f'{birthday.strftime(\"%H:%M:%S\")}')\n\n# Día de año\nprint(f'{birthday.strftime(\"%j\")}')\n\n# Día de la semana\nprint(f'{birthday.strftime(\"%A\")}')\n\n# Nombre del mes\nprint(f'{birthday.strftime(\"%B\")}')\nprint(f'{birthday.strftime(\"%h\")}')\n\n# Representación por defecto del locale\nprint(f'{birthday.strftime(\"%c\")}')\nprint(f'{birthday.strftime(\"%x\")}')\nprint(f'{birthday.strftime(\"%X\")}')\n\n# AM/PM\nprint(f'{birthday.strftime(\"%I:%M:%S %p\")}')"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/roswer13.py",
    "content": "# EJERCICIO:\n# Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n# - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n# - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n# Calcula cuántos años han transcurrido entre ambas fechas.\nimport unittest\nfrom datetime import datetime\n\ndef get_dates() -> tuple:\n    now = datetime.now()\n    birth = datetime(1993, 2, 13, 6, 36, 34)\n    return now, birth\n\ndef calcuates_years_difference(now: datetime, birth: datetime) -> int:\n    nowYear = now.year\n    birthYear = birth.year\n\n    if nowYear>=birthYear:\n        return nowYear - birthYear\n    \n    return birthYear - nowYear\n\nif __name__ == '__main__':\n    now, birth = get_dates()\n    print(f\"Tiempo transcurrido desde el nacimiento: {calcuates_years_difference(now, birth)} años.\")\n\n# DIFICULTAD EXTRA (opcional):\n# Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n# 10 maneras diferentes. Por ejemplo:\n# - Día, mes y año.\n# - Hora, minuto y segundo.\n# - Día de año.\n# - Día de la semana.\n# - Nombre del mes.\ndef calculate_date_format(birth: datetime, format: str) -> str:\n    return birth.strftime(format)\n\nif __name__ == '__main__':\n    _, birth = get_dates()\n    print(f\"Día, mes y año: {calculate_date_format(birth, '%d/%m/%Y')}\") # 13/02/1993\n    print(f\"Hora, minuto y segundo: {calculate_date_format(birth, '%H:%M:%S')}\") # 06:36:34\n    print(f\"Día de año: {calculate_date_format(birth, '%j')}\") # 044\n    print(f\"Día de la semana: {calculate_date_format(birth, '%A')}\") # Saturday\n    print(f\"Nombre del mes: {calculate_date_format(birth, '%B')}\") # February\n\n# TESTS\n\nclass TestDate(unittest.TestCase):\n    def test_get_dates(self):\n        # Arrange\n        # Act\n        now, birth = get_dates()\n        # Assert\n        self.assertTrue(type(now) == datetime)\n        self.assertTrue(type(birth) == datetime)\n\n    def test_calculates_years_difference(self):\n        # Arrange\n        now = datetime(2021, 6, 30, 12, 0, 0)\n        birth = datetime(1993, 6, 30, 8, 0, 0)\n        # Act\n        result = calcuates_years_difference(now, birth)\n        # Assert\n        self.assertTrue(result == 28)\n\n    def test_calculate_date_format(self):\n        # Arrange\n        birth = datetime(1993, 2, 13, 6, 36, 34)\n        # Act\n        # Assert\n        self.assertTrue(calculate_date_format(birth, '%d/%m/%Y') == \"13/02/1993\")\n        self.assertTrue(calculate_date_format(birth, '%H:%M:%S') == \"06:36:34\")\n        self.assertTrue(calculate_date_format(birth, '%j') == \"044\")\n        self.assertTrue(calculate_date_format(birth, '%A') == \"Saturday\")\n        self.assertTrue(calculate_date_format(birth, '%B') == \"February\")\n\nif __name__ == '__main__':\n    unittest.main()"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/santyjl.py",
    "content": "#14 FECHAS\n\"\"\"\n/*\n * EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n */\n\"\"\"\n\nfrom datetime import datetime\n\nfecha_actual = datetime.now()\nfecha_nacimiento = datetime(2010 , 1 , 20 , 20 , 17 , 24)\n\ndef calcular_diferencia_de_años(actual : datetime , nacimiento : datetime):\n    año_1 = actual.year\n    año_2 = nacimiento.year\n\n    if año_2 > año_1 :\n        return año_2 - año_1\n\n    return año_1 - año_2\n\naños_transcurridos = calcular_diferencia_de_años(fecha_actual , fecha_nacimiento)\nprint(f\"desde tu nacimiento hasta la actualidad han transcurrido : {años_transcurridos}años\")\n\n### Extra\nprint(\"\\Diferentes formas para ver una fecha\")\n\nprint(datetime.strftime(fecha_nacimiento , \"%d/%m/%y\")) #dia/mes/año\nprint(datetime.strftime(fecha_nacimiento , \"%H: %M: %S\")) #hora:minuto:segundo\nprint(datetime.strftime(fecha_nacimiento , \"%j\")) # dia del año\nprint(datetime.strftime(fecha_nacimiento , \"%A\")) #dia de la semana\nprint(datetime.strftime(fecha_nacimiento , \"%B\")) #mes\nprint(datetime.strftime(fecha_nacimiento , \"%B-%d-%y\")) #mes-dia-año\nprint(datetime.strftime(fecha_nacimiento , \"%y/%m/%d\")) #año/mes/dia\nprint(datetime.strftime(fecha_nacimiento , \"%A/%B/%H:%M\")) #dia_nombre/mes_nombre/hora:minuto\n\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/sorubadguy.py",
    "content": "from datetime import datetime\nimport calendar\n\nahora = datetime.now()\nnac = datetime(1994, 3, 27, 11, 32, 16)\nprint(f\"han pasado {(ahora.year - nac.year)} años\")\n\n#!Extra\n\nprint(f\"{nac.year}/{nac.month}/{nac.day}\")\nprint(f\"{nac.day}/{nac.month}/{nac.year}\")\nprint(f\"{nac.year}/{nac.month}\")\nprint(f\"{nac.hour}:{nac.minute}\")\nprint(f\"{nac.minute}:{nac.second}\")\nprint(f\"{nac.day}/{nac.month}\")\nprint(nac.strftime(\"%H:%M %d/%b/%Y\"))\nprint(nac.strftime(\"%d/%b\"))\nprint(f\"son las: {ahora.strftime('%H:%M')}\")\nprint(f\"naci el: {calendar.day_name[calendar.weekday(nac.year, nac.month, nac.day)]} {nac.day} de {calendar.month_name[nac.month]} de {nac.year}\")"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/sperezsa.py",
    "content": "from datetime import datetime\n\nnow = datetime.now()\n\n# Me quedo con la parte de la fecha sin los milisegundos\nnow_format = datetime.strptime(str(now).split(\".\")[0], \"%Y-%m-%d %H:%M:%S\")\n\nprint(f\"Fecha actual en formato '%Y-%m-%d %H:%M:%S': {now_format}\")\n\nbirth_date = datetime(1979, 9, 8, 12, 23, 59)\nprint(f\"Fecha de nacimiento: {birth_date}\")\n\nprint(f\"Resta de fechas en años: {(now - birth_date).days / 365.25}\")\n\n\"\"\"\nExtra\n\"\"\"\n\nprint(\"EXTRA\")\n\ndias_semana = [\"Lunes\", \"Martes\", \"Miércoles\", \"Jueves\", \"Viernes\", \"Sábado\", \"Domingo\"]\nmeses = [\"Enero\", \"Febrero\", \"Marzo\", \"Abril\", \"Mayo\", \"Junio\", \"Julio\", \"Agosto\", \"Septiembre\", \"Octubre\", \"Noviembre\", \"Diciembre\"]\n\n# Dia, mes, año\nprint(\"Día, mes, año:\", birth_date.strftime(\"%d-%m-%Y\"))\n\n# hora, min, segundo\nprint(\"Hora, min, segundo:\", birth_date.strftime(\"%H:%M:%S\"))\n\n# día del año desde 01-ene\nprint(\"Día del año desde 01-ene:\", birth_date.strftime(\"%j\"))\n\n# día de la semana, en Inglés y en Castellano\nprint(\"Día de la semana, en Inglés y en Castellano:\", birth_date.strftime(\"%A\"), dias_semana[birth_date.weekday()])\n\n#Nombre del mes, en Inglés y en Castellano\nprint(\"Nombre del mes, en Inglés y en Castellano:\", birth_date.strftime(\"%B\"),meses[birth_date.month-1])\n\n\n\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/victorfer69.py",
    "content": "from datetime import datetime\n\n#Ejercicio\n\nnow = datetime.now()\nbirth_date = datetime(2003, 9, 6, 12, 0, 0)\n\nprint(now)\nprint(birth_date)\n\ndifference = now - birth_date\n\nprint(type(difference))\nprint(f\"Tengo {difference.days // 365} años\")\n\n\n#EJERCICIO EXTRA\n\naños = difference.days // 365\nmeses = difference.days % 12\ndias = difference.days % 30\nprint(f\"Tengo {años} años, {meses} meses y {dias} días.\")\n\n# Día, mes y año\nprint(birth_date.strftime(\"%d/%m/%y\"))\nprint(birth_date.strftime(\"%d/%m/%Y\"))\n\n# Horas, minutos y segundos\nprint(birth_date.strftime(\"%H:%M:%S\"))\n\n# Día del año\nprint(birth_date.strftime(\"%j\"))\n\n# Día de la semana\nprint(birth_date.strftime(\"%A\"))\n\n# Nombre del mes\nprint(birth_date.strftime(\"%h\"))\nprint(birth_date.strftime(\"%B\"))\n\n# Representación por defecto del locale\nprint(birth_date.strftime(\"%c\"))\nprint(birth_date.strftime(\"%x\"))\nprint(birth_date.strftime(\"%X\"))\n\n# AM/PM\nprint(birth_date.strftime(\"%p\"))"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/worlion.py",
    "content": "import datetime\nimport dateutil.relativedelta\n\n\"\"\"\n* EJERCICIO: Fechas\n\"\"\"\n\nnow = datetime.datetime.now()\nprint(f\"Today is: {now.strftime('%x')}\")\n\nmy_birthday = datetime.datetime(1984, 4, 20)\nprint(f\"born in {my_birthday.strftime('%x')}\")\n\ndelta = dateutil.relativedelta.relativedelta(now, my_birthday)\nprint(f\"Tienes {delta.years} años, 'chaval'... 🤨\")\n\n\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n* Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n* 10 maneras diferentes. Por ejemplo:\n* - Día, mes y año.\n* - Hora, minuto y segundo.\n* - Día de año.\n* - Día de la semana.\n* - Nombre del mes.\n* (lo que se te ocurra...)\n\"\"\"\n\nprint(\"\\n ---- 🌩 DIFICULTAD EXTRA 🌩 ----\\n\")\n\n\nprint(f\"1.- Fecha simple: {my_birthday.strftime('%x')}\")\n# my_birthday.hour = 23\n# my_birthday.minute = 30\n\nprint(f\"2.- Hora: {my_birthday.strftime('%X')}\")\nprint(f\"3.- Hora (AM/PM): {my_birthday.strftime('%I:%M %p')}\")\nprint(f\"4.- Fecha simple completa: {my_birthday}\")\nprint(f\"5.- Fecha con día sem: {my_birthday.strftime('%A %Y/%m/%d')}\")\nprint(f\"6.- Día del año: {my_birthday.strftime('%j')} - semana número: {my_birthday.strftime('%W')}\")\nprint(f\"7.- Fecha local: {my_birthday.strftime('%c')}\")\nprint(f\"8.- Fecha larga: {my_birthday.strftime('%A %B %d of %Y')}\")\nprint(f\"9.- Siglo: {int(my_birthday.strftime('%C'))+1}\") #Sale el 19 🤔\nprint(f\"10.- Mes: {my_birthday.strftime('%B (%h)')}\")\n\n\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/ycanas.py",
    "content": "import datetime\n\n# ------ 1. Ejercicio\n\nactual = datetime.datetime.now()\nbirth = datetime.datetime(2000, 1, 3, 6, 0, 0, 0)\n\ndifference = actual - birth\nyears = int(difference.days / 365)\ndays = difference.days % 365\n\nprint(f\"Desde mi nacimiento han pasado: {years} años y {days} días.\")\n\n\n# ------ 2. Extra\n\nprint(\"Día mes y año →\", birth.strftime(\"%d/%m/%Y\"))\nprint(\"Hora minuto y segundo →\", birth.strftime(\"%H:%M:%S\"))\nprint(\"Día del año →\", birth.strftime(\"%j\"))\nprint(\"Día de la semana →\", birth.strftime(\"%w\"))\nprint(\"Nombre del mes →\", birth.strftime(\"%B\"))\nprint(\"Nombre del día de la semana →\", birth.strftime(\"%A\"))\nprint(\"Número de semana del año →\", birth.strftime(\"%W\"))\nprint(\"¿AM o PM? →\", birth.strftime(\"%p\"))\nprint(\"Nombre del día, día, nombre del mes y año →\", birth.strftime(\"%A %d %B %Y\"))\nprint(\"Número del mes\", birth.strftime(\"%m\"))\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/yenneralayon142.py",
    "content": "from datetime import datetime\n\n\"\"\"\nFechas\n\"\"\"\n\nnow = datetime.now()\nmy_birhtday = datetime(2003,5, 30, 17,0,0)\n\ndifference = now - my_birhtday\nprint(f\"Tengo {difference.days // 365} años\")\n\n\n\"\"\"\nExtra\n\"\"\"\n# Dia,mes, año\nprint(my_birhtday.strftime(\"%d-%m-%y\"))\nprint(my_birhtday.strftime(\"%d/%m/%Y\"))\n\n#Dia\nprint(my_birhtday.strftime(\"%a\"))\n\n#Dia del año\nprint(my_birhtday.strftime(\"%j\"))\n\n#Mes\nprint(my_birhtday.strftime(\"%h\"))\n\n#Mes\nprint(my_birhtday.strftime(\"%B\"))\n\n#AM/PM\nprint(my_birhtday.strftime(\"%p\"))\n\n# Representación por defecto del locale\nprint(my_birhtday.strftime(\"%x\"))\nprint(my_birhtday.strftime(\"%c\"))\n\n# Numero de la semana\nprint(my_birhtday.strftime(\"%W\"))"
  },
  {
    "path": "Roadmap/14 - FECHAS/python/zetared92.py",
    "content": "# RETO 14 FECHAS\n\nfrom datetime import datetime\n\n\"\"\"\nCREA DOS VARIABLES CON LOS OBJETOS FECHA\n(año, mes, día, hora, minutos, segundos)\n1: FECHA ACTUAL \n2: FECHA DE NACIMIENTO\n= AÑOS TRANSCURRIDOS ENTRE AMBAS FECHAS\n\"\"\"\n\nnow = datetime.now()\nbirth_date = datetime(1992, 12, 3, 16, 30, 0)\n\nprint(now)\nprint(birth_date)\n\ndiferrence = now - birth_date\nprint(type(diferrence))\n\nprint(f\"I have {diferrence.days // 365} years.\")\n\n\n# Extra\n\nprint(\"🧩 DIFICULTAD EXTRA - 10 MANERAS DE MOSTRAR LA FECHA 🧩\")\n\n# Día, mes y año\nprint(birth_date.strftime(\"%d/%m/%y\"))\n\n# Hora, minutos y segundos\nprint(birth_date.strftime(\"%H:%M:%S\"))\n\n# Día del año\nprint(birth_date.strftime(\"%j\"))\n\n# Día de la semana\nprint(birth_date.strftime(\"%A\"))\n\n# Nombre del mes\nprint(birth_date.strftime(\"%B\"))\n\n# Locale\nprint(birth_date.strftime(\"%c\"))\n\n# AM/PM\nprint(birth_date.strftime(\"%p\"))"
  },
  {
    "path": "Roadmap/14 - FECHAS/ruby/Elmer125.rb",
    "content": "#  * EJERCICIO:\n#  * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n#  * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n#  * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n#  * Calcula cuántos años han transcurrido entre ambas fechas.\nrequire 'date'\n\ntoday = DateTime.now\nbirth_date = DateTime.parse(\"14-09-1995 10:05:33\")\n\nyears = today.year - birth_date.year\nputs \"Years: #{years}\"\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n#  * 10 maneras diferentes. Por ejemplo:\n#  * - Día, mes y año.\n#  * - Hora, minuto y segundo.\n#  * - Día de año.\n#  * - Día de la semana.\n#  * - Nombre del mes.\n#  * (lo que se te ocurra...)\n\nputs \"Day/Month/Year: #{birth_date.strftime('%d/%m/%Y')}\"\nputs \"Year/Month/Day: #{birth_date.strftime('%Y/%m/%d')}\"\nputs \"Hours:Mins:Secs: #{birth_date.strftime('%H:%M:%S')}\"\nputs \"Day of the year: #{birth_date.yday}\"\nputs \"Day of the week: #{birth_date.strftime('%A')}\"\nputs \"Month name: #{birth_date.strftime('%B')}\"\nputs \"Full date: #{birth_date.strftime('%A, %d de %B de %Y')}\"\nputs \"Week of the year: #{birth_date.strftime('%U')}\"\nputs \"Month and year: #{birth_date.strftime('%B %Y')}\"\nputs \"AM/PM: #{birth_date.strftime('%p')}\"\n\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/rust/kenysdev.rs",
    "content": "/*\n╔═══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado                ║\n║ GitHub: https://github.com/Kenysdev   ║\n║ 2024 -  Rust                          ║\n╚═══════════════════════════════════════╝\n-----------------------------------------\n* FECHAS\n-----------------------------------------\nEn Rust, la forma predeterminada de trabajar con fechas y horas es con crono.\nMas info: https://crates.io/crates/chrono\n\n[dependencies]\nchrono = \"0.4.37\"\n\n_______________\n* EJERCICIO 1\n* Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n* - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n* - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n* Calcula cuántos años han transcurrido entre ambas fechas.\n*/\nuse chrono::prelude::*;\n\nfn date_diff(now: DateTime<Local>, birth_date: DateTime<Utc>) {\n    let difference = now.signed_duration_since(birth_date);\n    let years = difference.num_days() / 365;\n    let months = (difference.num_days() % 365) / 30;\n    let days = (difference.num_days() % 365) % 30;\n    println!(\"Juanito tiene: {years} años, {months} meses y {days} días.\");\n}\n\n/* \n_______________\n* EJERCICIO 2\n* Utilizando la fecha de tu cumpleaños, formatéala y muestra su \n  resultado de 10 maneras diferentes.\n*/\n\nfn others_format(birth_date: DateTime<Utc>) {\n    println!(\"\\n* 10 maneras diferentes:\");\n    println!(\"1. Predeterminado   -> {}\", birth_date.format(\"%Y-%m-%d %H:%M:%S\"));\n    println!(\"2. Fecha larga      -> {}\", birth_date.format(\"%A, %d de %B de %Y\"));\n    println!(\"3. dd-mm-yyyy       -> {}\", birth_date.format(\"%d-%m-%Y\"));\n    println!(\"4. Nombre del mes   -> {}\", birth_date.format(\"%B\"));\n    println!(\"5. Mes abreviado    -> {}\", birth_date.format(\"%b\"));\n    println!(\"6. Nombre dia       -> {}\", birth_date.format(\"%A\"));\n    println!(\"7. Dia abreviado    -> {}\", birth_date.format(\"%a\"));\n    println!(\"8. Hora (12 horas)  -> {}\", birth_date.format(\"%I:%M:%S %p\"));\n    println!(\"9. Hora (24 horas)  -> {}\", birth_date.format(\"%H:%M:%S\"));\n    println!(\"0. Personalizado    -> {}\", birth_date.format(\"Born on %A, %dth of %B %Y at %I:%M:%S %p\"));\n}\n\nfn main() {\n    let now: DateTime<Local> = Local::now();\n    let birth_date = Utc.with_ymd_and_hms(1995, 10, 20, 12, 30, 0).unwrap(); \n    date_diff(now, birth_date);\n\n    others_format(birth_date);\n}\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/sql/Nicojsuarez2.sql",
    "content": "# #14 FECHAS\n> #### Dificultad: Fácil | Publicación: 01/04/24 | Corrección: 08/04/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/swift/allbertoMD.swift",
    "content": "import Foundation\n\n// Obtener la fecha actual.\nlet currentDate = Date()\nprint(\"\\nEsta es la fecha de hoy.\")\nprint(currentDate)\n\n// Crear un calendario gregoriano.\nlet calendar = Calendar(identifier: .gregorian)\n\n// Especifica la fecha de nacimiento.\nvar birthComponent = DateComponents()\nbirthComponent.year = 1984\nbirthComponent.month = 7\nbirthComponent.day = 4\nbirthComponent.hour = 04\nbirthComponent.minute = 17\nbirthComponent.second = 48\n\n// Obtener la fecha de nacimiento.\n// var birthDate = Date()\nguard let birthDate = calendar.date(from: birthComponent) else {\n    fatalError(\"No hay datos.\")\n}\nprint(\"\\n Esta es la fecha de mi nacimiento.\")\nprint(birthDate)\n\n// Calcular la diferencia entre las fechas.\nlet yearsApart: DateComponents = calendar.dateComponents([.year], from: birthDate, to: currentDate)\nlet monthsApart = calendar.dateComponents([.month], from: birthDate, to: currentDate)\nlet daysApart = calendar.dateComponents([.day], from: birthDate, to: currentDate)\nlet hoursApart = calendar.dateComponents([.hour], from: birthDate, to: currentDate)\nlet minutesApart = calendar.dateComponents([.minute], from: birthDate, to: currentDate)\nlet secondsApart = calendar.dateComponents([.second], from: birthDate, to: currentDate)\n\nprint(\"\\nEstos son las difrerencias.\")\n\n// Imprimir la diferencia en años.\nif let years = yearsApart.year {\n    print(\"Hay: \\(years) años de diferencia.\")    \n}\n// Imprimir la diferencia en meses.\nif let months = monthsApart.month {\n    print(\"Hay \\(months) meses de diferencia.\")\n}\n// Imprimir la diferencia en dias.\nif let days = daysApart.day {\n    print(\"Hay: \\(days) dias de diferencia.\")\n}\n// Imprime la diferencia en horas.\nif let hours = hoursApart.hour {\n    print(\"Hay: \\(hours) horas de diferencia.\")\n}\n// imprime la diferencia en minutos.\nif let minutes = minutesApart.minute {\n    print(\"Hay: \\(minutes) minutos de direrencia.\")\n}\n// Imprime la diferencia en segundos.\nif let seconds = secondsApart.second {\n    print(\"Hay: \\(seconds) segundos de diferencia.\")\n}\n\n\n\n\n// DIFICULTAD EXTRA\nprint(\"\\nDIFICULTAD EXTRA\")\n\n\n\n\n// Crear un DateFormatter.\nlet dateFormatter = DateFormatter()\n\n// Establecer el formato de la fecha original.\ndateFormatter.dateFormat = \"dd-MM-yyyy\"\nlet originalDate = \"04-07-2024\"\n\nprint(\"\\nFecha Original:\")\nprint(\"\\(originalDate)\")\n\n// Convertir la cadena de fecha a un objeto Date.\nguard let date = dateFormatter.date(from: originalDate) else {\n    fatalError(\"Error al convertir la fecha\")\n}\n\nprint(\"\\nLos 10 formatos:\")\n// Crear un array con 10 formatos diferentes para formatear la fecha.\nlet formats = [\n    \"dd-MM-yyyy\",\n    \"MM-dd-yyyy\",\n    \"yyyy-MM-dd\",\n    \"EEEE, d MMMM yyyy\",\n    \"dd/MMM/yyyy\",\n    \"MMM dd, yyyy\",\n    \"MMMM d, yyyy\",\n    \"yyyy/MM/dd\",\n    \"MMM d, yyyy h:mm a\",\n    \"MMMM dd, yyyy HH:mm:ss\"\n]\n\n// Imprimir la fecha formateada en los diferentes formatos.\nfor format in formats {\n    dateFormatter.dateFormat = format\n    let formattedDate = dateFormatter.string(from: date)\n    print(formattedDate)\n}\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/swift/blackriper.swift",
    "content": "import Foundation\n\n/*\n Para manejar fechas en swift se puede usar la clase Date o la clase DateFormatter para formatearlas\n también se puede usar la clase Calendar para realizar operaciones con fechas.\n */\n\n enum DateError: Error {\n    case invalidDate\n }\n\n// fecha actual\n let currentDate = Date()\n print(currentDate)\n\n// instacia de calendar\n let calendar = Calendar.current\n// crear una fecha    \n var componets = DateComponents()\n componets.day = 20\n componets.month = 5\n componets.year = 1994\n componets.hour =  13 \n componets.minute = 30\n componets.second = 0\n\n guard let bithday = calendar.date(from: componets) else {\n        throw DateError.invalidDate\n  }\n print(bithday)\n\n if let years = calendar.dateComponents([.year], from: bithday, to: currentDate).year {\n    print(\"Iam \\(years) years old\")\n }\n\nlet formatted = DateFormatter()\n\n// dia mes año\nformatted.dateFormat = \"dd/MM/yyyy\"\nprint(formatted.string(from: bithday))\n// hora minuto segundo\nformatted.dateFormat = \"HH:mm:ss\"\nprint(formatted.string(from: bithday))\n// nombre del mes \nformatted.dateFormat = \"LLLL\"\nprint(formatted.string(from: bithday))\n\nif let dayofWeek = calendar.dateComponents([.weekday], from: bithday).weekday{\n    print(\"I was born on a \\(dayofWeek) day\")\n}\n\nif let dayofYear = calendar.ordinality(of: .day, in: .year, for: bithday){\n   print(\"I was born on the \\(dayofYear) day of the year\")\n}\n\n\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/swift/kontroldev.swift",
    "content": "import Foundation\n\n/*\n * EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n */\n\n\n// Obtén la fecha actual\nlet currentDate = Date()\n\n// Configura el formato de la fecha\nlet dateFormatter = DateFormatter()\ndateFormatter.dateFormat = \"yyyy/MM/dd HH:mm:ss\"\n\n// Define tu fecha de nacimiento (por ejemplo, 1 de enero de 1990 a las 12:00:00)\nlet birthDateString = \"1990/01/01 12:00:00\"\nguard let birthDate = dateFormatter.date(from: birthDateString) else {\n    fatalError(\"Error al convertir la cadena de fecha a objeto Date\")\n}\n\n// Calcula la diferencia de años entre la fecha actual y la fecha de nacimiento\nlet calendar = Calendar.current\nlet ageComponents = calendar.dateComponents([.year], from: birthDate, to: currentDate)\nlet age = ageComponents.year!\n\nprint(\"Han transcurrido \\(age) años desde tu fecha de nacimiento.\")\n\n\n//MARK: - DIFICULTAD EXTRA (opcional)\n\n// Configura el formato de la fecha\nlet dateFormatter2 = DateFormatter()\ndateFormatter.dateFormat = \"yyyy/MM/dd HH:mm:ss\"\n\n// Define tu fecha de nacimiento (por ejemplo, 1 de enero de 1990 a las 12:00:00)\nlet birthDateString2 = \"1990/01/01 12:00:00\"\nguard let birthDate = dateFormatter.date(from: birthDateString) else {\n    fatalError(\"Error al convertir la cadena de fecha a objeto Date\")\n}\n\n// Función para formatear y mostrar la fecha en diferentes formatos\nfunc displayFormattedDates(for date: Date) {\n    let formats = [\n        \"dd/MM/yyyy\",              // Día, mes y año\n        \"HH:mm:ss\",                // Hora, minuto y segundo\n        \"D\",                       // Día del año\n        \"EEEE\",                    // Día de la semana\n        \"MMMM\",                    // Nombre del mes\n        \"MM/dd/yyyy HH:mm\",        // Mes/día/año hora:minuto\n        \"yyyy/MM/dd\",              // Año/mes/día\n        \"MMM d, yyyy\",             // Mes abreviado día, año\n        \"EEEE, MMM d, yyyy\",       // Día de la semana, mes abreviado día, año\n        \"E, d MMM yyyy HH:mm:ss\",  // Día de la semana abreviado, día mes año hora:minuto:segundo\n    ]\n    \n    for format in formats {\n        dateFormatter.dateFormat = format\n        let formattedDate = dateFormatter.string(from: date)\n        print(\"Formato '\\(format)': \\(formattedDate)\")\n    }\n}\n\n// Muestra las diferentes representaciones de la fecha de nacimiento\ndisplayFormattedDates(for: birthDate)\n\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/swift/pedroomar23.swift",
    "content": "import Foundation\n\n/*\n * EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n */\n\nenum DateError: Error {\n    case dateInvalid\n}\n\nlet currentDate = Date()\nprint(currentDate)\n\nlet calendar = Calendar.current\nvar components = DateComponents()\ncomponents.day = 20\ncomponents.month = 3\ncomponents.year = 2024\ncomponents.hour = 3\ncomponents.minute = 25\ncomponents.second = 30\n\nguard let bithday = calendar.date(from: components) else {\n    throws DateError.dateInvalid\n}\n\nprint(bithday)\n\nlet years = calendar.dateComponents([.year], from: bithday, to: components).year {\n    print(\"Ahora mismo tengo \\(year) años de edad\")\n}\n\n\n\n\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/typescript/AChapeton.ts",
    "content": "const currentDate: Date = new Date()\nconsole.log(currentDate)\nconst birthDate: Date = new Date(1997, 5, 2, 13, 30, 0)\nconsole.log(birthDate)\n\nconst getYearsBetweenDates = (birthDate: Date, currentDate:Date = new Date()) => {\n  const birthTime = new Date(birthDate).getTime()\n  const currentTime = new Date(currentDate).getTime()\n  const age = (currentTime - birthTime) / (365 * 24 * 60 * 60 * 1000)\n  return Math.floor(age)\n}\n\nconsole.log(getYearsBetweenDates(birthDate))\n\nconst days = ['Domingo', 'Lunes', 'Martes', 'Miercoles', 'Jueves', 'Viernes', 'Sabado']\nconst months = ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre']\n\nconst isLeapYear = y => y % 4 === 0 && y % 100 !== 0 || y % 400 === 0;\nconst daysInAYear = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\n\n\n// DIFICULTAD EXTRA\nconsole.log('Dia, mes, y año: ', birthDate.getDay() + 1, '/', months[birthDate.getMonth()], '/', birthDate.getFullYear())\nconsole.log('Hora, minuto y segundo: ', 'Hora: ', birthDate.getHours(), ' Minutos: ', birthDate.getMinutes(), ' Segundos: ', birthDate.getSeconds())\nconsole.log('Dia de la semana: ', (birthDate.getDay() > 7) ? days[birthDate.getDay() - 7] : days[birthDate.getDay()])\nconsole.log('Nombre del mes: ', months[birthDate.getMonth()])\nconsole.log('Año: ', birthDate.getFullYear())\nconsole.log('Version ingles: ', birthDate.toDateString())\n\nfunction dayOfYear ( date ) {\n  const d = new Date(date);\n  const daysGiven = d.getDate();\n  const month = d.getMonth();\n  const year = d.getFullYear();\n\n  if ( isLeapYear(year) && month > 1) {\n      return daysInAYear.slice(0, month).reduce( (a, c) => a + c, 0) + 1 + daysGiven;\n  } else {\n      return daysInAYear.slice(0, month).reduce( (a, c) => a + 1, 0) + daysGiven;\n  }\n}\n\nconsole.log('Dia de año: ', dayOfYear(\"06/02/2020\"))\nconsole.log('Fecha completa: ', birthDate.getDay() + 1, ' de ', months[birthDate.getMonth()], ' de ', birthDate.getFullYear())\nconsole.log('Mes/Dia/Año: ', birthDate.toLocaleDateString())\nconsole.log('Formato Tiempo 12 horas: ', birthDate.toLocaleTimeString())\nconsole.log('Formato Tiempo 24 horas: ', birthDate.toTimeString())\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/typescript/IgleDev.ts",
    "content": "// 1º Ejercicio\n\n    let fechaActual : Date = new Date();    // Cojemos la fecha entera\n\n    console.log(fechaActual);   // Mostramos la fecha\n\n    let fechaNacimiento: Date = new Date(2004, 10, 3, 3, 30, 0); // (año, mes, día, hora, minuto, segundo)\n    // En TS y JS los meses empiezan en el 0 y acaban en el 11, por lo cual Noviembre es el 10.\n\n    console.log(fechaNacimiento);   // Mostramos la fecha\n\n    let diferenciaAnhos : number = fechaActual.getFullYear() - fechaNacimiento.getFullYear();\n\n    console.log(diferenciaAnhos);\n\n// Ejercicio Extra\n\n    // 1º Mostrando Día, mes y año\n    // El +1 es importante en el 'getMonth()' debido a que los meses en TS empiezan en el 0\n    console.log(`${fechaNacimiento.getDay()}/${fechaNacimiento.getMonth() +1 }/${fechaNacimiento.getFullYear()}`);\n\n    // 2º Mostrando Hora, minuto y segundo.\n    console.log(`${fechaNacimiento.getHours()}/${fechaNacimiento.getMinutes() +1 }/${fechaNacimiento.getSeconds()}`);\n\n    // 3º Mostrar por Día de año\n    function diaDelAnho(fecha: Date): number {\n        let anhoPorDefecto = new Date(fecha.getFullYear(), 0, 0);\n        let diferencia = (fecha.getTime() - anhoPorDefecto.getTime()) + ((anhoPorDefecto.getTimezoneOffset() - fecha.getTimezoneOffset()) * 60 * 1000);\n        let dia = 1000 * 60 * 60 * 24;\n        return Math.floor(diferencia / dia);\n    }\n    console.log(`${diaDelAnho(fechaNacimiento)}`);\n\n    // 4º Mostrar por Día de la semana.\n    function nombreDiaSemana(dia: number): string {\n        let diasSemana: string[] = ['Domingo', 'Lunes', 'Martes', 'Miércoles', 'Jueves', 'Viernes', 'Sábado'];\n        return diasSemana[dia];\n    }\n    console.log(`${nombreDiaSemana(fechaNacimiento.getDay())}`);\n\n    // 5º Mostrar por Nombre del mes.\n    function obtenerNombreMes(mes: number): string {\n        let meses: string[] = ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'];\n        return meses[mes];\n    }\n    console.log(`${obtenerNombreMes(fechaNacimiento.getMonth())}`);\n\n    // 6º Mostrar FECHA de nacimiento en forma de String\n    console.log(fechaNacimiento.toLocaleDateString());\n\n    // 7º Mostrar HORA de nacimiento en forma de String\n    console.log(fechaNacimiento.toLocaleTimeString());\n\n    // 8º Mostrar Día de la semana y día del mes\n    // Con este formato le podemos especificar más parámetros y como los queremos\n    console.log(`${fechaNacimiento.toLocaleDateString('es-ES', { weekday: 'long' })}, ${fechaNacimiento.getDate()}`);\n\n    // 9º Mostrar Nombre del mes, día del mes y año\n    console.log(`${fechaNacimiento.toLocaleDateString('es-ES', { month: 'long' })} ${fechaNacimiento.getDate()}, ${fechaNacimiento.getFullYear()}`);\n\n    // 10º Mostrar Día de la semana, día del mes, nombre del mes y año abreviados\n    console.log(`${fechaNacimiento.toLocaleDateString('es-ES', { weekday: 'short', month: 'short' })} ${fechaNacimiento.getDate()}, ${fechaNacimiento.getFullYear()}`);"
  },
  {
    "path": "Roadmap/14 - FECHAS/typescript/Sac-Corts.ts",
    "content": "const currentDate: Date = new Date();\nconst birthdate: Date = new Date('2001-10-21T08:30:00');\n\nfunction calculateAge(currentDate: Date, birthdate: Date): number {\n    let age: number = currentDate.getFullYear() - birthdate.getFullYear();\n    const month: number = currentDate.getMonth() - birthdate.getMonth();\n\n    if (month < 0 || (month === 0 && currentDate.getDate() < birthdate.getDate())) {\n        age--;\n    }\n\n    return age;\n}\n\nconst age: number = calculateAge(currentDate, birthdate);\nconsole.log(`${age} years have passed since the date of birth`);\n\n// ** Extra Exercise ** //\nconst dayMonthYear: string = birthdate.toLocaleDateString('es-ES');\n\nconst hourMinuteSecond: string = birthdate.toLocaleTimeString('es-ES');\n\nconst startYear: Date = new Date(birthdate.getFullYear(), 0, 0);\nconst difference: number = birthdate.getTime() - startYear.getTime();\nconst oneDay: number = 1000 * 60 * 60 * 24;\nconst dayOfTheYear: number = Math.floor(difference / oneDay);\n\nconst dayOfTheWeek: string = birthdate.toLocaleDateString('es-ES', { weekday: 'long' });\n\nconst nameMonth: string = birthdate.toLocaleDateString('es-ES', { month: 'long' });\n\nconst longDate: string = birthdate.toLocaleDateString('es-ES', { year: 'numeric', month: 'long', day: 'numeric' });\n\nconst formatISO: string = birthdate.toISOString();\n\nconst formatUTC: string = birthdate.toUTCString();\n\nconst timeUnix: number = birthdate.getTime();\n\nconst abbreviatedDate: string = birthdate.toLocaleDateString('es-ES', { weekday: 'short', month: 'short', day: 'numeric' });\n\nconsole.log('Day, month and year:', dayMonthYear);\nconsole.log('Hour, minute and second:', hourMinuteSecond);\nconsole.log('Day of the year:', dayOfTheYear);\nconsole.log('Day of the week:', dayOfTheWeek);\nconsole.log('Name of the month:', nameMonth);\nconsole.log('Long date:', longDate);\nconsole.log('Format ISO:', formatISO);\nconsole.log('Format UTC:', formatUTC);\nconsole.log('Time in milliseconds since 1970:', timeUnix);\nconsole.log('Abbreviated date:', abbreviatedDate);\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/typescript/david-git-dev.ts",
    "content": "const now = new Date(Date.now()).getFullYear();\nconst birthDate = new Date(\"1999-06-13\").getFullYear();\nlet age = now - birthDate;\nconsole.log(\"han pasado->\", age, \"años\");\n//dificultad extra\nconst birthDateX = new Date(\"1999-06-13\");\nconst fechas = {\n  formato1: `${birthDateX.getDate()}-${birthDateX.getDay()}-${birthDateX.getFullYear()}`,\n  formato2: `${birthDateX.getTime()}->milisegundos han pasado desde tu nacimiento`,\n  formato3: `${birthDateX.getUTCFullYear()}-> welcome to earth boy!!`,\n  formato4: `${birthDateX.toISOString()}->tu fecha en formato iso`,\n  formato5: birthDateX.toLocaleString(),\n  formato6: birthDateX.toLocaleTimeString(),\n  formato7: birthDateX.toString(),\n  formato8: birthDateX.toTimeString(),\n  formato9: birthDateX.toUTCString(),\n  formato10: `${birthDateX.getDay()}/${birthDateX.getMonth()}/${birthDateX.getFullYear()}`\n};\nconsole.log(fechas);\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/typescript/duendeintemporal.ts",
    "content": "/*\n * EJERCICIO #14 { retosparaprogramadortes } FECHAS:\n * Crea dos variables utilizando los objetos fecha (Date) de TypeScript:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n */\n\n// Short for console.log()\nconst log = console.log;\n\n// Conditional check for browser environment\nif (typeof window !== 'undefined') {\n    window.addEventListener('load', () => {\n        const body: HTMLBodyElement | null = document.querySelector('body');\n        const title = document.createElement('h1');\n\n        body?.style.setProperty('background', '#000');\n        body?.style.setProperty('text-align', 'center');\n\n        title.textContent = 'Retosparaprogramadores #14.';\n        title.style.setProperty('font-size', '3.5vmax');\n        title.style.setProperty('color', '#fff');\n        title.style.setProperty('line-height', '100vh');\n\n        body?.appendChild(title);\n\n        setTimeout(() => {\n            alert('Retosparaprogramadores #14. Please open the Browser Developer Tools.');\n        }, 2000);\n        log('Retosparaprogramadores #14');\n    });\n} else {\n    log('This code is designed to run in a browser environment. Skipping window-related code.');\n    log('Retosparaprogramadores #14');\n}\n\n// Get the current date and time\nconst today: Date = new Date();\nlog(today); // Current date and time  output example: 2025-02-25T00:41:23.422Z\nlog(today.toDateString()); // Current date in a readable format  output example: Mon Feb 24 2025\n\n// Define a birthday date (example: August 8, 1983, 08:30:00)\nconst myBirthday: Date = new Date(Date.parse(\"1983-08-08T08:30:00\"));\nlog(myBirthday); // Birthday date and time  1983-08-08T12:30:00.000Z\nlog(myBirthday.toDateString()); // Birthday date in a readable format   8/8/1983\nlog(myBirthday.toLocaleDateString()); // Birthday date in a localized format   8/8/1983\nlog(myBirthday.toLocaleString()); // Birthday date and time in a localized format   8/8/1983, 8:30:00 \n\n/**\n * Calculates the number of years between two dates.\n * @param date1 - The first date.\n * @param date2 - The second date.\n * @returns The number of years between the two dates.\n */\nconst calcYearsBetween = (date1: Date, date2: Date): number => {\n    if (date1 < date2) {\n        [date1, date2] = [date2, date1]; // Swap if date1 is earlier\n    }\n\n    const differenceInMilliseconds: number = date1.getTime() - date2.getTime();\n    const years: number = differenceInMilliseconds / (1000 * 60 * 60 * 24 * 365.25);\n\n    let fullYears: number = Math.floor(years);\n\n    // Check if the anniversary has not yet occurred this year\n    if (\n        date1.getMonth() < date2.getMonth() ||\n        (date1.getMonth() === date2.getMonth() && date1.getDate() < date2.getDate())\n    ) {\n        fullYears--;\n    }\n    return years;\n};\n\nconst yearsBetween: number = calcYearsBetween(today, myBirthday);\nlog(`Years between: ${yearsBetween.toFixed(2)}`); // Output: Years between: 41.55\n\n/**\n * Alternative method to calculate the number of years between two dates.\n * @param date1 - The first date.\n * @param date2 - The second date.\n * @returns The number of years between the two dates.\n */\nconst calcYearsBetween2 = (date1: Date, date2: Date): number => {\n    if (date1 < date2) {\n        [date1, date2] = [date2, date1]; // Swap if date1 is earlier\n    }\n    let years: number = date1.getFullYear() - date2.getFullYear();\n\n    if (\n        date1.getMonth() < date2.getMonth() ||\n        (date1.getMonth() === date2.getMonth() && date1.getDate() < date2.getDate())\n    ) {\n        years--;\n    }\n\n    return years;\n};\n\nlog(calcYearsBetween2(today, myBirthday)); // Output: 41\n\n/**\n * Calculates the difference between two dates in years, months, weeks, days, hours, minutes, and seconds.\n * @param date1 - The first date.\n * @param date2 - The second date.\n * @returns An object containing the difference in years, months, weeks, days, hours, minutes, and seconds.\n */\nconst calcDateDifference = (date1: Date, date2: Date) => {\n    if (date1 < date2) {\n        [date1, date2] = [date2, date1]; // Swap if date1 is earlier\n    }\n\n    const differenceInMilliseconds: number = date1.getTime() - date2.getTime();\n    const totalSeconds: number = Math.floor(differenceInMilliseconds / 1000);\n    const totalMinutes: number = Math.floor(totalSeconds / 60);\n    const totalHours: number = Math.floor(totalMinutes / 60);\n    const totalDays: number = Math.floor(totalHours / 24);\n\n    const years: number = date1.getFullYear() - date2.getFullYear();\n    const months: number = date1.getMonth() - date2.getMonth() + (years * 12);\n    const weeks: number = Math.floor(totalDays / 7);\n    const days: number = totalDays % 7;\n\n    const remainingHours: number = totalHours % 24;\n    const remainingMinutes: number = totalMinutes % 60;\n    const remainingSeconds: number = totalSeconds % 60;\n\n    return {\n        years,\n        months,\n        weeks,\n        days,\n        hours: remainingHours,\n        minutes: remainingMinutes,\n        seconds: remainingSeconds\n    };\n};\n\nconst difference = calcDateDifference(today, myBirthday);\nlog(`Difference: \n${difference.years} years, \n${difference.months} months, \n${difference.weeks} weeks, \n${difference.days} days, \n${difference.hours} hours, \n${difference.minutes} minutes, \n${difference.seconds} seconds`);\n\n/* Output:\nDifference:         \n42 years,\n498 months,\n2168 weeks,\n0 days,\n12 hours,\n11 minutes,\n23 seconds */\n\n/**\n * Formats a birthday date in 10 different ways.\n * @param birthday - The birthday date.\n */\nconst formatBirthday = (birthday: Date): void => {\n    const date: Date = new Date(birthday);\n\n    const dayMonthYear: string = date.toLocaleDateString('en-US', { day: 'numeric', month: 'long', year: 'numeric' });\n    const time: string = date.toLocaleTimeString('es-ES', { hour: 'numeric', minute: 'numeric', second: 'numeric' });\n    const dayOfYear: number = Math.floor((date.getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 1000 / 60 / 60 / 24);\n    const dayOfWeek: string = date.toLocaleDateString('en-US', { weekday: 'long' });\n    const monthName: string = date.toLocaleDateString('en-US', { month: 'long' });\n    const isoFormat: string = date.toISOString();\n    const shortFormat: string = date.toLocaleDateString('en-US');\n    const longFormat: string = date.toLocaleDateString('en-US', { weekday: 'long', day: 'numeric', month: 'long', year: 'numeric' });\n    const time12Hour: string = date.toLocaleString('en-US', { hour: 'numeric', minute: 'numeric', second: 'numeric', hour12: true });\n    const timeWithTimezone: string = date.toLocaleString('es-ES', { timeZoneName: 'short' });\n\n    log(\"1. I was born on:\", dayMonthYear);\n    log(\"2. at:\", time + ' AM');\n    log(\"3. the day:\", dayOfYear + ' of the year ' + date.getFullYear());\n    log(\"4. on:\", dayOfWeek);\n    log(\"5. one special day of:\", monthName);\n    log(\"6. isoFormat:\", isoFormat);\n    log(\"7. shortFormat:\", shortFormat);\n    log(\"8. longFormat:\", longFormat);\n    log(\"9. time12hour:\", time12Hour);\n    log(\"10. timeWithTimezone:\", timeWithTimezone);\n};\n\nformatBirthday(myBirthday);\n\n/* Output:\n1. I was born on: August 8, 1983\n2. at: 8:30:00 AM\n3. the day: 220 of the year 1983\n4. on: Monday\n5. one special day of: August\n6. isoFormat: 1983-08-08T12:30:00.000Z\n7. shortFormat: 8/8/1983\n8. longFormat: Monday, August 8, 1983\n9. time12hour: 8:30:00 AM\n10. timeWithTimezone: 8/8/1983, 8:30:00 GMT-4 */"
  },
  {
    "path": "Roadmap/14 - FECHAS/typescript/eulogioep.ts",
    "content": "// Definimos algunas interfaces útiles\ninterface DateFormats {\n    dayMonthYear: string;\n    hourMinuteSecond: string;\n    dayOfYear: number;\n    dayOfWeek: string;\n    monthName: string;\n    longFormat: string;\n    isoFormat: string;\n    twelveHourFormat: string;\n    unixTimestamp: number;\n    quarterOfYear: number;\n}\n\n// Definimos algunos tipos de utilidad\ntype MonthName = 'Enero' | 'Febrero' | 'Marzo' | 'Abril' | 'Mayo' | 'Junio' | \n                 'Julio' | 'Agosto' | 'Septiembre' | 'Octubre' | 'Noviembre' | 'Diciembre';\ntype DayOfWeek = 'Domingo' | 'Lunes' | 'Martes' | 'Miércoles' | 'Jueves' | 'Viernes' | 'Sábado';\n\n// Creamos algunas constantes con tipos\nconst DAYS_OF_WEEK: DayOfWeek[] = [\n    'Domingo', 'Lunes', 'Martes', 'Miércoles', 'Jueves', 'Viernes', 'Sábado'\n];\n\nconst MONTHS: MonthName[] = [\n    'Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio',\n    'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'\n];\n\nclass DateCalculator {\n    private currentDate: Date;\n    private birthDate: Date;\n\n    constructor(birthDate: Date) {\n        this.currentDate = new Date();\n        this.birthDate = birthDate;\n    }\n\n    calculateYearsBetween(): number {\n        let years = this.currentDate.getFullYear() - this.birthDate.getFullYear();\n        const currentMonth = this.currentDate.getMonth();\n        const birthMonth = this.birthDate.getMonth();\n        \n        // Ajustamos si aún no hemos llegado al mes y día de nacimiento este año\n        if (currentMonth < birthMonth || \n            (currentMonth === birthMonth && \n             this.currentDate.getDate() < this.birthDate.getDate())) {\n            years--;\n        }\n        \n        return years;\n    }\n\n    formatDates(): DateFormats {\n        return {\n            dayMonthYear: this.formatDate(this.birthDate, 'dd/MM/yyyy'),\n            hourMinuteSecond: this.formatTime(this.birthDate),\n            dayOfYear: this.getDayOfYear(this.birthDate),\n            dayOfWeek: DAYS_OF_WEEK[this.birthDate.getDay()],\n            monthName: MONTHS[this.birthDate.getMonth()],\n            longFormat: this.getLongFormat(this.birthDate),\n            isoFormat: this.birthDate.toISOString(),\n            twelveHourFormat: this.get12HourFormat(this.birthDate),\n            unixTimestamp: Math.floor(this.birthDate.getTime() / 1000),\n            quarterOfYear: Math.floor(this.birthDate.getMonth() / 3) + 1\n        };\n    }\n\n    private formatDate(date: Date, format: string): string {\n        const day = String(date.getDate()).padStart(2, '0');\n        const month = String(date.getMonth() + 1).padStart(2, '0');\n        const year = date.getFullYear();\n        \n        return format\n            .replace('dd', day)\n            .replace('MM', month)\n            .replace('yyyy', String(year));\n    }\n\n    private formatTime(date: Date): string {\n        return date.toLocaleTimeString('es-ES', { \n            hour12: false,\n            hour: '2-digit',\n            minute: '2-digit',\n            second: '2-digit'\n        });\n    }\n\n    private getDayOfYear(date: Date): number {\n        const startOfYear = new Date(date.getFullYear(), 0, 0);\n        const diff = date.getTime() - startOfYear.getTime();\n        const oneDay = 1000 * 60 * 60 * 24;\n        return Math.floor(diff / oneDay);\n    }\n\n    private getLongFormat(date: Date): string {\n        const dayOfWeek = DAYS_OF_WEEK[date.getDay()];\n        const dayOfMonth = date.getDate();\n        const month = MONTHS[date.getMonth()];\n        const year = date.getFullYear();\n        \n        return `${dayOfWeek}, ${dayOfMonth} de ${month} de ${year}`;\n    }\n\n    private get12HourFormat(date: Date): string {\n        return date.toLocaleTimeString('es-ES', { hour12: true });\n    }\n}\n\n// Uso del código\nconst birthDate = new Date(1990, 4, 15, 14, 30, 0); // Mes 4 es Mayo (0-11)\nconst calculator = new DateCalculator(birthDate);\n\n// PARTE 1: Calcular años transcurridos\nconst yearsPassedTesting = (): void => {\n    console.log('Fecha actual:', new Date().toLocaleString());\n    console.log('Fecha de nacimiento:', birthDate.toLocaleString());\n    console.log('Años transcurridos:', calculator.calculateYearsBetween());\n};\n\n// PARTE 2: Mostrar diferentes formatos de fecha\nconst showFormattedDates = (): void => {\n    const formats = calculator.formatDates();\n    \n    console.log('\\nDIFERENTES FORMATOS DE FECHA:');\n    console.log('1. Día, mes y año:', formats.dayMonthYear);\n    console.log('2. Hora, minuto y segundo:', formats.hourMinuteSecond);\n    console.log('3. Día del año:', formats.dayOfYear);\n    console.log('4. Día de la semana:', formats.dayOfWeek);\n    console.log('5. Nombre del mes:', formats.monthName);\n    console.log('6. Formato largo:', formats.longFormat);\n    console.log('7. Formato ISO:', formats.isoFormat);\n    console.log('8. Formato 12 horas:', formats.twelveHourFormat);\n    console.log('9. Unix Timestamp:', formats.unixTimestamp);\n    console.log('10. Trimestre del año:', formats.quarterOfYear);\n};\n\n// Ejecutamos las funciones\nyearsPassedTesting();\nshowFormattedDates();"
  },
  {
    "path": "Roadmap/14 - FECHAS/typescript/hozlucas28.ts",
    "content": "/*\n    Dates...\n*/\n\nconsole.log('Dates...')\n\nconst actualDate: Date = new Date()\nconst bornDate: Date = new Date(2002, 1, 20)\n\nconsole.log(`\\nToday is: ${actualDate}`)\nconsole.log(`\\nLucas Hoz born date: ${bornDate}`)\n\nconst millisecondsPerDay: number = 86_400_000\nconst millisecondsBetweenDates = actualDate.getTime() - bornDate.getTime()\nconst daysBetweenDates = Math.round(\n\tmillisecondsBetweenDates / millisecondsPerDay\n)\n\nconsole.log(\n\t`\\nNumber of days between today and Lucas Hoz born date: ${daysBetweenDates} days`\n)\n\nconsole.log(\n\t'\\n# ---------------------------------------------------------------------------------- #\\n'\n)\n\n/*\n    Additional challenge...\n*/\n\nconsole.log('Additional challenge...')\n\nfunction dayOfYear(date: Date): number {\n\tconst millisecondsPerDay: number = 86_400_000\n\n\tconst baseDate = new Date(date.getFullYear(), 0, 0)\n\tconst dayOfTheYear = Math.floor(\n\t\t(date.getTime() - baseDate.getTime()) / millisecondsPerDay\n\t)\n\n\treturn dayOfTheYear\n}\n\nconst bornDateObj = {\n\tday: bornDate.getDate(),\n\tmonth: bornDate.getMonth() + 1,\n\tyear: bornDate.getFullYear(),\n\thours: bornDate.getHours(),\n\tminutes: bornDate.getMinutes(),\n\tseconds: bornDate.getSeconds(),\n\tdayOfTheYear: dayOfYear(bornDate),\n\tdayOfTheWeek: bornDate.getDay(),\n\tmonthName: bornDate.toLocaleString('en', { month: 'long' }),\n}\n\nconsole.log(\n\t`\\nDay, month, and year: ${bornDateObj.day}, ${bornDateObj.month}, and ${bornDateObj.year}`\n)\n\nconsole.log(\n\t`\\nHours, minutes, and seconds: ${bornDateObj.hours} hours, ${bornDateObj.minutes} minutes, and ${bornDateObj.seconds} seconds`\n)\n\nconsole.log(`\\nDay of the year: ${bornDateObj.dayOfTheYear}`)\n\nconsole.log(`\\nName of the month: ${bornDateObj.monthName}`)\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/typescript/nlarrea.ts",
    "content": "/*\n * EJERCICIO:\n * Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n * - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n * - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n * Calcula cuántos años han transcurrido entre ambas fechas.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n */\n\n\nconst currentDate: Date = new Date()\nconst birthdayDate: Date = new Date('1998-06-29 09:25:00')\n\nconst getYearsDifference = (dateOne: Date, dateTwo: Date): number => {\n    if (dateOne > dateTwo) {\n        return dateOne.getFullYear() - dateTwo.getFullYear()\n    }\n\n    return dateTwo.getFullYear() - dateOne.getFullYear()\n}\n\nconsole.log(getYearsDifference(currentDate, birthdayDate))\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n * 10 maneras diferentes. Por ejemplo:\n * - Día, mes y año.\n * - Hora, minuto y segundo.\n * - Día de año.\n * - Día de la semana.\n * - Nombre del mes.\n * (lo que se te ocurra...)\n */\n\nconst weekDays: Object = {\n    0: 'Sunday',\n    1: 'Monday',\n    2: 'Tuesday',\n    3: 'Wednesday',\n    4: 'Thursday',\n    5: 'Friday',\n    6: 'Saturday'\n}\n\nconst months: Object = {\n    0: 'January',\n    1: 'February',\n    2: 'March',\n    3: 'April',\n    4: 'May',\n    5: 'June',\n    6: 'July',\n    7: 'August',\n    8: 'September',\n    9: 'October',\n    10: 'November',\n    11: 'December'\n}\n\nconsole.log(`1. ${birthdayDate.toDateString()}`)  // 1. Mon Jun 29 1998\nconsole.log(`2. ${birthdayDate.toLocaleDateString()}`)  // 2. 29/6/1998\nconsole.log(`3. ${birthdayDate.toLocaleString()}`)  // 3. 29/6/1998, 9:25:00\nconsole.log(`4. ${birthdayDate.getHours()}:${birthdayDate.getMinutes()}:${birthdayDate.getSeconds()}`)  // 4. 9:25:0\nconsole.log(`5. ${birthdayDate.toLocaleTimeString()}`)  // 5. 9:25:00\nconsole.log(`6. ${birthdayDate.getDay()}`)  // 6. 1\nconsole.log(`7. ${weekDays[birthdayDate.getDay()]}`)  // 7. Monday\nconsole.log(`8. ${birthdayDate.getMonth() + 1}`)  // 8. 6\nconsole.log(`9. ${months[birthdayDate.getMonth()]}`)  // 9. June\nconsole.log(`10. ${birthdayDate.toJSON()}`)  // 10. 1998-06-29T07:25:00.000Z"
  },
  {
    "path": "Roadmap/14 - FECHAS/typescript/roswer13.ts",
    "content": "// EJERCICIO:\n// Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n// - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n// - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n// Calcula cuántos años han transcurrido entre ambas fechas.\n\nfunction getDates(): [Date, Date] {\n    return [new Date(), new Date(1993, 1, 13, 6, 36, 34)];\n}\n\nfunction calcuatesYearsDifference(now: Date, birth: Date): number {\n    var nowYear = now.getFullYear();\n    var birthYear = birth.getFullYear();\n\n    if (nowYear >= birthYear) {\n        return nowYear - birthYear;\n    }\n\n    return birthYear - nowYear;\n}\n\nconst [now, birth] = getDates();\nconsole.log(\"Tiempo transcurrido desde el nacimiento: \", calcuatesYearsDifference(now, birth), \" años.\");\n\n\n// DIFICULTAD EXTRA (opcional):\n// Utilizando la fecha de tu cumpleaños, formatéala y muestra su resultado de\n// 10 maneras diferentes. Por ejemplo:\n// - Día, mes y año.\n// - Hora, minuto y segundo.\n// - Día de año.\n// - Día de la semana.\n// - Nombre del mes.\n\nfunction dayIntToStringFormat(day: number): string {\n    switch (day) {\n        case 0: return \"Sunday\";\n        case 1: return \"Monday\";\n        case 2: return \"Tuesday\";\n        case 3: return \"Wednesday\";\n        case 4: return \"Thursday\";\n        case 5: return \"Friday\";\n        case 6: return \"Saturday\";\n        default: return \"Invalid day\";\n    }\n}\n\nfunction formatDates(date: Date) {\n    return {\n        day: date.getDate(),\n        month: date.getMonth() + 1,\n        year: date.getFullYear(),\n        hours: date.getHours(),\n        minutes: date.getMinutes(),\n        seconds: date.getSeconds(),\n        dayOfYear: Math.floor((date.getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86_400_000),\n        dayOfWeek: dayIntToStringFormat(date.getDay()),\n        monthName: date.toLocaleString('en', { month: 'long' })\n    };\n}\n\nconst formattedDates = formatDates(birth);\nconsole.log(`Dia, mes y año: ${formattedDates.day}/${formattedDates.month}/${formattedDates.year}`);\nconsole.log(`Hora, minuto y segundo: ${formattedDates.hours}:${formattedDates.minutes}:${formattedDates.seconds}`);\nconsole.log(`Dia del año: ${formattedDates.dayOfYear}`);\nconsole.log(`Dia de la semana: ${formattedDates.dayOfWeek}`);\nconsole.log(`Nombre del mes: ${formattedDates.monthName}`);\n\n// Make testings for the functions.\nfunction validateTets(bool: boolean, functionName?: string) {\n    console.log(bool ? `✅ Test passed ${functionName}` : `❌ Test failed ${functionName}`);\n}\nfunction testGetDates() {\n    // Arrange\n    const [now, birth] = getDates();\n    // Act\n    // Assert\n    validateTets(now instanceof Date, \"testGetDates\");\n    validateTets(birth instanceof Date, \"testGetDates\");\n}\n\nfunction testCalcuatesYearsDifference() {\n    // Arrange\n    const now = new Date(2021, 1, 13, 6, 36, 34);\n    const birth = new Date(1993, 1, 13, 6, 36, 34);\n    // Act\n    const result = calcuatesYearsDifference(now, birth);\n    // Assert\n    validateTets(result === 28, \"testCalcuatesYearsDifference\");\n}\n\nfunction testCalculateYearsDifferenceWhenNowIsBeforeBirth() {\n    // Arrange\n    const now = new Date(1993, 1, 13, 6, 36, 34);\n    const birth = new Date(2021, 1, 13, 6, 36, 34);\n    // Act\n    const result = calcuatesYearsDifference(now, birth);\n    // Assert\n    validateTets(result === 28, \"testCalculateYearsDifferenceWhenNowIsBeforeBirth\");\n}\n\nfunction testCalculateDayIntToStringFormat() {\n    // Arrange\n    // Act\n    const result = dayIntToStringFormat(0);\n    // Assert\n    validateTets(result === \"Sunday\", \"testCalculateDayIntToStringFormat\");\n}\n\nfunction testFormatDates() {\n    // Arrange\n    const date = new Date(1993, 1, 13, 6, 36, 34);\n    // Act\n    const result = formatDates(date);\n    // Assert\n    validateTets(result.day === 13, \"testFormatDates\");\n    validateTets(result.month === 2, \"testFormatDates\");\n    validateTets(result.year === 1993, \"testFormatDates\");\n    validateTets(result.hours === 6, \"testFormatDates\");\n    validateTets(result.minutes === 36, \"testFormatDates\");\n    validateTets(result.seconds === 34, \"testFormatDates\");\n    validateTets(result.dayOfYear === 44, \"testFormatDates\");\n    validateTets(result.dayOfWeek === \"Saturday\", \"testFormatDates\");\n    validateTets(result.monthName === \"February\", \"testFormatDates\");\n}\n\nfunction runTests() {\n    console.log(\"Running tests...\");\n    testGetDates();\n    testCalculateYearsDifferenceWhenNowIsBeforeBirth();\n    testCalcuatesYearsDifference();\n    testCalculateDayIntToStringFormat();\n    testFormatDates();\n    console.log(\"Tests finished.\");\n}\n\nrunTests();\n\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/typescript/victor-Casta.ts",
    "content": "const actual: Date = new Date()\nconst birthdayDate: Date = new Date('2002-12-17')\n\nlet years: number = actual.getFullYear() - birthdayDate.getFullYear()\nconsole.log(years)\n\nconst date: Date = new Date()\nconsole.log(`${date.getDate()}/${date.getMonth() + 1}/${date.getFullYear()}`)\nconsole.log(`${date.getMonth() + 1}/${date.getDate()}/${date.getFullYear()}`)\nconsole.log(`${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()}`)\nconsole.log(`${date.getHours()}/${date.getMinutes()}/${date.getSeconds()}`)\nconsole.log(`${date.getSeconds()}/${date.getMinutes()}/${date.getHours()}`)\nconsole.log(`${date.getMinutes()}/${date.getSeconds()}/${date.getHours()}`)\nconsole.log(`${date.getMinutes()}`)\nconsole.log(`${date.getHours()}`)\nconsole.log(`${date.getSeconds()}`)\nconsole.log(`${date.getMonth()}`)\nconsole.log(`${date.getFullYear()}`)\nconsole.log(`${date.getDate()}`)"
  },
  {
    "path": "Roadmap/14 - FECHAS/typescript/victoriaparraf.ts",
    "content": "//Creacion de variables de tipo fecha\n//fecha actual\nconst fechaActual = new Date();\n//fecha nacimiento\nconst fechaNacimiento = new Date(2001,3,8,3,0,0);\n\n// Cálculo de la diferencia en milisegundos\nconst diferenciaMilisegundos = fechaActual.getTime() - fechaNacimiento.getTime();\n\n// Cálculo de la diferencia en años\nconst milisegundosEnUnAnio = 1000 * 60 * 60 * 24 * 365.25; // Incluye el ajuste de años bisiestos\nconst diferenciaAnios = diferenciaMilisegundos / milisegundosEnUnAnio;\n\n// Imprimir resultados\nconsole.log(`Fecha actual: ${fechaActual}`);\nconsole.log(`Fecha de nacimiento: ${fechaNacimiento}`);\nconsole.log(`Han transcurrido aproximadamente ${Math.floor(diferenciaAnios)} años entre ambas fechas.`);\n\n//Otra opcion\n\n// Fecha actual\nconst fechaActual2 = new Date();\n\n// Fecha de nacimiento\nconst fechaNacimiento2 = new Date(2001, 3, 8, 3, 0, 0);\n\n// Obtener los años de las fechas\nconst anioActual = fechaActual2.getFullYear();\nconst anioNacimiento = fechaNacimiento2.getFullYear();\n\n// Calcular la diferencia en años\nlet diferenciaAnios2 = anioActual - anioNacimiento;\n\n// Ajustar si el cumpleaños de este año aún no ha ocurrido\nconst mesActual = fechaActual2.getMonth();\nconst diaActual = fechaActual2.getDate();\nconst mesNacimiento = fechaNacimiento2.getMonth();\nconst diaNacimiento = fechaNacimiento2.getDate();\n\nif (mesActual < mesNacimiento || (mesActual === mesNacimiento && diaActual < diaNacimiento)) {\n    diferenciaAnios2--;\n}\n\n// Imprimir resultados\nconsole.log(`Fecha actual: ${fechaActual2}`);\nconsole.log(`Fecha de nacimiento: ${fechaNacimiento2}`);\nconsole.log(`Han transcurrido aproximadamente ${diferenciaAnios2} años entre ambas fechas.`);\n\n\n/****************************************/\n//EXTRAAAA//\nimport { format } from 'date-fns';\n\n// Fecha de nacimiento\nconst fechaNac = new Date(2001, 3, 8, 3, 0, 0); // 15 de mayo de 1999 a las 10:30:00\n\n// 1. Día, mes y año\nconst formato1 = format(fechaNac, 'dd/MM/yyyy');\n// 2. Hora, minuto y segundo\nconst formato2 = format(fechaNac, 'HH:mm:ss');\n// 3. Día del año\nconst formato3 = format(fechaNac, 'DDD');\n// 4. Día de la semana\nconst formato4 = format(fechaNac, 'EEEE');\n// 5. Nombre del mes\nconst formato5 = format(fechaNac, 'MMMM');\n// 6. Día del mes\nconst formato6 = format(fechaNac, 'do');\n// 7. Año completo y corto\nconst formato7 = format(fechaNac, 'yyyy / yy');\n// 8. Mes y año\nconst formato8 = format(fechaNac, 'MMMM yyyy');\n// 9. Fecha y hora ISO 8601\nconst formato9 = fechaNac.toISOString();\n// 10. Fecha y hora locales\nconst formato10 = fechaNac.toLocaleString();\n\nconsole.log(`1. Día, mes y año: ${formato1}`);\nconsole.log(`2. Hora, minuto y segundo: ${formato2}`);\nconsole.log(`3. Día del año: ${formato3}`);\nconsole.log(`4. Día de la semana: ${formato4}`);\nconsole.log(`5. Nombre del mes: ${formato5}`);\nconsole.log(`6. Día del mes: ${formato6}`);\nconsole.log(`7. Año completo y corto: ${formato7}`);\nconsole.log(`8. Mes y año: ${formato8}`);\nconsole.log(`9. Fecha y hora ISO 8601: ${formato9}`);\nconsole.log(`10. Fecha y hora locales: ${formato10}`);\n"
  },
  {
    "path": "Roadmap/14 - FECHAS/vb.net/kenysdev.vb",
    "content": "' ╔══════════════════════════════════════╗\n' ║ Autor:  Kenys Alvarado               ║\n' ║ GitHub: https://github.com/Kenysdev  ║\n' ║ 2024 -  VB.NET                       ║\n' ╚══════════════════════════════════════╝\n'-----------------------------------------------\n'* FECHAS\n'-----------------------------------------------\nImports System.Globalization\n\nModule Program\n    Sub Main(args As String())\n        '* EJERCICIO 1\n        '* Crea dos variables utilizando los objetos fecha (date, o semejante) de tu lenguaje:\n        '* - Una primera que represente la fecha (día, mes, año, hora, minuto, segundo) actual.\n        '* - Una segunda que represente tu fecha de nacimiento (te puedes inventar la hora).\n        '* Calcula cuántos años han transcurrido entre ambas fechas\n\n        Dim currentDateTime As DateTime = DateTime.Now\n        Dim birthDate As DateTime = New DateTime(1995, 10, 20, 2, 30, 0)\n\n        Dim difference As TimeSpan = currentDateTime - birthDate\n        Dim years As Integer = difference.Days \\ 365\n        Dim months As Integer = (difference.Days Mod 365) \\ 30\n        Dim days As Integer = (difference.Days Mod 365) Mod 30\n\n        Console.WriteLine(\n            years & \" años, \" &\n            months & \" meses y \" &\n            days & \" días\"\n        )\n\n        '* EJERCICIO 2\n        '* Utilizando la fecha de tu cumpleaños, formatéala y muestra su \n        '  resultado de 10 maneras diferentes.\n\n        Console.WriteLine(\"\n        Formatos de fecha:\n        -----------------------\n        1. Predeterminado -> \" & birthDate.ToString() & \"\n        2. Fecha larga    -> \" & birthDate.ToString(\"D\") & \"\n        3. dd-MM-yyyy     -> \" & birthDate.ToString(\"dd-MM-yyyy\") & \"\n        4. Nombre del mes -> \" & birthDate.ToString(\"MMMM\") & \"\n        5. Mes abreviado  -> \" & birthDate.ToString(\"MMM\") & \"\n        6. Nombre del día -> \" & birthDate.ToString(\"dddd\") & \"\n        7. Día abreviado  -> \" & birthDate.ToString(\"ddd\") & \"\n        8. Hora(24 horas) -> \" & birthDate.ToString(\"HH:mm:ss\") & \"\n        9. Hora(12 horas) -> \" & birthDate.ToString(\n            \"hh:mm tt\", CultureInfo.InvariantCulture) & \"\n        0. Personalizado  -> \" & birthDate.ToString(\n            \"Born on dddd, dd'th of' MMMM yyyy 'at' hh:mm:ss tt\"))\n\n    End Sub\nEnd Module\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/bash/h4ckxel.sh",
    "content": "#!/bin/bash\n\n# Función genérica que ejecuta tareas asincrónicamente con nombre y duración\nfunction run_task() {\n    local name=\"$1\"\n    local duration=\"$2\"\n    \n    if [[ -z \"$name\" || -z \"$duration\" ]]; then\n        echo -e \"[!] Error: Debes proporcionar un nombre y una duración para la tarea.\\n\"\n        return 1\n    fi\n\n    echo -e \"[+] La tarea '$name' comienza a ejecutarse y durará ${duration} segundos...\\n\"\n    sleep \"$duration\"\n    echo -e \"[!] La tarea '$name' ha finalizado.\\n\"\n}\n\n# Función principal para ejecutar las tareas en el orden especificado\nfunction main() {\n    echo -e \"[+] Ejecutando las tareas en paralelo...\\n\"\n\n    # Ejecutar tareas C, B y A en paralelo\n    run_task \"Tarea C\" 3 &\n    run_task \"Tarea B\" 2 &\n    run_task \"Tarea A\" 1 &\n\n    # Esperar a que todas las tareas en paralelo finalicen\n    wait\n\n    echo -e \"[+] Todas las tareas C, B y A han terminado. Iniciando la tarea D...\\n\"\n    \n    # Ejecutar la tarea D después de que las demás terminen\n    run_task \"Tarea D\" 1\n}\n\n# Ejecutar la función principal\nmain\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/bash/rantamhack.sh",
    "content": "#!/bin/bash\n\n# * EJERCICIO:\n# * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n# * asincrona una funcion que tardara en finalizar un numero concreto de\n# * segundos parametrizables. Tambien debes poder asignarle un nombre.\n# * La funcion imprime su nombre, cuando empieza, el tiempo que durara\n# * su ejecucion y cuando finaliza.\n\nfunction task_D(){\n    echo -e \"[+] La tarea $1 comienza a ejecutarse....\\n\"\n    sleep 5\n    echo -e \"[!] La tarea $1 ha finalizado\\n\"\n}    \ntask_D \"Tarea D\"\n\n\n\n\n# * DIFICULTAD EXTRA (opcional):\n# * Utilizando el concepto de asincronia y la funcion anterior, crea\n# * el siguiente programa que ejecuta en este orden:\n# * - Una funcion C que dura 3 segundos.\n# * - Una funcion B que dura 2 segundos.\n# * - Una funcion A que dura 1 segundo.\n# * - Una funcion D que dura 1 segundo.\n# * - Las funciones C, B y A se ejecutan en paralelo.\n# * - La funcion D comienza su ejecucion cuando las 3 anteriores han\n# *   finalizado.\n\n\nfunction task_C(){\n    echo -e \"[+] La tarea $1 comienza a ejecutarse....\\n\"\n    sleep 3\n    echo -e \"[!] La tarea $1 ha finalizado\\n\"\n}\n\nfunction task_B(){\n    echo -e \"[+] La tarea $1 comienza a ejecutarse....\\n\"\n    sleep 2\n    echo -e \"[!] La tarea $1 ha finalizado\\n\"\n}\n\nfunction task_A(){\n    echo -e \"[+] La tarea $1 comienza a ejecutarse....\\n\"\n    sleep 1\n    echo -e \"[!] La tarea $1 ha finalizado\\n\"\n}\n\nfunction main(){\n   \n   echo -e \"[+] La 'Tarea D' Espera a que las demas terminen de ejecutarse....\\n\"\n   \n   task_C \"Tarea C\" &\n   task_B \"Tarea B\" &\n   task_A \"Tarea A\" &\n   wait\n   task_D \"Tarea D\" \n\n}  \n\nmain\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/c/N0HagoNada.c",
    "content": "#include <stdio.h>\n#include <stdlib.h>\n#include <unistd.h>\n#include <pthread.h>\n\n// compilar con gcc -pthread -o Asincronia .\\N0HagoNada.c\ntypedef struct\n{\n    const char *nombre;\n    int duracion;\n} FuncionInfo;\n\nvoid *funcionAsincrona(void *arg)\n{\n    FuncionInfo *info = (FuncionInfo *)arg;\n    printf(\"%s comenzo\\n\", info->nombre);\n    printf(\"%s tardara %d segundos en finalizar\\n\", info->nombre, info->duracion);\n    sleep(info->duracion);\n    printf(\"%s finalizo\\n\", info->nombre);\n    free(info);\n    return NULL;\n}\n\nint main()\n{\n    pthread_t hilos[3];\n    FuncionInfo *info;\n\n    // Ejecutar las funciones C, B y A en paralelo\n    info = malloc(sizeof(FuncionInfo));\n    info->nombre = \"Funcion C\";\n    info->duracion = 3;\n    pthread_create(&hilos[0], NULL, funcionAsincrona, info);\n\n    info = malloc(sizeof(FuncionInfo));\n    info->nombre = \"Funcion B\";\n    info->duracion = 2;\n    pthread_create(&hilos[1], NULL, funcionAsincrona, info);\n\n    info = malloc(sizeof(FuncionInfo));\n    info->nombre = \"Funcion A\";\n    info->duracion = 1;\n    pthread_create(&hilos[2], NULL, funcionAsincrona, info);\n\n    // Esperar a que las funciones C, B y A finalicen\n    for (int i = 0; i < 3; i++)\n    {\n        pthread_join(hilos[i], NULL);\n    }\n\n    // Ejecutar la función D\n    info = malloc(sizeof(FuncionInfo));\n    info->nombre = \"Funcion D\";\n    info->duracion = 1;\n    funcionAsincrona(info);\n\n    printf(\"Programa finalizado\\n\");\n\n    return 0;\n}"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/c#/Andreavzqz.cs",
    "content": "using System; \nusing System.Threading.Tasks;\n\nnamespace ProgramaAsincrono\n{\n    class Program\n    {\n        static async task Main(string[] args)\n        {\n\n            //Dificultad extra\n            Task taskC = EjecutarFuncionAsync(\"Funcion C\", 3);\n            Task taskB = EjecutarFuncionAsync(\"Funcion B\", 2);\n            Task taskA = EjecutarFuncionAsync(\"Funcion A\", 1);\n\n            //Esperar a que las funciones C, B Y A finalicen\n            await task.WhenAll(taskC, taskB, taskA);\n\n            //Ejecutar funcion D despues de las anteriores hayan terminado\n            await EjecutarFuncionAsync(\"Funcion D\", 1);\n        }\n\n        static async Task EjecutarFuncionAsync(string nombre, int segundos)\n        {\n            Console.WriteLine($\"{nombre} empieza. Duracion: {segundos} segundos.\");\n            Console.WriteLine($\"{nombre} empieza a las {DateTime.Now:T}.\");\n\n            await Task.Delay(segundos * 1000);\n\n            Console.WriteLine($\"{nombre} finaliza a las {DateTime.T}.\");\n        }\n    }\n/*\n\n- Explicación\n\nMétodo Main:\nEste método es el punto de entrada del programa y se declara como async para permitir el uso de await.\nSe crean tareas (Task) para las funciones C, B y A que se ejecutan en paralelo. Se utiliza Task.WhenAll para esperar que todas estas tareas finalicen antes de continuar con la ejecución.\nDespués de que las funciones C, B y A finalicen, se ejecuta la función D.\n\nMétodo EjecutarFuncionAsync:\nEste método representa una función que se ejecutará de manera asíncrona. Toma un nombre y una duración en segundos como parámetros.\nImprime el nombre de la función, la hora de inicio y la duración.\nUtiliza Task.Delay para simular una tarea que toma tiempo en completarse. Task.Delay es una manera de esperar de forma asíncrona sin bloquear el hilo.\nUna vez completado el tiempo de espera, se imprime la hora de finalización de la función.\n\n*/\n\n}\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/c#/hequebo.cs",
    "content": "class Program\n{\n    static async Task Main(string[] args)\n    {\n        await RunTask(\"Task 1\", 2);\n\n        // Ejercicio extra\n        Task taskC = RunTask(\"Task C\", 3);\n        Task taskB = RunTask(\"Task B\", 2);\n        Task taskA = RunTask(\"Task A\", 1);\n        \n        await Task.WhenAll(taskC, taskB, taskA);\n        await RunTask(\"Task D\", 1);\n    }\n    \n    static async Task RunTask(string name, int seconds)\n    {\n        Console.WriteLine($\"Se inicia ejecución de función {name} a las {DateTime.Now.TimeOfDay}\");\n        await Task.Delay(seconds * 1000);\n        Console.WriteLine($\"Finaliza la ejecución de {name} a las {DateTime.Now.TimeOfDay}\");\n    }\n}"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/c#/isaacus98.cs",
    "content": "﻿/*\n * EJERCICIO:\n * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n * asíncrona una función que tardará en finalizar un número concreto de\n * segundos parametrizables. También debes poder asignarle un nombre.\n * La función imprime su nombre, cuándo empieza, el tiempo que durará\n * su ejecución y cuando finaliza.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han finalizado.\n */\n\nnamespace Roadmap\n{\n    public class Reto15\n    {\n        static async Task Main(string[] args)\n        {\n            await Funcion(\"Isaac\", 5000);\n\n            // Reto extra\n            await Task.WhenAll(Funcion(\"A\", 3000), Funcion(\"B\", 2000), Funcion(\"A\", 1000));\n            await Funcion(\"D\", 1000);\n        }\n\n        static async Task Funcion(string nombre, int segundos)\n        {\n            Console.WriteLine($\"nombre: {nombre}, tiempo de duración: {segundos}\");\n            await Task.Delay(segundos);\n            Console.WriteLine(\"Finalización de la funcion\");\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/c#/jamerrq.cs",
    "content": "/*\n * EJERCICIO:\n * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n * asíncrona una función que tardará en finalizar un número concreto de\n * segundos parametrizables. También debes poder asignarle un nombre.\n * La función imprime su nombre, cuándo empieza, el tiempo que durará\n * su ejecución y cuando finaliza.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han\n *   finalizado.\n */\n\nusing System;\nusing System.Threading;\n\nnamespace Roadmap15\n{\n    class Async\n    {\n        static void Main(string[] args)\n        {\n            Thread c = new(() => Function(\"C\", 3));\n            Thread b = new(() => Function(\"B\", 2));\n            Thread a = new(() => Function(\"A\", 1));\n            Thread d = new(() => Function(\"D\", 1));\n\n            c.Start();\n            b.Start();\n            a.Start();\n\n            c.Join();\n            b.Join();\n            a.Join();\n\n            d.Start();\n            d.Join();\n        }\n\n        static void Function(string name, int seconds)\n        {\n            Console.WriteLine($\"{name} starts at {DateTime.Now}\");\n            Thread.Sleep(seconds * 1000);\n            Console.WriteLine($\"{name} ends at {DateTime.Now}\");\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/c#/kenysdev.cs",
    "content": "/*\n╔═══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado                ║\n║ GitHub: https://github.com/Kenysdev   ║\n║ 2024 -  C#                            ║\n╚═══════════════════════════════════════╝\n-----------------------------------------------\n* ASINCRONÍA\n-----------------------------------------------\n*/\n\n#pragma warning disable CA1050\nclass Program {\n    /*\n    * EJERCICIO #1:\n    * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n    * asíncrona una función que tardará en finalizar un número concreto de\n    * segundos parametrizables. También debes poder asignarle un nombre.\n    * La función imprime su nombre, cuándo empieza, el tiempo que durará\n    * su ejecución y cuando finaliza.\n    */\n    static async Task Process(string name, int time)\n    {\n        Console.WriteLine($\"- Iniciar función: {name} -> Duración: {time}\");\n        await Task.Delay(time * 1000);\n        Console.WriteLine($\"* Función {name} ha terminado.\");\n    }\n\n    static async Task Test()\n    {\n        await Task.WhenAll(\n            Process(\"Test 2\", 4),\n            Process(\"Test 1\", 2)\n        );\n    }\n\n    /*\n    * EJERCICIO #2:\n    * Utilizando el concepto de asincronía y la función anterior, crea\n    * el siguiente programa que ejecuta en este orden:\n    * - Una función C que dura 3 segundos.\n    * - Una función B que dura 2 segundos.\n    * - Una función A que dura 1 segundo.\n    * - Una función D que dura 1 segundo.\n    * - Las funciones C, B y A se ejecutan en paralelo.\n    * - La función D comienza su ejecución cuando las 3 anteriores han\n    *   finalizado.\n    */\n\n    static async Task InParallel()\n    {\n        await Task.WhenAll(\n            Process(\"C\", 3),\n            Process(\"B\", 2),\n            Process(\"A\", 1)\n        );\n    }\n\n    static async Task Main()\n    {\n        await Test();\n        await InParallel();\n        await Process(\"D\", 1);\n    }\n}\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/c++/hectorio23.cpp",
    "content": "// Author: Héctor Adan\n// GitHub: https://github.com/hectorio23\n// EJECUTANDO TAREAS ASINCRONAS AL ESTILO PYTHON\n#include <iostream>\n#include <string>\n#include <thread>\n#include <chrono>\n\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n * asíncrona una función que tardará en finalizar un número concreto de\n * segundos parametrizables. También debes poder asignarle un nombre.\n * La función imprime su nombre, cuándo empieza, el tiempo que durará\n * su ejecución y cuando finaliza.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han\n *   finalizado.\n */\n\n// Funcion que imprime el tiempo en un formato dado\nstd::string time(const char* format) {\n    std::time_t t = std::time(nullptr);\n    std::tm* now = std::localtime(&t);\n    char buffer[128];\n\n    std::strftime(buffer, std::size(buffer), format ,now);\n    return  buffer;\n}\n\nvoid foo(std::string nameTask, int duration) {\n    std::this_thread::sleep_for(std::chrono::milliseconds(duration * 1000));\n    std::cout << \"Ending [ \" << nameTask << \" ] at \" << time(\"%X\") << \"\\n\";\n};\n\n// La siguiente clase permite \"programar\" tareas para su porterior ejecución.\n// La clase quedaría inutilizada sin en lugar de ejecutar el codigo descomentado de la funcion\n// main, se ejcurara el codigo comentado al final de esta misma.\nclass Task {\n    private:\n    std::string name;\n    int duration = 0.0;\n\n    public:\n    Task() {};\n    Task(std::string name): name(name) {};\n    Task(std::string name, int duration): name(name), duration(duration) {};\n\n    void run () { foo(name, this->duration); }\n\n    std::string getName() { \n        if (name.length() != 0) return name;\n        \n        return \"None\\n\";\n    }\n};\n\n// Funcion necesaria para la ejecucion de las tareas \"programadas\", la clase Task\n// hace uso de esta en el metodo run().\n// esta funcion es inservible en caso de que se use el metodo 2 comentado al final de la funcion main \nvoid exec(Task t){\n    t.run();\n}\n\nint main() {\n    /*********************************************************************************************\n    ************************************** ASINCRONIA TIPO \"PYTHON\" *******************************\n    **********************************************************************************************/\n\n    // Se programan las tareas para su ejecucion\n    Task t1 {\"custom\", 2};\n\n    Task C {\"C\", 3};\n    Task B {\"B\", 2};\n    Task A {\"A\", 1};\n\n    Task D {\"D\", 1};\n\n    std::cout << \"************** EJERCICO **********\\n\\n\";\n    std::cout << \"La funcion *custom* tardará 2 segundos al ejecutarse\\n\";\n    std::cout << \"Starting [ \" << t1.getName() << \" ] at \" << time(\"%X\") << \"\\n\";\n    t1.run();\n\n    std::cout << \"\\n************** EJERCICO EXTRA **********\\n\\n\";\n\n    // se crear los hilos para la ejecucion paralela de las tareas C,B y A.\n    std::thread c_task (&exec, C);\n    std::thread b_task (&exec, B);\n    std::thread a_task (&exec, A);\n    \n    std::cout << \"Starting tasks [  C, B, A ] at \" << time(\"%X\") << \"\\n\";\n    // se ejecutan las tareas de manera concurrente\n    c_task.join();\n    b_task.join();\n    a_task.join();\n\n    std::cout << \"\\nStarting task [ D ] at \" << time(\"%X\") << \"\\n\";\n    // se ejcuta la ultima tarea \"D\"\n    D.run();\n\n    /*********************************************************************************************\n    ******************************** El siguiente código también es valido ***********************\n    **********************************************************************************************/\n\n    // std::cout << \"Starting task [ *custom* ] at \" << time(\"%X\") << \"\\n\";\n    // foo(\"custom\", 1);\n\n    // std::cout << \"\\n************** EJERCICO EXTRA **********\\n\\n\";\n    // std::cout << \"Starting tasks [  C, B, A ] at \" << time(\"%X\") << \"\\n\";\n    // std::thread C(foo, \"Task C\", 3);\n    // std::thread B(foo, \"Task B\", 2);\n    // std::thread A(foo, \"Task A\", 1);\n\n    // C.join();\n    // B.join();\n    // A.join();\n\n    // std::cout << \"\\nStarting task [ D ] at \" << time(\"%X\") << \"\\n\";\n    // foo(\"Task D\", 1);\n    return EXIT_SUCCESS;\n}\n\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/c++/yeisonagm.cpp",
    "content": "/* EJERCICIO #15: ASINCRONÍA\n * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n * asíncrona una función que tardará en finalizar un número concreto de\n * segundos parametrizables. También debes poder asignarle un nombre.\n * La función imprime su nombre, cuándo empieza, el tiempo que durará\n * su ejecución y cuando finaliza.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han finalizado.\n */\n#include <iostream>\n#include <thread>\n#include <chrono>\n#include <future>\n\nusing namespace std;\n\n// Obtener la hora actual\nstring getCurrentTime() {\n    // Hora actual\n    auto now = chrono::system_clock::now();\n\n    // Convertir la hora\n    time_t now_time = chrono::system_clock::to_time_t(now);\n\n    // Formatear la hora\n    char now_str[80];\n    strftime(now_str, sizeof(now_str), \"%H:%M:%S\", localtime(&now_time));\n\n    return now_str;\n}\n\n// Función asíncrona\nvoid asyncFunction(const string &name, int time) {\n    cout << \"Inicia \" << name << \" a las \" << getCurrentTime() << \" con una duración de \" << time << \" segundos.\"\n         << endl;\n\n    // Tiempo de espera\n    this_thread::sleep_for(chrono::seconds(time));\n\n    // Imprimir la hora de finalización\n    cout << \"La función \" << name << \" a terminado el \" << getCurrentTime() << endl;\n}\n\n// Dificultas extra\nvoid dificultadExtra() {\n    // Ejecuta las funciones asíncronas en paralelo\n    future<void> functionC = async(launch::async, asyncFunction, \"C\", 3);\n    future<void> functionB = async(launch::async, asyncFunction, \"B\", 2);\n    future<void> functionA = async(launch::async, asyncFunction, \"A\", 1);\n\n    // Esperar a que las funciones C, B y A terminen\n    functionC.get();\n    functionB.get();\n    functionA.get();\n\n    // Ejecuta la función D\n    cout << endl;\n    asyncFunction(\"Función D\", 1);\n}\n\n\nint main() {\n    // Ejecución secuencial de funciones asíncronas\n    asyncFunction(\"X\", 1);\n    asyncFunction(\"Y\", 2);\n\n    // Dificultad extra\n    cout << endl << \"Dificultad extra: Ejecución en paralelo\" << endl;\n    dificultadExtra();\n}\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/dart/teren91.dart",
    "content": "/*\n * EJERCICIO:\n * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n * asíncrona una función que tardará en finalizar un número concreto de\n * segundos parametrizables. También debes poder asignarle un nombre.\n * La función imprime su nombre, cuándo empieza, el tiempo que durará\n * su ejecución y cuando finaliza.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han\n *   finalizado.\n */\n\nimport 'dart:async';\n\nvoid main() async\n{\n\n  //Ejecución en paralelo\n  List<Future<void>> functions = [\n\n    showName('Función C', 3),\n    showName('Función B', 2),\n    showName('Función A', 1)\n  ];\n\n  await Future.wait(functions); \n  \n  await showName('Función D', 1);\n}\n\nFuture<void> showName(String name, int duration) async \n{\n  await Future.delayed(Duration(seconds: duration));\n  print('Soy $name');\n}"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/ejercicio.md",
    "content": "# #15 ASINCRONÍA\n> #### Dificultad: Difícil | Publicación: 08/04/24 | Corrección: 15/04/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n * asíncrona una función que tardará en finalizar un número concreto de\n * segundos parametrizables. También debes poder asignarle un nombre.\n * La función imprime su nombre, cuándo empieza, el tiempo que durará\n * su ejecución y cuando finaliza.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han\n *   finalizado.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/elixir/boterop.ex",
    "content": "defmodule Boterop.Asynchrony do\n  @spec timer(seconds :: integer()) :: Task.t()\n  def timer(seconds) do\n    Task.async(fn ->\n      for count <- 1..seconds do\n        :timer.sleep(995)\n        IO.inspect(count)\n      end\n    end)\n  end\n\n  @spec async_func(name :: String.t(), seconds :: integer()) :: Task.t()\n  def async_func(name, seconds) do\n    Task.async(fn ->\n      print_start(name, seconds)\n      :timer.sleep(seconds * 1000)\n      print_end(name)\n    end)\n  end\n\n  @spec a() :: Task.t()\n  def a() do\n    name = \"A\"\n    seconds = 1\n\n    Task.async(fn ->\n      print_start(name, seconds)\n\n      :timer.sleep(seconds * 1000)\n      print_end(name)\n    end)\n  end\n\n  @spec b() :: Task.t()\n  def b() do\n    name = \"B\"\n    seconds = 2\n\n    Task.async(fn ->\n      print_start(name, seconds)\n\n      :timer.sleep(seconds * 1000)\n      print_end(name)\n    end)\n  end\n\n  @spec c() :: Task.t()\n  def c() do\n    name = \"C\"\n    seconds = 3\n\n    Task.async(fn ->\n      print_start(name, seconds)\n\n      :timer.sleep(seconds * 1000)\n      print_end(name)\n    end)\n  end\n\n  @spec d(on_complete_list :: list(Task.t())) :: Task.t()\n  def d(on_complete_list) do\n    wait_for(on_complete_list)\n\n    Task.async(fn ->\n      name = \"D\"\n      seconds = 1\n\n      print_start(name, seconds)\n\n      :timer.sleep(seconds * 1000)\n      print_end(name)\n    end)\n  end\n\n  @spec print_start(name :: String.t(), seconds :: integer()) :: String.t()\n  defp print_start(name, seconds), do: IO.inspect(\"Starting #{name} (#{seconds} sec)\")\n\n  @spec print_end(name :: String.t()) :: String.t()\n  defp print_end(name), do: IO.inspect(\"#{name} has finished\")\n\n  @spec wait_for(list(Task.t())) :: term()\n  defp wait_for([]), do: nil\n\n  defp wait_for([head | tail]) do\n    Task.await(head)\n    wait_for(tail)\n  end\nend\n\ntimer = Boterop.Asynchrony.timer(15)\n\nBoterop.Asynchrony.async_func(\"Task 1\", 10)\na = Boterop.Asynchrony.a()\nb = Boterop.Asynchrony.b()\nc = Boterop.Asynchrony.c()\nBoterop.Asynchrony.d([a, b, c])\n\nTask.await(timer, 20000)\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/go/DaFi02.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n\t\"time\"\n)\n\nfunc main() {\n\tvar wg sync.WaitGroup\n\n\twg.Add(1)\n\tgo process(&wg, \"Soy un proceso y duro poco :c\", 1)\n\twg.Wait()\n\n\tfmt.Println(\"-------------------------\")\n\tfmt.Println(\"Reto : Procesos en paralelo con un proceso más largo\")\n\tfmt.Println(\"-------------------------\")\n\n\twg.Add(3)\n\n\tgo process(&wg, \"C\", 3)\n\tgo process(&wg, \"B\", 2)\n\tgo process(&wg, \"A\", 1)\n\n\twg.Wait()\n\n\tfmt.Println(\"-------------------------\")\n\n\twg.Add(1)\n\tgo process(&wg, \"D\", 1)\n\twg.Wait()\n}\n\nfunc process(wg *sync.WaitGroup, name string, seconds int) {\n\tdefer wg.Done()\n\tstart := time.Now()\n\tfmt.Printf(\"El proceso %s comienza a las  %s y terminará en %d segundos\\n\", name, start.Format(time.DateTime), seconds)\n\ttime.Sleep(time.Duration(seconds) * time.Second)\n\tfmt.Printf(\"Proceso: %s terminó a las: %s\\n\", name, time.Now().Format(time.DateTime))\n}\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/go/MiguelP-Dev.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n\t\"time\"\n)\n\nfunc AsyncT(name string, duration int, wg *sync.WaitGroup) {\n\tif wg != nil {\n\t\tdefer wg.Done()\n\t}\n\n\tstartTime := time.Now()\n\tfmt.Printf(\"Task \\\"%s\\\" started at %s\\n\", name, startTime.Format(\"15:04:05\"))\n\tfmt.Printf(\"Task \\\"%s\\\" will last %d seconds\\n\", name, duration)\n\n\ttime.Sleep(time.Duration(duration) * time.Second)\n\n\tendTime := time.Now()\n\tfmt.Printf(\"Task \\\"%s\\\" finished at %s\\n\", name, endTime.Format(\"15:04:05\"))\n}\n\nfunc main() {\n\tfmt.Println(\"Starting program...\")\n\n\t// Creamos un Grupo de espera para syncronizar las gorutinas\n\tvar wg sync.WaitGroup\n\n\t// Añadimos 3 tareas al grupo\n\twg.Add(3)\n\n\t// Ejecutamos las tareas A, B y C en paralelo mediante goroutines\n\tgo AsyncT(\"C\", 3, &wg)\n\tgo AsyncT(\"B\", 2, &wg)\n\tgo AsyncT(\"A\", 1, &wg)\n\n\t// Esperamos a que funalizen las todas las tareas\n\twg.Wait()\n\n\t// Una vez finalizadas todas las tareas ejecutamos la tarea D\n\tAsyncT(\"D\", 1, nil)\n\n\tfmt.Println(\"Program Finished\")\n}\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/go/N0HagoNada.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n\t\"time\"\n)\n\nfunc funcionAsincrona(nombre string, duracion time.Duration, wg *sync.WaitGroup) {\n\tif wg != nil {\n\t\tdefer wg.Done()\n\t}\n\tfmt.Printf(\"%s comenzó\\n\", nombre)\n\tfmt.Printf(\"%s tardará %s en finalizar\\n\", nombre, duracion)\n\ttime.Sleep(duracion)\n\tfmt.Printf(\"%s finalizó\\n\", nombre)\n}\n\nfunc main() {\n\tvar wg sync.WaitGroup\n\n\t// Ejecutar las funciones C, B y A en paralelo\n\twg.Add(3)\n\tgo funcionAsincrona(\"Función C\", 3*time.Second, &wg)\n\tgo funcionAsincrona(\"Función B\", 2*time.Second, &wg)\n\tgo funcionAsincrona(\"Función A\", 1*time.Second, &wg)\n\n\t// Esperar a que las funciones C, B y A finalicen\n\twg.Wait()\n\n\t// Ejecutar la función D\n\tfuncionAsincrona(\"Función D\", 1*time.Second, nil)\n\n\tfmt.Println(\"Programa finalizado\")\n}\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/go/hozlucas28.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n\t\"time\"\n)\n\nfunc fn(fnName string, delay int8) {\n\tfmt.Printf(\"\\n%s start...\\n\", fnName)\n\tvar startTime time.Time = time.Now()\n\n\ttime.Sleep(time.Duration(delay))\n\n\tvar endTime time.Time = time.Now()\n\tfmt.Printf(\"%s: %v\\n\", fnName, endTime.Sub(startTime))\n\tfmt.Printf(\"%s end!\\n\", fnName)\n}\n\nfunc main() {\n\t/*\n\t   Asynchrony...\n\t*/\n\tvar startTime time.Time = time.Now()\n\n\tfmt.Println(\"Asynchrony...\")\n\n\tvar wg sync.WaitGroup\n\n\tfmt.Println(\"\\n> Instructions executed before calling `asyncFn` (asynchrony function)\")\n\n\twg.Add(1)\n\tgo func() {\n\t\tdefer wg.Done()\n\t\tfn(\"asyncFn\", 5)\n\t}()\n\n\tfmt.Println(\"\\n> Instructions executed after called `asyncFn` (asynchrony function)\")\n\n\twg.Wait()\n\n\tfmt.Println(\"\\n# ---------------------------------------------------------------------------------- #\")\n\n\t/*\n\t   Additional challenge...\n\t*/\n\n\tfmt.Println(\"\\nAdditional challenge...\")\n\n\twg.Add(3)\n\tgo func() {\n\t\tfor range 3 {\n\t\t\tdefer wg.Done()\n\t\t}\n\n\t\tfn(\"A\", 1)\n\t\tfn(\"B\", 2)\n\t\tfn(\"C\", 3)\n\t}()\n\n\twg.Wait()\n\tfn(\"D\", 1)\n\n\tfmt.Printf(\"\\nTotal time of execution: %v\", time.Now().Sub(startTime))\n}\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/go/kodenook.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n\t\"time\"\n)\n\nfunc main() {\n\tvar wg sync.WaitGroup\n\n\twg.Add(2)\n\n\tgo MyFunc(\"async 1\", &wg)\n\tgo MyFunc(\"async 2\", &wg)\n\n\twg.Wait()\n}\n\nfunc MyFunc(name string, wg *sync.WaitGroup) {\n\tstart := time.Now()\n\tdefer wg.Done()\n\n\tfmt.Printf(\"name execution : %v\\n\", name)\n\tfmt.Printf(\"start %v execution : %v\\n\", name, start)\n\n\tfmt.Printf(\"duration %v execution : 5 milliseconds\\n\", name)\n\ttime.Sleep(5 * time.Millisecond)\n\n\tfmt.Printf(\"execution %v finalized at: %v\\n\", name, time.Now())\n}\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/go/miguelex.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"time\"\n)\n\nfunc asyncTask(name string, seconds int) <-chan struct{} {\n\tdone := make(chan struct{})\n\tgo func() {\n\t\tfmt.Printf(\"Comienza la función %s. Duración de %d segundos. Hora de comienzo %s\\n\", name, seconds, time.Now().Format(\"15:04:05\"))\n\t\ttime.Sleep(time.Duration(seconds) * time.Second)\n\t\tfmt.Printf(\"Finaliza la función %s. Hora de finalización %s\\n\", name, time.Now().Format(\"15:04:05\"))\n\t\tclose(done)\n\t}()\n\treturn done\n}\n\nfunc main() {\n\n\tdone := asyncTask(\"Test 1\", 5)\n\t<-done\n\n\t// Extra\n\tdoneC := asyncTask(\"C\", 3)\n\tdoneB := asyncTask(\"B\", 2)\n\tdoneA := asyncTask(\"A\", 1)\n\t<-doneC\n\t<-doneB\n\t<-doneA\n\tdoneD := asyncTask(\"D\", 1)\n\t<-doneD\n}\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/go/qwik-zgheib.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n\t\"time\"\n)\n\ntype Task interface {\n\tRun()\n\tGetName() string\n}\n\ntype NamedTask struct {\n\tName     string\n\tDuration time.Duration\n}\n\nfunc NewNamedTask(name string, duration time.Duration) *NamedTask {\n\treturn &NamedTask{Name: name, Duration: duration}\n}\n\nfunc (t *NamedTask) Run() {\n\tstartTime := time.Now()\n\tfmt.Printf(\"Task %s started at %s and will run for %d seconds\\n\", t.Name, startTime.Format(\"15:04:05\"), t.Duration)\n\ttime.Sleep(t.Duration * time.Second)\n\tendTime := time.Now()\n\tfmt.Printf(\"Task %s ended at %s\\n\", t.Name, endTime.Format(\"15:04:05\"))\n}\n\nfunc (t *NamedTask) GetName() string {\n\treturn t.Name\n}\n\ntype AsyncExecutor struct {\n\ttasks []Task\n\twg    *sync.WaitGroup\n}\n\nfunc NewAsyncExecutor() *AsyncExecutor {\n\treturn &AsyncExecutor{wg: &sync.WaitGroup{}}\n}\n\nfunc (ae *AsyncExecutor) AddTask(task Task) {\n\tae.tasks = append(ae.tasks, task)\n}\n\nfunc (ae *AsyncExecutor) RunAllTasks() {\n\tfor _, task := range ae.tasks {\n\t\tae.wg.Add(1)\n\t\tgo func(t Task) {\n\t\t\tdefer ae.wg.Done()\n\t\t\tt.Run()\n\t\t}(task)\n\t}\n}\n\nfunc (ae *AsyncExecutor) Wait() {\n\tae.wg.Wait()\n}\n\nfunc main() {\n\ttaskC := NewNamedTask(\"C\", 3)\n\ttaskB := NewNamedTask(\"B\", 2)\n\ttaskA := NewNamedTask(\"A\", 1)\n\ttaskD := NewNamedTask(\"D\", 1)\n\n\texecutor := NewAsyncExecutor()\n\n\texecutor.AddTask(taskC)\n\texecutor.AddTask(taskB)\n\texecutor.AddTask(taskA)\n\n\texecutor.RunAllTasks()\n\n\texecutor.Wait()\n\n\ttaskD.Run()\n}\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/go/raynerpv2022.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n\t\"time\"\n)\n\n// /*\n//   - EJERCICIO:\n//   - Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n//   - asíncrona una función que tardará en finalizar un número concreto de\n//   - segundos parametrizables. También debes poder asignarle un nombre.\n//   - La función imprime su nombre, cuándo empieza, el tiempo que durará\n//   - su ejecución y cuando finaliza.\n//     *\n//   - DIFICULTAD EXTRA (opcional):\n//   - Utilizando el concepto de asincronía y la función anterior, crea\n//   - el siguiente programa que ejecuta en este orden:\n//   - - Una función C que dura 3 segundos.\n//   - - Una función B que dura 2 segundos.\n//   - - Una función A que dura 1 segundo.\n//   - - Una función D que dura 1 segundo.\n//   - - Las funciones C, B y A se ejecutan en paralelo.\n//   - - La función D comienza su ejecución cuando las 3 anteriores han\n//   - finalizado.\n//     */\n\nfunc my_task(duration int, name string, wg *sync.WaitGroup) {\n\tif wg != nil {\n\t\tdefer wg.Done()\n\t}\n\tstart := time.Now()\n\tfmt.Printf(\" Task: %v Start: %v\\n\", name, start)\n\ttime.Sleep(time.Duration(duration) * time.Second)\n\tend := time.Now()\n\tfmt.Printf(\" Task: %v End: %v  Duration%v\\n\", name, end, duration)\n}\n\nfunc main() {\n\tvar wg sync.WaitGroup\n\twg.Add(3)\n\tgo my_task(10, \"TAsk A\", &wg)\n\tgo my_task(8, \"TAsk B\", &wg)\n\tgo my_task(4, \"TAsk c\", &wg)\n\twg.Wait()\n\tmy_task(1, \"TAsk D\", nil)\n\n}\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/go/thegera4.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"time\"\n)\n\nfunc main() {\n\t// Ejercicio regular:\n\tasyncFunction(\"Prueba\", 5, nil)\n\n\t// Ejercicio EXTRA:\n\t// Primero, creamos un canal de tipo booleano (un canal es una estructura de datos que permite la comunicación entre goroutines)\n\tdoneChan := make(chan bool) \n\tdefer close(doneChan)\n\n\t// Luego, ejecutamos las goroutines / funciones de forma concurrente\n\tgo asyncFunction(\"C\", 3, doneChan) // goroutines son funciones que se ejecutan de forma concurrente (al mismo tiempo / paralelas)\n\tgo asyncFunction(\"B\", 2, doneChan) // solo agregamos la palabra \"go\" antes de la llamada a la función, asi se ejecuta de forma concurrente\n\tgo asyncFunction(\"A\", 1, doneChan) // y le pasamos el canal para que las goroutines puedan indicar que han finalizado\n\n\t// Esperamos a que las funciones finalicen (se envíe un valor al canal)\n\tfor i := 0; i < 3; i++ {\n\t\t<-doneChan\n\t}\n\n\t// Luego continuamos con la ejecución del programa. En este caso, ejecutamos una función de forma secuencial.\n\tasyncFunction(\"D\", 1, nil)\n\n}\n\nfunc asyncFunction(name string, seconds int, doneChan chan bool) {\n\tfmt.Printf(\"La función %s comienza a las %s\\n\", name, time.Now().Format(\"15:04:05\"))\n\tfmt.Printf(\"La función %s durará %d segundos\\n\", name, seconds)\n\ttime.Sleep(time.Duration(seconds) * time.Second)\n\tfmt.Printf(\"La función %s finaliza a las %s\\n\", name, time.Now().Format(\"15:04:05\"))\n\tif doneChan != nil{ \n\t\tdoneChan <- true // Enviamos un valor al canal para indicar que la función ha finalizado\n\t}\n}"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/java/AmadorQuispe.java",
    "content": "/* ╔══════════════════════════════════════╗\n   ║ Autor:  Amador Q                     ║\n   ║ Web  : https://amsoft.dev            ║\n   ║ 2024                                 ║\n   ╚══════════════════════════════════════╝\n*/\n\n\npublic class Main {\n    public static void main(String[] args) throws InterruptedException {\n        Thread functionX = createAsyncFunction(\"Funcion X\", 4);\n        Thread functionA = createAsyncFunction(\"Funcion A\", 1);\n        Thread functionB = createAsyncFunction(\"Funcion B\", 2);\n        Thread functionC = createAsyncFunction(\"Funcion C\", 3);\n        Thread functionD = createAsyncFunction(\"Funcion D\", 1);\n        // Inicia la ejecución de las tres funciones\n        functionX.start();\n        functionC.start();\n        functionB.start();\n        functionA.start();\n        // Espera que se ejecuten (join)\n        functionC.join();\n        functionB.join();\n        functionA.join();\n\n        System.out.println(\"Regresamos a main para continuar\");\n        // Iniciamos la función D se aseguró que las funciones A,B,C ya terminaaron\n        functionD.start();\n    }\n\n    public static Thread createAsyncFunction(String functionName, int secondsToRun) {\n        return new Thread(() -> {\n            System.out.println(functionName + \" empezó.\");\n            long startTime = System.currentTimeMillis();\n            try {\n                Thread.sleep(secondsToRun * 1000);\n            } catch (InterruptedException e) {\n                e.printStackTrace();\n            }\n\n            long endTime = System.currentTimeMillis();\n            System.out.println(functionName + \" duró \" + secondsToRun + \" segundos.\");\n            System.out.println(functionName + \" finalizó. Tiempo total: \" + (endTime - startTime) + \" milisegundos.\");\n        });\n    }\n}\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/java/AnaLauDB.java",
    "content": "import java.time.LocalTime;\nimport java.util.concurrent.CompletableFuture;\n\npublic class AnaLauDB {\n\n    // Función asíncrona parametrizable\n    public static CompletableFuture<Void> tareaAsync(String nombre, int segundos) {\n        return CompletableFuture.runAsync(() -> {\n            System.out.println(\"[\" + LocalTime.now() + \"] \" + nombre + \" inicia. Duración: \" + segundos + \" segundos.\");\n            try {\n                Thread.sleep(segundos * 1000L);\n            } catch (InterruptedException e) {\n                System.out.println(nombre + \" fue interrumpida.\");\n            }\n            System.out.println(\"[\" + LocalTime.now() + \"] \" + nombre + \" finaliza.\");\n        });\n    }\n\n    public static void main(String[] args) {\n        // DIFICULTAD EXTRA\n        // C (3s), B (2s), A (1s) en paralelo, luego D (1s) cuando todas acaben\n\n        CompletableFuture<Void> tareaC = tareaAsync(\"Función C\", 3);\n        CompletableFuture<Void> tareaB = tareaAsync(\"Función B\", 2);\n        CompletableFuture<Void> tareaA = tareaAsync(\"Función A\", 1);\n\n        // Cuando C, B y A terminen, ejecutar D\n        CompletableFuture<Void> todas = CompletableFuture.allOf(tareaC, tareaB, tareaA)\n                .thenRun(() -> {\n                    tareaAsync(\"Función D\", 1).join();\n                });\n\n        // Esperar a que todo termine antes de salir\n        todas.join();\n        System.out.println(\"Programa finalizado.\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/java/FranDev200.java",
    "content": "import java.time.LocalTime;\nimport java.time.format.DateTimeFormatter;\n\npublic class FranDev200 {\n\n\n    static void main() {\n\n        /*\n            EJERCICIO:\n            * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n            * asíncrona una función que tardará en finalizar un número concreto de\n            * segundos parametrizables. También debes poder asignarle un nombre.\n            * La función imprime su nombre, cuándo empieza, el tiempo que durará\n            * su ejecución y cuando finaliza.\n         */\n\n        Hilo hilo1 = new Hilo(5, \"Hilo 1\");\n        hilo1.start();\n\n        try {\n            hilo1.join();\n        }catch (InterruptedException e){\n            System.out.println(e.getMessage());\n        }\n\n\n        /*\n            DIFICULTAD EXTRA (opcional):\n            * Utilizando el concepto de asincronía y la función anterior, crea\n            * el siguiente programa que ejecuta en este orden:\n            * - Una función C que dura 3 segundos.\n            * - Una función B que dura 2 segundos.\n            * - Una función A que dura 1 segundo.\n            * - Una función D que dura 1 segundo.\n            * - Las funciones C, B y A se ejecutan en paralelo.\n            * - La función D comienza su ejecución cuando las 3 anteriores han finalizado.\n         */\n\n        Hilo a = new Hilo(1, \"Funcion A\");\n        Hilo b = new Hilo(2, \"Funcion B\");\n        Hilo c = new Hilo(3, \"Funcion C\");\n        Hilo d = new Hilo(1, \"Funcion D\");\n\n        a.start();\n        b.start();\n        c.start();\n\n        try {\n            a.join();\n            b.join();\n            c.join();\n        }catch (InterruptedException e){\n            e.getMessage();\n        }\n\n\n        d.start();\n\n\n    }\n\n    static class Hilo extends Thread {\n\n        int segundos;\n        String nombre;\n\n        Hilo(int segundos, String nombre){\n            this.segundos = segundos;\n            this.nombre = nombre;\n        }\n\n        @Override\n        public void run() {\n            DateTimeFormatter formatter = DateTimeFormatter.ofPattern(\"HH:mm:ss\");\n            LocalTime empieza = LocalTime.now();\n\n\n            System.out.println(\"\\nComienzo de la función: \" + nombre + \", a las \" + formatter.format(empieza));\n            System.out.println(\"Durará: \" +  segundos + \" segundos.\");\n\n            try {\n\n                Thread.sleep(segundos * 1000);\n\n            }catch (InterruptedException e){\n                e.getMessage();\n            }\n\n            LocalTime acaba = LocalTime.now();\n\n            System.out.println(nombre + \" ha finalizado, a las \"  + formatter.format(acaba));\n        }\n    }\n\n\n}\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/java/JesusWay69.java",
    "content": "package ejercicio15;\n\nimport static ejercicio15.JesusWay69.*;\nimport java.time.LocalTime;\nimport java.time.temporal.ChronoUnit;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\n\n\n/*\n * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n * asíncrona una función que tardará en finalizar un número concreto de segundos\n * parametrizables. También debes poder asignarle un nombre. La función imprime\n * su nombre, cuándo empieza, el tiempo que durará su ejecución y cuando\n * finaliza.\n */\npublic class JesusWay69 {\n\n    public static void main(String[] args) throws InterruptedException {\n        asynchrone(2, \"Hola mundo\");\n        C myThreadC = new C();\n        B myThreadB = new B();\n        A myThreadA = new A();\n        myThreadC.start();\n        myThreadB.start();\n        myThreadA.start(); \n        \n    }\n\n    static void asynchrone(int waitSeconds, String name) throws InterruptedException {\n        LocalTime startTime = LocalTime.now();\n        System.out.println(\"La ejecución de '\" + name + \"' durará \" + waitSeconds + \" segundos\");\n        System.out.println(\"La ejecución comienza a las \" + LocalTime.now().getHour() + \":\" + LocalTime.now().getMinute() + \":\" + LocalTime.now().getSecond());\n        Thread.sleep(waitSeconds * 1000);\n        System.out.println(\"Ejecución terminada a las \" + LocalTime.now().getHour() + \":\" + LocalTime.now().getMinute() + \":\" + LocalTime.now().getSecond());\n        LocalTime endTime = LocalTime.now();\n        System.out.println(\"Duración de la ejecución: \" + ChronoUnit.SECONDS.between(startTime, endTime) + \" segundos.\");\n    }\n\n /*\n * DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han finalizado.\n */\n    static void C() throws InterruptedException {\n        System.out.println(\"Función C iniciada a las: \" + LocalTime.now().getHour() + \":\" + LocalTime.now().getMinute() + \":\" + LocalTime.now().getSecond());\n        Thread.sleep(3000);\n        System.out.println(\"Función C terminada a las: \" + LocalTime.now().getHour() + \":\" + LocalTime.now().getMinute() + \":\" + LocalTime.now().getSecond());\n        D();\n    }\n\n    static void B() throws InterruptedException {\n        System.out.println(\"Función B iniciada a las: \" + LocalTime.now().getHour() + \":\" + LocalTime.now().getMinute() + \":\" + LocalTime.now().getSecond());\n        Thread.sleep(2000);\n        System.out.println(\"Función B terminada a las: \" + LocalTime.now().getHour() + \":\" + LocalTime.now().getMinute() + \":\" + LocalTime.now().getSecond());\n    }\n\n    static void A() throws InterruptedException {\n        System.out.println(\"Función A iniciada a las: \" + LocalTime.now().getHour() + \":\" + LocalTime.now().getMinute() + \":\" + LocalTime.now().getSecond());\n        Thread.sleep(1000);\n        System.out.println(\"Función A terminada a las: \" + LocalTime.now().getHour() + \":\" + LocalTime.now().getMinute() + \":\" + LocalTime.now().getSecond());\n    }\n\n    static void D() throws InterruptedException {\n        System.out.println(\"Función D iniciada a las: \" + LocalTime.now().getHour() + \":\" + LocalTime.now().getMinute() + \":\" + LocalTime.now().getSecond());\n        Thread.sleep(1000);\n        System.out.println(\"Función D terminada a las: \" + LocalTime.now().getHour() + \":\" + LocalTime.now().getMinute() + \":\" + LocalTime.now().getSecond());\n    }\n\n}\n\nclass C extends Thread {\n\n    @Override\n    public void run() {\n        try {\n            C();\n        } catch (InterruptedException ex) {\n            Logger.getLogger(C.class.getName()).log(Level.SEVERE, null, ex);\n        }\n\n    }\n}\n\nclass B extends Thread {\n\n    @Override\n    public void run() {\n        try {\n            B();\n        } catch (InterruptedException ex) {\n            Logger.getLogger(B.class.getName()).log(Level.SEVERE, null, ex);\n        }\n\n    }\n}\n\nclass A extends Thread {\n\n    @Override\n    public void run() {\n        try {\n            A();\n        } catch (InterruptedException ex) {\n            Logger.getLogger(A.class.getName()).log(Level.SEVERE, null, ex);\n        }\n\n    }\n}\n\n\n\n\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/java/JimsimroDev.java",
    "content": "import java.time.LocalDateTime;\nimport java.time.Duration;\nimport java.lang.Thread;\npublic class JimsimroDev {\n  private static int tareasEjecutadas = 0;\n   private static final Object lock = new Object();\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n * asíncrona una función que tardará en finalizar un número concreto de\n * segundos parametrizables. También debes poder asignarle un nombre.\n * La función imprime su nombre, cuándo empieza, el tiempo que durará\n * su ejecución y cuando finaliza.\n */\n  public static void tarea(String name, int duration) {\n\n    long startTime = System.currentTimeMillis();\n    LocalDateTime inicio = LocalDateTime.now();\n    imprimirInicio(name, inicio, duration);\n\n    Thread thread = new Thread(() ->{\n      try {\n        //Simula un esperar durante la duración especificada\n          System.out.printf(\"Tarea: %s en espera durante %d milisegundos %n\", name, duration);\n        Thread.sleep(duration);\n      } catch (InterruptedException e) {\n        System.err.println(\"Tarea interrupted: \" + e.getMessage());\n      }\n\n      LocalDateTime fin = LocalDateTime.now();\n      long endTime = System.currentTimeMillis();\n\n      System.out.printf(\"Tarea: %s finalizo el %s y su duracion es %d %n\", name,fin,duration);\n\n      System.out.printf(\"Tarea: %s duración en milisegundos %d %n\", name, (endTime - startTime));\n    });\n        thread.start();\n  }\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han finalizado.\n */\n  public static void crearThreads(String name, int duracion) {\n    long startTime = System.currentTimeMillis();\n\n    Thread thread = new Thread(() ->{\n      try {\n        LocalDateTime inicio = LocalDateTime.now();\n        imprimirInicio(name, inicio, duracion);\n\n        Thread.sleep(duracion);\n        //Simula un esperar durante la duración especificada\n        synchronized (lock){\n          ++tareasEjecutadas;\n          System.out.printf(\"Tareas completedas %d%n\", tareasEjecutadas);\n          lock.notifyAll();\n        }\n      } catch (InterruptedException e) {\n        System.err.println(\"Tarea interrupted: \" + e.getMessage());\n      }\n\n      LocalDateTime fin = LocalDateTime.now();\n      long endTime = System.currentTimeMillis();\n\n      System.out.printf(\"Tarea: %s finalizo el %s y su duracion es %d %n\", name,fin,duracion);\n\n      System.out.printf(\"Tarea: %s duración en milisegundos %d %n\", name, (endTime - startTime));\n    });\n        thread.start();\n  }\n\n  public static void imprimirInicio(String name, LocalDateTime inicio, int duration){\n        System.out.printf(\"🟢 Tarea: %s inició a las %s (duración: %d ms)%n\", name, inicio, duration);\n  }\n  public static void esperarTareas(int count){\n    Thread thread = new Thread(() ->{\n          synchronized (lock){\n      while (tareasEjecutadas < count){\n        try{\n\n            System.out.println(\"Esperando que tareas sean ejecutadas...\");\n            lock.wait();\n        }catch (InterruptedException e){\n          System.err.println(\"Thread interrupted: \" + e.getMessage());\n        }\n      }\n          }\n      System.out.println(\"Las  tres primeras tareas han sido ejecutadas\");\n      crearThreads(\"D\", 1000);\n    });\n    thread.start();\n  }\n  //Extra \n   public static void multiThread() {\n      crearThreads(\"C\", 3000);\n      crearThreads(\"B\", 2000);\n      crearThreads(\"A\", 1000);\n      System.out.println(\"Tareas iniciadas\");\n  }\n\n    public static void main(String[] args) {\n\n//    tarea(\"1\", 5000);\n    //Extra\n multiThread();\n esperarTareas(3);\n    }\n}\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/java/Josegs95.java",
    "content": "import java.time.LocalTime;\nimport java.util.concurrent.BrokenBarrierException;\nimport java.util.concurrent.CyclicBarrier;\n\npublic class Josegs95 {\n    public static void main(String[] args) {\n        //Ejercicio\n        Thread thread = new Thread(new Task(\"Tarea 1\", 5, false));\n        thread.start();\n\n        //Reto\n        System.out.println(\"\\n\");\n        retoFinal();\n        System.out.println(\"Finaliza el programa\");\n    }\n\n    private static CyclicBarrier barrier;\n\n    public static void retoFinal(){\n        Thread thread1 = new Thread(new Task(\"Función C\", 3, true));\n        Thread thread2 = new Thread(new Task(\"Función B\", 2, true));\n        Thread thread3 = new Thread(new Task(\"Función A\", 1, true));\n        Thread thread4 = new Thread(new Task(\"Función D\", 1, false));\n\n        barrier = new CyclicBarrier(3, thread4);\n\n        thread1.start();\n        thread2.start();\n        thread3.start();\n    }\n\n    public static class Task implements Runnable{\n\n        private String name;\n        private int duration;\n        private boolean useBarrier;\n\n        public Task(String name, int duration, boolean useBarrier){\n            this.name = name;\n            this.duration = duration;\n            this.useBarrier = useBarrier;\n        }\n\n        @Override\n        public void run() {\n            System.out.println(name + \" empieza a las \" + LocalTime.now() + \" y durará \" + duration + \" segundos\");\n            try {\n                Thread.sleep(duration * 1000);\n            } catch (InterruptedException e) {\n                throw new RuntimeException(e);\n            }\n            System.out.println(name + \" finaliza a las \" + LocalTime.now());\n\n            if (useBarrier){\n                try {\n                    barrier.await();\n                } catch (InterruptedException e) {\n                    throw new RuntimeException(e);\n                } catch (BrokenBarrierException e) {\n                    throw new RuntimeException(e);\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/java/asjordi.java",
    "content": "import java.time.LocalTime;\nimport java.util.concurrent.CompletableFuture;\nimport java.util.concurrent.TimeUnit;\n\npublic class Main {\n\n    public static void main(String[] args) {\n        asyncFunction(\"Function Z\", 5);\n        asyncFunctions();\n    }\n\n    /**\n     * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n     * asíncrona una función que tardará en finalizar un número concreto de\n     * segundos parametrizables. También debes poder asignarle un nombre.\n     * La función imprime su nombre, cuándo empieza, el tiempo que durará\n     * su ejecución y cuando finaliza.\n     */\n\n    static void asyncFunction(String name, int seconds) {\n        var future = CompletableFuture.runAsync(() -> {\n            System.out.println(name + \" started at \" + LocalTime.now() + \" and will run for \" + seconds + \" seconds\");\n            try {\n                TimeUnit.SECONDS.sleep(seconds);\n            } catch (InterruptedException e) {\n                e.printStackTrace();\n            }\n            System.out.println(name + \" finished at \" + LocalTime.now());\n        });\n        future.join();\n    }\n\n    /**\n     * DIFICULTAD EXTRA (opcional):\n     * Utilizando el concepto de asincronía y la función anterior, crea\n     * el siguiente programa que ejecuta en este orden:\n     * - Una función C que dura 3 segundos.\n     * - Una función B que dura 2 segundos.\n     * - Una función A que dura 1 segundo.\n     * - Una función D que dura 1 segundo.\n     * - Las funciones C, B y A se ejecutan en paralelo.\n     * - La función D comienza su ejecución cuando las 3 anteriores han finalizado\n     */\n\n    static void asyncFunctions() {\n        var futureA = CompletableFuture.runAsync(() -> asyncFunction(\"Function A\", 1));\n        var futureB = CompletableFuture.runAsync(() -> asyncFunction(\"Function B\", 2));\n        var futureC = CompletableFuture.runAsync(() -> asyncFunction(\"Function C\", 3));\n        CompletableFuture.allOf(futureA, futureB, futureC).join();\n        asyncFunction(\"Function D\", 1);\n    }\n}\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/java/chartypes.java",
    "content": "public class chartypes {\n\n  public static void main(String[] args) {\n    try {\n      exercise();\n      extra();\n\n    } catch (Exception e) {\n      System.out.println(e.getMessage());\n    }\n\n  }\n\n  private static Thread asynFunction(String funcitonName, int duration) {\n    return new Thread(() -> {\n\n      long startTime = System.currentTimeMillis();\n      System.out.println(\n          funcitonName + \" started. Time: \" + startTime +\n              \" milliseconds. Should take \" + duration * 1000 + \" milliseconds.\");\n      try {\n        Thread.sleep((long) duration * 1000);\n      } catch (InterruptedException e) {\n        System.out.println(e.getMessage());\n      }\n\n      long endTime = System.currentTimeMillis();\n      System.out.println(funcitonName + \" has done. Time: \" + (endTime - startTime) + \" milliseconds\");\n\n    });\n  }\n\n  private static void exercise() {\n    System.out.println(\"EXERCISE:\");\n    Thread thread = asynFunction(\"my function1\", 20);\n    thread.start();\n    try {\n\n      thread.join();\n    } catch (InterruptedException e) {\n      e.printStackTrace();\n    }\n\n  }\n\n  private static void extra() {\n\n    System.out.println();\n    System.out.println(\"EXTRA:\");\n\n    Thread threadA = asynFunction(\"Function A\", 1);\n    Thread threadB = asynFunction(\"Function B\", 2);\n    Thread threadC = asynFunction(\"Function C\", 3);\n    Thread threadD = asynFunction(\"Function D\", 1);\n\n    try {\n      threadA.start();\n      threadB.start();\n      threadC.start();\n\n      threadA.join(5000);\n      threadB.join(5000);\n      threadC.join(5000);\n\n      System.out.println(\"Starting Function D...\");\n      threadD.start();\n      threadD.join();\n\n    } catch (InterruptedException e) {\n      System.out.println(e.getMessage());\n    }\n\n  }\n}\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/java/danhingar.java",
    "content": "import java.time.LocalDateTime;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\n\npublic class danhingar {\n\n    public static void main(String[] args) throws InterruptedException {\n        Thread thread = taskThread(\"1\", 10);\n        thread.start();\n        taskExecutor(\"1\", 10);\n\n        // Ejercicio extra\n        extraThread();\n\n    }\n\n    private static Thread taskThread(String name, int seconds) {\n        return new Thread(() -> {\n            try {\n                System.out.println(\"Tarea: \" + name + \". Duración: \" + seconds + \"s. Inicio: \" + LocalDateTime.now());\n                Thread.sleep(seconds * 1000);\n                System.out.println(\"Tarea: \" + name + \". Fin: \" + LocalDateTime.now());\n            } catch (InterruptedException e) {\n                e.printStackTrace();\n            }\n        });\n    }\n\n    private static void taskExecutor(String name, int seconds) {\n        ExecutorService threadpool = Executors.newCachedThreadPool();\n        threadpool.submit(() -> {\n            System.out.println(\"Tarea: \" + name + \". Duración: \" + seconds + \"s. Inicio: \" + LocalDateTime.now());\n            try {\n                Thread.sleep(seconds * 1000);\n            } catch (InterruptedException e) {\n                e.printStackTrace();\n            }\n            System.out.println(\"Tarea: \" + name + \". Fin: \" + LocalDateTime.now());\n        });\n        threadpool.shutdown();\n    }\n\n    private static void extraThread() {\n        Thread threadC = taskThread(\"C\", 3);\n        Thread threadB = taskThread(\"B\", 2);\n        Thread threadA = taskThread(\"A\", 1);\n\n        threadC.start();\n        threadB.start();\n        threadA.start();\n\n        try {\n            threadC.join();\n            threadB.join();\n            threadA.join();\n        } catch (Exception e) {\n            System.out.println(\"Error al terminar la ejecución\");\n        }\n\n        Thread threadD = taskThread(\"D\", 1);\n        threadD.start();\n    }\n}\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/java/eulogioep.java",
    "content": "import java.util.concurrent.CompletableFuture;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.TimeUnit;\n\npublic class eulogioep {\n    \n    /**\n     * Método principal que demuestra el uso de asincronía en Java\n     */\n    public static void main(String[] args) {\n        // Demostración básica\n        System.out.println(\"=== Demostración Básica ===\");\n        ejecutarTareaAsincrona(\"TareaEjemplo\", 2);\n        \n        // Para asegurar que la demostración básica termine antes de la extra\n        try {\n            Thread.sleep(3000);\n        } catch (InterruptedException e) {\n            e.printStackTrace();\n        }\n        \n        // Dificultad Extra\n        System.out.println(\"\\n=== Dificultad Extra ===\");\n        dificultadExtra();\n    }\n    \n    /**\n     * Ejecuta una tarea asíncrona con un nombre y duración especificados\n     * @param nombre Nombre de la tarea\n     * @param segundos Duración de la tarea en segundos\n     * @return CompletableFuture<Void> que representa la tarea asíncrona\n     */\n    public static CompletableFuture<Void> ejecutarTareaAsincrona(String nombre, int segundos) {\n        return CompletableFuture.runAsync(() -> {\n            try {\n                System.out.println(nombre + \" - Iniciando...\");\n                System.out.println(nombre + \" - Durará \" + segundos + \" segundos\");\n                Thread.sleep(segundos * 1000);\n                System.out.println(nombre + \" - Finalizada\");\n            } catch (InterruptedException e) {\n                e.printStackTrace();\n            }\n        });\n    }\n    \n    /**\n     * Implementación de la dificultad extra\n     * Ejecuta las tareas C, B y A en paralelo y luego D cuando las anteriores terminan\n     */\n    public static void dificultadExtra() {\n        // Crear un ExecutorService para manejar los hilos\n        ExecutorService executor = Executors.newFixedThreadPool(3);\n        \n        // Crear las tareas asíncronas\n        CompletableFuture<Void> tareaC = ejecutarTareaAsincrona(\"Tarea C\", 3);\n        CompletableFuture<Void> tareaB = ejecutarTareaAsincrona(\"Tarea B\", 2);\n        CompletableFuture<Void> tareaA = ejecutarTareaAsincrona(\"Tarea A\", 1);\n        \n        // Esperar a que todas las tareas terminen y luego ejecutar D\n        CompletableFuture.allOf(tareaC, tareaB, tareaA)\n            .thenRun(() -> ejecutarTareaAsincrona(\"Tarea D\", 1));\n        \n        // Esperar a que todo termine antes de cerrar el programa\n        try {\n            executor.shutdown();\n            executor.awaitTermination(10, TimeUnit.SECONDS);\n        } catch (InterruptedException e) {\n            e.printStackTrace();\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/java/h4ckxel.java",
    "content": "public class h4ckxel{\n\npublic static void main(String[] args) {\n    try {\n        exercise();\n        extra();\n\n    } catch (Exception e) {\n        System.out.println(e.getMessage());\n    }\n}\n\nprivate static Thread asynFunction(String funcitonName, int duration) {\n    return new Thread(() -> {\n\n    long startTime = System.currentTimeMillis();\n    System.out.println(\n        funcitonName + \" started. Time: \" + startTime +\n              \" milliseconds. Should take \" + duration * 1000 + \" milliseconds.\");\n    try {\n        Thread.sleep((long) duration * 1000);\n    } catch (InterruptedException e) {\n        System.out.println(e.getMessage());\n    }\n\n    long endTime = System.currentTimeMillis();\n    System.out.println(funcitonName + \" has done. Time: \" + (endTime - startTime) + \" milliseconds\");\n\n    });\n}\n\nprivate static void exercise() {\n    System.out.println(\"EXERCISE:\");\n    Thread thread = asynFunction(\"my function1\", 20);\n    thread.start();\n    try {\n\n    thread.join();\n    } catch (InterruptedException e) {\n    e.printStackTrace();\n    }\n\n}\n\nprivate static void extra() {\n\n    System.out.println();\n    System.out.println(\"EXTRA:\");\n\n    Thread threadA = asynFunction(\"Function A\", 1);\n    Thread threadB = asynFunction(\"Function B\", 2);\n    Thread threadC = asynFunction(\"Function C\", 3);\n    Thread threadD = asynFunction(\"Function D\", 1);\n\n    try {\n    threadA.start();\n    threadB.start();\n    threadC.start();\n\n    threadA.join(5000);\n    threadB.join(5000);\n    threadC.join(5000);\n\n    System.out.println(\"Starting Function D...\");\n    threadD.start();\n    threadD.join();\n\n    } catch (InterruptedException e) {\n    System.out.println(e.getMessage());\n    }\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/java/martinbohorquez.java",
    "content": "import java.time.LocalDateTime;\nimport java.time.format.DateTimeFormatter;\nimport java.util.concurrent.CountDownLatch;\n\nimport static java.util.concurrent.TimeUnit.SECONDS;\n\n/**\n * #15 ASINCRONÍA\n *\n * @author martinbohorquez\n */\npublic class martinbohorquez {\n\n    private static final DateTimeFormatter f = DateTimeFormatter.ofPattern(\"dd-MM-yyyy HH:mm:ss\");\n\n    public static void main(String[] args) throws InterruptedException {\n        CountDownLatch latch = new CountDownLatch(2);\n        getTask(\"tarea 1\", 3, latch);\n        getTask(\"tarea 2\", 2, latch);\n        latch.await();\n\n        /*\n         * DIFICULTAD EXTRA\n         */\n        latch = new CountDownLatch(3);\n        System.out.println(\"[======== DIFICULTAD EXTRA =========]\");\n        getTask(\"C\", 3, latch);\n        getTask(\"B\", 2, latch);\n        getTask(\"A\", 1, latch);\n        latch.await();\n        getTask(\"D\", 1, latch);\n\n    }\n\n    private static void getTask(String tarea, int duration, CountDownLatch latch) throws InterruptedException {\n        Task task = new Task(tarea, duration, latch);\n        task.start();\n//        if (join) task.join();\n    }\n\n    public static class Task extends Thread {\n        private final int duration;\n        private final CountDownLatch latch;\n\n        public Task(String name, int duration, CountDownLatch latch) {\n            super(name);\n            this.duration = duration;\n            this.latch = latch;\n        }\n\n        @Override\n        public void run() {\n            System.out.printf(\"Tarea: %s | Duración: %d segundos | Inicio: %s%n\",\n                    getName(), duration, LocalDateTime.now().format(f));\n            try {\n                SECONDS.sleep(duration);\n//                sleep(Duration.ofSeconds(duration));\n            } catch (InterruptedException e) {\n                throw new RuntimeException(e);\n            }\n            System.out.printf(\"Tarea: %s | Fin: %s%n\", getName(), LocalDateTime.now().format(f));\n            latch.countDown();\n            System.out.printf(\"El contador de %s es: %s%n\", getName(), latch.getCount());\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/java/simonguzman.java",
    "content": "import java.util.concurrent.CompletableFuture;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\n\npublic class simonguzman {\n\n    private static ExecutorService executor = Executors.newFixedThreadPool(3);\n\n    public  static void main(String[] args) {\n        executeThreads();\n    }\n\n    public static void executeThreads(){\n        CompletableFuture<Void> futureC = executeAsync(\"C\", 3);\n        CompletableFuture<Void> futureB = executeAsync(\"B\", 2);\n        CompletableFuture<Void> futureA = executeAsync(\"A\", 1);\n\n        CompletableFuture.allOf(futureC, futureB, futureA).thenRun(()->{\n            executeAsync(\"D\", 1);\n        }).thenRun(()->{\n            executor.shutdown();\n        });\n    }\n\n    public static CompletableFuture<Void> executeAsync(String name, int durationSeconds){\n        return CompletableFuture.runAsync(() -> {\n            long startTime = System.currentTimeMillis();   \n            System.out.println(name + \" started at \"+ startTime);\n            System.out.println(name + \" will take \"+durationSeconds+\" seconds to complete\");\n            try {\n                Thread.sleep(durationSeconds * 1000);\n            } catch (InterruptedException e) {\n                Thread.currentThread().interrupt();\n            }\n            long endTime = System.currentTimeMillis();\n            long difference = endTime - startTime;\n            System.out.println(name + \" finished at \"+endTime);\n            System.out.println(name + \" took \"+difference+ \" milliseconds to complete\"); \n            }, executor);\n     }  \n}\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/javascript/7R0N1X.js",
    "content": "const funcionAsincrona = async (nombre, tiempo) => {\n  console.log(`La función \"${nombre}\" comienza. Duración esperada: ${tiempo} segundos.`)\n  const inicio = new Date();\n  console.log(`Inicio: ${inicio.toLocaleTimeString()}`);\n\n  await new Promise(resolve => setTimeout(resolve, tiempo * 1000))\n\n  const fin = new Date();\n  console.log(`La función \"${nombre}\" ha finalizado.`);\n  console.log(`Fin: ${fin.toLocaleTimeString()}`);\n}\n\nfuncionAsincrona(\"Proceso 1\", 5)\n\n// DIFICULTAD EXTRA\nconst funcionC = async () => {\n  console.log('La función C comienza. Duración esperada: 3 segundos.')\n  const inicio = new Date();\n  console.log(`Inicio: ${inicio.toLocaleTimeString()}`);\n\n  await new Promise(resolve => setTimeout(resolve, 3000))\n\n  const fin = new Date();\n  console.log(`La función C ha finalizado.`);\n  console.log(`Fin: ${fin.toLocaleTimeString()}`);\n}\n\nconst funcionB = async () => {\n  console.log('La función B comienza. Duración esperada: 2 segundos.')\n  const inicio = new Date();\n  console.log(`Inicio: ${inicio.toLocaleTimeString()}`);\n\n  await new Promise(resolve => setTimeout(resolve, 2000))\n\n  const fin = new Date();\n  console.log(`La función B ha finalizado.`);\n  console.log(`Fin: ${fin.toLocaleTimeString()}`);\n}\n\nconst funcionA = async () => {\n  console.log('La función A comienza. Duración esperada: 1 segundos.')\n  const inicio = new Date();\n  console.log(`Inicio: ${inicio.toLocaleTimeString()}`);\n\n  await new Promise(resolve => setTimeout(resolve, 1000))\n\n  const fin = new Date();\n  console.log(`La función A ha finalizado.`);\n  console.log(`Fin: ${fin.toLocaleTimeString()}`);\n}\n\nconst funcionD = async () => {\n  console.log('La función D comienza. Duración esperada: 1 segundos.')\n  const inicio = new Date();\n  console.log(`Inicio: ${inicio.toLocaleTimeString()}`);\n\n  await new Promise(resolve => setTimeout(resolve, 1000))\n\n  const fin = new Date();\n  console.log(`La función D ha finalizado.`);\n  console.log(`Fin: ${fin.toLocaleTimeString()}`);\n}\n\nconst main = async () => {\n  const C = funcionC()\n  const B = funcionB()\n  const A = funcionA()\n\n  await Promise.all([C, B, A])\n\n  const D = funcionD()\n}\n\nmain()"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/javascript/AChapeton.js",
    "content": "const asyncFunction = async (name, seconds) => {\n  console.log(`Inicia la ejecucion de ${name}`)\n  console.log(`Duracion de ${name}: ${seconds} segundos`)\n  \n  await new Promise(res => {\n    setTimeout(res, seconds * 1000)\n  })\n\n  console.log(`Finaliza la ejecuncion de ${name}`)\n}\n\nconst main = async () => {\n  const promise1 = asyncFunction('Funcion 1', 5)\n  const promise2 = asyncFunction('Funcion 2', 3)\n\n  await Promise.all([promise1, promise2])\n}\n\nmain()\n\n\n// DIFICULTAD EXTRA\n\nconst funcionC = async () => {\n  console.log(`Inicia la ejecucion de la funcion C`)\n  \n  await new Promise(res => {\n    setTimeout(res, 3000)\n  })\n\n  console.log(`Finaliza la ejecucion de la funcion C luego de 3 segundos`)\n}\n\nconst funcionB = async () => {\n  console.log(`Inicia la ejecucion de la funcion B`)\n  \n  await new Promise(res => {\n    setTimeout(res, 2000)\n  })\n\n  console.log(`Finaliza la ejecucion de la funcion B luego de 2 segundos`)\n}\n\nconst funcionA = async () => {\n  console.log(`Inicia la ejecucion de la funcion A`)\n  \n  await new Promise(res => {\n    setTimeout(res, 1000)\n  })\n\n  console.log(`Finaliza la ejecucion de la funcion A luego de 1 segundo`)\n}\n\nconst funcionD = async () => {\n  console.log(`Inicia la ejecucion de la funcion D`)\n  \n  await new Promise(res => {\n    setTimeout(res, 1000)\n  })\n\n  console.log(`Finaliza la ejecucion de la funcion D luego de 1 segundo`)\n}\n\nconst mainFunction = async () => {\n  const respuestaC = funcionC()\n  const respuestaB = funcionB()\n  const respuestaA = funcionA()\n\n  await Promise.all([respuestaC, respuestaB, respuestaA])\n\n  const respuestaD = await funcionD()\n}\n\nmainFunction()"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/javascript/DavidMoralesDeveloper.js",
    "content": "// * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n//  * asíncrona una función que tardará en finalizar un número concreto de\n//  * segundos parametrizables. También debes poder asignarle un nombre.\n//  * La función imprime su nombre, cuándo empieza, el tiempo que durará\n//  * su ejecución y cuando finaliza.\n\n// ------------------------------No es asincrona\n// function temporizador (tiempo){\n//     function saludar( nombre ){\n//         console.log('hola buenas tardes ' + nombre)\n//     }\n//     console.log('aqui comienza settimeout')\n//     setTimeout(() => {\n//     saludar('David')\n//     console.log('finaliza settimeout')\n//     }, tiempo);\n// }\n\n// temporizador(3000)\n\n//async , await --------------------------------------------------------------\n\n\n  function promiseFunction( tarea, tiempo){\n    return new Promise((resolve) => {\n        setTimeout(() => {\n            resolve('la funcion ' + tarea + ' que dura ' + tiempo/1000 + 'segundos')\n        }, tiempo);\n    })\n  }\n\n  //  * DIFICULTAD EXTRA (opcional):\n//  * Utilizando el concepto de asincronía y la función anterior, crea\n//  * el siguiente programa que ejecuta en este orden:\n//  * - Una función C que dura 3 segundos.\n//  * - Una función B que dura 2 segundos.\n//  * - Una función A que dura 1 segundo.\n//  * - Una función D que dura 1 segundo.\n//  * - Las funciones C, B y A se ejecutan en paralelo.\n//  * - La función D comienza su ejecución cuando las 3 anteriores han\n//  *   finalizado.\n//  */\n\n  async function CallAsync () {\n    console.log('llamando a mis tareas')\n    const llamadoa = await promiseFunction('A', 1000)\n    const llamadob = await promiseFunction('B', 2000)\n    const llamadoc = await promiseFunction('C', 3000)\n    const llamadod = await promiseFunction('D', 1000)\n    console.log( await Promise.all([llamadoc, llamadob, llamadoa]))\n    console.log(llamadod)\n  }\n\n  CallAsync()\n\n\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/javascript/Deyvid-10.js",
    "content": "// asincronia\n\nasync function asincrona(nombre, tiempo)\n{\n    console.log(`Inicio: ${new Date().toLocaleTimeString()}`);\n    console.log(`Nombre: ${nombre}`);\n    console.log(`Duracion: ${tiempo} segundos`);\n    let esperar =  await new Promise(texto => setTimeout(() => {texto(nombre)}, tiempo * 1000))\n    console.log(esperar);\n    console.log(`Fin: ${new Date().toLocaleTimeString()}`);\n}\n\nasincrona(\"Asincrono\", 2)\n\n// DIFICULTAD EXTRA\n\nasync function extra()\n{\n    await Promise.all([asincrona(\"C\", 3), asincrona(\"B\", 2), asincrona(\"A\", 1)])\n    await asincrona(\"D\", 1)\n}\n\nextra()\n\n\n  "
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/javascript/FabianRpv.js",
    "content": "// Asincronia\n\n\n\n/**\n * Función asíncrona que simula una tarea que tarda un tiempo en completarse.\n * @param {string} nombre - El nombre de la tarea.\n * @param {number} segundos - El número de segundos que durará la tarea.\n */\nasync function ejecutarTarea(nombre, segundos) {\n    const inicio = new Date();\n    console.log(`[${inicio.toLocaleTimeString()}] Tarea \"${nombre}\" iniciada. Duración: ${segundos} segundos.`);\n\n    // Simulamos la tarea asíncrona con un setTimeout dentro de una promesa\n    await new Promise((resolve) => {\n        setTimeout(resolve, segundos * 1000);\n    });\n\n    const fin = new Date();\n    console.log(`[${fin.toLocaleTimeString()}] Tarea \"${nombre}\" finalizada.`);\n}\n\n/**\n * Función principal para ejecutar tareas asíncronas.\n */\nasync function main() {\n    // Ejecutamos varias tareas asíncronas\n    await ejecutarTarea(\"Tarea 1\", 3); // Tarea 1 dura 3 segundos\n    await ejecutarTarea(\"Tarea 2\", 5); // Tarea 2 dura 5 segundos\n    await ejecutarTarea(\"Tarea 3\", 2); // Tarea 3 dura 2 segundos\n\n    console.log(\"Todas las tareas han finalizado.\");\n}\n\n// Llamamos a la función principal\nmain();"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/javascript/Glitzypanic.js",
    "content": "/*\n * EJERCICIO:\n * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n * asíncrona una función que tardará en finalizar un número concreto de\n * segundos parametrizables. También debes poder asignarle un nombre.\n * La función imprime su nombre, cuándo empieza, el tiempo que durará\n * su ejecución y cuando finaliza.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han\n *   finalizado.\n */\n\n// const cafeFiltrado = async (nombre, segundos) => {\n//   console.log(`Metodo de filtrado: ${nombre}`);\n//   console.log(`Duración: ${segundos} segundos`);\n\n//   const inicio = new Date();\n\n//   await new Promise((resolve) => setTimeout(resolve, segundos * 1000));\n\n//   const termino = new Date();\n\n//   console.log(`Cafe listo con el metodo: ${nombre}`);\n//   console.log(`Tiempo transcurrido: ${(termino - inicio) / 1000} segundos`);\n// };\n\n// cafeFiltrado(\"v60\", 5);\n\n// Ejercicio extra\n\nconst funcionC = async (nombre, segundos) => {\n  console.log(`Nombre: ${nombre}`);\n  console.log(`Duración: ${segundos}`);\n\n  await new Promise((resolve) => setTimeout(resolve, segundos * 1000));\n\n  console.log(`Terminado en: ${segundos}s`);\n};\n\nfuncionC(\"Cafe\", 3);\n\nconst funcionB = async (nombre, segundos) => {\n  console.log(`Nombre: ${nombre}`);\n  console.log(`Duración: ${segundos}`);\n\n  await new Promise((resolve) => setTimeout(resolve, segundos * 1000));\n\n  console.log(`Terminado en: ${segundos}s`);\n};\n\nfuncionB(\"Pastel\", 2);\n\nconst funcionA = async (nombre, segundos) => {\n  console.log(`Nombre: ${nombre}`);\n  console.log(`Duración: ${segundos}`);\n\n  await new Promise((resolve) => setTimeout(resolve, segundos * 1000));\n\n  console.log(`Terminado en: ${segundos}s`);\n};\n\nfuncionA(\"Pan\", 1);\n\nconst funcionD = async (nombre, segundos) => {\n  console.log(`Nombre: ${nombre}`);\n  console.log(`Duración: ${segundos}`);\n\n  await new Promise((resolve) => setTimeout(resolve, segundos * 1000));\n\n  console.log(`Terminado en: ${segundos}s`);\n};\n\nfuncionD(\"mantequilla\", 1);\n\nconst cafeteria = async () => {\n  await Promise.all([funcionC(), funcionB(), funcionA()]);\n\n  await funcionD();\n};\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #15 - JavaScript ->Jesus Antonio Escamilla */\n/**\n * Es uno de los pilares de fundamentales de JavaScript,\n    ya que es un lenguaje de programación de uns sólo sub-proceso\n    o hilo (single thread), lo que significa que solo puede\n    ejecutarse una cosa a la vez\n*/\n\n//---EJERCIÓ---\n// Aquí esta función asíncrona\nasync function asyncFunction(nombre, segundo) {\n    console.log(`Inicia la ejecución de ${nombre}, empieza en ${new Date().toLocaleTimeString()}.`)\n\n    // La forma asíncrona para simular la esperar utilizando SetTimeout\n    await new Promise (res => {\n        setTimeout(res, segundo * 1000);\n    });\n\n    console.log(`Se finaliza la ejecución de ${nombre} en ${segundo / 1000} segundos, finalizo en ${new Date().toLocaleTimeString()}.`);\n}\n\n// Una función muestra para ejecutar la función asíncrona\nasync function muestra() {\n    try {\n        await Promise.all([\n            asyncFunction('Proceso1', 2),\n            asyncFunction('Proceso2', 3)\n        ]);\n    } catch (error) {\n        console.error('Se produjo un error:', error);\n    }\n}\n\n// Se ejecuta el main\nmuestra()\n\n\n\n/**-----DIFICULTAD EXTRA-----*/\n\n//  Ejecución de funciones de A B C D\nasync function main() {\n    //  Se un Try-Catch para evitar errores al ejecutarlos\n    try {\n        //  La funciones a ejecutar\n        await Promise.all([\n            asyncFunction('función C', 3),\n            asyncFunction('función B', 2),\n            asyncFunction('función A', 1),\n        ]);\n\n        //  La muestra la ultima función\n        await asyncFunction('función D', 1);\n    } catch (error) {\n        console.error('Se produjo un error:', error)\n    }\n}\n\n//  La ejecución de la función principal\nmain()\n\n/**-----DIFICULTAD EXTRA-----*/"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/javascript/Larasoft123.js",
    "content": "async function delay(name, seconds) {\n  console.log(`la funcion ${name} empezó el ${new Date().toLocaleTimeString()} y tardará ${seconds} segundos`);\n\n  await new Promise((resolve) => setTimeout(() => {\n    console.log(`la funcion ${name} terminó el ${new Date().toLocaleTimeString()}`);\n    resolve();\n  }, seconds *1000));\n}\n\n\n\ndelay(\"FUNCION 1\",5)\n\n\n\n/*/\nEXTRA\n/*/\n\nawait Promise.all([delay(\"C\", 3),\ndelay(\"B\", 2),\ndelay(\"A\", 1)])\n\ndelay(\"D\", 1)"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/javascript/RaulDoezon.js",
    "content": "/*\n  EJERCICIO:\n  Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n  asíncrona una función que tardará en finalizar un número concreto de\n  segundos parametrizables. También debes poder asignarle un nombre.\n  La función imprime su nombre, cuándo empieza, el tiempo que durará\n  su ejecución y cuando finaliza.\n*/\nfunction currentTime() {\n  const date = new Date();\n\n  return `${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}:${date.getMilliseconds()}`;\n}\n\nfunction asynchronousFunction(functionName, delay){\n  return new Promise((resolve) => {\n    console.log(`${functionName}: Duro ${delay}s. Inicié: ${currentTime()}`);\n\n    setTimeout(() => {\n      console.log(`${functionName}: Finalicé ${currentTime()}`);\n\n      resolve();\n    }, delay * 1000);\n  })\n}\n\nasynchronousFunction(\"Asíncrona\", 1);\n\n/*\n  DIFICULTAD EXTRA (opcional):\n  Utilizando el concepto de asincronía y la función anterior, crea\n  el siguiente programa que ejecuta en este orden:\n  - Una función C que dura 3 segundos.\n  - Una función B que dura 2 segundos.\n  - Una función A que dura 1 segundo.\n  - Una función D que dura 1 segundo.\n  - Las funciones C, B y A se ejecutan en paralelo.\n  - La función D comienza su ejecución cuando las 3 anteriores han\n    finalizado.\n*/\n\nasync function showFunctions() {\n  await Promise.all([asynchronousFunction('C', 3), asynchronousFunction('B', 2), asynchronousFunction('A', 1)]);\n  await asynchronousFunction('D', 1);\n}\n\nshowFunctions()"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/javascript/RicJDev.js",
    "content": "//EJERCICIO\nconst asyncDisplay = (name, seconds) => {\n\tconsole.log(\n\t\t`\\n${name} empezó a ejecutarse\\n(${new Date().toLocaleTimeString()})`\n\t);\n\tconsole.log(`Duración: ${seconds} segundo(s)`);\n\n\treturn new Promise((resolve, reject) => {\n\t\tsetTimeout(() => {\n\t\t\tconsole.log(\n\t\t\t\t`\\n${name} se ha ejecutado\\n(${new Date().toLocaleTimeString()})`\n\t\t\t);\n\t\t\tresolve();\n\t\t}, seconds * 1000);\n\t});\n};\n\nasyncDisplay('Mi función', 8);\n\n//DIFICULTAD EXTRA\nconst runAllFuntions = async () => {\n\tawait Promise.all([\n\t\tasyncDisplay('Función C', 3),\n\t\tasyncDisplay('Función B', 2),\n\t\tasyncDisplay('Función A', 1),\n\t]);\n\n\tawait asyncDisplay('Función D', 1);\n};\n\nrunAllFuntions();\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/javascript/Sac-Corts.js",
    "content": "async function runAsyncTask(taskName, durationInSeconds) {\n    console.log(`${taskName} start.`);\n    console.log(`Duration: ${durationInSeconds} seconds.`);\n\n    const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\n    await wait(durationInSeconds * 1000);\n\n    console.log(`${taskName} ends.`);\n}\n\n//runAsyncTask('Task 1', 3);\n//runAsyncTask('Task 2', 6);\n\n// Extra Exercise //\n\nfunction delay(durationInSeconds, functionName) {\n    return new Promise((resolve) => {\n        setTimeout(() => {\n            console.log(`${functionName} has ended after ${durationInSeconds} seconds.`);\n            resolve();\n        }, durationInSeconds * 1000);\n    });\n}\n\nasync function functionA() {\n    await delay(1, 'Function A');\n}\n\nasync function functionB() {\n    await delay(2, 'Function B');\n}\n\nasync function functionC() {\n    await delay(3, 'Function C');\n}\n\nasync function functionD() {\n    await delay(1, 'Function D');\n}\n\nasync function executeFunctionsInOrder() {\n    await Promise.all([functionC(), functionB(), functionA()]);\n    await functionD();\n}\n\nexecuteFunctionsInOrder();"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/javascript/adrs1166ma.js",
    "content": "/*\n🔥 EJERCICIO:\nUtilizando tu lenguaje, crea un programa capaz de ejecutar de manera\nasíncrona una función que tardará en finalizar un número concreto de\nsegundos parametrizables. También debes poder asignarle un nombre.\nLa función imprime su nombre, cuándo empieza, el tiempo que durará\nsu ejecución y cuando finaliza.\n*/\n// Función asíncrona parametrizable\nfunction ejecutarTarea(nombre, duracion) {\n  console.log(`${nombre} empieza. Durará ${duracion} segundos.`);\n  return new Promise((resolve) => {\n      setTimeout(() => {\n          console.log(`${nombre} ha finalizado.`);\n          resolve();\n      }, duracion * 1000); // Seg a Miliseg\n  });\n}\n\nejecutarTarea(\"Tarea de ejemplo\", 5);\n// Tarea de ejemplo empieza. Durará 5 segundos.\n// Tarea de ejemplo ha finalizado.\n\n/* --------------------------------------------------------------------------------------\n🔥 DIFICULTAD EXTRA (opcional):\nUtilizando el concepto de asincronía y la función anterior, crea\nel siguiente programa que ejecuta en este orden:\n- Una función C que dura 3 segundos.\n- Una función B que dura 2 segundos.\n- Una función A que dura 1 segundo.\n- Una función D que dura 1 segundo.\n- Las funciones C, B y A se ejecutan en paralelo.\n- La función D comienza su ejecución cuando las 3 anteriores han\nfinalizado.\n*/\n\n// Reutilizamos : ejecutarTarea()\nasync function programaPrincipal() {\n  console.log(\"Iniciando programa...\");\n\n  // Ejecutar en paralelo\n  const tareaC = ejecutarTarea(\"Función C\", 3);\n  const tareaB = ejecutarTarea(\"Función B\", 2);\n  const tareaA = ejecutarTarea(\"Función A\", 1);\n\n  // Esperar a que C, B y A terminen\n  await Promise.all([tareaC, tareaB, tareaA]);\n\n  // Ejecutar D después de que C, B y A hayan terminado\n  await ejecutarTarea(\"Función D\", 1);\n\n  console.log(\"Programa finalizado.\");\n}\n\nprogramaPrincipal();\n\n// S A L I D A\n\n// Iniciando programa...\n// Función C empieza. Durará 3 segundos.\n// Función B empieza. Durará 2 segundos.\n// Función A empieza. Durará 1 segundos.\n// Función A ha finalizado.\n// Función B ha finalizado.\n// Función C ha finalizado.\n// Función D empieza. Durará 1 segundos.\n// Función D ha finalizado.\n// Programa finalizado.\n// Tarea de ejemplo ha finalizado."
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/javascript/agusrosero.js",
    "content": "/*\n * EJERCICIO:\n * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n * asíncrona una función que tardará en finalizar un número concreto de\n * segundos parametrizables. También debes poder asignarle un nombre.\n * La función imprime su nombre, cuándo empieza, el tiempo que durará\n * su ejecución y cuando finaliza.\n */\n\nconst asyncFunction = async (name, seconds) => {\n  console.log(`Inicio de la ejecucion ${name}`);\n  console.log(`Duracion de ${name}: ${seconds} segundos..`);\n\n  await new Promise((res) => {\n    setTimeout(res, seconds * 1000);\n  });\n\n  console.log(`Fin de la ejecucion: ${name}`);\n};\n\nconst main = async () => {\n  const promise1 = asyncFunction(\"Funcion 1\", 2);\n\n  await Promise.all([promise1]);\n};\n\n// main();\n\n/* DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han\n *   finalizado.\n */\nconst funcionC = async () => {\n  await setTimeout(() => {\n    console.log(\"función C\");\n  }, 3000);\n};\n\nconst funcionB = async () => {\n  await setTimeout(() => {\n    console.log(\"función B\");\n  }, 2000);\n};\n\nconst funcionA = async () => {\n  await setTimeout(() => {\n    console.log(\"función A\");\n  }, 1000);\n};\n\nconst funcionD = async () => {\n  await setTimeout(() => {\n    console.log(\"función D\");\n  }, 1000);\n};\n\nconst main2 = async () => {\n  const res1 = funcionC();\n  const res2 = funcionB();\n  const res3 = funcionA();\n\n  await Promise.all([res1, res2, res3]);\n\n  const res4 = await funcionD();\n};\n\nmain2;\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/javascript/bernatcs.js",
    "content": "// ** EJERCICIO\n\nfunction funcionAsincrona(seg){\n    console.log(`Esta función se llama ${funcionAsincrona.name} y acaba de empezar.\\nLa función va a durar ${seg} segundos`)\n\n    setTimeout(function() {\n        console.log('La función ya ha terminado')\n    }, seg*1000);\n}\n\n// funcionAsincrona(3)\n\n// ** DIFICULTAD EXTRA ** -------------------------------------------------------------------------------------------------------------------------------------------------\n\nfunction funcA() {\n    setTimeout(() => {\n        console.log('Ha acabado la función A')\n    }, 1000)\n}\n\nfunction funcB() {\n    setTimeout(() => {\n        console.log('Ha acabado la función B')\n    }, 2000)\n}\n\nfunction funcC() {\n    return new Promise((resolve, reject) => {\n        setTimeout(() => {\n            console.log('Ha acabado la función C')\n            resolve()\n        }, 3000)\n    })\n}\n\nfunction funcD() {\n    setTimeout(() => {\n        console.log('Ha acabado la función D')\n    }, 1000)\n}\n\nfuncA()\nfuncB()\nfuncC()\n    .then(() => funcD())\n\n\n// -----------\n\nfunction funcA2() {\n    return new Promise((resolve, reject) => {\n        setTimeout(() => {\n            console.log('Ha acabado la función A2');\n            resolve();\n        }, 1000);\n    });\n}\n\nfunction funcB2() {\n    return new Promise((resolve, reject) => {\n        setTimeout(() => {\n            console.log('Ha acabado la función B2');\n            resolve();\n        }, 2000);\n    });\n}\n\nfunction funcC2() {\n    return new Promise((resolve, reject) => {\n        setTimeout(() => {\n            console.log('Ha acabado la función C2');\n            resolve();\n        }, 3000);\n    });\n}\n\nfunction funcD2() {\n    return new Promise((resolve, reject) => {\n        setTimeout(() => {\n            console.log('Ha acabado la función D2');\n            resolve();\n        }, 1000);\n    });\n}\n\nasync function ejecutarEnOrden() {\n    await Promise.all([funcA2(), funcB2(), funcC2()]);\n    await funcD2();\n}\n\nejecutarEnOrden();"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/javascript/caterinarodriguezdev.js",
    "content": "/*\n * EJERCICIO:\n * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n * asíncrona una función que tardará en finalizar un número concreto de\n * segundos parametrizables. También debes poder asignarle un nombre.\n * La función imprime su nombre, cuándo empieza, el tiempo que durará\n * su ejecución y cuando finaliza.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han finalizado.\n */\n\nconst miFunc = async (time, nombre) => {\n  console.log(\"Soy la función \", nombre);\n\n  await new Promise((resolve) =>\n    setTimeout(() => {\n      console.log(`Me he ejecutado después de ${time} segundos`);\n      console.log(`Ejecución finalizada`);\n      resolve();\n    }, time * 1000)\n  );\n};\n\nconst ejecucionParalela = async () => {\n\n    await miFunc(3, \"C\");\n    await miFunc(2, \"B\");\n    await miFunc(1, \"A\");\n    miFunc(1, \"D\");\n};\n\nejecucionParalela();"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/javascript/cesar-ch.js",
    "content": "/*\n    * #15 ASINCRONÍA\n*/\n\nfunction funcionAsincrona(nombre, tiempo) {\n    return new Promise((resolve, reject) => {\n        if (isNaN(tiempo) || tiempo <= 0) {\n            reject(new Error('El parámetro \"tiempo\" debe ser un número positivo'));\n            return;\n        }\n\n        console.log(`Iniciando función \"${nombre}\"...`);\n        console.log(`Duración: ${tiempo} segundos`);\n\n        const tiempoInicio = Date.now();\n\n        setTimeout(() => {\n            console.log(`Función \"${nombre}\" finalizada`);\n            console.log(`Tiempo total de ejecución: ${Date.now() - tiempoInicio} milisegundos`);\n            resolve();\n        }, tiempo * 1000);\n    });\n}\n\n/*\n    *  DIFICULTAD EXTRA\n*/\n\nasync function ejecutarFunciones() {\n    const functionA = () => funcionAsincrona(\"A\", 3)\n    const functionB = () => funcionAsincrona(\"B \", 2)\n    const functionC = () => funcionAsincrona(\"C\", 1)\n    const functionD = () => funcionAsincrona(\"D\", 1)\n\n    await Promise.all([functionA(), functionB(), functionC()]);\n    await functionD();\n}\n\nejecutarFunciones();\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/javascript/christian-jfr.js",
    "content": "// #15 ASINCRONÍA\n\n/**\n * EJERCICIO:\n * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n * asíncrona una función que tardará en finalizar un número concreto de\n * segundos parametrizables. También debes poder asignarle un nombre.\n * La función imprime su nombre, cuándo empieza, el tiempo que durará\n * su ejecución y cuando finaliza.\n */\n\nasync function asyncTask(name, seconds) {\n\tconsole.log(\n\t\t`starting ${name}, at: ${new Date().toLocaleTimeString()}, duration: ${seconds} seconds`\n\t);\n\n\tawait new Promise((resolve) => {\n\t\tsetTimeout(() => {\n\t\t\tlet end = `finished ${name}, at: ${new Date().toLocaleTimeString()}`;\n\t\t\tresolve(end);\n\t\t\tconsole.log(end);\n\t\t}, seconds * 1000);\n\t});\n}\n\nasyncTask('test-1', 5);\n\n/**\n * DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han\n *   finalizado.\n */\n\nasync function extra() {\n\tawait Promise.all([asyncTask('C', 3), asyncTask('B', 2), asyncTask('A', 1)]);\n\tawait asyncTask('D', 1);\n}\n\nextra();\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/javascript/duendeintemporal.js",
    "content": "//#15 ASINCRONÍA \n\n// short for console.log()\nlet log = console.log;\n\nwindow.addEventListener('load', ()=>{\n    const body = document.querySelector('body');\n    const title = document.createElement('h1');\n    \n    body.style.setProperty('background', '#000');\n    body.style.setProperty('text-align', 'center');\n    \n    title.textContent = 'Retosparaprogramadores #15.';\n    title.style.setProperty('font-size', '3.5vmax');\n    title.style.setProperty('color', '#fff');\n    title.style.setProperty('line-height', '100vh');\n    \n    body.appendChild(title);\n    \n    setTimeout(()=>{\n    alert('Retosparaprogramadores #15. Please open the Browser Developer Tools.');\n    }, 2000);\n    log( 'Retosparaprogramadores #15'); \n});\n\n\nfunction runFunc(name, seconds) {\n    return new Promise((resolve) => {\n        log(`${name} - Start at: ${new Date().toLocaleTimeString()}`);\n        log(`${name} - Last: ${seconds} seconds`);\n\n        setTimeout(() => {\n            log(`${name} - Ends at: ${new Date().toLocaleTimeString()}`);\n            resolve();\n        }, seconds * 1000);\n    });\n}\n\nasync function runFunces() {\n    const functionC = runFunc('Function C', 3);\n    const functionB = runFunc('Function B', 2);\n    const functionA = runFunc('Function A', 1);\n\n    await Promise.all([functionC, functionB, functionA]);\n\n    await runFunc('Function D', 1);\n}\n\nrunFunces();\n/* Logs: \n         Function C - Start at: 13:01:18\n         Function C - Last: 3 seconds\n         Function B - Start at: 13:01:18\n         Function B - Last: 2 seconds\n         Function A - Start at: 13:01:18\n         Function A - Last: 1 seconds\n         Function A - Ends at: 13:01:19\n         Function B - Ends at: 13:01:20\n         Function C - Ends at: 13:01:21\n         Function D - Start at: 13:01:21\n         Function D - Last: 1 seconds\n         Function D - Ends at: 13:01:22\n*/"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/javascript/emedevelopa.js",
    "content": "/* EJERCICIO:\n * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n * asíncrona una función que tardará en finalizar un número concreto de\n * segundos parametrizables. También debes poder asignarle un nombre.\n * La función imprime su nombre, cuándo empieza, el tiempo que durará\n * su ejecución y cuando finaliza.*/\n\nfunction asincrona (nombre, segundos) {\n    console.log(`${nombre} comienza.`);\n    console.log(`${nombre} empezó a las ${new Date().toLocaleTimeString()}.`);\n    return new Promise((resolve, reject) => {\n        setTimeout(() => {\n            console.log(`${nombre} ha finalizado después de ${segundos} segundos.`);\n            console.log(`${nombre} terminó a las ${new Date().toLocaleTimeString()}.`);\n            resolve();\n        }, segundos * 1000);\n    });\n}\nasincrona(\"El programa\",13);\n\n//EXTRA\n/*Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n* - Una función C que dura 3 segundos.\n* - Una función B que dura 2 segundos.\n* - Una función A que dura 1 segundo.\n* - Una función D que dura 1 segundo.\n* - Las funciones C, B y A se ejecutan en paralelo.\n* - La función D comienza su ejecución cuando las 3 anteriores han finalizado.*/\n\nasync function programa() {\n    try {\n        await Promise.all([\n            asincrona(\"Función C\", 3),\n            asincrona(\"Función B\", 2),\n            asincrona(\"Función A\", 1)\n        ]);\n        await asincrona(\"Función D\", 1);\n    } catch (error) {\n        console.log(\"Se produjo un error:\", error);\n    }\n}\n\nprograma();"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/javascript/eugeniasoria.js",
    "content": "/*\r\n * EJERCICIO:\r\n * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\r\n * asíncrona una función que tardará en finalizar un número concreto de\r\n * segundos parametrizables. También debes poder asignarle un nombre.\r\n * La función imprime su nombre, cuándo empieza, el tiempo que durará\r\n * su ejecución y cuando finaliza.\r\n *\r\n * DIFICULTAD EXTRA (opcional):\r\n * Utilizando el concepto de asincronía y la función anterior, crea\r\n * el siguiente programa que ejecuta en este orden:\r\n * - Una función C que dura 3 segundos.\r\n * - Una función B que dura 2 segundos.\r\n * - Una función A que dura 1 segundo.\r\n * - Una función D que dura 1 segundo.\r\n * - Las funciones C, B y A se ejecutan en paralelo.\r\n * - La función D comienza su ejecución cuando las 3 anteriores han\r\n *   finalizado.\r\n */\r\n\r\nasync function demorarAPedido(demora, nombre) {\r\n  return new Promise((resolve, reject) => {\r\n    let inicio = Date.now()\r\n    if (demora < 0) {\r\n      reject('El valor para demora debe ser mayor que cero');\r\n    } else {\r\n      setTimeout(() => { \r\n        let ahora = Date.now();\r\n        let message = `Inicio: ${inicio} /Demora en milis:${ahora - inicio}/ ${Date.now()}: Finalizado ${nombre} (${demora})`;\r\n        resolve(message); \r\n        console.log(message);\r\n      }, demora)\r\n    }\r\n  })\r\n  \r\n}\r\n\r\n\r\nasync function main() {\r\n  await Promise.all([demorarAPedido (3000, 'C'), demorarAPedido (2000, 'B'), demorarAPedido (1000, 'A')])\r\n  .then((data) => { })  \r\n  .catch((err) => {\r\n    console.log(err);\r\n })\r\n console.log('por ejecutar D')\r\n let D = await demorarAPedido (1000, 'D');\r\n}\r\n    \r\nmain()\r\n.catch(error => console.error('Error: ', error));\r\n\r\n\r\n\r\n\r\n\r\n\r\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/javascript/eulogioep.js",
    "content": "/**\n * Función asíncrona que simula una tarea que tarda un tiempo específico\n * @param {string} nombre - Nombre de la tarea\n * @param {number} segundos - Duración de la tarea en segundos\n * @returns {Promise} Una promesa que se resuelve cuando la tarea termina\n */\nfunction ejecutarTareaAsincrona(nombre, segundos) {\n    return new Promise(resolve => {\n        console.log(`${nombre} - Iniciando...`);\n        console.log(`${nombre} - Durará ${segundos} segundos`);\n        \n        setTimeout(() => {\n            console.log(`${nombre} - Finalizada`);\n            resolve();\n        }, segundos * 1000);\n    });\n}\n\n/**\n * Demostración básica de una tarea asíncrona\n */\nasync function demostracionBasica() {\n    console.log(\"=== Demostración Básica ===\");\n    await ejecutarTareaAsincrona(\"TareaEjemplo\", 2);\n}\n\n/**\n * Implementación de la dificultad extra\n * Ejecuta las tareas C, B y A en paralelo y luego D cuando las anteriores terminan\n */\nasync function dificultadExtra() {\n    console.log(\"\\n=== Dificultad Extra ===\");\n    \n    // Ejecutar tareas C, B y A en paralelo\n    const tareaC = ejecutarTareaAsincrona(\"Tarea C\", 3);\n    const tareaB = ejecutarTareaAsincrona(\"Tarea B\", 2);\n    const tareaA = ejecutarTareaAsincrona(\"Tarea A\", 1);\n    \n    // Esperar a que todas las tareas terminen\n    await Promise.all([tareaC, tareaB, tareaA]);\n    \n    // Ejecutar tarea D después de que las otras hayan terminado\n    await ejecutarTareaAsincrona(\"Tarea D\", 1);\n}\n\n/**\n * Función principal que ejecuta todas las demostraciones\n */\nasync function main() {\n    await demostracionBasica();\n    await dificultadExtra();\n}\n\n// Ejecutar el programa\nmain().catch(error => console.error('Error:', error));"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/javascript/garos01.js",
    "content": "function ejecutarFuncion(nombre, segundos) {\n  console.log(`Función \"${nombre}\" empezando...`);\n\n  return new Promise((resolve, reject) => {\n    setTimeout(() => {\n      console.log(\n        `Función \"${nombre}\" finalizada después de ${segundos} segundos.`\n      );\n      resolve();\n    }, segundos * 1000);\n  });\n}\n\nasync function ejecucionAsincrona() {\n  try {\n    await ejecutarFuncion(\"Función 1\", 3);\n    await ejecutarFuncion(\"Función 2\", 2);\n    await ejecutarFuncion(\"Función 3\", 4);\n  } catch (error) {\n    console.error(\"Ocurrió un error:\", error);\n  }\n}\n\nejecucionAsincrona();\n\n// Ejercicio extra\n\nasync function ejecutarFuncion(nombre, segundos) {\n  console.log(`Función \"${nombre}\" empezando...`);\n\n  return new Promise((resolve, reject) => {\n    setTimeout(() => {\n      console.log(\n        `Función \"${nombre}\" finalizada después de ${segundos} segundos.`\n      );\n      resolve();\n    }, segundos * 1000);\n  });\n}\n\nasync function funcionA() {\n  console.log(\"Función A empezando...\");\n  await ejecutarFuncion(\"Función A\", 1);\n}\n\nasync function funcionB() {\n  console.log(\"Función B empezando...\");\n  await ejecutarFuncion(\"Función B\", 2);\n}\n\nasync function funcionC() {\n  console.log(\"Función C empezando...\");\n  await ejecutarFuncion(\"Función C\", 3);\n}\n\nasync function funcionD() {\n  await Promise.all([funcionA(), funcionB(), funcionC()]);\n  console.log(\"Función D empezando...\");\n  await ejecutarFuncion(\"Función D\", 1);\n}\n\nasync function main() {\n  await funcionD();\n}\n\nmain();\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/javascript/giovanyosorio.js",
    "content": "/*\n * EJERCICIO:\n * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n * asíncrona una función que tardará en finalizar un número concreto de\n * segundos parametrizables. También debes poder asignarle un nombre.\n * La función imprime su nombre, cuándo empieza, el tiempo que durará\n * su ejecución y cuando finaliza.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han\n *   finalizado.\n */\n\nfunction resolve(name,time) {\n    return new Promise((resolve) => {\n      setTimeout(() => {\n        resolve('resolved');\n      }, time);\n    });\n  }\n  \n  async function asyncCall(name,time) {\n    console.log(`calling my first function ${name} in ${time/1000} segundos`);\n    const result = await resolve(name,time);\n    console.log(result);\n    // Expected output: \"resolved\"\n  }\n  \n  asyncCall(\"myfunction\",4000);\n  \n\n  function sleep(duration) {\n    return new Promise(resolve => setTimeout(resolve, duration));\n  }  \n  async function A(){\n    await sleep(1000)\n    console.log('Función A completada (1 segundo)');\n  }\n\n  async function B(){\n    await sleep(2000)\n    console.log('Función B completada (2 segundo)');\n  }\n  async function C(){\n    await sleep(3000)\n    console.log('Función C completada (3 segundo)');\n  }\n  async function D(){\n    await sleep(1000)\n    console.log('Función D completada (1 segundo)');\n  }\n\n  async function execute(){\n    console.log('Iniciando funciones A, B y C en paralelo');\n    await Promise.all([A(),B(),C()])\n    console.log(\"han finalizado las tres funciones en paralelo\")\n    await D()\n\n    console.log('Función D ha finalizado');\n\n  }\n\n  execute();"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/javascript/hectorio23.js",
    "content": "const { performance } = require('perf_hooks');\n\nfunction customTask(name, duration) {\n    return new Promise(resolve => {\n        setTimeout(() => {\n            console.log(`Ending [ ${name} ] at ${new Date().toLocaleTimeString()}`);\n            resolve();\n        }, duration * 1000);\n    });\n}\n\nclass Task {\n    constructor(name, duration = 0) {\n        this.name = name;\n        this.duration = duration;\n    }\n\n    async run() {\n        await customTask(this.name, this.duration);\n    }\n}\n\n// Ejercicio principal\nasync function main() {\n    // Asincronía estilo \"JavaScript\"\n    const t1 = new Task(\"custom\", 2);\n\n    const C = new Task(\"C\", 3);\n    const B = new Task(\"B\", 2);\n    const A = new Task(\"A\", 1);\n    const D = new Task(\"D\", 1);\n\n    console.log(\"************** EJERCICIO **********\\n\");\n    console.log(\"La función *custom* tardará 2 segundos en ejecutarse\");\n    console.log(`Starting [ ${t1.name} ] at ${new Date().toLocaleTimeString()}`);\n    await t1.run();\n\n    console.log(\"\\n************** EJERCICIO EXTRA **********\\n\");\n\n    // Ejecución concurrente de C, B y A\n    const promises = [C.run(), B.run(), A.run()];\n    \n    console.log(`Starting tasks [ C, B, A ] at ${new Date().toLocaleTimeString()}`);\n\n    await Promise.all(promises);\n\n    console.log(`\\nStarting task [ ${D.name} ] at ${new Date().toLocaleTimeString()}`);\n    await D.run();\n}\n\nmain();\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n_______________________________________\n#15 ASINCRONÍA\n---------------------------------------\n * EJERCICIO:\n * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n * asíncrona una función que tardará en finalizar un número concreto de\n * segundos parametrizables. También debes poder asignarle un nombre.\n * La función imprime su nombre, cuándo empieza, el tiempo que durará\n * su ejecución y cuando finaliza.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han\n *   finalizado.\n*/\n// ________________________________________________________\n\nasync function process(name, time) {\n    console.log(`- Iniciar función: ${name} -> Duración: ${time}s`);\n    await new Promise(resolve => setTimeout(resolve, time * 1000));\n    console.log(`* Función ${name} finaliza.`);\n}\n\nasync function test() {\n    await Promise.all([\n        process(\"Test 2\", 4),\n        process(\"Test 1\", 2)\n    ]);\n}\n\n// ________________________________________________________\n// DIFICULTAD EXTRA\n\nasync function in_parallel() {\n    await Promise.all([\n        process(\"C\", 3),\n        process(\"B\", 2),\n        process(\"A\", 1)\n    ]);\n}\n\nasync function main() {\n    await test();\n    await in_parallel();\n    await process(\"D\", 1); \n}\n\nmain();\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/javascript/miguelex.js",
    "content": "function asyncTask(name, seconds) {\n    return new Promise((resolve, reject) => {\n        console.log(`Comienza la función ${name}. Duración de ${seconds} segundos. Hora de comienzo ${new Date().toLocaleTimeString()}`);\n        setTimeout(() => {\n            console.log(`Finaliza la función ${name}. Hora de finalización ${new Date().toLocaleTimeString()}`);\n            resolve();\n        }, seconds * 1000);\n    });\n}\n\nasync function extra() {\n    await Promise.all([\n        asyncTask(\"C\", 3),\n        asyncTask(\"B\", 2),\n        asyncTask(\"A\", 1)\n    ]);\n    await asyncTask(\"D\", 1);\n}\n\nasyncTask(\"Test 1\", 5)\n    .then(() => extra())\n    .catch(error => console.error(error));\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/javascript/monicavaquerano.js",
    "content": "// 15 ASINCRONÍA\n// Monica Vaquerano\n//  https://monicavaquerano.dev\n\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n * asíncrona una función que tardará en finalizar un número concreto de\n * segundos parametrizables. También debes poder asignarle un nombre.\n * La función imprime su nombre, cuándo empieza, el tiempo que durará\n * su ejecución y cuando finaliza.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han\n *   finalizado.\n */\n\nasync function asincrona() {\n    let inicio = new Date();\n    console.log(`starts at ${inicio.toString()}`)\n\n    console.log(\"Soy una ...\\n\")\n\n    await new Promise((resolve) => {\n        setTimeout(resolve, 5000);\n    });\n\n    console.log(\"\\n... función asíncrona!\")\n\n    let final = new Date();\n    let seconds = (final.getTime() - inicio.getTime()) / 1000\n\n    console.log(`ends at ${final.toString()}`)\n    console.log(`\\nLa función se demoró ${seconds.toFixed(2)} segundos.\\n`)\n\n}\n\nasincrona();\n\nasync function tarea(nombre = \"default\", segundos = 1) {\n    let inicio = new Date();\n\n    console.log(`\\tNombre: ${nombre} Comienzo: ${inicio.toString()} Duración: ${segundos} segundo(s).`)\n\n    await new Promise((resolve) => {\n        setTimeout(resolve, segundos * 1000);\n    });\n\n    let final = new Date();\n    console.log(`\\t... Nombre: ${nombre} Final: ${final.toString()}.`)\n\n\n    let seconds = (final.getTime() - inicio.getTime()) / 1000\n\n    console.log(`\\t\\tLa función se demoró ${seconds.toFixed(2)} segundos.\\n`)\n\n}\n\ntarea(\"Prueba\", 1);\n\n\n// #  * DIFICULTAD EXTRA (opcional):\n// #  * Utilizando el concepto de asincronía y la función anterior, crea\n// #  * el siguiente programa que ejecuta en este orden:\n// #  * - Una función C que dura 3 segundos.\n// #  * - Una función B que dura 2 segundos.\n// #  * - Una función A que dura 1 segundo.\n// #  * - Una función D que dura 1 segundo.\n// #  * - Las funciones C, B y A se ejecutan en paralelo.\n// #  * - La función D comienza su ejecución cuando las 3 anteriores han\n// #  *   finalizado.\n\nasync function tareas() {\n    await Promise.all([tarea(\"A\", 1), tarea(\"B\", 2), tarea(\"C\", 3)])\n    await tarea(\"D\", 1);\n}\n\ntareas();\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/javascript/nlarrea.js",
    "content": "/*\n * EJERCICIO:\n * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n * asíncrona una función que tardará en finalizar un número concreto de\n * segundos parametrizables. También debes poder asignarle un nombre.\n * La función imprime su nombre, cuándo empieza, el tiempo que durará\n * su ejecución y cuando finaliza.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han\n *   finalizado.\n*/\n\n\nfunction print_parameters(seconds, name) {\n    console.log(\n        `Task: ${name}\\nTime: ${seconds}\\nStart: ${new Date().toLocaleTimeString()}\\n`\n    );\n    \n    return new Promise((resolve) => {\n        setTimeout(() => {\n            console.log(`Task: ${name}\\nEnd: ${new Date().toLocaleTimeString()}\\n`);\n            resolve();\n        }, seconds * 1000);\n    });\n}\n\n\nasync function main() {\n    await Promise.all([\n        print_parameters(5, \"task 1\"),\n        print_parameters(8, \"task 2\"),\n        print_parameters(1, \"task 3\"),\n        print_parameters(15, \"task 4\"),\n    ])\n}\n\n\nmain();\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han\n *   finalizado.\n*/\n\n\nasync function run() {\n    const tasks = [\n        print_parameters(3, \"C\"),\n        print_parameters(2, \"B\"),\n        print_parameters(1, \"A\"),\n    ];\n    await Promise.all(tasks);\n\n    await print_parameters(1, \"D\");\n}\n\nrun()"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/javascript/parababire.js",
    "content": "function inicio() {\n  return new Date().toLocaleTimeString();\n}\n\nfunction task(name, timer) {\n  const seg = timer / 1000;\n  console.log(`Tarea: ${name}, Duración: ${seg}seg, Inicio: ${inicio()}`);\n  return new Promise((resolve) => {\n    setTimeout(() => {\n      resolve(`Tarea: ${name}, Fin: ${inicio()}`);\n    }, timer);\n  });\n}\n\nfunction manejoDePromesa(resultado) {\n  return console.log(resultado);\n}\n\n//Extra\n\nasync function esperaTask() {\n  await Promise.all([task('C', 3000).then(manejoDePromesa), task('B', 2000).then(manejoDePromesa), task('A', 1000).then(manejoDePromesa)]);\n  await task('D', 1000).then(manejoDePromesa);\n}\n\nesperaTask();"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/javascript/pedamoci.js",
    "content": "function esperar2segundos(resolve) {\n  console.log('esperar2segundos, la funcón tardara en ejecutarse 2 segundos')\n  return new Promise(() => {\n    setTimeout(() => {\n      console.log('esperar2segundos: He finalizado mi ejecución')\n      resolve()\n    }, 2000)\n  })\n}\n\nasync function asincrona() {\n  await esperar2segundos()\n}\n\nasincrona()\n\n// ------------------------------------ DIFICULTAD EXTRA ------------------------------------\nfunction C() {\n  console.log('La función \"C\" ha empezado su ejecución')\n  return new Promise(resolve => {\n    setTimeout(() => {\n      resolve()\n      console.log('La función \"C\" ha finalizado su ejecución')\n    }, 3000)\n  })\n}\n\nfunction B() {\n  console.log('La función \"B\" ha empezado su ejecución')\n  return new Promise(resolve => {\n    setTimeout(() => {\n      resolve()\n      console.log('La función \"B\" ha finalizado su ejecución')\n    }, 2000)\n  })\n}\n\nfunction A() {\n  console.log('La función \"A\" ha empezado su ejecución')\n  return new Promise(resolve => {\n    setTimeout(() => {\n      resolve()\n      console.log('La función \"A\" ha finalizado su ejecución')\n    }, 1000)\n  })\n}\n\nfunction D() {\n  console.log('La función \"D\" ha empezado su ejecución')\n  return new Promise(resolve => {\n    setTimeout(() => {\n      resolve()\n      console.log('La función \"D\" ha finalizado su ejecución')\n    }, 1000)\n  })\n}\n\nasync function program() {\n  await Promise.all([C(),B(),A()])\n  await D()\n}\n\nprogram()"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/javascript/raulG91.js",
    "content": "\nasync function asyncfunction(seconds,name){\n    console.log(`Starting async function: ${name}` );\n    return new Promise(resolve => setTimeout(function(){\n                                console.log(`Ending async function: ${name}`);\n                                 resolve()}, 1000*seconds));\n    \n}\n\nasyncfunction(2,\"Function\");\n\n/*Extra */ \n\nasync function executePromises(){\n\n    await Promise.all([asyncfunction(3,\"C\"),asyncfunction(2,\"B\"),asyncfunction(1,\"A\")]);\n    await asyncfunction(1,\"D\")\n}\n\nexecutePromises()"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/javascript/victor-Casta.js",
    "content": "/*\n * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n * asíncrona una función que tardará en finalizar un número concreto de\n * segundos parametrizables. También debes poder asignarle un nombre.\n * La función imprime su nombre, cuándo empieza, el tiempo que durará\n * su ejecución y cuando finaliza.\n*/\n\nfunction time(nameTime, duration) {\n  return new Promise((resolve) => {\n    const startTime = new Date().toLocaleTimeString();\n    console.log(`Function Name: ${nameTime}`);\n    console.log(`Start Time: ${startTime}`);\n    console.log(`Duration: ${duration / 1000} seconds`);\n    setTimeout(() => {\n      const endTime = new Date().toLocaleTimeString();\n      console.log(`${nameTime} End Time: ${endTime}`);\n      resolve();\n    }, duration);\n  });\n}\n\n/*\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han\n *   finalizado.\n*/\n\nasync function main() {\n  const c = time('C', 3000);\n  const b = time('B', 2000);\n  const a = time('A', 1000);\n\n  await Promise.all([c, b, a]);\n  await time('D', 1000);\n}\n\nmain();\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/javascript/wapastorv.js",
    "content": "/* EJERCICIO:\n * Utilizando Javascript, para crear un programa capaz de ejecutar de manera\n * asíncrona una función que tardará en finalizar un número concreto de\n * segundos parametrizables. También debes poder asignarle un nombre.\n * La función imprime su nombre, cuándo empieza, el tiempo que durará\n * su ejecución y cuando finaliza.\n */\nfunction asyncFunction(name, seconds) {\n    console.log(`Starting ${name}`);\n    setTimeout(() => {\n        console.log(`Finishing ${name}`);\n    }, seconds * 1000);\n}\n\nasyncFunction('First', 3);\nasyncFunction('Second', 1);\nasyncFunction('Third', 5);\n\n/* DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han\n *   finalizado.\n */\nfunction asyncFunction(name, seconds) {\n    // Tu código aquí\n\n    console.log(`Starting ${name}`); // Esta línea no se puede modificar\n    setTimeout(() => {              // Esta línea no se puede modificar \n        console.log(`Finishing ${name}`);\n    }, seconds * 1000);\n}\n\n// Tu código aquí\n\nasyncFunction('C', 3);\nasyncFunction('B', 2);\nasyncFunction('A', 1);\nasyncFunction('D', 1);\n// Fin de tu código\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/kotlin/blackriper.kt",
    "content": "import kotlinx.coroutines.async\r\nimport kotlinx.coroutines.delay\r\nimport kotlinx.coroutines.launch\r\nimport kotlinx.coroutines.runBlocking\r\nimport kotlin.system.measureTimeMillis\r\nimport kotlin.time.measureTime\r\n\r\n/*\r\nLa asincronia es una forma de  ejecutar una o mas tareas en segundo plano algunas formas de la\r\nmisma siguen dependiendo del hilo principal en el que se ejecute.Los principales conceptos  al ejecutar\r\ntareas en paralelo son.\r\n\r\nAsincronia: Tarea no bloqueante que puede seguir ejecutando el hilo principal aunque la tarea\r\nque este en segundo plano no se ha completado.\r\n\r\nConcurrencia: Tarea no bloqueante que acomparacion dela anterior no tiene un orden de ejecucion\r\nde las tareas. sigue dependendo del hilo principal en el que se ejecute.\r\n\r\nParalelismo: Tarea que se puede ejecutar en paralelo de forma simultanea y no depende del hilo principal\r\n\r\nEn kotlin hay diferentes tecnicas para la ejecucion de tareas en segundo plano.\r\n\r\n-Thereading (hilo de ejecucion) un hilo\r\n-Callback (llamada de retorno) una llamada de retorno\r\n-Futures , promises\r\n-Reactive extensions\r\n-Coroutines\r\n\r\npara este erjercicio usaremos la libreria coroutines para la ejecucion de tareas en segundo plano\r\nya que es la mas utilizada.\r\n\r\npara mas informacion ver la documentacion de coroutines en\r\nhttps://github.com/Kotlin/kotlinx.coroutines\r\nhttps://kotlinlang.org/docs/coroutines-basics.html\r\n\r\nmeasureTime: sirve para medir el tiempo de ejecucion de una tarea\r\n\r\ndentro de corutines existen las que se corren de mode concurrente con la palabra launch y async\r\nlo cual lo hace de forma asincrona  esta forma es parecida a como lo hacen lenguajes como rust o\r\ntypescript\r\n\r\n*/\r\n\r\n\r\nsuspend  fun runTask(nameTask:String,duration:Long){\r\n    val time= measureTimeMillis {\r\n        println(\"starting $nameTask\")\r\n        delay(duration)\r\n        println(\"finishing $nameTask\")\r\n    }\r\n    println(\"task $nameTask took $time.ms\")\r\n}\r\n\r\n\r\n\r\nfun main() = runBlocking {\r\n    runTask(\"Example\", 1000L)\r\n\r\n    // reto extra\r\n    val taskA = async { runTask(\"Task A\", 1000L) }\r\n    val taskB = async { runTask(\"Task B\", 2000L) }\r\n    val taskC = async { runTask(\"Task C\", 3000L) }\r\n    val taskD = async { runTask(\"Task D\", 1000L) }\r\n\r\n    taskA.await()\r\n    taskB.await()\r\n    taskC.await()\r\n    if (taskA.isCompleted && taskB.isCompleted && taskC.isCompleted) taskD.await()\r\n}"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/kotlin/eulogioep.kt",
    "content": "import kotlinx.coroutines.*\nimport java.time.LocalTime\nimport java.time.format.DateTimeFormatter\n\nsuspend fun asyncFunction(name: String, duration: Int) {\n    val formatter = DateTimeFormatter.ofPattern(\"HH:mm:ss\")\n    \n    println(\"$name: Iniciando en ${LocalTime.now().format(formatter)}\")\n    println(\"$name: Duración de $duration segundos\")\n    \n    delay(duration * 1000L)\n    \n    println(\"$name: Finalizando en ${LocalTime.now().format(formatter)}\")\n}\n\nsuspend fun main() = coroutineScope {\n    // Parte básica del ejercicio\n    launch { asyncFunction(\"Función de ejemplo\", 5) }\n    \n    // Parte extra del ejercicio\n    val jobC = launch { asyncFunction(\"Función C\", 3) }\n    val jobB = launch { asyncFunction(\"Función B\", 2) }\n    val jobA = launch { asyncFunction(\"Función A\", 1) }\n    \n    // Esperamos a que las funciones A, B y C terminen\n    jobC.join()\n    jobB.join()\n    jobA.join()\n    \n    // Ejecutamos la función D después de que A, B y C hayan terminado\n    asyncFunction(\"Función D\", 1)\n}"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/nasm/evanz2608.s",
    "content": "; https://nasm.us\n\n; ================================================\n; 15 - ASINCRONÍA\n; ================================================\n;\n; Tal vez el ejercicio más difícil hasta el momento.\n; En ensamblador, debemos de crear un thread cada vez que querramos correr código de manera\n; asíncrona, y para eso usaré la syscall \"fork\".\n; A diferencia de otros lenguajes, cada vez que creamos un thread con fork, se crea una cópia del proceso, y el thread continuará su ejecución\n; en la instrucción siguiente al syscall.\n; Por suerte, podemos diferenciar si estamos en el proceso padre, o en un proceso hijo gracias a que la llamada a fork,\n; devuelve en RAX: 0 en el proceso hijo (thread ó child), y el PID del thread en el proceso padre,\n; con lo que comprobando RAX, podemos saltar a una parte u ótra del código.\n; Otra cuestión a tener en cuenta, es que el proceso padre va a finalizar independiente a si el thread terminó o no su ejecución, con lo que\n; deberemos de indicarle al proceso padre que \"espere\" a que todos los threads creados finalizen antes de terminar.\n\n\nSYS_write equ 1\nSYS_nanosleep equ 35\nSYS_fork equ 57\nSYS_exit equ 60\nSYS_wait4 equ 61\nSYS_time equ 201\nSYS_clock_gettime equ 228\nSYS_waitid equ 247\nSTDIN equ 0\nSTDOUT equ 1\nSTDERR equ 2\n\n%define WNOHANG 1\n%define WEXITED 4\n%define OPTIONS WNOHANG | WEXITED\n%define get_month(index) [months + index]\n\nglobal _start\nextern printf\nsection .text\n\n_start:\n  mov rax, SYS_fork\n  syscall\n  cmp rax, 0\n  je call_task\n\n\n  mov rax, SYS_fork\n  syscall\n  cmp rax, 0\n  je funcA\n  mov rax, SYS_fork\n  syscall\n  cmp rax, 0\n  je funcB\n  mov rax, SYS_fork\n  syscall\n  cmp rax, 0\n  je funcC\n  \n.loop:\n  xor r8, r8\n  mov r10, OPTIONS\n  xor rdx, rdx\n  xor rsi, rsi\n  xor rdi, rdi\n  mov rax, SYS_waitid\n  syscall\n  cmp rax, 0\n  je .loop\n  jmp funcD\n\n_exit:\n  mov rax, SYS_exit\n  xor rdi, rdi\n  syscall\n\n\nfuncA:\n  lea rdi, [mask2_start]\n  lea rsi, [funcA_name]\n  mov rdx, 1\n  call printf\n  mov qword [timer + ts.tv_sec], 1\n  mov rax, SYS_nanosleep\n  lea rdi, [timer]\n  syscall\n  lea rdi, [mask2_end]\n  lea rsi, [funcA_name]\n  call printf\n  jmp _exit\n\nfuncB:\n  lea rdi, [mask2_start]\n  lea rsi, [funcB_name]\n  mov rdx, 2\n  call printf\n  mov qword [timer + ts.tv_sec], 2\n  mov rax, SYS_nanosleep\n  lea rdi, [timer]\n  syscall\n  lea rdi, [mask2_end]\n  lea rsi, [funcB_name]\n  call printf\n  jmp _exit\n\nfuncC:\n  lea rdi, [mask2_start]\n  lea rsi, [funcC_name]\n  mov rdx, 3\n  call printf\n  mov qword [timer + ts.tv_sec], 3\n  mov rax, SYS_nanosleep\n  lea rdi, [timer]\n  syscall\n  lea rdi, [mask2_end]\n  lea rsi, [funcC_name]\n  call printf\n  jmp _exit\n\nfuncD:\n  lea rdi, [mask2_start]\n  lea rsi, [funcD_name]\n  mov rdx, 1\n  call printf\n  mov qword [timer + ts.tv_sec], 1\n  mov rax, SYS_nanosleep\n  lea rdi, [timer]\n  syscall\n  lea rdi, [mask2_end]\n  lea rsi, [funcD_name]\n  call printf\n  jmp _exit\n\ncall_task:\n  lea rdi, [task1_name]\n  mov rsi, 3\n  call task\n  jmp _exit\n\ntask:\n  enter 16, 0\n  mov qword [rbp - 16], rdi\n  mov qword [rbp - 08], rsi\n  mov rax, SYS_clock_gettime\n  xor rdi, rdi\n  lea rsi, [epoch]\n  syscall\n  mov rdi, [epoch + ts.tv_sec]\n  lea rsi, [date]\n  call get_date\n  lea rdi, [mask_start]\n  mov rsi, [rbp - 16]\n  mov rdx, [rbp - 08]\n  mov rcx, [date + tm.tm_hour]\n  mov r8, [date + tm.tm_min]\n  mov r9, [date + tm.tm_sec]\n  call printf\n  mov rax, [rbp - 08]\n  mov qword [timer + ts.tv_sec], rax\n  mov qword [timer + ts.tv_nsec], 0\n  mov rax, SYS_nanosleep\n  lea rdi, [timer]\n  xor rsi, rsi\n  syscall\n  mov rax, SYS_clock_gettime\n  xor rdi, rdi\n  lea rsi, [epoch]\n  syscall\n  mov rdi, [epoch + ts.tv_sec]\n  lea rsi, [date]\n  call get_date\n  lea rdi, [mask_end]\n  mov rsi, [rbp - 16]\n  mov rdx, [date + tm.tm_hour]\n  mov rcx, [date + tm.tm_min]\n  mov r8, [date + tm.tm_sec]\n  call printf\nleave\n  ret\n\n; RDI: fecha en segundos.\n; RSI: puntero a struct tm\nget_date:\n  enter 16, 0\n  mov [rbp - 16], rdi\n  mov r15, rsi\n\n  ; Segundos\n  mov rax, [rbp - 16]\n  xor rdx, rdx\n  mov rbx, 60\n  div rbx\n  mov qword [imin], rax\n  xor rdx, rdx\n  mul rbx\n  mov rbx, [rbp - 16]\n  sub rbx, rax\n  mov qword [r15 + tm.tm_sec], rbx\n\n  ; Minutos\n  mov rax, qword [imin]\n  xor rdx, rdx\n  mov rbx, 60\n  div rbx\n  mov qword [ihrs], rax\n  xor rdx, rdx\n  mov rbx, 60\n  mul rbx\n  mov rbx, qword [imin]\n  sub rbx, rax\n  mov qword [r15 + tm.tm_min], rbx\n\n  ; Hora\n  mov rax, qword [ihrs]\n  xor rdx, rdx\n  mov rbx, 24\n  div rbx\n  mov qword [iday], rax\n  xor rdx, rdx\n  mov rbx, 24\n  mul rbx\n  mov rbx, qword [ihrs]\n  sub rbx, rax\n  mov qword [r15 + tm.tm_hour], rbx\n\n  ; Fecha\n  add qword [iday], 365\n  add qword [iday], 366\n  mov rax, qword [iday]\n  xor rdx, rdx\n  mov rbx, ((4 * 365) + 1)\n  div rbx\n  mov qword [lday], rax\n  mov qword [qday], rdx\n  cmp qword [qday], 60\n  jl .l1\n  inc qword [lday]\n.l1:\n  mov rax, qword [iday]\n  sub rax, qword [lday]\n  xor rdx, rdx\n  mov rbx, 365\n  div rbx\n  mov qword [iyrs], rax\n  mov rdx, 365\n  mul rdx\n  mov rbx, qword [iday]\n  sub rbx, rax\n  sub rbx, qword [lday]\n  mov qword [jday], rbx\n  cmp qword [qday], 365\n  ja .l2\n  cmp qword [qday], 60\n  jl .l2\n  inc qword [jday]\n.l2:\n  lea rdi, [r15 + tm.tm_year]\n  lea rsi, [iyrs]\n  movsq\n  add qword [r15 + tm.tm_year], 1968\n  mov qword [r15 + tm.tm_mon], 13\n  mov qword [mday], 366\n.while:\n  mov rax, qword [jday]\n  mov rbx, qword [mday]\n  cmp rax, rbx\n  jae .end_while\n  dec qword [r15 + tm.tm_mon]\n  mov rax, [r15 + tm.tm_mon]\n  mov rdx, 8\n  mul rdx\n  mov rbx, get_month(rax)\n  mov qword [mday], rbx\n  cmp qword [r15 + tm.tm_mon], 2\n  jl .endif\n  mov rax, [r15 + tm.tm_year]\n  xor rdx, rdx\n  mov rbx, 4\n  div rbx\n  test rdx, rdx\n  jnz .endif\n  inc qword [mday]\n.endif:\n  jmp .while\n.end_while:\n  mov rax, qword [jday]\n  sub rax, qword [mday]\n  inc rax\n  mov qword [r15 + tm.tm_mday], rax\n  inc qword [r15 + tm.tm_mon]\n  leave\n  ret\n\n\nsection .rodata\n  months: dq 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365\n  task1_name: db \"task1\", 0x00\n  mask_start: db \"Task name: %s - Duration: %usecs - Start: %02u:%02u:%02u\", 0x0A, 0x00\n  mask_end: db \"Task name: %s - End: %02u:%02u:%02u\", 0x0A, 0x00\n\n  mask2_start: db \"Function [%s] STARTED. Duration :%02u seconds\", 0x0A, 0x00\n  mask2_end: db \"Function [%s] FINISHED.\", 0x0A, 0x00\n\n  funcA_name: db \"Function A\", 0x00\n  funcB_name: db \"Function B\", 0x00\n  funcC_name: db \"Function C\", 0x00\n  funcD_name: db \"Function D\", 0x00\n\nsection .data\n  struc ts\n    .tv_sec: resq 1\n    .tv_nsec: resq 1\n  endstruc\n\n  struc tm\n    .tm_sec:  resq 1  ; segundos [0 - 60]\n    .tm_min:  resq 1  ; minutos [0 - 59]\n    .tm_hour: resq 1  ; hora [0 - 23]\n    .tm_mday: resq 1  ; día del mes [1, 31]\n    .tm_mon:  resq 1  ; mes [0 - 11] (enero = 0)\n    .tm_year: resq 1  ; año\n    .tm_wday: resq 1  ; día de la semana [0 - 6] (domingo = 0)\n    .tm_yday: resq 1  ; día del año [0 - 365]\n  endstruc\n\nsection .bss\n  timer: resb ts_size\n  epoch: resb ts_size\n  date: resb tm_size\n  imin: resq 1\n  ihrs: resq 1\n  iday: resq 1\n  lday: resq 1\n  qday: resq 1\n  iyrs: resq 1\n  jday: resq 1\n  mday: resq 1\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/ocaml/luishendrix92.ml",
    "content": "open Lwt_io\n\n(*****************************************************************************)\n(*                                                                           *)\n(*                Asynchronous Programming (and Concurrency)                 *)\n(*                                                                           *)\n(*  Concurrency in OCaml is done via Threads, and it can also leverage the   *)\n(*  [Domain] data structure for parallel programming. However there are 2    *)\n(*  main libraries to handle and wrap async operations: Lwt (acronym for     *)\n(*  \"lightweight threads\") and Async.                                        *)\n(*                                                                           *)\n(*  Lwt is a promise-like library that wraps IO and Unix operations, among   *)\n(*  other tasks that may need to be done concurrently. Many libraries are    *)\n(*  built with or on top of it; [cohttp] (HTTP library) is an example.       *)\n(*    A new library is on development called Riot which promises Erlang      *)\n(*  -like actor concurrency that can be run on multiple cores. But for this  *)\n(*  exercise I'm gonna use 3 {e opam} packages:                              *)\n(*                                                                           *)\n(*  1. [lwt]: The main Lwt package that contains many modules. One of them   *)\n(*     is the [Lwt_io] module that wraps your usual IO operations (print,    *)\n(*     read_char, read_line, assert, etc). And the core [Lwt] module that    *)\n(*     contains the glue functions like [join], [return], [pick], [bind].    *)\n(*  2. [lwt.unix]: Unix functions wrapped by promises, like [sleep].         *)\n(*  3. [lwt_ppx]: Syntax sugar for [bind] (and other) operations. Example:   *)\n(*     [let%lwt ln = Lwt_io.read_line () in printf \"I got: %s\" ln] instead   *)\n(*     of [Lwt_io.read_line () >>= fun ln -> Lwt_io.printf \"I got %s\" ln].   *)\n(*                                                                           *)\n(*****************************************************************************)\n\nlet time_now () =\n  let open Core.Time_float in\n  now () |> to_ofday ~zone:Zone.utc |> Ofday.to_sec_string\n;;\n\nlet delay_function ?(seconds = 1.0) ~name f =\n  let%lwt () =\n    printf \"[%s] will run after %.2f seconds | %s\\n\" name seconds (time_now ())\n  in\n  let%lwt () = Lwt_unix.sleep seconds in\n  f ();\n  printf \"[%s] has been called | %s\\n\" name (time_now ())\n;;\n\n(* Output:\n\n   [Ejercicio] will run after 4.00 seconds | 21:22:36\n   The answer is 42!\n   [Ejercicio] has been called | 21:22:40\n*)\nlet _ =\n  Lwt_main.run\n  @@ delay_function ~name:\"Ejercicio\" ~seconds:4.0 (fun () ->\n    print_endline \"The answer is 42!\")\n;;\n\n(****************************************************************************)\n(*                                                                          *)\n(*                        Dificultad Extra (opcional)                       *)\n(*                                                                          *)\n(*  Utilizando el concepto de asincronía y la función anterior, crea el     *)\n(*  siguiente programa que ejecuta en este orden:                           *)\n(*                                                                          *)\n(*  - Una función C que dura 3 segundos.                                    *)\n(*  - Una función B que dura 2 segundos.                                    *)\n(*  - Una función A que dura 1 segundo.                                     *)\n(*  - Una función D que dura 1 segundo.                                     *)\n(*  - Las funciones C, B, y A se ejecutan en paralelo.                      *)\n(*  - La función D comienza su ejecición cuando las 3 anteriores finalicén. *)\n(*                                                                          *)\n(****************************************************************************)\n\n(* Output:\n\n   [C] will run after 3.00 seconds | 22:02:10\n   [B] will run after 2.00 seconds | 22:02:10\n   [A] will run after 1.00 seconds | 22:02:10\n   Uploaded image family.jpg\n   [A] has been called | 22:02:11\n   Response from server: Error 404\n   [B] has been called | 22:02:12\n   Successfully downloaded avengers.mp4\n   [C] has been called | 22:02:13\n   [D] will run after 1.00 seconds | 22:02:13\n   Processed results, goodbye!\n   [D] has been called | 22:02:14\n*)\nlet _ =\n  let open Lwt in\n  let c =\n    delay_function ~name:\"C\" ~seconds:3.0 (fun () ->\n      print_endline \"Successfully downloaded avengers.mp4\")\n  in\n  let b =\n    delay_function ~name:\"B\" ~seconds:2.0 (fun () ->\n      print_endline \"Response from server: Error 404\")\n  in\n  let a =\n    delay_function ~name:\"A\" (fun () ->\n      print_endline \"Uploaded image family.jpg\")\n  in\n  (* If I create the promise and store it in a variable, nothing stops it from\n     starting right away so I have to defer its creation until it's needed. *)\n  let d () =\n    delay_function ~name:\"D\" (fun () ->\n      print_endline \"Processed results, goodbye!\")\n  in\n  Lwt_main.run (join [ c; b; a ] >>= d)\n;;\n\n(* Lastly, there are other ways of handling this. What about threads? I could\n   have used the [Thead] module with these functions: [Thread.create] and\n   [Thread.join]; and [Thread.delay] to block each thread for N seconds. *)\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/php/eulogioep.php",
    "content": "<?php\n\n/**\n * Clase para manejar tareas asíncronas\n */\nclass TareaAsincrona {\n    private $nombre;\n    private $segundos;\n    private $pid;\n\n    /**\n     * Constructor de la clase\n     * @param string $nombre Nombre de la tarea\n     * @param int $segundos Duración de la tarea en segundos\n     */\n    public function __construct($nombre, $segundos) {\n        $this->nombre = $nombre;\n        $this->segundos = $segundos;\n    }\n\n    /**\n     * Ejecuta la tarea de forma asíncrona\n     * @return bool True si la tarea se inició correctamente\n     */\n    public function ejecutar() {\n        // Crear un proceso hijo\n        $pid = pcntl_fork();\n        \n        if ($pid == -1) {\n            die(\"No se pudo crear el proceso hijo\\n\");\n        } else if ($pid) {\n            // Proceso padre\n            $this->pid = $pid;\n            return true;\n        } else {\n            // Proceso hijo\n            echo \"{$this->nombre} - Iniciando...\\n\";\n            echo \"{$this->nombre} - Durará {$this->segundos} segundos\\n\";\n            sleep($this->segundos);\n            echo \"{$this->nombre} - Finalizada\\n\";\n            exit(0);\n        }\n    }\n\n    /**\n     * Espera a que la tarea termine\n     */\n    public function esperar() {\n        if ($this->pid) {\n            pcntl_waitpid($this->pid, $status);\n        }\n    }\n}\n\n/**\n * Demostración básica de una tarea asíncrona\n */\nfunction demostracionBasica() {\n    echo \"=== Demostración Básica ===\\n\";\n    $tarea = new TareaAsincrona(\"TareaEjemplo\", 2);\n    $tarea->ejecutar();\n    $tarea->esperar();\n}\n\n/**\n * Implementación de la dificultad extra\n */\nfunction dificultadExtra() {\n    echo \"\\n=== Dificultad Extra ===\\n\";\n    \n    // Crear las tareas\n    $tareaC = new TareaAsincrona(\"Tarea C\", 3);\n    $tareaB = new TareaAsincrona(\"Tarea B\", 2);\n    $tareaA = new TareaAsincrona(\"Tarea A\", 1);\n    $tareaD = new TareaAsincrona(\"Tarea D\", 1);\n\n    // Ejecutar C, B y A en paralelo\n    $tareaC->ejecutar();\n    $tareaB->ejecutar();\n    $tareaA->ejecutar();\n\n    // Esperar a que terminen C, B y A\n    $tareaC->esperar();\n    $tareaB->esperar();\n    $tareaA->esperar();\n\n    // Ejecutar D después de que las otras hayan terminado\n    $tareaD->ejecutar();\n    $tareaD->esperar();\n}\n\n// Función principal\nfunction main() {\n    demostracionBasica();\n    dificultadExtra();\n}\n\n// Ejecutar el programa\nmain();\n\n?>"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/php/gabrielmoris.php",
    "content": "<?php\n/*\n * EXERCISE:\n * Using your language, create a program capable of asynchronously executing\n * a function that will take a specific number of seconds to complete, which\n * can be parameterized. You should also be able to assign it a name.\n * The function prints its name, when it starts, the duration of its execution,\n * and when it finishes.\n */\n\n\nfunction async($name, $sleep)\n{\n    $pid = pcntl_fork(); // creates a new child process.\n\n    if ($pid == -1) {\n        die('Failed to fork process');\n    } elseif ($pid) {\n        return $pid; // Parent process\n        // pcntl_wait($status); // Parent process\n    } else {\n        // Child process\n        echo \"Starting : $name\\n\";\n        $startTime = time();\n        sleep($sleep);\n        $endTime = time();\n        $executionTime = $endTime - $startTime;\n        echo \"Function: $name completed in $executionTime seconds\\n\";\n        exit(0);\n    }\n}\n// echo async('Function first', 1);\n// echo async('Function second', 2);\n// echo async('Function third', 3);\necho \"======================\\n\";\necho \"Main process continues\\n\";\n\n/*\n * EXTRA DIFFICULTY (optional):\n * Using the concept of asynchrony and the previous function, create\n * the following program that executes in this order:\n * - A function C that lasts 3 seconds.\n * - A function B that lasts 2 seconds.\n * - A function A that lasts 1 second.\n * - A function D that lasts 1 second.\n * - Functions C, B, and A are executed in parallel.\n * - Function D starts its execution when the previous 3 have finished.\n */\n\nfunction executeAsyncFunctions()\n{\n    $childPids = [];\n\n    // Execute async functions and store child process IDs\n    $childPids[] = async('C', 3);\n    $childPids[] = async('B', 2);\n    $childPids[] = async('A', 1);\n\n    // Wait for all child processes to complete\n    foreach ($childPids as $childPid) {\n        pcntl_waitpid($childPid, $status);\n    }\n\n    // Execute the final async function\n    $childPids[] = async('D', 1);\n    foreach ($childPids as $childPid) {\n        pcntl_waitpid($childPid, $status);\n    }\n    echo \"Main process Finished\\n\";\n    exit(0);\n}\n\nexecuteAsyncFunctions();\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/php/miguelex.php",
    "content": "<?php\n\nrequire 'vendor/autoload.php';  \n\nuse Amp\\Loop;\nuse Amp\\Promise;\n\n/*\n* De forma nativa, php no tiene soporte para funciones asíncronas. \n* Sin embargo, podemos simularlo con la función sleep.\n*/\nfunction asyncTask($name, $seconds){\n    echo \"Función asíncrona con nombre $name iniciada en el instante \" . date('H:i:s') . \"\\n\";\n    sleep($seconds);\n    echo \"Función asíncrona con nombre $name finalizada en el instante \" . date('H:i:s') . \"\\n\";\n}\n\necho \"Simulacion con sleep (No realmente asincrono)\\n\";\nasyncTask('MiFuncion', 5);\n\n/*\n* Para realizar tareas asíncronas de forma real, podemos utilizar librerías externas como Amp.\n* Amp es una librería que nos permite realizar tareas asíncronas de forma sencilla.\n*/\n\nfunction asyncTaskAmp($name, $seconds){\n    return Amp\\call(function () use ($name, $seconds) {\n        echo \"Función asíncrona con nombre $name iniciada en el instante \" . date('H:i:s') . \"\\n\";\n        yield Amp\\delay($seconds * 1000);  // Amp\\delay espera un tiempo en milisegundos\n        echo \"Función asíncrona con nombre $name finalizada en el instante \" . date('H:i:s') . \"\\n\";\n    });\n}\n\necho \"\\n\\nAsincronía real mediante uso de libreria externa\\n\";  \nLoop::run(function () {\n    asyncTaskAmp('MiFuncion', 5);\n});\n\necho \"\\n\\nEjercicio Extra (solo con Amp, con sleep no se podria hacer)\\n\";\nLoop::run(function () {\n    // Iniciar las funciones C, B y A en paralelo\n    $promises = [\n        asyncTaskAmp('C', 3),\n        asyncTaskAmp('B', 2),\n        asyncTaskAmp('A', 1),\n    ];\n\n    // Esperar a que las funciones C, B y A finalicen\n    Promise\\wait(Promise\\all($promises));\n\n    // Iniciar la función D\n    Loop::run(function () {\n        asyncTaskAmp('D', 1);\n    });\n});"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/php/thaishdz.php",
    "content": "<?php\n\n/*\n* Utilizando el concepto de asincronía y la función anterior, crea\n* el siguiente programa que ejecuta en este orden:\n* - Una función C que dura 3 segundos.\n* - Una función B que dura 2 segundos.\n* - Una función A que dura 1 segundo.\n* - Una función D que dura 1 segundo.\n* - Las funciones C, B y A se ejecutan en paralelo.\n* - La función D comienza su ejecución cuando las 3 anteriores han finalizado.\n*/\n\n# Usé ReactPHP para manejar la asincronía\n\nuse React\\EventLoop\\Loop;\nuse React\\Promise\\Promise;\nuse function React\\Async\\parallel;\n\n\nfunction task(string $name, int $interval)\n{\n    return new Promise(function ($resolver) use ($name, $interval) \n    {\n        Loop::addTimer($interval, function () use ($resolver, $name, $interval)\n        {\n            $resolver(\"Task $name ... Total Time Execution : $interval sg 👻\\n\");\n        });\n    });\n}\n\n\nparallel([\n    function () { return task('C',3);},\n    function () { return task('B',2);},\n    function () { return task('A',1);}\n\n])->then(function (array $results){\n    // Muestra los resultados de las promesas\n    foreach ($results as $result) {\n        echo \"$result\\n\";\n    }\n    return task('D', 1);\n})->then(function ($result){\n    // Muestra el resultado de la tarea D una vez acaben las 3 anteriores\n    echo $result;\n});\n\n// Iniciar el loop de eventos\nLoop::get()->run();"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/AChapeton.py",
    "content": "import asyncio\n\nasync def asyncFunction(name, seconds):\n  print(f\"Inicia la ejecucion de {name}\")\n  print(f\"Duracion de {name}: {seconds} segundos\")\n  await asyncio.sleep(seconds)\n  print(f\"Finaliza la ejecucion de {name}\")\n\n# asyncio.run(asyncFunction(\"Test\", 3))\n\n\n# DIFICULTAD EXTRA\n\nasync def multipleFunctions():\n  await asyncio.gather(asyncFunction(\"C\", 3), asyncFunction(\"B\", 2), asyncFunction(\"A\", 1))\n  await asyncFunction(\"D\", 1)\n\nasyncio.run(multipleFunctions())"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/Aldroide.py",
    "content": "# Ejercicio\n\"\"\"\n    Ejecutar una programa capaz de ejecutar de manera asíncrona una función\n    que tardará en finalizar un numero concreto de segundos parametrizables\n    Tambien debes poder asignarle un nombre\n    La función imprime su nombre, cuando empieza, el tiempo que durara la ejecución\n    y cuando finaliza\n\"\"\"\nimport asyncio\nimport datetime\n\n\nasync def asyncHello(name: str, seconds: int):\n    print(f\"\"\"La función {name}, dura {seconds} segundos\n              Inica en {datetime.datetime.now().strftime('%H:%M:%S')}\"\"\")\n    await asyncio.sleep(seconds)\n    print(\n        f\"La función {name} ha finalizado en: {datetime.datetime.now().strftime('%H:%M:%S')}\")\n\nasyncio.run(asyncHello(\"Test\", 5))\n\n\n# Ejercicio extra\n\"\"\"\n  Utilizando el concepto de asincronía y la función anterior, crea\n  el siguiente programa que ejecuta en este orden:\n  - Una función C que dura 3 segundos.\n  - Una función B que dura 2 segundos.\n  - Una función A que dura 1 segundo.\n  - Una función D que dura 1 segundo.\n  - Las funciones C, B y A se ejecutan en paralelo.\n  - La función D comienza su ejecución cuando las 3 anteriores han\n  finalizado.\n\"\"\"\n\n\nasync def ejercicioExtra():\n    await asyncio.gather(\n        asyncHello(\"C\", 3),\n        asyncHello(\"B\", 2),\n        asyncHello(\"A\", 1),\n    )\n\n\nasyncio.run(ejercicioExtra())\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/CaveroBrandon.py",
    "content": "\"\"\"EJERCICIO:\nUtilizando tu lenguaje, crea un programa capaz de ejecutar de manera\nasíncrona una función que tardará en finalizar un número concreto de\nsegundos parametrizables. También debes poder asignarle un nombre.\nLa función imprime su nombre, cuándo empieza, el tiempo que durará\nsu ejecución y cuando finaliza.\"\"\"\n\nimport asyncio\n\n\nasync def async_function(function_name, delay):\n    print(f'The function \"{function_name}\", is starting it will take {delay} seconds to be completed...')\n    await asyncio.sleep(delay)\n    print(f'\"{function_name}\" was completed after {delay} seconds')\n\n\nasync def exercise():\n    await async_function(function_name='First Exercise', delay=1)\n\n\n\"\"\"DIFICULTAD EXTRA (opcional):\nUtilizando el concepto de asincronía y la función anterior, crea\nel siguiente programa que ejecuta en este orden:\n- Una función C que dura 3 segundos.\n- Una función B que dura 2 segundos.\n- Una función A que dura 1 segundo.\n- Una función D que dura 1 segundo.\n- Las funciones C, B y A se ejecutan en paralelo.\n- La función D comienza su ejecución cuando las 3 anteriores han finalizado.\"\"\"\n\n\nasync def function_a():\n    await async_function('Function A', 1)\n\n\nasync def function_b():\n    await async_function('Function B', 2)\n\n\nasync def function_c():\n    await async_function('Function C', 3)\n\n\nasync def function_d():\n    await async_function('Function D', 1)\n\n\nasync def parallel_execution():\n    exe_c = asyncio.create_task(function_c())\n    exe_b = asyncio.create_task(function_b())\n    exe_a = asyncio.create_task(function_a())\n\n    await asyncio.gather(exe_c, exe_b, exe_a)\n\n\nasync def sequential_execution():\n    await function_d()\n\n\nasync def main():\n    print('**** Basic exercise ****')\n    await exercise()\n    print('\\n**** Extra ****')\n    await parallel_execution()\n    await sequential_execution()\n\n\nasyncio.run(main())\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/CesarCarmona30.py",
    "content": "import asyncio\nimport datetime\n\nasync def async_function(function_name, time):\n    start_time = datetime.datetime.now()\n    print(f\"Start function {function_name}\")\n    print(f\"{function_name} will take {time} seconds\")\n    while (datetime.datetime.now() - start_time).total_seconds() < time:\n        current_time = datetime.datetime.now()\n        elapsed_time = (current_time - start_time).total_seconds()\n        print(f\"{function_name} - Sec {int(elapsed_time) + 1}\")\n        await asyncio.sleep(1)\n    print(f\"{function_name} was completed after {time} seconds\")\n\nasync def tasks():\n    # Crear y ejecutar tareas asíncronas\n    task_1 = async_function(\"Task 1\", 10)\n    task_2 = async_function(\"Task 2\", 5)\n    await asyncio.gather(task_1, task_2)\n\n# Ejecutar el bucle de eventos de asyncio\nasyncio.run(tasks())\n\nasync def main():\n    # Ejecutar las funciones C, B y A en paralelo\n    task_c = async_function(\"Function C\", 3)\n    task_b = async_function(\"Function B\", 2)\n    task_a = async_function(\"Function A\", 1)\n    await asyncio.gather(task_c, task_b, task_a)\n    \n    # Cuando C, B y A han terminado, ejecutar la función D\n    task_d = async_function(\"Function D\", 1)\n    await task_d\n\n# Ejecutar el bucle de eventos de asyncio\nasyncio.run(main())"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/Chrisdev00.py",
    "content": "\"\"\"\n* EJERCICIO:\n* Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n* asíncrona una función que tardará en finalizar un número concreto de\n* segundos parametrizables. También debes poder asignarle un nombre.\n* La función imprime su nombre, cuándo empieza, el tiempo que durará\n* su ejecución y cuando finaliza.\n*\n* DIFICULTAD EXTRA (opcional):\n* Utilizando el concepto de asincronía y la función anterior, crea\n* el siguiente programa que ejecuta en este orden:\n* - Una función C que dura 3 segundos.\n* - Una función B que dura 2 segundos.\n* - Una función A que dura 1 segundo.\n* - Una función D que dura 1 segundo.\n* - Las funciones C, B y A se ejecutan en paralelo.\n* - La función D comienza su ejecución cuando las 3 anteriores han finalizado.\n\"\"\"\n\nimport asyncio\nimport time\n\nasync def run_task (name, duration):\n\n    #print(f\"Task '{name}' started.\")\n    start_time = time.time()\n\n    await asyncio.sleep(duration)\n\n    end_time = time.time()\n    elapsed_time = end_time - (start_time)\n\n    print(f\"Task '{name}' started at {time.ctime(start_time)}, will run for '{duration}' seconds. Took {elapsed_time:.2f} seconds to complete.\")\n\nasync def main():\n\n    tasks = [\n        run_task(\"Tarea 1\", 3),\n        run_task(\"Tarea 2\", 1),\n        run_task(\"Tarea 3\", 4)\n    ]\n\n    await asyncio.gather(*tasks)\n\nasyncio.run(main())\n\n\n##########  ------------------------  EXTRA  ---------------------------------- ##################\n\n\nasync def function_c():\n    \n    print(\"La funcion 'C' comenzo a ejecutarse.\")\n    await asyncio.sleep(3)\n    print(\"Funcion 'C' completada.\")\n\nasync def function_b():\n\n    print(\"La funcion 'B' comenzo a ejecutarse.\")\n    await asyncio.sleep(2)\n    print(\"Funcion 'B' completada.\")\n\nasync def function_a():\n\n    print(\"La funcion 'A' comenzo a ejecutarse.\")\n    await asyncio.sleep(1)\n    print(\"Funcion 'A' completada.\")\n\nasync def function_d():\n\n    print(\"Funcion 'D' esperando que las funciones C,B y A se completen.\")\n    await asyncio.gather(function_c(), function_b(), function_a())\n    print(\"Funcion 'D' comenzo a ejecutarse.\")\n    await asyncio.sleep(1)\n    print(\"Funcion 'D' completada\")\n\nasync def main():\n\n    await asyncio.gather(function_c(), function_b(), function_a())  # Ejecuta las funciones C,B y A en paralelo\n\n    await function_d()    # Una vez finalizadas C, B y A, ejecuta la función D  \n\nasyncio.run(main())"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/Complex303.py",
    "content": "\"\"\"\nAsincronia\n\"\"\"\n\n#Ejecutar tareas sin esperar a que terminen para seguir con otras. Permite que un programa siga funcionando mientras espera respuestas de operaciones lentas (como leer un archivo, consultar una API, etc).\n\nimport datetime  # Para trabajar con fechas y horas\nimport time      # Para simular una pausa (bloqueante)\nimport asyncio   # Para manejar asincronía\n\n\n# Definimos una función asíncrona (puede ser pausada sin bloquear)\nasync def task(name: str, duration: int):\n     # Mostramos el nombre de la tarea, su duración y la hora de inicio\n    print(f\"Tarea: {name}. Duracion: {duration}s. Inicio {datetime.datetime.now()}\") #Aquí usamos datetime.datetime.now() porque: datetime es el módulo. Dentro de él hay una clase datetime. Y dentro de esa clase está el método now().\n#Si hubiéramos hecho from datetime import datetime, podríamos escribir solo datetime.now().\n\n    #Mal uso de time.sleep() en función async. Debe ser await asyncio.sleep() para no bloquear.\n    #time.sleep(duration) # Simulamos que la tarea toma tiempo (bloqueante)\n\n    await asyncio.sleep(duration) #pausa la corrutina durante duration segundos, pero permite que otras tareas sigan ejecutándose mientras.\n\n    # Mostramos la hora al terminar\n    print(f\"Tarea: {name}. Fin {datetime.datetime.now()}\")\n\n# Ejecutamos la corrutina en un event loop\nasyncio.run(task(\"1\", 2))\n\n\"\"\"* DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han\n *   finalizado.\"\"\"\n\n #Definimos otra función asíncrona que se encargará de manejar varias tareas a la vez.\nasync def async_tasks():\n    #asyncio.gather() permite ejecutar varias corrutinas al mismo tiempo.\n    await asyncio.gather(task(\"C\", 3), task(\"B\", 2), task(\"A\", 1)) #Aquí las tareas C, B y A se lanzan juntas y terminan según su duración.\n    await task(\"D\", 2) #Se espera a que terminen C, B y A, y luego se ejecuta D.\n\n#Ejecutar todo el grupo de tareas\nasyncio.run(async_tasks())\n\n\n# async def\tDefine una función asincrónica (corrutina).\n# await\tEspera sin bloquear. Permite continuar otras tareas.\n# asyncio.sleep()\tPausa la corrutina de forma no bloqueante.\n# asyncio.gather()\tEjecuta varias corrutinas en paralelo.\n# asyncio.run()\tInicia y maneja el event loop asincrónico.\n# datetime.datetime.now()\tObtiene la fecha y hora actual.\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/DaniQB99.py",
    "content": "'''\nEJERCICIO:\nUtilizando tu lenguaje, crea un programa capaz de ejecutar de manera \nasincrona una función que tardará en finalizar un número concreto de\nsegundos parametrizables. También debes poder asignarle un nombre.\nLa función imprime su nombre, cuándo empieza, el tiempo que durará\nsu ejecución y cuando finaliza.\n'''\nimport datetime, asyncio \n\nasync def tik_tak(name: str, duration: int):\n    \n    print(f\"Tarea: {name}. Duración: {duration}s. \\n    - Inicio de tarea: {datetime.datetime.now()}\")\n                \n    await asyncio.sleep(duration) # Tiempo de espera\n    \n    print(f\"- Fin de tarea {name}: {datetime.datetime.now()}\")\n    \nasyncio.run(tik_tak(\"1\", 2))\n\n\n    \n\n'''DIFICULTAD EXTRA (opcional):\nUtilizando el concepto de asincronía y la función anterior, crea\nel siguiente programa que ejecuta en este orden:\n- Una función C que dura 3 segundos.\n- Una función B que dura 2 segundos.\n- Una función A que dura 1 segundo.\n- Una función D que dura 1 segundo.\n- Las funciones C, B y A se ejecutan en paralelo.\n- La función D comienza su ejecución cuando las 3 anteriores han\nfinalizado.\n'''\n\nasync def async_tik_tak():\n    await asyncio.gather( # GATHER es una función que espera a que todos los \n                          # parámetros de su llamada se ajecuten antes de \n                          # continuar\n        tik_tak(\"C\", 3), \n        tik_tak(\"B\", 2),  \n        tik_tak(\"A\", 1)\n    )\n    await tik_tak(\"D\", 1) # AWAIT es una palabra reservada que espera a que \n                          # la función que está a su lado se complete antes \n                          # de continuar\n    \nasyncio.run(async_tik_tak()) # .run es una función que ejecuta una función asincrona\n\n    "
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/EmmanuelMMontesinos.py",
    "content": "\"\"\"/*\n * EJERCICIO:\n * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n * asíncrona una función que tardará en finalizar un número concreto de\n * segundos parametrizables. También debes poder asignarle un nombre.\n * La función imprime su nombre, cuándo empieza, el tiempo que durará\n * su ejecución y cuando finaliza.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han\n *   finalizado.\n */\"\"\"\n\n# Ejercicio Base y Extra\n\nimport asyncio\nimport time\n\nclass Proceso:\n    def __init__(self,nombre:str,tiempo:int) -> None:\n        if type(nombre) == str and type(tiempo) == int:\n            self.nombre = nombre\n            self.tiempo = tiempo\n\n    async def ejecutar(self):\n        inicio = time.time()\n        print(f\"Iniciando: {self.nombre}\\nTiempo: {self.tiempo} segundos\\n\")\n        await asyncio.sleep(self.tiempo)\n        print(f\"Terminado: {self.nombre} en {time.time()-inicio} segundos\\n\")\n\nasync def main():\n    proceso_1 = Proceso(\"A\",1)\n    proceso_2 = Proceso(\"B\",2)\n    proceso_3 = Proceso(\"C\",3)\n    proceso_4 = Proceso(\"D\",1)\n\n    a = loop.create_task(proceso_1.ejecutar())\n    b = loop.create_task(proceso_2.ejecutar())\n    c = loop.create_task(proceso_3.ejecutar())\n    await asyncio.gather(a,b,c)\n    d = loop.create_task(proceso_4.ejecutar())\n    await asyncio.gather(d)\n    \nif __name__ == \"__main__\":\n    \n    loop = asyncio.get_event_loop()\n    loop.run_until_complete(main())\n    loop.close()\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/FedeAirala.py",
    "content": "# 15 ASINCRONÍA\n\n\"\"\"\n * EJERCICIO:\n * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n * asíncrona una función que tardará en finalizar un número concreto de\n * segundos parametrizables. También debes poder asignarle un nombre.\n * La función imprime su nombre, cuándo empieza, el tiempo que durará\n * su ejecución y cuando finaliza.\n\"\"\"\n\nimport asyncio\nimport time\n\nasync def main(name):\n\n    print(f\"Start function:  {time.strftime('%X')}\")\n    print(name)\n    print (\"Wait 4 seconds to finish\")\n    await asyncio.sleep(4)\n    print(f\"Finish function {time.strftime('%X')}\")\n\nasyncio.run(main(\"Async Function\"))\n\nprint (\"-\"*100)\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han\n *   finalizado.\n \"\"\"\n\nprint (\"Ejercicio Extra\\n\")\n\nasync def a_function():\n    await asyncio.sleep(1)\n    return print(\"Function A\")\n\nasync def b_function():\n    await asyncio.sleep(2)\n    return print (\"Function B\")\n\nasync def c_function():\n    await asyncio.sleep(3)\n    print (\"Function C\")\n    \nasync def asinc():\n\n    task_a = asyncio.create_task(a_function()) # Asigno tareas\n    task_b = asyncio.create_task(b_function())\n    task_c = asyncio.create_task(c_function())\n    await asyncio.gather(task_a,task_b,task_c) # Ejecución de las 3 tareas juntas\n\nasync def d_function():\n    await asyncio.sleep(1)\n    return print(\"Function D\")\n\nasyncio.run(asinc())\nasyncio.run(d_function())"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/Gallitofast.py",
    "content": "#  * EJERCICIO:\n#  * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n#  * asíncrona una función que tardará en finalizar un número concreto de\n#  * segundos parametrizables. También debes poder asignarle un nombre.\n#  * La función imprime su nombre, cuándo empieza, el tiempo que durará\n#  * su ejecución y cuando finaliza.\n\nimport asyncio\nfrom datetime import datetime\nasync def funcion_asincronia():\n    print(f\"Comenzando a la hora {datetime.now().strftime('%H:%M:%S')}\")\n    await asyncio.sleep(2) #simulamos 2 segundos de espera\n    print(f\"Finalizando a las {datetime.now().strftime('%H:%M:%S')}\")\n\nasyncio.run(funcion_asincronia())\n\nprint(\"-\"*60)\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Utilizando el concepto de asincronía y la función anterior, crea\n#  * el siguiente programa que ejecuta en este orden:\n#  * - Una función C que dura 3 segundos.\n#  * - Una función B que dura 2 segundos.\n#  * - Una función A que dura 1 segundo.\n#  * - Una función D que dura 1 segundo.\n#  * - Las funciones C, B y A se ejecutan en paralelo.\n#  * - La función D comienza su ejecución cuando las 3 anteriores han\n#  *   finalizado.\n\nprint(\"Dificultad extra\\n\")\nprint(f\"Las funciones se empezaran a ejecutar a las: {datetime.now().strftime('%H:%M:%S')}\")\nasync def funcion_c():\n    await asyncio.sleep(3)\n    return print(f\"Funcion C termino a las: {datetime.now().strftime('%H:%M:%S')}\")\nasync def funcion_b():\n    await asyncio.sleep(2)\n    return print(f\"Funcion B termino a las: {datetime.now().strftime('%H:%M:%S')}\")\n\nasync def funcion_a():\n    await asyncio.sleep(1)\n    return print(f\"Funcion A termino a las: {datetime.now().strftime('%H:%M:%S')}\")\n\nasync def conjuncion():\n    task_a= asyncio.create_task(funcion_a())\n    task_b= asyncio.create_task(funcion_b())\n    task_c= asyncio.create_task(funcion_c())\n    await asyncio.gather(task_a,task_b,task_c)\n\nasync def funcion_d():\n    await asyncio.sleep(1)\n    return print(f\"Funcion D termino a las {datetime.now().strftime('%H:%M:%S')}\")\n\nasyncio.run(conjuncion())\nasyncio.run(funcion_d())\nprint(\"-\"*60)\n\n\n\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/Gordo-Master.py",
    "content": "# 15 - Asincronia\n\nimport asyncio\nfrom datetime import datetime\n\nasync def call_name(name,time_to_wait):\n    print(datetime.now().time().strftime(f\"Comienza función: {name}: %X, durara {time_to_wait} segundos\"))\n    await asyncio.sleep(time_to_wait)\n    print(datetime.now().time().strftime(f\"Termina funcion {name}: %X\"))\n\n# asyncio.run(call_name(\"Gordo Master\",2))\n\n\"\"\"\nEjercicio Extra\n\"\"\"\nasync def main():\n\n    await asyncio.gather(\n        call_name(\"C\",3),\n        call_name(\"B\",2),\n        call_name(\"A\",1)\n    )\n    \n    await call_name(\"D\",1)\n\nasyncio.run(main())\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/Hyromy.py",
    "content": "import asyncio, datetime # importando paquetes\n\n# funcion asincrona\nasync def funcion_asincrona(tiempo:float, task_name:str):\n    inicio = datetime.datetime.now() # tiempo y hora de inicio\n    print(f\"tarea: {task_name} iniciada el {inicio}\")\n\n    await asyncio.sleep(tiempo) # esperar x cantidad de tiempo\n\n    fin = datetime.datetime.now() # tiempo y hora de fin\n    print(f\"{task_name} terminado el {fin}\")\n\n    transcurrido = fin - inicio # diferencia entre inicio y fin\n    print(f\"Tiempo transcurrido: {transcurrido}\")\n\nasyncio.run(funcion_asincrona(5, \"ir al baño\")) # ejecucion de la funcion asincrona\n\n# ---- DIFICULTAD EXTRA ----\n\nasync def funcion(nombre:str, espera:float):\n    print(f\"Funcion {nombre} comenzada\")\n\n    await asyncio.sleep(espera)\n\n    print(f\"Funcion {nombre} terminada ({espera} segundos)\")\n\nasync def main():\n    await asyncio.gather(funcion(\"C\", 3),\n                         funcion(\"B\", 2),\n                         funcion(\"A\", 1))\n\n    await funcion(\"D\", 1)\n\nasyncio.run(main())"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/Irenetitor.py",
    "content": "import datetime\nimport asyncio\n\nasync def task(name: str, duration: int):\n    print(f\"Task: {name}. Duration: {duration}s. Start: {datetime.datetime.now()}\")\n    await asyncio.sleep(duration)\n    print(f\"Task: {name}. End: {datetime.datetime.now()}\")\n\n#asyncio.run(task(\"1\", 4))\n\n\n\n#Extra Exercise\n\nasync def async_tasks():\n    await asyncio.gather(task(\"c\", 3), task(\"B\", 2), task(\"A\", 1))\n\n    await task(\"D\", 1)\n\n#asyncio.run(async_tasks())\n\nasync def main():\n    await task(\"1\", 4) #part 1\n\n    await async_tasks() #part2\n    \n\nasyncio.run(main())"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/JAFeito.py",
    "content": "\"\"\"\n EJERCICIO:\n Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n asíncrona una función que tardará en finalizar un número concreto de\n segundos parametrizables. También debes poder asignarle un nombre.\n La función imprime su nombre, cuándo empieza, el tiempo que durará\n su ejecución y cuando finaliza.\n\n DIFICULTAD EXTRA (opcional):\n Utilizando el concepto de asincronía y la función anterior, crea\n el siguiente programa que ejecuta en este orden:\n - Una función C que dura 3 segundos.\n - Una función B que dura 2 segundos.\n - Una función A que dura 1 segundo.\n - Una función D que dura 1 segundo.\n - Las funciones C, B y A se ejecutan en paralelo.\n - La función D comienza su ejecución cuando las 3 anteriores han finalizado.\n\"\"\"\nimport asyncio\nasync def delay (nombre , tiempo:int):\n    print(f\"Iniciando funcion {nombre}\")\n    await asyncio.sleep(tiempo)\n    print(f\"Han pasado {tiempo} segundos\")\n    print(f\"Funcion {nombre} terminada\")\n#nombre =  input(\"Introduzca el el nombre de la tarea:\")   \n#tiempo = input(\"Introduzca el tiempo de espera:\")\n#asyncio.run(delay(nombre, tiempo))\n\n#EXTRA\nasync def lanzador ():\n    await asyncio.gather(delay(\"C\",3),delay(\"B\",2),delay(\"A\",1))\n    await delay(\"D\",1)\n\n\nasyncio.run(lanzador())"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/JesusWay69.py",
    "content": "import os\nos.system('cls')\nfrom datetime import datetime as DT\nimport time\nimport asyncio\n\n\"\"\" * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n * asíncrona una función que tardará en finalizar un número concreto de\n * segundos parametrizables. También debes poder asignarle un nombre.\n * La función imprime su nombre, cuándo empieza, el tiempo que durará\n * su ejecución y cuando finaliza.\n *\n\"\"\"\n\ndef asynchrone (wait_seconds:int,name:str):\n    start_time = DT.now()\n    print(f\"La ejecución de {name} durará {wait_seconds} segundos\")\n    print(\"La ejecución comienza a las {}:{}:{}\".format(DT.now().hour,DT.now().minute,DT.now().second))\n    time.sleep(wait_seconds)\n    print(\"Ejecución de \",name,\" terminada a las {}:{}:{}\".format(DT.now().hour,DT.now().minute,DT.now().second))\n    end_time = DT.now()\n    print(\"Duración de la ejecución: \", end_time-start_time, \"\\n\")\nasynchrone(4,\"\\'Hola Mundo\\'\")\n\n\"\"\" * DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han finalizado.\"\"\"\n\nasync def C ():\n    print(\"Función C iniciada a las {}:{}:{}\".format(DT.now().hour,DT.now().minute,DT.now().second))\n    await asyncio.sleep(3)\n    print(\"Función C terminada a las {}:{}:{}\".format(DT.now().hour,DT.now().minute,DT.now().second))\nasync def B ():\n    print(\"Función B iniciada a las {}:{}:{}\".format(DT.now().hour,DT.now().minute,DT.now().second))\n    await asyncio.sleep(2)\n    print(\"Función B terminada a las {}:{}:{}\".format(DT.now().hour,DT.now().minute,DT.now().second))\n    \nasync def A ():\n    print(\"Función A iniciada a las {}:{}:{}\".format(DT.now().hour,DT.now().minute,DT.now().second))\n    await asyncio.sleep(1)\n    print(\"Función A terminada a las {}:{}:{}\".format(DT.now().hour,DT.now().minute,DT.now().second))\n    \ndef D ():\n    print(\"Función D iniciada a las {}:{}:{}\".format(DT.now().hour,DT.now().minute,DT.now().second))\n    time.sleep(1)\n    print(\"Función D terminada a las {}:{}:{}\".format(DT.now().hour,DT.now().minute,DT.now().second))\n\nasync def paralllel_funtcions():\n    funtc_C = asyncio.create_task(C())\n    funtc_B = asyncio.create_task(B())\n    funtc_A = asyncio.create_task(A())\n    await asyncio.gather(funtc_C,funtc_B,funtc_A)\nasyncio.run(paralllel_funtcions())\nD()\n\n    \n\n\n\n\n    "
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/JheisonQuiroga.py",
    "content": "import asyncio\nimport time\nfrom datetime import datetime, timedelta\n\n\"\"\"/*\n * EJERCICIO:\n * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n * asíncrona una función que tardará en finalizar un número concreto de\n * segundos parametrizables. También debes poder asignarle un nombre.\n * La función imprime su nombre, cuándo empieza, el tiempo que durará\n * su ejecución y cuando finaliza.\"\"\"\n\nasync def task(name, seconds):\n    init_time = timedelta(seconds=datetime.now().second)\n    print(f\"Start fetching data from {name}\")\n    await asyncio.sleep(seconds)\n    finish_time = timedelta(seconds=datetime.now().second)\n    difference = finish_time - init_time\n    print(f\"Data fetched from {name} in {difference} seconds\")\n    return f\"Data from {name}\"\n\n\n\nasync def main():\n    result = await asyncio.create_task(task(\"API_1\", 5))\n    return result\n\n\n# if __name__ == \"__main__\":\n#     asyncio.run(main())\n\n\n\"\"\" * DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han finalizado.\n */\"\"\"\n\nasync def main2():\n    start_time = time.time()\n    # Creamos las tareas explicitamente\n    task_a = asyncio.create_task(task(\"A\", 1))\n    task_b = asyncio.create_task(task(\"B\", 2))\n    task_c = asyncio.create_task(task(\"C\", 3))\n    \n    # Esperamos que terminen las tareas paralelas (se ejecutan en paralelo)\n    results = await asyncio.gather(task_a, task_b, task_c)\n\n    # Ejecutamos la función D\n    result_d = await task(\"D\", 1)\n    \n    results.append(result_d)\n\n    end_time = time.time() - start_time\n\n    print(\"Results:\", results)\n    print(\"Total time:\", end_time, \"seconds\")\n\nif __name__ == \"__main__\":\n    asyncio.run(main2())"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/JuanDAW37.py",
    "content": "\"\"\"* EJERCICIO:\n * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n * asíncrona una función que tardará en finalizar un número concreto de\n * segundos parametrizables. También debes poder asignarle un nombre.\n * La función imprime su nombre, cuándo empieza, el tiempo que durará\n * su ejecución y cuando finaliza.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han finalizado.\"\"\"\n\nimport  datetime\nimport asyncio # Librería de Python para asincronía\n\nasync def  funcion_asincrona(nombre, tiempo): # Declaración de función asíncrona\n    print(f\"Comienza la función {nombre}\")\n    print(f\"La función {nombre} durará {tiempo} segundos y comienza {datetime.datetime.now()}\")\n    await asyncio.sleep(tiempo) # Permite que se detenga un hilo asíncrono\n    print(f\"Finaliza la función {nombre} en {datetime.datetime.now()}\")\n    \n\nasyncio.run(funcion_asincrona('Función asíncrona UNO', 5)) # Se usa asyncio con el método run para ejecutar la función asíncrona\nasyncio.run(funcion_asincrona('Función asíncrona DOS', 5)) # Se usa asyncio con el método run para ejecutar la función asíncrona\n\n#EXTRA\n#Es necesario crear una función para la ejecución en paralelo\nasync def ejecuta_paralelo():\n    # Ejecución asíncrona en paralelo, las 3 a la vez, se lanzan las 3, pero finaliza primero la que tenga menor duración\n    await asyncio.gather(funcion_asincrona('Función C', 3), funcion_asincrona('Función B', 2), funcion_asincrona('Función A', 1)) # Permite que se detenga un hilo asíncrono\n    await funcion_asincrona('Función D', 1)\n\nasyncio.run(ejecuta_paralelo())"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/KevinED11.py",
    "content": "import asyncio\nfrom typing import Callable, Iterable, Awaitable\n\n\ntype T[T] = T\ntype Number = int | float\ntype TAwaitable = Awaitable[T]\ntype VoidCoroutine = Awaitable[None]\ntype VoidCoroutineFn = Callable[[], VoidCoroutine]\ntype CoroutineFn = Callable[..., TAwaitable]\ntype VariadicFunction = Callable[..., T] | Callable[..., TAwaitable]\n\n\ndef set_function_name(func: VariadicFunction, new_name: str) -> None:\n    func.__name__ = new_name\n\n\ndef get_function_name(func: VariadicFunction) -> str:\n    return func.__name__\n\n\nasync def generic_function(wait_time: Number, func_name: str) -> None:\n    await sleep_program(seconds=wait_time, name=func_name)\n\n\ndef is_coroutine_function(func: CoroutineFn) -> bool:\n    return asyncio.iscoroutinefunction(func)\n\n\ndef async_partial(func: CoroutineFn, *args, **kwargs) -> CoroutineFn:\n    async def f2(*args2, **kwargs2) -> T:\n        result = func(*args, *args2, **kwargs, **kwargs2)\n        if is_coroutine_function(func):\n            result = await result\n\n        return result\n\n    return f2\n\n\nfunction_a = async_partial(generic_function, wait_time=1, func_name=\"Function A\")\nfunction_b = async_partial(generic_function, wait_time=2, func_name=\"Function B\")\nfunction_c = async_partial(generic_function, wait_time=3, func_name=\"Function C\")\nfunction_d = async_partial(generic_function, wait_time=1, func_name=\"Function D\")\nfunction_e = async_partial(generic_function, wait_time=11, func_name=\"Function E\")\n\n\nasync def execute_void_coroutines_simultaneously(\n    coros: Iterable[VoidCoroutineFn],\n) -> None:\n    async with asyncio.TaskGroup() as tg:\n        for coro in coros:\n            tg.create_task(coro())\n\n\nasync def sleep_program(seconds: Number, name: str = \"Sleep\") -> None:\n    set_function_name(sleep_program, name)\n    current_name = get_function_name(sleep_program)\n\n    print(f\"{current_name} program started\")\n    print(f\"Sleeping for {seconds} seconds\")\n    await asyncio.sleep(delay=seconds)\n\n    print(f\"{current_name} program finished\")\n\n\nasync def goodbye() -> None:\n    print(\"¡Adiós, mundo!\")\n\n\nasync def main() -> None:\n    await sleep_program(5)\n    print(\"¡Hola, mundo!\")\n\n    cor = function_a()\n    result = await cor\n    print(result)\n\n    void_coroutine_functions = [\n        function_e,\n        function_c,\n        function_b,\n        function_a,\n        function_d,\n        goodbye,\n    ]\n    await execute_void_coroutines_simultaneously(void_coroutine_functions)\n\n    await function_d()\n    print(\"Adios\")\n\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/LucasRebuffo.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n * asíncrona una función que tardará en finalizar un número concreto de\n * segundos parametrizables. También debes poder asignarle un nombre.\n * La función imprime su nombre, cuándo empieza, el tiempo que durará\n * su ejecución y cuando finaliza.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han finalizado.\n */ \"\"\"\n\nimport datetime\nimport time\nimport asyncio\n\n\nasync def task(duration: int, name: str):\n    print(f\"Tarea {name}: Duracion: {duration} Inicio: {datetime.datetime.now()}\")\n\n    await asyncio.sleep(duration)\n\n    print(f\"Tarea {name}: Fin: {datetime.datetime.now()}\")\n\n\n# asyncio.run(task(5, \"Tarea 1\"))\n\n# asyncio.run(task(1,\"Tarea 2\"))\n# asyncio.run(task(3,\"Tarea 3\"))\n\nasync def async_tasks():\n    await asyncio.gather(task(3, \"Funcion C\"), task(2, \"Funcion B\"), task(1, \"Funcion A\"))\n    await task(1, \"Funcion D\")\n\nasyncio.run(async_tasks())\n\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/Lumanet.py",
    "content": "import datetime\nimport asyncio\n\nasync def cosa(nombre, duracion): # async se usa para definir una función asíncrona que puede contener una o más llamadas a await\n    print(f\"Tarea: {nombre}. Duración: {duracion}s. Inicio: {datetime.datetime.now()}\") \n    await asyncio.sleep(duracion) # await se usa para esperar a que se complete una tarea asíncrona\n    print(f\"Tarea: {nombre}. Fin: {datetime.datetime.now()}\")\n\nasyncio.run(cosa(\"Prueba\", 7)) # asyncio.run() se usa para ejecutar una función asíncrona\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\nUtilizando el concepto de asincronía y la función anterior, crea\nel siguiente programa que ejecuta en este orden:\n- Una función C que dura 3 segundos.\n- Una función B que dura 2 segundos.\n- Una función A que dura 1 segundo.\n- Una función D que dura 1 segundo.\n- Las funciones C, B y A se ejecutan en paralelo.\n- La función D comienza su ejecución cuando las 3 anteriores han finalizado.\n\"\"\"\n\nasync def tareas_asincronas():\n    await asyncio.gather(cosa(\"C\", 3), cosa(\"B\", 2), cosa(\"A\", 1)) # asyncio.gather() se usa para ejecutar varias tareas asíncronas en paralelo\n    await cosa(\"D\", 1) \n    \nasyncio.run(tareas_asincronas())"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/Nicojsuarez2.py",
    "content": "# #15 ASINCRONÍA\n> #### Dificultad: Difícil | Publicación: 08/04/24 | Corrección: 15/04/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n * asíncrona una función que tardará en finalizar un número concreto de\n * segundos parametrizables. También debes poder asignarle un nombre.\n * La función imprime su nombre, cuándo empieza, el tiempo que durará\n * su ejecución y cuando finaliza.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han\n *   finalizado.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/Nightblockchain30.py",
    "content": "# EJERCICIO:\n# Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n# asíncrona una función que tardará en finalizar un número concreto de\n# segundos parametrizables. También debes poder asignarle un nombre.\n# La función imprime su nombre, cuándo empieza, el tiempo que durará\n# su ejecución y cuando finaliza.\n#\n# DIFICULTAD EXTRA (opcional):\n# Utilizando el concepto de asincronía y la función anterior, crea\n# el siguiente programa que ejecuta en este orden:\n# - Una función C que dura 3 segundos.\n# - Una función B que dura 2 segundos.\n# - Una función A que dura 1 segundo.\n# - Una función D que dura 1 segundo.\n# - Las funciones C, B y A se ejecutan en paralelo.\n# - La función D comienza su ejecución cuando las 3 anteriores han\n#   finalizado.\n\nimport datetime\nimport asyncio\n\nasync def duration_task(name: str,duration: int):\n    start = datetime.datetime.now()\n\n    print(f\"Tarea {name.upper()} <<< INICIO: {datetime.datetime.now()}s\")\n\n    await asyncio.sleep(duration)\n\n    print(f\"{name.upper()}     >>> FIN:{datetime.datetime.now()}s\")        \n\n\nasyncio.run(duration_task(\"Correr\",3))\n\nasync def contexto_async():\n    await asyncio.gather(duration_task(\"C\",3),duration_task(\"B\",2),duration_task(\"A\",1))\n    await duration_task(\"D\",1)\n    \n\nasyncio.run(contexto_async())\n\n\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/Sac-Corts.py",
    "content": "import asyncio\nfrom datetime import datetime\n\nasync def async_task(nombre, duracion):\n    print(f\"{datetime.now()}: La tarea '{nombre}' empieza. Durará {duracion} segundos.\")\n    await asyncio.sleep(duracion)\n    print(f\"{datetime.now()}: La tarea '{nombre} ha terminado.\")\n\nasync def main():\n    tarea1 = asyncio.create_task(async_task(\"Tarea 1\", 3))\n    tarea2 = asyncio.create_task(async_task(\"Tarea 2\", 5))\n    tarea3 = asyncio.create_task(async_task(\"Tarea 3\", 2))\n    await   asyncio.gather(tarea1, tarea2, tarea3)\n\nasyncio.run(main())\n\n### Ejercicio Extra ###\n\nasync def final_task(nombre, duracion):\n    print(f\"{datetime.now()}: La tarea '{nombre}' empieza. Durará {duracion} segundos.\")\n    await asyncio.sleep(2)\n    print(f\"{datetime.now()}: La tarea '{nombre} ha terminado.\")\n    \n\nasync def main_extra():\n    tareas = [\n    asyncio.create_task(async_task(\"Función C\", 3)),\n    asyncio.create_task(async_task(\"Función B\", 2)),\n    asyncio.create_task(async_task(\"Función A\", 1)),\n    ]\n    await asyncio.wait(tareas)\n\n    await final_task(\"Función D\", 1)\n\nasyncio.run(main_extra())"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/SaezMD.py",
    "content": "#15 - Asincronía\n\"\"\"\n * EJERCICIO:\n * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera asíncrona una función que tardará en finalizar un número concreto de\n * segundos parametrizables. También debes poder asignarle un nombre.\n  La función imprime su nombre, cuándo empieza, el tiempo que durará su ejecución y cuando finaliza.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han finalizado.\n\"\"\"\nfrom datetime import datetime \n\nimport asyncio\nasync def nameAndWait(nameFunct: str, seconds: int) -> int:\n    \"\"\"function to wait\"\"\"\n\n    print(f\"Fucntion name: {nameFunct}\")\n    now = datetime.today().strftime('%d/%m/%Y %H:%M:%S')\n    print(f\"{nameFunct} Starting at: {now}\")\n    print(f\"{nameFunct} Wait for: {seconds} seconds.\")\n    await asyncio.sleep(seconds)\n    print(f\"{nameFunct} Ending at: {datetime.today().strftime('%d/%m/%Y %H:%M:%S')}\")\n\nasyncio.run(nameAndWait(\"Wait for five minutes...\",5))\n#asyncio.run(sumWithWait(20,2,2))\n\n#EXTRA:\nimport time\n\nasync def main():\n    \"\"\"calling the functions together\"\"\"\n    # testing\n    await asyncio.gather(\n        nameAndWait(\"C\", 3),\n        nameAndWait(\"B\", 1),\n        nameAndWait(\"A\", 1)\n    )\n\nasync def second():\n    \"\"\"calling more functions before\"\"\"\n    await asyncio.gather(\n        nameAndWait(\"D\", 1)\n    )\n\nif __name__ == \"__main__\":\n    init_time = time.time()\n\n    # strating main function\n    asyncio.run(main())\n    asyncio.run(second())\n\n    finish_time = time.time()\n\n    print(f\"\\nAll Excecution took: {round(finish_time - init_time, 3)} seconds.\")\n\n\n#extraMOURE\nasync def aync_tasks():\n    await asyncio.gather(nameAndWait(\"C\",3), nameAndWait(\"B\",2), nameAndWait(\"A\",1))\n    await nameAndWait(\"A\",1)\n\nasyncio.run(aync_tasks())\n\n\n\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/SooHav.py",
    "content": "# 15 ASINCRONÍA\n\n# Ejercicio\n\nimport asyncio\nimport time\n\n\nasync def ejecutar_tarea(tarea: str, duracion: int):\n    \"\"\"\n    Ejecuta una tarea asíncrona que espera durante un tiempo especificado.\n    Parametros:\n    - tarea (str): Nombre de la tarea.\n    - duracion (int): Duración en segundos que tarda la tarea.\n    \"\"\"\n    print(f'[{tarea}] Empieza la ejecución')\n    inicio = time.time()\n    await asyncio.sleep(duracion)\n    fin = time.time()\n    print(f'[{tarea}] Tiene una duración de {fin - inicio:.2f} segundos')\n    print(f'[{tarea}] Termina la ejecución.')\n\n\nasync def ejecutar_programa() -> None:\n    await asyncio.create_task(ejecutar_tarea('Tarea 1', 3))\n\nasyncio.run(ejecutar_programa())\n\n# Ejercicio Extra\n\n\nasync def ejecutar_tarea_2(tarea: str, duracion: int) -> None:\n    \"\"\"\n    Ejecuta una tarea asíncrona que espera durante un tiempo especificado.\n    Parametros:\n    - tarea (str): Nombre de la tarea.\n    - duracion (int): Duración en segundos que tarda la tarea.\n    \"\"\"\n    try:\n        print(f'[{tarea}] Empieza la ejecución')\n        inicio = time.time()\n        await asyncio.sleep(duracion)\n        fin = time.time()\n        print(f'[{tarea}] Tiene una duración de {fin - inicio:.2f} segundos')\n    except Exception as e:\n        print(f'[{tarea}] Error: {e}')\n    finally:\n        print(f'[{tarea}] Termina la ejecución.')\n\n\nasync def ejecutar_programa_2() -> None:\n    tareas = [\n        asyncio.create_task(ejecutar_tarea_2('C', 3)),\n        asyncio.create_task(ejecutar_tarea_2('B', 2)),\n        asyncio.create_task(ejecutar_tarea_2('A', 1))\n    ]\n    await asyncio.gather(*tareas)\n    await asyncio.create_task(ejecutar_tarea_2('D', 1))\n\nasyncio.run(ejecutar_programa_2())\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/adolfolozaa.py",
    "content": "'''\r\nEJERCICIO:\r\n * Crea una función que se encargue de sumar dos números y retornar\r\n * su resultado.\r\n * Crea un test, utilizando las herramientas de tu lenguaje, que sea\r\n * capaz de determinar si esa función se ejecuta correctamente.\r\n'''\r\nimport unittest\r\n\r\ndef sum(a, b):\r\n    if not isinstance(a, (int, float)) or not isinstance(b, (int, float)):\r\n        raise ValueError(\"Los argumentos deben ser enteros o decimales.\")\r\n    return a + b\r\n\r\n\r\nclass TestSum(unittest.TestCase):\r\n\r\n    def test_sum(self):\r\n        self.assertEqual(sum(5, 7), 12)\r\n        self.assertEqual(sum(5, -7), -2)\r\n        self.assertEqual(sum(0, 0), 0)\r\n        self.assertEqual(sum(2.5, 2.1), 4.6)\r\n        self.assertEqual(sum(2, 2.1), 4.1)\r\n        self.assertEqual(sum(2.5, 2.5), 5)\r\n\r\n    def test_sum_type(self):\r\n        with self.assertRaises(ValueError):\r\n            sum(\"5\", 7)\r\n        with self.assertRaises(ValueError):\r\n            sum(5, \"7\")\r\n        with self.assertRaises(ValueError):\r\n            sum(\"5\", \"7\")\r\n        with self.assertRaises(ValueError):\r\n            sum(\"a\", 7)\r\n        with self.assertRaises(ValueError):\r\n            sum(None, 7)\r\n#unittest.main()\r\n\r\n\r\n'''\r\n * DIFICULTAD EXTRA (opcional):\r\n * Crea un diccionario con las siguientes claves y valores:\r\n * \"name\": \"Tu nombre\"\r\n * \"age\": \"Tu edad\"\r\n * \"birth_date\": \"Tu fecha de nacimiento\"\r\n * \"programming_languages\": [\"Listado de lenguajes de programación\"]\r\n * Crea dos test:\r\n * - Un primero que determine que existen todos los campos.\r\n * - Un segundo que determine que los datos introducidos son correctos.'''\r\n\r\nfrom datetime import datetime, date\r\n\r\n\r\nclass TestData(unittest.TestCase):\r\n\r\n    def setUp(self) -> None:\r\n        self.data = {\r\n            'name': 'Adolfo',\r\n            'age': 56,\r\n            \"birth_date\": datetime.strptime(\"29-04-87\", \"%d-%m-%y\").date(),\r\n            'programing_languages': ['Python', 'Basic', 'C']\r\n        }\r\n\r\n    def test_fields_exist(self):\r\n        self.assertIn(\"name\", self.data)\r\n        self.assertIn(\"age\", self.data)\r\n        self.assertIn(\"birth_date\", self.data)\r\n        self.assertIn(\"programing_languages\", self.data)\r\n\r\n    def test_data_is_correct(self):\r\n        self.assertIsInstance(self.data[\"name\"], str)\r\n        self.assertIsInstance(self.data[\"age\"], int)\r\n        self.assertIsInstance(self.data[\"birth_date\"], date)\r\n        self.assertIsInstance(self.data[\"programing_languages\"], list)\r\n\r\n\r\nunittest.main()\r\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/adra-dev.py",
    "content": "\"\"\"\nEJERCICIO:\nUtilizando tu lenguaje, crea un programa capaz de ejecutar de manera \nasincrona una función que tardará en finalizar un número concreto de\nsegundos parametrizables. También debes poder asignarle un nombre.\nLa función imprime su nombre, cuándo empieza, el tiempo que durará\nsu ejecución y cuando finaliza.\n\nDIFICULTAD EXTRA (opcional):\nUtilizando el concepto de asincronía y la función anterior, crea\nel siguiente programa que ejecuta en este orden:\n- Una función C que dura 3 segundos.\n- Una función B que dura 2 segundos.\n- Una función A que dura 1 segundo.\n- Una función D que dura 1 segundo.\n- Las funciones C, B y A se ejecutan en paralelo.\n- La función D comienza su ejecución cuando las 3 anteriores han\nfinalizado.\n\nby adra-dev\n\"\"\"\n\n\n\"\"\"\nFunciones Asíncronas:\n\nDesde python 3.5 es posible crear funciones asíncronas utilizando las \npalabras reservadas async y wait. La primera se usa para definir que \nuna funcion es asíncrona, y la segunda, que el valor esperado es de \ntipo asíncrono.\n\nEl uso de la programacion asíncrona permite que una funcion no se \nejecute continuamente cuando este esperando a que un evento ocurra, \npor ejemplo, que haya una respuesta desde una peticion web, una \nrespuesta de una consulta a una base de datos, apertura de un fichero\nen disco o cualquier otro tipo de acceso a un sistema o proceso que \nprovoque que la funcion deba esperar haciendo una operacion de \nentrada/salida y pueda cambiar de contexto hasta que el recurso este \ndisponible.\n\"\"\"\n\nimport asyncio\nimport datetime\n\n\"\"\"\nEjercicio\n\"\"\"\n\n\"\"\"\nEjercicio\n\"\"\"\n\n\nasync def task(name: str, duration: int):\n    print(\n        f\"Tarea: {name}. Duración: {duration}s. Inicio: {datetime.datetime.now()}\")\n    await asyncio.sleep(duration)\n    print(\n        f\"Tarea: {name}. Fin: {datetime.datetime.now()}\")\n\n\nasyncio.run(task(\"1\", 2))\n\n\"\"\"\nExtra\n\"\"\"\n\n\nasync def async_tasks():\n    await asyncio.gather(task(\"C\", 3), task(\"B\", 2), task(\"A\", 1))\n    await task(\"D\", 1)\n\nasyncio.run(async_tasks())"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/agusrosero.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n * asíncrona una función que tardará en finalizar un número concreto de\n * segundos parametrizables. También debes poder asignarle un nombre.\n * La función imprime su nombre, cuándo empieza, el tiempo que durará\n * su ejecución y cuando finaliza.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han\n *   finalizado.\n */\n\"\"\"\nimport asyncio\n\n\"\"\"EJERCICIO:\"\"\"\n\n\nasync def main(seconds):\n    print('Hernan ...')\n    await asyncio.sleep(seconds)\n    print('Fin de la ejecucion!')\n\nasyncio.run(main(2))\n\n\"\"\"DIFICULTAD EXTRA:\"\"\"\n\n\nasync def funcion_C():\n    print('Funcion C')\n    await asyncio.sleep(3)\n\n\nasync def funcion_B():\n    print('Funcion B')\n    await asyncio.sleep(2)\n\n\nasync def funcion_A():\n    print('Funcion A')\n    await asyncio.sleep(1)\n\n\nasync def funcion_D():\n    print('Funcion D')\n    await asyncio.sleep(1)\n\n\nasync def test():\n    await asyncio.gather(funcion_C(), funcion_B(), funcion_A())\n    await funcion_D()\n\nasyncio.run(test())\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/alanshakir.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n * asíncrona una función que tardará en finalizar un número concreto de\n * segundos parametrizables. También debes poder asignarle un nombre.\n * La función imprime su nombre, cuándo empieza, el tiempo que durará\n * su ejecución y cuando finaliza.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han\n *   finalizado.\n */\n\"\"\"\nimport asyncio\n\nasync def fun_asyn(name: str, wait_seconds: int):\n    print(f\"La funcion {name}, tiene una duracion de: {wait_seconds}\")\n    await asyncio.sleep(wait_seconds)\n    print(f\"ha finalizado la ejecucion: {name}\") \n\nasyncio.run(fun_asyn(\"Alan Ramirez\", 1))\n#Extra\n\nasync def multitask():\n    await asyncio.gather(fun_asyn(\"C\", 3), fun_asyn(\"B\", 2), fun_asyn(\"A\", 1))\n    await fun_asyn(\"D\", 1)\n\nasyncio.run(multitask())\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/any7dev.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n * asíncrona una función que tardará en finalizar un número concreto de\n * segundos parametrizables. También debes poder asignarle un nombre.\n * La función imprime su nombre, cuándo empieza, el tiempo que durará\n * su ejecución y cuando finaliza.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han\n *   finalizado.\n */ \"\"\"\n\n#EJERCICIO\nimport asyncio\nimport time\n\nasync def funcion_asincrona(segundos):\n    nombre = \"Hola Mundo asíncrono\"\n    print(nombre)\n    print(time.strftime(\"%H:%M:%S\"))\n    print(segundos)\n    await asyncio.sleep(segundos)    \n    print(time.strftime(\"%H:%M:%S\"))\n\nasyncio.run(funcion_asincrona(3))\n\n#DIFICULTAD EXTRA\nasync def funcion_a():\n    print(\"Soy la función A\")\n    await asyncio.sleep(1)\n\nasync def funcion_b():\n    print(\"Soy la función B\")\n    await asyncio.sleep(2)\n\nasync def funcion_c():\n    print(\"Soy la función C\")\n    await asyncio.sleep(3)\n\nasync def funcion_d():\n    print(\"Soy la función D\")\n    await asyncio.sleep(1)\n\nasync def extra():\n    await asyncio.gather(funcion_a(), funcion_b(), funcion_c())\n    await funcion_d()\n    \n\nasyncio.run(extra())\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/avcenal.py",
    "content": "import asyncio\nimport time\n\n\"\"\"\n* EJERCICIO:\n * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n * asíncrona una función que tardará en finalizar un número concreto de\n * segundos parametrizables. También debes poder asignarle un nombre.\n * La función imprime su nombre, cuándo empieza, el tiempo que durará\n * su ejecución y cuando finaliza.\n\"\"\"\n\nasync def async_func(secs,name):\n    print(f\"El nombre de la función es {name} y va a tardar {secs} segundos en ejecutarse\")\n    print(f\"La hora de inicio es {time.strftime(\"%X\")}\")\n    await asyncio.sleep(secs)\n    print(f\"La hora de fin es {time.strftime(\"%X\")}\")\n    \n\nasyncio.run(async_func(3,\"test\"))\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han finalizado.\n\"\"\"\nasync def A ():\n    await asyncio.sleep(1)\n    print(f\"ejecutada función A a las {time.strftime(\"%X\")}\")\nasync def B ():\n    await asyncio.sleep(2)\n    print(f\"ejecutada función B a las {time.strftime(\"%X\")}\")\nasync def C ():\n    await asyncio.sleep(3)\n    print(f\"ejecutada función C a las {time.strftime(\"%X\")}\")\n\nasync def D():\n    print(f\"Inicio: {time.strftime(\"%X\")}\")\n    task1 = asyncio.create_task(A())\n    task2 = asyncio.create_task(B())\n    task3 = asyncio.create_task(C())\n    await task1\n    await task2\n    await task3\n    print(f\"ejecutada función D a las {time.strftime(\"%X\")}\")\n\nasyncio.run(D())\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/cesar-ch.py",
    "content": "\"\"\"\n    * #15 ASINCRONÍA\n\"\"\"\n\nimport asyncio\n\n\nasync def ejecutar_tarea(nombre, duracion):\n    print(f\"Tarea {nombre} iniciada\")\n    await asyncio.sleep(duracion)\n    print(f\"Tarea {nombre} finalizada\")\n\n\n\"\"\"\n    * DIFICULTAD EXTRA\n\"\"\"\n\n\nasync def main():\n    tarea_c = ejecutar_tarea(\"C\", 3)\n    tarea_b = ejecutar_tarea(\"B\", 2)\n    tarea_a = ejecutar_tarea(\"A\", 1)\n\n    await asyncio.gather(tarea_c, tarea_b, tarea_a)\n    print(\"Tareas A, B y C finalizadas. Iniciando tarea D...\")\n    await ejecutar_tarea(\"D\", 1)\n\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/cristianfloyd.py",
    "content": "import asyncio\nimport datetime\n\n# Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n# asíncrona una función que tardará en finalizar un número concreto de\n# segundos parametrizables. También debes poder asignarle un nombre.\n# La función imprime su nombre, cuándo empieza, el tiempo que durará\n# su ejecución y cuando finaliza.\n\nasync def funcion_asincrona(tarea: str, tiempo: int) -> None:\n    \"\"\"\n    Args: tarea : string con el nombre de la tarea\n          tiempo: entero en segundos, tiempo que tardara en finalizar\n    \"\"\"\n    print(f\"Tarea: {tarea} - Inicio: {datetime.datetime.now().strftime(format='%H:%M:%S')}\")\n    await asyncio.sleep(tiempo)\n    print(f\"Tarea: {tarea} - Fin: {datetime.datetime.now().strftime(format='%H:%M:%S')}\")\n    print(f\"Tarea: {tarea} - Duración: {tiempo} segundos\")\n\nasync def main():\n    await funcion_asincrona(tarea=\"Tarea 1\", tiempo=3)\n    await funcion_asincrona(tarea=\"Tarea 2\", tiempo=2)\n    await funcion_asincrona(tarea=\"Tarea 3\", tiempo=1)\n\nasyncio.run(main())\n\n#\n# DIFICULTAD EXTRA (opcional):\n# Utilizando el concepto de asincronía y la función anterior, crea\n# el siguiente programa que ejecuta en este orden:\n# - Una función C que dura 3 segundos.\n# - Una función B que dura 2 segundos.\n# - Una función A que dura 1 segundo.\n# - Una función D que dura 1 segundo.\n# - Las funciones C, B y A se ejecutan en paralelo.\n\nasync def main_extra():\n    await asyncio.gather(\n        funcion_asincrona(tarea=\"C\", tiempo=3),\n        funcion_asincrona(tarea=\"B\", tiempo=2),\n        funcion_asincrona(tarea=\"A\", tiempo=1)\n    )\n    await funcion_asincrona(tarea=\"D\", tiempo=1)\n\nasyncio.run(main_extra())"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/danielhdzr.py",
    "content": "# #15 ASINCRONÍA\n#### Dificultad: Difícil | Publicación: 08/04/24 | Corrección: 15/04/24\n\n## Ejercicio\n\n\n''' * EJERCICIO:\n * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n * asíncrona una función que tardará en finalizar un número concreto de\n * segundos parametrizables. También debes poder asignarle un nombre.\n * La función imprime su nombre, cuándo empieza, el tiempo que durará\n * su ejecución y cuando finaliza.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han\n *   finalizado.'''\n\nimport asyncio, datetime\n\ndef main():\n    async def tarea(nombre: str, duerme: int, ejecuta: int, lock: asyncio.Lock):\n        async with lock:\n            print(f\"Tarea {nombre} comenzara en {duerme} segundos \") \n            print(f\"Tarea {nombre} comenzando en\", end=\"\")\n            for i in range(duerme, 0, -1):\n                await asyncio.sleep(1)\n                print(f\" {i}...\", end=\"\", flush=True)\n            print(\"\\n\")\n\n        async with lock: \n            print(f\"Tarea {nombre} comenzo a las {datetime.datetime.now()}\")\n            print(f\"Tarea {nombre} ejecutando\", end=\"\")\n            for i in range(ejecuta, 0, -1):\n                await asyncio.sleep(1)\n                print(f\" {i}...\", end=\"\", flush=True)\n            print(\"\\n\")\n\n        async with lock:\n            print(f\"Tarea {nombre} ha finalizado\")\n            print(f\"Tarea {nombre} finalizo a las {datetime.datetime.now()}\")\n\n    async def ejecutable():\n        lock = asyncio.Lock()\n        await asyncio.gather(\n            tarea(\"C\", 2, 1, lock),\n            tarea(\"B\", 2, 2, lock),\n            tarea(\"A\", 2, 3, lock)\n        )\n        # Ejecutar una tarea después de que las anteriores hayan terminado\n        await tarea(\"D\", 2, 1, lock)\n\n    asyncio.run(ejecutable())\nif __name__==\"__main__\":\n    main()"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/davidrguez98.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n * asíncrona una función que tardará en finalizar un número concreto de\n * segundos parametrizables. También debes poder asignarle un nombre.\n * La función imprime su nombre, cuándo empieza, el tiempo que durará\n * su ejecución y cuando finaliza.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han\n *   finalizado.\n */ \"\"\"\n\n#EJERCICIO\nimport datetime\nimport time\nimport asyncio\n\nasync def task(name: str, duration: int):\n\n    print(f\"Tarea: {name}. Duración: {duration}s. Inicio: {datetime.datetime.now()}\")\n    await asyncio.sleep(duration)\n    print(f\"Tarea: {name}. Fin: {datetime.datetime.now()}\")\n\nasyncio.run(task(\"1\", 2))\n\n#DIFICULTAD EXTRA\n\nasync def async_tasks():\n    await asyncio.gather(task(\"C\", 3), task(\"B\", 2), task(\"A\", 1))\n\nasyncio.run(async_tasks())\nasyncio.run(task(\"D\", 1))"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/didacdev.py",
    "content": "import time\nfrom datetime import datetime\nimport asyncio\n\n\nasync def main():\n    # await asyn_function(3)\n    await asyncio.gather(C(), B(), A())\n    await D()\n\n\nasync def asyn_function(seconds: int):\n    start = datetime.now()\n    print(f\"Ejecutando la funcion asyn_function\")\n    print(f\"Comienzo: {start}\")\n    asyncio.sleep(seconds)\n    finish = datetime.now()\n    print(f\"Fin: {finish}\")\n    print(f\"Duración: {round((finish - start).seconds, 0)} segundos\")\n\n\nasync def A():\n    await asyncio.sleep(1)\n    print(\"Función A finalizada\")\n\n\nasync def B():\n    await asyncio.sleep(2)\n    print(\"Función B finalizada\")\n\n\nasync def C():\n    await asyncio.sleep(3)\n    print(\"Función C finalizada\")\n\n\nasync def D():\n    await asyncio.sleep(1)\n    print(\"Función D finalizada\")\n\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/duendeintemporal.py",
    "content": "#15 { Retos para Programadores } ASINCRONÍA\n\n# Bibliography reference\n# Professional JavaScript for web developers by Matt Frisbie [Frisbie, Matt] (z-lib.org)\n#Python Notes for Professionals. 800+ pages of professional hints and tricks (GoalKicker.com) (Z-Library)\n# Additionally, I use GPT as a reference and sometimes to correct or generate proper comments.\n\n\"\"\"  \n* EJERCICIO:\n * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n * asíncrona una función que tardará en finalizar un número concreto de\n * segundos parametrizables. También debes poder asignarle un nombre.\n * La función imprime su nombre, cuándo empieza, el tiempo que durará\n * su ejecución y cuando finaliza.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han finalizado.\n \n\"\"\"\n\nimport time\nimport threading\n\n# Short for print()\nlog = print\n\ndef run_func(name, seconds):\n    log(f\"{name} - Start at: {time.strftime('%H:%M:%S')}\")\n    log(f\"{name} - Last: {seconds} seconds\")\n\n    time.sleep(seconds)\n\n    log(f\"{name} - Ends at: {time.strftime('%H:%M:%S')}\")\n\ndef run_funces():\n    # Create threads for each function to run concurrently\n    function_c = threading.Thread(target=run_func, args=('Function C', 3))\n    function_b = threading.Thread(target=run_func, args=('Function B', 2))\n    function_a = threading.Thread(target=run_func, args=('Function A', 1))\n\n    # Start all threads\n    function_c.start()\n    function_b.start()\n    function_a.start()\n\n    # Wait for all threads to complete\n    function_c.join()\n    function_b.join()\n    function_a.join()\n\n    # Run Function D after A, B, and C have completed\n    run_func('Function D', 1)\n\n# Simulate the loading of a web page\ntime.sleep(2)  # Simulate a delay before showing the alert\nlog('Retosparaprogramadores #15')\n\nrun_funces()\n\n# Output Example:\n\"\"\"  \nRetosparaprogramadores #15\nFunction C - Start at: 07:27:35\nFunction C - Last: 3 seconds\nFunction B - Start at: 07:27:35\nFunction B - Last: 2 seconds\nFunction A - Start at: 07:27:35\nFunction A - Last: 1 seconds\nFunction A - Ends at: 07:27:36\nFunction B - Ends at: 07:27:37\nFunction C - Ends at: 07:27:38\nFunction D - Start at: 07:27:38\nFunction D - Last: 1 seconds\nFunction D - Ends at: 07:27:39\n\n\"\"\"\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/fborjalv.py",
    "content": "import asyncio\nimport datetime\n\nasync def my_func(name, duration):\n    print(f\"Nombre de la función: {name}. Duración: {duration} segundos. Inicio: {datetime.datetime.now()}\")\n    await asyncio.sleep(duration)\n    print(f\"Nombre de la función: {name}. Fin: {datetime.datetime.now()}\")\n\nasyncio.run(my_func(\"A\", 2))\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han finalizado.\n\n\"\"\"\n# EJECUCIÓN EN PARALELO (GATHER)\n\nasync def async_funcs():\n    await asyncio.gather(my_func(\"C\", 3),my_func(\"B\", 2),my_func(\"A\", 1))\n    await my_func(\"D\", 1)\nasyncio.run(async_funcs())\n\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/garos01.py",
    "content": "import asyncio\n\n\nasync def ejecutar_tarea(nombre, segundos):\n    print(f\"{nombre}: Comenzando la tarea.\")\n    await asyncio.sleep(segundos)\n    print(f\"{nombre}: Tarea completada después de {segundos} segundos.\")\n\n\nasync def main():\n    # Definir las tareas que se ejecutarán de manera asíncrona\n    tarea1 = ejecutar_tarea(\"Tarea 1\", 3)\n    tarea2 = ejecutar_tarea(\"Tarea 2\", 5)\n    tarea3 = ejecutar_tarea(\"Tarea 3\", 2)\n\n    # Ejecutar las tareas de manera simultánea\n    await asyncio.gather(tarea1, tarea2, tarea3)\n\n\n# Iniciar el bucle de eventos de asyncio y ejecutar el programa\nasyncio.run(main())\n\n\n# Ejercicio extra\n\n\nasync def funcion_a():\n    print(\"Función A: Comenzando la ejecución.\")\n    await asyncio.sleep(1)\n    print(\"Función A: Finalizada.\")\n\n\nasync def funcion_b():\n    print(\"Función B: Comenzando la ejecución.\")\n    await asyncio.sleep(2)\n    print(\"Función B: Finalizada.\")\n\n\nasync def funcion_c():\n    print(\"Función C: Comenzando la ejecución.\")\n    await asyncio.sleep(3)\n    print(\"Función C: Finalizada.\")\n\n\nasync def funcion_d():\n    print(\"Función D: Esperando a que finalicen las funciones C, B y A.\")\n    await asyncio.gather(funcion_c(), funcion_b(), funcion_a())\n    print(\n        \"Función D: Todas las funciones C, B y A han finalizado. Comenzando ejecución.\"\n    )\n    await asyncio.sleep(1)\n    print(\"Función D: Finalizada.\")\n\n\nasync def main():\n    await asyncio.gather(funcion_c(), funcion_b(), funcion_a(), funcion_d())\n\n\nasyncio.run(main())\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/ggilperez.py",
    "content": "# 15 Async\nimport asyncio\nfrom datetime import datetime\n\n\nasync def async_function(sleep_time: int, name: str) -> None:\n    print(f\"Function {name}. Starting at: {datetime.utcnow()}. Duration {sleep_time}\")\n\n    await asyncio.sleep(sleep_time)\n\n    print(f\"Function {name}. Ending at: {datetime.utcnow()}\")\n\nasyncio.run(async_function(2, \"slow_func\"))\n\n# Extra\n\nasync def run_tasks():\n    await asyncio.gather(async_function(3, \"C\"), async_function(2, \"B\"), async_function(1, \"A\"))\n    await async_function(1, \"D\")\n\nasyncio.run(run_tasks())\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/gringoam.py",
    "content": "import datetime\nimport time\nimport asyncio\n\"\"\"\nEjercicio\n\"\"\"\n\n\nasync def tarea(nombre: str, duracion: int):\n    print(f\"Tarea: {nombre} duración: {duracion}s. Inicio {datetime.datetime.now()} \")\n    await asyncio.sleep(duracion)\n    print(f\"Tarea: {nombre} Fin: {datetime.datetime.now()} \")\n\n#asyncio.run(tarea(\"1\", 5))\n\n\"\"\"\nExtra\n\"\"\"\n\nasync def tareas_asincronas():\n    await asyncio.gather(tarea(\"C\", 5),\n    tarea(\"B\", 2),\n    tarea(\"A\", 1)\n    )\n    await tarea(\"D\", 1)\n    \n\n \nasyncio.run(tareas_asincronas())\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/hectorio23.py",
    "content": "# /bin/python3\n# Author: Héctor Adán \n# GitHub: https://github.com/hectorio23\n\nimport asyncio\nimport time\n\n'''\n* EJERCICIO:\n* Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n* asíncrona una función que tardará en finalizar un número concreto de\n* segundos parametrizables. También debes poder asignarle un nombre.\n* La función imprime su nombre, cuándo empieza, el tiempo que durará\n* su ejecución y cuando finaliza.\n*\n* DIFICULTAD EXTRA (opcional):\n* Utilizando el concepto de asincronía y la función anterior, crea\n* el siguiente programa que ejecuta en este orden:\n* - Una función C que dura 3 segundos.\n* - Una función B que dura 2 segundos.\n* - Una función A que dura 1 segundo.\n* - Una función D que dura 1 segundo.\n* - Las funciones C, B y A se ejecutan en paralelo.\n* - La función D comienza su ejecución cuando las 3 anteriores han\n*   finalizado.\n'''\n\nasync def imprimir_nombre(delay: int, name: str ) -> None:\n    '''\n    Esta corrutina esta diseñada para que se ingresen los datos correctos,\n    de lo contrario, dará un error porque no se implementaron validaciones.\n    '''\n    print(f\"Hola { name }, es un gusto verte de nuevo por aqui!\")\n    print(f\"Espera { delay } seg\")\n    await asyncio.sleep(delay)\n\n\n# Corrutina -> Funcion Asincrona en python\nasync def do_something(name: str, delay:int) -> None:\n    print(f\"Una funcion { name } que dura { delay } segundos\")\n    await asyncio.sleep(delay)\n\n\nasync def main() -> None:\n    # Creating a Task group for schedule the tasks\n    # Task Group es la mejor manera para ejecutar tareas asincronas de manera\n    # concurrente\n    async with asyncio.TaskGroup() as tg:\n        print(f\"Iniciando la ejecucion concurrente de las tareas C,B y A en: { time.strftime('%X') }\")\n        tg.create_task(do_something(\"C\", 3), name=\"Task C\")\n        tg.create_task(do_something(\"B\", 2), name=\"Task B\")\n        tg.create_task(do_something(\"A\", 1), name=\"Task A\")\n        # Las tareas se ejcutan de manera implicita cuando se sale del manejador de contexto\n    \n    print(f\"Finalizando la ejecucion de las tareas C,B y A en: { time.strftime('%X') }\")\n\n    # La tarea C se ejecuta cuando las demas tareas se hayan ejecutado, ya que\n    # al no formar parte del grupo, no se ejecuta de manera concurrente con las\n    # tareas anteriores.\n    await do_something(\"D\", 1 )\n\n\n# Se crea un gestor de contexto asincrono para ejecutar la corrutine principal.\n# Tambien de puede crear una corrutina de la siguiente manera:\n# asyncio.run(coro())\n# Los argumentos debug -> default: None, loop_factory -> default: new_event_loop() se pueden omitir \nwith asyncio.Runner(debug=True, loop_factory=asyncio.new_event_loop) as runner:\n    # Codigo que da resolucion al ejercicio de la semana\n    print(\"Ejecucion del ejercicio de la semana\")\n    name = input(\"Ingresa tu nombre: \")\n    delay = int(input(\"Ingresa el tiempo de retraso: \"))\n    runner.run(imprimir_nombre(delay, name))\n\n    # Ejecucion para la resolucion del ejercicio extra\n    print(\"\\nEjecucion del EJERCICIO EXTRA\")\n    runner.run(main())\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/hozlucas28.py",
    "content": "import asyncio\n\n\n\"\"\"\n    Asynchrony...\n\"\"\"\n\nprint(\"Asynchrony...\")\n\n\nasync def parallel_instructions(*, sleep_time: int) -> None:\n    \"\"\"Parallel instructions\"\"\"\n    print(\"\\nparallel_instructions start...\")\n\n    await asyncio.sleep(delay=sleep_time)\n    print(\"\\n> Parallel instructions executed\")\n\n    print(f\"\\nparallel_instructions: {sleep_time} seconds of execution\")\n    print(\"\\nparallel_instructions end!\")\n\n\nasync def async_fn(*, sleep_time: int) -> None:\n    \"\"\"Async function example\"\"\"\n    print(\"\\nasyncFn start...\")\n\n    await asyncio.sleep(delay=sleep_time)\n\n    print(f\"\\nasyncFn: {sleep_time} seconds of execution\")\n    print(\"\\nasyncFn end!\")\n\n\nasync def main_challenge() -> None:\n    \"\"\"Main challenge function\"\"\"\n    await asyncio.gather(\n        parallel_instructions(sleep_time=2),\n        async_fn(sleep_time=5),\n    )\n\n    print(\"\\nmain_challenge: 5 seconds to execute async_fn and parallel_instructions\")\n\n\nasyncio.run(main=main_challenge())\n\n\n\"\"\"\n    Additional challenge...\n\"\"\"\n\nprint(\n    \"\\n# ---------------------------------------------------------------------------------- #\\n\"\n)\n\nprint(\"Additional challenge...\")\n\n\nasync def delayed_fn(*, sleep_time: int, title: str) -> None:\n    \"\"\"Asynchronous function\"\"\"\n    await asyncio.sleep(delay=sleep_time)\n    print(f\"\\n{title}: {sleep_time} seconds of execution\")\n\n\nasync def main_additional_challenge() -> None:\n    \"\"\"Main additional challenge function\"\"\"\n    await asyncio.gather(\n        delayed_fn(sleep_time=1, title=\"A\"),\n        delayed_fn(sleep_time=2, title=\"B\"),\n        delayed_fn(sleep_time=3, title=\"C\"),\n    )\n\n    await delayed_fn(sleep_time=1, title=\"D\")\n\n    print(\"\\nmain_additional_challenge: 4 seconds to execute A, B, C, and D\")\n\n\nasyncio.run(main=main_additional_challenge())\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/idiegorojas.py",
    "content": "# Asincronia\n\n\"\"\"\nCalves de la asincronia:\n\n* Coroutines: \n    Se definen con la palabra 'async def'\n    Suspenden o reanudan una ejecucion en puntos especificos usando 'await'\n* Await: \n    Se usa dentro de una coroutina para suspender una ejecucion \n    Solamente puede ser usada dentro de una funcion \n* Event Loop:\n    Administra las coroutina esperando y ejecutando las tareas asincronicas en el orden correcto\n    Se puede usar 'asyncio' para manejar el evento loop\n* Asyncio:\n    Proporsiona la infraestructura para escribir codigo asincronico\n\"\"\"\n\n# Importar el modulo\nimport asyncio\n\nasync def main():\n    print('Hola ...')\n    await asyncio.sleep(5)\n    print('... mundo.')\n\nasyncio.run(main())\n\n\n# Ejercicio\nimport asyncio\nimport datetime\n\nasync def tarea(nombre: str, duracion: int):\n    print(f'Tarea: {nombre}. Duracion: {duracion}')\n    print(f'Inicio: {datetime.datetime.now()}')\n    await asyncio.sleep(duracion)\n    print(f'Tarea: {nombre}. Duracion: {duracion}')\n    print(f'Finalizo: {datetime.datetime.now()}')\n\nnombre_tarea = 'Tarea 1'\nduracion_tarea = 5\n\nasyncio.run(tarea(nombre_tarea, duracion_tarea))\n\nasync def tareas():\n    await asyncio.gather(tarea('A', 1),tarea('B', 2),tarea('C', 3))\n    await tarea('D', 1)\n\nasyncio.run(tareas())"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/ignaciovihe.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n * asíncrona una función que tardará en finalizar un número concreto de\n * segundos parametrizables. También debes poder asignarle un nombre.\n * La función imprime su nombre, cuándo empieza, el tiempo que durará\n * su ejecución y cuando finaliza.\n\"\"\"\n\nimport asyncio\nfrom datetime import datetime\n\nasync def task(name, seconds):\n    start = datetime.now()\n    print(f\"La tarea {name} empieza en {start}\")\n    print(f\"La tarea {name} se ejecuta durante {seconds} segundos\")\n    await asyncio.sleep(seconds)\n    finish = datetime.now()\n    print(f\"La tarea {name} termina en {finish}\")\n\nasyncio.run(task(\"1\", 5))\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han\n *   finalizado.\n\"\"\"\n\nasync def async_tasks():\n    # Se crea una tarea en segundo plano que no para a las demas. No pedido en el ejercicio.\n    tarea_grande = asyncio.create_task(task(\"SEGUNDO PLANO\",6)) #para probar\n\n    await asyncio.gather(task(\"C\", 3), task(\"B\", 2), task(\"A\", 1))\n    await task(\"D\", 1)\n    await tarea_grande\n\nasyncio.run(async_tasks())\n\n\n\n\n\n\n\n\n\n\"\"\"\nPruebas adicionales\n\"\"\"\n\"\"\"Ejemplo funciones asincronas y sincronas al mismo tiempo\"\"\"\nimport asyncio\nimport time  #Importamos time para medir el tiempo\n\n# Simula la consulta a la base de datos (tarda 2 seg)\nasync def leer_bd(nombre_bd):\n    print(f\"Consultando {nombre_bd}...\")\n    await asyncio.sleep(5)  # Simula el tiempo de consulta\n    return f\"Datos de {nombre_bd}\"  # Simula datos obtenidos\n\n# Simula el procesamiento de datos (bloqueante)\ndef procesar_datos(datos):\n    print(f\"Procesando {datos}...\")\n    return f\"{datos} - Procesado\"\n\n# Simula guardar datos en la base de datos (tarda 2 seg)\nasync def guardar_bd(nombre_bd, datos):\n    print(f\"Guardando en {nombre_bd}: {datos}...\")\n    await asyncio.sleep(5)  # Simula el tiempo de guardado\n    print(f\"Datos guardados en {nombre_bd}.\")\n\n# Función principal\nasync def main():\n\n    inicio = time.perf_counter()  #Iniciamos el cronómetro\n\n    nombres_bd = [\"DB1\", \"DB2\", \"DB3\", \"DB4\", \"DB5\"]\n\n    # Leer de las 5 bases de datos en paralelo\n    resultados = await asyncio.gather(*(leer_bd(nombre) for nombre in nombres_bd))\n\n    # Procesar cada conjunto de datos (esto es síncrono)\n    datos_procesados = [procesar_datos(datos) for datos in resultados]\n\n    # Guardar los datos procesados en las 5 bases de datos en paralelo\n    await asyncio.gather(*(guardar_bd(nombre, datos) for nombre, datos in zip(nombres_bd, datos_procesados)))\n\n    fin = time.perf_counter()  #Finalizamos el cronómetro\n    print(f\"\\n Tiempo total de ejecución: {fin - inicio:.2f} segundos\")\n\n# Ejecutar\nasyncio.run(main())\n\n\n\"\"\"\nEjemplo real lectura de ficheros\nFunciona mejor con ficheros grandes y dependiendo del tamaño de bloque\nDe todos modos la mejora del asincrono no es demasido visible.\n\"\"\"\nimport aiofiles\nimport asyncio\nimport time\n\n# Función para leer un archivo en bloques de tamaño 'block_size' de manera asincrónica.\n# Al usar yield se \"convierte\" en un generador asincrónico.\nasync def read_file_in_chunks(file_name: str, block_size: int):\n    async with aiofiles.open(file_name, \"r\") as file:\n        while True:\n            chunk = await file.read(block_size)\n            if not chunk:\n                break\n            yield chunk  # Devuelve cada bloque leído\n\n# Función para escribir en un archivo de manera asincrónica\nasync def write_file(file_name: str, content: str):\n    async with aiofiles.open(file_name, \"a\") as file:\n        await file.write(content)\n\n# Función principal asincrónica\nasync def main():\n    block_size = 256 * 1024  # Tamaño del bloque en bytes (1 MB en este caso)\n    files_to_read = [\"1.txt\", \"2.txt\"]  # Lista de archivos a leer\n\n    inicio = time.perf_counter()  # Inicia el cronómetro\n    tasks = []  # Lista para almacenar las tareas asincrónicas\n\n    # Para cada archivo, lee en bloques de manera asincrónica y escribe el contenido\n    for file_name in files_to_read:\n        async for chunk in read_file_in_chunks(file_name, block_size): #\"async for\" ejecuta un generador asincrono(ya contiene el await)\n            tasks.append(write_file(\"result_a.txt\", chunk))     # Agrega tarea de escritura a la lista\n                                                                # Al estar definida como async se genera un objeto corutine\n    # Ejecuta todas las tareas de escritura de manera asincrónica\n    await asyncio.gather(*tasks)\n\n    fin = time.perf_counter()  # Finaliza el cronómetro\n    print(f\"\\nTiempo total de ejecución asincrona: {fin - inicio:.10f} segundos\")\n\n# Ejecuta la función principal asincrónica\nasyncio.run(main())\n\n\"\"\"Con lectura/escritura sincrona\"\"\"\ndef read_file_s(file_name: str):\n    with open(file_name, \"r\") as file: #Abro el fichero en un contexto asincrono.\n        return file.read()\n    \ndef write_file_s(file_name: str, content: str):\n    with open(file_name, \"a\") as file:\n        for paragraph in content:\n            file.write(paragraph)\n            file.write(\"\\n\")\n\nfiles_to_read = [\"1.txt\", \"2.txt\"]\n\ndef main():\n    inicio = time.perf_counter()\n    paragraphs= []\n    for item in files_to_read:\n        paragraphs.append(read_file_s(item))\n    write_file_s(\"result_s.txt\", paragraphs)\n    fin = time.perf_counter()  #Finalizamos el cronómetro\n    print(f\"\\n Tiempo total de ejecución sincrona: {fin - inicio:.10f} segundos\")\n\nmain()"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/isilanes.py",
    "content": "import asyncio\n\n\nasync def async_func(name: str, delay: int) -> None:\n    print(f\"[{name.upper()}] Empezamos a ejecutar {name}, que tardará {delay} segundos\")\n    await asyncio.sleep(delay)\n    print(f\"[{name.upper()}] Hemos tardado {delay} segundos en terminar\")\n\n\nasync def main(delay: int) -> None:\n    print(\"==== MAIN ====\")\n    coro = async_func(\"tontería\", delay)\n    print(\"Hemos definido la corrutina, pero todavía no se está ejecutando nada\")\n\n    task = asyncio.create_task(coro)\n    print(\"Definimos una tarea con la corrutina, y empieza a ejecutar\")\n\n    await asyncio.sleep(0.1)\n    print(\"Hemos esperado 0.1s para que este print salga tras arrancar la corrutina e imprimir la línea anterior.\")\n\n    print(\"Ahora esperamos a que la tarea termine...\")\n    await task\n\n    print(\"Tras el await, la tarea ya terminó\")\n\n\nasync def extra() -> None:\n    print(\"==== EXTRA ====\")\n    coros = [\n        async_func(\"C\", 3),\n        async_func(\"B\", 2),\n        async_func(\"A\", 1),\n        async_func(\"D\", 1),\n    ]\n    print(\"Corrutinas definidas...\")\n\n    tasks = [asyncio.create_task(c) for c in coros[:3]]\n    print(\"Tareas arrancadas...\")\n\n    await asyncio.gather(*tasks)\n    print(\"Tareas terminadas. Arrancamos la D...\")\n    await coros[3]\n\n\nif __name__ == \"__main__\":\n    asyncio.run(main(delay=3))\n    asyncio.run(extra())\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/juanchernandezdev.py",
    "content": "### Async Python ###\nimport asyncio\nimport time\n\nasync def first_function(name: str, seconds: int):\n  print(f'{name}, function started, run time will be {seconds}.')\n  start = time.time()\n  await asyncio.sleep(seconds)\n  timelapse = time.time() - start\n  print(f'execution time: {timelapse:.2f}s')\n\nasync def test():\n  await first_function('my test function', 2)\n\nasyncio.run(test())\n\n#! Optional Challenge\n\nasync def function_a():\n  start = time.time()\n  await asyncio.sleep(1)\n  timelapse = time.time() - start\n  print(f'Function A execution time: {timelapse:.2f}s')\n  \nasync def function_b():\n  start = time.time()\n  await asyncio.sleep(2)\n  timelapse = time.time() - start\n  print(f'Function B execution time: {timelapse:.2f}s')\n\nasync def function_c():\n  start = time.time()\n  await asyncio.sleep(3)\n  timelapse = time.time() - start \n  print(f'Function C execution time: {timelapse:.2f}s')\n  \nasync def function_d():\n  start = time.time()\n  await asyncio.sleep(1)\n  timelapse = time.time() - start\n  print(f'Function D execution time: {timelapse:.2f}s')\n  \nasync def main():\n  await asyncio.gather(function_a(), function_b(), function_c())\n  await function_d()\n  \nasyncio.run(main())\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/juandaherrera.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n * asíncrona una función que tardará en finalizar un número concreto de\n * segundos parametrizables. También debes poder asignarle un nombre.\n * La función imprime su nombre, cuándo empieza, el tiempo que durará\n * su ejecución y cuando finaliza.\n\"\"\"\n\nimport asyncio\nfrom datetime import datetime, timedelta\n\n\nasync def my_async_function(sleep_time: int, name: str) -> None:\n    starts_at = datetime.now()\n    ends_at = starts_at + timedelta(0, sleep_time)\n    print(\n        f\"{name:-^60}\",\n        f\"starts_at={starts_at.strftime(\"%c\")}\",\n        f\"duration={sleep_time}\",\n        f\"ends_at={ends_at.strftime(\"%c\")}\",\n        sep=\"\\n\"\n    )\n    await asyncio.sleep(sleep_time)\n    ends_at = datetime.now().strftime(\"%c\")\n    print(f\"{name} - Finshed at {ends_at}\")\n\n\nasync def main():\n    task_1 = asyncio.create_task(my_async_function(5, \"first\"))\n    task_2 = asyncio.create_task(my_async_function(3, \"second\"))\n    task_3 = asyncio.create_task(my_async_function(7, \"third\"))\n\n    await task_1\n    await task_2\n    await task_3\n\n\nasyncio.run(main())\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han\n *   finalizado.\n\"\"\"\n\nprint(\"-\" * 60)\n\nasync def extra():\n    await asyncio.gather(\n        my_async_function(3, \"C\"),\n        my_async_function(2, \"B\"),\n        my_async_function(1, \"A\")\n    )\n\n    await my_async_function(1, \"D\")\n\nasyncio.run(extra())"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/juanmax2.py",
    "content": "from datetime import datetime\nimport time\nimport asyncio\n\"\"\"\nAsincronía\n\"\"\"\n\nasync def tarea(name: str, duration: int):\n    print(\n        f\"Tarea: {name}. Duración: {duration}s. Inicio: {datetime.now()}\"\n    )\n    await asyncio.sleep(duration)\n    print(\n        f\"Tarea: {name}. Fin: {datetime.now()}\"\n    )\n    \n\nasyncio.run(tarea(\"1\", 3))\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han\n *   finalizado.\n\"\"\"\n\n\nasync def async_tareas():\n    await asyncio.gather(\n    tarea(\"C\", 3),\n    tarea(\"B\", 2),\n    tarea(\"A\", 1)\n)\n    await tarea(\"D\", 1)\n    \nasyncio.run(async_tareas())\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/juanppdev.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n * asíncrona una función que tardará en finalizar un número concreto de\n * segundos parametrizables. También debes poder asignarle un nombre.\n * La función imprime su nombre, cuándo empieza, el tiempo que durará\n * su ejecución y cuando finaliza.\n\"\"\"\n\nimport asyncio\nimport time\n\nasync def tarea_asincrona(nombre, duracion):\n    print(f\"{nombre} empieza. Durará {duracion} segundos.\")\n    inicio = time.time()\n    await asyncio.sleep(duracion)\n    fin = time.time()\n    print(f\"{nombre} ha terminado. Duración real: {fin - inicio:.2f} segundos.\")\n\nasync def main():\n    # Crear y ejecutar tareas asincrónicas\n    tareas = [\n        tarea_asincrona(\"Tarea 1\", 3),\n        tarea_asincrona(\"Tarea 2\", 5),\n        tarea_asincrona(\"Tarea 3\", 2)\n    ]\n    await asyncio.gather(*tareas)\n\n# Ejecutar el bucle de eventos\nasyncio.run(main())\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han\n *   finalizado.\n\"\"\"\n\nimport asyncio\nimport time\n\nasync def tarea_asincrona(nombre, duracion):\n    print(f\"{nombre} empieza. Durará {duracion} segundos.\")\n    inicio = time.time()\n    await asyncio.sleep(duracion)\n    fin = time.time()\n    print(f\"{nombre} ha terminado. Duración real: {fin - inicio:.2f} segundos.\")\n\nasync def main():\n    # Crear tareas asincrónicas para C, B y A\n    tarea_C = tarea_asincrona(\"Función C\", 3)\n    tarea_B = tarea_asincrona(\"Función B\", 2)\n    tarea_A = tarea_asincrona(\"Función A\", 1)\n    \n    # Ejecutar C, B y A en paralelo\n    await asyncio.gather(tarea_C, tarea_B, tarea_A)\n    \n    # Ejecutar la tarea D después de que C, B y A hayan terminado\n    await tarea_asincrona(\"Función D\", 1)\n\n# Ejecutar el bucle de eventos\nasyncio.run(main())\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/juxxon23.py",
    "content": "import asyncio\n\"\"\"\n ╔═════════════════════════════════════╗\n ║ Autor:  Juxxon23                    ║\n ║ GitHub: https://github.com/juxxon23 ║\n ║ Python - 2024                       ║\n ║ Reto 15 - ASINCRONIA                ║\n ╚═════════════════════════════════════╝\n\nEJERCICIO:\nUtilizando tu lenguaje, crea un programa capaz de ejecutar de manera\nasíncrona una función que tardará en finalizar un número concreto de\nsegundos parametrizables. También debes poder asignarle un nombre.\nLa función imprime su nombre, cuándo empieza, el tiempo que durará\nsu ejecución y cuando finaliza.\n\"\"\"\nasync def func_g(name, sec):\n    print(f'func_g started, this function will last {sec} seconds')\n    await asyncio.sleep(sec)\n    print(f\"{sec} seconds have passed, func_g finished\")\n\nasyncio.run(func_g(\"test\", 3))\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\nUtilizando el concepto de asincronía y la función anterior, crea\nel siguiente programa que ejecuta en este orden:\nUna función C que dura 3 segundos.\nUna función B que dura 2 segundos.\nUna función A que dura 1 segundo.\nUna función D que dura 1 segundo.\nLas funciones C, B y A se ejecutan en paralelo.\nLa función D comienza su ejecución cuando las 3 anteriores han\nfinalizado.\n\"\"\"\nasync def func_C():\n    print(\"func_C started, 3 sec\")\n    await asyncio.sleep(3)\n    print(\"func_C finished\")\n\nasync def func_B():\n    print(\"func_B started, 2 sec\")\n    await asyncio.sleep(2)\n    print(\"func_B finished\")\n\nasync def func_A():\n    print(\"func_A started, 1 sec\")\n    await asyncio.sleep(1)\n    print(\"func_A finished\")\n\nasync def func_D():\n    print(\"func_D started, 1 sec\")\n    await asyncio.sleep(1)\n    print(\"func_D finished\")\n\nasync def parallel_func():\n    _func_c = asyncio.create_task(func_C())\n    _func_b = asyncio.create_task(func_B())\n    _func_a = asyncio.create_task(func_A())\n\n    await asyncio.gather(_func_c, _func_b, _func_a)\n\nasyncio.run(parallel_func())\nasyncio.run(func_D())\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/kenysdev.py",
    "content": "# ╔═════════════════════════════════════╗\n# ║ Autor:  Kenys Alvarado              ║\n# ║ GitHub: https://github.com/Kenysdev ║\n# ║ 2024 -  Python                      ║\n# ╚═════════════════════════════════════╝\n\n# -----------------------------------\n# * ASINCRONÍA\n# -----------------------------------\n\n\"\"\"\n* EJERCICIO #1:\n* Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n* asíncrona una función que tardará en finalizar un número concreto de\n* segundos parametrizables. También debes poder asignarle un nombre.\n* La función imprime su nombre, cuándo empieza, el tiempo que durará\n* su ejecución y cuando finaliza.\n\"\"\"\n\nimport asyncio\n\nasync def process(name: str, time: int):\n    print(f\"- Iniciar función: {name} -> Duración: {time}\")\n    await asyncio.sleep(time)\n    print(f\"* Función {name} finaliza.\")\n\nasync def test():\n    await asyncio.gather(\n        process(\"Test 2\", 4),\n        process(\"Test 1\", 2)\n    )\n\n#asyncio.run(test())\n\n\"\"\"\n* EJERCICIO #2:\n* Utilizando el concepto de asincronía y la función anterior, crea\n* el siguiente programa que ejecuta en este orden:\n* - Una función C que dura 3 segundos.\n* - Una función B que dura 2 segundos.\n* - Una función A que dura 1 segundo.\n* - Una función D que dura 1 segundo.\n* - Las funciones C, B y A se ejecutan en paralelo.\n* - La función D comienza su ejecución cuando las 3 anteriores han\n*   finalizado.\n\"\"\"\n\nasync def in_parallel():\n    await asyncio.gather(\n        process(\"C\", 3),\n        process(\"B\", 2),\n        process(\"A\", 1)\n    )\n\nasync def main():\n    await test()\n    await in_parallel()\n    await process(\"D\", 1)\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/mhayhem.py",
    "content": "from time import sleep\nimport time\nimport asyncio\n\n# EJERCICIO:\n# Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n# asíncrona una función que tardará en finalizar un número concreto de\n# segundos parametrizables. También debes poder asignarle un nombre.\n# La función imprime su nombre, cuándo empieza, el tiempo que durará\n# su ejecución y cuando finaliza.\n\nasync def task(name: str, seconds: int):\n    print(f\"Iniciando {name}.\")\n    await asyncio.sleep(seconds)\n    print(f\"{name} tardara {seconds} segundos.\")\n    return f\"{name} termino.\"\n\nasync def main():\n    start = time.time()\n\n    answer = await asyncio.gather(\n        task(\"Descarga\", 6),\n        task(\"Inicialización\", 3),\n        task(\"Petición http\", 2)\n    )\n    \n    end = time.time()\n    print(f\"\\n Respuestas: {answer}\")\n    print(f\"Tiempo de ejecución del programa: {end - start} s.\")\n\n# asyncio.run(main())\n\n# DIFICULTAD EXTRA (opcional):\n# Utilizando el concepto de asincronía y la función anterior, crea\n# el siguiente programa que ejecuta en este orden:\n# - Una función C que dura 3 segundos.\n# - Una función B que dura 2 segundos.\n# - Una función A que dura 1 segundo.\n# - Una función D que dura 1 segundo.\n# - Las funciones C, B y A se ejecutan en paralelo.\n# - La función D comienza su ejecución cuando las 3 anteriores han\n#   finalizado.\n    \nasync def extra():\n    await asyncio.gather(\n        task(\"Función C\", 3),\n        task(\"Función B\", 2),\n        task(\"Función A\", 1)\n    )\n    await task(\"Función D\", 1)\n    \nasyncio.run(extra())"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/miguelex.py",
    "content": "import asyncio\nimport datetime\n\nasync def asyncTask(name: str, seconds: int):\n    print(f\"Comienza la función {name}. Duración de {seconds} segundos. Hora de comienzo {datetime.datetime.now().strftime('%H:%M:%S')}\")\n    await asyncio.sleep(seconds)\n    print(f\"Finaliza la función {name}. Hora de finalización {datetime.datetime.now().strftime('%H:%M:%S')}\")\n    \nasyncio.run(asyncTask(\"Test 1\", 5))\n\n\n# Extra\n\nasync def extra():\n    await asyncio.gather(\n        asyncTask(\"C\", 3),\n        asyncTask(\"B\", 2),\n        asyncTask(\"A\", 1)\n    )\n    await asyncTask(\"D\", 1)\n    \nasyncio.run(extra())"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/mikelm2020.py",
    "content": "import asyncio\nimport datetime\n\n# Ejercicio función asincrona\n\n\nasync def async_task(name: str, duration: int):\n    print(\n        f\"Comienza la tarea {name}. Duración de {duration} segundos. Hora de comienzo {datetime.datetime.now().strftime('%H:%M:%S')}\"\n    )\n    await asyncio.sleep(duration)\n    print(\n        f\"Finaliza la tarea {name}. Hora de finalización {datetime.datetime.now().strftime('%H:%M:%S')}\"\n    )\n\n\n# Dificultad extra\nasync def async_tasks():\n    await asyncio.gather(async_task(\"C\", 3), async_task(\"B\", 2), async_task(\"A\", 1))\n    await async_task(\"D\", 1)\n\n\nif __name__ == \"__main__\":\n    asyncio.run(async_task(\"Tarea 1\", 2))\n\n    asyncio.run(async_tasks())\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/monicavaquerano.py",
    "content": "# 15 ASINCRONÍA\n# Monica Vaquerano\n# https://monicavaquerano.dev\n\n\"\"\"/*\n * EJERCICIO:\n * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n * asíncrona una función que tardará en finalizar un número concreto de\n * segundos parametrizables. También debes poder asignarle un nombre.\n * La función imprime su nombre, cuándo empieza, el tiempo que durará\n * su ejecución y cuando finaliza.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han\n *   finalizado.\n */\"\"\"\n\nimport asyncio, time\n\n\nasync def main(tiempo: int):\n    print(f\"started at {time.strftime('%X')}\")\n\n    print(\"Soy una ...\")\n    await asyncio.sleep(tiempo)\n    print(\"... función asíncrona!\")\n\n    print(f\"finished at {time.strftime('%X')}\")\n\n\nasync def asincrona(tarea: str = \"Default\", tiempo: int = 1):\n    print(\n        f\"Tarea: {tarea} Comienzo: {time.strftime('%X')} Duración: {tiempo} segundo(s)\"\n    )\n    await asyncio.sleep(tiempo)\n    print(f\"... Tarea: {tarea} Final: {time.strftime('%X')}\")\n\n\ninicio = time.time()\nasyncio.run(main(3))\nfin = time.time()\n\nprint(f\"\\nLa función se demoró {(fin - inicio):.02f} segundos.\\n\")\n\ninicio = time.time()\nasyncio.run(asincrona(\"Prueba\", 2))\nfin = time.time()\n\nprint(f\"\\nLa función se demoró {(fin - inicio):.02f} segundos.\\n\")\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Utilizando el concepto de asincronía y la función anterior, crea\n#  * el siguiente programa que ejecuta en este orden:\n#  * - Una función C que dura 3 segundos.\n#  * - Una función B que dura 2 segundos.\n#  * - Una función A que dura 1 segundo.\n#  * - Una función D que dura 1 segundo.\n#  * - Las funciones C, B y A se ejecutan en paralelo.\n#  * - La función D comienza su ejecución cuando las 3 anteriores han\n#  *   finalizado.\n\n\nasync def asincronizadas():\n    await asyncio.gather(asincrona(\"A\", 1), asincrona(\"B\", 2), asincrona(\"C\", 3))\n    await asincrona(\"D\", 1)\n\n\ninicio = time.time()\nasyncio.run(asincronizadas())\nfin = time.time()\n\nprint(f\"\\nLa función se demoró {(fin - inicio):.02f} segundos.\\n\")\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/mouredev.py",
    "content": "import datetime\nimport asyncio\n\n\"\"\"\nEjercicio\n\"\"\"\n\n\nasync def task(name: str, duration: int):\n    print(\n        f\"Tarea: {name}. Duración: {duration}s. Inicio: {datetime.datetime.now()}\")\n    await asyncio.sleep(duration)\n    print(\n        f\"Tarea: {name}. Fin: {datetime.datetime.now()}\")\n\n\nasyncio.run(task(\"1\", 2))\n\n\"\"\"\nExtra\n\"\"\"\n\n\nasync def async_tasks():\n    await asyncio.gather(task(\"C\", 3), task(\"B\", 2), task(\"A\", 1))\n    await task(\"D\", 1)\n\nasyncio.run(async_tasks())\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/mrodara.py",
    "content": "###################################### ASINCRONÍA ################################################\nimport asyncio #Módulo para poder programar tareas recurrentes\n\n#async def async_task(name: str, execution_time: int = 1):\n#    \"\"\"Tarea asíncrona que ejecuta un bloque de código durante un tiempo determinado\"\"\"\n#    print(f\"Esta tarea tendrá una duración de {execution_time} segundos\")\n#    print(f\"Comenzando la tarea {name}...\")\n#    await asyncio.sleep(execution_time) #Pausa la ejecución durante el tiempo especificado\n#    print(f\"Tarea {name} finalizada.\")\n#\n#asyncio.run(async_task(\"Formating SSD\", 5))\n\n###################################  EXTRA  ##############################################################\nasync def proccess_data(name: str, execution_time: int = 1):\n    print(f\"Inicio de ejecución de tarea {name}\")\n    await asyncio.sleep(execution_time)\n    print(f\"Fin de ejecución de tarea {name}\")\n\n# Ejecución asíncrona del módulo main\nasync def main():\n    \n    # Ejecutamos varias tareas en paralelo\n    await asyncio.gather(\n        proccess_data(\"Tarea C\", 3),\n        proccess_data(\"Tarea B\", 2),\n        proccess_data(\"Tarea A\", 1),\n    )    \n    \n    # Ejecución última\n    final_task = asyncio.create_task(proccess_data(\"Tarea D\", 1))\n    await final_task\n    \n\nasyncio.run(main=main())\n###################################  FIN EXTRA  ##############################################################\n###################################### FIN ASINCRONÍA ################################################"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/mvidalb.py",
    "content": "from datetime import datetime\nimport time\nimport asyncio\n\n'''\nEjercicio\n'''\n\nasync def function(name : str, duration_sec: int):\n    \n    print(f\"Función: {name}. Duración: {duration_sec} s. Inicio; {datetime.now()}\")\n    await asyncio.sleep(duration_sec)\n    print(f\"Función: {name}. Fin; {datetime.now()}\")\n\n\nasyncio.run(function(\"Ejercicio\", 5))\n\n\n'''\nEjercicio extra\n'''\n#function(\"D\", 1) \nasync def async_tasks():\n    await asyncio.gather(function(\"C\", 3), function(\"B\", 2), function(\"A\", 1))  # Ejecución en paralelo\n    await function(\"D\", 1)\n\nasyncio.run(async_tasks())\n\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/neslarra.py",
    "content": "\"\"\"\n EJERCICIO:\n Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n asíncrona una función que tardará en finalizar un número concreto de\n segundos parametrizables. También debes poder asignarle un nombre.\n La función imprime su nombre, cuándo empieza, el tiempo que durará\n su ejecución y cuando finaliza.\n\n DIFICULTAD EXTRA (opcional):\n Utilizando el concepto de asincronía y la función anterior, crea\n el siguiente programa que ejecuta en este orden:\n - Una función C que dura 3 segundos.\n - Una función B que dura 2 segundos.\n - Una función A que dura 1 segundo.\n - Una función D que dura 1 segundo.\n - Las funciones C, B y A se ejecutan en paralelo.\n - La función D comienza su ejecución cuando las 3 anteriores han\n   finalizado.\n\"\"\"\n\nimport datetime\nimport asyncio\n\nprint(f\"== Explicación {'=' * 30}\\n\")\n\nprint(f\"\"\"\nTomado de https://eiposgrados.com/blog-python/programacion-asincronica-en-python/  <= muy buen artículo.\n\nEn esencia, la programación asincrónica es una técnica que permite a las aplicaciones realizar múltiples tareas simultáneamente, sin\nbloquear la ejecución del programa. A diferencia de la programación síncrona tradicional, donde las operaciones se realizan en orden secuencial,\nla programación asincrónica aprovecha la capacidad de ejecutar tareas en segundo plano mientras el programa principal sigue funcionando.\nEsto se logra mediante el uso de dos palabras clave fundamentales en Python: `async` y `await`. \n\nCon `async`, puedes declarar funciones asincrónicas que pueden ejecutar múltiples tareas sin bloquear el flujo principal del programa. Por otro lado,\n`await` permite que una función espere el resultado de una operación asíncrona sin bloquear la ejecución. Esta combinación permite que las\naplicaciones realicen operaciones en paralelo, mejorando drásticamente su capacidad de respuesta y rendimiento. \n\"\"\")\n\nprint(f\"== Dificultad Extra {'=' * 30}\\n\")\n\n\ndef log_task(funcion):\n    async def wrapper(*args, **kwargs):\n        inicio = datetime.datetime.now()\n        print(f\"BEGIN {funcion.__name__} - Nombre: {args[0]} - ejecutar por {args[1]} segundos - Lanzado a las {datetime.datetime.now().strftime('%H:%M:%S')}\")\n        await funcion(*args, **kwargs)\n        duracion = datetime.datetime.now() - inicio\n        print(f\"END {funcion.__name__} - Nombre: {args[0]} / duró: {duracion.seconds} segundo - Terminó a las {datetime.datetime.now().strftime('%H:%M:%S')}\")\n\n    return wrapper\n\n\n@log_task\nasync def task(tarea: str, tiempo: int):\n    return await asyncio.sleep(tiempo)\n\n\nasync def disparo_paralelo():\n    # gather lanza simultáneamente todas las funciones que se pasen como argumento.\n    await asyncio.gather(task(\"tarea_C\", 3), task(\"tarea_B\", 2), task(\"tarea_A\", 1))\n\n\n# Solo asíncrono\nasyncio.run(task(\"tarea_C\", 3))\n\n# Asíncrono y paralelo\nasyncio.run(disparo_paralelo())\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/nlarrea.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n * asíncrona una función que tardará en finalizar un número concreto de\n * segundos parametrizables. También debes poder asignarle un nombre.\n * La función imprime su nombre, cuándo empieza, el tiempo que durará\n * su ejecución y cuando finaliza.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han\n *   finalizado.\n\"\"\"\n\nimport asyncio\nfrom datetime import datetime\n\n\nasync def print_parameters(seconds: int, name: str) -> None:\n    print(f\"Task: {name}\\nTime: {seconds}\\nStart: {datetime.now()}\\n\")\n    await asyncio.sleep(seconds)\n    print(f\"Task: {name}\\nEnd: {datetime.now()}\\n\")\n\n\nasync def main():\n    await asyncio.gather(\n        print_parameters(5, \"task 1\"),\n        print_parameters(8, \"task 2\"),\n        print_parameters(1, \"task 3\"),\n        print_parameters(15, \"task 4\"),\n    )\n\n\nasyncio.run(main())\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han\n *   finalizado.\n\"\"\"\n\n\nasync def run():\n    tasks = [\n        print_parameters(3, \"C\"),\n        print_parameters(2, \"B\"),\n        print_parameters(1, \"A\"),\n    ]\n    await asyncio.gather(*tasks)\n\n    await print_parameters(1, \"D\")\n\n\nasyncio.run(run())\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/oniricoh.py",
    "content": "import asyncio\nimport time\n\nasync def execute_task(name, seconds):\n    print(\"\\nEjecutando la tarea de forma asíncrona...\")\n    #obtiene el tiempo actual del sistema\n    start_time = time.time()\n\n    # Simulamos una tarea que tarda un cierto número de segundos\n    await asyncio.sleep(seconds)\n    \n    #obtiene el tiempo actual del sistema (pasado los x segundos de espera)\n    end_time = time.time()\n    elapsed_time = end_time - start_time\n\n    print(f\"Nombre '{name}'. Duración: {elapsed_time:.2f} segundos\")\n\n# async def main():\n#     await execute_task(\"Daniel\", 3)\n\n# asyncio.run(main())\n\n\n\n###############################################################################\n## DIFICULTAD EXTRA\n###############################################################################\n\nasync def main():\n    tasks = [\n        (\"Task C\", 3),\n        (\"Task B\", 2),\n        (\"Task A\", 1),\n    ]\n    \n    for name, second in tasks:\n        await execute_task(name, second)\n    \n    await execute_task(\"Task D\", 1)\n\nasyncio.run(main())\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/oriaj3.py",
    "content": "\n\"\"\"\t\n15 - ASINCRONÍA\nAutor de la solución: Oriaj3\t\nTeoría:\t\nLa programación asíncrona es un paradigma de programación que permite que un \nprograma realice múltiples tareas simultáneamente. En lugar de ejecutar una\ntarea tras otra, las tareas se ejecutan de forma concurrente, lo que puede\nmejorar significativamente el rendimiento y la eficiencia de un programa.\n\nEn Python, la programación asíncrona se puede implementar utilizando el módulo\nasyncio, que proporciona una serie de funciones y clases para trabajar con\ntareas asíncronas. Para definir una función asíncrona en Python, se utiliza la\npalabra clave async antes de la definición de la función. Por ejemplo, la\nsiguiente función es asíncrona:\n\nasync def mi_funcion():\n    # Código de la función\n    return\n\nPara ejecutar una función asíncrona en Python, se puede utilizar la función\nasyncio.run(), que ejecuta la función de nivel superior y espera a que termine.\n\nPor ejemplo, la siguiente función ejecuta una tarea asíncrona que tarda un\nnúmero de segundos determinado:\n\nimport asyncio\nimport time\n\nasync def execute_task(name, seconds):\n\n    print(\"\\nEjecutando la tarea de forma asíncrona...\")\n    #obtiene el tiempo actual del sistema\n    start_time = time.time()\n\n    # Simulamos una tarea que tarda un cierto número de segundos\n    await asyncio.sleep(seconds)\n\n    # Obtiene el tiempo actual del sistema\n    end_time = time.time()\n    \n    # Muestra el nombre de la tarea, el tiempo de inicio, la duración y el tiempo de finalización\n    print(f\"Tarea: {name}\")\n    print(f\"Tiempo de inicio: {start_time}\")\n    print(f\"Duración: {seconds} segundos\")\n    print(f\"Tiempo de finalización: {end_time}\")\n\n# Ejecuta la tarea de forma asíncrona\nasyncio.run(execute_task(\"Tarea 1\", 3))\n\"\"\"\n\n\"\"\"\n * EJERCICIO:\n * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n * asíncrona una función que tardará en finalizar un número concreto de\n * segundos parametrizables. También debes poder asignarle un nombre.\n * La función imprime su nombre, cuándo empieza, el tiempo que durará\n * su ejecución y cuando finaliza.\n\n\"\"\"\n\nimport asyncio\nimport datetime\n\nasync def execute_task(name: str, seconds: int): \n    \n    tiempo_inicial = datetime.datetime.now()\n    tiempo_fin = tiempo_inicial + datetime.timedelta(seconds=seconds)  \n    print(f\"Tarea {name} iniciada a las {tiempo_inicial}, finalizará a las {tiempo_fin}, durando {seconds}s.\")\n\n    #Espera x seconds\n    await asyncio.sleep(seconds)\n\n    tiempo_final = datetime.datetime.now()\n\n    print(f\"**[FIN {name}]**: {tiempo_final}\")\n\nasyncio.run(execute_task(\"Tarea 1\", 1))\n\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han\n *   finalizado.\n */\n\"\"\"\nprint(\"***********************EXTRA***********************\")\nasync def extra():\n    await asyncio.gather(execute_task (\"C\", 3), execute_task(\"B\", 2), execute_task(\"A\", 1))\n    await execute_task(\"D\", 1)\n\nasyncio.run(extra())"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/pyramsd.py",
    "content": "import asyncio\n\nasync def Segundos(nombre, segundos):\n    print(f\"La tarea '{nombre}' comenzó.\")\n    print(f\"La tarea '{nombre}' durará {segundos} segundos.\")\n    await asyncio.sleep(segundos)\n    print(f\"La tarea '{nombre}' finalizó.\")\n\n\nasync def ejecutar_tareas():\n    nombre_func = input('Nombre de la función: ')\n    actividades = [\n        Segundos(nombre_func, 2),\n    ]\n    # Ejecutar las actividades\n    await asyncio.gather(*actividades)\n\nasyncio.run(ejecutar_tareas())\n\n'''\nEXTRA\n'''\n\nasync def funcA(segundos):\n\n    await asyncio.sleep(segundos)\n    print('La función A ya finalizó')\n\nasync def funcB(segundos):\n\n    await asyncio.sleep(segundos)\n    print('La función B ya finalizó')\n\nasync def funcC(segundos):\n\n    await asyncio.sleep(segundos)\n    print('La función C ya finalizó')\n\nasync def funcD(segundos):\n\n    await asyncio.sleep(segundos)\n    print('La función D ya finalizó')\n\n\nasync def FuncsABCD():\n    print('Las funciones A, B y C se estan ejecutandose')\n    await asyncio.gather(funcA(1), funcB(2), funcC(3))\n    print('Las funciones A, B y C finalizaron')\n    await asyncio.gather(funcD(1))\n\n\nasyncio.run(FuncsABCD())\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/qwik-zgheib.py",
    "content": "import time\n\n\n# -- synchronous exercise\ndef function_async(name: str, seconds: int) -> None:\n    print(f\"{name} starts\")\n    time.sleep(seconds)\n    print(f\"{name} ends\")\n\n\nfunction_async(\"A\", 3)\n\n\n# -- extra challenge\nfunction_async(\"C\", 3)\nfunction_async(\"B\", 2)\nfunction_async(\"A\", 1)\nfunction_async(\"D\", 1)\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/rantamhack.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n * asincrona una funcion que tardara en finalizar un numero concreto de\n * segundos parametrizables. Tambien debes poder asignarle un nombre.\n * La funcion imprime su nombre, cuando empieza, el tiempo que durara\n * su ejecucion y cuando finaliza.\n\"\"\"\n\nimport asyncio\n\n\nasync def task_D(name: str, seconds: int ):\n    print(f\"[+] La tarea {name} comienza a ejecutarse....\\n\")\n    await asyncio.sleep(seconds)\n               \n    print(f\"[!] La tarea {name} ha finalizado\\n\")\n    \nasyncio.run(task_D(\"Tarea D\", 5))\n\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronia y la funcion anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una funcion C que dura 3 segundos.\n * - Una funcion B que dura 2 segundos.\n * - Una funcion A que dura 1 segundo.\n * - Una funcion D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La funcion D comienza su ejecucion cuando las 3 anteriores han\n *   finalizado.\n\"\"\" \n\nasync def task_C(name: str, seconds: int):\n    print(f\"[+] La tarea {name} comienza a ejecutarse....\\n\")\n    await asyncio.sleep(seconds)\n    print(f\"[!] La tarea {name} ha finalizado\\n\")\n    \nasync def task_B(name: str, seconds: int):\n    print(f\"[+] La tarea {name} comienza a ejecutarse....\\n\")\n    await asyncio.sleep(seconds)\n    print(f\"[!] La tarea {name} ha finalizado\\n\")\n    \nasync def task_A(name: str, seconds: int):\n    print(f\"[+] La tarea {name} comienza a ejecutarse....\\n\")\n    await asyncio.sleep(seconds)\n    print(f\"[!] La tarea {name} ha finalizado\\n\")\n    \nasync def main():\n   \n   print(\"[+] La 'Tarea D' Espera a que las demas terminen de ejecutarse....\\n\")\n   await asyncio.gather(task_C(\"Tarea C\", 3), task_B(\"Tarea B\", 2), task_A(\"Tarea A\", 1))\n   await task_D(\"Tarea D\", 5)\n  \nasyncio.run(main())\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/raulG91.py",
    "content": "\nimport asyncio\nimport time\n\nasync def function(seconds:float,name:str):\n    await asyncio.sleep(seconds)\n    print(f'Hello {name}')\n    \nasyncio.run(function(3,\"Raul\"))  \n\n#Extra\nasync def functionC():\n    print(\"Starting function C\")\n    await asyncio.sleep(3)\n    print(\"Ending function C\")\nasync def functionB():\n    print(\"Starting function B\")\n    await asyncio.sleep(2)\n    print(\"Ending function B\")\nasync def functionA():\n    print(\"Starting function A\")\n    await asyncio.sleep(1)\n    print(\"Ending function A\")\nasync def functionD():\n    print(\"Starting function D\")\n    await asyncio.sleep(1)  \n    print(\"Ending function D\")  \n    \n#Group all async functions into main    \nasync def main():\n    print(f\"started at {time.strftime('%X')}\")\n    async with  asyncio.TaskGroup() as tg:\n      #it will wait until all tasks in the group are completed\n      task1= tg.create_task(functionC())\n      task2 = tg.create_task(functionB())\n      task3 = tg.create_task(functionA())\n    #Now run functionD\n    await functionD()\n      \n    print(f\"finished at {time.strftime('%X')}\")\nasyncio.run(main())    "
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/raynerpv2022.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n#  * asíncrona una función que tardará en finalizar un número concreto de\n#  * segundos parametrizables. También debes poder asignarle un nombre.\n#  * La función imprime su nombre, cuándo empieza, el tiempo que durará\n#  * su ejecución y cuando finaliza.\n#  *\nimport asyncio\nfrom datetime import datetime\n\nasync def my_asyn_func(time, name):\n    start = datetime.now()\n    print(f\"Task:{name} Start: {start.strftime(\"%H:%M:%S\")} \")\n    await asyncio.sleep(time)\n    end = datetime.now()\n   \n    print(f\"Task:{name} End:{end.strftime(\"%H:%M:%S\")} Duration:{time}\")\n\n \n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Utilizando el concepto de asincronía y la función anterior, crea\n#  * el siguiente programa que ejecuta en este orden:\n#  * - Una función C que dura 3 segundos.\n#  * - Una función B que dura 2 segundos.\n#  * - Una función A que dura 1 segundo.\n#  * - Una función D que dura 1 segundo.\n#  * - Las funciones C, B y A se ejecutan en paralelo.\n#  * - La función D comienza su ejecución cuando las 3 anteriores han\n#  *   finalizado.\n#  */\n\n\nasync def main():\n        \n        await asyncio.gather(my_asyn_func(10,\"Aufgabe A\"),my_asyn_func(7,\"Aufgabe B\"), my_asyn_func(3,\"Aufgabe C\"))\n        await my_asyn_func(1,\"Aufgabe D\")\n\nasyncio.run(main())"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/rigo93acosta.py",
    "content": "'''\n * EJERCICIO:\n * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n * asíncrona una función que tardará en finalizar un número concreto de\n * segundos parametrizables. También debes poder asignarle un nombre.\n * La función imprime su nombre, cuándo empieza, el tiempo que durará\n * su ejecución y cuando finaliza.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han\n *   finalizado.\n'''\n\n'''\nEjercicio\n'''\nimport datetime\nimport time\nimport asyncio\n\nasync def task(name: str, duration: int):\n    \n    print(f'Tarea:{name}. Duración:{duration} s. Inicio:{datetime.datetime.now()}')\n    await asyncio.sleep(duration)\n    print(f'Tarea:{name}. Fin:{datetime.datetime.now()}')\n\n# asyncio.run(task('1', 2))\n\n'''\nExtra\n'''\n\n# C-B-A Paralelo\n# D Comienza después de C-B-A\nasync def async_task():\n    await asyncio.gather(\n        task('C', 3),\n        task('B', 2),\n        task('A', 1)\n    )\n    await task('D', 1)\n\nasyncio.run(async_task())\n\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/roswer13.py",
    "content": "# EJERCICIO:\n# Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n# asíncrona una función que tardará en finalizar un número concreto de\n# segundos parametrizables. También debes poder asignarle un nombre.\n# La función imprime su nombre, cuándo empieza, el tiempo que durará\n# su ejecución y cuando finaliza.\n\nimport asyncio\nimport time\n\nasync def my_async_function(name: str, seconds: int):\n    if isinstance(name, str) == False:\n        raise TypeError('name must be a string')\n    if isinstance(seconds, int) == False:\n        raise TypeError('seconds must be an integer')\n    \n    print(f'{name} started at {time.strftime(\"%X\")}, duration: {seconds} seconds.')\n    await asyncio.sleep(seconds)\n    print(f'{name} finished at {time.strftime(\"%X\")}')\n\nif __name__ == '__main__':\n    asyncio.run(my_async_function(name='Taask 1', seconds=5))\n\n\n# DIFICULTAD EXTRA (opcional):\n# Utilizando el concepto de asincronía y la función anterior, crea\n# el siguiente programa que ejecuta en este orden:\n# - Una función C que dura 3 segundos.\n# - Una función B que dura 2 segundos.\n# - Una función A que dura 1 segundo.\n# - Una función D que dura 1 segundo.\n# - Las funciones C, B y A se ejecutan en paralelo.\n# - La función D comienza su ejecución cuando las 3 anteriores han\n#   finalizado.\n\nif __name__ == '__main__':\n    async def main():\n        await asyncio.gather(\n            my_async_function(name='Task C', seconds=3),\n            my_async_function(name='Task B', seconds=2),\n            my_async_function(name='Task A', seconds=1)\n        )\n        await my_async_function(name='Task D', seconds=1)\n    \n    asyncio.run(main())\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/santyjl.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n * asíncrona una función que tardará en finalizar un número concreto de\n * segundos parametrizables. También debes poder asignarle un nombre.\n * La función imprime su nombre, cuándo empieza, el tiempo que durará\n * su ejecución y cuando finaliza.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han finalizado.\n */\n\"\"\"\n\nimport asyncio  # asyncio es el modulo para funciones asincronas\nimport time\n\n\nasync def funcion_tareas(nombre : str , duracion : int) -> str: #async para definir que es una funcion asincrona\n    \"esta funcion permite el uso de funciones asicronas\"\n\n    inicio = time.time()\n    print(f\"El nombre de la tarea es {nombre} y dura {duracion} segundos\")\n\n    await asyncio.sleep(duracion)   #await para que espera pero sin afectar a otras funciones asincronas\n    final = time.time()\n    resultado : int = final - inicio\n\n    print(f\"La tarea {nombre} termino en {round(resultado , 1)} \")\n\nasync def ejecuciones_paralelas():\n    \"muestra el uso de funciones asicronas multiples\"\n\n    await asyncio.gather(       # asyncio.gatcher permite que que las funciones se ejecuten en paralelo\n        funcion_tareas(\"tarea uno\" , 4),\n        funcion_tareas(\"tarea dos\" , 1),\n        funcion_tareas(\"tarea tres\" , 2),\n        funcion_tareas(\"tarea cuatro\" , 5)\n        )\n\n    await asyncio.gather(funcion_tareas(\"tarea cinco\" , 3))\n\nasyncio.run(ejecuciones_paralelas())"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/sorubadguy.py",
    "content": "import asyncio\nimport datetime\n\nasync def esperar(nombre: str, duracion: int):\n    print(f\"nombre: {nombre}, duracion: {duracion}, comienzo: {datetime.datetime.now()}\")\n    await asyncio.sleep(duracion)\n    print(f\"Fin: {datetime.datetime.now()}\")\n    \nasyncio.run(esperar(\"Sorubadguy\", 1))\n\n#!Extra\n    \nasync def tareas():\n    await asyncio.gather(task(\"A\",1))\n    await asyncio.run(D)\n    \nasyncio.run(tareas())"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/sperezsa.py",
    "content": "import datetime\nimport asyncio\n\nasync def test(segundos, nombre):\n    print(f\"Comienza tarea '{nombre}', tiempo de espera {segundos} segundos: {datetime.datetime.now()}\")\n    await asyncio.sleep(segundos) \n    print(f\"Acaba tarea '{nombre}': {datetime.datetime.now()}\")\n\nasyncio.run(test(3,\"espera\"))\n\n\n\"\"\"\nExtra\n\"\"\"\n\nasync def async_tasks():\n    await asyncio.gather(test(3,\"C\"), test(2,\"B\"), test(1,\"A\"))\n    await test(1,\"D\")\n\nasyncio.run(async_tasks())\n\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/victorfer69.py",
    "content": "import datetime\nimport time\nimport asyncio\n\n#Ejercicio\n\nasync def task(name:str, duration:int):\n    print(f\"Tarea: {name}. Duración: {duration}s. Inicio: {datetime.datetime.now()}\")\n    await asyncio.sleep(duration)\n    print(f\"Fin {name}: {datetime.datetime.now()}\")\n\n#asyncio.run(task(\"1\", 3))\n#asyncio.run(task(\"2\", 2))\n\n\n#EJERCICIO EXTRA\n\nasync def async_tasks():\n    await asyncio.gather(task(\"C\", 3), task(\"B\", 2), task(\"A\", 1))\n    await task(\"D\", 1)\n\nasyncio.run(async_tasks())"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/worlion.py",
    "content": "import asyncio\nfrom datetime import datetime\n\n\"\"\"\n    EJERCICIO: Asincronía\n\"\"\"\n\nasync def sleeper(name: str, seconds: int):\n    now = datetime.now().strftime(\"%X\")\n    print(f\"me llamo {name}, son las {now} y me voy a echar {seconds} segunditos... 🥱\")    \n    await asyncio.sleep(seconds)\n    now = datetime.now().strftime(\"%X\")\n    print( f\"me llamo {name}, ahora son las {now} y ya he terminado ⏰\"    )\n\nasync def asynchronous_task(tasks):\n    start_time = datetime.now()\n    \n    # tasks = [sleeper('Pepe', 3), sleeper('Juan', 5), sleeper('Manolo', 2)]\n    await asyncio.gather(*tasks)\n    \n    end_time = datetime.now()\n    print('Duration async: {}'.format(end_time - start_time))\n        \nasyncio.run(asynchronous_task([sleeper('Pepe', 3), sleeper('Juan', 5), sleeper('Manolo', 2)]))\n\n\"\"\"\n    DIFICULTAD EXTRA (opcional):\n\"\"\"\n\nprint(\"\\n ---- 🌩 DIFICULTAD EXTRA 🌩 ----\\n\")\n\n\nasync def main():\n    tasks = [\n        sleeper('C', 3), \n        sleeper('B', 2), \n        sleeper('A', 1), \n        sleeper('D', 1)\n    ]\n    await asyncio.gather(*tasks[:3])\n    await tasks[3]\n    \nasyncio.run(main())"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/ycanas.py",
    "content": "import asyncio\nimport datetime\n\n# ------ I. Ejercicio\n\nasync def my_async_function(name: str, time: int) -> None:\n    print(f\"{name}, duración: {time}s, inicio: {datetime.datetime.now()}\")\n    await asyncio.sleep(time)\n    print(f\"{name} fin {datetime.datetime.now()}\")\n\n\nasyncio.run(my_async_function(\"task1\", 5))\n\n\n# ------ II. Extra\n\nasync def async_functions():\n    await asyncio.gather(\n        my_async_function(\"TaskC\", 3),\n        my_async_function(\"TaskB\", 2),\n        my_async_function(\"TaskA\", 1),\n    )\n    await my_async_function(\"TaskD\", 1)\n\n\nasyncio.run(async_functions())\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/yenneralayon142.py",
    "content": "import asyncio\nimport datetime\nimport time\n\n\"\"\"\nAsincronismo\n\"\"\"\n\nasync def task(name:str, duration:int):\n    print(\n        f\"Tarea: {name}. Duración: {duration}s. Inicio: {datetime.datetime.now()}\")\n    await asyncio.sleep(duration)\n    print(\n        f\"Tarea: {name}. Fin: {datetime.datetime.now()}\"\n    )\n\nasyncio.run(task(\"1\",2))\n\n\"\"\"\nExtra\n\"\"\"\n\nasync def async_task():\n    await asyncio.gather(task(\"A\",3), task(\"B\",2), task(\"C\",1))\n    await task(\"D\",1)\n\nasyncio.run(async_task())"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/python/zetared92.py",
    "content": "# RETO 15 ASINCRONÍA\n\nimport datetime\nimport asyncio\n\n\"\"\"\nPROGRAMA QUE EJECUTE UNA FUNCIÓN ASÍNCRONA\n\"\"\"\n\nasync def task(name: str, duration: int):\n    print(\n        f\"Task: {name}. Duration: {duration}sec. Start: {datetime.datetime.now()}\")\n    await asyncio.sleep(duration)\n    print(\n        f\"Task: {name}. End: {datetime.datetime.now()}\")\n    \n\nasyncio.run(task(\"1\", 2))\n\n\n\n# Extra\n\nprint(\"🧩 DIFICULTAD EXTRA - 10 MANERAS DE MOSTRAR LA FECHA 🧩\")\n\n\"\"\"\nUtilizando el concepto de asincronía y la función anterior, crea\nel siguiente programa que ejecuta en este orden:\nUna función C que dura 3 segundos.\nUna función B que dura 2 segundos.\nUna función A que dura 1 segundo.\nUna función D que dura 1 segundo.\nLas funciones C, B y A se ejecutan en paralelo.\nLa función D comienza su ejecución cuando las 3 anteriores han\nfinalizado.\n\"\"\"\n\nasync def async_task():\n    await asyncio.gather(task(\"C\", 3), task(\"B\", 2), task(\"A\", 1), task(\"D\", 1))\n\nasyncio.run(async_task())"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/ruby/Elmer125.rb",
    "content": "#  * EJERCICIO:\n#  * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n#  * asíncrona una función que tardará en finalizar un número concreto de\n#  * segundos parametrizables. También debes poder asignarle un nombre.\n#  * La función imprime su nombre, cuándo empieza, el tiempo que durará\n#  * su ejecución y cuando finaliza.\n# Doc: https://ruby-doc.org/core-2.5.1/Thread.html\n\ndef async_method(name, seconds)\n  Thread.new do\n    puts \"Task #{name} started at #{Time.now}, will run for #{seconds} seconds\"\n    sleep(seconds)\n    puts \"Task #{name} finished at #{Time.now}\"\n  end\nend\n\nthread1 = async_method(\"A\", 5)\nthread2 = async_method(\"B\", 3)\n\nthread1.join\nthread2.join\n\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Utilizando el concepto de asincronía y la función anterior, crea\n#  * el siguiente programa que ejecuta en este orden:\n#  * - Una función C que dura 3 segundos.\n#  * - Una función B que dura 2 segundos.\n#  * - Una función A que dura 1 segundo.\n#  * - Una función D que dura 1 segundo.\n#  * - Las funciones C, B y A se ejecutan en paralelo.\n#  * - La función D comienza su ejecución cuando las 3 anteriores han finalizado.\n\nmethod_c = async_method(\"C\", 3)\nmethod_b = async_method(\"B\", 2)\nmethod_a = async_method(\"A\", 1)\n[ method_c, method_b, method_a ].each(&:join)\nmethod_d = async_method(\"D\", 1)\nmethod_d.join\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/rust/kenysdev.rs",
    "content": "\n/*\n╔═══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado                ║\n║ GitHub: https://github.com/Kenysdev   ║\n║ 2024 -  Rust                          ║\n╚═══════════════════════════════════════╝\n-----------------------------------------\n* ASINCRONÍA\n-----------------------------------------\nhttps://crates.io/crates/tokio\n\n[dependencies]\ntokio = { version = \"1.37.0\", features = [\"full\"] }\n\n* EJERCICIO #1:\n* Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n* asíncrona una función que tardará en finalizar un número concreto de\n* segundos parametrizables. También debes poder asignarle un nombre.\n* La función imprime su nombre, cuándo empieza, el tiempo que durará\n* su ejecución y cuando finaliza.\n*/\n\nuse tokio::time::{sleep, Duration};\n\nasync fn process(name: &str, time: u64) {\n    println!(\"* Iniciar función: {} -> Duración: {}\", name, time);\n    sleep(Duration::from_secs(time)).await;\n    println!(\"- Función {} finaliza.\", name);\n}\n\nasync fn test() {\n    tokio::join!(\n        process(\"Test 2\", 3),\n        process(\"Test 1\", 1)\n    );\n}\n\n/*\n* EJERCICIO #2:\n* Utilizando el concepto de asincronía y la función anterior, crea\n* el siguiente programa que ejecuta en este orden:\n* - Una función C que dura 3 segundos.\n* - Una función B que dura 2 segundos.\n* - Una función A que dura 1 segundo.\n* - Una función D que dura 1 segundo.\n* - Las funciones C, B y A se ejecutan en paralelo.\n* - La función D comienza su ejecución cuando las 3 anteriores han\n*   finalizado.\n*/\n\nasync fn in_parallel() {\n    tokio::join!(\n        process(\"C\", 3),\n        process(\"B\", 2),\n        process(\"A\", 1)\n    );\n}\n\n#[tokio::main]\nasync fn main() {\n    test().await;\n    in_parallel().await;\n    process(\"D\", 1).await;\n}\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/sql/Nicojsuarez2.sql",
    "content": "# #15 ASINCRONÍA\n> #### Dificultad: Difícil | Publicación: 08/04/24 | Corrección: 15/04/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n * asíncrona una función que tardará en finalizar un número concreto de\n * segundos parametrizables. También debes poder asignarle un nombre.\n * La función imprime su nombre, cuándo empieza, el tiempo que durará\n * su ejecución y cuando finaliza.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han\n *   finalizado.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/swift/allbertoMD.swift",
    "content": "import Foundation\n\n/*\nNOTA:\nPara el correcto funcionamiento de este programa se debe ejecutar en un playground, no en consola.\n*/\n\n// Función para simular una ejecución asincrónica de una tarea que toma un cierto tiempo.\nfunc execute(functionNmae name: String, durationInSeconds secondsDuration: Int) async {\n    \n    let start = Date()\n    let formatter = DateFormatter()\n    formatter.dateFormat = \"HH:mm:ss\" // Formato personalizado para la hora.\n    \n    print(\"Función \\(name) iniciada a las \\(formatter.string(from: start))\")\n    print(\"Duración estimada: \\(secondsDuration) segundos\")\n    \n    // Simulamos la ejecución de la función con un retraso.\n    do {\n        try await Task.sleep(for: .seconds(secondsDuration))\n    } catch {\n        print(\"Error durante la simulación: \\(error)\")\n    }\n    \n    let end = Date()\n    \n    print(\"Función \\(name) finalizada a las \\(formatter.string(from: end))\")\n    print(\"Tiempo de ejecución de la función \\(name): \\(Int(end.timeIntervalSince(start))) segundos\")\n}\n\n// Ejecutamos las funciones de forma asíncrona.\nTask {\n    await execute(functionNmae: \"Tarea1\", durationInSeconds: 5)\n    print(\"Todas las funciones han finalizado!\")\n}\n\n// Tiempo de margen para que le de tiempo a ejecutarse la función Tarea1.\nsleep(10)\n\n\n\n\n// DIFICULTAD EXTRA.\nprint(\"\\nDIFICULTAD EXTRA.\\n\")\n\n\n\n\n// Función para simular una ejecución asincrónica de una tarea que toma un cierto tiempo.\nfunc executeTask(name: String, durationInSeconds secondsDuration: Int) async {\n    \n    let start = Date()\n    let formater = DateFormatter()\n    formater.dateFormat = \"HH:mm:ss\"\n    \n    print(\"Función \\(name) iniciada a las \\(formater.string(from: start)).\")\n    print(\"Tiempo estimado de la función \\(name): \\(secondsDuration).\")\n    \n    do {\n        try await Task.sleep(for: .seconds(secondsDuration))\n    } catch {\n        print(\"Error -> \\(error)\")\n    }\n    \n    let end = Date()\n    \n    print(\"Funcion \\(name) finalizada a las \\(formater.string(from: end)).\")\n    print(\"Tiempo de ejecución de la función \\(name): \\(Int(end.timeIntervalSince(start)))\" + (secondsDuration == 1 ? \" segundo.\" : \" segundos.\"))\n}\n\n// Función que ejecuta las tareas en paralelo y luego ejecuta la tarea D.\nfunc executeTasks() async {\n    \n    // Ejecutar las funciones C, B y A en paralelo\n    await withTaskGroup(of: Void.self) { group in\n        group.addTask {\n            await executeTask(name: \"C\", durationInSeconds: 3)\n        }\n        group.addTask {\n            await executeTask(name: \"B\", durationInSeconds: 2)\n        }\n        group.addTask {\n            await executeTask(name: \"A\", durationInSeconds: 1)\n        }\n    }\n    \n    // Cuando todas las tareas C, B y A han finalizado, ejecutar la función D.\n    await executeTask(name: \"D\", durationInSeconds: 1)\n}\n\n// Ejecutar la función que lanza las funciones C, B y A en paralelo y luego la D.\nTask {\n    await executeTasks()\n    print(\"Todas las funciones han finalizado!\")\n}\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/swift/blackriper.swift",
    "content": "import Foundation\n/*\n La asincronia es  la capacidad de ejecutar una tarea en segundo plano, sin detener la ejecucion de la aplicacion.\n los conceptos mas comunes que podemos encontrar son:\n\n  - Asincronia tarea no bloqueante que permite seguir ejecutando el hilo principal  sin que esta tarea \n    se haya concluido estos hilos secundarios siguen dependiendo del hilo principal.\n   \n   -Concurrencia:  tambien es una tarea no bloqueante que puede o no puede depender el hilo principal.\n   a diferencia de la asincronia la concurrencia no ejecuta la tarea de forma ordenada.\n\n   - Paralelismo: es la capacidad de ejecutar tareas de manera silmutanea a diferencia de las anteriores \n   esta se ejecuta de forma separada al hilo principal esto quiere decir que tiene su propio espacio en \n   memoria y procesamiento de computo.\n  \n */\n\n  func runTask(_ nameTask: String, duration:Double) async throws -> Bool {\n      let clock = ContinuousClock()\n      var isCompleted = false\n\n      let time = try await clock.measure {\n         print(\"Starting task: \\(nameTask)\")\n         try await Task.sleep(for: .seconds(duration))\n         print(\"Finished task: \\(nameTask)\")\n         isCompleted = true\n      } \n      print(\"Task \\(nameTask) took \\(time) seconds\")\n      return isCompleted\n   }\n \n   let completed = try await runTask(\"Task 1\", duration: 1);if completed {\n        print(\"Task completed\")\n    }\n   \n  // reto extra para correr alguna tarea en paralelo solo es necesario poner async antes de la tarea\n   async let isCompletedC = runTask(\"Task C\", duration: 3)\n   async let isCompletedB = runTask(\"Task B\", duration: 2)\n   async let isCompletedA = runTask(\"Task A\", duration: 1)\n   \n   // alamcenar los resultados de las tareas \n   let isCompleted =  try await [isCompletedA, isCompletedB, isCompletedC]\n\n  // comprobar que todas las tareas se han completado si todos los valores son true ejecutara la ultima tarea \n   if isCompleted.allSatisfy({$0==true}){\n       let isCompleted = try await runTask(\"Task D\", duration: 1); if isCompleted{\n           print(\"All tasks completed.\")\n        }\n    } \n\n\n\n\n   \n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/swift/kontroldev.swift",
    "content": "import Foundation\n\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n * asíncrona una función que tardará en finalizar un número concreto de\n * segundos parametrizables. También debes poder asignarle un nombre.\n * La función imprime su nombre, cuándo empieza, el tiempo que durará\n * su ejecución y cuando finaliza.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han\n *   finalizado.\n */\n\nimport Foundation\n\n// Función asíncrona\nfunc asyncFunction(name: String, duration: Int) {\n    let startTime = Date()\n    print(\"La función '\\(name)' ha empezado a las \\(startTime) y durará \\(duration) segundos.\")\n\n    // Simula una tarea larga usando sleep\n    sleep(UInt32(duration))\n    \n    let endTime = Date()\n    print(\"La función '\\(name)' ha terminado a las \\(endTime).\")\n}\n\n// Función que ejecuta la función asíncrona\nfunc executeAsyncFunction(name: String, duration: Int) {\n    DispatchQueue.global().async {\n        asyncFunction(name: name, duration: duration)\n    }\n}\n\n// Ejemplo de uso\nexecuteAsyncFunction(name: \"Tarea 1\", duration: 5)\nexecuteAsyncFunction(name: \"Tarea 2\", duration: 3)\n\n// Mantén el programa en ejecución para que puedas ver el resultado de las funciones asíncronas\nRunLoop.current.run(until: Date().addingTimeInterval(10))\n\n//MARK: - DIFICULTAD EXTRA (opcional)\n\n// Función asíncrona 👇\nfunc asyncFunction(name: String, duration: Int, completion: @escaping () -> Void) {\n    let startTime = Date()\n    print(\"La función '\\(name)' ha empezado a las \\(startTime) y durará \\(duration) segundos.\")\n    \n    // Simula una tarea larga usando el metodo sleep\n    sleep(UInt32(duration))\n    \n    let endTime = Date()\n    print(\"La función '\\(name)' ha terminado a las \\(endTime).\")\n    \n    // Llama al completion 'handler' al finalizar\n    completion()\n}\n\n// Ejecuta la función asíncrona con un DispatchGroup\nfunc executeAsyncFunction(name: String, duration: Int, group: DispatchGroup) {\n    group.enter()\n    DispatchQueue.global().async {\n        asyncFunction(name: name, duration: duration) {\n            group.leave()\n        }\n    }\n}\n\n// Crear un DispatchGroup para sincronizar las tareas\nlet group = DispatchGroup()\n\n// Ejecutar funciones C, B y A en paralelo\nexecuteAsyncFunction(name: \"C\", duration: 3, group: group)\nexecuteAsyncFunction(name: \"B\", duration: 2, group: group)\nexecuteAsyncFunction(name: \"A\", duration: 1, group: group)\n\n// Ejecutar la función D después de que C, B y A hayan finalizado\ngroup.notify(queue: DispatchQueue.global()) {\n    asyncFunction(name: \"D\", duration: 1) {\n        print(\"Todas las funciones han terminado.\")\n    }\n}\n\n// Mantén el programa en ejecución para ver los resultados\nRunLoop.current.run(until: Date().addingTimeInterval(10))\n\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/swift/pedroomar23.swift",
    "content": "import Foundation\n\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n * asíncrona una función que tardará en finalizar un número concreto de\n * segundos parametrizables. También debes poder asignarle un nombre.\n * La función imprime su nombre, cuándo empieza, el tiempo que durará\n * su ejecución y cuando finaliza.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han\n *   finalizado.\n */\n\nfunc starProgram(_ name: String, duration: Double) async {\n    let iniciarProgram = Date()\n    let finishPrgrom = Date()\n\n    let formatter = DateFormatter()\n    formatter.dateFormat = \"HH:mm:ss\"\n\n    print(\"El programa tiene como nombre \\(formatter.String(from: iniciarProgram))\")\n\n    do {\n        try await Task.slepp(from: .seconds(duration))\n    } catch {\n        print(\"Ha ocurrido un error a la hora de obtener la duracion \\(error.localizedDescription)\")\n    }\n\n    print(\"El programa de nombre \\(name) tuvo una duracion de \\(duration)\")\n}\n\nlet newProgram = starProgram(\"Games\", duration: 1)\nprint(newProgram)\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/typescript/AChapeton.ts",
    "content": "const asyncFunction: (name: string, seconds: number) => Promise<void> = async (name: string, seconds: number) => {\n  console.log(`Inicia la ejecucion de ${name}`)\n  console.log(`Duracion de ${name}: ${seconds} segundos`)\n  \n  await new Promise<void>(res => {\n    setTimeout(res, seconds * 1000)\n  })\n\n  console.log(`Finaliza la ejecuncion de ${name}`)\n}\n\nconst main: () => Promise<void> = async () => {\n  const promise1: Promise<void> = asyncFunction('Funcion 1', 5)\n  const promise2: Promise<void> = asyncFunction('Funcion 2', 3)\n\n  await Promise.all([promise1, promise2])\n}\n\nmain()\n\n\n// DIFICULTAD EXTRA\n\nconst funcionC: () => Promise<void> = async () => {\n  console.log(`Inicia la ejecucion de la funcion C`)\n  \n  await new Promise<void>(res => {\n    setTimeout(res, 3000)\n  })\n\n  console.log(`Finaliza la ejecucion de la funcion C luego de 3 segundos`)\n}\n\nconst funcionB: () => Promise<void> = async () => {\n  console.log(`Inicia la ejecucion de la funcion B`)\n  \n  await new Promise<void>(res => {\n    setTimeout(res, 2000)\n  })\n\n  console.log(`Finaliza la ejecucion de la funcion B luego de 2 segundos`)\n}\n\nconst funcionA: () => Promise<void> = async () => {\n  console.log(`Inicia la ejecucion de la funcion A`)\n  \n  await new Promise<void>(res => {\n    setTimeout(res, 1000)\n  })\n\n  console.log(`Finaliza la ejecucion de la funcion A luego de 1 segundo`)\n}\n\nconst funcionD: () => Promise<void> = async () => {\n  console.log(`Inicia la ejecucion de la funcion D`)\n  \n  await new Promise<void>(res => {\n    setTimeout(res, 1000)\n  })\n\n  console.log(`Finaliza la ejecucion de la funcion D luego de 1 segundo`)\n}\n\nconst mainFunction: () => Promise<void>  = async () => {\n  const respuestaC: Promise<void> = funcionC()\n  const respuestaB: Promise<void> = funcionB()\n  const respuestaA: Promise<void> = funcionA()\n\n  await Promise.all([respuestaC, respuestaB, respuestaA])\n\n  const respuestaD: void = await funcionD()\n}\n\nmainFunction()"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/typescript/EdiedRamos.ts",
    "content": "/**\n * Async function to simulate a timed execution.\n * @param name Name of the function.\n * @param timeInSeconds Time until the function ends in seconds.\n * @returns Promise<void>\n */\nfunction asyncFunction(name: string, timeInSeconds: number): Promise<void> {\n  return new Promise((resolve) => {\n    console.log(`${name}: Inicia la ejecución (⌚ ${timeInSeconds}s)`);\n    setTimeout(() => {\n      console.log(`${name}: Finaliza la ejecución`);\n      resolve();\n    }, timeInSeconds * 1000);\n  });\n}\n\n(() => {\n  // Run functions C, B and A in parallel\n  Promise.all([\n    asyncFunction(\"C\", 3),\n    asyncFunction(\"B\", 2),\n    asyncFunction(\"A\", 1),\n  ])\n    // Run function D after the previous functions have been executed successfully\n    .then(() => asyncFunction(\"D\", 1))\n    // Handle errors if something goes wrong\n    .catch((err) => console.log(err));\n})();\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/typescript/IgleDev.ts",
    "content": "// Ejercicio 1\n\n    let funcionAsincrona : (nombre : string, segundos : number) => Promise<void> = async(nombre, segundos) => {\n        console.log('Se inicia la ejecución');\n        console.log(`Duración de ${nombre} - ${segundos} segundos`);\n\n        await new Promise<void>(res => {\n            setTimeout(res, segundos * 1000)\n        });\n\n        console.log('Se acaba la ejecución');\n    }\n\n    let ejercicio1: () => Promise<void> = async () => {\n        let promesa1: Promise<void> = funcionAsincrona('Función 1', 5)\n        let promesa2: Promise<void> = funcionAsincrona('Función 2', 10)\n        await Promise.all([promesa1, promesa2]);\n    }\n\n    ejercicio1();\n\n// EJERCICIO EXTRA\n\n    let funcionC: () => Promise<void> = async () => {\n        console.log('Inicia la ejecución de la funcion C');\n\n        await new Promise<void>(res => {\n          setTimeout(res, 3000)\n        });\n    \n        console.log('Finaliza la ejecución de la funcion C después de 3 segundos');\n    }\n\n    let funcionB: () => Promise<void> = async () => {\n        console.log('Inicia la ejecución de la funcion B');\n\n        await new Promise<void>(res => {\n          setTimeout(res, 2000)\n        });\n    \n        console.log('Finaliza la ejecución de la funcion B después de 2 segundos');\n    }\n\n    let funcionA: () => Promise<void> = async () => {\n        console.log('Inicia la ejecución de la funcion A');\n\n        await new Promise<void>(res => {\n          setTimeout(res, 1000)\n        });\n    \n        console.log('Finaliza la ejecución de la funcion A después de 1 segundos');\n    }\n\n    let funcionD: () => Promise<void> = async () => {\n        console.log('Inicia la ejecución de la funcion D');\n\n        await new Promise<void>(res => {\n          setTimeout(res, 1000)\n        });\n    \n        console.log('Finaliza la ejecución de la funcion D después de 1 segundos');\n    }\n\n    let ejercicioExtra: () => Promise<void>  = async () => {\n        let respuestaC: Promise<void> = funcionC();\n        let respuestaB: Promise<void> = funcionB();\n        let respuestaA: Promise<void> = funcionA();\n    \n        await Promise.all([respuestaC, respuestaB, respuestaA])\n    \n        let respuestaD: void = await funcionD();\n    }\n\n    ejercicioExtra();"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/typescript/Sac-Corts.ts",
    "content": "async function runAsyncTask(taskName: string, durationInSeconds: number): Promise<void> {\n    console.log(`${taskName} start.`);\n    console.log(`Duration: ${durationInSeconds} seconds.`);\n\n    const wait = (ms: number): Promise<void> => new Promise((resolve) => setTimeout(resolve, ms));\n\n    await wait(durationInSeconds * 1000);\n\n    console.log(`${taskName} ends.`);\n}\n\n// runAsyncTask('Task 1', 3);\n// runAsyncTask('Task 2', 6);\n\n// ** Extra Exercise ** //\n\nfunction delay(durationInSeconds: number, functionName: string): Promise<void> {\n    return new Promise((resolve) => {\n        setTimeout(() => {\n            console.log(`${functionName} has ended after ${durationInSeconds} seconds.`);\n            resolve();\n        }, durationInSeconds * 1000);\n    });\n}\n\nasync function functionA(): Promise<void> {\n    await delay(1, 'Function A');\n}\n\nasync function functionB(): Promise<void> {\n    await delay(2, 'Function B');\n}\n\nasync function functionC(): Promise<void> {\n    await delay(3, 'Function C');\n}\n\nasync function functionD(): Promise<void> {\n    await delay(1, 'Function D');\n}\n\nasync function executeFunctionsInOrder(): Promise<void> {\n    await Promise.all([functionC(), functionB(), functionA()]);\n    await functionD();\n}\n\nexecuteFunctionsInOrder();"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/typescript/duendeintemporal.ts",
    "content": "//#15 { retosparaprogramadores } ASINCRONÍA \n\n// Short for console.log()\nconst log = console.log;\n\n// Conditional check for browser environment\nif (typeof window !== 'undefined') {\n    window.addEventListener('load', () => {\n        const body: HTMLBodyElement | null = document.querySelector('body');\n        const title = document.createElement('h1');\n\n        body?.style.setProperty('background', '#000');\n        body?.style.setProperty('text-align', 'center');\n\n        title.textContent = 'Retosparaprogramadores #15.';\n        title.style.setProperty('font-size', '3.5vmax');\n        title.style.setProperty('color', '#fff');\n        title.style.setProperty('line-height', '100vh');\n\n        body?.appendChild(title);\n\n        setTimeout(() => {\n            alert('Retosparaprogramadores #15. Please open the Browser Developer Tools.');\n        }, 2000);\n        log('Retosparaprogramadores #15');\n    });\n} else {\n    log('This code is designed to run in a browser environment. Skipping window-related code.');\n    log('Retosparaprogramadores #15');\n}\n\n/**\n * Simulates an asynchronous function that runs for a specified number of seconds.\n * @param name - The name of the function.\n * @param seconds - The duration in seconds that the function should run.\n * @returns A promise that resolves when the function completes.\n */\nfunction runFunc(name: string, seconds: number): Promise<void> {\n    return new Promise((resolve) => {\n        log(`${name} - Start at: ${new Date().toLocaleTimeString()}`);\n        log(`${name} - Last: ${seconds} seconds`);\n\n        setTimeout(() => {\n            log(`${name} - Ends at: ${new Date().toLocaleTimeString()}`);\n            resolve();\n        }, seconds * 1000);\n    });\n}\n\n/**\n * Runs multiple asynchronous functions in parallel and then runs a final function sequentially.\n */\nasync function runFunces(): Promise<void> {\n    // Run functions C, B, and A in parallel\n    const functionC = runFunc('Function C', 3);\n    const functionB = runFunc('Function B', 2);\n    const functionA = runFunc('Function A', 1);\n\n    // Wait for all functions to complete\n    await Promise.all([functionC, functionB, functionA]);\n\n    // Run function D sequentially after the others complete\n    await runFunc('Function D', 1);\n}\n\n// Execute the main function\nrunFunces();\n\n/* Logs: \n         Function C - Start at: 13:01:18\n         Function C - Last: 3 seconds\n         Function B - Start at: 13:01:18\n         Function B - Last: 2 seconds\n         Function A - Start at: 13:01:18\n         Function A - Last: 1 seconds\n         Function A - Ends at: 13:01:19\n         Function B - Ends at: 13:01:20\n         Function C - Ends at: 13:01:21\n         Function D - Start at: 13:01:21\n         Function D - Last: 1 seconds\n         Function D - Ends at: 13:01:22\n*/"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/typescript/eulogioep.ts",
    "content": "/**\n * Interfaz que define la estructura de una tarea asíncrona\n */\ninterface AsyncTask {\n    name: string;\n    duration: number;\n    status: 'pending' | 'running' | 'completed';\n    startTime?: Date;\n    endTime?: Date;\n}\n\n/**\n * Clase que implementa una tarea asíncrona\n */\nclass Task implements AsyncTask {\n    public status: 'pending' | 'running' | 'completed' = 'pending';\n    public startTime?: Date;\n    public endTime?: Date;\n\n    constructor(\n        public name: string,\n        public duration: number\n    ) {}\n\n    /**\n     * Ejecuta la tarea y retorna una promesa\n     * @returns Promise<void>\n     */\n    async execute(): Promise<void> {\n        this.status = 'running';\n        this.startTime = new Date();\n        \n        console.log(`${this.name} - Iniciando...`);\n        console.log(`${this.name} - Durará ${this.duration} segundos`);\n        \n        return new Promise<void>((resolve) => {\n            setTimeout(() => {\n                this.status = 'completed';\n                this.endTime = new Date();\n                console.log(`${this.name} - Finalizada`);\n                resolve();\n            }, this.duration * 1000);\n        });\n    }\n}\n\n/**\n * Clase que gestiona la ejecución de tareas asíncronas\n */\nclass TaskManager {\n    private tasks: Map<string, Task> = new Map();\n\n    /**\n     * Añade una nueva tarea al gestor\n     * @param name Nombre de la tarea\n     * @param duration Duración en segundos\n     */\n    addTask(name: string, duration: number): void {\n        this.tasks.set(name, new Task(name, duration));\n    }\n\n    /**\n     * Ejecuta una demostración básica con una sola tarea\n     */\n    async runBasicDemo(): Promise<void> {\n        console.log(\"=== Demostración Básica ===\");\n        const task = new Task(\"TareaEjemplo\", 2);\n        await task.execute();\n    }\n\n    /**\n     * Ejecuta la dificultad extra del ejercicio\n     */\n    async runExtraChallenge(): Promise<void> {\n        console.log(\"\\n=== Dificultad Extra ===\");\n        \n        // Crear tareas\n        this.addTask(\"Tarea C\", 3);\n        this.addTask(\"Tarea B\", 2);\n        this.addTask(\"Tarea A\", 1);\n        this.addTask(\"Tarea D\", 1);\n\n        // Ejecutar tareas C, B y A en paralelo\n        const parallelTasks = [\"Tarea C\", \"Tarea B\", \"Tarea A\"].map(name => \n            this.tasks.get(name)!.execute()\n        );\n\n        // Esperar a que terminen las tareas paralelas\n        await Promise.all(parallelTasks);\n\n        // Ejecutar tarea D\n        await this.tasks.get(\"Tarea D\")!.execute();\n    }\n\n    /**\n     * Obtiene estadísticas de ejecución de las tareas\n     */\n    getStats(): string {\n        let stats = \"\\nEstadísticas de ejecución:\\n\";\n        this.tasks.forEach(task => {\n            if (task.startTime && task.endTime) {\n                const executionTime = \n                    (task.endTime.getTime() - task.startTime.getTime()) / 1000;\n                stats += `${task.name}: ${executionTime.toFixed(2)} segundos\\n`;\n            }\n        });\n        return stats;\n    }\n}\n\n/**\n * Función principal que ejecuta todo el programa\n */\nasync function main(): Promise<void> {\n    const manager = new TaskManager();\n\n    try {\n        await manager.runBasicDemo();\n        await manager.runExtraChallenge();\n        console.log(manager.getStats());\n    } catch (error) {\n        console.error(\"Error durante la ejecución:\", error);\n    }\n}\n\n// Ejecutar el programa\nmain().catch(error => console.error('Error:', error));\n\n// Para compilar: tsc nombrearchivo.ts\n// Para ejecutar: node nombrearchivo.js"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/typescript/hozlucas28.ts",
    "content": "import { setTimeout } from 'timers/promises'\n\n/*\n    Asynchrony...\n*/\n\nconsole.log('Asynchrony...')\n\nconsole.log(\n\t'\\n> Instructions executed before calling `asyncFn` (asynchrony function)'\n)\n\nasync function asyncFn(time: number): Promise<void> {\n\tconsole.log('\\nasyncFn start...')\n\tconsole.time('asyncFn')\n\n\tawait setTimeout(time)\n\n\tconsole.timeEnd('asyncFn')\n\tconsole.log('asyncFn end!')\n\n\tadditionalChallenge()\n}\n\nasyncFn(5 * 1000)\n\nconsole.log(\n\t'\\n> Instructions executed after called `asyncFn` (asynchrony function)\\n'\n)\n\n/*\n    Additional challenge...\n*/\n\nfunction additionalChallenge() {\n\tconsole.log(\n\t\t'\\n# ---------------------------------------------------------------------------------- #\\n'\n\t)\n\n\tconsole.log('Additional challenge...\\n')\n\n\tconst aFn = async () => {\n\t\tconsole.time('aFn')\n\t\tawait setTimeout(1 * 1000)\n\t\tconsole.timeEnd('aFn')\n\t}\n\n\tconst bFn = async () => {\n\t\tconsole.time('bFn')\n\t\tawait setTimeout(2 * 1000)\n\t\tconsole.timeEnd('bFn')\n\t}\n\n\tconst cFn = async () => {\n\t\tconsole.time('cFn')\n\t\tawait setTimeout(3 * 1000)\n\t\tconsole.timeEnd('cFn')\n\t}\n\n\tconst dFn = async () => {\n\t\tconsole.time('dFn')\n\t\tawait setTimeout(1 * 1000)\n\t\tconsole.timeEnd('dFn')\n\t}\n\n\tPromise.all([aFn(), bFn(), cFn()]).then(async () => await dFn())\n}\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/typescript/miguelex.ts",
    "content": "function asyncTask(name: string, seconds: number): Promise<void> {\n    return new Promise<void>((resolve, reject) => {\n        console.log(`Comienza la función ${name}. Duración de ${seconds} segundos. Hora de comienzo ${new Date().toLocaleTimeString()}`);\n        setTimeout(() => {\n            console.log(`Finaliza la función ${name}. Hora de finalización ${new Date().toLocaleTimeString()}`);\n            resolve();\n        }, seconds * 1000);\n    });\n}\n\nasync function extra(): Promise<void> {\n    await Promise.all([\n        asyncTask(\"C\", 3),\n        asyncTask(\"B\", 2),\n        asyncTask(\"A\", 1)\n    ]);\n    await asyncTask(\"D\", 1);\n}\n\nasyncTask(\"Test 1\", 5)\n    .then(() => extra())\n    .catch(error => console.error(error));\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/typescript/nlarrea.ts",
    "content": "/*\n * EJERCICIO:\n * Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n * asíncrona una función que tardará en finalizar un número concreto de\n * segundos parametrizables. También debes poder asignarle un nombre.\n * La función imprime su nombre, cuándo empieza, el tiempo que durará\n * su ejecución y cuando finaliza.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han\n *   finalizado.\n*/\n\n\nfunction printParameters(seconds: number, name: string): Promise<void> {\n    console.log(\n        `Task: ${name}\\nTime: ${seconds}\\nStart: ${new Date().toLocaleTimeString()}\\n`\n    )\n\n    return new Promise((resolve) => {\n        setTimeout(() => {\n            console.log(`Task: ${name}\\nEnd: ${new Date().toLocaleTimeString()}\\n`)\n            resolve()\n        }, seconds * 1000)\n    })\n}\n\n\nasync function mainFunction() {\n    await Promise.all([\n        printParameters(5, 'task 1'),\n        printParameters(8, 'task 2'),\n        printParameters(1, 'task 3'),\n        printParameters(15, 'task 4')\n    ])\n}\n\n\nmainFunction()\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Utilizando el concepto de asincronía y la función anterior, crea\n * el siguiente programa que ejecuta en este orden:\n * - Una función C que dura 3 segundos.\n * - Una función B que dura 2 segundos.\n * - Una función A que dura 1 segundo.\n * - Una función D que dura 1 segundo.\n * - Las funciones C, B y A se ejecutan en paralelo.\n * - La función D comienza su ejecución cuando las 3 anteriores han\n *   finalizado.\n*/\n\n\nasync function asyncRun() {\n    const tasks: Promise<void>[] = [\n        printParameters(3, 'C'),\n        printParameters(2, 'B'),\n        printParameters(1, 'A')\n    ]\n    await Promise.all(tasks)\n\n    await printParameters(1, 'D')\n}\n\n\nasyncRun()"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/typescript/roswer13.ts",
    "content": "// EJERCICIO:\n// Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n// asíncrona una función que tardará en finalizar un número concreto de\n// segundos parametrizables. También debes poder asignarle un nombre.\n// La función imprime su nombre, cuándo empieza, el tiempo que durará\n// su ejecución y cuando finaliza.\n\nasync function myAsyncFunction(name: string, seconds: number): Promise<void> {\n    return new Promise<void>((resolve, reject) => {\n        if (seconds < 0) {\n            console.error(\"Seconds must be a positive number.\");\n            return;\n        }\n        console.log(`${name} started at ${new Date().toLocaleTimeString()}, duration: ${seconds} seconds.`);\n        setTimeout(() => {\n            console.log(`${name} finished at ${new Date().toLocaleTimeString()}`);\n            resolve();\n        }, seconds * 1000);\n    });\n}\n\nmyAsyncFunction(\"Task 1\", 5);\n\n// DIFICULTAD EXTRA (opcional):\n// Utilizando el concepto de asincronía y la función anterior, crea\n// el siguiente programa que ejecuta en este orden:\n// - Una función C que dura 3 segundos.\n// - Una función B que dura 2 segundos.\n// - Una función A que dura 1 segundo.\n// - Una función D que dura 1 segundo.\n// - Las funciones C, B y A se ejecutan en paralelo.\n// - La función D comienza su ejecución cuando las 3 anteriores han\n//   finalizado.\n\nasync function myAsyncMultipleFunctions(): Promise<void> {\n    await Promise.all([\n        myAsyncFunction(\"C\", 3),\n        myAsyncFunction(\"B\", 2),\n        myAsyncFunction(\"A\", 1)\n    ]).then(() => myAsyncFunction(\"D\", 1));\n}\n\nmyAsyncMultipleFunctions();\n\n\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/typescript/victor-Casta.ts",
    "content": "async function myAsyncFunction():Promise<void> {\n  console.log('myAsyncFunction')\n  console.log('la ejecución de la función tardará 5 segundos')\n  const data = await new Promise((resolve) => {\n    setTimeout(() => {console.log('Función finalizada')}, 5000)\n  })\n  console.log(data)\n}\n\nmyAsyncFunction()\n\n// extra\n\nasync function D(): Promise<void> {\n  const data = await new Promise((resolve) => setTimeout(() => resolve(\"D\"), 1000))\n  console.log(data)\n}\n\nasync function fetchMultiple(): Promise<void> {\n  const [data1, data2, data3] = await Promise.all([\n    new Promise((resolve) => setTimeout(() => resolve(\"A\"), 1000)),\n    new Promise((resolve) => setTimeout(() => resolve(\"B\"), 2000)),\n    new Promise((resolve) => setTimeout(() => resolve(\"C\"), 3000)),\n  ])\n\n  console.log(data1)\n  console.log(data2)\n  console.log(data3)\n\n  await D()\n}\n\nfetchMultiple()"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/typescript/victoriaparraf.ts",
    "content": "//FUNCION ASINCRONA\nfunction esperar(segundos: number): Promise<void> {\n    return new Promise(resolve => setTimeout(resolve, segundos * 1000));\n}\n\nasync function ejecutarFuncion(nombre: string, duracionSegundos: number) {\n    console.log(`La función ${nombre} comienza a ejecutarse.`);\n    console.log(`Duración esperada: ${duracionSegundos} segundos.`);\n\n    await esperar(duracionSegundos);\n\n    console.log(`La función ${nombre} ha finalizado su ejecución.`);\n}\n\n// Ejecutar una función de ejemplo\nejecutarFuncion('Ejemplo', 5);\n\n//EXTRA\n//ejecucion de varias funciones asincronas\n\nasync function main() {\n    // Crear las funciones A, B, y C que se ejecutarán en paralelo\n    const funcionC = ejecutarFuncion('C', 3);\n    const funcionB = ejecutarFuncion('B', 2);\n    const funcionA = ejecutarFuncion('A', 1);\n\n    // Esperar a que todas las funciones C, B, y A terminen\n    await Promise.all([funcionC, funcionB, funcionA]);\n\n    // Ejecutar la función D después de que C, B, y A hayan terminado\n    await ejecutarFuncion('D', 1);\n}\n\n// Llamar a la función principal\nmain();\n\n"
  },
  {
    "path": "Roadmap/15 - ASINCRONÍA/vb.net/kenysdev.vb",
    "content": "' ╔══════════════════════════════════════╗\n' ║ Autor:  Kenys Alvarado               ║\n' ║ GitHub: https://github.com/Kenysdev  ║\n' ║ 2024 -  VB.NET                       ║\n' ╚══════════════════════════════════════╝\n'-----------------------------------------------\n'* ASINCRONÍA\n'-----------------------------------------------\nImports System.Threading.Tasks\nModule Program\n    '* EJERCICIO #1:\n    '* Utilizando tu lenguaje, crea un programa capaz de ejecutar de manera\n    '* asíncrona una función que tardará en finalizar un número concreto de\n    '* segundos parametrizables. También debes poder asignarle un nombre.\n    '* La función imprime su nombre, cuándo empieza, el tiempo que durará\n    '* su ejecución y cuando finaliza.\n\n    Async Function Process(name As String, time As Integer) As Task\n        Console.WriteLine($\"- Iniciando función: {name} -> Duración: {time}\")\n        Await Task.Delay(time * 1000)\n        Console.WriteLine($\"* Función {name} ha terminado.\")\n    End Function\n\n    Async Function Test() As Task\n        Await Task.WhenAll(\n            Process(\"Test 2\", 4),\n            Process(\"Test 1\", 2)\n        )\n    End Function\n\n    '* EJERCICIO #2\n    '* Utilizando el concepto de asincronía y la función anterior, crea\n    '* el siguiente programa que ejecuta en este orden:\n    '* - Una función C que dura 3 segundos.\n    '* - Una función B que dura 2 segundos.\n    '* - Una función A que dura 1 segundo.\n    '* - Una función D que dura 1 segundo.\n    '* - Las funciones C, B y A se ejecutan en paralelo.\n    '* - La función D comienza su ejecución cuando las 3 anteriores han\n    '*   finalizado.\n\n    Async Function InParallel() As Task\n        Await Task.WhenAll(\n            Process(\"C\", 3),\n            Process(\"B\", 2),\n            Process(\"A\", 1)\n        )\n\n        Await Process(\"D\", 1)\n    End Function\n\n    Sub Main()\n        Test().Wait()\n        InParallel().Wait()\n    End Sub\nEnd Module\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/bash/h4ckxel.sh",
    "content": "#!/bin/bash\n\n# Script de validación utilizando expresiones regulares\n\nstring=\"Pepe tiene el número 1234 y 5678\"\nregex=\"[0-9]+\"\nnumbers=$(grep -oE \"$regex\" <<< \"$string\")\necho -e \"[+] Los números encontrados en la cadena de texto son: $numbers\"\n\necho -e \"\\n\\n================================ DIFICULTAD EXTRA ================================\\n\"\n\n# Función para solicitar la entrada de usuario\nsolicitar_entrada() {\n    local mensaje=\"$1\"\n    local variable=\"$2\"\n    read -p \"$mensaje\" \"$variable\"\n}\n\n# Función para validar un correo electrónico\nvalidar_email() {\n    solicitar_entrada \"[+] Introduce un email: \" email\n    regex_email=\"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$\"\n    \n    if [[ $email =~ $regex_email ]]; then\n        echo -e \"[+] El email introducido es válido.\\n\"\n    else\n        echo -e \"[!] El email introducido no es válido.\\n\"\n    fi\n}\n\n# Función para validar un número de teléfono\nvalidar_telefono() {\n    solicitar_entrada \"[+] Introduce un número de teléfono: \" telefono\n    regex_telefono=\"^\\+?[0-9]{1,3}?[-. ]?\\(?[0-9]{1,4}?\\)?[-. ]?[0-9]{1,4}[-. ]?[0-9]{1,9}$\"\n    \n    if [[ $telefono =~ $regex_telefono ]]; then\n        echo -e \"[+] El número de teléfono introducido es válido.\\n\"\n    else\n        echo -e \"[!] El número de teléfono introducido no es válido.\\n\"\n    fi\n}\n\n# Función para validar una URL\nvalidar_url() {\n    solicitar_entrada \"[+] Introduce una dirección URL: \" url\n    regex_url=\"^(https?://)?(www\\.)?[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}(/.*)?$\"\n    \n    if [[ $url =~ $regex_url ]]; then\n        echo -e \"[+] La dirección URL introducida es válida.\\n\"\n    else\n        echo -e \"[!] La dirección URL introducida no es válida.\\n\"\n    fi\n}\n\n# Ejecución de las validaciones\nvalidar_email\nvalidar_telefono\nvalidar_url\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/bash/rantamhack.sh",
    "content": "#!/bin/bash\n\n# Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n# creando una que sea capaz de encontrar y extraer todos los numeros\n# de un texto.\n\necho -e \"\\n\\n=======================================EJERCICIO=======================================\\n\\n\"\n\nstring=\"Mariano 1234\"\nregex=\"\\d+\"\nnumbers=$(grep -oP \"$regex\" <<< \"$string\")\necho -e \"\\n[+] Los numeros que hay en la cadena de texto son: $numbers\"\n\n\necho -e \"\\n\\n=======================================DIFICULTAD EXTRA=======================================\\n\\n\"\n\n\n# Crea 3 expresiones regulares (a tu criterio) capaces de:\n#   - Validar un email.\n#   - Validar un numero de telefono.\n#   - Validar una url.\n\n\nfunction check_email(){\n    read -p \"[+] Introduce un email: \" email\n    verify_email=\"^[a-zA-Z0-9_+-.]+@[a-zA-Z0-9_+-]+\\.[a-zA-Z]{2,}$\"\n    \n    if [[ $email =~ $verify_email ]]; then\n        echo -e \"\\n[+] El email introducido es correcto\\n\"\n    else\n        echo -e \"\\n[!] El email introducido no es correcto\\n\"\n    fi\n}\n\n\nfunction check_number(){\n    read -p \"[+] Introduce un un numero de telefono: \" number_phone\n    verify_phone=\"^[+[0-9]{1,3}]?[0-9]{4,9}$\"\n    \n    if [[ $number_phone =~ $verify_phone ]]; then\n        echo -e \"\\n[+] El numero introducido es correcto\\n\"\n    else\n        echo -e \"\\n[!] El numero introducido es incorrecto\\n\"\n    fi\n}\n\nfunction check_url(){\n    read -p \"[+] Introduce una direccion url: \" url\n    verify_url=\"((https?://(www\\.)?)|www\\.)\\w{3,}\\.[a-z]{2,}\"\n\n    if [[ $url =~ $verify_url ]]; then\n        echo -e \"\\n[+] La direccion url introdudida es correcta\\n\"\n    else\n        echo -e \"\\n[!] La direccion url introducida no es corrrecta\\n\"\n    fi\n}\n\n\ncheck_email\ncheck_number\ncheck_url\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/c#/Andreavzqz.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing Systeme.Text.RegularExpressions;\n\n\nnamespace ExpresionesRegulares\n{\n    class Program\n    {\n        \n        static void Main(string[] args)\n        {\n\n            // Ejemplo de texto con números\n            string texto = \"Mi número de telefono es: 123456789 y mi correo es: ejemplo@ejemplo.com. Hoy es 31/07/2024\";\n\n            // Expresion regular para encontrar números\n            string patronNumeros = @\"\\d+\";\n            List<string> numerosEncontrados = new List<string>();\n\n            foreach(Match match in Regex.Matches(texto, patronNumeros))\n            {\n                numerosEncontrados.Add(matches.Value);\n            }\n\n            Console.WriteLine(\"Números encontrados:\");\n            foreach(string numero in numerosEncontrados)\n            {\n                Console.WriteLine(numero);\n            }\n\n\n            // Difucultad extra\n            string email = \"ejemplo@ejemplo.com\";\n            string telefono = \"+34 123456789\";\n            string url = \"https://www.example.com\";\n\n            string patronEmail = @\"^[\\w\\.-]+@[a-zA-Z\\d\\.-]+\\.[a-zA-Z]{2,}$\";\n            string patronTelefono = @\"^\\+?\\d{1,4}?[\\s.-]?\\(?\\d{1,4}?\\)?[\\s.-]?\\d{1,4}[\\s.-]?\\d{1,4}[\\s.-]?\\d{1,9}$\";\n            string patronUrl = @\"^https?://([\\w-]+(\\.[\\w-]+)+)([/\\w- ./?%&=]*)?$\";\n\n\n            Console.WriteLine($\"\\nEmail '{email}' es válido: {Regex.IsMatch(email, patronEmail)}\");\n            Console.WriteLine($\"Teléfono '{telefono}' es válido: {Regex.IsMatch(telefono, patronTelefono)}\");\n            Console.WriteLine($\"URL '{url}' es válida: {Regex.IsMatch(url, patronUrl)}\");\n        }\n    }\n/*\n\n\nExplicación \n\nExtracción de Números del Texto:\nSe define un texto con varios números incrustados.\nSe utiliza una expresión regular \\d+ para encontrar secuencias de dígitos. \\d representa cualquier dígito y + indica una o más ocurrencias.\nRegex.Matches se utiliza para encontrar todas las coincidencias en el texto. Los números encontrados se almacenan en una lista y se imprimen.\n\nValidaciones Adicionales:\n\nValidación de Email:\nLa expresión regular ^[\\w\\.-]+@[a-zA-Z\\d\\.-]+\\.[a-zA-Z]{2,}$ valida un formato de email básico.\n^[\\w\\.-]+ corresponde al nombre del usuario, @ es el carácter que separa el nombre del dominio, [a-zA-Z\\d\\.-]+\\.[a-zA-Z]{2,}$ valida el dominio.\n\nValidación de Número de Teléfono:\nLa expresión regular ^\\+?\\d{1,4}?[\\s.-]?\\(?\\d{1,4}?\\)?[\\s.-]?\\d{1,4}[\\s.-]?\\d{1,4}[\\s.-]?\\d{1,9}$ valida números de teléfono con varios formatos.\nEsta expresión permite un prefijo de código de país opcional con un +, seguido de una combinación de números y separadores como espacios, puntos o guiones.\n\nValidación de URL:\nLa expresión regular ^https?://([\\w-]+(\\.[\\w-]+)+)([/\\w- ./?%&=]*)?$ valida URLs.\n^https?:// asegura que la URL comienza con http o https.\n([\\w-]+(\\.[\\w-]+)+) valida el nombre de dominio.\n([/\\w- ./?%&=]*)?$ valida la ruta y los parámetros adicionales.\n\n\n*/\n}\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/c#/hequebo.cs",
    "content": "using System.Text.RegularExpressions;\n\nclass Program\n{\n    static void Main(string[] args)\n    {\n        #region RegEx\n        // Expresiones Regulares\n        string texto = \"1Est3e T8ext0o tie5n4e n0um98er5467os q78u11e de7851b44e651n313 s51e35r 00ob5t3en5i1d6o0s5\";\n        // El siguiente patrón busca números del 0 al 9\n        string pattern = \"[0-9]\";\n        /*\n         * Se inicializa un objeto de tipo Regex y se envía\n         * el patrón anterior en su constructor\n         */\n        var regex = new Regex(pattern);\n        /*\n         * El método Matches() devuelve una colección con \n         * todas las coincidencias encontradas en el texto\n         * especificado\n         */\n        var numeros = regex.Matches(texto);\n        Console.WriteLine($\"Numeros Encontrados en texto: {texto}\");\n        /*\n         * Recorremos la colección e imprimimos todos las\n         * coincidencias\n         */\n        foreach (var numero in numeros)\n            Console.Write($\"{numero}, \");\n        Console.WriteLine();\n        /*\n         * La clase Regex contiene el método estático Replace()\n         * el cual reemplaza dentro de la cadena envíada el patrón\n         * que se indique por otro carácter\n         */\n        texto = Regex.Replace(texto, pattern, \"\");\n        Console.WriteLine($\"Texto con números eliminados: {texto}\");\n        #endregion\n        // Ejercicio extra\n        Console.ReadLine();\n        Console.Clear();\n        bool salir = false;\n        do\n        {\n            Menu();\n            string option = Console.ReadLine();\n            switch (option.ToLower())\n            {\n                case \"a\":\n                    var responseEmail = ValidarEmail();\n                    if (responseEmail.Item2)\n                        Console.WriteLine($\"El email {responseEmail.Item1} es válido...\");\n                    else\n                        Console.WriteLine($\"El email {responseEmail.Item1} no es válido...\");\n                    break;\n                case \"b\":\n                    var responseTelefono = ValidarNumero();\n                    if (responseTelefono.Item2)\n                        Console.WriteLine($\"El número {responseTelefono.Item1} es válido...\");\n                    else\n                        Console.WriteLine($\"El número {responseTelefono.Item1} no es válido...\");\n                    break;\n                case \"c\":\n                    var responseURL = ValidarURL();\n                    if (responseURL.Item2)\n                        Console.WriteLine($\"La URL {responseURL.Item1} es válida...\");\n                    else\n                        Console.WriteLine($\"La URL {responseURL.Item1} no es válida...\");\n                    break;\n                case \"d\":\n                    Console.Clear();\n                    Console.WriteLine(\"Hasta la próxima...\");\n                    salir = true;\n                    Thread.Sleep(1000);\n                    break;\n                default:\n                    Console.Clear();\n                    Console.WriteLine(\"Opción no válida...\");\n                    break;\n            }\n        }\n        while (!salir);\n        \n    }\n    static void Menu()\n    {\n        Console.WriteLine(\"---Sistema RegEx---\");\n        Console.WriteLine(\"a.- Validar email\");\n        Console.WriteLine(\"b.- Validar número telefónico\");\n        Console.WriteLine(\"c.- Validar URL\");\n        Console.WriteLine(\"d.- Salir\");\n        Console.WriteLine(\"Selecciones la opción deseada...\");\n    }\n    static (string, bool) ValidarEmail()\n    {\n        Console.Clear();\n        Console.WriteLine(\"Ingresa email a validar\");\n        string email = Console.ReadLine();\n\n        if(string.IsNullOrEmpty(email)) \n            return (email, false);\n\n        string pattern = @\"^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$\";\n        /*\n         * ^ -> Comenzar la búsqueda al inicio de la cadena\n         * [^@\\s]+ -> Busca uno o más carácterers diferentes de @ o espacio en blanco\n         * @ -> Busca el carácter @\n         * \\. -> Busca un único carácter de punto\n         * $ -> Finalizar la busqueda al final de la cadena\n         */\n        return Regex.IsMatch(email, pattern) ? (email, true) : (email, false);\n    }\n    static (string, bool) ValidarNumero()\n    {\n        Console.Clear();\n        Console.WriteLine(\"Ingresa número teléfonico a validar\");\n        string numero = Console.ReadLine();\n        if (string.IsNullOrEmpty(numero))\n            return (numero, false);\n        string pattern = @\"^(\\+?\\s?\\d{3}[\\s.-]?\\d{3}[\\s.-]?\\d{4}|\\d{10})$\";\n        /*\n         * ^ -> Comenzar la búsqueda al inicio de la cadena\n         * \\+? -> Puede comenzar con un +\n         * \\s -> Puede incluir un espacio en blanco\n         * \\d{3} Debe incluir tres dígitos\n         * [\\s.-]? -> Puede contener un espacio en blanco, un punto o un guión\n         * \\d{4} -> Debe incluir cuatro dígitos\n         * |\\d{10} O incluye dies dígitos\n         * $ -> Finalizar la busqueda al final de la cadena\n         */\n        return Regex.IsMatch(numero, pattern) ? (numero, true) : (numero, false);\n    }\n    static (string, bool) ValidarURL()\n    {\n        Console.Clear();\n        Console.WriteLine(\"Ingresa URL a validar\");\n        string url = Console.ReadLine();\n        if (string.IsNullOrEmpty(url))\n            return (url, false);\n        string pattern = @\"^(http+s?\\:\\/\\/)?(www\\.)?\\w+\\.\\w+$\";\n        /*\n         * ^ -> Comenzar la búsqueda al inicio de la cadena\n         * (http+s?\\:\\/\\/)? -> Puede incluir http:// o https://\n         * (www\\.)? -> Puede incluir www.\n         * \\w+ -> Incluye uno o varios carácteres alfanuméricos\n         * \\. Incluye un punto\n         * $ -> Finalizar la busqueda al final de la cadena\n         */\n\n        return Regex.IsMatch(url, pattern) ? (url, true) : (url, false);\n    }\n}"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/c#/jamerrq.cs",
    "content": "/*\n * EJERCICIO:\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\n */\n\nusing System;\nusing System.Text.RegularExpressions;\n\nnamespace Roadmap16\n{\n    class Regex\n    {\n\n        static void ExtraExercise()\n        {\n            // Usamos un texto con un email, un número de teléfono y una url\n            // para probar las expresiones regulares.\n            string generalText = \"This is a text with an email: noreply@nowhere.com, a phone number: 123-456-7890 and a url: https://www.nowhere.com\";\n\n            // Definimos las expresiones regulares\n            string emailPattern = @\"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}\";\n            string phoneNumberPattern = @\"\\d{3}-\\d{3}-\\d{4}\";\n            string urlPattern = @\"https?://[\\w\\.-]+\";\n\n            // Buscamos las coincidencias\n            Match emailMatch = System.Text.RegularExpressions.Regex.Match(generalText, emailPattern);\n            Console.WriteLine(\"Email: \" + emailMatch.Value);\n            Match phoneNumberMatch = System.Text.RegularExpressions.Regex.Match(generalText, phoneNumberPattern);\n            Console.WriteLine(\"Número de teléfono: \" + phoneNumberMatch.Value);\n            Match urlMatch = System.Text.RegularExpressions.Regex.Match(generalText, urlPattern);\n            Console.WriteLine(\"Url: \" + urlMatch.Value);\n        }\n\n        static void Main(string[] args)\n        {\n            string textWithNumbers = \"This is a text with 73 numbers 1729 in it 420.\";\n            string pattern = @\"\\d+\";\n            MatchCollection matches = System.Text.RegularExpressions.Regex.Matches(textWithNumbers, pattern);\n\n            Console.WriteLine(\"Numbers Found:\");\n            foreach (Match match in matches)\n            {\n                Console.WriteLine(match.Value);\n            }\n\n            Console.WriteLine(\"\\nExtra Exercise:\");\n            ExtraExercise();\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/c#/kenysdev.cs",
    "content": "/*\n╔══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado               ║\n║ GitHub: https://github.com/Kenysdev  ║\n║ 2024 -  C#                           ║\n╚══════════════════════════════════════╝\n------------------------------------------\n* EXPRESIONES REGULARES\n------------------------------------------\nhttps://learn.microsoft.com/es-es/dotnet/standard/base-types/regular-expressions\n\n* EJERCICIO #1:\n* Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n* creando una que sea capaz de encontrar y extraer todos los números\n* de un texto.\n*/\n\nusing System.Text.RegularExpressions;\n\nstatic void GetNumbers(string text) {\n    string Pattern = @\"\\d+\";\n    MatchCollection numbers = Regex.Matches(text, Pattern);\n        \n    foreach (object n in numbers) {\n        Console.WriteLine(n);\n    }\n}\n\nGetNumbers(\"abcdsfs1s(*&#}2. a3// 45sdf67\");\nGetNumbers(\"45sdf67\");\n\n/*\n* EJERCICIO #2:\n* Crea 3 expresiones regulares (a tu criterio) capaces de:\n* - Validar un email.\n* - Validar un número de teléfono.\n* - Validar una url.\n*/\n\nstatic bool IsEmail(string text) {\n    string patron = @\"^[\\w.%+-]+@[\\w.-]+\\.[a-zA-Z]{2,}$\";\n    return Regex.IsMatch(text, patron);\n}\n\nstatic bool IsPhoneNumber(string text) {\n    string patron = @\"^(\\d{3}-\\d{3}-\\d{4}|\\d{10})$\";\n    return Regex.IsMatch(text, patron);\n}\n\nstatic bool IsURL(string text) {\n    string patron = @\"^(https?://)?(www\\.)?([a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,}(/\\S*)?$\";\n    return Regex.IsMatch(text, patron);\n}\n\nstatic void Print(Object text) {\n    Console.WriteLine(text);\n}\n\nPrint(\"\\nIsEmail\");\nPrint(IsEmail(\"ejm@dmn.com\"));         // True\nPrint(IsEmail(\"e_jm-2+b@dmn.co.hn\"));  // True\nPrint(IsEmail(\"ejm@dmn.com_\"));        // False\nPrint(IsEmail(\"ejm@dmn\"));             // False\n\nPrint(\"\\nIsPhoneNumber\");\nPrint(IsPhoneNumber(\"123-456-7890\"));  // True\nPrint(IsPhoneNumber(\"1234567890\"));    // True\nPrint(IsPhoneNumber(\"123456-7890\"));   // False\nPrint(IsPhoneNumber(\"uno234567890\"));  // False\n\nPrint(\"\\nIsURL\");\nPrint(IsURL(\"http://www.ejm.com\"));    // True\nPrint(IsURL(\"google.com\"));            // True\nPrint(IsURL(\"ejm.com/a/b/c\"));         // True\nPrint(IsURL(\"https://.ejm.com\"));      // False\nPrint(IsURL(\"https://.ejm.com/a b\"));  // False \n\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/c#/miguelex.cs",
    "content": "using System;\nusing System.Text.RegularExpressions;\n\nclass miguelex\n{\n    static void RegExpr(string cadena)\n    {\n        string patron = @\"-?\\d+(\\.\\d+)?\";\n        MatchCollection numeros = Regex.Matches(cadena, patron);\n\n        Console.WriteLine(\"Números encontrados:\");\n        foreach (Match numero in numeros)\n        {\n            Console.WriteLine(numero.Value);\n        }\n        Console.WriteLine();\n    }\n\n    static void Main(string[] args)\n    {\n        string texto = \"Este es un texto con números como 123, 45.6, -7 y 1000.\";\n        Console.WriteLine(\"Vamos a analizar el siguiente texto:\");\n        Console.WriteLine(\"'\" + texto + \"'\\n\");\n        RegExpr(texto);\n\n        texto = \"123Erase una vez un número 1234567890 y otro 0987654321. Y para terminar456\";\n        Console.WriteLine(\"Vamos a analizar el siguiente texto:\");\n        Console.WriteLine(\"'\" + texto + \"'\\n\");\n        RegExpr(texto);\n\n        EmailValidation(\"correo@correo.com\");\n        EmailValidation(\"correo@correo\");\n\n        PhoneValidation(\"+34 123456789\");\n        PhoneValidation(\"123456789\");\n\n        UrlValidation(\"http://www.google.com\");\n        UrlValidation(\"www.google.com\");\n    }\n\n    static void EmailValidation(string email)\n    {\n        string patron = @\"^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}$\";\n        if (Regex.IsMatch(email, patron))\n        {\n            Console.WriteLine($\"El email {email} es válido.\");\n        }\n        else\n        {\n            Console.WriteLine($\"El email {email} no es válido.\");\n        }\n    }\n\n    static void PhoneValidation(string phone)\n    {\n        string patron = @\"^\\+?(\\d{2,3})?[-. ]?\\d{9}$\";\n        if (Regex.IsMatch(phone, patron))\n        {\n            Console.WriteLine($\"El teléfono {phone} es válido.\");\n        }\n        else\n        {\n            Console.WriteLine($\"El teléfono {phone} no es válido.\");\n        }\n    }\n\n    static void UrlValidation(string url)\n    {\n        string patron = @\"^(http|https):\\/\\/[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}\";\n        if (Regex.IsMatch(url, patron))\n        {\n            Console.WriteLine($\"La URL {url} es válida.\");\n        }\n        else\n        {\n            Console.WriteLine($\"La URL {url} no es válida.\");\n        }\n    }\n        \n}\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/c++/hectorio23.cpp",
    "content": "// Author: Hector Adán\n// GitHub: https://github.com/hectorio23 \n#include <iostream>\n#include <regex>\n#include <string>\n\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\n */\n\n/*************************************************\n**************  Prototipo de funcion *************\n*************************************************/\nstd::string verify(std::string, std::string, std::regex);\nstd::string extract(std::string);\n\n\n int main() {\n    /*************************************************\n    *******************  REGEX ZONE ******************\n    *************************************************/\n    std::regex email_regex (R\"(^\\w+@\\w{3,}\\.\\w{2,})\");\n    std::regex phone_number_regex (R\"(^\\+\\d{2,3}\\s\\d{3}\\s\\d{3}\\s\\d{2}\\s\\d{2})\");\n    std::regex url_regex (\"^https?://w{0,3}?[a-z]+\\\\.[a-z]{3}\");\n\n    std::string texto_legible = \"E5n e6l si5g7ui8e956nte tex8to s9e 0t4ien4e que3 extr3aer to3dos lo0s nume3ro0s pa2ra q4ue s8e7a l9e0gi9b0le\";\n\n    // IMPRESION DEL LA SALIDA DEL EJERCICIO 1\n    std::cout << \"***** EJERCICIO *****\\n\";\n    std::cout << \"[-] Cadena a extraer los numeros: \" << texto_legible << \"\\n\";\n    std::cout << \"[+] Cadena limpia sin numeros: \" << extract(texto_legible) << \"\\n\\n\";\n\n\n    // IMPRESION DEL LA SALIDA DEL EXTRA 1\n    std::cout << \"********* EJERCICIO EXTRA *********\\n\";\n    std::cout << \"*********************** EMAIL CHECK *********************************\\n\";\n    std::cout << verify(\"hectorino2789@gmail.com\", \"e-mail\", email_regex) << \"\\n\";\n    std::cout << verify(\"quesobadas@outlook.es\", \"e-mail\", email_regex) << \"\\n\";\n    std::cout << verify(\"nocorresponde a unema%il@gmaildjfj.completo\", \"e-mail\", email_regex) << \"\\n\";\n\n\n    std::cout << \"\\n*********************** PHONE CHECK *********************************\\n\";\n    std::cout << \"Para que un numero sea valido, tiene que estar escrito de la siguiente forma: +52 449 369 52 34\\n\";\n    std::cout << verify(\"+52 449-369-52-34\", \"numero de telefono\", phone_number_regex) << \"\\n\";\n    std::cout << verify(\"+52 449 369 52 34\", \"numero de telefono\", phone_number_regex) << \"\\n\";\n    std::cout << verify(\"449 369 52 34\", \"numero de telefono\", phone_number_regex) << \"\\n\";\n\n\n    std::cout << \"\\n*********************** URL CHECK *********************************\\n\";\n    std::cout << verify(\"https://github.com/hectorio23\", \"url\", url_regex) << \"\\n\";\n    std::cout << verify(\"outlook:///github.com\\\\hectorio23\", \"url\", url_regex) << \"\\n\";\n    std::cout << verify(\"127.0.0.1:89/path/otherpath\", \"url\", url_regex) << \"\\n\";\n    std::cout << verify(\"https://apple.com\", \"url\", url_regex) << \"\\n\";\n\n\n    return EXIT_SUCCESS;\n}\n\n// LA funcion verify solo compara la cadena de caracteres previamente especificada en el \n// parametro sValue con el pattern.\nstd::string verify(std::string sValue, std::string tipo, std::regex pattern) {\n\n    if (!std::regex_search(sValue, pattern)) return \"[-] El valor [ \" +  sValue  + \" ] no corresponde a un  \" + tipo;\n\n    return \"[+] El valor [ \" +  sValue  + \" ] corresponde a un  \" + tipo;\n}\n// Esta funcion extrae los numeros de una cadena de caracteres\n// y retorna la misma cadena sin los numeros.\nstd::string extract(std::string sValue) {\n    std::regex pattern(\"\\\\d\");\n\n    return std::regex_replace(sValue, pattern, \"\");\n }\n\n// OUTPUT\n//  ***** EJERCICIO *****\n// [-] Cadena a extraer los numeros: E5n e6l si5g7ui8e956nte tex8to s9e 0t4ien4e que3 extr3aer to3dos lo0s nume3ro0s pa2ra q4ue s8e7a l9e0gi9b0le\n// [+] Cadena limpia sin numeros: En el siguiente texto se tiene que extraer todos los numeros para que sea legible\n\n// ********* EJERCICIO EXTRA *********\n// *********************** EMAIL CHECK *********************************\n// [+] El valor [ hectorino2789@gmail.com ] corresponde a un  e-mail\n// [+] El valor [ quesobadas@outlook.es ] corresponde a un  e-mail\n// [-] El valor [ nocorresponde a unema%il@gmaildjfj.completo ] no corresponde a un  e-mail\n\n// *********************** PHONE CHECK *********************************\n// Para que un numero sea valido, tiene que estar escrito de la siguiente forma: +52 449 369 52 34\n// [-] El valor [ +52 449-369-52-34 ] no corresponde a un  numero de telefono\n// [+] El valor [ +52 449 369 52 34 ] corresponde a un  numero de telefono\n// [-] El valor [ 449 369 52 34 ] no corresponde a un  numero de telefono\n\n// *********************** URL CHECK *********************************\n// [+] El valor [ https://github.com/hectorio23 ] corresponde a un  url\n// [-] El valor [ outlook:///github.com\\hectorio23 ] no corresponde a un  url\n// [-] El valor [ 127.0.0.1:89/path/otherpath ] no corresponde a un  url\n// [+] El valor [ https://apple.com ] corresponde a un  url"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/c++/miguelex.cpp",
    "content": "#include <iostream>\n#include <string>\n#include <regex>\n\nvoid regExpr(std::string cadena) {\n    std::regex patron(R\"-(-?\\d+(\\.\\d+)?)-\");\n    std::smatch numeros;\n\n    std::cout << \"Números encontrados:\" << std::endl;\n    while (std::regex_search(cadena, numeros, patron)) {\n        std::cout << numeros.str() << std::endl;\n        cadena = numeros.suffix();\n    }\n    std::cout << std::endl;\n}\n\nvoid emailValidation(const std::string& email) {\n    std::regex patron(R\"-([a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4})-\");\n    if (std::regex_match(email, patron)) {\n        std::cout << \"El email \" << email << \" es válido.\" << std::endl;\n    } else {\n        std::cout << \"El email \" << email << \" no es válido.\" << std::endl;\n    }\n}\n\nvoid phoneValidation(const std::string& phone) {\n    std::regex patron(R\"-((\\+?\\d{2,3})?[-. ]?\\d{9})-\");\n    if (std::regex_match(phone, patron)) {\n        std::cout << \"El teléfono \" << phone << \" es válido.\" << std::endl;\n    } else {\n        std::cout << \"El teléfono \" << phone << \" no es válido.\" << std::endl;\n    }\n}\n\nvoid urlValidation(const std::string& url) {\n    std::regex patron(R\"-((http|https):\\/\\/[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4})-\");\n    if (std::regex_match(url, patron)) {\n        std::cout << \"La URL \" << url << \" es válida.\" << std::endl;\n    } else {\n        std::cout << \"La URL \" << url << \" no es válida.\" << std::endl;\n    }\n}\n\nint main() {\n    std::string texto = \"Este es un texto con números como 123, 45.6, -7 y 1000.\";\n    std::cout << \"Vamos a analizar el siguiente texto:\" << std::endl;\n    std::cout << \"'\" << texto << \"'\\n\\n\";\n    regExpr(texto);\n\n    texto = \"123Erase una vez un número 1234567890 y otro 0987654321. Y para terminar456\";\n    std::cout << \"Vamos a analizar el siguiente texto:\" << std::endl;\n    std::cout << \"'\" << texto << \"'\\n\\n\";\n    regExpr(texto);\n\n    emailValidation(\"correo@correo.com\");\n    emailValidation(\"correo@correo\");\n\n    phoneValidation(\"+34 123456789\");\n    phoneValidation(\"123456789\");\n\n    urlValidation(\"http://www.google.com\");\n    urlValidation(\"www.google.com\");\n\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/dart/miguelex.dart",
    "content": "void main() {\n  String texto = \"Este es un texto con números como 123, 45.6, -7 y 1000.\";\n\n  RegExp regExp = RegExp(r'-?\\d+(\\.\\d+)?');\n  Iterable<Match> matches = regExp.allMatches(texto);\n\n  print(\"Números encontrados:\");\n  matches.forEach((match) {\n    print(match.group(0));\n  });\n  print(\"\\n\\n\");\n\n  texto =\n      \"123Erase una vez un número 1234567890 y otro 0987654321. Y para terminar456\";\n  matches = regExp.allMatches(texto);\n\n  print(\"Números encontrados:\");\n  matches.forEach((match) {\n    print(match.group(0));\n  });\n  print(\"\\n\\n\");\n\n  emailValidation(\"correo@correo.com\");\n  emailValidation(\"correo@correo\");\n\n  phoneValidation(\"+34 123456789\");\n  phoneValidation(\"123456789\");\n\n  urlValidation(\"http://www.google.com\");\n  urlValidation(\"www.google.com\");\n}\n\nvoid emailValidation(String email) {\n  RegExp pattern = RegExp(r'^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}$');\n  if (pattern.hasMatch(email)) {\n    print(\"El email $email es válido.\");\n  } else {\n    print(\"El email $email no es válido.\");\n  }\n}\n\nvoid phoneValidation(String phone) {\n  RegExp pattern = RegExp(r'^\\+?(\\d{2,3})?[-. ]?\\d{9}$');\n  if (pattern.hasMatch(phone)) {\n    print(\"El teléfono $phone es válido.\");\n  } else {\n    print(\"El teléfono $phone no es válido.\");\n  }\n}\n\nvoid urlValidation(String url) {\n  RegExp pattern = RegExp(r'^(http|https):\\/\\/[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}');\n  if (pattern.hasMatch(url)) {\n    print(\"La URL $url es válida.\");\n  } else {\n    print(\"La URL $url no es válida.\");\n  }\n}\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/dart/teren91.dart",
    "content": "\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\n */\n\n\nvoid main()\n{\n  final alphaNumeric = RegExp(r'^[a-zA-Z0-9]+$');\n  final numeric = RegExp(r'^[0-9]+$');\n  \n  final mailRegEx = RegExp(r'^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*$');\n  final phoneRegEx = RegExp(r'^\\+?[0-9 ]{6,15}$');\n  final urlRegEx = RegExp(r'^https?:\\/\\/(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b([-a-zA-Z0-9()@:%_\\+.~#?&//=]*)$');\n\n  final mail = 'MailPrueba@test.es';\n  final phoneNumber = '646585921a';\n  final url = 'https://test.com/id=2034';\n\n  print(alphaNumeric.hasMatch('abc123'));\n  print(numeric.hasMatch('abc123'));\n  print(numeric.hasMatch('123'));\n\n  print('Validar mail: $mail -> ${mailRegEx.hasMatch(mail)}');\n  print('Validar teléfono: $phoneNumber -> ${phoneRegEx.hasMatch(phoneNumber)}');\n  print('Validar url: $url -> ${urlRegEx.hasMatch(url)}');\n}"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/ejercicio.md",
    "content": "# #16 EXPRESIONES REGULARES\n> #### Dificultad: Media | Publicación: 15/04/24 | Corrección: 22/04/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/elixir/boterop.ex",
    "content": "defmodule Boterop.Regex do\n  @spec get_numbers(text :: String.t()) :: list(String.t()) | nil\n  def get_numbers(text), do: Regex.scan(~r/\\d+/, text)\n\n  @spec is_a_valid_email?(email :: String.t()) :: boolean()\n  def is_a_valid_email?(email),\n    do: Regex.match?(~r/[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}/, email)\n\n  @spec is_a_valid_phone_number?(phone_number :: String.t()) :: boolean()\n  def is_a_valid_phone_number?(phone_number),\n    do:\n      Regex.match?(~r/^\\+?\\d{1,3}[-.\\s]?\\(?\\d{1,4}\\)?[-.\\s]?\\d{1,4}[-.\\s]?\\d{1,4}$/, phone_number)\n\n  @spec is_a_valid_url?(url :: String.t()) :: boolean()\n  def is_a_valid_url?(url),\n    do: Regex.match?(~r/https?:\\/\\/[^\\s\\/$.?#]+\\.(?:[a-z]{2,})+(?:\\/[^\\s$.?#]+)*/, url)\nend\n\nExUnit.start()\n\ndefmodule Boterop.RegexTest do\n  use ExUnit.Case\n\n  test \"get numbers from text\" do\n    expected_result = \"00100505\"\n\n    \"S0l0 qu1er0 l05 numer05\"\n    |> Boterop.Regex.get_numbers()\n    |> Enum.join()\n    |> Kernel.==(expected_result)\n    |> assert\n  end\n\n  describe \"validating email\" do\n    test \"with a valid email\" do\n      \"mail@domain.com\"\n      |> Boterop.Regex.is_a_valid_email?()\n      |> assert\n    end\n\n    test \"with an invalid tld\" do\n      \"mail@domain.c\"\n      |> Boterop.Regex.is_a_valid_email?()\n      |> refute\n    end\n\n    test \"with an invalid structure\" do\n      \"mail.domain@com\"\n      |> Boterop.Regex.is_a_valid_email?()\n      |> refute\n    end\n  end\n\n  describe \"validating phone number\" do\n    test \"with a valid country code\" do\n      \"+573015201917\"\n      |> Boterop.Regex.is_a_valid_phone_number?()\n      |> assert\n    end\n\n    test \"with a valid separator\" do\n      \"301 520 3261\"\n      |> Boterop.Regex.is_a_valid_phone_number?()\n      |> assert\n    end\n\n    test \"with an invalid number\" do\n      \"911\"\n      |> Boterop.Regex.is_a_valid_phone_number?()\n      |> refute\n    end\n\n    test \"with an invalid character\" do\n      \"+5730i5203261\"\n      |> Boterop.Regex.is_a_valid_phone_number?()\n      |> refute\n    end\n  end\n\n  describe \"validating url\" do\n    test \"with a valid url\" do\n      \"http://www.boterop.io\"\n      |> Boterop.Regex.is_a_valid_url?()\n      |> assert\n    end\n\n    test \"without subdomain\" do\n      \"http://boterop.io\"\n      |> Boterop.Regex.is_a_valid_url?()\n      |> assert\n    end\n\n    test \"with a valid https protocol\" do\n      \"https://www.boterop.io\"\n      |> Boterop.Regex.is_a_valid_url?()\n      |> assert\n    end\n\n    test \"with an invalid protocol\" do\n      \"invalid://www.boterop.io\"\n      |> Boterop.Regex.is_a_valid_url?()\n      |> refute\n    end\n\n    test \"with an invalid domain\" do\n      \"https://boterop\"\n      |> Boterop.Regex.is_a_valid_url?()\n      |> refute\n    end\n\n    test \"with an invalid tdl\" do\n      \"https://boterop.1\"\n      |> Boterop.Regex.is_a_valid_url?()\n      |> refute\n    end\n  end\nend\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/go/DaFi02.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n)\n\ntype texts struct {\n\ttext1 string\n\ttext2 string\n}\n\nfunc main() {\n\tt := texts{\n\t\ttext1: \"Es4 kasd 3 234 23  text0\",\n\t\ttext2: `This is the ex4 roslñdfalfj 3 39 fcm10`,\n\t}\n\n\t// Compila el patrón de expresión regular.\n\tre, err := regexp.Compile(`\\d+`)\n\tif err != nil {\n\t\tfmt.Println(\"Error al compilar la expresión regular:\", err)\n\t\treturn\n\t}\n\n\t// Encuentra todas las ocurrencias del patrón en el texto.\n\tfmt.Printf(\"Del texto 1: %s\\n\", t.text1)\n\tnumeros1 := re.FindAllString(t.text1, -1)\n\tfmt.Println(\"Números encontrados:\", numeros1)\n\tfmt.Printf(\"Del texto 2: %s\\n\", t.text2)\n\tnumeros2 := re.FindAllString(t.text2, -1)\n\tfmt.Println(\"Números encontrados:\", numeros2)\n\n\t// Dificutlad Extra\n\t// Creando los emails, número y url\n\temail := \"example.ga@gmail.com\"\n\tnumeroPeruano := \"987654321\"\n\turl := \"google.com\"\n\n\tfmt.Println(\"-------------------\")\n\tfmt.Println(\"-------------------\")\n\tfmt.Println(\"-------------------\")\n\n\t// Compila el patrón de expresión regular.para email\n\ttextEmail, valid := isEmailValited(email)\n\tif valid {\n\t\tfmt.Println(textEmail, \"valido\")\n\t} else {\n\t\tfmt.Println(textEmail, \"invalido\")\n\t}\n\n\ttextNumber, validnumber := isnumberphoneValited(numeroPeruano)\n\tif validnumber {\n\t\tfmt.Println(textNumber, \"valido\")\n\t} else {\n\t\tfmt.Println(textNumber, \"invalido\")\n\t}\n\n\ttextUrl, validurl := isurlValited(url)\n\tif validurl {\n\t\tfmt.Println(textUrl, \"valido\")\n\t} else {\n\t\tfmt.Println(textUrl, \"invalido\")\n\t}\n\n}\n\nfunc isEmailValited(e string) (string, bool) {\n\temailRegex := regexp.MustCompile(\"^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$\")\n\treturn fmt.Sprintf(\"El email: '%s' es:\", e), emailRegex.MatchString(e)\n}\n\nfunc isnumberphoneValited(e string) (string, bool) {\n\temailRegex := regexp.MustCompile(\"^[0-9]{9,9}$\")\n\treturn fmt.Sprintf(\"El numero: '%s' es:\", e), emailRegex.MatchString(e)\n}\n\nfunc isurlValited(e string) (string, bool) {\n\temailRegex := regexp.MustCompile(`[(http(s)?):\\/\\/(www\\.)?a-zA-Z0-9@:%._\\+~#=]{2,256}\\.[a-z]{2,6}\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*)`)\n\treturn fmt.Sprintf(\"La url: '%s' es:\", e), emailRegex.MatchString(e)\n}\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/go/MiguelP-Dev.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n)\n\nfunc main() {\n\ttext := \"Hola, mi número de teléfono es 1234567890 y mi email es miguelportillo2475@gmail.com\"\n\tre := regexp.MustCompile(`\\d+`)\n\tnumbers := re.FindAllString(text, -1)\n\tfor _, number := range numbers {\n\t\tprintln(number)\n\t}\n\n\tfmt.Printf(\"Tipo: %T, Valor0: %s, Valor1: %s\\n\", numbers, numbers[0], numbers[1])\n\n\t// Validación de correo electrónico\n\temail := \"miguelportillo2475@gmail.com\"\n\temailRegExp, err := regexp.Compile(`^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$`)\n\tif err != nil {\n\t\tfmt.Println(\"Error al compilar la expresión regular\")\n\t}\n\tif emailRegExp.MatchString(email) {\n\t\tfmt.Println(\"Correo electrónico válido\")\n\t} else {\n\t\tfmt.Println(\"Correo electrónico inválido\")\n\t}\n\n\t// Validación de número de teléfono\n\tphone := \"1234567890\"\n\tphoneRegExp, err := regexp.Compile(`^\\d{10}$`)\n\tif err != nil {\n\t\tfmt.Println(\"Error al compilar la expresión regular\")\n\t}\n\tif phoneRegExp.MatchString(phone) {\n\t\tfmt.Println(\"Número de teléfono válido\")\n\t} else {\n\t\tfmt.Println(\"Número de teléfono inválido\")\n\t}\n\n\t// Validación de URL\n\turl := \"https://ed.team\"\n\turlRegExp, err := regexp.Compile(`^https?://[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$`)\n\tif err != nil {\n\t\tfmt.Println(\"Error al compilar la expresión regular\")\n\t}\n\tif urlRegExp.MatchString(url) {\n\t\tfmt.Print(\"URL válida\")\n\t} else {\n\t\tfmt.Println(\"URL inválida\")\n\t}\n}\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/go/N0HagoNada.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n)\n\nfunc main() {\n\n\ttexto := \"Hola, mi número de teléfono es 123456789 y mi edad es 30 años.\"\n\n\t// Expresión regular para encontrar números\n\tre := regexp.MustCompile(`\\d+`)\n\n\t// Encontrar todos los números en el texto\n\tnumeros := re.FindAllString(texto, -1)\n\n\tfmt.Println(\"Números encontrados:\", numeros)\n\n\t// Expresión regular para validar un email\n\temailRegex := regexp.MustCompile(`^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$`)\n\n\temail1 := \"example@example.com\"\n\temail2 := \"invalid.email\"\n\n\tfmt.Println(\"Email válido:\", emailRegex.MatchString(email1))\n\tfmt.Println(\"Email inválido:\", emailRegex.MatchString(email2))\n\n\t// Expresión regular para validar un número de teléfono\n\ttelefonoRegex := regexp.MustCompile(`^\\d{10}$`)\n\n\ttelefono1 := \"1234567890\"\n\ttelefono2 := \"123-456-7890\"\n\n\tfmt.Println(\"Teléfono válido:\", telefonoRegex.MatchString(telefono1))\n\tfmt.Println(\"Teléfono inválido:\", telefonoRegex.MatchString(telefono2))\n\n\t// Expresión regular para validar una URL\n\turlRegex := regexp.MustCompile(`^(http|https)://[a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)*(\\.[a-zA-Z]{2,})(/.*)?$`)\n\n\turl1 := \"https://www.example.com\"\n\turl2 := \"invalid.url\"\n\n\tfmt.Println(\"URL válida:\", urlRegex.MatchString(url1))\n\tfmt.Println(\"URL inválida:\", urlRegex.MatchString(url2))\n}\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/go/hozlucas28.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strings\"\n)\n\ntype RegularExpressions struct {\n\temail       *regexp.Regexp\n\tphoneNumber *regexp.Regexp\n\turl         *regexp.Regexp\n}\n\nfunc main() {\n\t/*\n\t\tRegular expressions...\n\t*/\n\n\tfmt.Println(\"Regular expressions...\")\n\n\tconst text string = \"¡Hola Mundo! Hoy es 15/04/2024. Quedan 263 días para terminar el año 2024.\"\n\n\tvar regularExpression *regexp.Regexp = regexp.MustCompile(`[0-9]`)\n\tvar numbers string = strings.Join(regularExpression.FindAllString(text, -1), \"\")\n\n\tfmt.Printf(\"\\n`text` = '%s'\\n\", text)\n\tfmt.Printf(\"\\nNumbers inside `text` --> %s\\n\", numbers)\n\n\tfmt.Println(\"\\n# ---------------------------------------------------------------------------------- #\")\n\n\t/*\n\t\tAdditional challenge...\n\t*/\n\n\tfmt.Println(\"\\nAdditional challenge...\")\n\n\tvar regularExpressions RegularExpressions = RegularExpressions{\n\t\temail:       regexp.MustCompile(`^[a-zA-Z0-9]*@[a-zA-Z0-9]*\\.[a-zA-Z]{2,3}$`),\n\t\tphoneNumber: regexp.MustCompile(`^\\+[0-9]{1,4} [0-9]{4} [0-9]{4}$`),\n\t\turl:         regexp.MustCompile(`^https?://([a-zA-Z0-9]*\\.)?[a-zA-Z0-9]*\\.[a-zA-Z]{2,3}/?$`),\n\t}\n\n\tvar emails []string = []string{\"hozlucas28@gmail.com\",\n\t\t\"hozlucas28@dev.com\",\n\t\t\"hozlucas-28@hotmail.com\",\n\t\t\"hozlucas28@melí.com\",\n\t\t\"hozlucas28@edu.com\",\n\t}\n\n\tvar phoneNumbers []string = []string{\"+12 3456 7890\",\n\t\t\"+1 1234 5890\",\n\t\t\"+1234 1234 5690\",\n\t\t\"+123456789\",\n\t\t\"+123456789 1234 5678\",\n\t}\n\n\tvar urls []string = []string{\"https://www.example.cóm\",\n\t\t\"http://example.com\",\n\t\t\"https://subdomain.example.com\",\n\t\t\"http://www.example.c2.uk\",\n\t\t\"https://www.example.org\",\n\t}\n\n\tfmt.Println(\"\\nEmails...\")\n\tfor _, email := range emails {\n\t\tvar isValid bool = regularExpressions.email.MatchString(email)\n\t\tfmt.Printf(\"Is '%s' a valid email? %t\\n\", email, isValid)\n\t}\n\n\tfmt.Println(\"\\nPhone numbers...\")\n\tfor _, phoneNumber := range phoneNumbers {\n\t\tvar isValid bool = regularExpressions.phoneNumber.MatchString(phoneNumber)\n\t\tfmt.Printf(\"Is '%s' a valid phone number? %t\\n\", phoneNumber, isValid)\n\t}\n\n\tfmt.Println(\"\\nUrls...\")\n\tfor _, url := range urls {\n\t\tvar isValid bool = regularExpressions.url.MatchString(url)\n\t\tfmt.Printf(\"Is '%s' a valid url? %t\\n\", url, isValid)\n\t}\n}\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/go/kodenook.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n)\n\nfunc main() {\n\tfmt.Printf(\"%v\\n\", ExtractNumber(\"There are 3 apples, 5 oranges, and 12 bananas.\"))\n}\n\nfunc ExtractNumber(word string) []string {\n\tpattern := `\\d+`\n\tre := regexp.MustCompile(pattern)\n\treturn re.FindAllString(word, -1)\n}\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/go/miguelex.go",
    "content": "package main\n\nimport (\n    \"fmt\"\n    \"regexp\"\n)\n\nfunc regExpr(cadena string) {\n    patron := `-?\\d+(\\.\\d+)?`\n    regex := regexp.MustCompile(patron)\n    numeros := regex.FindAllString(cadena, -1)\n\n    fmt.Println(\"Números encontrados:\")\n    for _, numero := range numeros {\n        fmt.Println(numero)\n    }\n    fmt.Println()\n}\n\nfunc main() {\n    texto := \"Este es un texto con números como 123, 45.6, -7 y 1000.\"\n    fmt.Println(\"Vamos a analizar el siguiente texto:\")\n    fmt.Println(\"'\" + texto + \"'\\n\")\n    regExpr(texto)\n\n    texto = \"123Erase una vez un número 1234567890 y otro 0987654321. Y para terminar456\"\n    fmt.Println(\"Vamos a analizar el siguiente texto:\")\n    fmt.Println(\"'\" + texto + \"'\\n\")\n    regExpr(texto)\n\n    emailValidation := func(email string) {\n        patron := `^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}$`\n        regex := regexp.MustCompile(patron)\n        if regex.MatchString(email) {\n            fmt.Println(\"El email\", email, \"es válido.\")\n        } else {\n            fmt.Println(\"El email\", email, \"no es válido.\")\n        }\n    }\n\n    phoneValidation := func(phone string) {\n        patron := `^\\+?(\\d{2,3})?[-. ]?\\d{9}$`\n        regex := regexp.MustCompile(patron)\n        if regex.MatchString(phone) {\n            fmt.Println(\"El teléfono\", phone, \"es válido.\")\n        } else {\n            fmt.Println(\"El teléfono\", phone, \"no es válido.\")\n        }\n    }\n\n    urlValidation := func(url string) {\n        patron := `^(http|https):\\/\\/[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}`\n        regex := regexp.MustCompile(patron)\n        if regex.MatchString(url) {\n            fmt.Println(\"La URL\", url, \"es válida.\")\n        } else {\n            fmt.Println(\"La URL\", url, \"no es válida.\")\n        }\n    }\n\n    emailValidation(\"correo@correo.com\")\n    emailValidation(\"correo@correo\")\n\n    phoneValidation(\"+34 123456789\")\n    phoneValidation(\"123456789\")\n\n    urlValidation(\"http://www.google.com\")\n    urlValidation(\"www.google.com\")\n}\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/go/qwik-zgheib.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n)\n\ntype Validator interface {\n\tValidate(input string) bool\n}\n\n// NumberValidator -- -- --\ntype NumberValidator struct{}\n\nfunc (nv NumberValidator) Validate(input string) bool {\n\tre := regexp.MustCompile(`\\d+`)\n\treturn re.MatchString(input)\n}\n\nfunc (nv NumberValidator) Extract(input string) []string {\n\tre := regexp.MustCompile(`\\d+`)\n\treturn re.FindAllString(input, -1)\n}\n\n// EmailValidator -- -- --\ntype EmailValidator struct{}\n\nfunc (ev EmailValidator) Validate(input string) bool {\n\tre := regexp.MustCompile(`^[a-z0-9._%+\\-]+@[a-z0-9.\\-]+\\.[a-z]{2,}$`)\n\treturn re.MatchString(input)\n}\n\n// PhoneValidator -- -- --\ntype PhoneValidator struct{}\n\nfunc (pv PhoneValidator) Validate(input string) bool {\n\tre := regexp.MustCompile(`^\\+?[0-9]{1,3}?[-. ]?(\\(?\\d{1,4}?\\)?[-. ]?)?[\\d-. ]{7,10}$`)\n\treturn re.MatchString(input)\n}\n\n// URLValidator -- -- --\ntype URLValidator struct{}\n\nfunc (uv URLValidator) Validate(input string) bool {\n\tre := regexp.MustCompile(`^(https?|ftp)://[^\\s/$.?#].[^\\s]*$`)\n\treturn re.MatchString(input)\n}\n\nfunc main() {\n\n\ttext := \"Hello, I'm qwik zgheib, and my phone number is +51984371244\"\n\temail := \"qwikzgheib@gmail.com\"\n\tphone := \"+51984371244\"\n\turl := \"https://www.dota2.com/hero/legioncommander\"\n\n\tcontent := []string{\n\t\ttext,\n\t\temail,\n\t\tphone,\n\t\turl,\n\t}\n\n\tvalidators := []Validator{\n\t\tNumberValidator{},\n\t\tEmailValidator{},\n\t\tPhoneValidator{},\n\t\tURLValidator{},\n\t}\n\n\tfor i, validator := range validators {\n\t\tswitch v := validator.(type) {\n\t\tcase NumberValidator:\n\t\t\tif v.Validate(content[i]) {\n\t\t\t\tnumbers := v.Extract(text)\n\t\t\t\tfmt.Println(\"numbers found:\", numbers)\n\t\t\t} else {\n\t\t\t\tfmt.Println(\"no numbers found!\")\n\t\t\t}\n\t\tcase EmailValidator:\n\t\t\tfmt.Print(\"email: \", content[i])\n\t\t\tif v.Validate(content[i]) {\n\t\t\t\tfmt.Println(\" - valid\")\n\t\t\t} else {\n\t\t\t\tfmt.Println(\" - invalid\")\n\t\t\t}\n\t\tcase PhoneValidator:\n\t\t\tfmt.Print(\"phone number: \", content[i])\n\t\t\tif v.Validate(content[i]) {\n\t\t\t\tfmt.Println(\" - valid\")\n\t\t\t} else {\n\t\t\t\tfmt.Println(\" - invalid\")\n\t\t\t}\n\t\tcase URLValidator:\n\t\t\tfmt.Print(\"url: \", content[i])\n\t\t\tif v.Validate(content[i]) {\n\t\t\t\tfmt.Println(\" - valid\")\n\t\t\t} else {\n\t\t\t\tfmt.Println(\" - invalid\")\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/go/raynerpv2022.go",
    "content": "// #  * DIFICULTAD EXTRA (opcional):\n// #  * Crea 3 expresiones regulares (a tu criterio) capaces de:\n// #  * - Validar un email.\n// #  * - Validar un número de teléfono.\n// #  * - Validar una url.\n// #  */\n\npackage main\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n)\n\nfunc check_mail(email string) string {\n\tp := `^[\\w.]+@[a-zA-Z.-]+\\.[a-zA-Z]{2,}$`\n\n\tre := regexp.MustCompile(p)\n\tif re.MatchString(email) {\n\t\treturn email\n\t} else {\n\t\treturn email + \" NO VALIDO\"\n\t}\n\n}\nfunc emailsValidate() {\n\temails := []string{\n\t\t\"user@example.com\",\n\t\t\"firstname.lastname@example.co.uk\",\n\t\t\"user+name@example.com\",\n\t\t\"user_name@example.org\",\n\t\t\"user.name123@example.info\",\n\t\t\"user123@example.org\",\n\t\t\"user.name+label@example.com\",\n\t\t\"username@subdomain.example.com\",\n\t\t\"user@example.travel\",\n\t\t\"user@example.name\",\n\t\t\"user@.com\",\n\t\t\"@example.com\",\n\t\t\"user@com\",\n\t\t\"user@exam_ple.com\",\n\t\t\"user@ex-ample.com\",\n\t\t\"user@.example.com\",\n\t\t\"user@example.c\",\n\t\t\"user@-example.com\",\n\t\t\"user@example..com\",\n\t\t\"user@exa_mple.com\",\n\t}\n\n\tfor _, e := range emails {\n\t\tfmt.Println(check_mail(e))\n\t}\n}\n\nfunc checkPhone(number string) string {\n\tps := `^(\\+34\\s)?[\\d]{3}\\s[\\d]{3}\\s[\\d]{3}$`\n\tresult := regexp.MustCompile(ps)\n\tif result.MatchString(number) {\n\t\treturn number\n\t} else {\n\t\treturn number + \" NO VALIDO\"\n\t}\n\n}\n\nfunc telephonNUmber() {\n\ttelefonos := []string{\n\t\t\"+34 612 345 678\",\n\t\t\"612 345 678\",\n\t\t\"912 345 678\",\n\t\t\"(912) 345 678\",\n\t\t\"612345678\",\n\t\t\"+34 (612) 345 678\",\n\t\t\"612 34 56\",\n\t\t\"612-345-678\",\n\t\t\"123 456 789\",\n\t\t\"9123456789\",\n\t\t\"(612)345678\",\n\t\t\"612 345678\",\n\t}\n\n\tfor _, n := range telefonos {\n\t\tfmt.Println(checkPhone(n))\n\t}\n\n}\n\nfunc checkUrl(url string) string {\n\n\tps := `^https?://[\\w.]+\\.[a-zA-Z]{2,}$`\n\tresult := regexp.MustCompile(ps)\n\tif result.MatchString(url) {\n\t\treturn url\n\t} else {\n\t\treturn url + \" NO VALIDA\"\n\t}\n\n}\n\nfunc Urls() {\n\n\turls := []string{\n\t\t\"http://www.example.com\",\n\t\t\"https://subdomain.example.org\",\n\t\t\"http://example.co.uk\",\n\t\t\"http://example.com2\",\n\t\t\"http://www.example.c\",\n\t\t\"https://www.example.edu\",\n\t\t\"http://example\",\n\t\t\"ftp://example.com\",\n\t\t\"https://example.com/path\",\n\t\t\"http://123.456.789.0\",\n\t}\n\n\tfor _, l := range urls {\n\t\tfmt.Println(checkUrl(l))\n\t}\n\n}\nfunc main() {\n\temailsValidate()\n\tUrls()\n\ttelephonNUmber()\n}\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/go/thegera4.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n)\n\nfunc main() {\n\ttext := \"Hola, mi nombre es Juan y tengo 25 años. Mi número de teléfono es 1234567890 y mi email es juan@email.com. Puedes visitar mi sitio web en https://juan.com\";\n\t// Creamos la expresión regular\n\tre := regexp.MustCompile(`\\d+`)\n\t// Buscamos todas las coincidencias en el texto\n\tmatches := re.FindAllString(text, -1)\n\t// Imprimimos los resultados\n\tfmt.Println(\"Números encontrados:\")\n\tfor _, match := range matches {\n\t\tfmt.Println(match)\n\t}\n\n\t// EXTRA\n\n\t// Expresión regular para validar un email\n\temailRegex := regexp.MustCompile(`[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}`)\n\temailOK := \"thegera4@hotmail.com\"\n\temailNotOK := \"pepe4356hotmail.com\"\n\temailNotOK2 := \"pepe4356@hotmailco\"\n\temailNotOK3 := \"renata@.com\"\n\temailNotOK4 := \"gerardo@hotmail.c\"\n\tfmt.Printf(\"Email válido?: %v\\n\", emailRegex.MatchString(emailOK))\n\tfmt.Printf(\"Email válido?: %v\\n\", emailRegex.MatchString(emailNotOK))\n\tfmt.Printf(\"Email válido?: %v\\n\", emailRegex.MatchString(emailNotOK2))\n\tfmt.Printf(\"Email válido?: %v\\n\", emailRegex.MatchString(emailNotOK3))\n\tfmt.Printf(\"Email válido?: %v\\n\", emailRegex.MatchString(emailNotOK4))\n\n\t// Expresión regular para validar un número de teléfono\n\tphoneRegex := regexp.MustCompile(`^(\\+\\d{1,2}\\s?)?1?\\-?\\.?\\s?\\(?\\d{3}\\)?[\\s.-]?\\d{3}[\\s.-]?\\d{4}$`)\n\tphoneOK := \"+1 123-456-7890\"\n\tphoneNotOK := \"123456789\"\n\tphoneOK2 := \"+528712345678\"\n\tphoneNotOK2 := \"12345678a0\"\n\tfmt.Printf(\"Teléfono válido?: %v\\n\", phoneRegex.MatchString(phoneOK))\n\tfmt.Printf(\"Teléfono válido?: %v\\n\", phoneRegex.MatchString(phoneNotOK))\n\tfmt.Printf(\"Teléfono válido?: %v\\n\", phoneRegex.MatchString(phoneOK2))\n\tfmt.Printf(\"Teléfono válido?: %v\\n\", phoneRegex.MatchString(phoneNotOK2))\n\n\t// Expresión regular para validar una URL\n\turlOK := \"https://www.google.com\"\n\turlOK2 := \"www.google.com\"\n\turlNotOK := \"google.\"\n\turlRegex := regexp.MustCompile(`^(https?:\\/\\/)?(www\\.)?([a-zA-Z0-9-]+)\\.([a-zA-Z]{2,})(\\/[a-zA-Z0-9#]+\\/?)*$`)\n\tfmt.Printf(\"URL válida?: %v\\n\", urlRegex.MatchString(urlOK))\n\tfmt.Printf(\"URL válida?: %v\\n\", urlRegex.MatchString(urlOK2))\n\tfmt.Printf(\"URL válida?: %v\\n\", urlRegex.MatchString(urlNotOK))\n\n}"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/java/AmadorQuispe.java",
    "content": "\n\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\npublic class RegularExpresion {\n    public static void main(String[] args) {\n        String text = \"El precio del producto es de $99.99 y hay 100 unidades disponibles, oferta de 45.56%\";\n        String email = \"correo.dev@gmail.com\";\n        String phone = \"+051 999 888 666\";\n        String url = \"https://amsoft.dev\";\n        // EJERCICIO\n        extractNumbers(text);\n        // EXTRA\n        System.out.println(String.format(\"Formato de email %s es %s\", email, isFormatEmail(email)));\n        System.out.println(String.format(\"Formato de phone %s es %s\", phone, isFormatPhone(phone)));\n        System.out.println(String.format(\"Formato de url %s es %s\", url, isFormarUrl(url)));\n\n    }\n\n    private static void extractNumbers(String text) {\n        Pattern pattern = Pattern.compile(\"\\\\d+\\\\.\\\\d+|\\\\d+\");\n        Matcher matcher = pattern.matcher(text);\n        while (matcher.find()) {\n            System.out.println(matcher.group());\n        }\n    }\n\n    private static Boolean isFormatEmail(String email) {\n        String regex = \"^[a-zA-Z0-9._%+-]+@[a-zA-Z.-]+\\\\.[a-zA-Z]{2,}$\";\n        return email.matches(regex);\n\n    }\n\n    private static Boolean isFormatPhone(String phone) {\n        String regex = \"\\\\+051\\\\s\\\\d{3}\\\\s\\\\d{3}\\\\s\\\\d{3}\";\n        return phone.matches(regex);\n    }\n\n    private static Boolean isFormarUrl(String url) {\n        String regex = \"^(http|https)://[a-zA-Z0-9-]+(\\\\.[a-zA-Z0-9-]+)*(:\\\\d+)?(/\\\\S*)?$\";\n        return url.matches(regex);\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/java/AnaLauDB.java",
    "content": "import java.util.regex.*;\nimport java.util.*;\n\npublic class AnaLauDB {\n    public static void main(String[] args) {\n        // Extraer todos los números de un texto\n        String texto = \"Mi número es 1234, tengo 2 gatos y 1 perro. El año es 2025.\";\n        Pattern patronNumeros = Pattern.compile(\"\\\\d+\");\n        Matcher matcher = patronNumeros.matcher(texto);\n\n        System.out.println(\"Números encontrados en el texto:\");\n        while (matcher.find()) {\n            System.out.println(matcher.group());\n        }\n\n        // DIFICULTAD EXTRA\n\n        // 1. Validar email\n        String email = \"correo.ejemplo@dominio.com\";\n        Pattern patronEmail = Pattern.compile(\"^[\\\\w.-]+@[\\\\w.-]+\\\\.[a-zA-Z]{2,}$\");\n        System.out.println(\"\\n¿Email válido?: \" + patronEmail.matcher(email).matches());\n\n        // 2. Validar número de teléfono (ejemplo: 10 dígitos)\n        String telefono = \"5512345678\";\n        Pattern patronTelefono = Pattern.compile(\"^\\\\d{10}$\");\n        System.out.println(\"¿Teléfono válido?: \" + patronTelefono.matcher(telefono).matches());\n\n        // 3. Validar URL\n        String url = \"https://www.ejemplo.com/path?query=valor\";\n        Pattern patronUrl = Pattern.compile(\"^(https?://)?([\\\\w.-]+)\\\\.([a-zA-Z]{2,})(/\\\\S*)?$\");\n        System.out.println(\"¿URL válida?: \" + patronUrl.matcher(url).matches());\n    }\n}\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/java/FranDev200.java",
    "content": "import java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\npublic class FranDev200 {\n\n\n    static void main() {\n\n        /*\n         * EJERCICIO:\n         * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n         * creando una que sea capaz de encontrar y extraer todos los números\n         * de un texto.\n         */\n\n        String patron = \"\\\\d+\";\n\n        String texto =\n                \"Usuario: PaulaS40\\n\" +\n                        \"Email: paula.sanchez84@gmail.com\\n\" +\n                        \"Teléfono: +34 612-345-789\\n\" +\n                        \"CódigoPostal: 28013\\n\" +\n                        \"FechaNacimiento: 12/05/1984\\n\" +\n                        \"HoraRegistro: 09:45:32\\n\" +\n                        \"Password: P@ssw0rd_2026\\n\" +\n                        \"Dirección: CalleMayor123, Madrid\\n\" +\n                        \"IP: 192.168.1.45\\n\" +\n                        \"UUID: a3f1-9B2c-77Xz\\n\" +\n                        \"PrecioProducto: 19.99€\\n\" +\n                        \"Descuento: 15%\\n\" +\n                        \"PedidoID: ORD-2026-0045\\n\" +\n                        \"Tarjeta: 1234-5678-9012-3456\\n\";\n\n        Pattern pattern = Pattern.compile(patron);\n        Matcher matcher = pattern.matcher(texto);\n\n        while (matcher.find()) {\n            System.out.println(matcher.group());\n        }\n\n        /*\n        DIFICULTAD EXTRA (opcional):\n         * Crea 3 expresiones regulares (a tu criterio) capaces de:\n         * - Validar un email.\n         * - Validar un número de teléfono.\n         * - Validar una url.\n        */\n\n        String ptrEmail = \"([a-zA-Z]*\\\\d*\\\\w.)*@gmail.com\";\n        String ptrNumero = \"^\\\\d{9}$\";\n        String ptrUrl = \"http(s)?:(.)+\";\n\n        String emails = \"Fr4aBAv1ano.32dd2@gmail.com\\n\" +\n                \"Fr4aBAv1ano.32dd2@gmail\\n\" +\n                \"Fr4aBAv1ano.32dd2@gmail.es\";\n\n        String numeros = \"624893413\\n\" +\n                \"9672944\\n\" +\n                \"3346753573\";\n\n        String urls = \"https://regex101.com/\\n\" +\n                \"https://codegym.cc/es/groups/posts/es.130.expresiones-regulares-en-java\\n\" +\n                \"htts://codegym.cc/es/groups/posts/es.130.expresiones-regulares-en-java\";\n\n        System.out.println(\"\\nVALIDANDO EMAILS (se mostraran los correctos)\");\n        System.out.println(\"- - - - - - - - - - - - - - - - - - - - - - - -\");\n        pattern =  Pattern.compile(ptrEmail);\n        matcher = pattern.matcher(emails);\n\n        while (matcher.find()) {\n            System.out.println(matcher.group());\n        }\n\n        System.out.println(\"\\nVALIDANDO NÚMEROS DE TELÉFONO (se mostraran los correctos)\");\n        System.out.println(\"- - - - - - - - - - - - - - - - - - - - - - - -\");\n        pattern =  Pattern.compile(ptrNumero, Pattern.MULTILINE);\n        matcher = pattern.matcher(numeros);\n\n        while (matcher.find()) {\n            System.out.println(matcher.group());\n        }\n\n        System.out.println(\"\\nVALIDANDO URLs (se mostraran los correctos)\");\n        System.out.println(\"- - - - - - - - - - - - - - - - - - - - - - - -\");\n        pattern =  Pattern.compile(ptrUrl);\n        matcher = pattern.matcher(urls);\n\n        while (matcher.find()) {\n            System.out.println(matcher.group());\n        }\n\n\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/java/JesusWay69.java",
    "content": "package ejercicio16;\n\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\n */\npublic class JesusWay69 {\n\n    public static void main(String[] args) {\n        String text = \"Un año tiene 365 días excepto si es bisiesto que tiene 366 divididos en 12 meses que pueden tener hasta 31 días cada uno.\";\n        char[] characters = text.toCharArray();\n        String nums = \"\";\n        for (int i = 0; i < characters.length; i++) {\n            nums = Character.toString(characters[i]);\n            if (nums.matches(\"\\\\d\")) { //La er para cualquier número se puede declarar como \"\\\\d\" o \"[0-9]\"\n                System.out.print(nums + \"\\s\");\n            }\n\n        }\n        System.out.println(\"\\n\" + emailValidation(\"jesus.way.69@hoTMail.com\"));\n        System.out.println(spainPhoneNumberValidation(\"+34716984941\"));\n        System.out.println(urlValidation(\"www.retosdeprogramacion.com\"));\n        System.out.println(spainDniValidation(\"48526522Y\"));\n        System.out.println(dateValidation(\"01-09-2050\"));\n    }\n\n    private static boolean emailValidation(String email) {\n        email = email.toLowerCase();\n        return email.matches(\"[a-z0-9\\\\._-]+(@)[a-z0-9]+\\\\.[a-z]{2,4}\");\n    //Función que valida una dirección de email con usuario que puede tener letras, números, puntos\n    // o guiones, a continuación una @ , despues el proveedor que sólo puede incluir letras y números\n    // y separado por un punto el dominio que puede tener de 2 a 4 letras.\n    }\n\n    private static boolean spainPhoneNumberValidation(String phoneNumber) {\n        return phoneNumber.matches(\"[9||7||6][0-9]{8}||(\\\\+34)[9||7||6][0-9]{8}\");\n   //Función que valida un nº de tlf español particular cuyo primer número debe ser 6,7 (móvil) o 9 (fijo) ,\n   // tener en total 9 números y que puede incluir o no el prefijo español +34, el número no puede contener espacios.  \n    }\n\n    private static boolean urlValidation(String url) {\n        url = url.toLowerCase();\n        return url.matches(\"[a-z0-9._-]{1,63}\\\\.[a-z]{2,8}||(www)\\\\.[a-z0-9._-]{1,63}\\\\.[a-z]{2,8}\");\n    //Función que valida una url básica con dominio de hasta 63 caracteres que pueden incluir puntos y guiones\n    //   y , separado por un punto el TLD que puede ser de entre 2 y 8 letras (por ej .business)\n    }\n\n    private static boolean spainDniValidation(String dniNum) {\n        dniNum = dniNum.toUpperCase();\n        return dniNum.matches(\"[0-9]{8}[^IOU]{1}\");\n    //Función que valida un dni español con 8 cifras y una letra al final que no puede ser i,o,u ni ñ\n    // tal y como establece la normativa al respecto. \n\n    }\n    private static boolean dateValidation(String date){\n        return date.matches(\"^([0-2][0-9]||[3][0-1])(\\\\/|-)(0[1-9]||1[0-2])(\\\\/|-)((19)[5-9][0-9]||(20)[0-4][0-9]||(2050))$\");\n    //Función que valida una fecha en formato dd/mm/aaaa o dd-mm-yyyy con límites de días a 31,meses a 12 y años entre 1950 y 2050\n    }\n}\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/java/JimsimroDev.java",
    "content": "import java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\nimport static java.lang.String.*;\n\npublic class JimsimroDev {\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.\n */\npublic static void regexTest1(String texto){\n    Pattern patron = Pattern.compile(\"\\\\d+\");\n    patron.matcher(texto).results()\n        .forEach(match -> System.out.println(\"Número encontrado: \" + match.group()));\n  }\n    /*\n     * DIFICULTAD EXTRA (opcional):\n     * Crea 3 expresiones regulares (a tu criterio) capaces de:\n     * - Validar un email.\n     * - Validar un número de teléfono.\n     * - Validar una url.\n     */\n    public static boolean validarMail(String mail){\n        Pattern pattern = Pattern.compile(\"^[\\\\w\\\\.]+@[\\\\w\\\\.]+\\\\.[\\\\w]+$\");\n      return matcherTest(mail, pattern);\n    }\n    public static boolean validarPhone(String phone){\n        Pattern pattern = Pattern.compile(\"^(\\\\+?\\\\d{1,3}\\s*)?\\\\d{3}-\\\\d{3}-\\\\d{4}$\");\n       return  matcherTest(phone,pattern);\n    }\n\n    public static boolean validarUrl(String url){\n        Pattern pattern = Pattern.compile(\"^https?:\\\\/\\\\/(?:www\\\\.)?[\\\\w-]+\\\\.[a-z]{2,3}$\");\n        return matcherTest(url,pattern);\n    }\n\n    public static boolean matcherTest(String texts, Pattern pattern){\n        Matcher matcher = pattern.matcher(texts);\n        return matcher.find();\n    }\n    public static void main(String[] args) {\n        // Expresiones regulares en Java\n        String texto = \"Hola, mi número de teléfono es 123-456-7890 y mi correo es pepito@gmail.com\";\n        regexTest1(texto);\n   //Extra\n        //valid si el correo es valido\n   String mail = \"cualquier@gmail.com\";\n   System.out.printf((validarMail(mail) ? \"El correo %s es valido\" : \"El email %s no es valido\") + \"%n\", mail);\n\n   //valida si el telfono es valido\n   String phone = \"+57300-734-27414\";\n   System.out.printf((validarPhone(phone) ? \"El phone %s es valido\" : \"El phone %s no es valido\") + \"%n\", phone);\n   //valida si la url es valida\n        String url = \"https://www.google.com\";\n       System.out.printf((validarUrl(url) ? \"La url %s es valida\" : \"La url %s no es valida\") + \"%n\", url);\n }\n}\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/java/Josegs95.java",
    "content": "import java.util.ArrayList;\nimport java.util.List;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\npublic class Josegs95 {\n    public static void main(String[] args) {\n        //Ejercicio\n        Pattern pattern = Pattern.compile(\"\\\\d\");\n        Matcher matcher = pattern.matcher(\"En la calle ví 2 coches, 2 perros, 1 señora y 6 farolas\");\n        while(matcher.find()){\n            System.out.println(\"Match: \" + matcher.group());\n        }\n\n        //Reto\n        System.out.println(\"\\n\");\n        retoFinal();\n    }\n\n    public static void retoFinal(){\n        /*Email\n            He decidido que los emails son validos si tienen:\n            Cadena(1-n) + '.'||'-'||'_'(opcional) + Cadena(1-n)\n            @\n            Cadena(1-n) + '-'(opcional) + '.' + Cadena(2-3)\n         */\n        List<String> emailList = getEmailExamples();\n\n        String emailPattern = \"^\\\\w+([.\\\\-_]?\\\\w+)*@\\\\w+(\\\\-\\\\w+)?\\\\.\\\\w{2,3}$\";\n\n        for (String email : emailList){\n            System.out.println(\"\\\"\"+ email + \"\\\" es correcto: \" + Pattern.matches(emailPattern, email));\n        }\n\n        //Número de telefono\n        /*He decidido que los número de teléfonos son validos si tienen:\n            9 dígitos o\n            '+' + 11 dígitos\n         */\n        List<String> phoneList = getPhoneExamples();\n\n        String phonePattern = \"^\\\\d{9}|\\\\+\\\\d{11}$\";\n\n        for (String phoneNumber : phoneList){\n            System.out.println(\"\\\"\"+ phoneNumber + \"\\\" es correcto: \" + Pattern.matches(phonePattern, phoneNumber));\n        }\n\n        //URL\n        /*He decidido que las URL son validas si tienen:\n            'http'|'https''://'(opcional) + (Cadena(1-n) + '.')(opcional) +\n            Cadena(1-n) + ('-' + Cadena(1-n))(opcional) + '.' + Cadena(2-3)\n         */\n        List<String> urlList = getURLExamples();\n\n        //String urlPattern = \"^((http|https)?://)?(\\\\w+\\\\.)?\\\\w+\\\\.\\\\w{2,3}\";\n        String urlPattern = \"^((http|https)?://)?(\\\\w+\\\\.)?[a-zA-Z0-9]+(\\\\-[a-zA-Z0-9]+)*\\\\.\\\\w{2,3}\";\n\n        for (String url : urlList){\n            System.out.println(\"\\\"\"+ url + \"\\\" es correcta: \" + Pattern.matches(urlPattern, url));\n        }\n    }\n\n    private static List<String> getEmailExamples(){\n        List<String> emailList = new ArrayList<>();\n        emailList.add(\"juancarlos@gmail.com\");\n        emailList.add(\"juan.carlos@gmail.com\");\n        emailList.add(\"juan-carlos@gmail.com\");\n        emailList.add(\"juan_carlos@gmail.com\");\n        emailList.add(\"juan.carlos@gmail-gmail.com\");\n\n        emailList.add(\"juan$carlos@gmail.com\");\n        emailList.add(\".juancarlos@gmail.com\");\n        emailList.add(\"juancarlos.@gmail.com\");\n        emailList.add(\"juan.carlos@.gmailcom\");\n        emailList.add(\"juan.carlos@gmailcom.\");\n        emailList.add(\"juan.carlos@gmail.com.es\");\n        emailList.add(\"juan.carlos@gmail-com\");\n        emailList.add(\"juan.carlos@gmail-.com\");\n\n        return emailList;\n    }\n\n    private static List<String> getPhoneExamples(){\n        List<String> phoneList = new ArrayList<>();\n        phoneList.add(\"666554433\");\n        phoneList.add(\"+34666554433\");\n\n        phoneList.add(\"666554433808\");\n        phoneList.add(\"66+6554433808\");\n        phoneList.add(\"66655\");\n        phoneList.add(\"66655plko\");\n\n        return phoneList;\n    }\n\n    private static List<String> getURLExamples(){\n        List<String> urlList = new ArrayList<>();\n        urlList.add(\"https://www.google.es\");\n        urlList.add(\"www.google.es\");\n        urlList.add(\"videos.google.es\");\n        urlList.add(\"google.es\");\n        urlList.add(\"www.google-new.es\");\n\n        urlList.add(\"hptts://www.google.es\");\n        urlList.add(\".google.es\");\n        urlList.add(\"google.\");\n        urlList.add(\"www.goo_gle.es\");\n        urlList.add(\"www.google-.es\");\n        urlList.add(\"www.goo gle.es\");\n        urlList.add(\"www.google.españa\");\n\n        return urlList;\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/java/asjordi.java",
    "content": "import java.util.*;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\npublic class Main {\n    public static void main(String[] args) {\n        var numbers = findNumbers(\"Hay más de -2 y menos de 10 números aquí, o quizás solo hay 1.\");\n        var email = validateEmail(\"algo@gmail.com\");\n        var phone = validatePhoneNumber(\"123-456-7890\");\n        var url = validateUrl(\"https://www.google.com\");\n    }\n\n    /**\n     * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n     * creando una que sea capaz de encontrar y extraer todos los números\n     * de un texto.\n     */\n    static List<String> findNumbers(String str) {\n        List<String> numbers = new LinkedList<>();\n        Pattern p = Pattern.compile(\"-?\\\\d+\");\n        Matcher m = p.matcher(str);\n\n        while (m.find()) numbers.add(m.group());\n\n        return numbers;\n    }\n\n    /**\n     * Valida un correo electrónico.\n     * @param email\n     * @return\n     */\n    static boolean validateEmail(String email) {\n        Pattern p = Pattern.compile(\"^(?=.{1,64}@)[A-Za-z0-9_-]+(\\\\.[A-Za-z0-9_-]+)*@[^-][A-Za-z0-9-]+(\\\\.[A-Za-z0-9-]+)*(\\\\.[A-Za-z]{2,})$\");\n        Matcher m = p.matcher(email);\n        return m.matches();\n    }\n\n    /**\n     * Valida un número de teléfono.\n     * @param phone\n     * @return\n     */\n    static boolean validatePhoneNumber(String phone) {\n        Pattern p = Pattern.compile(\"\\\\d{10}|(?:\\\\d{3}-){2}\\\\d{4}|\\\\(\\\\d{3}\\\\)\\\\d{3}-?\\\\d{4}\");\n        Matcher m = p.matcher(phone);\n        return m.matches();\n    }\n\n    /**\n     * Valida una URL.\n     * @param url\n     * @return\n     */\n    static boolean validateUrl(String url) {\n        Pattern p = Pattern.compile(\"^(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]\");\n        Matcher m = p.matcher(url);\n        return m .matches();\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/java/cesar-ch.java",
    "content": "/*\n    * #16 EXPRESIONES REGULARES\n*/\nimport java.util.regex.*;\n\npublic class Main {\n    public static void main(String[] args) {\n        String texto = \"Este texto contiene 5 numeros del 1 al 5: 1,2,3,4,5\";\n        String regexNumeros = \"\\\\d+\";\n        Pattern pattern = Pattern.compile(regexNumeros);\n        Matcher matcher = pattern.matcher(texto);\n        while (matcher.find()) {\n            System.out.println(matcher.group());\n        }\n        System.out.println(\"------------------\");\n        /*\n         * DIFICULTAD EXTRA \n        */\n\n        String emailCorrecto = \"abc@mail.com\";\n        String emailIncorrecto = \"abcmail.com\";\n        String regexEmail = \"^[a-zA-Z0-9._+-]+@[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,4}$\";\n\n        System.out.println(emailCorrecto + \" es un email valido? \" + emailCorrecto.matches(regexEmail));\n        System.out.println(emailIncorrecto + \" es un email valido? \" + emailIncorrecto.matches(regexEmail));\n\n        String numeroCorrecto = \"+51 987654321\";\n        String numeroIncorrecto = \"987654321\";\n        String regexNumero = \"^\\\\+[0-9]{2}\\\\s[0-9]{9}$\";\n\n        System.out.println(numeroCorrecto + \" es un numero valido? \" + numeroCorrecto.matches(regexNumero));\n        System.out.println(numeroIncorrecto + \" es un numero valido? \" + numeroIncorrecto.matches(regexNumero));\n\n        String urlCorrecta = \"https://retosdeprogramacion.com\";\n        String urlIncorrecta = \"retosdeprogramacion.com/\";\n        String regexUrl = \"^https?://(www\\\\.)?[a-zA-Z0-9-]+\\\\.[a-zA-Z]{2,}$\";\n\n        System.out.println(urlCorrecta + \" es una url valida? \" + urlCorrecta.matches(regexUrl));\n        System.out.println(urlIncorrecta + \" es una url valida? \" + urlIncorrecta.matches(regexUrl));\n    }\n}\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/java/chartypes.java",
    "content": "\nimport java.util.regex.Pattern;\nimport java.util.regex.Matcher;\n\npublic class chartypes {\n    public static void main(String[] args) {\n        exercise();\n        extra();\n\n    }\n\n    private static void exercise() {\n        String regex = \"\\\\d+\";\n        String input = \"3456efg78\";\n        Pattern pattern = Pattern.compile(regex);\n        Matcher matcher = pattern.matcher(input);\n\n        while (matcher.find())\n            System.out.println(matcher.group(0));\n    }\n\n    private static boolean validateEmail(String email) {\n        String regex = \"^\\\\D\\\\w+@\\\\w+.\\\\D{3,5}$\";\n        return Pattern.matches(regex, email);\n    }\n\n    private static boolean validatePhoneNumber(String phoneNumber) {\n        String regex = \"^(\\\\+\\\\d{1,4}(-|\\s)?)?(\\\\d{1,3}(-|\\s)?){2}\\\\d{1,4}$\";\n        return Pattern.matches(regex, phoneNumber);\n    }\n\n    private static boolean validateURL(String url) {\n        String regex = \"^http(s)?://(w{3}.)?\\\\w+\\\\.\\\\D{3,5}$\";\n        return Pattern.matches(regex, url);\n    }\n\n    private static void extra() {\n\n        String email = \"asdfsdf@ssaf22.com\";\n        String phoneNumber = \"+1-123-123-3210\";\n        String url = \"https://carlosperezm.com\";\n\n        System.out.println(validateEmail(email));\n        System.out.println(validatePhoneNumber(phoneNumber));\n        System.out.println(validateURL(url));\n\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/java/danhingar.java",
    "content": "import java.util.ArrayList;\nimport java.util.List;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\npublic class danhingar {\n\n    public static void main(String[] args) {\n        String texto = \"efe4325 f2erf tfr8r743ry\";\n        System.out.println(findNumbers(texto));\n\n        // Extra\n        validateEmail(\"example@gmail.com\");\n        validatePhone(\"6123456789\");\n        validateUrl(\"http://www.google.com\");\n    }\n\n    private static List<String> findNumbers(String text) {\n        Pattern pattern = Pattern.compile(\"\\\\d\");\n        Matcher matcher = pattern.matcher(text);\n        List<String> matches = new ArrayList<>();\n        while (matcher.find()) {\n            matches.add(matcher.group());\n        }\n        return matches;\n    }\n\n    private static void validateEmail(String mail) {\n        Pattern pattern = Pattern.compile(\"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,}$\");\n        Matcher matcher = pattern.matcher(mail);\n        if (matcher.find()) {\n            System.out.println(\"Email válido\");\n        } else {\n            System.out.println(\"Email inválido\");\n        }\n    }\n\n    private static void validatePhone(String number) {\n        Pattern pattern = Pattern.compile(\"^(\\\\+\\\\d{1,3}[- ]?)?\\\\(?\\\\d{1,4}\\\\)?[- ]?\\\\d{1,4}[- ]?\\\\d{1,4}$\");\n        Matcher matcher = pattern.matcher(number);\n        if (matcher.find()) {\n            System.out.println(\"Teléfono válido\");\n        } else {\n            System.out.println(\"Teléfono inválido\");\n        }\n    }\n\n    private static void validateUrl(String url) {\n        Pattern pattern = Pattern.compile(\"^(https?|ftp):\\\\/\\\\/[^\\s/$.?#].[^\\s]*$\");\n        Matcher matcher = pattern.matcher(url);\n        if (matcher.find()) {\n            System.out.println(\"Url válida\");\n        } else {\n            System.out.println(\"Url inválida\");\n        }\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/java/eulogioep.java",
    "content": "import java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\npublic class eulogioep {\n    public static void main(String[] args) {\n        // Texto de ejemplo para probar las expresiones regulares\n        String texto = \"Hola, mi número es 123-456-789. Mi email es usuario@dominio.com \" +\n                       \"y mi sitio web es https://www.ejemplo.com. Tengo 25 años y otro \" +\n                       \"teléfono es +34 612 345 678.\";\n        \n        // 1. Encontrar y extraer todos los números del texto\n        System.out.println(\"1. Extracción de números:\");\n        extraerNumeros(texto);\n        \n        // DIFICULTAD EXTRA\n        // 2. Validación de email\n        System.out.println(\"\\n2. Validación de email:\");\n        validarEmail(\"usuario@dominio.com\");\n        validarEmail(\"email_invalido.com\");\n        \n        // 3. Validación de número de teléfono\n        System.out.println(\"\\n3. Validación de número de teléfono:\");\n        validarTelefono(\"123-456-789\");\n        validarTelefono(\"+34 612 345 678\");\n        validarTelefono(\"1234\");\n        \n        // 4. Validación de URL\n        System.out.println(\"\\n4. Validación de URL:\");\n        validarURL(\"https://www.ejemplo.com\");\n        validarURL(\"http://ejemplo\");\n    }\n    \n    /**\n     * Encuentra y extrae todos los números de un texto.\n     * Utiliza la expresión regular \\\\d+ que significa:\n     * \\\\d - cualquier dígito (0-9)\n     * +   - uno o más dígitos\n     */\n    public static void extraerNumeros(String texto) {\n        Pattern patron = Pattern.compile(\"\\\\d+\");\n        Matcher matcher = patron.matcher(texto);\n        \n        while (matcher.find()) {\n            System.out.println(\"Número encontrado: \" + matcher.group());\n        }\n    }\n    \n    /**\n     * Valida un email usando una expresión regular.\n     * ^[A-Za-z0-9+_.-]+@(.+)$ significa:\n     * ^ - inicio de la línea\n     * [A-Za-z0-9+_.-]+ - uno o más caracteres alfanuméricos, más algunos símbolos permitidos\n     * @ - el símbolo @\n     * (.+) - cualquier carácter (el dominio)\n     * $ - fin de la línea\n     */\n    public static void validarEmail(String email) {\n        String patronEmail = \"^[A-Za-z0-9+_.-]+@(.+)$\";\n        System.out.println(email + \" es válido: \" + email.matches(patronEmail));\n    }\n    \n    /**\n     * Valida un número de teléfono usando una expresión regular.\n     * ^(\\\\+\\\\d{1,3}\\\\s?)?(\\\\d{3}[-\\\\s]?){2}\\\\d{3}$ significa:\n     * ^        - inicio de la línea\n     * (\\\\+\\\\d{1,3}\\\\s?)? - código de país opcional (+34 )\n     * (\\\\d{3}[-\\\\s]?)    - grupos de 3 dígitos separados por guión o espacio\n     * \\\\d{3}$            - últimos 3 dígitos y fin de línea\n     */\n    public static void validarTelefono(String telefono) {\n        String patronTelefono = \"^(\\\\+\\\\d{1,3}\\\\s?)?(\\\\d{3}[-\\\\s]?){2}\\\\d{3}$\";\n        System.out.println(telefono + \" es válido: \" + telefono.matches(patronTelefono));\n    }\n    \n    /**\n     * Valida una URL usando una expresión regular.\n     * ^(https?:\\\\/\\\\/)(www\\\\.)?([\\\\w]+\\\\.)+[\\\\w]{2,63}\\\\/?$ significa:\n     * ^(https?:\\\\/\\\\/)   - inicio con http:// o https://\n     * (www\\\\.)?          - www. opcional\n     * ([\\\\w]+\\\\.)+       - uno o más subdominios\n     * [\\\\w]{2,63}        - dominio de nivel superior (2-63 caracteres)\n     * \\\\/?$              - barra final opcional y fin de línea\n     */\n    public static void validarURL(String url) {\n        String patronURL = \"^(https?:\\\\/\\\\/)(www\\\\.)?([\\\\w]+\\\\.)+[\\\\w]{2,63}\\\\/?$\";\n        System.out.println(url + \" es válido: \" + url.matches(patronURL));\n    }\n}"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/java/h4ckxel.java",
    "content": "/*\n    * #16 EXPRESIONES REGULARES\n*/\nimport java.util.regex.*;\n\npublic class Main {\n    public static void main(String[] args) {\n        String texto = \"Este texto contiene 5 numeros del 1 al 5: 1,2,3,4,5\";\n        String regexNumeros = \"\\\\d+\";\n        Pattern pattern = Pattern.compile(regexNumeros);\n        Matcher matcher = pattern.matcher(texto);\n        while (matcher.find()) {\n            System.out.println(matcher.group());\n        }\n        System.out.println(\"------------------\");\n        /*\n         * DIFICULTAD EXTRA \n        */\n\n        String emailCorrecto = \"abc@mail.com\";\n        String emailIncorrecto = \"abcmail.com\";\n        String regexEmail = \"^[a-zA-Z0-9._+-]+@[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,4}$\";\n\n        System.out.println(emailCorrecto + \" es un email valido? \" + emailCorrecto.matches(regexEmail));\n        System.out.println(emailIncorrecto + \" es un email valido? \" + emailIncorrecto.matches(regexEmail));\n\n        String numeroCorrecto = \"+51 987654321\";\n        String numeroIncorrecto = \"987654321\";\n        String regexNumero = \"^\\\\+[0-9]{2}\\\\s[0-9]{9}$\";\n\n        System.out.println(numeroCorrecto + \" es un numero valido? \" + numeroCorrecto.matches(regexNumero));\n        System.out.println(numeroIncorrecto + \" es un numero valido? \" + numeroIncorrecto.matches(regexNumero));\n\n        String urlCorrecta = \"https://retosdeprogramacion.com\";\n        String urlIncorrecta = \"retosdeprogramacion.com/\";\n        String regexUrl = \"^https?://(www\\\\.)?[a-zA-Z0-9-]+\\\\.[a-zA-Z]{2,}$\";\n\n        System.out.println(urlCorrecta + \" es una url valida? \" + urlCorrecta.matches(regexUrl));\n        System.out.println(urlIncorrecta + \" es una url valida? \" + urlIncorrecta.matches(regexUrl));\n    }\n}\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/java/martinbohorquez.java",
    "content": "import java.util.List;\nimport java.util.regex.Pattern;\n\n/**\n * #16 EXPRESIONES REGULARES\n *\n * @author martinbohorquez\n */\npublic class martinbohorquez {\n\n    public static void main(String[] args) {\n        String texto = \"Achieve your goals in 2024 by setting 3 milestones per quarter, \" +\n                \"and track your progress every 30 days consistently!\";\n        String regex = \"\\\\D+\";// Split by non-digit characters\n        Pattern pattern = Pattern.compile(regex);\n\n        List<String> digits = pattern.splitAsStream(texto)\n                .filter(s -> !s.isBlank())// Filter empty elements\n                .toList();\n\n        System.out.println(digits);\n\n        /*\n         * DIFICULTAD EXTRA\n         */\n        String email = \"email\";\n        match(email, \"ma.boh_26@gmail.com\");\n        match(email, \"ma.boh-26@gmail-peru01.com.pe\");\n        match(email, \"ma.boh.26@gmail.com\");\n        match(email, \"ma_boh+26@gmail.com.pe\");\n        match(email, \"ma.boh+26@gmail.com.pe\");\n        String phoneNumber = \"phoneNumber\";\n        match(phoneNumber, \"+51 999 345 654\");\n        match(phoneNumber, \"+(51) 999 345 654\");\n        match(phoneNumber, \"999345654\");\n        match(phoneNumber, \"+51 123 345\");\n        match(phoneNumber, \"32 999345654\");\n        String url = \"url\";\n        match(url, \"http://www.google.com?name=pepe\");\n        match(url, \"https://www.facebook.com.pe/user/id=1\");\n        match(url, \"m.tiktok.com/live/@mark\");\n        match(url, \"www.peru-champions.com.pe/portal/id=3\");\n        match(url, \"instagram.com.br/login?\");\n    }\n\n    private static void match(String tipo, String texto) {\n        String regexEmail = \"^([\\\\w.+-]+@[\\\\w.-]+)$\";\n        String regexPhoneNumber = \"^\\\\+?(\\\\(?\\\\d{1,3}\\\\)?)?(\\\\s\\\\d+)*|\\\\d{3,}(\\\\s\\\\d+)*$\";\n        String regexUrl = \"^(?:https?://)?(?:(?:www|m)\\\\.)?((?:[a-zA-Z0-9-]+\\\\.)+[a-zA-Z]{2,})([/?]+\\\\S*)?$\";\n\n        switch (tipo) {\n            case \"email\" ->\n                    System.out.printf(\"El correo electrónico '%s' es válido: %b\", texto, texto.matches(regexEmail));\n            case \"phoneNumber\" ->\n                    System.out.printf(\"El número telefónico '%s' es válido: %b\", texto, texto.matches(regexPhoneNumber));\n            case \"url\" -> System.out.printf(\"La URL '%s' es válida: %b\", texto, texto.matches(regexUrl));\n        }\n    }\n}\n\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/java/miguelex.java",
    "content": "import java.util.regex.*;\nimport java.util.*;\n\npublic class miguelex {\n    public static void regExpr(String cadena) {\n        String patron = \"-?\\\\d+(\\\\.\\\\d+)?\";\n        Pattern p = Pattern.compile(patron);\n        Matcher m = p.matcher(cadena);\n\n        System.out.println(\"Números encontrados:\");\n        while (m.find()) {\n            System.out.println(m.group());\n        }\n        System.out.println();\n    }\n\n    public static void main(String[] args) {\n        String texto = \"Este es un texto con números como 123, 45.6, -7 y 1000.\";\n        System.out.println(\"Vamos a analizar el siguiente texto:\");\n        System.out.println(\"'\" + texto + \"'\\n\");\n        regExpr(texto);\n\n        texto = \"123Erase una vez un número 1234567890 y otro 0987654321. Y para terminar456\";\n        System.out.println(\"Vamos a analizar el siguiente texto:\");\n        System.out.println(\"'\" + texto + \"'\\n\");\n        regExpr(texto);\n\n        // Extra\n        emailValidation(\"correo@correo.com\");\n        emailValidation(\"correo@correo\");\n\n        phoneValidation(\"+34 123456789\");\n        phoneValidation(\"123456789\");\n\n        urlValidation(\"http://www.google.com\");\n        urlValidation(\"www.google.com\");\n    }\n\n    public static void emailValidation(String email) {\n        String patron = \"^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,4}$\";\n        Pattern p = Pattern.compile(patron);\n        Matcher m = p.matcher(email);\n        if (m.matches()) {\n            System.out.println(\"El email \" + email + \" es válido.\");\n        } else {\n            System.out.println(\"El email \" + email + \" no es válido.\");\n        }\n    }\n\n    public static void phoneValidation(String phone) {\n        String patron = \"^\\\\+?(\\\\d{2,3})?[-. ]?\\\\d{9}$\";\n        Pattern p = Pattern.compile(patron);\n        Matcher m = p.matcher(phone);\n        if (m.matches()) {\n            System.out.println(\"El teléfono \" + phone + \" es válido.\");\n        } else {\n            System.out.println(\"El teléfono \" + phone + \" no es válido.\");\n        }\n    }\n\n    public static void urlValidation(String url) {\n        String patron = \"^(http|https):\\\\/\\\\/[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,4}\";\n        Pattern p = Pattern.compile(patron);\n        Matcher m = p.matcher(url);\n        if (m.matches()) {\n            System.out.println(\"La URL \" + url + \" es válida.\");\n        } else {\n            System.out.println(\"La URL \" + url + \" no es válida.\");\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/java/simonguzman.java",
    "content": "import java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\npublic class simonguzman {\n    public static void main(String[] args) {\n        extractNumbersOfText();\n        validateEmail();\n        validatePhoneNumber();\n        validateUrl();\n    }\n\n    static void extractNumbersOfText(){\n        String text = \"Este es un texto con numeros: 1,23,456,7890,0.5\";\n        Pattern pattern = Pattern.compile(\"\\\\d+(\\\\.\\\\d+)?\"); //Expresion regular para encontrar numeros\n        Matcher matcher = pattern.matcher(text);\n\n        while(matcher.find()){\n            System.out.println(\"Numero encontrado: \"+matcher.group());\n        }\n    } \n\n    static void validateEmail(){\n        String email = \"siguzman@unicauca.edu.co\";\n        String pattern = \"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,}$\"; //Expresion regular para validaar el email\n        if (Pattern.matches(pattern, email)){\n            System.out.println(\"Email valido\");\n        }else{\n            System.out.println(\"Email no valido\");\n        }\n    }\n\n    static void validatePhoneNumber(){\n        String number = \"+1 123 456 7890\";\n        String pattern = \"^\\\\+?\\\\d{1,3}?[- .]?\\\\(?(?:\\\\d{2,3})\\\\)?[- .]?\\\\d\\\\d\\\\d[- .]?\\\\d\\\\d\\\\d\\\\d$\"; // expresión regular para validar número de teléfono\n        if (Pattern.matches(pattern, number)){\n            System.out.println(\"Número de teléfono válido\");\n        }else{\n            System.out.println(\"Numero de telefono no valido\");\n        }\n    }\n\n    static void validateUrl(){\n        String url = \"https://www.example.com/path/to/resource\";\n        String pattern = \"^((http|https)://)(www.)?[a-zA-Z0-9@:%._\\\\+~#?&//=]{2,256}\\\\.[a-z]{2,6}\\\\b([-a-zA-Z0-9@:%_\\\\+.~#?&//=]*)$\"; // expresión regular para validar URL\n        if(Pattern.matches(pattern, url)){\n            System.out.println(\"Url valido.\");\n        }else{\n            System.out.println(\"Url no valido\");\n        }\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/javascript/7R0N1X.js",
    "content": "const regex = /\\-?\\d+/;\nconst str = 'precio: 888'\nconsole.log(str.match(regex))\n\n\n// DIFICULTAD EXTRA\nconst emailRegex = /\\S+@\\S+\\.\\S+/;\nconst email = 'admin@mail.com'\nemailRegex.test(email) ? console.log(`El correo ${email} es válido.`) : console.log(`El correo ${email} es inválido.`)\n\nconst phoneRegex = /^\\+?(\\d{1,3})?[-.\\s]?(\\d{2,4})[-.\\s]?(\\d{3})[-.\\s]?(\\d{4})$/;\nconst phoneNumber = '+593 97 999 1222'\nphoneRegex.test(phoneNumber) ? console.log(`El número de teléfono ${phoneNumber} es válido.`) : console.log(`El número de teléfono ${phoneNumber} es inválido.`)\n\nconst urlRegex = /^(https?:\\/\\/)?([a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,}(:\\d+)?(\\/[^\\s]*)?$/;\nconst url = 'https://tronix-portfolio.vercel.app'\nurlRegex.test(url) ? console.log(`La url ${url} es válida.`) : console.log(`La url ${url} no es válida.`)"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/javascript/AChapeton.js",
    "content": "// EJERCICIO\n\nconst regexHasNumbers = /[0-9]/;\n\nconst text1 = 'Lorem Ipsum es simplemente el texto de relleno de las imprentas desde el año 1500';\nconst text2 = 'Solo letras, sin nada de numeros';\nconst text3 = '1234567890-abc';\n\nconsole.log(\"El texto \\\"\".concat(text1, \"\\\" tiene numeros?: \"), regexHasNumbers.test(text1));\nconsole.log(\"El texto \\\"\".concat(text2, \"\\\" tiene numeros?: \"), regexHasNumbers.test(text2));\nconsole.log(\"El texto \\\"\".concat(text3, \"\\\" tiene numeros?: \"), regexHasNumbers.test(text3));\n\n\n// DESAFIO EXTRA\n\n//Regex para correos\nconst regexEmail = /^[\\w\\-\\.]+@([\\w]+\\.)+[\\w]{2,4}$/;\n\nconst email1 = 'andres.chapeton0206@gmail.com';\nconst email2 = 'andres@gmail';\n\nconsole.log(\"El correo \\\"\".concat(email1, \"\\\" es valido?: \"), regexEmail.test(email1));\nconsole.log(\"El correo \\\"\".concat(email2, \"\\\" es valido?: \"), regexEmail.test(email2));\n\n// Regex para telefonos (Con formato 0000-0000)\n\nconst regexPhone = /([0-9]{4})-([0-9]{4})/;\n\nconst phone1 = '7777-9999';\nconst phone2 = '77-5555';\n\nconsole.log(\"El telefono \\\"\".concat(phone1, \"\\\" es valido?: \"), regexPhone.test(phone1));\nconsole.log(\"El telefono \\\"\".concat(phone2, \"\\\" es valido?: \"), regexPhone.test(phone2));\n\n// Regex para URL (Con formato https o http)\n\nconst regexURL = /^https?:\\/\\/([a-zA-Z0-9]*\\.)?[a-zA-Z0-9]*\\.([a-zA-Z]{3})(\\.[a-zA-Z]{2,3})?\\/?$/;\n\nconst url1 = 'https://www.moure.dev';\nconst url2 = 'http://www.holamundo.dev';\nconst url3 = 'www.google.com';\nconst url4 = 'https://www.google';\nconst url5 = 'w.google';\n\nconsole.log(\"La URL \\\"\".concat(url1, \"\\\" es valida?: \"), regexURL.test(url1));\nconsole.log(\"La URL \\\"\".concat(url2, \"\\\" es valida?: \"), regexURL.test(url2));\nconsole.log(\"La URL \\\"\".concat(url3, \"\\\" es valida?: \"), regexURL.test(url3));\nconsole.log(\"La URL \\\"\".concat(url4, \"\\\" es valida?: \"), regexURL.test(url4));\nconsole.log(\"La URL \\\"\".concat(url5, \"\\\" es valida?: \"), regexURL.test(url5));\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/javascript/DavidMoralesDeveloper.js",
    "content": "let re = /ab+c/;\nlet re1 = new RegExp(\"ab+c\");\n\nconst paragraph = 'The quick brown fox jumps over the lazy dog. It barked. abc';\nconst mayus = /[A-Z]/g;\nconst minus = /[a-z]/g;\nconst found = paragraph.match(mayus);\n// const found1 = paragraph.match(minus);\nconst found2 = paragraph.match(re1);\nconsole.log(found)\nconsole.log(found2)\n// ejemplos\n\n// * EJERCICIO:\n// * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n// * creando una que sea capaz de encontrar y extraer todos los números\n// * de un texto.\n// Crea una exprecion regular\nconst regexnum = /[0-9]/g\nfunction extraerNum (frase) {\n    const numeros = frase.match(regexnum)\nreturn console.log(numeros)\n}\n\nextraerNum('Este es el ejercicio 16 publicado 15/04/2024.')\n\n// *\n// * DIFICULTAD EXTRA (opcional):\n// * Crea 3 expresiones regulares (a tu criterio) capaces de:\n// * - Validar un email.\n// * - Validar un número de teléfono.\n// * - Validar una url.\n\nconst email1 = 'ejemplo@gmail.com'\nconst email2 = 'ejemplo@gmail.'\n\nfunction ecmailCheck(email){\n    const mailRegex =(/^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,3}$/)\n    if(mailRegex.test(email))  {\n        console.log('email aprobo el test')\n    }else{\n        console.log('email no aprobo el test')\n    }\n}\necmailCheck(email1)\necmailCheck(email2)\n// ------------------------------------------------------------\nconst phone = '3490-8904'\nconst phone1 = '4141-515'\n\nfunction phoneCheck( phone ){\n    const phoneRegex = /([0-9]{4})-([0-9]{4})/\n    if(phoneRegex.test(phone)){\n       console.log( 'phone telefono valido')\n    }else{\n        console.log('phone no valido')\n    }\n}\n\nphoneCheck(phone)\n\n// -----------------------------------------------------------\nconst web = \"http://www.moure.dev\"\nconst web1 = \"http://www.mouredev\"\n\nfunction webCheck(web){\n\n    const webRegex = /^http\\[s\\]?:\\/\\/(www.)?[\\w]+\\.\\[a-zA-Z\\]{2,}$/;\n    if(webRegex.test(web)){\n        console.log('web aprobada')\n    }else{\n        console.log('web no aceptable' )\n    }\n}\n\nwebCheck(web)\nwebCheck(web1)"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/javascript/Deyvid-10.js",
    "content": "// Expresiones regulares\n\nlet texto = `En un día soleado de verano, caminé por la ciudad y vi a 5 pájaros volando en el cielo. \n            Pasé por 10 tiendas diferentes, donde compré 3 manzanas y 2 botellas de agua. \n            Luego, me senté en un banco y leí durante 2 horas un libro fascinante sobre la historia \n            del universo. Después, conocí a 7 amigos en un café y compartimos risas y conversaciones \n            durante toda la tarde. Finalmente, al regresar a casa, preparé una deliciosa cena con 4 \n            tipos diferentes de pasta y disfruté de una película emocionante hasta altas horas de la \n            noche.`\n\nlet regex = /\\d+/g\n\n// console.log(texto.match(regex));\n\n//  DIFICULTAD EXTRA\n\nlet regexCorro = /.+@\\w+[.]\\w+/\nlet regexTelefono = /\\d{3}-\\d{3}-\\d{4}/\nlet regexUrl = /(http|https):[/][/].+[.].+/\n\nlet correo = \"marmodeyvid@gmail.com\"\nlet telefono = \"809-447-5619\"\nlet url = \"https://retosdeprogramacion.com/roadmap/\"\n\nfunction validar(nombre, texto, expresion)\n{\n    console.log(\"*\".repeat(25) + ` ${nombre} ` + \"*\".repeat(25));\n    console.log(expresion.test(texto) ? \"Coincidencia: Si\" : \"Coincidencia: No\");\n    console.log(`Texto extraido: ${texto.match(expresion)[0]}\\n`);\n}\n\nvalidar(\"Correo\", correo, regexCorro)\nvalidar(\"Telefono\", telefono, regexTelefono)\nvalidar(\"Url\", url, regexUrl)"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/javascript/FabianRpv.js",
    "content": "// Expresiones Regulares\n\nconst texto = \"Hoy es 19 de Marzo del 2025\"\n\nconst regex = /\\d+/g;\n\nconst numeros = texto.match(regex)\n\nconsole.log(numeros)\n\n\n// Validar Email\n\nconst email = \"usuario@example.com\";\n\nconst regexEmail = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$/;\n\nconsole.log(regexEmail.test(email));\n\n\n// Validar numero de telefono\n\nconst telefono = \"+1-800-555-5555\";\n\nconst regexTelefono = /^\\+?\\d{1,3}[-.\\s]?\\(?\\d{1,4}\\)?[-.\\s]?\\d{1,4}[-.\\s]?\\d{1,9}$/;\n\nconsole.log(regexTelefono.test(telefono));\n\n\n// Validar una url\n\nconst url = \"https://www.example.com/path\";\n\nconst regexURL = /^(https?:\\/\\/)?(www\\.)?[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}(\\/\\S*)?$/;\n\nconsole.log(regexURL.test(url));"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/javascript/Glitzypanic.js",
    "content": "/*\n * EJERCICIO:\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\n */\n\n// Mejor eleccion cuando se utiliza el patrón constante\nlet re = /zcb/;\n\n// Mejor cuando el patrón puede variar o proviene de una entrada dinámica\nlet red = new RegExp(\"vbn\");\n\n// Método Test para comprobar si hay coincidencias y arrojar un boolean\nlet test = /hola/.test(\"hola mundo\"); // true\n\n// Método exec() busca coincidencias y devuelve un array con los resultados o un null si no hay coincidencias\nlet result = /hola/.exec(\n  \"hola mundo\"\n) // Métodos del objeto \"String\"\n`match()` // Busca coincidencias en una cadena y devuelve un array.\n`replace()` // Reemplaza las coincidencias encontradas con otro texto.\n`search()` // Busca una coincidencia y devuelve la posicion de la primera aparición.\n`split()`; // Divide una cadena en un arreglo usando la expresión regular como delimitador.\n\n// Ejercicio 1\nlet phoneNumber = \"Hola, mi numero de telefono es +569 1234567\";\nlet regex = /(\\d+)/g;\n\nlet newNumber = phoneNumber.match(regex);\n\nconsole.log(newNumber);\n\n// Ejercicio 2\n\n// Validar un email\nfunction validarEmail(email) {\n  const regex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$/;\n  return regex.test(email);\n}\n\nconst emailPrueba = \"ejemplo@dominio.com\";\nif (validarEmail(emailPrueba)) {\n  console.log(\"El email es valido\");\n} else {\n  console.log(\"El email es invalido\");\n}\n\n// Validar un número telefónico\nfunction validarTelefono(phone) {\n  const regex = /\\d/g;\n  return regex.test(phone);\n}\n\nconst telefono = \"926333333\";\nif (validarTelefono(telefono)) {\n  console.log(\"El telefono es valido\");\n} else {\n  console.log(\"El numero telefonico es invalido\");\n}\n// Validar una url\nconst isValidURL = (urlString) => {\n  return patronURL.test(urlString);\n};\n\nconsole.log(isValidURL(\"https://www.ejemplo.com\")); // true\nconsole.log(isValidURL(\"ftp://www.ejemplo.com\")); // false\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #16 - JavaScript ->Jesus Antonio Escamilla */\n/**\n * Las expresiones regulares son patrones que se utilizan para hacer coincidir combinaciones de caracteres en cadenas.\n * En JavaScript, las expresiones regulares también son objetos.\n * Una expresión regular es una secuencia de caracteres que forma una buscar patrón.\n*/\n\n//---EJERCIÓ---\n\n// Expresión con Función Objeto\nlet re = new RegExp(\"Jesus Antonio\");\n\n// Expresión Literal\nlet regex = /\\d+/g;\n\n// El textos en particulares.\nconst texto1 = \"Yo nací en 1999 y tengo 24 años de edad.\";\nconst yo = \"Jesus Antonio Escamilla - de la tierra 616, del universo 999\"\n\n// Se llama la función y se usa uno de los métodos de excreciones regulares que muestre los números.\nfunction texto_Num(texto) {\n    const númerosEncontrados = texto.match(regex);\n    return númerosEncontrados.map(num => parseInt(num));\n}\nconsole.log(`El texto, \"${texto1}\" contiene los siguientes números:`,texto_Num(texto1));\n\n//---Alguno Método de Expresiones Regulares---\n// exec(string)\nlet exec = re.exec(yo);\nconsole.log(`Si se encontró`,exec);\n\n//---Otr ejemplos de expresiones regulares---\n// Uso de caracteres especiales\nlet reg = /e/g;\n// Pero existen mas como: /CHAR+/ (Mas a en el texto), /\\d+/ (Mas dígitos), /\\w+/ (Mas letras), /\\s+/ (Mas espacios)\nconst abecedario = ['a', 'b', 'c', 'd', 'e', 'f'];\nconsole.log('Si se encontró las letras:', reg.exec(abecedario));\n\n// Búsqueda de caracteres específicos\nlet reg_especifico = /[abc]/;\nconsole.log('Se lo logro encontrar abc:', reg_especifico.test(abecedario));\n\n\n\n\n/**-----DIFICULTAD EXTRA-----*/\n\n//  Excreción para Email\nconst regex_Email = /^[\\w.%+-]+@[\\w.-]+\\.[a-zA-Z]+$/;   //Aquí es la expresión regular propia\n// Los ejemplos de correos electrónicos\nconst emailJesus = 'JesusA@outlook.com';\nconst emailEmpresa = '@trnetwork.com.mx'\n//  Imprimiendo en la consola\nconsole.log(`Es valido el correo \"${emailJesus}\":`, regex_Email.test(emailJesus));\nconsole.log(`Es valido el correo \"${emailEmpresa}\"`, regex_Email.test(emailEmpresa));\n\n\n//  Expresión para Teléfono\nconst regex_Teléfono = /^\\+([\\d]{2})-([\\d]{3})-([\\d]{3})-([\\d]{4})/;    //Aquí es la expresión regular propia\n// Los ejemplos de los teléfonos\nconst teléfonoA = '+52-953-123-4567';\nconst teléfonoB = '+1 123 456 7890';\n//  Imprimiendo en la consola\nconsole.log(`Es valido el teléfono \"${teléfonoA}\":`, regex_Teléfono.test(teléfonoA));\nconsole.log(`Es valido el teléfono \"${teléfonoB}\"`, regex_Teléfono.test(teléfonoB));\n\n\n//  Expresión para URL\nconst regex_URL = /^(http[s]?:\\/\\/)?([\\d\\w]*\\.)?[\\w]*\\.([\\w]{3})(\\.[\\w]{2,3})?\\/?$/;  //Aquí es la expresión regular propia\n// Los ejemplos de URL\nconst google_Url = 'www.google.com';\nconst moure_Url = 'https://www.moure.dev';\nconst aventure_Url = 'jajatoonstime.blogspot'\n//  Impresiones en la consola\nconsole.log(`Es valido la URL \"${google_Url}\":`, regex_URL.test(google_Url));\nconsole.log(`Es valido la URL \"${moure_Url}\":`, regex_URL.test(moure_Url));\nconsole.log(`Es valido la URL \"${aventure_Url}\":`, regex_URL.test(aventure_Url));\n\n\n/**-----DIFICULTAD EXTRA-----*/"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/javascript/RaulDoezon.js",
    "content": "// https://regexone.com/\n// https://www.freecodecamp.org/espanol/news/expresiones-regulares-regex-en-javascript-manual-para-principiantes/\n\n/*\n  EJERCICIO:\n  Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n  creando una que sea capaz de encontrar y extraer todos los números\n  de un texto.\n*/\n\nconst text = \"Gundam RX-78-2\";\nconst modifiedText = text.replace(/\\d+/g, '');\n\nconsole.log(`Texto inicial: ${text}`);\nconsole.log(`Texto sin números: ${modifiedText}`);\n\n/*\n  DIFICULTAD EXTRA (opcional):\n  Crea 3 expresiones regulares (a tu criterio) capaces de:\n  - Validar un email.\n  - Validar un número de teléfono.\n  - Validar una url.\n*/\n\nconst email = \"raul@mail.com\";\nconst validateEmail = /[^\\s@](\\.[a-z]{2,63})/\n\nconst phone = \"5555089590\";\nconst valiodatePhone = /\\d{10}/;\n\nconst url = \"https://raul.com.mx\";\nconst validateURL = /(https?:\\/\\/)?(\\.[a-z]{2,63})/;\n\nconsole.log(`¿El email es válido? ${validateEmail.test(email)}`);\nconsole.log(`¿El teléfono es válido? ${valiodatePhone.test(phone)}`);\nconsole.log(`¿La URL es válida? ${validateURL.test(url)}`);\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/javascript/RicJDev.js",
    "content": "//EJERCICIO\nlet myText = '4,iS?SbRj*E.g.URXcB5{iST23]-!i';\nlet regEx = /\\d+/g;\n\nconsole.log('\\nTexto de ejemplo:', myText);\nconsole.log(`\\nNumeros encontrados: ${myText.match(regEx)}`);\n\n//EXTRA\nfunction validateEmail(email) {\n\tlet emailRegEx = /\\b[\\w\\.-]+@[\\w\\.-]+\\.\\w{2,4}\\b/gi;\n\tconsole.log(\n\t\t`\\n${email} es un correo electrónico válido?:`,\n\t\temailRegEx.test(email)\n\t);\n}\nvalidateEmail('ricFakeEmail@gmail.com');\n\nfunction validatePhone(phone) {\n\t//Formato +58(000)-0000000\n\tlet phoneRegEx = /\\+58+(\\(\\d{3}\\))\\-(\\d{7})/g;\n\tconsole.log(\n\t\t`\\n${phone} es un número telefónico válido?:`,\n\t\tphoneRegEx.test(phone)\n\t);\n}\nvalidatePhone('+58(412)-3333333');\n\nfunction validateUrl(url) {\n\tlet urlRegEx = /[(http(s)?):\\/\\/(www\\.)?\\w\\d]{2,}\\.[a-z]{2,4}\\b([-\\w\\d]*)/gi;\n\tconsole.log(`\\n${url} es una url válida?`, urlRegEx.test(url));\n}\nvalidateUrl('https://github.com/');\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/javascript/Sac-Corts.js",
    "content": "const text = \"There are 3 cats, 7 dogs and 15 birds in the park.\";\nconst numbers = text.match(/\\d+/g) || [];\nconsole.log(numbers);\n\n// Extra Exercise //\nconst emailPattern = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$/;\nconst email = \"isaac@gmail.com\";\nconsole.log(emailPattern.test(email)); \n\nconst telPattern = /^\\d{3}-\\d{3}-\\d{4}$/;\nconst number = \"899-112-5641\";\nconsole.log(telPattern.test(number));\n\nconst urlPattern = /^(https?:\\/\\/)?([\\da-z.-]+\\.[a-z.]{2,6}|[\\d.]+)(:[0-9]{1,5})?(\\/[\\w.-]*)*\\/?(\\?[\\w=&]*)?(#[\\w-]*)?$/i;\nconst url = \"https://retosdeprogramacion.com/roadmap/\"\nconsole.log(urlPattern.test(url));"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/javascript/adrs1166ma.js",
    "content": "/* 🔥 EJERCICIO:\nUtilizando tu lenguaje, explora el concepto de expresiones regulares,\ncreando una que sea capaz de encontrar y extraer todos los números\nde un texto.\n*/\nconst texto = \"El precio es de 123 euros, pero con un descuento del 15%. Además, hay 4 productos disponibles.\";\n\n// Expresión regular para encontrar números\nconst regexNumeros = /\\d+/g;\n\n// Extraer números del texto\nconst numeros = texto.match(regexNumeros);\n\nconsole.log(\"Números encontrados:\", numeros);\n// Números encontrados:  (3) ['123', '15', '4']\n\n/*\nDictionary 📗 [ /\\d+/g ] = {\n    \\d: Coincide con cualquier dígito (0-9).\n    +: Indica que debe coincidir con uno o más dígitos consecutivos.\n    g: Modificador global que busca todas las coincidencias en el texto (no solo la primera).\n}\n*/\n//------------------------------------------------------------------------------------------------------------\n//------------------------------------------------------------------------------------------------------------\n\n/* 🔥 DIFICULTAD EXTRA (opcional):\nCrea 3 expresiones regulares (a tu criterio) capaces de:\n- Validar un email.\n- Validar un número de teléfono.\n- Validar una url.\n*/\n\nfunction validarEmail(email) {\n    const regexEmail = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$/;\n    return regexEmail.test(email);\n}\n\nfunction validarTelefono(telefono) {\n    const regexTelefono = /^\\+?\\d{1,3}?[-.\\s]?\\(?\\d{1,4}\\)?[-.\\s]?\\d{1,4}[-.\\s]?\\d{1,9}$/;\n    return regexTelefono.test(telefono);\n}\n\nfunction validarURL(url) {\n    const regexURL = /^(https?:\\/\\/)?([a-zA-Z0-9.-]+\\.[a-zA-Z]{2,})(\\/.*)?$/;\n    return regexURL.test(url);\n}\n\nconsole.log(\"¿Es válido el email 'usuario@example.com'?\", validarEmail(\"usuario@example.com\"))\nconsole.log(\"¿Es válido el email 'usuario@.com'?\", validarEmail(\"usuario@.com\"))\n// ¿Es válido el email 'usuario@example.com'? true\n// ¿Es válido el email 'usuario@.com'? false\n\nconsole.log(\"¿Es válido el teléfono '+51-999-999-999'?\", validarTelefono(\"+51-999-999-999\"))\nconsole.log(\"¿Es válido el teléfono '123'?\", validarTelefono(\"123\"))\n// ¿Es válido el teléfono '+51-999-999-999'? true\n// ¿Es válido el teléfono '123'? false\n\nconsole.log(\"¿Es válida la URL 'https://www.example.com'?\", validarURL(\"https://www.example.com\"))\nconsole.log(\"¿Es válida la URL 'www.example'?\", validarURL(\"www.example\"))\n// ¿Es válida la URL 'https://www.example.com'? true\n// ¿Es válida la URL 'www.example'? true\n\n\n/*\nDictionary 📗 [ expresiones regulares ] = {\n    regexEmail : {\n        ^[a-zA-Z0-9._%+-]+: Parte local del email (antes del @), permite letras, números y caracteres especiales como ., _, %, +, -.\n        @[a-zA-Z0-9.-]+: Dominio del email, permite letras, números, puntos (.) y guiones (-).\n        \\.[a-zA-Z]{2,}$: Extensión del dominio (ejemplo: .com, .es), debe tener al menos 2 caracteres.\n    }\n    regexTelefono : {\n        ^\\+?: Opcionalmente comienza con un + (indicador de país).\n        \\d{1,3}?: Código de país (1 a 3 dígitos).\n        [-.\\s]?: Separadores opcionales (-, ., espacio).\n        \\(?\\d{1,4}\\)?: Código de área opcionalmente entre paréntesis.\n        \\d{1,4}[-.\\s]?\\d{1,4}[-.\\s]?\\d{1,9}$: Número principal, separado en partes.\n    }\n    regexURL : {\n        ^(https?:\\/\\/)?: Protocolo opcional (http:// o https://).\n        [a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}: Dominio y extensión (ejemplo: example.com).\n        (\\/.*)?$: Ruta opcional después del dominio.\n    }\n}\n*/"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/javascript/agusrosero.js",
    "content": "/*\n * EJERCICIO:\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.\n */\nconst text = \"H0L4 QU3 T4L\";\nconst myRe = /\\d+/g;\nconsole.log(text.match(myRe));\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\n */\n\n// Validar un email.\nconst emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\nconst email = \"test@email.com\";\nconsole.log(emailRegex.test(email));\n\n// Validar un número de teléfono.\nconst phoneRegex =\n  /^\\+?(\\d{1,3})?[-.\\s]?(\\(?\\d{3}\\)?)?[-.\\s]?\\d{3}[-.\\s]?\\d{4}$/;\nconst phone = \"+54 341 3777777\";\nconsole.log(phoneRegex.test(phone));\n\n// Validar una url.\nconst urlRegex = /^(https?:\\/\\/)?([\\da-z.-]+)\\.([a-z.]{2,6})([/\\w .-]*)*\\/?$/;\nconst url = \"https://www.google.com\";\nconsole.log(urlRegex.test(url));\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/javascript/bernatcs.js",
    "content": "// ** EJERCICIO\n\nconst texto = '32T0 32 UN4 PRU3B4';\nconst regex = /\\d+/g;\nconst result = texto.match(regex);\nresult // Array(6) [ '32', '0', '32', '4', '3', '4']\n\n// ** DIFICULTAD EXTRA ** -------------------------------------------------------------------------------------------------------------------------------------------------\n\nconst regexEmail = /^[a-zA-Z0-9.]+@[a-zA-Z0-9]+\\.[a-zA-Z]{2,}$/\nconst regexTelefono = /^[0-9]{9}$/\nconst regexUrl = /^(https?:\\/\\/|ftp:\\/\\/)[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}.*$/"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/javascript/caterinarodriguezdev.js",
    "content": "/*\n * EJERCICIO:\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\n */\n\nconst textoConNumeros = \"El universo es un vasto y enigmático lugar que se estima tiene alrededor de 13.800 millones de años de antigüedad. Contiene más de 2 billones de galaxias, cada una con miles de millones de estrellas; por ejemplo, nuestra propia galaxia, la Vía Láctea, alberga aproximadamente 100.000 millones de estrellas.\";\n\nconst todosLosDigitos = /\\d/g;\nconst digitos = textoConNumeros.match(todosLosDigitos);\nconsole.log(digitos);\n\nconst email = \"a@a.com\";\nconst regexEmail = /^[\\w.-]+@[a-zA-Z\\d.-]+\\.[a-zA-Z]{2,}$/;\nconsole.log(regexEmail.test(email) ? 'email válido' : 'email no válido');\n\nconst url = \"https://google.com\";\nconst regexUrl = /^(https?:\\/\\/)[a-z]+\\.[a-z]{2,}$/;\nconsole.log(regexUrl.test(url) ? 'URL válida' : 'URL no válida');\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/javascript/cesar-ch.js",
    "content": "/*\n * #16 EXPRESIONES REGULARES\n*/\n\nconst texto = \"Es texto contiene 5 numeros del 1 al 5: 1,2,3,4,5\"\nconst regexNumeros = /\\d+/g\nconsole.log(\"Numeros encontrados: \" + texto.match(regexNumeros))\n\n\n/*\n * DIFICULTAD EXTRA \n*/\n\nconst emailCorrecto = \"abc@mail.com\"\nconst emailIncorrecto = \"abcmail.com\"\nconst regexEmail = /^[a-zA-Z0-9._+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}$/\n\nconsole.log(`${emailCorrecto} es un email valido? ` + regexEmail.test(emailCorrecto))\nconsole.log(`${emailIncorrecto} es un email valido? ` + regexEmail.test(emailIncorrecto))\n\nconst numeroCorrecto = \"+51 987654321\"\nconst numeroIncorrecto = \"987654321\"\nconst regexNumero = /^\\+[0-9]{2}\\s[0-9]{9}$/\n\nconsole.log(`${numeroCorrecto} es un numero valido? ` + regexNumero.test(numeroCorrecto))\nconsole.log(`${numeroIncorrecto} es un numero valido? ` + regexNumero.test(numeroIncorrecto))\n\n\nconst urlCorrecta = \"https://retosdeprogramacion.com\"\nconst urlIncorrecta = \"retosdeprogramacion.com/\"\nconst regexUrl = /^https?:\\/\\/(www\\.)?[a-zA-Z0-9-]+\\.[a-zA-Z]{2,}$/\n\nconsole.log(`${urlCorrecta} es una url valida? ` + regexUrl.test(urlCorrecta))\nconsole.log(`${urlIncorrecta} es una url valida? ` + regexUrl.test(urlIncorrecta))"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/javascript/christian-jfr.js",
    "content": "// #16 EXPRESIONES REGULARES\n\n/**\n * EJERCICIO:\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.\n */\n\nconst regex = /\\d+/g;\n\nconst extractNumbers = (string) => {\n\tconst numbers = string.match(regex);\n\n\treturn numbers ? numbers : [];\n};\n\nconsole.log(extractNumbers('Hello World')); // -> []\nconsole.log(extractNumbers('Y2024')); // -> [2024]\nconsole.log(extractNumbers('Friday 31 May 2024')); // -> [31, 2024]\n\n/**\n * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\n */\n\n// Email\nconst emailRegex = /^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$/;\n\nconst validateEmail = (email) => {\n\treturn emailRegex.test(email);\n};\n\nvalidateEmail('LkqZC@example.com'); // -> true\n\n// Phone\nconst phoneRegex = /^3[0-9]{9}$/;\n\nconst validatePhone = (phone) => {\n\treturn phoneRegex.test(phone);\n};\n\nvalidatePhone('123456789'); // -> false\nvalidatePhone('3010101010'); // -> true\n\n// Url\nconst urlRegex = /^https?:\\/\\/[\\w\\-]+(\\.[\\w\\-]+)+[/#?]?.*$/;\n\nconst validateUrl = (url) => {\n\treturn urlRegex.test(url);\n};\n\nvalidateUrl('https://retosdeprogramacion.com/roadmap'); // -> true\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/javascript/duendeintemporal.js",
    "content": "// #16 EXPRSIONES REGULARES\n// bibliography reference\n// Professional JavaScript for web developers by Matt Frisbie [Frisbie, Matt] (z-lib.org)\n\n/* EJERCICIO:\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.*/\n\n// short for console.log()\nlet log = console.log;\n\nwindow.addEventListener('load', ()=>{\n    const body = document.querySelector('body');\n    const title = document.createElement('h1');\n    \n    body.style.setProperty('background', '#000');\n    body.style.setProperty('text-align', 'center');\n    \n    title.textContent = 'Retosparaprogramadores #16.';\n    title.style.setProperty('font-size', '3.5vmax');\n    title.style.setProperty('color', '#fff');\n    title.style.setProperty('line-height', '100vh');\n    \n    body.appendChild(title);\n    \n    setTimeout(()=>{\n    alert('Retosparaprogramadores #16. Please open the Browser Developer Tools.');\n    }, 2000);\n    log( 'Retosparaprogramadores #16'); \n});\n\n/*\nSome Flags  (also known as a modifiers)\n➤➤\ng—Indicates global mode, meaning the pattern will be applied to all of the string instead of\nstopping after the first match is found.\n➤➤\ni—Indicates case-insensitive mode, meaning the case of the pattern and the string are\nignored when determining matches.\n➤➤\nm—Indicates multiline mode, meaning the pattern will continue looking for matches after\nreaching the end of one line of text.\n➤➤\ny—Indicates sticky mode, meaning the pattern will only look at the string contents\nbeginning at lastIndex.\n➤➤\nu—Indicates Unicode mode is enabled.\n*/\n\n\n/*\nAs with regular expressions in other languages, all metacharacters must be escaped when used as part\nof the pattern. The metacharacters are as follows:\n( [ { \\ ^ $ | ) ] } ? * + .\n*/\n\n/*\nEach instance of RegExp has the following properties that allow you to get information about\nthe pattern:\n➤➤\nglobal—A Boolean\nvalue indicating whether the g flag has been set.\n➤➤\nignoreCase—A Boolean value indicating whether the i flag has been set.\n➤➤\nunicode—A Boolean value indicating whether the u flag has been set.\n➤➤\nsticky—A Boolean value indicating whether the y flag has been set.\n➤➤\nlastIndex—An integer indicating the character position where the next match will be\nattempted in the source string. This value always begins as 0.\n➤➤\nmultiline—A Boolean value indicating whether the m flag has been set.\n➤➤\nsource—The string source of the regular expression. This is always returned as if specified\nin literal form (without opening and closing slashes) rather than a string pattern as passed\ninto the constructor.\n➤➤\nflags—The string flags of the regular expression. This is always returned as if specified in\nliteral form (without opening and closing slashes) rather than a string pattern as passed into\nthe constructor.\n*/\n\n\n// Define a pattern and flags\nconst pattern0 = 'abc';\nconst flags = 'gi'; // Global and case-insensitive\n\n// Create a regular expression using the RegExp constructor\nconst regex = new RegExp(pattern0, flags);\n\nlog(regex); // /abc/gi\n\nlet text = \"time: 08:07:06\";\nlet pattern1 = /(time(:)?)? ?([01][0-9]|2[0-3])([:/-])([0-5][0-9])\\4([0-5][0-9])/;\n\n/*\n**Explanation of the regular expression:**\n- **(time(:)?)**: Optionally matches the word \"time\" followed by an optional colon (:).\n- **?**: Matches an optional space.\n- **([01][0-9]|2[0-3])**: Matches the hour, allowing values from 00 to 23.\n  - **[01][0-9]**: Matches hours from 00 to 19.\n  - **|**: \"Or\" operator.\n  - **2[0-3]**: Matches hours from 20 to 23.\n- **([:/-])**: Matches one of the characters :, /, or - and captures it for later use.\n- **([0-5][0-9])**: Matches the minutes (00 to 59).\n- **\\4**: References the fourth captured group, which is the separator (it must be the same as used between the hour and the minutes).\n- **([0-5][0-9])**: Matches the seconds (00 to 59).\n*/\n\nlet matches1 = pattern1.exec(text);\n\nif(matches1){\n    log(matches1.index); // 0\n    log(matches1.input); // time: 08:07:06\n    log(matches1[0]); // time: 08:07:06\n    log(matches1[1]); // time:\n    log(matches1[2]); // :\n}\n\nlet pattern = /[0-9]/g;\nlet matches = pattern.exec(text);\nif(matches) log(matches) // ['0', index: 6, input: 'time: 08:07:06', groups: undefined]\n\nlet matches3 = text.match(pattern);\nif(matches3) log(matches3) // ['0', '8', '0', '7', '0', '6']\n\n//Note: that match() return all concidence when using global flat g\n\nif(matches3){\n    log(matches3.index); // undefined\n    log(matches3.input); // undefined\n    log(matches3[0]); // 0\n    log(matches3[1]); // 8\n    log(matches3[2]); // 0\n}\n\nlet pattern2 = /\\d/g\nlet matches2 = pattern2.exec(text);\nif(matches2) log(matches2) // ['0', index: 6, input: 'time: 08:07:06', groups: undefined]\n\nlet matches4 = text.match(pattern2);\nif(matches4) log(matches4) // ['0', '8', '0', '7', '0', '6']\n\n/*\nexec: Returns the first match and can be used in a loop to find all matches.\n\nmatch: Returns an array with all matches in a more direct and straightforward way.\n*/\n\n//Extra Dificulty Exercise:\n\nconst validateTlf = (num)=>{\n    if (!/^\\d{11}$/.test(num)) {\n        console.log(\"Invalid telephone number. Must be a numeric value and have 11 digits.\");\n        return false; \n    }    \n    return true;\n}\n\nconst ValidateEmail = (email)=>{\n    const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$/;\n    if(!emailRegex.test(email)){\n        console.log(\"Invalid emnail adress\");\n        return false;\n    }\n    return true;\n}\n\nconst validateURL = (url)=>{\n    const urlRegex = /^(https?:\\/\\/)?([a-zA-Z0-9.-]+)(:[0-9]{1,5})?(\\/[^\\s]*)?$/;\n    if(!urlRegex.test(url) || (!url.startsWith('http://') && !url.startsWith('https://'))){\n        console.log(\"Invalid URL\");\n        return false;\n    }\n    return true;\n}\n\nlet num1 = 1562737848, num2 = 34587452387, email1 = 'kamsutraniko@proton.me', email2 = 'kat@hotgirl.net', url1 = 'http://palnetaneurodiverso.org', url2 = 'https://moebius.org', url3 = 'something.com', url4 = 'gato';\n\nlog(validateTlf(num1)); // Invalid telephone number. Must be a numeric value and have 11 digits. false\nlog(`Is a valid tlf: ${validateTlf(num2)}`) // Is a valid tlf: true\nlog(`Is a valid tlf: ${ValidateEmail(email1)}`); // Is a valid tlf: true\nlog(`Is a valid email: ${ValidateEmail(email2)}`); // Is a valid email: true\nlog(`Is a valid URL: ${validateURL(url1)}`); // Is a valid URL: true\nlog(`Is a valid URL: ${validateURL(url2)}`); // Is a valid URL: true\nlog(`Is a valid URL: ${validateURL(url3)}`); // Invalid URL Is a valid URL: false\nlog(`Is a valid URL: ${validateURL(url4)}`);  // Invalid URL Is a valid URL: false\n\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/javascript/emedevelopa.js",
    "content": "/*EJERCICIO:\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.*/\n\nconst texto = \"Este es un texto de prueba que contiene todos estos números: 32, 45, 3, 25, 67 y además estos otros: 67, 8, 6, 14.\";\nconst numRegex = /\\d+/g;\nconst resultado = texto.match(numRegex);\nconsole.log(resultado);\n\n//EXTRA\n/*Crea 3 expresiones regulares (a tu criterio) capaces de:\n* - Validar un email.\n* - Validar un número de teléfono.\n* - Validar una url.*/\n\nfunction mail (email) {\n    const regex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n    return regex.test(email);\n  }\n  \n  console.log(mail(\"email@email.com\"));\n\n  function phone(number) {\n    const regex = /^\\d{9}$/;\n    return regex.test(number.toString());\n  }\n  \n  console.log(phone(611234321));\n\n  function url (url) {\n    const regex = /^(ftp|http|https):\\/\\/[^ \"]+$/;\n    return regex.test(url)\n  }\n  console.log(url(\"https://retosdeprogramacion.com/roadmap/\"));\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/javascript/eugeniasoria.js",
    "content": "/*\r\n * EJERCICIO:\r\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\r\n * creando una que sea capaz de encontrar y extraer todos los números\r\n * de un texto.\r\n *\r\n * DIFICULTAD EXTRA (opcional):\r\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\r\n * - Validar un email.\r\n * - Validar un número de teléfono.\r\n * - Validar una url.\r\n */\r\n\r\nfunction extraerNumerosDeTexto(texto) {\r\n  let result = '';\r\n  result = texto.match(/\\d/g);\r\n  return result;\r\n}\r\n\r\nlet miTexto = 'Este texto 1 puede tener algu3nos numeros 0 en el medio99';\r\nconsole.log(miTexto);\r\nlet numeros = extraerNumerosDeTexto(miTexto);\r\nconsole.log(\"Numeros encontrados:\", numeros.join(', '));\r\n\r\n\r\nfunction emailEsValido(email) {\r\n   const expRegEmail = new RegExp(/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*$/);\r\n  let evaluado = expRegEmail.exec(email);  \r\n  return evaluado === null ? false : true;  \r\n}\r\n\r\nlet email ='miemail123%valido@gmail.com';\r\nlet emailNoValido = 'culTTmail@@quenoPuedeser.com.com@'\r\n\r\nconsole.log(`El email ${email} es válido? : ${emailEsValido(email)}`);\r\nconsole.log(`El email ${emailNoValido} es válido? : ${emailEsValido(emailNoValido)}`);\r\n\r\n\r\nfunction telefonoEsValido(numeroTelefono) {\r\n  const expRegEmail = new RegExp(/^\\+[0-9]+[\\s0-9]*$/);\r\n  let evaluado = expRegEmail.exec(numeroTelefono);  \r\n  return evaluado === null ? false : true;  \r\n}\r\n\r\nlet telefono ='+598 85 69856325';\r\nlet telefonoNoValido = '- 852 A45892'\r\n\r\nconsole.log(`El telefono ${telefono} es válido? : ${telefonoEsValido(telefono)}`);\r\nconsole.log(`El telefono ${telefonoNoValido} es válido? : ${telefonoEsValido(telefonoNoValido)}`);\r\n\r\n\r\n\r\nfunction urlEsValida(url) {\r\n  const expRegEmail = new RegExp(/^[a-zA-Z0-9-_.~:\\/]*$/);\r\n  let evaluado = expRegEmail.exec(url);  \r\n  return evaluado === null ? false : true;  \r\n}\r\n\r\nlet url ='https://miviejayquerida.url.com/subcarpeta/contenido.com.uy';\r\nlet urlNoValida = 'xyh((((65555%%%%%'\r\n\r\nconsole.log(`La url ${url} es válida? : ${urlEsValida(url)}`);\r\nconsole.log(`La url ${urlNoValida} es válida? : ${urlEsValida(urlNoValida)}`);"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/javascript/eulogioep.js",
    "content": "// Ejercicio de Expresiones Regulares en JavaScript\n\n// Texto de ejemplo para probar todas las expresiones regulares\nconst textoEjemplo = `Hola, tengo 25 años y mi número de teléfono es 123-456-789. \nTambién puedes contactarme al +34 611 222 333 o por email a usuario@dominio.com. \nVisita mi página web en https://www.ejemplo.com para más información. \nHay 42 razones para usar expresiones regulares y 100 formas de aplicarlas.`;\n\n/**\n * 1. Función para encontrar y extraer todos los números de un texto\n * Utiliza la expresión regular \\b\\d+\\b que significa:\n * \\b  - límite de palabra\n * \\d+ - uno o más dígitos\n * \\b  - otro límite de palabra\n */\nfunction extraerNumeros(texto) {\n    const patron = /\\b\\d+\\b/g;\n    const numerosEncontrados = texto.match(patron);\n    \n    console.log('1. Números encontrados:');\n    numerosEncontrados.forEach(numero => console.log(numero));\n}\n\n/**\n * 2. Función para validar un email\n * Utiliza una expresión regular que verifica:\n * ^             - inicio de la cadena\n * [\\w.-]+       - uno o más caracteres de palabra, puntos o guiones\n * @             - símbolo @\n * [\\w-]+        - uno o más caracteres de palabra o guiones\n * \\.            - un punto literal\n * [\\w-]+        - dominio de nivel superior\n * (\\.[a-zA-Z]{2,})?$ - opcional: punto seguido de 2 o más letras, fin de cadena\n */\nfunction validarEmail(email) {\n    const patronEmail = /^[\\w.-]+@[\\w-]+\\.[\\w-]+(\\.[a-zA-Z]{2,})?$/;\n    return patronEmail.test(email);\n}\n\n/**\n * 3. Función para validar un número de teléfono\n * Acepta formatos:\n * - 123-456-789\n * - +34 611 222 333\n */\nfunction validarTelefono(telefono) {\n    const patronTelefono = /^(\\+\\d{1,3}\\s?)?(\\d{3}[-\\s]?){2}\\d{3}$/;\n    return patronTelefono.test(telefono);\n}\n\n/**\n * 4. Función para validar una URL\n * Acepta URLs que:\n * - Comienzan con http:// o https://\n * - Pueden tener www. (opcional)\n * - Tienen un dominio y una extensión válida\n */\nfunction validarURL(url) {\n    const patronURL = /^(https?:\\/\\/)(www\\.)?[\\w-]+(\\.[a-zA-Z]{2,})+$/;\n    return patronURL.test(url);\n}\n\n// Pruebas\nconsole.log('\\n=== PRUEBAS DE EXPRESIONES REGULARES ===');\n\n// 1. Extraer números\nextraerNumeros(textoEjemplo);\n\n// 2. Validar emails\nconsole.log('\\n2. Validación de emails:');\nconst emails = ['usuario@dominio.com', 'email_invalido.com', 'test@test.co.uk'];\nemails.forEach(email => {\n    console.log(`${email} es válido:`, validarEmail(email));\n});\n\n// 3. Validar números de teléfono\nconsole.log('\\n3. Validación de números de teléfono:');\nconst telefonos = ['123-456-789', '+34 611 222 333', '1234', '999-999-999'];\ntelefonos.forEach(telefono => {\n    console.log(`${telefono} es válido:`, validarTelefono(telefono));\n});\n\n// 4. Validar URLs\nconsole.log('\\n4. Validación de URLs:');\nconst urls = ['https://www.ejemplo.com', 'http://ejemplo', 'https://dominio.es'];\nurls.forEach(url => {\n    console.log(`${url} es válida:`, validarURL(url));\n});"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/javascript/garos01.js",
    "content": "// Texto de ejemplo\nvar texto =\n  \"Este es un texto con algunos números como 123 y 4567, pero también tiene palabras.\";\n\n// Expresión regular para encontrar números\nvar regex = /\\d+/g;\n\n// Extraer números del texto\nvar numeros = texto.match(regex);\n\n// Mostrar los números encontrados\nconsole.log(\"Números encontrados:\", numeros);\n\n// Ejercicio extra\n\n// Función para validar un email\nfunction validarEmail(email) {\n  var regexEmail = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n  return regexEmail.test(email);\n}\n\n// Función para validar un número de teléfono\nfunction validarTelefono(telefono) {\n  var regexTelefono = /^\\d{10}$/;\n  return regexTelefono.test(telefono);\n}\n\n// Función para validar una URL\nfunction validarURL(url) {\n  var regexURL = /^(https?:\\/\\/)?([\\w-]+\\.)*[\\w-]+(\\/[\\w-./?%&=]*)?$/;\n  return regexURL.test(url);\n}\n\n// Ejemplos\nvar email = \"ejemplo@dominio.com\";\nconsole.log(\"¿Email válido?\", validarEmail(email));\n\nvar telefono = \"1234567890\";\nconsole.log(\"¿Teléfono válido?\", validarTelefono(telefono));\n\nvar url = \"https://www.ejemplo.com\";\nconsole.log(\"¿URL válida?\", validarURL(url));\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/javascript/hectorio23.js",
    "content": "// Author: Héctor Adán \n// GitHub: https://github.com/hectorio23\n\"use strict\";\n\n\n// Zona de REGEX Patterns\nconst emailRegex = /\\w+@[a-z]+\\.[a-z]{3}$/g;\nconst phoneNumberRegex = /^(\\+\\d{2,3})\\s(\\d{3})\\s(\\d{3})\\s(\\d{2})\\s(\\d{2})/g;\nconst urlRegex = /^https?:\\/\\/([a-zA-Z0-9]*\\.)?[a-zA-Z0-9]*\\.([a-zA-Z]{3})(\\.[a-zA-Z]{2,3})?\\/?/;\n\n// texto al cual se le quitaran los numeros apra hacerlo\n// legible\nlet texto_legible = \"E5n e6l si5g7ui8e956nte tex8to s9e 0t4ien4e que3 extr3aer to3dos lo0s nume3ro0s pa2ra q4ue s8e7a l9e0gi9b0le\"\n\n//////////////////////////\n////// EJERCICIO 1 ///////\n//////////////////////////\n\nconsole.log(\"EJERCICIO\");\nconsole.log(`Cadena Original: ${ texto_legible }`)\nconsole.log(`Cadena aplicando la REGEX: ${ texto_legible.replace(/[0-9]+/g, \"\") }`)\n\nconsole.log(\"\\n********* EJERCICIO EXTRA **********\");\nconsole.log(\"********* EMAIL CHECKER **********\");\nconsole.log(`[ hectorino2789@gmail.com ] es un email? ${ emailRegex.test(\"hectorino2789@gmail.com\") }`);\nconsole.log(`[ quesobadas@outlook.es ] es un email? ${ emailRegex.test(\"quesobadas@outlook.es\") }`);\nconsole.log(`[ nocorresponde a unema%il@gmaildjfj.completo ] es un email? ${ emailRegex.test(\"nocorresponde a unema%il@gmaildjfj.completo\") }`);\n\nconsole.log(\"\\n********* PHONE NUMBER CHECKER **********\");\nconsole.log(`[ +52 449-369-52-34 ] es un número de teléfono? ${ phoneNumberRegex.test(\"+52 449-369-52-34\") }`);\nconsole.log(`[ +52 449 369 52 34 ] es un número de teléfono? ${ phoneNumberRegex.test(\"+52 449 369 52 34\") }`);\nconsole.log(`[ 449 369 52 34 ] es un número de teléfono? ${ phoneNumberRegex.test(\"449 369 52 34\") }`);\n\nconsole.log(\"\\n********* URL CHECKER **********\");\nconsole.log(`[ https://github.com/hectorio23 ] es una URL? ${ urlRegex.test(\"https://github.com/hectorio23\") }`);\nconsole.log(`[ outlook:///github.com\\hectorio23 ] es una URL? ${ urlRegex.test(\"outlook:///github.com\\hectorio23\") }`);\nconsole.log(`[ 127.0.0.1:89/path/otherpath ] es una URL? ${ urlRegex.test(\"127.0.0.1:89/path/otherpath\") }`);\nconsole.log(`[ https://apple.com ] es una URL? ${ urlRegex.test(\"https://apple.com\") }`);\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n_______________________________________\n#16 EXPRESIONES REGULARES\n---------------------------------------\n * EJERCICIO:\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\n*/\n// ________________________________________________________\n\nfunction toNumbers(text) {\n    const numberPattern = /\\d+/g;\n    return text.match(numberPattern) || [];\n}\n\nconst string = \"abcdsfs1s(*&#}2. a3// 45sdf67\";\nconst listNumbers = toNumbers(string);\nconsole.log(listNumbers); // ['1', '2', '3', '45', '67']\n\n// ________________________________________________________\n// DIFICULTAD EXTRA\n\nfunction isEmail(text) {\n    const pattern = /^[\\w.%+-]+@[\\w.-]+\\.[a-zA-Z]{2,}$/;\n    return pattern.test(text);\n}\n\nfunction isPhoneNumber(text) {\n    const pattern = /^(\\d{3}-\\d{3}-\\d{4}|\\d{10})$/;\n    return pattern.test(text);\n}\n\nfunction isUrl(text) {\n    const pattern = /^(https?:\\/\\/)?(www\\.)?([a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,}(\\/\\S*)?$/;\n    return pattern.test(text);\n}\n\n// Pruebas\nconsole.log(\"\\nisEmail\");\nconsole.log(isEmail(\"ejm@dmn.com\"));        // true\nconsole.log(isEmail(\"e_jm-2+b@dmn.co.hn\")); // true\nconsole.log(isEmail(\"ejm@dmn.com_\"));       // false\nconsole.log(isEmail(\"ejm@dmn\"));            // false\n\nconsole.log(\"\\nisPhoneNumber\");\nconsole.log(isPhoneNumber(\"123-456-7890\")); // true\nconsole.log(isPhoneNumber(\"1234567890\"));   // true\nconsole.log(isPhoneNumber(\"123456-7890\"));  // false\nconsole.log(isPhoneNumber(\"uno234567890\")); // false\n\nconsole.log(\"\\nisUrl\");\nconsole.log(isUrl(\"http://www.ejm.com\"));   // true\nconsole.log(isUrl(\"google.com\"));           // true\nconsole.log(isUrl(\"ejm.com/a/b/c\"));        // true\nconsole.log(isUrl(\"https://.ejm.com\"));     // false\nconsole.log(isUrl(\"https://.ejm.com/a b\")); // false\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/javascript/miguelex.js",
    "content": "function regExpr(cadena) {\n    let patron = /-?\\d+(\\.\\d+)?/g;\n    let numeros = cadena.match(patron);\n\n    console.log(\"Números encontrados:\");\n    numeros.forEach(numero => console.log(numero));\n    console.log();\n}\n\nlet texto = \"Este es un texto con números como 123, 45.6, -7 y 1000.\";\nconsole.log(\"Vamos a analizar el siguiente texto:\");\nconsole.log(\"'\" + texto + \"'\\n\");\nregExpr(texto);\n\ntexto = \"123Erase una vez un número 1234567890 y otro 0987654321. Y para terminar456\";\nconsole.log(\"Vamos a analizar el siguiente texto:\");\nconsole.log(\"'\" + texto + \"'\\n\");\nregExpr(texto);\n\nfunction emailValidation(email) {\n    let patron = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}$/;\n    if (patron.test(email)) {\n        console.log(\"El email \" + email + \" es válido.\");\n    } else {\n        console.log(\"El email \" + email + \" no es válido.\");\n    }\n}\n\nfunction phoneValidation(phone) {\n    let patron = /^\\+?(\\d{2,3})?[-. ]?\\d{9}$/;\n    if (patron.test(phone)) {\n        console.log(\"El teléfono \" + phone + \" es válido.\");\n    } else {\n        console.log(\"El teléfono \" + phone + \" no es válido.\");\n    }\n}\n\nfunction urlValidation(url) {\n    let patron = /^(http|https):\\/\\/[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}/;\n    if (patron.test(url)) {\n        console.log(\"La URL \" + url + \" es válida.\");\n    } else {\n        console.log(\"La URL \" + url + \" no es válida.\");\n    }\n}\n\nemailValidation(\"correo@correo.com\");\nemailValidation(\"correo@correo\");\n\nphoneValidation(\"+34 123456789\");\nphoneValidation(\"123456789\");\n\nurlValidation(\"http://www.google.com\");\nurlValidation(\"www.google.com\");\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/javascript/monicavaquerano.js",
    "content": "// # 16 EXPRESIONES REGULARES\n// # Monica Vaquerano\n// # https://monicavaquerano.dev\n\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\n */\n\n// Regular Expresions\n\n// Search Method\nlet text = \"hola, mundo!\";\n\n// with a String\nlet x = text.search(\"mundo\");\nconsole.log(x);\n\n// with a Regular Expression \nx = text.search(/mundo/i);\nconsole.log(x);\n\nx ? console.log(\"It's a match\") : console.log(\"Not a match\");\n\n// Replace Method\ntext = \"Visit Berlin!\";\n\n// with a String\nx = text.replace(\"Berlin\", \"Stuttgart\");\nconsole.log(x);\n\n// with a Regular Expression\nx = text.replace(/Berlin/i, \"Stuttgart\");\nconsole.log(x);\n\n// test() Method\nlet pattern = /e/;\nx = pattern.test(\"The best things in life are free!\");\nx ? console.log(\"El patrón existe en la string\") : console.log(\"El patrón NO existe en la string\")\n\n// exec() Method\nconst obj = /e/.exec(\"The best things in life are free!\");\nconsole.log(obj)\nconsole.log(`Found ${obj[0]} in position ${obj.index} in the text: ${obj.input}`)\n\n// toString() Method\npattern = new RegExp(\"Hello World\", \"g\");\ntext = pattern.toString();\nconsole.log(text)\n\n// match() Method\nconst findDigits = (txt) => {\n    let pattern = /\\d+/g;\n    let digits = txt.match(pattern);\n    return digits;\n}\n\nconsole.log(findDigits(\"The r4in in 5p4in\"))\n\n// Regular Expression Modifiers: Modifiers can be used to perform case-insensitive more global searches:\n// Modifier\tDescription\n// i        Perform case-insensitive matching\t\n// g        Perform a global match (find all)\t\n// m        Perform multiline matching\t\n// d        Perform start and end matching (New in ES2022)\n\n// Extra\n\n// E-Mail\nconst emailCheck = (email) => {\n    let pattern = /^[\\w.+-]+@[\\w.+-]+\\.[a-zA-Z]+$/g;\n    let check = pattern.test(email);\n    return check;\n}\nconsole.log(\"example@example.com es un email válido? =>\", emailCheck(\"example@example.com\")) // true\nconsole.log(\"Ex.4-mpl3@exampl3.co es un email válido? =>\", emailCheck(\"Ex.4-mpl3@exampl3.co\")) // true\nconsole.log(\"exampleexample.com es un email válido? =>\", emailCheck(\"exampleexample.com\")) // false\nconsole.log(\"example!@example.c0m es un email válido? =>\", emailCheck(\"example@example.c0m\")) // false\n\n// # Número de teléfono\nfunction telephoneCheck(str) {\n    let regex = /^(1\\s?)?(\\(\\d{3}\\)|\\d{3})([\\-\\s])?(\\d{3})([\\-\\s])?(\\d{4})$/;\n    let phoneCheck = regex.test(str)\n    return phoneCheck;\n}\n\nconsole.log(\"555-555-5555 es un número válido? =>\", telephoneCheck(\"555-555-5555\")); // true\nconsole.log(\"1 (555) 555-5555 es un número válido? =>\", telephoneCheck(\"1 (555) 555-5555\")); // true\nconsole.log(\"5555555555 es un número válido? =>\", telephoneCheck(\"5555555555\")) // true\nconsole.log(\"(555)555-5555 es un número válido? =>\", telephoneCheck(\"(555)555-5555\")) // true\nconsole.log(\"5555555 es un número válido? =>\", telephoneCheck(\"5555555\")) // false\nconsole.log(\"123**&!!asdf# es un número válido? =>\", telephoneCheck(\"123**&!!asdf#\")) // false\nconsole.log(\"11 555-555-5555 es un número válido? =>\", telephoneCheck(\"11 555-555-5555\")) // false\nconsole.log(\"1 555)555-5555 es un número válido? =>\", telephoneCheck(\"1 555)555-5555\")) // false\nconsole.log(\"(6054756961) es un número válido? =>\", telephoneCheck(\"(6054756961)\")) // false\nconsole.log(\"27576227382 es un número válido? =>\", telephoneCheck(\"27576227382\")) // false\nconsole.log(\"(275)76227382 es un número válido? =>\", telephoneCheck(\"(275)76227382\")) //false\n\n// # URL\nconst urlCheck = (url) => {\n    let pattern = /(https:\\/\\/www\\.|http:\\/\\/www\\.|https:\\/\\/|http:\\/\\/)?[a-zA-Z]{2,}(\\.[a-zA-Z]{2,})(\\.[a-zA-Z]{2,})?\\/[a-zA-Z0-9]{2,}|((https:\\/\\/www\\.|http:\\/\\/www\\.|https:\\/\\/|http:\\/\\/)?[a-zA-Z]{2,}(\\.[a-zA-Z]{2,})(\\.[a-zA-Z]{2,})?)|(https:\\/\\/www\\.|http:\\/\\/www\\.|https:\\/\\/|http:\\/\\/)?[a-zA-Z0-9]{2,}\\.[a-zA-Z0-9]{2,}\\.[a-zA-Z0-9]{2,}(\\.[a-zA-Z0-9]{2,})?/g;\n    let urlCheck = pattern.test(url);\n    return urlCheck;\n}\n\nconsole.log(\"https://google.com/ es un url válido? =>\", urlCheck(\"https://google.com/\")) // true\nconsole.log(\"http://google.com es un url válido? =>\", urlCheck(\"http://google.com\")) // true\nconsole.log(\"https://www.google.com es un url válido? =>\", urlCheck(\"https://www.google.com\")) // true\nconsole.log(\"www.google.com es un url válido? =>\", urlCheck(\"www.google.com\")) // true\nconsole.log(\"google.com es un url válido? =>\", urlCheck(\"google.com\")) // true\nconsole.log(\"google.c es un url válido? =>\", urlCheck(\"google.c\")) // false\nconsole.log(\"goo/gle.c es un url válido? =>\", urlCheck(\"goo/gle.c\")) // false\n\n//     pattern = r\"^(http[s]?://)?(www.)?[\\w]+\\.[\\w]{2,}[/]?$\""
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/javascript/nlarrea.js",
    "content": "/*\n * EJERCICIO:\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\n */\n\nconst text = `\nLorem ipsum dolor1 sit amet, consectetur adipiscing elit. Nullam ac mi in\nipsum ultricies 2 varius. Nullam euismod, justo nec fermentum ultricies, nunc\nnisl tempus purus, 3 sed dictum 563 nulla odio nec purus. Nullam nec purus\nconsectetur, consectetur justo. 10 Nullam nec purus consectetur, consectetur.\n`\n\nconst numbersPattern = /[\\d]{1,}/g;\nconst numbers = text.match(numbersPattern);\nconsole.log(numbers);\n// ['1', '2', '3', '563', '10']\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\n */\n\n\nfunction printTest(pattern, text) {\n    console.log(text + ':', text.match(pattern)?.length > 0);\n}\n\n\nconsole.log('\\nTesting emails:');\nconst emailPattern = /^[\\w]{1,}[\\w\\d\\._]{4,}\\@[\\w]{2,}\\.[\\w]{2,3}$/g;\nprintTest(emailPattern, 'an_email@gmail.com');  // true\nprintTest(emailPattern, '1234@email.com');  // false\nprintTest(emailPattern, 'an_email1234');  // false\nprintTest(emailPattern, 'an2_email4@gmail.com');  // true\nprintTest(emailPattern, 'another.2024@gmail');  // false\nprintTest(emailPattern, 'another.2024@gmail.');  // false\nprintTest(emailPattern, 'another.2024@gmail.com');  // true\n\nconsole.log('\\nTesting phone numbers:');\nconst phonePattern = /^\\+?\\d{3,}$/g;\nprintTest(phonePattern, '123456789');  // true\nprintTest(phonePattern, '+34123456789');  // true\nprintTest(phonePattern, 'abcdefghi');  // false\n\nconsole.log('\\nTesting URLs:');\nconst urlPattern = /^https?:\\/\\/(w{3}\\.)?[\\w\\d\\.\\-\\?]+\\.[\\w]{2,}\\/?$/g\nprintTest(urlPattern, 'https://github.com/');  // true\nprintTest(urlPattern, 'https://www.twitch.tv/');  // true"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/javascript/parababire.js",
    "content": "const string = 'ferrocarril';\nconst regex = /roca/;\nconst resultado = regex.test(string);\nconst ocurrencia = string.match(regex)\nconst someText = 'El siguiente número primo es el 11, por lo que tachamos todos los múltiplos de 11, que son el 22, 33, 44, 55, 66, 77, 88, y el 99.';\nconst matchNum = /\\d{2,}/g;\n\nconsole.log(resultado);\nconsole.log(ocurrencia[0]);\nconsole.log(someText.match(matchNum));\n\n//Extra\n\nconst mail = 'angelenarvaezm@gmail.com';\nconst phoneNum = '02812769886';\nconst url = 'www.frecodecamp.com'\n\n/* Validación de email */\nconst regexMail = /^([a-z\\d\\.-]+)@([a-z\\d-]+)\\.([a-z]{2,8})(\\.[a-z]{2,8})?$/;\nconsole.log(regexMail.test(mail));\n\n/* Validación número de teléfono */\nconst regexPhone = /^0\\d{10}$/;\nconsole.log(regexPhone.test(phoneNum));\n\n/* Validación url */\nconst regexUrl = /^w{3}\\.[a-z_\\.?]+\\.(com|org)$/;\nconsole.log(regexUrl.test(url));"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/javascript/pedamoci.js",
    "content": "let txt = 'En la excavación, el equipo encontró una cápsula del tiempo, sellada hacía exactamente 87 años. La tapa, de un metal grisáceo, tenía grabado el número 1938 en una caligrafía pulcra. Dentro, había tres objetos principales. El primero era un diario con 432 páginas, detallando una vida en la ciudad durante la Gran Depresión. La segunda pieza era una moneda de 25 centavos de dólar, y la tercera, la más intrigante, era una partitura musical con solo siete notas repetidas en un patrón rítmico. Se estimó que la temperatura interior se había mantenido constante a 18 grados Celsius. Tras un estudio preliminar, se anunció que casi 9 de cada 10 hallazgos de ese tipo son falsificaciones, pero este era 100% auténtico. El valor histórico de los 3 objetos era incalculable.'\n\nlet regexNumeros = /\\d+/g\nconsole.log(txt.match(regexNumeros))\n\n// --------------------------------------------------------- DIFICULTAD EXTRA ---------------------------------------------------------\n\nlet regexMail = /^[^\\W]+@[^\\W]+\\.[a-zA-Z]{2,63}(\\.[a-zA-Z]{2,63})?$/\n// ^ ---> iinicia el string\n// [^\\W]+ ---> tiene que haber mas de un caracter y no puede ser uno especial (. @ % ...)\n// @ ---> tiene que tener un arroba\n// [^\\W]+\n// \\. ---> tiene que tener un punto\n// [a-zA-Z]{2,63} ---> tiene que tener caracteres tipo letras, al menos tienen que ser 2 y como maximo 63\n// (\\.[a-zA-Z]{2,63})? ---> puede tener un punto y puede tener caracteres tipo letras, al menos tienen que ser 2 y como maximo 63\n// $ ---> finaliza el string\n\nlet regexNumerosDeTelefonos = /^(\\d+)?\\s?\\d{8}$/\n// ^ \n// (\\d{1,4})? ---> puede haber uno o hasta cuatro digitos \n// \\s? ---> puede haber un espacio \n// \\d{8} ---> tiene que tener ocho digitos\n// $\n\nlet regexUrl = /^https:\\/{2}[^\\s]{2,}\\.[a-zA-Z]{2,63}$/\n// ^\n// https: ---> tiene que tener 'https:' \n// \\/{2} ---> tiene que tener '//' \n// [^\\s]{2,} ---> tiene que tener al menos 2 caracteres y no puede tener espacios\n// \\.\n// [a-zA-Z]{2,63}\n// $\n\nconsole.log((regexMail).test('asdasdasd@sada.com'))\nconsole.log((regexNumerosDeTelefonos).test('159753624852'))\nconsole.log((regexUrl).test('https://google.com'))"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/javascript/victor-Casta.js",
    "content": "/*\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.\n*/\n\nconst getNumbersRegex = /\\d/g;\nconsole.log(\"JavaScript1995\".match(getNumbersRegex).join(\"\"))\n\n/*\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\n*/\n\n// Email Regex\nconst emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/\nconst phoneRegex= /^\\+?[1-9]\\d{1,14}$/\nconst urlRegex = /^(https?:\\/\\/)?([\\da-z\\.-]+)\\.([a-z\\.]{2,6})([\\/\\w \\.-]*)*\\/?$/"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/javascript/wapastorv.js",
    "content": "/*\n * EJERCICIO:\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.\n * \n * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\n */\n \n\n// Expresiones regulares en JavaScript\n/*\nUna expresión regular es una secuencia de caracteres que forma un patrón de búsqueda. Este patrón se puede usar para:\n\n    * Buscar texto dentro de una cadena.\n    * Validar si una cadena cumple con un formato específico (por ejemplo, un correo electrónico o un número de teléfono).\n    * Reemplazar partes de una cadena.\n    *Extraer información específica de un texto.\n*/\n// Creación de una expresión regular en JavaScript\n/* \n    1. Usando el constructor RegExp\n    Ejemplo:\n    var regex = new RegExp('pattern');\n    var regex = new RegExp('pattern', 'flags');\n    var regex = new RegExp(/pattern/);\n    var regex = new RegExp(/pattern/, 'flags');\n*/\n/* \n    2. Usando la notación literal\n    Ejemplo:\n    var regex = /pattern/;\n    var regex = /pattern/flags;\n\n    Donde:\n    - pattern es el patrón de búsqueda.\n    - flags son los modificadores que se pueden aplicar a la expresión regular.\n\n    Las barras diagonales (/) se utilizan para delimitar la expresión regular, y los modificadores se colocan al final de la expresión regular.\n    Pero las barras invertidas (\\) se utilizan para escapar caracteres especiales dentro de la expresión regular.\n\n    Ejemplo:\n    var regex = /pattern\\./;\n    var regex = /pattern\\./i;\n*/\n\n// Métodos de las expresiones regulares en JavaScript\n/*\n    - test(): Comprueba si una cadena cumple con el patrón de la expresión regular.\n    - exec(): Devuelve la primera coincidencia de la expresión regular en una cadena.\n    - match(): Devuelve un array con todas las coincidencias de la expresión regular en una cadena.\n    - matchAll(): Devuelve un iterador con todas las coincidencias de la expresión regular en una cadena.\n    - search(): Devuelve la posición de la primera coincidencia de la expresión regular en una cadena.\n    - replace(): Reemplaza las coincidencias de la expresión regular en una cadena.\n    - replaceAll(): Reemplaza todas las coincidencias de la expresión regular en una cadena.\n    - split(): Divide una cadena en un array de subcadenas utilizando la expresión regular como separador.\n    \n*/\n// las banderas o flags que se pueden utilizar en una expresión regular en JavaScript son:\n/*\n    - i: Realiza una búsqueda sin distinguir entre mayúsculas y minúsculas.\n    - g: Realiza una búsqueda global en toda la cadena.\n    - m: Realiza una búsqueda multilinea.\n    - u: Habilita el modo Unicode.\n    - y: Realiza una búsqueda pegajosa (sticky).\n    - s: Habilita el modo dotall.\n    - x: Ignora los espacios en blanco y permite comentarios en la expresión regular.\n    - U: Deshabilita el modo Unicode.\n    - A: Realiza una búsqueda en la cadena completa.\n    - D: Realiza una búsqueda en la cadena completa, pero excluye el último carácter.\n    - J: Realiza una búsqueda en la cadena completa, incluyendo el último carácter.\n*/\n// Caracteres especiales en las expresiones regulares en JavaScript\n\n/*\n    - \\d: Representa cualquier dígito (0-9).\n    - \\D: Representa cualquier carácter que no sea un dígito.\n    - \\w: Representa cualquier carácter alfanumérico (incluyendo el guion bajo _).\n    - \\W: Representa cualquier carácter que no sea alfanumérico.\n    - \\s: Representa cualquier carácter de espacio en blanco.\n    - \\S: Representa cualquier carácter que no sea un espacio en blanco.\n    - \\b: Representa un límite de palabra.\n    - \\B: Representa un límite que no sea de palabra.\n    - \\n: Representa un salto de línea.\n    - \\t: Representa un tabulador.\n    - \\r: Representa un retorno de carro.\n    - \\f: Representa un salto de página.\n    - \\v: Representa un tabulador vertical.\n    - \\0: Representa el carácter nulo.\n    - \\xhh: Representa el carácter ASCII especificado por los dos dígitos hexadecimales hh.\n    - \\uhhhh: Representa el carácter Unicode especificado por los cuatro dígitos hexadecimales hhhh.\n    - \\cX: Representa un control ASCII, donde X es una letra en mayúscula.\n    - \\: Escapa un carácter especial.\n    - .: Representa cualquier carácter, excepto un salto de línea.\n    - ^: Representa el inicio de una cadena.\n    - $: Representa el final de una cadena.\n    - *: Representa cero o más repeticiones del elemento anterior.\n    - +: Representa una o más repeticiones del elemento anterior.\n    - ?: Representa cero o una repetición del elemento anterior.\n    - {n}: Representa exactamente n repeticiones del elemento anterior.\n    - {n,}: Representa n o más repeticiones del elemento anterior.\n    - {n,m}: Representa entre n y m repeticiones del elemento anterior.\n    - (x): Representa un grupo de captura.\n    - [xyz]: Representa un conjunto de caracteres.\n    - ` `: Representa un conjunto de caracteres que no están en el rango especificado.\n*/\n\n// Ejercicio: Encontrar y extraer todos los números de un texto en JavaScript\n// Crear una expresión regular que encuentre y extraiga todos los números de un texto en JavaScript.\n\n// Ejemplo:\nvar text = 'En el año 2021, el precio del producto es $25.50 y el descuento es del 10%.';\nvar regex = /\\d+/g; // Expresión regular para encontrar números\nvar numbers = text.match(regex);\nconsole.log(numbers);// Output: ['2021', '25', '50', '10']\n\n// Explicación:\n// - La expresión regular /\\d+/g busca uno o más dígitos en el texto.\n// - El modificador g se utiliza para realizar una búsqueda global en todo el texto.\n// - El método match() devuelve un array con todas las coincidencias encontradas.\n\n// Ejercicio extra: Validar un email, un número de teléfono y una URL en JavaScript\n// Crear expresiones regulares que validen un email, un número de teléfono y una URL en JavaScript.\n\n// Ejemplo:\nvar emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$/;\nvar phoneRegex = /^\\+\\d{1,3}\\s?\\(\\d{1,3}\\)\\s?\\d{3}-\\d{4}$/;\nvar urlRegex = /^(https?:\\/\\/)?(www\\.)?[a-zA-Z0-9-]+\\.[a-zA-Z]{2,}\\/?$/;\n\nvar email = 'peito_qwq12.12@gmail.com';\nvar phone = '+57 (32) 353-7890';\nvar url = 'https://www.example.com';\n\nconsole.log(emailRegex.test(email)); // Output: true    \nconsole.log(phoneRegex.test(phone)); // Output: true\nconsole.log(urlRegex.test(url)); // Output: true\n\n// Explicación:\n// - La expresión regular /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$/ valida un email.\n// - La expresión regular /^\\+\\d{1,3}\\s?\\(\\d{1,3}\\)\\s?\\d{3}-\\d{4}$/ valida un número de teléfono.\n// - La expresión regular /^(https?:\\/\\/)?(www\\.)?[a-zA-Z0-9-]+\\.[a-zA-Z]{2,}\\/?$/ valida una URL.\n\n\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/kotlin/blackriper.kt",
    "content": "/*\r\n\r\nA una expresión regular es una cadena de caracteres que es utilizada para describir o encontrar\r\npatrones dentro de otros strings, en base a las delimitadores y ciertas reglas de sintaxis.\r\n\r\nEn kotlin las regex se pueden crear de tres  formas:\r\n\r\nRegex(\"a[bc]+d?\") // apartir de la clase Regex\r\n\r\n\"a[bc]+d?\".toRegex() // apartir de una cadena\r\n\r\nRegex.fromLiteral(\"a[bc]+d?\") // apartir de un metodo estatico de la clase Regex\r\n\r\npara crear testear y probar expresiones regulares visita el siguiente link:\r\nhttps://regexr.com/\r\n\r\n*/\r\n\r\nfun workingWithRegex() {\r\n    val regex = Regex(\"[0-9]\")\r\n\r\n    val text=\"\"\"\r\n        El manga Hokuto no ken cuenta con 245 capítulos, publicados en la revista semanal Shōnen Jump,\r\n        desde el número 41 de 1983 hasta el número 35 de 1988. Luego fue recopilado en 27 volúmenes\r\n        por Shueisha. Se está publicando en 14 Kanzenban por Shōgakukan y una Master Edition de 27 volúmenes \r\n        por Coamix.\r\n    \"\"\".trimIndent()\r\n\r\n    val result = regex.findAll(text)\r\n    result.forEach {\r\n        println(it.value)\r\n    }\r\n}\r\n\r\n\r\nfun validateUrl(url: String) =\r\n      Regex(\"^(https?)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]\").matches(url)\r\n\r\n/* explicacion del pattern\r\n^(https?):// : debe comenzar con http o https seguido de dos puntos y dos sla\r\n[-a-zA-Z0-9+&@#/%?=~_|!:,.;]: puede contener caracteres alfanuméricos, guiones bajos, signos mas, ampersands o guiones y puede ir separado por puntos\r\n*[-a-zA-Z0-9+&@#/%=~_|]: puede contener caracteres alfanuméricos, guiones bajos, signos mas puede terminar con un slash y seguido de algun caracter especial\r\n*/\r\n\r\n\r\nfun validateEmail(email: String) =\r\n    Regex(\"^[a-zA-Z0-9_+&*-]+(?:\\\\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\\\\.)+[a-zA-Z]{2,7}$\").matches(email)\r\n\r\n/* explicacion del pattern\r\n  ^[a-zA-Z0-9_+&*-] : debe comenzar uno o más caracteres alfanuméricos, guiones bajos, signos más, ampersands o guiones\r\n  +(?:\\.[a-zA-Z0-9_+&*-]+): puede contener caracteres alfanuméricos, guiones bajos, signos mas, ampersands o guiones y puede ir separado por puntos\r\n  *@(?:[a-zA-Z0-9-]+\\.): debe contener un arroba  puede contener numeros o letras y debe terminar en un punto\r\n  +[a-zA-Z]{2,7}$: debe terminar en un string de entre 2 y 7 caracteres\r\n */\r\n\r\n\r\n\r\n\r\nfun validatePhone(phone: String) =\r\n    Regex(\"^[+]*[(]{0,1}[0-9]{1,4}[)]{0,1}[-\\\\s\\\\./0-9]*\\$\").matches(phone)\r\n\r\n/* explicacion del pattern\r\n ^[+]* : puede inicar con un signo mas\r\n [(]{0,1} : puede inicar con un parentesis\r\n [0-9]{1,4} : puede contener digitos de 0 a 9 en un rango de 1 a 4 digitos\r\n [-\\s\\./0-9]* : puede contener guiones o puntos entre cada  numero\r\n */\r\n\r\nfun main() {\r\n  workingWithRegex()\r\n  validateUrl(\"https://www.google.com\").let {\r\n     println(it)\r\n   }\r\n   validateEmail(\"w0Ezy@example.com\").let {\r\n     println(it)\r\n   }\r\n\r\n   validatePhone(\"411-153-1223\").let {\r\n     println(it)\r\n   }\r\n}"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/kotlin/eulogioep.kt",
    "content": "import kotlin.text.Regex\n\nfun main() {\n    // Función para extraer números de un texto\n    fun extractNumbers(text: String): List<String> {\n        val numberRegex = Regex(\"\\\\d+\")\n        return numberRegex.findAll(text).map { it.value }.toList()\n    }\n\n    // Ejemplo de uso\n    val sampleText = \"Tengo 25 años y mi número de teléfono es 123-456-7890. Mi código postal es 12345.\"\n    val numbers = extractNumbers(sampleText)\n    println(\"Números encontrados: $numbers\")\n\n    // DIFICULTAD EXTRA\n\n    // 1. Validar un email\n    fun isValidEmail(email: String): Boolean {\n        val emailRegex = Regex(\"^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\\\.[A-Z|a-z]{2,}\\$\")\n        return emailRegex.matches(email)\n    }\n\n    // 2. Validar un número de teléfono (formato: XXX-XXX-XXXX)\n    fun isValidPhoneNumber(phoneNumber: String): Boolean {\n        val phoneRegex = Regex(\"^\\\\d{3}-\\\\d{3}-\\\\d{4}\\$\")\n        return phoneRegex.matches(phoneNumber)\n    }\n\n    // 3. Validar una URL\n    fun isValidUrl(url: String): Boolean {\n        val urlRegex = Regex(\"^(https?://)?([\\\\da-z.-]+)\\\\.([a-z.]{2,6})([/\\\\w .-]*)*/?$\")\n        return urlRegex.matches(url)\n    }\n\n    // Ejemplos de uso de las funciones de validación\n    println(\"¿Es válido el email 'usuario@dominio.com'? ${isValidEmail(\"usuario@dominio.com\")}\")\n    println(\"¿Es válido el número de teléfono '123-456-7890'? ${isValidPhoneNumber(\"123-456-7890\")}\")\n    println(\"¿Es válida la URL 'https://www.ejemplo.com'? ${isValidUrl(\"https://www.ejemplo.com\")}\")\n}"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/kotlin/miguelex.kt",
    "content": "import java.util.regex.Pattern\n\nfun regExpr(cadena: String) {\n    val patron = \"-?\\\\d+(\\\\.\\\\d+)?\"\n    val regex = Pattern.compile(patron)\n    val numeros = regex.matcher(cadena)\n\n    println(\"Números encontrados:\")\n    while (numeros.find()) {\n        println(numeros.group())\n    }\n    println()\n}\n\nfun main() {\n    var texto = \"Este es un texto con números como 123, 45.6, -7 y 1000.\"\n    println(\"Vamos a analizar el siguiente texto:\")\n    println(\"'$texto'\\n\")\n    regExpr(texto)\n\n    texto = \"123Erase una vez un número 1234567890 y otro 0987654321. Y para terminar456\"\n    println(\"Vamos a analizar el siguiente texto:\")\n    println(\"'$texto'\\n\")\n    regExpr(texto)\n\n    emailValidation(\"correo@correo.com\")\n    emailValidation(\"correo@correo\")\n\n    phoneValidation(\"+34 123456789\")\n    phoneValidation(\"123456789\")\n\n    urlValidation(\"http://www.google.com\")\n    urlValidation(\"www.google.com\")\n}\n\nfun emailValidation(email: String) {\n    val patron = \"^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,4}$\"\n    if (Pattern.matches(patron, email)) {\n        println(\"El email $email es válido.\")\n    } else {\n        println(\"El email $email no es válido.\")\n    }\n}\n\nfun phoneValidation(phone: String) {\n    val patron = \"^\\\\+?(\\\\d{2,3})?[-. ]?\\\\d{9}$\"\n    if (Pattern.matches(patron, phone)) {\n        println(\"El teléfono $phone es válido.\")\n    } else {\n        println(\"El teléfono $phone no es válido.\")\n    }\n}\n\nfun urlValidation(url: String) {\n    val patron = \"^(http|https):\\\\/\\\\/[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,4}\"\n    if (Pattern.matches(patron, url)) {\n        println(\"La URL $url es válida.\")\n    } else {\n        println(\"La URL $url no es válida.\")\n    }\n}\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/kotlin/rikmij.kt",
    "content": "fun main() {\n    val textoEjemplo = \"2 y dos son 4, cuatro y dos son 6, seis y dos son 8 y ocho 16\"\n    val findNums = Regex(\"\\\\d+\").findAll(textoEjemplo)\n    for (num in findNums) {\n        val first = num.range.first\n        val last = num.range.last\n        println(\"${num.value} -> ($first,$last)\")\n    }\n\n    println(\"${\"\\n\" + \"~\".repeat(7)} EJERCICIO EXTRA ${\"~\".repeat(7)}\")\n    //Validar email\n    val email = Regex(\"\\\\w+\\\\S*@\\\\w+.\\\\w+\")\n    val textEmail = \"Buenas tardes, el correo electrónico es correo.deprueba_hola@corporacion.es. Muchas gracias\"\n    val findEmail = email.find(textEmail)\n    println(findEmail?.value)\n\n    //Validar teléfono\n    val telf = Regex(\"[+]\\\\d+\\\\s\\\\d+\")\n    val textTelf = \"Puede llamar al número +34 6874521035200 para más información\"\n    val findTelf = telf.find(textTelf)\n    println(findTelf?.value)\n\n    //Validar URL\n    val url = Regex(\"https?://\\\\w+.\\\\w+.\\\\w+[.\\\\w+]*\")\n    val textUrl = \"Puede visitar nuestra web: https://www.unaweb_deprueba101.com.wordpress.es para más información\"\n    val findUrl = url.find(textUrl)\n    println(findUrl?.value)\n}\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/ocaml/luishendrix92.ml",
    "content": "open Re\nopen Printf\n\n(*****************************************************************************)\n(*                                                                           *)\n(*                       Regular Expressions (RegExp)                        *)\n(*                                                                           *)\n(*  Regular expressions are a way to represent a pattern of text. It's       *)\n(*  specified as a sequence of characters (with rules, and operators) that   *)\n(*  represent a full or partial match in a block of text. It's made out of   *)\n(*  2 components: a) The pattern itself delimited in [/] slashes; and b)     *)\n(*  a list of flags that change the way the pattern matching behaves.        *)\n(*    The 3 most common {e RegExp} flags are:                                *)\n(*                                                                           *)\n(*  1. [i]: Case {e insensitive} matching, meaning you don't have to         *)\n(*     manually specify the casing (lower/uppercase) of the charactes.       *)\n(*     It will match both lower and uppercase regardless of what you say.    *)\n(*  2. [m]: {e Multiline} matching, makes the [^] (start) and [$] (end)      *)\n(*     markers span the entire string rather than just the first line.       *)\n(*  3. [g]: For {e global} matching, which makes it so that a pattern can    *)\n(*     be executed multiple times in a string. Useful to extract all the     *)\n(*     substrings that match a given pattern, or during search and replace.  *)\n(*                                                                           *)\n(*  There are many RegExp standards, {i Perl} being one of the first and     *)\n(*  most used in Linux. OCaml's standard library comes with a subset of      *)\n(*  special characters in the form of the [Str] module, but if a developer   *)\n(*  needs actual support for the full experience, all it takes is            *)\n(*  installing the [re] package with [opam] which comes with the [Re] high   *)\n(*  level module, with [Re.Pcre], [Re.Perl], [Re.Glob], [Re.Posix], and      *)\n(*  [Re.Emacs] submodules to compile specific \"dialects\" of RegExp.          *)\n(*                                                                           *)\n(*****************************************************************************)\n\nlet text_block =\n  \"The company reported a profit increase of 10 million dollars in the last \\\n   quarter, surpassing expectations. However, they also experienced a decrease \\\n   in revenue of -3.2 million dollars due to unexpected market fluctuations. \\\n   The CEO announced a new investment plan worth 30.5 million dollars aimed at \\\n   expanding operations globally. Additionally, the company recorded a growth \\\n   rate of +8.3% in the previous year.\"\n;;\n\n(** [extract_numbers] returns a list of substrings that match a numeric pattern\n    explained as: a [+] or [-] symbol (optional), and one or more digits that\n    may or may not be followed by another set of digits preceded by a dot. *)\nlet extract_numbers = matches @@ Pcre.regexp {|[+-]?\\d+(?:\\.\\d+)?|}\n\nlet _ =\n  print_endline \"Extracting all numbers in the following text:\";\n  print_endline text_block;\n  print_endline \"---------------------------------------------\";\n  extract_numbers text_block |> String.concat \", \" |> print_endline;\n  print_endline \"---------------------------------------------\";\n  print_newline ()\n;;\n\n(**************************************************************)\n(*                                                            *)\n(*                 Dificultad Extra (Opcional)                *)\n(*                                                            *)\n(*  Crea 3 expresiones regulares (a tu criterio) capaces de:  *)\n(*                                                            *)\n(*  - Validar un email.                                       *)\n(*  - Validar un número de teléfono.                          *)\n(*  - Validar una URL.                                        *)\n(*                                                            *)\n(**************************************************************)\n\nmodule Validator : sig\n  val email : string -> bool\n  (** [email s] is [true] if [s] is a valid email address. *)\n\n  val phone_number : string -> bool\n  (** [phone_number s] is [true] if [s] is a valid phone number. *)\n\n  val url : string -> bool\n  (** [url s] is [true] if [s] is a valid URL (only http and https). *)\nend = struct\n  let email_re =\n    let name = {|[-a-z0-9_.]+|} in\n    let domain = {|[-a-z0-9]+|} in\n    let tld = {|\\.[a-z]{2,63}|} in\n    Pcre.regexp ~flags:[ `CASELESS ] @@ \"^\" ^ name ^ \"@\" ^ domain ^ tld ^ \"$\"\n  ;;\n\n  let phone_re =\n    let sep = {|[\\s.-]?|} in\n    let country = {|(?:\\+\\d{1,2}\\s)?|} in\n    let area = {|(?:\\(\\d{3}\\)|\\d{3})|} in\n    let prefix = {|\\d{3}|} in\n    let line = {|\\d{4}|} in\n    Pcre.regexp @@ \"^\" ^ country ^ area ^ sep ^ prefix ^ sep ^ line ^ \"$\"\n  ;;\n\n  let url_re =\n    let protocol = {|(?:https?://)?|} in\n    let subdomain = {|(?:[-0-9a-z]+\\.)?|} in\n    let domain = {|[-0-9a-z]+|} in\n    let tld = {|(?:\\.[a-z]{2,63}){1,2}|} in\n    let path = {|(?:/[-\\w]*)*|} in\n    let qparam = {|[-\\w~.]+=[-\\w,.%]*|} in\n    let query = sprintf {|(?:\\?%s(?:&%s)*)?|} qparam qparam in\n    Pcre.regexp ~flags:[ `CASELESS ]\n    @@ \"^\"\n    ^ protocol\n    ^ subdomain\n    ^ domain\n    ^ tld\n    ^ path\n    ^ query\n    ^ \"$\"\n  ;;\n\n  let email = execp email_re\n  let phone_number = execp phone_re\n  let url = execp url_re\nend\n\nlet _ =\n  let open Validator in\n  let phone_numbers =\n    [ \"664 730 9673\"\n    ; \"+52 (345)-080-1214\"\n    ; \"055-216-0945\"\n    ; \"(686).233.7676\"\n    ; \"(45)-35-17887\"\n    ]\n  in\n  let emails =\n    [ \"hello@kozmicblog.com\"\n    ; \"new.year@old-wave.com\"\n    ; \"just-AN-email@foo.bar\"\n    ; \"invalid@tld-domain.x\"\n    ]\n  in\n  let urls =\n    [ \"http://kozmicblog.com\"\n    ; \"https://regex101.com/\"\n    ; \"google.com.mx\"\n    ; \"your-site.net/route?param=val&param2=val2\"\n    ; \"http://]what[..is.this/\"\n    ]\n  in\n  let str_of_bool b = if b then \"VALID ✅\" else \"INVALID ❌\" in\n  List.iter\n    (fun s ->\n      printf \"Phone # Validation | %s | %s\\n\" s (phone_number s |> str_of_bool))\n    phone_numbers;\n  List.iter\n    (fun s -> printf \"Email Validation | %s | %s\\n\" s (email s |> str_of_bool))\n    emails;\n  List.iter\n    (fun s -> printf \"URL Validation | %s | %s\\n\" s (url s |> str_of_bool))\n    urls\n;;\n\n(* Output of running the program [dune exec reto16]:\n\n   Extracting all numbers in the following text:\n   The company reported a profit increase of 10 million dollars in the last quarter, surpassing expectations. However, they also experienced a decrease in revenue of -3.2 million dollars due to unexpected market fluctuations. The CEO announced a new investment plan worth 30.5 million dollars aimed at expanding operations globally. Additionally, the company recorded a growth rate of +8.3% in the previous year.\n   ---------------------------------------------\n   10, -3.2, 30.5, +8.3\n   ---------------------------------------------\n\n   Phone # Validation | 664 730 9673 | VALID ✅\n   Phone # Validation | +52 (345)-080-1214 | VALID ✅\n   Phone # Validation | 055-216-0945 | VALID ✅\n   Phone # Validation | (686).233.7676 | VALID ✅\n   Phone # Validation | (45)-35-17887 | INVALID ❌\n   Email Validation | hello@kozmicblog.com | VALID ✅\n   Email Validation | new.year@old-wave.com | VALID ✅\n   Email Validation | just-AN-email@foo.bar | VALID ✅\n   Email Validation | invalid@tld-domain.x | INVALID ❌\n   URL Validation | http://kozmicblog.com | VALID ✅\n   URL Validation | https://regex101.com/ | VALID ✅\n   URL Validation | google.com.mx | VALID ✅\n   URL Validation | your-site.net/route?param=val&param2=val2 | VALID ✅\n   URL Validation | http://]what[..is.this/ | INVALID ❌\n*)\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/php/eulogioep.php",
    "content": "<?php\n/**\n * Ejercicio de Expresiones Regulares en PHP\n * \n * Este script demuestra el uso de expresiones regulares en PHP para:\n * 1. Extraer números de un texto\n * 2. Validar direcciones de email\n * 3. Validar números de teléfono\n * 4. Validar URLs\n */\n\n// Texto de ejemplo para probar las expresiones regulares\n$textoEjemplo = \"Hola, tengo 25 años y mi número es 123-456-789. \" .\n                \"Puedes contactarme al +34 611 222 333 o por email a usuario@dominio.com. \" .\n                \"Visita mi web https://www.ejemplo.com para más información. \" .\n                \"Hay 42 razones para usar expresiones regulares y 100 formas de aplicarlas.\";\n\n/**\n * 1. Función para encontrar y extraer todos los números de un texto\n * \n * La expresión regular \\b\\d+\\b significa:\n * \\b  - límite de palabra\n * \\d+ - uno o más dígitos\n * \\b  - otro límite de palabra\n * \n * @param string $texto El texto del que extraer los números\n * @return array Array con todos los números encontrados\n */\nfunction extraerNumeros($texto) {\n    $patron = '/\\b\\d+\\b/';\n    preg_match_all($patron, $texto, $coincidencias);\n    return $coincidencias[0];\n}\n\n/**\n * 2. Función para validar un email\n * \n * La expresión regular verifica:\n * ^ - inicio de la cadena\n * [\\w\\.-]+ - uno o más caracteres de palabra, puntos o guiones\n * @ - símbolo @\n * [\\w\\.-]+ - uno o más caracteres de palabra, puntos o guiones\n * \\. - un punto literal\n * [\\w\\.-]+ - dominio de nivel superior\n * $ - fin de la cadena\n * \n * @param string $email El email a validar\n * @return bool true si el email es válido, false si no\n */\nfunction validarEmail($email) {\n    $patron = '/^[\\w\\.-]+@[\\w\\.-]+\\.\\w+$/';\n    return preg_match($patron, $email) === 1;\n}\n\n/**\n * 3. Función para validar un número de teléfono\n * \n * Acepta formatos:\n * - 123-456-789\n * - +34 611 222 333\n * \n * @param string $telefono El número de teléfono a validar\n * @return bool true si el teléfono es válido, false si no\n */\nfunction validarTelefono($telefono) {\n    $patron = '/^(\\+\\d{1,3}\\s?)?(\\d{3}[-\\s]?){2}\\d{3}$/';\n    return preg_match($patron, $telefono) === 1;\n}\n\n/**\n * 4. Función para validar una URL\n * \n * Verifica URLs que:\n * - Comienzan con http:// o https://\n * - Pueden tener www. (opcional)\n * - Tienen un dominio y una extensión válida\n * \n * @param string $url La URL a validar\n * @return bool true si la URL es válida, false si no\n */\nfunction validarURL($url) {\n    $patron = '/^https?:\\/\\/(www\\.)?[\\w\\.-]+\\.\\w{2,}$/';\n    return preg_match($patron, $url) === 1;\n}\n\n// PRUEBAS\n\necho \"=== PRUEBAS DE EXPRESIONES REGULARES ===\\n\\n\";\n\n// 1. Extraer números\necho \"1. Números encontrados:\\n\";\n$numeros = extraerNumeros($textoEjemplo);\nforeach ($numeros as $numero) {\n    echo \"- $numero\\n\";\n}\n\n// 2. Validar emails\necho \"\\n2. Validación de emails:\\n\";\n$emails = ['usuario@dominio.com', 'email_invalido.com', 'test@test.co.uk'];\nforeach ($emails as $email) {\n    $esValido = validarEmail($email) ? 'válido' : 'inválido';\n    echo \"- $email es $esValido\\n\";\n}\n\n// 3. Validar números de teléfono\necho \"\\n3. Validación de números de teléfono:\\n\";\n$telefonos = ['123-456-789', '+34 611 222 333', '1234', '999-999-999'];\nforeach ($telefonos as $telefono) {\n    $esValido = validarTelefono($telefono) ? 'válido' : 'inválido';\n    echo \"- $telefono es $esValido\\n\";\n}\n\n// 4. Validar URLs\necho \"\\n4. Validación de URLs:\\n\";\n$urls = ['https://www.ejemplo.com', 'http://ejemplo', 'https://dominio.es'];\nforeach ($urls as $url) {\n    $esValido = validarURL($url) ? 'válida' : 'inválida';\n    echo \"- $url es $esValido\\n\";\n}\n\n?>"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/php/gabrielmoris.php",
    "content": "<?php\n/*\nEXERCISE:\nUsing your language, explore the concept of regular expressions,\ncreating one that is capable of finding and extracting all numbers\nfrom a text.\n*/\n\nfunction get_all_numbers($str)\n{\n    $pattern = '/\\d/';\n    $matches = [];\n    preg_match_all($pattern, $str, $matches);\n    return implode('', $matches[0]);\n}\n\necho get_all_numbers(\"Holaque2tal\") . \"\\n\"; // Output: 2\n\n\n/*\nEXTRA DIFFICULTY (optional):\nCreate 3 regular expressions (at your discretion) capable of:\nValidating an email.\nValidating a phone number.\nValidating a URL.\n*/\n\nfunction validate_email($email)\n{\n    $pattern = '/^[\\w\\.-]+@[\\w\\.-]+\\.\\w{2,}$/';\n    // [\\w\\.-]+ matches the part before and after @\n    // \\w{2,} matches the top-level domain (min 2 letters)\n    return preg_match($pattern, $email) > 0;\n}\n\nvar_dump(validate_email(\"cuchara\"));\nvar_dump(validate_email(\"cuch@ra.da\"));\n\nfunction validate_phone($number)\n{\n    $pattern = '/^(\\+?\\d{1,3}[\\s-]?)?\\(?\\d{3}\\)?[\\s-]?\\d{3}[\\s-]?\\d{4}$/';\n    // (\\+?\\d{1,3}[\\s-]?)? - Matches an optional country code.\n    // $$? - Matches an optional opening parenthesis.\n    // [\\s-]? - Matches an optional space or hyphen.\n    // \\d{3} - Matches exactly 3 digits (prefix).\n    // [\\s-]? - Matches an optional space or hyphen.\n    // \\d{4} - Matches exactly 4 digits (line number).\n    return preg_match($pattern, $number) > 0;\n}\n\nvar_dump(validate_phone(\"12\"));\nvar_dump(validate_phone(\"+41 4588748965\"));\n\nfunction validate_url($url)\n{\n    $pattern = '/^(https?:\\/\\/)?([\\da-z\\.-]+)\\.([a-z\\.]{2,6})([\\/\\w \\.-]*)*/';\n    // ([\\da-z\\.-]+) matches the subdomain or domain name. It allows any combination of digits (\\d), lowercase letters (a-z), periods (.), and hyphens (-).\n    // ([a-z\\.]{2,6}) matches the top-level domain (TLD) with a length between 2 and 6 characters, allowing letters and periods.\n    // ([\\/\\w \\.-]*)* matches the path, query string, and fragment identifier optionally. It allows any combination of forward slashes (/), word characters (\\w), spaces, periods, and hyphens.\n    return preg_match($pattern, $url) > 0;\n}\n\nvar_dump(validate_url(\"http://.com\"));\nvar_dump(validate_url(\"https://www.gabrielcmoris.com\"));\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/php/miguelex.php",
    "content": "<?php\n\n$texto = \"Este es un texto con números como 123, 45.6, -7 y 1000.\";\n\nfunction regExpr($cadena){\n    $patron = '/-?\\d+(\\.\\d+)?/';\n    preg_match_all($patron, $cadena, $numeros);\n\n    echo \"Números encontrados:\\n\";\n    foreach ($numeros[0] as $numero) {\n        echo $numero . \"\\n\";\n    }\n    echo \"\\n\\n\";\n}\n\necho \"Vamos a analizar el siguiente texto:\\n\";\necho \"'\".$texto.\"'\\n\\n\";\n\nregExpr($texto);\n\n$texto = \"123Erase una vez un número 1234567890 y otro 0987654321. Y para terminar456\";\necho \"Vamos a analizar el siguiente texto:\\n\";\necho \"'\".$texto.\"'\\n\\n\";\n\nregExpr($texto);\n\n// Extra\n\nfunction emailValidation($email){\n    $patron = '/^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}$/';\n    if(preg_match($patron, $email)){\n        echo \"El email \".$email.\" es válido.\\n\";\n    } else {\n        echo \"El email \".$email.\" no es válido.\\n\";\n    }\n}\n\nfunction phoneValidation ($phone){\n    $patron = '/^\\+?(\\d{2,3})?[-. ]?\\d{9}$/';\n    if(preg_match($patron, $phone)){\n        echo \"El teléfono \".$phone.\" es válido.\\n\";\n    } else {\n        echo \"El teléfono \".$phone.\" no es válido.\\n\";\n    }\n}\n\nfunction urlValidation ($url){\n    $patron = '/^(http|https):\\/\\/[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}/';\n    if(preg_match($patron, $url)){\n        echo \"La URL \".$url.\" es válida.\\n\";\n    } else {\n        echo \"La URL \".$url.\" no es válida.\\n\";\n    }\n}\n\n\nemailValidation(\"correo@correo.com\");\nemailValidation(\"correo@correo\");\n\nphoneValidation(\"+34 123456789\");\nphoneValidation(\"123456789\");\n\nurlValidation(\"http://www.google.com\");\nurlValidation(\"www.google.com\");\n\n\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/AChapeton.py",
    "content": "import re\n\nregexHasNumbers = \"[0-9]\"\n\ntext1 = 'Lorem Ipsum es simplemente el texto de relleno de las imprentas desde el año 1500'\ntext2 = 'Solo letras, sin nada de numeros'\ntext3 = '1234567890-abc'\n\nresultText1 = re.findall(regexHasNumbers, text1)\nresultText2 = re.findall(regexHasNumbers, text2)\nresultText3 = re.findall(regexHasNumbers, text3)\n\nprint('Numero en text1', resultText1)\nprint('Numero en text2', resultText2)\nprint('Numero en text3', resultText3)\n\n\n# DIFICULTAD EXTRA\n\n# Regex para correos\n\nregexEmail = '^[\\w\\-\\.]+@([\\w]+\\.)+[\\w]{2,4}$'\n\nemail1 = 'andres.chapeton0206@gmail.com'\nemail2 = 'andres@gmail'\n\nresultEmail1 = re.search(regexEmail, email1)\nresultEmail2 = re.search(regexEmail, email2)\n\nprint('Es email1 valido?', resultEmail1)\nprint('Es email2 valido?', resultEmail2)\n\n\n# Regex para telefonos (Con formato 0000-0000)\n\nregexPhone = \"([0-9]{4})-([0-9]{4})\"\n\nphone1 = '7777-9999'\nphone2 = '77-5555'\n\nresultPhone1 = re.search(regexPhone, phone1)\nresultPhone2 = re.search(regexPhone, phone2)\n\nprint('Es phone1 valido?', resultPhone1)\nprint('Es phone1 valido?', resultPhone2)\n\n\n# Regex para URL (Con formato https o http)\n\nregexURL = \"^https?:\\/\\/([a-zA-Z0-9]*\\.)?[a-zA-Z0-9]*\\.([a-zA-Z]{3})(\\.[a-zA-Z]{2,3})?\\/?$\"\n\nurl1 = 'https://www.moure.dev'\nurl2 = 'http://www.holamundo.dev'\nurl3 = 'www.google.com'\nurl4 = 'https://www.google'\nurl5 = 'w.google'\n\nresultUrl1 = re.search(regexURL, url1)\nresultUrl2 = re.search(regexURL, url2)\nresultUrl3 = re.search(regexURL, url3)\nresultUrl4 = re.search(regexURL, url4)\nresultUrl5 = re.search(regexURL, url5)\n\nprint('Es url1 valida?', resultUrl1)\nprint('Es url2 valida?', resultUrl2)\nprint('Es url3 valida?', resultUrl3)\nprint('Es url4 valida?', resultUrl4)\nprint('Es url5 valida?', resultUrl5)\n\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/Aldroide.py",
    "content": "import re\n\"\"\" \n    Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n    creando una que sea capaz de encontrar y extraer todos los números\n    de un texto.\n\"\"\"\n\nregex = r\"[0-9]+\"\ntext = \"Ejercicio del 15/04/2024\"\n\n\ndef find_number(text: str) -> list:\n    return re.findall(r\"\\d+\", text)\n\n\nprint(find_number(\"Ejercicio 16 del 15/04/2024\"))\n\n\n\"\"\"\n    Ejercicio Extra\n    Crea 3 expresiones regulares (a tu criterio) capaces de:\n        * Validar un email.\n        * Validar un número de teléfono.\n        * Validar una url.\n\"\"\"\n\n\ndef validar_email(text: str) -> bool:\n    return bool(re.match(r\"^[\\w.+-]+@[\\w]+\\.[a-zA-z]+\", text))\n\n\ndef validar_telefono(phone: str) -> bool:\n    return bool(re.match(r\"^\\+?[\\d\\s]{3,}$\", phone))\n\n\ndef validar_url(url: str) -> bool:\n    return bool(re.match(r\"^http[s]?://(www.)?[\\w]+\\.[a-zA-z]{2,}$\", url))\n\n\nprint(validar_email(\"Aldroide@gmail.com\"))\nprint(validar_telefono(\"+5394576298\"))\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/CaveroBrandon.py",
    "content": "\"\"\"EJERCICIO:\nUtilizando tu lenguaje, explora el concepto de expresiones regulares,\ncreando una que sea capaz de encontrar y extraer todos los números\nde un texto.\"\"\"\n\nimport re\n\n\ndef find_numbers_in_a_text(text: str):\n    numbers = re.findall(r'\\d+\\.?\\d*', text)\n    if numbers:\n        print(f'The number founded in the text are: {numbers}')\n        return\n    else:\n        print('There are no numbers in the text')\n        return\n\n\"\"\"DIFICULTAD EXTRA (opcional):\nCrea 3 expresiones regulares (a tu criterio) capaces de:\n- Validar un email.\n- Validar un número de teléfono.\n- Validar una url.\"\"\"\n\n\ndef is_email(email: str):\n    email_pattern = r'^[\\w\\._-]+@[\\w\\._-]+\\.\\w+$'\n    if re.match(pattern=email_pattern, string=email):\n        print(f'The email \"{email}\" is a valid email')\n    else:\n        print(f'The text \"{email}\" is not a valid email')\n\n\ndef is_phone_number(phone_number: str):\n    phone_number_pattern = r'^(\\(\\d{3}\\)|\\d{3})[\\s.-]?\\d{3}[\\s.-]?\\d{4}$'\n    if re.match(pattern=phone_number_pattern, string=phone_number):\n        print(f'The phone number \"{phone_number}\" is a valid phone number')\n    else:\n        print(f'The phone number \"{phone_number}\" is not a valid phone number')\n\n\ndef is_url(url: str):\n    url_pattern = r'^(https):\\/\\/([A-Za-z0-9\\-._~:/?#[\\]@!$&\\'()*+,;=%]+)$'\n    if re.match(pattern=url_pattern, string=url):\n        print(f'The url \"{url}\" is a valid url')\n    else:\n        print(f'The \"{url}\" is not a valid url')\n\n\nfind_numbers_in_a_text(input('Enter text to analyze (to find numbers): '))\nprint('********')\nis_email(input('Enter an email to validate: '))\nprint('********')\nis_phone_number(input('Enter a phone number (don\\'t include country code): '))\nprint('********')\nis_url(input('Enter an url: '))\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/CesarCarmona30.py",
    "content": "import re\n\ntext = input(\"Introduce un texto (incluye números): \")\nnumbers = re.findall(r\"\\d+\", text)\n\nprint(f\"Numeros del texto introducido: {numbers}\")\n\n'''\n  EXTRA\n'''\n\nemail = input(\"Introduce un email: \")\npattern = r'^[\\w\\.-]+@[\\w\\.-]+\\.[a-zA-Z]{2,}$'\n# Iteramos hasta que el usuario ingrese un email valido\nwhile not re.search(pattern, email):\n  email = input(\"Introduce un email válido (email@example.com): \")\nprint(f\"Email válido: {email}\")\n\n\n# number_phone = input(\"Introduce un número de teléfono\")\npattern = r'^(\\(\\+\\d{1,3}\\)\\s?)?(\\d{2}\\s?(-|\\s)?\\d{4}\\s?(-|\\s)?){2}\\d{2}$'\n# lista de posibles formatos teléfonicos con algunos incorrectos\nnumber_list = [\n  \"(+55) 5555555555\",\n  \"(+55) 55 5555 5555\",\n  \"(+55) 55 55 55 55 55\",\n  \"(+55) 55-5555-5555\",\n  \"6532ww732\"\n  \"(+55) 55-55-55-55-55\",\n  \"+55 5555555555\",\n  \"+55 55 5555 5555\",\n  \"+55 55 55 55 55 55\",\n  \"543654563\"\n  \"+55 55-5555-5555\",\n  \"+55 55-55-55-55-55\",\n  \"46525365426423642\"\n  \"5555555555\",\n  \"55 5555 5555\",\n  \"55-5555-5555\",\n  \"534264236426246432\"\n  \"55 55 55 55 55\",\n  \"55-55-55-55-55\",\n  \"53452grfsyrw\"\n]\n  # Iteramos hasta que el usuario ingrese un número válido\n  # while not re.search(pattern, number_phone):\n    # number_phone = input(\"Introduce un número de teléfono válido: (+55 5555555555)\")\n\n# Recorremos la lista para validar los formatos\nfor number_phone in number_list:\n  if not re.search(pattern, number_phone):\n    print(f'{number_phone} es válido')\n  else:\n    print(f'{number_phone} no válido')\n\npattern = r'^(https?://)?(www\\.)?([a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,}(/\\S*)?$'\n\nurls_list = [\n  \"https://www.ejemplo.com\",\n  \"http://ejemplo.com\",\n  \"https://subdominio.ejemplo.com\",\n  \"http://www.subdominio.ejemplo.com\",\n  \"https://ejemplo.com/ruta\",\n  \"http://ejemplo.com/ruta/ejemplo\",\n  \"https://www.ejemplo.com/ruta/ejemplo.html\",\n  \"http://ejemplo.com/ruta?parametro=valor\",\n  \"https://www.ejemplo.com/ruta?parametro1=valor1&parametro2=valor2\",\n  \"http://subdominio.ejemplo.com/ruta\",\n  \"https://ejemplo.com/ruta#seccion\",\n  \"http://www.ejemplo.com#seccion\",\n  \"https://www.ejemplo.com/ruta#seccion\",\n  \"http://subdominio.ejemplo.com/ruta#seccion\",\n  \"https://www.ejemplo.com/ruta/ejemplo.html?parametro=valor#seccion\",\n  \"http://ejemplo.com/ruta/ejemplo?parametro1=valor1&parametro2=valor2#seccion\",\n  \"https://subdominio.ejemplo.com/ruta/ejemplo.html?parametro=valor#seccion\"\n  \"www.ejemplo.com\",\n  \"ejemplo.com\",\n  \"ftp://ejemplo.com\",\n  \"http://ejemplo\",\n  \"http://ejemplo.com?\",\n  \"http://ejemplo.com#\",\n  \"http://ejemplo.com/ruta/\",\n  \"http://ejemplo.com//ruta\",\n  \"http://ejemplo.com/ruta//\",\n  \"http://ejemplo.com/?parametro=valor\",\n  \"http://ejemplo.com/#seccion\",\n  \"http://ejemplo.com/ruta//ejemplo.html\",\n  \"http://ejemplo.com//ruta/ejemplo\",\n  \"http://ejemplo.com/ruta/?parametro=valor\",\n  \"http://ejemplo.com/ruta#seccion/\"\n  \"http://ejemplo.com/ruta//ejemplo.html?parametro=valor\",\n  \"http://ejemplo.com/ruta/ejemplo?parametro1=valor1&parametro2=valor2#seccion/\",\n  \"http://subdominio ejemplo.com\",\n  \"http://ejemplo .com\",\n  \"http://.ejemplo.com\",\n  \"http://ejemplo..com\",\n  \"http://ejemplo.com:abc\",\n  \"http://ejemplo.com:80abc\",\n  \"http://ejemplo.com:80abc/ruta\",\n  \"http://ejemplo.com:80abc/ruta/ejemplo.html\",\n  \"http://ejemplo.com:80abc/ruta?parametro=valor\",\n  \"http://ejemplo.com:80abc/ruta#seccion\",\n  \"http://ejemplo.com:80abc/ruta/ejemplo.html?parametro=valor#seccion\",\n  \"https://chat.openai.com/c/8c6fa1c0-7590-4c21-be8c-ff8d48edbfa1\",\n  \"https://docs.python.org/es/3/library/re.html\",\n  \"https://www.youtube.com/watch?v=ehTuatSx5Wc\"\n]\n# url = input(\"Introduce una URL válida: \")\n\n# Validar la URL\nfor url in urls_list:\n  if re.match(pattern, url):\n      print(\"La URL es válida.\")\n  else:\n      print(\"La URL no es válida.\")\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/Chrisdev00.py",
    "content": "\"\"\"\n* EJERCICIO:\n* Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n* creando una que sea capaz de encontrar y extraer todos los números\n* de un texto.\n*\n* DIFICULTAD EXTRA (opcional):\n* Crea 3 expresiones regulares (a tu criterio) capaces de:\n* - Validar un email.\n* - Validar un número de teléfono.\n* - Validar una url.\n\"\"\"\n\nimport re\n\ndef find_numbers(text):\n\n    pattern_num = r\"-?\\d+\\.?\\d*\"\n    numbers_found = re.findall(pattern_num, text)\n    numbers_found = [float(num) for num in numbers_found]\n    return numbers_found\n\ntexto = \"Este es un texto de prueba con varios numeros: 123, 45.6, -0.3, 789. Es importante encontrarlos todos.\"\nnumeros = find_numbers(texto)\n\nprint(numeros)\n\n\n########## --------------------------- EXTRA ------------------------------  #####################\n\n\ndef validate_email(email: str):\n\n    pattern = r\"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$\"\n    if re.match(pattern, email):\n        return True\n    else:\n        return False    \nprint(validate_email(\"nombre.apellido123@dominio.com\"))\nprint(validate_email(\"correo.invalido@com\"))\n\n\ndef validate_phoneNumber(num):\n    \n    pattern_num = r'^(\\+\\d{1,3}\\s?)?[-\\s]?[0-9]{7,8}$'\n    if re.match(pattern_num, num):\n        return True\n    else:\n        return False    \nprint(validate_phoneNumber(\"+591 79338521\"))\n\n\ndef validar_url(url):\n    pattern_url = r\"^(https?://)?(www\\.)?[\\w\\.-]+\\.[a-zA-Z]{2,}(/\\S*)?$\"\n    if re.match(pattern_url, url):\n        return True\n    else:\n        return False    \nprint(validar_url(\"http://www.moure.dev\"))\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/Complex303.py",
    "content": "\"\"\"\nExpresiones reguales\n\"\"\"\n\n#Expresiones regulares (regex) son patrones de búsqueda que se usan para validar, buscar o reemplazar texto en cadenas. Se componen de caracteres normales y especiales.\n\n# Importa el módulo 're' que permite trabajar con expresiones regulares en Python\nimport re\n\n# Define una función llamada 'find_number' que recibe un parámetro 'text' de tipo string y devuelve una lista \ndef find_number(text: str) -> list:\n    # Utiliza 're.findall' para buscar todas las secuencias de uno o más dígitos (\\d+)\n    # en el texto recibido. Retorna una lista con todas las coincidencias encontradas.\n    return re.findall(r\"\\d+\", text) #tambien se puede usar r\"[0-9]+, text\n\n# Llama a la función 'find_number' con un texto de ejemplo y muestra en pantalla la lista de números encontrados\nprint(find_number(\"Este es el ejercicio 16 publicado 15/04/24\"))\n\n\"\"\" * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n\n\n * - Validar un email.\"\"\"\n\n\n# Retorna True si 'email' coincide con el patrón:\n    # - ^ \tIndica el inicio de la cadena.\n    # - Empieza con letras/números/_.+-\n    # - Sigue un @\n    # - Dominio con letras/números/_\n    # - Un punto\n    # - Y termina con al menos dos letras\n    # - $ Indica el final de la cadena.\ndef validate_email(email: str)-> bool:\n    return bool(re.match(r\"^[\\w+.-]+@[\\w]+\\.[a-zA-Z]{2,}$\", email))\n\n\nprint(validate_email(\"Complex-_+.@gmail.com\"))\n\n\n\"\"\" - Validar un número de teléfono.\"\"\"\n\n\ndef validate_phone(phone: str)-> bool:\n      return bool(re.match(r\"^(\\+1[\\s-])?[\\d\\s-]{3,12}$\", phone))\n\n# ^\\+1 → debe empezar con +1\n#\"?\" Hace que el elemento anterior sea opcional: Es decir, puede aparecer una vez o no aparecer.\n# [\\s-]? → espacio o guion opcional después de +1\n# [\\d\\s-]{3,12} → luego entre 3 y 12 caracteres que sean dígitos, espacios o guiones\n# $ → final de cadena\n\n\nprint(validate_phone(\"+1 809 019 1092\"))\n\n\n\n\n\n\"\"\"- Validar una url.\"\"\"\n\ndef validate_url(url: str)-> bool:\n    # Usa re.match para verificar si la URL cumple con el patrón.\n    # Si coincide, devuelve True, si no, False.\n    return bool(re.match(r\"^http[s]?://(www.)?[\\w]+\\.[a-zA-Z]{2,}$\", url))\n\n# ^\tInicio de la cadena\n# http[s]?://\tDebe empezar con http:// o https:// (s es opcional por [s]?)\n# (www.)?\tOpcionalmente permite www. justo después (el ? lo hace opcional)\n# [\\w]+\tUno o más caracteres alfanuméricos o guion bajo (\\w equivale a [a-zA-Z0-9_])\n# \\.\tUn punto literal .\n# [a-zA-Z]{2,}\tDos o más letras (la extensión, como com, net, io)\n# $\tFin de la cadena\n\n\n\nprint(validate_url(\"http://Complex01_.com\"))\n\n\n#pagina web para evaluar codigo de expresiones reguales: https://regex101.com/\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/DaniQB99.py",
    "content": "'''\nEJERCICIO:\nUtilizando tu lenguaje, explora el concepto de expresiones regulares,\ncreando una que sea capaz de encontrar y extraer todos los numeros de\nun texto.\n'''\n\nimport re\n\ndef find_numbers(text: str) -> list:\n    # return re.findall(r'[0-9]+', text)\n    return re.findall(r'\\d+', text)  # \\d es un alias para [0-9]\n\nprint(find_numbers(\"Hola, mi nombre es Daniel y nací el 26/07/1999\"))\n\n\n'''\nDIFICULTAD EXTRA (opcional):\nCrea 3 expresiones regulares (a tu criterio) capaces de:\n- Validar un email.\n- Validar un número de teléfono.\n- Validar una url.\n'''\n\nprint(\"\\n\\nDIFICULTAD EXTRA\\n\")\n\n# Email\ndef validate_email(email: str) -> bool:\n    pattern = r'^[\\w.+-]+@+[\\w]+\\.(?:com|net|es|ai|ia|mx|co|uy|org)$'\n    if re.match(pattern, email):\n        return email + \" es válido\"\n    return email + \" no es válido\"\n\n    # \\w es un alias para [a-zA-Z0-9_]\n    # \\d es un alias para [0-9] \n    # $ indica el final de la cadena\n    # + indica que se puede repetir 1 o más veces\n    # ^ indica que se debe empezar en la primera posición\n    # (?:com|net|es|ai|ia|mx|co|uy|org) es un grupo de caracteres que se puede repetir 0 o más veces\n    \nprint(validate_email(\"daniqb99@gmail.com\"))\nprint(validate_email(\"daniqb99@gmail.com.com\"))\n\n# Número de teléfono\ndef validate_phone(phone: str) -> bool:\n    pattern = r'^\\+34(6|7)[0-9]{8}$'\n    if re.match(pattern, phone):\n        return phone + \" es válido\"\n    return phone + \" no es válido\"\n\nprint(validate_phone(\"+34649116982\"))\nprint(validate_phone(\"+34649116982a\"))\n\n# URL\ndef validate_url(url: str) -> bool:\n    pattern = r'^http[s]?://(www.)?[\\w]+\\.(?:com|net|es|ai|ia|mx|co|uy|org)$'\n    if re.match(pattern, url):\n        return url + \" es válida\"\n    return url + \" no es válida\"\n\nprint(validate_url(\"https://www.google.es\"))\nprint(validate_url(\"https://google.es\"))\nprint(validate_url(\"https://google.es.com\"))"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/EmmanuelMMontesinos.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\n */\n\"\"\"\n# Ejercicio Base y Extra\n\nimport re\n\nclass Expresion:\n    def __init__(self) -> None:\n        self.expres_tlf = r'\\d{9}'\n        self.expres_email = r'\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Z|a-z]{2,}\\b'\n        self.expres_url = r'https?://(?:[-\\w.]|(?:%[\\da-fA-F]{2}))+[-\\w./?%&=]*'\n\n    def numeros(self,entrada):\n        resultado = re.findall(r'\\d+',entrada)\n        if resultado:\n            for numero in resultado:\n                print(f\"Estos son los números dentro de la entrada:\\n{numero}\\n\")\n        else:\n            print(f\"No se han encontrado números:\\n{entrada}\\n\")\n        \n    def telefono(self,entrada):\n        resultado = re.findall(self.expres_tlf,entrada)\n        if resultado:\n            for tlf in resultado:\n                print(f\"Número de telefono encontrado:\\n{tlf}\\n\")\n        else:\n            print(f\"No se han encontrado número de teléfono:\\n{entrada}\\n\")\n    \n    def email(self,entrada):\n        resultado = re.findall(self.expres_email,entrada)\n        if resultado:\n            for email in resultado:\n                print(f\"Email encontrado:\\n{email}\\n\")\n        else:\n            print(f\"No se han encontrado Email:\\n{entrada}\\n\")\n        \n    def url(self,entrada):\n        resultado = re.findall(self.expres_url,entrada)\n        if resultado:\n            for url in resultado:\n                print(f\"Url encontrada:\\n{url}\\n\")\n        else:\n            print(f\"No se han encontrado Url:\\n{entrada}\\n\")\n\ntexto_consultar = \"\"\"\nBienvenido a Matrix Infinity, la empresa líder en desarrollo de software. Si deseas contactarnos, nuestro número de teléfono principal es 913456789 y nuestro correo electrónico es contacto@matrixinfinity.com. Nuestra oficina principal se encuentra en la calle Tecnología 123, y nuestro código postal es 45678.\n\nPuedes visitar nuestro sitio web en https://www.matrixinfinity.com para más información sobre nuestros servicios. También puedes seguir nuestro blog en https://blog.matrixinfinity.com para las últimas actualizaciones y noticias. Si necesitas soporte, envía un mensaje a soporte@matrixinfinity.com.\n\nPara consultas comerciales, llama al 687654321 o envía un correo a ventas@matrixinfinity.com. No olvides revisar nuestra sección de preguntas frecuentes en https://faq.matrixinfinity.com.\n\nPara más información sobre nuestros productos y servicios, visita https://productos.matrixinfinity.com o llámanos al 902112648.\n\nRecuerda que nuestras oficinas están abiertas de lunes a viernes de 9 AM a 6 PM, y puedes contactarnos en horario de oficina al 672333444.\n\nGracias por tu interés en Matrix Infinity. ¡Esperamos trabajar contigo pronto!\n\n\"\"\"\n\n\nconsulta = Expresion()\nconsulta.numeros(texto_consultar)\nconsulta.telefono(texto_consultar)\nconsulta.email(texto_consultar)\nconsulta.url(texto_consultar)\n\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/FedeAirala.py",
    "content": "#  16 EXPRESIONES REGULARES\n\"\"\"\n\nEJERCICIO:\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.\n\n \"\"\"\n\nimport re\n\nprint (\"-\"*100)\ntext = \"Las 1000 y una noches según 30 lectores\"\nx_num = re.findall(\"[0-9]\",text)\nprint (text)\nprint (f\"Números encontrados en el texto: {x_num}\")\nprint (\"-\"*100)\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\n```\n\"\"\"\n\n# Ejercicio realizado considerando los siguientes formatos\n# email: string@string.sss\n# phone: +01 0123 012345\n# url: www.string.com o https://www.string.com o http://www.string.com\n\n#Patrones\n\nregexemail = r\"^[a-zA-Z0-9]*@[a-zA-Z0-9]*\\.[a-z]{3}$\"\nrephone = r\"^\\+\\d{2} \\d{4} \\d{6}$\"\nreurl = r\"^(https?://)?([a-z0-9]*\\.)?[a-z0-9]*\\.[a-z]{3}$\"\n\n# Funcón para validar los datos\n\ndef validate_data(email,phone,url):\n\n    if re.search(regexemail,email):\n        print (f\"{email}: email válido\")\n    else:\n        print (f\"{email}: email inválido\")\n\n    if re.search(rephone,phone):\n        print (f\"{phone}: número válido\")\n    else:\n        print (f\"{phone}: número inválido\")\n\n    if re.search(reurl,url):\n\n        print (f\"{url}: url válida\")\n    else:\n        print (f\"{url}: url inválida\")\n\n\n# Función para ingresar datos a validar\n\ndef main():\n\n    validate_data(\"pedroalonzo84@gmail.com\",\"+54 6324 695874\",\"www.pedro.com\")\n    validate_data(\"pedroalonzo84@gmail.com\",\"+3 6324 695874\",\"www.pedro\")\n    validate_data(\"pedroalonzo84gmail.com\",\"+32 6324 695874\",\"www.pedro.com\")\n    validate_data(\"pedroalonzo84@gmail.com\",\"+2 63254 695874\",\"https://www.pedro.com\")\n    validate_data(\"pedroalonzo84@gmail.com3\",\"+25 6354 695874\",\"http://www.pedro.com\")\n \nif __name__ == \"__main__\":\n    main()"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/Gallitofast.py",
    "content": "# * EJERCICIO:\n#  * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n#  * creando una que sea capaz de encontrar y extraer todos los números\n#  * de un texto.\n\nimport re\ntext=\" Y esa fue la noche mas linda del mundo aunque nos durara tan solo 1 segundo\"\nx_num=re.findall(\"[0,9]\",text)\nprint(text)\nprint(f\"Los numeros encontrados en el texto son: {x_num}\")\nprint(\"-\"*60)\n\n# * DIFICULTAD EXTRA (opcional):\n#  * Crea 3 expresiones regulares (a tu criterio) capaces de:\n#  * - Validar un email.\n#  * - Validar un número de teléfono.\n#  * - Validar una url.\nrecorreo=r\"^[a-zA-Z0-9]*@[a-zA-Z0-9]*\\.[a-z]{3}$\"\nretelefono= r\"^\\+\\d{2} \\d{4} \\d{6}$\"\nreurl=r\"^(https?://)?([a-z0-9]*\\.)?[a-z0-9]*\\.[a-z]{3}$\"\n\ndef validacion(correo,telefono,url):\n    if re.search(recorreo,correo):\n        print(f\"Correo validado: {correo}\")\n    else:\n        print(f\"correo invalidado: {correo}\")\n    if re.search(retelefono,telefono):\n        print(f\"Numero de telefono validado: {telefono}\")\n    else:\n        print(f\"Numero de telefono invalidado: {telefono}\")\n    if re.search(reurl,url):\n        print(f\"Url validada: {url}\")\n    else:\n        print(f\"Url invalidada: {url}\")\n\nvalidacion(\"Messigallito@gmail.com\",\"+54 6324 695874\",\"www.freecodecamp.com\")\n    \n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/Gordo-Master.py",
    "content": "# 16 Expresiones Regulares.\n\nimport re\n\ntext = \"\"\"This regular expression example was made on September 8, 2024 \nand never revised. \nAunque yo empece este proyecto de retos de programación hace mas de \n5 meses\"\"\"\n\npattern = r\"[\\d]+\"\n\nprint(re.findall(pattern,text))\n\n\"\"\"\nEjercicio Extra\n\"\"\"\n\ndef valid_mail(mail: str) -> bool:\n    pattern = r\"^[a-zA-Z][\\w\\.+-]{6,30}@[a-zA-Z]+\\.[a-zA-Z]+(\\.[a-zA-Z]{2})?$\"\n    return bool(re.match(pattern,mail))\n\nprint(f\"El correo es valido: {valid_mail(\"GordoMaster@yahoo.net\")}\")\n\ndef valid_num(num: str) -> bool:\n    pattern = r\"^\\+\\d{1,3}\\s?9\\d{2}\\s?\\d{3}\\s?\\d{3,4}$\"\n    return bool(re.match(pattern,num))\n\nprint(f\"El numero es valido: {valid_num(\"+595 912 345 678\")}\")\n\ndef valid_url(url: str) -> bool:\n    pattern = r\"^http[s]?://(www\\.|blog\\.|store\\.)?[a-zA-Z]\\w*\\.[a-zA-Z]+(\\.[a-zA-Z]{2})?(/\\w+)*(\\?\\w+=\\w+)?(#\\w+)?$\"\n    return bool(re.match(pattern,url))\n\nprint(f\"La URL es valido: {valid_url(\"https://www.example.com.es/ruta/ruta2?parametro=true#prueba\")}\")\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/Hyromy.py",
    "content": "import re # modulo para expresiones regulares\n\npatron = r\"estoy\" # expresion regular\ncadena = \"Hola buenas, estoy bien\" # string\n\ncoincidencia = re.search(patron, cadena)\nprint(coincidencia.group()) # \"estoy\" en cadena, no patron\n\n\"\"\"\nmetacaracteres\n\n. -> coincide con calcualquier caracter menos con nueva linea\n^ -> coincide al inicio del string\n$ -> coincide al final del string\n* -> coincide con 0 o mas repeticiones del caracter anterior\n+ -> coincide con 1 o mas repeticiones del caracter anterior\n? -> coincide con 0 o 1 repeticion del caracter anterior\n{n} -> coincide con n repeticiones del caracter anterior\n{n,} -> coincide con n o mas repeticiones del caracter anterior\n{n,m} -> coincide entre n y m repeticiones del caracter anterior\n[] -> coincide con cualquier caracter dentro de []\n| -> coincide con el patron a la izquierda o a la derecha\n() -> agrupa partes de la expresion y captura el texto\n\"\"\"\n\npatron = r\".ola\"\nstring = \"Hola cara de bola\"\ncoincidencia = re.search(patron, string) # solo captura la primera coincidencia\nprint(coincidencia.group())\n\n\npatron1 = f\"^hola\"\npatron2 = f\"^Hola\"\nstring = \"Hola soy Hyromy\"\ncoincidencia1 = re.search(patron1, string)\ncoincidencia2 = re.search(patron2, string)\n#print(coincidencia1.group()) error porque no lo encuentra\nprint(coincidencia2.group())\n\npatron = r\"ga*to\"\nstring = \"me gustaria un gaaaaaato\"\ncoincidencia = re.search(patron, string)\nprint(coincidencia.group())\n\npatron = r\"o{2}\"\nstring = \"comida se escribe food pero se pronuncia fud\"\ncoincidencia = re.search(patron, string)\nprint(coincidencia.group())\n\npatron = r\"[aeiou]\"\nstring = \"no se cuantas vocales tenga esto\"\ncoincidencia = re.findall(patron, string) # busca todas las [a, e, i, o, u]\nprint(coincidencia)\n\npatron = r\"gato|perro\"\nstring1 = \"yo tenia un perro\"\nstring2 = \"yo tenia un gato\"\ncoincidencia1 = re.search(patron, string1)\ncoincidencia2 = re.search(patron, string2)\nprint(coincidencia1.group())\nprint(coincidencia2.group())\n\n\"\"\"\nmetodos del modulo re\n\nre.match(pattern, string) => comprueba si hay coincidencias\nre.search(pattern, string) => busca la primera coincidencia en cualquier parte\nre.findall(pattern, string) => busca todas las conicidencias y devuelve una lista\nre.finditer(pattern, string) => busca todas las coincidencias y devuelve un iterable\nre.sub(pattern, repl, string) => encuentra todas las coincidencias, las reemplaza y devuelve un str\n\"\"\"\n\npatron = r\"\\d+\"\nstring = \"Este es un texto con 1 numero, bueno 2, quiza tenga 1000 o mas\"\ncoincidencias = re.finditer(patron, string)\nfor i in coincidencias:\n    print(i.group())\n\nprint(\"\\n\")\n\n# ---- DIFICULTAD EXTRA ----\nemail = r\".+@.+\\.com$\"\ntelefono = r\"(\\+\\d{2} )?\\d{10}$\"\nurl = r\"(http)s?://.+/?$\"\n\nprueba_email = \"formulajoel9@gmail.com\"\nprueba_telefono = \"5550341128\"\nprueba_url = \"http://www.youtube.com/\"\n\nbuscar_email = re.match(email, prueba_email)\nif buscar_email:\n    print(buscar_email)\nelse:\n    print(None)\n\nbuscar_telefono = re.match(telefono, prueba_telefono)\nif buscar_email:\n    print(buscar_telefono)\nelse:\n    print(None)\n\nbuscar_url = re.match(url, prueba_url)\nif buscar_url:\n    print(buscar_url)\nelse:\n    print(None)"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/Irenetitor.py",
    "content": "import re\n\n#Exercise\n\nregex = r\"[0-9]+\" #same \"/d+\"\n\ntext = \"Yesterday I walked 7 kilometers and drank 2 liters of water before 8:30 PM.\"\n\ndef find_numbers(text: str) -> list:\n    return re.findall(regex, text)\n\nprint(find_numbers(text))\n\n#Extra exercise\n\n#r\"[a-zA-Z0-9_.]+\" == r\"[\\w]+\"\n\ndef validate_email(email: str) -> bool:\n    pattern = r\"^[\\w.+-]{3,40}@[A-Za-z0-9-]{2,7}\\.[A-Za-z]{2,6}$\"\n    return bool(re.match(pattern, email))\n\nprint(validate_email(\"Jordi-265@gmail.com\"))\n\ndef val_phone_num(num: str) -> bool:\n    pattern2 = r\"^\\+?\\d{1,3}?[- ]?\\d{7,14}$\"\n    return bool(re.match(pattern2, num))\n\nprint(val_phone_num(\"+34123456789\"))\nprint(val_phone_num(\"+1-234567890\")) \nprint(val_phone_num(\"0123456789\"))\n\ndef validate_url(url: str) -> bool:\n    pattern3 = r\"^(https?|ftp)://[A-Za-z0-9.-]{2,56}\\.[A-Za-z]{2,8}$\"\n    return bool(re.match(pattern3, url))\n\nprint(validate_url(\"http://domain\")) \nprint(validate_url(\"http://google.es\"))\nprint(validate_url(\"ftp://my-site123.org\"))"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/JAFeito.py",
    "content": "\"\"\"\n EJERCICIO:\n  Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n  creando una que sea capaz de encontrar y extraer todos los números\n  de un texto.\n \n  DIFICULTAD EXTRA (opcional):\n  Crea 3 expresiones regulares (a tu criterio) capaces de:\n  - Validar un email.\n  - Validar un número de teléfono.\n  - Validar una url.\n \"\"\"\n \nimport re\n\ncadena = \"abc1def2gh1\"\nnumeros = re.findall(r\"\\d+\",cadena)\nprint(numeros)        \n\n#EXTRA\ndef val_email (email:str) -> bool:\n   re.match (r\"[\\w.+-]+@[\\w]+\\.[a-z]+\",email)\n   \nprint(val_email(\"lalala@jo2.com\"))"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/JesusWay69.py",
    "content": "import os, re\nos.system('cls')\n\n\n\"\"\"\n * EJERCICIO:\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.\n *\n\"\"\"\ntext = \"Un año tiene 365 días excepto si es bisiesto que tiene 366 divididos en 12 meses que pueden tener hasta 31 días cada uno.\"\npattern = re.compile(\"\\d\") #La er para cualquier número se puede declarar como \"\\d\" o \"[0-9]\"\nnums = pattern.findall(text)\n\nfor num in nums:\n    print(num, end=\" \")\nprint()\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\"\"\"\n\ndef email_validation(email:str):\n    pattern = (\"(?i)[a-z0-9\\\\._-]+(@)[a-z0-9]+\\\\.[a-z]{2,4}\")\n\n    if re.match (pattern, email):\n        return True\n    else:\n        return False\n'''Función que valida una dirección de email con usuario que puede tener letras, números, puntos\n    o guiones, a continuación una @ , despues el proveedor que sólo puede incluir letras y números\n    y separado por un punto el dominio que puede tener de 2 a 4 letras'''\n\n\n\ndef spain_phone_validation(phone_num:str):\n    pattern = (\"[9|7|6][0-9]{8}||(\\\\+34)[9|7|6][0-9]{8}\")\n    if re.match(pattern, phone_num):\n        return True\n    else:\n        return False\n'''Función que valida un nº de tlf español particular cuyo primer número debe ser 6,7 (móvil) o 9 (fijo) ,\n   tener en total 9 números y que puede incluir o no el prefijo español +34, el número no puede contener espacios.  '''\n\n\n\ndef url_validation(url:str):\n    pattern = (\"(?i)[a-z0-9._-]{1,63}\\\\.[a-z]{2,8}||(www)\\\\.[a-z0-9._-]{1,63}\\\\.[a-z]{2,8}\")\n    if re.match(pattern, url):\n        return True\n    else:\n        return False\n'''Función que valida una url básica con dominio de hasta 63 caracteres que pueden incluir puntos y guiones\n    y , separado por un punto el TLD que puede ser de entre 2 y 8 letras (por ej .business)'''\n\n\n\ndef dni_validation(dni:str):\n    pattern = (\"(?i)[0-9]{8}[^IOU]{1}\")\n    if re.match(pattern,dni):\n        return True\n    else:\n        return False\n'''Función que valida un dni español con 8 cifras y una letra al final que no puede ser i,o,u ni ñ\n    tal y como establece la normativa al respecto.  '''\n\n\ndef date_validation(date:str):\n    pattern = (\"^([0-2][0-9]||[3][0-1])(\\/|-)(0[1-9]||1[0-2])(\\/|-)((19)[5-9][0-9]||(20)[0-4][0-9]||(2050))$\")\n    if re.match(pattern, date):\n        return True\n    else:\n        return False\n'''Función que valida una fecha en formato dd/mm/aaaa o dd-mm-yyyy con límites de días a 31,meses a 12 y años entre 1950 y 2050'''\n    \nprint(email_validation(\"je.suSw-ay69@hotmail.com\"))\nprint(spain_phone_validation(\"+34716984941\"))\nprint(url_validation(\"moure.dev\"))\nprint(dni_validation(\"60965022t\"))\nprint(date_validation(\"22/04/2050\"))"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/JheisonQuiroga.py",
    "content": "import re\n\n\"\"\"\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.\n\"\"\"\n\ntxt = \"\"\"\nCristiano Ronaldo dos Santos Aveiro (Funchal, Madeira, 5 de febrero de 1985)\nes un futbolista portugués. Juega como delantero y su equipo actual es el \nAl-Nassr F. C. de la Liga Profesional Saudí. Es internacional absoluto con la \nselección de Portugal, de la cual es capitán, máximo goleador histórico y \njugador con más presencias con 217 partidos, logro alcanzado en las eliminatorias \npara la Eurocopa 2024, reconocido por el Libro Guinness de los récords.\n\"\"\"\n\nregex_pattern = r\"\\d+\"\n\nmatches = re.findall(regex_pattern, txt)\nprint(matches)\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\n */\n\"\"\"\n\n# Validando un e-mail\n\ndef email_validation(email):\n\n    reg_pattern = r\"^[a-zA-Z0-9]+([.+-_][a-zA-Z0-9]+)*@([a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,6}$\"\n\n    # Verificamos si toda la cadena coincide con el patron\n\n    return True if re.fullmatch(reg_pattern, email) else False\n\n\nemails = [\n    \"usuario@example.com\",\n    \"user.name@sub.domain.org\",\n    \"correo@dominio.co\",\n    \"usuario123@dominio.com\",\n    \"mal.correo@com\",        # Inválido (extensión incorrecta)\n    \"sin-arroba.com\",        # Inválido (falta @)\n    \"@sin_nombre.com\"        # Inválido (falta nombre)\n]\n\nfor email in emails:\n    print(f\"{email}: {\"Valido\" if email_validation(email) else \"Invalido\"}\")\n\n# Validando un número de telefono en Colombia.\n# Formato 300-000-0000, debe tener 10 digitos\n\ndef phone_validation(phone):\n\n    reg_pattern = r'^([3][0-9]{2}-?[0-9]{3}-?[0-9]{4})'\n    return True if re.fullmatch(reg_pattern, phone) else False\n\n\nprint(phone_validation(\"320-326-7902\")) # True\nprint(phone_validation(\"320-326-790235\")) # False\nprint(phone_validation(\"3203267902\")) # True\nprint(phone_validation(\"2203267902\")) # False\n\n\n\n# Validando una URL\ndef url_validate(url:str) -> bool:\n    \n    pattern = (\n        r'^(https?://)' # Protocolo\n        r'([a-zA-Z0-9-]+\\.)*' # Subdominios\n        r'[a-zA-Z]{2,}' # TLD ej. (.com , .org)\n        r'(:[0-9]{1,5})?' # Puerto (opcional) ej. :8000\n        r'(/.*)?$'\n    )\n    # reg_pattern = r'^(https?://)?(www\\.)?([a-zA-Z0-9.-]+)\\.[a-zA-Z]{2,6}(/.*)?$'\n\n    return True if re.fullmatch(pattern, url) else False\n\n\nurls = [\n    \"https://www.google.com\",   # Válido\n    \"http://example.org\",       # Válido\n    \"https://sub.dominio.co/path?query=123\",  # Válido\n    \"ftp://invalid.com\",        # Inválido (no es HTTP o HTTPS)\n    \"www.nodominio\",            # Inválido (falta extensión)\n    \"http://localhost:8000\",    # Valido\n]\n\n\nprint(\"\\nValidación de URLs:\")\nfor url in urls:\n    print(f\"{url}: {'Válido' if url_validate(url) else 'Inválido'}\")"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/JuanDAW37.py",
    "content": "\"\"\"* EJERCICIO:\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\"\"\"\nimport re # Librería para expresiones regulares\n\nregex = r\"[0-9]+\" # Valdría también usando \\d+\n\ntexto_con_numeros = 'Hoy es miércoles 04/09/2024'\n\ndef encontrar_numeros(texto_con_numeros:str):\n    return re.findall(regex, texto_con_numeros)\n\nprint(encontrar_numeros(texto_con_numeros))\n\n#EXTRA\n#Validar un email\nregex_email = r\"^[a-zA-Z0-9._%+-]+@[a-zA-Z]\"\n#Validar un número de teléfono\nregex_telefono = r\"\\d{3}.\\d{3}.\\d{3}\"\n#Validar una url\nregex_url = r\"^https?://[a-zA-Z0-9.-]+\\.[a-zA]\"\n\nemail = 'pepe@gmail.com'\ntelefono = '627.998.325'\nurl = 'https://urlfalsa.com'\n\ndef valida_email():\n    return re.match(regex_email, email) is not None\n\ndef valida_telefono():\n    return re.match(regex_telefono, telefono) is not None\n\ndef valida_url():\n    return re.match(regex_url, url) is not None\n\nprint(valida_email())\nprint(valida_telefono())\nprint(valida_url())"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/KevinED11.py",
    "content": "import re\nfrom typing import Protocol\nfrom functools import partial, lru_cache\nfrom enum import StrEnum\n\n\ntype StrTuple = tuple[str, ...]\n\n\nclass SearcherFn(Protocol):\n    def __call__(self, text: str) -> StrTuple: ...\n\n\nclass SearchPattern(StrEnum):\n    ALL_NUMBERS = r\"\\d+\"\n\n\n@lru_cache\ndef generic_searcher(pattern: SearchPattern, text: str) -> StrTuple:\n    return tuple(re.findall(pattern, text))\n\n\nsearch_all_numbers = partial(generic_searcher, pattern=SearchPattern.ALL_NUMBERS)\n\n\nclass ValidatorFn(Protocol):\n    def __call__(self, value: str) -> bool: ...\n\n\nclass ValidationPattern(StrEnum):\n    pass\n\n\nclass EmailValidationPattern(ValidationPattern):\n    EMAIL = r\"^\\w+@\\w+\\.\\w+$\"\n    EMAIL2 = r\"^\\w+([\\.-]?\\w+)*@\\w+([\\.-]?\\w+)*(\\.\\w{2,3})+$\"\n    EMAIL3 = r\"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$)\"\n\n\nclass PhoneValidationPattern(ValidationPattern):\n    PHONE = r\"^\\+?\\d{10, 15}$\"\n    PHONE2 = r\"^\\+?1?\\d{9,15}$\"\n\n\nclass UrlValidationPattern(ValidationPattern):\n    URL = r\"^https?://.+$\"\n    URL2 = r\"^(http|https)://[a-zA-Z0-9-\\.].+\\.[a-zA-Z]{2,4}(/\\S*)?$\"\n\n\n@lru_cache\ndef generic_validator(pattern: ValidationPattern, value: str) -> bool:\n    return re.match(pattern, value) is not None\n\n\nvalidate_email = partial(generic_validator, pattern=EmailValidationPattern.EMAIL)\nvalidate_phone = partial(generic_validator, pattern=PhoneValidationPattern.PHONE)\nvalidate_url = partial(generic_validator, pattern=UrlValidationPattern.URL2)\n\n\ndef execute_validator(validator: ValidatorFn, value: str) -> bool:\n    return validator(value=value)\n\n\ndef execute_searcher(searcher: SearcherFn, text: str) -> StrTuple:\n    return searcher(text=text)\n\n\nclass Separator(StrEnum):\n    LINE_BREAK = \"\\n\"\n\n\ndef main() -> None:\n    email_result = execute_validator(validator=validate_email, value=\"a@a.com\")\n    phone_result = execute_validator(validator=validate_phone, value=\"000000000000\")\n    url_result = execute_validator(\n        validator=validate_url, value=\"https://wwwgoogle.com\"\n    )\n    print(email_result, phone_result, url_result, sep=Separator.LINE_BREAK)\n\n    search_result = execute_searcher(searcher=search_all_numbers, text=\"ke8i9\")\n    print(search_result)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/LucasRebuffo.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\n */ \"\"\"\n\nimport re\n\nregex = r\"[\\d]+\"\n\nfound = re.compile(regex).findall(\"1515dasdsd55dsf897fdfd988 !@ 15\")\n\nprint(found)\n\n\nregex_email = r\"^[\\w\\.+-]+@[\\w]+\\.[a-zA-Z]{2,4}$\"\n\ndef validate_email(email: str):\n    return bool(re.match(regex_email,email))\n\nprint(validate_email(\"lucas@gmail.com\"))\nprint(validate_email(\"lucasgmail.com\"))\n\nregex_phone = r\"^\\+?[\\d\\s]{3,}$\"\n\ndef validate_phone(phone: str):\n    return bool(re.match(regex_phone,phone))\n\nprint(validate_phone(\"1131639967\"))\nprint(validate_phone(\"11 3163 9967\"))\nprint(validate_phone(\"113163a99674\"))\nprint(validate_phone(\"+54 11316399674\"))\n\n\nregex_url = r\"^http[s]?://(www.)?[\\w]+\\.[a-zA-Z]{2,4}$\"\n\ndef validate_url(url: str):\n    return bool(re.match(regex_url,url))\n\nprint(validate_url(\"http://lucas.dev\"))\nprint(validate_url(\"http://www.lucas.dev\"))\nprint(validate_url(\"https://lucas.dev\"))\nprint(validate_url(\"https://www.lucas.dev\"))\nprint(validate_url(\"https://ww.lucas.dev\"))\n\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/Lumanet.py",
    "content": "import re\n\n# Function\tDescription\n# findall -\tReturns a list containing all matches\n# search -\tReturns a Match object if there is a match anywhere in the string\n# split -\tReturns a list where the string has been split at each match\n# sub - Replaces one or many matches with a string\n\ncadena = \"Esto es un texto de ejemplo con el número 12345 y otro número 54321\"\nresultado = re.findall(r\"\\d+\", cadena) # \\d+ busca uno o más dígitos \nprint(resultado)\nresultado = re.findall(r\"\\d{3}\", cadena) # \\d{3} busca exactamente 3 dígitos\nprint(resultado)\nresultado = re.search(r\"texto\", cadena) # search() busca la primera ocurrencia de la cadena \"texto\" y devuelve un objeto Match\nprint(resultado)\nresultado = re.split(r\"\\d+\", cadena) # split() divide la cadena en una lista donde se encuentran los números\nprint(resultado)\nresultado = re.sub(r\"\\d+\", \"XXXX\", cadena) # sub() reemplaza los números por la cadena \"XXXX\"\nprint(resultado)\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\nCrea 3 expresiones regulares (a tu criterio) capaces de:\n- Validar un email.\n- Validar un número de teléfono.\n- Validar una url.\n\"\"\"\ndef validar_email(email):\n    return bool(re.match(r\"^[\\w.+-]+@[\\w]+\\.[a-zA-Z]+$\", email))\n\ndef validar_telefono(phone):\n    return bool(re.match(r\"^\\+?[\\d\\s]{3,}$\", phone))\n\ndef validar_url(url):\n    return bool(re.match(r\"^(http[s]?://)?(www.)?[\\w]+\\.[\\w]{2,}[/]?$\", url))\n\nprint(validar_email(\"marcos@gmail.com\"))\nprint(validar_email(\"marcos@gmail.com\"))\nprint(validar_email(\"marcos@gmail.com\"))\nprint(validar_telefono(\"632562345\"))\nprint(validar_telefono(\"+34632562345\"))\nprint(validar_telefono(\"+34 632 56 23 45\"))\nprint(validar_url(\"http://www.marcos.com\"))\nprint(validar_url(\"https://www.marcos.com\"))\nprint(validar_url(\"http://www.marcos.com/\"))\nprint(validar_url(\"www.marcos.com\"))\nprint(validar_url(\"www.marcos.com/\"))\nprint(validar_url(\"marcos.com\"))\nprint(validar_url(\"m4rc0s.com\"))\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/Nicojsuarez2.py",
    "content": "# #16 EXPRESIONES REGULARES\n> #### Dificultad: Media | Publicación: 15/04/24 | Corrección: 22/04/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/Nightblockchain30.py",
    "content": "\n# \n#\n# EJERCICIO:\n# Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n# creando una que sea capaz de encontrar y extraer todos los números\n# de un texto.\n#\n# DIFICULTAD EXTRA (opcional):\n# Crea 3 expresiones regulares (a tu criterio) capaces de:\n# - Validar un email.\n# - Validar un número de teléfono.\n# - Validar una url.\n#\n\nimport re\n\ndef find_numbers(text: str)-> list:\n    return re.findall(regex,text)\n\nregex = r'\\d+'\ntext = \"1234 Hola soy un 56 texto de ejemplo 78 9\"\n\nprint(find_numbers(text))\n\n\n# EXTRA\n\ndef check_email(email: str)->bool:\n    return bool(re.match(regex_email,email))\n\nregex_email = r'^[\\w.+-_]+@[\\w]+\\.[a-z]{2,3}$'\nemail = \"nig_h-t+@gmail.com\"\n\nprint(check_email(email))\n\n\ndef check_number(number: str)->bool:\n    return bool(re.search(regex_number,number))\n\nregex_number = r'^(\\+[0-9]{1,3}\\s)?\\d{1,9}$'\nnumber = \"567437079\"\n\nprint(check_number(number))\n\n\ndef check_url(url : str)->bool:\n    return bool(re.match(regex_url,url))\n\nregex_url = r'^(http[s]?://)?[\\w]+\\.[\\w]+\\.[a-z]{2,}$'\nurl = \"https://www.google.com\"\n\nprint(check_url(url))"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/Sac-Corts.py",
    "content": "import re\n\npattern = r'\\d+'\ntext = \"Tengo 2 perros y 3 gatos. También tengo 6 tortugas, 1 serpiente, 2 arañas, 4 ratones y ya.\"\nresult = re.findall(pattern, text)\nprint(result)\n\n### Ejercicio Extra ###\n\nregex_email = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$'\nemail = \"ejemplo@dominio.com\"\nif re.match(regex_email, email):\n    print(\"Correo válido\")\nelse:\n    print(\"Correo no válido\")\n\n\nregex_telefono = r'^\\+?[\\d\\s-]{7,15}$'\ntelefono = \"+123-456-7890\"\nif re.match(regex_telefono, telefono):\n    print(\"Teléfono válido\")\nelse:\n    print(\"Teléfono no válido\")\n\n\nregex_url = r'^(https?:\\/\\/)?(www\\.)?[a-zA-Z0-9._%+-]+\\.[a-zA-Z]{2,}(:[0-9]{1,5})?(\\/.*)?$'\nurl = \"https://www.ejemplo.com:8080/path/to/page\"\nif re.match(regex_url, url):\n    print(\"URL válida\")\nelse:\n    print(\"URL no válida\")\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/SaezMD.py",
    "content": "#16 - EXPRESIONES REGULARES\n\"\"\"\n * EJERCICIO:\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\n\"\"\"\n\nimport re\n\ndef extract_numbers(text:str)-> str:\n\n    numbers = re.findall('[\\d]+',text)\n\n    #To find commas, e.g. 12,300 or 12,300.00\n    #r'[\\d]+[.,\\d]+'  \n    #To find floats, e.g. 0.123 or .123\n    #r'[\\d]*[.][\\d]+'     \n    #To find integers, e.g. 123\n    #r'[\\d]+'\n\n    all_numbers = \"\".join(numbers)\n    return all_numbers\n\nprint(extract_numbers(\"hello23 numbers 1234, not\"))\n      \nprint(extract_numbers(\"hello 2,3 numbers 1234, not\"))\n\n\n#EXTRA:\n#Validate EMAIL:\ndef validEmail(email):\n    regexEmail = re.compile(r'([A-Za-z0-9]+[.-_])*[A-Za-z0-9]+@[A-Za-z0-9-]+(\\.[A-Z|a-z]{2,})+')\n    if re.fullmatch(regexEmail, email):\n      print(\"Valid email\")\n    else:\n      print(\"Invalid email\")\n\nvalidEmail(\"saezmd@gmail.net\")\nvalidEmail(\"sae.zmd@gmail.net\")\nvalidEmail(\"saezmd@gmail\")\nvalidEmail(\"saezmd@dotdot.net\")\nvalidEmail(\"saezmd@gmail..net\")\n\n#Validate Phone Number:\ndef validPhone(phoneNumber):\n    regexPhone = re.compile(r'^(\\+\\d{1,2}|00\\d{2})?[ -]*(6|7)[ -]*([0-9][ -]*){8}$')\n    phoneNumber = str(phoneNumber)\n    if re.fullmatch(regexPhone, phoneNumber):\n      print(\"Valid phone\")\n    else:\n      print(\"Invalid phone\")\n\nvalidPhone(\"0034612358902\")\nvalidPhone(\"+34612358902\")\nvalidPhone(612358902)\nvalidPhone(\"+34239847298435\")\n\n#Validate URL:\n\ndef validURL(URLlink):\n    regexURL = re.compile(\n            r'^(?:http|ftp)s?://' # http:// or https://\n            r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\\.)+(?:[A-Z]{2,6}\\.?|[A-Z0-9-]{2,}\\.?)|' #domain...\n            r'localhost|' #localhost...\n            r'\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})' # ...or ip\n            r'(?::\\d+)?' # optional port\n            r'(?:/?|[/?]\\S+)$', re.IGNORECASE)\n\n    if re.fullmatch(regexURL, URLlink):\n       print(\"Valid URL\")\n    else:\n       print(\"Invalid URL\")\n\n\nvalidURL(\"http://www.saezMD.com\")\nvalidURL(\"example.com\")\nvalidURL(\"https://saezmd.vercel.app/\")\n\n\n\n\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/SooHav.py",
    "content": "# 16 EXPRESIONES REGULARES\n\n# Ejercicio\n\nimport re\n\npatron = r\"\\d+((\\,\\d+)|(\\.\\d+))*\"\n\n\"\"\"\\d+: Coincide con uno o más dígitos (\\d). El + indica que debe coincidir al menos con un dígito.\n(\\,\\d+)*: Este grupo de captura (...) seguido de * indica que puede coincidir cero o más veces con una coma seguida de uno o más dígitos.\n(\\.\\d+)?: Este grupo de captura (...) seguido de ? indica que puede coincidir cero o una vez con un punto seguido de uno o más dígitos.\"\"\"\n\n\ntxt = \"\"\"A partir de la UM1, se determinó que el prototipo no presentó un offset asociado a la presión atmosférica durante el período observado, mientras que el equipo\n         comercial tuvo un offset promedio de 18 mm. La repetibilidad y reproducibilidad del sistema de medición se evaluaron utilizando el método de promedios\n         y rangos sugerido por Moret y Paisan (2010), con los datos de la UM2. El % de repetibilidad promedio de todos los niveles de agua resultó ser 15,430\n         ligeramente mayor al % de reproducibilidad promedio (12,369). Esto indica que la variabilidad existente entre las mediciones se debe al instrumento\n         en sí y/o al sistema utilizado para realizar las mediciones en los diferentes tratamientos aplicados. El porcentaje de la relación entre la repetibilidad\n         y la reproducibilidad promedio R&R fue de 20,041, ubicándose entre el rango 10% y 30%. Esto implica que el sistema de medición es aceptable temporalmente,\n         aunque se requieren mejoras. Se plantearon dos hipótesis: en primer lugar, puede ser necesario aumentar la tolerancia admitida (T= 10 mm) en la medición; y\n         en segundo lugar, se debe revisar el sistema de medición, ya que los mejores resultados se obtuvieron en las mediciones centrales, lo que sugiere que los extremos\n         podrían tener un error asociado a una mayor dificultad operativa. El sesgo de las mediciones se obtuvo a partir del método de Bland-Altman (Figura 2). A partir del\n         gráfico se puede observar que el sesgo medio de los datos se mantiene cerca del cero. La mayoría de las diferencias individuales se encuentran dentro de un rango\n         de confianza del 95% (± 5 mm). El 99% de los datos se encuentra dentro de las líneas establecidas como tolerancia del instrumento (± 10 mm), y todos los\n         datos están dentro de la tolerancia proporcionada por el fabricante del sensor (máximo ± 50 mm para la sonda utilizada).\"\"\"\n\nresultado = re.sub(patron, \"\", txt)\nprint(resultado)\n\n# Extra\n\n# Correos electronicos\n\npatron = r\"[\\w\\.-]+@[\\w\\.-]+\"\nmail = 'havrylenko.sb@gmail.com'\n\nresultado = re.search(patron, mail)\nif resultado:\n    print(f\"Mail válido: {mail}\")\nelse:\n    print(f\"Mail inválido: {mail}\")\n\n# Nùmeros de telefono\npatron = r\"\\+?\\d{0,2}?-?\\d{3,4}?-?\\d{5,9}\"\n\ntelefonos = ['+54-011-1511111111', '+54-011-11111111',\n             '011-11111111', '11111111', '1511111111']\n\nfor telefono in telefonos:\n    resultado = re.search(patron, telefono)\n    if resultado:\n        print(f\"Teléfono válido: {telefono}\")\n    else:\n        print(f\"Teléfono inválido: {telefono}\")\n\n# URL\n\npatron = r\"(\\www\\.)[\\w\\.-]+\"\nurl = \"www.disneyplus.com\\es\"\n\nresultado = re.search(patron, url)\nif resultado:\n    print(f\"URL válida: {url}\")\nelse:\n    print(f\"URL inválida: {url}\")\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/Trufoplus.py",
    "content": "import re\n\n#Texto de ejemplo\ntext = \"Tengo 2 gatos, 3 perros, 18 iguanas y 10 tortugas\"\n#Patron para encontrar los numeros desde el 0 al 9\npattern = re.compile(r\"[0-9]\")\n#Reemplazamos todos los numeros de el texto por nada.\nnew_text = pattern.sub(\"\", text)\n#Imprimimos el resultado\nprint(new_text)\n\n\n###############################################################################\n## DIFICULTAD EXTRA\n###############################################################################  \n\nemail = input(\"Escribe tu email: \")\ntlf = input(\"Escrine tu mumero de telefono: \")\nurl = input(\"Escribe la url de tu web favorita: \")\n\ndef match(data: str):\n    if matches:\n        print(f\"Datos de {data} correctos\")\n    else:\n        print(f\"Error datos de {data} incorrectos\")\n\nemail_pattern = re.compile(r\"\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Z|a-z]{2,}\\b\")\nmatches = email_pattern.search(email)\nmatch(\"email\")                               \n                               \ntlf_pattern = re.compile(r\"\\d{9}\")\nmatches = tlf_pattern.search(tlf)\nmatch(\"Telefono\")\n\nurl_pattern = re.compile(r\"\\b[w]{3,}+\\.[A-Za-z0-9.-]+\\.[A-Z|a-z]{2,}\\b\")\nmatches = url_pattern.search(url)\nmatch(\"url\")\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/adolfolozaa.py",
    "content": "'''\r\n * EJERCICIO:\r\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\r\n * creando una que sea capaz de encontrar y extraer todos los números\r\n * de un texto.\r\n '''\r\nimport re\r\n\r\n\r\n\r\ntexto = 'Quito, la capital de Ecuador, se ubica en la altura de las laderas de los Andes a 2,850 m. Fue construida sobre los cimientos de una antigua ciudad inca y es famosa por su centro colonial bien conservado, con varias iglesias de los siglos XVI y XVII, y otras 2 estructuras que mezclan estilos europeos, moriscos e indígenas. Estos incluyen la catedral, en la Plaza Grande, y la iglesia jesuita altamente decorada de la Compañía de Jesús'\r\n\r\n#x = re.findall(r\"[0-9]+\", texto)   # con + toma numeros consecutivos como un solo numero\r\nx = re.findall(r'\\d+', texto)  #\\d busca los numeros\r\nprint(x)\r\n#print(texto)\r\n\r\n\r\n'''\r\n * DIFICULTAD EXTRA (opcional):\r\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\r\n * - Validar un email.\r\n * - Validar un número de teléfono.\r\n * - Validar una url.\r\n '''\r\n\r\n#validar correo electronico\r\n\r\ndef valid_email(email):\r\n    regex = r'^[a-z0-9]+[\\._]?[a-z0-9]+[@]\\w+[.]\\w+$'\r\n\r\n    if re.match(regex, email):\r\n        return True\r\n    else:\r\n        return False\r\n    \r\nemails = ['adolfolozaa@gmail.com', 'alozavera@gmail.com', 'vera.gaby@gmail.com', 'ddjjdjdjjd.djdjd']\r\n\r\nfor email in emails:\r\n    if valid_email(email):\r\n        print(f'{email} es valido')\r\n    else:\r\n        print(f'{email} es NO valido')\r\n\r\nfor email in emails:\r\n    match = re.search(r'^[a-z0-9]+[\\._]?\\w+@\\w+[.]\\w+$', email)\r\n    if match:\r\n        print(match.group()) \r\n\r\n# validar numero telefonico\r\ndef valid_phone(phone):\r\n    phone_number_regex = re.compile(r\"^(\\+\\d{1,3})?\\s?\\(?\\d{1,4}\\)?[\\s.-]?\\d{3}[\\s\\.-]?\\d{4}$\")\r\n\r\n    if re.match(phone_number_regex, phone):\r\n        return True\r\n    else:\r\n        return False\r\n\r\nphones = ['+1 555 123 4567','+1-555-123-4567', '+1.555.123.4567','+15551234567','+1 (555) 1234567', '0963564397','+593999447336' ]\r\n\r\nfor phone in phones:\r\n    if valid_phone(phone):\r\n        print(f'{phone} es valido')\r\n    else:\r\n        print(f'{phone} es NO valido')\r\n\r\n# validar una url\r\ndef valid_url(url):\r\n    url_regex = re.compile(\"^https?:\\\\/\\\\/(?:www\\\\.)?[-a-zA-Z0-9@:%._\\\\+~#=]{1,256}\\\\.[a-zA-Z0-9()]{1,6}\\\\b(?:[-a-zA-Z0-9()@:%_\\\\+.~#?&\\\\/=]*)$\"\r\n)\r\n\r\n    if re.match(url_regex, url):\r\n        return True\r\n    else:\r\n        return False\r\n\r\nurls = ['https://uibakery.io/regex-library/url-regex-python','https://keep.google.com/#NOTE/1QHupYobDyDMiNA0zZSYuAqkGM0HSaOunci0o78fxH-qQ2Ynl4U5afF4bxJp_yA', 'https://www.guru99.com/es/python-check-if-file-exists.html','https://mail.google.com/mail/u/0/?hl=es#inbox','https://blog.artegrafico.net/composicion-de-numeros-de-telefono-y-expresion-regular-con-python', 'https://github.com/adolfolozaa/roadmap-retos-programacion','https://developers.google.com/edu/python/regular-expressions?hl=es-419' ]\r\n\r\nfor url in urls:\r\n    if valid_url(url):\r\n        print(f'{url} es valido')\r\n    else:\r\n        print(f'{url} es NO valido')\r\n\r\n\r\n\r\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/adra-dev.py",
    "content": "\"\"\"\nEJERCICIO:\nUtilizando tu lenguaje, explora el concepto de expresiones regulares,\ncreando una que sea capaz de encontrar y extraer todos los numeros de\nun texto.\n\nDIFICULTAD EXTRA (opcional):\nCrea 3 expresiones regulares (a tu criterio) capaces de:\n- Validar un email.\n- Validar un número de teléfono.\n- Validar una url.\n\nby adra-dev\n\"\"\"\n\n\n\"\"\"\nExpresiones regulares:\n\nUna expresion regular es una cadena de caracteres especial que define\nun patron de busqueda. Son una herramienta fundamental para manipular\nconjuntos de datos en texto, como las listas de nombres de archivos, \ndirecciones de correo electronico, modelos de productos, etc. \nLas expresiones regulares pueden ahorrarte mucho trabajo si sabes \nsacarle partido y Python ofrece potentes herramientas para su \nmanipulacion.\n\"\"\"\n\nimport re\n\nregex1 = r'\\d+'\nregex2 = re.compile(r'\\d+')\n\ntext  = \"\"\" En un lugar muy lejano, había un Rey al que todos consideraban muy sabio.\n\nGobernaba con gran justicia 99 aldeas. Las 9 eran vecinas y en perfecta armonía todas convivían.\n\nEl Rey se ocupaba de que todas las aldeas tuvieran agua, comida y una bonita escuela.\n\nLas 9 aldeas estaban rodeadas por 999999 riachuelos. \n\nY el Rey construyo 90123 molinos y 10 puentes para que todos pudieran cruzar de un lado a otro sin correr ningún riesgo.\"\"\"\n\nprint(re.findall(regex2, text))\n\n\n\"\"\"\nExtra\n\"\"\"\n\nregex_email = re.compile('^[\\w\\-\\.]+@([\\w-]+\\.)+[\\w-]{2,}$')\n\nregex_phone = re.compile('(?:([+]\\d{1,4})[-.\\s]?)?(?:[(](\\d{1,3})[)][-.\\s]?)?(\\d{1,4})[-.\\s]?(\\d{1,4})[-.\\s]?(\\d{1,9})')\n\nregex_url = re.compile('^(http://|https://|http://www\\.|https://www\\.|www\\.)?(www\\.(twanda))?(([\\w\\-]+)?\\.?(twanda|))(\\.ch|\\.com)(:\\d+)?/.+$')\n\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/agusrosero.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\n */\n\"\"\"\n\nimport re\n\n# EJERCICIO:\ntexto = 'Este es mi texto numero 123456'\nbusqueda = re.findall('[0-9]', texto)\nprint(busqueda)\n\n# DIFICULTAD EXTRA:\nvalidar_email = r'\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Z|a-z]{2,7}\\b'\nvalidar_telefono = '^\\\\+?[1-9][0-9]{7,14}$'\nvalidar_url = '((http|https)\\:\\/\\/)?[a-zA-Z0-9\\.\\/\\?\\:@\\-_=#]+\\.([a-zA-Z]){2,6}([a-zA-Z0-9\\.\\&\\/\\?\\:@\\-_=#])*'\n\nprint(re.fullmatch(validar_email, 'test@gmail.com'))\nprint(re.match(validar_telefono, '+543413333333'))\nprint(re.match(validar_url, 'https://www.google.com'))\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/alanshakir.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\n */\n\"\"\"\n\nimport re\n\ndef find_extract(text: str):\n    regex_pattern = r\"\\d\"\n    findall = re.findall(regex_pattern, text, re.I)\n    return findall\nprint(find_extract(\"Est5o e8s un 8te9xto con numeros4\"))\n\n#Extra\n\ndef mail_validate(email: str):\n    mail_pattern = r\"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$\"\n    return bool(re.match(mail_pattern, email))\nprint(mail_validate(\"alan2085@gmail.com\"))\n\ndef phone_validate(phone: str):\n    phone_pattern = r'^(\\+\\d{1,3}\\s?)?[-\\s]?[0-9]{7,8}$'\n    return bool(re.match(phone_pattern, phone))\n\nprint (phone_validate(\"+569 53155806\"))\n\ndef url_validate(url: str):\n    url_pattern = r\"^[a-zA-Z0-9_.+-]+:+//[a-zA-Z0-9-.]+[a-zA-Z0-9-.]+$\"\n    return bool(re.match(url_pattern, url))\n\nprint(url_validate(\"https://www.google.com\"))\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/alcaan16.py",
    "content": "\"\"\"/*\n * EJERCICIO:\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\n */\"\"\"\n\nimport re\n\n#ejercicio\n\nfrase = \"hoy es el dia 22/01/2025\"\n\ndef find(frase)-> list:\n    return re.findall(r\"\\d+\", frase)# entre comilla:\\d el tipo de caracter y el + el numero de caracter\n    #return re.findall(r\"\\d{2}\", frase) #digitos separados por 2\n\nprint(find(frase))\n\n#extra\n\nemail1 = \"angel@correo.com\"\nemail2 = \"correo.com\" \n\ndef find_email(email)->bool:\n    # encuentra solo el simbolo @ en la frase\n    #if \"@\" in re.findall(r\"[@]\",email) : return True; \n    #else : return False\n    \n    return bool(re.match(r\"^[\\w.+-]+@[\\w]+\\.[a-zA-z]+$\", email))\n\nprint(f\"{email1} es un correo? {find_email(email1)}\")\nprint(f\"{email2} es un correo? {find_email(email2)}\")\n\nphone1 = \"123456789\"\nphone2 = \"13\"\n\ndef find_phone(phone)->bool:\n\n    return bool(re.match(r\"^\\+?[\\d\\s]{3,9}$\", phone))\n    \n    \nprint(f\"{phone1} es un telefono? {find_phone(phone1)}\")\nprint(f\"{phone2} es un telefono? {find_phone(phone2)}\")\n\nurl1 = \"http://www.google.com\"\nurl2 = \"cor\" \n\n\n\ndef find_url(url)->bool:\n    \n    return bool(re.match(r\"^http[s]?://(www.)?[\\w]+\\.[a-zA-Z]{2,}$\", url))\n\nprint(f\"{url1} es un correo? {find_url(url1)}\")\nprint(f\"{url2} es un correo? {find_url(url2)}\")\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/any7dev.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\n */ \"\"\"\n\n#EJERCICIO\nimport re\n\ntexto = (\"La sociedad francesa estaba dividida en estamentos dependiendo de sus clases sociales\",\n        \"el poder mas alto lo tenía el rey, detrás estaban la nobleza y el clero y el nivel mas bajo de poder\", \n        \"lo tenia el tercer estado que estaba constituido por la burguesía, los artesanos y los campesinos.\", \n        \"Los Estados Generales eran una asamblea, compuesta por tres ordenes separados: el clero, la nobleza y el grupo formado\", \n        \"por burguesía y campesinado. Este último orden se conoce como el tercer estadeo, término que usaremos para referirnos\", \n        \"a él en lo sucesivo. Dicha asamblea se había citado por ultima vez en 1614 y el dramatismo de la situación obligó al\", \n        \"gobierno a convocarla nuevamente.\",\n        \"Luis XVI cedió a las presiones de la reina María Antonieta y del conde de Artois y dio instrucciones para que varios\", \n        \"regimientos extranjeros leales se concentraran en París y Versailles. Al mismo tiempo, Necker fue nuevamente destituido.\", \n        \"El pueblo de París respondió con la insurrección ante estos actos de provocación; los disturbios comenzaron el 12 de julio\", \n        \"y las multitudes asaltaron y tomaron La Bastilla -una prisión real que simbolizaba el despotismo de los Borbones- el 14\", \n        \"de julio.\",\n        \"El 5 de octubre de 1789, las mujeres parisinas partieron desde los barrios obreros hacia la residencia real de Versailles,\", \n        \"este suceso dió comienzo a la revolución.\", \n        \"A fines de 1792 comenzó el proceso de Convención contra Luis XVI, quien fue juzgado y condenado a la guillotina por mayoría\",\n        \"de votos. El 21 de enero de 1793, Luis subió al cadalso, inconmovible hasta el último momento en el sentimiento\", \n        \"de su inocencia. La noticia de la muerte del rey produjo indignación en Inglaterra, la que despidió al embajador o\",  \n        \"representante francés. Francia contestó declarando la guerra a Inglaterra y a Holanda, su aliada.\")\n\npatron1 = re.findall(r\"\\b(\\d{1,})\\b\", str(texto))\nprint(patron1)\nfor match in re.finditer(r\"\\b(\\d{1,})\\b\", str(texto)):\n    print(match.group())\n\npatron2 = re.findall(\"[0-9]\", str(texto))\nprint(patron2)\n\n#DIFICULTAD EXTRA\nemail1 = \"ana@ana.es\"\nemail2 = \"-1.3@_dev.com\"\nemail3 = \"12345\"\n\npatron_email = r\"\\b[a-z0-9\\\"#$% &`*+-_.\\/|\\^\\{\\} ~]+[a-z0-9]@[a-z0-9-]+.[a-z]{2,}\\b\"  \n\nif re.match(patron_email, email1):\n    print(f\"{email1} válido\")\nelse:\n    print(f\"{email1} no válido\")\n\nif re.match(patron_email, email2):\n    print(f\"{email2} válido\")\nelse:\n    print(f\"{email2} no válido\")\n\nif re.match(patron_email, email3):\n    print(f\"{email3} válido\")\nelse:\n    print(f\"{email3} no válido\")        \n\ntlf1 = \"911203650\"\ntlf2 = \"541201459\"\ntlf3 = \"770777007\"\n\npatron_tlf = r\"\\b[6-9]+[0-9]{8}\\b\"\n\nif re.match(patron_tlf,tlf1):\n    print(f\"{tlf1} válido\")\nelse:\n    print(f\"{tlf1} no válido\")\n\nif re.match(patron_tlf,tlf2):\n    print(f\"{tlf2} válido\")\nelse:\n    print(f\"{tlf2} no válido\")\n\nif re.match(patron_tlf,tlf3):\n    print(f\"{tlf3} válido\")\nelse:\n    print(f\"{tlf3} no válido\")\n\n\nurl1 = \"http://www.hack.com\"\t\nurl2 = \"123.com\"\nurl3 = \"hola_!3.es\"\n\npatron_url = \"(http|https|ftp):\\/\\/[w]{3}\\.[a-z0-9]+\\.[a-z0-9]{2,}\"\n\nif re.match(patron_url,url1):\n    print(f\"{url1} válida\")\nelse:\n    print(f\"{url1} no válida\")\n\nif re.match(patron_url,url2):\n    print(f\"{url2} válido\")\nelse:\n    print(f\"{url2} no válida\")\n\nif re.match(patron_url,url3):\n    print(f\"{url3} válida\")\nelse:\n    print(f\"{url3} no válida\")\n\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/avcenal.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.\n\"\"\"\nimport re\n\ndef extract_numbers(one_string):\n    pattern = r\"\\d+\"\n    findall = re.findall(pattern,one_string)\n    final=\"\"\n    for element in findall:\n        final += element\n    return final\n\nprint(f\"Los números de la cadena \\\"4l3j4ndr0\\\" son: {extract_numbers(\"4l3j4ndr0\")}\")\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\nURL: ^https:\\\\\\\\(?:www\\.)*[a-zA-Z0-9]+(?:\\.[a-zA-Z0-9]+)*\\.(?:(?:com|net|org)|(?:es|ai|io))$\n\"\"\"\n\ndef email_validation(one_email):\n    pattern = r\"^[A-Za-z]+(?:(?:\\.|_)*[A-Za-z]*)*@[A-Za-z]+\\.(?:com|net|es|ai|ia|mx|co|uy|org)$\"\n    match = re.match(pattern,one_email)\n    if match == None:\n        return False\n    else:\n        return True\n\ndef spanish_mobile_phone_number_validation(one_phone):\n    pattern = r\"^\\+34(6|7)[0-9]{8}\"\n    match = re.match(pattern,one_phone)\n    if match == None:\n        return False\n    else:\n        return True\n    \ndef url_validation(one_url): #faltaría añadir los casos de http: que aún existen dominios no seguros\n    pattern = r\"^(?:https:\\\\\\\\(?:www\\.){0,1}|(?:https:\\\\\\\\){0,1}www\\.)[a-zA-Z0-9]+(?:\\.[a-zA-Z0-9]+)*\\.(?:(?:com|net|org|es|ai|io))$\"\n    match = re.match(pattern,one_url)\n    if match == None:\n        return False\n    else:\n        return True\n\n\nif (email_validation(\"avcenal@gmail.com\")):\n    print(\"El email avcenal@gmail.com es válido\")\nelse:\n    print(\"El email avcenal@gmail.com no es válido\")\n\nif (spanish_mobile_phone_number_validation(\"+34649116982\")):\n    print(\"El teléfono +34649116982 es válido\")\nelse:\n    print(\"El teléfono +34649116982 no es válido\")\n\nif (url_validation(\"https:\\\\\\\\google.es\")):\n    print(\"La url https:\\\\\\\\google.es es válida\")\nelse:\n    print(\"La url https:\\\\\\\\google.es no es válida\")\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/barrancus.py",
    "content": "import re\n\ndef serparacion(cadena):\n    print('{}'.format(cadena * 20))\n\ntelefono_listado = [\n    \"+34 601 789 234\",\n    \"+1 (555) 123-4567\",\n    \"+49-170/9876543\",\n    \"+52 81-22-33-44-55\",\n    \"+33 06.12.34.56.78\",\n    \"+86 (10) 8765 4321\",\n    \"+44 7700 900358\",\n    \"+91 987-654-3210\",\n    \"+39 333-1122334\",\n    \"+7 (495) 000-11-22\",\n    \"+61 401 555 121\",\n    \"+81 090-5432-1098\",\n    \"+54 11 4567 8901\",\n    \"+351 961/000-111\",\n    \"+46 70-123 45 67\",\n    \"+55 (21) 98765-4321\",\n    \"+41 79 123 45 67\",\n    \"+82 10-1234-5678\",\n    \"+972 54-888-9999\",\n    \"+27 82 123 4567\",\n    \"+1-555555555\"\n]\n\nemail_listado = [\n    \"usuario123@gmail.com\",\n    \"nombre.apellido@empresa.es\",\n    \"info-ventas@dominio.net\",\n    \"soporte@techsolutions.org\",\n    \"contacto.oficial@servicio.com.mx\",\n    \"j.perez_dev@agencia.io\",\n    \"proyecto_alfa@mailinator.com\",\n    \"laura.fernandez@universidad.edu\",\n    \"admin@misitio.blog\",\n    \"dev_testing_01@testserver.dev\",\n    \"martin-gomez-45@yahoo.es\",\n    \"recepcion@hotelparadise.com\",\n    \"inversiones.2025@finance.co\",\n    \"cliente-vip@premiumservices.us\",\n    \"marta.sanz@publicaciones.cat\",\n    \"notificaciones@appmovil.net\",\n    \"registro_temporal@tempmail.org\",\n    \"elena.rodriguez.s@otroservidor.net\",\n    \"secretaria.ejecutiva@consorcio.es\",\n    \"postmaster@localhost.localdomain\" # Un email técnico\n]\n\nurl_listado = [\n    \"https://www.ejemplo.com/pagina-principal\",\n    \"http://api.servidor.net/v1/data?id=12345\",\n    \"https://docs.organizacion.org/manual/guia-usuario.pdf\",\n    \"https://tienda.com/productos/categoria/item-001\",\n    \"https://blog.personal.dev/2025/11/mi-articulo-fantastico\",\n    \"ftp://descargas.backup.com/archivos/reporte_anual.zip\",\n    \"https://www.redsocial.es/perfil/nombre_usuario_1\",\n    \"https://support.software.net/faq/solucion-problema-x\",\n    \"http://localhost:8080/dashboard\",\n    \"https://universidad.edu/cursos/ingenieria/materia-a\",\n    \"https://images.storage.cloud/fotos/vacaciones/playa-05.jpg\",\n    \"https://noticias24.com/seccion/politica/\",\n    \"https://www.geolocalizacion.maps/lugar/@40.7128,-74.0060,12z\",\n    \"https://repositorio.codigo.git/proyecto-python/src/main.py\",\n    \"https://foro.comunidad.net/thread/500-pregunta-tecnica\",\n    \"https://catalogo.biblioteca.gov/libro/isbn-9781234567890\",\n    \"https://docs.api.empresa.com/endpoints/autenticacion\",\n    \"http://192.168.1.1/admin/configuracion\",\n    \"https://video.streaming.tv/pelicula/id-xyz789\",\n    \"https://www.ejemplo.com/contacto?asunto=consulta&prioridad=alta\"\n]\n\ntext = \"Esto es lo que podemos sacar en conclusión debido a que las 7 naciones están actualmente en guerra con un 33.33 de \\\npocentaje de porobavilidades de victoria para cada uno de estos 3 paises. 1) Alemania 2) Gran Bretaña 3) España.\"\n\ndef search_numbers(text: str) -> list:\n    findallmatch= re.findall(r'\\b\\d+\\.?\\d*\\b', text)\n    print(findallmatch)\n    for element in findallmatch:\n        print(element)\n\ndef search_phone_number(tlfnum):\n    tlf_patr = r'(\\+\\d{1,3})(-|/|\\s)?\\(?((\\d)(-|/|\\s|\\)\\s)?){9}'\n    for num in tlfnum:\n        tlf = re.match(tlf_patr, num)\n        if tlf != None:\n            print(tlf.group())\n\ndef search_email(mails):\n    mail_patr = r'.*@.*\\.\\w{2,11}'\n    for num in mails:\n        mail = re.match(mail_patr, num)\n        if mail != None:\n            print(mail.group())\n\ndef search_url(urls):\n    url_patr = r'http(s?)://.*\\..*\\..*/*'\n    for num in urls:\n        url = re.match(url_patr, num)\n        if url != None:\n            print(url.group())\n\n\ndef main():\n    print()\n    search_numbers(text)\n    serparacion('-:-:-:')\n    search_phone_number(telefono_listado)\n    serparacion('-:-:-:')\n    search_email(email_listado)\n    serparacion('-:-:-:')\n    search_url(url_listado)\n    serparacion('-:-:-:')\n\nmain()\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/cesar-ch.py",
    "content": "\"\"\"\n    * #16 EXPRESIONES REGULARES\n\"\"\"\n\nimport re\n\ntexto = \"Es texto contiene 5 numeros del 1 al 5: 1,2,3,4,5\"\nregex_numeros = r\"\\d+\"\nprint(\"Numeros encontrados:\", re.findall(regex_numeros, texto))\n\n\"\"\"\n    * DIFICULTAD EXTRA\n\"\"\"\n\nemail_correcto = \"abc@mail.com\"\nemail_incorrecto = \"abcmail.com\"\nregex_email = r\"^[a-zA-Z0-9._+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}$\"\n\nprint(\n    f\"{email_correcto} es un email válido? \",\n    bool(re.match(regex_email, email_correcto)),\n)\nprint(\n    f\"{email_incorrecto} es un email válido? \",\n    bool(re.match(regex_email, email_incorrecto)),\n)\n\nnumero_correcto = \"+51 987654321\"\nnumero_incorrecto = \"987654321\"\nregex_numero = r\"^\\+[0-9]{2}\\s[0-9]{9}$\"\n\nprint(\n    f\"{numero_correcto} es un número válido? \",\n    bool(re.match(regex_numero, numero_correcto)),\n)\nprint(\n    f\"{numero_incorrecto} es un número válido? \",\n    bool(re.match(regex_numero, numero_incorrecto)),\n)\n\nurl_correcta = \"https://retosdeprogramacion.com\"\nurl_incorrecta = \"retosdeprogramacion.com/\"\nregex_url = r\"^https?://(www\\.)?[a-zA-Z0-9-]+\\.[a-zA-Z]{2,}$\"\n\nprint(f\"{url_correcta} es una URL válida? \", bool(re.match(regex_url, url_correcta)))\nprint(\n    f\"{url_incorrecta} es una URL válida? \", bool(re.match(regex_url, url_incorrecta))\n)\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/cristianfloyd.py",
    "content": "# EJERCICIO:\n# Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n# creando una que sea capaz de encontrar y extraer todos los números\n# de un texto.\nimport re\n\n\ndef find_numbers(text: str) -> list:\n    return re.findall(r\"\\d+\", text)\n\ntexto = \"Este es el ejercicio 16 publicado 15/04/2024.\"\nprint(find_numbers(texto))\n\n\n#\n# DIFICULTAD EXTRA (opcional):\n# Crea 3 expresiones regulares (a tu criterio) capaces de:\n# - Validar un email.\n# - Validar un número de teléfono.\n# - Validar una url.\n\ndef validate_email(email: str) -> bool:\n    return bool(re.match(r\"^[\\w.+-]+@[\\w]+\\.[a-zA-Z]+$\", email))\n\ndef validate_phone(phone: str) -> bool:\n    return bool(re.match(r\"^\\+?[\\d\\s-]{3,}$\", phone))\n\ndef validate_url(url: str) -> bool:\n    return bool(re.match(r\"^http[s]?://(www.)?[\\w]+\\.[a-zA-Z]{2,}$\", url))\n\nemail = \"test@test.com\"\nphone = \"+54-9-011-4223-5656\"\nphone2 = \"+54 9 011 4223 5656\"\nurl = \"https://www.test.com\"\n\nprint(validate_email(email))\nprint(validate_phone(phone))\nprint(validate_phone(phone2))\nprint(validate_url(url))\n\n\"\"\"\nPatrones comunes para validaciones:\n\n- ^  : Inicia la expresión.\n- \\d : Un dígito (0-9).\n- \\w : Un carácter alfanumérico (letras, números, guión bajo).\n- \\s : Espacio en blanco.\n- [] : Define un conjunto de caracteres (ejemplo: [a-z] para letras minúsculas).\n- () : Define un grupo de caracteres (ejemplo: (a-z) para letras minúsculas).\n- *  : 0 o mas repeticiones.\n- +  : 1 o mas repeticiones.\n- ?  : 0 o una repeticion.\n- .  : cualquier caracter (excepto salto de linea).\n- $  : Termina la expresión.\n\"\"\""
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/danielhdzr.py",
    "content": "# #16 EXPRESIONES REGULARES\n#### Dificultad: Media | Publicación: 15/04/24 | Corrección: 22/04/24\n\n## Ejercicio\n\n\n'''EJERCICIO:\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.'''\n\nimport re\ndef main():\n\n    def validar_email(email) -> bool:\n        regex = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$'\n        return bool (re.match(regex, email))\n\n    # Ejemplo de uso\n    print(validar_email(\"ejemplo@dominio.com\"))  # True\n    print(validar_email(\"email_incorrecto@.com\"))  # False\n\n    def validar_telefono(telefono) -> bool:\n        regex = r'^(\\+?\\d{1,3})?[-.\\s]?\\(?\\d{1,4}\\)?[-.\\s]?\\d{1,4}[-.\\s]?\\d{1,9}$'\n        return bool (re.match(regex, telefono))\n\n    # Ejemplo de uso\n    print(validar_telefono(\"+1-800-555-1234\"))  # True\n    print(validar_telefono(\"555-1234\"))  # True\n    print(validar_telefono(\"12345\"))  # False\n\n    def validar_url(url) -> bool:\n        regex = r'^(https?:\\/\\/)?([a-zA-Z0-9.-]+)\\.([a-zA-Z]{2,})([\\/\\w .-]*)*\\/?$'\n        return bool (re.match(regex, url))\n\n    # Ejemplo de uso\n    print(validar_url(\"https://www.ejemplo.com\"))  # True\n    print(validar_url(\"http://ejemplo.com/path/to/resource\"))  # True\n    print(validar_url(\"www.ejemplo\"))  # False\nif __name__==\"__main__\":\n    main()\n\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/davidrguez98.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\n */ \"\"\"\n\nimport re\n\n#EJERCICIO\n\ndef find_numbers(text: str) -> list:\n    return re.findall(r\"[0-9]+\", text)\n\nprint(find_numbers(\"Este es el ejercicio 16.\"))\n\n#DIFICULTAD EXTRA\n\ndef email_check(email: str) -> bool:\n    return bool(re.match(r\"^[\\w.+-]+@[\\w]+\\.[a-zA-Z]+$\", email))\n\nprint(email_check(\"ropeda98@gmail.com\"))\nprint(email_check(\"ropeda98@gmailcom\"))\n\ndef phone_number_check(phonenumber: str) -> bool:\n    return bool(re.match(r\"^[+]?[\\d\\s]{3,}$\", phonenumber))\n\nprint(phone_number_check(\"444444444\"))\nprint(phone_number_check(\"444 44 44 44\"))\nprint(phone_number_check(\"+44 4444444\"))\nprint(phone_number_check(\"4\"))\n\ndef url_check(url: str) -> bool:\n    return bool(re.match(r\"^http[s]?://(www.)?[\\w]+\\.[a-zA-Z]+$\", url))\n\nprint(url_check(\"https://klajsdlkas.com\"))\nprint(url_check(\"http://klajsdlkas.com\"))\nprint(url_check(\"http://www.klajsdlkas.com\"))\nprint(url_check(\"http://klajsdlkas\"))"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/didacdev.py",
    "content": "import re\n\ntext = '''\nEn un día soleado de abril, caminé 3 kilómetros por un sendero montañoso. \nLuego, compré 2 manzanas y 1 naranja en la tienda del pueblo. \nDespués, tomé el autobús número 45 de regreso a casa.\n'''\n\n\ndef main():\n    get_numbers(text)\n    check_email(\"diego@gmail.com\")\n    check_tlf_number(\"645324565\")\n    check_URL(\"https://web.didacdev.es/fotos/foto\")\n\n\ndef get_numbers(text: str):\n    regex = r\"\\d+\"\n    findall = re.findall(regex, text)\n    print(findall)\n\n\ndef check_email(email: str):\n    regex = r\"\\w+@\\w+\\.(es|com)\"\n    search = re.search(regex, email)\n    print(search)\n\n\ndef check_tlf_number(number: str):\n    regex = r\"^6\\d{8}$\"\n    search = re.search(regex, number)\n    print(search)\n\n\ndef check_URL(URL: str):\n    regex = r\"^(http://|https://)?[a-z0-9]+(\\.[a-z0-9]+)*\\.[a-z]{2,5}(/.*)$\"\n    search = re.search(regex, URL)\n    print(search)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/duendeintemporal.py",
    "content": "#16 { Retos para Programadores } EXPRESIONES REGULARES\n\n# Bibliography reference\n# Professional JavaScript for web developers by Matt Frisbie [Frisbie, Matt] (z-lib.org)\n#Python Notes for Professionals. 800+ pages of professional hints and tricks (GoalKicker.com) (Z-Library)\n# Additionally, I use GPT as a reference and sometimes to correct or generate proper comments.\n\n\"\"\"\n * EJERCICIO:\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\n \n\"\"\"\n\nimport re\nimport time\n\n# Short for print()\nlog = print\n\n# Simulate the loading of a web page\nlog('Retosparaprogramadores #16')\ntime.sleep(2)  # Simulate a delay before showing the alert\nlog('Retosparaprogramadores #16. Please open the Browser Developer Tools.')\n\n# Define a pattern and flags\npattern0 = 'abc'\nflags = re.IGNORECASE | re.MULTILINE  # Global and case-insensitive\n\n# Create a regular expression using the re.compile() function\nregex = re.compile(pattern0, flags)\n\nlog(regex)  # Output the regex object\n\ntext = \"time: 08:07:06\"\npattern1 = r'(time(:)?)? ?([01][0-9]|2[0-3])([:/-])([0-5][0-9])\\4([0-5][0-9])'\n\n# Explanation of the regular expression:\n# - (time(:)?) : Optionally matches the word \"time\" followed by an optional colon (:).\n# - ? : Matches an optional space.\n# - ([01][0-9]|2[0-3]) : Matches the hour, allowing values from 00 to 23.\n# - ([:/-]) : Matches one of the characters :, /, or - and captures it for later use.\n# - ([0-5][0-9]) : Matches the minutes (00 to 59).\n# - \\4 : References the fourth captured group, which is the separator (it must be the same as used between the hour and the minutes).\n# - ([0-5][0-9]) : Matches the seconds (00 to 59).\n\nmatches1 = re.search(pattern1, text)\n\nif matches1:\n    log(matches1.start())  # 0\n    log(matches1.string)    # time: 08:07:06\n    log(matches1.group(0))  # time: 08:07:06\n    log(matches1.group(1))  # time:\n    log(matches1.group(2))  # :\n\npattern = r'[0-9]'\nmatches = re.search(pattern, text)\nif matches:\n    log(matches.group())  # '0'\n\nmatches3 = re.findall(pattern, text)\nif matches3:\n    log(matches3)  # ['0', '8', '0', '7', '0', '6']\n\nif matches3:\n    log(matches3[0])  # 0\n    log(matches3[1])  # 8\n    log(matches3[2])  # 0\n\npattern2 = r'\\d'\nmatches2 = re.search(pattern2, text)\nif matches2:\n    log(matches2.group())  # '0'\n\nmatches4 = re.findall(pattern2, text)\nif matches4:\n    log(matches4)  # ['0', '8', '0', '7', '0', '6']\n\n# exec: Returns the first match and can be used in a loop to find all matches.\n# findall: Returns a list with all matches in a more direct and straightforward way.\n\n# Extra Difficulty Exercise:\n\ndef validate_tlf(num):\n    if not re.match(r'^\\d{11}$', str(num)):\n        log(\"Invalid telephone number. Must be a numeric value and have 11 digits.\")\n        return False\n    return True\n\ndef validate_email(email):\n    email_regex = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$'\n    if not re.match(email_regex, email):\n        log(\"Invalid email address\")\n        return False\n    return True\n\ndef validate_url(url):\n    url_regex = r'^(https?:\\/\\/)?([a-zA-Z0-9.-]+)(:[0-9]{1,5})?(\\/[^\\s]*)?$'\n    if not re.match(url_regex, url) or (not url.startswith('http://') and not url.startswith('https://')):\n        log(\"Invalid URL\")\n        return False\n    return True\n\nnum1 = 1562737848\nnum2 = 34587452387\nemail1 = 'kamsutraniko@proton.me'\nemail2 = 'kat@hotgirl.net'\nurl1 = 'http://palnetaneurodiverso.org'\nurl2 = 'https://moebius.org'\nurl3 = 'something.com'\nurl4 = 'gato'\n\nlog(validate_tlf(num1))  # Invalid telephone number. Must be a numeric value and have 11 digits. False\nlog(f'Is a valid tlf: {validate_tlf(num2)}')  # Is a valid tlf: True\nlog(f'Is a valid email: {validate_email(email1)}')  # Is a valid email: True\nlog(f'Is a valid email: {validate_email(email2)}')  # Is a valid email: True\nlog(f'Is a valid URL: {validate_url(url1)}')        # Is a valid URL: True\nlog(f'Is a valid URL: {validate_url(url2)}')        # Is a valid URL: True\nlog(f'Is a valid URL: {validate_url(url3)}')        # Invalid URL & Is a valid URL: False\nlog(f'Is a valid URL: {validate_url(url4)}')        # Invalid URL & Is a valid URL: False\n\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/fborjalv.py",
    "content": "import re\n\n\n\n\n\"\"\"\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.\n *\n\"\"\"\n\n\n\n\ntext = \"Este es el ejercicio 16 publicado 15/04/2024\"\n\n\ndef find_numbers(text):\n    return re.findall(r\"\\d+\", text)\n\nprint(find_numbers(text))\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\n */\n\n\"\"\"\n\ndef validate_email(email):\n    return bool(re.match(r\"^[\\w.+-]+@[\\w]+\\.[a-zA-Z]+$\", email)) \n\n\nprint(validate_email(\"fborjalv@gmail.com\"))\n\ndef validate_phone_number(phone):\n    return bool(re.match(r\"^\\+?[\\d\\s]{3,}$\", phone))\n\nprint(validate_phone_number(\"+34 679200199\"))\n\ndef validate_url(url):\n    return bool(re.match(r\"^http[s]?://(www.)?[\\w]+\\.[a-zA-Z]+$\", url))\n\nprint(validate_url(\"https://mouredev.es\"))"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/garos01.py",
    "content": "import re\n\ntexto = \"Hoy es 24 de abril de 2024. El número de teléfono es 555-123-4567 y el precio es $99.99.\"\n\nnumeros_encontrados = re.findall(r\"\\d+\", texto)\n\nprint(\"Números encontrados:\", numeros_encontrados)\n\n\n# Ejercicio extra\n\n\ndef validar_email(email):\n    # Expresión regular para validar email\n    patron_email = r\"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$\"\n    return re.match(patron_email, email) is not None\n\n\ndef validar_telefono(telefono):\n    # Expresión regular para validar número de teléfono\n    patron_telefono = r\"^\\(?\\d{3}\\)?[-.\\s]?\\d{3}[-.\\s]?\\d{4}$\"\n    return re.match(patron_telefono, telefono) is not None\n\n\ndef validar_url(url):\n    # Expresión regular para validar URL\n    patron_url = r\"^(http|https):\\/\\/[\\w\\-_]+(\\.[\\w\\-_]+)+([\\w\\-\\.,@?^=%&:/~\\+#]*[\\w\\-\\@?^=%&/~\\+#])?$\"\n    return re.match(patron_url, url) is not None\n\n\n# Ejemplos\nemail = \"ejemplo@dominio.com\"\ntelefono = \"(555) 123-4567\"\nurl = \"https://www.ejemplo.com\"\n\nprint(\"Email válido:\", validar_email(email))\nprint(\"Teléfono válido:\", validar_telefono(telefono))\nprint(\"URL válida:\", validar_url(url))\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/ggilperez.py",
    "content": "# 16 Regex\nimport re\n\npattern = r\"\\d+\"\nrand_string = \"qwe7865qwe978123087qwe\"\nprint(f\"{rand_string = }\")\n\n# Match with regex\nmatches = re.findall(pattern, rand_string)\nfor match in matches:\n    print(match)\n\n# Extra\nemail_pattern = r\"^\\S+@\\S+\\.\\S+$\"\nphone_pattern = r\"^(\\+\\d{1,3})? ?\\d{1,4}[ -]?\\d{1,4}[ -]?\\d{1,4}$\"\nurl_pattern = r\"^(https:\\/\\/www\\.|http:\\/\\/www\\.|https:\\/\\/|http:\\/\\/)?[a-zA-Z0-9]{2,}(\\.[a-zA-Z0-9]{2,})(\\.[a-zA-Z0-9]{2,})?$\"\n\nprint(bool(re.match(email_pattern, \"ggilperezalcazar@gmail.com\")))\nprint(bool(re.match(phone_pattern, \"695847123\")))\nprint(bool(re.match(url_pattern, \"python.org\")))\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/girngoma.py",
    "content": "import re\n\n\"\"\"\nEjercicio\n\"\"\"\n\ndef find_numbers(cadena:str)->list:\n    return re.findall(r\"\\d+\", cadena)\n\nprint(find_numbers(\"papa1hermano2si1no2\"))\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/hectorio23.py",
    "content": "#! /usr/bin/python3\nimport re\n\n'''\nEJERCICIO:\nUtilizando tu lenguaje, explora el concepto de expresiones regulares,\ncreando una que sea capaz de encontrar y extraer todos los números\nde un texto.\n\n* DIFICULTAD EXTRA (opcional):\n* Crea 3 expresiones regulares (a tu criterio) capaces de:\n* - Validar un email.\n* - Validar un número de teléfono.\n* - Validar una url.\n'''\n\n###################################################\n############ ZONA DE REGEX PATTERNS ###############\n###################################################\n\nemail_regex = r\"^(\\w+)@([a-z]{3,}\\.[a-z]{,3})$\"\nphone_number_regex = r\"^(\\+\\d{2,3})\\s(\\d{3})\\s(\\d{3})\\s(\\d{2})\\s(\\d{2})\" # +54 339 450 85 56 \nurl_regex = r\"^https?:\\/\\/([a-zA-Z0-9]*\\.)?[a-zA-Z0-9]*\\.([a-zA-Z]{3})(\\.[a-zA-Z]{2,3})?\\/?\"\n\n###################################################\n################ ZONA EJEMPLOS ####################\n###################################################\n\ntexto_legible = \"E5n e6l si5g7ui8e956nte tex8to s9e 0t4ien4e que3 extr3aer to3dos lo0s nume3ro0s pa2ra q4ue s8e7a l9e0gi9b0le\"\n\ndef extract_numbers(sValue = '') -> str:\n    '''extract_numbers\n    Extrae los numeros de una cadena de caracteres\n\n    Params\n    - sValue: Representa el valor de la cadena para extraer los numeros \n    '''\n    # Se ejecuta siempre hasta que deje de encontrar coincidencias dentro de la \n    # cadena pasada a traves del parámetro sValue\n    while True:\n        # Comprueba si existe un numero dentro de la cadena\n        value = re.search(r'\\d+', sValue)\n        \n        # En caso de no existir un numero, solo se retorna la cadena\n        if not value:\n            return sValue\n        \n        # De lo contrario, se extrae los numeros de sValue  \n        sValue = sValue[0:value.span()[0]] + sValue[value.span()[1]:]\n\n    # Cuando ya no existan coincidencias, se retorna la cadena de caracteres limpia\n    return sValue\n\n\ndef verify(pattern, tipo, sValue = '') -> str:\n    ''' verify\n    Lo unico que hace es comparar cadenas de caracteres con un patron regex.\n    retorna una secuancia de caracteres distinta en base a la coondicion.\n\n    Params\n    - pattern -> patron regex\n    - tipo -> a lo que hace referencia sValue\n    - sValue -> la cadena de caracteres con la que se opera\n    '''\n\n    # Compara la cadena de caracteres con el patron, en caso de no coincidir, \n    # de imprime un mensaje que hace alusion a eso.\n    if not re.match(pattern, sValue):\n        return f\"[-] El valor [ { sValue } ] no corresponde a un { tipo }\"\n\n    # En caso de coincidir\n    return f\"[+] El valor [ { sValue } ] corresponde a un { tipo }\"\n\nprint(\"----- EJERCICIO -----\\n\")\nprint(f\"Cadena cruda: { texto_legible }\")\nprint(f\"Cadena sin numeros: { extract_numbers(texto_legible) }\\n\\n\")\n\n\n\nprint(\"----- EJERCICIO EXTRA -----\")\n###################################################\n################# EMAIL CHECK #####################\n###################################################\nprint(\"*********************** EMAIL CHECK *********************************\")\nprint(verify(email_regex, 'e-mail', 'hectorino2789@gmail.com'))\nprint(verify(email_regex, 'e-mail', 'quesobadas@outlook.es'))\nprint(verify(email_regex, 'e-mail', 'nocorresponde a unema%il@gmaildjfj.completo'))\n\n\n###################################################\n############ PHONE NUMBER CHECK ###################\n###################################################\nprint(\"\\n*********************** NUMBER CHECK *********************************\")\nprint('Para que un numero sea valido, tiene que estar escrito de la siguiente forma: +52 449 369 52 34')\nprint(verify(phone_number_regex, 'numero de telefono', '+52 449-369-52-34'))\nprint(verify(phone_number_regex, 'numero de telefono', '+52 449 369 52 34'))\nprint(verify(phone_number_regex, 'numero de telefono', '449 369 52 34'))\n\n\n###################################################\n################### URL CHECK #####################\n###################################################\nprint(\"\\n*********************** URL CHECK *********************************\")\nprint(verify(url_regex, \"url\", \"https://github.com/hectorio23\"))\nprint(verify(url_regex, \"url\", \"outlook:///github.com\\hectorio23\"))\nprint(verify(url_regex, \"url\", \"127.0.0.1:89/path/otherpath\"))\nprint(verify(url_regex, \"url\", \"https://apple.com\"))\n\n\n#################################################################\n######################### OUTPUT ################################\n#################################################################\n# ----- EJERCICIO -----\n\n# Cadena cruda: E5n e6l si5g7ui8e956nte tex8to s9e 0t4ien4e que3 extr3aer to3dos lo0s nume3ro0s pa2ra q4ue s8e7a l9e0gi9b0le\n# Cadena sin numeros: En el siguiente texto se tiene que extraer todos los numeros para que sea legible\n\n\n# ----- EJERCICIO EXTRA -----\n# *********************** EMAIL CHECK *********************************\n# [+] El valor [ hectorino2789@gmail.com ] corresponde a un e-mail\n# [+] El valor [ quesobadas@outlook.es ] corresponde a un e-mail\n# [-] El valor [ nocorresponde a unema%il@gmaildjfj.completo ] no corresponde a un e-mail\n\n# *********************** NUMBER CHECK *********************************\n# Para que un numero sea valido, tiene que estar escrito de la siguiente forma: +52 449 369 52 34\n# [-] El valor [ +52 449-369-52-34 ] no corresponde a un numero de telefono\n# [+] El valor [ +52 449 369 52 34 ] corresponde a un numero de telefono\n# [-] El valor [ 449 369 52 34 ] no corresponde a un numero de telefono\n\n# *********************** URL CHECK *********************************\n# [+] El valor [ https://github.com/hectorio23 ] corresponde a un url\n# [-] El valor [ outlook:///github.com\\hectorio23 ] no corresponde a un url\n# [-] El valor [ 127.0.0.1:89/path/otherpath ] no corresponde a un url\n# [+] El valor [ https://apple.com ] corresponde a un url"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/hozlucas28.py",
    "content": "import re\nfrom typing import TypedDict\n\n\"\"\"\n    Regular expressions...\n\"\"\"\n\nprint(\"Regular expressions...\")\n\nTEXT: str = \"¡Hola Mundo! Hoy es 15/04/2024. Quedan 263 días para terminar el año 2024.\"\nnumbers: str = \"\".join(element for element in re.findall(r\"[0-9]\", TEXT))\n\nprint(f\"\\n{TEXT = }\")\n\nprint(f\"\\nNumbers inside `TEXT` --> {numbers}\")\n\nprint(\n    \"\\n# ---------------------------------------------------------------------------------- #\\n\"\n)\n\n\"\"\"\n    Additional challenge...\n\"\"\"\n\nprint(\"Additional challenge...\")\n\nRegularExpressions = TypedDict(\n    \"RegularExpressions\",\n    {\n        \"email\": str,\n        \"phone_number\": str,\n        \"url\": str,\n    },\n)\n\nregular_expressions: RegularExpressions = {\n    \"email\": r\"^[a-zA-Z0-9]*@[a-zA-Z0-9]*\\.[a-zA-Z]{2,3}$\",\n    \"phone_number\": r\"^\\+[0-9]{1,4} [0-9]{4} [0-9]{4}$\",\n    \"url\": r\"^https?://([a-zA-Z0-9]*\\.)?[a-zA-Z0-9]*\\.[a-zA-Z]{2,3}/?$\",\n}\n\nEMAILS: list[str] = [\n    \"hozlucas28@gmail.com\",\n    \"hozlucas28@dev.com\",\n    \"hozlucas-28@hotmail.com\",\n    \"hozlucas28@melí.com\",\n    \"hozlucas28@edu.com\",\n]\n\nPHONE_NUMBERS: list[str] = [\n    \"+12 3456 7890\",\n    \"+1 1234 5890\",\n    \"+1234 1234 5690\",\n    \"+123456789\",\n    \"+123456789 1234 5678\",\n]\n\nURLS: list[str] = [\n    \"https://www.example.cóm\",\n    \"http://example.com\",\n    \"https://subdomain.example.com\",\n    \"http://www.example.c2.uk\",\n    \"https://www.example.org\",\n]\n\nprint(\"\\nEmails...\")\nfor email in EMAILS:\n    is_valid: bool = len(re.findall(regular_expressions[\"email\"], email)) > 0\n    print(f\"Is '{email}' a valid email? {is_valid}\")\n\nprint(\"\\nPhone numbers...\")\nfor phone_number in PHONE_NUMBERS:\n    is_valid: bool = (\n        len(re.findall(regular_expressions[\"phone_number\"], phone_number)) > 0\n    )\n    print(f\"Is '{phone_number}' a valid phone number? {is_valid}\")\n\nprint(\"\\nUrls...\")\nfor url in URLS:\n    is_valid: bool = len(re.findall(regular_expressions[\"url\"], url)) > 0\n    print(f\"Is '{url}' a valid url? {is_valid}\")\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/idiegorojas.py",
    "content": "# Regex\n\n\"\"\"\nEs una herramienta para trabjar con texto\nSe trabaja a traves del modulo 'Re'\n    Permite buscar, coincidir y manipular cadenas de texto\nSe usan para:\n    * Validar formatos (correos electronicos o numeros de telefono)\n    * Extraer info especifica de un texto (fechas o palabras clave)\n    * Reemplazar partes de un texto\n\"\"\"\n\n# Importamos el modulo re\nimport re\n\n\"\"\"\nMetodos clave:\n    * re.search() Busca la primera coincidencia del patron del texto\n    * re.match() Verifica si el patron coincide al inicio del texto\n    * re.findall() Devuelve todas las coincidencias en una lista\n    * re.sub() Reemplaza coincidencias por otro texto\n\"\"\"\n\n# Ejercicio:\ntexto = 'Mi numero es 1234 y el tuyo es 5678'\npatron = r'\\d+' # '\\d+' uno o mas digitos\nnumeros = re.findall(patron, texto)\nprint(numeros)\n\n\"\"\"\nCaracteres comunes es regex\n    * .: cualquier caracter (excepto salto de linea)\n    * *: 0 o mas repeticiones\n    * +: 1 o mas repeticiones\n    * ?: 0 o una repeticion\n    * \\d: Un dígito (0-9).\n    * \\w: Un carácter alfanumérico (letras, números, guión bajo).\n    * \\s: Espacio en blanco.\n    * []: Define un conjunto de caracteres (ejemplo: [a-z] para letras minúsculas).\n\"\"\"\n\n# Validar un email\nemail = 'usuario@dominio10.com'\npatron = r\"^[a-zA-Z0-9_.+-]+@[a-zA-Z]+\\.[a-zA-Z]+$\"\nif re.match(patron, email):\n    print('Email valido')\nelse:\n    print('Email invalido')\n\n# Validar telefono\ntelefono = '+99(534)547-5561'\npatron = r'\\+[0-9]+\\([0-9]+\\)[0-9]+\\-[0-9]'\nif re.match(patron, telefono):\n    print('Numero valido')\nelse:\n    print('Numero invalido')\n\n# Validar una url\nurl = 'http://sample.info/?insect=fireman&porter=attraction#cueva'\npatron = r'^http[s]?://(www\\.)?[\\w-]+\\.[a-zA-Z]{2,}$'\nif re.match(patron, url):\n    print('Url valida.')\nelse:\n    print('Url invalida.')"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/ignaciovihe.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.\n\"\"\"\n\nimport re\n\ntext = \"Hola, mi nonbre es Pedro y tengo 25 años. Mi direccción es calle falsa 12-3. Mi número favorito es el 7. mi Perro tien3 12 años\"\npattern = r\"\\d+\"\nprint(re.findall(pattern, text))\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\n\"\"\"\n\ndef validate_data():\n    email_pattern = r\"^[\\w.+-]+@[\\w&-]+\\.[a-zA-z]{2,}$\"\n    telefon_pattern = r\"^\\+?[\\d\\s]{3,}$\"\n    url_pattern = r\"^http[s]?://(?:www\\.)?[\\w-]+\\.[a-zA-Z]{2,}$\" # Usa grupo no capturador\n\n    while True:\n        data = input(\"Introduce un email, un telefono o una url para validar, o 'salir' para terminar: \")\n        if data == \"salir\":\n            break\n        if re.match(email_pattern, data):\n            print(\"Email valido\")\n            continue\n        elif re.match(telefon_pattern, data):\n            print(\"Telefono válido\")\n            continue\n        elif re.match(url_pattern, data):\n            print(\"Url válido\")\n            continue\n        else:\n            print(\"Formato invalido\")\n            continue\n\nvalidate_data()\n\n\n\n\n\n\n\"\"\"Conceptos explorados adicionales\"\"\"\n\nprint(\"-----------------re.search()----------------------\")\ntexto = \"Hola, me gustan los gatos y los perros.\"\npatron = r\"g[aeiou]tos\"  # Encuentra \"gatos\" pero no \"g1tos\"\n\nresultado = re.search(patron, texto)\n\nif resultado:\n    print(f\"Encontrado: {resultado.group()}\")  # Devuelve la palabra encontrada\nelse:\n    print(\"No encontrado.\")\n\n\nprint(\"-----------------re.findall()----------------------\")\ntexto = \"gato perro Python calle paraguas\"\npatron = r\"\\b[Pp]\\w+\"\n\nresultado = re.findall(patron, texto)\n\nif resultado:\n    print(\"¡Coincidencia encontrada!\")\n    print(resultado)\nelse:\n    print(\"No se encontró la palabra.\")\n\n\nprint(\"-----------------re.sub()----------------------\")\ntexto = \"Mi número es 123-456-7890\"\npatron = r\"\\d\"  # Cualquier número\n\nnuevo_texto = re.sub(patron, \"X\", texto)\n\nprint(nuevo_texto)\n\n\nprint(\"-----------------Grupos y Capturas----------------------\")\ntexto = \"Teléfono: (123) 456-7890\"\npatron = r\"\\((\\d{3})\\) (\\d{3})-(\\d{4})\" #Si quiero aplicar un grupo no capturador --> (?:)\n\nresultado = re.search(patron, texto)\n\nif resultado:\n    print(\"Código de área:\", resultado.group(1))\n    print(\"Primera parte:\", resultado.group(2))\n    print(\"Segunda parte:\", resultado.group(3))\n    print(resultado.groups())\nelse:\n    print(\"NO se encontro el patrón\")\n\n\nprint(\"-----------------re.match()----------------------\")\nemail = \"correo@example.com\"\npatron = r\"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z]{2,}$\"\n\nif re.match(patron, email):\n    print(\"Correo válido\")\nelse:\n    print(\"Correo inválido\")\n\n\nprint(\"-----------------groupdict()----------------------\")\ntexto = \"Mi email es juan.perez@example.com\"\npatron = r\"(?P<usuario>[a-zA-Z0-9_.+-]+)@(?P<dominio>[a-zA-Z0-9-]+\\.[a-zA-Z]{2,})\"\n\nresultado = re.search(patron, texto)\n\nif resultado:\n    print(resultado.groupdict())"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/isilanes.py",
    "content": "import re\n\nTEXT = \"\"\"\nThis is 1 funny text with 2 or 3 numbers, but not 1000 numbers,\nbecause more than 999.9 numbers are too much. Numb3rs c4n appear 1ns1de\nwords, and be fl0.4ts\"\"\"\nEXPECTED_NUMBERS = [1, 2, 3, 1000, 999.9, 3, 4, 1, 1, 0.4]\n\n\ndef extract_numbers(text: str) -> list[int | float]:\n    \"\"\"\n    Given a string 'text', extract and return all numbers within it,\n    be they integer or float.\n\n    Args:\n        text (str):\n            String where numbers are to be found.\n\n    Returns:\n        List of numbers found in input text. Integers will appear\n        as integers, and floats as floats.\n    \"\"\"\n    pattern = re.compile(r\"\\d+\\.?\\d*\")\n    match = pattern.findall(text) or []\n    return [float(n) if \".\" in n else int(n) for n in match]\n\n\ndef main(text: str, expected: list[int | float]) -> None:\n    \"\"\"\n    Given a string 'text' and a list of expected numbers 'expected',\n    make sure that 'text' contains all numbers in 'expected', and\n    only those, in that order.\n\n    Args:\n        text (str):\n            String where numbers are to be found.\n        expected (list of ints and floats):\n            List of numbers expected to be found in input string.\n\n    Returns:\n        Nothing.\n    \"\"\"\n    print(\"==== MAIN ====\")\n    numbers = extract_numbers(text)\n    assert numbers == expected\n    print(\"Todos los números se extrajeron.\")\n    print(\"Texto:\", text)\n    print(\"Números:\", numbers)\n\n\ndef is_email(candidate: str) -> bool:\n    \"\"\"\n    Return True if string 'candidate' is an e-mail. False, otherwise.\n\n    NOTE: the REAL validation of an email string is quite complicated,\n          because obscure rules apply (see RFC 5322 and others). We are\n          going to use an arbitrary subset of those rules:\n          - the address must consist of two strings separated by an '@' sign: <local>@<domain>\n          - the <domain> part must contain either 2 or 3 fragments, separated by a dot: <a>.<b> OR <a>.<b>.<c>\n          - the <a> and <b> parts (and <c> if present) of <domain> must consist only on 'word'\n            characters: upper or lower case a to z (which is further complicated by locales, and we will\n            gracefully ignore this problem), digits, dashes and underscores.\n          - the <local> part of the address can contain 'word' characters (see previous point), PLUS:\n             - dots, EXCEPT no two dots together, and can not start or end with a dot.\n             - plus sign '+'. We will apply the same limitations to the plus sign as we do to the dot.\n          - the <local> part could theoretically contain parentheses, curly and square brackets, and some\n            other special characters, such as '&' or '='. We will not accept such nonsense, for the sake\n            of simplicity, and also because WTF.\n\n\n    Args:\n        candidate (str):\n            String what will be checked for email validity.\n\n    Returns:\n        True if 'candidate' is a valid e-mail, False otherwise.\n    \"\"\"\n    pattern = re.compile(r\"[\\w-]+([.+]?[\\w-]+)*@\\w+(\\.\\w+){1,2}$\")\n\n    return bool(pattern.match(candidate))\n\n\ndef is_phone_number(candidate: str) -> bool:\n    \"\"\"\n    Return True if string 'candidate' is a valid phone number, False otherwise.\n\n    As with emails, this is more complex than is apparent. We are going to use\n    a set of arbitrary custom rules:\n    - the string can contain any number of spaces, that will be ignored.\n    - the string will only contain spaces and digits. Optionally, it can start with a plus sign.\n    - the string will strictly contain 9, 10 or 11 digits.\n\n    Args:\n        candidate (str):\n            The candidate string to be checked.\n\n    Returns:\n        True if input string is a valid phone number, False otherwise.\n    \"\"\"\n    pattern = re.compile(r\"\\+? *(\\d *){9,11}$\")\n\n    return bool(pattern.match(candidate))\n\n\ndef is_url(candidate: str) -> bool:\n    \"\"\"\n    Return True if string 'candidate' is a valid URL, False otherwise.\n\n    As with the others, the real, comprehensive, rules are far too complex.\n    I will use a very simple set of rules:\n    - string must be formed by three sections <pre>://<main>/<rest>\n    - <pre> must be literally either 'http' or 'https'\n    - <main> must be formed by two or more strings separated by a dot: <a1>.<a2> OR <a1>.<a2>.<a3>, etc\n    - sections <ai> can contain only 'word' characters: upper and lowercase a to z, digits, dashes and\n      underscores. Probably others are allowed in reality, but not in MY function.\n    - <rest> can be literally anything, we are not even going to bother checking.\n    - if <rest> is not present, the / preceding it can be omitted.\n    \"\"\"\n    pattern = re.compile(r\"https?://\\w+(\\.\\w+)+(/.*)?\")\n\n    return bool(pattern.match(candidate))\n\n\ndef extra():\n    print(\"==== EXTRA ====\")\n    email_candidates = (\n        (\"yo@gmail.com\", True),\n        (\"yo@gmail.co.uk\", True),\n        (\"tú@gmail.co.uk\", True),\n        (\"tú@gmail.co.uk.doc\", False),\n        (\"@gmail.com\", False),\n        (\"something@gmail\", False),\n        (\"something.gmail.com\", False),\n        (\"something77@gmail.com\", True),\n        (\"SomeThing77@gmaIl.cOm\", True),\n        (\"something.77@gmail.com\", True),\n        (\"something.7.7@gmail.com\", True),\n        (\"something..77@gmail.com\", False),\n        (\"something-77@gmail.com\", True),\n        (\"something_77@gmail.com\", True),\n        (\"something+77@gmail.com\", True),\n        (\".something77@gmail.com\", False),\n        (\"something77.@gmail.com\", False),\n    )\n    for email_candidate, expected in email_candidates:\n        print(f\"Is '{email_candidate}' a valid email?: {expected}\")\n        assert is_email(email_candidate) is expected\n\n    phone_candidates = (\n        (\"12345678\", False),\n        (\"123456789\", True),\n        (\"1234567890\", True),\n        (\"12345678901\", True),\n        (\"123456789012\", False),\n        (\"+12345678901\", True),\n        (\"+ 12 3 4 567 89 01  \", True),\n    )\n    for phone_candidate, expected in phone_candidates:\n        print(f\"Is '{phone_candidate}' a valid phone number?: {expected}\")\n        assert is_phone_number(phone_candidate) is expected\n\n    url_candidates = (\n        (\"http://google.com\", True),\n        (\"https://google.com\", True),\n        (\"https://google.com/cosas\", True),\n        (\"http//google.com\", False),\n        (\"http:/google.com\", False),\n        (\"http://google\", False),\n        (\"https://google.co.uk\", True),\n        (\"https://maps.google.co.uk\", True),\n    )\n    for url_candidate, expected in url_candidates:\n        print(f\"Is '{url_candidate}' a valid URL?: {expected}\")\n        assert is_url(url_candidate) is expected\n\n\nif __name__ == \"__main__\":\n    main(text=TEXT, expected=EXPECTED_NUMBERS)\n    extra()\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/javierfiestasbotella.py",
    "content": "''' * EJERCICIO:\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\n */'''\nimport re\n\ntexto = \"Este texto numero 546 es 1 ejemplo para poder extraer varios numeros como 67 o 230 con expresiones regulares\"\n\npatron_numeros = r'\\d+'\nnumeros_encontrados = re.findall(patron_numeros, texto)\nprint(\"Números encontrados:\", numeros_encontrados)\n\n\n\n\npatron_email = r'^[\\w\\.-]+@[\\w\\.-]+\\.\\w+$'\npatron_telefono = r'^(\\+\\d{1,3})?\\s?(\\d{3}|\\(\\d{3}\\))[\\s.-]?\\d{3}[\\s.-]?\\d{4}$'\npatron_url = r'^(https?://)?(www\\.)?[\\w-]+\\.[a-z]{2,}(\\/\\S*)?$'\n\ndef validar(entrada, patron):\n    return bool(re.match(patron, entrada))\n\nemail_valido = \"pedrito@ejemplo.com\"\nemail_invalido = \"pedrito@.com\"\n\ntelefono_valido = \"122-655-7240\"\ntelefono_invalido = \"023-406-555\" \n\nurl_valida = \"https://www.pedrito.com\"\nurl_invalida = \"pedrito.com\"\n\nprint(\"Email válido:\", validar(email_valido, patron_email))\nprint(\"Email inválido:\", validar(email_invalido, patron_email))\n\nprint(\"Teléfono válido:\", validar(telefono_valido, patron_telefono))\nprint(\"Teléfono inválido:\", validar(telefono_invalido, patron_telefono))\n\nprint(\"URL válida:\", validar(url_valida, patron_url))\nprint(\"URL inválida:\", validar(url_invalida, patron_url))\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/jptxaya.py",
    "content": "# #16 EXPRESIONES REGULARES\n# /*\n#  * EJERCICIO:\n#  * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n#  * creando una que sea capaz de encontrar y extraer todos los números\n#  * de un texto.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea 3 expresiones regulares (a tu criterio) capaces de:\n#  * - Validar un email.\n#  * - Validar un número de teléfono.\n#  * - Validar una url.\n#  */\n\nimport re\n\n#Ejercicio\ntexto = \"0-Texto a evaluar con 1,2,3 y como maximo 10, es decir un rango de [0-10] numeros para regex\"\nprint(re.findall(r\"[0-9]+\",texto))\n\n#Dificultad Extra\n\ndef validar_email(email:str)->bool:\n    return bool(re.match(r\"^[\\w.+-]+@[\\w]+\\.[a-zA-Z]{2,4}$\",email))\n\nprint(\"Validacion email\")\nprint(validar_email(\"jos@gg.io\"))\nprint(validar_email(\"jos.sdad@gg.io\"))\nprint(validar_email(\"jos.sdad@gg.i\"))\nprint(validar_email(\"jos.sdadgg.io\"))\n\ndef validar_tlfno(tlfno:str)->bool:\n    return bool(re.match(r\"^\\+{0,1}[\\d\\s]{3,15}$\",tlfno))\n\nprint(\"Validacion Tlfno\")\nprint(validar_tlfno(\"+3411106\"))\nprint(validar_tlfno(\"666882788\"))\nprint(validar_tlfno(\"666 88 27 88\"))\nprint(validar_tlfno(\"66688a788\"))\n\n\nprint(\"Validacion url\")\ndef validar_url(url:str)->bool:\n    return bool(re.match(r\"^https?://(www\\.)?[0-9a-zA-Z]*\\.[a-zA-Z]{2,}[\\w/]*$\",url))\n\nprint(validar_url(\"http://hola.com\"))\nprint(validar_url(\"http://hola.com/1\"))\nprint(validar_url(\"http://www.hola.com/1\"))\nprint(validar_url(\"https://www.hola.com/1\"))\nprint(validar_url(\"hatp://www.hola.com/1\"))\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/juampaweb.py",
    "content": "# # #16 EXPRESIONES REGULARES\n# > #### Dificultad: Media | Publicación: 15/04/24 | Corrección: 22/04/24\n\n# ## Ejercicio\n\n# ```\n# /*\n#  * EJERCICIO:\n#  * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n#  * creando una que sea capaz de encontrar y extraer todos los números\n#  * de un texto.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea 3 expresiones regulares (a tu criterio) capaces de:\n#  * - Validar un email.\n#  * - Validar un número de teléfono.\n#  * - Validar una url.\n#  */\n# ```\n# #### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\n# Sigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n# > Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n\n\nimport re\n\n\ndef extract_number(texto):\n    \"\"\"Return a dictionary with the list of numbers and the string without numbers.\"\"\"\n    response = {}\n    response['list_numbers'] = re.findall(r'\\d+', texto)\n    response['string_not_numbers'] = re.sub(r'\\d+', '', texto)\n\n    return response\n\ndef validate_email(email):\n    \"\"\"Return True if the email is valid, False otherwise.\"\"\"\n    patron = r'^[a-zA-Z0-9._+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}$'\n    if re.match(patron, email):\n        return True\n    return False\n\ndef validate_phone(phone):\n    \"\"\"Return True if the phone is valid, False otherwise.\"\"\"\n    patron = r'^\\+?(\\d{2,3})?[-. ]?(\\d[-. ]?){0,9}(\\d)$'\n    if re.match(patron, phone):\n        return True\n    return False\n\ndef validate_url(url):\n    \"\"\"Return True if the url is valid, False otherwise.\"\"\"\n    patron = r'^(http|https):\\/\\/[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}'\n    if re.match(patron, url):\n        return True\n    return False\n\n\n# Validación de extracción de números en un texto\n\nlist_strings = [\n    \"Este es un texto con números como 123, 45.6, -7 y 1000.\",\n    \"123Erase una vez un número 1234567890 y otro 0987654321. Y para terminar456\",\n    \"hola 1234 mundo 5678\",\n]\nfor string in list_strings:\n    new_string = extract_number(string)\n    print(\"Cadena original: \", string)\n    print(\"Números encontrados: \", new_string['list_numbers'])\n    print(\"Cadena sin números: \", new_string['string_not_numbers'])\n    print(\"--------------------\")\n    print(\"\\n\")\n\nprint()\nprint()\n\n### FIN de validación de extracción de números en un texto\n\n\n\n\n\n# Validación de los emails\ntest_emails = [\n    \"jauns@pepe.com\",\n    \"jauns@pepe\",\n    \"pe@\",\n    \"pepe@com\",\n    \"juans+pepe@ally.com.ar\",\n    \"__pepe@juan.com\",\n]\n\n\nfor email in test_emails:\n    if validate_email(email):\n        print(\"El email\", email, \"es válido.\")\n    else:\n        print(\"El email\", email, \"no es válido.\")\n\nprint()\nprint()\n### FIN de validación de emails\n\n\n\n# Validación de teléfonos\ntest_phones = [\n    \"+34 123456789\",\n    \"123456789\",\n    \"+34-123456789\",\n    \"123-456-789\",\n    \"+54 11.5140.8258\"\n]\n\nfor phone in test_phones:\n    if validate_phone(phone):\n        print(\"El teléfono\", phone, \"es válido.\")\n    else:\n        print(\"El teléfono\", phone, \"no es válido.\")\n\nprint()\nprint()\n### FIN de validación de teléfonos\n\n\n# Validación de URLs\ntest_urls = [\n    \"http://www.google.com\",\n    \"www.google.com\",\n    \"http://www.google\",\n    \"http://www.google.com.ar\",\n    \"http://www.google.com.ar.com\",\n    \"http://www.google.com.ar.com.ar\",\n    \"://www.google.com.ar.com.ar.com\",\n]\n\nfor url in test_urls:\n    if validate_url(url):\n        print(\"La URL\", url, \"es válida.\")\n    else:\n        print(\"La URL\", url, \"no es válida.\")\n\n### FIN de validación de URLs\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/juanchernandezdev.py",
    "content": "### Python Regex ###\nimport re\n\npattern = r'\\d+'\nstring = 'this is my test with numbers 1 2 12 45 48'\nresult = re.findall(pattern, string, re.IGNORECASE)\nprint(result)\n\n#! Optional Challenge\n#* Email\n\nemail_pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,6}$'\nemail = 'johndoe@gmail.com'\n\nif re.match(email_pattern, email):\n  print('Your email is correct')\nelse:\n  print('Wrong email format')\n\n#* Phone number US format\nphone_pattern = r'^\\+?1?\\s?\\(?\\d{3}\\)?[\\s.-]?\\d{3}[\\s.-]?\\d{4}$'\nphone_number = '123 456 7890'\n\nif re.match(phone_pattern, phone_number):\n  print('Your phone is correct')\nelse:\n  print('Wrong phone format')\n\n#* URL  \nurl_pattern = r'^(https?:\\/\\/)?([a-zA-Z0-9_-]+\\.)+[a-zA-Z]{2,6}(:\\d+)?(\\/[a-zA-Z0-9@:%._\\+~#?&\\/=-]*)?$'\nurl_number = \"https://www.mytesturl.com\"\n\nif re.match(url_pattern, url_number):\n  print('Your url is correct')\nelse:\n  print('Wrong url format')\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/juandaherrera.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.\n\"\"\"\n\nimport re\n\ntest_cases = [\"1249830hola\", \"Esto nos costó 56800\", \"1278, no se, 2121\"]\n\npattern = r\"\\d+\"\nresults = [re.findall(pattern, test_case) for test_case in test_cases]\nprint(results)\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\n\"\"\"\n\nemail_pattern = r\"^\\w+@\\w+\\.\\w+$\"\nphone_pattern = r\"^3[0-9]{9}$\"\nurl_pattern = r\"^https?:\\/\\/[\\w\\-]+(\\.[\\w\\-]+)+[/#?]?.*$\"\n\ntest_emails = [\n    \"juandaherreparra@gmail.com\",\n    \"juanda.com\",\n    \"juanda@gmail\",\n    \"juanda45@yahoo.es\",\n    \"no soy un correo\",\n]\n\ntest_phones = [\"3218199645\", \"2178929201\", \"3128436677\", \"31284399001\"]\n\ntest_urls = [\n    \"http://www.juanda.com\",\n    \"https://www.juanda.com\",\n    \"https://web.com.co\",\n    \"https://www.my_web.com/hola_mundo\",\n    \"321819\",\n    \"prueba\",\n]\n\n\ndef compare_pattern(pattern: str, compare_list: list[str]) -> dict[str, bool]:\n    print({compare_item: bool(re.match(pattern, compare_item)) for compare_item in compare_list})\n\n\ncompare_pattern(email_pattern, test_emails)\ncompare_pattern(phone_pattern, test_phones)\ncompare_pattern(url_pattern, test_urls)\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/juanmax2.py",
    "content": "import re\n\"\"\"\nExpresiones regulares\n\"\"\"\n\n\n\n\n\ndef find_numbers(text: str) -> list:\n    \"\"\"Esta función se encarga de buscar números en el texto\"\"\"\n    return re.findall(r\"\\d+\", text)\n\ntext = \"Esta es el ejercicio 16 publicado el 15/04/2024\"\nprint(find_numbers(text))\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\n */\n\"\"\"\n\ndef validate_email(email: str) -> bool:\n    return bool(re.match(r\"^[\\w.+-]+@[\\w]+.[a-zA-Z]+$\", email))\n\nprint(validate_email(\"juanmajge@gmail.com\"))\n\ndef validate_phone(phone: str) -> bool:\n    return bool(re.match(r\"^\\+?[\\d\\s]{3,}$\", phone))\n\nprint(validate_phone(\"+123\"))\n\ndef validate_url(url: str) -> bool:\n    return bool(re.match(r\"^http[s]?://(www.)?[\\w]+\\.[a-zA-Z]+$\", url))\n\nprint(validate_url(\"https://juanma.com\"))\n\nprint(validate_url(\"https://www.juanma.com\"))"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/juanppdev.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.\n\"\"\"\n\nimport re\n\ndef extraer_numeros(texto):\n    # Definir la expresión regular para encontrar números\n    patron = r'\\d+'\n    # Buscar todos los números en el texto\n    numeros = re.findall(patron, texto)\n    return numeros\n\n# Ejemplo de uso\ntexto = \"En 2023, la población de la ciudad era de 1,234,567 personas.\"\nnumeros = extraer_numeros(texto)\nprint(numeros)  # Salida: ['2023', '1', '234', '567']\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\n\"\"\"\n\nimport re\n\ndef validar_email(email):\n    patron = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$'\n    return re.match(patron, email) is not None\n\n# Ejemplo de uso\nemail = \"ejemplo@dominio.com\"\nprint(validar_email(email))  # Salida: True\n\ndef validar_telefono(telefono):\n    patron = r'^\\+?\\d{1,3}?[-.\\s]?\\(?\\d{1,4}?\\)?[-.\\s]?\\d{1,4}[-.\\s]?\\d{1,9}$'\n    return re.match(patron, telefono) is not None\n\n# Ejemplo de uso\ntelefono = \"+34 123-456-789\"\nprint(validar_telefono(telefono))  # Salida: True\n\ndef validar_url(url):\n    patron = r'^(https?|ftp)://[^\\s/$.?#].[^\\s]*$'\n    return re.match(patron, url) is not None\n\n# Ejemplo de uso\nurl = \"https://www.ejemplo.com\"\nprint(validar_url(url))  # Salida: True\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/kenysdev.py",
    "content": "# ╔═════════════════════════════════════╗\n# ║ Autor:  Kenys Alvarado              ║\n# ║ GitHub: https://github.com/Kenysdev ║\n# ║ 2024 -  Python                      ║\n# ╚═════════════════════════════════════╝\n\n# -----------------------------------\n# * EXPRESIONES REGULARES\n# -----------------------------------\n# https://docs.python.org/es/3/howto/regex.html\n\n\"\"\"\n* EJERCICIO #1:\n* Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n* creando una que sea capaz de encontrar y extraer todos los números\n* de un texto.\n\"\"\"\n\nimport re\n\ndef to_numbers(text: str) -> list:\n    number_pattern = r'\\d+'\n    return re.findall(number_pattern, text)\n\nstring = \"abcdsfs1s(*&#}2. a3// 45sdf67\"\nlist_numbers = to_numbers(string)\nprint(list_numbers)\n\n\n\"\"\"\n* EJERCICIO #2:\n* Crea 3 expresiones regulares (a tu criterio) capaces de:\n* - Validar un email.\n* - Validar un número de teléfono.\n* - Validar una url.\n\"\"\"\n\ndef is_email(text: str) -> bool:\n    pattern = r'^[\\w.%+-]+@[\\w.-]+\\.[a-zA-Z]{2,}$'\n    if re.match(pattern, text):\n        return True\n    else:\n        return False\n\ndef is_phone_number(text: str) -> bool:\n    pattern = r'^(\\d{3}-\\d{3}-\\d{4}|\\d{10})$'\n    if re.match(pattern, text):\n        return True\n    else:\n        return False\n\ndef is_url(text: str) -> bool:\n    pattern = r'^(https?://)?(www\\.)?([a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,}(/\\S*)?$'\n    if re.match(pattern, text):\n        return True\n    else:\n        return False\n\n\nprint(\"\\nis_email\")\nprint(is_email(\"ejm@dmn.com\"))        # True\nprint(is_email(\"e_jm-2+b@dmn.co.hn\")) # True\nprint(is_email(\"ejm@dmn.com_\"))       # False\nprint(is_email(\"ejm@dmn\"))            # False\n\nprint(\"\\nis_email\")\nprint(is_phone_number(\"123-456-7890\"))  # True\nprint(is_phone_number(\"1234567890\"))    # True\nprint(is_phone_number(\"123456-7890\"))   # False\nprint(is_phone_number(\"uno234567890\"))  # False\n\nprint(\"\\nis_url\")\nprint(is_url(\"http://www.ejm.com\"))   # True\nprint(is_url(\"google.com\"))           # True\nprint(is_url(\"ejm.com/a/b/c\"))        # True\nprint(is_url(\"https://.ejm.com\"))     # False\nprint(is_url(\"https://.ejm.com/a b\")) # False\n\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/mariovelascodev.py",
    "content": "import re\n\ntext = \"El ejercicio 16 de expresiones regulares ha sido resulto el 05/03/2025\"\n\n#Expresión regular que busca números\nregular_expression = \"\\d+\"\n\n#Encontrar y mostrar todos los números de una cadena\nprint(re.findall(regular_expression, text))\n\n\n#EXTRA\n#Validar email\nemail_validate = \"^[a-zA-Z]+.?[a-zA-Z0-9]+.?[a-zA-Z0-9]+\\@[a-zA-Z]+\\.[a-zA-Z]+\"\nvalid_email = re.match(email_validate, \"correo2@correo.es\")\n\nif valid_email is not None:\n    print(\"Email correcto\")\nelse:\n    print(\"El email no es valido\")\n\n#Validar número de teléfono\nphone_validate = \"\\+?\\d{3,15}$\"\n\nvalid_phone = re.match(phone_validate, \"+34123456789\")\n\nif valid_phone is not None:\n    print(\"Número de teléfono correcto\")\nelse:\n    print(\"El número de teléfono no es valido\")\n\n#Validar una url\nurl_validate = \"[w]{0,3}\\.?\\w{3,}\\.{1}[a-z]{2,4}$\"\n\nvalid_url = re.match(url_validate, \"google.com\")\n\nif valid_url is not None:\n    print(\"La url es correcta\")\nelse:\n    print(\"La url no es valida\")"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/mhayhem.py",
    "content": "# EJERCICIO:\n# Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n# creando una que sea capaz de encontrar y extraer todos los números\n# de un texto.\n\nimport re\n\ntext = \"Hola, 12 de cada 20 animales están abandocnados en una calle\"\n\npatron = r\"\\d+\"\n\nnums = re.findall(patron, text)\nprint(nums)\n\n# DIFICULTAD EXTRA (opcional):\n# Crea 3 expresiones regulares (a tu criterio) capaces de:\n# - Validar un email.\n# - Validar un número de teléfono.\n# - Validar una url.\n\n\ndef re_web(text: str):\n    re_url = r\"^(www)\\.[a-z0-9.+-]+\\.[a-z]{2,10}$\"\n    is_web = bool(re.fullmatch(re_url, text))\n    return is_web\n\n\ndef re_telephon_number(phone: str):\n    re_phone = r\"^\\d{9}$\"\n    is_phone = bool(re.fullmatch(re_phone, phone))\n    return is_phone\n\n\ndef re_mail(mail: str):\n    re_mail = r\"^[A-Za-z0-9.+-]+@[A-Za-z0-9.+-]+\\.[A-Za-z]{2,63}$\"\n    is_mail = bool(re.fullmatch(re_mail, mail))\n    return is_mail\n\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/miguelex.py",
    "content": "import re\n\ndef reg_expr(cadena):\n    patron = r'-?\\d+\\.?\\d*'\n    numeros = re.findall(patron, cadena)\n\n    print(\"Números encontrados:\")\n    for numero in numeros:\n        print(numero)\n\n    print(\"\\n\")\n\ntexto = \"Este es un texto con números como 123, 45.6, -7 y 1000.\"\nprint(\"Vamos a analizar el siguiente texto:\")\nprint(\"'\" + texto + \"'\\n\")\nreg_expr(texto)\n\ntexto = \"123Erase una vez un número 1234567890 y otro 0987654321. Y para terminar456\"\nprint(\"Vamos a analizar el siguiente texto:\")\nprint(\"'\" + texto + \"'\\n\")\nreg_expr(texto)\n\ndef email_validation(email):\n    patron = r'^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}$'\n    if re.match(patron, email):\n        print(\"El email\", email, \"es válido.\")\n    else:\n        print(\"El email\", email, \"no es válido.\")\n\ndef phone_validation(phone):\n    patron = r'^\\+?(\\d{2,3})?[-. ]?\\d{9}$'\n    if re.match(patron, phone):\n        print(\"El teléfono\", phone, \"es válido.\")\n    else:\n        print(\"El teléfono\", phone, \"no es válido.\")\n\ndef url_validation(url):\n    patron = r'^(http|https):\\/\\/[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}'\n    if re.match(patron, url):\n        print(\"La URL\", url, \"es válida.\")\n    else:\n        print(\"La URL\", url, \"no es válida.\")\n\nemail_validation(\"correo@correo.com\")\nemail_validation(\"correo@correo\")\n\nphone_validation(\"+34 123456789\")\nphone_validation(\"123456789\")\n\nurl_validation(\"http://www.google.com\")\nurl_validation(\"www.google.com\")\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/mikelm2020.py",
    "content": "import re\n\n# Ejercicio\n\n\ndef find_numbers_in_string(text: str) -> list:\n    regex = r\"\\d+\"\n\n    return re.findall(regex, text)\n\n\n# Extra\n\n\ndef validate_email(email: str) -> bool:\n    regex = r\"^[\\w_.+-]+@[\\w-]+\\.[a-zA-Z.]+$\"\n    return bool(re.match(regex, email))\n\n\ndef validate_phone_number(phone_number: str) -> bool:\n    regex = r\"^\\+\\d{2}\\s{1}[\\d{2}\\s?\\-?}]+$\"\n    return bool(re.match(regex, phone_number))\n\n\ndef validate_url(url: str) -> bool:\n    regex = r\"^(https?:\\/\\/)?((www.)?[a-zA-Z0-9.-]+)\\.([a-zA-Z]{2,})([\\/\\w .-]*)*\\/?$\"\n    return bool(re.match(regex, url))\n\n\nif __name__ == \"__main__\":\n    text = \"Este es el ejercicio 16 publicado el 15/04/2024\"\n    print(find_numbers_in_string(text))\n\n    email = \"mario.vidal-klm@midominio-1.com.mx\"\n    print(validate_email(email))\n    phone = \"+52 5523458970\"\n\n    url = \"http://www.midominio.com.mx/sitio/mundo\"\n    print(validate_url(url))\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/monicavaquerano.py",
    "content": "# 16 EXPRESIONES REGULARES\n# Monica Vaquerano\n# https://monicavaquerano.dev\n\n\"\"\"/*\n * EJERCICIO:\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\n */\"\"\"\n\n# Regular Expresions\nimport re\n\ntext = \"hola, mundo!\"\nx = re.search(r\"hola\", text)\n\nif x:\n    print(\"It's a match\")\nelse:\n    print(\"Not a match\")\n\n# Function\tDescription\n# findall -\tReturns a list containing all matches\n# search -\tReturns a Match object if there is a match anywhere in the string\n# split -\tReturns a list where the string has been split at each match\n# sub - Replaces one or many matches with a string\n\n\ndef findDigits(txt):\n    pattern = \"\\d+\"\n    digits = re.findall(pattern, txt)\n    return digits\n\n\nprint(findDigits(\"The r4in in 5p4in\"))\n\n# Extra\n\n\n# E-Mail\ndef emailCheck(email):\n    pattern = r\"^[\\w.+-]+@[\\w.+-]+\\.[a-zA-Z]+$\"\n    check = bool(re.match(pattern, email))\n    return check\n\n\nprint(\"example@example.com es un email válido? =>\", emailCheck(\"example@example.com\"))\nprint(\"Ex.4-mpl3@exampl3.co es un email válido? =>\", emailCheck(\"Ex.4-mpl3@exampl3.co\"))\nprint(\"exampleexample.com es un email válido? =>\", emailCheck(\"exampleexample.com\"))\nprint(\"example!@example.c0m es un email válido? =>\", emailCheck(\"example@example.c0m\"))\n\n\n# Número de teléfono\ndef telephoneCheck(number):\n    pattern = r\"^(1\\s?)?(\\(\\d{3}\\)|\\d{3})([\\-\\s])?(\\d{3})([\\-\\s])?(\\d{4})$\"\n    check = bool(re.match(pattern, number))\n    return check\n\n\nprint(\"555-555-5555 es un número válido? =>\", telephoneCheck(\"555-555-5555\"))\nprint(\"1 555-555-5555 es un número válido? =>\", telephoneCheck(\"1 555-555-5555\"))\nprint(\"555-5555 es un número válido? =>\", telephoneCheck(\"555-5555\"))\nprint(\"(555)5(55?)-5555 es un número válido? =>\", telephoneCheck(\"(555)5(55?)-5555\"))\n\n\n# URL\ndef urlCheck(url):\n    pattern = r\"^(http[s]?://)?(www.)?[\\w]+\\.[\\w]{2,}[/]?$\"\n    check = bool(re.match(pattern, url))\n    return check\n\n\nprint(\"https://google.com/ es un url válido? =>\", urlCheck(\"https://google.com/\"))\nprint(\"http://google.com es un url válido? =>\", urlCheck(\"http://google.com\"))\nprint(\"https://www.google.com es un url válido? =>\", urlCheck(\"https://www.google.com\"))\nprint(\"www.google.com es un url válido? =>\", urlCheck(\"www.google.com\"))\nprint(\"google.com es un url válido? =>\", urlCheck(\"google.com\"))\nprint(\"google.c es un url válido? =>\", urlCheck(\"google.c\"))\nprint(\"goo/gle.c es un url válido? =>\", urlCheck(\"goo/gle.c\"))\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/mouredev.py",
    "content": "import re\n\n\"\"\"\nEjercicio\n\"\"\"\n\n\ndef find_numbers(text: str) -> list:\n    return re.findall(r\"\\d+\", text)\n\n\nprint(find_numbers(\"Este es el ejercicio 16 publicado 15/04/2024.\"))\n\n\n\"\"\"\nExtra\n\"\"\"\n\n\ndef validate_email(email: str) -> bool:\n    return bool(re.match(r\"^[\\w.+-]+@[\\w]+\\.[a-zA-Z]+$\", email))\n\n\nprint(validate_email(\"mouredev@gmail.com\"))\n\n\ndef validate_phone(phone: str) -> bool:\n    return bool(re.match(r\"^\\+?[\\d\\s]{3,}$\", phone))\n\n\nprint(validate_phone(\"+34 901 65 89 04\"))\n\n\ndef validate_url(url: str) -> bool:\n    return bool(re.match(r\"^http[s]?://(www.)?[\\w]+\\.[a-zA-Z]{2,}$\", url))\n\n\nprint(validate_url(\"http://www.moure.dev\"))\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/mrodara.py",
    "content": "############################################  EXPRESIONES REGULARES  ############################################################\n\nimport re # Módulo para tratamiento de expresiones regulares\n\nmy_string = \"El señor Daniel tiene 3 hijos y 5 esposas, además ha sido agraciado con 1000 €\"\nmy_other_string = \"A 4 vecinos de la comunidad en el bloque nro. 2 le han tocado 100.000 $ de la lotería\"\n\ndef extract_numbers_from_text(text: str) -> list:\n\n    pattern = r\"\\d+\" # Busca cualquier número entero\n\n    return re.findall(pattern=pattern, string=text)\n\nstr_list = [my_string, my_other_string]\n\nfor phrase in str_list:\n    matches = extract_numbers_from_text(text=phrase)\n    \n    if matches:\n        print(f\"En la frase '{phrase}' se encontraron los siguientes números: {matches}\")\n\n\n##############################################  EXTRA  ###################################################################################\n\ndef validate_email(email: str) -> bool:\n    \n    pattern = r\"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-z]{2,}$\"\n    \n    if re.match(pattern=pattern, string=email):\n        return True\n    else:\n        return False\n    \nmy_fake_email = \"root.srisemipresencial.com\"\nmy_trusted_email = \"root@srisemipresencial.com\"\n\nprint(validate_email(my_fake_email))\nprint(validate_email(my_trusted_email))\n\ndef validate_phone_number(phone: str) -> bool:\n    \n    pattern = r\"^\\+?[1-9]\\d{1,3}[-.\\s]?\\d{1,4}[-.\\s]?\\d{3,4}[-.\\s]?\\d{3,4}$\"\n    \n    if re.match(pattern=pattern, string=phone):\n        return True\n    else:\n        return False\n\nmy_fake_phone = \"+1234567890\"\nmy_trusted_phone = \"+1 234 567 890\"\nmy_trusted_phone_2 = \"+123456789\"\n\n\nprint(validate_phone_number(my_fake_phone))\nprint(validate_phone_number(my_trusted_phone))\nprint(validate_phone_number(my_trusted_phone_2))\n\ndef validate_url(url: str) -> bool:\n    \n    pattern = r\"^(https?:\\/\\/)?([a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,}(:\\d+)?(\\/[^\\s]*)?$\"\n    \n    if re.match(pattern=pattern, string=url):\n        return True\n    else:\n        return False\n\nmy_fake_url = \"http://www.google\"\nmy_trusted_url = \"https://www.google.com\"\nmy_trusted_url_2 = \"www.google.com\"\nmy_trusted_url_3 = \"http://www.google.com\"\n\nprint(validate_url(my_fake_url))\nprint(validate_url(my_trusted_url))\n##############################################  FIN EXTRA  ###################################################################################\n\n\n\n\n############################################  FIN EXPRESIONES REGULARES  ############################################################"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/mvidalb.py",
    "content": "import re\n\n\"\"\"\nEjercicio\n\"\"\"\n\ndef find_numbers(text: str) -> list:\n    return re.findall(r\"\\d+\", text)\n\ntext = \"Este es el ejercicio 16 publicado el 15/04/2024.\"\nprint(find_numbers(text))\n\n\n\"\"\"\nEjercicio extra\n\"\"\"\nemail = \"mario.vidal@gmail.com\"\nnumber = \"+34 654 32 13 21\"\nurl = \"https://www.retosdeprogramacion.com\"\n\n\ndef validate_email(email : str) -> bool:\n    return bool(re.match(r\"^[\\w.+-]{5,15}@[\\w]+\\.[a-zA-Z]{2,4}$\", email))\n\n\ndef validate_number(number : str) -> bool:\n    return bool(re.match(r\"^\\+?[\\d\\s]{3,}$\", number))\n\n\ndef validate_url(url : str) -> bool:\n    return bool(re.match(r\"^http[s]?://(www.)?[\\w]+\\.[a-zA-Z]{2,3}$\", url))\n\nprint(validate_email(email))\nprint(validate_number(number))\nprint(validate_url(url))\n\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/neslarra.py",
    "content": "\"\"\"\n EJERCICIO:\n Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n creando una que sea capaz de encontrar y extraer todos los números\n de un texto.\n\n DIFICULTAD EXTRA (opcional):\n Crea 3 expresiones regulares (a tu criterio) capaces de:\n - Validar un email.\n - Validar un número de teléfono.\n - Validar una url.\n\"\"\"\nimport re\n\n\nprint(f\"== Explicación {'=' * 30}\\n\")\n\nprint(\"\"\"Una expresión regular es una cadena que indica como identificar un patrón dentro de otras cadena.\nAsí como indicamos formato prefijando la cadena a imprimir con \"f\", a la cadena de expresión regular\nse la prefija con \"r\".\n\nAlgunas reglas básicas de RE son:\n    [] indica secuencia =>  [a-z] letras minúsculas, [0-9] dígitos, [0-9A-F] hexadecimal\n    () indica literalidad => (Hola) debe decir \"Hola\"\n    * indica 0 más ocurrencias => (Hola)* puede o no decir \"Hola\"\n    + indica 1 o más ocurrencias => [0-9]+ debe haber uno o más dígitos\n    ^ puede indicar \"negación\" o \"inicio\":\n        (^Hola) NO debe decir \"Hola\"\n        ^(Hola) debe decir \"Hola\" al inicio de la cadena\n    $ indica el final de una cadena (o de una línea)\n\ndef numero_a_palabra(cadena: str) -> str:\n    reg_exp = r\"[0-9]+\"\n    numeros = {0: \"cero\", 1: \"uno\", 2: \"dos\", 3: \"tres\", 4: \"cuatro\", 5: \"cinco\", 6: \"seis\", 7: \"siete\", 8: \"ocho\", 9: \"nueve\"}\n    for n in re.findall(reg_exp, cadena):\n        numero = \"\"\n        for d in n:\n            numero += numeros[int(d)] + \" \"\n        cadena = cadena.replace(n, numero, 1)\n    return cadena\n\n\nprint(f\"{numero_a_palabra('Hola, vivo en el 1357 de la calle 23 de la ciudad de 9 de Julio. Llamame al 9864211 -URGENCIAS-.')}\")\n\nLo que devuelve:\n\"\"\")\n\n\ndef numero_a_palabra(cadena: str) -> str:\n    reg_exp = r\"[0-9]+\"\n    numeros = {0: \"cero\", 1: \"uno\", 2: \"dos\", 3: \"tres\", 4: \"cuatro\", 5: \"cinco\", 6: \"seis\", 7: \"siete\", 8: \"ocho\", 9: \"nueve\"}\n    for n in re.findall(reg_exp, cadena):\n        numero = \"\"\n        for d in n:\n            numero += numeros[int(d)] + \" \"\n        cadena = cadena.replace(n, numero, 1)\n    return cadena\n\n\nprint(f\"{numero_a_palabra('Hola, vivo en el 1357 de la calle 23 de la ciudad de 9 de Julio. Llamame al 9864211 -URGENCIAS-.')}\", end=\"\\n\\n\")\n\nprint(f\"== Dificultad extra {'=' * 30}\\n\")\n\n\ndef validar_mail(email: str) -> bool:\n    reg_exp = r\"^[a-zA-Z0-9_\\-.]+@[a-zA-Z0-9]+\\.[a-zA-Z.]+$\"\n    return bool(re.match(reg_exp, email))\n\n\ndef validar_telefono(telefono: str) -> bool:\n    reg_exp = r\"^\\+?[0-9]+[ \\t]?[0-9]+[ \\t\\-]?[0-9]*[ \\t\\-]?[0-9]*$\"\n    return bool(re.match(reg_exp, telefono))\n\n\ndef validar_url(url: str) -> bool:\n    reg_exp = r\"^(http://|https://)?[a-zA-Z0-9_\\-.]+\\.[a-zA-Z]+$\"\n    return bool(re.match(reg_exp, url))\n\n\ndef validar_nombre(nombre: str) -> bool:\n    reg_exp = r\"^[a-zA-Z]{2,}[( \\t)+[a-zA-Z]{2,}]*$\"\n    return bool(re.match(reg_exp, nombre))\n\n\nprint(f\"Validar nestor.larralde@gmail.com <=> {validar_mail('nestor.larralde@gmail.com')}\")\nprint(f\"Validar nlarralde@miningrapba.com.ar <=> {validar_mail('nlarralde@miningrapba.com.ar')}\")\nprint(f\"Validar neslarra@gmail <=> {validar_mail('neslarra@gmail')}\")\n\nprint(f\"Validar +54 11 1234-5678 <=> {validar_telefono('+54 11 1234-5678')}\")\nprint(f\"Validar +54 11 12345678 <=> {validar_telefono('+54 11 12345678')}\")\nprint(f\"Validar +54 11 1234 5678 <=> {validar_telefono('+54 11 12345678')}\")\nprint(f\"Validar 1234 5678 <=> {validar_telefono('1234 5678')}\")\nprint(f\"Validar +AR 11 1234 5678 <=> {validar_telefono('+AR 11 1234 5678')}\")\n\nprint(f\"Validar http://github.com.ar <=> {validar_url('http://github.com.ar')}\")\nprint(f\"Validar https://github.com.ar <=> {validar_url('https://github.com.ar')}\")\nprint(f\"Validar github.com.ar <=> {validar_url('github.com.ar')}\")\nprint(f\"Validar htp://github.com.ar <=> {validar_url('htp://github.com.ar')}\")\nprint(f\"Validar github.999 <=> {validar_url('github.999')}\")\n\nprint(f\"Validar Nestor <=> {validar_nombre('Nestor')}\")\nprint(f\"Validar Nestor Larralde <=> {validar_nombre('Nestor Larralde')}\")\nprint(f\"Validar Nestor O Larralde <=> {validar_nombre('Nestor O Larralde')}\")\nprint(f\"Validar 5estor Larralde <=> {validar_nombre('5estor Larralde')}\")\nprint(f\"Validar N Larralde <=> {validar_nombre('N Larralde')}\")\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/nlarrea.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\n\"\"\"\n\nimport re\n\ntext = \"\"\"\nLorem ipsum dolor1 sit amet, consectetur adipiscing elit. Nullam ac mi in\nipsum ultricies 2 varius. Nullam euismod, justo nec fermentum ultricies, nunc\nnisl tempus purus, 3 sed dictum 563 nulla odio nec purus. Nullam nec purus\nconsectetur, consectetur justo. 10 Nullam nec purus consectetur, consectetur.\n\"\"\"\n\nnumbers_pattern = r\"[\\d]{1,}\"\nnumbers = re.findall(numbers_pattern, text)\nprint(numbers)\n# ['1', '2', '3', '563', '10']\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\n\"\"\"\n\n\ndef print_test(pattern: str, text: str) -> bool:\n    print(text + \":\", bool(re.match(pattern, text)))\n\n\nprint(\"\\nTesting emails:\")\nemail_pattern = r\"^[\\w]{1,}[\\w\\d\\._]{4,}\\@[\\w]{2,}\\.[\\w]{2,3}$\"\nprint_test(email_pattern, \"an_email@gmail.com\")  # True\nprint_test(email_pattern, \"1234@email.com\")  # False\nprint_test(email_pattern, \"an_email1234\")  # False\nprint_test(email_pattern, \"an2_email4@gmail.com\")  # True\nprint_test(email_pattern, \"another.2024@gmail\")  # False\nprint_test(email_pattern, \"another.2024@gmail.\")  # False\nprint_test(email_pattern, \"another.2024@gmail.com\")  # True\n\nphone_pattern = r\"^\\+?\\d{3,}$\"\nprint_test(phone_pattern, \"123456789\")  # True\nprint_test(phone_pattern, \"+34123456789\")  # True\nprint_test(phone_pattern, \"abcdefghi\")  # False\n\nurl_pattern = r\"^https?://(w{3}\\.)?[\\w\\d\\.\\-\\?]+\\.[\\w]{2,}/?$\"\nprint_test(url_pattern, \"https://github.com/\")  # True\nprint_test(url_pattern, \"https://www.twitch.tv/\")  # True\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/oriaj3.py",
    "content": "\"\"\"\n16 - EXPRESIONES REGULARES\n\nAutor de la solución: Oriaj3\t\n\nTeoría:\t\nLas expresiones regulares son patrones utilizados para encontrar una determinada\nsecuencia de caracteres dentro de una cadena de texto. Son una herramienta\npoderosa y flexible que permite buscar y extraer información de manera eficiente\ny precisa.\n\nEn Python, las expresiones regulares se pueden utilizar a través del módulo\nre, que proporciona una serie de funciones y métodos para trabajar con ellas.\nPara utilizar expresiones regulares en Python, se debe importar el módulo re y\nluego compilar el patrón de expresión regular utilizando la función compile().\n\nPor ejemplo, la siguiente expresión regular encuentra y extrae todos los números\nde una cadena de texto:\n\nimport re\n\n# Compila el patrón de expresión regular\npattern = re.compile(r'\\d+')\n\n# Cadena de texto de ejemplo\ntext = 'Hoy es 25 de diciembre de 2021'\n\n# Busca y extrae todos los números de la cadena de texto\nnumbers = pattern.findall(text)\n\n# Imprime los números encontrados\nprint(numbers)\n\nEn este caso, la expresión regular \\d+ busca uno o más dígitos en la cadena de\ntexto. Al compilar el patrón de expresión regular y utilizar el método findall(),\nse obtienen todos los números de la cadena de texto.\n\nRe usa una sintaxis especial para definir patrones de expresión regular. Algunos\nde los caracteres especiales más comunes son:\n\n\\d: Coincide con cualquier dígito.\n\\w: Coincide con cualquier carácter alfanumérico.\n\\s: Coincide con cualquier carácter de espacio en blanco.\n.: Coincide con cualquier carácter excepto un salto de línea.\n*: Coincide con cero o más repeticiones del carácter anterior.\n+: Coincide con una o más repeticiones del carácter anterior.\n?: Coincide con cero o una repetición del carácter anterior.\n[]: Coincide con cualquier carácter dentro de los corchetes.\n(): Agrupa una serie de caracteres para aplicar operadores como * o +.\n|: Coincide con cualquiera de las opciones separadas por el operador.\n^: Coincide con el inicio de una cadena de texto.\n$: Coincide con el final de una cadena de texto.\n\"\"\"\n\n\"\"\"\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.\n\"\"\"\n\nimport re\n\ntexto = 'Hoy es 25 de diciembre de 2021, tengo 30 años y mi número de teléfono es 1234567890, vivo en la calle 1234 y mi código postal es 54321.'\n\n# Compila el patrón de expresión regular\npattern = re.compile(r'\\d+') # \\d+ busca uno o más dígitos en la cadena de texto r indica que es una cadena cruda (raw string)\n\n# Busca y extrae todos los números de la cadena de texto\nnumeros = pattern.findall(texto)\n\n# Imprime los números encontrados\nprint(numeros)\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\n */\n\"\"\"\n\"\"\"\nPatrón explicado: \n^: Inicio de la cadena.\n[a-zA-Z0-9._%+-]+: Uno o más caracteres alfanuméricos, puntos, guiones bajos, porcentajes, signos más o menos (parte local del correo).\n@: El símbolo arroba.\n[a-zA-Z0-9.-]+: Uno o más caracteres alfanuméricos, puntos o guiones (nombre de dominio).\n\\.: Un punto literal.\n[a-zA-Z]{2,}$: Dos o más letras (dominio de nivel superior, como .com, .es, .org).\n$: Fin de la cadena.\n\"\"\"\n\ndef valida_email(email: str):\n    patron = re.compile(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$')\n    if re.match(patron, email) is not None:\n        return True\n    else: \n        return False\n\nprint(valida_email(\"pepe@gmail.com\"))\n\n\"\"\"\nPatrón explicado:\n^: Inicio de la cadena.\n\\+\\d\\d\\s\\d{9}: Un signo más seguido de dos dígitos, un espacio en blanco y nueve dígitos.\n\"\"\"\n\ndef valida_telefono(num: str):\n    patron = re.compile(r'^\\+\\d\\d\\s\\d{9}$')\n    if re.match(patron, num):\n        return True\n    else:\n        return False\n\nprint(valida_telefono(\"+34 644112233\"))\n\n\"\"\"\nPatrón explicado en comentarios en el código\n\"\"\"\n\ndef valida_url(url: str):\n    patron_url = re.compile(\n    r'^(https?://)?'  # Protocolo (http://, https://) opcional\n    r'(www\\.)?'       # www. opcional\n    r'[a-zA-Z0-9.-]+'  # Nombre de dominio (letras, números, guiones, puntos)\n    r'\\.[a-zA-Z]{2,}'  # Dominio de nivel superior (.com, .es, etc.)\n    r'(:\\d+)?'        # Puerto opcional (por ejemplo, :8080)\n    r'(/.*)?$'        # Path opcional (cualquier cosa después de la barra /)\n    )\n\n    if re.match(patron_url, url):\n        return True\n    else:\n        return False\n    \nprint(valida_url(\"https://www.google.com\"))\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/pyramsd.py",
    "content": "import re\ntexto1 = \"Texto sin numeros\"\ntexto2 = \"Texto con numeros 123321\"\ntexto3 = \"e42423\"\n\nnums_in_texto1 = re.findall(\"[0-9]\", texto1)\nnums_in_texto2 = re.findall(\"[0-9]\", texto2)\nnums_in_texto3 = re.findall(\"[0-9]\", texto3)\n\nprint(nums_in_texto1)\nprint(nums_in_texto2)\nprint(nums_in_texto3)\n\n'''\nEXTRA\n'''\n# para correos\nregex = '^[a-z0-9]+[\\._]?[a-z0-9]+[@]\\w+[.]\\w{2,3}$'\nemail = 'minauzum56@gmail.com'\nresultEmail2 = re.search(regex, email)\n\nif resultEmail2:\n    print('Es válido')\n\n# para numeros de telefonos, en mi pais los numeros de celular empienzan con 9 y tienen 9 digitos\nregex = '^9[0-9]{8}$'\nnumero_telefono = \"956442361\"\n\nif re.findall(regex, numero_telefono):\n    print(\"Es válido\")\n\n# para  url\nregex = \"^https?:\\/\\/([a-zA-Z0-9]*\\.)?[a-zA-Z0-9]*\\.([a-zA-Z]{3})(\\.[a-zA-Z]{2,3})?\\/?$\"\nurl = 'http://www.holamundo.dev'\n\nif re.findall(regex, url):\n    print(\"Es válido\")\n    \n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/qwik-zgheib.py",
    "content": "import re\n\n\n# -- exercise\ndef extract_numbers(text: str) -> list:\n    return re.findall(r\"\\d+\", text)\n\n\nany_text: str = \"in the year 2024, the number 42 is the answer to everything.\"\nprint(extract_numbers(any_text))\n\n\n# -- extra challenge\ndef validate_email(email: str) -> bool:\n    return bool(re.match(r\"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$\", email))\n\n\ndef validate_phone(phone: str) -> bool:\n    return bool(re.match(r\"^\\+?(\\d{1,3})?\\s?(\\d{10})$\", phone))\n\n\ndef validate_url(url: str) -> bool:\n    return bool(re.match(r\"^https?://[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+\", url))\n\n\nprint(validate_email(\"qwikzgheib@gmail.com\"))\nprint(validate_phone(\"+1234567890\"))\nprint(validate_url(\"https://www.google.com\"))\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/rantamhack.py",
    "content": "'''\n* Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n* creando una que sea capaz de encontrar y extraer todos los numeros\n* de un texto.\n'''\nimport re\n\nprint(\"\\n\\n=======================================EJERCICIO=======================================\\n\\n\")\n\nstring = \"Mariano 1234\"\nregex = r\"\\d+\" \nnumbers = re.findall(regex, string)\nprint(numbers)\n\nnumbers2 = re.search(regex, string)\nprint(numbers2)\n\n\nprint(\"\\n\\n=======================================DIFICULTAD EXTRA=======================================\\n\\n\")\n\n'''\n* Crea 3 expresiones regulares (a tu criterio) capaces de:\n* - Validar un email.\n* - Validar un numero de telefono.\n* - Validar una url.\n'''\n    \n\ndef check_email():\n    email = input(\"\\n[+] Introduce un email: \")\n    verify_email = r\"^[a-zA-Z0-9_+-.]+@[a-zA-Z0-9_+-]+\\.[a-zA-Z]{2,}$\"\n    \n    if re.findall(verify_email, email):\n        print(\"\\n[+] El email introducido es correcto\")\n    else:\n        print(\"\\n[!] El email introducido no es correcto\")\n    \ndef check_number():\n    number_phone = input(\"\\n[+] Introduce un un numero de telefono: \")\n    verify_phone = r\"^[+[0-9]{1,3}]?[0-9]{4,9}$\"\n    \n    if re.findall(verify_phone, number_phone):\n        print(\"\\n[+] El numero introducido es correcto\")\n    else:\n        print(\"\\n[!] El numero introducido es incorrecto\")\n    \n    \ndef check_url():\n    url = input(\"\\n[+] Introduce una direccion url: \")\n    verify_url = r\"((https?://(www\\.)?)|www\\.)\\w{3,}\\.[a-z]{2,}\"\n\n    if re.search(verify_url, url):\n        print (\"\\n[+] La direccion url introdudida es correcta\")\n    else:\n        print(\"\\n[!] La direccion url introducida no es corrrecta\")\n\ncheck_email()\ncheck_number()\ncheck_url()\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/raulG91.py",
    "content": "import re\n\ntext = \"THis is a text with 3 numbers: 4,3,5\"\n\n#Find all numbers in text\nprint(re.findall('[0-9]', text))\n\n#Extra \n\n#Create a regular expresion to validate an email\ndef validate_email(email):\n    return bool(re.match(r\"^[\\w.+-]+@[\\w]+\\.[a-zA-Z]+$\",email))\n\nprint(validate_email(\"raul.garcia@text.com\"))\nprint(validate_email(\"raul.garcia@textcom\"))\n\n#Validate phone number\ndef validate_phone(phone):\n    return bool(re.match(r'[6|7]\\d{8}',phone))\n\nprint(validate_phone(\"925259972\"))\n\n#Validate url\ndef validate_url(url):\n    return bool(re.match(r'^http[s]?://www.\\S*\\.[a-zA-Z]{2,}$',url))\n\nprint(validate_url(\"https://www.marca.es\"))\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/raynerpv2022.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n#  * creando una que sea capaz de encontrar y extraer todos los números\n#  * de un texto.\n#  *\nimport re\n\npattern = r'\\d+'\ntext = \"\"\"Utilizando tu lenguaje, explora el concepto de expres67676iones regulares,\n#  * creando una que sea capaz de encontrar y extraer todos los 333números\n#  * de un texto.DIFICULTAD334 EXTRA (opcional):\n#  * Crea 3 expresiones regulares (a tu criterio) ca343434paces de:\n#  * - Validar un email.\n#  * - Validar565  un número de teléfono.\n#  * - Validar una url.\"\"\"\nresult = re.search(pattern,text)\nprint(result.group())\nresult = re.findall(pattern,text)\nprint(result)\n\n\n\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea 3 expresiones regulares (a tu criterio) capaces de:\n#  * - Validar un email.\n#  * - Validar un número de teléfono.\n#  * - Validar una url.\n#  */\n\ndef check_email(email):\n    \n     p = r\"^[\\w.]+@[a-zA-Z0-9.-]+\\.+[a-zA-Z]{2,}$\"\n       \n     result = re.fullmatch(p,email)\n     if result:\n        return email\n     else:\n         return f\"{email} : \"+\"\".join(\"No valido\")\n\n    \n\ndef emails():\n    emails = [\n    \"user@example.com\",\n    \"firstname.lastname@example.co.uk\",\n    \"user+name@example.com\",\n    \"user_name@example.org\",\n    \"user.name123@example.info\",\n    \"user123@example.org\",\n    \"user.name+label@example.com\",\n    \"username@subdomain.example.com\",\n    \"user@example.travel\",\n    \"user@example.name\",\n    \"user@.com\",\n    \"@example.com\",\n    \"user@com\",\n    \"user@exam_ple.com\",\n    \"user@ex-ample..com\",\n    \"user@.example.com\",\n    \"user@example.c\",\n    \"user@-example.com\",\n    \"user@example..com\",\n    \"user@exa_mple.com\"\n    ]\n\n    for e in emails:\n        print(check_email(e))\n\ndef check_phone(number):\n    ps = r\"^(\\+34\\s)?[\\d]{3}\\s[\\d]{3}\\s[\\d]{3}$\"\n    result = re.fullmatch(ps,number)\n    if result:\n        return result.group()\n    else:\n        return f\"{number} : \"+\"\".join(\"No valida\")\n\n     \n\ndef telephon_NUmber():\n    telefonos = [\n    '+34 612 345 678',   # Válido\n    '612 345 678',       # Válido\n    '912 345 678',       # Válido\n    '(912) 345 678',     # Válido\n    '612345678',         # Válido\n    '+34 (612) 345 678', # Válido\n    '612 34 56',         # No válido (menos dígitos)\n    '612-345-678',       # No válido (caracteres no permitidos)\n    '123 456 789',       # No válido (no comienza con 6, 7, o 9)\n    '9123456789',        # No válido (demasiados dígitos)\n    '(612)345678',       # No válido (espacio mal ubicado)\n    '612 345678'         # No válido (espacio mal ubicado)\n]\n    \n    for n in telefonos:\n        print(check_phone(n))\n\ndef check_url(url):\n     \n    ps = r\"^https?://[\\w.]+\\.[a-zA-Z]{2,}$\"\n    result = re.match(ps,url)\n    if result:\n        return result.group()\n    else:\n        return f\"{url} : \"+\"\".join(\"No valida\")\n\n    \ndef urls():\n\n    urls = [\n        \"http://www.example.com\",\n        \"https://subdomain.example.org\",\n        \"http://example.co.uk\",\n        \"http://example.com2\",\n        \"http://www.example.c\",\n        \"https://www.example.edu\",\n        \"http://example\",\n        \"ftp://example.com\",\n        \"https://example.com/path\",\n        \"http://123.456.789.0\"\n    ]\n\n    for l in urls:\n\n        print(check_url(l))\nurls()\nprint()\nemails()\nprint()\ntelephon_NUmber()\n\n\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/restevean.py",
    "content": "import re\n\n\n\"\"\"\nExercise\n\"\"\"\n\n\ndef extract_numbers(text):\n    regex = r'\\d+'\n    pattern = re.compile(regex)\n    numbers = pattern.findall(text)\n    return numbers\n\n\n\"\"\"\nExtra\n\"\"\"\n\n\ndef validate_data(input_data):\n    regex_email = r'^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,6}$'\n    regex_phone = r'^(\\+?\\d{1,3})?[\\s-]?(\\(\\d{2,3}\\)|\\d{2,3})[\\s-]?(\\d{3}[\\s-]?\\d{4})$'\n    regex_url = r'^https?://[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,6}(/[\\w\\-.~:/?#\\[\\]@!$&\\'()*+,;=]*)?$'\n\n    if re.match(regex_email, input_data):\n        return \"Email is valid\"\n    elif re.match(regex_phone, input_data):\n        return \"Phone number is valid\"\n    elif re.match(regex_url, input_data):\n        return \"URL is valid\"\n    else:\n        return \"Invalid input\"\n\n\nif __name__ == '__main__':\n    text = \"En 1992, tenía 10 años. En el 2020, tenía 38. Han pasado 200 años desde 1822.\"\n    print(extract_numbers(text))\n    print(validate_data(\"usuario@example.com\"))\n    print(validate_data(\"usuarioexample.com\"))\n    print(validate_data(\"usuarioexample\"))\n    print(validate_data(\"+34 912345678\"))\n    print(validate_data(\"https://www.example.com\"))\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/rigo93acosta.py",
    "content": "'''\n * EJERCICIO:\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\n */\n'''\n\nimport re\n\n\"\"\"\nEjericio\n\"\"\"\n\n# regex = r\"[0-9]+\" # Otra forma de hacerlo\nregex = r\"\\d+\"\n\ntext = \"El 18/12/2022 Argentina ganó el mundial de fútbol.\"\n\ndef find_numbers(text: str, regex) -> list:\n    return re.findall(regex, text)\n\n\nprint(find_numbers(text, regex))\n\n\"\"\"\nExtra\n\"\"\"\n\ndef validate_email(email: str) -> bool:\n    \n    regex = r\"^[\\w.+-]+@[\\w]+\\.[a-zA-Z]+$\"\n    return bool(re.match(regex, email))\n\ndef validate_phone(phone: str) -> bool:\n\n    regex = r\"^\\+?[\\d\\s]{3,}$\"\n    return bool(re.match(regex, phone))\n\ndef validate_url(url: str) -> bool:\n\n    regex = r\"^http[s]?://(www.)?[\\w]+\\.[a-zA-Z]{2,}$\"\n    return bool(re.match(regex, url))\n\nprint(validate_email(\"rigo93acosta@gmail.com\"))\nprint(validate_phone(\"+54 9 11 555 55555\"))\nprint(validate_url(\"https://www.google.com\"))\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/rikmij.py",
    "content": "import re\n\ntexto_ejemplo = \"2 y dos son 4, cuatro y dos son 6, seis y dos son 8 y ocho 16\"\n\n'''find_nums = re.findall(r'\\d+', texto_ejemplo)\n\nprint(find_nums)'''\nfind_nums = r'\\d+'\nfor elem in re.finditer(find_nums, texto_ejemplo):\n    first = elem.start()\n    last = elem.end()\n    print(f\"{texto_ejemplo[first:last]} -> posiciones ({first}-{last})\")\n\nprint('\\n', '~'*7, \"EJERCICIO EXTRA\", '~'*7)\n#Validar email\nemail = r'\\w+\\S*@\\w+.\\w+'\ntexto_email = \"Buenas tardes, el correo electrónico es correo.deprueba_hola@corporacion.es. Muchas gracias\"\nprint(re.search(email, texto_email))\n\n#Validar número teléfono\ntelf = r'[+]\\d+\\s\\d+'\ntexto_telf = \"Puede llamar al número +34 6874521035200 para más información\"\nprint(re.search(telf,texto_telf))\n\n#Validar URL\nweb = r'https?://\\w+.\\w+.\\w+[.\\w+]*'\ntexto_web = \"Puede visitar nuestra web: https://www.unaweb_deprueba101.com.wordpress.es para más información\"\nprint(re.search(web, texto_web))\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/santyjl.py",
    "content": "#16 -- EXPRESIONES REGULARES\n\n\"\"\"\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\n */\n\"\"\"\nimport re  # Importamos el módulo re para trabajar con expresiones regulares\n\n\ndef exprecion_regular_numeros(texto: str):\n    \"\"\"\n    Función para encontrar y mostrar los números en un texto utilizando expresiones regulares.\n\n    Args:\n    texto (str): El texto en el que se buscarán los números.\n    \"\"\"\n    numeros = re.findall(r'\\d+', texto)  # Buscamos todos los números en el texto\n\n    print(\"Números encontrados:\")\n    for numero in numeros:\n        print(numero)\n\ntexto = \"\"\"hola mundo esto es una prueba del reto de programacion numero 16 , esto significa que\nque han vido otros retos como el 10 , 5 o un reto numero 0\"\"\"\n\nexprecion_regular_numeros(texto)  # Llamamos a la función para buscar y mostrar los números en el texto\n\n### Extra\nemail_exprecion = r'^[\\w\\.-]+@[\\w\\.-]+\\.\\w+$'  # Patrón de expresión regular para validar correos electrónicos\nnumero_exprecion = r'^\\d{4}\\s\\d{4}$'  # Patrón de expresión regular para validar números de teléfono\n\n# Patrón de expresión regular para validar URLs\nurl_exprecion = r'^(https?://)?([a-z0-9]*\\.)?[a-z0-9-]+\\.[a-z]{2,3}$'\n\ndef email_numero_url(elemento: str):\n    \"\"\"\n    Función para verificar si un elemento es un correo electrónico, número de teléfono o URL válidos.\n\n    Args:\n    elemento (str): El elemento a verificar.\n    \"\"\"\n    if re.match(email_exprecion, elemento):\n        print(f\"El texto '{elemento}' es un correo electrónico válido.\")\n\n    elif re.match(numero_exprecion, elemento):\n        print(f\"El texto '{elemento}' es un número de teléfono válido.\")\n\n    elif re.match(url_exprecion, elemento):\n        print(f\"El texto '{elemento}' es una URL válida.\")\n\n    else:\n        print(f\"El texto '{elemento}' no coincide con ningún patrón de correo electrónico, número de teléfono o URL.\")\n\n# Definimos algunos ejemplos válidos e inválidos de números de teléfono, correos electrónicos y URLs\nnumero_valido = \"8888 9999\"\nnumero_invalido = \"8888999\"\n\nemail_valido = \"jlopezsanty1@gmail.com\"\nemail_invalido = \"13lopez@com\"\n\nurl_valida = \"https://www.holamundo.day\"\nurl_invalida = \"www.hola_mundo.dev\"\n\n# Probamos la función con los ejemplos definidos\nemail_numero_url(numero_valido)\nemail_numero_url(email_valido)\nemail_numero_url(url_valida)\n\nprint(\"\\n---------------------------------\\n\")\n\nemail_numero_url(numero_invalido)\nemail_numero_url(email_invalido)\nemail_numero_url(url_invalida)\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/sorubadguy.py",
    "content": "import re\n\ndef obtener_numeros(text: str):\n    \n    numeros = re.findall(\"\\d\", text)\n    return numeros   \n\nprint(obtener_numeros(\"Hoy es 05/08/2024 y esta nublado desde las 3PM\"))\n\n#!Extra\n\nmail = \"lucas_martinez33@hotmail.com.ar\"\ntelefono = \"+54 9 2234 537643\"\nurl = \"https://github.com/sorubadguy\"\n\ndef validar_mail(mail: str):\n    \n    reEmail = r\"^[\\w]+@[\\w]+\\.{1}[\\w]+\\.?[\\w]*\"\n    return bool(re.fullmatch(reEmail, mail))\n    \nprint(validar_mail(mail))\n\ndef validar_telefono(telefono: str):\n    \n    reTel = r\"^\\+\\d+\\s{1}\\d+\\s{1}\\d+\\s{1}\\d+\"\n    return bool(re.fullmatch(reTel, telefono))\n\nprint(validar_telefono(telefono))\n\ndef validar_url(url: str):\n    \n    reUrl = r\"^http[s]?://\\w+\\.{1}\\w+\\.?\\w*\\.?\\w*[/\\w]*[\\.\\w]*\"\n    return bool(re.fullmatch(reUrl, url))\n\nprint(validar_url(url))"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/sperezsa.py",
    "content": "import re\n\ntext = \"Ej6emplo 3 de buscar 2 números entre 1 text0 5073.22\"\npattern = r\"[0-9]\"\nprint(re.findall(pattern, text))\n\n\n\"\"\"\nExtra\n\"\"\"\n\n#EMAIL\ntext = \"ejemplo@terra.es\"\ntext= \"0nuevo@dia-e.com\" \ntext= \"a3@media.n-e-t\"\npattern_email = r\"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z-.]+$\"\nprint(re.findall(pattern_email, text))\n\n#MOBILE PHONE\ntext = \"766666466\"\npattern_mobile = r\"^[6|7][0-9]{8}\"\nprint(re.findall(pattern_mobile, text))\n\n#URL\ntext = \"www.google.es\"\npattern_url = r\"^[w]{3}\\.[a-zA-Z0-9-]+\\.[a-zA-Z-.]+$\"\nprint(re.findall(pattern_url, text))\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/victorfer69.py",
    "content": "import re\n\n#Ejercicio\n\nregex = r\"\\d+\"\n\ntext = \"Este es el ejercicio 16 a fecha del 22 de enero de 2025.\"\n\ndef find_numbers(text:str) -> list:\n    return re.findall(regex, text)\n\nprint(find_numbers(text))\n\n\n#EJERCICIO EXTRA\n\ndef validate_email(email: str) -> bool:\n    return bool(re.match(r\"^[\\w.+-]+@[\\w]+\\.[a-zA-Z]+$\", email))\n\n\nprint(validate_email(\"qwert@sdf.com\"))\n\n\ndef validate_phone(phone: str) -> bool:\n    return bool(re.match(r\"^\\+?[\\d\\s]{3,}$\", phone))\n\n\nprint(validate_phone(\"+34 901 65 89 044\"))\n\n\ndef validate_url(url: str) -> bool:\n    return bool(re.match(r\"^http[s]?://(www.)?[\\w]+\\.[a-zA-Z]{2,}$\", url))\n\n\nprint(validate_url(\"http://www.moure.dev\"))\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/worlion.py",
    "content": "import unittest\nimport re\n\n\"\"\"\n * EJERCICIO: REGEX\n\"\"\"\n\ndef extract_numbers(text: str) -> str:\n    regex = \"\\d+\"\n    return re.findall(regex, txt)\n\ntxt = \"mi perro tiene 6 años y pesa 150kg., me lo compré el 7 de mayo al lado del 12 de octubre\"\n\n# print(f\"Texto: {txt}\")\n# print(f\"Numeros en el texto: {extract_numbers(txt)}\")\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n\"\"\"\n\nprint(\"\\n ---- 🌩 DIFICULTAD EXTRA 🌩 ----\\n\")\n\nrgx_digit = \"\\d+\"\nrgx_mail = \"[a-zA-Z0-9]+[a-zA-Z0-9.-]*@[a-zA-Z0-9]+[a-zA-Z0-9]*.[a-zA-Z]+\"\nrgx_phone = \"((\\+|00)\\d{1,3})?\\d{9}\"\nrgx_url = \"(http://|https://)?[a-z0-9]+([\\-\\.][a-z0-9]+)*\\.[a-z]{2,}$\"\n\ndef valid(text: str, regex: str) -> bool:\n    print(f\"validating '{text}' with '{regex}' : --> {bool(re.fullmatch(regex, text))}\")\n    return bool(re.fullmatch(regex, text))\n\ndef is_valid_number(number: str) -> bool:\n    return valid(number, rgx_digit)\n\ndef is_valid_mail(mail: str) -> bool:\n    return valid(mail, rgx_mail)\n\ndef is_valid_phone(phone: str) -> bool:\n    # Descartamos los espacios\n    return valid(phone.replace(' ', ''), rgx_phone)\n\ndef is_valid_url(url: str) -> bool:\n    return valid(url, rgx_url)\n\nclass TestRegex(unittest.TestCase):\n    \n    def test_mail(self):\n        print (\"\\nTest de mails:\")\n        self.assertTrue(is_valid_mail('imanol@pepe.com'))\n        self.assertTrue(is_valid_mail('imanol-dev@pepe.com'))\n        self.assertTrue(is_valid_mail('imanol.dev@pepe.com'))\n        \n        self.assertFalse(is_valid_mail('imanolpepe.com'))\n        self.assertFalse(is_valid_mail('-imanol@pepe.com'))\n    \n    def test_phone(self):\n        print (\"\\nTest de teléfonos:\")\n        self.assertTrue(is_valid_phone('666555444'))\n        self.assertTrue(is_valid_phone('+34666555444'))\n        self.assertTrue(is_valid_phone('+34 666 55 54 44'))\n        self.assertFalse(is_valid_phone('-1666555444'))\n        self.assertFalse(is_valid_phone('+9999999999999999999999999999666555444'))\n        self.assertFalse(is_valid_phone('A 666 55 54 44'))\n        \n    def test_url(self):\n        print (\"\\nTest de URLs:\")\n        self.assertTrue(is_valid_url('www.worlion.com'))\n        self.assertTrue(is_valid_url('http://www.worlion.com'))\n        self.assertTrue(is_valid_url('https://www.worlion.com'))\n        self.assertTrue(is_valid_url('www.worlion-willenthur.com'))\n        self.assertTrue(is_valid_url('worlion.com'))\n        \n        self.assertFalse(is_valid_url('www.worlion.com/'))\n        self.assertFalse(is_valid_url('worlioncom'))\n        self.assertFalse(is_valid_url('worlioncom'))\n        self.assertFalse(is_valid_url('httpa://www.worlion.com'))\n        self.assertFalse(is_valid_url('www.worlion..com'))\n        \n        \nif __name__ == '__main__':\n    unittest.main()\n    \n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/ycanas.py",
    "content": "import re\n\n# ------ I. Ejercicio\n\ndef extract(text: str) -> list[int]:\n    pattern: str = r\"\\d+\"\n    numbers: list[str] = re.findall(pattern, text)\n    return [int(n) for n in numbers]\n\n\nmy_text: str = \"hol4 a tod0s s0y un str1ng hell0 de numerb0s y l3tr45\"\nnumbers: int = extract(my_text)\n\nprint(f\"Números encontrados → {numbers}, total de números encontrados → {len(numbers)}\")\n\n\n# ------ II. Extra\n\ndef is_valid_email(email: str) -> bool:\n    pattern: str = r\"^[\\w.-]+@\\w+\\.[a-z.]{2,}$\"\n    return bool(re.match(pattern, email))\n\n\ndef is_valid_number(cellnumber: str) -> bool:\n    pattern: str = r\"^\\+\\d{1,3}\\s[\\d\\s]+$\"\n    return bool(re.match(pattern, cellnumber))\n\n\ndef is_valid_url(url: str) -> bool:\n    pattern: str = r\"^https?://(www.)?[\\w/-]+\\.[a-z]{2,}/?$\"\n    return bool(re.match(pattern, url))\n\n\nprint(is_valid_email(\"em4il.example@gmail.edu.co\"))\nprint(is_valid_number(\"+57 311 567 8976\"))\nprint(is_valid_url(\"https://github/io.co/\"))\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/yenneralayon142.py",
    "content": "import re\n\n\"\"\"\nExpresiones Regulares\n\"\"\"\ndef find_numbers(text:str) -> list:\n    return re.findall(r\"\\d+\",text)\n\nprint(find_numbers(\"Este es el ejercicio 16 publicado 15/04/2024.\"))\n\n\n\n\"\"\"\nExtra\n\"\"\"\n\ndef validate_email(email:str) -> bool:\n    return bool(re.match(r\"^[\\w.+-]+@[\\w]+\\.[a-zA-Z]+$\",email))\nprint(validate_email(\"yenneralayon@gmail.com\"))\n\ndef validate_phone(phone:str) -> bool:\n    return bool(re.match(r\"^\\+?[\\d\\s]{3,}$\",phone))\nprint(validate_phone(\"+57 311 200 66 77\")) \n\ndef validate_url(url: str) -> bool:\n    return bool(re.match(r\"^http[s]?://(www.)?[\\w]+\\.[a-zA-Z]{2,}$\", url))\nprint(validate_url(\"http://www.moure.dev\"))\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/python/zetared92.py",
    "content": "# RETO 16 EXPRESIONES REGULARES\n\nimport re\n\n\"\"\"\nEXPRESIÓN REGULAR QUE SEA CAPAZ DE\nEXTRAER TODOS LOS NÚMEROS DE UN TEXTO\n\"\"\"\n\ndef find_numbers(text: str) -> list:\n    return re.findall(r\"\\d+\", text)\n\nprint(find_numbers(\"El 20/07/1969, la misión estadounidense Apolo 11 colocó a los primeros hombres en la Luna: el comandante Neil Armstrong y el piloto Edwin F. Aldrin\"))\n\n# Extra\n\nprint(\"🧩 DIFICULTAD EXTRA - 3 EXPRESIONES REGULARES 🧩\")\n\n\"\"\"\nCREA 3 EXPRESIONES REGULARES CAPACES DE:\n1.- VALIDAR UN EMAIL\n2.- VALIDAR UN NÚMERO DE TELÉFONO\n3.- VALIDAR UNA URL\n\"\"\"\n\ndef validate_email(email: str) -> bool:\n    return bool(re.match(r\"^[w.+-]+@[\\w]+ \\.[a-zA-Z]+$\", email))\n\nprint(validate_email(\"zetar92@mail.com\"))\n\ndef validate_phone(phone: str) -> bool:\n    return bool(re.match(r\"^\\+?[\\d\\s]{3,}$\", phone))\n\nprint(validate_phone(\"+34 928 00 00 00\"))\n\ndef validate_url(url: str) -> bool:\n    return bool(re.match(r\"^http[s]?://(www.)?[\\w]+\\.[a-zA-Z]{2,}$\", url))\n\nprint(validate_url(\"http://www.zeta92.dev\"))"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/ruby/Elmer125.rb",
    "content": "#  * EJERCICIO:\n#  * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n#  * creando una que sea capaz de encontrar y extraer todos los números\n#  * de un texto.\n# DOC: https://www.rubyguides.com/2015/06/ruby-regex/\n\ndef get_numbers(text)\n  text.scan(/\\d+/)\nend\n\nputs get_numbers(\"Hola, mi número es 1234567890 y el tuyo?\") # [\"1234567890\"]\nputs get_numbers(\"Este es el ejercicio 16 publicado 15/04/2024.\") # [\"16\", \"15\", \"04\", \"2024\"]\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea 3 expresiones regulares (a tu criterio) capaces de:\n#  * - Validar un email.\n#  * - Validar un número de teléfono.\n#  * - Validar una url.\n\ndef email_valid?(email)\n  email.match?(/\\A[\\w+\\-.]+@[a-z\\d\\-.]+\\.[a-z]+\\z/i)\nend\n\ndef phone_valid?(phone)\n  phone.match?(/(^[3]([1-9]{2})([0-9]{7})$)/)\nend\n\ndef url_valid?(url)\n  url.match?(/\\Ahttps?:\\/\\/[a-z\\d\\-.]+\\.[a-z]+\\z/i)\nend\n\nputs \"Valid Emails\"\nputs \"joeDoe@example.com #{email_valid?(\"joeDoe@example.com\")}\" # true\nputs \"joeDoe@example #{email_valid?(\"joeDoe@example\")}\" # false\n\nputs \"Valid Phones\"\nputs \"3123456789 #{phone_valid?(\"3123456789\")}\" # true\nputs \"3120456781 #{phone_valid?(\"3021456781\")}\" # false\n\nputs \"Valid URLS\"\nputs \"https://www.example.com #{url_valid?(\"https://www.example.com\")}\" # true\nputs \"http://example #{url_valid?(\"http://example\")}\" # false"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/ruby/miguelex.rb",
    "content": "def reg_expr(cadena)\n    patron = /-?\\d*\\.?\\d+/\n    numeros = cadena.scan(patron)\n  \n    puts \"Números encontrados:\"\n    numeros.each { |numero| puts numero }\n    puts \"\\n\"\nend\n  \n\ndef email_validation(email)\n  patron = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}$/\n  if email.match?(patron)\n    puts \"El email #{email} es válido.\"\n  else\n    puts \"El email #{email} no es válido.\"\n  end\nend\n\ndef phone_validation(phone)\n  patron = /^\\+?(\\d{2,3})?[-. ]?\\d{9}$/\n  if phone.match?(patron)\n    puts \"El teléfono #{phone} es válido.\"\n  else\n    puts \"El teléfono #{phone} no es válido.\"\n  end\nend\n\ndef url_validation(url)\n  patron = /^(http|https):\\/\\/[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}/\n  if url.match?(patron)\n    puts \"La URL #{url} es válida.\"\n  else\n    puts \"La URL #{url} no es válida.\"\n  end\nend\n\ntexto = \"Este es un texto con números como 123, 45.6, -7 y 1000.\"\nputs \"Vamos a analizar el siguiente texto:\"\nputs \"'#{texto}'\\n\\n\"\nreg_expr(texto)\n\ntexto = \"123Erase una vez un número 1234567890 y otro 0987654321. Y para terminar456\"\nputs \"Vamos a analizar el siguiente texto:\"\nputs \"'#{texto}'\\n\\n\"\nreg_expr(texto)\n\nemail_validation(\"correo@correo.com\")\nemail_validation(\"correo@correo\")\n\nphone_validation(\"+34 123456789\")\nphone_validation(\"123456789\")\n\nurl_validation(\"http://www.google.com\")\nurl_validation(\"www.google.com\")\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/rust/kenysdev.rs",
    "content": "/*\n╔═══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado                ║\n║ GitHub: https://github.com/Kenysdev   ║\n║ 2024 -  Rust                          ║\n╚═══════════════════════════════════════╝\n-----------------------------------------\n* EXPRESIONES REGULARES\n-----------------------------------------\nhttps://crates.io/crates/regex\n\n[dependencies]\nregex = \"1.10.4\"\n\n* EJERCICIO #1:\n* Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n* creando una que sea capaz de encontrar y extraer todos los números\n* de un texto.\n*/\n\nuse regex::Regex;\n\nfn get_numbers(text: &str) {\n    let pattern = Regex::new(r\"\\d+\").unwrap();\n    for number in pattern.find_iter(text) {\n        println!(\"{}\", number.as_str());\n    }\n}\n\n/*\n* EJERCICIO #2:\n* Crea 3 expresiones regulares (a tu criterio) capaces de:\n* - Validar un email.\n* - Validar un número de teléfono.\n* - Validar una url.\n*/\n\nfn is_email(text: &str) -> bool {\n    let pattern = Regex::new(\n        r\"^[\\w.%+-]+@[\\w.-]+\\.[a-zA-Z]{2,}$\").unwrap();\n    return pattern.is_match(text)\n}\n\nfn is_phone_number(text: &str) -> bool {\n    let pattern = Regex::new(\n        r\"^(\\d{3}-\\d{3}-\\d{4}|\\d{10})$\").unwrap();\n    return pattern.is_match(text)\n}\n\nfn is_url(text: &str) -> bool {\n    let pattern = Regex::new(\n        r\"^(https?://)?(www\\.)?([a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,}(/\\S*)?$\"\n    ).unwrap();\n    return pattern.is_match(text)\n}\n\nfn main() {\n    println!(\"GetNumbers\");\n    get_numbers(\"abcdsfs1s(*&#}2. a3// 45sdf67\");\n    get_numbers(\"45sdf67\");\n\n    println!(\"\\nis_email\");\n    println!(\"{}\", is_email(\"ejm@dmn.com\"));        // True\n    println!(\"{}\",is_email(\"e_jm-2+b@dmn.co.hn\"));  // True\n    println!(\"{}\",is_email(\"ejm@dmn.com_\"));        // False\n    println!(\"{}\",is_email(\"ejm@dmn\"));             // False\n\n    println!(\"\\nis_email\");\n    println!(\"{}\",is_phone_number(\"123-456-7890\")); // True\n    println!(\"{}\",is_phone_number(\"1234567890\"));   // True\n    println!(\"{}\",is_phone_number(\"123456-7890\"));  // False\n    println!(\"{}\",is_phone_number(\"uno234567890\")); // False\n\n    println!(\"\\nis_url\");\n    println!(\"{}\",is_url(\"http://www.ejm.com\"));    // True\n    println!(\"{}\",is_url(\"google.com\"));            // True\n    println!(\"{}\",is_url(\"ejm.com/a/b/c\"));         // True\n    println!(\"{}\",is_url(\"https://.ejm.com\"));      // False\n    println!(\"{}\",is_url(\"https://.ejm.com/a b\"));  // False\n\n}\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/rust/miguelex.rs",
    "content": "use regex::Regex;\n\nfn reg_expr(cadena: &str) {\n    let patron = Regex::new(r\"-?\\d+(\\.\\d+)?\").unwrap();\n    let numeros: Vec<&str> = patron.find_iter(cadena).map(|m| m.as_str()).collect();\n\n    println!(\"Números encontrados:\");\n    for numero in numeros {\n        println!(\"{}\", numero);\n    }\n    println!(\"\\n\");\n}\n\nfn email_validation(email: &str) {\n    let patron = Regex::new(r\"^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}$\").unwrap();\n    if patron.is_match(email) {\n        println!(\"El email {} es válido.\", email);\n    } else {\n        println!(\"El email {} no es válido.\", email);\n    }\n}\n\nfn phone_validation(phone: &str) {\n    let patron = Regex::new(r#\"^\\+?(\\d{2,3})?[-. ]?\\d{9}$\"#).unwrap();\n    if patron.is_match(phone) {\n        println!(\"El teléfono {} es válido.\", phone);\n    } else {\n        println!(\"El teléfono {} no es válido.\", phone);\n    }\n}\n\nfn url_validation(url: &str) {\n    let patron = Regex::new(r#\"^(http|https)://[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}\"#).unwrap();\n    if patron.is_match(url) {\n        println!(\"La URL {} es válida.\", url);\n    } else {\n        println!(\"La URL {} no es válida.\", url);\n    }\n}\n\nfn main() {\n    let texto = \"Este es un texto con números como 123, 45.6, -7 y 1000.\";\n    println!(\"Vamos a analizar el siguiente texto:\");\n    println!(\"'{}'\\n\", texto);\n    reg_expr(texto);\n\n    let texto = \"123Erase una vez un número 1234567890 y otro 0987654321. Y para terminar456\";\n    println!(\"Vamos a analizar el siguiente texto:\");\n    println!(\"'{}'\\n\", texto);\n    reg_expr(texto);\n\n    email_validation(\"correo@correo.com\");\n    email_validation(\"correo@correo\");\n\n    phone_validation(\"+34 123456789\");\n    phone_validation(\"123456789\");\n\n    url_validation(\"http://www.google.com\");\n    url_validation(\"www.google.com\");\n}\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/sql/Nicojsuarez2.sql",
    "content": "# #16 EXPRESIONES REGULARES\n> #### Dificultad: Media | Publicación: 15/04/24 | Corrección: 22/04/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/swift/allbertoMD.swift",
    "content": "import Foundation\n\n// Texto que contiene números.\nlet text = \"\"\"\n    El chef preparaba la receta con precisión, midiendo cada ingrediente con cuidado. 1.25 La cocina estaba llena de aromas tentadores que  inundaban el aire, despertando el apetito de cualquiera que pasara cerca. 2 Con un toque de sal y una pizca de pimienta, el sabor de la salsa comenzaba a tomar forma. 3.75\n\n    Mientras tanto, en el horno, el pan se doraba lentamente, emitiendo un delicioso olor a hogar. 4 El chef sonrió satisfecho al ver que la masa había crecido de manera perfecta, alcanzando su punto justo de cocción. 5.5 Era un espectáculo para los sentidos, donde cada aroma, cada textura, se combinaba en armonía. 6.8\n\n    Con habilidad experta, el chef emplató cada porción con elegancia, creando una presentación digna de un restaurante de alta cocina. 7.3 Cada plato era una obra de arte comestible, lista para deleitar a los comensales más exigentes. 8 El chef sabía que la comida no solo se disfrutaba con el paladar, sino también con la vista y el olfato. 9.25\n\n    Al finalizar su obra maestra culinaria, el chef observó con orgullo la mesa preparada para recibir a los invitados. 10 Todo estaba listo para una velada inolvidable, llena de conversaciones animadas y sabores exquisitos. 11.75 Con una sonrisa, el chef se dispuso a dar la bienvenida a sus comensales, ansioso por compartir su pasión por la cocina con quienes apreciaban el arte de la gastronomía. 12.9\n\"\"\"\n\n// Lanza la \ndo {\n    // Lanza el inicializador de la structura Regex() y lo almacena en la variable regex.\n    let regex = try Regex(#\"[0-9]+(.[0-9]+)?\"#)\n    \n    // Busca los todos los matches proporcionados en la expresion regular proporcionada por la variable reges.\n    let matches = text.matches(of: regex)\n\n    // Array String donde se almacenaaran los matches conseguidos por el metodo matches(of: ).\n    var extractedNumbers = \"\"\n\n    // Itera por el array que devuelve el metodo matches(of: )\n    for m in matches {\n        // Añade uno a uno los matches y extrae el string de cada match haciendo uso de .0.\n        extractedNumbers.append(\"\\(m.0), \")\n    }\n    // Elimina los dos ultimos caracteres del String extractedNumber que es \", \".\n    extractedNumbers.removeLast(2)\n\n    // Imprime el String con los matches.\n    print(\"Estos son los números que contiene el texto:\")\n    print(extractedNumbers)\n} catch {\n    // Captura el error y lo imprime en caso de haberlo.\n    print(\"ERROR ---> \\(error.localizedDescription)\")\n}\n// Espera 5 segundos antes de ejecutar la DIFICULTAD EXTRA.\nsleep(5)\n\n\n\n\n\n\n// DIFICULTAD EXTRA\nprint(\"\\nDIFICULTAD EXTRA.\")\n\n\n\n// Pide por consola el valor de la variable email o imprime el error si algo falla.\nprint(\"\\nIntroduce la dirección de correo electronico:\")\nguard let email = readLine() else {\n    fatalError()\n}\n\ndo {\n    // Lanza el inicializador de la structura Regex() y lo almacena en la variable emailRegex.\n    let emailRegex = try Regex(#\"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$\"#)\n\n    // Compara los matches con todo el contenido de la variiable email que coincida con la expresion regular proporcionada por emailRegex.\n    if let emailWholeMatch = email.wholeMatch(of: emailRegex) {\n        // Si la expresion regular a coincidido con todo el contenido de la variable email imprime \"Dirección de correo correcta.\".\n        // La variable emailWholeMatch contiene el contenido de la variable email.\n        print(\"La diirección de correo: \\(emailWholeMatch.0) es correcta.\\n\")\n    } else {\n        // Si la expresion regular no ha coincidido con todo el contenido de la variable email se imprime \"Correo no valido.\".\n        // La Variable emailWholeMatch esta vacia.\n        print(\"Dirección de correo: \\(email) no es valida.\\n\")\n    }\n} catch {\n    // Captura el error y lo imprime en caso de haberlo.\n    print(\"ERROR ---> \\(error.localizedDescription)\")\n}\n\n\n// Pide por consola el valor de la variable telephoneNumber o imprime el error si algo falla.\nprint(\"Introduce el número de telefono, con el siguiente formato: +prefijo 111 111 111:\")\nguard let telephoneNumber = readLine() else {\n    fatalError()\n}\n\ndo {\n    // Lanza el inicializador de la structura Regex() y lo almacena en la variable telephoneNumbeeRegex.\n    let telephoneNumberRegex = try Regex(#\"^\\+\\d{1,3}\\s\\d{3}\\s\\d{3}\\s\\d{3}$\"#)\n\n    // Compara el match con todo el contenido de la variiable email que coincida con la expresion regular proporcionada por telephonoNumberRegex.\n    if let telephoneNumberWholeMatch = telephoneNumber.wholeMatch(of: telephoneNumberRegex) {\n        // Si la expresion regular a coincidido con todo el contenido de la variable email imprime \"Dirección de correo correcta.\".\n        // La variable telephoneNumberWleMatch contiene el contenido de la variable email.\n        print(\"El número de telefono: \\(telephoneNumberWholeMatch.0) es correcto.\\n\")\n    } else {\n        // Si la expresion regular no ha coincidido con todo el contenido de la variable email se imprime \"Correo no valido.\".\n        // La Variable telephoneNumberWholeMatch esta vacia.\n        print(\"El número de telefono: \\(telephoneNumber) no es valido.\\n\")\n    }\n} catch {\n    // Captura el error y lo imprime en caso de haberlo.\n    print(\"ERROR ---> \\(error.localizedDescription)\")\n}\n\n\n// Pide por consola el valor de la variable url o imprime el error si algo falla.\nprint(\"Introduce la URL:\")\nguard let url = readLine() else {\n    fatalError()\n}\n\ndo {\n    // Lanza el inicializador de la structura Regex() con la expresion regular y lo almacena en la variable urlRegex.\n    let urlRegex = try Regex(#\"^(https?|ftp):\\/\\/[^\\s\\/$.?#]+\\.[a-zA-Z]{2,}(\\/[^\\s\\/$.?#]*)?$\"#)\n\n    // Compara el match con todo el contenido de la variiable email que coincida con la expresion regular proporcionada por urlrRegex.\n    if let urlWholeMatch = url.wholeMatch(of: urlRegex) {\n            // Si la expresion regular no ha coincidido con todo el contenido de la variable email se imprime \"Correo no valido.\".\n        // La Variable urlWholeMatch tiene el contenido del la variable url.\n        print(\"La URL: \\(urlWholeMatch.0) es correcta.\\n\")\n    } else {\n        // Si la expresion regular no ha coincidido con todo el contenido de la varible email se imprime \"Correo no valido.\".\n        // La Variable telephoneNumberWholeMatch esta vacia.\n        print(\"La URL: \\(url) no es valida.\\n\")\n    }\n} catch {\n    // Captura el error y lo imprime en caso de haberlo.\n    print(\"ERROR ---> \\(error.localizedDescription)\")\n}\n\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/swift/blackriper.swift",
    "content": "import Foundation\n\n/* las expresiones regulares son patterns que nos permiten extraer informacion de una cadena de texto\n  en swift se puede evaluar la expresion regular con NSRegularExpression o con un metodo de String llamado\n  range para crear el regex se utiliza la clase Regex  para mas informacion ver:\n\n  https://developer.apple.com/documentation/foundation/nsregularexpression\n  https://www.advancedswift.com/regular-expressions/\n\n  para este ejercicio solo vamos a usar el metodo range\n */\n\n\nfunc examplePattern() {\n   let exampleText = \"\"\"\n        El manga Hokuto no ken cuenta con 245 capítulos, publicados en la revista semanal Shōnen Jump,\n        desde el número 41 de 1983 hasta el número 35 de 1988. Luego fue recopilado en 27 volúmenes\n        por Shueisha. Se está publicando en 14 Kanzenban por Shōgakukan y una Master Edition de 27 volúmenes \n        por Coamix.\n        \"\"\"\n\n   do {\n     let pattern = try Regex(\"[0-9]\")\n     print(exampleText.ranges(of: pattern).map { String(exampleText[$0]) })\n   } catch {\n     print(error)\n   }\n   \n }\n\n examplePattern()\n\n // ejercicio extra \n \n enum ValidData {\n    case url  \n    case email\n    case phone\n }\n   \n  // para mas informacion de los patters te invito a ver mi solucion en kotlin \n func validateData(_ data: String, type: ValidData) throws ->  Bool {\n   \n   let regEx = switch type {\n   case .url:\n        \"^(https?)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]\"\n\n   case .email:\n        \"^[a-zA-Z0-9_+&*-]+(?:\\\\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\\\\.)+[a-zA-Z]{2,7}$\"\n   \n   case .phone:\n      #\"^\\(?\\d{3}\\)?[ -]?\\d{3}[ -]?\\d{4}$\"# \n    }\n\n   let result = data.range(of: regEx, options: .regularExpression) \n   return (result != nil)\n }\n\n do {\n   let validUrl = try validateData(\"https://google.com\", type: .url)\n   print(validUrl)\n\n   let validEmail = try validateData(\"XG7p7@example.com\", type: .email)\n   print(validEmail)\n\n   let validPhone = try validateData(\"411-153-1223\", type: .phone)\n   print(validPhone)\n\n } catch {\n   print(error)\n }\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/swift/miguelex.swift",
    "content": "import Foundation\n\nfunc regExpr(_ cadena: String) {\n    let pattern = #\"-?\\d*\\.?\\d+\"#\n    let regex = try! NSRegularExpression(pattern: pattern)\n    let matches = regex.matches(in: cadena, range: NSRange(cadena.startIndex..., in: cadena))\n    \n    print(\"Números encontrados:\")\n    for match in matches {\n        if let range = Range(match.range, in: cadena) {\n            print(String(cadena[range]))\n        }\n    }\n    print(\"\\n\")\n}\n\nfunc emailValidation(_ email: String) {\n    let pattern = #\"^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}$\"#\n    let regex = try! NSRegularExpression(pattern: pattern)\n    if regex.firstMatch(in: email, options: [], range: NSRange(location: 0, length: email.utf16.count)) != nil {\n        print(\"El email \\(email) es válido.\")\n    } else {\n        print(\"El email \\(email) no es válido.\")\n    }\n}\n\nfunc phoneValidation(_ phone: String) {\n    let pattern = #\"^\\+?(\\d{2,3})?[-. ]?\\d{9}$\"#\n    let regex = try! NSRegularExpression(pattern: pattern)\n    if regex.firstMatch(in: phone, options: [], range: NSRange(location: 0, length: phone.utf16.count)) != nil {\n        print(\"El teléfono \\(phone) es válido.\")\n    } else {\n        print(\"El teléfono \\(phone) no es válido.\")\n    }\n}\n\nfunc urlValidation(_ url: String) {\n    let pattern = #\"^(http|https)://[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}\"#\n    let regex = try! NSRegularExpression(pattern: pattern)\n    if regex.firstMatch(in: url, options: [], range: NSRange(location: 0, length: url.utf16.count)) != nil {\n        print(\"La URL \\(url) es válida.\")\n    } else {\n        print(\"La URL \\(url) no es válida.\")\n    }\n}\n\nlet texto = \"Este es un texto con números como 123, 45.6, -7 y 1000.\"\nprint(\"Vamos a analizar el siguiente texto:\")\nprint(\"'\\(texto)'\\n\")\nregExpr(texto)\n\nlet texto2 = \"123Erase una vez un número 1234567890 y otro 0987654321. Y para terminar456\"\nprint(\"Vamos a analizar el siguiente texto:\")\nprint(\"'\\(texto2)'\\n\")\nregExpr(texto2)\n\nemailValidation(\"correo@correo.com\")\nemailValidation(\"correo@correo\")\n\nphoneValidation(\"+34 123456789\")\nphoneValidation(\"123456789\")\n\nurlValidation(\"http://www.google.com\")\nurlValidation(\"www.google.com\")\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/swift/pedroomar23.swift",
    "content": "import Foundation\n\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\n */\n\nfunc textExample() {\n    let text = \"\"\"\n        La serie Naruto tiene 987 capitulos, con 2 temporadas. La serie fue vista en su\n        estrenos por millones de personas en cerca de mas de 50 paises. Cada temporada conto con 456 capitulos con una \n        duracion de 20 minutos cada uno.\n    \"\"\"\n    do {\n        let serie = try Regex(\"[0-5]\")\n    } catch {\n        print(\"Se ha encontrado un error al extraer los numeros \\(error.localizedDescription)\")\n    }\n}\n\nlet newSerie = textExample()\nprint(newSerie)\n\n// Extra \nfunc validEmail(email: String) -> Bool { // Validar Email\n    return email.hasSuffix(\"@gmail.com\")\n}\nlet newEmail = validEmail(email: \"@yahoo.com\")\nprint(newEmail)\n\nfunc validNumber(numero: Int) -> Bool { // Validar numero de telefono\n    return numero != 50987654\n}\nlet newNumero = validNumber(numero: 564356785678)\nprint(newNumero)\n\nfunc validUrl(url: String) -> Bool {\n    return url.hasSuffix(\"www.google.com\")\n}\nlet newUrl = validUrl(url: \"www.yahoo.com\")\nprint(newUrl)\n\nfunc validTodo(email: String, numero: Int, url: String) -> Bool { // Validar Todo \n    return validEmail(email: email) && validNumber(numero: numero) && validUrl(url: url)\n}\nlet new = validTodo(email: \"@yahoo.com\", numero: 65789065, url: \"www.yahoo.com\")\nprint(new)\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/typescript/AChapeton.ts",
    "content": "// EJERCICIO\n\nconst regexHasNumbers: RegExp = /[0-9]/\n\nconst text1: string = 'Lorem Ipsum es simplemente el texto de relleno de las imprentas desde el año 1500'\nconst text2: string = 'Solo letras, sin nada de numeros'\n\nconst text3: string = '1234567890-abc'\n\nconsole.log(`El texto \"${text1}\" tiene numeros?: `, regexHasNumbers.test(text1))\nconsole.log(`El texto \"${text2}\" tiene numeros?: `,regexHasNumbers.test(text2))\nconsole.log(`El texto \"${text3}\" tiene numeros?: `,regexHasNumbers.test(text3))\n\n// DESAFIO EXTRA\n\n//Regex para correos\nconst regexEmail: RegExp = /^[\\w\\-\\.]+@([\\w]+\\.)+[\\w]{2,4}$/\n\nconst email1: string = 'andres.chapeton0206@gmail.com'\nconst email2: string = 'andres@gmail'\n\nconsole.log(`El correo \"${email1}\" es valido?: `, regexEmail.test(email1))\nconsole.log(`El correo \"${email2}\" es valido?: `, regexEmail.test(email2))\n\n\n// Regex para telefonos (Con formato 0000-0000)\n\nconst regexPhone: RegExp = /([0-9]{4})-([0-9]{4})/\n\nconst phone1: string = '7777-9999'\nconst phone2: string = '77-5555'\n\nconsole.log(`El telefono \"${phone1}\" es valido?: `, regexPhone.test(phone1))\nconsole.log(`El telefono \"${phone2}\" es valido?: `, regexPhone.test(phone2))\n\n\n// Regex para URL (Con formato https o http)\n\nconst regexURL: RegExp = /^https?:\\/\\/([a-zA-Z0-9]*\\.)?[a-zA-Z0-9]*\\.([a-zA-Z]{3})(\\.[a-zA-Z]{2,3})?\\/?$/\n\nconst url1: string = 'https://www.moure.dev'\nconst url2: string = 'http://www.holamundo.dev'\nconst url3: string = 'www.google.com'\nconst url4: string = 'https://www.google'\nconst url5: string = 'w.google'\n\nconsole.log(`La URL \"${url1}\" es valida?: `, regexURL.test(url1))\nconsole.log(`La URL \"${url2}\" es valida?: `, regexURL.test(url2))\nconsole.log(`La URL \"${url3}\" es valida?: `, regexURL.test(url3))\nconsole.log(`La URL \"${url4}\" es valida?: `, regexURL.test(url4))\nconsole.log(`La URL \"${url5}\" es valida?: `, regexURL.test(url5))"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/typescript/IgleDev.ts",
    "content": "// Ejercicio 1º\n\n    let texto : string = 'Buenas días! Hoy hacen 25º Grados en pleno 16 de Abril de 2024';\n\n    let expresionRegular = /\\d+/g;\n\n    let numeros = texto.match(expresionRegular);\n\n    if(numeros !== null){\n        console.log(`Números encontrados: ${numeros}`);\n    }else{\n        console.log(`No hay números`);\n    }\n\n// Ejercicio Extra\n    // GMAIL\n        let expresionGmail = /^[a-zA-Z0-9._%+-]+@gmail\\.com$/;\n        let correoElectronico = 'adri.iglesias.fernandez@gmail.com';\n\n        if (expresionGmail.test(correoElectronico)) {\n            console.log('El correo electrónico es válido.');\n        } else {\n            console.log('El correo electrónico no es válido.');\n        }\n\n    // Nº Telefono - Versión España\n        let expresionTelefono = /^\\+34\\s?(\\d{3}\\s?){3}$/;\n        let numeroTelefono = '+34 123 456 789';\n        \n        if (expresionTelefono.test(numeroTelefono)) {\n            console.log('El número de teléfono es válido.');\n        } else {\n            console.log('El número de teléfono no es válido.');\n        }\n    \n    // URL\n        let expresionURL = /^(http|https):\\/\\/[a-zA-Z0-9]+(\\.[a-zA-Z]{2,}){1,}$/;\n        let url = 'https://igledev.netlify.app';\n        \n        if (expresionURL.test(url)) {\n            console.log('La URL es válida.');\n        } else {\n            console.log('La URL no es válida.');\n        }"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/typescript/Sac-Corts.ts",
    "content": "const text: string = \"There are 3 cats, 7 dogs and 15 birds in the park.\";\nconst numbers: string[] = text.match(/\\d+/g) || [];\nconsole.log(numbers);\n\n// ** Extra Exercise ** //\n\nconst emailPattern: RegExp = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$/;\nconst email: string = \"isaac@gmail.com\";\nconsole.log(emailPattern.test(email)); \n\nconst telPattern: RegExp = /^\\d{3}-\\d{3}-\\d{4}$/;\nconst number: string = \"899-112-5641\";\nconsole.log(telPattern.test(number));\n\nconst urlPattern: RegExp = /^(https?:\\/\\/)?([\\da-z.-]+\\.[a-z.]{2,6}|[\\d.]+)(:[0-9]{1,5})?(\\/[\\w.-]*)*\\/?(\\?[\\w=&]*)?(#[\\w-]*)?$/i;\nconst url: string = \"https://retosdeprogramacion.com/roadmap/\";\nconsole.log(urlPattern.test(url));\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/typescript/duendeintemporal.ts",
    "content": "// #16 { Retosparaprogramadores } EXPRESIONES REGULARES\n// Bibliography reference:\n// Professional JavaScript for web developers by Matt Frisbie [Frisbie, Matt] (z-lib.org)\n\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\n */\n\n// Short for console.log()\nconst log = console.log;\n\n// Conditional check for browser environment\nif (typeof window !== 'undefined') {\n    window.addEventListener('load', () => {\n        const body: HTMLBodyElement | null = document.querySelector('body');\n        const title = document.createElement('h1');\n\n        body?.style.setProperty('background', '#000');\n        body?.style.setProperty('text-align', 'center');\n\n        title.textContent = 'Retosparaprogramadores #16.';\n        title.style.setProperty('font-size', '3.5vmax');\n        title.style.setProperty('color', '#fff');\n        title.style.setProperty('line-height', '100vh');\n\n        body?.appendChild(title);\n\n        setTimeout(() => {\n            alert('Retosparaprogramadores #16. Please open the Browser Developer Tools.');\n        }, 2000);\n        log('Retosparaprogramadores #16');\n});\n} else {\n    log('This code is designed to run in a browser environment. Skipping window-related code.');\n    log('Retosparaprogramadores #16');\n}\n\n/*\n * Regular Expression Flags (Modifiers):\n * - g: Global mode (applies to all matches in the string).\n * - i: Case-insensitive mode.\n * - m: Multiline mode.\n * - y: Sticky mode.\n * - u: Unicode mode.\n */\n\n/*\n * Regular Expression Metacharacters:\n * ( [ { \\ ^ $ | ) ] } ? * + .\n * These must be escaped when used in a pattern.\n */\n\n/*\n * RegExp Instance Properties:\n * - global: Boolean indicating if the 'g' flag is set.\n * - ignoreCase: Boolean indicating if the 'i' flag is set.\n * - unicode: Boolean indicating if the 'u' flag is set.\n * - sticky: Boolean indicating if the 'y' flag is set.\n * - lastIndex: Integer indicating the position for the next match.\n * - multiline: Boolean indicating if the 'm' flag is set.\n * - source: The source string of the regular expression.\n * - flags: The flags of the regular expression.\n */\n\n// Define a pattern and flags\nconst pattern0: string = 'abc';\nconst flags: string = 'gi'; // Global and case-insensitive\n\n// Create a regular expression using the RegExp constructor\nconst regex: RegExp = new RegExp(pattern0, flags);\n\nlog(regex); // Output: /abc/gi\n\nlet text: string = \"time: 08:07:06\";\nlet pattern1 = /(time(:)?)? ?([01][0-9]|2[0-3])([:/-])([0-5][0-9])\\4([0-5][0-9])/;\n\n/*\n * Explanation of the regular expression:\n * - (time(:)?): Optionally matches the word \"time\" followed by an optional colon (:).\n * - ?: Matches an optional space.\n * - ([01][0-9]|2[0-3]): Matches the hour (00-23).\n * - ([:/-]): Matches a separator (:, /, or -).\n * - ([0-5][0-9]): Matches the minutes (00-59).\n * - \\4: References the fourth captured group (separator).\n * - ([0-5][0-9]): Matches the seconds (00-59).\n */\n\nlet matches1 = pattern1.exec(text);\n\nif (matches1) {\n    log(matches1.index); // 0\n    log(matches1.input); // time: 08:07:06\n    log(matches1[0]); // time: 08:07:06\n    log(matches1[1]); // time:\n    log(matches1[2]); // :\n}\n\nlet pattern = /[0-9]/g;\nlet matches = pattern.exec(text);\nif (matches) log(matches); // ['0', index: 6, input: 'time: 08:07:06', groups: undefined]\n\nlet matches3 = text.match(pattern);\nif (matches3) log(matches3); // ['0', '8', '0', '7', '0', '6']\n\n// Note: match() returns all matches when using the global flag 'g'.\n\nif (matches3) {\n    log(matches3.index); // undefined\n    log(matches3.input); // undefined\n    log(matches3[0]); // 0\n    log(matches3[1]); // 8\n    log(matches3[2]); // 0\n}\n\nlet pattern2 = /\\d/g;\nlet matches2 = pattern2.exec(text);\nif (matches2) log(matches2); // ['0', index: 6, input: 'time: 08:07:06', groups: undefined]\n\nlet matches4 = text.match(pattern2);\nif (matches4) log(matches4); // ['0', '8', '0', '7', '0', '6']\n\n/*\n * exec: Returns the first match and can be used in a loop to find all matches.\n * match: Returns an array with all matches in a more direct and straightforward way.\n */\n\n// Extra Difficulty Exercise:\n\n/**\n * Validates a telephone number.\n * @param num - The telephone number to validate.\n * @returns True if the telephone number is valid, otherwise false.\n */\nconst validateTlf = (num: string): boolean => {\n    if (!/^\\d{11}$/.test(num)) {\n        console.log(\"Invalid telephone number. Must be a numeric value and have 11 digits.\");\n        return false;\n    }\n    return true;\n};\n\n/**\n * Validates an email address.\n * @param email - The email address to validate.\n * @returns True if the email address is valid, otherwise false.\n */\nconst validateEmail = (email: string): boolean => {\n    const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$/;\n    if (!emailRegex.test(email)) {\n        console.log(\"Invalid email address.\");\n        return false;\n    }\n    return true;\n};\n\n/**\n * Validates a URL.\n * @param url - The URL to validate.\n * @returns True if the URL is valid, otherwise false.\n */\nconst validateURL = (url: string): boolean => {\n    const urlRegex = /^(https?:\\/\\/)?([a-zA-Z0-9.-]+)(:[0-9]{1,5})?(\\/[^\\s]*)?$/;\n    if (!urlRegex.test(url) || (!url.startsWith('http://') && !url.startsWith('https://'))) {\n        console.log(\"Invalid URL.\");\n        return false;\n    }\n    return true;\n};\n\n// Test cases\nlet num1 = \"1562737848\"; // Invalid (less than 11 digits)\nlet num2 = \"34587452387\"; // Valid (11 digits)\nlet email1 = 'kamsutraniko@proton.me'; // Valid\nlet email2 = 'kat@hotgirl.net'; // Valid\nlet url1 = 'http://palnetaneurodiverso.org'; // Valid\nlet url2 = 'https://moebius.org'; // Valid\nlet url3 = 'something.com'; // Invalid (missing protocol)\nlet url4 = 'gato'; // Invalid (not a URL)\n\nlog(validateTlf(num1)); // Invalid telephone number. Must be a numeric value and have 11 digits. \n//false\nlog(`Is a valid tlf: ${validateTlf(num2)}`); // Is a valid tlf: true\nlog(`Is a valid email: ${validateEmail(email1)}`); // Is a valid email: true\nlog(`Is a valid email: ${validateEmail(email2)}`); // Is a valid email: true\nlog(`Is a valid URL: ${validateURL(url1)}`); // Is a valid URL: true\nlog(`Is a valid URL: ${validateURL(url2)}`); // Is a valid URL: true\nlog(`Is a valid URL: ${validateURL(url3)}`); // Invalid URL. \n// Is a valid URL: false\nlog(`Is a valid URL: ${validateURL(url4)}`); // Invalid URL. \n// Is a valid URL: false"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/typescript/eulogioep.ts",
    "content": "/**\n * Ejercicio de Expresiones Regulares en TypeScript\n * \n * Este script demuestra el uso de expresiones regulares para:\n * 1. Extraer números de un texto\n * 2. Validar direcciones de email\n * 3. Validar números de teléfono\n * 4. Validar URLs\n */\n\n// Texto de ejemplo para probar las expresiones regulares\nconst textoEjemplo: string = `Hola, tengo 25 años y mi número es 123-456-789. \nTambién puedes contactarme al +34 611 222 333 o por email a usuario@dominio.com. \nVisita mi página web en https://www.ejemplo.com para más información. \nHay 42 razones para usar expresiones regulares y 100 formas de aplicarlas.`;\n\n/**\n * Interfaz para los resultados de validación\n */\ninterface ResultadoValidacion {\n    valor: string;\n    esValido: boolean;\n}\n\n/**\n * 1. Clase para manejar la extracción de números\n */\nclass ExtractorNumeros {\n    private static readonly PATRON: RegExp = /\\b\\d+\\b/g;\n\n    /**\n     * Extrae todos los números de un texto dado\n     * @param texto - El texto del que extraer los números\n     * @returns Un array con todos los números encontrados\n     */\n    public static extraer(texto: string): string[] {\n        return texto.match(this.PATRON) || [];\n    }\n}\n\n/**\n * 2. Clase para validación de email\n */\nclass ValidadorEmail {\n    private static readonly PATRON: RegExp = /^[\\w.-]+@[\\w.-]+\\.\\w+$/;\n\n    /**\n     * Valida una dirección de email\n     * @param email - El email a validar\n     * @returns Un objeto ResultadoValidacion con el resultado\n     */\n    public static validar(email: string): ResultadoValidacion {\n        return {\n            valor: email,\n            esValido: this.PATRON.test(email)\n        };\n    }\n}\n\n/**\n * 3. Clase para validación de números de teléfono\n */\nclass ValidadorTelefono {\n    private static readonly PATRON: RegExp = /^(\\+\\d{1,3}\\s?)?(\\d{3}[-\\s]?){2}\\d{3}$/;\n\n    /**\n     * Valida un número de teléfono\n     * @param telefono - El número de teléfono a validar\n     * @returns Un objeto ResultadoValidacion con el resultado\n     */\n    public static validar(telefono: string): ResultadoValidacion {\n        return {\n            valor: telefono,\n            esValido: this.PATRON.test(telefono)\n        };\n    }\n}\n\n/**\n * 4. Clase para validación de URLs\n */\nclass ValidadorURL {\n    private static readonly PATRON: RegExp = /^https?:\\/\\/(www\\.)?[\\w.-]+\\.\\w{2,}$/;\n\n    /**\n     * Valida una URL\n     * @param url - La URL a validar\n     * @returns Un objeto ResultadoValidacion con el resultado\n     */\n    public static validar(url: string): ResultadoValidacion {\n        return {\n            valor: url,\n            esValido: this.PATRON.test(url)\n        };\n    }\n}\n\n/**\n * Función para imprimir los resultados de validación\n */\nfunction imprimirResultados(titulo: string, resultados: ResultadoValidacion[]): void {\n    console.log(`\\n${titulo}`);\n    resultados.forEach(({ valor, esValido }) => {\n        console.log(`${valor} es ${esValido ? 'válido' : 'inválido'}`);\n    });\n}\n\n// Ejecución de pruebas\nfunction ejecutarPruebas(): void {\n    console.log('=== PRUEBAS DE EXPRESIONES REGULARES ===');\n\n    // 1. Extraer números\n    const numerosEncontrados: string[] = ExtractorNumeros.extraer(textoEjemplo);\n    console.log('\\n1. Números encontrados:');\n    numerosEncontrados.forEach(numero => console.log(numero));\n\n    // 2. Validar emails\n    const emails: string[] = ['usuario@dominio.com', 'email_invalido.com', 'test@test.co.uk'];\n    const resultadosEmail: ResultadoValidacion[] = emails.map(email => ValidadorEmail.validar(email));\n    imprimirResultados('2. Validación de emails:', resultadosEmail);\n\n    // 3. Validar números de teléfono\n    const telefonos: string[] = ['123-456-789', '+34 611 222 333', '1234', '999-999-999'];\n    const resultadosTelefono: ResultadoValidacion[] = telefonos.map(tel => ValidadorTelefono.validar(tel));\n    imprimirResultados('3. Validación de números de teléfono:', resultadosTelefono);\n\n    // 4. Validar URLs\n    const urls: string[] = ['https://www.ejemplo.com', 'http://ejemplo', 'https://dominio.es'];\n    const resultadosURL: ResultadoValidacion[] = urls.map(url => ValidadorURL.validar(url));\n    imprimirResultados('4. Validación de URLs:', resultadosURL);\n}\n\n// Ejecutar todas las pruebas\nejecutarPruebas();"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/typescript/hozlucas28.ts",
    "content": "/*\n    Regular expressions...\n*/\n\nconsole.log('Regular expressions...')\n\nconst customText: string =\n\t'¡Hola Mundo! Hoy es 15/04/2024. Quedan 263 días para terminar el año 2024.'\n\nconst numbersInsideCustomText: `${number}` = customText\n\t.match(/[0-9]/g)\n\t?.join('') as `${number}`\n\nconsole.log(`\\n\\`customText\\` = '${customText}'`)\n\nconsole.log(`\\nNumbers inside \\`customText\\` --> ${numbersInsideCustomText}`)\n\nconsole.log(\n\t'\\n# ---------------------------------------------------------------------------------- #\\n'\n)\n\n/*\n    Additional challenge...\n*/\n\nconsole.log('Additional challenge...')\n\nconst regularExpressions = {\n\temail: new RegExp(/^[a-zA-Z0-9]*@(gmail|outlook|hotmail|yahoo)\\.com$/),\n\tphoneNumber: new RegExp(/^\\+\\d{1,4} \\d{10}$/),\n\turl: new RegExp(\n\t\t/^https?:\\/\\/([a-zA-Z0-9]*\\.)?[a-zA-Z0-9]*\\.([a-zA-Z]{3})(\\.[a-zA-Z]{2,3})?\\/?$/\n\t),\n}\n\nconst emails: string[] = [\n\t'hozlucas28@gmail.com',\n\t'hozlucas28@dev.com',\n\t'hozlucas-28@hotmail.com',\n\t'hozlucas28@meli.com',\n\t'hozlucas28@edu.com',\n]\n\nconst phoneNumbers: string[] = [\n\t'+1234567890',\n\t'+1 1234567890',\n\t'+1234 1234567890',\n\t'+123456789',\n\t'+123456789 1234567890',\n]\n\nconst urls: string[] = [\n\t'https://www.example.cóm',\n\t'http://example.com',\n\t'https://subdomain.example.com',\n\t'http://www.example.c2.uk',\n\t'https://www.example.org',\n]\n\nconsole.log('\\n\\nEmails...')\n\nfor (const email of emails) {\n\tconst isValid: boolean = regularExpressions.email.test(email)\n\tconsole.log(`\\n'${email}' is valid? --> ${isValid}`)\n}\n\nconsole.log('\\n\\nPhone numbers...')\n\nfor (const phoneNumber of phoneNumbers) {\n\tconst isValid: boolean = regularExpressions.phoneNumber.test(phoneNumber)\n\tconsole.log(`\\n'${phoneNumber}' is valid? --> ${isValid}`)\n}\n\nconsole.log('\\n\\nUrls...')\n\nfor (const url of urls) {\n\tconst isValid: boolean = regularExpressions.url.test(url)\n\tconsole.log(`\\n'${url}' is valid? --> ${isValid}`)\n}\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/typescript/miguelex.ts",
    "content": "function regExpr(cadena: string): void {\n    let patron: RegExp = /-?\\d+(\\.\\d+)?/g;\n    let numeros: RegExpMatchArray | null = cadena.match(patron);\n\n    console.log(\"Números encontrados:\");\n    if (numeros) {\n        numeros.forEach(numero => console.log(numero));\n    }\n    console.log();\n}\n\nlet texto: string = \"Este es un texto con números como 123, 45.6, -7 y 1000.\";\nconsole.log(\"Vamos a analizar el siguiente texto:\");\nconsole.log(\"'\" + texto + \"'\\n\");\nregExpr(texto);\n\ntexto = \"123Erase una vez un número 1234567890 y otro 0987654321. Y para terminar456\";\nconsole.log(\"Vamos a analizar el siguiente texto:\");\nconsole.log(\"'\" + texto + \"'\\n\");\nregExpr(texto);\n\nfunction emailValidation(email: string): void {\n    let patron: RegExp = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}$/;\n    if (patron.test(email)) {\n        console.log(\"El email \" + email + \" es válido.\");\n    } else {\n        console.log(\"El email \" + email + \" no es válido.\");\n    }\n}\n\nfunction phoneValidation(phone: string): void {\n    let patron: RegExp = /^\\+?(\\d{2,3})?[-. ]?\\d{9}$/;\n    if (patron.test(phone)) {\n        console.log(\"El teléfono \" + phone + \" es válido.\");\n    } else {\n        console.log(\"El teléfono \" + phone + \" no es válido.\");\n    }\n}\n\nfunction urlValidation(url: string): void {\n    let patron: RegExp = /^(http|https):\\/\\/[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}/;\n    if (patron.test(url)) {\n        console.log(\"La URL \" + url + \" es válida.\");\n    } else {\n        console.log(\"La URL \" + url + \" no es válida.\");\n    }\n}\n\nemailValidation(\"correo@correo.com\");\nemailValidation(\"correo@correo\");\n\nphoneValidation(\"+34 123456789\");\nphoneValidation(\"123456789\");\n\nurlValidation(\"http://www.google.com\");\nurlValidation(\"www.google.com\");\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/typescript/nlarrea.ts",
    "content": "/*\n * EJERCICIO:\n * Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n * creando una que sea capaz de encontrar y extraer todos los números\n * de un texto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\n */\n\n\nconst getNumbersFromText = (text: string): string[] | null => {\n    const regExp = /\\d{1,}/g\n    return text.match(regExp)\n}\n\n\nconst longText = `\nLorem ipsum dolor1 sit amet, consectetur adipiscing elit. Nullam ac mi in\nipsum ultricies 2 varius. Nullam euismod, justo nec fermentum ultricies, nunc\nnisl tempus purus, 3 sed dictum 563 nulla odio nec purus. Nullam nec purus\nconsectetur, consectetur justo. 10 Nullam nec purus consectetur, consectetur.\n`\ngetNumbersFromText(longText)  // ['1', '2', '3', '563', '10']\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea 3 expresiones regulares (a tu criterio) capaces de:\n * - Validar un email.\n * - Validar un número de teléfono.\n * - Validar una url.\n */\n\n\nfunction printTests(pattern: RegExp, text: string): void {\n    const result: RegExpMatchArray | null = text.match(pattern)\n\n    console.log(`${text}: ${(result?.length ?? 0) > 0}`)\n}\n\n\n// Validar un email\n\nconst checkEmailPattern: RegExp = /^[\\w]{1,}[\\w\\d\\._]{4,}\\@[\\w]{2,}\\.[\\w]{2,3}$/g\nconsole.log('\\nTesting emails:')\nprintTests(checkEmailPattern, 'an_email@gmail.com')  // true\nprintTests(checkEmailPattern, '1234@email.com')  // false\nprintTests(checkEmailPattern, 'an_email1234')  // false\nprintTests(checkEmailPattern, 'an2_email4@gmail.com')  // true\nprintTests(checkEmailPattern, 'another.2024@gmail')  // false\nprintTests(checkEmailPattern, 'another.2024@gmail.')  // false\nprintTests(checkEmailPattern, 'another.2024@gmail.com')  // true\n\n// Validar un número de teléfono\n\nconst checkPhonePattern: RegExp = /^\\+?\\d{3,}$/g\nconsole.log('\\nTesting phone numbers:')\nprintTests(checkPhonePattern, '123456789')  // true\nprintTests(checkPhonePattern, '+34123456789')  // true\nprintTests(checkPhonePattern, 'abcdefghi')  // false\n\n// Validar una url\n\nconst checkUrlPattern: RegExp = /^https?:\\/\\/(w{3}\\.)?[\\w\\d\\.\\-\\?]+\\.[\\w]{2,}\\/?$/g\nconsole.log('\\nTesting URLs:')\nprintTests(checkUrlPattern, 'https://github.com/')  // true\nprintTests(checkUrlPattern, 'https://www.twitch.tv')  // true"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/typescript/victor-Casta.ts",
    "content": "const text: string = 'lor0em 9ip6sum 2 dolor 334, asit am3ed'\nconst getNumbersRegex: RegExp = /\\d/g\nconsole.log(text.match(getNumbersRegex)?.join(''))\n\n// extra\n\nconst emailRegex: RegExp  = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/\nconst phoneRegex: RegExp = /^\\+?[1-9]\\d{1,14}$/\nconst urlRegex: RegExp  = /^(https?:\\/\\/)?([\\da-z\\.-]+)\\.([a-z\\.]{2,6})([\\/\\w \\.-]*)*\\/?$/"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/typescript/victoriaparraf.ts",
    "content": "/*se definen utilizando dos barras inclinadas (/pattern/) o el constructor RegExp. */\nlet regex = /abc/;\nconst regexConstructor = new RegExp('abc');\n\n//Busqueda en una cadena\nconst regular = /hello/;\nlet str = \"hello world\";\nconsole.log(regular.test(str)); // true\n\n//Busqueda con más opciones\nconst exp = /h.llo/;\nconst cadena = \"hello world\";\nconsole.log(exp.test(cadena)); // true (coincide con \"hello\" y \"hallo\")\n\n//Reemplazo de una cadena\nregex = /world/;\nstr = \"hello world\";\nconst newStr = str.replace(regex, \"TypeScript\");\nconsole.log(newStr); // hello TypeScript\n\n//Extraccion de coincidencias\nregex = /\\d+/;\nstr = \"There are 123 apples\";\nconst match = str.match(regex);\nconsole.log(match); // [\"123\"]\n\n//division de una cadena\nregex = /\\s+/;\nstr = \"Split this string into words\";\nconst words = str.split(regex);\nconsole.log(words); // [\"Split\", \"this\", \"string\", \"into\", \"words\"]\n\n//buscar y extraer numeros de una cadena\nconst text = \"En el año 2024, hubo 300 eventos importantes y 12 conferencias.\";\nconst numberRegex = /\\d+/g;\nconst numbers = text.match(numberRegex);\n\nif (numbers) {\n    console.log(numbers); // [\"2024\", \"300\", \"12\"]\n} else {\n    console.log(\"No se encontraron números.\");\n}\n\n/*EXTRAAAAAAA*/\n\nconst emailRegex = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,6}$/;\nconst email = \"test@example.com\";\nconsole.log(emailRegex.test(email)); // true\n\nconst urlRegex = /^(https?:\\/\\/)?([\\da-z.-]+)\\.([a-z.]{2,6})([/\\w .-]*)*\\/?$/;\nconst url = \"https://www.example.com\";\nconsole.log(urlRegex.test(url)); // true\n\nconst phoneRegex = /^\\+?\\d{1,3}?[-.\\s]?\\(?\\d{1,4}?\\)?[-.\\s]?\\d{1,4}[-.\\s]?\\d{1,9}$/;\nconst phoneNumber = \"+1-800-555-1234\";\nconsole.log(phoneRegex.test(phoneNumber)); // true\n\n\n"
  },
  {
    "path": "Roadmap/16 - EXPRESIONES REGULARES/vb.net/kenysdev.vb",
    "content": "' ╔══════════════════════════════════════╗\n' ║ Autor:  Kenys Alvarado               ║\n' ║ GitHub: https://github.com/Kenysdev  ║\n' ║ 2024 -  VB.NET                       ║\n' ╚══════════════════════════════════════╝\n'-----------------------------------------------\n'* EXPRESIONES REGULARES\n'-----------------------------------------------\nImports System.Text.RegularExpressions\n\nModule Program\n    '* EJERCICIO #1:\n    '* Utilizando tu lenguaje, explora el concepto de expresiones regulares,\n    '* creando una que sea capaz de encontrar y extraer todos los números\n    '* de un texto.\n\n    Sub GetNumbers(text As String)\n        Dim pattern = \"\\d+\"\n        Dim numbers = Regex.Matches(text, pattern)\n\n        For Each n As Match In numbers\n            Console.WriteLine(n)\n        Next\n    End Sub\n\n    '* EJERCICIO #2\n    '* Crea 3 expresiones regulares (a tu criterio) capaces de\n    '* - Validar un email.\n    '* - Validar un número de teléfono.\n    '* - Validar una url.\n\n    Function IsEmail(text As String) As Boolean\n        Dim pattern = \"^[\\w.%+-]+@[\\w.-]+\\.[a-zA-Z]{2,}$\"\n        Return Regex.IsMatch(text, pattern)\n    End Function\n\n    Function IsPhoneNumber(text As String) As Boolean\n        Dim pattern = \"^(\\d{3}-\\d{3}-\\d{4}|\\d{10})$\"\n        Return Regex.IsMatch(text, pattern)\n    End Function\n\n    Function IsURL(text As String) As Boolean\n        Dim pattern = \"^(https?://)?(www\\.)?([a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,}(/\\S*)?$\"\n        Return Regex.IsMatch(text, pattern)\n    End Function\n\n    Sub Print(text As Object)\n        Console.WriteLine(text)\n    End Sub\n\n    Sub Main()\n        Print(\"GetNumbers\")\n        GetNumbers(\"abcdsfs1s(*&#}2. a3// 45sdf67\")\n        GetNumbers(\"45sdf67\")\n\n        Print(vbCrLf + \"IsEmail\")\n        Print(IsEmail(\"ejm@dmn.com\"))         ' True\n        Print(IsEmail(\"e_jm-2+b@dmn.co.hn\"))  ' True\n        Print(IsEmail(\"ejm@dmn.com_\"))        ' False\n        Print(IsEmail(\"ejm@dmn\"))             ' False\n\n        Print(vbCrLf + \"IsPhoneNumber\")\n        Print(IsPhoneNumber(\"123-456-7890\"))  ' True\n        Print(IsPhoneNumber(\"1234567890\"))    ' True\n        Print(IsPhoneNumber(\"123456-7890\"))   ' False\n        Print(IsPhoneNumber(\"uno234567890\"))  ' False\n\n        Print(vbCrLf + \"IsURL\")\n        Print(IsURL(\"http://www.ejm.com\"))    ' True\n        Print(IsURL(\"google.com\"))            ' True\n        Print(IsURL(\"ejm.com/a/b/c\"))         ' True\n        Print(IsURL(\"https://.ejm.com\"))      ' False\n        Print(IsURL(\"https://.ejm.com/a b\"))  ' False \n    End Sub\nEnd Module\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/bash/arturonavas.sh",
    "content": "#!/usr/bin/bash\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n * números del 1 al 10 mediante iteración.\n *\n * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n */\n\n # mecanismo 1 || desde i hasta 10\nfor i in {1..10}\ndo\n  echo $i\ndone\n\n\n# mecanismo 2 || un for basico\nfor ((i=1; i<=10; i++))\ndo\n  echo $i\ndone\n\n# mecanismo 3 ||(while)\ni=1\nwhile [ $i -le 10 ]\ndo\n  echo $i\n  ((i++))\ndone\n\n# mecanismo 4 || lo mismo que un while\ni=1\nuntil [ $i -gt 10 ]\ndo\n  echo $i\n  ((i++))\ndone\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/bash/rantamhack.sh",
    "content": "#!/bin/bash\n\n\n# * EJERCICIO:\n# * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n# * numeros del 1 al 10 mediante iteracion.\n\n\necho -e \"\\n\\n=======================================EJERCICIO=======================================\\n\\n\"\n\n# Usando 'for'\n\nfor i in {1..10}; do\n    echo \"El valor de la iteracion en 'bucle for' para 'i' es: $i\"\ndone\n\necho -e \"\\n=====================\\n\"\n    \n# Usando 'while break'    \n    \nn=1    \nwhile true; do\n    if [ $n -gt 10 ]; then\n        break\n    fi\n    echo \"El valor de la iteracion en bucle 'while' para 'n' es: $n\"\n    ((n++))\ndone\n    \necho -e \"\\n=====================\\n\"\n\n# Usando 'until'\n\nn=10\nuntil [ $n -lt 0 ]; do\n    echo \"El valor de la iteracion en bucle 'until' para 'n' es: $n\"\n    ((n--))\n\ndone\n \n\n\necho -e \"\\n\\n=======================================DIFICULTAD EXTRA=======================================\\n\\n\"\n\n\n\n# DIFICULTAD EXTRA (opcional):\n# Escribe el mayor numero de mecanismos que posea tu lenguaje\n# para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n\n\n# while continue\n\nfor i in {1..10}; do\n    if [[ $i -eq 5 || $i -eq 6 ]];then\n        continue\n    fi\n    echo \"Mi posicion en el bucle for es: $i\"\ndone\n\necho -e \"\\n=====================\\n\"\n\n# Iterar Cadena de Texto\n\ntexto=\"rantamplan\"\nfor (( i=0; i<${#texto}; i++ )); do\n    echo \"${texto:$i:1}\"\ndone\n\necho -e \"\\n=====================\\n\"\n\n# Iterar rango de 2 en 2\n\nfor i in {0..20..2}; do\n    echo $i\ndone\n\necho -e \"\\n=====================\\n\"\n\n# Iterar lista\n\nlista=(1 2 3 4 5 6 7 8 9 10)\nfor i in \"${lista[@]}\"; do\n    echo \"Mi posicion en la lista es: $i\"\ndone\n\necho -e \"\\n=====================\\n\"\n    \n# Iterar diccionario por clave\n\ndeclare -A dict\n\ndict[1]='a'\ndict[2]='b'\ndict[3]='c'\ndict[4]='d'\ndict[5]='e'\n\nfor key in \"${!dict[@]}\"; do\n    echo \"Estoy en la posicion de claves del diccionario: $key\"\ndone\n\necho -e \"\\n=====================\\n\"\n\n# Iterar diccionario por valor\n\nfor value in \"${dict[@]}\"; do\n    echo \"Estoy en la posicion de valores del diccionario: $value\"\ndone\n    \necho -e \"\\n=====================\\n\"\n\n# Iterando lista al reves\n\nfor i in $(seq 10 -1 1); do\n    echo \"mi posiciÃ³n descendente es: $i\"\ndone\n\necho -e \"\\n=====================\\n\"\n\n\n# Iterando mediante recursividad\n\nfunction recursive(){\n    if [[ $1 -le 10 ]]; then    \n        echo \"Mi posicion en la funcion recursiva es: $1\"\n        recursive $(( $1 +1 ))\n    fi\n}\n\nrecursive 0\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/c#/SBS24.cs",
    "content": "﻿// Author: Sandra Baigorri\nusing System;\nusing System.Linq;\n\n\nnamespace Iteracciones\n{\n    internal class Program\n    {\n        static void Main(string[] args)\n        {\n            /*\n             * EJERCICIO:\n             * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n             * números del 1 al 10 mediante iteración.\n             *\n             * DIFICULTAD EXTRA (opcional):\n             * Escribe el mayor número de mecanismos que posea tu lenguaje\n             * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n             */\n            int num = 1;\n            Imprimir1();\n            Imprimir2();\n            Imprimir3();\n            Imprimir4();\n            Console.WriteLine(\"----------- IMPRIMIR5 -----------\");\n            Imprimir5(num);\n        }\n        //FOR\n        private static void Imprimir1()\n        {\n            Console.WriteLine(\"----------- IMPRIMIR1 -----------\");\n            for (int i = 1; i <= 10; i++) \n            {\n                Console.WriteLine(\"Número: \" + i);\n            }\n        }\n        //WHILE\n        private static void Imprimir2()\n        {\n            Console.WriteLine(\"----------- IMPRIMIR2 -----------\");\n            int i = 1;\n            while (i <= 10)\n            {\n                Console.WriteLine(\"Número: \" + i);\n                i++;\n            }\n        }\n        //DO WHILE\n        private static void Imprimir3()\n        {\n            Console.WriteLine(\"----------- IMPRIMIR3 -----------\");\n            int i = 1;\n            do\n            {\n                Console.WriteLine(\"Número: \" + i);\n                i++;\n            } \n            while (i <= 10);\n        }\n        //FOREACH\n        private static void Imprimir4()\n        {\n            Console.WriteLine(\"----------- IMPRIMIR4 -----------\");            \n            foreach (int i in Enumerable.Range(1, 10))\n            {\n                Console.WriteLine(\"Número: \" + i);      \n            }\n        }\n        //RECURSIVIDAD\n        private static void Imprimir5(int num)\n        {                        \n            if(num <= 10)\n            {\n                Console.WriteLine(\"Número: \" + num);\n                Imprimir5(num + 1); \n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/c#/hequebo.cs",
    "content": "class Program\n{\n    static void Main(string[] args)\n    {\n        #region Bucles\n        // Bucle While\n        /*\n         * Un bucle While verifica primero que la \n         * condición sea verdadera antes de ejecutar\n         * su bloque de código. Por default no interactua\n         * con su condición de salida por lo que si en este\n         * caso nunca se aumenta el valor de i el bucle se\n         * volverá un bucle infinito.\n         */\n        Console.WriteLine(\"---While---\");\n        int i = 1;\n        while (i <= 10)\n        {\n            Console.Write($\"{i}, \");\n            i++;\n        }\n        Console.WriteLine();\n\n        // Bucle Do While\n        /*\n         * Al contrario del bucle While el bucle \n         * Do While se ejecuta por lo menos una vez\n         * y verifica su condición al final del bloque\n         * de igual manera se tiene que modificar dentro del\n         * bloque de código la variable i\n         */\n        Console.WriteLine(\"---Do While---\");\n        i = 1;\n        do\n        {\n            Console.Write($\"{i}, \");\n            i++;\n        } while (i <= 10);\n        Console.WriteLine();\n        // Bucle For\n        /*\n         * En un bucle For en su definición además de \n         * indicar la condición para ejecutar el código\n         * tambien se modifica la variable i por lo que es\n         * menos probable que se cree un bucle infinito\n         */\n        Console.WriteLine(\"---Bucle For---\");\n        for (i = 1; i <= 10; i++)\n        {\n            Console.Write($\"{i}, \");\n        }\n        Console.ReadLine();\n        #endregion\n        #region Extra\n        Console.WriteLine(\"----Extra----\");\n        List<string> lenguajes = new List<string>\n        {\n            \"C#\",\n            \"Java\",\n            \"Python\",\n            \"PHP\",\n            \"C++\",\n            \"Javascript\",\n            \"Kotlin\"\n        };\n\n        Console.WriteLine(\"---While---\");\n        i = 0;\n        while (i < lenguajes.Count)\n        {\n            Console.Write($\"{lenguajes[i]} | \");\n            i++;\n        }\n        Console.WriteLine();\n\n        Console.WriteLine(\"---Do While---\");\n        i = 0;\n        do\n        {\n            Console.Write($\"{lenguajes[i]} | \");\n            i++;\n        } while (i < lenguajes.Count);\n        Console.WriteLine();\n\n        Console.WriteLine(\"---For---\");\n        for(i = 0; i < lenguajes.Count; i++)\n            Console.Write($\"{lenguajes[i]} | \");\n        Console.WriteLine();\n\n        Console.WriteLine(\"---For Each---\");\n        foreach (string lenguaje in lenguajes)\n            Console.Write($\"{lenguaje} | \");\n        Console.WriteLine();\n\n        Console.WriteLine(\"---Recursión---\");\n        Recursion(lenguajes);\n        #endregion\n    }\n    static void Recursion(List<string> list)\n    {\n        if(list.Count == 0)\n            return;\n        Console.Write($\"{list.First()} | \");\n        list.RemoveAt(0);\n        \n        Recursion(list);\n    }\n}"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/c#/isaacus98.cs",
    "content": "﻿/*\n * EJERCICIO:\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n * números del 1 al 10 mediante iteración.\n *\n * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n */\n\nnamespace Roadmap\n{\n    internal class Reto17\n    {\n        static void Main(string[] args)\n        {\n            for (int i = 1; i <= 10;  i++)\n                Console.WriteLine(i.ToString());\n\n            Console.WriteLine();\n\n            int counter = 1;\n            while (counter <= 10)\n            {\n                Console.WriteLine(counter.ToString());\n                counter++;\n            }\n\n            Console.WriteLine();\n\n            counter = 1;\n            do\n            {\n                Console.WriteLine(counter.ToString());\n                counter++;\n            } while (counter <= 10);\n\n            Console.WriteLine();\n\n            // Reto extra\n            int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };\n            foreach (int number in numbers)\n                Console.WriteLine(number.ToString());\n\n            Console.WriteLine();\n\n            Iterar1al10(1);\n        }\n\n        static void Iterar1al10(int number)\n        {\n            if (number <= 10)\n            {\n                Console.WriteLine(number.ToString());\n                Iterar1al10(++number);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/c#/jamerrq.cs",
    "content": "﻿/*\r\n * EJERCICIO:\r\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\r\n * números del 1 al 10 mediante iteración.\r\n *\r\n * DIFICULTAD EXTRA (opcional):\r\n * Escribe el mayor número de mecanismos que posea tu lenguaje\r\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\r\n */\r\n\r\nusing System;\r\n\r\nnamespace Roadmap17\r\n{\r\n    class Iterations\r\n    {\r\n        // Primera forma: ciclo for\r\n        static void ForLoop()\r\n        {\r\n            for (int i = 1; i <= 10; i++)\r\n            {\r\n                Console.WriteLine(i);\r\n            }\r\n        }\r\n\r\n        // Segunda forma: ciclo while\r\n        static void WhileLoop()\r\n        {\r\n            int i = 1;\r\n            while (i <= 10)\r\n            {\r\n                Console.WriteLine(i);\r\n                i++;\r\n            }\r\n        }\r\n\r\n        // Tercera forma: ciclo do-while\r\n        static void DoWhileLoop()\r\n        {\r\n            int i = 1;\r\n            do\r\n            {\r\n                Console.WriteLine(i);\r\n                i++;\r\n            } while (i <= 10);\r\n        }\r\n\r\n        // Cuarta forma: ciclo foreach\r\n        static void ForEachLoop()\r\n        {\r\n            int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };\r\n            foreach (int number in numbers)\r\n            {\r\n                Console.WriteLine(number);\r\n            }\r\n        }\r\n\r\n        // Quinta forma: ciclo foreach con rangos\r\n        static void ForEachRangeLoop()\r\n        {\r\n            foreach (int number in Enumerable.Range(1, 10))\r\n            {\r\n                Console.WriteLine(number);\r\n            }\r\n        }\r\n\r\n        static void Main(string[] args)\r\n        {\r\n            Console.WriteLine(\"For Loop:\");\r\n            ForLoop();\r\n\r\n            Console.WriteLine(\"\\nWhile Loop:\");\r\n            WhileLoop();\r\n\r\n            Console.WriteLine(\"\\nDo-While Loop:\");\r\n            DoWhileLoop();\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/c#/kenysdev.cs",
    "content": "/*\n╔══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado               ║\n║ GitHub: https://github.com/Kenysdev  ║\n║ 2024 -  C#                           ║\n╚══════════════════════════════════════╝\n------------------------------------------\n* ITERACIONES\n------------------------------------------\n* EJERCICIO #1:\n* Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n* números del 1 al 10 mediante iteración.\n*\n* EJERCICIO #2:\n* Escribe el mayor número de mecanismos que posea tu lenguaje\n* para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n*/\n//_____________________________\nConsole.WriteLine(\"(1). for\");\nfor (int n = 1; n <= 10; n++) {\n    Console.WriteLine(n);\n}\n\n//_____________________________\nConsole.WriteLine(\"\\n(2). while\");\nint num = 1;\nwhile (num <= 10) {\n    Console.WriteLine(num);\n    num++;\n}\n\n//_____________________________\nConsole.WriteLine(\"\\n(3). foreach\");\nforeach (int n in Enumerable.Range(1, 10)) {\n    Console.WriteLine(n);\n}\n\n//_____________________________\nConsole.WriteLine(\"\\n(4). do-while\");\nint nu = 1;\ndo {\n    Console.WriteLine(nu);\n    nu++;\n} while (nu <= 10);\n\n//_____________________________\nConsole.WriteLine(\"\\n(5). Iteradores yield\");\nstatic IEnumerable<int> Nums() {\n    for (int n = 1; n <= 10; n++) {\n        yield return n;\n    }\n}\n\nforeach (var n in Nums()) {\n    Console.WriteLine(n);\n}\n\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/c++/hectorio23.cpp",
    "content": "// Author: Héctor Adán \n// GitHub: https://github.com/hectorio23 \n#include <algorithm>\n#include <iostream>\n#include <cstdlib>\n\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n * números del 1 al 10 mediante iteración.\n *\n * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n*/\n\n// Esta funcion imprimira el numero los 10 al 1\nint recursive(int numero) {\n    std::cout << numero << \", \";\n    if (numero == 1) return 1;\n    return numero * recursive(numero - 1);\n}\n\nint main() {\n    // bucle for\n    std::cout << \"Forma 1 -> bucle for\\n\";\n    for (int i = 1; i <= 10; i++) std::cout << i << \", \";\n    std::cout << \"\\n\";\n\n    // bucle while\n    std::cout << \"Forma 2 -> bucle While\\n\";\n    int n = 1;\n    while (n <= 10) { std::cout << n << \", \"; n++; }\n    std::cout << \"\\n\";\n\n    // bucle do while\n    std::cout << \"Forma 3 -> bucle Do While\\n\";\n    n = 1;\n    do { std::cout << n << \", \"; n++; } while (n <= 10);\n    std::cout << \"\\n\";\n\n    // bucle for auto\n    std::cout << \"Forma 4 -> bucle for auto\\n\";\n    int data[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };\n    for (auto element : data) std::cout << element << \", \";\n    std::cout << \"\\n\";\n\n    // bucle for indefinido\n    std::cout << \"Forma 5 -> bucle for indefinido\\n\";\n    n = 1;\n    for (;;) { std::cout << n << \", \"; n ++; if (n == 11) break; };\n    std::cout << \"\\n\";\n\n    // recursividad\n    std::cout << \"Forma 6 -> recursividad\\n\";\n    recursive(10);\n    std::cout << \"\\n\";\n\n    // bucle con iteradores\n    std::cout << \"Forma 7 -> bucle for con iteradores\\n\";\n    int array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};\n    for (auto it = std::begin(array); it != std::end(array); ++it) {\n        std::cout << *it << \", \";\n    }\n    std::cout << \"\\n\";\n\n    // bucle for_each usando funciones lambda o \"anonimas\" \n    std::cout << \"Forma 8 -> bucle for_each con lambda/for each\\n\";\n    std::for_each(std::begin(array), std::end(array), [](int value) {\n        std::cout << value << \", \";\n    });\n    std::cout << \"\\n\";\n\n    // bucle for con indexacion de puntero \n    std::cout << \"Forma 9 -> bucle con indexación de puntero\\n\";\n    int* ptr = array;\n    for (int i = 0; i < 10; ++i) {\n        std::cout << *(ptr + i) << \", \";\n    }\n    std::cout << \"\\n\";\n\n    return EXIT_SUCCESS;\n}\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/dart/eulogioep.dart",
    "content": "/**\n * Demostración de diferentes mecanismos de iteración en Dart\n * \n * Dart proporciona varios mecanismos de iteración, combinando\n * sintaxis familiar con características únicas del lenguaje.\n */\n\nimport 'dart:io' show stdout;\n\nvoid main() {\n  print('=== Demostración de Mecanismos de Iteración en Dart ===\\n');\n\n  // 1. Bucle for tradicional\n  print('1. Usando bucle for tradicional:');\n  void forLoop() {\n    for (int i = 1; i <= 10; i++) {\n      stdout.write('$i ');\n    }\n    print(''); // Nueva línea\n  }\n  forLoop();\n\n  // 2. Bucle while\n  print('\\n2. Usando bucle while:');\n  void whileLoop() {\n    int contador = 1;\n    while (contador <= 10) {\n      stdout.write('$contador ');\n      contador++;\n    }\n    print('');\n  }\n  whileLoop();\n\n  // 3. Bucle do-while\n  print('\\n3. Usando bucle do-while:');\n  void doWhileLoop() {\n    int num = 1;\n    do {\n      stdout.write('$num ');\n      num++;\n    } while (num <= 10);\n    print('');\n  }\n  doWhileLoop();\n\n  // 4. forEach con List\n  print('\\n4. Usando forEach con List:');\n  void forEachLoop() {\n    List<int> numeros = List.generate(10, (index) => index + 1);\n    numeros.forEach((numero) => stdout.write('$numero '));\n    print('');\n  }\n  forEachLoop();\n\n  // 5. for-in loop\n  print('\\n5. Usando for-in loop:');\n  void forInLoop() {\n    var numeros = List.generate(10, (index) => index + 1);\n    for (var numero in numeros) {\n      stdout.write('$numero ');\n    }\n    print('');\n  }\n  forInLoop();\n\n  // 6. Usando Iterable.generate\n  print('\\n6. Usando Iterable.generate:');\n  void iterableGenerate() {\n    var numeros = Iterable.generate(10, (index) => index + 1);\n    numeros.forEach((numero) => stdout.write('$numero '));\n    print('');\n  }\n  iterableGenerate();\n\n  // 7. Usando map\n  print('\\n7. Usando map:');\n  void mapExample() {\n    var numeros = List.generate(10, (index) => index + 1);\n    numeros.map((numero) => stdout.write('$numero ')).toList();\n    print('');\n  }\n  mapExample();\n\n  // 8. Usando Iterador personalizado\n  print('\\n8. Usando Iterador personalizado:');\n  class NumberIterator implements Iterator<int> {\n    int _current = 0;\n    \n    @override\n    int get current => _current;\n    \n    @override\n    bool moveNext() {\n      if (_current < 10) {\n        _current++;\n        return true;\n      }\n      return false;\n    }\n  }\n\n  class NumberIterable extends Iterable<int> {\n    @override\n    Iterator<int> get iterator => NumberIterator();\n  }\n\n  void customIterator() {\n    var numbers = NumberIterable();\n    for (var number in numbers) {\n      stdout.write('$number ');\n    }\n    print('');\n  }\n  customIterator();\n\n  // 9. Usando async* para generar un stream\n  print('\\n9. Usando async* para generar un stream:');\n  Stream<int> countStream() async* {\n    for (int i = 1; i <= 10; i++) {\n      yield i;\n    }\n  }\n\n  void streamExample() async {\n    await for (var number in countStream()) {\n      stdout.write('$number ');\n    }\n    print('');\n  }\n  // Nota: Este ejemplo es asíncrono y no se ejecutará en orden\n  streamExample();\n\n  // 10. Usando recursión\n  print('\\n10. Usando recursión:');\n  void recursion(int n) {\n    if (n <= 10) {\n      stdout.write('$n ');\n      recursion(n + 1);\n    }\n  }\n  recursion(1);\n  print('');\n\n  // EXTRA: Ejemplo con Dart Collection Methods\n  print('\\n11. Bonus: Usando métodos de colección de Dart:');\n  void dartCollectionMethods() {\n    var numeros = List.generate(10, (index) => index + 1);\n    \n    // where para filtrar\n    print('Números pares:');\n    numeros.where((n) => n.isEven).forEach((n) => stdout.write('$n '));\n    print('');\n    \n    // take para obtener los primeros n elementos\n    print('Primeros 5 números:');\n    numeros.take(5).forEach((n) => stdout.write('$n '));\n    print('');\n    \n    // skip para saltar elementos\n    print('Saltando los primeros 5 números:');\n    numeros.skip(5).forEach((n) => stdout.write('$n '));\n    print('');\n  }\n  dartCollectionMethods();\n}\n\n/**\n * NOTAS SOBRE LAS CARACTERÍSTICAS ÚNICAS DE DART:\n * \n * 1. Dart tiene soporte nativo para streams con async* y yield\n * 2. Los tipos son obligatorios para las variables públicas\n * 3. Las colecciones en Dart son muy potentes y tienen muchos métodos útiles\n * 4. Dart tiene un sistema de tipos sound null safety\n * 5. La sintaxis para iteración es similar a otros lenguajes, pero con\n *    algunas peculiaridades propias de Dart\n */\n\n/**\n * MEJORES PRÁCTICAS PARA ITERACIÓN EN DART:\n * \n * 1. Usar for-in cuando sea posible, es más legible\n * 2. Aprovechar los métodos de colección como where, map, etc.\n * 3. Considerar el uso de streams para datos asíncronos\n * 4. Implementar Iterable cuando se necesite una colección personalizada\n * 5. Usar final o const cuando sea posible para variables\n */"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/dart/teren91.dart",
    "content": "\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n * números del 1 al 10 mediante iteración.\n *\n * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n */\n\nvoid main()\n{\n  //Iteraciones básicas\n  for(int i = 1; i <= 10; i++ )\n  {\n    print('Bucle for $i');\n  }\n\n  int cont = 1;\n\n  while(cont <= 10)\n  {\n    print('Bucle While $cont');\n    cont++;\n  }\n\n  cont = 1;\n\n  do \n  {\n    print('Bucle Do - While $cont');\n    cont ++;\n  }while(cont <= 10);\n\n  //Otras Iteracciones \n\n  final List<int> numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n\n  numbers.forEach((element) {\n    print('Bucle forEach de Listas: $element');\n  });\n\n  \n}"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/ejercicio.md",
    "content": "# #17 ITERACIONES\n> #### Dificultad: Fácil | Publicación: 22/04/24 | Corrección: 29/04/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n * números del 1 al 10 mediante iteración.\n *\n * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/17 - ITERACIONES/go/DaFi02.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc count(n int, limit int) {\n\tif n <= limit {\n\t\tfmt.Println(n)\n\t\tcount(n+1, limit)\n\t}\n}\n\nfunc main() {\n\n\tlimit := 10\n\ti := 1\n\n\t// First Method\n\tfmt.Println(\"First Method...\")\n\tfor ; i <= limit; i++ {\n\t\tfmt.Println(i)\n\t}\n\n\ti = 1\n\n\tfmt.Println(\"----------------------------------------------------------------------------------\")\n\t// Second Method\n\tfmt.Println(\"\\nSecond Method...\")\n\tfmt.Println(\"Recursive Function...\")\n\n\tcount(i, limit)\n\n\tfmt.Println(\"----------------------------------------------------------------------------------\")\n\t// Third Mehtod\n\tfmt.Println(\"\\nThird Method\")\n\tfmt.Println(\"Anonymous Recursive Function\")\n\n\tvar countAnon func(n int, limit int)\n\tcountAnon = func(n int, limit int) {\n\t\tif n <= limit {\n\t\t\tfmt.Println(n)\n\t\t\tcountAnon(n+1, limit)\n\t\t}\n\t}\n\tcountAnon(i, limit)\n\n}\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/go/MiguelP-Dev.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc main() {\n\t// 1. Bucle for básico\n\tfor i := 1; i < 10; i++ {\n\t\tfmt.Println(i)\n\t}\n\n\t// 2. Bucle for con condición\n\ti := 1\n\tfor i < 10 {\n\t\tfmt.Println(i)\n\t\ti++\n\t}\n\n\t// 3. Bucle infinito con break\n\ti = 1\n\tfor {\n\t\tif i > 10 {\n\t\t\tbreak\n\t\t}\n\t\tfmt.Println(i)\n\t\ti++\n\t}\n\n\t// 4. Iteración sobre un Array\n\tnumsArray := [10]int{1, 2, 3, 5, 6, 7, 8, 9, 10}\n\tfor i, num := range numsArray {\n\t\tfmt.Printf(\"Índice: %v, Valor: %d\\n\", i, num)\n\t}\n\n\t// Iteración sobre un Slice\n\tnumSlice := [10]int{1, 2, 3, 5, 6, 7, 8, 9, 10}\n\tfor _, number := range numSlice {\n\t\tfmt.Println(number)\n\t}\n\n\t// 6. Iteración sobre un Map\n\tnumsMap := map[string]int{\"uno\": 1, \"dos\": 2, \"tres\": 3, \"cuatro\": 4, \"cinco\": 5, \"seis\": 6, \"siete\": 7, \"ocho\": 8, \"nueve\": 9, \"diez\": 10}\n\tfor key := range numsMap {\n\t\tfmt.Println(key, numsMap[key])\n\t}\n\n\t//  Iteración sobre una cadena de texto\n\ttext := \"Hola Mundo\"\n\tfor i, char := range text {\n\t\tfmt.Printf(\"Índice: %v, Caracter: %c\\n\", i, char)\n\t}\n\n\t// 8. Iteración sobre un canal\n\tnumsChan := make(chan int)\n\tgo func() {\n\t\tfor i := 1; i <= 10; i++ {\n\t\t\tnumsChan <- i\n\t\t}\n\t\tclose(numsChan)\n\t}()\n\tfor num := range numsChan {\n\t\tfmt.Println(num)\n\t}\n\n\t// 9. Iteración sobre un canal con select\n\tnumsChan1 := make(chan int)\n\tnumsChan2 := make(chan int)\n\tgo func() {\n\t\tfor i := 1; i <= 10; i++ {\n\t\t\tnumsChan1 <- i\n\t\t\tnumsChan2 <- i\n\t\t}\n\t\tclose(numsChan1)\n\t\tclose(numsChan2)\n\t}()\n\tfor {\n\t\tselect {\n\t\tcase num, ok := <-numsChan1:\n\t\t\tif !ok {\n\t\t\t\tnumsChan1 = nil\n\t\t\t} else {\n\t\t\t\tfmt.Println(\"Canal 1:\", num)\n\t\t\t}\n\t\tcase num, ok := <-numsChan2:\n\t\t\tif !ok {\n\t\t\t\tnumsChan2 = nil\n\t\t\t} else {\n\t\t\t\tfmt.Println(\"Canal 2:\", num)\n\t\t\t}\n\t\t}\n\t\tif numsChan1 == nil && numsChan2 == nil {\n\t\t\tbreak\n\t\t}\n\t}\n\n\t// 9. Iteración con una función recursiva\n\tvar recursivePrint func(int)\n\trecursivePrint = func(n int) {\n\t\tif n > 10 {\n\t\t\treturn\n\t\t}\n\t\tfmt.Println(n)\n\t\trecursivePrint(n + 1)\n\t}\n\trecursivePrint(1)\n\n\t// 10. Iteración con un defer\n\tfor i := 1; i <= 10; i++ {\n\t\tdefer fmt.Println(i)\n\t}\n\tfmt.Println(\"Fin del programa\")\n\n\t// 11. Iteración con un defer y una función anónima\n\tfor i := 1; i <= 10; i++ {\n\t\tdefer func() {\n\t\t\tfmt.Println(i)\n\t\t}()\n\t}\n\tfmt.Println(\"Fin del programa\")\n\n\t// 12. Iteracion con goto (No Recomendado)\n\ti = 1\nLoop:\n\tif i <= 10 {\n\t\tfmt.Println(i)\n\t\ti++\n\t\tgoto Loop\n\t}\n\n\t/*\n\t\tEl uso de goto para crear bucles no es recomendado en la mayoría de los lenguajes de programación, incluyendo Go, por varias razones:\n\n\t\tLegibilidad: El uso de goto puede hacer que el flujo del programa sea difícil de seguir y entender. Los bucles for y while son estructuras de control más claras y fáciles de leer.\n\n\t\tMantenimiento: El código que utiliza goto puede ser más difícil de mantener y depurar. Los saltos incondicionales pueden llevar a errores difíciles de rastrear y corregir.\n\n\t\tEstructura: Los lenguajes modernos promueven el uso de estructuras de control más estructuradas y legibles, como los bucles for, while, y las funciones recursivas. Estas estructuras ayudan a mantener el código organizado y comprensible.\n\n\t\tErrores: El uso de goto puede llevar a errores como bucles infinitos o saltos a etiquetas incorrectas, lo que puede causar comportamientos inesperados en el programa.\n\n\t\tEn resumen, aunque goto puede ser útil en casos muy específicos, generalmente es mejor evitar su uso y optar por estructuras de control más claras y seguras.\n\t*/\n}\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/go/hozlucas28.go",
    "content": "package main\n\nimport \"fmt\"\n\nconst FROM int = 1\nconst TO int = 10\n\nfunc recursiveFn(from int, to int) {\n\tfmt.Printf(\"\\n%d\", from)\n\n\tif from < to {\n\t\trecursiveFn(from+1, to)\n\t}\n}\n\nfunc main() {\n\t/*\n\t\tIterations...\n\t*/\n\n\tfmt.Println(\"Additional challenge...\")\n\n\tfmt.Println(\"\\nFirst method...\")\n\trecursiveFn(FROM, TO)\n\n\tfmt.Println(\"\\n\\nSecond method...\")\n\tfor i := FROM; i < TO+1; i++ {\n\t\tfmt.Printf(\"\\n%d\", i)\n\t}\n\n\tfmt.Println(\"\\n\\nThird method...\")\n\tvar j int = FROM\n\tfor j < TO+1 {\n\t\tfmt.Printf(\"\\n%d\", j)\n\t\tj++\n\t}\n\n\tfmt.Println(\"\\n\\n# ---------------------------------------------------------------------------------- #\")\n\n\t/*\n\t\tAdditional challenge...\n\t*/\n\n\tfmt.Println(\"\\nAdditional challenge...\")\n\n\tfmt.Println(\"\\nFirst method...\")\n\trecursiveFn(FROM, TO)\n\n\tfmt.Println(\"\\n\\nSecond method...\")\n\tfor i := FROM; i < TO+1; i++ {\n\t\tfmt.Printf(\"\\n%d\", i)\n\t}\n\n\tfmt.Println(\"\\n\\nThird method...\")\n\tj = FROM\n\tfor j < TO+1 {\n\t\tfmt.Printf(\"\\n%d\", j)\n\t\tj++\n\t}\n\n\tfmt.Println(\"\\n\\nFourth method...\")\n\tfor i := range [TO]int{} {\n\t\tfmt.Printf(\"\\n%d\", i+1)\n\t}\n}\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/go/kodenook.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc main() {\n\t// This Go code snippet is using a `for` loop to iterate over the numbers from 1 to 10.\n\tfor i := 1; i < 11; i++ {\n\t\tfmt.Printf(\"%d\\n\", i)\n\t}\n\n\t// This code snippet in Go is creating an array named `loop` with a length of 10, where each element\n\t// is of type `uint` (unsigned integer).\n\tloop := [10]uint{}\n\tfor i, _ := range loop {\n\t\tfmt.Printf(\"%d\\n\", i+1)\n\t}\n\n\t// The code snippet you provided is using a `for` loop with a condition to iterate over the numbers\n\t// from 1 to 10. Here's a breakdown of what it does:\n\tindex := 1\n\tfor index < 11 {\n\t\tfmt.Printf(\"%d\\n\", index)\n\t\tindex++\n\t}\n\n\t// The code snippet `index = 1\n\t// for ; index < 11; index++ {\n\t//     fmt.Printf(\"%d\\n\", index)\n\t// }` is using a `for` loop in Go to iterate over the numbers from 1 to 10. Here's a breakdown of what\n\t// it does:\n\tindex = 1\n\tfor ; index < 11; index++ {\n\t\tfmt.Printf(\"%d\\n\", index)\n\t}\n}\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/go/qwik-zgheib.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc ClassicForLoop() {\n\tfor i := 1; i <= 10; i++ {\n\t\tfmt.Println(i)\n\t}\n}\n\nfunc ConditionalForLoop() {\n\ti := 1\n\tfor i <= +10 {\n\t\tfmt.Println(i)\n\t\ti++\n\t}\n}\n\nfunc RangeForLoop() {\n\ts := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}\n\tfor _, v := range s {\n\t\tfmt.Println(v)\n\t}\n}\n\nfunc RecursiveForLoop(n int) {\n\tif n > 10 {\n\t\treturn\n\t}\n\tfmt.Println(n)\n\tRecursiveForLoop(n + 1)\n}\n\nfunc AnonymousForLoop() {\n\t(func(i int) {\n\t\tfor i := 1; i <= 10; i++ {\n\t\t\tfmt.Println(i)\n\t\t}\n\t})(1)\n}\n\nfunc main() {\n\tfmt.Println(\"classic for loop\")\n\tClassicForLoop()\n\n\tfmt.Println(\"conditional for loop\")\n\tConditionalForLoop()\n\t\n\tfmt.Println(\"range for loop\")\n\tRangeForLoop()\n\t\n\tfmt.Println(\"recursive for loop\")\n\tRecursiveForLoop(1)\n\t\n\tfmt.Println(\"anonymous for loop\")\n\tAnonymousForLoop()\n}\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/go/raynerpv2022.go",
    "content": "package main\n\nimport \"fmt\"\n\n/*\n#  * EJERCICIO:\n#  * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n#  * números del 1 al 10 mediante iteración.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Escribe el mayor número de mecanismos que posea tu lenguaje\n#  * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n#  */\n\nfunc main() {\n\n\tfor i := 1; i < 11; i++ {\n\t\tfmt.Println(i)\n\t}\n\n\t// for like while\n\ti := 1\n\tfor i < 11 {\n\t\tfmt.Println(i)\n\t\ti++\n\n\t}\n\n\t// EXTRA\n\t// / Slice of cryptocurrency names\n\tcryptocurrencies := []string{\"Bitcoin\", \"Ethereum\", \"Tether\", \"Binance Coin\", \"Solana\", \"USD Coin\", \"XRP\", \"Dogecoin\", \"TRON\", \"Toncoin\"}\n\n\t// Slice of corresponding values\n\tprices := []float64{57732.00, 2341.66, 1.00, 543.83, 134.33, 1.00, 0.57, 0.10, 0.09, 5.40}\n\n\tfor k, i := range cryptocurrencies {\n\t\tfmt.Printf(\" Index %v : Crypto: %v\\n\", k+1, i)\n\t}\n\n\t// crear mapacon los dos slice\n\tcryptoMap := map[string]float64{}\n\n\tfor k, i := range cryptocurrencies {\n\t\tcryptoMap[i] = prices[k]\n\t}\n\n\tfor k, v := range cryptoMap {\n\t\tfmt.Printf(\" Crypto %v : Value: %v\\n\", k, v)\n\t}\n}\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/go/thegera4.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc main() {\n\t// Mecanismo 1\n\tfor i := 1; i <= 10; i++ {\n\t\tfmt.Println(i)\n\t}\n\n\t// Mecanismo 2\n\ti := 1\n\tfor i <= 10 {\n\t\tfmt.Println(i)\n\t\ti++\n\t}\n\n\t// Mecanismo 3\n\tfor _, i := range []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} {\n\t\tfmt.Println(i)\n\t}\n\n\t//Extra\n\t// Mecanismo 4\n\ti = 1\n\tfor {\n\t\tfmt.Println(i)\n\t\ti++\n\t\tif i > 10 {\n\t\t\tbreak\n\t\t}\n\t}\n\n\t// Mecanismo 5\n\ti = 1\n\tfor {\n\t\tif i > 10 {\n\t\t\tbreak\n\t\t}\n\t\tfmt.Println(i)\n\t\ti++\n\t}\n\n}"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/java/AmadorQuispe.java",
    "content": "\nimport java.util.ArrayList;\nimport java.util.BitSet;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.stream.IntStream;\nimport java.util.stream.Stream;\n\n/* ╔══════════════════════════════════════╗\n   ║ Autor:  Amador Q                     ║\n   ║ Web  : https://amsoft.dev            ║\n   ║ 2024                                 ║\n   ╚══════════════════════════════════════╝\n*/\npublic class Main {\n\n    public static void main(String[] args) {\n        iteration1();\n        iteration2();\n        iteration3();\n        iteration4();\n        iteration5();\n        iteration6();\n        System.out.println(\"Iteración utilizando recursividad\");\n        iterator7(1);\n        iteration8();\n    }\n\n    public static void iteration1() {\n        System.out.println(\"Iteración usando un bucle for\");\n        for (int i = 1; i <= 10; i++) {\n            System.out.println(i);\n        }\n    }\n\n    public static void iteration2() {\n        int num = 1;\n        System.out.println(\"Iteración usando un bucle while\");\n        while (num <= 10) {\n            System.out.println(num);\n            num++;\n        }\n    }\n\n    public static void iteration3() {\n        System.out.println(\"Iteración usando do while\");\n        int i = 1;\n        do {\n            System.out.println(i);\n            i++;\n        } while (i <= 10);\n    }\n\n    public static void iteration4() {\n        System.out.println(\"Iteración utilizando un iterator\");\n        List<Integer> list = new ArrayList<>();\n        for (int i = 1; i <= 10; i++) {\n            list.add(i);\n        }\n        Iterator<Integer> iterator = list.iterator();\n        while (iterator.hasNext()) {\n            System.out.println(iterator.next());\n        }\n    }\n\n    public static void iteration5() {\n        System.out.println(\"Iteración utilizando IntStream\");\n        IntStream numbers = IntStream.rangeClosed(1, 10);\n        numbers.forEach(System.out::println);\n\n    }\n\n    public static void iteration6() {\n        System.out.println(\"Iteración usando Api Stream (java 8)\");\n        Stream.iterate(1, n -> n + 1).limit(10)\n                .forEach(System.out::println);\n    }\n\n    private static void iterator7(int i) {\n        if (i <= 10) {\n            System.out.println(i++);\n            iterator7(i);\n        }\n    }\n\n    public static void iteration8() {\n        System.out.println(\"Iteración utilizando la clase BitSet\");\n        BitSet bitSet = new BitSet(10);\n        bitSet.set(0, 10);\n        for (int i = bitSet.nextSetBit(0); i >= 0; i = bitSet.nextSetBit(i + 1)) {\n            System.out.println(i + 1);\n        }\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/java/AnaLauDB.java",
    "content": "public class AnaLauDB {\n    public static void main(String[] args) {\n        // Ejemplo de uso de bucles\n        for (int i = 0; i <= 10; i++) {\n            System.out.println(\"Número (for): \" + i);\n        }\n\n        // Ejemplo de uso de un bucle while\n        int j = 0;\n        while (j <= 10) {\n            System.out.println(\"Número (while): \" + j);\n            j++;\n        }\n\n        // Ejemplo de uso de un bucle do-while\n        int k = 0;\n        do {\n            System.out.println(\"Número (do-while): \" + k);\n            k++;\n        } while (k <= 10);\n        System.out.println(\"          \");\n\n        // DIFICULTAD EXTRA\n        System.out.println(\"DIFICULTAD EXTRA\");\n        // 4. For-each sobre un array\n        int[] numeros = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };\n        for (int n : numeros) {\n            System.out.println(\"for-each: \" + n);\n            System.out.println(\"          \");\n        }\n\n        // 5. Iterando con Streams (Java 8+)\n        java.util.stream.IntStream.rangeClosed(1, 10)\n                .forEach(x -> System.out.println(\"stream: \" + x));\n        System.out.println(\"          \");\n\n        // 6. Iterando con recursividad\n        imprimirRecursivo(1, 10);\n        System.out.println(\"          \");\n\n        // 7. Iterando con java.util.Iterator\n        java.util.List<Integer> lista = java.util.Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);\n        java.util.Iterator<Integer> it = lista.iterator();\n        while (it.hasNext()) {\n            System.out.println(\"iterator: \" + it.next());\n        }\n        System.out.println(\"          \");\n    }\n\n    // Método recursivo para imprimir del a al b\n    public static void imprimirRecursivo(int a, int b) {\n        if (a > b)\n            return;\n        System.out.println(\"recursivo: \" + a);\n        imprimirRecursivo(a + 1, b);\n    }\n}\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/java/FranDev200.java",
    "content": "import java.util.ArrayList;\nimport java.util.Iterator;\nimport java.util.ListIterator;\nimport java.util.Spliterator;\nimport java.util.stream.Stream;\n\npublic class FranDev200 {\n\n\n    static void main() {\n\n        /*\n\n        EJERCICIO:\n         * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n         * números del 1 al 10 mediante iteración.\n\n         */\n\n        // Mecanismo 1\n        for(int i = 1; i <= 10; i++){\n            System.out.print(i + \", \");\n        }\n\n        System.out.println();\n\n        // Mecanismo 2\n        int contador = 1;\n        while(contador <= 10){\n\n            System.out.print(contador + \", \");\n            contador++;\n\n        }\n\n        System.out.println();\n\n        // Mecanismo 3\n\n        contador = 1;\n        do{\n\n            System.out.print(contador + \", \");\n            contador++;\n\n        }while(contador <= 10);\n\n        /*\n\n        DIFICULTAD EXTRA (opcional):\n         * Escribe el mayor número de mecanismos que posea tu lenguaje\n         * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n\n\n         */\n\n        System.out.println(\"\\nEJERCICIO EXTRA\");\n        System.out.println(\"===============\");\n\n        System.out.println(\"- - - - - - \");\n        System.out.println(\"Iteracion 1\");\n        System.out.println(\"- - - - - - \");\n        iteracion1();\n\n        System.out.println(\"\\n- - - - - - \");\n        System.out.println(\"Iteracion 2\");\n        System.out.println(\"- - - - - - \");\n        iteracion2();\n\n        System.out.println(\"\\n- - - - - - \");\n        System.out.println(\"Iteracion 3\");\n        System.out.println(\"- - - - - - \");\n        iteracion3();\n\n        System.out.println(\"\\n- - - - - - \");\n        System.out.println(\"Iteracion 4\");\n        System.out.println(\"- - - - - - \");\n        iteracion4(1);\n\n        System.out.println(\"\\n- - - - - - \");\n        System.out.println(\"Iteracion 5\");\n        System.out.println(\"- - - - - - \");\n        iteracion5();\n\n        System.out.println(\"\\n- - - - - - \");\n        System.out.println(\"Iteracion 6\");\n        System.out.println(\"- - - - - - \");\n        iteracion6();\n\n        System.out.println(\"\\n- - - - - - \");\n        System.out.println(\"Iteracion 7\");\n        System.out.println(\"- - - - - - \");\n        iteracion7();\n\n        System.out.println(\"\\n- - - - - - \");\n        System.out.println(\"Iteracion 8\");\n        System.out.println(\"- - - - - - \");\n        iteracion8();\n\n        System.out.println(\"\\n- - - - - - \");\n        System.out.println(\"Iteracion 9\");\n        System.out.println(\"- - - - - - \");\n        iteracion9();\n\n        System.out.println(\"\\n- - - - - - \");\n        System.out.println(\"Iteracion 10\");\n        System.out.println(\"- - - - - - \");\n        iteracion10();\n\n    }\n\n    // Bucle for\n    static public void iteracion1(){\n\n        for(int i = 1; i <= 10; i++){\n            System.out.print(i + \", \");\n        }\n\n    }\n\n    // Bucle while\n    static public void iteracion2(){\n\n        int contador = 1;\n        while(contador <= 10){\n\n            System.out.print(contador + \", \");\n            contador++;\n\n        }\n\n    }\n\n    // Bucle do-while\n    static public void iteracion3(){\n\n        int contador = 1;\n        do{\n\n            System.out.print(contador + \", \");\n            contador++;\n\n        }while(contador <= 10);\n\n    }\n\n    // Recursividad\n    static public void iteracion4(int contador){\n\n        System.out.print(contador + \", \");\n        contador ++;\n\n        if(contador <= 10){\n\n            iteracion4(contador);\n\n        }\n\n    }\n\n    // Iterador\n    static public void iteracion5(){\n\n        ArrayList<Integer> lista = new ArrayList<>();\n        for(int i = 1; i <= 10; i++){\n            lista.add(i);\n        }\n\n        Iterator<Integer> iterator = lista.iterator();\n        while(iterator.hasNext()){\n            System.out.print(iterator.next() + \", \");\n        }\n\n    }\n\n    // Stream, forEach (lambda)\n    static public void iteracion6(){\n\n        ArrayList<Integer> lista = new ArrayList<>();\n        for(int i = 1; i <= 10; i++){\n            lista.add(i);\n        }\n\n        Stream<Integer> stream = lista.stream();\n\n        stream.forEach(n -> System.out.print(n + \", \"));\n\n    }\n\n    // Iterador y Stream\n    static public void iteracion7(){\n\n        ArrayList<Integer> lista = new ArrayList<>();\n        for(int i = 1; i <= 10; i++){\n            lista.add(i);\n        }\n\n        Stream<Integer> stream = lista.stream();\n        Iterator<Integer> iterator = stream.iterator();\n        while(iterator.hasNext()){\n            System.out.print(iterator.next() + \", \");\n        }\n\n    }\n\n    // Iterador con lambda\n    static public void iteracion8(){\n\n        ArrayList<Integer> lista = new ArrayList<>();\n        for(int i = 1; i <= 10; i++){\n            lista.add(i);\n        }\n\n        Iterator<Integer> iterator = lista.iterator();\n\n        iterator.forEachRemaining(s-> System.out.print(s+\", \"));\n\n    }\n\n    // Spliterator\n    static public void iteracion9(){\n\n        ArrayList<Integer> lista = new ArrayList<>();\n\n        for(int i = 1; i <= 10; i++){\n            lista.add(i);\n        }\n\n        Spliterator<Integer> spliterator = lista.spliterator();\n\n        spliterator.forEachRemaining(s-> System.out.print(s+\", \"));\n\n    }\n\n    // ListIterator\n    static public void iteracion10(){\n\n        ArrayList<Integer> lista = new ArrayList<>();\n        for(int i = 1; i <= 10; i++){\n            lista.add(i);\n        }\n\n        ListIterator<Integer> listIterator =  lista.listIterator();\n\n        listIterator.forEachRemaining(n -> System.out.print(n + \", \"));\n\n\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/java/JesusWay69.java",
    "content": "package roadmap.ejercicio_17;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Set;\nimport java.util.TreeSet;\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n * números del 1 al 10 mediante iteración.\n *\n * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n */\npublic class JesusWay69 {\n    public static void main(String[] args) {\n        iterator1();\n        iterator2();\n        iterator3();\n        iterator4();\n        iterator5();\n        iterator6();\n        iterator7();\n        iterator8();\n        iterator9(0);\n        iterator10();\n        iterator11();\n        iterator12();\n        iterator13();\n        iterator14();\n        iterator15();\n    }\n\n    /*FUNCIÓN FOR CON CONDICIÓN DE INICIO,PARADA Y PASO*/\n    private static void iterator1() {\n        for (int i = 1; i <= 10; i++) {\n            System.out.print(i + \" \");\n        }\n        System.out.print(\" --> Método 1\");\n        System.out.println(\"\");\n    }\n\n    /*FUNCIÓN WHILE CON CONDICIÓN DE PARADA Y PASO*/\n    private static void iterator2() {\n        int i = 1;\n        while (i <= 10) {\n            System.out.print(i + \" \");\n            i++;\n        }\n        System.out.print(\" --> Método 2\");\n        System.out.println(\"\");\n    }\n\n    /*FUNCIÓN DO-WHILE CON CONDICIÓN DE PASO Y PARADA*/\n    private static void iterator3() {\n        int i = 1;\n        do {\n            System.out.print(i + \" \");\n            i++;\n        } while (i <= 10);\n        System.out.print(\" --> Método 3\");\n        System.out.println(\"\");\n    }\n\n    /*FUNCIÓN FOR CON DOS ÍNDICES DE CONTROL (PARES-IMPARES) MEDIANTE PASO DE 2 EN 2*/\n    private static void iterator4() {\n        for (int i = 1, j = 2; i < 10 && j <= 10; i += 2, j += 2) {\n            System.out.print(i + \" \" + j + \" \");\n        }\n        System.out.print(\" --> Método 4\");\n        System.out.println(\"\");\n    }\n\n    /*FUNCIÓN FOR CON DOS ÍNDICES DE CONTROL (PARES-IMPARES) MEDIANTE CONDICIÓN DE SU MÓDULO*/\n    private static void iterator5() {\n        for (int i = 1, j = 2; i < 10 && j <= 10; i++, j++) {\n            if (i % 2 != 0 || j % 2 == 0) {\n                System.out.print(i + \" \" + j + \" \");\n            }\n        }\n        System.out.print(\" --> Método 5\");\n        System.out.println(\"\");\n    }\n\n    /*FUNCIÓN CON 2 FOR CONCATENADOS , EL SEGUNDO RECIBE EL ÍNDICE DONDE TERMINA EL ANTERIOR Y COMPLETA LA ITERACIÓN*/\n    private static void iterator6() {\n        int i;\n        for (i = 1; i <= 5; i++) {\n            if (i <= 5) {\n                System.out.print(i + \" \");\n            }\n        }\n        for (int j = i; j <= 10; j++) {\n            System.out.print(j + \" \");\n        }\n        System.out.print(\" --> Método 6\");\n        System.out.println(\"\");\n    }\n\n    /*FUNCIÓN FOR CON CONDICIÓN DE INICIO Y PASO FUERA DE SU CONSTRUCCIÓN Y CON CONDICIÓN DE PARADA BOOLEANA */\n    private static void iterator7() {\n        int i = 1;\n        for (; true;) {\n            if (i <= 10) {\n                System.out.print(i + \" \");\n                i++;\n            } else {\n                System.out.print(\" --> Método 7\");\n                System.out.println(\"\");\n                break;\n            }\n\n        }\n    }\n\n    /*FUNCIÓN CON FOR ANIDADOS CON CONDICIÓN DE INICIO,PARADA Y PASO, EL PRIMERO IMPRIME LOS IMPARES Y EL SEGUNDO LOS PARES */\n    private static void iterator8() {\n        int i;\n        for (i = 1; i <= 10; i += 2) {\n            System.out.print(i + \" \");\n            for (int j = 0; j < 1; j++) {\n                if (i < 10) {\n                    System.out.print(i + 1 + \" \");\n                }\n            }\n        }\n        System.out.print(\" --> Método 8\");\n        System.out.println(\"\");\n    }\n\n    /*FUNCIÓN CON CONDICIÓN DE PARADA, INCREMENTO Y RECURSIVIDAD QUE RECIBE UN 0 COMO PARÁMETRO Y HACE EL INCREMETO\n    PREVIO EN LA PROPIA FUNCIÓN PRINT*/\n    private static void iterator9(int i) {\n        if (i < 10) {\n            System.out.print(++i + \" \");\n            iterator9(i);\n        } else {\n            System.out.print(\" --> Método 9\");\n            System.out.println(\"\");\n        }\n    }\n\n    /*FUNCIÓN QUE CONSTRUYE UN STRINGBUILDER , SE LLENA CON LA SECUENCIA NUMÉRICA Y LUEGO SE RECORRE EXTRAYÉNDOLOS COMO CHAR,\n    COMO CADA CHAR ES INPENDIENTE \"TRUCAMOS\" LA IMPRESIÓN PARA QUE IMPRIMA UN 10 Y NO UN 1 Y UN 0 AL FINAL*/\n    private static void iterator10() {\n        StringBuilder nums = new StringBuilder();\n        for (int i = 1; i <= 10; i++) {\n            nums.append(i);\n        }\n        for (int j = 0; j <= nums.length() - 1; j++) {\n            if (nums.charAt(j) == '0') {\n                System.out.print(\"\\b0 \");\n            } else {\n                System.out.print(nums.charAt(j) + \" \");\n            }\n        }\n        System.out.print(\" --> Método 10\");\n        System.out.println(\"\");\n    }\n\n    /*FUNCIÓN CON GENERACIÓN DE NÚMEROS ALEATORIOS QUE SE AÑADEN A UN TREESET HASTA QUE ESTE CUMPLA LA CONDICIÓN DE LONGITUD 10\n    MEDIANTE UN CICLO DO-WHILE Y SE EXTRAEN CON UN CICLO FOR-EACH*/\n    private static void iterator11() {\n        Set<Integer> mySet = new TreeSet<>();\n        do {\n            int num = (int) (Math.random() * 10 + 1);\n            mySet.add(num);\n        } while (mySet.size() <= 9);\n\n        for (Integer value : mySet) {\n            System.out.print(value + \" \");\n        }\n        System.out.print(\" --> Método 11\");\n        System.out.println(\"\");\n    }\n\n    /*FUNCIÓN DONDE DECLARAMOS UN ARRAY CON LOS CARACTERES CORRESPONDIENTES A LOS CÓDIGO ASCII DEL 51 AL 60,\n    DESPUES LOS RECORREMOS CON UN FOR-EACH DECLARANDO LOS ELEMENTOS COMO NUMÉRICOS Y RESTÁNDOLES 50 */\n    private static void iterator12() {\n        char[] myList = {'3', '4', '5', '6', '7', '8', '9', ':', ';', '<'};\n\n        for (int myCode : myList) {\n            System.out.print((myCode - 50) + \" \");\n        }\n        System.out.print(\" --> Método 12\");\n        System.out.println(\"\");\n    }\n\n    /*FUNCIÓN CON 5 WHILES ANIDADOS CON CONDICIONES DE PARADA IDÉNTICAS PARA COMPROBAR QUE CADA UNO SOLO ITERA\n    UNA VEZ SIEMPRE QUE HAYA OTRO POR DEBAJO, EL ULTIMO (EL 5º) ES EL QUE COMPLETA LA SECUENCIA DEL 5 AL 10\n    Y VA VOLVIENDO UNO POR UNO A LOS ANTERIORES COMPROBANDO SI LA CONDICIÓN DE PARADA SE CUMPLE EN TODOS Y COMO\n    ES ASÍ LA EJECUCIÓN TERMINA, EN UN CASO DE FOR ANIDADOS OCURRE EXACTAMENTE LO MISMO*/\n\n    private static void iterator13() {\n        int i = 0;\n        while (i < 10) {\n            i++;\n            System.out.print(i + \" \");\n            while (i < 10) {\n                i++;\n                System.out.print(i + \" \");\n                while (i < 10) {\n                    i++;\n                    System.out.print(i + \" \");\n                    while (i < 10) {\n                        i++;\n                        System.out.print(i + \" \");\n                        while (i < 10) {\n                            i++;\n                            System.out.print(i + \" \");\n                        }\n                    }\n                }\n            }\n        }\n        System.out.print(\" --> Método 13\");\n        System.out.println(\"\");\n    }\n\n    /*FUNCIÓN DONDE SE DECLARAN 2 VARIABLES ORIGINALES Y EN BASE A ESTAS SE DECLARAN 7 MÁS CON CÁLCULOS BASADOS EN ELLAS\n    QUE TERMINAN REPRESENTANDO LA SECUENCIA POR PAREJAS (EXCEPTO EL 9), SE AÑADEN A UN ARRAYLIST Y SE RECORREN CON UN FOR PARA \n    EXTRAER LOS ELEMENTOS (PAREJAS DE NÚMEROS) Y UN FOR-EACH ANIDADO DENTRO QUE SEPARA CADA PAREJA EN 2 CHAR INDEPENDIENTES\n    (EXCEPTO EL 10)*/\n    private static void iterator14() {\n        List<String> myList = new ArrayList<>();\n        int a = 1, b = 11, c = b + a, d = b * 2, e = c + d, f = e + d, g = f + d, h = g / 2 - 30, i = (g + d) / 10;\n        myList.add(c + \"\");\n        myList.add(e + \"\");\n        myList.add(f + \"\");\n        myList.add(g + \"\");\n        myList.add(h + \"\");\n        myList.add(i + \"\");\n\n        for (String element : myList) {\n            for (int j = 0; j < element.length(); j++) {\n                if (element.charAt(j) == '0') {\n                    System.out.print(\"\\b\");\n                }\n                System.out.print(element.charAt(j) + \" \");\n            }\n        }\n        System.out.print(\" --> Método 14\");\n        System.out.println(\"\");\n    }\n\n    /*FUNCIÓN CON WHILE CUYA CONDICIÓN ES UN TIPO BOOLEAN DECLARADO PREVIAMENTE CON INCREMENTO, IMPRESIÓN CON\n    IF TERNARIO Y CONDICIÓN DE SALIDA CON EL PROPIO ELEMENTO BOOLEANO*/\n    private static void iterator15() {\n        boolean num = true;\n        int i = 0;\n        while (num) {\n            ++i;\n            num = (i <= 10);\n            System.out.print(num ? i + \" \" : \" --> Método 15\\n\");\n            if (!num) break;      \n        }\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/java/JimsimroDev.java",
    "content": "import java.util.HashMap;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Map;\n\npublic class JimsimroDev {\n\n    /*\n     * EJERCICIO:\n     * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n     * números del 1 al 10 mediante iteración.\n     */\n\n    public static void iterarNumber(int i) {\n        if (i <= 10) {\n            System.out.printf(\"Iteraciones %d %n\", i);\n            iterarNumber(i + 1);\n        }\n    }\n\n    public static void iterarNumber() {\n        iterarNumber(1);\n    }\n\n    public static void main(String[] args) {\n        /*\n         * DIFICULTAD EXTRA (opcional):\n         * Escribe el mayor número de mecanismos que posea tu lenguaje\n         * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n         */\n\n        //Iterar texto con for\n        String texto = \"java\";\n        System.out.println(\"Iterar texto con for:\");\n        for (int i = 0; i < texto.length(); i++) {\n            System.out.printf(\"Caracter %d: %s %n\", i, texto.charAt(i));\n        }\n\n        //Iterar arreglo con for\n        System.out.println(\"Iterar arreglo con for:\");\n        String[] array = { \"a\", \"b\", \"c\", \"d\", \"e\" };\n        for (int i = 0; i < array.length; i++) {\n            System.out.printf(\"Elemento %d: %s %n\", i, array[i]);\n        }\n\n        //Iterar lista con lambda\n        System.out.println(\"Iterar lista con lambda:\");\n        List<String> list = List.of(\"Java\", \"Kotlin\", \"Elixir\", \"PHP\", \"Zig\");\n        list.stream().forEach(System.out::println); //con referencia a metodo\n        list\n            .stream()\n            .forEach(element -> System.out.printf(\"Elemento: %s %n\", element));\n\n        Map<Integer, Object> map = new HashMap<>();\n        map.put(1, \"Java\");\n        map.put(2, \"Kotlin\");\n        map.put(3, \"Elixir\");\n        map.put(4, \"PHP\");\n\n        //Recorrer pares indice valor del diccionario\n        System.out.println(\"Recorrer pares clave-valor del diccionario:\");\n        for (Iterator it = map.entrySet().iterator(); it.hasNext();) {\n            Map.Entry entry = (Map.Entry) it.next();\n            System.out.printf(\n                \"Clave: %d Valor: %s %n\",\n                entry.getKey(),\n                entry.getValue()\n            );\n        }\n\n        //Recorrer valor del diccionario con for\n        System.out.println(\"Recorrer valores del diccionario:\");\n        for (Iterator it = map.keySet().iterator(); it.hasNext();) {\n            System.out.printf(\"Valor: %s %n\", map.get(it.next()));\n        }\n\n        //Recorrer clave del diccionario con for\n        System.out.println(\"Recorrer claves del diccionario:\");\n        for (Iterator it = map.keySet().iterator(); it.hasNext();) {\n            System.out.printf(\"Clave: %s %n \", it.next());\n        }\n\n        //Recorrer pares clave-valor del diccionario con lambda\n        System.out.println(\n            \"Recorrer pares clave-valor del diccionario con lambda:\"\n        );\n\n        map.forEach((key, value) ->\n            System.out.printf(\"Clave: %d Valor: %s %n\", key, value)\n        );\n\n        //Iterar hata 10 con for\n        System.out.println(\"Iteraciones con for:\");\n        for (int i = 1; i <= 10; i++) {\n            System.out.printf(\"Iteraciones %d %n\", i);\n        }\n\n        //Iterar hasta 10 con while\n        System.out.println(\"Iteraciones con while:\");\n        int iteraciones = 1;\n        while (iteraciones <= 10) {\n            System.out.printf(\"Iteraciones %d %n\", iteraciones);\n            iteraciones++;\n        }\n\n        System.out.println(\"Iteraciones con recursividad:\");\n        iterarNumber();\n    }\n}\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/java/Josegs95.java",
    "content": "import java.util.ArrayList;\nimport java.util.Collection;\n\npublic class Josegs95 {\n    public static void main(String[] args) {\n        //Ejercicio\n        //iterateFor(1, 10);\n        //iterateWhile(1, 10);\n        //iterateDoWhile(1, 10);\n\n        //Reto\n        retoFinal();\n    }\n\n    public static void retoFinal(){\n        //Los 3 anteriores\n        //iterateRecursive(1, 10);\n        iterateForEach(createIntegerList(1, 10));\n    }\n\n    public static void iterateFor(int begin, int end){\n        for (;begin <= end; begin++){\n            System.out.println(begin);\n        }\n    }\n\n    public static void iterateWhile(int begin, int end){\n        while (begin <= end){\n            System.out.println(begin);\n            begin++;\n        }\n    }\n\n    public static void iterateDoWhile(int begin, int end){\n        do{\n            System.out.println(begin);\n            begin++;\n        }while (begin <= end);\n    }\n\n    public static void iterateRecursive(int begin, int end){\n        if (begin < end)\n            iterateRecursive(begin, end - 1);\n        System.out.println(end);\n    }\n\n    public static void iterateForEach(Collection<Integer> intList){\n        for(int n : intList){\n            System.out.println(n);\n        }\n    }\n\n    private static ArrayList<Integer> createIntegerList(int begin, int end){\n        ArrayList<Integer> intList = new ArrayList<>();\n        while(begin <= end){\n            intList.add(begin);\n            begin++;\n        }\n\n        return intList;\n    }\n}\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/java/asjordi.java",
    "content": "import java.util.*;\nimport java.util.stream.IntStream;\nimport java.util.stream.Stream;\n\npublic class Main {\n\n    public static void main(String[] args) {\n        printNumbers();\n        iterate();\n    }\n\n    /**\n     * EJERCICIO:\n     * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n     * números del 1 al 10 mediante iteración.\n     */\n    static void printNumbers() {\n        // Forma 1: Usando un for\n        for (int i = 1; i <= 10 ; i++) System.out.println(i);\n\n        // Forma 2: Iterando un List con forEach\n        for (int i : Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)) System.out.println(i);\n\n        // Forma 3: Iterando un IntStream\n        IntStream.rangeClosed(1, 10).forEach(System.out::println);\n    }\n\n    /**\n     * DIFICULTAD EXTRA (opcional):\n     * Escribe el mayor número de mecanismos que posea tu lenguaje\n     * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n     */\n\n    static void iterate() {\n        List<Integer> nums = List.of(1, 2, 3, 4, 5);\n\n        for (int i = 0; i < nums.size(); i++) System.out.println(nums.get(i));\n\n        for (Integer num : nums) System.out.println(num);\n\n        nums.forEach(System.out::println);\n\n        nums.stream().forEach(n -> System.out.println(n));\n\n        int i = 0;\n        while (i < nums.size()) {\n            System.out.println(nums.get(i));\n            i++;\n        }\n\n        Iterator<Integer> iterator = nums.iterator();\n        while (iterator.hasNext()) System.out.println(iterator.next());\n\n        Iterator<Integer> it = nums.iterator();\n        it.forEachRemaining(num -> System.out.println(num));\n\n        ListIterator<Integer> listIterator = nums.listIterator();\n        while (listIterator.hasNext()) System.out.println(listIterator.next());\n\n        nums.spliterator().forEachRemaining(System.out::println);\n\n        Arrays.stream(nums.toArray()).forEach(n -> System.out.println(n));\n\n        Stream.of(nums).forEach(System.out::println);\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/java/cesar-ch.java",
    "content": "/*\n * #17 ITERACIONES\n*/\n\nimport java.util.Arrays;\n\npublic class Main {\n    public static void main(String[] args) {\n        // Arreglo de números\n        int[] numeros = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };\n\n        // Bucle for\n        for (int i = 0; i < numeros.length; i++) {\n            System.out.println(numeros[i]);\n        }\n\n        // Bucle for each\n        for (int numero : numeros) {\n            System.out.println(numero);\n        }\n\n        /*\n         * DIFICULTAD EXTRA\n        */\n        // Bucle while\n        int j = 0;\n        while (j < numeros.length) {\n            System.out.println(numeros[j]);\n            j++;\n        }\n\n        // Bucle do while\n        int k = 0;\n        do {\n            System.out.println(numeros[k]);\n            k++;\n        } while (k < numeros.length);\n\n        // Usando un bucle for each\n        Arrays.stream(numeros)\n                .forEach(numero -> System.out.println(numero));\n\n        // Usando un bucle map\n        Arrays.stream(numeros)\n                .map(numero -> numero * 2)\n                .forEach(numero -> System.out.println(numero));\n\n        // ....\n    }\n}\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/java/chartypes.java",
    "content": "import java.util.Arrays;\nimport java.util.List;\n\npublic class chartypes {\n\n    public static void main(String[] args) {\n        // exercise\n        System.out.println();\n        System.out.println(1);\n        for (int i = 1; i < 11; i++)\n            System.out.print(i);\n\n        System.out.println();\n        System.out.println(2);\n        int iterator = 1;\n        while (iterator <= 10) {\n            System.out.print(iterator);\n            iterator++;\n        }\n\n        System.out.println();\n        System.out.println(3);\n        iterator = 1;\n        do {\n            System.out.print(iterator);\n            iterator++;\n\n        } while (iterator <= 10);\n\n        // extra\n        System.out.println();\n        System.out.println(4);\n        int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };\n        for (int i : numbers)\n            System.out.print(i);\n\n        System.out.println();\n        System.out.println(5);\n        List<Integer> numbersList = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);\n        numbersList.stream().forEach(System.out::print);\n\n        System.out.println();\n        System.out.println(6);\n        recursiveIterator(1);\n\n    }\n\n    private static void recursiveIterator(int number) {\n        if (number > 10) {\n            return;\n        }\n        System.out.print(number);\n        number++;\n        recursiveIterator(number);\n    }\n\n}"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/java/danhingar.java",
    "content": "import java.util.Iterator;\nimport java.util.List;\nimport java.util.stream.IntStream;\n\npublic class danhingar {\n\n    public static void main(String[] args) {\n\n        for (int i = 1; i < 11; i++) {\n            System.out.println(i);\n        }\n\n        int j = 1;\n        while (j < 11) {\n            System.out.println(j);\n            j++;\n        }\n\n        int x = 1;\n        do {\n            System.out.println(x);\n            x++;\n        } while (x < 11);\n\n        List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);\n\n        // Extra 1\n\n        IntStream.range(1, 10).forEach(i -> System.out.println(i));\n\n        // Extra 2\n\n        for (Integer number : numbers) {\n            System.out.println(number);\n        }\n\n        // Extra 3\n        numbers.forEach(i -> System.out.println(i));\n\n        //Extra 4\n        Iterator<Integer> i = numbers.iterator();\n        while(i.hasNext()){\n            System.out.println(i.next());\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/java/eulogioep.java",
    "content": "/**\n * Clase que demuestra diferentes mecanismos de iteración en Java\n * \n * En programación, la iteración es el proceso de repetir un bloque de código\n * múltiples veces. Java ofrece varios mecanismos para realizar iteraciones,\n * cada uno con sus propias características y casos de uso ideales.\n */\npublic class eulogioep {\n    public static void main(String[] args) {\n        System.out.println(\"Demostración de diferentes mecanismos de iteración en Java\\n\");\n        \n        // 1. Bucle for tradicional\n        System.out.println(\"1. Usando bucle for tradicional:\");\n        /*\n         * El bucle for es uno de los más comunes y versátiles.\n         * Sintaxis: for (inicialización; condición; incremento)\n         * - inicialización: se ejecuta una vez al principio\n         * - condición: se evalúa antes de cada iteración\n         * - incremento: se ejecuta al final de cada iteración\n         */\n        for (int i = 1; i <= 10; i++) {\n            System.out.print(i + \" \");\n        }\n        System.out.println(\"\\n\");\n\n        // 2. Bucle while\n        System.out.println(\"2. Usando bucle while:\");\n        /*\n         * El bucle while se ejecuta mientras una condición sea verdadera.\n         * Es útil cuando no sabemos exactamente cuántas iteraciones necesitamos.\n         */\n        int contador = 1;\n        while (contador <= 10) {\n            System.out.print(contador + \" \");\n            contador++;\n        }\n        System.out.println(\"\\n\");\n\n        // 3. Bucle do-while\n        System.out.println(\"3. Usando bucle do-while:\");\n        /*\n         * Similar al while, pero garantiza que el código se ejecute al menos una vez\n         * ya que la condición se evalúa al final de cada iteración.\n         */\n        int num = 1;\n        do {\n            System.out.print(num + \" \");\n            num++;\n        } while (num <= 10);\n        System.out.println(\"\\n\");\n\n        // EXTRA: Más mecanismos de iteración\n\n        // 4. forEach con array\n        System.out.println(\"4. Usando forEach con array:\");\n        /*\n         * El bucle forEach es una forma más moderna y legible de iterar\n         * sobre colecciones o arrays.\n         */\n        int[] numeros = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};\n        for (int numero : numeros) {\n            System.out.print(numero + \" \");\n        }\n        System.out.println(\"\\n\");\n\n        // 5. Stream forEach\n        System.out.println(\"5. Usando Stream forEach:\");\n        /*\n         * Los Streams, introducidos en Java 8, ofrecen una forma funcional\n         * de procesar colecciones de datos.\n         */\n        java.util.stream.IntStream.rangeClosed(1, 10)\n            .forEach(n -> System.out.print(n + \" \"));\n        System.out.println(\"\\n\");\n\n        // 6. Iterator\n        System.out.println(\"6. Usando Iterator:\");\n        /*\n         * Los Iterators son objetos que permiten recorrer una colección\n         * y eliminar elementos durante la iteración si es necesario.\n         */\n        java.util.List<Integer> lista = new java.util.ArrayList<>();\n        for (int i = 1; i <= 10; i++) lista.add(i);\n        \n        java.util.Iterator<Integer> iterator = lista.iterator();\n        while (iterator.hasNext()) {\n            System.out.print(iterator.next() + \" \");\n        }\n        System.out.println(\"\\n\");\n\n        // 7. Stream iterate\n        System.out.println(\"7. Usando Stream.iterate:\");\n        /*\n         * Otra forma de usar Streams para generar una secuencia infinita\n         * y limitarla según necesitemos.\n         */\n        java.util.stream.Stream.iterate(1, n -> n + 1)\n            .limit(10)\n            .forEach(n -> System.out.print(n + \" \"));\n        System.out.println(\"\\n\");\n    }\n}"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/java/h4ckxel.java",
    "content": "import java.util.Arrays;\nimport java.util.List;\n\npublic class h4ckxel{\n\n    public static void main(String[] args) {\n        // exercise\n        System.out.println();\n        System.out.println(1);\n        for (int i = 1; i < 11; i++)\n            System.out.print(i);\n\n        System.out.println();\n        System.out.println(2);\n        int iterator = 1;\n        while (iterator <= 10) {\n            System.out.print(iterator);\n            iterator++;\n        }\n\n        System.out.println();\n        System.out.println(3);\n        iterator = 1;\n        do {\n            System.out.print(iterator);\n            iterator++;\n\n        } while (iterator <= 10);\n\n        // extra\n        System.out.println();\n        System.out.println(4);\n        int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };\n        for (int i : numbers)\n            System.out.print(i);\n\n        System.out.println();\n        System.out.println(5);\n        List<Integer> numbersList = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);\n        numbersList.stream().forEach(System.out::print);\n\n        System.out.println();\n        System.out.println(6);\n        recursiveIterator(1);\n\n    }\n\n    private static void recursiveIterator(int number) {\n        if (number > 10) {\n            return;\n        }\n        System.out.print(number);\n        number++;\n        recursiveIterator(number);\n    }\n\n}"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/java/martinbohorquez.java",
    "content": "import java.util.*;\n\n/**\n * #17 ITERACIONES\n *\n * @author martinbohorquez\n */\npublic class martinbohorquez {\n    public static void main(String[] args) {\n        // 1. for\n        System.out.println(\"1. Iteración usando 'for':\");\n        for (int i = 1; i <= 10; i++) System.out.println(i);\n\n        // 2. while\n        System.out.println(\"2. Iteración usando 'while':\");\n        int i = 1;\n        while (i <= 10) System.out.println(i++);\n\n        // 3. recursividad\n        System.out.println(\"3. Iteración usando 'función recursiva':\");\n        count10(1);\n\n        /*\n         * DIFICULTAD EXTRA\n         */\n        //4. Array y for\n        System.out.println(\"4. Iteración usando 'array con fori'\");\n        int[] numbers = {6, 5, 4, 3, 2, 1};\n        for (int number : numbers) System.out.println(number);\n\n        //5. Stream y forEach\n        System.out.println(\"5. Iteración usando 'stream con forEach'\");\n        Arrays.stream(numbers).forEach(System.out::println);\n\n        // 6. Lista, reversed y forEach\n        System.out.println(\"6. Iteración usando 'lista con forEach(reversed)'\");\n        Arrays.asList(1, 2, 3, 4).reversed().forEach(System.out::println);\n\n        //7 String, split, stream y forEach\n        System.out.println(\"7. Iteración para una 'string' (sorted) usando 'split, stream y forEach'\");\n        String word = \"strawberry\";\n        Arrays.stream(word.split(\"\")).sorted().forEach(System.out::println);\n\n        // 8. Map, keySet, values, forEach\n        System.out.println(\"8. Iteración para una 'map' por keys/values usando 'forEach'\");\n        Map<Integer, String> map = new HashMap<>();\n        map.put(1, \"a\");\n        map.put(2, \"b\");\n        map.put(3, \"c\");\n        map.put(4, \"d\");\n        map.put(5, \"e\");\n        map.keySet().forEach(System.out::println);\n        map.values().forEach(System.out::println);\n        map.forEach((key, value) -> System.out.println(key + \": \" + value));\n\n        // 9. do-while\n        System.out.println(\"9. Iteración usando 'do-while':\");\n        i = 10;\n        do {\n            System.out.println(i--);\n        } while (i >= 1);\n\n        // 10. set, iterator\n        System.out.println(\"10. Iteración de un 'set' usando 'iterator':\");\n        Set<String> set = new HashSet<>(Arrays.asList(\"a\", \"b\", \"c\", \"d\", \"e\"));\n        Iterator<String> iterator = set.iterator();\n        iterator.forEachRemaining(System.out::println);\n\n    }\n\n    private static void count10(int i) {\n        if (i <= 10) {\n            System.out.println(i);\n            count10(++i);\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/java/simonguzman.java",
    "content": "import java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Enumeration;\nimport java.util.HashSet;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.ListIterator;\nimport java.util.NoSuchElementException;\nimport java.util.Set;\nimport java.util.Spliterator;\nimport java.util.Spliterators;\nimport java.util.Vector;\nimport java.util.stream.IntStream;\n\npublic class simonguzman {\n    public static void main(String[] args) {\n        bucleFor();\n        bucleWhile();\n        bucleForEachArray();\n        bucleDoWhile();\n        iteradorConjunto();\n        streamApi();\n        bucleIterator();\n        bucleEnumeration();\n        bucleListIterator();\n        bucleIteratorIterable();\n        bucleSpliterator();\n        bucleArrayIterator();\n        bucleEnumerator();\n        bucleCursor();\n        buclePeekingIterator();\n    }\n\n    static void bucleFor(){\n        for (int i = 1; i <= 10; i++){\n            System.out.println(i);\n        }\n    }\n\n    static void bucleWhile(){\n        int i = 1;\n        while(i <=10){\n            System.out.println(i);\n            i++;\n        }\n    }\n\n    static void bucleForEachArray(){\n        int [] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};\n        for (int number : numbers){\n            System.out.println(number);\n        }\n    }\n\n    static void bucleDoWhile(){\n        int i = 1;\n        do{\n            System.out.println(i);\n            i++;\n        }while(i <= 10);\n    }\n\n    static void iteradorConjunto(){\n        Set<Integer> numbers = new HashSet<>();\n        for (int i = 1; i <= 10; i++){\n            numbers.add(i);\n        }\n        for (Integer number : numbers){\n            System.out.println(number);\n        }\n    }\n\n    static void streamApi(){\n        IntStream.range(1, 11).forEach(System.out::println);\n    }\n\n    static void bucleIterator(){\n        List<Integer> numbers = new ArrayList<>();\n        for(int i = 1; i <=10; i++){\n            numbers.add(i);\n        }\n        Iterator<Integer> iterator = numbers.iterator();\n        while(iterator.hasNext()){\n            System.out.println(iterator.next());\n        }\n    }\n\n    static void bucleEnumeration(){\n        Vector<Integer> numbers = new Vector<>();\n        for (int i = 0; i <= 10; i++){\n            numbers.add(i);\n        }\n        Enumeration<Integer> enumeration = numbers.elements();\n        while (enumeration.hasMoreElements()) { \n            System.out.println(enumeration.nextElement());\n        }\n    }\n\n    static void bucleListIterator(){\n        List<Integer> numbers = new ArrayList<>();\n        for (int i = 1; i <= 10; i++){\n            numbers.add(i);\n        }\n        ListIterator<Integer> listIterator =  numbers.listIterator();\n        while (listIterator.hasNext()) { \n            System.out.println(listIterator.next());\n        }\n    }\n\n    static void bucleIteratorIterable(){\n        Iterable<Integer> numbers = new Iterable<Integer>() {\n            @Override\n            public Iterator<Integer> iterator() {\n                return new Iterator<Integer>() {\n                    int i = 1;\n                    @Override\n                    public boolean hasNext() {\n                        return i <= 10;\n                    }\n                    @Override\n                    public Integer next() {\n                        return i++;\n                    }\n                };\n            }\n        };\n        for (Integer number : numbers){\n            System.out.println(number);\n        }\n    }\n\n    static void bucleSpliterator(){\n        int[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};\n        Spliterator<Integer> spliterator = Arrays.spliterator(numbers);\n        spliterator.forEachRemaining(System.out::println);\n    }\n\n    static void bucleArrayIterator(){\n        Integer[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};\n        Iterator<Integer> arrayIterator = ArrayIterator.iterator(numbers);\n        while (arrayIterator.hasNext()) {\n            System.out.println(arrayIterator.next());\n        }\n    }\n\n    static void bucleEnumerator(){\n        Enumeration<Integer> enumeration = Enumerator.enumeration((new Integer[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}));\n        while (enumeration.hasMoreElements()) {\n            System.out.println(enumeration.nextElement());\n        }   \n    }\n\n    static void bucleCursor(){\n        Iterator<Integer> cursor = Cursor.cursor((new Integer[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}));\n        while (cursor.hasNext()) {\n            System.out.println(cursor.next());\n        }\n    }\n\n    static void buclePeekingIterator(){\n        Iterator<Integer> peekingIterator = PeekingIterator.peekingIterator((new Integer[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}));\n        while (peekingIterator.hasNext()) {\n            System.out.println(peekingIterator.next());\n        }\n    }\n\n    static class ArrayIterator{\n        public static <T> Iterator<T> iterator(T[] array) {\n        return new Iterator<T>() {\n            private int index = 0;\n\n            @Override\n            public boolean hasNext() {\n                return index < array.length;\n            }\n\n            @Override\n            public T next() {\n                if (!hasNext()) {\n                    throw new NoSuchElementException();\n                }\n                return array[index++];\n            }\n        };\n    }\n    }\n\n    static class Enumerator{\n        public static <T> Enumeration<T> enumeration(T[] array) {\n        return new Enumeration<T>() {\n            private int index = 0;\n\n            @Override\n            public boolean hasMoreElements() {\n                return index < array.length;\n            }\n\n            @Override\n            public T nextElement() {\n                if (!hasMoreElements()) {\n                    throw new NoSuchElementException();\n                }\n                return array[index++];\n            }\n        };\n    }\n    }\n\n    static class Cursor{\n        public static <T> Iterator<T> cursor(T[] array) {\n        return new Iterator<T>() {\n            private int index = 0;\n\n            @Override\n            public boolean hasNext() {\n                return index < array.length;\n            }\n\n            @Override\n            public T next() {\n                if (!hasNext()) {\n                    throw new NoSuchElementException();\n                }\n                return array[index++];\n            }\n        };\n    }\n    }\n\n    static class PeekingIterator{\n        public static <T> Iterator<T> peekingIterator(T[] array) {\n            return new Iterator<T>() {\n                private int index = 0;\n                private T peekedElement = null;\n    \n                @Override\n                public boolean hasNext() {\n                    return index < array.length;\n                }\n    \n                @Override\n                public T next() {\n                    if (!hasNext()) {\n                        throw new NoSuchElementException();\n                    }\n                    if (peekedElement != null) {\n                        T element = peekedElement;\n                        peekedElement = null;\n                        return element;\n                    }\n                    return array[index++];\n                }\n    \n                public T peek() {\n                    if (!hasNext()) {\n                        throw new NoSuchElementException();\n                    }\n                    if (peekedElement == null) {\n                        peekedElement = array[index];\n                    }\n                    return peekedElement;\n                }\n            };\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/javascript/7R0N1X.js",
    "content": "let index = 1\nconst numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n\nconsole.log(`-----  FOR -----`)\nfor (index = 1; index <= 10; index++) {\n  console.log(index)\n}\n\nconsole.log(`-----  FOREACH -----`)\nnumeros.forEach(numero => console.log(numero))\n\nconsole.log(`-----  FOR IN -----`)\nindex = 1\nfor (index in numeros) {\n  console.log(numeros[index])\n}\n\nconsole.log(`-----  MAP -----`)\nnumeros.map(numero => console.log(numero))\n\nconsole.log(`-----  WHILE -----`)\nindex = 1\nwhile (index <= 10) {\n  console.log(index)\n  index++\n}\n\nconsole.log(`-----  DO WHILE -----`)\nindex = 1\ndo {\n  console.log(index)\n  index++\n} while (index <= 10);\n\nconsole.log(`-----  function* -----`)\nindex = 1\nfunction* iteracion() {\n  while (index <= 10) yield index++\n}\n\nconst iterar = iteracion()\nconsole.log(iterar.next().value)\nconsole.log(iterar.next().value)\nconsole.log(iterar.next().value)\nconsole.log(iterar.next().value)\nconsole.log(iterar.next().value)\nconsole.log(iterar.next().value)\nconsole.log(iterar.next().value)\nconsole.log(iterar.next().value)\nconsole.log(iterar.next().value)\nconsole.log(iterar.next().value)"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/javascript/AChapeton.js",
    "content": "// FOR\nconsole.log('FOR');\nfor (let i = 0; i <= 10; i++) {\n    console.log(i);\n}\n// FOREACH\nconsole.log('FOREACH');\nlet numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\nnumbers.forEach(function (i) {\n    console.log(i);\n});\n// FOR IN\nconsole.log('FOR IN');\nfor (let i in numbers) {\n    console.log(numbers[i]);\n}\n// FOR OF\nconsole.log('FOR OF');\nfor (let _i = 0, numbers_1 = numbers; _i < numbers_1.length; _i++) {\n    let i = numbers_1[_i];\n    console.log(i);\n}\n// WHILE\nconsole.log('WHILE');\nlet w = 0;\nwhile (w < 11) {\n    console.log(w);\n    w++;\n}\n// DO-WHILE\nconsole.log('DO-WHILE');\nlet d = 0;\ndo {\n    console.log(d);\n    d++;\n} while (d < 11);\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/javascript/Artickun.js",
    "content": "\n// ⚡ Iteraciones\n\n// 1. While\nlet i = 0;\nwhile (i < 10) {\n    console.log(i);\n    i++;\n};\n\n// 2. Do While\nlet j = 0;\ndo {\n    console.log(j);\n    j++;\n} while (j < 10);\n\n// 3. For\nfor (let k = 0; k < 10; k++) {\n    console.log(k);\n};\n\n\n/*\nDIFICULTAD EXTRA (opcional):\n\n  - Escribe el mayor número de mecanismos que posea tu lenguaje\n  - para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n\n*/\n\n// For in\nconst obj = {a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7, h: 8, i: 9, j: 10};\nfor (let key in obj) {\n    console.log(obj[key]);\n};\n\n// For of\nconst array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\nfor (let item of array) {\n    console.log(item);\n};\n\n// For each\narray.forEach(function(element) {\n    console.log(element);\n});\n\n// For await\nasync function asyncFunction() {\n    for await (const element of array) {\n        console.log(element);\n    }\n};\nasyncFunction();\n\n//map\n[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map( num => console.log(num) );\n\n//filter\n[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].filter( num => {\n    console.log(num);\n    return false;\n});\n\n//every\n[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].every(num => {\n    console.log(num);\n    return true;\n});\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/javascript/DavidMoralesDeveloper.js",
    "content": "// Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n//  * números del 1 al 10 mediante iteración.\n\n// for  --------------\nlet arr = []\nfor(let i = 0; i < 10; i++){\narr.push(i)\nconsole.log(i  + 'crando numeros en for y push en arr')\n}\n\n\n\n// forech \narr.forEach( a  => {\n    console.log(a + 'dentro de  forech')\n});\n\n// for in\nfor (const numer in arr) {\n    console.log(numer + 'forin')\n}\n\n//for of\nfor (let i of arr) {\n    console.log(i + 'forof');\n  }\n\n\n// do while ----------------\nlet result = '';\nlet i = 0;\n\ndo {\n  i = i + 1;\n  console.log(i + 'dowhile')\n  result = result + i;\n} while (i < 10);\n\nconsole.log(  result + ' dowhile me da un string de el 1 al 10' );\n\n// while ------------------------------ \nlet y = 0\nlet z = 0\n while (y < 10) {\n    y++\n    z += y\n    console.log(y + 'dentro de while')\n }\nconsole.log(z + 'fuera de while')\n\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/javascript/Deyvid-10.js",
    "content": "// Iteraciones\n\n// loop for\nfor (let i = 1; i <= 10; i++) \n    {\n        console.log(i);\n    }\n    \n    // loop for of\n    let array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n    \n    for(const a of array) \n    {\n        console.log(a);\n    }\n    \n    // loop for in\n    let objeto = {a:1, b:2, c:3, d:4, e:5, f:6, g:7, h:8, i:9, j:10}\n    for (const o in objeto) \n    {\n        console.log(objeto[o]);\n    }\n    \n    // DIFICULTAD EXTRA\n    \n    // loop while\n    \n    let cont = 0\n    \n    while(cont < 10)\n    {\n        cont++\n        console.log(cont);\n    }\n    \n    // loop do while\n    \n    let cont2 = 0\n    do\n    {\n        cont2++\n        console.log(cont2);\n    }while (cont2 < 10)\n    \n    // recursividad\n    function recursivo(num)\n    {\n        if(num <= 10)\n        {\n            console.log(num);\n            recursivo(num + 1)\n        }\n    }\n    \n    recursivo(1)\n    \n    // loop forEach()\n    \n    let array2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n    \n    array2.forEach(num => console.log(num))\n    \n    // for of para un string\n    \n    for(const a of \"0123456789\") \n    {\n        console.log(a);\n    }"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #17 - JavaScript ->Jesus Antonio Escamilla */\n/**\n * Las iteraciones en JavaScript son acciones encargadas de extraer datos permanentemente que son solicitados a la base de datos para ser mostrados en el lado del cliente.\n * Una de las principales ventajas de la programación es la posibilidad de crear bucles y repeticiones para tareas específicas, y que no tengamos que realizar el mismo código varias veces de forma manual.\n * Los bucles ofrecen una forma rápida y sencilla de hacer algo repetidamente.\n*/\n\n//---EJERCIÓ---\n\n// Utilizaremos el bucle FOR\nfor (let i = 1; i <= 10; i++) {     //for(inicializar; condición; incrementó)\n    console.log(i);     //Aquí se imprime del 1 - 10\n}\n\n// Otro forma se usar bucle WHILE\nlet i = 1;  //Aquí se declara una variable para usar como condición\nwhile (i <= 10) {   //Se pone el incrementó\n    console.log(`El valor es:`,i);  //Aquí imprimimos la siempre la variable\n    i = i + 1;      //Se va incrementando hasta que la condición diga\n}\n\n// Y la última forma de usar bucle es FOR-EACH\nconst números = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];    //Hacemos un array de los números\nnúmeros.forEach(number => {     //Y el Método forEach va iterando todos los elementos\n    console.log(`Los números son ${number}`);   //Aquí se imprime los números\n});\n\n\n\n/**-----DIFICULTAD EXTRA-----*/\n\n//Otra Forma de hacer Iteraciones:\n//  DO...WHILE\nlet k = 1;  // Variable nueva\ndo {\n    console.log(`Se imprimen ${k}`);\n    k++\n} while (k <= 10);\n\n//  FOR...OF\nconst iterable = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\nfor (const item of iterable) {\n    console.log(`El numero es : ${item}`);\n}\n\n//  FUNCIÓN RECESIVA\nfunction contar(i) {\n    if (i <= 10) {\n        console.log(`Se cuenta a ${i}`);\n        contar(i + 1);\n    }\n}\ncontar(1);\n\n//  FOR...IN\nconst number = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\nfor (const key in number) {\n    console.log(`Se muestra el indice: ${number[key]}`);\n}\n\n/**-----DIFICULTAD EXTRA-----*/"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/javascript/RaulDoezon.js",
    "content": "/*\n  EJERCICIO:\n  Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n  números del 1 al 10 mediante iteración.\n*/\n\nconsole.log(\"Imprimir números del 1 al 10 mediante:\");\nconsole.log(\"\\n+++++++++ FOR +++++++++\");\n\nfor (let iteration1 = 1; iteration1 < 11; iteration1++) {\n  const element = iteration1;\n\n  console.log(element);\n}\n\nconsole.log(\"\\n+++++++++ WHILE +++++++++\");\n\nlet iteration2 = 1;\n\nwhile (iteration2 < 11) {\n  console.log(iteration2++);\n}\n\nconsole.log(\"\\n+++++++++ DO WHILE +++++++++\");\n\nlet iteration3 = 1;\n\ndo {\n  console.log(iteration3++);\n} while (iteration3 < 11);\n\n/*\n  EJERCICIO:\n  DIFICULTAD EXTRA (opcional):\n  Escribe el mayor número de mecanismos que posea tu lenguaje\n  para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n*/\nconsole.log(\"\\nMECANISMOS PARA ITERAR:\");\nconsole.log(\"\\n+++++++++ 1. FOR +++++++++\");\n\nconst dbCharacters = [\"Goku\", \"Vegeta\", \"Piccolo\", \"Gohan\"];\n\nfor(let index = 0; index < dbCharacters.length; index++) {\n  const character = dbCharacters[index];\n\n  console.log(character);\n}\n\nconsole.log(\"\\n+++++++++ 2. FOR...IN +++++++++\");\nfor (const forInCharacter in dbCharacters) {\n  const element = dbCharacters[forInCharacter];\n\n  console.log(element);\n}\n\nconsole.log(\"\\n+++++++++ 3. FOR...OF +++++++++\");\nfor (const dbIterator of dbCharacters) {\n  console.log(dbIterator);\n}\n\nconsole.log(\"\\n+++++++++ 4. FOREACH +++++++++\");\ndbCharacters.forEach((element) => {\n  console.log(element);\n});\n\nconsole.log(\"\\n+++++++++ 5. WHILE +++++++++\");\n\nlet whileIndex = 0;\n\nwhile (whileIndex < dbCharacters.length) {\n  console.log(dbCharacters[whileIndex]);\n\n  whileIndex++;\n}\n\nconsole.log(\"\\n+++++++++ 6. DO WHILE +++++++++\");\n\nlet doWhileIndex = 0;\n\ndo {\n  console.log(dbCharacters[doWhileIndex]);\n\n  doWhileIndex++;\n} while (doWhileIndex < dbCharacters.length);\n\nconsole.log(\"\\n+++++++++ 7. FUNCIÓN RECURSIVA +++++++++\");\n\nfunction recursiveFunction(number) {\n  if (number === 11) {\n    return;\n  }\n\n  console.log(dbCharacters[number]);\n\n  return recursiveFunction(number + 1)\n}\n\nrecursiveFunction(0);\n\nconsole.log(\"\\n+++++++++ 8. MAP +++++++++\");\ndbCharacters.map(function(character){\n  console.log(character);\n});\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/javascript/RicJDev.js",
    "content": "//EJERCICIO\nconsole.log('\\n-BUCLE FOR-');\n\nfor (let i = 1; i <= 10; i++) {\n\tconsole.log(i);\n}\n\nconsole.log('\\n-BUCLE WHILE-');\n\nlet counter = 1;\n\nwhile (counter <= 10) {\n\tconsole.log(counter);\n\tcounter++;\n}\n\nconsole.log('\\n-BUCLE DO/WHILE-');\n\nlet counter2 = 1;\n\ndo {\n\tconsole.log(counter2);\n\tcounter2++;\n} while (counter2 <= 10);\n\n//EXTRA\nconsole.log('\\n-RECURSIVIDAD-');\n\nfunction countTen(i = 1) {\n\tif (i <= 10) {\n\t\tconsole.log(i);\n\t\tcountTen(i + 1);\n\t}\n}\n\ncountTen();\n\nconsole.log('\\n-BUCLE FOR EACH-');\n\nconst numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n\nnumbers.forEach((n) => {\n\tconsole.log(n);\n});\n\nconsole.log('\\n-BUCLE FOR IN-');\n\nconst numbersObj = {\n\t1: 'A',\n\t2: 'B',\n\t3: 'C',\n\t4: 'D',\n\t5: 'E',\n\t6: 'F',\n\t7: 'G',\n\t8: 'H',\n\t9: 'I',\n\t10: 'J',\n};\n\nfor (let i in numbersObj) {\n\tconsole.log(i);\n}\n\nconsole.log('\\n-BUCLE FOR OF-');\n\nconst numbersSet = new Set(numbers);\n\nfor (let i of numbersSet) {\n\tconsole.log(i);\n}\n\nconsole.log('\\n-ITERANDO UNA STRING CONVERTIDA EN ARRAY-');\nlet numbersString = '1234567890';\nnumbersString.split('').forEach((n) => {\n\tconsole.log(n);\n});\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/javascript/Sac-Corts.js",
    "content": "console.log(\"for\");\nfor (i = 1; i <= 10; i++) {\n    console.log(i);\n}\n\nconsole.log(\"while\");\nlet n = 1;\nwhile (n <= 10) {\n    console.log(n);\n    n++;\n}\n\nconsole.log(\"do while\");\nn = 1;\ndo {\n    console.log(n);\n    n++;\n} while (n <= 10);\n\n// Extra Exercise //\nconsole.log(\"for of\");\nnumbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\nfor (number of numbers) {\n    console.log(number);\n}\n\nconsole.log(\"for in\");\nfor (number in numbers) {\n    console.log(numbers[number]);\n}\n\nconsole.log(\"forEach\");\nnumbers.forEach((number) => {\n    console.log(number);\n});\n\nconsole.log(\"map\");\nnumbers.map((number) => {\n    console.log(number);\n});\n\nconsole.log(\"Array.from\");\nArray.from({ length: 10 }, (_, i) => console.log(i + 1));\n\nconsole.log(\"reduce\");\nnumbers.reduce((_, number) => {\n    console.log(number);\n    return number;\n}, 0);\n\nconsole.log(\"Recursion\");\nfunction printNumbers(n) {\n    if (n > 10) return;\n    console.log(n);\n    printNumbers(n + 1);\n}\n\nprintNumbers(1);"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/javascript/adrs1166ma.js",
    "content": "/* 🔥EJERCICIO:\nUtilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\nnúmeros del 1 al 10 mediante iteración.\n*/\n// * 1. Bucle for tradicional \nconsole.log(\"Mecanismo 1: Bucle for\");\nfor (let i = 1; i <= 10; i++) {\n    console.log(i);\n}\n\n// * 2. Bucle while\nconsole.log(\"\\nMecanismo 2: Bucle while\");\nlet i = 1;\nwhile (i <= 10) {\n    console.log(i);\n    i++;\n}\n\n// * 3. Método forEach con un array\nconsole.log(\"\\nMecanismo 3: forEach con un array\");\nconst numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\nnumeros.forEach((numero) => {\n    console.log(numero);\n});\n\n/* 🔥 DIFICULTAD EXTRA (opcional):------------------------------------------------------------------------\nEscribe el mayor número de mecanismos que posea tu lenguaje\npara iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n*/\n// * 4.  Bucle do...while\nconsole.log(\"\\nMecanismo 4: Bucle do...while\");\nlet j = 1;\ndo {\n    console.log(j);\n    j++;\n} while (j <= 10);\n\n// * 5. Método map con un array\nconsole.log(\"\\nMecanismo 5: map con un array\");\nconst numerosMap = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\nnumerosMap.map((numero) => {\n    console.log(numero);\n});\n\n// * 6. Recursión\nconsole.log(\"\\nMecanismo 6: Recursión\");\nfunction imprimirNumeros(n) {\n    if (n > 10) return;\n    console.log(n);\n    imprimirNumeros(n + 1);\n}\nimprimirNumeros(1);\n\n// * 7. Generadores (function*)\nconsole.log(\"\\nMecanismo 7: Generadores\");\nfunction* generarNumeros() {\n    for (let i = 1; i <= 10; i++) {\n        yield i;\n    }\n}\nconst generador = generarNumeros();\nfor (const numero of generador) {\n    console.log(numero);\n}\n\n// * 8. Método reduce con un array\nconsole.log(\"\\nMecanismo 8: reduce con un array\");\nconst numerosReduce = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\nnumerosReduce.reduce((_, numero) => {\n    console.log(numero);\n    return null;\n}, null);\n\n// * 9. Iterador personalizado (Symbol.iterator)\nconsole.log(\"\\nMecanismo 9: Iterador personalizado\");\nconst iterable = {\n    [Symbol.iterator]() {\n        let i = 1;\n        return {\n            next() {\n                if (i <= 10) {\n                    return { value: i++, done: false };\n                } else {\n                    return { done: true };\n                }\n            },\n        };\n    },\n};\nfor (const numero of iterable) {\n    console.log(numero);\n}\n\n// * 10. Promesas encadenadas\nconsole.log(\"\\nMecanismo 10: Promesas encadenadas\");\nlet promesa = Promise.resolve(1);\nfor (let i = 1; i <= 10; i++) {\n    promesa = promesa.then((valor) => {\n        console.log(valor);\n        return valor + 1;\n    });\n}"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/javascript/agusrosero.js",
    "content": "/*\n * EJERCICIO:\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n * números del 1 al 10 mediante iteración.\n *\n * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n */\n\n// EJERCICIO:\n// for\nfor (let i = 1; i < 11; i++) {\n  console.log(i);\n}\n\n// while\nconsole.log();\nx = 1;\nwhile (x < 11) {\n  console.log(x);\n  x++;\n}\n\n// do-while\nconsole.log();\na = 1;\ndo {\n  console.log(a);\n  a++;\n} while (a < 11);\n\n// DIFICULTAD EXTRA:\n// 1\nconst object = { a: 1, b: 2, c: 3 };\nfor (const property in object) {\n  console.log(`${property}: ${object[property]}`);\n}\n\n// 2\nconst miArray = [1, 2, 3, 4, 5];\nfor (arr of miArray) {\n  console.log(arr);\n}\n\n// 3\nasync function forAwait() {\n  const secondArray = [6, 7, 8, 9];\n  for await (arr of secondArray) {\n    console.log(arr);\n  }\n}\n\n// 4\nconst array = [1, 2, 3, 4, 5];\narray.forEach((value) => {\n  console.log(value);\n});\n\n// 5\nconst array2 = [4, 5, 6];\nconst newArray = array2.map((value) => value * 2);\nconsole.log(newArray);\n\n// 6\nconst array3 = [7, 8, 9, 10];\nconst filteredArray = array3.filter((value) => value > 2);\nconsole.log(filteredArray);\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/javascript/bernatcs.js",
    "content": "// ** EJERCICIO \n\n// for\nfor (let index = 1; index <= 10; index++) {\n    console.log(index)\n    \n}\n\n// while\nlet index2 = 1\nwhile (index2 <= 10) {\n    console.log(index2);\n    index2++\n}\n\n// forEach\nlet index3 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\nindex3.forEach(element => {\n    console.log(element)\n});\n\n// ** DIFICULTAD EXTRA ** -----------------------------------------------------------------------------------------------------------\n\n// for...of\nlet index4 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\nfor (let element of index4) {\n    console.log(element)\n}\n\n// for...in --> La diferencia con el of es que devuelve los índices \nlet index5 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\nfor (let element in index5) {\n    console.log(Number(element) + 1)\n}\n\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/javascript/caterinarodriguezdev.js",
    "content": "/*\n * EJERCICIO:\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n * números del 1 al 10 mediante iteración.\n *\n * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n */\n\nconsole.log('for');\nfor (let i = 1; i <= 10; i++) {\n    console.log(i);\n}\n\nconsole.log('while');\nlet i = 1;\nwhile (i <= 10) {\n    console.log(i);\n    i++;\n}\n\nconsole.log('do while');\nlet j = 1;\ndo {\n    console.log(j);\n    j++\n} while (j <= 10);\n\n\nconsole.log('---------------------DIFICULTAD EXTRA-------------------------------');\n\nconsole.log('for of');\nconst numerosHastaDiez = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\nfor (numero of numerosHastaDiez) {\n    console.log(numero);\n}\n\nconsole.log('for in');\nfor (index in numerosHastaDiez) {\n    console.log(numerosHastaDiez[index]);\n}\n\nconsole.log('forEach');\nnumerosHastaDiez.forEach(num => console.log(num))\n\nconsole.log('map');\nnumerosHastaDiez.map(num => console.log(num));\n\nconsole.log('flatMap');\nnumerosHastaDiez.flatMap(num => console.log(num));\n\nconsole.log('reduce');\nnumerosHastaDiez.reduce((_prevValue, num) => {\n    console.log(num);\n    return _prevValue;\n}, 0)"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/javascript/cesar-ch.js",
    "content": "/*\n    *  #17 ITERACIONES\n*/\n\nconst numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n// 1. Bucle for\nfor (let i = 0; i < numeros.length; i++) {\n    console.log(numeros[i]);\n}\n\n// 2. Bucle for in\nfor (const i in numeros) {\n    console.log(numeros[i]);\n}\n\n// 3. Bucle forEach\nnumeros.forEach((numero) => {\n    console.log(numero);\n});\n\n/*\n    * DIFICULTAD EXTRA\n*/\n\n// 4. Bucle for of \nfor (const numero of numeros) {\n    console.log(numero);\n}\n\n// 5. Bucle while\nlet i = 0;\nwhile (i < numeros.length) {\n    console.log(numeros[i])\n    i++\n}\n\n// 6. Bucle do while\nlet j = 0;\ndo {\n    console.log(numeros[j]);\n    j++;\n} while (j < numeros.length)\n\n// 7. Bucle map \nnumeros.map((numero) => {\n    console.log(numero);\n})\n\n// ..."
  },
  {
    "path": "Roadmap/17 - ITERACIONES/javascript/christian-jfr.js",
    "content": "// #17 ITERACIONES\n\n/**\n * EJERCICIO:\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n * números del 1 al 10 mediante iteración.\n */\n\n// for\nfor (let i = 1; i <= 10; i++) {\n\tconsole.log(i);\n} // 1, 2, 3, 4, 5, 6, 7, 8, 9, 10\n\n// while\nlet i = 1;\nwhile (i <= 10) {\n\tconsole.log(i);\n\ti++;\n} // 1, 2, 3, 4, 5, 6, 7, 8, 9, 10\n\n// do...While\nlet j = 1;\ndo {\n\tconsole.log(j);\n\tj++;\n} while (j <= 10);\n\n/**\n * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n */\n\nconst arrayNumbers = [1, 2, 3, 4, 5];\nconst arrayStrings = ['a', 'b', 'c', 'd', 'e'];\nconst myObject = {\n\tname: 'Christian',\n\tage: 23,\n\tlanguages: ['Javascript', 'Typescript', 'Python', 'Rust'],\n};\n// for...in\nfor (let index in arrayNumbers) {\n\tconsole.log(`${index} = ${arrayNumbers[index]}`);\n} // -> 0 = 1, 1 = 2, 2 = 3, 3 = 4, 4 = 5\n\nfor (let index in arrayStrings) {\n\tconsole.log(`${index} = ${arrayStrings[index]}`);\n} // -> 0 = a, 1 = b, 2 = c, 3 = d, 4 = e\n\nfor (let key in myObject) {\n\tconsole.log(`${key}: ${myObject[key]}`);\n} // -> name: Christian, age: 23, languages: Javascript, Typescript, Python, Rust\n\n// for...of\nfor (let element of arrayNumbers) {\n\tconsole.log(element);\n} // -> 1, 2, 3, 4, 5\n\nfor (let element of arrayStrings) {\n\tconsole.log(element);\n} // -> a, b, c, d, e\n\nfor (let element of myObject.languages) {\n\tconsole.log(element);\n} // -> Javascript, Typescript, Python, Rust\n\nfor (let element of 'JavaScript') {\n\tconsole.log(element);\n} // -> J, a, v, a, s, c, r, i, p, t,\n\n// recursividad\nfunction iterateArray(array, index) {\n\tif (index >= array.length) {\n\t\treturn -1;\n\t}\n\n\tconsole.log(array[index]);\n\titerateArray(array, index + 1);\n}\n\niterateArray(arrayNumbers, 0); // -> 1, 2, 3, 4, 5\niterateArray(arrayStrings, 0); // -> a, b, c, d, e\n\n// .forEach()\narrayNumbers.forEach((element) => console.log(element));\narrayStrings.forEach((element) => console.log(element));\nmyObject.languages.forEach((element) => console.log(element));\n'JavaScript'.split('').forEach((element) => console.log(element));\n\n// .map()\narrayNumbers.map((element) => console.log(element));\narrayStrings.map((element) => console.log(element));\nmyObject.languages.map((element) => console.log(element));\n'JavaScript'.split('').map((element) => console.log(element));\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/javascript/duendeintemporal.js",
    "content": "// #17 - ITERACIONES    \n/*\n * EJERCICIO:\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n * números del 1 al 10 mediante iteración.\n *\n * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n */\n\n// short for console.log\nlet log = console.log;\n\nwindow.addEventListener('load', ()=>{\n    const body = document.querySelector('body');\n    const title = document.createElement('h1');\n    \n    body.style.setProperty('background', '#000');\n    body.style.setProperty('text-align', 'center');\n    \n    title.textContent = 'Retosparaprogramadores #17.';\n    title.style.setProperty('font-size', '3.5vmax');\n    title.style.setProperty('color', '#fff');\n    title.style.setProperty('line-height', '100vh');\n    \n    body.appendChild(title);\n    \n    setTimeout(()=>{\n    alert('Retosparaprogramadores #17. Please open the Browser Developer Tools.');\n    }, 2000);\n    log( 'Retosparaprogramadores #17'); \n});\n\nfor(let i = 1; i <= 10; i++){\n    log(i);\n}\n\nlet count = 0;\nwhile(count < 10){\n    count ++;\n    log(count);\n}\n\n// forEach method\nlet nums = [1,2,3,4,5,6,7,8,9,10];\nnums.forEach(n=>log(n));\n\n//Extra Dificulty Exercise\n\n// do while\nlet i = 0;\ndo {\n    console.log(i);\n    i++;\n} while (i < 5);\n\n//map method\nconst arr = [1, 2, 3, 4, 5];\nconst doubled = arr.map((value) => value * 2);\nlog(doubled); // [2, 4, 6, 8, 10]\n\n// filter method\nconst arr1 = [1, 2, 3, 4, 5];\nconst evenNumbers = arr1.filter((value) => value % 2 === 0);\nlog(evenNumbers); // [2, 4]\n\n// reduce method\nconst arr2 = [1, 2, 3, 4, 5];\nconst sum = arr2.reduce((total, current) => total + current, 0);\nlog(sum); // 15\n\n// some method\nconst arr3 = [1, 2, 3, 4, 5];\nconst hasEven = arr3.some((value) => value % 2 === 0);\nlog(hasEven); // true\n\n// every method\nconst arr4 = [1, 2, 3, 4, 5];\nconst allEven = arr4.every((value) => value % 2 === 0);\nlog(allEven); // false\n\n// For of...\nconst arr5 = [1, 2, 3, 4, 5];\nfor (const value of arr5) {\n    log(value); // Logs: 1 2 3 4 5\n}\n\n// Iteración con entries\nconst arr6 = ['a', 'b', 'c'];\nfor (const [index, value] of arr6.entries()) {\n    log(index, value); // 0 'a' 1 'b' 2 'c'\n}\n\nconst obj1 = { a: 1, b: 2, c: 3 };\nfor (const [key, value] of Object.entries(obj1)) {\n    log(key, value); // a 1 b 2 c 3\n}\n\n// Iteración con keys\nconst arr7 = ['a', 'b', 'c'];\nfor (const index of arr7.keys()) {\n    log(index); // 0 1 2\n}\n\nconst obj2 = { a: 1, b: 2, c: 3 };\nfor (const key of Object.keys(obj2)) {\n    log(key); // a b c\n}\n\n\n// Iteración con values\nconst arr8 = ['a', 'b', 'c'];\nfor (const value of arr8.values()) {\n    log(value); // a b c\n}\n\nconst obj3 = { a: 1, b: 2, c: 3 };\nfor (const value of Object.values(obj3)) {\n    log(value); // 1 2 3\n}\n\n// For in...\nconst obj = { a: 1, b: 2, c: 3 };\nfor (const key in obj) {\n    log(`${key}: ${obj[key]}`); // a: 1 b: 2 c: 3\n}\n\n\n\n\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/javascript/edalmava.js",
    "content": "// 1. Uso de la sintaxis for .. of\nconst array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\nfor (let num of array) console.log(num)\n\n// Symbol.iterator\nlet range = {\n    from: 1,\n    to: 10\n}\nrange[Symbol.iterator] = function() {\n    return {\n        current: this.from,\n        last: this.to, \n        next() {\n            if (this.current <= this.last) {\n                return { done: false, value: this.current++ }\n            } else {\n                return { done: true }\n            }\n        }\n    }\n}\nfor (let num of range) console.log(num)\n\n// Uso de Array.from\n\nlet arr = Array.from(range)\nfor (let num of arr) console.log(num)\n\n// Funciones generadoras\n\nrange = {\n  from: 1,\n  to: 10,\n\n  *[Symbol.iterator]() { \n    for (let value = this.from; value <= this.to; value++) {\n      yield value;\n    }\n  }\n};\nfor (let value of range) console.log(value)\n\n// 2. Uso de for .. in\nfor (let num in array) console.log(++num)\n\n// 3. Uso de forEach\narray.forEach(e => console.log(e))\n\n// 4. Uso de for \nfor (let i = 1; i <=10; i++) console.log(i)\n\n// 5. Uso de while\nlet i = 1\nwhile (i <= 10) {\n    console.log(i)\n    i++\n}\n\n// 6. Uso de do .. while\ni = 1\ndo {\n    console.log(i)\n    i++\n} while (i <= 10)\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/javascript/emedevelopa.js",
    "content": "/*Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\nnúmeros del 1 al 10 mediante iteración.*/\n\n//For\nfor (let i = 1; i <= 10; i++) {\n    console.log(i)\n}\n\n//While\nlet i = 1;\nwhile (i <= 10) {\n    console.log(i)\n    i++\n}\n\n//Do...while\nlet i = 1;\ndo {\n    console.log(i)\n    i++\n} while (i <= 10);\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/javascript/eugeniasoria.js",
    "content": "/*\r\n * EJERCICIO:\r\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\r\n * números del 1 al 10 mediante iteración.\r\n *\r\n * DIFICULTAD EXTRA (opcional):\r\n * Escribe el mayor número de mecanismos que posea tu lenguaje\r\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\r\n */\r\n\r\n\r\nfunction mecanismo1 () {  \r\n  console.log('\\nUsando un bucle for');\r\n  for (let i = 1; i <= 10; i++) {\r\n    console.log(i);    \r\n  }\r\n}\r\n\r\nfunction mecanismo2 () {\r\n  console.log('\\nUsando un bucle while');\r\n  let i=1\r\n  while (i<=10) {\r\n    console.log(i);\r\n    i++;\r\n  }\r\n}\r\n\r\nfunction mecanismo3 () {\r\n  console.log('\\nUsando un bucle do while');\r\n  let i=1\r\n  do {\r\n    console.log(i);\r\n    i++;    \r\n  } while (i<=10);\r\n}\r\n\r\nfunction mecanismo4(desde, hasta) {\r\n  if (hasta > 0) {\r\n    console.log(Math.abs(hasta-10) + 1);\r\n    mecanismo4(desde, hasta -1)\r\n  }\r\n  \r\n}\r\n\r\nfunction mecanismo5() {\r\n  console.log('\\nUsar foreach');\r\n  let array = []\r\n  for (let index = 1; index <= 10; index++) {\r\n    array.push(index)    \r\n  }\r\n  array.forEach((element) => console.log(element))\r\n}\r\n\r\nfunction mecanismo5() {\r\n  console.log('\\nUsar for in');\r\n  let array = []\r\n  for (let index = 1; index <= 10; index++) {\r\n    array.push(index)    \r\n  }\r\n  for (const i in array) {\r\n    console.log(i);\r\n  }\r\n}\r\n\r\nfunction mecanismo6() {\r\n  console.log('\\nbucle while(true)');\r\n  let i=1;\r\n  while(true) {\r\n    if (i<=10) {\r\n      console.log(i)\r\n      i++      \r\n    } else {\r\n      break;\r\n    }\r\n  }\r\n}\r\n\r\n\r\n\r\nmecanismo1();\r\nmecanismo2();\r\nmecanismo3();\r\nconsole.log('Usando una funcion recursiva');\r\nmecanismo4(1, 10);\r\nmecanismo5();\r\nmecanismo6();\r\n\r\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/javascript/eulogioep.js",
    "content": "/**\n * Demostración de diferentes mecanismos de iteración en JavaScript\n * \n * JavaScript, como lenguaje moderno y versátil, ofrece múltiples formas\n * de realizar iteraciones. Cada método tiene sus propias características\n * y casos de uso óptimos.\n */\n\nconsole.log(\"=== Demostración de Mecanismos de Iteración en JavaScript ===\\n\");\n\n// 1. Bucle for tradicional\nconsole.log(\"1. Usando bucle for tradicional:\");\n/*\n * El bucle for es uno de los más básicos y ampliamente utilizados.\n * Sintaxis: for (inicialización; condición; incremento)\n * Es muy similar a otros lenguajes como Java o C++\n */\nfor (let i = 1; i <= 10; i++) {\n    process.stdout.write(i + \" \");\n}\nconsole.log(\"\\n\");\n\n// 2. Bucle while\nconsole.log(\"2. Usando bucle while:\");\n/*\n * El bucle while ejecuta un bloque de código mientras\n * una condición específica sea verdadera.\n */\nlet contador = 1;\nwhile (contador <= 10) {\n    process.stdout.write(contador + \" \");\n    contador++;\n}\nconsole.log(\"\\n\");\n\n// 3. Bucle do...while\nconsole.log(\"3. Usando bucle do...while:\");\n/*\n * Similar al while, pero garantiza que el código se ejecute\n * al menos una vez, ya que la condición se evalúa al final.\n */\nlet num = 1;\ndo {\n    process.stdout.write(num + \" \");\n    num++;\n} while (num <= 10);\nconsole.log(\"\\n\");\n\n// 4. forEach con array\nconsole.log(\"4. Usando forEach con array:\");\n/*\n * El método forEach es una forma más funcional de iterar\n * sobre elementos de un array.\n */\nconst numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\nnumeros.forEach(numero => process.stdout.write(numero + \" \"));\nconsole.log(\"\\n\");\n\n// 5. for...of loop\nconsole.log(\"5. Usando for...of:\");\n/*\n * Introducido en ES6, for...of proporciona una forma más concisa\n * de iterar sobre elementos iterables (arrays, strings, etc.)\n */\nfor (const numero of numeros) {\n    process.stdout.write(numero + \" \");\n}\nconsole.log(\"\\n\");\n\n// 6. Array.from con mapeo\nconsole.log(\"6. Usando Array.from con mapeo:\");\n/*\n * Array.from puede crear un array a partir de un objeto iterable\n * y permite mapear valores durante la creación\n */\nArray.from({length: 10}, (_, i) => i + 1)\n    .forEach(num => process.stdout.write(num + \" \"));\nconsole.log(\"\\n\");\n\n// 7. Recursión\nconsole.log(\"7. Usando recursión:\");\n/*\n * Aunque técnicamente no es un loop, la recursión es otra forma\n * de realizar iteraciones mediante una función que se llama a sí misma\n */\nfunction contarHasta10(n = 1) {\n    process.stdout.write(n + \" \");\n    if (n < 10) contarHasta10(n + 1);\n}\ncontarHasta10();\nconsole.log(\"\\n\");\n\n// 8. Map\nconsole.log(\"8. Usando Map:\");\n/*\n * Similar a forEach, pero crea un nuevo array con los resultados\n * de llamar a una función para cada elemento\n */\nconsole.log(Array(10).fill().map((_, index) => index + 1).join(\" \"));\n\n// 9. Generator function\nconsole.log(\"9. Usando Generator function:\");\n/*\n * Las funciones generadoras permiten definir un algoritmo iterativo\n * escribiendo una función que puede mantener su propio estado\n */\nfunction* generarNumeros() {\n    for (let i = 1; i <= 10; i++) {\n        yield i;\n    }\n}\n\nfor (const num of generarNumeros()) {\n    process.stdout.write(num + \" \");\n}\nconsole.log(\"\\n\");\n\n// 10. Reduce\nconsole.log(\"10. Usando Reduce (aunque no es su uso típico):\");\n/*\n * Reduce normalmente se usa para acumular valores, pero también\n * puede usarse para iterar realizando una acción en cada paso\n */\nArray(10).fill().reduce((_, __, i) => {\n    process.stdout.write((i + 1) + \" \");\n    return null;\n}, null);\nconsole.log(\"\\n\");\n\nconsole.log(\"\\n=== Fin de la demostración ===\");"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/javascript/garos01.js",
    "content": "// Método 1: Bucle for\nconsole.log(\"Método 1: Bucle for\");\nfor (let i = 1; i <= 10; i++) {\n  console.log(i);\n}\n\n// Método 2: Bucle while\nconsole.log(\"Método 2: Bucle while\");\nlet j = 1;\nwhile (j <= 10) {\n  console.log(j);\n  j++;\n}\n\n// Método 3: Bucle do-while\nconsole.log(\"Método 3: Bucle do-while\");\nlet k = 1;\ndo {\n  console.log(k);\n  k++;\n} while (k <= 10);\n\n// Ejercicio extra\n\n// Método 1: Bucle for clásico\nconsole.log(\"Método 1: Bucle for clásico\");\nfor (let i = 1; i <= 10; i++) {\n  console.log(i);\n}\n\n// Método 2: Bucle while\nconsole.log(\"Método 2: Bucle while\");\nlet l = 1;\nwhile (l <= 10) {\n  console.log(l);\n  l++;\n}\n\n// Método 3: Bucle do-while\nconsole.log(\"Método 3: Bucle do-while\");\nlet m = 1;\ndo {\n  console.log(m);\n  m++;\n} while (m <= 10);\n\n// Método 4: forEach() en arrays\nconsole.log(\"Método 4: forEach()\");\nconst array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\narray.forEach((item) => console.log(item));\n\n// Método 5: map() en arrays\nconsole.log(\"Método 5: map()\");\nconst newArray = array.map((item) => item);\nconsole.log(newArray);\n\n// Método 6: filter() en arrays\nconsole.log(\"Método 6: filter()\");\nconst filteredArray = array.filter((item) => item <= 10);\nconsole.log(filteredArray);\n\n// Método 7: reduce() en arrays\nconsole.log(\"Método 7: reduce()\");\nconst sum = array.reduce(\n  (accumulator, currentValue) => accumulator + currentValue\n);\nconsole.log(sum);\n\n// Método 8: for...of en iterables\nconsole.log(\"Método 8: for...of\");\nfor (const item of array) {\n  console.log(item);\n}\n\n// Método 9: for...in en objetos\nconsole.log(\"Método 9: for...in\");\nconst obj = { a: 1, b: 2, c: 3 };\nfor (const key in obj) {\n  console.log(obj[key]);\n}\n\n// Método 10: for await...of en iterables asíncronos (ejemplo simplificado)\nconsole.log(\"Método 10: for await...of (ejemplo simplificado)\");\nconst asyncIterable = {\n  [Symbol.asyncIterator]() {\n    return {\n      i: 0,\n      async next() {\n        if (this.i < 10) {\n          await new Promise((resolve) => setTimeout(resolve, 1000));\n          return { value: ++this.i, done: false };\n        } else {\n          return { done: true };\n        }\n      },\n    };\n  },\n};\n\n(async () => {\n  for await (const item of asyncIterable) {\n    console.log(item);\n  }\n})();\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/javascript/giovanyosorio.js",
    "content": "/* EJERCICIO:\n* Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n* números del 1 al 10 mediante iteración.\n*\n* DIFICULTAD EXTRA (opcional):\n* Escribe el mayor número de mecanismos que posea tu lenguaje\n* para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n*/\n\n// 1 ejemplo\n\nfunction iteration1(num){\n    let mynumber=num\n\n    for(let i=0;i<mynumber;i++){\n        console.log(i)\n    }\n}\n\niteration1(10)\n\n\n// 2 ejemplo (using for of)\nfunction iteration2(num){\n    for (const key of num) {\n        console.log(key)\n    }\n}\n\niteration2([1,2,3,4,5,6,7,8,10])\n\n// 3 ejemplo (using for each)\nfunction iteration3(num){\nnum.forEach(element => {\n    console.log(element)\n});\n}\n\niteration3([1,2,3,4,5,6,7,8,10])\n\n// 4 ejemplo (using map)\nfunction iteration4(num){\n\n    let mapeo=num.map((item)=>item)\n    console.log(mapeo)\n    \n    }\n        \n    iteration4([1,2,3,4,5,6,7,8,10])\n    \n    // 5 bucle (using do while)\n    function iteration5(num){\n        do {\n          console.log(num)\n            num++\n    \n        } while (num<=10);\n            \n        }\n                \n    iteration5(1)\n\n\n        // 6 bucle (using while)\n        function iteration6(num){\n            while (num<=10) {\n                console.log(num)\n                num++\n            }\n                \n        }\n                    \n        iteration6(1)\n    \n    // 7 ejemplo (using filter)\n    function iteration7 (num){\n        let filtrado=num.filter((item)=>item)\n        console.log(filtrado)\n      }\n      iteration7([1,2,3,4,5,6,7,8,9,10])\n\n      // 8 ejemplo (using for in)\n      function iteration8 (num){\n      \n        for(let item in num){\n          console.log(parseInt(item))\n        }\n        }\n        iteration8([1,2,3,4,5,6,7,8,9,10])"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/javascript/hectorio23.js",
    "content": "// Author: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\n\"use strict\";\n\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n * números del 1 al 10 mediante iteración.\n *\n * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n */\n\n// Mecanismo 1: Bucle for\nconsole.log(\"[ Mecanismo 1 ] -> Bucle for\");\nfor (let i = 1; i <= 10; i++) {\n    process.stdout.write(i + \", \");\n}\nconsole.log(\"\\n\");\n\n// Mecanismo 2: forEach()\nconsole.log(\"[ Mecanismo 2 ] -> forEach()\");\nconst array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\narray.forEach(function(element) {\n    process.stdout.write(element + \", \");\n});\nconsole.log(\"\\n\");\n\n// Mecanismo 3: for...of\nconsole.log(\"[ Mecanismo 3 ] -> for...of\");\nfor (const element of array) {\n    process.stdout.write(element + \", \");\n}\nconsole.log(\"\\n\");\n\n// Mecanismo 4: for...in (no recomendado para arrays)\nconsole.log(\"[ Mecanismo 4 ] -> for...in\");\nfor (const index in array) {\n    process.stdout.write(array[index] + \", \");\n}\nconsole.log(\"\\n\");\n\n// Mecanismo 5: while\nconsole.log(\"[ Mecanismo 5 ] -> while\");\nlet i = 0;\nwhile (i < array.length) {\n    process.stdout.write(array[i] + \", \");\n    i++;\n}\nconsole.log(\"\\n\");\n\n// Mecanismo 6: do...while\nconsole.log(\"[ Mecanismo 6 ] -> do...while\");\nlet j = 0;\ndo {\n    process.stdout.write(array[j] + \", \");\n    j++;\n} while (j < array.length);\nconsole.log(\"\\n\");\n\n// Mecanismo 7: recursividad\nconsole.log(\"[ Mecanismo 7 ] -> recursividad\");\nconst recursive = (value) => {\n    process.stdout.write(value + \", \");\n    if (value === 1) return 1;\n    return value * recursive(value -1)\n\n}\nrecursive(10);\nconsole.log(\"\\n\");\n\n// Mecanismo 8: Array.from() (para convertir otros objetos en arrays)\nconsole.log(\"[ Mecanismo 8 ] -> Array.from()\");\nconst arrayFromSet = Array.from(new Set(array));\narrayFromSet.forEach(function(element) {\n    process.stdout.write(element + \", \");\n});\nconsole.log(\"\\n\");\n\n// Mecanismo 9: Array.prototype.entries() (para obtener pares clave-valor de un objeto)\nconsole.log(\"[ Mecanismo 9 ] -> Array.prototype.entries()\");\nconst entries = array.entries();\nfor (const [index, value] of entries) {\n    process.stdout.write(value + \", \");\n}\nconsole.log(\"\\n\");\n\n// Mecanismo 10: Array.prototype.keys() (para obtener las claves de un objeto)\nconsole.log(\"[ Mecanismo 10 ] -> Array.prototype.keys()\");\nconst keys = array.keys();\nfor (const index of keys) {\n    process.stdout.write(array[index] + \", \");\n}\nconsole.log(\"\\n\");\n\n// Mecanismo 11: for...await...of (para iterar sobre async iterables)\nconsole.log(\"[ Mecanismo 11 ] -> for...await...of\");\nasync function asyncFunction() {\n    for await (const element of array) {\n        process.stdout.write(element + \", \");\n    }\n    console.log(\"\\n\");\n}\nasyncFunction();"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n_______________________________________\n#17 ITERACIONES\n---------------------------------------\n * EJERCICIO:\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n * números del 1 al 10 mediante iteración.\n *\n * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n*/\n// ________________________________________________________\n\nconsole.log(\"bucle 'for'\")\nfor (let i = 1; i <= 10; i++) {\n    console.log(i);\n}\n\nconsole.log(\"\\nbucle 'while'\")\nlet i = 1;\nwhile (i <= 10) {\n    console.log(i);\n    i++;\n}\n\nconsole.log(\"\\nbucle 'do...while'\")\nlet n = 1;\ndo {\n    console.log(n);\n    n++;\n} while (n <= 10);\n\n// ________________________________________________________\n// DIFICULTAD EXTRA\n\nconsole.log(\"\\nfor...of con Array.from()\")\nfor (const num of Array.from({ length: 5 }, (_, i) => i + 1)) {\n    console.log(num);\n}\n\nconsole.log(\"\\nArray.from() con .forEach()\")\nArray.from({ length: 5 }, (_, i) => i + 1).forEach(num => console.log(num));\n\nconsole.log(\"\\nUsando 'map()'\")\nArray.from({ length: 5 }, (_, i) => i + 1).map(num => console.log(num));\n\nconsole.log(\"\\nUsando 'reduce'\")\nArray.from({ length: 5 }, (_, i) => i + 1).reduce((_, num) => {\n    console.log(num);\n    return num;\n}, 0);\n\nconsole.log(\"\\nUsando 'every'\")\nconst result = [1, 2, 3, 4].every(num => {\n    console.log(num);\n    return num < 4;\n});\n\nconsole.log(\"\\nUsando 'some'\")\nconst result2  = [1, 2, 3, 4].some(num => {\n    console.log(num);\n    return num === 3;\n});\n\nconsole.log(\"\\nUsando 'for...in'\")\nconst numbers = [1, 2, 3 , 4, 5]\nfor (const n in numbers) {\n    console.log(n);\n}\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/javascript/manjaitan.js",
    "content": "// imprime nº del 1 al 10 con bucle for.\n\nfor (let index = 1; index < 11; index++) {\n    console.log (index);\n}\n\n// imprime nº del 1 al 10 con bucle while.\n\nlet index = 0;\n\nwhile (index <= 9) {\n    index += 1\n    console.log (index);\n}\n\n\n// imprime nº del 1 al 10 con bucle do\n\nlet index = 1;\n\ndo {\n    console.log (index);\n    index += 1;\n} while (index <= 10);\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/javascript/monicavaquerano.js",
    "content": "// 17 ITERACIONES\n// Monica Vaquerano\n// https://monicavaquerano.dev\n\n\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n * números del 1 al 10 mediante iteración.\n *\n * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n */\n\nconsole.log(\"For Loop\");\nfor (let i = 1; i < 11; i++) {\n    console.log(i);\n};\n\nconsole.log(\"\\nWhile Loop\");\nlet x = 1;\nwhile (x < 11) {\n    console.log(x);\n    x++;\n};\nconsole.log(\"\\nDo-While Loop\");\nlet y = 1\ndo {\n    console.log(y);\n    y++;\n} while (y < 11);"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/javascript/n-skot.js",
    "content": "const numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\nlet cont = 0;\n\n// 17 ITERACIONES - imprimir números del 1 al 10\n// #1\n\nwhile (cont < numeros.length) {\n  console.log(numeros[cont])\n  cont += 1;\n}\n\n// #2\ncont = 0;\ndo {\n  console.log(numeros[cont]);\n  cont += 1;\n} while (cont < numeros.length)\n\n// #3\nfor (let i = 0; i < numeros.length; i++) {\n  console.log(numeros[i])\n}\n\n// [Extra]\n//\nconsole.log('Extra')\n// #1\ncont = 0;\nwhile (cont < numeros.length) {\n  console.log(numeros[cont])\n  cont += 1;\n}\n\n// #2\n\ncont = 0;\ndo {\n  console.log(numeros[cont]);\n  cont += 1;\n} while (cont < numeros.length)\n\n// #3\n\nfor (let i = 0; i < numeros.length; i++) {\n  console.log(numeros[i])\n}\n\n// #4\n\nfor (const numero of numeros) {\n  console.log(numero);\n}\n\n// #5\n\nnumeros.forEach((numero) => console.log(numero));\n\n// #6\nfor (const contIn in numeros) {\n  console.log(numeros[contIn]);\n}\n\n// #7\nnumeros.map((numero) => console.log(numero));\n\n// #8\nnumeros.filter((numero) => console.log(numero))\n\n// #9\nnumeros.flatMap((numero) => console.log(numero))\n\n// #10\nArray.from(numeros, (numero) => console.log(numero));\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/javascript/nlarrea.js",
    "content": "/*\n * EJERCICIO:\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n * números del 1 al 10 mediante iteración.\n *\n * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n */\n\n// OPTION 1\n\nconsole.log(\"\\nOPTION 1: for loop\");\n\nfor (let num = 1; num <= 10; num++) {\n    console.log(num);\n}\n\n\n// OPTION 2\n\nconsole.log(\"\\nOPTION 2: while loop\");\n\nlet num = 1;\nwhile (num <= 10) {\n    console.log(num);\n    num++;\n}\n\n\n// OPTION 3\n\nconsole.log(\"\\nOPTION 3: recursive function call\");\n\n\n/**\n * Prints the numbers in the given range.\n * @param {Number} start The number where the counter starts to count (included).\n * @param {Number} stop The number where the counter stops (included).\n */\nfunction counter(start, stop) {\n    console.log(start);\n\n    if (start >= stop) {\n        return stop;\n    }\n\n    counter(start + 1, stop);\n}\n\n\ncounter(1, 10);\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/javascript/parababire.js",
    "content": "// 1. For loop\n\nfor (let i = 1; i <= 10; i++) {\n  console.log(i);\n}\n\n// 2. Do While loop\n\nlet num = 1;\ndo {\n  console.log(num);\n  num++;\n} while (num <= 10);\n\n// 3. For of\n\nlet numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n\nfor (const num of numbers) {\n  console.log(num);\n}\n\n// Extra\n\n// 4. While\n\nlet i = 1;\n\nwhile (i <= 10) {\n  console.log(i);\n  i++;\n}\n\n// 5. For in\n\nfor (const num in numbers) {\n  console.log(numbers[num]);\n}\n\n// 6. For each\n\nfunction impresora(item) {\n  console.log(item);\n}\n\nnumbers.forEach(element => {\n  impresora(element);\n});\n\n// 7. Map\n\nnumbers.map(impresora);\n\n// 8. Flatmap\n\nnumbers.flatMap(impresora);\n\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/javascript/pedamoci.js",
    "content": "for (let i = 1; i <= 10; i++) {\n  console.log(`Iteracion de for número ${i}`);\n}\n\nlet i = 1\nwhile (i <= 10) {\n  console.log(`Iteracion de while número ${i}`);\n  i++\n}\n\ni = 1\ndo {\n  console.log(`Iteracion de do while número ${i}`);\n  i++\n} while (i <= 10)\n\n// ------------------------------------- DIFICULTAD EXTRA -------------------------------------\n  // constantes, variables, funciones necesarias\nconst obj = {1: 1,2: 2,3: 3,4: 4,5: 5,6: 6,7: 7,8: 8,9: 9,10: 10}\nconst arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\nconst initialValue = 0\nconst isBelowThreshold = (x) => x < 11\nasync function* foo() {\n  yield 1;\n  yield 2;\n  yield 3;\n  yield 4;\n  yield 5;\n  yield 6;\n  yield 7;\n  yield 8;\n  yield 9;\n  yield 10;\n}\n\n// ITERACIONES (empiezo desde 4 ya que arriba hay 3 del ejercicio anterior \"for\", \"while\", \"do while\")\n  // #4 (for in)\n  for (const key in obj) {\n    console.log(`Iteracion de for in número ${obj[key]}`)\n  }\n\n  // #5 (for of)\n  for (const i of arr) {\n    console.log(`Iteracion de for of número ${i}`)\n  }\n\n  //#6 (forEach)\n  arr.forEach(element => {console.log(`Iteracion de forEach número ${element}`)});\n\n  //#7 (for await of)\n  (async () => {\n    for await (const num of foo()) {\n      console.log(`Iteracion de for await of número ${num}`);\n    }\n  })();\n\n  //#8 (map)\n  const mapped = arr.map((x) => console.log(`Iteracion de map número ${x}`))\n\n  //#9 (filter)\n  const filtered = arr.filter((x) => console.log(`Iteracion de filter número ${x}`))\n\n  //#10 (reduce)\n  const reduced = arr.reduce((accumulator, currentValue) => console.log(`Iteracion de reduce número ${currentValue}`),initialValue)\n\n  //#11 (reduceRight)\n  const reducedRight = arr.reduceRight((accumulator, currentValue) => console.log(`Iteracion de reduceRight número ${11 - currentValue}`),initialValue)\n\n  //#12 (every)\n  arr.every(num => {\n    console.log(`Iteracion de every número ${num}`)\n    return true\n  })\n\n  //#13 (some)\n  const some = arr.some((x) => console.log(`Iteracion de some número ${x}`))\n\n  //#14 (find)\n  const find = arr.find((x) => console.log(`Iteracion de find número ${x}`))\n\n  //#15 (findIndex)\n  const findIndex = arr.findIndex((x) => console.log(`Iteracion de findIndex número ${x}`))\n\n  //#16 (findLast)\n  const findLast = arr.findLast((x) => console.log(`Iteracion de findLast número ${11 - x}`))\n\n  //#17 (findLastIndex)\n  const findLastIndex = arr.findLastIndex((x) => console.log(`Iteracion de findLastIndex número ${11 - x}`))\n\n  //#18 (flatMap)\n  const flatMap = arr.flatMap((x) => console.log(`Iteracion de flatMap número ${x}`))\n\n  //#19 (entries)\n  console.log([...arr.entries()])\n\n  //#20 (keys)\n  console.log([...arr.keys()])\n\n  //#21 (values)\n  console.log([...arr.values()])\n\n  //#22 ([Symbol.iterator])\n  console.log([...arr[Symbol.iterator]()])\n\n  //#23 ('...' spread operator)\n  console.log([...arr])\n\n  //#24 (from)\n  Array.from(arr, (x) => console.log(`Iteracion de from número ${x}`))"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/javascript/victor-Casta.js",
    "content": "/*\n  * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n  * números del 1 al 10 mediante iteración.\n*/\n\n// For\nconsole.log('For')\nfor (let i = 1; i <= 10; i++) {\n  console.log(i)\n}\n\n// While\nconsole.log('While')\nlet i = 1\nwhile (i <= 10) {\n  console.log(i)\n  i++;\n}\n\n// Do while\nconsole.log('Do While');\nlet j = 1\ndo {\n  console.log(j)\n  j++\n} while(j <= 10)\n\n/*\n  * DIFICULTAD EXTRA (opcional):\n  * Escribe el mayor número de mecanismos que posea tu lenguaje\n  * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n*/\n\n// for in\n\nconst list = [1,2,3,4,5]\n\nfor(item in list) {\n  console.log(item)\n}\n\n// for of\n\nfor(item of list) {\n  console.log(item)\n}"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/javascript/wapastor.js",
    "content": "/*\n * EJERCICIO:\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n * números del 1 al 10 mediante iteración.\n *\n * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n */\n\n// Mecanismo 1: for\nconsole.log('Mecanismo 1: for');\nfor (var i = 1; i <= 10; i++) {\n    console.log(i);\n}\n\n// Mecanismo 2: while\nvar i = 1;\nconsole.log('Mecanismo 2: while');\nwhile (i <= 10) {\n    console.log(i);\n    i++;\n}\n\n// Mecanismo 3: do-while\nvar i = 1;\nconsole.log('Mecanismo 3: do-while');\ndo {\n    console.log(i);\n    i++;\n} while (i <= 10);\n\n// Mecanismo 4: forEach\nconsole.log('Mecanismo 4: forEach');\n[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].forEach(function (i) {\n    console.log(i);\n});\n\n// Mecanismo 5: for...in\nconsole.log('Mecanismo 5: for...in');\nconst numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\nfor (var indice in numbers) {\n    console.log(numbers[indice]);\n}\n// Mecanismo 6: for...of\nconsole.log('Mecanismo 6: for...of');\nfor (var number of numbers) {\n    console.log(number);\n}\n\n\n// Mecanismo 7: map\nconsole.log('Mecanismo 7: map');\nnumbers.map(function (i) {\n    console.log(i);\n});\n\n// Mecanismo 8: reduce\nconsole.log('Mecanismo 8: reduce');\nnumbers.reduce((acc,number) => {\n    console.log(number);\n    return acc;\n},0);\n\n// mecanismo 9: array.from\nconsole.log('Mecanismo 9: array.from');\nArray.from({ length: 10 }, (_, i) => i + 1).forEach(number => {\n    console.log(number);\n});\n\n// Mecanismo 10: array.prototype.keys\nconsole.log('Mecanismo 10: array.prototype.keys');\n[...Array(10).keys()].forEach(number => {\n    console.log(number + 1);\n});\n\n\n\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/kotlin/blackriper.kt",
    "content": "/*\r\nInteraciones\r\nEs una forma  para poder recorrer una lista de elementos de una coleccion\r\n*/\r\n\r\nfun exampleWithIterators(){\r\n  val list = listOf(1,2,3,4,5,6,7,8,9,10)\r\n\r\n  // foreach\r\n  println(\"using foreach\")\r\n  list.forEach { println(it) }\r\n\r\n  // for convencional\r\n  println(\"using for\")\r\n  for (i in list){\r\n      println(i)\r\n  }\r\n\r\n  // while\r\n  println(\"using while\")\r\n  var i = 0\r\n  while (i < list.size){\r\n      println(list[i])\r\n      i++\r\n  }\r\n\r\n}\r\n\r\nfun exampleWithOthersIterators(){\r\n val list = listOf(1,2,3,4,5,6,7,8,9,10)\r\n\r\n    // utilizando el iterator\r\n    println(\"using iterator\")\r\n    for (item in list.iterator()){\r\n        println(item)\r\n    }\r\n\r\n    // utilizando el listIterator\r\n    println(\"using listIterator\")\r\n    val listIterator= list.listIterator()\r\n    while (listIterator.hasNext()){\r\n        println(listIterator.next())\r\n    }\r\n\r\n    // usando do while\r\n    println(\"using do while\")\r\n    var i = 0\r\n    do {\r\n        println(list[i])\r\n        i++\r\n    }while (i < list.size)\r\n\r\n    // usando el map por lo general es para hacer algun cambio sobre la lista sin mutar el array original\r\n    println(\"using map\")\r\n    list.map { println(it) }\r\n\r\n    // for con rango\r\n    println(\"using for with range\")\r\n    for (num in 1..10){\r\n        println(num)\r\n    }\r\n\r\n\r\n}\r\n\r\n\r\nfun main() {\r\n    exampleWithIterators()\r\n    exampleWithOthersIterators()\r\n}\r\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/kotlin/eulogioep.kt",
    "content": "fun main() {\n    println(\"Diferentes mecanismos de iteración en Kotlin:\")\n\n    // 1. Usando un bucle for con un rango\n    println(\"\\n1. Usando for con rango:\")\n    for (i in 1..10) {\n        print(\"$i \")\n    }\n    println()\n\n    // 2. Usando un bucle while\n    println(\"\\n2. Usando while:\")\n    var j = 1\n    while (j <= 10) {\n        print(\"$j \")\n        j++\n    }\n    println()\n\n    // 3. Usando forEach con una lista\n    println(\"\\n3. Usando forEach con lista:\")\n    (1..10).toList().forEach { print(\"$it \") }\n    println()\n\n    // 4. Usando repeat\n    println(\"\\n4. Usando repeat:\")\n    repeat(10) { print(\"${it + 1} \") }\n    println()\n\n    // 5. Usando do-while\n    println(\"\\n5. Usando do-while:\")\n    var k = 1\n    do {\n        print(\"$k \")\n        k++\n    } while (k <= 10)\n    println()\n\n    // 6. Usando un iterador\n    println(\"\\n6. Usando un iterador:\")\n    val iterator = (1..10).iterator()\n    while (iterator.hasNext()) {\n        print(\"${iterator.next()} \")\n    }\n    println()\n\n    // 7. Usando secuencias\n    println(\"\\n7. Usando secuencias:\")\n    (1..10).asSequence().forEach { print(\"$it \") }\n    println()\n\n    // 8. Usando un bucle for con índices\n    println(\"\\n8. Usando for con índices:\")\n    for (index in 0 until 10) {\n        print(\"${index + 1} \")\n    }\n    println()\n\n    // 9. Usando takeWhile\n    println(\"\\n9. Usando takeWhile:\")\n    generateSequence(1) { it + 1 }\n        .takeWhile { it <= 10 }\n        .forEach { print(\"$it \") }\n    println()\n\n    // 10. Usando fold\n    println(\"\\n10. Usando fold:\")\n    (1..10).fold(\"\") { acc, i -> \"$acc$i \" }.also { print(it) }\n    println()\n}"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/kotlin/gonzalinuz18.kt",
    "content": "/*\n * EJERCICIO:\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n * números del 1 al 10 mediante iteración.\n *\n * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n */\n// solucion con kotlin\n\nfun main(){\n    //firstWay(9)\n    //secondWay(3)\n    //thirtWay(6)\n    //fourtWay(5)\n    //fiftWay(3)\n    //sixtWay(4)\n\n\n}\n\nfun firstWay(x:Int = 0):Int{\n    var long = x\n    var num = -1\n\n    while (num < long){\n        num++\n        println(num)\n\n    }\n    return 0\n}\n\nfun secondWay(i:Int = 0):Int{\n    for( i in 0..i){\n        println(i)\n    }\n\n    return 0\n}\n\nfun thirtWay(z:Int = 0):Int {\n    var lista1:ArrayList<Int> = arrayListOf()\n\n    for (i in 0..z){\n        lista1.add(i)\n    }\n\n    for (lista1 in lista1){\n        println(lista1)\n    }\n    return 0\n}\n\nfun  fourtWay(a:Int = 0):Int{\n\n    val list2:MutableList<Int> = mutableListOf()\n    for(i in 0..a){\n        list2.add(i)\n    }\n\n    list2.forEach{it -> println(it) }\n\n    return 0\n}\n\nfun  fiftWay(w:Int = 0):Int{\n\n    val list3:MutableList<Int> = mutableListOf()\n    for(i in 0..w){\n        list3.add(i)\n    }\n\n    list3.forEachIndexed { index, i -> println(\"${list3[i]}\") }\n\n    return 0\n}\n\nfun sixtWay(l:Int = 0):Int{\n    val list4:MutableList<Int> = mutableListOf()\n    for(i in 0..l){\n        list4.add(i)\n    }\n    val it:ListIterator<Int> = list4.listIterator()\n\n    while (it.hasNext()){\n        var e:Int = it.next()\n        println(\"$e\")\n    }\n    return 0\n}\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/nasm/evanz2608.s",
    "content": "; https://nasm.us\n\n; ===================================================\n; 17 - ITERACIONES\n; ===================================================\n;\n; Existe en ensamblador, una forma de iteración que usa el registro RCX como contador\n; y es la instrucción LOOP. La particularidad de este tipo de iteraciónes es que va en\n; forma decreciente, donde se guarda en RCX el número de iteraciones que uno desea, y cada vez\n; que se ejecuta la instrucción LOOP, se decrementa RCX y se comprueba si no es 0.\n; En caso que no sea 0, LOOP salta a la etiqueta para ejecutar una vez mas el loop.\n; Si RCX ES 0, loop no salta y la ejecución sigue.\n\n\nSTDIN: equ 0\nSTDOUT: equ 1\nSTDERR: equ 2\n\nSYS_exit: equ 60\n\n\nextern printf\nglobal _start\nsection .text\n_start:\n; Iteraciones con LOOP\n\n  sub rsp, 8    ; Alineamos el stack, para que luego del push podamos hacer el call a printf\n  mov rcx, 10\nloop_tag:\n  push rcx      ; Cada vez que hacemos un call, rcx cambia su valor, por lo que debemos guardar en el stack.\n  lea rdi, [number_mask]\n  mov rsi, rcx\n  call printf\n  pop rcx       ; Y restauramos RCX a su valor antes del call\n  loop loop_tag\n\n  add rsp, 8\n  lea rdi, [new_line]\n  call printf\n\n; Y ahora vamos a hacer una iteración con saltos condicionales.\n  sub rsp, 8\n  mov rcx, 1\njump_tag:\n  push rcx\n  lea rdi, [number_mask]\n  mov rsi, rcx\n  call printf\n  pop rcx\n  inc rcx\n  cmp rcx, 10\n  jle jump_tag\n\n  add rsp, 8\n  lea rdi, [new_line]\n  call printf\n\n; y estas son las únicas 2 formas de hacer iteraciones.\n\n_exit:\n  mov rax, SYS_exit\n  xor rdi, rdi\n  syscall\n\nsection .rodata\n  number_mask: db \"%d \", 0x00\n  new_line: db 0x0A, 0x00\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/ocaml/luishendrix92.ml",
    "content": "open Moure.Io\n\n(*****************************************************************************)\n(*                                                                           *)\n(*                                 Iteration                                 *)\n(*                                                                           *)\n(*  OCaml offers many ways to iterate through a condition or over a defined  *)\n(*  sequence of values (finite or lazily infinite) such a [List], [Array],   *)\n(*  or [Seq] ([Sequence] in {b Jane Street's [Core]}).                       *)\n(*                                                                           *)\n(*  1. Recursion: as a functional language, the most idiomatic way of doing  *)\n(*     iteration through a recursive function (preferably TC optimized).     *)\n(*  2. Lazy Sequences: [Seq] offers a way to declaratively define finite or  *)\n(*     infinite sequences of values that are only evaluated on-demand.       *)\n(*  3. Lists and Arrays: Iterating over linked lists is possible through     *)\n(*     recursive functions that make use of their head and tail. Whereas     *)\n(*     iterating over arrays can be done through Stdlib functions or loops   *)\n(*     (imperative) while accessing their values by index.                   *)\n(*  4. Imperative Loops: OCaml offers [while] and [for] just like any other  *)\n(*     language; it's very useful for running imperative code (IO).          *)\n(*                                                                           *)\n(*  Other functional languages (and Python) offere something called {e list  *)\n(*  comprehensions} which transforms a list or sequence into a new one.      *)\n(*  Sadly, OCaml doesn't offer list comprehensions but it can be achieved    *)\n(*  with [Seq] and its many transformative functions.                        *)\n(*                                                                           *)\n(*****************************************************************************)\n\nlet recursive_tco a b =\n  let rec aux i =\n    if i <= b\n    then begin\n      print_int_endl i;\n      aux (i + 1)\n    end\n  in\n  print_endline \"Iteration with TCO recursion:\";\n  aux a\n;;\n\nlet lazy_seq_iter a b =\n  print_endline \"Iteration with infinite lazy sequences:\";\n  Seq.(ints a |> take_while (fun n -> n <= b) |> iter print_int_endl)\n;;\n\nlet list_iter a b =\n  let rec aux = function\n    | hd :: tl ->\n      print_int_endl hd;\n      aux tl\n    | [] -> ()\n  in\n  print_endline \"1-10 Count with list iteration (TCO):\";\n  (* Alternative: [List.iter print_int_endl my_range]. *)\n  aux @@ Core.List.range ~stop:`inclusive a b\n;;\n\nlet array_iter a b =\n  let range = Core.List.range ~stop:`inclusive a b |> Array.of_list in\n  let i = ref 0 in\n  print_endline \"1-10 Count with array iteration:\";\n  (* Alternative 1: [Array.iter print_int_endl range].\n     Alternative 2: Get the length of the array and use [for] instead:\n\n     {[\n       for i = 0 to Array.length range - 1 do\n         print_int_endl range.(i)\n       done\n     ]}\n  *)\n  try\n    while true do\n      print_int_endl range.(!i);\n      incr i\n    done\n  with\n  | Invalid_argument _ -> ()\n;;\n\nlet for_loop_iter a b =\n  print_endline \"Iteration with a bound for-loop:\";\n  for i = a to b do\n    print_int_endl i\n  done\n;;\n\n(** [dispenser] is a funny function that I thought of after remembering\n    ES6 Javascript generators, which return values by requesting them with\n    the [.next()] method and the [yield] keyword.\n\n    While OCaml doesn't offer something directly similar, it can be achieved\n    with mutable lazy sequences or lists, or a mutable data structure.\n    [dispenser n] returns a runnable function that returns [n+1] every time\n    it's called (starting with [n] itself). *)\nlet dispenser n =\n  let i : int ref = ref (n - 1) in\n  let dispense () =\n    incr i;\n    !i\n  in\n  dispense\n;;\n\n(* In recent versions of Ocaml that provide OOP syntax for classes, we can\n   achieve the same effect with an object or a class:\n\n   {[\n     class countup (start : int) =\n       object (self)\n         val mutable i = start - 1\n         method private inc = i <- i + 1\n\n         method next =\n           self#inc;\n           i\n       end\n     ;;\n\n     let counter = new countup 1 in\n     for i = 0 to 9 do\n       print_int_endl counter#next\n     done\n   ]}\n*)\n\nlet _ =\n  recursive_tco 1 10;\n  print_newline ();\n  lazy_seq_iter 1 10;\n  print_newline ();\n  list_iter 1 10;\n  print_newline ();\n  array_iter 1 10;\n  print_newline ();\n  for_loop_iter 1 10;\n  print_newline ();\n  let dispense = dispenser 1 in\n  print_endline \"1-10 Count with a closure function:\";\n  for i = 0 to 9 do\n    print_int_endl @@ dispense ()\n  done\n;;\n\n(* Total: 6 Ways of Iterating from 1 to 10. Could be more, but there is no\n   point anyway. I already covered the most important ones. *)\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/pascal/edalmava.pas",
    "content": "program Iteraciones;\nuses Crt;\nvar\n    i: Integer;\n\nprocedure imprimirNumeros(num : Integer);\nbegin\n    if num <= 10 then\n    begin\n        WriteLn(num);\n        imprimirNumeros(num + 1);\n    end;\nend;\n\nbegin\n    ClrScr;\n    // Usando un ciclo for\n    WriteLn('Usando un ciclo for: ');\n    for i := 1 to 10 do\n        WriteLn(i);\n    WriteLn('');\n\n    // Usando un ciclo while\n    WriteLn('Usando un ciclo while: ');\n    i := 1;\n    while i <= 10 do\n    begin\n        WriteLn(i);\n        i := i + 1;\n    end;\n    WriteLn('');\n\n    // Usando un ciclo repeat\n    WriteLn('Usando un ciclo repeat: ');\n    i := 1;\n    repeat\n        WriteLn(i);\n        i := i + 1;\n    until i > 10;\n    WriteLn('');\n\n    // Usando Recursividad\n    WriteLn('Usando Recursividad: ');\n    imprimirNumeros(1);\n    WriteLn('');\n\n    ReadLn;\nend.\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/php/eulogioep.php",
    "content": "<?php\n/**\n * Demostración de diferentes mecanismos de iteración en PHP\n * \n * PHP ofrece múltiples formas de realizar iteraciones, cada una\n * con sus propias características y casos de uso específicos.\n */\n\necho \"=== Demostración de Mecanismos de Iteración en PHP ===\\n\\n\";\n\n// 1. Bucle for tradicional\necho \"1. Usando bucle for tradicional:\\n\";\n/*\n * El bucle for es uno de los más comunes y versátiles.\n * Sintaxis: for (inicialización; condición; incremento)\n */\nfor ($i = 1; $i <= 10; $i++) {\n    echo $i . \" \";\n}\necho \"\\n\\n\";\n\n// 2. Bucle while\necho \"2. Usando bucle while:\\n\";\n/*\n * El bucle while se ejecuta mientras una condición sea verdadera.\n * Es útil cuando no sabemos exactamente cuántas iteraciones necesitamos.\n */\n$contador = 1;\nwhile ($contador <= 10) {\n    echo $contador . \" \";\n    $contador++;\n}\necho \"\\n\\n\";\n\n// 3. Bucle do-while\necho \"3. Usando bucle do-while:\\n\";\n/*\n * Similar al while, pero garantiza que el código se ejecute al menos una vez\n * ya que la condición se evalúa al final de cada iteración.\n */\n$num = 1;\ndo {\n    echo $num . \" \";\n    $num++;\n} while ($num <= 10);\necho \"\\n\\n\";\n\n// EXTRA: Más mecanismos de iteración\n\n// 4. foreach con array\necho \"4. Usando foreach con array:\\n\";\n/*\n * foreach es especialmente útil para iterar sobre arrays y objetos.\n * Es muy legible y evita tener que manejar índices manualmente.\n */\n$numeros = range(1, 10);\nforeach ($numeros as $numero) {\n    echo $numero . \" \";\n}\necho \"\\n\\n\";\n\n// 5. array_map\necho \"5. Usando array_map:\\n\";\n/*\n * array_map aplica una función a cada elemento de un array.\n * Es útil para transformar datos de forma funcional.\n */\n$resultado = array_map(function($n) {\n    echo $n . \" \";\n    return $n;\n}, range(1, 10));\necho \"\\n\\n\";\n\n// 6. array_walk\necho \"6. Usando array_walk:\\n\";\n/*\n * array_walk es similar a array_map, pero modifica el array original\n * y permite pasar parámetros adicionales a la función de callback.\n */\narray_walk($numeros, function($valor) {\n    echo $valor . \" \";\n});\necho \"\\n\\n\";\n\n// 7. Iterator\necho \"7. Usando Iterator:\\n\";\n/*\n * PHP proporciona varias clases de iterador para manejar colecciones\n * de manera más orientada a objetos.\n */\n$arrayIterator = new ArrayIterator($numeros);\nwhile ($arrayIterator->valid()) {\n    echo $arrayIterator->current() . \" \";\n    $arrayIterator->next();\n}\necho \"\\n\\n\";\n\n// 8. Generator\necho \"8. Usando Generator:\\n\";\n/*\n * Los generadores permiten crear iteradores de forma simple y eficiente\n * sin necesidad de implementar la interfaz completa de Iterator.\n */\nfunction generarNumeros() {\n    for ($i = 1; $i <= 10; $i++) {\n        yield $i;\n    }\n}\n\nforeach (generarNumeros() as $numero) {\n    echo $numero . \" \";\n}\necho \"\\n\\n\";\n\n// 9. array_reduce\necho \"9. Usando array_reduce:\\n\";\n/*\n * Aunque array_reduce se usa principalmente para reducir un array a un solo valor,\n * también puede usarse para iterar realizando una acción en cada paso.\n */\narray_reduce($numeros, function($carry, $item) {\n    echo $item . \" \";\n    return $carry;\n});\necho \"\\n\\n\";\n\n// 10. SPL DirectoryIterator (ejemplo con números)\necho \"10. Usando SPL DirectoryIterator (simulado con números):\\n\";\n/*\n * PHP proporciona iteradores especializados para diferentes propósitos.\n * Aquí simulamos uno similar a DirectoryIterator pero con números.\n */\nclass NumberIterator implements Iterator {\n    private $position = 0;\n    private $array = [];\n\n    public function __construct() {\n        $this->array = range(1, 10);\n    }\n\n    public function rewind() {\n        $this->position = 0;\n    }\n\n    public function current() {\n        return $this->array[$this->position];\n    }\n\n    public function key() {\n        return $this->position;\n    }\n\n    public function next() {\n        ++$this->position;\n    }\n\n    public function valid() {\n        return isset($this->array[$this->position]);\n    }\n}\n\n$numberIterator = new NumberIterator();\nforeach ($numberIterator as $number) {\n    echo $number . \" \";\n}\necho \"\\n\\n\";\n\necho \"=== Fin de la demostración ===\\n\";\n?>"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/php/gabrielmoris.php",
    "content": "<?php\n/*\n* EXERCISE:\n* Using your language, employ 3 different mechanisms to print\n* numbers from 1 to 10 through iteration.\n*/\n$count = 0;\n\ndo {\n    $count++;\n    echo \"Doing while: $count\\n\";\n} while ($count < 10);\n\n$count = 0;\nwhile ($count < 10) {\n    $count++;\n    echo \"While: $count\\n\";\n}\n\nfor ($i = 1; $i < 11; $i++) {\n    echo \"For loop: $i\\n\";\n}\n\n/*\n* EXTRA DIFFICULTY (optional):\n* Write the highest number of mechanisms that your language has\n* to iterate values. Can you use 5? And 10?\n*/\n\n$count = 0;\n$limit = 10;\n\nfunction iterator($count, $limit)\n{\n    if ($count < $limit) {\n        $count++;\n        echo \"Recursive Fn: $count\\n\";\n        return iterator($count, $limit);\n    } else {\n        return;\n    }\n}\n\niterator($count, $limit);\n\n$numbers = range(1, 10);\n\nforeach ($numbers as $number) {\n    echo \"Foreach Fn: $number\\n\";\n}\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/php/miguelex.php",
    "content": "<?php\n\n    echo \"Imprimiendo los numeros del 1 al 10 con un bucle for: \\n\";\n\n    for ($i = 1; $i <= 10; $i++) {\n        echo $i . \" \";\n    }\n\n    echo \"\\nImprimiendo los numeros del 1 al 10 con un bucle while: \\n\";\n\n    $i = 1;\n\n    while($i <= 10) {\n        echo $i . \" \";\n        $i++;\n    }\n\n    echo \"\\nImprimiendo los numeros del 1 al 10 con un bucle do-while: \\n\";\n\n    $i = 1;\n    while($i <= 10) {\n        echo $i . \" \";\n        $i++;\n    }\n\n    echo \"\\nImprimiendo los numeros del 1 al 10 con un bucle foreach: \\n\";\n\n    $numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n        \n    foreach ($numeros as $numero) {\n        echo $numero . \" \";\n    }\n\n    echo \"\\nImprimiendo los numeros del 1 al 10 con array map\\n\";\n    $funcion_map = function($numero) {\n        return $numero;\n    };\n    \n    $resultado_map = array_map($funcion_map, $numeros);\n    print_r($resultado_map);\n\n    echo \"\\nImprimiendo los numeros del 1 al 10 con array filter\\n\";\n    $funcion_filter = function($numero) {\n        return $numero;\n    };\n\n    $resultado_filter = array_filter($numeros, $funcion_filter);\n    print_r($resultado_filter);\n\n    \n\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/AChapeton.py",
    "content": "# WHILE\nprint('WHILE')\nx = 0\nwhile(x < 11):\n  print(x)\n  x = x + 1\n\n# FOR IN\nprint('FOR IN')\nnumbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\nfor i in numbers:\n  print(i)\n\n# FOR IN with RANGE\nprint('FOR IN with range')\nfor i in range(10):\n  print(1)"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/Aldroide.py",
    "content": "\"\"\"\n    Ejercicio:\n    Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n    números del 1 al 10 mediante iteración.\n\"\"\"\n\n# For\nfor i in range(i, 11):\n    print(i)\n\n\n# While\ni = 1\nwhile i <= 10:\n    print(i)\n    i += 1\n\n# Recursión\n\n\ndef recursivo(i=1):\n    if i <= 10:\n        print(i)\n        recursivo(i+1)\n\n\nrecursivo()\n\n\n\"\"\"\n    Dificultad Extra\n    Escribe el mayor número de mecanismos que posea tu lenguaje\n    para iterar valores\n\"\"\"\n\nfor e in [1, 2, 3, 4]:\n    print(e)\n\nfor e in {1, 2, 3, 4}:\n    print(e)\n\nfor e in (1, 2, 3, 4):\n    print(e)\n\nprint(*[i for i in range(1, 11)], sep=\"\\n\")\n\nfor c in \"Python\":\n    print(c)\n\nfor e in reversed([1, 2, 3, 4]):\n    print(e)\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/CaveroBrandon.py",
    "content": "\"\"\"EJERCICIO:\nUtilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\nnúmeros del 1 al 10 mediante iteración.\"\"\"\n\n\ndef print_to_10_using_for():\n    print('Using \"For\" loop:')\n    for i in range(1, 11):\n        print(i, end=' ')\n\n\ndef print_to_10_using_while():\n    print('\\nUsing \"While\" loop:')\n    n = 1\n    while n < 11:\n        print(n, end=' ')\n        n += 1\n\n\ndef print_to_10_using_recursive(num):\n    if num < 11:\n        print(num, end=' ')\n        num += 1\n        print_to_10_using_recursive(num)\n    else:\n        return\n\n\ndef print_to_5_using_list_comprehension():\n    print('\\nIteration using list comprehension')\n    numbers = [num for num in range(1, 6)]\n    print(numbers)\n\n\ndef print_to_5_using_iterators():\n    print('Iteration using iterators')\n    numbers = [num for num in range(1, 6)]\n    iter_number = iter(numbers)\n    while True:\n        try:\n            value = next(iter_number)\n            print(value, end=' ')\n        except StopIteration:\n            break\n\n\ndef print_to_5_using_enumerate_method():\n    print('\\nIteration using enumerate method')\n    numbers = [num for num in range(1, 6)]\n    for _, number in enumerate(numbers):\n        print(number, end=' ')\n\n\ndef print_to_5_using_zip_function():\n    print('\\nIteration using zip function')\n    for _, number in zip(range(1, 6), range(1, 6)):\n        print(number, end=' ')\n\n\ndef print_to_5_using_keys_in_dictionary():\n    print('\\nIteration using keys of a dictionary')\n    numbers_dict = {1: 1, 2: 2, 3: 3, 4: 4, 5: 5}\n    for key in numbers_dict:\n        print(key, end=' ')\n\n\ndef print_to_5_using_map_function():\n    def print_number(n):\n        print(n, end=' ')\n\n    print('\\nIteration using map function')\n    numbers_map = map(print_number, range(1, 6))\n    list(numbers_map)\n\n\n\"\"\"DIFICULTAD EXTRA (opcional):\nEscribe el mayor número de mecanismos que posea tu lenguaje\npara iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\"\"\"\n\nprint_to_10_using_for()\nprint_to_10_using_while()\nprint('\\nUsing \"Recursive\" loop:')\nprint_to_10_using_recursive(1)\n\nprint_to_5_using_list_comprehension()\nprint_to_5_using_iterators()\nprint_to_5_using_enumerate_method()\nprint_to_5_using_zip_function()\nprint_to_5_using_keys_in_dictionary()\nprint_to_5_using_map_function()\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/CesarCarmona30.py",
    "content": "from itertools import count, islice\nfrom functools import reduce\nimport numpy as np\n'''\n  EJERCICIO\n'''\nprint('\\nEJERCICIO')\n\nprint('a. For in range:')\nfor number in range(1, 11):\n print(number, end=' ')\n\nnumber = 1\nprint('\\nb. While:')\nwhile number <= 10:\n print(number, end= ' ', )\n number += 1\n\nprint('\\nc. Diccionario:')\ndict_numbers = {'1': 2, '3': 4, '5': 6, '7': 8, '9': 10}\nfor key, value in dict_numbers.items():\n print(key, value, sep=' ', end=' ')\n\n'''\n  EXTRA\n'''\n\nprint('\\n\\nEXTRA')\n\nodds = [1, 3, 5, 7, 9]\nevens = [2, 4, 6, 8, 10]\nprint('\\n- 1. For in con zip:')\nfor odd, even in zip(odds, evens):\n print(odd, even, sep=' ', end=' ')\n\nprint('\\n- 2. For in enumerate:')\nten_letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']\nfor index, value in enumerate(ten_letters):\n  print(index + 1, end=' ')\n\nprint('\\n- 3. For in slicing:')\nnumbers = list(range(1, 101))  # Crear una lista del 1 al 100\nnumbers = numbers[0:10:1] # Selecciono del 1 al 10\nfor number in numbers:\n print(number, end=' ')\n\nprint('\\n- 4. Funcion con yield:')\ndef mi_generador():\n  yield 1, 2, 3, 4 ,5 ,6, 7, 8, 9, 10\ngen = mi_generador()\nprint(next(gen))\n\nprint(\"- 5. For in con list comprehensions:\")\nlist_nubers = [i for i in range(1, 11)]\nfor number in list_nubers:  \n  print(number, end=' ')\n\nprint(\"\\n- 6. Recursividad:\")\ndef printed(number):\n if number > 1:\n  printed(number - 1)\n print(number, end=' ')\nprinted(10)\n\nprint(\"\\n- 7. Map:\")\nnumbers = list(map(lambda x: x, range(1, 11)))\nfor number in numbers:\n    print(number, end=' ')\n\nprint(\"\\n- 8. Filter:\")\nfilter_numbers = list(filter(lambda x: True if x <= 10 else False, range(1, 101)))\nfor number in filter_numbers:\n    print(number, end=' ')\n\nprint(\"\\n- 9. Itertools:\")\nfor number in islice(count(1), 10):\n    print(number, end=' ')\n\nprint(\"\\n- 10. Utilizando NumPy:\")\nnumbers = np.arange(1, 11)\nfor number in numbers:\n    print(number, end=' ')"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/Chrisdev00.py",
    "content": "\"\"\"\n* EJERCICIO:\n* Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n* números del 1 al 10 mediante iteración.\n*\n* DIFICULTAD EXTRA (opcional):\n* Escribe el mayor número de mecanismos que posea tu lenguaje\n* para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n\"\"\"\n\nprint(\"a.- Utilizando un bucle 'for' con 'range()' \")\nfor i in range(1,11):\n    print(i, end=\" \")\nprint()\n\nprint(\"b.- Utilizando un bucle 'for' con una lista\")\nnumeros = [1,2,3,4,5,6,7,8,9,10]\nfor num in numeros:\n    print(num, end=\" \")\nprint()\n\nprint(\"c.- Utilizando un bucle 'while'\")\ncont = 1\nwhile cont <= 10:\n    print(cont, end=\" \")\n    cont += 1\nprint()\n\n\n############  ----------------------------- EXTRA ------------------------------- #############\n\n# 1.- Bucle for con range()\n\nprint(\"1.- Utilizando un bucle 'for' con 'range()' \")\nfor i in range(1,11):\n    print(i, end=\" \")\nprint()\n\n# 2.- Bucle for con una Lista\n\nprint(\"2.- Utilizando un bucle 'for' con una lista\")\nnumeros = [1,2,3,4,5,6,7,8,9,10]\nfor num in numeros:\n    print(num, end=\" \")\nprint()\n\n# 3.-  Bucle while\n\nprint(\"3.- Utilizando un bucle 'while'\")\ncont = 1\nwhile cont <= 10:\n    print(cont, end=\" \")\n    cont += 1\nprint()\n\n# 4.- Bucle for con enumerate()\n\nprint(\"4.- Utilizando bucle for con enumerate\")\nlanguages = [\"Python\", \"JavaScript\", \"C#\"]\nfor indice, language in enumerate(languages, start=1):\n    print(f\"Lenguaje {indice}: {language}\", end=\" \")\nprint()\n\n# 5.- Bucle for con zip()\n\nprint(\"5.- Utilizando bucle for con zip\")\nnombres = ['Juan', 'María', 'Pedro']\nedades = [30, 25, 35]\nfor nombre, edad in zip(nombres, edades):\n    print(f\"{nombre} tiene {edad} años.\", end=\" \")\nprint()\n\n# 6.- Iteradores Personalizados\n\nprint(\"6.- Utilizando iteradores personalizados __iter__() y __next__()\")\n\nclass Contador:\n    def __init__(self, inicio, fin):\n        self.actual = inicio\n        self.fin = fin\n    \n    def __iter__(self):\n        return self\n    \n    def __next__(self):\n        if self.actual > self.fin:\n            raise StopIteration\n        else:\n            valor = self.actual\n            self.actual += 1\n            return valor\n\ncontador = Contador(1, 10)\nfor num in contador:\n    print(num, end=\" \")\nprint()\n\n# 7.- Utilizando itertools\n\nprint(\"7.- Utilizando itertools\")\nimport itertools\nfor i in itertools.count(1):\n    if i > 10:\n        break\n    print(i, end=\" \")\nprint()\n\n# 8.- Bucle for con dict.items()\n\nprint(\"8.- Utilizando bucle for con dict.items\")\nstudent = {\"name\": \"Juan\", \"edad\": 30, \"lenguaje\": \"Python\"}\nfor clave, valor in student.items():\n    print(f\"{clave}: {valor}.\", end=\" \")\nprint()\n\n# 9.- Bucle for con set\n\nprint(\"9.- Utilizando un bucle for con set\")\nlanguages = {'Python', 'Java', 'JavaScript'}\nfor language in languages:\n    print(language, end=\" \")\nprint()\n\n# 10.- Bucle for con os.listdir()\n\nprint(\"10.- Utilizando un bucle for con os.listdir()\")\nimport os\nfor archivo in os.listdir():\n    print(archivo)\nprint()\n\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/Complex303.py",
    "content": "\"\"\"\nIteraciones\n\"\"\"\n\n\n#For\nfor i in range(1,11):\n    print(i)\n\n\n#While\nnumero = 1\n\nwhile numero <=10:\n    print(numero)\n    numero+=1\n\n\n#Recursividad\ndef iteracion(num = 1) -> int:\n    if num <=10:\n        print(num)\n        iteracion(num +1)\n\niteracion()\n\n\n\"\"\" * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\"\"\"\n\n\n# Itera sobre una lista de letras y las imprime una por una\nfor i in [\"a\", \"b\", \"c\", \"d\"]:\n    print(i)\n\n# Itera sobre la lista al revés usando reversed()\nfor i in reversed([\"a\", \"b\", \"c\", \"d\"]):\n    print(i)\n\n# Itera sobre una lista ordenada alfabéticamente\nfor i in sorted([\"C\", \"O\", \"M\", \"P\", \"L\", \"E\", \"X\"]):\n    print(i)\n\n# Itera sobre una lista ordenada y a la vez muestra su índice y valor usando enumerate()\nfor i, e in enumerate(sorted([\"C\", \"O\", \"M\", \"P\", \"L\", \"E\", \"X\"])):\n    print(f\"indice: {i}, valor: {e}\")\n\n# Itera sobre un conjunto (set)\nfor i in {1, 2, 3, 4}:\n    print(i)\n\n# Itera sobre una tupla\nfor i in (1, 2, 3, 4):\n    print(i)\n\n\n# Itera sobre un diccionario, obteniendo clave y valor al mismo tiempo\ndictionario: dict = {1: \"a\", 2: \"b\", 3: \"c\"}\nfor key, value in dictionario.items():\n    print(key, \"-\", value)\n\n# Itera solo por las claves de un diccionario\nfor key in {1: \"a\", 2: \"b\", 3: \"c\"}.keys():\n    print(key)\n\n# Itera solo por los valores de un diccionario\nfor value in dictionario.values():\n    print(value)\n\n\n# Imprime del 1 al 10 usando comprensión de lista + desempaquetado * y separador de línea\nprint(*[i for i in range(1, 11)], sep=\"\\n\")\n\n# [i for i in range(1, 11)] genera una lista del 1 al 10.\n# * desempaqueta la lista para pasar cada elemento como argumento a print.\n# sep=\"\\n\" hace que cada elemento se imprima en una línea distinta.\n\n# Itera sobre una cadena carácter por carácter\nfor i in \"python\":\n    print(i)\n\n\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/DaniQB99.py",
    "content": "'''\nEJERCICIO:\nUtilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\nnúmeros del 1 al 10 mediante iteración.\n'''\n# FOR \nfor i in range(1,11):\n    print(i)\n\n# WHILE\ni = 1 \nwhile i <= 10:\n    print(i)\n    i +=1\n\n# RECURSIVIDAD\ndef count_ten(i=1):\n    if i <= 10:\n        print(i)\n        count_ten(i + 1)\n\ncount_ten()\n    \n\n'''\nDIFICULTAD EXTRA (opcional):\nEscribe el mayor número de mecanismos que posea tu lenguaje para \niterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n'''\n\nprint(\"\\n\\nDIFICULTAD EXTRA\\n\")\n\n# FOR in list\nprint('LIST')\nfor x in [1, 2, 3, 4, 5 , 6 ,7, 8, 9, 10]:\n    print(x)\n    \n# FOR in set\nprint('SET')\nfor x in {1, 2, 3, 4 , 5 , 6 ,7, 8, 9, 10}:\n    print(x)\n    \n# FOR in tuple\nprint('TUPLE')\nfor x in (1, 2, 3, 4, 5 , 6 ,7, 8, 9, 10):\n    print(x)\n    \n# FOR in dict\nprint('DICT')\nfor x in {1: \"a\", 2: \"b\", 3: \"c\", 4: \"d\", 5: \"e\", 6: \"f\", 7: \"g\", 8: \"h\", 9: \"i\", 10: \"j\"}:\n    print(x)\n    \n# FOR in dict values\nprint('DICT VALUES')\nfor x in {1: \"a\", 2: \"b\", 3: \"c\", 4: \"d\", 5: \"e\", 6: \"f\", 7: \"g\", 8: \"h\", 9: \"i\", 10: \"j\"}.values():\n    print(x)\n\n# FOR in dict keys\nprint('DICT KEYS')\nfor x in {1: \"a\", 2: \"b\", 3: \"c\", 4: \"d\", 5: \"e\", 6: \"f\", 7: \"g\", 8: \"h\", 9: \"i\", 10: \"j\"}.keys():\n    print(x)\n\n# FOR in list unpack\nprint('*' * 10)\nprint(*[i for i in range(1, 11)], sep=\"\\n\")\n\n# FOR in reverse list\nprint('LIST REVERSA')\nfor x in reversed([1, 2, 3, 4, 5 , 6 ,7, 8, 9, 10]):\n    print(x)\n\n# FOR in sort list\nprint('LIST SORT')\nfor x in sorted([\"a\", \"d\", \"r\", \"i\"]):\n    print(x)\n\n# FOR in list enumerate\nprint('LIST ENCUENTE')\nfor i, x in enumerate(sorted(['p', 'h', 'y', 't', 'h', 'o', 'n'])):\n    print(f\"Índice: {i}, valor: {x}\")   \n\n# FOR in string'\nprint('STRING')\nfor x in 'Python':\n    print(x)"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/EmmanuelMMontesinos.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n * números del 1 al 10 mediante iteración.\n *\n * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n */\n\"\"\"\n# Ejercicio Base y Extra\n\nlista = [1,2,3,4,5,6,7,8,9]\n\n'''Primero: Bucle for'''\nfor numero in lista:\n    print(f\"Bucle for: {numero}\")\n\n'''Segundo: Bucle while'''\ncontador = 1\nwhile contador < 10:\n    print(f\"Bucle while: {contador}\")\n    contador += 1\n\n'''Tercero: Compresión'''\nlista_compres = [print(f\"Compresión: {n}\") for n in range(1,10)]\n\n'''Cuarto: Map'''\nmap_print = [print(f\"Map: {x}\") for x in map(lambda x: x*100,lista)]\nmap = list(map(lambda x: x*100,lista))\n\n'''Quinto: Iter'''\nitinerador = iter(lista)\ntry:\n    while True:\n        print(f\"Iter: {next(itinerador)}\")\n\nexcept StopIteration:\n    pass\n\n'''Sexto: Generador'''\ndef generador():\n    for n in range(1,10):\n        yield n\nfor n in generador():\n    print(f\"Generador: {n}\")\n\n'''Septimo: Zip'''\nfor n,n_100 in zip(lista,map):\n    print(f\"Zip: {n} X 100 = {n_100}\")\n\n'''Octavo: Enumerate'''\nfor index,valor in enumerate(lista):\n    print(f\"Enumerate: {valor}\")"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/FedeAirala.py",
    "content": "# #17 ITERACIONES\n\"\"\"\n * EJERCICIO:\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n * números del 1 al 10 mediante iteración.\n \"\"\"\n\n\nprint (\"-\"*60)\nprint (\"Bucle While\")\n\ni=0\nwhile i<10:\n    print (f\"Number: {i+1}\")\n    i +=1\n\nprint (\"-\"*60)\nprint (\"Bucle For\")\n\nfor i in range (10):\n    print (f\"Number: {i+1}\")\n\n\nprint (\"-\"*60)\nprint (\"Recursividad\")\n\ndef contador(cont):\n    if cont<11:\n        print (f\"Number: {cont}\")\n        cont+=1\n        contador(cont)\ncontador(1)\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n */\n \"\"\"\n\nprint (\"-\"*60)\nprint (\"While Infinito con break\")\n\ni=0\nwhile True:\n    if i<10:\n        print (f\"Number: {i+1}\")\n        i+=1\n    else:\n        break\n\nprint (\"-\"*60)\nprint (\"Iterables\")\n\nmytuple = (1,2,3,4,5,6,7,8,9,10)\nmyit = iter(mytuple)\n\nfor i in range (len(mytuple)):\n    print (next(myit))\n\n\nprint (\"-\"*60)\nprint (\"Clases\")\n\nclass Numbers:\n    def __init__(self,number) -> None:\n        self.number=number\n        \n    def print_numbers(self):\n        for i in range (self.number):\n                print (i+1)\n\n\ncont = Numbers(10)\ncont.print_numbers()\n\nprint (\"-\"*60)\nprint (\"Compresión de Listas\")\n\ncont = [x+1 for x in range (10)]\nfor i in cont:\n    print (i)\n\nprint (\"-\"*60)\nprint (\"Con Numpy\")\n\nimport numpy as np\n\ndef cont_numpy(cont):\n    cont = np.array([i+1 for i in range (cont)])\n    print (cont)\ncont_numpy(10)\n\ncont2 = np.arange(1,11)\nfor i in range (len(cont2)):\n    print (cont2[i])"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/Gallitofast.py",
    "content": "# * EJERCICIO:\n#  * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n#  * números del 1 al 10 mediante iteración.\n#----------------------------------------------------------------------------\nprint(\"-\"*60)\nprint(\"Ciclo for\")\nfor i in range (10):\n    print(i+1)\nprint(\"-\"*60)\nprint(\"While\")\na=0\nwhile a<10:\n    print(a+1)\n    a+=1\nprint(\"-\"*60)\nprint(\"For con lista\")\nlista=[1,2,3,4,5,6,7,8,9,10]\nfor item in lista:\n    print(item)\n\n# * DIFICULTAD EXTRA (opcional):\n#  * Escribe el mayor número de mecanismos que posea tu lenguaje\n#  * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\nprint(\"-\"*60)\nprint(\"1.-For\")\nfor i in range(5):\n    print(\"i+1\")\nprint(\"-\"*60)\nprint(\"2.-While\")\na=0\nwhile a<5:\n    print(\"a+1\")\n    a+=1\nprint(\"-\"*60)\nprint(\"3.-Iteracion de lista con for\")\nfor item in lista:\n    print(item)\nprint(\"-\"*60)\nprint(\"4.-Recursividad\")\ndef recursifuncion(numero):\n    print(numero)\n    if numero>0:\n        numero-=1\n        recursifuncion(numero)\n    else:\n        print(\"Iteracion recursiva finalizada\")\n\nrecursifuncion(10)\nprint(\"-\"*60)\n\nfor e in sorted([\"G\",\"a\",\"l\",\"l\",\"o\"]):\n    print(e)\n\nfor i, e in enumerate(sorted([\"G\",\"a\",\"l\",\"l\",\"o\"])):\n    print(f\"Índice: {i}, valor: {e}\")\n\n\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/Gordo-Master.py",
    "content": "# 17 - Iteraciones\n\nfor i in range(10):\n    print(i+1)\n\ncontador = 0\nwhile contador < 10:\n    contador += 1\n    print(contador)\n\n\niterador = iter([i+1 for i in range(10)])\n\nfor i in iterador:\n    print(i)\n\n\"\"\"\nEjercicio extra\n\"\"\"\ncontador = 0\ndef generador():\n    yield 1\n    yield 2\n    yield 3\n    yield 4\n    yield 5\n    yield 6\n    yield 7\n    yield 8\n    yield 9\n    yield 10\n\nfor i in generador():\n    print(i)\n\ndef count_from_1_to(num):\n    if not num == 1:\n        count_from_1_to(num-1)\n        print(num)\n    else:\n        print(num)\n\ncount_from_1_to(10)\n\nfor e in [1,2,3,4]:\n    print(e)\n\nfor e in {1,2,3,4}:\n    print(e)\n\nfor e in (1,2,3,4):\n    print(e)\n\nfor e in {1:\"a\",2:\"b\",3:\"c\",4:\"d\"}:\n    print(e)\n\nfor e in {1:\"a\",2:\"b\",3:\"c\",4:\"d\"}.values():\n    print(e)\n\nprint(*[i for i in range(1, 11)], sep = \"\\n\")\n\nfor c in \"Python\":\n    print(c)\n\nfor e in reversed([1,2,3,4]):\n    print(e)\n\nfor e in sorted([\"G\",\"O\",\"R\",\"D\",\"O\"]):\n    print(e)\n\nfor n, e in enumerate(sorted([\"G\",\"O\",\"R\",\"D\",\"O\"])):\n    print(f\"{n}:{e}\")\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/Hyromy.py",
    "content": "# iteracion por for\nfor i in range(1, 11):\n    print(i)\n\nprint(\"\\n\")\n\n# iteracion por while\nx = 1\nwhile x <= 10:\n    print(x)\n    x += 1\n\nprint(\"\\n\")\n\n# iteracion por recursividad\ndef iterar(valor:int, objetivo:int):\n    print(valor)\n\n    if valor < objetivo:\n        iterar(valor +1, objetivo)\n\niterar(1, 10)"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/Irenetitor.py",
    "content": "#Exercise\nfor i in range(1, 11):\n    print(i)\n\ni = 1\nwhile i <= 10:\n    print(i)\n    i += 1\n\n\ndef count(i=1):\n    if i <= 10:\n        print(i)\n        count(i + 1)\n\ncount()\n\n#Extra Exercise\n\nfor n in (1, 4, 6 , 8, 9):\n    print(n)\n\nfor n in {1, 4, 6 , 8, 9}:\n    print(n)\n\nfor n in [1, 4, 6 , 8, 9]:\n    print(n)\n\nfor n in [1, 4, 6 , 8, 9]:\n    print(n)\n\nfor n in {1: \"i\", 4: \"r\", 6: \"e\", 8: \"n\", 9: \"e\"}:\n    print(n)\n\nfor n in {1: \"i\", 4: \"r\", 6: \"e\", 8: \"n\", 9: \"e\"}.values():\n    print(n)\n\n\nfor n in reversed([1, 4, 6 , 8, 9]):\n    print(n)\n\nfor c in \"iteration\":\n    print(c)\n\nprint(*[i for i in range(1, 11)])\n\nfor n in sorted([\"i\", \"t\", \"e\", \"r\", \"a\", \"t\", \"i\", \"o\", \"n\"]):\n    print(n)\n\nfor i,n in enumerate([\"i\", \"t\", \"e\", \"r\", \"a\", \"t\", \"i\", \"o\", \"n\"]):\n    print(f\"Index: {i}, value: {n}\")\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/JAFeito.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n * números del 1 al 10 mediante iteración.\n *\n * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n \"\"\"\n \n#bucle for \nfor i in range(1,11):\n    print(i)\n#bucle while     \ni=1\nwhile i <=10:\n    print(i) \n    i+=1  \n#funciion recursiva\ndef imp_num(n: int):\n    if n <=10:\n        print(n)\n        n+=1\n        imp_num(n)\n\nimp_num(1)\n\nprint(*[i for i in range (1,11)],sep = \"\\n\")\n\nfor i in [1,2,3,4,5]:\n    print(i)\n    \nfor i in (1,2,3,4,5):\n    print(i)\n    \nfor i in{1:\"a\",2:\"b\",3:\"c\",4:\"d\",5:\"e\"}:\n    print(i)"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/JesusWay69.py",
    "content": "import os, random\nos.system('cls')\nos.system('clear')\n\n\"\"\"* EJERCICIO:\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n * números del 1 al 10 mediante iteración.\n *\n * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\"\"\"\n\n'''FOR CON RANGO CONDICIONAL DE INICIO Y PARADA'''\ndef iterator_1():\n    for i in range (1,11):\n        print(i, end=\" \")\n    print(\"\\b --> Método 1\")\niterator_1()\n\n'''FOR CON RANGO SOLO DE PARADA Y CONDICIONAL PARA SALTARSE EL 0 CON EL QUE EMPIEZA POR DEFECTO'''\ndef iterator_2():\n    for i in range (11):\n        if i == 0:\n            continue\n        print(i, end=\" \")\n    print(\"\\b --> Método 2\")\niterator_2()\n\n'''FOR ANIDADOS CON CONDICIÓN DE INICIO,PARADA Y PASO, EL PRIMERO IMPRIME LOS IMPARES Y EL SEGUNDO LOS PARES'''\ndef iterator_3(i:int):\n    for i in range (1,11,2):\n        print(i, end=\" \")\n        for j in range(1):\n            if i<10:\n                print (i+1, end=\" \")\n    print(\"\\b --> Método 3\")\niterator_3(0)\n\n'''BUCLE FOR-ELSE CON CONDICIÓN DE INICIO Y PARADA'''\ndef iterator_4(i:int):\n    for i in range (i,1):\n        if i == 1:\n            break \n    else:\n        for i in range(i+1,11):\n            print(i,end=\" \")\n    print(\"\\b --> Método 4\")\niterator_4(0)\n\n\n   \n'''WHILE CON CONDICIÓN DE PARADA Y OPERADOR DE INCREMENTO'''\ndef iterator_5(i:int):\n    while i<10:\n        i+=1\n        print(i, end=\" \")\n    print(\"\\b --> Método 5\")\niterator_5(0)\n\n\n'''WHILE CON OPERADOR DE INCREMENTO Y CONDICIÓN DE SALIDA (DO-WHILE)'''\ndef iterator_6(i:int):\n    while True:\n        i+=1\n        print (i,end=\" \")\n        if i == 10:\n            break\n    print(\"\\b --> Método 6\")\niterator_6(0)\n\n\n'''WHILE ANIDADOS CON CONDICIÓN DE PARADA Y OPERADOR DE INCREMENTO'''\ndef iterator_7(i:int):\n    while i<10:\n        i+=1\n        print(i, end=\" \")\n        while i<10:\n            i+=1\n            print(i, end=\" \")\n    print(\"\\b --> Método 7\")\niterator_7(0)\n\n\n'''FUNCIÓN CON INCREMENTO, CONDICIÓN DE PARADA Y RECURSIVIDAD'''\ndef iterator_8(i:int):\n    i+=1\n    print(i, end=\" \")\n    if i<=9:\n        iterator_8(i)\niterator_8(0)\nprint(\"\\b --> Método 8\")\n\n'''FUNCIÓN CON GENERACIÓN DE NÚMEROS ALEATORIOS QUE SE AÑADEN A UN SET HASTA QUE ESTE CUMPLA LA CONDICIÓN DE LONGITUD 10'''\ndef iterator_9(i:int):\n    my_list = set()\n    while len(my_list)<i:\n       num = random.randint(1,10)\n       my_list.add(num)\n    [print(num, end=\" \") for num in my_list]\n    print(\"\\b --> Método 9\")\niterator_9(10)\n\n'''FUNCIÓN CON MÉTODO DE LENGUAJE ITER'''\ndef iterator_10():\n    my_list = []\n    [my_list.append(i) for i in range(1,11)]\n    my_iterator = (iter(my_list))\n    [print(next(my_iterator), end=\" \") for i in range (len(my_list))]\n    print(\"\\b --> Método 10\")\niterator_10()\n\n'''FUNCIÓN QUE TRANSFORMA CARACTERES A SU CÓDIGO ASCII CON EL MÉTODO ORD'''\ndef iterator_11(symbols:str):\n    for char in symbols:\n        print(ord(char)-40,end=\" \")\n    print(\"\\b --> Método 11\")\niterator_11(\")*+,-./012\")\n\n'''FUNCIÓN QUE CREA 2 SETS CON FOR Y WHILE E IMPRIME LOS ELEMENTOS COMUNES DE AMBOS '''\ndef iterator_12():\n    set1 = set()\n    set2 = set()\n    for i in range (10,-15,-1):\n       set1.add(i)\n    i=1\n    while i>0 and i<25:\n        set2.add(i)\n        i+=1\n    [print(i, end = ' ') for i in set2.intersection(set1)]  \n    print(\"\\b --> Método 12\")     \niterator_12()\n\n'''FUNCIÓN QUE CREA UN SET DE NÚMEROS PARES DEL 0 AL 20 Y LUEGO UN DICCIONARIO A PARTIR DE ESE SET\n   CON SUS ELEMENTOS COMO CLAVES Y LA DIVISIÓN DE ESTOS ENTRE 2 COMO VALORES '''\ndef iterator_13():\n    my_list = set() \n    [my_list.add(i) for i in range(0,21,2)]\n    my_dict = {j:j/2 for j in my_list}\n    del(my_dict[0])\n    [print(int(v),end=\" \") for v in my_dict.values()]\n    print(\"\\b --> Método 13\") \niterator_13()\n\n'''FUNCIÓN QUE CREA UNA LISTA CON NÚMEROS DE 10 A 1 CON FOR REGRESIVO Y LUEGO CON OTRO FOR\n   SE DESAPILA Y SE IMPRIME'''\ndef iterator_14():\n    my_list = []\n    [my_list.append(i) for i in range(10,0,-1)]\n    [print(my_list.pop(), end=\" \") for j in range(len(my_list))]   \n    print(\"\\b --> Método 14\")    \niterator_14()\n'''FUNCIÓN QUE CREA UNA LISTA CON NÚMEROS DE 10 A 1 CON FOR REGRESIVO, SE CONVIERTE\n   A UN STRING, SE VOLTEA EL ORDEN DE LOS CARACTERES Y SE IMPRIMEN LOS CARACTERES CON\n   OTRO FOR'''\ndef iterator_15():\n    my_list = []\n    my_str = \"\"\n    [my_list.append(i) for i in range(10,0,-1)]\n    for j in my_list:\n        j = str(j)\n        my_str=my_str+j\n    my_str=my_str.replace(\"10\",\"01\")\n    my_str= (my_str[::-1])\n    for n in my_str:\n        if n==\"0\":\n            print(\"\\b\",end=\"0\")\n        else:\n            print(int(n), end=\" \")\n    print(\" \\b --> Método 15\")\niterator_15()\n\n\n\n\n\n \n\n\n\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/JheisonQuiroga.py",
    "content": "\"\"\"/*\n * EJERCICIO:\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n * números del 1 al 10 mediante iteración.\n *\n\"\"\"\n\n# Métodos Básicos\n\n# 1. For:\nprint(\"1. For\")\nfor num in range(10):\n    print(num + 1)\n\n# 2. While\nprint(\"\\n2. While\")\nnumber = 0\n\nwhile number < 10:\n    number += 1\n    print(number)\n\n# 3. List Comprehension\nprint(\"\\n3. List Comprehension\")\n[print(n) for n in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n */\n\"\"\"\n\n# 4. Map y lambda\nprint(\"\\n4. Map y Lambda\")\nnumbers = list(map(lambda x: x, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]))\nfor n in numbers:\n    print(n)\n\n# 5. Generator Expression\nprint(\"\\n5. Generator Expression\")\ngen = (i for i in range(1, 11))\nprint(gen) # <generator object <genexpr> at 0x7a17b4734a00>\nfor num in gen:\n    print(num)\n\n# 6. Generator Function\n\nprint(\"\\n6. Generator Function\")\n\ndef generator_function(limit):\n    num = 0\n    while num < limit:\n        num += 1\n        yield num\n\n\nfor num in generator_function(10):\n    print(num)\n\n\n# 7. Recursion\nprint(\"\\n7. Recursion\")\n\ndef print_number(n=1):\n    if n > 10:\n        return\n    print(n)\n    print_number(n+1)\n\nprint_number(1)\n\n# 8. Next and Iter\n\"\"\"Creamos un objeto iter y lo iteramos manualmente\"\"\"\n\nprint(\"\\n8. Next and Iter\")\n\ndef next_and_iter():\n    numbers_iter= iter(range(1,11))\n    while True:\n        try:\n            print(next(numbers_iter))\n        except StopIteration:\n            print(\"Iteración finalizada\")\n            return\n    \n\nnext_and_iter()\n\n# 9. Iterator Class\nprint(\"\\n9.Iterator Class\")\n\nclass CounterClass:\n    def __init__(self, current, limit) -> None:\n        self.current = current\n        self.limit = limit\n    \n    def __iter__(self):\n        return self\n    \n    def __next__(self):\n        if self.current > self.limit:\n            raise StopIteration\n        current = self.current\n        self.current += 1\n        return current\n    \n\nnumbers = [num for num in CounterClass(1, 10)]\nprint(numbers) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n\nprint(\"No me alcanzo para llegar al num 10. Lo siento :(\")"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/JuanDAW37.py",
    "content": "\"\"\"\n* EJERCICIO:\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n * números del 1 al 10 mediante iteración.\n *\n * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n\"\"\"\n# Bucle while\nprint('*******Bucle While*******')\ni = 1\nwhile i <= 10:\n    print(i)\n    i += 1\n    \n# Simulando Do...While\nprint('*******Bucle Simulando Do...While*******')\ni = 1\nwhile True:\n    if i <= 10:\n        print(i)\n        i += 1\n    else:\n        break\n\n# Bucle for\nprint('*******Bucle For con listas(lists)*******')\nnumeros = [1,2,3,4,5,6,7,8,9,10]\n\nfor i in numeros:\n    print(i)\n    \nprint('*******Bucle For con conjuntos(sets)*******')\nfor i in {1,2,3,4,5,6,7,8,9,10}:\n    print(i)\n    \nprint('*******Bucle For con mapas(maps)*******')\nfor i in {1:'a',2:'b',3:'c',4:'d',5:'e',6:'f',7:'g',8:'h',9:'i',10:'j'}:\n    print(i)\n\nprint('*******Bucle For con tuplas(tuples)*******')\nfor i in (1,2,3,4,5,6,7,8,9,10):\n    print(i)\n    \nprint('*******Bucle For con función range()*******')\nfor i in range(1, 11):\n    print(i)\n    \n# Función recursiva:\nprint('*******Función Recursiva*******')\ndef imprimir_numeros(n:int = 1):\n    if n <= 10:\n        print(n)        \n        imprimir_numeros(n + 1)\n        \nimprimir_numeros()\n\n# EXTRA, de las 10 solicitadas podemos contar con las anteriores\nprint('*******Bucle For con Generadores Conprehesion List*******')\nprint(*[x for x in range(1, 11)], sep='\\n') #El * indica que es un conprehesion list y usando sep indicamos que el separador, en este caso, será un retorno de carro\n\nprint('*******Cadena de texto*******')\nlenguaje = 'Python'\nfor letra in lenguaje:\n    print(letra)\n    \nprint('*******Cadena de texto al revés*******')\nfor letra in reversed(lenguaje):\n    print(letra)\n    \nprint('*******Cadena de texto ordenada, usando enumerate para saber su índice*******')\nfor i, letra in enumerate(sorted(lenguaje)):\n    print(f'Índice {i}, letra {letra}')"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/KevinED11.py",
    "content": "from typing import Generator\nfrom functools import reduce\n\n\ndef iteration_1() -> None:\n    for n in range(1, 11):\n        print(n)\n\n\ndef iteration_2() -> None:\n    numbers = [num for num in range(1, 11)]\n    print(numbers, sep=\"\\n\")\n\n\ndef iterarion_3() -> None:\n    counter = 1\n    while counter <= 10:\n        print(counter)\n        counter += 1\n\n\ndef iteration_4() -> None:\n    iter = iter([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])\n    print(next(iter))\n    print(next(iter))\n\n\ndef iteraration_5() -> None:\n    numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n    doubled = list(map(lambda x: x * 2, numbers))\n    print(doubled)\n\n\ndef iteration_6() -> None:\n    numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n    filtered = list(filter(lambda x: x % 2 == 0, numbers))\n    print(filtered)\n\n\ndef iteration_7() -> None:\n    square_dict = {x: x * 2 for x in range(1, 11)}\n    print(square_dict)\n\n\ndef iteration_7() -> None:\n    numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n    result = reduce(lambda x, y: x + y, numbers, 0)\n    print(result)\n\n\ndef iteration_8() -> None:\n    numbers = tuple(num for num in range(1, 11))\n    print(numbers)\n\n\ndef iteration_9() -> None:\n    numbers = {num for num in range(1, 11)}\n    print(numbers)\n\n\ndef iteration_10() -> None:\n    numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n\n    for i, item in enumerate(numbers):\n        print(f\"elemento {item} en la posición {i}\")\n\n\ndef iteration_11() -> None:\n    numbers = [n for n in range(1, 11)]\n\n    for n in range(len(numbers)):\n        print(f\"elemento {numbers[n]} en la posición {n}\")\n\n\ndef even_number_generator() -> Generator[int, None, None]:\n    num = 0\n    while True:\n        yield num\n        num += 2\n\n\ndef main() -> None:\n    even_numbers = even_number_generator()\n\n    for _ in range(11):\n        print(next(even_numbers))\n\n    iteration_8()\n    iteration_9()\n    iteration_10()\n    iteration_11()\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/LucasRebuffo.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n * números del 1 al 10 mediante iteración.\n *\n * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n */ \"\"\"\n\nfrom os import sep\n\n\nfor i in range(1, 11):\n    print(i)\n\ni = 1\nwhile i <= 10:\n    print(i)\n    i += 1\n\n\ndef count_recursive(index: int = 1):\n    if index <= 10:\n        print(index)\n        count_recursive(index + 1)\n\n\ncount_recursive()\n\nfor e in [1, 2, 3, 4, 5]:\n    print(e)\n\nfor e in {4, 5, 9, 3}:\n    print(e)\n\nfor e in {1: \"a\", 2: \"b\", 3: \"c\"}:\n    print(e)\n\nprint(*[i for i in range(1, 11)], sep=\"\\n\")\n\nfor ch in \"python\":\n    print(ch)\n\nfor ch in reversed(\"python\"):\n    print(ch)\n\nfor e in sorted(\"lucas\"):\n    print(e)\n\nfor i, e in enumerate(\"lucas\"):\n    print(f\"Indice: {i}, valor: {e}\")\n\nfor e in {1: \"a\", 2: \"b\", 3: \"c\"}.values():\n    print(e)\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/Lumanet.py",
    "content": "# for -> Se ejecuta un número determinado de veces\nfor i in range(1, 11):\n    print(i, end=\" \")\nprint(\"\\n\")\n\n# While -> Se ejecuta mientras la condición sea verdadera\ni = 1\nwhile i <= 10:\n    print(i, end=\" \")\n    i += 1\nprint(\"\\n\")\n\n# Recursividad -> La función se llama a sí misma\ndef cuenta_diez(i=1):\n    if i <= 10:\n        print(i, end=\" \")\n        cuenta_diez(i + 1)\n\ncuenta_diez()\nprint(\"\\n\")\n\n# Map -> Aplica una función a cada elemento de una lista\ndef impresion(i):\n    print(i, end=\" \")\n\nlist(map(impresion, range(1, 11)))\nprint(\"\\n\")"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/Marlonleon2023.py",
    "content": "\"\"\"/*\n * EJERCICIO:\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n * números del 1 al 10 mediante iteración.\n *\n * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n */\"\"\"\n \n\n# con for \nprint(\"imprimiendo con for\")\nfor i in range(1,11):\n    print(i)\n    \n# con while\n\nprint(\"imprimiendo con while\")\ncontador=0\n\nwhile contador<10:\n    contador+=1\n    print(contador)\n    \n    \nprint(\"imprimiendo print se utiliza la funcion map\")\nlist(map(print, range(1, 11)))"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/Nicojsuarez2.py",
    "content": "# #17 ITERACIONES\n> #### Dificultad: Fácil | Publicación: 22/04/24 | Corrección: 29/04/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n * números del 1 al 10 mediante iteración.\n *\n * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/Sac-Corts.py",
    "content": "# Iterar sobre una lista con bucle for\nmi_lista = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\nfor elemento in mi_lista:\n    print(elemento)\n\n# Iterar con range()\nfor i in range(11):\n    print(i)\n\n# Iterar con while \ni = 0\nwhile i <= 10:\n    print(i)\n    i += 1\n\n### Ejercicio Extra ###\n\n# Iterar sobre un diccionario\nmi_diccionario = {'a': 1, 'b': 2, 'c': 3, 'd': 4}\nfor clave in mi_diccionario:\n    print(clave)\n\nfor valor in mi_diccionario.values():\n    print(valor)\n\nfor clave, valor in mi_diccionario.items():\n    print(f\"Clave: {clave}, Valor: {valor}\")\n\n# Iterar sobre conjuntos\nmi_conjunto = {1, 2, 3, 4, 5}\nfor elemento in mi_conjunto:\n    print(elemento)\n\n# Iterar sobre una cadena de texto\nmi_cadena = \"Hola Mundo\"\nfor caracter in mi_cadena:\n    print(caracter)\n\n# Iterar sobre una lista con índices\nmi_lista = [1, 2, 3, 4, 5]\nfor i in range(len(mi_lista)):\n    print(f\"Índice: {i}, Elemento: {mi_lista[i]}\")\n\n# Iterar sobre una lista con enumerate()\nmi_lista = ['a', 'b', 'c', 'd', 'e']\nfor indice, elemento in enumerate(mi_lista):\n    print(f\"Índice: {indice}, Elemento: {elemento}\")\n\n# Iterar sobre varias listas usando zip()\nnombres = [\"Isaac\", \"Geovanni\", \"Sac\"]\nedades = [22, 30, 16]\nfor nombre, edad in zip(nombres, edades):\n    print(f\"{nombre} tiene {edad} años\")\n\n# Iterar sobre archivos línea por línea\nfile_name = \"archivo.txt\"\nfile = open(file_name, \"w\")\nname = \"Isaac Cortés\"\nage = 22\nlanguage = \"Python\"\n\nfile.write(f\"Nombre: {name}\\n\")\nfile.write(f\"Edad: {age}\\n\")\nfile.write(f\"Lenguaje de programación: {language}\\n\")\n\nfile.close()\n\nwith open('archivo.txt', 'r') as archivo:\n    for linea in archivo:\n        print(linea.strip())\n\n# Iterar sobre generadores \ndef generador():\n    for i in range(6):\n        yield i\n\nfor valor in generador():\n    print(valor)\n\n# Iterar sobre comprensiones\nmi_lista = [1, 2, 3, 4, 5]\ncuadrados = [x**2 for x in mi_lista]\nprint(cuadrados)\n\n# Iterar con recursividad\ndef contador(i = 1):\n    if i <= 10:\n        print(i)\n        contador(i + 1)\n\ncontador()"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/SaezMD.py",
    "content": "#17 - ITERACIONES\n\"\"\"\n * EJERCICIO:\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir números del 1 al 10 mediante iteración.\n *\n * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n\"\"\"\n\n#Iteration from 1 to 10\n#Option1:\n\nfor i in range(0,11):\n    print(1,i)\n\n#Option2:\n\ncounter = 0\nwhile counter <= 9:\n    counter += 1\n    print(2,counter)\n\n#Option3:\n\nnumber_list = [1,2,3,4,5,6,7,8,9,10]\niterator = iter(number_list)\n\nfor element in iterator:\n    print(3, element)\n\n#EXTRA:\n\n\nfor e in [1, 2, 3, 4]:\n    print(e)\n\nfor e in {1, 2, 3, 4}:\n    print(e)\n\nfor e in (1, 2, 3, 4):\n    print(e)\n\nfor e in {1: \"a\", 2: \"b\", 3: \"c\", 4: \"d\"}:\n    print(e)\n\nfor e in {1: \"a\", 2: \"b\", 3: \"c\", 4: \"d\"}.values():\n    print(e)\n\nprint(*[i for i in range(1, 11)], sep=\"\\n\")\n\nfor c in \"Python\":\n    print(c)\n\nfor e in reversed([1, 2, 3, 4]):\n    print(e)\n\nfor e in sorted([\"m\", \"o\", \"u\", \"r\", \"e\"]):\n    print(e)\n\nfor i, e in enumerate(sorted([\"m\", \"o\", \"u\", \"r\", \"e\"])):\n    print(f\"Índice: {i}, valor: {e}\")\n\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/SooHav.py",
    "content": "# 17 ITERACIONES\n\n# Ejercicio\n\n# While\n\nc = 0\nwhile c <= 9:\n    c += 1\n    print(c)\n\n# for con range\nfor i in range(10):\n    print(i)\n\n# for con lista\nnumeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\nfor numero in numeros:\n    print(numero)\n\n# Extra\n\n# variantes de while\n\nc = 0\nwhile c <= 10:\n    c += 1\n    if (c == 10):\n        print(\"Rompemos el bucle cuando c vale\", c)\n        break\n    print(c)\nelse:\n    print(\"Se ha completado toda la iteración y c vale\", c)\n\nc = 0\nwhile c <= 10:\n    c += 1\n    if c == 11:\n        # print(\"Continuamos con la siguiente iteración\", c)\n        continue\n    print(c)\nelse:\n    print(\"Se ha completado toda la iteración y c vale\", c)\n\nwhile True:\n    linea = input('>')\n    if int(linea) >= 10 or int(linea) < 0:\n        break\n    print(linea)\nprint('¡Terminado!')\n\n# variantes del bucle for\n\nnumeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\nfor indice, numero in enumerate(numeros):\n    numeros[indice] *= 1\nnumeros\n\nindice = 0\nnumeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n# asignar un nuevo valor a los elementos de una lista (en este caso los mismos)\nfor numero in numeros:\n    numeros[indice] *= 1\n    indice += 1\nnumeros\n\nnumero = (num * 1 for num in range(1, 11))  # generador\nfor n in numero:\n    print(n)\n\n# otras formas\n\n# iterable iter\nfor i in iter([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]):\n    print(i)\n\n# list\nlist(range(1, 11))\n\n# uso de funciones generadores/yield\n\n\ndef even_generator(n):\n    counter = 1\n    while counter <= n:\n        if counter % 1 == 0:\n            yield counter\n        counter += 1\n\n\nfor num in even_generator(10):\n    print(num)\n\n\n# objetos iteradores con 2 métodos: __iter__() y __next__()\n\neven_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\nmy_iterator = iter(even_list)\nprint(next(my_iterator))\nprint(next(my_iterator))\nprint(next(my_iterator))\nprint(next(my_iterator))\nprint(next(my_iterator))\nprint(next(my_iterator))\nprint(next(my_iterator))\nprint(next(my_iterator))\nprint(next(my_iterator))\nprint(next(my_iterator))\n\n# Comprensiones de listas para crear nuevas listas aplicando una función\n# a cada elemento de las listas existentes\n\nmy_numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\neven_number_list = [num for num in my_numbers if num % 1 == 0]\nprint(even_number_list)\n\n# funcion filtro (ej. divison por 1)\n\n\ndef is_even(n):\n    return n % 1 == 0\n\n\nnums_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\neven_list = filter(is_even, nums_list)\nprint(list(even_list))\n\n# la función map() con lambda, toma como argumentos un iterable y una función.\nmy_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\nnumbers = map(lambda x: x ** 1, my_list)\nprint(list(numbers))\n\n# iterables anidados\nlist = [[1, 2, 3, 4], [5, 6], [7, 8, 9, 10]]\nfor inner_list in list:\n    for number in inner_list:\n        print(number)\n\n# numpy\n\"\"\"import numpy as np\nfor i in np.arange(1, 11):\n    print(i)\"\"\"\n\n# recursion\n\n\ndef itera_numeros(n):\n    if n <= 10:\n        print(n)\n        itera_numeros(n + 1)\n\n\nitera_numeros(1)\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/Trufoplus.py",
    "content": "###############################################################################\n## EJERCICIO\n###############################################################################\nprint(\"\\n1# Bucle for\")\nfor numero in range(10):\n    print(numero+1)\n\n\nprint(\"\\n2# Bucle While\")\nnumber = 1\nwhile number <= 10:\n    print(number)\n    number += 1\n\n\nprint(\"\\n3#Funcion Recursiva\")\ndef counter(number=1):\n    if number == 10:\n        print(10)\n        return\n    else:\n        print(number)\n        counter(number+1)\ncounter()\n\n\n###############################################################################\n## DIFICULTAD EXTRA\n###############################################################################\nprint(\"\\n4# En una linea\")\n[print(number) for number in range(1, 11)]\n\nprint(\"\\n5# While + break\")\nnumber = 1\nwhile True:\n    if number <= 10:\n        print(number)\n        number += 1\n    else:\n        break\n\nprint(\"\\n6# While + break\")\nnumber = 1\nwhile True:\n    print(number)\n    number += 1\n    if number == 11:\n        break\n\nprint(\"\\n7# Bucle for con lista predefinida\")\nnumeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\nfor numero in numeros:\n    print(numero)\n\nprint(\"\\n8# Función Map:\")\nlist(map(lambda x: print(x), range(1, 11)))\n\nprint(\"\\n9# Usando la Función reduce():\")\nfrom functools import reduce\nreduce(lambda _, numero: print(numero), range(1, 11), None)\n\nprint(\"\\nUsando NumPy arange():\")\nimport numpy as np\nfor numero in np.arange(1, 11):\n    print(numero)\n\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/adra-dev.py",
    "content": "\"\"\"\nEJERCICIO:\nUtilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\nnúmeros del 1 al 10 mediante iteración.\n\nDIFICULTAD EXTRA (opcional):\nEscribe el mayor número de mecanismos que posea tu lenuaje para \niterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n\nby adra-dev\n\"\"\"\n\n# For \nfor i in range(1,11):\n    print(i)\n\n# While\ni = 1 \nwhile i <= 10:\n    print(i)\n    i +=1\n\n# Recursividad \n\ndef count_ten(i=1):\n    if i <= 10:\n        print(i)\n        count_ten(i + 1)\n\ncount_ten()\n\n\n\"\"\"\nExtra\n\"\"\"\n\nfor e in [1, 2, 3, 4]:\n    print(e)\n\nfor e in {1, 2, 3, 4}:\n    print(e)\n\nfor e in (1, 2, 3, 4):\n    print(e)\n\nfor e in {1:\"a\", 2:\"b\", 3:\"c\", 4:\"d\"}:\n    print(e)\n\nfor e in {1: \"a\", 2: \"b\", 3: \"c\", 4: \"d\"}.values():\n    print(e)\n\nprint(*[i for i in range(1, 11)], sep=\"\\n\")\n\nfor c in \"Python\":\n    print(c)\n\nfor e in reversed([1, 2, 3, 4]):\n    print(e)\n\nfor e in sorted([\"a\", \"d\", \"r\", \"i\"]):\n    print(e)\n\nfor i, e in enumerate(sorted([\"a\", \"d\", \"r\", \"i\"])):\n    print(f\"Índice: {i}, valor: {e}\")"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/agusrosero.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n * números del 1 al 10 mediante iteración.\n *\n * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n */\n\"\"\"\n\n# EJERCICIO:\n# 1.\nfor i in range(1, 11):\n    print(i)\n\n# 2.\ni = 1\nj = 10\nwhile i <= j:\n    print(i)\n    i += 1\n\n# 3.\n\n\ndef iteracion(i=1):\n    if i <= 10:\n        print(i)\n        iteracion(i + 1)\n\n\niteracion()\n\n# DIFICULTAD EXTRA:\nfruits_list = [\"Apple\", \"Mango\", \"Peach\", \"Orange\", \"Banana\"]\n\nfor fruit in fruits_list:\n    print(fruit)\n\nfruits_tuple = (\"Apple\", \"Mango\", \"Peach\", \"Orange\", \"Banana\")\n\nfor fruit in fruits_tuple:\n    print(fruit)\n\nfruits_set = {\"Apple\", \"Mango\", \"Peach\", \"Orange\", \"Banana\"}\n\nfor fruit in fruits_set:\n    print(fruit)\n\nstring = \"Hernan\"\n\nfor char in string:\n    print(char)\n\ncountries_capital = {\n    \"USA\": \"Washington D.C.\",\n    \"France\": \"Paris\",\n    \"Egypt\": \"Cairo\",\n    \"Japan\": \"Tokyo\"\n}\n\nfor country in countries_capital.keys():\n    print(country)\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/alanshakir.py",
    "content": "for i in range(1, 11):\n    print(f\"for: {i}\")\n\ni = 1\nwhile i <= 10:\n    print(f\"while: {i}\")\n    i += 1\n\ndef count_recursiva(numero: int):\n    if numero <= 10:\n        print(f\"recursividad: {numero}\")\n        count_recursiva(numero + 1)\n\ncount_recursiva(1) \n\n#extra\n\nfor i in enumerate([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 1):\n    print(i[1])\n\nfor i in reversed(range(1,11)):\n    print(i)\n\nlista = [1,2,3,4,5,6,7,8,9,10]\nfor i in lista:\n    print(i)\n\nfor i in range(len(lista)):\n    print(lista[i])\n\ndict = {'alan': 1, 'shakir': 2, 'ramirez': 3, 'lugo': 4, 'chile': 5, 'santiago': 6, 'puente': 7, 'alto': 8, 'sancarlos': 9, 'skatepark': 10}\nfor i in dict.values():\n    print(i)\n\nset = (1,2,3,4,5,6,7,8,9,10)\nfor i in set:\n    print(i)\n\nlanguages = ['Python', 'C', 'Java', 'Cobol', 'Typescript', 'Javascript']\nfor i in sorted(languages):\n    print(i)\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/any7dev.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n * números del 1 al 10 mediante iteración.\n *\n * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n */ \"\"\"\n\n#EJERCICIO\nfor i in range(1, 11): #1\n    print(i)\n\ni = 1 \nwhile i<=10: #2\n    print(i)\n    i += 1\n\nlista_numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] #3\nfor i in lista_numeros:\n    print(i)\n\n#DIFICULTAD EXTRA\ndef iterar(numero):\n    if numero <= 10:\n        print(numero)\n        iterar(numero+1) #4\n\niterar(1)\n\nfor num in enumerate(lista_numeros): #5\n    print(num)\n\nzip_numeros = zip(lista_numeros) #6\nfor num in zip_numeros:\n    print(num)\n\ndict_numeros = {\"n1\":1, \"n2\":2, \"n3\":3, \"n4\":4, \"n5\":5, \"n6\":6, \"n7\":7, \"n8\":8, \"n9\":9, \"n10\":10}\nfor n, numero in dict_numeros.items(): #7\n    print(n, numero)\n\ndef generador(n):\n    contador = 1\n    while contador <= n:\n        yield contador #8\n        contador += 1\n\nfor numero in generador(10):\n    print(numero)\n\nmi_iterador = iter(lista_numeros) #9\nprint(next(mi_iterador))\nprint(next(mi_iterador))\nprint(next(mi_iterador))\nprint(next(mi_iterador))\nprint(next(mi_iterador))\nprint(next(mi_iterador))\nprint(next(mi_iterador))\nprint(next(mi_iterador))\nprint(next(mi_iterador))\nprint(next(mi_iterador))\n\nprint([num for num in lista_numeros]) #10\n\nlista_numeros15= [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]\n\ndef menores(n):\n    return n <= 10\n\nlista_numeros15_filtrada = filter(menores, lista_numeros15) #11\nprint(list(lista_numeros15_filtrada))\n\nsuma_lista = map(lambda n: n + 0, lista_numeros) #12\nprint(list(suma_lista))\n\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/avcenal.py",
    "content": "\"\"\"\n* EJERCICIO:\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n * números del 1 al 10 mediante iteración.\n\"\"\"\nprint(\"bucle WHILE\")\ni = 0\nwhile i < 10:\n    i +=1\n    print(i)\n\nprint(\"bucle FOR\")\nfor i in range (0,11):\n    print(i)\n\nprint(\"RECURSIVIDAD\")\ndef to_ten(number):\n    if number == 10:\n        print(number)\n    else:\n        print(number)\n        to_ten(number+1)\n\nto_ten(0)\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n\"\"\"\n\nfor k,v in {1:\"a\",2:\"b\",3:\"c\"}.items():\n    print(f\"Clave: {k}, Valor: {v}\")\n\nfor element in [1,2,3,4,5,6,7,8,9,10]:\n    print(element)\n\nfor element in {1,2,3,4,5}:\n    print (element)\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/barrancus.py",
    "content": "# \n# EJERCICIO:\n# Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n# números del 1 al 10 mediante iteración.\n# \n# DIFICULTAD EXTRA (opcional):\n# Escribe el mayor número de mecanismos que posea tu lenguaje\n# para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n# \nemail_listado = [\n    \"usuario123@gmail.com\",\n    \"nombre.apellido@empresa.es\",\n    \"info-ventas@dominio.net\",\n    \"soporte@techsolutions.org\",\n    \"contacto.oficial@servicio.com.mx\",\n    \"j.perez_dev@agencia.io\",\n    \"proyecto_alfa@mailinator.com\",\n    \"laura.fernandez@universidad.edu\",\n    \"admin@misitio.blog\",\n    \"dev_testing_01@testserver.dev\",\n    \"martin-gomez-45@yahoo.es\",\n    \"recepcion@hotelparadise.com\",\n    \"inversiones.2025@finance.co\",\n    \"cliente-vip@premiumservices.us\",\n    \"marta.sanz@publicaciones.cat\",\n    \"notificaciones@appmovil.net\",\n    \"registro_temporal@tempmail.org\",\n    \"elena.rodriguez.s@otroservidor.net\",\n    \"secretaria.ejecutiva@consorcio.es\",\n    \"postmaster@localhost.localdomain\" # Un email técnico\n]\n\ndef serparacion(cadena) -> str:\n    print('{}'.format(cadena * 20))\n\nclass MyIteratorNext:\n    def __iter__(self):\n        self.a = 1\n        return self\n    \n    def __next__(self):\n        x = self.a\n        self.a += 1\n        return x\n\nclass MyIteratorExp:\n    def __iter__(self):\n        self.a = 2\n        return self\n    \n    def __next__(self):\n        x = self.a\n        self.a *= 2\n        return x\n\ndef day_of_week(): # Es un bucle infinito\n    i = 0\n    days= [\"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\", \"Sunday\"]\n    while True:\n        yield days[i % 7]\n        i += 1\n\ndef colours():\n    while True:\n        yield \"black\"\n        yield \"yellow\"\n        yield \"orange\"\n        yield \"blue\"\n\ndef main():\n    for num in range(1,11):\n        print(num)\n    serparacion('-***-')\n\n    numb = 1\n    while numb <= 10:\n        print(numb)\n        numb += 1\n    serparacion('-***-')\n\n    print([n + 1 for n in range(10)])\n    serparacion('-***-')\n\n    for mail in email_listado:\n        print(mail)\n    serparacion('-***-')\n\n    myiterator = MyIteratorNext()\n    myiter = iter(myiterator)\n    while myiter.a <= 10:\n        print(myiter.a)\n        next(myiter)\n    serparacion('-***-')\n\n    myiteratorexp = MyIteratorExp()\n    myitere = iter(myiteratorexp)\n    while myitere.a <= 1024:\n        print(myitere.a)\n        next(myitere)\n    serparacion('-***-')\n\n    counter = 0\n    for x in day_of_week():\n        if counter >= 7:\n            break\n        print(x)\n        counter += 1\n    serparacion('-***-')\n\n    colour = colours()\n    counter = 0\n    for x in range(8):\n        print(next(colour))\n    serparacion('-***-')\n        \nmain()\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/cesar-ch.py",
    "content": "\"\"\"\n    * #17 ITERACIONES\n\"\"\"\n\nnumeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n# 1. Bucle for\nfor i in range(len(numeros)):\n    print(numeros[i])\n\n# 2. Bucle while\ni = 0\nwhile len(numeros) < 10:\n    print(numeros[i])\n    i += 1\n\n# 3. Bucle for with step\nfor i in range(0, 10, 2):\n    print(numeros[i])\n\n\"\"\"\n    * DIFICULTAD EXTRA\n\"\"\"\n\n# 4. Bucle with lambda\nnumeros.sort(key=lambda x: x)\nprint(numeros)\n\n# 5. Bucle with enumerate\nfor i, numero in enumerate(numeros):\n    print(numero)\n\n# 6. Bucle with zip\nfor i, numero in enumerate(zip(numeros, numeros)):\n    print(numero)\n\n# 7. Bucle with filter\nnumeros_pares = list(filter(lambda x: x % 2 == 0, numeros))\nprint(numeros_pares)\n\n# ...\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/cristianfloyd.py",
    "content": "# EJERCICIO:\n# Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n# números del 1 al 10 mediante iteración.\n\ndef bucle_for():\n    for i in range(1,11):\n        print(f\"Bucle FOR - numero: {i}\")\n\n\ndef bucle_while():\n    i: int = 1\n    while i <= 10:\n        print(f\"Bucle while - numero: {i}\")\n        i += 1\n\n# recursividad\n\ndef bucle_recursivo(i: int = 1):\n    if i > 1:\n        bucle_recursivo(i - 1)\n    print(f\"Funcion recursiva: {i}\")\n\n\nbucle_for()\nbucle_while()\nbucle_recursivo(10)\n\n\n#\n# DIFICULTAD EXTRA (opcional):\n# Escribe el mayor número de mecanismos que posea tu lenguaje\n# para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n\nprint(\"=\" * 80)\nprint(\"DIFICULTAD EXTRA (opcional):\")\nprint(\"Escribe el mayor número de mecanismos que posea tu lenguaje\")\nprint(\"para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\")\nprint(\"=\" * 80)\n\n# Mecanismos de iteracion\n\n# 1. For con range\nfor i in range(1, 11):\n    print(f\"For con range - numero: {i}\")\n\n# 2. For con lista\nfor i in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]:\n    print(f\"For con lista - numero: {i}\")\n\n# 3. For con tupla\nfor i in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10):\n    print(f\"For con tupla - numero: {i}\")\n\n# 4. For con set\nfor i in {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}:\n    print(f\"For con set - numero: {i}\")\n\n# 5. For con diccionario\nfor i, value in {1: \"a\", 2: \"b\", 3: \"c\", 4: \"d\", 5: \"e\", 6: \"f\", 7: \"g\", 8: \"h\", 9: \"i\", 10: \"j\"}.items():\n    print(f\"For con diccionario - numero: {i} - valor: {value}\")\n\n# 6. For con string\nfor i in \"Hello, World!\":\n    print(f\"For con string - caracter: {i}\")\n\n# 7. For con enumerate\nfor i, value in enumerate(\"Hello, World!\"):\n    print(f\"For con enumerate - numero: {i} - valor: {value}\")\n\n# 8. For con zip\nfor i, value in zip([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\", \"h\", \"i\", \"j\"]):\n    print(f\"For con zip - numero: {i} - valor: {value}\")\n\n# 9. For con reversed\nfor i in reversed([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]):\n    print(f\"For con reversed - numero: {i}\")\n\n# 10. For con sorted\nfor i in sorted([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]):\n    print(f\"For con sorted - numero: {i}\")\n\n# 11. For con generator\nfor i in (i for i in range(1, 11)):\n    print(f\"For con generator - numero: {i}\")\n\n# 12. For con iter\nfor i in iter([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]):\n    print(f\"For con iter - numero: {i}\")\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/danielhdzr.py",
    "content": "# #17 ITERACIONES\n#### Dificultad: Fácil | Publicación: 22/04/24 | Corrección: 29/04/24\n\n'''\n* EJERCICIO:\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n * números del 1 al 10 mediante iteración.\n *\n * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n'''\n\n# Metodo 1\nlista_numeros = [1,2,3,4,5,6,7,8,9,10]\nfor i in lista_numeros:\n    print(i)\nprint(\"Fin de iteracion 1\")\n\n# Metodo 2\nnumero = 0 \nwhile True:\n    numero += 1\n    if numero <= 10:\n        print(numero)\n    else: \n        print(\"Fin de iteracion 2\")\n        break\n\n# Metodo 3\nfor i in range(10):\n    print(i+1)\nprint(\"Fin de iteracion 3\")\n\n# Metodo 4\nnumero = 10\nfor i in range(1, numero+1):\n    print(i)\nprint(\"Fin de iteracion 4\")\n\n# Metodo 5\ndef iteracion(iter_num):\n    numeros = []\n    for i in range(iter_num):\n        numeros.append(i)\n    for j in (numeros):\n        print(j+1)\n    return(\"Fin de iteracion 5\")\nprint(iteracion(10))\n\nnumeros = 10\nprint(*[i+1 for i in range(numeros)], sep=\"\\n\")\nprint(\"Fin de iteracion 6\")\n\nfor i in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]:\n    print(i)\nprint(\"Fin de iteracion 7\")\n\nfor i in {1: \"a\", 2: \"b\", 3: \"c\", 4: \"d\", 5: \"e\", 6: \"f\", 7: \"g\", 8: \"h\", 9: \"i\", 10: \"j\"}.values():\n    print(i)\nprint(\"Fin de iteracion 8\")\n\nprint(*[i for i in range(1, 11)], sep=\"\\n\")\nprint(\"Fin de iteracion 9\")"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/davidrguez98.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n * números del 1 al 10 mediante iteración.\n *\n * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n */ \"\"\"\n\n#EJERCICIO\n\nfor i in range(1,11):\n    print(i)\n\ni = 1\nwhile i <= 10:\n    print(i)\n    i += 1\n\ndef counter(i):\n    if i <= 10:\n        print(i)\n        counter(i+1)\ncounter(1)\n\n#DIFICULTAD EXTRA\n\ndef automatic_counter_for(count = 1):\n    for count in range(1,11):\n        if count <= 10:\n            print(count)\n            count += 1\n        else:\n            pass\n\nautomatic_counter_for()\n\ndef automatic_counter_while(count = 1):\n    while count <= 10:\n        print(count)\n        count += 1\n\nautomatic_counter_while()"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/didacdev.py",
    "content": "if __name__ == '__main__':\n    # Método 1\n    for i in range(1, 11):\n        print(i)\n\n    # Método 2\n    i = 1\n    while i <= 10:\n        print(i)\n        i += 1\n\n    # Método 3\n    list(map(print, range(1, 11)))\n\n    # Método 4\n    numbers = list(range(1, 11))\n    iterator = iter(numbers)\n\n    try:\n        while True:\n            number = next(iterator)\n            print(number)\n    except StopIteration:\n        pass\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/duendeintemporal.py",
    "content": "#17 { Retos para Programadores } ITERACIONES\n\n# Bibliography reference\n# Professional JavaScript for web developers by Matt Frisbie [Frisbie, Matt] (z-lib.org)\n#Python Notes for Professionals. 800+ pages of professional hints and tricks (GoalKicker.com) (Z-Library)\n# Additionally, I use GPT as a reference and sometimes to correct or generate proper comments.\n\n\"\"\"\n* Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n * números del 1 al 10 mediante iteración.\n *\n * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n\n\"\"\"\n\nimport time\n\n# Short for print\nlog = print\n\nlog('Retosparaprogramadores #17')\n\n# For loop\nfor i in range(1, 11):\n    log(i) # logs nums from 1 to 10\n\n# While loop\ncount = 0\nwhile count < 10:\n    count += 1\n    log(count) # logs nums from 1 to 10\n\n# forEach equivalent using a for loop\nnums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\nfor n in nums:\n    log(n) # logs nums from 1 to 10 \n\n# Extra Difficulty Exercise\n\n# do while equivalent using a while loop\ni = 0\nwhile True:\n    log(i) # will log nums form 0 to 4\n    i += 1\n    if i >= 5:\n        break\n\n# map equivalent using list comprehension\narr = [1, 2, 3, 4, 5]\ndoubled = [value * 2 for value in arr]\nlog(doubled)  # [2, 4, 6, 8, 10]\n\n# filter equivalent using list comprehension\narr1 = [1, 2, 3, 4, 5]\neven_numbers = [value for value in arr1 if value % 2 == 0]\nlog(even_numbers)  # [2, 4]\n\n# reduce equivalent using functools.reduce\nfrom functools import reduce\narr2 = [1, 2, 3, 4, 5]\nsum_result = reduce(lambda total, current: total + current, arr2, 0)\nlog(sum_result)  # 15\n\n# some equivalent using any()\narr3 = [1, 2, 3, 4, 5]\nhas_even = any(value % 2 == 0 for value in arr3)\nlog(has_even)  # True\n\n# every equivalent using all()\narr4 = [1, 2, 3, 4, 5]\nall_even = all(value % 2 == 0 for value in arr4)\nlog(all_even)  # False\n\n# For of equivalent using a for loop\narr5 = [1, 2, 3, 4, 5]\nfor value in arr5:\n    log(value)  # Logs: 1 2 3 4 5\n\n# Iteration with enumerate (similar to entries)\narr6 = ['a', 'b', 'c']\nfor index, value in enumerate(arr6):\n    log(index, value)  # 0 a 1 b 2 c 3\n\n# Iteration with items (similar to Object.entries)\nobj1 = {'a': 1, 'b': 2, 'c': 3}\nfor key, value in obj1.items():\n    log(key, value)  # a 1 b 2 c 3\n\n# Iteration with keys\narr7 = ['a', 'b', 'c']\nfor index in range(len(arr7)):\n    log(index)  # 0 1 2\n\n# Iteration with keys of a dictionary\nobj2 = {'a': 1, 'b': 2, 'c': 3}\nfor key in obj2.keys():\n    log(key)  # a b c\n\n# Iteration with values\narr8 = ['a', 'b', 'c']\nfor value in arr8:\n    log(value)  # a b c\n\n# Iteration with values of a dictionary\nobj3 = {'a': 1, 'b': 2, 'c': 3}\nfor value in obj3.values():\n    log(value)  # 1 2 3\n\n# For in equivalent using a for loop\nobj = {'a': 1, 'b': 2, 'c': 3}\nfor key in obj:\n    log(f\"{key}: {obj[key]}\")  #  a: 1 b: 2 c: 3\n\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/fborjalv.py",
    "content": "\n\n\n\"\"\"\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n * números del 1 al 10 mediante iteración.\n *\n\"\"\"\n# Opción 1: for\n\nfor i in range(1, 11):\n    print(i)\n\nj = 1\nwhile j < 11: \n    print(j)\n    j +=1\n\ndef ten_numbers(num):\n    if num < 11:\n        print(num)\n        return ten_numbers(num+1)\n\nten_numbers(1)\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n */\n\"\"\"\nlista_num = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n\nprint(lista_num[::1])"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/garos01.py",
    "content": "# Método 1: Utilizando un bucle for\nprint(\"Metodo 1: Utilizando un bucle for\")\nfor i in range(1, 11):\n    print(i)\n\n\n# Método 2: Utilizando un bucle while\nprint(\"Metodo 2: Utilizando un bucle while\")\ni = 1\nwhile i <= 10:\n    print(i)\n    i += 1\n\n\n# Metodo 3: Simulando un bucle do while en Python\nprint(\"Metodo 3: Simulando un bucle do while en Python\")\ni = 1\nwhile True:\n    print(i)\n    i += 1\n    if i > 10:\n        break\n\n\n# Ejercicio extra\n\n# Bucle for con range()\nprint(\"Bucle for con range():\")\nfor i in range(1, 11):\n    print(i)\n\n# Bucle for con elementos de una lista\nprint(\"\\nBucle for con elementos de una lista:\")\nnumeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\nfor num in numeros:\n    print(num)\n\n# Bucle for con elementos de una tupla\nprint(\"\\nBucle for con elementos de una tupla:\")\nnumeros = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)\nfor num in numeros:\n    print(num)\n\n# Bucle for con elementos de un conjunto (set)\nprint(\"\\nBucle for con elementos de un conjunto (set):\")\nnumeros = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}\nfor num in numeros:\n    print(num)\n\n# Bucle for con elementos de un diccionario\nprint(\"\\nBucle for con elementos de un diccionario:\")\nnumeros = {\n    1: \"uno\",\n    2: \"dos\",\n    3: \"tres\",\n    4: \"cuatro\",\n    5: \"cinco\",\n    6: \"seis\",\n    7: \"siete\",\n    8: \"ocho\",\n    9: \"nueve\",\n    10: \"diez\",\n}\nfor key, value in numeros.items():\n    print(key, value)\n\n# Utilizando la función map() junto con print()\nprint(\"\\nUtilizando la función map() junto con print():\")\nnumeros = list(range(1, 11))\nprint(*map(str, numeros), sep=\"\\n\")\n\n# Utilizando una comprensión de lista\nprint(\"\\nUtilizando una comprensión de lista:\")\n[num for num in range(1, 11)]\n\n# Utilizando el operador enumerate()\nprint(\"\\nUtilizando el operador enumerate():\")\nfor idx, num in enumerate(range(1, 11)):\n    print(idx + 1, num)\n\n# Utilizando la función itertools.count()\nprint(\"\\nUtilizando la función itertools.count():\")\nimport itertools\n\nfor num in itertools.count(start=1, step=1):\n    if num > 10:\n        break\n    print(num)\n\n# Utilizando un iterador personalizado\nprint(\"\\nUtilizando un iterador personalizado:\")\n\n\nclass Contador:\n    def __init__(self, start, end):\n        self.current = start\n        self.end = end\n\n    def __iter__(self):\n        return self\n\n    def __next__(self):\n        if self.current > self.end:\n            raise StopIteration\n        else:\n            self.current += 1\n            return self.current - 1\n\n\ncontador = Contador(1, 10)\nfor num in contador:\n    print(num)\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/ggilperez.py",
    "content": "# 17 Iterators\nimport itertools\n\n# For loop\nprint(\"For\")\nfor i in range(1, 11):\n    print(i)\nprint()\n\n# While\nprint(\"While\")\ni = 1\nwhile i <= 10:\n    print(i)\n    i += 1\nprint()\n\n# Recursion\nprint(\"Recursion\")\n\n\ndef countdown(i=1):\n    print(i)\n    if i == 10:\n        return\n    return countdown(i + 1)\n\n\ncountdown()\nprint()\n\n# Extra\n\n# List can be iterable\nmy_list = [1, 2, 3, 4]\nfor item in my_list:\n    print(item)\n\n# Also sets, tuples, dict, strings\nfor item in (1, 2, 3, 4):\n    print(item)\nfor item in {1, 2, 3, 4}:\n    print(item)\nfor item in {\"one\": 1, \"two\": 2}:\n    print(item)\nfor item in \"Hello World\":\n    print(item)\n\n# For loop in comprehensions\nprint([item for item in my_list])\nprint((item for item in my_list))\nprint({item for item in my_list})\nprint({str(item): item for item in my_list})\n\n# Map\nprint(list(map(lambda x: x ** 2, my_list)))\n\n# Filter\nprint(list(filter(lambda x: x % 2 == 0, my_list)))\n\n# Reverse an iterable\nfor item in reversed(my_list):\n    print(item)\n\n# Sorted an iterable\nfor item in sorted([4,2,1,3]):\n    print(item)\n\n# Enumerate\nfor index, item in enumerate([\"one\", \"two\", \"three\"]):\n    print(f\"{index = }, {item = }\")\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/gringoam.py",
    "content": "\"\"\"\nEjercicio\n\"\"\"\n\nfor i in range(1,11):\n   print(i)\n\ni=1\nwhile i <=10 :\n    print(i)\n    i+=1\n\ndef contador(i=1):\n    if i<=10:\n        print(i)\n        contador(i+1)\n   \n        \n\ncontador()\n\n\"\"\"\nExtra\n\"\"\"\nfor e in [1, 2, 3, 4]:\n    print(e)\n\nfor e in {1, 2, 3, 4}:\n    print(e)\n\nfor e in (1, 2, 3, 4):\n    print(e)\n\nfor e in {1: \"a\", 2: \"b\", 3: \"c\", 4: \"d\"}:\n    print(e)\n\nfor e in {1: \"a\", 2: \"b\", 3: \"c\", 4: \"d\"}.values():\n    print(e)\n\nprint(*[i for i in range(1,11)], sep=\"\\n\")\n\nfor c in \"Python\":\n    print(c)\n\nfor e in reversed([1, 2, 3, 4]):\n    print(e)\n\nfor e in sorted([\"m\", \"o\", \"u\", \"r\", \"e\"]):\n    print(e)\n\nfor i, e in enumerate(sorted([\"m\", \"o\", \"u\", \"r\", \"e\"])):\n    print(f\"Índice: {i}, valor: {e}\")"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/hectorio23.py",
    "content": "# /bin/python3\n# Author: Héctor Adán\n# GitHub: https://github.com/hectorio23\n'''\nEJERCICIO:\nUtilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\nnúmeros del 1 al 10 mediante iteración.\n\nDIFICULTAD EXTRA (opcional):\nEscribe el mayor número de mecanismos que posea tu lenguaje\npara iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n'''\n\n##################################################################\n############################ EJERCICIO ###########################\n##################################################################\nprint(\"[ Mecanismo 1 ] -> objeto range\") # objeto RANGE\nfor element in range(1, 11):\n    print(element, end=\", \")\n\nprint(\"\\n\\n[ Mecanismo 2 ] -> usando una lista\") # lista por comprension -> lista normal\nfor element in [item for item in range(1,11)]:\n    print(element, end=\", \")\n\nprint(\"\\n\\n[ Mecanismo 3 ] -> usando un set\") # set por comprension -> set normal\nfor element in {item for item in range(1,11)}:\n    print(element, end=\", \")\n\nprint(\"\\n\\n[ Mecanismo 4 ] -> usando un diccionario\") # dictionary por comprension -> dictionary normal\nfor element in {item:item for item in range(1,11)}:\n    print(element, end=\", \")\n\nprint(\"\\n\\n[ Mecanismo 5 ] -> usando una cadena\") # iterar los elementos de una cadena \nfor element in \"0123456789\":\n    print(int(element) + 1, end=\", \")\n\nprint(\"\\n\\n[ Mecanismo 6 ] -> usando recursividad\") # recursivo n veces -> en python el limite por defecto es 1,000\ndef recursivo(n):\n    print(n, end=\", \")\n\n    if n == 1:\n        return 1\n    \n    return n * recursivo(n - 1)\n\nrecursivo(10)\n\nprint(\"\\n\\n[ Mecanismo 7 ] -> usando un 'iterator'\") # usando iterador\nfor element in iter(range(1,11)): \n    print(element, end=', ')\n\nprint(\"\\n\\n[ Mecanismo 8 ] -> usando zip\") # usando zip\nfor element in zip(range(1,11), [x for x in range(1,11)]):\n    print(element[0], end=', ')\n\nprint(\"\\n\\n[ Mecanismo 9 ] -> usando enumerate\") # usando enumerate\nfor element in enumerate([x for x in range(1,11)], 1):\n    print(element[0], end=', ')\n\nprint(\"\\n\\n[ Mecanismo 10 ] -> usando bucle while\")\nn = 1\nwhile n <= 10:\n    print(n, end=', ')\n    n += 1\nlog = lambda value: print(value, end=', ') \nprint(\"\\n\\n[ Mecanismo 11 ] -> usando la funcion map\")\nlist(map(log, [ x for x in range(1, 11) ] ))\n\n\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/hozlucas28.py",
    "content": "# pylint: disable=missing-function-docstring,pointless-string-statement,expression-not-assigned,unnecessary-lambda\n\n\"\"\"\n    Iterations...\n\"\"\"\n\nfrom typing import Literal\n\n\nprint(\"Iterations...\")\n\nSTART: Literal[1] = 1\nEND: Literal[10] = 10\n\n\ndef recursive_fn(*, end: int, start: int) -> None:\n    print(start)\n    if start < end:\n        recursive_fn(\n            end=end,\n            start=start + 1,\n        )\n\n\nprint(\"\\nFirst method...\\n\")\nrecursive_fn(end=END, start=START)\n\nprint(\"\\nSecond method...\\n\")\nfor i in range(START, END + 1):\n    print(i)\n\n\nprint(\"\\nThird method...\\n\")\nj = START\nwhile j <= END:\n    print(j)\n    j += 1\n\n\nprint(\n    \"\\n# ---------------------------------------------------------------------------------- #\\n\"\n)\n\n\"\"\"\n    Additional challenge...\n\"\"\"\n\nprint(\"Additional challenge...\")\n\nprint(\"\\nFirst method...\\n\")\nrecursive_fn(end=END, start=START)\n\nprint(\"\\nSecond method...\\n\")\nfor i in range(START, END + 1):\n    print(i)\n\n\nprint(\"\\nThird method...\\n\")\nj = START\nwhile j <= END:\n    print(j)\n    j += 1\n\nprint(\"\\nFourth method...\\n\")\n[print(i) for i in range(START, END + 1)]\n\nprint(\"\\nFifth method...\\n\")\nlist(map(lambda i: print(i), range(START, END + 1)))\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/idiegorojas.py",
    "content": "# Iteraciones\n\n\"\"\"\nEs el proceso de repetir una serie de instrucciones o pasos varias veces\nEn python se suele manejar con los bucles 'for' y 'while'.\n\"\"\"\n\n# Bucle for\n\"\"\"\nSe usa cuando cuando se sabe cuantas veces que quiere repetir algo.\nCundo se quiere recorrer una secuencia (lista, tupla, cadena o rango)\n\"\"\"\n\n\"\"\"\nfor variable in secuencia:\n    pass # codigo a ejecutar en cada secuencia\n\"\"\"\n\n# Imprimir los numeros del 1 al 5\nfor i in range(1, 6):\n    print(i)\n\n\nprint('-----------------')\n\n\n\n# i toma el valor de la secuncia generada por range() y el bucle itera 5 veces\n\nfrutas = ['Manzana', 'Uva', 'Pera']\nfor fruta in frutas:\n    print(f'Me gusta la {fruta}')\n\n\nprint('-----------------')\n\n\n\n# Bucle while\n\"\"\"\nSe usa cuando no se sabe exactamente cuantas veces se necesita iterar.\nTiene una condicion que determina cuando debe parar.\n\"\"\"\n\n\"\"\"\nwhile condicion:\n    pass # Codigo que se ejecuta mientras la condicion es verdadera\n\"\"\"\n\n# Contar del 1 al 5\ncontador = 0\nwhile contador <= 5:\n    print(contador)\n    contador += 1 # Incrementa el contador en 1\n# Si no se incrementa el contador el bucle sera infinito\n\n\n\nprint('-----------------')\n\n\n\n# Iterables e iteradores\n\"\"\"\nIterable:\n    Es cualquier objeto que se puede recorrer elemento por elemento\n    Listas, cadenas, diccionarios.\n\nIteradores:\n    Son objetos que implementan los metodos 'iter()' y 'next()' para controlar como se recorre el iterable\n\"\"\"\n\n# Iterar hasta el numero 3\nlista = [1, 2, 3, 4, 5]\niterador = iter(lista)\nprint(next(iterador))\nprint(next(iterador))\nprint(next(iterador))\n\n\nprint('-----------------')\n\n\n\n# Comprensiones \n\"\"\"\nEs una forma mas elegante y concisa de iterar\n\"\"\"\n\ncuadrados = [x**2 for x in range(1, 5)]\nprint(cuadrados)\n\n\n\nprint('-----------------')\n\n\n\n# Break y continue\n\"\"\"\nBreak: Termina el bucle antes de tiempo\nContinue: Salta a la sigueinte iteracion sin ejecutar el coidgo en esa vuelta.\n\"\"\"\n\nfor i in range(1, 6):\n    if i == 3:\n        continue # Salta el 3\n    if i == 5:\n        break # Termina en 5\n    print(i)\n\n\nprint('-----------------')\n\n\n# Ejercicio\nfor i in range(1, 11):\n    print(i)\n\n\nprint('-----------------')\n\ncontador = 1\nwhile contador <= 10:\n    print(contador)\n    contador += 1\n\n\nprint('-----------------')\n\ncontador = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\niterador = iter(contador)\nprint(next(iterador))\nprint(next(iterador))\nprint(next(iterador))\nprint(next(iterador))\nprint(next(iterador))\nprint(next(iterador))\nprint(next(iterador))\nprint(next(iterador))\nprint(next(iterador))\nprint(next(iterador))\n\n\nprint('-----------------')\n\n\ndef contar_hasta_diez(i=1):\n    if i <= 10:\n        print(i)\n        contar_hasta_diez(i+1)\n\ncontar_hasta_diez()\n\nprint('-----------------')\n\n\n\n# Extra\n\n# iterar una lista\nfor i in [1,2,3,4,5]:\n    print(i)\n\n\nprint('-----------------')\n\n# Iterar un tupla\nfor i in (1,2,3,4,5):\n    print(i)\n\n\nprint('-----------------')\n\n\n# Iterar un diccionario\nfor i in {1,2,3,4,5}:\n    print(i)\n\nprint('-----------------') \n\n\n# Iterar un diccionario por Clave\nfor i in {'a': 1, 'b': 2, 'c':3, 'd': 4, 'e':5}:\n    print(i)\n\nprint('-----------------')\n\n# Iterar un diccionario por Valor\nfor i in {'a': 1, 'b': 2, 'c':3, 'd': 4, 'e':5}.values():\n    print(i)\n\nprint('-----------------')\n\nfor i in 'Python':\n    print(i)\n\nprint('-----------------')\n\nfor i in reversed('Python'):\n    print(i)\n\nprint('-----------------')\n\nfor i in sorted('python'):\n    print(i)\n\nprint('-----------------')\n\nfor i, e in enumerate(sorted([\"p\", \"y\", \"t\", \"h\", \"o\", \"n\"])):\n    print(f\"Índice: {i}, valor: {e}\")"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/ignaciovihe.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n * números del 1 al 10 mediante iteración.\n\"\"\"\n\n#FOR\n\nfor i in range(1,11):\n    print(i)\n\n\n#WHILE\n\ni=1\nwhile i < 11:\n    print(i)\n    i += 1\n\n\n#RECURSIVIDAD\n\ndef increment(i = 1):\n    if i < 11:\n        print(i)\n        increment(i + 1)\n        \nincrement()\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n\"\"\"\n\n#1 For con set\n\nlanguages = {\"python\", \"javascript\", \"html\", \"css\"}\nfor language in languages:\n    print(language)\n\n\n#2 For con tupla\n\nlanguages = (\"python\", \"javascript\", \"html\", \"css\")\nfor language in languages:\n    print(language)\n\n\n#3 For con lista\n\nlanguages = [\"python\", \"javascript\", \"html\", \"css\"]\nfor language in languages:\n    print(language)\n\n\n#4 for con dict\n\nlanguages = {\"1\": \"python\", \"2\": \"javascript\", \"3\": \"html\", \"4\": \"css\"}\nfor language in languages:\n    print(language)\n\n\n#5 for con dict y values\n\nlanguages = {\"1\": \"python\", \"2\": \"javascript\", \"3\": \"html\", \"4\": \"css\"}\nfor language in languages.values():\n    print(language)\n\n\n#5 for con dict y enumerate\n\nlanguages = {\"1\": \"python\", \"2\": \"javascript\", \"3\": \"html\", \"4\": \"css\"}\nfor key, value in languages.items():\n    print(f\"{key}: {value}\")\n\n\n#6 while\n\nlanguages = [\"python\", \"javascript\", \"html\", \"css\"]\nwhile languages:\n    print(languages.pop(0))\n\n\n#7 For con enumerate\n\nlanguages = [\"python\", \"javascript\", \"html\", \"css\"]\nfor index, language in enumerate(languages):\n    print(f\"{index} : {language}\")\n\n\n#8 Generador y print\n\nprint(*[i for i in range(1, 11)], sep=\"\\n\")\n\n\n#9 Str\n\nmy_str = \"Hello Python\"\nfor char in my_str:\n    print(char)\n\n\n#10 intertools-cycle\n\nfrom itertools import cycle\n\ncolors = [\"red\", \"yellow\", \"green\"]\ncicle = cycle(colors)\nfor i in range(9):\n    print(next(cicle))\n\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/isilanes.py",
    "content": "def m1():\n    print(\"== (m1) for loop simple ==\")\n    for i in range(1, 11):\n        print(i)\n\n\ndef m2():\n    print(\"== (m2) print dentro de loop comprehension ==\")\n    [print(i) for i in range(1, 11)]\n\n\ndef m3():\n    print(\"== (m3) imprimir lista completa formada desde generador ==\")\n    print(list(range(1, 11)))\n\n\ndef e1():\n    print(\"== (e1) for loop sobre generador ==\")\n    for i in range(3):\n        print(f\"Valor {i} OK\")\n\n\ndef e2():\n    print(\"== (e2) for loop sobre lista ==\")\n    for c in [\"a\", \"b\", \"c\"]:\n        print(f\"Valor {c} OK\")\n\n\ndef e3():\n    print(\"== (e3) for loop sobre tupla ==\")\n    for v in (True, False, None, Ellipsis):\n        print(f\"Valor {v} OK\")\n\n\ndef e4():\n    print(\"== (e4) for loop sobre cadena ==\")\n    for c in \"hola\":\n        print(f\"Valor {c} OK\")\n\n\ndef e5():\n    print(\"== (e5) for loop sobre clave/valor de diccionario ==\")\n    d = {f\"k{i}\": f\"v{i}\" for i in range(3)}\n    for k, v in d.items():\n        print(f\"Clave {k} -> Valor {v} OK\")\n\n\ndef e6():\n    print(\"== (e6) dict comprehension para construir diccionarios (usado también en e5) ==\")\n    print({f\"k{i}\": f\"v{i}\" for i in range(3)})\n\n\ndef e7():\n    print(\"== (e7) list comprehension para construir lista ==\")\n    print([i**2 for i in range(5)])\n\n\ndef e8():\n    print(\"== (e8) comprehension para construir generador ==\")\n    g = (i**2 for i in range(5))\n    print(\"Generador:\", g)\n    print(\"Lista desde generador:\", list(g))\n\n\ndef e9():\n    print(\"== (e9) comprehension para construir set ==\")\n    print({abs(i) for i in range(-5, 3)})\n\n\ndef e10():\n    print(\"== (e10) map para procesar enumerable ==\")\n    print(list(map(int, [1.1, 2.2, 3.3, 4.5])))\n\n\ndef main():\n    print(\"==== MAIN ====\")\n    for fun in (m1, m2, m3):\n        fun()\n\n\ndef extra():\n    print(\"==== EXTRA ====\")\n    for fun in (e1, e2, e3, e4, e5, e6, e7, e8, e9, e10):\n        fun()\n\n\nif __name__ == \"__main__\":\n    main()\n    extra()\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/javierfiestasbotella.py",
    "content": "'''EJERCICIO:\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n * números del 1 al 10 mediante iteración.\n *\n * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n */'''\n\nfor i in range(1,11):\n  print(i)\n#___________________________\nprint()\nn=1\nwhile n<11:\n  print(n)\n  n+=1\n#___________________________\nprint()\ndef secuencia(n):\n  if n==10:\n    print(10)\n  else:\n    print(n)\n    secuencia(n+1)\nsecuencia(1)\n\n#___________________________\nprint()\nprint(*[i+1 for i in range(10) if i <11])"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/jptxaya.py",
    "content": "# #17 ITERACIONES\n#### Dificultad: Fácil | Publicación: 22/04/24 | Corrección: 29/04/24\n\n## Ejercicio\n\n# \"\"\" ```\n# /*\n#  * EJERCICIO:\n#  * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n#  * números del 1 al 10 mediante iteración.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Escribe el mayor número de mecanismos que posea tu lenguaje\n#  * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n#  */ \"\"\"\n\nprint(\"For\")\nfor i in range(1,11):\n    print(i)\n\nprint(\"While\")\ni = 1\nwhile i <= 10:\n    print(i)\n    i+=1\n\nprint(\"Recursity\")\ndef print_counter(num):\n    if num < 11:\n        print(num)\n        print_counter(num + 1)\n\nprint_counter(1)\n\nprint(\"Dificultad Extra\")\n\nfor i in [1,2,3,4,6,7,8,9,10]:\n    print(i)\n\nfor i in (1,2,3,4,5,6,7,8,9,10):\n    print( i)\n\nfor i in {1,2,3,4,5,6,7,8,9,10}:\n    print(i)\n\nmy_dict = {1:\"a\",2:\"b\",3:\"c\"}\nfor k in my_dict.keys():\n    print(k)\n\nfor k,v in my_dict.items():\n    print(k)"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/juanchernandezdev.py",
    "content": "### Python Iteration ###\n\n#! for loop\nfor num in range(1, 11):\n  print(num)\n\n#! while loop\nnum = 1\n\nwhile num <= 10:\n  print(num)\n  num += 1\n  \n#! recursion\ndef num_printer(num = 1):\n  if num > 10:\n    return\n  \n  print(num)\n  num_printer(num + 1)\n\nnum_printer()\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/juandaherrera.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n * números del 1 al 10 mediante iteración.\n\n\"\"\"\n\nfor i in range(1, 11):\n    print(i)\n\ni = 1\nwhile i <= 10:\n    print(i)\n    i += 1\n\n\ndef count_ten(i=1):\n    if i <= 10:\n        print(i)\n        count_ten(i + 1)\n\n\ncount_ten()\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/juanmax2.py",
    "content": "\"\"\"\nIteraciones\n\"\"\"\n# For\nfor i in range(1,11):\n    print(i)\n\n# Recursividad\ndef contador(num = 1):\n    \n    if num <= 10:\n        print(num)\n        contador(num + 1)\n    \ncontador()\n\n# While\nnum = 1\nwhile num <= 10:\n    print(num)\n    num += 1 \n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n */\n\"\"\"\n\n# For in lista\nfor e in [1, 2, 3, 4]:\n    print(e)\n    \n# For in set\nfor e in {1, 2, 3, 4}:\n    print(e)\n\n# For in dict\nfor e in {1: \"a\", 2: \"b\", 3: \"c\", 4: \"d\"}:\n    print(e)\n\nprint(*[i for i in range(1, 11)], sep=\"\\n\")\n\n# For cadena de texto\nfor w in \"Python\":\n    print(w)\n\n# For en lista revertida\nfor e in reversed([1, 2, 3, 4]):\n    print(e)\n\n# For en una cadena de texto ordenada\nfor e in sorted([\"j\", \"u\", \"a\", \"n\", \"m\", \"a\"]):\n    print(e)\n\n# For con enumerate \nfor i, e in enumerate([\"j\", \"u\", \"a\", \"n\", \"m\", \"a\"]):\n    print(i, e)"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/juanppdev.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n * números del 1 al 10 mediante iteración.\n\"\"\"\n\nfor i in range(1, 11):\n    print(i)\n\ni = 1\nwhile i <= 10:\n    print(i)\n    i += 1\n\n\n[print(i) for i in range(1, 11)]\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n\"\"\"\n\nfor i in range(1, 11):\n    print(i)\n\ni = 1\nwhile i <= 10:\n    print(i)\n    i += 1\n\n[print(i) for i in range(1, 11)]\n\nlist(map(lambda x: print(x), range(1, 11)))\n\nlist(filter(lambda x: print(x) or True, range(1, 11)))\n\nfrom functools import reduce\nreduce(lambda _, x: print(x), range(1, 11), None)\n\niterator = iter(range(1, 11))\nfor i in iterator:\n    print(i)\n\nfor index, value in enumerate(range(1, 11), start=1):\n    print(value)\n\nfor i, _ in zip(range(1, 11), range(1, 11)):\n    print(i)\n\nimport itertools\ncounter = itertools.cycle(range(1, 11))\nfor _ in range(10):\n    print(next(counter))\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/kenysdev.py",
    "content": "# ╔═════════════════════════════════════╗\n# ║ Autor:  Kenys Alvarado              ║\n# ║ GitHub: https://github.com/Kenysdev ║\n# ║ 2024 -  Python                      ║\n# ╚═════════════════════════════════════╝\n\n# -----------------------------------\n# * ITERACIONES\n# -----------------------------------\n\n\"\"\"\n * EJERCICIO #1:\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n * números del 1 al 10 mediante iteración.\n\"\"\"\n#_______________________\nprint(\"Bucle for\")\nfor n in range(1, 11):\n    print(n)\n\n#_______________________\nprint(\"\\nBucle while\")\nn = 1\nwhile n <= 10:\n    print(n)\n    n += 1\n\n#_______________________\nprint(\"\\nfunción map()\")\nlist(map(print, range(1, 11)))\n\n\"\"\"\n* EJERCICIO #2:\n* Escribe el mayor número de mecanismos que posea tu lenguaje\n* para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n\"\"\"\n\n#_______________________\nprint(\"\\nFunción filter()\")\ndef is_even(n):\n    return n % 2 == 0\n\nfiltered = list(filter(is_even, range(1, 21)))\nprint(filtered)\n\n#_______________________\nprint(\"\\ncon reversed()\")\nnums = [1, 2, 3, 4]\n\nnums_reversed = list(reversed(nums))\nprint(nums_reversed)\n\n#_______________________\nprint(\"\\nIteradores personalizados\")\nclass NumbersEvens:\n    def __init__(self):\n        self.number = 0\n\n    def __iter__(self):\n        return self\n\n    def __next__(self):\n        self.number += 2\n        return self.number\n\nevens_iterator = NumbersEvens()\nfor _ in range(4):\n    print(next(evens_iterator))\n\n#_______________________\nprint(\"\\ncon enumerate()\")\nnames = [\"Zoe\", \"Bob\", \"Ben\"]\n\nenumeration = list(enumerate(names, start=1))\nprint(enumeration)\n\n#_______________________\nprint(\"\\nFunción zip()\")\nnames = [\"Zoe\", \"Bob\", \"Ben\"]\nages = [21, 22, 23]\n\n# No es un mecanismo de iteración en el sentido tradicional.\nusers = list(zip(names, ages))\nprint(users)\n\n#_______________________\nprint(\"\\nCon recursividad\")\n# No es un mecanismo de iteración en el sentido tradicional.\n\ndef num(n: int):\n    print(n)\n    if n > 0:\n        num(n - 1)\nnum(10)\n\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/mariovelascodev.py",
    "content": "for number in range(1,11):\n    print(number)\n\nprint(\"Termina la iteración del bucle for con range()\\n\")\n\nnumber = 0\nwhile number < 10:\n    number += 1\n    print(number)\n\nprint(\"Termina la iteración del bucle while\\n\")\n\nnumbers = [1,2,3,4,5,6,7,8,9,10]\nfor number in numbers:\n    print(number)\n\nprint(\"Termina la iteración del bucle for en listas\\n\")\n\n#EXTRA\nprint(\"EXTRA\")\nnumbers = {1,2,3,4}\n\nfor number in numbers:\n    print(number)\n\nprint(\"\\n----------------------\")\n\ndictionary = {\n    \"a\": 1,\n    \"b\": 2,\n    \"c\": 3\n}\n\nfor key, value in dictionary.items():\n    print(f\"{key}: {value}\")\n\nprint(\"\\n----------------------\")\n\nlist = [number**2 for number in range(1,6)]\nprint(list)\n\nprint(\"\\n----------------------\")\n\nnumbers = (1,2,3,4)\n\nfor number in numbers:\n    print(number)\n\nprint(\"\\n----------------------\")    \n\nnumber = 0\nwhile number < 5:\n    number += 1\n    print(\"La variable number vale\", number)\nelse:\n    print(\"Se ha completado toda la iteración y la variable number vale\", number)"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/mhayhem.py",
    "content": "# @Author: Mhayhem\n\n# EJERCICIO:\n# Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n# números del 1 al 10 mediante iteración.\n\n# iteración For.\n\ndef for_iteration():\n    for n in range(1, 11):\n        print(n, end=\", \")\n    print(\"\\n\")\n# iteración while.\n\ndef while_iteration():\n    n = 1\n    while n < 11:\n        print(n, end=\", \")\n        n += 1\n    print(\"\\n\")\n\n# iteración por compresión de lista.\n\ndef comprehesion_iteration():\n    print([x + 1 for x in range(10)])\n    print(\"\\n\")\n    \n\n\n# DIFICULTAD EXTRA (opcional):\n# Escribe el mayor número de mecanismos que posea tu lenguaje\n# para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n\n\n# iteración compresión de conjunto.\n\ndef set_iteration():\n    print({x +1 for x in range(10)})\n    print(\"\\n\")\n\n# iteración comprensión de diccionario.    \n\ndef dict_iteration():\n    print({n: n + 2 for n in range(1,11)})\n    print(\"\\n\")\n\n# iteración usando map().\n    \ndef map_iteration():\n    print(list(map(lambda x: x, range(1,11))))\n    print(\"\\n\")\n\n# iteración usando filter.\n\ndef filter_iteration():\n    print(list(filter(lambda x: True, range(1, 11))))\n    print(\"\\n\")\n\n# iteración usando iter.\n\ndef iter_iteration():\n    it = iter(range(1, 11))\n    \n    while True:\n        try:\n            print(next(it), end=\", \")\n        except StopIteration:\n            break\n    print(\"\\n\")\n\n# iteración usando zip.\n\ndef zip_iteration():\n    values = \"0123456789\"\n    for n, v in zip(range(1, 11), values):\n        print(f\"{n}:{v}\", end=\", \")\n    print(\"\\n\")\n    \ndef main():\n    print(\"Iteración For\")\n    for_iteration()\n    print(\"Iteración While\")\n    while_iteration()\n    print(\"Iteración Comprensión de lista\")\n    comprehesion_iteration()\n    print(\"Iteración compresión de conjunto\")\n    set_iteration()\n    print(\"Iteración compresión de diccionario\")\n    dict_iteration()\n    print(\"Iteración usando map()\")\n    map_iteration()\n    print(\"Iteración usando filter()\")\n    filter_iteration()\n    print(\"Iteración manual con iter()\")\n    iter_iteration()\n    print(\"Iteración usando zip()\")\n    zip_iteration()\n\nif __name__==\"__main__\":\n    main()"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/mikelm2020.py",
    "content": "# Ejercicio\nfrom functools import reduce\nfrom itertools import count, islice\n\n\ndef iteration_with_for():\n    for index in range(1, 11):\n        print(index)\n\n\ndef iteration_with_while():\n    index = 1\n    while index <= 10:\n        print(index)\n        index += 1\n\n\ndef iteration_with_for_in():\n    array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n    for index in array:\n        print(index)\n\n\n# Extra\ndef iteration_with_for_each():\n    array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n    for element in array:\n        print(element)\n\n\ndef recursive_count(number=1):\n    if number <= 10:\n        print(number)\n        recursive_count(number + 1)\n\n\ndef iteration_with_comprehension():\n    print(*[index for index in range(1, 11)], sep=\"\\n\")\n\n\ndef iteration_with_map():\n    print(*map(lambda x: x, range(1, 11)))\n\n\ndef iteration_with_filter():\n    print(*filter(lambda x: True if x <= 10 else False, range(1, 101)))\n\n\ndef iteration_with_reduce():\n    print(reduce(lambda x, y: x + y, range(1, 11)))\n\n\ndef iteration_with_islice():\n    print(*islice(count(1), 10))\n\n\ndef iteration_with_zip():\n    print(*zip(range(1, 11), range(11, 21)))\n\n\ndef iteration_with_enumerate():\n    print(*enumerate([x for x in range(1, 11)], 1))\n\n\ndef iteration_with_comprehension_2():\n    print(*[(x, y) for x in range(1, 11) for y in range(x, 11)])\n\n\ndef iteration_with_comprehension_3():\n    print(*[(x, y) for x in range(1, 11) for y in range(x, 11) if x != y])\n\n\ndef iteration_with_comprehension_4():\n    print(\n        *[\n            (x, y, z)\n            for x in range(1, 11)\n            for y in range(x, 11)\n            for z in range(y, 11)\n            if x != y != z\n        ]\n    )\n\n\ndef iteration_with_comprehension_5():\n    print(\n        *[\n            (x, y, z)\n            for x in range(1, 11)\n            for y in range(x, 11)\n            for z in range(y, 11)\n            if x != y != z and x < y < z\n        ]\n    )\n\n\ndef iteration_with_comprehension_6():\n    print(\n        *[\n            (x, y, z)\n            for x in range(1, 11)\n            for y in range(x, 11)\n            for z in range(y, 11)\n            if x != y != z and x > y > z\n        ]\n    )\n\n\ndef iteration_with_comprehension_7():\n    print(\n        *[\n            (x, y, z)\n            for x in range(1, 11)\n            for y in range(x, 11)\n            for z in range(y, 11)\n            if x != y != z and x == y == z\n        ]\n    )\n\n\ndef iteration_with_comprehension_8():\n    print(\n        *[\n            (x, y, z)\n            for x in range(1, 11)\n            for y in range(x, 11)\n            for z in range(y, 11)\n            if x != y != z and x < y > z\n        ]\n    )\n\n\ndef iteration_with_comprehension_9():\n    print(\n        *[\n            (x, y, z)\n            for x in range(1, 11)\n            for y in range(x, 11)\n            for z in range(y, 11)\n            if x != y != z and x > y < z\n        ]\n    )\n\n\ndef iteration_with_comprehension_10():\n    print(\n        *[\n            (x, y, z)\n            for x in range(1, 11)\n            for y in range(x, 11)\n            for z in range(y, 11)\n            if x != y != z and x < y == z\n        ]\n    )\n\n\ndef iteration_with_comprehension_11():\n    print(\n        *[\n            (x, y, z)\n            for x in range(1, 11)\n            for y in range(x, 11)\n            for z in range(y, 11)\n            if x != y != z and x > y == z\n        ]\n    )\n\n\nif __name__ == \"__main__\":\n    print(\"Con For\")\n    iteration_with_for()\n    print(\"Con While\")\n    iteration_with_while()\n    print(\"Con For In\")\n    iteration_with_for_in()\n    print(\"Con For Each\")\n    iteration_with_for_each()\n    print(\"Con Recursividad\")\n    recursive_count()\n    print(\"Con list comprehension\")\n    iteration_with_comprehension()\n    print(\"Con Map\")\n    iteration_with_map()\n    print(\"Con Filter\")\n    iteration_with_filter()\n    print(\"Con Reduce\")\n    iteration_with_reduce()\n    print(\"Con Islice\")\n    iteration_with_islice()\n    print(\"Con Zip\")\n    iteration_with_zip()\n    print(\"Con Enumerate\")\n    iteration_with_enumerate()\n    print(\"Con Comprehension v2\")\n    iteration_with_comprehension_2()\n    print(\"Con Comprehension v3\")\n    iteration_with_comprehension_3()\n    print(\"Con Comprehension v4\")\n    iteration_with_comprehension_4()\n    print(\"Con Comprehension v5\")\n    iteration_with_comprehension_5()\n    print(\"Con Comprehension v6\")\n    iteration_with_comprehension_6()\n    print(\"Con Comprehension v7\")\n    iteration_with_comprehension_7()\n    print(\"Con Comprehension v8\")\n    iteration_with_comprehension_8()\n    print(\"Con Comprehension v9\")\n    iteration_with_comprehension_9()\n    print(\"Con Comprehension v10\")\n    iteration_with_comprehension_10()\n    print(\"Con Comprehension v11\")\n    iteration_with_comprehension_11()\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/monicavaquerano.py",
    "content": "# 17 ITERACIONES\n# Monica Vaquerano\n# https://monicavaquerano.dev\n\n\"\"\"\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n * números del 1 al 10 mediante iteración.\n *\n * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n */\n\"\"\"\n\nprint(\"\\nFor Range Loop\")\nfor i in range(1, 11):\n    print(i, end=\" \")\n\nprint(\"\\nWhile Loop\")\nx = 0\nwhile x < 10:\n    x += 1\n    print(x, end=\" \")\n\nprint(\"\\nMap() Function\")\n\n\ndef impresion(x):\n    print(x, end=\" \")\n\n\nlist(map(impresion, range(1, 11)))\n\nprint(\"\\n\\n# Extra\")\n\nprint(\"For Loop\")\nnumbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\nfor number in numbers:\n    print(number, end=\" \")\n\nprint(\"\\nRecursividad\")\n\n\ndef printToTen(x):\n    if x >= 10:\n        print(10)\n        return\n    print(x, end=\" \")\n    printToTen(x + 1)\n\n\nprintToTen(1)\n\nprint(\"\\nEnumerate() Function\")\nfor i, number in enumerate(numbers, start=1):\n    print(f\"{i}.{number}\", end=\" \")\n\nprint(\"\\nZip() Function\")\nletters = [\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\", \"h\", \"i\", \"j\"]\nfor number, letter in zip(numbers, letters):\n    print(f\"{number}.{letter}\", end=\" \")\n\nprint(\"\\nIterators\")\n# Un iterador es un objeto que implementa los métodos __iter__() y __next__().\n# Se utiliza para recorrer una secuencia de elementos.\n\nmy_list = [1, 2, 3]\nmy_iter = iter(my_list)\nprint(next(my_iter))  # 1\nprint(next(my_iter))  # 2\nprint(next(my_iter))  # 3\n\nprint(\"\\nGenerators\")\n# Los generadores son una forma especial de crear iteradores utilizando la palabra clave yield.\n\n\ndef count_up_to(max):\n    count = 1\n    while count <= max:\n        yield count\n        count += 1\n\n\ncounter = count_up_to(5)\nfor num in counter:\n    print(num, end=\" \")\n\n\nprint(\"\\nComprensiones\")\n# Las comprensiones en Python proporcionan una forma concisa de crear listas, conjuntos y diccionarios.\n\n# Lista de comprensiones\nsquares = [x**2 for x in range(10)]\nprint(squares)\n\n# Conjunto de comprensión\nunique_squares = {x**2 for x in range(10)}\nprint(unique_squares)\n\n# Diccionario de comprensiones\nsquares_dict = {x: x**2 for x in range(10)}\nprint(squares_dict)\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/mouredev.py",
    "content": "\"\"\"\nEjercicio\n\"\"\"\n# For\nfor i in range(1, 11):\n    print(i)\n\n# While\ni = 1\nwhile i <= 10:\n    print(i)\n    i += 1\n\n# Recursividad\n\n\ndef count_ten(i=1):\n    if i <= 10:\n        print(i)\n        count_ten(i + 1)\n\n\ncount_ten()\n\n\"\"\"\nExtra\n\"\"\"\n\nfor e in [1, 2, 3, 4]:\n    print(e)\n\nfor e in {1, 2, 3, 4}:\n    print(e)\n\nfor e in (1, 2, 3, 4):\n    print(e)\n\nfor e in {1: \"a\", 2: \"b\", 3: \"c\", 4: \"d\"}:\n    print(e)\n\nfor e in {1: \"a\", 2: \"b\", 3: \"c\", 4: \"d\"}.values():\n    print(e)\n\nprint(*[i for i in range(1, 11)], sep=\"\\n\")\n\nfor c in \"Python\":\n    print(c)\n\nfor e in reversed([1, 2, 3, 4]):\n    print(e)\n\nfor e in sorted([\"m\", \"o\", \"u\", \"r\", \"e\"]):\n    print(e)\n\nfor i, e in enumerate(sorted([\"m\", \"o\", \"u\", \"r\", \"e\"])):\n    print(f\"Índice: {i}, valor: {e}\")\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/mrodara.py",
    "content": "##################################  ITERACIONES  ###################################################\n\n# EJERCICIO 3 MANERAS DIFERENTES DE IMPRIMIR SECUENCIA 1 AL 10\n\n# 1. Usando un for\n\nfor i in range(1,11):\n    print(i,\" \", end=\"\")\n    \n# 2. Recorriendo un lista wildcard\nlista = [1,2,3,4,5,6,7,8,9,10]\n\nprint(lista[:])\n\n# También podemos crear la lista por comprenhension\nprint (* [i for i in range(1,11)])\n\n# 3. Usando un bucle While\nnumber = 1\n\nwhile number <= 10:\n    print(number, \" \", end=\"\")\n    number += 1\n\n\n##################################  EXTRA ITERACIONES  ###################################################\n\n# Podemos usar recursividad para iterar números\n\ndef recursive_iteration(i: int = 1):\n    if i <= 10:\n        print(i, \" \", end=\"\")\n        recursive_iteration(i + 1)\n\nrecursive_iteration()\n\n# Antes hemos usado listas pero también son iterables las tuplas y los diccionarios\n\ntupla = (1,2,3,4,5,6,7,8,9,10)\n\nfor num in tupla:\n    print(num, \" \", end=\"\")\n    \nmy_dict = {'a':1, 'b':2, 'c':3, 'd':4, 'e':5, 'f':6, 'g':7, 'h':8, 'i':9, 'j':10}\n\n# En el caso de los diccionarios podemos iterar las claves, los valores u ambos a la vez\n\nfor key in my_dict.keys():\n    print(key, \" \", end=\"\")\n    \nfor value in my_dict.values():\n    print(value, \" \", end=\"\")\n\nfor key,value in my_dict.items():\n    print(f'Clave: {key}, Valor: {value}')\n    \n# Cadenas de caracteres también son iterables.\n\nmy_str = \"Lleva la tarara un vestido blanco lleno de cascabeles\"\n\nfor char in my_str:\n    print(char, \" \", end=\"\")\n    \n# De la misma cadena también podemos iterar por las palabras que la conforman\nfor word in my_str.split():\n    if word != \" \":\n        print(word, \" \", end=\"\")\n\n# En listas, tuplas y cadenas de caracteres podemos iterar en orden inverso\n\nprint(tupla[::-1])\nprint(my_str[::-1])\nprint(my_str.split()[::-1])\n\n##################################  FIN EXTRA ITERACIONES  ###################################################\n\n##################################  FIN ITERACIONES  ###################################################"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/mvidalb.py",
    "content": "'''\nEjercicio\n'''\n\n# For\nfor i in range(1,11):\n    print(i)\n\n# Wjoñe\ni = 1\nwhile i <= 10:\n    print(i)\n    i += 1\n\n# Recursividad\ndef count(i):\n    if i <= 10:\n        print(i)\n        count(i+1)\n\ncount(1)\n\n\n'''\nEjercicio extra\n'''\nfor e in [1, 2, 3, 4]:\n    print(e)\n\nfor e in {1, 2, 3, 4}:\n    print(e)\n\nfor e in (1, 2, 3, 4):\n    print(e)\n\nfor e in {1: \"a\", 2: \"b\", 3: \"c\", 4: \"d\"}:\n    print(e)\n\nfor e in {1: \"a\", 2: \"b\", 3: \"c\", 4: \"d\"}.keys():\n    print(e)\n\nfor e in {1: \"a\", 2: \"b\", 3: \"c\", 4: \"d\"}.values():\n    print(e)\n\nprint(*[i for i in range(1,11)], sep=\"\\n\")\n\nfor c in \"python\":\n    print(c)\n\nfor e in reversed([1, 2, 3, 4]):\n    print(e)\n\nfor e in sorted([\"v\", \"i\", \"d\", \"a\", \"l\"]):\n    print(e)\n\nfor i, e in enumerate(sorted([\"v\", \"i\", \"d\", \"a\", \"l\"])):\n    print(f\"Índice: {i}, Value: {e}\")\n\n    "
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/nandaAlf.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n#  * números del 1 al 10 mediante iteración.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Escribe el mayor número de mecanismos que posea tu lenguaje\n#  * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n#  */\n\n# 1 for Loop\nprint(\"**********1**********\")\nfor i in range(10):\n    print(i+1)\n\n# 2 while Loop\nprint(\"\\n**********2**********\")\ni=1\nwhile i<11:\n    print(i)\n    i+=1\n\n#3 while loop using IN\nprint(\"\\n**********3**********\")\ni=1\nwhile i in [1,2,3,4,5,6,7,8,9,10]:\n    print(i)\n    i+=1\n\n#4 function iter()\nprint(\"\\n**********4**********\")\nnumbers = iter(range(1, 11))\nfor n in numbers:\n    print(n)\n\n#5 functions iter() and next()\nprint(\"\\n**********5**********\")\nnumbers = iter(range(1, 11))\nwhile(True):\n    try:\n        n=next(numbers)\n        print(n)\n    except StopIteration:\n        break\n\n#6 generator\nprint(\"\\n**********6**********\")\ndef generator(n):\n    for i in range(1,n+1):\n        yield i\nfor i in generator(10):\n    print(i)\n\n#7 list Compression\nprint(\"\\n**********7**********\")\nnumber1=[i for i in range(1,11)]\nfor n in number1:\n    print(n)\n\n#8 function enumerate()\nprint(\"\\n**********8**********\")\nfor index,number in enumerate(range(1,11),1):\n    print(index)\n\n#9 class\nprint(\"\\n**********9**********\")\nclass Nums:\n    def __init__(self, n):\n        self.n = n\n        self.i = 1\n\n    def __iter__(self):\n        return self\n\n    def __next__(self):\n        if self.i > self.n:\n            raise StopIteration\n        number = self.i\n        self.i += 1\n        return number\n\nnumbers2 = Nums(10)\nfor n in numbers2:\n    print(n)\n\n# 10 function map()\nprint(\"\\n**********10*********\")\nnumber5=map(lambda x:x,[1,2,3,4,5,6,7,8,9,10])\nfor n in number5:\n    print(n)"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/neslarra.py",
    "content": "\"\"\"\n EJERCICIO:\n Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n números del 1 al 10 mediante iteración.\n DIFICULTAD EXTRA (opcional):\n Escribe el mayor número de mecanismos que posea tu lenguaje\n para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n\"\"\"\nfrom collections.abc import Iterator\n\nprint(f\"\"\"##  Explicación  {'#' * 30}\"\"\")\n\nprint(f\"\"\"\nUn \"iterable\" es una colección que puede recorrerse y referenciarse a través de un índice (implementan __iter__ y __getitem__,  que automáticamente\nes llamada a través de [indice] o de [slice] => ES suscriptable).\nListas, tuplas, cadenas, diccionarios SON \"iterables\".\n    a = [1, 2, 3]\n    isinstance(a, Iterable) => True\n    hasattr(a, \"__iter__\") => True\n    hasattr(a, \"__getitem__\") => True\n    isinstance(a, Iterator) => False\n    hasattr(a, \"__next__\") => False\n    \n    a = 1\n    isinstance(a, Iterable) => False\n    isinstance(a, Iterator) => False\n    \nUn \"iterador\" es, en cambio, una colección que que genera un puntero a un elemento de manera secuencial y hacia adelante (implementa __iter__ y \n__next__, el cual es llamado cada vez para traer el próximo elemento => NO se puede referencia on un índice => NO es \"suscriptable\". Cuando ya no\nhay elementos, lanza la excepción StopIteration).  \n    \n    class MiClase(Iterator):\n        xxxxxxxx   <=  implementada en uno de los casos de \"dificultad extra\"\n    a = MiClase()\n    isinstance(a, Iterable) => True\n    hasattr(a, \"__iter__\") => True\n    hasattr(a, \"__getitem__\") => False\n    isinstance(a, Iterator) => True\n    hasattr(a, \"__next__\") => True\nDejo unos links donde se explica claramente Iterables e Iteradores:\n    https://ellibrodepython.com/iterator-python\n    http://cuartas.es/python/iterables/\n    https://es.stackoverflow.com/questions/84591/diferencia-entre-objetos-iterable-iterator-y-secuencias-en-python-3\nEl ejercicio de implementar tres maneras de mostrar los números del 1 al 10 es parte de la \"dificultad extra\" <=> 10 maneras de iterar.\n\"\"\")\n\n\ndef numerar_comprehension(inicio=0, fin=100):\n    mapa = \"\".maketrans(\"\", \"\", \"[],\")       # # mapa = {91: None, 93: None, 44: None}   <= cualquiera de las dos maneras es válida\n    return f\"{[x for x in range(inicio, fin + 1)].__str__().translate(mapa)}\"\n\n\ndef numerar_for(inicio=0, fin=100):\n    salida = \"\"\n    for numero in range(inicio, fin + 1):\n        salida += str(numero) + \" \"\n    return salida\n\n\ndef numerar_loop(inicio=0, fin=100):\n    salida = \"\"\n    x = inicio\n    while x <= fin:\n        salida += str(x) + \" \"\n        x += 1\n    return salida\n\n\ndef numerar_recursivo(inicio=0, numeros=\"\", fin=100):\n    if inicio == fin:\n        return numeros + str(fin)\n    else:\n        numeros += str(inicio) + \" \"\n        return numerar_recursivo(inicio + 1, numeros, fin)\n\n\ndef generador(inicio, fin):\n    valor = inicio\n    while valor <= fin:\n        yield valor\n        valor += 1\n\n\ndef numerar_generador(inicio=0, fin=100):\n    salida = \"\"\n    numeros = generador(inicio, fin)\n    while True:\n        try:\n            salida += str(next(numeros)) + \" \"\n        except StopIteration:\n            break\n    return salida\n\n\nclass Numerar(Iterator):\n    def __init__(self, inicio, fin):\n        self.fin = fin\n        self.inicio = inicio\n\n    def __iter__(self):\n        return self\n\n    def __next__(self):\n        if self.inicio > self.fin:\n            raise StopIteration\n        else:\n            valor_actual = self.inicio\n            self.inicio += 1\n            return valor_actual\n\n\ndef numerar_zip(inicio=0, fin=100):\n    salida = \"\"\n    pares = [x for x in range(inicio, fin + 1) if (x % 2) == 0]\n    impares = [x for x in range(inicio, fin + 1) if (x % 2) == 1]\n    for x, y in zip(impares, pares):\n        salida += str(x) + \" \" + str(y) + \" \"\n    return salida\n\n\ndef numerar_cadena():\n    salida = \"\"\n    numeros = \"0123456789\"\n    for d in numeros:\n        salida += str(int(d) + 1) + \" \"\n    return salida\n\n\ndef numerar_enumerate(lista_de_numeros, inicio=0, fin=100):\n    salida = \"\"\n    if fin > lista_de_numeros.__len__():\n        return\n    for ind, _ in enumerate(lista_de_numeros):\n        if inicio <= ind <= fin:\n            salida += str(ind) + \" \"\n    return salida\n\n\ndef numerar_reversa(inicio=100, fin=-1):\n    salida = \"\"\n    for numero in reversed(range(inicio, fin - 1, -1)):\n        salida += str(numero) + \" \"\n    return salida\n\n\nprint(f\"\"\"\\n \\n##  Dificultad extra  {'#' * 30}\\n\"\"\")\n\ncaso = Numerar(1, 10)\nprint(f\"Caso {caso.__next__()}: mostrar números del 1 al 10 por comprehensión: {numerar_comprehension(1, 10)}\")\nprint(f\"Caso {caso.__next__()}: mostrar números del 1 al 10 con un for loop:   {numerar_for(1, 10)}\")\nprint(f\"Caso {caso.__next__()}: mostrar números del 1 al 10 con un while loop: {numerar_loop(1, 10)}\")\nprint(f\"Caso {caso.__next__()}: mostrar números del 1 al 10 con recursividad:  {numerar_recursivo(inicio=1, fin=10)}\")\nprint(f\"Caso {caso.__next__()}: mostrar números del 1 al 10 con un generador:  {numerar_generador(1, 10)}\")\nprint(f\"Caso {caso.__next__()}: mostrar números del 1 al 10 con zip:           {numerar_zip(1, 10)}\")\nprint(f\"Caso {caso.__next__()}: mostrar números del 1 al 10 desde cadena:      {numerar_cadena()}\")\nprint(f\"\"\"Caso {caso.__next__()}: mostrar números del 1 al 10 con enumerate:     {numerar_enumerate(['cero', 'uno', 'dos', 'tres', 'cuatro',\n                                                                                                 'cinco', 'seis', 'siete', 'ocho', 'nueve', 'diez', \n                                                                                                 'once', 'doce'], 1, 10)}\"\"\")\nprint(f\"Caso {caso.__next__()}: mostrar números del 10 al 1 en reversa:        {numerar_reversa(10, 1)}\")\nprint(f\"Caso {caso.__next__()}: mostrar números del 1 al 10 con un iterador:  la numeración de estos casos con la variable 'caso'\")\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/nlarrea.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n * números del 1 al 10 mediante iteración.\n *\n * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n\"\"\"\n\n# OPTION 1\n\nprint(\"\\nOPTION 1: for loop\")\n\nfor num in range(1, 11):\n    print(num)\n\n\n# OPTION 2\n\nprint(\"\\nOPTION 2: while loop\")\n\nnum = 1\nwhile num <= 10:\n    print(num)\n    num += 1\n\n\n# OPTION 3\n\nprint(\"\\nOPTION 3: recursive function call\")\n\n\ndef counter(start: int, stop: int) -> int:\n    \"\"\"Prints the numbers in the given range.\n\n    Parameters:\n    - `start`: The number where the counter starts to count (included).\n    - `stop`: The number where the count stops (included).\n    \"\"\"\n\n    print(start)\n\n    if start >= stop:\n        return stop\n\n    counter(start + 1, stop)\n\n\ncounter(1, 10)\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/oriaj3.py",
    "content": "\n\"\"\"\t\n16 - Iteraciones\n\nAutor de la solución: Oriaj3\t\n\nTeoría:\t\n\nLas iteraciones son una parte fundamental de la programación, ya que permiten\nrepetir un bloque de código varias veces. En Python, las iteraciones se pueden\nrealizar de varias formas, como con el bucle for o con el bucle while.\nEn este problema, se pide que se realice un programa que imprima los números\ndel 1 al 10 utilizando un bucle for.\n\"\"\"\n\"\"\"\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n * números del 1 al 10 mediante iteración.\n\"\"\"\ndef mec1():\n    for i in range(1, 11):\n        print(i)\n\ndef mec2():\n    num=1\n    while (num <= 10):\n        print(num)\n        num+=1\n\ndef mec3(num: int = 1):\n    if num <= 10:\n        print(num)\n        mec3(num+1)\n\n\nprint(\"******************MEC1\")\nmec1()\nprint(\"******************MEC2\") \nmec2()\nprint(\"******************MEC3\")\nmec3()  \n    \n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n */\n\"\"\"\n\n#For clásico \nnumeros = [1, 2, 3]\nfor numero in numeros:\n    print(numero)\n\n#For con range\nfor i in range(5):\n    print(i)\n\n#For con enumerate\nfrutas = [\"manzana\", \"pera\", \"sandía\"]\nfor indice, fruta in enumerate(frutas):\n    print(indice, fruta) \n\n#While\nnum=0\nwhile num<5:\n    print(num)\n    num += 1\n\n#Comprensión de las listas\ncuadrados = [x**2 for x in range(1,6)]\nprint(cuadrados)\n\n#Comprensión de conjuntos\npares = {x for x in range(10) if x % 2 ==0}\nprint(pares)\n\n#Comprensión de diccionarios:\ncuadrados_dict = {x: x**2 for x in range(1, 6)}\nprint(cuadrados_dict)\n\n#Map\ndef cuadrado(x):\n    return x**2\n\nnumeros = [1, 2, 3]\ncuadrados = map(cuadrado, numeros)\nprint(list(cuadrados))\n\n#Itertools.product\nimport itertools\n\nletras = [\"a\", \"b\"]\nnumeros = [1, 2]\ncombinaciones = itertools.product(letras,numeros)\nprint(list(combinaciones))\n\n#generadores\ndef generador_cuadrados(n):\n    for i in range(n):\n        yield i**2\n\nfor cuadrado in generador_cuadrados(5):\n    print(cuadrado)\n\n\n#TODO: Revisar\nfor e in [1, 2, 3, 4]:\n    print(e)\n\nfor e in {1, 2, 3, 4}:\n    print(e)\n\nfor e in (1, 2, 3, 4):\n    print(e)\n\nfor e in {1: \"a\", 2: \"b\", 3: \"c\", 4: \"d\"}:\n    print(e)\n\nfor e in {1: \"a\", 2: \"b\", 3: \"c\", 4: \"d\"}.values():\n    print(e)\n\nprint(*[i for i in range(1, 11)], sep=\"\\n\")\n\nfor c in \"Python\":\n    print(c)\n\nfor e in reversed([1, 2, 3, 4]):\n    print(e)\n\nfor e in sorted([\"m\", \"o\", \"u\", \"r\", \"e\"]):\n    print(e)\n\nfor i, e in enumerate(sorted([\"m\", \"o\", \"u\", \"r\", \"e\"])):\n    print(f\"Índice: {i}, valor: {e}\")\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/pyramsd.py",
    "content": "# For\nfor i in range(1, 11): print(i)\n\n# While\ni = 1\nwhile i <= 10:\n    print(i)\n    i += 1\n\n# Recursividad\ndef count_ten(i=1):\n    if i <= 10:\n        print(i)\n        count_ten(i + 1)\ncount_ten()\n\n\"\"\"\nExtra\n\"\"\"\nfor e in [1, 2, 3, 4, 5, 6, 7, 8, 9]: print(e)\n\nfor e in {1, 2, 3, 4, 5, 6, 7, 8, 9}: print(e)\n\nfor e in (1, 2, 3, 4, 5, 6, 7, 8, 9): print(e)\n\nfor e in {1: \"a\", 2: \"b\", 3: \"c\", 4: \"d\", 5:\"e\"}: print(e)\n\nfor e in {1: \"a\", 2: \"b\", 3: \"c\", 4: \"d\", 5:\"e\"}.values(): print(e)\n\nprint(*[i for i in range(1, 11)], sep=\"\\n\")\n\nfor c in \"Python\": print(c)\n\nfor e in reversed([1, 2, 3, 4]): print(e)\n\nfor e in sorted([\"s\", \"e\", \"r\", \"g\", \"i\", \"0\"]): print(e)\n\nfor i, e in enumerate(sorted([\"s\", \"e\", \"r\", \"g\", \"i\", \"o\"])):\n    print(f\"Índice: {i}, valor: {e}\")\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/qwik-zgheib.py",
    "content": "# -- exercise\nfor i in range(1, 11):\n    print(i)\n\ni: int = 1\nwhile i <= 10:\n    print(i)\n    i += 1\n\n[print(i) for i in range(1, 11)]\n\n\n# -- extra challenge\ndata_list: list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\nfor i in data_list:\n    print(i)\n    i += 1\n\ni: int = 0\nwhile i < len(data_list):\n    print(data_list[i])\n    i += 1\n\nfor i in range(len(data_list)):\n    print(data_list[i])\n    i += 1\n\nfor i in range(0, len(data_list)):\n    print(data_list[i])\n    i += 1\n\n\ndef recursive_print(data_list: list, i: int) -> None:\n    if i < len(data_list):\n        print(data_list[i])\n        recursive_print(data_list, i + 1)\n    else:\n        return\n\n\nrecursive_print(data_list, 0)\n\n\ndef anonymous_print(data_list: list) -> None:\n    [print(i) for i in data_list]\n\n\nanonymous_print(data_list)\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/rantamhack.py",
    "content": "'''\n* EJERCICIO:\n* Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n* numeros del 1 al 10 mediante iteracion.\n'''\n\nprint(\"\\n\\n=======================================EJERCICIO=======================================\\n\\n\")\n\n# Usando 'for'\n\nfor i in range(1, 11):\n    print(f\"El valor de la iteracion en 'bucle for' para 'i' es: {i}\")\n\nprint(\"\\n=====================\\n\")    \n    \n# Usando 'while'    \n    \nn = 1    \nwhile n < 11:\n    print(f\"El valor de la iteracion en bucle 'while' para 'n' es: {n}\")\n    n += 1\n    \nprint(\"\\n=====================\\n\")\n\n# Usando 'while do'\n\nn = 1\nwhile True:\n    if n > 10:\n        break\n    print(f\"El valor de la iteracion en bucle 'do while' para 'n' es: {n}\")\n    n += 1    \n\n\nprint(\"\\n\\n=======================================DIFICULTAD EXTRA=======================================\\n\\n\")\n\n\n'''\n* DIFICULTAD EXTRA (opcional):\n* Escribe el mayor numero de mecanismos que posea tu lenguaje\n* para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n'''\n\n# Iterar Cadena de Texto\n\ntexto = \"rantamplan\"\n\nfor c in texto:\n    print(c)\n    \nprint(\"\\n=====================\\n\")\n    \n# Iterar lista\n\nfor i in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]:\n    print(i)\n    \nprint(\"\\n=====================\\n\")\n    \n# Iterar tupla\n\nfor i in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10):\n    print(i)\n    \nprint(\"\\n=====================\\n\")\n\n# Iterar set\n\nfor i in {\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\", \"h\", \"i\", \"j\"}:\n    print(i)\n    \nprint(\"\\n=====================\\n\")\n\n# Iterar diccionario por clave\n\nfor i in {1: \"a\", 2: \"b\", 3: \"c\", 4: \"d\", 5: \"e\", 6: \"f\", 7: \"g\", 8: \"h\", 9: \"i\", 10: \"j\"}.keys():\n    print(i)\n    \nprint(\"\\n=====================\\n\")\n\n# Iterar diccionario por valor\n\nfor i in {1: \"a\", 2: \"b\", 3: \"c\", 4: \"d\", 5: \"e\", 6: \"f\", 7: \"g\", 8: \"h\", 9: \"i\", 10: \"j\"}.values():\n    print(i)\n    \nprint(\"\\n=====================\\n\")\n\n# Iterando lista al reves\n\nfor i in reversed([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]):\n    print(i)\n    \nprint(\"\\n=====================\\n\")\n\n# Iterando mediante recursividad\n\n\ndef recursive(x = 1):\n    if x < 11:    \n        print(x)\n        recursive(x+1)\n\n\nrecursive()\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/raynerpv2022.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n#  * números del 1 al 10 mediante iteración.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Escribe el mayor número de mecanismos que posea tu lenguaje\n#  * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n#  */\n\nfor i in range(1,11):\n    print(i)\n\ni=1\n\nwhile i <=10:\n    print(i)\n    i+=1\n\nnumeros = [x  for x in range(1,11)]\nprint(numeros)\n\ndef print_number(n):\n    print(n)\n    if n == 10:\n        return n\n    return print_number(n+1)\n\nprint_number(1)\n\n\n# EXTRA\n\n# Lista de países\npaises = ['España', 'Francia', 'Alemania', 'Italia', 'Japón', 'México', 'Brasil', 'Argentina', 'Canadá', 'Australia']\n\n# Lista de capitales\ncapitales = ['Madrid', 'París', 'Berlín', 'Roma', 'Tokio', 'Ciudad de México', 'Brasilia', 'Buenos Aires', 'Ottawa', 'Canberra']\n\nfor i,v in zip(paises, capitales):\n    print(f\" Pais: {i} Capital: {v}\")\n\nmapa_mundi = {i:v  for i,v in zip(paises, capitales)}\nfor i,v in mapa_mundi.items():\n    print(f\" Pais: {i} Capital: {v}\")"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/restevean.py",
    "content": "\"\"\"\nExercise\n\"\"\"\n\nprint(\"#01 - Using 'for' with a range\")\nfor i in range(1, 11):\n    print(i)\n\nprint(\"#02 - Using 'while':\")\ni = 1\nwhile i <= 10:\n    print(i)\n    i += 1\n\nprint(\"#03 - Using list comprehension:\")\nprint(*[i for i in range(1, 11)], sep='\\n')\n\n\"\"\"\nExtra\n\"\"\"\n\nprint(\"#04 - List iteration:\")\nmy_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\nfor item in my_list:\n    print(item)\n\nprint(\"#05 - Using 'map':\")\nlist(map(print, range(1, 11)))\n\nprint(\"#06 - Using dictionaries iteration:\")\nmy_dict = {1: 'one', 2: 'two', 3: 'three', 4: 'four', 5: 'five'}\nfor key, value in my_dict.items():\n    print(key, value)\n\nprint(\"#07 - Using 'Iterators':\")\niterable = iter(range(1, 11))\nfor value in iterable:\n    print(value)\n\nprint(\"#08 - Using 'generators':\")\n\n\ndef generate_numbers():\n    for i in range(1, 11):\n        yield i\n\n\nfor number in generate_numbers():\n    print(number)\n\nprint(\"#09 - Using 'enumerate':\")\nfor index, value in enumerate(range(1, 11), start=1):\n    print(index, value)\n\nprint(\"#10 - Using recursion:\")\n\n\ndef recursive_print(n):\n    if n > 0:\n        recursive_print(n - 1)\n        print(n)\n\n\nrecursive_print(10)\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/rigo93acosta.py",
    "content": "'''\n * EJERCICIO:\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n * números del 1 al 10 mediante iteración.\n *\n * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n */\n'''\n\n'''\nEjercicio\n'''\n# 1. For\nfor i in range(1, 11):\n    print(i)\n\n# 2. While\ni = 1\nwhile i <= 10:\n    print(i)\n    i += 1\n\n# 3. Recursividad\ndef count(n=1):\n    if n <= 10:\n        print(n)\n        count(n + 1)\n\ncount()\n\n'''\nDificultad extra\n'''\n\nfor e in [1, 2, 3, 4]:\n    print(e)\n\nfor e in {1, 2, 3, 4}:\n    print(e)\n\nfor e in (1, 2, 3, 4):\n    print(e)\n\nfor e in {1: \"a\", 2: \"b\", 3:\"c\", 4:\"d\"}:\n    print(e)\n\nfor e in {1: \"a\", 2: \"b\", 3:\"c\", 4:\"d\"}.values():\n    print(e)\n\nprint(*[i for i in range(1, 11)], sep=\"\\n\")\n\nfor c in \"Python\":\n    print(c)\n\nfor e in reversed([1, 2, 3, 4]):\n    print(e)\n\nfor e in sorted([\"c\", \"a\", \"b\"]):\n    print(e)\n\nfor index, value in enumerate([\"a\", \"b\", \"c\"]):\n    print(f'Index: {index}, value: {value}')"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/santyjl.py",
    "content": "#17 - ITERACIONES\n\n\"\"\"\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n * números del 1 al 10 mediante iteración.\n *\n * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n */\n\"\"\"\n\n#forma uno\nfor i in range(1 , 11):\n    print(i)\n\n#forma dos\ni = 1\nwhile i < 11 :\n    print(i)\n    i+=1\n\n#forma tres\ndef uno_al_10(num = 0):\n    if num <= 10 :\n        return uno_al_10(num+1)\n\nprint(uno_al_10())\n\n#5 formas de iterar\n\nfor i in [1 , 2 ,3 ,4 ,5]:\n    print(i)\n\nprint([i for i in [1 , 2 ,3 , 4 , 5]])\n\ni = 1\nif i <=5:\n    print(i)\n    i+=1\n\nprint(*[i for i in range(1,6)] , sep=\"\\n\")\n\niterador = lambda x : print(x)\nfor i in range(1, 5):\n    iterador(i)\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/sorubadguy.py",
    "content": "#? Imprimir numeros del 1 al 10\nprint(\"for:\")\nfor i in range(1, 11):\n    print(i)\n\nprint(\"while\")\ni = 1\nwhile i <= 10:\n    print(i)\n    i += 1\n\nprint(\"recurvivo\")\ndef numeros(n: int) -> int:\n    print(n)\n    if n < 10:\n        numeros(n+1)\n        \nnumeros(1)\n\n#! Extra\n\nlista = [1,2,3,4,5,6,7,8,9,0]\ndiccionario = {\n    \"1\" : \"uno\",\n    \"2\" : \"dos\",\n    \"3\" : \"tres\",\n    \"4\" : \"cuatro\",\n    \"5\" : \"cinco\",\n    \"6\" : \"seis\",\n    \"7\" : \"siete\",\n    \"8\" : \"ocho\",\n    \"9\" : \"nueve\",\n    \"0\" : \"cero\"\n}\ntupla = (1,2,3,4,5,6,7,8,9,0)\nsets = {\"1\",\"2\",\"3\",\"4\",\"5\",\"6\",\"7\",\"8\",\"9\",\"0\"}\ntexto = \"hola mundo\"\n\nprint(\"Lista\")\nfor i in lista:\n    print(i)\n\nprint(\"diccionario\")\nfor i in diccionario:\n    print(i + diccionario[i])\n\nprint(\"tupla\")\nfor i in tupla:\n    print(i)\n\nprint(\"sets\")\nfor i in sets:\n    print(i)\n\nprint(\"Texto\")\nfor i in texto:\n    print(i)"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/victorfer69.py",
    "content": "#EJERCICIO\n\nfor i in range(1, 11):\n    print(i)\nprint(\"==============\")\n\ni = 1\nwhile(i < 11):\n    print(i)\n    i += 1\nprint(\"==============\")\n\ndef function_recursive(i:int):\n    if i == 10:\n        print(i)\n    else:\n        print(i)\n        i += 1\n        function_recursive(i)\n\nfunction_recursive(1)\nprint(\"==============\")\n\n#EJERCICIO EXTRA\n\nfor i in [1, 2, 3]:\n    print(i)\nprint(\"==============\")\n\nfor i in {1, 2, 3}:\n    print(i)\nprint(\"==============\")\n\nfor i in {1: \"a\", 2: \"b\", 3: \"c\"}:\n    print(i)\nprint(\"==============\")\n\nprint(*[i for i in range(1, 11)], sep=\"\\n\")\nprint(\"==============\")"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/worlion.py",
    "content": "\"\"\"\n* EJERCICIO: Iteradores\n\"\"\"\n\n# While\nx = 1\nprint(\"\\nIterando con el while...\")\nwhile x <= 10: print(x); x+=1\n\n# For range\nprint(\"\\nIterando con el for...\")\nfor x in range(1,11):  print(x)\n\n# Iterate list with map O_O\nprint(\"\\nIterando con el list(map)...\")\nlist(map(print, range(1, 11)))\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n\"\"\"\n\n# Recursividad (No es iteración)\n\ndef print_to(x: int):\n    if(x > 0):\n        print_to(x-1)\n        print(x)\n        \nprint(\"\\nCon recursividad:\")\nprint_to(10)"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/ycanas.py",
    "content": "# ------ I. Ejercicio\n\n# 1). for\n\nfor i in range(1, 11):\n    print(i)\n\n# 2). while\n\nc: int = 1\n\nwhile c < 11:\n    print(c)\n    c = c + 1\n\n# 3).\n\nc: list[int] = range(1, 11)\n\nfor i in c:\n    print(i)\n\n\n# ------ Extra\n\n# 4). recursive\n\ndef recursive(n):\n    if n == 10:\n        print(n)\n        return\n    \n    print(n)\n    recursive(n + 1)\n\n\nrecursive(1)\n\n# 5). iter\nnumbers = iter(range(1, 11))\nprint(*numbers)\n\n# 6). iter - next\n\nnumbers = iter(range(1, 11))\n\nwhile True:\n    try:\n        print(next(numbers))\n    except StopIteration:\n        break\n\n# 7). list comprehension\n\n[print(i) for i in range(1, 11)]\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/yenneralayon142.py",
    "content": "\"\"\"\nIteraciones\n\"\"\"\n\n# FOR\n\nfor i in range(1,11):\n    print(i)\n\n#WHILE\n\ni = 1\nwhile i <= 10:\n    print(i)\n    i += 1\n\n# RECURSIVIDAD\ndef count_ten(i = 1):\n    if i <= 10:\n        print(i)\n        count_ten(i + 1)\ncount_ten()\n\n\n\"\"\"\nEjercicio\n\"\"\"\n\nfor i in [1,2,3,4,5,6,7,8,9,10]:\n    print(i)\n\nfor i in {1,2,3,4,5,6,7,8,9}:\n    print(i)\n\nfor i in {1:\"a\",2:\"b\",3:\"c\",4:\"d\",5:\"e\",6:\"f\",7:\"h\",8:\"i\"}:\n    print(i)\n\nprint(*[i for i in range(1,20)], sep='\\n')\n\nfor i in \"Ubosque\":\n    print(i)\n\nfor i in reversed([1,2,3,4]):\n    print(i)\n\nfor i in sorted([\"y\",\"e\",\"n\",\"n\",\"e\",\"r\"]):\n    print(i)\n\nfor i,e in enumerate(sorted([\"y\",\"e\",\"n\",\"n\",\"e\",\"r\"])):\n    print(f\"Indice: {i}, valor: {e}\")\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/python/zetared92.py",
    "content": "# RETO 17 ITERACIONES\n\n\"\"\"\nEMPLEA 3 MECANISMOS DIFERENTES PARA \nIMPRIMIR NÚMEROS DEL 1-10 MEDIANTE ITEACIÓN\n\"\"\"\n\n# FOR\nfor i in range(1,11):\n    print(i)\n\n# WHILE\ni = 1\nwhile i <= 10:\n    print(i)\n    i += 1\n\n# RECURSIVIDAD\ndef count_ten(i=1):\n    if i <= 10:\n        print(i)\n        count_ten(i + 1)\n\ncount_ten()\n\n# Extra\n\nprint(\"🧩 DIFICULTAD EXTRA - MECANISMOS PARA ITERAR VALORES 🧩\")\n\nfor e in [1, 2, 3, 4]:\n    print(e)\n\nfor e in {1, 2, 3, 4}:\n    print(e)\n\nfor e in (1, 2, 3, 4):\n    print(e)\n\nfor e in {1: \"a\", 2: \"b\", 3: \"c\", 4: \"d\"}:\n    print(e)\n\nfor e in {1: \"a\", 2: \"b\", 3: \"c\", 4: \"d\"}.values():\n    print(e)\n\nprint(*[i for i in range(1, 11)], sep=\"\\n\")\n\nfor c in \"Python\":\n    print(c)\n\nfor e in reversed([1, 2, 3, 4]):\n    print(e)\n\nfor e in sorted([\"z\", \"e\", \"t\", \"a\"]):\n    print(e)\n\nfor i, e in enumerate(sorted([\"z\", \"e\", \"t\", \"a\"])):\n    print(f\"Index: {i}, value: {e}\")"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/ruby/Elmer125.rb",
    "content": "#  * EJERCICIO:\n#  * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n#  * números del 1 al 10 mediante iteración.\nputs \"Iterating numbers from 1 to 10 using each\"\n(1..10).each { |i| puts i }\n\nputs \"Iterating numbers from 1 to 10 using times\"\n10.times { |i| puts i + 1 }\n\nputs \"Iterating numbers from 1 to 10 using for\"\nfor i in 1..10\n  puts i\nend\n\nputs \"Iterating numbers from 1 to 10 using while\"\nn = 0\nwhile n < 10\n  puts n + 1\n  n += 1\nend\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Escribe el mayor número de mecanismos que posea tu lenguaje\n#  * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\nputs \"Iterating numbers from 1 to 10 using recursion\"\ndef iterate(n)\n  puts n\n  return n < 10 ? iterate(n + 1) : n\nend\nputs iterate(1)\n\nputs \"Iterating numbers from 1 to 10 using upto\"\n1.upto(10) { |i| puts i }\n\nputs \"Strings\"\nstring = \"Ruby on Rails\"\nstring.each_char { |c| puts c }\nstring.split(\"\").each { |c| puts c }\nstring.scan(/./) { |c| puts c }\n\nputs \"Arrays\"\narray = [1, 2, 3, 4, 5]\narray.each { |i| puts i }\narray.each_index { |i| puts array[i] }\narray.each_with_index { |i, index| puts i }\n\nputs \"Hashes\"\nhash = { a: 1, b: 2, c: 3 }\nhash.each { |k, v| puts \"#{k}: #{v}\" }\nhash.each_key { |k| puts k }\nhash.each_value { |v| puts v }\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/rust/kenysdev.rs",
    "content": "/*\n╔═══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado                ║\n║ GitHub: https://github.com/Kenysdev   ║\n║ 2024 -  Rust                          ║\n╚═══════════════════════════════════════╝\n-----------------------------------------\n* ITERACIONES\n-----------------------------------------\n\n* EJERCICIO #1:\n* Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n* números del 1 al 10 mediante iteración.\n*\n* EJERCICIO #2:\n* Escribe el mayor número de mecanismos que posea tu lenguaje\n* para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n*/\n\nfn main() {\n    //_____________________________\n    println!(\"(1). for\");\n    for num in 1..=10 {\n        println!(\"{}\", num);\n    }\n    \n    //_____________________________\n    println!(\"\\n(2). while\");\n    let mut num = 1;\n    while num <= 10 {\n        println!(\"{}\", num);\n        num += 1;\n    }\n    //_____________________________\n    println!(\"\\n(3). loop\");\n    let mut num = 1;\n    loop {\n        println!(\"{}\", num);\n        num += 1;\n        if num > 10 {\n            break;\n        }\n    }\n\n    //_____________________________\n    println!(\"\\n(4). Método iter()\");\n    let numbers = vec![1, 2, 3, 4, 5];\n    for num in numbers.iter() {\n        println!(\"{}\", num);\n    }\n\n    //_____________________________\n    println!(\"\\n(5). Método iter_mut()\");\n    // Devuelve un iterador mutable que permite modificar los elementos.\n    let mut numbers = vec![1, 2, 3, 4, 5];\n    for num in numbers.iter_mut() {\n        *num *= 2;\n        println!(\"{}\", num);\n    }\n\n    //_____________________________\n    println!(\"\\n(6). Método filter()\");\n    let numbers = vec![1, 2, 3, 4, 5, 6, 7, 8];\n    for num in numbers.iter().filter(|&x| *x % 2 == 0) {\n        println!(\"{}\", num);\n    }\n\n    //_____________________________\n    println!(\"\\n(6). Método zip()\");\n    let numbers = vec![1, 2, 3];\n    let letters = vec!['a', 'b', 'c'];\n    for (num, letter) in numbers.iter().zip(&letters) {\n        println!(\"Number: {}, Letter: {}\", num, letter);\n    }\n\n    //_____________________________\n    println!(\"\\n(7). Método enumerate()\");\n    let numbers = vec![1, 2, 3, 4, 5];\n    for (index, num) in numbers.iter().enumerate() {\n        println!(\"Index: {}, Value: {}\", index, num);\n    }\n\n    //_____________________________\n    println!(\"\\n(8). Método map()\");\n    let numbers = vec![1, 2, 3, 4, 5];\n    let doubled_numbers: Vec<_> = numbers.iter().map(|&x| x * 2).collect();\n    println!(\"{:?}\", doubled_numbers);\n\n}\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/sql/Nicojsuarez2.sql",
    "content": "# #17 ITERACIONES\n> #### Dificultad: Fácil | Publicación: 22/04/24 | Corrección: 29/04/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n * números del 1 al 10 mediante iteración.\n *\n * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/swift/allbertoMD.swift",
    "content": "import Foundation\n\n// Array para iterar.\nvar numbers = [1, 2, 3, 4, 5, 5, 7, 8, 9, 10]\n\n\n// Función recursiva con numeros.\nprint(\"\\nFunción recursiva con numeros.\")\nfunc printNumbers(_ n: Int) {\n    if n > 0 {\n        printNumbers(n - 1)\n        \n        print(n)\n    }\n}\nprintNumbers(10)\n\n\n// Función recursiva con array.\nprint(\"\\nFunción recursiva con array.\")\nfunc printArray(_ a: inout [Int]) {\n    var b: [Int] = a\n    \n    if !b.isEmpty {\n        print(b[0])\n        \n        b.removeFirst()\n        \n        printArray(&b)\n    }\n}\nprintArray(&numbers)\n\n\n// Metodo map, imprime los números del array.\nprint(\"\\nMetodo map.\")\nlet map: [()] = numbers.map { n in\n    print(n)\n}\n\n\n// Metodo forEach, imprime los números del array.\nprint(\"\\nMetodo forEach.\")\nnumbers.forEach { n in\n    print(n)\n}\n\n\n\n\n// DIFICULTAD EXTRA\nprint(\"\\nDIFICULTAD EXTRA.\")\n\n\n// Clouser que imprime los caracteres de un string.\nprint(\"\\nClosure imprime caracteres.\")\nvar string = \"\"\nlet closurePrint: (String) -> Void = { str in\n    string = str\n    if !str.isEmpty {\n        print(str[string.startIndex])\n        string.removeFirst()\n        closurePrint(string)\n\n    }\n}\nclosurePrint(\"Hello\")\n\n\n// Metodo filter, imprime los números del array que sean multiplos de 2.\nprint(\"\\nMetodo filter\")\nlet filter = numbers.filter { n in\n    if n % 2 == 0 {\n        print(n)\n    }\n    return true\n}\n\n\n\n// Metodo reduce, sume 10 a cada uno de los números del array y los imprime.\nprint(\"\\nMetodo reduce.\")\nlet reduce = numbers.reduce(into: 10) { n1, n2 in\n    print(n1 + n2)\n}\n\n\n// Metodo sequencee, inicia una secuencia en 10 y le eleva al cubo tantas veces como sea indicado.\nprint(\"\\nMetodo sequence.\")\nlet seq = sequence(first: 10) { n in\n    pow(n, 3)\n}\n// Se eleva 4 veces al cubo el numero 10 e imprime los números.\nlet firstFour: [()] = Array(seq.prefix(4)).map { n in\n    print(n)\n}\n\n\n// Metodo sort, ordena de mayor a menor e imprime los numeros.\nprint(\"\\nMetodo sort.\")\nnumbers.sort { n1, n2 in\n    n1 > n2\n}\nnumbers.forEach { n in\n    print(n)\n}\n\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/swift/blackriper.swift",
    "content": "/* iteractors son una forma de recorrer una colección de datos\n   en swift contamos con los protocolos IteratorProtocol y Sequence \n   para poder crear nuestros propios iteradores\n */\n\n\nimport Foundation\n\n\nfunc examplesWithIterators() {\n  let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n\n  print(\"using for in\")\n  for number in numbers {\n    print(number)\n  }\n\n  print(\"using forEach\")\n  numbers.forEach { number in\n    print(number)\n  }\n\n  print(\"using repeat while\")\n  var index = 0\n  repeat {\n    print(numbers[index])\n    index += 1\n  } while index < numbers.count\n\n}\n\nexamplesWithIterators()\n\n// ejercicio extra\n\nfunc examplesWithOtherIterators() {\n  let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n\n   print(\"usando while\")\n   var index = 0\n   while index < numbers.count {\n     print(numbers[index])\n     index += 1\n   }\n    \n   print(\"using custom struct\")\n   struct MyIterator: Sequence,IteratorProtocol {\n       var current = 1\n       mutating func next() -> Int? {\n           defer { current += 1 }\n           return current\n       }\n   }\n   var i=0\n   for number in MyIterator() {\n       i+=1\n       if i == 10 {break}\n       print(number)\n   }\n\n   print(\"using for range \")\n   for number in 1...10 {\n       print(number)\n   }\n}\n\nexamplesWithOtherIterators()\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/swift/pedroomar23.swift",
    "content": "import Foundation\n\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n * números del 1 al 10 mediante iteración.\n *\n * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n */\n\nlet numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n\n// Metodo for-in \nfor i in numeros {\n    print(i)\n}\n\n// Metodo ForEach \nnumeros.forEach { number in \n    print(number)\n}\n\n// Metodo repeat-while \nvar number = 0 \nrepeat {\n    print(numeros[number])\n    number += 1\n} while number < numeros.count \n\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/typescript/AChapeton.ts",
    "content": "// FOR\nconsole.log('FOR')\nfor(let i: number = 0; i <= 10; i++){\n  console.log(i)\n}\n\n// FOREACH\nconsole.log('FOREACH')\nconst numbers: Array<number> = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\nnumbers.forEach(i => {\n  console.log(i)\n});\n\n\n// FOR IN\nconsole.log('FOR IN')\nfor(const i in numbers){\n  console.log(numbers[i])\n}\n\n// FOR OF\nconsole.log('FOR OF')\nfor(const i of numbers){\n  console.log(i)\n}\n\n// WHILE\nconsole.log('WHILE')\nlet w: number = 0\nwhile(w < 11){\n  console.log(w)\n  w++\n}\n\n\n// DO-WHILE\nconsole.log('DO-WHILE')\nlet d: number = 0\ndo{\n  console.log(d)\n  d++\n}while(d < 11)\n\n\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/typescript/IgleDev.ts",
    "content": "// Ejercicio 1º\n\n    // Interación por Bucle For\n        for(let i : number = 1; i <= 10; i++){\n            console.log(`Número ${i}`);\n        }\n    // Iteración por While\n        let iWhile = 1\n        while(iWhile <= 10){\n            console.log(`Número ${iWhile}`);\n            iWhile++;\n        }\n    // Iteración con doWhile\n        let iDoWhile = 1\n        do{\n            console.log(`Número ${iDoWhile}`);\n            iDoWhile++;\n        }while(iDoWhile<= 10)\n\n//Ejercicio Extra\n    let numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n    // Iteración con For of\n        for (let num of numeros) {\n            console.log(num);\n        }\n    // Iteración con For each\n        numeros.forEach(num => console.log(num));\n    // Iteración con Map\n        numeros.map(num => console.log(num));\n    // Iteración con entries\n        let numerosEntries = [...Array(10).keys()].map(x => x + 1);\n        for (let [value] of numerosEntries.entries()) {\n            console.log(value);\n        }\n    // Iteración con Recursión\n        function printarNumeros(start: number, end: number) {\n            if (start <= end) {\n                console.log(start);\n                printarNumeros(start + 1, end);\n            }\n        }\n        printarNumeros(1, 10);\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/typescript/Sac-Corts.ts",
    "content": "console.log(\"for\");\nfor (let i: number = 1; i <= 10; i++) {\n    console.log(i);\n}\n\nconsole.log(\"while\");\nlet n: number = 1;\nwhile (n <= 10) {\n    console.log(n);\n    n++;\n}\n\nconsole.log(\"do while\");\nn = 1;\ndo {\n    console.log(n);\n    n++;\n} while (n <= 10);\n\n// ** Extra Exercise ** //\nconsole.log(\"for of\");\nconst numbers: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\nfor (const number of numbers) {\n    console.log(number);\n}\n\nconsole.log(\"for in\");\nfor (const index in numbers) {\n    console.log(numbers[index]);\n}\n\nconsole.log(\"forEach\");\nnumbers.forEach((number: number) => {\n    console.log(number);\n});\n\nconsole.log(\"map\");\nnumbers.map((number: number) => {\n    console.log(number);\n});\n\nconsole.log(\"Array.from\");\nArray.from({ length: 10 }, (_, i: number) => console.log(i + 1));\n\nconsole.log(\"reduce\");\nnumbers.reduce((_, number: number) => {\n    console.log(number);\n    return number;\n}, 0);\n\nconsole.log(\"Recursion\");\nfunction printNumbers(n: number): void {\n    if (n > 10) return;\n    console.log(n);\n    printNumbers(n + 1);\n}\n\nprintNumbers(1);\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/typescript/duendeintemporal.ts",
    "content": "// #17 { retosparaprogramadores } - ITERACIONES    \n/*\n * EJERCICIO:\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n * números del 1 al 10 mediante iteración.\n *\n * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n */\n\n// short for console.log\nlet log = console.log;\n\n// Conditional check for browser environment\nif (typeof window !== 'undefined') {\n    window.addEventListener('load', () => {\n        const body: HTMLBodyElement | null = document.querySelector('body');\n        const title = document.createElement('h1');\n\n        body?.style.setProperty('background', '#000');\n        body?.style.setProperty('text-align', 'center');\n\n        title.textContent = 'Retosparaprogramadores #17.';\n        title.style.setProperty('font-size', '3.5vmax');\n        title.style.setProperty('color', '#fff');\n        title.style.setProperty('line-height', '100vh');\n\n        body?.appendChild(title);\n\n        setTimeout(() => {\n            alert('Retosparaprogramadores #17. Please open the Browser Developer Tools.');\n        }, 2000);\n        log('Retosparaprogramadores #17');\n});\n} else {\n    log('This code is designed to run in a browser environment. Skipping window-related code.');\n    log('Retosparaprogramadores #17');\n}\nfor(let i = 1; i <= 10; i++){\n    log(i);\n}\n\nlet count: number = 0;\nwhile(count < 10){\n    count ++;\n    log(count); // log numbers from 1 to 10\n}\n\n// forEach method\nlet nums: number[] = [1,2,3,4,5,6,7,8,9,10];\nnums.forEach(n=>log(n)); // log numbers from 1 to 10\n\n//Extra Dificulty Exercise\n\n// do while\nlet i: number = 0;\ndo {\n    console.log(i);\n    i++;\n} while (i < 5); // log numbers fronm 0 to 4\n\n\n// Note: in the tsconfig.json\n // Enable 'downlevelIteration' to support iterating over iterators (e.g., Array.prototype.entries(),\n        // Array.prototype.keys(), Array.prototype.values()) in environments that do not natively support them\n        // (e.g., ES5 or older). This flag generates additional helper code to make iteration work correctly.\n        // Without this flag, TypeScript throws errors when using modern iteration features with older targets.\n       // \"downlevelIteration\": true,\n\n\n//map method\nconst arr: number[] = [1, 2, 3, 4, 5];\nconst doubled = arr.map((value) => value * 2);\nlog(doubled); // [2, 4, 6, 8, 10]\n\n// filter method\nconst arr1: number[] = [1, 2, 3, 4, 5];\nconst evenNumbers = arr1.filter((value) => value % 2 === 0);\nlog(evenNumbers); // [2, 4]\n\n// reduce method\nconst arr2: number[] = [1, 2, 3, 4, 5];\nconst sum = arr2.reduce((total, current) => total + current, 0);\nlog(sum); // 15\n\n// some method\nconst arr3: number[] = [1, 2, 3, 4, 5];\nconst hasEven = arr3.some((value) => value % 2 === 0);\nlog(hasEven); // true\n\n// every method\nconst arr4: number[] = [1, 2, 3, 4, 5];\nconst allEven = arr4.every((value) => value % 2 === 0);\nlog(allEven); // false\n\n// For of...\nconst arr5: number[] = [1, 2, 3, 4, 5];\nfor (const value of arr5) {\n    log(value); // Logs: 1 2 3 4 5\n}\n\n// Iteración con entries\nconst arr6: string[] = ['a', 'b', 'c'];\nfor (const [index, value] of arr6.entries()) {\n    log(index, value); // 0 'a' 1 'b' 2 'c'\n}\n\nconst obj1: { [key: string]: number } = { a: 1, b: 2, c: 3 };\nfor (const [key, value] of Object.entries(obj1)) {\n    log(key, value); // a 1 b 2 c 3\n}\n\n// Iteración con keys\nconst arr7: string[] = ['a', 'b', 'c'];\nfor (const index of arr7.keys()) {\n    log(index); // 0 1 2\n}\n\nconst obj2: { [key: string]: number } = { a: 1, b: 2, c: 3 };\nfor (const key of Object.keys(obj2)) {\n    log(key); // a b c\n}\n\n// Iteración con values\nconst arr8: string[] = ['a', 'b', 'c'];\nfor (const value of arr8.values()) {\n    log(value); // a b c\n}\n\nconst obj3: { [key: string]: number } = { a: 1, b: 2, c: 3 };\nfor (const value of Object.values(obj3)) {\n    log(value); // 1 2 3\n}\n\nconst obj: { [key: string]: number } = { a: 1, b: 2, c: 3 };\nfor (const key in obj) {\n    log(`${key}: ${obj[key]}`); // a: 1 b: 2 c: 3\n}\n\n// Note2: I share my tsconfig.json\n/*\n{\n    \"compilerOptions\": {\n        // Set the target JavaScript version to ES6 (ECMAScript 2015).\n        // This ensures that TypeScript generates modern JavaScript code.\n        \"target\": \"es6\",\n\n        // Enable 'downlevelIteration' to support iterating over iterators (e.g., Array.prototype.entries(),\n        // Array.prototype.keys(), Array.prototype.values()) in environments that do not natively support them\n        // (e.g., ES5 or older). This flag generates additional helper code to make iteration work correctly.\n        // Without this flag, TypeScript throws errors when using modern iteration features with older targets.\n        \"downlevelIteration\": true,\n\n        // Use CommonJS as the module system. This is the default module system for Node.js.\n        \"module\": \"commonjs\",\n\n        // Enable all strict type-checking options to enforce stricter type safety in the codebase.\n        \"strict\": true,\n\n        // Enable ES module interoperability. This allows using ES modules with CommonJS modules seamlessly.\n        \"esModuleInterop\": true,\n\n        // Skip type checking of declaration files (e.g., .d.ts files). This can improve compilation speed.\n        \"skipLibCheck\": true,\n\n        // Ensure consistent casing in file names. This helps avoid issues on case-sensitive file systems.\n        \"forceConsistentCasingInFileNames\": true\n    },\n\n    // Include all files in the current directory and its subdirectories for compilation.\n    */ \n   // \"include\": [\"./**/*\"],\n\n    // Exclude files in the '../Javascript' and '../Python' directories from compilation.\n    // This prevents TypeScript from processing unrelated files in those directories.\n   // \"exclude\": [\"../Javascript/**/*\", \"../Python/**/*\"]\n//}\n\n\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/typescript/eulogioep.ts",
    "content": "/**\n * Demostración de diferentes mecanismos de iteración en TypeScript\n * \n * TypeScript extiende JavaScript añadiendo tipos estáticos y algunas\n * características adicionales, lo que nos permite escribir código\n * más robusto y mantenible.\n */\n\n// Configuración inicial para algunos ejemplos\nconst numbers: number[] = Array.from({length: 10}, (_, i) => i + 1);\n\nclass IterationDemo {\n    private static printNumbers(numbers: number[]): void {\n        console.log(numbers.join(' '));\n    }\n\n    // 1. Bucle for tradicional\n    static forLoop(): void {\n        console.log(\"1. Usando bucle for tradicional:\");\n        const result: number[] = [];\n        for (let i: number = 1; i <= 10; i++) {\n            result.push(i);\n        }\n        this.printNumbers(result);\n    }\n\n    // 2. Bucle while\n    static whileLoop(): void {\n        console.log(\"\\n2. Usando bucle while:\");\n        const result: number[] = [];\n        let count: number = 1;\n        while (count <= 10) {\n            result.push(count);\n            count++;\n        }\n        this.printNumbers(result);\n    }\n\n    // 3. Bucle do...while\n    static doWhileLoop(): void {\n        console.log(\"\\n3. Usando bucle do...while:\");\n        const result: number[] = [];\n        let num: number = 1;\n        do {\n            result.push(num);\n            num++;\n        } while (num <= 10);\n        this.printNumbers(result);\n    }\n\n    // 4. forEach con array\n    static forEachLoop(): void {\n        console.log(\"\\n4. Usando forEach con array:\");\n        const result: number[] = [];\n        numbers.forEach((num: number): void => {\n            result.push(num);\n        });\n        this.printNumbers(result);\n    }\n\n    // 5. for...of loop\n    static forOfLoop(): void {\n        console.log(\"\\n5. Usando for...of:\");\n        const result: number[] = [];\n        for (const num of numbers) {\n            result.push(num);\n        }\n        this.printNumbers(result);\n    }\n\n    // 6. Array.map\n    static arrayMap(): void {\n        console.log(\"\\n6. Usando Array.map:\");\n        const result: number[] = Array.from({length: 10}).map((_, i: number): number => i + 1);\n        this.printNumbers(result);\n    }\n\n    // 7. Recursión con tipo de retorno explícito\n    static recursion(n: number = 1, result: number[] = []): number[] {\n        if (n <= 10) {\n            result.push(n);\n            return this.recursion(n + 1, result);\n        }\n        return result;\n    }\n\n    static showRecursion(): void {\n        console.log(\"\\n7. Usando recursión:\");\n        const result: number[] = this.recursion();\n        this.printNumbers(result);\n    }\n\n    // 8. Generator function con tipo Generator\n    static *numberGenerator(): Generator<number, void, unknown> {\n        for (let i: number = 1; i <= 10; i++) {\n            yield i;\n        }\n    }\n\n    static showGenerator(): void {\n        console.log(\"\\n8. Usando Generator function:\");\n        const result: number[] = [...this.numberGenerator()];\n        this.printNumbers(result);\n    }\n\n    // 9. Implementación de Iterable\n    static iterableExample(): void {\n        console.log(\"\\n9. Usando implementación de Iterable:\");\n        \n        class NumberRange implements Iterable<number> {\n            constructor(private start: number, private end: number) {}\n\n            *[Symbol.iterator](): Iterator<number> {\n                for (let i: number = this.start; i <= this.end; i++) {\n                    yield i;\n                }\n            }\n        }\n\n        const numberRange = new NumberRange(1, 10);\n        const result: number[] = [...numberRange];\n        this.printNumbers(result);\n    }\n\n    // 10. Reduce con tipos explícitos\n    static reduceExample(): void {\n        console.log(\"\\n10. Usando Reduce:\");\n        const result: number[] = numbers.reduce((acc: number[], curr: number): number[] => {\n            acc.push(curr);\n            return acc;\n        }, []);\n        this.printNumbers(result);\n    }\n}\n\n// Ejecutar todas las demostraciones\nconsole.log(\"=== Demostración de Mecanismos de Iteración en TypeScript ===\\n\");\n\nIterationDemo.forLoop();\nIterationDemo.whileLoop();\nIterationDemo.doWhileLoop();\nIterationDemo.forEachLoop();\nIterationDemo.forOfLoop();\nIterationDemo.arrayMap();\nIterationDemo.showRecursion();\nIterationDemo.showGenerator();\nIterationDemo.iterableExample();\nIterationDemo.reduceExample();\n\nconsole.log(\"\\n=== Fin de la demostración ===\");\n\n// Ejemplo de uso con tipos genéricos\ninterface IterableCollection<T> {\n    forEach(callback: (item: T) => void): void;\n}\n\nclass NumberCollection implements IterableCollection<number> {\n    constructor(private numbers: number[]) {}\n\n    forEach(callback: (item: number) => void): void {\n        for (const num of this.numbers) {\n            callback(num);\n        }\n    }\n}\n\n// Bonus: Demostración de uso de la interfaz genérica\nconsole.log(\"\\nBonus: Usando interfaz genérica IterableCollection:\");\nconst collection = new NumberCollection(numbers);\nconst result: number[] = [];\ncollection.forEach((num: number): void => {\n    result.push(num);\n});\nconsole.log(result.join(' '));"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/typescript/hozlucas28.ts",
    "content": "/*\n    Iterations...\n*/\n\nconsole.log('Iterations...')\n\nconst FROM: number = 0\nconst TO: number = 10\n\nfunction recursiveFn(from: number, to: number): void {\n\tconsole.log(`${from}`)\n\tfrom < to && recursiveFn(from + 1, to)\n}\n\nconsole.log('\\nFirst method...\\n')\nrecursiveFn(FROM, TO)\n\nconsole.log('\\nSecond method...\\n')\nfor (let i: number = FROM; i <= TO; i++) console.log(`${i}`)\n\nconsole.log('\\nThird method...\\n')\nlet nJ: number = FROM\nwhile (nJ <= TO) {\n\tconsole.log(`${nJ}`)\n\tnJ++\n}\n\nconsole.log(\n\t'\\n# ---------------------------------------------------------------------------------- #\\n'\n)\n\n/*\n    Additional challenge...\n*/\n\nconsole.log('Additional challenge...')\n\nconsole.log('\\nFirst method...\\n')\nrecursiveFn(FROM, TO)\n\nconsole.log('\\nSecond method...\\n')\nfor (let i: number = FROM; i <= TO; i++) console.log(`${i}`)\n\nconsole.log('\\nThird method...\\n')\nnJ = FROM\nwhile (nJ <= TO) {\n\tconsole.log(`${nJ}`)\n\tnJ++\n}\n\nconsole.log('\\nFourth method...\\n')\nnJ = FROM\ndo {\n\tconsole.log(`${nJ}`)\n\tnJ++\n} while (nJ <= TO)\n\nconsole.log('\\nFifth method...\\n')\nArray.from({ length: TO }, (_, i) => i + 1).map((_, index) =>\n\tconsole.log(`${index + 1}`)\n)\n\nconsole.log('\\nSixth method...\\n')\nArray.from({ length: TO }, (_, i) => i + 1).forEach((value, index) => {\n\tconsole.log(`${index + 1}`)\n\treturn value\n})\n\nconsole.log('\\nSeventh method...\\n')\nArray.from({ length: TO }, (_, i) => i + 1).reduce((_, current, currentI) => {\n\tconsole.log(`${currentI + 1}`)\n\treturn current\n}, 0)\n\nconsole.log('\\nEighth method...\\n')\nArray.from({ length: TO }, (_, i) => i + 1).every((_, index) => {\n\tconsole.log(`${index + 1}`)\n\treturn true\n})\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/typescript/nlarrea.ts",
    "content": "/*\n * EJERCICIO:\n * Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n * números del 1 al 10 mediante iteración.\n *\n * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n */\n\n\n// OPTION 1\n\nconsole.log('OPTION 1: for loop')\n\nfor (let num = 1; num <= 10; num++) {\n    console.log(num)\n}\n\n// OPTION 2\n\nconsole.log('OPTION 2: while loop')\n\nlet num: number = 1\nwhile (num <= 10) {\n    console.log(num)\n    num++\n}\n\n// OPTION 3\n\nconsole.log('OPTION 3: recursive function call')\n\nfunction count(start: number, stop: number) {\n    console.log(start)\n\n    if (start >= stop) {\n        return\n    }\n\n    count(start + 1, stop)\n}\n\ncount(1, 10)\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Escribe el mayor número de mecanismos que posea tu lenguaje\n * para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n */\n\n\n// En los ejemplos anteriores hemos mostrado 3 formas diferentes\n\n// 4. Do-While\n\nnum = 1\ndo {\n    console.log(num)\n    num++\n} while (num <= 10)\n    \n// Para seguir con otros ejemplos, creamos el siguiente array: [0, ..., 9]\nconst numbers: number[] = [...Array(10).keys()]\n\n// 5. For Each\n\nnumbers.forEach(num => {\n    console.log(num)\n})\n\n// 6. For in\n\nfor (const index in numbers) {\n    console.log(numbers[index])  // -> index\n}\n\n// 7. For of\n\nfor (const num of numbers) {\n    console.log(num)\n}\n\n// 8. Map\n\nnumbers.map(num => {\n    console.log(num)\n})"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/typescript/victor-Casta.ts",
    "content": "// 1. for\nfor(let i:number = 1; i <= 10; i++) {\n  console.log(i)\n}\n\n// 2. while\nlet i:number = 1\nwhile (i <= 10) {\n  console.log(i)\n  i++\n}\n\n// 3. do while\nlet j: number = 1\ndo {\n  console.log(j)\n  j++\n} while (j <= 10)\n\n// extra\n\n\nconst numbers: number[] = [1, 2, 3, 4, 5]\n\n// 4. for of\nconsole.log(\"4. for...of\")\nfor (const number of numbers) {\n  console.log(number)\n}\n\n// 5. for in\nconsole.log(\"5. for...in\")\nfor (const index in numbers) {\n  console.log(numbers[index])\n}\n\n// 6. forEach\nconsole.log(\"6. forEach\")\nnumbers.forEach((number) => {\n  console.log(number)\n});\n\n// 7. map\nconsole.log(\"7. map\")\nnumbers.map((number) => {\n  console.log(number)\n});\n\n// 8. filter\nconsole.log(\"8. filter\")\nnumbers.filter((number) => {\n  console.log(number)\n  return true\n});\n\n// 9. reduce\nconsole.log(\"9. reduce\");\nnumbers.reduce((_, number) => {\n  console.log(number)\n  return 0\n}, 0)\n\n// 10. every\nconsole.log(\"10. every\");\nnumbers.every((number) => {\n  console.log(number)\n  return true\n})\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/typescript/victoriaparraf.ts",
    "content": "let i:number = 1;\n\nfor(i; i<=10; i++){\n    console.log(i);\n}\n\nwhile(i<=10){\n    console.log(i);\n    i++;\n}\n\nfunction imprimir(numero:number):void{\n    if(numero<=10){\n        console.log(numero);\n        imprimir(numero+1);\n    }else return;\n}\n\nimprimir(i);\n\n/*Extraaaaa */\n\nlet j = 1;\ndo {\n    console.log(j);\n    j++;\n} while (j <=10);\n\nconst array = [1, 2, 3, 4, 5];\nfor (const value of array) {\n    console.log(value);\n}\n\nconst object = { a: 1, b: 2, c: 3 };\nfor (const key in object) {\n    if (object.hasOwnProperty(key)) {\n        console.log(`${key}: ${object[key]}`);\n    }\n}\n\nconst numbers = [1, 2, 3, 4, 5];\nnumbers.forEach((number) => {\n    console.log(number);\n});\n\nconst doubled = numbers.map((number) => number * 2);\nconsole.log(doubled);\n\nconst sum = numbers.reduce((acc, number) => acc + number, 0);\nconsole.log(sum);\n\nconst hasEvenNumber = numbers.some((number) => number % 2 === 0);\nconsole.log(hasEvenNumber); // true\n\n"
  },
  {
    "path": "Roadmap/17 - ITERACIONES/vb.net/kenysdev.vb",
    "content": "' ╔══════════════════════════════════════╗\n' ║ Autor:  Kenys Alvarado               ║\n' ║ GitHub: https://github.com/Kenysdev  ║\n' ║ 2024 -  VB.NET                       ║\n' ╚══════════════════════════════════════╝\n'-----------------------------------------------\n'* ITERACIONES\n'-----------------------------------------------\n\nModule Program\n    '* EJERCICIO #1:\n    '* Utilizando tu lenguaje, emplea 3 mecanismos diferentes para imprimir\n    '* números del 1 al 10 mediante iteración.\n    '*\n    '* EJERCICIO #2:\n    '* Escribe el mayor número de mecanismos que posea tu lenguaje\n    '* para iterar valores. ¿Eres capaz de utilizar 5? ¿Y 10?\n\n    Sub Main()\n        '_____________________________\n        Console.WriteLine(\"(1). for\")\n        For n As Integer = 1 To 10\n            Console.WriteLine(n)\n        Next\n\n        '_____________________________\n        Console.WriteLine(vbCrLf & \"(2). while\")\n        Dim num As Integer = 1\n        While num <= 10\n            Console.WriteLine(num)\n            num += 1\n        End While\n\n        '_____________________________\n        Console.WriteLine(vbCrLf & \"(3). foreach\")\n        For Each n As Integer In Enumerable.Range(1, 10)\n            Console.WriteLine(n)\n        Next\n\n        '_____________________________\n        Console.WriteLine(vbCrLf & \"(4). do-while\")\n        Dim nu As Integer = 1\n        Do\n            Console.WriteLine(nu)\n            nu += 1\n        Loop While nu <= 10\n\n        '_____________________________\n        Console.WriteLine(vbCrLf & \"(5). Do Until\")\n        Dim i As Integer = 0\n\n        Do Until i >= 5\n            Console.WriteLine(i)\n            i += 1\n        Loop\n\n        '_____________________________\n        Console.WriteLine(vbCrLf & \"(6). LINQ\")\n        Dim numbers = Enumerable.Range(1, 10).ToList()\n        Dim evenNumbers = From x In numbers\n                          Where x Mod 2 = 0\n                          Select x\n\n        For Each num In evenNumbers\n            Console.WriteLine(num)\n        Next\n\n        '_____________________________\n        Console.WriteLine(vbCrLf & \"(7). Iterators yield\")\n        For Each n As Integer In Nums()\n            Console.WriteLine(n)\n        Next\n\n    End Sub\n\n    Iterator Function Nums() As IEnumerable(Of Integer)\n        For n As Integer = 1 To 10\n            Yield n\n        Next\n    End Function\n\nEnd Module\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/bash/rantamhack.sh",
    "content": "#!/bin/bash\n\n# EJERCICIO:\n# Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n# operaciones (debes utilizar una estructura que las soporte):\n# - Inserta un elemento al final.\n# - Inserta un elemento al principio.\n# - Inserta varios elementos en bloque al final.\n# - Inserta varios elementos en bloque en una posicion concreta.\n# - Elimina un elemento en una posicion concreta.\n# - Actualiza el valor de un elemento en una posicion concreta.\n# - Comprueba si un elemento esta en un conjunto.\n# - Elimina todo el contenido del conjunto.\n\ngroup=(Miguel Ana Juan Rantamplan Helena Brais)\n\necho \"Los elementos que conforman ahora mismo el conjunto group son: ${group[*]}\"\n\necho -e \"\\n=====================\\n\"\n\ngroup=(\"${group[@]}\" Raul)\necho \"Inserto un elemento al final del conjunto: ${group[*]}\"\n\necho -e \"\\n=====================\\n\"\n\ngroup=(Luis \"${group[@]}\")\necho \"Inserto un elemento al principio del conjunto: ${group[*]}\"\n\necho -e \"\\n=====================\\n\"\n\ngroup=(\"${group[@]}\" Jaime Isabel Rosa) \necho \"Inserto varios elementos en bloque al final del conjunto: ${group[*]}\"\n\necho -e \"\\n=====================\\n\"\n\ngroup=(\"${group[@]:0:2}\" Fernando Cristina Jon \"${group[@]:3}\")  \necho \"Inserto en bloque 3 elementos en la posicion 2 del conjunto: ${group[*]}\"\n\necho -e \"\\n=====================\\n\"\n\nunset 'group[4]'\necho \"Elimino el elemento elegido (4 - Jon) del conjunto: ${group[*]}\"\n\necho -e \"\\n=====================\\n\"\n\ngroup[6]=\"Rantamhack\"\necho \"Actualizo el elemento elegido (6 - Rantamplan) del conjunto: ${group[*]}\"\n# El elemento a actualizar es el '6º' porque borrando el 4º con 'unset' lo elimina pero el hueco sigue existiendo\n\necho -e \"\\n=====================\\n\"\n\nif [[ \"${group[*]}\" =~ \"Jon\" ]]; then\n    echo \"El elemento pertenece a 'group'\"\nelse\n    echo \"El elemento no pertenece 'group'\"\nfi\n\necho -e \"\\n=====================\\n\"\n\nunset group\necho  \"${group[*]}\"\n\n\n\n# DIFICULTAD EXTRA (opcional):\n# Muestra ejemplos de las siguientes operaciones con conjuntos:\n# - Union.\n# - Interseccion.\n# - Diferencia.\n# - Diferencia simetrica.\n\n\necho -e \"\\n\\n=======================================DIFICULTAD EXTRA=======================================\\n\\n\"\n\nalumnos_ciencias=('Luis' 'Miguel' 'Fernando' 'Cristina' 'Ana' 'Juan')\n\nalumnos_letras=('Helena' 'Brais' 'Ana' 'Juan' 'Raul' 'Jaime' 'Luis' 'Isabel' 'Miguel' 'Rosa')\n\ntotal_alumnos=($(echo \"${alumnos_ciencias[@]}\" \"${alumnos_letras[@]}\" | tr ' ' '\\n' | sort -u)) \n\necho -e \"El total de alumnos matriculados es: ${total_alumnos[*]}\"\n\necho -e \"\\n=====================\\n\"\n\nalumnos_mixtos=$(printf \"%s\\n\" \"${alumnos_ciencias[@]}\" | grep -F -e \"$(printf \"%s\\n\" \"${alumnos_letras[@]}\")\")  \necho -e \"El total de alumnos matriculados en las dos ramas: ${alumnos_mixtos[*]}\"\n\necho -e \"\\n=====================\\n\"\n\nalumnos_solo_ciencias=($(comm -23 <(printf \"%s\\n\" \"${alumnos_ciencias[@]}\" | sort) <(printf \"%s\\n\" \"${alumnos_letras[@]}\" | sort)))\n\necho -e \"Alumnos matriculados solo en ciencias: ${alumnos_solo_ciencias[*]}\"\n\nalumnos_solo_letras=($(comm -13 <(printf \"%s\\n\" \"${alumnos_ciencias[@]}\" | sort) <(printf \"%s\\n\" \"${alumnos_letras[@]}\" | sort)))\n\necho -e \"\\nAlumnos matriculados solo en letras: ${alumnos_solo_letras[*]}\"\n\necho -e \"\\n=====================\\n\"\n\nalumnos_una_matricula=($(comm -3 <(printf \"%s\\n\" \"${alumnos_ciencias[@]}\" | sort) <(printf \"%s\\n\" \"${alumnos_letras[@]}\" | sort)))\n\necho -e \"Alumnos matriculados solo en una rama sin importar cual: ${alumnos_una_matricula[*]}\"\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/c#/SBS24.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Conjuntos\n{\n    internal class Program\n    {\n        static void Main(string[] args)\n        {\n            /*\n             * EJERCICIO:\n             * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n             * operaciones (debes utilizar una estructura que las soporte):*/\n            List<string> conjuntos = new List<string>();\n            conjuntos.Add(\"casa\");\n            conjuntos.Add(\"coche\");\n            conjuntos.Add(\"llaves\");\n\n            List<string> conjuntos2 = new List<string>();\n            conjuntos2.Add(\"casa2\");\n            conjuntos2.Add(\"coche\");\n            conjuntos2.Add(\"llaves2\");\n\n            List<string> conjuntos3 = new List<string>();\n            conjuntos3.Add(\"casa3\");\n            conjuntos3.Add(\"coche3\");\n            conjuntos3.Add(\"llaves3\");\n\n            List<string> conjuntos4 = new List<string>();\n            conjuntos4.Add(\"casa4\");\n            conjuntos4.Add(\"coche4\");\n            conjuntos4.Add(\"llaves4\");\n\n            /* - Añade un elemento al final.*/\n            conjuntos.Add(\"final\");            \n\n            /* - Añade un elemento al principio.*/\n            conjuntos.Insert(0, \"principio\");\n            \n            /* - Añade varios elementos en bloque al final.*/\n            conjuntos.AddRange(conjuntos2);\n\n            /* - Añade varios elementos en bloque en una posición concreta.*/\n            conjuntos.InsertRange(3, conjuntos3);//pendiente de que lo inserte en una posición concreta\n            \n            /* - Elimina un elemento en una posición concreta.*/            \n            conjuntos.RemoveRange(1, 1);//borra 1 elemento (casa) que esta en la posición 1\n\n            /* - Actualiza el valor de un elemento en una posición concreta.*/\n            conjuntos[5] = \"Posicion actualizada 5\";\n            /* - Comprueba si un elemento está en un conjunto.*/\n            if (conjuntos.IndexOf(\"casa2\") != -1)\n            {\n                Console.WriteLine(\"El elemento está en la posición \" + (conjuntos.IndexOf(\"casa2\") + 1));\n            }\n            else \n            {\n                Console.WriteLine(\"El elemento no está en la lista\");\n            }\n\n            /* - Elimina todo el contenido del conjunto.*/\n            conjuntos4.RemoveRange(0, (conjuntos4.Count() - 1));            \n\n            /*\n            /* DIFICULTAD EXTRA (opcional):\n            /* Muestra ejemplos de las siguientes operaciones con conjuntos:\n            /* - Unión.*/\n            conjuntos2 = conjuntos2.Concat(conjuntos4).ToList();\n\n            /* - Intersección.*/\n            IEnumerable<string> both = conjuntos.Intersect(conjuntos2);            \n\n            /* - Diferencia.*/\n            var diferencias = conjuntos.Except(conjuntos2);\n            var diferencias2 = conjuntos2.Except(conjuntos);\n\n            /* - Diferencia simétrica.*/\n            var primer_conjunto = conjuntos.ToHashSet();\n            primer_conjunto.SymmetricExceptWith(conjuntos2);\n            var dif_simetrica = primer_conjunto.ToList();\n\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/c#/hequebo.cs",
    "content": "class Program\n{\n    static void Main(string[] args)\n    {\n        #region Conjuntos\n        // Conjuntos\n        Console.WriteLine(\"----Conjuntos----\");\n        var conjunto = new List<int> { 1, 2, 3, 4, 5, 6 };\n        Console.Write(\"Conjunto inicial: \");\n        Console.Write(string.Join(\", \", conjunto));\n        Console.WriteLine();\n\n        // Agregar elemento al final\n        conjunto.Add(7);\n        Console.Write(\"Agregar elemento al final con .Add(item): \");\n        Console.Write(string.Join(\", \", conjunto));\n        Console.WriteLine();\n\n        // Agregar elemento al inicio\n        conjunto.Insert(0, 0);\n        Console.Write(\"Agregar elemento al inicio con .Insert(index, item): \");\n        Console.Write(string.Join(\", \", conjunto));\n        Console.WriteLine();\n\n        // Agregar varios elementos al final del bloque\n        conjunto.AddRange(new List<int> { 11, 12, 15, 14 });\n        Console.Write(\"Agregar varios elementos al final con .AddRange(collection): \");\n        Console.Write(string.Join(\", \", conjunto));\n        Console.WriteLine();\n\n        // Agregar varios elementos en posición concreta\n        conjunto.InsertRange(8, new List<int> { 8, 9, 10 });\n        Console.Write(\"Agregar varios elementos en posición específica con .InsertRange(index, collection): \");\n        Console.Write(string.Join(\", \", conjunto));\n        Console.WriteLine();\n\n        // Eliminar elemnto en posición específica\n        conjunto.RemoveAt(13);\n        Console.Write(\"Eliminar un elemento en posición específica con .RemoveAt(index): \");\n        Console.Write(string.Join(\", \", conjunto));\n        Console.WriteLine();\n\n        // Actualizar elemento en posición específica\n        conjunto[13] = 13;\n        Console.Write(\"Actualzar un elemento en posición específica con collection[index] = value: \");\n        Console.Write(string.Join(\", \", conjunto));\n        Console.WriteLine();\n\n        // Comprobar si un elemento existe en el conjunto\n        Console.WriteLine(\"Buscar elemento en conjubto con Contains(item)\");\n        if (conjunto.Contains(6))\n            Console.WriteLine(\"Dentro del conjunto existe el elemento 6\");\n\n        // Eliminar todo el contenido del conjunto \n        conjunto.Clear();\n        Console.WriteLine(\"Se eliminan todos los elmentos del conjunto to .Clear()\");\n        #endregion\n\n        #region Extra\n        // Ejercicio Extra\n        Console.ReadLine();\n        Console.Clear();\n        Console.WriteLine(\"----Extra----\");\n        var conjunto1 = new List<int> { 5, 7, 6, 2, 0 };\n        var conjunto2 = new List<int> { 5, 3, 1, 0, 9 };\n\n        Console.Write(\"Primer conjunto: \");\n        Console.Write(string.Join(\", \", conjunto1));\n        Console.WriteLine();\n\n        Console.Write(\"Segundo conjunto: \");\n        Console.Write(string.Join(\", \", conjunto2));\n        Console.WriteLine();\n\n\n        // Unión\n        /*\n         * La operación Union devuelve una colección con \n         * todos los elementos únicos  de las dos colecciones\n         * especificacdas\n         */\n        Console.WriteLine(\"---Union---\");\n        var union = from item in conjunto1.Union(conjunto2)\n                    select item;\n        Console.Write(\"Resultado de la operación de conjuntos Union: \");\n        Console.Write(string.Join(\", \", union));\n        Console.WriteLine();\n\n        // Intersección\n        /*\n         * La operación Intersección devuelve una\n         * colección con elementos que se encuentran\n         * en ambas colecciones\n         */\n        Console.WriteLine(\"---Intersección---\");\n        var intersection = from item in conjunto1.Intersect(conjunto2)\n                           select item;\n        Console.Write(\"Resultado de la operación de conjuntos Intersección: \");\n        Console.Write(string.Join(\", \", intersection));\n        Console.WriteLine();\n\n        // Diferencia\n        /*\n         * La operación Diferencia devuelve una colección\n         * con elementos de la primera colección que no se\n         * encuentran en la segunda\n         */\n        Console.WriteLine(\"---Diferencia---\");\n        var difference = from item in conjunto1.Except(conjunto2)\n                         select item;\n        Console.Write(\"Resultado de la operación de conjuntos Diferencia: \");\n        Console.Write(string.Join(\", \", difference));\n        Console.WriteLine();\n\n        // Diferencia Simétrica\n        /*\n         * La opercacion de Diferencia Simétrica \n         * modifica el primer conjunto para que \n         * contenga elementos que existen dentro de sí\n         * o dentro del segundo conjunto, pero no en ambos\n         */\n        Console.WriteLine(\"---Diferencia Simétrica---\");\n        /*\n         * El método SymmetricExceptWith existe para la \n         * estructura HashSet\n         */\n        var hash1 = new HashSet<int>(conjunto1);\n        var hash2 = new HashSet<int>(conjunto2);\n        \n        hash1.SymmetricExceptWith(hash2);\n\n        Console.Write(\"Resultado de la operación de conjuntos Diferencia Simétrica: \");\n        Console.Write(string.Join(\", \", hash1));\n        Console.WriteLine();\n        #endregion\n\n    }\n}"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/c#/isaacus98.cs",
    "content": "﻿/*\n * EJERCICIO:\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n * operaciones (debes utilizar una estructura que las soporte):\n * - Añade un elemento al final.\n * - Añade un elemento al principio.\n * - Añade varios elementos en bloque al final.\n * - Añade varios elementos en bloque en una posición concreta.\n * - Elimina un elemento en una posición concreta.\n * - Actualiza el valor de un elemento en una posición concreta.\n * - Comprueba si un elemento está en un conjunto.\n * - Elimina todo el contenido del conjunto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Unión.\n * - Intersección.\n * - Diferencia.\n * - Diferencia simétrica.\n */\n\nnamespace Roadmap\n{\n    internal class Reto18\n    {\n        static void Main(string[] args)\n        {\n            List<int> numbers = new List<int>() { 1, 2, 3, 4 };\n            \n            // Elemento al final de la lista\n            numbers.Add(5);\n            Console.WriteLine(String.Join(\", \", numbers));\n            \n            Console.WriteLine();\n\n            // Elemento al principio\n            numbers.Insert(0, 1);\n            Console.WriteLine(String.Join(\", \", numbers));\n\n            Console.WriteLine();\n\n            // Varios elementos al final\n            int[] numbers2 = [6, 7, 8, 9, 10];\n            numbers.AddRange(numbers2);\n            Console.WriteLine(String.Join(\", \", numbers));\n\n            Console.WriteLine();\n\n            // Varios elementos en una posicion concreta\n            int[] numbers3 = [15, 16, 17, 18];\n            numbers.InsertRange(4, numbers3);\n            Console.WriteLine(String.Join(\", \", numbers));\n\n            Console.WriteLine();\n            \n            // Eliminar elemento de una posición en concreto\n            numbers.RemoveAt(3);\n            Console.WriteLine(String.Join(\", \", numbers));\n\n            Console.WriteLine();\n            \n            // Actualizar valor en una posición concreta\n            numbers[4] = 20;\n            Console.WriteLine(String.Join(\", \", numbers));\n\n            Console.WriteLine();\n\n            //Comprobar que elemento existe\n            Console.WriteLine(numbers.Contains(5));\n\n            Console.WriteLine();\n\n            // Eliminar todos los valores de la lista\n            numbers.Clear();\n\n            // Reto extra\n            HashSet<int> hashset1 = new HashSet<int>() { 1, 2, 3, 4 };\n            HashSet<int> hashset2 = new HashSet<int>() { 1, 5, 3, 6, 8 };\n\n            //Unión\n            var union = hashset1.Union(hashset2);\n            Console.WriteLine(string.Join(\",\", union));\n\n            Console.WriteLine();\n\n            // Intersección\n            var interseccion = hashset1.Intersect(hashset2);\n            Console.WriteLine(string.Join(\",\", interseccion));\n\n            Console.WriteLine();\n\n            // Diferencia\n            var diferencia = hashset1.Except(hashset2);\n            Console.WriteLine(string.Join(\",\", diferencia));\n            diferencia = hashset2.Except(hashset1);\n            Console.WriteLine(string.Join(\",\", diferencia));\n\n            Console.WriteLine();\n\n            // Diferencia simetrica\n            hashset1.SymmetricExceptWith(hashset2);\n            Console.WriteLine(string.Join(\",\", hashset1));\n\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/c#/jamerrq.cs",
    "content": "﻿/*\r\n * EJERCICIO:\r\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\r\n * operaciones (debes utilizar una estructura que las soporte):\r\n * - Añade un elemento al final.\r\n * - Añade un elemento al principio.\r\n * - Añade varios elementos en bloque al final.\r\n * - Añade varios elementos en bloque en una posición concreta.\r\n * - Elimina un elemento en una posición concreta.\r\n * - Actualiza el valor de un elemento en una posición concreta.\r\n * - Comprueba si un elemento está en un conjunto.\r\n * - Elimina todo el contenido del conjunto.\r\n *\r\n * DIFICULTAD EXTRA (opcional):\r\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\r\n * - Unión.\r\n * - Intersección.\r\n * - Diferencia.\r\n * - Diferencia simétrica.\r\n */\r\n\r\nusing System;\r\n\r\nnamespace Roadmap18\r\n{\r\n    class Sets\r\n    {\r\n        static void Main(string[] args)\r\n        {\r\n            // Creamos un conjunto de datos\r\n            int[] set = [];\r\n\r\n            // Añadimos un elemento al final\r\n            Array.Resize(ref set, set.Length + 1);\r\n            set[^1] = 1;\r\n\r\n            // Añadimos un elemento al principio\r\n            Array.Resize(ref set, set.Length + 1);\r\n            Array.Copy(set, 0, set, 1, set.Length - 1);\r\n            set[0] = 2;\r\n\r\n            // Añadimos varios elementos al final\r\n            int[] newElements = [3, 4, 5];\r\n            Array.Resize(ref set, set.Length + newElements.Length);\r\n            Array.Copy(newElements, 0, set, set.Length - newElements.Length, newElements.Length);\r\n\r\n            // Añadimos varios elementos en una posición concreta\r\n            int[] newElements2 = [6, 7, 8];\r\n            int position = 2;\r\n            Array.Resize(ref set, set.Length + newElements2.Length);\r\n            Array.Copy(set, position, set, position + newElements2.Length, set.Length - position - newElements2.Length);\r\n            Array.Copy(newElements2, 0, set, position, newElements2.Length);\r\n\r\n            // Eliminamos un elemento en una posición concreta\r\n            position = 3;\r\n            Array.Copy(set, position + 1, set, position, set.Length - position - 1);\r\n            Array.Resize(ref set, set.Length - 1);\r\n\r\n            // Actualizamos el valor de un elemento en una posición concreta\r\n            position = 2;\r\n            set[position] = 9;\r\n\r\n            // Comprobamos si un elemento está en un conjunto\r\n            int element = 5;\r\n            bool contains = Array.Exists(set, e => e == element);\r\n            Console.WriteLine(\"El conjunto contiene el elemento \" + element + \": \" + contains);\r\n\r\n            // Eliminamos todo el contenido del conjunto\r\n            Array.Resize(ref set, 0);\r\n\r\n            // Mostramos el contenido del conjunto\r\n            Console.WriteLine(\"Contenido del conjunto:\");\r\n            foreach (int e in set)\r\n            {\r\n                Console.WriteLine(e);\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/c#/kenysdev.cs",
    "content": "/*\n╔══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado               ║\n║ GitHub: https://github.com/Kenysdev  ║\n║ 2024 -  C#                           ║\n╚══════════════════════════════════════╝\n------------------------------------------\n* CONJUNTOS\n------------------------------------------\nSon una colección desordenada de elementos únicos.\n*/\nvar mySet = new HashSet<int> { 1, 2, 3, 0 };\n\n/*\n* EJERCICIO #1:\n* Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n* operaciones (debes utilizar una estructura que las soporte):\n\nNOTA: - Algunas operaciones del ejercicio no pueden realizarse utilizando 'HashSet'.\n*/\n\nvar myList = new List<string> { \"a\", \"b\", \"c\" };\n\n// Añade un elemento al final.\nmyList.Add(\"d\");\n\n// Añadir un elemento al principio\nmyList.Insert(0, \"-\");\n\n// Añadir varios elementos en bloque al final\nmyList.AddRange(new string[] { \"e\", \"f\" });\n\n// Añadir varios elementos en bloque en una posición concreta\nmyList.InsertRange(4, new string[] { \"-\", \">\" });\n\n// Eliminar un elemento en una posición concreta\nmyList.RemoveAt(5);\n\n// Actualizar el valor de un elemento en una posición concreta\nmyList[2] = \"-b\";\n\n// Mostrar la lista\nConsole.WriteLine(\"Elementos de la lista:\");\nConsole.WriteLine(string.Join(\", \", myList));\n\n// Comprueba si un elemento está en un conjunto\nConsole.WriteLine($\"4 en conjunto: {mySet.Contains(4)}\");\n\nConsole.WriteLine($\"'c' en lista: {myList.Contains(\"c\")}\");\n\n// Elimina todo el contenido del conjunto y la lista.\nmySet.Clear();\nmyList.Clear();\n\n/*\n* EJERCICIO #2:\n* Muestra ejemplos de las siguientes operaciones con conjuntos:\n* - Unión.\n* - Intersección.\n* - Diferencia.\n* - Diferencia simétrica.\n*/\n\nvar set1 = new HashSet<int>() { 1, 2, 3, 4 };\nvar set2 = new HashSet<int>() { 3, 4, 5, 6 };\n\nConsole.WriteLine(\n    $\"\\n* set_1: {{{string.Join(\", \", set1)}}} - set_2: {{{string.Join(\", \", set2)}}}\");\n\n// Unión\n// Elementos que están en al menos uno de los conjuntos.\nvar union = new HashSet<int>(set1);\nunion.UnionWith(set2);\nConsole.WriteLine($\"\\n- Union: {{{string.Join(\", \", union)}}}\");\n\n// Intersección\n// Elementos que están en ambos conjuntos.\nvar intersection = new HashSet<int>(set1);\nintersection.IntersectWith(set2);\nConsole.WriteLine($\"\\n- Intersection: {{{string.Join(\", \", intersection)}}}\");\n\n// Diferencia\n// Elementos que están en set_1 pero no en set_2\nvar difference = new HashSet<int>(set1);\ndifference.ExceptWith(set2);\nConsole.WriteLine($\"\\n- Difference: {{{string.Join(\", \", difference)}}}\");\n\n// Diferencia simétrica\n// Elementos que están en uno de los conjuntos pero no en ambos.\nvar symmetricDiff = new HashSet<int>(set1);\nsymmetricDiff.SymmetricExceptWith(set2);\nConsole.WriteLine($\"\\n- Symmetric Difference: {{{string.Join(\", \", symmetricDiff)}}}\");\n\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/c++/hectorio23.cpp",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n#include <iostream>\n#include <algorithm>\n#include <iterator>\n#include <set>\n#include <vector>\n#include <map>\n\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n * operaciones (debes utilizar una estructura que las soporte):\n * - Añade un elemento al final.\n * - Añade un elemento al principio.\n * - Añade varios elementos en bloque al final.\n * - Añade varios elementos en bloque en una posición concreta.\n * - Elimina un elemento en una posición concreta.\n * - Actualiza el valor de un elemento en una posición concreta.\n * - Comprueba si un elemento está en un conjunto.\n * - Elimina todo el contenido del conjunto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Unión.\n * - Intersección.\n * - Diferencia.\n * - Diferencia simétrica.\n*/\n\n// Funcion lambda que permite imprimir los elementos\n// que confirman un SET\nauto print = [](std::set<int> &conjunto) -> void {\n    int counter = 0;\n    for (auto &elemento : conjunto) {\n\n        if (counter != conjunto.size() - 1) std::cout << elemento << \", \";\n        else std::cout << elemento << \".\";\n        counter++;\n    }\n    std::cout << \"\\n\";\n};\n\n// Clase custom que permite operar los set como en Python, es decir, \n// nos habilita para realizar ciertas operaciones usando operadores \n// especiales en lugar de usar métodos\nclass SetCustom {\npublic:\n    std::set<int> values;\n\n    /********************************\n    ********* CONSTRUCTORES *********\n    *********************************/\n    SetCustom(){};\n    SetCustom(int value) { values.insert(value); };\n    SetCustom(std::set<int> new_set): values(new_set) {  };\n    SetCustom(std::vector<int> items) {\n        for (auto &element : items)\n        values.insert(element);\n    };\n\n    /********************************\n    ************* MÉTODOS ***********\n    *********************************/\n\n    void insert(int value) { values.insert(value); };\n    void insert(std::vector<int> items) {\n        for (auto &element : items)\n        values.insert(element);\n    };\n\n    // Calcular la diferencia del subset\n    SetCustom operator-(SetCustom &other) {\n        std::vector<int> result;\n        int index, counter = 0;\n        SetCustom tmp;\n\n        // Se encarga de comparar cada elemento de un Set con todos los elementos\n        // del segundo set con el objetivo de verificar que no se repita en el segundo, \n        // cuando un elemento no se repite, lo guarda en un vector.\n        for (auto &element : other.values) {\n            counter = 0;\n            for (auto &item : this->values) {\n\n                if (element == item) break;\n                counter++;\n\n                if (counter == values.size() - 1) {\n                    result.push_back(element);\n                    index++;\n                }\n            }\n        }\n\n        if (result.size() != 0) tmp.insert(result);\n\n        // Retorna un objeto de la clase SetCustom con los valores que no se interceptan\n        // del primer Set de datos del operando \n        return tmp;\n    }\n\n    // Realiza la union de los conjuntos y los retorna empaquetados\n    // en el objeto SetCustom\n    SetCustom operator+(SetCustom &other) {\n        std::set<int> tmp_set { this->values };\n        tmp_set.merge(other.values);\n\n        return SetCustom(tmp_set);\n    }\n\n    // Realiza la interseccion de los conjuntos y los retorna empaquetados\n    // en el objeto SetCustom\n    SetCustom operator&(SetCustom &other) {\n        std::set<int> intersection;\n        std::set_intersection(other.values.begin(), other.values.end(), this->values.begin(), this->values.end(), \n        std::inserter(intersection, intersection.begin()));\n\n        return SetCustom(intersection);\n    }\n\n    // Realiza la diferencia simétrica de los conjuntos y los retorna empaquetados\n    // en el objeto SetCustom\n    SetCustom operator^(SetCustom &other) {\n        std::set<int> symmetric_difference;\n        std::set_symmetric_difference(this->values.begin(), this->values.end(), other.values.begin(), other.values.end(), std::inserter(symmetric_difference, symmetric_difference.begin()));\n\n        return SetCustom(symmetric_difference);\n    }\n};\n\nint main() {\n    std::map<int, int> myMap;\n\n    // Añade un elemento al final\n    myMap[1] = 10;\n\n    // Añade un elemento al principio\n    myMap[0] = 5;\n\n    // Añade varios elementos en bloque al final\n    std::map<int, int> additionalMap = {{2, 20}, {3, 30}};\n    myMap.insert(additionalMap.begin(), additionalMap.end());\n\n    // Añade varios elementos en bloque en una posición concreta\n    std::map<int, int> blockInsertMap = {{4, 40}, {5, 50}};\n    myMap.insert({56, 9, });\n\n    // Elimina un elemento en una posición concreta\n    myMap.erase(3);\n\n    // Actualiza el valor de un elemento en una posición concreta\n    myMap[2] = 25;\n\n    // Comprueba si un elemento está en un conjunto\n    if (myMap.find(4) != myMap.end()) {\n        std::cout << \"El elemento 4 está en el conjunto.\" << std::endl;\n    } else {\n        std::cout << \"El elemento 4 no está en el conjunto.\" << std::endl;\n    }\n\n    // Elimina todo el contenido del conjunto\n    myMap.clear();\n    \n    // Se crean los objetos con los que se va a estar trabajando a lo largo del ejercicio\n    // Setcustom es una clase custom que nos permite operar con conjutnos de una manera más flexible\n    SetCustom value1 = std::vector<int>{1, 2, 4, 5, 6, 7};\n    SetCustom value2 = std::vector<int>{1, 2, 46, 5, 6, 7};\n\n    // Se imrpimen el SET1 antes de ser modificado\n    std::cout << \"Set1 antes de ser modificado: \\n\";\n    print(value1.values);\n\n    // insertar un dato al final del SET1\n    std::cout << \"Set1 despues de agregar un elemento al final: \\n\";\n    value1.insert(239);\n    print(value1.values);\n\n    // Insertar varios elementos al final del SET2\n    std::cout << \"Set1 despues de agregar un conjunto de elementos al final: \\n\";\n    value1.insert({ 500, 674, 786, 8493 });\n    print(value1.values);\n\n    std::cout << \"\\n****** CONJUNTOS A {1, 2, 4, 5, 6, 7} y B {1, 2, 46, 5, 6, 7} *******\\n\\n\";\n\n    std::cout << \"* Diferencia de conjuntos A y B: -> \";\n    SetCustom value3 = value1 - value2;\n    print(value3.values);\n\n    std::cout << \"* Union de conjuntos A y B: -> \";\n    value3 = value1 + value2;\n    print(value3.values);\n\n    std::cout << \"* Interseccion de conjuntos A y B: -> \";\n    value3 = value1 & value2;\n    print(value3.values);\n\n    std::cout << \"* Diferencia simetrica de conjuntos A y B: -> \";\n    value3 = value1 ^ value2;\n    print(value3.values);\n\n    return 0;\n}"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/dart/teren91.dart",
    "content": "/*\n * EJERCICIO:\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n * operaciones (debes utilizar una estructura que las soporte):\n * - Añade un elemento al final.\n * - Añade un elemento al principio.\n * - Añade varios elementos en bloque al final.\n * - Añade varios elementos en bloque en una posición concreta.\n * - Elimina un elemento en una posición concreta.\n * - Actualiza el valor de un elemento en una posición concreta.\n * - Comprueba si un elemento está en un conjunto.\n * - Elimina todo el contenido del conjunto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Unión.\n * - Intersección.\n * - Diferencia.\n * - Diferencia simétrica.\n */\nimport 'dart:collection';\n\nvoid main()\n{\n  final List<String> animales =[];\n\n  //Añadir elemento al final\n  animales.add('Perro');\n  animales.add('Gato');\n  animales.add('Tucán');\n\n  print('Animales inicial: $animales');\n\n  \n  //Añadir elemento al principio\n  animales.insert(0, 'Colibrí');\n\n  print('Animales insert inicio: $animales');\n\n  //Varios al final\n  animales.addAll(['Foca', 'Delfín']);\n  print('Animales varios al final: $animales');\n\n\n  //Varios en posición concreta\n  animales.insertAll(2, ['Tortuga', 'Lagarto']);\n  print('Animales varios en posición concreta: $animales');\n\n  //Eliminar en posición concreta\n  animales.removeAt(1);\n  print('Animales eliminar en pos concreta: $animales');\n\n  //Actualizar valor en posición concreta\n  animales[3] = 'Serpiente';\n  print('Animales actualizar valor concreto: $animales');\n\n  //Comprobar si un elemento existe en la colección\n  \n  print('Hay gato en la colección: ${animales.contains('Gato')}');\n  print('Hay Tucán en la colección: ${animales.contains('Tucán')}');\n\n  //Vaciar conjunto\n  animales.removeRange(0, animales.length);\n  print('Vaciar colección: $animales');\n\n  //Unión\n  final Set<String> mamiferos = Set<String>();\n  final Set<String> aves = Set<String>();\n  Set<String> mamiferos_aves = Set<String>();\n  mamiferos.add('Suricato');\n  mamiferos.add('Jirafa');\n  mamiferos.add('Pantera');\n\n  aves.add('Gorrión');\n  aves.add('Cuervo');\n  aves.add('Águila');\n\n  //Union\n  mamiferos_aves = mamiferos_aves.union(mamiferos);\n  mamiferos_aves = mamiferos_aves.union(aves);\n  print('Mamíferos: $mamiferos');\n  print('Aves: $aves');\n  print('Mamíferos y aves: $mamiferos_aves');\n\n  //Intersección - Eliminamos un elemento para que sea distinto al original\n  mamiferos_aves.remove('Jirafa');\n  mamiferos_aves = mamiferos_aves.intersection(mamiferos);\n\n  print('Mamíferos y aves intersección mamíferos: $mamiferos_aves');\n\n  //Diferencia\n  mamiferos_aves.add('Rinoceronte');\n  print('Mamíferos y aves añadido elemento: $mamiferos_aves');\n  mamiferos_aves = mamiferos_aves.difference(mamiferos);\n  print('Mamíferos y aves diferencia mamíferos: $mamiferos_aves');\n\n  //Diferencia simétrica\n  mamiferos_aves.add('Jirafa');\n  print('Mamíferos y aves añadido elemento: $mamiferos_aves');\n  mamiferos_aves = mamiferos_aves.difference(mamiferos).union(mamiferos.difference(mamiferos_aves));\n  print('Mamíferos y aves diferencia simétrica mamíferos: $mamiferos_aves');\n}"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/ejercicio.md",
    "content": "# #18 CONJUNTOS\n> #### Dificultad: Fácil | Publicación: 29/04/24 | Corrección: 06/05/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n * operaciones (debes utilizar una estructura que las soporte):\n * - Añade un elemento al final.\n * - Añade un elemento al principio.\n * - Añade varios elementos en bloque al final.\n * - Añade varios elementos en bloque en una posición concreta.\n * - Elimina un elemento en una posición concreta.\n * - Actualiza el valor de un elemento en una posición concreta.\n * - Comprueba si un elemento está en un conjunto.\n * - Elimina todo el contenido del conjunto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Unión.\n * - Intersección.\n * - Diferencia.\n * - Diferencia simétrica.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/go/DaFi02.go",
    "content": "package main\n\nimport \"fmt\"\n\ntype data struct {\n\telements []interface{}\n}\n\n/* Funciones para que se use cada punto */\n\n/*Imprimir valors*/\n\nfunc printData(d *data) {\n\tfor i, element := range d.elements {\n\t\tif i != len(d.elements)-1 {\n\t\t\tfmt.Print(element, \", \")\n\t\t} else {\n\t\t\tfmt.Print(element)\n\n\t\t}\n\n\t}\n\tfmt.Println()\n}\n\n/* añadir elemento al final */\nfunc addData(d *data, element interface{}) {\n\td.elements = append(d.elements, element)\n}\n\n/*Añadir elementos al inicio*/\nfunc addFirstData(d *data, element interface{}) {\n\td.elements = append([]interface{}{element}, d.elements...)\n}\n\n/*Añadir varios elementos en bloque*/\nfunc addBlockDataFinal(d *data, elements ...interface{}) {\n\td.elements = append(d.elements, elements...)\n}\n\nfunc addBlockDataPosition(d *data, position int, elements ...interface{}) {\n\td.elements = append(d.elements[:position], append(elements, d.elements[position:]...)...)\n}\n\nfunc deleteDataPosition(d *data, position int) {\n\td.elements = append(d.elements[:position], d.elements[position+1:]...)\n}\n\nfunc updateDataPosition(d *data, position int, element interface{}) {\n\td.elements[position] = element\n}\n\nfunc verificationElementInData(d *data, element interface{}) string {\n\tfor _, el := range d.elements {\n\t\tif el == element {\n\t\t\treturn \"'\" + element.(string) + \"'\" + \" is here!\"\n\t\t}\n\t}\n\treturn \"'\" + element.(string) + \"'\" + \" is not here! :c\"\n}\n\nfunc deleteAllData(d *data) {\n\td.elements = []interface{}{}\n}\n\nfunc unionData(d1 *data, d2 *data) *data {\n\tdUnion := data{}\n\tdUnion.elements = append(d1.elements, d2.elements...)\n\treturn &dUnion\n}\n\nfunc intersectionData(d1 *data, d2 *data) *data {\n\tdIntersection := data{}\n\tfor _, el1 := range d1.elements {\n\t\tfor _, el2 := range d2.elements {\n\t\t\tif el1 == el2 {\n\t\t\t\tdIntersection.elements = append(dIntersection.elements, el1)\n\t\t\t}\n\t\t}\n\t}\n\treturn &dIntersection\n}\n\nfunc differenceData(d1 *data, d2 *data) *data {\n\tdDiference := data{}\n\tfor _, el1 := range d1.elements {\n\t\tisIn := false\n\t\tfor _, el2 := range d2.elements {\n\t\t\tif el1 == el2 {\n\t\t\t\tisIn = true\n\t\t\t}\n\t\t}\n\t\tif !isIn {\n\t\t\tdDiference.elements = append(dDiference.elements, el1)\n\t\t}\n\t}\n\treturn &dDiference\n}\n\nfunc symmetricaldDifferenceData(d1 *data, d2 *data) *data {\n\tdDiference := differenceData(d1, d2)\n\td2Diference := differenceData(d2, d1)\n\tdSymmetricalDifference := unionData(dDiference, d2Diference)\n\treturn dSymmetricalDifference\n}\n\n/* funcion main */\n\nfunc main() {\n\tinitialData := data{\n\t\telements: []interface{}{1, \"MoureDev\", 3, \"hello\", \"DaFi\"},\n\t}\n\n\tfmt.Println(\"Initial Data:\")\n\tfmt.Println(initialData.elements)\n\n\tfmt.Println(\"-------------------------\")\n\tfmt.Println(\"Adding elements at the end:\")\n\taddData(&initialData, \"Voy al Final\")\n\tprintData(&initialData)\n\n\tfmt.Println(\"-------------------------\")\n\tfmt.Println(\"Adding elements at the beginning:\")\n\taddFirstData(&initialData, \"Voy al principio\")\n\tprintData(&initialData)\n\n\tfmt.Println(\"-------------------------\")\n\tfmt.Println(\"Adding multiple elements at the end:\")\n\taddBlockDataFinal(&initialData, \"Voy al final 2.0\", 987654, \"Voy al final 3.0\")\n\tprintData(&initialData)\n\n\tfmt.Println(\"-------------------------\")\n\tfmt.Println(\"Adding multiple elements at a specific position:\")\n\taddBlockDataPosition(&initialData, 2, \"Voy en la Posición 2\", \"Voy seguido al de la posición 2\")\n\tprintData(&initialData)\n\n\tfmt.Println(\"-------------------------\")\n\tfmt.Println(\"Deleting element at a specific position:\")\n\tdeleteDataPosition(&initialData, 2)\n\tprintData(&initialData)\n\n\tfmt.Println(\"-------------------------\")\n\tfmt.Println(\"Updating element at a specific position:\")\n\tupdateDataPosition(&initialData, 4, \"Elemento Actualizado\")\n\tprintData(&initialData)\n\n\tfmt.Println(\"-------------------------\")\n\tfmt.Println(\"Verifying if an element is in the data:\")\n\tfmt.Println(verificationElementInData(&initialData, \"MoureDev\"))\n\tfmt.Println(verificationElementInData(&initialData, \"Elemento finisimo\"))\n\n\tcopyData := initialData\n\n\tfmt.Println(\"-------------------------\")\n\tfmt.Println(\"Deleting all elements:\")\n\tdeleteAllData(&initialData)\n\tprintData(&initialData)\n\tfmt.Println(\"NO HAVE DATA! XD\")\n\n\t/* Dificultad Extra */\n\n\tseconData := data{\n\t\telements: []interface{}{1, \"MoureDev\", 3, \"hello\", \"DaFi\"},\n\t}\n\tfmt.Println(\"-------------------------\")\n\tfmt.Println(\"Initial Data:\")\n\tprintData(&copyData)\n\tfmt.Println(\"Second Data:\")\n\tprintData(&seconData)\n\n\tfmt.Println(\"-------------------------\")\n\tfmt.Println(\"Union of the two data:\")\n\tdUnion := unionData(&copyData, &seconData)\n\tprintData(dUnion)\n\n\tfmt.Println(\"-------------------------\")\n\tfmt.Println(\"Intersection of the two data:\")\n\tdIntersection := intersectionData(&copyData, &seconData)\n\tprintData(dIntersection)\n\n\tfmt.Println(\"-------------------------\")\n\tfmt.Println(\"Difference of the two data, First Case:\")\n\tdDiference := differenceData(&copyData, &seconData)\n\tprintData(dDiference)\n\tfmt.Println(\"Difference of the two data, Second Case:\")\n\td2Diference := differenceData(&seconData, &copyData)\n\tprintData(d2Diference)\n\n\tfmt.Println(\"-------------------------\")\n\tfmt.Println(\"Symmetrical Difference of the two data:\")\n\tdSymmetricalDifference := symmetricaldDifferenceData(&copyData, &seconData)\n\tprintData(dSymmetricalDifference)\n\n}\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/go/MiguelP-Dev.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\n// Un conjunto es una colección de elementos no repetidos.\n// En Go, los conjuntos se pueden implementar utilizando mapas.\n// La clave del mapa es el elemento y el valor es un booleano que indica si el elemento está presente en el conjunto.\n\n// Set Definimos la estructura de un conjunto.\ntype Set struct {\n\telements map[any]bool\n}\n\n// Creamos un nuevo conjunto.\nfunc NewSet() *Set {\n\treturn &Set{elements: make(map[any]bool)}\n}\n\n// Add Añade un elemento al conjunto.\nfunc (s *Set) Add(element any) {\n\ts.elements[element] = true\n}\n\n// Remove Elimina un elemento del conjunto.\nfunc (s *Set) Remove(element any) {\n\tdelete(s.elements, element)\n}\n\n// Contains Comprueba si un elemento está en el conjunto.\nfunc (s *Set) Contains(element any) bool {\n\t// Extra: Comprobamos si el elemento es de tipo string y lo convertimos a minúsculas para comprobar si existe en el conjunto.\n\tif _, ok := element.(string); ok {\n\t\tstrings.ToLower(element.(string))\n\t\treturn s.elements[element]\n\t}\n\n\treturn s.elements[element]\n}\n\n// Size Devuelve el tamaño del conjunto.\nfunc (s *Set) Size() int {\n\treturn len(s.elements)\n}\n\n// Task1: Union de conjuntos.\n// La unión de dos conjuntos es la operación que resulta en un nuevo conjunto que\n// contiene todos los elementos de los conjuntos originales.\nfunc Union(set1, set2 *Set) *Set {\n\tunionSet := NewSet()\n\n\tfor element := range set1.elements {\n\t\tunionSet.Add(element)\n\t}\n\n\tfor element := range set2.elements {\n\t\tunionSet.Add(element)\n\t}\n\n\treturn unionSet\n}\n\n// Task2 : Intersección de conjuntos.\n// La intersección de dos conjuntos es la operación que resulta en un nuevo conjunto que contiene solo\n// los elementos que están presentes en ambos conjuntos originales.\nfunc intersection(set1, set2 *Set) *Set {\n\tintersectionSet := NewSet()\n\n\tfor element := range set1.elements {\n\t\tif set2.Contains(element) {\n\t\t\tintersectionSet.Add(element)\n\t\t}\n\t}\n\n\treturn intersectionSet\n}\n\n// Task3 : Diferencia de conjuntos.\n// La diferencia de dos conjuntos es la operación que resulta en un nuevo conjunto que contiene solo\n// los elementos que están presentes en el primer conjunto original pero no en el segundo.\nfunc difference(set1, set2 *Set) *Set {\n\tdifferenceSet := NewSet()\n\n\tfor element := range set1.elements {\n\t\tif !set2.Contains(element) {\n\t\t\tdifferenceSet.Add(element)\n\t\t}\n\t}\n\treturn differenceSet\n}\n\n// Task4 : Diferencia simétrica de conjuntos.\n// La diferencia simétrica de dos conjuntos es la operación que resulta en un nuevo conjunto que contiene solo\n// los elementos que están presentes en uno de los conjuntos originales, pero no en ambos.\nfunc symmetricDifference(set1, set2 *Set) *Set {\n\tsymmetricDifferenceSet := NewSet()\n\n\tfor element := range set1.elements {\n\t\tif !set2.Contains(element) {\n\t\t\tsymmetricDifferenceSet.Add(element)\n\t\t}\n\t}\n\n\tfor element := range set2.elements {\n\t\tif !set1.Contains(element) {\n\t\t\tsymmetricDifferenceSet.Add(element)\n\t\t}\n\t}\n\n\treturn symmetricDifferenceSet\n}\nfunc main() {\n\t// Creamos un nuevo conjunto.\n\tset := NewSet()\n\n\t// Añadimos elementos al conjunto.\n\tset.Add(1)\n\tset.Add(\"hello\")\n\tset.Add(3)\n\n\t// Comprobamos si un elemento está en el conjunto.\n\tfmt.Println(set.Contains(1))       // true\n\tfmt.Println(set.Contains(2))       // false\n\tfmt.Println(set.Contains(3))       // true\n\tfmt.Println(set.Contains(\"hello\")) // true\n\n\t// Eliminamos un elemento del conjunto.\n\tset.Remove(1)\n\n\t// Comprobamos si el elemento ha sido eliminado.\n\tfmt.Println(set.Contains(1)) // false\n\n\t// Mostramos el tamaño del conjunto.\n\tfmt.Println(set.Size()) // 2\n\n\t// Nota: Los conjuntos no permiten elementos duplicados. En Golang trabajamos con mapas para los conjuntos y las claves no pueden ser duplicadas.\n\t// Por lo tanto, si intentamos añadir un elemento que ya existe en el conjunto, no se añadirá. También al ser un mapa, los elementos no tienen un orden específico.\n\t// Por lo tanto, no podemos garantizar el orden de los elementos en el conjunto. Solo podemos usar trucos para insertar elemtos al principio o al final.\n\t// Para mantener el orden de los elementos, podemos usar una lista enlazada o una lista doblemente enlazada.\n\n\t// Añade un elemento al principio.\n\tset.Add(0)\n\tfmt.Println(set.Size()) // 4\n\tfmt.Println(set.elements)\n\n\t// Añade un elemento al final.\n\tset.Add(4)\n\tfmt.Println(set.Size()) // 3\n\tfmt.Println(set.elements)\n\n\t// Añade varios elementos en bloque al final.\n\tset.Add(5)\n\tset.Add(6)\n\tset.Add(7)\n\tfmt.Println(set.Size()) // 7\n\tfmt.Println(set.elements)\n\n\t// Añade varios elementos en bloque en una posición concreta.\n\t// Actualiza el valor de un elemento en una posición concreta.\n\tset.Add(8)\n\tset.Add(9)\n\tset.Add(10)\n\tfmt.Println(set.Size()) // 10\n\tfmt.Println(set.elements)\n\n\t// Actualiza el valor de un elemento en una posición concreta.\n\tset.Add(10)\n\tfmt.Println(set.Size()) // 10\n\tfmt.Println(set.elements)\n\n\t// Elimina todo el contenido del conjunto.\n\tset = NewSet()\n\tfmt.Println(set.Size()) // 0\n\tfmt.Println(set.elements)\n\n\t// Extra: Ejemplos de operaciones de conjuntos.\n\t// Unión de conjuntos.\n\t// Creamos dos conjuntos.\n\tset1 := NewSet()\n\tset2 := NewSet()\n\n\t// Añadimos elementos a los conjuntos.\n\tset1.Add(1)\n\tset1.Add(2)\n\tset1.Add(3)\n\n\tset2.Add(4)\n\tset2.Add(5)\n\tset2.Add(6)\n\n\t// Unimos los conjuntos.\n\tunionSet := Union(set1, set2)\n\tfmt.Println(\"UnionSets:\")\n\tfmt.Println(unionSet.Size()) // 6\n\tfmt.Println(unionSet.elements)\n\n\t// Intersección de conjuntos.\n\t// Creamos dos conjuntos.\n\tset3 := NewSet()\n\tset4 := NewSet()\n\n\t// Añadimos elementos a los conjuntos.\n\tset3.Add(1)\n\tset3.Add(2)\n\tset3.Add(3)\n\n\tset4.Add(2)\n\tset4.Add(3)\n\tset4.Add(4)\n\n\t// Obtenemos la intersección de los conjuntos.\n\tintersectionSet := intersection(set3, set4)\n\tfmt.Println(\"IntersectionSet:\")\n\tfmt.Println(\"Size: \", intersectionSet.Size()) // 2\n\tfmt.Println(\"Elements: \", intersectionSet.elements)\n\n\t// Diferencia de conjuntos.\n\t// Creamos dos conjuntos.\n\tset5 := NewSet()\n\tset6 := NewSet()\n\n\t// Añadimos elementos a los conjuntos.\n\tset5.Add(1)\n\tset5.Add(2)\n\tset5.Add(3)\n\n\tset6.Add(2)\n\tset6.Add(3)\n\tset6.Add(4)\n\n\t// Obtenemos la diferencia de los conjuntos.\n\tdifferenceSet := difference(set5, set6)\n\tfmt.Println(\"DifferenceSet:\")\n\tfmt.Println(\"Size: \", differenceSet.Size()) // 1\n\tfmt.Println(\"Elements: \", differenceSet.elements)\n\n\t// Diferencia simétrica de conjuntos.\n\t// Creamos dos conjuntos.\n\tset7 := NewSet()\n\tset8 := NewSet()\n\n\t// Añadimos elementos a los conjuntos.\n\tset7.Add(1)\n\tset7.Add(2)\n\tset7.Add(3)\n\n\tset8.Add(2)\n\tset8.Add(3)\n\tset8.Add(4)\n\n\t// Obtenemos la diferencia simétrica de los conjuntos.\n\tsymmetricDifferenceSet := symmetricDifference(set7, set8)\n\tfmt.Println(\"SymmetricDifferenceSet:\")\n\tfmt.Println(\"Size: \", symmetricDifferenceSet.Size()) // 2\n\tfmt.Println(\"Elements: \", symmetricDifferenceSet.elements)\n}\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/go/N0HagoNada.go",
    "content": "package main\n\nimport \"fmt\"\n\n// Definimos una estructura de datos slice como nuestro conjunto\ntype mySet []interface{}\n\nfunc main() {\n\t// Creamos un nuevo conjunto vacío\n\tset := mySet{}\n\n\t// Añadimos un elemento al final\n\tset = append(set, 1)\n\tfmt.Println(\"Añadimos 1 al final:\", set)\n\n\t// Añadimos un elemento al principio\n\tset = append(mySet{2}, set...)\n\tfmt.Println(\"Añadimos 2 al principio:\", set)\n\n\t// Añadimos varios elementos en bloque al final\n\tset = append(set, 3, 4, 5)\n\tfmt.Println(\"Añadimos 3, 4, 5 al final:\", set)\n\n\t// Añadimos varios elementos en bloque en una posición concreta\n\tset = append(set[:2], append(mySet{6, 7}, set[2:]...)...)\n\tfmt.Println(\"Añadimos 6, 7 en la posición 2:\", set)\n\n\t// Eliminamos un elemento en una posición concreta\n\tset = append(set[:3], set[4:]...)\n\tfmt.Println(\"Eliminamos el elemento en la posición 3:\", set)\n\n\t// Actualizamos el valor de un elemento en una posición concreta\n\tset[1] = 8\n\tfmt.Println(\"Actualizamos el valor del segundo elemento a 8:\", set)\n\n\t// Comprobamos si un elemento está en un conjunto\n\tfmt.Println(\"¿El elemento 6 está en el conjunto?\", containsElement(set, 6))\n\n\t// Eliminamos todo el contenido del conjunto\n\tset = mySet{}\n\tfmt.Println(\"Conjunto vacío:\", set)\n}\n\n// Función auxiliar para comprobar si un elemento está en el conjunto\nfunc containsElement(set mySet, val interface{}) bool {\n\tfor _, v := range set {\n\t\tif v == val {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/go/hozlucas28.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"slices\"\n\t\"strings\"\n)\n\n/* -------------------------------------------------------------------------- */\n/*                                 SET (CLASS)                                */\n/* -------------------------------------------------------------------------- */\n\ntype Set struct {\n\telements []string\n}\n\nfunc NewSet(initialElements []string) *Set {\n\tvar set Set = Set{}\n\tset.AddElements(initialElements...)\n\n\treturn &set\n}\n\nfunc (set *Set) GetElements() []string {\n\treturn slices.Clone(set.elements)\n}\n\nfunc (set *Set) AddElements(elements ...string) *Set {\n\tset.elements = append(set.elements, elements...)\n\tset.sanitizeElements()\n\n\treturn set\n}\n\nfunc (set *Set) sanitizeElements() *Set {\n\tvar sanitizedElements []string\n\n\tfor i := 0; i < len(set.elements); i++ {\n\t\tvar flag bool = true\n\t\tvar anchorElement string = set.elements[i]\n\n\t\tfor j := i + 1; j < len(set.elements); j++ {\n\t\t\tvar nextElement string = set.elements[j]\n\t\t\tif strings.EqualFold(anchorElement, nextElement) {\n\t\t\t\tflag = false\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tif flag {\n\t\t\tsanitizedElements = append(sanitizedElements, anchorElement)\n\t\t}\n\t}\n\n\tset.elements = sanitizedElements\n\n\treturn set\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                  FUNCTIONS                                 */\n/* -------------------------------------------------------------------------- */\n\nfunc DifferenceSets(setA *Set, setB *Set) *Set {\n\tvar set *Set = NewSet([]string{})\n\n\tvar setAElements []string = setA.GetElements()\n\tvar setBElements []string = setB.GetElements()\n\n\tfor i := 0; i < len(setAElements); i++ {\n\t\tvar flag bool = true\n\t\tvar aElement string = setAElements[i]\n\n\t\tfor j := 0; j < len(setBElements); j++ {\n\t\t\tvar bElement string = setBElements[j]\n\t\t\tif strings.EqualFold(aElement, bElement) {\n\t\t\t\tflag = false\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tif flag {\n\t\t\tset.AddElements(aElement)\n\t\t}\n\t}\n\n\treturn set\n}\n\nfunc IntersectionSets(setA *Set, setB *Set) *Set {\n\tvar set *Set = NewSet([]string{})\n\n\tvar setAElements []string = setA.GetElements()\n\tvar setBElements []string = setB.GetElements()\n\n\tfor i := 0; i < len(setAElements); i++ {\n\t\tvar flag bool = false\n\t\tvar aElement string = setAElements[i]\n\n\t\tfor j := 0; j < len(setBElements); j++ {\n\t\t\tvar bElement string = setBElements[j]\n\t\t\tif strings.EqualFold(aElement, bElement) {\n\t\t\t\tflag = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tif flag {\n\t\t\tset.AddElements(aElement)\n\t\t}\n\t}\n\n\treturn set\n\n}\n\nfunc JoinSets(setA *Set, setB *Set) *Set {\n\tvar set *Set = NewSet([]string{})\n\n\tvar setAElements []string = setA.GetElements()\n\tvar setBElements []string = setB.GetElements()\n\n\tset.AddElements(setAElements...)\n\tset.AddElements(setBElements...)\n\n\treturn set\n}\n\nfunc SymmetricDifferenceSets(setA *Set, setB *Set) *Set {\n\tvar set *Set = NewSet([]string{})\n\n\tvar leftSide *Set = DifferenceSets(setA, setB)\n\tvar rightSide *Set = DifferenceSets(setB, setA)\n\n\tset.AddElements(leftSide.GetElements()...)\n\tset.AddElements(rightSide.GetElements()...)\n\n\treturn set\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\nfunc main() {\n\t/*\n\t\tData methods...\n\t*/\n\n\tfmt.Println(\"Data methods...\")\n\n\tvar data []string = []string{\n\t\t\"Buenos Aires\",\n\t\t\"Texas\",\n\t\t\"Madrid\",\n\t\t\"Houston\",\n\t\t\"California\",\n\t}\n\n\tfmt.Printf(\"\\ndata = %v\\n\", data)\n\n\tfmt.Println(\"\\nAppend data at the end...\")\n\tfmt.Println(\"\\ndata = append(data, \\\"Berlin\\\")\")\n\n\tdata = append(data, \"Berlin\")\n\tfmt.Printf(\"data = %v\\n\", data)\n\n\tfmt.Println(\"\\nAppend data at the start...\")\n\tfmt.Println(\"\\ndata = slices.Concat([]string{\\\"Chaco\\\"}, data)\")\n\n\tdata = slices.Concat([]string{\"Chaco\"}, data)\n\tfmt.Printf(\"data = %v\\n\", data)\n\n\tfmt.Println(\"\\nAppend several data at the end...\")\n\tfmt.Println(\"\\ndata = append(data, \\\"Paris\\\", \\\"Montana\\\")\")\n\n\tdata = append(data, \"Paris\", \"Montana\")\n\tfmt.Printf(\"data = %v\\n\", data)\n\n\tfmt.Println(\"\\nAppend several data at index 4...\")\n\tfmt.Println(\"\\ndata = slices.Concat(data[:4], []string{\\\"Jujuy\\\", \\\"Formosa\\\"}, data[4:])\")\n\n\tdata = slices.Concat(data[:4], []string{\"Jujuy\", \"Formosa\"}, data[4:])\n\tfmt.Printf(\"data = %v\\n\", data)\n\n\tfmt.Println(\"\\nDelete data at index 3...\")\n\tfmt.Println(\"\\ndata = slices.Delete(data, 3, 3+1)\")\n\n\tdata = slices.Delete(data, 3, 3+1)\n\tfmt.Printf(\"data = %v\\n\", data)\n\n\tfmt.Println(\"\\nUpdate data at index 6...\")\n\tfmt.Println(\"\\ndata[6] = \\\"Miami\\\"\")\n\n\tdata[6] = \"Miami\"\n\tfmt.Printf(\"data = %v\\n\", data)\n\n\tfmt.Println(\"\\nCheck if a data is present...\")\n\tfmt.Printf(\"\\nslices.Contains(data, \\\"Buenos Aires\\\") => %t\\n\", slices.Contains(data, \"Buenos Aires\"))\n\n\tfmt.Printf(\"data = %v\\n\", data)\n\n\tfmt.Println(\"\\nClear data...\")\n\tfmt.Println(\"\\ndata = nil\")\n\n\tdata = nil\n\tfmt.Printf(\"data = %v\\n\", data)\n\n\tfmt.Println(\"\\n# ---------------------------------------------------------------------------------- #\")\n\n\t/*\n\t\tAdditional challenge...\n\t*/\n\n\tfmt.Println(\"\\nAdditional challenge...\")\n\n\tvar firstSet *Set = NewSet([]string{\"Hello\", \"Go (Golang)\", \"World!\"})\n\tvar secondSet *Set = NewSet([]string{\"By\", \"Go (Golang)\"})\n\n\tfmt.Printf(\"\\nfirstSet = %v\", firstSet.GetElements())\n\tfmt.Printf(\"\\nsecondSet = %v\\n\", secondSet.GetElements())\n\n\tvar intersectedSets *Set = IntersectionSets(firstSet, secondSet)\n\tfmt.Printf(\"\\nIntersection (firstSet, and secondSet) => %v\\n\", intersectedSets.GetElements())\n\n\tvar jointSets *Set = JoinSets(firstSet, secondSet)\n\tfmt.Printf(\"\\nJoin (firstSet, and secondSet) => %v\\n\", jointSets.GetElements())\n\n\tvar differencedSets *Set = DifferenceSets(firstSet, secondSet)\n\tfmt.Printf(\"\\nDifferenced (firstSet, and secondSet) => %v\\n\", differencedSets.GetElements())\n\n\tvar symmetricDifferencedSets *Set = SymmetricDifferenceSets(firstSet, secondSet)\n\tfmt.Printf(\"\\nSymmetric difference (firstSet, and secondSet) => %v\", symmetricDifferencedSets.GetElements())\n}\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/go/kodenook.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc main() {\n\tlanguages := []string{\"golang\"}\n\n\tlanguages = append(languages, \"rust\")\n\tlanguages = append([]string{\"typescript\"}, languages...)\n\tlanguages = append(languages, \"python\", \"php\")\n\tlanguages = append(languages[:2], append([]string{\"ruby\", \"java\"}, languages[2:]...)...)\n\tlanguages = append(languages[:5], languages[6:]...)\n\tlanguages[3] = \"python\"\n\n\tfmt.Printf(\"%v\\n\", languages)\n\n\tfind := \"golang\"\n\tfor _, v := range languages {\n\t\tif v == find {\n\t\t\tfmt.Printf(\"%v\\n\", true)\n\t\t\tbreak\n\t\t}\n\t}\n\n\tlanguages = []string{}\n\tfmt.Printf(\"%v\\n\", languages)\n}\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/go/qwik-zgheib.go",
    "content": "package main\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n)\n\ntype Set interface {\n\tAdd(element int)\n\tAddToBeginning(element int)\n\tAddAll(elements ...int)\n\tAddAllAtPosition(position int, elements ...int)\n\tRemoveAt(position int) error\n\tUpdateAt(position int, element int) error\n\tContains(element int) bool\n\tClear()\n\tUnion(other Set) Set\n\tIntersection(other Set) Set\n\tDifference(other Set) Set\n\tSymmetricDifference(other Set) Set\n\tElements() []int\n}\n\ntype IntSet struct {\n\telements []int\n}\n\nfunc NewIntSet() *IntSet {\n\treturn &IntSet{\n\t\telements: []int{},\n\t}\n}\n\nfunc (s *IntSet) Add(element int) {\n\ts.elements = append(s.elements, element)\n}\n\nfunc (s *IntSet) AddToBeginning(element int) {\n\ts.elements = append([]int{element}, s.elements...)\n}\n\nfunc (s *IntSet) AddAll(elements ...int) {\n\ts.elements = append(s.elements, elements...)\n}\n\nfunc (s *IntSet) AddAllAtPosition(position int, elements ...int) {\n\tif position < 0 || position > len(s.elements) {\n\t\treturn\n\t}\n\ts.elements = append(s.elements[:position], append(elements, s.elements[position:]...)...)\n}\n\nfunc (s *IntSet) RemoveAt(position int) error {\n\tif position < 0 || position >= len(s.elements) {\n\t\treturn errors.New(\"position out of bounds\")\n\t}\n\ts.elements = append(s.elements[:position], s.elements[position+1:]...)\n\treturn nil\n}\n\nfunc (s *IntSet) UpdateAt(position int, element int) error {\n\tif position < 0 || position >= len(s.elements) {\n\t\treturn errors.New(\"position out of bounds\")\n\t}\n\ts.elements[position] = element\n\treturn nil\n}\n\nfunc (s *IntSet) Contains(element int) bool {\n\tfor _, el := range s.elements {\n\t\tif el == element {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (s *IntSet) Clear() {\n\ts.elements = []int{}\n}\n\nfunc (s *IntSet) Elements() []int {\n\treturn s.elements\n}\n\nfunc (s *IntSet) Union(other Set) Set {\n\tresult := NewIntSet()\n\texistingElements := s.Elements()\n\totherElements := other.Elements()\n\tresult.AddAll(existingElements...)\n\tfor _, el := range otherElements {\n\t\tif !result.Contains(el) {\n\t\t\tresult.Add(el)\n\t\t}\n\t}\n\treturn result\n}\n\nfunc (s *IntSet) Intersection(other Set) Set {\n\tresult := NewIntSet()\n\tfor _, el := range s.Elements() {\n\t\tif other.Contains(el) {\n\t\t\tresult.Add(el)\n\t\t}\n\t}\n\treturn result\n}\n\nfunc (s *IntSet) Difference(other Set) Set {\n\tresult := NewIntSet()\n\tfor _, el := range s.Elements() {\n\t\tif !other.Contains(el) {\n\t\t\tresult.Add(el)\n\t\t}\n\t}\n\treturn result\n}\n\nfunc (s *IntSet) SymmetricDifference(other Set) Set {\n\tresult := NewIntSet()\n\tfor _, el := range s.Elements() {\n\t\tif !other.Contains(el) {\n\t\t\tresult.Add(el)\n\t\t}\n\t}\n\tfor _, el := range other.Elements() {\n\t\tif !s.Contains(el) {\n\t\t\tresult.Add(el)\n\t\t}\n\t}\n\treturn result\n}\n\nfunc main() {\n\tset := NewIntSet()\n\tset.Add(5)\n\tset.AddToBeginning(1)\n\tset.AddAll(3, 4, 6)\n\tset.AddAllAtPosition(2, 2, 3)\n\n\terrUA := set.UpdateAt(2, 7)\n\tif errUA != nil {\n\t\treturn\n\t}\n\n\terrRA := set.RemoveAt(3)\n\tif errRA != nil {\n\t\treturn\n\t}\n\n\tfmt.Println(\"current set:\", set.Elements())\n\tfmt.Println(\"contains 4:\", set.Contains(4))\n\tfmt.Println(\"contains 8:\", set.Contains(8))\n\n\tset.Clear()\n\tfmt.Println(\"set after cleaning:\", set.Elements())\n\n\tset1 := NewIntSet()\n\tset1.AddAll(1, 2, 3, 4)\n\tset2 := NewIntSet()\n\tset2.AddAll(3, 4, 5, 6)\n\n\tfmt.Println(\"set1:\", set1.Elements())\n\tfmt.Println(\"set2:\", set2.Elements())\n\n\tunionSet := set1.Union(set2)\n\tintersectionSet := set1.Intersection(set2)\n\tdifferenceSet := set1.Difference(set2)\n\tsymmetricDifferenceSet := set1.SymmetricDifference(set2)\n\n\tfmt.Println(\"union:\", unionSet.Elements())\n\tfmt.Println(\"intersection:\", intersectionSet.Elements())\n\tfmt.Println(\"difference:\", differenceSet.Elements())\n\tfmt.Println(\"symmetric difference:\", symmetricDifferenceSet.Elements())\n}\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/go/raynerpv2022.go",
    "content": "package main\n\nimport \"fmt\"\n\n// /*\n//  * EJERCICIO:\n//  * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n//  * operaciones (debes utilizar una estructura que las soporte):\n//  * - Añade un elemento al final.\n//  * - Añade un elemento al principio.\n//  * - Añade varios elementos en bloque al final.\n//  * - Añade varios elementos en bloque en una posición concreta.\n//  * - Elimina un elemento en una posición concreta.\n//  * - Actualiza el valor de un elemento en una posición concreta.\n//  * - Comprueba si un elemento está en un conjunto.\n//  * - Elimina todo el contenido del conjunto.\n//  *\n\n/* DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Unión.\n * - Intersección.\n * - Diferencia.\n * - Diferencia simétrica.\n */\n\nfunc main() {\n\n\tdata := []int{1, 2, 3, 4}\n\tfmt.Printf(\"Original DATA  %v\\n\", data)\n\tdata = append(data, 5)\n\tfmt.Printf(\"add items at the end %v\\n\", data)\n\n\t// append(data[:1], data[0:]...) en este ejemplo, da como resultado [1, 1, 2, 3, 4].\n\t// Aquí, el primer elemento [1] se duplica, pero se está agregando un espacio adicional para el nuevo elemento.\n\tdata = append(data[:1], data[0:]...)\n\tdata[0] = 0\n\tfmt.Printf(\"add item at the Start %v\\n\", data)\n\n\tdata = append(data, []int{6, 7, 8}...)\n\tfmt.Printf(\"add several items at the end %v\\n\", data)\n\n\t// Crear una nueva slice con espacio para los valores adicionales\n\t// y concatenar las partes del slice con los nuevos valores\n\t// es decir parto desde 0 hasta 4, conacteno el nuevo slice, y pego de 5 hasta final\n\tdata = append(data[:5], append([]int{-1, -2, -3}, data[5:]...)...)\n\tfmt.Printf(\"add several items at index position  %v\\n\", data)\n\n\t// creo primer slice hasta posicion deseada a eliminar y el segundo slice desde la posicion siguente,\n\t// eliinando el elemento\n\tdata = append(data[:3], data[4:]...)\n\tfmt.Printf(\"add several items at index position  %v\\n\", data)\n\n\tdata[3] = 100\n\tfmt.Printf(\"Update  item at index position  %v\\n\", data)\n\n\tfound := false\n\tfor _, v := range data {\n\t\tif v == 100 {\n\t\t\tfmt.Printf(\"  %v is in  slice  %v\\n\", 100, data)\n\t\t\tfound = true\n\t\t\tbreak\n\t\t}\n\t}\n\tif !found {\n\t\tfmt.Printf(\"  %v is NOT in  slice  %v\\n\", 100, data)\n\t}\n\tdata = []int{}\n\tfmt.Printf(\"  Data empty  %v\\n\", data)\n\n\t// EXTRA\n\n\tset1 := map[int]bool{0: true, 2: true, 4: true, 6: true, 8: true, 10: true}\n\tset2 := map[int]bool{1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true}\n\n\t// Interseccion\n\tinterseccion := map[int]bool{}\n\tfor i, _ := range set1 {\n\n\t\tintValue := set2[i]\n\t\tif intValue {\n\t\t\tinterseccion[i] = true\n\t\t}\n\t}\n\tfmt.Printf(\"  INTERSECCION  %v\\n\", interseccion)\n\n\t// diferencia set 1 con set2\n\n\tdiferencia1 := map[int]bool{}\n\tfor i, _ := range set1 {\n\t\tdif := set2[i]\n\t\tif !dif {\n\t\t\tdiferencia1[i] = true\n\t\t}\n\t}\n\n\tfmt.Printf(\"  Diferencia Set1 con Set2 %v\\n\", diferencia1)\n\n\t// diferencia set 1 con set2\n\n\tdiferencia2 := map[int]bool{}\n\tfor i, _ := range set2 {\n\t\tdif := set1[i]\n\t\tif !dif {\n\t\t\tdiferencia2[i] = true\n\t\t}\n\t}\n\n\tfmt.Printf(\"  Diferencia Set2 con Set1 %v\\n\", diferencia2)\n\n\t// diferencia simetrica\n\n\tfor i, _ := range diferencia1 {\n\n\t\tdiferencia2[i] = true\n\n\t}\n\n\tfmt.Printf(\"  Diferencia simetrica %v\\n\", diferencia2)\n\n\t// union\n\n\tfor i, _ := range set1 {\n\t\tset2[i] = true\n\t}\n\tfmt.Printf(\"  UNION  %v\\n\", set2)\n\n}\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/go/thegera4.go",
    "content": "package main\n\nimport \"fmt\"\n\ntype Conjunto struct {\n\telementos []string\n}\n\nfunc (c *Conjunto) añadirElementoFinal(elemento string) {\n\tc.elementos = append(c.elementos, elemento)\n}\n\nfunc (c *Conjunto) añadirElementoInicio(elemento string) {\n\tc.elementos = append([]string{elemento}, c.elementos...)\n}\n\nfunc (c *Conjunto) añadirVariosElementosFinal(elementos ...string) { //...string indica que se pueden pasar un numero variable de \"elementos\"\n\tc.elementos = append(c.elementos, elementos...)\n}\n\nfunc (c *Conjunto) añadirVariosElementosPosicion(posicion int, elementos ...string) {\n\t//c.elementos[:posicion] -> elementos desde el inicio hasta la \"posicion\", excluyendo la \"posicion\"\n\tc.elementos = append(c.elementos[:posicion], append(elementos, c.elementos[posicion:]...)...)\n\t//append(elementos, c.elementos[posicion:]...) -> añade los \"elementos\" al final de \"c.elementos\" desde la \"posicion\"\n}\n\nfunc (c *Conjunto) eliminarElementoPosicion(posicion int) {\n\tc.elementos = append(c.elementos[:posicion], c.elementos[posicion+1:]...)\n}\n\nfunc (c *Conjunto) actualizarElementoPosicion(posicion int, elemento string) {\n\tc.elementos[posicion] = elemento\n}\n\nfunc (c *Conjunto) comprobarElemento(elemento string) bool {\n\tfor _, e := range c.elementos {\n\t\tif e == elemento {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (c *Conjunto) eliminarContenido() {\n\tc.elementos = []string{}\n}\n\nfunc main() {\n\tconjunto := Conjunto{}\n\n\tconjunto.añadirElementoFinal(\"naranja\")\n\tfmt.Println(conjunto.elementos)\n\n\tconjunto.añadirElementoInicio(\"manzana\")\n\tfmt.Println(conjunto.elementos)\n\n\tconjunto.añadirVariosElementosFinal(\"pera\", \"kiwi\", \"melon\")\n\tfmt.Println(conjunto.elementos)\n\n\tconjunto.añadirVariosElementosPosicion(2, \"sandia\", \"uva\", \"mango\")\n\tfmt.Println(conjunto.elementos)\n\n\tconjunto.eliminarElementoPosicion(3)\n\tfmt.Println(conjunto.elementos)\n\n\tconjunto.actualizarElementoPosicion(2, \"fresa\")\n\tfmt.Println(conjunto.elementos)\n\n\tfmt.Println(conjunto.comprobarElemento(\"fresa\"))\n\tfmt.Println(conjunto.comprobarElemento(\"platano\"))\n\n\tconjunto.eliminarContenido()\n\tfmt.Println(conjunto.elementos)\n\n\t//Extra:\n\n\t//Unión\n\tconjunto1 := Conjunto{}\n\tconjunto1.añadirVariosElementosFinal(\"naranja\", \"manzana\")\n\tconjunto2 := Conjunto{}\n\tconjunto2.añadirVariosElementosFinal(\"pera\", \"uva\")\n\tconjunto1.union(conjunto2)\n\tfmt.Println(\"Union: \", conjunto1.elementos)\n\n\t//Intersección\n\tconjunto3 := Conjunto{}\n\tconjunto3.añadirVariosElementosFinal(\"naranja\", \"manzana\", \"pera\")\n\tconjunto4 := Conjunto{}\n\tconjunto4.añadirVariosElementosFinal(\"pera\", \"uva\")\n\tconjunto3.interseccion(conjunto4)\n\tfmt.Println(\"Interseccion: \", conjunto3.elementos)\n\n\t//Diferencia\n\tconjunto5 := Conjunto{}\n\tconjunto5.añadirVariosElementosFinal(\"naranja\", \"manzana\", \"pera\")\n\tconjunto6 := Conjunto{}\n\tconjunto6.añadirVariosElementosFinal(\"pera\", \"uva\")\n\tconjunto5.diferencia(conjunto6)\n\tfmt.Println(\"Diferencia: \", conjunto5.elementos)\n\n\t//Diferencia simétrica\n\tconjunto7 := Conjunto{}\n\tconjunto7.añadirVariosElementosFinal(\"naranja\", \"manzana\", \"pera\")\n\tconjunto8 := Conjunto{}\n\tconjunto8.añadirVariosElementosFinal(\"pera\", \"uva\")\n\tconjunto7.diferenciaSimetrica(conjunto8)\n\tfmt.Println(\"Diferencia simetrica: \", conjunto7.elementos)\n\n}\n\n//Extra:\n\n//Unión\nfunc (c *Conjunto) union(c2 Conjunto) {\n\tfor _, e := range c2.elementos {\n\t\tif !c.comprobarElemento(e) {\n\t\t\tc.añadirElementoFinal(e)\n\t\t}\n\t}\n}\n\n//Intersección\nfunc (c *Conjunto) interseccion(c2 Conjunto) {\n\tfor i := 0; i < len(c.elementos); i++ {\n\t\tif !c2.comprobarElemento(c.elementos[i]) {\n\t\t\tc.eliminarElementoPosicion(i)\n\t\t\ti--\n\t\t}\n\t}\n}\n\n//Diferencia\nfunc (c *Conjunto) diferencia(c2 Conjunto) {\n\tfor i := 0; i < len(c.elementos); i++ {\n\t\tif c2.comprobarElemento(c.elementos[i]) {\n\t\t\tc.eliminarElementoPosicion(i)\n\t\t\ti--\n\t\t}\n\t}\n}\n\n//Diferencia simétrica\nfunc (c *Conjunto) diferenciaSimetrica(c2 Conjunto) {\n\t// crear conjuntos temporales/auxiliares\n\ttemp1 := make(map[string]bool)\n\ttemp2 := make(map[string]bool)\n\n\t// almacenar los elementos unicos del primer conjunto\n\tfor _, e := range c.elementos {\n\t\ttemp1[e] = true\n\t}\n\n\t// almacenar los elementos unicos del segundo conjunto\n\tfor _, e := range c2.elementos {\n\t\ttemp2[e] = true\n\t}\n\n\t// crear un nuevo conjunto para almacenar la diferencia simetrica\n\tdiff := Conjunto{}\n\n\t// agregar elementos que estan en c pero no en c2\n\tfor e := range temp1 {\n\t\tif !temp2[e] {\n\t\t\tdiff.añadirElementoFinal(e)\n\t\t}\n\t}\n\n\t// agregar elementos que estan en c2 pero no en c\n\tfor e := range temp2 {\n\t\tif !temp1[e] {\n\t\t\tdiff.añadirElementoFinal(e)\n\t\t}\n\t}\n\n\t// actualizar el conjunto original con la diferencia simetrica\n\t*c = diff\n}"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/java/AmadorQuispe.java",
    "content": "/* ╔══════════════════════════════════════╗\n   ║ Autor:  Amador Q                     ║\n   ║ Web  : https://amsoft.dev            ║\n   ║ 2024                                 ║\n   ╚══════════════════════════════════════╝\n*/\n\nimport java.util.Arrays;\nimport java.util.LinkedHashSet;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.Set;\n\npublic class Main {\n\n    public static void main(String[] args) {\n        List<String> conjunto = new LinkedList<>();\n\n        // Añade un elemento al final.\n        conjunto.add(\"C\");\n        conjunto.add(\"D\");\n        conjunto.add(\"E\");\n        conjunto.add(\"J\");\n        conjunto.add(\"K\");\n\n        System.out.println(conjunto);\n\n        // Agregar al inicio\n        conjunto.add(0, \"A\");\n        System.out.println(conjunto);\n\n        // Agregar en posición concreta\n        conjunto.add(1, \"B\");\n        System.out.println(conjunto);\n\n        // Añade varios elementos en bloque al final.\n        List<String> bloque = new LinkedList<>();\n        bloque.add(\"L\");\n        bloque.add(\"M\");\n        bloque.add(\"N\");\n        bloque.add(\"O\");\n        conjunto.addAll(bloque);\n        System.out.println(conjunto);\n\n        // Añade varios elementos en bloque en una posición concreta.\n        List<String> bloque1 = new LinkedList<>();\n        bloque1.add(\"F\");\n        bloque1.add(\"G\");\n        bloque1.add(\"H\");\n        bloque1.add(\"I\");\n        conjunto.addAll(5, bloque1);\n        System.out.println(conjunto);\n\n        // Elimina un elemento en una posición concreta.\n        conjunto.remove(0);\n        System.out.println(conjunto);\n\n        // Actualiza el valor de un elemento en una posición concreta\n        conjunto.set(0, \"A\");\n        System.out.println(conjunto);\n\n        // Comprueba si un elemento está en un conjunto.\n        System.out.println(\"¿Está la letra 'B'? \" + conjunto.contains(\"B\"));\n\n        // Elimina todo el contenido del conjunto.\n        conjunto.clear();\n\n        // EXTRA\n        extra();\n    }\n\n    static void extra() {\n        Set<String> conjuntoA = new LinkedHashSet<>(List.of(\"A\", \"B\", \"C\", \"D\"));\n        System.out.println(\"Conjunto A: \" + conjuntoA);\n\n        Set<String> conjuntoB = new LinkedHashSet<>(List.of(\"C\", \"D\", \"E\", \"F\"));\n        System.out.println(\"Conjunto B: \" + conjuntoB);\n\n        // Unión\n        Set<String> union = new LinkedHashSet<>(conjuntoA);\n        union.addAll(conjuntoB);\n        System.out.println(\"Unión: \" + union);\n\n        // Intersección\n        Set<String> interseccion = new LinkedHashSet<>(conjuntoA);\n        interseccion.retainAll(conjuntoB);\n        System.out.println(\"Intersección: \" + interseccion);\n\n        // Diferencia (A - B)\n        Set<String> diferenciaAB = new LinkedHashSet<>(conjuntoA);\n        diferenciaAB.removeAll(conjuntoB);\n        System.out.println(\"Diferencia (A - B): \" + diferenciaAB);\n\n        // Diferencia simétrica (A Δ B)\n        Set<String> diferenciaSimetrica = new LinkedHashSet<>(conjuntoA);\n        diferenciaSimetrica.addAll(conjuntoB);\n        Set<String> interseccionRemoval = new LinkedHashSet<>(conjuntoA);\n        interseccionRemoval.removeAll(conjuntoB);\n        diferenciaSimetrica.removeAll(interseccionRemoval);\n        System.out.println(\"Diferencia simétrica (A Δ B): \" + diferenciaSimetrica);\n    }\n}\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/java/AnaLauDB.java",
    "content": "import java.util.*;\n\npublic class AnaLauDB {\n    public static void main(String[] args) {\n        // Usamos ArrayList para operaciones de posición\n        List<String> lista = new ArrayList<>(Arrays.asList(\"A\", \"B\", \"C\"));\n        System.out.println(\"Lista inicial: \" + lista);\n\n        // Añadir al final\n        lista.add(\"D\");\n        System.out.println(\"Añadir al final: \" + lista);\n\n        // Añadir al principio\n        lista.add(0, \"Inicio\");\n        System.out.println(\"Añadir al principio: \" + lista);\n\n        // Añadir varios al final\n        lista.addAll(Arrays.asList(\"E\", \"F\"));\n        System.out.println(\"Añadir varios al final: \" + lista);\n\n        // Añadir varios en posición concreta (en la posición 2)\n        lista.addAll(2, Arrays.asList(\"X\", \"Y\"));\n        System.out.println(\"Añadir varios en posición 2: \" + lista);\n\n        // Eliminar elemento en posición concreta (posición 3)\n        lista.remove(3);\n        System.out.println(\"Eliminar elemento en posición 3: \" + lista);\n\n        // Actualizar valor en posición concreta (posición 1)\n        lista.set(1, \"NuevoValor\");\n        System.out.println(\"Actualizar valor en posición 1: \" + lista);\n\n        // Comprobar si un elemento está en el conjunto\n        System.out.println(\"¿Contiene 'E'? \" + lista.contains(\"E\"));\n\n        // Eliminar todo el contenido\n        lista.clear();\n        System.out.println(\"Lista tras clear(): \" + lista);\n\n        // DIFICULTAD EXTRA: Operaciones de conjuntos\n        Set<Integer> conjunto1 = new HashSet<>(Arrays.asList(1, 2, 3, 4));\n        Set<Integer> conjunto2 = new HashSet<>(Arrays.asList(3, 4, 5, 6));\n\n        // Unión\n        Set<Integer> union = new HashSet<>(conjunto1);\n        union.addAll(conjunto2);\n        System.out.println(\"Unión: \" + union);\n\n        // Intersección\n        Set<Integer> interseccion = new HashSet<>(conjunto1);\n        interseccion.retainAll(conjunto2);\n        System.out.println(\"Intersección: \" + interseccion);\n\n        // Diferencia\n        Set<Integer> diferencia = new HashSet<>(conjunto1);\n        diferencia.removeAll(conjunto2);\n        System.out.println(\"Diferencia (conjunto1 - conjunto2): \" + diferencia);\n\n        // Diferencia simétrica\n        Set<Integer> difSim = new HashSet<>(union);\n        difSim.removeAll(interseccion);\n        System.out.println(\"Diferencia simétrica: \" + difSim);\n    }\n}\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/java/FranDev200.java",
    "content": "import java.util.ArrayList;\nimport java.util.HashSet;\nimport java.util.Set;\n\npublic class FranDev200 {\n\n\n    static void main() {\n\n        /*\n\n        EJERCICIO:\n        * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n        * operaciones (debes utilizar una estructura que las soporte):\n        * - Añade un elemento al final.\n        * - Añade un elemento al principio.\n        * - Añade varios elementos en bloque al final.\n        * - Añade varios elementos en bloque en una posición concreta.\n        * - Elimina un elemento en una posición concreta.\n        * - Actualiza el valor de un elemento en una posición concreta.\n        * - Comprueba si un elemento está en un conjunto.\n        * - Elimina todo el contenido del conjunto.\n\n         */\n\n        ArrayList<Integer> lista = new ArrayList<>();\n        lista.add(1);\n        lista.add(2);\n        lista.add(3);\n        lista.add(5);\n\n        System.out.println(\"Lista inicial\");\n        System.out.println(lista);\n\n        // Añadir un elemento al final\n        lista.addLast(4);\n        System.out.println(\"Número añadido al final de la lista [4]:\");\n        System.out.println(lista);\n\n        // Añadir un elemento al principio\n        lista.addFirst(0);\n        System.out.println(\"Número añadido al principio de la lista [0]:\");\n        System.out.println(lista);\n\n        // Añade varios elementos en bloque al final\n        ArrayList<Integer> bloqueAniadir = new ArrayList<>();\n        bloqueAniadir.add(7);\n        bloqueAniadir.add(8);\n        bloqueAniadir.add(9);\n        lista.addAll(lista.size(), bloqueAniadir);\n        System.out.println(\"Bloque añadido al final de la lista [7, 8, 9]:\");\n        System.out.println(lista);\n\n        // Añade varios elementos en bloque en una posicion concreta\n        ArrayList<Integer> bloqueAniadir2 = new ArrayList<>();\n        bloqueAniadir2.add(3);\n        bloqueAniadir2.add(3);\n        bloqueAniadir2.add(3);\n        lista.addAll(lista.indexOf(5), bloqueAniadir2);\n        System.out.println(\"Bloque añadido en una posicion especifica de la lista [3, 3, 3] | Pos -> Donde este el 5:\");\n        System.out.println(lista);\n\n        // Elimina un elemento de una posicion concreta\n        lista.remove(8);\n        System.out.println(\"Elemento de una posicion concreta eliminado [8]:\");\n        System.out.println(lista);\n\n        // Actualizacion de un elemento\n        lista.set(4, 4);\n        System.out.println(\"Elemento de una posicion concreta actualizado [4]:\");\n        System.out.println(lista);\n\n        // Comprobar si un elemento esta en la lista\n        System.out.println(\"¿Está el 34 en la lista?\");\n        System.out.println(lista.contains(34));\n\n        // Limpiar la lista\n        lista.clear();\n        System.out.println(\"Contenido de la lista despues de limpiarla\");\n\n        /*\n        DIFICULTAD EXTRA (opcional):\n        * Muestra ejemplos de las siguientes operaciones con conjuntos:\n        * - Unión.\n        * - Intersección.\n        * - Diferencia.\n        * - Diferencia simétrica.\n         */\n\n        System.out.println(\"\\nEjercicio Extra\");\n        Set<String> listaUnion = new HashSet<>();\n        Set<String> listaInterseccion = new HashSet<>();\n        Set<String> listaDiferencia = new HashSet<>();\n        Set<String> listaDiferenciaSimetrica = new HashSet<>();\n        Set<String> listaDiferenciaSimetricaCoincidentes = new HashSet<>();\n\n        Set<String> alumnosFisica = new HashSet<>();\n        Set<String> alumnosBiologia = new HashSet<>();\n\n        alumnosFisica.add(\"Manuel\");\n        alumnosFisica.add(\"Inma\");\n        alumnosFisica.add(\"Mario\");\n\n        alumnosBiologia.add(\"Laura\");\n        alumnosBiologia.add(\"Manuel\");\n        alumnosBiologia.add(\"Carlos\");\n\n        System.out.println(\"\\nAlumnos de la clase de Física: \" + alumnosFisica);\n        System.out.println(\"Alumnos de la clase de Biologia: \" + alumnosBiologia);\n\n        // UNION\n        listaUnion.addAll(alumnosFisica);\n        listaUnion.addAll(alumnosBiologia);\n        System.out.println(\"===== ||\");\n        System.out.println(\"UNION ||\");\n        System.out.println(\"===== ||\");\n        System.out.println(\"Todos los alumnos que hay: \" + listaUnion);\n\n        // INTERSECCION\n        listaInterseccion.addAll(alumnosFisica);\n        listaInterseccion.retainAll(alumnosBiologia);\n        System.out.println(\"============ ||\");\n        System.out.println(\"INTERSECCION ||\");\n        System.out.println(\"============ ||\");\n        System.out.println(\"Alumnos comunes de ambas asignaturas: \" + listaInterseccion);\n\n        // DIFERENCIA\n        listaDiferencia.addAll(alumnosFisica);\n        listaDiferencia.removeAll(alumnosBiologia);\n        System.out.println(\"=================== ||\");\n        System.out.println(\"DIFERENCIA (Física) ||\");\n        System.out.println(\"=================== ||\");\n        System.out.println(\"Alumnos que solo van a física: \" + listaDiferencia);\n\n        listaDiferencia.clear();\n\n        listaDiferencia.addAll(alumnosBiologia);\n        listaDiferencia.removeAll(alumnosFisica);\n        System.out.println(\"===================== ||\");\n        System.out.println(\"DIFERENCIA (Biologia) ||\");\n        System.out.println(\"===================== ||\");\n        System.out.println(\"Alumnos que solo van a biología: \" + listaDiferencia);\n\n        // DIFERENCIA SIMETRICA\n        listaDiferenciaSimetrica.addAll(alumnosFisica);\n        listaDiferenciaSimetrica.addAll(alumnosBiologia);\n        listaDiferenciaSimetricaCoincidentes.addAll(alumnosFisica);\n        listaDiferenciaSimetricaCoincidentes.retainAll(alumnosBiologia);\n        listaDiferenciaSimetrica.removeAll(listaDiferenciaSimetricaCoincidentes);\n        System.out.println(\"===================== ||\");\n        System.out.println(\"DIFERENCIA (Biologia o Física) ||\");\n        System.out.println(\"===================== ||\");\n        System.out.println(\"Alumnos que solo van a biología o a física: \" + listaDiferenciaSimetrica);\n\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/java/JimsimroDev.java",
    "content": "/*\n * EJERCICIO:\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n * operaciones (debes utilizar una estructura que las soporte):\n * - Añade un elemento al final.\n * - Añade un elemento al principio.\n * - Añade varios elementos en bloque al final.\n * - Añade varios elementos en bloque en una posición concreta.\n * - Elimina un elemento en una posición concreta.\n * - Actualiza el valor de un elemento en una posición concreta.\n * - Comprueba si un elemento está en un conjunto.\n * - Elimina todo el contenido del conjunto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Unión.\n * - Intersección.\n * - Diferencia.\n * - Diferencia simétrica.\n */\n\nimport java.util.HashSet;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.Set;\n\nclass Conjunto {\n  final String DIVLINE = \":::::::::::::::::::::::::::::::::\";\n  LinkedList<Integer> conjunto = new LinkedList<>();\n\n  // agrega los primeros 6 elementos a la pila\n  void agregaPrimerosDatos() {\n    for (int i = 1; i <= 6; i++) {\n      conjunto.add(i);\n    }\n  }\n\n  // agrega elemento al final\n  void agragarElementoAlFinal(int elemento) {\n    conjunto.addLast(elemento);\n\n  }\n\n  // agrega elemento al principio\n  void agragarElementoAlPrincipio(int elemento) {\n    conjunto.addFirst(elemento);\n  }\n\n  // Añade varios elementos en bloque al final.\n  void agregaVariosElmentosAlFinal(List<Integer> nuevosElementos) {\n    conjunto.addAll(nuevosElementos);\n  }\n\n  // Añade varios elementos en bloque en una posición concreta.\n  void agregaVariosElmentosSegunPosicionDada(int posicion, List<Integer> elementosNuevos) {\n    conjunto.addAll(posicion, elementosNuevos);\n  }\n\n  // Elimina un elemento en una posición concreta.\n  void eliminarValor(int posicion) {\n    try {\n      conjunto.remove(posicion);\n      IO.println(String.format(\"Se elimino el elemento en la posición %d \", posicion));\n    } catch (Exception e) {\n      IO.println(String.format(\"El conjunto solo tiene %d posiciónes %s\", conjunto.size(), e));\n    }\n  }\n\n  // Actualiza el valor de un elemento en una posición concreta.\n  void actualizarElemento(int posicion, int elemento) {\n    conjunto.set(posicion, elemento);\n  }\n\n  // Validar si el valor existe en el conjunto\n  boolean ifValueExist(int valor) {\n    for (int i = 0; i < conjunto.size(); i++) {\n      if (conjunto.get(i) == valor) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  void valorEncotrado(int valor) {\n    String valorEncotrado = ifValueExist(valor) ? String.format(\"El valor %d si esta en el conjunto\", valor)\n        : String.format(\"El valor %d no se encuentra en el conjunto\", valor);\n    IO.println(valorEncotrado);\n  }\n\n  // Imprime los valores del conjunto y su posición\n  void printConjunto() {\n    for (int i = 0; i < conjunto.size(); i++) {\n      IO.print(String.format(\"posición %d valor %d %n \", i, conjunto.get(i)));\n    }\n  }\n\n  // Inicializa el conjunto y le agrega valores\n  void run() {\n    agregaPrimerosDatos();\n\n    IO.println(DIVLINE);\n    printConjunto();\n\n    agragarElementoAlFinal(7);\n\n    IO.println(DIVLINE);\n    printConjunto();\n    agragarElementoAlPrincipio(8);\n    List<Integer> elementos = List.of(11, 12, 13);\n    agregaVariosElmentosAlFinal(elementos);\n\n    IO.println(DIVLINE);\n    printConjunto();\n    List<Integer> elementosNuevos = List.of(8, 9, 10);\n    agregaVariosElmentosSegunPosicionDada(8, elementosNuevos);\n    IO.println(DIVLINE);\n    printConjunto();\n\n    eliminarValor(0);\n\n    IO.println(DIVLINE);\n    printConjunto();\n\n    actualizarElemento(0, 30);\n    valorEncotrado(12);\n    IO.println(DIVLINE);\n    printConjunto();\n\n    conjunto.clear();\n    IO.println(DIVLINE);\n    IO.println(conjunto);\n  }\n\n  void main() {\n    run();\n    // EXTRA\n    IO.println(\"EXTRA\");\n    Set<Integer> elementos1 = new HashSet<>();\n    elementos1.add(1);\n    elementos1.add(2);\n    elementos1.add(3);\n    elementos1.add(4);\n    elementos1.add(5);\n    IO.println(elementos1);\n\n    Set<Integer> elementos2 = new HashSet<>();\n    elementos2.add(1);\n    elementos2.add(2);\n    elementos2.add(3);\n    elementos2.add(4);\n    elementos2.add(6);\n    elementos2.add(7);\n    IO.println(elementos2);\n\n    // Unión\n    Set<Integer> union = new HashSet<>(elementos1);\n    union.addAll(elementos2);\n\n    IO.println(\"Unión\");\n    IO.println(union);\n\n    // Intersección\n    Set<Integer> interseccion = new HashSet<>(elementos2);\n    interseccion.retainAll(elementos1);\n    IO.println(\"Intersección\");\n    IO.println(interseccion);\n\n    // Diferencia\n    Set<Integer> diferencia = new HashSet<>(elementos2);\n    diferencia.removeAll(elementos1);\n    IO.println(\"Diferencia\");\n    IO.println(diferencia);\n\n    // Diferencia simétrica\n    Set<Integer> diferenciaSimetrica = new HashSet<>(union);\n    diferenciaSimetrica.removeAll(interseccion);\n    IO.println(\"Diferencia simétrica\");\n    IO.print(diferenciaSimetrica);\n  }\n}\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/java/Josegs95.java",
    "content": "import java.util.*;\n\npublic class Josegs95 {\n    public static void main(String[] args) {\n        //Lo mas parecido a un conjunto en java son los Set.\n        //Pero para la parte del ejercicio, voy a usar una lista, ya que hay operaciones que\n        //ninguna implementación de Set puede hacer de forma nativa.\n        List<String> elementList = new ArrayList<>();\n        elementList.add(\"1\");\n        elementList.add(\"2\");\n        elementList.add(\"3\");\n        System.out.println(elementList);\n\n\n        //Añadir elemento al final\n        elementList.add(\"Final\");\n        System.out.println(\"1. \" + elementList);\n\n        //Añadir elemento al principio\n        elementList.add(0, \"Principio\");\n        System.out.println(\"2. \" + elementList);\n\n        //Añadir varios elementos al final\n        elementList.addAll(Arrays.asList(\"Final1\", \"Final2\"));\n        System.out.println(\"3. \" + elementList);\n\n        //Añadir varios elementos en una posición\n        elementList.addAll(2, Arrays.asList(\"1.3\", \"1.6\"));\n        System.out.println(\"4. \" + elementList);\n\n        //Eliminar elemento por posición\n        elementList.remove(2);\n        System.out.println(\"5. \" + elementList);\n\n        //Actualizar elemento por posición\n        elementList.set(5, \"FinalActualizado\");\n        System.out.println(\"6. \" + elementList);\n\n        //Comprobar si existe un elemento en el conjunto\n        System.out.println(\"7. Existe el elemento '4': \" + elementList.contains(\"4\"));\n\n        //Elimina el contenido del conjunto\n        elementList.clear();\n        System.out.println(\"8. \" + elementList);\n\n        //Reto\n        retoFinal();\n    }\n\n    public static void retoFinal(){\n        Set<String> set1 = new HashSet<>(Arrays.asList(\"1\", \"2\", \"4\", \"6\"));\n        Set<String> set2 = new HashSet<>(Arrays.asList(\"1\", \"3\", \"6\", \"9\"));\n        System.out.println(\"Set1: \" + set1);\n        System.out.println(\"Set2: \" + set2);\n\n        //Union\n        Set<String> union = new HashSet<>(set1);\n        union.addAll(set2);\n        System.out.println(\"Set1 U Set2: \" + union);\n\n        //Intersección\n        Set<String> intersection = new HashSet<>(set1);\n        intersection.retainAll(set2);\n        System.out.println(\"Set1 ∩ Set2: \" + intersection);\n\n        //Diferencia\n        Set<String> difference = new HashSet<>(set1);\n        difference.removeAll(set2);\n        System.out.println(\"Set1 - Set2: \" + difference);\n\n        //Diferencia simétrica\n        Set<String> symmetricDifference = new HashSet<>(union);\n        symmetricDifference.removeAll(intersection);\n        System.out.println(\"Set1 Δ Set2: \" + symmetricDifference);\n    }\n}\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/java/asjordi.java",
    "content": "import java.util.HashSet;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.Set;\n\npublic class Main {\n\n    public static void main(String[] args) {\n        operaciones();\n        operacionesConjuntos();\n    }\n\n    /**\n     * EJERCICIO:\n     * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n     * operaciones (debes utilizar una estructura que las soporte):\n     * - Añade un elemento al final.\n     * - Añade un elemento al principio.\n     * - Añade varios elementos en bloque al final.\n     * - Añade varios elementos en bloque en una posición concreta.\n     * - Elimina un elemento en una posición concreta.\n     * - Actualiza el valor de un elemento en una posición concreta.\n     * - Comprueba si un elemento está en un conjunto.\n     * - Elimina todo el contenido del conjunto.\n     */\n    static void operaciones(){\n        List<Integer> lista = new LinkedList<>(List.of(1, 2, 3, 4, 5));\n\n        System.out.println(\"Lista original: \" + lista);\n\n        // Añade un elemento al final\n        lista.add(6);\n\n        // Añade un elemento al principio\n        lista.add(0, 0);\n\n        // Añade varios elementos en bloque al final\n        lista.addAll(List.of(7, 8, 9));\n\n        // Añade varios elementos en bloque en una posición concreta\n        lista.addAll(0, List.of(-3, -2, -1));\n\n        // Elimina un elemento en una posición concreta\n        lista.remove(0);\n\n        // Actualiza el valor de un elemento en una posición concreta\n        lista.set(0, -10);\n\n        // Comprueba si un elemento está en un conjunto\n        var containsNumber = lista.contains(5);\n\n        System.out.println(\"Lista modificada: \" + lista);\n\n        // Elimina todo el contenido del conjunto\n        lista.clear();\n\n        System.out.println(\"Lista vacía: \" + lista);\n    }\n\n    /**\n     * DIFICULTAD EXTRA (opcional):\n     * Muestra ejemplos de las siguientes operaciones con conjuntos:\n     * - Unión.\n     * - Intersección.\n     * - Diferencia.\n     * - Diferencia simétrica.\n     */\n    static void operacionesConjuntos(){\n        // Crear dos conjuntos de números para realizar las operaciones\n        Set<Integer> conjunto1 = new HashSet<>(Set.of(1, 2, 3, 4, 5));\n        Set<Integer> conjunto2 = new HashSet<>(Set.of(4, 5, 6, 7, 8));\n\n        // UNIÓN\n        Set<Integer> union = new HashSet<>(conjunto1);\n        union.addAll(conjunto2);\n\n        System.out.println(\"Unión: \" + union);\n\n        // INTERSECCIÓN\n        Set<Integer> interseccion = new HashSet<>(conjunto1);\n        interseccion.retainAll(conjunto2);\n\n        System.out.println(\"Intersección: \" + interseccion);\n\n        // DIFERENCIA\n        Set<Integer> diferencia = new HashSet<>(conjunto1);\n        diferencia.removeAll(conjunto2);\n\n        System.out.println(\"Diferencia: \" + diferencia);\n\n        // DIFERENCIA SIMÉTRICA\n        Set<Integer> diferenciaSimetrica = new HashSet<>(conjunto1);\n        diferenciaSimetrica.addAll(conjunto2);\n        Set<Integer> tmp = new HashSet<>(conjunto1);\n        tmp.retainAll(conjunto2);\n        diferenciaSimetrica.removeAll(tmp);\n\n        System.out.println(\"Diferencia simétrica: \" + diferenciaSimetrica);\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/java/chartypes.java",
    "content": "import java.util.ArrayList;\nimport java.util.HashSet;\nimport java.util.Set;\n\npublic class chartypes {\n\n  public static void main(String[] args) {\n    exercise();\n    System.out.println(\"Extra\");\n    extra();\n\n  }\n\n  private static void exercise() {\n    ArrayList<Integer> numbers = new ArrayList<>();\n    // Añade un elemento al final.\n    numbers.addLast(1);\n    System.out.println(numbers);\n    // Añade un elemento al principio.\n    numbers.addFirst(5);\n    System.out.println(numbers);\n    // Añade varios elementos en bloque al final.\n    ArrayList<Integer> myList = new ArrayList<>();\n    myList.add(1);\n    myList.add(2);\n    myList.add(3);\n    numbers.addAll(myList);\n    System.out.println(numbers);\n    // Añade varios elementos en bloque en una posición concreta.\n    numbers.addAll(1, myList);\n    System.out.println(numbers);\n    // Elimina un elemento en una posición concreta.\n    numbers.remove(1);\n    System.out.println(numbers);\n    // Actualiza el valor de un elemento en una posición concreta.\n    numbers.set(2, 800);\n    System.out.println(numbers);\n    // Comprueba si un elemento está en un conjunto.\n    System.out.println(numbers.contains(800));\n    // Elimina todo el contenido del conjunto.\n    numbers.clear();\n    System.out.println(numbers);\n  }\n\n  private static void extra() {\n    Set<Integer> A = new HashSet<>();\n    Set<Integer> B = new HashSet<>();\n    A.add(1);\n    A.add(2);\n    A.add(3);\n    A.add(6);\n    B.add(3);\n    B.add(4);\n    B.add(5);\n    B.add(6);\n\n    // * - Unión.\n    Set<Integer> union = new HashSet<>(A);\n    union.addAll(B);\n    System.out.println(union);\n\n    // * - Intersección.\n    Set<Integer> intersection = new HashSet<>(A);\n    intersection.retainAll(B);\n    System.out.println(intersection);\n    // * - Diferencia.\n    Set<Integer> difference = new HashSet<>(A);\n    difference.removeAll(B);\n    System.out.println(difference);\n    // * - Diferencia simétrica.\n    Set<Integer> simetricDifferenceUnion = new HashSet<>(A);\n    simetricDifferenceUnion.addAll(B);\n    Set<Integer> simetricDifferenceIntersection = new HashSet<>(A);\n    simetricDifferenceIntersection.retainAll(B);\n\n    simetricDifferenceUnion.removeAll(simetricDifferenceIntersection);\n    System.out.println(simetricDifferenceUnion);\n\n  }\n\n}\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/java/danhingar.java",
    "content": "import java.util.ArrayList;\nimport java.util.HashSet;\nimport java.util.List;\n\npublic class danhingar {\n    public static void main(String[] args) {\n        List<Integer> numbers = new ArrayList<>();\n        numbers.add(1);\n        numbers.add(2);\n        numbers.add(3);\n        numbers.add(4);\n        numbers.add(5);\n        numbers.add(6);\n\n        // Añade elemento al final\n        numbers.add(7);\n        System.out.println(numbers);\n\n        // Añade elemento al principio\n        numbers.addFirst(0);\n        System.out.println(numbers);\n\n        // Añade varios elementos en bloque al final.\n        numbers.addAll(List.of(8, 9, 10));\n        System.out.println(numbers);\n\n        // Añade varios elementos en bloque en una posición concreta.\n        numbers.addAll(2, List.of(11, 12));\n        System.out.println(numbers);\n\n        // Elimina un elemento en una posición concreta.\n        numbers.remove(3);\n        System.out.println(numbers);\n\n        // Actualiza el valor de un elemento en una posición concreta.\n        numbers.set(3, 20);\n        System.out.println(numbers);\n\n        // Comprueba si un elemento está en un conjunto.\n        System.out.println(numbers.contains(9));\n\n        // Elimina todo el contenido del conjunto.\n        numbers.clear();\n        System.out.println(numbers);\n\n        // Extra\n        List<String> letters1 = new ArrayList<>(List.of(\"A\", \"B\", \"C\", \"D\"));\n        List<String> letters2 = new ArrayList<>(List.of(\"D\", \"C\", \"V\", \"T\"));\n\n        // Union\n        List<String> letters3 = new ArrayList<>(letters1);\n        letters3.addAll(letters2);\n        System.out.println(\"Unión: \" + new HashSet<>(letters3));\n\n        // Interseccion\n        List<String> letters4 = new ArrayList<>(letters1);\n        letters4.retainAll(letters2);\n        System.out.println(\"Intersección: \" + new HashSet<>(letters4));\n\n        // Diferencia 1\n        List<String> letters5 = new ArrayList<>(letters1);\n        letters5.removeAll(letters4);\n        System.out.println(\"Diferencia : \" + new HashSet<>(letters5));\n\n        // Diferencia 2\n        List<String> letters6 = new ArrayList<>(letters2);\n        letters6.removeAll(letters4);\n        System.out.println(\"Diferencia : \" + new HashSet<>(letters6));\n\n        // Diferencia simétrica\n        letters3.removeAll(letters4);\n        System.out.println(\"Diferencia: \" + new HashSet<>(letters3));\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/java/eulogioep.java",
    "content": "import java.util.*;\n\npublic class eulogioep {\n    public static void main(String[] args) {\n        // TEORÍA: Los conjuntos en Java\n        /*\n         * En Java, un Set es una colección que no puede contener elementos duplicados.\n         * Hay tres implementaciones principales de Set:\n         * 1. HashSet - La más rápida, no mantiene orden\n         * 2. TreeSet - Mantiene los elementos ordenados\n         * 3. LinkedHashSet - Mantiene el orden de inserción\n         * \n         * Para este ejercicio, usaremos principalmente HashSet para las operaciones básicas\n         * y luego mostraremos ejemplos con otros tipos para las operaciones adicionales.\n         */\n\n        // PARTE 1: OPERACIONES BÁSICAS CON CONJUNTOS\n        System.out.println(\"PARTE 1: OPERACIONES BÁSICAS\");\n        \n        // Creación de un conjunto\n        Set<String> conjunto = new HashSet<>();\n        System.out.println(\"Conjunto inicial: \" + conjunto);\n\n        // 1. Añadir un elemento al final\n        // NOTA: En un HashSet no hay \"final\" como tal, ya que no mantiene orden\n        conjunto.add(\"Elemento1\");\n        System.out.println(\"Después de añadir un elemento: \" + conjunto);\n\n        // 2. Añadir un elemento al principio\n        // NOTA: Como HashSet no mantiene orden, es igual que añadir al final\n        conjunto.add(\"Elemento2\");\n        System.out.println(\"Después de añadir otro elemento: \" + conjunto);\n\n        // 3. Añadir varios elementos en bloque al final\n        List<String> elementosNuevos = Arrays.asList(\"Elemento3\", \"Elemento4\", \"Elemento5\");\n        conjunto.addAll(elementosNuevos);\n        System.out.println(\"Después de añadir varios elementos: \" + conjunto);\n\n        // 4. Añadir elementos en una posición concreta\n        // NOTA: HashSet no permite insertar en posiciones específicas\n        // Para demostrar esto, usaremos una LinkedList temporalmente\n        List<String> listaOrdenada = new LinkedList<>(conjunto);\n        listaOrdenada.addAll(2, Arrays.asList(\"ElementoA\", \"ElementoB\"));\n        conjunto = new HashSet<>(listaOrdenada);\n        System.out.println(\"Después de 'insertar' en posición específica: \" + conjunto);\n\n        // 5. Eliminar un elemento\n        conjunto.remove(\"Elemento3\");\n        System.out.println(\"Después de eliminar 'Elemento3': \" + conjunto);\n\n        // 6. Actualizar un elemento\n        // NOTA: En un Set no se pueden actualizar elementos directamente\n        // Hay que eliminar el viejo y añadir el nuevo\n        if (conjunto.remove(\"Elemento4\")) {\n            conjunto.add(\"Elemento4Actualizado\");\n        }\n        System.out.println(\"Después de actualizar 'Elemento4': \" + conjunto);\n\n        // 7. Comprobar si un elemento está en el conjunto\n        boolean contiene = conjunto.contains(\"Elemento1\");\n        System.out.println(\"¿Contiene 'Elemento1'? \" + contiene);\n\n        // 8. Eliminar todo el contenido\n        conjunto.clear();\n        System.out.println(\"Después de limpiar el conjunto: \" + conjunto);\n\n        // PARTE 2: OPERACIONES EXTRA CON CONJUNTOS\n        System.out.println(\"\\nPARTE 2: OPERACIONES EXTRA\");\n        \n        Set<Integer> conjunto1 = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5));\n        Set<Integer> conjunto2 = new HashSet<>(Arrays.asList(4, 5, 6, 7, 8));\n        \n        // 1. Unión\n        Set<Integer> union = new HashSet<>(conjunto1);\n        union.addAll(conjunto2);\n        System.out.println(\"Unión: \" + union);\n        \n        // 2. Intersección\n        Set<Integer> interseccion = new HashSet<>(conjunto1);\n        interseccion.retainAll(conjunto2);\n        System.out.println(\"Intersección: \" + interseccion);\n        \n        // 3. Diferencia\n        Set<Integer> diferencia = new HashSet<>(conjunto1);\n        diferencia.removeAll(conjunto2);\n        System.out.println(\"Diferencia (conjunto1 - conjunto2): \" + diferencia);\n        \n        // 4. Diferencia simétrica\n        Set<Integer> diferenciaSimetrica = new HashSet<>(conjunto1);\n        diferenciaSimetrica.addAll(conjunto2);           // Unión\n        Set<Integer> temp = new HashSet<>(conjunto1);\n        temp.retainAll(conjunto2);                       // Intersección\n        diferenciaSimetrica.removeAll(temp);             // Unión - Intersección\n        System.out.println(\"Diferencia simétrica: \" + diferenciaSimetrica);\n    }\n}"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/java/martinbohorquez.java",
    "content": "import java.util.*;\n\n/**\n * #18 CONJUNTOS\n *\n * @author martinbohorquez\n */\npublic class martinbohorquez {\n    public static void main(String[] args) {\n        List<Integer> lista = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));\n        System.out.printf(\"La lista mutable: %s%n\", lista);\n        // Añade un elemento al final.\n        lista.add(6);\n        System.out.printf(\"Añadimos un elementos al final de la lista: %s%n\", lista);\n        // Añade un elemento al principio.\n        lista.addFirst(0);\n        System.out.printf(\"Añadimos un elementos al inicio de la lista: %s%n\", lista);\n        // Añade varios elementos en bloque al final.\n        lista.addAll(List.of(7, 8, 9));\n        System.out.printf(\"Añadimos un conjunto de elementos al final de la lista: %s%n\", lista);\n        // Añade varios elementos en bloque en una posición concreta.\n        lista.addAll(4, List.of(31, 32, 33));\n        System.out.printf(\"Añadimos un conjunto de elementos a la lista: %s%n\", lista);\n        // Elimina un elemento en una posición concreta.\n        lista.remove(4);\n        System.out.printf(\"Eliminamos el 5to elemento de la lista: %s%n\", lista);\n        // Actualiza el valor de un elemento en una posición concreta.\n        lista.set(5, 36);\n        System.out.printf(\"Actualizamos el 6to elemento de la lista: %s%n\", lista);\n        // Comprueba si un elemento está en un conjunto.\n        int num = 32;\n        System.out.printf(\"Lista contiene el elemento '%d': %b%n\", num, lista.contains(num));\n        // Eliminar todos los elementos de la lista.\n        lista.clear();\n        System.out.printf(\"Todos los elementos de la lista han sido eliminados: %s%n\", lista);\n\n        /*\n         * DIFICULTAD EXTRA\n         */\n        Set<Integer> lista1 = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5));\n        Set<Integer> lista2 = new HashSet<>(Arrays.asList(7, 6, 5, 4, 3));\n\n        Set<Integer> union = new LinkedHashSet<>(lista1);\n        union.addAll(lista2);\n        System.out.printf(\"La unión de ambas listas es: %s%n\", union);\n\n        Set<Integer> intersection = new LinkedHashSet<>(lista1);\n        intersection.retainAll(lista2);\n        System.out.printf(\"La intersección de ambas listas es: %s%n\", intersection);\n\n        Set<Integer> difference1 = new LinkedHashSet<>(lista1);\n        difference1.removeAll(lista2);\n        System.out.printf(\"La diferencia de lista1 respecto a la lista2 es: %s%n\", difference1);\n\n        Set<Integer> difference2 = new LinkedHashSet<>(lista2);\n        difference2.removeAll(lista1);\n        System.out.printf(\"La diferencia de lista2 respecto a la lista1 es: %s%n\", difference2);\n\n        Set<Integer> symDifference = new LinkedHashSet<>(difference1);\n        symDifference.addAll(difference2);\n        System.out.printf(\"La diferencia simétrica de las listas es: %s%n\", symDifference);\n\n        symDifference = new LinkedHashSet<>(union);\n        symDifference.removeAll(intersection);\n        System.out.printf(\"La diferencia simétrica de las listas es: %s%n\", symDifference);\n\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/java/simonguzman.java",
    "content": "import java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.HashSet;\nimport java.util.Set;\n\npublic class simonguzman {\n    public static void main(String[] args) {\n        testArrayList();\n        extraExercise();\n    }\n    \n    static void testArrayList() {\n        ArrayList<Integer> list = new ArrayList<>();\n\n        addElementFinal(list);\n        addElementInitial(list);        \n\n        System.out.println(\"Contenido de la lista después de añadir elementos al final e inicial: \" + list);\n\n        addElementsFinalBlock(list);\n        addElementsBlockPositionConcrete(list);\n\n        System.out.println(\"Contenido de la lista después de añadir varios elementos al final y en una posición concreta: \" + list);\n\n        deleteElementConcretePosition(list);\n\n        System.out.println(\"Contenido de la lista después de eliminar un elemento en una posición concreta: \" + list);\n\n        updateValueConcretePosition(list);\n\n        System.out.println(\"Contenido de la lista después de actualizar el valor de un elemento en una posición concreta: \" + list);\n\n        containsElement(list);\n\n        System.out.println(\"Contenido de la lista después de comprobar si un elemento está en el conjunto: \" + list);\n\n        deleteAll(list);\n\n        System.out.println(\"Contenido de la lista después de eliminar todo el contenido del conjunto: \" + list);\n    }\n\n    static void addElementFinal(ArrayList<Integer> list){\n        list.add(10);\n    }\n\n    static void addElementInitial(ArrayList<Integer> list){\n        list.add(0, 10);\n    }\n\n    static void addElementsFinalBlock(ArrayList<Integer> list){\n        list.addAll(Arrays.asList(10,20,30));\n    }\n\n    static void addElementsBlockPositionConcrete(ArrayList<Integer> list){\n        list.addAll(0, Arrays.asList(10,20,30));\n    }\n\n    static void deleteElementConcretePosition(ArrayList<Integer> list){\n        list.remove(2);\n    }\n\n    static void updateValueConcretePosition(ArrayList<Integer> list){\n        list.set(2, 40);\n    }\n\n    static void containsElement(ArrayList<Integer> list){\n        boolean containsElem = list.contains(10);\n    }\n\n    static void deleteAll(ArrayList<Integer> list){\n        list.clear();\n    }\n\n    static void extraExercise(){\n        Set<String> setA = new HashSet<>();\n        Set<String> setB = new HashSet<>();\n        createSets(setA, setB);\n        setUnion(setA, setB);\n        setIntersection(setA, setB);\n        setDifference(setA, setB);\n        setSymmetricalDifference(setA, setB);\n    }\n\n    static void createSets(Set<String>setA, Set<String>setB){\n        setA.add(\"A\");\n        setA.add(\"B\");\n        setA.add(\"C\");\n        setB.add(\"B\");\n        setB.add(\"C\");\n        setB.add(\"D\");\n    }\n\n    static void setUnion(Set<String>setA, Set<String>setB){\n        Set<String> union = new HashSet<>(setA);\n        union.addAll(setB);\n        System.out.println(\"Union: \"+union);\n    }\n\n    static void setIntersection(Set<String>setA, Set<String>setB){\n        Set<String> intersection = new HashSet<>(setA);\n        intersection.retainAll(setB);\n        System.out.println(\"Interseccion: \"+intersection); \n    }\n\n    static void setDifference(Set<String>setA, Set<String>setB){\n        Set<String> difference = new HashSet<>(setA);\n        difference.removeAll(setB);\n        System.out.println(\"Diferencia: \"+difference);\n    }\n\n    static void setSymmetricalDifference(Set<String>setA, Set<String>setB){\n        Set<String> symmetricalDifference = new HashSet<>(setA);\n        symmetricalDifference.addAll(setB);\n        Set<String> tmp = new HashSet<>(setA);\n        tmp.retainAll(setB);\n        symmetricalDifference.removeAll(tmp);\n        System.out.println(\"Diferencia simetrica: \"+symmetricalDifference);\n    }\n}\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/java/vandresca.java",
    "content": "import java.util.ArrayList;\nimport java.util.LinkedHashSet;\nimport java.util.List;\nimport java.util.Set;\n\npublic class vandresca {\n    public static void main(String[] args) {\n       \n        //Crear un conjunto de datos\n        Set<String> conjuntoDatos = new LinkedHashSet<>();\n        conjuntoDatos.add(\"B\");\n        conjuntoDatos.add(\"C\");\n        conjuntoDatos.add(\"D\");\n        conjuntoDatos.add(\"E\");\n        conjuntoDatos.add(\"F\");\n\n        System.out.println(\"Conjunto de Datos: \"+conjuntoDatos); \n\n        //Añadir un elemento al final\n        conjuntoDatos.add(\"G\");\n        System.out.println(\"Conjunto de Datos: \"+conjuntoDatos);\n\n        //Añadir un elemento al inicio\n        List<String> aux = new ArrayList<>(conjuntoDatos);\n        aux.add(0, \"A\");\n        conjuntoDatos = new LinkedHashSet<>(aux);\n        System.out.println(\"Conjunto de Datos: \"+conjuntoDatos);\n\n        //Añadir varios elementos en bloque al final\n        Set<String> bloque1 = new LinkedHashSet<>();\n        bloque1.add(\"X\");\n        bloque1.add(\"Y\");\n        bloque1.add(\"Z\");\n\n        conjuntoDatos.addAll(bloque1);\n        System.out.println(\"Conjunto de Datos: \"+conjuntoDatos);\n\n        //Añadir varios elementos en bloque en una posición\n        //Añadimos a partir de la posición 7 despues de 'G'\n        Set<String> bloque2 = new LinkedHashSet<>();\n        bloque2.add(\"O\");\n        bloque2.add(\"P\");\n        bloque2.add(\"Q\");\n\n        aux = new ArrayList<>(conjuntoDatos);\n        aux.addAll(7,bloque2);\n\n        conjuntoDatos = new LinkedHashSet<>(aux);\n        System.out.println(\"Conjunto de Datos: \"+conjuntoDatos);\n       \n        //Eliminar un elemento en una posición concreta\n        //Eliminamos 'D' en la posición 3\n        aux = new ArrayList<>(conjuntoDatos);\n        aux.remove(3);\n        conjuntoDatos = new LinkedHashSet<>(aux);\n        System.out.println(\"Conjunto de Datos: \"+conjuntoDatos);\n\n        //Actualizar 'O' en la posición 6 por 'H'\n        aux = new ArrayList<>(conjuntoDatos);\n        aux.set(6, \"H\");\n        conjuntoDatos = new LinkedHashSet<>(aux);\n        System.out.println(\"Conjunto de Datos: \"+conjuntoDatos);\n\n        //Comprobar si un elemento está en el conunto\n        //Comprobmos si esta 'P'-> Dará true\n        System.out.println(\"Esta P: \"+conjuntoDatos.contains(\"P\"));\n        \n        //Comprobar si esta 'M'-> Dará false\n        System.out.println(\"Esta M: \"+conjuntoDatos.contains(\"M\"));\n   \n        //Eliminar todo el contenido del conjunto\n        conjuntoDatos.clear();\n        System.out.println(\"Conjunto de datos: \" + conjuntoDatos);\n\n\n        //////////////////////////\n        //                      //\n        //   DIFICULTAD EXTRA   //\n        //                      //\n        //////////////////////////\n    \n        Set<String> conjunto1 = new LinkedHashSet<>();\n        conjunto1.add(\"me\");\n        conjunto1.add(\"gustan\");\n        conjunto1.add(\"las\");\n        conjunto1.add(\"croquetas\");\n        Set<String> conjunto2 = new LinkedHashSet<>();\n        conjunto2.add(\"también\");\n        conjunto2.add(\"me\");\n        conjunto2.add(\"molan\");\n        conjunto2.add(\"las\");\n        conjunto2.add(\"paellas\");\n        System.out.println(\"Conjunto1: \"+ conjunto1);\n        System.out.println(\"Conjunto2: \"+conjunto2);\n\n        //Union\n        Set<String> union = new LinkedHashSet<>(conjunto1);\n        union.addAll(conjunto2);\n        System.out.println(\"Unión: \"+union);\n\n        //Intersección\n        Set<String> interseccion = new LinkedHashSet<>(conjunto1);\n        interseccion.retainAll(conjunto2);\n        System.out.println(\"Intersección: \"+interseccion);\n\n        //Diferencia\n        Set<String> difference = new LinkedHashSet<>(conjunto1);\n        difference.removeAll(conjunto2);\n        System.out.println(\"Diferencia: \"+difference);\n\n        //Diferencia simétrica\n        Set<String> difference1Minus2 = new LinkedHashSet<>(conjunto1);\n        difference1Minus2.removeAll(conjunto2);\n        Set<String> difference2Minus1 = new LinkedHashSet<>(conjunto2);\n        difference2Minus1.removeAll(conjunto1);\n        difference1Minus2.addAll(difference2Minus1);\n        System.out.println(\"Diferencia: \"+difference1Minus2);\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/java/worlion.java",
    "content": "/*\n * EJERCICIO: básico (Conjuntos)\n */\n\nimport java.util.HashSet;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.Set;\n\npublic class worlion {\n\n    public static void main(String[] args) {\n\n        playWithLists();\n        dificultadExtra();\n    }\n\n    private static void playWithLists() {\n        log(\"\\nEjercicio básico: \");\n        List<String> myList = new LinkedList<>(List.of(\"b\", \"c\"));\n        log(\"Lista inicial: \" + myList);\n\n        // Añade un elemento al final.\n        myList.add(\"g\");\n        log(\"Añado al final la 'g':\\n\" + myList);\n        // Añade un elemento al principio.\n        myList.add(0, \"a\");\n        log(\"Añado al principio la 'a':\\n\" + myList);\n        // Añade varios elementos en bloque al final.\n        myList.addAll(List.of(\"h\", \"i\"));\n        log(\"Añado al final la 'h' y la 'i':\\n\" + myList);\n        // Añade varios elementos en bloque en una posición concreta.\n        myList.addAll(3, List.of(\"D\", \"e\", \"f\", \"g\"));\n        log(\"Añado en medio las 'D', 'e', 'f' y 'g':\\n\" + myList);\n        // Elimina un elemento en una posición concreta.\n        myList.remove(6);\n        log(\"Elimino el elemento de la posición 6 (la 'g'):\\n\" + myList);\n        // Actualiza el valor de un elemento en una posición concreta.\n        myList.set(3, \"d\");\n        log(\"Modifico el elemento de la posición 3 ('D' por 'd'):\\n\" + myList);\n        // Comprueba si un elemento está en un conjunto.\n        log(\"Compruebo si la 'g' está contenida: --> \" + myList.contains(\"g\"));\n        log(\"Compruebo si la 'z' está contenida: --> \" + myList.contains(\"z\"));\n        // Elimina todo el contenido del conjunto.\n        myList.clear();\n        log(\"Elimino todos los elementos:\\n\" + myList);\n\n    }\n\n    /*\n     * DIFICULTAD EXTRA (opcional):\n     */\n\n\n    private static void dificultadExtra() {\n        log(\"\\nDificultad extra: \");\n        Set<String> set_1 = new HashSet<String>(Set.of(\"a\", \"b\", \"c\"));\n        log(\"Conjunto A: \"+set_1);  \n\n        Set<String> set_2 = new HashSet<String>(Set.of(\"c\", \"e\", \"f\"));\n        log(\"Conjunto A: \"+set_2);  \n\n        // Unión.\n        Set<String> union = new HashSet<String>(set_1);\n        union.addAll(set_2);\n        log(\"Unión: \" + union);  \n\n        // Intersección.\n        Set<String> intersection = new HashSet<String>(set_1);\n        intersection.retainAll(set_2);\n        log(\"Intersección: \" + intersection);  \n\n        // Diferencia.\n        Set<String> difference = new HashSet<String>(set_1);\n        difference.removeAll(set_2);\n        log(\"Diferencia: \" + difference);  \n\n        // Diferencia simétrica.\n        Set<String> simetricDifference = union;\n        simetricDifference.removeAll(intersection);\n        log(\"Intersección: \" + simetricDifference);  \n\n    } \n\n    private static void log(String message) {\n        System.out.println(message);\n    }\n}\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/javascript/7R0N1X.js",
    "content": "let data = [1, 2, 3]\n\ndata.push(4)\nconsole.log(`Añade un elemento al final: ${data}`)\n\ndata.unshift(0)\nconsole.log(`Añade un elemento al principio: ${data}`)\n\ndata = data.concat([5, 6])\nconsole.log(`Añade varios elementos en bloque al final: ${data}`)\n\ndata.splice(0, 0, [-1, -2])\nconsole.log(`Añade varios elementos en bloque en una posición concreta: ${data}`)\n\ndata.splice(1, 1)\nconsole.log(`Elimina un elemento en una posición concreta: ${data}`)\n\ndata[4] = -4\nconsole.log(`Actualiza el valor de un elemento en una posición concreta: ${data}`)\n\nconsole.log(`Comprueba si un elemento está en un conjunto: ${data.includes(0)}`)\n\ndata = []\nconsole.log(`Elimina todo el contenido del conjunto: ${data}`)\n\n\n// DIFICULTAD EXTRA\nconst set1 = new Set([1, 2, 3, 7, 8])\nconst set2 = new Set([1, 2, 3, 4, 5, 6])\n\nconsole.log('---  UNIÓN ---')\nconsole.log(set1.union(set2))\n\nconsole.log('---  INTERSECCIÓN ---')\nconsole.log(set1.intersection(set2))\n\nconsole.log('---  DIFERENCIA ---')\nconsole.log(set1.difference(set2))\n\nconsole.log('---  DIFERENCIA ASIMÉTRICA ---')\nconsole.log(set1.symmetricDifference(set2))\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/javascript/AChapeton.js",
    "content": "const letters = ['a', 'b', 'c', 'd']\nconsole.log('Original', letters)\n// Añade un elemento al final.\nletters.push('e')\nconsole.log('Añade un elemento al final', letters)\n\n// Añade un elemento al principio.\nletters.unshift('-')\nconsole.log('Añade un elemento al principio', letters)\n\n// Añade varios elementos en bloque al final.\nconst newLetters = ['x', 'y', 'z']\nletters.push(...newLetters)\nconsole.log('Añade varios elementos en bloque al final', letters)\n\n// Añade varios elementos en bloque en una posición concreta.\nconst newLetters2 = ['f', 'g', 'h']\nletters.splice(6, 0, ...newLetters2)\nconsole.log('Añade varios elementos en bloque en una posición concreta', letters)\n\n// Elimina un elemento en una posición concreta.\nletters.splice(5, 1)\nconsole.log('Elimina un elemento en una posición concreta', letters)\n\n// Actualiza el valor de un elemento en una posición concreta.\nletters[1] = '#'\nconsole.log('Actualiza el valor de un elemento en una posición concreta', letters)\n\n// Comprueba si un elemento está en un conjunto.\nconst isAinArray = letters.find(letter => letter === 'a' ? true : false)\nconsole.log(' Comprueba si el elemento -a- está en el conjunto letters', isAinArray)\nconst isXinArray = letters.find(letter => letter === 'x' ? true : false)\nconsole.log(' Comprueba si el elemento -x- está en el conjunto letters', isXinArray)\n\n// Elimina todo el contenido del conjunto.\nletters.length = 0\nconsole.log('Elimina todo el contenido del conjunto', letters)\n\n\n// DIFICULTAD EXTRA\n\n// Union de conjuntos\nconst first = [1, 2, 3, 4]\nconst second = [3, 4, 5, 6]\nconst union = new Set()\n\nfirst.forEach(number => union.add(number))\nsecond.forEach(number => union.add(number))\n\nconsole.log('Union', union)\n\n// Interseccion\nconst interseccion = new Set()\nfirst.forEach(n1 => {\n  second.forEach(n2 => {\n    if(n1 === n2){\n      interseccion.add(n1)\n    }\n  })\n})\n\nconsole.log('Interseccion', interseccion)\n\n// Diferencia\nconst diferencia = new Set()\nfirst.forEach(number => diferencia.add(number))\nsecond.forEach(number => {\n  if (diferencia.has(number)){\n    diferencia.delete(number)\n  }\n})\nconsole.log('Diferencia', diferencia)\n\n\n// Diferencia simetrica\nconst simetrica = new Set()\nfirst.forEach(number => simetrica.add(number))\nsecond.forEach(number => {\n  if(simetrica.has(number)){\n    simetrica.delete(number)\n  }else{\n    simetrica.add(number)\n  }\n})\nconsole.log('Diferencia simetrica', simetrica)\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/javascript/ArticKun.js",
    "content": "\n// ⚡ Conjuntos\n\n// Creamos un conjunto de datos inicial\nlet conjuntoDatos = [\"dato1\", \"dato2\", \"dato3\"];\n\n// Añadir un elemento al final\nconjuntoDatos.push(\"dato4\");\n\n// Añadir un elemento al principio\nconjuntoDatos.unshift(\"dato0\");\n\n// Añadir varios elementos en bloque al final\nconjuntoDatos = conjuntoDatos.concat([\"dato5\", \"dato6\"]);\n\n// Añadir varios elementos en bloque en una posición concreta\nconjuntoDatos.splice(3, 0, \"datoA\", \"datoB\");\n\n// Eliminar un elemento en una posición concreta\nconjuntoDatos.splice(2, 1);\n\n// Actualizar el valor de un elemento en una posición concreta\nconjuntoDatos[1] = \"datoX\";\n\n// Comprobar si un elemento está en el conjunto\nconst elementoBuscado = \"datoX\";\nconst estaEnConjunto = conjuntoDatos.includes(elementoBuscado);\n\n// Eliminar todo el contenido del conjunto\nconjuntoDatos = [];\n\n/*\n\nDIFICULTAD EXTRA (opcional):\n\n  Muestra ejemplos de las siguientes operaciones con conjuntos:\n  - Unión.\n  - Intersección.\n  - Diferencia.\n  - Diferencia simétrica.\n\n*/\n\n// Union\nconst conjuntoA = new Set([1, 2, 3]);\nconst conjuntoB = new Set([3, 4, 5]);\n// Unión de conjuntoA y conjuntoB\nconst union = new Set( [...conjuntoA, ...conjuntoB] );\nconsole.log(\"Unión:\", union); // Output: Set { 1, 2, 3, 4, 5 }\n\n\n// Intersección\nconst conjuntoC = new Set([1, 2, 3]);\nconst conjuntoD = new Set([3, 4, 5]);\n// Intersección de conjuntoC y conjuntoD\nconst interseccion = new Set( [...conjuntoC].filter(x => conjuntoD.has(x)) );\nconsole.log(\"Intersección:\", interseccion); // Output: Set { 3 }\n\n\n// Diferencia\nconst conjuntoE = new Set( [1, 2, 3] );\nconst conjuntoF = new Set( [3, 4, 5] );\n// Diferencia de conjuntoE y conjuntoF\nconst diferencia = new Set( [...conjuntoE].filter(x => !conjuntoF.has(x)) );\nconsole.log(\"Diferencia:\", diferencia); // Output: Set { 1, 2 }\n\n\n// Diferencia simétrica\nconst conjuntoG = new Set([1, 2, 3]);\nconst conjuntoH = new Set([3, 4, 5]);\n// Diferencia simétrica (G - H) U (H - G)\nconst diferenciaSimetrica = new Set([\n  ...[...conjuntoG].filter(x => !conjuntoH.has(x)),\n  ...[...conjuntoH].filter(x => !conjuntoG.has(x))\n]);\nconsole.log(\"Diferencia Simétrica:\", diferenciaSimetrica); // Output: Set { 1, 2, 4, 5 }\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/javascript/DavidMoralesDeveloper.js",
    "content": "// array -----\nconst arr = [1,2,3,4,5,6,7,8,9,10]\n// * - Añade un elemento al final.\narr. push(11)//11\nconsole.log(arr)\n// Añade un elemento al principio.\narr.shift()//1 delete\nconsole.log(arr)\n// Añade varios elementos en bloque al final.\narr.push(12, 13, 14) //agrego al final\nconsole.log(arr)\n// Añade varios elementos en bloque en una posición concreta.\narr.splice(0,0,-2,-1,0) //agrego en la posicion 0\nconsole.log(arr)\n// Elimina un elemento en una posición concreta.\narr.splice(8,1) //7 delete\nconsole.log(arr)\n// Actualiza el valor de un elemento en una posición concreta.\narr[5] = 10 \nconsole.log(arr) \narr.splice(0,0,-3)\nconsole.log(arr)\n// Comprueba si un elemento está en un conjunto = Comprobar si un elemento existe\nconsole.log(arr.includes(10))\n// - Elimina todo el contenido del conjunto.\narr.splice(0, arr.length);\nconsole.log(arr)\n\n// Extra\n\n// * Muestra ejemplos de las siguientes operaciones con conjuntos:\n// * - Unión.\nconst num1 = [1, 2, 3, 4, 5]\nconst num2 = [1, 2, 3, 4, 6, 7]\n\nfunction union ( arr, arr2) {\nlet resultado = [...arr] //[1, 2, 3, 4, 5]\n    for (const iterator of arr2) { // iteracion = [1[0], 2[1], 3[2], 4[3], 6[4], 7[5]]\n        if(!resultado.includes(iterator) ){ //cuando includes sea false entonces agrega el numero\n            resultado.push(iterator)\n        }\n        \n    }\n    return resultado\n}\nconsole.log(union(num1, num2))\n\n// Intersección.\n// La intersección de dos conjuntos (o arreglos) consiste en obtener un nuevo conjunto (o arreglo) que contenga solo los elementos que están presentes en ambos conjuntos (o arreglos) de entrada.\nfunction interseccion (arr, arr2){\nlet resultado = []\nfor (const iterator of arr) {\n    if(arr2.includes(iterator)){ // cuando includes sea true , agrega al []\n        resultado.push(iterator)\n    }\n}\nreturn resultado\n}\n\nconsole.log(interseccion(num1, num2))\n\n// Diferencia \n// La diferencia de dos conjuntos (o arreglos) consiste en obtener un nuevo conjunto (o arreglo) que contenga los elementos que están presentes en el primer conjunto (o arreglo) pero no en el segundo.\n\nfunction diferencia(arr, arr2) {\nlet resultado = []\nfor (const iterator of arr) {\n    if(!arr2.includes(iterator)){ //false \n        resultado.push(iterator)\n    }\n}\n    return resultado\n}\n\nconsole.log(diferencia(num1, num2))\nconsole.log(diferencia(num2, num1))\n\n// Diferencia simétrica.\n//recorro el primer arr\nfunction diferenciaSim (arr ,arr2) {\nlet resultado = []\nfor (const iterator of arr) {\n    if(!arr2.includes(iterator)){ //false\n        resultado.push(iterator)\n    }\n}\n//recorre el segundo arr\nfor (const iterator of arr2) {\n    if(!arr.includes(iterator)){//false\n        resultado.push(iterator)\n    }\n}\nreturn resultado\n}\n\nconsole.log(diferenciaSim(num1, num2))"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/javascript/Deyvid-10.js",
    "content": "// Conjuntos\n\nfunction agregarInicio(set, valor)\n{\n    let nuevoConjunto = new Set()\n    nuevoConjunto.add(valor)\n\n    for (let s of set) {\n        nuevoConjunto.add(s)\n    }\n\n    return nuevoConjunto\n}\n\nfunction agregarVariosFinal(set, valores)\n{\n    for (let v of valores) {\n        set.add(v)\n    }\n}\n\nfunction agregarVariosPosicion(set, posicion, valores)\n{\n    let cont = -1\n    let nuevoConjunto = new Set()\n    \n    for (let s of set) {\n        cont ++\n        \n        if(cont == posicion)\n        {\n            for (let v of valores) \n            {\n                nuevoConjunto.add(v)\n            }\n        }\n\n        nuevoConjunto.add(s)\n    }\n\n    if(posicion > cont)\n    {\n        console.log(\"Esta posicion no existe\");\n    }\n\n    return nuevoConjunto\n}\n\nfunction eliminar(set, posicion)\n{\n    let cont = -1\n    \n    for (let s of set) {\n        cont ++\n        \n        if(cont == posicion)\n        {\n            set.delete(s)\n        }\n    }\n}\n\nfunction actualizar(set, posicion, valor)\n{\n    let cont = -1\n    let nuevoConjunto = new Set()\n\n    for (let s of set) {\n        cont ++\n        \n        if(cont == posicion)\n        {\n            nuevoConjunto.add(valor)\n        }\n        else\n        {\n            nuevoConjunto.add(s)\n        }\n    }\n\n    if(posicion > cont)\n    {\n        console.log(\"Esta posicion no existe\");\n    }\n\n    return nuevoConjunto\n}\n\nlet conjunto = new Set() // Crear el conjunto\n\nconjunto.add(1) // Agregar al final del conjunto\nconjunto.add(2) // Agregar al final del conjunto\nconjunto.add(3) // Agregar al final del conjunto\nconsole.log(conjunto);\n\nconjunto = agregarInicio(conjunto, 0) // Agregar al inicio del conjunto\nconsole.log(conjunto);\n\nagregarVariosFinal(conjunto, [5, 6, 7]) // Agregar varios elementos al final\nconsole.log(conjunto);\n\nconjunto = agregarVariosPosicion(conjunto, 2, [8, 9, 10]) // Agregar varios elementos en una posicion concreta\nconsole.log(conjunto);\n\neliminar(conjunto, 2) // Eliminar un elemento en una posición concreta\nconsole.log(conjunto);\n\nconjunto = actualizar(conjunto, 2, 11) // Actualiza el valor de un elemento en una posición concreta\nconsole.log(conjunto);\n\nconsole.log(`La comprobacion del elemnto es: ${conjunto.has(2)}`); // Comprueba si un elemento está en un conjunto.\n\nconjunto.clear() // Eliminar todos los elementos\nconsole.log(conjunto);\n\n\n// DIFICULTAD EXTRA\n\nlet conjuntoA = new Set([1, 2, 3, 10, 12])\nlet conjuntoB = new Set([4, 5, 6, 10, 12])\n\n// Union\nlet unionConjunto = new Set([...conjuntoA, ...conjuntoB])\nconsole.log(unionConjunto);\n\n// Intersección\nlet intersecciónConjunto = new Set([...conjuntoA].filter(elemento => conjuntoB.has(elemento)))\nconsole.log(intersecciónConjunto);\n\n// Diferencia \nlet diferenciaConjunto = new Set([...conjuntoA].filter(elemento => !(conjuntoB.has(elemento))))\nconsole.log(diferenciaConjunto);\n\n// Diferencia simétrica\nlet simetricaConjunto = new Set([...conjuntoA, ...conjuntoB].filter(elemento => !(conjuntoB.has(elemento)) || !(conjuntoA.has(elemento))))\nconsole.log(simetricaConjunto);\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #18 - JavaScript ->Jesus Antonio Escamilla */\n\n/**\n * Verduras sera mis datos para utilizar\n */\n\n//---EJERCIÓ---\n// El conjunto de datos\nlet list = ['Apio', 'Brocoli', 'Maíz', 'Lechuga'];\n\n// Añade un elemento al final\nlist.push('Rábano');\nconsole.log('Agregando un elemento al final', list);\n\n// Añade un elemento al principio\nlist.unshift('Zanahoria');\nconsole.log('Agregando un elemento al inicio', list);\n\n// Añade un bloque de elementos al final\nconst blockList = ['Champion', 'Cebolla', 'Pimiento'];\nlist.push(...blockList);\nconsole.log('Agregando un bloque de elementos a la lista', list);\n\n// Añade un bloque de elementos al alguna parte de lista\nconst block_medList = ['Esparrago', 'Calzaba', 'Papa'];\nlist.splice(3, 0, ...block_medList);\nconsole.log('Agregando un bloque de elementos a la lista en especifico', list);\n\n// Eliminando un elemento de la lista\nlist.splice(9, 1);\nconsole.log('Eliminando un elemento a la lista en especifico', list);\n\n// Comprobando un elemento esta en un conjunto de la lista\nlet elementList = list.includes('Zanahoria');\nconsole.log('Se encuentra el elemento:', elementList);\n\n// Se elimina toda la lista\nlist = [];\nconsole.log('Se elimino la lista', list);\n\n\n\n/**-----DIFICULTAD EXTRA-----*/\n\n// Ejemplos de conjuntos\nconst conjuntoA = new Set(['a', 'b', 'c', 'd', 'e']);\nconst conjuntoB = new Set(['d', 'e', 'f', 'g', 'h']);\n\n//  UNION A U B\nlet union = new Set([...conjuntoA, ...conjuntoB]);\nconsole.log('La union entre las letras de conjuntos A y B', union);\n\n//  INTERSECCIÓN A n B\nlet intersección = new Set([...conjuntoA].filter(x => conjuntoB.has(x)));\nconsole.log('Se encontró las mismas letras en los conjuntos A y B',intersección);\n\n//  DIFERENCIA A - B\nlet diferenciaA = new Set([...conjuntoA].filter(x => !conjuntoB.has(x)));\nconsole.log('Se encontró las siguientes diferencias en los conjuntos A y B',diferenciaA);\nlet diferenciaB = new Set([...conjuntoB].filter(x => !conjuntoA.has(x)));\nconsole.log('Se encontró las siguientes diferencias en los conjuntos B y A',diferenciaB);\n\n//  DIFERENCIA SIMETRÍA A ^ B\nlet diferenciaSimétrica = new Set([...conjuntoA].filter(x => !conjuntoB.has(x)).concat([...conjuntoB].filter(x => !conjuntoA.has(x))));\nconsole.log('Se encontraron los valores no repetidos en los conjuntos A y B',diferenciaSimétrica);\n\n/**-----DIFICULTAD EXTRA-----*/"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/javascript/RaulDoezon.js",
    "content": "/*\n  EJERCICIO:\n  Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n  operaciones (debes utilizar una estructura que las soporte):\n  - Añade un elemento al final.\n  - Añade un elemento al principio.\n  - Añade varios elementos en bloque al final.\n  - Añade varios elementos en bloque en una posición concreta.\n  - Elimina un elemento en una posición concreta.\n  - Actualiza el valor de un elemento en una posición concreta.\n  - Comprueba si un elemento está en un conjunto.\n  - Elimina todo el contenido del conjunto.\n*/\n\nconst marvelCharacters = [\"Spider-Man\", \"Hawkeye\", \"Hulk\"];\nconsole.log('Arreglo inicial:', marvelCharacters);\nmarvelCharacters.push(\"Captain America\");\nconsole.log(\"Se agregó un elemento al final:\", marvelCharacters);\nmarvelCharacters.unshift(\"Firestar\");\nconsole.log('Se agregó un elemento al principio:', marvelCharacters);\nmarvelCharacters.push(\"Iron Man\", \"Ant-Man\");\nconsole.log(\"Se agregaron varios elementos al final\", marvelCharacters);\nmarvelCharacters.splice(5, 0, \"Wolverine\", \"Thor\");\nconsole.log('Se agregaron 3 elementos en el índice 5:', marvelCharacters);\nmarvelCharacters.splice(6, 1);\nconsole.log(\"Se eliminó el elemento del índice 6:\", marvelCharacters);\nmarvelCharacters.splice(2, 1, \"Iceman\");\nconsole.log(\"Se actualizó el elemento del índice 2:\", marvelCharacters);\nconsole.log(\"Se comprueba si existe el elemento Spider-Man:\", marvelCharacters.includes(\"Spider-Man\"));\nmarvelCharacters.splice(0, marvelCharacters.length);\nconsole.log(\"Todo el contenido del arreglo se eliminó:\", marvelCharacters);\n\n/*\n  DIFICULTAD EXTRA (opcional):\n  Muestra ejemplos de las siguientes operaciones con conjuntos:\n  - Unión.\n  - Intersección.\n  - Diferencia.\n  - Diferencia simétrica.\n*/\n\nconsole.log(\"\\n+++++++++ CONJUNTOS +++++++++\");\n\nlet bountyHunters1 = new Set([\"Gandrayda\", \"Samus\", \"Weavel\", \"Kanden\", \"Spire\", \"Noxus\"]);\nlet bountyHunters2 = new Set([\"Rundas\", \"Ghor\", \"Kanden\", \"Spire\", \"Gandrayda\", \"Sylux\"]);\nconsole.log(bountyHunters1);\nconsole.log(bountyHunters2);\n\nconsole.log(\"\\nUNIÓN\");\nlet union = new Set([...bountyHunters1, ...bountyHunters2]);\nconsole.log(union);\n\nconsole.log(\"\\nINTERSECCIÓN\");\nlet intersection = new Set([...bountyHunters1].filter((equal) => bountyHunters2.has(equal)));\nconsole.log(intersection);\n\nconsole.log(\"\\nDIFERENCIA\");\nlet difference1 = new Set([...bountyHunters1].filter((different1) => !bountyHunters2.has(different1)));\nlet difference2 = new Set([...bountyHunters2].filter((difference2) => !bountyHunters1.has(difference2)));\n\nconsole.log(\"Diferencia del Conjunto 1\", difference1);\nconsole.log(\"Diferencia del Conjunto 2\", difference2);\n\n\nconsole.log(\"\\nDIFERENCIA SIMÉTRICA\");\nlet symmetricDifference = new Set([...union].filter((symmetric) => !intersection.has(symmetric)));\nconsole.log(symmetricDifference);\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/javascript/RicJDev.js",
    "content": "//EJERCICIO\nconst elements = [1, 2, 3, 4];\nconsole.log('\\nElemento original: ', elements);\n\nelements.push(5);\nconsole.log('\\nAñadiendo un elemento al final: ', elements);\n\nelements.unshift(0);\nconsole.log('\\nAñadiendo un elemento al principio: ', elements);\n\nlet newElements = [6, 7, 8];\nelements.push(...newElements);\nconsole.log('\\nAñadiendo varios elementos en bloque al final: ', elements);\n\nnewElements = [-3, -2, -1];\nelements.unshift(...newElements);\nconsole.log('\\nAñadiendo varios elementos en bloque al principio: ', elements);\n\nelements.splice(7, 1);\nconsole.log('\\nEliminando un elemento en una posición concreta: ', elements);\n\nelements[5] = 34;\nconsole.log('\\nActualizando un elemento en una posición concreta: ', elements);\n\nconsole.log(\n\t`\\nComprobando si un elemento está en el conjunto: ${elements.includes(12)}`\n);\nconsole.log(\n\t`\\nComprobando si un elemento está en el conjunto: ${elements.includes(8)}`\n);\n\nelements.length = 0;\nconsole.log('\\nEliminando todos los elementos: ', elements);\n\n//EXTRA\nconst letters1 = new Set(['a', 'b', 'c']);\nconst letters2 = new Set(['b', 'd', 'e', 'f']);\n\nconst united = new Set([...letters1, ...letters2]);\nconsole.log('\\nUnión:', united);\n\nconst intersection = new Set(\n\t[...letters1].filter((element) => letters2.has(element))\n);\nconsole.log('\\nIntersección:', intersection);\n\nconst diference1 = new Set(\n\t[...letters1].filter((element) => !letters2.has(element))\n);\nconsole.log('\\nDiferencia:', diference1);\n\nconst diference2 = new Set(\n\t[...letters2].filter((element) => !letters1.has(element))\n);\nconsole.log('\\nDiferencia:', diference2);\n\nconsole.log('\\nDiferencia simétrica:', new Set([...diference1, ...diference2]));\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/javascript/Sac-Corts.js",
    "content": "let set = [];\nset.push(10);\nset.unshift(1);\nset.push(11, 12);\nset.splice(1, 0, 2, 3);\nset.splice(2, 1);\nset[2] = 5;\nlet elementExist = set.includes(3);\nconsole.log(elementExist);\nconsole.log(set);\nset = [];\nconsole.log(set);\n\n// Extra Exercise //\nconst setA = new Set([1, 2, 3]);\nconst setB = new Set([3, 4, 5]);\n\n// Union\nconst union = new Set([...setA, ...setB]);\nconsole.log(union);\n\n// Intersection\nconst intersection = new Set([...setA].filter(x => setB.has(x)));\nconsole.log(intersection);\n\n// Difference\nconst difference = new Set([...setA].filter(x => !setB.has(x)));\nconsole.log(difference);\n\n// Symmetric Difference\nconst symmetricDifference = new Set([\n    ...[...setA].filter(x => !setB.has(x)), \n    ...[...setB].filter(x => !setA.has(x))\n]);\nconsole.log(symmetricDifference);"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/javascript/adrs1166ma.js",
    "content": "/* 🔥 EJERCICIO:\nUtilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\noperaciones (debes utilizar una estructura que las soporte):\n- 1. Añade un elemento al final.\n- 2. Añade un elemento al principio.\n- 3. Añade varios elementos en bloque al final.\n- 4. Añade varios elementos en bloque en una posición concreta.\n- 5. Elimina un elemento en una posición concreta.\n- 6. Actualiza el valor de un elemento en una posición concreta.\n- 7. Comprueba si un elemento está en un conjunto.\n- 8. Elimina todo el contenido del conjunto.\n*/\nlet conjunto = [1, 2, 3, 4, 5];\nconsole.log(\"Conjunto inicial:\", conjunto);\n\n// 1. Añade un elemento al final.\nconjunto.push(6);\nconsole.log(\"Añadir un elemento al final:\", conjunto);\n\n// 2. Añade un elemento al principio.\nconjunto.unshift(0);\nconsole.log(\"Añadir un elemento al principio:\", conjunto);\n\n// 3. Añade varios elementos en bloque al final.\nconjunto.push(7, 8, 9);\nconsole.log(\"Añadir varios elementos en bloque al final:\", conjunto);\n\n// 4. Añade varios elementos en bloque en una posición concreta\nconst nuevosElementos = [10, 11];\nconst posicion = 3; // Posición donde insertar los nuevos elementos\nconjunto.splice(posicion, 0, ...nuevosElementos);\nconsole.log(\"Añadir varios elementos en bloque en una posición concreta:\", conjunto);\n\n// 5. Elimina un elemento en una posición concreta.\nconst posicionEliminar = 5;\nconjunto.splice(posicionEliminar, 1);\nconsole.log(\"Eliminar un elemento en una posición concreta:\", conjunto);\n\n// 6. Actualiza el valor de un elemento en una posición concreta.\nconst posicionActualizar = 4;\nconjunto[posicionActualizar] = 99;\nconsole.log(\"Actualizar el valor de un elemento en una posición concreta:\", conjunto);\n\n// 7. Comprueba si un elemento está en un conjunto.\nconst elementoBuscar = 99;\nconst existe = conjunto.includes(elementoBuscar);\nconsole.log(`¿El elemento ${elementoBuscar} está en el conjunto?:`, existe);\n\n// 8. Elimina todo el contenido del conjunto.\nconjunto = [];\nconsole.log(\"Eliminar todo el contenido del conjunto:\", conjunto);\n\n\n/* 🔥 DIFICULTAD EXTRA (opcional): ----------------------------------------------------------------------\nMuestra ejemplos de las siguientes operaciones con conjuntos:\n- 1. Unión.\n- 2. Intersección.\n- 3. Diferencia.\n- 4. Diferencia simétrica.\n */\n// Conjuntos iniciales\nconst conjuntoA = new Set([1, 2, 3, 4, 5]);\nconst conjuntoB = new Set([4, 5, 6, 7, 8]);\n\n// 1. Unión\nconst union = new Set([...conjuntoA, ...conjuntoB]);\nconsole.log(\"Unión:\", [...union]);\n\n// 2. Intersección\nconst interseccion = new Set([...conjuntoA].filter((x) => conjuntoB.has(x)));\nconsole.log(\"Intersección:\", [...interseccion]);\n\n// 3. Diferencia (A - B)\nconst diferencia = new Set([...conjuntoA].filter((x) => !conjuntoB.has(x)));\nconsole.log(\"Diferencia (A - B):\", [...diferencia]);\n\n// 4. Diferencia simétrica\nconst diferenciaSimetrica = new Set(\n    [...conjuntoA].filter((x) => !conjuntoB.has(x)).concat(\n        [...conjuntoB].filter((x) => !conjuntoA.has(x))\n    )\n);\nconsole.log(\"Diferencia simétrica:\", [...diferenciaSimetrica]);"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/javascript/agusrosero.js",
    "content": "/*\n * EJERCICIO:\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n * operaciones (debes utilizar una estructura que las soporte):\n * - Añade un elemento al final.\n * - Añade un elemento al principio.\n * - Añade varios elementos en bloque al final.\n * - Añade varios elementos en bloque en una posición concreta.\n * - Elimina un elemento en una posición concreta.\n * - Actualiza el valor de un elemento en una posición concreta.\n * - Comprueba si un elemento está en un conjunto.\n * - Elimina todo el contenido del conjunto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Unión.\n * - Intersección.\n * - Diferencia.\n * - Diferencia simétrica.\n */\nconst mySet = new Set();\n\n// Añade un elemento\nmySet.add(1);\nmySet.add(2);\nmySet.add(3);\n// Añade varios elementos en bloque al final.\nmySet.add([4, 5, 6]);\n// Elimina un elemento en una posición concreta.\nmySet.delete(3);\n// Comprueba si un elemento está en un conjunto.\nconsole.log(mySet.has(2));\nconsole.log(mySet);\n\n// DIFICULTAD EXTRA:\n// Unión\nconjunto1 = new Set([1, 2, 3, 4]);\nconjunto2 = new Set([5, 6, 7, 8]);\nconst union = [...new Set([...conjunto1, ...conjunto2])];\nconsole.log(union);\n\n// Intersección\nconst firstSet = new Set([1, 2, 3, 4, 5]);\nconst secondSet = new Set([4, 5, 6, 7, 8]);\nconst commonElements = [...firstSet].filter((element) =>\n  secondSet.has(element)\n);\nconst set = new Set(commonElements);\nconsole.log(set);\n\n// Diferencia\nconst firstSet2 = new Set([1, 2, 3, 4, 5]);\nconst secondSet2 = new Set([4, 5, 6, 7, 8]);\n\nconst diffElements = [...firstSet2].filter(\n  (element) => !secondSet2.has(element)\n);\nconst set2 = new Set(diffElements);\nconsole.log(set2);\n\n// Diferencia simétrica\nconst firstSet3 = new Set([1, 2, 3, 4, 5]);\nconst secondSet3 = new Set([4, 5, 6, 7, 8]);\n\nconst firstOnlyElements = [...firstSet3].filter(\n  (element) => !secondSet3.has(element)\n);\nconst secondOnlyElements = [...secondSet3].filter(\n  (element) => !firstSet3.has(element)\n);\nconst set3 = new Set([...firstOnlyElements, ...secondOnlyElements]);\nconsole.log(set3);\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/javascript/bernatcs.js",
    "content": "// ** EJERCICIO \n\nlet conjuntoDeDatos = ['dato1', 'dato2', 'dato3']\nconjuntoDeDatos.push('dato4') // Añade elemento al final\nconjuntoDeDatos.unshift('dato0') // Añade elemento al principio\nconjuntoDeDatos.push('dato5', 'dato6') // Añade varios elementos al final\nconjuntoDeDatos.splice(2, 0, 'dato1.3', 'dato1.6') // Añade varios elementos en un sitio en concreto\nconjuntoDeDatos.splice(2, 2) // Elimina elementos desde una posición dada\nconjuntoDeDatos.pop() // Elimina elemento al final\nconjuntoDeDatos.shift() // Elimina elemento al principio\nconjuntoDeDatos[1] = 'datoDos' // Actualiza el valor de un elemento en una posición concreta\nconjuntoDeDatos.includes('dato1') // Comprueba si en elemento está en un conjunto (True)\nconjuntoDeDatos.indexOf('dato1') // Devuelve el índice del primer elemento coincidente\nconjuntoDeDatos = [] // Elimina todo el contenido\n\n// ** DIFICULTAD EXTRA ** -------------------------------------------------------------------------------------------------------------------------------------------------\n\nlet conjuntoDatos1 = ['dato1', 'dato2', 'dato3', 'datoRepe', 'datoRepe2']\nlet conjuntoDatos2 = ['dato4', 'dato5', 'dato6', 'datoRepe', 'datoRepe2']\n\n// Unión\n\nconsole.log(conjuntoDatos1.concat(conjuntoDatos2)) \n\n// Intersección\n\nlet interseccion = []\n\nconjuntoDatos1.forEach(element => {\n    if (conjuntoDatos2.includes(element)) {\n        interseccion.push(element)\n    }\n});\n\ninterseccion\n\n\n// Diferencia\n\nlet diferencia = []\n\nconjuntoDatos1.forEach(element => {\n    if (!conjuntoDatos2.includes(element)) {\n        diferencia.push(element)\n    }\n});\n\ndiferencia\n\n// Diferencia simétrica\n\nlet diferenciaSim = []\n\nconjuntoDatos1.forEach(element => {\n    if (!conjuntoDatos2.includes(element)) {\n        diferenciaSim.push(element)\n    }\n});\n\nconjuntoDatos2.forEach(element => {\n    if (!conjuntoDatos1.includes(element)) {\n        diferenciaSim.push(element)\n    }\n});\n\ndiferenciaSim"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/javascript/caterinarodriguezdev.js",
    "content": "/*\n * EJERCICIO:\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n * operaciones (debes utilizar una estructura que las soporte):\n * - Añade un elemento al final.\n * - Añade un elemento al principio.\n * - Añade varios elementos en bloque al final.\n * - Añade varios elementos en bloque en una posición concreta.\n * - Elimina un elemento en una posición concreta.\n * - Actualiza el valor de un elemento en una posición concreta.\n * - Comprueba si un elemento está en un conjunto.\n * - Elimina todo el contenido del conjunto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Unión.\n * - Intersección.\n * - Diferencia.\n * - Diferencia simétrica.\n */\n\nlet arr = [1, 2, 3];\nconsole.log(\"Conjunto de datos original\", arr);\narr.push(4);\nconsole.log(\"Añadir un elemento al final -> push(4)\", arr);\n\narr.unshift(0);\nconsole.log(\"Añadir un elemento al principio\", arr);\n\narr.push(5, 6, 7);\nconsole.log(\"Añadir varios elementos en bloque al final\", arr);\n\narr.splice(3, 0, 2.5, 2.7);\nconsole.log(\n  \"Añadir varios elementos en una posición concreta. Posición 3\",\n  arr\n);\n\narr.splice(2, 1);\nconsole.log(\"Eliminar un elemento de una posición concreta. Posición 2\", arr);\n\nconsole.log(\n  arr.includes(2) ? \"El 2 está en el conjunto\" : \"El 2 no está en el conjunto\"\n);\nconsole.log(\n  arr.includes(3) ? \"El 3 está en el conjunto\" : \"El 3 no está en el conjunto\"\n);\n\narr.splice(0, arr.length);\nconsole.log(\"Eliminar los datos del conjunto\", arr);\n\nconsole.log(\"------------------DIFICULTAD EXTRA-----------------\");\n\nlet arr1 = [0, 1, 2];\nlet arr2 = [3, 4, 5];\nlet arr3 = [1, 3, 7];\n\nconsole.log(\"UNIÓN\");\nconsole.log(\n  `La unión de ${arr1} y ${arr2} es ${arr1.toSpliced(arr1.length, 0, arr2)}`\n);\n\nconsole.log(\"INTERSECCIÓN\");\nlet interseccion = arr1.filter((el) => arr3.includes(el));\nconsole.log(`La intersección de ${arr1} y ${arr3} es ${interseccion}`);\n\nconsole.log(\"DIFERENCIA\");\nconsole.log(\n  `La diferencia de arr1: ${arr1} respecto a arr3: ${arr3} es ${arr1.filter(\n    (el) => !arr3.includes(el)\n  )}`\n);\n\nconsole.log(\"DIFERENCIA SIMÉTRICA\");\nconsole.log(\n  `La diferencia simétrica entre arr1 y arr3 es ${[\n    arr1.filter((el) => !arr3.includes(el)),\n    arr3.filter((el) => !arr1.includes(el)),\n  ]}`\n);\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/javascript/cesar-ch.js",
    "content": "/*\n    * #18 CONJUNTOS \n*/\n\nlet conjunto = new Set()\n\n// añade un elemento\nconjunto.add(\"elemento 1\")\n\n// añade un elemento al inicio\nconst array = Array.from(conjunto)\narray.splice(0, 0, \"elemento 0\")\nconjunto = new Set(array)\n\n// añade varios elementos en bloque al final\nconjunto.add(\"elemento 2\")\nconjunto.add(\"elemento 3\")\n\n// añade varios elementos en bloque en una posicion concreta\nconst array2 = Array.from(conjunto)\narray2.splice(1, 0, \"elemento 0.25\", \"elemento 0.5\", \"elemento 0.75\")\nconjunto = new Set(array2)\n\n// elimina un elemento en la posicion concreta\nconst posicion = Array.from(conjunto).indexOf(\"elemento 0.25\")\nconjunto.delete(Array.from(conjunto)[posicion])\n\n// actualiza el valor de un elemento en una pocicion concreta\nconst array3 = Array.from(conjunto)\nconst posicion2 = array3.indexOf(\"elemento 0.5\")\narray3[posicion2] = \"elemento 0.4\"\nconjunto = new Set(array3)\n\n// comprueba si un elemento existe\nconsole.log(conjunto.has(\"elemento 1\"))\n\n// elimina todo el contenido del conjunto\nconjunto.clear()\n\nconsole.log(conjunto)\n\n/*\n    * DIFICULTAD EXTRA \n*/\n\n// UNION\nconst conjuntoA = new Set([\"a\", \"b\", \"c\"]);\nconst conjuntoB = new Set([\"b\", \"c\", \"d\"]);\nconst union = new Set([...conjuntoA, ...conjuntoB]);\nconsole.log(union);\n\n// INTERSECCION\n\nconst interseccion = new Set([...conjuntoA].filter(x => conjuntoB.has(x)));\nconsole.log(interseccion);\n\n// DIFERENCIA\n\nconst diferencia = new Set([...conjuntoA].filter(x => !conjuntoB.has(x)));\nconsole.log(diferencia);\n\n// DIFERENCIA SIMETRICA\n\nconst diferencia2 = new Set([...conjuntoB].filter(x => !conjuntoA.has(x)));\nconst diferenciaSimetrica = new Set([...diferencia, ...diferencia2]);\n\nconsole.log(diferenciaSimetrica);"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/javascript/christian-jfr.js",
    "content": "// #18 CONJUNTOS\n\n/**\n * EJERCICIO:\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n * operaciones (debes utilizar una estructura que las soporte):\n */\n\nlet colorSet = ['#0099ff', '#00ff99'];\nconsole.log(colorSet); // [ '#0099ff', '#00ff99' ]\n\n// * Añade un elemento al final.\ncolorSet.push('#99ff00');\nconsole.log(colorSet); // [ '#0099ff', '#00ff99', '#99ff00' ]\n\n// * Añade un elemento al principio.\ncolorSet.unshift('#9900ff');\nconsole.log(colorSet); // [ '#9900ff', '#0099ff', '#00ff99', '#99ff00' ]\n\n// * Añade varios elementos en bloque al final.\nlet colorSet2 = ['#ff0099', '#ff9900'];\ncolorSet.push(...colorSet2);\nconsole.log(colorSet); // [ '#9900ff', '#0099ff', '#00ff99', '#99ff00', '#ff0099', '#ff9900' ]\n\n// * Añade varios elementos en bloque en una posición concreta.\nlet colorSet3 = ['#ffaaff', '#aaffff'];\ncolorSet.splice(1, 0, ...colorSet3);\nconsole.log(colorSet); // [ '#9900ff', '#ffaaff', '#aaffff', '#0099ff', '#00ff99', '#99ff00', '#ff0099', '#ff9900' ]\n\n// * Elimina un elemento en una posición concreta.\ncolorSet.splice(3, 1);\nconsole.log(colorSet); // [ '#9900ff', '#ffaaff', '#aaffff', '#00ff99', '#99ff00', '#ff0099', '#ff9900' ]\n\n// * Actualiza el valor de un elemento en una posición concreta.\ncolorSet[0] = '#ffffaa';\nconsole.log(colorSet); // [ '#ffffaa', '#ffaaff', '#aaffff', '#00ff99', '#99ff00', '#ff0099', '#ff9900' ]\n\n// * Comprueba si un elemento está en un conjunto.\nconsole.log(colorSet.includes('#ffffaa')); // true\nconsole.log(colorSet.includes('#000000')); // false\n\n// * Elimina todo el contenido del conjunto.\nconjuntoDatos.length = 0;\n\n/**\n * DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n */\n\n// * Unión.\nconst setOne = new Set([1, 2, 3, 5, 8, 13]);\nconst setTwo = new Set([1, 2, 2, 4, 8, 32]);\nconst union = setOne.union(setTwo);\nconsole.log(union); // -> Set(8) { 1, 2, 3, 5, 8, 13, 4, 32 }\n\n// * Intersección.\nconst intersection = setOne.intersection(setTwo);\nconsole.log(intersection); // -> Set(3) { 1, 2, 8 }\n\n// * Diferencia.\nconst differenceOne = setOne.difference(setTwo);\nconsole.log(differenceOne); // -> Set(3) { 3, 5, 13 }\n\nconst differenceTwo = setTwo.difference(setOne);\nconsole.log(differenceTwo); // -> Set(2) { 4, 32 }\n\n// * Diferencia simétrica.\n\nconst symmetricDifference = setOne.symmetricDifference(setTwo);\nconsole.log(symmetricDifference); // -> Set(5) { 3, 5, 13, 4, 32}\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/javascript/duendeintemporal.js",
    "content": "//#18 - CONJUNTOS\n/* * EJERCICIO:\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n * operaciones (debes utilizar una estructura que las soporte):\n * - Añade un elemento al final.\n * - Añade un elemento al principio.\n * - Añade varios elementos en bloque al final.\n * - Añade varios elementos en bloque en una posición concreta.\n * - Elimina un elemento en una posición concreta.\n * - Actualiza el valor de un elemento en una posición concreta.\n * - Comprueba si un elemento está en un conjunto.\n * - Elimina todo el contenido del conjunto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Unión.\n * - Intersección.\n * - Diferencia.\n * - Diferencia simétrica.\n */\n\nlet log = console.log;\n\nwindow.addEventListener('load', ()=>{\n    const body = document.querySelector('body');\n    const title = document.createElement('h1');\n    \n    body.style.setProperty('background', '#000');\n    body.style.setProperty('text-align', 'center');\n    \n    title.textContent = 'Retosparaprogramadores #18.';\n    title.style.setProperty('font-size', '3.5vmax');\n    title.style.setProperty('color', '#fff');\n    title.style.setProperty('line-height', '100vh');\n    \n    body.appendChild(title);\n    \n    setTimeout(()=>{\n    alert('Retosparaprogramadores #18. Please open the Browser Developer Tools.');\n    }, 2000);\n    log( 'Retosparaprogramadores #18'); \n});\n\n\nlet arr = [1,2,3,4,5];\nlog(arr)// [1,2,3,4,5]\n// Adds an element to the end.\narr.push(6);\nlog(arr); // [1,2,3,4,5,6]\n\n// Adds an element to the beginning.\narr.unshift(0);\nlog(arr); // [0, 1, 2, 3, 4, 5, 6]\n// Adds multiple elements in bulk to the end.\narr2 = [7,8,9,10];\narr.push(...arr2);\nlog(arr); //  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n\n// Adds multiple elements in bulk at a specific position.\narr3 = [3.1, 3.2, 3.4]\narr.splice(4,0, ...arr3);\nlog(arr); // [0, 1, 2, 3, 3.1, 3.2, 3.4, 4, 5, 6, 7, 8, 9, 10]\n\n// Removes an element at a specific position.\narr.splice(6,1);\nlog(arr); // [0, 1, 2, 3, 3.1, 3.2, 4, 5, 6, 7, 8, 9, 10]\n\n// Updates the value of an element at a specific position.\narr.splice(arr.length - 1, 1, 9.1);\nlog(arr); // [0, 1, 2, 3, 3.1, 3.2, 4, 5, 6, 7, 8, 9, 9.1]\n\n// Checks if an element is in a set.\nlet nums = new Set();\narr.forEach(n=>nums.add(n));\nlog('Is 10 in nums: ', nums.has(10)) // false\n\n// Removes all content from the set.\nnums.clear();\nlog(nums); // {size: 0}\n\n// EXTRA DIFFICULTY (optional):\n\n// Union.\nlet arr4 = [10, 11, 12, 13, 14];\nlet union = new Set([...arr, ...arr4]);\nlog('union: ', union); // {0, 1, 2, 3, 3.1, …}\n\n// Intersection.\nlet arr5 = [1,4,5,6,15,16,17,18,19];\nlet intersection = new Set();\narr5.forEach(n => {\n    if (union.has(n)) {\n        intersection.add(n);\n    }});\n\nlog('Intersection:', [...intersection]); //  [1, 4, 5, 6]  \n\n// Difference.\nlet difference = new Set(arr); \narr5.forEach(n => {\n    if (difference.has(n)) {\n        difference.delete(n); \n    }});\n\nlog('Difference:', [...difference]); // [0, 2, 3, 3.1, 3.2, 7, 8, 9, 9.1]\n\n// Symmetric difference.\nlet symmetricDiff = new Set([...arr, ...arr5]); \narr5.forEach(n => {\n    if (union.has(n)) {\n        symmetricDiff.delete(n); \n    }\n});\narr.forEach(n => {\n    if (arr5.includes(n)) {\n        symmetricDiff.delete(n); \n    }});\n\nlog('Symmetric Difference:', [...symmetricDiff]); // [0, 2, 3, 3.1, 3.2, 7, 8, 9, 9.1, 15, 16, 17, 18, 19]\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/javascript/edalmava.js",
    "content": "// Ejercicio #18 - Conjuntos\n\nfunction mostrarConjunto(set) {\n    const ordenar = [...set].sort((a, b) => a - b)\n    return `{${ordenar.join(',')}}`\n}\n\nfunction mostrar(set) {\n    return `{${[...set].join(',')}}`\n}\n\nconst conjunto = new Set([1, 2, 3, 4, 5, 6])\nconst conjunto2 = new Set([1, 2, 4, 5, 6, 8, 10])\n\nconsole.log('A = ', mostrar(conjunto))\nconsole.log('B = ', mostrar(conjunto2))\nconsole.log('')\n\n// Añadir valores a los conjuntos\nconjunto.add(7)\nconsole.log('Añadido el número 7 al conjunto A')\nconjunto2.add(12)\nconsole.log('Añadido el número 12 al conjunto B')\nconsole.log('A = ', mostrar(conjunto))\nconsole.log('B = ', mostrar(conjunto2))\nconsole.log('')\n\n// Añadir un elemento al final del conjunto A\nconsole.log('Añadiendo el número 8 al final del conjunto A')\nconjunto.add(8)\nconsole.log(`A = ${mostrar(conjunto)}`)\nconsole.log('')\n\n// Eliminar un valor\nconjunto2.delete(12)\nconsole.log('Eliminado el número 12 del conjunto B')\nconsole.log('')\n\nconsole.log('El número 7 existe en el conjunto A: ', conjunto.has(7))\nconsole.log('El número 12 existe en el conjunto B: ', conjunto2.has(12))\nconsole.log('')\n\nconsole.log('El conjunto A tiene: ', conjunto.size, 'elementos')\nconsole.log('El conjunto B tiene: ', conjunto2.size, 'elementos')\nconsole.log('')\n\nconsole.log('Eliminado todo el contenido del conjunto A')\nconjunto.clear()\nconsole.log('')\n\nconsole.log('El conjunto A tiene: ', conjunto.size, 'elementos')\nconsole.log('El conjunto B tiene: ', conjunto2.size, 'elementos')\nconsole.log('')\n\nconsole.log('Añadiendo números al conjunto A')\nconjunto.add(1)\nconjunto.add(3)\nconjunto.add(5)\nconjunto.add(7)\nconjunto.add(9)\nconsole.log('')\n\nconsole.log('Conjunto A = ', mostrarConjunto(conjunto))\nconsole.log('Conjunto B = ', mostrarConjunto(conjunto2))\nconsole.log('')\n\nconsole.log('Unión de Conjuntos')\nconsole.log('A ∪ B = ', mostrarConjunto(conjunto.union(conjunto2)))\nconsole.log('')\n\nconsole.log('Intersección de Conjuntos')\nconsole.log('A ∩ B = ', mostrarConjunto(conjunto.intersection(conjunto2)))\nconsole.log('')\n\nconsole.log('Diferencia de Conjuntos')\nconsole.log('𝐴 ∖ 𝐵 = ', mostrarConjunto(conjunto.difference(conjunto2)))\nconsole.log('B ∖ A = ', mostrarConjunto(conjunto2.difference(conjunto)))\nconsole.log('')\n\nconsole.log('Diferencia simétrica de Conjuntos')\nconsole.log('(𝐴∖𝐵) ∪ (𝐵∖𝐴) =', mostrarConjunto(conjunto.symmetricDifference(conjunto2)))\nconsole.log('')\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/javascript/emedevelopa.js",
    "content": "/*EJERCICIO:\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n * operaciones (debes utilizar una estructura que las soporte):\n * - Añade un elemento al final.\n * - Añade un elemento al principio.\n * - Añade varios elementos en bloque al final.\n * - Añade varios elementos en bloque en una posición concreta.\n * - Elimina un elemento en una posición concreta.\n * - Actualiza el valor de un elemento en una posición concreta.\n * - Comprueba si un elemento está en un conjunto.\n * - Elimina todo el contenido del conjunto.*/\n\n//Añade un elemento al final\nconst dias = [\"miércoles\", \"jueves\"];\ndias.push(\"viernes\");\nconsole.log(dias);\n\n//Añade un elemento al principio\ndias.unshift(\"martes\");\nconsole.log(dias);\n\n//Añade varios elementos en bloque al final\nconst finde = [\"sábado\", \"domingo\"];\ndias.push(...finde);\nconsole.log(dias);\n\n//Añade varios elementos en bloque en una posición concreta.\nconst inicioSemana = [\"Comenzamos!\", \"lunes\"];\ndias.splice(0, 0, ...inicioSemana);\nconsole.log(dias);\n\n//Elimina un elemento en una posición concreta\ndias.splice(0, 1);\nconsole.log(dias);\n\n//Actualiza el valor de un elemento en una posición concreta.\ndias[0] = \"Maldito lunes\";\nconsole.log(dias);\n\n//Comprueba si un elemento está en un conjunto.\nconst estaSabado = dias.includes(\"sábado\");\nconsole.log(estaSabado);\n\n//Elimina todo el contenido del conjunto.\ndias.length = 0;\nconsole.log(dias);\n\n/*DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Unión.\n * - Intersección.\n * - Diferencia.\n * - Diferencia simétrica.*/\n\n//Unión\nconst names = [\"Pepe\", \"Bartolo\", \"Benito\"];\nconst names2 = [\"Paco\", \"Avelino\", \"Benito\"];\nconst union = new Set();\n\nnames.forEach(nombres => union.add(nombres));\nnames2.forEach(nombres => union.add(nombres));\nconsole.log(union); //Set(5) { 'Pepe', 'Bartolo', 'Benito', 'Paco', 'Avelino' }\n\n//Intersección\nconst interseccion = new Set();\n\nnames.forEach(nombre => {\n    if(names2.includes(nombre)) {\n        interseccion.add(nombre);\n    }\n});\nconsole.log(interseccion); //[ 'Benito' ]\n\n//Diferencia\nconst diferencia = new Set();\n\nnames.forEach(nombre => {\n    if(!names2.includes(nombre)) {\n        diferencia.add(nombre);\n    }\n})\nconsole.log(diferencia); //[ 'Pepe', 'Bartolo' ]\n\n//Diferencia simétrica.\nconst diferenciaSimetrica = new Set();\n\nnames.forEach(nombre => {\n    if(!names2.includes(nombre)){\n        diferenciaSimetrica.add(nombre);\n    }\n})\nnames2.forEach(nombre => {\n    if(!names.includes(nombre)){\n        diferenciaSimetrica.add(nombre);\n    }\n});\nconsole.log(diferenciaSimetrica); //{ 'Pepe', 'Bartolo', 'Paco', 'Avelino' }\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/javascript/eugeniasoria.js",
    "content": "/*\r\n * EJERCICIO:\r\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\r\n * operaciones (debes utilizar una estructura que las soporte):\r\n * - Añade un elemento al final.\r\n * - Añade un elemento al principio.\r\n * - Añade varios elementos en bloque al final.\r\n * - Añade varios elementos en bloque en una posición concreta.\r\n * - Elimina un elemento en una posición concreta.\r\n * - Actualiza el valor de un elemento en una posición concreta.\r\n * - Comprueba si un elemento está en un conjunto.\r\n * - Elimina todo el contenido del conjunto.\r\n *\r\n * DIFICULTAD EXTRA (opcional):\r\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\r\n * - Unión.\r\n * - Intersección.\r\n * - Diferencia.\r\n * - Diferencia simétrica.\r\n */\r\n\r\n// Conjunto de datos\r\nlet conjunto = new Set(['Ash', 'Luna', 'Alma']);\r\nconsole.log('Conjunto inicial: ', conjunto);\r\n\r\n//Elemento añadido al final\r\nconjunto.add('Ciri');\r\nconsole.log('Elemento añadido al final: ', conjunto);\r\n\r\n//Elemento añadido al principio\r\nlet unArray = Array.from(conjunto);\r\nunArray.unshift('Camila');\r\nconjunto = new Set(unArray);\r\nconsole.log('Elemento añadido al principio: ', conjunto);\r\n\r\nlet numerosArray = [1, 2, 3];\r\nlet letrasArray = ['a', 'b', 'c'];\r\nconjunto.add(numerosArray);\r\nconjunto.add(letrasArray);\r\nlet objeto = {nombre: 'miobjeto', dato: 123}\r\nconjunto.add(objeto);\r\nconsole.log('Elementos en bloque añadidos al final: ', conjunto);\r\n\r\nunArray = Array.from(conjunto);\r\nlet otroArray = [5, 10, 15];\r\nunArray.splice(3, 0, otroArray);\r\nconjunto = new Set(unArray);\r\n\r\nlet otroObjeto = {nombre: 'otroObjeto', numero: 888, codigo: 'ASD543'}\r\nunArray.splice(1, 0, otroObjeto);\r\nconjunto = new Set(unArray);\r\n\r\nconsole.log('Elementos en bloque añadidos en posicion concreta(3 y 1): ', conjunto);\r\n\r\nunArray = Array.from(conjunto);\r\nunArray.splice(4,1)\r\nconjunto = new Set(unArray);\r\nconsole.log('Eliminar un elemento en posicion concreta(4): ', conjunto);\r\n\r\nunArray = Array.from(conjunto);\r\nunArray.splice(2,1);//Quito Ash\r\nunArray.splice(2,0, 'AshMejorado');//Quito Ash\r\nconjunto = new Set(unArray);\r\nconsole.log('Actualizar elemento en posicion concreta(2): ', conjunto);\r\n\r\nconsole.log('Comprobar si el elemento \"AshMejorado\" está en el conjunto: ', conjunto.has('AshMejorado'));\r\nconsole.log('Comprobar si el elemento \"EsteNoEstá\" está en el conjunto: ', conjunto.has('EsteNoEstá'));\r\nconsole.log('Comprobar si el elemento \"[1, 2, 3]\" está en el conjunto: ', conjunto.has([1, 2, 3]));\r\nconsole.log('Comprobar si el elemento \"numerosArray\" está en el conjunto: ', conjunto.has(numerosArray));\r\n\r\nconjunto.clear();\r\nconsole.log('Eliminar todo el contenido del conjunto: ', conjunto);\r\n\r\n\r\nconsole.log('\\n\\nDIFICULTAD EXTRA\\n')\r\n\r\nlet conjA = new Set([3, 6, 9, 12]);\r\nlet conjB = new Set([2, 4, 6, 8, 10, 12]);\r\nconsole.log('Conjunto A: ', conjA);\r\nconsole.log('Conjunto B: ', conjB);\r\n\r\nconst union = [...new Set([...conjA, ...conjB])];\r\nconsole.log('A union B: ', union);\r\n\r\nlet arrA = Array.from(conjA);\r\nlet arrInterseccion = arrA.filter((elem) => (conjB.has(elem)) ? elem : null);\r\nlet interseccion = new Set(arrInterseccion);\r\nconsole.log('A intersección B: ', interseccion);\r\n\r\narrA = Array.from(conjA);\r\nlet arrDiferencia = arrA.filter((elem) => (conjB.has(elem)) ? null : elem);\r\nlet diferenciaAB = new Set(arrDiferencia);\r\nconsole.log('Diferencia A - B: ', diferenciaAB);\r\n\r\nlet arrB = Array.from(conjB);\r\narrDiferencia = arrB.filter((elem) => (conjA.has(elem)) ? null : elem);\r\nlet diferenciaBA = new Set(arrDiferencia);\r\nconsole.log('Diferencia B - A: ', diferenciaBA);\r\n\r\nlet diferenciaSimetrica = [...new Set([...diferenciaAB, ...diferenciaBA])];\r\nconsole.log('Diferencia simétrica (A-B) U (B - A): ', diferenciaSimetrica);"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/javascript/eulogioep.js",
    "content": "// TEORÍA: Conjuntos (Sets) en JavaScript\n/*\n * Un Set en JavaScript es una estructura de datos que permite almacenar valores únicos\n * de cualquier tipo. A diferencia de los arrays:\n * - Los elementos en un Set son únicos\n * - No hay índices numéricos para acceder a los elementos\n * - El orden de los elementos se mantiene según el orden de inserción\n *\n * Los Sets son útiles cuando necesitamos asegurarnos de que no hay duplicados\n * y cuando el orden de los elementos no es crucial.\n */\n\n// Función principal que demuestra todas las operaciones\nfunction demostracionSets() {\n    console.log(\"PARTE 1: OPERACIONES BÁSICAS CON SETS\");\n    \n    // Creación de un Set\n    let conjunto = new Set();\n    console.log(\"Conjunto inicial:\", conjunto);\n\n    // 1. Añadir un elemento al final\n    conjunto.add(\"Elemento1\");\n    console.log(\"Después de añadir un elemento:\", conjunto);\n\n    // 2. Añadir un elemento al \"principio\"\n    // NOTA: En realidad, en un Set no hay concepto de principio o final\n    conjunto.add(\"Elemento2\");\n    console.log(\"Después de añadir otro elemento:\", conjunto);\n\n    // 3. Añadir varios elementos en bloque\n    const nuevosElementos = [\"Elemento3\", \"Elemento4\", \"Elemento5\"];\n    nuevosElementos.forEach(elemento => conjunto.add(elemento));\n    console.log(\"Después de añadir varios elementos:\", conjunto);\n\n    // 4. Añadir elementos en una posición concreta\n    // NOTA: Los Sets no permiten insertar en posiciones específicas\n    // Podemos convertir a array, modificar y volver a Set\n    let arrayTemporal = Array.from(conjunto);\n    arrayTemporal.splice(2, 0, \"ElementoA\", \"ElementoB\");\n    conjunto = new Set(arrayTemporal);\n    console.log(\"Después de 'insertar' en posición específica:\", conjunto);\n\n    // 5. Eliminar un elemento\n    conjunto.delete(\"Elemento3\");\n    console.log(\"Después de eliminar 'Elemento3':\", conjunto);\n\n    // 6. Actualizar un elemento\n    // NOTA: No se pueden actualizar elementos directamente\n    // Hay que eliminar el viejo y añadir el nuevo\n    if (conjunto.delete(\"Elemento4\")) {\n        conjunto.add(\"Elemento4Actualizado\");\n    }\n    console.log(\"Después de actualizar 'Elemento4':\", conjunto);\n\n    // 7. Comprobar si un elemento está en el conjunto\n    const contiene = conjunto.has(\"Elemento1\");\n    console.log(\"¿Contiene 'Elemento1'?\", contiene);\n\n    // 8. Eliminar todo el contenido\n    conjunto.clear();\n    console.log(\"Después de limpiar el conjunto:\", conjunto);\n\n    console.log(\"\\nPARTE 2: OPERACIONES EXTRA CON SETS\");\n    \n    // Creamos dos conjuntos para las operaciones\n    const conjunto1 = new Set([1, 2, 3, 4, 5]);\n    const conjunto2 = new Set([4, 5, 6, 7, 8]);\n    \n    // 1. Unión\n    const union = new Set([...conjunto1, ...conjunto2]);\n    console.log(\"Unión:\", union);\n    \n    // 2. Intersección\n    const interseccion = new Set(\n        [...conjunto1].filter(x => conjunto2.has(x))\n    );\n    console.log(\"Intersección:\", interseccion);\n    \n    // 3. Diferencia\n    const diferencia = new Set(\n        [...conjunto1].filter(x => !conjunto2.has(x))\n    );\n    console.log(\"Diferencia (conjunto1 - conjunto2):\", diferencia);\n    \n    // 4. Diferencia simétrica\n    const diferenciaSimetrica = new Set(\n        [...conjunto1].filter(x => !conjunto2.has(x))\n        .concat([...conjunto2].filter(x => !conjunto1.has(x)))\n    );\n    console.log(\"Diferencia simétrica:\", diferenciaSimetrica);\n}\n\n// Funciones auxiliares útiles para trabajar con Sets\nconst utilidadesSets = {\n    // Unión de dos sets\n    union: (setA, setB) => new Set([...setA, ...setB]),\n    \n    // Intersección de dos sets\n    interseccion: (setA, setB) => \n        new Set([...setA].filter(x => setB.has(x))),\n    \n    // Diferencia de dos sets\n    diferencia: (setA, setB) => \n        new Set([...setA].filter(x => !setB.has(x))),\n    \n    // Diferencia simétrica de dos sets\n    diferenciaSimetrica: (setA, setB) => \n        new Set([...setA].filter(x => !setB.has(x))\n                .concat([...setB].filter(x => !setA.has(x))))\n};\n\n// Ejecutar la demostración\ndemostracionSets();"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/javascript/garos01.js",
    "content": "// Creamos un array vacío para representar nuestro conjunto de datos\nlet conjunto = [\"elemento\"];\nconsole.log(\"Conjunto inicial:\", conjunto);\n\n// Añadir un elemento al final\nconjunto.push(\"elemento_final\");\nconsole.log(\"Conjunto después de añadir un elemento al final:\", conjunto);\n\n// Añadir un elemento al principio\nconjunto.unshift(\"elemento_inicio\");\nconsole.log(\"Conjunto después de añadir un elemento al principio:\", conjunto);\n\n// Añadir varios elementos en bloque al final\nconjunto.push(\"elemento1\", \"elemento2\", \"elemento3\");\nconsole.log(\n  \"Conjunto después de añadir varios elementos en bloque al final:\",\n  conjunto\n);\n\n// Añadir varios elementos en bloque en una posición concreta\nconjunto.splice(2, 0, \"bloque_elemento1\", \"bloque_elemento2\");\nconsole.log(\n  \"Conjunto después de añadir varios elementos en bloque en una posición concreta:\",\n  conjunto\n);\n\n// Eliminar un elemento en una posición concreta\nconjunto.splice(3, 1); // Eliminamos el elemento en la posición 3\nconsole.log(\n  \"Conjunto después de eliminar un elemento en una posición concreta:\",\n  conjunto\n);\n\n// Actualizar el valor de un elemento en una posición concreta\nconjunto[1] = \"nuevo_valor_elemento\";\nconsole.log(\n  \"Conjunto después de actualizar el valor de un elemento en una posición concreta:\",\n  conjunto\n);\n\n// Comprobar si un elemento está en un conjunto\nlet elementoBuscado = \"elemento1\";\nlet estaEnConjunto = conjunto.includes(elementoBuscado);\nconsole.log(\n  `¿El elemento \"${elementoBuscado}\" está en el conjunto? ${estaEnConjunto}`\n);\n\n// Eliminar todo el contenido del conjunto\nconjunto = []; // Asignamos un array vacío para vaciar el conjunto\nconsole.log(\"Conjunto después de eliminar todo su contenido:\", conjunto);\n\n// Ejercicio extra\n\n// Conjuntos de ejemplo\nlet conjunto1 = new Set([1, 2, 3, 4, 5]);\nlet conjunto2 = new Set([4, 5, 6, 7, 8]);\nconsole.log(\"Conjunto 1:\", conjunto1);\nconsole.log(\"Conjunto 2:\", conjunto2);\n\n// Unión\nlet union = new Set([...conjunto1, ...conjunto2]);\nconsole.log(\"Unión de los conjuntos:\", union);\n\n// Intersección\nlet interseccion = new Set([...conjunto1].filter((x) => conjunto2.has(x)));\nconsole.log(\"Intersección de los conjuntos:\", interseccion);\n\n// Diferencia\nlet diferencia1 = new Set([...conjunto1].filter((x) => !conjunto2.has(x)));\nlet diferencia2 = new Set([...conjunto2].filter((x) => !conjunto1.has(x)));\nconsole.log(\"Diferencia entre conjunto1 y conjunto2:\", diferencia1);\nconsole.log(\"Diferencia entre conjunto2 y conjunto1:\", diferencia2);\n\n// Diferencia simétrica\nlet diferenciaSimetrica = new Set(\n  [...conjunto1]\n    .filter((x) => !conjunto2.has(x))\n    .concat([...conjunto2].filter((x) => !conjunto1.has(x)))\n);\nconsole.log(\"Diferencia simétrica entre los conjuntos:\", diferenciaSimetrica);\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/javascript/hectorio23.js",
    "content": "// Autor: Héctor Adán \n// GitHub: https://github.com/hectorio23\n\"use strict\";\n\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n * operaciones (debes utilizar una estructura que las soporte):\n * - Añade un elemento al final.\n * - Añade un elemento al principio.\n * - Añade varios elementos en bloque al final.\n * - Añade varios elementos en bloque en una posición concreta.\n * - Elimina un elemento en una posición concreta.\n * - Actualiza el valor de un elemento en una posición concreta.\n * - Comprueba si un elemento está en un conjunto.\n * - Elimina todo el contenido del conjunto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Unión.\n * - Intersección.\n * - Diferencia.\n * - Diferencia simétrica.\n */\n\n\n// Crear un conjunto de datos utilizando un array en JavaScript\nconsole.log(\"Conjunto de datos antes de realizar los cambios: \");\nlet conjunto = [\"a\", \"b\", \"c\", \"d\"];\nconsole.log(conjunto);\n\n// Añadir un elemento al final del conjunto\nconjunto.push(\"e\");\nconsole.log(`*Agregando el elemento <<e>> al final del conjunto\\n ${ conjunto }`)\n\n// Añadir un elemento al principio del conjunto\nconjunto.unshift(\"z\");\nconsole.log(`*Agregando el elemento <<z>> al principio del conjunto\\n ${ conjunto }`)\n\n// Añadir varios elementos al final del conjunto\nconjunto.push(\"f\", \"g\");\nconsole.log(`*Agregando los elementos <<f,g>> al final del conjunto\\n ${ conjunto }`)\n\n// Añadir varios elementos en una posición concreta del conjunto\nconjunto.splice(3, 0, \"x\", \"y\");\nconsole.log(`*Agregando los elementos <<x, y>> en una posición en concreta del conjunto\\n ${ conjunto }`)\n\n// Eliminar un elemento en una posición concreta del conjunto\nconjunto.splice(2, 1);\nconsole.log(`*Eliminando elementos en posicion concreta\\n ${ conjunto }`)\n\n// Actualizar el valor de un elemento en una posición concreta del conjunto\nconjunto[1] = \"updated\";\nconsole.log(`*Actualizar el valor de los elementos en una posicion concreta\\n ${ conjunto }`)\n\n// Comprobar si un elemento está en el conjunto\nconst elementoBuscado = \"c\";\nconst estaEnConjunto = conjunto.includes(elementoBuscado);\nconsole.log(`*El elemento \"${elementoBuscado}\" ${estaEnConjunto ? \"sí\" : \"no\"} está en el conjunto.`);\n\n// Eliminar todo el contenido del conjunto\nconjunto.length = 0;\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Operaciones adicionales sobre conjuntos: Unión, Intersección, Diferencia, Diferencia simétrica\n */\n\n// Crear dos conjuntos adicionales\nlet conjunto1 = [\"a\", \"b\", \"c\", \"d\"];\nlet conjunto2 = [\"c\", \"d\", \"e\", \"f\"];\n\n// Unión de conjuntos\nconst union = [...new Set([...conjunto1, ...conjunto2])];\nconsole.log(\"*Unión:\", union);\n\n// Intersección de conjuntos\nconst interseccion = conjunto1.filter(elemento => conjunto2.includes(elemento));\nconsole.log(\"*Intersección:\", interseccion);\n\n// Diferencia de conjuntos (elementos en conjunto1 que no están en conjunto2)\nconst diferencia = conjunto1.filter(elemento => !conjunto2.includes(elemento));\nconsole.log(\"*Diferencia:\", diferencia);\n\n// Diferencia simétrica de conjuntos (elementos que están en un conjunto u otro, pero no en ambos)\nconst diferenciaSimetrica = [...new Set([...conjunto1.filter(elemento => !conjunto2.includes(elemento)), ...conjunto2.filter(elemento => !conjunto1.includes(elemento))])];\nconsole.log(\"*Diferencia simétrica:\", diferenciaSimetrica);\n\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n_______________________________________\n#18 CONJUNTOS\n---------------------------------------\n * EJERCICIO:\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n * operaciones (debes utilizar una estructura que las soporte):\n * - Añade un elemento al final.\n * - Añade un elemento al principio.\n * - Añade varios elementos en bloque al final.\n * - Añade varios elementos en bloque en una posición concreta.\n * - Elimina un elemento en una posición concreta.\n * - Actualiza el valor de un elemento en una posición concreta.\n * - Comprueba si un elemento está en un conjunto.\n * - Elimina todo el contenido del conjunto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Unión.\n * - Intersección.\n * - Diferencia.\n * - Diferencia simétrica.\n*/\n// ________________________________________________________\n\n// Crear una lista\nlet myList = [\"a\", \"b\", \"c\"];\n\n// Añade un elemento al final.\nmyList.push(\"d\");\n\n// Añade un elemento al principio.\nmyList.unshift(\"-\");\n\n// Añade varios elementos en bloque al final.\nmyList.push(\"e\", \"f\");\n\n// Añade varios elementos en bloque en una posición concreta.\nmyList.splice(4, 0, \"-\", \">\");\n\n// Elimina en una posición concreta.\nmyList.splice(5, 1);\n\n// Actualiza en una posición concreta.\nmyList[2] = \"-b\";\n\n// Mostrar\nconsole.log(myList);\n\n// Comprobar\nconsole.log(`\"c\" en lista: ${myList.includes(\"c\")}`);\nconsole.log(`\"g\" en lista: ${myList.includes(\"g\")}`);\n\n// Elimina todo el contenido.\nmyList.length = 0;\nconsole.log(myList);\n\n// ________________________________________________________\n// DIFICULTAD EXTRA\n\n// Crear conjuntos\nlet set1 = new Set([\"a\", \"b\", \"c\", \"d\"]);\nlet set2 = new Set([\"c\", \"d\", \"e\", \"f\"]);\nconsole.log(`set1: ${[...set1]} - set2: ${[...set2]}`)\n\n// Unión\nlet union = new Set([...set1, ...set2]);\nconsole.log(`Unión: ${[...union]}`);\n\n// Intersección\nlet intersection = new Set([...set1].filter(x => set2.has(x)));\nconsole.log(`Intersección: ${[...intersection]}`);\n\n// Diferencia (set1 - set2)\nlet difference1 = new Set([...set1].filter(x => !set2.has(x)));\nconsole.log(`Diferencia: ${[...difference1]}`);\n\n// Diferencia (set2 - set1)\nlet difference2 = new Set([...set2].filter(x => !set1.has(x)));\nconsole.log(`Diferencia: ${[...difference2]}`);\n\n// Diferencia simétrica\nlet symmetricDifference = new Set([\n  ...[...set1].filter(x => !set2.has(x)),\n  ...[...set2].filter(x => !set1.has(x))\n]);\nconsole.log(`Diferencia simétrica: ${[...symmetricDifference]}`);\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/javascript/manjaitan.js",
    "content": "// Conjuntos de datos en JavaScript\n\nlet myArray = [\"Perro\",\"Gato\",\"Ciervo\",\"Rinoceronte\"] // conjunto de datos array.\n\nmyArray.push (\"Cabra\"); // añade elemento al final del array.\nconsole.log(myArray);\n\nmyArray.unshift (\"Cebra\"); // añade elemento al principio del array.\nconsole.log(myArray);\n\nmyArray.push (\"Gamo\",\"Vaca\",\"Toro\"); // añade varios elementos en bloque al final.\nconsole.log(myArray);\n\nmyArray.splice (2,0,\"Gacela\",\"Cerdo\"); // añade varios elementos en la posicion dada.\nconsole.log(myArray);\n\ndelete (myArray[3]) // elimina elemento de array , en este caso posicion 3.\nconsole.log(myArray);\n\nmyArray[0] = 'Cerdo' // acutaliza elemento [0] del array , lo actualiza a nombre de animal 'Cerdo'.\nconsole.log(myArray);\n\nconsole.log('--------------')\nconsole.log (myArray.includes('Cerdo')) // busca el elemento 'Cerdo' dentro de myArray.\n\nmyArray = [] // Elimina todo el contenido del arrau\nconsole.log(myArray);\n\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/javascript/nlarrea.js",
    "content": "/*\n * EJERCICIO:\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n * operaciones (debes utilizar una estructura que las soporte):\n * - Añade un elemento al final.\n * - Añade un elemento al principio.\n * - Añade varios elementos en bloque al final.\n * - Añade varios elementos en bloque en una posición concreta.\n * - Elimina un elemento en una posición concreta.\n * - Actualiza el valor de un elemento en una posición concreta.\n * - Comprueba si un elemento está en un conjunto.\n * - Elimina todo el contenido del conjunto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Unión.\n * - Intersección.\n * - Diferencia.\n * - Diferencia simétrica.\n */\n\nlet data = [1, 2, 3, 4, 5];\nconsole.log(data);  // [1, 2, 3, 4, 5]\n\n// Añadir un elemento al final\ndata.push('final');\nconsole.log(data);  // [1, 2, 3, 4, 5, 'final']\n\n// Añadir un elemento al principio\ndata.unshift('start');\nconsole.log(data);  // ['start', 1, 2, 3, 4, 5, 'final']\n\n// Añadir varios elementos en bloque al final\ndata.push(['final', 'elements', 3])\nconsole.log(data);  // ['start', 1, 2, 3, 4, 5, 'final', ['final', 'elements', 3]]\n\n// Añadir varios elementos en bloque en una posición concreta\ndata.splice(2, 0, ['more', 'data', 'position', 2]);\nconsole.log(data);\n// ['start', 1, ['more', 'data', 'position', 2], 2, 3, 4, 5, 'final', ['final', 'elements', 3]]\n\n// Elimina un elemento en una posición concreta\ndata.splice(3, 1);\nconsole.log(data);\n// ['start', 1, ['more', 'data', 'position', 2], 3, 4, 5, 'final', ['final', 'elements', 3]]\n\n// Actualiza el valor de un elemento en una posición concreta\ndata[1] = true;\nconsole.log(data);\n// ['start', true, ['more', 'data', 'position', 2], 3, 4, 5, 'final', ['final', 'elements', 3]]\n\n// Comprueba si un elemento está en un conjunto\nconsole.log(data.includes('dato'));  // false\nconsole.log(data.includes(5));  // true\n\n// Elimina todo el contenido del conjunto\ndata.splice(0);\nconsole.log(data);  // []\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Unión.\n * - Intersección.\n * - Diferencia.\n * - Diferencia simétrica.\n */\n\nconst data1 = [1, 2, 3, 4];\nconst data2 = [1, 2, 3, 4, 5, 6, 7];\n\nconst union = [...new Set([...data1, ...data2])];\nconsole.log('Union:', union);\n\nconst intersection = data1.filter(item => data2.includes(item));\nconsole.log(\"Intersection:\", intersection);\n\nconst diff12 = data1.filter(item => !data2.includes(item));\nconsole.log('Difference 1-2:', diff12);\nconst diff21 = data2.filter(item => !data1.includes(item));\nconsole.log('Difference 2-1:', diff21);\n\nconst symmetricDiff = [...new Set([...diff12, ...diff21])];\nconsole.log('Symmetric difference:', symmetricDiff);"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/javascript/parababire.js",
    "content": "let fruits = [\"Banana\", \"Orange\", \"Apple\", \"Mango\"];\nfruits.push(\"Kiwi\"); // Añadir un elemento al final.\nfruits.unshift(\"Pear\"); // Añadir un elemento al principio.\nfruits.push(\"Lemon\", \"Grape\"); // Añade varios elementos en bloque al final.\nfruits.splice(6, 0, \"Strawberry\", \"Blueberry\"); // Añadir varios elementos en bloque en una posición concreta.\nfruits.splice(5, 1); // Elimina un elemento en una posición concreta.\nfruits[5] = \"Kiwi\"; // Actualiza el valor de un elemento en una posición concreta.\nfruits.includes(\"Strawberry\"); // Comprueba si un elemento está en un conjunto.\nfruits.splice(0, fruits.length); // Elimina todo el contenido del conjunto.\nconsole.log(fruits);\n\n// Extra\n\n/* Union: A U B */\n\nlet arr1 = [1, 2, 3, 4];\nlet arr2 = [3, 4, 5];\n\nfunction union(a, b) {\n  const result = [];\n\n  for (const item of a) {\n    if (!result.includes(item)) {\n      result.push(item);\n    }\n  }\n  for (const item of b) {\n    if (!result.includes(item)) {\n      result.push(item);\n    }\n  }\n  return result;\n}\n\nconsole.log(union(arr1, arr2));\n\n/* Intersección: A ∩ B */\n\nlet arr3 = [1, 2, 3, 4, 5];\nlet arr4 = [1, 6, 3, 7, 5];\n\nconsole.log(arr3.filter(data => arr4.includes(data)));\n\n/* Diferencia: A \\ B */\n\nfunction diferencia(a, b) {\n  let result = [];\n  for (const item of a) {\n    if (!b.includes(item)) {\n      result.push(item);\n    }\n  }\n  return result;\n}\n\nconsole.log(diferencia(arr3, arr4));\n\n/* Diferencia asimétrica : A Δ B */\n\nfunction diferenciaAsimetrica(a, b) {\n  let result = [];\n  for (const item of a) {\n    if (!b.includes(item)) {\n      result.push(item);\n    }\n  }\n  for (const item of b) {\n    if (!a.includes(item)) {\n      result.push(item);\n    }\n  }\n  return result;\n}\n\nconsole.log(diferenciaAsimetrica(arr3, arr4));"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/javascript/pedamoci.js",
    "content": "let conjunto = ['sada', 75654, 21, 3347, 'asd', 'adsd']\n\n// añadiendo elemento al final del conjunto\nconjunto.push('último elemento')\nconsole.log(conjunto)\n\n// añadiendo elemento al principio del conjunto\nconjunto.splice(0,0,'primer elemento')\nconsole.log(conjunto)\n\n// añadiendo varios elementos en bloque al final\nconjunto = conjunto.concat([['eB1', 'eB2', 'eB3']])\nconsole.log(conjunto)\n\n// añadiendo varios elementos en bloque en una posición concreta\nconjunto.splice(3, 0, ['eB1', 'eB2', 'eB3'])\nconsole.log(conjunto)\n\n// eliminando un elementos en una posición concreta\nconjunto.splice(5, 1)\nconsole.log(conjunto)\n\n// actualizando el valor de un elementos en una posición concreta\nconjunto.splice(7, 1, 'ya no soy el último elemento')\nconsole.log(conjunto)\n\n// comprobando si un elementos esta en el conjunto\nconsole.log(conjunto.includes(21))\n\n// eliminando todo el contenido conjunto\nconjunto.splice(0, conjunto.length)\nconsole.log(conjunto)\n\n// --------------------------------------- DIFICULTAD EXTRA ---------------------------------------\nlet arrConjunto1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\nlet arrConjunto2 = [5, 6, 7, 8, 9, 10, 11, 12, 13, 14]\n\n// Unión\nlet union = arrConjunto1.concat(arrConjunto2)\nconsole.log(`La unión de los dos conjuntos es ${union}`)\n\n// intersección\nlet interseccion = []\narrConjunto1.forEach((e) => {if (arrConjunto2.includes(e)) interseccion.push(e)})\nconsole.log(interseccion)\n\n// Diferencia en arrConjunto1\nlet difArrConjunto1 = []\narrConjunto1.forEach((e) => {if (!arrConjunto2.includes(e)) difArrConjunto1.push(e)})\nconsole.log(difArrConjunto1)\n\n// Diferencia en arrConjunto2\nlet difArrConjunto2 = []\narrConjunto2.forEach((e) => {if (!arrConjunto1.includes(e)) difArrConjunto2.push(e)})\nconsole.log(difArrConjunto2)\n\n// Diferencia simétrica\nlet diferenciaSimetrica = []\narrConjunto1.forEach((e) => {if (!arrConjunto2.includes(e)) diferenciaSimetrica.push(e)})\narrConjunto2.forEach((e) => {if (!arrConjunto1.includes(e)) diferenciaSimetrica.push(e)})\nconsole.log(diferenciaSimetrica)"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/javascript/rserradev.js",
    "content": "// Crear conjunto de datos\nlet conjunto = [\"elemento1\", \"elemento2\", \"elemento3\", \"elemento4\", \"elemento5\"];\nconsole.log(conjunto);\n\n// Añadir un elemento al final\nconjunto.push(\"elemento6\");\nconsole.log(conjunto);\n\n// Añadir un elemento al comienzo\nconjunto.unshift(\"elemento0\");\nconsole.log(conjunto);\n\n// Añadir varios elementos en bloque al final\nlet conjunto2 = [\"elemento7\", \"elemento8\", \"elemento9\", \"elemento10\", \"elemento11\"];\n\nconjunto2.forEach(Element => {\n    conjunto.push(Element);\n});\nconsole.log(conjunto);\n\n// Añadir varios elementos en bloque en una posición concreta\n\nlet conjunto3 = [\"elemento12\", \"elemento13\", \"elemento14\", \"elemento15\", \"elemento16\"];\n\nconjunto3.forEach(element => {\n    conjunto.splice(0, 0 , element);\n});\n\nconsole.log(conjunto);\n\n// Eliminar un elemento en una posición en concreto\nconjunto.splice(0,1);\nconsole.log(conjunto);\n\n// Actualizar valor de un elemento en una posición en concreto\nconjunto.splice(0, 1, \"Valor reemplazado\");\nconsole.log(conjunto);\n\n// Comprobar si un elemento esta en el conjunto\nconjunto.forEach(element => {\n    if (element === \"elemento100\") {\n        console.log(\"El elemento si esta en el conjunto y es el: \" + element);\n    } else {\n        console.log(\"El elemento no esta en el array: \" + element);\n    }\n});\nconsole.log(\"Se recorrieron todos los elementos y no se encontró el que se esperaba\");\n\n// Eliminar todo el contenido del conjunto\nlet tamañoConjunto = conjunto.length;\n\nfor (let index = 0; index < tamañoConjunto; index++) {\n    conjunto.splice(0, 1,);\n    console.log(conjunto);\n}\n\n// Ejemplo de unión\nconst conjuntoSet1 = new Set([\"uno\", \"dos\", \"tres\", \"cuatro\", \"cinco\"]);\nconst conjuntoSet2 = new Set([\"uno\", \"elemento20\", \"elemento21\", \"elemento22\", \"elemento23\", \"elemento24\"]);\n\nlet unionConjuntos = new Set([...conjuntoSet1, ...conjuntoSet2]);\n\nconsole.log(unionConjuntos);\n\n// Ejemplo de intersección\nconsole.log(\"Ejemplo de interseccion\");\nfor (const i of conjuntoSet1) {\n    if (conjuntoSet2.has(i)) {\n        console.log(i);\n    }\n}\n\n// Ejemplo de diferencias\nconsole.log(\"Ejemplo de diferencia\");\nfor (const element of conjuntoSet1) {\n    if (conjuntoSet2.has(element)) {\n        conjuntoSet1.delete(element);\n        console.log(\"El elemento \" + element + \" se a eliminado porque no es diferente\");\n    }\n}\nconsole.log(conjuntoSet1);\n\n// Diferencia simétrica\nconst conjuntoNum1 = new Set([1,2,3,4,5]);\nconst conjuntoNum2 = new Set([1,2,3,6,7]);\n\nconst conjuntoSimétrico = new Set([]);\n\n// Calcular la diferencia simétrica\nfor (const element of conjuntoNum1) {\n    if (conjuntoNum2.has(element)) {\n        conjuntoNum1.delete(element);\n    } else {\n        conjuntoSimétrico.add(element);\n    }\n}\n\nconsole.log(conjuntoSimétrico);"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/javascript/victor-Casta.js",
    "content": "/*\n  * Usando JavaScript, crea un conjunto de datos y realiza las siguientes operaciones:\n  * - Añade un elemento al final.\n  * - Añade un elemento al principio.\n  * - Añade varios elementos en bloque al final.\n  * - Añade varios elementos en una posición específica.\n  * - Elimina un elemento de una posición específica.\n  * - Actualiza el valor de un elemento en una posición específica.\n  * - Comprueba si un elemento está en el conjunto.\n  * - Elimina todo el contenido del conjunto.\n*/\n\n// Inicializa la lista de números\nconst numberList = [1, 2, 3];\n\nconsole.log(`Lista original: ${numberList}`);\n\n// Añade un elemento al final de la lista\nnumberList.push(4);\nconsole.log(`Añadiendo elemento al final: ${numberList}`);\n\n// Añade un elemento al inicio de la lista\nnumberList.unshift(0);\nconsole.log(`Añadiendo elemento al inicio: ${numberList}`);\n\n// Añade varios elementos al final de la lista\nnumberList.push(5, 6, 7);\nconsole.log(`Añadiendo bloque de elementos al final: ${numberList}`);\n\n// Añade varios elementos en una posición específica (índice 2)\nnumberList.splice(2, 0, -3, -4);\nconsole.log(`Añadiendo bloque de elementos en una posición: ${numberList}`);\n\n// Elimina un elemento de una posición específica (índice 2)\nnumberList.splice(2, 1);\nconsole.log(`Eliminando un elemento de una posición: ${numberList}`);\n\n// Actualiza el valor de un elemento en el índice 2\nnumberList[2] = -1;\nconsole.log(`Actualizando el valor de un elemento: ${numberList}`);\n\n// Comprueba si un elemento específico existe en la lista\nconsole.log(`¿Existe el elemento -1 en la lista? ${numberList.includes(-1)}`);\n\n// Elimina todo el contenido de la lista\nnumberList.length = 0;\nconsole.log(`Eliminando todo el contenido: ${numberList}`);\n\n/* -------- Operaciones con Sets -------- */\n\nconsole.log('Unión de conjuntos:');\nconst set1 = new Set([1, 2, 0]);\nconst set2 = new Set([3, 4, 0]);\n\n// Realiza la operación de unión añadiendo elementos de set2 a set1\nfor (let item of set2) {\n  set1.add(item);\n}\nconsole.log(set1);\n\nconsole.log('Intersección de conjuntos:');\nconst set3 = new Set([1, 2, 0]);\nconst set4 = new Set([3, 4, 0]);\nconst set5 = new Set();\n\n// Realiza la operación de intersección\nfor (let item of set4) {\n  if (set3.has(item)) {\n    set5.add(item);\n  }\n}\nconsole.log(set5);  // Debería mostrar Set { 0 }\n\nconsole.log('Diferencia de conjuntos:');\nconst set6 = new Set([1, 2, 0]);\nconst set7 = new Set([3, 4, 0]);\nconst set8 = new Set();\n\n// Realiza la operación de diferencia (set6 - set7)\nfor (let item of set6) {\n  if (!set7.has(item)) {\n    set8.add(item);\n  }\n}\nconsole.log(set8);  // Debería mostrar Set { 1, 2 }\n\nconsole.log('Más operaciones con conjuntos:');\n\n// Unión usando el operador spread\nconst set9 = new Set([1, 2, 0]);\nconst set10 = new Set([3, 4, 0]);\nconst setUnion = new Set([...set9, ...set10]);\n\n// Intersección usando filter\nconst intersection = new Set([...set9].filter(item => set10.has(item)));\n\n// Diferencia (set10 - set9)\nconst difference1 = new Set([...set10].filter(item => !set9.has(item)));\n\n// Diferencia (set9 - set10)\nconst difference2 = new Set([...set9].filter(item => !set10.has(item)));\n\nconsole.log(setUnion);  // Resultado de la unión\nconsole.log(intersection);  // Resultado de la intersección\nconsole.log(difference1);  // Resultado de la diferencia (set10 - set9)\nconsole.log(difference2);  // Resultado de la diferencia (set9 - set10)\n\n// Diferencia simétrica (elementos en set9 o set10, pero no en ambos)\nconst symmetricDifference = new Set([...difference1, ...difference2]);\nconsole.log(symmetricDifference);  // Resultado de la diferencia simétrica"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/javascript/wapastorv.js",
    "content": "/*\n * EJERCICIO:\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n * operaciones (debes utilizar una estructura que las soporte):\n * - Añade un elemento al final.\n * - Añade un elemento al principio.\n * - Añade varios elementos en bloque al final.\n * - Añade varios elementos en bloque en una posición concreta.\n * - Elimina un elemento en una posición concreta.\n * - Actualiza el valor de un elemento en una posición concreta.\n * - Comprueba si un elemento está en un conjunto.\n * - Elimina todo el contenido del conjunto.\n*/\n\n/* \nLa estructura de datos que se va a utilizar es un arreglo, ya que es una estructura que soporta todas las operaciones que se piden en el ejercicio.\n*/\n\nlet arregloDeNumeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n\n// Agregar un número al final del arreglo\narregloDeNumeros.push(11);\nconsole.log(arregloDeNumeros);// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]\n\n// Agregar un número al principio del arreglo\narregloDeNumeros.unshift(0);\nconsole.log(arregloDeNumeros);// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]\n\n// Agregar varios números al final del arreglo\narregloDeNumeros.push(12, 13, 14, 15);\nconsole.log(arregloDeNumeros); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] \n\n// Agregar varios números en una posición concreta\narregloDeNumeros.splice(5, 0, 5.1, 5.2, 5.3);\nconsole.log(arregloDeNumeros); // [0, 1, 2, 3, 4, 5, 5.1, 5.2, 5.3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]\n\n// Eliminar un elemento en una posición concreta\narregloDeNumeros.splice(5, 1);\nconsole.log(arregloDeNumeros); // [0, 1, 2, 3, 4, 5.1, 5.2, 5.3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]\n\n// Actualizar el valor de un elemento en una posición concreta\narregloDeNumeros[5] = 5;\nconsole.log(arregloDeNumeros); // [0, 1, 2, 3, 4, 5, 5.2, 5.3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]\n\n// Comprobar si un elemento está en un conjunto\nconsole.log(arregloDeNumeros.includes(5)); // true\n\n// Eliminar todo el contenido del conjunto\n//arregloDeNumeros = [];\n//console.log(arregloDeNumeros); // []\n\n\n\nconst array1 = [1, 2, 3, 6];\nconst array2 = [1, 2, 3, 4, 5];\n\nconsole.log(\"Arreglo original 1: \",array1);\nconsole.log(\"Arreglo original 2: \",array2);\n\n// Crear conjuntos a partir de arreglos\nconst conjuntoA = new Set(array1);\nconst conjuntoB = new Set(array2);\n\n// Operaciones de conjuntos con arreglos en JavaScript usando Set y Arreglos directamente\n// Set es una estructura de datos que no permite elementos duplicados, por lo que es ideal para trabajar con conjuntos.\n\n// Union de conjuntos\n\nfunction unionConSet(setA, setB) {\n    return new Set([...setA, ...setB]);\n}\n\nconsole.log(\"Union de conjuntos con SET: \",unionConSet(conjuntoA,conjuntoB)); // [1, 2, 3, 1, 2, 3, 4, 5]\n\n// Union mantenimentdo la estructua de arreglo\nconst unionArray = (array1, array2) => {\n    return [...new Set([...array1, ...array2])];\n}\nconsole.log(\"Union de arreglos\",unionArray(array1, array2)); // [1, 2, 3, 4, 5, 6]\n\n\n\n// Intersección de conjuntos\n// La intersección contiene solo los elementos que están en ambos conjuntos.\n\nfunction intersectionConSet(setA, setB) {\n    return new Set([...setA].filter(x => setB.has(x)));\n}\nconsole.log(\"Intersecion de conjuntos con SET\",intersectionConSet(conjuntoA,conjuntoB)); // [1, 2, 3]\n\n// Intersección mantenimentdo la estructua de arreglo\nconst intersectionArray = (array1, array2) => {\n    return array1.filter(value => array2.includes(value));\n}\nconsole.log(\"Intersecion de arreglos\",intersectionArray(array1, array2)); // [1, 2, 3]\n\n\n// Difference de conjuntos\n// La diferencia contiene los elementos que están en el primer conjunto pero no en el segundo.\n\n// Diferencia con la estructura de set\nconst differenceArraySet = (setA, setB) => {\n    return new Set([...setA].filter(x => !setB.has(x)));\n}\nconsole.log(\"Diferencia con la estrucura de set: \",differenceArraySet(conjuntoA,conjuntoB)); // [6]\n\n// Diferencia con la estructura de arreglos\nconst differenceArray = (array1, array2) => {\n    return array1.filter(value => !array2.includes(value));\n}\nconsole.log(\"Diferencia con la estructura de arreglos: \",differenceArray(array1, array2)); // [6]\n\n// Diferencia simétrica de conjuntos\n// La diferencia simétrica contiene los elementos que están en uno de los conjuntos pero no en ambos.\n\n//Diferencia simétrica con la estructura de set\nconst symmetricDifferenceArraySet = (setA, setB) => {\n    return new Set([...setA].filter(x => !setB.has(x)).concat([...setB].filter(x => !setA.has(x))))\n}\nconsole.log(\"Diferencia simétrica con la estructura de set: \",symmetricDifferenceArraySet(conjuntoA,conjuntoB)); // [4, 5, 6]\n\n// Diferencia simétrica con la estructura de arreglos\nconst symmetricDifferenceArray = (array1, array2) => {\n    return array1.filter(value => !array2.includes(value)).concat(array2.filter(value => !array1.includes(value)));\n}\n\nconsole.log(\"Diferencia simétrica con la estructura de arreglos: \",symmetricDifferenceArray(array1, array2)); // [4, 5, 6]\n\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/kotlin/blackriper.kt",
    "content": "/*\r\n conjunto: coleccion de elementos considerados como un objeto los mismos pueden ser de diferentes tipos\r\n no siempre son una coleccion ordenada.\r\n\r\n operaciones de conjuntos\r\n  -Unión: operacion que combina dos conjuntos o mas para formar un nuevo conjunto cuyos elementos son todos los elementos de los conjuntos originales\r\n  -Intersección: operacion que contienen elementos comunes entre dos conjuntos dando como resultado un nuevo conjunto\r\n  -Diferencia: operacion que cuyo conjunto resultante son los elementos comunes entre dos conjuntos originales\r\n  -Diferencia simetrica: operacion que cuyo conjunto resultante son los elementos que no son  comunes en ambos conjuntos\r\n\r\n\r\n*/\r\n\r\nfun basicOperations() {\r\n    val listNumbers = mutableListOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)\r\n\r\n    // add element\r\n    listNumbers.add(11)\r\n    println(listNumbers)\r\n    // add element at start position\r\n    listNumbers.add(0, 0)\r\n    println(listNumbers)\r\n    // adding multiple elements\r\n    listNumbers.addAll(listOf(12, 13, 14))\r\n    println(listNumbers)\r\n    // add element at specific position\r\n    listNumbers.addAll(3, listOf(15, 16, 17))\r\n    println(listNumbers)\r\n    // delete element\r\n    listNumbers.removeAt(3)\r\n    println(listNumbers)\r\n    // update element\r\n    listNumbers[4] = 4\r\n    println(listNumbers)\r\n    // find element\r\n    println(listNumbers.contains(17))\r\n    // delete all elements\r\n    listNumbers.clear()\r\n    println(listNumbers)\r\n}\r\n\r\nfun operationsWithConjuntos() {\r\n    val characters = mutableListOf(\"cell\",\"majin boo\",\"yanemba\",\"freezer\",\"broly\",\"cooler\",\"slug\")\r\n    val characters2 = mutableListOf(\"cell\",\"majin boo\",\"gohan\",\"freezer\",\"broly\",\"cooler\",\"goten\")\r\n\r\n    // union\r\n    val union = characters.union(characters2)\r\n    println(union)\r\n\r\n    // intersection\r\n    val intersection = characters.intersect(characters2)\r\n    println(intersection)\r\n\r\n    // difference\r\n    val difference = characters.subtract(characters2)\r\n    println(difference)\r\n\r\n    // symmetric difference\r\n    val symmetricDifference = characters.filter {  !characters2.contains(it)  }.union(characters2.filter { !characters.contains(it) })\r\n    println(symmetricDifference)\r\n\r\n\r\n}\r\n\r\n\r\nfun main() {\r\n  basicOperations()\r\n  operationsWithConjuntos()\r\n}\r\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/kotlin/eulogioep.kt",
    "content": "fun main() {\n    // Creamos un conjunto mutable\n    val conjunto = mutableListOf(\"A\", \"B\", \"C\")\n    println(\"Conjunto inicial: $conjunto\")\n\n    // Añade un elemento al final\n    conjunto.add(\"D\")\n    println(\"Después de añadir al final: $conjunto\")\n\n    // Añade un elemento al principio\n    conjunto.add(0, \"Z\")\n    println(\"Después de añadir al principio: $conjunto\")\n\n    // Añade varios elementos en bloque al final\n    conjunto.addAll(listOf(\"E\", \"F\", \"G\"))\n    println(\"Después de añadir en bloque al final: $conjunto\")\n\n    // Añade varios elementos en bloque en una posición concreta\n    conjunto.addAll(2, listOf(\"X\", \"Y\"))\n    println(\"Después de añadir en bloque en posición 2: $conjunto\")\n\n    // Elimina un elemento en una posición concreta\n    conjunto.removeAt(3)\n    println(\"Después de eliminar el elemento en posición 3: $conjunto\")\n\n    // Actualiza el valor de un elemento en una posición concreta\n    conjunto[1] = \"W\"\n    println(\"Después de actualizar el elemento en posición 1: $conjunto\")\n\n    // Comprueba si un elemento está en un conjunto\n    println(\"¿El conjunto contiene 'F'? ${conjunto.contains(\"F\")}\")\n\n    // Elimina todo el contenido del conjunto\n    conjunto.clear()\n    println(\"Después de eliminar todo el contenido: $conjunto\")\n\n    // DIFICULTAD EXTRA\n    val conjunto1 = setOf(1, 2, 3, 4, 5)\n    val conjunto2 = setOf(4, 5, 6, 7, 8)\n\n    // Unión\n    val union = conjunto1.union(conjunto2)\n    println(\"Unión: $union\")\n\n    // Intersección\n    val interseccion = conjunto1.intersect(conjunto2)\n    println(\"Intersección: $interseccion\")\n\n    // Diferencia\n    val diferencia = conjunto1.subtract(conjunto2)\n    println(\"Diferencia (conjunto1 - conjunto2): $diferencia\")\n\n    // Diferencia simétrica\n    val diferenciaSimetrica = conjunto1.symmetricDifference(conjunto2)\n    println(\"Diferencia simétrica: $diferenciaSimetrica\")\n}\n\n// Función de extensión para calcular la diferencia simétrica\nfun Set<Int>.symmetricDifference(other: Set<Int>): Set<Int> {\n    return (this subtract other) union (other subtract this)\n}"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/ocaml/luishendrix92.ml",
    "content": "open Printf\n\n(*****************************************************************************)\n(*                                                                           *)\n(*                            Set Data Structure                             *)\n(*                                                                           *)\n(*  Sets are a {e finite collection} of {b unique} data with roots in        *)\n(*  mathematics. The way sets are implemented allow for logarithmic-time     *)\n(*  access at the cost of slower write times than an array. Sets don't       *)\n(*  guarantee element order and they can't be repeated, they must be unique  *)\n(*  and depending on the language, of same type (mostly).                    *)\n(*    OCaml doesn't let you have sets of different types and the standard    *)\n(*  library implements them as functors, meaning, you need to pass a module  *)\n(*  to the [Set.Make] functor in order to get back a new module that is      *)\n(*  bound to the type that the passed module represent. Among the most       *)\n(*  popular modules to pass are [String], [Float], [Int], and [Char].        *)\n(*                                                                           *)\n(*  Set operations are:                                                      *)\n(*  - Union (A ∪ B): A set composed of all the elements from sets A and B.   *)\n(*  - Intersection (A ∩ B): Elements of A and B that appear on both sets.    *)\n(*  - Symmetric difference (A Δ B): All the elements of A and B that don't   *)\n(*  appear on both at the same time. Ex: {1,2,3} Δ {4,2,6} = {1,3,4,6}.      *)\n(*  - Difference (A - B): The elements of A without the ones that also       *)\n(*  appear on B; basically, subtration. Ex: {9,1,4,7} - {1,7,5,2} = {9,4}.   *)\n(*                                                                           *)\n(*****************************************************************************)\n\nmodule IntSet = Set.Make (Int)\n\nlet show_int_set s =\n  if IntSet.is_empty s\n  then \"∅\"\n  else\n    IntSet.to_list s\n    |> List.map string_of_int\n    |> String.concat \", \"\n    |> sprintf \"{ %s }\"\n;;\n\nlet tap str set =\n  printf str (show_int_set set);\n  set\n;;\n\n(** [symm_diff a b] is the symmetric difference between set [a] and set [b].\n    A symmetric difference can be described as the difference between the\n    union of [a] and [b], and their intersection. *)\nlet symm_diff a b = IntSet.diff (IntSet.union a b) (IntSet.inter a b)\n\nlet _ =\n  let b_set = IntSet.of_list [ 5; 10; 6; 0 ] in\n  let a_set =\n    IntSet.empty\n    |> tap \"Empty set: %s\\n\"\n    |> IntSet.add 8\n    |> tap \"After adding 1 element: %s\\n\"\n    |> IntSet.add_seq (List.to_seq [ 1; 5; 10 ])\n    (* NOTE: Adding elements to a certain position is irrelevant in an OCaml set\n       as they can't guarantee insertion order since the elements get sorted. *)\n    |> tap \"After adding multiple elements: %s\\n\"\n    |> IntSet.remove 8\n    |> tap \"After removing the number 8: %s\\n\"\n  in\n  printf\n    \"Union: A (%s) ∪ B (%s) = %s\\n\"\n    (show_int_set a_set)\n    (show_int_set b_set)\n    (IntSet.union a_set b_set |> show_int_set);\n  printf\n    \"Intersection: A (%s) ∩ B (%s) = %s\\n\"\n    (show_int_set a_set)\n    (show_int_set b_set)\n    (IntSet.inter a_set b_set |> show_int_set);\n  printf\n    \"Difference: B (%s) - A (%s) = %s\\n\"\n    (show_int_set b_set)\n    (show_int_set a_set)\n    (IntSet.diff b_set a_set |> show_int_set);\n  printf\n    \"Symmetric Difference: B (%s) Δ A (%s) = %s\\n\"\n    (show_int_set a_set)\n    (show_int_set b_set)\n    (symm_diff a_set b_set |> show_int_set);\n  printf\n    \"Is 0 an element of set B = %s? %b\\n\"\n    (show_int_set b_set)\n    (IntSet.mem 0 b_set);\n  printf \"Cardinality (elt. count) of set A: %d\\n\" (IntSet.cardinal a_set)\n;;\n\n(* Output of [dune exec reto18]\n\n   Empty set: ∅\n   After adding 1 element: { 8 }\n   After adding multiple elements: { 1, 5, 8, 10 }\n   After removing the number 8: { 1, 5, 10 }\n   Union: A ({ 1, 5, 10 }) ∪ B ({ 0, 5, 6, 10 }) = { 0, 1, 5, 6, 10 }\n   Intersection: A ({ 1, 5, 10 }) ∩ B ({ 0, 5, 6, 10 }) = { 5, 10 }\n   Difference: B ({ 0, 5, 6, 10 }) - A ({ 1, 5, 10 }) = { 0, 6 }\n   Symmetric Difference: B ({ 1, 5, 10 }) Δ A ({ 0, 5, 6, 10 }) = { 0, 1, 6 }\n   Is 0 an element of set B = { 0, 5, 6, 10 }? true\n   Cardinality (elt. count) of set A: 3\n*)\n\n(*****************************************************************************)\n(*                                                                           *)\n(*                         Implementation and Ordering                       *)\n(*                                                                           *)\n(* Sets can be implemented in 2 ways: with a tree-like data structure and    *)\n(* using a hash table. A binary properly balanced binary tree can give us    *)\n(* logarithmic access times and the traversal is done in orderly manner. In  *)\n(* OCaml's standard lib, [Set] is implemented with a binary tree and that's  *)\n(* why the module we pass to the functor must have a comparator function     *)\n(* called [compare]. If we were to implement a set that remembers insertion  *)\n(* order we could add both to a linked list and a b-tree or hash bucket.     *)\n(*   It's worth noting that if we wanted a data structure to add stuff to    *)\n(* either end (front/rear) or at a specific position then maybe we're better *)\n(* off with an array or a linked list which can be converted to a set at a   *)\n(* later time anyway (getting rid of duplicates).                            *)\n(*                                                                           *)\n(*****************************************************************************)\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/pascal/edalmava.pas",
    "content": "program Conjuntos;\nuses Crt;\n\ntype\n    Digitos = set of 0 .. 100;   // Tipos conjunto (set)\n\nvar\n    Impares, Primos, Set1 : Digitos;\n\nfunction mostrarSet(s : Digitos) : String;\nvar\n    i : Integer;\n    c : String;\n    num : String;\nbegin\n    c := '';\n    for i := 0 to 100 do\n        if i in s then\n        begin\n            if (c <> '') then c := c + ', ';\n            Str(i, num);\n            c := c + num;\n        end;\n    mostrarSet := '{' + c + '}';\nend;\n\nbegin\n    ClrScr;\n\n    Impares := [11, 13, 15, 17, 19, 21, 23, 25, 27, 29];\n    Primos := [1, 3, 5, 7, 11, 13, 17];\n\n    WriteLn('Dados dos conjuntos I = {11, 13, 15, 17, 19, 21, 23, 25, 27, 29} y P = {1, 3, 5, 7, 11, 13, 17}');\n    WriteLn('');\n\n    Set1 := Impares + Primos;\n\n    WriteLn('Union de conjuntos -> I + P = ' + mostrarSet(Set1));\n    WriteLn('');\n\n    WriteLn('Diferencia de conjuntos');\n    Set1 := Impares - Primos;\n    WriteLn('I - P = ' + mostrarSet(Set1));\n    Set1 := Primos - Impares;\n    WriteLn('P - I = ' + mostrarSet(Set1));\n    WriteLn('');\n\n    Set1 := Impares * Primos;\n    WriteLn('Interseccion de conjuntos -> I * P = ', mostrarSet(Set1));\n    WriteLn('');\n\n    Set1 := Impares >< Primos;\n    WriteLn('Diferencia simetrica de conjuntos -> I >< P = ', mostrarSet(Set1));\n    WriteLn('');\n\n    Include(Impares, 31);\n    WriteLn('Incluir el elemento 31 al conjunto I:');\n    WriteLn('I = ', mostrarSet(Impares));\n    WriteLn('');\n\n    Exclude(Primos, 17);\n    WriteLn('Excluir el elemento 17 al conjunto P:');\n    WriteLn('P = ', mostrarSet(Primos));\n    WriteLn('');\n\n    WriteLn('Verificar si el elemento 31 esta en el conjunto I : ', 31 in Impares);\n    WriteLn('Verificar si el elemento 17 esta en el conjunto P : ', 17 in Primos);\nend.\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/php/edalmava.php",
    "content": "<?php\n    $array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5];\n    \n    $set = new \\Ds\\Set($array); // Uso de la clase Set de la extensión PECL Ds\n\n    // https://www.php.net/manual/es/class.ds-set.php\n    // En mi caso particular descargue la extensión dll y añadi la extensión en php.ini\n\n    echo \"El conjunto tiene \", $set->count(), \" elementos\\n\";\n    \n    // Añadir un elemento al conjunto\n\n    $set->add(10);\n\n    // Añadir varios elementos al conjunto\n\n    $set->add(11, 12, 13);\n\n    echo \"Despues de añadir cuatro elementos el conjunto tiene ahora \", $set->count(), \" elementos\\n\";\n\n    // Verificar si un set contiene un elemento\n\n   echo \"El conjunto tiene el número 10: \", $set->contains(10)?\"true\":\"false\", \" \\n\";  // true\n   echo \"El conjunto tiene el número 15: \", $set->contains(15)?\"true\":\"false\", \" \\n\";  // false\n\n   // Remover un elemento del conjunto\n\n   $set->remove(0);\n\n   // Remover varios elementos del conjunto\n\n   $set->remove(10, 11, 12, 13); // Tambien se puede $set->remove(...[10, 11, 12, 13])\n\n   echo \"Tras eliminar algunos elementos, el conjunto ahora tiene: \", $set->count(), \" elementos\\n\";\n\n   // Eliminar todo el contenido del conjunto\n\n   $set->clear();\n\n   echo \"El conjunto después de eliminar todo el contenido tiene ahora \", $set->count(), \" elementos\\n\";\n\n   // RETO EXTRA\n\n   echo \"\\n*****RETO EXTRA*****\\n\";\n\n   // Creando dos conjuntos para mostrar varias operaciones con conjuntos\n   $M = new \\Ds\\Set([0, 1, 2, 3, 4, 5]);\n   $N = new \\Ds\\Set([6, 7, 8, 9, 2, 4]);\n\n   echo \"\\nDado los conjuntos M = {0, 1, 2, 3, 4, 5} y N = {6, 7, 8, 9, 2, 4}\\n\\n\";\n\n   // Diferencia de Conjuntos M \\ N\n   echo \"La diferencia M \\ N es: { \", $M->diff($N)->join(\",\"), \" }\\n\";\n   echo \"La diferencia N \\ M es: { \", $N->diff($M)->join(\",\"), \" }\\n\";\n\n   // Intersección de Conjuntos M ∩ N\n   echo \"La intersección entre los conjuntos es: { \", $M->intersect($N)->join(\",\"), \" }\\n\";\n\n   // Unión de Conjuntos M ∪ N \n   echo \"La unión de los conjuntos es: { \", $M->union($N)->join(\",\"), \" }\\n\";\n\n   // Diferencia simétrica de Conjuntos M ⊖ N\n   echo \"La diferencia simétrica (XOR) de los conjuntos es: { \", $M->xor($N)->join(\",\"), \" }\\n\";\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/php/eulogioep.php",
    "content": "<?php\n/**\n * TEORÍA: Conjuntos en PHP\n * \n * En PHP, no existe una estructura de datos específica para conjuntos como en otros lenguajes.\n * Sin embargo, podemos simular conjuntos usando arrays y algunas funciones específicas:\n * \n * 1. array_unique() - Para eliminar duplicados\n * 2. array_values() - Para reindexar arrays después de operaciones\n * 3. array_intersect() - Para intersección\n * 4. array_diff() - Para diferencia\n * 5. array_merge() - Para unión\n * \n * También usaremos la clase SplObjectStorage para demostrar una implementación\n * más orientada a objetos cuando sea necesario.\n */\n\nclass ConjuntosEjemplo {\n    private $conjunto;\n\n    public function __construct() {\n        $this->conjunto = [];\n    }\n\n    /**\n     * Muestra el contenido actual del conjunto\n     */\n    public function mostrarConjunto($mensaje = \"Conjunto actual\") {\n        echo \"$mensaje: [\" . implode(\", \", $this->conjunto) . \"]\\n\";\n    }\n\n    /**\n     * 1. Añade un elemento al final\n     */\n    public function agregarAlFinal($elemento) {\n        $this->conjunto[] = $elemento;\n        $this->conjunto = array_values(array_unique($this->conjunto));\n        $this->mostrarConjunto(\"Después de añadir '$elemento' al final\");\n    }\n\n    /**\n     * 2. Añade un elemento al principio\n     */\n    public function agregarAlPrincipio($elemento) {\n        array_unshift($this->conjunto, $elemento);\n        $this->conjunto = array_values(array_unique($this->conjunto));\n        $this->mostrarConjunto(\"Después de añadir '$elemento' al principio\");\n    }\n\n    /**\n     * 3. Añade varios elementos en bloque al final\n     */\n    public function agregarVariosAlFinal($elementos) {\n        $this->conjunto = array_values(array_unique(array_merge($this->conjunto, $elementos)));\n        $this->mostrarConjunto(\"Después de añadir varios elementos al final\");\n    }\n\n    /**\n     * 4. Añade varios elementos en bloque en una posición concreta\n     */\n    public function agregarVariosEnPosicion($elementos, $posicion) {\n        $primera_parte = array_slice($this->conjunto, 0, $posicion);\n        $segunda_parte = array_slice($this->conjunto, $posicion);\n        $this->conjunto = array_values(array_unique(array_merge($primera_parte, $elementos, $segunda_parte)));\n        $this->mostrarConjunto(\"Después de añadir varios elementos en posición $posicion\");\n    }\n\n    /**\n     * 5. Elimina un elemento en una posición concreta\n     */\n    public function eliminarEnPosicion($posicion) {\n        if (isset($this->conjunto[$posicion])) {\n            $elemento = $this->conjunto[$posicion];\n            unset($this->conjunto[$posicion]);\n            $this->conjunto = array_values($this->conjunto);\n            $this->mostrarConjunto(\"Después de eliminar elemento en posición $posicion\");\n        }\n    }\n\n    /**\n     * 6. Actualiza el valor de un elemento en una posición concreta\n     */\n    public function actualizarEnPosicion($posicion, $nuevoValor) {\n        if (isset($this->conjunto[$posicion])) {\n            $this->conjunto[$posicion] = $nuevoValor;\n            $this->conjunto = array_values(array_unique($this->conjunto));\n            $this->mostrarConjunto(\"Después de actualizar elemento en posición $posicion\");\n        }\n    }\n\n    /**\n     * 7. Comprueba si un elemento está en el conjunto\n     */\n    public function contiene($elemento) {\n        $resultado = in_array($elemento, $this->conjunto);\n        echo \"¿El conjunto contiene '$elemento'? \" . ($resultado ? \"Sí\" : \"No\") . \"\\n\";\n        return $resultado;\n    }\n\n    /**\n     * 8. Elimina todo el contenido del conjunto\n     */\n    public function limpiar() {\n        $this->conjunto = [];\n        $this->mostrarConjunto(\"Después de limpiar el conjunto\");\n    }\n\n    /**\n     * Obtiene el conjunto actual\n     */\n    public function obtenerConjunto() {\n        return $this->conjunto;\n    }\n}\n\n/**\n * Clase para operaciones extra con conjuntos\n */\nclass OperacionesExtra {\n    /**\n     * Unión de dos conjuntos\n     */\n    public static function union($conjunto1, $conjunto2) {\n        return array_values(array_unique(array_merge($conjunto1, $conjunto2)));\n    }\n\n    /**\n     * Intersección de dos conjuntos\n     */\n    public static function interseccion($conjunto1, $conjunto2) {\n        return array_values(array_intersect($conjunto1, $conjunto2));\n    }\n\n    /**\n     * Diferencia de dos conjuntos\n     */\n    public static function diferencia($conjunto1, $conjunto2) {\n        return array_values(array_diff($conjunto1, $conjunto2));\n    }\n\n    /**\n     * Diferencia simétrica de dos conjuntos\n     */\n    public static function diferenciaSimetrica($conjunto1, $conjunto2) {\n        $diff1 = array_diff($conjunto1, $conjunto2);\n        $diff2 = array_diff($conjunto2, $conjunto1);\n        return array_values(array_merge($diff1, $diff2));\n    }\n}\n\n// Demostración de uso\necho \"PARTE 1: OPERACIONES BÁSICAS\\n\";\n$demo = new ConjuntosEjemplo();\n\n$demo->agregarAlFinal(\"Elemento1\");\n$demo->agregarAlPrincipio(\"Elemento2\");\n$demo->agregarVariosAlFinal([\"Elemento3\", \"Elemento4\", \"Elemento5\"]);\n$demo->agregarVariosEnPosicion([\"ElementoA\", \"ElementoB\"], 2);\n$demo->eliminarEnPosicion(3);\n$demo->actualizarEnPosicion(1, \"ElementoActualizado\");\n$demo->contiene(\"Elemento1\");\n$demo->limpiar();\n\necho \"\\nPARTE 2: OPERACIONES EXTRA\\n\";\n$conjunto1 = [1, 2, 3, 4, 5];\n$conjunto2 = [4, 5, 6, 7, 8];\n\necho \"Conjunto 1: [\" . implode(\", \", $conjunto1) . \"]\\n\";\necho \"Conjunto 2: [\" . implode(\", \", $conjunto2) . \"]\\n\";\n\n$union = OperacionesExtra::union($conjunto1, $conjunto2);\necho \"Unión: [\" . implode(\", \", $union) . \"]\\n\";\n\n$interseccion = OperacionesExtra::interseccion($conjunto1, $conjunto2);\necho \"Intersección: [\" . implode(\", \", $interseccion) . \"]\\n\";\n\n$diferencia = OperacionesExtra::diferencia($conjunto1, $conjunto2);\necho \"Diferencia (conjunto1 - conjunto2): [\" . implode(\", \", $diferencia) . \"]\\n\";\n\n$diferenciaSimetrica = OperacionesExtra::diferenciaSimetrica($conjunto1, $conjunto2);\necho \"Diferencia simétrica: [\" . implode(\", \", $diferenciaSimetrica) . \"]\\n\";\n?>"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/php/gabrielmoris.php",
    "content": "<?php\n\n/*\n* Using your language, create a data set and perform the following operations (you must use a structure that supports them):\n* Add an element to the end.\n* Add an element to the beginning.\n* Add multiple elements in a block to the end.\n* Add multiple elements in a block to a specific position.\n* Delete an element at a specific position.\n* Update the value of an element at a specific position.\n* Check if an element is in a set.\n* Clear the entire contents of the set.\n*/\n$dataset = [[\"name\" => \"Gabriel\", \"language\" => \"javascript\"], [\"name\" => \"Sascha\", \"language\" => \"php\"]];\n// 1. Add an element to the end.\n$dataset[] = [\"name\" => \"Georg\", \"language\" => \"deutsch\"];\n// 2. Add an element to the beginning.\narray_unshift($dataset, [\"name\" => \"Matheus\", \"language\" => \"Portuguese\"]);\n// 3. Add multiple elements in a block to the end.\n$dataset = array_merge($dataset, [[\"name\" => \"Munch\", \"language\" => \"paintings\"], [\"name\" => \"Juan\", \"language\" => \"rust\"]]);\n// 4. Add multiple elements in a block to a specific position.\n$newElements = [[\"name\" => \"somebody\", \"language\" => \"somelanguage\"], [\"name\" => \"Mark\", \"language\" => \"C++\"]];\narray_splice($dataset, 1, 0, $newElements); // (original array, positiontoadd,number of elements to remove before the insertion,elements to add )\n// 5. Delete an element at a specific position.\nunset($dataset[1]); // this will delete the key an value, but will leave a gap in the order 0,2,3,4,...\n$dataset = array_values($dataset); // This would rearange the keys\n// 6. Update the value of an element at a specific position.\n$dataset[4] = [\"name\" => \"Kent C. Dodds\", \"language\" => \"Javascript\"];\n// 7. Check if an element is in a set.\necho in_array([\"name\" => \"Kent C. Dodds\", \"language\" => \"Javascript\"], $dataset) . \"\\n\"; // 1 means found\n// 8. Clear the entire contents of the set.\n$dataset = [];\necho empty($dataset) . \"\\n\"; // to check if it is empty\n\nvar_dump($dataset);\n/*\n* EXTRA DIFFICULTY (optional): \n* Show examples of the following operations with sets:\n* Union.\n* Intersection.\n* Difference.\n* Symmetric difference.\n*/\n/** @var object $set1 */\n$dataset1 = [[\"number\" => \"1\", \"letter\" => \"a\"], [\"number\" => \"2\", \"letter\" => \"b\"]];\n$dataset2 = [[\"number\" => \"2\", \"letter\" => \"b\"], [\"number\" => \"3\", \"letter\" => \"c\"], [\"number\" => \"4\", \"letter\" => \"d\"]];\n\n// 1. Union: combines the two datasets and removes duplicates.\n$union = array_merge($dataset1, $dataset2);\n$union = array_map(\"unserialize\", array_unique(array_map(\"serialize\", $union)));\necho \"Union: \";\nvar_dump($union);\n\n// 2. Intestection: finds elements that are common to both datasets.\n$intersection = array_uintersect($dataset1, $dataset2, 'compare_deep_value');\nfunction compare_deep_value($val1, $val2)\n{\n    return strcmp(serialize($val1), serialize($val2));\n}\necho \"Intersection: \";\nvar_dump($intersection);\n\n// 3. Difference: finds elements that are in the first dataset but not in the second.\n$difference = array_udiff($dataset1, $dataset2, 'compare_deep_value');\necho \"Difference: \";\nvar_dump($difference);\n\n// 4. Symmetric difference:  operation finds elements that are in either of the datasets but not in both.ç\n$symmetricDifference = array_merge(array_udiff($dataset1, $dataset2, 'compare_deep_value'), array_udiff($dataset2, $dataset1, 'compare_deep_value'));\necho \"Symetric difference: \";\nvar_dump($symmetricDifference);\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/php/miguelex.php",
    "content": "<?php\n\n    $conjunto = [1,2,3];\n\n    echo \"Vamos a mostrar el conjunto inicial: \\n\";\n    print_r($conjunto);\n    echo \"\\n\\n\";\n\n    $conjunto[] = 4;\n    \n    echo \"Vamos a mostrar el conjunto tras añadir 4 al final: \\n\";\n    print_r($conjunto);\n    echo \"\\n\\n\";\n\n    array_unshift($conjunto, 0);\n\n    echo \"Vamos a mostrar el conjunto tras añadir 0 al principio: \\n\";\n    print_r($conjunto);\n    echo \"\\n\\n\";\n\n    $nuevos = [5, 6, 7];\n    $conjunto = array_merge($conjunto, $nuevos); \n\n    echo \"Vamos a mostrar el conjunto tras añadir 5, 6 y 7 al final: \\n\";\n    print_r($conjunto);\n    echo \"\\n\\n\";\n\n    array_splice($conjunto, 2, 0, [0.5, 0.75]);\n\n    echo \"Vamos a mostrar el conjunto tras añadir 2.5 y 2.75 en la posición 2: \\n\";\n    print_r($conjunto);\n    echo \"\\n\\n\";\n\n    unset($conjunto[3]);\n\n    echo \"Vamos a mostrar el conjunto tras eliminar el elemento en la posición 3: \\n\";\n    print_r($conjunto);\n    echo \"\\n\\n\";\n\n    $conjunto[1] = 0.5;\n    echo \"Cambiamos el valor de la posición 1 por 0.5: \\n\";\n    print_r($conjunto);\n    echo \"\\n\\n\";\n\n    $elemento = 1.5;\n    if (in_array($elemento, $conjunto)) {\n        echo \"$elemento está en el conjunto.\";\n    } else {\n        echo \"$elemento no está en el conjunto.\";\n    }\n    echo \"\\n\\n\";\n\n    $conjunto = [];\n    echo \"Vamos a mostrar el conjunto tras vaciarlo: \\n\";\n    print_r($conjunto);\n    echo \"\\n\\n\";\n\n    // Extra\n\n    $conjunto1 = [1, 2, 3, 4];\n    $conjunto2 = [3, 4, 5, 6];\n\n    // Unión\n    $union = array_merge($conjunto1, $conjunto2);\n    \n    echo \"Vamos a mostrar la union de los dos conjuntos: \\n\";\n    print_r($union);\n    echo \"\\n\\n\";\n\n    // Intersección\n    $interseccion = array_intersect($conjunto1, $conjunto2);\n\n    echo \"Vamos a mostrar la interseccion de los dos conjuntos: \\n\";\n    print_r($interseccion);\n    echo \"\\n\\n\";\n    // Diferencia\n    $diferencia = array_diff($conjunto1, $conjunto2);\n\n    echo \"Vamos a mostrar la diferencia de los dos conjuntos: \\n\";\n    print_r($diferencia);\n    echo \"\\n\\n\";\n\n    // Diferencia simétrica\n    $diferencia_simetrica = array_merge(array_diff($conjunto1, $conjunto2), array_diff($conjunto2, $conjunto1));\n\n    echo \"Vamos a mostrar la diferencia simetrica de los dos conjuntos: \\n\";\n    print_r($diferencia_simetrica);\n    echo \"\\n\\n\";\n\n\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/AChapeton.py",
    "content": "letters = ['a', 'b', 'c', 'd']\nprint('Original', letters)\n\n# Añade un elemento al final.\nletters.append('e')\nprint('Añade un elemento al final', letters)\n\n# Añade un elemento al principio.\nletters.insert(0, '-')\nprint('Añade un elemento al principio', letters)\n\n# Añade varios elementos en bloque al final.\nnewLetters = ['x', 'y', 'z']\nletters.extend(newLetters)\nprint('Añade varios elementos en bloque al final', letters)\n\n# Añade varios elementos en bloque en una posición concreta.\nnewLetters2 = ['f', 'g', 'h']\nfor letter in reversed(newLetters2):\n  letters.insert(6, letter)\nprint('Añade varios elementos en bloque en una posición concreta', letters)\n\n# Elimina un elemento en una posición concreta.\nletters.pop(5)\nprint('Elimina un elemento en una posición concreta', letters)\n\n# Actualiza el valor de un elemento en una posición concreta.\nletters[1] = '#'\nprint('Actualiza el valor de un elemento en una posición concreta', letters)\n\n# Comprueba si un elemento está en un conjunto.\ntry:\n  print('Comprueba si el elemento -a- está en el conjunto letters (buscar posicion)', letters.index('a'))\nexcept ValueError:\n  print('El elemento -a- no existe')\n\ntry:\n  print('Comprueba si el elemento -b- está en el conjunto letters (buscar posicion)', letters.index('b'))\nexcept ValueError:\n  print('El elemento -a- no existe')\n\n# Elimina todo el contenido del conjunto.\nletters.clear()\nprint('Elimina todo el contenido del conjunto', letters)\n\n\n# DIFICULTAD EXTRA\\\n\n# Union\nfirst ={1, 2, 3, 4}\nsecond = {3, 4, 5, 6}\nunion = first.union(second)\nprint('Union', union)\n\n# Interseccion\ninterseccion = first.intersection(second)\nprint('Interseccion', interseccion)\n\n# Diferencia\ninterseccion = first.difference(second)\nprint('Diferencia', interseccion)\n\n# Diferencia simetrica\ninterseccion = first.symmetric_difference(second)\nprint('Diferencia simetrica', interseccion)"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/Aldroide.py",
    "content": "\"\"\"\n    Ejercicio\n    Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n    operaciones (debes utilizar una estructura que las soporte):\n    * Añade un elemento al final.\n    * Añade un elemento al principio.\n    * Añade varios elementos en bloque al final.\n    * Añade varios elementos en bloque en una posición concreta.\n    * Elimina un elemento en una posición concreta.\n    * Actualiza el valor de un elemento en una posición concreta.\n    * Comprueba si un elemento está en un conjunto.\n    * Elimina todo el contenido del conjunto.\n\"\"\"\nmy_set1 = set(['Anahi', 'Sebastian', 'Samira', 'Emmanuel'])\nprint(my_set1)\n\n# Añadir un elemento\nmy_set1.add('Erwin')\nprint(f\"Añadimos Erwin: {my_set1}\")\n# Eliminar elemento\nmy_set1.remove('Anahi')\nprint(f\"Se removio Anahi: {my_set1}\")\n\n\n\"\"\"\n    EJERCICIO EXTRA:\n    * Muestra ejemplos de las siguientes operaciones con conjuntos:\n    * Unión.\n    * Intersección.\n    * Diferencia.\n    * Diferencia simétrica.\n\"\"\"\nmy_set1 = set([1, 2, 3, 4])\nmy_set2 = set([3, 4, 5, 6])\n\nprint(f\"\\nSets a usar {my_set1} y {my_set2}\")\nmysetR = my_set1.union(my_set2)\nprint(f\"Union {mysetR}\")\n\nmysetR = my_set1.intersection(my_set2)\nprint(f\"Interseccion {mysetR}\")\n\nmysetR = my_set1.difference(my_set2)\nprint(f\"diferencia {mysetR}\")\n\nmysetR = my_set1.symmetric_difference(my_set2)\nprint(f\"Diferencia simetrica {mysetR}\")\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/CaveroBrandon.py",
    "content": "\"\"\"Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\noperaciones (debes utilizar una estructura que las soporte):\n- Añade un elemento al final.\n- Añade un elemento al principio.\n- Añade varios elementos en bloque al final.\n- Añade varios elementos en bloque en una posición concreta.\n- Elimina un elemento en una posición concreta.\n- Actualiza el valor de un elemento en una posición concreta.\n- Comprueba si un elemento está en un conjunto.\"\"\"\n\n\nclass DataCollection:\n    def __init__(self):\n        self.my_list = list()\n\n    def show_list(self):\n        print(self.my_list)\n\n    def add_an_element_to_the_end(self, element):\n        self.my_list.append(element)\n        self.show_list()\n\n    def add_an_element_to_the_beginning(self, element):\n        self.my_list.insert(0, element)\n        self.show_list()\n\n    def add_multiple_elements_to_the_end(self, *args):\n        elements_to_add = list(args)\n        self.my_list.extend(elements_to_add)\n        self.show_list()\n\n    def add_multiple_elements_to_the_beginning(self, *args):\n        elements_to_add = list(args)\n        self.my_list[:0] = elements_to_add\n        self.show_list()\n\n    def add_multiple_elements_to_a_given_position(self, position: int, *args):\n        elements_to_add = list(args)\n        self.my_list[position:position] = elements_to_add\n        self.show_list()\n\n    def remove_elements_from_a_given_position(self, position: int):\n        self.my_list.pop(position)\n        self.show_list()\n\n    def update_element_given_a_position(self, position: int, new_value):\n        self.my_list[position] = new_value\n        self.show_list()\n\n    def verify_that_an_element_is_available(self, element) -> bool:\n        if element not in self.my_list:\n            return False\n        return True\n\n    def convert_list_to_a_set(self):\n        my_set = set(self.my_list)\n        print(my_set)\n\n    def remove_all_content(self):\n        self.my_list = []\n        self.show_list()\n\n\"\"\"DIFICULTAD EXTRA (opcional): \nMuestra ejemplos de las siguientes operaciones con conjuntos:\n- Unión.\n- Intersección.\n- Diferencia.\n- Diferencia simétrica.\"\"\"\n\n\ndef set_union():\n    set_a = {1, 2, 3, 4}\n    set_b = {2, 3, 4, 5}\n    set_result = set_a | set_b\n    print(f'{set_a} Union {set_b} = {set_result}')\n\n\ndef set_intersection():\n    set_a = {1, 2, 3, 4}\n    set_b = {2, 3, 4, 5}\n    set_result = set_a & set_b\n    print(f'{set_a} Intersection {set_b} = {set_result}')\n\n\ndef set_difference():\n    set_a = {1, 2, 3, 4}\n    set_b = {2, 3, 4, 5}\n    set_result = set_a - set_b\n    print(f'{set_a} Difference {set_b} = {set_result}')\n\n\ndef set_symmetric_difference():\n    set_a = {1, 2, 3, 4}\n    set_b = {2, 3, 4, 5}\n    set_result = set_a ^ set_b\n    print(f'{set_a} Symmetric Difference {set_b} = {set_result}')\n\n\nmy_collection = DataCollection()\n\nmy_collection.add_an_element_to_the_end(100)\nmy_collection.add_an_element_to_the_beginning(2)\nmy_collection.add_multiple_elements_to_the_end(10, 20, 30)\nmy_collection.add_multiple_elements_to_the_beginning(1, 2, 3)\nmy_collection.add_multiple_elements_to_a_given_position(2, 11, 22, 33)\nmy_collection.remove_elements_from_a_given_position(3)\nmy_collection.update_element_given_a_position(3, 'x')\nprint(my_collection.verify_that_an_element_is_available('x'))\nmy_collection.convert_list_to_a_set()\n\nprint('\\n**** EXTRA ****')\nset_union()\nset_intersection()\nset_difference()\nset_symmetric_difference()\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/CesarCarmona30.py",
    "content": "'''\n  EJERCICIO\n'''\n\nmy_list = [1, 2, 3, 'c', True, 'texto']\nprint(f'Lista original:\\n{my_list}')\n# - Añade un elemento al final.\nmy_list.append('elemento final')\nprint(f'Lista después de agregar un elemento al final:\\n{my_list}')\n# - Añade un elemento al principio.\nmy_list.insert(0, 'primer elemento')\nprint(f'Lista después de agregar un elemento al principio:\\n{my_list}')\n# - Añade varios elementos en bloque al final.\nmy_list.extend(\"Mundo\")\nprint(f'Lista después de agregar varios elementos al final:\\n{my_list}')\n# - Añade varios elementos en bloque en una posición concreta.\nmy_list[8:8] = \"Hola\"\nprint(f'Lista después de agregar varios elementos en una posición concreta:\\n{my_list}')\n# - Elimina un elemento en una posición concreta.\ndel my_list[3]\nprint(f'Lista después de1 eliminar un elemento en una posición concreta:\\n{my_list}')\n# - Actualiza el valor de un elemento en una posición concreta.\nmy_list[5] = 'Py'\nprint(f'Lista después de actualizar un elemento en una posición concreta:\\n{my_list}')\n# - Comprueba si un elemento está en un conjunto.\nprint(f'6 esta en la lista?: {6 in my_list}')\n# - Elimina todo el contenido del conjunto.\nmy_list.clear()\nprint(f'Lista después de eliminar todo su contenido:\\n{my_list}')\n\n'''\n  EXTRA\n'''\n\nA = {12, 45, 76, 24, 65, 75, 13, 54}\nB = {56, 65, 12, 13, 67, 23, 87, 23}\n\nprint(f'''\nDado los siguientes conjuntos:\n  A = {A}\n  B = {B}\nEstas son su operaciones entre ellos: ''')\n\nprint(f'''\nUnión: A U B = {A | B}\nTodo elemento tal que pertence a por lo menos uno de los conjuntos\nIntersección: A ∩ B = {A & B}\nTodo elemento que pertenece a ambos conjuntos\nDiferencia: A - B = {A - B}\nTodos los elementos de A que no estan en B\nDiferencia: B - A = {B - A}\nTodos los elementos de B que no estan en A\nDiferencia simétrica: A Δ B = {A ^ B}\nTodos los elementos que estan en A o en B pero\nno en ambos a la vez\n''')"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/Chrisdev00.py",
    "content": "\"\"\"\n* EJERCICIO:\n* Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n* operaciones (debes utilizar una estructura que las soporte):\n* - Añade un elemento al final.\n* - Añade un elemento al principio.\n* - Añade varios elementos en bloque al final.\n* - Añade varios elementos en bloque en una posición concreta.\n* - Elimina un elemento en una posición concreta.\n* - Actualiza el valor de un elemento en una posición concreta.\n* - Comprueba si un elemento está en un conjunto.\n* - Elimina todo el contenido del conjunto.\n*\n* DIFICULTAD EXTRA (opcional):\n* Muestra ejemplos de las siguientes operaciones con conjuntos:\n* - Unión.\n* - Intersección.\n* - Diferencia.\n* - Diferencia simétrica.\n\"\"\"\n\nmy_list = [\"Python\", \"Java\", \"Kotlin\"]\n\nmy_list.append(\"Php\")                # Añade un elemento al final de la lista\nprint(my_list)\n\nmy_list.insert(0, \"JavaScript\")      # Añade un elemento en un especifico indice de la lista en esta caso al principio\nprint(my_list)\n\nmy_list.extend([\"C++\", \"Html\", \"Ruby\"])   # Añade varios elementos en bloque al final\nprint(my_list)\n\nindex_pos = 2\nmy_list[index_pos:index_pos]= [\"swift\", \"typescript\"]  # Añade elementos en bloque en una posicion concreta\nprint(my_list)\n\ndel my_list[3]                              # Elimina un elemento en una posicion concreta\nprint(my_list)\n\nmy_list[1] = \"Html\"                         # Actualiza el valor de un elemento en una posición concreta.\nprint(my_list)\n\nitem_to_check = \"Python\"\nin_list = item_to_check in my_list          # Comprueba si un elemento esta en un conjunto\nprint(f\"El elemento {item_to_check} esta en la lista? {in_list}\")\n\nmy_list.clear()                             # Elimina todos los elementos de una lista\nprint(my_list)\n\n\n\n########### -------------------------- EXTRA --------------------------------- ####################\n\n# Union\n\nmy_set = {\"orange\", \"banana\", \"apple\"}\nmy_other_set = {\"mango\", \"lemon\", \"pineapple\"}\nresult = my_set.union(my_other_set)\nprint(result)\n\n# Interseccion\n\npython = {'p', 'y', 't', 'h', 'o','n'}\ntypescript = {'t', 'y', 'p', 'e', 's','c','r','i','p','t'}\nprint(python.intersection(typescript))\n\n# Diferencia\n\nset_one = {\"elem1\", \"elem2\", \"elem3\", \"elem4\"}\nset_two = {\"elem2\", \"elem3\"}\n\nprint(set_one.difference(set_two))\nprint(set_two.difference(set_one))\n\n# Diferencia simetrica\n\npython = {'p', 'y', 't', 'h', 'o','n'}\ntypescript = {'t', 'y', 'p', 'e', 's','c','r','i','p','t'}\nprint(python.symmetric_difference(typescript))\n\n# se actualiza para contener la diferencia simétrica entre typescript y python\n\ntypescript.symmetric_difference_update(python)\nprint(typescript)"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/Complex303.py",
    "content": "\"\"\"Conjuntos\n\"\"\"\n\n#Un conjunto (o set) es una colección de elementos no ordenados, sin elementos repetidos, y que admite operaciones matemáticas como unión, intersección, diferencia, etc.\n\ndata = [2,3,4,5,6]\nprint(f\"Estructura inicial {data}\")\n\n\ndata.append(7)\nprint(f\"Añadiendo elemento al final {data}\")\n\n\ndata.insert(0,1)\nprint(f\"Añadiendo elemento al principio {data}\")\n\ndata.extend([8,9,10])\nprint(f\"Añadiendo elementos al final {data}\")\n\ndata[3:3] = [3.2, 3.6, 3.8]\nprint(f\"Añadiendo elementos en una posicion {data}\")\n\ndel data[4]\nprint(f\"Eliminando un elemento concreto {data}\")\n\ndata[3] = 3.4\nprint(f\"Actualizando un elemento concreto {data}\")\n\nprint(f\"Comprobar si un elemento existe {3.2 in data}\")\n\nprint(f\"Eliminar el contenido {data.clear()}\")\n\n\n\n\"\"\" * DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Unión.\n * - Intersección.\n * - Diferencia.\n * - Diferencia simétrica.\"\"\"\n\n\nsets_1 = {1,2,3,4}\nsets_2 = {1,2,3,5,6,7}\n\n#Une todos los elementos de ambos conjuntos (sin repetidos).\nprint(f\"Union: {sets_1.union(sets_2)}\")\nprint(f\"union {sets_1 | sets_2}\")\n\n#Elementos que están en ambos conjuntos.\nprint(f\"Intersección: {sets_1.intersection(sets_2)}\")\nprint(f\"Intersección: {sets_1 & sets_2}\")\n\n#Elementos que están en A pero no en B.\nprint(f\"Diferencia: {sets_1.difference(sets_2)}\")\nprint(f\"Diferencia: {sets_1 - sets_2}\")\n\n#Elementos que están en A o B, pero no en ambos.\nprint(f\"Diferencia asimetrica: {sets_1.symmetric_difference(sets_2)}\")\nprint(f\"Diferencia asimetrica: {sets_1 ^ sets_2}\")\n\n\n#convertir una lista conjunto\nlista = [1, 2, 3, 4, 3, 2, 5]\nconjunto = set(lista)\n\nprint(conjunto)\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/DaniQB99.py",
    "content": "'''\nEJERCICIO:\nUtilizando tu lenguaje crea un conjunto de datos y realiza las \nsiguientes operaciones (debes utilizar una estructura que las soporte):\n\n- Añade un elemento al final.\n- Añade un elemento al principio.\n- Añade varios elementos en bloque al final.\n- Añade varios elementos en bloque en una posición concreta.\n- Elimina un elemento en una posición concreta.\n- Actualiza el valor de un elemento en una posición concreta.\n- Comprueba si un elemento está en un conjunto.\n- Elimina todo el contenido del conjunto.\n\n\nDIFICULTAD EXTRA (opcional):\nMuestra ejemplos de las siguientes operaciones con conjutos:\n- Unión.\n- Intersección.\n- Diferencia.\n- Diferencia simétrica.\n'''\n\ndef conjunto_datos():\n    \n    data = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']\n    set1 = set()\n    set2 = set()\n            \n    while True:\n        \n        def sets():\n            set1_input = input(\"Indica el conjunto 1 (Separados por coma): \")\n            set1 = {int(num.strip()) for num in set1_input.split(\",\") if num.strip().isdigit()}  # Asegura que sean enteros\n\n            set2_input = input(\"Indica el conjunto 2 (Separados por coma): \")\n            set2 = {int(num.strip()) for num in set2_input.split(\",\") if num.strip().isdigit()}\n\n            return set1, set2\n    \n        switch = input(\"\"\"\\nElige una de las siguientes opciones:\n            1- Añade un elemento al final\n            2- Añade un elemento al principio\n            3- Añade varios elementos en bloque al final\n            4- Añade varios elementos en bloque en una posición concreta\n            5- Elimina un elemento en una posición concreta\n            6- Actualiza el valor de un elemento en una posición concreta\n            7- Comprueba si un elemento está en un conjunto\n            8- Elimina todo el contenido del conjunto\n            9- Unión\n            10- Intersección\n            11- Diferencia \n            12- Diferencia simétrica  \n            13- Salir \\n\"\"\")\n        \n        # ----- EJERCICIOS -----\n        \n        # Unión al final\n        if switch == \"1\":\n            data.append(input(\"Añade un elemento al final: \"))\n            print(data)\n        \n        # Unión al principio\n        elif switch == \"2\":\n            data.insert(0, input(\"Añade un elemento al principio: \"))\n            print(data)\n            \n        # Union en bloque al final\n        elif switch == \"3\":\n            final_block = input(\"Añade varios elementos en bloque al final: \")\n            data.extend(final_block)\n            print(data)\n           \n        # Union en bloque en una posición concreta\n        elif switch == \"4\":\n            block = input(\"Añade varios elementos separados por coma en bloque en una posición concreta: \")\n            block = [str(num.strip()) for num in block.split(\",\")]  # Convierte el input en una lista de strings\n            position = int(input(\"Indica la posición: \"))\n\n            if position > len(data):\n                print(\"Posición incorrecta\")\n                continue\n\n            data[position:position] = block # Inserta los valores en la posición indicada\n            print(data)\n          \n        # Elimina un elemento en una posición concreta\n        elif switch == \"5\":\n            print(data)\n            element_remove = input(\"Indica la posición del elemento a eliminar: \")\n            del data[int(element_remove)]\n            print(data)\n\n        # Actualiza el valor de un elemento en una posición concreta\n        elif switch == \"6\":\n            print(data)\n            data[int(input(\"Indica la posición: \"))] = input(\"Actualiza el valor de un elemento en una posición concreta: \")\n            print(data)\n          \n        # Comprueba si un elemento está en un conjunto\n        elif switch == \"7\":\n            print(data)\n            element_find = input(\"Indica el elemento a buscar: \")\n            if element_find in data:\n                print(\"El elemento está en el conjunto\")\n            else: \n                print(\"El elemento no está en el conjunto\")\n            \n        # Elimina todo el contenido del conjunto\n        elif switch == \"8\":\n            data.clear()\n            print(data)\n            \n            \n        # ----- EJERCICIOS EXTRA -----\n            \n        \n        # Unión\n        elif switch == \"9\":  \n            set1, set2 = sets()  # Asignamos  los valores de la función a set1 y set2\n            print(f\"La unión de {set1} y {set2} es:\", set1.union(set2) )\n         \n        # Intersección\n        elif switch == \"10\":\n            set1, set2 = sets()  \n            print(f\"La intersección de {set1} y {set2} es:\", set1.intersection(set2))\n            \n        # Diferencia \n        elif switch == \"11\":\n            set1, set2 = sets() \n            \n            print(f\"La diferencia de {set1} y {set2} es:\", set1.difference(set2))\n           \n        # Diferencia simétrica\n        elif switch == \"12\":\n            set1, set2 = sets()\n            print(f\"La diferencia simétrica de {set1} y {set2} es:\", set1.symmetric_difference(set2))\n            \n        # Salir   \n        elif switch == \"13\":\n            exit()\n            \n        # Error\n        else:\n            print(f\"Opción {switch} no disponible\")\n            \nconjunto_datos()"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/EmmanuelMMontesinos.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n * operaciones (debes utilizar una estructura que las soporte):\n * x Añade un elemento al final.\n * x Añade un elemento al principio.\n * x Añade varios elementos en bloque al final.\n * x Añade varios elementos en bloque en una posición concreta.\n * x Elimina un elemento en una posición concreta.\n * x Actualiza el valor de un elemento en una posición concreta.\n * x Comprueba si un elemento está en un conjunto.\n * x Elimina todo el contenido del conjunto.\n */\n\"\"\"\n\n'''Base'''\n# Conjuntos\n# Pensaba que se referia a sets {}, pero al ver los requerimientos he visto que se refiere a conjunto de datos simplemente\n\nmi_conjunto = [\"Hola\",1,False]\nprint(mi_conjunto)\n\n# Añadir Elementos\n'''Inicio'''\nmi_conjunto.insert(0, \"Nuevo Elemento Principio\")\nprint(mi_conjunto)\n'''Final'''\nmi_conjunto.append(\"Nuevo Elemento Final\")\nprint(mi_conjunto)\n'''Varios al Final'''\nmi_conjunto.extend([\"Varios1\",\"Varios2\"])\nprint(mi_conjunto)\n\n'''Varios en Posición Concreta'''\nmi_conjunto[1:1] = [\"Varios3\",\"Varios4\"]\nprint(mi_conjunto)\n\n# Eliminar Elementos\nmi_conjunto.remove(mi_conjunto[4])\nprint(mi_conjunto)\n\n# Actualizar Elemento\nmi_conjunto[4] = True\nprint(mi_conjunto)\n\n# Comprobación de Elemento\nelemento_comprobar = \"Varios3\"\nprint(f\"¿{elemento_comprobar} esta en el conjunto?: {elemento_comprobar in mi_conjunto}\")\n\n# Borrar todo el conjunto\nmi_conjunto.clear()\nprint(mi_conjunto)\n\n'''\n * DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * x Unión.\n * x Intersección.\n * x Diferencia.\n * x Diferencia simétrica.\n'''\n\nconjunto_1 = [1,\"2\",False,\"3\",4]\nconjunto_2 = [1,\"2\",False,3,\"4\"]\n\n# Union\nunion = list(set(conjunto_1).union(conjunto_2))\nprint(union)\n\n# Intersección\ninterset = list(set(conjunto_1).intersection(conjunto_2))\nprint(interset)\n\n# Diferencia\ndeffe_1 = list(set(conjunto_1).difference(conjunto_2))\ndeffe_2 = list(set(conjunto_2).difference(conjunto_1))\nprint(deffe_1)\nprint(deffe_2)\n\n# Diferencia simetrica\nsimetrica = list(set(conjunto_1).symmetric_difference(conjunto_2))\nprint(simetrica)\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/FedeAirala.py",
    "content": "# #18 CONJUNTOS\n\n\n\"\"\"\n * EJERCICIO:\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n * operaciones (debes utilizar una estructura que las soporte):\n * - Añade un elemento al final.\n * - Añade un elemento al principio.\n * - Añade varios elementos en bloque al final.\n * - Añade varios elementos en bloque en una posición concreta.\n * - Elimina un elemento en una posición concreta.\n * - Actualiza el valor de un elemento en una posición concreta.\n * - Comprueba si un elemento está en un conjunto.\n * - Elimina todo el contenido del conjunto.\n\"\"\"\ndata_set = [1,2,3,4,5,6]\nprint (f\"Datos de la lista: {data_set}\")\n\ndata_set.append(7)\nprint (f\"Elemento añadido al final de la lista: {data_set}\")\n\ndata_set.insert(0,0)\nprint (f\"Elemento añadido al principio de la lista: {data_set}\")\n\n\ndata_set.extend([8,9,10])\nprint (f\"Elementos añadidos en bloque un posición específica de la lista: {data_set}\")\n\n\ndata_set[2:2]=[\"a\",\"b\"]\nprint (f\"Elementos añadidos en bloque un posición específica de la lista: {data_set}\")\n\ndel data_set[3]\nprint (f\"Elimina un elemento en una posición concreta de la lista: {data_set}\")\n\ndata_set[10]=\"z\"\nprint (f\"Actualiza el valor de un elemento en una posición concreta de la lista: {data_set}\")\n\nprint (f\" Comprueba si un elemento está en la lista {'a' in data_set}\")\n\nprint (f\"Conjunto eliminado, contenido de la lista:  {data_set.clear()}\")\n\"\"\"\n *\n * DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Unión.\n * - Intersección.\n * - Diferencia.\n * - Diferencia simétrica.\n \"\"\"\n\n\nset_a = {'a','b','c','d'}\nset_b = {'a','b','e','f'}\n\nprint (set_a)\nprint (set_b)\nprint (f\"Unión : {set_a.union(set_b)}\")\nprint (f\"Intersección : {set_a.intersection(set_b)}\")\nprint (f\"Diferencia a - b : {set_a.difference(set_b)}\")\nprint (f\"Diferencia b - a : {set_b.difference(set_a)}\")\nprint (f\"Diferencia simétrica : {set_a.symmetric_difference(set_b)}\")"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/Gallitofast.py",
    "content": "# * Ejercicio 18 Conjuntos\n#  * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n#  * operaciones (debes utilizar una estructura que las soporte):\n#  * - Añade un elemento al final.\n#  * - Añade un elemento al principio.\n#  * - Añade varios elementos en bloque al final.\n#  * - Añade varios elementos en bloque en una posición concreta.\n#  * - Elimina un elemento en una posición concreta.\n#  * - Actualiza el valor de un elemento en una posición concreta.\n#  * - Comprueba si un elemento está en un conjunto.\n#  * - Elimina todo el contenido del conjunto.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Muestra ejemplos de las siguientes operaciones con conjuntos:\n#  * - Unión.\n#  * - Intersección.\n#  * - Diferencia.\n#  * - Diferencia simétrica.\n\ngalloconjunto =[1,2,3,4]\nprint(f\"Galloconjuntos inicio con {galloconjunto}\")\ngalloconjunto.append(4) #Insertando dato al final\nprint(f\"Galloconjuntos inserto un dato al final{galloconjunto}\")\ngalloconjunto.insert(0,0) #Insertando un elemento al principio\nprint(f\"Galloconjunto inserto un dato al principio {galloconjunto}\")\ngalloconjunto.extend([9,9,9])\nprint(f\"Se añadieron tres 9 al final del galloconjunto: {galloconjunto}\")\ngalloconjunto[2:2]=[5,5,5]\nprint(f\"Se añadieron tres \\\"5\\\" en una posicion concreta {galloconjunto}\")\ndel galloconjunto [-1::]\nprint(f\"Se elimino un conjunto en especifico {galloconjunto}\")\ngalloconjunto[0]=0\nprint(f\"Se actualizo un valor\")\n\n\nprint(f\"Comprobar si elemento existe {0 in galloconjunto}\")\nprint(f\"Eliminar contenido {galloconjunto.clear()}\")\nprint(f\"Ahora galloconjunto es: {galloconjunto}\")\n\n\"\"\"Dificultad extra\"\"\"\n\nconjunto_1={0,1,2,3,4,5,6}\nconjunto_2={4,5,6,7,8,9,10}\n\nprint(f\"Union {conjunto_1.union(conjunto_2)}\")\n\nprint(f\"Interseccion {conjunto_1.intersection(conjunto_2)}\")\nprint(f\"Diferencia: {conjunto_1.difference(conjunto_2)}\")\nprint(f\"Diferencia: {conjunto_2.difference(conjunto_1)}\")\nprint(f\"Diferencia simetrica: {conjunto_1.symmetric_difference(conjunto_2)}\")\n\nprint(f\"Haciendo mi propia diferencia simetrica: {[conjunto_1.difference(conjunto_2)]+[conjunto_2.difference(conjunto_1)]}\")\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/Gordo-Master.py",
    "content": "# 18 - Conjuntos\n\nconjunto = {\"a\",\"e\",\"i\",\"o\",\"u\"}\nprint(conjunto)\n\n# En los conjuntos no se repiten los valores y no esta en orden los valores.\n\n# Añadir un elemento:\nconjunto.add(\"b\")\nprint(conjunto)\n\n# Añade varios elementos\nconjunto.update([\"c\",\"d\",\"f\",\"g\",\"h\",\"j\",\"k\",\"l\",\"m\",\"n\",\"p\",\"q\",\"r\",\"s\",\"t\",\"v\",\"w\",\"x\",\"y\",\"z\"])\nprint(conjunto)\n\n# Eliminar un elemento\nconjunto.remove(\"x\") # Genera un error si no se encuentra el elemento\nprint(conjunto)\nconjunto.discard(\"y\") # No genera error si no se encuentra el elemento\nprint(conjunto)\nprint(conjunto.pop()) # Es aleatorio el que remueve\nprint(conjunto)\n\n# Comprueba si un elemento se encuentra en el conjunto\nprint(\"d\" in conjunto)\n\n# Limpia el conjunto\nconjunto.clear()\nprint(conjunto)\n\n\"\"\"\nParte corregida con la trampa de Brais\n\"\"\"\n\ndata = [1, 2, 3, 4, 5]\nprint(data)\n\n# Añade un elemento\ndata.append(6)\nprint(data)\n\n# Añade al principio\ndata.insert(0,0)\nprint(data)\n\n# Añade varios elementos al final\ndata.extend([9,10])\nprint(data)\n\n# Añade varios elementos en una posición\ndata[7:7]=[7,8]\nprint(data)\n\n# Actualiza un posición en concreto\ndata[3]=-3\nprint(data)\n\n# Elimina un dato segun su posición\nprint(data.pop(7))\nprint(data)\ndel data[1]\nprint(data)\n\n# Comprueba que el valor este\nprint(4 in data)\n\n# Vaciar\nprint(data.clear())\n\n\"\"\"\nEjercicio Extra\n\"\"\"\n\nconj_1 = set([i for i in range(2,31,2)])\nconj_2 = set([i for i in range(3,31,3)])\n\nprint(conj_1)\nprint(conj_2)\n\n# Union\nprint(conj_1.union(conj_2))\nprint(conj_1|conj_2)\n\n# Intersección\nprint(conj_1.intersection(conj_2))\nprint(conj_1&conj_2)\n\n# Diferencia\nprint(conj_1.difference(conj_2))\nprint(conj_1 - conj_2)\n\n# Diferencia simetrica\nprint(conj_1.symmetric_difference(conj_2))\nprint(conj_1^conj_2)"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/Hyromy.py",
    "content": "conjunto = [1, 2, 3, 4, 5] # ya se que es una lista y no un conjunto\nprint(conjunto)\n\nconjunto.append(\"A\")\nprint(conjunto)\n\nconjunto.insert(0, \"b\")\nprint(conjunto)\n\nconjunto.extend([-1, -2, -3])\nprint(conjunto)\n\nblock = [\"x\", \"y\", \"z\"]\nfor i, item in enumerate(block):\n    conjunto.insert(i + 3, item)\nprint(conjunto)\n\nconjunto.pop(5)\nprint(conjunto)\n\nconjunto[7] = \"C\"\nprint(conjunto)\n\nprint(-1 in conjunto)\nprint(5 in conjunto)\n\nconjunto.clear()\n\n# ---- DIFUCULTAD EXTRA ----\nconjunto_a = {1, 2, 3, 4, 5}\nconjunto_b = {4, 5, 6, 7, 8}\n\nprint(conjunto_a.union(conjunto_b)) # unir ambos conjuntos\nprint(conjunto_a.intersection(conjunto_b)) # elementos comunes\nprint(conjunto_a.difference(conjunto_b)) # elementos en A que no estan en B\nprint(conjunto_b.difference(conjunto_a)) # elementos en B que no estan en A\nprint(conjunto_a.symmetric_difference(conjunto_b)) # insertesecion inversa"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/Irenetitor.py",
    "content": "#Exercise\ndata = [1, 5, 8, 3]\nprint(data)\n\ndata.append(2)\nprint(data)\n\ndata.insert(5, 4)\nprint(data)\n\ndata.extend([9, 6, 7])\nprint(data)\n\ndata[2:2] = [-2, -4, -6]\nprint(data)\n\ndel data[2]\nprint(data)\n\ndata[5] = -3\nprint(data)\n\nif 9 in data:\n    print(True)\n\ndata.clear()\nprint(data)\n\n#Extra Exercise\n\nfirst_ele = {1, 4, 6, 7, 8}\nsecond_ele = {2, 3, 5, 7, 9}\nlist_ele = [3, 6, 0, 2]\n\n#Union same as update\nother_ele = first_ele | second_ele   #you can use this way if both are sets\nprint(other_ele)\n\nfirst_ele = first_ele.union(list_ele)\nprint(first_ele)\n\n#Intersection\nfirst_ele = first_ele.intersection(second_ele)\nprint(first_ele)\n\n#Difference\nthird_ele = second_ele - first_ele  #you can use this way if both are sets\nprint(third_ele)\n\nfourth_ele = second_ele.difference(list_ele)\nprint(fourth_ele)\n\n#Symmetric_difference\n\nos_ele = first_ele ^ second_ele   #you can use this way if both are sets\nprint(os_ele)\n\nme_ele = first_ele.symmetric_difference(list_ele)\nprint(me_ele)"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/JAFeito.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n * operaciones (debes utilizar una estructura que las soporte):\n * - Añade un elemento al final.\n * - Añade un elemento al principio.\n * - Añade varios elementos en bloque al final.\n * - Añade varios elementos en bloque en una posición concreta.\n * - Elimina un elemento en una posición concreta.\n * - Actualiza el valor de un elemento en una posición concreta.\n * - Comprueba si un elemento está en un conjunto.\n * - Elimina todo el contenido del conjunto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Unión.\n * - Intersección.\n * - Diferencia.\n * - Diferencia simétrica.\n \"\"\"\n \nconjunto = [1,2,3,4,5]\n#Añdir un elemento al final\nconjunto.append(6)\nprint(conjunto)\n#Añadir un elemento al principio\nconjunto.insert(0,0)\nprint(conjunto)\n#Añadir varios elementos al final\nconjunto.extend([7,8,9])\nprint(conjunto)\n#Añadir varios elementos en un posicion concreta\nconjunto[3:3]=[10,11,12]\nprint(conjunto)\n#Eliminar un elemento de una posicion concreta\ndel conjunto[3]\nprint(conjunto)\n#Actualizar el valor de un elemento en una posicion concreta\nconjunto[3] = 3\n#Comprobar si un elemento esta en el conjunto\nn =  5\nif(n in conjunto):\n    print(f\"El elemento {n} esta en el conjunto.\")\nelse:\n    print(f\"El elemento {n} no esta en el conjunto.\") \nconjunto.clear()\nprint(conjunto)\n\n#Extra\nconjunto_a = {20,21,22,23,24,25}\nconjuto_b = {19,21,18,23,17,25}\n#Union\nconjunto = conjunto_a.union(conjuto_b)\nprint(conjunto)\n#Interseccion\nconjunto = conjunto_a.intersection(conjuto_b)\nprint(conjunto)\n#Diferencia\nconjunto = conjunto_a.difference(conjuto_b)\nprint(conjunto)\n#Diferencia simetrica\nconjunto = conjunto_a.symmetric_difference(conjuto_b)\nprint(conjunto)\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/JesusWay69.py",
    "content": "import os\nos.system('clear')\nos.system('cls')\n\n\n\"\"\" * EJERCICIO:\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n * operaciones (debes utilizar una estructura que las soporte):\n * - Añade un elemento al final.\n * - Añade un elemento al principio.\n * - Añade varios elementos en bloque al final.\n * - Añade varios elementos en bloque en una posición concreta.\n * - Elimina un elemento en una posición concreta.\n * - Actualiza el valor de un elemento en una posición concreta.\n * - Comprueba si un elemento está en un conjunto.\n * - Elimina todo el contenido del conjunto.\n *\n \"\"\"\n\nmy_list = [1,7,0,2,4,6]\nprint(\"La lista original:            \", my_list)\nmy_list.append(8)\n\nprint(\"Le añadimos un 8 al final:    \",my_list)\n\nmy_list.insert(0,3)\n\nprint(\"Le añadimos un 3 al principio:\",my_list)\n\n\nmy_tuple = \"Hola\", True, (1,2,3)\nprint(\"Creamos esta tupla:           \",my_tuple)\n[my_list.insert(3,my_tuple[i]) for i in range(2,-1,-1)]\n\nprint(\"Insertamos los elementos de la tupla en la lista en la posición 3:\",my_list)\nhola = \"Hola\" in my_list\nprint (\"¿El elemento \\\"Hola\\\" está en la lista? \", hola )\nmy_list.clear()\nprint(\"Borramos todo el contenido de la lista, ahora la lista es esta: \", my_list)\nprint('\\n')\n\n\"\"\"* DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Unión.\n * - Intersección.\n * - Diferencia.\n * - Diferencia simétrica.\"\"\"\n\nset1 = {\"C\", \"Kotlin\", \"Swift\", \"C#\", \"Java\", \"Rust\", \"Javascript\", \"PhP\", \"Python\", \"R\", \"Ruby\", \"Scala\"}\nset2 = {\"C++\", \"Dart\", \"Python\", \"Cobol\", \"Javascript\", \"Pascal\", \"Abap\", \"Typescript\", \"Java\", \"Fortran\"}\n\nprint(\"### UNIÓN ###\")\nprint(set1 | set2)# Muestra todos los elementos de ambos sets sin repeticiones\nprint(set1.union(set2))# Muestra todos los elementos de ambos sets sin repeticiones\nprint()\n\nprint(\"### INTERSECCIÓN ###\")\nprint(set1.intersection(set2))# Muestra únicamente los elementos que existen a la vez en ambos sets\nprint(set2 & set1)# Muestra únicamente los elementos que existen a la vez en ambos sets\nprint()\n\nprint(\"### DIFERENCIA ###\")\nprint(set1 - set2)# Muestra los elementos que sólo existen en set1 y no están en set2 ni en ambos\nprint(set1.difference(set2))# Muestra los elementos que sólo existen en set1 y no están en set2 ni en ambos\nprint(set2 - set1)# Muestra los elementos que sólo existen en set2 y no están en set1 ni en ambos\nprint(set2.difference(set1))# Muestra los elementos que sólo existen en set2 y no están en set1 ni en ambos\nprint()\n\nprint(\"### DIFERENCIA SIMÉTRICA ###\")\nprint(set1 ^ set2)# Muestra los elementos de ambos sets que están en uno u otro set pero no en ambos \nprint(set1.symmetric_difference(set2))# Muestra los elementos de ambos sets que están en uno u otro set pero no en ambos \n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/JheisonQuiroga.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n * operaciones (debes utilizar una estructura que las soporte):\n * - Añade un elemento al final.\n * - Añade un elemento al principio.\n * - Añade varios elementos en bloque al final.\n * - Añade varios elementos en bloque en una posición concreta.\n * - Elimina un elemento en una posición concreta.\n * - Actualiza el valor de un elemento en una posición concreta.\n * - Comprueba si un elemento está en un conjunto.\n * - Elimina todo el contenido del conjunto.\n\"\"\"\n\n# 1. Creando un Conjunto de datos\ndata = [1, 2, 3]\n\n# 2. Agregando un elemento al final\ndata.append(4)\n\n# 3. Añade un elemento al principio\ndata.insert(0, 0)\n\n# 4. Añade varios elementos al final.\ndata.extend([5, 6])\nprint(data) \n\n# 5. Añadiendo varios elementos en una posición concreta\ndata[0:0] = [-2, -1]\n\n# 6. Eliminando un elemento en una posición concreta\ndeleted_element = data.pop(0)\nprint(\"Elemento eliminado:\", deleted_element) # Elemento eliminado: -2\n\n# 7. Actualiza el valor de un elemento en una posición concreta\ndata[3] = 7\nprint(data) # [-1, 0, 1, 7, 3, 4, 5, 6]\n\n# 8. Comprueba si un elemento existe en un conjunto\ncero_exists = 0 in data\nprint(\"El cero existe dentro de data?:\", cero_exists)\n\n# 9. Elimina todo el contenido\n\ndata.clear()\nprint(data) # []\n\n\n\"\"\"\n *\n * DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Unión.\n * - Intersección.\n * - Diferencia.\n * - Diferencia simétrica.\n */\n\"\"\"\n\nprint(\"-\" * 5, \"Operaciones con Conjuntos\", \"-\" * 5)\n\na = {1, 2, 3, 4}\nb = {3, 4, 5, 6}\n\n# 1. Unión\n\nc = a.union(b)\nprint(c) # {1, 2, 3, 4, 5, 6}\n\n# 2. Intersección\n\ninter = a & b\nprint(inter) # {3, 4}\n\n# 3. Diferencia\ndif = a.difference(b)\nprint(dif)  # {1, 2}\n\ndif = a - b\nprint(dif)\n\n# 4. Diferencia simétrica\nsim_difference = a.symmetric_difference(b)\nprint(sim_difference) # {1, 2, 5, 6}"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/JuanDAW37.py",
    "content": "\"\"\"* EJERCICIO:\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n * operaciones (debes utilizar una estructura que las soporte):\n * - Añade un elemento al final.\n * - Añade un elemento al principio.\n * - Añade varios elementos en bloque al final.\n * - Añade varios elementos en bloque en una posición concreta.\n * - Elimina un elemento en una posición concreta.\n * - Actualiza el valor de un elemento en una posición concreta.\n * - Comprueba si un elemento está en un conjunto.\n * - Elimina todo el contenido del conjunto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Unión.\n * - Intersección.\n * - Diferencia.\n * - Diferencia simétrica.\"\"\"\n\nconjunto = ['a', 'b', 'c', 'd']\nprint(f'Mi conjunto es {conjunto}')\n# Añade un elemento al final.\nconjunto.append('e')\nprint(f'Mi conjunto es {conjunto}')\n# Añade un elemento al principio.\nconjunto.insert(0,'a')\nprint(f'Mi conjunto es {conjunto}')\n# Añade varios elementos en bloque al final.\nconjunto.extend(['y', 'z'])\nprint(f'Mi conjunto es {conjunto}')\n# Añade varios elementos en bloque en una posición concreta.\nconjunto[2:2] = ['d', 'h', 'r']\nprint(f'Mi conjunto es {conjunto}')\n# Elimina un elemento en una posición concreta.\ndel conjunto[2]\nprint(f'Mi conjunto es {conjunto}')\n# Actualiza el valor de un elemento en una posición concreta.\nconjunto[3] = 'ñ'\nprint(f'Mi conjunto es {conjunto}')\n# Comprueba si un elemento está en un conjunto.\nprint(f'¿El elemento está en el conjunto? {'t' in conjunto}')\n# Elimina todo el contenido del conjunto.\nconjunto.clear()\nprint(f'Mi conjunto es {conjunto}')\n\n# EXTRA\nconjunto1 = {'a', 'b', 'c'}\nconjunto2 = {'b', 'c', 'd'}\n# - Unión.\nprint(conjunto1.union(conjunto2))\n\n# - Intersección\nprint(conjunto1.intersection(conjunto2))\n\n# - Diferencia\nprint(conjunto1.difference(conjunto2))\n\n# - Diferencia simétrica:\nprint(conjunto1.symmetric_difference(conjunto2))"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/LucasRebuffo.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n * operaciones (debes utilizar una estructura que las soporte):\n * - Añade un elemento al final.\n * - Añade un elemento al principio.\n * - Añade varios elementos en bloque al final.\n * - Añade varios elementos en bloque en una posición concreta.\n * - Elimina un elemento en una posición concreta.\n * - Actualiza el valor de un elemento en una posición concreta.\n * - Comprueba si un elemento está en un conjunto.\n * - Elimina todo el contenido del conjunto. \n \"\"\"\n\n# Conjuntos\n\nmy_set = {1,2,3,4,5}\n\nmy_set.add(6)\n\nprint(my_set)\n\n\"\"\"\n \n *\n * DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Unión.\n * - Intersección.\n * - Diferencia.\n * - Diferencia simétrica.\n */ \"\"\"\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/Marlonleon2023.py",
    "content": "\"\"\"* EJERCICIO:\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n * operaciones (debes utilizar una estructura que las soporte):\n * - Añade un elemento al final.\n * - Añade un elemento al principio.\n * - Añade varios elementos en bloque al final.\n * - Añade varios elementos en bloque en una posición concreta.\n * - Elimina un elemento en una posición concreta.\n * - Actualiza el valor de un elemento en una posición concreta.\n * - Comprueba si un elemento está en un conjunto.\n * - Elimina todo el contenido del conjunto.\n \"\"\"\n\nprint(\"-----------------Ejercicios---------------\")\n\nlistConjunto =[\"hola\",\"marlon\",\"casa\",\"avion\",\"carro\",\"persona\",\"nombre\"]\n# Se añade un elmento al final\nlistConjunto.append(\"edifico\")\n# Se añade un elemeto al principio\nlistConjunto.insert(0,\"feliz\")\n# varios elementos en el bloque final\nagregarbloqueFinal=[\"escuela\",\"colegio\",\"aeropueto\",\"viaje\"]\nlistConjunto.extend(agregarbloqueFinal)\n# Añadir varios elementos en bloque en una posicion concreta\nagregarEspecifico=[\"libro\",\"bolso\",\"papel\"]\nposicion=5\nlistConjunto[posicion:posicion]=agregarEspecifico\n\n#Elimina un elemento en una posición concreta.\nlistConjunto.remove(\"carro\")\n#Actualiza el valor de un elemento en una posición concreta.\nposicion1=3\nnuevoValor=\"Bacaciones\"\nlistConjunto[posicion1]=nuevoValor\nprint(type(listConjunto))\nprint(listConjunto)\n#Comprueba si un elemento está en un conjunto.\nprint(\"Comprobacion si un elemento estaen un conjunto\")\nprint(\"Bacaciones\" in listConjunto)\n#Elimina todo el contenido del conjunto.\nprint(\"Eliminacion del contenido del conjunto\")\nlistConjunto.clear()\nprint(\"marlon\" in listConjunto)\n\n\n\"\"\" * DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Unión.\n * - Intersección.\n * - Diferencia.\n * - Diferencia simétrica.\"\"\"\n \nprint(\"----------------Dificulta Extra----------------\")\n \ninstrumentosComunes={\"guitarra\",\"tiple\",\"flauta\"}\ninstrumentosRaros={\"arpa\",\"birimbao\",\"derbake\"}\n# Unión.\nprint(\"Union------------\")\nconjuntoInstrumentos=instrumentosComunes.union(instrumentosRaros)\nconjuntoInstrumentos=instrumentosComunes|instrumentosRaros\nprint(conjuntoInstrumentos)\n#Intersección.\nprint(\"Intersección----------------\")\nnumber1={1,2,3,4}\nnumber2={4,5,6,6,7,1}\n\ninterset=number1.intersection(number2)\ninterset=number1 & number2\nprint(interset)\n\n#Diferencia.\nprint(\"Diferencia---------\")\ndiferencia=number1.difference(number2)\ndiferencia=number1-number2\nprint(diferencia)\n\n# Diferencia Simetrica\nprint(\"Diferencia Dimetrica-----------\")\ndiferSimetrica=number1.symmetric_difference(number2)\ndiferSimetrica=number1 ^ number2\nprint(diferSimetrica)\n\n\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/Mauricio-Leyva.py",
    "content": "# conjunto de datos (lista)\ndatos = [1, 2, 3, 4, 5]\n\n# Añade un elemento al final\ndatos.append(6)\nprint(\"Añadir un elemento al final:\", datos)  \n\n# Añade un elemento al principio\ndatos.insert(0, 0)\nprint(\"Añadir un elemento al principio:\", datos)  \n\n# Añade varios elementos en bloque al final\ndatos.extend([7, 8, 9])\nprint(\"Añadir varios elementos en bloque al final:\", datos)  \n\n# Añade varios elementos en bloque en una posición concreta\ndatos[3:3] = [10, 11]\nprint(\"Añadir varios elementos en bloque en una posición concreta:\", datos)  \n\n# Elimina un elemento en una posición concreta\ndel datos[5]\nprint(\"Eliminar un elemento en una posición concreta:\", datos)  \n\n# Actualiza el valor de un elemento en una posición concreta\ndatos[3] = 12\nprint(\"Actualizar el valor de un elemento en una posición concreta:\", datos)  \n\n# Comprueba si un elemento está en un conjunto\nprint(\"¿Está el elemento 4 en el conjunto?\", 4 in datos)  \nprint(\"¿Está el elemento 10 en el conjunto?\", 10 not in datos)  \n\n# Elimina todo el contenido del conjunto\ndatos.clear()\nprint(\"Eliminar todo el contenido del conjunto:\", datos)  "
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/Nicojsuarez2.py",
    "content": "# #18 CONJUNTOS\n> #### Dificultad: Fácil | Publicación: 29/04/24 | Corrección: 06/05/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n * operaciones (debes utilizar una estructura que las soporte):\n * - Añade un elemento al final.\n * - Añade un elemento al principio.\n * - Añade varios elementos en bloque al final.\n * - Añade varios elementos en bloque en una posición concreta.\n * - Elimina un elemento en una posición concreta.\n * - Actualiza el valor de un elemento en una posición concreta.\n * - Comprueba si un elemento está en un conjunto.\n * - Elimina todo el contenido del conjunto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Unión.\n * - Intersección.\n * - Diferencia.\n * - Diferencia simétrica.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/Pipe281.py",
    "content": "'''\n * EJERCICIO:\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n * operaciones (debes utilizar una estructura que las soporte):\n * - Añade un elemento al final.\n * - Añade un elemento al principio.\n * - Añade varios elementos en bloque al final.\n * - Añade varios elementos en bloque en una posición concreta.\n * - Elimina un elemento en una posición concreta.\n * - Actualiza el valor de un elemento en una posición concreta.\n * - Comprueba si un elemento está en un conjunto.\n * - Elimina todo el contenido del conjunto. '''\n\n#Creación de conjuntos\nconjunto1 = {1, 2, 3, 4}\nprint(conjunto1)\n\n#Añadiendo elemento al Final\nconjunto1.add(5)\nprint(conjunto1)\n\n#Añadiendo elemento al Comienzo\nconjunto2 = [1,2,3,4]\nconjunto2.insert(0, 0.5)\nprint(conjunto2)\n#Añade varios elementos en bloque al final.\nconjunto2.extend({6, 7, 8})\nprint(conjunto2)\n\n#Añade varios elementos en bloque en una posición concreta.\nconjunto2[2:3]=[22,23]\nprint(conjunto2)\n\n#Elimina un elemento en una posición concreta.\ndel conjunto2[2]\nprint(conjunto2)\n\n#Añade varios elementos en bloque en una posición concreta.\nconjunto2[2] = \"Perro\"\nprint(conjunto2)\n\n# Comprueba si un elemento está en un conjunto\nelemento = 5\nif elemento in conjunto2:\n    print(f\"El elemento {elemento} está en el conjunto.\")\nelse:\n    print(f\"El elemento {elemento} no está en el conjunto.\")\n\n# Elimina todo el contenido del conjunto\nconjunto2.clear()\nprint(\"Conjunto después de eliminar todo el contenido:\", conjunto2)\n\n\"\"\"\n* EJERCICIO #2:\n* Muestra ejemplos de las siguientes operaciones con conjuntos:\n* - Unión.\n* - Intersección.\n* - Diferencia.\n* - Diferencia simétrica.\n\"\"\"\n\n#Union, existen dos formas\nA = {1,2,3,4}\nB = {5,6,7,8}\n\nprint(A | B)\nprint(A.union(B))\n\n#Intersección.\nA = {1, 3, 5}\nB = {1, 2, 3}\nprint('Intersección usando &:', A & B)\nprint('Intersección usando intersection():', A.intersection(B))\n\n#Diferencia\nA = {2, 3, 5}\nB = {1, 2, 6}\nprint('Diferencia usando - :', A - B)\nprint('Diferencia usando difference():', A.difference(B))\nprint('Diferencia usando - :', B - A)\nprint('Diferencia usando difference():', B.difference(A))\n\n#Diferencia Simétrica\nA = {2, 3, 5}\nB = {1, 2, 6}\nprint('Usando ^:', A ^ B)\nprint('Usando symmetric_difference():', A.symmetric_difference(B)) "
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/Sac-Corts.py",
    "content": "my_list = [1, 2, 3, 4, 5]\nmy_list.append(6)\nprint(my_list)\n\nmy_list.insert(0, 0)\nprint(my_list)\n\nmy_list.extend([7, 8, 9])\nprint(my_list)\n\nmy_list[4:4] = [22, 23]\nprint(my_list)\n\ndel my_list[4]\ndel my_list[4]\nprint(my_list)\n\nmy_list[9] = 10\nprint(my_list)\n\nelement = 10\nin_list = element in my_list\nprint(in_list)\n\nmy_list.clear()\nprint(my_list)\n\n### Ejercicio Extra ###\n\nset_a = {1, 2, 3, 4, 5}\nset_b = {4, 5, 6, 7, 8}\nprint(\"Conjunto a:\", set_a)\nprint(\"Conjunto b:\", set_b)\n\n# Unión\nunion = set_a | set_b\nprint(\"Unión:\", union)\n\n# Intersección\nintersection = set_a & set_b\nprint(\"Intersección:\", intersection)\n\n# Diferencia\ndifference = set_a - set_b\nprint(\"Diferencia:\", difference)\n\n# Diferencia Simétrica\nsymmetrical_difference = set_a ^ set_b\nprint(\"Diferencia Simétrica:\", symmetrical_difference)"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/SaezMD.py",
    "content": "#18 Conjuntos\n\"\"\"\n * EJERCICIO:\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes operaciones (debes utilizar una estructura que las soporte):\n * - Añade un elemento al final.\n * - Añade un elemento al principio.\n * - Añade varios elementos en bloque al final.\n * - Añade varios elementos en bloque en una posición concreta.\n * - Elimina un elemento en una posición concreta.\n * - Actualiza el valor de un elemento en una posición concreta.\n * - Comprueba si un elemento está en un conjunto.\n * - Elimina todo el contenido del conjunto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Unión.\n * - Intersección.\n * - Diferencia.\n * - Diferencia simétrica.\n\"\"\"\n\n#create elememt:\ndataSet = [\"a\", \"b\", 1, 2]\n#add element to the end:\ndataSet.append(\"last\")\n#add element to the first:\ndataSet.insert(0,\"first\")\n#add several items as a block to the end:\nfor unit in [\"very last\", \"the end\"]:\n    dataSet.append(unit)\n#add several items as a block to specific position:\nposition = 2\nfor unit in [\"middle\", \"another\"]:\n    dataSet.insert(position,unit)\n    position += 1\n#delete an element in a position:\ndataSet.pop(3)\n#update the element in a position: \ndataSet.pop(5)\ndataSet.insert(5,\"update!\")\n#check if element is a list:\nif \"very last\" in dataSet:\n    print(\"yes\")\nelse:\n    print(\"no\")\n#delete all:\ndataSet.clear()\n\nprint(dataSet)\n\n#EXTRA:\n\n#join:\nlist1 = [\"a\", \"b\", \"c\"]\nlist2 = [1,2,3]\n\njoin00 = list1 + list2\nprint(join00)\n\n#intersection:\nlist3 = [1,2,3,4,5]\nlist4 = [6,7,8,9,0,1,2]\nintersect = []\nfor value in list3:\n    if value in list4:\n        intersect.append(value)\n\nprint(\"Intersect:\",intersect)\n\n#difference:\ndifference = []\nfor value in list3:\n    if value not in list4:\n        difference.append(value)\n\nprint(\"Difference:\",difference)\n\n#symmetric:\ndifference = []\nfor value in list3:\n    if value not in list4:\n        difference.append(value)\nfor value in list4:\n    if value not in list3:\n        difference.append(value)\n\nprint(\"Symmetric:\",difference)\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/SooHav.py",
    "content": "# 18 CONJUNTOS\n\"\"\"Ejercicio\"\"\"\n\n# Crear un conjunto de datos\nmi_conjunto = []\n\n# Añadir un elemento al final\nmi_conjunto.append(1)\nprint(mi_conjunto)\n\n# Añadir un elemento al principio\nmi_conjunto.insert(0, 0)\nprint(mi_conjunto)\n\n# Añadir varios elementos en bloque al final\nmi_conjunto.extend([2, 3, 6])\nprint(mi_conjunto)\n\n# Añadir varios elementos en bloque en una posición concreta\nmi_conjunto[4:4] = [4, 5]\nprint(mi_conjunto)\n\n# Eliminar un elemento en una posición concreta\ndel mi_conjunto[6]\nprint(mi_conjunto)\n\n# Actualizar el valor de un elemento en una posición concreta\nmi_conjunto[0] = \"a\"\nprint(mi_conjunto)\n\n# Comprobar si un elemento está en un conjunto\nelemento = 4\ntry:\n    mi_conjunto.index(elemento)\n    print(f\"{elemento} está en el conjunto\")\nexcept ValueError:\n    print(f\"{elemento} no está en el conjunto\")\n\n# Eliminar todo el contenido del conjunto\nmi_conjunto.clear()\n\nprint(mi_conjunto)\n\n\"\"\"Extra\"\"\"\n# Unión de conjuntos en Python\na = {1, 2, 3, 4}\nb = {2, 4, 6, 8}\nprint(a | b)\n\n# Intersección de conjuntos en Python\na = {1, 2, 3, 4}\nb = {2, 4, 6, 8}\nprint(a & b)\n\n# Diferencia de conjuntos en Python\na = {1, 2, 3, 4}\nb = {2, 4, 6, 8}\nprint(a - b)\n\n# Diferencia simétrica de conjuntos en Python\na = {1, 2, 3, 4}\nb = {2, 4, 6, 8}\nprint(a ^ b)\n\n\"\"\"Prueba de programa con el primer ejercicio\"\"\"\nwhile True:\n    print(\"\\nMenú:\")\n    print(\"0. Crea un conjunto de elementos\")\n    print(\"1. Inserta elemento/s al final\")\n    print(\"2. Inserta elemento/s al inicio\")\n    print(\"3. Inserta elemento/s en una posición\")\n    print(\"4. Elimina elemento en una posición\")\n    print(\"5. Actualiza elemento en una posición\")\n    print(\"6. Comprueba si un elemento está\")\n    print(\"7. Elimina todo el contenido\")\n    print(\"8. Sale del programa\")\n\n    opcion = input(\"Seleccione una opción: \")\n\n    if opcion == \"0\":\n        mi_conjunto = list()\n        opcion_conjunto = type(mi_conjunto)\n        print(f\"Se ha creado un conjunto de tipo {opcion_conjunto}\")\n\n    elif opcion == \"1\":\n        elementos = input(\n            \"Ingresa el/los elemento/s separados por comas:\\n\").split(\",\")\n        nuevo_elemento = []\n        for i in elementos:\n            i = i.strip()\n            if i.isdigit():\n                nuevo_elemento.append(int(i))\n            elif i.replace('.', '', 1).isdigit():\n                nuevo_elemento.append(float(i))\n            else:\n                nuevo_elemento.append(i)\n        mi_conjunto.extend(nuevo_elemento)\n        print(mi_conjunto)\n\n    elif opcion == \"2\":\n        elemento = input(\n            \"Ingresa el/los elemento/s separados por comas:\\n\").split(\",\")\n        nuevo_elemento = []\n        for i in elemento:\n            i = i.strip()\n            if i.isdigit():\n                nuevo_elemento.append(int(i))\n            elif i.replace('.', '', 1).isdigit():\n                nuevo_elemento.append(float(i))\n            else:\n                nuevo_elemento.append(i)\n        mi_conjunto = nuevo_elemento + mi_conjunto\n        print(mi_conjunto)\n\n    elif opcion == \"3\":\n        elemento = input(\"Ingresa el/los elemento/s:\\n\").split(\",\")\n        nuevo_elemento = []\n        for i in elemento:\n            i = i.strip()\n            if i.isdigit():\n                nuevo_elemento.append(int(i))\n            elif i.replace('.', '', 1).isdigit():\n                nuevo_elemento.append(float(i))\n            else:\n                nuevo_elemento.append(i)\n        indice = int(input(\"Ingresa la posición:\\n\"))\n        mi_conjunto[indice:indice] = nuevo_elemento\n        print(mi_conjunto)\n\n    elif opcion == \"4\":\n        indice = int(input(\"Ingresa la posición:\\n\"))\n        mi_conjunto.pop(indice)\n        print(mi_conjunto)\n\n    elif opcion == \"5\":\n        elemento = input(\"Ingresa el elemento a actualizar:\\n\")\n        try:\n            elemento_num = int(elemento)\n        except ValueError:\n            try:\n                elemento_num = float(elemento)\n            except ValueError:\n                elemento_num = elemento\n        indice = int(input(\"Ingresa la posición:\\n\"))\n        mi_conjunto[indice] = elemento_num\n        print(mi_conjunto)\n\n    elif opcion == \"6\":\n        elemento = input(\"Ingresa el elemento:\\n\")\n        try:\n            mi_conjunto.index(elemento)\n            print(f\"{elemento} está en el conjunto\")\n        except ValueError:\n            print(f\"{elemento} no está en el conjunto\")\n\n    elif opcion == \"7\":\n        mi_conjunto.clear()\n        print(mi_conjunto)\n\n    elif opcion == \"8\":\n        print(\"Saliendo del programa\")\n        break\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/Trufoplus.py",
    "content": "###############################################################################\n### CONJUNTOS\n###############################################################################\n\nmy_set = {1, 2, 3, 4, 5}\n\nprint(\"\\nAñade un elemento al final\")\nmy_set.add(6)\nprint(my_set)\n\n\nprint(\"\\nAñade un elemento al principio\")\nmy_set.add(0)\nprint(my_set)\n\n\nprint(\"\\nAñade varios elementos en bloque al final\")\nmy_list = [7, 8, 9, 10]\nmy_set.update(my_list)\nprint(my_set)\n\n\nprint(\"\\nElimina un elemento en una posición concreta\")\nmy_set = list(my_set)\nposition = my_set[1]\nmy_set.remove(position)\nmy_set = set(my_set)\nprint(my_set)\n\n\nprint(\"\\nActualiza el valor de un elemento en una posición concreta\")\nmy_set = list(my_set)\nmy_set[0] = 1\nmy_set = set(my_set)\nprint(my_set)\n\n\nprint(\"\\nComprueba si un elemento está en un conjunto\")\nelement = 2\nif element in my_set:\n    print(f\"El numero '{element}' esta en mi conjunto\")\nelse:\n    print(f\"El '{element}' no esta en mi conjunto\")\n\n\nprint(\"\\nElimina todo el contenido del conjunto.\")\nmy_set.clear()\nprint(my_set)\n\n###############################################################################\n### DIFICULTAD EXTRA\n###############################################################################\nmy_set_1 = {1,2,3,4,5,6}\nmy_set_2 = {5,6,7,8,9,10}\n\nprint(\"\\nUnion: \")\nunion = my_set_1 | my_set_2\nprint(union)\nunion2 = my_set_1.union(my_set_2)\nprint(union2)\n\nprint(\"\\nInterseccion: \")\ninterseccion = my_set_2 & my_set_1\nprint(interseccion)\nintesect = my_set_1.intersection(my_set_2)\nprint(intesect)  \n\nprint(\"\\nDiferencia: \")\ndiferencia = my_set_1 - my_set_2\nprint(diferencia)\ndiferencia = my_set_2.difference(my_set_1)\nprint(diferencia)\n\nprint(\"\\nDiferencia Simetrica: \")\nsimetric_difference = my_set_1 ^ my_set_2\nprint(simetric_difference)\nsimetric_difference2 = my_set_1.symmetric_difference(my_set_2)\nprint(simetric_difference2)\n\n  \n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/a-mayans.py",
    "content": "\n# conjunto de datos -> lista\nmy_list = [2, 4, 6, 8, 10]\n\n# añadir un elemento al final\nmy_list.append(12)\n\n# añadir un elemento al principio\nmy_list.insert(0, 13)\n\n# añadir varios elementos en bloque al final\nmy_list.extend([14, 16, 18])\n\n# añadir varios elementos en bloque en una posición concreta\nnew_elements = [27, 28, 29, 30]\nposition = 3\nmy_list[position:position] = new_elements\n\n# eliminar un elemento en una posición concreta\nmy_list.pop(10)\n\n# actualizar el valor de un elemento en una posición concreta\nmy_list[5] = 69\n\n# comprobar si un elemento está en un conjunto\nelement = 27\nis_present = element in my_list\nprint(is_present) # devuelve true\n\n# eliminar todo el contenido del conjunto\n## una opcion -> my_list = []\n## otra opcion\nmy_list.clear()\n\n\n'''\n * DIFICULTAD EXTRA \n'''\n\n# Unión: unir dos conjuntos\nlist1 = set([1, 2, 3, 4, 5])\nlist2 = set([5, 6, 7, 8, 9])\nunited = list1.union(list2)\nprint(united) # devuelve {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}\n\n# Intersección: que elementos tienen en comun\nintersection = list1.intersection(list2)\nprint(intersection) # devuelve {5}\n\n# Diferencia: se queda con los diferentes del conjunto a comparar\ndifference = list1.difference(list2)\nprint(difference) # devuelve {1, 2, 3, 4, 10}\n\n# Diferencia simétrica: se queda con todos, excluyendo los comunes\nsym_diff = list1.symmetric_difference(list2)\nprint(sym_diff) # devuelve {1, 2, 3, 4, 6, 7, 8, 9, 10}"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/adra-dev.py",
    "content": "\"\"\"\nEJERCICIO:\nUtilizando tu lenguaje crea un conjunto de datos y realiza las \nsiguientes operaciones (debes utilizar una estructura que las soporte):\n\n- Añade un elemento al final.\n- Añade un elemento al principio.\n- Añade varios elementos en bloque al final.\n- Añade varios elementos en bloque en una posición concreta.\n- Elimina un elemento en una posición concreta.\n- Actualiza el valor de un elemento en una posición concreta.\n- Comprueba si un elemento está en un conjunto.\n- Elimina todo el contenido del conjunto.\n\nDIFICULTAD EXTRA (opcional):\nMuestra ejemplos de las siguientes operaciones con conjutos:\n- Unión.\n- Intersección.\n- Diferencia.\n- Diferencia simétrica.\n\nby adra-dev\n\"\"\"\ndata = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10,]\nprint(f\"Estructura inicial: {data}\")\n\ndata.append(6)\nprint(f\"Añadiendo elemento al final: {data}\")\n\ndata.insert(0, 0)\nprint(f\"Añadiendo elemento al principio: {data}\")\n\ndata.extend([7, 8, 9])\nprint(f\"Añadiendo elementos al final: {data}\")\n\ndata[3:3] = [-1, -2, -3]\nprint(f\"Añadiendo elementos en una posición: {data}\")\n\ndel data[3]\nprint(f\"Eliminando un elemento concreto: {data}\")\n\ndata[4] = -1\nprint(f\"Actualizando un elemento concreto: {data}\")\n\nprint(f\"Comprobar si un elemento existe: {-1 in data}\")\n\nprint(f\"Eliminar el contenido: {data.clear()}\")\n\n\"\"\"\nExtra\n\"\"\"\n\nset1 = {-3, -2, -1, 0, 1, 2, 3}\nset2 = {0, 1, 2, 3}\n\nprint(f\"Union {set1.union(set2)}\")\n\nprint(f\"Intersección: {set1.intersection(set2)}\")\nprint(f\"Intersección: {set2.isdisjoint(set1)}\")\n\nprint(f\"Diferencia: {set1.difference(set2)}\")\nprint(f\"Diferencia: {set2.difference(set1)}\")\n\nprint(f\"Diferencia: {set2.issubset(set1)}\")\n\nprint(f\"Diferencia simétrica: {set1.symmetric_difference(set2)}\")"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/agusrosero.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n * operaciones (debes utilizar una estructura que las soporte):\n * - Añade un elemento al final.\n * - Añade un elemento al principio.\n * - Añade varios elementos en bloque al final.\n * - Añade varios elementos en bloque en una posición concreta.\n * - Elimina un elemento en una posición concreta.\n * - Actualiza el valor de un elemento en una posición concreta.\n * - Comprueba si un elemento está en un conjunto.\n * - Elimina todo el contenido del conjunto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Unión.\n * - Intersección.\n * - Diferencia.\n * - Diferencia simétrica.\n */\n\"\"\"\n\n# EJERCICIO:\n\nmi_conjunto = set([1, 2, 3, 4])\n# Añade un elemento al final\nmi_conjunto.add(5)\nprint(mi_conjunto)\n# Añade un elemento al principio\nnuevo_conjunto = {1}\nprint(nuevo_conjunto)\n# Añade varios elementos en bloque al final\nelementos = {8, 9, 10}\nmi_conjunto.update(elementos)\nprint(mi_conjunto)\n# Comprueba si un elemento está en un conjunto\nelemento_conjunto = 2 in mi_conjunto\nprint(elemento_conjunto)\n# Elimina todo el contenido del conjunto\nmi_conjunto.clear()\nprint(mi_conjunto)\n\n# DIFICULTAD EXTRA:\n\nst1 = {1, 2, 3}\nst2 = {4, 5, 6}\n# Unión\nprint(st1.union(st2))\n# Intersección\nprint(st1.intersection(st2))\n# Diferencia\nprint(st1.difference(st2))\nst1.difference_update(st2)\nprint(st1)\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/alanshakir.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n * operaciones (debes utilizar una estructura que las soporte):\n * - Añade un elemento al final.\n * - Añade un elemento al principio.\n * - Añade varios elementos en bloque al final.\n * - Añade varios elementos en bloque en una posición concreta.\n * - Elimina un elemento en una posición concreta.\n * - Actualiza el valor de un elemento en una posición concreta.\n * - Comprueba si un elemento está en un conjunto.\n * - Elimina todo el contenido del conjunto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Unión.\n * - Intersección.\n * - Diferencia.\n * - Diferencia simétrica.\n */\n\"\"\"\n\nmy_list = [25, 36, 85, 48, 98, 74, 15, 69, 37]\nmy_other_list = [10, 25, 85, 19, 1]\n# Añade un elemento al final.\nmy_list.append(20)\n# Añade un elemento al principio.\nmy_list.insert(0, 19)\nmy_position = 5\n#Añade varios elementos en bloque al final.\nmy_list.extend(my_other_list)\n# Añade varios elementos en bloque en una posición concreta.\nmy_position = 4\nmy_other_list[my_position:my_position] = [85, 25, 74]\n# Elimina un elemento en una posición concreta.\ndel my_list[my_position]\n# Actualiza el valor de un elemento en una posición concreta.\nmy_list[my_position] = 34\n# Comprueba si un elemento está en un conjunto.\nmy_element = 29\nelement = my_element in my_list\n# Elimina todo el contenido del conjunto\nmy_other_list.clear()\n\n#EXTRA\nmy_set = {20, 14, 75, 19, 85}\nmy_other_set = {15, 87, 24, 3, 5, 14}\nprint(f\"union de conjuntos: \", my_set | my_other_set)\nprint(f\"Interseccion de conjuntos: \", my_set & my_other_set)\nprint(f\"Diferencia de conjuntos: \", my_set - my_other_set)\nprint(f\"Diferencia simetrica de conjuntos: \", my_set ^ my_other_set)\n\n# Funciones propias de Set\nprint(f\"union de conjuntos: \", my_set.union(my_other_set))\nprint(f\"Interseccion de conjuntos: \", my_set.intersection(my_other_set))\nprint(f\"Diferencia de conjuntos: \", my_set.difference(my_other_set))\nprint(f\"Diferencia simetrica de conjuntos: \", my_set.symmetric_difference(my_other_set))\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/any7dev.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n * operaciones (debes utilizar una estructura que las soporte):\n * - Añade un elemento al final.\n * - Añade un elemento al principio.\n * - Añade varios elementos en bloque al final.\n * - Añade varios elementos en bloque en una posición concreta.\n * - Elimina un elemento en una posición concreta.\n * - Actualiza el valor de un elemento en una posición concreta.\n * - Comprueba si un elemento está en un conjunto.\n * - Elimina todo el contenido del conjunto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Unión.\n * - Intersección.\n * - Diferencia.\n * - Diferencia simétrica.\n */ \"\"\"\n\n#EJERCICIO\nlista = [2, 4, 7, 20, 23, 6] #Crear\nprint(lista)\n\nlista.append(24) #Añadir al final\nprint(lista)\n\nlista.insert(0, 1) #Añadir al principio\nprint(lista)\n\nlista.extend([0, 3, 10]) #Añadir en bloque al final\nprint(lista)\n\nlista[5:3] = [11, 50, 30] #Añade varios elementos en una posición concreta\nprint(lista)\n\nlista.pop(7) #Elimina el elemento de la posición 6\nprint(lista)\n\nlista[5] = 5 #Actualiza el valor del elemento en la posición 5\nprint(lista)\n\nprint(20 in lista) #Comprueba si 20 está en la lista\n\nlista.clear() #Elimina todo el contenido\nprint(lista)\n\n#DIFICULTAD EXTRA\nconjunto1 = {2, 4, 7, 20, 23, 6, 0, 11}\nconjunto2 = {0, 3, 10, 11, 50, 30, 7, 4}\n\nprint(conjunto1.union(conjunto2)) \nprint(conjunto1.intersection(conjunto2))\nprint(conjunto1.difference(conjunto2))\nprint(conjunto1.symmetric_difference(conjunto2))"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/avcenal.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n * operaciones (debes utilizar una estructura que las soporte):\n * - Añade un elemento al final.\n * - Añade un elemento al principio.\n * - Añade varios elementos en bloque al final.\n * - Añade varios elementos en bloque en una posición concreta.\n * - Elimina un elemento en una posición concreta.\n * - Actualiza el valor de un elemento en una posición concreta.\n * - Comprueba si un elemento está en un conjunto.\n * - Elimina todo el contenido del conjunto.\n\"\"\"\n\nclass MySet():\n    def __init__(self,*elements): #el constructor debe comprobar que si le pasamos el mismo argumento solo lo añade una vez\n        one_list = list(elements)\n        if len(one_list) == 1:\n            self.__custom_set = one_list.copy()\n        else:\n            for element in one_list:\n                if one_list.count(element) > 1:\n                    one_list.remove(element)\n            self.__custom_set = one_list.copy()\n        #self.__custom_set.append(element)\n\n    def __to_list(self):\n        return list(self.__custom_set)\n\n    def add_last(self,element): #en cualquier método para añadir se ha de comprobar si el elemento existe o no en el conjunto\n        for item in self.__custom_set:\n            if item == element:\n                break\n        else:\n            self.__custom_set.append(element)\n        return self.__custom_set\n\n    def add_first(self,element):\n        for item in self.__custom_set:\n            if item == element:\n                break\n        else:\n            self.__custom_set = [element] + self.__custom_set\n        return self.__custom_set\n    \n    def show_set(self):\n        if len(self.__custom_set) == 0:\n            print(\"El conjunto está vacío\")\n        else:\n            print(self.__custom_set)\n\n    def add_several_first(self,*elements): #lo mismo aquí, hay que comprobar que ningún elemento existe ya en el conjunto\n        element_list = [*elements]\n        for element in element_list:\n            if element_list.count(element)>1:\n                element_list.remove(element)\n            elif element in self.__custom_set:\n                element_list.remove(element)\n        self.__custom_set = element_list + self.__custom_set\n        return self.__custom_set\n    \n    def add_several_last(self,*elements):\n        element_list = [*elements]\n        for element in element_list:\n            if element_list.count(element)>1:\n                element_list.remove(element)\n            elif element in self.__custom_set:\n                element_list.remove(element)\n        self.__custom_set = self.__custom_set + element_list\n        return self.__custom_set\n    \n    def erase_element_at_position(self,position): #se ha de comprobar que el elemento existe en el conjunto\n        try:                                      #y que no le pasamos un índice mayor que el máximo del conjunto\n            del(self.__custom_set[position])\n        except TypeError:\n            print(\"Debes introducir un número entero como posición para borrar\")\n        except IndexError:\n            print(f\"Solo puedes elegir valores entre el 0 y {len(self.__custom_set)-1}\")\n        return self.__custom_set\n\n    def update_value(self, position,value): #lo mismo que el método anterior\n        try:\n            self.__custom_set[position] = value\n        except TypeError:\n            print(\"Debes introducir un número entero como posición para actualizar el valor\")\n        except IndexError:\n            print(f\"Solo puedes elegir valores entre el 0 y {len(self.__custom_set)-1}\")\n        return self.__custom_set\n    \n    def check_element(self,element):\n        try:\n            self.__custom_set.index(element)\n        except ValueError:\n            print(f\"El elemento {element} no está en el conjunto\")\n        else:\n            print(f\"El elemento {element} si está en el conjunto\")\n\n    def delete_set(self):\n        return self.__custom_set.clear()\n    \n    def union (self,other_set): #se unen los dos conjuntos sin repetir elementos\n        if type(other_set) != MySet:\n            raise TypeError(\"El otro elemento no es un conjunto\")\n        else:\n            my_new_set = MySet()\n            other_set_list = my_other_set.__to_list()\n            for element_a in self.__custom_set:\n                for element_b in other_set_list:\n                    if element_a == element_b:\n                        other_set_list.remove(element_b)\n                        break\n                my_new_set.add_last(element_a)\n            for element in other_set_list:\n                my_new_set.add_last(element)\n            return my_new_set\n    \n    def intersection (self,other_set): #nos da como resultado los elementos comunes a los conjuntos\n        if type(other_set) != MySet:\n            raise TypeError(\"El otro elemento no es un conjunto\")\n        else:\n            my_new_set = MySet()\n            other_set_list = my_other_set.__to_list()\n            for element_a in self.__custom_set:\n                for element_b in other_set_list:\n                    if element_a == element_b:\n                        my_new_set.add_last(element_a)\n            return my_new_set\n        \n    def difference (self,other_set): #nos da como resultado los elementos que estan en el conjunto A pero no en el B\n        if type(other_set) != MySet: #ha de funcionar A / B y B / A\n            raise TypeError(\"El otro elemento no es un conjunto\")\n        else:\n            my_new_set = MySet()\n            temp_list = self.__custom_set.copy()\n            other_set_list = other_set.__to_list()\n            for element_a in self.__custom_set:\n                for element_b in other_set_list:\n                    if element_a == element_b:\n                        temp_list.remove(element_a)\n            for element in temp_list:\n                my_new_set.add_last(element)\n            return my_new_set\n    \n    def simmetric_difference(self,other_set): #nos da como resultado un conjunto que incluye las diferencias A/B y B/A\n        if type(other_set) != MySet:\n            raise TypeError(\"El otro elemento no es un conjunto\")\n        else:\n            my_new_set = MySet()\n            temp_list = self.__custom_set.copy()\n            other_set_list = other_set.__to_list()\n            for element_a in temp_list:\n                for element_b in other_set_list:\n                    if element_a == element_b:\n                        temp_list.remove(element_a)\n                        other_set_list.remove(element_b)\n            for element in (temp_list + other_set_list):\n                my_new_set.add_last(element)\n            return my_new_set\n\n    \nmy_set = MySet(3,\"Alex\",\"Alex\",\"Alex\") #se controla que no se guarden valores repetidos al crear el conjunto\nmy_set.show_set()\nmy_set.add_first(\"hola\") #ni al añadir\nmy_set.add_first(\"hola\")\nmy_set.show_set()\nmy_set.add_last(18.3)\nmy_set.add_last(\"Alex\")\nmy_set.show_set()\nmy_set.add_several_first(\"que\",5,\"que\",\"que\")\nmy_set.show_set()\nmy_set.add_several_last(\"Cenalmor\",11.3,\"Cenalmor\",\"Cenalmor\")\nmy_set.show_set()\nmy_set.erase_element_at_position(\"a\")\nmy_set.erase_element_at_position(0)\nmy_set.erase_element_at_position(7)\nmy_set.show_set()\nmy_set.update_value(\"a\",\"hey\")\nmy_set.update_value(5,\"Valderrama\")\nmy_set.update_value(9,\"sssap\")\nmy_set.show_set()\nmy_set.check_element(\"Alejandro\")\nmy_set.check_element(\"Alex\")\nmy_set.delete_set()\nmy_set.show_set()\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Unión.\n * - Intersección.\n * - Diferencia.\n * - Diferencia simétrica.\n\"\"\"\nmy_set = MySet(\"Alex\",\"Gonzalez\",39)\nmy_other_set= MySet(\"Sole\",\"Gonzalez\",41)\nprint(\"\\n\")\nprint(\"CONJUNTOS\")\nmy_set.show_set()\nmy_other_set.show_set()\nprint(\"\\n\")\nprint(\"UNION\")\nmy_union_set = my_set.union(my_other_set)\nmy_union_set.show_set()\nprint(\"\\n\")\nprint(\"INTERSECCIÓN\")\nmy_intersection_set = my_set.intersection(my_other_set)\nmy_intersection_set.show_set()\nprint(\"\\n\")\nprint(\"DIFERENCIAS\")\nmy_difference_set = my_set.difference(my_other_set)\nmy_difference_set.show_set()\nmy_other_difference_set = my_other_set.difference(my_set)\nmy_other_difference_set.show_set()\nprint(\"\\n\")\nprint(\"DIFERENCIA SIMÉTRICA\")\nmy_simmetric_diff_set = my_set.simmetric_difference(my_other_set)\nmy_simmetric_diff_set.show_set()\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/barrancus.py",
    "content": "\"#18 - Python\"\n# \n# EJERCICIO:\n# Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n# operaciones (debes utilizar una estructura que las soporte):\n# - Añade un elemento al final.\n# - Añade un elemento al principio.\n# - Añade varios elementos en bloque al final.\n# - Añade varios elementos en bloque en una posición concreta.\n# - Elimina un elemento en una posición concreta.\n# - Actualiza el valor de un elemento en una posición concreta.\n# - Comprueba si un elemento está en un conjunto.\n# - Elimina todo el contenido del conjunto.\n# \n# DIFICULTAD EXTRA (opcional):\n# Muestra ejemplos de las siguientes operaciones con conjuntos:\n# - Unión.\n# - Intersección.\n# - Diferencia.\n# - Diferencia simétrica.\n# \ndef serparacion(cadena) -> str:\n    print('{}'.format(cadena * 20))\n\ndef listasset(lista: list) -> set:\n    my_set = lista\n    print(my_set)\n    serparacion('-:-')\n    # Añade un elemento al final.\n    my_set.append('Aguila')\n    print(my_set)\n    serparacion('-:-')\n    # Añade un elemento al principio.\n    my_set.insert(0, 'Elefante')\n    print(my_set)\n    serparacion('-:-')\n    # Añade varios elementos en bloque al final.\n    my_set.extend(['Tigre', 'Yak'])\n    print(my_set)\n    serparacion('-:-')\n    # Añade varios elementos en bloque en una posición concreta.\n    for animal in ['Pato', 'Orca', 'Delfín']:\n        my_set.insert(3, animal)\n    print(my_set)\n    serparacion('-:-')\n    # Elimina un elemento en una posición concreta.\n    my_set.pop(4)\n    print(my_set)\n    serparacion('-:-')\n    # Actualiza el valor de un elemento en una posición concreta.\n    my_set.pop(1)\n    my_set.insert(1, 'Iguana')\n    print(my_set)\n    serparacion('-:-')\n    # Comprueba si un elemento está en un conjunto.\n    tocheck = 'Iguana'\n    print(f'Existe \"{tocheck}\" en \"{my_set}\": {bool(my_set.count(tocheck))}')\n    serparacion('-:-')\n    tocheck = 'Perro'\n    print(f'Existe \"{tocheck}\" en \"{my_set}\": {bool(my_set.count(tocheck))}')\n    serparacion('-:-')\n    my_set_copy = my_set.copy()\n    # Elimina todo el contenido del conjunto.\n    my_set.clear()\n    print(my_set)\n    serparacion('-:-')\n    return set(my_set_copy)\n\ndef setasset(my_set: set) -> None:\n    check_set = {'Tigre', 'Yak', 'Perro', 'Minotauro', 'Hydra'}\n    # Unión.\n    new_set = check_set.union(my_set)\n    print(new_set)\n    serparacion('-\\-')\n    # Intersección.\n    print(my_set.intersection(check_set))\n    serparacion('-\\-')\n    # Diferencia.\n    print(my_set.difference(check_set))\n    print(check_set.difference(my_set))\n    serparacion('-\\-')\n    # Diferencia simétrica.\n    print(my_set.symmetric_difference(check_set))\n    serparacion('-\\-')\n    \ndef main():\n    new_list = ['Perro', 'Gato', 'Leon', 'Cebra']\n    setasset(listasset(new_list))\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/cesar-ch.py",
    "content": "\"\"\"\n    #18 CONJUNTOS\n\"\"\"\n\nconjunto = set()\n\n# añade un elemento\nconjunto.add(\"elemento 1\")\n\n# añade un elemento al inicio\nlista = list(conjunto)\nlista.insert(0, \"elemento 0\")\nconjunto = set(lista)\n\n# añade varios elementos en bloque al final\nconjunto.update([\"elemento 2\", \"elemento 3\"])\n\n# añade varios elementos en bloque en una posición concreta\nlista = list(conjunto)\nlista[1:1] = [\"elemento 0.25\", \"elemento 0.5\", \"elemento 0.75\"]\nconjunto = set(lista)\n\n# elimina un elemento en la posición concreta\nelemento_eliminar = \"elemento 0.25\"\nconjunto.discard(elemento_eliminar)\n\n# actualiza el valor de un elemento en una posición concreta\nlista = list(conjunto)\nposicion = lista.index(\"elemento 0.5\")\nlista[posicion] = \"elemento 0.4\"\nconjunto = set(lista)\n\n# comprueba si un elemento existe\nprint(\"elemento 1\" in conjunto)\n\n# elimina todo el contenido del conjunto\nconjunto.clear()\n\nprint(conjunto)\n\n\n# Eliminar todo el contenido del conjunto\nconjunto.clear()\n\n\"\"\"\n    DIFICULTAD EXTRA\n\"\"\"\nconjunto1 = {1, 2, 3, 4, 5}\nconjunto2 = {4, 5, 6, 7, 8}\n\n# Unión\nunion = conjunto1.union(conjunto2)\nprint(\"Unión:\", union)\n\n# Intersección\ninterseccion = conjunto1.intersection(conjunto2)\nprint(\"Intersección:\", interseccion)\n\n# Diferencia\ndiferencia = conjunto1.difference(conjunto2)\nprint(\"Diferencia:\", diferencia)\n\n# Diferencia simétrica\ndiferencia_simetrica = conjunto1.symmetric_difference(conjunto2)\nprint(\"Diferencia simétrica:\", diferencia_simetrica)\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/cristianfloyd.py",
    "content": " # EJERCICIO:\n # Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n # operaciones (debes utilizar una estructura que las soporte):\n # - Añade un elemento al final.\n # - Añade un elemento al principio.\n # - Añade varios elementos en bloque al final.\n # - Añade varios elementos en bloque en una posición concreta.\n # - Elimina un elemento en una posición concreta.\n # - Actualiza el valor de un elemento en una posición concreta.\n # - Comprueba si un elemento está en un conjunto.\n # - Elimina todo el contenido del conjunto.\n\nfrom typing import Any\nfrom random import randint\n\nmi_lista: list[Any] = [randint(1, 5) for _ in range(7)]\nmi_conjunto_1 = set[Any](mi_lista)\nprint(f\"Lista de numeros enteros: {mi_lista}\")\nprint(f\"Mi set: {mi_conjunto_1}\")\n\n# Inicio ejercicio\n\n# Añade un elemento al final.\nmi_lista.append(\"final\")\nprint(f\"Lista con el elemento al final: {mi_lista}\")\n\n# Añade un elemento al principio.\nmi_lista.insert(0, \"A\")\nprint(f\"Lista con el elemento al principio: {mi_lista}\")\n\n# Añade varios elementos en bloque al final.\nmi_lista.extend([randint(1, 5) for _ in range(3)])\nprint(f\"Lista con los elementos en bloque al final: {mi_lista}\")\n\n# Añade varios elementos en bloque en una posición concreta.\nmi_lista[2:2] = [randint(20,29) for _ in range(3)]\nprint(f\"Lista con los elementos en bloque en una posición concreta: {mi_lista}\")\n\n# comprobar si un elemento esta en la lista\nprint(f\"El elemento 3 esta en la lista: {\"Si\" if 3 in mi_lista else \"NO\"}\")\n\n# eliminar todo el contenido de la lista\nmi_lista.clear()\nprint(f\"Lista con todo el contenido eliminado: {mi_lista}\")\n\n\n #\n # DIFICULTAD EXTRA (opcional):\n # Muestra ejemplos de las siguientes operaciones con conjuntos:\n # - Unión.\n # - Intersección.\n # - Diferencia.\n # - Diferencia simétrica.\n\nmi_set_1 = set([\"A\", \"B\", \"C\", \"D\", \"E\"])\nprint(f\"Mi set inicial: {mi_set_1}\")\n\nmi_set_2 = set([\"B\", \"D\", \"F\", \"G\", \"H\"])\nprint(f\"Mi set inicial: {mi_set_2}\")\n\n# Unión de conjuntos\nmi_set_union = mi_set_1 | mi_set_2\nprint(f\"Unión de conjuntos: {mi_set_union}\")\nprint(f\"Unión de conjuntos: {mi_set_1.union(mi_set_2)}\")\n\n\n# Intersección de conjuntos\nprint(f\"Intersección de conjuntos: {mi_set_1 & mi_set_2}\")\nprint(f\"Intersección de conjuntos: {mi_set_1.intersection(mi_set_2)}\")\n\n# Diferencia de conjuntos\nprint(f\"Diferencia de conjuntos: {mi_set_1 - mi_set_2}\")\nprint(f\"Diferencia de conjuntos: {mi_set_1.difference(mi_set_2)}\")\n\n# Diferencia simétrica de conjuntos\nprint(f\"Diferencia simétrica de conjuntos: {mi_set_1 ^ mi_set_2}\")\nprint(f\"Diferencia simétrica de conjuntos: {mi_set_1.symmetric_difference(mi_set_2)}\")"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/danielhdzr.py",
    "content": "# #18 CONJUNTOS\n#### Dificultad: Fácil | Publicación: 29/04/24 | Corrección: 06/05/24\n\n'''\n * EJERCICIO:\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n * operaciones (debes utilizar una estructura que las soporte):\n * - Añade un elemento al final.\n * - Añade un elemento al principio.\n * - Añade varios elementos en bloque al final.\n * - Añade varios elementos en bloque en una posición concreta.\n * - Elimina un elemento en una posición concreta.\n * - Actualiza el valor de un elemento en una posición concreta.\n * - Comprueba si un elemento está en un conjunto.\n * - Elimina todo el contenido del conjunto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Unión.\n * - Intersección.\n * - Diferencia.\n * - Diferencia simétrica.\n'''\n# Añade un elemento al final.\ndatos = [1,2,3,4]\ndatos.append(5)\nprint(datos)\n\n# Añade un elemento al principio.\ndatos.insert(0,0)\nprint(datos)\n\n# Añade varios elementos en bloque al final.\nun_set = {1,2,3}\nprint(un_set)\nnuevo_set = {4,5,6}\nprint(nuevo_set)\nun_set.update(nuevo_set)\nprint(un_set)\n\n# Añade varios elementos en bloque en una posición concreta.\ndiccionario = {\"k1\":1, \"k5\":5, \"k6\":6}\nprint(diccionario)\notro_dicc = {\"k2\":2, \"k3\":3, \"k4\":4}\nprint(otro_dicc)\ndiccionario.update(otro_dicc)\nnuevo_dict = [key for key in sorted(diccionario)]\nprint(f\"Sin mostrar values {nuevo_dict}\")\nnuevo_dict = {key: diccionario[key] for key in sorted(diccionario)}\nprint(f\"Mostrando values: {nuevo_dict}\")\n\n# Elimina un elemento en una posición concreta.\ndatos.remove(4) # lista\nprint(datos)\n\nmy_set = {1, 2, 3} # set\nmy_set.remove(3)\nprint(my_set)\n\ndel nuevo_dict[\"k6\"] # dicc\nprint(nuevo_dict)\n\n # Actualiza el valor de un elemento en una posición concreta.\ndatos[1] = 4 # lista\nprint(datos)\nnuevo_dict[\"k1\"] = 0.5 # dicc\nprint(nuevo_dict)\n\n# Comprueba si un elemento está en un conjunto.\nprint(2 in datos)\nprint(\"k1\" in nuevo_dict)\nprint(1 in my_set)\n\n\n# Elimina todo el contenido del conjunto.\ndatos.clear() # lista\nprint(datos)\n\nnuevo_dict.clear() # dicc\nprint(nuevo_dict)\n\nmy_set.clear() # set\nprint(my_set)"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/davidrguez98.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n * operaciones (debes utilizar una estructura que las soporte):\n * - Añade un elemento al final.\n * - Añade un elemento al principio.\n * - Añade varios elementos en bloque al final.\n * - Añade varios elementos en bloque en una posición concreta.\n * - Elimina un elemento en una posición concreta.\n * - Actualiza el valor de un elemento en una posición concreta.\n * - Comprueba si un elemento está en un conjunto.\n * - Elimina todo el contenido del conjunto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Unión.\n * - Intersección.\n * - Diferencia.\n * - Diferencia simétrica.\n */ \"\"\"\n\n#EJERCICIO\n\ndata_base = [1, 2, 3, 4, 5]\n\ndata_base.append(6)\nprint(data_base)\n\ndata_base.insert(0, 0)\nprint(data_base)\n\ndata_base.extend([7, 8, 9])\nprint(data_base)\n\ndata_base[2:2] = [-1, -2, -3]\nprint(data_base)\n\ndata_base.pop(2)\nprint(data_base)\n\ndata_base[2] = 2\nprint(data_base)\n\nprint(data_base.index(4))\n\ndata_base.clear()\nprint(data_base)\n\n#DIFICULTAD EXTRA\n\ndata_base_1 = {1, 2, 3, 4, 5}\ndata_base_2 = {1, 2, 6, 7, 8}\n\nprint(data_base_1.union(data_base_2))\n\nprint(data_base_1.intersection(data_base_2))\n\nprint(data_base_1.difference(data_base_2))\n\nprint(data_base_1.symmetric_difference(data_base_2))"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/didacdev.py",
    "content": "def main():\n    test_list = [1, 2, 3, 4]\n\n    test_list.insert(0, 0)\n    test_list.append(5)\n    test_list += [6, 7, 8]\n    test_list[3:3] = [9, 10]\n    test_list.pop(3)\n    test_list[3] = 3\n    is_in_list = True if 10 in test_list else False\n    test_list.clear()\n\n    union_list = list(set([0, 1, 3, 2]) | set([4, 1, 2]))\n    intersection_list = list(set([0, 1, 3, 2]) & set([4, 1, 2]))\n    difference_list = list(set([0, 1, 3, 2]) - set([4, 1, 2]))\n    simetric_difference_list = list(set([0, 1, 3, 2]) ^ set([4, 1, 2]))\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/duendeintemporal.py",
    "content": "#18 { Retos para Programadores } CONJINTOS\n\n# Bibliography reference\n# Professional JavaScript for web developers by Matt Frisbie [Frisbie, Matt] (z-lib.org)\n#Python Notes for Professionals. 800+ pages of professional hints and tricks (GoalKicker.com) (Z-Library)\n# Additionally, I use GPT as a reference and sometimes to correct or generate proper comments.\n\n\"\"\" \n* EJERCICIO:\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n * operaciones (debes utilizar una estructura que las soporte):\n * - Añade un elemento al final.\n * - Añade un elemento al principio.\n * - Añade varios elementos en bloque al final.\n * - Añade varios elementos en bloque en una posición concreta.\n * - Elimina un elemento en una posición concreta.\n * - Actualiza el valor de un elemento en una posición concreta.\n * - Comprueba si un elemento está en un conjunto.\n * - Elimina todo el contenido del conjunto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Unión.\n * - Intersección.\n * - Diferencia.\n * - Diferencia simétrica.\n\n\"\"\"\nimport time\n\n# Function to simulate console.log\nlog = print\n    \nlog('Retosparaprogramadores #18')\n\n# Array operations\narr = [1, 2, 3, 4, 5]\nlog(arr)  # [1, 2, 3, 4, 5]\n\n# Adds an element to the end\narr.append(6)\nlog(arr)  # [1, 2, 3, 4, 5, 6]\n\n# Adds an element to the beginning\narr.insert(0, 0)\nlog(arr)  # [0, 1, 2, 3, 4, 5, 6]\n\n# Adds multiple elements in bulk to the end\narr2 = [7, 8, 9, 10]\narr.extend(arr2)\nlog(arr)  # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n\n# Adds multiple elements in bulk at a specific position\narr3 = [3.1, 3.2, 3.4]\narr[4:4] = arr3\nlog(arr)  # [0, 1, 2, 3, 3.1, 3.2, 3.4, 4, 5, 6, 7, 8, 9, 10]\n\n# Removes an element at a specific position\ndel arr[6]\nlog(arr)  # [0, 1, 2, 3, 3.1, 3.2, 4, 5, 6, 7, 8, 9, 10]\n\n# Updates the value of an element at a specific position\narr[-1] = 9.1\nlog(arr)  # [0, 1, 2, 3, 3.1, 3.2, 4, 5, 6, 7, 8, 9, 9.1]\n\n# Checks if an element is in a set\nnums = set(arr)\nlog('Is 10 in nums:', 10 in nums)  # Is 10 in nums: False\n\n# Removes all content from the set\nnums.clear()\nlog(nums)  # set()\n\n# EXTRA DIFFICULTY (optional):\n\n# Union\narr4 = [10, 11, 12, 13, 14]\nunion = set(arr) | set(arr4)\nlog('Union:', union)  # {0, 1, 2, 3, 3.1, 3.2, 4, 5, 6, 7, 8, 9, 9.1, 10, 11, 12, 13, 14}\n\n# Intersection\narr5 = [1, 4, 5, 6, 15, 16, 17, 18, 19]\nintersection = set()\nfor n in arr5:\n    if n in union:\n        intersection.add(n)\n\nlog('Intersection:', list(intersection))  # [1, 4, 5, 6]\n\n# Difference\ndifference = set(arr)\nfor n in arr5:\n    difference.discard(n)\n\nlog('Difference:', list(difference))  # [0, 2, 3, 3.1, 3.2, 7, 8, 9, 9.1]\n\n# Symmetric difference\nsymmetric_diff = set(arr) ^ set(arr5)\nlog('Symmetric Difference:', list(symmetric_diff))  # [0, 2, 3, 3.1, 3.2, 7, 8, 9, 9.1, 15, 16, 17, 18, 19]\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/fborjalv.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n * operaciones (debes utilizar una estructura que las soporte):\n * - Añade un elemento al final.\n * - Añade un elemento al principio.\n * - Añade varios elementos en bloque al final.\n * - Añade varios elementos en bloque en una posición concreta.\n * - Elimina un elemento en una posición concreta.\n * - Actualiza el valor de un elemento en una posición concreta.\n * - Comprueba si un elemento está en un conjunto.\n * - Elimina todo el contenido del conjunto.\n *\n\"\"\"\n\nmy_list = [1, 2, 3, 4, 5, 6, 7, 8]\n\nprint(my_list)\nprint(\"Añade un elemento al final\")\nmy_list.append(9)\nprint(my_list)\nprint(\"Añade un elemento al principio\")\nmy_list.insert(0, 0)\nprint(my_list)\nprint(\"Añade varios elementos en bloque al final\")\nmy_list.extend([10, 11])\nprint(my_list)\nprint(\"Añade varios elementos en bloque en una posición\")\nmy_list[2:2] = [-1, -2]\nprint(my_list)\nprint(\"Elimina un valor en una posición concreta\")\ndel my_list[7]\nprint(my_list)\nprint(\"Actualiza el valor de un elemento en una posición concreta\")\nmy_list[5] = \"Nuevo dato\"\nprint(my_list)\nprint(\"Comprobar si un elemento está en un conjunto\")\nprint(4 in my_list)\nprint(\"Elmina todo el contenido del conjunto\")\nmy_list.clear()\nprint(my_list)\n\n\n\n\"\"\" \n  * DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Unión.\n * - Intersección.\n * - Diferencia.\n * - Diferencia simétrica.\n */\n\"\"\"\n\nmy_set1 = {2, 3, 4, 5}\nmy_set2 = {3, 5, 6, 8}\n\n\nprint(f\"Conjunto 1: {my_set1}\")\nprint(f\"Conjunto 2: {my_set2}\")\nprint(f\"Unión de conjuntos: {my_set1.union(my_set2)}\")\nprint(f\"Intersección de conjuntos: {my_set1.intersection(my_set2)}\")\nprint(f\"Diferencia de conjuntos: {my_set1.difference(my_set2)}\")\nprint(f\"Diferencia simétrica de conjuntos: {my_set1.symmetric_difference(my_set2)}\")"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/garos01.py",
    "content": "# Creamos un conjunto\nconjunto = set([\"elemento\"])\nprint(conjunto)\n\n# Añadir un elemento al final\nconjunto.add(\"elemento_final\")\nprint(conjunto)\n\n# Añadir un elemento al principio (no se puede directamente en un conjunto, ya que no tienen un orden específico)\n# Sin embargo, podemos usar otro tipo de estructura de datos como una lista para simularlo\nlista_conjunto = list(conjunto)\nlista_conjunto.insert(0, \"elemento_inicio\")\nconjunto = set(lista_conjunto)\nprint(conjunto)\n\n# Añadir varios elementos en bloque al final\nconjunto.update([\"bloque1\", \"bloque2\", \"bloque3\"])\nprint(conjunto)\n\n# Añadir varios elementos en bloque en una posición concreta (no se puede directamente en un conjunto)\n# Pero podemos usar una lista para luego convertirla en conjunto\nlista_conjunto = list(conjunto)\nlista_conjunto[2:2] = [\"nuevo_bloque1\", \"nuevo_bloque2\"]\nconjunto = set(lista_conjunto)\nprint(conjunto)\n\n# Eliminar un elemento en una posición concreta (no se puede directamente en un conjunto)\n# Pero podemos usar una lista para luego convertirla en conjunto\nlista_conjunto = list(conjunto)\nlista_conjunto.pop(1)\nconjunto = set(lista_conjunto)\nprint(conjunto)\n\n# Actualizar el valor de un elemento en una posición concreta (no se puede directamente en un conjunto)\n# Pero podemos usar una lista para luego convertirla en conjunto\nlista_conjunto = list(conjunto)\nlista_conjunto[0] = \"nuevo_valor\"\nconjunto = set(lista_conjunto)\nprint(conjunto)\n\n# Comprobar si un elemento está en el conjunto\nif \"nuevo_valor\" in conjunto:\n    print('El elemento \"nuevo_valor\" está en el conjunto')\nprint(conjunto)\n\n# Eliminar todo el contenido del conjunto\nconjunto.clear()\n\n# Mostrar el conjunto\nprint(conjunto)\n\n\n# Ejercicio extra\n\nconjunto1 = set([1, 2, 3, 4, 5])\nconjunto2 = set([4, 5, 6, 7, 8])\nprint(f\"Conjunto 1: {conjunto1}\\nConjunto 2: {conjunto2}\")\n# Unión\nprint(f\"Unión: {conjunto1.union(conjunto2)}\")\n# Intersección\nprint(f\"Intersección: {conjunto1.intersection(conjunto2)}\")\n# Diferencia\nprint(f\"Diferencia 1: {conjunto1.difference(conjunto2)}\")\nprint(f\"Diferencia 2: {conjunto2.difference(conjunto1)}\")\n# Diferencia simétrica\nprint(f\"Diferencia simétrica: {conjunto1.symmetric_difference(conjunto2)}\")\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/ggilperez.py",
    "content": "# 18 Sets\n\ndata = [1, 2, 3, 4]\nprint(f\"Initial {data = }\")\n\ndata.append(5)\nprint(f\"Insert at end {data = }\")\n\ndata.insert(0, 0)\nprint(f\"Insert at beginning {data = }\")\n\ndata.extend([6,7,8])\nprint(f\"Insert multiple elements {data = }\")\n\ndata[2:2] = [9,11]\nprint(f\"Insert multiple elements at some index {data = }\")\n\ndata.pop(1)\nprint(f\"Remove element at index {data = }\")\n\ndata[3] = 54\nprint(f\"Update element at index {data = }\")\n\nprint(f\"Check if element 3 exists in data: {3 in data}\")\n\ndata.clear()\nprint(f\"Clear {data = }\")\n\n# Extra\nprint(f\"Union {set([1,2]).union(set([3,4])) = }\")\nprint(f\"Intersection {set([1,2]).intersection(set([2,3])) = }\")\nprint(f\"Union {set([1,2]).difference(set([2,3])) = }\")\nprint(f\"Union {set([1,2]).symmetric_difference(set([2,3])) = }\")\n\n\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/gringoam.py",
    "content": "\"\"\"\nEjercicio\n\"\"\"\n\nconjunto=[1,2,3,4]\nprint(f\"Comienzo del conjunto\")\n\n#Agregar elemento al final\nconjunto.append(5)\nprint(f\"Aregando al final {conjunto}\")\n#Agregando al principio\nconjunto.insert(0,0)\nprint(f\"Aregando al principio {conjunto}\")\n#Agrega unbloque de elementos al final\nconjunto.extend([6,7,8,])\nprint(f\"Aregando un bloque final {conjunto}\")\n#Agrega unbloque de elementos en la pcisión 3\nconjunto[3:3]=[9,10,11]\nprint(f\"Aregando un bloque en pocisión concreta {conjunto}\")\n#Elimina un ellemnto de una pocisión concreta\n#conjunto.pop(3)\ndel conjunto[3]\nprint(f\"Elimina un elemnto pocisión concreta {conjunto}\")\n#Actualiza valor de un elemneto en una pocosión concreta\nconjunto[3]=9\nprint(f\"Actualiza el valor de pocision concreta {conjunto}\")\n#Corrobora si un elemnto está en el conjunto\nvalor=3\nprint(f\"Comprobar si {valor} está en {conjunto}  {valor in conjunto}\")\n#Elimina todos los elementos\nconjunto.clear()\nprint(conjunto)\n\n\"\"\"\nExtra\n\"\"\"\n\nconj_1={1,2,3,4,5}\nconj_2={1,2,3,4,6,7}\n\nprint(conj_1)\nprint(conj_2)\n\nprint(f\"Union de conjuntos {conj_1.union(conj_2)}\")\nprint(f\"Intersección de conjuntos {conj_1.intersection(conj_2)}\")\nprint(f\"Diferencia de conjuntos {conj_1.difference(conj_2)}\")\nprint(f\"Diferencia simetrica de conjuntos {conj_1.symmetric_difference(conj_2)}\")\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/h4ckxel.py",
    "content": "def main():\n    test_list = [1, 2, 3, 4]\n\n    test_list.insert(0, 0)\n    test_list.append(5)\n    test_list += [6, 7, 8]\n    test_list[3:3] = [9, 10]\n    test_list.pop(3)\n    test_list[3] = 3\n    is_in_list = True if 10 in test_list else False\n    test_list.clear()\n\n    union_list = list(set([0, 1, 3, 2]) | set([4, 1, 2]))\n    intersection_list = list(set([0, 1, 3, 2]) & set([4, 1, 2]))\n    difference_list = list(set([0, 1, 3, 2]) - set([4, 1, 2]))\n    simetric_difference_list = list(set([0, 1, 3, 2]) ^ set([4, 1, 2]))\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/hectorio23.py",
    "content": "# Autor: Héctor Adán\n# GitHub: https://github.com/hectorio23\n\n\n# EJERCICIO:\n# Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n# operaciones (debes utilizar una estructura que las soporte):\n# - Añade un elemento al final.\n# - Añade un elemento al principio.\n# - Añade varios elementos en bloque al final.\n# - Añade varios elementos en bloque en una posición concreta.\n# - Elimina un elemento en una posición concreta.\n# - Actualiza el valor de un elemento en una posición concreta.\n# - Comprueba si un elemento está en un conjunto.\n# - Elimina todo el contenido del conjunto.\n\n# DIFICULTAD EXTRA (opcional):\n# Muestra ejemplos de las siguientes operaciones con conjuntos:\n# - Unión.\n# - Intersección.\n# - Diferencia.\n# - Diferencia simétrica.\n\nlista = [1, 2, 3, 4, 5, 6, 7, 8, 9]\nprint(f\"*Lista antes de ser modificada: \\n{ lista }\")\n\n# Añadiend un elemento al final de la lista \nlista.append(\"Ultimo elemento\")\nprint(f\"\\n*Lista al agregarle un elemento al final: \\n{ lista }\")\n\n# Añadiend un elemento al inicio de la lista \nlista.insert(0, \"Primer elemento\")\nprint(f\"\\n*Lista al agregarle un elemento al inicio: \\n{ lista }\")\n\n# Añadiend varios elementos al final de la lista\nlista.append([word for word in \"Hola Mundo\"])\nprint(f\"\\n*Lista al agregarle varios elemento al inicio: \\n{ lista }\")\n\n# Añadiend varios elementos al inicio de la lista\nlista.insert(0, [word for word in \"Refugio\"])\nprint(f\"\\n*Lista al agregarle varios elemento al inicio: \\n{ lista }\")\n\n# Eliminar un elemento de una posicion concreta\nlista.remove(lista.index(4))\nprint(f\"\\n*Lista despues de eliminar el elemento en la posicion4: \\n{ lista }\")\n\n# Actualizar un elemento en una posicion concreta\nlista[2] = \"Elemento actualizado\"\nprint(f\"\\n*Lista despues de actualizar el elemento No.2: \\n{ lista }\")\n\n# Comprobar si un elemento esta e un conjunto\nresponse = 4 in lista\nprint(f\"\\n*¿Está el número 4 en la lista?: \\n{ response }\")\n\n# Eliminar todos llos valores contenidos en la lista\nlista.clear()\nprint(f\"\\n*Lista despues de haber eliminado todos sus valores: \\n{ lista }\")\n\nA = { 1, 2 , 4, 5, 6, 7, 8, 9 }\nB = { 10, 35 , 575, 5, 6, 57, 8, 90 }\n\nprint(f\"****** Conjuntos A { A } y B { B } ******\\n\")\n\n# - Unión.\nprint(f\"Union A | B: { A | B }\")\n# - Intersección. \nprint(f\"Union A & B: { A & B }\")\n# - Diferencia.\nprint(f\"Union A - B: { A - B }\")\n# - Diferencia simétrica.\nprint(f\"Union A ^ B: { A ^ B }\")"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/hozlucas28.py",
    "content": "# pylint: disable=missing-function-docstring,pointless-string-statement,expression-not-assigned\n\n\"\"\"\n    Sets...\n\"\"\"\n\nprint(\"Sets...\")\n\nstates: list[str] = [\"Buenos Aires\", \"Texas\", \"Madrid\", \"Houston\", \"California\"]\n\n\nprint('\\nstates: list[str] = [\"Texas\", \"Madrid\", \"Houston\", \"California\"]')\n\nprint(f\"{states=}\")\n\nprint(\"\\nAppend new state at the end...\")\nprint('\\nstates.append(\"Berlin\")')\n\nstates.append(\"Berlin\")\nprint(f\"{states=}\")\n\nprint(\"\\nAppend new state at the start...\")\nprint('\\nstates.insert(0, \"Chaco\")')\n\nstates.insert(0, \"Chaco\")\nprint(f\"{states=}\")\n\nprint(\"\\nAppend several states at the end...\")\nprint('\\nstates.extend([\"Paris\", \"Montana\"])')\n\nstates.extend([\"Paris\", \"Montana\"])\nprint(f\"{states=}\")\n\nprint(\"\\nAppend several states at index 4...\")\nprint('\\nstates = [*states[0:4], *[\"Jujuy\", \"Formosa\"], *states[4:]]')\n\nstates = [*states[0:4], *[\"Jujuy\", \"Formosa\"], *states[4:]]\nprint(f\"{states=}\")\n\nprint(\"\\nDelete state at index 3...\")\nprint(\"\\nstates = [*states[0:3], *states[3 + 1:]]\")\n\nstates = [*states[0:3], *states[3 + 1 :]]\nprint(f\"{states=}\")\n\nprint(\"\\nUpdate state at index 6...\")\nprint('\\nstates[6] = \"Miami\"')\n\nstates[6] = \"Miami\"\nprint(f\"{states=}\")\n\nprint(\"\\nCheck if a state is present...\")\nprint(f'\\nstates.count(\"Buenos Aires\") > 0 => {states.count(\"Buenos Aires\") > 0}')\n\nprint(f\"{states=}\")\n\nprint(\"\\nClear saved data...\")\nprint(\"\\ndata.clear()\")\n\nstates.clear()\nprint(f\"{states=}\")\n\nprint(\n    \"\\n# ---------------------------------------------------------------------------------- #\\n\"\n)\n\n\"\"\"\n    Additional challenge...\n\"\"\"\n\nprint(\"Additional challenge...\")\n\nfirst_set: set[str] = {\"Hello\", \"TypeScript\", \"World!\"}\nsecond_set: set[str] = {\"By\", \"TypeScript\"}\n\nprint(f\"\\n{first_set=}\")\nprint(f\"{second_set=}\")\n\nintersected: set[str] = first_set.intersection(second_set)\n\nprint(\"\\nintersected: set[str] = first_set.intersection(second_set)\")\nprint(f\"{intersected=}\")\n\njoined: set[str] = first_set.union(second_set)\n\nprint(\"\\njoined: set[str] = first_set.union(second_set)\")\nprint(f\"{joined=}\")\n\ndifference: set[str] = first_set.difference(second_set)\n\nprint(\"\\ndifference: set[str] = first_set.difference(second_set)\")\nprint(f\"{difference=}\")\n\nsymmetric_difference: set[str] = first_set.symmetric_difference(second_set)\n\nprint(\"\\nsymmetric_difference: set[str] = first_set.symmetric_difference(second_set)\")\nprint(f\"{symmetric_difference=}\")\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/idiegorojas.py",
    "content": "\"\"\"\nConjuntos\n\"\"\"\n\n# Son una coleccion desordenada de elementos unicos.\n# Son utiles cuando cuandos se necesita almacenar elmentes sin duplicados. \n# Sirve para hacer operaciones matematicas como union, interseccion y diferencia.\n\n\"\"\"\nCrear un conjunto\n\"\"\"\n# Usando llaves\nmi_conjunto = {1,2,3,4,5}\nprint(mi_conjunto)\n\n\nprint('----------')\n\n\n# Usando la funcion set()\notro_conjunto = set([1,2,2,3,4,4,5,5,5]) # Se eliminan los duplicados automaticamente\nprint(otro_conjunto)\n\n\nprint('----------')\n\n\n\"\"\"\nOperaciones comunes\n\"\"\"\n\n# Agregar un elemento: .add()\nmi_conjunto = {1,2,3}\nmi_conjunto.add(4)\nprint(mi_conjunto)\n\n\nprint('----------')\n\n\n# Eliminar elementos: .remove()\nmi_conjunto.remove(2)\nprint(mi_conjunto)\n\n\n# Union: '|' o '.union()'\nconjunto_uno = {1, 2, 3}\nconjunto_dos = {3, 4, 5}\nunion = conjunto_uno | conjunto_dos\nprint(union)\n\n\n# Interseccion: Encuentra elementos comunes '&' o intersection()\ninterseccion = conjunto_uno & conjunto_dos\nprint(interseccion)\n\n\n# Diferencia: Elementos de un conjunto pero no en otro '-' o '.difference()'\ndiferencia = conjunto_uno - conjunto_dos\nprint(diferencia)\n\n\n\"\"\"\nCasos de usos\n\"\"\"\n\n# Eliminar duplicados de una lista\n# Verificar membresias rapidamente\n# Operaciones matematicas entre grupos de datos\n\n\n\"\"\"\nEjercicio\n\"\"\"\n\ndatos = [1, 2, 3, 4, 5]\nprint(f'Estructura inicial: {datos}')\n\n #Añade un elemento al final.\ndatos.append(6)\nprint(datos)\n\n # Añade un elemento al principio.\ndatos.insert(0, 0)\nprint(datos)\n\n # Añade varios elementos en bloque al final.\ndatos.extend([7, 8, 9])\nprint(datos)\n\n # Añade varios elementos en bloque en una posición concreta.\ndatos[4:4] = [-1,-2,-3]\nprint(datos)\n\n # Elimina un elemento en una posición concreta.\ndel datos[3]\nprint(datos)\n\n # Actualiza el valor de un elemento en una posición concreta.\ndatos[3:6] = [3,4,5]\nprint(datos)\n \n # Comprueba si un elemento está en un conjunto.\nprint(-1 in datos)\n\n # Elimina todo el contenido del conjunto.\ndatos.clear()\nprint(datos)\n\n\n\"\"\"\nExtra\n\"\"\"\n\ndatos_uno = {1,2,3,4,5}\ndatos_dos = {2,3,4,5,6}\n\n# Unión.\nunion = datos_uno | datos_dos\nprint(union)\n\n# Intersección.\ninterseccion = datos_uno & datos_dos\nprint(interseccion)\n\n# Diferencia.\ndiferencia_uno = datos_uno - datos_dos\ndiferencia_dos = datos_dos - datos_uno\nprint(diferencia_uno)\nprint(diferencia_dos)\n\n# Diferencia simétrica.\ndiferencia_simetrica = datos_uno.symmetric_difference(datos_dos)\nprint(diferencia_simetrica)\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/ignaciovihe.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n * operaciones (debes utilizar una estructura que las soporte):\n * - Añade un elemento al final.\n * - Añade un elemento al principio.\n * - Añade varios elementos en bloque al final.\n * - Añade varios elementos en bloque en una posición concreta.\n * - Elimina un elemento en una posición concreta.\n * - Actualiza el valor de un elemento en una posición concreta.\n * - Comprueba si un elemento está en un conjunto.\n * - Elimina todo el contenido del conjunto.\n *\n\"\"\"\n\nmy_list = [i for i in range (1,11)]\nprint(my_list)\n\n#Añadir elemento al final\n\nmy_list.append(\"a\")\nprint(my_list)\n\n#Añadir elemento al principio\n\nmy_list.insert(0, \"b\")\nprint(my_list)\n\n#Añadir elementos en bloque al final.\n\nmy_second_list = [\"c\", \"d\"]\nmy_list.extend(my_second_list)\nprint(my_list)\n\n#Añade elementos en bloque en posición concreta\n\nmy_empty_list = []\nmy_third_list = [\"e\", \"f\"]\nmy_list[2:2] = my_third_list #inserta los valores en el índice indicado\nprint(my_list)\nmy_list[2:4] = my_empty_list # Sustituye los valores entre los indices por los nuevos. EN este caso los borra porque la listga esta vacia.\nprint(my_list)\n\n#Eliminar un elemento de posición concreta\n\nelement = my_list.pop(6) # Tambien del my_list[6]\nprint(element)\nprint(my_list)\n\n#Actualiza el elemento de una posición\n\nmy_list[4] = \"e\"\nprint(my_list)\n\n# Comprobar si u elemento esta en un conjunto\n\nelement= 10\nprint(f\" {element} Esta en la lista: {element in my_list} --> Posición: {my_list.index(element) if element in my_list else \"-\"}\")\n\n# Eliminar el contenido de un conjunto\n\nmy_list.clear()\nprint(my_list)\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Unión.\n * - Intersección.\n * - Diferencia.\n * - Diferencia simétrica.\n\"\"\"\n\nset_a = {\"j\", \"g\", \"i\", \"f\", \"p\", \"a\", \"r\"}\nset_b = {\"g\", \"l\", \"r\", \"f\", \"b\", \"i\"}\n\n#Unión\nprint(set_a | set_b) # Une los elementos de ambos conjuntos (sin duplicados).\n\n\n#Initersección\nprint(set_a & set_b) # Devuelve los elementos comunes entre ambos conjuntos.\n\n\n#Diferencia\n\nprint(set_a - set_b) # Elementos que están en A pero no en B (Como una resta)\nprint(set_b - set_a) #Elementos que están en B pero no en A (Como una resta)\n\n#Diferencia simetrica\nprint(set_a ^ set_b) #Elementos que están en A o en B, pero no en ambos."
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/isilanes.py",
    "content": "def main():\n    print(\"\\n==== Ejercicio ====\")\n    collection = [1, 2, 3]\n    print(f\"El conjunto inicial (una lista): {collection}\")\n\n    print(\"\\nAñadimos el elemento '4' al final:\")\n    print('>>> collection.append(4)')\n    collection.append(4)\n    print(f\"El conjunto actualizado: {collection}\")\n\n    print(\"\\nAñadimos el elemento '-1' al inicio (posición 0):\")\n    print('>>> collection.insert(0, -1)')\n    collection.insert(0, -1)\n    print(f\"El conjunto actualizado: {collection}\")\n\n    print(\"\\nAñadimos los elementos '[5, 6, 7]' en bloque al final:\")\n    print('>>> collection.extend([5, 6, 7])')\n    collection.extend([5, 6, 7])\n    print(f\"El conjunto actualizado: {collection}\")\n\n    print('\\nAñadimos los elementos \\'[\"a\", \"b\",  \"c\"]\\' en bloque en la posición 2 (entre el 1 y el 2):')\n    print('>>> collection[2:2] = [\"a\", \"b\", \"c\"]')\n    collection[2:2] = [\"a\", \"b\", \"c\"]\n    print(f\"El conjunto actualizado: {collection}\")\n\n    print('\\nEliminamos el elemento en la posición 5 (el 2):')\n    print('>>> collection.pop(5)')\n    collection.pop(5)\n    print(f\"El conjunto actualizado: {collection}\")\n\n    print('\\nActualizamos el elemento en la posición 3 (la \"b\") al valor \\'True\\':')\n    print('>>> collection[3] = True')\n    collection[3] = True\n    print(f\"El conjunto actualizado: {collection}\")\n\n    print(\"\\nComprobamos el conjunto contiene el valor '4':\")\n    print(f\"El conjunto contiene un 4?: 4 in collection = {4 in collection}\")\n\n    print('\\nVaciamos el conjunto (sin sustituir el objeto por otro vacío):')\n    print(f\">>> id(collection) = {id(collection)}\")\n    print('>>> collection[:] = []')\n    collection[:] = []\n    print(f\"El conjunto actualizado: {collection}\")\n    print(f\">>> id(collection) = {id(collection)}\")\n\n\ndef extra():\n    print(\"\\n==== Extra ====\")\n    print(\"Dado que no se indica que deba usarse el mismo tipo de conjunto que en el ejercicio anterior,\")\n    print(\"en este caso usaré objetos set(), o literalmente 'conjunto' en castellano.\")\n    print('>>> odd = {1, 3, 5, 7, 9, 11}')\n    print('>>> prime = {1, 2, 3, 5, 7, 11}')\n    odd = {1, 3, 5, 7, 9, 11}\n    prime = {1, 2, 3, 5, 7, 11}\n\n    print(\"\\nUnión de primos e impares:\")\n    print('>>> res = odd | prime')\n    res = odd | prime\n    print(f\"Resultado: {res}\")\n\n    print(\"\\nIntersección de primos e impares:\")\n    print('>>> res = odd & prime')\n    res = odd & prime\n    print(f\"Resultado: {res}\")\n\n    print(\"\\nDiferencia entre primos e impares:\")\n    print('>>> res = prime - odd')\n    res = prime - odd\n    print(f\"Resultado: {res}\")\n    print(\"Nótese que, a diferencia de las otras 3 operaciones, la diferencia no es conmutativa.\")\n    print(\"Hemos hecho la diferencia entre primos e impares, que son todos los primos que no son impares.\")\n    print(\"Si hubiéramos hecho la diferencia entre impares y primos, el resultado habría sido {9},\")\n    print(\"el número impar que no es primo.\")\n\n    print(\"\\nDiferencia simétrica entre primos e impares:\")\n    print('>>> res = odd ^ prime')\n    res = odd ^ prime\n    print(f\"Resultado: {res}\")\n\n\nif __name__ == \"__main__\":\n    main()\n    extra()\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/jptxaya.py",
    "content": "# # #18 CONJUNTOS\n\n# /*\n#  * EJERCICIO:\n#  * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n#  * operaciones (debes utilizar una estructura que las soporte):\n#  * - Añade un elemento al final.\n#  * - Añade un elemento al principio.\n#  * - Añade varios elementos en bloque al final.\n#  * - Añade varios elementos en bloque en una posición concreta.\n#  * - Elimina un elemento en una posición concreta.\n#  * - Actualiza el valor de un elemento en una posición concreta.\n#  * - Comprueba si un elemento está en un conjunto.\n#  * - Elimina todo el contenido del conjunto.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Muestra ejemplos de las siguientes operaciones con conjuntos:\n#  * - Unión.\n#  * - Intersección.\n#  * - Diferencia.\n#  * - Diferencia simétrica.\n#  */\n\nmy_conj = [0,1,2,3,4]\nprint(my_conj)\n\nprint(\"Add element at the end\")\nmy_conj.append(5)\nprint(my_conj)\n\nprint(\"Add a element at the beginning\")\nmy_conj.insert(0,-1)\nprint(my_conj)\n\nprint(\"Add several items at the end\")\nmy_conj2 = [6,7]\nmy_conj = my_conj + my_conj2\nprint(my_conj)\n\nprint(\"Add several items at a position\")\nmy_conj3 = [4.5 ,4.7]\nmy_conj[6:6] = my_conj3\nprint(my_conj)\n\nprint(\"Delete item at specified position\")\nmy_conj.pop(7)\nprint(my_conj)\n\nprint(\"Update a value at specified position\")\nmy_conj[6] = 4.2\nprint(my_conj)\n\nprint(\"Check if the value exist\")\ntry:\n    my_conj.index(8)\nexcept ValueError as ex:\n    print(ex.args)\n\nprint(\"Delete all content\")\nmy_conj.clear()\nprint(my_conj)\n\nprint(\"Dificultad extra\")\nmy_conj1 = [1,2,3]\nmy_conj2 = [3,4,5]\nprint(f\"Conj1:  {my_conj1}\")\nprint(f\"Conj2:  {my_conj2}\")\nprint(\"Union\")\nmy_conj_union = my_conj1 + my_conj2\nprint(my_conj_union)\n\nprint(\"Interseccion\")\nmy_conj_inter = set(my_conj1).intersection(set(my_conj2))\nprint(list(my_conj_inter))\n\nprint(\"Difference\")\nmy_conj_dif = set(my_conj1).difference(set(my_conj2))\nprint(list(my_conj_dif))\n\nprint(\"Symetric Difference\")\nmy_conj_sdif = set(my_conj1).symmetric_difference(set(my_conj2))\nprint(list(my_conj_sdif))\n\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/juanchernandezdev.py",
    "content": "### Python Data Structures ###\n\nmy_data = [1, 4, 5, 8, 10, 50, 100, 500]\n\nmy_data.append(800)\nprint(my_data)\n\nmy_data.insert(0, 200)\nprint(my_data)\n\nmy_data.extend([4, 8, 15])\nprint(my_data)\n\nmy_data[4:5] = [12, 14, 16]\nprint(my_data)\n\nmy_data.pop(-1)\nmy_data.pop(5)\nprint(my_data)\n\nmy_data[2] = 800\nprint(my_data)\n\nprint(800 in my_data)\n\nmy_data.clear()\nprint(my_data)\n\n#! Optional Challenge\nlist_one = [1, 5, 8, 10, 12, 15]\nlist_two = [20, 11, 15, 45, 8, 50]\n\n#? Union\nnew_list = list_one + list_two\nnew_list = [*list_one, *list_two]\nprint(new_list)\n\n#? Intersection\nintersection_list = [num for num in list_one if num in list_two]\nprint(intersection_list)\n\n#? Differece\ndifference_list = [num for num in list_one if num not in list_two]\nprint(difference_list)\n\n#? Symmetric Difference\nsymm_diff_list = list(set(list_one).symmetric_difference(set(list_two)))\nprint(symm_diff_list)\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/juandaherrera.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n * operaciones (debes utilizar una estructura que las soporte):\n * - Añade un elemento al final.\n * - Añade un elemento al principio.\n * - Añade varios elementos en bloque al final.\n * - Añade varios elementos en bloque en una posición concreta.\n * - Elimina un elemento en una posición concreta.\n * - Actualiza el valor de un elemento en una posición concreta.\n * - Comprueba si un elemento está en un conjunto.\n * - Elimina todo el contenido del conjunto.\n\"\"\"\n\nmy_set = [1, 2, 3, 4, 5]\nmy_set.append(6)\nmy_set.insert(0, 0)\nmy_set.extend([7, 8, 9])\nmy_set[3:3] = [-1, -2, -3]\ndel my_set[3]\nmy_set[4] = -1\nprint(-1 in my_set)\n\nprint(my_set)\nmy_set.clear()\nprint(my_set)\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Unión.\n * - Intersección.\n * - Diferencia.\n * - Diferencia simétrica.\n\"\"\"\n\nmy_new_set = {1, 2, 3, 4, 5}\nmy_other_set = {1, 2, 3, 4, 6, 7}\n\nprint(f\"{my_new_set=}, {my_other_set=}\")\nprint(\"Union:\", my_new_set.union(my_other_set))\nprint(\"Intersección:\", my_new_set.intersection(my_other_set))\nprint(\"Diferencia:\", my_new_set.difference(my_other_set))\nprint(\"Diferencia Simétrica:\", my_other_set.symmetric_difference(my_new_set))\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/juanmax2.py",
    "content": "\"\"\"\nConjuntos:\n\n\"\"\"\n\nmy_list = [1, 2, 3]\n\n# Añade un elemento al final.\nmy_list.append(4)\nprint(my_list)\n\n# Añade un elemento al principio.\nmy_list.insert(0, 0)\nprint(my_list)\n\n# Añade varios elementos en bloque al final.\nmy_list.extend([5, 6, 7])\nprint(my_list)\n\n# Añade varios elementos en bloque en una posición concreta.\nmy_list[3:3] = [4, 3, 2]\nprint(my_list)\n\n# Elimina un elemento en una posición concreta.\ndel my_list[3]\nprint(my_list)\n\n# Actualiza el valor de un elemento en una posición concreta.\nmy_list[0] = 2\nprint(my_list)\n\n# Comprueba si un elemento está en un conjunto.\nprint(2 in my_list)\n\n# Elimina todo el contenido del conjunto.\n#del my_list[:]\nmy_list.clear()\nprint(my_list)\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Unión.\n * - Intersección.\n * - Diferencia.\n * - Diferencia simétrica.\n\"\"\"\n\nelements_1 = {1, 2, 3, 4}\nelements_2 = {1, 3, 7, 5}\n\n# Unión\nprint(f\"Unión: {elements_1.union(elements_2)}\")\n\n# Intersección\nprint(f\"Intersección: {elements_1.intersection(elements_2)}\")\n\n# Diferencia\nprint(f\"Diferencia: {elements_1.difference(elements_2), elements_2.difference(elements_1)}\")\n\n# Diferencia simétrica\nprint(f\"Intersección: {elements_1.symmetric_difference(elements_2)}\")"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/juanppdev.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n * operaciones (debes utilizar una estructura que las soporte):\n * - Añade un elemento al final.\n * - Añade un elemento al principio.\n * - Añade varios elementos en bloque al final.\n * - Añade varios elementos en bloque en una posición concreta.\n * - Elimina un elemento en una posición concreta.\n * - Actualiza el valor de un elemento en una posición concreta.\n * - Comprueba si un elemento está en un conjunto.\n * - Elimina todo el contenido del conjunto.\n\"\"\"\n\n# Crear un conjunto de datos (lista)\ndatos = [1, 2, 3, 4, 5]\n\n# Añadir un elemento al final\ndatos.append(6)\nprint(\"Añadir al final:\", datos)\n\n# Añadir un elemento al principio\ndatos.insert(0, 0)\nprint(\"Añadir al principio:\", datos)\n\n# Añadir varios elementos en bloque al final\ndatos.extend([7, 8, 9])\nprint(\"Añadir varios al final:\", datos)\n\n# Añadir varios elementos en bloque en una posición concreta\ndatos[3:3] = [10, 11, 12]\nprint(\"Añadir varios en posición 3:\", datos)\n\n# Eliminar un elemento en una posición concreta\ndel datos[4]\nprint(\"Eliminar en posición 4:\", datos)\n\n# Actualizar el valor de un elemento en una posición concreta\ndatos[2] = 99\nprint(\"Actualizar en posición 2:\", datos)\n\n# Comprobar si un elemento está en el conjunto\nelemento = 99\nprint(f\"¿Está {elemento} en el conjunto?:\", elemento in datos)\n\n# Eliminar todo el contenido del conjunto\ndatos.clear()\nprint(\"Eliminar todo el contenido:\", datos)\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Unión.\n * - Intersección.\n * - Diferencia.\n * - Diferencia simétrica.\n\"\"\"\n\n# Crear dos conjuntos de datos\nconjunto1 = {1, 2, 3, 4, 5}\nconjunto2 = {4, 5, 6, 7, 8}\n\n# Unión\nunion = conjunto1.union(conjunto2)\nprint(\"Unión:\", union)\n\n# Intersección\ninterseccion = conjunto1.intersection(conjunto2)\nprint(\"Intersección:\", interseccion)\n\n# Diferencia\ndiferencia = conjunto1.difference(conjunto2)\nprint(\"Diferencia:\", diferencia)\n\n# Diferencia simétrica\ndiferencia_simetrica = conjunto1.symmetric_difference(conjunto2)\nprint(\"Diferencia simétrica:\", diferencia_simetrica)\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/kenysdev.py",
    "content": "# ╔═════════════════════════════════════╗\n# ║ Autor:  Kenys Alvarado              ║\n# ║ GitHub: https://github.com/Kenysdev ║\n# ║ 2024 -  Python                      ║\n# ╚═════════════════════════════════════╝\n\n# -----------------------------------\n# * CONJUNTOS\n# -----------------------------------\n# Son una colección desordenada de elementos únicos.\nmy_set: set = {1, 2, 3, 0}\n\n\"\"\"\n * EJERCICIO #1:\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n * operaciones (debes utilizar una estructura que las soporte):\n\"\"\"\n# Algunas operaciones del ejercicio no pueden realizarse utilizando 'set'.\nmy_list: list = [\"a\", \"b\", \"c\"]\n\n# Añade un elemento al final.\nmy_list.append(\"d\")\n\n# Añade un elemento al principio.\nmy_list.insert(0, \"-\")\n\n# Añade varios elementos en bloque al final.\nmy_list.extend([\"e\", \"f\"])\n\n# Añade varios elementos en bloque en una posición concreta.\nmy_list[4:4] = \"-\", \">\"\n\n# Elimina un elemento en una posición concreta.\ndel my_list[5]\n\n# Actualiza el valor de un elemento en una posición concreta.\nmy_list[2] = \"-b\"\n\nprint(my_list)\nprint(my_set)\n\n# Comprueba si un elemento está en un conjunto.\nprint(f\"4 en conjunto: {4 in my_set}\")\nprint(f\"c en lista: {'c' in my_list}\")\n\n# Elimina todo el contenido del conjunto.\nmy_set.clear()\nmy_list.clear()\n\n\"\"\"\n* EJERCICIO #2:\n* Muestra ejemplos de las siguientes operaciones con conjuntos:\n* - Unión.\n* - Intersección.\n* - Diferencia.\n* - Diferencia simétrica.\n\"\"\"\n\nset_1: set = {1, 2, 3, 4}\nset_2: set = {3, 4, 5, 6}\n\nprint(f\"\"\"\n* set_1: {set_1} - set_2: {set_2}\n\n- Unión: {set_1 | set_2}\n  Elementos que están en al menos uno de los conjuntos.\n\n- Intersección: {set_1 & set_2}\n  Elementos que están en ambos conjuntos.\n\n- Diferencia: {set_1 - set_2}\n  Elementos que están en set_1 pero no en set_2\n\n- Diferencia simétrica: {set_1 ^ set_2}\n  Elementos que están en uno de los conjuntos pero no en ambos.\n\"\"\")\n\n\"\"\"\nNota: También pueden usarse los métodos::\n      - union()\n      - intersection()\n      - difference()\n      - symmetric_difference()\n\"\"\"\n\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/mariovelascodev.py",
    "content": "languages = ['python', 'c', 'php']\n\n#Añade un elemento al final\nlanguages.append('ruby')\n\n#Añade un elemento al principio\nlanguages.insert(0, 'java') \n\n#Añade varios elementos al bloque final\nother_languages = ['javascript', 'rust']\nlanguages.extend(other_languages)\n\n#Añade varios elementos en una posición concreta\nlanguages[2:2] = ['Go', 'Kotlin']\n\n#Elimina elementos de una posición concreta\nlanguages.pop(4)\n\n#Actualiza el valor de una posición concreta\nlanguages[2] = 'go'\n\n#Comprueba si un elemento esta en un conjunto\nif 'python' in languages:\n    print(\"Elemento encontrado\")\nelse:\n    print(\"Elemento no encontrado\")\n\n#Elimina todo el contenido del conjunto\nlanguages.clear()\n\nprint(languages)\n\n#EXTRA\n\nnumber_list_1 = {1, 2, 3, 5}\nnumber_list_2 = {4, 5, 6, 7}\n\n#Unión\nunion_list = number_list_1.union(number_list_2)\nprint(f\"La unión de los dos conjuntos es: {union_list}\")\n\n#Intersección\nintersection_list = number_list_1.intersection(number_list_2)\nprint(f\"La intersección de los dos conjuntos es: {intersection_list}\")\n\n#Diferencia\ndifference_list = number_list_2.difference(number_list_1)\nprint(f\"La diferencia entre los dos conjuntos es: {difference_list}\")\n\n#Diferencia simétrica\nsymmetric_list = number_list_1.symmetric_difference(number_list_2)\nprint(f\"La diferencia simétrica de los conjuntos es: {symmetric_list}\")"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/mhayhem.py",
    "content": "# @Author Mhayhem\n\n# EJERCICIO:\n# Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n# operaciones (debes utilizar una estructura que las soporte):\n\nmy_list = [1, 2, 3]\n\n# - Añade un elemento al final.\n\nmy_list.append(4)\n\n# - Añade un elemento al principio.\n\nmy_list.insert(0, 0)\n\n# - Añade varios elementos en bloque al final.\n\nmy_list.extend([7, 8]) # otra opciones seria my_list += [7, 8], my_list[len(my_list): ] = [7, 8]\n\n# - Añade varios elementos en bloque en una posición concreta.\n\nmy_list[5:5] = [5, 6]\n\n# - Elimina un elemento en una posición concreta.\n\nmy_list.pop(2)\n\n# - Actualiza el valor de un elemento en una posición concreta.\n\nmy_list[3] = 10\n\n# - Comprueba si un elemento está en un conjunto.\n\nis_in = 7 in my_list\n\n# - Elimina todo el contenido del conjunto.\n\nmy_list.clear()\n\n# DIFICULTAD EXTRA (opcional):\n# Muestra ejemplos de las siguientes operaciones con conjuntos:\n\ns1 = {1, 2, 3}\ns2 = {\"a\", \"b\", \"c\"}\n\n# - Unión.\n\ns_union = s1.union(s2)\n\n# - Intersección.\n\ns3 = s1.intersection({\"a\", 2, \"d\", 6})\n\n# - Diferencia.\n\ndiff = s1.difference(s3)\n\n# - Diferencia simétrica.\n\ns1.symmetric_difference({1, 2, 4, 5})"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/mikelm2020.py",
    "content": "my_set = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}\n\n# ejercicio\n\nprint(\"Ejercio\")\nprint(\"Conjunto a trabajar\")\nprint(my_set)\nprint(\"\\nAñade un elemento al final, añadimos el 11\")\nmy_set.add(11)\nprint(my_set)\n\nprint(\"\\nAñade un elemento al principio, añadimos el 0\")\nmy_list = list(my_set)\nmy_list.insert(0, 0)\nmy_set = set(my_list)\nprint(my_set)\n\nprint(\"\\nAñade varios elementos en bloque al final, añadimos 13,14,15,16\")\nmy_list = [13, 14, 15, 16]\nmy_set.update(my_list)\nprint(my_set)\n\nprint(\"\\nAñade varios elementos en bloque en una dirección concreta\")\nprint(\"Añadimos en la posición 2 los valores 17,18,19,20\")\nmy_list = list(my_set)\nprint(f\" El conjunto convertido en lista es {my_list}\")\nmy_list[2:4] = [17, 18, 19, 20]\nprint(f\" La lista con los elementos insertados es {my_list}\")\nmy_set = set(my_list)\nprint(\"El conjunto resultante\")\nprint(my_set)\n\nprint(\"\\nElimina un elemento en una posición concreta, eliminamos el de la posición 2\")\nmy_list = list(my_set)\ndel my_list[2]\nmy_set = set(my_list)\nprint(my_set)\n\nprint(\n    \"\\nActualiza el valor de un elemento en una dirección concreta, actualiazamos el de la posición 4\"\n)\nmy_list = list(my_set)\nmy_list[4] = 35\nmy_set = set(my_list)\nprint(my_set)\n\nprint(\"\\nComprueba si un elemento está en un conjunto, comprobamos si existe el 35\")\nprint(35 in my_set)\n\nprint(\"\\nElimina todo el contenido del conjunto\")\nmy_set.clear()\nprint(my_set)\n\n\n# Extra\n\nmy_set = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}\nmy_set2 = {4, 6, 7, 8, 12, 14, 16}\n\nprint(\"Dificultad extra\")\nprint(\"Conjuntos para trabajar\")\nprint(f\" my_set = {my_set}\")\nprint(f\" my_set2 = {my_set2}\")\nprint(\"\\nUnión: \")\nunion = my_set | my_set2\nprint(union)\n\nprint(\"\\nIntersección: \")\ninterseccion = my_set & my_set2\nprint(interseccion)\n\nprint(\"\\nDiferencia: \")\ndiferencia = my_set - my_set2\nprint(diferencia)\n\nprint(\"\\nDiferencia simétrica: \")\nsimetric_difference = my_set ^ my_set2\nprint(simetric_difference)\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/mouredev.py",
    "content": "\"\"\"\nEjercicio\n\"\"\"\n\ndata = [1, 2, 3, 4, 5]\nprint(f\"Estructura inicial: {data}\")\n\ndata.append(6)\nprint(f\"Añadiendo elemento al final: {data}\")\n\ndata.insert(0, 0)\nprint(f\"Añadiendo elemento al principio: {data}\")\n\ndata.extend([7, 8, 9])\nprint(f\"Añadiendo elementos al final: {data}\")\n\ndata[3:3] = [-1, -2, -3]\nprint(f\"Añadiendo elementos en una posición: {data}\")\n\ndel data[3]\nprint(f\"Eliminando un elemento concreto: {data}\")\n\ndata[4] = -1\nprint(f\"Actualizando un elemento concreto: {data}\")\n\nprint(f\"Comprobar si un elemento existe: {-1 in data}\")\n\nprint(f\"Eliminar el contenido: {data.clear()}\")\n\n\"\"\"\nExtra\n\"\"\"\n\nset_1 = {1, 2, 3, 4, 5}\nset_2 = {1, 2, 3, 4, 6, 7}\n\nprint(f\"Unión: {set_1.union(set_2)}\")\n\nprint(f\"Intersección: {set_1.intersection(set_2)}\")\n\nprint(f\"Diferencia: {set_1.difference(set_2)}\")\nprint(f\"Diferencia: {set_2.difference(set_1)}\")\n\nprint(f\"Diferencia simétrica: {set_1.symmetric_difference(set_2)}\")\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/mrodara.py",
    "content": "###############################################  CONJUNTOS EN PYTHON  ###################################################################\n\n# Para la definición de un conjunto de datos usaremos {} o la función set()\n# Los conjuntos no pueden tener elementos repetidos y no es necesario que estén ordenados\n# Los conjuntos no pueden tener elementos que no sean inmutables (no pueden ser modificados)\n\nc1 = {1,2,3,7,5}\n\n# Agregar un elemento\nc1.add(6)\n\nprint(c1)\n\n# Eliminar un elemento\nc1.remove(7) # Da error si no existe el elemento dentro del conjunto\nprint(c1)\n\n# Podemos eliminar y no generar error si el elemento no existe con discard\nc1.discard(7)\n\n# Vaciar completamente el conjunto con clear\nc1.clear()\n\n# Operaciones matemáticas de conjutos (union |   intersección &   diferencia -   diferencia simétrica ^)\nc1 = {1,2,3,7,5}\nc2 = {1,2,3,7,8}\n\nprint(f\"Unión: {c1 | c2}\")\nprint(f\"Intersección: {c1 & c2}\" )\nprint(f\"Diferencia: {c1 - c2}\")\nprint(f\"Diferencia simétrica: {c1 ^ c2}\")\n\n\n# Ejercicio\n\nc2 = {3,5,2,1}\nprint(c2)\n\nc2.add(7) # Añade un elemento\nprint(c2)\n\n'''\nEn Python, los conjuntos (set) son colecciones desordenadas, por lo que no tienen un concepto de \"inicio\" o \"final\". \nLos elementos no se almacenan en un orden específico. Por esta razón, \nno podemos \"añadir un elemento al inicio\" como lo haríamos con una lista.\n\nPodemos convertir el conjunto en lista, añadir, eliminar etc en las posiciones que queramos y posteriormente convertila\na un conjunto\n'''\n\nc2_list = list(c2)\n\nprint(type(c2_list))\nprint(len(c2_list))\n\nc2_list.extend([i for i in range(11,21)]) # Añadimos varios elementos en bloque a la lista\nc2_list[5] = 1000 # Actualizamos el valor en una posición concreta\nc2 = set(c2_list) # Acabamos de añadir varios elementos en bloque a un conjunto\n\nprint(c2)\n\n# Si queremos eliminar uno o varios elementos concretos de un conjunto tendríamos que operar de la misma forma\nc2_list = list(c2)\n\nc2_list.pop() # Para eliminar un elemento\nc2_list.pop(0) # Para eliminar un elemento en una posición concreta\nc2_list.remove(12) # Para eliminar un elemento concreto\n\nc2 = set(c2_list)\nprint(c2)\n\n# Comprobaciones de pertenencia\nprint(1 in c2)\nprint(1000 in c2)\nprint(12 in c2)\n\n# Por último limpiar todo el conjunto\nc2.clear()\n\nprint(c2)\n\n\n\n###############################################  EJERCICIO EXTRA  ###################################################################\n# Mostrar operaciones con conjuntos:\nl1 = [i for i in range(1, 100)]\nl2 = [i for i in range(50, 150)]\nc1 = set(l1)\nc2 = set(l2)\n\nprint(c1)\nprint(c2)\n\nprint(f\"Union: {c1.union(c2)}\")\nprint(f\"Intersección: {c1.intersection(c2)}\")\nprint(f\"Diferencia: {c1.difference(c2)}\")\nprint(f\"Diferencia simétrica: {c1.symmetric_difference(c2)}\")\n\n\n###############################################  FIN EJERCICIO EXTRA  ###################################################################\n\n###############################################  FIN CONJUNTOS EN PYTHON  ###################################################################"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/mvidalb.py",
    "content": "\"\"\"\nEjercicio\n\"\"\"\n\ndata = [1, 2, 3, 4, 5]\nprint(f\"Estructura inicial: {data}\")\n\ndata.append(6)\nprint(f\"Añadiendo elemento al final: {data}\")\n\ndata.insert(0, 0)\nprint(f\"Añadiendo elemento al principio: {data}\")\n\ndata.extend([7, 8, 9])\nprint(f\"Añadiendo elementos al final: {data}\")\n\ndata[3:3] = [-1, -2, -3]\nprint(f\"Añadiendo elementos en una posición: {data}\")\n\ndel data[3]\nprint(f\"Eliminando un elemento concreto: {data}\")\n\ndata[4] = -1\nprint(f\"Actualizando un elemento concreto: {data}\")\n\nprint(f\"Comprobar si un elemento existe: {-1 in data}\")\n\nprint(f\"Eliminar el contenido: {data.clear()}\")\n\n\"\"\"\nExtra\n\"\"\"\n\nset_1 = {1, 2, 3, 4, 5}\nset_2 = {1, 2, 3, 4, 6, 7}\n\nprint(f\"Unión: {set_1.union(set_2)}\")\n\nprint(f\"Intersección: {set_1.intersection(set_2)}\")\n\nprint(f\"Diferencia: {set_1.difference(set_2)}\")\nprint(f\"Diferencia: {set_2.difference(set_1)}\")\n\nprint(f\"Diferencia simétrica: {set_1.symmetric_difference(set_2)}\")\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/nandaAlf.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n#  * operaciones (debes utilizar una estructura que las soporte):\n#  * - Añade un elemento al final.\n#  * - Añade un elemento al principio.\n#  * - Añade varios elementos en bloque al final.\n#  * - Añade varios elementos en bloque en una posición concreta.\n#  * - Elimina un elemento en una posición concreta.\n#  * - Actualiza el valor de un elemento en una posición concreta.\n#  * - Comprueba si un elemento está en un conjunto.\n#  * - Elimina todo el contenido del conjunto.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Muestra ejemplos de las siguientes operaciones con conjuntos:\n#  * - Unión.\n#  * - Intersección.\n#  * - Diferencia.\n#  * - Diferencia simétrica.\n#  */\n\nmyList=[1,2,3,4,5]\n\n# Añade un elemento al final.\nmyList.append(6)\n\n# Añade un elemento al principio.\nmyList.insert(0,0)\n\n# Añade varios elementos en bloque al final.\nmyList.extend(['a','b'])\n\n# Añade varios elementos en bloque en una posición concreta.\nmyList[2:3]=['c','d']\n\n# Elimina un elemento en una posición concreta.\ndel myList[3]\n\n# Actualiza el valor de un elemento en una posición concreta.\nmyList[2]='hello'\n\n# Comprueba si un elemento está en un conjunto.\nprint(10 in myList)\n\n# Elimina todo el contenido del conjunto.\nmyList.clear()\n\n#EXTRA\nset1={1,2,3,4,5}\nset2={1,3,5,7,9}\n\n#Union\nprint(set1|set2)\n\n#Interseccion\nprint(set1&set2)\n\n#Diferencia\nprint(set1-set2)\n\n#Diferencia simetrica\nprint(set1^set2)"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/neslarra.py",
    "content": "\"\"\"\n EJERCICIO:\n Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n operaciones (debes utilizar una estructura que las soporte):\n - Añade un elemento al final.\n - Añade un elemento al principio.\n - Añade varios elementos en bloque al final.\n - Añade varios elementos en bloque en una posición concreta.\n - Elimina un elemento en una posición concreta.\n - Actualiza el valor de un elemento en una posición concreta.\n - Comprueba si un elemento está en un conjunto.\n - Elimina todo el contenido del conjunto.\n\n DIFICULTAD EXTRA (opcional):\n Muestra ejemplos de las siguientes operaciones con conjuntos:\n - Unión.\n - Intersección.\n - Diferencia.\n - Diferencia simétrica.\n\"\"\"\n\nprint(f\"##  Explicación  {'#' * 30}\\n\")\n\nprint(f\"\"\"Un conjunto es una colección no ordenada de objetos únicos => no tiene índice, ni primero ni último.\nSe le pueden agregar elementos (método add), eliminar elementos (método remove) o eliminar TODOS los elementos (método clear).\nUn conjunto es iterable.\nUn conjunto vacío se puede crear con: \"vacio = set()\", PERO no con: \"vacio = {{}}\"  <= lo cual crea un diccionario vacío.\nTambién se pueden crear asignando elementos directamente al conjunto: \"numeros = {{1, 2, 3, 4, 5}}\"\nSi al conjunto le pasamos elementos \"repetidos\", se filtrarán las repeteciones: \"numeros = {{1, 2, 3, 1, 3}}\" => queda como: \"numeros = {{1, 2, 3}}\"\nTiene métodos para ejecutar operaciones de conjunto: intersection, union, issubset (incluído), issuperset (incluye), symmetric_difference (unión\nexcluyente), etc, las cuales se pueden explorar con la función \"dir(set())\"   \n\"\"\")\n\ncero = set()\nprimos = set()\nno_primos = set()\n\ncero.add(0)\n\nprimos.add(1)\nprimos.add(2)\nprimos.add(3)\nprimos.add(5)\nprimos.add(7)\n\nno_primos.add(4)\nno_primos.add(6)\nno_primos.add(8)\nno_primos.add(9)\n\ndigitos = cero.union(primos).union(no_primos)\n\nprint(f\"Conjuntos:\\n\\tCero: {cero}\\n\\tPrimos: {primos}\\n\\tNo primos {no_primos}\\n\\tDígitos: {digitos}\\n\")\nprint(f\"Elementos comunes por intersección: {cero.intersection(primos).intersection(no_primos).__len__()}\\n\")\n\ndigitos = digitos.union({2, 4, 5, 7, 11, 14, 15})\nprint(f\"Agrego más números a digitos {digitos}\\n\")\nprint(\"Subconjuntos:\")\nprint(f\"\\tPrimos está incluído en dígitos: {primos.issubset(digitos)}\\n\\tDígitos incluye no primos: {digitos.issuperset(no_primos)}\")\nprint(\"También podemos usar operadores:\")\nprint(f\"\\tPrimos está incluído en dígitos: {primos < digitos}\\n\\tDígitos incluye no primos: {no_primos < digitos}\\n\")\nprint(f\"Se puede crear un conjunto por comprehensión:\")\npares_mayores = set(x for x in digitos if (x > 9) and (x % 2 == 0))\nimpares_mayores = {x for x in digitos if (x > 9) and (x % 2 == 1)}\nprint(f\"\\tPares mayores: {pares_mayores}\\n\\tImpares mayores: {impares_mayores}\\n\")\nprint(\"Se puede itarar (recorro la union de los conjuntos pares e impoares mayores y los elimino de digitos):\")\nfor n in pares_mayores.union(impares_mayores):\n    digitos.remove(n)\nprint(f\"\\t{digitos}\")\nprint(\"\\nElimino TODOS los elementos de pares e impares mayores:\")\npares_mayores = pares_mayores.clear()\nimpares_mayores = impares_mayores.clear()\nprint(f\"\\tpares_mayore = {pares_mayores}\")\nprint(f\"\\timpares_mayores = {impares_mayores}\\n\")\nprint(\"Un conjunto puede ser inmutable: digitos = frozenset(digitos)\")\ndigitos = frozenset(digitos)\ntry:\n    digitos.add(10)\nexcept Exception as e:\n    print(f\"\\t{e.__str__()}\\n\")\nprint(f\"Teniendo digitos = {digitos}, primos = {primos} y no_primos = {no_primos}\")\nprint(f\"Intersección:\\n\\t{digitos.intersection(primos)}\")\nprint(f\"Unión:\\n\\t{digitos.union(no_primos)}\")\nprint(f\"Diferencia:\\n\\t{digitos.difference(primos)}\")\nprint(f\"Unión exclusiva:\\n\\t{digitos.symmetric_difference(no_primos)}\")\n\n\nprint(f\"\\n##  Dificultad extra  {'#' * 30}\\nIncluída en la explicación!!!\")\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/nlarrea.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n * operaciones (debes utilizar una estructura que las soporte):\n * - Añade un elemento al final.\n * - Añade un elemento al principio.\n * - Añade varios elementos en bloque al final.\n * - Añade varios elementos en bloque en una posición concreta.\n * - Elimina un elemento en una posición concreta.\n * - Actualiza el valor de un elemento en una posición concreta.\n * - Comprueba si un elemento está en un conjunto.\n * - Elimina todo el contenido del conjunto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Unión.\n * - Intersección.\n * - Diferencia.\n * - Diferencia simétrica.\n\"\"\"\n\ndata = [1, 2, 3, 4, 5]\nprint(data)  # [1, 2, 3, 4, 5]\n\n# Añadir un elemento al final\ndata.append(\"final\")\nprint(data)  # [1, 2, 3, 4, 5, 'final']\n\n# Añadir un elemento al principio\ndata.insert(0, \"start\")\nprint(data)  # ['start', 1, 2, 3, 4, 5, 'final']\n\n# Añadir varios elementos en bloque al final\ndata.append([\"final\", \"elements\", 3])\nprint(data)  # ['start', 1, 2, 3, 4, 5, 'final', ['final', 'elements', 3]]\n\n# Añadir varios elementos en bloque en una posición concreta\ndata.insert(2, [\"more\", \"data\", \"position\", 2])\nprint(data)\n# ['start', 1, ['more', 'data', 'position', 2], 2, 3, 4, 5, 'final', ['final', 'elements', 3]]\n\n# Elimina un elemento en una posición concreta\ndata.pop(3)\nprint(data)\n# ['start', 1, ['more', 'data', 'position', 2], 3, 4, 5, 'final', ['final', 'elements', 3]]\n\n# Actualiza el valor de un elemento en una posición concreta\ndata[1] = True\nprint(data)\n# ['start', True, ['more', 'data', 'position', 2], 3, 4, 5, 'final', ['final', 'elements', 3]]\n\n# Comprueba si un elemento está en un conjunto\nprint(\"dato\" in data)  # False\nprint(5 in data)  # True\n\n# Elimina todo el contenido del conjunto\ndata.clear()\nprint(data)  # []\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Unión.\n * - Intersección.\n * - Diferencia.\n * - Diferencia simétrica.\n\"\"\"\n\nset_1 = {1, 2, 3, 4}\nset_2 = {1, 2, 3, 4, 5, 6, 7}\n\nprint(\"Union:\", set_1.union(set_2))\n\nprint(\"Intersection:\", set_1.intersection(set_2))\n\nprint(\"Difference:\", set_1.difference(set_2))\nprint(\"Difference:\", set_2.difference(set_1))\n\nprint(\"Symmetric difference:\", set_1.symmetric_difference(set_2))\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/oriaj3.py",
    "content": "\"\"\"\n18 - Conjuntos\n\nAutor de la solución: Oriaj3\t\n\nTeoria: \n\nLos conjuntos son una estructura de datos que permite almacenar elementos de forma no ordenada.\nEn Python, los conjuntos se definen con llaves {} y los elementos se separan por comas.\nLos conjuntos no permiten elementos duplicados, por lo que si se añade un elemento que ya existe, no se añadirá.\nLos conjuntos son mutables, por lo que se pueden añadir o eliminar elementos.\nLos conjuntos no permiten acceder a los elementos por índice, ya que no tienen un orden definido.\nLos conjuntos son útiles para realizar operaciones de conjuntos, como unión, intersección, diferencia y diferencia simétrica.\n\nEjemplo:\nConjunto con mamíferos\nmamiferos = {\"perro\", \"gato\", \"elefante\", \"jirafa\"}\n\nOperaciones con conjuntos\n*add - Añade un elemento al conjunto\n*update - Añade varios elementos al conjunto\n*remove - Elimina un elemento del conjunto\n*discard - Elimina un elemento del conjunto si existe\n*clear - Elimina todos los elementos del conjunto\n*in - Comprueba si un elemento está en el conjunto\n*union - Realiza la unión de dos conjuntos\n*intersection - Realiza la intersección de dos conjuntos\n*difference - Realiza la diferencia de dos conjuntos\n*symmetric_difference - Realiza la diferencia simétrica de dos conjuntos\n\n\"\"\"\n\n\"\"\"\n * EJERCICIO:\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n * operaciones (debes utilizar una estructura que las soporte):\n * - Añade un elemento al final.\n * - Añade un elemento al principio.\n * - Añade varios elementos en bloque al final.\n * - Añade varios elementos en bloque en una posición concreta.\n * - Elimina un elemento en una posición concreta.\n * - Actualiza el valor de un elemento en una posición concreta.\n * - Comprueba si un elemento está en un conjunto.\n * - Elimina todo el contenido del conjunto.\n\"\"\"\n\n#Conjunto de mamíferos con lista\nmamiferos = [\"perro\", \"gato\", \"elefante\", \"jirafa\"]\nprint(mamiferos)\n\nmamiferos.append(\"vaca\") \nprint(mamiferos)\n\nmamiferos.insert(0, \"mono\")\nprint(mamiferos)\n\nmamiferos.extend([\"cabra\",\"oveja\"])\nprint(mamiferos)\n\nmamiferos[2:2]= [ \"caballo\", \"llama\"]\nprint(mamiferos)\n\ndel mamiferos[2] \nprint(mamiferos)\n\nmamiferos[3] = \"gorila\"\nprint(mamiferos)\n\nprint(f\"Está gorila? {'Sí' if 'gorila' in mamiferos else 'No'}\")\n\nmamiferos.clear()\nprint(mamiferos)\n\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Unión.\n * - Intersección.\n * - Diferencia.\n * - Diferencia simétrica.\n */\n\"\"\"\n\nconjunto1 = {1, 2, 3, 4, 5}\nconjunto2 = {1, 2, 3, 4, 6, 7}\n\nprint(f\"Unión: {conjunto1.union(conjunto2)}\")\nprint(f\"Intersección: {conjunto1.intersection(conjunto2)}\")\nprint(f\"Diferencia: {conjunto1.difference(conjunto2)}\")\nprint(f\"Diferencia: {conjunto2.difference(conjunto1)}\")\nprint(f\"Diferencia simétrica: {conjunto1.symmetric_difference(conjunto2)}\")\nprint(f\"Diferencia simétrica: {conjunto2.symmetric_difference(conjunto1)}\")\n\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/ouendinga.py",
    "content": "# 1. Crear una lista\nlista = ['elemento1', 'elemento2', 'elemento3']\nprint(f'1.: {lista}')\n\n# 2. Añadir un elemento al final de la lista\nlista.append('elemento4')\nprint(f'2.: {lista}')\n\n# 3. Añadir un elemento al principio de la lista\nlista.insert(0, 'elemento0')\nprint(f'3.: {lista}')\n\n# 4. Añadir varios elementos en bloque al final de la lista\nlista.extend(['elemento5', 'elemento6', 'elemento7'])\nprint(f'4.: {lista}')\n\n# 5. Añadir varios elementos en bloque en una posición concreta de la lista\nlista[2:2] = ['elemento1.5', 'elemento1.75']\nprint(f'5.: {lista}')\n\n# 6. Eliminar un elemento en una posición concreta de la lista\ndel lista[1]\nprint(f'6.: {lista}')\n\n# 7. Actualizar el valor de un elemento en una posición concreta de la lista\nlista[0] = 'elemento0.5'\nprint(f'7.: {lista}')\n\n# 8. Comprobar si un elemento está en la lista\nif 'elemento0.5' in lista:\n\tprint('elemento0.5 está en la lista')\nprint(f'8.: {lista}')\n\n# 9. Eliminar todo el contenido de la lista\nlista.clear()\nprint(f'9.: {lista}')\n\nprint('DIFICULTAD EXTRA')\n\n# 1. Crear dos conjuntos de datos\nconjunto1 = set(['a', 'b', 'c', 'd'])\nconjunto2 = set(['c', 'd', 'e', 'f'])\n\n# 2. Realizar la unión de los dos conjuntos\nunion = conjunto1.union(conjunto2)\nprint(f'Unión: {union}')\n\n# 3. Realizar la intersección de los dos conjuntos\ninterseccion = conjunto1.intersection(conjunto2)\nprint(f'Intersección: {interseccion}')\n\n# 4. Realizar la diferencia de los dos conjuntos\ndiferencia = conjunto1.difference(conjunto2)\nprint(f'Diferencia: {diferencia}')\n\n# 5. Realizar la diferencia simétrica de los dos conjuntos\ndiferencia_simetrica = conjunto1.symmetric_difference(conjunto2)\nprint(f'Diferencia simétrica: {diferencia_simetrica}')"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/pyramsd.py",
    "content": "conjunto = [1, 2, 3, 4]\nprint(f'Inicial: {conjunto}')\n\n# Añadir al final\nconjunto.append(5)\nprint(conjunto)\n\n# Añadir al principio\nconjunto.insert(0, 0)\nprint(conjunto)\n\n# Añadir varios en bloque al final.\nconjunto.extend([6, 7])\nprint(conjunto)\n\n# Añadir varios en bloque en una posición concreta\nconjunto[3:3] = [2.3, 2.5]\nprint(conjunto)\n\n# Eliminar de una posicion concreta\nconjunto.pop(3)\nprint(conjunto)\n\n# Actualizar un valor de una posición concreta\nconjunto[8] = 6.5\nprint(conjunto)\n\n# verificar si un elemento se encuntra\nprint(5 in conjunto)\n\n# Limpiar todo el conjunto\nconjunto.clear()\nprint(conjunto)\n\n\n'''\nEXTRA\n'''\nset1 = {1,2,3,4,5}\nset2 = {5,6,7,8,9}\n\n# UNION\nprint(set1.union(set2))\n\n# INTERSECCION\nprint(set1.intersection(set2))\n\n# DIFERENCIA\nprint(set1.difference(set2))\n\n# DIFERENCIA SIMETRICA\nprint(set1.symmetric_difference(set2))\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/qwik-zgheib.py",
    "content": "# -- exercise\n\ndata_list: list[int] = [2, 3, 4, 5]\nprint(f\"original data_list: {data_list}\")\nprint(f\"add element at the end: {data_list.append(6)}\")\nprint(f\"add element at the beginning: {data_list.insert(0, 1)}\")\nprint(f\"add multiple elements at the end: {data_list.extend([7, 8, 9])}\")\nprint(f\"add multiple elements at a specific position: {data_list.insert(2, 10)}\")\nprint(f\"remove an element at a specific position: {data_list.pop(3)}\")\nprint(f\"update the value of an element at a specific position: {data_list[3] == 11}\")\nprint(f\"check if an element is in a set: {11 in data_list}\")\nprint(f\"remove all content from the set\")\ndata_list.clear()\nprint(f\"final data_list: {data_list}\")\n\n# -- extra challenge\nset_a: set[int] = {1, 2, 3, 4, 5}\nset_b: set[int] = {4, 5, 6, 7, 8}\n\nprint(f\"set_a: {set_a}\")\nprint(f\"set_b: {set_b}\")\nprint(f\"union: {set_a | set_b}\")\nprint(f\"intersection: {set_a & set_b}\")\nprint(f\"difference: {set_a - set_b}\")\nprint(f\"symmetric difference: {set_a ^ set_b}\")\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/rantamhack.py",
    "content": "'''\n * EJERCICIO:\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n * operaciones (debes utilizar una estructura que las soporte):\n * - Inserta un elemento al final.\n * - Inserta un elemento al principio.\n * - Inserta varios elementos en bloque al final.\n * - Inserta varios elementos en bloque en una posicion concreta.\n * - Elimina un elemento en una posicion concreta.\n * - Actualiza el valor de un elemento en una posicion concreta.\n * - Comprueba si un elemento esta en un conjunto.\n * - Elimina todo el contenido del conjunto.\n'''\n\nprint(\"\\n\\n=======================================EJERCICIO=======================================\\n\\n\")\n\n\ngroup = ['Miguel', 'Ana', 'Juan', 'Rantamplan', 'Helena', 'Brais']\n\nprint(f\"Los elementos que conforman ahora mismo el conjunto son: {group}\")\n\nprint(\"\\n=====================\\n\")\n\ngroup.append('Raul')\nprint(f\"Inserto un elemento al final del conjunto: {group}\")\n\nprint(\"\\n=====================\\n\")\n\ngroup.insert(0, 'Luis')\nprint(f\"Inserto un elemento al principio del conjunto: {group}\")\n\nprint(\"\\n=====================\\n\")\n\ngroup.extend(['Jaime', 'Isabel', 'Rosa'])\nprint(f\"Inserto varios elementos en bloque al final del conjunto: {group}\")\n\nprint(\"\\n=====================\\n\")\n\ngroup[2:2] = ['Fernando', 'Cristina', 'Jon']    \nprint(f\"Inserto en bloque 3 elementos en la posicion 2 del conjunto: {group}\")\n\nprint(\"\\n=====================\\n\")\n\ndel group[4]\nprint(f\"Elimino el elemento elegido (4 - Jon) del conjunto: {group}\")\n\nprint(\"\\n=====================\\n\")\n\ngroup[6] = 'Rantamhack'\nprint(f\"Actualizo el elemento elegido (6 - Rantamplan) del conjunto: {group}\")\n\nprint(\"\\n=====================\\n\")\n\nprint(f\"Comprobar si esta es elemento 'Jon' en el conjunto 'group': {'Jon' in group}\")\n\nprint(f\"\\nComprobar si esta es elemento 'Juan' en el conjunto 'group': {'Juan' in group}\")\n\nprint(\"\\n=====================\\n\")\n\ngroup.clear()\nprint(f\"El contenido del conjunto 'group' {group} ha sido borrado\")\n\n\n'''\n * DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Union.\n * - Interseccion.\n * - Diferencia.\n * - Diferencia simetrica.\n'''\n\nprint(\"\\n\\n=======================================DIFICULTAD EXTRA=======================================\\n\\n\")\n\nalumnos_ciencias = {'Luis', 'Miguel', 'Fernando', 'Cristina', 'Ana', 'Juan'}\n\nalumnos_letras = {'Helena', 'Brais','Ana', 'Juan', 'Raul', 'Jaime', 'Luis', 'Isabel', 'Miguel', 'Rosa'}\n\ntotal_alumnos = alumnos_ciencias.union(alumnos_letras)\n\nprint(f\"El total de alumnos matriculados es: {sorted(total_alumnos)}\")\n\nprint(\"\\n=====================\\n\")\n\nalumnos_mixtos = alumnos_ciencias.intersection(alumnos_letras)\n\nprint(f\"El total de alumnos matriculados en las dos ramas: {sorted(alumnos_mixtos)}\")\n\nprint(\"\\n=====================\\n\")\n\nalumnos_solo_ciencias = alumnos_ciencias.difference(alumnos_letras)\n\nprint(f\"Alumnos matriculados solo en ciencias: {sorted(alumnos_solo_ciencias)}\")\n\nalumnos_solo_letras = alumnos_letras.difference(alumnos_ciencias)\n\nprint(f\"\\nAlumnos matriculados solo en letras: {sorted(alumnos_solo_letras)}\")\n\nprint(\"\\n=====================\\n\")\n\nalumnos_una_matricula = alumnos_ciencias.symmetric_difference(alumnos_letras)\n\nprint(f\"Alumnos matriculados solo en una rama sin importar cual: {sorted(alumnos_una_matricula)}\")\n\n\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/raulG91.py",
    "content": "\nmy_set = [1,4,3]\n\n#Add element at the end\nmy_set.append(8)\nprint(f'Adding element to the end {my_set}')\n\n#Add element at the begining\nmy_set.insert(0,24)\nprint(f'Adding element to the begining {my_set}')\n\n#Add multiple elments at the end\nmy_set.extend([10,23,32])\nprint(f'After adding multiple elements {my_set}')\n\n#Add multiple elements in a given postion\nmy_set[2:3] = [98,97,12]\nprint(f'Adding multiple elements at postion 3 {my_set}')\n\n#Delete element in a specfic postion\ndel(my_set[2])\nprint(f'Deleting element at postion 2 {my_set}')\n\n#Update element in a position\nmy_set[1] = 100\nprint(f'Updating element at postion 2 {my_set}')\n\n#Check if an element is in the set\n\nif 3 in my_set:\n    print(\"Element 3 is in the set\")\nelse:\n    print(\"Element 3 is not in the set\")    \n\n#Delete set\ndel(my_set)\n\n#Extra\n\nset1 = {1,2,4}\nset2 = {9,3,4}\n#Union\nunion = set1.union(set2)\nprint(f'Union {union}')\n\n#Intersection\nintersection = set1.intersection(set2)\nprint(f'Intersection {intersection}')\n\n#Diference\ndiference = set1.difference(set2)\nprint(f'Diference {diference}')\n\n#Symetric diference\n\nsymetric_diference = set1.symmetric_difference(set2)\nprint(f'Symetric diference {symetric_diference}')"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/raynerpv2022.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n#  * operaciones (debes utilizar una estructura que las soporte):\n\nclass MyConjunto:\n    def __init__(self, conjunto=[]) -> None:\n        self.conjunto = conjunto\n\n#  * - Añade un elemento al final.\n    def insert_at_end(self, items):\n        self.conjunto.append(items)\n         \n    #  * - Añade un elemento al principio.\n    def  insert_at_start(self, items):\n        self.conjunto.insert(0,items)\n         \n    #  * - Añade varios elementos en bloque al final.\n    def bloque_At_end(self, bloque):\n        self.conjunto.extend(bloque)\n         \n\n    #  * - Añade varios elementos en bloque en una posición concreta.\n    def insertBloque(self,pos, bloque):\n        self.conjunto[pos:pos] = bloque\n         \n\n    #  * - Elimina un elemento en una posición concreta.\n    def delete_at_index(self, index):\n        \n         print(f\"se elimino el items {self.conjunto.pop(index)}\")\n\n    #  * - Actualiza el valor de un elemento en una posición concreta.\n    def update_at_index(self, index, new_value):\n            self.conjunto[index] = new_value\n\n    #  * - Comprueba si un elemento está en un conjunto.\n    def chek_value(self, items):\n         print(f\"Elemento {items} esta en {self.conjunto}? : {items in self.conjunto}\")\n        \n              \n     \n    #  * - Elimina todo el contenido del conjunto.\n    def remove_data(self):\n         self.conjunto.clear()\n\n    def print_data(self):\n         print(self.conjunto)\n\n\nconjunto = MyConjunto()\nconjunto.print_data()\nconjunto.insert_at_end(4)\nconjunto.print_data()\nconjunto.bloque_At_end([1,2,3,4,5,6])\nconjunto.print_data()\nconjunto.insert_at_start(0)\nconjunto.print_data()\nconjunto.insertBloque(3,[99,98,97])\nconjunto.print_data()\nconjunto.update_at_index(0,100)\nconjunto.print_data()\nconjunto.delete_at_index(4)\nconjunto.print_data()\nconjunto.chek_value(100)\nconjunto.print_data()\nconjunto.chek_value(123)\nconjunto.print_data()\nconjunto.print_data()\nconjunto.remove_data()\nconjunto.print_data()\n                \n\n\n    #  *\n\n\n\n\n\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Muestra ejemplos de las siguientes operaciones con conjuntos:\n#  * - Unión.\n#  * - Intersección.\n#  * - Diferencia.\n#  * - Diferencia simétrica.\n#  */\n\nset1 = {2,4,6,8,10}\nset2 = {1,2,3,4,5,7,9}\n\n \nprint(f\"UNION {set1.union(set2)}\")\nprint(f\"INTERSECCION {set1.intersection(set2)}\")\nprint(f\"Diferencia {set1.difference(set2)}\")\nprint(f\"Diferencia {set2.difference(set1)}\")\nprint(f\"Diferencia Simetrica {set1.symmetric_difference(set2)}\")\n\n# usando lista\ns1 = [2,4,6,8,10]\ns2 = [1,2,3,4,5,7,9]\n\n# Union\n\nprint(\"UNION\", set(s1+s2))\n\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/restevean.py",
    "content": "\"\"\"\nExercise\n\"\"\"\nlist_data = [10, 20, 30, 40, 50]\nprint(f\"Initial list: {list_data}\")\n\nlist_data.append(60)\nprint(f\"Adden an element at the end: {list_data}\")\n\nlist_data.insert(0, 5)\nprint(f\"Element added at the begin: {list_data}\")\n\nlist_data.extend([70, 80, 90])\nprint(f\"Several elements added at the end: {list_data}\")\n\nlist_data[3:3] = [25, 35]\nprint(f\"Several elements added at a specific position: {list_data}\")\n\nlist_data.pop(2)\nprint(f\"Element removed at position 2: {list_data}\")\n\nlist_data[5] = 45\nprint(f\"Value of an element updated at position 5: {list_data}\")\n\nelement_present = 50 in list_data\nprint(f\"Element present: {element_present}\")\n\nlist_data.clear()\nprint(f\"List cleared: {list_data}\")\n\n\n\"\"\"\nExtra\n\"\"\"\na = {1, 2, 3}\nb = {3, 4, 5}\nprint(f\"Conjuntos a y b: {a}, {b}\")\n\nunion_result = a | b\nintersection_result = a & b\ndifference_result = a - b\nsymmetric_difference_result = a ^ b\n\nprint({\n    \"union\": union_result,\n    \"intersection\": intersection_result,\n    \"difference\": difference_result,\n    \"symmetric_difference\": symmetric_difference_result\n})\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/rigo93acosta.py",
    "content": "'''\n * EJERCICIO:\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n * operaciones (debes utilizar una estructura que las soporte):\n * - Añade un elemento al final.\n * - Añade un elemento al principio.\n * - Añade varios elementos en bloque al final.\n * - Añade varios elementos en bloque en una posición concreta.\n * - Elimina un elemento en una posición concreta.\n * - Actualiza el valor de un elemento en una posición concreta.\n * - Comprueba si un elemento está en un conjunto.\n * - Elimina todo el contenido del conjunto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Unión.\n * - Intersección.\n * - Diferencia.\n * - Diferencia simétrica.\n'''\n\n'''\nEjercicio:\n'''\n\n# Crear un conjunto de datos\ndata = [1, 2, 3, 4, 5]\nprint(f\"Estructura incial: {data}\")\n\n# Añadir un elemento al final\ndata.append(6)\nprint(f\"Añadiendo elemento al final: {data}\")\n\n# Añadir un elemento al principio\ndata.insert(0, 0)\nprint(f\"Añadiendo elemento al principio: {data}\")\n\n# Añadir varios elementos en bloque al final\ndata.extend([7, 8, 9])\nprint(f\"Añadiendo elementos en bloque: {data}\")\n\n# Añadir varios elementos en bloque en una posición concreta\ndata[3:3] = [10, 11, 12] # Slice: Inserta en la posicion 3\nprint(f\"Añadiendo elementos en posición concreta: {data}\")\n\n# Eliminar un elemento en una posición concreta\ndel data[3]\n# data.pop(3) # Otro método\nprint(f\"Eliminando elementos en posición concreta: {data}\")\n\n# Actualizar el valor de un elemento en una posición concreta\ndata[3] = 13\nprint(f\"Actualizando elementos en posición concreta: {data}\")\n\n# Comprobar si un elemento está en un conjunto\nprint(f\"El elemento 13 está en el conjunto: {13 in data}\")\n\n# Eliminar todo el contenido del conjunto\ndata.clear()\nprint(f\"Eliminando todo el contenido del conjunto: {data}\")\n\n'''\nDificultad extra:\n'''\n\nset_1 = {1, 2, 3, 4, 5}\nset_2 = {1, 2, 3, 4, 6, 7}\n\n# Unión\nprint(f\"Unión de conjuntos: {set_1.union(set_2)}\")\n\n# Intersección\nprint(f\"Intersección de conjuntos: {set_1.intersection(set_2)}\")\n\n# Diferencia\nprint(f\"Diferencia de conjuntos: {set_1.difference(set_2)}\")\nprint(f\"Diferencia de conjuntos: {set_2.difference(set_1)}\")\n\n# Diferencia simétrica\nprint(f\"Diferencia simétrica de conjuntos: {set_1.symmetric_difference(set_2)}\")"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/santyjL.py",
    "content": "#18 CONJUNTOS\n\n\"\"\"\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n * operaciones (debes utilizar una estructura que las soporte):\n * - Añade un elemento al final.\n * - Añade un elemento al principio.\n * - Añade varios elementos en bloque al final.\n * - Añade varios elementos en bloque en una posición concreta.\n * - Elimina un elemento en una posición concreta.\n * - Actualiza el valor de un elemento en una posición concreta.\n * - Comprueba si un elemento está en un conjunto.\n * - Elimina todo el contenido del conjunto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Unión.\n * - Intersección.\n * - Diferencia.\n * - Diferencia simétrica.\n */\n\"\"\"\n\ndatos: list = [1, 2, 3, 4]\nprint(\"Lista inicial:\", datos)\n\n# Añadir datos\ndatos.append(5)\nprint(\"Después de añadir 5:\", datos)\n\n# Añadir dato al inicio\ndatos.insert(0, 0)\nprint(\"Después de insertar 0 al inicio:\", datos)\n\n# Añadir varios datos al final\ndatos.extend([6, 7, 8])\nprint(\"Después de extender con 6, 7 y 8:\", datos)\n\n# Añadir dato en posición específica\ndatos[4:4] = [5, 8, 13]\nprint(\"Después de insertar 5, 8 y 13 en la posición 4:\", datos)\n\n# Eliminar un dato concreto\ndel datos[4]\nprint(\"Después de eliminar el dato en la posición 4 con 'del':\", datos)\n\ndatos.pop(4)\nprint(\"Después de eliminar el dato en la posición 4 con 'pop':\", datos)\n\n# Actualizar elemento\ndatos[4] = 10\nprint(\"Después de actualizar el elemento en la posición 4 a 10:\", datos)\n\n# Comprobar si un elemento está en el conjunto\ncomprobando = 8 in datos\nprint(\"Comprobando si 8 está en la lista:\", comprobando)\n\n# Eliminar elementos de la lista\ndatos.clear()\nprint(\"Después de limpiar la lista:\", datos)\n\n# EXTRA\n\nconjunto1: set = {1, 1, 2, 3, 5, 8}\nconjunto2: set = {8,13, 21, 34, 55, 89, 144}\n\nprint(\"Conjunto 1:\", conjunto1)\nprint(\"Conjunto 2:\", conjunto2)\n\n# Unión de conjuntos\nunion = conjunto1.union(conjunto2)\nprint(\"Unión de conjunto1 y conjunto2:\", union)\n\n# Intersección de conjuntos\ninterseccion = conjunto1.intersection(conjunto2)\nprint(\"Intersección de conjunto1 y conjunto2:\", interseccion)\n\n# Diferencia de conjuntos\ndiferencia = conjunto1.difference(conjunto2)\nprint(\"Diferencia de conjunto1 y conjunto2:\", diferencia)\n\n# Diferencia simétrica de conjuntos\ndiferencia_simetrica = conjunto1.symmetric_difference(conjunto2)\nprint(\"Diferencia simétrica de conjunto1 y conjunto2:\", diferencia_simetrica)\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/sorubadguy.py",
    "content": "# Conjuntos\n\nanimales = [\"conejo\", \"perro\", \"gato\"]\nprint(animales)\nanimales.append(\"serpiente\")\nprint(animales)\nanimales.insert(0,\"gallina\")\nprint(animales)\nanimales.extend([\"hamster\", \"panda\", \"iguana\"])\nprint(animales)\nanimales[5:3] = [\"cocodrilo\", \"avestrus\", \"mono\"]\nprint(animales)\nanimales.pop(3)\nprint(animales)\nanimales[5] = \"tigre\"\nprint(animales)\n\nanimal = \"cocodrilo\"\nif animal in animales:\n    print(f\"{animal} se encuentra en animales\")\nelse:\n    print(f\"{animal} no se encuentra en animales\")\n    \nanimales.clear()\nprint(animales)\n\n#!Extra\n\nmult2 = {2,4,6,8,10,12,14,16,18,20,22,24,26,28,30}\nmult3 = {3,6,9,12,15,18,21,24,27,30}\n\nprint(f\"union: {mult2.union(mult3)}\")\nprint(f\"union: {mult2 | mult3}\")\nprint(f\"interseccion: {mult2.intersection(mult3)}\")\nprint(f\"interseccion: {mult2 & mult3}\")\nprint(f\"diferencia: {mult2.difference(mult3)}\")\nprint(f\"diferencia: {mult2 - mult3}\")\nprint(f\"diferencia simetrica: {mult2.symmetric_difference(mult3)}\")\nprint(f\"diferencia simetrica: {mult2 ^ mult3}\")"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/victorfer69.py",
    "content": "#EJERCICIO\n\ndata = [1, 2, 3, 4, 5]\nprint(data)\n\n#Añade un elemento al principio.\ndata.append(6)\nprint(data)\n\n#Añade un elemento en la posicion que quieras\ndata.insert(0, 0)\nprint(data)\n\n#Añade varios elementos en bloque al final.\nblock = [7, 8, 9]\ndata.extend(block)\nprint(data)\n\n#Añade varios elementos en bloque en una posición concreta.\ndata[3:3] = [-1, -2, -3]\nprint(data)\n\n# Elimina un elemento en una posición concreta.\ndata.pop(5)\nprint(data)\n\n# Actualiza el valor de un elemento en una posición concreta.\ndata[4] = 10\nprint(data)\n\n# Comprueba si un elemento está en un conjunto.\nprint(data.__contains__(3))\nprint(data.__contains__(1234))\n\n# Elimina todo el contenido del conjunto.\ndata.clear()\nprint(data)\n\n\n#EJERCICIO EXTRA\n\n#Union\ndef union(a, b):\n    c = []\n    a.extend(b)\n    for i in a:\n        if not c.__contains__(i):\n            c.append(i)\n    return c\n\na = [1, 2, 3, 4, 5]\nb = [1, 3, 5, 7, 9]\nprint(union(a,b))\n\n#Interseccion\ndef interseccion(a, b):\n    c = []\n    for i in a:\n        if b.__contains__(i):\n            c.append(i)\n    return c\n\na = [1, 2, 3, 4, 5]\nb = [1, 3, 5, 7, 9]\nprint(interseccion(a, b))\n\n#Diferencia \ndef diferencia(a, b):\n    c = a\n    for i in b:\n        if a.__contains__(i):\n            c.remove(i)\n    return c\n\na = [1, 2, 3, 4, 5]\nb = [1, 3, 5, 7, 9]\nprint(diferencia(a, b))\n\n#Hay operaciones que lo hacen solas\na = {1, 2, 3, 4, 5}\nb = {1, 3, 5, 7, 9}\nprint(f\"Unión: {a.union(b)}\")\nprint(f\"Intersección: {a.intersection(b)}\")\nprint(f\"Diferencia: {a.difference(b)}\")"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/worlion.py",
    "content": "\"\"\"\n * EJERCICIO: Conjuntos\n\"\"\"\n\nmy_list = [\"b\", \"c\"]\nprint(f\"Mi lista: {my_list}\")\n\n# Añade un elemento al final.\nmy_list.append(\"g\")\nprint(f\" - Añade un elemento al final: {my_list} ✅\")\n\n# Añade un elemento al principio.\nmy_list = [\"a\"] + my_list\nprint(f\" - Añade un elemento al principio: {my_list} ✅\")\n\n# Añade varios elementos en bloque al final.\nmy_list.extend([\"h\", \"i\"])\nprint(f\" - Añade varios elementos en bloque al final: {my_list} ✅\")\n\n# Añade varios elementos en bloque en una posición concreta.\nindex = 3\nmy_list[index:index] = [\"D\", \"e\", \"f\", \"g\"]\nprint(f\" - Añade varios elementos en bloque en una posición concreta: {my_list} ✅\")\n\n# Elimina un elemento en una posición concreta.\ndel my_list[6]\nprint(f\" - Elimina un elemento en una posición concreta: {my_list} ✅\")\n\n# Actualiza el valor de un elemento en una posición concreta.\nmy_list[3] = \"d\"\nprint(f\" - Actualiza el valor de un elemento en una posición concreta: {my_list} ✅\")\n\n# Comprueba si un elemento está en un conjunto.\n\nprint(f\" - Comprueba si un elemento ('g') está en un conjunto: {'g' in my_list} ✅\")\nprint(f\" - Comprueba si un elemento ('z') está en un conjunto: {'z' in my_list} ✅\")\n\n# Elimina todo el contenido del conjunto.\nmy_list.clear()\nprint(f\" - Elimina todo el contenido del conjunto.: {my_list}\")\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n\n\"\"\"\n\nprint(\"\\n ---- 🌩 DIFICULTAD EXTRA 🌩 ----\\n\")\n\nset_1 = {'a', 'b', 'c'}\nprint(f\"Set A: {set_1}\")\nset_2 = {'c', 'e', 'f'}\nprint(f\"Set C: {set_2}\")\n\n# Unión: ...otro conjunto, cuyos elementos son los mismos de los conjuntos iniciales.\nprint(f\"Unión (Están en A o en B): { set_1.union(set_2)}\")\n\n# Intersección: ... otro conjunto que contiene los elementos comunes a los conjuntos partida\nprint(f\"Intersección (Están en A y en B): { set_1.intersection(set_2)}\")\n\n# Diferencia: ...otro conjunto con los elementos del primer conjunto sin los elementos del segundo conjunto\nprint(f\"Diferencia (Están en A pero no en B): { set_1.difference(set_2)}\")\n\n# Diferencia simétrica: otro conjunto que contiene a aquellos elementos que pertenecen a cada uno de los conjuntos iniciales, pero no a ambos a la vez\nprint(f\"Diferencia simétrica (Están en A pero no en B o viceversa): { set_1.symmetric_difference(set_2)}\")"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/ycanas.py",
    "content": "# ------ I. Ejercicio\n\nmy_set = [i for i in range(10)]\nprint(my_set)\n\nmy_set.append(10)\nprint(my_set)\n\nmy_set.insert(0, 11)\nprint(my_set)\n\nmy_set.extend([12, 13, 14])\nprint(my_set)\n\nmy_set[4:4] = [15, 16, 17]\nprint(my_set)\n\nmy_set.pop(2)\nprint(my_set)\n\nmy_set[0] = -1\nprint(my_set)\n\nprint(17 in my_set)\n\nmy_set.clear()\nprint(my_set)\n\n# ------ II. Extra\n\nmy_set_1 = {2, 3, 6, 7}\nmy_set_2 = {3, 5, 7, 9}\n\nprint(my_set_1.union(my_set_2))\nprint(my_set_1.intersection(my_set_2))\nprint(my_set_1.difference(my_set_2))\nprint(my_set_1.symmetric_difference(my_set_2))\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/yenneralayon142.py",
    "content": "\"\"\"\nconjuntos\n\"\"\"\nmy_set = {2,3,4,5,6}\nmy_set.add(7) # Añadir elemento al final\nprint(f\"A1{my_set}\")\nnew_element = 1\nmy_new_set = {new_element, *my_set} # Añadir elemento al inicio\nprint(f\"A2{my_new_set}\")\nnew_elements = {8,9,10}\nmy_new_set.update(new_elements)\nprint(f\"A3{my_new_set}\") #Añadir varios elementos en bloque al final\n\n\"\"\"\nEn Python, los sets no tienen un orden específico de elementos, por lo que técnicamente no puedes\nagregar elementos en una posición concreta como podrías hacer con una lista o una tupla\n\"\"\"\n\n\"\"\"\nNo puedo acceder a una posición, pero puedo eliminar el elemento único\n\"\"\"\nmy_new_set.remove(6)\nprint(f\"A5{my_new_set}\") # Eliminar elemento unico\n\n\"\"\"\nEn un set no se puede actualizar un elemento ya que trabaja con elementos unicos\n\"\"\"\nprint(f\"A6\",10 in my_new_set) # Comprobar si el elemento está en el conjunto\n\nmy_new_set.clear()\nprint(f\"A7 Contenido eliminado  {my_new_set}\") #Eliminar todo el contenido del conjunto\n\n\n\"\"\"\nEjercicio\n\"\"\"\n\nmy_set1 = {1,2,3,4}\nmy_set2 = {4,5,6}\n\nunion_set = my_set1.union(my_set2)\nprint(f\"Esta es la unión de los dos conjuntos {union_set}\") #Unión\n\nintersection_set = my_set1.intersection(my_set2)\nprint(f\"Esta es la intersección de los dos conjuntos {intersection_set}\") #Intersección\n\ndifference_set = my_set1.difference(my_set2)\nprint(f\"Esta es la diferencia de los dos conjuntos {difference_set}\") #Diferencia\n \nsimetry_difference = my_set1.symmetric_difference(my_set2)\nprint(f\"Esta es la diferencia simetrica de los dos conjuntos {simetry_difference}\") #Diferencia simetrica\n\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/python/zetared92.py",
    "content": "# RETO 18 CONJUNTOS\n\n\"\"\"\nCREAR CONJUNTO DE DATOS Y REALIZAR OPERACIONES\n\"\"\"\n\ndata = [1, 2, 3, 4]\nprint(f\"Initial structure: {data}\")\n\n# AÑADE UN ELEMENTO AL FINAL\ndata.append(5)\nprint(f\"Adding element to the end: {data}\")\n\n# AÑADE UN ELEMENTO AL PRINCIPIO\ndata.insert(0, 0)\nprint(f\"Adding element to the start: {data}\")\n\n# AÑADE VARIOS ELEMENTOS EN BLOQUE AL FINAL\ndata.extend([6, 7, 8])\nprint(f\"Adding block elements to the end: {data}\")\n\n# AÑADE VARIOS ELEMENTOS EN BLOQUE EN UNA POSICIÓN ESPECÍFICA\ndata[3:3] = [-1, -2, -3]\nprint(f\"Adding elements in bulk at a specific position: {data}\")\n\n# ELIMINA UN ELEMENTO EN UN POSICIÓN CONCRETA\ndel data [3]\nprint(f\"Deleting an element at a specific position: {data}\")\n\n# ACTUALIZA EL VALOR DE UN ELEMENTO EN UNA POSICIÓN CONCRETA\ndata[2] = +1\nprint(f\"Updating a specific element: {data}\")\nprint(f\"Check if an element exists: {+1 in data}\")\nprint(f\"Delete content: {data.clear()}\")\n\n\n# Extra\n\nprint(\"🧩 DIFICULTAD EXTRA - EJEMPLOS DE OPERACIONES CON CONJUNTOS 🧩\")\n\nfirst_set = {1, 2, 3, 4, 5, 6}\nsecond_set = {1, 2, 3, 4, 5, 6, 7, 8}\n\n# UNIÓN\nprint(f\"Union: {first_set.union(second_set)}\")\n\n# INTERSECCIÓN\nprint(f\"Intersection: {first_set.intersection(second_set)}\")\n\n# DIFERENCIA\nprint(f\"Difference: {first_set.difference(second_set)}\")\nprint(f\"Difference: {second_set.difference(first_set)}\")\n\n# DIFERENCIA SIMÉTRICA\nprint(f\"Symmetrical difference: {first_set.symmetric_difference(second_set)}\")\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/ruby/Elmer125.rb",
    "content": "#  * EJERCICIO:\n#  * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n#  * operaciones (debes utilizar una estructura que las soporte):\n#  * - Añade un elemento al final.\n#  * - Añade un elemento al principio.\n#  * - Añade varios elementos en bloque al final.\n#  * - Añade varios elementos en bloque en una posición concreta.\n#  * - Elimina un elemento en una posición concreta.\n#  * - Actualiza el valor de un elemento en una posición concreta.\n#  * - Comprueba si un elemento está en un conjunto.\n#  * - Elimina todo el contenido del conjunto.\ndata = [1, 2, 3, 4, 5]\nputs \"Initial data: #{data}\"\n\ndata.push(6)\nputs \"Add an element at the end: #{data}\"\n\ndata.unshift(0)\nputs \"Add an element at the beginning: #{data}\"\n\ndata.concat([7, 8, 9])\nputs \"Add multiple elements at the end: #{data}\"\n\ndata.insert(5, 10, 11, 12)\nputs \"Add multiple elements at a specific position: #{data}\"\n\ndata.delete_at(5)\nputs \"Delete an element at a specific position: #{data}\"\n\ndata[5] = 13\nputs \"Update the value of an element at a specific position: #{data}\"\n\nputs \"Check if an element is in the set: #{data.include?(13)}\"\n\ndata.clear\nputs \"Delete all the content of the set: #{data}\"\n\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Muestra ejemplos de las siguientes operaciones con conjuntos:\n#  * - Unión.\n#  * - Intersección.\n#  * - Diferencia.\n#  * - Diferencia simétrica.\nset_a = [1, 2, 3, 4, 5]\nset_b = [4, 5, 6, 7, 8]\n\nputs \"Union: #{set_a | set_b}\"\n\nputs \"Intersection: #{set_a & set_b}\"\n\nputs \"Difference: #{set_a - set_b}\"\n\nputs \"Symmetric difference: #{set_a - set_b | set_b - set_a}\""
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/rust/kenysdev.rs",
    "content": "/*\n╔═══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado                ║\n║ GitHub: https://github.com/Kenysdev   ║\n║ 2024 -  Rust                          ║\n╚═══════════════════════════════════════╝\n-----------------------------------------\n* CONJUNTOS\n-----------------------------------------\n*/\n\nuse std::collections::HashSet;\nfn main() {\n    // Conjuntos\n    // Son una colección desordenada de elementos únicos.\n    let mut my_set: HashSet<i32> = vec![1, 2, 3, 0].into_iter().collect();\n\n    // EJERCICIO #1:\n    // Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n    // operaciones (debes utilizar una estructura que las soporte):\n\n    // NOTA: - Algunas operaciones del ejercicio no pueden realizarse utilizando 'HashSet'.\n\n    let mut my_list: Vec<String> = vec![\n        \"a\".to_string(), \n        \"b\".to_string(), \n        \"c\".to_string()\n    ];\n\n    // Añade un elemento al final.\n    my_list.push(\"d\".to_string());\n\n    // Añadir un elemento al principio\n    my_list.insert(0, \"-\".to_string());\n\n    // Añadir varios elementos en bloque al final\n    my_list.extend(vec![\"e\".to_string(), \"f\".to_string()]);\n\n    // Añadir varios elementos en bloque en una posición concreta\n    my_list.splice(4..4, vec![\"-\".to_string(), \">\".to_string()]);\n\n    // Eliminar un elemento en una posición concreta\n    my_list.remove(5);\n\n    // Actualizar el valor de un elemento en una posición concreta\n    my_list[2] = \"-b\".to_string();\n\n    // Mostrar la lista\n    println!(\"Elementos de la lista:\");\n    println!(\"{:?}\", my_list);\n\n    // Comprueba si un elemento está en un conjunto\n    println!(\"4 en conjunto: {}\", my_set.contains(&4));\n\n    println!(\"'c' en lista: {}\", my_list.contains(&\"c\".to_string()));\n\n    // Elimina todo el contenido del conjunto y la lista.\n    my_set.clear();\n    my_list.clear();\n\n    // EJERCICIO #2:\n    // Muestra ejemplos de las siguientes operaciones con conjuntos:\n    // - Unión.\n    // - Intersección.\n    // - Diferencia.\n    // - Diferencia simétrica.\n\n    let set1: HashSet<i32> = vec![1, 2, 3, 4].into_iter().collect();\n    let set2: HashSet<i32> = vec![3, 4, 5, 6].into_iter().collect();\n\n    println!(\n        \"\\n* set_1: {:?} - set_2: {:?}\",\n        set1, set2\n    );\n\n    // Unión\n    // Elementos que están en al menos uno de los conjuntos.\n    let union: HashSet<i32> = set1.union(&set2).cloned().collect();\n    println!(\"\\n- Union: {:?}\", union);\n\n    // Intersección\n    // Elementos que están en ambos conjuntos.\n    let intersection: HashSet<i32> = set1.intersection(&set2).cloned().collect();\n    println!(\"\\n- Intersection: {:?}\", intersection);\n\n    // Diferencia\n    // Elementos que están en set_1 pero no en set_2\n    let difference: HashSet<i32> = set1.difference(&set2).cloned().collect();\n    println!(\"\\n- Difference: {:?}\", difference);\n\n    // Diferencia simétrica\n    // Elementos que están en uno de los conjuntos pero no en ambos.\n    let symmetric_diff: HashSet<i32> = set1.symmetric_difference(&set2).cloned().collect();\n    println!(\"\\n- Symmetric Difference: {:?}\", symmetric_diff);\n}\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/sql/Nicojsuarez2.sql",
    "content": "# #18 CONJUNTOS\n> #### Dificultad: Fácil | Publicación: 29/04/24 | Corrección: 06/05/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n * operaciones (debes utilizar una estructura que las soporte):\n * - Añade un elemento al final.\n * - Añade un elemento al principio.\n * - Añade varios elementos en bloque al final.\n * - Añade varios elementos en bloque en una posición concreta.\n * - Elimina un elemento en una posición concreta.\n * - Actualiza el valor de un elemento en una posición concreta.\n * - Comprueba si un elemento está en un conjunto.\n * - Elimina todo el contenido del conjunto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Unión.\n * - Intersección.\n * - Diferencia.\n * - Diferencia simétrica.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/swift/allbertoMD.swift",
    "content": "import Foundation\n\n\nvar myArray = [1, 2, 3, 4, 5]\nprint(myArray)\n\n\n\n// Insertar.\nprint(\"\\nInserción.\")\n\nmyArray.append(6)\nprint(myArray)\n\nmyArray.append(contentsOf: [7, 8, 9])\nprint(myArray)\n\nmyArray.insert(0, at: 0)\nprint(myArray)\n\nmyArray.insert(contentsOf: [-2, -1], at: 0)\nprint(myArray)\n\n\n\n// Eliminar.\nprint(\"\\nEliminación\")\n\nmyArray.remove(at: 4)\nprint(myArray)\n\n\n\n// Actualizar.\nprint(\"\\nActualizar.\")\n\nmyArray[7] = 400\nprint(myArray)\n\n\n\n// Contiene.\nprint(\"\\nContenido.\")\n\nprint(myArray.contains(400))\n\n\n\n// Eliminar todos.\nprint(\"\\nElinar todas todo.\")\n\nmyArray.removeAll()\nprint(myArray)\n\n\n\n\n// DIFICULTAD EXTRA\nprint(\"\\nDIFICULTAD EXTRA.\")\n\n\n\n\n// Union.\nprint(\"\\nUnión.\")\n\n\nvar mySet: Set<Int> = [100, 44, 29, 71, -14, 999, 1, -4194]\nvar newSet: Set<Int> = [440, 71, 32, -18, 44, 4194, 12, 87]\n\n\nlet union = mySet.union(newSet)\nprint(union)\n\nmySet.formUnion(newSet)\nprint(mySet)\n\n\n\n// Intersección.\nprint(\"\\nIntersección.\")\n\n\nmySet = [100, 44, 29, 71, -14, 999, 1, -4194]\nnewSet = [440, 71, 32, -18, 44, 4194, 12, 87]\n\n\nlet intersection = mySet.intersection(newSet)\nprint(intersection)\n\nmySet.formIntersection(newSet)\nprint(mySet)\n\n\n\n// Diferencia.\nprint(\"\\nDiferencia.\")\n\n\nmySet = [100, 44, 29, 71, -14, 999, 1, -4194]\nnewSet = [440, 71, 32, -18, 44, 4194, 12, 87]\n\n\nlet subtracting = mySet.subtracting(newSet)\nprint(subtracting)\n\n\n\n// Diferencia simetrica.\nprint(\"\\nDiferencia Simetrica.\")\n\n\nmySet = [100, 44, 29, 71, -14, 999, 1, -4194]\nnewSet = [440, 71, 32, -18, 44, 4194, 12, 87]\n\n\nlet symmetricDiferene = mySet.symmetricDifference(newSet)\nprint(symmetricDiferene)\n\nmySet.formSymmetricDifference(newSet)\nprint(mySet)\n\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/swift/blackriper.swift",
    "content": "import Foundation\n\n/*\n  un conjunto es la collecion de elementos  agrupados en algun objeto esta collecion no \n  necesariamente tiene un orden y a estas se les pueden aplicar varias operaciones \n\n  Uniòn : es cuando los elementos de un conjunto se combinan con otro  para dar como resultado \n  un nuevo conjunto de elementos conformados por los elementos de los dos conjuntos originales.\n\n  Intersección :  operacion que como resultado da un conjuto cuyos elementos son los elementos\n  comunes entre los dos conjuntos originales.\n\n  Diferencia : es la operacion que da como resultado un conjunto de elementos que son los elementos\n  que no son comunes entre los dos conjuntos originales\n\n  Diferencia simétrica : es la operacion que da como resultado un conjunto cuyos elementos pertenecen a ambos \n  conjuntos originales pero no a ambos ala vez.\n\n */\n\n func OperationsWithCollections(){\n    var numbers = [1,2,3,4,5,6,7,8,9,10]\n    \n    // agregar elementos a la lista \n    numbers.append(11)\n    print(numbers)\n    \n    //agregar elementos al principio de la lista\n    numbers.insert(0, at: 0)\n    print(numbers)\n    \n   // agregar varios elemntos \n    numbers.append(contentsOf: [12,13,14,15,16])  \n    print(numbers)\n\n    // agregar varios elementos en un indice particular\n    numbers.insert(contentsOf: [17,18,19,20], at: 2)\n    print(numbers)\n\n    // actualizar un elemento de la lista\n    numbers[2] = 3\n    print(numbers)\n\n    // encontrar un elemento de la lista\n     print(numbers.contains(21)) \n\n    //remover un elemento de la lista\n    numbers.remove(at: 0)\n    print(numbers)\n    \n    //remover todos los elementos de la lista\n    numbers.removeAll()\n    print(numbers)\n        \n }\n \n OperationsWithCollections()\n\n func OperationsWithSets(){\n     let characters: Set<String> = [\"orochimaru\",\"obito\",\"madara\",\"kisame\",\"danzo\",\"sasori\",\"hidan\",\"kakashi\"]\n     let charactersNaruto: Set<String> = [\"naruto\",\"sasuke\",\"itachi\",\"sakura\",\"kakashi\",\"sasori\",\"danzo\"]\n\n     // union de conjunto \n     \n     // forma declarativa\n     print(\"union de conjuntos declarativa\")\n     let newCharacters = characters.union(charactersNaruto)\n     print(newCharacters)\n\n     // forma imperativa\n     print(\"union de conjuntos imperativa\")\n     var unionCharacters: [String]=[]\n     unionCharacters+=characters\n     unionCharacters+=charactersNaruto\n     print(unionCharacters)\n \n      // intersección de conjuntos\n      \n      print(\"interseccion de conjuntos declarativa\")\n      let commonCharacters = characters.intersection(charactersNaruto)\n      print(commonCharacters)\n\n      print(\"interseccion de conjuntos imperativa\")\n      let commonCh = characters.filter{charactersNaruto.contains($0)}\n      print(commonCh)\n      \n      // diferencia de conjuntos\n\n      // forma declarativa\n      print(\"diferencia de conjuntos declarativa\")\n      let differentCharacters = characters.subtracting(charactersNaruto)\n      print(differentCharacters)\n\n      // forma imperativa\n      print(\"diferencia de conjuntos imperativa\")\n      let differentCh = characters.filter{!charactersNaruto.contains($0)}\n      print(differentCh)\n      \n      // diferencia simétrica\n     \n      // forma declarativa\n      print(\"diferencia simétrica de conjuntos declarativa\")\n      let symmetricDifference = characters.symmetricDifference(charactersNaruto)\n      print(symmetricDifference)\n\n      // forma imperativa\n      print(\"diferencia simétrica de conjuntos imperativa\")\n      let different = characters.filter{!charactersNaruto.contains($0)}\n      let different2 = charactersNaruto.filter{!characters.contains($0)}\n      let symmetricDifferenceCh = Array(different.union(different2))\n      print(symmetricDifferenceCh)\n\n }\n\n OperationsWithSets()\n\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/swift/pedroomar23.swift",
    "content": "import Foundation \n\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n * operaciones (debes utilizar una estructura que las soporte):\n * - Añade un elemento al final.\n * - Añade un elemento al principio.\n * - Añade varios elementos en bloque al final.\n * - Añade varios elementos en bloque en una posición concreta.\n * - Elimina un elemento en una posición concreta.\n * - Actualiza el valor de un elemento en una posición concreta.\n * - Comprueba si un elemento está en un conjunto.\n * - Elimina todo el contenido del conjunto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Unión.\n * - Intersección.\n * - Diferencia.\n * - Diferencia simétrica.\n */\n\n // Conjuntos \n let conjunto = [1, 2, 3, 4, 5]\n\n // Eliminar todo el conjunto \n conjunto.removeAll()\n\n // Eliminar un elemento en concreto \n conjunto.remove(2)\n\n // Añadir un elemento al principio \n conjunto.insert(contentsOf: [-1, 0], at: 0)\n\n // Añadir un elemento al final \n conjunto.append(contentsOf: [6, 7, 8])\n\n // Añadir varios elemnetos en bloque en una posicion concreta \n conjunto.append(contentsOf: [2.1, 2.2, 2.3], at: 2)\n\n // Actualizar el valor de un elemento en una posicion concreta \n conjunto[2] = 10\n\n // Comprobar si un elemento esta en el conjunto \n conjunto.contains(3)\n\n \n\n\n\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/typescript/AChapeton.ts",
    "content": "const letters: Array<string> = ['a', 'b', 'c', 'd']\nconsole.log('Original', letters)\n// Añade un elemento al final.\nletters.push('e')\nconsole.log('Añade un elemento al final', letters)\n\n// Añade un elemento al principio.\nletters.unshift('-')\nconsole.log('Añade un elemento al principio', letters)\n\n// Añade varios elementos en bloque al final.\nconst newLetters: Array<string> = ['x', 'y', 'z']\nletters.push(...newLetters)\nconsole.log('Añade varios elementos en bloque al final', letters)\n\n// Añade varios elementos en bloque en una posición concreta.\nconst newLetters2: Array<string> = ['f', 'g', 'h']\nletters.splice(6, 0, ...newLetters2)\nconsole.log('Añade varios elementos en bloque en una posición concreta', letters)\n\n// Elimina un elemento en una posición concreta.\nletters.splice(5, 1)\nconsole.log('Elimina un elemento en una posición concreta', letters)\n\n// Actualiza el valor de un elemento en una posición concreta.\nletters[1] = '#'\nconsole.log('Actualiza el valor de un elemento en una posición concreta', letters)\n\n// Comprueba si un elemento está en un conjunto.\nconst isAinArray = letters.find(letter => letter === 'a' ? true : false)\nconsole.log(' Comprueba si el elemento -a- está en el conjunto letters', isAinArray)\nconst isXinArray = letters.find(letter => letter === 'x' ? true : false)\nconsole.log(' Comprueba si el elemento -x- está en el conjunto letters', isXinArray)\n\n// Elimina todo el contenido del conjunto.\nletters.length = 0\nconsole.log('Elimina todo el contenido del conjunto', letters)\n\n\n// DIFICULTAD EXTRA\n\n// Union de conjuntos\nconst first: Array<number> = [1, 2, 3, 4]\nconst second: Array<number> = [3, 4, 5, 6]\nconst union: Set<number> = new Set()\n\nfirst.forEach(number => union.add(number))\nsecond.forEach(number => union.add(number))\n\nconsole.log('Union', union)\n\n// Interseccion\nconst interseccion: Set<number> = new Set()\nfirst.forEach(n1 => {\n  second.forEach(n2 => {\n    if(n1 === n2){\n      interseccion.add(n1)\n    }\n  })\n})\n\nconsole.log('Interseccion', interseccion)\n\n// Diferencia\nconst diferencia: Set<number> = new Set()\nfirst.forEach(number => diferencia.add(number))\nsecond.forEach(number => {\n  if (diferencia.has(number)){\n    diferencia.delete(number)\n  }\n})\nconsole.log('Diferencia', diferencia)\n\n\n// Diferencia simetrica\nconst simetrica: Set<number> = new Set()\nfirst.forEach(number => simetrica.add(number))\nsecond.forEach(number => {\n  if(simetrica.has(number)){\n    simetrica.delete(number)\n  }else{\n    simetrica.add(number)\n  }\n})\nconsole.log('Diferencia simetrica', simetrica)\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/typescript/IgleDev.ts",
    "content": "// Ejercicio 1º\n    // Declaramos el conjunto de datos\n        let idolos : Array<string> = ['Igledev', 'Messi'];\n        console.log(`Mis idolos principales ${idolos}`);\n    // Añadir elemento al final\n        idolos.push('MoureDev');\n        console.log(`Añdiendo un nuevo ídolo ${idolos}`);\n    // Añadir elemento al principio\n        idolos.unshift('Mi novia');\n        console.log(`Actualizando mi primer ídolo ${idolos}`);\n    // Añade varios elementos en bloque al final.\n        let idolos2 : Array<string> = ['Yoshi', 'Ana Pontón'];\n        idolos.push(...idolos2);\n        console.log(`Añadiendo más ídolos ${idolos}`);\n    // Añade varios elementos según la posición deseada\n        let masIdolos : Array<string> = ['Lahm', 'Luis Suarez', 'Neymar'];\n        idolos.splice(6, 0, ...masIdolos);\n        console.log(`Añadiendo más ídolos pero con posición${idolos}`);\n    // Actualiza el valor de un elemento en una posición concreta\n        idolos[1] = 'Arrian';\n        console.log(`Cambiando el ídolo${idolos}`);\n    // Comprueba si un elemento está en un conjunto.\n        let idoloEncontrado = idolos.find(idolo => idolo === 'Messi' ? true : false);\n        console.log(`Esta el ídolo en la lista? ${idoloEncontrado}`);\n    // Elimina todo el contenido del conjunto\n        idolos.length = 0;\n        console.log(`Eliminando todos los idolos: ${idolos}`);\n\n// Ejercicio Extra\n    let numeros1: Array<number> = [1, 2, 3, 4];\n    let numeros2: Array<number> = [3, 4, 5, 6];\n    let union: Set<number> = new Set();\n\n    // Union\n        numeros1.forEach(number => union.add(number));\n        numeros2.forEach(number => union.add(number));\n        console.log(`Unión de numeros: ${union}`);\n    // Interseccion\n        let interseccion: Set<number> = new Set();\n        numeros1.forEach(n1 => {\n            numeros2.forEach(n2 => {\n                if(n1 === n2){\n                  interseccion.add(n1);\n                }\n            })\n        })\n        console.log(`Interseccion de numeros: ${interseccion}`);\n    // Diferencia\n        let diferencia: Set<number> = new Set();\n        numeros1.forEach(number => diferencia.add(number));\n        numeros2.forEach(number => {\n            if (diferencia.has(number)){\n              diferencia.delete(number);\n            }\n        })\n        console.log(`Diferencia de numeros: ${diferencia}`);\n    // Diferencia simetrica\n        let difSimetrica: Set<number> = new Set();\n        numeros1.forEach(number => difSimetrica.add(number))\n        numeros2.forEach(number => {\n            if(difSimetrica.has(number)){\n              difSimetrica.delete(number);\n            }else{\n              difSimetrica.add(number);\n            }\n        });\n        console.log(`Diferencia SIMÉTRICA de números: ${difSimetrica}`)"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/typescript/Sac-Corts.ts",
    "content": "let set: number[] = [];\nset.push(10);\nset.unshift(1);\nset.push(11, 12);\nset.splice(1, 0, 2, 3);\nset.splice(2, 1);\nset[2] = 5;\nlet elementExist: boolean = set.includes(3);\nconsole.log(elementExist);\nconsole.log(set);\nset = [];\nconsole.log(set);\n\n// ** Extra Exercise ** //\nconst setA: Set<number> = new Set([1, 2, 3]);\nconst setB: Set<number> = new Set([3, 4, 5]);\n\n// Union\nconst union: Set<number> = new Set([...setA, ...setB]);\nconsole.log(union);\n\n// Intersection\nconst intersection: Set<number> = new Set([...setA].filter(x => setB.has(x)));\nconsole.log(intersection);\n\n// Difference\nconst difference: Set<number> = new Set([...setA].filter(x => !setB.has(x)));\nconsole.log(difference);\n\n// Symmetric Difference\nconst symmetricDifference: Set<number> = new Set([\n    ...[...setA].filter(x => !setB.has(x)), \n    ...[...setB].filter(x => !setA.has(x))\n]);\nconsole.log(symmetricDifference);\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/typescript/duendeintemporal.ts",
    "content": "//#18  { retosparaprogramadores } - CONJUNTOS\n/*\n * EJERCICIO:\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n * operaciones (debes utilizar una estructura que las soporte):\n * - Añade un elemento al final.\n * - Añade un elemento al principio.\n * - Añade varios elementos en bloque al final.\n * - Añade varios elementos en bloque en una posición concreta.\n * - Elimina un elemento en una posición concreta.\n * - Actualiza el valor de un elemento en una posición concreta.\n * - Comprueba si un elemento está en un conjunto.\n * - Elimina todo el contenido del conjunto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Unión.\n * - Intersección.\n * - Diferencia.\n * - Diferencia simétrica.\n */\n\nlet log = console.log;\n\n// Conditional check for browser environment\nif (typeof window !== 'undefined') {\n    window.addEventListener('load', () => {\n        const body: HTMLBodyElement | null = document.querySelector('body');\n        const title = document.createElement('h1');\n\n        body?.style.setProperty('background', '#000');\n        body?.style.setProperty('text-align', 'center');\n\n        title.textContent = 'Retosparaprogramadores #18.';\n        title.style.setProperty('font-size', '3.5vmax');\n        title.style.setProperty('color', '#fff');\n        title.style.setProperty('line-height', '100vh');\n\n        body?.appendChild(title);\n\n        setTimeout(() => {\n            alert('Retosparaprogramadores #18. Please open the Browser Developer Tools.');\n        }, 2000);\n        log('Retosparaprogramadores #18');\n});\n} else {\n    log('This code is designed to run in a browser environment. Skipping window-related code.');\n    log('Retosparaprogramadores #18');\n}\nfor(let i = 1; i <= 10; i++){\n    log(i);\n} // print numbers from 1 to 10\n\n\nlet arr: number[] = [1,2,3,4,5];\nlog(arr)// [1,2,3,4,5]\n// Adds an element to the end.\narr.push(6);\nlog(arr); // [1,2,3,4,5,6]\n\n// Adds an element to the beginning.\narr.unshift(0);\nlog(arr); // [0, 1, 2, 3, 4, 5, 6]\n// Adds multiple elements in bulk to the end.\nlet arr2: number[] = [7,8,9,10];\narr.push(...arr2);\nlog(arr); //  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n\n// Adds multiple elements in bulk at a specific position.\nlet arr3: number[] = [3.1, 3.2, 3.4]\narr.splice(4,0, ...arr3);\nlog(arr); // [0, 1, 2, 3, 3.1, 3.2, 3.4, 4, 5, 6, 7, 8, 9, 10]\n\n// Removes an element at a specific position.\narr.splice(6,1);\nlog(arr); // [0, 1, 2, 3, 3.1, 3.2, 4, 5, 6, 7, 8, 9, 10]\n\n// Updates the value of an element at a specific position.\narr.splice(arr.length - 1, 1, 9.1);\nlog(arr); // [0, 1, 2, 3, 3.1, 3.2, 4, 5, 6, 7, 8, 9, 9.1]\n\n// Checks if an element is in a set.\nlet nums: Set<number> = new Set();\narr.forEach(n=>nums.add(n));\nlog('Is 10 in nums: ', nums.has(10)) // Is 10 in nums:  false\n\n// Removes all content from the set.\nnums.clear();\nlog(nums); // Set(0) {}\n\n// EXTRA DIFFICULTY (optional):\n\n// Union.\nlet arr4: number[] = [10, 11, 12, 13, 14];\nlet union: Set<number> = new Set([...arr, ...arr4]);\nlog('union: ', union); // union:  Set(18) {0, 1, 2, 3, 3.1, …}\n\n// Intersection.\nlet arr5: number[] = [1,4,5,6,15,16,17,18,19];\nlet intersection: Set<number> = new Set();\narr5.forEach(n => {\n    if (union.has(n)) {\n        intersection.add(n);\n    }});\n\nlog('Intersection:', [...intersection]); // Intersection: [1, 4, 5, 6]  \n\n// Difference.\nlet difference: Set<number> = new Set(arr); \narr5.forEach(n => {\n    if (difference.has(n)) {\n        difference.delete(n); \n    }});\n\nlog('Difference:', [...difference]); // Difference: [0, 2, 3, 3.1, 3.2, 7, 8, 9, 9.1]\n\n// Symmetric difference.\nlet symmetricDiff: Set<number> = new Set([...arr, ...arr5]); \narr5.forEach(n => {\n    if (union.has(n)) {\n        symmetricDiff.delete(n); \n    }\n});\narr.forEach(n => {\n    if (arr5.includes(n)) {\n        symmetricDiff.delete(n); \n    }});\n\nlog('Symmetric Difference:', [...symmetricDiff]); \n// Symmetric Difference: [0, 2, 3, 3.1, 3.2, 7, 8, 9, 9.1, 15, 16, 17, 18, 19]"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/typescript/eulogioep.ts",
    "content": "/**\n * TEORÍA: Conjuntos (Sets) en TypeScript\n * \n * TypeScript utiliza la misma implementación de Set que JavaScript, pero añade\n * tipado estático y algunas mejoras en la sintaxis. Los Sets en TypeScript:\n * \n * 1. Son colecciones de valores únicos\n * 2. Pueden contener cualquier tipo de valor\n * 3. Mantienen el orden de inserción\n * 4. Proporcionan operaciones eficientes para añadir, eliminar y verificar elementos\n * \n * TypeScript añade la capacidad de tipar los Sets, por ejemplo:\n * let stringSet: Set<string> = new Set<string>();\n */\n\nclass SetOperations<T> {\n    private conjunto: Set<T>;\n\n    constructor() {\n        this.conjunto = new Set<T>();\n    }\n\n    /**\n     * Muestra el contenido actual del conjunto\n     */\n    private mostrarConjunto(mensaje: string): void {\n        console.log(`${mensaje}: [${Array.from(this.conjunto).join(\", \")}]`);\n    }\n\n    /**\n     * 1. Añade un elemento al final\n     */\n    agregarAlFinal(elemento: T): void {\n        this.conjunto.add(elemento);\n        this.mostrarConjunto(`Después de añadir '${String(elemento)}' al final`);\n    }\n\n    /**\n     * 2. Añade un elemento al \"principio\"\n     * Nota: En realidad, en un Set no hay concepto de principio o final\n     * Simulamos esto convirtiendo a array, modificando y volviendo a Set\n     */\n    agregarAlPrincipio(elemento: T): void {\n        const tempArray = Array.from(this.conjunto);\n        this.conjunto = new Set([elemento, ...tempArray]);\n        this.mostrarConjunto(`Después de añadir '${String(elemento)}' al principio`);\n    }\n\n    /**\n     * 3. Añade varios elementos en bloque al final\n     */\n    agregarVariosAlFinal(elementos: T[]): void {\n        elementos.forEach(elemento => this.conjunto.add(elemento));\n        this.mostrarConjunto(\"Después de añadir varios elementos al final\");\n    }\n\n    /**\n     * 4. Añade varios elementos en bloque en una posición concreta\n     */\n    agregarVariosEnPosicion(elementos: T[], posicion: number): void {\n        const tempArray = Array.from(this.conjunto);\n        tempArray.splice(posicion, 0, ...elementos);\n        this.conjunto = new Set(tempArray);\n        this.mostrarConjunto(`Después de añadir elementos en posición ${posicion}`);\n    }\n\n    /**\n     * 5. Elimina un elemento en una posición concreta\n     */\n    eliminarEnPosicion(posicion: number): void {\n        const tempArray = Array.from(this.conjunto);\n        if (posicion >= 0 && posicion < tempArray.length) {\n            tempArray.splice(posicion, 1);\n            this.conjunto = new Set(tempArray);\n            this.mostrarConjunto(`Después de eliminar elemento en posición ${posicion}`);\n        }\n    }\n\n    /**\n     * 6. Actualiza el valor de un elemento en una posición concreta\n     */\n    actualizarEnPosicion(posicion: number, nuevoValor: T): void {\n        const tempArray = Array.from(this.conjunto);\n        if (posicion >= 0 && posicion < tempArray.length) {\n            tempArray[posicion] = nuevoValor;\n            this.conjunto = new Set(tempArray);\n            this.mostrarConjunto(`Después de actualizar elemento en posición ${posicion}`);\n        }\n    }\n\n    /**\n     * 7. Comprueba si un elemento está en el conjunto\n     */\n    contiene(elemento: T): boolean {\n        const resultado = this.conjunto.has(elemento);\n        console.log(`¿El conjunto contiene '${String(elemento)}'? ${resultado ? \"Sí\" : \"No\"}`);\n        return resultado;\n    }\n\n    /**\n     * 8. Elimina todo el contenido del conjunto\n     */\n    limpiar(): void {\n        this.conjunto.clear();\n        this.mostrarConjunto(\"Después de limpiar el conjunto\");\n    }\n\n    /**\n     * Obtiene el conjunto actual\n     */\n    obtenerConjunto(): Set<T> {\n        return this.conjunto;\n    }\n}\n\n/**\n * Clase estática para operaciones extra con conjuntos\n */\nclass OperacionesExtra {\n    /**\n     * Unión de dos conjuntos\n     */\n    static union<T>(conjunto1: Set<T>, conjunto2: Set<T>): Set<T> {\n        return new Set([...conjunto1, ...conjunto2]);\n    }\n\n    /**\n     * Intersección de dos conjuntos\n     */\n    static interseccion<T>(conjunto1: Set<T>, conjunto2: Set<T>): Set<T> {\n        return new Set([...conjunto1].filter(x => conjunto2.has(x)));\n    }\n\n    /**\n     * Diferencia de dos conjuntos\n     */\n    static diferencia<T>(conjunto1: Set<T>, conjunto2: Set<T>): Set<T> {\n        return new Set([...conjunto1].filter(x => !conjunto2.has(x)));\n    }\n\n    /**\n     * Diferencia simétrica de dos conjuntos\n     */\n    static diferenciaSimetrica<T>(conjunto1: Set<T>, conjunto2: Set<T>): Set<T> {\n        const diferencia1 = OperacionesExtra.diferencia(conjunto1, conjunto2);\n        const diferencia2 = OperacionesExtra.diferencia(conjunto2, conjunto1);\n        return OperacionesExtra.union(diferencia1, diferencia2);\n    }\n}\n\n// Función para mostrar un conjunto\nfunction mostrarConjunto<T>(nombre: string, conjunto: Set<T>): void {\n    console.log(`${nombre}: [${Array.from(conjunto).join(\", \")}]`);\n}\n\n// Demostración de uso\nfunction demostrarOperaciones(): void {\n    console.log(\"PARTE 1: OPERACIONES BÁSICAS\");\n    const demo = new SetOperations<string>();\n\n    demo.agregarAlFinal(\"Elemento1\");\n    demo.agregarAlPrincipio(\"Elemento2\");\n    demo.agregarVariosAlFinal([\"Elemento3\", \"Elemento4\", \"Elemento5\"]);\n    demo.agregarVariosEnPosicion([\"ElementoA\", \"ElementoB\"], 2);\n    demo.eliminarEnPosicion(3);\n    demo.actualizarEnPosicion(1, \"ElementoActualizado\");\n    demo.contiene(\"Elemento1\");\n    demo.limpiar();\n\n    console.log(\"\\nPARTE 2: OPERACIONES EXTRA\");\n    const conjunto1 = new Set([1, 2, 3, 4, 5]);\n    const conjunto2 = new Set([4, 5, 6, 7, 8]);\n\n    mostrarConjunto(\"Conjunto 1\", conjunto1);\n    mostrarConjunto(\"Conjunto 2\", conjunto2);\n\n    const union = OperacionesExtra.union(conjunto1, conjunto2);\n    mostrarConjunto(\"Unión\", union);\n\n    const interseccion = OperacionesExtra.interseccion(conjunto1, conjunto2);\n    mostrarConjunto(\"Intersección\", interseccion);\n\n    const diferencia = OperacionesExtra.diferencia(conjunto1, conjunto2);\n    mostrarConjunto(\"Diferencia (conjunto1 - conjunto2)\", diferencia);\n\n    const diferenciaSimetrica = OperacionesExtra.diferenciaSimetrica(conjunto1, conjunto2);\n    mostrarConjunto(\"Diferencia simétrica\", diferenciaSimetrica);\n}\n\n// Ejecutar la demostración\ndemostrarOperaciones();"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/typescript/hozlucas28.ts",
    "content": "/*\n    Data methods...\n*/\n\nconsole.log('Data methods...')\n\nclass Data<T extends string> {\n\tprivate savedData: T[]\n\n\tconstructor(initialData: T[]) {\n\t\tthis.savedData = this.sanitizeData(initialData)\n\t}\n\n\tpublic getData(): T[] {\n\t\treturn this.savedData\n\t}\n\n\tpublic setData(newInitialData: T[]): this {\n\t\tthis.savedData = this.sanitizeData(newInitialData)\n\t\treturn this\n\t}\n\n\tprivate sanitizeData(data: T[]): T[] {\n\t\tconst uniqueData: Set<T> = new Set(data)\n\t\tconst uniqueDataValues: IterableIterator<T> = uniqueData.values()\n\n\t\tconst sanitizedData: T[] = []\n\t\tfor (let i = 0; i < uniqueData.size; i++) {\n\t\t\tsanitizedData.push(uniqueDataValues.next().value)\n\t\t}\n\n\t\treturn sanitizedData\n\t}\n\n\tpublic appendEnd(newData: T[]): this {\n\t\tthis.savedData.push(...newData)\n\t\treturn this\n\t}\n\n\tpublic appendStart(newData: T[]): this {\n\t\tthis.savedData.unshift(...newData)\n\t\treturn this\n\t}\n\n\tpublic appendAt(index: number, newData: T | T[]): this {\n\t\tconst head: T[] = this.savedData.slice(0, index)\n\t\tconst tail: T[] = this.savedData.slice(index)\n\n\t\tconst newSavedData: T[] = [...head]\n\n\t\ttypeof newData === 'string'\n\t\t\t? newSavedData.push(newData)\n\t\t\t: newSavedData.push(...newData)\n\n\t\tnewSavedData.push(...tail)\n\n\t\tthis.setData(newSavedData)\n\t\treturn this\n\t}\n\n\tpublic clear(): this {\n\t\tthis.setData([])\n\t\treturn this\n\t}\n\n\tpublic deleteAt(index: number): this {\n\t\tconst head: T[] = this.savedData.slice(0, index)\n\t\tconst tail: T[] = this.savedData.slice(index + 1)\n\n\t\tconst newSavedData: T[] = [...head, ...tail]\n\n\t\tthis.setData(newSavedData)\n\t\treturn this\n\t}\n\n\tpublic has(data: T): boolean {\n\t\treturn this.savedData.some((value) => value === data)\n\t}\n\n\tpublic updateAt(index: number, newValue: T): this {\n\t\tthis.savedData[index] = newValue\n\t\treturn this\n\t}\n}\n\nconst data: Data<string> = new Data([\n\t'Buenos Aires',\n\t'Texas',\n\t'Madrid',\n\t'Houston',\n\t'Buenos Aires',\n\t'California',\n\t'Texas',\n])\n\nconsole.log(\n\t`\\nconst data: Data<string> = new Data(['Buenos Aires', 'Texas', 'Madrid', 'Houston', 'Buenos Aires', 'California', 'Texas'])`\n)\n\nconsole.table(data.getData())\n\nconsole.log('\\nAppend data at the end...')\nconsole.log(`\\ndata.appendEnd(['Berlin'])`)\n\ndata.appendEnd(['Berlin'])\nconsole.table(data.getData())\n\nconsole.log('\\nAppend data at the start...')\nconsole.log(`\\ndata.appendStart(['Chaco'])`)\n\ndata.appendStart(['Chaco'])\nconsole.table(data.getData())\n\nconsole.log('\\nAppend several data at the end...')\nconsole.log(`\\ndata.appendEnd(['Paris', 'Montana'])`)\n\ndata.appendEnd(['Paris', 'Montana'])\nconsole.table(data.getData())\n\nconsole.log('\\nAppend several data at index 4...')\nconsole.log(`\\ndata.appendAt(4, ['Jujuy', 'Formosa'])`)\n\ndata.appendAt(4, ['Jujuy', 'Formosa'])\nconsole.table(data.getData())\n\nconsole.log('\\nDelete data at index 3...')\nconsole.log(`\\ndata.deleteAt(3)`)\n\ndata.deleteAt(3)\nconsole.table(data.getData())\n\nconsole.log('\\nUpdate data at index 6...')\nconsole.log(`\\ndata.updateAt(6, 'Miami')`)\n\ndata.updateAt(6, 'Miami')\nconsole.table(data.getData())\n\nconsole.log('\\nCheck if a data is present...')\nconsole.log(`\\ndata.has('Buenos Aires') => ${data.has('Buenos Aires')}`)\n\nconsole.table(data.getData())\n\nconsole.log('\\nClear saved data...')\nconsole.log(`\\ndata.clear()`)\n\ndata.clear()\nconsole.table(data.getData())\n\nconsole.log(\n\t'\\n# ---------------------------------------------------------------------------------- #\\n'\n)\n\n/*\n    Additional challenge...\n*/\n\nconsole.log('Additional challenge...')\n\nfunction differenceSets<T>(firstSet: Set<T>, secondSet: Set<T>): Set<T> {\n\tconst differenceSets: Set<T> = new Set()\n\n\tconst firstSetValues: IterableIterator<T> = firstSet.values()\n\n\tfor (let i = 0; i < firstSet.size; i++) {\n\t\tconst firstSetValue = firstSetValues.next().value\n\t\tif (!secondSet.has(firstSetValue)) differenceSets.add(firstSetValue)\n\t}\n\treturn differenceSets\n}\n\nfunction intersectionSets<T>(firstSet: Set<T>, secondSet: Set<T>): Set<T> {\n\tconst intersectedSets: Set<T> = new Set()\n\n\tconst [shortestSet, longestSet]: [Set<T>, Set<T>] =\n\t\tfirstSet.size < secondSet.size\n\t\t\t? [firstSet, secondSet]\n\t\t\t: [secondSet, firstSet]\n\n\tconst shortestSetValues: IterableIterator<T> = shortestSet.values()\n\n\tfor (let i = 0; i < shortestSet.size; i++) {\n\t\tconst shortestSetValue = shortestSetValues.next().value\n\t\tif (longestSet.has(shortestSetValue)) intersectedSets.add(shortestSetValue)\n\t}\n\n\treturn intersectedSets\n}\n\nfunction joinSets<T>(firstSet: Set<T>, secondSet: Set<T>): Set<T> {\n\tconst joinedSets: Set<T> = new Set()\n\n\tconst [shortestSet, longestSet]: [Set<T>, Set<T>] =\n\t\tfirstSet.size < secondSet.size\n\t\t\t? [firstSet, secondSet]\n\t\t\t: [secondSet, firstSet]\n\n\tconst shortestSetValues: IterableIterator<T> = shortestSet.values()\n\tconst longestSetValues: IterableIterator<T> = longestSet.values()\n\n\tfor (let i = 0; i < longestSet.size; i++) {\n\t\tif (i < shortestSet.size) joinedSets.add(shortestSetValues.next().value)\n\t\tjoinedSets.add(longestSetValues.next().value)\n\t}\n\n\treturn joinedSets\n}\n\nfunction symmetricDifferenceSets<T>(\n\tfirstSet: Set<T>,\n\tsecondSet: Set<T>\n): Set<T> {\n\tconst symmetricDifferenceSets: Set<T> = new Set()\n\n\tconst headDifference = differenceSets(firstSet, secondSet)\n\tconst tailDifference = differenceSets(secondSet, firstSet)\n\n\tconst headDifferenceValues = headDifference.values()\n\tconst tailDifferenceValues = tailDifference.values()\n\n\tfor (let i = 0; i < headDifference.size + tailDifference.size; i++) {\n\t\tconst headDifferenceValuesObj = headDifferenceValues.next()\n\t\tconst tailDifferenceValuesObj = tailDifferenceValues.next()\n\n\t\tif (!headDifferenceValuesObj.done)\n\t\t\tsymmetricDifferenceSets.add(headDifferenceValuesObj.value)\n\n\t\tif (!tailDifferenceValuesObj.done)\n\t\t\tsymmetricDifferenceSets.add(tailDifferenceValuesObj.value)\n\t}\n\n\treturn symmetricDifferenceSets\n}\n\nconst firstSet: Set<string> = new Set(['Hello', 'TypeScript', 'World!'])\nconst secondSet: Set<string> = new Set(['By', 'TypeScript'])\n\nconsole.log('\\nfirstSet =', firstSet)\nconsole.log('\\nsecondSet =', secondSet)\n\nconst intersectedSets: Set<string> = intersectionSets(firstSet, secondSet)\n\nconsole.log('\\nIntersection (firstSet, and secondSet) =>', intersectedSets)\n\nconst joinedSets: Set<string> = joinSets(firstSet, secondSet)\n\nconsole.log('\\nJoin (firstSet, and secondSet) =>', joinedSets)\n\nconst differenceSetsRtn: Set<string> = differenceSets(firstSet, secondSet)\n\nconsole.log('\\nDifference (firstSet, and secondSet) =>', differenceSetsRtn)\n\nconst symmetricDifferenceSetsRtn: Set<string> = symmetricDifferenceSets(\n\tfirstSet,\n\tsecondSet\n)\n\nconsole.log(\n\t'\\nSymmetric difference (firstSet, and secondSet) =>',\n\tsymmetricDifferenceSetsRtn\n)\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/typescript/nlarrea.ts",
    "content": "/*\n * EJERCICIO:\n * Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n * operaciones (debes utilizar una estructura que las soporte):\n * - Añade un elemento al final.\n * - Añade un elemento al principio.\n * - Añade varios elementos en bloque al final.\n * - Añade varios elementos en bloque en una posición concreta.\n * - Elimina un elemento en una posición concreta.\n * - Actualiza el valor de un elemento en una posición concreta.\n * - Comprueba si un elemento está en un conjunto.\n * - Elimina todo el contenido del conjunto.\n *\n * DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Unión.\n * - Intersección.\n * - Diferencia.\n * - Diferencia simétrica.\n */\n\n\nconst data: (number | string | any[])[] = [1, 2, 3, 4, 5]\n\n// Añadir elemento al final\ndata.push('end')\nconsole.log(data)  // [ 1, 2, 3, 4, 5, 'end' ]\n\n// Añadir elemento al principio\ndata.unshift('start')\nconsole.log(data)  // [ 'start', 1, 2, 3, 4, 5, 'end' ]\n\n// Añade varios elementos en bloque al final\ndata.push(['more', 'elements', 3])\nconsole.log(data)  // [ 'start', 1, 2, 3, 4, 5, 'end', [ 'more', 'elements', 3 ] ]\n\n// Añade varios elementos en bloque en una posición concreta\ndata.splice(2, 0, ['position', 2])\nconsole.log(data)\n// ['start', 1, [ 'position', 2 ], 2, 3, 4, 5, 'end', [ 'more', 'elements', 3 ]]\n\n// Elimina un elemento en una posición concreta\ndata.splice(1, 1)\nconsole.log(data)\n// ['start', [ 'position', 2 ], 2, 3, 4, 5, 'end', [ 'more', 'elements', 3 ]]\n\n// Actualiza el valor de un elemento en una posición concreta\ndata[1] = 1\nconsole.log(data)  // [ 'start', 1, 2, 3, 4, 5, 'end', [ 'more', 'elements', 3 ] ]\n\n// Comprueba si un elemento está en un conjunto\nconsole.log(data.includes('start'))  // true\nconsole.log(data.includes('bbb'))  // false\n\n// Elimina todo el contenido del conjunto\ndata.splice(0)\nconsole.log(data)  // []\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Muestra ejemplos de las siguientes operaciones con conjuntos:\n * - Unión.\n * - Intersección.\n * - Diferencia.\n * - Diferencia simétrica.\n */\n\n\nconst d1: number[] = [...Array(4).keys()]  // d1 = [0, 1, 2, 3]\nconst d2: number[] = [1, 2, 3, 4, 5, 6, 7]\n\nconst dataUnion: number[] = [...new Set([...d1, ...d2])]\nconsole.log(dataUnion)\n// [ 0, 1, 2, 3, 4, 5, 6, 7 ]\n\nconst dataIntersection: number[] = d1.filter(item => d2.includes(item))\nconsole.log(dataIntersection)\n// [ 1, 2, 3 ]\n\nconst difference12: number[] = d1.filter(item => !d2.includes(item))\nconsole.log(difference12)\n// [  0 ]\nconst difference21: number[] = d2.filter(item => !d1.includes(item))\nconsole.log(difference21)\n// [ 4, 5, 6, 7 ]\n\nconst symmetricDifference: number[] = [\n    ...new Set([...difference12, ...difference21])\n]\nconsole.log(symmetricDifference)\n// [ 0, 4, 5, 6, 7 ]"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/typescript/victor-Casta.ts",
    "content": "const myList: (number | number[])[] = [1,2,3,4]\n\nmyList.push(5)\nmyList.unshift(0)\nmyList.push([10, 11, 12])\nmyList[2] = [20, 21, 23]\nmyList.splice(0, 1)\nmyList[0] = 3\nmyList.includes(3)\nmyList.length = 0\n\n/*\n  Extra\n*/\n\nconst mySet1: Set<number> = new Set([1, 3, 5, 7, 9])\nconst mySet2: Set<number> = new Set([1, 4, 9])\n\n// Unión\nconsole.log(mySet1.union(mySet2))\n\n// Intersección\nconsole.log(mySet1.intersection(mySet2))\n\n// Diferencia\nconsole.log(mySet1.difference(mySet2))\n\n// Diferencia simétrica\nconsole.log(mySet1.symmetricDifference(mySet2))\n\n/*\n  * Referencia: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set\n*/"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/typescript/victoriaparraf.ts",
    "content": "let data: number[] = [2, 3, 4];\n\n// Añade un elemento al final\ndata.push(5);\nconsole.log(\"Añade un elemento al final:\", data); // [2, 3, 4, 5]\n\n// Añade un elemento al principio\ndata.unshift(1);\nconsole.log(\"Añade un elemento al principio:\", data); // [1, 2, 3, 4, 5]\n\n// Añade varios elementos en bloque al final\ndata.push(6, 7, 8);\nconsole.log(\"Añade varios elementos en bloque al final:\", data); // [1, 2, 3, 4, 5, 6, 7, 8]\n\n// Añade varios elementos en bloque en una posición concreta\ndata.splice(4, 0, 9, 10);\nconsole.log(\"Añade varios elementos en bloque en una posición concreta:\", data); // [1, 2, 3, 4, 9, 10, 5, 6, 7, 8]\n\n// Elimina un elemento en una posición concreta\ndata.splice(4, 1);\nconsole.log(\"Elimina un elemento en una posición concreta:\", data); // [1, 2, 3, 4, 10, 5, 6, 7, 8]\n\n// Actualiza el valor de un elemento en una posición concreta\ndata[4] = 11;\nconsole.log(\"Actualiza el valor de un elemento en una posición concreta:\", data); // [1, 2, 3, 4, 11, 5, 6, 7, 8]\n\n// Comprueba si un elemento está en un conjunto\nlet contains = data.includes(11);\nconsole.log(\"Comprueba si un elemento está en un conjunto:\", contains); // true\n\n// Elimina todo el contenido del conjunto\ndata = [];\nconsole.log(\"Elimina todo el contenido del conjunto:\", data); // []\n\n/**************/\nconst setA: Set<number> = new Set([1, 2, 3, 4, 5]);\nconst setB: Set<number> = new Set([4, 5, 6, 7, 8]);\n\n// Unión\nconst union = new Set([...setA, ...setB]);\nconsole.log(\"Unión:\", union); // Set { 1, 2, 3, 4, 5, 6, 7, 8 }\n\n// Intersección\nconst intersection = new Set([...setA].filter(x => setB.has(x)));\nconsole.log(\"Intersección:\", intersection); // Set { 4, 5 }\n\n// Diferencia\nconst difference = new Set([...setA].filter(x => !setB.has(x)));\nconsole.log(\"Diferencia:\", difference); // Set { 1, 2, 3 }\n\n// Diferencia Simétrica\nconst symmetricDifference = new Set([...setA].filter(x => !setB.has(x)).concat([...setB].filter(x => !setA.has(x))));\nconsole.log(\"Diferencia Simétrica:\", symmetricDifference); // Set { 1, 2, 3, 6, 7, 8 }\n\n"
  },
  {
    "path": "Roadmap/18 - CONJUNTOS/vb.net/kenysdev.vb",
    "content": "' ╔══════════════════════════════════════╗\n' ║ Autor:  Kenys Alvarado               ║\n' ║ GitHub: https://github.com/Kenysdev  ║\n' ║ 2024 -  VB.NET                       ║\n' ╚══════════════════════════════════════╝\n'-----------------------------------------------\n'* CONJUNTOS\n'-----------------------------------------------\n\nModule Program\n\n    Sub Main()\n        ' CONJUNTOS: Son una colección desordenada de elementos únicos.\n        Dim mySet As New HashSet(Of Integer) From {1, 2, 3, 0}\n\n        ' EJERCICIO #1:\n        ' Utilizando tu lenguaje crea un conjunto de datos y realiza las siguientes\n        ' operaciones (debes utilizar una estructura que las soporte):\n\n        ' NOTA: - Algunas operaciones del ejercicio no pueden realizarse utilizando 'HashSet'.\n\n        Dim myList As New List(Of String) From {\"a\", \"b\", \"c\"}\n\n        ' Añade un elemento al final.\n        myList.Add(\"d\")\n\n        ' Añadir un elemento al principio\n        myList.Insert(0, \"-\")\n\n        ' Añadir varios elementos en bloque al final\n        myList.AddRange({\"e\", \"f\"})\n\n        ' Añadir varios elementos en bloque en una posición concreta\n        myList.InsertRange(4, {\"-\", \">\"})\n\n        ' Eliminar un elemento en una posición concreta\n        myList.RemoveAt(5)\n\n        ' Actualizar el valor de un elemento en una posición concreta\n        myList(2) = \"-b\"\n\n        ' Mostrar la lista\n        Console.WriteLine(\"Elementos de la lista:\")\n        Console.WriteLine(String.Join(\", \", myList) + vbCrLf)\n\n        ' Comprueba si un elemento está en un conjunto\n        Console.WriteLine($\"'4' en conjunto: {mySet.Contains(4)}\" + vbCrLf)\n        Console.WriteLine($\"'c' en lista: {myList.Contains(\"c\")}\" + vbCrLf)\n\n        ' Elimina todo el contenido del conjunto y la lista.\n        mySet.Clear()\n        myList.Clear()\n\n        ' EJERCICIO #2:\n        ' Muestra ejemplos de las siguientes operaciones con conjuntos:\n        ' - Unión.\n        ' - Intersección.\n        ' - Diferencia.\n        ' - Diferencia simétrica.\n\n        Dim set1 As New HashSet(Of Integer) From {1, 2, 3, 4}\n        Dim set2 As New HashSet(Of Integer) From {3, 4, 5, 6}\n\n        Console.WriteLine(\n            $\"* set_1: {{{String.Join(\", \", set1)}}} - set_2: {{{String.Join(\", \", set2)}}}\" + vbCrLf)\n\n        ' Unión\n        ' Elementos que están en al menos uno de los conjuntos.\n        Dim union As New HashSet(Of Integer)(set1)\n        union.UnionWith(set2)\n        Console.WriteLine($\"- Unión: {{{String.Join(\", \", union)}}}\" + vbCrLf)\n\n        ' Intersección\n        ' Elementos que están en ambos conjuntos.\n        Dim intersection As New HashSet(Of Integer)(set1)\n        intersection.IntersectWith(set2)\n        Console.WriteLine($\"- Intersección: {{{String.Join(\", \", intersection)}}}\" + vbCrLf)\n\n        ' Diferencia\n        ' Elementos que están en set_1 pero no en set_2\n        Dim difference As New HashSet(Of Integer)(set1)\n        difference.ExceptWith(set2)\n        Console.WriteLine($\"- Diferencia: {{{String.Join(\", \", difference)}}}\" + vbCrLf)\n\n        ' Diferencia simétrica\n        ' Elementos que están en uno de los conjuntos pero no en ambos.\n        Dim symmetricDiff As New HashSet(Of Integer)(set1)\n        symmetricDiff.SymmetricExceptWith(set2)\n        Console.WriteLine($\"- Diferencia simétrica: {{{String.Join(\", \", symmetricDiff)}}}\")\n    End Sub\nEnd Module\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/bash/rantamhack.sh",
    "content": "#!/bin/bash\n\n\n# * EJERCICIO:\n# * Empleando tu lenguaje, explora la definiciÃ³n del tipo de dato\n# * que sirva para definir enumeraciones (Enum).\n# * Crea un Enum que represente los dÃ­as de la semana del lunes\n# * al domingo, en ese orden. Con ese enumerado, crea una operaciÃ³n\n# * que muestre el nombre del dÃ­a de la semana dependiendo del nÃºmero entero\n# * utilizado (del 1 al 7).\n\n\necho -e \"\\n\\n=======================================EJERCICIO=======================================\\n\\n\"\n\n# Bash no tiene un tipo de dato \"enum\". Bash es un lenguaje de scripting que no admite la definiciÃ³n \n# de tipos de datos enumerados como en otros lenguajes de programaciÃ³n. Hay que simularlo\n\ndeclare -A week\n\nweek[MONDAY]='1'\nweek[TUESDAY]='2'\nweek[WEDNESDAY]='3'\nweek[THURSDAY]='4'\nweek[FRIDAY]='5'\nweek[SATURDAY]='6'\nweek[SUNDAY]='7'\n\n\nfor key in \"${!week[@]}\"; do\n    if [[ \"${week[$key]}\" -eq '3' ]]; then\n        echo \"$key\"\n    fi\ndone\n\n\necho -e \"\\n\\n=======================================DIFICULTAD EXTRA=======================================\\n\\n\"\n\n# * DIFICULTAD EXTRA (opcional):\n# * Crea un pequeÃ±o sistema de gestiÃ³n del estado de pedidos.\n# * Implementa una clase que defina un pedido con las siguientes caracterÃ­sticas:\n# * - El pedido tiene un identificador y un estado.\n# * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n# * - Implementa las funciones que sirvan para modificar el estado:\n# * - Pedido enviado\n# * - Pedido cancelado\n# * - Pedido entregado\n# *  (Establece una lÃ³gica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n# * - Implementa una funciÃ³n para mostrar un texto descriptivo segÃºn el estado actual.\n# * - Crea diferentes pedidos y muestra cÃ³mo se interactÃºa con ellos. \n\n\n\ndeclare -A order_management\n\norder_management[PENDING]=1\norder_management[SENT]=2\norder_management[DELIVERED]=3\norder_management[CANCELED]=4        \n    \n\nfunction initialize_order {\n\n    local order_id=$1\n    declare -g \"order_${order_id}_status\"\n    eval \"order_${order_id}_status=${order_management[PENDING]}\"\n    echo -e \"Order $order_id initialized with status PENDING\\n\"\n\n}\n\n\n\nfunction send_order {\n\n    local order_id=$1\n    local current_status_var=\"order_${order_id}_status\"\n    local current_status=${!current_status_var}\n\n    if [[ $current_status == \"${order_management[PENDING]}\" ]]; then\n        echo -e \"The order with the id $1 has been received and is ready to be shipped\\n\"\n        eval \"$current_status_var=${order_management[SENT]}\"\n        echo -e \"The order with the id $order_id has already been submitted\\n\"\n    else\n        #status=${order_management[CANCELED]}v\n        #echo -e \"The order with the id $1 has been cancelled\\n\"\n        echo -e \"The order with the id $order_id cannot be sent\\n\"\n    fi\n\n}\n    \nfunction delivered_order {\n\n    local order_id=$1\n    local current_status_var=\"order_${order_id}_status\"\n    local current_status=${!current_status_var}\n\n    if [[ $current_status == \"${order_management[SENT]}\" ]]; then\n        eval \"$current_status_var=${order_management[DELIVERED]}\"\n        echo -e \"The order with the id $1 has been delivered\\n\"\n    else\n        echo -e \"The order with the id $order_id cannot be delivered\\n\"\n    fi\n\n}\n\nfunction rejected_order {\n\n    local order_id=$1\n    local current_status_var=\"order_${order_id}_status\"\n    local current_status=${!current_status_var}\n\n    if [[ $current_status == \"${order_management[PENDING]}\" ]] || [[ $current_status == \"${order_management[SENT]}\" ]]; then\n        eval \"$current_status_var=${order_management[CANCELED]}\"\n        echo -e \"The order with the id $order_id has been cancelled\\n\"\n    else            \n        [[ $current_status == \"${order_management[DELIVERED]}\" ]]\n        echo -e \"The order with the id $order_id has been delivered and cannot be cancelled\\n\"\n    fi\n\n}\n\nfunction show_status {\n\n    local order_id=$1\n    local current_status_var=\"order_${order_id}_status\"\n    local current_status=${!current_status_var}\n\n    echo -e \"The order with id $order_id is in status $current_status\\n\"\n}\n\n\ninitialize_order 1\nshow_status 1\n\nsend_order 1\nshow_status 1\n\ndelivered_order 1\nshow_status 1\n\nrejected_order 1\nshow_status 1\n\ninitialize_order 2\nshow_status 2\nsend_order 2\nrejected_order 2\nshow_status 2\n\n       \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/c#/hequebo.cs",
    "content": "enum Days\n{\n    MONDAY = 1,\n    TUESDAY = 2,\n    WEDNESDAY = 3,\n    THURSDAY = 4,\n    FRIDAY = 5,\n    SATURDAY = 6,\n    SUNDAY = 7\n}\nenum OrderStatus\n{\n    PENDING = 1,\n    SEND = 2,\n    DELIVERED = 3,\n    CANCELLED = 4\n}\nclass Program\n{\n    static void Main(string[] args)\n    {\n        // Enumeraciones\n        PrintDay(1);\n        PrintDay(2);\n        PrintDay(3);\n        PrintDay(4);\n        PrintDay(5);\n        PrintDay(6);\n        PrintDay(7);\n\n        // Ejercicio Extra\n        Console.ReadLine();\n        Console.Clear();\n        bool salir = false;\n        List<Order> orders = new List<Order>();\n\n        do\n        {\n            Menu();\n            int opcion = 0;\n            int.TryParse(Console.ReadLine(), out opcion);\n\n            switch(opcion)\n            {\n                case 1:\n                    CheckOrders(orders);\n                    break;\n                case 2:\n                    AddOrder(ref orders);\n                    break;\n                case 3:\n                    Send(ref orders);\n                    break;\n                case 4:\n                    Deliver(ref orders);\n                    break;\n                case 5:\n                    Cancel(ref orders);\n                    break;\n                case 6:\n                    Console.Clear();\n                    Console.WriteLine(\"Hasta la próxima...\");\n                    salir = true;\n                    Thread.Sleep(1000);\n                    break;\n                default:\n                    Console.Clear();\n                    Console.WriteLine(\"Opción no válida...\");\n                    break;\n            }\n        } while (!salir);\n\n\n    }\n    static void PrintDay(int day) => \n        Console.WriteLine((Days)day);\n\n    static int id = 1;\n    static void Menu()\n    {\n        Console.WriteLine(\"---Sistema de pedidos---\");\n        Console.WriteLine(\"1.- Consultar pedidos\");\n        Console.WriteLine(\"2.- Crear nuevo pedido\");\n        Console.WriteLine(\"3.- Enviar pedido\");\n        Console.WriteLine(\"4.- Entregar pedido\");\n        Console.WriteLine(\"5.- Cancelar pedido\");\n        Console.WriteLine(\"6.- Salir\");\n        Console.WriteLine(\"Elija la opción deseada...\");\n\n    }\n    static bool CheckOrders(List<Order> orders)\n    {\n        Console.Clear();\n        if (orders.Count == 0)\n        {\n            Console.WriteLine(\"No hay pedidos registrados...\");\n            return false;\n        }\n            \n        foreach (var order in orders)\n            Console.WriteLine($\"Id: {order.Id}, Estado: {(OrderStatus)order.State}\");\n        return true;\n    }\n    static void AddOrder(ref List<Order> orders)\n    {\n        Console.Clear();\n        var order = new Order(id);\n        id++;\n        orders.Add(order);\n        Console.WriteLine(\"Pedido creado...\");\n        Console.WriteLine($\"Id: {order.Id}, Estado: {(OrderStatus)order.State}\");\n    }\n    static void Send(ref List<Order> orders)\n    {\n        Console.Clear();\n        if (!CheckOrders(orders))\n        {\n            return;\n        }\n        var result = SearchOrder(orders);\n        if (!result.Item1)\n            return;\n        var order = orders.FirstOrDefault(o => o.Id == result.Item2);\n        if (order.State == (int)OrderStatus.CANCELLED)\n        {\n            Console.WriteLine(\"El pedido ha sido cancelado, no es posible enviarlo...\");\n            return;\n        }\n        else if (order.State != (int)OrderStatus.PENDING)\n        {\n            Console.WriteLine(\"El pedido solo puede ser enviado si su estado es PENDING...\");\n            return;\n        }\n        order.State = (int)OrderStatus.SEND;\n        Console.WriteLine(\"El pedido ha sido enviado...\");\n\n\n    }\n    static void Deliver(ref List<Order> orders)\n    {\n        Console.Clear();\n        if (!CheckOrders(orders))\n        {\n            return;\n        }\n        var result = SearchOrder(orders);\n        if (!result.Item1)\n            return;\n        var order = orders.FirstOrDefault(o => o.Id == result.Item2);\n        if (order.State == (int)OrderStatus.CANCELLED)\n        {\n            Console.WriteLine(\"El pedido ha sido cancelado, no es posible entregarlo...\");\n            return;\n        }\n        else if (order.State != (int)OrderStatus.SEND)\n        {\n            Console.WriteLine(\"El pedido solo puede ser enviado si su estado es SEND...\");\n            return;\n        }\n        order.State = (int)OrderStatus.DELIVERED;\n        Console.WriteLine(\"El pedido ha sido entregado...\");\n    }\n    static void Cancel(ref List<Order> orders)\n    {\n        Console.Clear();\n        if (!CheckOrders(orders))\n        {\n            return;\n        }\n        var result = SearchOrder(orders);\n        if (!result.Item1)\n            return;\n        var order = orders.FirstOrDefault(o => o.Id == result.Item2);\n        if (order.State == (int)OrderStatus.CANCELLED)\n        {\n            Console.WriteLine(\"El pedido ya ha sido cancelado...\");\n            return;\n        }\n        else if (order.State == (int)OrderStatus.DELIVERED)\n        {\n            Console.WriteLine(\"El pedido ya ha sido entregado...\");\n            return;\n        }\n        order.State = (int)OrderStatus.CANCELLED;\n        Console.WriteLine(\"El pedido ha sido cancelado...\");\n    }\n    static (bool, int) SearchOrder(List<Order> orders)\n    {\n        Console.WriteLine(\"Ingresa Id de pedido...\");\n        int idBusqueda = 0;\n        int.TryParse(Console.ReadLine(), out idBusqueda);\n\n        if (idBusqueda == 0)\n        {\n            Console.WriteLine(\"El Id no es válido...\");\n            return (false, idBusqueda);\n        }\n        if (orders.Where(o => o.Id == idBusqueda).Count() == 0)\n        {\n            Console.WriteLine($\"El pedido con Id {idBusqueda} no existe...\");\n            return (false, idBusqueda);\n        }\n        return (true, idBusqueda);\n\n    }\n}\nclass Order\n{\n    public int Id { get; set; }\n    public int State { get; set; }\n\n    public Order(int id)\n    {\n        Id = id;\n        State = (int)OrderStatus.PENDING;\n    }\n}"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/c#/isaacus98.cs",
    "content": "﻿/*\n * EJERCICIO:\n * Empleando tu lenguaje, explora la definición del tipo de dato\n * que sirva para definir enumeraciones (Enum).\n * Crea un Enum que represente los días de la semana del lunes\n * al domingo, en ese orden. Con ese enumerado, crea una operación\n * que muestre el nombre del día de la semana dependiendo del número entero\n * utilizado (del 1 al 7).\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un pequeño sistema de gestión del estado de pedidos.\n * Implementa una clase que defina un pedido con las siguientes características:\n * - El pedido tiene un identificador y un estado.\n * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n * - Implementa las funciones que sirvan para modificar el estado:\n *   - Pedido enviado\n *   - Pedido cancelado\n *   - Pedido entregado\n *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n * - Crea diferentes pedidos y muestra cómo se interactúa con ellos. \n */\n\nnamespace Roadmap\n{\n    internal class Reto19\n    {\n        enum Semana\n        {\n            Lunes = 1,\n            Martes = 2,\n            Miercoles = 3,\n            Jueves = 4,\n            Viernes = 5,\n            Sabado = 6,\n            Domingo = 7\n        }\n\n        static void Main(string[] args)\n        {\n            Console.WriteLine(ObtenerDia(5));\n\n            // Reto extra\n            Paquete paquete1 = new(1);\n            Paquete paquete2 = new(2);\n            \n            Console.WriteLine(paquete1.ToString());\n            paquete1.CanviarEstado(Estado.Enviado);\n            Console.WriteLine(paquete1.ToString());\n            paquete1.CanviarEstado(Estado.Entregado);\n            Console.WriteLine(paquete1.ToString());\n\n            Console.WriteLine(paquete2.ToString());\n            paquete2.CanviarEstado(Estado.Entregado);\n            Console.WriteLine(paquete2.ToString());\n            paquete2.CanviarEstado (Estado.Cancelado);\n            Console.WriteLine(paquete2.ToString());\n            paquete2.CanviarEstado(Estado.Enviado);\n            Console.WriteLine(paquete2.ToString()); \n\n\n\n        }\n\n        static string ObtenerDia(int numDia)\n        {\n            return ((Semana)numDia).ToString();\n        }\n    }\n\n    public enum Estado\n    {\n        Pendiente,\n        Enviado,\n        Entregado,\n        Cancelado\n    }\n\n    public class Paquete\n    {\n        private int Id;\n        private Estado Estado;\n\n        public Paquete(int id, Estado estado = Estado.Pendiente)\n        {\n            Id = id;\n            Estado = estado;\n        }\n\n        public void CanviarEstado(Estado estado)\n        {\n            if ((Estado == Estado.Pendiente & estado == Estado.Enviado) | (Estado == Estado.Enviado & estado == Estado.Entregado) | (Estado == Estado.Pendiente & estado == Estado.Cancelado))\n                Estado = estado;\n            else\n                Console.WriteLine($\"No se puede canviar el estado de {Estado} a {estado} del paquete {Id}\");\n\n        }\n\n        public override string ToString()\n        {\n            return $\"El paquete {Id} tiene el estado {Estado}\";\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/c#/jamerrq.cs",
    "content": "﻿/*\r\n * EJERCICIO:\r\n * Empleando tu lenguaje, explora la definición del tipo de dato\r\n * que sirva para definir enumeraciones (Enum).\r\n * Crea un Enum que represente los días de la semana del lunes\r\n * al domingo, en ese orden. Con ese enumerado, crea una operación\r\n * que muestre el nombre del día de la semana dependiendo del número entero\r\n * utilizado (del 1 al 7).\r\n *\r\n * DIFICULTAD EXTRA (opcional):\r\n * Crea un pequeño sistema de gestión del estado de pedidos.\r\n * Implementa una clase que defina un pedido con las siguientes características:\r\n * - El pedido tiene un identificador y un estado.\r\n * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\r\n * - Implementa las funciones que sirvan para modificar el estado:\r\n *   - Pedido enviado\r\n *   - Pedido cancelado\r\n *   - Pedido entregado\r\n *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\r\n * - Implementa una función para mostrar un texto descriptivo según el estado actual.\r\n * - Crea diferentes pedidos y muestra cómo se interactúa con ellos.\r\n */\r\n\r\nusing System;\r\n\r\nnamespace Roadmap19\r\n{\r\n    class Enumerations\r\n    {\r\n        public enum DaysOfWeek\r\n        {\r\n            Monday = 1,\r\n            Tuesday,\r\n            Wednesday,\r\n            Thursday,\r\n            Friday,\r\n            Saturday,\r\n            Sunday\r\n        }\r\n\r\n        public static void ShowDay(int day)\r\n        {\r\n            if (day < 1 || day > 7)\r\n            {\r\n                Console.WriteLine(\"Invalid day\");\r\n                return;\r\n            }\r\n\r\n            DaysOfWeek dayOfWeek = (DaysOfWeek)day;\r\n            Console.WriteLine(dayOfWeek);\r\n        }\r\n\r\n        public enum OrderStatus\r\n        {\r\n            PENDING,\r\n            SENT,\r\n            DELIVERED,\r\n            CANCELED\r\n        }\r\n\r\n        public class Order\r\n        {\r\n            public int Id { get; set; }\r\n            public OrderStatus Status { get; set; }\r\n\r\n            public Order(int id)\r\n            {\r\n                Id = id;\r\n                Status = OrderStatus.PENDING;\r\n            }\r\n\r\n            public void Send()\r\n            {\r\n                if (Status == OrderStatus.PENDING)\r\n                {\r\n                    Status = OrderStatus.SENT;\r\n                }\r\n                else\r\n                {\r\n                    Console.WriteLine(\"Order already sent\");\r\n                }\r\n            }\r\n\r\n            public void Deliver()\r\n            {\r\n                if (Status == OrderStatus.SENT)\r\n                {\r\n                    Status = OrderStatus.DELIVERED;\r\n                }\r\n                else\r\n                {\r\n                    Console.WriteLine(\"Order must be sent first\");\r\n                }\r\n            }\r\n\r\n            public void Cancel()\r\n            {\r\n                if (Status == OrderStatus.PENDING)\r\n                {\r\n                    Status = OrderStatus.CANCELED;\r\n                }\r\n                else\r\n                {\r\n                    Console.WriteLine(\"Order cannot be canceled\");\r\n                }\r\n            }\r\n\r\n            public void ShowStatus()\r\n            {\r\n                Console.WriteLine($\"Order {Id} is {Status}\");\r\n            }\r\n        }\r\n\r\n        public static void Main(string[] args)\r\n        {\r\n            ShowDay(1);\r\n            ShowDay(7);\r\n            ShowDay(8);\r\n\r\n            Order order1 = new Order(1);\r\n            order1.ShowStatus();\r\n            order1.Send();\r\n            order1.ShowStatus();\r\n            order1.Send();\r\n            order1.Deliver();\r\n            order1.ShowStatus();\r\n\r\n            Order order2 = new Order(2);\r\n            order2.ShowStatus();\r\n            order2.Send();\r\n            order2.Deliver();\r\n            order2.ShowStatus();\r\n            order2.Cancel();\r\n            order2.ShowStatus();\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/c#/kenysdev.cs",
    "content": "/*\n╔══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado               ║\n║ GitHub: https://github.com/Kenysdev  ║\n║ 2024 -  C#                           ║\n╚══════════════════════════════════════╝\n------------------------------------------\n* ENUMERACIONES\n------------------------------------------\nhttps://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/enum\nhttps://learn.microsoft.com/es-es/dotnet/api/system.enum?view=net-8.0\n*/\n\n#pragma warning disable CA1050\nclass Program {\n/*\n* EJERCICIO 1:\n* Empleando tu lenguaje, explora la definición del tipo de dato\n* que sirva para definir enumeraciones (Enum).\n* Crea un Enum que represente los días de la semana del lunes\n* al domingo, en ese orden. Con ese enumerado, crea una operación\n* que muestre el nombre del día de la semana dependiendo del número entero\n* utilizado (del 1 al 7).\n*/\n    enum Weekday {\n        MONDAY = 1,\n        TUESDAY = 2,\n        WEDNESDAY = 3,\n        THURSDAY = 4,\n        FRIDAY = 5,\n        SATURDAY = 6,\n        SUNDAY = 7\n    }\n\n    static string GetDay(int num) {\n        return Enum.GetName(typeof(Weekday), num) ?? \"'o'\";\n    }\n\n    static int GetNumDay(string day) {\n        return Enum.TryParse(day, out Weekday weekday) ? (int)weekday : 0;\n    }\n\n/*\n* EJERCICIO 2:\n* Crea un pequeño sistema de gestión del estado de pedidos.\n* Implementa una clase que defina un pedido con las siguientes características:\n* - El pedido tiene un identificador y un estado.\n* - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n* - Implementa las funciones que sirvan para modificar el estado:\n*   - Pedido enviado\n*   - Pedido cancelado\n*   - Pedido entregado\n*   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n* - Implementa una función para mostrar un texto descriptivo según el estado actual.\n* - Crea diferentes pedidos y muestra cómo se interactúa con ellos. \n*/\n    enum Status {\n        PENDING,\n        SHIPPED,\n        DELIVERED,\n        CANCELED\n    }\n\n    class Order(string identifier) {\n        Status _status = Status.PENDING;\n\n        public void Send() {\n            Console.WriteLine(\"\\nEnviar:\");\n            if (_status == Status.PENDING) {\n                _status = Status.SHIPPED;\n                Console.WriteLine(Info());\n            } else {\n                Console.WriteLine($\"invalid operation, {Info()}\");\n            }\n        }\n\n        public void Cancelled() {\n            Console.WriteLine(\"\\nCancelar:\");\n            if (_status == Status.PENDING) {\n                _status = Status.CANCELED;\n                Console.WriteLine(Info());\n            } else {\n                Console.WriteLine($\"invalid operation, {Info()}\");\n            }\n        }\n\n        public void Delivered() {\n            Console.WriteLine(\"\\nEntregar:\");\n            if (_status == Status.SHIPPED) {\n                _status = Status.DELIVERED;\n                Console.WriteLine(Info());\n            } else {\n                Console.WriteLine($\"invalid operation, {Info()}\");\n            }\n        }\n\n        public string Info() {\n            return $\"{identifier} is {_status}\";\n        }\n    }\n\n\n    static void Main() {\n        // _____________________________________\n        Console.WriteLine(GetDay(7));\n        Console.WriteLine(GetDay(3));\n        Console.WriteLine(GetDay(8));\n\n        Console.WriteLine(GetNumDay(\"TUESDAY\"));\n        Console.WriteLine(GetNumDay(\"FRIDAY\"));\n        Console.WriteLine(GetNumDay(\"abc\"));\n\n        // _____________________________________\n        // Creación de pedidos\n        Order libro1 = new(\"libro1\");\n        Order libro2 = new(\"libro2\");\n        Order libro3 = new(\"libro3\");\n\n        // Positivas\n        Console.WriteLine(\"\\n-----\\nOperaciones exitosas:\\n-----\");\n        libro1.Send();\n        libro1.Delivered();\n        libro2.Cancelled();\n\n        // Negativas\n        Console.WriteLine(\"\\n-----\\nOperaciones inválidas:\\n-----\");\n        libro3.Delivered();\n        libro2.Cancelled();\n        libro1.Send();\n\n        // Info\n        Console.WriteLine(\"\\n-----\\nEstado de órdenes\\n-----\");\n        Console.WriteLine(libro1.Info());\n        Console.WriteLine(libro2.Info());\n        Console.WriteLine(libro3.Info());\n    }\n}\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/c++/hectorio23.cpp",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n#include <iostream>\n#include <string>\n\n/*\n * EJERCICIO:\n * Empleando tu lenguaje, explora la definición del tipo de dato\n * que sirva para definir enumeraciones (Enum).\n * Crea un Enum que represente los días de la semana del lunes\n * al domingo, en ese orden. Con ese enumerado, crea una operación\n * que muestre el nombre del día de la semana dependiendo del número entero\n * utilizado (del 1 al 7).\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un pequeño sistema de gestión del estado de pedidos.\n * Implementa una clase que defina un pedido con las siguientes características:\n * - El pedido tiene un identificador y un estado.\n * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n * - Implementa las funciones que sirvan para modificar el estado:\n *   - Pedido enviado\n *   - Pedido cancelado\n *   - Pedido entregado\n *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n * - Crea diferentes pedidos y muestra cómo se interactúa con ellos. \n*/\n\n\n// Definición del enum para los días de la semana\n// Usamos enum class para tener un mejor manejo de ámbitos\nenum class DiaSemana { \n    Lunes = 1,\n    Martes,\n    Miercoles,\n    Jueves,\n    Viernes,\n    Sabado,\n    Domingo\n};\n\n// Función para obtener el nombre del día de la semana a partir del número\nstd::string obtenerNombreDiaSemana(int numeroDia) {\n    switch(numeroDia) {\n        case static_cast<int>(DiaSemana::Lunes):\n            return \"Lunes\";\n        case static_cast<int>(DiaSemana::Martes):\n            return \"Martes\";\n        case static_cast<int>(DiaSemana::Miercoles):\n            return \"Miércoles\";\n        case static_cast<int>(DiaSemana::Jueves):\n            return \"Jueves\";\n        case static_cast<int>(DiaSemana::Viernes):\n            return \"Viernes\";\n        case static_cast<int>(DiaSemana::Sabado):\n            return \"Sábado\";\n        case static_cast<int>(DiaSemana::Domingo):\n            return \"Domingo\";\n        default:\n            return \"Número de día inválido\";\n    }\n}\n\n// Definición del Enum para los estados de pedido\nenum class EstadoPedido {\n    PENDIENTE,\n    ENVIADO,\n    ENTREGADO,\n    CANCELADO\n};\n\n// Clase Pedido\nclass Pedido {\nprivate:\n    int id;\n    EstadoPedido estado;\n\npublic:\n    // Constructor\n    Pedido(int _id) : id(_id), estado(EstadoPedido::PENDIENTE) {}\n\n    // Función para marcar el pedido como enviado\n    void marcarEnviado() {\n        if (estado == EstadoPedido::PENDIENTE) {\n            estado = EstadoPedido::ENVIADO;\n            std::cout << \"El pedido con ID \" << id << \" ha sido enviado.\\n\";\n        } else {\n            std::cout << \"El pedido con ID \" << id << \" no se puede enviar en su estado actual.\\n\";\n        }\n    }\n\n    // Función para marcar el pedido como entregado\n    void marcarEntregado() {\n        if (estado == EstadoPedido::ENVIADO) {\n            estado = EstadoPedido::ENTREGADO;\n            std::cout << \"El pedido con ID \" << id << \" ha sido entregado.\\n\";\n        } else {\n            std::cout << \"El pedido con ID \" << id << \" no se puede entregar en su estado actual.\\n\";\n        }\n    }\n\n    // Función para cancelar el pedido\n    void cancelarPedido() {\n        if (estado != EstadoPedido::CANCELADO) {\n            estado = EstadoPedido::CANCELADO;\n            std::cout << \"El pedido con ID \" << id << \" ha sido cancelado.\\n\";\n        } else {\n            std::cout << \"El pedido con ID \" << id << \" ya está cancelado.\\n\";\n        }\n    }\n\n    // Función para mostrar el estado del pedido\n    void mostrarEstado() {\n        std::string estado_str;\n        switch(estado) {\n            case EstadoPedido::PENDIENTE:\n                estado_str = \"Pendiente\";\n                break;\n            case EstadoPedido::ENVIADO:\n                estado_str = \"Enviado\";\n                break;\n            case EstadoPedido::ENTREGADO:\n                estado_str = \"Entregado\";\n                break;\n            case EstadoPedido::CANCELADO:\n                estado_str = \"Cancelado\";\n                break;\n        }\n        std::cout << \"Estado del pedido con ID \" << id << \": \" << estado_str << \"\\n\";\n    }\n};\n\nint main() {\n\n    std::cout << \"******** EJERCICIO ********\\n\";\n    int numeroDia;\n\n    std::cout << \"Ingrese un número de día de la semana (del 1 al 7): \";\n    std::cin >> numeroDia;\n\n    // Mostrar el nombre del día de la semana correspondiente\n    std::cout << \"El día de la semana es: \" << obtenerNombreDiaSemana(numeroDia) << \"\\n\";\n\n\n    std::cout << \"\\n********** EJERCICIO EXTRA **********\\n\";\n    // Crear pedidos\n    Pedido pedido1(1);\n    Pedido pedido2(2);\n\n    // Mostrar el estado inicial de los pedidos\n    pedido1.mostrarEstado();\n    pedido2.mostrarEstado();\n\n    // Interactuar con los pedidos\n    pedido1.marcarEnviado();\n    pedido2.marcarEnviado();\n    pedido1.marcarEntregado();\n    pedido2.cancelarPedido();\n\n    // Mostrar el estado final de los pedidos\n    pedido1.mostrarEstado();\n    pedido2.mostrarEstado();\n\n    return 0;\n}"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/ejercicio.md",
    "content": "# #19 ENUMERACIONES\n> #### Dificultad: Media | Publicación: 06/05/24 | Corrección: 13/05/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Empleando tu lenguaje, explora la definición del tipo de dato\n * que sirva para definir enumeraciones (Enum).\n * Crea un Enum que represente los días de la semana del lunes\n * al domingo, en ese orden. Con ese enumerado, crea una operación\n * que muestre el nombre del día de la semana dependiendo del número entero\n * utilizado (del 1 al 7).\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un pequeño sistema de gestión del estado de pedidos.\n * Implementa una clase que defina un pedido con las siguientes características:\n * - El pedido tiene un identificador y un estado.\n * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n * - Implementa las funciones que sirvan para modificar el estado:\n *   - Pedido enviado\n *   - Pedido cancelado\n *   - Pedido entregado\n *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n * - Crea diferentes pedidos y muestra cómo se interactúa con ellos. \n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/go/DaFi02.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n)\n\ntype Week_day int\n\nconst (\n\tMonday Week_day = iota + 1\n\tTuesday\n\tWednesday\n\tThursday\n\tFriday\n\tSaturday\n\tSunday\n)\n\n// this function returns the name of the day of the week, and is metod of the type Week_day\nfunc (day Week_day) string() string {\n\tswitch day {\n\tcase Monday:\n\t\treturn \"Monday\"\n\tcase Tuesday:\n\t\treturn \"Tuesday\"\n\tcase Wednesday:\n\t\treturn \"Wednesday\"\n\tcase Thursday:\n\t\treturn \"Thursday\"\n\tcase Friday:\n\t\treturn \"Friday\"\n\tcase Saturday:\n\t\treturn \"Saturday\"\n\tcase Sunday:\n\t\treturn \"Sunday\"\n\tdefault:\n\t\treturn \"Invalid day\"\n\t}\n}\n\nfunc getDayOfWeek(dayNumber int) string {\n\tday := Week_day(dayNumber)\n\treturn day.string()\n}\n\n/*\n\tExtra Dificult\n*/\n\ntype Order struct {\n\tid    int\n\tstate Status_Product\n}\n\ntype Status_Product int\n\nconst (\n\tPending Status_Product = iota\n\tEnvoy\n\tReceived\n\tCanceled\n)\n\nfunc (state Status_Product) string() string {\n\tswitch state {\n\tcase Pending:\n\t\treturn \"Pending\"\n\tcase Envoy:\n\t\treturn \"Envoy\"\n\tcase Received:\n\t\treturn \"Received\"\n\tcase Canceled:\n\t\treturn \"Canceled\"\n\tdefault:\n\t\treturn \"Invalid state\"\n\t}\n}\n\nfunc chageStatus(order *Order, newState Status_Product) string {\n\tif newState == Received && order.state != Envoy {\n\t\treturn fmt.Sprintf(\"Invalid state for order %d, the order is not envoy\\n\", order.id)\n\t}\n\n\tif newState == Canceled && order.state == Received {\n\t\treturn fmt.Sprintf(\"Invalid state for order %d, the order is already received\\n\", order.id)\n\t}\n\n\tif newState == Canceled && order.state == Pending {\n\t\torder.state = Canceled\n\t\treturn order.state.string()\n\t}\n\n\tif newState == Canceled && order.state == Envoy {\n\t\treturn fmt.Sprintf(\"Invalid state for order %d, the order is already envoy\\n\", order.id)\n\t}\n\n\tif order.state == Canceled {\n\t\treturn fmt.Sprintf(\"Invalid state for order %d, the order is already canceled\\n\", order.id)\n\n\t}\n\n\torder.state = newState\n\treturn fmt.Sprintf(\"The order %d is now %s\\n\", order.id, order.state.string())\n}\n\nfunc (order *Order) print() {\n\tfmt.Println(\" ---------------------------------- \")\n\tfmt.Println(\"Order ID: \", order.id, \" - \", order.state.string())\n}\n\nfunc main() {\n\t// The function getDayOfWeek() returns the day of the week corresponding to the number passed as an argument\n\tfmt.Println(getDayOfWeek(1)) // print \"Monday\"\n\tfmt.Println(getDayOfWeek(7)) // Print \"Sunday\"\n\n\t/*\n\t\tExtra Dificult\n\t*/\n\n\t// Remember\n\t// Pending = 0\n\t// Envoy = 1\n\t// Received = 2\n\t// Canceled = 3\n\t// Create a product with the status \"Pending\"\n\torder_1 := Order{id: 1, state: Pending}\n\torder_2 := Order{id: 2, state: Envoy}\n\torder_3 := Order{id: 3, state: Received}\n\torder_4 := Order{id: 4, state: Canceled}\n\torder_5 := Order{id: 5, state: Envoy}\n\n\tfmt.Println(\"Initial status\")\n\torder_1.print()\n\torder_2.print()\n\torder_3.print()\n\torder_4.print()\n\torder_5.print()\n\n\tfmt.Println(\"\")\n\tfmt.Println(\"Change Status of the orders\")\n\n\tfmt.Print(chageStatus(&order_1, Received))\n\tfmt.Print(chageStatus(&order_2, Canceled))\n\tfmt.Print(chageStatus(&order_3, Canceled))\n\tfmt.Print(chageStatus(&order_4, Envoy))\n\tfmt.Print(chageStatus(&order_5, Received))\n\tfmt.Print(chageStatus(&order_1, Envoy))\n\n\tfmt.Println(\"\")\n\tfmt.Println(\"Final status\")\n\n\torder_1.print()\n\torder_2.print()\n\torder_3.print()\n\torder_4.print()\n\n\tfmt.Println(\" \")\n\tfmt.Println(\"Additional changes\")\n\tfmt.Print(chageStatus(&order_2, Received))\n\tfmt.Print(chageStatus(&order_1, Received))\n\n\tfmt.Println(\" \")\n\tfmt.Println(\"Final status\")\n\torder_1.print()\n\torder_2.print()\n\n\t// The function chageStatus() changes the status of the order, and returns the new status\n\n}\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/go/MiguelP-Dev.go",
    "content": "package main\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"slices\"\n)\n\n// Tarea exploratorio:\nconst (\n\temptyDay = iota\n\tday1\n\tday2\n\tday3\n\tday4\n\tday5\n\tday6\n\tday7\n)\n\nfunc ViewDay(dayNumber int) string {\n\tif dayNumber <= 0 || dayNumber > 7 {\n\t\terrornumber := errors.New(\"Error: The number must be greater than '0' and less than '8'\")\n\t\treturn errornumber.Error()\n\t}\n\tDays := [...]string{\"\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\", \"Sunday\"}\n\treturn Days[dayNumber]\n}\n\n// Extra\nconst (\n\tStatusPending   = iota // 0\n\tStatusShipped          // 1\n\tStatusDelivered        // 2\n\tStatusCancelled        // 3\n)\n\nvar StatusOptions = fmt.Sprintf(\"0 for Pending\\n 1 for Shipped\\n 2 for Delivered\\n 3 for Cancelled\\n\")\n\nvar statusStrings = [...]string{\"Pending\", \"Shipped\", \"Delivered\", \"Cancelled\"}\n\nfunc getStatusString(status int) string {\n\tif status < 0 || status >= len(statusStrings) {\n\t\treturn \"Unknown\"\n\t}\n\treturn statusStrings[status]\n}\n\ntype OrdersManager struct {\n\tOrders map[int](string)\n\tid     int\n\tstate  string\n}\n\nfunc NewOrdesManager() OrdersManager {\n\treturn OrdersManager{\n\t\tOrders: make(map[int]string),\n\t\tid:     0,\n\t\tstate:  \"\",\n\t}\n}\n\nfunc (om *OrdersManager) searchNextID() int {\n\tif len(om.Orders) == 0 {\n\t\treturn 1\n\t}\n\n\treturn len(om.Orders) + 1\n}\n\nfunc (om *OrdersManager) RegisterOrder() {\n\tlastid := om.searchNextID()\n\n\tif st := getStatusString(StatusPending); st == \"Unknown\" {\n\t\tfmt.Println(\"RegisterOrder(): Impossible register that status\")\n\t\treturn\n\t}\n\n\tom.Orders[lastid] = getStatusString(StatusPending)\n}\n\nfunc (om *OrdersManager) verifyStatus(id, newStatus int) bool {\n\tactualStatus := om.Orders[id]\n\tstatus := getStatusString(newStatus)\n\tcancelled := getStatusString(StatusCancelled)\n\tdelivered := getStatusString(StatusDelivered)\n\tpending := getStatusString(StatusPending)\n\tshipped := getStatusString(StatusShipped)\n\n\tif actualStatus == pending && (status == shipped || status == cancelled) {\n\t\treturn true\n\t} else if actualStatus == shipped && status == delivered {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\nfunc (om *OrdersManager) ChangeStatus(id, newStatus int) {\n\tif len(om.Orders) == 0 {\n\t\tfmt.Println(\"ChangeStatus(): The Orders registry is empty\")\n\t\treturn\n\t}\n\n\tidlist := []int{}\n\tfor oid, _ := range om.Orders {\n\t\tidlist = append(idlist, oid)\n\t}\n\n\tif !slices.Contains(idlist, id) {\n\t\tfmt.Println(\"ChangeStatus(): the id of the entered order does not exist in the registry\")\n\t\treturn\n\t}\n\n\tif om.verifyStatus(id, newStatus) {\n\t\tom.Orders[id] = getStatusString(newStatus)\n\t\tfmt.Printf(\"ChangeStatus(): The status has been changed to: %s\\n\", om.Orders[id])\n\t\treturn\n\t}\n\n\tfmt.Println(\"ChangeStatus(): The status can not be changed\")\n\treturn\n}\n\nfunc (om *OrdersManager) ViewAllOrders() {\n\tfor id, order := range om.Orders {\n\t\tfmt.Printf(\"Order ID: %d, Order Status: %s\\n\", id, order)\n\t}\n}\nfunc (om *OrdersManager) OrderStatus() {\n\tvar pending int\n\tvar cancelled int\n\tvar delivered int\n\tvar shipped int\n\n\tfor _, orderStatus := range om.Orders {\n\t\tswitch orderStatus {\n\t\tcase \"Delivered\":\n\t\t\tdelivered += 1\n\t\tcase \"Pending\":\n\t\t\tpending += 1\n\t\tcase \"Shipped\":\n\t\t\tshipped += 1\n\t\tcase \"Cancelled\":\n\t\t\tcancelled += 1\n\t\tdefault:\n\t\t\tcontinue\n\t\t}\n\t}\n\n\tif pending > 0 {\n\t\tfmt.Printf(\"NumberOfOrders: %d\\n Status: 📦 Pending, Description: Your order is confirmed and being prepared for shipment. We’re working to get it to you soon!\\n\", pending)\n\t}\n\n\tif shipped > 0 {\n\t\tfmt.Printf(\"NumberOfOrders: %d\\n Status: 🚚 Shipped, Description: Your order is on the way! Track your package using the link provided in your email.\\n\", shipped)\n\t}\n\n\tif delivered > 0 {\n\t\tfmt.Printf(\"NumberOfOrders: %d\\n Status: ✅ Delivered, Description: Your order has arrived! Enjoy your purchase, and thank you for choosing us.\\n\", delivered)\n\t}\n\n\tif cancelled > 0 {\n\t\tfmt.Printf(\"NumberOfOrders: %d\\n Status: ❌ Canceled, Description: This order has been canceled and will not be processed further.\\n\", cancelled)\n\t}\n}\n\nfunc main() {\n\t// Tarea exploratoria: Pansando número y luego constantes\n\tfmt.Printf(\"ViewDay(0): %v\\n\", ViewDay(0))\n\tfmt.Printf(\"ViewDay(1): %v\\n\", ViewDay(1))\n\tfmt.Printf(\"ViewDay(2): %v\\n\", ViewDay(2))\n\tfmt.Printf(\"ViewDay(3): %v\\n\", ViewDay(3))\n\tfmt.Printf(\"ViewDay(4): %v\\n\", ViewDay(4))\n\tfmt.Printf(\"ViewDay(5): %v\\n\", ViewDay(5))\n\tfmt.Printf(\"ViewDay(6): %v\\n\", ViewDay(6))\n\tfmt.Printf(\"ViewDay(7): %v\\n\", ViewDay(7))\n\tfmt.Printf(\"ViewDay(8): %v\\n\", ViewDay(8))\n\n\tfmt.Printf(\"ViewDay(day1): %v\\n\", ViewDay(day1))\n\tfmt.Printf(\"ViewDay(day2): %v\\n\", ViewDay(day2))\n\tfmt.Printf(\"ViewDay(day3): %v\\n\", ViewDay(day3))\n\tfmt.Printf(\"ViewDay(day4): %v\\n\", ViewDay(day4))\n\tfmt.Printf(\"ViewDay(day5): %v\\n\", ViewDay(day5))\n\tfmt.Printf(\"ViewDay(day6): %v\\n\", ViewDay(day6))\n\tfmt.Printf(\"ViewDay(day7): %v\\n\", ViewDay(day7))\n\tfmt.Printf(\"ViewDay(emptyDay): %v\\n\", ViewDay(emptyDay))\n\n\t// Extra\n\tmanager := NewOrdesManager()\n\tfor {\n\t\tvar option int\n\t\tfmt.Printf(\"Option 1: Register Orders \\n Option 2: Change status \\n Option 3: See All commands\\n Option 4: See States of orders \\n Option 5: Exit \\n\")\n\t\tfmt.Scan(&option)\n\t\tswitch option {\n\t\tcase 1:\n\t\t\tmanager.RegisterOrder()\n\t\tcase 2:\n\t\t\tfmt.Println(\"Enter the orderId:\")\n\t\t\tvar id int\n\t\t\tfmt.Scan(&id)\n\t\t\tfmt.Println(\"Enter the new Status from options:\")\n\t\t\tfmt.Println(StatusOptions)\n\t\t\tvar status int\n\t\t\tfmt.Scan(&status)\n\t\t\tmanager.ChangeStatus(id, status)\n\t\tcase 3:\n\t\t\tmanager.ViewAllOrders()\n\t\tcase 4:\n\t\t\tmanager.OrderStatus()\n\t\tcase 5:\n\t\t\treturn\n\t\tdefault:\n\t\t\tcontinue\n\t\t}\n\t}\n\n}\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/go/N0HagoNada.go",
    "content": "package main\n\nimport \"fmt\"\n\ntype DayOfWeek int\n\nconst (\n\tLundi DayOfWeek = iota\n\tMardi\n\tMercredi\n\tJeudi\n\tVendredi\n\tSamedi\n\tDimanche\n)\n\nfunc main() {\n\tfmt.Println(\"Ingrese un número del 1 al 7 para obtener el día de la semana correspondiente:\")\n\tvar numero int\n\tfmt.Scanln(&numero)\n\n\tdia := obtenerDia(DayOfWeek(numero))\n\tif dia != \"\" {\n\t\tfmt.Printf(\"El número %d corresponde al día %s\\n\", numero, dia)\n\t} else {\n\t\tfmt.Println(\"Número no válido. Debe estar entre 1 y 7.\")\n\t}\n}\n\n// Función que devuelve el nombre del día correspondiente al número\nfunc obtenerDia(d DayOfWeek) string {\n\tswitch d {\n\tcase Lundi:\n\t\treturn \"Lundi\"\n\tcase Mardi:\n\t\treturn \"Mardi\"\n\tcase Mercredi:\n\t\treturn \"Mercredi\"\n\tcase Jeudi:\n\t\treturn \"Jeudi\"\n\tcase Vendredi:\n\t\treturn \"Vendredi\"\n\tcase Samedi:\n\t\treturn \"Samedi\"\n\tcase Dimanche:\n\t\treturn \"Dimanche\"\n\tdefault:\n\t\treturn \"\"\n\t}\n}\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/go/hozlucas28.go",
    "content": "package main\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"strings\"\n)\n\n/* -------------------------------------------------------------------------- */\n/*                               WEEKDAYS (ENUM)                              */\n/* -------------------------------------------------------------------------- */\n\ntype Weekday int\n\nfunc (weekday *Weekday) ToString() string {\n\tswitch *weekday {\n\tcase monday:\n\t\treturn \"Monday\"\n\tcase tuesday:\n\t\treturn \"Tuesday\"\n\tcase wednesday:\n\t\treturn \"Wednesday\"\n\tcase thursday:\n\t\treturn \"Thursday\"\n\tcase friday:\n\t\treturn \"Friday\"\n\tcase saturday:\n\t\treturn \"Saturday\"\n\tdefault:\n\t\treturn \"Sunday\"\n\t}\n}\n\ntype weekDays struct {\n\tMonday    Weekday\n\tTuesday   Weekday\n\tWednesday Weekday\n\tThursday  Weekday\n\tFriday    Weekday\n\tSaturday  Weekday\n\tSunday    Weekday\n}\n\nconst (\n\tmonday Weekday = iota\n\ttuesday\n\twednesday\n\tthursday\n\tfriday\n\tsaturday\n\tsunday\n)\n\nvar WeekDays weekDays = weekDays{\n\tMonday:    monday,\n\tTuesday:   tuesday,\n\tWednesday: wednesday,\n\tThursday:  thursday,\n\tFriday:    friday,\n\tSaturday:  saturday,\n\tSunday:    sunday,\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                STATES (ENUM)                               */\n/* -------------------------------------------------------------------------- */\n\ntype State int\n\nfunc (state *State) ToString() string {\n\tswitch *state {\n\tcase earring:\n\t\treturn \"Earring\"\n\tcase sent:\n\t\treturn \"Sent\"\n\tcase delivered:\n\t\treturn \"Delivered\"\n\tdefault:\n\t\treturn \"Cancelled\"\n\t}\n}\n\ntype states struct {\n\tEarring   State\n\tSent      State\n\tDelivered State\n\tCancelled State\n}\n\nconst (\n\tearring State = iota\n\tsent\n\tdelivered\n\tcancelled\n)\n\nvar States states = states{\n\tEarring:   earring,\n\tSent:      sent,\n\tDelivered: delivered,\n\tCancelled: cancelled,\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                ORDER (CLASS)                               */\n/* -------------------------------------------------------------------------- */\n\ntype order struct {\n\tid    int\n\tstate State\n}\n\nfunc NewOrder(id int, state State) *order {\n\tvar order order = order{id: id, state: state}\n\treturn &order\n}\n\nfunc (order *order) GetId() int {\n\treturn order.id\n}\n\nfunc (order *order) GetState() State {\n\treturn order.state\n}\n\nfunc (order *order) Cancel() error {\n\tif order.state == States.Earring {\n\t\torder.state = States.Cancelled\n\t\treturn nil\n\t}\n\n\tvar errorMessage string = fmt.Sprintf(\"The order with %d id can't be cancelled\", order.id)\n\treturn errors.New(errorMessage)\n}\n\nfunc (order *order) Deliver() error {\n\tif order.state == States.Sent {\n\t\torder.state = States.Delivered\n\t\treturn nil\n\t}\n\n\tvar errorMessage string = fmt.Sprintf(\"The order with %d id can't be delivered\", order.id)\n\treturn errors.New(errorMessage)\n}\n\nfunc (order *order) PrintState() *order {\n\tvar loweredOrderState string = strings.ToLower(order.state.ToString())\n\tfmt.Printf(\"The order with %d id was %s\\n\", order.id, loweredOrderState)\n\treturn order\n}\n\nfunc (order *order) Send() error {\n\tif order.state == States.Earring {\n\t\torder.state = States.Sent\n\t\treturn nil\n\t}\n\n\tvar errorMessage string = fmt.Sprintf(\"The order with %d id can't be sent\", order.id)\n\treturn errors.New(errorMessage)\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\nfunc main() {\n\t/*\n\t\tEnums...\n\t*/\n\n\tfmt.Println(\"Enums...\")\n\n\tfmt.Printf(\"\\nName of the first week day: %s\\n\", WeekDays.Monday.ToString())\n\tfmt.Printf(\"Name of the second week day: %s\\n\", WeekDays.Tuesday.ToString())\n\tfmt.Printf(\"Name of the third week day: %s\\n\", WeekDays.Wednesday.ToString())\n\tfmt.Printf(\"Name of the fourth week day: %s\\n\", WeekDays.Thursday.ToString())\n\tfmt.Printf(\"Name of the fifth week day: %s\\n\", WeekDays.Friday.ToString())\n\tfmt.Printf(\"Name of the sixth week day: %s\\n\", WeekDays.Saturday.ToString())\n\tfmt.Printf(\"Name of the seventh week day: %s\\n\", WeekDays.Sunday.ToString())\n\n\tfmt.Println(\"\\n# ---------------------------------------------------------------------------------- #\")\n\n\t/*\n\t\tAdditional challenge...\n\t*/\n\n\tfmt.Println(\"\\nAdditional challenge...\")\n\n\tvar firstOrder *order = NewOrder(1, States.Earring)\n\tvar secondOrder *order = NewOrder(2, States.Sent)\n\tvar thirdOrder *order = NewOrder(3, States.Delivered)\n\tvar fourthOrder *order = NewOrder(4, States.Cancelled)\n\n\tfmt.Println()\n\tfirstOrder.PrintState()\n\tsecondOrder.PrintState()\n\tthirdOrder.PrintState()\n\tfourthOrder.PrintState()\n\n\tfirstOrder.Send()\n\tfirstOrder.Deliver()\n\n\tfmt.Println()\n\tfirstOrder.PrintState()\n\n\tfmt.Println()\n\tsendError := secondOrder.Send()\n\tif sendError != nil {\n\t\tfmt.Println(sendError)\n\t}\n\n\tvar deliveredError error = thirdOrder.Deliver()\n\tif deliveredError != nil {\n\t\tfmt.Println(deliveredError)\n\t}\n\n\tsendError = fourthOrder.Send()\n\tif sendError != nil {\n\t\tfmt.Println(sendError)\n\t}\n}"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/go/kodenook.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc main() {\n\tconst (\n\t\tmonday int = iota\n\t\ttuesday\n\t\twednesday\n\t\tthursday\n\t\tfriday\n\t\tsaturday\n\t\tsunday\n\t)\n\n\tday := 6\n\n\tswitch day {\n\tcase monday:\n\t\tfmt.Println(\"Monday\")\n\tcase tuesday:\n\t\tfmt.Println(\"Tuesday\")\n\tcase wednesday:\n\t\tfmt.Println(\"Wednesday\")\n\tcase thursday:\n\t\tfmt.Println(\"Thursday\")\n\tcase friday:\n\t\tfmt.Println(\"Friday\")\n\tcase saturday:\n\t\tfmt.Println(\"Saturday\")\n\tcase sunday:\n\t\tfmt.Println(\"Sunday\")\n\t}\n}\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/go/qwik-zgheib.go",
    "content": "package main\n\nimport \"fmt\"\n\ntype DayOfWeek int\n\nconst (\n\tMonday DayOfWeek = iota + 1\n\tTuesday\n\tWednesday\n\tThursday\n\tFriday\n\tSaturday\n\tSunday\n)\n\nfunc (d DayOfWeek) String() string {\n\treturn [...]string{\"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\", \"Sunday\"}[d-1]\n}\n\ntype OrderStatus int\n\nconst (\n\tPending OrderStatus = iota\n\tShipped\n\tDelivered\n\tCanceled\n)\n\nfunc (os OrderStatus) String() string {\n\treturn [...]string{\"Pending\", \"Shipped\", \"Delivered\", \"Canceled\"}[os]\n}\n\ntype Order struct {\n\tID     int\n\tStatus OrderStatus\n}\n\nfunc NewOrder(id int) *Order {\n\treturn &Order{\n\t\tID:     id,\n\t\tStatus: Pending,\n\t}\n}\n\nfunc (o *Order) Send() error {\n\tif o.Status != Pending {\n\t\treturn fmt.Errorf(\"order cannot be shipped unless it is pending\")\n\t}\n\to.Status = Shipped\n\treturn nil\n}\n\nfunc (o *Order) Cancel() error {\n\tif o.Status == Delivered {\n\t\treturn fmt.Errorf(\"order cannot be canceled after it is delivered\")\n\t}\n\to.Status = Canceled\n\treturn nil\n}\n\nfunc (o *Order) Deliver() error {\n\tif o.Status != Shipped {\n\t\treturn fmt.Errorf(\"order cannot be delivered unless it is shipped\")\n\t}\n\to.Status = Delivered\n\treturn nil\n}\n\nfunc (o *Order) Description() string {\n\treturn fmt.Sprintf(\"order #%d is currently %s\", o.ID, o.Status)\n}\n\nfunc main() {\n\tfor i := Monday; i <= Sunday; i++ {\n\t\tfmt.Println(i.String())\n\t}\n\n\torder1 := NewOrder(1)\n\tfmt.Println(order1.Description())\n\n\terr := order1.Send()\n\tif err != nil {\n\t\tfmt.Println(\"Err:\", err)\n\t}\n\tfmt.Println(order1.Description())\n\n\terr = order1.Deliver()\n\tif err != nil {\n\t\tfmt.Println(\"Err:\", err)\n\t}\n\tfmt.Println(order1.Description())\n\n\torder2 := NewOrder(2)\n\tfmt.Println(order2.Description())\n\n\terr = order2.Cancel()\n\tif err != nil {\n\t\tfmt.Println(\"Err:\", err)\n\t}\n\tfmt.Println(order2.Description())\n}\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/go/raynerpv2022.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"time\"\n)\n\n//\t/*\n//\n// #  * EJERCICIO:\n// #  * Empleando tu lenguaje, explora la definición del tipo de dato\n// #  * que sirva para definir enumeraciones (Enum).\n// #  * Crea un Enum que represente los días de la semana del lunes\n// #  * al domingo, en ese orden. Con ese enumerado, crea una operación\n// #  * que muestre el nombre del día de la semana dependiendo del número entero\n// #  * utilizado (del 1 al 7).\ntype WeekDay int\n\nconst (\n\tmonday WeekDay = iota\n\ttuesday\n\twednesday\n\tthrusday\n\tfriday\n\tsaturday\n\tsunday\n)\n\nfunc (w WeekDay) String() string {\n\tdays := [...]string{\"\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\", \"Sunday\"}\n\treturn days[w]\n}\n\nfunc getDay(index int) WeekDay {\n\treturn WeekDay(index)\n}\n\ntype Estado int\n\nconst (\n\tPENDIENTE Estado = iota + 1\n\tENVIADO\n\tENTREGADO\n\tCANCELADO\n)\n\nfunc (e Estado) String() string {\n\tswitch e {\n\tcase PENDIENTE:\n\t\treturn \"PENDIENTE\"\n\tcase ENVIADO:\n\t\treturn \"ENVIADO\"\n\tcase ENTREGADO:\n\t\treturn \"ENTREGADO\"\n\tcase CANCELADO:\n\t\treturn \"CANCELADO\"\n\tdefault:\n\t\treturn \"UNKNOWN\"\n\t}\n}\n\ntype Pedido struct {\n\tSerial string\n\tID     Estado\n}\n\nfunc (p *Pedido) Enviar() {\n\tif p.ID == PENDIENTE {\n\t\tp.ID = ENVIADO\n\t\tfmt.Printf(\"Pedido %s ha sido enviado\\n\", p.Serial)\n\t} else if p.ID == CANCELADO {\n\t\tfmt.Printf(\"Pedido %s está Cancelado\\n\", p.Serial)\n\t} else {\n\t\tfmt.Printf(\"Pedido %s no puede ser Enviado porque no está pendiente\\n\", p.Serial)\n\t}\n}\n\nfunc (p *Pedido) MostrarEstado() string {\n\treturn fmt.Sprintf(\"El estado actual del pedido %s es: %s\", p.Serial, p.ID)\n}\n\nfunc (p *Pedido) Cancelar() {\n\tif p.ID == CANCELADO {\n\t\tfmt.Printf(\"Pedido %s ya está Cancelado\\n\", p.Serial)\n\t} else if p.ID != ENTREGADO {\n\t\tp.ID = CANCELADO\n\t\tfmt.Printf(\"Pedido %s ha sido Cancelado\\n\", p.Serial)\n\t} else {\n\t\tfmt.Printf(\"Pedido %s no puede ser Cancelado porque ya se entregó\\n\", p.Serial)\n\t}\n}\n\nfunc (p *Pedido) Entregar() {\n\tif p.ID == ENVIADO {\n\t\tp.ID = ENTREGADO\n\t\tfmt.Printf(\"Pedido %s ha sido Entregado\\n\", p.Serial)\n\t} else if p.ID == CANCELADO {\n\t\tfmt.Printf(\"Pedido %s está Cancelado\\n\", p.Serial)\n\t} else {\n\t\tfmt.Printf(\"Pedido %s no puede ser Entregado porque no se ha enviado\\n\", p.Serial)\n\t}\n}\n\nfunc clearScreen() {\n\t// Clear the screen (works for Unix-like systems)\n\tfmt.Print(\"\\033[H\\033[J\")\n}\n\nfunc buscarPedido(pedidos []*Pedido, serial string) int {\n\tfor i, pedido := range pedidos {\n\t\tif pedido.Serial == serial {\n\t\t\treturn i\n\t\t}\n\t}\n\treturn -1\n}\nfunc seleccionarProducto(pedidos []*Pedido, serial string) {\n\tindex := buscarPedido(pedidos, serial)\n\tif index == -1 {\n\t\tfmt.Println(\"Pedido no encontrado\")\n\t\treturn\n\t}\n\n\tclearScreen()\n\teliminar := false\n\tfor {\n\t\tfmt.Println(\"1 - Ver Estado\", serial)\n\t\tfmt.Println(\"2 - Enviar Pedido\", serial)\n\t\tfmt.Println(\"3 - Cancelar Pedido\", serial)\n\t\tfmt.Println(\"4 - Entregar Pedido\", serial)\n\t\tfmt.Println(\"5 - Salir del Producto\", serial)\n\n\t\tvar s string\n\t\tfmt.Scanln(&s)\n\t\tswitch s {\n\t\tcase \"1\":\n\t\t\tfmt.Println(\"Mostrando Estado\")\n\t\t\tfmt.Println(pedidos[index].MostrarEstado())\n\t\tcase \"2\":\n\t\t\tfmt.Println(\"Enviando Producto\")\n\t\t\tpedidos[index].Enviar()\n\t\tcase \"3\":\n\t\t\tfmt.Println(\"Cancelando Producto\")\n\t\t\tpedidos[index].Cancelar()\n\t\t\teliminar = true\n\t\tcase \"4\":\n\t\t\tfmt.Println(\"Entregando Producto\")\n\t\t\tpedidos[index].Entregar()\n\t\tcase \"5\":\n\t\t\tfmt.Println(\"Saliendo del Producto\")\n\t\t\tif eliminar {\n\t\t\t\tfmt.Printf(\"Pedido %s Eliminado\\n\", pedidos[index].Serial)\n\t\t\t\tfmt.Println(pedidos[:index])\n\t\t\t\tfmt.Println(pedidos[index+1:])\n\n\t\t\t\tpedidos = append(pedidos[:index], pedidos[index+1:]...) //bug al eliminar repite el ultimo elemento\n\t\t\t}\n\t\t\tbreak\n\t\tdefault:\n\t\t\tfmt.Println(\"Opción Inválida\")\n\t\t}\n\n\t\tif s == \"5\" {\n\t\t\tbreak\n\t\t}\n\t}\n}\nfunc main() {\n\tpedidos1 := []int{0, 1, 2, 3, 4, 5}\n\tindex := 3\n\tpedidos1 = append(pedidos1[:index], pedidos1[index+1:]...)\n\tfmt.Println(pedidos1)\n\n\tfmt.Println(getDay(7))\n\n\tfmt.Println(\"EXTRA\")\n\n\tvar pedidos []*Pedido\n\tserial := 100\n\n\tfor {\n\t\tfmt.Println(\"Seleccione opción\")\n\t\tfmt.Println(\"1 - Crear Pedido\")\n\t\tfmt.Println(\"2 - Mostrar todos Pedidos\")\n\t\tfmt.Println(\"3 - Seleccionar Pedido\")\n\t\tfmt.Println(\"4 - Salir\")\n\n\t\tvar op string\n\t\tfmt.Scanln(&op)\n\n\t\tswitch op {\n\t\tcase \"1\":\n\t\t\tserial++\n\t\t\tpedidos = append(pedidos, &Pedido{\n\t\t\t\tSerial: fmt.Sprintf(\"%dA\", serial),\n\t\t\t\tID:     PENDIENTE,\n\t\t\t})\n\t\tcase \"2\":\n\t\t\tfmt.Println(\"Mostrando Todos los Pedidos\")\n\t\t\tfor _, pedido := range pedidos {\n\t\t\t\tfmt.Printf(\"Pedido: %s Estado: %s\\n\", pedido.Serial, pedido.ID)\n\t\t\t}\n\t\tcase \"3\":\n\t\t\tfmt.Println(\"Indique serial del pedido\")\n\t\t\tvar serialInput string\n\t\t\tfmt.Scanln(&serialInput)\n\t\t\tseleccionarProducto(pedidos, serialInput)\n\t\tcase \"4\":\n\t\t\tfmt.Println(\"Saliendo...\")\n\t\t\tfor i := 10; i > 0; i-- {\n\t\t\t\tfmt.Print(i, \" \")\n\t\t\t\ttime.Sleep(time.Second)\n\t\t\t}\n\t\t\tfmt.Println(\"\\nPrograma terminado\")\n\t\t\treturn\n\t\tdefault:\n\t\t\tfmt.Println(\"Opción no válida, 1-4\")\n\t\t}\n\t}\n\n}\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/go/thegera4.go",
    "content": "package main\n\nimport \"fmt\"\n\n// No existe la estructura de enumeraciones en Go, pero se puede simular con constantes\n// Primero creamos un tipo de dato para representar, en este caso, los días de la semana (este paso es opcional)\ntype DiaSemana string\n\n// Luego creamos las constantes con su valor, que representan los días de la semana\nconst (\n\tLunes DiaSemana = \"Lunes\"\n\tMartes DiaSemana = \"Martes\"\n\tMiercoles DiaSemana = \"Miercoles\"\n\tJueves DiaSemana = \"Jueves\"\n\tViernes DiaSemana = \"Viernes\"\n\tSabado DiaSemana = \"Sabado\"\n\tDomingo DiaSemana = \"Domingo\"\n)\n\n// Creamos una función que recibe un entero y devuelve el día de la semana correspondiente\nfunc DiaSemanaFromInt(dia int) DiaSemana {\n\tswitch dia {\n\tcase 1:\n\t\treturn Lunes\n\tcase 2:\n\t\treturn Martes\n\tcase 3:\n\t\treturn Miercoles\n\tcase 4:\n\t\treturn Jueves\n\tcase 5:\n\t\treturn Viernes\n\tcase 6:\n\t\treturn Sabado\n\tcase 7:\n\t\treturn Domingo\n\tdefault:\n\t\treturn \"No existe\"\n\t}\n}\n\nfunc main() {\n\tfmt.Println(DiaSemanaFromInt(1))\n\tfmt.Println(DiaSemanaFromInt(2))\n\tfmt.Println(DiaSemanaFromInt(3))\n\tfmt.Println(DiaSemanaFromInt(4))\n\tfmt.Println(DiaSemanaFromInt(5))\n\tfmt.Println(DiaSemanaFromInt(6))\n\tfmt.Println(DiaSemanaFromInt(7))\n\tfmt.Println(DiaSemanaFromInt(8))\n\n\t//Extra:\n\n\tp1 := Pedido{id: 1, status: PENDIENTE}\n\tp2 := Pedido{id: 2, status: ENVIADO}\n\tp3 := Pedido{id: 3, status: ENTREGADO}\n\tp4 := Pedido{id: 4, status: CANCELADO}\n\n\tfmt.Println(\"Pedido 1:\")\n\tfmt.Println(p1)\n\tp1.Enviar()\n\tfmt.Println(p1)\n\tp1.Cancelar()\n\tfmt.Println(p1)\n\n\tfmt.Println(\"Pedido 2:\")\n\tfmt.Println(p2)\n\tp2.Cancelar()\n\tfmt.Println(p2)\n\tp2.Entregar()\n\tfmt.Println(p2)\n\n\tfmt.Println(\"Pedido 3:\")\n\tfmt.Println(p3)\n\tp3.Enviar()\n\tp3.Cancelar()\n\n\tfmt.Println(\"Pedido 4:\")\n\tfmt.Println(p4)\n\tp4.Entregar()\n\n}\n\n//Extra:\n\ntype EstadoPedido int\n\nconst (\n\tPENDIENTE EstadoPedido = iota\n\tENVIADO\n\tENTREGADO\n\tCANCELADO\n)\n\ntype Pedido struct {\n\tid     int\n\tstatus EstadoPedido\n}\n\nfunc (p *Pedido) Enviar() {\n\tif(p.status == ENVIADO){\n\t\tfmt.Println(\"El pedido ya ha sido enviado\")\n\t} else if (p.status == ENTREGADO) {\n\t\tfmt.Println(\"El pedido ya ha sido entregado\")\n\t} else if (p.status == PENDIENTE) {\n\t\tp.status = ENVIADO\n\t} else {\n\t\tfmt.Println(\"No se puede enviar un pedido que no está pendiente\")\n\t}\n}\n\nfunc (p *Pedido) Cancelar() {\n\tif p.status == CANCELADO {\n\t\tfmt.Println(\"El pedido ya ha sido cancelado\")\n\t} else if p.status == ENTREGADO {\n\t\tfmt.Println(\"El pedido ya ha sido entregado\")\n\t} else if p.status == PENDIENTE {\n\t\tp.status = CANCELADO\n\t} else {\n\t\tfmt.Println(\"No se puede cancelar un pedido que no está pendiente\")\n\t}\n}\n\nfunc (p *Pedido) Entregar() {\n\tif p.status == ENTREGADO {\n\t\tfmt.Println(\"El pedido ya ha sido entregado\")\n\t} else if p.status == CANCELADO {\n\t\tfmt.Println(\"El pedido ya ha sido cancelado\")\n\t} else if p.status == ENVIADO {\n\t\tp.status = ENTREGADO\n\t} else {\n\t\tfmt.Println(\"No se puede entregar un pedido que no está enviado\")\n\t}\n}\n\nfunc (p *Pedido) Estado() string {\n\tswitch p.status {\n\tcase PENDIENTE:\n\t\treturn \"Pedido pendiente\"\n\tcase ENVIADO:\n\t\treturn \"Pedido enviado\"\n\tcase ENTREGADO:\n\t\treturn \"Pedido entregado\"\n\tcase CANCELADO:\n\t\treturn \"Pedido cancelado\"\n\tdefault:\n\t\treturn \"Estado desconocido\"\n\t}\n}\n\nfunc (p *Pedido) String() string {\n\treturn fmt.Sprintf(\"Pedido %d: %s\", p.id, p.Estado())\n}"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/java/AmadorQuispe.java",
    "content": "/* ╔══════════════════════════════════════╗\n   ║ Autor:  Amador Q                     ║\n   ║ Web  : https://amsoft.dev            ║\n   ║ 2024                                 ║\n   ╚══════════════════════════════════════╝\n*/\n\nenum DiaSemana {\n    LUNES(\"Lunes\", 1),\n    MARTES(\"Martes\", 2),\n    MIERCOLES(\"Miércoles\", 3),\n    JUEVES(\"Jueves\", 4),\n    VIERNES(\"Viernes\", 5),\n    SABADO(\"Sabado\", 6),\n    DOMINGO(\"Domingo\", 7);\n\n    private String nombreDia;\n    private int numeroDia;\n\n    private DiaSemana(String nombreDia, int numeroDia) {\n        this.nombreDia = nombreDia;\n        this.numeroDia = numeroDia;\n    }\n\n    public String getNombreDia() {\n        return nombreDia;\n    }\n\n    public int getNumeroDia() {\n        return numeroDia;\n    }\n\n}\n\nenum Estado {\n    PENDIENTE, ENVIADO, ENTREGADO, CANCELADO\n}\n\npublic class Main {\n    public static void main(String[] args) {\n        System.out.println(DiaSemana.DOMINGO);\n\n        // EXTRA\n        Pedido pedido1 = new Pedido(\"0001\", Estado.PENDIENTE);\n        pedido1.enviar();\n        pedido1.enviar();\n        pedido1.entregar();\n        pedido1.mostrarEstado();\n\n        Pedido pedido2 = new Pedido(\"0002\", Estado.PENDIENTE);\n        pedido2.cancelar();\n        pedido2.mostrarEstado();\n        pedido2.enviar();\n    }\n}\n\nclass Pedido {\n    private String id;\n    private Estado estado;\n\n    public Pedido(String id, Estado estado) {\n        this.id = id;\n        this.estado = estado;\n    }\n\n    public void enviar() {\n        if (estado == Estado.PENDIENTE) {\n            estado = Estado.ENVIADO;\n            System.out.println(\"El pedido # \" + id + \" ha sido enviado.\");\n        } else {\n            System.out.println(\"El pedido # \" + id + \" no se puede enviar porque su estado actual es: \" + estado);\n        }\n    }\n\n    public void cancelar() {\n        if (estado == Estado.PENDIENTE) { // Solo se puede cancelar si no ha sido enviada\n            estado = Estado.CANCELADO;\n            System.out.println(\"El pedido # \" + id + \" ha sido cancelado.\");\n        } else {\n            System.out.println(\"El pedido # \" + id + \" no se puede cancelar porque su estado actual es: \" + estado);\n        }\n    }\n\n    public void entregar() {\n        if (estado == Estado.ENVIADO) {\n            estado = Estado.ENTREGADO;\n            System.out.println(\"El pedido # \" + id + \" ha sido entregado.\");\n        } else {\n            System.out.println(\"El pedido # \" + id + \" no se puede entregar porque su estado actual es: \" + estado);\n        }\n    }\n\n    public void mostrarEstado() {\n        System.out.println(\"Estado del pedido # \" + id + \": \" + estado);\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/java/AnaLauDB.java",
    "content": "public class AnaLauDB {\n\n    // Enum para los días de la semana\n    public enum DiaSemana {\n        LUNES, MARTES, MIERCOLES, JUEVES, VIERNES, SABADO, DOMINGO\n    }\n\n    // Enum para el estado del pedido\n    public enum EstadoPedido {\n        PENDIENTE, ENVIADO, ENTREGADO, CANCELADO\n    }\n\n    // Clase Pedido\n    public static class Pedido {\n        private int id;\n        private EstadoPedido estado;\n\n        public Pedido(int id) {\n            this.id = id;\n            this.estado = EstadoPedido.PENDIENTE;\n        }\n\n        public void enviar() {\n            if (estado == EstadoPedido.PENDIENTE) {\n                estado = EstadoPedido.ENVIADO;\n                System.out.println(\"Pedido \" + id + \" enviado.\");\n            } else {\n                System.out.println(\"No se puede enviar el pedido \" + id + \" en estado \" + estado);\n            }\n        }\n\n        public void cancelar() {\n            if (estado == EstadoPedido.PENDIENTE || estado == EstadoPedido.ENVIADO) {\n                estado = EstadoPedido.CANCELADO;\n                System.out.println(\"Pedido \" + id + \" cancelado.\");\n            } else {\n                System.out.println(\"No se puede cancelar el pedido \" + id + \" en estado \" + estado);\n            }\n        }\n\n        public void entregar() {\n            if (estado == EstadoPedido.ENVIADO) {\n                estado = EstadoPedido.ENTREGADO;\n                System.out.println(\"Pedido \" + id + \" entregado.\");\n            } else {\n                System.out.println(\"No se puede entregar el pedido \" + id + \" en estado \" + estado);\n            }\n        }\n\n        public void mostrarEstado() {\n            switch (estado) {\n                case PENDIENTE:\n                    System.out.println(\"Pedido \" + id + \" está pendiente de envío.\");\n                    break;\n                case ENVIADO:\n                    System.out.println(\"Pedido \" + id + \" ha sido enviado.\");\n                    break;\n                case ENTREGADO:\n                    System.out.println(\"Pedido \" + id + \" ha sido entregado.\");\n                    break;\n                case CANCELADO:\n                    System.out.println(\"Pedido \" + id + \" ha sido cancelado.\");\n                    break;\n            }\n        }\n    }\n\n    // Mostrar el nombre del día según número (1-7)\n    public static void mostrarDia(int numero) {\n        if (numero < 1 || numero > 7) {\n            System.out.println(\"Número de día inválido.\");\n            return;\n        }\n        DiaSemana dia = DiaSemana.values()[numero - 1];\n        System.out.println(\"Día \" + numero + \": \" + dia);\n    }\n\n    public static void main(String[] args) {\n        // Ejemplo Enum días de la semana\n        for (int i = 1; i <= 7; i++) {\n            mostrarDia(i);\n        }\n\n        System.out.println(\"\\n--- Gestión de pedidos ---\");\n        Pedido p1 = new Pedido(101);\n        Pedido p2 = new Pedido(102);\n\n        p1.mostrarEstado();\n        p1.enviar();\n        p1.entregar();\n        p1.mostrarEstado();\n\n        p2.mostrarEstado();\n        p2.cancelar();\n        p2.entregar(); // No debe permitir entregar\n        p2.mostrarEstado();\n    }\n}\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/java/FranDev200.java",
    "content": "import java.util.ArrayList;\nimport java.util.Scanner;\n\npublic class FranDev200 {\n\n    enum DiasSemana{\n        Lunes, Martes, Miercoles, Jueves, Viernes, Sabado, Domingo\n    }\n\n    static ArrayList<Pedido> pedidos = new ArrayList<>();\n\n    static void main() {\n\n        /*\n\n         * EJERCICIO:\n         * Empleando tu lenguaje, explora la definición del tipo de dato\n         * que sirva para definir enumeraciones (Enum).\n         * Crea un Enum que represente los días de la semana del lunes\n         * al domingo, en ese orden. Con ese enumerado, crea una operación\n         * que muestre el nombre del día de la semana dependiendo del número entero\n         * utilizado (del 1 al 7).\n\n         */\n\n        Scanner sc = new Scanner(System.in);\n\n        for(int i=1 ; i <= 7 ; i++) {\n\n            System.out.println(i + \" --- \" + DiasSemana.values()[i - 1]);\n\n        }\n\n        while(true) {\n\n            try {\n\n                System.out.print(\"Indica un numero del 1 al 7: \");\n                int dia = Integer.parseInt(sc.nextLine());\n                System.out.println( dia + \" --- \" + DiasSemana.values()[dia - 1]);\n\n            }catch (ArrayIndexOutOfBoundsException e) {\n\n                System.out.println(\"Numero fuera de rango.\");\n                break;\n\n            }catch (NumberFormatException e) {\n\n                System.out.println(\"Numero invalido.\");\n                break;\n\n            }\n\n\n\n        }\n\n        /*\n            DIFICULTAD EXTRA (opcional):\n            * Crea un pequeño sistema de gestión del estado de pedidos.\n            * Implementa una clase que defina un pedido con las siguientes características:\n            * - El pedido tiene un identificador y un estado.\n            * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n            * - Implementa las funciones que sirvan para modificar el estado:\n            *   - Pedido enviado\n            *   - Pedido cancelado\n            *   - Pedido entregado\n            *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n            * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n            * - Crea diferentes pedidos y muestra cómo se interactúa con ellos.\n         */\n\n        pedidos.add(new Pedido(\"GGTDGT345\"));\n        pedidos.add(new Pedido(\"GGTDGT346\"));\n        pedidos.add(new Pedido(\"GGTDGT347\"));\n        pedidos.add(new Pedido(\"GGTDGT348\"));\n        pedidos.add(new Pedido(\"GGTDGT349\"));\n        pedidos.add(new Pedido(\"GGTDGT350\"));\n        pedidos.add(new Pedido(\"GGTDGT351\"));\n\n        System.out.println(\"\\nEjercicio EXTRA\");\n        System.out.println(\"===============\");\n\n        while (true) {\n\n            int respuesta = 0;\n            String id;\n\n            System.out.println(\"\\n- - - - - - - - - - - - - - - - - - - - - - - -\");\n            System.out.println(\"1 - Comprobar el estado de los pedidos.\");\n            System.out.println(\"2 - Comprobar el estado de un pedido concreto.\");\n            System.out.println(\"3 - Cambiar el estado de un pedido.\");\n            System.out.println(\"4 - Salir.\");\n            System.out.println(\"- - - - - - - - - - - - - - - - - - - - - - - -\");\n            System.out.print(\"Respuesta: \");\n\n            try {\n                respuesta = Integer.parseInt(sc.nextLine());\n            } catch (NumberFormatException e) {\n                System.out.println(\"Error - \" + e.getMessage());\n            }\n\n            switch (respuesta) {\n                case 1:\n                    System.out.println(\"\\nEstado de los pedidos:\");\n                    System.out.println(\"----------------------\");\n                    for (Pedido pedido : pedidos) {\n                        System.out.println(pedido.getId() + \" --> \" + pedido.getEstado());\n                    }\n                    break;\n\n                case 2:\n\n                    System.out.print(\"Indica el ID del pedido: \");\n                    id = sc.nextLine();\n                    comprobarEstadoPedido(id);\n                    break;\n\n                case 3:\n                    System.out.print(\"Indica el ID del pedido: \");\n                    id = sc.nextLine();\n                    cambiarEstado(id);\n                    break;\n\n                case 4:\n                    System.out.println(\"Saliendo del programa.\");\n                    System.exit(0);\n            }\n\n        }\n\n    }\n\n    public static void comprobarEstadoPedido(String id){\n\n        Pedido pedido = null;\n\n        for(Pedido p : pedidos){\n            if(p.getId().equals(id)){\n                pedido = p;\n                break;\n            }\n        }\n\n        if(pedido != null){\n            System.out.println(\"El estado del pedido con ID, \" + pedido.getId() + \", es \" + pedido.getEstado());\n        }else{\n            System.out.println(\"Este pedido no está guardado en la Base de Datos.\");\n        }\n\n\n    }\n\n    public static void cambiarEstado(String id){\n\n        Scanner sc = new Scanner(System.in);\n\n        Pedido pedido = null;\n        for(Pedido p : pedidos){\n            if(p.getId().equals(id)){\n\n                pedido = p;\n\n                if(pedido.getEstado().equals(Estado.PENDIENTE)){\n\n                    System.out.println(\"¿Quieres cancelarlo?[Si|No]\");\n                    String respuesta =  sc.nextLine();\n\n                    if(respuesta.equalsIgnoreCase(\"si\")){\n                        pedido.pedidoCancelado();\n                    }else if(respuesta.equalsIgnoreCase(\"no\")){\n                        pedido.pedidoEnviado();\n                    }\n\n                } else if (pedido.getEstado().equals(Estado.ENVIADO)) {\n                    pedido.pedidoEntregado();\n                } else if (pedido.getEstado().equals(Estado.ENTREGADO)) {\n                    System.out.println(\"El pedido con id \" + pedido.getId() + \" ya fue entregado.\");\n                } else if (pedido.getEstado().equals(Estado.CANCELADO)) {\n                    System.out.println(\"El pedido con id \" + pedido.getId() + \" fue cancelado anteriormente.\");\n                }\n\n                break;\n\n            }\n\n        }\n\n        if(pedido == null){\n            System.out.println(\"No se ha encontrado un pedido con ese ID.\");\n        }\n\n\n    }\n\n    enum Estado{\n        PENDIENTE, ENVIADO, ENTREGADO, CANCELADO\n    }\n\n    static class Pedido{\n        private String id;\n        private Estado estado;\n\n        public Pedido(String id) {\n            this.id = id;\n            this.estado = Estado.PENDIENTE;\n        }\n\n        public String getId() { return id; }\n\n        public void setId(String id) { this.id = id; }\n\n        public Estado getEstado() { return estado; }\n\n        public void setEstado(Estado estado) { this.estado = estado; }\n\n        public void pedidoEnviado(){\n            setEstado(Estado.ENVIADO);\n            System.out.println(\"El pedido con ID \" + getId() + \" ha cambiado de estado a \" +  getEstado());\n        }\n\n        public void pedidoCancelado(){\n            setEstado(Estado.CANCELADO);\n            System.out.println(\"El pedido con ID \" + getId() + \" ha cambiado de estado a \" +  getEstado());\n        }\n\n        public  void pedidoEntregado(){\n            setEstado(Estado.ENTREGADO);\n            System.out.println(\"El pedido con ID \" + getId() + \" ha cambiado de estado a \" +  getEstado());\n            System.out.println(\"PAQUETE ENTREGADO CON EXITO !!!\");\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/java/JimsimroDev.java",
    "content": "\n/*\n * EJERCICIO:\n * Empleando tu lenguaje, explora la definición del tipo de dato\n * que sirva para definir enumeraciones (Enum).\n * Crea un Enum que represente los días de la semana del lunes\n * al domingo, en ese orden. Con ese enumerado, crea una operación\n * que muestre el nombre del día de la semana dependiendo del número entero\n * utilizado (del 1 al 7).\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un pequeño sistema de gestión del estado de pedidos.\n * Implementa una clase que defina un pedido con las siguientes características:\n * - El pedido tiene un identificador y un estado.\n * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n * - Implementa las funciones que sirvan para modificar el estado:\n *   - Pedido enviado\n *   - Pedido cancelado\n *   - Pedido entregado\n *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n * - Crea diferentes pedidos y muestra cómo se interactúa con ellos. \n */\n\nenum DiasSemana {\n  LUNES(1),\n  MARTES(2),\n  MIERCOLES(3),\n  JUEVES(4),\n  VIERNES(5),\n  SABADO(6),\n  DOMINGO(7);\n\n  private final int numero;\n\n  private DiasSemana(int numero) {\n    this.numero = numero;\n  }\n}\n\nDiasSemana getDia(int numero) {\n  if (numero < 1 || numero > 7) {\n    throw new IllegalArgumentException(\"El número debe se entre 1 y 7\");\n  }\n  DiasSemana[] dias = DiasSemana.values();\n  for (int i = 0; i < DiasSemana.values().length; i++) {\n    if (dias[i].numero == numero) {\n      return dias[i];\n    }\n  }\n  return null;\n}\n\nclass Pedido {\n  private Long id;\n  private Estados estado;\n\n  public Pedido(Long id) {\n    this.id = id;\n    this.estado = estado.PENDIENTE;\n  }\n\n  void enviado() {\n    if (estado != Estados.PENDIENTE) {\n      IO.println(\"No puedes cambiar el estado\");\n      return;\n    }\n    estado = Estados.ENVIADO;\n    IO.println(\"El estado a sido cambiado a \" + estado);\n    printPedido();\n  }\n\n  void entregado() {\n    if (estado != Estados.ENVIADO) {\n      IO.println(\"El estado aun no a sido enviado\");\n      return;\n    }\n    estado = Estados.ENTREGADO;\n    IO.println(\"El estado a sido cambiado a \" + estado);\n    printPedido();\n  }\n\n  void cancelar() {\n    if (estado == Estados.ENTREGADO) {\n      IO.println(\"El pedido ya se encuentra \" + estado + \" No se puede cancelar\");\n      return;\n    }\n    estado = Estados.CANCELADO;\n    IO.println(\"El pedido a sido \" + estado);\n    printPedido();\n  }\n\n  void printPedido() {\n    IO.println(String.format(\"El estado del pedido %d es %s \", id, estado));\n  }\n\n  /*\n   *\n   * - Pedido enviado\n   * - Pedido cancelado\n   * - Pedido entregado\n   * (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado,\n   * etc...)\n   * - Implementa una función para mostrar un texto descriptivo según el estado\n   * actual.\n   * - Crea diferentes pedidos y muestra cómo se interactúa con ellos.\n   */\n}\n\nenum Estados {\n\n  PENDIENTE(1), ENVIADO(2), ENTREGADO(3), CANCELADO(4);\n\n  private final int numero;\n\n  private Estados(int numero) {\n    this.numero = numero;\n  }\n}\n\nvoid main() {\n  DiasSemana dia = getDia(1);\n  DiasSemana dia1 = getDia(7);\n  IO.println(dia);\n  IO.println(dia1);\n\n  // EXTRA\n  Pedido pedido = new Pedido(1L);\n  pedido.printPedido();\n\n  pedido.enviado();\n\n  pedido.cancelar();\n\n  pedido.entregado();\n\n}\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/java/Josegs95.java",
    "content": "public class Josegs95 {\n\n    public enum DayOfWeek{\n        LUNES(\"Lunes\"),\n        MARTES(\"Martes\"),\n        MIÉRCOLES(\"Miércoles\"),\n        JUEVES(\"Jueves\"),\n        VIERNES(\"Viernes\"),\n        SÁBADO(\"Sábado\"),\n        DOMINGO(\"Domingo\");\n\n        private String title;\n\n        private DayOfWeek(String title){\n            this.title = title;\n        }\n\n        public static void printDay(int index){\n            if (index > DayOfWeek.values().length || index < 1)\n                return;\n            System.out.println(DayOfWeek.values()[index - 1]);\n        }\n\n        @Override\n        public String toString() {\n            return title;\n        }\n    }\n\n    public static void main(String[] args) {\n        //Ejercicio\n        //Día de la semana: 2\n        DayOfWeek.printDay(2);\n\n        //Día de la semana: 5\n        DayOfWeek.printDay(5);\n\n        //Reto\n        retoFinal();\n    }\n\n    public static void retoFinal(){\n        Order order1 = new Order(1);\n        Order order2 = new Order(2);\n        Order order3 = new Order(3);\n\n        order1.ship();\n        order2.cancel();\n\n        order1.printStatus();\n        order2.printStatus();\n        order3.printStatus();\n\n        order1.deliver();\n        order2.deliver();\n        order3.deliver();\n\n        order1.printStatus();\n        order2.printStatus();\n        order3.printStatus();\n\n        order1.cancel();\n    }\n\n    public static class Order{\n        private final int id;\n        private OrderStatus status;\n\n        enum OrderStatus{\n            PENDIENTE,\n            ENVIADO,\n            ENTREGADO,\n            CANCELADO\n        }\n\n        Order(int id){\n            this.id = id;\n            status = OrderStatus.PENDIENTE;\n        }\n\n        public void ship(){\n            if (status == OrderStatus.CANCELADO){\n                System.out.println(\"El pedido \" + id + \" ha sido cancelado y no se puede entregar.\");\n                return;\n            } else if (status == OrderStatus.ENTREGADO){\n                System.out.println(\"El pedido \" + id + \" ya ha sido enviado y entregado.\");\n                return;\n            }\n            status = OrderStatus.ENVIADO;\n        }\n\n        public void deliver(){\n            if (status == OrderStatus.CANCELADO){\n                System.out.println(\"El pedido \" + id + \" ha sido cancelado y no se puede entregar.\");\n                return;\n            } else if (status == OrderStatus.PENDIENTE){\n                System.out.println(\"El pedido \" + id + \" necesita ser enviado antes de poder entregarlo.\");\n                return;\n            }\n            status = OrderStatus.ENTREGADO;\n        }\n\n        public void cancel(){\n            if (status == OrderStatus.ENTREGADO){\n                System.out.println(\"El pedido \" + id + \" ha sido entregado y no se puede cancelar.\");\n                return;\n            }\n            status = OrderStatus.CANCELADO;\n        }\n\n        public void printStatus(){\n            switch (status){\n                case PENDIENTE -> System.out.println(\"El paquete \" + id + \" está pendiente aún.\");\n                case ENVIADO -> System.out.println(\"El paquete \" + id + \" ha sido enviado.\");\n                case ENTREGADO -> System.out.println(\"El paquete \" + id + \" ha sido entregado.\");\n                case CANCELADO -> System.out.println(\"El paquete \" + id + \" ha sido cancelado.\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/java/MohamedElderkaoui.java",
    "content": "// Clase principal\npublic class MohamedElderkaoui {\n    public static void main(String[] args) {\n        // Parte 1: Enum de días de la semana\n        System.out.println(\"Días de la semana:\");\n        for (int i = 1; i <= 7; i++) {\n            System.out.println(\"Día \" + i + \": \" + DiaSemana.obtenerDiaPorNumero(i));\n        }\n\n        // Parte 2: Sistema de gestión de pedidos\n        Pedido pedido1 = new Pedido(1);\n        Pedido pedido2 = new Pedido(2);\n\n        // Interacción con los pedidos\n        System.out.println(\"\\nGestión de pedidos:\");\n        System.out.println(pedido1);\n        pedido1.enviarPedido();\n        System.out.println(pedido1);\n        pedido1.entregarPedido();\n        System.out.println(pedido1);\n\n        System.out.println(\"\\nEstado inicial del segundo pedido:\");\n        System.out.println(pedido2);\n        pedido2.cancelarPedido();\n        System.out.println(pedido2);\n    }\n}\n\n// Enum para los días de la semana\nenum DiaSemana {\n    LUNES, MARTES, MIERCOLES, JUEVES, VIERNES, SABADO, DOMINGO;\n\n    public static DiaSemana obtenerDiaPorNumero(int numero) {\n        if (numero < 1 || numero > 7) {\n            throw new IllegalArgumentException(\"El número debe estar entre 1 y 7.\");\n        }\n        return DiaSemana.values()[numero - 1];\n    }\n}\n\n// Enum para los estados de un pedido\nenum EstadoPedido {\n    PENDIENTE, ENVIADO, ENTREGADO, CANCELADO\n}\n\n// Clase que representa un pedido\nclass Pedido {\n    private final int id;\n    private EstadoPedido estado;\n\n    public Pedido(int id) {\n        this.id = id;\n        this.estado = EstadoPedido.PENDIENTE;\n    }\n\n    public void enviarPedido() {\n        if (estado == EstadoPedido.PENDIENTE) {\n            estado = EstadoPedido.ENVIADO;\n            System.out.println(\"El pedido #\" + id + \" ha sido enviado.\");\n        } else {\n            System.out.println(\"No se puede enviar el pedido #\" + id + \" en su estado actual: \" + estado);\n        }\n    }\n\n    public void entregarPedido() {\n        if (estado == EstadoPedido.ENVIADO) {\n            estado = EstadoPedido.ENTREGADO;\n            System.out.println(\"El pedido #\" + id + \" ha sido entregado.\");\n        } else {\n            System.out.println(\"No se puede entregar el pedido #\" + id + \" en su estado actual: \" + estado);\n        }\n    }\n\n    public void cancelarPedido() {\n        if (estado == EstadoPedido.PENDIENTE || estado == EstadoPedido.ENVIADO) {\n            estado = EstadoPedido.CANCELADO;\n            System.out.println(\"El pedido #\" + id + \" ha sido cancelado.\");\n        } else {\n            System.out.println(\"No se puede cancelar el pedido #\" + id + \" en su estado actual: \" + estado);\n        }\n    }\n\n    @Override\n    public String toString() {\n        String descripcionEstado;\n        switch (estado) {\n            case PENDIENTE:\n                descripcionEstado = \"Pendiente de envío.\";\n                break;\n            case ENVIADO:\n                descripcionEstado = \"Enviado, en espera de entrega.\";\n                break;\n            case ENTREGADO:\n                descripcionEstado = \"Entregado al cliente.\";\n                break;\n            case CANCELADO:\n                descripcionEstado = \"Pedido cancelado.\";\n                break;\n            default:\n                descripcionEstado = \"Estado desconocido.\";\n        }\n        return \"Pedido #\" + id + \" - Estado: \" + descripcionEstado;\n    }\n}\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/java/asjordi.java",
    "content": "/**\n * Un ENUM es un tipo de dato que se utiliza para definir un conjunto fijo de constantes.\n * Es útil cuando se tiene un conjunto de valores que no cambian durante toda la ejecución del programa.\n * Por ejemplo, los días de la semana, los meses del año, los colores, etc.\n */\npublic class Main {\n    public static void main(String[] args) {\n        System.out.println(Day.getDayName(11)); // -> MONDAY\n        manejarPedidos();\n    }\n\n    /**\n     * Crea un Enum que represente los días de la semana del lunes\n     * al domingo, en ese orden. Con ese Enum, crea una operación\n     * que muestre el nombre del día de la semana dependiendo del número entero\n     * utilizado (del 1 al 7).\n     */\n    public enum Day{\n        MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;\n\n        public static String getDayName(int n){\n            return switch (n) {\n                case 1 -> MONDAY.name();\n                case 2 -> TUESDAY.name();\n                case 3 -> WEDNESDAY.name();\n                case 4 -> THURSDAY.name();\n                case 5 -> FRIDAY.name();\n                case 6 -> SATURDAY.name();\n                case 7 -> SUNDAY.name();\n                default -> throw new IllegalArgumentException(\"Invalid day number: \" + n);\n            };\n        }\n    }\n\n    /**\n     * DIFICULTAD EXTRA (opcional):\n     * Crea un pequeño sistema de gestión del estado de pedidos.\n     * Implementa una clase que defina un pedido con las siguientes características:\n     * - El pedido tiene un identificador y un estado.\n     * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n     * - Implementa las funciones que sirvan para modificar el estado:\n     *  - Pedido enviado\n     *  - Pedido cancelado\n     *  - Pedido entregado\n     * (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n     * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n     * - Crea diferentes pedidos y muestra cómo se interactúa con ellos.\n     */\n\n    static class Pedido {\n        private Integer id;\n        private Estado estado;\n\n        public Pedido(Integer id, Estado estado) {\n            this.id = id;\n            this.estado = estado;\n        }\n\n        public void enviar() {\n            if (estado == Estado.PENDIENTE) {\n                estado = Estado.ENVIADO;\n            } else {\n                throw new IllegalStateException(\"No se puede enviar un pedido que no está pendiente.\");\n            }\n        }\n\n        public void entregar() {\n            if (estado == Estado.ENVIADO) {\n                estado = Estado.ENTREGADO;\n            } else {\n                throw new IllegalStateException(\"No se puede entregar un pedido que no está enviado.\");\n            }\n        }\n\n        public void cancelar() {\n            if (estado == Estado.PENDIENTE) {\n                estado = Estado.CANCELADO;\n            } else {\n                throw new IllegalStateException(\"No se puede cancelar un pedido que no está pendiente.\");\n            }\n        }\n\n        public String getEstado() {\n            return switch (estado) {\n                case PENDIENTE -> \"El pedido está pendiente.\";\n                case ENVIADO -> \"El pedido está enviado.\";\n                case ENTREGADO -> \"El pedido está entregado.\";\n                case CANCELADO -> \"El pedido está cancelado.\";\n            };\n        }\n    }\n\n    public enum Estado {\n        PENDIENTE, ENVIADO, ENTREGADO, CANCELADO;\n    }\n\n    public static void manejarPedidos() {\n        Pedido pedido1 = new Pedido(1, Estado.PENDIENTE);\n        System.out.println(pedido1.getEstado()); // -> El pedido está pendiente.\n        pedido1.enviar();\n        System.out.println(pedido1.getEstado()); // -> El pedido está enviado.\n        pedido1.entregar();\n        System.out.println(pedido1.getEstado()); // -> El pedido está entregado.\n\n        Pedido pedido2 = new Pedido(2, Estado.PENDIENTE);\n        System.out.println(pedido2.getEstado()); // -> El pedido está pendiente.\n        pedido2.cancelar();\n        System.out.println(pedido2.getEstado()); // -> El pedido está cancelado.\n    }\n}\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/java/carlosmperezm.java",
    "content": "public class chartypes {\n\n  public static void main(String[] args) {\n    exercise(1);\n    extra();\n\n  }\n\n  private static void exercise(int dayNumber) {\n    enum Day {\n      MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;\n    }\n    System.out.println(Day.values()[dayNumber - 1]);\n  }\n\n  enum OrderStatus {\n    PENDING, SENT, DELIVERED, CANCELLED;\n  }\n\n  public static class Order {\n    OrderStatus status = OrderStatus.PENDING;\n\n    public void sendOrder() {\n      if (status == OrderStatus.PENDING)\n        status = OrderStatus.SENT;\n      else\n        System.out.println(\"The order can't be sent\");\n    }\n\n    public void deliverOrder() {\n      if (status == OrderStatus.SENT)\n        status = OrderStatus.DELIVERED;\n      else\n        System.out.println(\"The order can't be delivered\");\n    }\n\n    public void cancelOrder() {\n      status = OrderStatus.CANCELLED;\n    }\n\n    public void ShowStatus(OrderStatus status) {\n      switch (status) {\n        case PENDING:\n          System.out.println(\"The order is pending\");\n          break;\n        case SENT:\n          System.out.println(\"The order is sent\");\n          break;\n        case DELIVERED:\n          System.out.println(\"The order is delivered\");\n          break;\n        case CANCELLED:\n          System.out.println(\"The order is cancelled\");\n          break;\n      }\n\n    }\n\n  }\n\n  private static void extra() {\n    Order order1 = new Order();\n    order1.ShowStatus(order1.status);\n    order1.sendOrder();\n    order1.ShowStatus(order1.status);\n    order1.deliverOrder();\n    order1.ShowStatus(order1.status);\n    order1.cancelOrder();\n    order1.ShowStatus(order1.status);\n    System.out.println(\"__________________________\");\n    System.out.println(\"Order 2\");\n\n    Order order2 = new Order();\n    order2.ShowStatus(order2.status);\n    // order2.sendOrder();\n    order2.ShowStatus(order2.status);\n    order2.deliverOrder();\n    order2.ShowStatus(order2.status);\n    order2.cancelOrder();\n    order2.ShowStatus(order2.status);\n\n  }\n\n}\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/java/danhingar.java",
    "content": "\npublic class danhingar {\n\n    public static void main(String[] args) {\n        System.out.println(Days.valueOf(8));\n\n        // EXTRA\n        Order order = new Order(1);\n        order.displayStatus();\n        order.deliever();\n        order.ship();\n        order.deliever();\n        order.cancel();\n    }\n\n    static class Order {\n        private static int id;\n        private static Status status;\n\n        public Order(int identifier) {\n            id = identifier;\n            status = Status.PENDIENTE;\n        }\n\n        public void ship() {\n            if (status.equals(Status.PENDIENTE)) {\n                status = Status.ENVIADO;\n                displayStatus();\n            } else {\n                System.out.println(\"El pedido ya ha sido enviado o cancelado\");\n            }\n        }\n\n        public void deliever() {\n            if (status.equals(Status.ENVIADO)) {\n                status = Status.ENTREGADO;\n                displayStatus();\n            } else {\n                System.out.println(\"El pedido necesita ser enviado antes de entregarse\");\n            }\n        }\n\n        public void cancel() {\n            if (!status.equals(Status.ENTREGADO)) {\n                status = Status.CANCELADO;\n                displayStatus();\n            } else {\n                System.out.println(\"El pedido no se puede cancelar ya que ya se ha entregado.\");\n            }\n        }\n\n        public void displayStatus() {\n            System.out.println(\"El estado del pedido \" + id + \" es \" + status);\n        }\n\n    }\n\n}\n\nenum Days {\n    LUNES(1),\n    MARTES(2),\n    MIERCOLES(3),\n    JUEVES(4),\n    VIERNES(5),\n    SABADO(6),\n    DOMINGO(7);\n\n    private int numberDay;\n\n    private Days(int numberDay) {\n        this.numberDay = numberDay;\n    }\n\n    public static String valueOf(int i) {\n        return Days.values().length >= i ? Days.values()[i - 1].name() : \"Selecciona un valor entre 1-7\";\n    }\n\n    public int getNumberDay() {\n        return numberDay;\n    }\n\n}\n\nenum Status {\n    PENDIENTE,\n    ENVIADO,\n    ENTREGADO,\n    CANCELADO;\n}\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/java/eulogioep.java",
    "content": "/*\n * TEORÍA SOBRE ENUMERACIONES EN JAVA\n * \n * Las enumeraciones en Java son un tipo especial de clase que representa un grupo\n * de constantes (variables inmutables). Se definen usando la palabra clave 'enum'.\n * \n * Características principales:\n * 1. Son implícitamente final y estáticas\n * 2. Pueden tener constructores, métodos y campos\n * 3. Implementan implícitamente java.lang.Comparable y java.io.Serializable\n * 4. Se utilizan comúnmente para representar un conjunto fijo de opciones\n */\n\npublic class eulogioep {\n    // Enumeración para los días de la semana\n    enum DiaSemana {\n        LUNES, MARTES, MIERCOLES, JUEVES, VIERNES, SABADO, DOMINGO\n    }\n\n    // Enumeración para los estados de un pedido\n    enum EstadoPedido {\n        PENDIENTE, ENVIADO, ENTREGADO, CANCELADO\n    }\n\n    // Clase para gestionar pedidos\n    static class Pedido {\n        private final int id;\n        private EstadoPedido estado;\n\n        // Constructor\n        public Pedido(int id) {\n            this.id = id;\n            this.estado = EstadoPedido.PENDIENTE;\n        }\n\n        // Método para enviar el pedido\n        public boolean enviarPedido() {\n            if (estado == EstadoPedido.PENDIENTE) {\n                estado = EstadoPedido.ENVIADO;\n                return true;\n            }\n            return false;\n        }\n\n        // Método para cancelar el pedido\n        public boolean cancelarPedido() {\n            if (estado == EstadoPedido.PENDIENTE || estado == EstadoPedido.ENVIADO) {\n                estado = EstadoPedido.CANCELADO;\n                return true;\n            }\n            return false;\n        }\n\n        // Método para entregar el pedido\n        public boolean entregarPedido() {\n            if (estado == EstadoPedido.ENVIADO) {\n                estado = EstadoPedido.ENTREGADO;\n                return true;\n            }\n            return false;\n        }\n\n        // Método para obtener descripción del estado\n        public String obtenerDescripcionEstado() {\n            return switch (estado) {\n                case PENDIENTE -> \"El pedido \" + id + \" está pendiente de envío.\";\n                case ENVIADO -> \"El pedido \" + id + \" ha sido enviado y está en camino.\";\n                case ENTREGADO -> \"El pedido \" + id + \" ha sido entregado con éxito.\";\n                case CANCELADO -> \"El pedido \" + id + \" ha sido cancelado.\";\n            };\n        }\n\n        // Getter para el estado\n        public EstadoPedido getEstado() {\n            return estado;\n        }\n    }\n\n    // Método para obtener el día de la semana según un número\n    public static String obtenerDiaSemana(int numero) {\n        if (numero < 1 || numero > 7) {\n            return \"Número inválido. Debe estar entre 1 y 7.\";\n        }\n        return DiaSemana.values()[numero - 1].toString();\n    }\n\n    public static void main(String[] args) {\n        // Prueba de días de la semana\n        System.out.println(\"=== PRUEBA DE DÍAS DE LA SEMANA ===\");\n        for (int i = 1; i <= 7; i++) {\n            System.out.println(\"Día \" + i + \": \" + obtenerDiaSemana(i));\n        }\n\n        // Prueba del sistema de gestión de pedidos\n        System.out.println(\"\\n=== PRUEBA DE GESTIÓN DE PEDIDOS ===\");\n\n        Pedido pedido1 = new Pedido(1);\n        Pedido pedido2 = new Pedido(2);\n\n        // Mostrar estado inicial\n        System.out.println(pedido1.obtenerDescripcionEstado());\n\n        // Enviar pedido1\n        pedido1.enviarPedido();\n        System.out.println(pedido1.obtenerDescripcionEstado());\n\n        // Intentar entregar pedido2 (debería fallar)\n        if (!pedido2.entregarPedido()) {\n            System.out.println(\"No se puede entregar el pedido 2 porque no ha sido enviado.\");\n        }\n\n        // Entregar pedido1\n        pedido1.entregarPedido();\n        System.out.println(pedido1.obtenerDescripcionEstado());\n\n        // Cancelar pedido2\n        pedido2.cancelarPedido();\n        System.out.println(pedido2.obtenerDescripcionEstado());\n    }\n}"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/java/martinbohorquez.java",
    "content": "import java.util.Arrays;\nimport java.util.Scanner;\n\n/**\n * #19 ENUMERACIONES\n *\n * @author martinbohorquez\n */\npublic class martinbohorquez {\n\n    public static void main(String[] args) {\n        System.out.println(\"Ingresar el número de semana que desea consultar(1 al 7):\");\n        Scanner sc = new Scanner(System.in);\n        printDayOfWeek(sc.nextInt());\n\n        /*\n         * DIFICULTAD EXTRA: Crea un pequeño sistema de gestión del estado de pedidos.\n         */\n        Order order1 = new Order(1);\n        order1.deliver();\n        order1.ship();\n        order1.deliver();\n        order1.cancel();\n        Order order2 = new Order(2);\n        order2.ship();\n        order2.cancel();\n        order2.deliver();\n    }\n\n    private static void printDayOfWeek(Integer dayNumber) {\n        String day = Arrays.stream(DayWeek.values())\n                .filter(d -> d.getNumberDay().equals(dayNumber))\n                .map(Enum::name)\n                .findFirst()\n                .orElse(\"No existe un día para el número escogido. Debe escoger un número del 1 al 7.\");\n        System.out.println(day);\n    }\n\n    enum DayWeek {\n        MONDAY(1),\n        TUESDAY(2),\n        WEDNESDAY(3),\n        THURSDAY(4),\n        FRIDAY(5),\n        SATURDAY(6),\n        SUNDAY(7);\n        private Integer numberDay = 0;\n\n        private DayWeek(Integer numberDay) {\n            this.numberDay = numberDay;\n        }\n\n        private Integer getNumberDay() {\n            return numberDay;\n        }\n    }\n\n    enum OrderStatus {\n        PENDING,\n        SHIPPED,\n        DELIVERED,\n        CANCELED;\n    }\n\n    private static class Order {\n        Integer orderId;\n        OrderStatus status;\n\n        public Order(Integer orderId) {\n            this.orderId = orderId;\n            status = OrderStatus.PENDING;\n        }\n\n        private void ship() {\n            if (status == OrderStatus.PENDING) {\n                status = OrderStatus.SHIPPED;\n                displayStatus();\n            } else System.out.println(\"El pedido ya ha sido enviado o cancelado!\");\n        }\n\n        private void deliver() {\n            if (status == OrderStatus.SHIPPED) {\n                status = OrderStatus.DELIVERED;\n                displayStatus();\n            } else System.out.println(\"El pedido necesita ser enviado antes de entregarse!\");\n        }\n\n        private void cancel() {\n            if (status != OrderStatus.DELIVERED) {\n                status = OrderStatus.CANCELED;\n                displayStatus();\n            } else System.out.println(\"El pedido ya ha sido entregado, no es posible cancelar!\");\n        }\n\n        private void displayStatus() {\n            System.out.printf(\"El estado del pedido %d es %s%n\", orderId, status);\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/java/simonguzman.java",
    "content": "import java.util.Scanner;\npublic class simonguzman {\n \n    public static void main(String[] args) {\n        firstExercise();\n        aditionalExercise();\n    }\n    //************************** First exercise **************************/\n    public enum Days{\n        LUNES,\n        MARTES,\n        MIERCOLES,\n        JUEVES,\n        VIERNES,\n        SABADO,\n        DOMINGO     \n    }\n    \n    static void firstExercise(){\n        Scanner scanner = new Scanner(System.in);\n        System.out.println(\"Ingrese un dia de la semana\");\n        int n = scanner.nextInt();\n\n        System.out.println(\"El dia \"+n+\" corresponde al dia: \"+getDay(n));\n    }\n\n    static Days getDay(int n){\n        Days day = weekDays(n);\n        return day;\n    }\n\n    static Days weekDays(int n){\n        switch (n) {\n            case 1: return Days.LUNES;\n            case 2: return Days.MARTES;\n            case 3: return Days.MIERCOLES;\n            case 4: return Days.JUEVES;\n            case 5: return Days.VIERNES;\n            case 6: return Days.SABADO;\n            case 7: return Days.DOMINGO;\n            default:\n                throw new IllegalArgumentException(\"ERROR: Numero incorrecto.\");\n        }\n    }\n\n    //************************** Aditional exercise **************************/  \n    \n    public enum statusOrder{\n        PENDIENTE,\n        ENVIADO,\n        ENTREGADO,\n        CANCELADO\n    }\n\n    static void aditionalExercise(){\n        Order order = new Order(1, statusOrder.PENDIENTE);\n        Scanner scanner = new Scanner(System.in);\n        int n;\n        do { \n            optionsMenu();\n            System.out.println(\"Ingrese una opcion: \");\n            n = scanner.nextInt();\n            menu(order, n);\n        } while (n != 5);\n    }\n\n    static void optionsMenu(){\n        System.out.println(\"Menú:\");\n        System.out.println(\"1. Enviar pedido\");\n        System.out.println(\"2. Entregar pedido\");\n        System.out.println(\"3. Cancelar pedido\");\n        System.out.println(\"4. Mostrar estado del pedido\");\n        System.out.println(\"5. Salir\");\n    }\n    static void menu(Order order, int n){\n        switch (n) {\n            case 1:\n                order.sendOrder();\n                break;\n                \n            case 2:\n                order.deliverOrder();\n                break;\n            case 3:\n                order.cancelOrder();\n                break;\n            case 4:\n                System.out.println(\"Estado del pedido: \"+order.getStatus());\n                break;\n            case 5:\n                System.out.println(\"Saliendo...\");\n                break;\n            default:\n                System.out.println(\"ERROR: opcion incorrecta...\");\n        }\n    }\n\n    static class Order{\n        protected double id;\n        protected statusOrder status;\n\n        public Order(){\n\n        }\n\n        public Order(double id, statusOrder status){\n            this.id = id;\n            this.status = statusOrder.PENDIENTE;\n        }\n\n        public void sendOrder(){\n            if (status == statusOrder.PENDIENTE) {\n                status = statusOrder.ENVIADO;\n                System.out.println(\"Pedido: \"+id+\" ha sido enviado.\");\n            }else{\n                System.out.println(\"El pedido: \"+id+\" No se puede enviar ya que no se encuentra pendiente\");\n            }\n        }\n\n        public void deliverOrder(){\n            if(status == statusOrder.ENVIADO){\n                status = statusOrder.ENTREGADO;\n                System.out.println(\"Pedido: \"+id+\" ha sido entregado.\");\n            }else{\n                System.out.println(\"El pedido: \"+id+\" No se puede enviar ya que no ha sido enviado.\");\n            }\n        }\n\n        public void cancelOrder(){\n            if(status == statusOrder.PENDIENTE || status == statusOrder.ENVIADO){\n                status = statusOrder.CANCELADO;\n                System.out.println(\"Pedido: \"+id+\" ha sido cancelado.\");\n            }else{\n                System.out.println(\"El pedido: \"+id+\" No se puede cancelar ya que ya ha sido entregado\");\n            }\n        }\n\n        public String getStatus(){\n            switch(status){\n                case PENDIENTE: return \"El pedido esta pendiente\";\n                case ENVIADO: return \"El pedido ha sido enviado\";\n                case ENTREGADO: return \"El pedido ha sido entregado\";\n                case CANCELADO: return \"El pedido esta pendiente\";\n                default:\n                    return \"Estado desconocido\";\n            }\n        }\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/java/vandresca.java",
    "content": "import java.time.DayOfWeek;\n\npublic class vandresca {\n    public static void main(String[] args) {\n        printDaysOfWeek();\n\n        Order order1 = new Order();\n        Order order2 = new Order();\n        Order order3 = new Order();\n        Order order4 = new Order();\n        Order order5 = new Order();\n        Order order6 = new Order();\n        Order order7 = new Order();\n        Order order8 = new Order();\n        Order order9 = new Order();\n        Order order10 = new Order();\n        Order order11 = new Order();\n        System.out.println();\n\n        //Ciclo completo del pedido\n        System.out.println(\"Ciclo completo del pedido\");\n        order1.getOrderSate();\n        order1.sendOrder();\n        order1.getOrderSate();\n        order1.deliverOrder();\n        order1.getOrderSate();\n        System.out.println();\n\n        //Cancelar en estado pendiente\n        System.out.println(\"Cancelar en estado pendiente\");\n        order2.getOrderSate();\n        order2.cancelOrder();\n        System.out.println();\n\n        //Cancelar en estado enviado\n        System.out.println(\"Cancelar en estado enviado\");\n        order3.getOrderSate();\n        order3.sendOrder();\n        order3.getOrderSate();\n        order3.cancelOrder();\n        order3.getOrderSate();\n        System.out.println();\n\n        //Cancelar en estado entregado\n        System.out.println(\"Cancelar en estado entregado\");\n        order4.getOrderSate();\n        order4.sendOrder();\n        order4.getOrderSate();\n        order4.deliverOrder();\n        order4.getOrderSate();\n        order4.cancelOrder();\n        order4.getOrderSate();\n        System.out.println();\n\n        //Cancelar en estado cancelado\n        System.out.println(\"Cancelar en estado cancelado\");\n        order5.getOrderSate();\n        order5.cancelOrder();\n        order5.getOrderSate();\n        order5.cancelOrder();\n        order5.getOrderSate();\n        System.out.println();\n\n        //Enviar sin estar pendiente\n        System.out.println(\"Enviar sin estar pendiente\");\n        order6.getOrderSate();\n        order6.deliverOrder();\n        order6.getOrderSate();\n        System.out.println();\n\n        //Enviar estando entregado\n        System.out.println(\"Enviar estando entregado\");\n        order7.getOrderSate();\n        order7.sendOrder();\n        order7.getOrderSate();\n        order7.deliverOrder();\n        order7.getOrderSate();\n        order7.sendOrder();\n        order7.getOrderSate();\n        System.out.println();\n\n        //Enviar estando cancelado\n        System.out.println(\"Enviar estando cancelado\");\n        order8.getOrderSate();\n        order8.cancelOrder();\n        order8.getOrderSate();\n        order8.sendOrder();\n        order8.getOrderSate();\n        System.out.println();\n\n        //Entregar estando pendiente\n        System.out.println(\"Entregar estando pendiente\");\n        order9.getOrderSate();\n        order9.deliverOrder();\n        order9.getOrderSate();\n        System.out.println();\n\n        //Entregar estando entregado\n        System.out.println(\"Entregar estando entregado\");\n        order10.getOrderSate();\n        order10.sendOrder();\n        order10.getOrderSate();\n        order10.deliverOrder();\n        order10.getOrderSate();\n        order10.deliverOrder();\n        order10.getOrderSate();\n        System.out.println();\n\n        //Entregar estando cancelado\n        System.out.println(\"Entregar estando cancelado\");\n        order11.getOrderSate();\n        order11.cancelOrder();\n        order11.getOrderSate();\n        order11.sendOrder();\n        order11.getOrderSate();\n    }\n\n    public static void printDaysOfWeek(){\n        System.out.println(WeekDay.getDayOfWeek(7));\n        System.out.println(WeekDay.getDayOfWeek(6));\n        System.out.println(WeekDay.getDayOfWeek(5));\n        System.out.println(WeekDay.getDayOfWeek(4));\n        System.out.println(WeekDay.getDayOfWeek(3));\n        System.out.println(WeekDay.getDayOfWeek(2));\n        System.out.println(WeekDay.getDayOfWeek(1));\n    }\n}\n\nenum WeekDay{\n    LUNES(1),\n    MARTES(2),\n    MIERCOLES(3),\n    JUEVES(4),\n    VIERNES(5),\n    SABADO(6),\n    DOMINGO(7);\n\n    private int numberDay = 0;\n    WeekDay(int numberDay){\n        this.numberDay=numberDay;\n    }\n    private int getNumberDay(){\n        return this.numberDay;\n    }\n\n    public static String getDayOfWeek(int numberDay){\n        for(WeekDay day: values()){\n            if(day.getNumberDay()==numberDay) return day.name();\n        }\n        return \"\";\n    }\n}\n\n //////////////////////////\n //                      //\n //   DIFICULTAD EXTRA   //\n //                      //\n //////////////////////////\n\nclass Order{\n    private int id = 0;\n    private static int count= 0;\n    private OrderState orderState = OrderState.PENDIENTE;\n\n    public Order(){\n        count++;\n        id = count;\n    }\n\n    public void getOrderSate(){\n        System.out.println(\"Estado del pedido \"+id+ \":  \"+orderState.name());\n    }\n\n    public void sendOrder(){\n        if(orderState.equals(OrderState.PENDIENTE)){\n            orderState = OrderState.ENVIADO;\n            System.out.println(\"El pedido ha cambiado a estado enviado\");\n        }else{\n            System.out.println(\">> ERROR: No es posible pasar el pedido a enviado \" +\n                    \"pues no se encuentra en estado pendiente\");\n        }\n    }\n    public void cancelOrder(){\n        if(orderState.equals(OrderState.PENDIENTE) || orderState.equals(OrderState.ENVIADO)){\n            orderState = OrderState.CANCELADO;\n            System.out.println(\"El pedido ha sido cancelado\");\n        }else if(orderState.equals(OrderState.CANCELADO)){\n            System.out.println(\">> ERROR: El pedido ya se encuentra cancelado\");\n        }else if(orderState.equals(OrderState.ENTREGADO)){\n            System.out.println(\">> ERROR: El pedido no puede ser cancelado pues ya se ha entregado\");\n        }\n    }\n    public void deliverOrder(){\n        if(orderState.equals(OrderState.ENVIADO)){\n            orderState = OrderState.ENTREGADO;\n            System.out.println(\"El pedido ha sido entregado con exito\");\n        }else if(orderState.equals(OrderState.CANCELADO)){\n            System.out.println(\">> ERROR: El pedido no ha sido entregado porque ha sido cancelado\");\n        }else if(orderState.equals(OrderState.PENDIENTE)){\n            System.out.println(\">> ERROR: Para ser entregado el pedido, primero debe ser enviado\");\n        }else if(orderState.equals(OrderState.ENTREGADO)){\n            System.out.println(\">> ERROR: El pedido ya se encuentra entregado\");\n        }\n    }\n}\n\nenum OrderState{\n    PENDIENTE,\n    ENVIADO,\n    ENTREGADO,\n    CANCELADO;\n}\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/javascript/7R0N1X.js",
    "content": "const diasDeLaSemana = Object.freeze({\n  1: 'Lunes',\n  2: 'Martes',\n  3: 'Miércoles',\n  4: 'Jueves',\n  5: 'Viernes',\n  6: 'Sábado',\n  7: 'Domingo'\n})\n\nconst obtenerDiaSemana = (dia) => {\n  switch (dia) {\n    case 1:\n      console.log(diasDeLaSemana[1])\n      break\n    case 2:\n      console.log(diasDeLaSemana[2])\n      break\n    case 3:\n      console.log(diasDeLaSemana[3])\n      break\n    case 4:\n      console.log(diasDeLaSemana[4])\n      break\n    case 5:\n      console.log(diasDeLaSemana[5])\n      break\n    case 6:\n      console.log(diasDeLaSemana[6])\n      break\n    case 7:\n      console.log(diasDeLaSemana[7])\n      break\n    default:\n      console.log('Día de la semana no encontrado.')\n  }\n}\n\nobtenerDiaSemana(4)\n\nconst estado = Object.freeze({\n  PENDIENTE: 'PENDIENTE',\n  ENVIADO: 'ENVIADO',\n  ENTREGADO: 'ENTREGADO',\n  CANCELADO: 'CANCELADO'\n})\n\n\n// DIFICULTAD EXTRA\nclass Pedido {\n\n  constructor() {\n    this._id = Date.now()\n    this._estado = 'PENDIENTE'\n  }\n\n  getId() {\n    return this._id\n  }\n\n  getEstado() {\n    return this._estado\n  }\n\n  setEstado(estado) {\n    const estadoActual = this.getEstado()\n    if (estadoActual === 'PENDIENTE') {\n      if (estado === 'ENVIADO' || estado === 'CANCELADO') this._estado = estado\n    }\n    if (estadoActual === 'ENVIADO') {\n      if (estado === 'ENTREGADO' || estado === 'CANCELADO') this._estado = estado\n    }\n  }\n\n  mostrarDetalle() {\n    return `#${this.getId()} - Estado: ${this.getEstado()}`\n  }\n\n}\n\nconsole.log('---  PEDIDO 1  ---')\nconst pedido1 = new Pedido()\nconsole.log(pedido1.mostrarDetalle())\npedido1.setEstado(estado.ENVIADO)\nconsole.log(pedido1.mostrarDetalle())\npedido1.setEstado(estado.ENTREGADO)\nconsole.log(pedido1.mostrarDetalle())\n\nconsole.log('---  PEDIDO 2  ---')\nconst pedido2 = new Pedido()\nconsole.log(pedido2.mostrarDetalle())\npedido2.setEstado(estado.CANCELADO)\nconsole.log(pedido2.mostrarDetalle())"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/javascript/AChapeton.js",
    "content": "const WeekDays = {\n  Monday: 1,\n  Tuesday: 2,\n  Wednesday: 3,\n  Thursday: 4,\n  Friday: 5,\n  Saturday: 6,\n  Sunday: 7\n}\n\nconst obtainDay = numberOfDay => {\n  const days = Object.keys(WeekDays)\n  console.log(`Number of the day ${numberOfDay} of the week is ${days[numberOfDay - 1]}`);\n};\n\nobtainDay(3);\nobtainDay(7);\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/javascript/ArticKun.js",
    "content": "\n//⚡ Enumeraciones\n\n/*\n\nEmpleando tu lenguaje, explora la definición del tipo de dato\n    - que sirva para definir enumeraciones (Enum).\n    - Crea un Enum que represente los días de la semana del lunes\n    - al domingo, en ese orden. Con ese enumerado, crea una operación\n    - que muestre el nombre del día de la semana dependiendo del número entero\n    - utilizado (del 1 al 7).\n\n\n\n1.Object.freeze Para asegurarte de que la enumeración no se modifique \naccidentalmente\n\n2. Uso de Symbol para valores únicos\nSymbol para asegurarse de que cada valor de la enumeración sea único\n\n*/\n\nconst Semana = Object.freeze({\n    LUNES     : Symbol('lunes'),\n    MARTES    : Symbol('martes'),\n    MIERCOLES : Symbol('miércoles'), \n    JUEVES    : Symbol('jueves'),\n    VIERNES   : Symbol('viernes'),\n    SABADO    : Symbol('sábado'), \n    DOMINGO   : Symbol('domingo'),\n});\n\n// Función para obtener el nombre del día de la semana dependiendo del número entero\nconst getDia = (numeroDia) => {\n\n    switch (numeroDia) {\n        case 1:\n            return Semana.LUNES;\n        case 2: \n            return Semana.MARTES;\n        case 3:\n            return Semana.MIERCOLES;\n        case 4:\n            return Semana.JUEVES;\n        case 5:\n            return Semana.VIERNES;\n        case 6:\n            return Semana.SABADO;\n        case 7:\n            return Semana.DOMINGO;\n        default:\n            return \"No existe ese día de la semana\";\n    }\n};\n\nconsole.log( getDia(7) );\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/javascript/DavidMoralesDeveloper.js",
    "content": "// Crea un Enum que represente los días de la semana del lunes\n//  * al domingo, en ese orden. Con ese enumerado, crea una operación\n//  * que muestre el nombre del día de la semana dependiendo del número entero\n//  * utilizado (del 1 al 7).\n// un objeto o  una clase lo averiguaremos.\n// que me aproximo a mi respuesta\n// https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Object/entries\n\nconst diasDelaSemana = {\n  lunes: 1,\n  martes: 2,\n  miercoles: 3,\n  jueves: 4,\n  viernes: 5,\n  sabado: 6,\n  domingo: 7,\n};\n\nfunction diaEnNum(num) {\n  const numeros = Object.entries(diasDelaSemana);\n  const guardar = numeros.find(([key, value]) => value === 4); //desestructuro mi arr en dos\n  return guardar[0]\n}\n\nconsole.log(diaEnNum(3))\n\n// * DIFICULTAD EXTRA (opcional):\n// * Crea un pequeño sistema de gestión del estado de pedidos.\n// * Implementa una clase que defina un pedido con las siguientes características:\n// * - El pedido tiene un identificador y un estado.\n// * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n// * - Implementa las funciones que sirvan para modificar el estado:\n// *   - Pedido enviado\n// *   - Pedido cancelado\n// *   - Pedido entregado\n// *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n// * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n// * - Crea diferentes pedidos y muestra cómo se interactúa con ellos. \n\n\nclass estadosDePedidos {\n\n     estadosDelPedido = {\n        PENDIENTE : 1,\n        ENVIADO : 2,\n        ENTREGADO : 3,\n        CANCELADO : 4\n     }\n     numero =Object.entries(this.estadosDelPedido)\n     stado = this.numero.find(([key, value]) => value === 1)\n   \n    constructor(id){\n        this.id = id\n        this.estado =  this.stado[0]\n        \n    }\n\n    enviado () {\n        if(this.estado === 'PENDIENTE'){\n            this.stado = this.numero.find(([key, value]) => value === 2)\n            this.estado = this.stado[0]\n        }else{\n            console.log('el pedido fue entregado o cancelado')\n        }\n        this.descStatus()\n    }\n\n    entregado () {\n        if (this.estado === 'ENVIADO'){\n            this.stado = this.numero.find(([key, value]) => value === 3)\n            this.estado = this.stado[0]\n        }else{\n            console.log(`el estado debe ser enviado o fue cancelado`)\n        }\n        this.descStatus()\n        // console.log('gracias por su compra vuelva pronto')\n    }\n\n    cancelado () {\n        this.stado = this.numero.find(([key, value]) => value === 4)\n        this.estado = this.stado[0]\n        this.descStatus()\n    }\n \n    descStatus (){\n        // Implementa una función para mostrar un texto descriptivo según el estado actual.\n        console.log(`el estado actual de el pedido ${this.id} tiene un estado de ${this.estado}`)\n    }    \n       \n}\n\n\n\nlet orden1 = new estadosDePedidos(1)\norden1.descStatus()\norden1.enviado()\norden1.entregado()\n\nconsole.log('-----------------------------------------orden2')\nlet oreden2 = new estadosDePedidos(2)\noreden2.descStatus()\noreden2.entregado()\noreden2.cancelado()\noreden2.enviado()\n\n\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/javascript/Deyvid-10.js",
    "content": "// No hay Enum en JavaScript\n// Ejercicio\n\nlet dias = {1: \"Lunes\", 2: \"Martes\", 3: \"Miercoles\", 4: \"Jueves\", 5: \"Viernes\", 6: \"Sabado\", 7: \"Domingo\"}\n\nconsole.log(dias[1]); // Lunes\nconsole.log(dias[6]); // Sabado\n\n// DIFICULTAD EXTRA\nclass Pedidos\n{\n    constructor(id)\n    {\n        this.id = id\n        this.nombreEstado = [\"PENDIENTE\", \"ENVIADO\", \"ENTREGADO\", \"CANCELADO\"]\n        this.estado = this.nombreEstado[0]\n    }\n\n    consultar()\n    {\n        console.log(`Pedido: ${this.id}\\nEstado: ${this.estado}`);\n    }\n\n    enviado()\n    {\n        if(this.estado == this.nombreEstado[0])\n        {\n            this.estado = this.nombreEstado[1]\n            console.log(\"El envio se realizo correctamente\");\n        }\n        else if(this.estado == this.nombreEstado[1])\n        {\n            console.log(\"El pedido ya estaba en estado enviado\");\n        }\n        else if(this.estado == this.nombreEstado[2])\n        {\n            console.log(\"El pedido fue entregado\");\n        }\n        else\n        {\n            console.log(\"El pedido fue cancelado\");\n        }\n    }\n\n    entregado()\n    {\n        if(this.estado == this.nombreEstado[1])\n        {\n            this.estado = this.nombreEstado[2]\n            console.log(\"El pedido ha sido entregado con exito\");\n        }\n        else if(this.estado == this.nombreEstado[2])\n        {\n            console.log(\"El pedido ya estaba en estado entregado\");\n        }\n        else if(this.estado == this.nombreEstado[0])\n        {\n            console.log(\"El pedio sigue en estado de pendiente, ni quiera ha sido enviado\");\n        }\n        else\n        {\n            console.log(\"El pedido fue cancelado\");\n        }\n    }\n\n    cancelado()\n    {\n        if(this.estado != this.nombreEstado[3])\n        {\n            this.estado = this.nombreEstado[3]\n            console.log(\"El pedido se cancelo con exito\");\n        }\n        else\n        {\n            console.log(\"El peido ya estaba en estado de cancelado\");\n        }\n    }\n}\n\n\nlet pedido52 = new Pedidos(52)\nlet pedido89 = new Pedidos(89)\nlet pedido101 = new Pedidos(101)\n\n\npedido52.entregado()\npedido52.consultar()\n\npedido52.enviado()\npedido52.entregado()\n\npedido89.enviado()\npedido89.cancelado()\n\npedido101.enviado()\n\npedido52.consultar()\npedido89.consultar()\npedido101.consultar()"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #19 - JavaScript ->Jesus Antonio Escamilla */\n\n/**\n * Aunque JavaScript no tiene un tipo de datos enum incorporado como algunos otros lenguajes de programación,\n    se pueden simular mediante el uso de Objects o Constantes.\n * En general, los enums son un tipo que puede contener un número finito de valores definidos.\n * Los valores de los enums no son mutables.\n */\n\n//---EJERCIÓ---\n// Creamos una función que puede agregar y leer los objetos (Enum)\nfunction Enum() {\n    this.obj = {};\n    this.add = function(key, value) {\n        this[key] = value;\n        this.obj[value] = key;\n    };\n    this.getName = function(value) {\n        return this.obj[value];\n    };\n}\n\n// Creamos el Enum como Objeto\nconst Semana_Enum = new Enum();\n// Agregamos Valores\nSemana_Enum.add(\"Lunes\", 1);\nSemana_Enum.add(\"Martes\", 2);\nSemana_Enum.add(\"Miércoles\", 3);\nSemana_Enum.add(\"Jueves\", 4);\nSemana_Enum.add(\"Viernes\", 5);\nSemana_Enum.add(\"Sábado\", 6);\nSemana_Enum.add(\"Domingo\", 7);\n\n// Retornamos el nombre del dia asignado\nfunction nombreDia(numero) {\n    return Semana_Enum.getName(numero);\n}\n\n// Lo llamamos en un consola\nconsole.log(`El numero es 5 que es el dia ${nombreDia(5)}`);\n\n\n\n/**-----DIFICULTAD EXTRA-----*/\n\n//  Creamos una función para el ENUM Estado\nfunction StateRaques() {\n    this.obj = [];\n    this.add = function(key, value) {\n        this[key] = value;\n        this.obj[value] = key;\n    };\n    this.getName = function(value) {\n        return this.obj[value];\n    };\n}\n\n//  Creamos un Estado de Pedidos\nconst State = new StateRaques();\n//  Aquí agregamos en ENUM\nState.add(\"Pendiente\", 0);\nState.add(\"Enviado\", 1);\nState.add(\"Entregado\", 2);\nState.add(\"Cancelado\", 3);\n\n//  Clase Pedido\nclass Order {\n    constructor(identificador){\n        this.identificador = identificador;\n        this.estado = State.Pendiente\n    }\n\n    SendOrder(){\n        if (this.estado === State.Pendiente) {\n            this.estado = State.Enviado;\n            console.log(`Pedido ${this.identificador} enviado.`);\n        } else {\n            console.log(`El pedido \"${this.identificador}\", no se puede enviar porque no está pendiente.`);\n        }\n    }\n\n    DeliverOrder(){\n        if (this.estado === State.Enviado) {\n            this.estado = State.Entregado;\n            console.log(`Pedido ${this.identificador} entregado.`);\n        } else {\n            console.log(`El pedido \"${this.identificador}\", no se puede entregar porque no ha sido enviado.`);\n        }\n    }\n    \n    CancelOrder(){\n        if (this.estado !== State.Entregado) {\n            this.estado = State.Cancelado;\n            console.log(`Pedido ${this.identificador} cancelado.`);\n        } else {\n            console.log(`El pedido \"${this.identificador}\" no se puede cancelar porque ya fue entregado.`);\n        }\n    }\n\n    DescriptionOrder(){\n        return `El estado del pedido ${this.identificador} es: ${State.getName(this.estado)}.`;\n    }\n}\n\n//  Ejemplo de ENUM\nconst order1 = new Order(\"001\");\norder1.SendOrder();\norder1.DeliverOrder();\nconsole.log(order1.DescriptionOrder());\n\nconst order2 = new Order(\"002\");\norder2.SendOrder();\norder2.CancelOrder();\nconsole.log(order2.DescriptionOrder());\n\nconst order3 = new Order(\"003\");\nconsole.log(order3.DescriptionOrder());\n\n/**-----DIFICULTAD EXTRA-----*/"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/javascript/RaulDoezon.js",
    "content": "/*\n  EJERCICIO:\n  Empleando tu lenguaje, explora la definición del tipo de dato\n  que sirva para definir enumeraciones (Enum).\n  Crea un Enum que represente los días de la semana del lunes\n  al domingo, en ese orden. Con ese enumerado, crea una operación\n  que muestre el nombre del día de la semana dependiendo del número entero\n  utilizado (del 1 al 7).\n*/\n\nconsole.log(\"\\n+++++++++ DÍAS DE LA SEMANA +++++++++\");\n\nconst weekDays = {\n  lunes: 1,\n  martes: 2,\n  miercoles: 3,\n  jueves: 4,\n  viernes: 5,\n  sabado: 6,\n  domingo: 7,\n}\n\nfunction findDay(dayNumber) {\n  return Object.keys(weekDays).find((key) =>\n    weekDays[key] === dayNumber,\n  );\n}\n\nconsole.log(\"El número de la semana ingresado corresponde a:\", findDay(2));\n\n/*\n  DIFICULTAD EXTRA (opcional):\n  Crea un pequeño sistema de gestión del estado de pedidos.\n  Implementa una clase que defina un pedido con las siguientes características:\n  - El pedido tiene un identificador y un estado.\n  - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n  - Implementa las funciones que sirvan para modificar el estado:\n    - Pedido enviado\n    - Pedido cancelado\n    - Pedido entregado\n    (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n  - Implementa una función para mostrar un texto descriptivo según el estado actual.\n  - Crea diferentes pedidos y muestra cómo se interactúa con ellos. \n*/\nconsole.log(\"\\n+++++++++ GESTIÓN DE PEDIDOS +++++++++\");\n\nclass OrderStatus {\n  constructor(id) {\n    this.id = id;\n    this.status = {\n      pending: \"Pendiente\",\n      send: \"Enviado\",\n      delivered: \"Entregado\",\n      cancelled: \"Cancelado\",\n    };\n  }\n\n  get printStatus() {\n    if (this.definedStatus !== \"Error\") {\n      return `- El estado del pedido ${this.id} es: ${this.definedStatus}.`;\n    } else {\n      return `- El pedido ${this.id} no puede entregarse sin antes enviado.`;\n    }\n  }\n\n  set setStatus(status) {\n    if (status === this.status.pending) {\n      this.definedStatus = this.pending();\n    }\n\n    if (status === this.status.send) {\n      this.definedStatus = this.send();\n      this.currentStatus = this.send();\n    }\n\n    if (status === this.status.delivered) {\n      if (this.currentStatus === this.send()) {\n        this.definedStatus = this.delivered();\n        this.currentStatus = this.delivered();\n      } else {\n        this.definedStatus = this.send();\n        this.definedStatus = \"Error\";\n      }\n    }\n\n    if (status === this.status.cancelled) {\n      this.definedStatus = this.cancelled();\n    }\n  }\n\n  pending() {\n    return this.status.pending;\n  }\n\n  send() {\n    return this.status.send;\n  }\n\n  delivered() {\n    return this.status.delivered;\n  }\n\n  cancelled() {\n    return this.status.cancelled;\n  }\n}\n\nconst order1 = new OrderStatus(112314);\nconst order2 = new OrderStatus(223425);\n\norder1.setStatus = order1.pending();\nconsole.log(order1.printStatus);\norder1.setStatus = order1.delivered();\nconsole.log(order1.printStatus);\norder1.setStatus = order1.send();\nconsole.log(order1.printStatus);\norder1.setStatus = order1.delivered();\nconsole.log(order1.printStatus);\nconsole.log(\"------------------------------------------------------\");\n\norder2.setStatus = order2.pending();\nconsole.log(order2.printStatus);\norder2.setStatus = order2.cancelled();\nconsole.log(order2.printStatus);\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/javascript/RicJDev.js",
    "content": "//EJERCICIO\nclass Enum {\n\tobject = {};\n\n\tadd(key, value) {\n\t\tthis.object[key] = value;\n\t}\n\n\tgetById(valueId) {\n\t\tconst values = Object.keys(this.object);\n\t\tif (typeof values[valueId - 1] === 'undefined') {\n\t\t\tthrow new Error('Valor inexistente');\n\t\t}\n\t\treturn values[valueId - 1];\n\t}\n}\n\nconst weekDays = new Enum('weekDays');\n\nweekDays.add('lunes', 1);\nweekDays.add('martes', 2);\nweekDays.add('miercoles', 3);\nweekDays.add('jueves', 4);\nweekDays.add('viernes', 5);\nweekDays.add('sabado', 6);\nweekDays.add('domingo', 7);\n\nconsole.log(`\\nDía de la semana: ${weekDays.getById(2)}`);\n\n//EXTRA\nlet cancelledOrders = [];\n\nclass Order extends Enum {\n\tconstructor(identifier) {\n\t\tsuper();\n\t\tthis.identifier = identifier;\n\t\tthis.status = this.getById(1);\n\t}\n\n\tobject = {\n\t\tpending: 1,\n\t\tsent: 2,\n\t\tdelivered: 3,\n\t\tcancelled: 4,\n\t};\n\n\tsendOrder() {\n\t\tif (this.status === 'pending') {\n\t\t\tconsole.log('\\nEnviando...');\n\t\t\treturn (this.status = this.getById(2));\n\t\t} else {\n\t\t\tconsole.log('\\nEl pedido debe estar pendiente para poder enviarlo');\n\t\t}\n\t}\n\n\tdeliverOrder() {\n\t\tif (this.status === 'sent') {\n\t\t\tconsole.log('\\nEntregando...');\n\t\t\treturn (this.status = this.getById(3));\n\t\t} else {\n\t\t\tconsole.log('\\nEl pedido debe haber sido enviado para poder entregarlo');\n\t\t}\n\t}\n\n\tcancelOrder() {\n\t\tif (this.status === 'delivered') {\n\t\t\tconsole.log('\\nNo se puede cancelar un pedido entregado');\n\t\t} else {\n\t\t\tconsole.log('\\nCancelando...');\n\t\t\tcancelledOrders.push(this.identifier);\n\t\t\treturn (this.status = this.getById(4));\n\t\t}\n\t}\n\n\tshowStatus() {\n\t\tconsole.log(`\\nEstado actual del pedido ${this.identifier}:`);\n\t\tswitch (this.status) {\n\t\t\tcase 'pending':\n\t\t\t\tconsole.log('Pendiente. Envíe cuando guste');\n\t\t\t\tbreak;\n\t\t\tcase 'sent':\n\t\t\t\tconsole.log('Enviado. En cualquier momento se entregará');\n\t\t\t\tbreak;\n\t\t\tcase 'delivered':\n\t\t\t\tconsole.log('Entregado. Puede realizar más pedidos si quiere');\n\t\t\t\tbreak;\n\t\t\tcase 'cancelled':\n\t\t\t\tconsole.log('Cancelado. La vida es impredecible');\n\t\t\t\tbreak;\n\t\t}\n\t}\n}\n\nlet myOrder = new Order(1434343);\n\nmyOrder.showStatus();\n\nmyOrder.sendOrder();\nmyOrder.showStatus();\n\nmyOrder.deliverOrder();\nmyOrder.showStatus();\n\nmyOrder.cancelOrder();\n\nlet myPizzaOrder = new Order(1223456);\n\nmyPizzaOrder.showStatus();\n\nmyPizzaOrder.deliverOrder();\nmyPizzaOrder.sendOrder();\nmyPizzaOrder.showStatus();\n\nmyPizzaOrder.cancelOrder();\nmyPizzaOrder.showStatus();\n\nlet myShoesOrder = new Order(4546066)\n\nmyShoesOrder.showStatus();\n\nmyShoesOrder.cancelOrder();\nmyShoesOrder.showStatus();\n\nconsole.log('\\n- Lista de pedidos cancelados 😭:');\ncancelledOrders.forEach(element => {\n\tconsole.log(element);\n});"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/javascript/Sac-Corts.js",
    "content": "const DaysOfWeek = {\n    1: \"Monday\",\n    2: \"Tuesday\",\n    3: \"Wednesday\",\n    4: \"Thursday\",\n    5: \"Friday\",\n    6: \"Saturday\",\n    7: \"Sunday\" \n};\n\nfunction getDayName(dayNumber) {\n    return DaysOfWeek[dayNumber] || \"Invalid day number\";\n}\n\nconsole.log(getDayName(1));\nconsole.log(getDayName(7));\nconsole.log(getDayName(8));\n\n// Extra Exercise //\nconst OrderStatus = {\n    PENDING: \"pending\",\n    SENT: \"sent\",\n    DELIVERED: \"delivered\", \n    CANCELED: \"canceled\"\n}\n\nclass Order {\n    constructor(id) {\n        this.id = id;\n        this.status = OrderStatus.PENDING;\n    }\n\n    sendOrder() {\n        if (this.status === OrderStatus.PENDING) {\n            this.status = OrderStatus.SENT;\n            console.log(`Order ${this.id} has been sent.`);\n        } else {\n            console.log(`Order ${this.id} cannot be sent in status ${this.status}.`);\n        }\n    }\n\n    cancelOrder() {\n        if (this.status === OrderStatus.DELIVERED) {\n            console.log(`Order ${this.id} cannot be canceled, because it has already been delivered.`);\n        } else {\n            this.status = OrderStatus.CANCELED;\n            console.log(`Order ${this.id} has been canceled.`);\n        }\n    }\n\n    deliverOrder() {\n        if (this.status === OrderStatus.SENT) {\n            this.status = OrderStatus.DELIVERED;\n            console.log(`Order ${this.id} has been delivered`);\n        } else {\n            console.log(`Order ${this.id} cannot be delivered in status ${this.status}`);\n        }\n    }\n\n    showStatus() {\n        console.log(`Order ${this.id} status is ${this.status}`);\n    }\n}\n\nconst order1 = new Order(1);\norder1.showStatus();\norder1.sendOrder();\norder1.deliverOrder();\norder1.cancelOrder();\n\nconst order2 = new Order(2);\norder2.sendOrder();\norder2.cancelOrder();\norder2.showStatus();"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/javascript/adrs1166ma.js",
    "content": "/* 🔥 EJERCICIO:\nEmpleando tu lenguaje, explora la definición del tipo de dato\nque sirva para definir enumeraciones (Enum).\nCrea un Enum que represente los días de la semana del lunes\nal domingo, en ese orden. Con ese enumerado, crea una operación\nque muestre el nombre del día de la semana dependiendo del número entero\nutilizado (del 1 al 7).\n*/\nconst DiasSemana = {\n    LUNES: 1,\n    MARTES: 2,\n    MIERCOLES: 3,\n    JUEVES: 4,\n    VIERNES: 5,\n    SABADO: 6,\n    DOMINGO: 7,\n};\n\nfunction obtenerNombreDia(numero) {\n    switch (numero) {\n        case DiasSemana.LUNES:\n            return \"Lunes\";\n        case DiasSemana.MARTES:\n            return \"Martes\";\n        case DiasSemana.MIERCOLES:\n            return \"Miércoles\";\n        case DiasSemana.JUEVES:\n            return \"Jueves\";\n        case DiasSemana.VIERNES:\n            return \"Viernes\";\n        case DiasSemana.SABADO:\n            return \"Sábado\";\n        case DiasSemana.DOMINGO:\n            return \"Domingo\";\n        default:\n            return \"Número inválido. Debe estar entre 1 y 7.\";\n    }\n}\n\nconsole.log(obtenerNombreDia(1))\nconsole.log(obtenerNombreDia(5))\nconsole.log(obtenerNombreDia(8))\n\n// Lunes\n// Viernes\n// Número inválido. Debe estar entre 1 y 7.\n\n/* 🔥 DIFICULTAD EXTRA (opcional): ---------------------------------------------------------\nCrea un pequeño sistema de gestión del estado de pedidos.\nImplementa una clase que defina un pedido con las siguientes características:\n- El pedido tiene un identificador y un estado.\n- El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n- Implementa las funciones que sirvan para modificar el estado:\n  - Pedido enviado\n  - Pedido cancelado\n  - Pedido entregado\n  (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n- Implementa una función para mostrar un texto descriptivo según el estado actual.\n- Crea diferentes pedidos y muestra cómo se interactúa con ellos. \n*/\nconst EstadoPedido = {\n    PENDIENTE: \"PENDIENTE\",\n    ENVIADO: \"ENVIADO\",\n    ENTREGADO: \"ENTREGADO\",\n    CANCELADO: \"CANCELADO\",\n};\n\nclass Pedido {\n    constructor(id) {\n        this.id = id\n        this.estado = EstadoPedido.PENDIENTE\n    }\n\n    enviar() {\n        if (this.estado === EstadoPedido.PENDIENTE) {\n            this.estado = EstadoPedido.ENVIADO\n            console.log(`Pedido ${this.id}: Enviado.`)\n        } else {\n            console.log(`Pedido ${this.id}: No se puede enviar. Estado actual: ${this.estado}`)\n        }\n    }\n\n    entregar() {\n        if (this.estado === EstadoPedido.ENVIADO) {\n            this.estado = EstadoPedido.ENTREGADO;\n            console.log(`Pedido ${this.id}: Entregado.`)\n        } else {\n            console.log(`Pedido ${this.id}: No se puede entregar. Estado actual: ${this.estado}`)\n        }\n    }\n\n    cancelar() {\n        if (this.estado !== EstadoPedido.ENTREGADO) {\n            this.estado = EstadoPedido.CANCELADO\n            console.log(`Pedido ${this.id}: Cancelado.`)\n        } else {\n            console.log(`Pedido ${this.id}: No se puede cancelar porque ya fue entregado.`)\n        }\n    }\n\n    mostrarEstado() {\n        console.log(`Pedido ${this.id}: Estado actual -> ${this.estado}`)\n    }\n}\n\n// Crear pedidos y probar las funciones\nconst pedido1 = new Pedido(1)\npedido1.mostrarEstado()\npedido1.enviar()\npedido1.entregar()\npedido1.cancelar()\npedido1.mostrarEstado()\n\nconsole.log(\"\")\n\nconst pedido2 = new Pedido(2)\npedido2.mostrarEstado()\npedido2.cancelar()\npedido2.mostrarEstado()\n\n// Pedido 1: Estado actual -> PENDIENTE\n// Pedido 1: Enviado.\n// Pedido 1: Entregado.\n// Pedido 1: No se puede cancelar porque ya fue entregado.\n// Pedido 1: Estado actual -> ENTREGADO\n//\n// Pedido 2: Estado actual -> PENDIENTE\n// Pedido 2: Cancelado.\n// Pedido 2: Estado actual -> CANCELADO"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/javascript/agusrosero.js",
    "content": "/*\n * EJERCICIO:\n * Empleando tu lenguaje, explora la definición del tipo de dato\n * que sirva para definir enumeraciones (Enum).\n * Crea un Enum que represente los días de la semana del lunes\n * al domingo, en ese orden. Con ese enumerado, crea una operación\n * que muestre el nombre del día de la semana dependiendo del número entero\n * utilizado (del 1 al 7).\n */\nconst diasSemana = Object.freeze({\n  LUNES: \"Lunes\",\n  MARTES: \"Martes\",\n  MIERCOLES: \"Miercoles\",\n  JUEVES: \"Jueves\",\n  VIERNES: \"Viernes\",\n  SABADO: \"Sabado\",\n  DOMINGO: \"Domingo\",\n});\nconsole.log(diasSemana);\n\nfunction getWeekdays(num) {\n  switch (num) {\n    case 1:\n      console.log(diasSemana.LUNES);\n      break;\n    case 2:\n      console.log(diasSemana.MARTES);\n      break;\n    case 3:\n      console.log(diasSemana.MIERCOLES);\n      break;\n    case 4:\n      console.log(diasSemana.JUEVES);\n      break;\n    case 5:\n      console.log(diasSemana.VIERNES);\n      break;\n    case 6:\n      console.log(diasSemana.SABADO);\n      break;\n    case 7:\n      console.log(diasSemana.DOMINGO);\n      break;\n  }\n}\n\ngetWeekdays(5);\n\n/**\n * DIFICULTAD EXTRA (opcional):\n * Crea un pequeño sistema de gestión del estado de pedidos.\n * Implementa una clase que defina un pedido con las siguientes características:\n * - El pedido tiene un identificador y un estado.\n * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n * - Implementa las funciones que sirvan para modificar el estado:\n *   - Pedido enviado\n *   - Pedido cancelado\n *   - Pedido entregado\n *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n * - Crea diferentes pedidos y muestra cómo se interactúa con ellos.\n */\nconst estados = Object.freeze({\n  PENDIENTE: \"Pendiente\",\n  ENVIADO: \"Enviado\",\n  ENTREGADO: \"Entregado\",\n  CANCELADO: \"Cancelado\",\n});\n\nclass GestionEstadoPedidos {\n  constructor(id) {\n    this.id = id;\n    this.estado = estados.PENDIENTE;\n  }\n\n  pedidoEnviado() {\n    if (this.estado === estados.ENVIADO) {\n      console.log(\"Pedido enviado con exito\");\n    } else {\n      console.log(\"Error en el envio del pedido\");\n    }\n  }\n\n  pedidoCancelado() {\n    if (this.estado === estados.CANCELADO) {\n      console.log(\"Pedido cancelado\");\n    } else {\n      console.log(\"Error al cancelar el pedido\");\n    }\n  }\n\n  pedidoEntregado() {\n    if (this.estado === estados.ENTREGADO) {\n      console.log(\"Pedidos entregado correctamente\");\n    } else {\n      console.log(\"Error al entregar el pedido\");\n    }\n  }\n\n  textoDescriptivo() {\n    console.log(`Estado del pedido: ${this.estado}`);\n  }\n}\n\nconst pedido1 = new GestionEstadoPedidos();\npedido1.textoDescriptivo();\npedido1.pedidoEnviado();\n\nconst pedido2 = new GestionEstadoPedidos();\npedido2.textoDescriptivo();\npedido2.pedidoCancelado();\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/javascript/bernatcs.js",
    "content": "// ** EJERCICIO \n\nconst diasSemana = Object.freeze({\n    1: 'Lunes',\n    2: 'Martes',\n    3: 'Miércoles',\n    4: 'Jueves',\n    5: 'Viernes',\n    6: 'Sábado',\n    7: 'Domingo'\n})\n\nfunction diaSemana(num) {\n    return diasSemana[num] || console.error('Número inválido')\n}\n\nconsole.log(diaSemana(7))\n\n\n// ** DIFICULTAD EXTRA ** -------------------------------------------------------------------------------------------------------------------------------------\n\nconst EstadoPedido = Object.freeze({\n    1: 'PENDIENTE',\n    2: 'ENVIADO',\n    3: 'ENTREGADO',\n    4: 'CANCELADO'\n});\n\nclass Pedido {\n    constructor(id) {\n        this.id = id;\n        this.estado = EstadoPedido[1];\n    }\n\n    enviar() {\n        if (this.estado === EstadoPedido[1]) {\n            this.estado = EstadoPedido[2];\n            console.log(`El estado del pedido ha cambiado a: ${EstadoPedido[2]}`);\n        } else {\n            console.log(`El pedido no se puede enviar porque se encuentra en estado: ${this.estado}`);\n        }\n    }\n\n    cancelar() {\n        if (this.estado !== EstadoPedido[4]) {\n            this.estado = EstadoPedido[4];\n            console.log(`El estado del pedido ha cambiado a: ${EstadoPedido[4]}`);\n        } else {\n            console.log(`El pedido ya está cancelado.`);\n        }\n    }\n\n    entregar() {\n        if (this.estado === EstadoPedido[2]) {\n            this.estado = EstadoPedido[3];\n            console.log(`El estado del pedido ha cambiado a: ${EstadoPedido[3]}`);\n        } else {\n            console.log(`El pedido no se puede entregar porque se encuentra en estado: ${this.estado}`);\n        }\n    }\n\n    mostrarEstado() {\n        switch (this.estado) {\n            case EstadoPedido[1]:\n                console.log(`El pedido ${this.id} está en estado: ${EstadoPedido[1]}`);\n                break;\n            case EstadoPedido[2]:\n                console.log(`El pedido ${this.id} está en estado: ${EstadoPedido[2]}`);\n                break;\n            case EstadoPedido[3]:\n                console.log(`El pedido ${this.id} está en estado: ${EstadoPedido[3]}`);\n                break;\n            case EstadoPedido[4]:\n                console.log(`El pedido ${this.id} está en estado: ${EstadoPedido[4]}`);\n                break;\n            default:\n                console.log(`Estado desconocido para el pedido ${this.id}`);\n        }\n    }\n}\n\n// Crear un pedido\nconst pedido1 = new Pedido(1);\n\npedido1.mostrarEstado(); // El pedido 1 está en estado: PENDIENTE\npedido1.enviar(); // El estado del pedido ha cambiado a: ENVIADO\npedido1.enviar(); // El pedido no se puede enviar porque se encuentra en estado: ENVIADO\npedido1.entregar(); // El estado del pedido ha cambiado a: ENTREGADO\npedido1.cancelar(); // El estado del pedido ha cambiado a: CANCELADO\npedido1.mostrarEstado(); // El pedido 1 está en estado: CANCELADO"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/javascript/caterinarodriguezdev.js",
    "content": "/*\n * EJERCICIO:\n * Empleando tu lenguaje, explora la definición del tipo de dato\n * que sirva para definir enumeraciones (Enum).\n * Crea un Enum que represente los días de la semana del lunes\n * al domingo, en ese orden. Con ese enumerado, crea una operación\n * que muestre el nombre del día de la semana dependiendo del número entero\n * utilizado (del 1 al 7).\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un pequeño sistema de gestión del estado de pedidos.\n * Implementa una clase que defina un pedido con las siguientes características:\n * - El pedido tiene un identificador y un estado.\n * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n * - Implementa las funciones que sirvan para modificar el estado:\n *   - Pedido enviado\n *   - Pedido cancelado\n *   - Pedido entregado\n *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n * - Crea diferentes pedidos y muestra cómo se interactúa con ellos.\n */\n\nconst diasDeLaSemana = Object.freeze({\n  LUNES: 1,\n  MARTES: 2,\n  MIERCOLES: 3,\n  JUEVES: 4,\n  VIERNES: 5,\n  SABADO: 6,\n  DOMINGO: 7,\n});\n\nconst getDayFromNumber = (number) => {\n  let day = Object.keys(diasDeLaSemana).find(\n    (key) => diasDeLaSemana[key] === number\n  );\n  console.log(day);\n};\n\ngetDayFromNumber(2);\n\nconsole.log(\"---------------DIFICULTAD EXTRA----------------\");\n\nconst statusEnum = Object.freeze({\n  PENDIENTE: 0,\n  ENVIADO: 1,\n  ENTREGADO: 2,\n  CANCELADO: 4,\n});\n\nclass Order {\n  constructor(id, state) {\n    this.id = id;\n    this.status = state;\n  }\n\n  order() {\n    this.status = statusEnum.PENDIENTE;\n    console.log(\"El pedido se ha creado con id: \", this.id);\n  }\n\n  send() {\n    if (!this.checkIsCanceled('enviar')) {\n      return false;\n    } else if (this.status === 0) {\n      console.log(\"El pedido se está enviando\");\n      this.status = statusEnum.ENVIADO;\n    } else if (this.status === statusEnum.ENVIADO) {\n      console.log(\"El pedido ya se ha enviado o ha sido cancelado\");\n    } else {\n      console.log(\"No se puede enviar un envío inexistente\");\n    }\n  }\n\n  deliver() {\n    if (!this.checkIsCanceled('entregar')) {\n      return false;\n    } else if (this.status > 2) {\n      this.status = statusEnum.ENTREGADO;\n      console.log(\"El pedido se está entregando\");\n    } else {\n      console.log(\n        \"No se puede entregar un envío que no se ha creado y/o mandado\"\n      );\n    }\n  }\n\n  cancel() {\n    if (this.status < 2) {\n      this.status = statusEnum.CANCELADO;\n      console.log(\"El pedido se ha cancelado\");\n    } else {\n      console.log(\n        \"No se puede entregar un envío que no se ha creado y/o mandado\"\n      );\n    }\n  }\n\n  checkStatus() {\n    console.log(\n      \"El estado del pedido es: \",\n      Object.keys(statusEnum).find((key) => statusEnum[key] === this.status)\n    );\n  }\n\n  checkIsCanceled(operacion) {\n    if (this.status === statusEnum.CANCELADO) {\n      console.log(\"El pedido ha sido cancelado, no se puede realizar la operación: \", operacion);\n      return false;\n    }\n    return true;\n  }\n}\n\nconst order1 = new Order('001');\norder1.order();\norder1.checkStatus();\norder1.send();\norder1.checkStatus();\n\nconst order2 = new Order('002');\norder2.order();\norder2.checkStatus();\norder2.cancel();\norder2.send();"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/javascript/christian-jfr.js",
    "content": "// #19 ENUMERACIONES\n\n/**\n * EJERCICIO:\n * Empleando tu lenguaje, explora la definición del tipo de dato\n * que sirva para definir enumeraciones (Enum).\n * Crea un Enum que represente los días de la semana del lunes\n * al domingo, en ese orden. Con ese enumerado, crea una operación\n * que muestre el nombre del día de la semana dependiendo del número entero\n * utilizado (del 1 al 7).\n */\nconst weekDays = Object.freeze({\n\tMONDAY: 1,\n\tTUESDAY: 2,\n\tWEDNESDAY: 3,\n\tTHURSDAY: 4,\n\tFRIDAY: 5,\n\tSATURDAY: 6,\n\tSUNDAY: 7,\n});\n\nfunction getDay(dayNumber) {\n\tif (dayNumber < 1 || dayNumber > 7) {\n\t\tconsole.log('Invalid day number. Please enter a number between 1 and 7.');\n\t} else {\n\t\tconst dayEnum = Object.keys(weekDays)[dayNumber - 1];\n\t\tconsole.log(dayEnum);\n\t}\n}\n\ngetDay(1); // -> MONDAY\ngetDay(8); // -> Invalid day number. Please enter a number between 1 and 7.\ngetDay(5); // -> FRIDAY\n\n/**\n * DIFICULTAD EXTRA (opcional):\n * Crea un pequeño sistema de gestión del estado de pedidos.\n * Implementa una clase que defina un pedido con las siguientes características:\n * - El pedido tiene un identificador y un estado.\n * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n * - Implementa las funciones que sirvan para modificar el estado:\n *   - Pedido enviado\n *   - Pedido cancelado\n *   - Pedido entregado\n *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n * - Crea diferentes pedidos y muestra cómo se interactúa con ellos.\n */\n\nconst Status = Object.freeze({\n\tPENDING: 'PENDING',\n\tSHIPPED: 'SHIPPED',\n\tCANCELED: 'CANCELED',\n\tDELIVERED: 'DELIVERED',\n});\n\nclass Order {\n\tstatus = Status.PENDING;\n\tconstructor(id) {\n\t\tthis.id = id;\n\t}\n\n\tdisplay_status() {\n\t\tconsole.log(`Order ${this.id} status: ${this.status}`);\n\t}\n\n\tship() {\n\t\tif (this.status == Status.PENDING) {\n\t\t\tthis.status = Status.SHIPPED;\n\t\t\tthis.display_status();\n\t\t} else {\n\t\t\tconsole.log(\n\t\t\t\t`Order ${this.id} cannot be shipped because it is not pending.`\n\t\t\t);\n\t\t}\n\t}\n\n\tcancel() {\n\t\tif (this.status == Status.PENDING || this.status == Status.SHIPPED) {\n\t\t\tthis.status = Status.CANCELED;\n\t\t\tthis.display_status();\n\t\t} else {\n\t\t\tconsole.log(\n\t\t\t\t`Order ${this.id} cannot be canceled because it was already ${this.status}.`\n\t\t\t);\n\t\t}\n\t}\n\n\tdeliver() {\n\t\tif (this.status == Status.SHIPPED) {\n\t\t\tthis.status = Status.DELIVERED;\n\t\t\tthis.display_status();\n\t\t} else {\n\t\t\tconsole.log(\n\t\t\t\t`Order ${this.id} cannot be delivered because it is not shipped.`\n\t\t\t);\n\t\t}\n\t}\n}\n\nlet order10 = new Order(10);\nlet order20 = new Order(20);\nlet order30 = new Order(30);\nlet order40 = new Order(40);\n\norder10.display_status(); // -> Order 10 status: PENDING\norder10.deliver(); // -> Order 10 cannot be delivered because it is not shipped.\norder10.ship(); // -> Order 10 status: SHIPPED\norder10.deliver(); // -> Order 10 status: DELIVERED\n\norder20.cancel(); // -> Order 20 status: CANCELED\norder20.cancel(); // -> Order 20 cannot be canceled because it was already CANCELED.\n\norder30.ship(); // -> Order 30 status: SHIPPED\norder30.cancel(); // -> Order 30 status: CANCELED\n\norder40.ship(); // -> Order 40 status: SHIPPED\norder40.deliver(); // -> Order 40 status: DELIVERED\norder40.cancel(); // -> Order 40 cannot be canceled because it was already DELIVERED.\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/javascript/duendeintemporal.js",
    "content": "//#19 ENUMERACIONES\n//I use GPT as a reference for concepts\n/*\n * EJERCICIO:\n * Empleando tu lenguaje, explora la definición del tipo de dato\n * que sirva para definir enumeraciones (Enum).\n * Crea un Enum que represente los días de la semana del lunes\n * al domingo, en ese orden. Con ese enumerado, crea una operación\n * que muestre el nombre del día de la semana dependiendo del número entero\n * utilizado (del 1 al 7).\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un pequeño sistema de gestión del estado de pedidos.\n * Implementa una clase que defina un pedido con las siguientes características:\n * - El pedido tiene un identificador y un estado.\n * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n * - Implementa las funciones que sirvan para modificar el estado:\n *   - Pedido enviado\n *   - Pedido cancelado\n *   - Pedido entregado\n *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n * - Crea diferentes pedidos y muestra cómo se interactúa con ellos. \n */\n\n/* In JavaScript, Enums (short for \"enumerations\") are not a native feature of the language like in other programming languages (for example, TypeScript, C#, Java). However, you can simulate the behavior of enums using objects.\n\nWhat are Enums?\nEnums are a way to define a set of named constants. They are used to represent a group of related values, making the code more readable and easier to maintain. For example, you might have an enum for the days of the week, the statuses of an order, or colors. */\n\nwindow.addEventListener('load', ()=>{\n    const body = document.querySelector('body');\n    const title = document.createElement('h1');\n    \n    body.style.setProperty('background', '#000');\n    body.style.setProperty('text-align', 'center');\n    \n    title.textContent = 'Retosparaprogramadores #19.';\n    title.style.setProperty('font-size', '3.5vmax');\n    title.style.setProperty('color', '#fff');\n    title.style.setProperty('line-height', '100vh');\n    \n    body.appendChild(title);\n    \n    setTimeout(()=>{\n    alert('Retosparaprogramadores #19. Please open the Browser Developer Tools.');\n    }, 2000);\n    log( 'Retosparaprogramadores #19'); \n});\n\nlet log = console.log;\n\nconst DaysOfWeek = {\n    MONDAY: 'Monday',\n    TUESDAY: 'Tuesday',\n    WEDNESDAY: 'Wednesday',\n    THURSDAY: 'Thursday',\n    FRIDAY: 'Friday',\n    SATURDAY: 'Saturday',\n    SUNDAY: 'Sunday'\n};\n\nObject.freeze(DaysOfWeek);\n\nconst showDay = (day)=>{    \n    const w_days = Object.keys(DaysOfWeek);\n    return (w_days[day - 1])? DaysOfWeek[w_days[day - 1]] : 'You enter a invalid day, try between 1 and 7'; \n} \n\nlog(DaysOfWeek.MONDAY); // Monday\nlog(showDay(3)) // Wednesday\n//Extra Dificulty Exercise\n\n//Enum simulation\nconst OrderStatus = {\n    PENDING: 'Pending',\n    SHIPPED: 'Shipped',\n    DELIVERED: 'Delivered',\n    CANCELED: 'Canceled'\n};\n\nObject.freeze(OrderStatus);\n\nclass Order{\n    constructor(id){\n        this.id = id;\n        this.state = OrderStatus.PENDING;\n    }\n\n    setState(state){\n        this.state = OrderStatus[state];\n    }\n\n    getState(){\n        return this.state;\n    }\n\n    shipOrder(){\n        if(this.state.toLowerCase() == OrderStatus.PENDING.toLowerCase()){\n            log('The order is Shipped');\n            this.setState('SHIPPED');\n        }else {\n            log(`Cannot ship. Current state: ${this.state}`);\n        }\n    }\n\n    deliverOrder(){\n        if(this.state.toLowerCase() == OrderStatus.SHIPPED.toLowerCase()){\n            log('The order is Delivered');\n            this.setState('DELIVERED');\n        }else{\n            log(`Cannot deliver. The order state is: ${this.state}`);\n        }\n    }\n\n    cancelOrder(){\n        if(this.state.toLowerCase() == OrderStatus.DELIVERED.toLowerCase()){\n            log('Cannot cancel. The order has already been delivered.')\n        }\n            log('The order is Canceled');\n            this.setState('CANCELED');\n        }\n\n        describeOrder() {\n            log(`Order ID: ${this.id}, Current State: ${this.state}`);\n        }\n    }\n\nlet order15 = new Order('001');\nlet order16 = new Order('002');\nlet order17 = new Order('003');\n\norder16.shipOrder(); // The order is Shipped\norder15.deliverOrder(); // Cannot Deliver. The order state is: Pending\norder17.shipOrder(); // The order is Shipped\n\norder16.deliverOrder(); // The order is Delivered\norder15.shipOrder(); // The order is Shipped\norder17.cancelOrder(); // The order is Canceled\n\nlog(order16.getState()); // Delivered\nlog(order15.getState()); // Shipped\nlog(order17.getState()); // Canceled\n\norder16.shipOrder() // Cannot ship. Current state: Delivered\n\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/javascript/edalmava.js",
    "content": "/* \n  El tipo Enumerado no existe en JavaScript\n*/\n\nconst diasSemana = ['Lunes', 'Martes', 'Miércoles', 'Jueves', 'Viernes', 'Sábado', 'Domingo']\nconst numerosValidos = [1, 2, 3, 4, 5, 6, 7]\n\nconst getDiaSemana = (numero) => numerosValidos.includes(numero)\n                                 ?diasSemana[numero - 1]\n                                 :diasSemana[numero % 7 - 1]\n\nfor (let i = 1; i <= 7; i++) console.log(getDiaSemana(i))\n\n/* Reto Extra */\n\nclass Pedido {\n    estadoPedido = {\n        'PENDIENTE': 'Pendiente', \n        'ENVIADO': 'Enviado', \n        'ENTREGADO': 'Entregado',\n        'CANCELADO': 'Cancelado'\n    }\n\n    constructor(id) {\n      this.estado = 'PENDIENTE'\n      this.id = id\n    }\n\n    enviarPedido() {\n      if (this.estado === 'PENDIENTE') {\n        this.estado = 'ENVIADO'        \n      } else {\n        return 'No se puede enviar el pedido'\n      } \n      return 'Pedido Enviado'\n    }\n\n    entregarPedido() {\n      if (this.estado === 'ENVIADO') {\n        this.estado = 'ENTREGADO'\n      } else {\n        return 'No se puede entregar un pedido que no se ha enviado'\n      }\n      return 'Pedido Entregado'\n    }\n\n    cancelarPedido() {\n        if (this.estado === 'ENTREGADO') {\n            return 'No se puede cancelar el pedido ya fue entregado'\n        } else {\n            this.estado = 'CANCELADO'\n            return 'Pedido Cancelado'\n        }\n    }\n\n    mostrarEstadoPedido() {\n      console.log(`Pedido ${this.id}: ${this.estadoPedido[this.estado]}`)\n    }\n}\n\n\n/* Creando Pedidos */\nconsole.log('\\n\\nCreando Pedidos')\n\nconst pedido1 = new Pedido(101)\nconst pedido2 = new Pedido(102)\nconst pedido3 = new Pedido(103)\n\npedido1.mostrarEstadoPedido()\npedido2.mostrarEstadoPedido()\npedido3.mostrarEstadoPedido()\n\n/* Modificando estado de los pedidos */\nconsole.log('')\nconsole.log('Interactuando con los pedidos')\n\nconsole.log(pedido1.enviarPedido())\nconsole.log(pedido2.entregarPedido())\nconsole.log(pedido3.cancelarPedido())\nconsole.log(pedido1.entregarPedido())\nconsole.log(pedido2.enviarPedido())\nconsole.log(pedido3.enviarPedido())\n\n/* Mostrar estado de los Pedidos tras interactuar */\nconsole.log('\\nEstado de los pedidos tras interactuar: ')\npedido1.mostrarEstadoPedido()\npedido2.mostrarEstadoPedido()\npedido3.mostrarEstadoPedido()"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/javascript/emedevelopa.js",
    "content": "/* Empleando tu lenguaje, explora la definición del tipo de dato\n * que sirva para definir enumeraciones (Enum).\n * Crea un Enum que represente los días de la semana del lunes\n * al domingo, en ese orden. Con ese enumerado, crea una operación\n * que muestre el nombre del día de la semana dependiendo del número entero\n * utilizado (del 1 al 7).*/\n\nconst dias = [\"Lunes\", \"Martes\", \"Miércoles\", \"Jueves\", \"Viernes\", \"Sábado\", \"Domingo\"];\n\nfunction diaDeLaSemana (numero) {\n    if (numero >= 1 && numero <= 7) {\n        return dias[numero - 1];\n    } else{\n        return \"Número no válido\"\n    }\n};\n\nconsole.log(diaDeLaSemana(7));\n\n/*DIFICULTAD EXTRA (opcional):\n * Crea un pequeño sistema de gestión del estado de pedidos.\n * Implementa una clase que defina un pedido con las siguientes características:\n * - El pedido tiene un identificador y un estado.\n * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n * - Implementa las funciones que sirvan para modificar el estado:\n *   - Pedido enviado\n *   - Pedido cancelado\n *   - Pedido entregado\n *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n * - Crea diferentes pedidos y muestra cómo se interactúa con ellos. \n */\n\nconst EstadoPedido = Object.freeze({\n    PENDIENTE: 'Pendiente',\n    ENVIADO: 'Enviado',\n    ENTREGADO: 'Entregado',\n    CANCELADO: 'Cancelado'\n});\n\nclass Pedido {\n    constructor(id) {\n        this.id = id;\n        this.estado = EstadoPedido.PENDIENTE; // Estado inicial\n    }\n\n    enviar() {\n        if (this.estado === EstadoPedido.PENDIENTE) {\n            this.estado = EstadoPedido.ENVIADO;\n        } else {\n            console.log(`No se puede enviar el pedido ${this.id}. Estado actual: ${this.estado}`);\n        }\n    }\n\n    entregar() {\n        if (this.estado === EstadoPedido.ENVIADO) {\n            this.estado = EstadoPedido.ENTREGADO;\n        } else {\n            console.log(`No se puede entregar el pedido ${this.id}. Estado actual: ${this.estado}`);\n        }\n    }\n\n    cancelar() {\n        if (this.estado === EstadoPedido.PENDIENTE || this.estado === EstadoPedido.ENVIADO) {\n            this.estado = EstadoPedido.CANCELADO;\n        } else {\n            console.log(`No se puede cancelar el pedido ${this.id}. Estado actual: ${this.estado}`);\n        }\n    }\n\n    mostrarEstado() {\n        return `El estado del pedido ${this.id} es el siguiente: ${this.estado}`;\n    }\n}\n\nconst pedido1 = new Pedido(1);\nconsole.log(pedido1.mostrarEstado()); // El estado del pedido 1 es el siguiente: Pendiente\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/javascript/eugeniasoria.js",
    "content": "/*\r\n# #19 ENUMERACIONES\r\n * EJERCICIO:\r\n * Empleando tu lenguaje, explora la definición del tipo de dato\r\n * que sirva para definir enumeraciones (Enum).\r\n * Crea un Enum que represente los días de la semana del lunes\r\n * al domingo, en ese orden. Con ese enumerado, crea una operación\r\n * que muestre el nombre del día de la semana dependiendo del número entero\r\n * utilizado (del 1 al 7).\r\n */\r\n\r\n//No existen los ENUM en javascript\r\nconst Semana = {\r\n  LUNES: 1,\r\n  MARTES: 2,\r\n  MIERCOLES: 3,\r\n  JUEVES: 4,\r\n  VIERNES: 5,\r\n  SABADO: 6,\r\n  DOMINGO: 7,\r\n};\r\nObject.freeze(Semana);\r\n\r\nconsole.log(Semana);\r\n\r\nfunction showDiaSemana(num) {\r\n  if (!num || num <=0 || num >7) {\r\n    return \"Error: El número debe ser del 1 al 7\";\r\n  }\r\n  return Object.keys(Semana)[num-1];\r\n}\r\nconsole.log(\"Día de la semana 0: \", showDiaSemana(0));\r\nconsole.log(\"Día de la semana 1: \", showDiaSemana(1));\r\nconsole.log(\"Día de la semana 3: \", showDiaSemana(3));\r\nconsole.log(\"Día de la semana 5: \", showDiaSemana(5));\r\nconsole.log(\"Día de la semana 8: \", showDiaSemana(8));\r\n\r\n/*\r\n* DIFICULTAD EXTRA (opcional):\r\n* Crea un pequeño sistema de gestión del estado de pedidos.\r\n* Implementa una clase que defina un pedido con las siguientes características:\r\n* - El pedido tiene un identificador y un estado.\r\n* - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\r\n* - Implementa las funciones que sirvan para modificar el estado:\r\n*   - Pedido enviado\r\n*   - Pedido cancelado\r\n*   - Pedido entregado\r\n*   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\r\n* - Implementa una función para mostrar un texto descriptivo según el estado actual.\r\n* - Crea diferentes pedidos y muestra cómo se interactúa con ellos. \r\n*/\r\n\r\nconsole.log(\"\\n\\n* DIFICULTAD EXTRA (opcional):\")\r\n\r\nconst EstadoPedido = {\r\n  PENDIENTE: 1,\r\n  ENVIADO: 2,\r\n  ENTREGADO: 3,\r\n  CANCELADO: 4,\r\n};\r\n\r\nconsole.log(EstadoPedido);\r\n\r\nfunction obtenerEstadoPedido(num) {\r\n  if (!num || num <=0 || num >4) {\r\n    return \"Error: El número debe0 ser del 1 al 4\";\r\n}\r\n  return Object.keys(EstadoPedido)[num-1];\r\n}\r\n\r\nlet pedidoA = { id: 1, estado: 1}\r\nlet pedidoB = { id: 2, estado: 2}\r\nlet pedidoC = { id: 2, estado: 4}\r\n\r\nconsole.log(\"El pedidoA está en estado: \", obtenerEstadoPedido(pedidoA.estado));\r\nconsole.log(\"El pedidoB está en estado: \", obtenerEstadoPedido(pedidoB.estado));\r\nconsole.log(\"El pedidoC está en estado: \", obtenerEstadoPedido(pedidoC.estado));\r\n\r\nfunction modificarEstadoPedido(pedido, nuevoEstado) {\r\n  if (pedido.estado == 2 && nuevoEstado == 4) {\r\n    console.log('No se puede cambiar el estado de un pedido ENVIADO a CANCELADO');\r\n    return;\r\n  }\r\n  if (pedido.estado == 4 && nuevoEstado == 2) {\r\n    console.log('No se puede cambiar el estado de un pedido CANCELADO a ENVIADO');\r\n    return;\r\n  }\r\n  pedido.estado = nuevoEstado;\r\n}\r\nconsole.log('\\nCambiar pedidoA a estado CANCELADO');\r\nmodificarEstadoPedido(pedidoA, 4);\r\nconsole.log(\"El pedidoA está ahora en estado: \", obtenerEstadoPedido(pedidoA.estado));\r\n\r\nconsole.log('\\nCambiar pedidoB a estado CANCELADO');\r\nmodificarEstadoPedido(pedidoB, 4);\r\nconsole.log(\"El pedidoB está ahora en estado: \", obtenerEstadoPedido(pedidoB.estado));\r\n\r\nconsole.log('\\nCambiar pedidoC a estado ENVIADO');\r\nmodificarEstadoPedido(pedidoC, 2);\r\nconsole.log(\"El pedidoC está ahora en estado: \", obtenerEstadoPedido(pedidoC.estado));"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/javascript/eulogioep.js",
    "content": "/**\n * TEORÍA SOBRE ENUMERACIONES EN JAVASCRIPT\n *\n * JavaScript no tiene un tipo de dato nativo para enumeraciones como Java,\n * pero hay varias formas de implementarlas:\n *\n * 1. Usando Object.freeze() para crear objetos inmutables\n * 2. Utilizando símbolos (Symbol)\n * 3. Creando clases con getters\n *\n * En este ejercicio, usaremos Object.freeze() para crear enumeraciones\n * similares a las que encontraríamos en otros lenguajes.\n */\n\n// Enumeración para los días de la semana\nconst DiaSemana = Object.freeze({\n  LUNES: 1,\n  MARTES: 2,\n  MIERCOLES: 3,\n  JUEVES: 4,\n  VIERNES: 5,\n  SABADO: 6,\n  DOMINGO: 7,\n\n  // Método para obtener el nombre del día por número\n  obtenerNombre(numero) {\n    const dias = Object.entries(this).find(([_, value]) => value === numero);\n    return dias ? dias[0] : \"Número inválido. Debe estar entre 1 y 7.\";\n  },\n});\n\n// Enumeración para los estados de un pedido\nconst EstadoPedido = Object.freeze({\n  PENDIENTE: \"PENDIENTE\",\n  ENVIADO: \"ENVIADO\",\n  ENTREGADO: \"ENTREGADO\",\n  CANCELADO: \"CANCELADO\",\n});\n\n// Clase para gestionar pedidos\nclass Pedido {\n  constructor(id) {\n    this.id = id;\n    this.estado = EstadoPedido.PENDIENTE;\n  }\n\n  // Método para enviar el pedido\n  enviarPedido() {\n    if (this.estado === EstadoPedido.PENDIENTE) {\n      this.estado = EstadoPedido.ENVIADO;\n      return true;\n    }\n    return false;\n  }\n\n  // Método para cancelar el pedido\n  cancelarPedido() {\n    if (\n      this.estado === EstadoPedido.PENDIENTE ||\n      this.estado === EstadoPedido.ENVIADO\n    ) {\n      this.estado = EstadoPedido.CANCELADO;\n      return true;\n    }\n    return false;\n  }\n\n  // Método para entregar el pedido\n  entregarPedido() {\n    if (this.estado === EstadoPedido.ENVIADO) {\n      this.estado = EstadoPedido.ENTREGADO;\n      return true;\n    }\n    return false;\n  }\n\n  // Método para obtener descripción del estado\n  obtenerDescripcionEstado() {\n    switch (this.estado) {\n      case EstadoPedido.PENDIENTE:\n        return `El pedido ${this.id} está pendiente de envío.`;\n      case EstadoPedido.ENVIADO:\n        return `El pedido ${this.id} ha sido enviado y está en camino.`;\n      case EstadoPedido.ENTREGADO:\n        return `El pedido ${this.id} ha sido entregado con éxito.`;\n      case EstadoPedido.CANCELADO:\n        return `El pedido ${this.id} ha sido cancelado.`;\n    }\n  }\n}\n\n// Función principal para probar la funcionalidad\nfunction main() {\n  console.log(\"=== PRUEBA DE DÍAS DE LA SEMANA ===\");\n  for (let i = 1; i <= 7; i++) {\n    console.log(`Día ${i}: ${DiaSemana.obtenerNombre(i)}`);\n  }\n\n  console.log(\"\\n=== PRUEBA DE GESTIÓN DE PEDIDOS ===\");\n\n  const pedido1 = new Pedido(1);\n  const pedido2 = new Pedido(2);\n\n  // Mostrar estado inicial\n  console.log(pedido1.obtenerDescripcionEstado());\n\n  // Enviar pedido1\n  pedido1.enviarPedido();\n  console.log(pedido1.obtenerDescripcionEstado());\n\n  // Intentar entregar pedido2 (debería fallar)\n  if (!pedido2.entregarPedido()) {\n    console.log(\"No se puede entregar el pedido 2 porque no ha sido enviado.\");\n  }\n\n  // Entregar pedido1\n  pedido1.entregarPedido();\n  console.log(pedido1.obtenerDescripcionEstado());\n\n  // Cancelar pedido2\n  pedido2.cancelarPedido();\n  console.log(pedido2.obtenerDescripcionEstado());\n}\n\n// Ejecutar el programa\nmain();\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/javascript/garos01.js",
    "content": "const DaysOfWeek = {\n  Monday: 1,\n  Tuesday: 2,\n  Wednesday: 3,\n  Thursday: 4,\n  Friday: 5,\n  Saturday: 6,\n  Sunday: 7,\n};\n\nfunction getDayName(dayNumber) {\n  switch (dayNumber) {\n    case DaysOfWeek.Monday:\n      return \"Monday\";\n    case DaysOfWeek.Tuesday:\n      return \"Tuesday\";\n    case DaysOfWeek.Wednesday:\n      return \"Wednesday\";\n    case DaysOfWeek.Thursday:\n      return \"Thursday\";\n    case DaysOfWeek.Friday:\n      return \"Friday\";\n    case DaysOfWeek.Saturday:\n      return \"Saturday\";\n    case DaysOfWeek.Sunday:\n      return \"Sunday\";\n    default:\n      return \"Invalid day number\";\n  }\n}\n\nconsole.log(getDayName(1));\nconsole.log(getDayName(3));\nconsole.log(getDayName(7));\nconsole.log(getDayName(8));\n\n// Ejercicio extra\n\n// Definición del \"enum\" para los estados del pedido\nconst OrderStatus = {\n  PENDING: \"Pendiente\",\n  SHIPPED: \"Enviado\",\n  DELIVERED: \"Entregado\",\n  CANCELED: \"Cancelado\",\n};\n\nclass Order {\n  constructor(id) {\n    this.id = id;\n    this.status = OrderStatus.PENDING;\n  }\n\n  // Método para enviar el pedido\n  shipOrder() {\n    if (this.status === OrderStatus.PENDING) {\n      this.status = OrderStatus.SHIPPED;\n      console.log(`Pedido ${this.id} ha sido enviado.`);\n    } else {\n      console.log(\n        `Pedido ${this.id} no se puede enviar. Estado actual: ${this.status}.`\n      );\n    }\n  }\n\n  // Método para cancelar el pedido\n  cancelOrder() {\n    if (this.status === OrderStatus.PENDING) {\n      this.status = OrderStatus.CANCELED;\n      console.log(`Pedido ${this.id} ha sido cancelado.`);\n    } else {\n      console.log(\n        `Pedido ${this.id} no se puede cancelar. Estado actual: ${this.status}.`\n      );\n    }\n  }\n\n  // Método para entregar el pedido\n  deliverOrder() {\n    if (this.status === OrderStatus.SHIPPED) {\n      this.status = OrderStatus.DELIVERED;\n      console.log(`Pedido ${this.id} ha sido entregado.`);\n    } else {\n      console.log(\n        `Pedido ${this.id} no se puede entregar. Estado actual: ${this.status}.`\n      );\n    }\n  }\n\n  // Método para obtener la descripción del estado actual\n  getStatusDescription() {\n    return `El estado actual del pedido ${this.id} es: ${this.status}.`;\n  }\n}\n\n// Crear algunos pedidos y mostrar cómo interactuar con ellos\nconst order1 = new Order(1);\nconsole.log(order1.getStatusDescription());\n\norder1.shipOrder();\nconsole.log(order1.getStatusDescription());\n\norder1.deliverOrder();\nconsole.log(order1.getStatusDescription());\n\nconst order2 = new Order(2);\nconsole.log(order2.getStatusDescription());\n\norder2.cancelOrder();\nconsole.log(order2.getStatusDescription());\n\norder2.deliverOrder();\nconsole.log(order2.getStatusDescription());\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/javascript/hectorio23.js",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23 \n\"use strict\";\n\n// Definición del Enum para los días de la semana\nconst Week = {\n    LUNES: 1,\n    MARTES: 2,\n    MIERCOLES: 3,\n    JUEVES: 4,\n    VIERNES: 5,\n    SABADO: 6,\n    DOMINGO: 7\n};\n\n// Función para mostrar el nombre del día de la semana\nconst getNameWeek = numeroDia => {\n    switch(numeroDia) {\n        case Week.LUNES:\n            return \"Lunes\";\n        case Week.MARTES:\n            return \"Martes\";\n        case Week.MIERCOLES:\n            return \"Miércoles\";\n        case Week.JUEVES:\n            return \"Jueves\";\n        case Week.VIERNES:\n            return \"Viernes\";\n        case Week.SABADO:\n            return \"Sábado\";\n        case Week.DOMINGO:\n            return \"Domingo\";\n        default:\n            return \"Número de día inválido\";\n    }\n}\n\n// Ejemplo de uso\nconsole.log(\"************ EJERCICIO ***************\");\nconst day = 4;\nconsole.log(`El día ${ day } es: ${ getNameWeek(day) }`);\n\nconsole.log(\"\\n************ EJERCICIO EXTRA ***************\");\n\n// Definición del Enum para los estados de pedido\nconst EstadoPedido = {\n    PENDIENTE: 1,\n    ENVIADO: 2,\n    ENTREGADO: 3,\n    CANCELADO: 4\n};\n\n// Clase Pedido\nclass Pedido {\n    constructor(_id) {\n        this.id = _id;\n        this.estado = EstadoPedido.PENDIENTE;\n    }\n\n    // Método para marcar el pedido como enviado\n    marcarEnviado() {\n        if (this.estado === EstadoPedido.PENDIENTE) {\n            this.estado = EstadoPedido.ENVIADO;\n            console.log(`El pedido con ID ${ this.id } ha sido enviado.`);\n        } else {\n            console.log(`El pedido con ID ${ this.id } no se puede enviar en su estado actual.`);\n        }\n    }\n\n    // Método para marcar el pedido como entregado\n    marcarEntregado() {\n        if (this.estado === EstadoPedido.ENVIADO) {\n            this.estado = EstadoPedido.ENTREGADO;\n            console.log(`El pedido con ID ${ this.id } ha sido entregado.`);\n        } else {\n            console.log(`El pedido con ID ${ this.id } no se puede entregar en su estado actual.`);\n        }\n    }\n\n    // Método para cancelar el pedido\n    cancelarPedido() {\n        if (this.estado !== EstadoPedido.CANCELADO) {\n            this.estado = EstadoPedido.CANCELADO;\n            console.log(`El pedido con ID ${ this.id } ha sido cancelado.`);\n        } else {\n            console.log(`El pedido con ID ${ this.id } ya está cancelado.`);\n        }\n    }\n\n    // Método para mostrar el estado del pedido\n    mostrarEstado() {\n        const estado_str = {\n            [EstadoPedido.PENDIENTE]: \"Pendiente\",\n            [EstadoPedido.ENVIADO]: \"Enviado\",\n            [EstadoPedido.ENTREGADO]: \"Entregado\",\n            [EstadoPedido.CANCELADO]: \"Cancelado\"\n        };\n        console.log(`Estado del pedido con ID ${ this.id }: ${ estado_str[this.estado] }`);\n    }\n}\n\n// Creando pedidos\nconst pedido1 = new Pedido(1);\nconst pedido2 = new Pedido(2);\n\n// Mostrar el estado inicial de los pedidos\npedido1.mostrarEstado();\npedido2.mostrarEstado();\n\n// Interactuar con los pedidos\npedido1.marcarEnviado();\npedido2.marcarEnviado();\npedido1.marcarEntregado();\npedido2.cancelarPedido();\n\n// Mostrar el estado final de los pedidos\npedido1.mostrarEstado();\npedido2.mostrarEstado();\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n_______________________________________\n#19 ENUMERACIONES\n---------------------------------------\n * EJERCICIO:\n * Empleando tu lenguaje, explora la definición del tipo de dato\n * que sirva para definir enumeraciones (Enum).\n * Crea un Enum que represente los días de la semana del lunes\n * al domingo, en ese orden. Con ese enumerado, crea una operación\n * que muestre el nombre del día de la semana dependiendo del número entero\n * utilizado (del 1 al 7).\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un pequeño sistema de gestión del estado de pedidos.\n * Implementa una clase que defina un pedido con las siguientes características:\n * - El pedido tiene un identificador y un estado.\n * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n * - Implementa las funciones que sirvan para modificar el estado:\n *   - Pedido enviado\n *   - Pedido cancelado\n *   - Pedido entregado\n *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n * - Crea diferentes pedidos y muestra cómo se interactúa con ellos.\n*/\n// ________________________________________________________\n\nconst Weekday = Object.freeze({\n    MONDAY: 1,\n    TUESDAY: 2,\n    WEDNESDAY: 3,\n    THURSDAY: 4,\n    FRIDAY: 5,\n    SATURDAY: 6,\n    SUNDAY: 7,\n});\n\nfunction getDay(num) {\n    for (const [key, value] of Object.entries(Weekday)) {\n        if (value === num) {\n            return key;\n        }\n    }\n    return \"'o'\";\n}\n\nfunction getNumDay(day) {\n    return Weekday[day] || 0;\n}\n\nconsole.log(getDay(7)); // SUNDAY\nconsole.log(getDay(3)); // WEDNESDAY\nconsole.log(getDay(8)); // 'o'\n\nconsole.log(getNumDay(\"TUESDAY\")); // 2\nconsole.log(getNumDay(\"FRIDAY\")); // 5\nconsole.log(getNumDay(\"abc\")); // 0\n\n// ________________________________________________________\n// DIFICULTAD EXTRA\n\nconsole.log(\"\\nEJERCICIO 2:\");\n\n// Enum para el estado de pedidos\nconst Status = Object.freeze({\n    PENDING: 1,\n    SHIPPED: 2,\n    DELIVERED: 3,\n    CANCELED: 4,\n});\n\nclass Order {\n    constructor(identifier) {\n        this.identifier = identifier;\n        this._status = Status.PENDING;\n    }\n\n    send() {\n        console.log(\"\\nEnviar:\");\n        if (this._status === Status.PENDING) {\n            this._status = Status.SHIPPED;\n            console.log(this.info());\n        } else {\n            console.log(`Operación inválida:`, this.info());\n        }\n    }\n\n    cancel() {\n        console.log(\"\\nCancelar:\");\n        if (this._status === Status.PENDING) {\n            this._status = Status.CANCELED;\n            console.log(this.info());\n        } else {\n            console.log(`Operación inválida:`, this.info());\n        }\n    }\n\n    deliver() {\n        console.log(\"\\nEntregar:\");\n        if (this._status === Status.SHIPPED) {\n            this._status = Status.DELIVERED;\n            console.log(this.info());\n        } else {\n            console.log(`Operación inválida:`, this.info());\n        }\n    }\n\n    info() {\n        const statusName = Object.keys(Status).find(\n            key => Status[key] === this._status\n        );\n        return `${this.identifier} -> ${statusName}`;\n    }\n}\n\nconst libro1 = new Order(\"libro1\");\nconst libro2 = new Order(\"libro2\");\nconst libro3 = new Order(\"libro3\");\n\nconsole.log(\"\\n-----\\nOperaciones exitosas:\\n-----\");\nlibro1.send();\nlibro1.deliver();\nlibro2.cancel();\n\nconsole.log(\"\\n-----\\nOperaciones inválidas:\\n-----\");\nlibro3.deliver();\nlibro2.cancel();\nlibro1.send();\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/javascript/manjaitan.js",
    "content": "\nlet day = 0;\n\nconst DiasDeLaSemana = {\n\n   LUNES: 1,\n   MARTES: 2,\n   MIERCOLES: 3,\n   JUEVES: 4,\n   VIERNES: 5,  \n   SABADO: 6,\n   DOMINGO: 7, \n\n}\n\nfunction greetdia(day) {\n  \n    if (day === DiasDeLaSemana.LUNES) {\n        console.log('Se ha seleccionado el día Lunes');\n    }  else if (day === DiasDeLaSemana.MARTES) {\n        console.log('Se ha seleccionado el día Martes');\n    } else if (day === DiasDeLaSemana.MIERCOLES) {\n        console.log('Se ha seleccionado el día Miercoles');\n    } else if (day === DiasDeLaSemana.JUEVES) {\n        console.log('Se ha seleccionado el día Jueves');\n    } else if (day === DiasDeLaSemana.VIERNES) {\n        console.log('Se ha seleccionado el día Viernes');\n    } else if (day === DiasDeLaSemana.SABADO) {\n        console.log('Se ha seleccionado el día Sabado');\n    } else if (day === DiasDeLaSemana.DOMINGO) {\n        console.log('Se ha seleccionado el día Domingo');\n    }\n    else \n        {\n        console.log('Dia seleccionado erróneo, rango de datos insertables del 1 al 7,')\n        };\n\n }\n\n\ngreetdia(7)"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/javascript/nlarrea.js",
    "content": "/*\n * EJERCICIO:\n * Empleando tu lenguaje, explora la definición del tipo de dato\n * que sirva para definir enumeraciones (Enum).\n * Crea un Enum que represente los días de la semana del lunes\n * al domingo, en ese orden. Con ese enumerado, crea una operación\n * que muestre el nombre del día de la semana dependiendo del número entero\n * utilizado (del 1 al 7).\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un pequeño sistema de gestión del estado de pedidos.\n * Implementa una clase que defina un pedido con las siguientes características:\n * - El pedido tiene un identificador y un estado.\n * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n * - Implementa las funciones que sirvan para modificar el estado:\n *   - Pedido enviado\n *   - Pedido cancelado\n *   - Pedido entregado\n *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n * - Crea diferentes pedidos y muestra cómo se interactúa con ellos. \n */\n\n\n// In JS there are no Enums -> we create one\nclass Enum {\n    object = {};\n\n    add(key, value) {\n        this.object[key] = value;\n    }\n\n    getById(valueId) {\n        const keys = Object.keys(this.object);\n        if (typeof keys[valueId - 1] === 'undefined') {\n            throw new Error('Value Not Found');\n        }\n\n        return keys[valueId - 1];\n    }\n}\n\n\nclass WeekDay extends Enum {\n    constructor () {\n        super();\n    }\n\n    object = {\n        MONDAY: 1,\n        TUESDAY: 2,\n        WEDNESDAY: 3,\n        THURSDAY: 4,\n        FRIDAY: 5,\n        SATURDAY: 6,\n        SUNDAY: 7\n    };\n};\n    \n\nconst weekdays = new WeekDay();\nconsole.log(weekdays.getById(5));  // friday\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea un pequeño sistema de gestión del estado de pedidos.\n * Implementa una clase que defina un pedido con las siguientes características:\n * - El pedido tiene un identificador y un estado.\n * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n * - Implementa las funciones que sirvan para modificar el estado:\n *   - Pedido enviado\n *   - Pedido cancelado\n *   - Pedido entregado\n *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n * - Crea diferentes pedidos y muestra cómo se interactúa con ellos. \n */\n\n\nclass OrderStatus extends Enum {\n    constructor () {\n        super();\n    }\n\n    object = {\n        PENDING: 1,\n        SHIPPED: 2,\n        DELIVERED: 3,\n        CANCELED: 4\n    }\n};\n\n\nclass Order {\n    constructor (orderId) {\n        this.orderId = orderId;\n        this.state = new OrderStatus().getById(1);\n\n        console.log(`\\nThe order '${this.orderId}' is ${this.state}`);\n    };\n\n    updateState() {\n        if (this.state == 'CANCELED' || this.state == 'DELIVERED') {\n            // If order is canceled or delivered -> maintain the state as it is\n            return;\n        } else if (this.state == 'PENDING') {\n            this.state = new OrderStatus().getById(2);\n        } else if (this.state == 'SHIPPED') {\n            this.state = new OrderStatus().getById(3);\n        }\n    }\n\n    cancelOrder() {\n        if (this.state != 'DELIVERED') {\n            this.state = new OrderStatus().getById(4);\n        }\n    }\n\n    printCurrentState() {\n        console.log(`The order '${this.orderId}' is ${this.state}`);\n    }\n}\n\nconst order1 = new Order('1234');  // The order '1234' is PENDING\norder1.updateState();\norder1.printCurrentState();  // shipped\norder1.updateState();\norder1.printCurrentState();  // delivered\norder1.cancelOrder();  // it won't work because it's delivered already\norder1.printCurrentState();  // delivered\n\nconst order2 = new Order(\"5678\");  // pending\norder2.updateState();\norder2.printCurrentState();  // shipped\norder2.cancelOrder();\norder2.printCurrentState();  // canceled\norder2.updateState();  // it won't work because it's canceled\norder2.printCurrentState();  // canceled\n\nconst order3 = new Order(\"1290\");  // pending\norder3.cancelOrder();\norder3.printCurrentState();  // canceled\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/javascript/parababire.js",
    "content": "/* Enumeraciones no existen como un tipo de valor especìfico en Javascript. Son objetos que nos permiten disponer diferentes opciones sobre un mismo elemento */\n\n/* Generalmente se desea que las enumeraciones no cambien; entonces, usamos Object.freeze() para lograrlo */\n\nconst WEEKDAYS = Object.freeze({\n  Monday: \"Monday\",\n  Tuesday: \"Tuesday\",\n  Wednesday: \"Wednesday\",\n  Thursday: \"Thursday\",\n  Friday: \"Friday\",\n  Saturday: \"Saturday\",\n  Sunday: \"Sunday\"\n});\n\nfunction getWeekdays(num) {\n  switch (num) {\n    case 1:\n      console.log(WEEKDAYS.Monday);\n      break;\n    case 2:\n      console.log(WEEKDAYS.Tuesday);\n      break;\n    case 3:\n      console.log(WEEKDAYS.Wednesday);\n      break;\n    case 4:\n      console.log(WEEKDAYS.Thursday);\n      break;\n    case 5:\n      console.log(WEEKDAYS.Friday);\n      break;\n    case 6:\n      console.log(WEEKDAYS.Saturday);\n      break;\n    case 7:\n      console.log(WEEKDAYS.Sunday);\n      break;\n    default:\n      console.log(\"Requerimiento inválido\");\n      break;\n  }\n}\n\ngetWeekdays(1);\n\n//Extra\n\nconst ORDER_STATUS = Object.freeze({\n  Pending: \"Pending\",\n  Shipped: \"Shipped\",\n  Delivered: \"Delivered\",\n  Cancelled: \"Cancelled\"\n});\n\nclass ORDER {\n  status = ORDER_STATUS.Pending;\n  constructor(id) {\n    this.id = id;\n  }\n  display_status() {\n    console.log(`El estado de la orden es: ${this.status}`); \n  }\n  shipped() {\n    if (this.status == ORDER_STATUS.Pending) {\n      this.status = ORDER_STATUS.Shipped;\n      this.display_status();\n    } else {\n      console.log(\"El pedido ya ha sido enviado o cancelado.\");\n    }\n  }\n  delivered() {\n    if (this.status == ORDER_STATUS.Shipped) {\n      this.status = ORDER_STATUS.Delivered;\n      this.display_status();\n    } else {\n      console.log(\"El pedido necesita ser enviado antes de entregarse.\");\n    }\n  }\n  cancelled() {\n    if (this.status != ORDER_STATUS.Delivered) {\n      this.status = ORDER_STATUS.Cancelled;\n      this.display_status();\n    } else {\n      console.log(\"El pedido no se puede cancelar ya que fue entregado.\");\n    }\n  }\n}\n\nlet pedido = new ORDER(2);\npedido.display_status();\npedido.delivered();\npedido.shipped();\npedido.delivered();\npedido.cancelled();"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/javascript/pedamoci.js",
    "content": "const Semana = Object.freeze({\n  LUNES: 'LUNES',\n  MARTES: 'MARTES',\n  MIERCOLES: 'MIERCOLES',\n  JUEVES: 'JUEVES',\n  VIERNES: 'VIERNES',\n  SABADO: 'SABADO',\n  DOMINGO: 'DOMINGO'\n})\n\nfunction diaDeLaSemana(num) {\n  if (num > 7) num %= 7\n  switch (num) {\n    case 1: return(Semana.LUNES);\n    case 2: return(Semana.MARTES);\n    case 3: return(Semana.MIERCOLES);\n    case 4: return(Semana.JUEVES);\n    case 5: return(Semana.VIERNES);\n    case 6: return(Semana.SABADO);\n    default: return(Semana.DOMINGO);\n  }\n}\n\nconsole.log(diaDeLaSemana(15))\nconsole.log(diaDeLaSemana(2))\nconsole.log(diaDeLaSemana(24))\nconsole.log(diaDeLaSemana(53))\nconsole.log(diaDeLaSemana(6))\nconsole.log(diaDeLaSemana(49))\n// --------------------------------- DIFICULTAD EXTRA ---------------------------------\nconst Estado = Object.freeze({\n  PENDIENTE: 'PENDIENTE',\n  ENVIADO: 'ENVIADO',\n  ENTREGADO: 'ENTREGADO',\n  CANCELADO: 'CANCELADO'\n})\n\nclass Pedido {\n  constructor(id) {\n    this.id = id\n    this.estado = 'CREADO'\n  }\n\n  cambiarEstado(estado) {\n    switch (estado) {\n      case Estado.PENDIENTE:\n        (this.estado === 'CREADO') ? console.log(`Se ha cambiado el estado de su pedido a: ${this.estado = Estado.PENDIENTE}`)\n                                    : console.log(`No se podido cambiar el estado a pendiente, el estado de su pedido es: ${this.estado}`)\n        break;\n      case Estado.ENVIADO:\n        (this.estado === Estado.PENDIENTE) ? console.log(`Se ha cambiado el estado de su pedido a: ${this.estado = Estado.ENVIADO}`)\n                                            : console.log(`No se podido cambiar el estado a enviado, el estado de su pedido es: ${this.estado}`)\n        break;\n      case Estado.ENTREGADO:\n        (this.estado === Estado.ENVIADO) ? console.log(`Se ha cambiado el estado de su pedido a: ${this.estado = Estado.ENTREGADO}`)\n                                          : console.log(`No se podido cambiar el estado a entregado, el estado de su pedido es: ${this.estado}`)\n        break;\n      case Estado.CANCELADO:\n        (this.estado === Estado.ENTREGADO || this.estado === Estado.CANCELADO) ? console.log('No se ha podido cancelar su pedido')\n        : (this.estado !== Estado.ENVIADO) ? console.log(`Su pedido se ha ${this.estado = Estado.CANCELADO}`) // se cancela si esta en estado pendiente o creado\n                                              : console.log(`Su pepido se ha ${this.estado = Estado.CANCELADO} el repartidor tuvo un accidente`)\n        break;\n      default:\n        console.log('El estado solicitado para el pedido no existe')\n        break;\n    }\n  }\n\n  estadoActual() {\n    switch (this.estado) {\n      case Estado.PENDIENTE:\n        console.log('Su pedido esta pendiente seguramente dentro de unos minutos sera enviado')\n        break;\n      case Estado.ENVIADO:\n        console.log('Su pedido ya ha sido enviado, en unos minutos le llegara\\n¡Esperamos que lo disfrute!')\n        break;\n      case Estado.ENTREGADO:\n        console.log('El pedido ha sido entregado\\nDeje un comentario de como fue su experiencia')\n        break;\n      case Estado.CANCELADO:\n        console.log('Ups su pedido esta cancelado, esperemos que no pase la proxima ;)')\n        break;\n      default:\n        console.log('El pedido se ha creado con exito, dentro de unos minutos ya estara pendiente')\n        break;\n    }\n  }\n}\n\nconst pedidoEntregado = new Pedido(159753)\npedidoEntregado.cambiarEstado(Estado.PENDIENTE)\npedidoEntregado.cambiarEstado(Estado.ENVIADO)\npedidoEntregado.cambiarEstado(Estado.ENTREGADO)\nconsole.log('\\n')\nconst pedidoCancelado = new Pedido(159753)\npedidoCancelado.cambiarEstado(Estado.PENDIENTE)\npedidoCancelado.cambiarEstado(Estado.ENVIADO)\npedidoCancelado.cambiarEstado(Estado.CANCELADO)\npedidoCancelado.estadoActual()\nconsole.log('\\n')\nconst pedidoVerEstados = new Pedido(159753)\npedidoVerEstados.estadoActual()\npedidoVerEstados.cambiarEstado(Estado.PENDIENTE)\npedidoVerEstados.estadoActual()\npedidoVerEstados.cambiarEstado(Estado.ENVIADO)\npedidoVerEstados.estadoActual()\npedidoVerEstados.cambiarEstado(Estado.ENTREGADO)\npedidoVerEstados.estadoActual()\nconsole.log('\\n')\nconst pedidoCambiarMalEstados = new Pedido(159753)\npedidoCambiarMalEstados.cambiarEstado(Estado.PENDIENTE)\npedidoCambiarMalEstados.cambiarEstado(Estado.ENTREGADO)\npedidoCambiarMalEstados.cambiarEstado(Estado.ENVIADO)"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/javascript/victor-Casta.js",
    "content": "/*\n  * Empleando tu lenguaje, explora la definición del tipo de dato\n  * que sirva para definir enumeraciones (Enum).\n  * Crea un Enum que represente los días de la semana del lunes\n  * al domingo, en ese orden. Con ese enumerado, crea una operación\n  * que muestre el nombre del día de la semana dependiendo del número entero\n  * utilizado (del 1 al 7).\n*/\n\nconst DAYS_OF_WEEK = Object.freeze({\n  'Monday': 1,\n  'Tuesday': 2,\n  'Wednesday': 3,\n  'Thursday': 4,\n  'Friday': 5,\n  'Saturday': 6,\n  'Sunday': 7\n})\n\nfunction getDay(numberOfDay) {\n  let value\n  for (let item in DAYS_OF_WEEK) {\n    if (DAYS_OF_WEEK[item] === numberOfDay) {\n      value = item\n    }\n  }\n  return value\n}\n\nconsole.log(getDay(1))\n\n/*\n  * DIFICULTAD EXTRA (opcional):\n  * Crea un pequeño sistema de gestión del estado de pedidos.\n  * Implementa una clase que defina un pedido con las siguientes características:\n  * - El pedido tiene un identificador y un estado.\n  * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n  * - Implementa las funciones que sirvan para modificar el estado:\n  *   - Pedido enviado\n  *   - Pedido cancelado\n  *   - Pedido entregado\n  *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n  * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n  * - Crea diferentes pedidos y muestra cómo se interactúa con ellos.\n*/\n\nconst ORDER_STATE = Object.freeze({\n  'SENT': 1,\n  'PENDING': 2,\n  'DELIVERED': 3,\n  'CANCELED': 4\n});\n\nclass ORDER {\n  constructor(id) {\n    this.id = id;\n    this.state = ORDER_STATE.PENDING;\n  }\n\n  shipped() {\n    if (this.state === ORDER_STATE.PENDING) {\n      this.state = ORDER_STATE.SENT;\n    }\n  }\n\n  delivered() {\n    if (this.state === ORDER_STATE.SENT) {\n      this.state = ORDER_STATE.DELIVERED;\n    }\n  }\n\n  canceled() {\n    if (this.state !== ORDER_STATE.SENT && this.state !== ORDER_STATE.DELIVERED && this.state !== ORDER_STATE.CANCELED) {\n      this.state = ORDER_STATE.CANCELED;\n    } else {\n      console.log('El pedido no se puede cancelar');\n    }\n  }\n\n  getStateName() {\n    return Object.entries(ORDER_STATE).find(([key, value]) => value === this.state)?.[0] || 'Estado desconocido';\n  }\n\n  viewState() {\n    const stateName = this.getStateName();\n    console.log(`El estado del pedido #${this.id} es ${stateName}`);\n  }\n}\n\nconst order1 = new ORDER(1);\norder1.viewState()\norder1.shipped()\norder1.viewState()\norder1.delivered()\norder1.viewState()\norder1.canceled()\norder1.viewState()\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/javascript/wapastorv.js",
    "content": "// ENUMS en JavaScript\n/*\nLos enums en JavaScript son una forma de crear un conjunto de constantes que pueden ser utilizadas en cualquier parte de nuestro código.\nlos enumeradores (enums) no existen como una característica nativa del lenguaje, pero podemos simularlos utilizando objetos o técnicas específicas.\n\n¿Cómo crear un ENUM en JavaScript?\nEn JavaScript, los ENUM se pueden implementar de varias formas. Aquí te muestro las más comunes:\n\n1. Usando un objeto:\nLa forma más sencilla de crear un ENUM es utilizando un objeto donde las claves son los nombres de las constantes y los valores son los valores asociados.\nPor ejemplo:\n*/\nconst DaysOfWeek = {\n    MONDAY: 'Monday',\n    TUESDAY: 'Tuesday',\n    WEDNESDAY: 'Wednesday',\n    THURSDAY: 'Thursday',\n    FRIDAY: 'Friday',\n    SATURDAY: 'Saturday',\n    SUNDAY: 'Sunday',\n  };\n  \nconsole.log(DaysOfWeek.MONDAY);\nconsole.log(DaysOfWeek.TUESDAY);\n\n/*\n2. Usando Object.freeze():\nPara evitar que el objeto sea modificado accidentalmente, puedes usar Object.freeze. Esto hace que el objeto sea inmutable.\n*/\nconst DaysOfWeek2 = Object.freeze({\n    MONDAY: 'Monday',\n    TUESDAY: 'Tuesday',\n    WEDNESDAY: 'Wednesday',\n    THURSDAY: 'Thursday',\n    FRIDAY: 'Friday',\n    SATURDAY: 'Saturday',\n    SUNDAY: 'Sunday',\n    });\nDaysOfWeek2.MONDAY = 'New Day'; // Esto no tendrá efecto\nconsole.log(DaysOfWeek2.MONDAY); // Output: Monday\n/*\n3. Usando Symbol para mayor seguridad\nLos símbolos son únicos y pueden ser útiles para evitar colisiones de nombres.\n*/\nconst Colors = Object.freeze({\n    RED: Symbol('red'),\n    GREEN: Symbol('green'),\n    BLUE: Symbol('blue'),\n  });\n  \nconsole.log(Colors.RED);\nconsole.log(Colors.RED.description); // Output: red\n\n/*\n4. Usando map:\nUn Map permite asignar valores personalizados sin perder flexibilidad\n*/\nconst UserRole = new Map([\n    [\"ADMIN\", { level: 3, canEdit: true, canDelete: true }],\n    [\"EDITOR\", { level: 2, canEdit: true, canDelete: false }],\n    [\"USER\", { level: 1, canEdit: false, canDelete: false }]\n  ]);\n  \n  // ✅ Uso del Enum\nconsole.log(UserRole.get(\"EDITOR\")); // { level: 2, canEdit: true, canDelete: false }\nconsole.log(UserRole.get(\"USER\").canEdit); // false\n\n\n/*\n * EJERCICIO:\n * Empleando tu lenguaje, explora la definición del tipo de dato\n * que sirva para definir enumeraciones (Enum).\n * Crea un Enum que represente los días de la semana del lunes\n * al domingo, en ese orden. Con ese enumerado, crea una operación\n * que muestre el nombre del día de la semana dependiendo del número entero\n * utilizado (del 1 al 7).\n */\n\n// Definimos un objeto con las constantes que necesitamos\nconst diasDeLaSemana = {\n    LUNES: 1,\n    MARTES: 2,\n    MIERCOLES: 3,\n    JUEVES: 4,\n    VIERNES: 5,\n    SABADO: 6,\n    DOMINGO: 7\n};\n\n// Utilizamos las constantes en nuestro código, por ejemplo:\n\nlet dia = diasDeLaSemana.LUNES;\nconsole.log(dia); // 1\n\n// Podemos utilizar un switch para hacer algo diferente dependiendo del valor de la constante:\nswitch (dia) {\n    case diasDeLaSemana.LUNES:\n        console.log('Hoy es Lunes');\n        break;\n    case diasDeLaSemana.MARTES:\n        console.log('Hoy es Martes');\n        break;\n    case diasDeLaSemana.MIERCOLES:\n        console.log('Hoy es Miércoles');\n        break;\n    case diasDeLaSemana.JUEVES:\n        console.log('Hoy es Jueves');\n        break;\n    case diasDeLaSemana.VIERNES:\n        console.log('Hoy es Viernes');\n        break;\n    case diasDeLaSemana.SABADO:\n        console.log('Hoy es Sábado');\n        break;\n    case diasDeLaSemana.DOMINGO:\n        console.log('Hoy es Domingo');\n        break;\n    default:\n        console.log('Día no válido');\n}\n\n// Podemos hacer un bucle para recorrer todas las constantes:\nfor (let dia in diasDeLaSemana) {\n    console.log(diasDeLaSemana[dia]);\n}\n\n// Podemos obtener el nombre de la constante a partir de su valor:\nfunction getDia(dia) {\n    for (let d in diasDeLaSemana) {\n        if (diasDeLaSemana[d] === dia) {\n            return d;\n        }\n    }\n    return null;\n}\n\nconsole.log(getDia(1)); // LUNES\n\nfunction obtenerNombreDelDia(valor){\n    const clave = Object.keys(diasDeLaSemana).find(key => diasDeLaSemana[key] === valor);\n    \n    return clave || 'No existe';\n}\n\nconsole.log(obtenerNombreDelDia(1)); // LUNES\nconsole.log(obtenerNombreDelDia(8)); // No existe\n\n\n/* DIFICULTAD EXTRA (opcional):\n* Crea un pequeño sistema de gestión del estado de pedidos.\n* Implementa una clase que defina un pedido con las siguientes características:\n* - El pedido tiene un identificador y un estado.\n* - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n* - Implementa las funciones que sirvan para modificar el estado:\n*   - Pedido enviado\n*   - Pedido cancelado\n*   - Pedido entregado\n*   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n* - Implementa una función para mostrar un texto descriptivo según el estado actual.\n* - Crea diferentes pedidos y muestra cómo se interactúa con ellos. \n*/\n\nconst estadosPedido = {\n    PENDIENTE: 1,\n    ENVIADO: 2,\n    ENTREGADO: 3,\n    CANCELADO: 4\n}\n\nclass Pedido {\n\n    constructor(id){\n        this.id = id;\n        this.estado = estadosPedido.PENDIENTE;\n    }\n\n    pedidoEnviado(){\n        if(this.estado === estadosPedido.PENDIENTE){\n            this.estado = estadosPedido.ENVIADO;\n        }\n        else{\n            console.log('El pedido no se puede enviar, ya ha sido enviado o cancelado');\n        }\n    }\n\n    pedidoEntregado(){\n        if(this.estado === estadosPedido.ENVIADO){\n            this.estado = estadosPedido.ENTREGADO;\n        }\n        else{\n            console.log('El pedido no se puede entregar, no ha sido enviado');\n        }\n    }\n\n    pedidoCancelado(){\n        if(this.estado != estadosPedido.ENTREGADO){\n            this.estado = estadosPedido.CANCELADO;\n        }\n        else{\n            console.log('El pedido no se puede cancelar ya se entrego');\n        }\n    }\n\n    mostrarEstado(){\n        let mensaje = '';\n        switch (this.estado) {\n            case estadosPedido.PENDIENTE:\n                mensaje = `El pedido ${this.id} está pendiente`;\n                break;\n            case estadosPedido.ENVIADO:\n                mensaje = `El pedido ${this.id} ha sido enviado`;\n                break;\n            case estadosPedido.ENTREGADO:\n                mensaje = `El pedido ${this.id} ha sido entregado`;\n                break;\n            case estadosPedido.CANCELADO:\n                mensaje = `El pedido ${this.id} ha sido cancelado`;\n                break;\n            default:\n                mensaje = 'Estado no válido';\n        }\n        console.log(mensaje);\n    }\n}\n\nconst pedido1 = new Pedido(1);\npedido1.mostrarEstado();\npedido1.pedidoEnviado();\npedido1.mostrarEstado();\npedido1.pedidoCancelado();\npedido1.mostrarEstado();\npedido1.pedidoEntregado();\npedido1.mostrarEstado();\nconsole.log('-------------------------');\nconst pedido2 = new Pedido(2);\npedido2.mostrarEstado();\npedido2.pedidoEntregado();\npedido2.mostrarEstado();\npedido2.pedidoCancelado();\npedido2.mostrarEstado();\npedido2.pedidoEnviado();\npedido2.mostrarEstado();\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/kotlin/blackriper.kt",
    "content": "import java.util.UUID\r\n\r\n/*\r\n Las Enumeraciones son un tipo de estructura que nos ayuda agrupar datos  los cuales rara vez cambian\r\n su valor por lo general son constantes.\r\n\r\n por ejemplo tenemos una opcion llamda direccion esta puede ser norte, sur ,oeste ,este\r\n si las evaluamos como  un  string este puede ser mayusculas o minusculas o incluso puede estar\r\n mal escrito. estas direcciones nuncan cambian asi que en un enum se resumira asi\r\n\r\n enum class Direccion{\r\n     NORTE,SUR,OESTE,ESTE\r\n }\r\n cada enum en kotlin  consta de un objeto y cada valor son  constantes separadas por comas\r\n\r\ngracias al enum evitamos errores por algun valor introducido y no es necesario escribir el\r\nvalor solo basta con poner Direccion.Norte esto indica que estamos usando el valor de norte\r\nlos enums en kotlin tiene varias aplicaciones para mas informacion.\r\n\r\nhttps://kotlinlang.org/docs/enum-classes.html\r\n\r\n*/\r\n\r\n// creamos el enum\r\nenum class WekendDay{\r\n  MONDAY,\r\n  TUESDAY,\r\n  WEDNESDAY,\r\n  THURSDAY,\r\n  FRIDAY,\r\n  SATURDAY,\r\n  SUNDAY\r\n}\r\n\r\n\r\n\r\nfun exampleWithEnums(numDay : Int){\r\n  when(numDay){\r\n      1 -> println(WekendDay.MONDAY)\r\n      2 -> println(WekendDay.TUESDAY)\r\n      3 -> println(WekendDay.WEDNESDAY)\r\n      4 -> println(WekendDay.THURSDAY)\r\n      5 -> println(WekendDay.FRIDAY)\r\n      6 -> println(WekendDay.SATURDAY)\r\n      7 -> println(WekendDay.SUNDAY)\r\n  }\r\n\r\n}\r\n\r\n// ejercicio extra\r\n\r\n// definir tipos de datos\r\n\r\nenum class State{\r\n  PENDING,SENDING,RECEIVED,CANCELED\r\n}\r\n\r\ndata class Order( val id: Int,var state : State){\r\n    fun showOrderState() = println(\"Order $id is $state\")\r\n}\r\n\r\ninterface OrderManager {\r\n    fun createOrder(order: Order)\r\n    fun updateState(id: Int, state: State)\r\n    fun showOrders()\r\n}\r\n\r\nclass OrderAdmin : OrderManager{\r\n    private var orders = mutableListOf<Order>()\r\n\r\n    override fun createOrder(order: Order) {\r\n        orders.add(order)\r\n    }\r\n\r\n    override fun updateState(id: Int, state: State) {\r\n        val order = orders.find { it.id == id }\r\n        if (order != null) {\r\n            if(validateOrder(order.state,state)){\r\n                order.state = state\r\n                order.showOrderState()\r\n            }else{\r\n                println(\"Order $id can not be updated to $state\")\r\n            }\r\n\r\n\r\n        }else{\r\n            println(\"Order not found\")\r\n        }\r\n    }\r\n\r\n    override fun showOrders() {\r\n        orders.forEach { println(\"Order ${it.id} is ${it.state}\") }\r\n    }\r\n\r\n}\r\n\r\nfun validateOrder(currentState: State, newState: State):Boolean{\r\n  // si la orden esta pediente no puede ser recibida\r\n  if (currentState ==State.PENDING && newState == State.RECEIVED) {\r\n      return false\r\n  }\r\n\r\n  // si la orden ya fue enviada no puede ser pendiente\r\n  if (currentState == State.SENDING && newState == State.PENDING){\r\n      return false\r\n  }\r\n\r\n  // si la orden ya fue recibida no puede ser enviada\r\n  if (currentState == State.RECEIVED && newState == State.SENDING){\r\n      return false\r\n  }\r\n\r\n  // si la orden ya fue cancelada no puede pasar a ningun otro estado\r\n  if (currentState==State.CANCELED){\r\n      return false\r\n  }\r\n\r\n  return true\r\n}\r\n\r\n\r\n\r\n\r\n\r\n\r\nfun main() {\r\n  exampleWithEnums(3)\r\n  val order1=Order(1,State.PENDING)\r\n  val order2=Order(2,State.SENDING)\r\n  val order3=Order(3,State.CANCELED)\r\n\r\n  val orderAdmin = OrderAdmin()\r\n  orderAdmin.createOrder(order1)\r\n  orderAdmin.createOrder(order2)\r\n  orderAdmin.createOrder(order3)\r\n\r\n  orderAdmin.updateState(1,State.SENDING)\r\n  orderAdmin.updateState(2,State.RECEIVED)\r\n  orderAdmin.updateState(3,State.RECEIVED)\r\n\r\n orderAdmin.showOrders()\r\n\r\n}\r\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/kotlin/eulogioep.kt",
    "content": "enum class EstadoPedido {\n    PENDIENTE, ENVIADO, ENTREGADO, CANCELADO\n}\n\nclass Pedido(val id: Int) {\n    var estado: EstadoPedido = EstadoPedido.PENDIENTE\n        private set\n\n    fun enviar() {\n        if (estado == EstadoPedido.PENDIENTE) {\n            estado = EstadoPedido.ENVIADO\n            println(\"Pedido $id enviado.\")\n        } else {\n            println(\"No se puede enviar el pedido $id. Estado actual: $estado\")\n        }\n    }\n\n    fun cancelar() {\n        if (estado != EstadoPedido.ENTREGADO) {\n            estado = EstadoPedido.CANCELADO\n            println(\"Pedido $id cancelado.\")\n        } else {\n            println(\"No se puede cancelar el pedido $id. Ya ha sido entregado.\")\n        }\n    }\n\n    fun entregar() {\n        if (estado == EstadoPedido.ENVIADO) {\n            estado = EstadoPedido.ENTREGADO\n            println(\"Pedido $id entregado.\")\n        } else {\n            println(\"No se puede entregar el pedido $id. Estado actual: $estado\")\n        }\n    }\n\n    fun mostrarEstado() {\n        val descripcion = when (estado) {\n            EstadoPedido.PENDIENTE -> \"El pedido está pendiente de envío.\"\n            EstadoPedido.ENVIADO -> \"El pedido ha sido enviado y está en camino.\"\n            EstadoPedido.ENTREGADO -> \"El pedido ha sido entregado con éxito.\"\n            EstadoPedido.CANCELADO -> \"El pedido ha sido cancelado.\"\n        }\n        println(\"Estado del pedido $id: $descripcion\")\n    }\n}\n\nfun main() {\n    val pedido1 = Pedido(1)\n    val pedido2 = Pedido(2)\n\n    pedido1.mostrarEstado()\n    pedido1.enviar()\n    pedido1.mostrarEstado()\n    pedido1.entregar()\n    pedido1.mostrarEstado()\n\n    println()\n\n    pedido2.mostrarEstado()\n    pedido2.cancelar()\n    pedido2.mostrarEstado()\n    pedido2.enviar()  // Esto no debería funcionar\n    pedido2.entregar()  // Esto no debería funcionar\n}"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/ocaml/luishendrix92.ml",
    "content": "open Printf\n\nlet today () =\n  Core.Date.today ~zone:Core.Time_float.Zone.utc |> Core.Date.to_string_american\n;;\n\nmodule Day : sig\n  type t\n\n  val of_int : int -> t\n  val show : t -> string\nend = struct\n  type t =\n    | Sunday\n    | Monday\n    | Tuesday\n    | Wednesday\n    | Thursday\n    | Friday\n    | Saturday\n  [@@deriving show { with_path = false }]\n\n  let of_int = function\n    | 1 -> Sunday\n    | 2 -> Monday\n    | 3 -> Tuesday\n    | 4 -> Wednesday\n    | 5 -> Thursday\n    | 6 -> Friday\n    | 7 -> Saturday\n    | _ -> raise (Invalid_argument \"Day number not between 1 and 7\")\n  ;;\nend\n\nlet _ =\n  print_endline \"These are the days of the week from 1 to 7:\";\n  for i = 1 to 7 do\n    printf \"Day #1: %s\\n\" Day.(of_int i |> show)\n  done\n;;\n\n(*****************************************************************************)\n(*                                                                           *)\n(*                        Dificultad Extra (Opcional)                        *)\n(*                                                                           *)\n(*  Crea un pequeño sistema de gestión del estado de pedidos.                *)\n(*  Implementa una clase que define un pedido con las siguientes caracte-    *)\n(*  rísticas:                                                                *)\n(*                                                                           *)\n(*  - El pedido tiene un identificador y un estado.                          *)\n(*  - El estado es un Enum con estos valores: PENDIENTE, ENVIADO,            *)\n(*    ENTREGADO, y CANCELADO.                                                *)\n(*  - Implementa las funciones que sirven para modificar el estado:          *)\n(*    - Pedido enviado                                                       *)\n(*    - Pedido cancelado                                                     *)\n(*    - Pedido entregado                                                     *)\n(*  - Establecer lógica, por ejemplo, no se puede entregar si no se ha       *)\n(*    enviado, etc...                                                        *)\n(*  - Implementa una función para mostrar un texto asociado según el estado  *)\n(*    actual.                                                                *)\n(*  - Crea diferentes pedidos y muestra cómo se interactúa con ellos.        *)\n(*                                                                           *)\n(*****************************************************************************)\n\nmodule Shipment : sig\n  exception ShipmentError of string\n\n  type t\n\n  val create : int -> t\n  val to_string : t -> string\n  val ship : t -> unit\n  val deliver : t -> string -> unit\n  val cancel : t -> unit\nend = struct\n  exception ShipmentError of string\n\n  type status =\n    | Pending\n    | Shipped of string\n    | Delivered of (string * string)\n    | Cancelled\n\n  type t =\n    { mutable history : status list\n    ; mutable status : status\n    ; id : int\n    }\n\n  let create id = { history = []; status = Pending; id }\n\n  let set_status st sh =\n    let curr_status = sh.status in\n    begin\n      match curr_status, st with\n      | Pending, Pending\n      | Cancelled, Cancelled\n      | Shipped _, Shipped _\n      | Delivered _, Delivered _ ->\n        raise @@ ShipmentError \"Current and new status are the same.\"\n      | Pending, Delivered _ ->\n        raise\n        @@ ShipmentError \"Can't deliver a shipment without shipping it first.\"\n      | Cancelled, x when x <> Pending ->\n        raise @@ ShipmentError \"Can't ship or deliver while cancelled.\"\n      | Shipped _, Pending ->\n        raise @@ ShipmentError \"Can't set to pending, already shipped.\"\n      | Shipped _, Cancelled ->\n        raise @@ ShipmentError \"Already shipped, can't cancel.\"\n      | Delivered _, _ -> raise @@ ShipmentError \"Already delivered.\"\n      | _ -> ()\n    end;\n    sh.history <- sh.status :: sh.history;\n    sh.status <- st\n  ;;\n\n  let show_status = function\n    | Pending -> \"Pending\"\n    | Shipped date -> sprintf \"Shipped on %s\" date\n    | Delivered (date, signed_by) ->\n      sprintf \"Delivered on %s (signed: %s)\" date signed_by\n    | Cancelled -> \"Cancelled\"\n  ;;\n\n  let to_string { history; status; id } =\n    sprintf \"Shipment #%d Information\\n\" id\n    ^ sprintf \"Current status: %s\\n\" (show_status status)\n    ^ \"-------------------------\\n\"\n    ^ \"Status change history:\\n\"\n    ^ (List.rev history\n       |> List.mapi (fun i status ->\n         string_of_int (i + 1) ^ \" - \" ^ show_status status)\n       |> String.concat \"\\n\")\n    ^ \"\\n\"\n  ;;\n\n  let ship sh = set_status (Shipped (today ())) sh\n  let deliver sh signed_by = set_status (Delivered (today (), signed_by)) sh\n  let cancel sh = set_status Cancelled sh\nend\n\nlet safe_perform f =\n  try f () with\n  | Shipment.ShipmentError msg -> printf \"[SHIPMENT ERROR]: %s\\n\" msg\n;;\n\nlet _ =\n  let mock_shipment_1 = Shipment.create 23677 in\n  let mock_shipment_2 = Shipment.create 15622 in\n  print_endline \"Here are 2 newly created shipments, stringified:\";\n  print_string (Shipment.to_string mock_shipment_1);\n  print_string (Shipment.to_string mock_shipment_2);\n  print_endline \"Changes will be done to both...\";\n  safe_perform (fun () -> Shipment.cancel mock_shipment_1);\n  safe_perform (fun () -> Shipment.ship mock_shipment_1);\n  safe_perform (fun () -> Shipment.cancel mock_shipment_1);\n  safe_perform (fun () -> Shipment.deliver mock_shipment_2 \"John Doe\");\n  safe_perform (fun () -> Shipment.ship mock_shipment_2);\n  safe_perform (fun () -> Shipment.deliver mock_shipment_2 \"Luis Lopez\");\n  print_endline \"Now that changes were made, show shipments again:\";\n  print_string (Shipment.to_string mock_shipment_1);\n  print_string (Shipment.to_string mock_shipment_2)\n;;\n\n(* Output of [dune exec reto19]\n\n   These are the days of the week from 1 to 7:\n   Day #1: Sunday\n   Day #1: Monday\n   Day #1: Tuesday\n   Day #1: Wednesday\n   Day #1: Thursday\n   Day #1: Friday\n   Day #1: Saturday\n   Here are 2 newly created shipments, stringified:\n   Shipment #23677 Information\n   Current status: Pending\n   -------------------------\n   Status change history:\n\n   Shipment #15622 Information\n   Current status: Pending\n   -------------------------\n   Status change history:\n\n   Changes will be done to both...\n   [SHIPMENT ERROR]: Can't ship or deliver while cancelled.\n   [SHIPMENT ERROR]: Current and new status are the same.\n   [SHIPMENT ERROR]: Can't deliver a shipment without shipping it first.\n   Now that changes were made, show shipments again:\n   Shipment #23677 Information\n   Current status: Cancelled\n   -------------------------\n   Status change history:\n   1 - Pending\n   Shipment #15622 Information\n   Current status: Delivered on 05/13/2024 (signed: Luis Lopez)\n   -------------------------\n   Status change history:\n   1 - Pending\n   2 - Shipped on 05/13/2024\n*)\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/pascal/edalmava.pas",
    "content": "program Enumerado;\nUses Crt;\n\ntype\n    DiasSemana = (Lunes, Martes, Miercoles, Jueves, Viernes, Sabado, Domingo);\n    EstadoPedido = (PENDIENTE, ENVIADO, ENTREGADO, CANCELADO);\n    Pedido = object\n    private\n        id : Integer;\n        estado : EstadoPedido;\n    public\n        constructor Iniciar(Identificador: Integer);\n        procedure EnviarPedido;\n        procedure EntregarPedido;\n        procedure CancelarPedido;\n        procedure MostrarEstadoPedido;\n    end;\n\nvar\n    Dia: DiasSemana;\n    numDia: Byte;\n    pedido1, pedido2, pedido3, pedido4: Pedido;\n    ids : String;\n\nconstructor Pedido.Iniciar(Identificador: Integer);\nbegin\n    id := Identificador;\n    estado := PENDIENTE\nend;\n\nprocedure Pedido.EnviarPedido();\nbegin\n    if estado = PENDIENTE then\n    begin\n        estado := ENVIADO;\n        Str(id, ids); WriteLn('Pedido ' + ids + ' Enviado')\n    end\n    else\n        WriteLn('No se puede enviar el pedido')\nend;\n\nprocedure Pedido.EntregarPedido();\nbegin\n    if estado = ENVIADO then\n    begin\n        estado := ENTREGADO;\n        Str(id, ids); WriteLn('Pedido ' + ids + ' Entregado')\n    end\n    else\n        WriteLn('No se puede entregar un pedido que no se ha enviado')\nend;\n\nprocedure Pedido.CancelarPedido();\nbegin\n    if estado = ENTREGADO then\n        Writeln('No se puede cancelar el pedido porque ya fue entregado')\n    else\n    begin\n        estado := CANCELADO;\n        Str(id, ids); WriteLn('Pedido ' + ids + ' Cancelado')\n    end\nend;\n\nprocedure Pedido.MostrarEstadoPedido();\nbegin\n    Str(id, ids);\n    Write('Pedido ' + ids);\n    case estado of\n        PENDIENTE: Writeln(' : Pendiente');\n        ENVIADO: WriteLn(' : Enviado');\n        ENTREGADO: WriteLn(' : Entregado');\n        CANCELADO: WriteLn(' : Cancelado');\n    end;\nend;\n\nfunction getDia(const dia: Byte):DiasSemana;\nbegin\n    getDia := DiasSemana(dia - 1);\nend;\n\nbegin\n    ClrScr();\n    Write('Digite el numero del dia: ');\n    ReadLn(numDia);\n    if not (numDia in [1, 2, 3, 4, 5, 6, 7]) then\n    begin\n        WriteLn('El numero debe ser un numero entre 1 y 7');\n        exit\n    end;\n    Dia := getDia(numDia);\n    Write('Corresponde a: ');\n    case Dia of\n        Lunes: Writeln('Lunes');\n        Martes: Writeln('Martes');\n        Miercoles: Writeln('Miercoles');\n        Jueves: Writeln('Jueves');\n        Viernes: Writeln('Viernes');\n        Sabado: Writeln('Sabado');\n        Domingo: Writeln('Domingo');\n    end;\n\n    Writeln('');\n    WriteLn('Reto Extra');\n    Delay(1000);\n\n    WriteLn('');\n    WriteLn('Iniciando Pedidos');\n    pedido1.Iniciar(101);\n    pedido2.Iniciar(102);\n    pedido3.Iniciar(103);\n    pedido4.Iniciar(104);\n\n    WriteLn('');\n    WriteLn('Movimiento de Pedidos');\n    pedido1.EnviarPedido();\n    pedido2.EnviarPedido();\n    pedido3.EntregarPedido();\n    pedido4.EntregarPedido();\n    pedido1.EntregarPedido();\n    pedido2.EntregarPedido();\n    pedido3.CancelarPedido();\n    pedido1.CancelarPedido();\n\n    WriteLn('');\n    WriteLn('Tras realizar movimientos');\n    pedido1.MostrarEstadoPedido();\n    pedido2.MostrarEstadoPedido();\n    pedido3.MostrarEstadoPedido();\n    pedido4.MostrarEstadoPedido();\nend."
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/php/edalmava.php",
    "content": "<?php\n    enum DiasSemana: int {\n        case Lunes = 1;\n        case Martes = 2;\n        case Miercoles = 3;\n        case Jueves = 4;\n        case Viernes = 5;\n        case Sabado = 6;\n        case Domingo = 7;\n\n        public function label(): string {\n            return match($this) {\n                static::Lunes => 'Lunes',\n                static::Martes => 'Martes',\n                static::Miercoles => 'Miércoles',\n                static::Jueves => 'Jueves',\n                static::Viernes => 'Viernes',\n                static::Sabado => 'Sábado',\n                static::Domingo => 'Domingo'\n            };\n        }\n    }\n\n    function getNameDay($day) {\n        if (in_array($day, [1, 2, 3, 4, 5, 6, 7])) {\n            return DiasSemana::from($day)->label();\n        } else {\n            return \"Número de día no válido.  Debe estar en el rango de 1 a 7\";\n        }        \n    }\n\n    for ($i = 0; $i <=10; $i++) {\n        echo getNameDay($i), \"\\n\";\n    } \n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/php/eulogioep.php",
    "content": "<?php\n// Resumen sobre Enumeraciones\n// Las enumeraciones (Enums) en PHP 8.1 permiten definir un tipo de dato con un conjunto finito de valores posibles. \n// Son útiles para representar datos categóricos que tienen un número limitado de valores, como los días de la semana o el estado de un pedido.\n\nenum DiasSemana: int\n{\n    case Lunes = 1;\n    case Martes = 2;\n    case Miercoles = 3;\n    case Jueves = 4;\n    case Viernes = 5;\n    case Sabado = 6;\n    case Domingo = 7;\n}\n\n// Función para obtener el nombre del día a partir de un número entero\nfunction obtenerNombreDia(int $numeroDia): string\n{\n    return DiasSemana::from($numeroDia)->name;\n}\n\n// Ejemplo de uso de la función obtenerNombreDia\necho obtenerNombreDia(1); // Salida: Lunes\necho \"\\n\";\necho obtenerNombreDia(7); // Salida: Domingo\n\n// Dificultad Extra: Sistema de gestión del estado de pedidos\nenum EstadoPedido: string\n{\n    case Pendiente = 'Pendiente';\n    case Enviado = 'Enviado';\n    case Entregado = 'Entregado';\n    case Cancelado = 'Cancelado';\n}\n\nclass Pedido\n{\n    private int $id;\n    private EstadoPedido $estado;\n\n    public function __construct(int $id, EstadoPedido $estado = EstadoPedido::Pendiente)\n    {\n        $this->id = $id;\n        $this->estado = $estado;\n    }\n\n    public function enviar(): void\n    {\n        if ($this->estado === EstadoPedido::Pendiente) {\n            $this->estado = EstadoPedido::Enviado;\n        } else {\n            echo \"El pedido no se puede enviar.\\n\";\n        }\n    }\n\n    public function entregar(): void\n    {\n        if ($this->estado === EstadoPedido::Enviado) {\n            $this->estado = EstadoPedido::Entregado;\n        } else {\n            echo \"El pedido no se puede entregar.\\n\";\n        }\n    }\n\n    public function cancelar(): void\n    {\n        if ($this->estado !== EstadoPedido::Entregado) {\n            $this->estado = EstadoPedido::Cancelado;\n        } else {\n            echo \"El pedido no se puede cancelar.\\n\";\n        }\n    }\n\n    public function obtenerDescripcionEstado(): string\n    {\n        return \"El estado actual del pedido {$this->id} es {$this->estado->value}.\\n\";\n    }\n}\n\n// Ejemplo de interacción con diferentes pedidos\n$pedido1 = new Pedido(1);\n$pedido2 = new Pedido(2);\n\n$pedido1->enviar();\necho $pedido1->obtenerDescripcionEstado(); // Salida: El estado actual del pedido 1 es Enviado.\n\n$pedido1->entregar();\necho $pedido1->obtenerDescripcionEstado(); // Salida: El estado actual del pedido 1 es Entregado.\n\n$pedido2->cancelar();\necho $pedido2->obtenerDescripcionEstado(); // Salida: El estado actual del pedido 2 es Cancelado.\n\n$pedido3 = new Pedido(3);\n$pedido3->enviar();\n$pedido3->cancelar(); // Esto no debería ser posible, y se verá reflejado en el mensaje.\n\necho $pedido3->obtenerDescripcionEstado(); // Salida: El estado actual del pedido 3 es Enviado.\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/php/gabrielmoris.php",
    "content": "<?php\n/* EXERCISE:\n* Using your language, explore the definition of the data type\n* that serves to define enumerations (Enum).\n* Create an Enum that represents the days of the week from Monday\n* to Sunday, in that order. With that enum, create an operation\n* that displays the name of the day of the week depending on the integer\n* used (from 1 to 7).\n*/\nenum Week\n{\n    case Monday;\n    case Tuesday;\n    case Wednesday;\n    case Thursday;\n    case Friday;\n    case Saturday;\n    case Sunday;\n}\n\n\nfunction getWeekDay($num)\n{\n    switch ($num) {\n        case 1:\n            echo Week::Monday->name . \"\\n\";\n            break;\n        case 2:\n            echo Week::Tuesday->name . \"\\n\";\n            break;\n        case 3:\n            echo Week::Wednesday->name . \"\\n\";\n            break;\n        case 4:\n            echo Week::Thursday->name . \"\\n\";\n            break;\n        case 5:\n            echo Week::Friday->name . \"\\n\";\n            break;\n        case 6:\n            echo Week::Saturday->name . \"\\n\";\n            break;\n        case 7:\n            echo Week::Sunday->name . \"\\n\";\n            break;\n        default:\n            echo \"Whe week has only 7 days.\";\n    }\n}\n\n$count = 1;\nwhile ($count < 8) {\n    getWeekDay($count);\n    $count++;\n}\n\n/* EXTRA DIFFICULTY (optional):\n* Create a small order status management system.\n* Implement a class that defines an order with the following characteristics:\n* - The order has an identifier and a status.\n* - The status is an Enum with these values: PENDING, SENT, DELIVERED and CANCELED.\n* - Implement the functions to modify the status:\n*   - Order sent\n*   - Order canceled\n*   - Order delivered\n*   (Establish logic, for example, it cannot be delivered if it has not been sent, etc...)\n* - Implement a function to display a descriptive text according to the current status.\n* - Create different orders and show how they interact with them.\n*/\n\nenum OrderStatus\n{\n    case PENDING;\n    case SENT;\n    case DELIVERED;\n    case CANCELED;\n};\n\nclass OrderSystem\n{\n    private $orders;\n\n    public function __construct()\n    {\n        $this->orders = [];\n    }\n\n    private function randomString()\n    {\n        return substr(str_shuffle('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'), 0, 10);\n    }\n\n    private function manageOrder($id, $status = \"\")\n    {\n        $index = array_search($id, array_column($this->orders, \"id\"));\n        if ($index !== false) {\n            $targetedOrder = &$this->orders[$index];\n            if ($status != \"\") {\n                $targetedOrder[\"status\"] =  $status;\n            }\n\n            echo \"=============================================\\n\";\n            echo \"Your order: \" . $targetedOrder[\"item\"] . \" with id $id now has the status \" . $targetedOrder[\"status\"] . \". \\n\";\n            echo \"=============================================\\n\";;\n        } else {\n            echo \"Error: Order ID not found.\\n\";\n        }\n    }\n\n\n    public function sendOrder($item)\n    {\n        $orderId = $this->randomString();\n        $orderStatus = OrderStatus::SENT->name;\n        $this->orders[] = [\"id\" => $orderId, \"item\" => $item, \"status\" => $orderStatus];\n        echo \"=============================================\\n\";\n        echo \"Your order: $item with id $orderId  Has the status $orderStatus. \\nPlease, save the order ID in a safe place and don't share it.\\n\";\n        echo \"=============================================\\n\";\n    }\n\n    public function forceDeleteOrder($id)\n    {\n        $index = array_search($id, array_column($this->orders, \"id\"));\n        if ($index !== false) {\n            unset($this->orders[$index]);\n            $this->orders = array_values($this->orders);\n        } else {\n            echo \"Error: Order ID not found.\\n\";\n        }\n    }\n\n    public function changeToDelivered($id)\n    {\n        $status = OrderStatus::DELIVERED->name;\n        $this->manageOrder($id, $status);\n    }\n\n    public function cancelOrder($id)\n    {\n        $status = OrderStatus::CANCELED->name;\n        $this->manageOrder($id, $status);\n    }\n\n    public function checkOrderStatus($id)\n    {\n        $this->manageOrder($id);\n    }\n}\n\n\n\nfunction orderStatusManager()\n{\n    $orderManager = new OrderSystem();\n\n    echo \"\n    ===== PRINTER =====\n     1.- Send Order \n     2.- Check order Status\n     3.- Change Status to Delivered\n     4.- Cancel Order\n     5.- Delete Order (Only in extreme cases)\n     6.- Exit\n    ==================\n     \\n\";\n\n    while (true) {\n        $selection = readline(\"Select an option\\n\");\n        switch ($selection) {\n            case 1:\n                $item =  readline(\"What do you want to send? \\n\");\n                $orderManager->sendOrder($item);\n                break;\n            case 2:\n                $id = readline(\"Give me your order ID: \\n\");\n                $orderManager->checkOrderStatus($id);\n                break;\n            case 3:\n                $id = readline(\"Give me your order ID: \\n\");\n                $orderManager->changeToDelivered($id);\n                break;\n            case 4:\n                $id = readline(\"Give me your order ID: \\n\");\n                $orderManager->cancelOrder($id);\n                break;\n            case 5:\n                $id = readline(\"Give me your order ID: \\n\");\n                $orderManager->forceDeleteOrder($id);\n                break;\n            case 6:\n                echo \"\\033c\";\n                echo \"Good bye 👋 📦\\n\";\n                exit;\n            default:\n                echo \"This option doesn't exist.\\n\";\n        }\n    }\n}\n\norderStatusManager();\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/php/miguelex.php",
    "content": "<?php\n\n// Enumeración de los días de la semana\nenum WeekDay: int {\n    case LUNES = 1;\n    case MARTES = 2;\n    case MIERCOLES = 3;\n    case JUEVES = 4;\n    case VIERNES = 5;\n    case SABADO = 6;\n    case DOMINGO = 7;\n}\n\nfunction dayOfWeek($day){\n\n    echo \"El día de la semana correspondiente al número $day es: \";\n    echo WeekDay::from($day)->name;\n    echo \"\\n\";\n                \n}\n\nfor ($i = 1; $i <= 7; $i++) {\n    dayOfWeek($i);\n}\n\n// Extra\n\necho \"\\n\\n EJERCICIO EXTRA \\n\\n\"; \n\nenum Status {\n    case PENDIENTE;\n    case ENVIADO;\n    case ENTREGADO;\n    case CANCELADO;\n}\nclass Parcel {\n\n    private $id;\n    private $status;\n\n    function __construct($id, $status) {\n        $this->id = $id;\n        $this->status = $status;\n    }\n\n    function __toString(){\n        return \"Paquete $this->id: {$this->status->name}\\n\";\n    }\n\n    function sendPackage($id) {\n        if ($this->status == Status::PENDIENTE){\n            echo \"El paquete $id ya ha sido enviado\\n\";\n            $this->status = Status::ENVIADO;\n            return;\n        }\n\n        echo \"El paquete $id no se encuentra preparado para el envío o ya no está en el sistema\\n\";\n    }\n\n    function deliverPackage($id) {\n        if ($this->status == Status::ENVIADO){\n            echo \"El paquete $id ha sido entregado\\n\";\n            $this->status = Status::ENTREGADO;\n            return;\n        }\n\n        echo \"El paquete $id no se encuentra en estado de envío\\n\";\n    }\n\n    function cancelPackage($id) {\n        if ($this->status == Status::PENDIENTE){\n            echo \"El paquete $id ha sido cancelado\\n\";\n            $this->status = Status::CANCELADO;\n            return;\n        }\n\n        echo \"El paquete $id no se encuentra en estado de envío\\n\";\n    }\n    \n}\n\n$parcel1 = new Parcel(1, Status::PENDIENTE);\n$parcel2 = new Parcel(2, Status::PENDIENTE);\n$parcel3 = new Parcel(3, Status::PENDIENTE);\n\necho $parcel1;\necho $parcel2;\necho $parcel3;\n\n$parcel1->sendPackage(1);\n$parcel2->deliverPackage(2);\n$parcel3->cancelPackage(3);\n\n$parcel1->deliverPackage(1);\n$parcel2->sendPackage(2);\n$parcel3->sendPackage(3);\n\necho $parcel1;\necho $parcel2;\necho $parcel3;\n\n\n\n\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/AChapeton.py",
    "content": "from enum import Enum\n\nclass WeekDays(Enum):\n  Monday = 1\n  Tuesday = 2\n  Wednesday = 3\n  Thursday = 4\n  Friday = 5\n  Saturday = 6\n  Sunday = 7\n\ndef getDayOfWeek(number):\n  for day in WeekDays:\n    if day.value == number:\n      return day.name\n  return \"Invalid number\"\n\nprint(getDayOfWeek(3))"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/Aldroide.py",
    "content": "\"\"\"\n    Ejercicio\n    EXplora la definicion del tipo de dato oara definir enumeraciónes (ENUM)\n    Crea un Enum que represente los dias de las semanas del lunes al domingo en ese orden.\n    Con ese enumerado, crea una operación de muestre el dia de la semana dependeiendo del \n    número entero utilizando del 1 al 7\n\"\"\"\n\nfrom enum import Enum\n\n\nclass week(Enum):\n    Lunes = 1\n    Martes = 2\n    Miercoles = 3\n    Jueves = 4\n    Viernes = 5\n    Sabado = 6\n    Domingo = 7\n\n\ndef get_day(num: int) -> str:\n    try:\n        day = week(num)\n        return day.name\n    except ValueError:\n        return \"No Existe\"\n\n\ndef get_num_day(day: str) -> int:\n    try:\n        return week[day].value\n    except KeyError:\n        return \"No Existe\"\n\n\nprint(f\"El dia 7 es: {get_day(7)}\")\nprint(f\"El dia 7 es: {get_day(3)}\")\nprint(f\"El dia 7 es: {get_day(8)}\")\nprint(f\"El martes tiene el numero: {get_num_day('Martes')}\")\nprint(f\"El jueves tiene el numero: {get_num_day('Jueves')}\")\nprint(f\"Diciembre tiene el numero: {get_num_day('Diciembre')} \\n\")\n\n\"\"\"\n    Realiza un pequeño sistema de gestion de estado de pedidos\n    Implementa una clase que defina un pedido con las siguientes caracteristicas:\n        * El pedido tiene un identificador y un estado\n        * El estado es un Enum con estos valores:\n            - Pendiente\n            - Enviado\n            - Entregado\n            - Cancelado\n        * Implementa las funciones que sirvan para modificar el estado:\n            - Pedido enviado\n            - Pedido cancelado\n            - Pedido entregado\n        (Establece una lógica, por ejemplo no se puede entregar si no se ha enviado etc.)\n        Implementa una función para mostrar un texto descriptivo segun el estado actual\n        Crea diferentes pedidos y muestra cómo se interactúa con ellos.\n\"\"\"\n\n\nclass Estado(Enum):\n    Pendiente = 1\n    Enviado = 2\n    Entregado = 3\n    Cancelado = 4\n\n\nclass Pedidos:\n\n    estado = Estado.Pendiente\n\n    def __init__(self, id_pedido):\n        self.id_pedido = id_pedido\n\n    def enviar(self):\n        if self.estado == Estado.Pendiente:\n            self.estado = Estado.Enviado\n            self.mostrar_estado()\n        else:\n            self.mostrar_estado()\n\n    def entregar(self):\n        if self.estado == Estado.Enviado:\n            self.estado = Estado.Entregado\n            self.mostrar_estado()\n        else:\n            self.mostrar_estado()\n\n    def cancelar(self):\n        if self.estado != Estado.Entregado:\n            self.estado = Estado.Cancelado\n            self.mostrar_estado()\n        else:\n            self.mostrar_estado()\n\n    def mostrar_estado(self):\n        print(\n            f\"El estado del paquete {self.id_pedido}  es: {self.estado.name}\")\n\n\nprint(\"\\n==== Sistema de pedidos====\\n\")\npedido1 = Pedidos('P01')\n# pedido1.mostrar_estado()\npedido1.entregar()\npedido1.enviar()\npedido1.entregar()\npedido1.cancelar()\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/CaveroBrandon.py",
    "content": "\"\"\"EJERCICIO:\nEmpleando tu lenguaje, explora la definición del tipo de dato\nque sirva para definir enumeraciones (Enum).\nCrea un Enum que represente los días de la semana del lunes\nal domingo, en ese orden. Con ese enumerado, crea una operación\nque muestre el nombre del día de la semana dependiendo del número entero\nutilizado (del 1 al 7).\"\"\"\n\nfrom enum import Enum\n\n\nclass WeekDay(Enum):\n    MONDAY = 1\n    TUESDAY = 2\n    WEDNESDAY = 3\n    THURSDAY = 4\n    FRIDAY = 5\n    SATURDAY = 6\n    SUNDAY = 7\n\n\ndef get_day_from_value(day_number: int) -> str:\n    return WeekDay(day_number).name\n\n\n\"\"\"DIFICULTAD EXTRA (opcional):\n * Crea un pequeño sistema de gestión del estado de pedidos.\n * Implementa una clase que defina un pedido con las siguientes características:\n * - El pedido tiene un identificador y un estado.\n * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n * - Implementa las funciones que sirvan para modificar el estado:\n *   - Pedido enviado\n *   - Pedido cancelado\n *   - Pedido entregado\n *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n * - Crea diferentes pedidos y muestra cómo se interactúa con ellos. \"\"\"\n\n\nclass Status(Enum):\n    PENDING = 0\n    SEND = 1\n    COMPLETED = 2\n    CANCELLED = 3\n\n\nclass Order:\n    def __init__(self, order_id):\n        self.order_id = order_id\n        self.status = Status.PENDING\n        print(f'Operation successful: Order #{self.order_id} was created with {self.status.name} status')\n\n    def send_order(self):\n        if self.status.value == 0:\n            self.status = Status.SEND\n            print(f'Operation successful: Order #{self.order_id} set to {self.status.name} status')\n        elif self.status.value == 1:\n            print(f'Operation denied: Order #{self.order_id} was already SEND')\n        else:\n            print(f'Operation denied: {self.status.name} order cannot be changed to SEND status')\n\n    def completed_order(self):\n        if self.status.value == 1:\n            self.status = Status.COMPLETED\n            print(f'Operation successful: Order #{self.order_id} set to {self.status.name} status')\n        elif self.status.value == 2:\n            print(f'Operation denied: Order #{self.order_id} was already COMPLETED')\n        else:\n            print(f'Operation denied: {self.status.name} order cannot be changed to COMPLETED status')\n\n    def cancel_order(self):\n        self.status = Status.CANCELLED\n        print(f'Operation successful: #Order #{self.order_id} status set to {self.status.name}')\n\n    def get_order_status(self):\n        return self.status.name\n\n\nprint(f'The day that represent the number 2 is: {get_day_from_value(day_number=2)}')\nprint(f'The day that represent the number 5 is: {get_day_from_value(day_number=5)}')\nprint(f'The day that represent the number 7 is: {get_day_from_value(day_number=7)}')\n\nprint('**** EXTRA ****')\nprint('\\n**** Regular order process ****')\nnew_order = Order(order_id=111)\nnew_order.send_order()\nnew_order.completed_order()\n\nprint('\\n**** Order cancelled ****')\nnew_order = Order(order_id=222)\nnew_order.send_order()\nnew_order.cancel_order()\n\nprint('\\n**** Attempt to complete an order before send it ****')\nnew_order = Order(order_id=333)\nnew_order.completed_order()\n\nprint('\\n**** Attempt to send the order when it\\'s already completed ****')\nnew_order = Order(order_id=444)\nnew_order.send_order()\nnew_order.completed_order()\nnew_order.send_order()"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/CesarCarmona30.py",
    "content": "from enum import Enum\n\nclass Weekday(Enum):\n  MONDAY = 1\n  TUESDAY = 2\n  WEDNESDAY = 3\n  THURSDAY = 4\n  FRIDAY = 5\n  SATURDAY = 6\n  SUNDAY = 7\n\ndef name_day(number):\n  try:\n    return Weekday(number).name.capitalize()\n  except ValueError:\n    return \"Invalid day\"\n  \n'''\n  EXTRA\n'''\n\nclass Status(Enum):\n  PENDING = 1\n  SHIPPED = 2\n  DELIVERED = 3\n  CANCELED = 4\n\nclass Order:\n  def __init__(self, identifier):\n    self._identifier = identifier\n    self._status = Status.PENDING\n\n  def send(self):\n    if self._status == Status.PENDING:\n      self._status = Status.SHIPPED\n      print(f'{self._identifier} shipped')\n    else:\n      print('Shipped invalid operation')\n\n  def canceled(self):\n    if self._status == Status.PENDING:\n      self._status = Status.CANCELED\n      print(f'{self._identifier} canceled')\n    else:\n      print('Canceled invalid operation')\n\n  def delivered(self):\n    if self._status == Status.SHIPPED:\n      self._status = Status.DELIVERED\n      print(f'{self._identifier} delivered')\n    else:\n      print('Delivered invalid operation')\n\n  def show_details(self):\n    print(f'{self._identifier}: {self._status.name}')\n\n\nprint(name_day(3))\nprint(name_day(6))\nprint(name_day(9))\n\n\nproduct1 = Order('Keyboard')\nproduct2 = Order('Sweater')\n\nproduct1.show_details()\nproduct1.send()\nproduct1.show_details()\nproduct1.delivered()\nproduct1.show_details()\nproduct1.canceled()\nproduct1.show_details()\n\nproduct2.show_details()\nproduct2.canceled()\nproduct2.show_details()\nproduct2.delivered()\nproduct2.show_details()"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/Chrisdev00.py",
    "content": "\"\"\"\n* EJERCICIO:\n* Empleando tu lenguaje, explora la definición del tipo de dato\n* que sirva para definir enumeraciones (Enum).\n* Crea un Enum que represente los días de la semana del lunes\n* al domingo, en ese orden. Con ese enumerado, crea una operación\n* que muestre el nombre del día de la semana dependiendo del número entero\n* utilizado (del 1 al 7).\n*\n* DIFICULTAD EXTRA (opcional):\n* Crea un pequeño sistema de gestión del estado de pedidos.\n* Implementa una clase que defina un pedido con las siguientes características:\n* - El pedido tiene un identificador y un estado.\n* - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n* - Implementa las funciones que sirvan para modificar el estado:\n*   - Pedido enviado\n*   - Pedido cancelado\n*   - Pedido entregado\n*   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n* - Implementa una función para mostrar un texto descriptivo según el estado actual.\n* - Crea diferentes pedidos y muestra cómo se interactúa con ellos. \n\"\"\"\n\nfrom enum import Enum\n\nclass WeekDays(Enum):\n    MONDAY = 1\n    TUESDAY = 2\n    WEDNESDAY = 3\n    THURSDAY = 4\n    FRIDAY = 5\n    SATURDAY = 6\n    SUNDAY = 7\n\ndef day_name(num):\n    try:\n        day = WeekDays(num)\n        return day.name.capitalize()\n    except ValueError:\n        return \"Numero del dia invalido\"\n    \nprint(day_name(4))\nprint(day_name(1))\nprint(day_name(7))\nprint(day_name(8))\n\n######## -----------------------------------  EXTRA  ------------------------------------- ################\n\nclass OrderState(Enum):\n    PENDIENTE = 1\n    ENVIADO = 2\n    ENTREGADO = 3\n    CANCELADO = 4\n\nclass Pedido:\n\n    def __init__(self, identificador, estado):\n        self.identificador = identificador\n        self.estado = estado\n\n    def upgrade_state(self, new_state):\n        if new_state in OrderState:\n            self.estado = new_state\n            print(f\"El estado del pedido {self.identificador} ha sido actualizado a {self.estado.name}\")\n        else:\n            print(f\"El pedido {self.identificador} no se pudo enviar.\")\n    \n    def send_order(self):\n        if self.estado == OrderState.PENDIENTE:\n            self.upgrade_state(OrderState.ENVIADO)\n        else:\n            print(\"El pedido no se pudo enviar porque no esta pendiente\")\n\n    def order_delivered(self):\n        if self.estado == OrderState.ENVIADO:\n            self.upgrade_state(OrderState.ENTREGADO)\n        else:\n            print(f\"El pedido {self.identificador} no se pudo marcar como entregado porque no fue enviado aun\")\n    \n    def cancel_order(self):\n        if self.estado != OrderState.CANCELADO or self.estado != OrderState.ENTREGADO:\n            self.upgrade_state(OrderState.CANCELADO)\n        else:\n            print(\"El pedido ya esta cancelado\")\n\n\n\npedido1 = Pedido(identificador=3, estado=OrderState.PENDIENTE)\n\npedido1.send_order()\nprint(f\"El pedido {pedido1.identificador}: Estado - {pedido1.estado.name}\")\n\npedido1.cancel_order()\nprint(f\"El pedido {pedido1.identificador}: Estado - {pedido1.estado.name}\")\n\npedido1.order_delivered()\nprint(f\"El pedido {pedido1.identificador}: Estado - {pedido1.estado.name}\")\n\npedido1.cancel_order()\npedido1.order_delivered()"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/Complex303.py",
    "content": "\"\"\"\nEnumeraciones\n\"\"\"\n\n#enumeraciones: Enum es una clase especial que te permite definir constantes con nombre agrupadas en una categoría. Es como crear una lista de opciones válidas con nombre propio y valor asociado.\n\n# Importamos la clase Enum desde el módulo enum\nfrom enum import Enum\n\n# Definimos una clase Weekday que hereda de Enum (es una enumeración)\nclass Weekday(Enum):\n    MONDAY = 1        # Asociamos MONDAY con el valor 1\n    TUESDAY = 2       # Asociamos TUESDAY con el valor 2\n    WEDNESDAY = 3     # Y así sucesivamente...\n    THURSDAY = 4\n    FRIDAY = 5\n    SATURDAY = 6\n    SUNDAY = 7\n\n# Definimos una función llamada get_day que recibe un número entero\ndef get_day(number: int):\n    # Convertimos ese número a su día correspondiente usando Weekday(number)\n    # y accedemos a su nombre (por ejemplo Weekday(6) es SATURDAY)\n    print(Weekday(number).name)\n\n# Llamamos a la función get_day pasando 6 como argumento\nget_day(6)\n\n\n\n\n\"\"\" * DIFICULTAD EXTRA (opcional):\n * Crea un pequeño sistema de gestión del estado de pedidos.\n * Implementa una clase que defina un pedido con las siguientes características:\n * - El pedido tiene un identificador y un estado.\n * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n * - Implementa las funciones que sirvan para modificar el estado:\n *   - Pedido enviado\n *   - Pedido cancelado\n *   - Pedido entregado\n *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n * - Crea diferentes pedidos y muestra cómo se interactúa con ellos. \n */\"\"\"\n\n\n# Importamos la clase Enum desde el módulo enum\nfrom enum import Enum\n\n# Definimos una enumeración llamada OrderStatus para los estados posibles de un pedido\nclass OrderStatus(Enum):\n    PENDING = 1      # Pedido pendiente\n    SHIPPED = 2      # Pedido enviado\n    DELIVERED = 3    # Pedido entregado\n    CANCELLED = 4    # Pedido cancelado\n\n# Definimos la clase Order para representar un pedido\nclass Order:\n\n    # Atributo de clase: todos los pedidos empiezan con estado PENDING\n    status = OrderStatus.PENDING\n\n    # Método constructor que recibe un id de pedido\n    def __init__(self, id: int):\n        # Guarda el id en la instancia\n        self.id = id\n\n    # Método para cambiar el estado a SHIPPED\n    def ship(self):\n        # Verifica si el pedido está en estado PENDING antes de enviarlo\n        if self.status == OrderStatus.PENDING:\n            # Cambia el estado a SHIPPED\n            self.status = OrderStatus.SHIPPED\n            # Muestra el estado actual\n            self.display_status()\n        else:\n            # Si no está pendiente, muestra este mensaje\n            print(\"El pedido ya se ha enviado o cancelado\")\n\n    # Método para cambiar el estado a DELIVERED\n    def deliver(self):\n        # Verifica si el pedido está en estado SHIPPED antes de entregarlo\n        if self.status == OrderStatus.SHIPPED:\n            # Cambia el estado a DELIVERED\n            self.status = OrderStatus.DELIVERED\n            # Muestra el estado actual\n            self.display_status()\n        else:\n            # Si no ha sido enviado, no se puede entregar\n            print(\"El pedido necesita ser enviado o cancelado\")\n\n    # Método para cancelar el pedido\n    def cancel(self):\n        # Verifica si el pedido NO está ya entregado\n        if self.status != OrderStatus.DELIVERED:\n            # Cambia el estado a CANCELLED\n            self.status = OrderStatus.CANCELLED\n            # Muestra el estado actual\n            self.display_status()\n        else:\n            # Si ya fue entregado, no se puede cancelar\n            print(\"El pedido no se puede cancelar porque ya ha sido entregado\")\n\n    # Método para mostrar el estado actual del pedido\n    def display_status(self):\n        print(f\"El estado del pedido {self.id} es: {self.status.name}\")\n\n# Creamos un pedido con id 1\norder_1 = Order(1)\n\n# Mostramos su estado actual (debería ser PENDING)\norder_1.display_status()\n\n# Intentamos entregar el pedido sin enviarlo (esto no debería funcionar)\norder_1.deliver()\n\n# Enviamos el pedido (cambia de PENDING a SHIPPED)\norder_1.ship()\n\n# Ahora sí, lo entregamos (cambia de SHIPPED a DELIVERED)\norder_1.deliver()\n\n# Intentamos cancelar un pedido ya entregado (no debería permitirlo)\norder_1.cancel()\n\n\n\"\"\" Enum → para definir los estados posibles de un pedido.\nVerificación de estado antes de permitir cambios, respetando un flujo lógico:\n*Solo se puede enviar si está pendiente.\n*Solo se puede entregar si está enviado.\n*Solo se puede cancelar si no está entregado.\ndisplay_status() → muestra el estado actual con .name (el nombre del Enum)\"\"\"\n\n\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/EmmanuelMMontesinos.py",
    "content": "\"\"\"/*\n * EJERCICIO:\n * Empleando tu lenguaje, explora la definición del tipo de dato\n * que sirva para definir enumeraciones (Enum).\n * Crea un Enum que represente los días de la semana del lunes\n * al domingo, en ese orden. Con ese enumerado, crea una operación\n * que muestre el nombre del día de la semana dependiendo del número entero\n * utilizado (del 1 al 7).\n */\"\"\"\n\n# Enumeracion\nfrom enum import Enum\n\nclass Dias(Enum):\n    lunes = 1\n    martes = 2\n    miercoles = 3\n    jueves = 4\n    viernes = 5\n    sabado = 6\n    domingo = 7\n\n    def numero_a_dia(self,num:int):\n        try:\n            print(f\"El {num} es {self(num).name.title()}\\n\")\n        except ValueError as e:\n            print(f\"{num} no esta dentro del rango (1/7)\\n\")\n\n# Pruebas\n\nDias.numero_a_dia(Dias,1)\n\n'''\n * DIFICULTAD EXTRA (opcional):\n * Crea un pequeño sistema de gestión del estado de pedidos.\n * Implementa una clase que defina un pedido con las siguientes características:\n * - El pedido tiene un identificador y un estado.\n * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n * - Implementa las funciones que sirvan para modificar el estado:\n *   - Pedido enviado\n *   - Pedido cancelado\n *   - Pedido entregado\n *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n * - Crea diferentes pedidos y muestra cómo se interactúa con ellos. \n'''\n\n# Pedidos\nclass Pedidos:\n    \n    # Estados de los pedidos\n    class Estados_Pedidos(Enum):\n        PENDIENTE = \"Pendiente\"\n        ENVIADO = \"Enviado\"\n        ENTREGADO = \"Entregado\"\n        CANCELADO = \"Cancelado\"\n\n    total_pedidos = 0\n\n    def __init__(self) -> None:\n\n        Pedidos.total_pedidos += 1\n        self.identificador = Pedidos.total_pedidos\n        self.estado = Pedidos.Estados_Pedidos.PENDIENTE\n\n    def info(self):\n        print(f\"Identificador: {self.identificador}\\nEstado: {self.estado.value}\\nPedidos Totales: {Pedidos.total_pedidos}\\n\")\n\n    # Metodo para cambiar de estado dependiendo de su estado actual\n    def cambiar_estado(self,cambio):\n\n        if cambio.lower() == \"enviado\":\n\n            if self.estado == Pedidos.Estados_Pedidos.PENDIENTE:\n\n                print(f\"Cambiando estado de {self.estado.value} a {cambio.title()}\")\n                self.estado = Pedidos.Estados_Pedidos.ENVIADO\n                print(\"Cambio realizado con exito\\n\")\n\n            else:\n\n                print(f\"No se puede cambiar de estado de {self.estado.value} a {cambio}\\n\")\n\n        elif cambio.lower() == \"entregado\":\n\n            if self.estado == Pedidos.Estados_Pedidos.ENVIADO:\n\n                print(f\"Cambiando estado de {self.estado.value} a {cambio.title()}\")\n                self.estado = Pedidos.Estados_Pedidos.ENTREGADO\n                print(\"Cambio realizado con exito\\n\")\n\n            else:\n\n                print(f\"No se puede cambiar de estado de {self.estado.value} a {cambio}\\n\")\n\n\n        elif cambio.lower() == \"cancelado\":\n\n            if self.estado != Pedidos.Estados_Pedidos.CANCELADO:\n\n                print(f\"Cambiando estado de {self.estado.value} a {cambio.title()}\")\n                self.estado = Pedidos.Estados_Pedidos.CANCELADO\n                print(\"Cambio realizado con exito\\n\")\n\n            else:\n\n                print(f\"No se puede cambiar de estado de {self.estado.value} a {cambio}\\n\")\n        self.info()\n\n# Pruebas\npedido_1 = Pedidos()\npedido_2 = Pedidos()\npedido_3 = Pedidos()\n\npedido_1.cambiar_estado(\"enviado\")\npedido_2.cambiar_estado(\"entregado\")\npedido_3.cambiar_estado(\"cancelado\")\n\npedido_1.info()\npedido_2.info()\npedido_3.info()"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/FedeAirala.py",
    "content": "# #19 ENUMERACIONES\n\n\"\"\"\n * EJERCICIO:\n * Empleando tu lenguaje, explora la definición del tipo de dato\n * que sirva para definir enumeraciones (Enum).\n * Crea un Enum que represente los días de la semana del lunes\n * al domingo, en ese orden. Con ese enumerado, crea una operación\n * que muestre el nombre del día de la semana dependiendo del número entero\n * utilizado (del 1 al 7).\n\"\"\"\nfrom enum import Enum\n\nclass days (Enum):\n    Lunes = 1\n    Martes = 2\n    Miércoles = 3\n    Jueves = 4\n    Viernes = 5\n    Sábado = 6\n    Domingo = 7\n\ndays_list = [d for d in days]\n\nfor day in days_list:\n    print (f\"El día {days(day).value} es {day.name}\")\n\n\n\"\"\"\n \n * DIFICULTAD EXTRA (opcional):\n * Crea un pequeño sistema de gestión del estado de pedidos.\n * Implementa una clase que defina un pedido con las siguientes características:\n * - El pedido tiene un identificador y un estado.\n * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n * - Implementa las funciones que sirvan para modificar el estado:\n *   - Pedido enviado\n *   - Pedido cancelado\n *   - Pedido entregado\n *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n * - Crea diferentes pedidos y muestra cómo se interactúa con ellos. \n \n\"\"\"\nclass Estado(Enum):\n    PENDIENTE = 1\n    ENVIADO = 2\n    ENTREGADO = 3\n    CANCELADO = 4\n    \nclass Pedido ():\n    \n    def __init__(self,id, estado = Estado.PENDIENTE):\n        self.id = id\n        self.estado = estado\n    \n    def enviar(self):\n        if self.estado == Estado.PENDIENTE:\n            self.estado = Estado.ENVIADO\n        else:\n            print (f\"El estado del pedido {self.id} se encuentra {self.estado.name} para poder enviar debe estar en {Estado.PENDIENTE.name}\")\n        \n    def entregar(self):\n        if self.estado == Estado.ENVIADO:\n            self.estado = Estado.ENTREGADO\n        else:\n            print (f\"El estado del pedido {self.id} se encuentra {self.estado.name} para poder entregar debe estar en {Estado.ENVIADO.name}\")    \n    \n    def cancelar(self):\n        if self.estado != Estado.ENTREGADO:\n            self.estado = Estado.CANCELADO\n        else:\n            print (\"El pedido ya fue entregado\")\n    \n    def mostrar_estado(self):\n        print (f\"El estado del pedido {self.id} es {self.estado.name}\")\n        \n\npedido_1 = Pedido(1)\npedido_2 = Pedido(2)\npedido_1.enviar()\npedido_1.mostrar_estado()\npedido_2.mostrar_estado()\npedido_2.cancelar()\npedido_2.mostrar_estado()\npedido_3 = Pedido (3)\npedido_3.mostrar_estado()\npedido_3.entregar()\n\n\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/Gallitofast.py",
    "content": "#Enumeraciones Python\nfrom enum import Enum\nclass Weekdays(Enum):\n    Monday=1\n    Tuesday=2\n    Wednesday=3\n    Thursday=4\n    Friday=5\n    Saturday=6\n    Sunday=7\n\n    @classmethod\n    def get_day(cls,num):\n        #this function to return the day name\n        try:\n            return cls(num).name\n        except ValueError:\n            return \"Error, {num} is not a valid number, the week only have 7 days you fool!\"\n    \nif __name__==\"__main__\":\n    for i in range (1,8):\n        print(f\"Day {i} : {Weekdays.get_day(i)}\")\n    print(f\"\\nFourth day is: {Weekdays.get_day(4)}\")\n\n    \"\"\"Dificultad extra\"\"\"\n\nclass Orderstatus(Enum):\n    Pending=1\n    Shipping=2\n    Delivered=3\n    Canceled=4\nclass Order:\n    status=Orderstatus.Pending\n    def __init__(self,id) -> None:\n        self.id=id\n\n    def ship(self):\n        if self.status==Orderstatus.Pending:\n           self.status=Orderstatus.Shipping\n           self.display_status()\n        else:\n            print(\"The order has already been shipped or cancelled\")\n\n    def deliver(self):\n        if self.status == Orderstatus.Shipping:\n            self.status = Orderstatus.Delivered\n            self.display_status()\n        else:\n            print(\"The order has to been sent before deliver\")\n\n    def cancel(self):\n        if self.status != Orderstatus.Delivered:\n            self.status= Orderstatus.Canceled\n            self.display_status()\n        else:\n            print(\"The order cannot be cancelled since it has already been delivered\")\n\n    def display_status(self):\n        print(f\"El status de el envio({self.id}) es: {self.status.name}\")\n\n\nfirst_order = Order(1)\nfirst_order.display_status()\nfirst_order.deliver()\nfirst_order.ship()\nfirst_order.deliver()\nfirst_order.cancel()"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/Gordo-Master.py",
    "content": "# 19 - Enumeraciones\nfrom enum import Enum\n\nclass WeekDay(Enum):\n    LUNES = 1\n    MARTES = 2\n    MIERCOLES = 3\n    JUEVES = 4\n    VIERNES = 5\n    SABADO = 6\n    DOMINGO = 7\n\ndef show_day(num):\n    print(WeekDay(num).name)\n\nshow_day(2)\n\n\"\"\"\nEjercicio Extra\n\"\"\"\nclass State(Enum):\n    PENDIENTE = 1\n    ENVIADO = 2\n    ENTREGADO = 3\n    CANCELADO = 4\n\nclass Request():\n\n    def __init__(self,id: int, state: State = State(1)) -> None:\n        self.id = id\n        self.state = state\n    \n    def send(self):\n        if self.state == State.PENDIENTE:\n            self.state = State.ENVIADO\n            print(f\"Se ha {State(self.state).name} el pedido {self.id}\")\n\n        elif self.state == State.ENVIADO:\n            print(f\"El pedido ({self.id}) ya se encuentra: {State(self.state).name}\")\n\n        else:\n            print(f\"No se pudo ejecutar el envio de {self.id}, porque esta: {State(self.state).name}\")\n\n    def cancel(self):\n        if self.state != State.ENTREGADO and self.state != State.CANCELADO:\n            self.state = State.CANCELADO\n            print(f\"Se ha {State(self.state).name} el pedido {self.id}\")\n\n        elif self.state == State.CANCELADO:\n            print(f\"El pedido ({self.id}) ya se encuentra: {State(self.state).name}\")\n\n        else:\n            print(f\"No se pudo cancelar pedido ({self.id}), porque esta: {State(self.state).name}\")\n\n    def delivered(self):\n        if self.state == State.ENVIADO:\n            self.state = State.ENTREGADO\n            print(f\"Se ha {State(self.state).name} el pedido {self.id}\")\n\n        elif self.state == State.ENTREGADO:\n            print(f\"El pedido ({self.id}) ya se encuentra: {State(self.state).name}\")\n\n        else:\n            print(f\"No se pudo entregar el pedido ({self.id}), porque esta: {State(self.state).name}\")\n\n    def show_state(self):\n        print(f\"El estado del pedido {self.id} es: {State(self.state).name}\")\n\nrequet_1 = Request(\"r_1\")\nrequet_2 = Request(\"r_2\")\n\nprint(requet_1.id)\nprint(requet_1.state)\n\n# Pendiente\nrequet_1.send()\n# Enviado\nrequet_1.cancel()\n# Cancelado\nrequet_1.send()\nrequet_1.delivered()\nrequet_1.show_state()\n\n# Pendiente\nrequet_2.delivered()\nrequet_2.send()\n# Enviado\nrequet_2.send()\nrequet_2.delivered()\n# Entregado\nrequet_2.send()\nrequet_2.cancel()\nrequet_2.delivered()\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/Hyromy.py",
    "content": "from enum import Enum\n\nclass Calendar(Enum):\n    lunes = 1\n    martes = 2\n    miercoles = 3\n    jueves = 4\n    viernes = 5\n    sabado = 6\n    domingo = 7\n\n    def get_day_by_number(num):\n        return Calendar(num)\n\nday = Calendar.get_day_by_number(2)\nprint(day.name)\n\n# ---- DIFICULTAD EXTRA ----\n\nclass Estados(Enum):\n    PENDIENTE = 0\n    ENVIADO = 1\n    ENTREGADO = 2\n    CANCELADO = -1\n\nclass Pedidos:\n    def __str__(self):\n        return f\"Pedidos id={self.id}, estado={self.estado}\"\n\n    def __init__(self, id):\n        self.id = id\n        self.estado = Estados(0)\n        self.anterior_estado = None\n\n    def enviar(self):\n        if not self.estado == Estados.PENDIENTE:\n            raise Exception(f\"El pedido no se puede enviar con estado: {self.estado}\")\n\n        self.estado = Estados(1)\n        self.anterior_estado = Estados(0)\n\n\n    def cancelar(self):\n        if self.estado == Estados.ENTREGADO:\n            raise Exception(f\"El pedido no se puede cancelar con estado: {self.estado}\")\n\n        self.estado = Estados(-1)\n\n    def entregado(self):\n        if not self.estado == Estados.ENVIADO:\n            raise Exception(f\"El pedido no se puede entregar con estado: {self.estado}\")\n\n        self.estado = Estados(2)\n        self.anterior_estado = Estados(1)\n\npedido1 = Pedidos(1)\nprint(pedido1)\npedido1.cancelar()\nprint(pedido1)\nprint()\n\npedido2 = Pedidos(2)\nprint(pedido2)\npedido2.enviar()\nprint(pedido2)\npedido2.entregado()\nprint(pedido2)\ntry:\n    pedido2.cancelar()\nexcept:\n    pass\nprint(pedido2)\nprint()\n\npedido3 = Pedidos(3)\nprint(pedido3)\npedido3.enviar()\nprint(pedido3)\npedido3.cancelar()\nprint(pedido3)\ntry:\n    pedido3.entregado()\nexcept:\n    pass\nprint(pedido3)"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/Irenetitor.py",
    "content": "from enum import Enum\n\n#Exercise\nclass Weekday(Enum):\n    MONDAY = 1\n    TUESDAY = 2\n    WEDNESDAY = 3\n    THURSDAY =  4\n    FRIDAY =  5\n    SATURDAY = 6\n    SUNDAY = 7\n\ndef get_day(number: int):\n    print(Weekday(number).name)\n\nget_day(4)\n\n#Extra Exercise\n\nclass OrderStatus(Enum):\n    Pending = 1\n    Shipped = 2\n    Delivered = 3\n    Canceled = 4\n\nclass Order:\n\n    def __init__(self, id) -> None:\n        self.id = id\n        self.status = OrderStatus.Pending\n\n    def ship(self):\n        if self.status == OrderStatus.Pending:\n            self.status = OrderStatus.Shipped\n            self.display_status()\n        else:\n            print(\"The order has been shipped or cancelled\")\n\n    def deliver(self):\n        if self.status == OrderStatus.Shipped:\n            self.status = OrderStatus.Delivered\n            self.display_status()\n        else:\n            print(\"The order has been shipped or cancelled\")\n\n\n    def cancel(self):\n        if self.status not in (OrderStatus.Shipped, OrderStatus.Delivered):\n            self.status = OrderStatus.Canceled\n            self.display_status()\n        else:\n            print(\"The order can't be canceled, it has been shipped or delivered already\")\n\n\n    def display_status(self):\n        print(f\"the status of your order {self.id} is {self.status.name}\")\n\n\norder_1 = Order(1)\norder_1.display_status()\norder_1.deliver()\norder_1.ship()\norder_1.cancel()\norder_1.deliver()\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/JesusWay69.py",
    "content": "import os, enum\nos.system ('cls')\n\n\"\"\"* EJERCICIO:\n * Empleando tu lenguaje, explora la definición del tipo de dato\n * que sirva para definir enumeraciones (Enum).\n * Crea un Enum que represente los días de la semana del lunes\n * al domingo, en ese orden. Con ese enumerado, crea una operación\n * que muestre el nombre del día de la semana dependiendo del número entero\n * utilizado (del 1 al 7).\n *\n  \"\"\"\n\nweekdays_list = [\"Lunes\", \"Martes\", \"Miércoles\", \"Jueves\", \"Viernes\", \"Sábado\", \"Domingo\"]\nweekdays_tuple = \"Lunes\", \"Martes\", \"Miércoles\", \"Jueves\", \"Viernes\", \"Sábado\", \"Domingo\"\nweekdays_set = {\"Lunes\", \"Martes\", \"Miércoles\", \"Jueves\", \"Viernes\", \"Sábado\", \"Domingo\"}\nweekdays_dict = dict(enumerate(weekdays_list, start=1))# Se puede crear un diccionario a partir de una lista o tupla \n                                        # donde los valores numéricos serán las claves y los elementos los valores\nclass Weekdays(enum.Enum): # Creación de clase con Enum desde la cual podremos acceder diréctamente a sus elementos\n    Lunes = 1\n    Martes = 2\n    Miércoles = 3 \n    Jueves = 4 \n    Viernes =5 \n    Sábado = 6 \n    Domingo = 7\n\n[print(i,d , end=\" \") for i, d in enumerate(weekdays_list, 1)]# Podemos iterar sobre una lista mostrando elemento y valor con enumerate\nprint()\n[print(i,d , end=\" \") for i, d in enumerate(weekdays_tuple, 1)]# También sobre una tupla\nprint()\n[print(i,d , end=\" \") for i, d in enumerate(weekdays_set, 1)]# Con un set los elementos se asignarán desordenados a los valores \nprint()\n[print(i,d , end=\" \") for i, d in weekdays_dict.items()]\nprint() \nprint(f\"El día de la semana correspondiente al número {Weekdays.Miércoles.value} es el {Weekdays.Miércoles.name}\")\n\n\n\ndef show_day(key:int):\n    days = list(enumerate(weekdays_list,1))\n    if key < (len(weekdays_list)) and key > 0:\n        print (f\"El día de la semana correspondiente al número {key} es el {days[key-1][1]}\")\n    else:\n        print (\"El número debe ser mayor a 0 y menor a 8\")\nshow_day(6)\nprint(\"\\n\\n\\n\")\n\n\n\n\"\"\"* DIFICULTAD EXTRA (opcional):\n * Crea un pequeño sistema de gestión del estado de pedidos.\n * Implementa una clase que defina un pedido con las siguientes características:\n * - El pedido tiene un identificador y un estado.\n * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n * - Implementa las funciones que sirvan para modificar el estado:\n *   - Pedido enviado\n *   - Pedido cancelado\n *   - Pedido entregado\n *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n * - Crea diferentes pedidos y muestra cómo se interactúa con ellos.\"\"\"\n\nclass Status (enum.Enum):\n    PENDIENTE=1\n    ENVIADO=2\n    ENTREGADO=3\n    CANCELADO=4\nclass Orders():\n    status = Status.value=1\n    def __init__(self, id):\n        self.id = id\n    def waiting_to_cancelled(self):\n        if self.status == 1:\n           self.status = 4\n           self.show_status()\n        else:\n            print(\"No se puede cancelar un producto que ya se ha enviado o entregado\")  \n    def waiting_to_sent(self):\n        if self.status==1:\n           self.status=2\n           self.show_status()\n        else:\n            print(\"No se puede enviar un producto que ya se ha enviado, entregado o cancelado\")\n    def sent_to_delivered(self):\n        if  self.status==2:\n            self.status=3\n            self.show_status()\n        else:\n            print(\"No se puede marcar como entregado un producto que no se ha enviado, ya se ha entregado o se ha cancelado\")\n    def cancelled_to_waiting(self):\n        if self.status == 4 or self.status == 1:\n           self.status = 1\n           self.show_status()\n        else:\n            print(\"No se puede volver a poner pendiente un producto que ya se ha enviado o entregado\")  \n    def show_status(self):\n        print(f\"El estado del producto {self.id} es: {Status(self.status).name}\")\n    \norders_instance_1 = Orders(1)\norders_instance_1.sent_to_delivered()# Se intenta entregar un producto que no se ha enviado, devuelve aviso.\norders_instance_1.waiting_to_sent()# El pedido sigue estando pendiente, se envía y devuelve el mensaje de enviado.\norders_instance_1.sent_to_delivered()# El pedido está enviado, se entrega y devuelve el mensaje de entregado.\norders_instance_1.waiting_to_cancelled()# Se intenta cancelar el pedido y devuelve aviso de que ya ha sido enviado o entregado.\norders_instance_2 = Orders(2)\norders_instance_2.cancelled_to_waiting()# Esta función devuelve el producto de cancelado a pendiente, como no se ha cancelado sigue pendiente.\norders_instance_2.waiting_to_cancelled()# Se cancela el producto pendiente y muestra el estado de cancelado.\norders_instance_2.cancelled_to_waiting()# Ahora sí devolvemos el pedido cancelado a pendiente.\norders_instance_2.sent_to_delivered()# Se intenta entregar el pedido y devuelve el aviso de que aun no ha sido enviado.\norders_instance_2.show_status()# Al llamar a este método imprimirá el estado actual del pedido.\norders_instance_1.show_status()\n    \n    \n    \n    \n    \n    \n    \n    \n  \n\n            \n\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/JheisonQuiroga.py",
    "content": "from enum import Enum\nfrom datetime import date\nfrom typing import Literal\n\n\"\"\"/*\n * EJERCICIO:\n * Empleando tu lenguaje, explora la definición del tipo de dato\n * que sirva para definir enumeraciones (Enum).\n * Crea un Enum que represente los días de la semana del lunes\n * al domingo, en ese orden. Con ese enumerado, crea una operación\n * que muestre el nombre del día de la semana dependiendo del número entero\n * utilizado (del 1 al 7). \"\"\"\n\nclass WeekDay(Enum):\n    MONDAY = 1\n    TUESDAY = 2\n    WEDNESDAY = 3\n    THURSDAY = 4\n    FRIDAY = 5\n    SATURDAY = 6\n    SUNDAY = 7\n\n    @classmethod\n    def today(cls):\n        print(\"Today is %s\" % cls(date.today().isoweekday()).name)\n\n\nWeekDay.today() # Today is Friday\n\ndef show_week_day(num: Literal[1, 2, 3, 4, 5, 6, 7]):\n    try:\n        day = WeekDay(num)\n        print(f\"The day is {day.name}\")\n\n    except ValueError:\n        print(\"Invalid Week Number\")\n\n\nfor i in range(1, 8):\n    show_week_day(i)\n\n\"\"\"\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un pequeño sistema de gestión del estado de pedidos.\n * Implementa una clase que defina un pedido con las siguientes características:\n * - El pedido tiene un identificador y un estado.\n * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n * - Implementa las funciones que sirvan para modificar el estado:\n *   - Pedido enviado\n *   - Pedido cancelado\n *   - Pedido entregado\n *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n * - Crea diferentes pedidos y muestra cómo se interactúa con ellos. \n */\n\"\"\"\n\nclass OrderState(Enum):\n    PENDING = 0\n    SENDED = 1\n    DELIVERED = 2\n    CANCELED = 3\n\nclass Order:\n    def __init__(self, identificator: int):\n        self.identificator = identificator\n        print(f\"Orden creada, identificador: {self.identificator}\")\n        self._state = OrderState.PENDING\n\n    def send(self):\n        if self._state == OrderState.PENDING:\n            self._state = OrderState.SENDED\n        else:\n            raise ValueError(f\"No se puede enviar el pedido. Estado: {self._state.name}\")\n        \n    def cancel(self):\n        if self._state in (OrderState.PENDING, OrderState.SENDED):\n            self._state = OrderState.CANCELED\n        else:\n            raise ValueError(f\"No se puede cancelar el pedido. Estado: {self._state.name}\")\n        \n    def deliver(self):\n        if self._state == OrderState.SENDED:\n            self._state = OrderState.DELIVERED\n        else:\n            raise ValueError(f\"No se puede entregar el pedido. Estado: {self._state.name}\")\n\n    def current_state(self):\n        description = {\n            OrderState.PENDING: \"Pendiente\",\n            OrderState.SENDED: \"Enviado\",\n            OrderState.CANCELED: \"Cancelado\",\n            OrderState.DELIVERED: \"Entregado\"\n        }\n        return f\"Pedido: {self.identificator}, Estado: {description[self._state]}\"\n    \n\n# Uso\n\nif __name__ == \"__main__\":\n    print(\"-----Gestión de Pedidos-----\")\n    order1 = Order(1)\n    print(order1.current_state())\n    order1.send()\n    print(order1.current_state())\n    order1.deliver()\n    print(order1.current_state())\n\n    order2 = Order(2)\n    order2.send()\n    print(order2.current_state())\n    order2.cancel()\n    print(order2.current_state())\n\n    order3 = Order(3)\n    order3.send()\n    order3.deliver()\n    print(order3.current_state())\n\n    try:\n        order3.cancel()\n    except ValueError as e:\n        print(f\"Error: {type(e).__name__},\", e)"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/JuanDAW37.py",
    "content": "\"\"\"* Empleando tu lenguaje, explora la definición del tipo de dato\n * que sirva para definir enumeraciones (Enum).\n * Crea un Enum que represente los días de la semana del lunes\n * al domingo, en ese orden. Con ese enumerado, crea una operación\n * que muestre el nombre del día de la semana dependiendo del número entero\n * utilizado (del 1 al 7).\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un pequeño sistema de gestión del estado de pedidos.\n * Implementa una clase que defina un pedido con las siguientes características:\n * - El pedido tiene un identificador y un estado.\n * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n * - Implementa las funciones que sirvan para modificar el estado:\n *   - Pedido enviado\n *   - Pedido cancelado\n *   - Pedido entregado\n *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n * - Crea diferentes pedidos y muestra cómo se interactúa con ellos. \"\"\"\nfrom enum import Enum\n\n# Definición como clase\nclass DiasSem(Enum):\n    lunes = 1\n    martes = 2\n    miercoles = 3\n    jueves = 4\n    viernes = 5\n    sabado = 6\n    domingo = 7\n\n# Otra forma de crearla\ndiasSem = Enum('diasSem', ['lunes', 'martes', 'miércoles', 'jueves', 'viernes', 'sábado', 'domingo'])\n\n# Crea una operación que muestre el nombre del día de la semana dependiendo del número entero utilizado (del 1 al 7).\nnum_Dia = 0\nwhile True:\n    num_Dia = int(input('Escribe un número de día de la semana 1 - 7-> '))\n    if num_Dia >= 1 & num_Dia <= 7:\n        break\nprint(diasSem(num_Dia).name)\n\n#EXTRA\nclass Estado(Enum):\n    PENDIENTE = 1\n    ENVIADO = 2\n    ENTREGADO = 3\n    CANCELADO = 4\n\nclass Pedido():\n    def __init__(self, id_pedido, estado=Estado.PENDIENTE):\n        self.id_pedido = id_pedido\n        self.estado = estado\n    \n    def enviarPedido(self):\n        if self.estado == Estado.PENDIENTE:\n            self.estado = Estado.ENVIADO\n        else:\n            print(f\"El pedido {self.id_pedido}, ya ha sido enviado o cancelado\")\n    \n    def entregarPedido(self):\n        if self.estado == Estado.ENVIADO:\n            self.estado = Estado.ENTREGADO\n        else:\n            print(f\"El pedido {self.id_pedido}, ya ha sido entregado o cancelado\")\n        \n    def cancelarPedido(self):\n        if self.estado != Estado.ENTREGADO:\n            self.estado = Estado.CANCELADO\n        else:\n            print(f\"El pedido {self.id_pedido}, no se puede cancelar, ya ha sido entregado\")\n        \n    def verEstado(self):\n        print(f'El pedido número {self.id_pedido} está: {self.estado.name}')        \n\npedido1 = Pedido(1)\npedido1.verEstado()\n\npedido1.enviarPedido()\npedido1.verEstado()\n\npedido1.entregarPedido()\npedido1.verEstado()\n\npedido1.cancelarPedido()\npedido1.verEstado()"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/Mauricio-Leyva.py",
    "content": "# Ejercicio:\n\nfrom enum import Enum\n\nclass DiaSemana(Enum):\n    LUNES = 1\n    MARTES = 2\n    MIERCOLES = 3\n    JUEVES = 4\n    VIERNES = 5\n    SABADO = 6\n    DOMINGO = 7\n\ndef obtener_dia(numero):\n    dias = {\n        1: DiaSemana.LUNES,\n        2: DiaSemana.MARTES,\n        3: DiaSemana.MIERCOLES,\n        4: DiaSemana.JUEVES,\n        5: DiaSemana.VIERNES,\n        6: DiaSemana.SABADO,\n        7: DiaSemana.DOMINGO\n    }\n    if numero in dias:\n        return dias[numero].name\n    else:\n        return \"Número inválido\"\n\n# Ejemplos de uso\nprint(obtener_dia(1))\nprint(obtener_dia(5))\nprint(obtener_dia(8))\n\n\n# Dificultad extra:\n\nfrom enum import Enum\n\nclass EstadoPedido(Enum):\n    PENDIENTE = 1\n    ENVIADO = 2\n    ENTREGADO = 3\n    CANCELADO = 4\n\nclass Pedido:\n    def __init__(self, id_pedido):\n        self.id_pedido = id_pedido\n        self.estado = EstadoPedido.PENDIENTE\n\n    def enviar_pedido(self):\n        if self.estado == EstadoPedido.PENDIENTE:\n            self.estado = EstadoPedido.ENVIADO\n            print(f\"El pedido {self.id_pedido} ha sido enviado.\")\n        else:\n            print(f\"No se puede enviar el pedido {self.id_pedido} porque su estado actual es {self.estado.name}.\")\n\n    def cancelar_pedido(self):\n        if self.estado == EstadoPedido.PENDIENTE or self.estado == EstadoPedido.ENVIADO:\n            self.estado = EstadoPedido.CANCELADO\n            print(f\"El pedido {self.id_pedido} ha sido cancelado.\")\n        else:\n            print(f\"No se puede cancelar el pedido {self.id_pedido} porque su estado actual es {self.estado.name}.\")\n\n    def entregar_pedido(self):\n        if self.estado == EstadoPedido.ENVIADO:\n            self.estado = EstadoPedido.ENTREGADO\n            print(f\"El pedido {self.id_pedido} ha sido entregado.\")\n        else:\n            print(f\"No se puede entregar el pedido {self.id_pedido} porque su estado actual es {self.estado.name}.\")\n\n    def mostrar_estado(self):\n        print(f\"El pedido {self.id_pedido} tiene el estado: {self.estado.name}\")\n\n# Ejemplo de uso\npedido1 = Pedido(\"P001\")\npedido1.mostrar_estado()  \n\npedido1.enviar_pedido()\npedido1.mostrar_estado()  \n\npedido1.entregar_pedido()\npedido1.mostrar_estado()  \n\npedido1.cancelar_pedido()  \n\npedido2 = Pedido(\"P002\")\npedido2.cancelar_pedido()\npedido2.mostrar_estado()  \n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/Nicojsuarez2.py",
    "content": "# #19 ENUMERACIONES\n> #### Dificultad: Media | Publicación: 06/05/24 | Corrección: 13/05/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Empleando tu lenguaje, explora la definición del tipo de dato\n * que sirva para definir enumeraciones (Enum).\n * Crea un Enum que represente los días de la semana del lunes\n * al domingo, en ese orden. Con ese enumerado, crea una operación\n * que muestre el nombre del día de la semana dependiendo del número entero\n * utilizado (del 1 al 7).\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un pequeño sistema de gestión del estado de pedidos.\n * Implementa una clase que defina un pedido con las siguientes características:\n * - El pedido tiene un identificador y un estado.\n * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n * - Implementa las funciones que sirvan para modificar el estado:\n *   - Pedido enviado\n *   - Pedido cancelado\n *   - Pedido entregado\n *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n * - Crea diferentes pedidos y muestra cómo se interactúa con ellos. \n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/Nightmare79.py",
    "content": "from enum import Enum\n\n\n# EJERCICIO 1\n\nclass DiasSemana(Enum):\n    \"\"\"Enumera Dias de la semana\"\"\"\n    LUNES = 1\n    MARTES = 2\n    MIERCOLES = 3\n    JUEVES = 4\n    VIERNES = 5\n    SABADO = 6\n    DOMINGO = 7\n    \n    \ndef obtener_dia_semana():\n        while True:\n            try:\n                numero = int(input(\"Ingrese el numero del dia de la semana: \"))\n                \n                if numero < 1 or numero > 7:\n                    print(\"Numero del dia de la semana incorrecto, debe ser en el rango de 1 a 7\")\n                    continue\n                \n                mensaje = f\"El dia de la semana es: {DiasSemana(numero).name.capitalize()}\"\n    \n                print(mensaje)\n                \n                break\n            \n            except ValueError:\n                print(\"Debe ser un numero entero en el rango del 1 - 7\")\n                continue\n\n\n# ------------------------------------------------------#\n\n\n# EJERCICIO 2\n\nclass EstadoPedido(Enum):\n    PENDIENTE = 1\n    ENVIADO = 2\n    ENTREGADO = 3\n    CANCELADO = 4\n\n\nclass Pedido:\n    def __init__(self, identificador):\n        # Genera un identificador\n        self.identificador = identificador\n        self.estado = EstadoPedido.PENDIENTE\n    \n    def enviar_pedido(self):\n        if self.estado == EstadoPedido.PENDIENTE:\n            self.estado = EstadoPedido.ENVIADO\n            print(f\"El pedido {self.identificador} ya ha sido enviado\")\n        \n        elif self.estado == EstadoPedido.ENVIADO:\n            print(f\"El pedido {self.identificador} ya fue enviado\")\n        \n        elif self.estado == EstadoPedido.CANCELADO:\n            print(f\"El pedido {self.identificador} ya fue cancelado\")\n        \n        elif self.estado == EstadoPedido.ENTREGADO:\n            print(f\"El pedido {self.identificador} ya fue entregado\")\n                            \n    \n    def cancelar_pedido(self):\n        if self.estado == EstadoPedido.PENDIENTE or self.estado == EstadoPedido.ENVIADO:\n            self.estado = EstadoPedido.CANCELADO\n            print(f\"El pedido {self.identificador} ha sido cancelado\")\n            \n        elif self.estado == EstadoPedido.ENTREGADO:\n            print(f\"No se puede cancelar el pedido {self.identificador} por que ya se entrego\")\n            \n        elif self.estado == EstadoPedido.CANCELADO:\n            print(f\"El pedido {self.identificador} ya fue cancelado\")\n            \n    \n    def entregar_pedido(self):\n        if self.estado == EstadoPedido.ENVIADO:\n            self.estadio = EstadoPedido.ENTREGADO\n            print(f\"El pedido {self.identificador} fue entregado\")\n        \n        elif self.estado == EstadoPedido.PENDIENTE:\n            print(f\"El pedido {self.identificador} aun esta pendiente\")    \n        \n        elif self.estado == EstadoPedido.ENTREGADO:\n            print(f\"El pedido {self.identificador} ya fue entregado\")\n        \n        elif self.estado == EstadoPedido.CANCELADO:\n            print(f\"El pedido {self.identificador} ya fue cancelado\")\n\n\n\nif __name__ == \"__main__\":\n    # Ejemplo de uso del ejercicio 1:\n    obtener_dia_semana()\n    \n    \n    # --------------------------------#\n    \n    \n    # Ejemplos de uso dle ejercicio 2:\n    pedido_1 = Pedido(identificador=1)\n    pedido_2 = Pedido(identificador=2)\n\n\n    pedido_1.enviar_pedido()\n    pedido_1.cancelar_pedido()\n    pedido_1.entregar_pedido()\n\n    pedido_2.cancelar_pedido()\n    pedido_2.entregar_pedido()\n    pedido_2.enviar_pedido()   "
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/Sac-Corts.py",
    "content": "from enum import Enum\n\nclass Weekday(Enum):\n    MONDAY = 1\n    TUESDAY = 2\n    WEDNESDAY = 3\n    THURSDAY = 4\n    FRIDAY = 5\n    SATURDAY = 6\n    SUNDAY = 7\n\ndef get_day(number: int):\n    print(Weekday(number).name)\n\nget_day(7)\nget_day(1)\n\n### Ejercicio Exra ###\n\nclass OrderStatus(Enum):\n    PENDING = 1\n    SENT = 2\n    DELIVERED = 3\n    CANCELLED = 4\n\nclass Order:\n    def __init__(self, identifier):\n        self.identifier = identifier\n        self.status = OrderStatus.PENDING\n\n    def send(self):\n        if self.status == OrderStatus.PENDING:\n            self.status = OrderStatus.SENT\n        else:\n            print(f\"El pedido {self.identifier} no se puede enviar porque su estado actual es {self.status.name}\")\n\n    def cancel(self):\n        if self.status in [OrderStatus.PENDING, OrderStatus.SENT]:\n            self.status = OrderStatus.CANCELLED\n        else:\n            print(f\"El pedido {self.identifier} no se puede cancelar porque su estado actual es {self.status.name}\")\n\n    def deliver(self):\n        if self.status == OrderStatus.SENT:\n            self.status = OrderStatus.DELIVERED\n        else:\n            print(f\"El pedido {self.identifier} no se puede entregar porque su estado actual es {self.status.name}\")\n\n    def show_status(self):\n        status_text = {\n            OrderStatus.PENDING : \"pendiente\",\n            OrderStatus.SENT : \"enviado\",\n            OrderStatus.DELIVERED : \"entregado\",\n            OrderStatus.CANCELLED : \"cancelado\"\n        }\n        return f\"El pedido {self.identifier} está {status_text[self.status]}\"\n    \norder1 = Order(1)\norder2 = Order(2)\n\nprint(order1.show_status())\norder1.send()\nprint(order1.show_status())\norder1.deliver()\nprint(order1.show_status())\n\nprint(order2.show_status())\norder2.cancel()\nprint(order2.show_status())\norder2.deliver()\nprint(order2.show_status())"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/SooHav.py",
    "content": "# 19 - Enummeraciones\n\n# Ejercicio\n\nfrom enum import Enum\nimport datetime\n# import pytz\n\n\nclass DiasDeSemana(Enum):\n    LUNES = 1\n    MARTES = 2\n    MIERCOLES = 3\n    JUEVES = 4\n    VIERNES = 5\n    SABADO = 6\n    DOMINGO = 7\n\n    @classmethod\n    def dia(cls, numero):\n        print(cls(numero).name)\n\n    @classmethod\n    def dia_actual(cls):\n        # hoy = datetime.datetime.now(tz).isoweekday()\n        hoy = datetime.datetime.now().isoweekday()\n        print(f\"Hoy es {cls(hoy).name}\")\n\n\n# Para usar la función que muestra el día actual\n# tz = pytz.timezone('America/Buenos_Aires')\nDiasDeSemana.dia_actual()\n# Para usar la función que muestra un día particular\nnumero = int(\n    input(\"Ingresa un número del 1 al 7 para conocer el día elegido:\\n\"))\nDiasDeSemana.dia(numero)\n\n\n# Extra\n\n\nclass Estado(Enum):\n    PENDIENTE = 0\n    ENVIADO = 1\n    ENTREGADO = 2\n    CANCELADO = 3\n\n\nclass GestionPedidos:\n    def __init__(self):\n        self.pedidos = {}\n\n    def nuevo_pedido(self, id_pedido):\n        self.pedidos[id_pedido] = Estado.PENDIENTE\n\n    def cambiar_estado(self, id_pedido, nuevo_estado):\n        if id_pedido in self.pedidos:\n            estado_actual = self.pedidos[id_pedido]\n            transiciones = {\n                Estado.PENDIENTE: [Estado.ENVIADO, Estado.CANCELADO],\n                Estado.ENVIADO: [Estado.ENTREGADO],\n                Estado.ENTREGADO: [],\n                Estado.CANCELADO: []\n            }\n\n            if nuevo_estado in transiciones[estado_actual]:\n                self.pedidos[id_pedido] = nuevo_estado\n                print(f\"Estado del pedido {\n                      id_pedido} cambiado a {nuevo_estado.name}\")\n            else:\n                raise ValueError(f\"No se puede cambiar el estado de {\n                                 estado_actual.name} a {nuevo_estado.name}\")\n        else:\n            raise ValueError(f\"No se encontró el pedido con ID {id_pedido}\")\n\n    def estado_pedido(self, id_pedido):\n        if id_pedido in self.pedidos:\n            return self.pedidos[id_pedido]\n        else:\n            raise ValueError(f\"No se encontró el pedido con ID {id_pedido}\")\n\n\n# Crear una instancia de la clase GestionPedidos\ngestion = GestionPedidos()\n\nwhile True:\n    print(\"\\nMenú:\")\n    print(\"1. Nuevo pedido\")\n    print(\"2. Cambiar estado de un pedido\")\n    print(\"3. Consultar estado de un pedido\")\n    print(\"4. Salir\")\n\n    opcion = input(\"Seleccione una opción: \")\n\n    if opcion == \"1\":\n        while True:\n            try:\n                id_pedido = int(input(\"Ingrese el ID del nuevo pedido: \"))\n                if id_pedido in gestion.pedidos:\n                    raise ValueError(f\"Ya existe un pedido con ID {id_pedido}\")\n                else:\n                    gestion.nuevo_pedido(id_pedido)\n                    print(f\"Nuevo pedido registrado con ID {id_pedido}\")\n                    break  # Salir del bucle si el ID es válido\n            except ValueError:\n                print(\"Error: Ingrese un ID válido (número entero).\")\n\n    elif opcion == \"2\":\n        while True:\n            try:\n                id_pedido = int(\n                    input(\"Ingrese el ID del pedido a modificar: \"))\n                nuevo_estado = Estado(int(input(\n                    \"Ingrese el nuevo estado (0: PENDIENTE, 1: ENVIADO, 2: ENTREGADO, 3: CANCELADO): \")))\n                gestion.cambiar_estado(id_pedido, nuevo_estado)\n                break  # Salir del bucle si el ID es válido\n            except ValueError:\n                print(\"Error: Ingrese un  nuevo estado.\")\n\n    elif opcion == \"3\":\n        id_pedido = int(input(\"Ingrese el ID del pedido a consultar: \"))\n        estado_actual = gestion.estado_pedido(id_pedido)\n        print(f\"El estado actual del pedido {\n              id_pedido} es: {estado_actual.name}\")\n\n    elif opcion == \"4\":\n        print(\"Saliendo del programa...\")\n        break\n\n    else:\n        print(\"Opción no válida. Intente de nuevo.\")\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/Trufoplus.py",
    "content": "###############################################################################\n### ENUMERACIONES:\n### (https://docs.python.org/es/3.14/howto/enum.html#enum-basic-tutorial)\n###############################################################################\nfrom enum import Enum\n\n# Definimos el Enum para los dias de la semana\nclass Weekday(Enum):\n    MONDAY = 1\n    TUESDAY = 2\n    WEDNESDAY = 3\n    THURSDAY = 4\n    FRIDAY = 5\n    SATURDAY = 6\n    SUNDAY = 7\n\n# Solicitamos el dia de la semana para los numeros de 1 al 7\nfor day in range(1, 8): \n    print(Weekday(day).name)\n    \n###############################################################################\n### DIFICULTAD EXTRA\n###############################################################################\n\nclass OrderStatus(Enum):\n    PENDIENTE = 1\n    ENVIADO = 2\n    CANCELADO = 3\n    ENTREGADO = 4\n\nclass Order():\n    def __init__(self, id:str):\n        self.id = id\n        self.status = OrderStatus(1)       \n    \n    def change_status(self):\n        print(\"\\nSelecciona el nuevo estado del pedido (del 2 al 4): \")\n        new_status = OrderStatus(int(input(\"2:ENVIADO, 3:CANCELADO, 4:ENTREGADO: \")))\n            \n        if self.status == OrderStatus.CANCELADO:\n            print(\"*EL pedido ha sido cancelado, no se puede modificar\")\n        elif new_status.value <= self.status.value:\n            print(f\"*El pedido ya ha sido {self.status.name.lower()} no se puede cambiar a {new_status.name.lower()}\")\n        else:\n            self.status = new_status\n            print(f\"Pedido cambiado a {self.status.name.lower()}\")\n        print(self)\n        self.new_change()\n        \n    def new_change(self):\n        new_change = input(\"\\n¿quieres cambiar el estado (si/no): \").lower()\n        if new_change == \"si\":\n            self.change_status()\n                      \n    def __str__(self):\n        return f\"\\nEstado del pedido:\\nId: {self.id}\\nStatus: {self.status.name.capitalize()}\" \n\ndef new_order():\n    id = input(\"identificador del pedido: \")    \n    return Order(id)\n\n\nmy_order = new_order()\nprint(my_order)\nmy_order.change_status()\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/Vikernes27666.py",
    "content": "# 19 ENUMERACIONES\n\n\"\"\"SOLUCIÓN - PROBLEMA DÍAS DE LA SEMANA \"\"\"\n\nfrom enum import Enum\n\n# Definición del Enum\n\n\nclass DiaSemana(Enum):\n    LUNES = 1\n    MARTES = 2\n    MIERCOLES = 3\n    JUEVES = 4\n    VIERNES = 5\n    SABADO = 6\n    DOMINGO = 7\n\n# Función\n\n\ndef nombre_dia():\n    try:\n        numero = int(input(\"Ingrese el número del día (1 al 7): \"))\n        dia = DiaSemana(numero)\n        return dia.name.capitalize()\n    except ValueError:\n        return \"Número de día inválido\"\n\n\n# Salida:\nprint(nombre_dia())\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/adra-dev.py",
    "content": "\"\"\"\nEJERCICIO:\nEmpleando tu lenguaje, explora la definición del tipo de dato\nque sirva para definir enumeraciones (Enum).\nCrea un Enum que represente los días de la semana del lunes\nal domingo, en ese orden. Con ese enumerado, crea una operación\nque muestre el nombre del día de la semana dependiendo del número entero\nutilizado (del 1 al 7).\n \nDIFICULTAD EXTRA (opcional):\nCrea un pequeño sistema de gestión del estado de pedidos.\nImplementa una clase que defina un pedido con las siguientes características:\n- El pedido tiene un identificador y un estado.\n- El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n- Implementa las funciones que sirvan para modificar el estado:\n- Pedido enviado\n- Pedido cancelado\n- Pedido entregado\n(Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n- Implementa una función para mostrar un texto descriptivo según el estado actual.\n- Crea diferentes pedidos y muestra cómo se interactúa con ellos. \n\nby adra-dev\n\"\"\"\n\nfrom enum import Enum\n\nclass day_of_week(Enum):\n    MONDAY = 1\n    TUESDAY = 2\n    WEDNESDAY = 3\n    THURSDAY = 4\n    FRIDAY = 5\n    SATURDAY = 6\n    SUNDAY = 7\n\n\ndef get_day(number:int):\n    print(day_of_week(number).name)\n\n\nget_day(1)\nget_day(5)\n\n\n\"\"\"\nExtra\n\"\"\"\n\n\nclass OrderStatus(Enum):\n    PENDING = 1\n    SHIPPED = 2\n    DELIVERED = 3\n    CANCELED = 4\n\n\nclass Order:\n\n    status = OrderStatus.PENDING\n\n    def __init__(self, id) -> None:\n        self.id = id\n\n    def ship(self):\n        if self.status == OrderStatus.PENDING:\n            self.status = OrderStatus.SHIPPED\n            self.display_status()\n        else:\n            print(\"El pedido ya ha sido enviado o cancelado\")\n\n    def deliver(self):\n        if self.status == OrderStatus.SHIPPED:\n            self.status = OrderStatus.DELIVERED\n            self.display_status()\n        else:\n            print(\"El pedido necesita ser enviado antes de entregarse.\")\n\n    def cancel(self):\n        if self.status != OrderStatus.DELIVERED:\n            self.status = OrderStatus.CANCELLED\n            self.display_status()\n        else:\n            print(\"El pedido no se puede cancelar ya que ya se ha entregado.\")\n\n    def display_status(self):\n        print(f\"El estado del pedido {self.id} es {self.status.name}\")\n\n\norder_1 = Order(1)\norder_1.display_status()\norder_1.deliver()\norder_1.ship()\norder_1.deliver()\norder_1.cancel()"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/agusrosero.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Empleando tu lenguaje, explora la definición del tipo de dato\n * que sirva para definir enumeraciones (Enum).\n * Crea un Enum que represente los días de la semana del lunes\n * al domingo, en ese orden. Con ese enumerado, crea una operación\n * que muestre el nombre del día de la semana dependiendo del número entero\n * utilizado (del 1 al 7).\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un pequeño sistema de gestión del estado de pedidos.\n * Implementa una clase que defina un pedido con las siguientes características:\n * - El pedido tiene un identificador y un estado.\n * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n * - Implementa las funciones que sirvan para modificar el estado:\n *   - Pedido enviado\n *   - Pedido cancelado\n *   - Pedido entregado\n *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n * - Crea diferentes pedidos y muestra cómo se interactúa con ellos. \n */\n\"\"\"\nfrom enum import Enum\n\n\nclass DiasDeLaSemana(Enum):\n    LUNES = 1\n    MARTES = 2\n    MIERCOLES = 3\n    JUEVES = 4\n    VIERNES = 5\n    SABADO = 6\n    DOMINGO = 7\n\n    def mostrar_dia_semana(num):\n        if num == 1:\n            return DiasDeLaSemana.LUNES.name\n        elif num == 2:\n            return DiasDeLaSemana.MARTES.name\n        elif num == 3:\n            return DiasDeLaSemana.MIERCOLES.name\n        elif num == 4:\n            return DiasDeLaSemana.JUEVES.name\n        elif num == 5:\n            return DiasDeLaSemana.VIERNES.name\n        elif num == 6:\n            return DiasDeLaSemana.SABADO.name\n        elif num == 7:\n            return DiasDeLaSemana.DOMINGO.name\n        else:\n            print(\"Error, elige el numero del dia de la semana, del 1 al 7\")\n\n\ndias = DiasDeLaSemana.mostrar_dia_semana(3)\nprint(dias)\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/alanshakir.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Empleando tu lenguaje, explora la definición del tipo de dato\n * que sirva para definir enumeraciones (Enum).\n * Crea un Enum que represente los días de la semana del lunes\n * al domingo, en ese orden. Con ese enumerado, crea una operación\n * que muestre el nombre del día de la semana dependiendo del número entero\n * utilizado (del 1 al 7).\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un pequeño sistema de gestión del estado de pedidos.\n * Implementa una clase que defina un pedido con las siguientes características:\n * - El pedido tiene un identificador y un estado.\n * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n * - Implementa las funciones que sirvan para modificar el estado:\n *   - Pedido enviado\n *   - Pedido cancelado\n *   - Pedido entregado\n *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n * - Crea diferentes pedidos y muestra cómo se interactúa con ellos. \n */\n\"\"\"\nfrom enum import Enum\n\nclass WeekDay(Enum):\n    MONDAY = 1\n    TUESDAY = 2\n    WEDNESDAY = 3\n    THURSDAY = 4\n    FRIDAY = 5\n    SATURDAY = 6\n    SUNDAY = 7\n\ndef week_day(day):\n    print(WeekDay(day).name)\nweek_day(4)\n\n#EXTRA\n\nclass Status(Enum):\n    PENDIENTE = 1\n    ENVIADO = 2\n    ENTREGADO = 3\n    CANCELADO = 4\n\nclass Order():\n    status = Status.PENDIENTE\n    def __init__(self, id_order) -> None:\n        self.id = id_order\n    \n    def display_order(self):\n        print(f\"La orden {self.id} tiene el siguiente estado: {self.status.name}\")\n\n    def send_order(self):\n        if self.status == Status.PENDIENTE:\n            self.status = Status.ENVIADO\n            self.display_order()\n        else:\n            print(\"El pedido no se encuentra PENDIENTE\")\n    \n    def cancel_order(self):\n        if self.status != Status.ENTREGADO:\n            self.status = Status.CANCELADO\n            self.display_order()\n        else:\n            print(\"El pedido se encuentra ENTREGADO\")\n\n    def deliver_order(self):\n        if self.status == Status.ENVIADO:\n            self.status = Status.ENTREGADO\n            self.display_order()\n        else:\n            print(\"El pedido necesita ser enviado\")\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/any7dev.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Empleando tu lenguaje, explora la definición del tipo de dato\n * que sirva para definir enumeraciones (Enum).\n * Crea un Enum que represente los días de la semana del lunes\n * al domingo, en ese orden. Con ese enumerado, crea una operación\n * que muestre el nombre del día de la semana dependiendo del número entero\n * utilizado (del 1 al 7).\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un pequeño sistema de gestión del estado de pedidos.\n * Implementa una clase que defina un pedido con las siguientes características:\n * - El pedido tiene un identificador y un estado.\n * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n * - Implementa las funciones que sirvan para modificar el estado:\n *   - Pedido enviado\n *   - Pedido cancelado\n *   - Pedido entregado\n *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n * - Crea diferentes pedidos y muestra cómo se interactúa con ellos. \n */ \"\"\"\n\n#EJERCICIO\nfrom enum import Enum\n\nclass Dias(Enum):\n    LUNES = 1\n    MARTES = 2\n    MIERCOLES = 3\n    JUEVES = 4\n    VIERNES = 5\n    SÁBADO = 6\n    DOMINGO = 7\n\ndef mostrar_dia(numero):\n    print(Dias(numero).name)\n\nmostrar_dia(2)\nmostrar_dia(7)\n\n#DIFICULTAD EXTRA\nclass Estados(Enum):\n    PENDIENTE = 1\n    ENVIADO = 2\n    ENTREGADO = 3\n    CANCELADO = 0\n\nclass Pedido:\n\n    estado = Estados.PENDIENTE\n\n    def __init__(self, id):\n        self.id = id\n        \n    def enviar(self):\n        if (self.estado is not Estados.CANCELADO) and (self.estado is not Estados.ENTREGADO) and (self.estado is not Estados.ENVIADO):\n            self.estado = Estados.ENVIADO\n            print(f\"Pedido {self.id} enviado\")\n        else:\n            print(f\"No se puede enviar el pedido {self.id}, su estado es {self.mostrar()}\")\n\n    def cancelar(self):\n        if (self.estado is not Estados.CANCELADO) and (self.estado is not Estados.ENTREGADO):\n            self.estado = Estados.CANCELADO\n            print(f\"Pedido {self.id} cancelado\")\n        else:\n            print(f\"No se puede cancelar el pedido {self.id}, su estado es {self.mostrar()}\")\n\n    def entregar(self):\n        if (self.estado is not Estados.CANCELADO) and (self.estado is not Estados.ENTREGADO):\n            self.estado = Estados.ENTREGADO\n            print(f\"Pedido {self.id} entregado\")\n        else:\n            print(f\"No se puede entregar el pedido {self.id}, su estado es {self.mostrar()}\")\n\n    def mostrar(self):\n        return self.estado.name\n\npedido1 = Pedido(\"001\")\npedido1.cancelar()\n\npedido2 = Pedido(\"002\")\npedido2.enviar()\n\npedido3 = Pedido(\"003\")\npedido3.entregar()\npedido3.cancelar()\n\npedido4 = Pedido(\"004\")\npedido4.cancelar()\npedido4.enviar()\n\npedido5 = Pedido(\"005\")\npedido5.enviar()\npedido5.entregar()"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/avcenal.py",
    "content": "\"\"\"\n* EJERCICIO:\n * Empleando tu lenguaje, explora la definición del tipo de dato\n * que sirva para definir enumeraciones (Enum).\n * Crea un Enum que represente los días de la semana del lunes\n * al domingo, en ese orden. Con ese enumerado, crea una operación\n * que muestre el nombre del día de la semana dependiendo del número entero\n * utilizado (del 1 al 7).\n\"\"\"\n\nfrom enum import Enum\nfrom time import sleep\n\nclass Weekdays(Enum):\n    Lunes = 1\n    Martes = 2\n    Miércoles = 3\n    Jueves = 4\n    Viernes = 5\n    Sábado = 6\n    Domingo = 7\n\ndef find_weekday(num):\n    print(f\"El día de la semana correspondiente al {num} es el {Weekdays(num).name}\")\n\nwhile True:\n    number = int(input(\"Introduce un número del 1 al 7: \"))\n    if number > 7 or number < 1:\n        print (\"El número ha de ser mayor que 1 y menor que 7\")\n    else:\n        find_weekday(number)\n        break\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un pequeño sistema de gestión del estado de pedidos.\n * Implementa una clase que defina un pedido con las siguientes características:\n * - El pedido tiene un identificador y un estado.\n * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n * - Implementa las funciones que sirvan para modificar el estado:\n *   - Pedido enviado\n *   - Pedido cancelado\n *   - Pedido entregado\n *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n * - Crea diferentes pedidos y muestra cómo se interactúa con ellos. \n\"\"\"\n\nclass Status(Enum):\n    PENDIENTE = 1\n    ENVIADO = 2\n    ENTREGADO = 3\n    CANCELADO = 4\n\nclass Order():\n    def __init__(self,id): #se inicializa un pedido directamente como pendiente\n        self.id = id\n        self.status = Status.PENDIENTE\n\n    def check_id(self,num):\n        if int(num) == int(self.id):\n            return True\n        else:\n            return False\n\n    def show_order(self):\n        print(f\"NÚMERO DE PEDIDO: {self.id}\")\n        print(f\"ESTADO: {self.status.name}\")\n        print(\"\\n\")\n    \n    def send_order(self):\n        if self.status == Status.CANCELADO:\n            print(\"El pedido no puede ser enviado porque está cancelado\")\n        elif self.status == Status.ENTREGADO:\n            print(\"El pedido no puede ser enviado porque ya está entregado\")\n        elif self.status == Status.ENVIADO:\n            print(\"El pedido ya ha sido enviado previamente\")\n        else:\n            self.status = Status.ENVIADO\n            print(f\"Pedido {self.id} ENVIADO\")\n        print(\"\\n\")\n\n    def cancel_order(self):\n        if self.status == Status.ENVIADO:\n            print(\"El pedido no puede ser cancelado porque ya se ha enviado\")\n        elif self.status == Status.ENTREGADO: #or self.status == Status.ENVIADO:\n            print(\"El pedido no se puede cancelar porque ya está entregado\")\n        elif self.status == Status.CANCELADO:\n            print(\"El pedido ya ha sido cancelado anteriormente\")\n        else:\n            self.status = Status.CANCELADO\n            print(f\"Pedido {self.id} CANCELADO\")\n        print(\"\\n\")\n\n    def order_delivered(self):\n        if self.status == Status.CANCELADO:\n            print(\"El pedido no se puede entregar porque está cancelado\")\n        elif self.status == Status.ENTREGADO:\n            print(\"El pedido ya ha sido entregado anteriormente\")\n        elif self.status != Status.ENVIADO:\n            print(\"El pedido no ha sido enviado aún, no se puede marcar como entregado\")\n        else:\n            self.status = Status.ENTREGADO\n            print(f\"Pedido {self.id} ENTREGADO\")\n        print(\"\\n\")\n\nprint(\"\\n\")\nprint(\"TE DOY LA BIENVENIDA AL PROGRAMA DE GESTIÓN DE PEDIDOS\")\norders = list()\nwhile True:\n    option  = input(\"¿Qué quieres hacer?\\n - Registrar un nuevo pedido(N)\\n - Mostrar el estado de un pedido(S)\\n - Enviar un pedido(E)\\n - Cancelar un pedido(C)\\n - Marcar un pedido como entregado(D)\\n - Mostrar todos los pedidos(A)\\n - Salir(O)\\nIntroduce la opción ---->\").lower()\n    if len(orders)==0 and option != \"n\":\n            print(\"No hay pedidos registrados en el sistema...\")\n            print(\"\\n\")\n            sleep(1)\n    else:\n        if option == \"n\":\n            num_order = int(input(\"Entendido, dime el número de pedido: \"))\n            for element in orders:\n                if int(num_order) == int(element.id):\n                    print(f\"El pedido {num_order} se encuentra ya registrado en sistema\")\n                    break\n            else:\n                new_order = Order(num_order)\n                orders.append(new_order)\n                print(f\"Pedido con ID {num_order} creado y almacenado en el sistema\")\n            sleep(1)\n        elif option == \"s\":\n            order_id = input(\"Ok, dime el id del pedido que quieres ver: \")\n            for order in orders:\n                if order.check_id(order_id):\n                    print(\"A continuación te muestro el pedido solicitado:\")\n                    order.show_order()\n                    break\n            else:\n                print(\"No hay ningún pedido con ese id...\")\n            sleep(1)\n        elif option == \"e\":\n            order_id = input(\"Vale, dime el id del pedido que quieres marcar como enviado: \")\n            for order in orders:\n                if order.check_id(order_id):\n                    order.send_order()\n                    break\n            else:\n                print(\"No hay pedidos con ese id...\")\n            sleep(1)\n        elif option == \"c\":\n            order_id = input(\"Entendido, dime el id del pedido que deseas cancelar: \")\n            for order in orders:\n                if order.check_id(order_id):\n                    order.cancel_order()\n                    break\n            else:\n                print(\"No existe ningún pedido con ese id en el sistema...\")\n            sleep(1)\n        elif option == \"d\":\n            order_id = input(\"Perfecto, dime el id del pedido que quieres marcar como entregado: \")\n            for order in orders:\n                if order.check_id(order_id):\n                    order.order_delivered()\n                    break\n            else:\n                print(\"No hay ningún pedido en el sistema con ese id...\")\n            sleep(1)\n        elif option == \"a\":\n            print(\"Estos son los pedidos que hay en el sistema:\")\n            print(\"\\n\")\n            for order in orders:\n                order.show_order()\n            sleep(1)\n        elif option == \"o\":\n            print(\"GRACIAS POR USAR EL PROGRAMA DE GESTIÓN DE PEDIDOS. HASTA PRONTO.\")\n            print(\"\\n\")\n            break\n        else:\n            print(\"La opción no es válida, prueba de nuevo...\")\n            sleep(1)\n        print(\"\\n\")\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/barrancus.py",
    "content": "#19 - Python\n# \n# EJERCICIO:\n# Empleando tu lenguaje, explora la definición del tipo de dato\n# que sirva para definir enumeraciones (Enum).\n# Crea un Enum que represente los días de la semana del lunes\n# al domingo, en ese orden. Con ese enumerado, crea una operación\n# que muestre el nombre del día de la semana dependiendo del número entero\n# utilizado (del 1 al 7).\n# \n# DIFICULTAD EXTRA (opcional):\n# Crea un pequeño sistema de gestión del estado de pedidos.\n# Implementa una clase que defina un pedido con las siguientes características:\n# - El pedido tiene un identificador y un estado.\n# - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n# - Implementa las funciones que sirvan para modificar el estado:\n#   - Pedido enviado\n#   - Pedido cancelado\n#   - Pedido entregado\n#   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n# - Implementa una función para mostrar un texto descriptivo según el estado actual.\n# - Crea diferentes pedidos y muestra cómo se interactúa con ellos. \n# /\nfrom random import randint\nimport datetime\nclass Counter:\n    def __iter__(self):\n        self.a = 1\n        return self\n    \n    def __next__(self):\n        x = self.a\n        self.a += 1\n        return x\n\ndef serparacion(cadena) -> str:\n    global contador\n    print(f'\\nEjercicio {next(contador)}. {cadena * 20}')\n\ndef basic() -> None:\n    serparacion(\"_:_\")\n    week_days = enumerate(('Lunes', 'Martes', 'Miercoles', 'Jueves', 'Viernes', 'Sabado', 'Domingo'),start=1)\n    for contday in range(7):\n        print(next(week_days))\n    serparacion(\"_:_\")\n    search_day = randint(1,7)\n    for num_day, day in enumerate(('Lunes', 'Martes', 'Miercoles', 'Jueves', 'Viernes', 'Sabado', 'Domingo'),start=1):\n        if search_day == num_day:\n            print(f'El día de la semana {search_day} es {day}')\n\nclass Pedido:\n    \n    def __init__(self):\n        self.identifier = self.gen_cod_ped()\n        # El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n        self.states = ('PENDIENTE', 'ENVIADO', 'ENTREGADO', 'TERMINADO', 'CANCELADO', 'FINALIZADO')\n        self.change_order = enumerate(self.states,start=1)\n        self.state = next(self.change_order)\n\n    def __str__(self):\n        return f'El pedido \"{self.identifier}\" se encuentra \"{self.state}\"'\n    \n    def __repr__(self):\n        return f'Pedido({self.identifier}, {self.state})'\n    \n    def gen_cod_ped(self) -> str:\n        tnw = datetime.datetime.now()\n        code=f'{tnw.strftime(\"%Y\")}{tnw.strftime(\"%V\")}{tnw.strftime(\"%m\")}{tnw.strftime(\"%d\")}{tnw.strftime(\"%j\"):03}{tnw.strftime(\"%w\")}{tnw.strftime(\"%H\")}{tnw.strftime(\"%M\")}{tnw.strftime(\"%S\")}{tnw.strftime(\"%f\")}'\n        return code\n    \n    def change_state(self):\n        try:\n            self.state = next(self.change_order)\n        except StopIteration:\n            print('Ya está en el estado final, no se puede cambiar el estado.')\n\n    def force_state(self, state: str) -> bool:\n        if state not in self.states:\n            print(f'El valor introducido \"{state}\" no es correcto.\\nSolo se aceptan \"{self.states}\"')\n            return False\n        for ind, expre in enumerate(self.states,start=1):\n            if expre == state:\n                if (ind - 1) in self.state:\n                    self.state = next(self.change_order)\n                    print(self)\n                    return True\n                elif state == 'CANCELADO':\n                    while 'CANCELADO' not in self.state:\n                        self.state = next(self.change_order)\n                    print(self)\n                    return True\n                else:\n                    print(f'No se permite pasar de {self.state} a {state}')\n                    return False\n    def print_item(self):\n        print(self)\n\ndef extra() -> None:\n    \n    serparacion(\"_:_\")\n    pedidos=[]\n\n    def search_ped(option) -> None:\n        ped_id = input('\\nIntroduzca el número de pedido.\\nPedido: ')\n        for pedido in pedidos:\n            if pedido.identifier == ped_id:\n                if option == \"3\":\n                    pedido.change_state()\n                elif option == \"4\":\n                    ped_state = (input('Introduzca el nuevo estado del pedido.\\nEstado: ')).upper()\n                    if pedido.force_state(ped_state): print('Operación exitosa.')\n                else:\n                    print('El pedido no existe.')\n    \n    while True:\n        print(\"\\nSelecciona una de las siguientes opciones:\")\n        print('1) Para añadir un pedido.')\n        print('2) Para listar los pedidos.')\n        print('3) Para modificar estado de un pedido.')\n        print('4) Para forzar el estado de un pedido.')\n        print('0) Para Salir.')\n        option = input('Opcion: ')\n        match option:\n            case \"0\":\n                print(\"Programa finlizado.\")\n                break\n            case \"1\":\n                pedidos.append(Pedido())\n            case \"2\":\n                for pedido in pedidos:\n                    pedido.print_item()\n            case \"3\":\n                search_ped(option)\n            case \"4\":\n                search_ped(option)\n            case _:\n                print('Seleccione una opción correcta.')\n\ndef main() -> None:\n    basic()\n    extra()\n\ncontador = iter(Counter())\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/cesar-ch.py",
    "content": "from enum import Enum\n\n\nclass DiaSemana(Enum):\n    LUNES = 1\n    MARTES = 2\n    MIERCOLES = 3\n    JUEVES = 4\n    VIERNES = 5\n    SABADO = 6\n    DOMINGO = 7\n\n\ndef nombre_dia(numero):\n    try:\n        return DiaSemana(numero).name\n    except ValueError:\n        return \"Número de día inválido\"\n\n\nprint(nombre_dia(1))\nprint(nombre_dia(3))\n\n\"\"\"\n     DIFICULTAD EXTRA\n\"\"\"\n\n\nclass EstadoPedido(Enum):\n    PENDIENTE = \"pendiente\"\n    ENVIADO = \"enviado\"\n    ENTREGADO = \"entregado\"\n    CANCELADO = \"cancelado\"\n\n\nclass Pedido:\n    def __init__(self, estado):\n        self.estado = estado\n\n    def pedido_enviado(self):\n        if self.estado == EstadoPedido.PENDIENTE:\n            self.estado = EstadoPedido.ENVIADO\n        else:\n            print(\"El pedido no puede ser enviado en su estado actual\")\n\n    def pedido_entregado(self):\n        if self.estado == EstadoPedido.ENVIADO:\n            self.estado = EstadoPedido.ENTREGADO\n        else:\n            print(\"El pedido no puede ser entregado en su estado actual\")\n\n    def pedido_cancelado(self):\n        if self.estado == EstadoPedido.PENDIENTE:\n            self.estado = EstadoPedido.CANCELADO\n        else:\n            print(\"El pedido no puede ser cancelado en su estado actual\")\n\n    def estado_actual(self):\n        return f\"Estado del pedido: {self.estado.name}\"\n\n\npedido1 = Pedido(EstadoPedido.PENDIENTE)\npedido2 = Pedido(EstadoPedido.ENVIADO)\n\nprint(pedido1.estado_actual()) \npedido1.pedido_enviado()\nprint(pedido1.estado_actual())  \n\npedido2.pedido_cancelado()\nprint(pedido2.estado_actual())  \n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/cristianfloyd.py",
    "content": "# EJERCICIO:\n# Empleando tu lenguaje, explora la definición del tipo de dato\n# que sirva para definir enumeraciones (Enum).\n# Crea un Enum que represente los días de la semana del lunes\n# al domingo, en ese orden. Con ese enumerado, crea una operación\n# que muestre el nombre del día de la semana dependiendo del número entero\n# utilizado (del 1 al 7).\n\nfrom enum import Enum\n\n\nclass DiasSemana(Enum):\n    LUNES = 1\n    MARTES = 2\n    MIERCOLES = 3\n    JUEVES = 4\n    VIERNES = 5\n    SABADO = 6\n    DOMINGO = 7\n\n\ndef mostrar_dia_semana() -> None:\n    dia = input(\"Introduce el numero del dia de la semana: \")\n    if not dia.isdigit() or int(dia) < 1 or int(dia) > 7:\n        print(\"Error, el numero del dia de la semana debe ser entre 1 y 7\")\n        return mostrar_dia_semana()\n    else:\n        dia = int(dia)\n        print(DiasSemana(dia).name)\n\n\nmostrar_dia_semana()\n\n\n#\n# DIFICULTAD EXTRA (opcional):\n# Crea un pequeño sistema de gestión del estado de pedidos.\n# Implementa una clase que defina un pedido con las siguientes características:\n# - El pedido tiene un identificador y un estado.\n# - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n# - Implementa las funciones que sirvan para modificar el estado:\n#   - Pedido enviado\n#   - Pedido cancelado\n#   - Pedido entregado\n#   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n# - Implementa una función para mostrar un texto descriptivo según el estado actual.\n# - Crea diferentes pedidos y muestra cómo se interactúa con ellos.\n\n\nclass EstadoPedido(Enum):\n    PENDIENTE = 1\n    ENVIADO = 2\n    ENTREGADO = 3\n    CANCELADO = 4\n\n\nclass Pedido:\n    def __init__(self, id: int, estado: EstadoPedido = EstadoPedido.PENDIENTE) -> None:\n        self.id = id\n        self.estado = estado\n\n    def enviar(self) -> None:\n        if self.estado == EstadoPedido.PENDIENTE:\n            self.estado = EstadoPedido.ENVIADO\n            print(f\"El pedido {self.id} ha sido enviado\")\n        else:\n            print(\n                f\"El pedido {self.id} no puede ser enviado porque su estado es {self.estado.name}\"\n            )\n\n    def cancelar(self) -> None:\n        if self.estado == EstadoPedido.PENDIENTE:\n            self.estado = EstadoPedido.CANCELADO\n            print(f\"El pedido {self.id} ha sido cancelado\")\n        else:\n            print(\n                f\"El pedido {self.id} no puede ser cancelado porque su estado es {self.estado.name}\"\n            )\n\n    def entregar(self) -> None:\n        if self.estado == EstadoPedido.ENVIADO:\n            self.estado = EstadoPedido.ENTREGADO\n            print(f\"El pedido {self.id} ha sido entregado\")\n        else:\n            print(\n                f\"El pedido {self.id} no puede ser entregado porque su estado es {self.estado.name}\"\n            )\n\n    def mostrar_estado(self) -> None:\n        print(f\"El estado del pedido {self.id} es {self.estado.name}\")\n\n\npedidos = [\n    Pedido(1, EstadoPedido.PENDIENTE),\n    Pedido(2, EstadoPedido.ENVIADO),\n    Pedido(3, EstadoPedido.ENTREGADO),\n    Pedido(4, EstadoPedido.CANCELADO),\n]\n\nfor pedido in pedidos:\n    pedido.mostrar_estado()\n    pedido.enviar()\n    pedido.entregar()\n    pedido.cancelar()\n    pedido.mostrar_estado()"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/cub-tor.py",
    "content": "from enum import Enum\n\nclass Week(Enum):\n    MONDAY = 1\n    TUESDAY = 2\n    WEDNESDAY = 3\n    THURSDAY = 4\n    FRIDAY = 5\n    SATURDAY = 6\n    SUNDAY = 7\n\n    def showDayWeek(number):\n        if number == 1:\n            return Week.MONDAY.name\n        elif number == 2:\n            return Week.TUESDAY.name\n        elif number == 3:\n            return Week.WEDNESDAY.name\n        elif number == 4:\n            return Week.THURSDAY.name\n        elif number == 5:\n            return Week.FRIDAY.name\n        elif number == 6:\n            return Week.SATURDAY.name\n        elif number == 7:\n            return Week.SUNDAY.name\n        else:\n            return \"Elige el número de día de la semana, del 1 al 7\"\n\n# print(Week.showDayWeek(1)) # Monday\n\n# Clase para definir los distintos estados de un pedido\nclass Status(Enum):\n    PENDING = 1\n    SHIPPED = 2\n    DELIVERED = 3\n    CANCELED = 4\n\n    \n# Clase para definir un pedido\nclass Order ():\n    # Constructor\n    def __init__(self, id, numberStatus):\n        self.id = id\n        self.numberStatus = numberStatus\n        \n    # Función para mostrar el estado del pedido\n    def showStatus(self):\n        status = \"\"\n        if self.numberStatus == 1:\n            status = Status.PENDING.name\n        elif self.numberStatus == 2:\n            status = Status.SHIPPED.name\n        elif self.numberStatus == 3:\n            status = Status.DELIVERED.name\n        elif self.numberStatus == 4:\n            status = Status.CANCELED.name\n        else:\n            status = \"Error en el pedido\"\n        return status\n\n\n    # Función para modificar el estado\n    def changeStatus (self):\n        if self.numberStatus == 1: # si está pendiente puede pasar a enviado\n            self.numberStatus = 2\n        elif self.numberStatus == 2: #si está enviado puede pasar a entregado\n            self.numberStatus = 3\n        elif self.numberStatus == 3: # si está entregado no se puede modificar su estado\n            print (\"El pedido ya ha sido entregado\")\n        elif self.numberStatus == 4: # si se ha cancelado no se puede modificar su estado\n            print (\"El pedido ha sido cancelado\")\n        else:\n            print(\"Hay algún error en su pedido\")\n        return self.numberStatus\n    \n    # Función para mostrar un texto descriptivo según el estado actual\n    def commentStatus(self):\n        comment = \"\"\n        if self.numberStatus == 1:\n            comment = f\"El estado de su pedido es: {Status.PENDING.name}. Se enviará en los próximos días.\"\n        elif self.numberStatus == 2:\n            comment = f\"El estado de su pedido es: {Status.SHIPPED.name}. Lo recibirá en los próximos días.\"\n        elif self.numberStatus == 3:\n            comment = f\"El estado de su pedido es: {Status.DELIVERED.name}.\"\n        elif self.numberStatus == 4:\n            comment = f\"El estado de su pedido es: {Status.CANCELED.name}. Si desea que se lo enviemos vuelva a solicitarlo\"\n        else:\n            comment = \"Hay un error en su pedido.\"\n        return comment\n \n                \n# Diferentes pedidos de ejemplo\n\norder1 = Order(1, 1) # primer objeto order1\nprint(\"ID:\", order1.id)\nprint(\"Número de estado:\", order1.numberStatus)\nprint(\"Estado:\", order1.showStatus())\nprint(\"Comentario:\", order1.commentStatus())\nprint(\"Cambio de estado:\", order1.changeStatus())\nprint(\"Nuevo estado:\", order1.showStatus())\nprint(\"Comentario del estado nuevo:\", order1.commentStatus())\n\norder2 = Order(2, 4) # segundo objeto order2\nprint(\"ID:\", order2.id)\nprint(\"Número de estado:\", order2.numberStatus)\nprint(\"Estado:\", order2.showStatus())\nprint(\"Comentario:\", order2.commentStatus())\nprint(\"Cambio de estado:\", order2.changeStatus())\nprint(\"Nuevo estado:\", order2.showStatus())\nprint(\"Comentario del estado nuevo:\", order2.commentStatus())"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/danielhdzr.py",
    "content": "# #19 ENUMERACIONES\n#### Dificultad: Media | Publicación: 06/05/24 | Corrección: 13/05/24\n\n## Ejercicio\n\n'''\n * EJERCICIO:\n * Empleando tu lenguaje, explora la definición del tipo de dato\n * que sirva para definir enumeraciones (Enum).\n * Crea un Enum que represente los días de la semana del lunes\n * al domingo, en ese orden. Con ese enumerado, crea una operación\n * que muestre el nombre del día de la semana dependiendo del número entero\n * utilizado (del 1 al 7).\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un pequeño sistema de gestión del estado de pedidos.\n * Implementa una clase que defina un pedido con las siguientes características:\n * - El pedido tiene un identificador y un estado.\n * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n * - Implementa las funciones que sirvan para modificar el estado:\n *   - Pedido enviado\n *   - Pedido cancelado\n *   - Pedido entregado\n *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n * - Crea diferentes pedidos y muestra cómo se interactúa con ellos. \n'''\n\nfrom enum import Enum\n\nclass weekday(Enum):\n    LUNES = 1\n    MARTES  = 2\n    MIERCOLES = 3\n    JUEVES = 4\n    VIERNES = 5\n    SABADO = 6\n    DOMINGO = 7\n\ndef get_day(number: int):\n    print(weekday(number).name)\n\nget_day(1)\nget_day(5)\nprint(\"**********************************\")\n\n# Estado del pedido \nclass estado(Enum):\n    PENDIENTE = 1  # name.value\n    ENVIADO = 2\n    ENTREGADO = 3\n    CANCELADO = 4\n\n# Clase para la orden\nclass Order:\n    # Estado predeterminado\n    status_envio = estado.PENDIENTE\n\n    def __init__(self, id) -> None:\n        self.id = id\n\n    def ship(self):\n        if self.status_envio == estado.PENDIENTE:  # si status de envio es pendiente cambia \n            self.status_envio = estado.ENVIADO  # cambia a enviado\n            self.display_status()  # muestra el estado del pedido\n        else:  # si no es pendiente, imprime mensaje\n            print(\"El pedido ya ha sido enviado o cancelado\")\n\n    def deliver(self):\n        if self.status_envio == estado.ENVIADO:\n            self.status_envio = estado.ENTREGADO\n            self.display_status()\n        else:\n            print(\"El pedido necesita ser enviado antes de entregarse.\")\n\n    def cancel(self):\n        if self.status_envio != estado.ENTREGADO:\n            self.status_envio = estado.CANCELADO\n            self.display_status()\n        else:\n            print(\"El pedido no se puede cancelar ya que ya se ha entregado.\")\n\n    def display_status(self):\n        print(f\"El estado del pedido {self.id} es {self.status_envio.name}\")\n\n\norder_1 = Order(1)\norder_1.display_status()\norder_1.deliver()\norder_1.ship()\norder_1.deliver()\norder_1.cancel()"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/davidrguez98.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Empleando tu lenguaje, explora la definición del tipo de dato\n * que sirva para definir enumeraciones (Enum).\n * Crea un Enum que represente los días de la semana del lunes\n * al domingo, en ese orden. Con ese enumerado, crea una operación\n * que muestre el nombre del día de la semana dependiendo del número entero\n * utilizado (del 1 al 7).\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un pequeño sistema de gestión del estado de pedidos.\n * Implementa una clase que defina un pedido con las siguientes características:\n * - El pedido tiene un identificador y un estado.\n * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n * - Implementa las funciones que sirvan para modificar el estado:\n *   - Pedido enviado\n *   - Pedido cancelado\n *   - Pedido entregado\n *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n * - Crea diferentes pedidos y muestra cómo se interactúa con ellos. \n */ \"\"\"\n\nfrom enum import Enum\n\n#EJERCICIO\n\nclass Weekday(Enum):\n    MONDAY = 1\n    TUESDAY = 2\n    WEDNESDAY = 3\n    THURSDAY = 4\n    FRIDAY = 5\n    SATURDAY = 6\n    SUNDAY = 7\n\ndef get_day(number: int):\n    print(Weekday(number))\n\nget_day(1)\nget_day(2)\nget_day(3)\nget_day(4)\nget_day(5)\nget_day(6)\nget_day(7)\n\n#DIFICULTAD EXTRA\n\nclass order_status(Enum):\n    Pending = 1\n    Shipped = 2\n    Delivered = 3\n    Cancelled = 4\n\nclass order():\n\n    status = order_status.Pending\n\n    def __init__(self, id):\n        self.id = id\n\n    def ship(self):\n        if self.status == order_status.Pending:\n            self.status = order_status.Shipped\n            print(\"El pedido ya ha sido enviado.\")\n        else:\n            print(\"El pedido ya ha sido enviado o cancelado.\")\n\n    def deliver(self):\n        if self.status == order_status.Shipped:\n            self.status = order_status.Delivered\n            print(\"El pedido ya se ha enviado.\")\n        else:\n            print(\"El pedido necesita ser enviado antes de entregarse.\")\n\n    def cancel(self):\n        if self.status == order_status.Pending:\n            self.status = order_status.Cancelled\n            print(\"El pedido se ha cancelado.\")\n        elif self.status == order_status.Shipped:\n            print(\"El pedido no puede ser cancelado porque ya se ha enviado.\")\n        elif self.status == order_status.Delivered:\n            print(\"El pedido no puede ser cancelado porque ya se ha entregado.\")\n        else:\n            print(\"El pedido ya ha sido cancelado previamente.\")\n\n    def display_status(self):\n        print(f\"El estado del pedido {self.id} es {self.status.name}\")\n\nOrder1 = order(1)\nOrder1.display_status()\nOrder1.deliver()\nOrder1.display_status()\nOrder1.ship()\nOrder1.display_status()\nOrder1.deliver()\nOrder1.display_status()"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/didacdev.py",
    "content": "from enum import Enum\n\n\nclass Day_of_the_week(Enum):\n    MONDAY = 1\n    TUESDAY = 2\n    WEDNESDAY = 3\n    THURSDAY = 4\n    FRIDAY = 5\n    SATURDAY = 6\n    SUNDAY = 7\n\n\nclass State(Enum):\n    PENDIENTE = 1\n    ENVIADO = 2\n    CANCELADO = 3\n    ENTREGADO = 4\n\n\nclass Order:\n    id: int\n    state: State\n\n    def __init__(self, id):\n        self.id = id\n        self.state = State.PENDIENTE\n\n    def pedido_enviado(self):\n        if self.state != State.CANCELADO:\n            self.state = State.ENVIADO\n        else:\n            print(f\"El pedido {self.id} ha sido cancelado\")\n\n    def pedido_cancelado(self):\n        if self.state == State.PENDIENTE:\n            self.state = State.CANCELADO\n        else:\n            print(f\"El pedido {self.id} ya ha sido enviado o entregado\")\n\n    def pedido_entregado(self):\n        if self.state == State.ENVIADO:\n            self.state = State.ENTREGADO\n        else:\n            print(f\"El pedido {self.id} no ha sido enviado\")\n\n    def print_state(self):\n        print(f\"El estado del pedido {self.id} es: {self.state.name}\")\n\n\ndef number_of_the_day(day: Day_of_the_week):\n    print(f\"{day.name} is the {day.value} day of the week\")\n\n\ndef main():\n    number_of_the_day(Day_of_the_week.MONDAY)\n\n    order1 = Order(1)\n    order2 = Order(2)\n    order3 = Order(3)\n\n    order1.print_state()\n    order2.print_state()\n    order3.print_state()\n\n    order1.pedido_cancelado()\n    order2.pedido_enviado()\n    order3.pedido_entregado()\n\n    order1.print_state()\n    order2.print_state()\n    order3.print_state()\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/duendeintemporal.py",
    "content": "#19 { Retos para Programadores } ENUMERACIONES\n\n# Bibliography reference\n# Professional JavaScript for web developers by Matt Frisbie [Frisbie, Matt] (z-lib.org)\n#Python Notes for Professionals. 800+ pages of professional hints and tricks (GoalKicker.com) (Z-Library)\n# Additionally, I use GPT as a reference and sometimes to correct or generate proper comments.\n\n\"\"\"  \n * EJERCICIO:\n * Empleando tu lenguaje, explora la definición del tipo de dato\n * que sirva para definir enumeraciones (Enum).\n * Crea un Enum que represente los días de la semana del lunes\n * al domingo, en ese orden. Con ese enumerado, crea una operación\n * que muestre el nombre del día de la semana dependiendo del número entero\n * utilizado (del 1 al 7).\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un pequeño sistema de gestión del estado de pedidos.\n * Implementa una clase que defina un pedido con las siguientes características:\n * - El pedido tiene un identificador y un estado.\n * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n * - Implementa las funciones que sirvan para modificar el estado:\n *   - Pedido enviado\n *   - Pedido cancelado\n *   - Pedido entregado\n *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n * - Crea diferentes pedidos y muestra cómo se interactúa con ellos. \n\n\"\"\"\n\n# Function to simulate console.log\nlog = print\n# Days of the week as a constant dictionary\nclass DaysOfWeek:\n    MONDAY = 'Monday'\n    TUESDAY = 'Tuesday'\n    WEDNESDAY = 'Wednesday'\n    THURSDAY = 'Thursday'\n    FRIDAY = 'Friday'\n    SATURDAY = 'Saturday'\n    SUNDAY = 'Sunday'\n\n# Function to show the day based on input\ndef show_day(day):\n    w_days = [DaysOfWeek.MONDAY, DaysOfWeek.TUESDAY, DaysOfWeek.WEDNESDAY,\n              DaysOfWeek.THURSDAY, DaysOfWeek.FRIDAY, DaysOfWeek.SATURDAY,\n              DaysOfWeek.SUNDAY]\n    return w_days[day - 1] if 1 <= day <= 7 else 'You entered an invalid day, try between 1 and 7'\n\nlog(DaysOfWeek.MONDAY)  # Monday\nlog(show_day(3))  # Wednesday\n\n# Extra Difficulty Exercise\n\n# Enum simulation\nclass OrderStatus:\n    PENDING = 'Pending'\n    SHIPPED = 'Shipped'\n    DELIVERED = 'Delivered'\n    CANCELED = 'Canceled'\n\n# Order class\nclass Order:\n    def __init__(self, id):\n        self.id = id\n        self.state = OrderStatus.PENDING\n\n    def set_state(self, state):\n        self.state = getattr(OrderStatus, state)\n\n    def get_state(self):\n        return self.state\n\n    def ship_order(self):\n        if self.state.lower() == OrderStatus.PENDING.lower():\n            log('The order is Shipped')\n            self.set_state('SHIPPED')\n        else:\n            log(f'Cannot ship. Current state: {self.state}')\n\n    def deliver_order(self):\n        if self.state.lower() == OrderStatus.SHIPPED.lower():\n            log('The order is Delivered')\n            self.set_state('DELIVERED')\n        else:\n            log(f'Cannot deliver. The order state is: {self.state}')\n\n    def cancel_order(self):\n        if self.state.lower() == OrderStatus.DELIVERED.lower():\n            log('Cannot cancel. The order has already been delivered.')\n        log('The order is Canceled')\n        self.set_state('CANCELED')\n\n    def describe_order(self):\n        log(f'Order ID: {self.id}, Current State: {self.state}')\n\n# Creating order instances\norder15 = Order('001')\norder16 = Order('002')\norder17 = Order('003')\n\norder16.ship_order()  # The order is Shipped\norder15.deliver_order()  # Cannot deliver. The order state is: Pending\norder17.ship_order()  # The order is Shipped\n\norder16.deliver_order()  # The order is Delivered\norder15.ship_order()  # The order is Shipped\norder17.cancel_order()  # The order is Canceled\n\nlog(order16.get_state())  # Delivered\nlog(order15.get_state())  # Shipped\nlog(order17.get_state())  # Canceled\n\norder16.ship_order()  # Cannot ship. Current state: Delivered\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/fborjalv.py",
    "content": "from enum import Enum\n\n\"\"\"\n/*\n * EJERCICIO:\n * Empleando tu lenguaje, explora la definición del tipo de dato\n * que sirva para definir enumeraciones (Enum).\n * Crea un Enum que represente los días de la semana del lunes\n * al domingo, en ese orden. Con ese enumerado, crea una operación\n * que muestre el nombre del día de la semana dependiendo del número entero\n * utilizado (del 1 al 7).\n\n\"\"\"\n\n\nclass days_of_week(Enum):\n    MONDAY = 1\n    TUESDAY = 2\n    WEDNESDAY = 3\n    THURSDAY = 4\n    FRIDAY = 5\n    SATURDAY = 6\n    SUNDAY = 7\n\n\ndef show_day(number):\n    print(days_of_week(number).name)\n\nshow_day(5)\n\n\"\"\"\n\nDIFICULTAD EXTRA (opcional):\n * Crea un pequeño sistema de gestión del estado de pedidos.\n * Implementa una clase que defina un pedido con las siguientes características:\n * - El pedido tiene un identificador y un estado.\n * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n * - Implementa las funciones que sirvan para modificar el estado:\n *   - Pedido enviado\n *   - Pedido cancelado\n *   - Pedido entregado\n *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n * - Crea diferentes pedidos y muestra cómo se interactúa con ellos. \n */\n\n\"\"\"\n\nclass OrderStatus(Enum):\n    PENDIENTE = 1\n    ENVIADO = 2\n    ENTREGADO = 3\n    CANCELADO = 4\n\nclass Order:\n\n    status = OrderStatus.PENDIENTE\n    def __init__(self, id) -> None:\n        self.id = id\n\n    def pedido_enviado(self):\n        if self.status == OrderStatus.PENDIENTE:\n            print(\"Hemos enviado el pedido\")\n            self.status = OrderStatus.ENVIADO\n            self.estado_actual()\n        else:\n            print(\"Pedido no disponible para enviar\")\n\n\n    def pedido_entregado(self):\n        if self.status == OrderStatus.ENVIADO:\n            self.status = OrderStatus.ENTREGADO\n            print(\"Hemos entregado el pedido\")\n            self.estado_actual()\n        else:\n            print(\"El pedido aún no está en reparto\")\n\n    def pedido_cancelado(self):\n        if self.status == OrderStatus.ENTREGADO or  self.status == OrderStatus.ENVIADO:\n            print(\"No se puede cancelar el pedido\")\n            self.estado_actual()\n        else:\n            self.status = OrderStatus.CANCELADO\n            self.estado_actual()\n    def estado_actual(self):\n        print(f\"ESTADO ACTUAL DEL PEDIDO: {self.status.name}\")\n\n\nnew_order = Order(19)\n\nprint(new_order.status.name)\nnew_order.pedido_enviado()\nnew_order.pedido_entregado()\nnew_order.pedido_cancelado()"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/garos01.py",
    "content": "from enum import Enum\n\n\nclass DiaSemana(Enum):\n    LUNES = 1\n    MARTES = 2\n    MIERCOLES = 3\n    JUEVES = 4\n    VIERNES = 5\n    SABADO = 6\n    DOMINGO = 7\n\n\ndef obtener_nombre_dia(numero):\n    if 1 <= numero <= 7:\n        return DiaSemana(numero).name.capitalize()\n    else:\n        return \"Número de día no válido\"\n\n\nnumero_dia = 6\nprint(f\"El día {numero_dia} es {obtener_nombre_dia(numero_dia)}\")\n\n\n# Ejercicio extra\n\n\nclass EstadoPedido(Enum):\n    PENDIENTE = 1\n    ENVIADO = 2\n    ENTREGADO = 3\n    CANCELADO = 4\n\n\nclass Pedido:\n    def __init__(self, identificador):\n        self.identificador = identificador\n        self.estado = EstadoPedido.PENDIENTE\n\n    def pedido_enviado(self):\n        if self.estado == EstadoPedido.PENDIENTE:\n            self.estado = EstadoPedido.ENVIADO\n            print(f\"Pedido {self.identificador} enviado.\")\n\n    def pedido_entregado(self):\n        if self.estado == EstadoPedido.ENVIADO:\n            self.estado = EstadoPedido.ENTREGADO\n            print(f\"Pedido {self.identificador} entregado.\")\n\n    def pedido_cancelado(self):\n        if self.estado != EstadoPedido.ENTREGADO:\n            self.estado = EstadoPedido.CANCELADO\n            print(f\"Pedido {self.identificador} cancelado.\")\n\n    def mostrar_estado(self):\n        estado_descripcion = {\n            EstadoPedido.PENDIENTE: \"El pedido está pendiente de envío.\",\n            EstadoPedido.ENVIADO: \"El pedido ha sido enviado pero aún no ha sido entregado.\",\n            EstadoPedido.ENTREGADO: \"El pedido ha sido entregado con éxito.\",\n            EstadoPedido.CANCELADO: \"El pedido ha sido cancelado.\",\n        }\n        print(\n            f\"Estado del pedido {self.identificador}: {estado_descripcion[self.estado]}\"\n        )\n\n\n# Ejemplo de uso\npedido1 = Pedido(\"0001\")\npedido1.mostrar_estado()\npedido1.pedido_enviado()\npedido1.mostrar_estado()\npedido1.pedido_entregado()\npedido1.mostrar_estado()\n\npedido2 = Pedido(\"0002\")\npedido2.mostrar_estado()\npedido2.pedido_cancelado()\npedido2.mostrar_estado()\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/ggilperez.py",
    "content": "# 19 Enumerates\nimport uuid\nfrom enum import Enum\n\n\nclass Weekdays(Enum):\n    Monday = 1\n    Tuesday = 2\n    Wednesday = 3\n    Thursday = 4\n    Friday = 5\n    Saturday = 6\n    Sunday = 7\n\ndef show_day(num):\n    print(Weekdays(num).name)\n\nshow_day(2)\n\n# Extra\n\nclass ShipStatus(Enum):\n    PENDING = 1\n    SENT = 2\n    DELIVERED = 3\n    CANCELED = 4\n\nclass Order:\n\n    def __init__(self):\n        self.id = uuid.uuid4()\n        self.state: ShipStatus = ShipStatus.PENDING\n\n    def send(self):\n        if self.state != ShipStatus.PENDING:\n            print(\"Can't send non pending order\")\n        else:\n            self.state = ShipStatus.SENT\n            print(f\"Order {self.id} sent\")\n\n    def cancel(self):\n        if self.state not in [ShipStatus.SENT, ShipStatus.PENDING]:\n            print(\"Can't cancel non sent or pending order\")\n        else:\n            self.state = ShipStatus.CANCELED\n            print(f\"Order {self.id} cancelled\")\n\n    def deliver(self):\n        if self.state not in [ShipStatus.SENT]:\n            print(\"Can't deliver non sent order\")\n        else:\n            self.state = ShipStatus.DELIVERED\n            print(f\"Order {self.id} delivered\")\n\norder_1 = Order()\norder_1.deliver()\norder_1.send()\norder_1.cancel()\norder_1.send()\norder_1.deliver()\n\norder_2 = Order()\norder_2.send()\norder_2.deliver()\norder_1.cancel()"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/gringoam.py",
    "content": "from enum import Enum\r\n\r\n\r\n\r\n\"\"\"\r\nEjercicio\r\n\"\"\"\r\n\r\nclass Semana(Enum):\r\n\r\n    LUNES=1\r\n    MAERTES=2\r\n    MIERCOLES=3\r\n    JUEVES=4\r\n    VIERNES=5\r\n    SABADO=6\r\n    DOMINGO=7\r\n\r\ndef dia(num_dia: int):\r\n   print(Semana(num_dia).name)\r\n\r\ndia(5)\r\n\r\n\r\n\"\"\"\r\nExtra\r\n\"\"\"\r\nclass Estado(Enum):\r\n    PENDIENTE= 1\r\n    ENVIADO=2\r\n    ENTREGADO=3\r\n    CANCELADO=4\r\n\r\nclass  Pedido():\r\n    estado= Estado.PENDIENTE\r\n\r\n    def __init__(self, numero:int) -> None:\r\n        self.numero= numero\r\n        \r\n    \r\n    def enviar(self):\r\n        if self.estado == Estado.PENDIENTE:\r\n            self.estado= Estado.ENVIADO\r\n            self.mostrar_estado()\r\n        else:\r\n            print(\"El pedido ya fue enviado o cancelado\")\r\n\r\n    def entregar(self):\r\n        if self.estado == Estado.ENVIADO:\r\n            self.estado= Estado.ENTREGADO\r\n            self.mostrar_estado()\r\n        else:\r\n            print(\"El pedido tiene que ser enviado antes de entregarse\")\r\n\r\n    def cancelar(self):\r\n        if self.estado != Estado.ENTREGADO:\r\n            self.estado= Estado.CANCELADO\r\n            self.mostrar_estado()\r\n        else:\r\n            print(\"El pedido ya fue entregado no se puede cancelar\")\r\n\r\n    def mostrar_estado(self):\r\n        print(f\"El el estado del pedido {self.numero} es {self.estado.name}\")\r\n\r\n\r\npedido1=Pedido(1)\r\npedido1.mostrar_estado()\r\npedido1.entregar()\r\npedido1.enviar()\r\n#pedido1.entregar()\r\npedido1.cancelar()\r\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/hectorio23.py",
    "content": "# Autor: Héctor Adán\n# GitHub: https://github.com/hectorio23 \nfrom enum import Enum\n\nclass EstadoPedido(Enum):\n    PENDIENTE = 1\n    ENVIADO = 2\n    ENTREGADO = 3\n    CANCELADO = 4\n\n# Clase Pedido\nclass Pedido:\n    def __init__(self, _id):\n        self.id = _id\n        self.estado = EstadoPedido.PENDIENTE\n\n    #Metodo para marcar el pedido como enviado\n    def marcar_enviado(self):\n        if self.estado == EstadoPedido.PENDIENTE:\n            self.estado = EstadoPedido.ENVIADO\n            print(f\"El pedido con ID { self.id } ha sido enviado.\")\n        else:\n            print(f\"El pedido con ID { self.id } no se puede enviar en su estado actual.\")\n\n    #Metodo para marcar el pedido como entregado\n    def marcar_entregado(self):\n        if self.estado == EstadoPedido.ENVIADO:\n            self.estado = EstadoPedido.ENTREGADO\n            print(f\"El pedido con ID { self.id } ha sido entregado.\")\n        else:\n            print(f\"El pedido con ID { self.id } no se puede entregar en su estado actual.\")\n\n    # Función para cancelar el pedido\n    def cancelar_pedido(self):\n        if self.estado != EstadoPedido.CANCELADO:\n            self.estado = EstadoPedido.CANCELADO\n            print(f\"El pedido con ID { self.id } ha sido cancelado.\")\n        else:\n            print(f\"El pedido con ID { self.id } ya está cancelado.\")\n\n    # Función para mostrar el estado del pedido\n    def mostrar_estado(self):\n        estado_str = {\n            EstadoPedido.PENDIENTE: \"Pendiente\",\n            EstadoPedido.ENVIADO: \"Enviado\",\n            EstadoPedido.ENTREGADO: \"Entregado\",\n            EstadoPedido.CANCELADO: \"Cancelado\"\n        }\n        print(f\"Estado del pedido con ID { self.id }: { estado_str[self.estado] }\")\n\n# Definición del Enum para los días de la semana\nclass Week(Enum):\n    LUNES = 1\n    MARTES = 2\n    MIERCOLES = 3\n    JUEVES = 4\n    VIERNES = 5\n    SABADO = 6\n    DOMINGO = 7\n\n# Función para mostrar el nombre del día de la semana\ndef nombre_dia_semana(numero_dia):\n    try:\n        dia = Week(numero_dia)\n        return dia.name.capitalize()  # Devuelve el nombre del día con la primera letra mayúscula\n    except ValueError:\n        return \"Número de día inválido\"\n\n# Ejemplo de uso\nprint(\"************ EJERCICIO ***************\")\n\nday = 4\nprint(f\"El día { day } es: {nombre_dia_semana(day)}\")\n\nprint(\"\\n************ EJERCICIO EXTRA ***************\")\n\n# Crear pedidos\npedido1 = Pedido(1)\npedido2 = Pedido(2)\n\n# Mostrar el estado inicial de los pedidos\npedido1.mostrar_estado()\npedido2.mostrar_estado()\n\n# Interactuar con los pedidos\npedido1.marcar_enviado()\npedido2.marcar_enviado()\npedido1.marcar_entregado()\npedido2.cancelar_pedido()\n\n# Mostrar el estado final de los pedidos\npedido1.mostrar_estado()\npedido2.mostrar_estado()\n\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/hozlucas28.py",
    "content": "# pylint: disable=missing-function-docstring,pointless-string-statement,missing-module-docstring,missing-class-docstring,broad-exception-raised,broad-exception-caught\n\nfrom enum import Enum\nfrom typing import Self\n\n\"\"\"\n    Enums...\n\"\"\"\n\nprint(\"Enums...\")\n\nWeekDays = Enum(\n    \"WeekDays\",\n    [\n        \"Monday\",\n        \"Tuesday\",\n        \"Wednesday\",\n        \"Thursday\",\n        \"Friday\",\n        \"Saturday\",\n        \"Sunday\",\n    ],\n)\n\nprint(f\"\\nName of the first week day: {WeekDays.Monday.name}\")\nprint(f\"Name of the second week day: {WeekDays.Tuesday.name}\")\nprint(f\"Name of the third week day: {WeekDays.Wednesday.name}\")\nprint(f\"Name of the fourth week day: {WeekDays.Thursday.name}\")\nprint(f\"Name of the fifth week day: {WeekDays.Friday.name}\")\nprint(f\"Name of the sixth week day: {WeekDays.Saturday.name}\")\nprint(f\"Name of the seventh week day: {WeekDays.Sunday.name}\")\n\nprint(\n    \"\\n# ---------------------------------------------------------------------------------- #\\n\"\n)\n\n\"\"\"\n    Additional challenge...\n\"\"\"\n\nprint(\"Additional challenge...\")\n\nStates = Enum(\n    \"State\",\n    [\n        \"Earring\",\n        \"Sent\",\n        \"Delivered\",\n        \"Cancelled\",\n    ],\n)\n\n\nclass Order:\n    __uid: int\n    __state: States\n\n    def __init__(self, *, uid: int, state: States) -> None:\n        self.__uid = uid\n        self.__state = state\n\n    def get_uid(self) -> int:\n        return self.__uid\n\n    def get_state(self) -> States:\n        return self.__state\n\n    def cancel(self) -> None | Exception:\n        if self.__state == States.Earring:\n            self.__state = States.Cancelled\n            return\n\n        raise Exception(f\"The order with id {self.__uid} can't be cancelled\")\n\n    def deliver(self) -> None | Exception:\n        if self.__state == States.Sent:\n            self.__state = States.Delivered\n            return\n\n        raise Exception(f\"The order with id {self.__uid} can't be delivered\")\n\n    def print_state(self) -> Self:\n        print(f\"The order with id {self.__uid} is {self.__state.name.lower()}\")\n        return self\n\n    def send(self) -> None | Exception:\n        if self.__state == States.Earring:\n            self.__state = States.Sent\n            return\n\n        raise Exception(f\"The order with id {self.__uid} can't be sent\")\n\n\nfirst_order: Order = Order(uid=1, state=States.Earring)\nsecond_order: Order = Order(uid=2, state=States.Sent)\nthird_order: Order = Order(uid=3, state=States.Delivered)\nfourth_order: Order = Order(uid=4, state=States.Cancelled)\n\nprint()\nfirst_order.print_state()\nsecond_order.print_state()\nthird_order.print_state()\nfourth_order.print_state()\n\nfirst_order.send()\nfirst_order.deliver()\n\nprint()\nfirst_order.print_state()\n\nprint()\ntry:\n    second_order.send()\nexcept Exception as error:\n    print(error)\n\ntry:\n    third_order.deliver()\nexcept Exception as error:\n    print(error)\n\ntry:\n    fourth_order.send()\nexcept Exception as error:\n    print(error)\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/idiegorojas.py",
    "content": "\"\"\"\nEnumeracion (enums)\n\"\"\"\n\n# Es una coleccion de nombres que esta asociado a valores\n# Es una forma de darle significado claro y legible a los datos\n# Se crean importando el modulo 'enum' y luego y luego se define la clase que herada enum\n\nfrom enum import Enum\n\nclass Color(Enum):\n    ROJO = 1\n    VERDE = 2\n    AZUL = 3\n\n# Cada iembro tiene un nombre(ROJO) y un valor(1) asociado \n\nprint(Color.ROJO)\nprint(Color.ROJO.value)\nprint(Color.ROJO.name)\n\n\n\"\"\"\nCaracteristicas\n\"\"\"\n\n# Unicos: Los valores en una enumeracion son unicos\n# se usa el decorador @unique para asegurarnos de que no existan duplicados\n\nfrom enum import Enum, unique\n\n@unique\nclass Dia(Enum):\n    LUNES = 1\n    MARTES = 2\n    # MIERCOLES = 1  Esto lanzaria un error\n\n# Iterables: Pueden recorrer los miembros de una enumeracion\n\nfor color in Color:\n    print(color)\n\n\n# Inmutables: Una vez definidos no pueden cambiar su valor\n\n# Tipos especiales: \n    # IntEnum: Para valores enteros y compatibles con operaciones matematicas\n    # Flag: Para convinar valores como banderas binarias\n\nfrom enum import Enum\n\nclass Semaforo(Enum):\n    ROJO = 'Alto'\n    AMARILLO = 'Preparate'\n    VERDE = 'Avanza'\n\nluz_actual = Semaforo.AMARILLO\nprint(f'Estado del semaforo: {luz_actual.value}')\n\n\n\"\"\"\nPor que usar enumeraciones\n\"\"\"\n\n# Claridad: El codigo es ma legible y menos propenso a errores\n# Seguridad: Evita que se usen valores invalidos accidentalmente\n# Mantenibilidad: Si se requiere cambiar un valor, solo se hace en la definicion de la enumeracion \n\n\n\"\"\"\nEjercicio\n\"\"\"\n\nfrom enum import Enum, unique\n\n@unique\nclass DiaSemana(Enum):\n    LUNES = 1\n    MARTES = 2\n    MIERCOLES = 3\n    JUEVES = 4\n    VIERNES = 5\n    SABADO = 6\n    DOMINGO = 7\n\ndef obtener_dia(numero: int):\n    print(f'Dia de la semana: {DiaSemana(numero).name}')\n\nobtener_dia(1)\nobtener_dia(5)\n\n\n\"\"\"\nExtra\n\"\"\"\n\nfrom enum import Enum, unique\n\n@unique\nclass Estado(Enum):\n    PENDIENTE = 1\n    ENVIADO = 2\n    ENTREGADO = 3\n    CANCELADO = 4\n\nclass Orden:\n\n    status = Estado.PENDIENTE\n\n    def __init__(self, id) -> None:\n        self.id = id\n\n    def enviado(self):\n        if self.status == Estado.PENDIENTE:\n            self.status = Estado.ENVIADO\n            self.mostrar_estado()\n        else:\n            ('El pedido ya ha sido enviado o cancelado.')\n\n    def entregado(self):\n        if self.status == Estado.ENVIADO:\n            self.status = Estado.ENTREGADO\n            self.mostrar_estado()\n        else:\n            print('El pedido debe ser enviado antes de entregarse.')\n\n    def cancelado(self):\n        if self.status != Estado.ENTREGADO:\n            self.status = Estado.CANCELADO\n            self.mostrar_estado()\n        else:\n            print('El pedido no se puede cancelar.')\n\n    def mostrar_estado(self):\n        print(f'El estado del pedido {self.id} es: {self.status.name}')\n\n\norden_uno = Orden(1)\norden_uno.mostrar_estado()\norden_uno.entregado()\norden_uno.enviado()\norden_uno.entregado()\norden_uno.cancelado()"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/ignaciovihe.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Empleando tu lenguaje, explora la definición del tipo de dato\n * que sirva para definir enumeraciones (Enum).\n * Crea un Enum que represente los días de la semana del lunes\n * al domingo, en ese orden. Con ese enumerado, crea una operación\n * que muestre el nombre del día de la semana dependiendo del número entero\n * utilizado (del 1 al 7).\n\"\"\"\n\nfrom enum import Enum\n\nclass DayOfWeek(Enum):\n\n    MONDAY = 1\n    TUESDAY = 2\n    WEDNESDAY = 3\n    THURSDAY = 4\n    FRYDAY = 5\n    SATURDAY = 6\n    SUNDAY = 7\n\ndef get_name_day_of_week(number: int):\n    return DayOfWeek(number)\n\ndef get_number_day_of_week(name: str):\n    return DayOfWeek[name]\n\nday = get_name_day_of_week(2)\nprint(day)\nprint(day.name)\n\nday = get_number_day_of_week(\"WEDNESDAY\")\nprint(day)\nprint(day.value)\n\n\n\"\"\"\n * Crea un pequeño sistema de gestión del estado de pedidos.\n * Implementa una clase que defina un pedido con las siguientes características:\n * - El pedido tiene un identificador y un estado.\n * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n * - Implementa las funciones que sirvan para modificar el estado:\n *   - Pedido enviado\n *   - Pedido cancelado\n *   - Pedido entregado\n *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n * - Crea diferentes pedidos y muestra cómo se interactúa con ellos.\n\"\"\"\n\nfrom datetime import datetime\n\nclass OrderStatus(Enum):\n    CANCELED = 0\n    PENDING = 1\n    SHIPPED = 2\n    DELIVERED = 3\n\nclass Order():\n\n    total_orders = 0\n\n    def __init__(self):\n        Order.total_orders += 1\n        self.id = f\"ORD-{datetime.now().year}-{str(Order.total_orders).zfill(3)}\"\n        self.status = OrderStatus.PENDING\n        self.print_status()\n\n    def change_status(self):\n        if 0 < self.status.value < 3:\n            self.status = OrderStatus(self.status.value + 1)\n            self.print_status()\n        else:\n            print(f\"No se puede modificar el estado del pedido {self.id}. - Pedido entregado o cancelado.\")\n\n    def cancel_order(self):\n        if self.status == OrderStatus.PENDING:\n            self.status = OrderStatus.CANCELED\n            self.print_status()\n        else:\n            print(f\"No se puede cancelar el pedido {self.id} debido a que ya ha sido enviado, entregado o cancelado.\")\n\n    def print_status(self):\n        match self.status:\n            case OrderStatus.CANCELED:\n                print(f\"El pedido {self.id} fue cancelado.\")\n            case OrderStatus.PENDING:\n                print(f\"El envío {self.id} esta en preparación y será enviado en breve.\")\n            case OrderStatus.SHIPPED:\n                print(f\"El envío {self.id} ya ha sido envíado y lo recibirá pronto.\")\n            case OrderStatus.DELIVERED:\n                print(f\"El envío {self.id} ha sido entregado.\")\n            \n\n\n\n\norder1 = Order()\norder2 = Order()\norder3 = Order()\norder2.cancel_order()\norder1.change_status()\norder2.change_status()\norder1.change_status()\norder3.change_status()\norder3.change_status()\n\n\n\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/isilanes.py",
    "content": "from enum import Enum\n\n\nclass Day(int, Enum):\n    MONDAY = 1\n    TUESDAY = 2\n    WEDNESDAY = 3\n    THURSDAY = 4\n    FRIDAY = 5\n    SATURDAY = 6\n    SUNDAY = 7\n\n    @property\n    def spanish_name(self) -> str:\n        return {\n            self.MONDAY: \"lunes\",\n            self.TUESDAY: \"martes\",\n            self.WEDNESDAY: \"miércoles\",\n            self.THURSDAY: \"jueves\",\n            self.FRIDAY: \"viernes\",\n            self.SATURDAY: \"sábado\",\n            self.SUNDAY: \"domingo\",\n        }.get(self, \"DESCONOCIDO\")\n\n\ndef main(index: int):\n    print(\"==== EJERCICIO ====\")\n\n    print(f\"\\nAl índice {index} le corresponde el siguiente objeto:\")\n    day = Day(index)\n    print(f\">>> day = Day({index})\")\n    print(f\">>> str(day) == '{str(day)}'\")\n    print(f\"El valor correspondiente es:\")\n    print(f\">>> day.name == '{day.name}'\")\n    print(\"Para imprimir un valor 'humano' usaremos un método personalizado,\")\n    print(\"que deberemos haber implementado nosotros:\")\n    print(f\">>> day.spanish_name == '{day.spanish_name}'\")\n\n\nclass Status(int, Enum):\n    \"\"\"\n    Uso nombres en castellano por respeto al enunciado, pero niños,\n    nunca uséis otra cosa que no sea inglés para nombrar variables.\n    \"\"\"\n    PENDIENTE = 0\n    ENVIADO = 1\n    ENTREGADO = 2\n    CANCELADO = 3\n\n\nclass Order:\n    \"\"\"\n    Implemento la funcionalidad como métodos de la clase, y no como funciones,\n    porque modifican el estado del objeto, porque no modifican nada externo,\n    y porque sólo requieren el propio estado del objeto como entrada.\n\n    Si se dieran otras circunstancias, podría valorarse implementar una función\n    send(order), en vez de un método order.send().\n    \"\"\"\n\n    def __init__(self, oid: int, status: Status = Status.PENDIENTE):\n        self.oid = oid\n        self.status = status\n\n    def send(self) -> bool:\n        \"\"\"\n        Returns:\n             True if succeeded, False otherwise.\n        \"\"\"\n        if self.status == Status.PENDIENTE:\n            print(f\"El pedido {self.oid} pasa de estado {self.status.name} a {Status.ENVIADO.name}.\")\n            self.status = Status.ENVIADO\n            return True\n\n        if self.status == Status.ENVIADO:\n            print(f\"El pedido {self.oid} ya se encuentra en estado {self.status.name}. Ignorando orden...\")\n            return True\n\n        print(f\"El pedido {self.oid} se encuentra en el estado {self.status.name}, y no puede ser enviado.\")\n        return False\n\n    def cancel(self) -> bool:\n        \"\"\"\n        Returns:\n             True if succeeded, False otherwise.\n        \"\"\"\n        if self.status == Status.CANCELADO:\n            print(f\"El pedido {self.oid} ya se encuentra en estado {self.status.name}. Ignorando orden...\")\n            return True\n\n        if self.status == Status.ENTREGADO:\n            print(f\"El pedido {self.oid} se encuentra en estado {self.status.name}, no puede cancelarse.\")\n            return False\n\n        print(f\"El pedido {self.oid} pasa de estado {self.status.name} a {Status.CANCELADO.name}.\")\n        self.status = Status.CANCELADO\n        return True\n\n    def deliver(self) -> bool:\n        \"\"\"\n        Returns:\n             True if succeeded, False otherwise.\n        \"\"\"\n        if self.status == Status.ENVIADO:\n            print(f\"El pedido {self.oid} pasa de estado {self.status.name} a {Status.ENTREGADO.name}.\")\n            self.status = Status.ENVIADO\n            return True\n\n        print(f\"El pedido {self.oid} se encuentra en estado {self.status.name}, y no puede ser entregado.\")\n        return False\n\n\ndef extra():\n    print(\"\\n==== EXTRA ====\")\n\n    print(\"\\nCreamos un pedido con ciclo de vida normal:\")\n    print('>>> order = Order(1)')\n    order = Order(1)\n    print('>>> order.send()')\n    order.send()\n    print('>>> order.deliver()')\n    order.deliver()\n\n    print(\"\\nCreamos un pedido que intentamos enviar dos veces:\")\n    print('>>> order = Order(2)')\n    order = Order(2)\n    print('>>> order.send()')\n    order.send()\n    print('>>> order.send()')\n    order.send()\n\n    print(\"\\nCreamos un pedido que cancelamos antes de enviar, y luego intentamos enviar:\")\n    print('>>> order = Order(3)')\n    order = Order(3)\n    print('>>> order.cancel()')\n    order.cancel()\n    print('>>> order.send()')\n    order.send()\n\n    print(\"\\nCreamos un pedido que intentamos cancelar tras haber sido entregado:\")\n    print('>>> order = Order(4)')\n    order = Order(4)\n    print('>>> order.send()')\n    order.send()\n    print('>>> order.deliver()')\n    order.deliver()\n    print('>>> order.cancel()')\n    order.cancel()\n\n    print(\"\\nCreamos un pedido que intentamos entregar antes de enviar:\")\n    print('>>> order = Order(5)')\n    order = Order(5)\n    print('>>> order.deliver()')\n    order.deliver()\n\n\nif __name__ == \"__main__\":\n    main(index=1)\n    extra()\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/jptxaya.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * Empleando tu lenguaje, explora la definición del tipo de dato\n#  * que sirva para definir enumeraciones (Enum).\n#  * Crea un Enum que represente los días de la semana del lunes\n#  * al domingo, en ese orden. Con ese enumerado, crea una operación\n#  * que muestre el nombre del día de la semana dependiendo del número entero\n#  * utilizado (del 1 al 7).\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea un pequeño sistema de gestión del estado de pedidos.\n#  * Implementa una clase que defina un pedido con las siguientes características:\n#  * - El pedido tiene un identificador y un estado.\n#  * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n#  * - Implementa las funciones que sirvan para modificar el estado:\n#  *   - Pedido enviado\n#  *   - Pedido cancelado\n#  *   - Pedido entregado\n#  *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n#  * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n#  * - Crea diferentes pedidos y muestra cómo se interactúa con ellos. \n#  */\n\ndia_semana = {1:\"Lunes\",\n              2:\"Martes\",\n              3:\"Miercoles\",\n              4:\"Jueves\",\n              5:\"Viernes\",\n              6:\"Sabado\",\n              7:\"Domingo\"}\n\ndef dia_semanal(dia):\n    return dia_semana.get(dia)\n\nprint(dia_semanal(4))\n\nprint(\"Dificultad Extra\")\n\nclass Pedido:\n\n    id = \"\"\n    order_Status = {1:\"PENDIENTE\",\n                    2:\"ENVIADO\",\n                    3:\"ENTREGADO\",\n                    4:\"CANCELADO\"}\n    \n    def __init__(self, param_id) -> None:\n        self.id = param_id\n        self.status = 1\n    \n    def enviado(self) -> None:\n        if self.status == 1 and self.status != 4:\n            self.status = 2\n    \n    def entregado(self) -> None:\n        if self.status == 2 and self.status != 4:\n            self.status = 3\n    \n    def cancelado(self) -> None:\n        if self.status != 3:\n            self.status = 4\n    \n    def estado(self):\n        return (self.order_Status.get(self.status))\n    \n    def str_pedido(self):\n        print(f\"Pedido: {self.id} Estado: {self.estado()}\")\n    \npedido1 = Pedido(\"id01\")\npedido2 = Pedido(\"id02\")\npedido1.str_pedido()\npedido2.str_pedido()\nprint(\"Enviando pedido1, Cancelando pedido2\")\npedido1.enviado()\npedido2.cancelado()\npedido1.str_pedido()\npedido2.str_pedido()\nprint(\"Entregado pedido1, Entregado pedido2\")\npedido1.entregado()\npedido2.entregado()\npedido1.str_pedido()\npedido2.str_pedido()\nprint(\"Cancelado pedido1, Entregado pedido2\")\npedido1.cancelado\npedido2.entregado()\npedido1.str_pedido()\npedido2.str_pedido()\n\n \n        "
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/juandaherrera.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Empleando tu lenguaje, explora la definición del tipo de dato\n * que sirva para definir enumeraciones (Enum).\n * Crea un Enum que represente los días de la semana del lunes\n * al domingo, en ese orden. Con ese enumerado, crea una operación\n * que muestre el nombre del día de la semana dependiendo del número entero\n * utilizado (del 1 al 7).\n\"\"\"\n\nfrom enum import Enum\n\n\nclass WeekDays(Enum):\n    MONDAY = 1\n    TUESDAY = 2\n    WEDNESDAY = 3\n    THURSDAY = 4\n    FRIDAY = 5\n    SATURDAY = 6\n    SUNDAY = 7\n\n\ndef get_day_name(day: int) -> str:\n    return WeekDays(day).name.lower()\n\n\nprint(get_day_name(6))\n\n\n\"\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un pequeño sistema de gestión del estado de pedidos.\n * Implementa una clase que defina un pedido con las siguientes características:\n * - El pedido tiene un identificador y un estado.\n * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n * - Implementa las funciones que sirvan para modificar el estado:\n *   - Pedido enviado\n *   - Pedido cancelado\n *   - Pedido entregado\n *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n * - Crea diferentes pedidos y muestra cómo se interactúa con ellos. \n\"\"\"\n\n\nclass OrderStatus(Enum):\n    PENDING = 1\n    SHIPPED = 2\n    DELIVERED = 3\n    CANCELED = 4\n\n\nclass Order:\n    status = OrderStatus.PENDING\n\n    def __init__(self, id) -> None:\n        self.id = id\n\n    def ship(self):\n        if self.status == OrderStatus.PENDING:\n            self.status = OrderStatus.SHIPPED\n            self.display_status()\n        else:\n            print(\"El pedido ya ha sido enviado o cancelado\")\n\n    def deliver(self):\n        if self.status == OrderStatus.SHIPPED:\n            self.status = OrderStatus.DELIVERED\n            self.display_status()\n        elif self.status == OrderStatus.DELIVERED:\n            print(\"El pedido ya ha sido entregado.\")\n        elif self.status == OrderStatus.CANCELED:\n            print(\"El pedido ha sido cancelado.\")\n        else:\n            print(\"El pedido necesita ser enviado antes de entregarse.\")\n\n    def cancel(self):\n        if self.status != OrderStatus.DELIVERED:\n            self.status = OrderStatus.CANCELED\n            self.display_status()\n        else:\n            print(\"El pedido no se puede cancelar ya que ya se ha entregado.\")\n\n    def display_status(self):\n        print(f\"El estado del pedido {self.id} es {self.status.name}\")\n\n\nmy_order = Order(12336)\nmy_order.display_status()\nmy_order.ship()\nmy_order.deliver()\n\nmy_order_2 = Order(12337)\nmy_order_2.ship()\nmy_order_2.cancel()\nmy_order_2.deliver()\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/juanmax2.py",
    "content": "from enum import Enum\n\n\"\"\"\nEnumeraciones\n\"\"\"\n\nclass Weekday(Enum):\n    MONDAY = 1\n    TUESDAY = 2\n    WEDNESDAY = 3\n    THURSDAY = 4\n    FRIDAY = 5\n    SATURDAY = 6\n    SUNDAY = 7\n    \ndef get_day(id : int):\n    print(Weekday(id).name.title())\n    \nget_day(1)\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un pequeño sistema de gestión del estado de pedidos.\n * Implementa una clase que defina un pedido con las siguientes características:\n * - El pedido tiene un identificador y un estado.\n * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n * - Implementa las funciones que sirvan para modificar el estado:\n *   - Pedido enviado\n *   - Pedido cancelado\n *   - Pedido entregado\n *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n * - Crea diferentes pedidos y muestra cómo se interactúa con ellos. \n\"\"\"\n\nclass Status(Enum):\n    PENDIENTE = 1\n    ENVIADO = 2\n    ENTREGADO = 3\n    CANCELADO = 4\n\nclass Order():\n    \n    status = Status.PENDIENTE\n    \n    def __init__(self, id : int) -> None:\n        self.id = id\n        \n\n    \n    def ship(self):\n        if self.status == Status.PENDIENTE:\n            self.status = Status.ENVIADO\n            self.display_status()\n            \n    def deliver(self):\n        if self.status == Status.ENVIADO:\n            self.status = Status.ENTREGADO\n        self.display_status()\n            \n    def cancel(self):\n        if self.status != Status.ENTREGADO:\n            self.status = Status.CANCELADO\n        self.display_status()\n        \n    def display_status(self):\n        print(f\"Order: {self.id} : Status : {self.status}\")\n    \n    \n\n        \n        \norder_1 = Order(1)\norder_1.display_status()\norder_1.ship()\norder_1.deliver()\n\norder_2 = Order(2)\norder_2.display_status()\norder_2.ship()\norder_2.cancel()\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/juanppdev.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Empleando tu lenguaje, explora la definición del tipo de dato\n * que sirva para definir enumeraciones (Enum).\n * Crea un Enum que represente los días de la semana del lunes\n * al domingo, en ese orden. Con ese enumerado, crea una operación\n * que muestre el nombre del día de la semana dependiendo del número entero\n * utilizado (del 1 al 7).\n\"\"\"\n\nfrom enum import Enum\n\nclass DiaSemana(Enum):\n    LUNES = 1\n    MARTES = 2\n    MIERCOLES = 3\n    JUEVES = 4\n    VIERNES = 5\n    SABADO = 6\n    DOMINGO = 7\n\ndef obtener_nombre_dia(numero):\n    try:\n        return DiaSemana(numero).name\n    except ValueError:\n        return \"Número inválido. Por favor, introduce un número del 1 al 7.\"\n\n# Ejemplo de uso\nfor i in range(1, 8):\n    print(f\"{i}: {obtener_nombre_dia(i)}\")\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un pequeño sistema de gestión del estado de pedidos.\n * Implementa una clase que defina un pedido con las siguientes características:\n * - El pedido tiene un identificador y un estado.\n * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n * - Implementa las funciones que sirvan para modificar el estado:\n *   - Pedido enviado\n *   - Pedido cancelado\n *   - Pedido entregado\n *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n * - Crea diferentes pedidos y muestra cómo se interactúa con ellos. \n\"\"\"\n\nfrom enum import Enum\n\nclass EstadoPedido(Enum):\n    PENDIENTE = 1\n    ENVIADO = 2\n    ENTREGADO = 3\n    CANCELADO = 4\n\nclass Pedido:\n    def __init__(self, identificador):\n        self.identificador = identificador\n        self.estado = EstadoPedido.PENDIENTE\n\n    def enviar(self):\n        if self.estado == EstadoPedido.PENDIENTE:\n            self.estado = EstadoPedido.ENVIADO\n        else:\n            print(\"El pedido no puede ser enviado en su estado actual.\")\n\n    def cancelar(self):\n        if self.estado in [EstadoPedido.PENDIENTE, EstadoPedido.ENVIADO]:\n            self.estado = EstadoPedido.CANCELADO\n        else:\n            print(\"El pedido no puede ser cancelado en su estado actual.\")\n\n    def entregar(self):\n        if self.estado == EstadoPedido.ENVIADO:\n            self.estado = EstadoPedido.ENTREGADO\n        else:\n            print(\"El pedido no puede ser entregado en su estado actual.\")\n\n    def mostrar_estado(self):\n        estados_descriptivos = {\n            EstadoPedido.PENDIENTE: \"El pedido está pendiente.\",\n            EstadoPedido.ENVIADO: \"El pedido ha sido enviado.\",\n            EstadoPedido.ENTREGADO: \"El pedido ha sido entregado.\",\n            EstadoPedido.CANCELADO: \"El pedido ha sido cancelado.\"\n        }\n        return estados_descriptivos[self.estado]\n\ndef mostrar_menu():\n    print(\"\\nMenú de Gestión de Pedidos\")\n    print(\"1. Crear pedido\")\n    print(\"2. Enviar pedido\")\n    print(\"3. Cancelar pedido\")\n    print(\"4. Entregar pedido\")\n    print(\"5. Mostrar estado del pedido\")\n    print(\"6. Salir\")\n\ndef main():\n    pedidos = {}\n    while True:\n        mostrar_menu()\n        opcion = input(\"Selecciona una opción: \")\n        if opcion == '1':\n            identificador = input(\"Introduce el identificador del pedido: \")\n            pedidos[identificador] = Pedido(identificador)\n            print(f\"Pedido {identificador} creado.\")\n        elif opcion == '2':\n            identificador = input(\"Introduce el identificador del pedido a enviar: \")\n            if identificador in pedidos:\n                pedidos[identificador].enviar()\n                print(f\"Pedido {identificador} enviado.\")\n            else:\n                print(\"Pedido no encontrado.\")\n        elif opcion == '3':\n            identificador = input(\"Introduce el identificador del pedido a cancelar: \")\n            if identificador in pedidos:\n                pedidos[identificador].cancelar()\n                print(f\"Pedido {identificador} cancelado.\")\n            else:\n                print(\"Pedido no encontrado.\")\n        elif opcion == '4':\n            identificador = input(\"Introduce el identificador del pedido a entregar: \")\n            if identificador in pedidos:\n                pedidos[identificador].entregar()\n                print(f\"Pedido {identificador} entregado.\")\n            else:\n                print(\"Pedido no encontrado.\")\n        elif opcion == '5':\n            identificador = input(\"Introduce el identificador del pedido: \")\n            if identificador in pedidos:\n                print(pedidos[identificador].mostrar_estado())\n            else:\n                print(\"Pedido no encontrado.\")\n        elif opcion == '6':\n            break\n        else:\n            print(\"Opción no válida. Por favor, selecciona una opción del 1 al 6.\")\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/kenysdev.py",
    "content": "# ╔═════════════════════════════════════╗\n# ║ Autor:  Kenys Alvarado              ║\n# ║ GitHub: https://github.com/Kenysdev ║\n# ║ 2024 -  Python                      ║\n# ╚═════════════════════════════════════╝\n\n# -----------------------------------\n# * ENUMERACIONES\n# -----------------------------------\n# - Una enumeración en Python es un conjunto de nombres simbólicos(miembros) \n#   que están vinculados a valores únicos.\n# - se puede iterar y acceder.\n\n# Mas info: https://docs.python.org/3/library/enum.html\n\n\"\"\"\n * EJERCICIO 1:\n * Empleando tu lenguaje, explora la definición del tipo de dato\n * que sirva para definir enumeraciones (Enum).\n * Crea un Enum que represente los días de la semana del lunes\n * al domingo, en ese orden. Con ese enumerado, crea una operación\n * que muestre el nombre del día de la semana dependiendo del número entero\n * utilizado (del 1 al 7).\n\"\"\"\n\nfrom enum import Enum\n\nclass Weekday(Enum):\n    MONDAY = 1\n    TUESDAY = 2\n    WEDNESDAY = 3\n    THURSDAY = 4\n    FRIDAY = 5\n    SATURDAY = 6\n    SUNDAY = 7\n\ndef get_day(num: int) -> str:\n    try:\n        day = Weekday(num)\n        return day.name\n    except ValueError:\n        return \"'o'\"\n\ndef get_num_day(day: str) -> int:\n    try:\n        return Weekday[day].value\n    except KeyError:\n        return 0\n\nprint(get_day(7))\nprint(get_day(3))\nprint(get_day(8))\n\nprint(get_num_day(\"TUESDAY\"))\nprint(get_num_day(\"FRIDAY\"))\nprint(get_num_day(\"abc\"))\n\n\"\"\"\n * EJERCICIO 2:\n * Crea un pequeño sistema de gestión del estado de pedidos.\n * Implementa una clase que defina un pedido con las siguientes características:\n * - El pedido tiene un identificador y un estado.\n * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n * - Implementa las funciones que sirvan para modificar el estado:\n *   - Pedido enviado\n *   - Pedido cancelado\n *   - Pedido entregado\n *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n * - Crea diferentes pedidos y muestra cómo se interactúa con ellos. \n\"\"\"\n\nprint(\"\\nEJERCICIO 2:\")\n\nclass Status(Enum):\n    PENDING = 1\n    SHIPPED = 2\n    DELIVERED = 3\n    CANCELED = 4\n\nclass Order:\n    def __init__(self, identifier):\n        self.identifier = identifier\n        self._status = Status.PENDING\n    \n    def send(self):\n        print(\"\\nEnviar:\")\n        if self._status == Status.PENDING:\n            self._status = Status.SHIPPED\n            print(self.info())\n        else:\n            print(f\"invalid operation, \", self.info())\n\n    def cancelled(self):\n        print(\"\\nCancelar:\")\n        if self._status == Status.PENDING:\n            self._status = Status.CANCELED\n            print(self.info())\n        else:\n            print(f\"invalid operation, \", self.info())\n    \n    def delivered(self):\n        print(\"\\nEntregar:\")\n        if self._status == Status.SHIPPED:\n            self._status = Status.DELIVERED\n            print(self.info())\n        else:\n            print(f\"invalid operation, \", self.info())\n\n    def info(self):\n        return (f\"{self.identifier} is {self._status.name}\")\n\n# \"Creación de pedidos\"\nlibro1 = Order(\"libro1\")\nlibro2 = Order(\"libro2\")\nlibro3 = Order(\"libro2\")\n\n# Positivas:\nprint(\"\\n-----\\nOperaciones exitosas:\\n-----\")\nlibro1.send()\nlibro1.delivered()\nlibro2.cancelled()\n\n# negativas:\nprint(\"\\n-----\\nOperaciones invalidas:\\n-----\")\nlibro3.delivered()\nlibro2.cancelled()\nlibro1.send()\n\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/mariovelascodev.py",
    "content": "from enum import Enum\n    \nclass Weekday(Enum):\n    LUNES = 1\n    MARTES = 2\n    MIERCOLES = 3\n    JUEVES = 4\n    VIERNES = 5\n    SABADO = 6\n    DOMINGO = 7\ndef what_day_is(number):\n    try:\n        if number > 0 or number < 8:\n            print(Weekday(number).name)\n    except:\n        print(\"Solo hay 7 días a la semana introduce un número del 1 al 7\")\nwhat_day_is(2)\nwhat_day_is(5)\n\n#EXTRA\nclass Status(Enum):\n    PENDIENTE = 0\n    ENVIADO = 1\n    ENTREGADO = 2\n    CANCELADO = 3\n\nclass Order:\n    \n    status = Status.PENDIENTE.name\n    #Constructor\n    def __init__(self, id):\n        self.id = id\n\n    #Mostrar estado pedido\n    def show_status(self):\n        print(f\"El pedido con ID {self.id} esta en estado {self.status}\")\n\n    #Modificar estado pedido\n    def send(self):\n        if self.status == \"PENDIENTE\":\n            self.status = Status.ENVIADO.name\n            return self.show_status()\n    \n    def deliver(self):\n        if self.status == \"ENVIADO\":\n            self.status = Status.ENTREGADO.name\n            return self.show_status()    \n        else:\n            print(f\"El pedido con ID {self.id} no puede ser entregado ya que aún no ha sido enviado\")\n\n    def cancel(self):\n        if self.status == \"PENDIENTE\":\n            self.status = Status.CANCELADO.name\n            return self.show_status()\n        else:\n            print(f\"El pedido con ID {self.id} no se ha podido cancelar porque ya ha sido {self.status}\")\n\norder_1 = Order(1)\norder_1.show_status()\norder_1.send()\norder_1.deliver()\norder_1.cancel()\n\norder_2 = Order(2)\norder_2.show_status()\norder_2.cancel()\n\norder_3 = Order(3)\norder_3.show_status()\norder_3.deliver()"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/mhayhem.py",
    "content": "# @Author Mhayhem\n\nfrom enum import Enum\nimport random\n\n\n# EJERCICIO:\n# Empleando tu lenguaje, explora la definición del tipo de dato\n# que sirva para definir enumeraciones (Enum).\n# Crea un Enum que represente los días de la semana del lunes\n# al domingo, en ese orden. Con ese enumerado, crea una operación\n# que muestre el nombre del día de la semana dependiendo del número entero\n# utilizado (del 1 al 7).\n\n\nclass Week(Enum):\n    LUNES = 1\n    MARTES = 2\n    MIERCOLES = 3\n    JUEVES = 4\n    VIERNES = 5\n    SABADO = 6\n    DOMINGO = 7\n    \n    def get_day_name(num: int):\n        print(Week(num).name)\n\n\n# DIFICULTAD EXTRA (opcional):\n# Crea un pequeño sistema de gestión del estado de pedidos.\n# Implementa una clase que defina un pedido con las siguientes características:\n# - El pedido tiene un identificador y un estado.\n# - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n# - Implementa las funciones que sirvan para modificar el estado:\n#   - Pedido enviado\n#   - Pedido cancelado\n#   - Pedido entregado\n#   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n# - Implementa una función para mostrar un texto descriptivo según el estado actual.\n# - Crea diferentes pedidos y muestra cómo se interactúa con ellos.\n\nclass ProductOrderStatus(Enum):\n    PENDIENTE = 1\n    ENVIADO = 2\n    CANCELADO = 3\n    ENTREGADO = 4\n    \n    \n        \n    \nclass Order:\n    def __init__(self, id: int, product: str):\n        self.id = id\n        self.product = product\n        self.status = ProductOrderStatus.PENDIENTE\n    \n    def __str__(self):\n        return f\"Pedido: {self.id}; Producto: {self.product}; Estado: {self.status.name.capitalize()}.\"\n    \n    def status_change(self, num: int):\n        if ProductOrderStatus(num).name == \"ENTREGADO\" and self.status != ProductOrderStatus.ENVIADO:\n            print(f\"No se puede entregar el pedido con ID {self.id}, su estado es {self.status.name.capitalize()}\")\n        elif ProductOrderStatus(num).name == \"CANCELADO\" and self.status == ProductOrderStatus.ENTREGADO:\n            print(f\"El pedido con ID {self.id} no se puede cancelar por que su estado es {self.status.name.capitalize()}\")\n        elif ProductOrderStatus(num).name == \"ENVIADO\" and self.status == ProductOrderStatus.CANCELADO:\n            print(f\"El pedido con ID {self.id} no se puede enviar por que su estado es {self.status.name.capitalize()}\")\n        else:\n            self.status = ProductOrderStatus(num)\n            print(f\"Pedido ID {self.id} es {self.status.name.capitalize()}\")\n\n\ndef order_create(array: list[Order]):\n    print(\"Creando Pedido.\")\n    \n    product = input(\"Producto: \\n\")\n    id = random.randint(100, 999)\n    \n    print(f\"Pedido creado con ID {id}, Producto: {product}\")\n    order = Order(id, product)\n    \n    \n    array.append(order)\n    \n    return array\n    \ndef show_orders(array: list[Order]):\n    return [f\"{item.id} {item.product} {item.status.name.capitalize()}\" for item in array]\n     \n    \n\ndef order_management(array: list[Order]):\n    while True:\n        print(\"\\n\")\n        if not array:\n            print(\"No hay pedidos en cola.\")\n            order_create(array)\n        else:\n            print(\"C. Crear nuevo pedido.\\n\"\n                \"A. Actualizar estado del Pedido.\\n\"\n                \"M. Mostrar Pedidos.\\n\"\n                \"D. descripcion del pedido.\\n\"\n                \"S. Salir del gestor de pedidos.\\n\")\n            option = input().lower()\n            match option:\n                case \"c\":\n                    order_create(array)\n                case \"a\":\n                    print(show_orders(array))\n                    try:\n                        order_update = int(input(\"Pedido que quiere actualizar: (id).\\n\"))\n                        found = False\n                        for item in array:\n                            if item.id == order_update:\n                                found = True\n                                print(\"Nuevo estado del pedido.\\n\"\n                                    \"2. Enviado.\\n\"\n                                    \"3. Cancelar.\\n\"\n                                    \"4. Entregado.\\n\")\n                                status = input()\n                                match status:\n                                    case \"2\":\n                                        num = 2\n                                    case \"3\":\n                                        num = 3\n                                    case \"4\":\n                                        num = 4\n                                \n                                item.status_change(num)\n                        if not found:\n                            print(f\"No hay ningún pedido con el id {order_update}.\")\n                    except ValueError:\n                        print(\"El ID solo pueden ser números\")\n                    \n                case \"m\":\n                    print(show_orders(array))\n                \n                case \"d\":\n                    print(\"Id del pedido: \\n\")\n                    try:\n                        id_description = int(input())\n                        for item in array:\n                            if  item.id == id_description:\n                                print(item)\n                    except ValueError:\n                        print(\"El ID solo pueden ser números\")\n                case \"s\":\n                    print(\"Saliendo del gestor de pedidos.\")\n                    break\n        print(\"\\n\")\n                \nif __name__==\"__main__\":\n    order_list = []\n    order_management(order_list)"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/mouredev.py",
    "content": "from enum import Enum\n\n\"\"\"\nEjercicio\n\"\"\"\n\n\nclass Weekday(Enum):\n    MONDAY = 1\n    TUESDAY = 2\n    WEDNESDAY = 3\n    THURSDAY = 4\n    FRIDAY = 5\n    SATURDAY = 6\n    SUNDAY = 7\n\n\ndef get_day(number: int):\n    print(Weekday(number).name)\n\n\nget_day(1)\nget_day(3)\n\n\"\"\"\nExtra\n\"\"\"\n\n\nclass OrderStatus(Enum):\n    PENDING = 1\n    SHIPPED = 2\n    DELIVERED = 3\n    CANCELLED = 4\n\n\nclass Order:\n\n    status = OrderStatus.PENDING\n\n    def __init__(self, id) -> None:\n        self.id = id\n\n    def ship(self):\n        if self.status == OrderStatus.PENDING:\n            self.status = OrderStatus.SHIPPED\n            self.display_status()\n        else:\n            print(\"El pedido ya ha sido enviado o cancelado\")\n\n    def deliver(self):\n        if self.status == OrderStatus.SHIPPED:\n            self.status = OrderStatus.DELIVERED\n            self.display_status()\n        else:\n            print(\"El pedido necesita ser enviado antes de entregarse.\")\n\n    def cancel(self):\n        if self.status != OrderStatus.DELIVERED:\n            self.status = OrderStatus.CANCELLED\n            self.display_status()\n        else:\n            print(\"El pedido no se puede cancelar ya que ya se ha entregado.\")\n\n    def display_status(self):\n        print(f\"El estado del pedido {self.id} es {self.status.name}\")\n\n\norder_1 = Order(1)\norder_1.display_status()\norder_1.deliver()\norder_1.ship()\norder_1.deliver()\norder_1.cancel()\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/mrodara.py",
    "content": "### ENUMERACIONES\n'''\nLas enumeraciones (enums) son un conjunto de nombres simbólicos (miembros) asignados a valores únicos. \nEn Python, el módulo estándar enum permite trabajar con enumeraciones de manera sencilla, \nfacilitando la organización y manipulación de conjuntos de valores relacionados.\n'''\nfrom enum import Enum\n\nclass Week(Enum):\n    LUNES = 1\n    MARTES = 2\n    MIERCOLES = 3\n    JUEVES = 4\n    VIERNES = 5\n    SABADO = 6\n    DOMINGO = 7\n    \nprint(Week.LUNES.name)\nprint(Week.LUNES.value)\n\ndef get_week_day(number: int = 1):\n    if number < 1 or number > 7:\n        print(\"Error!!!\")\n        return None\n    \n    return Week(number).name\n\nprint(get_week_day(2))\nprint(get_week_day(4))\nprint(get_week_day(7))\n\n### EJERCICIO EXTRA\n\nclass Estado(Enum):\n    PENDIENTE = 1\n    ENVIADO = 2\n    ENTREGADO = 3\n    CANCELADO = 4\n\nclass Pedido:\n    def __init__(self, id_pedido, estado):\n        self.__id_pedido = id_pedido\n        self.__estado = estado\n\n    @property\n    def id_pedido(self):\n        return self.__id_pedido\n\n    @id_pedido.setter\n    def id_pedido(self, id: int):\n        self.__id_pedido = id\n\n    @property\n    def estado(self):\n        return self.__estado\n\n    def cambiar_estado(self, estado: Estado):\n        if self.__estado.value == 1 and estado.value == 3:\n            print(\"Error: El estado no puede cambiar de pendiente a entregado hasta que no se haya enviado\")\n        elif self.__estado.value == 3 and estado.value == 4:\n            print(\"Error: El estado no puede cambiar de entregado a cancelado\")\n        else:\n            print(f\"Cambiando el pedido {self.__id_pedido} de {self.__estado.name} a {estado.name}\")\n            self.__estado = estado\n\np1 = Pedido(1, Estado.PENDIENTE)\np2 = Pedido(2, Estado.ENVIADO)\np3 = Pedido(3, Estado.ENTREGADO)\n\nprint(f\"Id: {p1.id_pedido}, Estado: {p1.estado.name}\")\nprint(f\"Id: {p2.id_pedido}, Estado: {p2.estado.name}\")\nprint(f\"Id: {p3.id_pedido}, Estado: {p3.estado.name}\")\n\n# P1 pasa a estado enviado\np1.cambiar_estado(Estado.ENVIADO)\np3.cambiar_estado(Estado.CANCELADO) # Este cambio no se puede realizar\nprint(p3.estado.name)\n\n### FIN EJERCICIO EXTRA\n\n\n### FIN ENUMERACIONES"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/mvidalb.py",
    "content": "from enum import Enum\n\n\"\"\"\nEjercicio\n\"\"\"\n\n\nclass Weekday(Enum):\n    MONDAY = 1\n    TUESDAY = 2\n    WEDNESDAY = 3\n    THURSDAY = 4\n    FRIDAY = 5\n    SATURDAY = 6\n    SUNDAY = 7\n\n\ndef get_day(number: int):\n    print(Weekday(number).name)\n\n\nget_day(1)\nget_day(3)\n\n\"\"\"\nEjercicio Extra\n\"\"\"\n\n\nclass OrderStatus(Enum):\n    PENDING = 1\n    SHIPPED = 2\n    DELIVERED = 3\n    CANCELLED = 4\n\n\nclass Order:\n\n    status = OrderStatus.PENDING\n\n    def __init__(self, id) -> None:\n        self.id = id\n\n    def ship(self):\n        if self.status == OrderStatus.PENDING:\n            self.status = OrderStatus.SHIPPED\n            self.display_status()\n        else:\n            print(\"El pedido ya ha sido enviado o cancelado\")\n\n    def deliver(self):\n        if self.status == OrderStatus.SHIPPED:\n            self.status = OrderStatus.DELIVERED\n            self.display_status()\n        else:\n            print(\"El pedido necesita ser enviado antes de entregarse.\")\n\n    def cancel(self):\n        if self.status != OrderStatus.DELIVERED:\n            self.status = OrderStatus.CANCELLED\n            self.display_status()\n        else:\n            print(\"El pedido no se puede cancelar ya que ya se ha entregado.\")\n\n    def display_status(self):\n        print(f\"El estado del pedido {self.id} es {self.status.name}\")\n\n\norder_1 = Order(1)\norder_1.display_status()\norder_1.deliver()\norder_1.ship()\norder_1.deliver()\norder_1.cancel()\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/neslarra.py",
    "content": "\"\"\"\n EJERCICIO:\n Empleando tu lenguaje, explora la definición del tipo de dato\n que sirva para definir enumeraciones (Enum).\n Crea un Enum que represente los días de la semana del lunes\n al domingo, en ese orden. Con ese enumerado, crea una operación\n que muestre el nombre del día de la semana dependiendo del número entero\n utilizado (del 1 al 7).\n *\n DIFICULTAD EXTRA (opcional):\n Crea un pequeño sistema de gestión del estado de lista_de_pedidos.\n Implementa una clase que defina un pedido con las siguientes características:\n - El pedido tiene un identificador y un estado.\n - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n - Implementa las funciones que sirvan para modificar el estado:\n *   - Pedido enviado\n *   - Pedido cancelado\n *   - Pedido entregado\n *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n - Implementa una función para mostrar un texto descriptivo según el estado actual.\n - Crea diferentes lista_de_pedidos y muestra cómo se interactúa con ellos. \n\"\"\"\nfrom enum import Enum\n\nprint(f\"##  Explicación  {'#' * 30}\\n\")\nprint(r\"\"\"\nEnumerar es nombrar cosas en un orden determinado, por ejemplo: nombrar los elementos de una colección, del primero al último, correspondiendole \na cada elemento los número 1 a n. Ésto se puede hacer de diversas maneras.\n\nPuedo \"enumerar\" los días de la semana utilizando un diccionario con clave el número de día y valor el nombre del día:\ndias_de_senama = {\n    1: \"Lunes\",\n    2: \"Martes\",\n    3: \"Miércoles\",\n    4: \"Jueves\",\n    5: \"Viernes\",\n    6: \"Sábado\",\n    7: \"Domingo\"\n}\nprint(\"Qué día de la semana podés ir al cine?\")\nfor key, value in dias_de_senama.items():\n    print(f\"\\t{key} - {value}\")\ndia = \"_\"\nwhile not (dia.isnumeric() and int(dia) in range(1, 8)):\n    dia = input(\"Decime cual [1-7] => \")\nprint(f\"Ok, vamos al cine el día {dias_de_senama[int(dia)]}\", end=\"\\n\\n\")\n\nTambién puedo hacerlo utilizando una lista y la función \"enumerate\" la cual devolverá el índice correspondiente a cada elemento de la lista\n(como, para este caso, la pocisión 0 no será utilizada, inicio la lista con un valor dummy \"_\":\ndias_de_senama = [\"_\", \"Lunes\", \"Martes\", \"Miércoles\", \"Jueves\", \"Viernes\", \"Sábado\", \"Domingo\"]\nprint(\"Qué día querés ir al cine conmigo?\")\nfor dia_num, dia in enumerate(dias_de_senama):\n    print(f\"\\t{dia_num} - {dias_de_senama[dia_num]}\")\ndia = \"_\"\nwhile not (dia.isnumeric() and int(dia) in range(1, 8)):\n    dia = input(\"Decime cual [1-7 o 0 si no querés] => \")\nprint(f\"Ok, vamos al cine el día {dias_de_senama[int(dia)]}\", end=\"\\n\\n\")\n\nO puedo usar el módula Enum del paquete enum, el cual asigna un valor a cada uno de los nombres:\nfrom enum import Enum\ndias_de_senama = Enum(value=\"dias_de_la_semana\", names=(\"Lunes\", \"Martes\", \"Miércoles\", \"Jueves\", \"Viernes\", \"Sábado\", \"Domingo\"))\nprint(\"Qué día te gusta ir al cine?\")\nfor d in dias_de_senama:\n    print(f\"\\t{d.value} - {d.name}\")\ndia = \"_\"\nwhile not (dia.isnumeric() and int(dia) in [x for x in range(1, dias_de_senama.__len__() + 1)]):\n    dia = input(\"Decime cual [1-7] => \")\nprint(f\"Ok, vamos al cine el día {dias_de_senama(int(dia)).name}\", end=\"\\n\\n\")\n\"\"\")\n\ndias_de_senama = {\n    1: \"Lunes\",\n    2: \"Martes\",\n    3: \"Miércoles\",\n    4: \"Jueves\",\n    5: \"Viernes\",\n    6: \"Sábado\",\n    7: \"Domingo\"\n}\nprint(\"Usando diccionario:\\nQué día de la semana podés ir al cine?\")\nfor key, value in dias_de_senama.items():\n    print(f\"\\t{key} - {value}\")\ndia = \"_\"\nwhile not (dia.isnumeric() and int(dia) in range(1, 8)):\n    dia = input(\"Decime cual [1-7] => \")\nprint(f\"Ok, vamos al cine el día {dias_de_senama[int(dia)]}\", end=\"\\n\\n\")\n\ndias_de_senama = [\"_\", \"Lunes\", \"Martes\", \"Miércoles\", \"Jueves\", \"Viernes\", \"Sábado\", \"Domingo\"]\nprint(\"Usando lista:\\nQué día querés ir al cine conmigo?\")\nfor dia_num, dia in enumerate(dias_de_senama):\n    print(f\"\\t{dia_num} - {dias_de_senama[dia_num]}\")\ndia = \"_\"\nwhile not (dia.isnumeric() and int(dia) in range(1, 8)):\n    dia = input(\"Decime cual [1-7 o 0 si no querés] => \")\nprint(f\"Ok, vamos al cine el día {dias_de_senama[int(dia)]}\", end=\"\\n\\n\")\n\ndias_de_senama = Enum(value=\"dias_de_la_semana\", names=(\"Lunes\", \"Martes\", \"Miércoles\", \"Jueves\", \"Viernes\", \"Sábado\", \"Domingo\"))\nprint(\"Usando Enum:\\nQué día te gusta ir al cine?\")\nfor d in dias_de_senama:\n    print(f\"\\t{d.value} - {d.name}\")\ndia = \"_\"\nwhile not (dia.isnumeric() and int(dia) in [x for x in range(1, dias_de_senama.__len__() + 1)]):\n    dia = input(\"Decime cual [1-7] => \")\nprint(f\"Ok, vamos al cine el día {dias_de_senama(int(dia)).name}\", end=\"\\n\\n\")\n\nprint(f\"##  Dificultad extra  {'#' * 30}\\n\")\n\n\nclass Pedido:\n\n    pedido_nro = 2384\n    numeros_de_pedidos = Enum(value=\"numeros_de_pedidos\", names=[])\n    estado = Enum(value=\"estado\", names=(\"PENDIENTE\", \"ENVIADO\", \"ENTREGADO\", \"CANCELADO\"))\n    acciones = Enum(value=\"acciones\", names=(\"Listar\", \"Nuevo pedido\", \"Cambiar estado\"))\n\n    def __init__(self):\n        self.pedido = Pedido.nuevo_pedido()\n        self.estado = 1\n\n    def __str__(self):\n        return f\"Pedido nro {self.pedido} con estado {Pedido.estado(self.estado).name}\"\n\n    def cambiar_estado(self, nuevo_estado: str) -> bool:\n        estado = getattr(Pedido.estado, nuevo_estado).value\n        if estado == self.estado + 1 or estado == 4:\n            self.estado = estado\n            return True\n        return False\n\n    @classmethod\n    def nuevo_pedido(cls):\n        cls.pedido_nro += 1\n        nombres = [p.name for p in cls.numeros_de_pedidos] + [str(cls.pedido_nro)]\n        cls.numeros_de_pedidos = Enum(value=\"numeros_de_pedidos\", names=nombres)\n        return cls.pedido_nro\n\n\ndef menu_estados() -> str:\n    print(\"\\nSeleccionar nuevo estado\")\n    for e in Pedido.estado:\n        print(f\"\\t{e.value} - {e.name}\")\n    estado = \"_\"\n    while not (estado.isnumeric() and int(estado) in [x for x in range(1, Pedido.estado.__len__() + 1)]):\n        estado = input(\"Estado => \")\n    return Pedido.estado(int(estado)).name\n\n\ndef menu_pedidos() -> int:\n    print(f\"\\nMenu de lista_de_pedidos\")\n    for a in Pedido.acciones:\n        print(f\"\\t{a.value} - {a.name}\")\n    print(\"\\t0 - Salir\")\n    accion = \"_\"\n    while not (accion.isnumeric() and int(accion) in [x for x in range(0, Pedido.acciones.__len__() + 1)]):\n        accion = input(f\"Seleccionar opcion [0-{Pedido.acciones.__len__()}] => \")\n    return int(accion)\n\n\ndef seleccionar_pedido() -> int:\n    print(f\"\\nSeleccionar pedido\")\n    for p in Pedido.numeros_de_pedidos:\n        print(f\"\\t{p.value} - {p.name}\")\n    print(\"\\t0 - Volver\")\n    item = \"_\"\n    while not (item.isnumeric() and int(item) in [x for x in range(0, Pedido.numeros_de_pedidos.__len__() + 1)]):\n        item = input(f\"Seleccionar item [0-{Pedido.numeros_de_pedidos.__len__()}] => \")\n    pedido_nro = Pedido.numeros_de_pedidos(int(item)).name\n    return int(Pedido.numeros_de_pedidos(int(item)).name) if int(item) > 0 else 0\n\n\nlista_de_pedidos = []\nwhile True:\n    accion = menu_pedidos()\n    match accion:\n        case 0:\n            break\n        case 1:\n            for p in Pedido.numeros_de_pedidos:\n                pedido = [pe for pe in lista_de_pedidos if pe.pedido == int(p.name)][0]\n                print(f\"\\t{pedido}\")\n        case 2:\n            pedido = Pedido()\n            lista_de_pedidos.append(pedido)\n            print(f\"\\tNuevo pedido => {pedido.__str__()}\")\n        case 3:\n            pedido_nro = seleccionar_pedido()\n            nuevo_estado = menu_estados()\n            pedido = [p for p in lista_de_pedidos if p.pedido == pedido_nro][0]\n            pedido.cambiar_estado(nuevo_estado)\n            print(pedido)\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/nlarrea.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Empleando tu lenguaje, explora la definición del tipo de dato\n * que sirva para definir enumeraciones (Enum).\n * Crea un Enum que represente los días de la semana del lunes\n * al domingo, en ese orden. Con ese enumerado, crea una operación\n * que muestre el nombre del día de la semana dependiendo del número entero\n * utilizado (del 1 al 7).\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un pequeño sistema de gestión del estado de pedidos.\n * Implementa una clase que defina un pedido con las siguientes características:\n * - El pedido tiene un identificador y un estado.\n * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n * - Implementa las funciones que sirvan para modificar el estado:\n *   - Pedido enviado\n *   - Pedido cancelado\n *   - Pedido entregado\n *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n * - Crea diferentes pedidos y muestra cómo se interactúa con ellos. \n\"\"\"\n\nfrom enum import Enum\n\n\nclass WeekDay(Enum):\n    MONDAY = 1\n    TUESDAY = 2\n    WEDNESDAY = 3\n    THURSDAY = 4\n    FRIDAY = 5\n    SATURDAY = 6\n    SUNDAY = 7\n\n\ndef print_week_day(day_index: int) -> None:\n    if day_index < 1 or day_index > 7:\n        print(\"You should enter a number between 1 and 7 (both included).\")\n        return\n\n    print(WeekDay(day_index).name.capitalize())\n\n\nprint_week_day(5)  # Friday\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un pequeño sistema de gestión del estado de pedidos.\n * Implementa una clase que defina un pedido con las siguientes características:\n * - El pedido tiene un identificador y un estado.\n * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n * - Implementa las funciones que sirvan para modificar el estado:\n *   - Pedido enviado\n *   - Pedido cancelado\n *   - Pedido entregado\n *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n * - Crea diferentes pedidos y muestra cómo se interactúa con ellos. \n\"\"\"\n\n\nclass OrderStatus(Enum):\n    PENDING = 1\n    SHIPPED = 2\n    DELIVERED = 3\n    CANCELED = 4\n\n\nclass Order:\n    def __init__(self, order_id: str) -> None:\n        self.order_id = order_id\n        self.state = OrderStatus.PENDING\n\n        print(f\"\\nThe order '{self.order_id}' is {self.state.name}\")\n\n    def update_state(self):\n        if (\n            self.state == OrderStatus.CANCELED\n            or self.state == OrderStatus.DELIVERED\n        ):\n            # If order is canceled or delivered -> maintain the state as it is\n            return\n\n        self.state = OrderStatus(self.state.value + 1)\n\n    def cancel_order(self):\n        if self.state != OrderStatus.DELIVERED:\n            self.state = OrderStatus.CANCELED\n\n    def print_current_state(self):\n        print(f\"The order '{self.order_id}' is {self.state.name}\")\n\n\norder_1 = Order(\"1234\")  # pending\norder_1.update_state()\norder_1.print_current_state()  # shipped\norder_1.update_state()\norder_1.print_current_state()  # delivered\norder_1.cancel_order()  # it won't work because it's delivered already\norder_1.print_current_state()  # delivered\n\norder_2 = Order(\"5678\")  # pending\norder_2.update_state()\norder_2.print_current_state()  # shipped\norder_2.cancel_order()\norder_2.print_current_state()  # canceled\norder_2.update_state()  # it won't work because it's canceled\norder_2.print_current_state()  # canceled\n\norder_3 = Order(\"1290\")  # pending\norder_3.cancel_order()\norder_3.print_current_state()  # canceled\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/oriaj3.py",
    "content": "\"\"\"\n19 - ENUMERACIONES\n\nAutor de la solución: Oriaj3\t\n\nTeoría: \n\nLas enumeraciones son una forma de representar un conjunto de valores constantes\ncon nombres descriptivos. En Python, las enumeraciones se pueden crear utilizando\nla clase Enum del módulo enum. Las enumeraciones son útiles para representar\nvalores que no cambian durante la ejecución del programa, como los días de la\nsemana, los meses del año, los colores, etc.\n\n\"\"\"\n\n\"\"\"\n/*\n * EJERCICIO:\n * Empleando tu lenguaje, explora la definición del tipo de dato\n * que sirva para definir enumeraciones (Enum).\n * Crea un Enum que represente los días de la semana del lunes\n * al domingo, en ese orden. Con ese enumerado, crea una operación\n * que muestre el nombre del día de la semana dependiendo del número entero\n * utilizado (del 1 al 7).\n\"\"\"\nfrom enum import Enum\n\nclass Weekday(Enum):\n    LUNES = 1\n    MARTES = 2\n    MIERCOLES = 3\n    JUEVES = 4\n    VIERNES = 5\n    SABADO = 6\n    DOMINGO = 7\n\ndef get_weekday(num: int):\n    for day in Weekday:\n        if day.value == num:\n            return day.name\n    return \"Error\"    \nprint(get_weekday(5))\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un pequeño sistema de gestión del estado de pedidos.\n * Implementa una clase que defina un pedido con las siguientes características:\n * - El pedido tiene un identificador y un estado.\n * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n * - Implementa las funciones que sirvan para modificar el estado:\n *   - Pedido enviado\n *   - Pedido cancelado\n *   - Pedido entregado\n *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n * - Crea diferentes pedidos y muestra cómo se interactúa con ellos. \n */\n\"\"\"\n\nclass Estado(Enum):\n    PENDIENTE = 1\n    ENVIADO = 2\n    ENTREGADO = 3\n    CANCELADO = 4\n\nclass Pedido():\n    siguiente_id: int=1 \n    estado: Estado= Estado.PENDIENTE\n    \n    def __init__(self):\n        self.id = Pedido.siguiente_id\n        Pedido.siguiente_id += 1\n\n    def enviar(self):\n        self.estado = Estado.ENVIADO\n        print(f\"Enviando pedido {self.id}\")\n\n    def entregar(self):\n        if self.estado == Estado.ENVIADO:\n            self.estado = Estado.ENTREGADO\n            print(f\"Entregado pedido {self.id}\")\n        else:\n            print(f\"No se puede entregar el pedido {self.id}\")\n\n    def cancelar(self):\n        if self.estado == Estado.ENTREGADO:\n            print(f\"No se puede cancelar un pedido entregado, id: {self.id}\")\n        else:\n            self.estado = Estado.CANCELADO\n            print(f\"Cancelado el pedido {self.id}\")\n        \n    def get_estado(self):\n        print(f\"El estado del pedido {self.id} es {self.estado.name}\")\n\n\n#Ejemplo de uso\n#Pedido1\npedido1 = Pedido()\npedido1.enviar()\npedido1.entregar()\npedido1.cancelar()\npedido1.get_estado() \n\n#Pedido2\npedido2 = Pedido()\npedido2.enviar()\npedido2.cancelar()\npedido2.get_estado()\n\n#Pedido3\npedido3 = Pedido()\npedido3.entregar()\npedido3.get_estado()\n\n#Pedido4\npedido4 = Pedido()\npedido4.cancelar()\npedido4.get_estado()\n\n#Pedido5\npedido5 = Pedido()\npedido5.enviar()\npedido5.entregar()\npedido5.get_estado()\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/pyramsd.py",
    "content": "from enum import Enum\n\nclass DiasSemana(Enum):\n    Lunes = 1\n    Martes = 2\n    Miercoles = 3\n    jueves = 4\n    Viernes = 5\n    Sabado = 6\n    Domingo = 7\n\ndef getDiaSemana(n):\n    for day in DiasSemana:\n        if day.value == n:\n            return day.name\n    return \"Dia no valido\"\n\nprint(getDiaSemana(2))\n\n\n'''\nEXTRA\n'''\nclass EstadoPedido(Enum):\n    PENDIENTE = 0\n    ENVIADO = 1\n    ENTREGADO = 2\n    CANCELADO = 3\n\nclass Pedido:\n    def __init__(self, status, id) -> None:\n        self.status = status\n        self.id = id\n    \n    def enviar_pedido(self):\n        if self.status == EstadoPedido.PENDIENTE:\n            self.status = EstadoPedido.ENVIADO\n        else:\n            print(\"El pedido no puede ser enviado en su estado actual\")\n\n    def pedido_entregado(self):\n        if self.status == EstadoPedido.ENVIADO:\n            self.status = EstadoPedido.ENTREGADO\n        else:\n            print(\"El pedido no puede ser entregado en su estado actual\")\n\n    def cancelar_pedido(self):\n        if self.status == EstadoPedido.PENDIENTE:\n            self.status = EstadoPedido.CANCELADO\n        else:\n            print(\"El pedido no puede ser cancelado en su estado actual\")\n\n    def estado_actual(self):\n        return f\"Estado actual del pedido {self.id}: {self.status.name}\"\n\n\npedido1 = Pedido(EstadoPedido.PENDIENTE, 1)\nprint(pedido1.estado_actual())\npedido1.enviar_pedido()\nprint(pedido1.estado_actual())\npedido1.pedido_entregado()\nprint(pedido1.estado_actual())\npedido1.cancelar_pedido()\n\npedido2 = Pedido(EstadoPedido.PENDIENTE, 2)\nprint(pedido2.estado_actual())\npedido2.cancelar_pedido()\nprint(pedido2.estado_actual())\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/qwik-zgheib.py",
    "content": "# -- exercise\nfrom enum import Enum\n\n\nclass Days(Enum):\n    LUNES = 1\n    MARTES = 2\n    MIERCOLES = 3\n    JUEVES = 4\n    VIERNES = 5\n    SABADO = 6\n    DOMINGO = 7\n\n\ndef show_day(day: int) -> str:\n    return Days(day).name\n\n\nprint(show_day(3))\n\n\n# -- extra challenge\nclass OrderState(Enum):\n    PENDING = 1\n    SENT = 2\n    DELIVERED = 3\n    CANCELED = 4\n\n\nclass Order:\n    def __init__(self, order_id: int):\n        self.order_id = order_id\n        self.state = OrderState.PENDING\n\n    def send_order(self):\n        if self.state == OrderState.PENDING:\n            self.state = OrderState.SENT\n            return True\n        return False\n\n    def deliver_order(self):\n        if self.state == OrderState.SENT:\n            self.state = OrderState.DELIVERED\n            return True\n        return False\n\n    def cancel_order(self):\n        if self.state == OrderState.PENDING:\n            self.state = OrderState.CANCELED\n            return True\n        return False\n\n    def get_state(self):\n        return self.state.name\n\n\norder1 = Order(1)\norder2 = Order(2)\norder3 = Order(3)\n\nprint(order1.get_state())\nprint(order2.get_state())\n\nprint(order1.send_order())\nprint(order2.send_order())\n\nprint(order1.get_state())\nprint(order2.get_state())\n\nprint(order1.deliver_order())\nprint(order2.deliver_order())\n\n\nprint(order1.get_state())\nprint(order2.get_state())\n\nprint(order1.cancel_order())\nprint(order2.cancel_order())\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/rantamhack.py",
    "content": "'''\n* EJERCICIO:\n* Empleando tu lenguaje, explora la definicion del tipo de dato\n* que sirva para definir enumeraciones (Enum).\n* Crea un Enum que represente los dias de la semana del lunes\n* al domingo, en ese orden. Con ese enumerado, crea una operacion\n* que muestre el nombre del dia de la semana dependiendo del numero entero\n* utilizado (del 1 al 7).\n'''\n\nprint(\"\\n\\n=======================================EJERCICIO=======================================\\n\\n\")\n\nprint(\"\\nLas enumeraciones son un conjunto de nombres simbolicos (miembros) vinculados a valores unicos y constantes\\n\")\n\nfrom enum import Enum\n\nweek = Enum(\n    value = 'week',\n    names = ('MONDAY TUESDAY WEDNESDAY THURSDAY FRIDAY SATURDAY SUNDAY'),\n)\n\nprint(f\"El valor del primer dia de la semana (lunes) es: {week.MONDAY.value}\\n\")\nprint(f\"El valor nombre del septimo dia de la semana es: {week(7)}\\n\")\n\nprint(\"El valor se asigna a cada uno de los miembros automaticamente\\n\")\nfor day in week:\n    print(f\"\\t{day.name, '->', day.value}\")\n\n'''\n\"Otra forma de expresion valida es\"\nclass week (Enum):\n    MONDAY = 1\n    TUESDAY = 2\n    WEDNESDAY = 3\n    THURSDAY = 4\n    FRIDAY = 5\n    SATURDAY = 6\n    SUNDAY = 7\n    \nprint(week(7))\nprint(week.SATURDAY.value)\n\nfor day in week:\n    print(day.name, '->', day.value)\n'''\n\n\"==========================================================================================================================\"\n\n\n'''\n* DIFICULTAD EXTRA (opcional):\n* Crea un pequeño sistema de gestion del estado de pedidos.\n* Implementa una clase que defina un pedido con las siguientes caracteri­sticas:\n* - El pedido tiene un identificador y un estado.\n* - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n* - Implementa las funciones que sirvan para modificar el estado:\n*   - Pedido enviado\n*   - Pedido cancelado\n*   - Pedido entregado\n*   (Establece una logica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n* - Implementa una funcion para mostrar un texto descriptivo segun el estado actual.\n* - Crea diferentes pedidos y muestra como se interactua con ellos. \n'''\n\nprint(\"\\n\\n=======================================DIFICULTAD EXTRA=======================================\\n\\n\")\n\n    \nclass order_management(Enum):\n    PENDING = 1\n    SENT = 2\n    DELIVERED = 3\n    CANCELED = 4        \n    \nclass order:\n    def __init__(self, id):\n        self.id = id\n        self.status = order_management(1)\n        \n    def send_order(self):\n        if self.status == order_management(1):\n            print(f\"The order with the id {self.id} has been received and is ready to be shipped\\n\")\n            self.status = order_management(2)\n            print(f\"The order with the id {self.id} has already been submitted\\n\")\n        else: \n            self.status == order_management(4)\n            print(f\"The order with the id {self.id} has been cancelled\\n\")\n            \n    \n    def delivered(self):\n        if self.status == order_management(2):\n            self.status = order_management(3)\n            print(f\"The order with the id {self.id} has been delivered\\n\")\n    \n    def cancelled(self):\n        if self.status == order_management(1) or self.status == order_management(2):\n            print(f\"The order with the id {self.id} has been cancelled\\n\")\n            self.status = order_management(4)\n        else:\n            self.status == order_management(3)\n            print(f\"The order with the id {self.id} has been delivered and cannot be cancelled\\n\")\n    \n    def show_status(self):\n        print(f\"The order with id {self.id} is in status {self.status.name}\\n\")\n            \n  \n  \norder1 = order(100)\norder1.show_status()\n\norder1.send_order()\norder1.show_status()\n\norder1.cancelled()\norder1.show_status() \n\norder2 = order(101)\norder2.show_status()\n\norder2.send_order()\norder2.show_status()\n\norder2.delivered()\norder2.show_status()\n\norder2.cancelled()\norder2.show_status()        \n       \n\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/raulG91.py",
    "content": "from enum import Enum\n\nclass Weekday(Enum):\n    MONDAY = 1\n    TUESDAY = 2\n    WEDNESDAY = 3\n    THURSDAY = 4\n    FRIDAY = 5\n    SATURDAY = 6\n    SUNDAY = 7\n\n\ndef get_day_name(number):\n    try:\n        day = Weekday(number)\n        return day.name\n    except ValueError:\n        return \"Error\"\n\nprint(get_day_name(2))\nprint(get_day_name(6))\nprint(get_day_name(4))\n\n\n#Extra\nclass Status(Enum):\n    sent = \"Sent\"\n    pending = \"Pending\"\n    cancel = \"Cancel\"\n    delivered = \"Delivered\"\n\nclass Order:\n\n    def __init__(self,id:int,status:Status) -> None:\n        self.id = id\n        self.status = status\n    \n    def get_status(self):\n        return self.status.value    \n    def set_sent(self):\n        if self.status == Status.pending:\n            self.status = Status.sent\n        else:\n            print(f'Current status is {self.status.name} could not be change to sent')\n\n    def set_delivered(self):\n        if self.status == Status.sent:\n            self.status = Status.delivered\n        else:\n            print(\"Status is not sent so could not be changed to delivered\")                \n    def cancel(self):\n        if self.status == Status.delivered:\n            print(\"Order was delivered could not be cancelled\") \n        else:\n            self.status = Status.cancel   \n\norder1 = Order(1,Status.pending)\nprint(order1.get_status())\norder1.set_delivered()\norder1.set_sent()\nprint(order1.get_status())\norder1.set_delivered()\nprint(order1.get_status())\norder1.cancel()\n\norder2 = Order(2,Status.pending)\norder2.cancel()\nprint(order2.get_status())"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/raynerpv2022.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * Empleando tu lenguaje, explora la definición del tipo de dato\n#  * que sirva para definir enumeraciones (Enum).\n#  * Crea un Enum que represente los días de la semana del lunes\n#  * al domingo, en ese orden. Con ese enumerado, crea una operación\n#  * que muestre el nombre del día de la semana dependiendo del número entero\n#  * utilizado (del 1 al 7).\n\nfrom enum import Enum\n\nclass Week_days(Enum):\n    monday = 1\n    tuesday = 2\n    wednesday =3\n    thrusday = 4\n    friday = 5\n    saturday = 6\n    sunday = 7\n\n   \n    \ndef get_week(index):\n    return Week_days(index).name\n\n\n\nprint(Week_days(1))\nprint(Week_days.monday.name)\nprint(Week_days.monday.value)\nprint(get_week(3))\n\n \n\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea un pequeño sistema de gestión del estado de pedidos.\n#  * Implementa una clase que defina un pedido con las siguientes características:\n#  * - El pedido tiene un identificador y un estado.\n#  * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n#  * - Implementa las funciones que sirvan para modificar el estado:\n#  *   - Pedido enviado\n#  *   - Pedido cancelado\n#  *   - Pedido entregado\n#  *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n#  * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n#  * - Crea diferentes pedidos y muestra cómo se interactúa con ellos. \n#  */\n\nimport time\nimport os\n\nclass Pedido :\n\n    def __init__(self, serial=1) -> None:\n        self.serial = serial\n        self.ID = self.Estado.PENDIENTE.name\n        \n\n    class Estado (Enum):\n        PENDIENTE = 1\n        ENVIADO = 2\n        ENTREGADO = 3\n        CANCELADO = 4\n    \n    def  Enviar(self):\n         if self.ID == self.Estado.PENDIENTE.name:\n             self.ID = self.Estado.ENVIADO.name\n             print(f\"Pedido {self.serial} ha sido enviado \")\n         elif self.ID == self.Estado.CANCELADO.name:\n             print(f\"Pedido {self.serial} esta Cancelado\")\n         else:\n            print(f\"Pedido {self.serial} no puede ser Enviado  porque porque no esta pendiente\")\n\n    def MostrarEstado(self):\n        return f\"el Estado actual del pedido {self.serial} es : {self.ID}\"\n    \n    def Cancelar(self):\n        if self.ID == self.Estado.CANCELADO.name:\n             print(f\"Pedido {self.serial} ya esta Cancelado\")\n             return True\n            \n        elif self.ID != self.Estado.ENTREGADO.name:\n            self.ID = self.Estado.CANCELADO.name\n            print(f\"Pedido {self.serial} ha sido Cancelado \")\n        else:\n            print(f\"Pedido {self.serial} no puede ser Cancelado porque ya se entrego\")\n        return False\n\n    def Entregar(self):\n        if self.ID == self.Estado.ENVIADO.name:\n            self.ID = self.Estado.ENTREGADO.name\n            print(f\"Pedido {self.serial} ha sido Entregado \")\n        elif self.ID == self.Estado.CANCELADO.name:\n             print(f\"Pedido {self.serial} esta Cancelado\")\n        else:\n            print(f\"Pedido {self.serial} no puede ser ENtregado porque no se ha enviado\")\n\n\n \ndef buscar_pedido(ped):\n    for i in pedidos:\n        if i.serial == ped:\n            return pedidos.index(i)\n    return -1\n            \n    \n\ndef seleccionar_producto(ped):\n    index = buscar_pedido(ped)\n    if  index == -1:\n        print(f\"Pedido no encontrado\")\n        return\n    \n    os.system(\"clear\")\n    eliminar =  False\n    while True:\n        \n        print(f\"1 - Ver Estado {ped} \")\n        print(f\"2 - Enviar Pedido {ped}  \")\n        print(f\"3 - Cancelar Pedido {ped} \")\n        print(f\"4 - ENtregar Pedido {ped} \")\n        print(f\"5 - Salir del Producto {ped} \")\n        s = input(\"\")\n        match s:\n            case \"1\":\n                print(\"MOstrando Estado\")\n                print(pedidos[index].ID)\n            case \"2\":\n                print(\"Enviando Producto  \")\n                pedidos[index].Enviar()\n            case \"3\":\n                print(\"Cancelando Producto  \")\n                if pedidos[index].Cancelar():\n                    eliminar = True\n\n            case \"4\":\n                print(\"Entregando Producto  \")\n                pedidos[index].Entregar()\n            case \"5\":\n                print(\"Saliendo del Producto  \")\n                if eliminar:\n                    print(f\"Pedido {pedidos.pop(index).serial} Eliminado\")\n                break\n            case _:\n                print(\"Opcion Invalida\")\n\n \n    \n\n\n\n\n\n\n\npedidos = []\nserial = 100\nwhile True:\n    \n    print(\"Seleccione opcion\")\n    print(\"1 - Crear Pedido \")\n    print(\"2 - Mostrar todos Pedido\")\n    print(\"3 - Seleccionar Pedido\")\n    print(\"4 - Salir\")\n    op = input(\"\")\n    \n    match op:\n            case \"1\":\n                serial +=1\n                pedidos.append(Pedido(f\"{serial}A\"))\n\n            case \"2\":\n                print(\"Mostrando Todos los Pedidos\")\n                for i in pedidos:\n                    print(f\"Pedido: {i.serial} Estado: {i.ID}\")\n                 \n            case \"3\":\n                print(\"Indique serial del pedido\")\n                serial = input(\"\")\n                seleccionar_producto(serial)\n            \n            case \"4\":\n                print(\"Saliendo...\")\n                for i in range (10,0,-1):\n                    print(i,end=\" \", flush=True)\n                    time.sleep(1)\n                print()\n                print(\"Programa terminado\")\n                break\n            case _:\n                print(\"Opcion no valida, 1-6 \")\n\n\n\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/restevean.py",
    "content": "\"\"\"\nExercise\n\"\"\"\nfrom enum import Enum, auto\n\n\nclass Weekday(Enum):\n    LUNES = 1\n    MARTES = 2\n    MIARCOLES = 3\n    JUEVES = 4\n    VIERNES = 5\n    SABADO = 6\n    DOMINGO = 7\n\n\ndef get_weekday_name(day_number):\n    # Validate if the input is within the correct range\n    if 1 <= day_number <= 7:\n        return Weekday(day_number).name\n    else:\n        raise ValueError(\"Número fuera de rango. Ingrese un número del 1 al 7.\")\n\n\n\"\"\"\nExtra\n\"\"\"\n\n\nclass EstadoPedido(Enum):\n    PENDIENTE = auto()\n    ENVIADO = auto()\n    ENTREGADO = auto()\n    CANCELADO = auto()\n\n\nclass Pedido:\n    def __init__(self, id):\n        self.id = id\n        self.estado = EstadoPedido.PENDIENTE\n\n    def enviar_pedido(self):\n        if self.estado == EstadoPedido.PENDIENTE:\n            self.estado = EstadoPedido.ENVIADO\n        else:\n            raise ValueError(\"Solo los pedidos pendientes pueden ser enviados.\")\n\n    def cancelar_pedido(self):\n        if self.estado in {EstadoPedido.PENDIENTE, EstadoPedido.ENVIADO}:\n            self.estado = EstadoPedido.CANCELADO\n        else:\n            raise ValueError(\"Solo los pedidos pendientes o enviados pueden ser cancelados.\")\n\n    def entregar_pedido(self):\n        if self.estado == EstadoPedido.ENVIADO:\n            self.estado = EstadoPedido.ENTREGADO\n        else:\n            raise ValueError(\"Solo los pedidos enviados pueden ser entregados.\")\n\n    def mostrar_estado(self):\n        estado_descripcion = {\n            EstadoPedido.PENDIENTE: f\"El pedido {self.id} está pendiente.\",\n            EstadoPedido.ENVIADO: f\"El pedido {self.id} ha sido enviado.\",\n            EstadoPedido.ENTREGADO: f\"El pedido {self.id} ha sido entregado.\",\n            EstadoPedido.CANCELADO: f\"El pedido {self.id} ha sido cancelado.\"\n        }\n        return estado_descripcion[self.estado]\n\n\nif __name__ == \"__main__\":\n    print(get_weekday_name(3))  # Should print \"MIERCOLES\"\n\n    pedido1 = Pedido(1)\n    print(pedido1.mostrar_estado())\n    pedido1.enviar_pedido()\n    print(pedido1.mostrar_estado())\n    pedido1.entregar_pedido()\n    print(pedido1.mostrar_estado())\n\n    pedido2 = Pedido(2)\n    print(pedido2.mostrar_estado())\n    pedido2.cancelar_pedido()\n    print(pedido2.mostrar_estado())\n\n    pedido3 = Pedido(3)\n    print(pedido3.mostrar_estado())\n    pedido3.enviar_pedido()\n    print(pedido3.mostrar_estado())\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/rigo93acosta.py",
    "content": "'''\n * EJERCICIO:\n * Empleando tu lenguaje, explora la definición del tipo de dato\n * que sirva para definir enumeraciones (Enum).\n * Crea un Enum que represente los días de la semana del lunes\n * al domingo, en ese orden. Con ese enumerado, crea una operación\n * que muestre el nombre del día de la semana dependiendo del número entero\n * utilizado (del 1 al 7).\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un pequeño sistema de gestión del estado de pedidos.\n * Implementa una clase que defina un pedido con las siguientes características:\n * - El pedido tiene un identificador y un estado.\n * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n * - Implementa las funciones que sirvan para modificar el estado:\n *   - Pedido enviado\n *   - Pedido cancelado\n *   - Pedido entregado\n *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n * - Crea diferentes pedidos y muestra cómo se interactúa con ellos. \n'''\n\n'''\nEjercicio\n'''\n\nfrom enum import Enum\n\nclass Weekday(Enum):\n    MONDAY = 1\n    TUESDAY = 2\n    WEDNESDAY = 3\n    THURSDAY = 4\n    FRIDAY = 5\n    SATURDAY = 6\n    SUNDAY = 7\n\ndef get_day(number: int):\n\n    print(Weekday(number).name)\n\nget_day(1)\n\n'''\nDificultad Extra\n'''\nclass OrderStatus(Enum):\n    PENDIENTE = 1\n    ENVIADO = 2\n    ENTREGADO = 3\n    CANCELADO = 4\n\nclass Order:\n    def __init__(self, id: int, status=OrderStatus.PENDIENTE):\n        self.id = id\n        self.status = status\n\n    def send(self):\n        if self.status == OrderStatus.PENDIENTE:\n            self.status = OrderStatus.ENVIADO\n            self.display_status()\n        else:\n            print(f\"El Pedido: {self.id} se ha enviado o cancelado.\")\n\n    def deliver(self):\n        if self.status == OrderStatus.ENVIADO:\n            self.status = OrderStatus.ENTREGADO\n            self.display_status()\n        else:\n            print(f\"No se puede entregar el Pedido: {self.id} pues no ha sido enviado.\")\n\n    def cancel(self):\n        if self.status != OrderStatus.ENTREGADO:\n            self.status = OrderStatus.CANCELADO\n            self.display_status()\n        else:\n            print(f\"No se puede cancelar el Pedido: {self.id} pues ya ha sido entregado.\")\n\n    def display_status(self):\n        print(f'Pedido: {self.id} Estado: {self.status.name}')\n\n\norder_1 = Order(1)\norder_1.deliver()\norder_1.send()\norder_1.deliver()\norder_1.cancel()\n\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/santyjL.py",
    "content": "#19 - ENUMERACIONES\n\n\"\"\"\n/*\n * EJERCICIO:\n * Empleando tu lenguaje, explora la definición del tipo de dato\n * que sirva para definir enumeraciones (Enum).\n * Crea un Enum que represente los días de la semana del lunes\n * al domingo, en ese orden. Con ese enumerado, crea una operación\n * que muestre el nombre del día de la semana dependiendo del número entero\n * utilizado (del 1 al 7).\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un pequeño sistema de gestión del estado de pedidos.\n * Implementa una clase que defina un pedido con las siguientes características:\n * - El pedido tiene un identificador y un estado.\n * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n * - Implementa las funciones que sirvan para modificar el estado:\n *   - Pedido enviado\n *   - Pedido cancelado\n *   - Pedido entregado\n *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n * - Crea diferentes pedidos y muestra cómo se interactúa con ellos.\n */\n\"\"\"\n\n# Importamos Enum del módulo enum para crear enumeraciones.\nfrom enum import Enum\n\n\n# Definimos una clase enum para representar los días de la semana.\nclass Dias(Enum):\n    LUNES = 1\n    MARTES = 2\n    MIERCOLES = 3\n    JUEVES = 4\n    VIERNES = 5\n    SABADO = 6\n    DOMINGO = 7\n\n# Función para obtener el nombre del día de la semana dado un número entero.\ndef dia_de_la_semana(dia: int) -> str:\n    if 1 <= dia <=7:  # Verifica si el día está en el rango válido.\n        return Dias(dia).name  # Devuelve el nombre del día.\n\n    return \"Ese dia de la semana no existe\"  # Mensaje de error si el día no es válido.\n\n# Extra\n# Definimos una clase enum para representar el estado de un pedido.\nclass Estado(Enum):\n    PENDIENTE = 1\n    ENVIADO = 2\n    ENTREGADO = 3\n    CANCELADO = 4\n\n# Clase para representar un pedido con su estado.\nclass Pedido:\n    def __init__(self, identificador: int) -> None:\n        self.identificador = identificador  # Identificador del pedido.\n        self.estado = Estado.PENDIENTE  # Estado inicial del pedido.\n\n    # Método para cambiar el estado a ENVIADO.\n    def enviado(self):\n        if self.estado == Estado.PENDIENTE:\n            print(self.estado_actual())\n            self.estado = Estado.ENVIADO\n        else:\n            print(\"El producto ya se está enviando\")\n\n    # Método para cambiar el estado a ENTREGADO.\n    def entregado(self):\n        if self.estado == Estado.ENVIADO:\n            print(self.estado_actual())\n            self.estado = Estado.ENTREGADO\n        else:\n            print(\"El pedido aún no ha sido enviado\")\n\n    # Método para cambiar el estado a CANCELADO.\n    def cancelado(self):\n        if self.estado == Estado.ENTREGADO:\n            print(self.estado_actual())\n        elif self.estado == Estado.CANCELADO:\n            print(self.estado_actual())\n        self.estado = Estado.PENDIENTE\n\n    # Método para obtener una descripción del estado actual del pedido.\n    def estado_actual(self):\n        descripciones: dict = {\n            Estado.PENDIENTE: f\"El pedido {self.identificador} está pendiente\",\n            Estado.ENVIADO: f\"El pedido {self.identificador} está siendo enviado\",\n            Estado.ENTREGADO: f\"El pedido {self.identificador} fue entregado\",\n            Estado.CANCELADO: f\"El pedido {self.identificador} fue cancelado\"\n        }\n        return descripciones[self.estado]\n\n# Se muestra la funcion del inicio\nprint(dia_de_la_semana(3))\n\n# Crear instancias de Pedido.\npedido1 = Pedido(1)\npedido2 = Pedido(2)\n\n# Cambiar y mostrar estados de los pedidos.\npedido1.enviado()\npedido2.enviado()\n\npedido1.entregado()\npedido1.estado = Estado.CANCELADO\npedido2.entregado()\n\npedido1.cancelado()\npedido2.cancelado()\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/victorfer69.py",
    "content": "from enum import Enum\n\n#EJERCICIO\n\nclass Weekday(Enum):\n    Monday = 1\n    Tuesday = 2\n    Wednesday = 3\n    Thursday = 4\n    Friday = 5\n    Saturday = 6\n    Sunday = 7\n\ndef get_day(number:int):\n    print(Weekday(number).name)\n\nget_day(1)\n\n\n#EJERCICIO EXTRA\n\nclass Estado(Enum):\n    PENDIENTE = 1\n    ENVIADO = 2\n    ENTREGADO = 3\n    CANCELADO = 4\n\nclass order:\n\n    def __init__(self, id:int):\n        self.id = id\n        self.state = Estado.PENDIENTE\n\n    def OrderSended(self):\n        if self.state == Estado.PENDIENTE:\n            self.state = Estado.ENVIADO\n            print(\"Enviando pedido\")\n        else:\n            print(\"El pedido no existe\")\n\n    def OrderDelivered(self):\n        if self.state == Estado.ENVIADO:\n            self.state = Estado.ENTREGADO\n            print(\"Pedido entregado\")\n        else:\n            print(\"El pedido no esta enviado\")\n    \n    def OrderCancelled(self):\n        if self.state != Estado.ENTREGADO:\n            self.state = Estado.CANCELADO\n            print(\"Pedido cancelado\")\n        else:\n            print(\"El pedido no existe\")\n\n    def print(self):\n        print(f\"El pedido {self.id}, se encuentra en estado de {self.state.name}.\")\n\norder_1 = order(1)\norder_1.print()\norder_1.OrderSended()\norder_1.OrderDelivered()\norder_1.print()\n\n\norder_2 = order(2)\norder_2.print()\norder_2.OrderSended()\norder_2.OrderCancelled()\norder_2.print()"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/worlion.py",
    "content": "from enum import Enum\n\n\"\"\"\n    EJERCICIO: Enumeraciones\n\"\"\"\n\n# Enumeración de los días de la semana\nclass DiaSemana(Enum):\n    LUNES = 1\n    MARTES = 2\n    MIERCOLES = 3\n    JUEVES = 4\n    VIERNES = 5\n    SABADO = 6\n    DOMINGO = 7\n\ndef dia_semana(numero):\n    if numero < 1 or numero > 7:\n        return \"Día no válido\"\n    return DiaSemana(numero).name\n\nprint(f\"Dia 1 : {dia_semana(1)} \") # LUNES\nprint(f\"Dia 7 : {dia_semana(7)} \") # DOMINGO\nprint(f\"Dia 8 : {dia_semana(8)} \") # Día no válido\nprint(f\"Dia 0 : {dia_semana(0)} \") # Día no válido\n\n\"\"\"\n    DIFICULTAD EXTRA (opcional): Pedidos\n\"\"\"\n\nprint(\"\\n ---- 🌩 DIFICULTAD EXTRA 🌩 ----\\n\")\n\nclass EstadoPedido(Enum):\n    PENDIENTE = 1\n    ENVIADO = 2\n    ENTREGADO = 3\n    CANCELADO = 4\n    \nclass Pedido:\n    def __init__(self, identificador):\n        self.identificador = identificador\n        self.estado = EstadoPedido.PENDIENTE\n\n    def pedido_enviado(self):\n        if self.estado == EstadoPedido.PENDIENTE:\n            self.estado = EstadoPedido.ENVIADO\n        else:\n            print(\"No se puede enviar el pedido\")\n\n    def pedido_cancelado(self):\n        if self.estado == EstadoPedido.PENDIENTE:\n            self.estado = EstadoPedido.CANCELADO\n        else:\n            print(\"No se puede cancelar el pedido\")\n\n    def pedido_entregado(self):\n        if self.estado == EstadoPedido.ENVIADO:\n            self.estado = EstadoPedido.ENTREGADO\n        else:\n            print(\"No se puede entregar el pedido\")\n\n    def mostrar_estado(self):\n        return f\"Pedido {self.identificador} : {self.estado.name}\"\n    \n    def __str__(self):\n        return self.mostrar_estado()\n\npedido1 = Pedido(1)\npedido2 = Pedido(2)\npedido3 = Pedido(3)\n\nprint(pedido1)\npedido1.pedido_enviado()\nprint(pedido1)\npedido1.pedido_entregado()\nprint(pedido1)\npedido1.pedido_cancelado()\nprint(pedido1)\n\nprint(pedido2)\npedido2.pedido_entregado()\nprint(pedido2)\npedido2.pedido_cancelado()\nprint(pedido2)\n\nprint(pedido3)\npedido3.pedido_enviado()\nprint(pedido3)\npedido3.pedido_entregado()\nprint(pedido3)\npedido3.pedido_cancelado()\nprint(pedido3)\n\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/ycanas.py",
    "content": "from enum import Enum\n\n# ------ Ejercicio\n\nclass Days(Enum):\n\n    MONDAY: int = 1\n    TUESDAY: int = 2\n    WEDNESDAY: int = 3\n    THURSDAY: int = 4\n    FRIDAY: int = 5\n    SATURDAY: int = 6\n    SUNDAY: int = 7\n\n\nfor i in range(7):\n    print(Days(i + 1).name)\n\n\n# ------ Extra\n\nclass State(Enum):\n\n    OPEN: int = 1\n    SHIPPED: int = 2\n    DELIVERED: int = 3\n    CANCELLED: int = 4\n\n\nclass Order:\n\n    identifier: int\n    state: State\n\n\n    def __init__(self, state: State, identifier: int) -> None:\n        self.state = state\n        self.identifier = identifier\n\n\n    def get_state(self):\n        return f\"* Order #{self.identifier} {self.state.name}\"\n\n    \n    def send(self):\n        if self.state == State.OPEN:\n            self.state = State.SHIPPED\n            print(f\"* Order #{self.identifier} {self.state.name}\")\n            return\n        \n        self.__error()\n\n\n    def deliver(self):\n        if self.state == State.SHIPPED:\n            self.state = State.DELIVERED\n            print(f\"* Order #{self.identifier} {self.state.name}\")\n            return\n        \n        self.__error()\n\n\n    def cancel(self):\n        if self.state == State.OPEN or self.state == State.SHIPPED:\n            self.state = State.CANCELLED\n            print(f\"* Order #{self.identifier} {self.state.name}\")\n            return\n        \n        self.__error()\n\n    \n    def __error(self):\n        print(f\"* [Error] imposible change state, actual state ({self.state.name})\")\n\n\n\npc = Order(State.OPEN, 1587454)\nprint(pc.get_state())\npc.send()\npc.deliver()\npc.cancel()\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/python/zetared92.py",
    "content": "# RETO 19 ENUMERACIONES\nfrom enum import Enum\n\n\"\"\"\nCREAR UN ENUM QUE REPRESENTE LOS DÍAS DE LA SEMANA Y CREAR\nUNA OPERACIÓN QUE MUESTRE EL NOMBRE DEL DÍA DEPENDIENDO DEL\nNÚMERO ENTERO UTILIZADO (1-7)\n\"\"\"\n\nclass Week(Enum):\n    MONDAY = 1\n    TUESDAY = 2\n    WEDNESDAY = 3\n    THURSDAY = 4\n    FRIDAY = 5\n    SATURDAY = 6\n    SUNDAY = 7\n\ndef get_day(number: int):\n    print(Week(number).name)\n\nget_day(4)\nget_day(6)\n\n\n\n# Extra\n\nprint(\"🧩 DIFICULTAD EXTRA - SISTEMA DE GESTIÓN DEL ESTADO DE LOS PEDIDOS 🧩\")\n\nclass OrderStatus(Enum):\n    PENDING = 1\n    SHIPPED = 2\n    DELIVERED = 3\n    CANCELLED = 4\n\nclass Order:\n\n    status = OrderStatus.PENDING\n\n    def __init__(self, id) -> None:\n        self.id = id\n\n    def ship(self):\n        if self.status == OrderStatus.PENDING:\n            self.status = OrderStatus.SHIPPED\n            self.display_status()\n        else:\n            print(\"ORDER ISSUED OR CANCELED\")\n\n    def deliver(self):\n        if self.status == OrderStatus.SHIPPED:\n            self.status = OrderStatus.DELIVERED\n            self.display_status()\n        else:\n            print(\"THE ORDER NEEDS TO BE SHIPPED BEFORE BEING DELIVERED\")\n\n    def cancel(self):\n        if self.status != OrderStatus.DELIVERED:\n            self.status = OrderStatus.CANCELLED\n            self.display_status()\n        else:\n            print(\"ORDER SENT, CANNOT BE CANCELLED\")\n\n    def display_status(self):\n        print(f\"THE STATUS OF THE ORDER {self.id} IS {self.status.name}\")\n\nFirst_Order = Order(1)\nFirst_Order.display_status()\nFirst_Order.deliver()\nFirst_Order.ship()\nFirst_Order.deliver()\nFirst_Order.cancel()        "
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/ruby/Elmer125.rb",
    "content": "#  * EJERCICIO:\n#  * Empleando tu lenguaje, explora la definición del tipo de dato\n#  * que sirva para definir enumeraciones (Enum).\n#  * Crea un Enum que represente los días de la semana del lunes\n#  * al domingo, en ese orden. Con ese enumerado, crea una operación\n#  * que muestre el nombre del día de la semana dependiendo del número entero\n#  * utilizado (del 1 al 7).\n\nclass Week\n  DAYS_OF_THE_WEEK = { 1 => \"Monday\", 2 => \"Tuesday\", 3 => \"Wednesday\", 4 => \"Thursday\", 5 => \"Friday\", 6 => \"Saturday\", 7 => \"Sunday\" }\n\n  def self.get_day(day)\n    puts DAYS_OF_THE_WEEK[day]\n  end\nend\n\nWeek.get_day(1) # monday\nWeek.get_day(2) # tuesday\nWeek.get_day(3) # wednesday\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea un pequeño sistema de gestión del estado de pedidos.\n#  * Implementa una clase que defina un pedido con las siguientes características:\n#  * - El pedido tiene un identificador y un estado.\n#  * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n#  * - Implementa las funciones que sirvan para modificar el estado:\n#  *   - Pedido enviado\n#  *   - Pedido cancelado\n#  *   - Pedido entregado\n#  *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n#  * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n#  * - Crea diferentes pedidos y muestra cómo se interactúa con ellos.\n\nclass Orders\n  attr_accessor :id, :state\n  ORDERS_STATES = { 1 => \"PENDING\", 2 => \"SENT\", 3 => \"DELIVERED\", 4 => \"CANCELED\" }\n\n  def initialize(id)\n    @id = id\n    @state = 1\n  end\n\n  def show_state\n    puts \"The state of order #{@id} is #{ORDERS_STATES[@state]}\"\n  end\n\n  def send_order\n    if @state == 1\n      @state = 2\n      show_state\n    else\n      puts \"Order #{@id} can't be sent\"\n    end\n  end\n\n  def deliver_order\n    if @state == 2\n      @state = 3\n      show_state\n    else\n      puts \"Order #{@id} can't be delivered\"\n    end\n  end\n\n  def cancel_order\n    case @state\n    when 2\n      puts \"Order #{@id} can't be canceled because it has been sent\"\n      show_state\n    when 3\n      puts \"Order #{@id} can't be canceled because it has been delivered\"\n      show_state\n    else\n      @state = 4\n      show_state\n    end\n  end\nend\n\nbox = Orders.new(1)\nbox.show_state\nbox.send_order\nbox.cancel_order\nbox.deliver_order\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/rust/kenysdev.rs",
    "content": "/*\n╔═══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado                ║\n║ GitHub: https://github.com/Kenysdev   ║\n║ 2024 -  Rust                          ║\n╚═══════════════════════════════════════╝\n-----------------------------------------\n* ENUMERACIONES\n-----------------------------------------\nhttps://www.rustlang-es.org/rust-book-es/ch06-00-enums.html\n\n* EJERCICIO 1:\n* Empleando tu lenguaje, explora la definición del tipo de dato\n* que sirva para definir enumeraciones (Enum).\n* Crea un Enum que represente los días de la semana del lunes\n* al domingo, en ese orden. Con ese enumerado, crea una operación\n* que muestre el nombre del día de la semana dependiendo del número entero\n* utilizado (del 1 al 7).\n*/\n\n#[derive(Debug, PartialEq)]\nenum Weekday {\n    Monday = 1,\n    Tuesday = 2,\n    Wednesday = 3,\n    Thursday = 4,\n    Friday = 5,\n    Saturday = 6,\n    Sunday = 7,\n}\n\nimpl Weekday {\n    fn from_i32(num: i32) -> Option<Weekday> {\n        match num {\n            1 => Some(Weekday::Monday),\n            2 => Some(Weekday::Tuesday),\n            3 => Some(Weekday::Wednesday),\n            4 => Some(Weekday::Thursday),\n            5 => Some(Weekday::Friday),\n            6 => Some(Weekday::Saturday),\n            7 => Some(Weekday::Sunday),\n            _ => None,\n        }\n    }\n\n    fn get_day(num: i32) -> String {\n        if let Some(weekday) = Weekday::from_i32(num) {\n            format!(\"{:?}\", weekday)\n        } else {\n            String::from(\"'o'\")\n        }\n    }\n}\n\n/*\n* EJERCICIO 2:\n* Crea un pequeño sistema de gestión del estado de pedidos.\n* Implementa una clase que defina un pedido con las siguientes características:\n* - El pedido tiene un identificador y un estado.\n* - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n* - Implementa las funciones que sirvan para modificar el estado:\n*   - Pedido enviado\n*   - Pedido cancelado\n*   - Pedido entregado\n*   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n* - Implementa una función para mostrar un texto descriptivo según el estado actual.\n* - Crea diferentes pedidos y muestra cómo se interactúa con ellos. \n*/\n\n#[derive(Debug, PartialEq)] \nenum Status {\n    PENDING,\n    SHIPPED,\n    DELIVERED,\n    CANCELED,\n}\n\nstruct Order {\n    identifier: String,\n    status: Status,\n}\n\nimpl Order {\n    fn new(identifier: &str) -> Self {\n        Order {\n            identifier: identifier.to_string(),\n            status: Status::PENDING,\n        }\n    }\n\n    fn send(&mut self) {\n        println!(\"\\nEnviar:\");\n        if self.status == Status::PENDING {\n            self.status = Status::SHIPPED;\n            println!(\"{}\", self.info());\n        } else {\n            self.invalid();\n        }\n    }\n\n    fn cancel(&mut self) {\n        println!(\"\\nCancelar:\");\n        if self.status == Status::PENDING {\n            self.status = Status::CANCELED;\n            println!(\"{}\", self.info());\n        } else {\n            self.invalid();\n        }\n    }\n\n    fn deliver(&mut self) {\n        println!(\"\\nEntregar:\");\n        if self.status == Status::SHIPPED {\n            self.status = Status::DELIVERED;\n            println!(\"{}\", self.info());\n        } else {\n            self.invalid();\n        }\n    }\n\n    fn info(&self) -> String {\n        format!(\"{} is {:?}\", self.identifier, self.status)\n    }\n\n    fn invalid(&self) {\n        println!(\"Invalid operation, {}\", self.info());\n    }\n}\n\nfn main() {\n    println!(\"{}\", Weekday::get_day(7));\n    println!(\"{}\", Weekday::get_day(3));\n    println!(\"{}\", Weekday::get_day(9));\n\n     // Creación de pedidos\n     let mut libro1 = Order::new(\"libro1\");\n     let mut libro2 = Order::new(\"libro2\");\n     let mut libro3 = Order::new(\"libro3\");\n \n     // Positivas\n     println!(\"\\n-----\\nOperaciones exitosas:\\n-----\");\n     libro1.send();\n     libro1.deliver();\n     libro2.cancel();\n \n     // Negativas\n     println!(\"\\n-----\\nOperaciones inválidas:\\n-----\");\n     libro3.deliver();\n     libro2.cancel();\n     libro1.send();\n \n     // Info\n     println!(\"\\n-----\\nEstado de órdenes\\n-----\");\n     println!(\"{}\", libro1.info());\n     println!(\"{}\", libro2.info());\n     println!(\"{}\", libro3.info());\n\n}\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/sql/Nicojsuarez2.sql",
    "content": "# #19 ENUMERACIONES\n> #### Dificultad: Media | Publicación: 06/05/24 | Corrección: 13/05/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Empleando tu lenguaje, explora la definición del tipo de dato\n * que sirva para definir enumeraciones (Enum).\n * Crea un Enum que represente los días de la semana del lunes\n * al domingo, en ese orden. Con ese enumerado, crea una operación\n * que muestre el nombre del día de la semana dependiendo del número entero\n * utilizado (del 1 al 7).\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un pequeño sistema de gestión del estado de pedidos.\n * Implementa una clase que defina un pedido con las siguientes características:\n * - El pedido tiene un identificador y un estado.\n * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n * - Implementa las funciones que sirvan para modificar el estado:\n *   - Pedido enviado\n *   - Pedido cancelado\n *   - Pedido entregado\n *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n * - Crea diferentes pedidos y muestra cómo se interactúa con ellos. \n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/swift/allbertoMD.swift",
    "content": "import Foundation\n\n\n\n// Definición del enum de los dias de la semana.\nenum WeekDays: Int {\n    case monday = 1\n    case tuesday = 2\n    case wednesday = 3\n    case thursday = 4\n    case  friday = 5\n    case saturday = 6\n    case sunday = 7\n}\n\n// Pide por consola el número del dia de la semana que quieres comprobar.\nprint(\"\\n[+] - Introduce el número del dia de la semana:\")\nguard let input = readLine(), let numberOfTheDay = Int(input) else {\n    fatalError()\n}\n\n// Inserta el número añadido al valor del enum.\nif let weekDays = WeekDays(rawValue: numberOfTheDay) {\n    // Comprueva que dia de la semana corresponde al número introducido.\n    switch weekDays {\n    \n    case .monday:\n        print(\"Es lunes.\")\n    \n    case .tuesday:\n        print(\"Es martes.\")\n    \n    case .wednesday:\n        print(\"Es miercoles.\")\n    \n    case .thursday:\n        print(\"Es jueves.\")\n    \n    case .friday:\n        print(\"Es viernes.\")\n    \n    case .saturday:\n        print(\"Es sabado.\")\n    \n    case .sunday:\n        print(\"Es domingo.\")\n    }\n} else {\n    print(\"[!] - Numero no valido.\")\n}\n\n\n\n\n// DIFICULTAD EXTRA\nprint(\"\\nDIFICULTAD EXTRA.\")\n// Espera 4 segundos antes de ejecutar la dificultad extra.\nsleep(4)\n\n\n\n// Definición de la clase para manejar el estatus de un pedido.\nclass Order {\n    let id: String // Declara la propiedad id.\n    var orderStatus: Status // Declara la propiedad orderStatus\n    \n    // Define el inicializador para las dos propiedades, el parametro id tiene valor por defecto.\n    init(id: String = UUID().uuidString, orderStatus: Status) {\n        self.id = id\n        self.orderStatus = orderStatus\n    }\n    \n    // Definición del enum con los estados del producto.\n    enum Status {\n        case pending\n        case shipped\n        case delivered\n        case cancelated\n    }\n    \n    // Definición de la función para enviar el pedido, el parametro shippedStatus con valor por defecto.\n    func shippedOrder(forOrder order: Order, shippedStatus: Status = .shipped) {\n        if orderStatus == .shipped {\n            print(\"\\nEl pedido \\(order.id) esta enviado.\")\n            \n        } else if orderStatus == .pending {\n            print(\"\\nEl pedido \\(order.id) esta aun pendiente.\")\n            \n        } else if orderStatus == .delivered {\n            print(\"\\nEl pedido \\(order.id) aun no se ha entregado.\")\n            \n        } else if orderStatus == .cancelated {\n            print(\"\\nEl pedido \\(order.id) se ha cancelado.\")\n        }\n    }\n    \n    // Definición de la función para entregra el pedido, el parametro deliveredStatus con valor por defecto.\n    func deliveredOrder(forOrder order: Order, deliveredStatus: Status = .delivered) {\n        if orderStatus == .delivered {\n            print(\"El pedido \\(order.id) fue entregado.\")\n            \n        } else if orderStatus == .pending {\n            print(\"\\nEl pedido \\(order.id) aun esta pendiente.\")\n            \n        } else if orderStatus == .shipped {\n            print(\"\\nEl pedido \\(order.id) este de camino.\")\n            \n        } else if orderStatus == .cancelated {\n            print(\"\\nEl pedido \\(order.id) fue cancelado.\")\n        }\n    }\n    \n    // Definición de la función para cancelar el pedido, el parametro cancelatedStatus con valor por defecto.\n    func cancelatedOrder(forOrder order: Order, cancelatedStatus: Status = .cancelated) {\n        if orderStatus == .cancelated {\n            print(\"\\nPedido \\(order.id) cancelado.\")\n            \n        } else if orderStatus == .pending {\n            print(\"\\nPedido \\(order.id) cancelado.\")\n            \n        } else if orderStatus == .shipped {\n            print(\"\\nEl pedido \\(order.id) esta de camino, no se puede cancelar\")\n            \n        } else if orderStatus == .delivered {\n            print(\"\\nEl pedido \\(order.id) fue entregado, no se puede cancelar.\")\n        }\n    }\n    \n    // Definición de la función para imprimir el estado del producto.\n    func printOrderInfo(forOrder order: Order) {\n        switch order.orderStatus {\n            \n        case .pending:\n            print(\"El pedido \\(order.id) esta pendiente.\")\n        \n        case .shipped:\n            print(\"El pedido \\(order.id) esta de camino.\")\n        \n        case .delivered:\n            print(\"El pedido \\(order.id) fue entregado.\")\n        \n        case .cancelated:\n            print(\"El pedido \\(order.id) fue cancelado.\")\n        }\n    }\n}\n\n// Ejemplos con la clase.\nlet order1 = Order(orderStatus: .pending)\norder1.shippedOrder(forOrder: order1)\norder1.printOrderInfo(forOrder: order1)\n\nlet order2 = Order(orderStatus: .shipped)\norder2.deliveredOrder(forOrder: order2)\norder2.printOrderInfo(forOrder: order2)\n\nlet order3 = Order(orderStatus: .delivered)\norder3.cancelatedOrder(forOrder: order3)\norder3.printOrderInfo(forOrder: order3)\n\nlet order4 = Order(orderStatus: .cancelated)\norder4.deliveredOrder(forOrder: order4)\norder4.printOrderInfo(forOrder: order4)\n\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/swift/blackriper.swift",
    "content": "import Foundation\n/*\n La Enumeracion define un grupo de un solo tipo de valor lo cual ayuda \n a trabajar con los datos de forma mas eficiente.\n\n Las Enumeracion asocioan los valores de una variable o constante\n con un nombre de identificador.\n\n las enumeraciones en swift  son un tipo de  clase por lo cual pueden\n adoptar caracteristicas de las mismas\n\n Ejemplo de Enumeracion\n\n enum Direction {\n     case north\n     case south\n     case east\n     case west\n }\n */\n\nenum DayoftheWeek:Int {\n    case sunday=1\n    case monday=2\n    case tuesday=3\n    case wednesday=4\n    case thursday=5\n    case friday=6\n    case saturday=7\n}\n\nif let possibleday = DayoftheWeek(rawValue: 3){\n    print(possibleday)\n}\n\n// extra exercise\n\n\nenum State{\n    case pending\n    case sending\n    case received\n    case completed\n    case canceled\n }\n\n\nstruct Order{\n   let id : Int\n   var state : State\n\n  mutating func ChangeState(newState: State){\n       if RuleChangeState(newState){\n           self.state = newState           \n       }          \n   }\n\n\n   private func RuleChangeState(_ newState: State)->Bool{\n      // si la orden esta en estado pendiente este no puede pasar a recibido sin ser enviado\n      if  self.state == .pending && newState == .received {\n          return false\n      }\n\n     // si le orden ya fue enviada esta no puede estar en estado pendiente\n     if self.state == .sending && newState == .pending{\n         return false\n     }\n    \n    // si la orden ya fue recibida esta no puede cambiar de estado a pendiente o enviada \n    if self.state == .received  && (newState == .pending || newState == .sending){\n        return false\n    }\n     \n     // si es cancelado este no puede cambiar de estado\n      if self.state == .canceled{\n          return false\n        }\n     return true\n   }\n}\n\n// ejemplos \nvar order1 :Order = Order(id: 1, state: .pending)\nvar order2 :Order = Order(id: 2, state: .pending)\nvar order3 :Order = Order(id: 3, state: .canceled)\n\n// no se puede cambiar de estado por laa reglas definidas\norder1.ChangeState(newState: .received)\nprint(\"Order \\(order1.id) state: \\(order1.state)\")\n\n// se actualiza el estado correctamente \norder2.ChangeState(newState: .sending)\nprint(\"Order \\(order2.id) state: \\(order2.state)\")\n\n// no se puede cambiar de estado porque la orden ya fue cancelada\norder3.ChangeState(newState: .sending)\nprint(\"Order \\(order3.id) state: \\(order3.state)\")\n\n\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/swift/pedroomar23.swift",
    "content": "import Foundation \n\n/*\n * EJERCICIO:\n * Empleando tu lenguaje, explora la definición del tipo de dato\n * que sirva para definir enumeraciones (Enum).\n * Crea un Enum que represente los días de la semana del lunes\n * al domingo, en ese orden. Con ese enumerado, crea una operación\n * que muestre el nombre del día de la semana dependiendo del número entero\n * utilizado (del 1 al 7).\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un pequeño sistema de gestión del estado de pedidos.\n * Implementa una clase que defina un pedido con las siguientes características:\n * - El pedido tiene un identificador y un estado.\n * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n * - Implementa las funciones que sirvan para modificar el estado:\n *   - Pedido enviado\n *   - Pedido cancelado\n *   - Pedido entregado\n *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n * - Crea diferentes pedidos y muestra cómo se interactúa con ellos. \n */\n\nenum Weekend: Int {\n    case luenes = 1 \n    case martes = 2 \n    case miercoles = 3 \n    case jueves = 4 \n    case viernes = 5 \n    case sabado = 6 \n    case domingo = 7 \n}\n\n\n\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/typescript/AChapeton.ts",
    "content": "enum WeekDays {\n  Monday = 1,\n  Tuesday = 2,\n  Wednesday = 3,\n  Thursday = 4,\n  Friday = 5,\n  Saturday = 6,\n  Sunday = 7\n}\n\nconst obtainDay = (numberOfDay: number) => {\n  console.log(`Number of the day ${numberOfDay} of the week is ${WeekDays[numberOfDay]}`) \n}\n\nobtainDay(3)\nobtainDay(7)"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/typescript/IgleDev.ts",
    "content": "// Ejercicio 1\n    // Un enum es una lista de constantes.\n    enum diasSemana {Lunes = 1, Martes = 2, Miércoles = 3, Jueves = 4, Viernes = 5, Sábado = 6, Domingo = 7};\n\n    console.log('Introduce un número')\n    console.log(`Hoy es ${diasSemana[2]}`);\n    console.log(`Quedan 7 días para él ${diasSemana[1]}`);\n    console.log(`Mi cumple cuadra un ${diasSemana[3]}`);\n\n// Ejercicio Extra\n\n    enum EstadoPedido{PENDIENTE, ENVIADO, ENTREGADO, CANCELADO}\n\n    class Pedido {\n        constructor(private _id : number, private _estado : EstadoPedido){}\n\n        set id(id : number){\n            this._id = id;\n        } \n\n        get id() : number{\n            return this._id;\n        }\n\n        set estado(estado : EstadoPedido){\n            this._estado = estado;\n        }\n        \n        get estado() : EstadoPedido{\n            return this._estado;\n        }\n    \n        public ActualizarEstado(nuevoEstado : EstadoPedido) : void {\n            this._estado = nuevoEstado;\n        }\n    }\n\n    // Ciclo de vida de nuestro Pedido 1\n    let pedido1 = new Pedido(1, EstadoPedido.PENDIENTE);\n    console.log(`Día de hoy: ${diasSemana[2]}. Tu pedido con identificador ${pedido1.id} está ${EstadoPedido[pedido1.estado]}, llegará el ${diasSemana[4]}`);\n    //Mandando el pedido\n    pedido1.ActualizarEstado(EstadoPedido.ENVIADO)\n    console.log(`Día de hoy: ${diasSemana[3]}. Tu pedido con identificador ${pedido1.id} está ${EstadoPedido[pedido1.estado]}, llegará el ${diasSemana[4]}`);\n    //Pedido Entregado\n    pedido1.ActualizarEstado(EstadoPedido.ENTREGADO)\n    console.log(`Día de hoy: ${diasSemana[4]}. Tu pedido con identificador ${pedido1.id} está ${EstadoPedido[pedido1.estado]}`);\n    \n    // Ciclo de vida de nuestro Pedido 2\n    let pedido2 = new Pedido(2, EstadoPedido.PENDIENTE);\n    console.log(`Día de hoy: ${diasSemana[2]}. Tu pedido con identificador ${pedido2.id} está ${EstadoPedido[pedido2.estado]}, llegará el ${diasSemana[6]}`);\n    //Mandando el pedido\n    pedido2.ActualizarEstado(EstadoPedido.ENVIADO)\n    console.log(`Día de hoy: ${diasSemana[3]}. Tu pedido con identificador ${pedido2.id} está ${EstadoPedido[pedido2.estado]}, llegará el ${diasSemana[6]}`);\n    //Pedido Cancelado\n    pedido2.ActualizarEstado(EstadoPedido.CANCELADO)\n    console.log(`Día de hoy: ${diasSemana[4]}. El cliente decidió cancelar su pedido con identificador ${pedido2.id}, el pedido está ${EstadoPedido[pedido2.estado]}`);\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/typescript/Sac-Corts.ts",
    "content": "const DaysOfWeek: { [key: number]: string } = {\n    1: \"Monday\",\n    2: \"Tuesday\",\n    3: \"Wednesday\",\n    4: \"Thursday\",\n    5: \"Friday\",\n    6: \"Saturday\",\n    7: \"Sunday\"\n};\n\nfunction getDayName(dayNumber: number): string {\n    return DaysOfWeek[dayNumber] || \"Invalid day number\";\n}\n\nconsole.log(getDayName(1));\nconsole.log(getDayName(7));\nconsole.log(getDayName(8));\n\n// ** Extra Exercise ** //\nconst OrderStatus = {\n    PENDING: \"pending\",\n    SENT: \"sent\",\n    DELIVERED: \"delivered\", \n    CANCELED: \"canceled\"\n} as const;\n\nclass Order {\n    id: number;\n    status: typeof OrderStatus[keyof typeof OrderStatus];\n\n    constructor(id: number) {\n        this.id = id;\n        this.status = OrderStatus.PENDING;\n    }\n\n    sendOrder(): void {\n        if (this.status === OrderStatus.PENDING) {\n            this.status = OrderStatus.SENT;\n            console.log(`Order ${this.id} has been sent.`);\n        } else {\n            console.log(`Order ${this.id} cannot be sent in status ${this.status}.`);\n        }\n    }\n\n    cancelOrder(): void {\n        if (this.status === OrderStatus.DELIVERED) {\n            console.log(`Order ${this.id} cannot be canceled, because it has already been delivered.`);\n        } else {\n            this.status = OrderStatus.CANCELED;\n            console.log(`Order ${this.id} has been canceled.`);\n        }\n    }\n\n    deliverOrder(): void {\n        if (this.status === OrderStatus.SENT) {\n            this.status = OrderStatus.DELIVERED;\n            console.log(`Order ${this.id} has been delivered.`);\n        } else {\n            console.log(`Order ${this.id} cannot be delivered in status ${this.status}.`);\n        }\n    }\n\n    showStatus(): void {\n        console.log(`Order ${this.id} status is ${this.status}`);\n    }\n}\n\nconst order1 = new Order(1);\norder1.showStatus();\norder1.sendOrder();\norder1.deliverOrder();\norder1.cancelOrder();\n\nconst order2 = new Order(2);\norder2.sendOrder();\norder2.cancelOrder();\norder2.showStatus();\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/typescript/cesar-ch.ts",
    "content": "// Enum para representar los días de la semana\nenum DiasSemana {\n    LUNES,\n    MARTES,\n    MIERCOLES,\n    JUEVES,\n    VIERNES,\n    SABADO,\n    DOMINGO\n}\n\n// Función para obtener el nombre del día de la semana según el número\n\nfunction obtenerDia(numeroDia: number): string {\n    return DiasSemana[numeroDia];\n}\n\nconsole.log(obtenerDia(DiasSemana.LUNES)); \nconsole.log(obtenerDia(DiasSemana.JUEVES)); \n\n/*\n    * DIFICULTAD EXTRA\n*/\n\n// Enum para representar el estado de los pedidos\nenum EstadoPedido {\n    PENDIENTE = \"Pendiente\",\n    ENVIADO = \"Enviado\",\n    ENTREGADO = \"Entregado\",\n    CANCELADO = \"Cancelado\"\n}\n\n\nclass Pedido {\n    constructor(private id: number, private estado: EstadoPedido = EstadoPedido.PENDIENTE) { }\n\n    enviar(): void {\n        if (this.estado === EstadoPedido.PENDIENTE) {\n            this.estado = EstadoPedido.ENVIADO;\n            console.log(`El pedido ${this.id} ha sido enviado.`);\n        } else {\n            console.log(`El pedido ${this.id} no puede ser enviado porque su estado es ${this.estado}.`);\n        }\n    }\n\n    entregar(): void {\n        if (this.estado === EstadoPedido.ENVIADO) {\n            this.estado = EstadoPedido.ENTREGADO;\n            console.log(`El pedido ${this.id} ha sido entregado.`);\n        } else {\n            console.log(`El pedido ${this.id} no puede ser entregado porque su estado es ${this.estado}.`);\n        }\n    }\n\n    cancelar(): void {\n        if (this.estado !== EstadoPedido.ENTREGADO) {\n            this.estado = EstadoPedido.CANCELADO;\n            console.log(`El pedido ${this.id} ha sido cancelado.`);\n        } else {\n            console.log(`El pedido ${this.id} no puede ser cancelado porque ya ha sido entregado.`);\n        }\n    }\n\n    mostrarEstado(): void {\n        console.log(`Estado del pedido ${this.id}: ${this.estado}`);\n    }\n}\n\n\nconst pedido1 = new Pedido(1);\npedido1.mostrarEstado(); \npedido1.enviar(); \npedido1.entregar(); \npedido1.mostrarEstado();\n\nconst pedido2 = new Pedido(2);\npedido2.cancelar(); \npedido2.mostrarEstado();\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/typescript/duendeintemporal.ts",
    "content": "//#19  { Retos para Programadores } ENUMERACIONES\n//I use GPT as a reference for concepts\n/*\n * EJERCICIO:\n * Empleando tu lenguaje, explora la definición del tipo de dato\n * que sirva para definir enumeraciones (Enum).\n * Crea un Enum que represente los días de la semana del lunes\n * al domingo, en ese orden. Con ese enumerado, crea una operación\n * que muestre el nombre del día de la semana dependiendo del número entero\n * utilizado (del 1 al 7).\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un pequeño sistema de gestión del estado de pedidos.\n * Implementa una clase que defina un pedido con las siguientes características:\n * - El pedido tiene un identificador y un estado.\n * - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n * - Implementa las funciones que sirvan para modificar el estado:\n *   - Pedido enviado\n *   - Pedido cancelado\n *   - Pedido entregado\n *   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n * - Implementa una función para mostrar un texto descriptivo según el estado actual.\n * - Crea diferentes pedidos y muestra cómo se interactúa con ellos. \n */\n\n/* In JavaScript, Enums (short for \"enumerations\") are not a native feature of the language like in other programming languages (for example, TypeScript, C#, Java). However, you can simulate the behavior of enums using objects.\n/* \n * In TypeScript, Enums (short for \"enumerations\") are a native feature of the language.\n * Enums allow you to define a set of named constants, making your code more readable and maintainable.\n * Unlike JavaScript, where you need to simulate enums using objects, TypeScript provides built-in support for enums.\n * \n * Example:\n * enum Direction {\n *   Up = \"UP\",\n *   Down = \"DOWN\",\n *   Left = \"LEFT\",\n *   Right = \"RIGHT\"\n * }\n * \n * This creates a type-safe way to work with a fixed set of values.\n */\n// What are Enums?\n// Enums are a way to define a set of named constants. They are used to represent a group of related values, making the code more readable and easier to maintain. For example, you might have an enum for the days of the week, the statuses of an order, or colors. */\n\nlet log = console.log;\n\n// Conditional check for browser environment\nif (typeof window !== 'undefined') {\n    window.addEventListener('load', () => {\n        const body: HTMLBodyElement | null = document.querySelector('body');\n        const title = document.createElement('h1');\n\n        body?.style.setProperty('background', '#000');\n        body?.style.setProperty('text-align', 'center');\n\n        title.textContent = 'Retosparaprogramadores #19.';\n        title.style.setProperty('font-size', '3.5vmax');\n        title.style.setProperty('color', '#fff');\n        title.style.setProperty('line-height', '100vh');\n\n        body?.appendChild(title);\n\n        setTimeout(() => {\n            alert('Retosparaprogramadores #19. Please open the Browser Developer Tools.');\n        }, 2000);\n        log('Retosparaprogramadores #19');\n});\n} else {\n    log('This code is designed to run in a browser environment. Skipping window-related code.');\n    log('Retosparaprogramadores #19');\n}\nfor(let i = 1; i <= 10; i++){\n    log(i);\n} // print numbers from 1 to 10\n\nconst DaysOfWeek: { [key: string]: string } = {\n    MONDAY: 'Monday',\n    TUESDAY: 'Tuesday',\n    WEDNESDAY: 'Wednesday',\n    THURSDAY: 'Thursday',\n    FRIDAY: 'Friday',\n    SATURDAY: 'Saturday',\n    SUNDAY: 'Sunday'\n};\n\nObject.freeze(DaysOfWeek);\n\nconst showDay = (day: number): string=>{    \n    const w_days = Object.keys(DaysOfWeek);\n    return (w_days[day - 1])? DaysOfWeek[w_days[day - 1]] : 'You enter a invalid day, try between 1 and 7'; \n} \n\nlog(DaysOfWeek.MONDAY); // Monday\nlog(showDay(3)) // Wednesday\n\n//Extra Dificulty Exercise\n\n//Enum simulation\nconst OrderStatus: { [key: string]: string } = {\n    PENDING: 'Pending',\n    SHIPPED: 'Shipped',\n    DELIVERED: 'Delivered',\n    CANCELED: 'Canceled'\n};\n\nObject.freeze(OrderStatus);\n\nclass Order{\n    id: string;\n    state: string;\n\n    constructor(id: string){\n        this.id = id;\n        this.state = OrderStatus.PENDING;\n    }\n\n    setState(state: string){\n        this.state = OrderStatus[state];\n    }\n\n    getState(): string{\n        return this.state;\n    }\n\n    shipOrder(): void{\n        if(this.state.toLowerCase() == OrderStatus.PENDING.toLowerCase()){\n            log('The order is Shipped');\n            this.setState('SHIPPED');\n        }else {\n            log(`Cannot ship. Current state: ${this.state}`);\n        }\n    }\n\n    deliverOrder(): void{\n        if(this.state.toLowerCase() == OrderStatus.SHIPPED.toLowerCase()){\n            log('The order is Delivered');\n            this.setState('DELIVERED');\n        }else{\n            log(`Cannot deliver. The order state is: ${this.state}`);\n        }\n    }\n\n    cancelOrder(): void{\n        if(this.state.toLowerCase() == OrderStatus.DELIVERED.toLowerCase()){\n            log('Cannot cancel. The order has already been delivered.')\n        }\n            log('The order is Canceled');\n            this.setState('CANCELED');\n        }\n\n        describeOrder(): void {\n            log(`Order ID: ${this.id}, Current State: ${this.state}`);\n        }\n    }\n\nlet order15: Order = new Order('001');\nlet order16: Order = new Order('002');\nlet order17: Order = new Order('003');\n\norder16.shipOrder(); // The order is Shipped\norder15.deliverOrder(); // Cannot Deliver. The order state is: Pending\norder17.shipOrder(); // The order is Shipped\n\norder16.deliverOrder(); // The order is Delivered\norder15.shipOrder(); // The order is Shipped\norder17.cancelOrder(); // The order is Canceled\n\nlog(order16.getState()); // Delivered\nlog(order15.getState()); // Shipped\nlog(order17.getState()); // Canceled\n\norder16.shipOrder() // Cannot ship. Current state: Delivered\n\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/typescript/eulogioep.ts",
    "content": "// Resumen sobre Enumeraciones\n// Las enumeraciones (Enums) en TypeScript permiten definir un conjunto de valores con nombre.\n// Son útiles para representar datos categóricos que tienen un número limitado de valores, como los días de la semana o el estado de un pedido.\n\nenum DiasSemana {\n  Lunes = 1,\n  Martes = 2,\n  Miercoles = 3,\n  Jueves = 4,\n  Viernes = 5,\n  Sabado = 6,\n  Domingo = 7,\n}\n\n// Función para obtener el nombre del día a partir de un número entero\nfunction obtenerNombreDia(numeroDia: number): string {\n  switch (numeroDia) {\n    case DiasSemana.Lunes:\n      return \"Lunes\";\n    case DiasSemana.Martes:\n      return \"Martes\";\n    case DiasSemana.Miercoles:\n      return \"Miércoles\";\n    case DiasSemana.Jueves:\n      return \"Jueves\";\n    case DiasSemana.Viernes:\n      return \"Viernes\";\n    case DiasSemana.Sabado:\n      return \"Sábado\";\n    case DiasSemana.Domingo:\n      return \"Domingo\";\n    default:\n      return \"Número de día inválido\";\n  }\n}\n\n// Ejemplo de uso de la función obtenerNombreDia\nconsole.log(obtenerNombreDia(1)); // Salida: Lunes\nconsole.log(obtenerNombreDia(7)); // Salida: Domingo\n\n// Dificultad Extra: Sistema de gestión del estado de pedidos\nenum EstadoPedido {\n  Pendiente = \"Pendiente\",\n  Enviado = \"Enviado\",\n  Entregado = \"Entregado\",\n  Cancelado = \"Cancelado\",\n}\n\nclass Pedido {\n  private id: number;\n  private estado: EstadoPedido;\n\n  constructor(id: number, estado: EstadoPedido = EstadoPedido.Pendiente) {\n    this.id = id;\n    this.estado = estado;\n  }\n\n  public enviar(): void {\n    if (this.estado === EstadoPedido.Pendiente) {\n      this.estado = EstadoPedido.Enviado;\n    } else {\n      console.log(\"El pedido no se puede enviar.\");\n    }\n  }\n\n  public entregar(): void {\n    if (this.estado === EstadoPedido.Enviado) {\n      this.estado = EstadoPedido.Entregado;\n    } else {\n      console.log(\"El pedido no se puede entregar.\");\n    }\n  }\n\n  public cancelar(): void {\n    if (this.estado !== EstadoPedido.Entregado) {\n      this.estado = EstadoPedido.Cancelado;\n    } else {\n      console.log(\"El pedido no se puede cancelar.\");\n    }\n  }\n\n  public obtenerDescripcionEstado(): string {\n    return `El estado actual del pedido ${this.id} es ${this.estado}.`;\n  }\n}\n\n// Ejemplo de interacción con diferentes pedidos\nconst pedido1 = new Pedido(1);\nconst pedido2 = new Pedido(2);\n\npedido1.enviar();\nconsole.log(pedido1.obtenerDescripcionEstado()); // Salida: El estado actual del pedido 1 es Enviado.\n\npedido1.entregar();\nconsole.log(pedido1.obtenerDescripcionEstado()); // Salida: El estado actual del pedido 1 es Entregado.\n\npedido2.cancelar();\nconsole.log(pedido2.obtenerDescripcionEstado()); // Salida: El estado actual del pedido 2 es Cancelado.\n\nconst pedido3 = new Pedido(3);\npedido3.enviar();\npedido3.cancelar(); // Esto no debería ser posible, y se verá reflejado en el mensaje.\n\nconsole.log(pedido3.obtenerDescripcionEstado()); // Salida: El estado actual del pedido 3 es Enviado.\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/typescript/hozlucas28.ts",
    "content": "/*\n    Enums...\n*/\n\nconsole.log('Enums...')\n\nenum WeekDays {\n\tMonday,\n\tTuesday,\n\tWednesday,\n\tThursday,\n\tFriday,\n\tSaturday,\n\tSunday,\n}\n\nconsole.log(`\\nName of the first week day: ${WeekDays[0]}`)\nconsole.log(`Name of the second week day: ${WeekDays[1]}`)\nconsole.log(`Name of the third week day: ${WeekDays[2]}`)\nconsole.log(`Name of the fourth week day: ${WeekDays[3]}`)\nconsole.log(`Name of the fifth week day: ${WeekDays[4]}`)\nconsole.log(`Name of the sixth week day: ${WeekDays[5]}`)\nconsole.log(`Name of the seventh week day: ${WeekDays[6]}`)\n\nconsole.log(\n\t'\\n# ---------------------------------------------------------------------------------- #\\n'\n)\n\n/*\n    Additional challenge...\n*/\n\nconsole.log('Additional challenge...')\n\nenum State {\n\tEarring,\n\tSent,\n\tDelivered,\n\tCancelled,\n}\n\nclass Order {\n\tprotected id: number\n\tprotected state: State\n\n\tconstructor({ id, state }: { id: number; state: State }) {\n\t\tthis.id = id\n\t\tthis.state = state\n\t}\n\n\tpublic getId(): number {\n\t\treturn this.id\n\t}\n\n\tpublic getState(): State {\n\t\treturn this.state\n\t}\n\n\tpublic cancel(): void | never {\n\t\tif (this.state === State.Earring) {\n\t\t\tthis.state = State.Cancelled\n\t\t\treturn\n\t\t}\n\n\t\tthrow new Error(`The order with ${this.id} id can't be cancelled`)\n\t}\n\n\tpublic delivered(): void | never {\n\t\tif (this.state === State.Sent) {\n\t\t\tthis.state = State.Delivered\n\t\t\treturn\n\t\t}\n\n\t\tthrow new Error(`The order with ${this.id} id can't be delivered`)\n\t}\n\n\tpublic printState(): this {\n\t\tconsole.log(\n\t\t\t`The order with ${this.id} id was ${State[this.state].toLowerCase()}`\n\t\t)\n\t\treturn this\n\t}\n\n\tpublic send(): void | never {\n\t\tif (this.state === State.Earring) {\n\t\t\tthis.state = State.Sent\n\t\t\treturn\n\t\t}\n\n\t\tthrow new Error(`The order with ${this.id} id can't be sent`)\n\t}\n}\n\nconst firstOrder: Order = new Order({ id: 1, state: State.Earring })\nconst secondOrder: Order = new Order({ id: 2, state: State.Sent })\nconst thirdOrder: Order = new Order({ id: 3, state: State.Delivered })\nconst fourthOrder: Order = new Order({ id: 4, state: State.Cancelled })\n\nconsole.log()\nfirstOrder.printState()\nsecondOrder.printState()\nthirdOrder.printState()\nfourthOrder.printState()\n\nfirstOrder.send()\nfirstOrder.delivered()\n\nconsole.log()\nfirstOrder.printState()\n\nconsole.log()\ntry {\n\tsecondOrder.send()\n} catch (error) {\n\tif (error instanceof Error) console.error(error.message)\n}\n\ntry {\n\tthirdOrder.delivered()\n} catch (error) {\n\tif (error instanceof Error) console.error(error.message)\n}\n\ntry {\n\tfourthOrder.send()\n} catch (error) {\n\tif (error instanceof Error) console.error(error.message)\n}\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/typescript/victor-Casta.ts",
    "content": "enum DaysOfTheWeek {\n  MONDAY = 1,\n  TUESDAY = 2,\n  WEDNESDAY = 3,\n  THURSDAY = 4,\n  FRIDAY = 5,\n  SATURDAY = 6,\n  SUNDAY = 7\n}\n\nconst getDay: (number: number) => string  = (number: number) => {\n  return DaysOfTheWeek[number]\n}\n\nconsole.log(getDay(1))\n\n\n/*\n  * Extra\n*/\n\n\nenum DeliveryStatus {\n  PENDING,\n  SHIPPED,\n  DELIVERED,\n  CANCELLED\n}\n\nclass OrderSystem {\n  id: number\n  status: DeliveryStatus\n  nameOfOrder: string\n\n  constructor(id: number, nameOfOrder: string) {\n    this.id = id\n    this.status = DeliveryStatus.PENDING\n    this.nameOfOrder = nameOfOrder\n  }\n\n  orderShipped() {\n    if (this.status !== DeliveryStatus.PENDING) {\n      console.log(`El pedido \"${this.nameOfOrder}\" ya se ha enviado o cancelado`)\n      return\n    }\n    this.status = DeliveryStatus.SHIPPED\n    console.log(`El pedido \"${this.nameOfOrder}\" ha sido enviado`)\n  }\n\n  orderCancelled() {\n    if (this.status === DeliveryStatus.SHIPPED) {\n      console.log(`El pedido \"${this.nameOfOrder}\" no se puede cancelar porque ya se ha enviado`)\n      return\n    }\n    if (this.status === DeliveryStatus.CANCELLED) {\n      console.log(`El pedido \"${this.nameOfOrder}\" ya se encuentra cancelado`)\n      return\n    }\n    if (this.status === DeliveryStatus.DELIVERED) {\n      console.log(`El pedido \"${this.nameOfOrder}\" no se puede cancelar porque ya se ha entregado`)\n      return\n    }\n    this.status = DeliveryStatus.CANCELLED\n    console.log(`El pedido \"${this.nameOfOrder}\" ha sido cancelado`)\n  }\n\n  orderDelivered() {\n    if (this.status === DeliveryStatus.CANCELLED) {\n      console.log(`El pedido \"${this.nameOfOrder}\" no se puede entregar porque ha sido cancelado`)\n      return\n    }\n    if (this.status === DeliveryStatus.PENDING) {\n      console.log(`El pedido \"${this.nameOfOrder}\" aún no se ha enviado`)\n      return\n    }\n    this.status = DeliveryStatus.DELIVERED\n    console.log(`El pedido \"${this.nameOfOrder}\" ha sido entregado`)\n  }\n\n  actualStateOfOrder() {\n    const statusMap = {\n      [DeliveryStatus.PENDING]: 'Pendiente',\n      [DeliveryStatus.SHIPPED]: 'Enviado',\n      [DeliveryStatus.DELIVERED]: 'Entregado',\n      [DeliveryStatus.CANCELLED]: 'Cancelado'\n    }\n    console.log(`El estado actual del pedido \"${this.nameOfOrder}\" es: ${statusMap[this.status]}`)\n  }\n}\n\nconst burguerOrder = new OrderSystem(1, 'Burguer Max')\nburguerOrder.actualStateOfOrder()\nburguerOrder.orderShipped()\nburguerOrder.actualStateOfOrder()\nburguerOrder.orderDelivered()\nburguerOrder.actualStateOfOrder()\n\nconst iceCreamOrder = new OrderSystem(2, 'Ice cream')\niceCreamOrder.actualStateOfOrder()\niceCreamOrder.orderShipped()\niceCreamOrder.orderCancelled()\niceCreamOrder.actualStateOfOrder()\niceCreamOrder.orderDelivered()\niceCreamOrder.actualStateOfOrder()"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/typescript/victoriaparraf.ts",
    "content": "enum DiasDeLaSemana {\n    Lunes = 1,\n    Martes,\n    Miercoles,\n    Jueves,\n    Viernes,\n    Sabado,\n    Domingo\n}\n\nfunction obtenerNombreDelDia(dia: number): string {\n    switch (dia) {\n        case DiasDeLaSemana.Lunes:\n            return \"Lunes\";\n        case DiasDeLaSemana.Martes:\n            return \"Martes\";\n        case DiasDeLaSemana.Miercoles:\n            return \"Miércoles\";\n        case DiasDeLaSemana.Jueves:\n            return \"Jueves\";\n        case DiasDeLaSemana.Viernes:\n            return \"Viernes\";\n        case DiasDeLaSemana.Sabado:\n            return \"Sábado\";\n        case DiasDeLaSemana.Domingo:\n            return \"Domingo\";\n        default:\n            return \"Número de día inválido\";\n    }\n}\n\n// Prueba de la función\nconsole.log(obtenerNombreDelDia(1)); // \"Lunes\"\nconsole.log(obtenerNombreDelDia(5)); // \"Viernes\"\nconsole.log(obtenerNombreDelDia(7)); // \"Domingo\"\nconsole.log(obtenerNombreDelDia(8)); // \"Número de día inválido\"\n"
  },
  {
    "path": "Roadmap/19 - ENUMERACIONES/vb.net/kenysdev.vb",
    "content": "' ╔══════════════════════════════════════╗\n' ║ Autor:  Kenys Alvarado               ║\n' ║ GitHub: https://github.com/Kenysdev  ║\n' ║ 2024 -  VB.NET                       ║\n' ╚══════════════════════════════════════╝\n'-----------------------------------------------\n'* ENUMERACIONES\n'-----------------------------------------------\n' https://learn.microsoft.com/es-es/dotnet/visual-basic/language-reference/statements/enum-statement\n' https://learn.microsoft.com/es-es/dotnet/api/system.enum?view=net-8.0\n\nModule Program\n    '* EJERCICIO 1:\n    '* Empleando tu lenguaje, explora la definición del tipo de dato\n    '* que sirva para definir enumeraciones (Enum).\n    '* Crea un Enum que represente los días de la semana del lunes\n    '* al domingo, en ese orden. Con ese enumerado, crea una operación\n    '* que muestre el nombre del día de la semana dependiendo del número entero\n    '* utilizado (del 1 al 7).\n\n    Enum Weekday\n        MONDAY = 1\n        TUESDAY = 2\n        WEDNESDAY = 3\n        THURSDAY = 4\n        FRIDAY = 5\n        SATURDAY = 6\n        SUNDAY = 7\n    End Enum\n\n    Function GetDay(ByVal num As Integer) As String\n        Dim name As String = [Enum].GetName(GetType(Weekday), num)\n        If name IsNot Nothing Then\n            Return name\n        Else\n            Return \"'o'\"\n        End If\n    End Function\n\n    Function GetNumDay(ByVal day As String) As Integer\n        Dim weekday As Weekday\n        If [Enum].TryParse(day, weekday) Then\n            Return CType(weekday, Integer)\n        Else\n            Return 0\n        End If\n    End Function\n\n    '* EJERCICIO 2:\n    '* Crea un pequeño sistema de gestión del estado de pedidos.\n    '* Implementa una clase que defina un pedido con las siguientes características:\n    '* - El pedido tiene un identificador y un estado.\n    '* - El estado es un Enum con estos valores: PENDIENTE, ENVIADO, ENTREGADO y CANCELADO.\n    '* - Implementa las funciones que sirvan para modificar el estado:\n    '*   - Pedido enviado\n    '*   - Pedido cancelado\n    '*   - Pedido entregado\n    '*   (Establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...)\n    '* - Implementa una función para mostrar un texto descriptivo según el estado actual.\n    '* - Crea diferentes pedidos y muestra cómo se interactúa con ellos. \n\n    Enum Status\n        PENDING\n        SHIPPED\n        DELIVERED\n        CANCELED\n    End Enum\n\n    Class Order\n        Private _identifier As String\n        Private _status As Status = Status.PENDING\n\n        Public Sub New(ByVal identifier As String)\n            _identifier = identifier\n        End Sub\n\n        Public Sub Send()\n            Console.WriteLine(vbCrLf & \"Enviar:\")\n            If _status = Status.PENDING Then\n                _status = Status.SHIPPED\n                Console.WriteLine(Info())\n            Else\n                Invalid()\n            End If\n        End Sub\n\n        Public Sub Cancelled()\n            Console.WriteLine(vbCrLf & \"Cancelar:\")\n            If _status = Status.PENDING Then\n                _status = Status.CANCELED\n                Console.WriteLine(Info())\n            Else\n                Invalid()\n            End If\n        End Sub\n\n        Public Sub Delivered()\n            Console.WriteLine(vbCrLf & \"Entregar:\")\n            If _status = Status.SHIPPED Then\n                _status = Status.DELIVERED\n                Console.WriteLine(Info())\n            Else\n                Invalid()\n            End If\n        End Sub\n\n        Public Function Info() As String\n            Return $\"{_identifier} is {_status}\"\n        End Function\n\n        Private Sub Invalid()\n            Console.WriteLine($\"Invalid operation, {Info()}\")\n        End Sub\n\n    End Class\n\n    Sub Main()\n        ' _____________________________________\n        Console.WriteLine(GetDay(7))\n        Console.WriteLine(GetDay(3))\n        Console.WriteLine(GetDay(8))\n\n        Console.WriteLine(GetNumDay(\"TUESDAY\"))\n        Console.WriteLine(GetNumDay(\"FRIDAY\"))\n        Console.WriteLine(GetNumDay(\"abc\"))\n\n        ' _____________________________________\n        ' Creación de pedidos\n        Dim libro1 As New Order(\"libro1\")\n        Dim libro2 As New Order(\"libro2\")\n        Dim libro3 As New Order(\"libro3\")\n\n        ' Positivas\n        Console.WriteLine(vbCrLf & \"-----\")\n        Console.WriteLine(\"Operaciones exitosas:\" & vbCrLf & \"-----\")\n        libro1.Send()\n        libro1.Delivered()\n        libro2.Cancelled()\n\n        ' Negativas\n        Console.WriteLine(vbCrLf & \"-----\")\n        Console.WriteLine(\"Operaciones inválidas:\" & vbCrLf & \"-----\")\n        libro3.Delivered()\n        libro2.Cancelled()\n        libro1.Send()\n\n        ' Información\n        Console.WriteLine(vbCrLf & \"-----\")\n        Console.WriteLine(\"Estado de órdenes\" & vbCrLf & \"-----\")\n        Console.WriteLine(libro1.Info())\n        Console.WriteLine(libro2.Info())\n        Console.WriteLine(libro3.Info())\n    End Sub\n    \nEnd Module\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/bash/arturonavas.sh",
    "content": "#!/usr/bin/bash\n: '\n/*\n * EJERCICIO:\n * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n * una petición a la web que tú quieras, verifica que dicha petición\n * fue exitosa y muestra por consola el contenido de la web.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n * terminal al que le puedas solicitar información de un Pokémon concreto\n * utilizando su nombre o número.\n * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n * - Muestra el nombre de su cadena de evoluciones\n * - Muestra los juegos en los que aparece\n * - Controla posibles errores\n */\n'\n\n#imprimiendo el menu principal\n\nmenu() {\n    clear\n    echo \"-------------------------------------\"\n    echo \"1. obtener html de un sitio web\"\n    echo \"2. consultar informacion de pokemon\"\n    echo \"3. salir\"\n    echo \"-------------------------------------\"\n}\n\n\n#obneter html de una url\n\nobtener_html() {\n    read -p \"introduce la url: \" url\n    echo \"realizando peticion a $url...\"\n    codigo=$(curl -s -o /dev/null -w \"%{http_code}\" \"$url\")\n    \n    if [ \"$codigo\" -eq 200 ]; then #verificar que el protocolo http sea existoso\n        echo \"-------------------------------------\"\n        curl -s \"$url\" | head -n 15\n        echo \"recortando contenido...\"\n        echo \"-------------------------------------\"\n    else\n        echo \"error!!!! >.< codigo de estado: $codigo\"\n    fi\n    read -p \"presiona enter para continuar...\"\n}\n\n\n#obtener datos de pokemon con jq\n\npokemon_info() {\n    if ! command -v jq &> /dev/null; then\n        echo \"necesitas instalar jq para usar esta opcion!!\"\n        echo \"instala con: sudo apt install jq o sudo pacman -S jq ^_^\"\n        read -p \"presiona enter para continuar...\"\n        return\n    fi\n    \n    read -p \"nombre o numero del pokemon: \" pokemon\n    url=\"https://pokeapi.co/api/v2/pokemon/$pokemon\"\n    codigo=$(curl -s -o /dev/null -w \"%{http_code}\" \"$url\")\n    \n    if [ \"$codigo\" -ne 200 ]; then\n        echo \"pokemon no encontrado! :c\"\n        read -p \"presiona enter para continuar...\"\n        return\n    fi\n    \n    datos=$(curl -s \"$url\")\n    especie_url=$(curl -s \"$url\" | jq -r '.species.url')\n    cadena_evo=$(curl -s \"$especie_url\" | jq -r '.evolution_chain.url')\n    evoluciones=$(curl -s \"$cadena_evo\" | jq -r '.chain | recurse(.evolves_to[]) | .species.name')\n    \n    echo \"-------------------------------------\"\n    echo \"nombre:   $(echo \"$datos\" | jq -r '.name')\"\n    echo \"id:       $(echo \"$datos\" | jq -r '.id')\"\n    echo \"peso:     $(echo \"$datos\" | jq -r '.weight/10') kg\"  # Convertir a kg\n    echo \"altuar:   $(echo \"$datos\" | jq -r '.height/10') m\"   # Convertir a metros\n    echo \"tipos:    $(echo \"$datos\" | jq -r '.types[].type.name')\"\n    echo \"evoluciones: ${evoluciones%, }\"\n    echo \"-------------------------------------\"\n    read -p \"presiona enter para continuar...\"\n}\n\n\n# delarar el bucle principal\n\nwhile true; do\n    menu\n    read -p \"eilge una opcion: \" opcion\n    case $opcion in\n        1) obtener_html ;;\n        2) pokemon_info ;;\n        3) exit ;;\n        *) echo \"opcion no valida\" ;;\n    esac\ndone"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/bash/rantamhack.sh",
    "content": "#!/bin/bash\n\n\n# * EJERCICIO:\n# * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n# * una peticion a la web que tu quieras, verifica que dicha peticion\n# * fue exitosa y muestra por consola el contenido de la web.\n\necho -e \"\\n\\n=======================================EJERCICIO=======================================\\n\\n\"\n\n\nurl=\"https://github.com/mouredev\"\n\nresponse=$(curl -s -w \"%{http_code}\" -o response.txt \"$url\")\n\nif [ \"$response\" -eq 200 ]; then\n    echo -e \"\\nEl codigo de salida es 200\\n\"\n    cat -n response.txt | head -n25\nelse\n    echo \"Error: No se pudo realizar la peticion, codigo de respuesta: $response\"\nfi\n\n\nrm response.txt\n\n\n\n# * DIFICULTAD EXTRA (opcional):\n# * Utilizando la PokeAPI (https://pokeapi.co), crea un programa por\n# * terminal al que le puedas solicitar informacion de un Pokemon concreto\n# * utilizando su nombre o numero.\n# * - Muestra el nombre, id, peso, altura y tipo(s) del Pokemon\n# * - Muestra el nombre de su cadena de evoluciones\n# * - Muestra los juegos en los que aparece\n# * - Controla posibles errores\n\n\n\necho -e \"\\n\\n=======================================DIFICULTAD EXTRA=======================================\\n\\n\"\n\n\n\nread -p \"Escribe el identificador o el nombre del pokemon que quieras conocer (hay 1025 pokemon): \" pokemon\n\nfind_pokemon() {\n    local name_or_id=$1\n    local url=\"https://pokeapi.co/api/v2/pokemon/$name_or_id\"\n    \n    response=$(curl -s -w \"%{http_code}\" -o response.json \"$url\")\n    \n    if [ \"$response\" -eq 200 ]; then\n        name=$(jq -r '.name' response.json | tr '[:lower:]' '[:upper:]')\n        id=$(jq -r '.id' response.json)\n        weight=$(jq -r '.weight' response.json)\n        height=$(jq -r '.height' response.json)\n        types=$(jq -r '[.types[].type.name] | join(\", \")' response.json)\n        games=$(jq -r '[.game_indices[].version.name] | join(\", \")' response.json)\n        \n        echo \"=======================================\"\n        echo \"El pokemon elegido es: $name\"\n        echo \"El id del pokemon $name: es $id\"\n        echo \"El peso del pokemon $name: es $weight\"\n        echo \"La altura del pokemon $name: es $height\"\n        echo \"$name es un pokemon de tipo: $types\"\n        echo \"$name participa en los juegos: $games\"\n        echo \"=======================================\"\n    else\n        echo \"Error: No se pudo encontrar el pokemon, codigo de respuesta: $response\"\n    fi\n}\n\nfind_pokemon \"$pokemon\"\n\nrm response.json\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/c#/hequebo.cs",
    "content": "using System.Text.Json;\n\nclass Program\n{\n    static async Task Main(string[] args)\n    {\n        #region Http\n        // Peticiones Http\n        Console.WriteLine(\"---Peticiones HTTP---\");\n        /*\n         * En .Net existe la clase HttpClient la cual nos\n         * permite crear peticiones http de manera asíncrona.\n         * En su constructor podemos proporcionar la url a la \n         * cual queremos realizar la petición, cual usa la \n         * clase Uri y dentro del constructor la cadena de \n         * texto con la url\n         */\n        var httpClient = new HttpClient\n        {\n            BaseAddress = new Uri(\"https://jsonplaceholder.typicode.com/users\"),\n        };\n        Console.WriteLine(\"Utilizamos el metodo GET en para la siguiente url:\");\n        Console.WriteLine(httpClient.BaseAddress);\n        /*\n         * Utilizamos el método GetAsync(requestUri) para realizar\n         * la petición y guardamos el resultado en una variable de \n         * la clase HttpResponseMessage\n         */\n        var response = await httpClient.GetAsync(httpClient.BaseAddress);\n        /*\n         * Convertimos el resultado en un json\n         */\n        var jsonResponse = await response.Content.ReadAsStringAsync();\n        Console.WriteLine(\"Nos devuelve la siguiente información:\");\n        Thread.Sleep(1000);\n        Console.WriteLine(jsonResponse);\n        httpClient.Dispose();\n        #endregion\n\n        Console.ReadLine();\n        Console.Clear();\n\n        // Ejercicio extra\n        var httpClientPokemon = new HttpClient\n        {\n            BaseAddress = new Uri(\"https://pokeapi.co/api/v2/pokemon\"),\n        };\n        bool salir = false;\n        do\n        {\n            Menu();\n            int option = 0;\n            int.TryParse(Console.ReadLine(), out option);\n            switch (option)\n            {\n                case 1:\n                    await Search(httpClientPokemon);\n                    break;\n                case 2:\n                    Console.Clear();\n                    Console.WriteLine(\"Hasta la próxima...\");\n                    Thread.Sleep(1000);\n                    salir = true;\n                    break;\n                default:\n                    Console.WriteLine(\"Opción no válida...\");\n                    break;\n            }\n\n        } while (!salir);\n    }\n    static void Menu()\n    {\n        Console.WriteLine(\"---Pokedex---\");\n        Console.WriteLine(\"1.- Buscar por id o nombre\");\n        Console.WriteLine(\"2.- Salir\");\n        Console.WriteLine(\"Ingrese opción deseada...\");\n    }\n    static async Task Search(HttpClient httpClient)\n    {\n        Console.Clear();\n        Console.WriteLine(\"Ingresa id o nombre de pokemón a consultar\");\n        string search = Console.ReadLine();\n\n        var response = await httpClient.GetAsync($\"{httpClient.BaseAddress}/{search}\");\n        if (response.StatusCode != System.Net.HttpStatusCode.OK)\n        {\n            Console.WriteLine(\"Pokemon no encontrado...\");\n            return;\n        }\n\n        var body = await response.Content.ReadAsStringAsync();\n        var options = new JsonSerializerOptions\n        {\n            PropertyNameCaseInsensitive = true\n        };\n        /*\n         * Con el metodo Deserialize podemos mapear el contenido\n         * de la respuesta a una clase propia\n         */\n        var pokemon = JsonSerializer.Deserialize<Pokemon>(body, options);\n\n        Console.WriteLine($\"Id: {pokemon.Id}\");\n        Console.WriteLine($\"Nombre: {pokemon.Name}\");\n        Console.WriteLine($\"Peso: {pokemon.Weight}\");\n        Console.WriteLine($\"Altura: {pokemon.Height}\");\n        Console.WriteLine(\"Tipos:\");\n        foreach (var type in  pokemon.Types)\n            Console.WriteLine($\"{type.Slot}: {type.Type.Name}\");\n        Console.WriteLine(\"Juegos:\");\n        foreach (var game in pokemon.Game_Indices)\n            Console.WriteLine($\"{game.Version.Name}\");\n        Console.WriteLine();\n\n    }\n\n}\nclass Pokemon\n{\n    public int Id { get; set; }\n    public string Name { get; set; }\n    public decimal Weight { get; set; }\n    public decimal Height { get; set; }\n    public List<TypeInfo> Types { get; set; }\n    public List<GameInfo> Game_Indices { get; set; }\n}\nclass TypeInfo\n{\n    public int Slot {  get; set; }\n    public Type Type { get; set; }\n}\nclass Type\n{\n    public string Name { get; set; }\n}\nclass GameInfo\n{\n    public int Game_Index { get; set; }\n    public Version Version { get; set; }\n}\nclass Version\n{\n    public string Name { get; set; }\n}\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/c#/isaacus98.cs",
    "content": "﻿/*\n * EJERCICIO:\n * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n * una petición a la web que tú quieras, verifica que dicha petición\n * fue exitosa y muestra por consola el contenido de la web.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n * terminal al que le puedas solicitar información de un Pokémon concreto\n * utilizando su nombre o número.\n * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n * - Muestra el nombre de su cadena de evoluciones\n * - Muestra los juegos en los que aparece\n * - Controla posibles errores\n */\n\nnamespace Roadmap\n{\n    internal class Reto20\n    {\n\n        static async Task Main(string[] args)\n        {\n            HttpClient client = new HttpClient()\n            {\n                BaseAddress = new Uri(\"http://jsonplaceholder.typicode.com\")\n            };\n\n            await PeticionHttp(client);\n        }\n\n        private async static Task PeticionHttp(HttpClient client)\n        {\n            try\n            {\n                using HttpResponseMessage response = await client.GetAsync(\"Todos/1\");\n                response.EnsureSuccessStatusCode();\n                string jsonResponse = await response.Content.ReadAsStringAsync();\n                Console.WriteLine(jsonResponse);\n            }\n            catch (HttpRequestException ex)\n            {\n                Console.WriteLine(ex.Message);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/c#/jamerrq.cs",
    "content": "﻿/*\r\n * EJERCICIO:\r\n * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\r\n * una petición a la web que tú quieras, verifica que dicha petición\r\n * fue exitosa y muestra por consola el contenido de la web.\r\n *\r\n * DIFICULTAD EXTRA (opcional):\r\n * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\r\n * terminal al que le puedas solicitar información de un Pokémon concreto\r\n * utilizando su nombre o número.\r\n * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\r\n * - Muestra el nombre de su cadena de evoluciones\r\n * - Muestra los juegos en los que aparece\r\n * - Controla posibles errores\r\n */\r\n\r\nusing System;\r\n\r\nnamespace Roadmap20\r\n{\r\n    class HTTPRequest\r\n    {\r\n        static readonly HttpClient client = new HttpClient();\r\n        static void Main(string[] args)\r\n        {\r\n            // Llamada a la función que realiza la petición\r\n            string url = \"https://randomuser.me/api/\";\r\n\r\n            try\r\n            {\r\n                // Realizamos la petición\r\n                HttpResponseMessage response = client.GetAsync(url).Result;\r\n                response.EnsureSuccessStatusCode();\r\n\r\n                // Mostramos el contenido de la web\r\n                string responseBody = response.Content.ReadAsStringAsync().Result;\r\n                Console.WriteLine(responseBody);\r\n            }\r\n            catch (HttpRequestException e)\r\n            {\r\n                Console.WriteLine(\"\\nException Caught!\");\r\n                Console.WriteLine(\"Message :{0} \", e.Message);\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/c#/kenysdev.cs",
    "content": "/*\n╔══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado               ║\n║ GitHub: https://github.com/Kenysdev  ║\n║ 2024 -  C#                           ║\n╚══════════════════════════════════════╝\n------------------------------------------\n* PETICIONES HTTP\n------------------------------------------\n*/\n\nusing System.Text.Json;\n\n#pragma warning disable CA1050\nclass Program {\n    /*\n    * EJERCICIO:\n    * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n    * una petición a la web que tú quieras, verifica que dicha petición\n    * fue exitosa y muestra por consola el contenido de la web.\n    */\n    static readonly HttpClient client = new();\n\n    static async Task<Dictionary<string, object>> GetUser(int userId) {\n        try {\n            string url = $\"https://jsonplaceholder.typicode.com/users/{userId}\";\n            HttpResponseMessage response = await client.GetAsync(url);\n            \n            if (response.IsSuccessStatusCode) {\n                string json = await response.Content.ReadAsStringAsync();\n                return JsonSerializer.Deserialize<Dictionary<string, object>>(json);\n            } else {\n                Console.WriteLine($\"Id: {userId} No encontrado\");\n                Console.WriteLine(response.StatusCode);\n                return [];\n            }\n        }\n        catch (HttpRequestException) {\n            Console.WriteLine(\"Error de conexión\");\n            return [];\n        }\n    }\n\n    static void PrintUser(Dictionary<string, object> userData) {\n        if (userData.Count > 0) {\n            Console.WriteLine(\n                $\"Usuario con id: '{userData[\"id\"]}':\\n\" +\n                $\"Nombre:  {userData[\"name\"]}\\n\" +\n                $\"Usuario: {userData[\"username\"]}\\n\" +\n                $\"Email:   {userData[\"email\"]}\\n\" +\n                $\"Teléfono: {userData[\"phone\"]}\\n\"\n            );\n        }\n    }\n\n    static async Task Main() {\n        Console.WriteLine(\"\\nEJERCICIO #1:\\n\");\n\n        var u1 = await GetUser(1);\n        PrintUser(u1);\n\n        var u2 = await GetUser(2);\n        PrintUser(u2);\n\n        var u3 = await GetUser(777); // no existente\n        PrintUser(u3);\n\n        client.Dispose();\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/c++/hectorio23.cpp",
    "content": "// Autor: Héctor Adán \n// Github: https://github.com/hectorio23\n\n#include <iostream>\n#include <curl/curl.h>\n#include <json/json.h>  // Usamos la biblioteca JSON para manejar las respuestas JSON\n#include <sstream>\n\n// Callback function to handle the data returned by cURL\n// Función de callback para manejar los datos devueltos por cURL\nsize_t WriteCallback(void* contents, size_t size, size_t nmemb, std::string* s) {\n    s->append((char*)contents, size * nmemb);  // Añade los datos recibidos al buffer de la string\n    return size * nmemb;  // Devuelve el tamaño de los datos procesados\n}\n\n// Function to fetch data from a given URL\n// Función para obtener datos de una URL dada\nstd::string fetch_data(const std::string& url) {\n    // Puntero para la instancia de cURL\n    CURL* curl;  \n\n    // Código de resultado de la operación cURL\n    CURLcode res;  \n\n    // Buffer para almacenar la respuesta\n    std::string readBuffer;  \n\n    // Inicializa cURL\n    curl = curl_easy_init();  \n    if(curl) {\n        curl_easy_setopt(curl, CURLOPT_URL, url.c_str());  // Establece la URL objetivo\n        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);  // Define la función de callback\n        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);  // Define el buffer de destino para los datos\n        res = curl_easy_perform(curl);  // Realiza la petición HTTP\n        if(res != CURLE_OK) {\n            // Manejo de errores en caso de fallo en la petición HTTP\n            std::cerr << \"curl_easy_perform() failed: \" << curl_easy_strerror(res) << std::endl;\n        }\n        // Limpia la instancia de cURL\n        curl_easy_cleanup(curl);  \n    }\n    // Devuelve la respuesta \n    return readBuffer;  \n}\n\n// Function to print Pokémon details\n// Función para imprimir los detalles de un Pokémon\nvoid print_pokemon_details(const Json::Value& pokemon) {\n    std::cout << \"Name: \" << pokemon[\"name\"].asString() << std::endl;\n    std::cout << \"ID: \" << pokemon[\"id\"].asInt() << std::endl;\n    std::cout << \"Height: \" << pokemon[\"height\"].asInt() << std::endl;\n    std::cout << \"Weight: \" << pokemon[\"weight\"].asInt() << std::endl;\n\n    std::cout << \"Types: \";\n    for (const auto& type : pokemon[\"types\"]) {\n        std::cout << type[\"type\"][\"name\"].asString() << \" \";\n    }\n    std::cout << std::endl;\n\n    // Obtiene e imprime la cadena de evoluciones\n    std::string evolution_url = pokemon[\"species\"][\"url\"].asString();\n    std::string species_data = fetch_data(evolution_url);\n    Json::Value species_json;\n    std::stringstream(species_data) >> species_json;\n    std::string evolution_chain_url = species_json[\"evolution_chain\"][\"url\"].asString();\n    std::string evolution_data = fetch_data(evolution_chain_url);\n    Json::Value evolution_json;\n    std::stringstream(evolution_data) >> evolution_json;\n    \n    std::cout << \"Evolution Chain: \";\n    Json::Value current_evolution = evolution_json[\"chain\"];\n    while(!current_evolution.isNull()) {\n        std::cout << current_evolution[\"species\"][\"name\"].asString() << \" \";\n        current_evolution = current_evolution[\"evolves_to\"][0];\n    }\n    std::cout << std::endl;\n\n    // Imprime los juegos en los que aparece el Pokémon\n    std::cout << \"Games: \";\n    for (const auto& game : pokemon[\"game_indices\"]) {\n        std::cout << game[\"version\"][\"name\"].asString() << \" \";\n    }\n    std::cout << std::endl;\n}\n\nint main() {\n    // Primera parte: realizar una petición HTTP a un sitio web de ejemplo\n    // Puntero para la instancia de cURL\n    CURL* curl;  \n\n    // Código de resultado de la operación cURL\n    CURLcode res;  \n    \n    // Buffer para almacenar la respuesta\n    std::string readBuffer;  \n\n    // Inicializa cURL\n    curl = curl_easy_init();  \n    if(curl) {\n        curl_easy_setopt(curl, CURLOPT_URL, \"https://www.example.com\");  // Establece la URL objetivo\n        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);  // Define la función de callback\n        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);  // Define el buffer de destino para los datos\n        res = curl_easy_perform(curl);  // Realiza la petición HTTP\n        if(res != CURLE_OK) {\n            // Manejo de errores en caso de fallo en la petición HTTP\n            std::cerr << \"curl_easy_perform() failed: \" << curl_easy_strerror(res) << std::endl;\n        } else {\n            // Imprime la respuesta de la petición HTTP\n            std::cout << readBuffer << std::endl;\n        }\n        curl_easy_cleanup(curl);  // Limpia la instancia de cURL\n    }\n\n    // Segunda parte: interacción con la PokéAPI\n    std::string pokemon_name_or_id;  // Variable para almacenar el nombre o ID del Pokémon\n    std::cout << \"Enter the name or ID of the Pokémon: \";\n    std::cin >> pokemon_name_or_id;\n\n    std::string url = \"https://pokeapi.co/api/v2/pokemon/\" + pokemon_name_or_id;  // Construye la URL de la API\n    std::string data = fetch_data(url);  // Obtiene los datos de la API\n\n    Json::Value pokemon_json;  // Variable para almacenar los datos JSON del Pokémon\n    std::stringstream(data) >> pokemon_json;  // Convierte la respuesta en un objeto JSON\n\n    if(pokemon_json.isNull()) {\n        // Manejo de errores en caso de que la respuesta JSON sea nula\n        std::cerr << \"Error fetching Pokémon data. Please check the name or ID and try again.\" << std::endl;\n        return 1;  // Termina el programa con código de error\n    }\n\n    print_pokemon_details(pokemon_json);  // Imprime los detalles del Pokémon\n\n    return 0;  // Termina el programa exitosamente\n}\n\n// Instrucción para compilar el código: g++ -o pokeapi hectorio23.cpp -lcurl -ljsoncpp\n// Ejecucion: ./pokeapi\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/ejercicio.md",
    "content": "# #20 PETICIONES HTTP\n> #### Dificultad: Difícil | Publicación: 13/05/24 | Corrección: 20/05/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n * una petición a la web que tú quieras, verifica que dicha petición\n * fue exitosa y muestra por consola el contenido de la web.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n * terminal al que le puedas solicitar información de un Pokémon concreto\n * utilizando su nombre o número.\n * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n * - Muestra el nombre de su cadena de evoluciones\n * - Muestra los juegos en los que aparece\n * - Controla posibles errores\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/go/N0HagoNada.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"io/iota\"\n\t\"net/http\"\n)\n\nfunc main() {\n\t// URL de la web a la que haremos la petición\n\turl := \"https://www.example.com\"\n\n\t// Realizar la petición HTTP GET\n\tresponse, err := http.Get(url)\n\tif err != nil {\n\t\tfmt.Println(\"Error al realizar la petición:\", err)\n\t\treturn\n\t}\n\tdefer response.Body.Close()\n\n\t// Verificar si la petición fue exitosa\n\tif response.StatusCode == http.StatusOK {\n\t\t// Leer el contenido de la respuesta\n\t\tbody, err := iota.ReadAll(response.Body)\n\t\tif err != nil {\n\t\t\tfmt.Println(\"Error al leer la respuesta:\", err)\n\t\t\treturn\n\t\t}\n\n\t\t// Mostrar el contenido de la web por consola\n\t\tfmt.Println(string(body))\n\t} else {\n\t\tfmt.Printf(\"La petición no fue exitosa. Código de estado: %d\\n\", response.StatusCode)\n\t}\n}\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/go/edalmava.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\tresponse, err := http.Get(\"https://httpbin.org/get\")\n\n\tif err != nil {\n\t\tfmt.Println(\"Error al realizar la petición HTTP Get\")\n\t}\n\n\tdefer response.Body.Close()\n\n\tif response.StatusCode == 200 {\n\t\tbody, err := io.ReadAll(response.Body)\n\n\t\tif err != nil {\n\t\t\tfmt.Println(\"Error al leer el contenido del cuerpo de la petición\")\n\t\t}\n\n\t\tfmt.Println(string(body))\n\t}\n}\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/go/hozlucas28.go",
    "content": "package main\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"strings\"\n)\n\n/* -------------------------------------------------------------------------- */\n/*                                    TYPES                                   */\n/* -------------------------------------------------------------------------- */\n\n/* -------------------------------- Dog Fact -------------------------------- */\n\ntype Fact struct {\n\tId         string `json:\"id\"`\n\tType       string `json:\"type\"`\n\tAttributes struct {\n\t\tBody string `json:\"body\"`\n\t} `json:\"attributes\"`\n}\n\ntype DogFact struct {\n\tData []Fact `json:\"data\"`\n}\n\n/* --------------------------------- Pokemon -------------------------------- */\n\ntype GameIndex struct {\n\tGameIndex int `json:\"game_index\"`\n\tVersion   struct {\n\t\tName string `json:\"name\"`\n\t} `json:\"version\"`\n}\n\ntype Type struct {\n\tSlot int `json:\"slot\"`\n\tType struct {\n\t\tName string `json:\"name\"`\n\t} `json:\"type\"`\n}\n\ntype Pokemon struct {\n\tGameIndices []GameIndex `json:\"game_indices\"`\n\tHeight      int         `json:\"height\"`\n\tId          int         `json:\"id\"`\n\tName        string      `json:\"name\"`\n\tTypes       []Type      `json:\"types\"`\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                  FUNCTIONS                                 */\n/* -------------------------------------------------------------------------- */\n\nfunc getPokemon[Query int | string](query Query) (Pokemon, error) {\n\tvar pokemon Pokemon\n\n\tvar endPoint string = fmt.Sprintf(\"https://pokeapi.co/api/v2/pokemon/%v\", query)\n\n\tresponse, err := http.Get(endPoint)\n\tif err != nil {\n\t\treturn pokemon, err\n\t}\n\n\tif response.StatusCode == 200 {\n\t\tbody, err := io.ReadAll(response.Body)\n\t\tif err != nil {\n\t\t\treturn pokemon, err\n\t\t}\n\n\t\terr = json.Unmarshal(body, &pokemon)\n\t\tif err != nil {\n\t\t\treturn pokemon, err\n\t\t}\n\t} else {\n\t\treturn pokemon, errors.New(response.Status)\n\t}\n\n\treturn pokemon, nil\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\nfunc main() {\n\t/*\n\t\tHTTP request...\n\t*/\n\n\tfmt.Println(\"HTTP request...\")\n\n\tresponse, err := http.Get(\"https://dogapi.dog/api/v2/facts\")\n\tif err != nil {\n\t\tfmt.Printf(\"\\n%s\\n\", err.Error())\n\t}\n\n\tif response.StatusCode == 200 {\n\t\tstringifiedJson, err := io.ReadAll(response.Body)\n\t\tif err != nil {\n\t\t\tfmt.Printf(\"\\n%s\\n\", err.Error())\n\t\t}\n\n\t\tvar randomDogFact DogFact\n\t\terr = json.Unmarshal(stringifiedJson, &randomDogFact)\n\t\tif err != nil {\n\t\t\tfmt.Printf(\"\\n%s\\n\", err.Error())\n\t\t}\n\n\t\tfmt.Printf(\"\\nRandom dog fact: %s\\n\", randomDogFact.Data[0].Attributes.Body)\n\t} else {\n\t\tfmt.Printf(\"\\n%s\\n\", response.Status)\n\t}\n\n\tfmt.Println(\"\\n# ---------------------------------------------------------------------------------- #\")\n\n\t/*\n\t\tAdditional challenge...\n\t*/\n\n\tfmt.Println(\"\\nAdditional challenge...\")\n\n\tfmt.Println(\"\\nPokemon with id number five...\")\n\n\tfourthPokemon, err := getPokemon(4)\n\tif err != nil {\n\t\tfmt.Printf(\"\\n%s\\n\", err.Error())\n\t}\n\n\tvar fourthPokemonTypes string\n\tfor _, t := range fourthPokemon.Types {\n\t\tfourthPokemonTypes += \", \" + t.Type.Name\n\t}\n\tfourthPokemonTypes = strings.TrimLeft(fourthPokemonTypes, \", \")\n\n\tvar fourthPokemonGames string\n\tfor _, game := range fourthPokemon.GameIndices {\n\t\tfourthPokemonGames += \", \" + game.Version.Name\n\t}\n\tfourthPokemonGames = strings.TrimLeft(fourthPokemonGames, \", \")\n\n\tfmt.Printf(\"\\nid: %d\", fourthPokemon.Id)\n\tfmt.Printf(\"\\nname: %s\", fourthPokemon.Name)\n\tfmt.Printf(\"\\nheight: %d\", fourthPokemon.Height)\n\tfmt.Printf(\"\\ntypes: %s\", fourthPokemonTypes)\n\tfmt.Printf(\"\\ngames: %s\\n\", fourthPokemonGames)\n\n\tfmt.Println(\"\\nPokemon with 'Mew' name...\")\n\n\tmewPokemon, err := getPokemon(\"mew\")\n\tif err != nil {\n\t\tfmt.Printf(\"\\n%s\\n\", err.Error())\n\t}\n\n\tvar mewPokemonTypes string\n\tfor _, t := range mewPokemon.Types {\n\t\tmewPokemonTypes += \", \" + t.Type.Name\n\t}\n\tmewPokemonTypes = strings.TrimLeft(mewPokemonTypes, \", \")\n\n\tvar mewPokemonGames string\n\tfor _, game := range mewPokemon.GameIndices {\n\t\tmewPokemonGames += \", \" + game.Version.Name\n\t}\n\tmewPokemonGames = strings.TrimLeft(mewPokemonGames, \", \")\n\n\tfmt.Printf(\"\\nid: %d\", mewPokemon.Id)\n\tfmt.Printf(\"\\nname: %s\", mewPokemon.Name)\n\tfmt.Printf(\"\\nheight: %d\", mewPokemon.Height)\n\tfmt.Printf(\"\\ntypes: %s\", mewPokemonTypes)\n\tfmt.Printf(\"\\ngames: %s\\n\", mewPokemonGames)\n}\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/go/kodenook.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"log\"\n\t\"net/http\"\n)\n\nfunc main() {\n\tresp, err := http.Get(\"https://go.dev\")\n\tif err != nil {\n\t\tlog.Println(err)\n\t}\n\tdefer resp.Body.Close()\n\n\tbody, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\tlog.Println(err)\n\t}\n\n\tfmt.Println(string(body))\n}\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/go/qwik-zgheib.go",
    "content": "package main\n\nimport (\n\t\"bufio\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n)\n\nfunc fetchURL(url string) (string, error) {\n\tresp, err := http.Get(url)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tdefer func(Body io.ReadCloser) {\n\t\terr := Body.Close()\n\t\tif err != nil {\n\t\t\tfmt.Println(\"error closing response body:\", err)\n\t\t}\n\t}(resp.Body)\n\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn \"\", fmt.Errorf(\"error: status code %d\", resp.StatusCode)\n\t}\n\n\tbody, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn string(body), nil\n}\n\n// -- extra challenge --\ntype HTTPClient interface {\n\tDo(req *http.Request) (*http.Response, error)\n}\n\ntype PokeAPI struct {\n\tClient  HTTPClient\n\tBaseURL string\n}\n\ntype Pokemon struct {\n\tName   string `json:\"name\"`\n\tID     int    `json:\"id\"`\n\tHeight int    `json:\"height\"`\n\tWeight int    `json:\"weight\"`\n\tTypes  []Type `json:\"types\"`\n}\n\ntype Type struct {\n\tSlot int `json:\"slot\"`\n\tType struct {\n\t\tName string `json:\"name\"`\n\t} `json:\"type\"`\n}\n\ntype EvolutionChain struct {\n\tChain Chain `json:\"chain\"`\n}\n\ntype Chain struct {\n\tSpecies struct {\n\t\tName string `json:\"name\"`\n\t} `json:\"species\"`\n\tEvolvesTo []Chain `json:\"evolves_to\"`\n}\n\nfunc (api *PokeAPI) fetchPokemon(nameOrID string) (Pokemon, error) {\n\turl := fmt.Sprintf(\"%s/pokemon/%s\", api.BaseURL, nameOrID)\n\treq, err := http.NewRequest(\"GET\", url, nil)\n\tif err != nil {\n\t\treturn Pokemon{}, err\n\t}\n\n\tresp, err := api.Client.Do(req)\n\tif err != nil {\n\t\treturn Pokemon{}, err\n\t}\n\tdefer func(Body io.ReadCloser) {\n\t\terr := Body.Close()\n\t\tif err != nil {\n\t\t\tfmt.Println(\"error closing response body:\", err)\n\t\t}\n\t}(resp.Body)\n\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn Pokemon{}, fmt.Errorf(\"error: status code %d\", resp.StatusCode)\n\t}\n\n\tbody, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn Pokemon{}, err\n\t}\n\n\tvar pokemon Pokemon\n\terr = json.Unmarshal(body, &pokemon)\n\tif err != nil {\n\t\treturn Pokemon{}, err\n\t}\n\n\treturn pokemon, nil\n}\n\nfunc (api *PokeAPI) fetchEvolutionChain(url string) (EvolutionChain, error) {\n\treq, err := http.NewRequest(\"GET\", url, nil)\n\tif err != nil {\n\t\treturn EvolutionChain{}, err\n\t}\n\n\tresp, err := api.Client.Do(req)\n\tif err != nil {\n\t\treturn EvolutionChain{}, err\n\t}\n\tdefer func(Body io.ReadCloser) {\n\t\terr := Body.Close()\n\t\tif err != nil {\n\n\t\t}\n\t}(resp.Body)\n\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn EvolutionChain{}, fmt.Errorf(\"error: status code %d\", resp.StatusCode)\n\t}\n\n\tbody, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn EvolutionChain{}, err\n\t}\n\n\tvar chain EvolutionChain\n\terr = json.Unmarshal(body, &chain)\n\tif err != nil {\n\t\treturn EvolutionChain{}, err\n\t}\n\n\treturn chain, nil\n}\n\nfunc printPokemonDetails(pokemon Pokemon) {\n\tfmt.Printf(\"Name: %s\\n\", pokemon.Name)\n\tfmt.Printf(\"ID: %d\\n\", pokemon.ID)\n\tfmt.Printf(\"Height: %d\\n\", pokemon.Height)\n\tfmt.Printf(\"Weight: %d\\n\", pokemon.Weight)\n\tfmt.Printf(\"Types: \")\n\tfor _, t := range pokemon.Types {\n\t\tfmt.Printf(\"%s \", t.Type.Name)\n\t}\n\tfmt.Println()\n}\n\nfunc getEvolutionChain(chain Chain, names *[]string) {\n\t*names = append(*names, chain.Species.Name)\n\tfor _, evolve := range chain.EvolvesTo {\n\t\tgetEvolutionChain(evolve, names)\n\t}\n}\n\nfunc printEvolutionChain(chain Chain) {\n\tvar names []string\n\tgetEvolutionChain(chain, &names)\n\tfmt.Printf(\"Evolves: %s\\n\", strings.Join(names, \" - \"))\n}\n\nfunc isValidID(input string) bool {\n\tif input == \"\" {\n\t\treturn false\n\t}\n\n\tintValue, err := strconv.Atoi(input)\n\tif intValue <= 0 {\n\t\treturn false\n\t}\n\n\treturn err == nil\n}\n\nfunc main() {\n\turl := \"https://www.dota2.com/hero/legioncommander\"\n\tcontent, err := fetchURL(url)\n\tif err != nil {\n\t\tfmt.Println(\"err fetching URL:\", err)\n\t\treturn\n\t}\n\n\tfmt.Println(\"content of the URL:\", content)\n\n\t// -- extra challenge --\n\tclient := &http.Client{}\n\tapi := &PokeAPI{\n\t\tClient:  client,\n\t\tBaseURL: \"https://pokeapi.co/api/v2\",\n\t}\n\n\treader := bufio.NewReader(os.Stdin)\n\tvar pokemonNameOrID string\n\tfor {\n\t\tfmt.Print(\"Enter Pokémon number or name: \")\n\t\tinput, err := reader.ReadString('\\n')\n\t\tif err != nil {\n\t\t\tfmt.Println(\"Error reading input:\", err)\n\t\t\tcontinue\n\t\t}\n\n\t\tpokemonNameOrID = strings.TrimSpace(input)\n\t\tif isValidID(pokemonNameOrID) {\n\t\t\tbreak\n\t\t} else {\n\t\t\tfmt.Println(\"Invalid input. Please enter a positive integer or a valid Pokémon id.\")\n\t\t}\n\t}\n\n\tpokemon, err := api.fetchPokemon(pokemonNameOrID)\n\tif err != nil {\n\t\tfmt.Println(\"Error fetching Pokémon:\", err)\n\t\treturn\n\t}\n\n\tprintPokemonDetails(pokemon)\n\n\tevolutionChainURL := fmt.Sprintf(\"%s/evolution-chain/%d\", api.BaseURL, pokemon.ID)\n\tevolutionChain, err := api.fetchEvolutionChain(evolutionChainURL)\n\tif err != nil {\n\t\tfmt.Println(\"Error fetching evolution chain:\", err)\n\t\treturn\n\t}\n\n\tfmt.Println(\"Evolution Chain:\")\n\tprintEvolutionChain(evolutionChain.Chain)\n}\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/go/raynerpv2022.go",
    "content": "/*\n * EJERCICIO:\n * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n * una petición a la web que tú quieras, verifica que dicha petición\n * fue exitosa y muestra por consola el contenido de la web.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n * terminal al que le puedas solicitar información de un Pokémon concreto\n * utilizando su nombre o número.\n * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n * - Muestra el nombre de su cadena de evoluciones\n * - Muestra los juegos en los que aparece\n * - Controla posibles errores\n */\n\npackage main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\n\t\"net/http\"\n)\n\nfunc exercice(url string) {\n\tresp, err := http.Get(url)\n\n\tif err != nil {\n\n\t\tfmt.Printf(\"Error readinng web site %v\\n\", err)\n\t\treturn\n\t}\n\tdefer resp.Body.Close()\n\tdata, err := io.ReadAll(resp.Body)\n\n\tif err != nil {\n\t\tfmt.Printf(\"Error readinng data %v\", err)\n\t}\n\tif resp.StatusCode == 200 {\n\t\tfmt.Println(\"Conexion Exitosa. Code :\", resp.StatusCode)\n\t}\n\tfmt.Println(string(data))\n\n}\n\nfunc getPokeUrl(url string) *http.Response {\n\tresponse, e := http.Get(url)\n\n\tif e != nil {\n\n\t\tfmt.Printf(\"Error de Red %v \\n\", e)\n\t\treturn nil\n\t}\n\n\tif response.StatusCode == http.StatusNotFound {\n\t\tfmt.Println(\"Pokemmon no encontrado \")\n\t\treturn nil\n\t}\n\n\treturn response\n}\n\nfunc extra() {\n\n\tvar PokemonName string\n\tfmt.Println(\"Nombre o NUmero del Pokemon \")\n\tfmt.Scanln(&PokemonName)\n\turl := fmt.Sprintf(\"https://pokeapi.co/api/v2/pokemon/%v\", PokemonName)\n\tfmt.Println(url)\n\n\tresponse := getPokeUrl(url)\n\tif response == nil {\n\t\treturn\n\t}\n\t// response, e := http.Get(url)\n\n\t// if e != nil {\n\n\t// \tfmt.Printf(\"Error de Red %v \\n\", e)\n\t// \treturn\n\t// }\n\n\t// if response.StatusCode == http.StatusNotFound {\n\t// \tfmt.Println(\"Pokemmon no encontrado \")\n\t// \treturn\n\t// }\n\n\tdefer response.Body.Close()\n\n\tdata, e := io.ReadAll(response.Body)\n\tif e != nil {\n\t\tfmt.Printf(\"Error reading Data %v \\n\", e)\n\t\treturn\n\t}\n\n\tvar poke Pokemon\n\te = json.Unmarshal(data, &poke)\n\tif e != nil {\n\t\tfmt.Printf(\"Error json data %v\\n\", e)\n\t\treturn\n\t}\n\n\tfmt.Printf(\"Name : %v\\t\", poke.Name)\n\tfmt.Printf(\"ID : %v\\t\", poke.Id)\n\tfmt.Printf(\"Weight : %v\\t\", poke.Weight)\n\tfmt.Printf(\"Height : %v\\t\\n\", poke.Height)\n\n\tfmt.Println(\"tIpOs\")\n\n\tfor _, v := range poke.Types {\n\t\tfmt.Printf(\"  \\t Name %v  URL %v  \\n\", v.Type.Name, v.Type.Url)\n\n\t}\n\tfmt.Println(\"Games\")\n\tfor _, v := range poke.GameIndices {\n\t\tfmt.Printf(\"  \\t Index %v  Name %v URL %v  \\n\", v.GameIndex, v.Version.Name, v.Version.Url)\n\t}\n\n\tspecie_url := fmt.Sprintf(\"https://pokeapi.co/api/v2/pokemon-species//%v\", PokemonName)\n\n\tRespspecie := getPokeUrl(specie_url)\n\n\tif Respspecie == nil {\n\n\t\treturn\n\t}\n\n\tdefer Respspecie.Body.Close()\n\n\tdata, e = io.ReadAll(Respspecie.Body)\n\n\tif e != nil {\n\t\tfmt.Printf(\"Error reading Data %v \\n\", e)\n\t\treturn\n\t}\n\n\tvar evolutionChain EvolutionChainUrl\n\te = json.Unmarshal(data, &evolutionChain)\n\tif e != nil {\n\t\tfmt.Printf(\"Error json data %v\\n\", e)\n\t\treturn\n\t}\n\n\tfmt.Println(\"URL\", evolutionChain.Evolution_chain.Url)\n\n\tevolution_chain := getPokeUrl(evolutionChain.Evolution_chain.Url)\n\tif evolution_chain == nil {\n\n\t\treturn\n\t}\n\tdefer evolution_chain.Body.Close()\n\n\tvar evolution_to eEvo\n\trespEvolutio_to, _ := io.ReadAll(evolution_chain.Body)\n\t_ = json.Unmarshal(respEvolutio_to, &evolution_to)\n\n\tfmt.Println(\"EStado Original : \", evolution_to.Chain.Species.Name)\n\tfmt.Println(\"Cadena de Evolution: \")\n\tprintEvo(evolution_to.Chain)\n\n}\n\nfunc printEvo(dd Ggg) {\n\n\tfor _, evo := range dd.Evolve_to {\n\t\tprintEvo(evo)\n\t\tfmt.Println(evo.Species.Name)\n\n\t}\n\n}\n\nfunc GetPokemon(url string) *http.Response {\n\tresponse, e := http.Get(url)\n\n\tif e != nil {\n\n\t\tfmt.Printf(\"Error de Red %v \\n\", e)\n\t\treturn nil\n\t}\n\n\tif response.StatusCode == http.StatusNotFound {\n\t\tfmt.Println(\"Pokemmon no encontrado \")\n\t\treturn nil\n\t}\n\n\tdefer response.Body.Close()\n\treturn response\n\n}\n\ntype eEvo struct {\n\tChain Ggg `json:\"chain\"`\n}\n\ntype Ggg struct {\n\tEvolve_to []Ggg `json:\"evolves_to\"`\n\n\tSpecies struct {\n\t\tName string `json:\"name\"`\n\t} `json:\"species\"`\n}\n\ntype EvolutionChainUrl struct {\n\tEvolution_chain struct {\n\t\tUrl string `json:\"url\"`\n\t} `json:\"evolution_chain\"`\n}\n\ntype Pokemon struct {\n\tId     int    `json:\"id\"`\n\tName   string `json:\"name\"`\n\tWeight int    `json:\"weight\"`\n\tHeight int    `json:\"height\"`\n\n\tGameIndices []struct {\n\t\tGameIndex int `json:\"game_index\"`\n\t\tVersion   struct {\n\t\t\tName string `json:\"name\"`\n\t\t\tUrl  string `json:\"url\"`\n\t\t} `json:\"version\"`\n\t} `json:\"game_indices\"`\n\n\tTypes []struct {\n\t\tSlot int `json:\"slot\"`\n\t\tType struct {\n\t\t\tName string `json:\"name\"`\n\t\t\tUrl  string `json:\"url\"`\n\t\t} `json:\"type\"`\n\t} `json:\"types\"`\n}\n\nfunc main() {\n\t// exercice(\"https://mouredev.pro\")\n\textra()\n}\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/go/thegera4.go",
    "content": " package main\n\n import (\n\t\"fmt\"\n\t\"net/http\"\n\t\"io\"\n\t\"encoding/json\"\n\t\"os\"\n)\n\n// Estructura para almacenar los datos del Pokémon de acuerdo a lo solicitado en la descripcion del ejercicio extra\ntype PokemonData struct {\n\tID     int    `json:\"id\"`\n\tName   string `json:\"name\"`\n\tWeight int    `json:\"weight\"`\n\tHeight int    `json:\"height\"`\n\tTypes  []struct {\n\t\tType struct {\n\t\t\tName string `json:\"name\"`\n\t\t} `json:\"type\"`\n\t} `json:\"types\"`\n\tForms []struct {\n\t\tName string `json:\"name\"`\n\t} `json:\"forms\"`\n\tGames []struct {\n\t\tVersion struct {\n\t\t\tName string `json:\"name\"`\n\t\t} `json:\"version\"`\n\t} `json:\"game_indices\"`\n}\n\nfunc main() {\n\n\t// Ejercicio: Petición HTTP\n\tresponse, err := http.Get(\"https://jsonplaceholder.typicode.com/posts\")\n\tif err != nil {\n\t\tfmt.Println(\"Error making request\")\n\t\tos.Exit(1)\n\t}\n\t\n\tdefer response.Body.Close() // Se debe cerrar el body al finalizar la ejecución\n\n\tbody, err := io.ReadAll(response.Body)\n\tif err != nil {\n\t\tfmt.Println(\"Error reading body\")\n\t\tos.Exit(1)\n\t}\n\n\tfmt.Println(string(body))\n\n\t// Ejercicio Extra\n\tpokeApi()\n\n}\n\nfunc pokeApi() {\n\tfor {\n\t\tfmt.Println(\"Introduce el nombre o número de un Pokémon o pulsa la tecla 'c + enter' para salir:\")\n\t\tvar pokemon string\n\t\tfmt.Scanln(&pokemon)\n\n\t\tif pokemon == \"c\" { break }\n\t\n\t\tpokemonData, err := getPokemon(pokemon)\n\t\tif err != nil {\n\t\t\tfmt.Println(\"Error while getting Pokémon data\")\n\t\t\tcontinue\n\t\t}\n\n\t\tprintPokemonData(pokemonData)\n\t}\n}\n\nfunc getPokemon(pokemon string) (PokemonData, error) {\n\tresponse, err := http.Get(\"https://pokeapi.co/api/v2/pokemon/\" + pokemon)\n\tif err != nil {\n\t\tfmt.Println(\"Error making request\")\n\t\treturn PokemonData{}, err\n\t}\n\t\n\tdefer response.Body.Close() // Se debe cerrar el body al finalizar la ejecución\n\n\tbody, err := io.ReadAll(response.Body)\n\tif err != nil {\n\t\tfmt.Println(\"Error reading body\")\n\t\treturn PokemonData{}, err\n\t}\n\n\tvar pokemonData PokemonData\n\terr = json.Unmarshal(body, &pokemonData)\n\tif err != nil {\n\t\tfmt.Println(\"Error unmarshalling body\")\n\t\treturn PokemonData{}, err\n\t}\n\n\treturn pokemonData, nil\n}\n\nfunc printPokemonData (pokemonData PokemonData) {\n\tfmt.Printf(\"ID: %d\\n\", pokemonData.ID)\n\tfmt.Printf(\"Nombre: %s\\n\", pokemonData.Name)\n\tfmt.Printf(\"Peso: %d\\n\", pokemonData.Weight)\n\tfmt.Printf(\"Altura: %d\\n\", pokemonData.Height)\n\n\tfmt.Printf(\"Tipos: \")\n\tfor i, t := range pokemonData.Types {\n\t\tif i > 0 {\n\t\t\tfmt.Print(\", \")\n\t\t}\n\t\tfmt.Print(t.Type.Name)\n\t}\n\tfmt.Println()\n\n\tfmt.Printf(\"Cadena de evoluciones: \")\n\tfor i, f := range pokemonData.Forms {\n\t\tif i > 0 {\n\t\t\tfmt.Print(\", \")\n\t\t}\n\t\tfmt.Print(f.Name)\n\t}\n\tfmt.Println()\n\n\tfmt.Printf(\"Juegos en que aparece:\")\n\tfor i, g := range pokemonData.Games {\n\t\tif i > 0 {\n\t\t\tfmt.Print(\", \")\n\t\t}\n\t\tfmt.Print(g.Version.Name)\n\t}\n\tfmt.Println()\n}"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/java/Abel-ADE.java",
    "content": "/*\n   <dependencies>\n        <dependency>\n            <groupId>com.google.code.gson</groupId>\n            <artifactId>gson</artifactId>\n            <version>2.10.1</version>\n        </dependency>\n    </dependencies>\n*/\n\nimport com.google.gson.Gson;\nimport com.google.gson.JsonArray;\nimport com.google.gson.JsonElement;\nimport com.google.gson.JsonObject;\n\nimport java.io.IOException;\nimport java.net.HttpURLConnection;\nimport java.net.URL;\nimport java.util.ArrayList;\nimport java.util.Scanner;\n\npublic class Main {\n    public final static ArrayList<String> nameEvolves = new ArrayList<>();\n\n    public static void getEvolve(JsonObject json){\n        String nameEvolve = json.getAsJsonObject(\"species\").get(\"name\").getAsString();\n        nameEvolves.add(nameEvolve);\n\n        JsonArray evolves = json.getAsJsonArray(\"evolves_to\");\n        if(evolves.size() > 0){\n            getEvolve(evolves.get(0).getAsJsonObject());\n        }\n    }\n\n    public static void main(String[] args) {\n        try {\n            System.out.println(\"Primera petición HTTP\");\n\n            //Establecemos la conexón con la web\n            URL url = new URL(\"https://holamundo.day/\");\n            HttpURLConnection connection = (HttpURLConnection) url.openConnection();\n            connection.setRequestMethod(\"GET\");\n            connection.connect();\n\n            //Recuperamos el código de respuesta\n            int code = connection.getResponseCode();\n            System.out.println(\"Resultado: \" + code);\n\n            //Leo el contenido de la web y lo guardo en una variable\n            Scanner scanner = new Scanner(connection.getInputStream());\n            StringBuilder html = new StringBuilder(\"\");\n            while (scanner.hasNextLine()) {\n                html.append(scanner.nextLine());\n            }\n            scanner.close();\n\n            //Si la petición fue exitosa\n            if (code == 200) {\n                //Imprimo por consola el contenido de la web\n                System.out.println(\"Contenido de la web: \");\n                System.out.println(html);\n            }\n\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n\n        /*DIFICULTAD EXTRA*/\n        try {\n            System.out.println(\"Poke api: \");\n\n            System.out.print(\"Introduce el nombre o id de un Pokemon: \");\n            Scanner scanner = new Scanner(System.in);\n            String nombre = scanner.nextLine();\n            System.out.println();\n\n            //Establecemos la conexón con la web\n            URL url = new URL(\"https://pokeapi.co/api/v2/pokemon/\" + nombre);\n            HttpURLConnection connection = (HttpURLConnection) url.openConnection();\n            connection.setRequestMethod(\"GET\");\n            connection.connect();\n            int code = connection.getResponseCode();\n\n            //Leo el contenido y lo guardo en una variable\n            scanner = new Scanner(connection.getInputStream());\n            StringBuilder json = new StringBuilder(\"\");\n            while (scanner.hasNextLine()) {\n                json.append(scanner.nextLine());\n            }\n\n            //Si la petición fue exitosa\n            if (code == 200) {\n                //Imprimo por consola el contenido\n                Gson gson = new Gson();\n                JsonObject data = gson.fromJson(json.toString(), JsonObject.class);\n\n                String name = data.get(\"name\").getAsString();\n                int id = data.get(\"id\").getAsInt();\n                int weight = data.get(\"weight\").getAsInt();\n                int height = data.get(\"height\").getAsInt();\n\n                ArrayList<String> nameGames = new ArrayList<>();\n                JsonArray games = data.getAsJsonArray(\"game_indices\");\n                for (int i = 0; i < games.size(); i++) {\n                    JsonObject game = games.get(i).getAsJsonObject();\n                    String nameGame = game.getAsJsonObject(\"version\").get(\"name\").getAsString();\n                    nameGames.add(nameGame);\n                }\n\n                ArrayList<String> nameTypes = new ArrayList();\n                JsonArray types = data.getAsJsonArray(\"types\");\n                for (JsonElement element : types) {\n                    String nameType = element.getAsJsonObject().getAsJsonObject(\"type\").get(\"name\").getAsString();\n                    nameTypes.add(nameType);\n                }\n\n                //Establecemos conexión para recuperar evoluciones\n                url = new URL(\"https://pokeapi.co/api/v2/pokemon-species/\"+id);\n                connection = (HttpURLConnection) url.openConnection();\n                connection.setRequestMethod(\"GET\");\n                connection.connect();\n                code = connection.getResponseCode();\n\n                //Leo el contenido y lo guardo en una variable\n                scanner = new Scanner(connection.getInputStream());\n                StringBuilder jsonSpecies = new StringBuilder(\"\");\n                while (scanner.hasNextLine()) {\n                    jsonSpecies.append(scanner.nextLine());\n                }\n\n                //Si la petición fue exitosa\n                if (code == 200) {\n                    JsonObject dataSpecies = gson.fromJson(jsonSpecies.toString(), JsonObject.class);\n                    url = new URL(dataSpecies.getAsJsonObject(\"evolution_chain\").get(\"url\").getAsString());\n                    connection = (HttpURLConnection) url.openConnection();\n                    connection.setRequestMethod(\"GET\");\n                    connection.connect();\n                    code = connection.getResponseCode();\n\n                    //Leo el contenido y lo guardo en una variable\n                    scanner = new Scanner(connection.getInputStream());\n                    StringBuilder jsonEvolves = new StringBuilder(\"\");\n                    while (scanner.hasNextLine()) {\n                        jsonEvolves.append(scanner.nextLine());\n                    }\n\n                    //Si la petición fue exitosa\n                    if (code == 200) {\n                        JsonObject dataEvolves = gson.fromJson(jsonEvolves.toString(), JsonObject.class);\n                        getEvolve(dataEvolves.getAsJsonObject(\"chain\"));\n                    }\n                }\n\n                //Mostramos todos los datos del pokemon\n                System.out.println(\"Datos de la pokeApi: \");\n                System.out.println(\"Name: \" + name);\n                System.out.println(\"Id: \" + id);\n                System.out.println(\"Weight: \" + weight);\n                System.out.println(\"Height: \" + height);\n                System.out.println(\"Types: \" + nameTypes);\n                System.out.println(\"Evolutions: \" + nameEvolves);\n                System.out.println(\"Games: \" + nameGames);\n            }\n\n            //Cerramos los recursos\n            scanner.close();\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/java/AmadorQuispe.java",
    "content": "/* ╔══════════════════════════════════════╗\n   ║ Autor:  Amador Q                     ║\n   ║ Web  : https://amsoft.dev            ║\n   ║ 2024                                 ║\n   ╚══════════════════════════════════════╝\n*/\n\n\n/*\n<dependency>\n\t<groupId>com.google.code.gson</groupId>\n\t<artifactId>gson</artifactId>\n\t<version>2.10.1</version>\n</dependency>\n*/\n\nimport com.google.gson.Gson;\nimport com.google.gson.JsonArray;\nimport com.google.gson.JsonObject;\n\nimport javax.net.ssl.HttpsURLConnection;\nimport java.io.BufferedReader;\nimport java.io.IOException;\nimport java.io.InputStreamReader;\nimport java.net.URL;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Scanner;\n\npublic class Roadmap {\n\n    public static void main(String[] args) {\n        //EJERCICIO\n        try {\n            getWeb(\"https://amsoft.dev\");\n        }catch (IOException e){\n            System.out.println(e.getMessage());\n        }\n        //EXTRA\n        Scanner sc = new Scanner(System.in);\n        System.out.println(\"====CONSULTA DE POKEMON====\");\n        System.out.print(\"Ingresa el id o nombre del pokemon :\");\n        String idPokemon = sc.nextLine();\n        try {\n            getPokemon(idPokemon);\n        } catch (Exception e) {\n            System.out.println(e.getMessage());;\n        }\n        sc.close();\n    }\n\n    public static void getWeb(String web) throws IOException {\n        URL url = new URL(web);\n        HttpsURLConnection con = (HttpsURLConnection) url.openConnection();\n        con.setRequestMethod(\"GET\");\n        int status = con.getResponseCode();\n        if (status == 200) {\n            try (BufferedReader in = new BufferedReader(\n                    new InputStreamReader(con.getInputStream()))) {\n                String inputLine;\n                StringBuffer content = new StringBuffer();\n                while ((inputLine = in.readLine()) != null) {\n                    content.append(inputLine);\n                }\n                System.out.println(\"====CONTENIDO DE LA WEB=====\");\n                System.out.println(content);\n            }\n        }\n        con.disconnect();\n    }\n\n    public static void getPokemon(String idPokemon) throws Exception {\n        String urlPoke = String.format(\"https://pokeapi.co/api/v2/pokemon/%s\", idPokemon);\n        URL url = new URL(urlPoke);\n        HttpsURLConnection con = (HttpsURLConnection) url.openConnection();\n        con.setRequestMethod(\"GET\");\n        Gson gson = new Gson();\n        try (BufferedReader in = new BufferedReader(\n                new InputStreamReader(con.getInputStream()))) {\n            String inputLine;\n            StringBuilder content = new StringBuilder();\n            while ((inputLine = in.readLine()) != null) {\n                content.append(inputLine);\n            }\n            JsonObject data = gson.fromJson(content.toString(), JsonObject.class);\n\n            String id = data.get(\"id\").getAsString();\n            String name = data.get(\"name\").getAsString();\n            String weight = data.get(\"weight\").getAsString();\n            String height = data.get(\"height\").getAsString();\n\n            var types = data.getAsJsonArray(\"types\");\n            var games = data.getAsJsonArray(\"game_indices\");\n            System.out.println(\"Datos del pokemon\");\n\n            System.out.println(\"id :\" + id);\n            System.out.println(\"name :\" + name);\n            System.out.println(\"weight :\" + weight);\n            System.out.println(\"height :\" + height);\n            System.out.print(\"Tipos : \");\n            List<String> typesPrint = new ArrayList<>();\n            types.forEach(\n                    p -> typesPrint.add(p.getAsJsonObject().get(\"type\").getAsJsonObject().get(\"name\").getAsString())\n            );\n            System.out.println(typesPrint);\n            System.out.print(\"Juegos : \");\n            List<String> gamesPrint = new ArrayList<>();\n            games.forEach(\n                    g -> gamesPrint.add(g.getAsJsonObject().get(\"version\").getAsJsonObject().get(\"name\").getAsString())\n            );\n            System.out.println(gamesPrint);\n\n            String evolutions = getEvolutionChains(idPokemon);\n            System.out.print(\"Evoluciones : \");\n            System.out.println(evolutions);\n\n\n        }\n\n    }\n\n\n\n    public static String getEvolutionChains(String idPokemon) throws Exception {\n        String urlEvolutionChain = getUrlEvolutionChain(idPokemon);\n        URL url = new URL(urlEvolutionChain);\n        HttpsURLConnection con = (HttpsURLConnection) url.openConnection();\n        con.setRequestMethod(\"GET\");\n        int status = con.getResponseCode();\n        if(status==200){\n            Gson gson = new Gson();\n            BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()));\n            String input = br.readLine();\n            JsonObject data = gson.fromJson(input, JsonObject.class);\n            var chain = data.getAsJsonObject(\"chain\");\n            StringBuilder evolutionNames = new StringBuilder();\n            String chainName = chain.getAsJsonObject(\"species\").get(\"name\").getAsString();\n            evolutionNames.append(chainName);\n            return chainFormat(chain,evolutionNames).toString();\n        }else {\n            throw new Exception(\"Respuesta diferente de OK\");\n        }\n    }\n\n    public static String getUrlEvolutionChain(String idPokemon) throws IOException, Exception{\n        String urlSpecies = String.format(\"https://pokeapi.co/api/v2/pokemon-species/%s\",idPokemon);\n        URL url = new URL(urlSpecies);\n        HttpsURLConnection con = (HttpsURLConnection) url.openConnection();\n        con.setRequestMethod(\"GET\");\n        int status = con.getResponseCode();\n        if (status==200){\n            Gson gson = new Gson();\n            BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()));\n            String input = br.readLine();\n            JsonObject data = gson.fromJson(input, JsonObject.class);\n            String evolutionChainUrl = data.getAsJsonObject(\"evolution_chain\").get(\"url\").getAsString();\n            br.close();\n            return  evolutionChainUrl;\n        }else {\n            throw new Exception(\"Respuesta diferente de OK\");\n        }\n    }\n\n    public static StringBuilder chainFormat(JsonObject chain, StringBuilder evolutionNames) {\n        evolutionNames.append(\"-> \");\n        JsonArray evolvesToArray = chain.get(\"evolves_to\").getAsJsonArray();\n        for (int i = 0; i < evolvesToArray.size(); i++) {\n            JsonObject evolution = evolvesToArray.get(i).getAsJsonObject();\n            evolutionNames.append(evolution.get(\"species\").getAsJsonObject().get(\"name\").getAsString());\n\n            if (i < evolvesToArray.size() - 1) {\n                evolutionNames.append(\", \");\n            }\n\n            if (!evolution.get(\"evolves_to\").getAsJsonArray().isEmpty()) {\n                chainFormat(evolution, evolutionNames);\n            }\n        }\n        return evolutionNames;\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/java/AnaLauDB.java",
    "content": "import java.io.BufferedReader;\nimport java.io.InputStreamReader;\nimport java.net.HttpURLConnection;\nimport java.net.URL;\nimport java.util.Scanner;\nimport org.json.*;\n\npublic class AnaLauDB {\n    // Realiza una petición HTTP GET y devuelve el contenido como String\n    public static String httpGet(String urlStr) throws Exception {\n        URL url = new URL(urlStr);\n        HttpURLConnection con = (HttpURLConnection) url.openConnection();\n        con.setRequestMethod(\"GET\");\n        int status = con.getResponseCode();\n        if (status != 200) {\n            throw new Exception(\"Error en la petición. Código: \" + status);\n        }\n        BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));\n        String inputLine;\n        StringBuilder content = new StringBuilder();\n        while ((inputLine = in.readLine()) != null) {\n            content.append(inputLine);\n        }\n        in.close();\n        con.disconnect();\n        return content.toString();\n    }\n\n    public static void main(String[] args) {\n        // Ejemplo simple: petición a una web\n        try {\n            String contenido = httpGet(\"https://pokeapi.co/api/v2/pokemon/ditto\");\n            System.out.println(\"Petición exitosa. Contenido de la web:\");\n            System.out.println(contenido.substring(0, Math.min(500, contenido.length())) + \"...\");\n        } catch (Exception e) {\n            System.out.println(\"Error: \" + e.getMessage());\n        }\n\n        // DIFICULTAD EXTRA: Consulta a la PokéAPI\n        Scanner sc = new Scanner(System.in);\n        System.out.print(\"\\nIntroduce el nombre o número de un Pokémon: \");\n        String poke = sc.nextLine().trim().toLowerCase();\n\n        try {\n            // 1. Datos básicos del Pokémon\n            String pokeJson = httpGet(\"https://pokeapi.co/api/v2/pokemon/\" + poke);\n            JSONObject pokeObj = new JSONObject(pokeJson);\n\n            String nombre = pokeObj.getString(\"name\");\n            int id = pokeObj.getInt(\"id\");\n            int peso = pokeObj.getInt(\"weight\");\n            int altura = pokeObj.getInt(\"height\");\n\n            // Tipos\n            JSONArray tiposArr = pokeObj.getJSONArray(\"types\");\n            StringBuilder tipos = new StringBuilder();\n            for (int i = 0; i < tiposArr.length(); i++) {\n                tipos.append(tiposArr.getJSONObject(i).getJSONObject(\"type\").getString(\"name\"));\n                if (i < tiposArr.length() - 1)\n                    tipos.append(\", \");\n            }\n\n            // Juegos\n            JSONArray juegosArr = pokeObj.getJSONArray(\"game_indices\");\n            StringBuilder juegos = new StringBuilder();\n            for (int i = 0; i < juegosArr.length(); i++) {\n                String juego = juegosArr.getJSONObject(i).getJSONObject(\"version\").getString(\"name\");\n                if (juegos.indexOf(juego) == -1) { // Evitar duplicados\n                    juegos.append(juego);\n                    if (i < juegosArr.length() - 1)\n                        juegos.append(\", \");\n                }\n            }\n\n            // Cadena de evolución\n            String especieUrl = pokeObj.getJSONObject(\"species\").getString(\"url\");\n            String especieJson = httpGet(especieUrl);\n            JSONObject especieObj = new JSONObject(especieJson);\n            String evoUrl = especieObj.getJSONObject(\"evolution_chain\").getString(\"url\");\n            String evoJson = httpGet(evoUrl);\n            JSONObject evoObj = new JSONObject(evoJson);\n\n            // Obtener nombres de la cadena de evolución\n            StringBuilder cadenaEvo = new StringBuilder();\n            JSONObject chain = evoObj.getJSONObject(\"chain\");\n            while (chain != null) {\n                cadenaEvo.append(chain.getJSONObject(\"species\").getString(\"name\"));\n                JSONArray evoluciones = chain.getJSONArray(\"evolves_to\");\n                if (evoluciones.length() > 0) {\n                    cadenaEvo.append(\" -> \");\n                    chain = evoluciones.getJSONObject(0);\n                } else {\n                    break;\n                }\n            }\n\n            // Mostrar resultados\n            System.out.println(\"\\n--- Información de Pokémon ---\");\n            System.out.println(\"Nombre: \" + nombre);\n            System.out.println(\"ID: \" + id);\n            System.out.println(\"Peso: \" + peso);\n            System.out.println(\"Altura: \" + altura);\n            System.out.println(\"Tipo(s): \" + tipos);\n            System.out.println(\"Cadena de evolución: \" + cadenaEvo);\n            System.out.println(\"Juegos: \" + juegos);\n\n        } catch (Exception e) {\n            System.out.println(\"No se pudo obtener información del Pokémon. \" + e.getMessage());\n        }\n        sc.close();\n    }\n}\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/java/FranDev200.java",
    "content": "import java.io.IOException;\nimport java.net.HttpURLConnection;\nimport java.net.URI;\nimport java.net.URL;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\nimport java.util.ArrayList;\nimport java.util.Scanner;\n\npublic class FranDev200 {\n\n    static ArrayList<String> evoluciones = new ArrayList<>();\n\n    // PARA EL APARTADO DE JSON, USO EL .jar DE GSON\n\n    static void main() {\n\n        /*\n\n        EJERCICIO:\n        * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n        * una petición a la web que tú quieras, verifica que dicha petición\n        * fue exitosa y muestra por consola el contenido de la web.\n\n         */\n\n        try{\n\n            HttpClient client = HttpClient.newHttpClient();\n\n            HttpRequest request = HttpRequest.newBuilder()\n                    .uri(URI.create(\"https://urbansoundprints.com/products/debi-tirar-mas-fotos\"))\n                    .GET()\n                    .build();\n\n            HttpResponse<String> respuesta =  client.send(request, HttpResponse.BodyHandlers.ofString());\n\n            System.out.println(\"Codigo de respuesta: \" + respuesta.statusCode());\n            System.out.println(\"Respuesta:\\n\" + respuesta.body());\n\n        }catch (InterruptedException e){\n            e.getMessage();\n        }catch (IOException e){\n            e.getMessage();\n        }\n\n\n        /*\n\n        DIFICULTAD EXTRA (opcional):\n         * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n         * terminal al que le puedas solicitar información de un Pokémon concreto\n         * utilizando su nombre o número.\n         * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n         * - Muestra el nombre de su cadena de evoluciones\n         * - Muestra los juegos en los que aparece\n         * - Controla posibles errores\n\n         */\n\n        String urlInicio = \"https://pokeapi.co/api/v2\";\n\n\n        Scanner scanner = new Scanner(System.in);\n\n        System.out.print(\"Introduce el nombre o número de la pokedex del pokemon: \");\n        String poke = scanner.nextLine();\n\n        try {\n\n            URL url = new URL(urlInicio + \"/pokemon/\" + poke);\n\n            HttpURLConnection connection = (HttpURLConnection) url.openConnection();\n\n            connection.setRequestMethod(\"GET\");\n            connection.connect();\n\n            int responseCode = connection.getResponseCode();\n\n            if(responseCode == 200){\n\n                System.out.println(\"Conexion exitosa\");\n\n                scanner = new Scanner(connection.getInputStream());\n                StringBuilder json = new StringBuilder(\"\");\n                while (scanner.hasNextLine()) {\n                    json.append(scanner.nextLine());\n                }\n\n                Gson gson = new Gson();\n\n                JsonObject pokeInfo = gson.fromJson(json.toString(), JsonObject.class);\n\n                String nombre = pokeInfo.get(\"name\").getAsString();\n                int nroPokedex = pokeInfo.get(\"id\").getAsInt();\n                double peso = pokeInfo.get(\"weight\").getAsDouble();\n                double altura = pokeInfo.get(\"height\").getAsDouble();\n                JsonArray tiposArray =  pokeInfo.get(\"types\").getAsJsonArray();\n                ArrayList<String> tipos = new ArrayList<>();\n\n                for(int i = 0; i < tiposArray.size(); i++){\n                    JsonObject t = tiposArray.get(i).getAsJsonObject();\n                    JsonObject tipo = t.get(\"type\").getAsJsonObject();\n                    String nombreTipo = tipo.get(\"name\").getAsString();\n                    String resultado = nombreTipo.substring(0, 1).toUpperCase() +\n                            nombreTipo.substring(1).toLowerCase();\n                    tipos.add(resultado);\n                }\n\n                ArrayList<String> juegos = new ArrayList<>();\n                JsonArray juegosArray = pokeInfo.get(\"game_indices\").getAsJsonArray();\n\n                for(int i = 0; i < juegosArray.size(); i++){\n                    JsonObject indice = juegosArray.get(i).getAsJsonObject();\n                    JsonObject juego = indice.get(\"version\").getAsJsonObject();\n                    String nombreJuego = juego.get(\"name\").getAsString();\n                    juegos.add(nombreJuego);\n                }\n\n\n                URL urlEspecie = new  URL(urlInicio + \"/pokemon-species/\" + poke);\n\n                connection = (HttpURLConnection) urlEspecie.openConnection();\n                connection.setRequestMethod(\"GET\");\n                connection.connect();\n\n                responseCode = connection.getResponseCode();\n\n                if(responseCode == 200){\n\n                    scanner = new Scanner(connection.getInputStream());\n                    StringBuilder jsonEspecies = new StringBuilder(\"\");\n                    while (scanner.hasNextLine()) {\n                        jsonEspecies.append(scanner.nextLine());\n                    }\n\n                    Gson gsonEspecies = new Gson();\n\n                    JsonObject especieInfo = gsonEspecies.fromJson(jsonEspecies.toString(), JsonObject.class);\n\n                    String urlEvoluciones = especieInfo.getAsJsonObject(\"evolution_chain\").get(\"url\").getAsString();\n                    URL urlEvolucion = new URL(urlEvoluciones);\n\n                    connection = (HttpURLConnection) urlEvolucion.openConnection();\n                    connection.setRequestMethod(\"GET\");\n                    connection.connect();\n\n                    responseCode = connection.getResponseCode();\n\n                    if(responseCode == 200){\n\n                        scanner = new Scanner(connection.getInputStream());\n                        StringBuilder jsonEvolucion = new StringBuilder(\"\");\n                        while (scanner.hasNextLine()) {\n                            jsonEvolucion.append(scanner.nextLine());\n                        }\n\n                        Gson gsonEvolucion = new Gson();\n\n                        JsonObject evoInfo = gsonEvolucion.fromJson(jsonEvolucion.toString(), JsonObject.class);\n\n                        getEvolucion(evoInfo.getAsJsonObject(\"chain\"));\n\n                    }\n\n                }\n\n                Pokemon pokemon = new Pokemon(nroPokedex, nombre, peso, altura, tipos, juegos,  evoluciones);\n\n                pokemon.infoPokemon();\n\n            }else{\n                System.out.println(\"No se ha podido acceder a la url indicada.\");\n                System.out.println(\"Posiblemente, el pokemon indicado no exista.\");\n            }\n\n\n        }catch (IOException e){\n            e.getMessage();\n        }\n\n\n\n\n\n    }\n\n    public static void getEvolucion(JsonObject json){\n        String nombreEvolucion = json.getAsJsonObject(\"species\").get(\"name\").getAsString();\n        evoluciones.add(nombreEvolucion);\n\n        JsonArray evolves = json.getAsJsonArray(\"evolves_to\");\n        if(evolves.size() > 0){\n            getEvolucion(evolves.get(0).getAsJsonObject());\n        }\n    }\n\n    static class Pokemon{\n        private String nombre;\n        private int nroPokedex;\n        private double peso;\n        private double altura;\n        private ArrayList<String> tipos;\n        private ArrayList<String> juegos;\n        private ArrayList<String> evoluciones;\n\n        public Pokemon(int nroPokedex, String nombre, double peso, double altura, ArrayList<String> tipos, ArrayList<String> juegos, ArrayList<String> evoluciones){\n\n            this.nroPokedex = nroPokedex;\n            this.nombre = nombre;\n            this.peso = peso / 10;\n            this.altura = altura;\n            this.juegos = juegos;\n            this.evoluciones = evoluciones;\n            this.tipos = tipos;\n\n        }\n\n        public Pokemon(int nroPokedex, String nombre, double peso, double altura, ArrayList<String> tipos, ArrayList<String> juegos){\n\n            this.nroPokedex = nroPokedex;\n            this.nombre = nombre;\n            this.peso = peso / 10;\n            this.altura = altura;\n            this.juegos = juegos;\n            this.tipos = tipos;\n\n        }\n\n        public String getNombre() {\n\n            String nombre = this.nombre.substring(0, 1).toUpperCase() +\n                    this.nombre.substring(1).toLowerCase();\n\n            return nombre;\n        }\n\n        public void setNombre(String nombre) { this.nombre = nombre; }\n\n        public int getNroPokedex() {\n            return nroPokedex;\n        }\n\n        public void setNroPokedex(int nroPokedex) {\n            this.nroPokedex = nroPokedex;\n        }\n\n        public double getPeso() {\n            return peso;\n        }\n\n        public void setPeso(double peso) { this.peso = peso; }\n\n        public double getAltura() {\n            return altura;\n        }\n\n        public void setAltura(double altura) {\n            this.altura = altura;\n        }\n\n        public ArrayList<String> getTipos() {\n            return tipos;\n        }\n\n        public void setTipos(ArrayList<String> tipos) { this.tipos = tipos; }\n\n        public ArrayList<String> getJuegos() {\n            return juegos;\n        }\n\n        public void setJuegos(ArrayList<String> juegos) {\n            this.juegos = juegos;\n        }\n\n        public ArrayList<String> getEvoluciones() {\n            return evoluciones;\n        }\n\n        public void setEvoluciones(ArrayList<String> evoluciones) {\n            this.evoluciones = evoluciones;\n        }\n\n        public void infoPokemon(){\n\n            System.out.println();\n            System.out.println(\"INFO. POKEMON\");\n            System.out.println(\"- - - - - - -\");\n            System.out.printf(\"Nº %04d\\t --> %s\\n\", getNroPokedex(),  getNombre());\n            System.out.println(\"===============\");\n\n            System.out.print(\"Tipo/s: \");\n            for (String tipo : getTipos()) {\n                System.out.print(tipo + \" | \");\n            }\n\n            System.out.println(\"\\n- Peso: \" +  getPeso() + \"Kg\");\n            System.out.println(\"- Altura: \" + getAltura() + \"m\");\n\n            System.out.println(\"=========================\\n\");\n\n            System.out.println(\" ---- Juegos en los que aparece ---- \");\n            System.out.println(\"-------------------------------------\");\n\n            int contador = 0;\n\n            System.out.print(\" - \");\n            for (String juego : getJuegos()) {\n\n                if(contador == 3){\n                    contador = 0;\n                    System.out.print(\"\\n - \");\n                }\n\n                System.out.print(juego + \" | \");\n                contador++;\n\n            }\n\n            System.out.println(\"\\n\\nLinea Evolutiva\");\n            System.out.println(\"===============\");\n            contador = 1;\n            for (String evolucion : getEvoluciones()) {\n                System.out.println( contador + \" - \" + evolucion);\n                contador++;\n            }\n\n        }\n    }\n\n\n}\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/java/JimsimroDev.java",
    "content": "/*\n * EJERCICIO:\n * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n * una petición a la web que tú quieras, verifica que dicha petición\n * fue exitosa y muestra por consola el contenido de la web.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n * terminal al que le puedas solicitar información de un Pokémon concreto\n * utilizando su nombre o número.\n * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n * - Muestra el nombre de su cadena de evoluciones\n * - Muestra los juegos en los que aparece\n * - Controla posibles errores\n */\n\nimport java.io.IOException;\nimport java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\nimport java.util.Scanner;\n\npublic class JimsimroDev {\n  private static final String URL_BASE = \"https://pokeapi.co/api/v2/pokemon/\";\n\n  String consumirApi(String url) {\n    HttpClient client = HttpClient.newHttpClient();\n    HttpRequest request = HttpRequest.newBuilder()\n        .uri(URI.create(url))\n        .build();\n    HttpResponse<String> response = null;\n\n    try {\n      response = client.send(request, HttpResponse.BodyHandlers.ofString());\n    } catch (IOException e) {\n      throw new RuntimeException(e);\n    } catch (InterruptedException e) {\n      throw new RuntimeException(e);\n    }\n    if (response.statusCode() == 200) {\n      IO.println(\"Respuesta exitosa codigo: \" + response.statusCode());\n      String json = response.body();\n      return json;\n    }\n    throw new RuntimeException(\"Eror al procesar la solicitud codigo de error \" + response.statusCode());\n  }\n\n  // Busca campo en la Raiz\n  private String getCampo(StringBuilder data, String campo) {\n    String patron = \"\\\"\" + campo + \"\\\":\";\n    int inicio = data.indexOf(patron);\n    if (inicio != -1) {\n      inicio += patron.length();\n      while (inicio < data.length() && Character.isWhitespace(data.charAt(inicio))) {\n        inicio++;\n      }\n      if (inicio < data.length()) {\n        if (data.charAt(inicio) == '\"') {\n          inicio++;\n          int fin = data.indexOf(\"\\\"\", inicio);\n          if (fin != -1) {\n            return data.substring(inicio, fin);\n          }\n        } else {\n          int fin = inicio;\n          while (fin < data.length() &&\n              data.charAt(fin) != ',' &&\n              data.charAt(fin) != '}' &&\n              data.charAt(fin) != '\\n') {\n            fin++;\n          }\n          return data.substring(inicio, fin).trim();\n        }\n      }\n    }\n    return null;\n  }\n\n  // Busca campo en una sección dada\n  private String getCampo(StringBuilder data, String seccion, String campo) {\n    int indiceSeccion = data.indexOf(\"\\\"\" + seccion + \"\\\"\");\n    if (indiceSeccion != -1) {\n      String patron = \"\\\"\" + campo + \"\\\":\\\"\";\n      int indiceCampo = data.indexOf(patron, indiceSeccion);\n\n      if (indiceCampo != -1) {\n        int empiezaValor = indiceCampo + patron.length();\n        int terminaValor = data.indexOf(\"\\\"\", empiezaValor);\n        return data.substring(empiezaValor, terminaValor);\n      }\n    }\n    return null;\n  }\n\n  // Busca los typos\n  private String[] getTypes(StringBuilder data) {\n    String tiposPattern = \"\\\"types\\\":[\";\n    int startIndex = data.indexOf(tiposPattern);\n    if (startIndex != -1) {\n      startIndex += tiposPattern.length();\n      int endIdex = data.indexOf(\"]\", startIndex);\n      if (endIdex != -1) {\n        String tiposArray = data.substring(startIndex, endIdex);\n        String[] tipos = tiposArray.split(\"},\");\n        String[] resultados = new String[tipos.length];\n        // Procesar cada tipo\n        for (int i = 0; i < tipos.length; i++) {\n          String tipo = tipos[i];\n          String namePattern = \"\\\"name\\\":\\\"\";\n          int nameStart = tipo.indexOf(namePattern);\n          if (nameStart != -1) {\n            nameStart += namePattern.length();\n            int nameEnd = tipo.indexOf(\"\\\"\", nameStart);\n            if (nameEnd != -1) {\n              resultados[i] = tipo.substring(nameStart, nameEnd);\n            }\n          }\n        }\n        return resultados;\n      }\n    }\n    return new String[0];\n  }\n\n  private String getEvolutionChainUrl(StringBuilder data) {\n    String patron = \"\\\"evolution_chain\\\":{\\\"url\\\":\\\"\";\n    int inicio = data.indexOf(patron);\n    if (inicio != -1) {\n      inicio += patron.length();\n      int fin = data.indexOf(\"\\\"\", inicio);\n      if (fin != -1) {\n        return data.substring(inicio, fin);\n      }\n    }\n    return null;\n  }\n\n  void evolution_chain(StringBuilder data) {\n    // Obtener el nombre de la especie actual\n    String speciesName = getCampo(data, \"species\", \"name\");\n    IO.println(\"Evolución: \" + speciesName);\n\n    // Buscar el patrón de evolves_to\n    String evolvesToPattern = \"\\\"evolves_to\\\":[\";\n    int evolvesToIndex = data.indexOf(evolvesToPattern);\n\n    if (evolvesToIndex != -1) {\n      // Si encontramos evolves_to y no está vacío\n      evolvesToIndex += evolvesToPattern.length();\n      if (data.charAt(evolvesToIndex) != ']') {\n        // Obtener el contenido del evolves_to\n        int endIndex = findMatchingBracket(data, evolvesToIndex);\n        if (endIndex != -1) {\n          // Crear un nuevo StringBuilder con el contenido de evolves_to\n          StringBuilder evolvesTo = new StringBuilder(\n              data.substring(evolvesToIndex, endIndex));\n          // Llamada recursiva con el nuevo contenido\n          evolution_chain(evolvesTo);\n        }\n      }\n    }\n  }\n\n  // Método auxiliar para encontrar el corchete de cierre correspondiente\n  private int findMatchingBracket(StringBuilder data, int startIndex) {\n    int count = 1;\n    for (int i = startIndex; i < data.length(); i++) {\n      if (data.charAt(i) == '[')\n        count++;\n      if (data.charAt(i) == ']')\n        count--;\n      if (count == 0)\n        return i;\n    }\n    return -1;\n  }\n\n  void main() {\n    Scanner in = new Scanner(System.in);\n\n    // HttpClient client = HttpClient.newHttpClient();\n    //\n    // HttpRequest request = HttpRequest.newBuilder()\n    // .uri(URI.create(\"https://www.mercadolibre.com.co/\"))\n    // .build();\n    // HttpResponse<String> response = null;\n    //\n    // try {\n    // response = client.send(request, HttpResponse.BodyHandlers.ofString());\n    // } catch (IOException e) {\n    // throw new RuntimeException(e);\n    // } catch (InterruptedException e) {\n    // throw new RuntimeException(e);\n    // }\n    // String json = response.body();\n    // IO.println(\"Estado \" + response.statusCode());\n    // IO.println(json);\n\n    IO.println(\"Ingresa el nombre del pokemon a consultar\");\n    String pokemon = in.nextLine();\n\n    StringBuilder data = new StringBuilder();\n    StringBuilder url = new StringBuilder();\n\n    data.append(consumirApi(URL_BASE + pokemon));\n\n    String nombre = getCampo(data, \"name\");\n\n    String id = getCampo(data, \"id\");\n\n    String peso = getCampo(data, \"weight\");\n\n    String altura = getCampo(data, \"height\");\n    String[] tipos = getTypes(data);\n\n    String urlSpecies = getCampo(data, \"species\", \"url\");\n\n    url.append(consumirApi(urlSpecies));\n    String urlEvolucion = getEvolutionChainUrl(url);\n\n    // StringBuilder evolution = new StringBuilder();\n    // String evolucin = getCampo(evolution, \"species\", \"name\");\n    // IO.println(\"url evloucion \" + evolution);\n    // IO.println(\"evolution\" + evolucin);\n\n    StringBuilder evolutionData = new StringBuilder(consumirApi(urlEvolucion));\n    evolution_chain(evolutionData);\n    IO.println(\"Nombre: \" + nombre);\n    IO.println(\"ID: \" + id);\n    IO.println(\"Peso: \" + peso);\n    IO.println(\"Altura: \" + altura);\n    IO.println(\"Tipos:\");\n    for (String tipo : tipos) {\n      IO.println(\"- \" + tipo);\n    }\n    in.close();\n  }\n}\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/java/Josegs95.java",
    "content": "import com.google.gson.JsonArray;\nimport com.google.gson.JsonElement;\nimport com.google.gson.JsonObject;\nimport com.google.gson.JsonParser;\n\nimport java.io.IOException;\nimport java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\nimport java.net.http.HttpResponse.BodyHandlers;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Scanner;\n\npublic class Josegs95 {\n    public static void main(String[] args) {\n        //Ejercicio\n        HttpClient client = HttpClient.newHttpClient();\n        HttpRequest request = HttpRequest.newBuilder()\n                .uri(URI.create(\"https://www.google.es\"))\n                .GET()\n                .build();\n        try {\n            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());\n            //Si no salta excepción, la petición fue exitosa.\n            if (response.statusCode() != 200)\n                System.out.println(\"Ha habido algún problema con la conexión. Cod: \" + response.statusCode());\n            else{\n                System.out.println(\"La conexión ha sido un éxito.\");\n                System.out.println(response.body());\n            }\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        } catch (InterruptedException e) {\n            throw new RuntimeException(e);\n        }\n\n        //Reto\n        retoFinal();\n    }\n\n    public static void retoFinal(){\n        //Voy a escribirlo todo en un método para hacerlo más sencillo y porque ya existen librerías especializadas\n        //en trabajar con la pokeapi.\n\n        Scanner sc = new Scanner(System.in);\n        System.out.print(\"Introduzca el nombre o el número del Pokémon: \");\n        String pokemon = sc.nextLine().toLowerCase();\n\n        HttpClient client = HttpClient.newHttpClient();\n        HttpRequest request = HttpRequest.newBuilder()\n                .uri(URI.create(\"https://pokeapi.co/api/v2/pokemon/\" + pokemon))\n                .build();\n        try {\n            HttpResponse<String> response = client.send(request, BodyHandlers.ofString());\n\n            if(response.statusCode() != 200)\n                System.out.println(\"Error \" + response.statusCode() + \". Pokémon desconocido.\");\n            else{\n                JsonObject pokemonData = JsonParser.parseString(response.body()).getAsJsonObject();\n\n                //ID, nombre, peso, altura y tipos\n                String id = pokemonData.get(\"id\").getAsString();\n                String name = pokemonData.get(\"name\").getAsString();\n                double weight = pokemonData.get(\"weight\").getAsDouble() / 10.0;\n                double height = pokemonData.get(\"height\").getAsDouble() / 10.0;\n\n                List<String> typeList = new ArrayList<>();\n                for (JsonElement type : pokemonData.get(\"types\").getAsJsonArray()) {\n                    JsonObject aux = type.getAsJsonObject();\n                    typeList.add(aux.get(\"type\").getAsJsonObject().get(\"name\").getAsString());\n                }\n\n                System.out.println(\"ID: \" + id);\n                System.out.println(\"Nombre: \" + name);\n                System.out.println(\"Peso: \" + weight + \" kg.\");\n                System.out.println(\"Altura: \" + height + \" m.\");\n                System.out.print(\"Tipos: \");\n                for (String type : typeList)\n                    System.out.print(type + \" \");\n                System.out.println();\n\n                //Evoluciones\n                request = HttpRequest.newBuilder(URI.create(\"https://pokeapi.co/api/v2/pokemon-species/\" + id))\n                        .build();\n                response = client.send(request, BodyHandlers.ofString());\n\n                if (response.statusCode() == 200){\n                    JsonObject specieData = JsonParser.parseString(response.body()).getAsJsonObject();\n                    String evoChainURL = specieData.get(\"evolution_chain\").getAsJsonObject().get(\"url\").getAsString();\n\n                    request = HttpRequest.newBuilder(URI.create(evoChainURL))\n                            .build();\n                    response = client.send(request, BodyHandlers.ofString());\n\n                    if (response.statusCode() == 200){\n                        JsonObject evolutionData = JsonParser.parseString(response.body()).getAsJsonObject();\n                        JsonElement auxElement = evolutionData.get(\"chain\");\n                        List<String> evolutionList = new ArrayList<>();\n                        String basePokemonName = auxElement.getAsJsonObject()\n                                .get(\"species\").getAsJsonObject()\n                                .get(\"name\").getAsString();\n                        evolutionList.add(basePokemonName);\n                        for(JsonElement evolution : auxElement.getAsJsonObject().get(\"evolves_to\").getAsJsonArray()){\n                            String aux = evolution.getAsJsonObject().get(\"species\").getAsJsonObject().get(\"name\").getAsString();\n                            evolutionList.add(aux);\n                            for (JsonElement evolution2 : evolution.getAsJsonObject().get(\"evolves_to\").getAsJsonArray()){\n                                aux = evolution2.getAsJsonObject().get(\"species\").getAsJsonObject().get(\"name\").getAsString();\n                                evolutionList.add(aux);\n                            }\n                        }\n                        System.out.println(\"Línea evolutiva: \" + evolutionList);\n                        //Juegos\n                        List<String> gameList = new ArrayList<>();\n                        for (JsonElement game : pokemonData.get(\"game_indices\").getAsJsonArray())\n                            gameList.add(game.getAsJsonObject()\n                                    .get(\"version\").getAsJsonObject()\n                                    .get(\"name\").getAsString());\n                        System.out.print(\"Juegos: \");\n                        for (String gameName : gameList)\n                            System.out.print(\"[Pokémon \" + gameName + \"] \");\n                        System.out.println();\n                    }\n                }\n            }\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        } catch (InterruptedException e) {\n            throw new RuntimeException(e);\n        }\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/java/asjordi.java",
    "content": "package dev.asjordi.r20;\n\nimport com.google.gson.Gson;\nimport com.google.gson.JsonObject;\nimport java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\nimport java.util.Scanner;\n\npublic class Main {\n\n    public static void main(String[] args) throws Exception {\n        getRequest(\"https://www.google.com\");\n        getPokemon();\n    }\n\n    /**\n     * EJERCICIO:\n     * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n     * una petición a la web que tú quieras, verifica que dicha petición\n     * fue exitosa y muestra por consola el contenido de la web.\n     */\n    public static void getRequest(String url) throws Exception {\n        HttpClient client = HttpClient.newHttpClient();\n        HttpRequest request = HttpRequest.newBuilder()\n                .uri(URI.create(url))\n                .build();\n\n        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());\n\n        if (response.statusCode() != 200) throw new Exception(\"Request failed with status code: \" + response.statusCode());\n        else System.out.println(response.body());\n    }\n\n    /**\n     * DIFICULTAD EXTRA (opcional):\n     * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n     * terminal al que le puedas solicitar información de un Pokémon concreto\n     * utilizando su nombre o número.\n     * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n     * - Muestra el nombre de su cadena de evoluciones\n     * - Muestra los juegos en los que aparece\n     * - Controla posibles errores\n     */\n    public static void getPokemon() {\n        Scanner sc = new Scanner(System.in);\n        Gson gson = new Gson();\n\n        System.out.println(\"Introduce el nombre o número del Pokémon:\");\n        String param = sc.nextLine();\n\n        String baseUrl = String.format(\"https://pokeapi.co/api/v2/pokemon/%s\", param);\n        var getBaseResponse = sendRequest(baseUrl);\n        if (getBaseResponse.statusCode() != 200) System.out.println(\"Error: \" + getBaseResponse.statusCode());\n        String baseResponseBody = getBaseResponse.body();\n        JsonObject data = gson.fromJson(baseResponseBody, JsonObject.class);\n\n        String id = data.get(\"id\").getAsString();\n        String name = data.get(\"name\").getAsString();\n        String weight = data.get(\"weight\").getAsString();\n        String height = data.get(\"height\").getAsString();\n\n        String chainUrl = String.format(\"https://pokeapi.co/api/v2/evolution-chain/%s\", id);\n        var getChainResponse = sendRequest(chainUrl);\n        if (getChainResponse.statusCode() != 200) System.out.println(\"Error: \" + getChainResponse.statusCode());\n        String chainResponseBody = getChainResponse.body();\n        JsonObject chainData = gson.fromJson(chainResponseBody, JsonObject.class);\n\n        var types = data.getAsJsonArray(\"types\");\n        StringBuilder typeNames = new StringBuilder();\n        for (int i = 0; i < types.size(); i++) {\n            JsonObject type = types.get(i).getAsJsonObject().getAsJsonObject(\"type\");\n            typeNames.append(type.get(\"name\").getAsString());\n            if (i < types.size() - 1) typeNames.append(\", \");\n        }\n\n        var gameIndices = data.getAsJsonArray(\"game_indices\");\n        StringBuilder gameNames = new StringBuilder();\n        for (int i = 0; i < gameIndices.size(); i++) {\n            JsonObject game = gameIndices.get(i).getAsJsonObject().getAsJsonObject(\"version\");\n            gameNames.append(game.get(\"name\").getAsString());\n            if (i < gameIndices.size() - 1) gameNames.append(\", \");\n        }\n\n        var chain = chainData.getAsJsonObject(\"chain\");\n        StringBuilder evolutionNames = new StringBuilder();\n        getEvolutions(chain, evolutionNames);\n\n        System.out.println(\"ID: \" + id);\n        System.out.println(\"Nombre: \" + name);\n        System.out.println(\"Peso: \" + weight);\n        System.out.println(\"Altura: \" + height);\n        System.out.println(\"Tipos: \" + typeNames.toString());\n        System.out.println(\"Las evoluciones de \" + name + \" son: \" + evolutionNames.toString());\n        System.out.println(\"Aparece en los juegos: \" + gameNames.toString());\n    }\n\n    private static void getEvolutions(JsonObject chain, StringBuilder evolutionNames) {\n        String chainName = chain.getAsJsonObject(\"species\").get(\"name\").getAsString();\n        evolutionNames.append(chainName);\n\n        var evolutions = chain.getAsJsonArray(\"evolves_to\");\n        for (int i = 0; i < evolutions.size(); i++) {\n            evolutionNames.append(\" -> \");\n            getEvolutions(evolutions.get(i).getAsJsonObject(), evolutionNames);\n        }\n    }\n\n    private static HttpResponse<String> sendRequest(String url) {\n        HttpClient client = HttpClient.newHttpClient();\n        HttpRequest getRequest = HttpRequest.newBuilder()\n                .uri(URI.create(url))\n                .GET()\n                .build();\n        HttpResponse<String> getResponse = null;\n\n        try {\n            getResponse = client.send(getRequest, HttpResponse.BodyHandlers.ofString());\n        } catch (Exception e) {\n            System.out.println(\"Error: \" + e.getMessage());\n        }\n\n        return getResponse;\n    }\n}\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/java/danhingar.java",
    "content": "import com.google.gson.Gson;\nimport com.google.gson.JsonArray;\nimport com.google.gson.JsonElement;\nimport com.google.gson.JsonObject;\n\nimport java.io.IOException;\nimport java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Objects;\nimport java.util.Scanner;\n\npublic class danhingar {\n\n    public static void main(String[] args) throws IOException, InterruptedException {\n        makeRequest();\n        pokemonApi();\n    }\n\n    public static void makeRequest() {\n        HttpClient client = HttpClient.newHttpClient();\n        HttpRequest request = HttpRequest.newBuilder()\n                .uri(URI.create(\"https://medium.com/\"))\n                .build();\n        try {\n            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());\n\n            System.out.println(response.body());\n        } catch (Exception e) {\n            System.out.println(\"Error en la petición\");\n        }\n    }\n\n    // EXTRA\n    private static void pokemonApi() {\n        System.out.print(\"Introduce el nombre o número del pokemon: \");\n        Scanner sc = new Scanner(System.in);\n        String value = sc.nextLine();\n        sc.close();\n        HttpClient client = HttpClient.newHttpClient();\n        HttpRequest request = HttpRequest.newBuilder()\n                .uri(URI.create(\"https://pokeapi.co/api/v2/pokemon/\" + value+\"/\"))\n                .build();\n\n\n        try {\n            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());\n            String content = response.body();\n            JsonObject convertedObject = new Gson().fromJson(content, JsonObject.class);\n\n            String name = convertedObject.get(\"name\").getAsString();\n            String id =convertedObject.get(\"id\").getAsString();\n            String weight = convertedObject.get(\"weight\").getAsString();\n            String height = convertedObject.get(\"height\").getAsString();\n            JsonArray types=convertedObject.get(\"types\").getAsJsonArray();\n            List<String> typesName=types.asList().stream().map(i-> i.getAsJsonObject().get(\"type\").getAsJsonObject().get(\"name\").getAsString()).toList();\n            System.out.printf(\"Name: %s, Id: %s, Weight: %s, Height: %s, Type: %s%n\",name, id, weight,height, typesName);\n\n            getEvolutions(id);\n\n            JsonArray games=convertedObject.get(\"game_indices\").getAsJsonArray();\n            List<String> gamesName=games.asList().stream().map(i-> i.getAsJsonObject().get(\"version\").getAsJsonObject().get(\"name\").getAsString()).toList();\n            System.out.printf(\"Games: %s%n\",gamesName);\n\n\n        } catch (Exception e) {\n            System.out.println(\"Error en la petición\");\n        }\n\n        System.exit(1);\n\n\n    }\n\n    private static void getEvolutions(String id) {\n        HttpClient client = HttpClient.newHttpClient();\n        HttpRequest request = HttpRequest.newBuilder()\n                .uri(URI.create(\"https://pokeapi.co/api/v2/pokemon-species/\" + id))\n                .build();\n\n        try {\n            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());\n            String content = response.body();\n            JsonObject convertedObject = new Gson().fromJson(content, JsonObject.class);\n            String url = convertedObject.get(\"evolution_chain\").getAsJsonObject().get(\"url\").getAsString();\n\n            HttpRequest request2 = HttpRequest.newBuilder()\n                    .uri(URI.create(url))\n                    .build();\n            HttpResponse<String> response2 = client.send(request2, HttpResponse.BodyHandlers.ofString());\n            String content2 = response2.body();\n            JsonObject convertedObject2 = new Gson().fromJson(content2, JsonObject.class);\n\n            System.out.println(\"Cadena de evoluciones: \"+getEvolution(convertedObject2.getAsJsonObject(\"chain\"),new ArrayList<>()));\n\n        } catch (Exception e) {\n            System.out.println(\"Error al obtener las evoluciones\");\n        }\n    }\n\n    public static List<String> getEvolution(JsonObject json,List<String> evolutions){\n        evolutions.add(json.get(\"species\").getAsJsonObject().get(\"name\").getAsString());\n        if(!json.getAsJsonArray(\"evolves_to\").isEmpty()){\n            for(JsonElement element:json.getAsJsonArray(\"evolves_to\")){\n                getEvolution(element.getAsJsonObject(),evolutions);\n            }\n        }else{\n            return evolutions;\n        }\n        return evolutions;\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/java/eulogioep.java",
    "content": "import java.io.BufferedReader;\nimport java.io.InputStreamReader;\nimport java.net.HttpURLConnection;\nimport java.net.URL;\nimport java.util.Scanner;\nimport org.json.JSONArray;\nimport org.json.JSONObject;\n\n/**\n * Este programa demuestra el uso de peticiones HTTP en Java y la integración\n * con la PokéAPI.\n * \n * Teoría sobre peticiones HTTP:\n * - HTTP (Hypertext Transfer Protocol) es un protocolo de comunicación que\n * permite\n * la transferencia de información en la World Wide Web.\n * - Los métodos HTTP más comunes son:\n * * GET: Solicita datos de un recurso específico\n * * POST: Envía datos para crear un nuevo recurso\n * * PUT: Actualiza un recurso existente\n * * DELETE: Elimina un recurso\n * \n * En Java, podemos realizar peticiones HTTP utilizando la clase\n * HttpURLConnection,\n * que nos permite establecer una conexión con un servidor web y enviar/recibir\n * datos.\n */\npublic class EulogioEP {\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n\n        // Ejemplo básico de petición HTTP\n        System.out.println(\"=== Ejemplo básico de petición HTTP ===\");\n        try {\n            String content = makeHttpRequest(\"https://www.example.com\");\n            System.out.println(\"Contenido de example.com:\");\n            System.out.println(content);\n        } catch (Exception e) {\n            System.out.println(\"Error al realizar la petición HTTP: \" + e.getMessage());\n        }\n\n        // Funcionalidad de la PokéAPI\n        while (true) {\n            System.out.println(\"\\n=== Búsqueda de Pokémon ===\");\n            System.out.println(\"Ingrese el nombre o número del Pokémon (o 'salir' para terminar):\");\n            String input = scanner.nextLine().toLowerCase();\n\n            if (input.equals(\"salir\")) {\n                break;\n            }\n\n            try {\n                // Realizar petición a la PokéAPI\n                String pokemonData = makeHttpRequest(\"https://pokeapi.co/api/v2/pokemon/\" + input);\n                JSONObject pokemon = new JSONObject(pokemonData);\n\n                // Mostrar información básica del Pokémon\n                System.out.println(\"\\nInformación del Pokémon:\");\n                System.out.println(\"Nombre: \" + pokemon.getString(\"name\"));\n                System.out.println(\"ID: \" + pokemon.getInt(\"id\"));\n                System.out.println(\"Peso: \" + pokemon.getInt(\"weight\") / 10.0 + \" kg\");\n                System.out.println(\"Altura: \" + pokemon.getInt(\"height\") / 10.0 + \" m\");\n\n                // Mostrar tipos\n                System.out.println(\"Tipos:\");\n                JSONArray types = pokemon.getJSONArray(\"types\");\n                for (int i = 0; i < types.length(); i++) {\n                    System.out.println(\"- \" + types.getJSONObject(i).getJSONObject(\"type\").getString(\"name\"));\n                }\n\n                // Obtener y mostrar cadena de evolución\n                String speciesUrl = pokemon.getJSONObject(\"species\").getString(\"url\");\n                String speciesData = makeHttpRequest(speciesUrl);\n                JSONObject species = new JSONObject(speciesData);\n                String evolutionChainUrl = species.getJSONObject(\"evolution_chain\").getString(\"url\");\n                String evolutionData = makeHttpRequest(evolutionChainUrl);\n                JSONObject evolution = new JSONObject(evolutionData);\n\n                System.out.println(\"\\nCadena de evolución:\");\n                printEvolutionChain(evolution.getJSONObject(\"chain\"));\n\n                // Mostrar juegos\n                System.out.println(\"\\nJuegos en los que aparece:\");\n                JSONArray games = pokemon.getJSONArray(\"game_indices\");\n                for (int i = 0; i < games.length(); i++) {\n                    System.out.println(\"- \" + games.getJSONObject(i).getJSONObject(\"version\").getString(\"name\"));\n                }\n\n            } catch (Exception e) {\n                System.out.println(\n                        \"Error: No se pudo encontrar el Pokémon. Asegúrese de escribir el nombre o número correctamente.\");\n            }\n        }\n\n        scanner.close();\n    }\n\n    /**\n     * Realiza una petición HTTP GET a la URL especificada.\n     * \n     * @param urlString La URL a la que se realizará la petición\n     * @return El contenido de la respuesta como String\n     * @throws Exception Si ocurre un error durante la petición\n     */\n    private static String makeHttpRequest(String urlString) throws Exception {\n        URL url = new URL(urlString);\n        HttpURLConnection conn = (HttpURLConnection) url.openConnection();\n        conn.setRequestMethod(\"GET\");\n\n        if (conn.getResponseCode() != 200) {\n            throw new RuntimeException(\"HTTP error code : \" + conn.getResponseCode());\n        }\n\n        BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));\n        StringBuilder response = new StringBuilder();\n        String output;\n        while ((output = br.readLine()) != null) {\n            response.append(output);\n        }\n        conn.disconnect();\n\n        return response.toString();\n    }\n\n    /**\n     * Imprime recursivamente la cadena de evolución de un Pokémon.\n     * \n     * @param chain El objeto JSON que contiene la información de la cadena de\n     *              evolución\n     */\n    private static void printEvolutionChain(JSONObject chain) {\n        String pokemonName = chain.getJSONObject(\"species\").getString(\"name\");\n        System.out.println(\"- \" + pokemonName);\n\n        JSONArray evolvesTo = chain.getJSONArray(\"evolves_to\");\n        for (int i = 0; i < evolvesTo.length(); i++) {\n            printEvolutionChain(evolvesTo.getJSONObject(i));\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/java/martinbohorquez.java",
    "content": "import com.google.gson.*;\n\nimport java.io.BufferedReader;\nimport java.io.IOException;\nimport java.io.InputStreamReader;\nimport java.net.HttpURLConnection;\nimport java.net.URI;\nimport java.net.URISyntaxException;\nimport java.net.URL;\nimport java.util.*;\nimport java.util.stream.Collectors;\nimport java.util.stream.StreamSupport;\n\n/**\n * #20 PETICIONES HTTP\n * <dependency>\n * <groupId>com.google.code.gson</groupId>\n * <artifactId>gson</artifactId>\n * <version>2.10.1</version>\n * </dependency>\n *\n * @author martinbohorquez\n */\npublic class martinbohorquez {\n    public static void main(String[] args) throws IOException, URISyntaxException {\n        getHttpResponse(\"https://www.moure.dev/\");\n\n        /*\n         * DIFICULTAD EXTRA\n         */\n        System.out.print(\"Introduce un nombre o número de Pokémon a buscar: \");\n        Scanner sc = new Scanner(System.in);\n        String pokemon = sc.nextLine().toLowerCase();\n\n        pokemonInfo(pokemon);\n    }\n\n    private static HttpURLConnection getResponse(String url) throws URISyntaxException, IOException {\n        HttpURLConnection response = null;\n        int responseCode;\n\n        while (true) {\n            URL obj = (new URI(url)).toURL();\n            response = (HttpURLConnection) obj.openConnection();\n            response.setRequestMethod(\"GET\");\n            response.setConnectTimeout(5000);\n            response.setReadTimeout(5000);\n\n            responseCode = response.getResponseCode();\n\n            if (responseCode >= 300 && responseCode < 400)\n                System.out.printf(\"Redirecting to: %s%n\", url = response.getHeaderField(\"Location\"));\n            else break;\n        }\n        return response;\n    }\n\n    private static void getHttpResponse(String url) throws IOException, URISyntaxException {\n        HttpURLConnection response = getResponse(url);\n        int responseCode = response.getResponseCode();\n\n        if (responseCode >= 200 && responseCode < 300)\n            try (BufferedReader in = new BufferedReader(new InputStreamReader(response.getInputStream()))) {\n                System.out.println(in.lines().collect(Collectors.joining()));\n            }\n        else System.out.printf(\"Error response código %d al realizar la petición\", response.getResponseCode());\n    }\n\n    private static void pokemonInfo(String pokemon) throws URISyntaxException, IOException {\n        HttpURLConnection response = getResponse(\"https://pokeapi.co/api/v2/pokemon/\" + pokemon);\n        int responseCode = response.getResponseCode();\n        if (responseCode >= 200 && responseCode < 300) {\n            try (BufferedReader in = new BufferedReader(new InputStreamReader(response.getInputStream()))) {\n                String jsonString = in.lines().collect(Collectors.joining());\n                Gson gson = new Gson();\n                JsonObject jsonObject = gson.fromJson(jsonString, JsonObject.class);\n\n                System.out.printf(\"Nombre: %s%n\", jsonObject.get(\"name\").getAsString());\n                System.out.printf(\"ID: %s%n\", jsonObject.get(\"id\").getAsString());\n                System.out.printf(\"Peso: %s%n\", jsonObject.get(\"weight\").getAsString());\n                System.out.printf(\"Altura: %s%n\", jsonObject.get(\"height\").getAsString());\n\n                List<String> types = StreamSupport.stream(jsonObject.getAsJsonArray(\"types\").spliterator(), false)\n                        .map(JsonElement::getAsJsonObject)\n                        .map(typeObject -> typeObject.getAsJsonObject(\"type\").get(\"name\").getAsString())\n                        .toList();\n                System.out.printf(\"Tipo(s): %s%n\", types);\n                evolutionChain(pokemon);\n                List<String> juegos = StreamSupport.stream(jsonObject.getAsJsonArray(\"game_indices\").spliterator(), false)\n                        .map(JsonElement::getAsJsonObject)\n                        .map(typeObject -> typeObject.getAsJsonObject(\"version\").get(\"name\").getAsString())\n                        .toList();\n                System.out.printf(\"Juegos: %s%n\", juegos);\n\n            }\n        } else System.out.printf(\"Error %d: Pokémon no encontrado!\", response.getResponseCode());\n    }\n\n    private static void evolutionChain(String pokemon) throws URISyntaxException, IOException {\n        HttpURLConnection response = getResponse(\"https://pokeapi.co/api/v2/pokemon-species/\" + pokemon);\n        int responseCode = response.getResponseCode();\n        if (responseCode >= 200 && responseCode < 300) {\n            try (BufferedReader in = new BufferedReader(new InputStreamReader(response.getInputStream()))) {\n                String jsonString = in.lines().collect(Collectors.joining());\n                Gson gson = new Gson();\n                JsonObject jsonObject = gson.fromJson(jsonString, JsonObject.class);\n\n                String url = jsonObject.get(\"evolution_chain\").getAsJsonObject().get(\"url\").getAsString();\n                response = getResponse(url);\n                responseCode = response.getResponseCode();\n                if (responseCode >= 200 && responseCode < 300) {\n                    try (BufferedReader inS = new BufferedReader(new InputStreamReader(response.getInputStream()))) {\n                        jsonString = inS.lines().collect(Collectors.joining());\n                        gson = new Gson();\n                        jsonObject = gson.fromJson(jsonString, JsonObject.class);\n\n                        StringBuilder evolutionChain = new StringBuilder();\n                        JsonObject chainObject = jsonObject.getAsJsonObject(\"chain\");\n\n                        System.out.println(\"Cadena(s) de evolución:\");\n                        Map<Integer, String> evolutionMap = new LinkedHashMap<>();\n                        getEvolveTo(evolutionMap, evolutionChain, chainObject).values().forEach(System.out::println);\n                    }\n                } else System.out.printf(\"Error %d: obteniendo evoluciones!\", response.getResponseCode());\n            }\n        } else System.out.printf(\"Error %d: obteniendo evoluciones!\", response.getResponseCode());\n    }\n\n    private static Map<Integer, String> getEvolveTo(Map<Integer, String> evolutionMap, StringBuilder evolutionChain, JsonObject chainObject) {\n        Set<String> evolutionSet = new LinkedHashSet<>();\n        JsonElement element = chainObject.getAsJsonObject(\"species\").get(\"name\");\n        evolutionChain.append(element);\n\n        JsonArray evolutions = chainObject.getAsJsonArray(\"evolves_to\");\n        for (int i = 0; i < evolutions.size(); i++) {\n            if (i != 0) {\n                int indexIni = evolutionChain.reverse().indexOf(\" >- \");\n                int length = evolutionChain.reverse().length();\n                evolutionChain.delete(length - indexIni - 4, length);\n                evolutionSet = new LinkedHashSet<>();\n            }\n            evolutionChain.append(\" -> \");\n            getEvolveTo(evolutionMap, evolutionChain, evolutions.get(i).getAsJsonObject());\n            evolutionSet.add(evolutionChain.toString());\n            if (!evolutionMap.containsValue(evolutionSet.toString())) evolutionMap.put(i, evolutionSet.toString());\n        }\n        return evolutionMap;\n    }\n}\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/java/simonguzman.java",
    "content": "import java.io.BufferedReader;\nimport java.io.IOException;\nimport java.io.InputStreamReader;\nimport java.io.StringReader;\nimport java.net.HttpURLConnection;\nimport java.net.URL;\n\n//Imports que no se pueden usar a no ser que se tengan en un archivo pom.xml\nimport javax.json.Json;\nimport javax.json.JsonArray;\nimport javax.json.JsonObject;\nimport javax.json.JsonReader;\n\n/* Dependencias necesarias para que funcione el codigo\n<dependency>\n        <groupId>javax.json</groupId>\n        <artifactId>javax.json-api</artifactId>\n        <version>1.1.4</version>\n    </dependency>\n    <dependency>\n        <groupId>org.glassfish</groupId>\n        <artifactId>javax.json</artifactId>\n        <version>1.1.4</version>\n    </dependency>*/\n\npublic class simonguzman {\n    public static void main(String[] args) throws IOException{\n        makeHttpRequest(\"https://www.google.com/\");\n        getPokemonApi(\"bulbasaur\");\n    }\n\n    public static void makeHttpRequest(String url) throws IOException{\n        URL obj = new URL(url);\n        HttpURLConnection con = (HttpURLConnection) obj.openConnection();\n        \n        con.setRequestMethod(\"GET\");\n\n        int responseCode = con.getResponseCode();\n        if (responseCode == 200) {\n            BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));\n            String inputLine;\n            StringBuffer response = new StringBuffer();\n\n            while ((inputLine = in.readLine()) != null) { \n                response.append(inputLine);\n            }\n            in.close();\n\n            System.out.println(response.toString());\n        }else{\n            System.out.println(\"ERROR: \"+responseCode);\n        }\n    }\n\n    public static void getPokemonInfo(String pokemonName) throws IOException {\n        String url = \"https://pokeapi.co/api/v2/pokemon/\" + pokemonName;\n        URL obj = new URL(url);\n        HttpURLConnection con = (HttpURLConnection) obj.openConnection();\n\n        con.setRequestMethod(\"GET\");\n        con.setRequestProperty(\"User-Agent\", \"MyPokemonApp\");\n\n        int responseCode = con.getResponseCode();\n        if (responseCode == 200) {\n            BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));\n            String inputLine;\n            StringBuffer response = new StringBuffer();\n\n            while ((inputLine = in.readLine()) != null) {\n                response.append(inputLine);\n            }\n            in.close();\n\n            JsonReader jsonReader = Json.createReader(new StringReader(response.toString()));\n            JsonObject jsonObject = jsonReader.readObject();\n\n            System.out.println(\"Nombre: \" + jsonObject.getString(\"name\"));\n            System.out.println(\"ID: \" + jsonObject.getInt(\"id\"));\n            System.out.println(\"Peso: \" + jsonObject.getJsonNumber(\"weight\").doubleValue());\n            System.out.println(\"Altura: \" + jsonObject.getJsonNumber(\"height\").doubleValue());\n            System.out.println(\"Tipos: \" + jsonObject.getJsonArray(\"types\"));\n\n            JsonObject speciesObject = jsonObject.getJsonObject(\"species\");\n            String speciesUrl = speciesObject.getString(\"url\");\n            URL speciesObj = new URL(speciesUrl);\n            HttpURLConnection speciesCon = (HttpURLConnection) speciesObj.openConnection();\n\n            speciesCon.setRequestMethod(\"GET\");\n            speciesCon.setRequestProperty(\"User-Agent\", \"MyPokemonApp\");\n\n            int speciesResponseCode = speciesCon.getResponseCode();\n            if (speciesResponseCode == 200) {\n                BufferedReader speciesIn = new BufferedReader(new InputStreamReader(speciesCon.getInputStream()));\n                String speciesInputLine;\n                StringBuffer speciesResponse = new StringBuffer();\n\n                while ((speciesInputLine = speciesIn.readLine()) != null) {\n                    speciesResponse.append(speciesInputLine);\n                }\n                speciesIn.close();\n\n                JsonReader speciesJsonReader = Json.createReader(new StringReader(speciesResponse.toString()));\n                JsonObject speciesJsonObject = speciesJsonReader.readObject();\n\n                String evolutionChainUrl = speciesJsonObject.getJsonObject(\"evolution_chain\").getString(\"url\");\n                System.out.println(\"Cadena de evoluciones: \" + evolutionChainUrl);\n            } else {\n                System.out.println(\"Error: \" + speciesResponseCode);\n            }\n\n            JsonArray games = jsonObject.getJsonArray(\"game_indices\");\n            System.out.println(\"Juegos: \");\n            for (int i = 0; i < games.size(); i++) {\n                JsonObject gameIndexObject = games.getJsonObject(i);\n                JsonObject versionObject = gameIndexObject.getJsonObject(\"version\");\n                System.out.println(\"  - \" + versionObject.getString(\"name\"));\n            }\n        } else {\n            System.out.println(\"Error: \" + responseCode);\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/javascript/7R0N1X.js",
    "content": "const peticion = async () => {\n  const response = await fetch('https://tronix-portfolio.vercel.app')\n  if (response.ok) {\n    const data = await response.text()\n    console.log(data)\n  }\n}\n\n// peticion()\n\n// DIFICULTAD EXTRA\nconst obtenerInfoPokemon = async (pokemon) => {\n  const response = await fetch(`https://pokeapi.co/api/v2/pokemon/${pokemon}`)\n  if (response.ok) {\n    const { id, forms: [{ name }], weight, height, types, game_indices } = await response.json()\n    return {\n      id, name, height, weight, types, game_indices\n    }\n  }\n}\n\nconst mostrarInformacion = async (pokemon) => {\n  const response = await obtenerInfoPokemon(pokemon)\n  const { id, name, weight, height, types, game_indices } = response\n  const tipos = types.map(type => type.type.name)\n  const juegos = game_indices.map(juego => juego.version.name)\n\n  console.log(`\n    ID: ${id}\n    Nombre: ${name}\n    Altura: ${height}\n    Peso: ${weight}\n    Tipo(s): ${tipos}\n    Juegos: ${juegos}\n    `)\n}\n\nmostrarInformacion(1)\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/javascript/AChapeton.js",
    "content": "const baseURL = 'https://pokeapi.co/api/v2/pokemon'\n\nconst getData = async (number) => {\n  try{\n    const res = await fetch(`${baseURL}/${number}`)\n    const data = await res.json()\n    \n    console.log('Name: ', data.name)\n    console.log('ID: ', data.id)\n    console.log('Weight: ', data.weight)\n    console.log('Height: ', data.height)\n\n    const types = data.types.map(type => type.type.name)\n    console.log('Types: ', types)\n\n    const games = data.game_indices.map(game => game.version.name)\n    console.log('Games: ', games)\n  }catch(error){\n    console.log(error)\n  }\n}\n\ngetData(9)"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/javascript/ArticKun.js",
    "content": "\n// ⚡ PETICIONES HTTP\n\nconst url = 'https://jsonplaceholder.typicode.com/todos/1';\n\nfetch(url)\n    .then( (response) =>  {\n        if (!response.ok) {\n            throw new Error('NETWORK RESPONSE ERROR');\n        }\n        return response.json();\n    })\n    .then( data => console.log(data) )\n    .catch( error => console.log(error) );\n\n\n/*\n\nDIFICULTAD EXTRA (opcional):\n     Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n     terminal al que le puedas solicitar información de un Pokémon concreto\n     utilizando su nombre o número.\n     - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n     - Muestra el nombre de su cadena de evoluciones\n     - Muestra los juegos en los que aparece\n     - Controla posibles errores\n\n*/\n\n    const URL = 'https://pokeapi.co/api/v2/pokemon';\n\n    const catchPokemon = async ( number ) => {\n    \n      try{\n        const res  = await fetch(`${URL}/${number}`)\n        const data = await res.json()\n    \n        console.log( data ); // verificar la respuesta\n    \n        const{ name, id, weight, height, types, game_indices } = data\n    \n        console.log( 'Nombre :' , name );\n        console.log( 'ID     :' , id );\n        console.log( 'Peso   :' , weight );\n        console.log( 'Altura :' , height );\n    \n        const [ type ] = types\n        console.log( 'Tipo   :' , type.type.name );\n    \n        console.log( 'Games  :' );\n        game_indices.forEach( game => {\n          console.log( game.version.name );\n        });\n        \n    \n      }catch( error ){\n        console.log( error );\n      }\n    \n    };\n    \n    catchPokemon( 6 );"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/javascript/Chrisdev00.js",
    "content": "// * EJERCICIO:\n// * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n// * una petición a la web que tú quieras, verifica que dicha petición\n// * fue exitosa y muestra por consola el contenido de la web.\n// *\n// * DIFICULTAD EXTRA (opcional):\n// * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n// * terminal al que le puedas solicitar información de un Pokémon concreto\n// * utilizando su nombre o número.\n// * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n// * - Muestra el nombre de su cadena de evoluciones\n// * - Muestra los juegos en los que aparece\n// * - Controla posibles errores\n\nfetch (\"https://dummyapi.io/data/v1/user/\", {\n    headers: {\n        \"app-id\": \"62b0433d2dfd91d4bf56c584\"\n    }\n})\n.then(response => {\n    if (response.ok) {\n        return response.json();\n    }else{\n        throw new Error(\"La solicitud no fue exitosa codigo de estado.\" + response.status);\n    }\n})\n.then(data => {\n    var result = data.data[0];\n    console.log(result);\n})\n.catch(error => {\n    console.error(\"Error\", error);\n})\n\n\n///////---------------------------------- EXTRA ---------------------------------------- /////////////\n\nconst fetch = require('node-fetch');\nconst { type } = require('os');\nconst readline = require('readline');\n\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout\n});\n\n\nfunction capitalize(str) {\n    if (!str) return str; \n    return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();\n}\n\n// Funcion para encontrar la cadena de evolucion\n\nconst getEvolutionChain = async(speciesUrl) => {\n    try {\n        const speciesResponse = await fetch(speciesUrl);\n        if (!speciesResponse.ok) throw new Error(`Error al obtener species: ${speciesResponse.status}`);\n        const speciesData = await speciesResponse.json();\n        const evolutionChainUrl = speciesData.evolution_chain.url;\n\n        const evolutionResponse = await fetch(evolutionChainUrl);\n        if (!evolutionResponse.ok) throw new Error(`Error al obtener la cadena de evolución: ${evolutionResponse.status}`);\n        const evolutionData = await evolutionResponse.json();\n\n        const evolutionNames = [];\n        let currentEvolution = evolutionData.chain;\n\n        while(currentEvolution){\n            evolutionNames.push(capitalize(currentEvolution.species.name));\n            currentEvolution = currentEvolution.evolves_to[0];\n        }\n\n        return evolutionNames;\n\n    } catch(error){\n        console.error(\"Error:\", error);\n    }\n}\n\n\n// Preguntar al usuario por el ID o nombre del Pokémon\n\nrl.question(\"Por favor, introduce el ID o nombre del Pokémon: \", async (idOrName) => {\n  try{\n    const response = await fetch(`https://pokeapi.co/api/v2/pokemon/${idOrName}`);\n    if (!response.ok) throw new Error(`La solicitud no fue exitosa. Código de estado: ${response.status}`);\n\n    const data = await response.json();\n\n    const {name, id, weight, height, types, species, game_indices} = data;\n    const typesNames = types.map(typeInfo => capitalize(typeInfo.type.name));\n    const gameNames = game_indices.map(game => capitalize(game.version.name));\n\n    const evolutionChain = await getEvolutionChain(species.url);\n\n    console.log(`Nombre del pokemon: ${capitalize(name)}`);\n    console.log(`Id del pokemon: ${id}`);\n    console.log(`Peso del pokemon: ${weight}`);\n    console.log(`Altura del pokemon: ${height}`);\n    console.log(`Tipo de pokemon: ${typesNames.join(', ')}`);\n    console.log(`Cadena de evolucion: ${evolutionChain.join(' -> ')}`);\n    console.log(`Juegos en los que aparece: ${gameNames.join(', ')}`);\n\n  }catch(error){\n    console.error(\"Error:\", error);\n  }finally{\n    rl.close();\n  }\n});"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/javascript/DavidMoralesDeveloper.js",
    "content": "const apiPokemon = \"https://pokeapi.co/api/v2/pokemon\";\n\n// async function callApi(url) {\n//   try {\n//     const res = await fetch(url);\n//     const data = await res.json();\n//     console.log(data);\n//     console.log('llamado de api')\n//   } catch (error) {\n//     console.log(error)\n//   }\n// }\n// getAPokemon()\n\n// callApi(apiPokemon);\n\n// -------- extra\n// * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n//  * terminal al que le puedas solicitar información de un Pokémon concreto\n// * utilizando su nombre o número.\n// * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n// * - Muestra el nombre de su cadena de evoluciones\n// * - Muestra los juegos en los que aparece\n// * - Controla posibles errores\n\nasync function getAPokemon(num) {\n  try {\n    const res = await fetch(`https://pokeapi.co/api/v2/pokemon/${num}`);\n    const data = await res.json();\n    console.log(\"el nombre de mi pokemon es : \" + data.name);\n    console.log(\"el id de mi pokemon es : \" + data.id);\n    console.log(\"el peso de mi pokemon es : \" + data.weight);\n    const typesPokemon = data.types.map((tipe) => tipe.type.name);\n    console.log(\"Tipos : \" + typesPokemon);\n    const games = data.game_indices.map((game) => game.version.name);\n    console.log(\"Juegos: \", games);\n    // console.log(data.evolution_chain.url) undefined\n    // ---------------------------\n    const res1 = await fetch(\n      `https://pokeapi.co/api/v2/pokemon-species/${num}`\n    );\n    const data1 = await res1.json();\n    const res2 = await fetch(data1.evolution_chain.url);\n    const data2 = await res2.json();\n    const chain = data2.chain\n\n    function getElvolves (chain) {\n      console.log(chain[\"species\"][\"name\"] + ' : evoluciona a ')\n      if(chain.evolves_to[0] === undefined){\n        console.log( 'No tiene evoluciones')\n      }else{\n        for (const evol of chain.evolves_to) {\n          getElvolves(evol)\n\n        }\n        \n      }\n    }\n\n    getElvolves(chain)\n\n    // console.log(chain.evolves_to[0].species.name)\n    // console.log(chain.evolves_to[0].evolves_to[0].species.name)\n     \n    \n  } catch (error) {\n    console.error(\"Error al obtener el Pokémon:\", error);\n  }\n}\n//numero de 1 al 1302\ngetAPokemon(1);\ngetAPokemon(132);\n\n\n// https://pokeapi.co/api/v2/evolution-chain/1/\n\n// {\n//\n//     \"chain\":\n//    {\n//\n//\n//           \"evolves_to\": [\n//             {\n//\n//\n//               \"is_baby\": false,\n//               \"species\": {\n//                 \"name\": \"venusaur\",\n//                 \"url\": \"https://pokeapi.co/api/v2/pokemon-species/3/\"\n//               }\n//             }\n//           ],\n//           \"is_baby\": false,\n//           \"species\": {\n//             \"name\": \"ivysaur\",\n//             \"url\": \"https://pokeapi.co/api/v2/pokemon-species/2/\"\n//           }\n//         }\n//       ],\n//       \"is_baby\": false,\n//       \"species\": {\n//         \"name\": \"bulbasaur\",\n//         \"url\": \"https://pokeapi.co/api/v2/pokemon-species/1/\"\n//       }\n//     },\n//     \"id\": 1\n//   }\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/javascript/Deyvid-10.js",
    "content": "// Peticiones HTTP\n\nfetch(\"https://www.youtube.com/\")\n.then(salida => {\n    console.log(`Codigo estado HTTP: ${salida.status}`)\n    fetch(\"https://www.youtube.com/\")\n    .then(res => res.text())\n    .then(salida => {\n    console.log(`Contenido:`)\n    console.log(salida);\n    })\n    .catch(error => console.error(error))\n})\n.catch(error => console.error(error))\n\n// DIFICULTAD EXTRA\n\nfunction pokemon(id_Nombre)\n{\n    fetch(`https://pokeapi.co/api/v2/pokemon/${id_Nombre}`)\n    .then(res => res.json())\n    .then(salida => {\n        console.log(`Nombre: ${salida.forms[0].name}`);\n        console.log(`Id: ${salida.id}`);\n        console.log(`Altura: ${salida.height}`);\n        console.log(`Peso: ${salida.weight} libras`);\n\n        let tipos = []\n\n        for (let t of salida.types) \n        {\n            tipos.push(t.type.name)\n        }\n\n        console.log(`Tipo(s): ${tipos}`);\n\n        let juegos = []\n\n        for (let g of salida.game_indices) \n        {\n            juegos.push(`Pokemon ${g.version.name}`)\n        }\n\n        console.log(`Juegos: ${juegos}`);\n    })\n    .catch(error => console.error(error))\n\n    fetch(`https://pokeapi.co/api/v2/pokemon-species/${id_Nombre}`)\n    .then(res => res.json())\n    .then(salida => {\n        fetch(salida.evolution_chain.url)\n        .then(res => res.json())\n        .then(salida => {\n            console.log(\"Cadena de evolucion:\");\n            console.log(\"-\" + salida.chain.species.name);\n\n            let cadenaEvolutiva = salida.chain\n\n           function evolucion(cadena)\n           {\n                if(\"evolves_to\" in cadena && cadena.evolves_to.length != 0)\n                {   \n                    for (let c of cadena.evolves_to) \n                    {\n                        console.log(\"-\" + c.species.name);\n                        evolucion(c)\n                    }\n                }\n           }\n\n           evolucion(cadenaEvolutiva)\n\n        })\n        .catch(error => console.error(error))\n    })\n    .catch(error => console.error(error))\n}\n\n// pokemon(\"charmander\")\n// pokemon(\"eevee\")\n// pokemon(\"poliwhirl\")\n// pokemon(\"wurmple\")\n// pokemon(\"ralts\")\n// pokemon(\"slowpoke\")"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #20 - JavaScript ->Jesus Antonio Escamilla */\n\nconst { error } = require(\"console\");\n\n/**\n * HTTP define un conjunto de métodos de petición para indicar la acción que se desea realizar para un recurso determinado.\n * La API Fetch proporciona una interfaz JavaScript para acceder y manipular partes del canal HTTP, tales como peticiones y respuestas.\n */\n\n//---EJERCIÓ---\n// URL donde se utilizara las peticiones\nconst url = 'https://jsonplaceholder.typicode.com/posts/1';\n\n// Realizaron las peticiones HTTP\nfetch(url)\n    .then(response => {\n        // Se checa la petición que se sea => 200 - OK\n        if (!response.ok) {\n            throw new Error('La respuesta de NETWORK no fue correcta' + response.statusText);\n        }\n        return response.json();\n    })\n    .then(data => {\n        // Se muestra los datos de la url\n        // console.log(data);\n    })\n    .catch(error => {\n        console.error('Hubo un error con la peticiones fetch:', error);\n    });\n\n\n\n/**-----DIFICULTAD EXTRA-----*/\n\n//  Se requiere esto para leer en la consola\nconst readline = require('node:readline');\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout,\n});\nconst baseURL = 'https://pokeapi.co/api/v2/pokemon';\nconst namePokemon = (texto) => {\n    if (!isNaN(parseInt(texto))) {\n        return texto;\n    }\n    return texto.toLowerCase();\n}\n\n//  El sistema Pokemon, \"Pokedex\"\nconst Pokedex = async (pokemon) => {\n    try {\n        //  URL del PokéAPI\n        const response = await fetch(`${baseURL}/${namePokemon(pokemon)}`);\n        if (!response.ok) {\n            throw new Error('La respuesta de NETWORK no fue correcta: ' + response.statusText);\n        }\n        const pokemonData = await response.json();\n\n        //  Se recorre los datos\n        const { id, name, weight, height, types } = pokemonData;\n        const typeNames = types.map(typeInfo => typeInfo.type.name);\n\n        //  Se muestra los datos\n        console.log(`Nombre: ${name}`);\n        console.log(`ID: ${id}`);\n        console.log(`Peso: ${weight}`);\n        console.log(`Altura: ${height}`);\n        console.log(`Tipo(s): ${typeNames.join(', ')}`);\n\n        //  Encontramos la especie del Pokemon\n        const speciesResponse = await fetch(pokemonData.species.url);\n        if (!speciesResponse.ok) {\n            throw new Error('La respuesta de NETWORK no fue correcta' + response.statusText);\n        }\n        const speciesData = await speciesResponse.json();\n        \n        //  Obteniendo la cadena de evolución\n        const evolutionResponse = await fetch(speciesData.evolution_chain.url);\n        if (!evolutionResponse.ok) {\n            throw new Error('La respuesta de NETWORK no fue correcta' + response.statusText);\n        }\n        const evolutionData = await evolutionResponse.json();\n\n        //  Se muestro la evolución del pokemon\n        const evolutionNames = [];\n        let currentEvolution = evolutionData.chain;\n        do {\n            evolutionNames.push(currentEvolution.species.name);\n            currentEvolution = currentEvolution.evolves_to[0];\n        } while (currentEvolution);\n        console.log(`Cadena de evoluciones: ${evolutionNames.join(' -> ')}`);\n\n        //  En los juegos que se encuentra\n        const gameIndices = pokemonData.game_indices.map(gameIndex => gameIndex.version.name);\n        console.log(`Aparece en los juegos: ${gameIndices.join(', ')}`);\n\n    } catch (error) {\n        console.error('Se encontró error:', error);\n    }\n};\n\nrl.question('¿Nombre o Numero de Pokemon? ', nameNumber => {\n    Pokedex(nameNumber);\n    rl.close();\n});\n\n/**-----DIFICULTAD EXTRA-----*/"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/javascript/RaulDoezon.js",
    "content": "// https://kinsta.com/es/base-de-conocimiento/javascript-peticion-http/\n// https://lenguajejs.com/javascript/peticiones-http/ajax/\n\n/*\n  EJERCICIO:\n  Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n  una petición a la web que tú quieras, verifica que dicha petición\n  fue exitosa y muestra por consola el contenido de la web.\n*/\n\nfetch(\"https://digi-api.com/api/v1/digimon/202\")\n  .then((response) => {\n    return response.ok ? response.json() : Promise.reject(response);\n  })\n  .then((json) => {\n    console.log(\"+++++++++ PETICIÓN DE EJEMPLO +++++++++\");\n    console.log(\"La petición fue exitosa. Se muestra la información obtenida sobre ¡WAR GREYMON!\");\n    console.log(json);\n  })\n  .catch((error) => {\n    console.log(error);\n  });\n/*\n  DIFICULTAD EXTRA (opcional):\n  Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n  terminal al que le puedas solicitar información de un Pokémon concreto\n  utilizando su nombre o número.\n  - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n  - Muestra el nombre de su cadena de evoluciones\n  - Muestra los juegos en los que aparece\n  - Controla posibles errores\n*/\n\nasync function getData(id) {\n  try {\n    let response = await fetch(`https://pokeapi.co/api/v2/pokemon/${id}`);\n    let information = await response.json();\n\n    console.log(\"\\n+++++++++ POKÉAPI +++++++++\");\n    console.log(information);\n\n    console.log(`NAME: ${information.name}`);\n    console.log(`ID: ${information.id}.`);\n    console.log(`HEIGHT: ${information.height}.`);\n    console.log(\"TYPE(S):\");\n\n    for (const type of information.types) {\n      console.log(`- ${type.type.name}.`);\n    }\n\n    console.log(\"VIDEO GAMES:\");\n\n    for (const games of information.game_indices) {\n      console.log(`- ${games.version.name}.`);\n    }\n  } catch (error) {\n    console.log(error);\n  }\n\n  try {\n    let speciesResponse = await fetch(`https://pokeapi.co/api/v2/evolution-chain/${id}`);\n    let pokemonSpecies = await speciesResponse.json();\n\n    console.log(`ESPECIES:`);\n\n    function allEvolutions(evolution) {\n      if (\"evolves_to\" in evolution) {\n        for (const evolve of evolution.evolves_to) {\n          console.log(`- ${evolve.species.name}`);\n\n          return allEvolutions(evolve);\n        }\n      }\n    }\n\n    allEvolutions(pokemonSpecies.chain);\n  } catch (error) {\n    \n  }\n}\n\nconst whatPokemon = prompt(\"Por favor, ingresa el ID del Pokémon que quieres revisar:\");\n\nasync function getPokemon() {\n  switch (whatPokemon) {\n    case '':\n      alert(\"Debes ingresar un número.\");\n      break;\n  \n    default:\n      await getData(whatPokemon);\n      break;\n  }\n}\n\ngetPokemon();\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/javascript/RicJDev.js",
    "content": "//EJERCICIO\nfunction getAbradolfLincler() {\n\tlet url = 'https://rickandmortyapi.com/api/character/7';\n\tfetch(url)\n\t.then((response) => response.json())\n\t.then((data) => {\n\t\tconsole.log(data);\n\t})\n\t.catch((error) => console.log(error));\n}\n\n//EXTRA\nconst readline = require('readline');\nconst rl = readline.createInterface({\n\tinput: process.stdin,\n\toutput: process.stdout,\n});\n\nasync function getPokeData(id) {\n\tlet baseUrl = 'https://pokeapi.co/api/v2/pokemon/';\n\tlet speciesUrl;\n\tlet chainUrl;\n\n\ttry {\n\t\tawait fetch(`${baseUrl}/${id.toLowerCase()}`)\n\t\t\t.then((response) => response.json())\n\t\t\t.then((data) => {\n\t\t\t\tconsole.log(`\\nName: ${data.name}`);\n\t\t\t\tconsole.log(`Id: ${data.id}`);\n\t\t\t\tconsole.log(`Weight: ${data.weight}`);\n\t\t\t\tconsole.log(`Height: ${data.height}`);\n\t\t\t\tconsole.log(`Type: ${data.types.map((type) => type.type.name)}`);\n\t\t\t\tconsole.log('Games: ');\n\t\t\t\tlet gamesArr = data.game_indices.map((game) => game.version.name);\n\t\t\t\tgamesArr.forEach((element) => {\n\t\t\t\t\tconsole.log(`* ${element}`);\n\t\t\t\t});\n\t\t\t\tspeciesUrl = data.species.url;\n\t\t\t});\n\n\t\tawait fetch(speciesUrl)\n\t\t\t.then((response) => response.json())\n\t\t\t.then((data) => {\n\t\t\t\tchainUrl = data.evolution_chain.url;\n\t\t\t});\n\n\t\tawait fetch(chainUrl)\n\t\t\t.then((response) => response.json())\n\t\t\t.then((data) => {\n\t\t\t\tlet evolves = data.chain.evolves_to;\n\t\t\t\tlet first = data.chain.species;\n\t\t\t\tlet second = evolves.map((name) => name.species.name);\n\t\t\t\tlet third = evolves[0].evolves_to.map((name) => name.species.name);\n\t\t\t\tconsole.log(`Evolution chain:\\n${first.name} => ${second} => ${third}`);\n\t\t\t});\n\t} catch (err) {\n\t\tconsole.log(`\\nHa ocurrido un error: ${err}`);\n\t}\n}\n\nfunction requestPokemon() {\n\trl.question(\n\t\t'\\nIngrese la ID o el nombre de su pokemon. Enter para salir\\n',\n\t\tasync (id) => {\n\t\t\tswitch (id) {\n\t\t\t\tcase '':\n\t\t\t\t\tconsole.log('Cerrando aplicación...');\n\t\t\t\t\trl.close();\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tawait getPokeData(id);\n\t\t\t\t\trequestPokemon();\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t);\n}\n\nrequestPokemon();\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/javascript/Sac-Corts.js",
    "content": "const id = 10;\nconst urljson = `https://jsonplaceholder.typicode.com/posts/${id}`;\n\nfetch(urljson)\n  .then(response => {\n    if (!response.ok) {\n      throw new Error(\"Request error: \" + response.status);\n    }\n    return response.json();\n  })\n  .then(data => {\n    console.log(data);\n  })\n  .catch(error => {\n    console.error(\"There was a problem with the request Fetch:\", error);\n  });\n\n// Extra Exercise //\n\nasync function getPokemonInfo(pokemon) {\n    try {\n        const response = await fetch(`https://pokeapi.co/api/v2/pokemon/${pokemon.toLowerCase()}`);\n        const pokemonData = await response.json();\n\n        console.log('Pokemon data:', pokemonData.forms[0][\"name\"]);\n\n        console.log('Name:', pokemonData.name);\n\n        console.log('ID:', pokemonData.id);\n\n        console.log('Weight:', pokemonData.weight);\n\n        console.log('Height:', pokemonData.height);\n\n        console.log('Types:');\n        pokemonData.types.forEach(type => {\n            console.log('-', type.type.name);\n        });\n\n        const speciesResponse = await fetch(pokemonData.species.url);\n        const speciesData = await speciesResponse.json();\n        const evolutionChainUrl = speciesData.evolution_chain.url;\n        const evolutionChainResponse = await fetch(evolutionChainUrl);\n        const evolutionChainData = await evolutionChainResponse.json();\n\n        console.log('Evolution chain:');\n        let evolutionChain = evolutionChainData.chain;\n        while (evolutionChain) {\n            console.log('-', evolutionChain.species.name);\n            evolutionChain = evolutionChain['evolves_to'][0];\n        }\n\n        console.log('Games in which it appears:');\n        pokemonData.game_indices.forEach(game => {\n            console.log('-', game.version.name);\n        });\n\n    } catch (error) {\n        console.error('Error:', error.message);\n    }\n}\n\nconst pokemon = '3'; \ngetPokemonInfo(pokemon);\n\n// Thanks to cesar-ch"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/javascript/adrs1166ma.js",
    "content": "/* 🔥 EJERCICIO:\nUtilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\nuna petición a la web que tú quieras, verifica que dicha petición\nfue exitosa y muestra por consola el contenido de la web.\n*/\n// Fetch API con Promises - No requeriere de una funcion\nconst url = 'https://jsonplaceholder.typicode.com/comments'\n\n\n// status : 200 , quiere decir que Si lo encontro\n// status : 404 , quiere decir que No lo encontro\nfetch(url)\n    .then((response) => {\n        if(response.ok){\n            return response.json()\n        }\n        throw new Error('Hubo un error...') // el error para al CATCH\n    })\n    .then(data=>{\n        console.log(data)\n    })\n    // Captura si hay error de red.\n    // ejm: no hay conexion a wifi\n    .catch(error => {\n        console.log(error.message)\n    })\n    \n    // en flecha\n    // .then(data=> console.log(data))\n    // .catch(error => console.log(error.message))\n    \n// (500) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, …]\n\n\n\n/*🔥 DIFICULTAD EXTRA (opcional): ------------------------------------------------------------------------------------------------------------------------------------\nUtilizando la PokéAPI (https://pokeapi.co), crea un programa por\nterminal al que le puedas solicitar información de un Pokémon concreto\nutilizando su nombre o número.\n- Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n- Muestra el nombre de su cadena de evoluciones\n- Muestra los juegos en los que aparece\n- Controla posibles errores\n*/\n\n// Función para obtener información de un Pokémon usando fetch\nfunction obtenerInfoPokemon(nombreOId) {\n    const url = `https://pokeapi.co/api/v2/pokemon/${nombreOId}`;\n\n    fetch(url)\n        .then((response) => {\n            if (!response.ok) {\n                throw new Error(`Error ${response.status}: ${response.statusText}`);\n            }\n            return response.json();\n        })\n        .then(async (pokemon) => {\n            // Extraer información básica del Pokémon\n            const nombre = pokemon.name;\n            const id = pokemon.id;\n            const peso = pokemon.weight;\n            const altura = pokemon.height;\n            const tipos = pokemon.types.map(tipo => tipo.type.name);\n            const juegos = pokemon.game_indices.map(juego => juego.version.name);\n\n            // Consultar la cadena de evoluciones\n            const especieResponse = await fetch(pokemon.species.url);\n            if (!especieResponse.ok) {\n                throw new Error(`Error al obtener la especie del Pokémon.`);\n            }\n            const especie = await especieResponse.json();\n\n            const cadenaEvolucionesResponse = await fetch(especie.evolution_chain.url);\n            if (!cadenaEvolucionesResponse.ok) {\n                throw new Error(`Error al obtener la cadena de evoluciones.`);\n            }\n            const cadenaEvoluciones = await cadenaEvolucionesResponse.json();\n\n            const nombreCadenaEvoluciones = cadenaEvoluciones.chain.species.name;\n\n            // Mostrar la información\n            console.log(`Nombre: ${nombre}`);\n            console.log(`ID: ${id}`);\n            console.log(`Peso: ${peso}`);\n            console.log(`Altura: ${altura}`);\n            console.log(`Tipos: ${tipos.join(\", \")}`);\n            console.log(`Cadena de evoluciones: ${nombreCadenaEvoluciones}`);\n            console.log(`Juegos en los que aparece: ${juegos.join(\", \")}`);\n        })\n        .catch((error) => {\n            console.error(\"Ocurrió un error:\", error.message);\n        });\n}\n\n\nconst args = process.argv.slice(2);\nif (args.length === 0) {\n    console.log(\"Uso: node script.js <nombre_o_id>\");\n} else {\n    const nombreOId = args[0];\n    obtenerInfoPokemon(nombreOId);\n}\n// node nombreDeArchivo.js pikachu\n\n// Nombre: pikachu\n// ID: 25\n// Peso: 60\n// Altura: 4\n// Tipos: electric\n// Cadena de evoluciones: pichu\n// Juegos en los que aparece: red, blue, yellow, gold, silver, crystal, ruby, sapphire, emerald, firered, leafgreen, diamond, pearl, platinum, heartgold, soulsilver, black, white, black-2, white-2"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/javascript/agusrosero.js",
    "content": "/*\n * EJERCICIO:\n * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n * una petición a la web que tú quieras, verifica que dicha petición\n * fue exitosa y muestra por consola el contenido de la web.\n *\n */\nconst url = \"https://google.com\";\n\nfetch(url)\n  .then((response) => {\n    if (response.ok) {\n      return response.text();\n    } else {\n      throw new Error(\"Network response was not ok.\");\n    }\n  })\n  .then((data) => {\n    console.log(data);\n  })\n  .catch((error) => {\n    console.log(\"Error:\", error);\n  });\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n * terminal al que le puedas solicitar información de un Pokémon concreto\n * utilizando su nombre o número.\n * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n * - Muestra el nombre de su cadena de evoluciones\n * - Muestra los juegos en los que aparece\n * - Controla posibles errores\n */\nconst pokeapiUrl = \"https://pokeapi.co/api/v2\";\n\nconst getPokemon = async (name) => {\n  try {\n    const response = await fetch(`${pokeapiUrl}/pokemon/${name}`);\n    if (response.ok) {\n      const data = await response.json();\n      return data;\n    }\n  } catch (error) {\n    console.log(error);\n  }\n};\n\ngetPokemon(\"gengar\").then((data) => {\n  const dataApi = data;\n  const { name, weight, height, types } = dataApi;\n  console.log(\"Nombre: \" + name);\n  console.log(\"Id: \" + dataApi.id);\n  console.log(\"Peso: \" + weight);\n  console.log(\"Altura: \" + height);\n  console.log(\"Tipo: \" + types[0].type.name);\n\n  const games = [];\n  for (let i = 0; i < dataApi.game_indices.length; i++) {\n    games.push(dataApi.game_indices[i].version.name);\n  }\n  console.log(\"Juegos: \" + games);\n});\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/javascript/bernatcs.js",
    "content": "// ** EJERCICIO \n\nlet url = 'https://bernatcucarella.com'\n\nfetch(url)\n  .then(response => response.text())\n  .then(data => console.log(data))\n\n\n// ** DIFICULTAD EXTRA ** ----------------------------------------------------------------------------------------------------------------------------------------------------\n\n// const https = require('node:https');\n\n// function obtenerInfoPokemon(nombreONumero) {\n//   const url = `https://pokeapi.co/api/v2/pokemon/${nombreONumero.toLowerCase()}`;\n\n//   https.get(url, (response) => {\n//     let data = '';\n\n//     // Recibir los datos en trozos\n//     response.on('data', (chunk) => {\n//       data += chunk;\n//     });\n\n//     // Cuando se termina de recibir la respuesta\n//     response.on('end', () => {\n//       if (response.statusCode === 200) {\n//         try {\n//           const pokemon = JSON.parse(data);\n\n//           // Mostrar información del Pokémon\n//           console.log(`Nombre: ${pokemon.name}`);\n//           console.log(`ID: ${pokemon.id}`);\n//           console.log(`Peso: ${pokemon.weight} kg`);\n//           console.log(`Altura: ${pokemon.height * 10} cm`); // Altura en decímetros\n//           console.log(`Tipos: ${pokemon.types.map(type => type.type.name).join(', ')}`);\n\n//           // Obtener la cadena de evolución del Pokémon\n//           obtenerCadenaEvolucion(pokemon.species.url);\n//         } catch (error) {\n//           console.error('Error al parsear la respuesta JSON:', error.message);\n//         }\n//       } else {\n//         console.error(`Error al obtener información del Pokémon. Código de estado: ${response.statusCode}`);\n//       }\n//     });\n//   }).on('error', (error) => {\n//     console.error('Error al hacer la solicitud:', error.message);\n//   });\n// }\n\n// function obtenerCadenaEvolucion(speciesUrl) {\n//   https.get(speciesUrl, (response) => {\n//     let data = '';\n\n//     // Recibir los datos en trozos\n//     response.on('data', (chunk) => {\n//       data += chunk;\n//     });\n\n//     // Cuando se termina de recibir la respuesta\n//     response.on('end', () => {\n//       if (response.statusCode === 200) {\n//         try {\n//           const species = JSON.parse(data);\n//           const evolutionChainUrl = species.evolution_chain.url;\n\n//           // Obtener la cadena de evolución desde la URL de la cadena\n//           https.get(evolutionChainUrl, (response) => {\n//             let data = '';\n\n//             // Recibir los datos en trozos\n//             response.on('data', (chunk) => {\n//               data += chunk;\n//             });\n\n//             // Cuando se termina de recibir la respuesta\n//             response.on('end', () => {\n//               if (response.statusCode === 200) {\n//                 try {\n//                   const evolutionChain = JSON.parse(data);\n//                   const cadenaEvolucion = obtenerNombreCadenaEvolucion(evolutionChain.chain);\n//                   console.log(`Cadena de Evolución: ${cadenaEvolucion}`);\n//                 } catch (error) {\n//                   console.error('Error al parsear la cadena de evolución:', error.message);\n//                 }\n//               } else {\n//                 console.error(`Error al obtener la cadena de evolución. Código de estado: ${response.statusCode}`);\n//               }\n//             });\n//           }).on('error', (error) => {\n//             console.error('Error al hacer la solicitud de la cadena de evolución:', error.message);\n//           });\n\n//         } catch (error) {\n//           console.error('Error al parsear la respuesta JSON:', error.message);\n//         }\n//       } else {\n//         console.error(`Error al obtener información de la especie del Pokémon. Código de estado: ${response.statusCode}`);\n//       }\n//     });\n//   }).on('error', (error) => {\n//     console.error('Error al hacer la solicitud de la especie del Pokémon:', error.message);\n//   });\n// }\n\n// function obtenerNombreCadenaEvolucion(chain) {\n//   let cadena = '';\n//   let currentPokemon = chain.species.name;\n\n//   if (chain.evolves_to.length > 0) {\n//     cadena += currentPokemon + ' -> ';\n//     let nextChain = chain.evolves_to[0];\n//     while (nextChain) {\n//       cadena += nextChain.species.name + ' -> ';\n//       nextChain = nextChain.evolves_to[0];\n//     }\n//     cadena = cadena.slice(0, -4); // Eliminar el último ' -> '\n//   } else {\n//     cadena = currentPokemon;\n//   }\n\n//   return cadena;\n// }\n\n// // Capturar el nombre o número del Pokémon desde la línea de comandos\n// const nombreONumero = process.argv[2];\n\n// if (!nombreONumero) {\n//   console.error('Por favor, proporciona el nombre o número del Pokémon como argumento.');\n// } else {\n//   obtenerInfoPokemon(nombreONumero);\n// }"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/javascript/brahiams7.js",
    "content": "// * EJERCICIO:\n//  * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n//  * una petición a la web que tú quieras, verifica que dicha petición\n//  * fue exitosa y muestra por consola el contenido de la web.\n//  *\nconst pokemon={}\n\nfetch('https://pokeapi.co/api/v2/pokemon/1/')\n    .then(response=>response.json())\n    .then(data=>console.log(\"\"))\n    .catch(error=>console.log(error)\n    )\n\n// * DIFICULTAD EXTRA (opcional):\n// * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n// * terminal al que le puedas solicitar información de un Pokémon concreto\n// * utilizando su nombre o número.\n// * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n// * - Muestra el nombre de su cadena de evoluciones\n// * - Muestra los juegos en los que aparece\n// * - Controla posibles errores\n// *\n\n    async function getData(pokemonId){\n        const response = await fetch(`https://pokeapi.co/api/v2/pokemon/${pokemonId}/`);\n        const data = response.json()\n        return data\n}\n    async function showPokemon(pokemonId){\n        try {\n            const datos=await getData(pokemonId);\n            const tipos=datos.types.map(tipo=>tipo.type.name)\n            const juegos=datos.game_indices.map(juego=>juego.version.name)\n            console.log(`\n                Nombre: ${datos.name}\n                ID: ${datos.id} \n                Weight: ${datos.weight}\n                Height:${datos.height}\n                Tipos: ${tipos} \n                Juegos: ${juegos}`)\n        } catch (error) {\n            console.log(error);\n            \n        }\n        \n        }\n\n\nlet readline = require('readline')\nlet rl = readline.createInterface({ input: process.stdin, output: process.stdout });\nfunction findPokemon(){\n    rl.question('MENU\\n 1.Buscar pokemon\\n 2.Salir\\n',(answer)=>{\n        let ans=answer.trim().toLocaleLowerCase();\n        switch (ans) {\n            case \"1\":\n                rl.question(\"\\n Ingrese el id del pokemon: \",(answer)=>{\n                    let ans=answer\n                    showPokemon(ans)\n                    findPokemon()\n                })\n                break;\n            default:\n                rl.close()\n                break;\n        }\n    })\n}\nfindPokemon()"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/javascript/caterinarodriguezdev.js",
    "content": "/*\n * EJERCICIO:\n * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n * una petición a la web que tú quieras, verifica que dicha petición\n * fue exitosa y muestra por consola el contenido de la web.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n * terminal al que le puedas solicitar información de un Pokémon concreto\n * utilizando su nombre o número.\n * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n * - Muestra el nombre de su cadena de evoluciones\n * - Muestra los juegos en los que aparece\n * - Controla posibles errores\n */\n\nfetch(\"https://pokeapi.co/api/v2/pokemon/pikachu\")\n  .then((resp) => {\n    return resp.json();\n  })\n  .then((data) => {\n    console.log(data);\n  })\n  .catch((error) => {\n    console.error(\"Error fetching data:\", error);\n  });\n\nconst readline = require(\"readline\");\nconst rl = readline.createInterface(process.stdin, process.stdout);\n\nrl.question(\n  \"Dame el nombre de un Pokemon y te diré lo que sé de él -> \",\n  (resp) => {\n    const pokemon = resp;\n\n    fetch(`https://pokeapi.co/api/v2/pokemon/${pokemon}`)\n      .then((resp) => {\n        if (resp.status === 404) {\n          console.log(\"No se ha encontrado el nombre del pokemon\");\n          return;\n        }\n        return resp.json();\n      })\n      .then( async (data) => {\n        if (data != undefined) {\n          console.log(\n            `Nombre: ${data.name}, id: ${data.id}, peso: ${data.weight}, altura: ${data.height}`\n          );\n          console.log(\"Tipos:\");\n          data.types.forEach((type) => {\n            console.log(\"-\", type.type.name);\n          });\n          console.log('Juegos en los que aparece:');\n          data.game_indices.forEach(game => {\n              console.log('-', game.version.name);\n          });  \n\n          const speciesResponse = await fetch(data.species.url);\n          const speciesData = await speciesResponse.json();\n          const evolutionChainUrl = speciesData.evolution_chain.url;\n          const evolutionChainResponse = await fetch(evolutionChainUrl);\n          const evolutionChainData = await evolutionChainResponse.json();\n  \n          console.log('Cadena de evolución:');\n          let evolutionChain = evolutionChainData.chain;\n          while (evolutionChain) {\n              console.log('-', evolutionChain.species.name);\n              evolutionChain = evolutionChain['evolves_to'][0];\n          }\n        }\n      })\n      .catch((error) => {\n        console.error(\"Error fetching data:\", error);\n      });\n  }\n);\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/javascript/cesar-ch.js",
    "content": "/*\n    * 20 PETICIONES HTTP \n*/\n\n/*\n    * DIFICULTAD EXTRA\n*/\nasync function getPokemonInfo(pokemon) {\n    try {\n        const response = await fetch(`https://pokeapi.co/api/v2/pokemon/${pokemon.toLowerCase()}`);\n        const pokemonData = await response.json();\n\n        console.log('Datos del pokemon:', pokemonData.forms[0][\"name\"]);\n        // Nombre\n        console.log('Nombre:', pokemonData.name);\n\n        // ID\n        console.log('ID:', pokemonData.id);\n\n        // Peso\n        console.log('Peso:', pokemonData.weight);\n\n        // Altura\n        console.log('Altura:', pokemonData.height);\n\n        // Tipos\n        console.log('Tipos:');\n        pokemonData.types.forEach(type => {\n            console.log('-', type.type.name);\n        });\n\n        // Cadena de evolución\n        const speciesResponse = await fetch(pokemonData.species.url);\n        const speciesData = await speciesResponse.json();\n        const evolutionChainUrl = speciesData.evolution_chain.url;\n        const evolutionChainResponse = await fetch(evolutionChainUrl);\n        const evolutionChainData = await evolutionChainResponse.json();\n\n        console.log('Cadena de evolución:');\n        let evolutionChain = evolutionChainData.chain;\n        while (evolutionChain) {\n            console.log('-', evolutionChain.species.name);\n            evolutionChain = evolutionChain['evolves_to'][0];\n        }\n\n        // Juegos en los que aparece\n        console.log('Juegos en los que aparece:');\n        pokemonData.game_indices.forEach(game => {\n            console.log('-', game.version.name);\n        });\n\n    } catch (error) {\n        console.error('Error:', error.message);\n    }\n}\n\nconst pokemon = 'pikachu'; \ngetPokemonInfo(pokemon);\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/javascript/christian-jfr.js",
    "content": "// #20 PETICIONES HTTP\n\n/**\n * EJERCICIO:\n * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n * una petición a la web que tú quieras, verifica que dicha petición\n * fue exitosa y muestra por consola el contenido de la web.\n */\n\n// Usando modulos de nodejs\nimport https from 'node:https';\nconst URL = 'https://info.cern.ch/hypertext/WWW/TheProject.html';\n\nhttps\n\t.get(URL, (res) => {\n\t\tconst data = [];\n\t\tconst headerDate =\n\t\t\tres.headers && res.headers.date ? res.headers.date : 'no response date';\n\t\tconsole.log('Status Code:', res.statusCode);\n\t\tconsole.log('Date in Response header:', headerDate);\n\t\tres.on('data', (chunk) => {\n\t\t\tdata.push(chunk);\n\t\t});\n\t\tif (res.statusCode === 200) {\n\t\t\tres.on('end', () => {\n\t\t\t\tconst body = Buffer.concat(data).toString();\n\t\t\t\tconsole.log('Body:', body);\n\t\t\t});\n\t\t}\n\t})\n\t.on('error', (err) => {\n\t\tconsole.log('Error: ', err.message);\n\t});\n\n/**\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n * terminal al que le puedas solicitar información de un Pokémon concreto\n * utilizando su nombre o número.\n * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n * - Muestra el nombre de su cadena de evoluciones\n * - Muestra los juegos en los que aparece\n * - Controla posibles errores\n */\n\nimport readline from 'node:readline';\n\nconst rl = readline.createInterface({\n\tinput: process.stdin,\n\toutput: process.stdout,\n});\n\nconst API = 'https://pokeapi.co/api/v2/pokemon/';\nconst API_SPECIES = 'https://pokeapi.co/api/v2/pokemon-species/';\n\nrl.question('What pokemon do you want? ', (answer) => {\n\tconst reqPokemon = API + answer.toLowerCase();\n\tconst reqSpecies = API_SPECIES + answer.toLowerCase();\n\n\tgetPokemon(reqPokemon, answer);\n\tgetEvolChainURL(reqSpecies, answer);\n\n\trl.close();\n});\n\nfunction getPokemon(req, id) {\n\tfetch(req, { method: 'GET' })\n\t\t.then((response) => {\n\t\t\tif (response.status !== 200) {\n\t\t\t\tconsole.log(`${response.status} - ${id} isn't a pokemon`);\n\t\t\t\treturn null;\n\t\t\t} else {\n\t\t\t\tconsole.log('Status Code:', response.status);\n\t\t\t\treturn response.json();\n\t\t\t}\n\t\t})\n\t\t.then((data) => {\n\t\t\tif (data) {\n\t\t\t\tgetInfo(data);\n\t\t\t\tgetGames(data);\n\t\t\t}\n\t\t});\n}\n\nfunction getEvolChainURL(req, id) {\n\tfetch(req, { method: 'GET' })\n\t\t.then((response) => {\n\t\t\tif (response.status !== 200) {\n\t\t\t\tconsole.log(`${response.status} - ${id} isn't a pokemon species`);\n\t\t\t\treturn null;\n\t\t\t} else {\n\t\t\t\treturn response.json();\n\t\t\t}\n\t\t})\n\t\t.then((data) => {\n\t\t\tif (data) {\n\t\t\t\tshowEvolChain(data.evolution_chain.url);\n\t\t\t}\n\t\t});\n}\n\nfunction showEvolChain(data) {\n\tfetch(data, { method: 'GET' })\n\t\t.then((response) => {\n\t\t\tif (response.status !== 200) {\n\t\t\t\tconsole.log(`${response.status} something went wrong`);\n\t\t\t\treturn null;\n\t\t\t} else {\n\t\t\t\treturn response.json();\n\t\t\t}\n\t\t})\n\t\t.then((data) => {\n\t\t\tif (data) {\n\t\t\t\tconsole.log('Evolutions: ');\n\t\t\t\tsearchEvol(data.chain);\n\t\t\t}\n\t\t});\n}\n\nfunction searchEvol(chain) {\n\tconsole.log(chain.species.name);\n\tif (chain.evolves_to) {\n\t\tfor (let evo in chain.evolves_to) {\n\t\t\tsearchEvol(chain.evolves_to[evo]);\n\t\t}\n\t}\n}\n\nfunction getInfo(data) {\n\tconst { name, id, weight, height, types } = data;\n\tconst typesNames = types.map((type) => type.type.name).join(' - ');\n\tconsole.log(`Name: ${name}`);\n\tconsole.log(`ID: ${id}`);\n\tconsole.log(`Weight: ${weight}`);\n\tconsole.log(`Height: ${height}`);\n\tconsole.log(`Types: ${typesNames}`);\n}\n\nfunction getGames(data) {\n\tconst { game_indices } = data;\n\tconst games = game_indices.map((game) => game.version.name).join(', ');\n\tconsole.log(`Games: ${games}`);\n}\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/javascript/duendeintemporal.js",
    "content": "// #20 PETICIONES HTPP\n/*\n * EJERCICIO:\n * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n * una petición a la web que tú quieras, verifica que dicha petición\n * fue exitosa y muestra por consola el contenido de la web.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n * terminal al que le puedas solicitar información de un Pokémon concreto\n * utilizando su nombre o número.\n * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n * - Muestra el nombre de su cadena de evoluciones\n * - Muestra los juegos en los que aparece\n * - Controla posibles errores\n */\n// I use GPT for reference information.\n\nlet log = console.log;\n\nwindow.addEventListener('load', ()=>{\n    const body = document.querySelector('body');\n    const title = document.createElement('h1');\n    \n    body.style.setProperty('background', '#000');\n    body.style.setProperty('text-align', 'center');\n    \n    title.textContent = 'Retosparaprogramadores #20.';\n    title.style.setProperty('font-size', '3.5vmax');\n    title.style.setProperty('color', '#fff');\n    title.style.setProperty('line-height', '34vh');\n    \n    body.appendChild(title);\n    log( 'Retosparaprogramadores #20'); \n\n    /* LoremIpsum Paragraph Maker Visual Modal */\n\n    let modal = document.createElement('div');\n    modal.style.setProperty('position', 'relative');\n    modal.style.setProperty('top', '50%');\n    modal.style.setProperty('left', '50%');\n    modal.style.setProperty('transform', 'translate(-50%, -20%)');\n    modal.style.setProperty('background', 'rgba(0,0,0,0.2)');\n    modal.style.setProperty('width', '400px');\n    modal.style.setProperty('min-height', '200px');\n    // modal.style.setProperty('display', 'none');\n    document.body.appendChild(modal);\n    \n    let loremIpsumContainer = document.createElement('div');\n    loremIpsumContainer.style.setProperty('font-family', 'sans-serif');\n    loremIpsumContainer.style.setProperty('margin', '1rem');\n    modal.appendChild(loremIpsumContainer);\n\n    let label = document.createElement('label');\n    label.style.setProperty('padding', '10px');\n    label.style.setProperty('color', '#fff');\n    label.setAttribute('for', 'paragraphsCount');\n    let strong = document.createElement('strong');\n    strong.textContent = 'How many Paragraphs?';\n    loremIpsumContainer.appendChild(label);\n    label.appendChild(strong);\n    \n    let input = document.createElement('input');\n    input.setAttribute('type', 'number')\n    input.style.setProperty('width', '4rem');\n    input.setAttribute('min', '0');\n    input.classList.add('paragraphsCount');\n    loremIpsumContainer.appendChild(input);\n\n    let button = document.createElement('button');\n    button.style.setProperty('background', '#ff8c00');\n    button.style.setProperty('color', '#f6f6f6');\n    button.style.setProperty('padding', '5px');\n    button.style.setProperty('border-radius', '15px');\n    button.style.setProperty('text-align', 'center');\n    button.style.setProperty('margin-left', '10px');\n    button.textContent = 'Generate';\n    button.classList.add('getLoremIpsum');\n    loremIpsumContainer.appendChild(button);\n\n    let result = document.createElement('div');\n    result.style.setProperty('margin-top', '1rem')\n    result.style.setProperty('padding', '1rem');\n    result.style.setProperty('border', '1px dashed black');\n    result.style.setProperty('font-size', '.75rem');\n    result.style.setProperty('position', 'absolute');\n    result.style.setProperty('left', '-25%');\n    result.style.setProperty('width', '58vw');\n    result.style.setProperty('display', 'none');\n    result.classList.add('result');\n    loremIpsumContainer.appendChild(result);\n});\n\n\n/* LoremIpsum Paragraph Maker Funcionality */\n\nfunction getLoremIpsum(numberOfParagraphs){\n    fetch(`https://baconipsum.com/api/?type=meat-and-filler&paras=${numberOfParagraphs}`)\n        .then(response => response.json())\n        .then(loremIpsumTextArray => {\n            updateResult(loremIpsumTextArray);\n        })\n        .catch(error => {\n            showError(error);\n        });\n};\n\nfunction updateResult(textArray) {\n    const resultElement = document.querySelector('.result');\n    resultElement.classList.add('show');\n    resultElement.style.setProperty('display', '');\n    resultElement.innerHTML = '';\n    resultElement.innerHTML = textArray\n        .map(paragraph => `<p>${paragraph}</p>`)\n        .join('');\n    addCopyButton(textArray.join(''));\n\n    // Apply styles to the paragraphs immediately\n    const p_elements = document.querySelectorAll('.result p');\n    p_elements.forEach(p => {\n        p.style.setProperty('color', '#fff');\n        p.style.setProperty('line-height', '16px');\n        p.style.setProperty('text-align', 'justify');\n    });\n}\n\nfunction showError(error){\n     const resultElement = document.querySelector('.result');\n    resultElement.innerHTML = '';\n    resultElement.innerHTML = `<p class=\"error\">${error.message}</p>`\n}\n\nfunction addCopyButton(text){\n    const resultElement = document.querySelector('.result');\n    const copyBtn = document.createElement('button');\n\n    copyBtn.textContent = 'Copy';\n    copyBtn.classList.add('copy');\n    copyBtn.onclick = () => {\n        navigator.clipboard.writeText(text);\n        copyBtn.textContent = 'Copied!';\n        setTimeout(() => {\n            copyBtn.textContent = 'Copy';\n        }, 2000);\n    }\n\n    resultElement.appendChild(copyBtn);\n\n    setTimeout(()=> getPokemon(id = prompt('Please type a number id to get the pokemon data')), 2000)\n}\n\nsetTimeout(()=>{\n    const getLoremIpsumElement = document.querySelector('.getLoremIpsum');\n    const paragraphsCountElement = document.querySelector('.paragraphsCount');\n\n    getLoremIpsumElement.addEventListener('click', () => {\n        getLoremIpsum(parseInt(paragraphsCountElement.value));\n        paragraphsCountElement.value = '';\n\n    })\n}, 1000);\n    \n\n// Extra Dificulty Exercise\n\nlet pokemon;\nfunction getPokemon(id){\n    fetch(`https://pokeapi.co/api/v2/pokemon/${id}`)\n    .then((response)=> response.json())\n    .then((data)=> {\n        log(data);\n      ;\n        pokemon = {\n\t\t\t\tname: `Name: ${data.name}`,\n\t\t\t\tid: `Id: ${data.id}`,\n\t\t\t\tweight: `Weight: ${data.weight}`,\n\t\t\t\theight: `Height: ${data.height}`,\n\t\t\t\ttype: `Type: ${data.types.map(t => t.type.name).join(', ')}`,\n\t\t\t\tgames: `Games: ${data.game_indices.map(g => g.version.name).join(', ')}`,\n        }\n        log(pokemon);\n\n        let modal1 = document.createElement('div');\n        modal1.style.setProperty('position', 'relative');\n        modal1.style.setProperty('top', '50%');\n        modal1.style.setProperty('color', '#fff');\n        modal1.style.setProperty('left', '50%');\n        modal1.style.setProperty('transform', 'translate(-50%, -72%)');\n        modal1.style.setProperty('background', 'rgba(0,0,0,0.9)');\n        modal1.style.setProperty('width', '100vw');\n        modal1.style.setProperty('height', '100vh');\n        modal1.style.setProperty('display', 'flex');\n        modal1.style.setProperty('justify-content', 'center');\n        modal1.style.setProperty('align-items', 'center');\n        let modal2 = document.createElement('div');\n        modal2.style.setProperty('width', '80vw');\n        modal2.style.setProperty('height', '100vh');\n        modal2.style.setProperty('display', 'flex');\n        modal2.style.setProperty('justify-content', 'space-arround');\n        modal2.style.setProperty('align-items', 'flex-start');\n        modal2.style.setProperty('flex-direction', 'column');\n        let h1 = document.createElement('h1');\n            h1.textContent = `POKEMON`;\n            h1.style.setProperty('align-self', 'center');\n            h1.style.setProperty('font-family', 'cursive');\n            modal2.appendChild(h1);\n            modal1.appendChild(modal2);\n        document.body.appendChild(modal1);\n\n        for(let key in pokemon){\n            let p = document.createElement('p');\n            p.textContent = `${pokemon[key]}`;\n            p.style.setProperty('color', 'yellow');\n            p.style.setProperty('font-size', '2vw');\n            p.style.setProperty('font-weight', '600');\n            p.style.setProperty('font-family', 'cursive');\n            p.style.setProperty('text-align', 'justify');\n            modal2.appendChild(p);\n        }\n\n                // Function to remove the modal\n                const removeModal = () => {\n                    modal1.remove(); \n                    document.removeEventListener('keydown', handleKeyDown); // Clean up the event listener\n                };\n        \n                // Add event listener to remove the modal when clicked\n                modal2.addEventListener('click', removeModal);\n        \n                // Function to handle keydown events\n                const handleKeyDown = (event) => {\n                    if (event.key === \"Escape\") { // Check if the pressed key is \"Escape\"\n                        removeModal(); // Call the function to remove the modal\n                    }\n                };\n        \n                // Add event listener for keydown events\n                document.addEventListener('keydown', handleKeyDown);\n            })\n            .catch((error) => console.error('Error fetching Pokémon:', error));\n        }\n        \n//Note: is easy use a external css file an just add classes rather than adding prperty by property.\n/* By using CSS classes, your JavaScript code becomes cleaner and easier to manage, while your styles are centralized in a dedicated CSS file. This approach is generally recommended for larger projects or when working in teams. */"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/javascript/edalmava.js",
    "content": "async function peticionHTTP() {\n  try {\n    const respuesta = await fetch('https://edalmava.co')\n    if (respuesta.ok) {\n      const datos = await respuesta.text()\n      console.log(datos)\n    } else {\n      console.log(\"Respuesta de red OK pero respuesta HTTP no OK: \")\n    }\n  } catch(error) {\n    console.log(\"Hubo un problema con la petición Fetch:\" + error.message)\n  }\n}\n\nasync function buscarPokemon(name) {\n  try {  \n    const respuesta = await fetch(`https://pokeapi.co/api/v2/pokemon/${name}`)\n    if (respuesta.ok) {\n      const datos = await respuesta.json()\n      \n      const nombre = datos.name\n      const id = datos.id\n      const peso = datos.weight\n      const altura = datos.height\n      const tipos = datos.types.map(e => e.type.name).join(',')\n\n      console.log('Información del Pokémon: ')\n      console.log('Nombre: ', nombre)\n      console.log('ID: ', id)\n      console.log('Peso: ', peso)\n      console.log('Altura: ', altura)\n      console.log('Tipo(s): ', tipos)\n\n      const res_evolution_chain = await fetch(`https://pokeapi.co/api/v2/evolution-chain/${id}/`)\n      if (res_evolution_chain.ok) {\n        const datos_chain = await res_evolution_chain.json()\n        console.log('Cadena de Evolución: ', datos_chain)\n      }\n    } else { \n      console.log(\"Respuesta de red OK pero respuesta HTTP no OK: \")\n      if (respuesta.status === 404) {\n        console.log('Pokémon no encontrado')\n      } else {\n        console.log(respuesta.statusText)\n      }\n    }\n  } catch(error) {\n    console.log(\"Hubo un problema con la petición Fetch:\" + error.message)\n  }\n}\n\nasync function inicio() {\n  console.log('*****Petición HTTP al sitio https://edalmava.co*****')\n  await peticionHTTP()\n  console.log('****************************************************')\n  console.log('****************************************************')\n  console.log('*****RETO EXTRA*****')\n  const readline = require('node:readline');\n  const rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout,\n  });\n  rl.question(`¿Nombre o número del Pokémon a buscar? `, name => {\n    buscarPokemon(name)\n    rl.close();\n  });\n}\n\ninicio()"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/javascript/emedevelopa.js",
    "content": "/*Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n * una petición a la web que tú quieras, verifica que dicha petición\n * fue exitosa y muestra por consola el contenido de la web.*/\n\n// URL de la API pública\nconst url1 = 'https://jsonplaceholder.typicode.com/posts/1';\n\n// Hacer una petición GET utilizando fetch\nfetch(url1)\n    .then(response => {\n        // Verificar si la respuesta fue exitosa (código de estado en el rango 200-299)\n        if (!response.ok) {\n            throw new Error('Network response was not ok ' + response.statusText);\n        }\n        // Parsear la respuesta como JSON\n        return response.json();\n    })\n    .then(data => {\n        // Mostrar el contenido de la respuesta en la consola\n        console.log('Contenido de la web:', data);\n    })\n    .catch(error => {\n        // Manejar cualquier error que ocurra durante la petición\n        console.error('Hubo un problema con la petición fetch:', error);\n    });\n\n\n    /*Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n * terminal al que le puedas solicitar información de un Pokémon concreto\n * utilizando su nombre o número.\n * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n * - Muestra el nombre de su cadena de evoluciones\n * - Muestra los juegos en los que aparece\n * - Controla posibles errores\n */\n\nconst url = \"https://pokeapi.co/api/v2/pokemon\";\n\nconst getPokemon = async (number) => {\n    try{\n        const res  = await fetch(`${url}/${number}`)\n        const data = await res.json()\n    \n        console.log( data ); // verificar la respuesta\n    \n        const{ name, id, weight, height, types, game_indices } = data\n    \n        console.log( 'Nombre :' , name );\n        console.log( 'ID     :' , id );\n        console.log( 'Peso   :' , weight );\n        console.log( 'Altura :' , height );\n    \n        const [ type ] = types\n        console.log( 'Tipo   :' , type.type.name );\n    \n        console.log( 'Games  :' );\n        game_indices.forEach( game => {\n          console.log( game.version.name );\n        });\n        \n    \n      }catch( error ){\n        console.log( error );\n      }\n    \n    };\n    \n    getPokemon( 61 );\n\n\n\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/javascript/eugeniasoria.js",
    "content": "/*\r\n# #20 PETICIONES HTTP\r\n * EJERCICIO:\r\n * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\r\n * una petición a la web que tú quieras, verifica que dicha petición\r\n * fue exitosa y muestra por consola el contenido de la web.\r\n *\r\n * DIFICULTAD EXTRA (opcional):\r\n * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\r\n * terminal al que le puedas solicitar información de un Pokémon concreto\r\n * utilizando su nombre o número.\r\n * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\r\n * - Muestra el nombre de su cadena de evoluciones\r\n * - Muestra los juegos en los que aparece\r\n * - Controla posibles errores\r\n */\r\n\r\n\r\nasync function fetchSomething() {\r\n  console.log(\"Peticion cualquiera\");\r\n  const response = await fetch(\"https://jsonplaceholder.typicode.com/todos/1\");\r\n  const result = await response.json();\r\n  console.log(result);\r\n}\r\n\r\n/* DIFICULTAD EXTRA (opcional):\r\n* Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\r\n* terminal al que le puedas solicitar información de un Pokémon concreto\r\n* utilizando su nombre o número.\r\n* - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\r\n* - Muestra el nombre de su cadena de evoluciones\r\n* - Muestra los juegos en los que aparece\r\n* - Controla posibles errores\r\n*/\r\n\r\nasync function quienEsEsePokemon(pokemonName) {  \r\n  if (!pokemonName) {\r\n    error = new Error('Ingrese un nombre de Pokemon');\r\n    throw error;\r\n  }\r\n    \r\n  try {    \r\n    const response = await fetch(\"https://pokeapi.co/api/v2/pokemon/\" + pokemonName);\r\n    console.log(\"\\n\\nQuién es ese Pokemon?\")\r\n    const {name, id, weight, height, types, game_indices} = await response.json();\r\n    console.log(`Pokemon: ${name}`);\r\n    console.log(` >Id: ${id}`);\r\n    console.log(` >Peso: ${weight}`);\r\n    console.log(` >Altura: ${height}`);\r\n    console.log(` >Tipos: ${JSON.stringify(types)}`);    \r\n\r\n    const responseChain = await fetch(\"https://pokeapi.co/api/v2/pokemon-species/\" + id);\r\n    const {evolution_chain} = await responseChain.json();\r\n    \r\n    const responseEvolutionChain = await fetch(evolution_chain.url);\r\n    \r\n    const evolutionChain = await responseEvolutionChain.json();\r\n    console.log(\" >Cadena de evolucion: \", JSON.stringify(evolutionChain.chain));\r\n    console.log(\" >Juegos: \", game_indices);\r\n\r\n  } catch (error) {\r\n    console.error(error.message);\r\n  }    \r\n}      \r\n\r\n/*Ejecucion*/\r\nasync function main() {\r\n  await fetchSomething();\r\n  await quienEsEsePokemon('oshawott');  \r\n}\r\n\r\nmain()\r\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/javascript/eulogioep.js",
    "content": "// Se requiere el módulo 'node-fetch' para realizar peticiones HTTP en Node.js\n// Instalar con: npm install node-fetch\nconst fetch = require(\"node-fetch\");\nconst readline = require(\"readline\");\n\n/**\n * Teoría sobre peticiones HTTP en JavaScript:\n *\n * En JavaScript moderno, podemos realizar peticiones HTTP de varias formas:\n * 1. Fetch API (nativo en navegadores, requiere módulo en Node.js)\n * 2. XMLHttpRequest (método más antiguo)\n * 3. Bibliotecas como axios\n *\n * La Fetch API utiliza Promesas, lo que permite un código más limpio y\n * manejo asíncrono más sencillo usando async/await.\n *\n * Conceptos clave:\n * - async/await: Permite escribir código asíncrono que parece síncrono\n * - try/catch: Maneja errores en operaciones asíncronas\n * - JSON: Formato común para intercambiar datos en la web\n */\n\n// Configuración de readline para entrada/salida en consola\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout,\n});\n\n// Función para realizar preguntas al usuario y obtener respuesta\nconst pregunta = (pregunta) => {\n  return new Promise((resolve) => {\n    rl.question(pregunta, resolve);\n  });\n};\n\n// Función para realizar petición HTTP\nasync function hacerPeticionHttp(url) {\n  try {\n    const respuesta = await fetch(url);\n    if (!respuesta.ok) {\n      throw new Error(`HTTP error! status: ${respuesta.status}`);\n    }\n    return await respuesta.json();\n  } catch (error) {\n    throw new Error(`Error al realizar la petición: ${error.message}`);\n  }\n}\n\n// Función para mostrar la cadena de evolución\nfunction mostrarCadenaEvolucion(cadena, nivel = 0) {\n  const indentacion = \"  \".repeat(nivel);\n  console.log(`${indentacion}- ${cadena.species.name}`);\n\n  if (cadena.evolves_to.length > 0) {\n    for (const evolucion of cadena.evolves_to) {\n      mostrarCadenaEvolucion(evolucion, nivel + 1);\n    }\n  }\n}\n\n// Función principal que ejecuta el programa\nasync function main() {\n  console.log(\"=== Ejemplo básico de petición HTTP ===\");\n  try {\n    const ejemploData = await hacerPeticionHttp(\"https://www.example.com\");\n    console.log(\"Petición exitosa a example.com\");\n  } catch (error) {\n    console.error(error.message);\n  }\n\n  while (true) {\n    console.log(\"\\n=== Búsqueda de Pokémon ===\");\n    const entrada = await pregunta(\n      \"Ingrese el nombre o número del Pokémon (o 'salir' para terminar): \"\n    );\n\n    if (entrada.toLowerCase() === \"salir\") {\n      break;\n    }\n\n    try {\n      // Obtener datos básicos del Pokémon\n      const pokemonData = await hacerPeticionHttp(\n        `https://pokeapi.co/api/v2/pokemon/${entrada.toLowerCase()}`\n      );\n\n      console.log(\"\\nInformación del Pokémon:\");\n      console.log(`Nombre: ${pokemonData.name}`);\n      console.log(`ID: ${pokemonData.id}`);\n      console.log(`Peso: ${pokemonData.weight / 10} kg`);\n      console.log(`Altura: ${pokemonData.height / 10} m`);\n\n      console.log(\"Tipos:\");\n      pokemonData.types.forEach((tipo) => {\n        console.log(`- ${tipo.type.name}`);\n      });\n\n      // Obtener y mostrar cadena de evolución\n      const speciesData = await hacerPeticionHttp(pokemonData.species.url);\n      const evolutionData = await hacerPeticionHttp(\n        speciesData.evolution_chain.url\n      );\n\n      console.log(\"\\nCadena de evolución:\");\n      mostrarCadenaEvolucion(evolutionData.chain);\n\n      // Mostrar juegos\n      console.log(\"\\nJuegos en los que aparece:\");\n      pokemonData.game_indices.forEach((juego) => {\n        console.log(`- ${juego.version.name}`);\n      });\n    } catch (error) {\n      console.error(\n        \"Error: No se pudo encontrar el Pokémon. Asegúrese de escribir el nombre o número correctamente.\"\n      );\n    }\n  }\n\n  rl.close();\n}\n\n// Ejecutar el programa\nmain().catch(console.error);\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/javascript/garos01.js",
    "content": "// Utilizando fetch para realizar una petición HTTP\nfetch(\"https://jsonplaceholder.typicode.com/posts/5\")\n  .then((response) => {\n    // Verifica si la respuesta fue exitosa\n    if (!response.ok) {\n      throw new Error(\"Network response was not ok \" + response.statusText);\n    }\n    return response.text(); // Convierte la respuesta a texto\n  })\n  .then((data) => {\n    console.log(\"Contenido de la web:\", data); // Muestra el contenido en la consola\n  })\n  .catch((error) => {\n    console.error(\"Hubo un problema con la petición fetch:\", error); // Muestra el error en caso de que ocurra\n  });\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/javascript/hectorio23.js",
    "content": "// Autor: Héctor Adán \n// GitHub: https://github.com/hectorio23\n\n// Realiza una petición HTTP a un sitio web de ejemplo\nfetch('https://www.example.com')\n    .then(response => {\n        // Verifica si la respuesta es exitosa\n        if (!response.ok) {\n            // Lanza un error si la respuesta no es exitosa\n            throw new Error('Network response was not ok ' + response.statusText);\n        }\n        // Convierte la respuesta en texto\n        return response.text();\n    })\n    .then(data => {\n        // Muestra el contenido de la web en la consola\n        console.log(data);\n    })\n    .catch(error => {\n        // Maneja cualquier error que ocurra durante la petición\n        console.error('There was a problem with the fetch operation:', error);\n    });\n\n// Función para obtener datos de una URL dada\nasync function fetchData(url) {\n    try {\n        // Realiza la petición HTTP a la URL especificada\n        const response = await fetch(url);\n        // Verifica si la respuesta es exitosa\n        if (!response.ok) {\n            // Lanza un error si la respuesta no es exitosa\n            throw new Error(`Network response was not ok: ${response.statusText}`);\n        }\n        // Convierte y devuelve la respuesta en formato JSON\n        return await response.json();\n    } catch (error) {\n        // Maneja cualquier error que ocurra durante la petición\n        console.error('There was a problem with the fetch operation:', error);\n        return null;\n    }\n}\n\n// Función para imprimir los detalles del Pokémon\nasync function printPokemonDetails(pokemon) {\n    // Imprime el nombre, ID, altura y peso del Pokémon\n    console.log(`Name: ${pokemon.name}`);\n    console.log(`ID: ${pokemon.id}`);\n    console.log(`Height: ${pokemon.height}`);\n    console.log(`Weight: ${pokemon.weight}`);\n\n    // Imprime los tipos del Pokémon\n    console.log('Types:');\n    pokemon.types.forEach(type => {\n        console.log(`- ${type.type.name}`);\n    });\n\n    // Obtiene e imprime la cadena de evoluciones\n    const speciesData = await fetchData(pokemon.species.url);\n    if (speciesData) {\n        const evolutionChainUrl = speciesData.evolution_chain.url;\n        const evolutionData = await fetchData(evolutionChainUrl);\n        if (evolutionData) {\n            console.log('Evolution Chain:');\n            let currentEvolution = evolutionData.chain;\n            while (currentEvolution) {\n                console.log(`- ${currentEvolution.species.name}`);\n                currentEvolution = currentEvolution.evolves_to[0];\n            }\n        }\n    }\n\n    // Imprime los juegos en los que aparece el Pokémon\n    console.log('Games:');\n    pokemon.game_indices.forEach(game => {\n        console.log(`- ${game.version.name}`);\n    });\n}\n\n// Función principal\nasync function main() {\n    // Parte 1: Realizar una petición HTTP a un sitio web de ejemplo\n    try {\n        // Realiza la petición HTTP a la URL especificada\n        const exampleResponse = await fetch('https://www.example.com');\n        // Verifica si la respuesta es exitosa\n        if (!exampleResponse.ok) {\n            // Lanza un error si la respuesta no es exitosa\n            throw new Error(`Network response was not ok: ${exampleResponse.statusText}`);\n        }\n        // Convierte la respuesta en texto\n        const exampleData = await exampleResponse.text();\n        // Muestra el contenido de la web en la consola\n        console.log(exampleData);\n    } catch (error) {\n        // Maneja cualquier error que ocurra durante la petición\n        console.error('There was a problem with the fetch operation:', error);\n    }\n\n    // Parte 2: Interacción con la PokéAPI\n    // Solicita al usuario que ingrese el nombre o ID de un Pokémon\n    const pokemonNameOrId = prompt('Enter the name or ID of the Pokémon:');\n    // Construye la URL de la API utilizando el nombre o ID del Pokémon\n    const url = `https://pokeapi.co/api/v2/pokemon/${pokemonNameOrId}`;\n    // Obtiene los datos del Pokémon desde la API\n    const pokemonData = await fetchData(url);\n    if (pokemonData) {\n        // Imprime los detalles del Pokémon si los datos son válidos\n        await printPokemonDetails(pokemonData);\n    } else {\n        // Muestra un mensaje de error si no se pudieron obtener los datos del Pokémon\n        console.error('Error fetching Pokémon data. Please check the name or ID and try again.');\n    }\n}\n\n// Ejecuta la función principal\nmain();\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n_______________________________________\n#20 PETICIONES HTTP\n---------------------------------------\n * EJERCICIO:\n * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n * una petición a la web que tú quieras, verifica que dicha petición\n * fue exitosa y muestra por consola el contenido de la web.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n * terminal al que le puedas solicitar información de un Pokémon concreto\n * utilizando su nombre o número.\n * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n * - Muestra el nombre de su cadena de evoluciones\n * - Muestra los juegos en los que aparece\n * - Controla posibles errores\n*/\n// ________________________________________________________\n\nimport fetch from \"node-fetch\";\n\nasync function getUser(userId) {\n    try {\n        const url = `https://jsonplaceholder.typicode.com/users/${userId}`;\n        const response = await fetch(url);\n\n        if (response.ok) {\n            return await response.json();\n        } else {\n            console.log(`Id: ${userId} no encontrado`);\n            console.log(\"status_code: \", response.status);\n            return {};\n        }\n    } catch (error) {\n        console.error(\"Error de conexión:\", error.message);\n        return {};\n    }\n}\n\nfunction printUser(userData) {\n    if (Object.keys(userData).length > 0) {\n        console.log(`\\nUsuario con id: '${userData.id}':\\n` +\n            `Nombre:  ${userData.name}\\n` +\n            `Usuario: ${userData.username}\\n` +\n            `Email:   ${userData.email}\\n` +\n            `Teléfono: ${userData.phone}`);\n    }\n}\n\n// ________________________________________________________\n// DIFICULTAD EXTRA\n\nclass GetPokemon {\n    constructor() {\n        this.baseUrl = \"https://pokeapi.co/api/v2/pokemon/\";\n        this.pokemon = null;\n    }\n\n    async load(id) {\n        try {\n            const url = `${this.baseUrl}${id}`;\n            const response = await fetch(url);\n\n            if (!response.ok) {\n                throw new Error(`Pokémon '${id}' no encontrado (status: ${response.status})`);\n            }\n\n            this.pokemon = await response.json();\n            console.log(`\\nPokémon '${id}' ha sido cargado.`);\n        } catch (error) {\n            GetPokemon.handleExceptions(error);\n        }\n    }\n\n    info() {\n        if (!this.pokemon) {\n            console.log(\"El Pokémon aún no ha sido cargado.\");\n            return;\n        }\n\n        console.log(`Información Básica \\n` +\n            `* Id:      ${this.pokemon.id} \\n` +\n            `* Nombre:  ${this.pokemon.name} \\n` +\n            `* Peso:    ${this.pokemon.weight} kg \\n` +\n            `* Altura:  ${this.pokemon.height} m \\n` +\n            `* Tipo(s):`\n        );\n\n        this.pokemon.types.forEach((typeInfo) => {\n            console.log(`         - ${typeInfo.type.name}`);;\n        });\n    }\n\n    async evolutionChain() {\n        if (!this.pokemon) {\n            console.log(\"El Pokémon aún no ha sido cargado.\");\n            return;\n        }\n\n        try {\n            const speciesUrl = this.pokemon.species.url;\n            const speciesData = await fetch(speciesUrl).then((res) => res.json());\n            const evolutionChainUrl = speciesData.evolution_chain.url;\n            const evolutionChainData = await fetch(evolutionChainUrl).then((res) => res.json());\n\n            console.log(\"\\nCadena de evoluciones:\");\n            let currentEvolution = evolutionChainData.chain;\n\n            while (currentEvolution) {\n                console.log(`- ${currentEvolution.species.name}`);\n                currentEvolution = currentEvolution.evolves_to[0] || null;\n            }\n        } catch (error) {\n            GetPokemon.handleExceptions(error);\n        }\n    }\n\n    showGames() {\n        if (!this.pokemon) {\n            console.log(\"El Pokémon aún no ha sido cargado.\");\n            return;\n        }\n\n        console.log(\"\\nJuegos en los que aparece:\");\n        if (this.pokemon.game_indices.length > 0) {\n            this.pokemon.game_indices.forEach((gameInfo) => {\n                console.log(`- ${gameInfo.version.name}`);\n            });\n        } else {\n            console.log(\"No aparece en ninguno.\");\n        }\n    }\n\n    static handleExceptions(error) {\n        if (error.name === \"FetchError\") {\n            console.log(\"Error de conexión:\", error.message);\n        } else {\n            console.log(\"Error inesperado:\", error.message);\n        }\n    }\n}\n\n// ________________________________________________________\n(async () => {\n    const u1 = await getUser(1);\n    printUser(u1);\n\n    const u2 = await getUser(2);\n    printUser(u2);\n\n    const u3 = await getUser(777); // No existente.\n    printUser(u3);\n\n    console.log(\"\\nDIFICULTAD EXTRA:\");\n\n    try {\n        const p1 = new GetPokemon();\n        await p1.load(1);\n        p1.info();\n        await p1.evolutionChain();\n        p1.showGames();\n\n        const p2 = new GetPokemon();\n        await p2.load(\"ivysaur\");\n        p2.info();\n        await p2.evolutionChain();\n        p2.showGames();\n    } catch (error) {\n        GetPokemon.handleExceptions(error);\n    }\n})();\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/javascript/nlarrea.js",
    "content": "/*\n * EJERCICIO:\n * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n * una petición a la web que tú quieras, verifica que dicha petición\n * fue exitosa y muestra por consola el contenido de la web.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n * terminal al que le puedas solicitar información de un Pokémon concreto\n * utilizando su nombre o número.\n * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n * - Muestra el nombre de su cadena de evoluciones\n * - Muestra los juegos en los que aparece\n * - Controla posibles errores\n */\n\nasync function fetchData() {\n    const response = await fetch('https://jsonplaceholder.typicode.com/posts/1');\n    const data = await response.json();\n    console.log(data);\n}\n\n// fetchData();\n/* prints:\n{\n  userId: 1,\n  id: 1,\n  title: 'sunt aut facere repellat provident occaecati excepturi optio reprehenderit',\n  body: 'quia et suscipit\\n' +\n    'suscipit recusandae consequuntur expedita et cum\\n' +\n    'reprehenderit molestiae ut ut quas totam\\n' +\n    'nostrum rerum est autem sunt rem eveniet architecto'\n}\n*/\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n * terminal al que le puedas solicitar información de un Pokémon concreto\n * utilizando su nombre o número.\n * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n * - Muestra el nombre de su cadena de evoluciones\n * - Muestra los juegos en los que aparece\n * - Controla posibles errores\n */\n\n\nconst readline = require('readline');\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nasync function getPokemon(pokemon) {\n    try {\n        const response = await fetch(`https://pokeapi.co/api/v2/pokemon/${pokemon}`);\n        \n        if (!response.ok) {\n            throw new Error('Data not found.');\n        }\n\n        const data = await response.json();\n        return data;\n    } catch(err) {\n        console.error(err);\n    }\n}\n\nfunction askPokemon() {\n    rl.question('Enter a Pokémon name or Id:\\n> ', (pokemon) => {\n        getPokemon(pokemon)\n        .then(data => {\n            if (!data) {\n                return;\n            }\n\n            const {name, weight, height, types} = data;\n\n            console.log('\\nName:', name?.charAt(0).toUpperCase() + name?.slice(1));\n            console.log('Pokémon Id:', data?.id);\n            console.log('Pokémon weight:', weight);\n            console.log('Pokémon height:', height);\n            console.log('Pokémon type(s):');\n            types?.forEach(({slot, type}) => {\n                console.log(`  ${slot}.`, type?.name);\n            });\n        });\n        rl.close();\n    });\n}\n\naskPokemon();"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/javascript/parababire.js",
    "content": "const prompt = require('prompt-sync')();\n\n//Ejecicio\n\nconst url = 'https://api.coindesk.com/v1/bpi/currentprice.json';\n\nasync function showResponse() {\n  await fetch(url)\n  .then(response => {\n    if (!response.ok) {\n      throw new Error(`HTTP error! Status: ${response.status}`);\n    }\n    return response.json();\n    }\n  )\n  .then(data => console.log(`La cotización del bitcoin es: ${data.bpi.USD.rate_float}$`))\n  .catch(error=> console.log(error));\n}\n\n//showResponse();\n\n//Extra\n\nlet pokemon = prompt('Nombre del pokemon: ', '').toLowerCase();\n\nconst pokeApiUrl = `https://pokeapi.co/api/v2/pokemon/${pokemon}/`;\nlet pokemonName;\nfetch(pokeApiUrl)\n.then(response => {\n  if (!response.ok) {\n    throw new Error(`HTTP error, pokemon no encontrado! Status: ${response.status}`);\n  }\n  return response.json();\n  }\n)\n.then(data => {\n  pokemonName = data;\n})\n.then(() => {\n  console.log(`Nombre: ${pokemonName.species.name}, \\nId: ${pokemonName.id}, \\nPeso: ${pokemonName.weight}, \\nAltura: ${pokemonName.height}`);\n})\n.then(() => {\n  console.log('Tipo(s):');\n  for (const key in pokemonName.types) {\n    if (Object.hasOwnProperty.call(pokemonName.types, key)) {\n      console.log(`${pokemonName.types[key].type.name}`);\n    }\n  }\n})\n.then(() => {\n  const pokeApiUrlEvolutionChain = `https://pokeapi.co/api/v2/pokemon-species/${pokemon}/`;\n  let pokemonEvolutionChainUrl;\n  fetch(pokeApiUrlEvolutionChain)\n  .then(response => {\n    if (!response.ok) {\n      throw new Error(`HTTP error, Status: ${response.status} obteniendo evoluciones`);\n    }\n    return response.json();\n    }\n  )\n  .then(data => {\n    pokemonEvolutionChainUrl = data['evolution_chain']['url'];\n  })\n  .then(() => {\n    fetch(pokemonEvolutionChainUrl)\n    .then(response => {\n      if (!response.ok) {\n        throw new Error(`HTTP error! Status: ${response.status} en busqueda de cadena de evolución`);\n      }\n      return response.json();\n      }\n    )\n    .then(data => {\n      console.log('Cadena de evolución:');\n      let getEvolves = data => {\n        console.log(data['species']['name']);\n        if (data.hasOwnProperty('evolves_to')) {\n          for (const iterator of data['evolves_to']) {\n            getEvolves(iterator);\n          }\n        }\n      }\n      getEvolves(data['chain']);\n    })\n    .catch(error=> console.log(error))\n  })\n  .catch(error=> console.log(error))\n})\n.then(() => {\n  console.log('Juegos:');\n  for (const key in pokemonName.game_indices) {\n    if (Object.hasOwnProperty.call(pokemonName.game_indices, key)) {\n      console.log(`${pokemonName.game_indices[key].version.name}`);\n    }\n  }\n})\n.catch(error=> console.log(error))"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/javascript/pedamoci.js",
    "content": "const respuesta = await fetch('https://retosdeprogramacion.com/roadmap')\nif (respuesta.ok) {\n  const contenido = await respuesta.text()\n  console.log(contenido)\n}\n\n// ------------------------------ DIFICULTAD EXTRA ------------------------------\nimport  readline  from \"readline\"\n\nfunction preguntar(pregunta) {\n  const rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n  })\n\n  return new Promise(resolve => {\n    rl.question(pregunta, (respuesta) => {\n      rl.close()\n      resolve(respuesta)\n    })\n  })\n}\n\nasync function Pokemon(pokemon) {\n  const urlApi = 'https://pokeapi.co/api/v2/pokemon/'\n  try {\n    const responsePokemon = await fetch(`${urlApi}${pokemon}`)\n    if (!responsePokemon.ok) throw new Error(\"No se pudo obtener información sobre ese pokemon\")\n    const characteristic = await responsePokemon.json()\n    console.log('Caracteristicas del pokemon ingresado:\\n' + \n                `Nombre: ${characteristic.name}\\n` +\n                `ID: ${characteristic.id}\\n` +\n                `Peso: ${characteristic.weight}\\n` +\n                `Altura: ${characteristic.height}\\n` + \n                `Tipos: ${characteristic.types[0].type.name}, ${characteristic.types[1].type.name}`)\n\n    const responseSpecies = await fetch(`${characteristic.species.url}`)               //\n    const infoSpecies = await responseSpecies.json()                                    // INFORMACION NECESARIA PARA LLEGAR A LA CADENA EVOLUTIVA\n    const responceChainEvolutions = await fetch(`${infoSpecies.evolution_chain.url}`)   //\n    const infoChainEvolutions = await responceChainEvolutions.json()\n    if (infoChainEvolutions.chain.evolves_to.length === 0) console.log('El pokemon no tiene cadena evolutiva')\n    else {\n      let evolutionChain = infoChainEvolutions.chain\n      let evolutions = [evolutionChain.species.name]\n      while (evolutionChain.evolves_to.length !== 0) {\n        evolutions.push(evolutionChain.evolves_to[0].species.name)\n        evolutionChain = evolutionChain.evolves_to[0]\n      }\n      console.log(`Cadena evolutiva: ${evolutions.join(', ')}`)\n    }\n\n    if (characteristic.game_indices.length === 0) console.log('La información sobre en que juegos aparece este pokemon no esta disponible')\n      else {\n        const games = characteristic.game_indices.map((x) => x.version.name)\n        console.log(`Juegos en los que aparece: ${games.join(', ')}`)\n      }\n\n  } catch (e) {\n    console.log(e)\n  }\n}\n\nPokemon(await preguntar('De que pokemon quieres obtener información?? (inserta el nobre o el número de la pokedex)\\n'))"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/javascript/rserradev.js",
    "content": "// Ejercicio\n\nurl = \"https://moure.dev\";\n\nfetch(url)\n  .then(response => response.text())\n  .then(data => {\n    console.log(data);\n  })\n  .catch(error => console.log(error));\n\n// Ejercicio extra\n\nurl = 'https://pokeapi.co/api/v2/';\n\nlet pokemonName = \"ditto\";\n\nconst getPokemonData = async() => {\n  try {\n    const response = await fetch(`${url}pokemon/${pokemonName}`);\n    if (!response.ok) {\n      throw new Error(\"Error al obtener la información del pokemon\");\n    }\n    const data = await response.json();\n    return data;\n  } catch (error) {\n    console.log(error);\n  }\n}\n\nlet dataApi;\n\ngetPokemonData()\n  .then(data => {\n    const dataApi = data;\n\n    const {name, weight, height, types} = dataApi;\n\n    // Nombre\n    console.log(\"Nombre del pokemon: \" + name);\n\n    // Id\n    console.log(\"Id del pokemon: \" + dataApi.id);\n    // Peso\n    console.log(\"Peso del pokemon: \" + weight);\n    // Altura\n    console.log(\"Altura del pokemon: \" + height);\n    \n    // Tipo\n    console.log(\"Tipo del pokemon: \" + types[0].type.name);\n\n    // Cadena de evolucion\n    \n\n    let games = [];\n    //Juegos en los que aparece el pokemon\n    for (let i = 0; i < dataApi.game_indices.length; i++) {\n      games.push(dataApi.game_indices[i].version.name);\n    }\n\n    console.log(\"Juegos en los que aparece el pokemon: \" + games);\n\n});"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/javascript/victor-Casta.js",
    "content": "const readline = require('readline')\n/*\n  * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n  * una petición a la web que tú quieras, verifica que dicha petición\n  * fue exitosa y muestra por consola el contenido de la web.\n*/\n\nfetch('https://api.escuelajs.co/api/v1/products')\n  .then(response => {\n    if (!response.ok) {\n      throw new Error('Error en la petición');\n    }\n    return response.json();\n  })\n  .then(data => console.log( /*data*/))\n  .catch(error => console.error('Error en la petición:', error));\n\n/*\n  * DIFICULTAD EXTRA (opcional):\n  * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n  * terminal al que le puedas solicitar información de un Pokémon concreto\n  * utilizando su nombre o número.\n  * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n  * - Muestra el nombre de su cadena de evoluciones\n  * - Muestra los juegos en los que aparece\n  * - Controla posibles errores\n*/\n\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout\n})\n\nrl.question('Escribe el nombre o id de un pokémon: ', userData => {\n  const nameOfPokemon = userData\n  fetch(`https://pokeapi.co/api/v2/pokemon/${nameOfPokemon}/`)\n    .then(response => response.json())\n    .then(data => {\n      console.log(`Nombre: ${data.name}`)\n      console.log(`Id: ${data.id}`)\n      console.log(`Peso: ${data.weight}`)\n      console.log(`Altura: ${data.height}`)\n      console.log('Tipos:')\n      data.types?.map((item, index) => {\n        console.log(`Tipo ${index}: ${item.type.name}`)\n      })\n      console.log('Juegos:')\n      data.game_indices?.map(item => {\n        console.log(\n          `Indice de Juego: ${item.game_index}, Nombre del Juego: ${item.version.name}`\n        )\n      })\n    })\n    .catch(error => console.error(error))\n  rl.close()\n})"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/javascript/wapastorv.js",
    "content": "/*\n * EJERCICIO:\n * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n * una petición a la web que tú quieras, verifica que dicha petición\n * fue exitosa y muestra por consola el contenido de la web.\n */\n\n\n\n\n/*fetch('https://jsonplaceholder.typicode.com/posts/1')\n    .then(response => {\n        if (!response.ok) {\n            throw new Error('Error al realizar la petición: ' + response.status \n                + ' ' + response.statusText) ;\n        }\n        return response.json();\n    })\n    .then(data => {\n        console.log(data);\n    })\n    .catch(error => {\n        console.log('Error: ' + error);\n    });\n*/\n\n/* DIFICULTAD EXTRA (opcional):\n* Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n* terminal al que le puedas solicitar información de un Pokémon concreto\n* utilizando su nombre o número.\n* - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n* - Muestra el nombre de su cadena de evoluciones\n* - Muestra los juegos en los que aparece\n* - Controla posibles errores\n*/\nconst readline = require(\"readline\"); // Importar el módulo readline, que permite leer datos del usuario\nconst rl = readline.createInterface({ // Crear una interfaz de lectura\n    input: process.stdin, // Establecer la entrada de la interfaz\n    output: process.stdout // Establecer la salida de la interfaz\n});\n\n\nfunction getPokemon(pokemon) {\n    fetch(`https://pokeapi.co/api/v2/pokemon/${pokemon}/`)\n        .then(response => {\n            if (!response.ok) {\n                throw new Error('Error al realizar la petición: ' + response.status \n                    + ' ' + response.statusText) ;\n            }\n            return response.json();\n        })\n        .then(data => {\n            console.log(`Nombre: ${data.name}`);\n            console.log(`ID: ${data.id}`);\n            console.log(`Peso: ${data.weight}`);\n            console.log(`Altura: ${data.height}`);\n            console.log('Tipos:');\n            data.types.forEach(type => {\n                console.log(`- ${type.type.name}`);\n            });\n            return fetch(data.species.url);\n        })\n        .then(response => {\n            if (!response.ok) {\n                throw new Error('Error al realizar la petición: ' + response.status \n                    + ' ' + response.statusText) ;\n            }\n            return response.json();\n        })\n        .then(data => {\n            console.log(`Cadena de evolución: ${data.evolves_from_species ? data.evolves_from_species.name : 'Ninguna'}`);\n            return fetch(data.varieties[0].pokemon.url);\n        })\n        .then(response => {\n            if (!response.ok) {\n                throw new Error('Error al realizar la petición: ' + response.status \n                    + ' ' + response.statusText) ;\n            }\n            return response.json();\n        })\n        .then(data => {\n            console.log('Juegos en los que aparece:');\n            data.game_indices.forEach(game => {\n                console.log(`- ${game.version.name}`);\n            });\n        })\n        .catch(error => {\n            console.log('Error: ' + error);\n        });\n}\nrl.question(\"Introduce el nombre o número de un Pokémon: \", function(pokemon) {\n    getPokemon(pokemon);\n    rl.close();\n});// Cerrar la interfaz de lectura cuando se introduce un Pokémon\n\n\n\n\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/kotlin/blackriper.kt",
    "content": "import fuel.Fuel\r\nimport fuel.get\r\nimport kotlinx.coroutines.async\r\nimport kotlinx.coroutines.runBlocking\r\nimport kotlinx.serialization.SerialName\r\nimport kotlinx.serialization.Serializable\r\nimport kotlinx.serialization.json.Json\r\n\r\n\r\n/*\r\n Una peticion http  utiliza el protocolo Hypertext Transfer Protocol (HTTP). para comunicar\r\n datos atravez  de la red. esta peticion suele hacerse a un servidor o backend para obtener\r\n datos.\r\n\r\n una solicitud http se componene de los siguintes elementos:\r\n  un metodo (GET, POST, PUT, DELETE, PATCH)\r\n  una url (url de la peticion)\r\n  un encabezado (cabeceras)\r\n  version del protocolo (HTTP/1.1)\r\n\r\n Glosario basico de conceptos\r\n\r\n el metodo (GET, POST, PUT, DELETE, PATCH) es un verbo que se utiliza para\r\n saber la operacion que se va a realizar. por ejemplo:\r\n\r\n GET: obtiene informacion\r\n POST: permite enviar datos al servidor\r\n PUT:  nos permite enviar datos para actualizar\r\n DELETE: elimina datos\r\n\r\n el encabezado (cabeceras) es un conjunto de datos que se envia con la peticion\r\n estos pueden aportar informacion  adcional al servidor. por ejemplo:\r\n\r\n  Accept: acepta informacion de la peticion ya sea JSON o XML o texto plano\r\n\r\nPeticiones Http en kotlin\r\n\r\npara poder hacer peticiones http en kotlin se pueden usar librarias como retrofit o okhttp o fuel\r\nen este caso vamos utilizar fuel y kotlinx.serialization para trasformar los datos de la peticion\r\na una clase de kotlin y por utlimo como esta peticion puede durar un tiempo usaremos kotlinxcoroutines\r\npara poder hacer las llamadas asincronas.\r\n\r\nhttps://github.com/kittinunf/fuel\r\nhttps://github.com/Kotlin/kotlinx.coroutines\r\nhttps://kotlinlang.org/docs/serialization.html\r\n\r\n*/\r\n\r\n//1.- preparar clase kotlin para  deserializar la peticion\r\n@Serializable\r\ndata class ChuckNorrisResponse(\r\n   @SerialName(\"icon_url\")\r\n    val iconUrl:String,\r\n    val id:String,\r\n    val url:String,\r\n    val value:String\r\n)\r\n\r\n// configuracion por si no necesitas todos los campos de json\r\nprivate val json = Json { ignoreUnknownKeys = true }\r\n\r\n\r\nfun exampleHttpRequest() = runBlocking{\r\n    //2.- hacer la peticion\r\n    val result= async {\r\n        Fuel.get(\"https://api.chucknorris.io/jokes/random\").body\r\n    }\r\n   //3.- esperar por la respuesta y convertirla a una clase de kotlin\r\n    try {\r\n        val response = result.await()\r\n        val data = json.decodeFromString<ChuckNorrisResponse>(response)\r\n        println(\"the joke is ${data.value}\")\r\n    }catch (e : Exception){\r\n        println(e)\r\n    }\r\n}\r\n\r\n/*Ejecicio extra */\r\n\r\n@Serializable\r\ndata class Pokemon(\r\n    val id: Int,\r\n    val name: String,\r\n    val types: List<PokemonType>,\r\n    @SerialName(\"game_indices\")\r\n    val games: List<GameIndex>,\r\n    val forms: List<PokeForms>,\r\n    val height: Int,\r\n    val weight: Int\r\n)\r\n\r\n@Serializable\r\ndata class PokeForms(\r\n    val name: String,\r\n    val url: String\r\n)\r\n\r\n\r\n// clases para los subtipos de games\r\n\r\n@Serializable\r\ndata class GameIndex(\r\n    @SerialName(\"game_index\")\r\n    val gameIndex: Int,\r\n    val version: PokeVersion\r\n)\r\n\r\n@Serializable\r\ndata class PokeVersion(\r\n    val name: String,\r\n    val url: String\r\n)\r\n\r\n// clases para los subtipos de types de pokemon\r\n@Serializable\r\ndata class PokemonType(\r\n    val slot: Int,\r\n    val type: PokeType\r\n)\r\n@Serializable\r\ndata class PokeType(\r\n    val name: String,\r\n    val url: String\r\n)\r\n\r\n// crear  clase para buscar pokemons\r\n\r\nclass Pokedex {\r\n    private lateinit var pokemonSearch: String\r\n    private var isSearchForID = false\r\n\r\n\r\n    fun askForPokemon() {\r\n        val regex = \"[0-9]\".toRegex()\r\n        println(\"Enter a pokemon name or ID\")\r\n        this.pokemonSearch = readLine().toString()\r\n        if (regex.matches(this.pokemonSearch)) {\r\n            this.isSearchForID = true\r\n        }\r\n    }\r\n\r\n    fun searchPokemon() {\r\n        val params = if (this.isSearchForID) this.pokemonSearch.toInt() else this.pokemonSearch\r\n        val url = \"https://pokeapi.co/api/v2/pokemon/$params\"\r\n        runBlocking {\r\n            val result = async {\r\n                Fuel.get(url).body\r\n            }\r\n\r\n            try {\r\n                val response = result.await()\r\n                val pokemon= json.decodeFromString<Pokemon>(response)\r\n                printPokemon(pokemon)\r\n\r\n            } catch (e: Exception) {\r\n                println(e)\r\n            }\r\n\r\n        }\r\n\r\n    }\r\n\r\n    private fun printPokemon(poke:Pokemon) {\r\n       val info= \"\"\"\r\n         ID : ${poke.id}   \r\n         Name : ${poke.name}\r\n         Type : ${poke.types.map {it.type.name}}\r\n         Game : ${poke.games.map {it.version.name}}\r\n         Forms : ${poke.forms.map {it.name}}\r\n         Height : ${poke.height}\r\n         Weight : ${poke.weight}\r\n            \r\n        \"\"\".trimIndent()\r\n        println(info)\r\n    }\r\n\r\n}\r\n\r\n\r\n\r\n\r\nfun main() {\r\n //exampleHttpRequest()\r\n val poke=Pokedex()\r\n poke.askForPokemon()\r\n poke.searchPokemon()\r\n}"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/kotlin/eulogioep.kt",
    "content": "import io.ktor.client.HttpClient\nimport io.ktor.client.call.body\nimport io.ktor.client.request.get\nimport io.ktor.client.statement.HttpResponse\nimport io.ktor.client.statement.bodyAsText\nimport io.ktor.http.ContentType\nimport io.ktor.http.HttpStatusCode\nimport io.ktor.http.contentType\n\nsuspend fun main() {\n    // Petición HTTP a una página web\n    val client = HttpClient()\n    val response: HttpResponse = client.get(\"https://www.example.com\")\n    \n    if (response.status == HttpStatusCode.OK) {\n        println(\"Petición exitosa, contenido de la web:\")\n        println(response.bodyAsText())\n    } else {\n        println(\"Error en la petición: ${response.status}\")\n    }\n\n    // Consulta de información de un Pokémon a través de la PokéAPI\n    println(\"\\nConsulta de información de un Pokémon:\")\n    val pokemonName = \"pikachu\"\n    val pokemonInfo = getPokemonInfo(pokemonName)\n    \n    println(\"Nombre: ${pokemonInfo.name}\")\n    println(\"ID: ${pokemonInfo.id}\")\n    println(\"Peso: ${pokemonInfo.weight}\")\n    println(\"Altura: ${pokemonInfo.height}\")\n    println(\"Tipos: ${pokemonInfo.types.map { it.type.name }.joinToString(\", \")}\")\n    \n    println(\"\\nCadena de evolución:\")\n    pokemonInfo.evolutionChain.forEach { evolution ->\n        println(\"- ${evolution.name}\")\n    }\n    \n    println(\"\\nJuegos en los que aparece:\")\n    pokemonInfo.games.forEach { game ->\n        println(\"- ${game.name}\")\n    }\n}\n\nsuspend fun getPokemonInfo(name: String): PokemonInfo {\n    val client = HttpClient()\n    val response: HttpResponse = client.get(\"https://pokeapi.co/api/v2/pokemon/$name\") {\n        contentType(ContentType.Application.Json)\n    }\n    \n    if (response.status == HttpStatusCode.OK) {\n        return response.body()\n    } else {\n        throw Exception(\"Error al obtener información del Pokémon: ${response.status}\")\n    }\n}\n\ndata class PokemonInfo(\n    val name: String,\n    val id: Int,\n    val weight: Int,\n    val height: Int,\n    val types: List<PokemonType>,\n    val evolutionChain: List<Evolution>,\n    val games: List<Game>\n)\n\ndata class PokemonType(\n    val type: TypeInfo\n)\n\ndata class TypeInfo(\n    val name: String\n)\n\ndata class Evolution(\n    val name: String\n)\n\ndata class Game(\n    val name: String\n)"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/nasm/evanz2608.s",
    "content": "; https://nasm.us\n\n; ===================================================\n; 20 - PETICIONES HTTP\n; ===================================================\n\n\nAF_INET: equ 2\nSOCK_STREAM: equ 1\n\nSTDIN: equ 0\nSTDOUT: equ 1\nSTDERR: equ 2\n\nSYS_read: equ 0\nSYS_write: equ 1\nSYS_socket: equ 41\nSYS_connect: equ 42\nSYS_sendto: equ 44\nSYS_recvfrom: equ 45\nSYS_sendmsg: equ 46\nSYS_bind: equ 49\nSYS_exit: equ 60\n\nBUF_LEN: equ 2048\n\n\nglobal _start\nextern inet_addr\nextern htons\nsection .text\n_start:\n  ; Creamos un socket, en este caso un socket TCP\n  mov rax, SYS_socket\n  mov rdi, AF_INET\n  mov rsi, SOCK_STREAM\n  mov rdx, 0\n  syscall\n\n  cmp rax, 0\n  jl _exit\n  mov dword [sockfd], eax\n\n; 93.184.215.14 - IP de http://example.com\n; 80 - Puerto de escucha de solicitudes HTTP\n  lea rdi, [example_url]\n  call inet_addr\n  mov dword [servaddr + sockaddr_in.sin_addr], eax\n  mov rdi, 80\n  call htons\n  mov word [servaddr + sockaddr_in.sin_port], ax\n  mov word [servaddr + sockaddr_in.sin_family], AF_INET\n  mov rax, SYS_connect\n  mov edi, dword [sockfd]\n  lea rsi, [servaddr]\n  mov rdx, sockaddr_in_size\n  syscall\n\n  test rax, rax\n  js _exit\n\n  mov rax, SYS_sendto\n  mov edi, dword [sockfd]\n  lea rsi, [request]\n  mov rdx, request_len\n  xor r10, r10\n  xor r8, r8\n  xor r9, r9\n  syscall\n\n  cmp rax, 0\n  js _exit\n\n.read_loop:\n  mov rax, SYS_recvfrom\n  mov edi, dword [sockfd]\n  lea rsi, [recv_buffer]\n  mov rdx, BUF_LEN\n  mov r10, 0x100\n  xor r8, r8\n  xor r9, r9\n  syscall\n\n  test rax, rax\n  js _exit\n  jz _exit\n\n  mov rax, SYS_write\n  mov rdi, STDOUT\n  lea rsi, [recv_buffer]\n  mov rdx, BUF_LEN\n  syscall\n  jmp .read_loop\n\n_exit:\n  mov rax, SYS_exit\n  xor rdi, rdi\n  syscall\n\nsection .data\n  struc sockaddr_in\n    .sin_family: resw 1\n    .sin_port: resw 1\n    .sin_addr: resd 1\n    .sin_zero: resq 1\n  endstruc\nsection .bss\n  sockfd: resd 1\n  servaddr: resb sockaddr_in_size\n  recv_buffer: resb BUF_LEN\n\nsection .rodata\n  request:  db \"GET / HTTP/1.1\", 0x0D, 0x0A\n            db \"Host: example.com\", 0x0D, 0x0A\n            db \"Connection: close\", 0x0D, 0x0A\n            db 0x0D, 0x0A\n  request_len: equ $-request\n\n  example_url: db \"93.184.215.14\", 0x00\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/ocaml/luishendrix92.ml",
    "content": "open Lwt\nopen Cohttp\nopen Cohttp_lwt_unix\nopen Yojson.Safe\nopen Printf\n\n(*****************************************************************************)\n(*                                                                           *)\n(*                               HTTP Requests                               *)\n(*                                                                           *)\n(*  HTTP in OCaml is very complex without a library because it has to be     *)\n(*  done with the [Unix] networking module, plus it requires heavy know-     *)\n(*  ledge of sockets, protocols, parsing, etc. Thankfully, there are many    *)\n(*  well maintained libraries out there, [CoHttp] being the most popular     *)\n(*  and the one I used in this exercise. It's based on both [Async] and      *)\n(*  [Lwt] (lightweight threads, promise-based).                              *)\n(*                                                                           *)\n(*  I chose to use monadic operators (>>=, >|=) instead of specialized       *)\n(*  syntax for self-learning purposes but there is a way to use custom let   *)\n(*  bindings like [let%lwt] and [let*] that make the code look more like     *)\n(*  async/await in other languages.                                          *)\n(*                                                                           *)\n(*****************************************************************************)\n\nlet http_get_string url =\n  Client.get (Uri.of_string url)\n  >>= fun (response, body) ->\n  let status_code = Code.code_of_status (Response.status response) in\n  Cohttp_lwt.Body.to_string body\n  >|= fun str_body ->\n  if status_code >= 200 && status_code < 400\n  then Result.Ok (status_code, str_body)\n  else Result.Error status_code\n;;\n\nlet _ =\n  let bacon_ipsum =\n    \"https://baconipsum.com/api/?type=all-meat&paras=1&start-with-lorem=1&format=html\"\n  in\n  Lwt_main.run\n    begin\n      http_get_string bacon_ipsum\n      >|= fun res ->\n      match res with\n      | Ok (code, body) ->\n        printf \"HTTP Call Successful With Code [%d] | HTML:\\n\" code;\n        print_endline body\n      | Error code -> printf \"HTTP Call Failed With Status Code [%d]!\\n\" code\n    end\n;;\n\n(*****************************************************************************)\n(*                                                                           *)\n(*                        Dificultad Extra (Opcional)                        *)\n(*                                                                           *)\n(*  Utilizando la PokéAPI (https://pokeapi.co), crea un programa por         *)\n(*  terminal al que le puedes solicitar información de un Pokémon concreto   *)\n(*  utilizando su nombre o id numérico.                                      *)\n(*                                                                           *)\n(*  - Muestra el nombre, id, peso, altura, y tipo(s) del Pokémon.            *)\n(*  - Muestra el nombre de su cadena de evoluciones                          *)\n(*  - Muestra los juegos en los que aparece                                  *)\n(*  - Controla posibles errores                                              *)\n(*                                                                           *)\n(*****************************************************************************)\n\nlet http_get_json url =\n  http_get_string url\n  >|= Result.map (fun (code, str_body) -> code, from_string str_body)\n;;\n\nlet path_exn path json = Yojson.Safe.Util.path path json |> Option.get\nlet ( >>>= ) = Lwt_result.bind\n\nmodule Pokedex = struct\n  open Yojson.Safe.Util\n\n  module Pokemon = struct\n    type t =\n      { id : int\n      ; name : string\n      ; height : int\n      ; weight : int\n      ; types : string list\n      ; games : string list\n      ; evolution_chain : string\n      }\n\n    let rec deserialize_ev_chain json =\n      let name = json |> path_exn [ \"species\"; \"name\" ] |> to_string in\n      let evolves_to = json |> member \"evolves_to\" |> to_list in\n      match evolves_to with\n      | [] -> name\n      | evolutions ->\n        let branches =\n          List.map deserialize_ev_chain evolutions |> String.concat \", \"\n        in\n        sprintf \"%s->[%s]\" name branches\n    ;;\n\n    let of_json pk_info_json ev_chain_json =\n      let name = pk_info_json |> member \"name\" |> to_string in\n      let id = pk_info_json |> member \"id\" |> to_int in\n      let weight = pk_info_json |> member \"weight\" |> to_int in\n      let height = pk_info_json |> member \"height\" |> to_int in\n      let games =\n        pk_info_json\n        |> member \"game_indices\"\n        |> to_list\n        |> List.map (fun t -> t |> path_exn [ \"version\"; \"name\" ] |> to_string)\n      in\n      let types =\n        pk_info_json\n        |> member \"types\"\n        |> to_list\n        |> List.map (fun t -> t |> path_exn [ \"type\"; \"name\" ] |> to_string)\n      in\n      let evolution_chain =\n        ev_chain_json |> member \"chain\" |> deserialize_ev_chain\n      in\n      { id; name; weight; height; types; games; evolution_chain }\n    ;;\n  end\n\n  let api_base_url = \"https://pokeapi.co/api/v2\"\n\n  let display (p : Pokemon.t) =\n    printf \"Name: %s (#%d)\\n\" p.name p.id;\n    printf \"Height: %d | Weight: %d\\n\" p.height p.weight;\n    printf \"Type(s): %s\\n\" (String.concat \", \" p.types);\n    printf \"Game(s): %s\\n\" (String.concat \", \" p.games);\n    printf \"Evolution Chain: %s\\n\" p.evolution_chain\n  ;;\n\n  let find_by_name name =\n    let name = Core.String.lowercase name in\n    let pk_info_url = sprintf \"%s/pokemon/%s\" api_base_url name in\n    let pk_species_url = sprintf \"%s/pokemon-species/%s\" api_base_url name in\n    http_get_json pk_species_url\n    >>>= fun (_, species_json) ->\n    let ev_chain_url =\n      species_json |> path_exn [ \"evolution_chain\"; \"url\" ] |> to_string\n    in\n    http_get_json ev_chain_url\n    >>>= fun (_, ev_chain_json) ->\n    http_get_json pk_info_url\n    >>>= fun (_, pk_info_json) ->\n    Lwt_result.return (Pokemon.of_json pk_info_json ev_chain_json)\n  ;;\nend\n\nlet _ =\n  Moure.Io.prompt_string \"Name of the pokemon: \"\n  |> Pokedex.find_by_name\n  |> Lwt_main.run\n  |> function\n  | Ok pokemon -> Pokedex.display pokemon\n  | Error code ->\n    printf \"Failed to fetch data from the PokéAPI (Status Code: %d)\\n\" code\n;;\n\n(* Output of running [dune exec reto20]:\n   -------------------------------------\n\n   HTTP Call Successful With Code [200] | HTML:\n   <p>Bacon ipsum dolor amet beef capicola short loin porchetta, swine andouille buffalo cow boudin leberkas ham venison bacon.  Landjaeger tail tenderloin shank, bresaola meatball andouille kielbasa boudin ball tip salami flank swine turkey.  Meatloaf corned beef pork pig kielbasa biltong, sirloin chicken alcatra cow porchetta pork belly ball tip ham.  Hamburger kevin ground round, flank cow biltong pastrami chislic sausage ham capicola meatloaf filet mignon corned beef cupim.  Cupim leberkas frankfurter, filet mignon sirloin venison fatback.</p>\n\n   Name of the pokemon: wurmple\n   Name: wurmple (#265)\n   Height: 3 | Weight: 36\n   Type(s): bug\n   Game(s): ruby, sapphire, emerald, firered, leafgreen, diamond, pearl, platinum, heartgold, soulsilver, black, white, black-2, white-2\n   Evolution Chain: wurmple->[silcoon->[beautifly], cascoon->[dustox]]\n\n   --------------------------------------------------------------------\n   NOTE: The evolution chain of {b wurmple} has 2 branches:\n   1. From wurmple to silcoon (which in turn evolves to beautifly)\n   2. From wurmple to cascoon (which in turn evolves to dustox)\n   Therefore, the chain expressed as a flat string can also be seen as:\n\n                           +---------+     +-----------+\n                    +----->| Silcoon |---->| Beautifly |\n   +---------+      |      +---------+     +-----------+\n   | Wurmple |----->o\n   +---------+      |      +---------+     +--------+\n                    +----->| Cascoon |---->| Dustox |\n                           +---------+     +--------+\n*)\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/pascal/edalmava.pas",
    "content": "program getURL;\n{$mode objfpc}\n\nuses\n    Classes, Crt, fphttpclient, opensslsockets, sysutils;\n\nvar\n    ClienteHttp : TFPHTTPClient;\n    Respuesta   : TStringStream;\n    URL         : string;\n\nbegin\n  try\n    ClrScr;\n    URL := 'https://pokeapi.co/api/v2/pokemon/ditto';\n\n    ClienteHttp := TFPHTTPClient.Create(nil);\n    Respuesta   := TStringStream.Create('');\n\n    try\n        ClienteHttp.Get(URL, Respuesta);\n\n        if ClienteHttp.ResponseStatusCode = 200 then\n        begin\n            Writeln('Respuesta 200 OK: ');\n            Writeln(Respuesta.DataString)\n        end\n        else\n        begin\n            Writeln('La solicitud fallo.  Codigo de Respuesta: ', ClienteHttp.ResponseStatusCode)\n        end;\n    except\n        on E: Exception do\n        begin\n            Writeln('Error al realizar la solicitud: ', E.Message);\n        end;\n    end;\n  finally\n        ClienteHttp.free;\n        Respuesta.free;\n  end;\nend.\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/php/eulogioep.php",
    "content": "<?php\n\n/**\n * Ejercicio de peticiones HTTP en PHP\n * \n * Teoría sobre peticiones HTTP en PHP:\n * PHP ofrece varias formas de realizar peticiones HTTP:\n * 1. cURL - Una biblioteca potente para transferir datos con varios protocolos\n * 2. file_get_contents() - Función simple para peticiones GET (requiere allow_url_fopen)\n * 3. Bibliotecas de terceros como Guzzle\n * \n * En este ejemplo usamos cURL por su flexibilidad y robustez.\n * \n * Conceptos clave:\n * - cURL: Cliente URL library, permite hacer peticiones HTTP\n * - JSON: Formato de intercambio de datos, decodificado con json_decode()\n * - CLI: Command Line Interface, interfaz por línea de comandos\n */\n\n/**\n * Realiza una petición HTTP GET\n * \n * @param string $url La URL a la que realizar la petición\n * @return string El contenido de la respuesta\n * @throws Exception Si hay un error en la petición\n */\nfunction realizarPeticionHttp($url)\n{\n    $ch = curl_init($url);\n    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\n    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);\n\n    $response = curl_exec($ch);\n    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);\n\n    if ($httpCode !== 200) {\n        $error = curl_error($ch);\n        curl_close($ch);\n        throw new Exception(\"Error en la petición HTTP (código $httpCode): $error\");\n    }\n\n    curl_close($ch);\n    return $response;\n}\n\n/**\n * Muestra la cadena de evolución de forma recursiva\n * \n * @param object $chain Objeto JSON con la información de evolución\n * @param int $nivel Nivel de indentación para la visualización\n */\nfunction mostrarCadenaEvolucion($chain, $nivel = 0)\n{\n    $indentacion = str_repeat(\"  \", $nivel);\n    echo \"{$indentacion}- \" . $chain->species->name . PHP_EOL;\n\n    if (!empty($chain->evolves_to)) {\n        foreach ($chain->evolves_to as $evolucion) {\n            mostrarCadenaEvolucion($evolucion, $nivel + 1);\n        }\n    }\n}\n\n// Ejemplo básico de petición HTTP\necho \"=== Ejemplo básico de petición HTTP ===\" . PHP_EOL;\ntry {\n    $contenido = realizarPeticionHttp('https://www.example.com');\n    echo \"Petición exitosa a example.com\" . PHP_EOL;\n} catch (Exception $e) {\n    echo \"Error: \" . $e->getMessage() . PHP_EOL;\n}\n\n// Programa principal para buscar información de Pokémon\nwhile (true) {\n    echo PHP_EOL . \"=== Búsqueda de Pokémon ===\" . PHP_EOL;\n    echo \"Ingrese el nombre o número del Pokémon (o 'salir' para terminar): \";\n    $entrada = trim(strtolower(fgets(STDIN)));\n\n    if ($entrada === 'salir') {\n        break;\n    }\n\n    try {\n        // Obtener datos básicos del Pokémon\n        $pokemonJson = realizarPeticionHttp(\"https://pokeapi.co/api/v2/pokemon/{$entrada}\");\n        $pokemon = json_decode($pokemonJson);\n\n        echo PHP_EOL . \"Información del Pokémon:\" . PHP_EOL;\n        echo \"Nombre: \" . $pokemon->name . PHP_EOL;\n        echo \"ID: \" . $pokemon->id . PHP_EOL;\n        echo \"Peso: \" . ($pokemon->weight / 10) . \" kg\" . PHP_EOL;\n        echo \"Altura: \" . ($pokemon->height / 10) . \" m\" . PHP_EOL;\n\n        // Mostrar tipos\n        echo \"Tipos:\" . PHP_EOL;\n        foreach ($pokemon->types as $tipo) {\n            echo \"- \" . $tipo->type->name . PHP_EOL;\n        }\n\n        // Obtener y mostrar cadena de evolución\n        $especieJson = realizarPeticionHttp($pokemon->species->url);\n        $especie = json_decode($especieJson);\n\n        $evolucionJson = realizarPeticionHttp($especie->evolution_chain->url);\n        $evolucion = json_decode($evolucionJson);\n\n        echo PHP_EOL . \"Cadena de evolución:\" . PHP_EOL;\n        mostrarCadenaEvolucion($evolucion->chain);\n\n        // Mostrar juegos\n        echo PHP_EOL . \"Juegos en los que aparece:\" . PHP_EOL;\n        foreach ($pokemon->game_indices as $juego) {\n            echo \"- \" . $juego->version->name . PHP_EOL;\n        }\n    } catch (Exception $e) {\n        echo \"Error: No se pudo encontrar el Pokémon. Asegúrese de escribir el nombre o número correctamente.\" . PHP_EOL;\n    }\n}\n\necho \"¡Gracias por usar el buscador de Pokémon!\" . PHP_EOL;\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/php/gabrielmoris.php",
    "content": "<?php\n/*\n * EXERCISE:\n * Using an HTTP request mechanism in your language, make\n * a request to the website of your choice, verify that the request\n * was successful, and display the website content in the console.\n */\n\n// $url = 'https://ai-coverletters.vercel.app/en';\n// // simplest way to get contents: Only works with GET requests and it is not safe (Requires allow_url_fopen enabled)\n// try {\n//     $context = stream_context_create(['https' => ['method' => 'GET']]);\n//     $content = file_get_contents('https://ai-coverletters.vercel.app/en/', false, $context);\n//     // echo $content . \"\\n\";\n// } catch (Exception $e) {\n//     echo \"Error: $e\";\n// }\n\n// cURL Is a library for making http requests in PHP\n// try {\n//     $ch = curl_init(\"https://ai-coverletters.vercel.app/en\");\n//     curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\n//     $content = curl_exec($ch);\n//     // echo $content . \"\\n\";\n//     curl_close($ch);\n// } catch (Exception $e) {\n//     echo \"Error: $e\";\n// }\n\n\n/*\n * EXTRA DIFFICULTY (optional):\n * Using the PokéAPI (https://pokeapi.co), create a terminal program\n * where you can request information about a specific Pokémon\n * using its name or number.\n * - Display the name, id, weight, height, and type(s) of the Pokémon\n * - Display the name of its evolution chain\n * - Display the games it appears in\n * - Handle potential errors\n */\n\nfunction pokemon()\n{\n    echo \"\n    ===== Welcome to the Pokemon Database =====\n     1.- Check Pokemon Data\n     2.- Check which games show the Pokemon \n     3.- Check Pokemon Evolutions\n     4.- Exit\n    ============================================\n     \\n\";\n\n    while (true) {\n        $selection = readline(\"Select an option\\n\");\n        switch ($selection) {\n            case 1:\n                $pokemon =  readline(\"Pokemon Name or Number: \\n\");\n                $info = apiCall($pokemon, \"pokemon\");\n                if (!json_decode($info, true) || !$info) {\n                    echo \"Invalid JSON string or API not working\";\n                    break;\n                }\n                $jsonObject = json_decode($info, true);\n\n                $name = $jsonObject['species']['name'];\n                $height = $jsonObject['height'];\n                $weight = $jsonObject['weight'];\n                $id = $jsonObject['id'];\n\n                $types = array_map(function ($type) {\n                    return $type['type']['name'];\n                }, $jsonObject['types']);\n\n                echo \"ID: $id\\nName: $name\\nHeight: $height m\\nWeight: $weight Kg\\nTypes: \" . implode(', ', $types)  . \"\\n\";\n                break;\n            case 2:\n                $pokemon = readline(\"Pokemon Name or Number \\n\");\n                $info = apiCall($pokemon, \"generation\");\n                if (!json_decode($info, true) || !$info) {\n                    echo \"Invalid JSON string or API not working\";\n                    break;\n                }\n                $jsonObject = json_decode($info, true);\n\n                $games = array_map(function ($version) {\n                    return $version['name'];\n                },  $jsonObject['version_groups']);\n\n                echo \"Games:\" . implode(', ', $games)  . \"\\n\";\n                break;\n            case 3:\n                $pokemon =  readline(\"Pokemon Name or Number: \\n\");\n                $info = apiCall($pokemon, \"evolution-chain\");\n                if (!json_decode($info, true) || !$info) {\n                    echo \"Invalid JSON string or API not working\";\n                    break;\n                }\n                $jsonObject = json_decode($info, true);\n\n\n                $evolutionChain = $jsonObject['chain'];\n                getEvolutions($evolutionChain);\n                break;\n            case 4:\n                echo \"\\033c\";\n                echo \"Good bye 👋 \\n\";\n                exit;\n            default:\n                echo \"This option doesn't exist.\\n\";\n        }\n    }\n}\n\nfunction apiCall($pokemon, $information)\n{\n    try {\n        $ch = curl_init(\"https://pokeapi.co/api/v2/$information/$pokemon\");\n        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\n        $content = curl_exec($ch);\n        return $content;\n        curl_close($ch);\n    } catch (Exception $e) {\n        echo \"Error: $e\";\n    }\n}\n\nfunction getEvolutions($data)\n{\n    if (!empty($data['evolves_to'])) {\n        $evolution = $data['evolves_to'][0]['species']['name'];\n        echo \"Evolves to: $evolution\\n\";\n        getEvolutions($data['evolves_to'][0]);\n    }\n}\n\npokemon();\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/php/miguelex.php",
    "content": "<?php\n\n$ch = curl_init();\n\n// Configurar la URL a la que se hará la petición\ncurl_setopt($ch, CURLOPT_URL, \"https://retosdeprogramacion.com/\");\n\n// Configurar cURL para devolver el resultado en lugar de imprimirlo directamente\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);\n\n// Configurar cURL para usar el archivo de certificados descargado\ncurl_setopt($ch, CURLOPT_CAINFO, 'cacert.pem');\n\n// Ejecutar la petición\n$output = curl_exec($ch);\n\n// Verificar si hubo algún error durante la ejecución de la petición\nif($output === false) {\n    echo \"cURL Error: \" . curl_error($ch);\n} else {\n    // Obtener el código de estado HTTP de la respuesta\n    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);\n\n    // Mostrar el código de estado HTTP\n    echo \"HTTP Status Code: \" . $http_code . \"\\n\\n\";\n\n    // Mostrar el contenido de la respuesta\n    echo $output;\n}\n\n// Cerrar la sesión cURL\ncurl_close($ch);\n\n\n\n// EXTRA\n\necho \"\\n\\n DIFICULTAD EXTRA \\n\\n\";\n\nfunction getPokemonData($pokemon) {\n    $data = file_get_contents(\"https://pokeapi.co/api/v2/pokemon/$pokemon\");\n    $data = json_decode($data);\n\n    echo \"Nombre: \" . $data->name . \"\\n\";\n    echo \"ID: \" . $data->id . \"\\n\";\n    echo \"Peso: \" . $data->weight . \"\\n\";\n    echo \"Altura: \" . $data->height . \"\\n\";\n    echo \"Tipos: \";\n    foreach ($data->types as $type) {\n        echo $type->type->name . \" \";\n    }\n    echo \"\\n\";\n\n    $speciesData = file_get_contents($data->species->url);\n    $speciesData = json_decode($speciesData);\n\n    echo \"Cadena de evolución: \" . $speciesData->evolution_chain->url . \"\\n\";\n\n    echo \"Juegos: \";\n    foreach ($data->game_indices as $game) {\n        echo $game->version->name . \" \";\n    }\n    echo \"\\n\";\n}\n\ntry {\n    while (true) {\n        echo \"Introduce el nombre o número del Pokémon (o 'salir' para terminar): \";\n        $pokemon = trim(fgets(STDIN));\n        if ($pokemon == 'salir') {\n            break;\n        }\n        getPokemonData($pokemon);\n    }\n} catch (Exception $e) {\n    echo \"Ha ocurrido un error: \" . $e->getMessage();\n}\n?>\n\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/AChapeton.py",
    "content": "import requests\n\nbaseURL = 'https://pokeapi.co/api/v2/pokemon'\n\ndef getData(number):\n  url = baseURL + '/' + number\n  res = requests.get(url)\n  data = res.json()\n  print('Name: ', data['name'])\n  print('ID: ', data['id'])\n  print('Weight: ', data['weight'])\n  print('Height: ', data['height'])\n\n  types = [type_info['type']['name'] for type_info in data['types']]\n  print('Types:', types)\n\n  games = [game['version']['name'] for game in data['game_indices']]\n  print('Games:', games)\n\n\ngetData('9')"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/Aldroide.py",
    "content": "\"\"\"\n    Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n    una petición a la web que tú quieras, verifica que dicha petición\n    fue exitosa y muestra por consola el contenido de la web.\n\"\"\"\nimport requests\nfrom bs4 import BeautifulSoup\n\n# url = \"https://espndeportes.espn.com/\"\nurl = \"https://www.google.com\"\nresponse = requests.get(url)\n\nif response.status_code == 200:\n    print(\"Petición Exitosa\")\n    soup = BeautifulSoup(response.text, 'html.parser')\n    print(soup.prettify())\nelse:\n    print(f\"La petición falló codigo: {response.status_code}\")\n\n\"\"\"\n    DIFICULTAD EXTRA (opcional):\n    Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n    terminal al que le puedas solicitar información de un Pokémon concreto\n    utilizando su nombre o número.\n        - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n        - Muestra el nombre de su cadena de evoluciones\n        - Muestra los juegos en los que aparece\n        - Controla posibles errores\n\"\"\"\n\n\ndef get_poke_info(poke_id):\n    try:\n        response = requests.get(f\"https://pokeapi.co/api/v2/pokemon/{poke_id}\")\n        response.raise_for_status()\n        data = response.json()\n        name = data[\"name\"].capitalize()\n        pokemon_id = data[\"id\"]\n        weight = data[\"weight\"] / 10\n        height = data[\"height\"] / 10\n        types = [t[\"type\"][\"name\"].capitalize() for t in data[\"types\"]]\n        evolution_url = f\"https://pokeapi.co/api/v2/pokemon-species/{poke_id}/\"\n        appearances1 = [entry[\"version\"][\"name\"]\n                        for entry in data[\"game_indices\"]]\n\n        \"\"\" evolution_response = requests.get(evolution_url)\n        evolution_response.raise_for_status()\n        evolution_data = evolution_response.json()#[\"evolution_chain\"][\"url\"]\n            \n        if \"evolution_chain\" in evolution_data and evolution_data[\"evolution_chain\"]:\n\n            evolution = [pokemon[\"species\"][\"name\"].capitalize()\n                        for pokemon in evolution_data[\"evolves_to\"]]\n        else:\n            evolution = [name]\"\"\"\n        response = requests.get(\n            f\"https://pokeapi.co/api/v2/pokemon-species/{poke_id}/\")\n        if response.status_code == 200:\n            url = response.json()[\"evolution_chain\"][\"url\"]\n            response = requests.get(url)\n            if response.status_code == 200:\n                data = response.json()\n\n                def get_evolves(data):\n                    stack = [data]\n                    stack1 = []\n                    while stack:\n                        current = stack.pop()\n                        if \"evolves_to\" in current:\n                            for evolve in current[\"evolves_to\"]:\n                                stack.append(evolve)\n                                stack1.append(evolve)\n                    return stack1\n                evolution = get_evolves(data[\"chain\"])\n            else:\n                print(\n                    f\"Error {response.status_code} obteniendo las evoluciones.\")\n        else:\n            print(f\"Error {response.status_code} obteniendo las evoluciones.\")\n\n        print(f\"\"\"  \n    Nombre: {name}\n    ID: {pokemon_id}\n    Peso: {weight} kg\n    Altura: {height} m\n    Tipo(s): {', '.join(types)}\n    Aparece en los juegos: {', '.join(appearances1)}\n    \"\"\")\n        print(\"Cadena de evolución:\", end=\"\")\n        while evolution:\n            c = evolution.pop()\n            if isinstance(c, str):\n                print(c, end=\", \")\n            else:\n                print(c[\"species\"][\"name\"], end=\", \")\n\n    except requests.exceptions.RequestException as error:\n        print(f\"Error en la petición: {error}\")\n    except ValueError:\n        print(\"Nombre o Id del pokemon invalido\")\n    except Exception as error:\n        print(f\"Error inesperado: {error}\")\n\n\nname_id = input(\"Ingresa el nombre o número del pokémon: \").lower()\n\nget_poke_info(name_id)\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/CaveroBrandon.py",
    "content": "\"\"\"EJERCICIO:\nUtilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\nuna petición a la web que tú quieras, verifica que dicha petición\nfue exitosa y muestra por consola el contenido de la web.\"\"\"\nimport requests\n\n\ndef get_an_activity() -> dict:\n    response = requests.get('https://www.boredapi.com/api/activity')\n    if response.status_code == 200:\n        return dict(response.json())\n    else:\n        print('Request failed')\n        return {}\n\n\ndef show_the_activity():\n    activity = get_an_activity()\n    if activity is not {}:\n        print('**** Bored API ****')\n        print(f'Activity: {activity.get(\"activity\")}')\n        print(f'Type of activity: {activity.get(\"type\")}')\n        print(f'Participants: {activity.get(\"participants\")}')\n        print(f'Price: {activity.get(\"price\")}')\n    else:\n        print('No activity to display')\n\n\n\"\"\"DIFICULTAD EXTRA (opcional):\nUtilizando la PokéAPI (https://pokeapi.co), crea un programa por\nterminal al que le puedas solicitar información de un Pokémon concreto\nutilizando su nombre o número.\n- Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n- Muestra el nombre de su cadena de evoluciones\n- Muestra los juegos en los que aparece\n- Controla posibles errores\"\"\"\n\n\ndef get_pokemon_by_name(pokemon_name: str) -> dict:\n    pokemon_name = pokemon_name.lower()\n\n    response = requests.get(f'https://pokeapi.co/api/v2/pokemon/{pokemon_name}/')\n    if response.status_code == 200:\n        return dict(response.json())\n    else:\n        return {}\n\n\ndef get_pokemon_evolution_chain(pokemon: dict) -> dict:\n    species_url = pokemon.get('species', {}).get('url')\n\n    if not species_url:\n        print('Species URL not found in the provided Pokemon dictionary')\n        return {}\n\n    species_response = requests.get(species_url)\n    if species_response.status_code != 200:\n        print('Failed to retrieve species data')\n        return {}\n\n    species_dict = species_response.json()\n\n    evolution_chain = species_dict.get('evolution_chain')\n    if not evolution_chain or 'url' not in evolution_chain:\n        print('Evolution chain URL not found in species data')\n        return {}\n\n    evolution_chain_url = evolution_chain['url']\n\n    evolution_chain_response = requests.get(evolution_chain_url)\n    if evolution_chain_response.status_code == 200:\n        evolution_chain_dict = evolution_chain_response.json()\n        return evolution_chain_dict\n    else:\n        print('Failed to retrieve evolution chain data')\n        return {}\n\n\ndef show_basic_pokemon_information(pokemon: dict):\n    print(f'Pokemon name: {pokemon.get(\"name\")}')\n    print(f'Pokemon id: {pokemon.get(\"id\")}')\n    print(f'Pokemon weight: {pokemon.get(\"weight\")}')\n    print(f'Pokemon height: {pokemon.get(\"height\")}')\n    print(f'Pokemon type: {pokemon.get(\"types\")[0][\"type\"][\"name\"]}')\n\n\ndef show_pokemon_evolution_chain(pokemon_evolution: dict):\n    try:\n        print(pokemon_evolution.get('chain', {}).get('species', {}).get('name'))\n    except IndexError as e:\n        pass\n    try:\n        print(pokemon_evolution.get('chain', {}).get('evolves_to', {})[0]['species']['name'])\n    except IndexError as e:\n        pass\n    try:\n        print(pokemon_evolution.get('chain', {}).get('evolves_to', {})[0]['evolves_to'][0]['species']['name'])\n    except IndexError as e:\n        pass\n\n\nprint('**** Exercise ****')\nshow_the_activity()\nprint('**** ****')\nwhile True:\n    pokemon_input = input('Enter the pokemon name or ID to search: ')\n    pokemon_info = get_pokemon_by_name(pokemon_name=pokemon_input)\n    if pokemon_info == {}:\n        print('That pokemon was not found, try again')\n    else:\n        print('\\n**** Pokemon basic information ****')\n        show_basic_pokemon_information(pokemon=pokemon_info)\n\n        print('\\n**** Pokemon evolution chain ****')\n        evolution_chain = get_pokemon_evolution_chain(pokemon=pokemon_info)\n        show_pokemon_evolution_chain(pokemon_evolution=evolution_chain)\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/CesarCarmona30.py",
    "content": "import requests\nfrom bs4 import BeautifulSoup\n\ndef get_website_content(url):\n  response = requests.get(url)\n  status = response.status_code\n  if status == 200:\n    print(\"La petición fue correcta\")\n    soup = BeautifulSoup(response.content, 'html.parser')\n    print(soup.prettify())\n  else:\n    print(f\"Petición fallida, código: {status}\")\n\ndef get_pokemon_data(name_or_id):\n  try:\n    response = requests.get(f'https://pokeapi.co/api/v2/pokemon/{name_or_id}')\n    response.raise_for_status()\n    data = response.json() \n    name = data[\"name\"].capitalize()\n    id = data[\"id\"]\n    weight = data[\"weight\"] / 10\n    height = data[\"height\"] / 10\n    types = [type[\"type\"][\"name\"].capitalize() for type in data[\"types\"]]\n    evolution_chain_url = data[\"species\"][\"url\"]\n    evolution_chain_response = requests.get(evolution_chain_url)\n    evolution_chain_response.raise_for_status()\n    evolution_chain_data = evolution_chain_response.json()\n\n    if \"chain\" in evolution_chain_data and evolution_chain_data[\"chain\"]:\n      evolution_chain = [pokemon[\"species\"][\"name\"].capitalize() for pokemon in evolution_chain_data[\"chain\"][\"evolves_to\"]]\n    else:\n      evolution_chain = [name]\n      game_appearances = [game[\"version\"][\"name\"] for game in data[\"game_indices\"]]\n\n    pokemon_info = f'''\n    POKEMON DATA:\n    -Name: {name}\n    -Id: {id}\n    -Weight: {weight} kg\n    -Height: {height} m\n    -Type(s): {', '.join(types)}\n    -Evolution chain: {' to '.join(evolution_chain)}\n    -Games: {', '.join(game_appearances)}\n    '''\n    return pokemon_info\n  except requests.HTTPError as err:\n    return f'Error al obtener datos: {err}'\n\nif __name__ == \"__main__\":\n    url = 'https://retosdeprogramacion.com/'\n    get_website_content(url)\n    pokemon_name_or_id = input(\"Enter the name or number of the Pokémon: \")\n    pokemon_info = get_pokemon_data(pokemon_name_or_id)\n    print(pokemon_info)\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/Chrisdev00.py",
    "content": "\"\"\"\n* EJERCICIO:\n* Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n* una petición a la web que tú quieras, verifica que dicha petición\n* fue exitosa y muestra por consola el contenido de la web.\n*\n* DIFICULTAD EXTRA (opcional):\n* Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n* terminal al que le puedas solicitar información de un Pokémon concreto\n* utilizando su nombre o número.\n* - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n* - Muestra el nombre de su cadena de evoluciones\n* - Muestra los juegos en los que aparece\n* - Controla posibles errores\n\"\"\"\n\nimport requests\n\nresponse_one = requests.get(\n    \"https://dummyapi.io/data/v1/user/\",\n    headers= {\n        \"app-id\": \"62b0433d2dfd91d4bf56c584\"\n    }\n)\n\nif response_one.status_code == 200:    \n    data = response_one.json()\n    result = data[\"data\"][0]\n    print(result)\nelse:\n    print(\"La solicitud no fue extisosa. Codigo de estado:\", response_one.status_code)\n\n\n############ -------------------------------- EXTRA ----------------------------------- ##############################\n\ndef info_pokemon(id_or_name):\n    response = requests.get(f\"https://pokeapi.co/api/v2/pokemon/{id_or_name}\")\n\n    if response.status_code == 200:        \n        data = response.json()\n\n        name = data[\"name\"]\n        id = data[\"id\"]\n        weight = data[\"weight\"]\n        height = data[\"height\"]\n        pokemon_type = [tipo[\"type\"][\"name\"].capitalize() for tipo in data[\"types\"]]\n        \n        # Obtener información sobre la cadena de evolución\n        species_url = data[\"species\"][\"url\"]\n        species_response = requests.get(species_url)\n        if species_response.status_code == 200:\n            species_data = species_response.json()\n            evolution_url = species_data.get(\"evolution_chain\", {}).get(\"url\")\n            if evolution_url:\n                evolution_response = requests.get(evolution_url)\n                if evolution_response.status_code == 200:\n                    evolution_data = evolution_response.json()\n                    evolution_chain = [evolution_data.get(\"chain\", {}).get(\"species\", {}).get(\"name\", \"\").capitalize()]\n                    while evolution_data.get(\"chain\", {}).get(\"evolves_to\"):\n                        evolution_data = evolution_data[\"chain\"][\"evolves_to\"][0]\n                        evolution_chain.append(evolution_data.get(\"species\", {}).get(\"name\", \"\").capitalize())\n                else:\n                    evolution_chain = [\"No se encontro informacion de evolucion\"]\n            else:\n                evolution_chain = [\"No se encontro URL de cadena de evolucion\"]\n        else:\n            evolution_chain = [\"No se encontro informacion de la especie\"]\n\n        # Obtener los nombres de los juegos en los que aparece el Pokemon\n        game_names = [game[\"version\"][\"name\"].replace(\"-\", \" \").capitalize() for game in data[\"game_indices\"]]\n\n        print(f\"Nombre del Pokemon: {name.capitalize()}\")\n        print(f\"ID del Pokemon: {id}\")\n        print(f\"Peso: {weight}\")\n        print(f\"Altura: {height}\")\n        print(f\"Tipo de Pokemon: {pokemon_type}\")\n        print(f\"Cadena de evolucion: {', '.join(evolution_chain)}\")\n        print(f\"Juegos en los que aparece: {', '.join(game_names)}\")        \n        \n    else:\n        print(\"La solicitud no fue exitosa. Codigo de estado:\", response.status_code)\n\nwhile True:\n    informacion = input(\"Ingrese el nombre o ID del Pokemon o 'salir' para salir: \").lower()\n    if informacion == \"salir\":\n        break\n    else:\n        info_pokemon(informacion)\n        print()\n\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/Complex303.py",
    "content": "\"\"\"\nPeticiones HTTP\n\"\"\"\n\n\"\"\"una petición HTTP es una solicitud que un cliente (como un navegador o una app) \nenvía a un servidor para pedir o enviar información a través de la web. \nSe compone de un método (como GET, POST, PUT o DELETE), una URL, y opcionalmente cabeceras y datos.\"\"\"\n\n# Importamos la librería requests, que permite hacer peticiones HTTP en Python.\nimport requests\nimport json\n# Realizamos una petición GET a la URL indicada (en este caso, el sitio de eBay)\n# response = requests.get(\"https://www.ebay.com/\")\n\n# # Verificamos si el código de estado de la respuesta es 200 (lo que significa que la petición fue exitosa)\n# if response.status_code == 200:\n#     # Si la respuesta fue exitosa, imprimimos el contenido de la página (en texto HTML)\n#     print(response.text)\n# else:\n#     # Si la respuesta no fue exitosa, mostramos un mensaje de error con el código de estado recibido\n#     print(f\"Error con codigo {response.status_code} al realizar la peticion\")\n\n\n\n\n\"\"\" * DIFICULTAD EXTRA (opcional):\n * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n * terminal al que le puedas solicitar información de un Pokémon concreto\n * utilizando su nombre o número.\n * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n * - Muestra el nombre de su cadena de evoluciones\n * - Muestra los juegos en los que aparece\n * - Controla posibles errores\"\"\"\n\n#un endpoint es una URL específica dentro de una API o servicio web a la que se puede enviar una petición para obtener o enviar datos.\n\n# Pedimos al usuario que escriba el nombre o número del Pokémon\n# Usamos .lower() para convertir todo a minúsculas y evitar errores por mayúsculas\npokemon = input(\"Introduce el nombre o el numero del pokemon a buscar: \").lower()\n\n# Realizamos una petición GET a la API de Pokémon para obtener información básica\nresponse = requests.get(f\"https://pokeapi.co/api/v2/pokemon/{pokemon}/\")\n\n# Verificamos si la respuesta de la API fue exitosa (código 200 = OK)\nif response.status_code == 200: \n    # Convertimos la respuesta JSON en un diccionario de Python\n    pokemon_data = response.json()\n\n    # Mostramos algunos datos del Pokémon en consola\n    print(\"Nombre: \", pokemon_data[\"name\"])       # Nombre del Pokémon\n    print(\"ID: \", pokemon_data[\"id\"])             # ID del Pokémon en la Pokédex\n    print(\"Peso: \", pokemon_data[\"weight\"])       # Peso del Pokémon\n    print(\"Altura: \", pokemon_data[\"height\"])     # Altura del Pokémon\n\n    # Mostramos los tipos del Pokémon (pueden ser 1 o 2)\n    print(\"Tipo(s): \", end=\"\") \n    print(\", \".join(tipo[\"type\"][\"name\"] for tipo in pokemon_data[\"types\"]))\n\n    # Mostramos los juegos en los que ha aparecido ese Pokémon\n    print(\"Juegos: \", end=\"\")\n    print(\", \".join(juego[\"version\"][\"name\"] for juego in pokemon_data[\"game_indices\"]))\n\n    # Hacemos otra petición para obtener información de la especie (donde está la cadena evolutiva)\n    response = requests.get(f\"https://pokeapi.co/api/v2/pokemon-species/{pokemon}/\")\n\n    # Si la respuesta fue exitosa\n    if response.status_code == 200:\n        # Obtenemos la URL de la cadena de evolución desde la respuesta\n        url = response.json()[\"evolution_chain\"][\"url\"]\n\n        # Hacemos otra petición a esa URL para obtener la cadena de evolución\n        response = requests.get(url)\n\n        # Si la respuesta fue exitosa\n        if response.status_code == 200:\n            # Convertimos la respuesta JSON en un diccionario\n            data = response.json()\n\n            # Mostramos el encabezado de la sección de evoluciones\n            print(\"Cadena de evolucion: \")\n\n            # Definimos una función recursiva para recorrer la cadena evolutiva\n            def get_evolves(data):\n                # Imprimimos el nombre de la especie actual\n                print(data[\"species\"][\"name\"])\n                # Verificamos si hay evoluciones en \"evolves_to\"\n                if \"evolves_to\" in data:\n                    # Por cada evolución encontrada, llamamos recursivamente a la función\n                    for evolve in data[\"evolves_to\"]:\n                        get_evolves(evolve)\n\n            # Llamamos a la función con la raíz de la cadena evolutiva\n            get_evolves(data[\"chain\"])\n        else:\n            # Si hubo error al obtener las evoluciones\n            print(f\"Error {response.status_code} obteniendo evoluciones\")\n    else:\n        # Si hubo error al obtener la especie del Pokémon\n        print(f\"Error {response.status_code} obteniendo evoluciones\")\n\n    # Creamos un diccionario con los datos resumidos del Pokémon\n    info_resumida = {\n        \"Nombre\": pokemon_data[\"name\"],\n        \"ID\": pokemon_data[\"id\"],\n        \"Peso\": pokemon_data[\"weight\"],\n        \"Altura\": pokemon_data[\"height\"],\n        \"Tipos\": [tipo[\"type\"][\"name\"] for tipo in pokemon_data[\"types\"]],\n        \"Juegos\": [juego[\"version\"][\"name\"] for juego in pokemon_data[\"game_indices\"]]\n    }\n\n    # Abrimos (o creamos) un archivo JSON para guardar el resumen\n    with open(f\"{pokemon}_resumen.json\", \"w\", encoding=\"utf-8\") as archivo:\n        # Guardamos el diccionario en el archivo con indentación de 4 espacios\n        json.dump(info_resumida, archivo, indent=4)\n\nelse:\n    # Si la primera petición falla (el Pokémon no existe o error en la API)\n    print(f\"Error: {response.status_code} pokemon no encontrado\")\n\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/EmmanuelMMontesinos.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n * una petición a la web que tú quieras, verifica que dicha petición\n * fue exitosa y muestra por consola el contenido de la web.\n */\n\"\"\"\n\n# Peticiones HTTP\nimport requests\n\nrespuesta = requests.get(\"https://retosdeprogramacion.com/\")\n\nif respuesta.status_code == 200:\n    print(respuesta.text)\n\nelse:\n    print(f\"Hay un error: {respuesta.status_code}\")\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n * terminal al que le puedas solicitar información de un Pokémon concreto\n * utilizando su nombre o número.\n * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n * - Muestra el nombre de su cadena de evoluciones\n * - Muestra los juegos en los que aparece\n * - Controla posibles errores\n\"\"\"\n\n# Clase para la consulta\nclass PokeConsulta:\n    \n    URL = \"https://pokeapi.co/api/v2/pokemon/\"\n\n    # Función para imprimir listas\n    def anidado(self,campo,nombre=None,evoluciones=False):\n        ciclo = 0\n        # Si NO son evoluciones\n        if not evoluciones:\n            for n in campo:\n                ciclo += 1\n                print(f\"{ciclo} - {n}\")\n        # Si son evoluciones\n        else:\n            marcador = \"Pre-Evolución\"\n            for n in campo:\n                ciclo += 1\n                if nombre == n:\n                    marcador = \"Pokemon Actual\"\n                elif nombre != n and marcador == \"Pokemon Actual\":\n                    marcador = \"Evolución\"\n                print(f\"{ciclo} - {n} ({marcador})\")\n\n        print()\n\n    # Función para consultar a la Api\n    def consultar(self,consulta):\n\n        respuesta = requests.get(f\"{PokeConsulta.URL+str(consulta)}\")\n\n        if respuesta.status_code == 200:\n            # Asigna valores para despues imprimirlos\n            pokemon = respuesta.json()\n            nombre = pokemon[\"name\"].title()\n            id = pokemon[\"id\"]\n            peso = pokemon[\"weight\"]\n            altura = pokemon[\"height\"]\n            tipos = [t[\"type\"][\"name\"].title() for t in pokemon[\"types\"]]\n\n            # Nueva request para obtener todas las evoluciones\n            evoluciones = []\n            respuesta_evo = requests.get(f\"https://pokeapi.co/api/v2/pokemon-species/{id}\")\n            respuesta_evo = respuesta_evo.json()\n            url_evo = respuesta_evo[\"evolution_chain\"][\"url\"]\n            respuesta_evo = requests.get(url_evo)\n            respuesta_evo = respuesta_evo.json()\n\n            check = False\n            nido = respuesta_evo[\"chain\"]\n            baby = None\n            if nido[\"is_baby\"] == True:\n                baby = nido[\"species\"][\"name\"].title()\n            while not check:\n                evoluciones.append(nido[\"species\"][\"name\"].title())\n                if len(nido[\"evolves_to\"]) == 0:\n                    check = True\n                else:\n                    nido = nido[\"evolves_to\"][0]\n            # Obtener todos los juegos donde aparece\n            juegos = [game[\"version\"][\"name\"].title() for game in pokemon[\"game_indices\"]]\n\n            # Imprimir Info\n            print(f\"Nombre: {nombre}\")\n            print(f\"ID: {id}\")\n            print(f\"Peso: {peso}\")\n            print(f\"Altura: {altura}\")\n            print()\n            print(\"Evoluciones:\")\n            print(f\"Bebe: {baby}\")\n            self.anidado(evoluciones,nombre=nombre,evoluciones=True)\n            print(\"Tipos:\")\n            self.anidado(tipos)\n            print(\"Ha salido en los siguientes Juegos:\")\n            self.anidado(juegos)\n        else:\n            print(f\"{consulta} no aparece en la api, comprueba que sea un nombre/numero válido\")\n\n# Programa en terminal\ndef program_terminal():\n\n    check = False\n    consulta = PokeConsulta()\n    while not check:\n\n        solicitud = input(\"Ponga el numero o el nombre de un pokemon (escribir 'salir' para cerrar): \")\n\n        if solicitud.lower() == \"salir\":\n            check = True\n        else:\n            consulta.consultar(solicitud)\n\n# Pruebas\nif __name__ == \"__main__\":\n    program_terminal()\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/FedeAirala.py",
    "content": " #20 PETICIONES HTTP\n\n\"\"\"\n * EJERCICIO:\n * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n * una petición a la web que tú quieras, verifica que dicha petición\n * fue exitosa y muestra por consola el contenido de la web.\n\"\"\"\nimport requests\nimport json\n\nrespuesta = requests.get(\"https://google.com\")\n\nif respuesta.status_code == 200:\n    print (respuesta.text)\nelse:\n    print (f\"Error {respuesta.status_code}, URL incorrecta\")\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n * terminal al que le puedas solicitar información de un Pokémon concreto\n * utilizando su nombre o número.\n * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n * - Muestra el nombre de su cadena de evoluciones\n * - Muestra los juegos en los que aparece\n * - Controla posibles errores\n\"\"\"\n\n\ndef data_pokemon(data):\n    name = data[\"name\"]\n    id = data[\"id\"]\n    weight = data[\"weight\"]\n    height = data[\"height\"]\n    types = data[\"types\"]\n    game = data[\"game_indices\"]\n    print (f\"Nombre: {name}\")\n    print (f\"ID: {id}\")\n    print (f\"Peso: {weight}\")\n    print (f\"Altura: {height}\")\n    print (\"Tipos:\")\n    for d in types:\n        x = d[\"type\"][\"name\"]\n        print (f\"{x}\",end = \" \")\n    print (\"\")\n    print (\"Juegos:\")\n    for d in game:\n        x = d[\"version\"][\"name\"]\n        print (f\"{x}\",end=\" / \")\n    \n\n\n\ndef pokemon_data():\n    pokemon = input (\"Ingrese pokémon que desea buscar :\").lower()\n    response = requests.get(f\"https://pokeapi.co/api/v2/pokemon/{pokemon}/\")\n    data = response.json()\n    if response.status_code == 200:\n        data_pokemon(data)\n    else:\n        print (f\"Error {response.status_code} , Pokemon no existe\")\n\npokemon_data()\n\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/Gallitofast.py",
    "content": "#Peticiones http\nimport requests\n\nresponse = requests.get(\"https://www.facebook.com\")\nif response.status_code==200:\n    print(response.text)\nelse:\n    print(f\"Error con codigo: {response.status_code} al realizar esta peticion.\")\n\n\n\"\"\"Dificultad extra\"\"\"\npokemon= input(\"Introduce the pokemon name or national pokedex number to search: \").lower()\n\nresponse= requests.get(f\"https://pokeapi.co/api/v2/pokemon/{pokemon}/\")\nif response.status_code==200:\n    data=response.json()\n    print(\"Pokemon name: \",data[\"name\"])\n    print(\"ID: \", data[\"id\"])\n    print(\"Weight: \",data[\"weight\"])\n    print(\"Height: \",data[\"height\"])\n    print(\"Types: \")\n    for type in data[\"types\"]:\n        print(type[\"type\"][\"name\"])\n    print(\"Games: \")\n    for game in data[\"game_indices\"]:\n        print(game[\"version\"][\"name\"])\n    \n    response = requests.get(f\"https://pokeapi.co/api/v2/pokemon-species/{pokemon}/\")\n    if response.status_code==200:\n        url=response.json()[\"evolution_chain\"][\"url\"]\n\n        response=requests.get(url)\n\n        if response.status_code==200:\n            data= response.json()\n\n            print(\"Evolution Chain\")\n\n            def get_evolves(data):\n                print(data[\"species\"][\"name\"])\n                if \"evolves_to\" in data:\n                    for evolve in data[\"evolves_to\"]:\n                        get_evolves(evolve)\n            get_evolves(data[\"chain\"])\n        else:\n            print(f\"Error: {response.status_code} obtaining evolutions.\")\n    else:\n            print(f\"Error: {response.status_code} obtaining evolutions.\")\nelse:\n    print(f\"Error: {response.status_code} Pokemon not found\")\n\n "
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/Gordo-Master.py",
    "content": "# 20 - Peticiones HTTP\n\nimport requests\n\nurl = \"https://moure.dev\"\n\nresponse = requests.get(url)\nif response.status_code == 200:\n    print(response.text)\nelse:\n    print(f\"Error con código {response.status_code} al realizar la petición\")\n\n\"\"\"\nEjercicio extra\n\"\"\"\n\nsession = requests.Session()\n\nname = input(\"Introduce un nombre o número del pokemon a buscar: \").lower()\n\nurl = f\"https://pokeapi.co/api/v2/pokemon/{name}/\"\n\nresponse = session.get(url)\n\ndata = response.json()\nif response.status_code == 200:\n    \n    name = data[\"name\"]\n    id = data[\"id\"]\n    weight = data[\"weight\"]\n    height = data[\"height\"]\n    type_pokemon = []\n    for i in data[\"types\"]:\n        type_pokemon.append(i[\"type\"][\"name\"])\n\n    response = session.get(data[\"species\"][\"url\"])\n    if response.status_code == 200:\n\n        url_2 = response.json()[\"evolution_chain\"][\"url\"]\n\n        response = session.get(url_2)\n\n        if response.status_code == 200:\n\n            data = response.json()\n            evolution = []\n\n            def create_the_total_list(data, all_evolves, actual_evolves = []):\n\n                actual_evolves.append(data[\"species\"][\"name\"])\n\n                if data[\"evolves_to\"] == []:\n                    all_evolves.append(list(actual_evolves))\n                else:\n                    for evolves in data[\"evolves_to\"]:\n                        create_the_total_list(evolves,all_evolves,actual_evolves)\n                \n                actual_evolves.pop()\n\n            \n            create_the_total_list(data[\"chain\"],evolution)\n\n\n    url_3 = f\"https://pokeapi.co/api/v2/pokemon/{id}/encounters\"\n\n    game_where_apear = []\n    for i in session.get(url_3).json():\n        game_where_apear.append(i[\"version_details\"][0][\"version\"][\"name\"])\n    game_where_apear = set(game_where_apear)\n\n    print(f\"Nombre: {name}\")\n    print(f\"ID: {id}\")\n    print(f\"Peso: {weight}\")\n    print(f\"Altura: {height}\")\n    print(f\"Tipos: {type_pokemon}\")\n    print(f\"Linea evolutiva: \")\n    for i in evolution:\n        print(i)\n    print(f\"Juegos donde aparece: {game_where_apear}\")\n\nelse:\n    print(f\"Nombre incorrecto, con error de {response.status_code}\")\n\nsession.close()"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/Hyromy.py",
    "content": "import requests # pip install requests\n\nYT_URL = \"https://www.youtube.com\"\n\ntry:\n    response = requests.get(YT_URL)\n    if response.status_code == 200: # 200 -> OK\n        print(\"Petición exitosa!\")\n        print(response.text[:128]) # Imprimir los primeros 128 caracteres de la pagina\n\nexcept requests.exceptions.RequestException as e:\n    print(e)\nprint(\"\\n\")\n\n# ---- DIFICULTAD EXTRA ----\n\npokeAPI = \"https://pokeapi.co/api/v2/pokemon/\"\n\nbusqueda = input(\"Ingrese el nombre o id de un pokemon => \")\n\ntry:\n    response = requests.get(pokeAPI + busqueda)\n    response.raise_for_status()\n    data = response.json()\n\nexcept Exception as e:\n    print(e)\n\nelse:\n    print(\"Nombre: \" + data[\"name\"])\n    print(\"ID: \" + str(data[\"id\"]))\n    print(\"Peso: \" + str(data[\"weight\"]))\n    print(\"Altura: \" + str(data[\"height\"]))\n    print(\"Tipos: \" + \", \".join([tipo[\"type\"][\"name\"] for tipo in data[\"types\"]]))\n\n    print(\"\\n\")\n\n    especies_data = requests.get(data[\"species\"][\"url\"]).json()\n    cadena_evolucion_data = requests.get(especies_data[\"evolution_chain\"][\"url\"]).json()\n    \n    evoluciones = [cadena_evolucion_data[\"chain\"][\"species\"][\"name\"]]\n    ev = cadena_evolucion_data[\"chain\"][\"evolves_to\"]\n    is_evolve = ev != []\n\n    while is_evolve:\n        evoluciones.append(ev[0][\"species\"][\"name\"])\n        ev = ev[0][\"evolves_to\"]\n        is_evolve = ev != []\n    \n    print(\"Cadena de evolución: \" + \" -> \".join(evoluciones))\n    print(\"Aparicion en juegos: \" + \", \".join([i[\"version\"][\"name\"] for i in data[\"game_indices\"]]))"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/Ikeragi05.py",
    "content": "'''\n * EJERCICIO:\n * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n * una petición a la web que tú quieras, verifica que dicha petición\n * fue exitosa y muestra por consola el contenido de la web.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n * terminal al que le puedas solicitar información de un Pokémon concreto\n * utilizando su nombre o número.\n * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n * - Muestra el nombre de su cadena de evoluciones\n * - Muestra los juegos en los que aparece\n * - Controla posibles errores\n'''\nimport requests\n\nbase_url =\"https://pokeapi.co/api/v2\"\npokemon= input(\"¿Que Pokemon quieres consultar?\\n\").lower()\n\n\nrequest= requests.get(f\"{base_url}/pokemon/{pokemon}\")\n\n\ndef obtener_cadena_evoluciones(pokemon):\n    global base_url\n    request= requests.get(f\"{base_url}/pokemon-species/{pokemon}\")\n\n    if request.status_code==200:\n        data= request.json()\n        cadena_url= data['evolution_chain']['url']\n        request_evolution= requests.get(cadena_url)\n\n    if request_evolution.status_code==200:\n        data_chain= request_evolution.json()\n        cadena_evoluciones = []\n        chain = data_chain['chain']\n        while chain:\n            cadena_evoluciones.append(chain['species']['name'])\n            if chain['evolves_to']:\n                chain = chain['evolves_to'][0]\n            else:\n                break\n\n        return cadena_evoluciones\nif request.status_code==200:\n    tipos=[]\n    evoluciones=obtener_cadena_evoluciones(pokemon)\n    juegos=[]\n    data=request.json()\n    print(f\"Nombre: {data['forms'][0]['name']}\")\n    print(f\"ID: {data['id']}\")\n    print(f\"Peso: {data['weight']}\")\n    print(f\"Altura: {data['height']}\")\n    for tipo in data['types']:\n        tipos.append(tipo['type']['name'])\n    print(f\"Tipos: {tipos}\")\n    print(f\"Cadena de evoluciones: {evoluciones}\")\n    for juego in data['game_indices']:\n        juegos.append(juego['version']['name'])\n    print(f\"Juegos en los que aparece: {juegos}\")\nelif request.status_code==404:\n   print(\"Pokemon no encontrado\")\nelse:\n    print(\"Algo salió mal\")\n\n\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/Irenetitor.py",
    "content": "import requests\n\n#Exercise\n\nresponse = requests.get(\"https://w3schools.com\")\nif response.status_code == 200:\n    print(response.text)\nelse:\n    print(f\"Error with code {response.status_code} when making the request\")\n\n\n#Extra Exercise\n\npokemon = input(\"Insert the name or number of the Pokemon to search:  \").lower()\n\nresponse = requests.get(f\"https://pokeapi.co/api/v2/pokemon/{pokemon}/\")\nif response.status_code == 200:\n    data = response.json()\n    print(\"Name: \", data[\"name\"])\n    print(\"Id: \", data[\"id\"] )\n    print(\"Weight: \", data[\"weight\"] )\n    print(\"Height: \", data[\"height\"] )\n    print(\"Type: \")\n    for type in data[\"types\"]:\n        print(type[\"type\"][\"name\"])\n    print(\"Games: \")\n    for game in data[\"game_indices\"]:\n        print(game[\"version\"][\"name\"])\n\n    response2 = requests.get(f\" https://pokeapi.co/api/v2/pokemon-species/{pokemon}\")\n    if response2.status_code == 200: \n        url = response2.json()[\"evolution_chain\"][\"url\"]\n        response2 = requests.get(url)\n        if response2.status_code == 200:\n            data = response2.json()\n\n            print(\"Evolution chain: \")\n            def get_evolves(data):\n                print(data[\"species\"][\"name\"])\n                if \"evolves_to\" in data:\n                    for evolve in data[\"evolves_to\"]:\n                        get_evolves(evolve)\n\n            get_evolves(data[\"chain\"])\n        else:\n            print(f\"Error {response.status_code}: Obtaining evolutions\")\n\n    else:\n        print(f\"Error {response.status_code}: Obtaining evolutions\")\n\nelse:\n    print(f\"Error {response.status_code}: Pokemon not found\")\n\n\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/JesusWay69.py",
    "content": "import requests, os\nos.system('cls')\n\n\"\"\" * EJERCICIO:\n * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n * una petición a la web que tú quieras, verifica que dicha petición\n * fue exitosa y muestra por consola el contenido de la web.\n *\n\"\"\"\n\ntry:\n    response = requests.get('https://retosdeprogramacion.com', timeout=1.00) \n    #Con la función get de response obtenemos la respuesta de la web que le pasemos por parámetro, también le podemos pasar\n        # otros parámetros como en este caso un límite de tiempo de espera en este caso de 1 segundo.\n    print(response.text) #Despues con el método text convertimos esa respuesta en el código html de la web.\n    print(response.status_code) #Con el método status_code obtenemos el código de estado de la respuesta.\nexcept requests.exceptions.RequestException: #Excepción genérica para cualquier fallo en la obtención de la respuesta\n    print(\"No se ha podido obtener la información\")\nexcept ConnectionError: #Excepción de comunicación con el servidor remoto.\n    print(\"Error de conexión\")\nexcept TimeoutError: #Excepción concreta de agotamiento del tiempo de espera especificado.\n    print(\"Se ha agotado el tiempo de espera\")\n\n\"\"\" \n * DIFICULTAD EXTRA (opcional):\n * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n * terminal al que le puedas solicitar información de un Pokémon concreto\n * utilizando su nombre o número.\n * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n * - Muestra el nombre de su cadena de evoluciones\n * - Muestra los juegos en los que aparece\n * - Controla posibles errores\"\"\"\n\ndef find():\n    pokemon_name = input(\"Escriba el nombre o número del pokemon a buscar: \")\n    try:\n        pokedata = get_data('https://pokeapi.co/api/v2/pokemon/'+ pokemon_name)\n    except requests.RequestException as ex:\n        print (\"URL no encontrada:  \",ex)\n    except Exception as name:\n        print(\"No se ha introducido ningún parámetro\",name)\n    else:\n        pokemon_types = [types['type']['name'] for types in pokedata['types']]\n        pokemon_games = [game_indices['version']['name'] for game_indices in pokedata['game_indices']]\n        \n        print('Nombre: ',pokedata['name'].capitalize())\n        print('ID:     ',pokedata['id'])\n        print('Peso:   ',pokedata['weight']/10, 'Kgs')\n        print('Altura: ',pokedata['height']/10, 'm')\n        print('Tipo/s:  ',', '.join(pokemon_types).title())\n        print('Juegos: ',', '.join(pokemon_games).title())\n        get_evolve('https://pokeapi.co/api/v2/evolution-chain/'+ str(pokedata['id']))\n\ndef get_data(url:str) ->dict:\n    pokemon_data = {\n    'name': '',\n    'id':'',\n    'weight':'',\n    'height':'',\n    'types':'',\n    'game_indices':'' \n    }\n  \n    response = requests.get(url)\n    data = response.json()\n    \n    pokemon_data['name'] = data['name']\n    pokemon_data['id'] = data['id']\n    pokemon_data['weight'] = data['weight']\n    pokemon_data['height'] = data['height']\n    pokemon_data['types'] = data['types']\n    pokemon_data['game_indices'] = data['game_indices']\n    return pokemon_data\n\ndef get_evolve(url:str):\n\n    response = requests.get(url)\n    data = response.json()['chain'] #diccionario principal\n    evolve = data['evolves_to'] #lista de diccionarios que almacenan las evoluciones\n\n    if (len(evolve) < 1):\n        return\n    else: \n        print(\"Evoluciones: \",end=' ')\n        for i in range (len(evolve)):\n            evo1:str = evolve[i]['species']['name']\n            print('\\b',evo1.capitalize(), end=', ')\n\n    if (len(evolve[0]['evolves_to']) < 1) :\n        return\n    else:\n        for j in range (len(evolve[0]['evolves_to'])):\n            evo2:str = evolve[0]['evolves_to'][j]['species']['name']\n            print('\\b',evo2.capitalize(), end=' ')\nprint()\nfind()\n\n\n\n\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/JheisonQuiroga.py",
    "content": "import requests\nimport sys\nfrom typing import List, Any\n\n# Author: Jheison Duban Quiroga Quintero\n# Github: https://github.com/JheisonQuiroga\n\n\"\"\"\n/*\n * EJERCICIO:\n * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n * una petición a la web que tú quieras, verifica que dicha petición\n * fue exitosa y muestra por consola el contenido de la web.\n\"\"\"\n\nurl = \"https://jsonplaceholder.typicode.com/todos/1\"\n\nresponse = requests.get(url)\nprint(response.status_code) # 200\n\nif response.status_code == 200:\n    print(response.json()) # Type dict\n    print(response.text) # Type str\n\nelse:\n    print(f\"Error al hacer la petición. Código de estado: {response.status_code}\")\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n * terminal al que le puedas solicitar información de un Pokémon concreto\n * utilizando su nombre o número.\n * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n * - Muestra el nombre de su cadena de evoluciones\n * - Muestra los juegos en los que aparece\n * - Controla posibles errores\n */\n\"\"\"\n\ndef get_evolutions(chain) -> List[str]:\n    evolutions = [chain['species']['name']]\n    for evolution in chain['evolves_to']:\n        evolutions.extend(get_evolutions(evolution))\n    return evolutions\n\ndef get_data_pokemon(pokemon_name: str) -> dict[str, Any] | Any:\n    \"\"\" Obtiene los datos de un pokémon a partir de su nombre o id\n    :param pokemon_name: Nombre o id del pokémon\n    :type pokemon_name: str\n    :return: Datos del pokémon\n    :rtype: dict\n    \"\"\"\n    try:\n        url = f\"https://pokeapi.co/api/v2/pokemon/{pokemon_name}\"\n        response = requests.get(url)\n        if response.status_code == 200:\n            pokemon_data = response.json()\n            url_species = pokemon_data['species']['url']\n            species_data = requests.get(url_species).json()['evolution_chain']['url']\n\n            # url_evolution_chain = species_data['evolution_chain']['url']\n            evolution_data = requests.get(species_data).json()\n\n            evolutions = list(dict.fromkeys(get_evolutions(evolution_data['chain'])))\n            games = [game['version']['name'] for game in pokemon_data['game_indices']]\n\n            return {\n                'name': pokemon_data['name'].capitalize(),\n                'id': pokemon_data['id'],\n                'height': pokemon_data['height'],\n                'weight': pokemon_data['weight'],\n                'types': [pokemon_type['type']['name'].capitalize() for pokemon_type in pokemon_data['types']],\n                'evolutions': evolutions,\n                'games': games\n            }\n\n        else:\n            raise Exception(f\"Fallo en recuperar los datos. Código de estado: {response.status_code}\")\n    except requests.exceptions.RequestException as e:\n        return None\n\n    \n\ndef main():\n    print(\"=\" * 5, \"Bienvenido a la PokéAPI\", \"=\" * 5)\n    while True:\n        pokemon = input(\"Ingresa el nombre o id del pokémon, salir para terminar el programa: \").lower().strip()\n\n        if pokemon == \"salir\":\n            print(\"¡Hasta luego!\")\n            return\n        \n        if not pokemon:\n            print(\"Debes ingresar un nombre o id de un pokémon valido!\")\n            continue\n\n        try:\n            data = get_data_pokemon(pokemon)\n            if data:\n                data = get_data_pokemon(pokemon) \n                print(f\"Name: {data['name']}\")\n                print(f\"Id: {data['id']}\")\n                print(f\"Height: {data['height']}\")\n                print(f\"Weight: {data['weight']}\")\n                print(f\"Type: {', '.join(data['types'])}\")\n                print(f\"Evolutions: {' → '.join(data['evolutions'])}\")\n                print(f\"Games: {', '.join(data['games'])}\")\n        except Exception as e:\n            print(f\"Error: {e}\")\n\n\n\nif \"__main__\" == __name__:\n    main()"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/JuanDAW37.py",
    "content": "\"\"\"* EJERCICIO:\n * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n * una petición a la web que tú quieras, verifica que dicha petición\n * fue exitosa y muestra por consola el contenido de la web.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n * terminal al que le puedas solicitar información de un Pokémon concreto\n * utilizando su nombre o número.\n * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n * - Muestra el nombre de su cadena de evoluciones\n * - Muestra los juegos en los que aparece\n * - Controla posibles errores\"\"\"\nimport requests\n\nurl = 'https://pokeapi.co'\n\nrespuesta = requests.get(url)\nif respuesta.status_code==200:\n    print(respuesta.text)\nelif respuesta.status_code == 404:\n    print(\"La petición no es válida\")\nelif respuesta.status_code == 500:\n    print(\"Error interno del servidor\")\n\n# EXTRA\nwhile True:    \n    nombre_pokemon = input(\"Introduce el nombre o el número del Pokémon, S/s para salir: \")\n    if nombre_pokemon == 'S' or nombre_pokemon == 's':\n        break\n    else:\n        # Datos generales del Pokémon\n        url_pokemon = f'https://pokeapi.co/api/v2/pokemon/{nombre_pokemon}'\n        respuesta = requests.get(url_pokemon)\n        if respuesta.status_code == 200:\n            datos = respuesta.json()\n            print(f'Id->{datos['id']}, Nombre-> {datos['name']}, peso-> {datos['weight']}, altura-> {datos['height']}')\n            print('Tipo(s):')\n            for type in datos['types']:\n                print(f'Tipo-> {type[\"type\"][\"name\"]}')  \n                \n            # Cadena de evoluciones\n            url_evoluciones = f'https://pokeapi.co/api/v2/pokemon-species/{nombre_pokemon}'\n            respuesta = requests.get(url_evoluciones)\n            if respuesta.status_code == 200:\n                url = respuesta.json()['evolution_chain']['url']\n                respuesta = requests.get(url)\n                if respuesta.status_code == 200:\n                    datos = respuesta.json()\n                    print('EVOLUCIÓN DEL POKEMON')                                        \n                    \n                    def evolucion(datos):                       \n                        print(datos['species']['name'])\n                        if 'evolves_to' in datos:\n                            for  evo in datos['evolves_to']:\n                                evolucion(evo)\n                                                            \n                    evolucion(datos['chain'])\n                \n                elif respuesta.status_code == 400:\n                    print(\"El nombre o el número del Pokémon no es válido\")\n                elif respuesta.status_code == 500:\n                    print(\"Error interno del servidor\")\n                    \n                # Juegos\n                respuesta = requests.get(url_pokemon)\n                if respuesta.status_code == 200:\n                    datos = respuesta.json()\n                    print('JUEGOS: ')\n                    for juego in datos['game_indices']:\n                        print(f'Número-> {juego['game_index']} - versión-> {juego[\"version\"][\"name\"]} - URL-> {juego[\"version\"][\"url\"]}')\n                elif respuesta.status_code == 400:\n                    print(\"El nombre o el número del Pokémon no es válido\")\n                elif respuesta.status_code == 500:\n                    print(\"Error interno del servidor\")\n                    \n            elif respuesta.status_code == 400:\n                print(\"El nombre o el número del Pokémon no es válido\")\n            elif respuesta.status_code == 500:\n                print(\"Error interno del servidor\")\n                \n        elif respuesta.status_code == 400:\n            print(\"El nombre o el número del Pokémon no es válido\")\n        elif respuesta.status_code == 500:\n            print(\"Error interno del servidor\")"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/Mauricio-Leyva.py",
    "content": "## Ejercicio\n\nimport requests\nfrom bs4 import BeautifulSoup\n\nurl = \"https://www.google.com\"\n\nresponse = requests.get(url)\n\nif response.status_code == 200:\n    print(\"La petición fue exitosa!\")\n\n    soup = BeautifulSoup(response.text, 'html.parser')\n\n    print(soup.prettify())\nelse:\n    print(f\"La petición falló con el código de estado: {response.status_code}\")\n\n\n\n\n## Dificultad extra\n\n\nimport requests\n\ndef get_pokemon_info(pokemon_name_or_id):\n    try:\n        response = requests.get(f\"https://pokeapi.co/api/v2/pokemon/{pokemon_name_or_id}\")\n        response.raise_for_status() \n\n        pokemon_data = response.json()\n\n        name = pokemon_data[\"name\"].capitalize()\n        pokemon_id = pokemon_data[\"id\"]\n        weight = pokemon_data[\"weight\"] / 10 \n        height = pokemon_data[\"height\"] / 10 \n        types = [t[\"type\"][\"name\"].capitalize() for t in pokemon_data[\"types\"]]\n        evolution_chain_url = pokemon_data[\"species\"][\"url\"]  \n        game_appearances = [entry[\"version\"][\"name\"] for entry in pokemon_data[\"game_indices\"]]\n\n        evolution_chain_response = requests.get(evolution_chain_url)\n        evolution_chain_response.raise_for_status()\n        evolution_chain_data = evolution_chain_response.json()\n\n        if \"chain\" in evolution_chain_data and evolution_chain_data[\"chain\"]:\n            evolution_chain = [pokemon[\"species\"][\"name\"].capitalize() for pokemon in evolution_chain_data[\"chain\"][\"evolves_to\"]]\n        else:\n            evolution_chain = [name]\n\n        print(f\"Nombre: {name}\")\n        print(f\"ID: {pokemon_id}\")\n        print(f\"Peso: {weight} kg\")\n        print(f\"Altura: {height} m\")\n        print(f\"Tipo(s): {', '.join(types)}\")\n        print(f\"Cadena de evolución: {' -> '.join(evolution_chain)}\")\n        print(f\"Aparece en los juegos: {', '.join(game_appearances)}\")\n\n    except requests.exceptions.RequestException as e:\n        print(f\"Error al realizar la petición: {e}\")\n    except ValueError:\n        print(\"El valor proporcionado no es un nombre o número de Pokémon válido.\")\n    except Exception as e:\n        print(f\"Error inesperado: {e}\")\n\n# Solicitar al usuario el nombre o número del Pokémon\npokemon_name_or_id = input(\"Ingresa el nombre o número del Pokémon: \").lower()\n\n# Llamar a la función para obtener la información del Pokémon\nget_pokemon_info(pokemon_name_or_id)\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/Nicojsuarez2.py",
    "content": "# #20 PETICIONES HTTP\n> #### Dificultad: Difícil | Publicación: 13/05/24 | Corrección: 20/05/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n * una petición a la web que tú quieras, verifica que dicha petición\n * fue exitosa y muestra por consola el contenido de la web.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n * terminal al que le puedas solicitar información de un Pokémon concreto\n * utilizando su nombre o número.\n * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n * - Muestra el nombre de su cadena de evoluciones\n * - Muestra los juegos en los que aparece\n * - Controla posibles errores\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/Sac-Corts.py",
    "content": "import requests\n\nurl = 'https://jsonplaceholder.typicode.com/posts/76'\nresponse = requests.get(url)\n\ndata = response.json()\n#print(data)\n\n### Ejercicio Extra ###\n\ndef get_pokemon_data(pokemon_name_or_id):\n    url = f'https://pokeapi.co/api/v2/pokemon/{pokemon_name_or_id.lower()}'\n    response = requests.get(url)\n    \n    if response.status_code != 200:\n        print(f\"Error: No se pudo encontrar el Pokémon '{pokemon_name_or_id}'. Código de estado: {response.status_code}\")\n        return None\n    return response.json()\n\ndef get_evolution_chain(url):\n    response = requests.get(url)\n    if response.status_code != 200:\n        print(f\"Error: No se pudo obtener la cadena de evoluciones. Código de estado: {response.status_code}\")\n        return None\n    return response.json()\n\ndef print_pokemon_info(pokemon):\n    print(f\"Nombre: {pokemon['name'].capitalize()}\")\n    print(f\"ID: {pokemon['id']}\")\n    print(f\"Peso: {pokemon['weight']} hectogramos\")\n    print(f\"Altura: {pokemon['height']} decímetros\")\n\n    types = [t['type']['name'] for t in pokemon['types']]\n    print(f\"Tipo(s): {', '.join(types).capitalize()}\")\n\ndef print_evolution_chain(evolution_chain):\n    chain = evolution_chain['chain']\n    evolution_names = []\n\n    while chain:\n        evolution_names.append(chain['species']['name'].capitalize())\n        if chain['evolves_to']:\n            chain = chain['evolves_to'][0]\n        else:\n            chain = None\n    \n    print(f\"Cadena de evoluciones: {', '.join(evolution_names)}\")\n\ndef print_game_indices(pokemon):\n    games = [game['version']['name'].capitalize() for game in pokemon['game_indices']]\n    print(f\"Juegos en los que aparece: {', '.join(games)}\")\n\ndef main():\n    pokemon_name_or_id = input(\"Introduce el nombre o número del Pokémon: \")\n    \n    pokemon = get_pokemon_data(pokemon_name_or_id)\n    if pokemon is None:\n        return\n\n    print_pokemon_info(pokemon)\n    \n    species_url = pokemon['species']['url']\n    species_data = requests.get(species_url).json()\n    \n    evolution_chain_url = species_data['evolution_chain']['url']\n    evolution_chain = get_evolution_chain(evolution_chain_url)\n    if evolution_chain:\n        print_evolution_chain(evolution_chain)\n    \n    print_game_indices(pokemon)\n\n\nmain()\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/SooHav.py",
    "content": "import requests\n\n# Ejercicio\n\nreq = requests.get(\"https://mouredev.com/brais-moure/\")\nprint(req.status_code)\nif req.status_code == 200:\n    print(req.text)\nelse:\n    print(f'Error: {req.status_code}')\n\n\n# Dificultad Extra\n\ndef info_pokemon(id=None, name=None):\n    if id is not None:\n        url = f'https://pokeapi.co/api/v2/pokemon/{id}'\n    elif name is not None:\n        url = f'https://pokeapi.co/api/v2/pokemon/{name.lower()}'\n    else:\n        print(\"Debes proporcionar un ID o un nombre.\")\n        return\n\n    response = requests.get(url)\n\n    if response.status_code == 200:\n        pokemon = response.json()\n        print(f\"Nombre: {pokemon['name']}\")\n        print(f\"ID: {pokemon['id']}\")\n        print(f\"Peso: {pokemon['weight']} hectogramos\")\n        print(f\"Altura: {pokemon['height']} decímetros\")\n        print(\"Tipos:\")\n        for tipo in pokemon['types']:\n            print(f\"  - {tipo['type']['name']}\")\n\n        especies_url = pokemon['species']['url']\n        especies_response = requests.get(especies_url)\n\n        if especies_response.status_code == 200:\n            especies = especies_response.json()\n            evolucion_url = especies['evolution_chain']['url']\n            evolucion_response = requests.get(evolucion_url)\n\n            if evolucion_response.status_code == 200:\n                evolucion = evolucion_response.json()\n                cadena = evolucion['chain']\n                print(\"Cadena de evolución:\")\n                while cadena:\n                    print(f\"  - {cadena['species']['name']}\")\n                    if cadena['evolves_to']:\n                        cadena = cadena['evolves_to'][0]\n                    else:\n                        break\n            else:\n                print(f'Error al obtener la cadena de evolución: {\n                      evolucion_response.status_code}')\n        else:\n            print(f'Error al obtener la especie del Pokémon: {\n                  especies_response.status_code}')\n\n        print(\"Aparece en los siguientes juegos:\")\n        for juego in pokemon['game_indices']:\n            print(f\"  - {juego['version']['name']}\")\n    else:\n        print(f'Error: {response.status_code}')\n\n\n# Ejemplo de uso\ninfo_pokemon('muk')\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/Trufoplus.py",
    "content": "###############################################################################\n### EJERCICIO\n###############################################################################\nimport requests\n\nresponse = requests.get('https://api.github.com')\n\nif response.status_code == 200:\n    print('Respuesta exitosa!')\n    content = response.json()\n    for line in content:\n        print(f'\\n{line} : {content[line]}')\nelse:\n    print('Error')\n\n\n###############################################################################\n### DIFICULTAD EXTRA\n###############################################################################\n\n\ndef pokemon_info(pokemon):\n    url = f'https://pokeapi.co/api/v2/pokemon/{pokemon.lower()}'\n    r = requests.get(url)\n    content = r.json()\n    \n    print('Nombre: ',content['name'].capitalize())\n    print('Id: ', content['id'])\n    print('Peso: ',content['weight'])\n    print('Altura: ',content['height'])\n    \n    types = []\n    for indice in range(0, len(content['types'])):\n        types.append(content['types'][indice]['type']['name'].capitalize())\n    print('Tipo: ', ', '.join(types))\n\n    url_species = content['species']['url']\n    r_species = requests.get(url_species)\n    species = r_species.json()\n\n    url_evolution_chain = species['evolution_chain']['url']\n    r_evolution = requests.get(url_evolution_chain)\n    evolution_chain = r_evolution.json()\n\n    current_chain = evolution_chain['chain']\n    evolves = []\n    while current_chain:\n        evolves_to = current_chain['evolves_to']\n        if evolves_to:\n            for evolution in evolves_to:\n                evolves.append(evolution['species']['name'].capitalize())\n            current_chain = evolves_to[0]\n        else:\n            break\n    print('Evoluciones:', \", \".join(evolves))\n\n    games = []\n    for indice in range(0, len(content['game_indices'])):\n        games.append(content['game_indices'][indice]['version']['name'])\n    print('Juegos en los que aparece: ', ', '.join(games))\n\n\n\npokemon = input('Introduce un pokemon: ')\npokemon_info(pokemon)"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/adra-dev.py",
    "content": "\"\"\"\nEJERCICIO:\nUtilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\nuna petición a la web que tú quieras, verifica que dicha petición\nfue exitosa y muestra por consola el contenido de la web.\n\nDIFICULTAD EXTRA (opcional):\nUtilizando la PokéAPI (https://pokeapi.co), crea un programa por\nterminal al que le puedas solicitar información de un Pokémon concreto\nutilizando su nombre o número.\n- Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n- Muestra el nombre de su cadena de evoluciones\n- Muestra los juegos en los que aparece\n- Controla posibles errores \n\nby adra-dev\n\"\"\"\nimport requests\n\nresponse = requests.get(\"https://api.github.com\")\n\nif response.status_code == 200:\n    print(response)\nelse:\n    print(f\"Error con codigo {response.status_code} al realizar la peticion.\")\n\n\n\"\"\"\nExtra\n\"\"\"\n\npokemon = input(\"Introduce un nombre o numero del Pokemon a buscar: \").lower()\n\nresponse = requests.get(f\"https://pokeapi.co/api/v2/pokemon/{pokemon}/\")\nif response.status_code == 200:\n    data = response.json()\n    print(\"Nombre: \", data[\"name\"])\n    print(\"ID: \", data[\"id\"])\n    print(\"Peso: \", data[\"weight\"])\n    print(\"Altura: \", data[\"height\"])\n    for type in data[\"types\"]:\n        print(type[\"type\"][\"name\"] )\n    \n    print(\"Juegos: \")\n    for game in data[\"game_indices\"]:\n        print(game[\"version\"][\"name\"])\n\n    response = requests.get(\n        f\"https://pokeapi.co/api/v2/pokemon-species/{pokemon}/\")\n    \n    if response.status_code == 200:\n        url = response.json()[\"evolution_chain\"][\"url\"]\n\n        response = requests.get(url)\n\n        if response.status_code == 200:\n            data = response.json()\n\n            print(\"Cadena de evolucion\")\n            \n\n            def get_evolves(data):\n                print(data[\"species\"][\"name\"])\n                if \"evolves_to\" in data:\n                    for evolve in data[\"evolves_to\"]:\n                        get_evolves(evolve)\n\n            get_evolves(data[\"chain\"])\n\n        else:\n            print(f\"Error {response.status_code} obteniendo las evoluciones\")\n    else: \n        print(f\"Error {response.status_code} obteniendo las evoluciones\")\nelse:\n    print(f\"Error {response.status_code}: Pokemon no encontrado\")\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/agusrosero.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n * una petición a la web que tú quieras, verifica que dicha petición\n * fue exitosa y muestra por consola el contenido de la web.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n * terminal al que le puedas solicitar información de un Pokémon concreto\n * utilizando su nombre o número.\n * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n * - Muestra el nombre de su cadena de evoluciones\n * - Muestra los juegos en los que aparece\n * - Controla posibles errores\n */\n\"\"\"\n\nimport requests\n\n# EJERCICIO:\npeticion = requests.get('https://www.google.com')\n\nif peticion.status_code == 200:\n    print(\"La peticion fue exitosa.\")\n    print(peticion.content)\nelse:\n    print(f\"Hubo un problema con la peticion: {peticion.status_code}\")\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/alanshakir.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n * una petición a la web que tú quieras, verifica que dicha petición\n * fue exitosa y muestra por consola el contenido de la web.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n * terminal al que le puedas solicitar información de un Pokémon concreto\n * utilizando su nombre o número.\n * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n * - Muestra el nombre de su cadena de evoluciones\n * - Muestra los juegos en los que aparece\n * - Controla posibles errores\n */\n\"\"\"\nimport requests\n\nurl = \"https://docs.python.org/es/3/tutorial/\"\nresponse = requests.get(url)\nstatus = response.status_code\n\nif status == 200:\n    print(\"Peticion exitosa\")\n    print(response.text)\nelse:\n    print(f\"Peticion fallida, error: {status}\")\n\n#Extra\n\npokemon = input(\"introduce el codigo o nombre del pokemon: \")\n\nresponse = requests.get(f\"https://pokeapi.co/api/v2/pokemon/{pokemon}/\")\n\nif response.status_code == 200:\n    data_pokemon = response.json()\n    print(\"Id: \", data_pokemon[\"id\"])\n    print(\"Name: \", data_pokemon[\"name\"])\n    print(\"Weight: \", data_pokemon[\"weight\"])\n    print(\"Height: \", data_pokemon[\"height\"])\n    for type in data_pokemon[\"types\"]:\n        print(\"Type(s): \", type[\"type\"][\"name\"]) \n    print(\"Game(s): \")\n    for game_index in data_pokemon[\"game_indices\"]:\n        print(game_index[\"version\"][\"name\"])       \n    response = requests.get(f\"https://pokeapi.co/api/v2/pokemon-species/{pokemon}/\")\n    if response.status_code == 200:\n        data_pokemon = response.json()[\"evolution_chain\"][\"url\"]\n        response = requests.get(data_pokemon)\n        if response.status_code == 200:\n            evolution_pokemon = response.json()\n            print(\"Cadena de evoluciones: \")\n            def evolutions(evolution_pokemon):\n                print(evolution_pokemon[\"species\"][\"name\"])\n                if \"evolves_to\" in evolution_pokemon:\n                    for evolution in evolution_pokemon[\"evolves_to\"]:\n                        evolutions(evolution)\n            evolutions(evolution_pokemon[\"chain\"])\n        else:\n            print(f\"No se encuentran cadena evoluciones para este pokemon, error: {response.status_code}\")\n    else:\n        print(f\"No se encuentran evoluciones para este pokemon, error: {response.status_code}\")\nelse:\n    print(f\"Peticion fallida, error: {response.status_code}\")\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/annaviper.py",
    "content": "import requests\nimport pandas as pd\n\nBASE_URL = \"https://pokeapi.co/api/v2/pokemon/\"\nr = requests.get(BASE_URL + \"jigglypuff\")\n\nif str(r.status_code).startswith(\"2\"):\n    data = r.json()\n    print(r.text)\nelse:\n    raise \n\nprint(f\"Nombre: {data['name']}\")\nprint(f\"ID: {data['id']}\")\nprint(f\"Peso: {data['weight']}\")\nprint(f\"Altura: {data['height']}\")\nprint(f\"Tipo(s): {', '.join([i['type']['name'] for i in data['types']])}\")\nprint(f\"Juegos(s): {', '.join([i['version']['name'] for i in data['game_indices']])}\")"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/any7dev.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n * una petición a la web que tú quieras, verifica que dicha petición\n * fue exitosa y muestra por consola el contenido de la web.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n * terminal al que le puedas solicitar información de un Pokémon concreto\n * utilizando su nombre o número.\n * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n * - Muestra el nombre de su cadena de evoluciones\n * - Muestra los juegos en los que aparece\n * - Controla posibles errores\n */ \"\"\"\n\n#EJERCICIO\nimport requests\n\ndef peticion(web):\n    respuesta = requests.get(web)\n\n    if respuesta.status_code == 200:\n        print(\"Petición Exitosa\")\n        print(f\"Contenido de la web:\\n{respuesta.text}\\n\")\n    else:\n        print(f\"Fallo al hacer la petición, código {respuesta.status_code}\\n\")\n\npeticion(\"https://www.google.es\")\npeticion(\"https://retosdeprogramacion.com/roadmap/\")\npeticion(\"https://thepiratebay3.com/\")\n\n#DIFICULTAD EXTRA\nINFO_POKEMON = \"https://pokeapi.co/api/v2/pokemon/\"\nINFO_SPECIES = \"https://pokeapi.co/api/v2/pokemon-species/\"\n\ndef inicio(pokemon):\n    url = INFO_POKEMON + pokemon\n    respuesta = requests.get(url)\n    datos = respuesta.json()\n    return datos            \n\ndef datos_simples(datos):\n    id = datos['id']\n    peso = datos['weight']\n    altura = datos['height']\n    return id, peso, altura\n\ndef tipos(datos):\n    tipos = datos['types']\n    lista_tipos = []\n    for tipo in tipos:\n        lista_tipos.append(tipo['type']['name'])\n    return lista_tipos\n\ndef games(datos):\n    juegos = datos['game_indices']\n    lista_juegos = []\n    for juego in juegos:\n        lista_juegos.append(juego['version']['name'])    \n    return lista_juegos\n\ndef datos_evo(id):\n    species = INFO_SPECIES + str(id) \n    respuesta = requests.get(species)\n    datos = respuesta.json()\n    evo_url = datos['evolution_chain']['url']\n    respuesta = requests.get(evo_url)\n    evo_json = respuesta.json()\n    return evo_json\n\ndef evoluciones(evo_json, lista = []):\n    lista.append(evo_json['species']['name'])\n    if \"evolves_to\" in evo_json: \n        for evo in evo_json['evolves_to']:\n            evoluciones(evo)\n    return lista\n\ndef extra():\n    pokemon = input(\"Dime el pokemon: \")\n    pokemon = pokemon.lower()\n    try:\n        data = inicio(pokemon)\n        id, peso, altura = datos_simples(data)\n        juegos = games(data)\n        json = datos_evo(id)\n        evo = evoluciones(json['chain'])\n        print(f\"Pokemon: {pokemon}, id: {id}, peso: {peso}, altura: {altura}\")\n        print(f\"Evoluciones: {evo}\")\n        print(f\"Juegos: {juegos}\")\n    except requests.exceptions.JSONDecodeError:\n        print(\"Pokemon no encontrado\")       \n\nextra()"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/avcenal.py",
    "content": "\"\"\"\n* EJERCICIO:\n * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n * una petición a la web que tú quieras, verifica que dicha petición\n * fue exitosa y muestra por consola el contenido de la web.\n\"\"\"\n\nfrom requests import get\nfrom time import sleep\n\nurl = \"https://retosdeprogramacion.com\"\nresponse = get(url)\nif response.status_code == 200:\n    print(response.text.replace(\">\",\">\\n\")) #doy formato a la respuesta\nelse:\n    print(f\"Error, código: {response.status_code}\")\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n * terminal al que le puedas solicitar información de un Pokémon concreto\n * utilizando su nombre o número.\n * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n * - Muestra el nombre de su cadena de evoluciones\n * - Muestra los juegos en los que aparece\n * - Controla posibles errores\n\"\"\"\n\ndef is_there_evolutions(json): #busca las evoluciones de manera recursiva y las almacena en una lista\n    evolutions = list()\n    if len(json[\"evolves_to\"])!= 0:\n        evolutions.append(json[\"species\"][\"name\"])\n        for index in range(0,(len(json[\"evolves_to\"]))):\n            evolutions.extend(is_there_evolutions(json[\"evolves_to\"][index]))\n    else:\n        evolutions.append(json[\"species\"][\"name\"])\n    return evolutions\n\ndef find_evolution(url):\n    evolutions = list()\n    response = get(url)\n    response_json = response.json()\n    evolutions = is_there_evolutions(response_json[\"chain\"])\n    return evolutions\n\ndef find_pokemon(response):\n    response_json = response.json()\n    response_species = get(response_json[\"species\"][\"url\"])\n    response_species_json = response_species.json()\n    response_evolution_url = response_species_json[\"evolution_chain\"][\"url\"]\n    evolutions = find_evolution(response_evolution_url)\n    name = response_json[\"forms\"][0][\"name\"]\n    id = response_json[\"id\"]\n    weight = response_json[\"weight\"]\n    height = response_json[\"height\"]\n    types = list()\n    for element in response_json[\"types\"]:\n        types.append(element[\"type\"][\"name\"])\n    games = list()\n    for element in response_json[\"game_indices\"]:\n        games.append(element[\"version\"][\"name\"])\n    return name,id,height,weight,types,evolutions,games\n\ndef make_http_request(data):\n    url = f\"https://pokeapi.co/api/v2/pokemon/{data}\"\n    response = get(url)\n    return response\n\ndef pokemon():\n    print(\"\\nTE DOY LA BIENVENIDA AL SISTEMA DE BÚSQUEDA DE POKEMONS - basado en la PokeAPI®\")\n    while True:\n        data = input(\"\\nDime el nombre del Pokemon que buscas o su número: \")\n        try:\n            pokemon = int(data)\n        except ValueError:\n            pokemon = data\n        response = make_http_request(pokemon)\n        if response.status_code == 200:\n            name,id,height,weight,types,evolutions,games = find_pokemon(response)\n            print(f\"\\nNombre: {name.title()}\")\n            print(f\"Número: {id}\")\n            print(f\"Altura: {float(height/10)} m\")\n            print(f\"Peso: {float(weight/10)} kg\\n\")\n            print(\"Elementos:\")\n            for type in types:\n                print(f\" - {type.title()}\")\n            print(\"\\nCadena de Evolución: \")\n            for evolution in evolutions:\n                print(f\" - {evolution.title()}\")\n            print(f\"\\nJuegos en los que aparece el pokemon {name.title()}\")\n            if len(games) == 0:\n                print(f\"Vaya parece que no tenemos registrado ningún juego en el que aparezca {name.title()}\")\n            else:\n                for game in games:\n                    print(f\" - {game.title()}\")\n        else:\n            print(\"No hay resultados para tu búsqueda\")\n        sleep(1)\n        print(\"\\n\")\n        option = input(\"¿Quieres buscar más pokemon?\\n - Si(S)\\n - No(N)\\n---> \").lower()\n        if option == \"n\":\n            print(\"Gracias por usar este sistema de búsqueda. Hasta Pronto\")\n            break\n\npokemon()\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/barrancus.py",
    "content": "# 20 - Python\n# \n# EJERCICIO:\n# Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n# una petición a la web que tú quieras, verifica que dicha petición\n# fue exitosa y muestra por consola el contenido de la web.\n# \n# DIFICULTAD EXTRA (opcional):\n# Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n# terminal al que le puedas solicitar información de un Pokémon concreto\n# utilizando su nombre o número.\n# - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n# - Muestra el nombre de su cadena de evoluciones\n# - Muestra los juegos en los que aparece\n# - Controla posibles errores\n# \n\nimport requests\nfrom bs4 import BeautifulSoup as bs\nimport json\n\nclass Counter:\n    def __iter__(self):\n        self.a = 1\n        return self\n    \n    def __next__(self):\n        x = self.a\n        self.a += 1\n        return x\n\ndef serparacion(cadena) -> str:\n    global contador\n    print(f'\\nEjercicio {next(contador)}. {cadena * 20}')\n\ndef ejercicio() -> None:\n    serparacion(\"_:_\")\n    web = requests.get(\"https://www.as.com\")\n    if web.status_code == 200:\n        testweb = bs(web.text, features=\"lxml\")\n        print(testweb)\n\ndef extra() -> None:\n    serparacion(\"_:_\")\n    # Busqueda recurente fases evolucion\n    def rev_poke_chain(chain) -> list:\n        test = []\n        if type(chain) == list:\n            for menta in chain:\n                chain = menta\n        if \"evolves_to\" in chain.keys() and len(chain[\"evolves_to\"]) != 0:\n            test = rev_poke_chain(chain[\"evolves_to\"])\n        test.append(chain[\"species\"][\"name\"])\n        return test\n    \n    while True:\n        print(\"\\nPor favor inserta el nº o el nombre del Pokemon que quieres buscar.\\nInserta 0 para salir.\")\n        search_pokemon = input(\"ID/Nombre: \")\n        if search_pokemon == \"0\":\n            break\n        pokeapi = requests.get(f\"https://pokeapi.co/api/v2/pokemon/{search_pokemon}/\")\n        if pokeapi.status_code == 200:\n            search_pokemon_info = json.loads(pokeapi.text)\n            poke_form = search_pokemon_info[\"forms\"]\n            for element in poke_form:\n                try:\n                    poke_name = element[\"name\"]\n                except:\n                    pass\n            poke_number = search_pokemon_info[\"id\"]\n            poke_height = search_pokemon_info[\"height\"]\n            poke_weight = search_pokemon_info[\"weight\"]\n            poke_game_indices = search_pokemon_info[\"game_indices\"]\n            poke_game_name=[]\n            for element in poke_game_indices:\n                version = element[\"version\"]\n                poke_game_name.append(version[\"name\"])\n\n            poke_weight = (poke_weight * 0.453592)\n            poke_height = (poke_height * 2.54)\n            print(f'\\nEl Pokemon {poke_name.upper()} es el id {poke_number}, tiene una altura de {poke_height:n} cm y un peso de {poke_weight:n} kilos.')\n            print(f'El Pokemon {poke_name.upper()} aparede en los juegos {poke_game_name}')\n            pokeapi2 = requests.get(f\"https://pokeapi.co/api/v2/pokemon-species/{search_pokemon}/\")\n            search_pokemon_info2 = json.loads(pokeapi2.text)\n            evol_chain = search_pokemon_info2[\"evolution_chain\"]\n            pokeapi3 = requests.get(evol_chain[\"url\"])\n            search_pokemon_evol = json.loads(pokeapi3.text)\n            poke_chain = search_pokemon_evol[\"chain\"]\n            chain = rev_poke_chain(poke_chain)\n            print(f'El Pokemon {poke_name.upper()} tiene la siguiente cadena de evolucion {chain}.\\n')\n\n        elif pokeapi.status_code >= 400 and pokeapi.status_code <= 499:\n            print('\\nProbablemente el Pokemon no existe o no está registrado, prueba con otro.')\n        elif pokeapi.status_code >= 500 and pokeapi.status_code <= 599:\n            print('\\nNo se puede proceder con la solicitud por problemas con el servidor.')\n        else:\n            print('\\nError desconocido, prueba con otro.')\n\ndef main() -> None:\n    ejercicio()\n    extra()\n\ncontador = iter(Counter())\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/beonzj.py",
    "content": "import requests\nimport sys\n\n#  EJERCICIO:\n#  Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n#  una petición a la web que tú quieras, verifica que dicha petición\n#  fue exitosa y muestra por consola el contenido de la web.\n\ndef exercise() -> str:\n    url = \"https://retosdeprogramacion.com/\"\n    response = requests.get(url)\n    if response.status_code != 200:\n        return f\"Error {response.status_code} al conectar con la API\"\n    return response.text\n        \n\n#  DIFICULTAD EXTRA (opcional):\n#  Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n#  terminal al que le puedas solicitar información de un Pokémon concreto\n#  utilizando su nombre o número.\n#  - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n#  - Muestra el nombre de su cadena de evoluciones\n#  - Muestra los juegos en los que aparece\n#  - Controla posibles errores\n\n\n\ndef api_response(pokemon: str) -> dict:\n    \n    response = requests.get(f\"https://pokeapi.co/api/v2/pokemon/{pokemon}\")\n      \n    if response.status_code == 200:\n        return response.json()\n    else:\n        if response.status_code == 404:\n            return None\n        else:\n            print(f\"Error {response.status_code} al conectar con la API\")\n            sys.exit()\n\ndef filtering_data(pokemon_dict: dict) -> dict:\n    data = pokemon_dict\n    leaked_pokemon_dict = {\n        \"name\": data[\"name\"].capitalize(),\n        \"id\": data[\"id\"],\n        \"weight\": data[\"weight\"] / 10,\n        \"height\": data[\"height\"] / 10,\n        \"types\": {t[\"type\"][\"name\"].capitalize() for t in data[\"types\"]},\n        \"games\": [g[\"version\"][\"name\"].capitalize() for g in data[\"game_indices\"]]\n        }\n    \n    return leaked_pokemon_dict\n        \ndef get_evolution_chain(pokemon_id: int) -> dict:\n    response = requests.get(f\"https://pokeapi.co/api/v2/pokemon-species/{pokemon_id}\")\n    if response.status_code != 200:\n        return f\"Error {response.status_code} al conectar con la API\"\n    else:\n        evolution_url = response.json()[\"evolution_chain\"][\"url\"]\n        response = requests.get(evolution_url)\n        if response.status_code != 200:\n            return f\"Error {response.status_code} al conectar con la API\"\n        else:\n            data = response.json()[\"chain\"]\n            leaked_chain = []\n\n            def get_evolves(data):\n                leaked_chain.append(data[\"species\"][\"name\"].capitalize())\n                if \"evolves_to\" in data:\n                    for evolve in data[\"evolves_to\"]:\n                        get_evolves(evolve)\n            get_evolves(data)\n            return leaked_chain\n            \ndef read_user_pokemon() -> str:\n    return input(\"Ingresa el nombre o número del pokémon: \").lower()\n\nif __name__=='__main__':\n    print(exercise(), \"\\n\\n\\n\\n\")\n    while True:\n        pokemon = read_user_pokemon()\n        api = api_response(pokemon)\n        \n        if api is not None:\n            data = filtering_data(api)\n            evolutions = get_evolution_chain(data[\"id\"])\n\n            print(\n                f\"\\nNombre: {data['name']}\\n\"\n                f\"ID: {data['id']}\\n\"\n                f\"Peso: {data['weight']} kg\\n\"\n                f\"Altura: {data['height']} m\\n\"\n            )\n\n            print(\"Tipo(s):\")\n            for type in data[\"types\"]:\n                print(type)\n            \n            print(\"\\nCadena de Evolución:\")\n            for evolution in evolutions:\n                print(evolution)\n\n            print(\"\\nJuegos en los que aparece:\")\n            for game in data[\"games\"]:\n                print(game)\n            break\n        else:\n            print(\"\\nPokémon no encontrado, por favor ingresa un nombre o id válido.\\n\")"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/cesar-ch.py",
    "content": "\"\"\"\n    * 20 PETICIONES HTTP \n\"\"\"\n\n\"\"\"\n    * DIFICULTAD EXTRA\n\"\"\"\n\nimport requests\n\n\ndef get_pokemon_data(identifier):\n    url = f\"https://pokeapi.co/api/v2/pokemon/{identifier}\"\n    response = requests.get(url)\n\n    if response.status_code != 200:\n        print(f\"Error: Pokémon no encontrado ({response.status_code})\")\n        return\n\n    data = response.json()\n    name = data[\"name\"]\n    id = data[\"id\"]\n    weight = data[\"weight\"]\n    height = data[\"height\"]\n    types = [type_info[\"type\"][\"name\"] for type_info in data[\"types\"]]\n\n    print(f\"Nombre: {name}\")\n    print(f\"ID: {id}\")\n    print(f\"Peso: {weight}\")\n    print(f\"Altura: {height}\")\n    print(f'Tipos: {\", \".join(types)}')\n\n    get_evolution_chain(data[\"species\"][\"url\"])\n    get_game_appearances(data[\"game_indices\"])\n\n\ndef get_evolution_chain(species_url):\n    response = requests.get(species_url)\n\n    if response.status_code != 200:\n        print(f\"Error al obtener la especie del Pokémon ({response.status_code})\")\n        return\n\n    species_data = response.json()\n    evolution_chain_url = species_data[\"evolution_chain\"][\"url\"]\n\n    response = requests.get(evolution_chain_url)\n    if response.status_code != 200:\n        print(f\"Error al obtener la cadena de evoluciones ({response.status_code})\")\n        return\n\n    chain = response.json()[\"chain\"]\n    evolution_names = []\n\n    def get_evolution_names(evolution):\n        evolution_names.append(evolution[\"species\"][\"name\"])\n        for evolves_to in evolution[\"evolves_to\"]:\n            get_evolution_names(evolves_to)\n\n    get_evolution_names(chain)\n    print(f'Cadena de Evoluciones: {\", \".join(evolution_names)}')\n\n\ndef get_game_appearances(game_indices):\n    games = [game[\"version\"][\"name\"] for game in game_indices]\n    print(f'Juegos en los que aparece: {\", \".join(games)}')\n\n\nif __name__ == \"__main__\":\n    pokemon = input(\"Introduce el nombre o número del Pokémon: \").lower()\n    get_pokemon_data(pokemon)\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/cristianfloyd.py",
    "content": "# EJERCICIO:\n# Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n# una petición a la web que tú quieras, verifica que dicha petición\n# fue exitosa y muestra por consola el contenido de la web.\n\nfrom typing import Any, Dict, Optional\n\nimport requests\n\ndef print_web_content(url: str) -> None:\n    response = requests.get(url)\n    if response.status_code == 200:\n        print(response.text)\n    else:\n        print(f\"Error: {response.status_code}\")\n\n\nprint_web_content(\"https://pokeapi.co/api/v2/pokemon/clefairy/\")\n\n#\n# DIFICULTAD EXTRA (opcional):\n# Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n# terminal al que le puedas solicitar información de un Pokémon concreto\n# utilizando su nombre o número.\n# - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n# - Muestra el nombre de su cadena de evoluciones\n# - Muestra los juegos en los que aparece\n# - Controla posibles errores\n\n\nclass PokemonInfo:\n    BASE_URL = \"https://pokeapi.co/api/v2/\"\n\n    def __init__(self, pokemon_id: str) -> None:\n        self.pokemon_id = pokemon_id.lower().strip()\n        self.pokemon_data: Optional[dict[str, Any]] = None\n        self.especies_data: Optional[dict[str, Any]] = None\n        self.cadena_evoluciones: Optional[dict[str, Any]] = None\n\n    def get_pokemon_info(self) -> bool:\n        \"\"\"Obtiene los datos basicos del pokemon\n\n        Retorns:\n        - True si se obtuvieron los datos correctamente\n        - False si no se obtuvieron los datos correctamente\n        \"\"\"\n\n        try:\n            response = requests.get(\n                f\"{self.BASE_URL}pokemon/{self.pokemon_id}\", timeout=10\n            )\n\n            if response.status_code == 200:\n                self.pokemon_data = response.json()\n                return True\n            else:\n                print(f\"Error: {response.status_code}\")\n                return False\n        except requests.exceptions.RequestException as e:\n            print(f\"Error: {e}\")\n            return False\n\n    def get_datos_especie(self):\n        \"\"\"Obtiene los datos de la especie del pokemon\n\n        Retorns:\n        - True si se obtuvieron los datos correctamente\n        - False si no se obtuvieron los datos correctamente\n        \"\"\"\n        try:\n            response = requests.get(\n                f\"{self.BASE_URL}pokemon-species/{self.pokemon_id}\", timeout=10\n            )\n\n            if response.status_code == 200:\n                self.especies_data = response.json()\n                return True\n            else:\n                print(\n                    f\"Error: {response.status_code} al obtener los datos de la especie\"\n                )\n                return False\n        except requests.exceptions.RequestException as e:\n            print(f\"Error: {e} al obtener los datos de la especie\")\n            return False\n\n    def get_cadena_evoluciones(self) -> bool:\n        \"\"\"Obtiene la cadena de evoluciones del pokemon\n\n        Retorns:\n        - True si se obtuvieron los datos correctamente\n        - False si no se obtuvieron los datos correctamente\n        \"\"\"\n        try:\n            if not self.especies_data:\n                print(\"Error: no se han obtenido los datos de la especie\")\n                return False\n\n            evolution_url = self.especies_data.get(\"evolution_chain\", {}).get(\"url\", \"\")\n\n            if not evolution_url:\n                print(\"Error: No se encontró la URL de la cadena de evoluciones\")\n                return False\n\n            response = requests.get(evolution_url, timeout=10)\n\n            if response.status_code == 200:\n                self.cadena_evoluciones = response.json()\n                return True\n            else:\n                print(\n                    f\"Error: {response.status_code} al obtener la cadena de evoluciones\"\n                )\n                return False\n\n        except requests.exceptions.RequestException as e:\n            print(f\"Error: {e} al obtener la cadena de evoluciones\")\n            return False\n\n    def show_informacion_basica(self):\n        \"\"\"Muestra la informacion basica del pokemon\"\"\"\n\n        if not self.pokemon_data:\n            print(\"Error: No se han obtenido los datos del pokemon\")\n            return\n\n        print(\"\\n\" + \"=\" * 50)\n        print(\"INFORMACIÓN DEL POKÉMON\")\n        print(\"=\" * 50)\n        print(f\"Nombre: {self.pokemon_data['name'].capitalize()}\")\n        print(f\"ID: {self.pokemon_data['id']}\")\n        print(f\"Peso: {self.pokemon_data['weight'] / 10:.1f} kg\")\n        print(f\"Altura: {self.pokemon_data['height'] / 10:.1f} m\")\n\n        tipos = [tipo[\"type\"][\"name\"] for tipo in self.pokemon_data.get(\"types\", [])]\n        print(f\"Tipo(s): {', '.join(tipo.capitalize() for tipo in tipos)}\")\n\n    def show_games(self):\n        \"\"\"Muestra los juegos en los que aparece el pokemon\"\"\"\n\n        if not self.pokemon_data:\n            print(\"Error: No se han obtenido los datos del pokemon\")\n            return\n\n        juegos = [\n            juego[\"version\"][\"name\"]\n            for juego in self.pokemon_data.get(\"game_indices\", [])\n        ]\n\n        if juegos:\n            print(\"\\n\" + \"=\" * 50)\n            print(\"JUEGOS EN LOS QUE APARECE\")\n            print(\"=\" * 50)\n            for juego in juegos:\n                print(f\" - {juego.replace('-', ' ').title()}\")\n        else:\n            print(\"\\nNo se han encontrado juegos en los que aparezca el pokemon\")\n\n    def show_cadena_evoluciones(self):\n        \"\"\"Muestra la cadena de evoluciones del pokemon\"\"\"\n        if not self.cadena_evoluciones:\n            print(\"Error: No hay datos en la cadena de evoluciones disponibles\")\n            return\n\n        print(\"\\n\" + \"=\" * 50)\n        print(\"CADENA DE EVOLUCIONES\")\n        print(\"=\" * 50)\n\n        def get_evoluciones(chain: Dict[str, Any], nivel: int = 0) -> None:\n            \"\"\"\n            Funcion recursiva\n\n            Args:\n                chain: La cadena de evoluciones\n                nivel: El nivel de indentacion\n            \"\"\"\n            nombre = chain[\"species\"][\"name\"]\n            identacion = \"  \" * nivel\n            print(f\"{identacion}- {nombre.capitalize()}\")\n\n            if chain.get(\"evolves_to\"):\n                for evolucion in chain[\"evolves_to\"]:\n                    get_evoluciones(evolucion, nivel + 1)\n\n        get_evoluciones(self.cadena_evoluciones[\"chain\"])\n\n    def show_toda_informacion(self) -> None:\n        \"\"\"Muestra toda la informacion del pokemon\"\"\"\n        if not self.get_pokemon_info():\n            return\n\n        self.show_informacion_basica()\n        self.show_games()\n\n        if self.get_datos_especie():\n            if self.get_cadena_evoluciones():\n                self.show_cadena_evoluciones()\n\n        print(\"\\n\" + \"=\" * 50)\n\n\ndef main():\n    print(\"=\" * 80)\n    print(\"CONSULTA INFORMACION DE UN POKEMON\")\n    print(\"=\" * 80)\n\n    pokemon_id = input(\"\\n Introduce el ID o nombre del pokemon: \")\n\n    if not pokemon_id:\n        print(\"Error: Debes introducir un ID o nombre de pokemon.\")\n        return\n\n    pokemon = PokemonInfo(pokemon_id)\n    pokemon.show_toda_informacion()\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/danielhdzr.py",
    "content": "# #20 PETICIONES HTTP\n#### Dificultad: Difícil | Publicación: 13/05/24 | Corrección: 20/05/24\n\n## Ejercicio\n\n'''\n * EJERCICIO:\n * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n * una petición a la web que tú quieras, verifica que dicha petición\n * fue exitosa y muestra por consola el contenido de la web.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n * terminal al que le puedas solicitar información de un Pokémon concreto\n * utilizando su nombre o número.\n * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n * - Muestra el nombre de su cadena de evoluciones\n * - Muestra los juegos en los que aparece\n * - Controla posibles errores\n'''\nimport requests\n\n'''\nresponse = requests.get((\"https://google.com\"))\nif response.status_code == 200:\n    print(response.text)\n    print(\"*****Se ha imprimido el codigo fuente de la pagina*****\")\nelse:\n    print(f\"Error: {response.status_code}\")\n'''\n    \n# Extra\n\npokemon = input(\"Introduce el nombre o numero del pokemon: \").lower()\n# Peticion al sitio web, a la seccion del pokemon elegido\npokedata = requests.get((f\"https://pokeapi.co/api/v2/pokemon/{pokemon}/\"))\n# Si la conexion es exitosa\nif pokedata.status_code == 200:\n    # Guardo los datos json de la web\n    datos = pokedata.json()\n    # Extraigo datos de los children correspondientes\n    print(\"Nombre: \", datos[\"name\"])\n    print(\"Id: \", datos[\"id\"])\n    print(\"Peso: \", datos[\"weight\"])\n    print(\"Altura: \", datos[\"height\"])\n    # Para pokemon con mas de un tipo\n    contador_de_tipos = 1\n    for type in datos[\"types\"]: # types guarda los tipos como un dict \n        # donde la key \"type\" guarda el value que es el \"name\" del tipo de pokemon\n        print(f\"Tipo({contador_de_tipos}): \", type[\"type\"][\"name\"])\n        contador_de_tipos += 1\n    # Imprime los juegos\n    print(\"Juegos:\")\n    # Itera dentro de la etiqueta y extrae lo encontrado\n    for game in datos[\"game_indices\"]:\n        print(game[\"version\"] [\"name\"])\n\n        '''\n        En busca de la cadena de evoluciones del pokemon\n        '''\n    # Peticion al sitio web del pokemon de nuevo, en el apartado de species\n    cadena_evoluciones = requests.get(f\"https://pokeapi.co/api/v2/pokemon-species/{pokemon}/\")\n    # Si conexion exitosa\n    if cadena_evoluciones.status_code == 200:\n    # Guardo el json, accedo al child \"evolucion_chain\", y a su grandchild \"url\"\n    # Asi obtengo la url de cada pokemon donde se guarda su cadena evolutiva\n        url = cadena_evoluciones.json()[\"evolution_chain\"][\"url\"]\n        # Peticion al url que tiene la cadena evolutiva\n        response = requests.get(url)\n\n        if response.status_code == 200:\n            # Guardo el json de la url de la cadena de evoluciones\n            datos = response.json()\n        # Funcion recursiva para obtener las evoluciones si las hubiera\n            def get_evolves(datos): # datos guarda el json\n                print(f\"especie y nombre: {datos[\"species\"][\"name\"]}\") # acceder al child y su sub-child\n                # etiqueta \"evolves_to\" contiene la evolcion en el json\n                if \"evolves_to\" in datos:\n                    '''\n                    Si encuentra \"evolves_to\" llama a la funcion de nuevo\n                    y trae las evoluciones encontradas dentro de cada evolucion\n                    '''\n                    for evolve in datos[\"evolves_to\"]:\n                        get_evolves(evolve)\n            # Llamado a la funcion. Parametro es la etiqueta \"chain\"\n            get_evolves(datos[\"chain\"])\n\n        else:\n            print(f\"Error {response.status_code}: Error con response\")\n\n    else:\n        print(f\"Error {cadena_evoluciones.status_code}: Error obteniendo cadena evolutiva\")\n\nelse:\n    print(f\"Error {pokedata.status_code}: Pokemon no encontrado\")"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/davidrguez98.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n * una petición a la web que tú quieras, verifica que dicha petición\n * fue exitosa y muestra por consola el contenido de la web.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n * terminal al que le puedas solicitar información de un Pokémon concreto\n * utilizando su nombre o número.\n * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n * - Muestra el nombre de su cadena de evoluciones\n * - Muestra los juegos en los que aparece\n * - Controla posibles errores\n */ \"\"\"\n\nimport requests\n\n#EJERCICIO\n\n\"\"\" response = requests.get(\"http://www.google.es\")\nif response.status_code == 200:\n    print(response.text)\n    print(response)\nelse:\n    (f\"Error con código {response.status_code} al utilizar la petición.\") \"\"\"\n    \n#DIFICULTAD EXTRA\n\npokemon = input(\"Introduce el nombre o número del Pokemon a buscar:\").lower()\n\nresponse_pokemon = requests.get(f\"https://pokeapi.co/api/v2/pokemon/{pokemon}/\")\nif response_pokemon.status_code == 200:\n    data = response_pokemon.json()\n    print(f\"\\nID: \", data[\"id\"])\n    print(f\"Nombre: \", data[\"name\"])\n    print(f\"Peso: \", data[\"weight\"])\n    print(f\"Altura: \", data[\"height\"])\n    for type in data[\"types\"]:\n        print(\"Tipo: \", type[\"type\"][\"name\"])\n\n    response_pokemon = requests.get(f\"https://pokeapi.co/api/v2/pokemon-species/{pokemon}/\")\n    if response_pokemon.status_code == 200:\n        url = response_pokemon.json()[\"evolution_chain\"][\"url\"]\n\n        response_pokemon = requests.get(url)\n\n        if response_pokemon.status_code == 200:\n            data = response_pokemon.json()\n\n            print(\"\\nCadena de evoluciones:\")\n\n            def get_evolves(data):\n                \n                print(data[\"species\"][\"name\"])\n                if \"evolves_to\" in data:\n                    for evolve in data[\"evolves_to\"]:\n                        get_evolves(evolve)\n\n            get_evolves(data[\"chain\"])\n\n        else:\n            print(\"Error\")\n         \n    else:\n        print(\"Error.\")\n\n    print(\"\\nListado de juegos:\")\n    response_pokemon = requests.get(f\"https://pokeapi.co/api/v2/pokemon/{pokemon}/\")\n    if response_pokemon.status_code == 200:\n        data = response_pokemon.json()\n        for game in data[\"game_indices\"]:\n            print(game[\"version\"][\"name\"])\n    else:\n        print(\"Error.\")\n\nelse:\n    print(\"Error, pokemon no encontrado.\")"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/didacdev.py",
    "content": "import requests as re\n\n\ndef check_connection():\n    try:\n        r = re.get(\"https://retosdeprogramacion.com\")\n        print(\"La petición fue existosa\")\n    except Exception as e:\n        print(f\"Error: {e}\")\n\n\ndef get_pokemon(identifier: str):\n    try:\n        r = re.get(f\"https://pokeapi.co/api/v2/pokemon/{identifier}\")\n        r_json = r.json()\n\n        types = r_json['types']\n\n        print(f\"\\nID: {r_json['id']}\")\n        print(f\"Nombre: {r_json['name']}\")\n        print(f\"Peso: {r_json['weight']} libras\")\n        print(f\"Altura: {r_json['height']} pies\")\n        print(f\"Tipos:\")\n        for type in types:\n            print(f\"    - {get_type(type['type']['url'])}\")\n\n    except Exception as e:\n        print(\"El Pokemon o ID no son válidos\")\n\n\ndef get_type(url: str):\n    r = re.get(url)\n    r_json = r.json()\n    return r_json['name']\n\n\ndef main():\n    finish = False\n\n    while not finish:\n\n        print(\"\\nSelecciona una opción:\\n\"\n              \"1 - Introducir nombre o ID del Pokemon\\n\"\n              \"2 - Salir\")\n        option = int(input(\"> \"))\n\n        match option:\n            case 1:\n                print(\"\\nEscribe el nombre o identificador del Pokemon\")\n                identifier = input(\"> \")\n                get_pokemon(identifier)\n            case 2:\n                finish = True\n                print(\"Hasta pronto 👋\")\n            case _:\n                print(\"⚠️ Opción seleccionada no válida\")\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/duendeintemporal.py",
    "content": "#20 { Retos para Programadores } PETICIONES HTTP\n\n# Bibliography reference\n# PokéAPI (https://pokeapi.co)\n# Additionally, I use GPT as a reference and sometimes to correct or generate proper comments.\n\n\"\"\"  \n * EJERCICIO:\n * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n * una petición a la web que tú quieras, verifica que dicha petición\n * fue exitosa y muestra por consola el contenido de la web.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n * terminal al que le puedas solicitar información de un Pokémon concreto\n * utilizando su nombre o número.\n * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n * - Muestra el nombre de su cadena de evoluciones\n * - Muestra los juegos en los que aparece\n * - Controla posibles errores\n\n\"\"\"\n\nimport requests\nimport time\n\n# Function to simulate console.log\ndef log(*args):\n    print(*args)\n\n# Simulating the window load event\ndef on_load():\n    log('Retosparaprogramadores #20')\n\n    # Simulating the modal creation\n    modal = {\n        'title': 'How many Paragraphs?',\n        'input': 0,\n        'result': '',\n    }\n\n    # Simulating user input for paragraphs count\n    modal['input'] = int(input(\"Enter number of paragraphs: \"))\n    get_lorem_ipsum(modal['input'])\n    log()\n\n# Function to get Lorem Ipsum text\ndef get_lorem_ipsum(number_of_paragraphs):\n    try:\n        response = requests.get(f'https://baconipsum.com/api/?type=meat-and-filler&paras={number_of_paragraphs}')\n        response.raise_for_status()\n        lorem_ipsum_text_array = response.json()\n        update_result(lorem_ipsum_text_array)\n    except Exception as error:\n        show_error(error)\n\n# Function to update the result\ndef update_result(text_array):\n    result = '\\n'.join(f'<p>{paragraph}</p>' for paragraph in text_array)\n    log(result)\n    log()\n    add_copy_button('\\n'.join(text_array))\n\n# Function to show error\ndef show_error(error):\n    log(f'Error: {error}')\n\n# Function to add a copy button (simulated)\ndef add_copy_button(text):\n    log('Copy button created. Text to copy:', text)\n    log()\n\n# Extra Difficulty Exercise\ndef get_pokemon(id):\n    try:\n        response = requests.get(f'https://pokeapi.co/api/v2/pokemon/{id}')\n        response.raise_for_status()\n        data = response.json()\n        pokemon = {\n            'name': f'Name: {data[\"name\"]}',\n            'id': f'Id: {data[\"id\"]}',\n            'weight': f'Weight: {data[\"weight\"]}',\n            'height': f'Height: {data[\"height\"]}',\n            'type': f'Type: {\", \".join(t[\"type\"][\"name\"] for t in data[\"types\"])}',\n            'games': f'Games: {\", \".join(g[\"version\"][\"name\"] for g in data[\"game_indices\"])}',\n        }\n        log(pokemon)\n        log()\n\n        # Simulating modal display for Pokémon data\n        display_pokemon_modal(pokemon)\n    except Exception as error:\n        log('Error fetching Pokémon:', error)\n\n# Function to display Pokémon modal (simulated)\ndef display_pokemon_modal(pokemon):\n    log('Displaying Pokémon Modal:')\n    for key, value in pokemon.items():\n        log(value)\n\n# Main execution\nif __name__ == \"__main__\":\n    on_load()\n    time.sleep(2)  # Simulating delay for user input\n    pokemon_id = input('Please type a number id to get the Pokémon data: ')\n    get_pokemon(pokemon_id)\n\n# Output Example:\n\"\"\"  \nRetosparaprogramadores #20\nEnter number of paragraphs: 4\n<p>Short ribs dolore incididunt dolore, ground round burgdoggen ut buffalo.  Shankle tempor ham hock ut ground round ad dolore esse.  Biltong shank sausage laborum dolore dolore landjaeger nisi.  Tenderloin reprehenderit jerky andouille tempor anim alcatra.</p>\n<p>Proident consequat venison, cupidatat cow pancetta ipsum occaecat irure sirloin shank lorem aute.  Eiusmod rump velit, jowl cupidatat mollit short loin culpa ut.  Picanha t-bone id est chislic.  Ut chislic sint, minim filet mignon turkey turducken excepteur consectetur occaecat beef venison est non shoulder.  Qui aute ribeye cupidatat, jerky dolore proident mollit pork chop tri-tip.  Ground round enim short loin veniam magna picanha strip steak, elit ribeye.</p>\n<p>Labore bacon frankfurter alcatra, minim ribeye cow non culpa id.  Pork loin lorem in, do commodo tempor rump in tri-tip tail ex shoulder.  Do tempor qui exercitation voluptate shankle capicola aute hamburger beef dolor.  Pork belly labore ex, alcatra andouille commodo ribeye leberkas reprehenderit shank ut do in jowl fatback.  Meatloaf ribeye deserunt, meatball ut irure id short ribs ea swine commodo tempor exercitation.  Tempor short loin t-bone ut tail chicken commodo shankle beef dolor.</p>\n<p>Prosciutto cupim ham aliqua proident, rump veniam duis minim.  Mollit jerky ut, pork labore voluptate t-bone salami pastrami id et pork chop ea tempor.  In meatball flank lorem non buffalo.  Shankle velit bresaola corned beef shoulder frankfurter.  Quis andouille aliqua biltong meatball cow ex in nostrud chuck ham tail tenderloin tempor.  T-bone short ribs consectetur bresaola enim laborum short loin sirloin et consequat occaecat shank minim sausage capicola.  Meatloaf capicola do enim, occaecat salami nostrud in incididunt id aliqua jowl deserunt sausage.</p>\n\nCopy button created. Text to copy: Short ribs dolore incididunt dolore, ground round burgdoggen ut buffalo.  Shankle tempor ham hock ut ground round ad dolore esse.  Biltong shank sausage laborum dolore dolore landjaeger nisi.  Tenderloin reprehenderit jerky andouille tempor anim alcatra.\nProident consequat venison, cupidatat cow pancetta ipsum occaecat irure sirloin shank lorem aute.  Eiusmod rump velit, jowl cupidatat mollit short loin culpa ut.  Picanha t-bone id est chislic.  Ut chislic sint, minim filet mignon turkey turducken excepteur consectetur occaecat beef venison est non shoulder.  Qui aute ribeye cupidatat, jerky dolore proident mollit pork chop tri-tip.  Ground round enim short loin veniam magna picanha strip steak, elit ribeye.\nLabore bacon frankfurter alcatra, minim ribeye cow non culpa id.  Pork loin lorem in, do commodo tempor rump in tri-tip tail ex shoulder.  Do tempor qui exercitation voluptate shankle capicola aute hamburger beef dolor.  Pork belly labore ex, alcatra andouille commodo ribeye leberkas reprehenderit shank ut do in jowl fatback.  Meatloaf ribeye deserunt, meatball ut irure id short ribs ea swine commodo tempor exercitation.  Tempor short loin t-bone ut tail chicken commodo shankle beef dolor.\nProsciutto cupim ham aliqua proident, rump veniam duis minim.  Mollit jerky ut, pork labore voluptate t-bone salami pastrami id et pork chop ea tempor.  In meatball flank lorem non buffalo.  Shankle velit bresaola corned beef shoulder frankfurter.  Quis andouille aliqua biltong meatball cow ex in nostrud chuck ham tail tenderloin tempor.  T-bone short ribs consectetur bresaola enim laborum short loin sirloin et consequat occaecat shank minim sausage capicola.  Meatloaf capicola do enim, occaecat salami nostrud in incididunt id aliqua jowl deserunt sausage.\n\nPlease type a number id to get the Pokémon data: 32\n{'name': 'Name: nidoran-m', 'id': 'Id: 32', 'weight': 'Weight: 90', 'height': 'Height: 5', 'type': 'Type: poison', 'games': 'Games: red, blue, yellow, gold, silver, crystal, ruby, sapphire, emerald, firered, leafgreen, diamond, pearl, platinum, heartgold, soulsilver, black, white, black-2, white-2'}\n\nDisplaying Pokémon Modal:\nName: nidoran-m\nId: 32\nWeight: 90\nHeight: 5\nType: poison\nGames: red, blue, yellow, gold, silver, crystal, ruby, sapphire, emerald, firered, leafgreen, diamond, pearl, platinum, heartgold, soulsilver, black, white, black-2, white-2\n\n\"\"\""
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/emersonxinay.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n * una petición a la web que tú quieras, verifica que dicha petición\n * fue exitosa y muestra por consola el contenido de la web.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n * terminal al que le puedas solicitar información de un Pokémon concreto\n * utilizando su nombre o número.\n * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n * - Muestra el nombre de su cadena de evoluciones\n * - Muestra los juegos en los que aparece\n * - Controla posibles errores\n */\n\"\"\"\n\nimport requests\n\n\ndef main():\n    url = \"https://www.compilandocode.com\"\n\n    try:\n        response = requests.get(url)\n        response.raise_for_status()  # Verifica si la petición fue exitosa\n\n        print(\"Contenido de la web:\")\n        print(response.text)  # Imprime el contenido de la respuesta\n\n    except requests.exceptions.RequestException as e:\n        print(\"Error al realizar la petición:\", e)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/fborjalv.py",
    "content": "\n\"\"\"\n/*\n * EJERCICIO:\n * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n * una petición a la web que tú quieras, verifica que dicha petición\n * fue exitosa y muestra por consola el contenido de la web.\n\"\"\"\n\n\nimport requests\n\nresponse = requests.get(\"https://www.elmundo.es\")\n\nif response.status_code == 200: \n    print(\"Respuesta correcta\")\nelse:\n    print(f\"Se ha producido un error: {response.status_code}\")\n\n#print(response.text)\n\n\n\"\"\"\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n * terminal al que le puedas solicitar información de un Pokémon concreto\n * utilizando su nombre o número.\n * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n * - Muestra el nombre de su cadena de evoluciones\n * - Muestra los juegos en los que aparece\n * - Controla posibles errores\n */\n\n\"\"\"\n\npokemon = input(\"¿Qué pokemon deseas consultar? \").lower()\n\n\nresponse = requests.get(f\"https://pokeapi.co/api/v2/pokemon/{pokemon}/\")\nif response.status_code == 200: \n    data = response.json()\n    print(f'Nombre: {data[\"name\"]}')\n    print(f'ID: {data[\"id\"]}')\n    print(f'Altura: {data[\"height\"]}')\n    print(f'Peso: {data[\"weight\"]}')\n    print(f'Tipo/s: {\", \".join([type[\"type\"][\"name\"] for type in data[\"types\"]])}')\n    print(f\"Juegos en los que aparece: {', '.join([game['version']['name'] for game in data['game_indices']])}\")\n    print(f'Evoluciones: ')\n    response = requests.get(f\"https://pokeapi.co/api/v2/pokemon-species/{pokemon}/\")\n    if response.status_code == 200:\n        data = response.json()\n        response = requests.get(data[\"evolution_chain\"][\"url\"])\n        if response.status_code == 200: \n            data = response.json()\n            \n            def get_evolutions(data):\n                if \"evolves_to\" in data:\n                    for item in data[\"evolves_to\"]:\n                        print((item[\"species\"][\"name\"]))\n                        get_evolutions(item)\n                        \n            get_evolutions(data[\"chain\"])\n        else: \n            print(f\"Error: {response.status_code}. \")\n    else: \n        print(f\"Error: {response.status_code}. \")\n\nelse:\n    print(f\"Error 404: el pokemon {pokemon} no existe\")"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/garos01.py",
    "content": "import requests\n\n\ndef obtener_contenido_web(url):\n    # Realizar la solicitud HTTP\n    respuesta = requests.get(url)\n\n    # Verificar si la solicitud fue exitosa (código de estado 200)\n    if respuesta.status_code == 200:\n        # Mostrar el contenido de la web por consola\n        print(respuesta.text)\n    else:\n        print(\"La solicitud no fue exitosa. Código de estado:\", respuesta.status_code)\n\n\n# URL de ejemplo\nurl_ejemplo = \"https://www.ejemplo.com\"\n\n# Llamar a la función con la URL deseada\nobtener_contenido_web(url_ejemplo)\n\n\n# Ejercicio extra\n\n\ndef obtener_informacion_pokemon(pokemon):\n    try:\n        # Realizar la solicitud a la PokéAPI\n        respuesta = requests.get(f\"https://pokeapi.co/api/v2/pokemon/{pokemon.lower()}\")\n        respuesta.raise_for_status()  # Levanta una excepción si la solicitud no fue exitosa\n        datos = respuesta.json()\n\n        # Obtener y mostrar la información básica del Pokémon\n        nombre = datos[\"name\"]\n        id_pokemon = datos[\"id\"]\n        peso = datos[\"weight\"]\n        altura = datos[\"height\"]\n        tipos = [tipo[\"type\"][\"name\"] for tipo in datos[\"types\"]]\n\n        print(f\"Nombre: {nombre.capitalize()}\")\n        print(f\"ID: {id_pokemon}\")\n        print(f\"Peso: {peso}\")\n        print(f\"Altura: {altura}\")\n        print(f\"Tipo(s): {', '.join(tipos)}\")\n\n        # Obtener la URL de la especie del Pokémon para más detalles\n        url_especie = datos[\"species\"][\"url\"]\n        respuesta_especie = requests.get(url_especie)\n        respuesta_especie.raise_for_status()\n        datos_especie = respuesta_especie.json()\n\n        # Obtener y mostrar la cadena de evoluciones\n        url_evoluciones = datos_especie[\"evolution_chain\"][\"url\"]\n        respuesta_evoluciones = requests.get(url_evoluciones)\n        respuesta_evoluciones.raise_for_status()\n        datos_evoluciones = respuesta_evoluciones.json()\n\n        cadena_evoluciones = []\n        actual = datos_evoluciones[\"chain\"]\n        while actual:\n            cadena_evoluciones.append(actual[\"species\"][\"name\"].capitalize())\n            actual = actual[\"evolves_to\"][0] if actual[\"evolves_to\"] else None\n\n        print(f\"Cadena de Evoluciones: {', '.join(cadena_evoluciones)}\")\n\n        # Obtener y mostrar los juegos en los que aparece\n        juegos = [\n            juego[\"version\"][\"name\"].capitalize() for juego in datos[\"game_indices\"]\n        ]\n        print(f\"Juegos: {', '.join(juegos)}\")\n\n    except requests.exceptions.HTTPError as err:\n        if err.response.status_code == 404:\n            print(f\"El Pokémon '{pokemon}' no se encontró.\")\n        else:\n            print(f\"Error en la solicitud: {err}\")\n    except Exception as e:\n        print(f\"Ha ocurrido un error: {e}\")\n\n\nif __name__ == \"__main__\":\n    pokemon = input(\"Introduce el nombre o número del Pokémon: \")\n    obtener_informacion_pokemon(pokemon)\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/ggilperez.py",
    "content": "# 20 HTTP requests\nfrom http import HTTPStatus\n\nimport requests  # It's not a built-in function, need \"python -m pip install requests\"\n\nresponse = requests.get(\"https://pokeapi.co/api/v2/\")\nif response.status_code == HTTPStatus.OK:\n    if \"application/json\" in response.headers.get(\"Content-Type\"):\n        print(response.json())\n    else:\n        print(response.text)\n\n\n# Extra\n\ndef show_pokemon_info(pokemon_id: str | int) -> None:\n    response = requests.get(f\"https://pokeapi.co/api/v2/pokemon/{pokemon_id}\")\n\n    if response.status_code != HTTPStatus.OK:\n        print(f\"Pokemon {pokemon_id} not found\")\n        return\n\n    if \"application/json\" not in response.headers.get(\"Content-Type\"):\n        print(\"Invalid response format\")\n        return\n\n    pokemon_data = response.json()\n\n    print(f\"Name: {pokemon_data.get('name')}\")\n    print(f\"ID: {pokemon_data.get('id')}\")\n    print(f\"Weight: {pokemon_data.get('weight')}\")\n    print(f\"Height: {pokemon_data.get('height')}\")\n    print(f\"Types:\")\n    for pok_type in pokemon_data.get('types', []):\n        print(f\"\\t{pok_type['type']['name']}\")\n\n    print(\"Games:\")\n    for pok_game in pokemon_data.get(\"game_indices\", []):\n        print(f\"\\t{pok_game['version']['name']}\")\n\n    evolves_url = pokemon_data[\"species\"][\"url\"]\n\n    response = requests.get(evolves_url)\n    if response.status_code != HTTPStatus.OK:\n        print(f\"Error {response.status_code} {response.reason} getting species\")\n        return\n\n    response = requests.get(response.json()[\"evolution_chain\"][\"url\"])\n    if response.status_code != HTTPStatus.OK:\n        print(f\"Error {response.status_code} {response.reason} getting evolution chain\")\n        return\n\n    if \"application/json\" not in response.headers.get(\"Content-Type\"):\n        print(\"Invalid response format from evolves\")\n        return\n\n    evolves_data = response.json()[\"chain\"]\n\n    def show_evolves(evo_data):\n        print(f\"\\t{evo_data['species']['name']}\")\n        if \"evolves_to\" in evo_data:\n            for evolve in evo_data[\"evolves_to\"]:\n                show_evolves(evolve)\n\n    print(\"Evolve chain:\")\n    show_evolves(evolves_data)\n\n\nshow_pokemon_info(\"pikachu\")\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/gringoam.py",
    "content": "import requests\n\n\"\"\"\nEjercicio\n\"\"\"\n\nrespuesta= requests.get(\"https://www.google.com\")\nprint(respuesta.status_code)\nif respuesta.status_code== 200:\n    print(respuesta.text)\n    \nelse:\n    print(f\"Error con codigo {respuesta.status_code} al realizar la petición\")\n\n\n\"\"\"\nExtra\n\"\"\"\n\npokemon = input(\"Introduce un nombre o número del Pokémon a buscar: \").lower()\n\nresponse = requests.get(f\"https://pokeapi.co/api/v2/pokemon/{pokemon}/\")\n\nif response.status_code == 200:\n    data = response.json()\n    print(\"Nombre: \", data[\"name\"])\n    print(\"ID: \", data[\"id\"])\n    print(\"Peso: \", data[\"weight\"])\n    print(\"Altura: \", data[\"height\"])\n    print(\"Tipo(s): \")\n    for type in data[\"types\"]:\n        print(type[\"type\"][\"name\"])\n    print(\"Juegos:\")\n    for game in data[\"game_indices\"]:\n        print(game[\"version\"][\"name\"])\n\n    response = requests.get(\n        f\"https://pokeapi.co/api/v2/pokemon-species/{pokemon}/\")\n\n    if response.status_code == 200:\n        url = response.json()[\"evolution_chain\"][\"url\"]\n\n        response = requests.get(url)\n\n        if response.status_code == 200:\n            data = response.json()\n\n            print(\"Cadena de evolución:\")\n\n            def get_evolves(data):\n                print(data[\"species\"][\"name\"])\n                if \"evolves_to\" in data:\n                    for evolve in data[\"evolves_to\"]:\n                        get_evolves(evolve)\n\n            get_evolves(data[\"chain\"])\n\n        else:\n            print(f\"Error {response.status_code} obteniendo las evoluciones.\")\n    else:\n        print(f\"Error {response.status_code} obteniendo las evoluciones.\")\nelse:\n    print(f\"Error {response.status_code}: Pokémon no encontrado\")\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/hectorio23.py",
    "content": "#! /bin/python3.11\n# Autor: Héctor Adán\n# GitHub: https://github.com/hectorio23 \nimport http.client\nimport json\n\n'''\n* EJERCICIO\n* Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n* una petición a la web que tú quieras, verifica que dicha petición\n* fue exitosa y muestra por consola el contenido de la web.\n*\n* DIFICULTAD EXTRA (opcional):\n* Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n* terminal al que le puedas solicitar información de un Pokémon concreto\n* utilizando su nombre o número.\n* - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n* - Muestra el nombre de su cadena de evoluciones\n* - Muestra los juegos en los que aparece\n* - Controla posibles errores\n'''\n\n##################################################\n################## EJERCICIO #####################\n##################################################\n\nHOSTNAME = 'www.python.org'\n\n# Se crea una instancia de HTTPSConnection\nconnection = http.client.HTTPSConnection(\n    host = HOSTNAME,  # Pagina de la documentacion de Python\n)\n\n# Se realiza la peticion al servidor\nconnection.request(method='GET', url=\"/\")\n\n# Se obtiene el resultado de la peticion\nresponse = connection.getresponse()\n\n#   Devuelve '+' si el status code se encuentra entre el rango 200 - 299 los cuales son códigos de exito   \nprint(f\"[{ '+' if 200 <= response.code < 300  else '-'}] Peticion al servidor { HOSTNAME } retornó un código { response.code }\")\nprint(\"Respuesta en binario: \\n\")\nif 200 <= response.code < 300: print(response.read())\n\n\n##################################################\n################ EJERCICIO EXTRA #################\n##################################################\n\nimport http.client\n\npoke_name_id = input(\"\\nIngrese el nombre/id de tu pokemon favorito: \").lower()\n\npoke_conn = http.client.HTTPSConnection(\"pokeapi.co\")\npoke_conn.request(\"GET\", f\"/api/v2/pokemon/{ poke_name_id }\")\npoke_resp = poke_conn.getresponse()\npoke_data = poke_resp.read().decode(\"utf-8\")\n\nif poke_resp.code == 200:\n    poke_json = json.loads(poke_data)\n    poke_name = poke_json[\"name\"].upper()\n    poke_id = poke_json[\"id\"]\n    poke_weight = poke_json[\"weight\"] / 10 \n    poke_height = poke_json[\"height\"] / 10 \n    poke_types = [typ[\"type\"][\"name\"].capitalize() for typ in poke_json[\"types\"]]\n    poke_evo_url = poke_json[\"species\"][\"url\"]  \n    poke_games = [entry[\"version\"][\"name\"] for entry in poke_json[\"game_indices\"]]\n\n    poke_conn.request(\"GET\", poke_evo_url)\n    evo_resp = poke_conn.getresponse()\n    evo_data = evo_resp.read().decode(\"utf-8\")\n\n    if evo_resp.code == 200:\n        evo_json = json.loads(evo_data)\n        if \"chain\" in evo_json and evo_json[\"chain\"]:\n            poke_evo_chain = [evo_poke[\"species\"][\"name\"].capitalize() for evo_poke in evo_json[\"chain\"][\"evolves_to\"]]\n        else:\n            poke_evo_chain = [poke_name]\n\n        print(f\"Nombre del pokemom: { poke_name }\")\n        print(f\"ID: { poke_id }\")\n        print(f\"Peso del pokemon: { poke_weight } kg\")\n        print(f\"Altura: { poke_height } mts\")\n        print(f\"Tipo(s): {', '.join(poke_types)}\")\n        print(f\"Cadena de evolución: {' -> '.join(poke_evo_chain)}\")\n        print(f\"Aparece en los juegos: {', '.join(poke_games)}\")\n    else:\n        print(\"Error al obtener datos de la cadena de evolución\")\nelse:\n    print(\"Error al obtener datos del Pokémon\")"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/hozlucas28.py",
    "content": "# pylint: disable=pointless-string-statement,broad-exception-caught,missing-module-docstring,missing-function-docstring\n\nfrom typing import TypedDict\n\nimport requests\n\n\"\"\"\n    HTTP request...\n\"\"\"\n\nprint(\"HTTP request...\")\n\nDogFactAttributes = TypedDict(\n    \"DogFactAttributes\",\n    {\n        \"body\": str,\n    },\n)\n\nDogFact = TypedDict(\n    \"DogFact\",\n    {\n        \"id\": str,\n        \"type\": str,\n        \"attributes\": DogFactAttributes,\n    },\n)\n\nDogRequest = TypedDict(\n    \"DogRequest\",\n    {\"data\": list[DogFact]},\n)\n\ntry:\n    response: requests.Response = requests.get(\n        url=\"https://dogapi.dog/api/v2/facts\", timeout=1000\n    )\n\n    if response.status_code == 200:\n        random_dog_fact: DogRequest = response.json()\n        print(f\"\\nRandom dog fact: {random_dog_fact[\"data\"][0][\"attributes\"][\"body\"]}\")\n    else:\n        raise RuntimeError(f\"{response.status_code} {response.text}\")\n\nexcept Exception as error:\n    print(f\"\\n{error}\")\n\n\nprint(\n    \"\\n# ---------------------------------------------------------------------------------- #\\n\"\n)\n\n\"\"\"\n    Additional challenge...\n\"\"\"\n\nprint(\"Additional challenge...\")\n\nTypeAttributes = TypedDict(\"TypeAttributes\", {\n    \"name\": str\n})\n\nType = TypedDict(\"Type\", {\n    \"type\": TypeAttributes\n})\n\nVersion = TypedDict(\"Version\", {\n    \"name\": str\n})\n\nGameIndex = TypedDict(\"GameIndex\", {\n    \"game_index\": int,\n    \"version\": Version,\n})\n\nPokemon = TypedDict(\"Pokemon\", {\n    \"game_indices\": list[GameIndex],\n    \"height\": int,\n    \"id\": int,\n    \"name\": str,\n    \"types\": list[Type],\n})\n\ndef get_pokemon(*,query: int | str) -> Pokemon:\n    __response: requests.Response = requests.get(\n        url=f\"https://pokeapi.co/api/v2/pokemon/{query}\",\n        timeout=1000\n    )\n\n    if __response.status_code == 200:\n        pokemon_data: Pokemon = __response.json()\n        return pokemon_data\n\n    raise RuntimeError(f\"{__response.status_code} {__response.text}\")\n\n\nprint(\"\\nPokemon with id number three...\")\n\ntry:\n    third_pokemon: Pokemon = get_pokemon(query=3)\n    print(f\"\\nid: {third_pokemon[\"id\"]}\")\n    print(f\"name: {third_pokemon[\"name\"]}\")\n    print(f\"height: {third_pokemon[\"height\"]}\")\n    print(f\"types: {[type[\"type\"][\"name\"] for type in third_pokemon[\"types\"]]}\")\n    print(f\"games: {[game[\"version\"][\"name\"] for game in third_pokemon[\"game_indices\"]]}\")\n\nexcept Exception as error:\n    print(f\"\\n{error}\")\n\nprint(\"\\nPokemon with 'Lugia' name...\")\n\ntry:\n    third_pokemon: Pokemon = get_pokemon(query=\"lugia\")\n    print(f\"\\nid: {third_pokemon[\"id\"]}\")\n    print(f\"name: {third_pokemon[\"name\"]}\")\n    print(f\"height: {third_pokemon[\"height\"]}\")\n    print(f\"types: {[type[\"type\"][\"name\"] for type in third_pokemon[\"types\"]]}\")\n    print(f\"games: {[game[\"version\"][\"name\"] for game in third_pokemon[\"game_indices\"]]}\")\n\nexcept Exception as error:\n    print(f\"\\n{error}\")\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/idiegorojas.py",
    "content": "\"\"\"\nPeticiones HTTP\n\"\"\"\n\n# Es la forma como un programa puede comunicarse con servidores web\n# Se usa para:\n    # Interactuar con APIs\n    # Descargar contenido\n    # Construir aplicaciones WEB\n\nimport requests\n\nresponse = requests.get('https://www.google.com/adsr4eta4rtserq32qDFA')\nif response.status_code == 200:\n    print(response.text)\nelse:\n    print(f'Error con codigo: {response.status_code} al realizar la peticion.')\n\nprint('--------------')\n\n\"\"\"\nExtra\n\"\"\"\n\npokemon = input('Introdusca el nombre o numero de Pokemon a consultar: ').lower()\n\nresponse = requests.get(f'https://pokeapi.co/api/v2/pokemon/{pokemon}/')\nif response.status_code == 200:\n    data = response.json()\n    print('Nombre: ', data['name'])\n    print('ID: ', data['id'])\n    print('Peso: ', data['weight'])\n    print('Altura: ', data['height'])\n    print('Tipos:')\n    for type in data['types']:\n        print(type['type']['name'])\n\n    response = requests.get(f'https://pokeapi.co/api/v2/pokemon-species/{pokemon}/')\n    if response.status_code == 200:\n        url = response.json()[\"evolution_chain\"][\"url\"]\n\n        response = requests.get(url)\n\n        if response.status_code == 200:\n            data = response.json()\n\n            print(\"Cadena de evolución:\")\n\n            def get_evolves(data):\n                print(data[\"species\"][\"name\"])\n                if \"evolves_to\" in data:\n                    for evolve in data[\"evolves_to\"]:\n                        get_evolves(evolve)\n\n            get_evolves(data[\"chain\"])\n\n        else:\n            print(f\"Error {response.status_code} obteniendo las evoluciones.\") \n    else:\n        print(f\"Error {response.status_code} obteniendo las evoluciones.\")\nelse:\n    print(f'Error {response.status_code}: Pokemon no encontrado.')\n\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/ignaciovihe.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n * una petición a la web que tú quieras, verifica que dicha petición\n * fue exitosa y muestra por consola el contenido de la web.\n\"\"\"\n\nimport requests\nimport time\n\nurl = \"https://www.python.org/\"\nanswer = requests.get(url)\nif answer.status_code == 200:\n    print(answer.text)\n\n\n\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n * terminal al que le puedas solicitar información de un Pokémon concreto\n * utilizando su nombre o número.\n * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n * - Muestra el nombre de su cadena de evoluciones\n * - Muestra los juegos en los que aparece\n * - Controla posibles errores\n\"\"\"\n\nimport asyncio\nimport aiohttp #modulo para llamadas http asincronas\n\nasync def call_api(session, url): # Función asincrona para las llamadas a la api\n    async with session.get(url) as answer: # La sesison creada por aiohttp funciona como el request.\n        if answer.status != 200:\n            return None\n        else:\n            return await answer.json() #Debe esperar porque sin el await devuelve una corutine(una promesa de los datos cuando termine la llamada)\n        \ndef print_evolutions(evolutions_root, level=0): # Funcion recursiva que imprime laas evoluciones de los pokemon. le paso la raiz de la cadena de evolución.\n    print(\"  \" * level  + f\"🔹{evolutions_root[\"species\"][\"name\"]}\")\n    for evolution in evolutions_root[\"evolves_to\"]:\n        print_evolutions(evolution, level + 1)\n\nasync def main():\n    id_pokemon = input(\"Intoduce el nombre o el numero de un pokemon: \").lower()\n    inicio = time.perf_counter()\n    url_info_pokemon = f\" https://pokeapi.co/api/v2/pokemon/{id_pokemon}/\" #genero los dos url que puedo llamar a la vez\n    url_species = f\"https://pokeapi.co/api/v2/pokemon-species/{id_pokemon}/\"\n    \n    async with aiohttp.ClientSession() as session: #el session es como el request. Para llamadas http asincronas. Utilizamos solo una sesión.\n        #Se hacen las dos primeras llamadas que no dependen entre si a la vez. Evolutions debe esperar a tener la url de especies.\n        info_pokemon_json, species_json = await asyncio.gather(call_api(session, url_info_pokemon), call_api(session, url_species))\n\n        if info_pokemon_json:\n            print(f\"Name: {info_pokemon_json[\"name\"]}\")\n            print(f\"Id: {info_pokemon_json[\"id\"]}\")\n            print(f\"Height: {info_pokemon_json[\"height\"]}\")\n            print(f\"Weight: {info_pokemon_json[\"weight\"]}\")\n            print(f\"Types: \")\n            for type in info_pokemon_json[\"types\"]:\n                print(f\"\\t🔸{type[\"type\"][\"name\"]}\")\n            print(\"Games: \")\n            for game in info_pokemon_json[\"game_indices\"]:\n                print(f\"\\t{game[\"version\"][\"name\"]}\")\n            \n            if species_json:\n                url_evolutions = species_json[\"evolution_chain\"][\"url\"]\n                evolutions_json = await call_api(session, url_evolutions) #aqui llamamos por tercera vez a la api y debemos esperar la respuesta.\n                if evolutions_json:\n                    print(\"\\nEvolutions: \")\n                    print_evolutions(evolutions_json[\"chain\"])\n                else:\n                    print(\"Error en la llamada a evolutions.\")    \n            else:\n                print(\"Error en la llamada a species.\")\n        else:\n            print(\"Error el poquemon no existe.\")\n    fin = time.perf_counter()  #Finalizamos el cronómetro\n    print(f\"\\n Tiempo total de ejecución: {fin - inicio:.2f} segundos\")\n\nasyncio.run(main())"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/isilanes.py",
    "content": "import requests\n\n\ndef main():\n    url = \"https://isilanes.org\"\n    response = requests.get(url)\n    assert response.status_code == 200\n    print(response.text)\n\n\ndef extra(name_or_pid: str | int | None = None):\n    name_or_pid = name_or_pid or input(\"Introduce el nombre o el ID del Pokémon: \")\n\n    if not name_or_pid:\n        print(\"Error: no has especificado qué Pokémon quieres.\")\n        return\n\n    pokemon = get_pokemon_by_name_or_id(name_or_pid)\n    pokemon_types = [t[\"type\"][\"name\"] for t in pokemon.get(\"types\", [])]\n    name: str = pokemon.get('name')\n\n    if not name:\n        print(\"Error. No pudimos encontrar ese Pokemon.\")\n        return\n\n    evolution_chain = get_evolution_chain(pokemon)\n    games = get_games(pokemon)\n\n    print(f\"Nombre:              {name}\")\n    print(f\"ID:                  {pokemon.get('id')}\")\n    print(f\"Altura:              {pokemon.get('height')}\")\n    print(f\"Peso:                {pokemon.get('weight')}\")\n    print(f\"Tipos:               {', '.join(pokemon_types)}\")\n    print(f\"Cadena de evolución: {' -> '.join(evolution_chain)}\")\n    print(f\"Juegos:              {', '.join(games)}\")\n\n\ndef get_games(pokemon: dict | None = None) -> list[str]:\n    return [g[\"version\"][\"name\"] for g in pokemon[\"game_indices\"]]\n\n\ndef get_evolution_chain(pokemon: dict | None = None) -> list[str]:\n    if not pokemon:\n        return []\n\n    species_url = pokemon[\"species\"][\"url\"]\n    species_data = requests.get(species_url).json()\n    chain_url = species_data.get(\"evolution_chain\", {}).get(\"url\")\n\n    if not chain_url:\n        return []\n\n    chain_data = requests.get(chain_url).json().get(\"chain\")\n\n    if not chain_data:\n        return []\n\n    chain = []\n    while chain_data:\n        name = chain_data[\"species\"][\"name\"]\n        if not name:\n            break\n\n        chain.append(name)\n\n        sub_chain = chain_data[\"evolves_to\"]\n        if not sub_chain:\n            break\n\n        chain_data = sub_chain[0]\n\n    return chain\n\n\ndef get_pokemon_by_name_or_id(name_or_pid: str | int | None = None) -> dict:\n    if not name_or_pid:\n        return {}\n\n    url = f\"https://pokeapi.co/api/v2/pokemon/{name_or_pid}\"\n    response = requests.get(url)\n\n    if response.status_code != 200:\n        return {}\n\n    return response.json()\n\n\nif __name__ == \"__main__\":\n    main()\n    extra()\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/jptxaya.py",
    "content": "# #20 PETICIONES HTTP\n# /*\n#  * EJERCICIO:\n#  * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n#  * una petición a la web que tú quieras, verifica que dicha petición\n#  * fue exitosa y muestra por consola el contenido de la web.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n#  * terminal al que le puedas solicitar información de un Pokémon concreto\n#  * utilizando su nombre o número.\n#  * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n#  * - Muestra el nombre de su cadena de evoluciones\n#  * - Muestra los juegos en los que aparece\n#  * - Controla posibles errores\n#  */\n\nimport requests\nimport json\n\nreq = requests.get(\"https://duckduckgo.com\")\n\nif req.status_code == 200:\n    print(\"Peticion Exitosa\")\n    print(\"Content:\")\n    print(req.content)\nelse:\n    print(\"Peticion Erronea\")\n    \nprint(\"****************************************\")\nprint(\"Dificultad Extra\")\nprint(\"Información de Pokemon\")\npokemon_id = input(\"Introduce el numero o nombre de Pokemon:\")\n\ndef get_evolucion(chain):\n    print(\"   -\"+chain[\"species\"][\"name\"])\n    for evol in chain[\"evolves_to\"]:\n        get_evolucion(evol)\n\nreq = requests.get(f\"https://pokeapi.co/api/v2/pokemon/{pokemon_id}\")\nif req.status_code == 200:\n    pokemon_data = req.json()\n    print(f\"Nombre:{pokemon_data[\"name\"]}\")\n    print(f\"Id:{pokemon_data[\"id\"]}\")\n    print(f\"Altura:{pokemon_data[\"height\"]}\")\n    print(f\"Peso:{pokemon_data[\"weight\"]}\")\n    print(\"Tipos:\")\n    for type_pokemon in pokemon_data[\"types\"]:\n        print(\"   *\"+type_pokemon[\"type\"][\"name\"])\n    print(\"Juegos:\")\n    for game_pokemon in pokemon_data[\"game_indices\"]:\n         print(\"   *\"+game_pokemon[\"version\"][\"name\"])\n    print(\"Evolution:\")\n    req = requests.get(f\"https://pokeapi.co/api/v2/pokemon-species/{pokemon_id}\")\n    if req.status_code != 200:\n        print(\"Error al obtener evolucion\")\n    else:\n        url_evolution_chain = req.json()[\"evolution_chain\"][\"url\"]\n        #print(url_evolution_chain)\n        req = requests.get(url_evolution_chain)\n        get_evolucion(req.json()[\"chain\"])\n    \nelif req.status_code == 404:\n    print(\"Pokemon no Encontrado\")  \nelse:\n    print(f\"Peticion Erronea. Status Code: {req.status_code}\")\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/juanmax2.py",
    "content": "import requests\n\n\"\"\"\nEjercicio\n\"\"\"\n\nresponse = requests.get(\"https://google.com\")\n\n# Mostrar por consola el contenido de la web\nif response.status_code == 200:\n    print(response.text)\nelse:\n    print(f\"Error con codigo {response.status_code} al realizar la petición\")\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n * terminal al que le puedas solicitar información de un Pokémon concreto\n * utilizando su nombre o número.\n * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n * - Muestra el nombre de su cadena de evoluciones\n * - Muestra los juegos en los que aparece\n * - Controla posibles errores\n\"\"\"\n\npokemon = input(\"Introduce el nombre o numero de un pokemon: \").lower()\n\npoke_response = requests.get(f\"https://pokeapi.co/api/v2/pokemon/{pokemon}/\")\nif poke_response.status_code == 200:\n    data = poke_response.json()\n    print(f\"Nombre: {data[\"name\"]}\")\n    print(f\"Peso: {data[\"weight\"]}\")\n    print(f\"ID: {data[\"id\"]}\")\n    print(f\"Altura: {data[\"height\"]}\")\n    print(\"Tipo(s):\")\n    for type in data[\"types\"]:\n        print(f\"{type[\"type\"][\"name\"]}\")\n    print(\"Juegos en los que aparece:\")\n    for game in data[\"game_indices\"]:\n        print(game[\"version\"][\"name\"])\n        \n    poke_response = requests.get(f\"https://pokeapi.co/api/v2/pokemon-species/{pokemon}/\")\n    if poke_response.status_code == 200:\n        url = poke_response.json()[\"evolution_chain\"][\"url\"]\n        \n        poke_response = requests.get(url)\n        if poke_response.status_code == 200:\n            data = poke_response.json()\n            \n            print(\"Cadena de evolución:\")\n            \n            \n            def get_evolves(data):\n                print(data[\"species\"][\"name\"])\n                if \"evolves_to\" in data:\n                    for evolve in data[\"evolves_to\"]:\n                        get_evolves(evolve)\n                \n            get_evolves(data[\"chain\"])\n                       \n        else:\n            print(f\"Error {poke_response.status_code} al realizar la petición.\")\n    else:\n        print(f\"Error {poke_response.status_code} al realizar la petición.\")\n    \n\nelse:\n    print(f\"Error con código {response.status_code} al realizar la petición\")\n    \n    "
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/juanppdev.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n * una petición a la web que tú quieras, verifica que dicha petición\n * fue exitosa y muestra por consola el contenido de la web.\n\"\"\"\n\nimport requests\n\n# URL de la página web a la que quieres hacer la petición\nurl = 'https://www.example.com'\n\ntry:\n    # Realizar la petición HTTP\n    response = requests.get(url)\n    \n    # Verificar si la petición fue exitosa (código de estado 200)\n    if response.status_code == 200:\n        print(\"Petición exitosa!\")\n        # Mostrar el contenido de la web\n        print(response.text)\n    else:\n        print(f\"Error en la petición: {response.status_code}\")\nexcept requests.exceptions.RequestException as e:\n    print(f\"Error en la petición: {e}\")\n\n\n\"\"\" \n* DIFICULTAD EXTRA (opcional):\n * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n * terminal al que le puedas solicitar información de un Pokémon concreto\n * utilizando su nombre o número.\n * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n * - Muestra el nombre de su cadena de evoluciones\n * - Muestra los juegos en los que aparece\n * - Controla posibles errores\n\"\"\"\n\nimport requests\n\ndef get_pokemon_info(pokemon):\n    url = f'https://pokeapi.co/api/v2/pokemon/{pokemon}'\n    try:\n        response = requests.get(url)\n        response.raise_for_status()  # Verifica si la petición fue exitosa\n        data = response.json()\n\n        # Información básica del Pokémon\n        name = data['name']\n        id = data['id']\n        weight = data['weight']\n        height = data['height']\n        types = [t['type']['name'] for t in data['types']]\n\n        print(f\"Nombre: {name}\")\n        print(f\"ID: {id}\")\n        print(f\"Peso: {weight}\")\n        print(f\"Altura: {height}\")\n        print(f\"Tipo(s): {', '.join(types)}\")\n\n        # Obtener la cadena de evoluciones\n        species_url = data['species']['url']\n        species_response = requests.get(species_url)\n        species_data = species_response.json()\n        evolution_chain_url = species_data['evolution_chain']['url']\n        evolution_response = requests.get(evolution_chain_url)\n        evolution_data = evolution_response.json()\n\n        print(\"Cadena de evoluciones:\")\n        chain = evolution_data['chain']\n        while chain:\n            print(chain['species']['name'])\n            if chain['evolves_to']:\n                chain = chain['evolves_to'][0]\n            else:\n                chain = None\n\n        # Obtener los juegos en los que aparece\n        games = [game['version']['name'] for game in data['game_indices']]\n        print(f\"Juegos: {', '.join(games)}\")\n\n    except requests.exceptions.HTTPError as http_err:\n        print(f\"HTTP error occurred: {http_err}\")\n    except Exception as err:\n        print(f\"Other error occurred: {err}\")\n\nif __name__ == \"__main__\":\n    pokemon = input(\"Introduce el nombre o número del Pokémon: \").lower()\n    get_pokemon_info(pokemon)\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/kenysdev.py",
    "content": "# ╔═════════════════════════════════════╗\n# ║ Autor:  Kenys Alvarado              ║\n# ║ GitHub: https://github.com/Kenysdev ║\n# ║ 2024 -  Python                      ║\n# ╚═════════════════════════════════════╝\n\n# -----------------------------------\n# * PETICIONES HTTP\n# -----------------------------------\n# Mas info: https://www.datacamp.com/es/tutorial/making-http-requests-in-python\n\n# pip install requests\n# https://requests.readthedocs.io/en/latest/\n\nimport requests\nimport textwrap\n\n\"\"\"\n* EJERCICIO #1:\n* Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n* una petición a la web que tú quieras, verifica que dicha petición\n* fue exitosa y muestra por consola el contenido de la web.\n\"\"\"\n\ndef get_user(user_id: int) -> dict:\n    try:\n        url = \"https://jsonplaceholder.typicode.com/users/{userId}\"\n        response = requests.get(url.format(userId=user_id))\n        if response.status_code == 200:\n            return response.json()\n        else:\n            print(f\"Id: {user_id} No encontrado\")\n            print(\"status_code: \", response.status_code)\n            return {}\n\n    except requests.ConnectionError as error:\n        #print(error)\n        print(\"error_de conexión\")\n        return {}\n\ndef print_user(user_data: dict):\n    if user_data:\n        print(textwrap.dedent(f\"\"\"\\\n        Usuario con id: '{user_data['id']}':\n        Nombre:  {user_data['name']}\n        Usuario:\" {user_data['username']}\n        Email:, {user_data['email']}\n        Teléfono: {user_data['phone']}\n        \\\n        \"\"\"))\n\nprint(\"\\nEJERCICIO #1:\\n\")\nu1 = get_user(1)\nprint_user(u1)\n\nu2 = get_user(2)\nprint_user(u2)\n\nu3 = get_user(777) # xD-error\nprint_user(u3)\n \n\"\"\"\n* EJERCICIO #2:\n* Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n* terminal al que le puedas solicitar información de un Pokémon concreto\n* utilizando su nombre o número.\n* - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n* - Muestra el nombre de su cadena de evoluciones\n* - Muestra los juegos en los que aparece\n* - Controla posibles errores\n\"\"\"\n\nclass GetPokemon:\n    def __init__(self, id: str | int):\n        base_url = \"https://pokeapi.co/api/v2/pokemon/{id_or_name}\"\n        url = base_url.format(id_or_name = id)\n        response = requests.get(url)\n        self._pokemon: dict = response.json()\n        print(f\"\\nPokémon '{id}' ha sido cargado.\")\n       \n    def info(self):\n        print(textwrap.dedent(f\"\"\"\\\n        Información Básica\n        * Id:      {self._pokemon[\"id\"]}\n        * Nombre:  {self._pokemon[\"name\"]}\n        * Peso:    {self._pokemon[\"weight\"]} kg\n        * Altura:  {self._pokemon[\"height\"]} m\n        * Tipo(s):\\\n        \"\"\"))\n        for t in self._pokemon.get(\"types\", []):\n            type_name = t.get(\"type\", {}).get(\"name\", \"\")\n            print(f\"{' ' * 9}- {type_name}\")\n    \n    def evolution_chain(self):\n        species_url = self._pokemon['species']['url']\n        species_data = requests.get(species_url).json()\n        evolution_chain_url = species_data['evolution_chain']['url']\n\n        evolution_chain_data = requests.get(evolution_chain_url).json()\n        current_evolution = evolution_chain_data['chain']\n\n        if \"species\" in current_evolution:\n            print(\"\\nCadena de evoluciones:\")\n            print(\"-\", current_evolution[\"species\"][\"name\"])\n            while current_evolution.get(\"evolves_to\"):\n                current_evolution = current_evolution[\"evolves_to\"][0]\n                print(\"- \", current_evolution[\"species\"][\"name\"])\n        else:\n            print(\"Este Pokémon no tiene cadena de evolución.\")\n\n    def show__games(self):\n        print(\"\\nJuegos en los que aparece:\")\n        if self._pokemon['game_indices']:\n            for game_info in self._pokemon['game_indices']:\n                print(\"-\", game_info['version']['name'])\n        else:\n            print(\"No aparece en ninguno.\")\n\n    @staticmethod\n    def handle_exceptions(e: Exception):\n        if isinstance(e, requests.exceptions.ConnectionError):\n            print(\"Error de conexión:\", e)\n        elif isinstance(e, requests.exceptions.Timeout):\n            print(\"Tiempo de espera agotado:\", e)\n        elif isinstance(e, requests.exceptions.RequestException):\n            print(\"Error durante la solicitud:\", e)\n        else:\n            print(\"Error inesperado:\", e)\n\nprint(\"\\nEJERCICIO #2:\\n\")\n\ntry:\n    p1 = GetPokemon(1)\n    p1.info()\n    p1.evolution_chain()\n    p1.show__games()\n\n    p2 = GetPokemon(\"ivysaur\")\n    p2.info()\n    p2.evolution_chain()\n    p2.show__games()\n\nexcept Exception as e:\n    GetPokemon.handle_exceptions(e)\n\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/mhayhem.py",
    "content": "# @Author Mhayhem (Daniel Grande)\n# @Github https://github.com/mhayhem\n\nimport requests\nimport json\n\n# EJERCICIO:\n# Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n# una petición a la web que tú quieras, verifica que dicha petición\n# fue exitosa y muestra por consola el contenido de la web.\n\nr = requests.get(\"https://www.python.org/\")\nsucces = r.status_code # 200 la peticion fue exitosa\n\ntext = r.text # contenido dela web\n\n\n# DIFICULTAD EXTRA (opcional):\n# Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n# terminal al que le puedas solicitar información de un Pokémon concreto\n# utilizando su nombre o número.\n# - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n# - Muestra el nombre de su cadena de evoluciones\n# - Muestra los juegos en los que aparece\n# - Controla posibles errores\n\ndef get_pokemon_info():\n    \n    while True:\n        option = input(\"Buscar por nombre (n) o id (i) salir (s): \").lower()\n        match option:\n            case \"n\":\n                param = input(\"Nombre del pokemón: \").capitalize()\n            case \"i\":\n                param = input(\"Id del pokemón: \")\n            case \"s\":\n                print(\"Saliendo del programa.\")\n                break\n            case _:\n                print(\"Opción no válida, pruebe de nuevo.\")\n                continue\n        print(\"Procesando.\\n\")\n        url = f\"https://pokeapi.co/api/v2/pokemon/{param}\"\n        \n        try:\n            response = requests.get(url, timeout=8)\n            response.raise_for_status()\n            if response.status_code == 200:\n                data = response.json()\n                print(\"Pokemón encontrado.\\n\")\n                extract_info(data)\n            \n            elif response.status_code == 404:\n                print(\"Pokemón no encontrado, intentelo de nuevo.\\n\")\n                continue\n            else:\n                print(f\"Error en la petición HTTP: {response.status_code}\\n\")\n                continue\n            \n        except requests.exceptions.Timeout:\n            print(\"Excedido el tiempo de espera, pruebe de nuevo.\\n\")\n            continue\n        except requests.exceptions.RequestException as error:\n            print(f\"Error en la petición HTTP: {error}\\n\")\n            continue\n            \ndef print_info_pokemon(name, pokemon_id, height, weight, types, games, evolution_chain):\n    while True:\n        selection = input(\"¿Qué información quiere mostrar?\\n\"\n                        \"1. Informacion basica\\n\"\n                        \"2. Cadena de evoluciones\\n\"\n                        \"3. Juegos en los que aparece\\n\"\n                        \"4. Información completa\\n\"\n                        \"5. Salir\\n\")\n        print(\"\\n\")\n        match selection:\n            case \"1\":\n                print(f\"Nombre: {name.capitalize()}, ID: {pokemon_id}, Altura: {height}, Peso: {weight}, Tipos: {\", \".join(types)}\")\n            case \"2\":\n                print(f\"Cadena de evoluciones: {' -> '.join(evolution_chain) if evolution_chain else \"Sin evoluciones.\"}\")\n            case \"3\":\n                print(f\"Juegos en los que aparece: {' - '.join(games)}\")\n            case \"4\":\n                print(\n                    f\"Nombre: {name.capitalize()}, ID: {pokemon_id}, Altura: {height}, Peso: {weight}, Tipos: {\", \".join(types)}\\n\"\n                    f\"Cadena de evoluciones: {' -> '.join(evolution_chain) if evolution_chain else \"Sin evoluciones.\"}\\n\"\n                    f\"Juegos en los que aparece: {' - '.join(games)}\"\n                )\n            case \"5\":\n                return \"Cerrando el programa.\"\n            case _:\n                print(\"Opción invalida, pruebe de nuevo.\")\n        print(\"\\n\")\n                 \n        \n        \ndef extract_info(data):\n    name = data[\"name\"]\n    pokemon_id = data[\"id\"]\n    height = data[\"height\"]\n    weight = data[\"weight\"]\n    types = [t[\"type\"][\"name\"] for t in data[\"types\"]]\n    games = [g[\"version\"][\"name\"] for g in data[\"game_indices\"]]\n    species_url = data[\"species\"][\"url\"]\n    species_data = requests.get(species_url).json()\n    evolution_chain = species_data[\"evolution_chain\"][\"url\"]\n    evolution_chain_data = requests.get(evolution_chain).json()\n    evolution_chain = get_evolution_chain(evolution_chain_data[\"chain\"])\n    \n    return print_info_pokemon(name, pokemon_id, height, weight, types, games, evolution_chain)\n\ndef get_evolution_chain(chain):\n    evolutions = [chain[\"species\"][\"name\"].capitalize()]\n      \n    for evo in chain[\"evolves_to\"]:\n        evolutions.extend(get_evolution_chain(evo))\n    \n    return evolutions\n            \n\nget_pokemon_info()"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/mouredev.py",
    "content": "import requests\n\n\"\"\"\nEjercicio\n\"\"\"\n\nresponse = requests.get(\"https://google.com\")\nif response.status_code == 200:\n    print(response.text)\nelse:\n    print(f\"Error con código {response.status_code} al realizar la petición.\")\n\n\"\"\"\nExtra\n\"\"\"\n\npokemon = input(\"Introduce un nombre o número del Pokémon a buscar: \").lower()\n\nresponse = requests.get(f\"https://pokeapi.co/api/v2/pokemon/{pokemon}/\")\nif response.status_code == 200:\n    data = response.json()\n    print(\"Nombre: \", data[\"name\"])\n    print(\"ID: \", data[\"id\"])\n    print(\"Peso: \", data[\"weight\"])\n    print(\"Altura: \", data[\"height\"])\n    print(\"Tipo(s): \")\n    for type in data[\"types\"]:\n        print(type[\"type\"][\"name\"])\n    print(\"Juegos:\")\n    for game in data[\"game_indices\"]:\n        print(game[\"version\"][\"name\"])\n\n    response = requests.get(\n        f\"https://pokeapi.co/api/v2/pokemon-species/{pokemon}/\")\n\n    if response.status_code == 200:\n        url = response.json()[\"evolution_chain\"][\"url\"]\n\n        response = requests.get(url)\n\n        if response.status_code == 200:\n            data = response.json()\n\n            print(\"Cadena de evolución:\")\n\n            def get_evolves(data):\n                print(data[\"species\"][\"name\"])\n                if \"evolves_to\" in data:\n                    for evolve in data[\"evolves_to\"]:\n                        get_evolves(evolve)\n\n            get_evolves(data[\"chain\"])\n\n        else:\n            print(f\"Error {response.status_code} obteniendo las evoluciones.\")\n    else:\n        print(f\"Error {response.status_code} obteniendo las evoluciones.\")\nelse:\n    print(f\"Error {response.status_code}: Pokémon no encontrado\")\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/mrodara.py",
    "content": "### PETICIONES HTTP EN PYTHON\n\n# Para realizar peticiones http en python requiere la importación del módulo requests\n# Instalar previamente si no la tenemos\n# pip install requests\n\nimport requests\n\n# Realizamos una petición get:\n#url = \"https://www.marca.com\"\n#\n##Almacenamos la respuesta\n#response = requests.get(url=url)\n#\n## Si obtenemos un código de estado 200 la comunicación es correcta\n#if response.status_code == 200:\n#    print(f\"Encabezados de la respuesta\")\n#    print(response.headers) # Imprimimos los encabezados de la respuesta\n#    \n#    print(f\"La respuesta a la petición ha sido exitosa\")\n#    print(response.text) # Imprimimos el contenido en formato texto\n#else:\n#    print(f\"La respuesta a la petición ha sido fallida\")\n#    print(response.status_code) # Imprimimos el código de estado de la respuesta\n\n\n### EJERCICIO EXTRA\n\n# Acceso a api pokemon\ndef get_pokemon_data(name: str = \"\", id: int = 0):\n    \n    if name:\n        url= f\"https://pokeapi.co/api/v2/pokemon/{name.lower()}\"\n    else:\n        url = f\"https://pokeapi.co/api/v2/pokemon/{id}\"\n    \n    response = requests.get(url=url)\n    \n    if response.status_code == 200:\n        return response.json()\n    else:\n        print(f'Estatus code: {response.status_code}')\n        print({f'error: No se pudo obtener la información del pokemon'})\n        return None\n\ndef get_pokemon_games(name: str = \"\", id: int = 0):\n    \n    if name:\n        url= f\"https://pokeapi.co/api/v2/version/{name.lower()}\"\n    else:\n        url = f\"https://pokeapi.co/api/v2/version/{id}\"\n    \n    response = requests.get(url=url)\n    \n    if response.status_code == 200:\n        return response.json()\n    else:\n        print(f'Estatus code: {response.status_code}')\n        print({f'error: No se pudo obtener la información del pokemon'})\n        return None\n\n\ndef get_pokemon_evolution_chain(name: str = \"\", id: int = 0):\n    \n    if name:\n        url= f\"https://pokeapi.co/api/v2/evolution-chain/{name.lower()}\"\n    else:\n        url = f\"https://pokeapi.co/api/v2/evolution-chain/{id}\"\n    \n    response = requests.get(url=url)\n    \n    if response.status_code == 200:\n        return response.json()\n    else:\n        print(f'Estatus code: {response.status_code}')\n        print({f'error: No se pudo obtener la información del pokemon'})\n        return None\n\nname = \"\"\nid = 0\n\nprint(\"Obtener datos de Pokemon: \")\noption = input(\"Indica el dato para buscar (n: nombre, i: id): \")\nwhile option[0].lower() not in ['n', 'i']:\n    print(\"Error: Debes indicar una de las dos opciones.\")\n    option = input(\"Indica el dato para buscar (n: nombre, i: id)\")\n\nif option[0].lower() == 'n':\n    name = input(\"Indica el nombre del Pokemon: \")\nelse:\n    id = int(input(\"Indica el id del Pokemon: \"))\n\ndata = get_pokemon_data(name=name, id=id)\ngames = get_pokemon_games(name=name, id=id)\nevolution = get_pokemon_evolution_chain(name=name, id=id)\n\nif data:\n    print(f\"Nombre: {data['name']}\")\n    print(f\"Id: {data['id']}\")\n    print(f\"Altura: {data['height']}\" )\n    print(f\"Peso: {data['weight']}\" )\n    print(\"Tipos:\")\n    for type in data['types']:\n        print(f\"{type['type']['name']}\" )\nelse:\n    print(\"No hay información para mostrar...\")\n\nif evolution:\n    print(\"Evolución:\")\n    print(evolution['chain']['species']['name'])\n\nif games:\n    print(\"Versiones:\")\n    for game in games['names']:\n        if game['language']['name'] == 'es':\n            print(f\"{game['name']}\")\nelse:\n    print(\"No hay información para mostrar acerca de las versiones de juegos de este pokemon...\")\n    \n    \n\n### FIN EJERCICIO EXTRA\n\n### FIN PETICIONES HTTP EN PYTHON\n\n\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/neslarra.py",
    "content": "\"\"\"\n EJERCICIO:\n Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n una petición a la web que tú quieras, verifica que dicha petición\n fue exitosa y muestra por consola el contenido de la web.\n\n DIFICULTAD EXTRA (opcional):\n Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n terminal al que le puedas solicitar información de un Pokémon concreto\n utilizando su nombre o número.\n - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n - Muestra el nombre de su cadena de evoluciones\n - Muestra los juegos en los que aparece\n - Controla posibles errores\n\"\"\"\nimport requests\n\n\nprint(f\"##  Explicación  {'#' * 30}\\n\")\nprint(r\"\"\"\nEl módulo \"requests\" permite hacer envío y recepción de solicitudes HTML a través de métodos GET, POST, PUT y DELETE.\nPara el caso, vamos a usat \"get\" para consumir una API que nos entregará una cantidad \"c\" de palabras en español (útil,\npor ejemplo, para hacer una partida de \"ahoracado\" -o adivina la palabra-).\n\nEs importante conocer qué estaría devolviendo la API para poder explotarla correctamente (viendo la doc específica o\nusando herramientas como \"postman\" o, si no, yendo a la \"url\" y ver qué trae).\n\nimport requests\n\nresponse = requests.get(url=\"https://clientes.api.greenborn.com.ar/public-random-word\", params={\"c\": 10}, timeout=5)\nstatus = response.status_code\nif status == 200:\n    palabras = response.json()\n    print(f\"Palabras para usar: {palabras}\")\nelse:\n    print(f\"Error HTTP: {status}\")\n\"\"\")\nresponse = requests.get(url=\"https://clientes.api.greenborn.com.ar/public-random-word\", params={\"c\": 10}, timeout=5)\nstatus = response.status_code\nif status == 200:\n    palabras = response.json()\n    print(f\"Palabras para usar: {palabras}\", end=\"\\n\\n\")\nelse:\n    print(f\"Error HTTP: {status}\", end=\"\\n\\n\")\n\nprint(f\"##  Dificultad extra  {'#' * 30}\")\n\nURL_BASE = \"https://pokeapi.co/api/v2/\"\n\n\ndef query_api(url: str, params=None) -> dict:\n    data = dict()\n    try:\n        req = requests.get(url, params, timeout=2)\n        if req.status_code == 200:\n            data = req.json()\n        else:\n            print(f\"{url} devolvió RC={req.status_code}\")\n    except requests.exceptions.Timeout:\n        print(f\"{url} NO respondió a tiempo. Intente más tarde.\")\n    return data\n\n\ndef get_pokemon_id(name: str, count: int) -> str:\n    def get_id(url: str) -> str:\n        fields = url[:-1].split(\"/\")\n        return fields.pop()\n\n    data = query_api(URL_BASE + \"pokemon/\", {\"offset\": 0, \"limit\": str(count)})\n\n    for pokemones in data.items():\n        if pokemones[0] == \"results\":\n            for p in pokemones[1]:\n                if p['name'].lower() == name.lower():\n                    return get_id(p['url'])\n    return \"\"\n\n\ndef get_pokemon_data(pok_id: str) -> tuple:\n    def pokemon_evol_chain(pok_id: str) -> list:\n        evolves_chain = []\n        data = query_api(URL_BASE + \"pokemon-species/\" + pok_id + \"/\")\n        try:\n            evolves_to_url = data[\"evolution_chain\"][\"url\"]\n            evol_to_data = query_api(evolves_to_url)\n            evolves_chain.append(evol_to_data[\"chain\"][\"species\"][\"name\"])\n            evolves_chain.append(evol_to_data[\"chain\"][\"evolves_to\"][0][\"species\"][\"name\"])\n            evolves_chain.append(evol_to_data[\"chain\"][\"evolves_to\"][0][\"evolves_to\"][0][\"species\"][\"name\"])\n        except Exception:\n            pass\n        finally:\n            return evolves_chain\n\n    games = []\n    data = query_api(URL_BASE + \"pokemon/\" + pok_id + \"/\")\n    type_ = data[\"types\"][0][\"type\"][\"name\"]\n    height = data[\"height\"]\n    weight = data[\"weight\"]\n    for game in data[\"game_indices\"]:\n        games.append(game[\"version\"][\"name\"])\n    form_url = data[\"forms\"][0][\"url\"]\n    form_data = query_api(form_url)\n    image_url = form_data[\"sprites\"][\"front_default\"]\n    evolves_chain = pokemon_evol_chain(pok_id)\n    return type_, height, weight, games, image_url, evolves_chain\n\n\ndef show_profile(name, id_, data):\n    print(f\"\"\"\n    Pokemon name: {name}  (id: {id_})\n    Type: {data[0]}\n    Height: {data[1]}\n    Weight: {data[2]}\n    Games:\n\"\"\", end=\"\")\n    for g in data[3]:\n        print(f\"\\t\\t{g}\")\n    print(f\"\\tEvolution chain:\")\n    for ec in data[5]:\n        print(f\"\\t\\t{ec}\")\n    print(f\"\\tImage: {data[4]}\")\n\n\ndef main():\n    pokemon = \"\"\n    pokemon_count = 0\n    data = query_api(URL_BASE + \"pokemon/\", {\"offset\": 0, \"limit\": 1})\n    if data:\n        pokemon = \"_\"\n        pokemon_count = data[\"count\"]\n    while pokemon:\n        pokemon = input(\"\\nEnter pokemon name (empty to exit): \")\n        pokemon_id = get_pokemon_id(pokemon, pokemon_count)\n        if pokemon_id:\n            pokemon_data = get_pokemon_data(pokemon_id)\n            show_profile(pokemon, pokemon_id, pokemon_data)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/nlarrea.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n * una petición a la web que tú quieras, verifica que dicha petición\n * fue exitosa y muestra por consola el contenido de la web.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n * terminal al que le puedas solicitar información de un Pokémon concreto\n * utilizando su nombre o número.\n * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n * - Muestra el nombre de su cadena de evoluciones\n * - Muestra los juegos en los que aparece\n * - Controla posibles errores\n\"\"\"\n\nimport requests\n\n\ndef fetch_data():\n    response = requests.get(\"https://jsonplaceholder.typicode.com/posts/1\")\n\n    if response.status_code == 200:\n        print(response.text)\n    else:\n        print(f\"{response.status_code} Error\")\n\n\nfetch_data()\n\"\"\" prints:\n{\n  userId: 1,\n  id: 1,\n  title: 'sunt aut facere repellat provident occaecati excepturi optio reprehenderit',\n  body: 'quia et suscipit\\n' +\n    'suscipit recusandae consequuntur expedita et cum\\n' +\n    'reprehenderit molestiae ut ut quas totam\\n' +\n    'nostrum rerum est autem sunt rem eveniet architecto'\n}\n\"\"\"\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n * terminal al que le puedas solicitar información de un Pokémon concreto\n * utilizando su nombre o número.\n * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n * - Muestra el nombre de su cadena de evoluciones\n * - Muestra los juegos en los que aparece\n * - Controla posibles errores\n\"\"\"\n\n\ndef get_pokemon(pokemon):\n    try:\n        URL = \"https://pokeapi.co/api/v2/pokemon/\"\n        response = requests.get(f\"{URL}{pokemon}\")\n\n        if response.status_code != 200:\n            raise RuntimeError(\"Data not found.\")\n\n        data = response.json()\n        return data\n    except Exception as err:\n        print(err)\n\n\ndef ask_pokemon():\n    pokemon = input(\"Enter a Pokémon name or Id:\\n> \")\n    data = get_pokemon(pokemon)\n    if not data:\n        return\n\n    print(\"\\nName:\", data[\"name\"].capitalize())\n    print(\"Pokémon Id:\", data[\"id\"])\n    print(\"Pokémon weight:\", data[\"weight\"])\n    print(\"Pokémon height:\", data[\"height\"])\n    print(\"Pokémon type(s):\")\n    for type in data[\"types\"]:\n        print(f\"  {type['slot']}.\", type[\"type\"][\"name\"])\n\n\nask_pokemon()\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/oriaj3.py",
    "content": "\"\"\"\n20 - PETICIONES HTTP\n\nAutor de la solución: Oriaj3\n\nTeoría:\nLas peticiones HTTP son solicitudes que se envían a un servidor web para obtener\no enviar información. En Python, el módulo requests proporciona una forma sencilla\nde realizar peticiones HTTP a través de una API fácil de usar.\n\nExisten distintos tipos de peticiones HTTP:\n- GET: se utiliza para obtener información del servidor.\n- POST: se utiliza para enviar información al servidor.\n- PUT: se utiliza para actualizar información en el servidor.   \n- DELETE: se utiliza para eliminar información del servidor.\n- PATCH: se utiliza para modificar información en el servidor.\n- HEAD: se utiliza para obtener la cabecera de una respuesta.\n- OPTIONS: se utiliza para obtener información sobre los métodos HTTP permitidos.\n- TRACE: se utiliza para realizar un seguimiento de la ruta de una petición.\n- CONNECT: se utiliza para convertir la conexión en un túnel TCP/IP.\n\n\"\"\"\n\n\"\"\"\n/*\n * EJERCICIO:\n * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n * una petición a la web que tú quieras, verifica que dicha petición\n * fue exitosa y muestra por consola el contenido de la web.\n\"\"\"\nimport requests \n\n#path url rickyandmorty\nurl = \"https://rickandmortyapi.com/api/character\"\n\nresponse = requests.get(url)\nif response.status_code == 200:\n    #Muestra solo los nonmbres de los personajes\n    data = response.json()\n    for character in data[\"results\"]:\n        print(character[\"name\"])\nelif response.status_code == 404:\n    print(\"Error 404: Página no encontrada\")\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n * terminal al que le puedas solicitar información de un Pokémon concreto\n * utilizando su nombre o número.\n * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n * - Muestra el nombre de su cadena de evoluciones\n * - Muestra los juegos en los que aparece\n * - Controla posibles errores\n */\n\"\"\"\nprint(\"\\n\\n*****EXTRA POKEMON*****\")\ndef pokedex(data):\n    #Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n    print(\"Nombre: \", data[\"name\"])\n    print(\"ID: \", data[\"id\"])\n    print(\"Peso: \", data[\"weight\"])\n    print(\"Altura: \", data[\"height\"])\n    print(\"Tipo(s): \")\n    for type in data[\"types\"]:\n        print(type[\"type\"][\"name\"])\n    print(\"Juegos:\")\n    for game in data[\"game_indices\"]:\n        print(game[\"version\"][\"name\"])\n    \n    \ndef evoluciones(data):\n    #Muestra el nombre de su cadena de evoluciones\n    #Para esto se hace otra petición a la API de pokemon-species\n    #para obtener la url de la cadena de evolución\n    response = requests.get(f\"https://pokeapi.co/api/v2/pokemon-species/{pokemon}/\")\n    if response.status_code == 200:\n        url = response.json()[\"evolution_chain\"][\"url\"]\n        response = requests.get(url)\n        if response.status_code == 200:\n            data = response.json()\n            print(\"Cadena de evolución:\")\n            def get_evolves(data):\n                print(data[\"species\"][\"name\"])\n                if \"evolves_to\" in data:\n                    for evolve in data[\"evolves_to\"]:\n                        get_evolves(evolve)\n            get_evolves(data[\"chain\"])\n        else:\n            print(f\"Error {response.status_code} obteniendo las evoluciones.\")\n    else:\n        print(f\"Error {response.status_code} obteniendo las evoluciones.\")\n    \npokemon = input(\"Introduce el nombre o el número del pokemon a mostrar: \").lower()\n\nresponse = requests.get(f\"https://pokeapi.co/api/v2/pokemon/{pokemon}\")\n\nif response.status_code == 200:\n    data = response.json()\n    pokedex(data)\n    evoluciones(data)\nelse:\n    print(f\"Error {response.status_code}: Pokémon no encontrado\")\n    \n    \n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/pyramsd.py",
    "content": "import requests\nfrom colorama import Fore\n\nquery = requests.get('https://comandos-de-linux.reflex.run/')\n\nstatusCode = query.status_code\n\nif statusCode == 200:\n    print(Fore.GREEN + \"[+] Petición exitosa\" + Fore.RESET)\n    print(query.content.decode('utf-8'))\nelse:\n    print(Fore.RED + \"[-] Algo salió mal!\" + Fore.RESET)\n\n'''\nEXTRA\n'''\nbaseURL = \"https://pokeapi.co/api/v2/pokemon\"\ndef getDataPokemon(name):\n    url = baseURL + \"/\" + name\n    try:\n        query = requests.get(url)\n        query.raise_for_status()\n        data = query.json()\n\n        print(f\"Name: {data['name']}\")\n        print(f\"ID: {data['id']}\")\n        print(f\"Weight: {data['weight']}\")\n        print(f\"Height: {data['height']}\")\n        print(f\"Types: {''.join([i['type']['name'] for i in data['types']])}\")\n        print(f\"Games: {[game['version']['name'] for game in data['game_indices']]}\")\n\n\n    except requests.exceptions.HTTPError as e:\n        if query.status_code == 404:\n            print(Fore.RED + f\"[-] Error 404: Pokemon '{name}' Not found\" + Fore.RESET)\n\nname = input(\"Nombre de pokemon: \")\ngetDataPokemon(name)\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/qwik-zgheib.py",
    "content": "# -- exercise\nurl: str = \"https://www.dota2.com/hero/legioncommander\"\n\nimport requests\n\n\ndef get_web_content(url: str) -> str:\n    try:\n        response = requests.get(url)\n        response.raise_for_status()\n        return response.text\n    except requests.exceptions.HTTPError as err:\n        return f\"err: {err}\"\n    except requests.exceptions.RequestException as err:\n        return f\"err: {err}\"\n    except Exception as err:\n        return f\"err: {err}\"\n\n\nif __name__ == \"__main__\":\n    print(get_web_content(url))\n\n\n# -- extra challenge\npoke_api: str = \"https://pokeapi.co/api/v2/pokemon/\"\n\n\nclass Pokemon:\n    def __init__(self, name: str):\n        self.name = name\n        self.url = f\"{poke_api}{name}\"\n        self.data = self.get_data()\n\n    def get_data(self):\n        try:\n            response = requests.get(self.url)\n            response.raise_for_status()\n            return response.json()\n        except requests.exceptions.HTTPError as err:\n            return f\"err: {err}\"\n        except requests.exceptions.RequestException as err:\n            return f\"err: {err}\"\n        except Exception as err:\n            return f\"err: {err}\"\n\n    def get_info(self):\n        if isinstance(self.data, dict):\n            name = self.data.get(\"name\")\n            id = self.data.get(\"id\")\n            weight = self.data.get(\"weight\")\n            height = self.data.get(\"height\")\n            types = [t[\"type\"][\"name\"] for t in self.data.get(\"types\")]\n            return f\"Name: {name}\\nID: {id}\\nWeight: {weight}\\nHeight: {height}\\nTypes: {types}\"\n        return self.data\n\n    def get_evolution_chain(self):\n        if isinstance(self.data, dict):\n            species_url = self.data.get(\"species\").get(\"url\")\n            species_data = requests.get(species_url).json()\n            evolution_chain_url = species_data.get(\"evolution_chain\").get(\"url\")\n            evolution_chain_data = requests.get(evolution_chain_url).json()\n            chain = evolution_chain_data.get(\"chain\")\n            evolutions = []\n            while chain:\n                evolutions.append(chain[\"species\"][\"name\"])\n                chain = chain.get(\"evolves_to\")[0] if chain.get(\"evolves_to\") else None\n            return \" -> \".join(evolutions)\n        return self.data\n\n    def get_games(self):\n        if isinstance(self.data, dict):\n            games = [v[\"version\"][\"name\"] for v in self.data.get(\"game_indices\")]\n            return games\n        return self.data\n\n\nif __name__ == \"__main__\":\n    name = input(\"enter a Pokémon name or number: \")\n    pokemon = Pokemon(name)\n    print(pokemon.get_info())\n    print(pokemon.get_evolution_chain())\n    print(pokemon.get_games())\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/rantamhack.py",
    "content": "'''\n* EJERCICIO:\n* Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n* una peticion a la web que tu quieras, verifica que dicha peticion\n* fue exitosa y muestra por consola el contenido de la web.\n'''\nprint(\"\\n\\n=======================================EJERCICIO=======================================\\n\\n\")\n\nimport requests\n\nresponse = requests.get(\"https://www.github.com/mouredev\", timeout=5)\n\n\nweb = response.content.decode('utf8')\n\nprint(web)\n\nprint(\"=======================================\")\nprint(response)\nprint(\"=======================================\")\n\n\n'''\n* DIFICULTAD EXTRA (opcional):\n* Utilizando la PokeAPI (https://pokeapi.co), crea un programa por\n* terminal al que le puedas solicitar informacion de un Pokemon concreto\n* utilizando su nombre o numero.\n* - Muestra el nombre, id, peso, altura y tipo(s) del Pokemon\n* - Muestra el nombre de su cadena de evoluciones\n* - Muestra los juegos en los que aparece\n* - Controla posibles errores\n'''\n\n\nprint(\"\\n\\n=======================================DIFICULTAD EXTRA=======================================\\n\\n\")\n\n\n\npokemon = input(\"Escribe el identificador o el nombre del pokemon que quieras conocer\\n(Si pones el identificador ten en cuenta que hay 1025 pokemon): \")\n\n \ndef find_pokemon(name_or_id):\n        \n    response = requests.get(f\"https://pokeapi.co/api/v2/pokemon/{name_or_id}\", timeout=5)\n    response.raise_for_status()\n    pokemon_data = response.json()\n        \n    print(\"=======================================\")\n    print(response)\n    print(\"=======================================\")\n        \n                    \n    name = pokemon_data[\"name\"].capitalize()\n    id = pokemon_data[\"id\"]\n    weight = pokemon_data[\"weight\"]\n    height = pokemon_data[\"height\"]\n    pokemon_type = [type[\"type\"][\"name\"] for type in pokemon_data[\"types\"]]\n\n        \n    pokemon_games = [game[\"version\"][\"name\"] for game in pokemon_data[\"game_indices\"]]     \n\n    \n    print(f\"El pokemon elegido es {name}\")\n    print(f\"El id del pokemon {name} es {id}\")\n    print(f\"El peso del pokemon {name} es de {weight}\")\n    print(f\"La altura del pokemon {name} es de {height}\")\n    print(f\"{name} es un pokemon de tipo {pokemon_type}\")\n    print(f\"{name} participa en los juegos: {pokemon_games}\")\n        \n        \n        \n\n\n    \nfind_pokemon(pokemon)\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/raulG91.py",
    "content": "import requests\n\nurl = \"https://httpbin.org/get\"\n\nr = requests.get(url)\n\n\nif r.status_code == 200:\n    print(\"Get executed\")\n    print(r.json())\nelif r.status_code == 401:\n    print(\"Unauthorized\")\nelif r.status_code == 403:\n    print(\"Forbidden\")    \nelse:\n    print(f'Error executing get request with status code {r.status_code}')    \n\n#Extra\n\nuri = \"https://pokeapi.co/api/v2/\"\n\nwhile(True):\n    print(\"Enter 1 to search pokemon by name or ID\")\n    print(\"Enter 2 to exit\")\n    value = int(input())\n\n    if value == 1:\n        pokemon = input(\"Enter  name or id for pokemon \")\n        pokemon = pokemon.lower()\n        url_final = uri +\"pokemon/\"+pokemon\n        \n        request = requests.get(url_final)\n\n        if request.status_code == 200 or request.status_code == 201:\n            \n            #Get JSON data\n            data = request.json()\n            #Extract data from the response\n            name = data[\"name\"]\n            id = data[\"id\"]\n            weight = data[\"weight\"]\n            height = data[\"height\"]\n            #Get type\n            pokemon_type = []\n            for type in data[\"types\"]:\n                pokemon_type.append(type[\"type\"][\"name\"])\n            #Get game list\n            game_list = []\n            for game in data[\"game_indices\"]:\n                game_list.append(game[\"version\"][\"name\"])\n\n            #Get evolution list\n\n            #First get speies URL\n            species_url = data[\"species\"][\"url\"]\n            request_evo = requests.get(species_url)\n            if request_evo.status_code == 200 or request_evo.status_code == 201:\n                data_evo = request_evo.json()\n                #if Success get URL for evolution chain\n                evo_chain = data_evo[\"evolution_chain\"][\"url\"]\n                #Now we have URL to get evolutions\n                request_evo = requests.get(evo_chain)\n                if request_evo.status_code == 200 or request_evo.status_code == 201:\n                    evo_details = request_evo.json()\n                    evolution_chain = []\n                    current_evo = evo_details[\"chain\"]\n                    #Iterate over evolutions\n                    while current_evo:\n                        evolution_chain.append(current_evo[\"species\"][\"name\"])\n                        if current_evo['evolves_to']:\n                            #If there are more evolutions, check it\n                            current_evo = current_evo['evolves_to'][0]\n                        else:\n                            current_evo = None   \n                else:\n                    print(f'Error executing {evo_chain} with status code {request_evo.status_code}')    \n            else:\n                print(f'Error executing {species_url} with status code {request_evo.status_code}')\n            \n            print(f'Name: {name}, id: {id}, Weight: {weight}, Height: {height}, Pokemon type: {pokemon_type}, Evoloves: {evolution_chain},Game list: {game_list}')\n        else:\n            print(f'Error executing API status code: {request.status_code}')    \n    elif value == 2:\n        break\n\n    "
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/raynerpv2022.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n#  * una petición a la web que tú quieras, verifica que dicha petición\n#  * fue exitosa y muestra por consola el contenido de la web.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n#  * terminal al que le puedas solicitar información de un Pokémon concreto\n#  * utilizando su nombre o número.\n#  * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n#  * - Muestra el nombre de su cadena de evoluciones\n#  * - Muestra los juegos en los que aparece\n#  * - Controla posibles errores\n#  */\n\nimport requests\n\n\ndef execrcice(url: str):\n    try:\n        response = requests.get(url)\n        response.raise_for_status()\n    except requests.exceptions.RequestException as e:\n         \n        print(\"Error Conexion Lost Code :\", e)\n        \n    else :\n        print(\"Conexion Succesfully, Code :\", response.status_code)\n        print(\"Data\")\n        print()    \n        print(response.text)\n    \ndef extra():\n    value = input(\"Numero o Nombredel  pOkEmOn:\")\n    url = f\"https://pokeapi.co/api/v2/pokemon/{value}\"\n   \n    poke = get_Poke_url(url)\n    if not poke :\n         return\n\n    print(f' Nombre {poke[\"name\"]}' )\n    print(f' ID {poke[\"id\"]}' )\n    print(f' Weight {poke[\"weight\"]}' )\n    print(f' Height {poke[\"height\"]}' )\n    print(\"Tipos \")\n    for  t in poke[\"types\"] :\n        print(f\"\\tNOmbre: {t['type']['name']} URL: {t['type']['url']}\")\n        print()\n        \n    print(\"GAmes  \")\n    for g in poke[\"game_indices\"]:\n        print(f\" \\t {g['version']['name']} *** url: {g['version']['url']}\")\n\n\n    specie_url = f\"https://pokeapi.co/api/v2/pokemon-species/{value}\"\n    specie_json = get_Poke_url(specie_url)\n    if not specie_json:\n         return\n    \n    evolution_chain_json = get_Poke_url(specie_json[\"evolution_chain\"][\"url\"])\n    if not evolution_chain_json:\n         return\n     \n    print(\"EVOLUTION CHAIN\")\n    get_evolution(evolution_chain_json[\"chain\"])\n\ndef get_evolution(evolution):\n         \n        if \"evolves_to\" in evolution:\n                        for i in evolution[\"evolves_to\"]:            \n                            \n                            get_evolution(i)\n                        print(f'\\t  {evolution[\"species\"][\"name\"]}')\n\ndef get_Poke_url(url):\n     response = requests.get(url)\n     status_code = response.status_code\n     if  status_code >= 300 or status_code < 200:\n        print(f\"Pokemon No encontrado, Error : {status_code}\")\n        return False\n     return response.json()\n     \n\n\n# execrcice(\"https://mouredev.pro/\")\nextra()\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/restevean.py",
    "content": "\"\"\"\nExercise\n\"\"\"\nimport requests\n\n\ndef request_url(url):\n    # Realizar la petición GET\n    response = requests.get(url)\n\n    # Verificar si la petición fue exitosa\n    if response.status_code == 200:\n        return \"Petición exitosa.\"\n    else:\n        return f\"Error en la petición: {response.status_code},\"\n\n\n\"\"\"\nExtra\n\"\"\"\n\n\ndef get_pokemon_data(pokemon_identifier):\n    base_url = \"https://pokeapi.co/api/v2/pokemon/\"\n    url = f\"{base_url}{pokemon_identifier.lower()}\"\n\n    response = requests.get(url)\n\n    if response.status_code != 200:\n        print(\n            f\"Error: No se pudo obtener información para {pokemon_identifier}. Código de estado: {response.status_code}\")\n        return\n\n    data = response.json()\n    print(f\"Name: {data['name'].capitalize()}\")\n    print(f\"ID: {data['id']}\")\n    print(f\"Weight: {data['weight']/10} kg\")\n    print(f\"Height: {data['height']*10} cm\")\n\n    types = [type_info['type']['name'] for type_info in data['types']]\n    print(f\"Tipe(s): {', '.join(types).capitalize()}\")\n\n    # Obtener cadena de evoluciones\n    species_url = data['species']['url']\n    species_response = requests.get(species_url)\n    species_data = species_response.json()\n    evolution_chain_url = species_data['evolution_chain']['url']\n\n    evolution_chain_response = requests.get(evolution_chain_url)\n    evolution_chain_data = evolution_chain_response.json()\n\n    evolution_chain = []\n    current_evolution = evolution_chain_data['chain']\n\n    while current_evolution:\n        evolution_chain.append(current_evolution['species']['name'].capitalize())\n        if current_evolution['evolves_to']:\n            current_evolution = current_evolution['evolves_to'][0]\n        else:\n            current_evolution = None\n\n    print(f\"Evolutions chain: {', '.join(evolution_chain)}\")\n\n    # Obtener juegos en los que aparece\n    games = [game_info['version']['name'] for game_info in data['game_indices']]\n    print(f\"Games where it appears: {', '.join(games).capitalize()}\")\n\n\nif __name__ == '__main__':\n    print(\"Exercise\")\n    url = \"https://retosdeprogramacion.com/roadmap/\"\n    print(\"GET to\", url, request_url(url))\n    url = \"https://retosdeprogramacion.com/roadmap/1\"\n    print(\"GET to\",url, request_url(url))\n\n    print(\"Extra\")\n    pokemon_name = input(\"Type pokemon's name or number: \")\n    get_pokemon_data(pokemon_name)\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/rigo93acosta.py",
    "content": "'''\n * EJERCICIO:\n * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n * una petición a la web que tú quieras, verifica que dicha petición\n * fue exitosa y muestra por consola el contenido de la web.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n * terminal al que le puedas solicitar información de un Pokémon concreto\n * utilizando su nombre o número.\n * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n * - Muestra el nombre de su cadena de evoluciones\n * - Muestra los juegos en los que aparece\n * - Controla posibles errores\n */\n'''\n\n'''\nEjercicio\n'''\n\nimport requests\n\n# # Peticion\n# response = requests.get(\"https://moure.dev/asdasdas\")\n# # Check\n# if response.status_code == 200: ## Estado\n#     print(response.text) ## Contenido\n# else:\n#     print(f\"Error con código {response.status_code} al realizar la petición.\")\n\n'''\nExtra\n'''\n\ninput_pokemon = input(\"Introduce el nombre o número del Pokémon: \").lower()\nresponse = requests.get(f\"https://pokeapi.co/api/v2/pokemon/{input_pokemon}\")\nif response.status_code == 200:\n    # print(response.text)\n    data = response.json()\n    print(f\"Nombre: {data['name'].capitalize()}\") ## Nombre\n    print(f\"ID: {data['id']}\") ## ID\n    print(f\"Peso: {data['weight']} [hg]\") ## Peso\n    print(f\"Altura: {data['height']} [dm]\") ## Altura\n    tipos = []\n    for tipo in data['types']:\n        tipos.append(tipo['type']['name'])\n    print(f\"Tipo(s): {', '.join(tipos)}\") ## Tipo(s)\n\n    ## Cadenas de evolución\n    response = requests.get(\n        f\"https://pokeapi.co/api/v2/pokemon-species/{input_pokemon}\"\n    )\n    if response.status_code == 200:\n        url = response.json()[\"evolution_chain\"][\"url\"]\n        response = requests.get(url)\n        if response.status_code == 200:\n            data = response.json()\n            \n            evolutions = []\n            def get_evolves(data):\n                evolutions.append(data[\"species\"][\"name\"].capitalize())\n                # print(data[\"species\"][\"name\"])\n                if \"evolves_to\" in data:\n                    for evolve in data[\"evolves_to\"]:\n                        get_evolves(evolve)\n        \n            get_evolves(data[\"chain\"])\n            print(f\"Cadena de evolución: {' -> '.join(evolutions)}\")\n        else:\n            print(f\"Error {response.status_code}: evoluciones no encontrada.\")    \n    else:\n        print(f\"Error {response.status_code}: evoluciones no encontrada.\")\n    \n    ## Juegos\n    response = requests.get(\n        f\"https://pokeapi.co/api/v2/pokemon/{input_pokemon}\"\n    )\n    if response.status_code == 200:\n        data = response.json()\n        games = []\n        for game in data[\"game_indices\"]:\n            games.append(game[\"version\"][\"name\"].capitalize())\n        print(f\"Juegos: {', '.join(games)}\")\n    else:\n        print(f\"Error {response.status_code}: juegos no encontrados.\")\nelse:\n    print(f\"Error {response.status_code}: Pokémon no encontrado.\")\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/santyjl.py",
    "content": "# #20 PETICIONES HTTP\n\"\"\"\n/*\n * EJERCICIO:\n * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n * una petición a la web que tú quieras, verifica que dicha petición\n * fue exitosa y muestra por consola el contenido de la web.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n * terminal al que le puedas solicitar información de un Pokémon concreto\n * utilizando su nombre o número.\n * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n * - Muestra el nombre de su cadena de evoluciones\n * - Muestra los juegos en los que aparece\n * - Controla posibles errores\n */\n\"\"\"\n\nimport requests\n\n# Realiza una solicitud HTTP GET a la página de inicio de Twitter\nr = requests.get(\"https://twitter.com/home\")  # Regresa el estado de la web\n\n# Verifica si la solicitud fue exitosa\nif r.status_code == 200:  # 200 indica que la solicitud fue exitosa\n    print(\"exitosa: \\n\")\n    print(r.text)  # Muestra el HTML de la página web\nelse:\n    print(\"fallido\")  # Indica que la solicitud falló\n\n# Solicita al usuario que introduzca el nombre o número de un Pokémon\npokemon = input(\"introduce el nombre o numero de un pokemon : \").lower()\n\n# Realiza una solicitud HTTP GET a la API de PokeAPI para obtener información del Pokémon\npokemones = requests.get(f\"https://pokeapi.co/api/v2/pokemon/{pokemon}/\")\n\n# Verifica si la solicitud fue exitosa\nif pokemones.status_code == 200:\n    info = pokemones.json()  # Convierte la respuesta JSON en un diccionario de Python\n    print(\"NOMBRE : \", info[\"name\"])  # Imprime el nombre del Pokémon\n    print(\"ID : \", info[\"id\"])  # Imprime el ID del Pokémon\n    print(\"PESO: \", info[\"weight\"])  # Imprime el peso del Pokémon\n    print(\"ALTURA: \", info[\"height\"])  # Imprime la altura del Pokémon\n\n    # Imprime los tipos del Pokémon\n    for tipo in info[\"types\"]:\n        print(\"TIPO(S) : \", tipo[\"type\"][\"name\"])\n\n    print(\"Juegos: \")\n\n    # Imprime los juegos en los que aparece el Pokémon\n    for juego in info[\"game_indices\"]:\n        print(juego[\"version\"][\"name\"], end=\" , \")\n\n    # Realiza una solicitud HTTP GET a la API de PokeAPI para obtener la cadena de evolución del Pokémon\n    evoluciones = requests.get(f\"https://pokeapi.co/api/v2/pokemon-species/{pokemon}/\")\n\n    # Verifica si la solicitud fue exitosa\n    if evoluciones.status_code == 200:\n        url = evoluciones.json()[\"evolution_chain\"][\"url\"]\n\n        evoluciones = requests.get(url)\n\n        # Verifica si la solicitud fue exitosa\n        if evoluciones.status_code == 200:\n            info = evoluciones.json()\n\n            print(\"\\nCadena de evolución:\")\n\n            # Función recursiva para imprimir la cadena de evolución\n            def get_evolves(info):\n                print(info[\"species\"][\"name\"], end=\" , \")\n                if \"evolves_to\" in info:\n                    for evolucion in info[\"evolves_to\"]:\n                        get_evolves(evolucion)\n\n            get_evolves(info[\"chain\"])\n        else:\n            print(f\"no tiene evolucion el pokemon {pokemon}\")\n    else:\n        print(f\"Error : {evoluciones.status_code} , hay problema en las evoluciones\")\nelse:\n    print(f\"Error : no hay un pokemos del nombre {pokemon} o te dio el erro {pokemones.status_code}\")\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/python/ycanas.py",
    "content": "import requests\n\n# ------ Ejercicio\n\nURL: str = r\"http://worldtimeapi.org/api/timezone/America/Bogota\"\n\nstatus = requests.request(\"GET\", URL)\n\nif status.status_code == 200:\n    data = status.json()\n    time = data[\"datetime\"].split('T')[1].split('.')[0]\n    decorator: str = '-' * 72\n    print(f\"{decorator}\\nResponse [{status.status_code}] OK\\nHiciste una petición a 'World Time Api' a las {time}, hora Colombiana.\\n{decorator}\\n\")\n\nelse:\n    print(f\"Error, Response [{status.status_code}]\")\n    \n\n# ------ Extra\n\nPOKEMON_INFO_BASE_URL: str = r\"https://pokeapi.co/api/v2/pokemon/\"\nPOKEMON: str = input(\"* Ingrese el nombre o id del Pokemon: \").lower()\nURL_POKEMON_INFO_API: str = POKEMON_INFO_BASE_URL + POKEMON + '/'\n\nstatus = requests.request(\"GET\", URL_POKEMON_INFO_API)\n\nif status.status_code == 200:\n    pokemon = status.json()\n\n    # info\n    print(f\"\\n{decorator}\")\n    print(\"Información del Pokemon →\\n\")\n\n    print(\"- Nombre:\", pokemon[\"name\"].capitalize())\n    print(\"- Id:\", pokemon[\"id\"])\n    print(\"- Peso:\", pokemon[\"weight\"])\n    print(\"- Altura:\", pokemon[\"height\"])\n    print(\"- Tipo(s):\")\n\n    # pokemon types\n    for type in pokemon[\"types\"]:\n        item = type[\"type\"][\"name\"].capitalize()\n        print(f\"  {item}\")\n\n    # pokemon games\n    print(\"- Juego(s):\")\n\n    for game in pokemon[\"game_indices\"]:\n        item = game[\"version\"][\"name\"].capitalize()\n        print(f\"  {item}\")\n    \n    print(decorator)\n\nelse:\n    print(f\"Error, Response [{status.status_code}]\")\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/ruby/Elmer125.rb",
    "content": "#  * EJERCICIO:\n#  * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n#  * una petición a la web que tú quieras, verifica que dicha petición\n#  * fue exitosa y muestra por consola el contenido de la web.\n# Doc: https://github.com/ruby/net-http\nrequire 'net/http'\nrequire 'json'\n\nNet::HTTP.start('www.google.com') do |http|\n  response = http.get('/')\n  if response.code == '200'\n    puts \"Request successful\"\n    puts response.body\n  else\n    puts \"Request failed\"\n  end\nend\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n#  * terminal al que le puedas solicitar información de un Pokémon concreto\n#  * utilizando su nombre o número.\n#  * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n#  * - Muestra el nombre de su cadena de evoluciones\n#  * - Muestra los juegos en los que aparece\n#  * - Controla posibles errores\n\npokemon_url = 'https://pokeapi.co/api/v2/pokemon/'\n\nputs \"Enter a Pokémon name or id:\"\npokemon = gets.chomp\nputs \"Searching for Pokémon #{pokemon}...\"\nresponse = Net::HTTP.get_response(URI(pokemon_url + pokemon))\nif response.code == '200'\n  pokemon_data = JSON.parse(response.body)\n  puts \"Name: #{pokemon_data['name']}\"\n  puts \"Id: #{pokemon_data['id']}\"\n  puts \"Weight: #{pokemon_data['weight']}\"\n  puts \"Height: #{pokemon_data['height']}\"\n  puts \"Types: #{pokemon_data['types'].map { |type| type['type']['name'] }.join(', ')}\"\n  puts \"Games: #{pokemon_data['game_indices'].map { |game| game['version']['name'] }.join(', ')}\"\n\n  pokemon_species_url = pokemon_data['species']['url']\n  pokemon_species_response = Net::HTTP.get_response(URI(pokemon_species_url))\n\n  if pokemon_species_response.code == '200'\n    pokemon_species_data = JSON.parse(pokemon_species_response.body)\n    evolution_chain_url = pokemon_species_data['evolution_chain']['url']\n    evolution_chain_response = Net::HTTP.get_response(URI(evolution_chain_url))\n\n    if evolution_chain_response.code == '200'\n      evolution_chain_data = JSON.parse(evolution_chain_response.body)\n      puts \"Evolutions: #{evolution_chain_data['chain']['evolves_to'].map { |evolution| evolution['species']['name'] }.join(', ')}\"\n    else\n      puts \"Request failed, couldn't get Pokémon evolution chain\"\n    end\n  else\n    puts \"Request failed, couldn't get Pokémon species\"\n  end\nelse\n  puts \"Request failed, Pokémon not found\"\nend"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/ruby/edalmava.rb",
    "content": "# Ruby tiene un cliente HTTP interno llamado 'net/http' que no logre configurar en Windows\n# En su lugar use la gema httparty que se instala con: gem install httparty\n\nrequire 'httparty'\nresponse = HTTParty.get('https://pokeapi.co/api/v2/pokemon/pikachu')\nif response.code == 200\n    puts \"Respuesta OK: \"\n    puts response.body\nelse \n    print 'Código de respuesta: ' \n    puts response.code\nend\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/rust/kenysdev.rs",
    "content": "/*\n╔═══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado                ║\n║ GitHub: https://github.com/Kenysdev   ║\n║ 2024 -  Rust                          ║\n╚═══════════════════════════════════════╝\n-----------------------------------------\n* PETICIONES HTTP\n-----------------------------------------\nhttps://crates.io/crates/reqwest\n\n[dependencies]\ntokio = { version = \"1.37.0\", features = [\"full\"] }\nserde = { version = \"1.0.197\", features = [\"derive\"] }\nreqwest = { version = \"0.12.4\", features = [\"json\"] }\n*/\n\n/*\n* EJERCICIO:\n* Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n* una petición a la web que tú quieras, verifica que dicha petición\n* fue exitosa y muestra por consola el contenido de la web.\n*/\nuse reqwest;\nuse serde::Deserialize;\n\n#[derive(Deserialize, Debug)]\nstruct User {\n    id: u32,\n    name: String,\n    username: String,\n    email: String,\n    phone: String,\n}\n\nasync fn get_user(user_id: u32) -> Result<Option<User>, reqwest::Error> {\n    let url = format!(\"https://jsonplaceholder.typicode.com/users/{}\", user_id);\n    let response = reqwest::get(&url).await?;\n\n    if response.status().is_success() {\n        let user: User = response.json().await?;\n        Ok(Some(user))\n    } else {\n        println!(\"Id: {} No encontrado\", user_id);\n        println!(\"status_code: {}\", response.status());\n        Ok(None)\n    }\n}\n\nfn print_user(user_data: Option<User>) {\n    if let Some(user) = user_data {\n        println!(\n            \"Usuario con id: '{}':\\n\\\n             Nombre: {}\\n\\\n             Usuario: {}\\n\\\n             Email: {}\\n\\\n             Teléfono: {}\\n\",\n            user.id, user.name, user.username, user.email, user.phone\n        );\n    }\n}\n\n#[tokio::main]\nasync fn main() -> Result<(), reqwest::Error> {\n\n    let u1 = get_user(1).await?;\n    print_user(u1);\n\n    let u2 = get_user(2).await?;\n    print_user(u2);\n\n    let u3 = get_user(777).await?; // xD-error\n    print_user(u3);\n\n    Ok(())\n}\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/sql/Nicojsuarez2.sql",
    "content": "# #20 PETICIONES HTTP\n> #### Dificultad: Difícil | Publicación: 13/05/24 | Corrección: 20/05/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n * una petición a la web que tú quieras, verifica que dicha petición\n * fue exitosa y muestra por consola el contenido de la web.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n * terminal al que le puedas solicitar información de un Pokémon concreto\n * utilizando su nombre o número.\n * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n * - Muestra el nombre de su cadena de evoluciones\n * - Muestra los juegos en los que aparece\n * - Controla posibles errores\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/swift/allbertoMD.swift",
    "content": "import Foundation\n\n// ESTE PROGRAMA PARA SU CORRECTRO FUNCIONAMIENTO SIN LOS METODOS sleep() SE TIENE QUE USAR EN UN PLAYGROUND.\n\nvar webUrlString = \"https://www.swift.org\"\nguard let webUrl = URL(string: webUrlString) else {\n    print(\"URL inválida\")\n    exit(1)\n}\n\n// Crear una solicitud URLRequest.\nvar webRequest = URLRequest(url: webUrl)\nwebRequest.httpMethod = \"GET\"\n\n// Crear una sesión URLSession.\nlet session = URLSession.shared\n\n// Crear una tarea de datos\nlet task = session.dataTask(with: webRequest) { (data, response, error) in\n    // Verificar si hay algún error\n    if let error = error {\n        print(\"Error: \\(error).\")\n        return\n    }\n\n    // Verificar si se recibió una respuesta HTTP.\n    guard let httpResponse = response as? HTTPURLResponse else {\n        print(\"Respuesta HTTP inválida.\")\n        return\n    }\n\n    // Verificar si la solicitud fue exitosa (código de estado 2xx).\n    guard (200...299).contains(httpResponse.statusCode) else {\n        print(\"Error en la solicitud. Código de estado: \\(httpResponse.statusCode).\")\n        return\n    }\n\n    // Verificar si se recibieron datos.\n    guard let responseData = data else {\n        print(\"No se recibieron datos.\")\n        return\n    }\n    \n    // Imprime el contenido html de la pagina.\n    if let dataString = String(data: responseData, encoding: .utf8) {\n        print(dataString)\n    } else {\n        print(\"No hay datos que mostrar.\")\n    }\n}\n\n// Empezar la tarea\ntask.resume()\nsleep(1)\n\n\n\n\n// DIFICULTAD EXTRA\nprint(\"\\nDIFICULTAD EXTRA.\\n\")\n\n\n// Pide por consola el nombre del pokemon para añadirlo al endpoint\nprint(\"Introduce el nombre del pokemon que quieras ver la info:\")\nguard let pokemonName = readLine() else {\n    fatalError()\n}\n\n\n// Structuras para la info del pokemon\nstruct Pokemon: Codable {\n    let gameIndices: [GameIndex]\n    let height: Int\n    let id: Int\n    let name: String\n    let types: [PokemonType]\n    let weight: Int\n    \n    private enum CodingKeys: String, CodingKey {\n        case gameIndices = \"game_indices\"\n        case height, id, name, types, weight\n    }\n}\n\nstruct GameIndex: Codable {\n    let gameIndex: Int\n    let version: Version\n    \n    private enum CodingKeys: String, CodingKey {\n        case gameIndex = \"game_index\"\n        case version\n    }\n}\n\nstruct Version: Codable {\n    let name: String\n    let url: String\n}\n\nstruct PokemonType: Codable {\n    let slot: Int\n    let type: Type\n    \n    private enum CodingKeys: String, CodingKey {\n        case slot, type\n    }\n}\n\nstruct Type: Codable {\n    let name: String\n    let url: String\n}\n\n\n// Solicitud para la info del pokemon\nvar apiUrlString = \"https://pokeapi.co/api/v2/pokemon/\\(pokemonName)\"\nguard var apiUrl = URL(string: apiUrlString) else {\n    print(\"URL inválida\")\n    exit(1)\n}\n\n// Crear una solicitud URLRequest.\nvar apiRequest = URLRequest(url: apiUrl)\napiRequest.httpMethod = \"GET\"\n\n// Crear una sesión URLSession.\nlet apiSession = URLSession.shared\n\n// Crear una tarea de datos\nlet apiTask = apiSession.dataTask(with: apiRequest) { (data, response, error) in\n    // Verificar si hay algún error\n    if let error = error {\n        print(\"Error: \\(error).\")\n        return\n    }\n    \n    // Verificar si se recibió una respuesta HTTP.\n    guard let httpResponse = response as? HTTPURLResponse else {\n        print(\"Respuesta HTTP inválida.\")\n        return\n    }\n    \n    // Verificar si la solicitud fue exitosa (código de estado 2xx).\n    guard (200...299).contains(httpResponse.statusCode) else {\n        print(\"Error en la solicitud. Código de estado: \\(httpResponse.statusCode).\")\n        return\n    }\n    \n    // Verificar si se recibieron datos.\n    guard let responseData = data else {\n        print(\"No se recibieron datos.\")\n        return\n    }\n    \n    let decoder = JSONDecoder()\n    \n    do {\n        let pokemon = try decoder.decode(Pokemon.self, from: responseData)\n        print(\"Nombre: \\(pokemon.name)\")\n        print(\"ID: \\(pokemon.id)\")\n        print(\"Peso: \\(pokemon.weight)\")\n        print(\"Altura: \\(pokemon.height)\")\n        \n        print(\"Typos: \")\n        for type in pokemon.types {\n            print(\"\\t\\(type.type.name)\")\n        }\n        \n        print(\"Juegos: \")\n        for game in pokemon.gameIndices {\n            print(\"\\t\\(game.version.name)\")\n        }\n    } catch {\n        print(error)\n    }\n}\n\n// Empezar la tarea\napiTask.resume()\nsleep(1)\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/swift/blackriper.swift",
    "content": "import Foundation\n/*\n Una peticion http  utiliza el protocolo Hypertext Transfer Protocol (HTTP). para comunicar\n datos atravez  de la red. esta peticion suele hacerse a un servidor o backend para obtener\n datos.\n\n una solicitud http se componene de los siguintes elementos:\n  un metodo (GET, POST, PUT, DELETE, PATCH)\n  una url (url de la peticion)\n  un encabezado (cabeceras)\n  version del protocolo (HTTP/1.1)\n\n Glosario basico de conceptos\n\n el metodo (GET, POST, PUT, DELETE, PATCH) es un verbo que se utiliza para\n saber la operacion que se va a realizar. por ejemplo:\n\n GET: obtiene informacion\n POST: permite enviar datos al servidor\n PUT:  nos permite enviar datos para actualizar\n DELETE: elimina datos\n\n el encabezado (cabeceras) es un conjunto de datos que se envia con la peticion\n estos pueden aportar informacion  adcional al servidor. por ejemplo:\n\n  Accept: acepta informacion de la peticion ya sea JSON o XML o texto plano\n\n  Peticiones http en Swift\n\n  en swift la libreria  de Foundation es la encargada de hacer las peticiones http\n  y asu vez nos permite convertir los datos recibidos  a una estructura de datos\n  de swift gracias al protocolo Codable.\n  \n  */\n  //1.- crear estructura para decodificar los datos de la solicitud\n   \n   struct Drink: Codable{\n        let strDrink: String\n        let strDrinkThumb: URL\n        let idDrink: String\n    }\n\n   struct Drinks: Codable {\n        let drinks: [Drink]\n    }\n\n   // 2.- hacer  solicitud http\n   \n   func fetchDrinks(url: URL) async throws -> [Drink] {\n        let (data, _) = try await URLSession.shared.data(from: url)\n        let drinks = try JSONDecoder().decode(Drinks.self, from: data)\n        return drinks.drinks\n    }\n\n\n   // 3.- llamar a la funcion de manera concurrente y crear el objeto url\n\n   let url = URL(string: \"https://www.thecocktaildb.com/api/json/v1/1/filter.php?i=Vodka\")!\n\n   Task {\n       let drinks = try await fetchDrinks(url: url)\n       print(drinks)\n   }\n\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/swift/pedroomar23.swift",
    "content": "import Foundation\n\n/*\n * EJERCICIO:\n * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n * una petición a la web que tú quieras, verifica que dicha petición\n * fue exitosa y muestra por consola el contenido de la web.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n * terminal al que le puedas solicitar información de un Pokémon concreto\n * utilizando su nombre o número.\n * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n * - Muestra el nombre de su cadena de evoluciones\n * - Muestra los juegos en los que aparece\n * - Controla posibles errores\n */\n\nstruct ExChange: Decodable {\n    let currency: String \n    let dataTime: String? \n    let exChangeDirection: String \n    let rates: Rates \n\n    enum CodingKeys: String, CodingKey {\n        case currency \n        case dataTime = \"data_time\"\n        case exChangeDirection = \"exchange_direction\"\n        case rates \n    }\n\n    init(from decoder: any Decoder) throws {\n        let container = try decoder.container(keyedBy: CodingKeys.self)\n        self.currency = try container.decode(String.self, forKey: .currency)\n        self.dataTime = try container.decodeIfPresent(String.self, forKey: .dataTime) ?? \"\"\n        self.exChangeDirection = try container.decode(String.self, forKey: .exChangeDirection)\n        self.rates = try container.decode(Rates.self, forKey: .rates)\n    }\n\n    init(currency: String, dataTime: String, exChangeDirection: String, rates: Rates) {\n        self.currency = currency\n        self.dataTime = dataTime\n        self.exChangeDirection = exChangeDirection\n        self.rates = rates \n    }\n}\n\nstruct Rates: Decodable {\n    let buy: Double \n    let sell: Double \n    let mid: Double \n\n    enum CodingKeys: CodingKey {\n        case buy \n        case sell \n        case mid \n    }\n\n    init(from decoder: any Decoder) throws {\n        let container = try decoder.container(keyedBy: CodingKeys.self)\n        self.buy = try container.decode(Double.self, forKey: .buy)\n        self.sell = try container.decode(Double.self, forKey: .sell)\n        self.mid = try container.decode(Double.self, forKey: .mid)\n    }\n\n    init(buy: Double, sell: Double, mid: Double) {\n        self.buy = buy \n        self.sell = sell \n        self.mid = mid \n    }\n}\n\nfunc exchange() async {\n    let urlCUP = URL(string: \"https://exchange-rate.decubba.com/api/v2/formal/target/cup.json\")!\n\n    let (dataCUP, _) = try! await URLSession.shared.data(from: urlCUP)\n    let exchangeCUP = try! JSONDecoder().decode(ExChange.self, from: dataCUP)\n    print(\"ExchangeCUP: \\(exchangeCUP)\")\n}\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/typescript/AChapeton.ts",
    "content": "const baseURL: string = 'https://pokeapi.co/api/v2/pokemon'\n\nconst getData = async (number: number) => {\n  try{\n    const res = await fetch(`${baseURL}/${number}`)\n    const data = await res.json()\n    \n    console.log('Name: ', data.name)\n    console.log('ID: ', data.id)\n    console.log('Weight: ', data.weight)\n    console.log('Height: ', data.height)\n\n    const types: Array<string> = data.types.map(type => type.type.name)\n    console.log('Types: ', types)\n\n    const games: Array<string> = data.game_indices.map(game => game.version.name)\n    console.log('Games: ', games)\n  }catch(error){\n    console.log(error)\n  }\n}\n\ngetData(9)"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/typescript/EdiedRamos.ts",
    "content": "// Author: EdiedRamos\n\nimport * as process from \"process\";\n\ninterface PokemonType {\n  name: string;\n  url: string;\n}\n\ninterface GameVersion {\n  name: string;\n  url: string;\n}\n\ninterface PokemonResponse {\n  id: number;\n  name: string;\n  weight: number;\n  height: number;\n  types: {\n    type: PokemonType;\n  }[];\n  game_indices: {\n    version: GameVersion;\n  }[];\n}\n\ninterface PokemonSpeciesResponse {\n  evolution_chain: {\n    url: string;\n  };\n}\n\ninterface Species {\n  name: string;\n  url: string;\n}\n\ninterface Chain {\n  evolves_to: Chain[];\n  species: Species;\n}\n\ninterface PokemonEvolutionResponse {\n  chain: Chain;\n}\n\nclass Pokemon {\n  private name: string;\n  private id: number;\n  private weight: number;\n  private height: number;\n  private types: string[];\n  private evolutions: string[];\n  private games: string[];\n\n  constructor(\n    private pokemonBaseInformation: PokemonResponse,\n    private pokemonEvolutions: PokemonEvolutionResponse\n  ) {\n    this.loadInformation();\n  }\n\n  private loadInformation() {\n    this.id = this.pokemonBaseInformation.id;\n    this.name = this.pokemonBaseInformation.name;\n    this.weight = this.pokemonBaseInformation.weight;\n    this.height = this.pokemonBaseInformation.height;\n    this.types = this.pokemonBaseInformation.types.map(({ type }) => type.name);\n    this.games = this.pokemonBaseInformation.game_indices.map(\n      ({ version }) => version.name\n    );\n    this.evolutions = this.evolutionPath(this.pokemonEvolutions.chain, []);\n  }\n\n  private evolutionPath(chain: Chain, currentPath: string[]): string[] {\n    currentPath.push(chain.species.name);\n    if (chain.evolves_to.length === 0) return currentPath;\n    return this.evolutionPath(chain.evolves_to[0], currentPath);\n  }\n\n  get toString(): string {\n    return `\n    ${\"=\".repeat(20)}\n    Id: ${this.id}\n    Nombre: ${this.name}\n    Peso: ${this.weight}\n    Altura: ${this.height}\n    Tipos: ${this.types.join(\",\")}\n    Juegos: ${this.games.join(\",\")}\n    Evoluciones: ${this.evolutions.join(\",\")}\n    ${\"=\".repeat(20)}\n    `;\n  }\n}\n\nclass Fetcher {\n  static async get<T>(endpoint: string): Promise<T> {\n    const response = await fetch(endpoint);\n    const data = (await response.json()) as T;\n    return data;\n  }\n}\n\nclass PokemonFetcher {\n  private static baseUrl = \"https://pokeapi.co/api/v2/\";\n\n  static async fetchPokemonInformation(\n    pokemonTarget: string\n  ): Promise<PokemonResponse> {\n    return await Fetcher.get<PokemonResponse>(\n      `${this.baseUrl}pokemon/${pokemonTarget}`\n    );\n  }\n\n  static async fetchPokemonSpecies(\n    pokemonTarget: string\n  ): Promise<PokemonSpeciesResponse> {\n    return await Fetcher.get<PokemonSpeciesResponse>(\n      `${this.baseUrl}pokemon-species/${pokemonTarget}`\n    );\n  }\n\n  static async fetchPokemonEvolutionFromURL(\n    evolutionURL: string\n  ): Promise<PokemonEvolutionResponse> {\n    return await Fetcher.get<PokemonEvolutionResponse>(evolutionURL);\n  }\n}\n\nclass PokemonService {\n  static async searchInformation(pokemonTarget: string): Promise<string> {\n    try {\n      const pokemonBaseInformation =\n        await PokemonFetcher.fetchPokemonInformation(pokemonTarget);\n      const pokemonSpecies = await PokemonFetcher.fetchPokemonSpecies(\n        pokemonTarget\n      );\n      const pokemonEvolutions =\n        await PokemonFetcher.fetchPokemonEvolutionFromURL(\n          pokemonSpecies.evolution_chain.url\n        );\n\n      const pokemon = new Pokemon(pokemonBaseInformation, pokemonEvolutions);\n      return pokemon.toString;\n    } catch (error) {\n      return `\n    ${\"=\".repeat(20)}\n    Pokémon no encontrado...\n    ${\"=\".repeat(20)}\n      `;\n    }\n  }\n}\n\nfunction menu() {\n  console.log(\"Ingrese el nombre o id del pokémon (o 'salir' para terminar): \");\n\n  process.stdin.on(\"data\", async (data: string) => {\n    const input = data.toString().trim().toLowerCase();\n\n    if (input === \"salir\") {\n      console.log(\"Saliendo del programa...\\n\");\n      process.stdin.close();\n    } else {\n      const information = await PokemonService.searchInformation(input);\n      console.log(information);\n      console.log(\n        \"Ingrese el nombre o id del pokémon (o 'salir' para terminar): \"\n      );\n    }\n  });\n}\n\n(() => menu())();\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/typescript/IgleDev.ts",
    "content": "const pokemonURL : string = 'https://pokeapi.co/api/v2/pokemon'\n\nconst getData = async (number: number) => {\n  try{\n    const res = await fetch(`${pokemonURL}/${number}`)\n    const data = await res.json()\n    \n    console.log('Nombre: ', data.name);\n    console.log('ID Pokemon: ', data.id);\n    console.log('Peso: ', data.weight);\n    console.log('Altura: ', data.height);\n\n    const tipos : Array<string> = data.types.map(tipos => tipos.type.name);\n    console.log('Tipos: ', tipos);\n\n    const juegos : Array<string> = data.game_indices.map(juegos => juegos.version.name)\n    console.log('Juegos: ', juegos)\n  }catch(error){\n    console.log('No hemos podido conectarnos a la API')\n  }\n}\n\ngetData(152);"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/typescript/Sac-Corts.ts",
    "content": "const id: number = 10;\nconst urljson: string = `https://jsonplaceholder.typicode.com/posts/${id}`;\n\nfetch(urljson)\n.then((response: Response) => {\n    if (!response.ok) {\n        throw new Error(\"Request error: \" + response.status);\n    }\n    return response.json();\n})\n.then((data: any) => {\n    console.log(data);\n})\n.catch((error: Error) => {\n    console.error(\"There was a problem with the request Fetch:\", error);\n});\n\n// ** Extra Exercise ** //\n\ninterface PokemonType {\n    type: {\n        name: string;\n    };\n}\n\ninterface PokemonData {\n    forms: { name: string }[];\n    name: string;\n    id: number;\n    weight: number;\n    height: number;\n    types: PokemonType[];\n    species: {\n        url: string;\n    };\n    game_indices: {\n        version: {\n            name: string;\n        };\n    }[];\n}\n\ninterface EvolutionChain {\n    species: {\n        name: string;\n    };\n    evolves_to: EvolutionChain[];\n}\n\nasync function getPokemonInfo(pokemon: string): Promise<void> {\n    try {\n        const response: Response = await fetch(`https://pokeapi.co/api/v2/pokemon/${pokemon.toLowerCase()}`);\n        const pokemonData: PokemonData = await response.json();\n\n        console.log('Pokemon data:', pokemonData.forms[0][\"name\"]);\n        console.log('Name:', pokemonData.name);\n        console.log('ID:', pokemonData.id);\n        console.log('Weight:', pokemonData.weight);\n        console.log('Height:', pokemonData.height);\n        console.log('Types:');\n        pokemonData.types.forEach((type: PokemonType) => {\n            console.log('-', type.type.name);\n        });\n\n        const speciesResponse: Response = await fetch(pokemonData.species.url);\n        const speciesData: any = await speciesResponse.json();\n        const evolutionChainUrl: string = speciesData.evolution_chain.url;\n        const evolutionChainResponse: Response = await fetch(evolutionChainUrl);\n        const evolutionChainData: { chain: EvolutionChain } = await evolutionChainResponse.json();\n\n        console.log('Evolution chain:');\n        let evolutionChain: EvolutionChain | null = evolutionChainData.chain;\n        while (evolutionChain) {\n            console.log('-', evolutionChain.species.name);\n            evolutionChain = evolutionChain.evolves_to[0] || null;\n        }\n\n        console.log('Games in which it appears:');\n        pokemonData.game_indices.forEach(game => {\n            console.log('-', game.version.name);\n        });\n\n    } catch (error) {\n        console.error('Error:', error.message);\n    }\n}\n\nconst pokemon: string = '3'; \ngetPokemonInfo(pokemon);\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/typescript/duendeintemporal.ts",
    "content": "// #20 PETICIONES HTPP\n/*\n * EJERCICIO:\n * Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n * una petición a la web que tú quieras, verifica que dicha petición\n * fue exitosa y muestra por consola el contenido de la web.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utilizando la PokéAPI (https://pokeapi.co), crea un programa por\n * terminal al que le puedas solicitar información de un Pokémon concreto\n * utilizando su nombre o número.\n * - Muestra el nombre, id, peso, altura y tipo(s) del Pokémon\n * - Muestra el nombre de su cadena de evoluciones\n * - Muestra los juegos en los que aparece\n * - Controla posibles errores\n */\n// I use GPT for reference information.\n\n// Short for console.log\nlet log = console.log;\n\n// Definimos una interfaz para el objeto Pokémon\ninterface Pokemon {\n    name: string;\n    id: number;\n    weight: number;\n    height: number;\n    types: { type: { name: string } }[];\n    game_indices: { version: { name: string } }[];\n}\n\n// Función para hacer una petición HTTP y obtener el contenido de una web\nasync function fetchContent(url: string): Promise<void> {\n    try {\n        const response = await fetch(url);\n        if (!response.ok) {\n            throw new Error(`HTTP error! status: ${response.status}`);\n        }\n        const data = await response.json();\n        log(data);\n    } catch (error) {\n        console.error('Error fetching content:', error);\n    }\n}\n\n// Función para obtener texto Lorem Ipsum\nasync function getLoremIpsum(numberOfParagraphs: number): Promise<void> {\n    try {\n        const response = await fetch(`https://baconipsum.com/api/?type=meat-and-filler&paras=${numberOfParagraphs}`);\n        if (!response.ok) {\n            throw new Error(`HTTP error! status: ${response.status}`);\n        }\n        const loremIpsumTextArray = await response.json();\n        updateResult(loremIpsumTextArray);\n    } catch (error) {\n        showError(error as Error);\n    }\n}\n\n// Función para actualizar el resultado en el DOM\nfunction updateResult(textArray: string[]): void {\n    const resultElement = document.querySelector('.result') as HTMLElement;\n    if (resultElement) {\n        resultElement.classList.add('show');\n        resultElement.style.display = '';\n        resultElement.innerHTML = textArray.map(paragraph => `<p>${paragraph}</p>`).join('');\n        addCopyButton(textArray.join(''));\n\n        // Aplicar estilos a los párrafos\n        const pElements = document.querySelectorAll('.result p') as NodeListOf<HTMLElement>;\n        pElements.forEach(p => {\n            p.style.color = '#fff';\n            p.style.lineHeight = '16px';\n            p.style.textAlign = 'justify';\n        });\n    }\n}\n\n// Función para mostrar errores\nfunction showError(error: Error): void {\n    const resultElement = document.querySelector('.result');\n    if (resultElement) {\n        resultElement.innerHTML = `<p class=\"error\">${error.message}</p>`;\n    }\n}\n\n// Función para añadir un botón de copiar\nfunction addCopyButton(text: string): void {\n    const resultElement = document.querySelector('.result');\n    if (resultElement) {\n        const copyBtn = document.createElement('button');\n        copyBtn.textContent = 'Copy';\n        copyBtn.classList.add('copy');\n        copyBtn.onclick = () => {\n            navigator.clipboard.writeText(text).then(() => {\n                copyBtn.textContent = 'Copied!';\n                setTimeout(() => {\n                    copyBtn.textContent = 'Copy';\n                }, 2000);\n            });\n        };\n        resultElement.appendChild(copyBtn);\n    }\n}\n\n// Función para obtener información de un Pokémon\nasync function getPokemon(id: string): Promise<void> {\n    try {\n        const response = await fetch(`https://pokeapi.co/api/v2/pokemon/${id}`);\n        if (!response.ok) {\n            throw new Error(`HTTP error! status: ${response.status}`);\n        }\n        const data: Pokemon = await response.json();\n\n        type PokemonInfo = {\n            name: string;\n            id: string;\n            weight: string;\n            height: string;\n            type: string;\n            games: string;\n        };\n\n        const pokemon: PokemonInfo = {\n            name: `Name: ${data.name}`,\n            id: `Id: ${data.id}`,\n            weight: `Weight: ${data.weight}`,\n            height: `Height: ${data.height}`,\n            type: `Type: ${data.types.map(t => t.type.name).join(', ')}`,\n            games: `Games: ${data.game_indices.map(g => g.version.name).join(', ')}`,\n        };\n\n        log(pokemon);\n\n        if (typeof window !== 'undefined') {\n            const modal1 = document.createElement('div');\n            modal1.style.position = 'relative';\n            modal1.style.top = '50%';\n            modal1.style.color = '#fff';\n            modal1.style.left = '50%';\n            modal1.style.transform = 'translate(-50%, -72%)';\n            modal1.style.background = 'rgba(0,0,0,0.9)';\n            modal1.style.width = '100vw';\n            modal1.style.height = '100vh';\n            modal1.style.display = 'flex';\n            modal1.style.justifyContent = 'center';\n            modal1.style.alignItems = 'center';\n\n            const modal2 = document.createElement('div');\n            modal2.style.width = '80vw';\n            modal2.style.height = '100vh';\n            modal2.style.display = 'flex';\n            modal2.style.justifyContent = 'space-around';\n            modal2.style.alignItems = 'flex-start';\n            modal2.style.flexDirection = 'column';\n\n            const h1 = document.createElement('h1');\n            h1.textContent = `POKEMON`;\n            h1.style.alignSelf = 'center';\n            h1.style.fontFamily = 'cursive';\n            modal2.appendChild(h1);\n            modal1.appendChild(modal2);\n            document.body.appendChild(modal1);\n\n            for (let key in pokemon) {\n                if (pokemon.hasOwnProperty(key)) {\n                    let p = document.createElement('p');\n                    p.textContent = pokemon[key as keyof PokemonInfo]; // Type assertion aquí\n                    p.style.color = 'yellow';\n                    p.style.fontSize = '2vw';\n                    p.style.fontWeight = '600';\n                    p.style.fontFamily = 'cursive';\n                    p.style.textAlign = 'justify';\n                    modal2.appendChild(p);\n                }\n            }\n\n            // Función para eliminar el modal\n            const removeModal = () => {\n                modal1.remove();\n                document.removeEventListener('keydown', handleKeyDown);\n            };\n\n            // Añadir event listener para eliminar el modal al hacer clic\n            modal2.addEventListener('click', removeModal);\n\n            // Función para manejar eventos de teclado\n            const handleKeyDown = (event: KeyboardEvent) => {\n                if (event.key === \"Escape\") {\n                    removeModal();\n                }\n            };\n\n            // Añadir event listener para eventos de teclado\n            document.addEventListener('keydown', handleKeyDown);\n        }\n    } catch (error) {\n        console.error('Error fetching Pokémon:', error);\n    }\n}\n\n// Verificamos si estamos en un entorno de navegador\nif (typeof window !== 'undefined') {\n    window.addEventListener('load', () => {\n        const body = document.querySelector('body');\n        const title = document.createElement('h1');\n\n        body?.style.setProperty('background', '#000');\n        body?.style.setProperty('text-align', 'center');\n\n        title.textContent = 'Retosparaprogramadores #20.';\n        title.style.setProperty('font-size', '3.5vmax');\n        title.style.setProperty('color', '#fff');\n        title.style.setProperty('line-height', '34vh');\n\n        body?.appendChild(title);\n        log('Retosparaprogramadores #20');\n\n        // Crear modal para Lorem Ipsum\n        const modal = document.createElement('div');\n        modal.style.position = 'relative';\n        modal.style.top = '50%';\n        modal.style.left = '50%';\n        modal.style.transform = 'translate(-50%, -20%)';\n        modal.style.background = 'rgba(0,0,0,0.2)';\n        modal.style.width = '400px';\n        modal.style.minHeight = '200px';\n        document.body.appendChild(modal);\n\n        const loremIpsumContainer = document.createElement('div');\n        loremIpsumContainer.style.fontFamily = 'sans-serif';\n        loremIpsumContainer.style.margin = '1rem';\n        modal.appendChild(loremIpsumContainer);\n\n        const label = document.createElement('label');\n        label.style.padding = '10px';\n        label.style.color = '#fff';\n        label.setAttribute('for', 'paragraphsCount');\n        const strong = document.createElement('strong');\n        strong.textContent = 'How many Paragraphs?';\n        loremIpsumContainer.appendChild(label);\n        label.appendChild(strong);\n\n        const input = document.createElement('input');\n        input.setAttribute('type', 'number');\n        input.style.width = '4rem';\n        input.setAttribute('min', '0');\n        input.classList.add('paragraphsCount');\n        loremIpsumContainer.appendChild(input);\n\n        const button = document.createElement('button');\n        button.style.background = '#ff8c00';\n        button.style.color = '#f6f6f6';\n        button.style.padding = '5px';\n        button.style.borderRadius = '15px';\n        button.style.textAlign = 'center';\n        button.style.marginLeft = '10px';\n        button.textContent = 'Generate';\n        button.classList.add('getLoremIpsum');\n        loremIpsumContainer.appendChild(button);\n\n        const result = document.createElement('div');\n        result.style.marginTop = '1rem';\n        result.style.padding = '1rem';\n        result.style.border = '1px dashed black';\n        result.style.fontSize = '.75rem';\n        result.style.position = 'absolute';\n        result.style.left = '-25%';\n        result.style.width = '58vw';\n        result.style.display = 'none';\n        result.classList.add('result');\n        loremIpsumContainer.appendChild(result);\n\n        // Añadir event listener para el botón de generar Lorem Ipsum\n        setTimeout(() => {\n            const getLoremIpsumElement = document.querySelector('.getLoremIpsum');\n            const paragraphsCountElement = document.querySelector('.paragraphsCount') as HTMLInputElement;\n\n            getLoremIpsumElement?.addEventListener('click', () => {\n                const numberOfParagraphs = parseInt(paragraphsCountElement.value);\n                if (!isNaN(numberOfParagraphs)) {\n                    getLoremIpsum(numberOfParagraphs);\n                    paragraphsCountElement.value = '';\n                }\n            });\n        }, 1000);\n\n        // Solicitar información de un Pokémon después de 2 segundos\n        setTimeout(() => {\n            const id = prompt('Please type a number id to get the pokemon data');\n            if (id) {\n                getPokemon(id);\n            }\n        }, 2000);\n    });\n} else {\n    log('This code is designed to run in a browser environment. Skipping window-related code.');\n    log('Retosparaprogramadores #20');\n}"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/typescript/eulogioep.ts",
    "content": "/**\n * Teoría sobre peticiones HTTP en TypeScript:\n *\n * TypeScript añade tipado estático a JavaScript, lo que nos permite:\n * 1. Definir interfaces para las respuestas de la API\n * 2. Tener mejor autocompletado y detección de errores en tiempo de compilación\n * 3. Hacer el código más mantenible y autodocumentado\n *\n * Para peticiones HTTP, podemos usar:\n * - fetch en navegadores o con 'node-fetch' en Node.js\n * - axios como una alternativa más robusta\n *\n * Este ejemplo usa 'node-fetch' y requiere:\n * npm install typescript @types/node node-fetch @types/node-fetch\n */\n\nimport fetch from \"node-fetch\";\nimport * as readline from \"readline\";\n\n// Interfaces para tipar las respuestas de la API\ninterface Pokemon {\n  name: string;\n  id: number;\n  weight: number;\n  height: number;\n  types: Array<{\n    type: {\n      name: string;\n    };\n  }>;\n  game_indices: Array<{\n    version: {\n      name: string;\n    };\n  }>;\n  species: {\n    url: string;\n  };\n}\n\ninterface PokemonSpecies {\n  evolution_chain: {\n    url: string;\n  };\n}\n\ninterface EvolutionChain {\n  chain: ChainLink;\n}\n\ninterface ChainLink {\n  species: {\n    name: string;\n  };\n  evolves_to: ChainLink[];\n}\n\n// Configuración de readline para entrada/salida en consola\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout,\n});\n\n// Función para realizar preguntas al usuario y obtener respuesta\nfunction pregunta(pregunta: string): Promise<string> {\n  return new Promise((resolve) => {\n    rl.question(pregunta, resolve);\n  });\n}\n\n// Función genérica para realizar peticiones HTTP\nasync function hacerPeticionHttp<T>(url: string): Promise<T> {\n  try {\n    const respuesta = await fetch(url);\n    if (!respuesta.ok) {\n      throw new Error(`HTTP error! status: ${respuesta.status}`);\n    }\n    return (await respuesta.json()) as T;\n  } catch (error) {\n    throw new Error(\n      `Error al realizar la petición: ${\n        error instanceof Error ? error.message : \"Unknown error\"\n      }`\n    );\n  }\n}\n\n// Función para mostrar la cadena de evolución\nfunction mostrarCadenaEvolucion(cadena: ChainLink, nivel: number = 0): void {\n  const indentacion = \"  \".repeat(nivel);\n  console.log(`${indentacion}- ${cadena.species.name}`);\n\n  if (cadena.evolves_to.length > 0) {\n    for (const evolucion of cadena.evolves_to) {\n      mostrarCadenaEvolucion(evolucion, nivel + 1);\n    }\n  }\n}\n\n// Función principal que ejecuta el programa\nasync function main(): Promise<void> {\n  console.log(\"=== Ejemplo básico de petición HTTP ===\");\n  try {\n    await hacerPeticionHttp(\"https://www.example.com\");\n    console.log(\"Petición exitosa a example.com\");\n  } catch (error) {\n    console.error(error instanceof Error ? error.message : \"Unknown error\");\n  }\n\n  while (true) {\n    console.log(\"\\n=== Búsqueda de Pokémon ===\");\n    const entrada = await pregunta(\n      \"Ingrese el nombre o número del Pokémon (o 'salir' para terminar): \"\n    );\n\n    if (entrada.toLowerCase() === \"salir\") {\n      break;\n    }\n\n    try {\n      // Obtener datos básicos del Pokémon\n      const pokemonData = await hacerPeticionHttp<Pokemon>(\n        `https://pokeapi.co/api/v2/pokemon/${entrada.toLowerCase()}`\n      );\n\n      console.log(\"\\nInformación del Pokémon:\");\n      console.log(`Nombre: ${pokemonData.name}`);\n      console.log(`ID: ${pokemonData.id}`);\n      console.log(`Peso: ${pokemonData.weight / 10} kg`);\n      console.log(`Altura: ${pokemonData.height / 10} m`);\n\n      console.log(\"Tipos:\");\n      pokemonData.types.forEach((tipo) => {\n        console.log(`- ${tipo.type.name}`);\n      });\n\n      // Obtener y mostrar cadena de evolución\n      const speciesData = await hacerPeticionHttp<PokemonSpecies>(\n        pokemonData.species.url\n      );\n      const evolutionData = await hacerPeticionHttp<EvolutionChain>(\n        speciesData.evolution_chain.url\n      );\n\n      console.log(\"\\nCadena de evolución:\");\n      mostrarCadenaEvolucion(evolutionData.chain);\n\n      // Mostrar juegos\n      console.log(\"\\nJuegos en los que aparece:\");\n      pokemonData.game_indices.forEach((juego) => {\n        console.log(`- ${juego.version.name}`);\n      });\n    } catch (error) {\n      console.error(\n        \"Error: No se pudo encontrar el Pokémon. Asegúrese de escribir el nombre o número correctamente.\"\n      );\n    }\n  }\n\n  rl.close();\n}\n\n// Ejecutar el programa\nmain().catch((error) => {\n  console.error(\n    \"Error en la ejecución del programa:\",\n    error instanceof Error ? error.message : \"Unknown error\"\n  );\n  process.exit(1);\n});\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/typescript/hozlucas28.ts",
    "content": "/*\n    HTTP request...\n*/\n\ninterface Fact {\n    id: string\n    type: string\n    attributes: {\n        body: string\n    }\n}\n\ninterface DogFact {\n    data: Fact[]\n}\n\nasync function httpRequestMain() {\n    console.log('HTTP request...')\n\n    try {\n        const response = await fetch('https://dogapi.dog/api/v2/facts')\n\n        if (response.status === 200) {\n            const dogFact: DogFact = await response.json()\n            console.log(`\\nRandom dog fact: ${dogFact.data[0].attributes.body}`)\n        } else {\n            throw new Error(`${response.status} ${response.statusText}`)\n        }\n    } catch (error) {\n        console.error(`\\n${error}`)\n    }\n}\n\n/*\n    Additional challenge...\n*/\n\ninterface GameIndex {\n    game_index: number\n    version: {\n        name: string\n    }\n}\n\ninterface Type {\n    slot: number\n    type: {\n        name: string\n    }\n}\n\ninterface Pokemon {\n    game_indices: GameIndex[]\n    height: number\n    id: number\n    name: string\n    types: Type[]\n}\n\nasync function getPokemonData(id: number | string): Promise<never | Pokemon> {\n    const response = await fetch(`https://pokeapi.co/api/v2/pokemon/${id}`)\n\n    if (response.status === 200) {\n        const pokemon: Pokemon = await response.json()\n        return pokemon\n    } else {\n        throw new Error(`${response.status} ${response.statusText}`)\n    }\n}\n\nasync function additionalChallengeMain() {\n    console.log(\n        '\\n# ---------------------------------------------------------------------------------- #\\n'\n    )\n\n    console.log('Additional challenge...')\n\n    const formatter = new Intl.ListFormat('en', {\n        style: 'long',\n        type: 'conjunction',\n    })\n\n    console.log('\\nPokemon with id number five...')\n\n    try {\n        const fifthPokemon: Pokemon = await getPokemonData(5)\n        const fifthPokemonGames = fifthPokemon.game_indices.map(\n            (gameIndex) => gameIndex.version.name\n        )\n        const fifthPokemonTypes = fifthPokemon.types.map(\n            (type) => type.type.name\n        )\n\n        console.log(`\\nid: ${fifthPokemon.id}`)\n        console.log(`name: ${fifthPokemon.name}`)\n        console.log(`height: ${fifthPokemon.height}`)\n        console.log(`type: ${formatter.format(fifthPokemonTypes)}`)\n        console.log(`games: ${formatter.format(fifthPokemonGames)}`)\n    } catch (error) {\n        console.error(`\\n${error}`)\n    }\n\n    console.log('\\nPokemon with \"Bulbasaur\" name...')\n\n    try {\n        const bulbasaur: Pokemon = await getPokemonData('bulbasaur')\n        const bulbasaurGames = bulbasaur.game_indices.map(\n            (gameIndex) => gameIndex.version.name\n        )\n        const bulbasaurTypes = bulbasaur.types.map((type) => type.type.name)\n\n        console.log(`\\nid: ${bulbasaur.id}`)\n        console.log(`name: ${bulbasaur.name}`)\n        console.log(`height: ${bulbasaur.height}`)\n        console.log(`type: ${formatter.format(bulbasaurTypes)}`)\n        console.log(`games: ${formatter.format(bulbasaurGames)}`)\n    } catch (error) {\n        console.error(`\\n${error}`)\n    }\n}\n\nPromise.all([httpRequestMain()]).then(\n    async () => await additionalChallengeMain()\n)\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/typescript/victor-Casta.ts",
    "content": "const readline = require('node:readline')\nconst { stdin: input, stdout: output } = require('node:process')\n\nconst rl = readline.createInterface({ input, output })\n\n\ninterface Products {\n  id: number\n  title: string\n  price: number\n  description: string\n  category: Category\n  images: string[]\n}\n\ninterface Category {\n  id: number\n  name: string\n  image: string\n}\n\nasync function getProducts(): Promise<Products[]> {\n  try {\n    const response = await fetch('https://api.escuelajs.co/api/v1/products')\n\n    if (!response.ok) {\n      throw new Error(`HTTP error! status: ${response.status}`)\n    }\n\n    const results: Products[] = await response.json()\n    console.log('Petición exitosa')\n    return results\n  } catch (error) {\n    console.log('Error al obtener productos:', error)\n    return []\n  }\n}\n\nasync function printData() {\n  const productsInformation = await getProducts()\n  console.log(productsInformation)\n}\n\n\n/*\n  * Extra\n*/\n\nconst baseUrl: string = 'https://pokeapi.co/api/v2/pokemon/'\n\ninterface Pokemon {\n  id: number\n  name: string\n  weight: number\n  height: number\n  abilities: Ability[]\n  types: Type[]\n  stats: Stat[]\n  sprites: Sprite\n}\n\ninterface Ability {\n  ability: NamedAPIResource\n  is_hidden: boolean\n  slot: number\n}\n\ninterface NamedAPIResource {\n  name: string\n  url: string\n}\n\ninterface Type {\n  slot: number\n  type: NamedAPIResource\n}\n\ninterface Stat {\n  base_stat: number\n  effort: number\n  stat: NamedAPIResource\n}\n\ninterface Sprite {\n  front_default: string\n  back_default?: string\n}\n\nasync function getPokemonInformation(\n  url: string,\n  pokemonName: string\n): Promise<Pokemon | null> {\n  try {\n    const response = await fetch(`${url}${pokemonName}`)\n    if (!response.ok) {\n      console.log(`Error en la respuesta de la API: ${response.status}`)\n      return null\n    }\n    const result: Pokemon = await response.json()\n    console.log('Petición exitosa')\n    return result\n  } catch (error) {\n    console.error('Error al realizar la petición:', error)\n    return null\n  }\n}\n\nrl.question('Ingresa el nombre de un Pokémon: ', async (pokemonNameAnswer: string) => {\n  const pokemonInformation = await getPokemonInformation(baseUrl, pokemonNameAnswer.toLowerCase())\n\n  if (pokemonInformation) {\n    console.log(`Información de ${pokemonInformation.name}:`)\n    console.log(`ID: ${pokemonInformation.id}`)\n    console.log(`Peso: ${pokemonInformation.weight}`)\n    console.log(`Altura: ${pokemonInformation.height}`)\n    console.log('Tipos:')\n    pokemonInformation.types.forEach((type) => console.log(` - ${type.type.name}`))\n    console.log('Estadísticas:')\n    pokemonInformation.stats.forEach((stat) => console.log(` - ${stat.stat.name}: ${stat.base_stat}`))\n  } else {\n    console.log('No se encontró información para el Pokémon ingresado.')\n  }\n\n  rl.close()\n})"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/typescript/victoriaparraf.ts",
    "content": "import axios from 'axios';\n\nasync function fetchWebContent(url: string): Promise<void> {\n    try {\n        const response = await axios.get(url);\n        console.log('Status:', response.status);\n        console.log('Headers:', response.headers);\n        console.log('Data:', response.data);\n    } catch (error) {\n        console.error('Error fetching the web content:', error);\n    }\n}\n\n// Llamada a la función con una URL de ejemplo\nfetchWebContent('https://wattpad.com');\n\n/************************************************************/\n\ninterface Pokemon {\n    name: string;\n    id: number;\n    weight: number;\n    height: number;\n    types: Array<{ type: { name: string } }>;\n    species: { url: string };\n    game_indices: Array<{ version: { name: string } }>;\n}\n\ninterface EvolutionChain {\n    chain: {\n        species: { name: string };\n        evolves_to: Array<any>;\n    };\n}\n\nasync function getPokemonInfo(identifier: string | number): Promise<void> {\n    try {\n        const response = await axios.get<Pokemon>(`https://pokeapi.co/api/v2/pokemon/${identifier}`);\n        const pokemon = response.data;\n\n        console.log(`Name: ${pokemon.name}`);\n        console.log(`ID: ${pokemon.id}`);\n        console.log(`Weight: ${pokemon.weight}`);\n        console.log(`Height: ${pokemon.height}`);\n        console.log('Types:', pokemon.types.map(type => type.type.name).join(', '));\n\n        // Get evolution chain\n        const speciesResponse = await axios.get<{ evolution_chain: { url: string } }>(pokemon.species.url);\n        const evolutionResponse = await axios.get<EvolutionChain>(speciesResponse.data.evolution_chain.url);\n        const evolutionChain = evolutionResponse.data.chain;\n        \n        const evolutionNames: string[] = [];\n        let current = evolutionChain;\n        while (current) {\n            evolutionNames.push(current.species.name);\n            current = current.evolves_to[0];\n        }\n        console.log('Evolution Chain:', evolutionNames.join(' -> '));\n\n        // Get game appearances\n        console.log('Games:', pokemon.game_indices.map(game => game.version.name).join(', '));\n    } catch (error) {\n        console.error('Error fetching Pokémon information:', error);\n    }\n}\n\n// Llamada a la función con un nombre o número de Pokémon\ngetPokemonInfo('pikachu'); // Puedes usar el nombre o el número del Pokémon\ngetPokemonInfo(1); // También puedes usar el número del Pokémon\n\n\n"
  },
  {
    "path": "Roadmap/20 - PETICIONES HTTP/vb.net/kenysdev.vb",
    "content": "' ╔══════════════════════════════════════╗\n' ║ Autor:  Kenys Alvarado               ║\n' ║ GitHub: https://github.com/Kenysdev  ║\n' ║ 2024 -  VB.NET                       ║\n' ╚══════════════════════════════════════╝\n'-----------------------------------------------\n'* PETICIONES HTTP\n'-----------------------------------------------\n\nImports System.Net.Http\nImports System.Text.Json\n\nModule Program\n    ' EJERCICIO:\n    ' Utilizando un mecanismo de peticiones HTTP de tu lenguaje, realiza\n    ' una petición a la web que tú quieras, verifica que dicha petición\n    ' fue exitosa y muestra por consola el contenido de la web.\n\n    Private ReadOnly client As New HttpClient()\n\n    Async Function GetUser(userId As Integer) As Task(Of Dictionary(Of String, Object))\n        Try\n            Dim url As String = $\"https://jsonplaceholder.typicode.com/users/{userId}\"\n            Dim response As HttpResponseMessage = Await client.GetAsync(url)\n\n            If response.IsSuccessStatusCode Then\n                Dim json As String = Await response.Content.ReadAsStringAsync()\n                Return JsonSerializer.Deserialize(Of Dictionary(Of String, Object))(json)\n            Else\n                Console.WriteLine($\"Id: {userId} No encontrado\")\n                Console.WriteLine(response.StatusCode)\n                Return New Dictionary(Of String, Object)()\n            End If\n        Catch ex As HttpRequestException\n            Console.WriteLine(\"Error de conexión\")\n            Return New Dictionary(Of String, Object)()\n        End Try\n    End Function\n\n    Sub PrintUser(userData As Dictionary(Of String, Object))\n        If userData.Count > 0 Then\n            Console.WriteLine(\n                $\"Usuario con id: '{userData(\"id\")}':\" & vbCrLf &\n                $\"Nombre:  {userData(\"name\")}\" & vbCrLf &\n                $\"Usuario: {userData(\"username\")}\" & vbCrLf &\n                $\"Email:   {userData(\"email\")}\" & vbCrLf &\n                $\"Teléfono: {userData(\"phone\")}\" & vbCrLf\n            )\n        End If\n    End Sub\n\n    Async Function MainAsync() As Task\n        Dim client As New HttpClient()\n\n        Dim u1 = Await GetUser(1)\n        PrintUser(u1)\n\n        Dim u2 = Await GetUser(2)\n        PrintUser(u2)\n\n        Dim u3 = Await GetUser(777) ' no existente\n        PrintUser(u3)\n\n        client.Dispose()\n    End Function\n\n    Sub Main()\n        MainAsync().Wait()\n    End Sub\n\nEnd Module\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/bash/rantamhack.sh",
    "content": "#!/bin/bash\n\n# * EJERCICIO:\n# * Explora el concepto de callback en tu lenguaje creando un ejemplo\n# * simple (a tu eleccion) que muestre su funcionamiento.\n\n\necho -e \"\\n\\n=======================================CONSIDERACIONES=======================================\\n\\n\"\n\n\necho -e \"\\n\\tEn bash no existe un return al uso por lo que hay que simularlo para\"\necho -e \"\\n\\tllamar a una funcion desde otra, para esto lo que hacemos es que el\"\necho -e \"\\n\\tvalor de la funcion a llamar lo igualamos a una variable y llamamos a esta\\n\"\n\n\necho -e \"\\n\\n=======================================EJERCICIO=======================================\\n\\n\"\n\n\nread -p \"Elige un primer numero: \" base\nread -p \"Elige un segundo numero: \" altura\n\n# Vamos a hacer el AREA DE UN TRIANGULO dividida en 2 funciones para que una llame a la otra\noperation_one () {\n    first_result=$(( $base * $altura ))\n    echo $first_result\n}\n\nresult=$(operation_one)\n\n# Funcion area\nvalue_area () {\n    area=$(echo \"scale=2; $1 / 2\" | bc)\n    echo -e \"El valor del area de este triangulo es: $area\"\n}\n\nvalue_area \"$result\"\n\n\n\n\n# * DIFICULTAD EXTRA (opcional):\n# * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n# * Estará formado por una función que procesa pedidos.\n# * Debe aceptar el nombre del plato, una callback de confirmacion, una\n# * de listo y otra de entrega.\n# * - Debe imprimir un confirmación cuando empiece el procesamiento.\n# * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n# *   procesos.\n# * - Debe invocar a cada callback siguiendo un orden de procesado.\n# * - Debe notificar que el plato está listo o ha sido entregado.\n\necho -e \"\\n\\n=======================================DIFICULTAD EXTRA=======================================\\n\\n\"\n\n\n\nmenu=(\"4Quesos\" \"Margarita\" \"Tropical\" \"Carbonara\" \"Campesina\" \"Barbacoa\")\n\nexit_program=false\n\nread -p \"Que Pizza de la carta te apetece tomar?: \" order\n\nfunction place_order() {\n\n    local order=$1\n    local callback=$2\n\n    for pizza in \"${menu[@]}\"; do\n        if [[ \"$pizza\" == \"$order\" ]]; then\n            echo -e \"\\nHa elegido pizza $order, enviamos el pedido a cocina\"\n            waiting_time=$(($RANDOM % 10 + 1))\n            sleep $waiting_time\n            $callback \"$order\" #\"order_in_process order_delivered\"\n            return 0\n        fi\n    done\n\n    echo -e \"\\nLa pizza elegida no esta en la carta.\" \n    echo -e \"\\n[!] Saliendo del programa .....\\n\"\n    exit_program=true \n}\n\nfunction order_received() {\n\n    local order=$1\n    #local callback=$2\n\n    if ! $exit_program; then\n        echo -e \"\\nSu pedido de pizza $order ha llegado a cocina y esta en espera\"\n        waiting_time=$(($RANDOM % 10 + 1))\n        sleep $waiting_time\n        #$callback \"$order\" \"order_delivered\"\n        order_in_process \"$order\"\n    fi    \n} \n\nfunction order_in_process() {\n\n    local order=$1\n\n    echo -e \"\\nSu pizza $order esta siendo procesada\"\n    waiting_time=$(($RANDOM % 10 + 1))\n    sleep $waiting_time\n    order_delivered \"$order\"\n}\n\nfunction order_delivered() {\n\n    local order=$1\n\n    echo -e \"\\nSu pizza $order esta preparada para entregar\"\n    waiting_time=$(($RANDOM % 10 + 1))\n    sleep $waiting_time\n    echo -e \"\\nSu pizza $order ha sido entregada\"\n}\n\n\nplace_order \"$order\" \"order_received\"\n\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/c#/hequebo.cs",
    "content": "/*\n * 1.- Un delegado es una variable que almacena una\n * función y define la estructura de esta misma\n * El delegado Operation establece que la función\n * que le sea asignada debe de recibir dos parámetros\n * de tipo entero y devolver un número entero\n */\ndelegate int Operation(int x, int y);\n\ndelegate void OrderProcess(string dish);\nclass Program\n{\n    static void Main(string[] args)\n    {\n        /*\n         * 5.- Asignamos a una variable de tipo\n         * Operation la función Addition\n         */\n        Operation op = Addition;\n        /*\n         * 6.- Ejecutamos la función ShowResult con la función\n         * op como parámetro\n         */\n        ShowResult(3, 5, op);\n        /*\n         * El concepto de miltifusión permite \n         * almacenar más de una función en un delegado\n         * por lo que dentro de order se encuentran las\n         * tres funciones definidas\n         */\n        OrderProcess order = Confirm;\n        order += Ready;\n        order += Deliver;\n        ProcessOrder(\"Hamburgesa\", order);\n    }\n    /*\n     * 2.- La función Addition cumple con los\n     * requisitos establecidos por el delegado\n     * Operation\n     */\n    static int Addition(int x, int y) => x + y;\n    /*\n     * 3.- La función ShowResult tiene como parámetros\n     * dos números enteros y una función que sea del\n     * tipo Operation\n     */\n    static void ShowResult(int x, int y, Operation op)\n    {\n        /*\n         * 4.- Dentro de la función ShowResult se ejecuta\n         * la función que se envío como parámetro\n         */\n        Console.WriteLine($\"El resultado es: {op(x, y)}\");\n    }\n    static void Confirm(string dish)  \n    { \n        Console.WriteLine($\"La orden de {dish} ha sido confirmada\"); \n        int seconds = new Random().Next(1,10);\n        Console.WriteLine(seconds);\n        Thread.Sleep(seconds * 1000);\n    }\n    static void Ready(string dish) \n    {\n        Console.WriteLine($\"La orden de {dish} está lista\");\n        int seconds = new Random().Next(1, 10);\n        Console.WriteLine(seconds);\n        Thread.Sleep(seconds * 1000);\n    }\n    static void Deliver(string dish) => Console.WriteLine($\"La orden de {dish} ha sido entregada\");\n    static void ProcessOrder(string dish, OrderProcess order)\n    {\n        Console.WriteLine(\"Se recibió orden\");\n        order(dish);\n    }\n}\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/c#/jamerrq.cs",
    "content": "﻿/*\r\n * EJERCICIO:\r\n * Explora el concepto de callback en tu lenguaje creando un ejemplo\r\n * simple (a tu elección) que muestre su funcionamiento.\r\n *\r\n * DIFICULTAD EXTRA (opcional):\r\n * Crea un simulador de pedidos de un restaurante utilizando callbacks.\r\n * Estará formado por una función que procesa pedidos.\r\n * Debe aceptar el nombre del plato, una callback de confirmación, una\r\n * de listo y otra de entrega.\r\n * - Debe imprimir un confirmación cuando empiece el procesamiento.\r\n * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\r\n *   procesos.\r\n * - Debe invocar a cada callback siguiendo un orden de procesado.\r\n * - Debe notificar que el plato está listo o ha sido entregado.\r\n */\r\nusing System;\r\n\r\nnamespace Roadmap21\r\n{\r\n    class Callbacks\r\n    {\r\n        public delegate void Callback();\r\n\r\n        public void ProcessOrder(string dish, Callback confirm, Callback ready, Callback delivered)\r\n        {\r\n            Console.WriteLine($\"🥫 Processing order for {dish}...\");\r\n            confirm();\r\n            Random random = new Random();\r\n            int seconds = random.Next(1, 11);\r\n            System.Threading.Thread.Sleep(seconds * 1000);\r\n            ready();\r\n            System.Threading.Thread.Sleep(seconds * 1000);\r\n            delivered();\r\n        }\r\n\r\n        public void Confirm()\r\n        {\r\n            Console.WriteLine(\"Order confirmed 📝\");\r\n        }\r\n\r\n        public void Ready()\r\n        {\r\n            Console.WriteLine(\"Order ready 🍽\");\r\n        }\r\n\r\n        public void Delivered()\r\n        {\r\n            Console.WriteLine(\"Order delivered 📥\");\r\n        }\r\n\r\n        public void Run()\r\n        {\r\n            ProcessOrder(\"Pizza 🍕\", Confirm, Ready, Delivered);\r\n        }\r\n\r\n        static void Main(string[] args)\r\n        {\r\n            Callbacks callbacks = new Callbacks();\r\n            callbacks.Run();\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/c#/kenysdev.cs",
    "content": "/*\n╔══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado               ║\n║ GitHub: https://github.com/Kenysdev  ║\n║ 2024 -  C#                           ║\n╚══════════════════════════════════════╝\n------------------------------------------\n* CALLBACKS\n------------------------------------------\nhttps://beetechnical.com/tech-tutorial/callbacks-in-csharp/\n\n*/\n\n#pragma warning disable CA1050\nclass Program {\n/*\n* EJERCICIO #1:\n* Explora el concepto de callback en tu lenguaje creando un ejemplo\n* simple (a tu elección) que muestre su funcionamiento.\n*/\n    // (opcional) Forma de representar y referenciar métodos con una firma específica.\n    delegate void CallbackDelegate(string summands, int result);\n\n    static void SumNumbers(int a, int b, CallbackDelegate callback) {\n        int result = a + b;\n        callback($\"{a} + {b}\", result);\n    }\n\n    static void MyCallback(string summands, int result) {\n        Console.WriteLine($\"La suma de {summands} es: {result}\");\n    }\n\n/*\n* EJERCICIO #2:\n* Crea un simulador de pedidos de un restaurante utilizando callbacks.\n* Estará formado por una función que procesa pedidos.\n* Debe aceptar el nombre del plato, una callback de confirmación, una\n* de listo y otra de entrega.\n* - Debe imprimir un confirmación cuando empiece el procesamiento.\n* - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n*   procesos.\n* - Debe invocar a cada callback siguiendo un orden de procesado.\n* - Debe notificar que el plato está listo o ha sido entregado.\n*/\n\n    static async Task ProcessOrder(\n        string name, Func<string, Task> confirm, Func<string, Task> prepare, \n        Func<string, Task> serving) {\n        Console.WriteLine($\"-----\\n* Procesando: '{name}' \\n-----\\n\");\n        await confirm(name);\n        await prepare(name);\n        await serving(name);\n    }\n\n    static int TimeRandom() {\n        Random random = new();\n        return random.Next(1, 11);\n    }\n\n    static async Task ConfirmOrder(string name) {\n        int time = TimeRandom();\n        Console.WriteLine($\"* Confirmando {name}, espere {time} segundos.\");\n        await Task.Delay(time * 1000);\n        Console.WriteLine($\"- '{name}', ha sido confirmado.\\n\");\n    }\n\n    static async Task PrepareOrder(string name) {\n        int time = TimeRandom();\n        Console.WriteLine($\"* Preparando, espere {time} segundos.\");\n        await Task.Delay(time * 1000);\n        Console.WriteLine($\"- '{name}', esta Listo.\\n\");\n    }\n\n    static async Task ServingOrder(string name) {\n        int time = TimeRandom();\n        Console.WriteLine($\"* Sirviendo, espere {time} segundos.\");\n        await Task.Delay(time * 1000);\n        Console.WriteLine($\"- '{name}', ha sido entregado.\\n\");\n    }\n\n    static async Task Order(string dishName) {\n        await ProcessOrder(dishName, ConfirmOrder, PrepareOrder, ServingOrder);\n    }\n\n    static async Task Main() {\n        Console.WriteLine(\"EJERCICIO #1\");\n        SumNumbers(6, 6, MyCallback);\n        SumNumbers(5, 2, MyCallback);\n\n        Console.WriteLine(\"\\nEJERCICIO #2\");\n        await Order(\"Baleadas\");\n        await Order(\"Tamales\");\n        await Order(\"Enchiladas\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/c++/hectorio23.cpp",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\n#include <iostream>\n#include <thread>\n#include <future>\n#include <chrono>\n#include <random>\n#include <string>\n\n/*\n * EJERCICIO:\n * Explora el concepto de callback en tu lenguaje creando un ejemplo\n * simple (a tu elección) que muestre su funcionamiento.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n * Estará formado por una función que procesa pedidos.\n * Debe aceptar el nombre del plato, una callback de confirmación, una\n * de listo y otra de entrega.\n * - Debe imprimir un confirmación cuando empiece el procesamiento.\n * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n *   procesos.\n * - Debe invocar a cada callback siguiendo un orden de procesado.\n * - Debe notificar que el plato está listo o ha sido entregado.\n*/\n\nvoid print(std::string msg) { std::cout << msg << \"\\n\"; }\n\n// Funcion simple la cual recibe uana funcion y un mensaje\nvoid console_log(void (*callback)(std::string), std::string message) {\n    callback(message);\n}\n\n\n\n// Función que confirma el pedido\nbool confirmacion(const std::string& nombre_plato, bool check) {\n    std::cout << \"[Confirmacion] - ¿Usted desea confirmar el pedido llamado \\\"\" << nombre_plato << \"\\\"?: \" << (check ? \"Yes\" : \"No\") << std::endl;\n\n    return check;\n}\n\n// Función que simula que el pedido está listo\nvoid listo(const std::string& nombre_plato) {\n    // Simula un retraso aleatorio\n    std::random_device rd;\n    std::mt19937 gen(rd());\n    std::uniform_int_distribution<> dis(0, 10);\n    std::this_thread::sleep_for(std::chrono::seconds(dis(gen)));\n\n    std::cout << \"[Listo] - El pedido \\\"\" << nombre_plato << \"\\\" está listo para ser entregado\" << std::endl;\n}\n\n// Función que simula que el pedido ha sido entregado\nvoid entrega(const std::string& nombre_plato) {\n    // Simula un retraso aleatorio\n    std::random_device rd;\n    std::mt19937 gen(rd());\n    std::uniform_int_distribution<> dis(0, 10);\n    std::this_thread::sleep_for(std::chrono::seconds(dis(gen)));\n\n    std::cout << \"[Entrega] - El pedido \\\"\" << nombre_plato << \"\\\" ha sido entregado\" << std::endl;\n}\n\n// Función que procesa las órdenes\nvoid make_order(const std::string& nombre_plato, bool check) {\n    bool confirmado = confirmacion(nombre_plato, check);\n    if (!confirmado) {\n        std::cout << \"[Cancelled] - El pedido \\\"\" << nombre_plato << \"\\\" no se confirmó, por lo que se canceló el pedido\" << std::endl;\n        return;\n    }\n\n    std::async(std::launch::async, listo, nombre_plato).get();\n    std::async(std::launch::async, entrega, nombre_plato).get();\n}\n\n\nint main() {\n\n    /***************************** EJERCICIO DE LA SEMANA *****************************/\n    console_log(print, \"[+] - Callback; Hola Mundo desde C++!\");\n\n    std::cout << \"\\n********* EJERCICIO EXTRA **********\\n\";\n\n    /***************************** EJERCICIO EXTRA *****************************/\n\n    std::vector<std::future<void>> tasks;\n    tasks.push_back(std::async(std::launch::async, make_order, \"Papas a la francesa\", true));\n    tasks.push_back(std::async(std::launch::async, make_order, \"Carne de Cocodrilo a la parrilla\", false));\n    tasks.push_back(std::async(std::launch::async, make_order, \"Tacos de Pastor\", true));\n    tasks.push_back(std::async(std::launch::async, make_order, \"Ensalada de Papas con albondigas\", true));\n\n    for (auto& task : tasks) {\n        task.get();\n    }\n\n    return EXIT_SUCCESS;\n}"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/ejercicio.md",
    "content": "# #21 CALLBACKS\n> #### Dificultad: Media | Publicación: 20/04/24 | Corrección: 27/05/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Explora el concepto de callback en tu lenguaje creando un ejemplo\n * simple (a tu elección) que muestre su funcionamiento.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n * Estará formado por una función que procesa pedidos.\n * Debe aceptar el nombre del plato, una callback de confirmación, una\n * de listo y otra de entrega.\n * - Debe imprimir un confirmación cuando empiece el procesamiento.\n * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n *   procesos.\n * - Debe invocar a cada callback siguiendo un orden de procesado.\n * - Debe notificar que el plato está listo o ha sido entregado.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/21 - CALLBACKS/go/N0HagoNada.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"math/rand\"\n\t\"time\"\n)\n\n// Función que simula el procesamiento de un pedido\nfunc procesarPedido(nombrePlato string, confirmar, listo, entregar func()) {\n\n\tconfirmar()\n\tfmt.Printf(\"Procesando pedido: %s\\n\", nombrePlato)\n\n\ttiempo := rand.Intn(10) + 1\n\tfmt.Printf(\"Tiempo de procesamiento estimado: %d segundos\\n\", tiempo)\n\ttime.Sleep(time.Duration(tiempo) * time.Second)\n\n\tlisto()\n\tfmt.Printf(\"El plato %s está listo\\n\", nombrePlato)\n\n\ttiempo = rand.Intn(5) + 1\n\tfmt.Printf(\"Tiempo de entrega estimado: %d segundos\\n\", tiempo)\n\ttime.Sleep(time.Duration(tiempo) * time.Second)\n\n\tentregar()\n\tfmt.Printf(\"El plato %s ha sido entregado\\n\", nombrePlato)\n}\n\nfunc main() {\n\t// Callbacks para las diferentes etapas del procesamiento\n\tconfirmar := func() {\n\t\tfmt.Println(\"Confirmando pedido...\")\n\t}\n\n\tlisto := func() {\n\t\tfmt.Println(\"El plato está listo para ser entregado\")\n\t}\n\n\tentregar := func() {\n\t\tfmt.Println(\"El plato ha sido entregado al cliente\")\n\t}\n\n\tprocesarPedido(\"Ensalada César\", confirmar, listo, entregar)\n\tfmt.Println()\n\tprocesarPedido(\"Pasta Carbonara\", confirmar, listo, entregar)\n}\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/go/hozlucas28.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"math/rand\"\n\t\"sync\"\n\t\"time\"\n)\n\n/* -------------------------------------------------------------------------- */\n/*                                  FUNCTIONS                                 */\n/* -------------------------------------------------------------------------- */\n\nfunc MapArray[T int | string](array []T, callback func(currentValue T, indexOfCurrentValue int) T) {\n\tfor index, value := range array {\n\t\tarray[index] = callback(value, index)\n\t}\n}\n\nfunc prepareDish(dishName string, onConfirm func(dishName string), onReady func(dishName string), onDeliver func(dishName string)) {\n\tonConfirm(dishName)\n\n\tvar randomTimeout int = rand.Intn(10) + 1\n\n\tfor i := 0; i < randomTimeout; i++ {\n\t\ttime.Sleep(time.Second)\n\t}\n\tonReady(dishName)\n\n\tonDeliver(dishName)\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\nfunc main() {\n\t/*\n\t\tCallbacks...\n\t*/\n\n\tfmt.Println(\"Callbacks...\")\n\n\tvar numbers []int = []int{0, 2, 4, 6, 8, 10, 12, 14, 16, 18}\n\tfmt.Printf(\"\\nNumbers array before 'MapArray' function call: %d\\n\", numbers)\n\n\tMapArray(numbers, func(currentValue int, indexOfCurrentValue int) int {\n\t\treturn currentValue - 1\n\t})\n\tfmt.Printf(\"Numbers array after 'MapArray' function call: %d\\n\", numbers)\n\n\tvar people []string = []string{\"Juan\", \"Lucas\", \"Manuel\", \"Jose\"}\n\tfmt.Printf(\"\\nPeople array before 'MapArray' function call: %s\\n\", people)\n\n\tMapArray(people, func(currentValue string, indexOfCurrentValue int) string {\n\t\treturn fmt.Sprintf(\"Hi %s!\", currentValue)\n\t})\n\tfmt.Printf(\"People array after 'MapArray' function call: %s\\n\", people)\n\n\tfmt.Println(\"\\n# ---------------------------------------------------------------------------------- #\")\n\n\t/*\n\t\tAdditional challenge...\n\t*/\n\n\tfmt.Printf(\"\\nAdditional challenge...\\n\\n\")\n\n\tvar wg sync.WaitGroup\n\n\tonConfirm := func(dishName string) {\n\t\tfmt.Printf(\"%s in preparation.\\n\", dishName)\n\t}\n\n\tonReady := func(dishName string) {\n\t\tfmt.Printf(\"%s is ready to deliver.\\n\", dishName)\n\t}\n\n\tonDeliver := func(dishName string) {\n\t\tfmt.Printf(\"%s delivered.\\n\", dishName)\n\t\twg.Done()\n\t}\n\n\twg.Add(2)\n\tgo prepareDish(\"Spaghetti\", onConfirm, onReady, onDeliver)\n\tgo prepareDish(\"Soup\", onConfirm, onReady, onDeliver)\n\twg.Wait()\n}\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/go/kodenook.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc main() {\n\tnumbers := []int{1, 2, 3, 4, 5}\n\n\tprocess(numbers, printNumber)\n}\n\nfunc process(numbers []int, callback func(int)) {\n\tfor _, num := range numbers {\n\t\tcallback(num)\n\t}\n}\n\nfunc printNumber(num int) {\n\tfmt.Println(num)\n}\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/go/qwik-zgheib.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"math/rand\"\n\t\"time\"\n)\n\ntype Callback func(int) int\n\n// process is a function that takes an integer n and a Callback function as parameters.\n// It executes the Callback function with the provided integer n and prints the result.\n//\n// Parameters:\n// - n: An integer value that will be passed to the Callback function.\n// - callback: A Callback function that takes an integer as a parameter and returns an integer.\n//\n// Return values:\n// - None\nfunc process(n int, callback Callback) {\n\tresult := callback(n)\n\tfmt.Println(\"result: \", result)\n}\n\nfunc multiplyByTwo(n int) int {\n\treturn n * 2\n}\n\n// -- extra challenge\n\ntype ConfirmCallback func(orderID int, dish string)\ntype ReadyCallback func(orderID int, dish string)\ntype DeliverCallback func(orderID int, dish string)\n\ntype OrderProcessor struct{}\n\nfunc NewOrderProcessor() *OrderProcessor {\n\treturn &OrderProcessor{}\n}\n\nfunc (op *OrderProcessor) ProcessOrder(orderID int, dish string, confirm ConfirmCallback, ready ReadyCallback, deliver DeliverCallback) {\n\tconfirm(orderID, dish)\n\ttime.Sleep(time.Duration(rand.Intn(10)+1) * time.Second)\n\n\tready(orderID, dish)\n\ttime.Sleep(time.Duration(rand.Intn(10)+1) * time.Second)\n\n\tdeliver(orderID, dish)\n}\n\nfunc main() {\n\tnumber := 5\n\tprocess(number, multiplyByTwo)\n\tprocess(number, func(n int) int {\n\t\treturn n + 10\n\t})\n\n\t// -- extra challenge\n\trand.New(rand.NewSource(time.Now().UnixNano()))\n\n\t// Callbacks\n\tconfirm := func(orderID int, dish string) {\n\t\tfmt.Printf(\"Order #%d: Confirmed dish %s\\n\", orderID, dish)\n\t}\n\n\tready := func(orderID int, dish string) {\n\t\tfmt.Printf(\"Order #%d: Dish %s is ready\\n\", orderID, dish)\n\t}\n\n\tdeliver := func(orderID int, dish string) {\n\t\tfmt.Printf(\"Order #%d: Dish %s has been delivered\\n\", orderID, dish)\n\t}\n\n\torderProcessor := NewOrderProcessor()\n\n\torderProcessor.ProcessOrder(1, \"Pizza Margherita\", confirm, ready, deliver)\n\torderProcessor.ProcessOrder(2, \"Spaghetti Carbonara\", confirm, ready, deliver)\n}\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/go/raynerpv2022.go",
    "content": "/*\n#  * EJERCICIO:\n#  * Explora el concepto de callback en tu lenguaje creando un ejemplo\n#  * simple (a tu elección) que muestre su funcionamiento.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n#  * Estará formado por una función que procesa pedidos.\n#  * Debe aceptar el nombre del plato, una callback de confirmación, una\n#  * de listo y otra de entrega.\n#  * - Debe imprimir un confirmación cuando empiece el procesamiento.\n#  * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n#  *   procesos.\n#  * - Debe invocar a cada callback siguiendo un orden de procesado.\n#  * - Debe notificar que el plato está listo o ha sido entregado.\n#  */\n\npackage main\n\nimport (\n\t\"fmt\"\n\t\"math/rand\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n)\n\ntype OrdersType func(name string) string\n\ntype MyFunction func(interface{}) interface{}\n\nfunc Orders(name string, c, r, d OrdersType, w *sync.WaitGroup) {\n\tdefer w.Done()\n\n\twaitTime := rand.Intn(10) + 1\n\ttime.Sleep(time.Duration(waitTime) * time.Second)\n\tfmt.Printf(\"%v Wait time: %vs\\n\", c(name), waitTime)\n\n\twaitTime = rand.Intn(10) + 1\n\ttime.Sleep(time.Duration(waitTime) * time.Second)\n\tfmt.Printf(\"%v Wait time: %vs\\n\", r(name), waitTime)\n\n\twaitTime = rand.Intn(10) + 1\n\ttime.Sleep(time.Duration(waitTime) * time.Second)\n\tfmt.Printf(\"%v Wait time: %vs\\n\", d(name), waitTime)\n\n}\n\nfunc Confirm(name string) string {\n\n\treturn fmt.Sprintf(\" Plato %v confirmado\", name)\n}\n\nfunc Ready(name string) string {\n\n\treturn fmt.Sprintf(\" Plato %v listo\", name)\n}\n\nfunc Delivered(name string) string {\n\n\treturn fmt.Sprintf(\" Plato %v entregado\", name)\n}\n\nfunc GetSum(list1 interface{}) interface{} {\n\tsum := 0\n\tfor _, i := range list1.([]int) {\n\t\tsum += i\n\t}\n\treturn sum\n}\n\nfunc GetNameUpperCase(name interface{}) interface{} {\n\treturn strings.ToUpper(name.(string))\n}\n\nfunc Nothing(param interface{}, myF MyFunction) interface{} {\n\treturn myF(param)\n}\n\nfunc main() {\n\tfmt.Println(Nothing([]int{1, 2, 3, 4, 5, 6, 7, 8, 9}, GetSum))\n\tfmt.Println(Nothing(\"resbaloso\", GetNameUpperCase))\n\n\tfmt.Println(\"Extra\")\n\torders := []string{\n\t\t\"Calabaza\",\n\t\t\"Brocoli\",\n\t\t\"Cebollino\"}\n\tvar w sync.WaitGroup\n\tfmt.Println(\"Precesamiento de Pedidos\")\n\tfor _, i := range orders {\n\t\tw.Add(1)\n\t\tgo Orders(i, Confirm, Ready, Delivered, &w)\n\t}\n\tw.Wait()\n}\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/go/thegera4.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"time\"\n)\n\n// NOTA: Un callback es una función que se pasa como argumento a otra función.\n\n// Definimos un tipo para la funcion callback, en este caso recibe un entero y devuelve un entero\ntype Callback func(int) int\n\n// Definimos una funcion que aplique una operacion al numero que recibe y devuelve el resultado\nfunc applyCallback(num int, callback Callback) int {\n\treturn callback(num)\n}\n\nfunc main() {\n\t// Definimos una funcion que multiplica por 2 el numero.\n\tduplica := func(num int) int {\n\t\treturn num * 2\n\t}\n\n\t// Definimos otra funcion que suma el numero con 10\n\tsuma := func(num int) int {\n\t\treturn num + 10\n\t}\n\n\t// Aplicamos la funcion duplicar al numero 5\n\tfmt.Println(\"Resultado de multiplicar 5 por 2:\", applyCallback(5, duplica))\n\n\t// Aplicamos la funcion triplicar al numero 5\n\tfmt.Println(\"Resultado de sumar 15 con 10:\", applyCallback(15, suma))\n\n\t// Extra\n\tsimuladorPedidos()\n\n}\n\nfunc simuladorPedidos() {\n\n\t// Definimos las funciones de confirmacion, listo y entrega\n\tconfirmacion := func(num int) int {\n\t\tfmt.Println(\"Pedido confirmado\")\n\t\treturn num\n\t}\n\n\tlisto := func(num int) int {\n\t\tfmt.Println(\"Plato listo\")\n\t\treturn num\n\t}\n\n\tentrega := func(num int) int {\n\t\tfmt.Println(\"Pedido entregado\")\n\t\treturn num\n\t}\n\n\t// Simulamos un pedido de pizza\n\tprocesarPedido(\"Pizza\", confirmacion, listo, entrega)\n\n\t// Simulamos un pedido de hamburguesa\n\tprocesarPedido(\"Hamburguesa\", confirmacion, listo, entrega)\n}\n\nfunc procesarPedido(plato string, confirmacion, listo, entrega Callback) {\n\tfmt.Println(\"Procesando pedido de\", plato)\n\n\ttime.Sleep(time.Duration(1+time.Now().Nanosecond()%10) * time.Second) // Simulamos un tiempo aleatorio entre 1 y 10 segundos\n\tconfirmacion(1)\n\n\ttime.Sleep(time.Duration(1+time.Now().Nanosecond()%10) * time.Second)\n\tlisto(2)\n\n\ttime.Sleep(time.Duration(1+time.Now().Nanosecond()%10) * time.Second)\n\tentrega(3)\n}"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/java/AmadorQuispe.java",
    "content": "\nimport java.util.concurrent.TimeUnit;\nimport java.util.function.Consumer;\n\n@FunctionalInterface\ninterface Greeting {\n    void accept(String name);\n}\n\npublic class Roadmap {\n    public static void main(String[] args) throws InterruptedException {\n        //Callbacks con functional interface, en ese caso la función greetByName recibe una función y un nombre\n        Greeting greeting = (n) -> System.out.println(\"Hola bienvenido \" + n);\n        GreetingConsumer.greetByName(greeting, \"Amador\");\n\n        //EXTRA\n        String dishOrder = \"Tacos\";\n        Consumer<String> onConfirm = (n) -> System.out.println(\"Pedido de \" + n + \" confirmado\");\n        Consumer<String> onReady = (n) -> System.out.println(\"Pedido de \" + n + \" está listo\");\n        Consumer<String> onDelivery = (n) -> System.out.println(\"Pedido de \" + n + \" entregado\");\n\n        Restaurant.processOrder(dishOrder, onConfirm, onReady, onDelivery);\n\n\n    }\n}\n\nclass GreetingConsumer {\n    public static void greetByName(Greeting callback, String name) {\n        callback.accept(name);\n    }\n}\n\nclass Restaurant {\n    public static void processOrder(\n            String orderName,\n            Consumer<String> confirm,\n            Consumer<String> ready,\n            Consumer<String> delivery\n    ) throws InterruptedException {\n        int durationProcess;\n        System.out.println(\"Preparación del plato\");\n\n        durationProcess = (int) (Math.floor(Math.random() * (1 - 10 + 1) + 10));\n        System.out.println(\"Tiempo del proceso confirmación \" + durationProcess);\n        TimeUnit.SECONDS.sleep(durationProcess);\n        confirm.accept(orderName);\n\n        durationProcess = (int) (Math.floor(Math.random() * (1 - 10 + 1) + 10));\n        System.out.println(\"Tiempo del proceso listo \" + durationProcess);\n        TimeUnit.SECONDS.sleep(durationProcess);\n        ready.accept(orderName);\n\n        durationProcess = (int) (Math.floor(Math.random() * (1 - 10 + 1) + 10));\n        System.out.println(\"Tiempo del proceso entregado \" + durationProcess);\n        TimeUnit.SECONDS.sleep(durationProcess);\n        delivery.accept(orderName);\n    }\n}"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/java/AnaLauDB.java",
    "content": "import java.util.Random;\n\npublic class AnaLauDB {\n\n    // Interfaz para callback simple\n    interface Callback {\n        void ejecutar(String mensaje);\n    }\n\n    // Ejemplo simple de callback\n    public static void procesarDatos(String datos, Callback callback) {\n        System.out.println(\"Procesando datos: \" + datos);\n        // Simular procesamiento\n        try {\n            Thread.sleep(1000);\n        } catch (InterruptedException e) {\n            e.printStackTrace();\n        }\n        // Ejecutar callback\n        callback.ejecutar(\"Datos procesados correctamente\");\n    }\n\n    // DIFICULTAD EXTRA: Simulador de restaurante\n    interface CallbackConfirmacion {\n        void confirmar(String plato);\n    }\n\n    interface CallbackListo {\n        void listo(String plato);\n    }\n\n    interface CallbackEntrega {\n        void entregado(String plato);\n    }\n\n    public static void procesarPedido(String plato,\n            CallbackConfirmacion confirmacion,\n            CallbackListo listo,\n            CallbackEntrega entrega) {\n        Random random = new Random();\n\n        // 1. Confirmación\n        confirmacion.confirmar(plato);\n\n        try {\n            // Tiempo aleatorio entre 1-10 segundos para cocinar\n            int tiempoCocinar = random.nextInt(10) + 1;\n            Thread.sleep(tiempoCocinar * 1000);\n\n            // 2. Plato listo\n            listo.listo(plato);\n\n            // Tiempo aleatorio entre 1-10 segundos para entregar\n            int tiempoEntrega = random.nextInt(10) + 1;\n            Thread.sleep(tiempoEntrega * 1000);\n\n            // 3. Entrega\n            entrega.entregado(plato);\n\n        } catch (InterruptedException e) {\n            System.out.println(\"Error en el procesamiento del pedido\");\n        }\n    }\n\n    public static void main(String[] args) {\n        // Ejemplo simple de callback\n        System.out.println(\"=== Ejemplo simple de callback ===\");\n        procesarDatos(\"información importante\", mensaje -> {\n            System.out.println(\"Callback ejecutado: \" + mensaje);\n        });\n\n        System.out.println(\"\\n=== Simulador de restaurante ===\");\n\n        // Callbacks del restaurante\n        CallbackConfirmacion confirmacion = plato -> {\n            System.out.println(\" Pedido confirmado: \" + plato);\n            System.out.println(\" Comenzando preparación...\");\n        };\n\n        CallbackListo listo = plato -> {\n            System.out.println(\" Plato listo: \" + plato);\n            System.out.println(\" Preparando entrega...\");\n        };\n\n        CallbackEntrega entrega = plato -> {\n            System.out.println(\" Plato entregado: \" + plato);\n            System.out.println(\"¡Que disfrute su comida!\");\n        };\n\n        // Procesar varios pedidos\n        procesarPedido(\"Pizza Margherita\", confirmacion, listo, entrega);\n        System.out.println(\"---\");\n        procesarPedido(\"Hamburguesa con papas\", confirmacion, listo, entrega);\n    }\n}\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/java/FranDev200.java",
    "content": "import java.util.Random;\nimport java.util.Scanner;\n\npublic class FranDev200 {\n\n    interface Callback{\n        void mensajeFinal(String mensaje);\n    }\n\n    static class Temporizador implements Runnable{\n\n        public void cuentaAtras(Callback callback){\n\n            System.out.println(\"Inciando la cuenta atrás...\");\n\n            run();\n\n            String mensajeCallback = \"Tiempo finalizado\";\n\n            callback.mensajeFinal(mensajeCallback);\n\n        }\n\n        @Override\n        public void run() {\n\n            int contador = 3;\n\n            while (true) {\n\n                if(contador != 0){\n                    System.out.println(contador-- + \"...\");\n                }else{\n                    System.out.println(contador--);\n                }\n\n\n                if(contador < 0){\n                    break;\n                }\n\n                try {\n                    Thread.sleep(1000);\n                }catch (InterruptedException e){\n                    System.out.println(e.getMessage());\n                }\n\n            }\n\n\n        }\n    }\n\n    static void main() {\n\n        /*\n\n        EJERCICIO:\n         * Explora el concepto de callback en tu lenguaje creando un ejemplo\n         * simple (a tu elección) que muestre su funcionamiento.\n\n         */\n\n        Temporizador temporizador = new Temporizador();\n\n        temporizador.cuentaAtras(new Callback(){\n\n            public void mensajeFinal(String mensaje){\n\n                System.out.println(mensaje);\n\n                System.out.println(\"Cerrando el temporizador...\");\n\n            }\n\n        });\n\n        System.out.println(\"Mensaje, fuera del temporizador.\");\n        System.out.println(\"Terminando el programa.\");\n\n\n        /*\n\n        DIFICULTAD EXTRA (opcional):\n         * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n         * Estará formado por una función que procesa pedidos.\n         * Debe aceptar el nombre del plato, una callback de confirmación, una\n         * de listo y otra de entregaDomicilio.\n         * - Debe imprimir un confirmación cuando empiece el procesamiento.\n         * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n         *   procesos.\n         * - Debe invocar a cada callback siguiendo un orden de procesado.\n         * - Debe notificar que el plato está listo o ha sido entregado.\n\n         */\n\n        System.out.println(\"\\nEjercicio Extra\");\n\n        Scanner sc = new Scanner(System.in);\n        boolean entregaDomicilio = false;\n\n        Pedido pedido1 = new Pedido();\n        Pedido pedido2 = new Pedido();\n        Pedido pedido3 = new Pedido();\n        Pedido pedido4 = new Pedido();\n\n        entregaDomicilio = pedir(sc);\n        System.out.print(\"Que quiere para comer: \");\n        String comando = sc.nextLine();\n\n        pedido1.realizarPedido(comando, new Callback2() {\n            @Override\n            public void confirmacion(String plato) {\n                System.out.println(\"Su pedido ha sido recibido correctamente.\");\n                System.out.println(\" - Plato: \" + plato);\n            }\n\n            @Override\n            public void preparado(String plato) {\n                System.out.println(\"Ya ha sido preparado el plato.\");\n            }\n\n            @Override\n            public void entregado(String plato) {\n                System.out.println(plato + \" entregado/a\");\n            }\n        }, entregaDomicilio);\n\n        entregaDomicilio = pedir(sc);\n        System.out.print(\"Que quiere para comer: \");\n        comando = sc.nextLine();\n\n\n        pedido2.realizarPedido(comando, new Callback2() {\n            @Override\n            public void confirmacion(String plato) {\n                System.out.println(\"Su pedido ha sido recibido correctamente.\");\n                System.out.println(\" - Plato: \" + plato);\n            }\n\n            @Override\n            public void preparado(String plato) {\n                System.out.println(\"Ya ha sido preparado el plato.\");\n            }\n\n            @Override\n            public void entregado(String plato) {\n                System.out.println(plato + \" entregado/a\");\n            }\n        },  entregaDomicilio);\n\n        entregaDomicilio = pedir(sc);\n        System.out.print(\"Que quiere para comer: \");\n        comando = sc.nextLine();\n\n        pedido3.realizarPedido(comando, new Callback2() {\n            @Override\n            public void confirmacion(String plato) {\n                System.out.println(\"Su pedido ha sido recibido correctamente.\");\n                System.out.println(\" - Plato: \" + plato);\n            }\n\n            @Override\n            public void preparado(String plato) {\n                System.out.println(\"Ya ha sido preparado el plato.\");\n            }\n\n            @Override\n            public void entregado(String plato) {\n                System.out.println(plato + \" entregado/a\");\n            }\n        },  entregaDomicilio);\n\n        entregaDomicilio = pedir(sc);\n        System.out.print(\"Que quiere para comer: \");\n        comando = sc.nextLine();\n\n        pedido4.realizarPedido(comando, new Callback2() {\n            @Override\n            public void confirmacion(String plato) {\n                System.out.println(\"Su pedido ha sido recibido correctamente.\");\n                System.out.println(\" - Plato: \" + plato);\n            }\n\n            @Override\n            public void preparado(String plato) {\n                System.out.println(\"Ya ha sido preparado el plato.\");\n            }\n\n            @Override\n            public void entregado(String plato) {\n                System.out.println(plato + \" entregado/a\");\n            }\n        },  entregaDomicilio);\n\n    }\n\n    private static boolean pedir(Scanner sc) {\n\n        boolean retorno = false;\n\n        System.out.print(\"\\nModo de entregaDomicilio [Domicilio | Caja]\");\n        String respuesta = sc.nextLine();\n\n        if(respuesta.equals(\"Domicilio\")){\n            retorno = true;\n        }else if(respuesta.equals(\"Caja\")){\n            retorno = false;\n        }\n        return retorno;\n    }\n\n    static class  Pedido{\n\n        public void realizarPedido(String nombrePlato, Callback2 callback, boolean entregaDomicilio){\n\n            Random rand = new Random();\n\n            callback.confirmacion(nombrePlato);\n\n            System.out.println(\"Su plato esta preparandose.\");\n\n            int tiempoPreparar = rand.nextInt(10) + 1;\n\n            System.out.println(\"Tardará unos \" + tiempoPreparar + \" segundos.\");\n\n            try {\n                Thread.sleep(tiempoPreparar * 1000);\n            } catch (InterruptedException e) {\n                System.out.println(e.getMessage());\n            }\n\n            callback.preparado(nombrePlato);\n\n            if(entregaDomicilio){\n\n                int tiempoEntrega = rand.nextInt(10) + 1;\n\n                System.out.println(\"Su plato se entregará en \" +  tiempoEntrega + \" segundos.\");\n\n                try {\n                    Thread.sleep(tiempoEntrega * 1000);\n                } catch (InterruptedException e) {\n                    System.out.println(e.getMessage());\n                }\n\n\n\n            }\n\n            callback.entregado(nombrePlato);\n\n            System.out.println(\"Pedido finalizado con exito.\");\n        }\n\n    }\n\n    interface Callback2{\n        void confirmacion(String plato);\n        void preparado(String plato);\n        void entregado(String plato);\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/java/JimsimroDev.java",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de callback en tu lenguaje creando un ejemplo\n * simple (a tu elección) que muestre su funcionamiento.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n * Estará formado por una función que procesa pedidos.\n * Debe aceptar el nombre del plato, una callback de confirmación, una\n * de listo y otra de entrega.\n * - Debe imprimir un confirmación cuando empiece el procesamiento.\n * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n *   procesos.\n * - Debe invocar a cada callback siguiendo un orden de procesado.\n * - Debe notificar que el plato está listo o ha sido entregado.\n */\n\npublic class JimsimroDev {\n  private static final String DIV_LINE = \":::::::::::::::::::::::::\";\n  private static final int MIN = 1000;\n  private static final int MAX = 10000;\n\n  interface Noficar {\n    void notificacion(String mensaje);\n  }\n\n  interface Confirmado {\n    void confirmarPedidos(String mensaje);\n  }\n\n  interface Listo {\n    void pedidoListo(String mensaje);\n  }\n\n  interface Entregado {\n    void entregarPedidos(String mensaje);\n  }\n\n  static void notificacionEnviada(String proceso, Noficar callback) {\n    try {\n      System.out.println(\"Iniciando proceso...\");\n      Thread.sleep(5000);\n      callback.notificacion(\"Proceso completado: \" + proceso);\n    } catch (InterruptedException e) {\n      System.out.println(\"Erro timeout\" + e);\n    }\n\n  }\n\n  static int ramdon() {\n    return (int) (Math.random() * (MAX - MIN + 1)) + MIN;\n  }\n\n  static void procesarPedidos(String plato, Confirmado confirmado, Listo listo, Entregado entregado) {\n    Thread hacerPedido = new Thread(() -> {\n      try {\n\n        print(\"Iniciando pedido \" + plato +\"....\");\n        Thread.sleep(ramdon());\n        confirmado.confirmarPedidos(plato + \" Confirmado\");\n\n        print(\"Preparando pedido \" + plato + \"....\");\n        print(DIV_LINE);\n        Thread.sleep(ramdon());\n        listo.pedidoListo(plato + \" Listo\");\n\n        print(\"Entregando el plato \"+plato);\n        print(DIV_LINE);\n        Thread.sleep(ramdon());\n        entregado.entregarPedidos(plato + \" Entregado\");\n\n      } catch (InterruptedException e) {\n        print(\"Erro no pedido\" + e);\n      }\n    });\n    hacerPedido.start();\n  }\n\n  static void hacerOrden(String plato) {\n    procesarPedidos(\n        plato,\n        JimsimroDev::print,\n        JimsimroDev::print,\n        JimsimroDev::print);\n  }\n\n  static void print(Object... args) {\n    for (Object s : args) {\n      System.out.print(s + \" \");\n    }\n    System.out.println();\n  }\n\n  public static void main(String[] args) {\n    notificacionEnviada(\"Enviando SMS \", System.out::println);\n\n    // EXTRA\n    hacerOrden(\"Bandeja Paisa\");\n    hacerOrden(\"Lechona\");\n    hacerOrden(\"Mote De Queso\");\n  }\n}\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/java/Josegs95.java",
    "content": "import java.util.Random;\n\npublic class Josegs95 {\n    public static void main(String[] args) {\n        //Ejercicio\n        int n1 = 25;\n        int n2 = 67;\n        int result = sum(n1, n2, new Farewell() {\n            @Override\n            public void goodbye() {\n                System.out.println(\"Los números han sido sumados. Hasta otra!\");\n            }\n        });\n\n        System.out.println(n1 + \" + \" + n2 + \" = \" + result);\n\n        //Reto\n        retoFinal();\n    }\n\n    public static void retoFinal(){\n        ClientMessages clientMessages = new ClientMessages() {\n            @Override\n            public void confirmed(String orderName) {\n                System.out.println(\"Tu pedido '\" + orderName + \"' está confirmado.\");\n            }\n\n            @Override\n            public void ready(String orderName) {\n                System.out.println(\"Tu pedido '\" + orderName + \"' está listo para enviar.\");\n            }\n\n            @Override\n            public void delivered(String orderName) {\n                System.out.println(\"Tu pedido '\" + orderName + \"' ha sido enviado.\");\n            }\n        };\n        order(\"Hamburguesa doble\", clientMessages);\n        order(\"Ensalada de pasta\", clientMessages);\n    }\n\n    public static int sum(int n1, int n2, Farewell farewell){\n        int result = n1 + n2;\n\n        farewell.goodbye();\n\n        return result;\n    }\n\n    public static void order(String name, ClientMessages clientMessages){\n        Random rnd = new Random();\n        try{\n            clientMessages.confirmed(name);\n            Thread.sleep(rnd.nextInt(1, 11) * 1000);\n\n            clientMessages.ready(name);\n            Thread.sleep(rnd.nextInt(1, 11) * 1000);\n\n            clientMessages.delivered(name);\n        } catch (InterruptedException e) {\n            throw new RuntimeException(e);\n        }\n    }\n\n    public interface Farewell{\n        void goodbye();\n    }\n\n    public interface ClientMessages{\n        void confirmed(String orderName);\n        void ready(String orderName);\n        void delivered(String orderName);\n    }\n}\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/java/asjordi.java",
    "content": "import java.util.List;\nimport java.util.Random;\nimport java.util.concurrent.TimeUnit;\nimport java.util.function.Function;\n\n/**\n * Un callback en Java es un concepto que permite a una función llamar a otra función.\n * En Java los callbacks se implementan a través de interfaces.\n * Una interfaz de callback es una interfaz con un método que se invocará cuando se produzca un evento en particular.\n * Un objeto que implementa esta interfaz se registra con otro objeto, que llama al método de callback cuando ocurre el evento.\n */\n\npublic class Main {\n\n    public static void main(String[] args) {\n        System.out.println(saludar(\"Pedro\", s -> s.toUpperCase()));\n        procesarPedidos(\"Ceviche\", s -> \"Confirmado\", s-> \"Listo\", s -> \"Entregado\");\n\n    }\n\n    /**\n     * EJERCICIO:\n     * Explora el concepto de callback en tu lenguaje creando un ejemplo\n     * simple (a tu elección) que muestre su funcionamiento.\n     * @param nombre Nombre a saludar\n     * @param f Callback que transforma el nombre\n     * @return Retorna un saludo con el nombre transformado por el callback f\n     */\n    public static String saludar(String nombre, Function<String, String> f) {\n        return \"Hola \" + f.apply(nombre) + \"!\";\n    }\n\n    /**\n     * DIFICULTAD EXTRA (opcional):\n     * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n     * Estará formado por una función que procesa pedidos.\n     * Debe aceptar el nombre del plato, una callback de confirmación, una\n     * de listo y otra de entrega.\n     * - Debe imprimir un confirmación cuando empiece el procesamiento.\n     * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre procesos.\n     * - Debe invocar a cada callback siguiendo un orden de procesado.\n     * - Debe notificar que el plato está listo o ha sido entregado.\n     * @param nombre\n     * @param fConfirmado\n     * @param fListo\n     * @param fEntregado\n     */\n    public static void procesarPedidos(String nombre, Function<String, String> fConfirmado, Function<String, String> fListo, Function<String, String> fEntregado) {\n        Random r = new Random();\n        List<Function<String, String>> procesos = List.of(fConfirmado, fListo, fEntregado);\n        System.out.println(\"Procesando pedido...\");\n\n        procesos.forEach(p -> {\n            try {\n                int t = r.nextInt(1, 11);\n                System.out.println(\"El plato \" + nombre + \" se encuentra \" + p.apply(nombre) + \" en \" + t + \" segundos.\");\n                TimeUnit.SECONDS.sleep(t);\n            } catch (InterruptedException e) {\n                throw new RuntimeException(e);\n            }\n        });\n\n        System.out.println(\"Pedido procesado exitosamente!\");\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/java/danhingar.java",
    "content": "import java.util.Random;\nimport java.util.function.Consumer;\n\npublic class danhingar {\n\n    public static void main(String[] args) throws InterruptedException {\n        GreetConsumerProcess.greet_process(\"Daniel\", GreetConsumerProcess::greet_callback);\n        GreetInterfacesProcess.process(\"Pepe\", new CallbackImpl());\n\n        // Extra\n        Restaurant.createOrderWithThread(\"Pizza Barbacoa\");\n        Restaurant.createOrderWithThread(\"Pizza Carbonara\");\n        Restaurant.createOrderWithThread(\"Pizza 4 Quesos\");\n        Restaurant.createOrderWithThread(\"Pizza Margarita\");\n    }\n\n}\n\n// Usando Consumer\nclass GreetConsumerProcess {\n\n    public static void greet_process(String name, Consumer<String> callback) {\n        System.out.println(\"Ejecutando el proceso de saludo...\");\n        callback.accept(name);\n    }\n\n    public static void greet_callback(String name) {\n        System.out.printf(\"Hola, %s\", name + \"\\n\");\n    }\n}\n\n// Usando interfaz\ninterface Callback {\n    void greet(String name);\n}\n\nclass CallbackImpl implements Callback {\n\n    @Override\n    public void greet(String name) {\n        System.out.printf(\"Hola, %s\\n\", name);\n    }\n\n}\n\nclass GreetInterfacesProcess {\n\n    static void process(String name, Callback callback) {\n        System.out.println(\"Ejecutando el proceso de saludo...\");\n        callback.greet(name);\n    }\n\n}\n\n// EXTRA\n\nclass Restaurant {\n\n    public static void createOrderWithThread(String dishName) {\n        Thread thread = new Thread(() -> {\n            try {\n                orderProcess(dishName, Restaurant::confirmOrder, Restaurant::orderReady,\n                        Restaurant::orderDelivered);\n            } catch (InterruptedException e) {\n                e.printStackTrace();\n            }\n        });\n        thread.start();\n\n    }\n\n    public static void orderProcess(String dishName, Consumer<String> confirmCallback, Consumer<String> readyCallback,\n            Consumer<String> deliveredCallback) throws InterruptedException {\n        Random random = new Random();\n        confirmCallback.accept(dishName);\n        Thread.sleep(random.nextInt(1, 11) * 1000);\n        readyCallback.accept(dishName);\n        Thread.sleep(random.nextInt(1, 11) * 1000);\n        deliveredCallback.accept(dishName);\n    }\n\n    public static void confirmOrder(String dishName) {\n\n        System.out.printf(\"Tu pedido %s ha sido confirmado\\n\", dishName);\n    }\n\n    public static void orderReady(String dishName) {\n        System.out.printf(\"Tu pedido %s está listo\\n\", dishName);\n    }\n\n    public static void orderDelivered(String dishName) {\n        System.out.printf(\"Tu pedido %s ha sido entregado\\n\", dishName);\n    }\n}"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/java/eulogioep.java",
    "content": "/*\n * TEORÍA DE CALLBACKS:\n * \n * Un callback es una función que se pasa como argumento a otra función y se ejecuta\n * después de que ocurra un evento específico o se complete una tarea. En Java, los\n * callbacks se implementan típicamente usando interfaces funcionales o lambdas.\n * \n * Los callbacks son útiles para:\n * 1. Programación asíncrona\n * 2. Manejo de eventos\n * 3. Personalización de comportamiento\n * \n * En Java, podemos implementar callbacks de varias formas:\n * 1. Interfaces funcionales\n * 2. Expresiones lambda\n * 3. Referencias a métodos\n */\n\n import java.util.Random;\n import java.util.concurrent.TimeUnit;\n \n public class eulogioep {\n     \n     // Interfaces funcionales para los callbacks\n     @FunctionalInterface\n     interface SimpleCallback {\n         void execute();\n     }\n     \n     @FunctionalInterface\n     interface StringCallback {\n         void execute(String message);\n     }\n     \n     // Ejemplo simple de callback\n     public static void procesarTarea(String tarea, SimpleCallback onComplete) {\n         System.out.println(\"Iniciando tarea: \" + tarea);\n         // Simulamos algún procesamiento\n         try {\n             Thread.sleep(1000);\n         } catch (InterruptedException e) {\n             e.printStackTrace();\n         }\n         \n         // Ejecutamos el callback\n         onComplete.execute();\n     }\n     \n     // Simulador de pedidos de restaurante\n     public static class RestaurantePedidos {\n         private Random random = new Random();\n         \n         public void procesarPedido(\n             String plato,\n             StringCallback onConfirmacion,\n             StringCallback onListo,\n             StringCallback onEntrega\n         ) {\n             // Callback de confirmación\n             onConfirmacion.execute(\"Pedido confirmado: \" + plato);\n             \n             // Simular preparación\n             simularTiempo();\n             \n             // Callback de listo\n             onListo.execute(\"¡\" + plato + \" está listo!\");\n             \n             // Simular entrega\n             simularTiempo();\n             \n             // Callback de entrega\n             onEntrega.execute(plato + \" ha sido entregado. ¡Buen provecho!\");\n         }\n         \n         private void simularTiempo() {\n             try {\n                 int tiempoEspera = random.nextInt(10) + 1;\n                 System.out.println(\"Procesando... (\" + tiempoEspera + \" segundos)\");\n                 TimeUnit.SECONDS.sleep(tiempoEspera);\n             } catch (InterruptedException e) {\n                 e.printStackTrace();\n             }\n         }\n     }\n     \n     public static void main(String[] args) {\n         // Ejemplo simple de callback\n         System.out.println(\"=== Ejemplo Simple de Callback ===\");\n         procesarTarea(\"Tarea de prueba\", () -> \n             System.out.println(\"¡Tarea completada!\")\n         );\n         \n         System.out.println(\"\\n=== Simulador de Restaurante ===\");\n         RestaurantePedidos restaurante = new RestaurantePedidos();\n         \n         // Procesamos un pedido usando el simulador\n         restaurante.procesarPedido(\n             \"Paella Valenciana\",\n             mensaje -> System.out.println(\"CONFIRMACIÓN: \" + mensaje),\n             mensaje -> System.out.println(\"LISTO: \" + mensaje),\n             mensaje -> System.out.println(\"ENTREGA: \" + mensaje)\n         );\n     }\n }"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/java/martinbohorquez.java",
    "content": "import java.util.Random;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.TimeUnit;\n\npublic class martinbohorquez {\n    public static void main(String[] args) {\n        callbackExample();\n        orderProcess(\"Pizza Carbonara\");\n        orderProcess(\"Pizza Margarita\");\n        orderProcess(\"Pizza Pepperoni\");\n        orderProcess(\"Pizza Barbacoa\");\n    }\n\n    private static void orderProcess(String dishName) {\n        orderProcess(dishName, martinbohorquez::confirmOrder, martinbohorquez::orderReady, martinbohorquez::orderDelivered);\n    }\n\n    private static void callbackExample() {\n        System.out.println(\"Iniciando el programa...\");\n        Processor processor = new Processor();\n        processor.process(message -> System.out.println(\"Callback recibido: \" + message));\n        System.out.println(\"Programa finalizado.\");\n    }\n\n    public static void orderProcess(String dishName, ConfirmCallback confirmCallback,\n                                    ReadyCallback readyCallback, DeliveredCallback deliveredCallback) {\n        ExecutorService executor = Executors.newSingleThreadExecutor();\n        executor.submit(() -> {\n            Random random = new Random();\n            try {\n                confirmCallback.execute(dishName);\n                TimeUnit.SECONDS.sleep(random.nextInt(1, 10));\n                readyCallback.execute(dishName);\n                TimeUnit.SECONDS.sleep(random.nextInt(1, 10));\n                deliveredCallback.execute(dishName);\n            } catch (InterruptedException e) {\n                throw new RuntimeException(e);\n            }\n        });\n        executor.shutdown();\n    }\n\n    private static void confirmOrder(String dishName) {\n        System.out.printf(\"Tu pedido %s ha sido confirmado!%n\", dishName);\n    }\n\n    private static void orderReady(String dishName) {\n        System.out.printf(\"Tu pedido %s está listo!%n\", dishName);\n    }\n\n    private static void orderDelivered(String dishName) {\n        System.out.printf(\"Tu pedido %s ha sido entregado!%n\", dishName);\n    }\n\n    private interface Callback {\n        void execute(String message);\n    }\n\n    // Interfaces para los callbacks\n    public interface ConfirmCallback {\n        void execute(String dishName);\n    }\n\n    public interface ReadyCallback {\n        void execute(String dishName);\n    }\n\n    public interface DeliveredCallback {\n        void execute(String dishName);\n    }\n\n    private static class Processor {\n        public void process(Callback callback) {\n            System.out.println(\"Procesando...\");\n            try {\n                Thread.sleep(4000);\n            } catch (InterruptedException e) {\n                e.printStackTrace();\n            }\n            callback.execute(\"Proceso completo\");\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/java/simonguzman.java",
    "content": "import java.util.Random;\nimport java.util.concurrent.TimeUnit;\n\npublic class simonguzman {\n    public static void main(String[] args) {\n        //callbackExample();\n        restaurantExercise();\n    }\n\n    /********************** Ejercicio adicional **********************/\n\n    public static void restaurantExercise(){\n        RestaurantOrder order = new RestaurantOrder();\n        \n        // Procesar pedido con callbacks\n        order.processOrder(\"Pizza\", \n            (dish) -> System.out.println(\"Confirmación: Se ha confirmado el pedido de \" + dish),\n            (dish) -> System.out.println(\"Listo: El plato \" + dish + \" está listo para ser servido\"),\n            (dish) -> System.out.println(\"Entregado: El plato \" + dish + \" ha sido entregado\")\n        ); \n    }\n    public static interface ConfirmCallback{\n        void OnConfirm(String dish);\n    }\n\n    public static interface ReadyCallback{\n        void OnReady(String dish);\n    }\n\n    public static interface DeliveryCallback{\n        void OnDelivery(String dish);\n    }\n\n    public static class RestaurantOrder{\n        private Random random = new Random();\n        public void processOrder(String dish, ConfirmCallback confirmcallback, ReadyCallback readyCallback, DeliveryCallback deliveryCallback){\n            confirmcallback.OnConfirm(dish);\n            proccessRestaurant(dish, confirmcallback, readyCallback, deliveryCallback);\n        }\n\n        public void proccessRestaurant(String dish, ConfirmCallback confirmcallback, ReadyCallback readyCallback, DeliveryCallback deliveryCallback){\n            \n            try {\n                int preparationTime = random.nextInt(10) + 1;\n                TimeUnit.SECONDS.sleep(preparationTime);\n\n                readyCallback.OnReady(dish);\n\n                int deliveryTime = random.nextInt(10) + 1;\n                TimeUnit.SECONDS.sleep(deliveryTime);\n\n                deliveryCallback.OnDelivery(dish);\n            } catch (InterruptedException e) {\n                e.printStackTrace();\n            }\n        }\n    }\n\n    /********************** Ejercicio principal - Ejemplo de Callback **********************/\n    public static void callbackExample(){\n        System.out.println(\"Iniciando el programa...\");\n        Processor processor = new Processor();\n        processor.process(message -> System.out.println(\"Callback recibido: \" + message));\n        System.out.println(\"Programa finalizado.\");\n    }\n\n    public static interface Callback{\n        void execute(String message);\n    }\n\n    public static class Processor{\n        public void process(Callback callback){\n            System.out.println(\"Procesando...\");\n            try {\n                Thread.sleep(2000);\n            } catch (InterruptedException e) {\n                e.printStackTrace();\n            }\n            callback.execute(\"Proceso completo\");\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/javascript/7R0N1X.js",
    "content": "const procesarNombres = (nombres, callback) => {\n  nombres.forEach(nombre => {\n    console.log(nombre.toUpperCase())\n  });\n  callback()\n}\n\nconst mostrarMensajeFinal = () => {\n  console.log('Procesamiento terminado.')\n}\n\nconst nombres = ['7r0n1x', 'eduardo', 'ana', 'pedro']\nprocesarNombres(nombres, mostrarMensajeFinal)\n\n// DIFICULTAD EXTRA\n\nconst procesarPedidos = (nombreDelPlato, cbConfirmacion, cbListo, cbEntrega) => {\n  setTimeout(() => {\n    cbConfirmacion(nombreDelPlato)\n    setTimeout(() => {\n      cbListo(nombreDelPlato)\n      setTimeout(() => {\n        cbEntrega(nombreDelPlato)\n      }, Math.floor((Math.random() * (10 - 1 + 1)) + 1) * 1000)\n    }, Math.floor((Math.random() * (10 - 1 + 1)) + 1) * 1000)\n  }, Math.floor((Math.random() * (10 - 1 + 1)) + 1) * 1000)\n}\n\nconst confirmacion = (nombreDelPlato) => {\n  console.log(`El pedido de ${nombreDelPlato} a sido confirmado.`)\n}\n\nconst listo = (nombreDelPlato) => {\n  console.log(`El pedido de ${nombreDelPlato} está listo.`)\n}\n\nconst entraga = (nombreDelPlato) => {\n  console.log(`El pedido de ${nombreDelPlato} a sido entregado.`)\n}\n\nprocesarPedidos('Ceviche', confirmacion, listo, entraga)"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/javascript/AChapeton.js",
    "content": "// Confirmar pedido\nconst confirmarPedido = (name) => {\n  console.log(\"Confirmando pedido de \".concat(name));\n};\n// Pedido listo\nconst confirmarPedidoListo = () => {\n  console.log('Pedido listo!!!');\n};\n// Pedido entregado\nconst confirmarPedidoEntregado = (name) => {\n  console.log(\"Pedido entregado! Gracias por confiar en nosotros \".concat(name));\n};\nconst crearPedido = (pedido, confirmarPedido, confirmarPedidoListo, confirmarPedidoEntregado) => {\n  setTimeout(() => {\n      confirmarPedido(pedido.name);\n      setTimeout(() => {\n          confirmarPedidoListo();\n          setTimeout(() => {\n              confirmarPedidoEntregado(pedido.name);\n          }, 3000);\n      }, 3000);\n  }, 2000);\n};\n\ncrearPedido(\n  {\n      id: '1',\n      name: 'Andres',\n      item: ['8oz steak', 'Lemonade', 'Cheescake'],\n      createdDate: new Date(),\n      note: 'I am hungry'\n  }, \n  confirmarPedido, \n  confirmarPedidoListo, \nconfirmarPedidoEntregado\n);\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/javascript/Chrisdev00.js",
    "content": "/*\n* EJERCICIO:\n* Explora el concepto de callback en tu lenguaje creando un ejemplo\n* simple (a tu elección) que muestre su funcionamiento.\n*\n* DIFICULTAD EXTRA (opcional):\n* Crea un simulador de pedidos de un restaurante utilizando callbacks.\n Estará formado por una función que procesa pedidos.\n* Debe aceptar el nombre del plato, una callback de confirmación, una\n* de listo y otra de entrega.\n* - Debe imprimir un confirmación cuando empiece el procesamiento.\n* - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n*   procesos.\n* - Debe invocar a cada callback siguiendo un orden de procesado.\n* - Debe notificar que el plato está listo o ha sido entregado.\n*/\n\nfunction sleep(ms){\n    return new Promise(resolve => setTimeout(resolve, ms));\n}\n  \nasync function main(){\n    await task_callback(tarea(), callback)\n}\n  \nasync function task_callback(tarea, callback){\n    await tarea,\n    callback()\n}\n  \nasync function tarea(){\n    console.log(\"Sumando numeros..\")\n    await sleep(2 * 1000)\n    console.log(\"Tarea Finalizada\")\n}\n  \nfunction callback(){\n    console.log(\"Funcion invocada luego de terminar task\")\n}\n  \nmain()\n\n\n////////////////////// ------------------------ EXTRA -------------------------------- ////////////////////////////\n\nconst menu = [\"Hamburguesa\", \"Pizza\", \"Tacos\", \"Ensalada Cesar\", \"Pollo Frito\"]\n\nfunction sleep(ms){\n  return new Promise(resolve => setTimeout(resolve, ms));\n}\n\nasync function order_process(plato, confirmarCallback, readyCallback, deliveryCallback){\n  \n  confirmarCallback(plato)\n  \n  const preparation_time = Math.floor(Math.random() * 10) + 1;\n  console.log(`Preparando ${plato}...(espera ${preparation_time} segundos)`);\n  await sleep(preparation_time * 1000);\n  \n  readyCallback(plato);\n  \n  const delivery_time = Math.floor(Math.random() * 10) + 1;\n  console.log(`Entregando ${plato}...(espera ${delivery_time} segundos)`);\n  await sleep(delivery_time * 1000);\n  \n  deliveryCallback(plato);\n}\n\nfunction confirmarPedido(plato){\n  console.log(`Pedido confirmado: ${plato}`);\n}\n\nfunction pedidoListo(plato){\n  console.log(`Pedido listo: ${plato}`);\n}\n\nfunction entregarPedido(plato){\n  console.log(`Pedido entregado: ${plato}`);\n}\n\nfunction mostrarMenu_y_pedido(){\n  console.log(\"Menu de platos disponible\");\n  menu.forEach((plato, id) =>{\n    console.log(`${id + 1}. ${plato}`);\n  });\n  \n  return new Promise((resolve) => {\n    const readline = require('readline').createInterface({\n      input: process.stdin,\n      output: process.stdout\n    });\n    \n    readline.question(\"\\nIngrese el numero de plato que desea pedir: \", (numero) => {\n      const election = parseInt(numero);\n      if (election >= 1 && election <= menu.length) {\n        readline.close();\n        resolve(menu[election - 1]);\n      }else{\n        console.log(\"Numero invalido porfavor intente nuevamente.\");\n        readline.close();\n        resolve(mostrarMenu_y_pedido());\n      }\n    });\n  });\n  \n}\n\nasync function realizarPedidos(){\n  console.log(\"Simulador de pedidos de un restaurante\\n\");\n  \n  const platoElegido = await mostrarMenu_y_pedido();\n  \n  await order_process(platoElegido, confirmarPedido, pedidoListo, entregarPedido);\n}\n\nrealizarPedidos();\n\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/javascript/DavidMoralesDeveloper.js",
    "content": "// Una función de callback es una función que se pasa a otra función como un argumento, que luego se invoca dentro de la función externa para completar algún tipo de rutina o acción.\n\n// function saludar (nombre) {\n//     console.log('hola ' + nombre)\n// }\n\n// function antesDecallback (funcionCallback) {\n// const name = 'david'\n// funcionCallback(name)\n// }\n\n// antesDecallback(saludar)\n\n// DIFICULTAD EXTRA (opcional):\n//  * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n//  * Estará formado por una función que procesa pedidos.\n//  * Debe aceptar el nombre del plato, una callback de confirmación, una\n//  * de listo y otra de entrega.\n//  * - Debe imprimir un confirmación cuando empiece el procesamiento.\n//  * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n//  *   procesos.\n//  * - Debe invocar a cada callback siguiendo un orden de procesado.\n//  * - Debe notificar que el plato está listo o ha sido entregado.\n\n\n\nfunction  pedidos (platillo, confirmado, listo, entregado ) {\n  \n    confirmado(platillo)\n    const numberRandom = () => {\n        return Math.floor(Math.random() * 10) * 1000\n    }\n    setTimeout(() => {\n        listo(platillo)\n        \n    }, numberRandom());\n    setTimeout(() => {\n        entregado(platillo)\n    }, numberRandom());\n}\n\nfunction confirmado (platillo ) {\n\n\n    console.log('platillo confirmado : ' + platillo) //son callbacks\n    \n}\nfunction listo (platillo ) {\n\n\n    console.log('platillo listo : ' + platillo)\n    //son callbacks\n    \n}\nfunction entregado (platillo ) {\n\n\n    console.log('platillo entregado : ' + platillo)//son callbacks\n    \n}\n\npedidos('caldo de pollo',confirmado, listo , entregado)\npedidos('filete de res',confirmado, listo , entregado)\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/javascript/Deyvid-10.js",
    "content": "// callbacks\n\nfunction tomarDatos(nombre, apellido, edad)\n{\n    console.log(\"Nombre: \" + nombre);\n    console.log(\"Apellido: \" + apellido);\n    console.log(\"Edad: \" + edad);\n}\n\nfunction esperarDatos(callback)\n{\n    callback(\"Deyvid\", \"Marmolejo\", 25)\n}\n\nesperarDatos(tomarDatos)\n\n\n// DIFICULTAD EXTRA\n\nasync function procesarPedido(plato, callbackConfirmacion, callbackListo, callbackEntrega)\n{\n    await callbackConfirmacion(plato)\n    await callbackListo(plato)\n    await callbackEntrega(plato)\n}\n\nfunction confirmacion(plato)\n{\n    return new Promise (resolver => setTimeout(()=>{\n    console.log(`El pedido del plato ${plato} esta en prepraracion`)\n    resolver()\n    } , Math.ceil(Math.random() * 10000)))\n}\n\nfunction listo(plato)\n{\n    return new Promise (resolver => setTimeout(()=>{\n    console.log(`El plato ${plato} esta listo para entregar`)\n    resolver()\n    } , Math.ceil(Math.random() * 10000)))\n}\n\nfunction entregado(plato)\n{\n    return new Promise (resolver => setTimeout(()=>{\n    console.log(`El plato ${plato} fue entregado`)\n    resolver()\n    } , Math.ceil(Math.random() * 10000)))\n}\n\nprocesarPedido(\"Sopa\", confirmacion, listo, entregado)\n\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #21 - JavaScript ->Jesus Antonio Escamilla */\n\n/**\n * Una función de callback es una función que se pasa a otra función como un argumento, que luego \n    se invoca dentro de la función externa para completar algún tipo de rutina o acción.\n * Es aquella que es pasada como argumento a otra función para que sea \"llamada de nuevo\" (call back)\n    en un momento posterior. \n*/\n\n//---EJERCIÓ---\n// Aquí podemos ver un ejemplo con tiempo\n// Hacemos una función que retorne en consola\nfunction saludar(data) {\n    console.log(data);\n}\n\n// Creamos el CALLBACK que retornara un texto para imprimirlo en consola\nfunction fetchData(name ,callback) {\n    setTimeout(() => {\n        const responder = `Hola soy, ${name}`;\n        callback(responder);    //Aquí vemos como retorna la función CallBack\n    }, 2000);\n}\n\n// Aquí solo llamamos el CALLBACK\nfetchData('Jesus Antonio', saludar);\n\n\n// También podemos crear primero el Callback con una suma de números\nfunction sum(a, b, callback) {\n    const resultado = a + b;\n    callback(resultado);    //Aquí vemos como retorna la función CallBack\n}\n\n// Después el torno del Callback a la consola\nfunction printSum(resultado) {\n    console.log('El resultado es:', resultado)\n}\n\n// Aquí solo llamamos el CALLBACK\nsum(3,6,printSum);\n\n\n\n/**-----DIFICULTAD EXTRA-----*/\n\n//  Una función que represente los tiempo aleatorio\nfunction getRandomTime() {\n    return Math.floor(Math.random() * 10000) + 1000;\n}\n\n//  La función del Callback donde tiene los 3 segmentos de \nfunction processOrder(namePlatillo, confirmCallback, readyCallback, deliveryCallback) {\n    console.log(`Procesando la orden: ${namePlatillo}\\n`);\n\n    // Confirmación del pedido\n    setTimeout(() => {\n        console.log('Preparando orden');\n        confirmCallback(namePlatillo);\n\n        // Simula el tiempo de preparación del plato\n        setTimeout(() => {\n            console.log('Preparando orden para enviar');\n            readyCallback(namePlatillo);\n\n            // Simula el tiempo de entrega del plato\n            setTimeout(() => {\n                console.log('Preparando orden para entregar');\n                deliveryCallback(namePlatillo);\n\n            }, getRandomTime());\n        }, getRandomTime());\n    }, getRandomTime());\n}\n\n//  Callback de confirmación\nfunction orderConfirmed(namePlatillo) {\n    console.log(`Orden confirmado del pedido: ${namePlatillo}\\n`);\n}\n\n//  Callback de plato listo\nfunction orderReady(namePlatillo) {\n    console.log(`Orden listo de: ${namePlatillo}\\n`);\n}\n\n//  Callback de entrega\nfunction orderDelivered(namePlatillo) {\n    console.log(`Orden entregado: ${namePlatillo}\\n`);\n}\n\n//  Ejemplo de uso de pedidos de restaurante\nprocessOrder('Pizza la Italiana', orderConfirmed, orderReady, orderDelivered);\nprocessOrder('Patas boloñesa', orderConfirmed, orderReady, orderDelivered);\nprocessOrder('Albóndigas con arroz', orderConfirmed, orderReady, orderDelivered);\n\n/**-----DIFICULTAD EXTRA-----*/"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/javascript/RaulDoezon.js",
    "content": "/*\n  EJERCICIO:\n  Explora el concepto de callback en tu lenguaje creando un ejemplo\n  simple (a tu elección) que muestre su funcionamiento.\n*/\n\nfunction phrase(message, callback) {\n  const fullMessage = \"¡Me gusta \" + message;\n\n  callback(fullMessage);\n}\n\nfunction complement(complementaryMessage) {\n  console.log(complementaryMessage);\n}\n\nphrase(\"la leche, la carne y el pan!\", complement);\n\n/*\n  DIFICULTAD EXTRA (opcional):\n  Crea un simulador de pedidos de un restaurante utilizando callbacks.\n  Estará formado por una función que procesa pedidos.\n  Debe aceptar el nombre del plato, una callback de confirmación, una\n  de listo y otra de entrega.\n  - Debe imprimir un confirmación cuando empiece el procesamiento.\n  - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n    procesos.\n  - Debe invocar a cada callback siguiendo un orden de procesado.\n  - Debe notificar que el plato está listo o ha sido entregado.\n*/\n\nfunction confirmation(receive, confirmationCallback) {\n  setTimeout(() => {\n    console.log(receive);\n\n    confirmationCallback();\n  }, Math.random() * 1000);\n}\n\nfunction ready(process, readyCallback) {\n  setTimeout(() => {\n    console.log(process);\n\n    readyCallback();\n  }, Math.random() * 1000);\n}\n\nfunction delivery(finish) {\n  setTimeout(() => {\n    console.log(finish);\n  }, Math.random() * 1000);\n}\n\nfunction orders(saucer, confirmation, ready, delivery) {\n  const confirmationMessage = `1. Recibimos la orden para preparar \"${saucer}\".`;\n  const readyMessage = `2. Ya estamos preparando \"${saucer}\". En unos momentos estará listo su platillo.`;\n  const deliveryMessage = `3. Hemos entregado su \"${saucer}\". ¡Buen provecho!`;\n\n  confirmation(confirmationMessage, () => {\n    ready(readyMessage, () => {\n      delivery(deliveryMessage);\n    });\n  });\n}\n\norders(\"Quesadilla de chicharrón prensado\", confirmation, ready, delivery);\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/javascript/RicJDev.js",
    "content": "//EJERCICIO\nfunction callbackFunction1(callback) {\n\tcallback();\n\tconsole.log('\\nSe ejecuta la primera función');\n}\n\ncallbackFunction1(() => {\n\tconsole.log('\\nSe ejecuta la primera callback');\n});\n\nfunction callbackFunction2(callback) {\n\tconsole.log('\\nSe ejecuta la segunda función');\n\tcallback();\n}\n\ncallbackFunction2(() => {\n\tconsole.log('\\nSe ejecuta la segunda callback');\n});\n\n//EXTRA\nfunction setRandomTime(callback) {\n\tlet randomNum = Math.floor(Math.random() * 11);\n\n\treturn new Promise((resolve) => {\n\t\tsetTimeout(() => {\n\t\t\tcallback();\n\t\t\tconsole.log(`Ejecutado en ${randomNum} segundo(s)`);\n\t\t\tresolve();\n\t\t}, randomNum * 1000);\n\t});\n}\n\nasync function orderDish(order, confirm, getReady, deliver) {\n\tconsole.log(`\\nProcesando pedido ${order}`);\n\n\tawait setRandomTime(() => {\n\t\tconfirm(order);\n\t});\n\n\tawait setRandomTime(() => {\n\t\tgetReady(order);\n\t});\n\n\tawait setRandomTime(() => {\n\t\tdeliver(order);\n\t});\n}\n\nlet myOrder = 'pizza con piña';\n\norderDish(\n\tmyOrder,\n\t(order) => {\n\t\tconsole.log(`\\nConfirma el pedido: ${order}`);\n\t},\n\t(order) => {\n\t\tconsole.log(`\\nEl pedido ${order} está listo!`);\n\t},\n\t(order) => {\n\t\tconsole.log(`\\nEl pedido ${order} ha sido entregado!`);\n\t}\n);\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/javascript/Sac-Corts.js",
    "content": "function greet(name, callback) {\n    console.log('Hi' + ' ' + name);\n    callback();\n}\n\nfunction callMe() {\n    console.log('I am callback function');\n}\n\ngreet('Isaac', callMe);\n\n// Extra Exercise //\nfunction processOrder(dish, confirmation, ready, delivery) {\n    setTimeout(() => {\n        console.log(`Order confirmed: ${dish}`);\n        confirmation(dish);\n        \n        setTimeout(() => {\n            console.log(`The dish ${dish} is ready.`);\n            ready(dish);\n\n            setTimeout(() => {\n                console.log(`The dish ${dish} has been delivered.`);\n                delivery(dish);\n            }, Math.random() * 9000 + 1000);\n        }, Math.random() * 9000 + 1000);\n    }, Math.random() * 9000 + 1000);\n}\n\nfunction confirmDish(dish) {\n    console.log(`Processing order: ${dish}`);\n}\n\nfunction readyDish(dish) {\n    console.log(`Preparing the dish: ${dish}`);\n}\n\nfunction deliverDish(dish) {\n    console.log(`Delivering the dish: ${dish}`);\n}\n\nprocessOrder('Pizza', confirmDish, readyDish, deliverDish);"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/javascript/adrs1166ma.js",
    "content": "/* 🔥 EJERCICIO:\nExplora el concepto de callback en tu lenguaje creando un ejemplo\nsimple (a tu elección) que muestre su funcionamiento.\n*/\n\nfunction saludar(nombre, callback) {\n    console.log(`Procesando saludo para ${nombre}...`)\n    setTimeout(() => {\n        const mensaje = `¡Hola, ${nombre}!`\n        callback(mensaje) // Invocamos el callback con el resultado\n    }, 2000)\n  }\n  \n  // Callback que maneja el resultado\n  function mostrarMensaje(mensaje) {\n    console.log(mensaje);\n  }\n  \n  saludar(\"Anderson\", mostrarMensaje);\n  // Procesando saludo para Anderson...\n  // ¡Hola, Anderson!\n  \n  \n  \n  /* 🔥 DIFICULTAD EXTRA (opcional): ----------------------------------------------------------------\n  Crea un simulador de pedidos de un restaurante utilizando callbacks.\n  Estará formado por una función que procesa pedidos.\n  Debe aceptar el nombre del plato, una callback de confirmación, una\n  de listo y otra de entrega.\n  - Debe imprimir un confirmación cuando empiece el procesamiento.\n  - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n    procesos.\n  - Debe invocar a cada callback siguiendo un orden de procesado.\n  - Debe notificar que el plato está listo o ha sido entregado.\n   */\n  \n  // Principal que procesa pedidos\n  function procesarPedido(plato, confirmacionCallback, listoCallback, entregaCallback) {\n    console.log(`Iniciando procesamiento del pedido: ${plato}`)\n  \n    // Paso 1: Confirmación del pedido\n    confirmacionCallback(plato)\n  \n    // Paso 2: Simular tiempo para preparar el plato\n    const tiempoPreparacion = Math.floor(Math.random() * 10 + 1) * 1000 // Entre 1 y 10 segundos\n    setTimeout(() => {\n        console.log(`Plato \"${plato}\" está siendo preparado...`)\n        listoCallback(plato) // Notificar que el plato está listo\n  \n        // Paso 3: Simular tiempo para entregar el plato\n        const tiempoEntrega = Math.floor(Math.random() * 10 + 1) * 1000 // Entre 1 y 10 segundos\n        setTimeout(() => {\n            entregaCallback(plato) // Notificar que el plato ha sido entregado\n        }, tiempoEntrega)\n    }, tiempoPreparacion)\n  }\n  \n  // Callbacks específicos\n  function confirmarPedido(plato) {\n    console.log(`[Confirmación] Pedido recibido para el plato: ${plato}`)\n  }\n  \n  function notificarListo(plato) {\n    console.log(`[Listo] El plato \"${plato}\" está listo para ser entregado.`)\n  }\n  \n  function notificarEntregado(plato) {\n    console.log(`[Entregado] El plato \"${plato}\" ha sido entregado al cliente.`)\n  }\n  \n  procesarPedido(\"Pizza Margherita\", confirmarPedido, notificarListo, notificarEntregado)\n  // Procesando saludo para Anderson...\n  // Iniciando procesamiento del pedido: Pizza Margherita\n  // [Confirmación] Pedido recibido para el plato: Pizza Margherita\n  // ¡Hola, Anderson!\n  // Plato \"Pizza Margherita\" está siendo preparado...\n  // [Listo] El plato \"Pizza Margherita\" está listo para ser entregado.\n  // [Entregado] El plato \"Pizza Margherita\" ha sido entregado al cliente."
  },
  {
    "path": "Roadmap/21 - CALLBACKS/javascript/agusrosero.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de callback en tu lenguaje creando un ejemplo\n * simple (a tu elección) que muestre su funcionamiento.\n */\nfunction saludar(nombre) {\n  console.log(\"Hola \" + nombre);\n}\n\nfunction procesarEntradaUsuario(callback) {\n  let nombre = \"Hernan!\";\n  callback(nombre);\n}\n\nprocesarEntradaUsuario(saludar);\n\n/* DIFICULTAD EXTRA (opcional):\n * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n * Estará formado por una función que procesa pedidos.\n * Debe aceptar el nombre del plato, una callback de confirmación, una\n * de listo y otra de entrega.\n * - Debe imprimir un confirmación cuando empiece el procesamiento.\n * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n *   procesos.\n * - Debe invocar a cada callback siguiendo un orden de procesado.\n * - Debe notificar que el plato está listo o ha sido entregado.\n */\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/javascript/bernatcs.js",
    "content": "// ** EJERCICIO \n\nconst readline = require('node:readline');\n\nfunction numeroAnos(callback) {\n    const rl = readline.createInterface({\n        input: process.stdin,\n        output: process.stdout\n    });\n\n    rl.question('Por favor ingresa tu edad: ', (edad) => {\n        callback(edad);\n        rl.close();\n    });\n}\n\nfunction cuandoNaciste(edad) {\n    let actual = new Date();\n    let anoNacimiento = actual.getFullYear() - edad;\n    console.log('Naciste en el: ' + anoNacimiento + ' o ' + (anoNacimiento - 1));\n}\n\n// numeroAnos(cuandoNaciste)\n\n\n// ** DIFICULTAD EXTRA ** ------------------------------------------------------------------------------------------------------------------------------------------------\n\nfunction procesaPedido(nombrePlato, callbackConfirmacion, callbackListo, callbackEntrega) {\n    console.log(`Iniciando pedido para ${nombrePlato}`);\n    setTimeout(() => {\n        callbackConfirmacion(nombrePlato);\n        setTimeout(() => {\n            callbackListo(nombrePlato);\n            setTimeout(() => {\n                callbackEntrega(nombrePlato);\n            }, Math.random() * 9000 + 1000);\n        }, Math.random() * 9000 + 1000); \n    }, Math.random() * 9000 + 1000); \n}\n\nprocesaPedido(\n    'Pizza Margarita',\n    (plato) => {\n        console.log(`Confirmación recibida para ${plato}.`);\n    },\n    (plato) => {\n        console.log(`${plato} está listo para ser entregado.`);\n    },\n    (plato) => {\n        console.log(`${plato} ha sido entregado al cliente.`);\n    }\n);"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/javascript/brahiams7.js",
    "content": "// * EJERCICIO:\n//  * Explora el concepto de callback en tu lenguaje creando un ejemplo\n//  * simple (a tu elección) que muestre su funcionamiento.\n\nfunction saludar(nombre, callback){\n    console.log(`Hola ${nombre}`);\n    callback();\n}\nfunction despedir(){\n    console.log(\"!Adios\");\n}\n\nsaludar(\"Saory\",despedir)\n\n// * DIFICULTAD EXTRA (opcional):\n// * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n// * Estará formado por una función que procesa pedidos.\n// * Debe aceptar el nombre del plato, una callback de confirmación, una\n// * de listo y otra de entrega.\n// * - Debe imprimir un confirmación cuando empiece el procesamiento.\n// * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n// *   procesos.\n// * - Debe invocar a cada callback siguiendo un orden de procesado.\n// * - Debe notificar que el plato está listo o ha sido entregado.\nfunction pedidos(nombrePlato,cbConfirmar,cbListo,cbEntregar){\n    setTimeout(() => {\n        cbConfirmar(nombrePlato);\n        setTimeout(() => {\n            cbListo(nombrePlato);\n            setTimeout(() => {\n               cbEntregar(nombrePlato); \n            }, Math.floor((Math.random() * (10 - 1 + 1)) + 1) * 1000);\n        }, Math.floor((Math.random() * (10 - 1 + 1)) + 1) * 1000);\n    }, Math.floor((Math.random() * (10 - 1 + 1)) + 1) * 1000);\n}\n\nconst confirmar=(nombrePlato)=>{\n    console.log(`Pedido de ${nombrePlato} confirmado.`);  \n}\nconst listo=(nombrePlato)=>{\n    console.log(`Pedido de ${nombrePlato} listo.`);  \n}\nconst entregar=(nombrePlato)=>{\n    console.log(`Pedido de ${nombrePlato} entregado.`);  \n}\n\npedidos('salchipicada',confirmar,listo,entregar)"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/javascript/caterinarodriguezdev.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de callback en tu lenguaje creando un ejemplo\n * simple (a tu elección) que muestre su funcionamiento.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n * Estará formado por una función que procesa pedidos.\n * Debe aceptar el nombre del plato, una callback de confirmación, una\n * de listo y otra de entrega.\n * - Debe imprimir un confirmación cuando empiece el procesamiento.\n * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n *   procesos.\n * - Debe invocar a cada callback siguiendo un orden de procesado.\n * - Debe notificar que el plato está listo o ha sido entregado.\n */\n\nconst legendario = (frase2, callback) => {\n  const frase = \"Mi nombre es Caterina, Caterina \" + frase2;\n  diMiApellido(frase);\n};\n\nconst diMiApellido = (frase) => {\n  console.log(frase);\n};\n\nlegendario(\"Rodríguez\", diMiApellido);\n\nconsole.log(\"--------------DIFICULTAD EXTRA---------------\");\n\nconst readline = require(\"readline\");\nconst rl = readline.createInterface(process.stdin, process.stdout);\n\nrl.question(\"¿Qué le gustaría pedir? 🤌 \", (resp) => {\n  pedir(resp, confirmar, notificarListo, notificarEntregado);\n});\n\nconst pedir = (nombrePlato, confirmar, notificarListo, notificarEntregado) => {\n  console.log(\"\\n\");\n\n  confirmar(nombrePlato);\n\n  console.log('\\n');\n\n  setTimeout(() => {\n    notificarListo(nombrePlato);\n    console.log(\"\\n\");\n\n    setTimeout(() => {\n      notificarEntregado(nombrePlato);\n    }, Math.floor(Math.random() * 10 + 1) * 1000);\n  }, Math.floor(Math.random() * 10 + 1) * 1000);\n};\n\nconst confirmar = (nombrePlato) => {\n  console.log(`El pedido ${nombrePlato} se ha recibido correctamente ✅`);\n};\n\nconst notificarListo = (nombrePlato) => {\n  console.log(`El pedido ${nombrePlato} ya está listo! 😄`);\n};\n\nconst notificarEntregado = (nombrePlato) => {\n  console.log(`El pedido ${nombrePlato} ya se ha entregado 😲`);\n};\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/javascript/cesar-ch.js",
    "content": "/*\n    * #21 CALLBACKS\n*/\n\nfunction greet(name, callback) {\n    console.log(\"Hello, \" + name + \"!\");\n    callback();\n}\n\nfunction sayGoodbye() {\n    console.log(\"Goodbye!\");\n}\n\ngreet(\"Mouredev\", sayGoodbye);\n\n/*\n    * DIFICULTAD EXTRA\n*/\n\nfunction procesarPedido(plato, confirmacionCallback, listoCallback, entregaCallback) {\n    console.log(`Procesando pedido para: ${plato}`);\n    confirmacionCallback(plato);\n\n    const tiempoPreparacion = Math.floor(Math.random() * 10) + 1;\n    console.log(\"Tiempo de preparacion es: \" + tiempoPreparacion)\n    setTimeout(() => {\n        listoCallback(plato);\n\n        const tiempoEntrega = Math.floor(Math.random() * 10) + 1;\n        console.log(\"Tiempo de entrega es: \" + tiempoEntrega)\n        setTimeout(() => {\n            entregaCallback(plato);\n        }, tiempoEntrega);\n    }, tiempoPreparacion);\n}\n\nfunction confirmarPedido(plato) {\n    console.log(`Pedido confirmado para: ${plato}`);\n}\n\nfunction platoListo(plato) {\n    console.log(`El plato ${plato} está listo para ser entregado.`);\n}\n\nfunction entregarPedido(plato) {\n    console.log(`El plato ${plato} ha sido entregado.`);\n}\n\nprocesarPedido(\"Pizza\", confirmarPedido, platoListo, entregarPedido);\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/javascript/christian-jfr.js",
    "content": "// #21 CALLBACKS\n/**\n * EJERCICIO:\n * Explora el concepto de callback en tu lenguaje creando un ejemplo\n * simple (a tu elección) que muestre su funcionamiento.\n */\nfunction double(number, callback) {\n\tconst result = number * 2;\n\tcallback(`${number} x 2 = ${result}`);\n}\n\ndouble(5, console.log); // 5 x 2 = 10\ndouble(7, console.log); // 7 x 2 = 14\n\n/**\n * DIFICULTAD EXTRA (opcional):\n * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n * Estará formado por una función que procesa pedidos.\n * Debe aceptar el nombre del plato, una callback de confirmación, una\n * de listo y otra de entrega.\n * - Debe imprimir un confirmación cuando empiece el procesamiento.\n * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n *   procesos.\n * - Debe invocar a cada callback siguiendo un orden de procesado.\n * - Debe notificar que el plato está listo o ha sido entregado.\n */\n\nfunction rng() {\n\tconst SIMULATE_TIME_IN_MS = Math.floor(Math.random() * 10 + 1) * 1000;\n\treturn SIMULATE_TIME_IN_MS;\n}\n\nfunction processOrders(dish, confirm_cb, ready_cb, deliver_cb) {\n\tconfirm_cb(dish);\n\tsetTimeout(() => {\n\t\tready_cb(dish);\n\t\tsetTimeout(() => {\n\t\t\tdeliver_cb(dish);\n\t\t}, rng());\n\t}, rng());\n}\n\nfunction confirm(dish) {\n\tconsole.log(`Your ${dish} order has been confirmed.`);\n}\n\nfunction ready(dish) {\n\tconsole.log(`Your ${dish} order is ready.`);\n}\n\nfunction deliver(dish) {\n\tconsole.log(`Your ${dish} order has been delivered`);\n}\n\nprocessOrders('Spaghetti Carbonara', confirm, ready, deliver);\nprocessOrders('Veggie Pizza', confirm, ready, deliver);\nprocessOrders('Bacon Burger', confirm, ready, deliver);\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/javascript/duendeintemporal.js",
    "content": "//#21 - CALLBACKS\n/*\n * EJERCICIO:\n * Explora el concepto de callback en tu lenguaje creando un ejemplo\n * simple (a tu elección) que muestre su funcionamiento.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n * Estará formado por una función que procesa pedidos.\n * Debe aceptar el nombre del plato, una callback de confirmación, una\n * de listo y otra de entrega.\n * - Debe imprimir un confirmación cuando empiece el procesamiento.\n * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n *   procesos.\n * - Debe invocar a cada callback siguiendo un orden de procesado.\n * - Debe notificar que el plato está listo o ha sido entregado.\n */\n\n//Bibliografy reference:\n//Secrets of the JavaScript Ninja (John Resig, Bear Bibeault, Josip Maras) (z-lib.org)\n//Eloquent Javascript A Modern Introduction to Programming by Marijn Haverbeke (z-lib.org)\n//GPT\n\nlet log = console.log;\n\nwindow.addEventListener('load', ()=>{\n    const body = document.querySelector('body');\n    const title = document.createElement('h1');\n    \n    body.style.setProperty('background', '#000');\n    body.style.setProperty('text-align', 'center');\n    \n    title.textContent = 'Retosparaprogramadores #21.';\n    title.style.setProperty('font-size', '3.5vmax');\n    title.style.setProperty('color', '#fff');\n    title.style.setProperty('line-height', '100vh');\n    \n    body.appendChild(title);\n    \n    setTimeout(()=>{\n    alert('Retosparaprogramadores #21. Please open the Browser Developer Tools.');\n    }, 2000);\n    log( 'Retosparaprogramadores #21'); \n});\n\n\n/* Callbacks\nOne approach to asynchronous programming is to make functions that perform\na slow action take an extra argument, a callback function. The action is started,\nand when it finishes, the callback function is called with the result.\nAs an example, the setTimeout function, available both in Node.js and in\nbrowsers, waits a given number of milliseconds (a second is a thousand mil-\nliseconds) and then calls a function.\nsetTimeout(() => console.log(\"Tick\"), 500); */\n\n/* Whenever we set up a function to be called at a later time, whether by the browser in\nthe event-handling phase or by other code, we’re setting up a callback. The term stems\nfrom the fact that we’re establishing a function that other code will later “call back” at\nan appropriate point of execution. */\n\nconst todayMenu = ['pizza', 'hamburger', 'paella', 'arabian food', 'posole', 'pastel azteca', 'carbonara past', 'napolitana past', 'fish', 'beaf'];\n\nconst orderConfirm = (order, cb) => {\n    log(`The order: ${order} is confirmed. Tell you when it's ready.`);\n   \n    const processingTime = Math.floor(Math.random() * 10000) + 1000; \n    setTimeout(() => {\n        cb(order);\n    }, processingTime);\n}\n\nconst orderReady = (order, cb) => {\n    log(`The order: ${order} is ready. Waiting to deliver.`);\n   \n    const deliveryTime = Math.floor(Math.random() * 10000) + 1000; \n    setTimeout(() => {\n        cb(order);\n    }, deliveryTime);\n}\n\nconst orderDeliver = (order) => {\n    log(`Order: ${order} delivered.`);\n}\n\nconst makeOrder = (listOrder) => {\n    listOrder.forEach(order => {\n        if (todayMenu.some(elm => elm.toLowerCase() === order.toLowerCase())) {\n            orderConfirm(order, (confirmedOrder) => {\n                orderReady(confirmedOrder, (readyOrder) => {\n                    orderDeliver(readyOrder);\n                });\n            });\n        } else {\n            log(`The order: ${order} is not in today's menu. Please choose another dish.`);\n        }\n    });\n}\n\nlet orderList1 = ['pastiche', 'hamburger', 'pizza'];\nlet orderList2 = ['arabian food', 'fish', 'pastel azteca'];\n\nmakeOrder(orderList1);\nmakeOrder(orderList2);\n\n/* Output Example: The order: pastiche is not in today's menu. Please choose another dish.\n21.js:42 The order: hamburger is confirmed. Tell you when it's ready.\n21.js:42 The order: pizza is confirmed. Tell you when it's ready.\n21.js:42 The order: arabian food is confirmed. Tell you when it's ready.\n21.js:42 The order: fish is confirmed. Tell you when it's ready.\n21.js:42 The order: pastel azteca is confirmed. Tell you when it's ready.\n21.js:51 The order: pizza is ready. Waiting to deliver.\n21.js:51 The order: pastel azteca is ready. Waiting to deliver.\n21.js:51 The order: hamburger is ready. Waiting to deliver.\n21.js:60 Order: pizza delivered.\n21.js:60 Order: hamburger delivered.\n21.js:51 The order: fish is ready. Waiting to deliver.\n21.js:51 The order: arabian food is ready. Waiting to deliver.\n21.js:60 Order: fish delivered.\n21.js:60 Order: pastel azteca delivered.\n21.js:60 Order: arabian food delivered. */"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/javascript/emedevelopa.js",
    "content": "/*Explora el concepto de callback en tu lenguaje creando un ejemplo\n * simple (a tu elección) que muestre su funcionamiento.\n */\n\nfunction doSomethingAsyn (callback) {\n    console.log(\"Inicio de la operación asíncrona...\")\n    setTimeout(() => {\n        console.log(\"Operación asíncrona completada.\");\n        callback();\n    }, 2000);\n}\n\nfunction complete () {\n    console.log(\"Callback ejecutado: Operació finalizada.\");\n}\n\ndoSomethingAsyn(complete);\n\n/*EXTRA\nCrea un simulador de pedidos de un restaurante utilizando callbacks.\n* Estará formado por una función que procesa pedidos.\n* Debe aceptar el nombre del plato, una callback de confirmación, una\n* de listo y otra de entrega.\n* - Debe imprimir un confirmación cuando empiece el procesamiento.\n* - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n*   procesos.\n* - Debe invocar a cada callback siguiendo un orden de procesado.\n* - Debe notificar que el plato está listo o ha sido entregado.\n*/\n\nfunction getRandomTime() {\n    return Math.floor(Math.random() * 1000) + 1000;\n}\n\nfunction procesarPedido(plato, confirmación, listo, entrega) {\n    console.log(`Procesando el pedido de ${plato}`);\n    setTimeout(() => {\n        confirmacion(plato);\n            setTimeout(() => {\n                listo(plato);\n                    setTimeout(() => {\n                        entrega(plato);\n                    }, getRandomTime());\n            }, getRandomTime());\n    }, getRandomTime());\n}\n\nfunction confirmacion(plato) {\n    console.log(`Pedido de ${plato} confirmado.`)\n}\nfunction listo(plato) {\n    console.log(`Pedido de ${plato} listo.`)\n}\nfunction entrega (plato) {\n    console.log(`El plato de ${plato} ha sido entregado.`)\n}\n\nprocesarPedido('Macarrones con tomate', confirmacion, listo, entrega);"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/javascript/eugeniasoria.js",
    "content": "/*\r\n# #21 CALLBACKS\r\n * EJERCICIO:\r\n * Explora el concepto de callback en tu lenguaje creando un ejemplo\r\n * simple (a tu elección) que muestre su funcionamiento.\r\n */\r\n\r\nconst numeros = [1, 2, 3, 4, 5, 6, 8, 9, 10];\r\n\r\n//Esta funcion dejará los elementos según la función que se pase como callback\r\nfunction filtrarArray(unArray, callback) {\r\n  const resultado = [];\r\n  for (const x of unArray) {\r\n    if (callback(x))\r\n      resultado.push(x);\r\n  }\r\n  return resultado;\r\n}\r\n\r\nfunction esPar(num) {\r\n  return (num % 2 === 0) \r\n}\r\n\r\nfunction esImpar(num) {\r\n  return (num % 2 > 0) \r\n}\r\n\r\n console.log('Array original: ', numeros);\r\n \r\n const quitarPares = filtrarArray(numeros, esPar);\r\n console.log('Filtrar los pares: ', quitarPares);\r\n\r\n const quitarImpares = filtrarArray(numeros, esImpar);\r\n console.log('Filtrar los impares: ', quitarImpares);\r\n\r\n\r\n /*\r\n * DIFICULTAD EXTRA (opcional):\r\n * Crea un simulador de pedidos de un restaurante utilizando callbacks.\r\n * Estará formado por una función que procesa pedidos.\r\n * Debe aceptar el nombre del plato, una callback de confirmación, una\r\n * de listo y otra de entrega.\r\n * - Debe imprimir un confirmación cuando empiece el procesamiento.\r\n * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\r\n *   procesos.\r\n * - Debe invocar a cada callback siguiendo un orden de procesado.\r\n * - Debe notificar que el plato está listo o ha sido entregado.\r\n */\r\nconsole.log('\\n\\nDIFICULTAD EXTRA: Simulador de Pedidos');\r\n\r\nasync function confirmarPedido(plato) {        \r\n    return new Promise(resolve => {\r\n      setTimeout(() => {\r\n        console.log( `${Date.now()} 1. Pedido Confirmado: ${plato}`);\r\n        resolve(true)\r\n      }, 2000)\r\n    })  \r\n}\r\n\r\nasync function pedidoListo(plato) {\r\n    return new Promise(resolve => {\r\n      setTimeout(() => {\r\n        console.log( `${Date.now()} 2. Pedido Listo: ${plato}`);\r\n        resolve(true)\r\n      }, 8000)\r\n    })\r\n}\r\n\r\nasync function entregarPedido(plato) {\r\n    return new Promise(resolve => {\r\n      setTimeout(() => {\r\n        console.log( `${Date.now()} 3. Pedido Entregado: ${plato}`);  \r\n        resolve(true)\r\n      }, 8000)\r\n    })\r\n}\r\n\r\nasync function procesarPedido (plato, callbackConfirmacion, callbackListo, callbackOtraEntrega) {\r\n  if (!plato) {\r\n    throw new Error('No se ha indicado un plato');\r\n  }\r\n  console.log(`${Date.now()} Iniciar Pedido. Plato: ${plato}`)\r\n  const mensaje1 = await confirmarPedido(plato);\r\n  const mensaje2 = await pedidoListo(plato);\r\n  const mensaje3 = await entregarPedido(plato);    \r\n}\r\n//Ejecucion\r\nprocesarPedido('papas fritas', confirmarPedido, pedidoListo, entregarPedido);\r\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/javascript/eulogioep.js",
    "content": "/*\n * TEORÍA DE CALLBACKS EN JAVASCRIPT:\n *\n * Un callback es una función que se pasa como argumento a otra función y se ejecuta\n * después de que ocurra un evento específico o se complete una tarea. En JavaScript,\n * los callbacks son muy comunes debido a su naturaleza asíncrona.\n *\n * Los callbacks son fundamentales en JavaScript para:\n * 1. Manejar operaciones asíncronas\n * 2. Event handling (manejo de eventos)\n * 3. Funciones de orden superior\n *\n * En JavaScript, los callbacks pueden ser:\n * 1. Funciones anónimas\n * 2. Funciones flecha\n * 3. Referencias a funciones nombradas\n */\n\n// Ejemplo simple de callback\nfunction procesarTarea(tarea, callback) {\n  console.log(`Iniciando tarea: ${tarea}`);\n\n  // Simulamos un proceso asíncrono con setTimeout\n  setTimeout(() => {\n    callback();\n  }, 1000);\n}\n\n// Ejemplo de uso simple\nconsole.log(\"=== Ejemplo Simple de Callback ===\");\nprocesarTarea(\"Tarea de prueba\", () => {\n  console.log(\"¡Tarea completada!\");\n});\n\n// Simulador de pedidos de restaurante\nclass RestaurantePedidos {\n  procesarPedido(plato, onConfirmacion, onListo, onEntrega) {\n    console.log(\"\\n=== Simulador de Restaurante ===\");\n\n    // Callback de confirmación\n    onConfirmacion(`Pedido confirmado: ${plato}`);\n\n    // Simular preparación\n    const tiempoPreparacion = this.#tiempoAleatorio();\n    console.log(`Preparando... (${tiempoPreparacion} segundos)`);\n\n    setTimeout(() => {\n      // Callback de listo\n      onListo(`¡${plato} está listo!`);\n\n      // Simular entrega\n      const tiempoEntrega = this.#tiempoAleatorio();\n      console.log(`Llevando a la mesa... (${tiempoEntrega} segundos)`);\n\n      setTimeout(() => {\n        // Callback de entrega\n        onEntrega(`${plato} ha sido entregado. ¡Buen provecho!`);\n      }, tiempoEntrega * 1000);\n    }, tiempoPreparacion * 1000);\n  }\n\n  // Método privado para generar tiempo aleatorio\n  #tiempoAleatorio() {\n    return Math.floor(Math.random() * 10) + 1;\n  }\n}\n\n// Crear instancia del restaurante\nconst restaurante = new RestaurantePedidos();\n\n// Procesar un pedido\nrestaurante.procesarPedido(\n  \"Paella Valenciana\",\n  (mensaje) => console.log(`CONFIRMACIÓN: ${mensaje}`),\n  (mensaje) => console.log(`LISTO: ${mensaje}`),\n  (mensaje) => console.log(`ENTREGA: ${mensaje}`)\n);\n\n// Para evitar que el programa termine antes de que se completen los callbacks\nconsole.log(\"Esperando a que se procese el pedido...\");\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/javascript/garos01.js",
    "content": "// Función que toma un número y un callback\nfunction procesarNumero(numero, callback) {\n  // Simulamos una operación asincrónica con setTimeout\n  setTimeout(() => {\n    let resultado = numero * 2;\n    callback(resultado);\n  }, 1000);\n}\n\n// Función callback que se ejecutará después de procesar el número\nfunction mostrarResultado(resultado) {\n  console.log(\"El resultado es:\", resultado);\n}\n\n// Llamamos a la función procesarNumero y le pasamos 5 como número y mostrarResultado como callback\nprocesarNumero(5, mostrarResultado);\n\n// Ejercicio extra\n\n// Función que genera un tiempo aleatorio entre 1 y 10 segundos\nfunction tiempoAleatorio() {\n  return Math.floor(Math.random() * 10000) + 1000;\n}\n\n// Función que procesa pedidos\nfunction procesarPedido(\n  nombrePlato,\n  callbackConfirmacion,\n  callbackListo,\n  callbackEntrega\n) {\n  console.log(`Pedido recibido: ${nombrePlato}`);\n\n  // Confirmar el pedido\n  setTimeout(() => {\n    console.log(`Confirmación: El pedido de ${nombrePlato} está en proceso.`);\n    callbackConfirmacion(nombrePlato);\n\n    // Notificar que el plato está listo\n    setTimeout(() => {\n      console.log(`Listo: El plato ${nombrePlato} está listo.`);\n      callbackListo(nombrePlato);\n\n      // Notificar que el plato ha sido entregado\n      setTimeout(() => {\n        console.log(`Entrega: El plato ${nombrePlato} ha sido entregado.`);\n        callbackEntrega(nombrePlato);\n      }, tiempoAleatorio());\n    }, tiempoAleatorio());\n  }, tiempoAleatorio());\n}\n\n// Funciones callback\nfunction confirmacionCallback(plato) {\n  console.log(`Callback de confirmación: ${plato} está siendo preparado.`);\n}\n\nfunction listoCallback(plato) {\n  console.log(`Callback de listo: ${plato} está listo para ser entregado.`);\n}\n\nfunction entregaCallback(plato) {\n  console.log(`Callback de entrega: ${plato} ha sido entregado al cliente.`);\n}\n\n// Ejemplos\nprocesarPedido(\n  \"Pizza Carne\",\n  confirmacionCallback,\n  listoCallback,\n  entregaCallback\n);\nprocesarPedido(\n  \"Ensalada\",\n  confirmacionCallback,\n  listoCallback,\n  entregaCallback\n);\nprocesarPedido(\n  \"Tiramisú\",\n  confirmacionCallback,\n  listoCallback,\n  entregaCallback\n);\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/javascript/hectorio23.js",
    "content": "// Autor: Héctor Adán \n// GitHub: https://github.com/hectorio23\n\"use strict\";\n\n/*******************************************\n*************** EJERCICO **************+****\n*******************************************/\n\nconst print = message => console.log(`Mensaje impreso por callback: ${ message }`);\n\nfunction doSomething(message, callback) {\n    callback(message);\n}\n\ndoSomething(\"¡Hola Mundo!\", print);\nconsole.log(\"\\n**************** EJERCICIO EXTRA *******************+\\n\")\n\n\n/*******************************************\n************ EJERCICO EXTRA  **********+****\n*******************************************/\n\n// Función que confirma el pedido, por defecto es Falso\nfunction confirmacion(nombre_plato, check) {\n    console.log(`[Confirmacion] - ¿Usted desea confirmar el pedido llamado \"${nombre_plato}\"?: ${check ? 'Yes' : 'No'}`);\n\n    return check;\n}\n\n// Función que imprime si el pedido está listo\nasync function listo(nombre_plato, confirmado) {\n    await new Promise(resolve => setTimeout(resolve, Math.random() * 10000));\n    console.log(`[Listo] - El pedido \"${nombre_plato}\" está listo para ser entregado`);\n}\n\n// Función que imprime si el pedido ya ha sido entregado\nasync function entrega(nombre_plato) {\n    await new Promise(resolve => setTimeout(resolve, Math.random() * 10000));\n    console.log(`[Entrega] - El pedido \"${nombre_plato}\" ha sido entregado`);\n}\n\n// Función que procesa las órdenes\nasync function make_order(nombre_plato, confirmacion, listo, entrega, check = false) {\n    const confirmado = confirmacion(nombre_plato, check);\n    if (!check) {\n        console.log(`[Cancelled] - El pedido \"${nombre_plato}\" no se confirmó, por lo que se canceló el pedido`);\n        return;\n    }\n    \n    await listo(nombre_plato, confirmado);\n    await entrega(nombre_plato);\n}\n\n// Función principal\nasync function main() {\n    const orders = [\n        make_order(\"Papas a la francesa\", confirmacion, listo, entrega, true),\n        make_order(\"Carne de Cocodrilo a la parrilla\", confirmacion, listo, entrega, false),\n        make_order(\"Tacos de Pastor\", confirmacion, listo, entrega, true),\n        make_order(\"Ensalada de Papas con albondigas\", confirmacion, listo, entrega, true)\n    ];\n    await Promise.all(orders);\n}\n\n// Ejecución del ejercicio extra\nmain().catch(console.error);"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n_______________________________________\n#21 CALLBACKS\n---------------------------------------\n * EJERCICIO:\n * Explora el concepto de callback en tu lenguaje creando un ejemplo\n * simple (a tu elección) que muestre su funcionamiento.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n * Estará formado por una función que procesa pedidos.\n * Debe aceptar el nombre del plato, una callback de confirmación, una\n * de listo y otra de entrega.\n * - Debe imprimir un confirmación cuando empiece el procesamiento.\n * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n *   procesos.\n * - Debe invocar a cada callback siguiendo un orden de procesado.\n * - Debe notificar que el plato está listo o ha sido entregado.\n*/\n// ________________________________________________________\nfunction sumNumbers(a, b, callback) {\n    if (typeof a === \"number\" && typeof b === \"number\") {\n      const result = a + b;\n      callback(`${a} + ${b}`, result);\n    }\n  }\n  \n  function myCallback(summands, result) {\n    if (typeof summands === \"string\" && typeof result === \"number\") {\n      console.log(`La suma de ${summands} es: ${result}`);\n    }\n  }\n  \n  sumNumbers(6, 6, myCallback);\n  sumNumbers(5, 2, myCallback);\n  \n  // ________________________________________________________\n  console.log(\"\\nDIFICULTAD EXTRA\");\n  \n  function timeRandom() {\n    return Math.floor(Math.random() * 10) + 1;\n  }\n  \n  function confirmOrder(name) {\n    return new Promise((resolve) => {\n      const time = timeRandom();\n      console.log(`* Confirmando ${name}, espere ${time} segundos.`);\n      setTimeout(() => {\n        console.log(`- '${name}', ha sido confirmado.\\n`);\n        resolve();\n      }, time * 1000);\n    });\n  }\n  \n  function prepareOrder(name) {\n    return new Promise((resolve) => {\n      const time = timeRandom();\n      console.log(`* Preparando ${name}, espere ${time} segundos.`);\n      setTimeout(() => {\n        console.log(`- '${name}', está listo.\\n`);\n        resolve();\n      }, time * 1000);\n    });\n  }\n  \n  function servingOrder(name) {\n    return new Promise((resolve) => {\n      const time = timeRandom();\n      console.log(`* Sirviendo ${name}, espere ${time} segundos.`);\n      setTimeout(() => {\n        console.log(`- '${name}', ha sido entregado.\\n`);\n        resolve();\n      }, time * 1000);\n    });\n  }\n  \n  async function processOrder(name) {\n    console.log(`-----\\n* Procesando: '${name}' \\n-----\\n`);\n    await confirmOrder(name);\n    await prepareOrder(name);\n    await servingOrder(name);\n  }\n  \n  async function ordersList() {\n    await processOrder(\"Baleadas\");\n    await processOrder(\"Tamales\");\n    await processOrder(\"Enchiladas\");\n  }\n  \n  ordersList();\n  "
  },
  {
    "path": "Roadmap/21 - CALLBACKS/javascript/nlarrea.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de callback en tu lenguaje creando un ejemplo\n * simple (a tu elección) que muestre su funcionamiento.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n * Estará formado por una función que procesa pedidos.\n * Debe aceptar el nombre del plato, una callback de confirmación, una\n * de listo y otra de entrega.\n * - Debe imprimir un confirmación cuando empiece el procesamiento.\n * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n *   procesos.\n * - Debe invocar a cada callback siguiendo un orden de procesado.\n * - Debe notificar que el plato está listo o ha sido entregado.\n */\n\n\nfunction greeting(user, callback) {\n    console.log('This is the greeting process...');\n    callback(user);\n}\n\n\nfunction greetUser(user) {\n    console.log(`Welcome ${user}!`);\n}\n\n\ngreeting('nlarrea', greetUser);\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n * Estará formado por una función que procesa pedidos.\n * Debe aceptar el nombre del plato, una callback de confirmación, una\n * de listo y otra de entrega.\n * - Debe imprimir un confirmación cuando empiece el procesamiento.\n * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n *   procesos.\n * - Debe invocar a cada callback siguiendo un orden de procesado.\n * - Debe notificar que el plato está listo o ha sido entregado.\n */\n\n\nfunction orderProcess(\n    dish, confirmCallback, readyCallback, deliveredCallback\n) {\n    const randTime = (min, max = 0) => {\n        [min, max] = [Math.min(min, max), Math.max(min, max)];\n        return Math.floor(Math.random() * (max - min) + min) * 1000;\n    };\n\n    setTimeout(() => {\n        confirmCallback(dish);\n        \n        setTimeout(() => {\n            readyCallback(dish);\n\n            setTimeout(() => {\n                deliveredCallback(dish);\n            }, randTime(1, 5));\n        }, randTime(1, 5));\n    }, randTime(1, 5));\n}\n\n\nfunction orderConfirmation(dish) {\n    console.log(`The order '${dish}' is confirmed.`);\n}\n\n\nfunction orderReady(dish) {\n    console.log(`The order '${dish}' is ready.`);\n}\n\n\nfunction orderDelivered(dish) {\n    console.log(`The order '${dish}' has been delivered.`);\n}\n\n\norderProcess(\n    'Tonkotsu Ramen', orderConfirmation, orderReady, orderDelivered\n);"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/javascript/parababire.js",
    "content": "//Ejercicio\n\n/* Las callback brillan en el mundo real cuando son usadas por funciones asyncronas */\n\nfunction myFunction() {\n  console.log('Hello World');\n}\n/* La función setTimeout nos permite emular un proceso asyncrono que al finalizar llama a nuestra callback */\nsetTimeout(myFunction, 3000);\n\n//Extra\n\nasync function orderProcess(dishName, confirmCallback, readyCallback, deliveredCallback) {\n  await confirmCallback(dishName).then(orderHandle);\n  await readyCallback(dishName).then(orderHandle);\n  await deliveredCallback(dishName).then(orderHandle);\n}\n\nfunction orderHandle(result) {\n  return console.log(result);\n}\n\nasync function confirmOrder(order) {\n  return new Promise(function(resolve) {\n    resolve(`Orden de ${order} Recibida`);\n  })\n}\n\nasync function orderReady(order) {\n  return new Promise(function(resolve) {\n    setTimeout(function() {\n      resolve(`${order} lista`);\n    }, Math.floor((Math.random() * 10000) + 1000));\n  })\n}\n\nasync function orderDelivered(order) {\n  return new Promise(function(resolve) {\n    setTimeout(function() {\n      resolve(`${order} entregada`);\n    }, Math.floor((Math.random() * 10000) + 1000));\n  })\n}\n\norderProcess('Pizza Margarita', confirmOrder, orderReady, orderDelivered);\norderProcess('Pizza 4 Quesos', confirmOrder, orderReady, orderDelivered);\norderProcess('Pizza Napolitana', confirmOrder, orderReady, orderDelivered);\norderProcess('Pizza Fungi', confirmOrder, orderReady, orderDelivered);"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/javascript/pedamoci.js",
    "content": "function sumar(a, b) {\n  console.log( a + b)\n}\n\nfunction pedirNumeros(callback) {\n  let a = 42\n  let b = 56\n  callback(a, b)\n}\n\npedirNumeros(sumar) \n\n// -------------------------------------- DIFICULTAD EXTRA --------------------------------------\nfunction confirmar(plato) {\n    console.log(`Se ha confirmado el pedido de: ${plato}`)\n}\n\nfunction preparar(plato) {\n    console.log(`Tu ${plato} ya esta listo`)\n}\n\nfunction entregar() {\n    console.log(`Ya se ha entregado tu pedido`)\n}\n\nfunction seguimientoPedido(plato, comprobar, elaborar, repartir) {\n  const functions = [comprobar, elaborar, repartir]\n  console.log('Procesando...')\n  for (let i = 0; i < functions.length; i++) {\n    setTimeout(() => {\n      functions[i](plato)\n    }, 1000 + Math.floor(Math.random() * 10000))\n  }\n}\n\nseguimientoPedido('ramen', confirmar, preparar, entregar)"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/javascript/victor-Casta.js",
    "content": "/*\n  * EJERCICIO:\n  * Explora el concepto de callback en tu lenguaje creando un ejemplo\n  * simple (a tu elección) que muestre su funcionamiento.\n*/\n\n//Ejemplo 1\nfunction updatelist(list, callback) {\n  list.push(7)\n  callback()\n}\n\nconst MyList = [1, 2, 3, 4, 5, 6]\n\nupdatelist(MyList, function () {\n  console.log(MyList)\n})\n\n// Ejemplo 2\nfunction getDataToUrl(callback) {\n  fetch('https:api.escuelajs.co/api/v1/products')\n    .then(response => response.json())\n    .then(data => {\n      let contentURL = data\n      callback(contentURL)\n    })\n    .catch(error => console.error('Error:', error))\n}\n\ngetDataToUrl((content) => {\n  console.log(content)\n})\n\n//  Ejemplo 3\nfunction multiply(a, b, callback) {\n  setTimeout(() => {\n    let result = a * b\n    callback(result)\n  }, 4000)\n}\n\nmultiply(3, 4, (result) => {\n  console.log(result)\n})\n\n/*\n  * DIFICULTAD EXTRA (opcional):\n  * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n  * Estará formado por una función que procesa pedidos.\n  * Debe aceptar el nombre del plato, una callback de confirmación, una\n  * de listo y otra de entrega.\n  * - Debe imprimir un confirmación cuando empiece el procesamiento.\n  * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n  *   procesos.\n  * - Debe invocar a cada callback siguiendo un orden de procesado.\n  * - Debe notificar que el plato está listo o ha sido entregado.\n*/\n\nfunction getRandomArbitrary(min, max) {\n  let number = Math.random() * (max - min) + min\n  return Math.round(number)\n}\n\nfunction orderProcess(orderName, checkCallback, readyCallback, deliveredCallback) {\n  checkCallback(orderName)\n  setTimeout(() => {\n    readyCallback(orderName)\n    setTimeout(() => {\n      deliveredCallback(orderName)\n    }, getRandomArbitrary(1000, 10000))\n  }, getRandomArbitrary(1000, 10000))\n}\n\nfunction checkOrder(orderName) {\n  console.log(`Su pedido ${orderName} ha sido confirmado`)\n}\n\nfunction readyOrder(orderName) {\n  console.log(`Su pedido ${orderName} está listo`)\n}\n\nfunction deliveredOrder(orderName) {\n  console.log(`Su pedido  ${orderName} ha sido entregado`)\n}\n\norderProcess('Hamburguesa sencilla', checkOrder, readyOrder, deliveredOrder)\n\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/kotlin/blackriper.kt",
    "content": "import kotlinx.coroutines.runBlocking\r\nimport kotlinx.coroutines.time.delay\r\nimport java.time.Duration\r\nimport kotlin.random.Random\r\n\r\n/*\r\n una funcion callback  es una funcion   que se pasa como parametro de otra funcion y\r\n que se ejecuta cuando la primera funcion termina de ejecutarse.\r\n\r\n los callback  pueden ser de dos tipos:\r\n -asincronos\r\n -sincronos\r\n\r\n Antes de la llegada del async  las callbacks eran muy utilizadas\r\n\r\n en kotlin  las callbacks se pueden simplificar usando las funciones lambda\r\n\r\n\r\n*/\r\n\r\nfun exampleWithCallback(callback:(Int)->Int){\r\n    val numbers= listOf(1,2,3,4,5,6,7,8,9,10);\r\n    numbers.forEach{\r\n       println(callback(it))\r\n    }\r\n}\r\n\r\n// ejercicio extra en este caso de forma  concurrente\r\n\r\nsuspend fun confirmOrder(dishName:String,duration:Long){\r\n    println(\"start to order $dishName\")\r\n    delay(Duration.ofSeconds(duration))\r\n}\r\n\r\nsuspend fun orderList(dishName:String,duration:Long){\r\n    delay(Duration.ofSeconds(duration))\r\n    println(\"order $dishName is ready \")\r\n}\r\n\r\nsuspend fun deliverOrder(dishName:String,duration:Long){\r\n    delay(Duration.ofSeconds(duration))\r\n    println(\"order $dishName  is recived \")\r\n}\r\n\r\n// para no escribir un tipo muy largo podemos crear un tipo personalizado\r\ntypealias Callback =suspend (String,Long)->Unit\r\n\r\nfun restaurantOrder(confirm: Callback, order:Callback, deliver:Callback){\r\n   runBlocking {\r\n       val random= Random.nextInt(1,10)\r\n       confirm(\"pizza hawaina\",random.toLong())\r\n       order(\"pizza hawaina\",random.toLong())\r\n       deliver(\"pizza hawaina\",random.toLong())\r\n   }\r\n\r\n}\r\n\r\n\r\n\r\nfun main() {\r\n    // pasando callback mediante lambda function\r\n    exampleWithCallback { it*2 }\r\n    // pasando callback forma tradicional omitiendo paramatros de la funcion por eso se usan de los ::\r\n    restaurantOrder(::confirmOrder,::orderList,::deliverOrder)\r\n}"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/kotlin/eulogioep.kt",
    "content": "import kotlinx.coroutines.*\nimport kotlin.random.Random\n\n// Ejemplo simple de callback\nfun operacionAsincrona(callback: (String) -> Unit) {\n    Thread {\n        Thread.sleep(2000) // Simula una operación que tarda 2 segundos\n        callback(\"Operación completada\")\n    }.start()\n}\n\n// Simulador de pedidos de restaurante\nfun procesarPedido(\n    nombrePlato: String,\n    confirmarPedido: () -> Unit,\n    platoProcesado: () -> Unit,\n    platoEntregado: () -> Unit\n) {\n    println(\"Procesando pedido: $nombrePlato\")\n    confirmarPedido()\n    \n    runBlocking {\n        delay(Random.nextLong(1000, 10001)) // Tiempo aleatorio entre 1 y 10 segundos\n        platoProcesado()\n        \n        delay(Random.nextLong(1000, 10001))\n        platoEntregado()\n    }\n}\n\nfun main() {\n    println(\"Ejemplo simple de callback:\")\n    operacionAsincrona { resultado ->\n        println(resultado)\n    }\n    \n    Thread.sleep(3000) // Espera para que se complete la operación asíncrona\n    \n    println(\"\\nSimulador de pedidos de restaurante:\")\n    procesarPedido(\n        \"Pizza Margherita\",\n        { println(\"Pedido confirmado: Pizza Margherita\") },\n        { println(\"Pizza Margherita está lista\") },\n        { println(\"Pizza Margherita ha sido entregada\") }\n    )\n}"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/nasm/evanz2608.s",
    "content": "; https://nasm.us\n\n; ===================================================\n; 21 - CALLBACKS\n; ===================================================\n;\n; Las funciones, en ensamblador, son en realidad etiquetas que luego en el proceso de ensamblado y linkeado,\n; son reemplazadas por una dirección de memoria a la que luego se salta para ejecutar el código desde ese lugar.\n; Con lo cual, pasar una funcíon a otra función, es exactamente igual que pasarle otro parámetro cualquiera.\n; La única diferencia en este caso, sería cargar esa dirección de memoria en algún registro, y hacer un call con ese registro\n; como parámetro.\n; Hay que tener en cuenta que los registros modifican constantemente su contenido, asi que lo mas prudente es almacenar la dirección de la\n; función en algún lugar de la memoria para luego poder hacer el call. El lugar mas obvio es dentro del stack en la función que recibe la callback.\n\nSYS_write equ 1\nSYS_exit equ 60\n\nSTDOUT equ 1\n\nglobal _start\nsection .text\n_start:\n  lea rdi, [funcion_callback]\n  call funcion_principal\n\n  lea rdi, [callback_con_parametros]\n  lea rsi, [callback_param_msg]\n  mov rdx, callback_param_msg_len\n  call funcion_principal_con_parametros\n_exit:\n  mov rax, SYS_exit\n  xor rdi, rdi\n  syscall\n\n\n; RDI = puntero a función callback\nfuncion_principal:\n  enter 16, 0\n  mov qword [rbp - 16], rdi       ; Almacenamos la dirección de la función callback\n  mov rax, SYS_write\n  mov rdi, STDOUT\n  lea rsi, [func_msg]\n  mov rdx, func_msg_len\n  syscall\n  mov rax, qword [rbp - 16]       ; Cargamos la dirección de la función callback en RAX\n  call rax                        ; Y llamamos a la función\n  leave\n  ret\n\n\n; Función que será pasada a otras funciones como parámetro.\nfuncion_callback:\n  mov rax, SYS_write\n  mov rdi, STDOUT\n  lea rsi, [callback_msg]\n  mov rdx, callback_msg_len\n  syscall\n  ret\n\n\n; RDI = puntero a función callback\n; RSI = primer parametro de la función callback\n; RDX = segundo parametro de la función callback\nfuncion_principal_con_parametros:\n  enter 32, 0\n  mov [rbp - 32], rdi\n  mov [rbp - 24], rsi\n  mov [rbp - 16], rdx\n\n  mov rax, SYS_write\n  mov rdi, STDOUT\n  lea rsi, [func_param_msg]\n  mov rdx, func_param_msg_len\n  syscall\n\n  mov rax, [rbp - 32]\n  mov rdi, [rbp - 24]\n  mov rsi, [rbp - 16]\n  call rax\n  leave\n  ret\n\n; Función callback con un parámetro.\n; Recibe en RDI un puntero a un string.\n; y en RSI el largo del string\ncallback_con_parametros:\n  mov rdx, rsi\n  mov rsi, rdi\n  mov rax, SYS_write\n  mov rdi, STDOUT\n  syscall\n  ret\n\nsection .rodata\n  func_msg: db \"Hola desde una función normal\", 0x0A\n  func_msg_len: equ $-func_msg\n  func_param_msg: db \"Hola desde una función normal con callback con parametros\", 0x0A\n  func_param_msg_len: equ $-func_param_msg\n  callback_msg: db \"Hola desde una función callback!\", 0x0A\n  callback_msg_len: equ $-callback_msg\n  callback_param_msg: db \"Hola desde una función callback con parámetros!\", 0x0A\n  callback_param_msg_len: equ $-callback_param_msg\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/ocaml/luishendrix92.ml",
    "content": "open Printf\n\n(****************************************************************************)\n(*                                                                          *)\n(*                             Callbacks (HoF)                              *)\n(*                                                                          *)\n(*  As a functional programming language, OCaml is perfectly capable of     *)\n(*  treating functions as first-class citizens; meaning, we can store them  *)\n(*  inside variables, accept them as parameters, return them from other     *)\n(*  functions, and more!                                                    *)\n(*                                                                          *)\n(*  In programming, a {b callback} is a function that is passed as an       *)\n(*  argument to a function, which will be later called (with or without     *)\n(*  arguments) once a certain task is completed synchronously or            *)\n(*  asynchronously. The term was popularized by the inception of NodeJS's   *)\n(*  single-threaded concurrent programming but it goes beyond just that...  *)\n(*  both in history and use cases. A callback can be just a function that   *)\n(*  represent a strategy, or can be a set of instructions to run at a       *)\n(*  certain point in time; it can be virtually any type of function,        *)\n(*  really; as long as it's passed as an argument to another function.      *)\n(*                                                                          *)\n(****************************************************************************)\n\nlet with_named_parameters ~callback name =\n  let greeting = sprintf \"Hello, %s! How are you today?\" name in\n  printf \"HoF 'with_named_parameters' will run callback with [%s]...\\n\" name;\n  callback greeting;\n  print_endline\n    \"Higher-Order Function 'with_named_parameters' finished execution!\"\n;;\n\nlet _ =\n  (* Why have [callback] as a named parameter?\n     It's idiomatic in the OCaml world... *)\n  with_named_parameters\n    ~callback:(fun greeting -> printf \"Greeting received: %s\\n\" greeting)\n    \"Luis\";\n  print_newline ()\n;;\n\n(**************************************************************************)\n(*                                                                        *)\n(*                      Dificultad Extra (opcional)                       *)\n(*                                                                        *)\n(*  Crea un simulador de pedidos de un restaurante utilizando callbacks.  *)\n(*  Estará formado por una función que procesa pedidos.                   *)\n(*  Debe aceptar el nombre del plato, una callback de confirmación, una   *)\n(*  de listo, y otra de entrega.                                          *)\n(*                                                                        *)\n(*  - Debe imprimir una confirmación cuando empiece el procesamiento.     *)\n(*  - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre        *)\n(*    procesos.                                                           *)\n(*  - Debe invocar a cada callback siguiendo un orden de procesado.       *)\n(*  - Debe notificar que el plato está listo o ha sido entregado.         *)\n(*                                                                        *)\n(**************************************************************************)\n\nlet wait_between_1_and_10_seconds () = Thread.delay (Random.float 9.0 +. 1.0)\n\nmodule Restaurant : sig\n  val show_menu : unit -> unit\n\n  val place_order\n    :  on_confirmed:(unit -> unit)\n    -> on_ready:(unit -> unit)\n    -> on_delivered:(string -> unit)\n    -> int\n    -> unit\nend = struct\n  Random.self_init ()\n\n  type dish =\n    | HotDog\n    | Cheeseburger\n    | CaesarSalad\n    | Chicken\n    | Shortcake\n    | Ramen\n  [@@deriving show]\n\n  let dish_of_int = function\n    | 1 -> HotDog\n    | 2 -> Cheeseburger\n    | 3 -> CaesarSalad\n    | 4 -> Chicken\n    | 5 -> Shortcake\n    | 6 -> Ramen\n    | _ -> raise (Invalid_argument \"Dish number not in the menu\")\n  ;;\n\n  let dish_to_emoji = function\n    | HotDog -> \"🌭\"\n    | Cheeseburger -> \"🍔\"\n    | CaesarSalad -> \"🥗\"\n    | Chicken -> \"🍗\"\n    | Shortcake -> \"🍰\"\n    | Ramen -> \"🍜\"\n  ;;\n\n  let show_menu () =\n    print_endline \"#1 <- Hot dog\";\n    print_endline \"#2 <- Cheeseburger\";\n    print_endline \"#3 <- Caesar salad\";\n    print_endline \"#4 <- Chicken wings\";\n    print_endline \"#5 <- Strawberry shortcake\";\n    print_endline \"#6 <- Ramen bowl\"\n  ;;\n\n  let process_order ~on_confirmed ~on_ready ~on_delivered dish =\n    wait_between_1_and_10_seconds ();\n    print_endline \"Order was confirmed, invoking confirmation callback...\";\n    on_confirmed ();\n    wait_between_1_and_10_seconds ();\n    print_endline \"Order is ready, invoking readiness callback...\";\n    on_ready ();\n    wait_between_1_and_10_seconds ();\n    print_endline \"Order being delived to table, invoking delivery callback...\";\n    on_delivered (dish_to_emoji dish)\n  ;;\n\n  let place_order ~on_confirmed ~on_ready ~on_delivered dish_number =\n    let dish = dish_of_int dish_number in\n    let order_thread =\n      Thread.create (process_order ~on_confirmed ~on_ready ~on_delivered) dish\n    in\n    printf\n      \"Restaurant cashier says: Order [%s] has been placed!\\n\"\n      (show_dish dish);\n    print_endline \"---------------------------------------------------\";\n    Thread.join order_thread\n  ;;\nend\n\nlet _ =\n  print_endline \"Welcome to my restaurant! Here's the menu:\";\n  Restaurant.show_menu ();\n  let dish_number =\n    Moure.Io.prompt\n      ~err_msg:\"Invalid number\"\n      ~f:int_of_string\n      \"Choose a menu item between 1 and 6: \"\n  in\n  match dish_number with\n  | Ok dish_number ->\n    Restaurant.place_order\n      ~on_confirmed:(fun () ->\n        print_endline \"Customer says: Time to take a seat :)\")\n      ~on_ready:(fun () ->\n        print_endline \"Customer says: Food's ready? I'll be waiting!\")\n      ~on_delivered:(fun emoji ->\n        printf \"Customer says: Yum, time to eat my [%s]!\\n\" emoji)\n      dish_number\n  | Error msg -> print_endline msg\n;;\n\n(* Output of [dune exec reto21]:\n\n   HoF 'with_named_parameters' will run callback with [Luis]...\n   Greeting received: Hello, Luis! How are you today?\n   Higher-Order Function 'with_named_parameters' finished execution!\n\n   Welcome to my restaurant! Here's the menu:\n   #1 <- Hot dog\n   #2 <- Cheeseburger\n   #3 <- Caesar salad\n   #4 <- Chicken wings\n   #5 <- Strawberry shortcake\n   #6 <- Ramen bowl\n   Choose a menu item between 1 and 6: 2\n   Restaurant cashier says: Order [Reto21.Restaurant.Cheeseburger] has been placed!\n   ---------------------------------------------------\n   Order was confirmed, invoking confirmation callback...\n   Customer says: Time to take a seat :)\n   Order is ready, invoking readiness callback...\n   Customer says: Food's ready? I'll be waiting!\n   Order being delived to table, invoking delivery callback...\n   Customer says: Yum, time to eat my [🍔]!\n*)\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/php/eulogioep.php",
    "content": "<?php\n/*\n * TEORÍA DE CALLBACKS EN PHP:\n * \n * Un callback en PHP es una función que se pasa como argumento a otra función\n * para ser ejecutada más tarde. PHP ofrece varias formas de implementar callbacks:\n * \n * 1. Funciones anónimas (closures)\n * 2. Arrays callable ([objeto/clase, método])\n * 3. Strings con nombres de funciones\n * 4. Arrow functions (PHP 7.4+)\n * \n * Los callbacks son útiles para:\n * 1. Personalizar el comportamiento de funciones\n * 2. Implementar patrones de diseño como Observer\n * 3. Manejar eventos y procesamiento asíncrono (en la medida que PHP lo permite)\n */\n\n// Función de utilidad para simular espera\nfunction simularEspera() {\n    $segundos = rand(1, 10);\n    echo \"Procesando... ({$segundos} segundos)\\n\";\n    sleep($segundos);\n}\n\n// Ejemplo simple de callback\nfunction procesarTarea(string $tarea, callable $callback): void {\n    echo \"Iniciando tarea: {$tarea}\\n\";\n    \n    // Simulamos algún procesamiento\n    sleep(1);\n    \n    // Ejecutamos el callback\n    $callback();\n}\n\n// Clase para el simulador de restaurante\nclass RestaurantePedidos {\n    public function procesarPedido(\n        string $plato,\n        callable $onConfirmacion,\n        callable $onListo,\n        callable $onEntrega\n    ): void {\n        // Callback de confirmación\n        $onConfirmacion(\"Pedido confirmado: {$plato}\");\n        \n        // Simular preparación\n        simularEspera();\n        \n        // Callback de listo\n        $onListo(\"¡{$plato} está listo!\");\n        \n        // Simular entrega\n        simularEspera();\n        \n        // Callback de entrega\n        $onEntrega(\"{$plato} ha sido entregado. ¡Buen provecho!\");\n    }\n}\n\n// Función principal para ejecutar los ejemplos\nfunction main(): void {\n    echo \"=== Ejemplo Simple de Callback ===\\n\";\n    \n    // Ejemplo usando una función anónima\n    procesarTarea(\"Tarea de prueba\", function() {\n        echo \"¡Tarea completada!\\n\";\n    });\n    \n    echo \"\\n=== Simulador de Restaurante ===\\n\";\n    \n    $restaurante = new RestaurantePedidos();\n    \n    // Procesamos un pedido usando el simulador\n    $restaurante->procesarPedido(\n        \"Paella Valenciana\",\n        // Callback de confirmación - usando arrow function (PHP 7.4+)\n        fn($mensaje) => echo \"CONFIRMACIÓN: {$mensaje}\\n\",\n        // Callback de listo - usando función anónima tradicional\n        function($mensaje) {\n            echo \"LISTO: {$mensaje}\\n\";\n        },\n        // Callback de entrega - también usando función anónima\n        function($mensaje) {\n            echo \"ENTREGA: {$mensaje}\\n\";\n        }\n    );\n}\n\n// Ejecutar el programa\nmain();\n\n?>"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/php/gabrielmoris.php",
    "content": "<?php\n/*\n * EXERCISE:\n * Explore the concept of callbacks in your language by creating a\n * simple example (of your choice) that demonstrates its functionality.\n */\n\nfunction return_callback($callback)\n{\n    return $callback();\n}\n\nfunction echo_sth()\n{\n    echo \"I am in a calback\\n\";\n}\n\nreturn_callback(\"echo_sth\");\n\n/*\n * EXTRA DIFFICULTY (optional):\n * Create a restaurant order simulator using callbacks.\n * It will consist of a function that processes orders.\n * It should accept the dish name, a confirmation callback, a\n * ready callback, and a delivery callback.\n * - It should print a confirmation when processing starts.\n * - It should simulate a random time between 1 to 10 seconds between\n *   processes.\n * - It should invoke each callback following a processing order.\n * - It should notify when the dish is ready or has been delivered.\n */\n\necho \"============= CHALLENGE =============\\n\";\n\nfunction restaurantOrder($dishname, $confirmationCB, $readyCB, $deliveryCB)\n{\n    $orderID = substr(str_shuffle('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'), 0, 10);\n    $confirmationCB($dishname);\n    echo \"Your Processing order is $orderID\\n\";\n    sleep(rand(1, 10));\n    $readyCB($dishname);\n    echo \"Your Processing order is $orderID\\n\";\n    sleep(rand(1, 10));\n    $deliveryCB($dishname);\n    echo \"Your Processing order is $orderID\\n\";\n}\n\nfunction confirmation($dishname)\n{\n    echo \"$dishname order confirmed.\\n\";\n}\n\nfunction ready($dishname)\n{\n    echo \"$dishname is ready.\\n\";\n}\n\nfunction delivery($dishname)\n{\n    echo \"$dishname has been delivered.\\n\";\n}\n\nrestaurantOrder(\"Kartoffelpure\", \"confirmation\", \"ready\", \"delivery\");\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/php/miguelex.php",
    "content": "<?php\nfunction callbackExample(array $numeros, callable $callback) {\n    $resultado = 0;\n    foreach ($numeros as $numero) {\n        $resultado = $callback($resultado, $numero);\n    }\n    return $resultado;\n}\n\n$numeros = [10, 9, -5, 3, 2, 1, 0];\n\nfunction numberSum($a, $b) {\n    return $a + $b;\n}\n\necho \"Vamos a ver un ejemplo simple de Callback. Pasaremos un array de numeros y obtendremos la suma de todo sus elementos\\n\";\n\necho \"El resultado de la suma de los numeros es: \" . callbackExample($numeros, 'numberSum');\n\n\n// Extra\n\necho '\\n\\nEjercicio Extra\\n\\n';\n\nfunction procesarPedido($plato, callable $confirmacion, callable $listo, callable $entrega) {\n    \n    echo \"Procesando el pedido del plato: $plato\\n\";\n    $confirmacion($plato);\n    \n    \n    $tiempoPreparacion = rand(1, 10);\n    sleep($tiempoPreparacion);\n    \n    \n    $listo($plato);\n    \n   \n    $tiempoEntrega = rand(1, 10);\n    sleep($tiempoEntrega);\n    \n    \n    $entrega($plato);\n}\n\n\nfunction confirmarPedido($plato) {\n    echo \"Pedido confirmado: $plato\\n\";\n}\n\nfunction platoListo($plato) {\n    echo \"El plato está listo: $plato\\n\";\n}\n\nfunction entregarPedido($plato) {\n    echo \"El plato ha sido entregado: $plato\\n\";\n}\n\n\nfunction leerEntrada($mensaje) {\n    echo $mensaje;\n    $entrada = trim(fgets(STDIN));\n    return $entrada;\n}\n\n\necho \"Simulador de pedidos de un restaurante\\n\\n\";\n\nwhile (true) {\n    $plato = leerEntrada(\"Ingrese el nombre del plato (o escriba 'salir' para terminar): \");\n    if (strtolower($plato) == 'salir') {\n        break;\n    }\n    procesarPedido($plato, 'confirmarPedido', 'platoListo', 'entregarPedido');\n    echo \"\\n\";\n}\n\necho \"Fin de la simulación de pedidos.\\n\";"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/php/thaishdz.php",
    "content": "<?php\n\nrequire 'vendor/autoload.php';\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n * Estará formado por una función que procesa pedidos.\n * Debe aceptar el nombre del plato, una callback de confirmación, una\n * de listo y otra de entrega. ✔️\n * - Debe imprimir un confirmación cuando empiece el procesamiento.\n * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n *   procesos. ✔️\n * - Debe invocar a cada callback siguiendo un orden de procesado. ✔️\n * - Debe notificar que el plato está listo o ha sido entregado. ✔️\n */\n\nuse React\\EventLoop\\Loop;\nuse React\\Promise\\Deferred;\n\nfunction processOrder(\n    string $meal, \n    callable $confirmCallback, \n    callable $readyCallback, \n    callable $deliveredCallback\n): void\n{\n    $deferredConfirm = new Deferred(); // crea una promesa\n\n    // Etapa Confirm\n    Loop::addTimer(rand(1,10), function() use ($meal, $confirmCallback,$deferredConfirm)\n    {\n        echo $confirmCallback($meal);\n        $deferredConfirm->resolve($meal); // se le pasa el pedido a la siguiente etapa\n    });\n\n    // Encadenar la siguiente etapa - Ready\n    $deferredConfirm->promise()->then(function($meal) use($readyCallback, $deliveredCallback) \n    {   \n        $deferredReady = new Deferred(); // nueva promesa ya que la anterior se resolvió\n\n        Loop::addTimer(rand(1,10), function() use ($meal, $readyCallback, $deliveredCallback, $deferredReady)\n        {\n            echo $readyCallback($meal);\n            $deferredReady->resolve($meal);\n\n                \n        });\n        // Encadenar la siguiente etapa - Delivered\n        $deferredReady->promise()->then(function($meal) use ($deliveredCallback)\n        {\n            Loop::addTimer(rand(1,10), function() use ($meal, $deliveredCallback)\n            {\n                \n                echo $deliveredCallback($meal);\n            });\n        });\n    });\n}\n\nfunction confirm(string $order) : string \n{\n    return \"$order confirmed \\n\";\n}\n\n\nfunction ready(string $order) : string \n{\n    return \"$order ready! \\n\";\n}\n\n\nfunction deliver(string $order) : string \n{\n   return \"Order delivered!, Enjoy your $order 😋 \\n\";\n}\n\n\n\n# Orders in queue\n\nprocessOrder('Big Mac 🍔', 'confirm', 'ready', 'deliver');\nprocessOrder('Happy Meal 🍟','confirm', 'ready', 'deliver');\nprocessOrder('Mcflurry 🍦', 'confirm', 'ready', 'deliver');\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/Aldroide.py",
    "content": "\"\"\"\n    Explora el concepto de callback en tu lenguaje creando un ejemplo\n    simple (a tu elección) que muestre su funcionamiento.\n\"\"\"\n\nimport random\nimport time\nimport threading\n\n\ndef saludar(nombre, callback):\n    print(\"Ejecutando saludo...\")\n    callback(nombre)\n\n\ndef EntradaUsuario(nombre):\n    print(f\"Hola, {nombre}!\")\n\n\nsaludar(\"aldo\", EntradaUsuario)\n\n\"\"\"DIFICULTAD EXTRA (opcional):\n    Crea un simulador de pedidos de un restaurante utilizando callbacks.\n    Estará formado por una función que procesa pedidos.\n    - Debe aceptar el nombre del plato, una callback de confirmación, una de listo y otra de entrega.\n    - Debe imprimir un confirmación cuando empiece el procesamiento.\n    - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre procesos.\n    - Debe invocar a cada callback siguiendo un orden de procesado.\n    - Debe notificar que el plato está listo o ha sido entregado.\n\"\"\"\n\n\n# Definir las funciones callback\ndef order_process(dish, confirm_callback, ready_callback, delivered_callback):\n    def process():\n        confirm_callback(dish)\n        # Simula el tiempo de preparación\n        prep_time = random.randint(1, 10)\n        time.sleep(prep_time)\n        ready_callback(dish)\n        # Simula el tiempo de entrega\n        delivery_time = random.randint(1, 10)\n        time.sleep(delivery_time)\n        delivered_callback(dish)\n    threading.Thread(target=process).start()\n\n\ndef confirm(dish: str):\n    print(f\"Pedido confirmado: {dish}\")\n\n\ndef ready(dish: str):\n    print(f\"Plato listo: {dish}\")\n\n\ndef delivered(dish: str):\n    print(f\"Pedido entregado: {dish}\")\n\n# Función que procesa los pedidos\n\n\n# Simular el procesamiento de un pedido\ndish = input(\"¿Que desea ordenar? \")\norder_process(\"Limon\", confirm, ready, delivered)\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/CaveroBrandon.py",
    "content": "\"\"\" EJERCICIO\nExplora el concepto de callback en tu lenguaje creando un ejemplo\nsimple (a tu elección) que muestre su funcionamiento.\"\"\"\n\nimport asyncio\nimport requests\nimport random\n\n\nasync def async_function(callback):\n    results = api_call()\n    print('Async function started')\n    print('loading 10%')\n    await asyncio.sleep(0.5)\n    print('loading 30%')\n    await asyncio.sleep(1)\n    print('loading 60%')\n    await asyncio.sleep(0.5)\n    print('loading 90%')\n    await asyncio.sleep(1)\n    print(\"Async operation completed\")\n    callback(results)\n\n\ndef api_call():\n    response = requests.get('https://www.boredapi.com/api/activity')\n    if response.status_code == 200:\n        return dict(response.json())\n    else:\n        return 0\n\n\ndef my_callback(activity):\n    if activity != 0:\n        print('**** Bored API ****')\n        print(f'Activity: {activity.get(\"activity\")}')\n        print(f'Type of activity: {activity.get(\"type\")}')\n        print(f'Participants: {activity.get(\"participants\")}')\n        print(f'Price: {activity.get(\"price\")}')\n    else:\n        print('No activity to display')\n\n\nasync def main():\n    await async_function(my_callback)\n\n\n\"\"\"DIFICULTAD EXTRA (opcional):\nCrea un simulador de pedidos de un restaurante utilizando callbacks.\nEstará formado por una función que procesa pedidos.\nDebe aceptar el nombre del plato, una callback de confirmación, una\nde listo y otra de entrega.\n- Debe imprimir un confirmación cuando empiece el procesamiento.\n- Debe simular un tiempo aleatorio entre 1 a 10 segundos entre procesos.\n- Debe invocar a cada callback siguiendo un orden de procesado.\n- Debe notificar que el plato está listo o ha sido entregado.\"\"\"\n\n\ndef show_menu():\n    print('---- Menu ----')\n    print('1. Beef and blue cheese burger')\n    print('2. Roast chicken')\n    print('3. Fish fingers')\n    print('4. Boiled eggs')\n\n\ndef get_order() -> str:\n    try:\n        print('Enter the number of your order: ', end='')\n        selected_order = int(input())\n        if selected_order == 1:\n            return 'Beef and blue cheese burger'\n        elif selected_order == 2:\n            return 'Roast chicken'\n        elif selected_order == 3:\n            return 'Fish fingers'\n        elif selected_order == 4:\n            return 'Boiled eggs'\n        else:\n            print('Select a valid order')\n            get_order()\n    except ValueError:\n        print('Enter a valid number')\n        get_order()\n\n\ndef callback_accept_order(selected_order: str):\n    print(f'Order accepted, processing order \"{selected_order}\"...')\n\n\ndef callback_confirm_order(selected_order: str):\n    print(f'Order confirmed: \"{selected_order}\"...')\n\n\ndef callback_order_completed(selected_order: str):\n    print(f'Order complete: \"{selected_order}\"...')\n\n\ndef callback_order_delivered(selected_order: str):\n    print(f'Order delivered: \"{selected_order}\"')\n\n\nasync def async_order_processing(selected_order: str, accept_order, confirm_order, order_completed, order_delivered):\n    accept_order(selected_order)\n    await asyncio.sleep(random.randint(1, 10))\n    confirm_order(selected_order)\n    await asyncio.sleep(random.randint(1, 10))\n    order_completed(selected_order)\n    await asyncio.sleep(random.randint(1, 10))\n    order_delivered(selected_order)\n\n\nasync def main_order_processing():\n    await async_order_processing(order, callback_accept_order, callback_confirm_order, callback_order_completed, callback_order_delivered)\n\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n    while True:\n        show_menu()\n        order = get_order()\n        asyncio.run(main_order_processing())\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/CesarCarmona30.py",
    "content": "import time\nimport random\n\n\ndef cuando_procesamiento_termina(resultado):\n    print(f\"El procesamiento ha terminado con el resultado: {resultado}\")\n\n\ndef procesar_datos(data, callback):\n    print(\"Procesando datos...\")\n    resultado = sum(data)\n    print(\"Datos procesados.\")\n    callback(resultado)\n\n\ndatos = [1, 2, 3, 4, 5]\n\nprocesar_datos(datos, cuando_procesamiento_termina)\n\n\n'''\n  EXTRA\n'''\n\n\ndef procesador_pedidos(plato, confirmacion, listo, entrega):\n    print(f'Procesando plato: {plato}')\n    tiempo_confirmacion = random.randint(1, 10)\n    print(\n        f\"Confirmación del pedido, tiempo estimado {tiempo_confirmacion} segundos\")\n    time.sleep(tiempo_confirmacion)\n    confirmacion()\n\n    tiempo_procesamiento = random.randint(1, 10)\n    print(f\"Tiempo de procesamiento estimado: {tiempo_procesamiento} segundos\")\n    time.sleep(tiempo_procesamiento)\n    listo()\n\n    tiempo_entrega = random.randint(1, 10)\n    print(f\"Tiempo de entrega estimada: {tiempo_entrega} min\")\n    print(\"Entregando plato...\")\n    time.sleep(tiempo_entrega)\n    entrega()\n\n\ndef confirmar_pedido():\n    print(\"Pedido confirmado.\")\n\n\ndef plato_listo():\n    print(\"El plato está listo.\")\n\n\ndef plato_entregado():\n    print(\"El plato ha sido entregado al cliente.\")\n\n\nprocesador_pedidos(\"Pizza\", confirmar_pedido, plato_listo, plato_entregado)\nprocesador_pedidos(\"Pollo frito\", confirmar_pedido,\n                   plato_listo, plato_entregado)\nprocesador_pedidos(\"Tacos\", confirmar_pedido, plato_listo, plato_entregado)\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/Chrisdev00.py",
    "content": "\"\"\"\n* EJERCICIO:\n* Explora el concepto de callback en tu lenguaje creando un ejemplo\n* simple (a tu elección) que muestre su funcionamiento.\n*\n* DIFICULTAD EXTRA (opcional):\n* Crea un simulador de pedidos de un restaurante utilizando callbacks.\n* Estará formado por una función que procesa pedidos.\n* Debe aceptar el nombre del plato, una callback de confirmación, una\n* de listo y otra de entrega.\n* - Debe imprimir un confirmación cuando empiece el procesamiento.\n* - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n*   procesos.\n* - Debe invocar a cada callback siguiendo un orden de procesado.\n* - Debe notificar que el plato está listo o ha sido entregado.\n\"\"\"\n\nimport asyncio\n\nasync def main():\n    await task_callback(tarea(), callback)\n\nasync def task_callback(tarea, callback):\n    await tarea\n    callback()\n\nasync def tarea():\n    print(\"Sumando numeros..\")\n    await asyncio.sleep(2)\n    print(\"Task finished\")\n\ndef callback():\n    print(\"Funcion callback invocada despues de completar task\")\n\nasyncio.run(main())\n\n\n#############  ---------------------------- EXTRA --------------------------  #################\n\nimport random\n\nmenu = [\"Hamburguesa\", \"Pizza\", \"Tacos\", \"Ensalada Cesar\", \"Pollo Frito\"]\n\nasync def order_process(plato, confir_callback, ready_callback, entrega_callback):\n    \n    confir_callback(plato)\n    preparation_time = random.randint(1,10)\n    print(f\"Preparando {plato}... (espera {preparation_time} segundos)\")\n    await asyncio.sleep(preparation_time)\n\n    ready_callback(plato)\n    delivery_time = random.randint(1,10)\n    print(f\"Entregando {plato}... (espera {delivery_time} segundos)\")\n    await asyncio.sleep(delivery_time)\n\n    entrega_callback(plato)\n\ndef confir_callback(plato):\n    print(f\"Pedido Confirmado: {plato}\")\n\ndef ready_callback(plato):\n    print(f\"Pedido listo: {plato}\")\n\ndef entrega_callback(plato):\n    print(f\"Pedido entregado: {plato}\")\n\n\ndef mostrar_menu_y_pedido():\n    print(\"Menu de platos disponible:\")\n    for id, plato in enumerate(menu, start=1):\n        print(f\"{id}: {plato}\")\n\n    while True:\n        try:\n            pedido= int(input(\"\\nIngrese el numero de plato que desea pedir: \"))\n            if 1 <= pedido <= len(menu):\n                return menu[pedido - 1]\n            else:\n                print(\"Numero invalido, porfavor intente nuevamente.\")\n        except ValueError:\n            print(\"Entrada invalida, porfavor ingrese un numero.\")\n\n\nasync def realizar_pedido():\n    print(\"Simulador de pedidos de un restaurante\\n\")\n\n    plato_elegido = mostrar_menu_y_pedido()\n    tarea = order_process(plato_elegido, confir_callback, ready_callback, entrega_callback)\n\n    await tarea    \n\nif __name__ == \"__main__\":\n    asyncio.run(realizar_pedido())\n\n\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/EmmanuelMMontesinos.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Explora el concepto de callback en tu lenguaje creando un ejemplo\n * simple (a tu elección) que muestre su funcionamiento.\n */\n\"\"\"\n\n# Callback\n\ndef mi_callback(numero):\n    for n in range(numero):\n        print(f\"Llamada a Callback nº {n+1} de {numero}\")\n\ndef ping(numero,callback):\n    if numero > 0:\n        callback(numero)\n    else:\n        print(f\"{numero} no es mayor a 0\")\n\nping(20,mi_callback)\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n * Estará formado por una función que procesa pedidos.\n * Debe aceptar el nombre del plato, una callback de confirmación, una\n * de listo y otra de entrega.\n * - Debe imprimir un confirmación cuando empiece el procesamiento.\n * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n *   procesos.\n * - Debe invocar a cada callback siguiendo un orden de procesado.\n * - Debe notificar que el plato está listo o ha sido entregado.\n\"\"\"\nfrom time import sleep\nfrom random import randint\nimport threading\n\ndef proceso_pedido(plato,confirmacion,listo,entregado):\n    def proceso():\n        confirmacion(plato)\n\n        tiempo_listo = randint(1,10)\n        sleep(tiempo_listo)\n        listo(plato,tiempo_listo)\n\n        tiempo_entregado = randint(1,10)\n        sleep(tiempo_entregado)\n        entregado(plato,tiempo_entregado)\n    threading.Thread(target=proceso).start()\ndef confirmacion(plato):\n    print(f\"{plato} ha sido confirmado, pronto estara listo.\")\n\ndef listo(plato,tiempo):\n    print(f\"{plato} esta listo en {tiempo}s\")\n\ndef entregado(plato,tiempo):\n    print(f\"{plato} ha sido entregado en {tiempo}s\")\n\nproceso_pedido(\"Tortilla de patatas\",confirmacion,listo,entregado)\nproceso_pedido(\"Burger XXL\",confirmacion,listo,entregado)\nproceso_pedido(\"Cordero Asado\",confirmacion,listo,entregado)"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/FedeAirala.py",
    "content": "# #21 CALLBACKS\n\"\"\"\n * EJERCICIO:\n * Explora el concepto de callback en tu lenguaje creando un ejemplo\n * simple (a tu elección) que muestre su funcionamiento.\n\"\"\"\n\n\n\ndef saludar(name):\n    return (f\"Hola {name}\")\n\ndef ejecutar_saludo(saluda, name):\n    return saluda(name)\n\nprint (ejecutar_saludo(saludar,\"Fede\"))\n \nnum = (8,7)\n\ndef multiplicar(num):\n    return num[0]*num[1]\n\ndef multiplicados(mult,n):\n    return mult(n)\n\nprint (multiplicados(multiplicar,num))\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n * Estará formado por una función que procesa pedidos.\n * Debe aceptar el nombre del plato, una callback de confirmación, una\n * de listo y otra de entrega.\n * - Debe imprimir un confirmación cuando empiece el procesamiento.\n * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n *   procesos.\n * - Debe invocar a cada callback siguiendo un orden de procesado.\n * - Debe notificar que el plato está listo o ha sido entregado.\n\"\"\" \n\nimport time\nimport random\nimport threading\n\ndef pedidos(plato,confirmado,listo,entregado):\n    def ejecutar():\n        confirmado(plato)\n        time.sleep(random.randint(1,10))\n        listo(plato)\n        time.sleep(random.randint(1,10))\n        entregado(plato)\n    threading.Thread(target=ejecutar).start()\n    \n\ndef confirmado(plato):\n    print (f\"El pedido de {plato} ha sido confirmado\")\n\ndef listo(plato):\n    print (f\"El pedido de {plato} está listo\")\n\ndef entregado(plato):\n    print (f\"El pedido de {plato} ha sido entregado\")\n\npedidos (\"Pizza\",confirmado,listo,entregado)\npedidos (\"Hamburguesa\",confirmado,listo,entregado)\npedidos (\"Empanadas\",confirmado,listo,entregado)"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/Gordo-Master.py",
    "content": "# 21 - Callbacks\n\nimport asyncio\nimport random\n\ndef end_process():\n    print(\"Proceso terminado.\")\n\ndef count_number(num, fun):\n    for i in range(num):\n        print(i+1)\n    fun()\n\ncount_number(6,end_process)\n\ndef greeting_process(callback, name):\n    print(\"Ejecutando el proceso de saludo....\")\n    callback(name)\n\ndef greet_callback(name: str):\n    print(f\"Hola {name}!\")\n\ngreeting_process(greet_callback, \"Gordo Master\")\n\n\"\"\"\nEjercicio Extra\n\"\"\"\n\nasync def confir(name):\n    print(f\"Pedido de: {name} confirmado\")\n\nasync def order_ok(name):\n    print(f\"Pedido de: {name} esta listo\")\n\nasync def delivered(name):\n    print(f\"Pedido de: {name} fue entregado\")\n\nasync def order(name,confir_callback,order_ok_callback,delivered_callback):\n    await confir_callback(name)\n    await asyncio.sleep(random.randint(1,10))\n    \n    await order_ok_callback(name)\n    await asyncio.sleep(random.randint(1,10))\n    \n    await delivered_callback(name)\n\nasync def main():\n    await asyncio.gather(\n    order(\"Hamburguesa\",confir,order_ok,delivered),\n    order(\"Papas fritas\",confir,order_ok,delivered),\n    order(\"Gaseosa\",confir,order_ok,delivered),\n    order(\"Helado\",confir,order_ok,delivered)\n    )\n\nasyncio.run(main())"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/Irenetitor.py",
    "content": "import random\nimport time\nimport threading\n\n#Exercise\ndef call_twice(callback):\n    print(\"About to call the callback...\")\n    callback()\n    callback()\n    print(\"Done!\")\n\n\ndef greeting():\n    print(\"Hello!\")\n\ncall_twice(greeting)\n\n#Extra Exercise\n\ndef order_process(dish_name: str, confirm_order, order_ready, order_delivered):\n    def orders():\n        confirm_order(dish_name)\n        time.sleep(random.randint(1, 10))\n        order_ready(dish_name)\n        time.sleep(random.randint(1, 10))\n        order_delivered(dish_name)\n\n    threading.Thread(target=orders).start()\n\ndef confirm_order(dish_name: str):\n    print(f\"Your {dish_name} order has been received and is being prepared.\")\n\ndef order_ready(dish_name: str):\n    print(f\"Your {dish_name} is cooked and ready for delivery\")\n\ndef order_delivered(dish_name: str):\n    print(f\"Your {dish_name} has been delivered. Enjoy your meal! :)\")\n\n\norder_process(\"Spicy Chicken wings\", confirm_order, order_ready, order_delivered)\norder_process(\"Chicken tenders\", confirm_order, order_ready, order_delivered)\norder_process(\"French fries\", confirm_order, order_ready, order_delivered)\norder_process(\"Caesar salad\", confirm_order, order_ready, order_delivered)"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/JesusWay69.py",
    "content": "import os, time, random\nos.system('cls')\n\n\n\n\"\"\"\n * EJERCICIO:\n * Explora el concepto de callback en tu lenguaje creando un ejemplo\n * simple (a tu elección) que muestre su funcionamiento.\n *\n \"\"\"\ndef show_result(result):#Esta función callback imprime el resltado que ha devuelto la función de suma\n    print(\"El resultado es: \",result)\n    print()\n\ndef main_funtcion (fun, args,callback):#Creamos una función principal con los argumentos de:\n        # otra función, los argumentos de esta y una o varias llamadas callback a otra/s funcion/es\n    result = fun(*args)#Le indicamos que la función debe retornar un resultado a partir de sus argumentos\n    callback(result)#Definimos la función callback a la que le pasamos ese resultado\n\ndef sum(a,b):\n    return a + b\nmain_funtcion(sum, (5,7), callback=show_result)#Llamamos a la función principal pasando la de sum, \n        # sus argumentos y la llamada a la función callback\n\n\"\"\"* DIFICULTAD EXTRA (opcional):\n * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n * Estará formado por una función que procesa pedidos.\n * Debe aceptar el nombre del plato, una callback de confirmación, una\n * de listo y otra de entrega.\n * - Debe imprimir un confirmación cuando empiece el procesamiento.\n * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n *   procesos.\n * - Debe invocar a cada callback siguiendo un orden de procesado.\n * - Debe notificar que el plato está listo o ha sido entregado.\"\"\"\n\ndef processing(state,args,callback1,callback2,callback3):\n    result = state(args)\n    if result == None:\n        return\n    callback1(result)#Las llamadas callback así como la función que lanza los pedidos  \n    callback2(result)# se harán en el el orden establecido\n    callback3(result)# aunque las funciones estén desordenadas como en este caso\n    \ndef ready(food:str)->str:\n    print(F\"El plato de {food} está listo para servir\")\n    seconds = random.randint(1,10)\n    time.sleep(seconds)\n    return food\n\ndef delivery(food:str):\n    print(F\"El plato de {food} está servido\")\n    seconds = random.randint(1,10)\n    time.sleep(seconds)\n    print()\n\ndef orders(foods:list)->str:\n    if len(foods)==0:\n        return\n    return foods.pop(0)#Esta función gestiona los pedidos por orden de llegada (FIFO)\n\ndef confirmation(food:str)->str:\n    print(F\"El plato de {food} se ha confirmado\")\n    seconds = random.randint(1,10)\n    time.sleep(seconds)\n    return food\n\n\n           \nfoods = [\"ensalada\", \"paella\", \"lentejas\"]\n\nwhile len(foods)>0:\n    processing(orders,foods, callback1=confirmation, callback2=ready,callback3=delivery) "
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/JheisonQuiroga.py",
    "content": "# Author: Jheison Duban Quiroga Quintero\n# Github: https://github.com/JheisonQuiroga\n\n\"\"\"\n/*\n * EJERCICIO:\n * Explora el concepto de callback en tu lenguaje creando un ejemplo\n * simple (a tu elección) que muestre su funcionamiento.\n\"\"\"\n\ndef greet(name):\n    return f\"Hello, {name}!\"\n\n\ndef call_func(func, name):\n    \"\"\"Función de orden superior que recibe un callback greet y un nombre\n    Args:\n        func (function): function callback\n        name (str): name to greet\n    Returns:\n        str: greeting message\n    \"\"\"\n\n    return func(name)\n\n\nprint(call_func(greet, \"Duban\")) # Hello, Duban!\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n * Estará formado por una función que procesa pedidos.\n * Debe aceptar el nombre del plato, una callback de confirmación, una\n * de listo y otra de entrega.\n * - Debe imprimir un confirmación cuando empiece el procesamiento.\n * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n *   procesos.\n * - Debe invocar a cada callback siguiendo un orden de procesado.\n * - Debe notificar que el plato está listo o ha sido entregado.\n */\n\"\"\"\n\nfrom typing import Callable\nimport random\nimport asyncio\nfrom enum import Enum, verify, UNIQUE\nfrom time import time\n\n@verify(UNIQUE)\nclass OrderStatus(Enum):\n    PENDING = \"pending\"\n    CONFIRMED = \"confirmed\"\n    READY = \"ready\"\n    DELIVERED = \"delivered\"\n\n\nasync def process_order(\n        dish: str,\n        confirm_callback: Callable,\n        ready_callback: Callable,\n        deliver_callback: Callable,\n        status: OrderStatus = OrderStatus.PENDING\n    ):\n\n    current_status = {\n        OrderStatus.PENDING: \"Pendiente\",\n        OrderStatus.CONFIRMED: \"Confirmado\",\n        OrderStatus.READY: \"Listo\",\n        OrderStatus.DELIVERED: \"Entregado\"\n    }\n\n    if not isinstance(dish, str) or dish == \"\":\n        raise ValueError(\"Ingrese un nombre de plato valido\")\n\n    \"\"\"Process an order\"\"\" \n    print(f\"Procesando pedido del plato: {dish}, estado: {current_status[status]}\")\n    status = await confirm_callback()\n    print(f\"Pedido de {dish}, estado: {current_status[status]}\")\n    status = await ready_callback()\n    print(f\"Pedido de {dish}, estado: {current_status[status]}\")\n    status = await deliver_callback()\n    print(f\"Pedido de {dish}, estado: {current_status[status]}\")\n\n\n# Callback de confirmación\nasync def confirm_order(status: OrderStatus = OrderStatus.CONFIRMED):\n    start_time = time()\n    await asyncio.sleep(random.randint(1, 10))\n    time_spend_in_task = time() - start_time\n    print(f\"Tiempo de espera {time_spend_in_task:.2f} segundos\")\n    return status\n\n# Callback de listo\nasync def ready_order(status: OrderStatus = OrderStatus.READY):\n    start_time = time()\n    await asyncio.sleep(random.randint(1, 10))\n    time_spend_in_task = time() - start_time\n    print(f\"Tiempo de espera {time_spend_in_task:.2f} segundos\")\n    return status\n\n\n# Callback de entrega\nasync def deliver_order(status: OrderStatus = OrderStatus.DELIVERED):\n    start_time = time()\n    await asyncio.sleep(random.randint(1, 10))\n    time_spend_in_task = time() - start_time\n    print(f\"Tiempo de espera {time_spend_in_task:.2f} segundos\")\n    return status\n\n\nif __name__ == \"__main__\":\n    dish = input(\"Ingrese el nombre del plato: \")\n\n    try:\n        asyncio.run(process_order(dish, confirm_order, ready_order, deliver_order))\n    except ValueError as e:\n        print(e)"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/JuanDAW37.py",
    "content": "\"\"\"\n* EJERCICIO:\n * Explora el concepto de callback en tu lenguaje creando un ejemplo\n * simple (a tu elección) que muestre su funcionamiento.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n * Estará formado por una función que procesa pedidos.\n * Debe aceptar el nombre del plato, una callback de confirmación, una\n * de listo y otra de entrega.\n * - Debe imprimir un confirmación cuando empiece el procesamiento.\n * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n *   procesos.\n * - Debe invocar a cada callback siguiendo un orden de procesado.\n * - Debe notificar que el plato está listo o ha sido entregado.\n\"\"\"\nimport random\nimport time\nimport threading # Se usa para trabajar con hilos\n\ndef saludo(nombre:str):\n    print('Ejecutando el proceso de saludar')\n    print(f'Hola {nombre}!!')\n    \ndef saludar(nombre:str, callback): # Callback, función que recibe como parámetro otra función\n    print('Llamando al proceso de saludar')\n    callback(nombre)\n    \nsaludar('Luis',saludo) # Se llama a la función saludar, que recibe el callback\n\n# EXTRA\ndef procesarPedido(comida:str, confirmar_callback, listo_callback, entregado_callback):\n    def procesar(): # Creamos esta función recursiva para ejecutar el hilo. Ejecución multihilo\n        print(f'Comenzando el proceso de preparación de {comida}')    \n        time.sleep(random.randint(1, 10)) # Paramos entre 1 y 10 segundos la ejecución\n        confirmar_callback(comida)\n        time.sleep(random.randint(1, 10)) \n        listo_callback(comida)\n        time.sleep(random.randint(1, 10)) \n        entregado_callback(comida)\n    threading.Thread(target=procesar).start() #Ejecutamos el hilo\n\ndef confirmarPedido(comida:str):\n    print(f'Pedido {comida} confirmado!!!')\n\ndef listoPedido(comida:str):\n    print(f'Pedido {comida} listo para enviar!!!')\n    \ndef entregadoPedido(comida:str):\n    print(f'Pedido {comida} ha sido entregado!!!')\n\nprocesarPedido('Churrasco', confirmarPedido, listoPedido, entregadoPedido)\nprocesarPedido('Callos', confirmarPedido, listoPedido, entregadoPedido)\nprocesarPedido('Carne asada', confirmarPedido, listoPedido, entregadoPedido)\nprocesarPedido('Tortilla de patatas con cebolla', confirmarPedido, listoPedido, entregadoPedido)"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/Marlonleon2023.py",
    "content": "\"\"\"/*\n * EJERCICIO:\n * Explora el concepto de callback en tu lenguaje creando un ejemplo\n * simple (a tu elección) que muestre su funcionamiento.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n * Estará formado por una función que procesa pedidos.\n * Debe aceptar el nombre del plato, una callback de confirmación, una\n * de listo y otra de entrega.\n * - Debe imprimir un confirmación cuando empiece el procesamiento.\n * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n *   procesos.\n * - Debe invocar a cada callback siguiendo un orden de procesado.\n * - Debe notificar que el plato está listo o ha sido entregado.\n */\"\"\"\n\n\"\"\"callback\"\"\"\n\nimport asyncio\nimport random\nasync def async_task(llamarDevuelta):\n    print(\"Iniciando Tarea...\")\n    await asyncio.sleep(2)\n    print(\"Tarea completa \")\n    llamarDevuelta()\n    \ndef my_callback():\n    print(\"Callback ejecutando despues de la tarea asincrona\")\n    \nasyncio.run(async_task(my_callback))\n\n\n\"\"\"DIFICULTAD EXTRA\"\"\"\n\nasync def procesoOrden(idOrden,callback):\n    print(f\"Pedido {idOrden} recibido. Procesando....\")\n    await asyncio.sleep(random.uniform(1,3))\n    print(f\"Pedido {idOrden} completado\")\n    callback(idOrden)\n    \ndef notifyPersona(idOrden):\n    print(f\"Notificacion: El pedido {idOrden} esta listo para ser recojido/enviado.\")\n    \nasync def main():\n    ordenesIds=[1,2,3]\n    tareas=[procesoOrden(idOrden,notifyPersona) for idOrden in ordenesIds]\n    await asyncio.gather(*tareas)\n\nasyncio.run(main())"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/Mauricio-Leyva.py",
    "content": "\"\"\"\nEjercicio\n\"\"\"\ndef apply_discount(prices, discount_function):\n  \"\"\"Aplica un descuento a cada precio en una lista.\n\n  Args:\n    prices: Una lista de precios.\n\n    discount_function: Una función que calcula el descuento.\n  \"\"\"\n  discounted_prices = []\n  for price in prices:\n    discounted_price = discount_function(price)\n    discounted_prices.append(discounted_price)\n  return discounted_prices\n\ndef ten_percent_off(price):\n  return price * 0.9\n\ndef twenty_percent_off(price):\n  return price * 0.8\n\nprices = [100, 50, 25, 75]\n\ndiscounted_prices_10 = apply_discount(prices, ten_percent_off)\ndiscounted_prices_20 = apply_discount(prices, twenty_percent_off)\n\nprint(\"Original Prices:\", prices)\nprint(\"10% Off:\", discounted_prices_10)\nprint(\"20% Off:\", discounted_prices_20)\n\n\n\"\"\"\nDificultad extra\n\"\"\"\n\nimport time\nimport random\n\ndef process_order(dish_name, confirmation_callback, ready_callback, delivery_callback):\n  \"\"\"Simula el procesamiento de un pedido de restaurante con callbacks.\n\n  Args:\n    dish_name: El nombre del plato ordenado.\n\n    confirmation_callback: Función a llamar al confirmar el pedido.\n\n    ready_callback: Función a llamar cuando el plato esté listo.\n\n    delivery_callback: Función a llamar al entregar el pedido.\n  \"\"\"\n  confirmation_callback(dish_name)  \n\n  print(f\"Preparing {dish_name}...\")\n  processing_time = random.randint(1, 10)  \n  time.sleep(processing_time)\n\n  ready_callback(dish_name) \n\n  print(f\"Delivering {dish_name}...\")\n  time.sleep(random.randint(1, 10))  \n\n  delivery_callback(dish_name) \n\n# Callback\ndef on_confirmation(dish):\n  print(f\"Order confirmed: {dish}\")\n\ndef on_ready(dish):\n  print(f\"{dish} is ready!\")\n\ndef on_delivery(dish):\n  print(f\"{dish} has been delivered. Enjoy!\")\n\n# Simula una orden\nprocess_order(\n    \"Pizza\",\n    on_confirmation,\n    on_ready,\n    on_delivery\n)"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/Nicojsuarez2.py",
    "content": "# #21 CALLBACKS\n> #### Dificultad: Media | Publicación: 20/04/24 | Corrección: 27/05/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Explora el concepto de callback en tu lenguaje creando un ejemplo\n * simple (a tu elección) que muestre su funcionamiento.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n * Estará formado por una función que procesa pedidos.\n * Debe aceptar el nombre del plato, una callback de confirmación, una\n * de listo y otra de entrega.\n * - Debe imprimir un confirmación cuando empiece el procesamiento.\n * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n *   procesos.\n * - Debe invocar a cada callback siguiendo un orden de procesado.\n * - Debe notificar que el plato está listo o ha sido entregado.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/Pipe281.py",
    "content": "'''\n * EJERCICIO:\n * Explora el concepto de callback en tu lenguaje creando un ejemplo\n * simple (a tu elección) que muestre su funcionamiento.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n * Estará formado por una función que procesa pedidos.\n * Debe aceptar el nombre del plato, una callback de confirmación, una\n * de listo y otra de entrega.\n * - Debe imprimir un confirmación cuando empiece el procesamiento.\n * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n *   procesos.\n * - Debe invocar a cada callback siguiendo un orden de procesado.\n * - Debe notificar que el plato está listo o ha sido entregado.\n'''\nimport time\nimport random\n\ndef mi_callback(name: str):\n    print(f\"Hola\", name)\n\ndef llamadora(name: str, callback):\n    print(\"Antes del callback\")\n    callback(name)\n    print(\"Después del callback\")\n\nllamadora(\"Pipe\", mi_callback)\n\n\n'''\nTarea extra\n'''\n\ndef orden (nombre_plato: str, confirmacion_orden, orden_lista, orden_entregada):\n    confirmacion_orden(nombre_plato)\n    time.sleep(random.randint(1,10))\n    orden_lista(nombre_plato)\n    time.sleep(random.randint(1,10))\n    orden_entregada(nombre_plato)\n\ndef confirmacion_orden (nombre_plato: str):\n    print (f\"Tu pedido {nombre_plato} a sido confirmado.\")\n\ndef orden_lista (nombre_plato: str):\n    print (f\"Tu pedido {nombre_plato} esta listo.\")\n\ndef orden_entregada (nombre_plato: str):\n    print (f\"Tu pedido {nombre_plato} a sido entregado.\")\n\norden (\"Churrasco\", confirmacion_orden, orden_lista, orden_entregada)"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/Sac-Corts.py",
    "content": "import time\nimport random\n\ndef process_data(data, function_callback): \n    for element in data:\n        function_callback(element)\n\ndef print_data(data):\n    print(f\"El dato es: {data}\")\n\ndef squared_data(data):\n    print(f\"El cuadrado del dato es: {data ** 2}\")\n\ndata = [1, 2, 3, 4, 5]\nprocess_data(data, print_data)\nprocess_data(data, squared_data)\n\n### Ejercicio Extra ###\n\ndef order_process(dish: str, callback_confirmation, callback_ready, callback_delivered):\n    callback_confirmation(dish)\n    preparation_time = random.randint(1, 15)\n    time.sleep(preparation_time)\n\n    callback_ready(dish)\n    delivery_time = random.randint(1, 30) \n    time.sleep(delivery_time)\n\n    callback_delivered(dish)\n\ndef order_confirm(dish):\n    print(f\"Pedido confirmado: {dish}\")\n\ndef order_ready(dish):\n    print(f\"Pedido listo: {dish}\")\n\ndef order_delivered(dish):\n    print(f\"Pedido {dish} ha sido entregado.\")\n\ndishes_names = [\"Pizza Margherita\", \"Sushi\", \"Hamburguesa\", \"Tacos\", \"Ensalada César\"]\ndish_random = random.choice(dishes_names)\norder_process(dish_random, order_confirm, order_ready, order_delivered)"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/SooHav.py",
    "content": "# 21 - CALLBACKS\n\n# Ejercicio\n\n\"\"\" Un callback es una función que se pasa como argumento a otra función.\nEsta función \"callback\" se invoca en algún punto de la ejecución de\nla función que la recibe como argumento.\"\"\"\n\n\nimport random\nimport time\n\n\ndef conversion_F_a_C(temperatura: float, funcion):\n    # Funcion que pasa grados Farengheint a grados Centigrados\n    resultado = temperatura-32 * 0.555\n    funcion(resultado)\n\n\ndef mostrar_resultado(resultado):\n    print(f\"El resultado es: {resultado}\")\n\n\nconversion_F_a_C(46.5, mostrar_resultado)\n\n\n# Dificultad Extra\n\n\ndef confirmar_menu(mensaje):\n    while True:\n        respuesta = input(f\"{mensaje} (sí/no): \").strip().lower()\n        if respuesta == \"sí\" or respuesta == \"si\":\n            return True\n        elif respuesta == \"no\":\n            return False\n        else:\n            print(\"Respuesta no válida. Por favor responde 'sí' o 'no'.\")\n\n\ndef pedido_listo(menu, cliente):\n    print(f\"El menú {menu} del cliente {\n          cliente} está listo para ser entregado.\")\n\n\ndef pedido_en_entrega(menu, cliente):\n    print(f\"El menú {menu} del cliente {cliente} fue entregado.\")\n\n\ndef simulador_de_pedidos(confirmacion=pedido_listo, servicio=pedido_listo, entrega=pedido_en_entrega):\n    print(\"Iniciando el procesamiento del pedido...\")\n    id = list(range(1, 11))\n    try:\n        menu = int(input(\"Seleccione un menú (1-10): \"))\n    except ValueError:\n        print(\"Debes proporcionar un número válido para el menú.\")\n        return\n\n    cliente = input(\"Indica el número de cliente: \").strip()\n\n    if not cliente:\n        print(\"Debes proporcionar un número de cliente.\")\n        return\n\n    if menu in id:\n        print(f\"Ud. ha elegido el menú número {menu}.\")\n    else:\n        print(f\"Ud. ha elegido el menú número {\n              menu} que no está dentro de nuestra carta, seleccione nuevamente.\")\n        return\n\n    if confirmar_menu(\"¿Confirma su elección?\"):\n        print(\"Confirmando menú, se envía a cocina...\")\n        time.sleep(random.randint(1, 10))\n        if confirmacion:\n            confirmacion(menu, cliente)\n    else:\n        print(\"Acción cancelada\")\n        return\n\n    print(\"Preparando el pedido...\")\n    time.sleep(random.randint(1, 10))\n    if servicio:\n        servicio(menu, cliente)\n\n    print(\"Entregando el pedido...\")\n    time.sleep(random.randint(1, 10))\n    if entrega:\n        entrega(menu, cliente)\n\n\n# Ejemplo de uso\nsimulador_de_pedidos()\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/Trufoplus.py",
    "content": "#######################  EJERCICIO  ###########################################\n\ndef my_callback(callback):\n    print('Haciendo algo....')\n    task = 'Tarea terminada.'\n    callback(task)\n\ndef result(task):\n    print(task)\n\nmy_callback(result)\n\n\n###############################################################################\n### DIFICULTAD EXTRA\n###############################################################################\nfrom time import sleep\nfrom random import randint\n\ndef process_order(confirmation):\n    print('\\n\\nConfirmando el pedido...')\n    random_time()\n    status = 'Plato confirmado'\n    confirmation(status)\n    \n    sleep(1)\n    print('Preparando el plato...')\n    random_time()\n    ready = 'Plato listo para servir'\n    confirmation(ready)\n    \n    sleep(1)\n    print('Entregando plato a la mesa...')\n    random_time()\n    delivery = 'Plato entregado'\n    confirmation(delivery)\n\ndef confirmation(status):\n    print(status)\n\ndef random_time():\n    random_time = randint(1, 10)\n    print(f'Tiempo de espera: {random_time} segundos\\n')\n    sleep(random_time)    \n\nprocess_order(confirmation)\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/adra-dev.py",
    "content": "\"\"\"\nEJERCICIO:\nExplora el concepto de callback en tu lenguaje creando un ejemplo\nsimple (a tu elección) que muestre su funcionamiento.\n\nDIFICULTAD EXTRA (opcional):\nCrea un simulador de pedidos de un restaurante utilizando callbacks.\nEstará formado por una función que procesa pedidos.\nDebe aceptar el nombre del plato, una callback de confirmación, una\nde listo y otra de entrega.\n- Debe imprimir un confirmación cuando empiece el procesamiento.\n- Debe simular un tiempo aleatorio entre 1 a 10 segundos entre \nprocesos.\n- Debe invocar a cada callback siguiendo un orden de procesado.\n- Debe notificar que el plato está listo o ha sido entregado.\n\nby adra-dev\n\"\"\"\n\n\"\"\"\nCALLBACKS:\n    Un callback es un concepto general en Python como en otros \n    lenguajes como Javascript, C, etc. Como sabemos Pyton es un\n    lenguaje orientado a objetos y las funciones en python son \n    ciudadanos de primer orden. Esto significa que podemos asignar\n    el valor devuelto por una funcion a una variable y devolver el \n    resultado de una funcion llamandola desde el interior de otra.\n    documentacion: https://www.askpython.com/python/built-in-methods/callback-functions-in-python \n\"\"\"\n\n\"\"\"\nSe desea mostrar un mensaje que muestre si un alumno aprobo el curso\no no segun su promedio\n\"\"\"\n\n# Definimos la funcion promedio\n\npromedio = lambda *args: sum(args) / len(args)\n\n# definimos la condicion de si el promedio es aprobatorio o no \naprobatorio = lambda calificacion : calificacion >=7\n\n# Definimos la funcion mostrar mensaje que va llamar a las otras 2 funciones como argumentos\ndef mostrar_mensaje(func_promedio, func_aporbatorio, *args):\n    promedio = func_promedio(*args)\n\n    if func_aporbatorio(promedio):\n        print(f'Felicidades, aprobaste la materia con {promedio}.')\n    else:\n        print('No aprobaste la materia.')\n\nmostrar_mensaje(promedio, aprobatorio, 10, 10 , 8, 7, 7)\nmostrar_mensaje(promedio, aprobatorio, 0, 2, 5, 6, 9, 3)\n\n\"\"\"\nEXTRA\n\"\"\"\nimport random\nimport time\nimport threading\n\n\n\ndef order_process(dish_name: str, confirm_callback, ready_callback, delivered_callback):\n    def process():\n            confirm_order(dish_name)\n            time.sleep(random.randint(1,10))\n            order_ready(dish_name)\n            time.sleep(random.randint(1,10))\n            order_delivered(dish_name)\n\n\n    threading.Thread(target=process).start()\n\n\ndef confirm_order(dish_name: str):\n    print(f\"Tu pedido {dish_name} ha sido confirmado.\")\n\n\ndef order_ready(dish_name: str):\n    print(f\"Tu pedido {dish_name} esta listo.\")\n\n\ndef order_delivered(dish_name: str):\n    print(f\"Tu pedido {dish_name} ha sido entregado.\")\n\n\norder_process(\"Pizza Barbacoa\", confirm_order, order_ready, order_delivered)\norder_process(\"Pizza 4 Quesos\", confirm_order, order_ready, order_delivered)\norder_process(\"Pizza Margarita\", confirm_order, order_ready, order_delivered)\norder_process(\"Pizza Pepperoni\", confirm_order, order_ready, order_delivered)"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/agusrosero.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Explora el concepto de callback en tu lenguaje creando un ejemplo\n * simple (a tu elección) que muestre su funcionamiento.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n * Estará formado por una función que procesa pedidos.\n * Debe aceptar el nombre del plato, una callback de confirmación, una\n * de listo y otra de entrega.\n * - Debe imprimir un confirmación cuando empiece el procesamiento.\n * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n *   procesos.\n * - Debe invocar a cada callback siguiendo un orden de procesado.\n * - Debe notificar que el plato está listo o ha sido entregado.\n */\n\"\"\"\nimport random\nimport time\nimport asyncio\n\n# EJERCICIO:\n\n\nasync def procesar_evento(callback):\n    print(\"Iniciamos proceso asincrono\")\n    await asyncio.sleep(1)\n    print(\"Llamando al callback\")\n    callback()\n\n\ndef mi_callback():\n    print(\"Callback ejecutado\")\n\n\nasyncio.run(procesar_evento(mi_callback))\n\n# DIFICULTAD EXTRA:\n\n\ndef procesar_pedido(plato, callback_confirmacion, callback_listo, callback_entrega):\n    callback_confirmacion(plato)\n\n    tiempo_procesamiento = random.randint(1, 10)\n    time.sleep(tiempo_procesamiento)\n\n    callback_listo(plato)\n\n    tiempo_entrega = random.randint(1, 10)\n    time.sleep(tiempo_entrega)\n\n    callback_entrega(plato)\n\n\ndef confirmar_pedido(plato):\n    print(f\"Confirmación: El pedido del plato {\n          plato} ha sido recibido y está en proceso.\")\n\n\ndef pedido_listo(plato):\n    print(f\"Listo: El plato {plato} está listo para ser entregado.\")\n\n\ndef entregar_pedido(plato):\n    print(f\"Entregado: El plato {plato} ha sido entregado al cliente.\")\n\n\nplato = \"Empanadas de Pollo\"\nprocesar_pedido(plato, confirmar_pedido, pedido_listo, entregar_pedido)\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/alanshakir.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Explora el concepto de callback en tu lenguaje creando un ejemplo\n * simple (a tu elección) que muestre su funcionamiento.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n * Estará formado por una función que procesa pedidos.\n * Debe aceptar el nombre del plato, una callback de confirmación, una\n * de listo y otra de entrega.\n * - Debe imprimir un confirmación cuando empiece el procesamiento.\n * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n *   procesos.\n * - Debe invocar a cada callback siguiendo un orden de procesado.\n * - Debe notificar que el plato está listo o ha sido entregado.\n */\n\"\"\"\nimport time\nimport random\n\ndef called(n):\n    return n[0] * n[1]\n\ndef caller(func, n):\n    return func(n)\n\nnum = (8, 5)\nans = caller(called, num)\n\nprint(f\"Multiplicación = {ans}\")\n\ndef orders(food, order_process, order_confirmation, order_delivered):\n    print(f\"su pedido es {food}\")\n    order_process(food)\n    time.sleep(random.randint(1, 10))\n    order_confirmation(food)\n    time.sleep(random.randint(1, 10))\n    order_delivered(food)\n\ndef order_process(food):\n    print(f\"Su orden de {food} esta siendo procesada\")\n\ndef order_confirmation(food):\n    print(f\"Su orden de {food} esta lista\")\n\ndef order_delivered(food):\n    print(f\"Su orden de {food} esta siendo entregada\")\n\norders(\"Pizza\", order_process, order_confirmation, order_delivered)\norders(\"Hamburguesa\", order_process, order_confirmation, order_delivered)\norders(\"sushi\", order_process, order_confirmation, order_delivered)\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/any7dev.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Explora el concepto de callback en tu lenguaje creando un ejemplo\n * simple (a tu elección) que muestre su funcionamiento.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n * Estará formado por una función que procesa pedidos.\n * Debe aceptar el nombre del plato, una callback de confirmación, una\n * de listo y otra de entrega.\n * - Debe imprimir un confirmación cuando empiece el procesamiento.\n * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n *   procesos.\n * - Debe invocar a cada callback siguiendo un orden de procesado.\n * - Debe notificar que el plato está listo o ha sido entregado.\n */ \"\"\"\n\n#EJERCICIO\ndef multiplicar(numeros):\n    return numeros[0]*numeros[1]\n\ndef llamar(funcion, numeros):\n    return funcion(numeros)\n\ntupla = (3, 9)\nresultado = llamar(multiplicar, tupla)\nprint(resultado)\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/avcenal.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el concepto de callback en tu lenguaje creando un ejemplo\n * simple (a tu elección) que muestre su funcionamiento.\n\"\"\"\ndef sum_five_to_value(value):\n    return value + 5 \n\ndef add_five_to_value(value,func):\n    return func(value)\n\nprint(add_five_to_value(5,sum_five_to_value))\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n * Estará formado por una función que procesa pedidos.\n * Debe aceptar el nombre del plato, una callback de confirmación, una\n * de listo y otra de entrega.\n * - Debe imprimir un confirmación cuando empiece el procesamiento.\n * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n *   procesos.\n * - Debe invocar a cada callback siguiendo un orden de procesado.\n * - Debe notificar que el plato está listo o ha sido entregado.\n\"\"\"\nfrom time import sleep\nfrom random import randint\n\ndef begin_processing(plate):\n    time = randint(1,10)\n    print (f\"El plato {plate} ha empezado a procesarse y tardará en estar procesado {time} min...\")\n    sleep(time)\n\ndef plate_ready(plate):\n    time = randint(1,10)\n    print(f\"El plato {plate} estará listo en {time} min...\")\n    sleep(time)\n\ndef plate_delivered(plate):\n    time = randint(1,10)\n    print(f\"El plato {plate} será entregado en {time} min...\")\n    sleep(time)\n\ndef main(plate,func_begin,func_ready,func_delivered):\n    func_begin(plate)\n    func_ready(plate)\n    func_delivered(plate)\n    print(f\"El plato {plate} ha sido entregado!!\\n\")\n\nplate = \"Pollo con Almendras\"\nmain(plate,begin_processing,plate_ready,plate_delivered)\nplate = \"Macarrones con Queso\"\nmain(plate,begin_processing,plate_ready,plate_delivered)\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/cesar-ch.py",
    "content": "\"\"\"\n    * 20 PETICIONES HTTP \n\"\"\"\n\n\ndef greet(name, callback):\n    print(f\"Hello, {name}!\")\n    callback()\n\n\ndef say_goodbye():\n    print(\"Goodbye!\")\n\n\ngreet(\"Mouredev\", say_goodbye)\n\n\n\"\"\"\n    * DIFICULTAD EXTRA\n\"\"\"\nimport time\nimport random\n\n\ndef procesar_pedido(plato, confirmacion_callback, listo_callback, entrega_callback):\n    print(f\"Procesando pedido para: {plato}\")\n    confirmacion_callback(plato)\n\n    tiempo_preparacion = random.randint(1, 10)\n    print(\"El tiempo de preparacion es: \" + str(tiempo_preparacion))\n    time.sleep(tiempo_preparacion)\n    listo_callback(plato)\n\n    tiempo_entrega = random.randint(1, 10)\n    print(\"El tiempo de entrega es: \" + str(tiempo_entrega))\n    time.sleep(tiempo_entrega)\n    entrega_callback(plato)\n\n\ndef confirmar_pedido(plato):\n    print(f\"Pedido confirmado para: {plato}\")\n\n\ndef plato_listo(plato):\n    print(f\"El plato {plato} está listo para ser entregado.\")\n\n\ndef entregar_pedido(plato):\n    print(f\"El plato {plato} ha sido entregado.\")\n\n\nif __name__ == \"__main__\":\n    procesar_pedido(\"Pizza\", confirmar_pedido, plato_listo, entregar_pedido)\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/cristianfloyd.py",
    "content": "# EJERCICIO:\n# Explora el concepto de callback en tu lenguaje creando un ejemplo\n# simple (a tu elección) que muestre su funcionamiento.\nimport random\nimport threading\nimport time\n\ndef funcion_principal(num1: int, num2: int, callback):\n    print(f\"Suma de {num1} y {num2}\")\n    callback(num1 + num2)\n\n\ndef callback_resultado(resultado: int) -> None:\n    print(f\"El resultado de la suma es: {resultado}\")\n\n\nfuncion_principal(5, 3, callback_resultado)\n\n#\n# DIFICULTAD EXTRA (opcional):\n# Crea un simulador de pedidos de un restaurante utilizando callbacks.\n# Estará formado por una función que procesa pedidos.\n# Debe aceptar el nombre del plato, una callback de confirmación, una\n# de listo y otra de entrega.\n# - Debe imprimir un confirmación cuando empiece el procesamiento.\n# - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n#   procesos.\n# - Debe invocar a cada callback siguiendo un orden de procesado.\n# - Debe notificar que el plato está listo o ha sido entregado.\n\n\n\n\ndef procesar_pedido(\n    pedido: str,\n    callback_confirmacion,\n    callback_listo,\n    callback_entrega,\n) -> None:\n    def process():\n        print(f\"Procesando pedido: {pedido}\")\n        tiempo = random.randint(1, 10)\n        callback_confirmacion(pedido, tiempo)\n        tiempo = random.randint(1, 10)\n        callback_listo(pedido, tiempo)\n        tiempo = random.randint(1, 10)\n        callback_entrega(pedido, tiempo)\n\n    threading.Thread(target=process).start()\n\n\n# definicion de callbacks\ndef callback_confirmacion(pedido: str, tiempo: int) -> None:\n    time.sleep(tiempo)\n    print(f\"Pedido {pedido} confirmado después de {tiempo} segundos\")\n\n\ndef callback_listo(pedido: str, tiempo: int) -> None:\n    time.sleep(tiempo)\n    print(f\"Pedido {pedido} listo después de {tiempo} segundos\")\n\n\ndef callback_entrega(pedido: str, tiempo: int) -> None:\n    time.sleep(tiempo)\n    print(f\"Pedido {pedido} entregado después de {tiempo} segundos\")\n\n\n# ejemplo de uso\n\nif __name__ == \"__main__\":\n    print(\"=\" * 50)\n    print(\"Simulador de pedidos de un restaurante\")\n    print(\"=\" * 50)\n    plato = input(\"Ingrese el nombre del plato: \")\n    if plato:\n        procesar_pedido(plato, callback_confirmacion, callback_listo, callback_entrega)\n    else:\n        pedidos = [\n            \"Pizza de pepperoni\",\n            \"Hamburguesa con queso\",\n            \"Ensalada\",\n            \"Sopa de fideos\",\n            \"Flan\",\n        ]\n        for i, pedido in enumerate(pedidos):\n            tiempo = random.randint(1, 5)\n            time.sleep(tiempo)\n            print(f\"Pedido {i + 1} de {len(pedidos)}\")\n            procesar_pedido(\n                pedido, callback_confirmacion, callback_listo, callback_entrega\n            )\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/danielhdzr.py",
    "content": "# #21 CALLBACKS\n# Dificultad: Media | Publicación: 20/04/24 | Corrección: 27/05/24\n\n## Ejercicio\n\n\n'''/*\n * EJERCICIO:\n * Explora el concepto de callback en tu lenguaje creando un ejemplo\n * simple (a tu elección) que muestre su funcionamiento.\n */\n'''\n# Ej. 1 Callback sincrono\n# Definicion de una funcion\ndef saludo(callback): # Parametro callback\n    print(\"Antes del callback\")\n    callback() # Llamado a funcion\n    print(\"Después del callback\")\n\n# Definicion de una funcion\ndef decir_hola():\n    print(\"¡Hola!\")\n\n# Llamado a funcion\nsaludo(decir_hola) \n''' Toma como arg. a la funcion decir_hola() que sustituye el parametro callback, \nahora decir_hola() sera llamada dentro de la funcion saludo en lugar de la funcion callback()'''\n\n'''/////////////////////////////////////////////////////////////////////////'''\n# Ej. 2 Callback asincrono\nimport time\nimport threading\n\n# Definicion de una funcion\ndef mi_callback(resultado):\n    print(f\"Resultado procesado: {resultado}\")\n\n# Definicion de una funcion\ndef tarea_larga(callback):\n    print(\"Iniciando tarea...\")\n    time.sleep(2)  # Simulación de tarea larga\n    resultado = \"Tarea completada\"\n    callback(resultado)\n\n# Llamada en un hilo separado\nthreading.Thread(target=tarea_larga, args=(mi_callback,)).start() # (Objeto, arg.,) inicio\n\n# Ej. 3\ndef mi_callback(resultado):\n    print(f\"El resultado es: {resultado}\")\n\ndef operacion_asincrona(callback):\n    resultado = 42  # Simulación de un resultado\n    callback(resultado)  # Llama al callback con el resultado\n\n# Usar el callback\noperacion_asincrona(mi_callback)\nprint()\n\n'''\n* DIFICULTAD EXTRA (opcional):\n * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n * Estará formado por una función que procesa pedidos.\n * Debe aceptar el nombre del plato, una callback de confirmación, una\n * de listo y otra de entrega.\n * - Debe imprimir un confirmación cuando empiece el procesamiento.\n * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n *   procesos.\n * - Debe invocar a cada callback siguiendo un orden de procesado.\n * - Debe notificar que el plato está listo o ha sido entregado.\n'''\n\n# Simulador de pedidos de restaurante\nimport asyncio\nimport random\n\n# Lapso aleatorio para cada etapa\ndef generar_lapso():\n    return random.uniform(1, 10)\n\n# Función principal que inicia el proceso\nasync def funcion_principal(orden):\n    print(f\"Pedido recibido: {orden}\")\n    # Iniciar la cadena de callbacks\n    await pedido(orden, confirmacion_pedido)\n\n# Pedido\nasync def pedido(orden, callback):\n    lapso = generar_lapso()\n    print(f\"Procesando pedido: {orden} (espera de {lapso:.2f} segundos)\")\n    await asyncio.sleep(lapso)\n    print(f\"Pedido {orden} realizado\")\n    # Llamar al siguiente callback\n    await callback(orden, pedido_listo)\n\n# Confirmación del pedido\nasync def confirmacion_pedido(orden, callback):\n    lapso = generar_lapso()\n    print(f\"Confirmando pedido: {orden} (espera de {lapso:.2f} segundos)\")\n    await asyncio.sleep(lapso)\n    print(f\"Pedido {orden} confirmado\")\n    # Llamar al siguiente callback\n    await callback(orden, pedido_entregado)\n\n# Pedido listo\nasync def pedido_listo(orden, callback):\n    lapso = generar_lapso()\n    print(f\"Preparando pedido: {orden} (espera de {lapso:.2f} segundos)\")\n    await asyncio.sleep(lapso)\n    print(f\"Pedido {orden} listo\")\n    # Llamar al siguiente callback\n    await callback(orden, None)\n\n# Pedido entregado\nasync def pedido_entregado(orden, callback):\n    lapso = generar_lapso()\n    print(f\"Entregando pedido: {orden} (espera de {lapso:.2f} segundos)\")\n    await asyncio.sleep(lapso)\n    print(f\"Pedido {orden} entregado. ¡Gracias por tu compra!\")\n    # Este es el último paso, no hay más callbacks\n\n# Capturar la orden\norden = input(\"Platillo a ordenar: \")\n\n# Ejecutar el flujo\nasyncio.run(funcion_principal(orden))\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/davidrguez98.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Explora el concepto de callback en tu lenguaje creando un ejemplo\n * simple (a tu elección) que muestre su funcionamiento.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n * Estará formado por una función que procesa pedidos.\n * Debe aceptar el nombre del plato, una callback de confirmación, una\n * de listo y otra de entrega.\n * - Debe imprimir un confirmación cuando empiece el procesamiento.\n * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n *   procesos.\n * - Debe invocar a cada callback siguiendo un orden de procesado.\n * - Debe notificar que el plato está listo o ha sido entregado.\n */ \"\"\"\n\nimport random\nimport time\n\n#EJERCICIO\n\ndef greeting_process(name: str, callback):\n    callback(name)\n\ndef greet_callback(name: str):\n    print(f\"Hola {name}.\")\n\ngreeting_process(\"David\", greet_callback)\n\n\n#DIFICULTAD EXTRA\n\ndef order(dish_name: str, confirmation_callback, ready_callback, delivered_callback):\n    dish_name = input(\"¿Qué quieres pedir?: \").lower()\n    confirmation_callback(dish_name)\n    time.sleep(random.randint(1, 10))\n    ready_callback(dish_name)\n    time.sleep(random.randint(1, 10))\n    delivered_callback(dish_name)\n\ndef order_confirmation(dish_name: str):\n    print(f\"Tu pedido {dish_name.lower()} ha sido confirmado.\")\n\n\ndef order_ready(dish_name: str):\n    print(f\"Tu pedido {dish_name.lower()} está listo.\")\n\ndef order_delivered(dish_name: str):\n    print(f\"Tu pedido {dish_name.lower()} ha sido entregado.\")\n\norder(\"\", order_confirmation, order_ready, order_delivered)"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/didacdev.py",
    "content": "import asyncio\nfrom random import randint\n\nplates = []\ntasks = []\n\n\nclass Plate:\n    id: int\n    name: str\n\n    def __init__(self, id, name):\n        self.id = id\n        self.name = name\n\n\nasync def confirmation(data: (int, str)):\n    await asyncio.sleep(randint(1, 10))\n    print(f\"\\n✅ Plato {data[0]} preparado\\n\")\n\n\nasync def create_plate(callback, plate_data: (int, str)):\n    plate = Plate(plate_data[0], plate_data[1])\n    plates.append(plate)\n    print(\"Plato en preparación\")\n    task = asyncio.create_task(callback(plate_data))\n    tasks.append(task)\n\n\ndef plate_given(id: int):\n    given = False\n    for plate in plates:\n        if plate.id == id:\n            plates.remove(plate)\n            print(\"Plato entregado\")\n            given = True\n            break\n\n    if not given:\n        print(\"❌ Plato no encontrado\")\n\n\nasync def async_input(prompt):\n    return await asyncio.to_thread(input, prompt)\n\n\nasync def main():\n    exit = False\n\n    while not exit:\n        print(\"\\nSelecciona una opción:\\n\"\n              \"1 - Introduce plato:\\n\"\n              \"2 - Indicar plato entregado\\n\"\n              \"3 - Salir\")\n        choice = int(await async_input(\"> \"))\n\n        if choice == 1:\n            plate_name = input(\"Nombre del plato: \")\n            plate_id = len(plates) + 1\n            await create_plate(confirmation, (plate_id, plate_name))\n        elif choice == 2:\n            id = int(input(\"ID del plato: \"))\n            plate_given(id)\n        elif choice == 3:\n            print(\"Hasta pronto 👋\")\n            exit = True\n        else:\n            print(\"⚠️ Opción errónea\")\n\n    # Espera a que todas las tareas se hayan completado antes de terminar\n    await asyncio.gather(*tasks)\n\n\nif __name__ == '__main__':\n    asyncio.run(main())\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/duendeintemporal.py",
    "content": "#21 { Retos para Programadores } CALLBACKS\n\n# Bibliography reference\n#Secrets of the JavaScript Ninja (John Resig, Bear Bibeault, Josip Maras) (z-lib.org)\n#Eloquent Javascript A Modern Introduction to Programming by Marijn Haverbeke (z-lib.org)\n#Python Notes for Professionals. 800+ pages of professional hints and tricks (GoalKicker.com) (Z-Library)\n# Additionally, I use GPT as a reference and sometimes to correct or generate proper comments.\n\n\"\"\"   \n* EJERCICIO:\n * Explora el concepto de callback en tu lenguaje creando un ejemplo\n * simple (a tu elección) que muestre su funcionamiento.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n * Estará formado por una función que procesa pedidos.\n * Debe aceptar el nombre del plato, una callback de confirmación, una\n * de listo y otra de entrega.\n * - Debe imprimir un confirmación cuando empiece el procesamiento.\n * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n *   procesos.\n * - Debe invocar a cada callback siguiendo un orden de procesado.\n * - Debe notificar que el plato está listo o ha sido entregado.\n\n\"\"\"\n\nimport random\nimport threading\n\n# Function to simulate console.log\nlog = print\n\nlog('Retosparaprogramadores #21.')\n\n# Function to confirm an order\ndef order_confirm(order, callback):\n    log(f'The order: {order} is confirmed. Tell you when it\\'s ready.')\n    processing_time = random.randint(1, 10)  # Random processing time between 1 and 10 seconds\n    threading.Timer(processing_time, callback, args=[order]).start()\n\n# Function to indicate that the order is ready\ndef order_ready(order, callback):\n    log(f'The order: {order} is ready. Waiting to deliver.')\n    delivery_time = random.randint(1, 10)  # Random delivery time between 1 and 10 seconds\n    threading.Timer(delivery_time, callback, args=[order]).start()\n\n# Function to deliver the order\ndef order_deliver(order):\n    log(f'Order: {order} delivered.')\n\n# Function to make an order\ndef make_order(list_order):\n    today_menu = ['pizza', 'hamburger', 'paella', 'arabian food', 'posole', \n                  'pastel azteca', 'carbonara past', 'napolitana past', 'fish', 'beef']\n    \n    for order in list_order:\n        if any(elm.lower() == order.lower() for elm in today_menu):\n            order_confirm(order, lambda confirmed_order: order_ready(confirmed_order, order_deliver))\n        else:\n            log(f'The order: {order} is not in today\\'s menu. Please choose another dish.')\n\n\n    \norder_list1 = ['pastiche', 'hamburger', 'pizza']\norder_list2 = ['arabian food', 'fish', 'pastel azteca']\nmake_order(order_list1)\nmake_order(order_list2)\n\n# Output Example:\n\"\"\"  \nRetosparaprogramadores #21.\nThe order: pastiche is not in today's menu. Please choose another dish.\nThe order: hamburger is confirmed. Tell you when it's ready.\nThe order: pizza is confirmed. Tell you when it's ready.\nThe order: arabian food is confirmed. Tell you when it's ready.\nThe order: fish is confirmed. Tell you when it's ready.\nThe order: pastel azteca is confirmed. Tell you when it's ready.\nThe order: hamburger is ready. Waiting to deliver.\nThe order: fish is ready. Waiting to deliver.\nOrder: fish delivered.\nThe order: arabian food is ready. Waiting to deliver.\nThe order: pastel azteca is ready. Waiting to deliver.\nOrder: hamburger delivered.\nThe order: pizza is ready. Waiting to deliver.\nOrder: pastel azteca delivered.\nOrder: arabian food delivered.\nOrder: pizza delivered.\n\n\"\"\" "
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/fborjalv.py",
    "content": "import time\nimport random\nimport threading\n\n\"\"\"\n/*\n * EJERCICIO:\n * Explora el concepto de callback en tu lenguaje creando un ejemplo\n * simple (a tu elección) que muestre su funcionamiento.\n\"\"\"\ndef saludar(name):\n    print(f\"¿Cómo estás? {name}\")\n\ndef ejecutar_callback(name, callback):\n    print(\"Este saludo es está ejecutando desde una callback: \")\n    callback(name)\n\nsaludar(\"Borja\")\n\nejecutar_callback(\"Mouredev\", saludar)\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n * Estará formado por una función que procesa pedidos.\n * Debe aceptar el nombre del plato, una callback de confirmación, una\n * de listo y otra de entrega.\n * - Debe imprimir un confirmación cuando empiece el procesamiento.\n * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n *   procesos.\n * - Debe invocar a cada callback siguiendo un orden de procesado.\n * - Debe notificar que el plato está listo o ha sido entregado.\n */\n\n\"\"\"\n\n\ndef order_process(dish, confirm, ready, delivering):\n    def process():\n        print(f\"Hemos recibido su pedido que incluye {dish}\")\n        time.sleep(random.randint(1, 10))\n        confirm(dish)\n        ready(dish)\n        delivering(dish)\n    threading.Thread(target=process).start()\n\ndef confirm_callback(dish):\n    print(f\"Su pedido que incluye {dish} se está procesando\")\n    time.sleep(random.randint(1, 10))\n\ndef ready_callback(dish):\n    print(f\"Su pedido que incluye {dish} está listo. Se entregará en los próximos minutos\")\n    time.sleep(random.randint(1, 10))\n\ndef deliver_callback(dish):\n    print(f\"Su pedido que incluye {dish} ha sido entregado correctamente\")\n\n\norder_process(\"gambas\", confirm_callback, ready_callback, deliver_callback)\norder_process(\"ternera\", confirm_callback, ready_callback, deliver_callback)\norder_process(\"mouse\", confirm_callback, ready_callback, deliver_callback)"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/garos01.py",
    "content": "import time\n\n\n# Función simulada que toma un tiempo para completarse\ndef funcion_asincrona(callback):\n    print(\"La función asincrónica está realizando alguna tarea...\")\n    time.sleep(2)  # Simulando una tarea que toma tiempo\n    print(\"La función asincrónica ha completado su tarea.\")\n    callback()  # Llamada al callback después de completar la tarea\n\n\n# Callback que se ejecutará después de que la función asincrónica termine\ndef mi_callback():\n    print(\"¡El callback ha sido llamado!\")\n\n\n# Llamada a la función asincrónica pasando el callback como argumento\nfuncion_asincrona(mi_callback)\n\n\n# Ejercicio extra\n\nimport random\n\n\n# Función de procesamiento de pedidos\ndef procesar_pedido(\n    nombre_plato, callback_confirmacion, callback_listo, callback_entrega\n):\n    # Confirmar que el pedido ha sido recibido\n    print(f\"Recibiendo el pedido para: {nombre_plato}\")\n    callback_confirmacion(nombre_plato)\n\n    # Simular tiempo de preparación\n    tiempo_preparacion = random.randint(1, 10)\n    time.sleep(tiempo_preparacion)\n\n    # Notificar que el plato está listo\n    print(\n        f\"El plato {nombre_plato} está listo después de {tiempo_preparacion} segundos.\"\n    )\n    callback_listo(nombre_plato)\n\n    # Simular tiempo de entrega\n    tiempo_entrega = random.randint(1, 10)\n    time.sleep(tiempo_entrega)\n\n    # Notificar que el plato ha sido entregado\n    print(\n        f\"El plato {nombre_plato} ha sido entregado después de {tiempo_entrega} segundos.\"\n    )\n    callback_entrega(nombre_plato)\n\n\n# Callbacks\ndef confirmacion_pedido(nombre_plato):\n    print(\n        f\"Confirmación: El pedido para {nombre_plato} ha sido recibido y está en proceso.\"\n    )\n\n\ndef plato_listo(nombre_plato):\n    print(f\"Notificación: El pedido para {nombre_plato} está listo para servir.\")\n\n\ndef entrega_pedido(nombre_plato):\n    print(f\"Notificación: El pedido para {nombre_plato} ha sido entregado al cliente.\")\n\n\n# Ejemplo\nprocesar_pedido(\"Pizza\", confirmacion_pedido, plato_listo, entrega_pedido)\nprocesar_pedido(\"Hamburguesa\", confirmacion_pedido, plato_listo, entrega_pedido)\nprocesar_pedido(\"Ensalada\", confirmacion_pedido, plato_listo, entrega_pedido)\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/ggilperez.py",
    "content": "# 21 Callbacks\nimport random\nimport time\n\n\ndef long_process(callback):\n    print(\"Starting process\")\n    time.sleep(2)\n    callback()\n\n\ndef process_completed():\n    print(\"Process completed\")\n\n\nlong_process(process_completed)\n\n\n# Extra\n\ndef process_order(dish, confirm_callback, ready_callback, deliver_callback):\n    print(f\"Processing {dish}\")\n    confirm_callback(dish)\n    time.sleep(random.randint(1, 10))\n    ready_callback(dish)\n    time.sleep(random.randint(1, 10))\n    deliver_callback(dish)\n\n\ndef confirm(dish):\n    print(f\"{dish} confirmed\")\n\n\ndef ready(dish):\n    print(f\"{dish} ready\")\n\n\ndef deliver(dish):\n    print(f\"{dish} delivered\")\n\nprocess_order(\"Fish and chips\", confirm, ready, deliver)"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/gringoam.py",
    "content": "import random\nimport time\nimport threading\n\"\"\"\nEjercicio\n\"\"\"\n\ndef proceso_prin(nom: str, fun_prin):\n    fun_prin(nom)\n\ndef imp_nom(nom:str):\n    print(nom)\n\nproceso_prin(\"Diego\", imp_nom)\n\n\"\"\"\nExtra\n\"\"\"\n\ndef procesa_pedidos(plato, conf_pedido, conf_listo, conf_entregado ):\n    def proceso():\n\n        conf_pedido(plato)\n        time.sleep(random.randint(1,10))\n        conf_listo(plato)\n        time.sleep(random.randint(1,10))\n        conf_entregado(plato)\n    threading.Thread(target=proceso).start()\n\ndef confirmar_pedido(producto:str):\n    print(f\"El pedido de {producto} fue confirmado\")\n\ndef pedido_listo(producto:str):\n    print(f\"El pedido de {producto} ya está listo\")\n\ndef pedido_entregado(producto:str):\n    print(f\"El pedido de {producto} fue esntregado\")\n\n\nprocesa_pedidos(\"Ravioles\", confirmar_pedido, pedido_listo, pedido_entregado)\nprocesa_pedidos(\"Milanesa\", confirmar_pedido, pedido_listo, pedido_entregado)\nprocesa_pedidos(\"Pizza\", confirmar_pedido, pedido_listo, pedido_entregado)\n    \n\n\n\n\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/hectorio23.py",
    "content": "# Autor: Héctor Adán \n# GitHub: https://github.com/hectorio23\n\n'''\nEJERCICIO:\nExplora el concepto de callback en tu lenguaje creando un ejemplo\nsimple (a tu elección) que muestre su funcionamiento.\n\nDIFICULTAD EXTRA (opcional):\nCrea un simulador de pedidos de un restaurante utilizando callbacks.\nEstará formado por una función que procesa pedidos.\nDebe aceptar el nombre del plato, una callback de confirmación, una\nde listo y otra de entrega.\n\n- Debe imprimir un confirmación cuando empiece el procesamiento.\n- Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n  procesos.\n- Debe invocar a cada callback siguiendo un orden de procesado.\n- Debe notificar que el plato está listo o ha sido entregado.\n\n'''\n\nimport asyncio\nimport random\n\n#########################################################\n##################### EJERCICIO 1 #######################\n#########################################################\n\nconsole_log = lambda message: print(f\"Mensage impreso por el callback: { message }\")\n\ndef do_something(msg: str, callback: callable) -> None:\n    console_log(msg)\n\n\ndo_something(\"¡Hola Mundo!\", console_log)\n\nprint(\"\\n****************** EJERCICIO EXTRA *******************\\n\")\n\n#########################################################\n################### EJERCICIO EXTRA #####################\n#########################################################\n\n# Corrutina que confirma el pedido, por defecto es Falso\ndef confirmacion(nombre_plato: str, check: bool) -> bool:\n    print(f\"[Confirmacion] - ¿Usted desea confirmar el pedido llamado \\\"{ nombre_plato }\\\"?: { 'Yes' if check else 'No' }\")\n\n    if check: return True\n\n    return False\n\n# Corrutina que imprime si el pedido está listo\nasync def listo(nombre_plato: str, confirmado: bool) -> bool:\n    await asyncio.sleep(random.randint(0, 10))\n    print(f\"[Listo] - El pedido \\\"{ nombre_plato }\\\" está listo para ser entregado\")\n\n# Corrutina que imprime si el pedido ya ha sido entregado\nasync def entrega(nombre_plato: str):\n    await asyncio.sleep(random.randint(0, 10))\n    print(f\"[Entrega] - El pedido \\\"{ nombre_plato }\\\" ha sido entregado\")\n\n# Corrutina que procesa las ordenes\nasync def make_order(nombre_plato: str, confirmacion: callable, listo: callable, entrega: callable, check = False) -> None:\n    confirmado = confirmacion(nombre_plato, check)\n    if not check:\n        print(f\"[Cancelled] - El pedido \\\"{ nombre_plato }\\\" no se confirmó, por lo que se cancelo el pedido\")\n        return None\n    \n    await listo(nombre_plato, confirmado)\n    await entrega(nombre_plato)\n\n\nasync def main():\n    async with asyncio.TaskGroup() as tg:\n        tg.create_task(make_order(\"Papas a la francesa\", confirmacion, listo, entrega, True))\n        tg.create_task(make_order(\"Carne de Cocodrilo a la parrilla\", confirmacion, listo, entrega, False))\n        tg.create_task(make_order(\"Tacos de Pastor\", confirmacion, listo, entrega, True))\n        tg.create_task(make_order(\"Ensalada de Papas con albondigas\", confirmacion, listo, entrega, True))\n\n\n# Ejecucion del ejercicio extra\nwith asyncio.Runner() as rn:\n    rn.run(main())"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/hozlucas28.py",
    "content": "# pylint: disable=pointless-string-statement,missing-function-docstring,missing-module-docstring,unused-argument\n\nfrom random import randrange\nfrom threading import Thread\nfrom time import sleep\nfrom typing import Callable, TypeVar\n\n\"\"\"\n    Callbacks...\n\"\"\"\n\nprint(\"Callbacks...\")\n\nT = TypeVar(\"T\")\n\n\ndef map_list(*, __array: list[T], __callback: Callable[[T, int], T]) -> None:\n    for __index, __value in enumerate(iterable=__array):\n        __array[__index] = __callback(__value, __index)\n\n\nnumbers: list[int] = [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]\nprint(f\"\\nNumbers array before 'map_list' function call: {numbers!r}\")\n\nmap_list(__array=numbers, __callback=lambda value, index: value + 1)\nprint(f\"Numbers array after 'map_list' function call: {numbers!r}\")\n\ncountries: list[str] = [\"Argentina\", \"United States\", \"Spain\", \"Germany\"]\nprint(f\"\\nCountries array before 'map_list' function call: {countries!r}\")\n\nmap_list(__array=countries, __callback=lambda value, index: f\"Are you from {value}?\")\nprint(f\"Countries array after 'map_list' function call: {countries!r}\")\n\nprint(\n    \"\\n# ---------------------------------------------------------------------------------- #\\n\"\n)\n\n\"\"\"\n    Additional challenge...\n\"\"\"\n\nprint(\"Additional challenge...\\n\")\n\n\ndef prepare_dish(\n    *,\n    dish_name: str,\n    on_confirm: Callable[[str], None],\n    on_ready: Callable[[str], None],\n    on_deliver: Callable[[str], None],\n) -> None:\n    on_confirm(dish_name)\n\n    random_timeout: int = randrange(start=1, stop=10 + 1, step=1)\n\n    sleep(random_timeout)\n    on_ready(dish_name)\n\n    on_deliver(dish_name)\n\n\nThread(\n    target=prepare_dish,\n    kwargs={\n        \"dish_name\": \"Spaghetti\",\n        \"on_confirm\": lambda dish_name: print(f\"{dish_name} in preparation.\"),\n        \"on_ready\": lambda dish_name: print(f\"{dish_name} is ready to deliver.\"),\n        \"on_deliver\": lambda dish_name: print(f\"{dish_name} delivered.\"),\n    },\n).start()\n\nThread(\n    target=prepare_dish,\n    kwargs={\n        \"dish_name\": \"Soup\",\n        \"on_confirm\": lambda dish_name: print(f\"{dish_name} in preparation.\"),\n        \"on_ready\": lambda dish_name: print(f\"{dish_name} is ready to deliver.\"),\n        \"on_deliver\": lambda dish_name: print(f\"{dish_name} delivered.\"),\n    },\n).start()\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/idiegorojas.py",
    "content": "\"\"\"\nCallbacks\n\"\"\"\n\n# Es una funcion que pasa como argumento a otra\n# La ultima funcion llama de vuelta a la otra funcion\n# Es una forma de manejar tareas asincronicas\n\n# Un callback serai como darle una tareas a un amigo y que este me avise cuando termino\n\ndef saludar(nombre: str):\n    print(f'Hola {nombre}.')\n\ndef ejecutar_callback(funcion, argumento):\n    print('Voy a ejecutar el callback ...')\n    funcion(argumento)\n\nejecutar_callback(saludar, 'Juan')\n\n\n\"\"\"\nUsos\n\"\"\"\n\n# Programación asíncrona: Por ejemplo, en manejo de eventos o cuando esperas que algo termine (como una descarga).\n# Librerías o frameworks: Piensa en una interfaz gráfica (como Tkinter) donde defines qué pasa cuando haces clic en un botón.\n# Procesamiento de datos: Como aplicar una función personalizada a cada elemento de una lista.\n\n\n\"\"\"\nEjemplo:\n\nSupóngamos que pedimos una pizza por teléfono. La pizzería nos dice: \"Te llamamos cuando la pizza esté lista\". Aquí, no sabes exactamente cuándo va a estar lista, pero confíamos en que nos avisarán. Ese \"te llamamos\" es el callback.\n\"\"\"\n\n# Creamos la funcion que prepara la pizza y nos avisa cuando este lista\ndef pedir_pizza(callback):\n    print('Preparando la pizza...')\n    for _ in range(3):\n        print('Hornenando la pizza...')\n    callback()\n\n# Creamos la funcion que avisa cuando la pizza este lista\ndef pizza_lista():\n    print('La pizza esta lista, ven a recogerla.')\n\n# Le damos la orden a la pizzeria de preparla y de avisarnos \npedir_pizza(pizza_lista)\n\n\n\"\"\"\nExtra\n\"\"\"\n\nimport random\nimport time\nimport threading\n\n\ndef proceso_pedidos():\n    nombre_plato = input('Hola, ingresa el nombre del plato que deseas: ')\n    print(f'El plato que elegiste fue {nombre_plato}')\n    confirmacion(nombre_plato)\n    time.sleep(random.randint(1, 10))\n    listo(nombre_plato)\n    time.sleep(random.randint(1, 10))\n    entrega(nombre_plato)\n\n    threading.Thread(target=proceso_pedidos).start()\n\ndef confirmacion(nombre_plato):\n        print(f'Tu plato {nombre_plato} esta en preparacion.')\n\ndef listo(nombre_plato):\n        print(f'Tu pedido de {nombre_plato} esta listo.')\n        print('Lo estamos empacando')\n\ndef entrega(nombre_plato):\n        print(f'Gracias por tu espera. Tu plato {nombre_plato} ha sido entregado.')\n\n\nproceso_pedidos() "
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/ignaciovihe.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el concepto de callback en tu lenguaje creando un ejemplo\n * simple (a tu elección) que muestre su funcionamiento.\n\"\"\"\nimport random\n\nmy_grades = [random.randint(0,10) for i in range (10)]\n\ndef process_grades(grades, callback):\n    return callback(grades)\n\ndef get_passed(grades):\n    return [grade for grade in grades if grade >= 5]\n\ndef get_failed(grades):\n    return [grade for grade in grades if grade < 5]\n\ndef average(grades):\n    return sum(grades) / len(grades)\n\nprint(process_grades(my_grades, get_passed))\nprint(process_grades(my_grades, get_failed))\nprint(process_grades(my_grades, average))\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n * Estará formado por una función que procesa pedidos.\n * Debe aceptar el nombre del plato, una callback de confirmación, una\n * de listo y otra de entrega.\n * - Debe imprimir un confirmación cuando empiece el procesamiento.\n * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n *   procesos.\n * - Debe invocar a cada callback siguiendo un orden de procesado.\n * - Debe notificar que el plato está listo o ha sido entregado.\n\"\"\"\n\nimport time\nimport threading\n\n#print_lock = threading.Lock()  Con esto podría hacer que bloques de codigo fueras sincronos (with print_lock:)\n\ndef confirm_order(order_name):\n    print(f\"Tu pedido {order_name} Ha sido confirmada.\")\n\ndef order_ready(order_name):\n    print(f\"Tu pedido {order_name} esta listo.\")\n\ndef order_delivered(order_name):\n    print(f\"Tu pedido {order_name} Ha sido entregado.\")\n\ndef process_order(order_name, callback_confirm, callback_ready, callback_delivered):\n    \n    def process():\n        callback_confirm(order_name)\n        time.sleep(random.randint(1,10))\n        callback_ready(order_name)\n        time.sleep(random.randint(1,10))\n        callback_delivered(order_name)\n\n    threading.Thread(target=process).start()\n\nprocess_order(\"Pizza Margarita\", confirm_order, order_ready, order_delivered)\nprocess_order(\"Hamburguesa\", confirm_order, order_ready, order_delivered)\nprocess_order(\"Shushi\", confirm_order, order_ready, order_delivered)\nprocess_order(\"Arroz frito\", confirm_order, order_ready, order_delivered)\n\n    \n\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/ikeragi05.py",
    "content": "'''/*\n * EJERCICIO:\n * Explora el concepto de callback en tu lenguaje creando un ejemplo\n * simple (a tu elección) que muestre su funcionamiento.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n * Estará formado por una función que procesa pedidos.\n * Debe aceptar el nombre del plato, una callback de confirmación, una\n * de listo y otra de entrega.\n * - Debe imprimir un confirmación cuando empiece el procesamiento.\n * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n *   procesos.\n * - Debe invocar a cada callback siguiendo un orden de procesado.\n * - Debe notificar que el plato está listo o ha sido entregado.\n */\n```'''\nimport random\nimport time\ndef espera():\n    return random.randint(1,10)\n    \ndef pedido(plato):\n    print(f\"Pedido de {plato} Aceptado\")\n\ndef preparacion(plato):\n    print(f\"{plato} listo para entrega\")\ndef entrega(plato):\n    print(f\"Enviando {plato}...\")\n\ndef proceso(plato, pedido, preparacion, entrega):\n    pedido(plato)\n    time.sleep(espera())\n    preparacion(plato)\n    time.sleep(espera())\n    entrega(plato)\n\nmenu = [\n    \"Ensalada Caprese\",\n    \"Bruschetta\",\n    \"Sopa de Cebolla\",\n    \"Tartar de Salmón\",\n    \"Risotto de Setas\",\n    \"Pollo al Curry\",\n    \"Paella de Mariscos\",\n    \"Lomo de Cerdo a la Mostaza\",\n    \"Tarta de Chocolate\",\n    \"Tiramisú\",\n    \"Cheesecake de Frutos Rojos\",\n    \"Helado Artesanal\"\n]\nprint(\"¿Que desea pedir?\")\nfor i in enumerate(menu):   \n    print(i)\nnum= int(input(\"introduza el numero del plato que desea pedir\\n\"))\nplato = menu[num]\nproceso(plato, pedido, preparacion, entrega)"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/isilanes.py",
    "content": "import random\nfrom time import sleep\n\n\ndef main():\n    print(\"===== MAIN =====\")\n\n    # Definimos funciones que usaremos como callback:\n    def add(a: int, b: int) -> int:\n        return a + b\n\n    def multiply(a: int, b: int) -> int:\n        return a * b\n\n    # Definimos funcion que usa callbacks:\n    def perform_operation(first: int, second: int, operation: callable) -> int:\n        return operation(first, second)\n\n    # Usamos la función con callbacks:\n    assert perform_operation(1, 2, add) == 3\n    assert perform_operation(1, -2, add) == -1\n    assert perform_operation(1, -2, multiply) == -2\n    assert perform_operation(0, -2, multiply) == 0\n    print(\"main() ejecutado con éxito\")\n\n\ndef extra():\n    print(\"===== EXTRA =====\")\n\n    def confirm_base(dish: str) -> None:\n        print(f\"Pedido '{dish}' confirmado!\")\n\n    def confirm_premium(dish: str) -> None:\n        print(f\"Su excelencia, su pedido '{dish}' ha sido confirmado.\")\n\n    def ready_base(dish: str) -> None:\n        print(f\"Pedido '{dish}' listo!\")\n\n    def ready_premium(dish: str) -> None:\n        print(f\"Vuecencia, su pedido '{dish}' está ya listo.\")\n\n    def delivered_base(dish: str) -> None:\n        print(f\"Pedido '{dish}' entregado!\")\n\n    def delivered_premium(dish: str) -> None:\n        print(f\"Alteza, su pedido '{dish}' ha sido ya entregado.\")\n\n    def process_dish(dish: str, user_credit: int) -> None:\n        confirm, ready, delivered = confirm_base, ready_base, delivered_base\n        if user_credit > 1000:\n            confirm, ready, delivered = confirm_premium, ready_premium, delivered_premium\n\n        confirm(dish)\n        sleep(random.randrange(1, 10))\n        ready(dish)\n        sleep(random.randrange(1, 10))\n        delivered(dish)\n\n    process_dish(\"Ostras rellenas de caviar\", user_credit=5000)\n    process_dish(\"Bocata de fuagrás\", user_credit=5)\n\n\nif __name__ == \"__main__\":\n    main()\n    extra()\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/jptxaya.py",
    "content": "# #21 CALLBACKS\n\n## Ejercicio\n\n# /*\n#  * EJERCICIO:\n#  * Explora el concepto de callback en tu lenguaje creando un ejemplo\n#  * simple (a tu elección) que muestre su funcionamiento.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n#  * Estará formado por una función que procesa pedidos.\n#  * Debe aceptar el nombre del plato, una callback de confirmación, una\n#  * de listo y otra de entrega.\n#  * - Debe imprimir un confirmación cuando empiece el procesamiento.\n#  * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n#  *   procesos.\n#  * - Debe invocar a cada callback siguiendo un orden de procesado.\n#  * - Debe notificar que el plato está listo o ha sido entregado.\n#  */\n\nlista = [\"fgd\",\"Fad\",\"gfads\",\"erd\"]\n\nprint(sorted(lista))\n\nprint(sorted(lista,key=str.lower))\n\n\ndef multiplicar(num1, num2):\n    return num1 * num2\n\ndef sumar(num1,num2):\n    return num1 + num2\n\ndef operacion(callback,num1,num2):\n    print(callback(num1,num2))\n\nprint(\"Callback sumar\")\noperacion(sumar,3,2)\nprint(\"Callback multiplicar\")\noperacion(multiplicar,3,2)\n\nprint(\"Dificultad Extra\")\n\nimport random\nimport time\n\ndef confirmacion(plate):\n    print(f\"Plato {plate} confirmado\")\n\ndef ready(plate):\n    print(f\"Plato {plate} listo\")\n\ndef delivered(plate):\n    print(f\"Plato {plate} entregado\")\n\ndef process_order(plate, on_confirmacion,on_ready,on_delivered):\n    on_confirmacion(plate)\n    time.sleep(random.randint(1,10))\n    on_ready(plate)\n    time.sleep(random.randint(1,10))\n    on_delivered(plate)\n    \n\nprocess_order(\"Asado\",confirmacion,ready,delivered)"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/juanmax2.py",
    "content": "\"\"\"\nEjercicio\n\"\"\"\n\ndef funcion_saludo(name: str, saludo):\n    saludo(name)\n    \ndef saludar_base(name: str):\n    print(f\"Hola, {name}\")\n\nfuncion_saludo(\"Juanma\", saludar_base)\nimport random\nimport time\nimport threading\n\"\"\"\n\n * DIFICULTAD EXTRA (opcional):\n * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n * Estará formado por una función que procesa pedidos.\n * Debe aceptar el nombre del plato, una callback de confirmación, una\n * de listo y otra de entrega.\n * - Debe imprimir un confirmación cuando empiece el procesamiento.\n * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n *   procesos.\n * - Debe invocar a cada callback siguiendo un orden de procesado.\n * - Debe notificar que el plato está listo o ha sido entregado.\n\"\"\"\n\ndef proceso_pedido(nombre_plato: str, confirmar_callback, pedido_callback, estado_callback):\n    def process():\n        confirmar_callback(nombre_plato)\n        time.sleep(random.randint(1, 10))\n        pedido_callback(nombre_plato)\n        time.sleep(random.randint(1, 10))\n        estado_callback(nombre_plato)\n    threading.Thread(target=process).start()\n\ndef confirmar_pedido(nombre_plato: str):\n    print(f\"Tu pedido {nombre_plato} ha sido confirmado\")\n    \ndef pedido_listo(nombre_plato: str):\n    print(f\"Tu pedido {nombre_plato} está listo\")\n\ndef estado_pedido(nombre_plato: str):\n    print(f\"Tu pedido {nombre_plato} ha sido entregado\")\n\nproceso_pedido(\"Carbonara\", confirmar_pedido, pedido_listo, estado_pedido )\nproceso_pedido(\"Barbacoa\", confirmar_pedido, pedido_listo, estado_pedido )\nproceso_pedido(\"Nona\", confirmar_pedido, pedido_listo, estado_pedido )\nproceso_pedido(\"4 quesos\", confirmar_pedido, pedido_listo, estado_pedido )"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/juanppdev.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el concepto de callback en tu lenguaje creando un ejemplo\n * simple (a tu elección) que muestre su funcionamiento.\n\"\"\"\n\ndef proceso_principal(callback):\n    print(\"Proceso principal en ejecución...\")\n    # Simulamos una tarea con una pausa\n    import time\n    time.sleep(2)\n    print(\"Proceso principal completado.\")\n    # Llamamos al callback\n    callback()\n\ndef mi_callback():\n    print(\"Callback ejecutado después del proceso principal.\")\n\n# Llamamos a la función principal y le pasamos el callback\nproceso_principal(mi_callback)\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n * Estará formado por una función que procesa pedidos.\n * Debe aceptar el nombre del plato, una callback de confirmación, una\n * de listo y otra de entrega.\n * - Debe imprimir un confirmación cuando empiece el procesamiento.\n * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n *   procesos.\n * - Debe invocar a cada callback siguiendo un orden de procesado.\n * - Debe notificar que el plato está listo o ha sido entregado.\n\"\"\"\n\nimport time\nimport random\n\ndef procesar_pedido(plato, confirmacion_callback, listo_callback, entrega_callback):\n    print(f\"Procesando pedido para {plato}...\")\n    confirmacion_callback(plato)\n    \n    # Simulamos el tiempo de preparación\n    tiempo_preparacion = random.randint(1, 10)\n    time.sleep(tiempo_preparacion)\n    listo_callback(plato)\n    \n    # Simulamos el tiempo de entrega\n    tiempo_entrega = random.randint(1, 10)\n    time.sleep(tiempo_entrega)\n    entrega_callback(plato)\n\ndef confirmar_pedido(plato):\n    print(f\"Pedido confirmado para {plato}.\")\n\ndef plato_listo(plato):\n    print(f\"{plato} está listo para ser entregado.\")\n\ndef entregar_pedido(plato):\n    print(f\"{plato} ha sido entregado al cliente.\")\n\ndef menu():\n    while True:\n        print(\"\\n--- Menú del Restaurante ---\")\n        print(\"1. Hacer un pedido\")\n        print(\"2. Salir\")\n        opcion = input(\"Selecciona una opción: \")\n        \n        if opcion == \"1\":\n            plato = input(\"Introduce el nombre del plato: \")\n            procesar_pedido(plato, confirmar_pedido, plato_listo, entregar_pedido)\n        elif opcion == \"2\":\n            print(\"Saliendo del sistema de pedidos. ¡Gracias!\")\n            break\n        else:\n            print(\"Opción no válida. Por favor, intenta de nuevo.\")\n\n# Ejecutamos el menú\nmenu()\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/kenysdev.py",
    "content": "# ╔═════════════════════════════════════╗\n# ║ Autor:  Kenys Alvarado              ║\n# ║ GitHub: https://github.com/Kenysdev ║\n# ║ 2024 -  Python                      ║\n# ╚═════════════════════════════════════╝\n\n# -----------------------------------\n# * CALLBACKS\n# -----------------------------------\n# https://www.askpython.com/python/built-in-methods/callback-functions-in-python\n\n\"\"\"\n* EJERCICIO #1:\n* Explora el concepto de callback en tu lenguaje creando un ejemplo\n* simple (a tu elección) que muestre su funcionamiento.\n\"\"\"\n\ndef sum_numbers(a: int, b: int, callback: object):\n    if isinstance(a, int) and isinstance(b, int):\n        result = a + b\n        callback((f\"{a} + {b}\"), result)\n\ndef my_callback(summands: str, result: int):\n    if isinstance(summands, str) and isinstance(result, int):\n        print(f\"La suma de {summands} es: {result}\")\n\nprint(\"EJERCICIO #1\")\nsum_numbers(6, 6, my_callback)\nsum_numbers(5, 2, my_callback)\n\n\"\"\"\n* EJERCICIO #2:\n* Crea un simulador de pedidos de un restaurante utilizando callbacks.\n* Estará formado por una función que procesa pedidos.\n* Debe aceptar el nombre del plato, una callback de confirmación, una\n* de listo y otra de entrega.\n* - Debe imprimir un confirmación cuando empiece el procesamiento.\n* - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n*   procesos.\n* - Debe invocar a cada callback siguiendo un orden de procesado.\n* - Debe notificar que el plato está listo o ha sido entregado.\n\"\"\"\n\nfrom random import randint\nimport asyncio\n\nasync def process_order(name: str, confirm, prepare, serving):\n    print(f\"-----\\n* Procesando: '{name}' \\n-----\\n\")\n    await confirm(name)\n    await prepare(name)\n    await serving(name)\n\ndef time_random() -> int:\n    return randint(1, 10)\n\nasync def confirm_order(name: str):\n    time: int = time_random()\n    print(f\"* Confirmando {name}, espere {time} segundos.\")\n    await asyncio.sleep(time)\n    print(f\"- '{name}', ha sido confirmado.\\n\")\n\nasync def prepare_order(name: str):\n    time: int = time_random()\n    print(f\"* Preparando, espere {time} segundos.\")\n    await asyncio.sleep(time)\n    print(f\"- '{name}', esta Listo.\\n\")\n\nasync def serving_order(name: str):\n    time: int = time_random()\n    print(f\"* Sirviendo, espere {time} segundos.\")\n    await asyncio.sleep(time)\n    print(f\"- '{name}', ha sido entregado.\\n\")\n\nasync def order(dish_name: str):\n    await process_order(\n        dish_name, \n        confirm_order, \n        prepare_order, \n        serving_order\n    )\n\nasync def orders_list():\n    await order(\"Baleadas\")\n    await order(\"Tamales\")\n    await order(\"Enchiladas\")\n\n\nprint(\"\\nEJERCICIO #2\")\nasyncio.run(orders_list())\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/mhayhem.py",
    "content": "import random\nfrom datetime import datetime as dt , UTC\nfrom time import sleep as s\n\n# EJERCICIO:\n# Explora el concepto de callback en tu lenguaje creando un ejemplo\n# simple (a tu elección) que muestre su funcionamiento.\n\ndef its_a_numbers(elem1: str, elem2: str, add: callable):\n    try:\n        elem1, elem2 = int(elem1), int(elem2)\n        return add(elem1, elem2)\n    except ValueError as e:\n        return f\"Error: {e}\"\n    \ndef add(num1: int, num2: int):\n    return num1 + num2\n\n# DIFICULTAD EXTRA (opcional):\n# Crea un simulador de pedidos de un restaurante utilizando callbacks.\n# Estará formado por una función que procesa pedidos.\n# Debe aceptar el nombre del plato, una callback de confirmación, una\n# de listo y otra de entrega.\n# - Debe imprimir un confirmación cuando empiece el procesamiento.\n# - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n#   procesos.\n# - Debe invocar a cada callback siguiendo un orden de procesado.\n# - Debe notificar que el plato está listo o ha sido entregado.\n\ndef food_order(confirm_order: callable, ready_order: callable, delivered_order: callable):\n    order = input(\"¿Qué plato desea pedir?\\n\")\n    print(confirm_order(order))\n    s(random.randint(1, 11))\n    print(ready_order(order))\n    s(random.randint(1, 11))\n    print(delivered_order(order))\n\ndef confirm_order(text: str):\n    return f\"El plato: {text}, ha sido confirmado. Hora: {dt.now(UTC).strftime('%H:%M:%S')}\"\n\ndef ready_order(text: str):\n    return f\"El plato: {text}, esta listo para entregar. Hora: {dt.now(UTC).strftime('%H:%M:%S')}\"\n\ndef delivered_order(text: str):\n    return f\"plato: {text}, ha sido entregado. Hora: {dt.now(UTC).strftime('%H:%M:%S')}\"\n\nfood_order(confirm_order, ready_order, delivered_order)"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/mouredev.py",
    "content": "import random\nimport time\nimport threading\n\n\"\"\"\nEjercicio\n\"\"\"\n\n\ndef greeting_process(name: str, callback):\n    print(\"Ejecutando el proceso de saludo...\")\n    callback(name)\n\n\ndef greet_callback(name: str):\n    print(f\"Hola, {name}!\")\n\n\ngreeting_process(\"Brais\", greet_callback)\n\n\"\"\"\nExtra\n\"\"\"\n\n\ndef order_process(dish_name: str, confirm_callback, ready_callback, delivered_callback):\n    def process():\n        confirm_callback(dish_name)\n        time.sleep(random.randint(1, 10))\n        ready_callback(dish_name)\n        time.sleep(random.randint(1, 10))\n        delivered_callback(dish_name)\n\n    threading.Thread(target=process).start()\n\n\ndef confirm_order(dish_name: str):\n    print(f\"Tu pedido {dish_name} ha sido confirmado.\")\n\n\ndef order_ready(dish_name: str):\n    print(f\"Tu pedido {dish_name} está listo.\")\n\n\ndef order_delivered(dish_name: str):\n    print(f\"Tu pedido {dish_name} ha sido entregado.\")\n\n\norder_process(\"Pizza Barbacoa\", confirm_order, order_ready, order_delivered)\norder_process(\"Pizza 4 Quesos\", confirm_order, order_ready, order_delivered)\norder_process(\"Pizza Margarita\", confirm_order, order_ready, order_delivered)\norder_process(\"Pizza con Piña\", confirm_order, order_ready, order_delivered)\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/mrodara.py",
    "content": "### CALLBACKS EN PYTHON\n\n'''\nUn callback es simplemente una función que:\n\nSe pasa como argumento a otra función.\nEs llamada dentro de esa función en un momento determinado.\n'''\n\n# Definimos una función callback\n#def saludo(name: str) -> None:\n#    print(f\"Hola {name}\")\n#\n## Función principal que usará el callback\n#def procesar_saludo(name: str, my_callback) -> None:\n#    print(\"Procesando saludo...\")\n#    my_callback(name)\n#    print(\"Saludo procesado.\")\n#\n#procesar_saludo(\"Brais\", saludo)\n\n\n### EJERCICIO EXTRA\nimport asyncio #Vamos a trabajar con procesos\nfrom random import randint #Para generar los tiempo aleatorios\n\n# Funciones callback\nasync def order_confirmed(plate_name: str) -> None:\n    print(f\"La comanda para el plato: {plate_name} está confirmada\")\n    await asyncio.sleep(randint(1,10)) # Generamos un tiempo aleatorio entre 1 y 10\n\nasync def order_ready(plate_name: str) -> None:\n    print(f\"La comanda para el plato: {plate_name} está lista\")\n    await asyncio.sleep(randint(1,10)) # Generamos un tiempo aleatorio entre 1 y 10\n\nasync def order_delivered(plate_name: str) -> None:\n    print(f\"La comanda para el plato: {plate_name} está entregada\")\n    await asyncio.sleep(randint(1,10)) # Generamos un tiempo aleatorio entre 1 y 10\n\n# Función principal\nasync def procesar_pedido(plate_name: str, cb_confirmed, cb_ready, cb_delivered) -> None:\n    print(f\"Procesando pedido de {plate_name}...\")\n    #await asyncio.sleep(1)\n    await cb_confirmed(plate_name)\n    #await asyncio.sleep(1)\n    await cb_ready(plate_name)\n    #await asyncio.sleep(1)\n    await cb_delivered(plate_name)\n    #await asyncio.sleep(1)\n    print(f\"Pedido de {plate_name} procesado.\")\n    \n# Ejecución asíncrona\nasync def main() -> None:\n    await asyncio.gather(\n        procesar_pedido(\"Pizza\", order_confirmed, order_ready, order_delivered),\n        procesar_pedido(\"Hamburguesa\", order_confirmed, order_ready, order_delivered),\n        procesar_pedido(\"Kebap\", order_confirmed, order_ready, order_delivered)\n    )\n\n# Ejecutar la función principal\nasyncio.run(main())\n    \n### FIN EJERCICIO EXTRA\n\n### FIN CALLBACKS EN PYTHON\n\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/neslarra.py",
    "content": "\"\"\"\n EJERCICIO:\n Explora el concepto de callback en tu lenguaje creando un ejemplo\n simple (a tu elección) que muestre su funcionamiento.\n\n DIFICULTAD EXTRA (opcional):\n Crea un simulador de pedidos de un restaurante utilizando callbacks.\n Estará formado por una función que procesa pedidos.\n Debe aceptar el nombre del plato, una callback de confirmación, una\n de listo y otra de entrega.\n - Debe imprimir un confirmación cuando empiece el procesamiento.\n - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n   procesos.\n - Debe invocar a cada callback siguiendo un orden de procesado.\n - Debe notificar que el plato está listo o ha sido entregado.\n\"\"\"\nfrom random import randint\n\nprint(f\"##  Explicación  {'#' * 30}\")\nprint(r\"\"\"\nUn \"callback\" es una función que puede ser llamada como argumento de otra función. Por ejemplo, tengo una función operar cuyos argumentos son\nla operación a ejecutar (que es el nombre de la función que hará la operación \"real\") más el resto de argumentos necesarios para que la \noperación pueda ejecutarse. \n\ndef sumar(num1, num2):\n    return num1 + num2\n\n\ndef multiplicar(num1, num2):\n    return num1 * num2\n\n\ndef factorial(num):\n    if num < 2:\n        return 1\n    return num * factorial(num - 1)\n\n\ndef operar(operacion, *args):\n    return operacion(*args)\n\n\nprint(f\"Suma: {operar(sumar, 3, 2)}\")\nprint(f\"Multiplicación: {operar(multiplicar, 2, 3)}\")\nprint(f\"Factorial: {operar(factorial, 4)}\")\nprint(f\"Factorial de la multiplicación: {operar(factorial, operar(multiplicar, 2, 3))}\")\n\nSuma: 5\nMultiplicación: 6\nFactorial: 24\nFactorial de la multiplicación: 720\n\n\"\"\")\n\nprint(f\"##  Dificultad extra  {'#' * 30}\\n\")\n\n\ndef seconds_in_wait(init: int, end: int) -> int:\n    return randint(init, end)\n\n\ndef process_order(callback_func, *args):\n    from time import sleep\n    sleep(seconds_in_wait(1, 10))\n    return callback_func(*args)\n\n\ndef order_number():\n    valor = 100\n    while valor <= 1000:\n        yield valor\n        valor += 1\n\n\ndef create_order(*args) -> int:\n    global orders\n    global order_gen\n    order_num = next(order_gen)\n    orders[order_num] = {\"meal\": args[0], \"state\": \"ordered\"}\n    return order_num\n\n\ndef confirm_order(*args):\n    global orders\n    if args[0] == \"Y\":\n        state = \"confirmed\"\n    else:\n        state = \"cancelled\"\n    orders[args[1]][\"state\"] = state\n\n\ndef order_ready(*args) -> int:\n    global orders\n    doing = randint(0, 5)\n    if not doing:\n        orders[args[0]][\"state\"] = \"ready\"\n    return doing\n\n\ndef order_delivered(*args) -> int:\n    global orders\n    delivering = randint(0, 3)\n    if not delivering:\n        orders[args[0]][\"state\"] = \"delivered\"\n    return delivering\n\n\ndef order_process(meal: str):\n    order = process_order(create_order, meal)\n    print(f\"New order: order {order} {orders[order]}\")\n    process_order(confirm_order, \"Y\", order)\n    print(f\"Confirmation: order {order} {orders[order]}\")\n    print(f\"Preparation: order {order} .\", end=\"\")\n    while process_order(order_ready, order):\n        print(\".\", end=\"\")\n    print(f\" {orders[order]}\")\n    print(f\"Delivering: order {order} .\", end=\"\")\n    while process_order(order_delivered, order):\n        print(\".\", end=\"\")\n    print(f\" {orders[order]}\")\n\n\norder_gen = order_number()\norders = {}\n\norder_process(\"milanesa\")\norder_process(\"locro\")\norder_process(\"pizza\")\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/nlarrea.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el concepto de callback en tu lenguaje creando un ejemplo\n * simple (a tu elección) que muestre su funcionamiento.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n * Estará formado por una función que procesa pedidos.\n * Debe aceptar el nombre del plato, una callback de confirmación, una\n * de listo y otra de entrega.\n * - Debe imprimir un confirmación cuando empiece el procesamiento.\n * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n *   procesos.\n * - Debe invocar a cada callback siguiendo un orden de procesado.\n * - Debe notificar que el plato está listo o ha sido entregado.\n\"\"\"\n\n\ndef greeting(user: str, callback):\n    print(\"This is the greeting process...\")\n    callback(user)\n\n\ndef greet_user(user: str):\n    print(f\"Welcome {user}!\")\n\n\ngreeting(\"nlarrea\", greet_user)\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n * Estará formado por una función que procesa pedidos.\n * Debe aceptar el nombre del plato, una callback de confirmación, una\n * de listo y otra de entrega.\n * - Debe imprimir un confirmación cuando empiece el procesamiento.\n * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n *   procesos.\n * - Debe invocar a cada callback siguiendo un orden de procesado.\n * - Debe notificar que el plato está listo o ha sido entregado.\n\"\"\"\n\n\nfrom random import randint\nimport time\n\n\ndef order_process(\n    dish: str, confirm_callback, ready_callback, delivered_callback\n):\n    confirm_callback(dish)\n    time.sleep(randint(1, 5))\n    ready_callback(dish)\n    time.sleep(randint(1, 5))\n    delivered_callback(dish)\n\n\ndef order_confirmation(dish: str):\n    print(f\"The order '{dish}' is confirmed.\")\n\n\ndef order_ready(dish: str):\n    print(f\"The order '{dish}' is ready.\")\n\n\ndef order_delivered(dish: str):\n    print(f\"The order '{dish}' has been delivered.\")\n\n\norder_process(\n    \"Tonkotsu Ramen\", order_confirmation, order_ready, order_delivered\n)\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/oriaj3.py",
    "content": "\"\"\" \n21 - CALLBACKS\nAutor de la solución: Oriaj3\n\nTeoría:\nUn callback es una función que se pasa como argumento a otra función y que se\nllama cuando un evento ocurre. En Python, los callbacks se pueden implementar\nutilizando funciones o clases.\n\nLos callbacks se utilizan para manejar eventos asíncronos, como la finalización\nde una tarea o la recepción de una respuesta de un servidor. También se utilizan\npara ejecutar código después de que se haya completado una tarea.\n\nLos callbacks se utilizan en muchos lenguajes de programación, como JavaScript,\nJava, C++ y Python. En Python, los callbacks se pueden implementar utilizando\nfunciones o clases.\n\nUn callbacks en una clase sirve para que una función se ejecute después de que\notra función haya terminado de ejecutarse.\n\nEjemplo de funcion:\ndef callback_function():\n    print(\"Callback function called\")\n\ndef main_function(callback):\n    print(\"Main function called\")\n    callback()\n\nmain_function(callback_function)\n\"\"\"\n\n\"\"\"\n/*\n * EJERCICIO:\n * Explora el concepto de callback en tu lenguaje creando un ejemplo\n * simple (a tu elección) que muestre su funcionamiento.\n\"\"\"\n\ndef funcion_callback(nombre):\n    print(f\"Hola, {nombre}!\")\n\ndef funcion_principal(nombre, callback):\n    print(\"Procesando saludo.\")\n    callback(nombre)\n\nfuncion_principal(\"Jairo\", funcion_callback)\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n * Estará formado por una función que procesa pedidos.\n * Debe aceptar el nombre del plato, una callback de confirmación, una\n * de listo y otra de entrega.\n * - Debe imprimir un confirmación cuando empiece el procesamiento.\n * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n *   procesos.\n * - Debe invocar a cada callback siguiendo un orden de procesado.\n * - Debe notificar que el plato está listo o ha sido entregado.\n */\n\"\"\"\n\nimport random\nfrom time import sleep\n\ndef confirmacion(plato: str):\n    print(f\"[{plato}] - confirmado\")\n\ndef listo(plato: str):\n    print(f\"[{plato}] - listo\")\n\ndef entrega(plato: str):\n    print(f\"[{plato}] - entregado\")\n\n\ndef procesar_pedido(nombre: str, confirm_callback, ok_callback, entrega_callback):\n    confirm_callback(nombre)\n    sleep(random.randint(1, 10))\n    ok_callback(nombre)\n    sleep(random.randint(1, 10))\n    entrega_callback(nombre)\n\nprocesar_pedido(\"Pizza hawaiana\", confirmacion, listo, entrega)\nprocesar_pedido(\"Pizza BBQ\", confirmacion, listo, entrega)\nprocesar_pedido(\"Pizza Carbonara\", confirmacion, listo, entrega)\n    "
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/pyramsd.py",
    "content": "import asyncio\nimport random\nimport time\n\ndef handle_response(response):\n    print(\"Respuesta recibida:\", response)\n\nasync def async_request(callback):\n    print(\"Iniciando solicitud asincrona\")\n    await asyncio.sleep(2)  # Simulando una operación asíncrona como una solicitud de red\n    response = \"Respuesta simulada\"\n    callback(response)\n\nasync def main():\n    print(\"Haciendo solicitud asincrona\")\n    await async_request(handle_response)\n    print(\"Solicitud realizada\")\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n\n'''\nEXTRA\n'''\n\ndef procesar_plato(plato, callback_confirm, callback_listo, callback_entrega):\n    callback_confirm(plato)\n\n    tiempo_procesamiento = random.randint(1, 10)\n    time.sleep(tiempo_procesamiento)\n\n    callback_listo(plato)\n\n    tiempo_entrega = random.randint(1, 10)\n    time.sleep(tiempo_entrega)\n\n    callback_entrega(plato)\n\ndef confirmar_pedido(plato):\n    print(f\"Confirmación: El pedido del plato {plato} ha sido recibido y está en proceso.\")\n\n\ndef pedido_listo(plato):\n    print(f\"Listo: El plato {plato} está listo para ser entregado.\")\n\n\ndef entregar_pedido(plato):\n    print(f\"Entregado: El plato {plato} ha sido entregado al cliente.\")\n\n\nplato = \"Empanadas de Pollo\"\nprocesar_plato(plato, confirmar_pedido, pedido_listo, entregar_pedido)\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/qwik-zgheib.py",
    "content": "# -- exercise\ndef callback(a, b):\n    print(\"Sum = {0}\".format(a + b))\n\n\ndef main(a, b, f=None):\n    print(\"Add any two digits.\")\n    if f is not None:\n        f(a, b)\n\n\nmain(1, 2, callback)\n\n\n# -- extra challenge\ndef confirm(order, f):\n    print(\"Confirming order: {0}\".format(order))\n    f(order)\n\n\ndef ready(order):\n    print(\"Order {0} is ready.\".format(order))\n\n\ndef deliver(order):\n    print(\"Delivering order {0}.\".format(order))\n\n\ndef process_order(order, confirm, ready, deliver):\n    confirm(order, ready)\n    confirm(order, deliver)\n    print(\"Order {0} processed.\".format(order))\n\n\ndef main():\n    order = \"Pizza\"\n    process_order(order, confirm, ready, deliver)\n    order = \"Burger\"\n    process_order(order, confirm, ready, deliver)\n    order = \"Salad\"\n    process_order(order, confirm, ready, deliver)\n\n    print(\"All orders processed.\")\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/rantamhack.py",
    "content": "import random\nimport time\n\n\n'''\n* EJERCICIO:\n* Explora el concepto de callback en tu lenguaje creando un ejemplo\n* simple (a tu eleccion) que muestre su funcionamiento.\n'''\nprint(\"\\n\\n=======================================EJERCICIO=======================================\\n\\n\")\n\n\n\ndef called(num):\n    return num[0] * num[1]\n\ndef caller(function, num):\n    return function(num)\n\nnum = [7, 8]\n\nresult = caller(called, num)\n\n\nprint(\"El resultado de la multiplcacion es: \", result)\n\n\n\n'''\n* DIFICULTAD EXTRA (opcional):\n* Crea un simulador de pedidos de un restaurante utilizando callbacks.\n* Estara formado por una funcion que procesa pedidos.\n* Debe aceptar el nombre del plato, una callback de confirmacion, una\n* de listo y otra de entrega.\n* - Debe imprimir un confirmacion cuando empiece el procesamiento.\n* - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n*   procesos.\n* - Debe invocar a cada callback siguiendo un orden de procesado.\n* - Debe notificar que el plato esta listo o ha sido entregado.\n'''\n\nprint(\"\\n\\n=======================================DIFICULTAD EXTRA=======================================\\n\\n\")\n\n\nexit_program = False\norder = input(\"Que Pizza de la carta te apetece tomar?: \")\n\ndef place_order(order):\n\n    global exit_program\n\n    if order in menu:\n        print(f\"Ha elegido la pizza {order}, enviamos el pedido a cocina\")\n        waiting_time = random.uniform(1, 10)\n        time.sleep(waiting_time)\n        return\n    else:\n        print(\"La pizza elegida no esta en la carta.\") \n        print(\"[!] Saliendo del programa .....\")\n        exit_program = True\n        return\n\ndef order_received(func):\n    if exit_program == False:\n        print(f\"Su pedido de pizza {order} ha llegado a cocina y esta en espera\")\n        waiting_time = random.uniform(1, 10)\n        time.sleep(waiting_time)\n        return   \n\ndef order_in_process(func):\n    print(f\"Su pizza {order} esta siendo procesada\")\n    waiting_time = random.uniform(1, 10)\n    time.sleep(waiting_time)\n\ndef order_delivered(func):\n    print(f\"Su pizza {order} esta preparada para entregar\")\n    waiting_time = random.uniform(1, 10)\n    time.sleep(waiting_time)\n    print(f\"La pizza {order} ha sido entregada\")\n\n\nmenu = (\"4 Quesos\", \"Margarita\", \"Tropical\", \"Carbonara\", \"Campesina\", \"Barbacoa\")\n\norder_received(place_order(order))\n\nif not exit_program:\n    order_delivered(order_in_process(order))\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/raulG91.py",
    "content": "import time\nfrom random import randrange\n#Callbacks\n\ndef sum_callback(a,b):\n    return a+b\n\ndef main(function_callback):\n    print(\"Doing main function\")     \n    result = function_callback\n    print(f'Return of the callback {result}')\n\nmain(sum_callback(2,3))    \n\n#Extra \n\ndef confirm_order(order:str):\n    print(f'Order {order} has been confirmed')\n\ndef orden_ready(order:str):\n    print(f'Order {order} is ready')\n\ndef order_deliver(order:str):\n    print(f'Order {order} has been delivered')\n\ndef process_order(order_name,callback_confirmation,callback_ready,callback_deliver):\n    callback_confirmation(order_name)\n    random = randrange(0,10)\n    time.sleep(random)\n    callback_ready(order_name)\n    random = randrange(0,10)\n    time.sleep(random)\n    callback_deliver(order_name )\n\n\n\n\nprocess_order(\"Pizza\",confirm_order,orden_ready,order_deliver)"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/raynerpv2022.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * Explora el concepto de callback en tu lenguaje creando un ejemplo\n#  * simple (a tu elección) que muestre su funcionamiento.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n#  * Estará formado por una función que procesa pedidos.\n#  * Debe aceptar el nombre del plato, una callback de confirmación, una\n#  * de listo y otra de entrega.\n#  * - Debe imprimir un confirmación cuando empiece el procesamiento.\n#  * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n#  *   procesos.\n#  * - Debe invocar a cada callback siguiendo un orden de procesado.\n#  * - Debe notificar que el plato está listo o ha sido entregado.\n#  */\n\ndef get_last (list1):\n     \n    \n    return list1[len(list1)-1]\n\ndef get_first(list1):\n    return list1[0]\n\ndef print_index(list1, function):\n     return function(list1)\n    \n    \n\n\nprint(f\" LAst items is  {print_index([1,2,3,4,5,6,7,8,9], get_last)}\")\nprint(f\" First items is  {print_index([1,2,3,4,5,6,7,8,9], get_first)}\")\n\nimport tkinter as tk\n\ndef on_button_click():\n    print(\"¡Botón presionado!\")\n\n# Crear la ventana principal\nroot = tk.Tk()\nroot.title(\"Ejemplo de Callback\")\n\n# Crear un botón y asignar el callback\nbutton = tk.Button(root, text=\"Presiona aquí\", command=on_button_click)\nbutton.pack()\n\n# # Iniciar el bucle de eventos\nroot.mainloop()\n\n\ndef Confirm(name : str):\n    return f\"El plato {name} esta confirmado\"\n\ndef Ready(name :str):\n    return f\"El plato {name} esta listo\"\n\ndef Delivered(name :int, price):\n    return f\"El plato {name} cuesta {price} y ha sido entregado\"\n\nimport random, time\n\ndef Orders(name :str, action_Confirm,action_Ready,action_Delivered):\n    stunden = random.randint(1,10)\n    time.sleep(stunden)\n    print( f\" {action_Confirm(name)}, tiempo de demora {stunden} Horas\")\n    stunden = random.randint(1,10)\n    time.sleep(stunden)\n    print( f\" {action_Ready(name)}, tiempo de demora {stunden} Horas\")\n    stunden = random.randint(1,10)\n    time.sleep(stunden)\n    print( f\" {action_Delivered(name,12*stunden)}, tiempo de demora {stunden} Horas\")\n\n\nimport threading\n\ndef Extra():\n    print(\"\")\n    print(\"Extra\")\n    print(\"\")\n    orders = [\"Brocolicon Queso\", \"Pizza de Coliflor\", \"Tortilla de Helado\",\" Helado de Zanahoria\"]\n    Threading = []\n    for order in orders:\n        Hilo = threading.Thread(target=Orders,args=(order,Confirm,Ready,Delivered))\n        Threading.append(Hilo)\n        Hilo.start()\n\n    # espera que terminen todos los hilos activos\n    for h in Threading:\n        h.join()\n    print(\"Estamos Cerrados\")\n    \n\nExtra() "
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/restevean.py",
    "content": "\"\"\"\nExercise\n\"\"\"\nimport time\nimport random\n\n\ndef data_processing(callback):\n    print(\"Processing data...\")\n    time.sleep(2)  # Simula una tarea que toma 2 segundos\n    print(\"Data processed.\")\n    callback()  # Llama al callback\n\n\ndef results_notify():\n    print(\"The process has ended.\")\n\n\n\"\"\"\nExtra\n\"\"\"\n\n\ndef process_order(dish, confirmation_callback, ready_callback, delivery_callback):\n    print(f\"Order received: {dish}\")\n    confirmation_callback(dish)\n\n    # Simulate processing time\n    processing_time = random.randint(1, 10)\n    time.sleep(processing_time)\n\n    ready_callback(dish)\n\n    # Simulate delivery time\n    delivery_time = random.randint(1, 10)\n    time.sleep(delivery_time)\n\n    delivery_callback(dish)\n\n\ndef confirmation(dish):\n    print(f\"Confirmation: The order for {dish} is being processed.\")\n\n\ndef ready(dish):\n    print(f\"Ready: The dish {dish} is ready for delivery.\")\n\n\ndef delivery(dish):\n    print(f\"Delivery: The dish {dish} has been delivered to the customer.\")\n\n\nif __name__ == \"__main__\":\n    print(\"Exercise\")\n    print(\"Starting processing...\")\n    data_processing(results_notify)\n\n    print(\"Extra\")\n    process_order(\"Pizza Margherita\", confirmation, ready, delivery)\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/rigo93acosta.py",
    "content": "'''\n/*\n * EJERCICIO:\n * Explora el concepto de callback en tu lenguaje creando un ejemplo\n * simple (a tu elección) que muestre su funcionamiento.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n * Estará formado por una función que procesa pedidos.\n * Debe aceptar el nombre del plato, una callback de confirmación, una\n * de listo y otra de entrega.\n * - Debe imprimir un confirmación cuando empiece el procesamiento.\n * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n *   procesos.\n * - Debe invocar a cada callback siguiendo un orden de procesado.\n * - Debe notificar que el plato está listo o ha sido entregado.\n */\n'''\n\n## Programación Asíncrona principal saludo.\n\ndef greeting_process(name: str, callback):\n    print('Ejecutando el proceso de saludo...')\n    callback(name)\n\ndef greet_callback(names: str):\n    print(f'Hola, {names}!')\n\ngreeting_process('Rigo', greet_callback)\n\n'''\nExtra\n'''\nimport random\nimport time\nimport threading\n\ndef order_process(dish_name: str, confirm_callbackm, ready_callback, delivered_callback):\n    def process():   \n        confirm_callbackm(dish_name)\n        time.sleep(random.randint(1, 10))    \n        ready_callback(dish_name)\n        time.sleep(random.randint(1, 10))\n        delivered_callback(dish_name)\n    \n    threading.Thread(target=process).start()\n\n\ndef confirm_order(dish_name: str):\n    print(f\"Tu pedido {dish_name} ha sido confirmado.\")\n\ndef order_ready(dish_name: str):\n    print(f\"Tu pedido {dish_name} está listo.\")\n\ndef order_delivered(dish_name: str):\n    print(f\"Tu pedido {dish_name} ha sido entregado.\")\n\norder_process(\"Pizza Barbacoa\", confirm_order, order_ready, order_delivered)\norder_process(\"Pizza 4 Quesos\", confirm_order, order_ready, order_delivered)\norder_process(\"Pizza Margarita\", confirm_order, order_ready, order_delivered)\norder_process(\"Pizza con Piña\", confirm_order, order_ready, order_delivered)\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/santyjl.py",
    "content": "#21 - CALLBACKS\n\"\"\"\n/*\n * EJERCICIO:\n * Explora el concepto de callback en tu lenguaje creando un ejemplo\n * simple (a tu elección) que muestre su funcionamiento.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n * Estará formado por una función que procesa pedidos.\n * Debe aceptar el nombre del plato, una callback de confirmación, una\n * de listo y otra de entrega.\n * - Debe imprimir un confirmación cuando empiece el procesamiento.\n * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n *   procesos.\n * - Debe invocar a cada callback siguiendo un orden de procesado.\n * - Debe notificar que el plato está listo o ha sido entregado.\n */\n\"\"\"\n# los callback son funciones que llaman a otra funciones tipo decoradores\ndef funcion_principal(callback):\n    print(\"Ejecutando función principal\")\n    callback()\n\ndef mi_callback():\n    print(\"Ejecutando el callback\")\n\nfuncion_principal(mi_callback)\n\n# extra\nimport random\nimport time\n\n\n# Función principal que procesa los pedidos\ndef procesar_pedido(nombre_plato, confirmacion_callback, listo_callback, entrega_callback):\n    print(f\"Confirmando pedido para {nombre_plato}...\")\n    confirmacion_callback(nombre_plato)\n\n    # Simular tiempo de preparación\n    tiempo_preparacion = random.randint(1, 10)\n    time.sleep(tiempo_preparacion)\n    print(f\"El plato {nombre_plato} está listo después de {tiempo_preparacion} segundos.\")\n    listo_callback(nombre_plato)\n\n    # Simular tiempo de entrega\n    tiempo_entrega = random.randint(1, 10)\n    time.sleep(tiempo_entrega)\n    print(f\"El plato {nombre_plato} ha sido entregado después de {tiempo_entrega} segundos.\")\n    entrega_callback(nombre_plato)\n\n# Callback de confirmación\ndef confirmacion(nombre_plato):\n    print(f\"Pedido confirmado para {nombre_plato}.\")\n\n# Callback de plato listo\ndef listo(nombre_plato):\n    print(f\"El plato {nombre_plato} está listo para ser servido.\")\n\n# Callback de entrega\ndef entrega(nombre_plato):\n    print(f\"El plato {nombre_plato} ha sido entregado al cliente.\")\n\n# Ejemplo de uso del simulador de pedidos\nnombre_plato = \"Pizza Margherita\"\nprocesar_pedido(nombre_plato, confirmacion, listo, entrega)\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/python/ycanas.py",
    "content": "import random\nimport time\n\n# ------ Ejercicio\n\ndef say_hello_callback(name: str, callback):\n    print(\"Imprimiendo Callback...\")\n    time.sleep(1)\n    callback(name)\n\n\ndef my_callback(name: str):\n    print(f\"Hola, soy un Callback y me llamo: '{name}'\")\n\n\nsay_hello_callback(\"callback1\", my_callback)\n\n\n# ------ Extra\n\ndef procesar_pedido(nombre_plato, callback_confirmacion, callback_listo, callback_entrega):\n    callback_confirmacion(nombre_plato)\n    tiempo_preparacion = random.randint(1, 10)\n    time.sleep(tiempo_preparacion)\n\n    callback_listo(nombre_plato)\n\n    tiempo_entrega = random.randint(1, 10)\n    time.sleep(tiempo_entrega)\n\n    callback_entrega(nombre_plato)\n\ndef confirmar_pedido(nombre_plato):\n    print(f\"Pedido confirmado: {nombre_plato}.\")\n\ndef plato_listo(nombre_plato):\n    print(f\"El plato '{nombre_plato}' está listo para ser servido.\")\n\ndef entregar_pedido(nombre_plato):\n    print(f\"El plato '{nombre_plato}' ha sido entregado al cliente.\")\n\n\nprocesar_pedido(\"Spaghetti Carbonara\", confirmar_pedido, plato_listo, entregar_pedido)\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/ruby/Elmer125.rb",
    "content": "#  * EJERCICIO:\n#  * Explora el concepto de callback en tu lenguaje creando un ejemplo\n#  * simple (a tu elección) que muestre su funcionamiento.\n# Doc: https://stackoverflow.com/questions/1677861/how-to-implement-a-callback-in-ruby\n\ndef say_hello(name, callback)\n  puts \"I'm going to say hello to #{name}\"\n  callback.call(name)\nend\n\ndef greet(name)\n  puts \"Hello, #{name}!\"\nend\n\nsay_hello(\"Alice\", method(:greet))\n\n# def do_stuff(a, b, c, &block)\n#   sum = a + b + c\n#   yield sum\n# end\n\ndef do_stuff(a, b, c)\n  sum = a + b + c\n  yield sum\nend\n\ndo_stuff(1, 2, 3) { |sum| puts \"The sum is #{sum}\" }\n\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n#  * Estará formado por una función que procesa pedidos.\n#  * Debe aceptar el nombre del plato, una callback de confirmación, una\n#  * de listo y otra de entrega.\n#  * - Debe imprimir un confirmación cuando empiece el procesamiento.\n#  * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n#  *   procesos.\n#  * - Debe invocar a cada callback siguiendo un orden de procesado.\n#  * - Debe notificar que el plato está listo o ha sido entregado.\n\ndef order_process(dish, confirm, ready, deliver)\n  Thread.new do\n    puts \"Processing order for #{dish}...\"\n    sleep(rand(1..10))\n    confirm.call(dish)\n    sleep(rand(1..10))\n    ready.call(dish)\n    sleep(rand(1..10))\n    deliver.call(dish)\n  end\nend\n\ndef confirm_order(dish)\n  puts \"Order confirmed for #{dish}\"\nend\n\ndef ready_order(dish)\n  puts \"#{dish} is ready\"\nend\n\ndef deliver_order(dish)\n  puts \"#{dish} has been delivered\"\nend\n\npizza = order_process(\"Pizza\", method(:confirm_order), method(:ready_order), method(:deliver_order))\nhot_dog = order_process(\"Hot dog\", method(:confirm_order), method(:ready_order), method(:deliver_order))\nsoup = order_process(\"Soup\", method(:confirm_order), method(:ready_order), method(:deliver_order))\nrice_with_chicken = order_process(\"Rice with chicken\", method(:confirm_order), method(:ready_order), method(:deliver_order))\n\n[pizza, hot_dog, soup, rice_with_chicken].each(&:join)"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/rust/kenysdev.rs",
    "content": "/*\n╔═══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado                ║\n║ GitHub: https://github.com/Kenysdev   ║\n║ 2024 -  Rust                          ║\n╚═══════════════════════════════════════╝\n-----------------------------------------\n* CALLBACKS\n-----------------------------------------\n\n* EJERCICIO #1:\n* Explora el concepto de callback en tu lenguaje creando un ejemplo\n* simple (a tu elección) que muestre su funcionamiento.\n*/\n\n// (Opcional) ya que Rust puede inferir automáticamente \n// el tipo de la función de callback en la mayoría de los casos. \ntype CallbackDelegate = fn(String, i32);\n\nfn sum_numbers(a: i32, b: i32, callback: CallbackDelegate) {\n    let result: i32 = a + b;\n    callback(format!(\"{} + {}\", a, b), result);\n}\n\nfn my_callback(summands: String, result: i32) {\n    println!(\"La suma de {} es: {}\", summands, result);\n}\n\n/*\n* EJERCICIO #2:\n* Crea un simulador de pedidos de un restaurante utilizando callbacks.\n* Estará formado por una función que procesa pedidos.\n* Debe aceptar el nombre del plato, una callback de confirmación, una\n* de listo y otra de entrega.\n* - Debe imprimir un confirmación cuando empiece el procesamiento.\n* - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n*   procesos.\n* - Debe invocar a cada callback siguiendo un orden de procesado.\n* - Debe notificar que el plato está listo o ha sido entregado.\n*/\n\nuse std::thread;\nuse std::time::Duration;\n\n// [dependencies]\n// rand = \"0.8.5\"\n// https://crates.io/crates/rand\nuse rand::prelude::*;\n\nfn process_order(name: &str, confirm: fn(&str), prepare: fn(&str), serving: fn(&str)) {\n    println!(\"-----\\n* Procesando: '{}' \\n-----\\n\", name);\n    confirm(name);\n    prepare(name);\n    serving(name);\n}\n\nfn time_random() -> u64 {\n    let mut rng: ThreadRng = rand::thread_rng();\n    rng.gen_range(1..=10)\n}\n\nfn confirm_order(name: &str) {\n    let time: u64 = time_random();\n    println!(\"* Confirmando {}, espere {} segundos.\", name, time);\n    thread::sleep(Duration::from_secs(time));\n    println!(\"- '{}', ha sido confirmado.\\n\", name);\n}\n\nfn prepare_order(name: &str) {\n    let time: u64 = time_random();\n    println!(\"* Preparando, espere {} segundos.\", time);\n    thread::sleep(Duration::from_secs(time));\n    println!(\"- '{}', esta Listo.\\n\", name);\n}\n\nfn serving_order(name: &str) {\n    let time: u64 = time_random();\n    println!(\"* Sirviendo, espere {} segundos.\", time);\n    thread::sleep(Duration::from_secs(time));\n    println!(\"- '{}', ha sido entregado.\\n\", name);\n}\n\nfn order(dish_name: &str) {\n    process_order(dish_name, confirm_order, prepare_order, serving_order);\n}\n\nfn main() {\n    println!(\"EJERCICIO #1\");\n    sum_numbers(6, 6, my_callback);\n    sum_numbers(5, 2, my_callback);\n\n    println!(\"\\nEJERCICIO #2\");\n    order(\"Baleadas\");\n    order(\"Tamales\");\n    order(\"Enchiladas\");\n}\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/sql/Nicojsuarez2.sql",
    "content": "# #21 CALLBACKS\n> #### Dificultad: Media | Publicación: 20/04/24 | Corrección: 27/05/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Explora el concepto de callback en tu lenguaje creando un ejemplo\n * simple (a tu elección) que muestre su funcionamiento.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n * Estará formado por una función que procesa pedidos.\n * Debe aceptar el nombre del plato, una callback de confirmación, una\n * de listo y otra de entrega.\n * - Debe imprimir un confirmación cuando empiece el procesamiento.\n * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n *   procesos.\n * - Debe invocar a cada callback siguiendo un orden de procesado.\n * - Debe notificar que el plato está listo o ha sido entregado.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/swift/allbertoMD.swift",
    "content": "import Foundation\n\n// Para el correcto funcionamiento del script se debe usar en un playground.\n\nfunc fetchData(from url: URL, completion: @escaping (Data?, Error?) -> Void) {\n    let task = URLSession.shared.dataTask(with: url) { (data, response, error) in\n        completion(data, error)\n    }\n    task.resume()\n}\n\nif let url = URL(string: \"https://swift.org\") {\n    fetchData(from: url) { (data, error) in\n        if let error = error {\n            print(\"Error al fetch data: \\(error)\")\n        }\n        guard let dataResponse = data else {\n            fatalError()\n        }\n        if let dataSting = String(data: dataResponse, encoding: .utf8) {\n            print(dataSting)\n        }\n    }\n}\n\n\n\n\n// DIFICULTAD EXTRA\nprint(\"\\nDIFICULTAD EXTRA.\")\n\n\nfunc order(name order: String, confirmation: @escaping (String) -> Void, done: @escaping (String) -> Void, delivery: @escaping (String) -> Void) {\n    \n    print(\"El pedido de \\(order) ha sido realizado.\")\n    \n    DispatchQueue.main.asyncAfter(deadline: .now() + 3) {\n        confirmation(order)\n    }\n    \n    DispatchQueue.main.asyncAfter(deadline: .now() + 9) {\n        done(order)\n    }\n    \n    DispatchQueue.main.asyncAfter(deadline: .now() + 15) {\n        delivery(order)\n    }\n}\n\n\n\norder(name: \"Alitas de pollo\") { orderConfirmate in\n    print(\"\\(orderConfirmate) confirmado.\")\n} done: { orderDone in\n    print(\"\\(orderDone) listo.\")\n} delivery: { orderDelivery in\n    print(\"\\(orderDelivery) entregado.\")\n}\n\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/swift/blackriper.swift",
    "content": "import Foundation\n\n/*\n un callback es una funcion que se pasa como argumento a otra funcion y se ejecuta en la misma \n al igual que en kotlin  estas funciones se pueden simplificar con closures.\n */\n\n\nfunc exampleWithCallback(callback: ([Int]) -> [Int]) {\n    let numbers = [1, 2, 3, 4, 5]\n    let result = callback(numbers)\n    print(result)\n}\n\n// estamos pasando una closure como argumento\nexampleWithCallback { numbers in\n    return numbers.map({ $0 * 2 })\n}\n\n//ejercicio extra\n\nfunc confirmOrder(_ dishName: String) async  throws {\n    let duration = Double.random(in: 1...10)\n    print(\"ordering \\(dishName)\")\n   try await Task.sleep(for: .seconds(duration))\n}\n\nfunc readyOrder(_ dishName: String) async throws{\n    let duration = Double.random(in: 1...10)\n    try await Task.sleep(for: .seconds(duration))\n    print(\"ready \\(dishName)\")\n}\n\nfunc recivedOrder(_ dishName: String) async throws{\n    let duration = Double.random(in: 1...10)\n    try await Task.sleep(for: .seconds(duration))\n    print(\"recived \\(dishName)\")\n}\n    \n// creamos un tipo personalido para no tener que escribir el tipo de callback\ntypealias Callback = (String) async throws -> Void\n\nfunc restaurantOrder(confirm: Callback, ready: Callback, recived: Callback) async throws {\n   print(\"What would you like to order?\") \n   let dishName = readLine() ?? \"Tacos\"\n\n   try await confirm(dishName)\n   try await ready(dishName)\n   try await recived(dishName)\n }\n\n try await restaurantOrder(confirm: confirmOrder, ready: readyOrder, recived: recivedOrder)\n\n\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/swift/pedroomar23.swift",
    "content": "import Foundation \n\n/*\n * EJERCICIO:\n * Explora el concepto de callback en tu lenguaje creando un ejemplo\n * simple (a tu elección) que muestre su funcionamiento.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n * Estará formado por una función que procesa pedidos.\n * Debe aceptar el nombre del plato, una callback de confirmación, una\n * de listo y otra de entrega.\n * - Debe imprimir un confirmación cuando empiece el procesamiento.\n * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n *   procesos.\n * - Debe invocar a cada callback siguiendo un orden de procesado.\n * - Debe notificar que el plato está listo o ha sido entregado.\n */\n\n// CallBacks \nlet url = URL(string: \"https://wwww.swift.org\")!\n\nfunc fetchData(from url: URL, completion: @escaping (Data?, Data?) -> Void) {\n    let task: URLSessionDataTask = URLSession.shared.dataTask(with: url) { (data: Data?, response: URLResponse?, error: _) in \n        completion(data, response)\n    }\n    task.resume()\n}\n\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/typescript/AChapeton.ts",
    "content": "interface Pedido {\n  id: string,\n  name: string,\n  item: Array<string>\n  createdDate: Date,\n  note: string\n}\n\n// Confirmar pedido\nconst confirmarPedido = (name: string) => {\n  console.log(`Confirmando pedido de ${name}`)\n}\n\n// Pedido listo\nconst confirmarPedidoListo = () => {\n  console.log('Pedido listo!!!')\n}\n\n// Pedido entregado\nconst confirmarPedidoEntregado = (name: string) => {\n  console.log(`Pedido entregado! Gracias por confiar en nosotros, ${name}`)\n}\n\nconst crearPedido = (\n  pedido: Pedido, \n  confirmarPedido: Function,\n  confirmarPedidoListo: Function,\n  confirmarPedidoEntregado: Function\n) => {\n  setTimeout(() => {\n    confirmarPedido(pedido.name)\n    \n    setTimeout(() => {\n      confirmarPedidoListo()\n      \n      setTimeout(() => {\n        confirmarPedidoEntregado(pedido.name)\n      }, 3000)  \n    }, 3000) \n  }, 2000) \n}\n\ncrearPedido(\n  {\n    id: '1',\n    name: 'Andres',\n    item: ['8oz steak', 'Lemonade', 'Cheescake'],\n    createdDate:  new Date(),\n    note: 'I am hungry'\n  },\n  confirmarPedido,\n  confirmarPedidoListo,\n  confirmarPedidoEntregado\n)"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/typescript/Sac-Corts.ts",
    "content": "function greet(name: string, callback: () => void): void {\n    console.log('Hi ' + name);\n    callback();\n}\n\nfunction callMe(): void {\n    console.log('I am callback function');\n}\n\ngreet('Isaac', callMe);\n\n// ** Extra Exercise ** //\nfunction processOrder(\n    dish: string,\n    confirmation: (dish: string) => void,\n    ready: (dish: string) => void,\n    delivery: (dish: string) => void\n): void {\n    setTimeout(() => {\n        console.log(`Order confirmed: ${dish}`);\n        confirmation(dish);\n        \n        setTimeout(() => {\n            console.log(`The dish ${dish} is ready.`);\n            ready(dish);\n\n            setTimeout(() => {\n                console.log(`The dish ${dish} has been delivered.`);\n                delivery(dish);\n            }, Math.random() * 9000 + 1000);\n        }, Math.random() * 9000 + 1000);\n    }, Math.random() * 9000 + 1000);\n}\n\nfunction confirmDish(dish: string): void {\n    console.log(`Processing order: ${dish}`);\n}\n\nfunction readyDish(dish: string): void {\n    console.log(`Preparing the dish: ${dish}`);\n}\n\nfunction deliverDish(dish: string): void {\n    console.log(`Delivering the dish: ${dish}`);\n}\n\nprocessOrder('Pizza', confirmDish, readyDish, deliverDish);\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/typescript/duendeintemporal.ts",
    "content": "//#21 { Retos para programadores } - CALLBACKS\n/*\n * EJERCICIO:\n * Explora el concepto de callback en tu lenguaje creando un ejemplo\n * simple (a tu elección) que muestre su funcionamiento.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un simulador de pedidos de un restaurante utilizando callbacks.\n * Estará formado por una función que procesa pedidos.\n * Debe aceptar el nombre del plato, una callback de confirmación, una\n * de listo y otra de entrega.\n * - Debe imprimir un confirmación cuando empiece el procesamiento.\n * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n *   procesos.\n * - Debe invocar a cada callback siguiendo un orden de procesado.\n * - Debe notificar que el plato está listo o ha sido entregado.\n */\n\n//Bibliografy reference:\n//Secrets of the JavaScript Ninja (John Resig, Bear Bibeault, Josip Maras) (z-lib.org)\n//Eloquent Javascript A Modern Introduction to Programming by Marijn Haverbeke (z-lib.org)\n//GPT\n\nlet log = console.log;\n\n// Conditional check for browser environment\nif (typeof window !== 'undefined') {\n    window.addEventListener('load', () => {\n        const body: HTMLBodyElement | null = document.querySelector('body');\n        const title = document.createElement('h1');\n\n        body?.style.setProperty('background', '#000');\n        body?.style.setProperty('text-align', 'center');\n\n        title.textContent = 'Retosparaprogramadores #21.';\n        title.style.setProperty('font-size', '3.5vmax');\n        title.style.setProperty('color', '#fff');\n        title.style.setProperty('line-height', '100vh');\n\n        body?.appendChild(title);\n\n        setTimeout(() => {\n            alert('Retosparaprogramadores #21. Please open the Browser Developer Tools.');\n        }, 2000);\n        log('Retosparaprogramadores #21');\n});\n} else {\n    log('This code is designed to run in a browser environment. Skipping window-related code.');\n    log('Retosparaprogramadores #21');\n}\n\n\n/* Callbacks\nOne approach to asynchronous programming is to make functions that perform\na slow action take an extra argument, a callback function. The action is started,\nand when it finishes, the callback function is called with the result.\nAs an example, the setTimeout function, available both in Node.js and in\nbrowsers, waits a given number of milliseconds (a second is a thousand mil-\nliseconds) and then calls a function.\nsetTimeout(() => console.log(\"Tick\"), 500); */\n\n/* Whenever we set up a function to be called at a later time, whether by the browser in\nthe event-handling phase or by other code, we’re setting up a callback. The term stems\nfrom the fact that we’re establishing a function that other code will later “call back” at\nan appropriate point of execution. */\n\nconst todayMenu: string[] = ['pizza', 'hamburger', 'paella', 'arabian food', 'posole', 'pastel azteca', 'carbonara past', 'napolitana past', 'fish', 'beaf'];\n\nconst orderConfirm = (order: string, cb: (o:string)=> void) => {\n    log(`The order: ${order} is confirmed. Tell you when it's ready.`);\n   \n    const processingTime = Math.floor(Math.random() * 10000) + 1000; \n    setTimeout(() => {\n        cb(order);\n    }, processingTime);\n}\n\nconst orderReady = (order: string, cb: (o:string)=> void) => {\n    log(`The order: ${order} is ready. Waiting to deliver.`);\n   \n    const deliveryTime: number = Math.floor(Math.random() * 10000) + 1000; \n    setTimeout(() => {\n        cb(order);\n    }, deliveryTime);\n}\n\nconst orderDeliver = (order: string) => {\n    log(`Order: ${order} delivered.`);\n}\n\nconst makeOrder = (listOrder: string[]) => {\n    listOrder.forEach(order => {\n        if (todayMenu.some(elm => elm.toLowerCase() === order.toLowerCase())) {\n            orderConfirm(order, (confirmedOrder) => {\n                orderReady(confirmedOrder, (readyOrder) => {\n                    orderDeliver(readyOrder);\n                });\n            });\n        } else {\n            log(`The order: ${order} is not in today's menu. Please choose another dish.`);\n        }\n    });\n}\n\nlet orderList1: string[] = ['pastiche', 'hamburger', 'pizza'];\nlet orderList2: string[] = ['arabian food', 'fish', 'pastel azteca'];\n\nmakeOrder(orderList1);\nmakeOrder(orderList2);\n\n/* Output Example: The order: pastiche is not in today's menu. Please choose another dish.\n21.js:42 The order: hamburger is confirmed. Tell you when it's ready.\n21.js:42 The order: pizza is confirmed. Tell you when it's ready.\n21.js:42 The order: arabian food is confirmed. Tell you when it's ready.\n21.js:42 The order: fish is confirmed. Tell you when it's ready.\n21.js:42 The order: pastel azteca is confirmed. Tell you when it's ready.\n21.js:51 The order: pizza is ready. Waiting to deliver.\n21.js:51 The order: pastel azteca is ready. Waiting to deliver.\n21.js:51 The order: hamburger is ready. Waiting to deliver.\n21.js:60 Order: pizza delivered.\n21.js:60 Order: hamburger delivered.\n21.js:51 The order: fish is ready. Waiting to deliver.\n21.js:51 The order: arabian food is ready. Waiting to deliver.\n21.js:60 Order: fish delivered.\n21.js:60 Order: pastel azteca delivered.\n21.js:60 Order: arabian food delivered. */"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/typescript/eulogioep.ts",
    "content": "/*\n * TEORÍA DE CALLBACKS EN TYPESCRIPT:\n *\n * TypeScript extiende JavaScript añadiendo tipos estáticos. Para callbacks,\n * esto significa que podemos definir claramente:\n * 1. Los tipos de los parámetros que el callback acepta\n * 2. El tipo de valor que el callback retorna\n *\n * Ventajas de usar callbacks en TypeScript:\n * 1. Mejor intellisense y autocompletado en IDEs\n * 2. Detección temprana de errores de tipo\n * 3. Documentación más clara a través de tipos\n * 4. Refactorización más segura\n */\n\n// Definición de tipos para los callbacks\ntype SimpleCallback = () => void;\ntype MessageCallback = (message: string) => void;\n\n// Interface para estructurar los callbacks del restaurante\ninterface RestaurantCallbacks {\n  onConfirmation: MessageCallback;\n  onReady: MessageCallback;\n  onDelivery: MessageCallback;\n}\n\n// Clase para manejar pedidos del restaurante\nclass RestaurantOrders {\n  // Método privado para generar tiempo aleatorio\n  private getRandomTime(): number {\n    return Math.floor(Math.random() * 10) + 1;\n  }\n\n  // Método para procesar un pedido\n  public processOrder(dish: string, callbacks: RestaurantCallbacks): void {\n    const { onConfirmation, onReady, onDelivery } = callbacks;\n\n    // Confirmación inmediata\n    onConfirmation(`Order confirmed: ${dish}`);\n\n    // Simular preparación\n    const prepTime = this.getRandomTime();\n    console.log(`Preparing... (${prepTime} seconds)`);\n\n    setTimeout(() => {\n      // Plato listo\n      onReady(`${dish} is ready!`);\n\n      // Simular entrega\n      const deliveryTime = this.getRandomTime();\n      console.log(`Delivering to table... (${deliveryTime} seconds)`);\n\n      setTimeout(() => {\n        // Entrega completada\n        onDelivery(`${dish} has been delivered. Enjoy your meal!`);\n      }, deliveryTime * 1000);\n    }, prepTime * 1000);\n  }\n}\n\n// Ejemplo simple de callback\nfunction processTask(task: string, callback: SimpleCallback): void {\n  console.log(`Starting task: ${task}`);\n\n  setTimeout(() => {\n    callback();\n  }, 1000);\n}\n\n// Función principal asíncrona\nasync function main() {\n  console.log(\"=== Simple Callback Example ===\");\n\n  // Ejemplo simple usando Promise para manejar el callback\n  await new Promise<void>((resolve) => {\n    processTask(\"Test task\", () => {\n      console.log(\"Task completed!\");\n      resolve();\n    });\n  });\n\n  console.log(\"\\n=== Restaurant Simulator ===\");\n\n  const restaurant = new RestaurantOrders();\n\n  // Creamos un Promise que se resolverá cuando se complete todo el proceso\n  await new Promise<void>((resolve) => {\n    restaurant.processOrder(\"Paella Valenciana\", {\n      onConfirmation: (message: string) => {\n        console.log(`CONFIRMATION: ${message}`);\n      },\n      onReady: (message: string) => {\n        console.log(`READY: ${message}`);\n      },\n      onDelivery: (message: string) => {\n        console.log(`DELIVERY: ${message}`);\n        resolve(); // Resolvemos el Promise cuando se complete la entrega\n      },\n    });\n  });\n}\n\n// Ejecutar el programa principal\nconsole.log(\"Starting the program...\");\nmain().then(() => {\n  console.log(\"\\nProgram completed successfully!\");\n});\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/typescript/hozlucas28.ts",
    "content": "/*\n    Callbacks...\n*/\n\nconsole.log('Callbacks...')\n\nfunction createArray<T extends number | string>(\n    length: number,\n    callback: (prevElement: undefined | T) => T\n): T[] {\n    const array: T[] = []\n\n    for (let i = 0; i < length; i++) {\n        const element: T = callback(array.at(i - 1))\n        array.push(element)\n    }\n\n    return array\n}\n\nconst arrayOfEvens: number[] = createArray<number>(10, (prevElement) => {\n    if (typeof prevElement === 'undefined') return 0\n    return prevElement + 2\n})\n\nconsole.log(`\\nArray of evens: [${arrayOfEvens}]`)\n\nconst arrayOfOdds: string[] = createArray<string>(10, (prevElement) => {\n    if (typeof prevElement === 'undefined') return 'I am the number 1'\n\n    const prevElementValue = parseInt(\n        prevElement.slice(prevElement.lastIndexOf(' '))\n    )\n\n    return `I am the number ${prevElementValue + 2}`\n})\n\nconsole.log(`\\nArray of named odds: [${arrayOfOdds}]`)\n\nconsole.log(\n    '\\n# ---------------------------------------------------------------------------------- #\\n'\n)\n\n/*\n    Additional challenge...\n*/\n\nconsole.log('Additional challenge...\\n')\n\ninterface RestaurantParams<T extends string = string> {\n    name: T\n    onConfirm(dishName: T): Promise<void>\n    onReady(dishName: T): void\n    onDeliver(dishName: T): Promise<void>\n}\n\nasync function prepareDish({\n    name,\n    onConfirm,\n    onReady,\n    onDeliver,\n}: RestaurantParams): Promise<void> {\n    await onConfirm(name)\n\n    const randomTimeout: number =\n        Math.max(Math.ceil(Math.random() * 10), 1) * 1000\n\n    await new Promise((resolve) =>\n        setTimeout(() => {\n            onReady(name)\n            resolve(null)\n        }, randomTimeout)\n    )\n\n    await onDeliver(name)\n}\n\nPromise.all([\n    prepareDish({\n        name: 'Spaghetti',\n        async onConfirm(dishName) {\n            console.log(`${dishName} in preparation.`)\n        },\n        onReady(dishName) {\n            console.log(`${dishName} is ready to deliver.`)\n        },\n        async onDeliver(dishName) {\n            console.log(`${dishName} delivered.`)\n        },\n    }),\n    prepareDish({\n        name: 'Soup',\n        async onConfirm(dishName) {\n            console.log(`${dishName} in preparation.`)\n        },\n        onReady(dishName) {\n            console.log(`${dishName} is ready to deliver.`)\n        },\n        async onDeliver(dishName) {\n            console.log(`${dishName} delivered.`)\n        },\n    }),\n])\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/typescript/victoriaparraf.ts",
    "content": "// Definimos un tipo de callback que toma un número y devuelve void\ntype Callback = (result: number) => void;\n\nfunction add(a: number, b: number, callback: Callback): void {\n    const result = a + b;\n    callback(result);\n}\n\n// Función callback que imprime el resultado\nconst printResult: Callback = (result) => {\n    console.log('Resultado:', result);\n};\n\n// Llamamos a la función `add` con el callback `printResult`\nadd(3, 4, printResult); // Resultado: 7\n\n\n/******************************************************************* */\n\ntype ConfirmationCallback = (dishName: string) => void;\ntype ReadyCallback = (dishName: string) => void;\ntype DeliveryCallback = (dishName: string) => void;\n\nfunction processOrder(\n    dishName: string,\n    confirmation: ConfirmationCallback,\n    ready: ReadyCallback,\n    delivery: DeliveryCallback\n): void {\n    // Confirmar el pedido\n    confirmation(dishName);\n\n    // Simular el tiempo de preparación del plato\n    setTimeout(() => {\n        // El plato está listo\n        ready(dishName);\n\n        // Simular el tiempo de entrega del plato\n        setTimeout(() => {\n            // El plato ha sido entregado\n            delivery(dishName);\n        }, getRandomTime());\n    }, getRandomTime());\n}\n\nfunction getRandomTime(): number {\n    return Math.floor(Math.random() * 10000) + 1000; // Tiempo aleatorio entre 1 y 10 segundos\n}\n\nconst confirmOrder: ConfirmationCallback = (dishName) => {\n    console.log(`Pedido confirmado: ${dishName}`);\n};\n\nconst dishReady: ReadyCallback = (dishName) => {\n    console.log(`El plato está listo: ${dishName}`);\n};\n\nconst deliverDish: DeliveryCallback = (dishName) => {\n    console.log(`El plato ha sido entregado: ${dishName}`);\n};\n\n// Simulación de un pedido\nprocessOrder(\"Pizza Margherita\", confirmOrder, dishReady, deliverDish);\n"
  },
  {
    "path": "Roadmap/21 - CALLBACKS/vb.net/kenysdev.vb",
    "content": "' ╔══════════════════════════════════════╗\n' ║ Autor:  Kenys Alvarado               ║\n' ║ GitHub: https://github.com/Kenysdev  ║\n' ║ 2024 -  VB.NET                       ║\n' ╚══════════════════════════════════════╝\n'-----------------------------------------------\n'* CALLBACKS\n'-----------------------------------------------\n\nModule Program\n    '* EJERCICIO #1\n    '* Explora el concepto de callback en tu lenguaje creando un ejemplo\n    '* simple (a tu elección) que muestre su funcionamiento.\n\n    Delegate Sub CallbackDelegate(summands As String, result As Integer)\n\n    Sub SumNumbers(a As Integer, b As Integer, callback As CallbackDelegate)\n        Dim result As Integer = a + b\n        callback($\"{a} + {b}\", result)\n    End Sub\n\n    Sub MyCallback(summands As String, result As Integer)\n        Console.WriteLine($\"La suma de {summands} es: {result}\")\n    End Sub\n\n    '* EJERCICIO #2\n    '* Crea un simulador de pedidos de un restaurante utilizando callbacks.\n    '* Estará formado por una función que procesa pedidos.\n    '* Debe aceptar el nombre del plato, una callback de confirmación, una\n    '* de listo y otra de entrega.\n    '* - Debe imprimir un confirmación cuando empiece el procesamiento.\n    '* - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre\n    '*   procesos.\n    '* - Debe invocar a cada callback siguiendo un orden de procesado.\n    '* - Debe notificar que el plato está listo o ha sido entregado.\n\n    Async Function ProcessOrder(name As String, confirm As Func(Of String, Task),\n                                prepare As Func(Of String, Task),\n                                serving As Func(Of String, Task)) As Task\n        Console.WriteLine($\"-----{vbCrLf}* Procesando: '{name}'{vbCrLf}-----{vbCrLf}\")\n        Await confirm(name)\n        Await prepare(name)\n        Await serving(name)\n    End Function\n\n    Function TimeRandom() As Integer\n        Dim random As New Random()\n        Return random.Next(1, 11)\n    End Function\n\n    Async Function ConfirmOrder(ByVal name As String) As Task\n        Dim time As Integer = TimeRandom()\n        Console.WriteLine($\"* Confirmando {name}, espere {time} segundos.\")\n        Await Task.Delay(time * 1000)\n        Console.WriteLine($\"- '{name}', ha sido confirmado.{vbCrLf}\")\n    End Function\n\n    Async Function PrepareOrder(ByVal name As String) As Task\n        Dim time As Integer = TimeRandom()\n        Console.WriteLine($\"* Preparando, espere {time} segundos.\")\n        Await Task.Delay(time * 1000)\n        Console.WriteLine($\"- '{name}', esta Listo.{vbCrLf}\")\n    End Function\n\n    Async Function ServingOrder(ByVal name As String) As Task\n        Dim time As Integer = TimeRandom()\n        Console.WriteLine($\"* Sirviendo, espere {time} segundos.\")\n        Await Task.Delay(time * 1000)\n        Console.WriteLine($\"- '{name}', ha sido entregado.{vbCrLf}\")\n    End Function\n\n    Async Function Order(ByVal dishName As String) As Task\n        Await ProcessOrder(dishName, AddressOf ConfirmOrder, AddressOf PrepareOrder, AddressOf ServingOrder)\n    End Function\n\n    Async Function OrdersList() As Task\n        Await Order(\"Baleadas\")\n        Await Order(\"Tamales\")\n        Await Order(\"Enchiladas\")\n    End Function\n\n    Sub Main()\n        Console.WriteLine(\"EJERCICIO #1\")\n        SumNumbers(6, 6, AddressOf MyCallback)\n        SumNumbers(5, 2, AddressOf MyCallback)\n\n        Console.WriteLine(vbCrLf & \"EJERCICIO #2\")\n        OrdersList().Wait()\n    End Sub\n\nEnd Module\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/bash/rantamhack.sh",
    "content": "#!/bin/bash\n\necho -e \"\\n\\n=======================================EJERCICIO=======================================\\n\\n\"\n\n\n# * EJERCICIO:\n# * Explora el concepto de funciones de orden superior en tu lenguaje \n# * creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n\n\nfunction arithmetic() {\n    square_root $1\n    elevate_cube $2\n}    \n\nfunction square_root() {\n    local num1=$1\n    result=$(echo \"scale=2; sqrt($num1)\" | bc -l)\n    echo -e \"\\nEl resultado de la raiz cuadrada de $num1 es $result\\n\"\n}\nfunction elevate_cube() {\n    local num2=$1\n    result=$(echo \"scale=10; $num2 ^ 3\" | bc -l)\n    echo -e \"El resultado de elevar al cubo $num2 es $result\\n\\n\"\n}\n\n arithmetic 25 10\n\n\n\n\necho -e \"\\n\\n=======================================DIFICULTAD EXTRA=======================================\\n\\n\"\n \n\n\n# * DIFICULTAD EXTRA (opcional):\n# * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n# * lista de calificaciones), utiliza funciones de orden superior para \n# * realizar las siguientes operaciones de procesamiento y análisis:\n# * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n# *   y promedio de sus calificaciones.\n# * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n# *   que tienen calificaciones con un 9 o mas de promedio.\n# * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el mas joven.\n# * - Mayor calificación: Obtiene la calificación mas alta de entre todas las\n# *   de los alumnos.\n# * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n\n\n\n# Lista de estudiantes en formato JSON\nstudents='[\n    {\"name\":\"Rantam\", \"born_date\":\"29-05-2000\", \"grades\":[7.2, 9.0, 8.6]},\n    {\"name\":\"Helena\", \"born_date\":\"12-02-2005\", \"grades\":[9.8, 9.2, 8.7]},\n    {\"name\":\"Silvia\", \"born_date\":\"10-07-2003\", \"grades\":[8.5, 8.0, 8.4]},\n    {\"name\":\"Jose Luis\", \"born_date\":\"22-10-2003\", \"grades\":[7.0, 6.5, 7.4]},\n    {\"name\":\"Fernando\", \"born_date\":\"17-07-1998\", \"grades\":[5.0, 3.8, 4.6]},\n    {\"name\":\"Brais\", \"born_date\":\"11-06-2003\", \"grades\":[8.0, 9.4, 9.7]}\n]'\n\n# Función para calcular el promedio\ncalculate_average() {\n    local grades=(\"$@\")\n    local sum=0\n    local count=${#grades[@]}\n    for grade in \"${grades[@]}\"; do\n        sum=$(echo \"$sum + $grade\" | bc)\n    done\n    echo \"scale=2; $sum / $count\" | bc\n}\n\n# Función para obtener la nota media de los estudiantes\nget_average_grades() {\n    echo \"$students\" | jq -r '.[] | [.name, (.grades | map(tostring) | join(\" \"))] | @tsv' |\n    while IFS=$'\\t' read -r name grades; do\n        avg=$(calculate_average $grades)\n        echo -e \"$name\\t$avg\"\n    done\n}\n\n# Función para obtener los mejores estudiantes\nget_top_students() {\n    get_average_grades | awk -F'\\t' '$2 >= 9.0 { print $1, $2 }'\n}\n\n# Función para ordenar estudiantes desde el mas joven\nsort_students_by_age() {\n    echo \"$students\" | jq -r '.[] | [.name, .born_date] | @tsv' |\n    while IFS=$'\\t' read -r name born_date; do\n        # Convertir la fecha de DD-MM-YYYY a YYYY-MM-DD para una ordenación correcta\n        born_date_formatted=$(echo \"$born_date\" | awk -F'-' '{ printf \"%04d-%02d-%02d\", $3, $2, $1 }')\n        echo -e \"$name\\t$born_date_formatted\"\n    done | sort -t$'\\t' -k2,2r | awk -F'\\t' '{ printf \"%s\\t%s\\n\", $1, $2 }'\n}\n\n# Función para obtener la calificación mas alta\nget_highest_grade() {\n    echo \"$students\" | jq -r '.[] | .grades[]' | sort -nr | head -n1\n}\n\n# Ejecución de las funciones\necho -e \"\\nPromedio calificaciones:\\n\"\nget_average_grades\n\necho -e \"\\nMejores estudiantes:\"\nget_top_students\n\necho -e \"\\nEstudiantes ordenados desde el mas joven:\"\nsort_students_by_age\n\necho -e \"\\nMayor calificación:\"\nget_highest_grade\n\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/c#/hequebo.cs",
    "content": "class Program\n{\n    static void Main(string[] args)\n    {\n        /*\n         * Una función de orden superior o HOF por sus siglas\n         * en inglés es una función la cual recibe en sus\n         * argumentos una o más funciones o regresa una función\n         * o ambos\n         */\n        Console.WriteLine($\"{Operation(3, 6, Addition)}\");\n        Console.WriteLine($\"{Operation(3, 6, Substraction)}\");\n        Console.WriteLine($\"{Operation(3, 6, Multiplication)}\");\n\n        // Ejercicio Extra\n        Console.ReadLine();\n        Console.Clear();\n        var students = new List<Student>\n        {\n           new Student\n           {\n               Name =\"Emilio Quezada\", \n               Birthdate = new DateTime(1997, 07, 28),\n               Grades= new List<decimal>{8.5m, 9.8m, 8.3m, 8.5m }\n           },\n           new Student\n           {\n               Name =\"Aldo Díaz\",\n               Birthdate = new DateTime(1998, 10, 5),\n               Grades= new List<decimal>{9.5m, 9.9m, 8.3m, 8.9m }\n           },\n           new Student\n           {\n               Name =\"Samantha Ortega\",\n               Birthdate = new DateTime(1997, 03, 30),\n               Grades= new List<decimal>{8.6m, 9, 9.5m, 8.5m }\n           },\n        };\n        /*\n         * En .Net LINQ utiiliza funciones de orden superarior en las cuales reciben dentro\n         * de sus parámetros una expresión lambda\n         */\n        var averageList = students.Select(s => new { Name = s.Name, Average = Average(s.Grades) });\n        Console.WriteLine(\"---Promedios estudiantes---\");\n        foreach (var student in averageList )\n            Console.WriteLine($\"Nombre: {student.Name}, Promerdio: {student.Average}\");\n        \n        Console.WriteLine(\"---Cuadro de honor---\");\n        var bestStudents = students.Where(s => Average(s.Grades) >= 9).Select(s => new { Name = s.Name, Average = Average(s.Grades)});\n        foreach (var student in bestStudents)\n            Console.WriteLine($\"Nombre: {student.Name}, Promedio: {student.Average}\");\n        \n        Console.WriteLine(\"---Estudiante ordenados por edad---\");\n        var orderedStudents = students.OrderBy(s => s.Birthdate);\n        foreach (var student in orderedStudents)\n            Console.WriteLine($\"Nombre: {student.Name}, Fecha de Nacimiento: {student.Birthdate.ToShortDateString()}\");\n\n        Console.WriteLine(\"---Estudiate con calificación más alta---\");\n        var highestGrade = students.OrderByDescending(s => Max(s.Grades)).Select(s => new { Name = s.Name, Grade = Max(s.Grades) }).First();\n        Console.WriteLine($\"Nombre: {highestGrade.Name}, Calificación: {highestGrade.Grade}\");\n\n    }\n    static int Addition(int x,  int y) => x + y;\n    static int Substraction(int x, int y) => x - y;\n    static int Multiplication(int x, int y) => x * y;\n    /*\n     * La función Operation recibe en sus argumentos\n     * dos datos de tipo entero y una funcion(Func)\n     * la cual recibe dos datos de tipo entero y \n     * devuelve un tipo entero. \n     * Así mismo la función Operation devuelve una \n     * función.\n     */\n    static int Operation(int x, int y, Func<int, int, int> fn) => fn(x, y);\n    static decimal Average(List<decimal> grades) => grades.Sum() / grades.Count;\n    static decimal Max(List<decimal> grades) => grades.Max(g => g);\n    \n\n}\nclass Student\n{\n    public string Name { get; set; }\n    public DateTime Birthdate { get; set; }\n    public List<decimal> Grades { get; set; }\n}\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/c#/jamerrq.cs",
    "content": "﻿/*\r\n * EJERCICIO:\r\n * Explora el concepto de funciones de orden superior en tu lenguaje\r\n * creando ejemplos simples (a tu elección) que muestren su funcionamiento.\r\n *\r\n * DIFICULTAD EXTRA (opcional):\r\n * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y\r\n * lista de calificaciones), utiliza funciones de orden superior para\r\n * realizar las siguientes operaciones de procesamiento y análisis:\r\n * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\r\n *   y promedio de sus calificaciones.\r\n * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\r\n *   que tienen calificaciones con un 9 o más de promedio.\r\n * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\r\n * - Mayor calificación: Obtiene la calificación más alta de entre todas las\r\n *   de los alumnos.\r\n * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\r\n */\r\n\r\nusing System;\r\n\r\nnamespace Roadmap22\r\n{\r\n    class SuperFunctions\r\n    {\r\n        public static double Average(double[] numbers)\r\n        {\r\n            double sum = 0;\r\n            foreach (double number in numbers)\r\n            {\r\n                sum += number;\r\n            }\r\n            return sum / numbers.Length;\r\n        }\r\n\r\n        public static double Max(double[] numbers)\r\n        {\r\n            double max = numbers[0];\r\n            foreach (double number in numbers)\r\n            {\r\n                if (number > max)\r\n                {\r\n                    max = number;\r\n                }\r\n            }\r\n            return max;\r\n        }\r\n\r\n        public static double Min(double[] numbers)\r\n        {\r\n            double min = numbers[0];\r\n            foreach (double number in numbers)\r\n            {\r\n                if (number < min)\r\n                {\r\n                    min = number;\r\n                }\r\n            }\r\n            return min;\r\n        }\r\n\r\n        public static double[] Filter(double[] numbers, Func<double, bool> condition)\r\n        {\r\n            int count = 0;\r\n            foreach (double number in numbers)\r\n            {\r\n                if (condition(number))\r\n                {\r\n                    count++;\r\n                }\r\n            }\r\n\r\n            double[] result = new double[count];\r\n            int index = 0;\r\n            foreach (double number in numbers)\r\n            {\r\n                if (condition(number))\r\n                {\r\n                    result[index] = number;\r\n                    index++;\r\n                }\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        public static double[] Map(double[] numbers, Func<double, double> operation)\r\n        {\r\n            double[] result = new double[numbers.Length];\r\n            for (int i = 0; i < numbers.Length; i++)\r\n            {\r\n                result[i] = operation(numbers[i]);\r\n            }\r\n            return result;\r\n        }\r\n\r\n        public static double[] Reduce(double[] numbers, Func<double, double, double> operation)\r\n        {\r\n            double result = numbers[0];\r\n            for (int i = 1; i < numbers.Length; i++)\r\n            {\r\n                result = operation(result, numbers[i]);\r\n            }\r\n            return new double[] { result };\r\n        }\r\n\r\n        public static void Main(string[] args)\r\n        {\r\n            double[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };\r\n\r\n            Console.WriteLine(\"Average: \" + Average(numbers));\r\n            Console.WriteLine(\"Max: \" + Max(numbers));\r\n            Console.WriteLine(\"Min: \" + Min(numbers));\r\n\r\n            double[] evenNumbers = Filter(numbers, number => number % 2 == 0);\r\n            Console.WriteLine(\"Even numbers: \" + string.Join(\", \", evenNumbers));\r\n\r\n            double[] squaredNumbers = Map(numbers, number => number * number);\r\n            Console.WriteLine(\"Squared numbers: \" + string.Join(\", \", squaredNumbers));\r\n\r\n            double[] sum = Reduce(numbers, (a, b) => a + b);\r\n            Console.WriteLine(\"Sum: \" + sum[0]);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/c#/kenysdev.cs",
    "content": "/*\n╔══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado               ║\n║ GitHub: https://github.com/Kenysdev  ║\n║ 2024 -  C#                           ║\n╚══════════════════════════════════════╝\n------------------------------------------\n* FUNCIONES DE ORDEN SUPERIOR\n------------------------------------------\n*/\n\n#pragma warning disable CA1050\nclass Program {\n    /*\n    * EJERCICIO #1:\n    * Explora el concepto de funciones de orden superior en tu lenguaje \n    * creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n    */\n    delegate int ArithmeticOperation(int x, int y);\n\n    static Func<int, int, int> ArithmeticOp(ArithmeticOperation operation) {\n        return (x, y) => operation(x, y);\n    }\n\n    static int Add(int x, int y) {\n        return x + y;\n    }\n\n    static int Subtract(int x, int y) {\n        return x - y;\n    }\n\n    static int Multiply(int x, int y) {\n        return x * y;\n    }\n\n    /*\n    * EJERCICIO #2:\n    * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n    * lista de calificaciones), utiliza funciones de orden superior para \n    * realizar las siguientes operaciones de procesamiento y análisis:\n    * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n    *   y promedio de sus calificaciones.\n    * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n    *   que tienen calificaciones con un 9 o más de promedio.\n    * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n    * - Mayor calificación: Obtiene la calificación más alta de entre todas las\n    *   de los alumnos.\n    * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n    */\n\n    static readonly List<Dictionary<string, object>> studentsList = [\n        new() { {\"name\", \"Ken\"}, {\"dob\", \"2012-04-21\"}, {\"grades\", new List<double> {9.5, 9.4, 9.3, 9.2} } },\n        new() { {\"name\", \"Ben\"}, {\"dob\", \"2012-03-20\"}, {\"grades\", new List<double> {8.5, 8.4, 8.3, 8.2} } },\n        new() { {\"name\", \"Ada\"}, {\"dob\", \"2012-02-19\"}, {\"grades\", new List<double> {7.5, 7.4, 7.3, 7.2} } },\n        new() { {\"name\", \"Zoe\"}, {\"dob\", \"2012-01-18\"}, {\"grades\", new List<double> {9.0, 9.1, 9.0, 9.1} } }\n    ];\n\n    delegate void PrintFunction(Dictionary<string, object> student);\n\n    static Action<List<Dictionary<string, object>>> HigherOrderFun(string msg, PrintFunction printFn) {\n        void wrapper(List<Dictionary<string, object>> students) {\n            Console.WriteLine($\"\\n----\\n{msg}\");\n            foreach (var student in students) {\n                printFn(student);\n            }\n        }\n\n        return wrapper;\n    }\n\n\n    static void PrintGradePointAverage(Dictionary<string, object> student) {\n        var grades = (List<double>)student[\"grades\"];\n        double averageGrade = grades.Sum() / grades.Count;\n        Console.WriteLine($\"{student[\"name\"]} {averageGrade}\");\n    }\n\n    static void PrintTopStudents(Dictionary<string, object> student) {\n        var grades = (List<double>)student[\"grades\"];\n        double average = grades.Sum() / grades.Count;\n        if (average >= 9) {\n            Console.WriteLine(student[\"name\"]);\n        }\n    }\n\n    static void PrintBirthOrder(Dictionary<string, object> student) {\n        Console.WriteLine($\"{student[\"name\"]} {student[\"dob\"]}\");\n    }\n\n    static void PrintHighestGrade(Dictionary<string, object> student) {\n        double  maxGrade = ((List<double>)student[\"grades\"]).Max();\n        Console.WriteLine($\"{student[\"name\"]} {maxGrade}\");\n    }\n\n    static void Main() {\n        Console.WriteLine(\"EJERCICIO #1\");\n        var addFunc = ArithmeticOp(Add);\n        var subtractFunc = ArithmeticOp(Subtract); \n        var multiplyFunc = ArithmeticOp(Multiply);\n\n        Console.WriteLine(addFunc(3, 5));\n        Console.WriteLine(subtractFunc(10, 3));\n        Console.WriteLine(multiplyFunc(2, 4));\n\n        Console.WriteLine(\"EJERCICIO #2\");\n        var gradePointAverage = HigherOrderFun(\"Promedio calificaciones\", PrintGradePointAverage);\n        var topStudents = HigherOrderFun(\"Mejores estudiantes:\", PrintTopStudents);\n        var birthOrder = HigherOrderFun(\"Por nacimiento:\", PrintBirthOrder);\n        var highestGrade = HigherOrderFun(\"Mayor calificación:\", PrintHighestGrade);\n\n        gradePointAverage(studentsList);\n        topStudents(studentsList);\n        birthOrder([.. studentsList.OrderBy(student => (string)student[\"dob\"])]);\n        highestGrade(studentsList);\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/c++/hectorio23.cpp",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n#include <algorithm> // Libreria con un conjunto de algoritmos\n#include <iostream>\n#include <vector>\n#include <string>\n#include <numeric>\n#include <iomanip> // Para setprecision\n#include <ctime>   // Para manejo de fechas\n\n/*\n * EJERCICIO:\n * Explora el concepto de funciones de orden superior en tu lenguaje \n * creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n *\n * DIFICULTAD EXTRA (opcional):\n * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n * lista de calificaciones), utiliza funciones de orden superior para \n * realizar las siguientes operaciones de procesamiento y análisis:\n * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n *   y promedio de sus calificaciones.\n * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n *   que tienen calificaciones con un 9 o más de promedio.\n * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n * - Mayor calificación: Obtiene la calificación más alta de entre todas las\n *   de los alumnos.\n * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n*/\n\n// Definimos una estructura para representar a un estudiante\nstruct Student {\n    std::string name;\n    std::string birthdate;\n    std::vector<double> grades;\n};\n\n// Función para calcular el promedio de una lista de calificaciones\ndouble average(const std::vector<double>& grades) {\n    if (grades.empty()) return 0.0;\n    double sum = std::accumulate(grades.begin(), grades.end(), 0.0);\n    return sum / grades.size();\n}\n\n// Función para convertir una fecha en formato string a time_t\ntime_t stringToDate(const std::string& date) {\n    struct tm tm{};\n    strptime(date.c_str(), \"%Y-%m-%d\", &tm);\n    return mktime(&tm);\n}\n\nint main() {\n    // Lista de estudiantes\n    std::vector<Student> students = {\n        {\"Adán\", \"2004-06-28\", {9.7, 10.0, 9.9}},\n        {\"Andy\", \"2006-07-17\", {9.5, 9.0, 9.0}},\n        {\"Mauricer\", \"2004-03-15\", {6.0, 7.5, 8.0}},\n        {\"David\", \"2005-06-30\", {10.0, 9.5, 9.5}}\n    };\n\n    // Promedio de calificaciones\n    std::cout << \"Promedio de calificaciones:\" << std::endl;\n    for (const auto& student : students) {\n        double avg = average(student.grades);\n        std::cout << student.name << \": \" << std::fixed << std::setprecision(2) << avg << std::endl;\n    }\n    \n    // Mejores estudiantes\n    std::cout << \"\\nMejores estudiantes (promedio >= 9):\" << std::endl;\n    for (const auto& student : students) {\n        if (average(student.grades) >= 9.0) {\n            std::cout << student.name << std::endl;\n        }\n    }\n\n    // Ordenar estudiantes por fecha de nacimiento, de más joven a más viejo\n    // Funcion de orden superior\n    std::sort(students.begin(), students.end(), [](const Student& a, const Student& b) {\n        return stringToDate(a.birthdate) > stringToDate(b.birthdate);\n    });\n\n    std::cout << \"\\nEstudiantes ordenados por nacimiento (de más joven a más viejo):\" << std::endl;\n    for (const auto& student : students) {\n        std::cout << student.name << \": \" << student.birthdate << std::endl;\n    }\n\n    // Mayor calificación entre todos los estudiantes\n    double highest_grade = 0.0;\n    for (const auto& student : students) {\n        for (double grade : student.grades) {\n            if (grade > highest_grade) {\n                highest_grade = grade;\n            }\n        }\n    }\n\n    std::cout << \"\\nMayor calificación entre todos los estudiantes: \" << highest_grade << std::endl;\n\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/c++/rawC1nnamon.cpp",
    "content": "/*\n┌───────────────────────────────────┐\n│  Autor: Camilo C.                 │\n│  Lenguaje: C++                    │\n└───────────────────────────────────┘\n*/\n\n#include <iostream>\n#include <cmath>\n#include <functional>\n\nusing namespace std;\n\n/*                                          [Explicación básica]\n                                           [Funciones superiores]                                      */\n\n// Función que usa otra función como argumento con punteros:\nvoid Q_sqrt(double (*func)(double), double value){\n    cout << func(value) << endl;\n}\n\n// Función que tiene un lambda como parámetro:\nvoid lambdaArgs(const function<int(int, int)>& func, int n1, int n2) {\n    cout << func(n1, n2) << endl;\n}\n\nint main()\n{\n    Q_sqrt(sqrt, 5); // Se pasa como argumento sqrt que ya está definida en la biblioteca estándar de C/C++.\n                     // También se debe pasar como argumento el número al que se le quiere sacar raíz. -> Devuelve 2.236\n    lambdaArgs([](int x, int y) { return x + y; }, 5, 6); // Suma los dos argumentos -> Devuelve 11\n\n    return 0;        \n}\n\n\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/ejercicio.md",
    "content": "# #22 FUNCIONES DE ORDEN SUPERIOR\n> #### Dificultad: Difícil | Publicación: 27/05/24 | Corrección: 03/06/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Explora el concepto de funciones de orden superior en tu lenguaje \n * creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n *\n * DIFICULTAD EXTRA (opcional):\n * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n * lista de calificaciones), utiliza funciones de orden superior para \n * realizar las siguientes operaciones de procesamiento y análisis:\n * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n *   y promedio de sus calificaciones.\n * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n *   que tienen calificaciones con un 9 o más de promedio.\n * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n * - Mayor calificación: Obtiene la calificación más alta de entre todas las\n *   de los alumnos.\n * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/go/N0HagoNada.go",
    "content": "package main\n\nimport \"fmt\"\n\n// Función de orden superior que toma otra función como argumento\nfunc aplicarOperacion(a, b int, operacion func(int, int) int) int {\n\treturn operacion(a, b)\n}\n\n// Función que suma dos números\nfunc sumar(a, b int) int {\n\treturn a + b\n}\n\n// Función que multiplica dos números\nfunc multiplicar(a, b int) int {\n\treturn a * b\n}\n\n// Función de orden superior que retorna una función\nfunc crearMultiplicador(factor int) func(int) int {\n\treturn func(num int) int {\n\t\treturn num * factor\n\t}\n}\nfunc main() {\n\t// Llamar a la función de orden superior pasando diferentes funciones como argumentos\n\tresultado := aplicarOperacion(5, 3, sumar)\n\tfmt.Println(\"Suma: 5 + 3 =\", resultado)\n\n\tresultado = aplicarOperacion(5, 3, multiplicar)\n\tfmt.Println(\"Multiplicación: 5 * 3 =\", resultado)\n\n\tduplicar := crearMultiplicador(2)\n\ttriplicar := crearMultiplicador(3)\n\n\t// Usar las funciones multiplicadoras\n\tfmt.Println(\"Duplicar 5:\", duplicar(5))\n\tfmt.Println(\"Triplicar 5:\", triplicar(5))\n}\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/go/hozlucas28.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"slices\"\n\t\"sort\"\n\t\"strings\"\n\t\"time\"\n)\n\n/* -------------------------------------------------------------------------- */\n/*                                    TYPES                                   */\n/* -------------------------------------------------------------------------- */\n\n/* --------------------------------- Student -------------------------------- */\n\ntype Student struct {\n\tbornDate       time.Time\n\tname           string\n\tqualifications []float32\n}\n\ntype Students []Student\n\nfunc (students Students) Print() {\n\tfor _, student := range students {\n\t\tvar studentBornDate string = fmt.Sprintf(\n\t\t\t\"%02d-%02d-%4d\",\n\t\t\tstudent.bornDate.Month(),\n\t\t\tstudent.bornDate.Day(),\n\t\t\tstudent.bornDate.Year(),\n\t\t)\n\n\t\tfmt.Printf(\"\\n%s / %s / %.2f\", student.name, studentBornDate, student.qualifications)\n\t}\n}\n\ntype SortByYoungestBornDate Students\n\nfunc (students SortByYoungestBornDate) Len() int { return len(students) }\nfunc (students SortByYoungestBornDate) Swap(i, j int) {\n\tstudents[i], students[j] = students[j], students[i]\n}\nfunc (students SortByYoungestBornDate) Less(i, j int) bool {\n\treturn students[i].bornDate.After(students[j].bornDate)\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                  FUNCTIONS                                 */\n/* -------------------------------------------------------------------------- */\n\nfunc Average(numbers ...float32) float32 {\n\tvar total float32\n\n\tfor _, number := range numbers {\n\t\ttotal += number\n\t}\n\n\treturn total / float32(len(numbers))\n}\n\nfunc ToFiltered[T any](slice []T, filterFn func(element T) bool) []T {\n\tvar filteredSlice []T\n\n\tfor _, element := range slice {\n\t\tif filterFn(element) {\n\t\t\tfilteredSlice = append(filteredSlice, element)\n\t\t}\n\t}\n\n\treturn filteredSlice\n}\n\nfunc ToMap[T any](array []T, callback func(element T, index int) T) []T {\n\tvar arrayCopy []T\n\n\tfor index, element := range array {\n\t\tvar mappedElement T = callback(element, index)\n\t\tarrayCopy = append(arrayCopy, mappedElement)\n\t}\n\n\treturn arrayCopy\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\nfunc main() {\n\t/*\n\t\tHigher order functions (HOF)...\n\t*/\n\n\tfmt.Println(\"Higher order functions (HOF)...\")\n\n\tvar names []string = []string{\n\t\t\"john\",\n\t\t\"mary\",\n\t\t\"david\",\n\t\t\"sarah\",\n\t\t\"james\",\n\t}\n\tfmt.Printf(\"\\nnames=%#v\\n\", names)\n\n\tvar capitalizedNames []string = ToMap(names, func(name string, index int) string {\n\t\tname = strings.TrimSpace(name)\n\t\treturn strings.ToUpper(string(name[0])) + name[1:]\n\t})\n\tfmt.Printf(\"\\ncapitalizedNames=%#v\\n\", capitalizedNames)\n\n\tvar uppercasedNames []string = ToMap(names, func(name string, index int) string {\n\t\tname = strings.TrimSpace(name)\n\t\treturn strings.ToUpper(name)\n\t})\n\n\tfmt.Printf(\"\\nuppercasedNames=%#v\\n\", uppercasedNames)\n\n\tfmt.Println(\"\\n# ---------------------------------------------------------------------------------- #\")\n\n\t/*\n\t\tAdditional challenge...\n\t*/\n\n\tfmt.Println(\"\\nAdditional challenge...\")\n\n\tvar students Students = []Student{\n\t\t{\n\t\t\tbornDate:       time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC),\n\t\t\tname:           \"Alice\",\n\t\t\tqualifications: []float32{8.5, 9.0, 7.8},\n\t\t},\n\t\t{\n\t\t\tbornDate:       time.Date(1999, time.February, 15, 0, 0, 0, 0, time.UTC),\n\t\t\tname:           \"Bob\",\n\t\t\tqualifications: []float32{7.2, 6.8, 8.0},\n\t\t},\n\t\t{\n\t\t\tbornDate:       time.Date(2001, time.January, 10, 0, 0, 0, 0, time.UTC),\n\t\t\tname:           \"Charlie\",\n\t\t\tqualifications: []float32{9.5, 8.7, 9.2},\n\t\t},\n\t\t{\n\t\t\tbornDate:       time.Date(2002, time.February, 5, 0, 0, 0, 0, time.UTC),\n\t\t\tname:           \"David\",\n\t\t\tqualifications: []float32{6.5, 7.0, 7.8},\n\t\t},\n\t\t{\n\t\t\tbornDate:       time.Date(2000, time.May, 20, 0, 0, 0, 0, time.UTC),\n\t\t\tname:           \"Eve\",\n\t\t\tqualifications: []float32{8.0, 8.5, 7.2},\n\t\t},\n\t\t{\n\t\t\tbornDate:       time.Date(1999, time.June, 25, 0, 0, 0, 0, time.UTC),\n\t\t\tname:           \"Frank\",\n\t\t\tqualifications: []float32{7.8, 7.5, 8.2},\n\t\t},\n\t\t{\n\t\t\tbornDate:       time.Date(2001, time.February, 15, 0, 0, 0, 0, time.UTC),\n\t\t\tname:           \"Grace\",\n\t\t\tqualifications: []float32{9.0, 9.2, 8.7},\n\t\t},\n\t\t{\n\t\t\tbornDate:       time.Date(2002, time.December, 10, 0, 0, 0, 0, time.UTC),\n\t\t\tname:           \"Henry\",\n\t\t\tqualifications: []float32{9.4, 7.87, 10.00},\n\t\t},\n\t}\n\n\tfmt.Println(\"\\nStudents...\")\n\tstudents.Print()\n\n\tfmt.Println(\"\\n\\nStudents with name and average qualification...\")\n\tfor _, student := range students {\n\t\tvar averageQualification float32 = Average(student.qualifications...)\n\t\tfmt.Printf(\"\\n%s / %.2f\", student.name, averageQualification)\n\t}\n\n\tvar studentsWithAverageQualificationMoreThanNine Students = ToFiltered(students, func(student Student) bool {\n\t\treturn Average(student.qualifications...) >= 9\n\t})\n\n\tfmt.Println(\"\\n\\nStudents with an average qualification more than nine...\")\n\tstudentsWithAverageQualificationMoreThanNine.Print()\n\n\tvar sortedStudentsByBornDate Students = slices.Clone(students)\n\tsort.Sort(SortByYoungestBornDate(sortedStudentsByBornDate))\n\n\tfmt.Println(\"\\n\\nSorted students by born date (youngest to oldest)...\")\n\tsortedStudentsByBornDate.Print()\n\n\tfmt.Println(\"\\n\\nStudents with name and best qualification...\")\n\tfor _, student := range students {\n\t\tvar bestQualification float32 = slices.Max(student.qualifications)\n\t\tfmt.Printf(\"\\n%s / %.2f\", student.name, bestQualification)\n\t}\n}\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/go/kodenook.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc main() {\n\tn1 := 2\n\tn2 := 3\n\n\tresult := apply(n1, n2, add)\n\n\tfmt.Println(result)\n}\n\nfunc apply(n1, n2 int, operation func(int, int) int) int {\n\treturn operation(n1, n2)\n}\n\nfunc add(n1, n2 int) int {\n\treturn n1 + n2\n}\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/go/qwik-zgheib.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"sort\"\n\t\"time\"\n)\n\n/* -- i -- Pass functions as arguments */\n\nfunc applyToEach(f func(int) int, list []int) []int {\n\tresult := make([]int, len(list))\n\tfor i, v := range list {\n\t\tresult[i] = f(v)\n\t}\n\treturn result\n}\n\nfunc square(n int) int {\n\treturn n * n\n}\n\nfunc increment(n int) int {\n\treturn n + 1\n}\n\n/* -- ii -- Return functions as results */\nfunc makeMultiplier(multiplier int) func(int) int {\n\treturn func(n int) int {\n\t\treturn n * multiplier\n\t}\n}\n\n/* -- iii -- Anonymous functions and closures */\nfunc filter(list []int, predicate func(int) bool) []int {\n\tvar result []int\n\tfor _, v := range list {\n\t\tif predicate(v) {\n\t\t\tresult = append(result, v)\n\t\t}\n\t}\n\treturn result\n}\n\n/* -- extra challenge */\n\ntype Student struct {\n\tName      string\n\tBirthDate time.Time\n\tGrades    []float64\n}\n\n// StudentProcessor -> Higher-order functions for student operations\ntype StudentProcessor struct{}\n\nfunc NewStudentProcessor() *StudentProcessor {\n\treturn &StudentProcessor{}\n}\n\nfunc (sp *StudentProcessor) AverageGrades(students []Student) map[string]float64 {\n\taverages := make(map[string]float64)\n\tfor _, student := range students {\n\t\tsum := 0.0\n\t\tfor _, grade := range student.Grades {\n\t\t\tsum += grade\n\t\t}\n\t\taverages[student.Name] = sum / float64(len(student.Grades))\n\t}\n\treturn averages\n}\n\nfunc (sp *StudentProcessor) BestStudents(students []Student) []string {\n\tvar bestStudents []string //bestStudents := []string{}\n\tfor _, student := range students {\n\t\taverage := sp.AverageGrades([]Student{student})[student.Name]\n\t\tif average >= 9 {\n\t\t\tbestStudents = append(bestStudents, student.Name)\n\t\t}\n\t}\n\treturn bestStudents\n}\n\nfunc (sp *StudentProcessor) SortByBirthDate(students []Student) []Student {\n\tsortedStudents := make([]Student, len(students))\n\tcopy(sortedStudents, students)\n\tsort.Slice(sortedStudents, func(i, j int) bool {\n\t\treturn sortedStudents[i].BirthDate.After(sortedStudents[j].BirthDate)\n\t})\n\treturn sortedStudents\n}\n\nfunc (sp *StudentProcessor) HighestGrade(students []Student) float64 {\n\thighest := 0.0\n\tfor _, student := range students {\n\t\tfor _, grade := range student.Grades {\n\t\t\tif grade > highest {\n\t\t\t\thighest = grade\n\t\t\t}\n\t\t}\n\t}\n\treturn highest\n}\n\nfunc main() {\n\t/* -- i */\n\tlist := []int{1, 2, 3, 4, 5}\n\n\tsquaredList := applyToEach(square, list)\n\tfmt.Println(\"Squared List:\", squaredList)\n\n\tincrementedList := applyToEach(increment, list)\n\tfmt.Println(\"Incremented List:\", incrementedList)\n\n\t/* -- ii */\n\tmultiplyByTwo := makeMultiplier(2)\n\tfmt.Println(\"3 * 2 =\", multiplyByTwo(3))\n\n\tmultiplyByFive := makeMultiplier(5)\n\tfmt.Println(\"3 * 5 =\", multiplyByFive(3))\n\n\t/* -- iii */\n\tlist = []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}\n\n\tevenNumbers := filter(list, func(n int) bool {\n\t\treturn n%2 == 0\n\t})\n\tfmt.Println(\"Even Numbers:\", evenNumbers)\n\n\tthreshold := 5\n\tgreaterThanThreshold := filter(list, func(n int) bool {\n\t\treturn n > threshold\n\t})\n\tfmt.Println(\"Numbers greater than threshold:\", greaterThanThreshold)\n\n\t/* -- extra challenge */\n\tstudents := []Student{\n\t\t{\"Alice\", time.Date(2000, 5, 14, 0, 0, 0, 0, time.UTC), []float64{8.5, 9.0, 9.5}},\n\t\t{\"Bob\", time.Date(1999, 3, 21, 0, 0, 0, 0, time.UTC), []float64{7.0, 6.5, 8.0}},\n\t\t{\"Charlie\", time.Date(2001, 7, 30, 0, 0, 0, 0, time.UTC), []float64{9.0, 9.5, 9.8}},\n\t}\n\n\tprocessor := NewStudentProcessor()\n\n\taverages := processor.AverageGrades(students)\n\tfmt.Println(\"Average Grades:\")\n\tfor name, avg := range averages {\n\t\tfmt.Printf(\"%s: %.2f\\n\", name, avg)\n\t}\n\n\tbestStudents := processor.BestStudents(students)\n\tfmt.Println(\"\\nBest Students:\")\n\tfor _, name := range bestStudents {\n\t\tfmt.Println(name)\n\t}\n\n\tsortedStudents := processor.SortByBirthDate(students)\n\tfmt.Println(\"\\nStudents sorted by birth date (youngest first):\")\n\tfor _, student := range sortedStudents {\n\t\tfmt.Printf(\"%s: %s\\n\", student.Name, student.BirthDate.Format(\"2006-01-02\"))\n\t}\n\n\thighestGrade := processor.HighestGrade(students)\n\tfmt.Printf(\"\\nHighest Grade: %.2f\\n\", highestGrade)\n}\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/go/raynerpv2022.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"sort\"\n\t\"strings\"\n\t\"time\"\n)\n\n/*\n#  * EJERCICIO:\n#  * Explora el concepto de funciones de orden superior en tu lenguaje\n#  * creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y\n#  * lista de calificaciones), utiliza funciones de orden superior para\n#  * realizar las siguientes operaciones de procesamiento y análisis:\n#  * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n#  *   y promedio de sus calificaciones.\n#  * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n#  *   que tienen calificaciones con un 9 o más de promedio.\n#  * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n#  * - Mayor calificación: Obtiene la calificación más alta de entre todas las\n#  *   de los alumnos.\n#  * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n#  */\n\n//  Pasar una función como argumento a otra función.\n\n// Interface\nfunc Func_root(x interface{}, y interface{}, f func(interface{}, interface{}) interface{}) interface{} {\n\treturn f(x, y)\n}\n\nfunc sum_number(n1 interface{}, n2 interface{}) interface{} {\n\treturn n1.(int) + n2.(int)\n}\n\nfunc sum_string(s1 interface{}, s2 interface{}) interface{} {\n\treturn fmt.Sprintf(\"%v %v\\n\", s1.(string), s2.(string))\n}\n\n// Genereic\nfunc Func_rootG[Gen any](x, y Gen, f func(Gen, Gen) Gen) Gen {\n\treturn f(x, y)\n}\n\nfunc sum_numberG(n1 int, n2 int) int {\n\treturn n1 + n2\n}\n\nfunc sum_stringG(s1 string, s2 string) string {\n\treturn fmt.Sprintf(\"%v %v\\n\", s1, s2)\n}\n\n// Devolver funciones\n\nfunc Return_Func(x int) func(int) int {\n\treturn func(number int) int {\n\t\treturn number * x\n\t}\n\n}\n\n// implementacion de map, filter  porque en go no existe nativamente\n// map\nfunc mapF[T any](f func(T) T, slice []T) []T {\n\tresult := []T{}\n\tfor _, i := range slice {\n\t\tresult = append(result, f(i))\n\t}\n\treturn result\n\n}\n\nfunc Qua2(x int) int {\n\treturn x * x\n}\n\n// filter\n\nfunc filterF[T any](slice1 []T, f func(T) bool) []T {\n\n\tresult := []T{}\n\tfor _, i := range slice1 {\n\n\t\tif f(i) {\n\t\t\tresult = append(result, i)\n\t\t}\n\n\t}\n\treturn result\n}\n\nfunc even_number(x int) bool {\n\treturn x%2 == 0\n}\n\nfunc odd_number(x int) bool {\n\treturn x%2 != 0\n}\n\n// reduce\n\nfunc reduceF[T any](slice1 []T, f func(x, y T) T) T {\n\tvar result T\n\tfor _, i := range slice1 {\n\t\tresult = f(result, i)\n\n\t}\n\treturn result\n}\n\n// Extra\n\ntype kv struct {\n\tkey   string\n\tvalue float64\n}\n\ntype Student struct {\n\tname        string\n\tdateBorn    time.Time\n\tnote        map[string]float64\n\taverageNote float64\n\tbestMateria kv\n}\n\n// promedio de calidicaciones, usare reduceF\n\nfunc (s *Student) AverageNote() { // point when variable is a map\n\tnoteValue := []float64{}\n\tfor _, v := range s.note {\n\t\tnoteValue = append(noteValue, v)\n\t}\n\n\tsumNote := reduceF(noteValue, func(acc, n float64) float64 {\n\t\treturn acc + n\n\t})\n\ts.averageNote = sumNote / float64(len(noteValue))\n\n}\n\nfunc (s *Student) OrderNote() {\n\tKV := []kv{}\n\tfor k, v := range s.note {\n\t\tKV = append(KV, kv{k, v})\n\t}\n\tsort.Slice(KV, func(x, y int) bool {\n\t\treturn KV[x].value > (KV[y].value)\n\t})\n\n\tfor _, v := range KV {\n\t\tfmt.Printf(\"Materia: %v, Note: %v\\n\", v.key, v.value)\n\t}\n\ts.bestMateria = KV[0]\n\n}\n\ntype Students []Student\n\nfunc BestStudient(student Student) bool {\n\treturn student.averageNote >= 9.0 // aqui paso como argumento el elemnto que paso en el slice de filterF\n\t// no puedo pasar la nota, porque el slice esta compuesto de Student y eso es lo que paso\n}\n\nfunc (s Students) SortByDateBorn() {\n\tsort.Slice(s, func(i, j int) bool {\n\t\treturn s[i].dateBorn.Before(s[j].dateBorn) // Ordena en orden ascendente\n\t})\n}\n\nfunc (s Students) Display() {\n\tfor _, i := range s {\n\t\tfmt.Printf(\"\\tName: %v, Ano: %v, Mes : %v, Dia : %v\\n\", i.name, i.dateBorn.Year(), i.dateBorn.Month(), i.dateBorn.Day())\n\t\tfmt.Printf(\"Promedio: %.2f,mejor asignatura: %v,  Notas: %v\\n\", i.averageNote, i.bestMateria, i.note)\n\t}\n}\n\nfunc main() {\n\tf1 := Func_root(21, 21, sum_number)\n\tfmt.Println(f1)\n\tf1 = Func_root(\"Resba\", \"loso\", sum_string)\n\tfmt.Println(f1)\n\n\tf1 = Func_rootG(210, 210, sum_numberG)\n\tfmt.Println(f1)\n\tf1 = Func_rootG(\"Resbaloso\", \"tiburcio\", sum_stringG)\n\tfmt.Println(f1)\n\n\tf2 := Return_Func(100) //return_func retorna una funcion\n\tfmt.Println(f2(2))     // f2 es una funcion retornada que recibe parametro\n\n\t// map\n\tlist1 := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}\n\tQ_list := mapF(Qua2, list1)\n\tfmt.Println(Q_list)\n\n\tlist2 := []string{\"mama\", \"loka\"}\n\tQ_list2 := mapF(func(n string) string {\n\t\treturn strings.ToUpper(n)\n\n\t}, list2)\n\tfmt.Println(Q_list2)\n\n\t// filter\n\tQ_list3 := filterF(list1, even_number)\n\tQ_list4 := filterF(list1, odd_number)\n\tfmt.Printf(\"Even Number: %v\\n Odd NUmber : %v\\n\", Q_list3, Q_list4)\n\n\t// reduce\n\tlist4 := []string{\"r\", \"e\", \"s\", \"b\", \"a\"}\n\tQ_list5 := reduceF(list1, func(x, y int) int {\n\t\treturn x + y\n\t})\n\n\tQ_list6 := reduceF(list4, func(x, y string) string {\n\t\treturn x + y\n\t})\n\n\tfmt.Println(Q_list5)\n\tfmt.Println(Q_list6)\n\n\t// Extra\n\n\tstudent := Students{\n\t\tStudent{\n\t\t\t\"perico 3\",\n\t\t\ttime.Date(2001, 1, 1, 0, 0, 0, 0, time.UTC),\n\t\t\tmap[string]float64{\n\t\t\t\t\"ma\": 9.0,\n\t\t\t\t\"l\":  5.6,\n\t\t\t\t\"EF\": 9.9,\n\t\t\t},\n\t\t\t0,\n\t\t\tkv{\"\", 0.0},\n\t\t},\n\t\tStudent{\n\t\t\t\"perico 2\",\n\t\t\ttime.Date(2000, 10, 10, 0, 0, 0, 0, time.UTC),\n\t\t\tmap[string]float64{\n\t\t\t\t\"ma\": 9.2,\n\t\t\t\t\"l\":  9.5,\n\t\t\t\t\"EF\": 8.7,\n\t\t\t},\n\t\t\t0,\n\t\t\tkv{\"\", 0.0},\n\t\t},\n\t\tStudent{\n\t\t\t\"perico 1\",\n\t\t\ttime.Date(2011, 12, 12, 0, 0, 0, 0, time.UTC),\n\t\t\tmap[string]float64{\n\t\t\t\t\"ma\": 9.0,\n\t\t\t\t\"l\":  9.3,\n\t\t\t\t\"EF\": 8.0,\n\t\t\t},\n\t\t\t0,\n\t\t\tkv{\"\", 0.0},\n\t\t}}\n\n\tfmt.Println(\" EXTRA \")\n\tfmt.Println()\n\tfmt.Println(\"Promedio de Calificaciones\")\n\tfor i, _ := range student {\n\t\tstudent[i].AverageNote()\n\t\tfmt.Printf(\"\\tName: %v, Average: %v\\n\", student[i].name, student[i].averageNote)\n\t}\n\n\tfmt.Println()\n\tfmt.Println(\"Mejores estudiantes\")\n\n\tbest := filterF(student, BestStudient) //uso la misma funcion filterF generica con T any y lo que paso es el elemento del slice a la funcion que paso como argumento\n\tfor _, i := range best {\n\t\tfmt.Printf(\"\\tName: %v, Average: %v\\n\", i.name, i.averageNote)\n\t}\n\n\tfmt.Println()\n\tfmt.Println(\"Sin Ordenar\")\n\tstudent.Display()\n\tfmt.Println()\n\tfmt.Println(\"Ordenados por fecha de Nacimiento\")\n\tstudent.SortByDateBorn()\n\tstudent.Display()\n\n\tfmt.Println()\n\tfmt.Println(\"Calificacion mas alta por alumno\")\n\tfor i, _ := range student {\n\t\tstudent[i].OrderNote()\n\n\t}\n\tstudent.Display()\n}\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/go/thegera4.go",
    "content": " package main\n\n import (\n\t\"fmt\"\n\t\"time\"\n\t\"sort\"\n)\n\n// Nota: una funcion de orden superior (HOF) es una funcion que recibe como parametro \n// otra(s) funcion(es) o devuelve una funcion.\n\n// Primero definimos una funcion de orden superior (recibe una funcion como parametro).\nfunc applyOperation(x int, y int, operation func(int, int) int) int {\n\treturn operation(x, y)\n}\n\n// Luego definimos dos funciones que seran pasadas como parametro a la funcion de orden superior anterior.\nfunc add(x int, y int) int {\n\treturn x + y\n}\n\nfunc subtract(x int, y int) int {\n\treturn x - y\n}\n\n// Y una funcion que regresa una funcion (tambien es una funcion de orden superior)...\nfunc makeMultiplier(factor int) func(int) int {\n\treturn func(x int) int {\n\t\treturn x * factor\n\t}\n}\n\nfunc main() {\n\tfmt.Println(\"Resultado de sumar 5 y 3:\", applyOperation(5, 3, add))\n\tfmt.Println(\"Resultado de multiplicar 5 y 3:\", applyOperation(5, 3, subtract))\n\t\n\ttriple := makeMultiplier(3)\n\tfmt.Println(\"Resultado de multiplicar 8 por 3:\", triple(8))\n\n\t//Extra\n\tanalisisEstudiantes()\n}\n\n// Extra\n\n// Definimos una estructura para los estudiantes\ntype Student struct {\n\tname string\n\tbirthDate string\n\tgrades []float64\n}\n\n// Definimos una funcion de orden superior que realiza el analisis de los estudiantes\nfunc applyAnalysis(students []Student, analysisType func([]Student) []string) []string {\n\treturn analysisType(students)\n}\n\n// Definimos las funciones para los tipos de analisis\nfunc average (students []Student) []string {\n\tvar result []string\n\tfor _, student := range students {\n\t\tsum := 0.0\n\t\tfor _, grade := range student.grades {\n\t\t\tsum += grade\n\t\t}\n\t\taverage := sum / float64(len(student.grades))\n\t\tresult = append(result, student.name + \": \" + fmt.Sprintf(\"%.2f\", average))\n\t}\n\treturn result\n}\n\nfunc bestStudents (students []Student) []string {\n\tvar result []string\n\tfor _, student := range students {\n\t\tsum := 0.0\n\t\tfor _, grade := range student.grades {\n\t\t\tsum += grade\n\t\t}\n\t\taverage := sum / float64(len(student.grades))\n\t\tif average >= 9.0 {\n\t\t\tresult = append(result, student.name)\n\t\t}\n\t}\n\treturn result\n}\n\nfunc birthDateSort (students []Student) []string {\n\tvar result []string\n\tsort.Slice(students, func(i, j int) bool {\n\t\tdate1, _ := time.Parse(\"2006-01-02\", students[i].birthDate)\n\t\tdate2, _ := time.Parse(\"2006-01-02\", students[j].birthDate)\n\t\treturn date1.After(date2)\n\t})\n\tfor _, student := range students {\n\t\tresult = append(result, student.name)\n\t}\n\treturn result\n}\n\nfunc highestGrade (students []Student) []string {\n\tvar result []string\n\thighest := 0.0\n\tfor _, student := range students {\n\t\tfor _, grade := range student.grades {\n\t\t\tif grade > highest {\n\t\t\t\thighest = grade\n\t\t\t}\n\t\t}\n\t}\n\tfor _, student := range students {\n\t\tfor _, grade := range student.grades {\n\t\t\tif grade == highest {\n\t\t\t\tresult = append(result, student.name + \": \" + fmt.Sprintf(\"%.2f\", grade))\n\t\t\t}\n\t\t}\n\t}\n\treturn result\n}\n\nfunc analisisEstudiantes() {\n\t// Definimos una lista de estudiantes\n\tstudentsList := []Student{\n\t\t{\"Juan\", \"2000-01-01\", []float64{8.5, 9.0, 7.5}},\n\t\t{\"Maria\", \"2001-02-03\", []float64{9.0, 9.5, 8.0}},\n\t\t{\"Pedro\", \"1999-03-05\", []float64{7.0, 8.0, 6.5}},\n\t\t{\"Ana\", \"2000-04-07\", []float64{9.5, 9.0, 8.5}},\n\t\t{\"Luis\", \"1998-05-09\", []float64{6.0, 7.0, 5.5}},\n\t}\n\n\t// Realizamos el analisis de los estudiantes\n\tfmt.Println(\"Promedio de calificaciones: \", applyAnalysis(studentsList, average))\n\tfmt.Println(\"Mejores estudiantes: \", applyAnalysis(studentsList, bestStudents))\n\tfmt.Println(\"Estudiantes ordenados empezando con los mas jovenes: \", applyAnalysis(studentsList, birthDateSort))\n\tfmt.Println(\"Calificacion(es) mas alta(s): \", applyAnalysis(studentsList, highestGrade))\n}"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/java/ASJordi.java",
    "content": "import java.time.LocalDate;\nimport java.util.Arrays;\nimport java.util.Comparator;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.function.Function;\n\n/**\n * Funciones de Orden Superior\n * Son funciones que pueden tomar otras funciones como argumentos y/o devolver funciones como resultado.\n * Esto permite la creación de abstracciones más complejas y potentes.\n * En Java, las funciones de orden superior se pueden implementar utilizando interfaces funcionales,\n * que son interfaces con un único método abstracto.\n * Java 8 introdujo varias interfaces funcionales predefinidas en el paquete java.util.function,\n * como Function, Predicate, Consumer, Supplier, etc.\n */\npublic class Main {\n\n    public static void main(String[] args) {\n//        System.out.println(iva.apply(100.0));\n//        System.out.println(applyTwice(x -> x + 1, 5));\n        administrarEstudiantes();\n    }\n\n    /**\n     * EJERCICIO:\n     * Explora el concepto de funciones de orden superior en tu lenguaje\n     * creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n     */\n\n    /**\n     * Función que calcula el IVA de un precio\n     * @param x Precio\n     * @return Precio con IVA\n     */\n    public static Function<Double, Double> iva = x -> x + (x * 0.16);\n\n    /**\n     * Función de orden superior que aplica una función dos veces\n     * @param f Función a aplicar dos veces\n     * @param x Valor a aplicar\n     * @return Resultado de aplicar la función dos veces al valor dado x\n     */\n    public static Integer applyTwice(Function<Integer, Integer> f, Integer x) {\n        return f.apply(f.apply(x));\n    }\n\n    /**\n     * DIFICULTAD EXTRA (opcional):\n     * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y lista de calificaciones),\n     * utiliza funciones de orden superior para realizar las siguientes operaciones de procesamiento y análisis:\n     * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre y promedio de sus calificaciones.\n     * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes que tienen calificaciones con un 9 o más de promedio.\n     * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n     * - Mayor calificación: Obtiene la calificación más alta de entre todas las de los alumnos.\n     * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n     */\n    public static void administrarEstudiantes() {\n        Function<Estudiante, Double> fPromedio = e -> e.getCalificaciones().stream().mapToDouble(Double::doubleValue).average().orElse(0.0);\n        Function<List<Estudiante>, Double> fCalificacionMasAlta = l -> l.stream().mapToDouble(e -> e.getCalificaciones().stream().mapToDouble(Double::doubleValue).max().orElse(0.0)).max().orElse(0.0);\n\n        var promedios = obtenerPromedios(fPromedio, obtenerEstudiantes());\n        promedios.forEach(e -> System.out.println(Arrays.toString(e)));\n\n        var mejoresEstudiantes = obtenerMejoresEstudiantes(fPromedio, obtenerEstudiantes());\n        System.out.println(\"Mejores estudiantes: \" + mejoresEstudiantes);\n\n        var estudiantesOrdenados = obtenerEstudiantesOrdenadosPorFechaNacimiento(obtenerEstudiantes());\n        estudiantesOrdenados.forEach(System.out::println);\n\n        var calificacionMasAlta = obtenerCalificacionMasAlta(fCalificacionMasAlta, obtenerEstudiantes());\n        System.out.println(\"Calificación más alta: \" + calificacionMasAlta);\n    }\n\n    public static List<String[]> obtenerPromedios(Function<Estudiante, Double> f, List<Estudiante> l) {\n        List<String[]> result = new LinkedList<>();\n        l.forEach(e -> result.add(new String[]{e.getNombre(), f.apply(e).toString()}));\n        return result;\n    }\n\n    public static List<String> obtenerMejoresEstudiantes(Function<Estudiante, Double> f, List<Estudiante> l) {\n        List<String> result = new LinkedList<>();\n        l.forEach(e -> {\n            if (f.apply(e) >= 9.0) result.add(e.getNombre());\n        });\n        return result;\n    }\n\n    public static List<Estudiante> obtenerEstudiantesOrdenadosPorFechaNacimiento(List<Estudiante> l) {\n        l.sort(Comparator.comparing(Estudiante::getFechaNacimiento));\n        return l;\n    }\n\n    public static Double obtenerCalificacionMasAlta(Function<List<Estudiante>, Double> f, List<Estudiante> l) {\n        return f.apply(l);\n    }\n\n    static class Estudiante {\n        private String nombre;\n        private LocalDate fechaNacimiento;\n        private List<Double> calificaciones;\n\n        public Estudiante(String nombre, LocalDate fechaNacimiento) {\n            this.nombre = nombre;\n            this.fechaNacimiento = fechaNacimiento;\n            this.calificaciones = new LinkedList<>();\n        }\n\n        public void setCalificaciones(List<Double> calificaciones) {\n            this.calificaciones = calificaciones;\n        }\n\n        public String getNombre() {\n            return nombre;\n        }\n\n        public LocalDate getFechaNacimiento() {\n            return fechaNacimiento;\n        }\n\n        public List<Double> getCalificaciones() {\n            return calificaciones;\n        }\n\n\n        @Override\n        public String toString() {\n            return \"Estudiante{\" + \"nombre='\" + nombre + '\\'' +\n                    \", fechaNacimiento=\" + fechaNacimiento +\n                    \", calificaciones=\" + calificaciones +\n                    '}';\n        }\n    }\n\n    /**\n     * Método que devuelve una lista de estudiantes\n     * @return\n     */\n    public static List<Estudiante> obtenerEstudiantes() {\n        List<Estudiante> list = new LinkedList<>();\n\n        Estudiante e1 = new Estudiante(\"Juan\", LocalDate.of(2010, 1, 1));\n        List<Double> c1 = List.of(8.0, 9.0, 7.0, 10.0, 8.5);\n        e1.setCalificaciones(c1);\n\n        Estudiante e2 = new Estudiante(\"Pedro\", LocalDate.of(2001, 2, 2));\n        List<Double> c2 = List.of(7.0, 6.0, 8.0, 9.0, 7.5);\n        e2.setCalificaciones(c2);\n\n        Estudiante e3 = new Estudiante(\"Maria\", LocalDate.of(2002, 3, 3));\n        List<Double> c3 = List.of(10.0, 10.0, 9.5, 9.0, 9.2);\n        e3.setCalificaciones(c3);\n\n        Estudiante e4 = new Estudiante(\"Ana\", LocalDate.of(2003, 4, 4));\n        List<Double> c4 = List.of(6.0, 7.0, 6.5, 8.0, 7.2);\n        e4.setCalificaciones(c4);\n\n        list.add(e1);\n        list.add(e2);\n        list.add(e3);\n        list.add(e4);\n        return list;\n    }\n}\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/java/AmadorQuispe.java",
    "content": "\nimport java.time.LocalDate;\nimport java.util.*;\nimport java.util.function.Consumer;\nimport java.util.function.Function;\nimport java.util.stream.Stream;\n\n@FunctionalInterface\ninterface Greeting {\n    void accept(String name);\n}\n\npublic class Roadmap {\n    public static void main(String[] args) throws InterruptedException {\n        Consumer<String> greeting = (n) -> System.out.println(\"Hola bienvenido \" + n);\n        welcome(greeting,\"Amador\");\n        //EXTRA\n        List<Student> students = getStudents();\n\n        //Función para obtener el promedio de calificaciónes dado un estudiante\n        Function<Student, Double> fAverage = e -> e.getQualifications().stream().mapToDouble(Double::doubleValue).average().orElse(0.0);\n        //Promedio calificaciones: Obtiene una lista de estudiantes por nombre y promedio de sus calificaciones\n        HashMap<String,Double> studentsWithAverageQualification = students.stream().collect(\n                HashMap::new,\n                (mapStudents,student) -> mapStudents.put(student.getName(),fAverage.apply(student)),\n                HashMap::putAll\n        );\n        System.out.println(studentsWithAverageQualification);\n\n        //Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes que tienen calificaciones con un 9 o más de promedio\n        List<String> studentsWithPassingGrade = students.stream().filter(s -> fAverage.apply(s) > 9).map(Student::getName).toList();\n        System.out.println(studentsWithPassingGrade);\n\n        //Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n        Stream<Student> studentsSortedByAgeAsc = students.stream().sorted(Comparator.comparing(Student::getBirthDate, Comparator.reverseOrder()));\n        studentsSortedByAgeAsc.forEach(System.out::println);\n\n        //Mayor calificación: Obtiene la calificación más alta de entre todas las de los alumnos.\n        OptionalDouble maxQualification = students.stream().mapToDouble(fAverage::apply).max();\n        System.out.println(\"Calificación más alta es :\" + maxQualification.orElse(0d));\n    }\n    public static void welcome(Consumer<String> f, String name){\n        f.accept(name);\n    }\n\n    public static List<Student> getStudents(){\n        List<Student> students = new ArrayList<>();\n        students.add(new Student(\"Amador\", LocalDate.of(1992, 5, 15), List.of(5.00, 8.2, 9.2, 10.00)));\n        students.add(new Student(\"Sofía\", LocalDate.of(1993, 3, 22), List.of(4.5, 6.3, 7.0, 8.5)));\n        students.add(new Student(\"Mateo\", LocalDate.of(1994, 7, 19), List.of(9.00, 9.0, 10.00, 9.1)));\n        students.add(new Student(\"Isabella\", LocalDate.of(1995, 11, 2), List.of(7.3, 4.9, 5.6, 9.1)));\n        students.add(new Student(\"Sebastián\", LocalDate.of(1996, 8, 13), List.of(1.2, 3.4, 5.5, 7.6)));\n        students.add(new Student(\"Valentina\", LocalDate.of(1997, 6, 25), List.of(10.00,9.0, 9.9, 8.9)));\n        students.add(new Student(\"Daniel\", LocalDate.of(1998, 9, 5), List.of(4.3, 5.6, 8.8, 6.1)));\n        students.add(new Student(\"Mariana\", LocalDate.of(1999, 2, 12), List.of(3.3, 4.4, 6.6, 7.7)));\n        students.add(new Student(\"Lucas\", LocalDate.of(1990, 10, 31), List.of(8.8, 9.9, 7.7, 6.6)));\n        students.add(new Student(\"Martina\", LocalDate.of(1991, 12, 24), List.of(5.5, 4.4, 3.3, 2.2)));\n        students.add(new Student(\"Gabriel\", LocalDate.of(1992, 4, 7), List.of(6.6, 7.7, 8.8, 9.9)));\n        students.add(new Student(\"Emilia\", LocalDate.of(1993, 1, 15), List.of(2.2, 3.3, 4.4, 5.5)));\n        students.add(new Student(\"Diego\", LocalDate.of(1994, 3, 30), List.of(7.7, 6.6, 5.5, 4.4)));\n        students.add(new Student(\"Renata\", LocalDate.of(1995, 5, 19), List.of(9.9, 9.8, 9.7, 9.00)));\n        students.add(new Student(\"David\", LocalDate.of(1996, 7, 14), List.of(1.1, 2.2, 3.3, 4.4)));\n        students.add(new Student(\"Victoria\", LocalDate.of(1997, 9, 27), List.of(5.5, 6.6, 7.7, 8.8)));\n        students.add(new Student(\"Jorge\", LocalDate.of(1998, 11, 11), List.of(2.3, 4.5, 6.7, 8.9)));\n        students.add(new Student(\"Camila\", LocalDate.of(1999, 1, 3), List.of(7.1, 8.2, 9.3, 6.4)));\n        students.add(new Student(\"Miguel\", LocalDate.of(2000, 4, 22), List.of(3.6, 4.7, 5.8, 6.9)));\n        students.add(new Student(\"Santiago\", LocalDate.of(1991, 6, 18), List.of(4.2, 5.3, 6.4, 7.5)));\n        students.add(new Student(\"Valeria\", LocalDate.of(1992, 8, 8), List.of(9.12, 10.00, 9.52, 9.00)));\n\n        return students;\n    }\n\n    static class Student {\n        private String name;\n        private LocalDate birthDate;\n        private List<Double> qualifications;\n\n        public Student() {\n        }\n\n        public Student(String name, LocalDate birthDate, List<Double> qualifications) {\n            this.name = name;\n            this.birthDate = birthDate;\n            this.qualifications = qualifications;\n        }\n\n        public String getName() {\n            return name;\n        }\n\n        public void setName(String name) {\n            this.name = name;\n        }\n\n        public LocalDate getBirthDate() {\n            return birthDate;\n        }\n\n        public void setBirthDate(LocalDate birthDate) {\n            this.birthDate = birthDate;\n        }\n\n        public List<Double> getQualifications() {\n            return qualifications;\n        }\n\n        public void setQualifications(List<Double> qualifications) {\n            this.qualifications = qualifications;\n        }\n\n        @Override\n        public String toString() {\n            return \"Student{\" +\n                    \"name='\" + name + '\\'' +\n                    \", birthDate=\" + birthDate +\n                    \", qualifications=\" + qualifications +\n                    '}';\n        }\n    }\n}\n\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/java/AnaLauDB.java",
    "content": "import java.util.*;\nimport java.util.stream.Collectors;\nimport java.time.LocalDate;\nimport java.util.function.*;\n\npublic class AnaLauDB {\n\n    // Clase Estudiante para la dificultad extra\n    static class Estudiante {\n        private String nombre;\n        private LocalDate fechaNacimiento;\n        private List<Double> calificaciones;\n\n        public Estudiante(String nombre, LocalDate fechaNacimiento, List<Double> calificaciones) {\n            this.nombre = nombre;\n            this.fechaNacimiento = fechaNacimiento;\n            this.calificaciones = calificaciones;\n        }\n\n        public String getNombre() {\n            return nombre;\n        }\n\n        public LocalDate getFechaNacimiento() {\n            return fechaNacimiento;\n        }\n\n        public List<Double> getCalificaciones() {\n            return calificaciones;\n        }\n\n        public double getPromedio() {\n            return calificaciones.stream()\n                    .mapToDouble(Double::doubleValue)\n                    .average()\n                    .orElse(0.0);\n        }\n\n        @Override\n        public String toString() {\n            return String.format(\"%s (Promedio: %.2f)\", nombre, getPromedio());\n        }\n    }\n\n    // Ejemplos de funciones de orden superior\n    public static void ejemplosBasicos() {\n        List<Integer> numeros = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);\n\n        // 1. map() - transforma cada elemento\n        List<Integer> cuadrados = numeros.stream()\n                .map(x -> x * x)\n                .collect(Collectors.toList());\n        System.out.println(\"Cuadrados: \" + cuadrados);\n\n        // 2. filter() - filtra elementos\n        List<Integer> pares = numeros.stream()\n                .filter(x -> x % 2 == 0)\n                .collect(Collectors.toList());\n        System.out.println(\"Números pares: \" + pares);\n\n        // 3. reduce() - reduce a un solo valor\n        int suma = numeros.stream()\n                .reduce(0, (a, b) -> a + b);\n        System.out.println(\"Suma total: \" + suma);\n\n        // 4. forEach() - ejecuta acción en cada elemento\n        System.out.print(\"Números: \");\n        numeros.stream().forEach(x -> System.out.print(x + \" \"));\n        System.out.println();\n    }\n\n    // Función que acepta otra función como parámetro\n    public static <T> List<T> filtrarLista(List<T> lista, Predicate<T> condicion) {\n        return lista.stream()\n                .filter(condicion)\n                .collect(Collectors.toList());\n    }\n\n    // Función que retorna otra función\n    public static Function<Integer, Integer> multiplicarPor(int factor) {\n        return x -> x * factor;\n    }\n\n    public static void main(String[] args) {\n        System.out.println(\"=== Ejemplos básicos de funciones de orden superior ===\");\n        ejemplosBasicos();\n\n        // Ejemplo de función que acepta otra función\n        List<String> palabras = Arrays.asList(\"Java\", \"Python\", \"JavaScript\", \"C++\");\n        List<String> palabrasLargas = filtrarLista(palabras, p -> p.length() > 4);\n        System.out.println(\"Palabras largas: \" + palabrasLargas);\n\n        // Ejemplo de función que retorna otra función\n        Function<Integer, Integer> multiplicarPor3 = multiplicarPor(3);\n        System.out.println(\"5 * 3 = \" + multiplicarPor3.apply(5));\n\n        System.out.println(\"\\n=== DIFICULTAD EXTRA: Análisis de estudiantes ===\");\n\n        // Crear lista de estudiantes\n        List<Estudiante> estudiantes = Arrays.asList(\n                new Estudiante(\"Ana\", LocalDate.of(2000, 5, 15),\n                        Arrays.asList(8.5, 9.0, 7.5, 8.0)),\n                new Estudiante(\"Luis\", LocalDate.of(1999, 3, 22),\n                        Arrays.asList(9.5, 9.0, 9.8, 9.2)),\n                new Estudiante(\"María\", LocalDate.of(2001, 8, 10),\n                        Arrays.asList(7.0, 6.5, 8.0, 7.5)),\n                new Estudiante(\"Carlos\", LocalDate.of(2000, 12, 3),\n                        Arrays.asList(9.0, 9.5, 8.5, 9.8)),\n                new Estudiante(\"Sofía\", LocalDate.of(2002, 1, 28),\n                        Arrays.asList(6.0, 7.0, 6.5, 7.5)));\n\n        // 1. Promedio de calificaciones por estudiante\n        System.out.println(\"1. Promedio de calificaciones:\");\n        estudiantes.stream()\n                .map(e -> e.getNombre() + \": \" + String.format(\"%.2f\", e.getPromedio()))\n                .forEach(System.out::println);\n\n        // 2. Mejores estudiantes (promedio >= 9.0)\n        System.out.println(\"\\n2. Mejores estudiantes (promedio >= 9.0):\");\n        estudiantes.stream()\n                .filter(e -> e.getPromedio() >= 9.0)\n                .map(Estudiante::getNombre)\n                .forEach(System.out::println);\n\n        // 3. Estudiantes ordenados por edad (más joven primero)\n        System.out.println(\"\\n3. Estudiantes ordenados por edad (más joven primero):\");\n        estudiantes.stream()\n                .sorted((e1, e2) -> e2.getFechaNacimiento().compareTo(e1.getFechaNacimiento()))\n                .map(e -> e.getNombre() + \" (\" + e.getFechaNacimiento() + \")\")\n                .forEach(System.out::println);\n\n        // 4. Mayor calificación de todos los estudiantes\n        double mayorCalificacion = estudiantes.stream()\n                .flatMap(e -> e.getCalificaciones().stream())\n                .mapToDouble(Double::doubleValue)\n                .max()\n                .orElse(0.0);\n        System.out.println(\"\\n4. Mayor calificación: \" + mayorCalificacion);\n    }\n}\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/java/FranDev200.java",
    "content": "import java.time.LocalDate;\nimport java.util.*;\nimport java.util.function.Function;\n\npublic class FranDev200 {\n\n    public static int operar(ArrayList<Integer> lista, Function<ArrayList<Integer>, Integer> sumar) {\n\n        return sumar.apply(lista);\n\n    }\n\n    public static ArrayList<Integer> ordenar (ArrayList<Integer> lista, Function<ArrayList<Integer>, List<Integer>> ordenacion) {\n\n        ArrayList<Integer> resultado = new ArrayList<>(ordenacion.apply(lista));\n\n        return  resultado;\n    }\n\n    public static ArrayList<Integer> calcularPares(ArrayList<Integer> lista, Function<ArrayList<Integer>, List<Integer>> par) {\n\n        ArrayList<Integer> resultado = new ArrayList<>(par.apply(lista));\n\n        return  resultado;\n\n    }\n\n    static void main() {\n\n        /*\n\n        EJERCICIO:\n         * Explora el concepto de funciones de orden superior en tu lenguaje\n         * creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n\n         */\n\n        ArrayList<Integer> listaNumeros = new ArrayList<>();\n        listaNumeros.add(14);\n        listaNumeros.add(5);\n        listaNumeros.add(54);\n        listaNumeros.add(12);\n        listaNumeros.add(88);\n        listaNumeros.add(36);\n        listaNumeros.add(29);\n        listaNumeros.add(67);\n        listaNumeros.add(53);\n        listaNumeros.add(2);\n        listaNumeros.add(9);\n\n        Function<ArrayList<Integer>, Integer> suma =\n                x -> x.stream().mapToInt(Integer::intValue).sum();\n\n        Function<ArrayList<Integer>, List<Integer>> ordenacion =\n                x -> x.stream().toList().stream().sorted().toList();\n\n        Function<ArrayList<Integer>, List<Integer>> pares =\n                x -> x.stream()\n                        .filter( n -> (n % 2) == 0)\n                        .toList();\n\n        System.out.println(\"\\nSuma total de todos estos números: \" + listaNumeros + \" = \" + operar(listaNumeros, suma));\n        System.out.println(\"=================\");\n        System.out.println(\"Ordenacion de los numeros de la lista\");\n        System.out.println(\"-------------------------------------\");\n        System.out.println(\"Antes de ordenar: \" + listaNumeros);\n        System.out.println(\"Después de ordenar: \" + ordenar(listaNumeros, ordenacion));\n        System.out.println(\"=================\");\n        System.out.println(\"Numeros pares de la lista: \" + calcularPares(listaNumeros, pares));\n        System.out.println(\"Lista de pares, ordenados: \" + ordenar(calcularPares(listaNumeros, pares), ordenacion));\n        System.out.println(\"=================\");\n\n\n\n        /*\n\n        DIFICULTAD EXTRA (opcional):\n         * Dada una listaNumeros de estudiantes (con sus nombres, fecha de nacimiento y\n         * listaNumeros de calificaciones), utiliza funciones de orden superior para\n         * realizar las siguientes operaciones de procesamiento y análisis:\n         * - Promedio calificaciones: Obtiene una listaNumeros de estudiantes por nombre\n         *   y promedio de sus calificaciones.\n         * - Mejores estudiantes: Obtiene una listaNumeros con el nombre de los estudiantes\n         *   que tienen calificaciones con un 9 o más de promedio.\n         * - Nacimiento: Obtiene una listaNumeros de estudiantes ordenada desde el más joven.\n         * - Mayor calificación: Obtiene la calificación más alta de entre todas las\n         *   de los alumnos.\n         * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n\n         */\n\n        ArrayList<Estudiante> alumnos = new ArrayList<>();\n\n        alumnos.add(new Estudiante(\"Ana López\",\n                LocalDate.of(2002, 3, 12),\n                new ArrayList<>(Arrays.asList(7.5, 8.0, 6.5))));\n\n        alumnos.add(new Estudiante(\"Carlos Martín\",\n                LocalDate.of(2001, 7, 25),\n                new ArrayList<>(Arrays.asList(5.5, 6.0, 7.0))));\n\n        alumnos.add(new Estudiante(\"Lucía Fernández\",\n                LocalDate.of(2003, 11, 9),\n                new ArrayList<>(Arrays.asList(9.0, 8.5, 9.5))));\n\n        alumnos.add(new Estudiante(\"David Gómez\",\n                LocalDate.of(2002, 1, 18),\n                new ArrayList<>(Arrays.asList(4.5, 5.0, 6.0))));\n\n        alumnos.add(new Estudiante(\"Marta Ruiz\",\n                LocalDate.of(2001, 6, 30),\n                new ArrayList<>(Arrays.asList(7.0, 7.5, 8.0))));\n\n        alumnos.add(new Estudiante(\"Javier Sánchez\",\n                LocalDate.of(2003, 2, 14),\n                new ArrayList<>(Arrays.asList(6.5, 6.0, 5.5))));\n\n        alumnos.add(new Estudiante(\"Elena Navarro\",\n                LocalDate.of(2002, 9, 22),\n                new ArrayList<>(Arrays.asList(8.5, 9.0, 8.0))));\n\n        alumnos.add(new Estudiante(\"Pablo Torres\",\n                LocalDate.of(2001, 5, 5),\n                new ArrayList<>(Arrays.asList(3.5, 4.0, 5.0))));\n\n        alumnos.add(new Estudiante(\"Sara Molina\",\n                LocalDate.of(2003, 12, 27),\n                new ArrayList<>(Arrays.asList(10.0, 9.5, 9.0))));\n\n        alumnos.add(new Estudiante(\"Raúl Ortega\",\n                LocalDate.of(2002, 8, 11),\n                new ArrayList<>(Arrays.asList(6.0, 7.0, 6.5))));\n\n\n        System.out.println(\"\\n\\nEJERCICIO EXTRA\");\n        System.out.println(\"===============\");\n\n        // Funcion que calcula el promedio de las notas de cada alumno\n        Function<Estudiante, Double> promedioNotas =\n                x -> x.getCalificaciones().stream().mapToDouble(Double::doubleValue)\n                        .average().orElse(0.0);\n\n        // Funcion que devuelve el alumno con la mayor media\n\n        Function<ArrayList<Estudiante>, Double> mejorNota =\n                x -> x.stream().mapToDouble(\n                        e -> e.getCalificaciones().stream().mapToDouble(Double::doubleValue)\n                                .max().orElse(0.0)).max().orElse(0.0);\n\n        System.out.println(\"Calculo de las medias de los estudiantes\");\n        System.out.println(\"----------------------------------------\");\n\n        HashMap<String, Double> estudiantesNotas = notasMediaAlumnos(promedioNotas, alumnos);\n\n        for (Map.Entry<String, Double> nota: estudiantesNotas.entrySet()) {\n\n            System.out.printf(\"%-15s --> %04.2f\\n\", nota.getKey(), nota.getValue());\n\n        }\n\n        System.out.println(\"===============\");\n        System.out.println(\"Mejores estudiantes. [Nota media >= 9]\");\n        System.out.println(\"----------------------------------------\");\n\n        HashMap<String, Double> estudiantesSobresalientes = notasSobresalientes(promedioNotas, alumnos);\n\n        for (Map.Entry<String, Double> nota: estudiantesSobresalientes.entrySet()) {\n\n            System.out.printf(\"%-15s --> %04.2f\\n\", nota.getKey(), nota.getValue());\n\n        }\n\n        System.out.println(\"===============\");\n        System.out.println(\"Alumnos ordenados de más joven a más mayor\");\n        System.out.println(\"----------------------------------------\");\n\n        for (Estudiante estudiante: ordenarEstudiantesFchNacimiento(alumnos)) {\n            System.out.printf(\"%-15s --> %s\\n\", estudiante.getNombre(), estudiante.getFch_nacimiento());\n        }\n\n        System.out.println(\"===============\");\n        System.out.println(\"La nota más alta en un examen fue: \" + mejorNota(mejorNota,  alumnos));\n        System.out.println(\"----------------------------------------\");\n\n\n    }\n\n    static class Estudiante{\n\n        private String nombre;\n        private LocalDate fch_nacimiento;\n        private ArrayList<Double> calificaciones;\n\n        public Estudiante(String nombre, LocalDate fch_nacimiento, ArrayList<Double> calificaciones) {\n            this.nombre = nombre;\n            this.fch_nacimiento = fch_nacimiento;\n            this.calificaciones = calificaciones;\n        }\n\n        public Estudiante(String nombre, ArrayList<Double> calificaciones) {\n            this.nombre = nombre;\n            this.calificaciones = calificaciones;\n        }\n\n        public String getNombre() {\n            return nombre;\n        }\n\n        public void setNombre(String nombre) {\n            this.nombre = nombre;\n        }\n\n        public LocalDate getFch_nacimiento() {\n            return fch_nacimiento;\n        }\n\n        public void setFch_nacimiento(LocalDate fch_nacimiento) {\n            this.fch_nacimiento = fch_nacimiento;\n        }\n\n        public ArrayList<Double> getCalificaciones() {\n            return calificaciones;\n        }\n\n        public void setCalificaciones(ArrayList<Double> calificaciones) {\n            this.calificaciones = calificaciones;\n        }\n    }\n\n    public static HashMap<String, Double> notasMediaAlumnos(Function<Estudiante, Double> promedioNotas, ArrayList<Estudiante> estudiantes){\n\n        HashMap<String, Double> notasMediaAlumnos = new HashMap<>();\n\n        estudiantes.forEach(estudiante -> {\n            notasMediaAlumnos.put(estudiante.getNombre(), promedioNotas.apply(estudiante));\n        });\n\n        return notasMediaAlumnos;\n\n    };\n\n    public static HashMap<String, Double> notasSobresalientes(Function<Estudiante, Double> promedioNotas, ArrayList<Estudiante> estudiantes){\n\n        HashMap<String, Double> notasMediaAlumnos = new HashMap<>();\n\n        estudiantes.forEach(estudiante -> {\n\n            if(promedioNotas.apply(estudiante) >= 9){\n                notasMediaAlumnos.put(estudiante.getNombre(), promedioNotas.apply(estudiante));\n            }\n\n        });\n\n        return notasMediaAlumnos;\n\n    };\n\n    public static List<Estudiante> ordenarEstudiantesFchNacimiento(ArrayList<Estudiante> estudiantes){\n\n        estudiantes.sort(Comparator.comparing(Estudiante::getFch_nacimiento));\n        return estudiantes;\n\n    }\n\n\n\n    public static Double mejorNota(Function<ArrayList<Estudiante>, Double> mejorEstudiante, ArrayList<Estudiante> estudiantes){\n\n        return mejorEstudiante.apply(estudiantes);\n\n    };\n\n}\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/java/JimsimroDev.java",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de funciones de orden superior en tu lenguaje\n * creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n *\n * DIFICULTAD EXTRA (opcional):\n * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y\n * lista de calificaciones), utiliza funciones de orden superior para\n * realizar las siguientes operaciones de procesamiento y análisis:\n * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n *   y promedio de sus calificaciones.\n * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n *   que tienen calificaciones con un 9 o más de promedio.\n * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n * - Mayor calificación: Obtiene la calificación más alta de entre todas las\n *   de los alumnos.\n * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n */\n\nimport java.time.LocalDate;\nimport java.time.format.DateTimeFormatter;\nimport java.util.Arrays;\nimport java.util.Comparator;\nimport java.util.List;\n\npublic class JimsimroDev {\n  // Filtra por pares imprime solo los numeros pares\n  private static List<Integer> filtrarPares(List<Integer> numeros) {\n    var pares = numeros.stream().filter(n -> n % 2 == 0).toList();\n    return pares;\n  }\n\n  // Ordena de mayor a menor\n  private static List<Integer> ordenardeMayorAmenor(List<Integer> numeros) {\n    var numerosOrdenadosDescendente = numeros.stream().sorted(Comparator.reverseOrder()).toList();\n    return numerosOrdenadosDescendente;\n  }\n\n  // Multiplicar * 2\n  private static List<Integer> multiplicarPorDos(List<Integer> numeros) {\n    var numerosMultiplicados = numeros.stream().map(n -> n * 2).toList();\n    return numerosMultiplicados;\n  }\n\n  // Extra\n  static class Alumno {\n    private String nombre;\n    private String fechaNacimiento;\n    private List<Double> calificacion;\n\n    Alumno(String nombre, String fechaNacimientos, List<Double> calificacion) {\n      this.nombre = nombre;\n      this.fechaNacimiento = fechaNacimientos;\n      this.calificacion = calificacion;\n    }\n\n    // Inicializa la lista de esutiantes\n    private static List<Alumno> obtenerAlumnos() {\n      List<Alumno> estudiantes = Arrays.asList(\n          new Alumno(\"Jhoan\", \"28/07/1995\", Arrays.asList(7.7, 4.1, 3.9)),\n          new Alumno(\"Juan\", \"05/08/1994\", Arrays.asList(9.7, 9.1, 9.0)),\n          new Alumno(\"Mario\", \"07/11/1990\", Arrays.asList(8.0, 9.1, 9.9)),\n          new Alumno(\"Keren\", \"20/12/2016\", Arrays.asList(9.8, 9.9, 10.0)));\n      return estudiantes;\n    }\n\n    @Override\n    public String toString() {\n      return String.format(\"{ Nombre: %s - Fecha Nacimiento: %s }\", nombre, fechaNacimiento);\n    }\n  }\n\n  static void print(Object... args) {\n    for (Object s : args) {\n      System.out.print(s + \"\\n\");\n    }\n  }\n\n  // Promedio calificaciones: Obtiene una lista de estudiantes por nombre y\n  // promedio de sus calificaciones.\n  private static void mostrarPromedioPorAlumnos() {\n    List<String> promedioEstudiante = Alumno.obtenerAlumnos().stream()\n        .map(s -> {\n          double promedio = s.calificacion.stream()\n              .mapToDouble(d -> d).average().getAsDouble();\n          return String.format(\"Nombre: %s - Fecha Nacimiento: %s - Promedio:  %.2f%n \", s.nombre, s.fechaNacimiento,\n              promedio);\n        }).toList();\n    print(promedioEstudiante);\n  }\n\n  // Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes que\n  // tienen calificaciones con un 9 o más de promedio.\n  private static void getMayorPromedio() {\n    print(\"Estudiantes con Promedio >= 9\");\n    print(Alumno.obtenerAlumnos().stream()\n        .filter(s -> s.calificacion.stream()\n            .mapToDouble(d -> d).average().getAsDouble() >= 9)\n        .map(estudiante -> {\n          double promedio = estudiante.calificacion.stream()\n              .mapToDouble(d -> d).average().getAsDouble();\n          return String.format(\"Nombre: %s - Promedio:  %.2f%n \", estudiante.nombre, promedio);\n        }).toList());\n  }\n\n  // Obtiene una lista de estudiantes ordenada desde el más joven.\n  private static void mostrarAlumnoPorEdadDescendente() {\n    print(\"Estudiantes ordenado por fecha nacimiento\");\n    Alumno.obtenerAlumnos().stream()\n        .sorted(Comparator\n            .comparing((Alumno e) -> LocalDate.parse(e.fechaNacimiento, DateTimeFormatter.ofPattern(\"dd/MM/yyyy\")))\n            .reversed())\n        .forEach(System.out::println);\n  }\n\n  // Mayor calificación: Obtiene la calificación más alta de entre todas las de\n  // los alumnos.\n  private static void mostrarCalificacionMasAltaPorEstudiante() {\n    print(\"La notas mas alta entre todos\");\n    Alumno.obtenerAlumnos().stream()\n        .mapToDouble(d -> d.calificacion.stream()\n            .mapToDouble(n -> n)\n            .max().getAsDouble())\n        .max().ifPresent(System.out::println);\n\n  }\n\n  // Mayor calificación: Obtiene la calificación más alta de entre todas las de\n  // los alumnos.\n  private static void mostrarCalificacionMasAltaGlobal() {\n    double notaMaxima = Alumno.obtenerAlumnos().stream()\n        .flatMapToDouble(e -> e.calificacion.stream()\n            .mapToDouble(d -> d))\n        .max().getAsDouble();\n    print(notaMaxima);\n  }\n\n  public static void main(String[] args) {\n    List<Integer> listaNumeros = Arrays.asList(8, 9, 12, 1, 4, 6, 7, 11, 5, 10, 2, 3);\n    print(\"Números ordenados  de > a < \" + ordenardeMayorAmenor(listaNumeros));\n    print(\"Ordena e imprime solo los pares \" + filtrarPares(ordenardeMayorAmenor(listaNumeros)));\n    print(\"Multiplicar el resultado * 2 \" + multiplicarPorDos(filtrarPares(ordenardeMayorAmenor(listaNumeros))));\n    print(\"Numeros Impares \" + listaNumeros.stream().filter(n -> n % 2 == 1).toList());\n    print(\"Mayor \" + listaNumeros.stream().max(Integer::compare).get());\n    print(\"Menor \" + listaNumeros.stream().min(Integer::compare).get());\n\n    // Extra\n    mostrarPromedioPorAlumnos();\n    getMayorPromedio();\n    mostrarAlumnoPorEdadDescendente();\n    mostrarCalificacionMasAltaPorEstudiante();\n    mostrarCalificacionMasAltaGlobal();\n\n    List<Double> average = Alumno.obtenerAlumnos().stream()\n        .map(estudiante -> estudiante.calificacion\n            .stream()\n            .mapToDouble(d -> d)\n            .average().getAsDouble())\n        .toList();\n    print(\"Average \" + average);\n  }\n}\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/java/Josegs95.java",
    "content": "import java.time.LocalDate;\nimport java.util.*;\nimport java.util.function.Function;\nimport java.util.function.Supplier;\n\npublic class Josegs95 {\n    public static void main(String[] args) {\n        //Ejercicio\n        //Las funciones de orden superior están muy relacionadas en java con todo el contenido del paquete\n        //java.util.function y las expresiones lambda, ambos introducidos en la versión 8 de Java.\n\n        //Pasar una función como parámetro\n        int a = 8;\n        int result = operate(a, x -> x * x);\n        System.out.println(result);\n\n        //Devolver una función desde otra función\n        int b = 3;\n        Supplier<Integer> supplier = doubleValue(b);\n        System.out.println(supplier.get());\n\n        //Reto\n        retoFinal();\n    }\n\n    public static int operate(int n, Function<Integer, Integer> function){\n        return function.apply(n);\n    }\n\n    public static Supplier<Integer> doubleValue(int n){\n        return () -> n * 2;\n    }\n\n    public static void retoFinal(){\n        List<Student> studentList = new ArrayList<>();\n        studentList.add(new Student(\"Jose\",\n                LocalDate.of(1995, 2, 28),\n                Arrays.asList(10.0, 8.25, 9.25, 10.0)));\n        studentList.add(new Student(\"María\",\n                LocalDate.of(1997, 4, 13),\n                Arrays.asList(6.5, 6.0, 8.5, 8.0)));\n        studentList.add(new Student(\"Guillermo\",\n                LocalDate.of(1992, 7, 22),\n                Arrays.asList(9.0, 9.5, 7.75, 8.5)));\n\n        //Promedio calificaciones\n        List<String> averageMarks = studentList.stream()\n                .map(s-> {\n                    double average = s.getMarkList()\n                            .stream()\n                            .mapToDouble(Double::doubleValue)\n                            .average()\n                            .getAsDouble();\n                    return s.getName() + \":\" + average;\n                }).toList();\n        System.out.println(\"Nota media de los estudiantes: \" + averageMarks);\n\n        //Mejores estudiantes (+9 de nota)\n        List<String> bestStudents = averageMarks.stream()\n                .filter(s -> {\n                    double averageMark = Double.parseDouble(s.substring(s.indexOf(\":\") + 1));\n                    return averageMark > 9.0;\n                }).toList();\n        System.out.println(\"Estudiantes con mas de un 9 de nota media: \" + bestStudents);\n\n        //Lista de estudiantes ordenada por nacimiento\n        List<Student> sortedStudentList = studentList.stream()\n                .sorted((x, y) -> x.getBirthday().compareTo(y.getBirthday())  * -1)\n                .toList();\n        System.out.println(\"Estudiantes ordenados ascendentemente por edad: \" + sortedStudentList);\n\n        //Mejor calificación de los estudiantes\n        double bestMark = studentList.stream()\n                .mapToDouble(s -> s.getMarkList()\n                        .stream()\n                        .max(Double::compareTo).get())\n                .max().getAsDouble();\n        System.out.println(\"Nota mas alta de entre los estudiantes: \" + bestMark);\n\n    }\n\n    public static class Student {\n        private String name;\n        private LocalDate birthday;\n        private List<Double> markList;\n\n        public Student(String name, LocalDate birthday, List<Double> markList) {\n            this.name = name;\n            this.birthday = birthday;\n            this.markList = markList;\n        }\n\n        public String getName() {\n            return name;\n        }\n\n        public void setName(String name) {\n            this.name = name;\n        }\n\n        public LocalDate getBirthday() {\n            return birthday;\n        }\n\n        public void setBirthday(LocalDate birthday) {\n            this.birthday = birthday;\n        }\n\n        public List<Double> getMarkList() {\n            return markList;\n        }\n\n        public void setMarkList(List<Double> markList) {\n            this.markList = markList;\n        }\n\n        @Override\n        public String toString() {\n            return getName();\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/java/danhingar.java",
    "content": "import java.time.LocalDate;\nimport java.util.Comparator;\nimport java.util.Date;\nimport java.util.List;\nimport java.util.function.Function;\n\npublic class danhingar {\n\n    public static void main(String[] args) {\n        System.err.println(applyFunc(String::length, \"Daniel\"));\n\n        Function<Integer, Integer> number = applyMultiplier(5);\n        int result = number.apply(5);\n        System.out.println(result);\n\n        List<Integer> numbers = List.of(1, 3, 4, 2, 5);\n        System.out.println(numbers.stream().map(num -> num * 2).toList());\n\n        System.out.println(numbers.stream().filter(num -> num % 2 == 0).toList());\n\n        System.out.println(numbers.stream().sorted().toList());\n\n        System.out.println(numbers.stream().sorted(Comparator.reverseOrder()).toList());\n\n        System.out.println(numbers.stream().reduce(0, Integer::sum));\n\n        // EXTRA\n        List<Student> students = List.of(\n                new Student(\"PEPE\", java.sql.Date.valueOf(LocalDate.parse(\"1987-04-29\")), List.of(5.0, 8.5, 3.0, 10.0)),\n                new Student(\"JUAN\", java.sql.Date.valueOf(LocalDate.parse(\"1995-08-04\")), List.of(1.0, 9.5, 2.0, 4.0)),\n                new Student(\"LUIS\", java.sql.Date.valueOf(LocalDate.parse(\"2000-12-15\")), List.of(4.0, 6.5, 5.0, 2.0)),\n                new Student(\"MATEO\", java.sql.Date.valueOf(LocalDate.parse(\"1980-01-25\")), List.of(10.0, 9.0, 9.7, 9.9)));\n\n        //Promedio\n        System.out.println(students.stream().map(s -> String.format(\"%s:%.2f\", s.getName(), s.average())).toList());\n\n        //Mejores\n        System.out.println(students.stream().filter(s-> s.average()>=9.0).map(Student::getName).toList());\n\n        //Fecha de nacimiento ordenada\n        System.out.println(students.stream().sorted(Comparator.comparing(Student::getBirthdate, Comparator.nullsLast(Comparator.reverseOrder()))).toList());\n\n        //Califiación más alta\n        System.out.println(students.stream().map(Student::getGrades).flatMap(List::stream).mapToDouble(Double::doubleValue).max().getAsDouble());\n    }\n\n    public static <W, X> X applyFunc(Function<W, X> function, W cadena) {\n        return function.apply(cadena);\n    }\n\n    public static Function<Integer, Integer> applyMultiplier(int n) {\n        return (number) -> number * n;\n    }\n\n}\n\nclass Student {\n    private String name;\n    private Date birthdate;\n    private List<Double> grades;\n\n    public Student(String name, Date birthdate, List<Double> grades) {\n        this.name = name;\n        this.birthdate = birthdate;\n        this.grades = grades;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public Date getBirthdate() {\n        return birthdate;\n    }\n\n    public void setBirthdate(Date birthdate) {\n        this.birthdate = birthdate;\n    }\n\n    public List<Double> getGrades() {\n        return grades;\n    }\n\n    public void setGrades(List<Double> grades) {\n        this.grades = grades;\n    }\n\n    public Double average() {\n        return this.grades.stream().reduce(0.0, Double::sum) / this.grades.size();\n    }\n\n    @Override\n    public String toString() {\n        return \"Student [name=\" + name + \", birthdate=\" + birthdate + \", grades=\" + grades + \"]\";\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/java/eulogioep.java",
    "content": "import java.time.LocalDate;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Comparator;\nimport java.util.List;\nimport java.util.stream.Collectors;\n\npublic class eulogioep {\n    // Clase Estudiante para almacenar la información de cada alumno\n    static class Estudiante {\n        private String nombre;\n        private LocalDate fechaNacimiento;\n        private List<Double> calificaciones;\n\n        public Estudiante(String nombre, LocalDate fechaNacimiento, List<Double> calificaciones) {\n            this.nombre = nombre;\n            this.fechaNacimiento = fechaNacimiento;\n            // Validamos que las calificaciones estén entre 0 y 10\n            this.calificaciones = calificaciones.stream()\n                .filter(calif -> calif >= 0 && calif <= 10)\n                .collect(Collectors.toList());\n        }\n\n        public String getNombre() { return nombre; }\n        public LocalDate getFechaNacimiento() { return fechaNacimiento; }\n        public List<Double> getCalificaciones() { return calificaciones; }\n    }\n\n    public static void main(String[] args) {\n        // Creamos una lista de estudiantes de ejemplo\n        List<Estudiante> estudiantes = Arrays.asList(\n            new Estudiante(\"Ana García\", \n                LocalDate.of(2000, 5, 15),\n                Arrays.asList(9.5, 8.7, 9.2, 9.8)),\n            new Estudiante(\"Carlos Pérez\",\n                LocalDate.of(1999, 3, 20),\n                Arrays.asList(7.5, 8.0, 6.5, 7.8)),\n            new Estudiante(\"María López\",\n                LocalDate.of(2001, 8, 10),\n                Arrays.asList(9.0, 9.5, 9.3, 9.7))\n        );\n\n        // 1. Promedio de calificaciones\n        // Usamos map() para transformar cada estudiante en un nuevo objeto con nombre y promedio\n        System.out.println(\"Promedios de calificaciones:\");\n        estudiantes.stream()\n            .map(e -> {\n                double promedio = e.getCalificaciones().stream()\n                    .mapToDouble(Double::doubleValue)\n                    .average()\n                    .orElse(0.0);\n                return String.format(\"%s: %.2f\", e.getNombre(), promedio);\n            })\n            .forEach(System.out::println);\n\n        // 2. Mejores estudiantes (promedio >= 9)\n        System.out.println(\"\\nMejores estudiantes (promedio >= 9):\");\n        estudiantes.stream()\n            .filter(e -> e.getCalificaciones().stream()\n                .mapToDouble(Double::doubleValue)\n                .average()\n                .orElse(0.0) >= 9)\n            .map(Estudiante::getNombre)\n            .forEach(System.out::println);\n\n        // 3. Estudiantes ordenados por fecha de nacimiento (más joven primero)\n        System.out.println(\"\\nEstudiantes ordenados por edad (más joven primero):\");\n        estudiantes.stream()\n            .sorted(Comparator.comparing(Estudiante::getFechaNacimiento).reversed())\n            .map(e -> String.format(\"%s (%s)\", \n                e.getNombre(), \n                e.getFechaNacimiento()))\n            .forEach(System.out::println);\n\n        // 4. Mayor calificación de todos los estudiantes\n        double maxCalificacion = estudiantes.stream()\n            .flatMap(e -> e.getCalificaciones().stream())\n            .max(Double::compare)\n            .orElse(0.0);\n        System.out.println(\"\\nMayor calificación: \" + maxCalificacion);\n    }\n}"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/java/martinbohorquez.java",
    "content": "import java.time.LocalDate;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Comparator;\nimport java.util.List;\nimport java.util.function.Function;\n\npublic class martinbohorquez {\n\n    public static void main(String[] args) {\n        //Función como argumento\n        String name = \"MartinDev\";\n        System.out.printf(\"La longitud '%s' es: %s%n\", name, applyFunction(String::length, name));\n        System.out.printf(\"El nombre '%s' en mayúscula es: %s%n\", name, applyFunction(String::toUpperCase, name));\n\n        //Retorno de función\n        int intA = 3;\n        int intB = 4;\n        System.out.printf(\"La multiplicación de %d y %d es: %d%n\", intA, intB, applyMultiplier(intA).apply(intB));\n        //Uso de API Stream con interfaces funcionales: Predicate<T>, Function<T, R>, Consumer<T>, Supplier<R>,\n        // BiPredicate<T, U>, BiFunction<T, U, R>, BiConsumer<T, U>, UnaryOperator<T>, BinaryOperator<T>\n        List<Integer> numbers = new ArrayList<>(Arrays.asList(1, 3, 4, 2, 5));\n        System.out.printf(\"La lista de números '%s' multiplicada por 2 es: %s%n\", numbers,\n                numbers.stream().map(n -> n * 2).toList()); //<R> Stream<R> map(Function<? super T, ? extends R> mapper)\n        System.out.printf(\"La lista de números '%s' filtrada por números pares es: %s%n\", numbers,\n                numbers.stream().filter(n -> n % 2 == 0).toList()); //Stream<T> filter(Predicate<? super T> predicate)\n        System.out.printf(\"La lista de números '%s' ordenada de forma ascendente es: %s%n\", numbers,\n                numbers.stream().sorted().toList());\n        System.out.printf(\"La lista de números '%s' ordenada de forma descendente es: %s%n\", numbers,\n                numbers.stream().sorted().toList().reversed());\n        System.out.printf(\"La lista de números '%s' ordenada de forma descendente es: %s%n\", numbers,\n                numbers.stream().sorted(Comparator.reverseOrder()).toList()); //Uso de Comparator\n        //UnaryOperator<T> == Function<T, R> cuando las clases T, U son iguales.\n        //BinaryOperator<T> == BiFunction<T, U, R> cuando las clases T, U, R son iguales.\n        System.out.printf(\"La suma de todos los elementos de la lista '%s' es: %d%n\", numbers,\n                numbers.stream().reduce(0, Integer::sum)); //T reduce(T identity, BinaryOperator<T> accumulator)\n\n        /*\n         * DIFICULTAD EXTRA\n         */\n        List<Student> students = Arrays.asList(\n                new Student(\"Piero\", LocalDate.of(1997, 12, 23), Arrays.asList(9.0, 9.0, 9.5)),\n                new Student(\"Katherine\", LocalDate.of(1996, 6, 1), Arrays.asList(9.5, 9.0, 9.5)),\n                new Student(\"Marshall\", LocalDate.of(1994, 3, 18), Arrays.asList(8.0, 7.5, 8.0)),\n                new Student(\"Martin\", LocalDate.of(1994, 9, 20), Arrays.asList(9.0, 9.7, 9.5)),\n                new Student(\"Jimena\", LocalDate.of(1997, 4, 29), Arrays.asList(8.5, 9.5, 9.5)),\n                new Student(\"Marcos\", LocalDate.of(1995, 9, 20), Arrays.asList(8.0, 8.0, 9.5))\n        );\n\n        System.out.printf(\"La lista de estudiantes con su respectivo promedio de calificaciones es: %n%s%n\",\n                students.stream().map(Student::toStringNameAveragegradePoint).toList());\n\n        System.out.printf(\"La lista de estudiantes con promedio de calificaciones mayores a 9 es: %s%n\",\n                students.stream()\n                        .filter(s -> s.getAverageGradePoint() > 9)\n                        .map(Student::getName)\n                        .toList());\n\n        students.sort(Comparator.comparing(Student::getBirthDate));\n        System.out.printf(\"La lista de estudiantes ordenada por edad (ascendente) es: %s%n\",\n                students.stream()\n                        .map(Student::getName)\n                        .toList());\n\n        System.out.printf(\"La calificación más alta entre la de todos los alumnos es: %.2f%n\",\n                students.stream()\n                        .map(student -> student.getGradesList().stream().max(Double::compareTo).orElse(0.0))\n                        .max(Double::compareTo)\n                        .orElse(0.00));\n\n\n        System.out.printf(\"La calificación más alta entre la de todos los alumnos es: %.2f%n\",\n                students.stream()\n                        .flatMap(s -> s.getGradesList().stream())\n                        .max(Double::compareTo)\n                        .orElse(0.00));\n\n    }\n\n    private static Function<Integer, Integer> applyMultiplier(int n) {\n        return x -> x * n;\n    }\n\n    public static <T, R> R applyFunction(Function<T, R> function, T x) {\n        return function.apply(x);\n    }\n\n    private static class Student {\n        private String name;\n        private LocalDate birthDate;\n        private List<Double> gradesList;\n\n        public Student(String name, LocalDate birthDate, List<Double> gradesList) {\n            this.name = name;\n            this.birthDate = birthDate;\n            this.gradesList = gradesList;\n        }\n\n        public String getName() {\n            return name;\n        }\n\n        public LocalDate getBirthDate() {\n            return birthDate;\n        }\n\n        public List<Double> getGradesList() {\n            return gradesList;\n        }\n\n        public Double getAverageGradePoint() {\n            return getGradesList().stream().mapToDouble(Double::doubleValue).average().orElse(0.0);\n        }\n\n        public String toStringNameAveragegradePoint() {\n            String averageGradePoint = String.format(\"%.2f\", getAverageGradePoint());\n            return \"{name = '\" + name + \"', \" +\n                    \"average = \" + averageGradePoint + \"}\";\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/java/simonguzman.java",
    "content": "import java.time.LocalDate;\nimport java.util.Arrays;\nimport java.util.List;\nimport java.util.function.Consumer;\nimport java.util.function.Function;\nimport java.util.function.Predicate;\nimport java.util.function.Supplier;\nimport java.util.stream.Collectors;\n\npublic class simonguzman {\n    public static void main(String[] args) {\n        //ejercicioPrincipal();\n        ejercicioAdicional();\n    }\n\n    /******************** Ejercicio adicional ********************/\n    public static void ejercicioAdicional(){\n        List<Estudiante> estudiantes = Arrays.asList(\n            new Estudiante(\"Juan\", LocalDate.of(2000, 5, 15), Arrays.asList(8.0, 9.0, 10.0)),\n            new Estudiante(\"Ana\", LocalDate.of(1998, 11, 3), Arrays.asList(9.5, 9.0, 9.7)),\n            new Estudiante(\"Carlos\", LocalDate.of(2002, 6, 21), Arrays.asList(6.0, 7.5, 8.0))\n        );\n        operaciones(estudiantes);\n    }\n\n    public static void operaciones(List<Estudiante> estudiantes){\n        promedioCalificaciones(estudiantes);\n\n        List<String> mejores = mejoresEstudiantes(estudiantes);\n        System.out.println(\"Mejores estudiantes: \"+mejores);\n\n        List<Estudiante> ordenados = ordenarPorNacimiento(estudiantes);\n        System.out.println(\"Estudiantes ordenados por nacimiento:\");\n        ordenados.forEach(est -> System.out.println(est.getNombre()));\n\n        double mayorCalificacion = obtenerMayorCalificacion(estudiantes);\n        System.out.println(\"Mayor calificación: \" + mayorCalificacion);\n    }\n\n    public static void promedioCalificaciones(List<Estudiante> estudiantes){\n        estudiantes.forEach(estudiante -> {\n            double promedio = estudiante.getPromedio();\n            System.out.println(\"Estudiante: \"+estudiante.getNombre()+ \" ,promedio: \"+promedio);\n        });\n    }\n\n    public static List<String> mejoresEstudiantes(List<Estudiante> estudiantes){\n        return estudiantes.stream().filter(est -> est.getPromedio() >= 9).map(Estudiante::getNombre).toList();\n    }\n\n    public static List<Estudiante> ordenarPorNacimiento(List<Estudiante> estudiantes){\n        return estudiantes.stream().sorted((e1, e2) -> e2.getFechaNacimiento().compareTo(e1.getFechaNacimiento())).toList();\n    }\n\n    public static double obtenerMayorCalificacion(List<Estudiante> estudiantes){\n        return estudiantes.stream().flatMap(est -> est.getCalificaciones().stream()).max(Double::compareTo).orElse(0.0);\n    }\n    public static class Estudiante {\n        private String nombre;\n        private LocalDate fechaNacimiento;\n        private List<Double> calificaciones;\n\n        public Estudiante(){\n\n        }\n\n        public Estudiante(String nombre, LocalDate fechaNacimiento, List<Double> calificaciones){\n            this.nombre = nombre;\n            this.fechaNacimiento = fechaNacimiento;\n            this.calificaciones = calificaciones;\n        }\n\n        public String getNombre() {\n            return nombre;\n        }\n\n        public LocalDate getFechaNacimiento() {\n            return fechaNacimiento;\n        }\n\n        public List<Double> getCalificaciones() {\n            return calificaciones;\n        }\n\n        public double getPromedio(){\n            return calificaciones.stream().mapToDouble(Double::doubleValue).average().orElse(0.0);\n        }\n    }\n\n    /******************** Ejercicio conceptual ********************/\n\n    public static void ejercicioPrincipal(){\n        List<Integer> numeros = Arrays.asList(1,2,3,4,5,6,7,8,9,10);\n        List<Integer> numerosMultiplicados = multiplicarXDos(numeros);\n        List<Integer> numerosPares = filtrarNumerosPares(numerosMultiplicados);\n        imprimirNumeros(numerosPares);\n        int suma = sumarNumeros(numerosPares);\n        System.out.println(\"Suma de los números pares multiplicados por 2: \" + suma);\n    }\n\n    public static List<Integer> multiplicarXDos(List<Integer> numeros){\n        Function<Integer, Integer> multiplicar = (n) -> n * 2;\n        return numeros.stream().map(multiplicar).collect(Collectors.toList());\n    }\n\n    public static List<Integer> filtrarNumerosPares(List<Integer> numeros){\n        Predicate<Integer> esPar = (n) -> n % 2 == 0;\n        return numeros.stream().filter(esPar).collect(Collectors.toList());\n    }\n\n    public static int sumarNumeros(List<Integer> numeros){\n        Supplier<Integer> sumar = () -> numeros.stream().mapToInt(Integer::intValue).sum();\n        return sumar.get();\n    }\n\n    public static void imprimirNumeros(List<Integer> numeros){\n        Consumer<Integer> imprimir = (n) -> System.out.println(\"Numero: \"+n);\n        numeros.forEach(imprimir);\n    }\n}\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/javascript/7R0N1X.js",
    "content": "const frutas = ['Manzana', 'Banana', 'Fresa', 'Uva', 'Mango', 'Pera', 'Kiwi', 'Durazno', 'Sandía', 'Naranja', 'Cereza']\n\nconst crearFiltroPorLetra = (letra) => {\n  return function (fruta) {\n    return fruta.startsWith(letra)\n  }\n}\n\nconst filtrarPorM = crearFiltroPorLetra('M')\nconst frutasConM = frutas.filter(filtrarPorM)\n\nconsole.log(frutasConM)\n\n// DIFICULTAD EXTRA\nconst estudiantes = [\n  { nombres: 'Eduardo Molina', fechaNacimiento: '1999-08-30', calificaciones: [10, 8, 9, 10] },\n  { nombres: 'Lucía Torres', fechaNacimiento: '2001-05-15', calificaciones: [9, 7, 8, 10] },\n  { nombres: 'Carlos Jiménez', fechaNacimiento: '2000-11-22', calificaciones: [6, 9, 8, 7] },\n  { nombres: 'Ana Pérez', fechaNacimiento: '1998-12-10', calificaciones: [10, 10, 9, 8] },\n  { nombres: 'Juan Rodríguez', fechaNacimiento: '2002-04-05', calificaciones: [7, 6, 7, 8] },\n  { nombres: 'María López', fechaNacimiento: '2000-03-18', calificaciones: [8, 9, 10, 9] },\n  { nombres: 'Sofía García', fechaNacimiento: '1999-09-12', calificaciones: [9, 8, 8, 9] },\n  { nombres: 'Miguel Castro', fechaNacimiento: '2003-01-25', calificaciones: [6, 7, 6, 7] },\n  { nombres: 'Laura Fernández', fechaNacimiento: '2001-06-30', calificaciones: [10, 9, 9, 10] },\n  { nombres: 'Andrés Martínez', fechaNacimiento: '2002-02-14', calificaciones: [8, 8, 7, 8] }\n]\n\nconst obtenerPromedio = (estudiante) => {\n  const { nombres, calificaciones } = estudiante\n  const promedio = calificaciones.reduce((acumulador, nota) => acumulador + nota / calificaciones.length, 0)\n  return {\n    nombres,\n    promedio\n  }\n}\n\nconst mejoresEstudiantes = (estudiante) => {\n  const { nombres, promedio } = estudiante\n  if (promedio >= 9) {\n    return { nombres }\n  }\n}\n\nconst ordenarFechaNacimiento = (estudianteA, estudianteB) => {\n  return new Date(estudianteB.fechaNacimiento) - new Date(estudianteA.fechaNacimiento)\n}\n\nconst calificacionMasAlta = (estudiante) => {\n  const { nombres, calificaciones } = estudiante\n  const calificacionAlta = Math.max(...calificaciones)\n  return {\n    nombres,\n    calificacionAlta\n  }\n}\n\nconst promedios = estudiantes.map(obtenerPromedio)\nconsole.log(promedios)\n\nconst mejoresNotas = promedios.filter(mejoresEstudiantes)\nconsole.log(mejoresNotas)\n\nconst estudiantesPorFechaNacimiento = estudiantes.sort(ordenarFechaNacimiento)\nconsole.log(estudiantesPorFechaNacimiento)\n\nconst calificacionMasAltaPorEstudiante = estudiantes.map(calificacionMasAlta)\nconsole.log(calificacionMasAltaPorEstudiante)\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/javascript/AChapeton.js",
    "content": "var radios = [1, 2, 3];\n\nvar calcularArea = function (radio) {\n    return Math.PI * (Math.pow(radio, 2));\n};\n\nvar calcularDiametro = function (radio) {\n    return 2 * radio;\n};\n\nvar calcular = function (radios, funcion) {\n    var resultados = [];\n    for (var i = 0; i < radios.length; i++) {\n        resultados.push(funcion(radios[i]));\n    }\n    return resultados;\n};\n\nconsole.log('Areas: ', calcular(radios, calcularArea));\nconsole.log('Diametros: ', calcular(radios, calcularDiametro));\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/javascript/Chrisdev00.js",
    "content": "/*\n* EJERCICIO:\n* Explora el concepto de funciones de orden superior en tu lenguaje \n* creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n*\n* DIFICULTAD EXTRA (opcional):\n* Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n* lista de calificaciones), utiliza funciones de orden superior para \n* realizar las siguientes operaciones de procesamiento y análisis:\n* - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n*   y promedio de sus calificaciones.\n* - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n*   que tienen calificaciones con un 9 o más de promedio.\n* - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n* - Mayor calificación: Obtiene la calificación más alta de entre todas las\n*   de los alumnos.\n* - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n*/\n\n\n//Map \n\nconst languages = [\"Java\", \"Python\", \"JavaScript\", \"Go\", \"Bash\"];\n\nconst languagesLower = languages.map((lan) => lan.toLowerCase());\nconsole.log(languagesLower)\n\n// Filter\n\nconst is_name_long = languages.filter((lan) => lan.length > 6);\nconsole.log(is_name_long)\n\nconst numbers = [1, 2, 3, 4, 5];\n\nconst is_odd = numbers.filter((num) => num % 2!= 0 );\nconsole.log(is_odd)\n\n// Reduce\n\nconst sum = numbers.reduce((acc, cur) => acc + cur, 0);\n\nconsole.log(sum)\n\n// every\n\nconst areAllint = numbers.every((nume) => typeof nume === \"number\");\n\nconsole.log(areAllint)\n\n// find\n\nconst name_long = languages.find((lan) => lan.length > 3);\nconsole.log(name_long)\n\n\nconst scores = [\n  {name: \"Juan\", score: 90},\n  {name: \"Raul\", score: 78},\n  {name: \"Pedro\", score: 69},\n  {name: \"Matias\", score: 98},\n];\n\nconst user_score = scores.find((user) => user.score > 91 );\nconsole.log(user_score)\n\n// findIndex\n\nconst ages = [34, 15, 26, 87, 47]\n\nconst age = ages.findIndex((age) => age < 20);\nconsole.log(age)\n\n// some\n\nconst list_age = [34, 15, \"26\", 87, 47]\n\nconst someTrue = list_age.some((x) => x===\"26\");\nconsole.log(someTrue)\n\n\n\n//////////////-----------------------------  EXTRA ----------------------------------/////////////////////////\n\nstudents = [\n  {\"name\": \"Carlos\", \"date_birth\": \"15-05-2001\", \"grades\": [8.5, 9, 9.5]},\n  {\"name\": \"Juan\", \"date_birth\": \"08-11-2000\", \"grades\": [10, 9, 9.5]},\n  {\"name\": \"Pedro\", \"date_birth\": \"17-01-2002\", \"grades\": [7, 8, 7.6]},\n  {\"name\": \"Jose\", \"date_birth\": \"22-10-2000\", \"grades\": [9.5, 7.5, 8.5]},\n  {\"name\": \"Mau\",\"date_birth\": \"30-09-2000\", \"grades\": [6.5, 9, 10]},\n  {\"name\": \"Chris\", \"date_birth\": \"10-04-2001\",\"grades\": [8.5, 10, 9.5]},\n  {\"name\": \"Marcelo\", \"date_birth\": \"15-12-2000\", \"grades\": [7.5, 10, 5]},\n  {\"name\": \"Edward\", \"date_birth\": \"04-01-2001\", \"grades\": [5.5, 8.8, 9.6]},\n  {\"name\": \"Rodrigo\", \"date_birth\": \"01-06-2002\", \"grades\": [9.4, 5.6, 9.3]}\n]\n\nfunction calculateAverage(grades) {\n  const validGrades = grades.filter(grade => grade >= 0 && grade <= 10);\n  return validGrades.length ? validGrades.reduce((sum, grade) => sum + grade, 0) / validGrades.length : 0;\n}\n\nfunction getAverageStudent(student) {\n  return {\n      name: student.name,\n      average_grade: calculateAverage(student.grades).toFixed(2)\n  };\n}\n\nfunction best_student(student) {\n  return student.average_grade>= 9\n}\n\nfunction parseDate(dob) {\n  const [day, month, year] = dob.split(\"-\");\n  return new Date(year, month - 1, day); // Note: month is 0-based in JavaScript Date\n}\n\nfunction getDateOfBirth(student) {\n  return parseDate(student.date_birth);\n}\n\nconst averageStudents = students.map(getAverageStudent);\n\nconst best_students = averageStudents.filter(best_student)\n\nconst studentsByAge = students.slice().sort((a, b) => getDateOfBirth(a) - getDateOfBirth(b));\n\nlet highestGrade = 0;\nlet studentWithHighestGrade = null;\n\nfor (const student of students){\n  for (const grade of student.grades){\n    if (grade > highestGrade){\n      highestGrade = grade\n      studentWithHighestGrade = student.name\n    }\n  }\n}\n\nconsole.log(\"Estudiantes con sus promedios de calificaciones:\")\nfor (const student of averageStudents){\n console.log(`${student['name']}: ${student['average_grade']}`)\n}\n\nconsole.log(\"\\nMejores Estudiantes (promedio >= 9):\");\nfor (const student of best_students) {\n  console.log(student.name);\n}\n\nconsole.log(\"\\nEstudiantes ordenados desde el más joven:\");\nfor (const student of studentsByAge) {\n  console.log(`${student.name}: ${student.date_birth}`);\n}\n\nconsole.log(`\\nLa calificacion mas alta es ${highestGrade} de ${studentWithHighestGrade}`)"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/javascript/DavidMoralesDeveloper.js",
    "content": "\n//  * EJERCICIO:\n//  * Explora el concepto de funciones de orden superior en tu lenguaje \n//  * creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n// map filter reduce....\n\nfunction procesar(array, callback) {\n  return array.map(callback);\n}\n\nconst numeros = [1, 2, 3];\nconst cuadrados = procesar(numeros, x => x * 2);\nconsole.log(cuadrados); // [2, 4, 6]\n\n// ---------\nfunction crearMultiplicador(factor) {\n  return function(numero) {\n    return numero * factor;\n  };\n}\n\nconst multiplicarPor3 = crearMultiplicador(3);\nconsole.log(multiplicarPor3(5)); // 15\n\n//  * DIFICULTAD EXTRA (opcional):\n//  * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n//  * lista de calificaciones), utiliza funciones de orden superior para \n//  * realizar las siguientes operaciones de procesamiento y análisis:\n//  * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n//  *   y promedio de sus calificaciones.\n//  * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n//  *   que tienen calificaciones con un 9 o más de promedio.\n//  * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n//  * - Mayor calificación: Obtiene la calificación más alta de entre todas las\n//  *   de los alumnos.\n//  * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\nconst estudiantes =[\n    {\n    nombre: \"Ana García\",\n    fechaNacimiento: \"2000-03-15\",\n    calificaciones: [85, 92, 78, 88, 95]\n  },\n  {\n    nombre: \"Carlos López\",\n    fechaNacimiento: \"1999-07-22\",\n    calificaciones: [76, 82, 90, 85, 79]\n  },\n  {\n    nombre: \"María Rodríguez\",\n    fechaNacimiento: \"2001-01-10\",\n    calificaciones: [95, 98, 92, 97, 94]\n  }\n]\n\n   \n// function escuela (estudiantes)  {\n    \n//     const nomyPro = estudiantes.map(estudiante => ({\n//         \"name\": estudiante.nombre,\n//          \"promedio\": estudiante.calificaciones.reduce((total, suma)=> total + suma)/estudiante.calificaciones.length\n//         }) \n//     )\n    \n// return nomyPro\n// }\n// console.log(escuela(estudiantes))\n\nconst promedio = (calificaciones) => {\n    return calificaciones.reduce((total, sum)=> total + sum) / calificaciones.length\n}\n\nconsole.log(\"nombre y promedio\")\n//nombre y promedio\nconst nomyprom = estudiantes.map(estudiantes => ({\n    \"nombre\": estudiantes.nombre,\n    \"promedio\": promedio(estudiantes.calificaciones)\n}))\n\nconsole.log(nomyprom)\n\n//Mejores\n// const mejores = estudiantes.map(estudiante => (\n//     ( promedio(estudiante.calificaciones) > 90 ? estudiante.nombre : \"\" )\n// ))\n\n// console.log(mejores)\nconsole.log(\"estudiantes con promedio superior a 9\")\n\nconst mejores = estudiantes\n    .filter(estudiante => promedio(estudiante.calificaciones) > 90)\n    .map(estudiante => estudiante.nombre)\n\n    console.log(mejores)\n\n  //  * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n  console.log(\"estudiantes ordenados desde el mas joven\")\n  function dateDeNacimiento (fechaString) {\n    const [año, mes, dia]= fechaString.split(\"-\")\n    return new Date(año,mes-1,dia)\n  }\n\n  \n//   const masJoven = estudiantes.map(estudiante => dateDeNacimiento(estudiante.fechaNacimiento)).sort()\nconst masJoven = [...estudiantes]. sort((a,b) => {\n    const fechaA = dateDeNacimiento(a.fechaNacimiento)\n    const fechaB = dateDeNacimiento(b.fechaNacimiento)\n    return fechaA - fechaB\n\n})\n  \n\n  console.log(masJoven)\n\n  console.log(\"mayor calificacion de cada alumno\")\n\n//   Falta el operador spread (...) para expandir el array---------\n\n  const calidicacionMayor = Math.max(...estudiantes.map(calificanciones => Math.max(...calificanciones.calificaciones)))\n\n  console.log(calidicacionMayor)\n  "
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/javascript/Deyvid-10.js",
    "content": "// Funciones de orden superior\n\n// #1\n\nfunction funcion1(num, funcion2) {\n    console.log(num + funcion2(2));\n}\n\nfunction funcion2(num2)\n{\n    return num2\n}\n\nfuncion1(2, funcion2)\n\n// #2\n\nlet numero = [1,2,3,4,5]\n\nlet filtro = numero.filter(function(num){\n    return num % 2 == 0 \n})\n\nconsole.log(filtro);\n\n// #3\n\nfunction funcion3(funcion4)\n{\n    return funcion4()\n}\n\nfunction funcion4()\n{\n    console.log(\"Soy la funcion 4\");\n}\n\nfuncion3(funcion4)\n\n\n// DIFICULTAD EXTRA\n\nlet estudiantes = [[\"Deyvid Marmolejo\", \"Daniel Amparo\", \"Hector Sanchez\"], \n                [\"1997-05-26\", \"1996-08-16\", \"1998-11-25\"], \n                [{\"espanol\": 9, \"matematicas\": 9.5, \"biologia\": 9, \"historia\": 9},\n                {\"espanol\": 8, \"matematicas\": 7, \"biologia\": 9, \"historia\": 9},\n                {\"espanol\": 10, \"matematicas\": 8, \"biologia\": 9, \"historia\": 8}\n                ]]\n\nfunction promedio(listaEstudiantes)\n{\n    return [listaEstudiantes[0], listaEstudiantes[2].map(num =>\n        Object.values(num).reduce((acumulado, suma)=>acumulado+suma, 0)/Object.values(num).length\n    )]\n}\n\nfunction mejoresEstudiantes(listaEstudiantes, promedio)\n{\n    let resumenPromedio = promedio(listaEstudiantes)\n    let mejoresEstudiantes = []\n\n    for(let i=0; i<resumenPromedio[1].length; i++)\n    {\n        if(resumenPromedio[1][i] >= 9)\n        {\n            mejoresEstudiantes.push(resumenPromedio[0][i])\n        }\n    }\n\n    return mejoresEstudiantes\n\n}\n\nfunction nacimiento(listaEstudiantes)\n{\n\n    return listaEstudiantes[1].sort((x, y) =>{\n        let fechaX = new Date(x)\n        let fechaY = new Date(y)\n\n        return fechaX - fechaY\n    })\n}\n\nfunction mayor(listaEstudiantes)\n{\n    return [listaEstudiantes[0], listaEstudiantes[2].map(num => Object.values(num).sort((x, y) => x-y)[listaEstudiantes[0].length])]     \n}\n\nconsole.log(promedio(estudiantes));\nconsole.log(mejoresEstudiantes(estudiantes , promedio));\nconsole.log(nacimiento(estudiantes));\nconsole.log(mayor(estudiantes));\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #22 - JavaScript ->Jesus Antonio Escamilla */\n\n/**\n * Hemos visto cómo crear funciones que toman cadenas y números como argumentos.\n * A veces, necesitaremos crear funciones que tomen otras funciones como argumentos o las utilicen como valores de retorno.\n * Éstas se denominan funciones de orden superior.\n * Una función de orden mayor (HOF -> Higher-Order Function) se denomina a (1) cualquier función que reciba una función como parámetro o (2) cualquier función que retorne otra función.\n * \n*/\n\n//---EJERCIÓ---\n// Aquí se puede ver como funciona una HOFs en un mensaje donde retorna el mensaje\nconst higherOrderFunction = (callback) => {\n    const string = '¡Las HOFs son realmente geniales!'\n    callback(string);\n}\n\n// Aquí se muestra el ejemplo\nhigherOrderFunction(console.log);\n\n\n// Creo un array de nombres para poder usarlo con los HOFs\nconst characters = [\n    {\n        firstName: 'Tulio',\n        lastName: 'Triviño',\n    },\n    {\n        firstName: 'Policarpo',\n        lastName: 'Avendaño',\n    },\n    {\n        firstName: 'Nicasio',\n        lastName: 'Fallido',\n    }\n];\n\n// Se creo la HOF usando MAP para encontrarlo\nconst names = characters.map(function(character) {\n    return character.firstName + \" \" + character.lastName;\n});\n\n// Aquí se muestra el ejemplo\nconsole.log(names);\n\n\n// Creo un array de números para poder usarlo con los HOFs\nconst numbers = [1, 2, 3, 4];\n\n// Creo la HOF se usa FILTER para hacer un filtro para encontrarlo\nconst even = numbers.filter(num => num % 2 === 0);\n\n// Aquí se muestra el ejemplo\nconsole.log(even);\n\n\n// Creo la HOF REDUCE para hacer un \nconst sum = numbers.reduce((acc, num) => acc + num, 0);\nconsole.log(sum);\n\n// Retorna una función de HOF\nfunction createMultiplier(multiplicar) {\n    return function(num) {\n        return num * multiplicar;\n    };\n}\n\n// Las constantes para usar\nconst doble = createMultiplier(2);\n\n// Los ejemplos de retorno de función\nconsole.log(doble(4));\nconsole.log(createMultiplier(3)(4));\n\n\n\n/**-----DIFICULTAD EXTRA-----*/\n\n//  Listado de Estudiantes\nconst students = [\n    {\"name\": \"Jesus\", \"birthDate\": \"22-12-1999\", \"grades\": [7, 8.5, 8, 10]},\n    {\"name\": \"Fatima\", \"birthDate\": \"02-04-2001\", \"grades\": [8, 7.2, 6, 9]},\n    {\"name\": \"Antonio\", \"birthDate\": \"15-11-1990\", \"grades\": [5, 9.8, 10, 5]},\n    {\"name\": \"Lizette\", \"birthDate\": \"28-07-2002\", \"grades\": [9.1, 9.6, 8.3, 10]},\n];\n\n\n//  Promedio de los Estudiantes en forma de lista\nconst promedios = students.map(estudiantes => {\n    let sumar = estudiantes.grades.reduce((a, b) => a + b, 0);\n    let promedio = sumar / estudiantes.grades.length;\n    return {name: estudiantes.name, promedio: promedio};\n});\n//  Se muestra el Promedio\nconsole.log('Los Promedio de los estudiantes', promedios);\n\n\n//  Los Mejores Estudiantes en forma de lista\nconst mejoresEstudiantes = promedios.filter(estudiantes => estudiantes.promedio >= 9).map(estudiantes => estudiantes.name);\n//  Se muestra los Mejores Estudiantes\nconsole.log('Los Mejores Estudiantes',mejoresEstudiantes);\n\n\n//  El Estudiante mas Joven en forma lista\nconst estudiantesOrdenados = students.slice().sort((a, b) => {\n    const [dayA, monthA, yearA] = a.birthDate.split('-').map(Number);\n    const [dayB, monthB, yearB] = b.birthDate.split('-').map(Number);\nreturn new Date(yearB, monthB - 1, dayB) - new Date(yearA, monthA - 1, dayA);\n});\n//  Se muestra los Estudiantes en orden del mas Joven Primero\nconsole.log('Los ordenados por fecha de Nacimiento (Por el mas Joven primero)',estudiantesOrdenados);\n\n\n//  La Mayor Calificación de todos los Estudiantes\nconst todasCali = students.flatMap(estudiantes => estudiantes.grades);\nconst masAltaGrade = Math.max(...todasCali);\n//  Se muestra la Calificación más alta\nconsole.log(masAltaGrade);\n\n\n/**-----DIFICULTAD EXTRA-----*/"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/javascript/RaulDoezon.js",
    "content": "/*\n  EJERCICIO:\n  Explora el concepto de funciones de orden superior en tu lenguaje \n  creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n*/\n\nconsole.log(\"+++++++++ FUNCIÓN DE ORDEN SUPERIOR QUE TOMA UN CALLBACK COMO ARGUMENTO +++++++++\");\n\nconst higherOrderFunction = (callback) => {\n  const message = \"¡Hola, soy una función de orden superior!\";\n\n  callback(message);\n}\n\nhigherOrderFunction(console.log);\n\nconsole.log(\"\\n+++++++++ DEVOLVER UNA FUNCIÓN DESDE OTRA FUNCIÓN +++++++++\");\n\nconst callMe = () => console.log;\n\ncallMe()(\"Hola, soy una función que devuelve otra función; en este caso, un console.log()\");\n\n/*\n  DIFICULTAD EXTRA (opcional):\n  Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n  lista de calificaciones), utiliza funciones de orden superior para \n  realizar las siguientes operaciones de procesamiento y análisis:\n  - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n    y promedio de sus calificaciones.\n  - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n    que tienen calificaciones con un 9 o más de promedio.\n  - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n  - Mayor calificación: Obtiene la calificación más alta de entre todas las\n    de los alumnos.\n  - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n*/\n\nconsole.log(\"\\n+++++++++ LISTA DE ESTUDIANTES +++++++++\");\n\nconst students = [\n  {\n    name: \"Pedro\",\n    birthday: \"01/01/1990\",\n    ratings: [9.1, 8.4, 9, 9.8, 9.9, 8.2],\n  },\n  {\n    name: \"Juan\",\n    birthday: \"02/02/1993\",\n    ratings: [6, 5.6, 7.8, 9.2, 9.8, 9.7],\n  },\n  {\n    name: \"Santiago\",\n    birthday: \"03/03/1992\",\n    ratings: [9, 8.1, 8.4, 6.8, 7.7, 7.5],\n  },\n  {\n    name: \"Mateo\",\n    birthday: \"04/04/1991\",\n    ratings: [5.1, 5.7, 6, 9, 9.4, 8.5],\n  },\n  {\n    name: \"Pablo\",\n    birthday: \"05/05/1994\",\n    ratings: [9, 9.2, 9.4, 9.8, 9.9, 10],\n  },\n];\n\nfunction average(data) {\n  const initialAverage = 0;\n  const sumOfGrades = data.ratings.reduce((accumulator, currentValue) => accumulator + currentValue, initialAverage);\n  return sumOfGrades / (data.ratings.length);\n}\n\nconst allStudents = () => students.map((student) => console.log(`- Nombre: ${student.name}. Promedio: ${average(student)}.`));\n\nconst sortByBirthDay = () => {\n  const sorting = students.slice().sort((a, b) => {\n    const birthDayA = new Date(a.birthday);\n    const birthDayB = new Date(b.birthday);\n\n    return birthDayB - birthDayA;\n  });\n\n  sorting.map((student) => console.log(`- Nombre: ${student.name}. Fecha de nacimiento: ${student.birthday}`));\n}\n\nconst bestAverages = () => {\n  students.map((student) => {\n    if (average(student) >= 9) {\n      console.log(`- ${student.name}.`);\n    }\n  });\n}\n\nconst bestGrade = () => {\n  console.log(Math.max(...students.map((student) => Math.max(...student['ratings']))));\n}\n\nconsole.log(\"Listado:\");\nallStudents();\n\nconsole.log(\"\\nEstudiantes con un promedio de 9 o superior:\");\nbestAverages();\n\nconsole.log(\"\\nEstudiantes ordenados de menor a mayor edad:\");\nsortByBirthDay();\n\nconsole.log(\"\\nLa calificación más alta:\");\nbestGrade();\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/javascript/RicJDev.js",
    "content": "//EJERCICIO\nlet arr = [1, 2, 3];\n\nconsole.log(arr.map((n) => n * 2));\n\nArray.prototype.customMap = function (callback) {\n\tlet result = [];\n\tfor (let i = 0; i < this.length; i++) {\n\t\tlet element = callback(this[i]);\n\t\tresult.push(element);\n\t}\n\treturn result;\n};\n\nconsole.log(arr.customMap((n) => n * 2));\n\n//EXTRA\nconst myStudents = [];\nconst bestStudents = [];\nconst failedStudents = [];\n\nclass Student {\n\tconstructor(name, grades, birthDate) {\n\t\tthis.name = name;\n\t\tthis.birthDate = birthDate;\n\t\tthis.grades = grades;\n\t\tthis.age = this.getAge();\n\t\tthis.average = this.getAverage();\n\n\t\tmyStudents.push(this);\n\n\t\tif (this.average >= 9) {\n\t\t\tbestStudents.push(this);\n\t\t}\n\n\t\tif (this.average < 5) {\n\t\t\tfailedStudents.push(this);\n\t\t}\n\t}\n\n\tgetAverage() {\n\t\tlet result = 0;\n\t\tthis.grades.forEach((element) => {\n\t\t\tresult = result + element;\n\t\t});\n\t\tlet average = result / this.grades.length;\n\t\treturn average;\n\t}\n\n\tgetAge() {\n\t\tlet now = new Date();\n\t\tlet age =\n\t\t\t(now.getTime() - this.birthDate.getTime()) / (365 * 24 * 60 * 60 * 1000);\n\t\treturn age;\n\t}\n}\n\nnew Student('Sophie', [8, 8, 7, 9], new Date(2003, 8, 21));\nnew Student('Rebeca', [8, 9, 10, 9], new Date(2001, 4, 16));\nnew Student('David', [7, 7, 9, 8], new Date(2003, 0, 15));\nnew Student('Eliezer', [4, 6, 7, 5], new Date(2005, 1, 21));\nnew Student('Robert', [10, 10, 10, 9], new Date(2002, 0, 16));\nnew Student('Erika', [10, 6, 6, 9], new Date(2003, 0, 20));\nnew Student('Tadeo', [4, 6, 3, 5], new Date(2004, 0, 2));\n\nfunction getHighestAverage() {\n\tlet result;\n\tlet average = 0;\n\tmyStudents.forEach((element) => {\n\t\tif (element.average > average) {\n\t\t\taverage = element.average;\n\t\t\tresult = element;\n\t\t}\n\t});\n\treturn result;\n}\n\nlet highestAverage = getHighestAverage();\n\nlet sortedByAverage = myStudents.toSorted((a, b) => {\n\treturn b.average - a.average;\n});\n\nlet sortedByAge = myStudents.toSorted((a, b) => {\n\treturn a.age - b.age;\n});\n\nconsole.log(`\\nCANTIDAD DE ESTUDIANTES: ${myStudents.length}`);\n\nconsole.log('\\nLISTA DE PROMEDIOS');\n\nsortedByAverage.customMap((element) => {\n\tconsole.log(`\\n${element.name}: ${element.average}`);\n});\n\nconsole.log(`\\nMEJORES ESTUDIANTES: ${bestStudents.length}`);\n\nbestStudents.customMap((element) => {\n\tconsole.log(`\\n${element.name}: ${element.average}`);\n});\n\nconsole.log(`\\nESTUDIANTES REPROBADOS: ${failedStudents.length}`);\nfailedStudents.customMap((element) => {\n\tconsole.log(`\\n${element.name}: ${element.average}`);\n});\n\nconsole.log('\\nLISTA DE NACIMIENTOS');\n\nsortedByAge.customMap((element) => {\n\tconsole.log(`\\n${element.name}: ${element.birthDate.toLocaleString()}`);\n\tconsole.log(`${Math.floor(element.age)} años`);\n});\n\nconsole.log('\\nMEJOR PROMEDIO DE LA CLASE');\n\nconsole.log(\n\t`\\nFelicidades a ${highestAverage.name}. Con un ${highestAverage.average} se ha coronado como el mejor promedio de la clase`\n);\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/javascript/Sac-Corts.js",
    "content": "// Function that accepts another function as an argument \nfunction processArray(func, arr) {\n    return arr.map(func);\n}\n\nfunction square(x) {\n    return x * x;\n}\n\nconst numbers = [1, 2, 3, 4];\nconst squares = processArray(square, numbers);\nconsole.log(squares);\n\n// Function that returns another function\nfunction createSum(x) {\n    return function(y) {\n        return x + y;\n    };\n}\n\nconst sum5 = createSum(5);\nconsole.log(sum5(20));\n\n// Using filter, map and reduce\nconst numbers10 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\nconst evenNumbers = numbers10.filter(num => num % 2 === 0);\nconst evenSquares = evenNumbers.map(num => num * num); \nconst sumEvenSquares = evenSquares.reduce((total, num) => total + num, 0);\n\nconsole.log(evenNumbers);\nconsole.log(evenSquares);\nconsole.log(sumEvenSquares);\n\n// Extra Exercise //\n\nconst students =  [{\n    name: 'Isaac',\n    birthdate: new Date(2001, 9, 21),\n    qualifications: [9.0, 10, 9.5, 9.8] \n},\n{\n    name: 'Juan',\n    birthdate: new Date(2001, 6, 22),\n    qualifications: [9, 8, 8.5, 9.5]\n},\n{\n    name: 'Luis',\n    birthdate: new Date(2003, 10, 5),\n    qualifications: [6, 7, 7.5, 8]\n},\n{\n    name: 'María',\n    birthdate: new Date(2000, 4, 20),\n    qualifications: [10, 9.5, 10, 10]\n}]; \n\nconst studentAverage = students.map(student => {\n    const average = student.qualifications.reduce((sum, score) => sum + score, 0) / student.qualifications.length;\n    return { name: student.name, average: average.toFixed(2) };\n});\nconsole.log(studentAverage);\n\nconst bestStudents = studentAverage.filter(student => student.average >= 9);\nconsole.log(bestStudents);\n\nconst datesOfBirthInOrder = students.sort((a, b) => b.birthdate - a.birthdate);\ndatesOfBirthInOrder.forEach(student => {\n    const date = student.birthdate;\n    console.log(`\\n${student.name}: ${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`);\n});\n\nconst allQualifications = students.flatMap(students => students.qualifications);\nconst highestScore = Math.max(...allQualifications);\n\nconsole.log(`\\nThe highest score is ${highestScore}`);"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/javascript/adrs1166ma.js",
    "content": "/* 🔥 EJERCICIO:\nExplora el concepto de funciones de orden superior en tu lenguaje \ncreando ejemplos simples (a tu elección) que muestren su funcionamiento.\n*/\n\n// Función de orden superior: map (transforma cada elemento de un array)\nconst numeros = [1, 2, 3, 4, 5]\nconst cuadrados = numeros.map(numero => numero * numero)\nconsole.log(\"Cuadrados:\", cuadrados) \n// Cuadrados: (5) [1, 4, 9, 16, 25]\n\n// Función de orden superior: filter (filtra elementos de un array)\nconst pares = numeros.filter(numero => numero % 2 === 0)\nconsole.log(\"Números pares:\", pares) \n// Números pares: (2) [2, 4]\n\n// Función de orden superior: reduce (reduce un array a un solo valor)\nconst suma = numeros.reduce((acumulador, numero) => acumulador + numero, 0)\nconsole.log(\"Suma total:\", suma) \n// Suma total: 15\n\n// Función de orden superior personalizada\nfunction operarNumeros(numeros, operacion) {\n    return numeros.map(operacion)\n}\nconst dobles = operarNumeros(numeros, numero => numero * 2)\nconsole.log(\"Dobles:\", dobles) \n// Dobles: (5) [2, 4, 6, 8, 10]\n\n/* 🔥 DIFICULTAD EXTRA (opcional): ------------------------------------------------------------------------------\nDada una lista de estudiantes (con sus nombres, fecha de nacimiento y \nlista de calificaciones), utiliza funciones de orden superior para \nrealizar las siguientes operaciones de procesamiento y análisis:\n- Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n  y promedio de sus calificaciones.\n- Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n  que tienen calificaciones con un 9 o más de promedio.\n- Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n- Mayor calificación: Obtiene la calificación más alta de entre todas las\n  de los alumnos.\n- Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n*/\n\nconst estudiantes = [\n    { nombre: \"Ana\", fechaNacimiento: \"2005-03-15\", calificaciones: [8.5, 9.0, 7.5] },\n    { nombre: \"Luis\", fechaNacimiento: \"2004-07-22\", calificaciones: [9.5, 8.0, 9.0] },\n    { nombre: \"Carlos\", fechaNacimiento: \"2006-01-10\", calificaciones: [7.0, 6.5, 8.0] },\n    { nombre: \"María\", fechaNacimiento: \"2003-11-30\", calificaciones: [10.0, 9.5, 9.0] }\n]\nconst promedios = estudiantes.map(estudiante => ({\n    nombre: estudiante.nombre,\n    promedio: estudiante.calificaciones.reduce((suma, nota) => suma + nota, 0) / estudiante.calificaciones.length\n}))\nconsole.log(\"Promedios:\", promedios)\n// Promedios: (4) [{…}, {…}, {…}, {…}]\n// 0 : {nombre: 'Ana', promedio: 8.333333333333334}\n// 1 : {nombre: 'Luis', promedio: 8.833333333333334}\n// 2 : {nombre: 'Carlos', promedio: 7.166666666666667}\n// 3 : {nombre: 'María', promedio: 9.5}\n// length : 4\n// [[Prototype]] : Array(0)\n\nconst mejoresEstudiantes = estudiantes\n    .map(estudiante => ({\n        nombre: estudiante.nombre,\n        promedio: estudiante.calificaciones.reduce((suma, nota) => suma + nota, 0) / estudiante.calificaciones.length\n    }))\n    .filter(estudiante => estudiante.promedio >= 9)\n    .map(estudiante => estudiante.nombre)\nconsole.log(\"Mejores estudiantes:\", mejoresEstudiantes)\n// ['María']\n\nconst ordenadosPorEdad = estudiantes.sort((a, b) => new Date(a.fechaNacimiento) - new Date(b.fechaNacimiento))\nconsole.log(\"Ordenados por edad:\", ordenadosPorEdad.map(e => e.nombre))\n// (4) ['María', 'Luis', 'Ana', 'Carlos']\n\nconst mayorCalificacion = Math.max(...estudiantes.flatMap(estudiante => estudiante.calificaciones))\nconsole.log(\"Mayor calificación:\", mayorCalificacion)\n// Mayor calificación: 10"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/javascript/agusrosero.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de funciones de orden superior en tu lenguaje\n * creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n */\nconst numbers = [1, 2, 3, 4, 5];\n\nconst double = (num) => num * 2;\n\nconst doubledNumbers = numbers.map(double);\n\nconsole.log(doubledNumbers);\n\n/* DIFICULTAD EXTRA (opcional):\n * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y\n * lista de calificaciones), utiliza funciones de orden superior para\n * realizar las siguientes operaciones de procesamiento y análisis:\n * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n *   y promedio de sus calificaciones.\n * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n *   que tienen calificaciones con un 9 o más de promedio.\n * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n * - Mayor calificación: Obtiene la calificación más alta de entre todas las\n *   de los alumnos.\n * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n */\nconst estudiantes = [\n  {\n    nombre: \"Hernan\",\n    fechaNacimiento: \"2000-03-08\",\n    notas: [7, 8, 9, 8, 7, 9, 8],\n  },\n  {\n    nombre: \"Agustin\",\n    fechaNacimiento: \"2000-08-03\",\n    notas: [7, 8, 9, 8, 7, 9, 8],\n  },\n  {\n    nombre: \"Juan\",\n    fechaNacimiento: \"1999-02-01\",\n    notas: [9, 9, 9, 9, 9, 9, 9],\n  },\n  {\n    nombre: \"María\",\n    fechaNacimiento: \"2001-01-15\",\n    notas: [9.5, 10, 8.5, 10],\n  },\n];\n\n// Promedio calificaciones\nconst calcularPromedio = (notas) => {\n  const suma = notas.reduce((acc, nota) => acc + nota, 0);\n  return suma / notas.length;\n};\n\nconst promedios = estudiantes.map((estudiante) =>\n  calcularPromedio(estudiante.notas)\n);\n\nconst promedioGeneral =\n  promedios.reduce((acc, promedio) => acc + promedio, 0) / promedios.length;\n\nconsole.log(promedioGeneral);\n\n// Filtrar estudiantes con promedio mayor o igual a 9\nconst mejoresEstudiantes = estudiantes\n  .filter((estudiante) => calcularPromedio(estudiante.notas) >= 9)\n  .map((estudiante) => estudiante.nombre);\n\nconsole.log(mejoresEstudiantes);\n\n// Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\nconst convertirFecha = (fecha) => new Date(fecha).getTime();\n\nconst estudiantesOrdenados = estudiantes.sort(\n  (a, b) =>\n    convertirFecha(b.fechaNacimiento) - convertirFecha(a.fechaNacimiento)\n);\n\nconsole.log(estudiantesOrdenados);\n\n// Mayor calificación: Obtiene la calificación más alta de entre todas las de los alumnos.\nconst todasLasNotas = estudiantes.flatMap((estudiante) => estudiante.notas);\n\nconst mayorCalificacion = todasLasNotas.reduce(\n  (max, nota) => Math.max(max, nota),\n  -Infinity\n);\n\nconsole.log(mayorCalificacion);\n\n// Una calificación debe estar comprendida entre 0 y 10 (admite decimales)\nconst lasNotas = estudiantes\n  .flatMap((estudiante) => estudiante.notas)\n  .filter((nota) => nota >= 0 && nota <= 10);\n\nconst calificacion = lasNotas.reduce(\n  (max, nota) => Math.max(max, nota),\n  -Infinity\n);\n\nconsole.log(calificacion);\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/javascript/bernatcs.js",
    "content": "// ** EJERCICIO\n\nfunction ordenSuperior(comprobar, funcion) {\n    if (comprobar){\n        funcion()\n    } else {\n        console.log('No hay nada que decir')\n    }\n}\n\nfunction decirHola(){\n    console.log('Hola')\n}\n\nordenSuperior('Sí que hay algo', decirHola)\n\n// ** DIFICULTAD EXTRA ** -------------------------------------------------------------------------------------------------------------------------------\n\n// const estudiantes = [\n//     { nombre: 'Estudiante1', fechaNacimiento: '2000-04-22', notas: [7, 8, 9, 8, 7, 9, 8] },\n//     { nombre: 'Estudiante2', fechaNacimiento: '1999-08-15', notas: [6, 7, 8, 7, 8, 9, 7] },\n//     { nombre: 'Estudiante3', fechaNacimiento: '2001-12-03', notas: [8, 9, 9, 8, 9, 8, 9] },\n//     { nombre: 'Estudiante4', fechaNacimiento: '2002-02-27', notas: [7, 8, 7, 8, 7, 8, 7] },\n//     { nombre: 'Estudiante5', fechaNacimiento: '2000-11-10', notas: [9, 8, 8, 9, 8, 8, 9] },\n//     { nombre: 'Estudiante6', fechaNacimiento: '1998-05-30', notas: [6, 7, 7, 6, 7, 7, 6] }\n// ];\n\n\n// // Promedio calificaciones: Obtiene una lista de estudiantes por nombre y promedio de sus calificaciones.\n// const obtenerPromedio = notas => notas.reduce((a, b) => a + b, 0) / notas.length;\n\n// const promedios = estudiantes.map(estudiante => ({\n//     nombre: estudiante.nombre,\n//     promedio: obtenerPromedio(estudiante.notas)\n// }));\n\n// console.log(\"Promedios:\", promedios);\n\n// // Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes que tienen calificaciones con un 9 o más de promedio.\n// const mejoresEstudiantes = promedios\n//     .filter(estudiante => estudiante.promedio >= 9)\n//     .map(estudiante => estudiante.nombre);\n\n// console.log(\"Mejores estudiantes:\", mejoresEstudiantes);\n\n// // Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n// const estudiantesOrdenadosPorNacimiento = estudiantes\n//     .slice()\n//     .sort((a, b) => new Date(b.fechaNacimiento) - new Date(a.fechaNacimiento));\n\n// console.log(\"Estudiantes ordenados por nacimiento (de más joven a más viejo):\", estudiantesOrdenadosPorNacimiento.map(est => est.nombre));\n\n// // Mayor calificación: Obtiene la calificación más alta de entre todas las de los alumnos.\n// const mayorCalificacion = Math.max(...estudiantes.flatMap(estudiante => estudiante.notas));\n\n// console.log(\"Mayor calificación:\", mayorCalificacion);"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/javascript/caterinarodriguezdev.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de funciones de orden superior en tu lenguaje \n * creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n *\n * DIFICULTAD EXTRA (opcional):\n * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n * lista de calificaciones), utiliza funciones de orden superior para\n * realizar las siguientes operaciones de procesamiento y análisis:\n * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n *   y promedio de sus calificaciones.\n * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n *   que tienen calificaciones con un 9 o más de promedio.\n * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n * - Mayor calificación: Obtiene la calificación más alta de entre todas las\n *   de los alumnos.\n * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n */\n\nconst devolverFuncion = () => {\n\n    const sum = (num1, num2) => num1 + num2; \n\n    return sum;\n}\n\nconst funcionDevuelta = devolverFuncion();\n\nconsole.log(funcionDevuelta(1, 1));\n\nconsole.log('----------DIFICULTAD EXTRA---------');\n\nlet estudiantes = [\n    {\n        nombre: 'Grace',\n        fechaNacimiento: '27/07/1999',\n        calificaciones: [10, 9, 8.5]\n    },\n    {\n        nombre: 'Cate',\n        fechaNacimiento: '12/08/1999',\n        calificaciones: [9, 6]\n    },\n    {\n        nombre: 'Valeria',\n        fechaNacimiento: '24/04/2007',\n        calificaciones: [9.9, 7]\n    },\n];\n\nconst getExpediente = (calcularPromedio, getMejoresEstudiantes, orderEstudiantesByBirth, getMayorNota) => {\n\n    console.log('Promedios: ',calcularPromedio());\n    console.log('Mejores estudiantes', getMejoresEstudiantes());\n    console.log('Nacimientos', orderEstudiantesByBirth());\n    console.log('Mayor nota', getMayorNota());\n}\n\nconst calcularPromedio = () => {\n    let promedios = {};\n\n    estudiantes.forEach(estudiante => {\n        let suma = 0;\n        estudiante.calificaciones.forEach(cal => suma += cal); \n        let promedio = suma / estudiante.calificaciones.length; \n\n        let nombre = estudiante.nombre;\n        promedios[nombre] = promedio;\n    });\n    \n    return promedios; \n}\n\nconst getMejoresEstudiantes = () => {\n    const promedios = calcularPromedio();\n    \n    const mejoresEstudiantes = Object.entries(promedios).filter(([nombre, promedio]) => promedio > 9);\n    const resultado = Object.fromEntries(mejoresEstudiantes);\n    \n    return resultado;\n}\n\nconst orderEstudiantesByBirth = () => {\n\n    return estudiantes.sort((a, b) => new Date(a.fechaNacimiento) - new Date(b.fechaNacimiento));\n}\n\nconst getMayorNota = () => {\n\n    return Math.max(...estudiantes.flatMap(estudiante => estudiante.calificaciones))\n}\n\ngetExpediente(calcularPromedio, getMejoresEstudiantes, orderEstudiantesByBirth, getMayorNota);"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/javascript/christian-jfr.js",
    "content": "// #22 FUNCIONES DE ORDEN SUPERIOR\n/**\n * EJERCICIO:\n * Explora el concepto de funciones de orden superior en tu lenguaje\n * creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n */\n// Callbacks\nconst numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n\nfunction arrayFilter(arr, callback) {\n\tconst filteredArr = [];\n\tfor (let i = 0; i < arr.length; i++) {\n\t\tcallback(arr[i]) ? filteredArr.push(arr[i]) : null;\n\t}\n\treturn filteredArr;\n}\n\nfunction isOdd(x) {\n\treturn x % 2 != 0;\n}\n\nfunction isEven(x) {\n\treturn x % 2 === 0;\n}\n\nconsole.log(arrayFilter(numbers, isOdd)); // -> [1, 3, 5, 7, 9]\nconsole.log(arrayFilter(numbers, isEven)); // -> [2, 4, 6, 8, 10]\n\n// Usando el filter que viene en javascript\n\nconsole.log(numbers.filter(isOdd)); // -> [1, 3, 5, 7, 9]\nconsole.log(numbers.filter(isEven)); // -> [2, 4, 6, 8, 10]\n\n// return una funcion\n\nfunction calculate(operator) {\n\tswitch (operator) {\n\t\tcase '*':\n\t\t\treturn function (a, b) {\n\t\t\t\tconsole.log(`${a * b}`);\n\t\t\t};\n\t\tcase '/':\n\t\t\treturn function (a, b) {\n\t\t\t\tconsole.log(`${a / b}`);\n\t\t\t};\n\t}\n}\n\ncalculate('*')(8, 4); // -> 32\ncalculate('/')(8, 4); // -> 2\n\n/**\n * DIFICULTAD EXTRA (opcional):\n * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y\n * lista de calificaciones), utiliza funciones de orden superior para\n * realizar las siguientes operaciones de procesamiento y análisis:\n * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n *   y promedio de sus calificaciones.\n * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n *   que tienen calificaciones con un 9 o más de promedio.\n * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n * - Mayor calificación: Obtiene la calificación más alta de entre todas las\n *   de los alumnos.\n * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n */\n\nconst students = [\n\t{ name: 'Christian', birthdate: '26-09-1987', grades: [7.2, 8.5, 8.8] },\n\t{ name: 'Nai', birthdate: '21-07-1985', grades: [9, 9.8, 10] },\n\t{ name: 'Johan', birthdate: '05-03-1986', grades: [9.2, 9.6, 10] },\n\t{ name: 'Nicholas', birthdate: '30-08-1988', grades: [5, 6, 8] },\n\t{ name: 'Dominique', birthdate: '12-04-1985', grades: [6.5, 7.2, 9] },\n];\n\n// Promedio calificaciones\nfunction getAverage(studentGrades) {\n\tlet sum = studentGrades.reduce(\n\t\t(accumulator, currentGrade) => accumulator + currentGrade,\n\t\t0\n\t);\n\tlet average = parseFloat((sum / studentGrades.length).toFixed(1));\n\treturn average;\n}\n\nconst getStudentsAverage = students.map((student) => {\n\treturn { name: student.name, average: getAverage(student.grades) };\n});\n\n// Mejores estudiantes\nfunction isTopStudent(average) {\n\treturn average >= 9;\n}\n\nconst getTopStudents = getStudentsAverage.filter((student) => {\n\treturn isTopStudent(student.average);\n});\n\n// Nacimiento\nfunction parseDate(dateString) {\n\tconst [day, month, year] = dateString.split('-');\n\treturn new Date(year, month - 1, day);\n}\n\nconst sortedStudents = students.sort((a, b) => {\n\tconst dateA = parseDate(a.birthdate);\n\tconst dateB = parseDate(b.birthdate);\n\treturn dateB - dateA;\n});\n\n// Mayor calificación\nconst allGrades = students.flatMap((student) => student.grades);\n\nconst highestGrade = allGrades.reduce(\n\t(max, grade) => (grade > max ? grade : max),\n\t-Infinity\n);\n\n// Resultados\nconsole.log(getStudentsAverage); // Muestra una lista con el nombre y promedio de calificaciones\nconsole.log(getTopStudents); // Muestra los estudiantes que tuvieron una calificación de 9 o superior\nconsole.log(sortedStudents); // Muestra la lista de estudiantes ordenados de menor a mayor edad\nconsole.log(highestGrade); // Muestra la mayor calificación\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/javascript/duendeintemporal.js",
    "content": "//#22 - FUNCIONES DE ORDER SUPERIOR \n/* \n * EJERCICIO:\n * Explora el concepto de funciones de orden superior en tu lenguaje \n * creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n *\n * DIFICULTAD EXTRA (opcional):\n * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n * lista de calificaciones), utiliza funciones de orden superior para\n * realizar las siguientes operaciones de procesamiento y análisis:\n * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n *   y promedio de sus calificaciones.\n * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n *   que tienen calificaciones con un 9 o más de promedio.\n * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n * - Mayor calificación: Obtiene la calificación más alta de entre todas las\n *   de los alumnos.\n * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales). \n * */\n\n//Reference Bibliografy:\n//Eloquent Javascript A Modern Introduction to Programming by Marijn Haverbeke (z-lib.org)\n//GPT\n\n\nwindow.addEventListener('load', ()=>{\n    const body = document.querySelector('body');\n    const title = document.createElement('h1');\n    \n    body.style.setProperty('background', '#000');\n    body.style.setProperty('text-align', 'center');\n    \n    title.textContent = 'Retosparaprogramadores #22.';\n    title.style.setProperty('font-size', '3.5vmax');\n    title.style.setProperty('color', '#fff');\n    title.style.setProperty('line-height', '100vh');\n    \n    body.appendChild(title);\n    \n    setTimeout(()=>{\n    alert('Retosparaprogramadores #22. Please open the Browser Developer Tools.');\n    }, 2000);\n    log( 'Retosparaprogramadores #22'); \n});\n\n\n\n/* Functions that operate on other functions, either by taking them as arguments\nor by returning them, are called higher-order functions. \nThe term comes from mathematics, where the distinction between functions and other values is taken more seriously.\nHigher-order functions allow us to abstract over actions, not just values. */\n\n\nlet log = console.log;\n\n//For example, we can have functions that create new functions.\n\nconst powder = (n) => {\n    return (m) => {\n        if (n === 0) return 1; \n        return m * powder(n - 1)(m);\n    };\n}; \n\nlet powder2 = powder(2);\nlog(powder2(10)) // 100\n\n//And we can have functions that change other functions.\n\nconst applyToArray = (func)=>{\n    return (...arr)=>  func(...arr);\n}\n\nconst totalAmount = (...arg)=>{\n    return arg.reduce((total, n)=> total + n, 0);\n}\n\nlet sales = [123, 45, 67, 865, 76, 54, 3254, 23];\n\nlog(applyToArray(totalAmount)(...sales)); // 4507\n\n//We can even write functions that provide new types of control flow.\n\nfunction unless(test, then) {\n    if (!test) then();\n}\n\nconst isOddNum = (n)=> n % 2 !== 0; \n\nconst addOddNums = (n)=> {\n    let total = 0;\n    do{\n        unless(!isOddNum(n), ()=> total += n);\n        n--;\n    }while(n > 0)  \n    return total;\n}\n\nlog(addOddNums(100)); // 2500\n\n//There are some built-in array methods, forEach, map, reduce, some... that provide something like a for/of loop as a higher-order function.\n\n//EXTRA DIFICULTY EXERCISE\n\n// Student class definition\nclass Student {\n    constructor(name, birthday, calification) {\n        this.name = name;\n        this.birthday = new Date(birthday); \n        this.calification = calification; \n    }\n\n    getName() {\n        return this.name; \n    }\n\n    getBirthday() {\n        return this.birthday; \n    }\n\n    getCalification() {\n        return this.calification;\n    }\n\n    setName(name) {\n        this.name = name; \n    }\n\n    setBirthday(birthday) {\n        this.birthday = new Date(birthday);\n    }\n\n    setCalification(calification) {\n        this.calification = calification; \n    }\n}\n\n// List of students\nlet students = [\n    new Student('Juan Rulfo', '1986-06-07', 7),\n    new Student('Moure Dev', '1982-03-08', 8.5),\n    new Student('Calvin Maker', '2000-04-02', 9.8),\n    new Student('Adela Jimenez', '1976-01-09', 7.9),\n    new Student('Crist Renegate', '2001-07-09', 5),\n    new Student('Gautama Buda', '0623-05-23', 9),\n    new Student('Niko Zen', '1983-08-08', 10)\n];\n\n// Function to get a list of students with their average grades\nconst studentsAverageList = (arr) => {\n    return arr.map(student => ({\n        name: student.getName(), \n        average: student.getCalification() \n    })).sort((a, b) => b.average - a.average);\n};\n\n// Function to get a list of students with grades of 9 or higher\nconst higherThan9Students = (arr) => {\n    return arr.filter(student => student.getCalification() >= 9) \n              .map(student => student.getName()); \n};\n\n// Function to sort students by their birth date\nconst sortStudentsByBirthday = (arr) => {\n    return arr.slice().sort((a, b) => a.getBirthday() - b.getBirthday()) \n              .map(student => student.getName()); \n};\n\n// Function to find the highest grade among all students\nconst highestCalification = (arr) => {\n    return Math.max(...arr.map(student => student.getCalification())); \n};\n\n// Execute the functions and store the results\nlet averageList = studentsAverageList(students); \nlet bestStudents = higherThan9Students(students);\nlet sortedStudents = sortStudentsByBirthday(students); \nlet highestGrade = highestCalification(students); \n\n// Display the results in the console\nlog(\"Average grades:\", averageList); /*\nAverage grades:\nArray(7) [ {…}, {…}, {…}, {…}, {…}, {…}, {…} ]\n0: Object { name: \"Niko Zen\", average: 10 }\n1: Object { name: \"Calvin Maker\", average: 9.8 }\n2: Object { name: \"Gautama Buda\", average: 9 }\n3: Object { name: \"Moure Dev\", average: 8.5 }\n4: Object { name: \"Adela Jimenez\", average: 7.9 }\n5: Object { name: \"Juan Rulfo\", average: 7 }\n6: Object { name: \"Crist Renegate\", average: 5 }\n */\nlog(\"Best students (9 or higher):\", bestStudents); // Best students (9 or higher): ['Calvin Maker', 'Gautama Buda', 'Niko Zen']\nlog(\"Students sorted by birth date:\", sortedStudents); // Students sorted by birth date: (7) ['Gautama Buda', 'Adela Jimenez', 'Moure Dev', 'Niko Zen', 'Juan Rulfo', 'Calvin Maker', 'Crist Renegate']\nlog(\"Highest grade:\", highestGrade); // Highest grade: 10\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/javascript/edalmava.js",
    "content": "const array = [1, 2, 3, 4, 5, 6, 7, 8, 9]\n// El método forEach() ejecuta la función indicada una vez por cada elemento del array.\narray.forEach(e => console.log(e))\n\n// El método map() crea un nuevo array con los resultados de la llamada a la función indicada aplicados a cada uno de sus elementos.\nconst dobles = array.map(e => e * 2)\nconsole.log(dobles) // Devuelve un array con los dobles de cada elemento\n\n// El método filter() crea un nuevo array con todos los elementos que cumplan la condición implementada por la función dada.\nconst pares = array.filter(e => e % 2 == 0)\nconsole.log(pares) // Devuelve un array con los números pares\n\n// El método reduce() ejecuta una función reductora sobre cada elemento de un array, devolviendo como resultado un único valor.\nconst suma = array.reduce((acc, e) => acc + e, 0)\nconsole.log(suma)  // Suma los elementos del array\n\n// El método some() comprueba si al menos un elemento del array cumple con la condición implementada por la función proporcionada.\nconst cero = array.some(e => e == 0)\nconsole.log(cero)  // Verifica si por lo menos uno de los elementos es cero\n\n// El método sort() ordena los elementos de un arreglo (array) localmente y devuelve el arreglo ordenado.\nconst array2 = [5, 4, 8, 7, 0]\narray2.sort((a, b) => a - b) // Ordenar de forma ascendente\nconsole.log(array2)\n\narray2.sort((a, b) => b - a) // Ordenar de forma descendente\nconsole.log(array2)\n\n// El método findIndex() devuelve el índice del primer elemento de un array que cumpla con la función de prueba proporcionada. \nconsole.log(array.findIndex(e => e % 2 == 0))\n\n// DIFICULTAD EXTRA\n\nconst estudiantes = [{ nombres: \"Juan Perez\", \n                      fecha_nacimiento: \"01/01/2010\", \n                      calificaciones: [4.0, 6.0, 10.0] }, \n                     { nombres: \"Simon Becerra\", \n                      fecha_nacimiento: \"02/05/2011\", \n                      calificaciones: [10.0, 9.0, 8.0] }, \n                     { nombres: \"Angel Martinez\", \n                      fecha_nacimiento: \"03/04/2010\", \n                      calificaciones: [10.0, 2.0, 6.0] }, \n                     { nombres: \"Jorge Vanegas\", \n                      fecha_nacimiento: \"08/09/2011\", \n                      calificaciones: [7.0, 9.0, 10.0] }, \n                     { nombres: \"Alberto Maldonado\", \n                      fecha_nacimiento: \"03/04/2011\", \n                      calificaciones: [10, 10, 10] }\n                    ]\n\n// Promedio de calificaciones\n\nconst listadoPromedio = estudiantes.map(e => \n    ({ nombres: e.nombres, \n      promedio: e.calificaciones.reduce((a, e) => a + e, 0)/e.calificaciones.length  \n    }))\nconsole.log(listadoPromedio)\n\n// Mejores estudiantes - promedio superior o igual a 9\nconst mejoresEstudiantes = listadoPromedio.filter(e => e.promedio >= 9)\nconsole.log(mejoresEstudiantes)\n\n// Mayor calificación\nconst mayorCalificacion = listadoPromedio.sort((a, b) => b.promedio - a.promedio)\nconsole.log(mayorCalificacion[0].promedio)\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/javascript/eugeniasoria.js",
    "content": "/*\r\n# #22 FUNCIONES DE ORDEN SUPERIOR\r\n * EJERCICIO:\r\n * Explora el concepto de funciones de orden superior en tu lenguaje \r\n * creando ejemplos simples (a tu elección) que muestren su funcionamiento.\r\n */\r\n\r\nconsole.log(\"Función de orden superior que pase una función como argumento\");\r\n//En este caso la función de Orden superior funciona como un filtro y se pasa como argumento \r\n//una función con el filtro que se quiere aplicar\r\nfunction vocalesMinuscula(letra) {\r\n  return (letra == 'a' || letra == 'e' || letra == 'i' || letra == 'o' || letra == 'u') ? true : false;\r\n}\r\n\r\nfunction vocalesMayuscula(letra) {\r\n  return (letra == 'A' || letra == 'E' || letra == 'I' || letra == 'O' || letra == 'U') ? true : false;\r\n}\r\nfunction numero(num) {\r\n  return (num == '0' || num == '1' || num == '2' || num == '3' || num == '4' || num == '5' || \r\n    num == '6' || num == '7' || num == '8' || num == '9' || num == '0') ? true : false;\r\n}\r\n\r\nfunction funcionOrdenSuperiorCadenas(cadena, funcOrdenInferior) {\r\n  let resultado = '';\r\n  for (i=0; i<cadena.length; i++) {\r\n    if (funcOrdenInferior(cadena[i]))\r\n      resultado += cadena[i]\r\n  }\r\n  return resultado\r\n}\r\n\r\nconst cadena1 = 'murcielago';\r\nconst vocalesMinusculasResultado = funcionOrdenSuperiorCadenas(cadena1, vocalesMinuscula); \r\nconsole.log(`Cadena original <${cadena1}> filtrando vocales minúsculas <${vocalesMinusculasResultado}>`);\r\n\r\nconst cadena2 = 'Ernesto come Ananá en su casa en Roma junto a Oscar';\r\nconst vocalesMayusculasResultado = funcionOrdenSuperiorCadenas(cadena2, vocalesMayuscula); \r\nconsole.log(`Cadena original <${cadena2}> filtrando vocales Mayúsculas <${vocalesMayusculasResultado}>`);\r\n\r\nconst cadena3 = 'C3PO y R2D2'\r\nconst numerosResultado = funcionOrdenSuperiorCadenas(cadena3, numero); \r\nconsole.log(`Cadena original <${cadena3}> filtrando vocales Mayúsculas <${numerosResultado}>`);\r\n\r\nconsole.log(\"\\n\\nFunción de orden superior que retorna una función\");\r\n\r\nfunction funcionOrdenSuperiorSaludo(idioma) {\r\n  \r\n  switch (idioma) {\r\n    case 'francais':\r\n      return function (nombre) {\r\n        return `Bonjour ${nombre}`\r\n      };\r\n      break;\r\n    case 'english':\r\n      return function (nombre) {\r\n        return `Hello ${nombre}`\r\n      };\r\n      break;\r\n        \r\n    default:\r\n      return function (nombre) {\r\n        return `Hola ${nombre}`\r\n      };      \r\n      break;\r\n  }\r\n  \r\n}\r\n\r\n//Usando las funciones retornadas por la funcion de orden superior\r\nconst saludarFrances = funcionOrdenSuperiorSaludo('francais');\r\nconsole.log(saludarFrances);\r\nconsole.log(saludarFrances('Pierre'));\r\nconsole.log(funcionOrdenSuperiorSaludo('francais')('Juliette'));\r\n\r\nconst saludarIngles = funcionOrdenSuperiorSaludo('english');\r\nconsole.log(saludarIngles);\r\nconsole.log(saludarIngles('Peter'));\r\nconsole.log(funcionOrdenSuperiorSaludo('english')('Melanie'));\r\n\r\nconst saludarDefault = funcionOrdenSuperiorSaludo('nose');\r\nconsole.log(saludarDefault);\r\nconsole.log(saludarDefault('Pedro'));\r\nconsole.log(funcionOrdenSuperiorSaludo('español')('Lucia'));\r\n\r\n\r\n/*\r\n* DIFICULTAD EXTRA (opcional):\r\n* Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \r\n* lista de calificaciones), utiliza funciones de orden superior para \r\n* realizar las siguientes operaciones de procesamiento y análisis:\r\n* - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\r\n*   y promedio de sus calificaciones.\r\n* - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\r\n*   que tienen calificaciones con un 9 o más de promedio.\r\n* - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\r\n* - Mayor calificación: Obtiene la calificación más alta de entre todas las\r\n*   de los alumnos.\r\n* - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\r\n*/\r\n\r\nconst listaEstudiantes = [\r\n  {\r\n    nombre: 'Rafaella Carra',\r\n    fechaNacimiento: '05/05/1976',\r\n    calificaciones: {\r\n      matematica: 2,\r\n      lengua: 10,\r\n      programación: 8.5\r\n    }\r\n  },\r\n  {\r\n    nombre: 'Esteban Quito',\r\n    fechaNacimiento: '04/08/1999',\r\n    calificaciones: {\r\n      matematica: 5,\r\n      lengua: 10,\r\n      programación: 1\r\n    }\r\n  },\r\n  {\r\n    nombre: 'Guillermo Puertas',\r\n    fechaNacimiento: '01/01/2000',\r\n    calificaciones: {\r\n      matematica: 10,\r\n      lengua: 10,\r\n      programación: 1\r\n    }\r\n  },    \r\n  {\r\n    nombre: 'Jorgito Alfajor',\r\n    fechaNacimiento: '15/05/2015',\r\n    calificaciones: {\r\n      matematica: 8,\r\n      lengua: 8,\r\n      programación: 8\r\n    }\r\n  },\r\n  {\r\n    nombre: 'Susana Dieta',\r\n    fechaNacimiento: '13/09/2017',\r\n    calificaciones: {\r\n      matematica: 3,\r\n      lengua: 2,\r\n      programación: 1\r\n    }\r\n  },\r\n  {\r\n    nombre: 'Lana Oveja',\r\n    fechaNacimiento: '28/02/1999',\r\n    calificaciones: {\r\n      matematica: 10,\r\n      lengua: 10,\r\n      programación: 10\r\n    }\r\n  },   \r\n];\r\nconsole.log('\\n\\nDIFICULTAD EXTRA');\r\nconsole.log('Lista de estudiantes', listaEstudiantes);\r\n\r\nfunction calcularPromedio(arrayNumeros) {  \r\n  return arrayNumeros.reduce((acum, elem) => acum += elem, 0)/arrayNumeros.length;\r\n}\r\n\r\nfunction calcularPromedioEstudiantes(estudiantes, funcionPromedio) {  \r\n  let resultado = [];\r\n  estudiantes.forEach(element => {        \r\n    resultado.push({ nombre: element.nombre, promedio: funcionPromedio(Object.values(element.calificaciones)) })\r\n  });\r\n  return resultado;\r\n}\r\nconsole.log('\\nPromedio por estudiante');\r\nlet promedios = calcularPromedioEstudiantes(listaEstudiantes, calcularPromedio);\r\nconsole.log(promedios);\r\n\r\nfunction mejoresEstudiantes (estudiantes, funcionPromedio, notaRequerida) {\r\n  let promedioPorEstudiante = calcularPromedioEstudiantes(estudiantes, funcionPromedio);  \r\n  let resultado = promedioPorEstudiante.filter((x) => (x.promedio > notaRequerida));\r\n  console.log(resultado);  \r\n}\r\nconsole.log('\\nMejores alumnos (promedio mayor a 9)');\r\nmejoresEstudiantes(listaEstudiantes, calcularPromedio, 9);\r\n\r\nfunction ordenarfechasNacimientoAlumnos(fechasNacimientoAlumnos) {\r\n\r\n  let resultado = [];\r\n  fechasNacimientoAlumnos.forEach(element => {    \r\n    const elemSplit = element.fechaNacimiento.split('/')\r\n    resultado.push(\r\n      {\r\n        nombre: element.nombre,\r\n        fechaOriginal: element.fechaNacimiento,\r\n        fechaConFormato: new Date(elemSplit[2], elemSplit[1]-1, elemSplit[0])\r\n      });    \r\n  });\r\n\r\n  resultado.sort((a, b) => (a.fechaConFormato - b.fechaConFormato));\r\n  \r\n  resultado.forEach(element => {\r\n    delete element.fechaConFormato\r\n  });\r\n\r\n  return resultado;  \r\n}\r\n\r\n\r\nfunction ordenarEstudiantesPorNacimiento(estudiantes, funcionOrdenarFecha) {\r\n  let fechas = [];\r\n  estudiantes.forEach(element => {          \r\n    fechas.push({ nombre: element.nombre, fechaNacimiento: element.fechaNacimiento }) });\r\n  let resultado = funcionOrdenarFecha(fechas);\r\n  console.log(resultado);\r\n}\r\nconsole.log('\\nAlumnos ordenados por fecha de nacimiento');\r\nordenarEstudiantesPorNacimiento(listaEstudiantes, ordenarfechasNacimientoAlumnos);\r\n\r\nfunction obtenerCalificacionMasAlta(calificacionesAlumnos) {\r\n  //Espera un array de objectos alumno/materia/calificacion  \r\n  let todasLasNotas = [];\r\n  calificacionesAlumnos.forEach(element => {\r\n    todasLasNotas.push(element.nota);\r\n  }); \r\n  let notaMaxima = Math.max(...todasLasNotas);\r\n\r\n  return calificacionesAlumnos.filter((x) => (x.nota === notaMaxima))  \r\n}\r\n\r\nfunction calificacionMasAlta(estudiantes, funcionMaxCalificacion) {\r\n  let estudianteNotas = []\r\n  estudiantes.forEach(estudiante => {\r\n    \r\n    Object.keys(estudiante.calificaciones).forEach(element => {\r\n      let item = {\r\n        nombre: estudiante.nombre,\r\n        materia: element,\r\n        nota: estudiante.calificaciones[element]\r\n      } \r\n      estudianteNotas.push(item)\r\n    });            \r\n  });\r\n\r\n  console.log(funcionMaxCalificacion(estudianteNotas));\r\n}\r\nconsole.log('\\nAlumnos con la calificación más alta');\r\ncalificacionMasAlta(listaEstudiantes, obtenerCalificacionMasAlta)\r\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/javascript/eulogioep.js",
    "content": "// Clase Estudiante para manejar la información de cada alumno\nclass Estudiante {\n  constructor(nombre, fechaNacimiento, calificaciones) {\n    this.nombre = nombre;\n    this.fechaNacimiento = new Date(fechaNacimiento);\n    // Validamos que las calificaciones estén entre 0 y 10\n    this.calificaciones = calificaciones.filter(\n      (calif) => calif >= 0 && calif <= 10\n    );\n  }\n}\n\n// Creamos una lista de estudiantes de ejemplo\nconst estudiantes = [\n  new Estudiante(\"Ana García\", \"2000-05-15\", [9.5, 8.7, 9.2, 9.8]),\n  new Estudiante(\"Carlos Pérez\", \"1999-03-20\", [7.5, 8.0, 6.5, 7.8]),\n  new Estudiante(\"María López\", \"2001-08-10\", [9.0, 9.5, 9.3, 9.7]),\n];\n\n// Funciones auxiliares\nconst calcularPromedio = (calificaciones) => {\n  return (\n    calificaciones.reduce((acc, curr) => acc + curr, 0) / calificaciones.length\n  );\n};\n\n// 1. Obtener lista de estudiantes con sus promedios\nconst obtenerPromedios = (estudiantes) => {\n  return estudiantes.map((estudiante) => ({\n    nombre: estudiante.nombre,\n    promedio: calcularPromedio(estudiante.calificaciones),\n  }));\n};\n\n// 2. Obtener mejores estudiantes (promedio >= 9)\nconst obtenerMejoresEstudiantes = (estudiantes) => {\n  return estudiantes\n    .filter((estudiante) => calcularPromedio(estudiante.calificaciones) >= 9)\n    .map((estudiante) => estudiante.nombre);\n};\n\n// 3. Obtener lista ordenada por fecha de nacimiento (más joven primero)\nconst ordenarPorEdad = (estudiantes) => {\n  return [...estudiantes]\n    .sort((a, b) => b.fechaNacimiento - a.fechaNacimiento)\n    .map((estudiante) => ({\n      nombre: estudiante.nombre,\n      fechaNacimiento: estudiante.fechaNacimiento.toISOString().split(\"T\")[0],\n    }));\n};\n\n// 4. Obtener la calificación más alta de todos los estudiantes\nconst obtenerMayorCalificacion = (estudiantes) => {\n  return Math.max(\n    ...estudiantes.flatMap((estudiante) => estudiante.calificaciones)\n  );\n};\n\n// Mostrar resultados\nconsole.log(\"1. Promedios de calificaciones:\");\nconsole.log(obtenerPromedios(estudiantes));\n\nconsole.log(\"\\n2. Mejores estudiantes (promedio >= 9):\");\nconsole.log(obtenerMejoresEstudiantes(estudiantes));\n\nconsole.log(\"\\n3. Estudiantes ordenados por edad (más joven primero):\");\nconsole.log(ordenarPorEdad(estudiantes));\n\nconsole.log(\"\\n4. Mayor calificación de todos los estudiantes:\");\nconsole.log(obtenerMayorCalificacion(estudiantes));\n\n// Ejemplos adicionales de funciones de orden superior en JavaScript\nconsole.log(\"\\nEjemplos adicionales de funciones de orden superior:\");\n\n// Ejemplo 1: función que retorna otra función (closure)\nconst multiplicadorPor = (factor) => (numero) => numero * factor;\nconst multiplicarPor2 = multiplicadorPor(2);\nconsole.log(\"Multiplicar 4 por 2:\", multiplicarPor2(4)); // Output: 8\n\n// Ejemplo 2: función que recibe otra función como parámetro\nconst aplicarOperacion = (numeros, operacion) => numeros.map(operacion);\nconst duplicar = (numero) => numero * 2;\nconsole.log(\"Duplicar números [1,2,3]:\", aplicarOperacion([1, 2, 3], duplicar)); // Output: [2,4,6]\n\n// Ejemplo 3: composición de funciones\nconst componerFunciones = (f, g) => (x) => f(g(x));\nconst sumar1 = (x) => x + 1;\nconst duplicarYSumar1 = componerFunciones(sumar1, duplicar);\nconsole.log(\"Duplicar 5 y sumar 1:\", duplicarYSumar1(5)); // Output: 11\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/javascript/hectorio23.js",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\n/*\n * EJERCICIO:\n * Explora el concepto de funciones de orden superior en tu lenguaje \n * creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n *\n * DIFICULTAD EXTRA (opcional):\n * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n * lista de calificaciones), utiliza funciones de orden superior para \n * realizar las siguientes operaciones de procesamiento y análisis:\n * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n *   y promedio de sus calificaciones.\n * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n *   que tienen calificaciones con un 9 o más de promedio.\n * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n * - Mayor calificación: Obtiene la calificación más alta de entre todas las\n *   de los alumnos.\n * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n*/\n\n// Definimos una clase para representar a un estudiante\nclass Student {\n    constructor(name, birthdate, grades) {\n        this.name = name;\n        this.birthdate = birthdate;\n        this.grades = grades;\n    }\n}\n\n// Función para calcular el promedio de una lista de calificaciones\nfunction average(grades) {\n    if (grades.length === 0) return 0.0;\n    const sum = grades.reduce((acc, grade) => acc + grade, 0);\n    return sum / grades.length;\n}\n\n// Lista de estudiantes\nconst students = [\n    new Student(\"Adán\", \"2004-06-28\", [9.7, 10.0, 9.9]),\n    new Student(\"Andy\", \"2006-07-17\", [9.5, 9.0, 9.0]),\n    new Student(\"Mauricer\", \"2004-03-15\", [6.0, 7.5, 8.0]),\n    new Student(\"David\", \"2005-06-30\", [10.0, 9.5, 9.5])\n];\n\n// Promedio de calificaciones\nconsole.log(\"Promedio de calificaciones:\");\nstudents.forEach(student => {\n    const avg = average(student.grades);\n    console.log(`${student.name}: ${avg.toFixed(2)}`);\n});\n\n// Mejores estudiantes\nconsole.log(\"\\nMejores estudiantes (promedio >= 9):\");\nstudents.forEach(student => {\n    if (average(student.grades) >= 9.0) {\n        console.log(student.name);\n    }\n});\n\n// Ordenar estudiantes por fecha de nacimiento, de más joven a más viejo\nconst studentsSortedByAge = students.sort((a, b) => new Date(b.birthdate) - new Date(a.birthdate));\n\nconsole.log(\"\\nEstudiantes ordenados por nacimiento (de más joven a más viejo):\");\nstudentsSortedByAge.forEach(student => {\n    console.log(`${student.name}: ${student.birthdate}`);\n});\n\n// Mayor calificación entre todos los estudiantes\nconst allGrades = students.flatMap(student => student.grades);\nconst highestGrade = Math.max(...allGrades);\n\nconsole.log(`\\nMayor calificación entre todos los estudiantes: ${highestGrade}`);\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n_______________________________________\n#22 FUNCIONES DE ORDEN SUPERIOR\n---------------------------------------\n * EJERCICIO:\n * Explora el concepto de funciones de orden superior en tu lenguaje\n * creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n *\n * DIFICULTAD EXTRA (opcional):\n * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y\n * lista de calificaciones), utiliza funciones de orden superior para\n * realizar las siguientes operaciones de procesamiento y análisis:\n * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n *   y promedio de sus calificaciones.\n * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n *   que tienen calificaciones con un 9 o más de promedio.\n * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n * - Mayor calificación: Obtiene la calificación más alta de entre todas las\n *   de los alumnos.\n * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n*/\n// ________________________________________________________\nfunction arithmeticOp(func) {\n    return function (x, y) {\n        return func(x, y);\n    };\n}\n\nfunction add(x, y) {\n    return x + y;\n}\n\nfunction subtract(x, y) {\n    return x - y;\n}\n\nfunction multiply(x, y) {\n    return x * y;\n}\n\nconst addition = arithmeticOp(add);\nconst subtraction = arithmeticOp(subtract);\nconst multiplication = arithmeticOp(multiply);\n\nconst rAddition = addition(2, 3);\nconst rSubtraction = subtraction(10, 5);\nconst rMultiplication = multiplication(2, 5);\n\nconsole.log(`\\n` +\n    `Resultado de la suma:    ${rAddition} \\n` +\n    `Resultado de la resta:   ${rSubtraction} \\n` +\n    `Resultado de la multip.: ${rMultiplication}`);\n\n// ________________________________________________________\nconsole.log(\"\\n----\\nDIFICULTAD EXTRA\\n\");\n\nconst studentsList = [\n    { name: \"Ken\", dob: \"2012-04-21\", grades: [9.5, 9.4, 9.3, 9.2] },\n    { name: \"Ben\", dob: \"2012-03-20\", grades: [8.5, 8.4, 8.3, 8.2] },\n    { name: \"Ada\", dob: \"2012-02-19\", grades: [7.5, 7.4, 7.3, 7.2] },\n    { name: \"Zoe\", dob: \"2012-01-18\", grades: [9.0, 9.1, 9.0, 9.1] },\n];\n\n// Función de orden superior\nfunction higherOrderFun(msg, printFn) {\n    return function (students) {\n        console.log(`\\n----\\n${msg}`);\n        students.forEach((student) => printFn(student));\n    };\n}\n\nfunction printGPA(student) {\n    const grades = student.grades;\n    const averageGrade = grades.reduce((sum, grade) => sum + grade, 0) / grades.length;\n    console.log(`${student.name}: ${averageGrade.toFixed(2)}`);\n}\n\nfunction printTop(student) {\n    const grades = student.grades;\n    const average = grades.reduce((sum, grade) => sum + grade, 0) / grades.length;\n    if (average >= 9) console.log(student.name);\n}\n\nfunction printBirth(student) {\n    console.log(`${student.name}: ${student.dob}`);\n}\n\nfunction printHighestGrade(student) {\n    const maxGrade = Math.max(...student.grades);\n    console.log(`${student.name}: ${maxGrade}`);\n}\n\nconst gradePointAverage = higherOrderFun(\"Promedio de calificaciones:\", printGPA);\nconst topStudents = higherOrderFun(\"Mejores estudiantes:\", printTop);\nconst birthOrder = higherOrderFun(\"Orden de nacimiento:\", printBirth);\nconst highestGrade = higherOrderFun(\"Mayor calificación:\", printHighestGrade);\n\ngradePointAverage(studentsList);\ntopStudents(studentsList);\nbirthOrder(\n    [...studentsList].sort((a, b) => new Date(a.dob) - new Date(b.dob))\n);\n\nhighestGrade(studentsList);\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/javascript/nlarrea.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de funciones de orden superior en tu lenguaje \n * creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n *\n * DIFICULTAD EXTRA (opcional):\n * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n * lista de calificaciones), utiliza funciones de orden superior para \n * realizar las siguientes operaciones de procesamiento y análisis:\n * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n *   y promedio de sus calificaciones.\n * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n *   que tienen calificaciones con un 9 o más de promedio.\n * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n * - Mayor calificación: Obtiene la calificación más alta de entre todas las\n *   de los alumnos.\n * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n */\n\n// Funciones de orden superior -> funciones que toman una función como argumento\n// o que devuelven una función como resultado\n\n// map\n\n\nfunction cube(x) {\n    return x**3;\n}\n\n\nlet numbers = [1, 2, 3, 4, 5];\nconst cubeNumbers = numbers.map(number => cube(number));\nconsole.log(cubeNumbers);  // [1, 8, 27, 64, 125]\n\n\n// filter\n\n\nfunction even(x) {\n    return x % 2 == 0;\n}\n\n\nconst evenNumbers = numbers.filter(number => even(number));\nconsole.log(evenNumbers);  // [2, 4]\n\n\n// sorted\n\nnumbers = [1, 4, 2, 6, 9];\nconsole.log(numbers.slice().sort());  // [1, 2, 4, 6, 9]\nconsole.log(numbers.slice().sort((a, b) => b - a));  // [9, 6, 4, 2, 1]\n\nconst fruits = ['banana', 'apple', 'melon', 'pineapple'];\nconsole.log(fruits.slice().sort((a, b) => a.length - b.length));  // sorts fruits based on the length of strings\n// ['apple', 'melon', 'banana', 'pineapple']\nconsole.log(fruits.slice().sort((a, b) => b.length - a.length));\n// ['pineapple', 'banana', 'apple', 'melon']\n\n\n// reduce\n\nnumbers = [1, 2, 3, 4, 5];\nconst sumOfValues = numbers.reduce((total, current) => total + current);\nconsole.log(sumOfValues);  // 15\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n * lista de calificaciones), utiliza funciones de orden superior para \n * realizar las siguientes operaciones de procesamiento y análisis:\n * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n *   y promedio de sus calificaciones.\n * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n *   que tienen calificaciones con un 9 o más de promedio.\n * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n * - Mayor calificación: Obtiene la calificación más alta de entre todas las\n *   de los alumnos.\n * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n */\n\nconst studentsData = [\n    {\n        firstName: 'Brennan',\n        lastName: 'Wiza',\n        birthDate: '11-02-2004',\n        marks: [5, 6.7, 8, 9.2, 3],\n    },\n    {\n        firstName: 'Hilton',\n        lastName: 'Schimmel',\n        birthDate: '07-07-1998',\n        marks: [8, 7.6, 7.8, 5.5, 9],\n    },\n    {\n        firstName: 'Aditya',\n        lastName: 'Rowe',\n        birthDate: '02-05-1999',\n        marks: [7.6, 8.9, 9.3, 10, 7.8],\n    },\n    {\n        firstName: 'Estella',\n        lastName: 'King',\n        birthDate: '29-06-1997',\n        marks: [9.6, 8.9, 9.3, 10, 7.8],\n    },\n];\n\n\n// Average\n\n\nfunction average(grades) {\n    return Math.round(\n        (\n            grades.reduce((total, current) => total + current)\n            / grades.length\n        ) * 100\n    ) / 100;\n}\n\n\nconsole.log(\n    studentsData.map(student => {\n        return {name: student.firstName, average: average(student.marks)}\n    })\n);\n/*\n  [{ name: 'Brennan', average: 6.38 },\n  { name: 'Hilton', average: 7.58 },\n  { name: 'Aditya', average: 8.72 },\n  { name: 'Estella', average: 9.12 }]\n */\n\n\n// Best students\n\nconsole.log(\n    studentsData\n    .filter(student => average(student.marks) >= 9)\n    .map(student => student.firstName)\n)\n// [ 'Estella' ]\n\n\n// Birth Day\n\nconsole.log(\n    studentsData.slice().sort((a, b) => {\n        const dateA = new Date(a.birthDate);\n        const dateB = new Date(b.birthDate);\n        return dateB - dateA;\n    })\n);\n\n\n// Highest score\n\nconsole.log(Math.max(...studentsData.flatMap(student => student.marks)));\n// 10\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/javascript/parababire.js",
    "content": "//Ejercicio\n\n//Función superior es aquella que recibe una función como argumento o devuelve a otra función\n\n/* Recibe función como argumento */\n\nconst arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];\n\nfunction filterArr(arr, callback) {\n  let filterNum = [];\n  for (let i = 0; i < arr.length; i++) {\n    callback(arr[i]) ? filterNum.push(arr[i]) : null;\n  }\n  return filterNum;\n}\n\nfunction isOdd(x) {\n  return x % 2 !== 0;\n}\n\nfunction isEven(x) {\n  return x % 2 === 0;\n}\n\nconsole.log(filterArr(arr, isEven));\nconsole.log(filterArr(arr, isOdd));\n\n/* Retorno de una función */\n\nfunction calculate(operation) {\n  switch (operation) {\n    case 'ADD':\n      return function (a, b) {\n        console.log(`${a} + ${b} = ${a + b}`);\n      };\n    case 'SUBTRACT':\n      return function (a, b) {\n        console.log(`${a} - ${b} = ${a - b}`);\n      };\n  }\n}\n\nconst calculateAdd = calculate('ADD');\ncalculateAdd(3, 5);\ncalculate('SUBTRACT')(13, 8);\n\n//Extra\n\nconst students = [\n  {'name': 'Ángel', 'birthdate': '09-16-1979', 'grades': [7, 7.2, 6.5, 9.5]},\n  {'name': 'María', 'birthdate': '06-10-1980', 'grades': [5, 7.2, 6.5, 8]},\n  {'name': 'Rosa', 'birthdate': '01-23-1985', 'grades': [7.1, 7.2, 10, 8.5]},\n  {'name': 'José', 'birthdate': '02-03-1987', 'grades': [9.1, 9.2, 10, 8.5]}\n];\n\n//Promedio\n\nfunction average(grades) {\n  let initialValue = 0;\n  return (grades.reduce(\n    (accumulator, currentValue) => accumulator + currentValue,\n    initialValue,\n  )/grades.length).toFixed(2);\n}\n\nfunction nameAndAverage(n) {\n  return {'name': n['name'], 'average': average(n['grades'])};\n}\n\nconsole.log(students.map(nameAndAverage));\n\n//Honores\n\nfunction bestAverage(student) {\n  return student.average >= 9;\n}\n\nconsole.log(students.map(nameAndAverage).filter(bestAverage).map(student => student.name));\n\n//Mas joven\n\nfunction nameAndBirth(n) {\n  return {'name': n['name'], 'birth': new Date(n['birthdate']), 'grades': n['grades']};\n}\n\nfunction dateFormat(a, b) {\n  let c = b.birth - a.birth;\n  return c;\n}\nconsole.log(students.map(nameAndBirth).sort(dateFormat).map((n) => {\n  return {'name': n['name'], 'birth': n['birth'].toLocaleDateString('es-es', {day: 'numeric', month: 'numeric', year: 'numeric'}), 'grades': n['grades']};\n}));\n\n// Mayor calificación\n\nconsole.log(Math.max(...students.map((n) => {\n  return Math.max(...n['grades']);\n})));\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/javascript/pedamoci.js",
    "content": "// FUNCIONES DE ORDEN SUPERIOR\n  // Reciben una función como parametro\n    function calcular(a, b, metodo) {\n      console.log(metodo(a, b))\n    }\n\n    const sumar = (num1, num2)=> {\n      return num1 + num2\n    }\n\n    calcular(5, 62, sumar)\n\n  // Devuelven una función\n    function devolverMetodo(num) {\n      if (num > 10) {\n        return multiplicar = (num1, num2)=>{\n          console.log(num1 * num2)\n        }\n      } else {\n        return sumar = (num1, num2)=> {\n          console.log(num1 + num2)\n        }\n      }\n    }\n\n    let metodo = devolverMetodo(23)\n\n    metodo(45, 32)\n// ----------------------------------- DIFICULTAD EXTRA -----------------------------------\nconst listaEstudiantes = [{\n  nombre: \"Juan\",\n  fechaNacimiento: \"12/05/04\",\n  notas: [6.75, 1.22, 3.47, 3.01, 7.62]\n}, {\n  nombre: \"Agus\",\n  fechaNacimiento: \"23/02/05\",\n  notas: [7.08, 9.02, 1.78, 4.79, 1.27]\n}, {\n  nombre: \"Victor\",\n  fechaNacimiento: \"26/12/04\",\n  notas: [2.97, 5.54, 1.24, 2.79, 6.84]\n}, {\n  nombre: \"Caterina\",\n  fechaNacimiento: \"04/06/04\",\n  notas: [10.0, 9.45, 9.06, 9.5, 9.76]\n}, {\n  nombre: \"Raul\",\n  fechaNacimiento: \"13/11/05\",\n  notas: [1.06, 8.24, 7.28, 4.06, 2.4]\n}, {\n  nombre: \"David\",\n  fechaNacimiento: \"08/08/05\",\n  notas: [9.61, 4.03, 1.83, 1.87, 8.62]\n}, {\n  nombre: \"Jesus\",\n  fechaNacimiento: \"18/07/04\",\n  notas: [9.6, 9.8, 9.72, 9.53, 9.96]\n}, {\n  nombre: \"Eugenia\",\n  fechaNacimiento: \"01/04/05\",\n  notas: [9.37, 9.55, 9.82, 9.61, 9.85]\n}]\n\n\nconst listaPromedios = listaEstudiantes.map((estudiante) => {\n  let prom = estudiante.notas.reduce((p, nota) => (p += nota / estudiante.notas.length), 0)\n  return {nombre: estudiante.nombre, promedio: prom.toFixed(2)}\n})\nconsole.log(listaPromedios)\n\nconst mejoresPromedios = listaPromedios.filter((estudiante) => estudiante.promedio >= 9)\nconsole.log(mejoresPromedios)\n\nconst listaNacimiento = listaEstudiantes\n  .map((estudiante) => ({\n    nombre: estudiante.nombre, \n    fecha: estudiante.fechaNacimiento.split('/')\n  }))\n  .sort((a, b) => \n    parseInt(a.fecha[2]) - parseInt(b.fecha[2]) ||  // los ordena en forma creciente por año, si es el mismo pasa a comparar el mes\n    parseInt(a.fecha[1]) - parseInt(b.fecha[1]) ||  // los ordena en forma creciente por mes, si es el mismo pasa a comparar el día\n    parseInt(a.fecha[0]) - parseInt(b.fecha[0])     // los ordena en forma creciente por día\n  )\nconsole.log(listaNacimiento)\n\nconst mejorNota = listaEstudiantes.filter((estudiante) => sacoDiez(estudiante.notas))\nfunction sacoDiez(notas) {\n  return notas.includes(10)\n}\nconsole.log(mejorNota)"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/javascript/victor-Casta.js",
    "content": "/*\n  * EJERCICIO:\n  * Explora el concepto de funciones de orden superior en tu lenguaje\n  * creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n*/\n\nconst numberslist = [1,2,3,4,5]\nnumberslist.forEach((item) => {\n  console.log(item)\n})\n\nfunction principal(a) {\n  function add(b) {\n    return a + b\n  }\n  return add\n}\n\nlet c = principal(3)\nconsole.log(c(3))\n\n/*\n  * DIFICULTAD EXTRA (opcional):\n  * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y\n  * lista de calificaciones), utiliza funciones de orden superior para\n  * realizar las siguientes operaciones de procesamiento y análisis:\n  * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n  *   y promedio de sus calificaciones.\n  * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n  *   que tienen calificaciones con un 9 o más de promedio.\n  * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n  * - Mayor calificación: Obtiene la calificación más alta de entre todas las\n  *   de los alumnos.\n  * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n*/\n\nconst studentsList = [\n  {\n    name: 'Victor',\n    birthday: new Date(2002, 11, 17),\n    notesList: [9.0, 8.7, 10, 9.5]\n  },\n  {\n    name: 'Juan',\n    birthday: new Date(2003, 10, 7),\n    notesList: [9.0, 9.1, 9.0, 9.3]\n  },\n  {\n    name: 'John',\n    birthday: new Date(2000, 11, 21),\n    notesList: [6.0, 7.0, 9.0, 9.0]\n  }\n]\n\n//Promedio\nconst studentsWithAverage = studentsList.map(student => {\n  const totalNotes = student.notesList.reduce((acc, note) => acc + note, 0)\n  const average = totalNotes / student.notesList.length\n\n  return {\n    name: student.name,\n    average: average.toFixed(1)\n  }\n})\nconsole.log('Promedio: \\n\\n', studentsWithAverage)\n\n//Mejores estudiantes\nconst bestStudents = studentsWithAverage.filter((item) => item.average >= 9)\nconsole.log('\\n Mejores estudiantes: \\n\\n',bestStudents)\n\n//Nacimiento\nconst sortedStudents = studentsList.sort((a, b) => b.birthday - a.birthday)\nconsole.log('\\n Estudiantes mas jovenes: \\n\\n',sortedStudents)\n\n//Calificación mas alta\nconst highestRating = studentsList.map(item => item.notesList).reduce((acc, val) => acc.concat(val), []).sort((a,b) => a - b)\nconsole.log('\\n Calificación mas alta: \\n\\n',highestRating[highestRating.length - 1])"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/kotlin/blackriper.kt",
    "content": "import java.text.SimpleDateFormat\r\n\r\n/*\r\nLas funciones de orden  superior  son cuyas funciones  que pueden recibir una funcion como argumento\r\no  devolver una funcion como resultado.\r\n\r\nusos comunes de la funcion de orden superior son el manejo de  listas,  map,  filter, etc.\r\n\r\nlas funciones de orden superior no mutan las listas originales  dan como resultado una nueva lista\r\npor lo cual la mutabilidad se mantiene al minimo.\r\n\r\n*/\r\n\r\nfun exampleWithOrderSuperiorFunc(){\r\n\r\n val list = listOf(1,2,3,4,5,6,7,8,9,10)\r\n println(\"list of kotlin $list\")\r\n\r\n // usando map para generar un nuevo resultado este puede recibir una lambda funcion como argumento\r\n val newList = list.map { it * 2 }\r\n println(\"list of map kotlin $newList\")\r\n\r\n // forma imperativa\r\n fun multiplyBy2(x:Int):Int = x * 2\r\n\r\n fun multipyNumber(listNum:List<Int>, func : (Int) -> Int): List<Int>{\r\n     val listResult = mutableListOf<Int>()\r\n     for (num in listNum){\r\n         listResult.add(func(num))\r\n     }\r\n    return  listResult\r\n }\r\n\r\nval newList2 = multipyNumber(list,::multiplyBy2)\r\nprintln(\"list of my own function $newList2\")\r\n\r\n// lambda function\r\nval newList3 = multipyNumber(list){it * 3}\r\nprintln(\"list of lambda function $newList3\")\r\n\r\n}\r\n\r\n// ejercicio extra\r\n\r\ndata class Student(val name:String,val birthDate:String,val scores:List<Int>)\r\n\r\nval listOfStudents = listOf(\r\n    Student(\"rodolfo\",\"20/05/1994\", listOf(8,9,9,10,9,10)),\r\n    Student(\"martin\",\"27/05/1993\", listOf(5,6,7,8,9,9)),\r\n    Student(\"roswell\",\"12/03/1992\", listOf(9,7,7,8,0,8)),\r\n    Student(\"salvador\",\"22/04/1995\", listOf(9,9,9,10,10,10)),\r\n    Student(\"luis\",\"01/01/1990\", listOf(8,9,5,4,9,10))\r\n)\r\n\r\n\r\nfun calculateAverageScore(student:Student):Int{\r\n    val total = student.scores.sum()\r\n    return total / student.scores.size\r\n}\r\n\r\n\r\n\r\nfun main() {\r\n    exampleWithOrderSuperiorFunc()\r\n\r\n    // ejercicio extra\r\n    val averageScore = listOfStudents.map { it.name to  calculateAverageScore(it) }\r\n    println(\"average score $averageScore\")\r\n\r\n    val bestStudents= averageScore.filter { it.second >=9 }\r\n    println(\"best students $bestStudents\")\r\n\r\n    val youngStudents = listOfStudents.sortedByDescending { SimpleDateFormat(\"dd/MM/yyyy\").parse(it.birthDate) }\r\n    println(\"young students $youngStudents\")\r\n\r\n   val majorScores= listOfStudents.map { it.name to it.scores.max() }\r\n    println(\"major scores $majorScores\")\r\n}"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/kotlin/eulogioep.kt",
    "content": "// Ejemplos simples de funciones de orden superior\n\n// 1. Función que recibe otra función como parámetro\nfun operacion(a: Int, b: Int, funcion: (Int, Int) -> Int): Int {\n    return funcion(a, b)\n}\n\n// 2. Función que devuelve otra función\nfun multiplicadorPor(factor: Int): (Int) -> Int {\n    return { numero -> numero * factor }\n}\n\nfun main() {\n    // Uso de la función 'operacion'\n    val suma = operacion(5, 3) { x, y -> x + y }\n    println(\"Suma: $suma\")\n\n    val multiplicacion = operacion(5, 3) { x, y -> x * y }\n    println(\"Multiplicación: $multiplicacion\")\n\n    // Uso de la función 'multiplicadorPor'\n    val duplicar = multiplicadorPor(2)\n    println(\"Duplicar 7: ${duplicar(7)}\")\n\n    // Ejercicio Extra\n    data class Estudiante(\n        val nombre: String,\n        val fechaNacimiento: String,\n        val calificaciones: List<Double>\n    )\n\n    val estudiantes = listOf(\n        Estudiante(\"Ana\", \"2000-05-15\", listOf(8.5, 9.0, 9.5, 10.0)),\n        Estudiante(\"Carlos\", \"1999-11-30\", listOf(7.0, 8.0, 8.5, 9.0)),\n        Estudiante(\"Elena\", \"2001-03-22\", listOf(9.0, 9.5, 10.0, 10.0)),\n        Estudiante(\"David\", \"2000-09-10\", listOf(6.5, 7.0, 7.5, 8.0))\n    )\n\n    // Promedio calificaciones\n    val promedios = estudiantes.map { estudiante ->\n        val promedio = estudiante.calificaciones.average()\n        \"${estudiante.nombre}: ${\"%.2f\".format(promedio)}\"\n    }\n    println(\"Promedios: $promedios\")\n\n    // Mejores estudiantes\n    val mejoresEstudiantes = estudiantes.filter { \n        it.calificaciones.average() >= 9.0 \n    }.map { it.nombre }\n    println(\"Mejores estudiantes: $mejoresEstudiantes\")\n\n    // Nacimiento (ordenado desde el más joven)\n    val ordenPorEdad = estudiantes.sortedByDescending { it.fechaNacimiento }\n        .map { it.nombre }\n    println(\"Orden por edad (más joven primero): $ordenPorEdad\")\n\n    // Mayor calificación\n    val mayorCalificacion = estudiantes.flatMap { it.calificaciones }.maxOrNull()\n    println(\"Mayor calificación: $mayorCalificacion\")\n}"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/ocaml/luishendrix92.ml",
    "content": "open Printf\n\n(*****************************************************************************)\n(*                                                                           *)\n(*                          Higher Order Functions                           *)\n(*                                                                           *)\n(*  As stated in previous files, a higher-order function is a Functional     *)\n(*  Programming term that describes a function that either:                  *)\n(*  a) Takes functions as parameters (named, or as lambdas).                 *)\n(*  b) Return functions (currying, closures, etc)                            *)\n(*  c) Both, making them very useful for state management, strategy picking  *)\n(*     , concurrent and parallel programming, async IO, currying and         *)\n(*     partial application, deferred and lazy programming, and more!         *)\n(*                                                                           *)\n(*  In OCaml, functions can be passed as arguments and it's idiomatic in     *)\n(*  the community to have them as named parameters such as ~f as you can     *)\n(*  observe in the List functions coming from the Core library.              *)\n(*    The langugae also provides currying and partial application which      *)\n(*  makes it very easy to return functions from functions.                   *)\n(*                                                                           *)\n(*****************************************************************************)\n\nlet hof_example_1 ~func x =\n  print_endline \"Higher order function example #1 - Function\";\n  print_endline \"Accepting a function (transformation from a to b):\";\n  printf \"Passed [%d], and f(x) = x^2, result = %d\\n\" x (func x)\n;;\n\nlet hof_example_2 ~consumer s =\n  print_endline \"HoF example #2 - Consumer\";\n  print_endline\n    \"A consumer is a function that accepts input but returns nothing (void):\";\n  printf \"Passed [%s] and f(s) = print Hello + s, output =\\n\" s;\n  consumer s\n;;\n\nlet hof_example_3 ~producer =\n  print_endline \"HoF example #3 - Producer\";\n  print_endline \"Producers take no arguments, they just generate values...\";\n  print_endline\n    \"I will combine this with the concept of closures to generate a counter:\";\n  print_endline \"Calling the producer closure callback 5 times...\";\n  for i = 1 to 5 do\n    producer () |> printf \"Next dispenser value: %i\\n\"\n  done\n;;\n\nlet hof_example_4 ~runnable =\n  let a =\n    Thread.create\n      (fun () ->\n        Thread.delay 1.0;\n        runnable ())\n      ()\n  in\n  let b =\n    Thread.create\n      (fun () ->\n        Thread.delay 1.0;\n        runnable ())\n      ()\n  in\n  print_endline \"HoF example #4 - Runnable\";\n  print_endline \"Runnables are void functions that take no parameters...\";\n  print_endline \"Their sole purpose is to run a task; very useful in async IO!\";\n  print_endline\n    \"I will call a [runnable] in 2 sepeate threads after 1s has elapsed:\";\n  Thread.join a;\n  Thread.join b\n;;\n\nlet _ =\n  hof_example_1 ~func:(fun x -> x * x) 5;\n  print_newline ();\n  hof_example_2 ~consumer:(fun s -> printf \"Hello, %s!\\n\" s) \"Luis\";\n  print_newline ();\n  (* [make_counter init] is a {b higher order function} that returns a function\n     as an anonymous producer lambda and closes over the {e ref} called [i] (set\n     to [init]) and increments its value after every call. *)\n  let make_counter init =\n    let i : int ref = ref init in\n    fun () ->\n      let n = !i in\n      incr i;\n      n\n  in\n  hof_example_3 ~producer:(make_counter 10);\n  print_newline ();\n  hof_example_4 ~runnable:(fun () -> print_endline \"Hello from a thread\");\n  print_newline ()\n;;\n\n(****************************************************************************)\n(*                                                                          *)\n(*                        Dificultad Extra (Opcional)                       *)\n(*                                                                          *)\n(*  Dada una lista de estudiantes (con sus nombres, fecha de nacimiento, y  *)\n(*  lista de calificaciones), utiliza funciones de orden superior para      *)\n(*  realizar las siguientes operaciones de procesamiento y análisis:        *)\n(*                                                                          *)\n(*  - {b Promedio de calificaciones}: Obtiene una lista de estudiantes por  *)\n(*    nombre y promedio de sus calificaciones.                              *)\n(*  - {b Mejores estudiantes}: Obtiene una lista con el nombre de los es-   *)\n(*    tudiantes que tienen calificaciones con un 9 o más de promedio.       *)\n(*  - {b Nacimiento}: Obtiene una lista de estudiantes ordenada desde el    *)\n(*    más jóven al más viejo.                                               *)\n(*  - {b Mayor calificación}: Obtiene la calificación más alta de entre     *)\n(*    todas las de los alumnos.                                             *)\n(*  - Una calificación debe estar comprendida {e entre 0 y 10} (admite de-  *)\n(*    cimales).                                                             *)\n(*                                                                          *)\n(****************************************************************************)\n\nmodule SchoolGroup = struct\n  open Core\n\n  type subject =\n    | Algebra\n    | History\n    | Geography\n    | Chemistry\n    | PhysEd\n    | Biology\n  [@@deriving show { with_path = false }]\n\n  type grade = subject * float [@@deriving show]\n\n  type student =\n    { name : string\n    ; birth_date : Date.t\n    ; grades : grade list\n    }\n  [@@deriving show { with_path = false }]\n\n  let averages =\n    List.map ~f:(fun st ->\n      st.name, st.grades |> List.map ~f:Tuple2.get2 |> Moure.Math.average)\n  ;;\n\n  let best_students sl =\n    averages sl |> List.filter ~f:(fun (_, avg) -> Float.( >= ) avg 9.0)\n  ;;\n\n  let highest_grade sl =\n    sl\n    |> List.map ~f:(fun st ->\n      st.grades\n      |> List.max_elt ~compare:(fun (_, score1) (_, score2) ->\n        Float.compare score1 score2)\n      |> Option.map ~f:(fun (sub, score) -> st.name, sub, score)\n      |> Option.value_exn)\n    |> List.max_elt ~compare:(fun (_, _, score1) (_, _, score2) ->\n      Float.compare score1 score2)\n    |> Option.value_exn\n  ;;\n\n  let sorted_by_age =\n    List.stable_sort ~compare:(fun st1 st2 ->\n      Int.neg @@ Date.compare st1.birth_date st2.birth_date)\n  ;;\nend\n\nlet _ =\n  let open Core in\n  let open SchoolGroup in\n  let students =\n    [ { name = \"Luis Lopez\"\n      ; birth_date = Date.create_exn ~d:9 ~m:Month.apr ~y:1992\n      ; grades =\n          [ Algebra, 8.8\n          ; History, 9.1\n          ; Geography, 9.0\n          ; Chemistry, 7.6\n          ; PhysEd, 6.0\n          ; Biology, 8.4\n          ]\n      }\n    ; { name = \"Fulanita Perez\"\n      ; birth_date = Date.create_exn ~d:25 ~m:Month.dec ~y:1985\n      ; grades =\n          [ Algebra, 9.3\n          ; History, 9.1\n          ; Geography, 9.2\n          ; Chemistry, 9.0\n          ; PhysEd, 9.1\n          ; Biology, 9.0\n          ]\n      }\n    ; { name = \"Menganito Mora\"\n      ; birth_date = Date.create_exn ~d:18 ~m:Month.jan ~y:2004\n      ; grades =\n          [ Algebra, 5.0\n          ; History, 3.4\n          ; Geography, 7.2\n          ; Chemistry, 6.9\n          ; PhysEd, 7.0\n          ; Biology, 8.6\n          ]\n      }\n    ; { name = \"Cere Brito\"\n      ; birth_date = Date.create_exn ~d:29 ~m:Month.aug ~y:1998\n      ; grades =\n          [ Algebra, 9.9\n          ; History, 9.2\n          ; Geography, 9.5\n          ; Chemistry, 10.0\n          ; PhysEd, 8.8\n          ; Biology, 9.8\n          ]\n      }\n    ; { name = \"Silvia Zamora\"\n      ; birth_date = Date.create_exn ~d:8 ~m:Month.may ~y:2000\n      ; grades =\n          [ Algebra, 6.9\n          ; History, 7.3\n          ; Geography, 9.4\n          ; Chemistry, 6.1\n          ; PhysEd, 9.2\n          ; Biology, 7.3\n          ]\n      }\n    ]\n  in\n  let show_avg_student (name, avg) =\n    printf \"name = %s | average grade = %f\\n\" name avg\n  in\n  let show_highest_grade (name, sub, score) =\n    printf \"name = %s | subject = %s | score %f\\n\" name (show_subject sub) score\n  in\n  print_endline \"Here's a list of students in the group:\";\n  students |> List.map ~f:show_student |> List.iter ~f:print_endline;\n  Stdlib.print_newline ();\n  print_endline \"Same students but sorted by age (youngest to oldest):\";\n  sorted_by_age students\n  |> List.map ~f:show_student\n  |> List.iter ~f:print_endline;\n  Stdlib.print_newline ();\n  print_endline \"Grade Averages per name:\";\n  averages students |> List.iter ~f:show_avg_student;\n  Stdlib.print_newline ();\n  print_endline \"Best students (average of 9.0 or greater):\";\n  best_students students |> List.iter ~f:show_avg_student;\n  Stdlib.print_newline ();\n  print_endline \"Highest grade out of all students:\";\n  highest_grade students |> show_highest_grade\n;;\n\n(* Output of [dune exec reto22]\n   ----------------------------\n\n   Higher order function example #1 - Function\n   Accepting a function (transformation from a to b):\n   Passed [5], and f(x) = x^2, result = 25\n\n   HoF example #2 - Consumer\n   A consumer is a function that accepts input but returns nothing (void):\n   Passed [Luis] and f(s) = print Hello + s, output =\n   Hello, Luis!\n\n   HoF example #3 - Producer\n   Producers take no arguments, they just generate values...\n   I will combine this with the concept of closures to generate a counter:\n   Calling the producer closure callback 5 times...\n   Next dispenser value: 10\n   Next dispenser value: 11\n   Next dispenser value: 12\n   Next dispenser value: 13\n   Next dispenser value: 14\n\n   HoF example #4 - Runnable\n   Runnables are void functions that take no parameters...\n   Their sole purpose is to run a task; very useful in async IO!\n   I will call a [runnable] in 2 sepeate threads after 1s has elapsed:\n   Hello from a thread\n   Hello from a thread\n\n   Here's a list of students in the group:\n   { name = \"Luis Lopez\"; birth_date = 1992-04-09;\n     grades =\n     [(Algebra, 8.8); (History, 9.1); (Geography, 9.); (Chemistry, 7.6);\n       (PhysEd, 6.); (Biology, 8.4)]\n     }\n   { name = \"Fulanita Perez\"; birth_date = 1985-12-25;\n     grades =\n     [(Algebra, 9.3); (History, 9.1); (Geography, 9.2); (Chemistry, 9.);\n       (PhysEd, 9.1); (Biology, 9.)]\n     }\n   { name = \"Menganito Mora\"; birth_date = 2004-01-18;\n     grades =\n     [(Algebra, 5.); (History, 3.4); (Geography, 7.2); (Chemistry, 6.9);\n       (PhysEd, 7.); (Biology, 8.6)]\n     }\n   { name = \"Cere Brito\"; birth_date = 1998-08-29;\n     grades =\n     [(Algebra, 9.9); (History, 9.2); (Geography, 9.5); (Chemistry, 10.);\n       (PhysEd, 8.8); (Biology, 9.8)]\n     }\n   { name = \"Silvia Zamora\"; birth_date = 2000-05-08;\n     grades =\n     [(Algebra, 6.9); (History, 7.3); (Geography, 9.4); (Chemistry, 6.1);\n       (PhysEd, 9.2); (Biology, 7.3)]\n     }\n\n   Same students but sorted by age (youngest to oldest):\n   { name = \"Menganito Mora\"; birth_date = 2004-01-18;\n     grades =\n     [(Algebra, 5.); (History, 3.4); (Geography, 7.2); (Chemistry, 6.9);\n       (PhysEd, 7.); (Biology, 8.6)]\n     }\n   { name = \"Silvia Zamora\"; birth_date = 2000-05-08;\n     grades =\n     [(Algebra, 6.9); (History, 7.3); (Geography, 9.4); (Chemistry, 6.1);\n       (PhysEd, 9.2); (Biology, 7.3)]\n     }\n   { name = \"Cere Brito\"; birth_date = 1998-08-29;\n     grades =\n     [(Algebra, 9.9); (History, 9.2); (Geography, 9.5); (Chemistry, 10.);\n       (PhysEd, 8.8); (Biology, 9.8)]\n     }\n   { name = \"Luis Lopez\"; birth_date = 1992-04-09;\n     grades =\n     [(Algebra, 8.8); (History, 9.1); (Geography, 9.); (Chemistry, 7.6);\n       (PhysEd, 6.); (Biology, 8.4)]\n     }\n   { name = \"Fulanita Perez\"; birth_date = 1985-12-25;\n     grades =\n     [(Algebra, 9.3); (History, 9.1); (Geography, 9.2); (Chemistry, 9.);\n       (PhysEd, 9.1); (Biology, 9.)]\n     }\n\n   Grade Averages per name:\n   name = Luis Lopez | average grade = 8.150000\n   name = Fulanita Perez | average grade = 9.116667\n   name = Menganito Mora | average grade = 6.350000\n   name = Cere Brito | average grade = 9.533333\n   name = Silvia Zamora | average grade = 7.700000\n\n   Best students (average of 9.0 or greater):\n   name = Fulanita Perez | average grade = 9.116667\n   name = Cere Brito | average grade = 9.533333\n\n   Highest grade out of all students:\n   name = Cere Brito | subject = Chemistry | score 10.000000\n*)\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/php/eulogioep.php",
    "content": "<?php\n\n// Clase Estudiante para manejar la información de cada alumno\nclass Estudiante {\n    private string $nombre;\n    private DateTime $fechaNacimiento;\n    private array $calificaciones;\n\n    public function __construct(string $nombre, string $fechaNacimiento, array $calificaciones) {\n        $this->nombre = $nombre;\n        $this->fechaNacimiento = new DateTime($fechaNacimiento);\n        // Validamos que las calificaciones estén entre 0 y 10\n        $this->calificaciones = array_filter($calificaciones, function($calif) {\n            return $calif >= 0 && $calif <= 10;\n        });\n    }\n\n    public function getNombre(): string {\n        return $this->nombre;\n    }\n\n    public function getFechaNacimiento(): DateTime {\n        return $this->fechaNacimiento;\n    }\n\n    public function getCalificaciones(): array {\n        return $this->calificaciones;\n    }\n}\n\n// Creamos una lista de estudiantes de ejemplo\n$estudiantes = [\n    new Estudiante(\n        \"Ana García\",\n        \"2000-05-15\",\n        [9.5, 8.7, 9.2, 9.8]\n    ),\n    new Estudiante(\n        \"Carlos Pérez\",\n        \"1999-03-20\",\n        [7.5, 8.0, 6.5, 7.8]\n    ),\n    new Estudiante(\n        \"María López\",\n        \"2001-08-10\",\n        [9.0, 9.5, 9.3, 9.7]\n    )\n];\n\n// Funciones auxiliares\nfunction calcularPromedio(array $calificaciones): float {\n    return array_sum($calificaciones) / count($calificaciones);\n}\n\n// 1. Obtener lista de estudiantes con sus promedios\nfunction obtenerPromedios(array $estudiantes): array {\n    return array_map(function($estudiante) {\n        return [\n            'nombre' => $estudiante->getNombre(),\n            'promedio' => calcularPromedio($estudiante->getCalificaciones())\n        ];\n    }, $estudiantes);\n}\n\n// 2. Obtener mejores estudiantes (promedio >= 9)\nfunction obtenerMejoresEstudiantes(array $estudiantes): array {\n    return array_map(\n        fn($estudiante) => $estudiante->getNombre(),\n        array_filter($estudiantes, function($estudiante) {\n            return calcularPromedio($estudiante->getCalificaciones()) >= 9;\n        })\n    );\n}\n\n// 3. Obtener lista ordenada por fecha de nacimiento (más joven primero)\nfunction ordenarPorEdad(array $estudiantes): array {\n    $estudiantesCopia = $estudiantes;\n    usort($estudiantesCopia, function($a, $b) {\n        return $b->getFechaNacimiento() <=> $a->getFechaNacimiento();\n    });\n    \n    return array_map(function($estudiante) {\n        return [\n            'nombre' => $estudiante->getNombre(),\n            'fechaNacimiento' => $estudiante->getFechaNacimiento()->format('Y-m-d')\n        ];\n    }, $estudiantesCopia);\n}\n\n// 4. Obtener la calificación más alta de todos los estudiantes\nfunction obtenerMayorCalificacion(array $estudiantes): float {\n    $todasLasCalificaciones = array_merge(...array_map(\n        fn($estudiante) => $estudiante->getCalificaciones(),\n        $estudiantes\n    ));\n    return max($todasLasCalificaciones);\n}\n\n// Mostrar resultados\necho \"1. Promedios de calificaciones:\\n\";\nprint_r(obtenerPromedios($estudiantes));\n\necho \"\\n2. Mejores estudiantes (promedio >= 9):\\n\";\nprint_r(obtenerMejoresEstudiantes($estudiantes));\n\necho \"\\n3. Estudiantes ordenados por edad (más joven primero):\\n\";\nprint_r(ordenarPorEdad($estudiantes));\n\necho \"\\n4. Mayor calificación de todos los estudiantes:\\n\";\necho obtenerMayorCalificacion($estudiantes) . \"\\n\";\n\n// Ejemplos adicionales de funciones de orden superior en PHP\necho \"\\nEjemplos adicionales de funciones de orden superior:\\n\";\n\n// Ejemplo 1: función que retorna otra función (closure)\nfunction multiplicadorPor($factor) {\n    return function($numero) use ($factor) {\n        return $numero * $factor;\n    };\n}\n$multiplicarPor2 = multiplicadorPor(2);\necho \"Multiplicar 4 por 2: \" . $multiplicarPor2(4) . \"\\n\"; // Output: 8\n\n// Ejemplo 2: función que recibe otra función como parámetro\nfunction aplicarOperacion(array $numeros, callable $operacion): array {\n    return array_map($operacion, $numeros);\n}\n$duplicar = fn($numero) => $numero * 2;\necho \"Duplicar números [1,2,3]: \";\nprint_r(aplicarOperacion([1,2,3], $duplicar));\n\n// Ejemplo 3: composición de funciones\nfunction componerFunciones(callable $f, callable $g): callable {\n    return function($x) use ($f, $g) {\n        return $f($g($x));\n    };\n}\n$sumar1 = fn($x) => $x + 1;\n$duplicarYSumar1 = componerFunciones($sumar1, $duplicar);\necho \"Duplicar 5 y sumar 1: \" . $duplicarYSumar1(5) . \"\\n\"; // Output: 11\n\n?>"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/php/gabrielmoris.php",
    "content": "<?php\n/*\n * EXERCISE:\n * Explore the concept of higher-order functions in your language\n * by creating simple examples (of your choice) that demonstrate their operation.\n */\nfunction sum($num1, $num2)\n{\n    return $num1 + $num2;\n}\n\nfunction sum5($sumfn, $num)\n{\n    return $sumfn(5, $num);\n}\n\necho sum5(\"sum\", 5) . \"\\n\";\n\n$arr = [1, 2, 3, 4, 5, \"potato\"];\n\n$filtered = array_map(function ($n) {\n    if (is_string($n)) {\n        return $n;\n    }\n}, $arr);\n\n$filtered = array_filter($filtered, function ($n) {\n    return !is_null($n);  // Check for non-null values\n});\n$filtered = array_values($filtered);\nvar_dump($filtered);\n\n/*\n * EXTRA DIFFICULTY (optional):\n * Given a list of students (with their names, date of birth, and\n * list of grades), use higher-order functions to perform the following\n * processing and analysis operations:\n * - Grade average: Get a list of students by name and their average grade.\n * - Top students: Get a list with the names of students who have an average\n *   grade of 9 or higher.\n * - Birth date: Get a list of students ordered from youngest to oldest.\n * - Highest grade: Get the highest grade among all students.\n * - A grade must be between 0 and 10 (decimal values allowed).\n */\n\n$students = [\n    [\n        \"name\" => \"Gaius Caesar Augustus\",\n        \"date_of_birth\" => strtotime(\"1990-01-01\"),\n        \"grades\" => [\n            \"Math\" => 8.5,\n            \"English\" => 9.0,\n            \"Science\" => 7.8,\n        ],\n    ],\n    [\n        \"name\" => \"Marcus Aurelius\",\n        \"date_of_birth\" => strtotime(\"1992-02-14\"),\n        \"grades\" => [\n            \"Math\" => 9.2,\n            \"English\" => 8.8,\n            \"Science\" => 8.2,\n        ],\n    ],\n    [\n        \"name\" => \"Lucius Claudius\",\n        \"date_of_birth\" => strtotime(\"1995-03-08\"),\n        \"grades\" => [\n            \"Math\" => 7.5,\n            \"English\" => 9.5,\n            \"Science\" => 8.9,\n        ],\n    ],\n    [\n        \"name\" => \"Julius Caesar\",\n        \"date_of_birth\" => strtotime(\"1991-04-22\"),\n        \"grades\" => [\n            \"Math\" => 9.8,\n            \"English\" => 9.2,\n            \"Science\" => 9.0,\n        ],\n    ],\n    [\n        \"name\" => \"Marcus Junius Brutus\",\n        \"date_of_birth\" => strtotime(\"1993-05-17\"),\n        \"grades\" => [\n            \"Math\" => 9.0,\n            \"English\" => 9.0,\n            \"Science\" => 9.2,\n        ],\n    ],\n];\n\n\n// Grade average: Get a list of students by name and their average grade.\n$average_grades = array_map(function ($student) {\n    $average = array_sum($student['grades']) / count($student['grades']);\n    return [\"name\" => $student[\"name\"], \"average\" => $average];\n}, $students);\nvar_dump($average_grades);\n\n// Top students: Get a list with the names of students who have an average grade of 9 or higher.\n$best_grades = array_map(function ($student) {\n    $average = array_sum($student['grades']) / count($student['grades']);\n    if ($average > 9) {\n        return [\"name\" => $student[\"name\"], \"average\" => $average];\n    }\n}, $students);\n\n$filtered_grades = array_filter($best_grades, function ($n) {\n    return !is_null($n);  // Check for non-null values\n});\n$best_grades = array_values($filtered_grades);\nvar_dump($best_grades);\n\n\n// Birth date: Get a list of students ordered from youngest to oldest. Modifies the original array\nusort($students, function ($student1, $student2) {\n    return $student1[\"date_of_birth\"] < $student2[\"date_of_birth\"];\n});\n\nvar_dump($students);\n\n// Highest grade: Get the highest grade among all students.\n\nusort($best_grades, function ($student1, $student2) {\n    return $student1[\"average\"] < $student2[\"average\"];\n});\n\n$best_grade = $best_grades[0];\nvar_dump($best_grade);\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/php/miguelex.php",
    "content": "<?php\n\n    // Ejemplo de funcion de orden superior con array map\n\n    $numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n\n    $squares = array_map(function($n) {\n        return $n * $n;\n    }, $numbers);\n\n    foreach ($squares as $key => $values){\n        echo \"El cuadrado de \". $numbers[$key] . \" es \". $values . \"\\n\"; \n    }\n\n    // Ejercicio extra\n\n    echo \"\\n\\nEJERCICIO EXTRA \\n\\n\";\n\n    $students = [\n        ['name' => 'Ana', 'birthdate' => '2000-06-15', 'grades' => [8.5, 9.2, 7.3]],\n        ['name' => 'Luis', 'birthdate' => '2002-12-03', 'grades' => [9.0, 8.7, 9.5]],\n        ['name' => 'María', 'birthdate' => '2001-01-25', 'grades' => [6.5, 7.8, 8.2]],\n        ['name' => 'Carlos', 'birthdate' => '2003-08-20', 'grades' => [9.1, 9.3, 9.4]],\n        ['name' => 'Eva', 'birthdate' => '2000-03-11', 'grades' => [8.8, 9.0, 8.9]],\n        ['name' => 'Fran', 'birthdate' => '1975-09-03', 'grades' => [2.5, 7.0]],\n        ['name' => 'Daniel', 'birthdate' => '2010-07-02', 'grades' => [1, 1.5, 9.5, 9.8, 7.8, 3.6]],\n    ];\n    \n\n    function calculateAverage($grades) {\n        return array_sum($grades) / count($grades);\n    }\n        \n    $averageGrades = array_map(function($student) {\n        return [\n            'name' => $student['name'],\n            'average' => calculateAverage($student['grades'])\n        ];\n    }, $students);\n    \n    \n    $topStudents = array_filter($averageGrades, function($student) {\n        return $student['average'] >= 9;\n    });\n    \n    usort($students, function($a, $b) {\n        return strtotime($b['birthdate']) - strtotime($a['birthdate']);\n    });\n    \n    \n    $allGrades = array_merge(...array_column($students, 'grades'));\n    $highestGrade = max($allGrades);\n    \n    echo \"Promedio de calificaciones por estudiante:\\n\";\n    foreach ($averageGrades as $student) {\n        echo \"{$student['name']}: {$student['average']}\\n\";\n    }\n    \n    echo \"\\nMejores estudiantes (promedio >= 9):\\n\";\n    foreach ($topStudents as $student) {\n        echo \"{$student['name']}: {$student['average']}\\n\";\n    }\n    \n    echo \"\\nEstudiantes ordenados del más joven al más viejo:\\n\";\n    foreach ($students as $student) {\n        echo \"{$student['name']} (Nacimiento: {$student['birthdate']})\\n\";\n    }\n    \n    echo \"\\nLa calificación más alta entre todos los estudiantes es: $highestGrade\\n\";\n\n\n\n    \n\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/php/thaishdz.php",
    "content": "<?php\n/*\n * DIFICULTAD EXTRA (opcional):\n * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n * lista de calificaciones),✔️ utiliza funciones de orden superior para\n * realizar las siguientes operaciones de procesamiento y análisis:\n * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n *   y promedio de sus calificaciones. ✔️\n * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n *   que tienen calificaciones con un 9 o más de promedio. ✔️\n * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven. ✔️\n * - Mayor calificación: Obtiene la calificación más alta de entre todas las\n *   de los alumnos.✔️\n * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).✔️\n */\n\n/*\n********** Este es un json que consideré como entrada externa **********\n\n{\n    \"dataStudents\" : [\n        {\n            \"name\": \"Thais\",\n            \"birthday\": \"10-09-1993\",\n            \"grades\": {\n                \"Math\" : 4.5,\n                \"Biology\" : 6,\n                \"Physics\": 8,\n                \"Philosophy\" : 9,\n                \"History\": 8\n            }\n        },\n        {\n            \"name\": \"Cristina\",\n            \"birthday\": \"30-08-1991\",\n            \"grades\": {\n                \"Math\" : 7,\n                \"Biology\" : 5,\n                \"Physics\": 7,\n                \"Philosophy\" : 10,\n                \"History\": 8\n            } \n        },\n        {\n            \"name\": \"Iván\",\n            \"birthday\": \"01-07-1993\",\n            \"grades\": {\n                \"Math\" : 10,\n                \"Biology\" : 10,\n                \"Physics\": 10,\n                \"Philosophy\" : 7.5,\n                \"History\": 8\n            } \n        },\n        {\n            \"name\": \"Paula\",\n            \"birthday\": \"20-01-1995\",\n            \"grades\": {\n                \"Math\" : 3,\n                \"Biology\" : 5,\n                \"Physics\": 7,\n                \"Philosophy\" : 5.5,\n                \"History\": 1\n            } \n        },\n        {\n            \"name\": \"Betancort\",\n            \"birthday\": \"18-02-1991\",\n            \"grades\": {\n                \"Math\" : 3.4,\n                \"Biology\" : 9.2,\n                \"Physics\": 2.5,\n                \"Philosophy\" : 5,\n                \"History\": 8\n            } \n        },\n        {\n            \"name\": \"Jerico\",\n            \"birthday\": \"07-06-1980\",\n            \"grades\": {\n                \"Math\" : 10,\n                \"Biology\" : 9.2,\n                \"Physics\": 10,\n                \"Philosophy\" : 9.3,\n                \"History\": 8\n            } \n        }\n    ]\n}\n************************************************************************\n\n*/\n\n\n$jsonDataStudents = file_get_contents(\"students.json\"); // Al estar el json en otro path, hago esto\n$dataset = json_decode($jsonDataStudents, true); // lo convierto a un array asociativo\n\n\nfunction calculateAverageGrade(array $student)\n{\n   $grades = $student[\"grades\"];\n   $average = array_sum($grades) / count($grades);\n\n   return [\n      \"name\"      => $student[\"name\"],\n      \"average\"   => $average\n   ];\n}\n\n\nfunction isTopStudent(array $student)\n{\n   return $student[\"average\"] >= 9;\n}\n\nfunction sortStudentsByBirthdateDesc(array $students) : array \n{\n   usort($students, function ($studentA, $studentB) {\n      $birthA = DateTime::createFromFormat('d-m-Y', $studentA[\"birthday\"]);\n      $birthB = DateTime::createFromFormat('d-m-Y', $studentB[\"birthday\"]);\n\n      return $birthB <=> $birthA; // Ordenar desde el más joven al más viejo\n   });\n   \n   return $students;\n}\n\n/* \n* Aquí entendí que solo debía devolver la nota más alta de todas\n* porque consideré que en otro apartado ya estaba obteniendo \n* al alumnado con las mejores calificaciones\n* así que me pareció volver a repetir lo mismo es por eso que solo devuelvo un valor\n* En el caso de que hayan 2 estudiantes con la misma nota no pasaría nada \n* porque sería la nota más alta igualmente 😛\n*/\nfunction getHighestGrade(array $studentData): float \n{\n   $grades = array_column($studentData, 'average');\n   return max($grades);\n}\n\n\n// Las llamaditas a cada apartado del ejercicio\n$averageStudentGrades = array_map('calculateAverageGrade', $dataset[\"dataStudents\"]);\n$bestStudents = array_filter($averageStudentGrades, 'isTopStudent');\n$sortedStudentsByBirth = sortStudentsByBirthdateDesc($dataset[\"dataStudents\"]);\n$highestGrade = getHighestGrade($averageStudentGrades);\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/Aldroide.py",
    "content": "from functools import reduce\nfrom datetime import datetime\n\n\"\"\"\n    Explora el concepto de funciones de orden superior en tu lenguaje \n    creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n\"\"\"\n# funcion como argumento\n\n\ndef apply_func(func, x):\n    return func(x)\n\n\nx = apply_func(len, \"Aldroide\")\nprint(x)\n\n# retorno de funcion\n\n\ndef apply_mult(n):\n    def mult(x):\n        return x*n\n    return (mult)\n\n\nx = apply_mult(2)\n\nmult = apply_mult(2)\nprint(mult(5))\n\n# Sistema\nnumbers = [1, 3, 4, 2, 5]\n\n# map\n\n\ndef apply_double(n):\n    return n*2\n\n\nprint(list(map(apply_double, numbers)))\n\n\n# filter\ndef is_even(n):\n    return n % 2 == 0\n\n\nprint(list(filter(is_even, numbers)))\n\n# sorted()\nprint(sorted(numbers))\nprint(sorted(numbers, reverse=True))\nprint(sorted(numbers, key=lambda x: -x))\n\n# reduce()\n\n\ndef sum_values(x, y):\n    return x + y\n\n\nprint(reduce(sum_values, numbers))\n\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n    Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n        lista de calificaciones), utiliza funciones de orden superior para \n        realizar las siguientes operaciones de procesamiento y análisis:\n        Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n            promedio de sus calificaciones.\n        Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n            que tienen calificaciones con un 9 o más de promedio.\n        Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n        Mayor calificación: Obtiene la calificación más alta de entre todas las\n            de los alumnos.\n        Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n\"\"\"\n\nstudents = [\n    {\"name\": \"Aldroide\", \"birthdate\": \"29-04-1983\",\n        \"grades\": [9.5, 8.5, 9.9, 10]},\n    {\"name\": \"Richard\", \"birthdate\": \"04-08-1983\", \"grades\": [7.5, 9.5, 7, 6]},\n    {\"name\": \"Emmanuel\", \"birthdate\": \"15-12-2000\",\n        \"grades\": [6, 8.5, 9.5, 8.2]},\n    {\"name\": \"Samira\", \"birthdate\": \"25-01-1980\", \"grades\": [10, 9, 9.7, 9.9]}\n]\n\n\ndef average(grades):\n    return sum(grades)/len(grades)\n\n\n# Promedio\nprint(\n    list(map(lambda student: {\n        \"name\": student[\"name\"],\n        \"average\": average(student[\"grades\"])}, students)\n    )\n)\n\n\n# Mejores\nprint(\n    list(map(lambda student:\n            student[\"name\"],\n            filter(lambda student: average(student[\"grades\"]) >= 9, students)\n            )\n        )\n)\n\n# Fecha de naciemiento ordenada\nprint(sorted(students, key=lambda student: datetime.strptime(\n    student[\"birthdate\"], \"%d-%m-%Y\"), reverse=True))\n\n\n# Califiación más alta\n\nprint(max(map(lambda student: max(student[\"grades\"]), students)))\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/CaveroBrandon.py",
    "content": "\"\"\"Explora el concepto de funciones de orden superior en tu lenguaje\ncreando ejemplos simples (a tu elección) que muestren su funcionamiento\"\"\"\nfrom math import sqrt, pow\nfrom datetime import datetime\n\n\ndef right_triangle(func, triangle: dict):\n    return func(triangle)\n\n\ndef triangle_area(triangle: dict) -> float:\n    adjacent = triangle.get('adjacent')\n    opposite = triangle.get('opposite')\n    area = (adjacent * opposite) / 2\n    return area\n\n\ndef triangle_hypotenuse(triangle: dict) -> float:\n    adjacent = triangle.get('adjacent')\n    opposite = triangle.get('opposite')\n    hypotenuse = sqrt(pow(adjacent, 2) + pow(opposite, 2))\n    return hypotenuse\n\n\ntriangle_definition = {'adjacent': 3, 'opposite': 4}\nprint(f'Triangle definition\\n'\n      f'Adjacent side: {triangle_definition[\"adjacent\"]}\\n'\n      f'Opposite side: {triangle_definition[\"opposite\"]}')\n\n# Found the area of a triangle\nexample_area = right_triangle(triangle_area, triangle_definition)\nprint(f'The area of the right triangle is {example_area}')\n\n# Found the hypotenuse of a triangle\nexample_hypotenuse = right_triangle(triangle_hypotenuse, triangle_definition)\nprint(f'The hypotenuse of the right triangle is {example_hypotenuse}')\n\n\n\"\"\"DIFICULTAD EXTRA (opcional):\nDada una lista de estudiantes (con sus nombres, fecha de nacimiento y \nlista de calificaciones), utiliza funciones de orden superior para \nrealizar las siguientes operaciones de procesamiento y análisis:\n- Promedio calificaciones: Obtiene una lista de estudiantes por nombre y promedio de sus calificaciones.\n- Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes \nque tienen calificaciones con un 9 o más de promedio.\n- Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n- Mayor calificación: Obtiene la calificación más alta de entre todas las de los alumnos.\n- Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\"\"\"\n\n\nstudents = [\n    {\"name\": \"Andres\", \"dob\": \"2000-01-01\", \"grades\": [5.0, 7.0, 3.5]},\n    {\"name\": \"Brandon\", \"dob\": \"2002-02-02\", \"grades\": [10, 9.8, 9.0]},\n    {\"name\": \"Ash\", \"dob\": \"2001-05-05\", \"grades\": [8.5, 9.0, 7.5]},\n    {\"name\": \"Seiya\", \"dob\": \"2001-10-10\", \"grades\": [9.4, 9.0, 8.6]},\n    {\"name\": \"Alpha\", \"dob\": \"2000-12-25\", \"grades\": [7.0, 6.5, 6.0]},\n]\n\n\ndef students_gpa(students_list: list) -> list:\n    students_gpa_list = list()\n\n    for student in students_list:\n        student_grades = student['grades']\n        gpa = round((sum(student_grades) / len(student_grades)), 2)\n\n        students_gpa_list.append({'name': student['name'], 'gpa': gpa})\n\n    return students_gpa_list\n\n\ndef best_gpa(student_gpa: list) -> list:\n    bets_students_list = list()\n\n    for student in student_gpa:\n        gpa = student['gpa']\n        if gpa >= 9.0:\n            bets_students_list.append({'name': student['name'], 'gpa': gpa})\n\n    return bets_students_list\n\n\ndef best_student(best_students_list: list) -> list:\n    highest_gpa = max(student['gpa'] for student in best_students_list)\n    best_students = [{'name': student['name'], 'gpa': student['gpa']} for student in best_students_list if\n                     student['gpa'] == highest_gpa]\n    return best_students\n\n\ndef sort_list_by_age(students_list: list) -> list:\n    def get_dob(student):\n        return datetime.strptime(student['dob'], '%Y-%m-%d')\n\n    sorted_students = sorted(students_list, key=get_dob, reverse=True)\n    return sorted_students\n\n\ndef students_grades_functions(get_gpa, get_best_gpa, get_best_student, get_sorted_student_list, students_list: list):\n    # Get a list of students with their gpa\n    student_gpa_list = get_gpa(students_list)\n\n    # Get a list of the best gpas\n    best_gpa_list = get_best_gpa(student_gpa_list)\n\n    # Get a list of the best student\n    best_student = get_best_student(best_gpa_list)\n\n    # Get a list of students sorted by age\n    sorted_student_list = get_sorted_student_list(students_list)\n\n    return student_gpa_list, best_gpa_list, best_student, sorted_student_list\n\n\ngpa_list, best_gpa, higher_gpa, sorted_list = students_grades_functions(students_gpa, best_gpa, best_student, sort_list_by_age, students)\nprint('**** List of students with their gpa ****')\nprint(gpa_list)\nprint('**** List of best gpa ****')\nprint(best_gpa)\nprint('**** Best gpa ****')\nprint(higher_gpa)\nprint('**** Sorted list ****')\nprint(sorted_list)\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/CesarCarmona30.py",
    "content": "from functools import reduce\nfrom datetime import datetime\n\nfrom numpy import number\n\ndef apply_func(func, arg):\n  return func(arg)\n\nprint(apply_func(len, \"omnia mea mecum porto\"))\n\ndef apply_multiplier(n):\n  def multiplier(x):\n    return x * n\n  return multiplier\n\nmultiplier = apply_multiplier(2)\nprint(multiplier(5))\nprint(apply_multiplier(3)(2))\n\ndef apply_double(n):\n  return n * 2\n\nnumbers = [1, 2, 3, 4, 5]\n\nprint(list(map(apply_double, numbers)))\n\ndef is_even(n):\n  return n % 2 == 0\n\nprint(list(filter(is_even, numbers)))\n\nprint(sorted(numbers))\nprint(sorted(numbers, reverse=True))\nprint(sorted(numbers, key=lambda x: -x))\n\ndef sum_values(x, y):\n  return x + y\n\nprint(reduce(sum_values, numbers))\n\n\n'''\n  EXTRA\n'''\n\nstudents = [\n  {\"name\": \"Cesar\", \"birthdate\": \"30-07-2004\", \"grades\": [10, 10, 10, 9, 9, 6]},\n  {\"name\": \"Alex\", \"birthdate\": \"06-04-2002\", \"grades\": [10, 9, 9, 8, 10, 7]},\n  {\"name\": \"Diego\", \"birthdate\": \"10-01-2003\", \"grades\": [8, 7, 10, 9, 6, 6]},\n]\n\ndef average(grades):\n  return sum(grades) / len(grades)\n\nprint(\n  list(map(lambda student: {\n    \"name\": student[\"name\"],\n    \"average\": average(student[\"grades\"])}, students)\n  )\n)\n\nprint(\n  list(\n    map(lambda student:\n        student[\"name\"],\n        filter(lambda student: average(student[\"grades\"]) >= 9, students)\n        )\n  )\n)\n\nprint(sorted(students, key=lambda student: datetime.strptime(\n  student[\"birthdate\"], \"%d-%m-%Y\")))\n\nprint(max(map(lambda student: max(student[\"grades\"]), students)))"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/Chrisdev00.py",
    "content": "\"\"\"\n* EJERCICIO:\n* Explora el concepto de funciones de orden superior en tu lenguaje \n* creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n*\n* DIFICULTAD EXTRA (opcional):\n* Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n* lista de calificaciones), utiliza funciones de orden superior para \n* realizar las siguientes operaciones de procesamiento y análisis:\n* - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n*   y promedio de sus calificaciones.\n* - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n*   que tienen calificaciones con un 9 o más de promedio.\n* - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n* - Mayor calificación: Obtiene la calificación más alta de entre todas las\n*   de los alumnos.\n* - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n\"\"\"\n\n# Map function\n# La función map() es una función incorporada que toma una función y es iterable como parámetros.\n\nlanguages = [\"Java\", \"Python\", \"JavaScript\", \"Go\", \"Bash\"]\n\ndef change_lower(name):\n    return name.lower()\n\nlanguages_changed= map(change_lower, languages)\nlanguages_changed_lambda = map(lambda lan: lan.lower(), languages)\nprint(list(languages_changed))\nprint(list(languages_changed_lambda))\n\n# Filter function\n# La función filter() llama a la función especificada que devuelve un valor booleano para cada elemento \n# del iterable (lista) especificado. Filtra los elementos que satisfacen los criterios de filtrado.\n\ndef is_name_long(name):\n    if len(name) > 6:\n        return True\n    return False\n\nlong_names = filter(is_name_long, languages)\nprint(list(long_names))\n\n\nnumbers = [1, 2, 3, 4, 5]\n\ndef is_odd(num):\n    return num % 2 != 0\n\nodd_numbers = filter(is_odd, numbers)\nprint(list(odd_numbers))\n\n# Reduce function\n# Aplica una función de manera acumulativa a los elementos de una lista, reduciéndolos a un solo valor. \n# Esta función está en el módulo functools.\n\nfrom functools import reduce\n\nlist_num = ['1', '2', '3', '4', '5']\n\ndef sum_two_nums(x, y):\n    return int(x) + int(y)\n\ntotal = reduce(sum_two_nums, list_num)\nprint(total)\n\n#########  ------------------------------ EXTRA ------------------------------------ ###########\n\nfrom datetime import datetime\n\nstudents = [\n    {\"name\": \"Carlos\", \"date_birth\": \"15-05-2001\", \"grades\": [8.5, 9, 9.5]},\n    {\"name\": \"Juan\", \"date_birth\": \"08-11-2000\", \"grades\": [10, 9, 9.5]},\n    {\"name\": \"Pedro\", \"date_birth\": \"17-01-2002\", \"grades\": [7, 8, 7.6]},\n    {\"name\": \"Jose\", \"date_birth\": \"22-10-2000\", \"grades\": [9.5, 7.5, 8.5]},\n    {\"name\": \"Mau\",\"date_birth\": \"30-09-2000\", \"grades\": [6.5, 9, 10]},\n    {\"name\": \"Chris\", \"date_birth\": \"10-04-2001\",\"grades\": [8.5, 10, 9.5]},\n    {\"name\": \"Marcelo\", \"date_birth\": \"15-12-2000\", \"grades\": [7.5, 10, 5]},\n    {\"name\": \"Edward\", \"date_birth\": \"04-01-2001\", \"grades\": [5.5, 8.8, 9.6]},\n    {\"name\": \"Rodrigo\", \"date_birth\": \"01-06-2002\", \"grades\": [9.4, 5.6, 9.3]}\n]\n\ndef calculate_average(grades):\n    valid_grades = [grade for grade in grades if 0 <= grade <= 10]\n    return sum(valid_grades) / len(valid_grades) if valid_grades else 0\n\ndef get_average_student(student):\n    return {\n        \"name\": student[\"name\"],\n        \"average_grade\": calculate_average(student[\"grades\"])\n    }\n\ndef best_student(student):\n    return student[\"average_grade\"] >= 9\n\ndef parse_date(dob):\n    return datetime.strptime(dob, \"%d-%m-%Y\")\n\ndef get_date_birth(student):\n    return parse_date(student[\"date_birth\"])\n\nstudents_with_averages = list(map(get_average_student, students))\n\nbest_students = list(filter(best_student, students_with_averages))\n\nstudents_by_age = sorted(students, key=get_date_birth)\n\nhighest_grade = 0\nstudent_with_highest_grade = None\n\nfor student in students:\n    for grade in student[\"grades\"]:\n        if grade > highest_grade:\n            highest_grade = grade\n            student_with_highest_grade = student[\"name\"]\n\nprint(\"Estudiantes con sus promedios de calificaciones:\")\nfor student in students_with_averages:\n    print(f\"{student['name']}: {student['average_grade']:.2f}\")\n\nprint(\"\\nMejores Estudiantes(promedio >= 9):\")\nfor student in best_students:\n    print(student[\"name\"])\n\nprint(\"\\nEstudiantes ordenados desde el mas joven:\")\nfor student in students_by_age:\n    print(f\"{student['name']}: {student['date_birth']}\")\n\nprint(f\"La calificacion mas alta es {highest_grade} de {student_with_highest_grade}\")"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/EmmanuelMMontesinos.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Explora el concepto de funciones de orden superior en tu lenguaje \n * creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n */\n\"\"\"\n\n# Funciones de Orden Superior\n'''Acepta función como argumento'''\n\ndef timbre(funcion,sonido):\n    print(\"Suena el timbre:\")\n    funcion(sonido)\n\ndef funcion(sonido):\n    print((sonido + \" \") * 2)\n\n# Pruebas\ntimbre(funcion,\"Ding-Dong\")\n\n'''Devuelve una funcion'''\nimport random\ndef torneo(nombre):\n    def ganador(participantes):\n        ganador = random.choice(participantes)\n        return f\"Ganador del torneo {nombre.upper()} es {ganador}\"\n    return ganador\n\n# Pruebas\ntorneo_wwe = torneo(\"wwe\")\nganador = torneo_wwe([\"Rey Misterio\",\"John Cena\",\"The Rock\"])\nprint(ganador)\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n * lista de calificaciones), utiliza funciones de orden superior para \n * realizar las siguientes operaciones de procesamiento y análisis:\n * x Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n *   y promedio de sus calificaciones.\n * x Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n *   que tienen calificaciones con un 9 o más de promedio.\n * x Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n * X Mayor calificación: Obtiene la calificación más alta de entre todas las\n *   de los alumnos.\n * X Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n\"\"\"\nimport datetime\n\n# Lista de esudiantes\nestudiantes = [\n    {\"nombre\":\"Juan\",\"fecha\":\"5/12/1994\",\"notas\":[5.6,6.2,8.6,5.2,3.4]},\n    {\"nombre\":\"Abel\",\"fecha\":\"12/1/1995\",\"notas\":[9.2,9.4,9.6,9.9,9.5]},\n    {\"nombre\":\"Jose\",\"fecha\":\"7/2/1993\",\"notas\":[5.2,5.8,6.2,5.9,5.4]},\n    {\"nombre\":\"Maria\",\"fecha\":\"21/6/1994\",\"notas\":[7.6,6.4,6.6,7.2,5.4]},\n    {\"nombre\":\"Isabel\",\"fecha\":\"30/10/1995\",\"notas\":[4.6,6.5,7.6,5.7,4.2]},\n]\n\ndef lista(estudiantes,funcion):\n    return funcion(estudiantes)\n\ndef promedio(estudiantes):\n    resultado = []\n    for alumno in estudiantes:\n        ciclo_notas = 0\n        total = 0\n        for notas in alumno[\"notas\"]:\n            total += notas\n            ciclo_notas += 1\n        resultado.append((f\"{alumno[\"nombre\"]}\",total/ciclo_notas))\n        # print(f\"{alumno[\"nombre\"]} -> {total/ciclo_notas}\")\n    return resultado\n\ndef mejores_alumnos(estudiantes):\n    promedio_alumnos = lista(estudiantes,promedio)\n    resultado = [alum for alum in promedio_alumnos if alum[1] >= 9]\n    return resultado\n\ndef mas_joven(estudiantes):\n    resultado = []\n    for estudiante in estudiantes:\n        dia,mes,ano = estudiante[\"fecha\"].split(\"/\")\n        consulta = datetime.datetime(int(ano),int(mes),int(dia)) - datetime.datetime.now()\n        resultado.append((estudiante[\"nombre\"],consulta))\n    resultado.sort(key=lambda x: x[1])\n    solicitud = []\n    for l in resultado:\n        for estudiante in estudiantes:\n            if estudiante[\"nombre\"] == l[0]:\n                solicitud.append((estudiante[\"nombre\"],estudiante[\"fecha\"]))\n    return solicitud\n\ndef mayor_nota(estudiantes):\n    mejor = []\n    for estudiante in estudiantes:\n        mejor_n = 0\n        for nota in estudiante[\"notas\"]:\n            if nota > mejor_n:\n                mejor_n = nota\n        mejor.append((estudiante[\"nombre\"],mejor_n))\n    mejor.sort(key=lambda x: x[1],reverse=True)\n    return mejor\n\n# Pruebas\npromedio_alumnos = lista(estudiantes,promedio)\nmej_alumnos = lista(estudiantes,mejores_alumnos)\nmas_alumnos = lista(estudiantes,mas_joven)\nmay_alumnos = lista(estudiantes,mayor_nota)\n\nprint(promedio_alumnos)\nprint(mej_alumnos)\nprint(mas_alumnos)\nprint(may_alumnos)"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/FedeAirala.py",
    "content": "# #22 FUNCIONES DE ORDEN SUPERIOR\n\"\"\"\n * EJERCICIO:\n * Explora el concepto de funciones de orden superior en tu lenguaje \n * creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n\"\"\"\n\nfrom functools import reduce\n# Función como argumento\n\ndef saludo (func):\n    func()\n    \ndef saludar():\n    print (f\"Hola Mundo\")\n\nsaludo(saludar)\n\n# Función como retorno\n\ndef saludo_2(x):\n    def saludar_2(x):\n        print(x)\n    return saludar_2(x)\n\nsaludo_2(\"Hello world\")\n\n# Funciones de orden superior del sistema\n\nnumeros = [1,3,5,2,4]\n\n# Filter\n\nresultado = filter (lambda x: x%2==1,numeros) # Filtra y etorna números impares\nprint (list(resultado))\n\n# Map\n\nprint (list(map(lambda x: x*2,numeros))) # Realiza el recoorido de la lista operando en cada elemento\n\n# Reduce\n\nprint (reduce(lambda x,y:x*y, numeros)) # Realiza las operaciones en todos los números de la lista de manera acumulativa\n\n# Sorted\n\nprint (sorted(numeros)) # Ordena los elementos de la lista\nprint (sorted(numeros,reverse=True))\n\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n * lista de calificaciones), utiliza funciones de orden superior para \n * realizar las siguientes operaciones de procesamiento y análisis:\n * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n *   y promedio de sus calificaciones.\n * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n *   que tienen calificaciones con un 9 o más de promedio.\n * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n * - Mayor calificación: Obtiene la calificación más alta de entre todas las\n *   de los alumnos.\n * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n\"\"\"\n\nestudiantes = [\n    {\"nombre\": \"Juan\", \"nacimiento\":25/4/1980,\"calificaciones\": [3,8,9,5,6]},\n    {\"nombre\": \"Pedro\", \"nacimiento\":20/3/1990,\"calificaciones\": [3,9,7,5,2]},\n    {\"nombre\": \"María\", \"nacimiento\":11/7/19850,\"calificaciones\": [10,9,9,9,9]}\n]\ndef main():\n    print (\"-\"*60)\n    print (\"Promedio de calificaciones por alumno\")\n    promedio(estudiantes)\n    print (\"-\"*60)\n    print (\"Estudiantes con promedio mayor a 9\")\n    mayor_nueve(estudiantes)\n    print (\"-\"*60)\n    print (\"La calificación más alta entre todos\")\n    mas_alta(estudiantes)\n    print (\"-\"*60)\n    \n    \n    \ndef promedio(estudiante):\n    for elem in estudiante:\n        prom = ((reduce(lambda x,y: x+y,elem[\"calificaciones\"]))/len(elem[\"calificaciones\"]))\n        nombre = elem[\"nombre\"]\n        print (f\"El estudiante {nombre} tiene un promedio de {prom}\")\n\ndef mayor_nueve(estudiante):\n    print (list(\n        map(lambda estudiante: estudiante[\"nombre\"],\n        filter(lambda estudiante: (sum(estudiante[\"calificaciones\"])/len(estudiante[\"calificaciones\"]))>=9,estudiante))))\n\ndef mas_alta(estudiante):\n    print (max(map(lambda estudiante: max(estudiante[\"calificaciones\"]),estudiante)))\n\nif __name__ == \"__main__\":\n    main()\n    \n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/Gordo-Master.py",
    "content": "# Funciones de Orden superior #\n\n# Son funciones que reciben como parametros otras funcion y devuelven otra funcion\n\n# Ejemplos\n# 1. Recibe una función como parametro\n\nfrom datetime import datetime \nfrom functools import reduce\n\ndef do_operation(a, b, operation):\n    return operation(a,b)\n\ndef suma_2_mumeros(a,b):\n    return a + b\n\nprint(do_operation(5,8,suma_2_mumeros))\n\n# 2. Devuelve una función\n\ndef multiplicator_maker(factor):\n    def multiplicator(num):\n        return num * factor\n    return multiplicator\n\ntri = multiplicator_maker(3)\nprint(tri(5))\n\n# 3. Sistema\n\nnumbers = [1, 3, 4, 2, 5]\n\n# map()\n\ndef apply_double(n):\n    return n*2\n\nprint(list(map(apply_double,numbers)))\n\n# filter()\n\ndef is_two(n):\n    return n % 2 == 0\n\nprint(list(filter(is_two,numbers)))\n\n# Sorted()\n\nprint(sorted(numbers))\nprint(sorted(numbers, reverse=True))\nprint(sorted(numbers, key= lambda x: -x))\n\n# Reduce()\n\ndef sum_two(x, y):\n    return x + y\n\nprint(reduce(sum_two, numbers))\n\n###########################################################################################################################\n\"Dificultad extra\"\n###########################################################################################################################\n\n######################### OPCION 1 ################################\n\nstudents_list = [\n    {\"name\": \"Gustavo\", \n    \"birthdate\": datetime.strptime(\"01/02/2015\",\"%d/%m/%Y\"),\n    \"scores\":\n    {\"math\": 6 ,\"english\": 8,\"science\": 5}\n},\n{\"name\": \"Maria\", \n    \"birthdate\": datetime.strptime(\"05/05/2014\",\"%d/%m/%Y\"),\n    \"scores\":\n    {\"math\": 5 ,\"english\": 10,\"science\": 7}\n},\n{\"name\": \"John\", \n    \"birthdate\": datetime.strptime(\"20/10/2016\",\"%d/%m/%Y\"),\n    \"scores\":\n    {\"math\": 10 ,\"english\": 8,\"science\": 10}\n}\n]\n\n# Toma un diccionario de materias y notas, para sacar un promedio total\ndef score_prom(scores: dict):\n    total_sum = 0\n    flag = 0\n    for key, value in scores.items():\n        total_sum += value\n        flag += 1 \n    return total_sum/flag \n\n# Toma un diccionario que tiene el nombre, y le aplica una función al valor del key (name) dado.\ndef student_duo(student: dict, function2, name):\n    return student[\"name\"], function2(student[name])\n\n# print(student_prom(students_list[0],score_prom))\n\n# Forma una lista, a partir de un diccionario mas grande con muchas dependencias, y le apica 2 funciones.\ndef student_form_list(student_list: list, function1,function2, item):\n    list_of_student = []\n    for i in student_list:\n        list_of_student.append(function1(i,function2, item)) \n    return list_of_student\n\n# Toma la lista de estudiantes con su promedio y elige los que tienen mayor promedio que 9\ndef student_best_list(student_form_list):\n    student_list_of_best = []    \n    for i in student_form_list:\n        if i[1]>9:\n            student_list_of_best.append(i)\n    return student_list_of_best\n\n# def student_date(student: dict):\n#     return student[\"name\"], student[\"birthdate\"]\n\ndef identidad(name):\n    return name\n\ndef age(date_given):\n    return date_given.strftime(\"%d/%m/%Y\")\n\nprint(student_form_list(students_list,student_duo,score_prom,\"scores\"))\nprint(student_best_list(student_form_list(students_list,student_duo,score_prom, \"scores\")))\n\nprint(student_duo(students_list[0],identidad,\"birthdate\"))\n\nprint(sorted(student_form_list(students_list,student_duo,identidad,\"birthdate\"),key=lambda x: x[1]))\n\ndef max_score(scores: dict):\n    score_data = list(scores.items())\n    # for key, value in scores.items():\n    return max(score_data, key=lambda x : x[1])\n\nprint(max_score(students_list[0][\"scores\"]))\n\nprint(max(student_form_list(students_list,student_duo,max_score,\"scores\")))\n\n\n\n######################### OPCION 2 ################################\n\nstudents = [\n    {\"name\": \"Brais\", \"birthdate\" : \"29-04-1987\", \"grades\": [5, 8.5, 3, 10]},\n    {\"name\": \"moure\", \"birthdate\" : \"04-08-1995\", \"grades\": [1, 9.5, 2, 4]},\n    {\"name\": \"mouredev\", \"birthdate\" : \"15-12-2000\", \"grades\": [4, 6.5, 5, 2]},\n    {\"name\": \"supermouredev\", \"birthdate\" : \"25-01-1980\", \"grades\": [10, 9, 9.7, 9.9]}\n]\n\ndef average(grades):\n    return sum(grades) / len(grades)\n\n\n# Promedio\n\nprint(\n    list(map(lambda student: {\n        \"name\": student[\"name\"], \n        \"average\": average(student[\"grades\"])},students)\n    )\n)\n\n\n# Mejores\n\nprint(\n    list(map(lambda student: \n        student[\"name\"], \n        filter(lambda student: average(student[\"grades\"]) >= 9 ,students)\n        )\n    )\n)\n\n# Fecha de nacimiento ordenada\n\nprint(sorted(students, key= lambda student: datetime.strptime(\n    student[\"birthdate\"], \"%d-%m-%Y\"), reverse= True))\n\n\n# Calificación mas alta\n\nprint(max(list(map(lambda student: max(student[\"grades\"]), students))))"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/Irenetitor.py",
    "content": "from functools import reduce\nfrom datetime import datetime\n\n#Exercise\n\ndef winner(name):\n    return f\"The winner is {name}\"\n\ndef candidate_winner(name, func):     #Passing a function as an argument\n    return func(name)\n\nprint(candidate_winner(\"Samuel\", winner))\n\n\n\ndef division(n):\n    def operation(x):\n        return n // x         #Returning a function\n    return operation\n\nhalf = division(12)\n\nprint(half(2))\nprint(division(16)(4))\n\n\n#------------------------------\n#Built-in Higher-Order Functions\n\nnums = [1, 2, 3, 4]\n\nresult = map(lambda x: x * 2, nums)    #map(function, iterable)\nprint(list(result))\n\n\nnums = [2, 3, 4, 6, 7, 9, 12]\n\nodds = filter(lambda x: x % 3 == 0, nums)     #filter(function, iterable)\nprint(list(odds))\n\n\nnums = [3, 6, 8, 5]\n\ntotal = reduce(lambda a, b: a + b, nums)      #reduce(function, iterable)\nprint(total)\n\nsorted([\"Irene\", \"Alex\", \"Michael\"], key=len)  #sorted() (if you pass a function)\n\n#Extra Exercise\n\nstudents = [\n    {\"name\": \"Lola\", \"birthday\": \"23-05-1997\", \"grades\": [7, 4.7, 6, 9]},\n    {\"name\": \"Rose\", \"birthday\": \"06-07-1993\", \"grades\": [6, 5.7, 7.7, 3.9]},\n    {\"name\": \"Valentino\", \"birthday\": \"12-02-1995\", \"grades\": [8.3, 6.7, 4.8, 10]},\n    {\"name\": \"Irene\", \"birthday\": \"12-02-1995\", \"grades\": [8.3, 9.7, 9.8, 10]},\n    {\"name\": \"Galileo\", \"birthday\": \"12-02-1995\", \"grades\": [6, 8.9, 7.8, 9.6]},\n    {\"name\": \"Kate\", \"birthday\": \"12-02-1995\", \"grades\": [9, 7, 10, 10]}\n]\n\ndef average(grades):\n    return sum(grades) / len(grades)\n\n#Average\nprint(\n    list(map(lambda student: {\n        \"name\": student[\"name\"],\n        \"average\": average(student[\"grades\"])}, students)\n    )\n)\n\n#Best students\nprint(\n    list(\n        map(lambda student: \n            student[\"name\"],\n            filter(lambda student: average(student[\"grades\"]) >= 9, students)\n            )\n        )\n    )\n\n#List of students from youngest to oldest\nprint(\n    list(\n        map(lambda student: \n            student[\"name\"],\n            sorted(students, key=lambda student: datetime.strptime(\n            student[\"birthday\"], \"%d-%m-%Y\"), reverse=True)))\n)\n\n#Highest grade\n\nprint(\n    max(map(lambda student: max(student[\"grades\"]), students))\n)"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/JesusWay69.py",
    "content": "import os\nos.system('cls')\nfrom datetime import datetime as DT\n\n\"\"\"* EJERCICIO:\n * Explora el concepto de funciones de orden superior en tu lenguaje \n * creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n *\n\"\"\"\n\ndef operator(fun:str):#Función de orden superior\n    def sum(num1:int,num2:int)->int:#Función secundaria\n        return num1+num2\n    def multiplication(num1:int,num2:int)->int:#Función secundaria\n        return num1*num2\n    def substraction(num1:int,num2:int)->int:#Función secundaria\n        return num1-num2\n    def division (num1:int,num2:int)->int:#Función secundaria\n        try:                                            \n           return num1/num2\n        except ZeroDivisionError as zde:\n            print(\"ERROR:\",zde) \n    def pow (num1:int,num2:int)->int:#Función secundaria\n        return num1**num2\n    if fun == '+':#Condicional para función de orden superior\n        return sum #Retorno de resultado de función secundaria\n    elif fun == '-':#Condicional para función de orden superior\n        return substraction#Retorno de resultado de función secundaria\n    elif fun == '*':#Condicional para función de orden superior\n        return multiplication#Retorno de resultado de función secundaria\n    elif fun == \"**\":#Condicional para función de orden superior\n        return pow#Retorno de resultado de función secundaria\n    elif fun == '/':#Condicional para función de orden superior\n        return division#Retorno de resultado de función secundaria\n    else:\n        print(\"Operador incorrecto\")\n    \nprint(operator('+')(6,5))#Llamada a función de orden superior asignando en los primeros paréntesis\n# su argumento y dentro del paréntesis siguiente los argumentos de la función secundaria a la que llama la primera\nresta = operator('-')#También se puede almacenar en una variable la llamada a la función de orden superior\nprint(resta(456,89.5))# con su argumento y pasarle a esta variable después los argumentos de la secundaria \nsuma = operator('+')\nmultiplicacion = operator('*')\ndivision = operator('/')\npotencia = operator(\"**\")\nprint (suma(485,896),\"\",division(4,0),\"\",potencia(2,8),\"\",multiplicacion(14,24))\nprint('\\n\\n\\n\\n')\n\n\"\"\" * DIFICULTAD EXTRA (opcional):\n * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n * lista de calificaciones), utiliza funciones de orden superior para\n * realizar las siguientes operaciones de procesamiento y análisis:\n * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n *   y promedio de sus calificaciones.\n * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n *   que tienen calificaciones con un 9 o más de promedio.\n * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n * - Mayor calificación: Obtiene la calificación más alta de entre todas las\n *   de los alumnos.\n * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\"\"\"\n\nstudents_list = [\n                 [\"Ana\", DT.strptime('31/1/1997', '%d/%m/%Y'), [10, 9.9, 8.8, 9.6, 8.7, 9.5, 9.2, 8.9, 9.9, 10]],\n                 [\"Carlos\", DT.strptime('21/3/1986', '%d/%m/%Y'), [8, 9.9, 8, 9.9, 8.7, 9.8, 9, 8.8, 9, 10, 6.9]],\n                 [\"Jesus\", DT.strptime('26/12/1974', '%d/%m/%Y'), [9.8, 8.3, 7.8, 9.9, 10, 9.7, 9.6, 9.7, 9.3]],\n                 [\"Leire\", DT.strptime('2/11/1991', '%d/%m/%Y'), [9.5, 9.7, 9.8, 9.3, 7.7, 9, 9, 8.7, 9.9, 8.9]],\n                 [\"Pablo\", DT.strptime('14/8/1982', '%d/%m/%Y'), [6.5, 7.3, 8, 9.6, 5, 8.5, 9, 9.8, 8, 9.6, 9]],\n                 [\"Sandra\", DT.strptime('24/3/1989', '%d/%m/%Y'), [6.2, 9.6, 7.9, 8, 7.8, 8.4, 9, 7.8, 9.8, 8.6]],\n                 [\"Sara\", DT.strptime('11/6/1991', '%d/%m/%Y'), [9.7, 9.7, 7.8, 9.9, 7.8, 9.5, 9.3, 9.7, 9.9, 10]],\n                 [\"Steven\", DT.strptime('10/2/1994', '%d/%m/%Y'), [9.7, 9.1, 8.8, 7.3, 7.9, 9.8, 9, 6.7, 10, 9]]\n                 ]\n\ndef students(option:int):\n\n    def avg_grade(students_list:list)->dict:\n        grade_list = []\n        names_list = []\n        acc = 0\n        for student in students_list:\n            names_list.append(student[0])\n            for grade in student[2]:\n                acc = grade + acc\n                grade = 0\n            grade_list.append(round(acc/len(student[2]),1))\n            acc = 0\n        if option == 1:\n            print(\"Nota media de los alumnos: \\n\")\n            for name, avg in zip(names_list,grade_list) :\n                print('{:<10}'.format(name),\" Nota media:\", avg)\n        name_grades_dict = {name:avg for name, avg in zip(names_list,grade_list)}     \n        return name_grades_dict\n\n\n    def best(students_list:list):\n      best_students = avg_grade(students_list)\n      print(\"Estudiantes con un 9 o más de nota media: \\n\")\n      for name,grade_over_nine in best_students.items():                                                                \n          if grade_over_nine >= 9:\n              print ('{:<10}'.format(name), \"-  Nota media:\", grade_over_nine)\n\n\n    def sorted_age(students_list:list):\n        print(\"Lista de estudiantes ordenados desde el más joven:\\n\")\n        sorted_age_list = sorted(students_list, key=lambda student: student[1], reverse=True)\n        for student in sorted_age_list:\n            birth_date = student[1].strftime('%d/%m/%Y')\n            print('{:<10}'.format(student[0]), \"-  Fecha de nacimiento:\", birth_date)\n    \n\n    def hight_grade(students_list:list):\n        print(\"Lista de estudiantes con su nota más alta: \\n\")\n        for student in students_list:\n            hightest = 0\n            name = student[0]\n            for grade in student[2]:\n                if grade > hightest:\n                    hightest = grade\n            print ('{:<10}'.format(name), \"-  Calificación más alta: \",hightest)\n\n    if option == 1:\n        return avg_grade\n    if option == 2:\n        return best\n    if option == 3:\n        return sorted_age\n    if option == 4:\n        return hight_grade\n    \nwhile True:\n    option = input(\"\"\"\\nElija una opción:\\n1-Mostrar la nota media de todos los alumnos\\n2-Mostrar los alumnos con nota media igual o superior a 9\n3-Mostrar todos los alumnos ordenados por fecha de nacimiento desde el más joven\\n4-Mostrar todos los alumnos con su nota más alta\\n5-Salir\\n---> \"\"\")\n    if option == \"5\":\n        break\n    elif option.isdigit():\n        if int(option) > 4 or int(option) < 1:\n            print(\"Solo se pueden introducir números del 1 al 5, intente de nuevo o pulse 5 para salir\\n\") \n            print()       \n        else:\n            students(int(option))(students_list)\n            break\n    else:\n        print(\"Solo se pueden introducir números del 1 al 5, intente de nuevo o pulse enter para salir\") \n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/JheisonQuiroga.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Explora el concepto de funciones de orden superior en tu lenguaje \n * creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n\"\"\"\n\n# 1. Ejemplo 1\n# Asignando una función a una variable\ndef greet(name):\n    return f\"Hello, {name}!\"\n\ngreet_someone = greet\nprint(greet_someone(\"Duban\")) # Hello, Duban!\n\n# 2. Ejemplo 2\n# Pasando una función como argumento y retornando una función\ndef call_function(func, name):\n    return func(name)\n\nprint(call_function(greet, \"Duban\")) # Hello, Duban!\n\n# 3. Ejemplo 3\n# Retornando una función\ndef compose_greet_func():\n    def greet(name):\n        return f\"Hello, {name}!\"\n    return greet\n\n\ngreet_function = compose_greet_func()\nprint(greet_function(\"Duban\")) # Hello, Duban!\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n * lista de calificaciones), utiliza funciones de orden superior para\n * realizar las siguientes operaciones de procesamiento y análisis:\n * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n *   y promedio de sus calificaciones.\n * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n *   que tienen calificaciones con un 9 o más de promedio.\n * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n * - Mayor calificación: Obtiene la calificación más alta de entre todas las\n *   de los alumnos.\n * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n */\n\"\"\"\nfrom datetime import datetime\nfrom typing import List, Tuple\nfrom functools import reduce\nimport textwrap\n\nclass Student:\n    def __init__(self, name: str, birthday: str, qualifications: List[float]) -> None:\n        self.name = name\n        self.birthday = datetime.strptime(birthday, \"%d/%m/%Y\")\n        # Validando las calificaciones entre 0 - 10\n        for grade in qualifications:\n            if not 0 <= grade <= 10:\n                raise ValueError(f\"La calificación {grade} no se encuentra en el rango válido [0 - 10]\")\n            \n        self.qualifications = qualifications\n\n    def __str__(self) -> str:\n        return f\"{self.name}, fecha de nacimiento: ({self.birthday.strftime(\"%d/%m/%Y\")}, calificaciones: {self.qualifications})\"\n    \n    def average(self):\n        average = round(sum(self.qualifications) / len(self.qualifications), 2)\n        return average\n    \n    def outstanding_student(self) -> bool:\n        \"\"\"Determina si el estudiante tiene un promedio de 9 o superior\"\"\"\n        return self.average() >= 9\n    \n    # Método para obtener la lista de promedios\n    @classmethod\n    def get_averages(cls, student_list: List['Student']) -> List[Tuple[str, float]]:\n        averages = map(lambda student: (student.name, student.average()), student_list)\n        return list(averages)\n    \n    # Método de clase para obtener los mejores estudiantes\n    @classmethod\n    def best_students(cls, students: List['Student']) -> List[Tuple[str, float]]:\n        return list(map(\n            lambda e: (e.name, e.average()), filter(lambda e: e.outstanding_student(), students)))\n    \n    @classmethod\n    def youngest_student(cls, students:List['Student']):\n        \"\"\"Método para obtener a los estudiantes mas joves, utiliza una función de orden superior\n        que es sorted\"\"\"\n        sorted_students = sorted(students, key=lambda e: e.birthday, reverse=True)\n        return list(map(lambda e: (e.name, e.birthday.strftime(\"%d/%m/%Y\")), sorted_students))\n    \n    @classmethod\n    def best_qualification(cls, students: List['Student']):\n        all_qualifications = [qualification for est in students for qualification in est.qualifications]\n        return reduce(\n            lambda a, b: a if a > b else b, map(\n                lambda qual: qual, all_qualifications \n            )\n        )\n    \nstudents = [\n    Student(\"Duban\", \"19/06/1998\", [9.9, 9.0, 9.1]),\n    Student(\"Anderson\", \"13/08/2005\", [1.0, 3.5, 8.0]),\n    Student(\"Josman\", \"05/05/2000\", [9.0, 8.5, 9.5])\n]\n\nif __name__ == \"__main__\":\n    print(textwrap.dedent(f\"\"\"\\\n        {\"-\" * 5}Resultados del analísis{\"-\" * 5}\n        1. Promedio de calificaciones:\\\n\"\"\"))\n    for name, average in Student.get_averages(students):\n        print(f\"{' ' * 5} - {name}: {average} \")\n    \n    print(\"2. Mejores estudiantes:\")\n    for name, average in Student.best_students(students):\n        print(f\"{' ' * 5} - {name}: {average} \")\n\n    print(\"3. Estudiantes más jovenes:\")\n    for name, birthday in Student.youngest_student(students):\n        print(f\"{' ' * 5} - {name}: {birthday} \")\n\n    print(\"4. Mejor calificación:\")\n\n    print(\" \" * 5, \"-\", Student.best_qualification(students))"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/JuanDAW37.py",
    "content": "\"\"\"* EJERCICIO:\n * Explora el concepto de funciones de orden superior en tu lenguaje \n * creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n *\n * DIFICULTAD EXTRA (opcional):\n * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n * lista de calificaciones), utiliza funciones de orden superior para\n * realizar las siguientes operaciones de procesamiento y análisis:\n * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n *   y promedio de sus calificaciones.\n * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n *   que tienen calificaciones con un 9 o más de promedio.\n * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n * - Mayor calificación: Obtiene la calificación más alta de entre todas las\n *   de los alumnos.\n * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\"\"\"\n\nfrom functools import reduce\nimport datetime\n\n# Pueden recibir funciones como parámetros\ndef funcSuperior(funcion, param): # Recibe una función y un parámetro\n    return funcion(param) \n\nlongitud = funcSuperior(len, 'Juan') # Se pasa la función len, propia de Python, y una cadena, para que devuelva la longitud de dicha cadena.\nprint(f'La longitud del parámetro es -> {longitud}')\n\n# Pueden devolver funciones como resultado\ndef aplicarOperacion(operando1, operador):\n    def operacion(operando2):\n        if operador == '+':\n            return operando1 + operando2\n        elif operador == '-':\n            return operando1 - operando2\n        elif operador == '*':\n            return operando1 * operando2\n        elif operador == '/':\n            return operando1 / operando2\n        else:\n            return 'Operador no soportado o incorrecto'\n    return(operacion) # Devuelve la función operacion\n\n# Aplicar la operación \nresultado = aplicarOperacion(3,'+') # resultado va a contener una función\nprint(resultado(4)) # A la función retornada, le envío el argumento restante para completar la operación\nprint(aplicarOperacion(4, '+')(5)) # Otra forma de llamarla\n\n# Hay funciones de orden superior, propias de Python\n# map(): Aplica una función a cada elemento de una lista\nletras = ['A', 'B', 'H', 'Y', 'J', 'P', 'R']\ndef ordenar(letras):\n    return sorted(letras)\n\nordenacion = map(ordenar, letras)\nprint(list(ordenacion))\n\n# filter(): Aplica una función a cada elemento de una lista y devuelve los elementos que cumplen\ndef mayorQue5(num):\n    return num > 5\n\nprint(list(filter(mayorQue5, [6,4,8,14])))\n\n# sorted() Ordena una lista\nprint(sorted(letras))\nprint(sorted(letras, reverse=True)) # Ordena en sentido inverso\nprint(sorted([6,4,8,14], key=lambda n: -n)) # Aquí se usa una lambda: Funciones anónimas a las que se le envía la lista, en este caso, y se recibe la lista ordenada al revés\n\n# reduce(): Aplica una función a cada elemento de una lista y devuelve el resultado final. Tenemos que importarla de functools\ndef sumar(x, y):\n    return x + y\n\nprint(reduce(sumar, [6,4,8,14])) # Devuelve la suma de los elementos de toda la lista (6 + 4 + 8 +14) = 32\n\n# EXTRA\nestudiantes = [\n    {'nombre': 'Juan', 'fecha_nacimiento':'01-05-1968', 'notas':[7,8,9]},\n    {'nombre': 'Mónica', 'fecha_nacimiento':'04-05-1968', 'notas':[8,7,9]},\n    {'nombre': 'Luis', 'fecha_nacimiento':'06-07-1999', 'notas':[6,7,8]}\n    ]\n# Promedio calificaciones: Obtiene una lista de estudiantes por nombre y promedio de sus calificaciones.\ndef media(notas):\n    return sum(notas) / len(notas)\n\nprint(list(map(lambda estudiante:{'nombre':estudiante['nombre'], \n                                'media':media(estudiante['notas'])}, estudiantes)))\n#  Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes que tienen calificaciones con un 9 o más de promedio.\n\nprint(list(map(lambda estudiante: \n    estudiante['nombre'], filter(lambda estudiante: media(estudiante['notas']) >= 9, estudiantes))))\n\n# Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\nprint(list(sorted(estudiantes,  key=lambda estudiante: datetime.datetime.strptime(estudiante['fecha_nacimiento'], '%d-%m-%Y'), reverse = True)))\n\n# Mayor calificación: Obtiene la calificación más alta de entre todas las de los alumnos.\nprint(max(map(lambda estudiante: max(estudiante['notas']), estudiantes)))"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/LucasRebuffo.py",
    "content": "\"\"\" Orden superior \"\"\"\n\nfrom datetime import datetime\nfrom functools import reduce\n\n\ndef apply_func(func, x):\n    return func(x)\n\n\nprint(apply_func(len, \"Lucas\"))\n\n\ndef apply_multiplier(n):\n    def multiplier(x):\n        return x * n\n\n    return multiplier\n\n\nmultiplier = apply_multiplier(2)\n\nprint(multiplier)\nprint(multiplier(5))\n\n# Funciones del sistema\n\n# MAP\nnumeros = [2, 54, 8, 79, 454, 6]\nmapped_numeros = map(lambda n: n * 2, numeros)\nprint(mapped_numeros)\nprint(list(mapped_numeros))\n\n# FILTER\nfiltered_numeros = filter(lambda x: x % 2 == 0, numeros)\nprint(filtered_numeros)\nprint(list(filtered_numeros))\n\n# SORTED\nsorted_numeros = sorted(numeros)\nsorted_numeros_2 = sorted(numeros, reverse=True)\nsorted_numeros_3 = sorted(numeros, key=lambda x: x % 2 == 0)\nprint(sorted_numeros)\nprint(sorted_numeros_2)\nprint(sorted_numeros_3)\n\n# REDUCE\nnombre = [\"L\", \"U\", \"C\", \"A\", \"S\"]\nconcated_nombre = reduce(lambda x, y: x + y, nombre)\nadded_numeros = reduce(lambda x, y: x + y, numeros)\nprint(added_numeros)\nprint(concated_nombre)\n\n\n# EXTRA\n\nestudiantes = [\n    {\"nombre\": \"Martin\", \"fecha_nac\": \"15-06-2000\", \"notas\": [7, 8, 6, 9.5, 9.9, 3]},\n    {\"nombre\": \"Lucas\", \"fecha_nac\": \"10-02-1997\", \"notas\": [9, 8, 8, 9.5, 10, 9.9]},\n    {\"nombre\": \"Marta\", \"fecha_nac\": \"20-04-1998\", \"notas\": [5, 6, 7, 9.5, 5, 8]},\n]\n\n\n# PROMEDIOS\ndef promedio(notas: list):\n    return sum(notas) / len(notas)\n\n\npromedios = list(\n    map(\n        lambda x: {\"nombre\": x[\"nombre\"], \"promedio\": promedio(x[\"notas\"])}, estudiantes\n    )\n)\nprint(promedios)\n\n\n# MEJORES ESTUDIANTES\nmejores_estudiantes = list(filter(lambda x: x[\"promedio\"] >= 9.0, promedios))\nprint(mejores_estudiantes)\n\n# ORDENACION POR FECHA DE NACIMIENTO\nestudiantes_ordenados = sorted(\n    estudiantes,\n    key=lambda x: datetime.strptime(x[\"fecha_nac\"], \"%d-%m-%Y\"),\n    reverse=True,\n)\nprint(estudiantes_ordenados)\n\n# CALIFICACION MAS ALTA\n\ncalificacion_mas_alta = sorted(\n    list(\n        map(\n            lambda x: {\"nombre\": x[\"nombre\"], \"nota_max\": max(x[\"notas\"])},\n            estudiantes,\n        )\n    ),\n    key=lambda x: x[\"nota_max\"],\n    reverse=True,\n)[0]\n\nprint(calificacion_mas_alta)\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/Mauricio-Leyva.py",
    "content": "\"\"\"\nEJERCICIO:\nfunciones de orden superior\n\"\"\"\n\n# Ejemplo 1: Funciones como argumentos\ndef apply_function(func, value):\n    return func(value)\n\ndef square(x):\n    return x * x\n\ndef double(x):\n    return x * 2\n\nresult_square = apply_function(square, 5)\nresult_double = apply_function(double, 5)\n\nprint(f\"apply_function(square, 5) = {result_square}\")  \nprint(f\"apply_function(double, 5) = {result_double}\")\n\n# Ejemplo 2: Funciones que retornan otras funciones\ndef create_multiplier(multiplier):\n    def multiplier_function(x):\n        return x * multiplier\n    return multiplier_function\n\ndouble = create_multiplier(2)\ntriple = create_multiplier(3)\n\nprint(f\"double(5) = {double(5)}\")  # Salida: 10\nprint(f\"triple(5) = {triple(5)}\")  # Salida: 15\n\n#Ejemplo 3: Usando map, filter y reduce\nfrom functools import reduce\n\nnumbers = [1, 2, 3, 4, 5]\nsquared_numbers = list(map(lambda x: x ** 2, numbers))\nprint(f\"map(lambda x: x ** 2, numbers) = {squared_numbers}\")  \n\neven_numbers = list(filter(lambda x: x % 2 == 0, numbers))\nprint(f\"filter(lambda x: x % 2 == 0, numbers) = {even_numbers}\")  \n\nproduct = reduce(lambda x, y: x * y, numbers)\nprint(f\"reduce(lambda x, y: x * y, numbers) = {product}\")  \n\n\n\"\"\"\nExtra:\n\"\"\"\nfrom datetime import datetime\nfrom functools import reduce\n\nstudents = [\n    {\"name\": \"Ana\", \"dob\": \"2005-04-23\", \"grades\": [8.5, 9.0, 7.5]},\n    {\"name\": \"Carlos\", \"dob\": \"2004-07-15\", \"grades\": [9.5, 9.0, 8.5]},\n    {\"name\": \"Beatriz\", \"dob\": \"2006-01-10\", \"grades\": [6.0, 7.5, 8.0]},\n    {\"name\": \"David\", \"dob\": \"2003-12-11\", \"grades\": [7.0, 6.5, 6.0]},\n    {\"name\": \"Elena\", \"dob\": \"2005-10-29\", \"grades\": [10.0, 9.5, 9.0]},\n]\n\n# 1. Promedio calificaciones\ndef calculate_average(grades):\n    return sum(grades) / len(grades)\n\naverage_grades = list(map(lambda student: {\"name\": student[\"name\"], \"average\": calculate_average(student[\"grades\"])}, students))\n\nprint(\"Promedio de calificaciones:\")\nfor student in average_grades:\n    print(f\"{student['name']}: {student['average']:.2f}\")\n\n# 2. Mejores estudiantes\ntop_students = list(filter(lambda student: calculate_average(student[\"grades\"]) >= 9, students))\ntop_students_names = list(map(lambda student: student[\"name\"], top_students))\n\nprint(\"Mejores estudiantes:\")\nprint(top_students_names)\n\n# 3. Nacimiento\ndef parse_date(date_str):\n    return datetime.strptime(date_str, \"%Y-%m-%d\")\n\nsorted_students_by_age = sorted(students, key=lambda student: parse_date(student[\"dob\"]), reverse=True)\n\nprint(\"Estudiantes ordenados desde el más joven:\")\nfor student in sorted_students_by_age:\n    print(f\"{student['name']} ({student['dob']})\")\n\n# 4. Mayor calificación\nall_grades = reduce(lambda acc, student: acc + student[\"grades\"], students, [])\nhighest_grade = max(all_grades)\n\nprint(f\"La calificación más alta es: {highest_grade}\")\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/Nicojsuarez2.py",
    "content": "# #22 FUNCIONES DE ORDEN SUPERIOR\n> #### Dificultad: Difícil | Publicación: 27/05/24 | Corrección: 03/06/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Explora el concepto de funciones de orden superior en tu lenguaje \n * creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n *\n * DIFICULTAD EXTRA (opcional):\n * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n * lista de calificaciones), utiliza funciones de orden superior para \n * realizar las siguientes operaciones de procesamiento y análisis:\n * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n *   y promedio de sus calificaciones.\n * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n *   que tienen calificaciones con un 9 o más de promedio.\n * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n * - Mayor calificación: Obtiene la calificación más alta de entre todas las\n *   de los alumnos.\n * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/Rikmij.py",
    "content": "#Una función de orden superior es aquella función que toma otra función como parámetro\ndef reverse(text:str):\n    #vamos a separar los elementos del texto en cada espacio, por palabras\n    words = text.split(\" \")\n    reversed_text = []\n\n    for element in words:\n        #agregamos cada elemento al revés en una nueva lista\n        reversed_text.append(element[::-1])\n    \n    #la función devolverá el texto con cada palabra invertida pero en el mismo orden.\n    #convertimos la lista a un string, que se una por cada espacio (por palabras)\n    return \" \".join(reversed_text)\n\ndef invert_word(text, fun):\n    return fun(text)\n\nprint(invert_word(\"Hola hackermen\", reverse))\n\n\nprint(\"\\n ------- EJERCICIO EXTRA -------\")\nimport datetime\n\n#función para especificar que se ordene por el 2º elemento de una lista (edad) en el formato dd/mm/YYYY\ndef sort_by_date(elem):\n    return datetime.datetime.strptime(elem[1], '%d/%m/%Y')\n\nstudent1 = [\"María\", \"17/2/1998\", [9, 7, 3, 8, 5]]\nstudent2 = [\"Peque\", \"3/6/2004\", [9, 10, 9, 10, 9]]\nstudent3 = [\"Jose\", \"20/9/1995\", [6, 8, 5, 3, 4]]\nstudents = [student1, student2, student3]\n\ndef average_marks(student):\n    marks = student[2]\n\n    total = 0\n    for mark in marks:\n        total += mark\n    average = total/len(marks)\n\n    return average\n\ndef students_marks(students:list):\n    for student in students:\n        print(f\"El alumno {student[0]} tiene una media de {average_marks(student)}\")\n\ndef best_students(students_list):\n    for student in students_list:\n        if average_marks(student) > 9:\n            print(f\"El alumno {student[0]} tiene un promedio de {average_marks(student)}, que es mayor que 9\")\n\ndef sort_age_students(students:list):\n    students.sort(key=sort_by_date, reverse=True)\n    student_name = []\n\n    for student in students:\n        student_name.append(student[0])\n    \n    print(\" < \".join(student_name), end=\"\\n\")\n\ndef sorted_marks(students:list):\n    best_mark = []\n    for student in students:\n        marks = student[2]\n        marks.sort()\n        best_marks = marks[-1]\n        best_mark.append(best_marks)\n\n        print(f\"La mejor nota de {student[0]} es {best_marks}\")\n    \n    best_mark.sort()\n    print(f\"La mejor nota es un {best_mark[-1]}\")\n\ndef interface(students, fun1, fun2, fun3, fun4):\n    print(\"-> DATOS DE ALUMNOS\")\n    for student in students:\n        print(f\"{student[0]} nacido el {student[1]}\")\n    \n    print(\"-- PROMEDIOS --\")\n    fun1(students)\n\n    print(\"-- MEJORES ESTUDIANTES --\")\n    fun2(students)\n\n    print(\"-- DEL ALUMNO MENOR AL MAYOR --\")\n    fun3(students)\n\n    print(\"-- MEJORES NOTAS --\")\n    fun4(students)\n    \ninterface(students, students_marks, best_students, sort_age_students, sorted_marks)\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/Sac-Corts.py",
    "content": "from datetime import datetime\n\ndef processOperation(a, b, operation):\n    return operation(a, b)\n\ndef addition(a, b):\n    return a + b\n\nprint(processOperation(4, 10, addition))\n\n### Ejercicio Extra ###\n\nstudents = [\n    {\"name\": \"Isaac\", \"birthdate\": \"2001-10-21\", \"notes\": [10, 10, 10]},\n    {\"name\": \"Marco\", \"birthdate\": \"2001-05-02\", \"notes\": [6, 8.9, 7.6]},\n    {\"name\": \"Felix\", \"birthdate\": \"2001-06-11\", \"notes\": [9.2, 9.8, 10]},\n    {\"name\": \"Jenni\", \"birthdate\": \"2001-03-28\", \"notes\": [8.5, 8.9, 7]},\n    {\"name\": \"Karen\", \"birthdate\": \"2001-01-13\", \"notes\": [8.2, 8.8, 8]},\n]\n\nprint(students)\n\ndef average(notes):\n    return sum(notes) / len(notes)\n\naverages = list(map(lambda student: {\n    \"name\": student[\"name\"],\n    \"average\": round(average(student[\"notes\"]), 1)\n}, students))\nprint(averages)\n\nbest_students = list(filter(lambda student: student[\"average\"] >= 9, averages))\nprint(best_students)\n\nordered_students = sorted(students, key=lambda student: datetime.strptime(student[\"birthdate\"], \"%Y-%m-%d\"), reverse=True)\nfor student in ordered_students:\n    print(f\"{student[\"name\"]}, {student[\"birthdate\"]}\")\n\nbest_average = max(averages, key=lambda student: student[\"average\"])\nprint(best_average)"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/SooHav.py",
    "content": "# 22 - FUNCIONES DE ORDEN SUPERIOR\nfrom datetime import datetime\nfrom functools import reduce\n\n# Ejercicio\n\n\ndef operacion(x1, x2, fun):\n    return fun(x1, x2)\n\n\ndef sumar(x1, x2):\n    return x1+x2\n\n\ndef restar(x1, x2):\n    return x1-x2\n\n\nresultado = operacion(1, 2, restar)\nprint(resultado)\n\n# Filter\nlista = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]\npares = list(filter(lambda x: x % 2 == 0, lista))\nprint(pares)\n\n# Map\nlista = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]\ncubo = list(map(lambda x: x**3, lista))\nprint(cubo)\n\n# Reduce\nlista = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]\nsumacum = reduce(lambda a, b: a+b, lista)\nprint(sumacum)\n\n# Dificultad Extra\n\nestudiantes = [\n    (\"Juan\", \"26-02-2010\", [6, 8, 9.5]),\n    (\"Sofia\", \"13-05-2010\", [8.5, 9.8, 9.5]),\n    (\"Julia\", \"13-06-2010\", [9, 8.5, 10]),\n    (\"Pedro\", \"16-03-2010\", [6, 7, 7.5])\n]\n\n\ndef calcular_promedio(notas):\n    return round(sum(notas) / len(notas), 2)\n\n\npromedio_estudiantes = [(estudiante[0], calcular_promedio(\n    estudiante[2])) for estudiante in estudiantes]\nprint(\"Lista de las notas promedio de cada estudiante:\")\nprint(promedio_estudiantes)\n\nmaximo = max([calcular_promedio(estudiante[2]) for estudiante in estudiantes])\nprint(\"Nota máxima del curso:\")\nprint(maximo)\n\nmejores_estudiantes = [estudiante[0] for estudiante in (\n    list(filter(lambda x: x[1] >= 9, promedio_estudiantes)))]\nprint(\"Lista de los mejores estudiantes:\")\nprint(mejores_estudiantes)\n\n\ndef convertir_fecha(fecha_str):\n    return datetime.strptime(fecha_str, \"%d-%m-%Y\")\n\n\nprint(\"Lista por fecha de nacimiento de los estudiantes:\")\norden = sorted(estudiantes, key=lambda x: convertir_fecha(x[1]), reverse=True)\nfor estudiante in orden:\n    print(estudiante)\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/Trufoplus.py",
    "content": "###############################################################################\n### EJERCIOCIO\n###############################################################################\ndef high_order_function(function, name:str):\n    \"\"\"\n    Una funcion que recibe otra funcion como argumento\n    \"\"\"\n    #Llama a la funcion con el nombre proporcionado\n    function(name)\n\ndef greeting(name:str):\n    \"\"\"\n    Simplemente devuelve un saludo\n    \"\"\"\n    print(f'Hola {name}, ¿Como estas?')\n\n#Ejemplo de uso: le pasamos la funcion y mi nombre.\nhigh_order_function(greeting, 'Dani')\n\n\n\n###############################################################################\n### DIFICULTAD EXTRA\n###############################################################################\n\n# DATOS:\nnames = ['Dani', 'Moure', 'Juanito', 'Conchita']\nbirthdates = [1989, 1986, 1990, 1970]\ngrades = [9,10,4,7]\nstudents_list = list(zip(names, birthdates, grades))\n\n\ndef main(function, student_list:list):\n    \"\"\"\n    Llama a la funcion y le pasa el listado de alumnos\n    \"\"\"\n    function(students_list)\n\n\ndef sort_by_grades(students_list):\n    \"\"\"\n    Ordena a los estudiantes por calificaicon mas alta a la mas baja\n    \"\"\"\n    students_list = sorted(students_list, key = lambda x: x[2])\n    print('\\nLista de estudiantes ordenada por notas:')\n    show_list(students_list)\n\n \ndef best_student(students_list):\n    \"\"\"\n    Muestra a los estudiantes con mas de 8 de calificacion\n    \"\"\"\n    students_list = list(filter(lambda x: x[2]>8, students_list))\n    print('\\nLos mejores estudiantes son:')\n    show_list(students_list)\n\n\ndef sort_by_age(students_list):\n    \"\"\"\n    Ordena a los estudiantes por edad de menor a mayor\n    \"\"\"\n    students_list = sorted(students_list, key=lambda x: x[1], reverse=True)\n    print('\\nLista Estudiantes ordenados por edad de menor a mayor: ')\n    show_list(students_list)\n\n\ndef best_grade(students_list):\n    \"\"\"\n    Muestra la calificacion mas alta\n    \"\"\"\n    students_list = max(students_list, key=lambda x: x[2])\n    print('\\nEl mejor estudiante es: ')\n    print(students_list)\n\n\ndef show_list(students_list):\n    \"\"\"\n    Muestra el resultado por pantalla\n    \"\"\"\n    for student in students_list:\n        print(student)\n\n     \nmain(sort_by_grades, students_list)\nmain(best_student, students_list)\nmain(sort_by_age, students_list)\nmain(best_grade, students_list)\n\n            \n \n \n    "
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/a-mayans.py",
    "content": "from datetime import datetime\n\n### Ejercicio ###\n\n# simple\ndef operation(x, fun):\n  return fun(x)\n\ndef squere_root(x):\n  return x**0.5\n\ndef squared(x):\n  return x**2\n\nresult_1 = operation(16, squere_root)\nresult_2 = operation(8, squared)\nprint(result_1)\nprint(result_2)\n\n# Otras funciones de orden superior podrian ser Filter, map, reduce...\n# Ejemplo con filter\nintegers = [1,2,3,4,5,6,7,8,9,10]\n\neven = list(filter(lambda x: x%2 == 0, integers))\nprint(even)\n\n\n### EXTRA ###\n\n# Datos de ejemplo de los estudiantes\nstudents = [\n    {\"nombre\": \"Alex\", \"fecha_nacimiento\": \"2000-01-15\", \"calificaciones\": [8.5, 9.0, 7.0]},\n    {\"nombre\": \"Carolina\", \"fecha_nacimiento\": \"1999-07-22\", \"calificaciones\": [9.5, 9.0, 9.0]},\n    {\"nombre\": \"Gerard\", \"fecha_nacimiento\": \"2001-05-30\", \"calificaciones\": [6.0, 7.5, 8.0]},\n    {\"nombre\": \"Sirius\", \"fecha_nacimiento\": \"2002-10-10\", \"calificaciones\": [9.0, 9.5, 9.7]},\n]\n\n# funcion principal\ndef analysis(students):\n  print(f\"Promedios:\\n{get_averages(students)}\")\n  print(f\"Calificaciones mejores estudiantes con promedio igual o mayor a 9:\\n{get_better_students(students)}\")\n  print(f\"Alumnos ordenados de mas joven a mas mayor:\\n{sort_by_date_of_birth(students)}\")\n  print(f\"Mayor calificacion obtenida de entre todos los alumnos:\\n{get_higher_qualification(students)}\")\n\n# 1. Promedio de calificaciones\ndef get_averages(students):\n    return list(map(lambda est: {\"nombre\": est[\"nombre\"], \"promedio\": sum(est[\"calificaciones\"]) / len(est[\"calificaciones\"])}, students))\n\ndef get_better_students(students):\n    return list(filter(lambda est: sum(est[\"calificaciones\"]) / len(est[\"calificaciones\"]) >= 9, students))\n\ndef sort_by_date_of_birth(students):\n    return sorted(students, key=lambda est: datetime.strptime(est[\"fecha_nacimiento\"], \"%Y-%m-%d\"))\n\n# 4. Mayor calificación\ndef get_higher_qualification(students):\n    return max(max(est[\"calificaciones\"]) for est in students)\n\nresults = analysis(students)\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/adra-dev.py",
    "content": "from functools import reduce\nfrom datetime import datetime\n\"\"\"\nEJERCICIO:\nExplora el concepto de funciones de orden superior en tu lenguaje \ncreando ejemplos simples (a tu elección) que muestren su funcionamiento.\n\nDIFICULTAD EXTRA(opcional):\nDada una lista de estudiantes (con sus nombres, feca de nacimiento y \nlista de calificaciones), utiliza funciones de orden superior para \nrealizar las siguientes operaciones de procesamiento y análisis:\n- Promedio calificaciones: Obtiene una lista de estudiantes por nombre \ny promedio de sus calificaciones.\n- MEJORES ESTUDIANTES: Obtiene una lista con el nombre de los estudiantes\nque tienen calificaciones con un 9 o más de promeido.\n- Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n- Mayor calificación: Obtiene la calificación más alta de entre todas las\nde los alumnos.\n- Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n\nby adra-dev\n\"\"\"\n\n\"\"\"\nFunciones de orden superior: Una función se denomina Función de orden\nsuperior si esta contiene otras funciones como parámetros de entrada \no si devuelve una función como salida, es decir, las funciones que \noperan con otra función se conocen como Funciones de orden superior \nen Python.\n\"\"\"\n\n# Función como argumento\n\ndef high_order_function(fun):\n  fun()\n\ndef greeting():\n  print(\"Hello World\")\n\nhigh_order_function(greeting) \n# Retorno de función\n\n\ndef apply_multiplier(n):\n    def multiplier(x):\n        return x * n\n    return multiplier\n\n\nmultiplier = apply_multiplier(2)\nprint(multiplier(5))\nprint(apply_multiplier(3)(2))\n\n#  Sistema\n\nnumbers = [1, 3, 4, 2, 5]\n\n# map()\n\n\ndef apply_double(n):\n    return n * 2\n\n\nprint(list(map(apply_double, numbers)))\n\n# filter()\n\n\ndef is_even(n):\n    return n % 2 == 0\n\n\nprint(list(filter(is_even, numbers)))\n\n# sorted()\n\nprint(sorted(numbers))\nprint(sorted(numbers, reverse=True))\nprint(sorted(numbers, key=lambda x: -x))\n\n# reduce()\n\n\ndef sum_values(x, y):\n    return x + y\n\n\nprint(reduce(sum_values, numbers))\n\n\"\"\"\nExtra\n\"\"\"\n\nstudents = [\n    {\"name\": \"Adrian\", \"birthdate\": \"29-04-1987\", \"grades\": [5, 8.5, 3, 10]},\n    {\"name\": \"Luis\", \"birthdate\": \"04-08-1995\", \"grades\": [1, 9.5, 2, 4]},\n    {\"name\": \"Pepe\", \"birthdate\": \"15-12-2000\", \"grades\": [4, 6.5, 5, 2]},\n    {\"name\": \"supermouredev\", \"birthdate\": \"25-01-1980\",\n        \"grades\": [10, 9, 9.7, 9.9]}\n]\n\n\ndef average(grades):\n   return sum(grades) / len(grades)\n\n# Promedio\n\nprint(\n   list(map(lambda student: {\n   \"name\": student[\"name\"], \"average\": average(student[\"grades\"])}, students)\n   )   \n)\n\n# Mejores\n\nprint(\n    list(\n        map(lambda student:\n            student[\"name\"],\n            filter(lambda student: average(student[\"grades\"]) >= 9, students)\n            )\n    )\n)\n\n# Fecha de nacimiento ordenada\n\nprint(sorted(students, key=lambda student: datetime.strptime(\n    student[\"birthdate\"], \"%d-%m-%Y\"), reverse=True))\n\n# Califiación más alta\n\nprint(max(map(lambda student: max(student[\"grades\"]), students)))"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/agusrosero.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Explora el concepto de funciones de orden superior en tu lenguaje \n * creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n *\n * DIFICULTAD EXTRA (opcional):\n * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n * lista de calificaciones), utiliza funciones de orden superior para \n * realizar las siguientes operaciones de procesamiento y análisis:\n * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n *   y promedio de sus calificaciones.\n * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n *   que tienen calificaciones con un 9 o más de promedio.\n * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n * - Mayor calificación: Obtiene la calificación más alta de entre todas las\n *   de los alumnos.\n * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n */\n\"\"\"\n\n# EJERCICIO:\nfrom datetime import datetime\n\n\ndef operation(x, func):\n    return func(x)\n\n\ndef squared(x):\n    return x ** 2\n\n\nresult = operation(10, squared)\nprint(result)\n\n# DIFICULTAD EXTRA:\nestudiantes = [\n    {\n        \"nombre\": \"Agustin\",\n        \"fecha_nacimiento\": \"28-09-01\",\n        \"lista_calificaciones\": [10, 6, 7, 8]\n    },\n    {\n        \"nombre\": \"Hernan\",\n        \"fecha_nacimiento\": \"03-08-00\",\n        \"lista_calificaciones\": [9, 8, 7, 6]\n    },\n    {\n        \"nombre\": \"Francisco\",\n        \"fecha_nacimiento\": \"01-03-02\",\n        \"lista_calificaciones\": [9, 8, 9, 10]\n    },\n    {\n        \"nombre\": \"Alfred\",\n        \"fecha_nacimiento\": \"09-02-03\",\n        \"lista_calificaciones\": [10, 10, 8, 8]\n    }\n]\n\n# Promedio calificaciones: Obtiene una lista de estudiantes por nombre y promedio de sus calificaciones.\n\n\ndef promedio_calificaciones(calificaciones):\n    return sum(calificaciones) / len(calificaciones)\n\n\nfor estudiante in estudiantes:\n    nombre = estudiante[\"nombre\"]\n    calificaciones = estudiante[\"lista_calificaciones\"]\n    print(f\"Nombre: {nombre}, Calificaciones: {\n          promedio_calificaciones(calificaciones)}\")\n\n# Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes que tienen calificaciones con un 9 o más de promedio.\nfor estudiante in estudiantes:\n    nombre = estudiante[\"nombre\"]\n    calificaciones = estudiante[\"lista_calificaciones\"]\n    if promedio_calificaciones(calificaciones) >= 9:\n        print(f\"Estudiantes con 9 o mas: {nombre}\")\n\n# Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n\n\ndef convertir_fecha(fecha_str):\n    return datetime.strptime(fecha_str, \"%d-%m-%y\")\n\n\nestudiantes_ordenados = sorted(estudiantes, key=lambda x: convertir_fecha(\n    x[\"fecha_nacimiento\"]), reverse=True)\n\nfor estudiante in estudiantes_ordenados:\n    print(f\"Nombre: {estudiante['nombre']}, Fecha de nacimiento: {\n          estudiante['fecha_nacimiento']}\")\n\n# Mayor calificación: Obtiene la calificación más alta de entre todas las de los alumnos.\nmax_calificacion = float('-inf')\n\nfor estudiante in estudiantes:\n    for calificacion in estudiante[\"lista_calificaciones\"]:\n        if calificacion > max_calificacion:\n            max_calificacion = calificacion\n\nprint(f\"La calificación más alta es: {max_calificacion}\")\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/alanshakir.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el concepto de funciones de orden superior en tu lenguaje \n * creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n *\n * DIFICULTAD EXTRA (opcional):\n * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n * lista de calificaciones), utiliza funciones de orden superior para \n * realizar las siguientes operaciones de procesamiento y análisis:\n * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n *   y promedio de sus calificaciones.\n * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n *   que tienen calificaciones con un 9 o más de promedio.\n * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n * - Mayor calificación: Obtiene la calificación más alta de entre todas las\n *   de los alumnos.\n * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n */\n\"\"\"\nfrom functools import reduce\nfrom datetime import datetime\nnumbers = [2 , 5, 10, 21, 3, 30]\nnumbers_str = ['1', '2', '3', '4', '5']  # iterable\n\n#Map -- devuelve un iterable\n\nnumbers_int = map(int, numbers_str)\nprint(list(numbers_int))    # [1, 2, 3, 4, 5]\n\n\ndef multiply_two(value):\n    return value*2\nprint(list(map(multiply_two, numbers)))\n\n#filter -- devuelve un iterable\n\ndef is_odd(num):\n    if num % 2 != 0:\n        return True\n    return False\n\nodd_numbers = filter(is_odd, numbers)\nprint(list(odd_numbers))\n\ndef filter_greater_than_ten(number):\n    if number > 10:\n        return True\n    return False\nprint(list(filter(filter_greater_than_ten, numbers)))\n\n#Reduce -- devuelve un unico valor\n\ndef add_two_nums(x, y):\n    return int(x) + int(y)\n\ntotal = reduce(add_two_nums, numbers_str)\nprint(total)\n\ndef sum_two_values_and_one(first_value, second_value):\n    return first_value + second_value\n\nprint(reduce(sum_two_values_and_one, numbers))\n\n#Extra\nlista_estudiantes = [{\"name\":\"Alan\", \"birthdate\":\"20-01-1985\", \"grades\": [9,8,7.3]},\n                     {\"name\":\"Nico\", \"birthdate\":\"05-04-2014\", \"grades\":[10,9.9,8]}, \n                     {\"name\":\"Matheo\",  \"birthdate\":\"03-01-2024\", \"grades\": [10,10,10]}]\n\n# Promedio calificaciones\ndef averages(notes):\n    return sum(notes) / len(notes)\n\nprint(list(map(lambda estudiante: \n               {\"name\": estudiante[\"name\"],\n                \"average\": averages(estudiante[\"grades\"])}, lista_estudiantes)))\n\n# Mejores estudiantes\nprint(list(map(lambda estudiante: \n               estudiante[\"name\"],\n               filter(lambda estudiante: averages(estudiante[\"grades\"]) >= 9, lista_estudiantes) )))\n\n#Nacimiento\nprint(sorted(lista_estudiantes, key=lambda estudiante: datetime.strptime(estudiante[\"birthdate\"], \"%d-%m-%Y\"), reverse=True))\n\n#Mayor calificación\nprint(max(map(lambda estudiante: max(estudiante[\"grades\"]), lista_estudiantes)))\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/any7dev.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Explora el concepto de funciones de orden superior en tu lenguaje \n * creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n *\n * DIFICULTAD EXTRA (opcional):\n * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n * lista de calificaciones), utiliza funciones de orden superior para \n * realizar las siguientes operaciones de procesamiento y análisis:\n * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n *   y promedio de sus calificaciones.\n * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n *   que tienen calificaciones con un 9 o más de promedio.\n * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n * - Mayor calificación: Obtiene la calificación más alta de entre todas las\n *   de los alumnos.\n * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n */ \"\"\"\n\nfrom functools import reduce\nfrom datetime import datetime\n\n#EJERCICIO\n\n#Función como parámetro\ndef funcion_orden_superior(num1, num2, funcion):\n    return funcion(num1, num2)\n\ndef suma(num1, num2):\n    return num1 + num2\n\ndef resta(num1, num2):\n    return num1 - num2\n\ndef multiplica(num1, num2):\n    return num1 * num2\n\ndef divide(num1, num2):\n    return num1 / num2\n\nprint(funcion_orden_superior(16, 5, suma))\nprint(funcion_orden_superior(16, 5, resta))\nprint(funcion_orden_superior(16, 5, divide))\nprint(funcion_orden_superior(16, 5, multiplica))\n\n#Función como valor de retorno\ndef cuadrado(num):\n    return num ** 2\n\ndef cubo(num):\n    return num ** 3\n\ndef funcion_orden_superior(operacion):\n    if operacion == \"doble\":\n        return cuadrado\n    else:\n        return cubo\n    \nresultado = (funcion_orden_superior(\"doble\"))\nprint(resultado(5))\nresultado = (funcion_orden_superior(\"triple\"))\nprint(resultado(5))\n\n#Función dentro de otra función(cierre)\ndef suma_dos():\n    dos = 2\n    def suma(num):\n        return num + dos\n    return suma\n\nresultado = suma_dos()\nprint(resultado(2))\nprint(resultado(7))\n\n#Map\nnumeros = [1, 2, 3, 4, 5]\ncadena = map(str, numeros)\nprint(list(cadena))\n\n#Filter\ndef par(numero):\n    if numero % 2 == 0:\n        return True\n    else:\n        return False\n\npares = filter(par, numeros)\nprint(list(pares))\n#Usando lambda\npares = filter((lambda x: x%2 == 0), numeros)\nprint(list(pares))\n\n#Reduce\ndef suma(num1, num2):\n    return num1 + num2\n\ntotal = reduce(suma, numeros)\nprint(total)\n#Usando lambda\ntotal = reduce((lambda x, y: x + y), numeros)\nprint(total)\n\n#Sort o sorted\nnumeros = [2, 0.2, 52, 41, 20]\nprint(sorted(numeros))\nprint(sorted(numeros, reverse=True))\n\n\n#DIFICULTAD EXTRA\n\nestudiantes = [[\"Estudiante1\",[8, 9.8, 9, 9.5], \"2/3/1995\"], \n[\"Estudiante2\",[5, 6.5, 7, 8], \"9/6/2001\"],\n[\"Estudiante3\",[9, 3.2, 10, 5], \"15/8/2020\"],\n[\"Estudiante4\",[9.2, 3.4, 7, 9.9], \"23/8/1999\"],\n[\"Estudiante5\",[9.7, 9.5, 8.8, 9], \"1/1/2003\"],\n[\"Estudiante6\",[1.2, 4.5, 7.6, 8.9], \"31/12/1980\"]]\n\nprint(f\"\\nLista Estudiantes: {estudiantes}\\n\")\n\nlista_promedio = list(map(lambda estudiante: [estudiante[0], round((reduce(lambda x,y: x+y, estudiante[1]))/len(estudiante[1]),2)], estudiantes))\nprint(f\"Promedio calificaciones: {lista_promedio}\\n\")\n\nmejores = list(map(lambda x: x[0], (filter(lambda estudiante: estudiante[1] >= 9, lista_promedio))))\nprint(f\"Mejores estudiantes: {mejores}\\n\")\n\ndef ordenar_fechas(lista):\n    return datetime.strptime(lista[2], \"%d/%m/%Y\")\nestudiantes.sort(key=ordenar_fechas, reverse=True)\nprint(f\"Estudiantes ordenados por el más joven: {estudiantes}\\n\")\n\nmayor_nota = max(list(map(lambda estudiante: max(estudiante[1]), estudiantes)))\nprint(f\"Mayor calificación: {mayor_nota}\\n\")\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/avcenal.py",
    "content": "\"\"\"\nEJERCICIO:\n * Explora el concepto de funciones de orden superior en tu lenguaje \n * creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n\"\"\"\ndef multiply_for_five(value:int):\n    return value*5\n\ndef multiply_for_two(value:int):\n    return value*2\n\ndef multiply_value(value:int,func):\n    return func(value)\n\nprint(multiply_value(5,multiply_for_five))\nprint(multiply_value(5,multiply_for_two)) #desde la misma función puedo llamar a otra\nprint(multiply_value(5,lambda x:x*3)) #o incluso crear una lambda\n\n#BUILT-IN HIGH ORDER LEVEL FUNCTIONS\nnumbers = [1,2,3,4,5,6]\nprint(list(map(lambda x:x*2,numbers)))\nprint(list(filter(lambda x:x>3,numbers)))\n\n#CLOSURES\ndef sum_five(): #una función que retorna una función\n    def add(value:int):\n        return value + 5\n    return add\n\nadd = sum_five()\nprint(add(3))\n\nprint(sum_five()(7))\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n * lista de calificaciones), utiliza funciones de orden superior para\n * realizar las siguientes operaciones de procesamiento y análisis:\n * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n *   y promedio de sus calificaciones.\n * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n *   que tienen calificaciones con un 9 o más de promedio.\n * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n * - Mayor calificación: Obtiene la calificación más alta de entre todas las\n *   de los alumnos.\n * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n\"\"\"\n\nstudents = [\n    {\n        \"name\":\"Alex\",\n        \"birthdate\" : \"19/12/1984\",\n        \"qualifications\": [8.0,7.5,6.7,7.2]\n    },\n    {\n        \"name\":\"Sole\",\n        \"birthdate\" : \"12/01/1983\",\n        \"qualifications\": [9.1,6.8,7.3,8.7]\n    },\n    {\n        \"name\":\"Martín\",\n        \"birthdate\" : \"12/11/2015\",\n        \"qualifications\": [9.4,8.9,9.9,9.4]\n    },\n    {\n        \"name\":\"Valeria\",\n        \"birthdate\" : \"17/04/2018\",\n        \"qualifications\": [9.0,8.9,9.7,9.1]\n    }\n]\n\nfrom functools import reduce\nfrom datetime import datetime\n\ndef average(students:list): #BUILT-IN FUNCTION: REDUCE + LAMBDA\n    return list(map(lambda student: {\"name\": student[\"name\"], \n                                    \"average\": round(reduce(lambda x,y:x+y,student[\"qualifications\"])/len(student[\"qualifications\"]),2)},students))\n\nprint(f\"PROMEDIO DE CALIFICACIONES:\\n{average(students)}\")\n\n\ndef best_students(students:list): #BUILT-IN FUNCTION: FILTER + LAMBDA\n    return list(map(lambda student: {\"name\":student[\"name\"]},filter(lambda student: student[\"average\"]>9,average(students))))\n\nprint(f\"\\nMEJORES ALUMNOS:\\n{best_students(students)}\")\n\ndef sort_youngest(students:list): #CLOSURE\n    def youngest ():\n        return sorted(students,key=lambda student:(datetime.strptime(student[\"birthdate\"],\"%d/%m/%Y\"),students),reverse=True)\n    return youngest\n\n\nprint(f\"\\nALUMNOS ORDENADOS DESDE EL MÁS JOVEN:\\n{sort_youngest(students)()}\")\n\ndef find_best_student(students:list): #CLOSURE\n    def best_qualifications():\n        return max(list(map(lambda student: max(student[\"qualifications\"]),students)))\n    return best_qualifications\n\nprint(f\"\\nLA MEJOR NOTA:\\n{find_best_student(students)()}\")\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/barrancus.py",
    "content": "# 22 - Python\n# \n# EJERCICIO:\n# Explora el concepto de funciones de orden superior en tu lenguaje \n# creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n# \n# DIFICULTAD EXTRA (opcional):\n# Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n# lista de calificaciones), utiliza funciones de orden superior para\n# realizar las siguientes operaciones de procesamiento y análisis:\n# - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n#   y promedio de sus calificaciones.\n# - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n#   que tienen calificaciones con un 9 o más de promedio.\n# - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n# - Mayor calificación: Obtiene la calificación más alta de entre todas las\n#   de los alumnos.\n# - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n# \nfrom random import randint, choice\nfrom functools import reduce, partial\n\nclass Counter:\n    def __iter__(self):\n        self.a = 1\n        return self\n    \n    def __next__(self):\n        x = self.a\n        self.a += 1\n        return x\n\ndef serparacion(cadena) -> str:\n    global contador\n    print(f'\\nEjercicio {next(contador)}. {cadena * 20}')\n\ncontador = iter(Counter())\n\nstudents = [\n    {\n        \"nombre\": \"Sofía Martínez\",\n        \"fecha_nacimiento\": \"2005-03-14\",\n        \"calificaciones\": [8.5, 9.0, 9.5, 8.8]\n    },\n    {\n        \"nombre\": \"Alejandro López\",\n        \"fecha_nacimiento\": \"2004-11-22\",\n        \"calificaciones\": [7.0, 6.5, 7.8, 6.0]\n    },\n    {\n        \"nombre\": \"Valeria González\",\n        \"fecha_nacimiento\": \"2005-01-10\",\n        \"calificaciones\": [9.8, 10.0, 9.9, 9.5]\n    },\n    {\n        \"nombre\": \"Diego Rodríguez\",\n        \"fecha_nacimiento\": \"2004-07-05\",\n        \"calificaciones\": [5.5, 6.0, 5.0, 6.2]\n    },\n    {\n        \"nombre\": \"Camila Fernández\",\n        \"fecha_nacimiento\": \"2005-09-30\",\n        \"calificaciones\": [8.0, 8.5, 7.5, 8.2]\n    },\n    {\n        \"nombre\": \"Mateo Sánchez\",\n        \"fecha_nacimiento\": \"2004-05-18\",\n        \"calificaciones\": [6.5, 7.0, 6.8, 7.2]\n    },\n    {\n        \"nombre\": \"Isabella Pérez\",\n        \"fecha_nacimiento\": \"2005-12-03\",\n        \"calificaciones\": [9.0, 9.2, 8.8, 9.5]\n    },\n    {\n        \"nombre\": \"Santiago Gómez\",\n        \"fecha_nacimiento\": \"2004-02-14\",\n        \"calificaciones\": [7.5, 7.0, 8.0, 7.8]\n    },\n    {\n        \"nombre\": \"Valentina Ruiz\",\n        \"fecha_nacimiento\": \"2005-06-21\",\n        \"calificaciones\": [8.8, 8.5, 9.0, 8.2]\n    },\n    {\n        \"nombre\": \"Daniel Díaz\",\n        \"fecha_nacimiento\": \"2004-08-09\",\n        \"calificaciones\": [6.0, 5.8, 6.5, 6.2]\n    },\n    {\n        \"nombre\": \"Lucía Hernández\",\n        \"fecha_nacimiento\": \"2005-04-17\",\n        \"calificaciones\": [9.5, 9.8, 9.2, 9.7]\n    },\n    {\n        \"nombre\": \"Nicolás Álvarez\",\n        \"fecha_nacimiento\": \"2004-10-25\",\n        \"calificaciones\": [7.2, 7.5, 7.0, 7.8]\n    },\n    {\n        \"nombre\": \"Mariana Torres\",\n        \"fecha_nacimiento\": \"2005-02-05\",\n        \"calificaciones\": [8.2, 8.0, 8.5, 8.1]\n    },\n    {\n        \"nombre\": \"Samuel Flores\",\n        \"fecha_nacimiento\": \"2004-12-12\",\n        \"calificaciones\": [5.0, 5.5, 6.0, 5.2]\n    },\n    {\n        \"nombre\": \"Gabriela Romero\",\n        \"fecha_nacimiento\": \"2005-08-28\",\n        \"calificaciones\": [9.0, 8.8, 9.2, 9.5]\n    },\n    {\n        \"nombre\": \"Felipe Castillo\",\n        \"fecha_nacimiento\": \"2004-03-08\",\n        \"calificaciones\": [7.8, 7.5, 8.0, 7.2]\n    },\n    {\n        \"nombre\": \"Victoria Medina\",\n        \"fecha_nacimiento\": \"2005-11-15\",\n        \"calificaciones\": [8.5, 8.2, 8.8, 8.5]\n    },\n    {\n        \"nombre\": \"Emiliano Silva\",\n        \"fecha_nacimiento\": \"2004-06-02\",\n        \"calificaciones\": [6.2, 6.5, 6.0, 6.8]\n    },\n    {\n        \"nombre\": \"Ximena Castro\",\n        \"fecha_nacimiento\": \"2005-05-20\",\n        \"calificaciones\": [9.2, 9.5, 9.0, 9.8]\n    },\n    {\n        \"nombre\": \"Andrés Morales\",\n        \"fecha_nacimiento\": \"2004-09-11\",\n        \"calificaciones\": [7.0, 7.2, 6.8, 7.5]\n    },\n    {\n        \"nombre\": \"Renata Ortega\",\n        \"fecha_nacimiento\": \"2005-07-29\",\n        \"calificaciones\": [8.0, 8.2, 7.8, 8.5]\n    },\n    {\n        \"nombre\": \"Joaquín Vargas\",\n        \"fecha_nacimiento\": \"2004-01-30\",\n        \"calificaciones\": [5.8, 6.0, 5.5, 6.2]\n    },\n    {\n        \"nombre\": \"Elena Navarro\",\n        \"fecha_nacimiento\": \"2005-10-08\",\n        \"calificaciones\": [9.8, 9.5, 9.2, 9.9]\n    },\n    {\n        \"nombre\": \"Gabriel Mendoza\",\n        \"fecha_nacimiento\": \"2004-04-22\",\n        \"calificaciones\": [7.5, 7.8, 7.2, 8.0]\n    },\n    {\n        \"nombre\": \"Daniela Rojas\",\n        \"fecha_nacimiento\": \"2005-03-01\",\n        \"calificaciones\": [8.5, 8.8, 8.2, 8.9]\n    },\n    {\n        \"nombre\": \"Adrián Cruz\",\n        \"fecha_nacimiento\": \"2004-12-20\",\n        \"calificaciones\": [6.5, 6.8, 6.2, 7.0]\n    }\n]\n\ndef func_superior_order() -> None:\n    serparacion('-:-')\n    numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n    print(f'Numeros iniciales: {numbers}')\n    print(f'Funcion de orden superior map(lambda x: x**2, numbers): {list(map(lambda x: x**2, numbers))}')\n    print(f'Funcion de orden superior filter(lambda x: x % 2 == 0, numbers): {list(filter(lambda x: x % 2 == 0, numbers))}')\n    print(f'Funcion de orden superior reduce(lambda x, y: x + y, numbers): {reduce(lambda x, y: x + y, numbers)}')\n    print(f'Funcion de orden superior sorted(numbers, reverse=True): {sorted(numbers, reverse=True)}')\n    basetwo = partial(int, base=2)\n    basetwo.__doc__ = 'Convert base 2 string to an int.'\n    basetwo.__name__ = 'basetwo'\n    print(f'Funcion de orden superior partial(int, base=2): {basetwo.__doc__}')\n    print(basetwo('10010')) \n    print(f'bin(18): {bin(18)}')\n\ndef extra() -> None:\n    serparacion('-:-')\n    while True:\n        print('\\nPor favor serlecciona una de las opciones a mostrar:')\n        print('1 - Promedio calificaciones de los estudiantes.')\n        print('2 - Mostrar los mejores estudiantes (promedio >= 9).')\n        print('3 - Mostrar estudiantes ordenados desde el más joven.')\n        print('4 - Mostrar la mayor calificación entre todos los estudiantes.')\n        print('0 - Salir.')\n        option = input('Opción seleccionada: ')\n        match option:\n            case '1':\n                print(f\"\\n{'Nombre':<20} | {'Promedio':<10}\")\n                print(\"-\" * 33)\n                for student in students:\n                    print(f\"{student['nombre']:<20} | {average_grades(student[\"calificaciones\"]):.2f}\")\n            case '2':\n                print(f\"\\n{'Nombre':<20} | {'Promedio':<10}\")\n                print(\"-\" * 33)\n                for student in students:\n                    aver = list(best_average_grades(student[\"calificaciones\"]))\n                    if len(aver) > 0: print(f\"{student['nombre']:<20} | {aver[0]:.2f}\")\n            case '3':\n                print(f\"\\n{'Nombre':<20} | {'Fecha Nacimiento':<18}\")\n                print(\"-\" * 41)\n                for student in sorted(students, key=lambda x: x[\"fecha_nacimiento\"], reverse=True):\n                    print(f\"{student['nombre']:<20} | {student[\"fecha_nacimiento\"]}\")\n            case '4':\n                print(f\"\\n{'Nombre':<20} | {'Promedio':<10}\")\n                print(\"-\" * 33)\n                highest_grade_value = highest_grade(students)\n                for student in students:\n                    if max(student[\"calificaciones\"]) == highest_grade_value:\n                        print(f\"{student['nombre']:<20} | {max(student['calificaciones']):.2f}\")\n            case '0':\n                print('\\nSalir.')\n                break\n            case _:\n                print('\\nOpción no válida. Por favor, intenta de nuevo.')\n    \ndef average_grades(grades: list) -> float:\n    return reduce(lambda x, y: x + y, grades) / len(grades)    \n\ndef best_average_grades(grades: list) -> filter:\n    return filter(lambda x: x >= 9, [average_grades(grades)])\n\ndef highest_grade(students: list) -> float:\n    return max(list(map(lambda student: max(student[\"calificaciones\"]), students)))\n\ndef main():\n    print('\\nFUNCIONES DE ORDEN SUPERIOR')\n    func_superior_order()\n    extra()\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/cristianfloyd.py",
    "content": "# EJERCICIO:\n# Explora el concepto de funciones de orden superior en tu lenguaje\n# creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n\nfrom datetime import date\nfrom typing import Any, Callable, Dict, List\n\nOperacionesMatematicas = Callable[[int, int], int]\n\n\ndef sumar(a: int, b: int) -> int:\n    return a + b\n\n\ndef multiplicar(a: int, b: int) -> int:\n    return a * b\n\n\ndef potenciar(a: int, b: int) -> int:\n    return a**b\n\n\nlista_original = [1, 2, 3, 4, 5]\n\n\ndef aplicar_operaciones(\n    lista: List[int], operaciones: List[OperacionesMatematicas]\n) -> Dict[str, List[int]]:\n    \"\"\"\n    Funcion de orden superior que aplica una 'operacion' a cada elemento de la 'lista'.\n\n    Args:\n        lista: Lista de elementos a los que se le aplicara la 'operacion'.\n        operaciones: Lista de operaciones a aplicar a la 'lista'.\n\n    Returns:\n        Lista de resultados de las operaciones aplicadas a la 'lista'.\n    \"\"\"\n    resultado = {}\n    resultados_parciales = []\n    for operacion in operaciones:\n        for elemento in lista:\n            nuevo_valor = operacion(elemento, elemento)\n            resultados_parciales.append(nuevo_valor)\n        resultado[operacion.__name__] = resultados_parciales.copy()\n        resultados_parciales = []\n    return resultado\n\n\nresultado = aplicar_operaciones(lista_original, [sumar, multiplicar, potenciar])\n\nprint(\"=\" * 50)\nprint(\"Lista original:\")\nprint(lista_original)\nprint(\"=\" * 50)\nprint(\"Resultado de las operaciones aplicadas a la lista:\")\nfor operacion, resultados in resultado.items():\n    print(f\"{operacion}: {resultados}\")\nprint(\"=\" * 50)\n\n\n# creador de potencias\ndef crear_potencia(exponente: int) -> Callable[[int], int]:\n    def potencia(base: int) -> int:\n        return base**exponente\n\n    return potencia\n\n\npotencia_2 = crear_potencia(2)\npotencia_3 = crear_potencia(3)\npotencia_4 = crear_potencia(4)\n\nprint(\"=\" * 50)\nprint(\"Potencias creadas:\")\nn = 2\nprint(f\"para base {n}:\")\nprint(f\"potencia de {n} elevado a la 2: {potencia_2(n)}\")\nprint(f\"potencia de {n} elevado a la 3: {potencia_3(n)}\")\nprint(f\"potencia de {n} elevado a la 4: {potencia_4(n)}\")\nprint(\"=\" * 50)\n\n\n#\n# DIFICULTAD EXTRA (opcional):\n# Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y\n# lista de calificaciones), utiliza funciones de orden superior para\n# realizar las siguientes operaciones de procesamiento y análisis:\n# - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n#   y promedio de sus calificaciones.\n# - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n#   que tienen calificaciones con un 9 o más de promedio.\n# - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n# - Mayor calificación: Obtiene la calificación más alta de entre todas las\n#   de los alumnos.\n# - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n\nestudiantes = [\n    {\n        \"nombre\": \"Juan\",\n        \"fecha_nacimiento\": date(1999, 5, 10),\n        \"calificaciones\": {\n            \"matematicas\": 9.0,\n            \"historia\": 8.0,\n            \"ingles\": 9.0,\n            \"fisica\": 10.0,\n            \"quimica\": 9.0,\n        },\n    },\n    {\n        \"nombre\": \"María\",\n        \"fecha_nacimiento\": date(2000, 3, 15),\n        \"calificaciones\": {\n            \"matematicas\": 4.0,\n            \"historia\": 7.0,\n            \"ingles\": 6.0,\n            \"fisica\": 5.0,\n            \"quimica\": 8.0,\n        },\n    },\n    {\n        \"nombre\": \"Pedro\",\n        \"fecha_nacimiento\": date(1998, 11, 20),\n        \"calificaciones\": {\n            \"matematicas\": 6.0,\n            \"historia\": 9.0,\n            \"ingles\": 4.0,\n        },\n    },\n    {\n        \"nombre\": \"Ana\",\n        \"fecha_nacimiento\": date(2001, 7, 5),\n        \"calificaciones\": {\n            \"matematicas\": 7.0,\n            \"historia\": 10.0,\n            \"ingles\": 8.0,\n        },\n    },\n]\n\n\ndef obtener_promedio(calificaciones: Dict[str, float]) -> float:\n    return sum(calificaciones.values()) / len(calificaciones.values())\n\n\ndef obtener_mejores_estudiantes(estudiantes) -> List[str]:\n    return [\n        estudiante[\"nombre\"]\n        for estudiante in estudiantes\n        if obtener_promedio(estudiante[\"calificaciones\"]) >= 9\n    ]\n\n\ndef obtener_nacimiento(estudiante: dict[str, Any | date]) -> date:\n    return estudiante[\"fecha_nacimiento\"]\n\n\n# Promedio\npromedios = list[dict[str, Any | float]](\n    map(\n        lambda estudiante: {\n            \"nombre\": estudiante[\"nombre\"],\n            \"promedio\": obtener_promedio(estudiante[\"calificaciones\"]),\n        },\n        estudiantes,\n    )\n)\n\n# Mejores estudiantes, nota mayor a 9\nmejores_estudiantes = list[dict[str, Any | float]](\n    filter(lambda estudiante: estudiante[\"promedio\"] >= 9, promedios)\n)\n\n# Nacimiento\nmas_jovenes = list[dict[str, Any | date]](\n    sorted(estudiantes, key=obtener_nacimiento, reverse=True)\n)\n\n# Mayor nota\nmayor_nota = max(\n    map(lambda estudiante: max(estudiante[\"calificaciones\"].values()), estudiantes)\n)\n\nprint(\"=\" * 50)\nprint(\"Promedios de los estudiantes:\")\nfor promedio in promedios:\n    print(f\"{promedio['nombre']}: {promedio['promedio']}\")\nprint(\"=\" * 50)\n\nprint(\"=\" * 50)\nprint(\"Mejores estudiantes:\")\nfor estudiante in mejores_estudiantes:\n    print(f\"{estudiante['nombre']}: promedio {estudiante['promedio']}\")\nprint(\"=\" * 50)\n\nprint(\"=\" * 50)\nprint(\"Mas jovenes:\")\nfor estudiante in mas_jovenes:\n    print(f\"{estudiante['nombre']}: {estudiante['fecha_nacimiento']}\")\nprint(\"=\" * 50)\n\nprint(\"=\" * 50)\nprint(\"Mayor nota:\")\nprint(mayor_nota)\nprint(\"=\" * 50)\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/davidrguez98.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Explora el concepto de funciones de orden superior en tu lenguaje \n * creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n *\n * DIFICULTAD EXTRA (opcional):\n * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n * lista de calificaciones), utiliza funciones de orden superior para \n * realizar las siguientes operaciones de procesamiento y análisis:\n * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n *   y promedio de sus calificaciones.\n * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n *   que tienen calificaciones con un 9 o más de promedio.\n * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n * - Mayor calificación: Obtiene la calificación más alta de entre todas las\n *   de los alumnos.\n * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n */ \"\"\"\n\n#EJERCICIO\n\n#Función de argumento\n\ndef apply_func(func, x):\n    return func(x)\n\nprint(apply_func(len, \"David\"))\n\n#Retorno de función\n\ndef apply_multiplier(n):\n    def multiplier(x):\n        return x * n\n    return multiplier\n\nprint(apply_multiplier(2)(3))\n\n#Sistema\n\nnumbers = [1, 3, 2, 5, 4]\n\n\"\"\" map() \"\"\"\n\ndef apply_double(n):\n    return n * 2\n\nprint(map(apply_double, numbers))\nprint(list(map(apply_double, numbers)))\n\n\"\"\" filter() \"\"\"\n\ndef is_even(n):\n    return n % 2 == 0\n\nprint(filter(is_even, numbers))\nprint(list(filter(is_even, numbers)))\n\n\"\"\" sorted() \"\"\"\n\nprint(sorted(numbers))\nprint(sorted(numbers))\nprint(sorted(numbers, key=lambda x: -x))\n\n\"\"\" reduce() \"\"\"\n\nfrom functools import reduce\n\ndef sum_(x, y):\n    return x + y\n\nprint(reduce(sum_, numbers))\n\n#DIFICULTAD EXTRA\n\nstudents = [\n    {\"name\": \"Juan\", \"birthdate\": \"10-03-1998\", \"results\": [5, 7, 6, 7]},\n    {\"name\": \"José\", \"birthdate\": \"02-03-1988\", \"results\": [7, 8, 9, 4]},\n    {\"name\": \"Pepe\", \"birthdate\": \"02-03-1978\", \"results\": [7, 8, 9, 4]},\n    {\"name\": \"Ramiro\", \"birthdate\": \"02-11-1990\", \"results\": [9.5, 9, 9, 10]}\n]\n\n#Promedio\n\ndef average(results):\n    return sum(results) / len(results)\n\nprint(\"\\nPromedio:\")\nprint(list(map(lambda student: {\"name\": student[\"name\"], \"average\": average(student[\"results\"])}, students)))\n\n#Mejores estudiantes\n\nprint(\"\\nMejores estudiantes:\")\nprint(list(map(lambda student: student[\"name\"], filter(lambda student: average(student[\"results\"]) >= 9, students))))\n\n#Nacimiento\n\nfrom datetime import datetime\n\nprint(\"\\nOrden de estudiantes por edad:\")\nprint(sorted(students, key=lambda student: datetime.strptime(student[\"birthdate\"], \"%d-%m-%Y\"), reverse=True))\n\n#Mayor calificación\n\nprint(\"\\nMayor calificación:\")\nprint(max(list(map(lambda student: max(student[\"results\"]), students))))"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/didacdev.py",
    "content": "from datetime import datetime\n\n\nclass Student:\n    name: str\n    birthday: datetime\n    marks: list[int]\n\n    def __init__(self, name, birthday, marks):\n        self.name = name\n        self.birthday = birthday\n        self.marks = marks\n\n\ndef operation(students: list[Student], operation):\n    try:\n        for student in students:\n            check_marks(student.marks)\n\n        return operation(students)\n    except ValueError as e:\n        return e\n\n\ndef average_grades(students):\n    average_grades = dict()\n\n    for student in students:\n        marks = student.marks\n\n        average = sum(marks) / len(marks)\n\n        average_grades[f\"{student.name}\"] = average\n\n    return average_grades\n\n\ndef best_students(students: list[Student]):\n    average = average_grades(students)\n    best_students = []\n\n    for name, mark in average.items():\n        if mark >= 9:\n            best_students.append(name)\n\n    return best_students\n\n\ndef order_by_birth(students: list[Student]):\n    ordered_students = sorted(students, key=lambda student: student.birthday, reverse=True)\n    ordered_students_list = []\n\n    for student in ordered_students:\n        ordered_students_list.append(student.name)\n\n    return ordered_students_list\n\n\ndef get_highest_mark(students: list[Student]):\n    highest_marks = max(student.marks for student in students)\n    highest_mark = max(highest_marks)\n\n    return highest_mark\n\n\ndef check_marks(marks: list[int]):\n    for mark in marks:\n        if not 0 <= mark <= 10:\n            raise ValueError(\"Una calificación debe estar comprendida entre 0 y 10\")\n\n\ndef main():\n    student1 = Student(\"Pepe\", datetime(1996, 3, 10), [10, 9, 8.75])\n    student2 = Student(\"Ana\", datetime(1996, 6, 12), [5, 4, 6])\n    student3 = Student(\"Juan\", datetime(1996, 5, 23), [8, 7, 3])\n\n    print(operation([student1, student2, student3], average_grades))\n    print(operation([student1, student2, student3], best_students))\n    print(operation([student1, student2, student3], order_by_birth))\n    print(operation([student1, student2, student3], get_highest_mark))\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/duendeintemporal.py",
    "content": "#22 { Retos para Programadores } FUNCIONES DE ORDEN SUPERIOR\n\n# Bibliography reference\n#Secrets of the JavaScript Ninja (John Resig, Bear Bibeault, Josip Maras) (z-lib.org)\n#Eloquent Javascript A Modern Introduction to Programming by Marijn Haverbeke (z-lib.org)\n#Python Notes for Professionals. 800+ pages of professional hints and tricks (GoalKicker.com) (Z-Library)\n# Additionally, I use GPT as a reference and sometimes to correct or generate proper comments.\n\n\"\"\"  \n* EJERCICIO:\n * Explora el concepto de funciones de orden superior en tu lenguaje \n * creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n *\n * DIFICULTAD EXTRA (opcional):\n * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n * lista de calificaciones), utiliza funciones de orden superior para\n * realizar las siguientes operaciones de procesamiento y análisis:\n * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n *   y promedio de sus calificaciones.\n * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n *   que tienen calificaciones con un 9 o más de promedio.\n * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n * - Mayor calificación: Obtiene la calificación más alta de entre todas las\n *   de los alumnos.\n * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n\n\"\"\"\nimport random\nfrom datetime import datetime\n\nlog = print\n\nlog('Retos para Programadores #22')\n\n# Higher-order function example: power function\ndef powder(n):\n    return lambda m: 1 if n == 0 else m * powder(n - 1)(m)\n\npowder2 = powder(2)\nlog(powder2(10))  # 100\n\n# Higher-order function to apply a function to an array\ndef apply_to_array(func):\n    return lambda *arr: func(*arr)\n\ndef total_amount(*args):\n    return sum(args)\n\nsales = [123, 45, 67, 865, 76, 54, 3254, 23]\nlog(apply_to_array(total_amount)(*sales))  # 4507\n\n# Control flow function\ndef unless(test, then):\n    if not test:\n        then()\n\ndef is_odd_num(n):\n    return n % 2 != 0\n\n# Higher-order function to add odd numbers up to n\ndef add_odd_nums(n):\n    total = 0\n    while n > 0:\n        if is_odd_num(n):  # Check if n is odd\n            total = add_to_total(n, total)  # Update total\n        n -= 1\n    return total\n\n# Helper function to add to total\ndef add_to_total(n, total):\n    return total + n\n\nlog(add_odd_nums(100))  # Should print 2500\n\n\n# EXTRA DIFFICULTY EXERCISE\n\n# Student class definition\nclass Student:\n    def __init__(self, name, birthday, calification):\n        self.name = name\n        self.birthday = datetime.strptime(birthday, '%Y-%m-%d')\n        self.calification = calification\n\n    def get_name(self):\n        return self.name\n\n    def get_birthday(self):\n        return self.birthday\n\n    def get_calification(self):\n        return self.calification\n\n    def set_name(self, name):\n        self.name = name\n\n    def set_birthday(self, birthday):\n        self.birthday = datetime.strptime(birthday, '%Y-%m-%d')\n\n    def set_calification(self, calification):\n        self.calification = calification\n\n# List of students\nstudents = [\n    Student('Juan Rulfo', '1986-06-07', 7),\n    Student('Moure Dev', '1982-03-08', 8.5),\n    Student('Calvin Maker', '2000-04-02', 9.8),\n    Student('Adela Jimenez', '1976-01-09', 7.9),\n    Student('Crist Renegate', '2001-07-09', 5),\n    Student('Gautama Buda', '0623-05-23', 9),\n    Student('Niko Zen', '1983-08-08', 10)\n]\n\n# Function to get a list of students with their average grades\ndef students_average_list(arr):\n    return sorted(\n        [{'name': student.get_name(), 'average': student.get_calification()} for student in arr],\n        key=lambda x: x['average'],\n        reverse=True\n    )\n\n# Function to get a list of students with grades of 9 or higher\ndef higher_than_9_students(arr):\n    return [student.get_name() for student in arr if student.get_calification() >= 9]\n\n# Function to sort students by their birth date\ndef sort_students_by_birthday(arr):\n    return [student.get_name() for student in sorted(arr, key=lambda student: student.get_birthday())]\n\n# Function to find the highest grade among all students\ndef highest_calification(arr):\n    return max(student.get_calification() for student in arr)\n\n# Execute the functions and store the results\naverage_list = students_average_list(students)\nbest_students = higher_than_9_students(students)\nsorted_students = sort_students_by_birthday(students)\nhighest_grade = highest_calification(students)\n\n# Display the results in the console\nlog(\"Average grades:\", average_list)\nlog(\"Best students (9 or higher):\", best_students)  # Best students (9 or higher): ['Calvin Maker', 'Gautama Buda', 'Niko Zen']\nlog(\"Students sorted by birth date:\", sorted_students)  # Students sorted by birth date\nlog(\"Highest grade:\", highest_grade)  # Highest grade: 10\n\n# Output Example:\n\"\"\"  \nAverage grades: [{'name': 'Niko Zen', 'average': 10}, {'name': 'Calvin Maker', 'average': 9.8}, {'name': 'Gautama Buda', 'average': 9}, {'name': 'Moure Dev', 'average': 8.5}, {'name': 'Adela Jimenez', 'average': 7.9}, {'name': 'Juan Rulfo', 'average': 7}, {'name': 'Crist Renegate', 'average': 5}]\nBest students (9 or higher): ['Calvin Maker', 'Gautama Buda', 'Niko Zen']\nStudents sorted by birth date: ['Gautama Buda', 'Adela Jimenez', 'Moure Dev', 'Niko Zen', 'Juan Rulfo', 'Calvin Maker', 'Crist Renegate']\nHighest grade: 10\n\n\"\"\"\n\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/fborjalv.py",
    "content": "\nfrom functools import reduce\nfrom datetime import date, datetime\n\"\"\"\n* EJERCICIO:\n * Explora el concepto de funciones de orden superior en tu lenguaje \n * creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n\n\"\"\"\n# Función como argumento \n\ndef saluda(name, saluda_callback):\n    saluda_callback(name)\n\ndef texto(name):\n    print(f\"Hola {name}, como estás?\")\n\nsaluda(\"Brais\", texto)\n\n# Función como retorno \n\ndef concatena_strings(name):\n    def get_last_name(last_name):\n        return name + \" \" + last_name\n    return get_last_name\nname = concatena_strings(\"Borja\") # devuelve función\nprint(name(\"Lv\")) #utlizamos función\nprint(concatena_strings(\"Brais\")(\"Moure\")) # pasamos todos los argumentos\n\n\n# Sistema: map(), filter(), sorted(), reduce\n\nmy_list = [\"Brais\", \"Borja\", \"María\", \"Sonia\"]\n\n\n# map\n\ndef to_lower(name):\n    return name.lower()\n\nprint(list(map(to_lower, my_list))) # aplica la función a todos los elementos de un iterable\n\n\n# filter: \n\ndef filter_by_name(name):\n    return name[0] == \"B\"\n\nprint(list(filter(filter_by_name, my_list)))\n\n\n# sorted\n\nprint(sorted(my_list))\nprint(sorted(my_list, reverse=True))\nprint(sorted(my_list, key=lambda x: x))\n\n# reduce\n\ndef reduce_one_line(x, y):\n    return x + \" \" + y\n\nprint(reduce(reduce_one_line, my_list))\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n * lista de calificaciones), utiliza funciones de orden superior para\n * realizar las siguientes operaciones de procesamiento y análisis:\n * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n *   y promedio de sus calificaciones.\n * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n *   que tienen calificaciones con un 9 o más de promedio.\n * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n * - Mayor calificación: Obtiene la calificación más alta de entre todas las\n *   de los alumnos.\n * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n\n\"\"\"\n\nstudent_list = [\n    {\"nombre\": \"Brais\", \"fecha_nacimiento\": \"29-04-1987\", \"calificaciones\": [10, 3, 5, 8]},\n    {\"nombre\": \"Borja\", \"fecha_nacimiento\": \"29-04-1992\", \"calificaciones\": [7, 6, 5, 9]},\n    {\"nombre\": \"Sonia\", \"fecha_nacimiento\": \"30-05-1999\", \"calificaciones\": [2, 10, 10, 4]},\n    {\"nombre\": \"María\", \"fecha_nacimiento\": \"13-01-1985\", \"calificaciones\": [4, 3, 4, 6]},\n]\n\ndef calcular_promedio_calificaciones(calificaciones):\n    return(sum(calificaciones)/len(calificaciones))\n\n\nprint(\"Promedio de calificaciones\")\nprint(list(map(lambda student: {\"name\": student[\"nombre\"], \"grades\": calcular_promedio_calificaciones(student[\"calificaciones\"])}, student_list)))\n\nprint(\"Mejores estudiantes\")\n\nprint(\n    list(\n        map(lambda student: \n        student[\"nombre\"], \n        filter(lambda student: calcular_promedio_calificaciones(student[\"calificaciones\"]) >=5, student_list)\n        )\n    )\n)\n\nprint(\"Nacimientos\")\n\ndef formatear_fechas(dates):\n    return datetime.strptime(dates, \"%d-%m-%Y\").date()\n\nprint(list(map(lambda student:\n                    student[\"nombre\"], \n                    sorted(student_list, key= lambda student: formatear_fechas(student[\"fecha_nacimiento\"]), reverse=True)\n                    )))\n\nprint(\"Mayor calificación\")\n\nprint(max(map(lambda student: max(student[\"calificaciones\"]), student_list)))"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/ggilperez.py",
    "content": "# higher-order functions\nimport time\nfrom datetime import datetime\n\n\ndef sum_nums(num_1: int, num_2: int) -> int:\n    return num_1 + num_2\n\n\ndef higher_order_function(num_1: int, num_2: int, func):\n    start = time.time()\n    result = func(num_1, num_2)\n    end = time.time()\n    print(f\"{func.__name__}({num_1}, {num_2}) = {result}. Function time: {end - start:.2f}\")\n    return result\n\n\nprint(higher_order_function(1, 2, sum_nums))\n\n# EXTRA\n\nstudents = [\n    {\n        \"name\": \"ggilperez\",\n        \"birthdate\": \"08-04-1993\",\n        \"grades\": [6, 7, 5, 8, 5, 9]\n    },\n    {\n        \"name\": \"mouredev\",\n        \"birthdate\": \"29-04-1987\",\n        \"grades\": [9, 9, 9, 10, 8, 9]\n    },\n    {\n        \"name\": \"midudev\",\n        \"birthdate\": \"13-07-1989\",\n        \"grades\": [8, 7, 9, 10, 8, 7]\n    }\n]\n\n\ndef average(grades: list[int]) -> float:\n    return round(sum(grades) / len(grades), 2)\n\n\n# Average\nprint(list(map(lambda x: {\"name\": x[\"name\"], \"average\": average(x[\"grades\"])}, students)))\n\n# Best above 9\nprint([x[\"name\"] for x in list(filter(lambda x: average(x[\"grades\"]) >= 9, students))])\n\n# Sort by birthdate\nprint(sorted(students, key=lambda x: datetime.strptime(x[\"birthdate\"], \"%d-%m-%Y\"), reverse=True))\n\n# Best grade\nprint(max(map(lambda x: max(x[\"grades\"]), students)))"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/gringoam.py",
    "content": "from functools import reduce\nfrom datetime import datetime\n\"\"\"\nEjercicio\n\"\"\"\n\ndef al_cubo(num, cuadrado ):\n    print(cuadrado(num)*num)\n\ndef cuadrado(num):\n    return num*num\n\nal_cubo(4, cuadrado)\n\n\n# Retorno de función\n\n\ndef apply_multiplier(n):\n    def multiplier(x):\n        return x * n\n    return multiplier\n\n\nmultiplier = apply_multiplier(2)\nprint(multiplier(5))\nprint(apply_multiplier(3)(2))\n\n#  Sistema\n\nnumbers = [1, 3, 4, 2, 5]\n\n# map()\n\n\ndef apply_double(n):\n    return n * 2\n\n\nprint(list(map(apply_double, numbers)))\n\n# filter()\n\n\ndef is_even(n):\n    return n % 2 == 0\n\n\nprint(list(filter(is_even, numbers)))\n\n# sorted()\n\nprint(sorted(numbers))\nprint(sorted(numbers, reverse=True))\nprint(sorted(numbers, key=lambda x: -x))\n\n# reduce()\n\n\ndef sum_values(x, y):\n    return x + y\n\n\nprint(reduce(sum_values, numbers))\n\n\"\"\"\nExtra\n\"\"\"\n# Alumno y Promedio  \nlista_alumnos=[\n    {\"nombre\": \"Diego\", \"fecha_nac\":\"09/06/1981\", \"notas\":[9,9,9.5,8]},\n    {\"nombre\": \"Pepe\", \"fecha_nac\":\"08/07/1982\", \"notas\":[2,3,4,8]},\n    {\"nombre\": \"Carlos\", \"fecha_nac\":\"08/06/1981\", \"notas\":[8,7.5,9,7]},\n]\n\ndef promedios_nota(notas):\n    return sum(notas)/ len(notas)\n\n\nprint(list(map(lambda alumno: {\"nombre\": alumno[\"nombre\"], \n                    \"promedio\":promedios_nota(alumno[\"notas\"]) },\n                lista_alumnos)))\n\n#Alumnos con promedio mayor o igaul a 9\nprint(\n    list(\n        map(\n            lambda alumno:  alumno[\"nombre\"], \n                   filter(lambda alumno: promedios_nota(alumno[\"notas\"])>=9, lista_alumnos) \n            )\n        )\n    )\n\n#Alumnos ordenados por edad \nprint(\n    sorted(lista_alumnos, key=lambda alumno: datetime.strptime(alumno[\"fecha_nac\"], \"%d/%m/%Y\"), reverse=True) \n        \n)\n\n#Mayor nota de entre todos los alumnos\n\nprint(max(map(lambda alumno: max(alumno[\"notas\"]), lista_alumnos )))"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/h4ckxel.py",
    "content": "\"\"\"Explora el concepto de funciones de orden superior en tu lenguaje\ncreando ejemplos simples (a tu elección) que muestren su funcionamiento\"\"\"\nfrom math import sqrt, pow\nfrom datetime import datetime\n\n\ndef right_triangle(func, triangle: dict):\n    return func(triangle)\n\n\ndef triangle_area(triangle: dict) -> float:\n    adjacent = triangle.get('adjacent')\n    opposite = triangle.get('opposite')\n    area = (adjacent * opposite) / 2\n    return area\n\n\ndef triangle_hypotenuse(triangle: dict) -> float:\n    adjacent = triangle.get('adjacent')\n    opposite = triangle.get('opposite')\n    hypotenuse = sqrt(pow(adjacent, 2) + pow(opposite, 2))\n    return hypotenuse\n\n\ntriangle_definition = {'adjacent': 3, 'opposite': 4}\nprint(f'Triangle definition\\n'\n      f'Adjacent side: {triangle_definition[\"adjacent\"]}\\n'\n      f'Opposite side: {triangle_definition[\"opposite\"]}')\n\n# Found the area of a triangle\nexample_area = right_triangle(triangle_area, triangle_definition)\nprint(f'The area of the right triangle is {example_area}')\n\n# Found the hypotenuse of a triangle\nexample_hypotenuse = right_triangle(triangle_hypotenuse, triangle_definition)\nprint(f'The hypotenuse of the right triangle is {example_hypotenuse}')\n\n\n\"\"\"DIFICULTAD EXTRA (opcional):\nDada una lista de estudiantes (con sus nombres, fecha de nacimiento y \nlista de calificaciones), utiliza funciones de orden superior para \nrealizar las siguientes operaciones de procesamiento y análisis:\n- Promedio calificaciones: Obtiene una lista de estudiantes por nombre y promedio de sus calificaciones.\n- Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes \nque tienen calificaciones con un 9 o más de promedio.\n- Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n- Mayor calificación: Obtiene la calificación más alta de entre todas las de los alumnos.\n- Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\"\"\"\n\n\nstudents = [\n    {\"name\": \"Andres\", \"dob\": \"2000-01-01\", \"grades\": [5.0, 7.0, 3.5]},\n    {\"name\": \"Brandon\", \"dob\": \"2002-02-02\", \"grades\": [10, 9.8, 9.0]},\n    {\"name\": \"Ash\", \"dob\": \"2001-05-05\", \"grades\": [8.5, 9.0, 7.5]},\n    {\"name\": \"Seiya\", \"dob\": \"2001-10-10\", \"grades\": [9.4, 9.0, 8.6]},\n    {\"name\": \"Alpha\", \"dob\": \"2000-12-25\", \"grades\": [7.0, 6.5, 6.0]},\n]\n\n\ndef students_gpa(students_list: list) -> list:\n    students_gpa_list = list()\n\n    for student in students_list:\n        student_grades = student['grades']\n        gpa = round((sum(student_grades) / len(student_grades)), 2)\n\n        students_gpa_list.append({'name': student['name'], 'gpa': gpa})\n\n    return students_gpa_list\n\n\ndef best_gpa(student_gpa: list) -> list:\n    bets_students_list = list()\n\n    for student in student_gpa:\n        gpa = student['gpa']\n        if gpa >= 9.0:\n            bets_students_list.append({'name': student['name'], 'gpa': gpa})\n\n    return bets_students_list\n\n\ndef best_student(best_students_list: list) -> list:\n    highest_gpa = max(student['gpa'] for student in best_students_list)\n    best_students = [{'name': student['name'], 'gpa': student['gpa']} for student in best_students_list if\n                     student['gpa'] == highest_gpa]\n    return best_students\n\n\ndef sort_list_by_age(students_list: list) -> list:\n    def get_dob(student):\n        return datetime.strptime(student['dob'], '%Y-%m-%d')\n\n    sorted_students = sorted(students_list, key=get_dob, reverse=True)\n    return sorted_students\n\n\ndef students_grades_functions(get_gpa, get_best_gpa, get_best_student, get_sorted_student_list, students_list: list):\n    # Get a list of students with their gpa\n    student_gpa_list = get_gpa(students_list)\n\n    # Get a list of the best gpas\n    best_gpa_list = get_best_gpa(student_gpa_list)\n\n    # Get a list of the best student\n    best_student = get_best_student(best_gpa_list)\n\n    # Get a list of students sorted by age\n    sorted_student_list = get_sorted_student_list(students_list)\n\n    return student_gpa_list, best_gpa_list, best_student, sorted_student_list\n\n\ngpa_list, best_gpa, higher_gpa, sorted_list = students_grades_functions(students_gpa, best_gpa, best_student, sort_list_by_age, students)\nprint('**** List of students with their gpa ****')\nprint(gpa_list)\nprint('**** List of best gpa ****')\nprint(best_gpa)\nprint('**** Best gpa ****')\nprint(higher_gpa)\nprint('**** Sorted list ****')\nprint(sorted_list)\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/hectorio23.py",
    "content": "# Autor: Héctor Adán\n# GitHub: https://github.com/hectorio23\n\nfrom datetime import datetime\nfrom functools import reduce\n\n# EJERCICIO:\n# Explora el concepto de funciones de orden superior en tu lenguaje \n# creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n#\n# DIFICULTAD EXTRA (opcional):\n# Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n# lista de calificaciones), utiliza funciones de orden superior para \n# realizar las siguientes operaciones de procesamiento y análisis:\n# - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n#   y promedio de sus calificaciones.\n# - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n#   que tienen calificaciones con un 9 o más de promedio.\n# - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n# - Mayor calificación: Obtiene la calificación más alta de entre todas las\n#   de los alumnos.\n# - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n\n# Definimos una clase para representar a un estudiante\nclass Student:\n    def __init__(self, name, birthdate, grades):\n        self.name = name\n        self.birthdate = birthdate\n        self.grades = grades\n\n# Función para calcular el promedio de una lista de calificaciones\ndef average(grades):\n    if not grades:\n        return 0.0\n    return sum(grades) / len(grades)\n\n# Lista de estudiantes\nstudents = [\n    Student(\"Adán\", \"2004-06-28\", [9.7, 10.0, 9.9]),\n    Student(\"Andy\", \"2006-07-17\", [9.5, 9.0, 9.0]),\n    Student(\"Mauricer\", \"2004-03-15\", [6.0, 7.5, 8.0]),\n    Student(\"David\", \"2005-06-30\", [10.0, 9.5, 9.5])\n]\n\n# Promedio de calificaciones\nprint(\"Promedio de calificaciones:\")\nfor student in students:\n    avg = average(student.grades)\n    print(f\"{student.name}: {avg:.2f}\")\n\n# Mejores estudiantes\nprint(\"\\nMejores estudiantes (promedio >= 9):\")\nfor student in students:\n    if average(student.grades) >= 9.0:\n        print(student.name)\n\n# Ordenar estudiantes por fecha de nacimiento, de más joven a más viejo\nstudents_sorted_by_age = sorted(students, key=lambda student: datetime.strptime(student.birthdate, \"%Y-%m-%d\"), reverse=True)\n\nprint(\"\\nEstudiantes ordenados por nacimiento (de más joven a más viejo):\")\nfor student in students_sorted_by_age:\n    print(f\"{student.name}: {student.birthdate}\")\n\n# Mayor calificación entre todos los estudiantes\nall_grades = [grade for student in students for grade in student.grades]\nhighest_grade = max(all_grades)\n\nprint(f\"\\nMayor calificación entre todos los estudiantes: {highest_grade}\")\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/hozlucas28.py",
    "content": "# pylint: disable=pointless-string-statement,missing-function-docstring,missing-module-docstring\n\nfrom typing import TypeVar, Callable, TypedDict\nfrom datetime import date\n\n\n\"\"\"\n    Higher order functions (HOF)...\n\"\"\"\n\nprint(\"Higher order functions (HOF)...\")\n\nT = TypeVar(\"T\")\n\n\ndef to_filtered(*, array: list[T], func: Callable[[T], bool]) -> list[T]:\n    sorted_array: list[T] = []\n\n    for element in array:\n        if func(element):\n            sorted_array.append(element)\n\n    return sorted_array\n\n\nnumbers: list[int] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\nprint(f\"\\n{numbers=}\")\n\neven_numbers: list[int] = to_filtered(\n    array=numbers, func=lambda number: number % 2 == 0\n)\nprint(f\"\\n{even_numbers=}\")\n\nodd_numbers: list[int] = to_filtered(array=numbers, func=lambda number: number % 2 != 0)\nprint(f\"\\n{odd_numbers=}\")\n\nprint(\n    \"\\n# ---------------------------------------------------------------------------------- #\\n\"\n)\n\n\n\"\"\"\n    Additional challenge...\n\"\"\"\n\nprint(\"Additional challenge...\\n\")\n\nStudent = TypedDict(\n    \"Student\",\n    {\n        \"born_date\": date,\n        \"name\": str,\n        \"qualifications\": list[float],\n    },\n)\n\ntype K = int | float\n\n\ndef get_average(*_numbers: K) -> K:\n    total: K = _numbers[0]\n    for number in _numbers[1:]:\n        total += number\n\n    return total / len(_numbers)\n\n\nstudents: list[Student] = [\n    {\n        \"born_date\": date(year=2000, month=1, day=1),\n        \"name\": \"John Doe\",\n        \"qualifications\": [8.5, 9.0, 7.5],\n    },\n    {\n        \"born_date\": date(year=1999, month=5, day=10),\n        \"name\": \"Jane Smith\",\n        \"qualifications\": [9.5, 9.5, 9.0],\n    },\n    {\n        \"born_date\": date(year=2001, month=3, day=15),\n        \"name\": \"Michael Johnson\",\n        \"qualifications\": [7.0, 8.0, 6.5],\n    },\n    {\n        \"born_date\": date(year=2002, month=7, day=20),\n        \"name\": \"Emily Davis\",\n        \"qualifications\": [9.0, 9.5, 8.5],\n    },\n    {\n        \"born_date\": date(year=2000, month=9, day=5),\n        \"name\": \"David Wilson\",\n        \"qualifications\": [8.0, 7.5, 8.5],\n    },\n    {\n        \"born_date\": date(year=1999, month=12, day=25),\n        \"name\": \"Olivia Martinez\",\n        \"qualifications\": [9.5, 9.0, 9.5],\n    },\n    {\n        \"born_date\": date(year=2001, month=8, day=12),\n        \"name\": \"Sophia Anderson\",\n        \"qualifications\": [7.5, 8.5, 7.0],\n    },\n    {\n        \"born_date\": date(year=2002, month=4, day=30),\n        \"name\": \"Daniel Thompson\",\n        \"qualifications\": [9.0, 8.0, 9.0],\n    },\n]\n\nprint(\"Students...\\n\")\nfor student in students:\n    print(f\"{student['name']} / {student['born_date']} / {student['qualifications']}\")\n\nstudents_with_name_and_average_qualification = list(\n    map(\n        lambda student: {\n            \"name\": student[\"name\"],\n            \"average_qualification\": get_average(*student[\"qualifications\"]),\n        },\n        students,\n    )\n)\n\nprint(\"\\nStudents with name and average qualification...\\n\")\nfor student in students_with_name_and_average_qualification:\n    print(f\"{student['name']} / {student['average_qualification']:.2f}\")\n\nstudents_with_average_qualification_more_than_nine: list[Student] = to_filtered(\n    array=students, func=lambda student: get_average(*student[\"qualifications\"]) >= 9\n)\n\nprint(\"\\nStudents with an average qualification more than nine...\\n\")\nfor student in students_with_average_qualification_more_than_nine:\n    print(f\"{student['name']} / {student['born_date']} / {student['qualifications']}\")\n\n\nsorted_students_by_born_date: list[Student] = sorted(\n    students, key=lambda student: student[\"born_date\"], reverse=True\n)\n\nprint(\"\\nSorted students by born date (youngest to oldest)...\\n\")\nfor student in sorted_students_by_born_date:\n    print(f\"{student['name']} / {student['born_date']} / {student['qualifications']}\")\n\nstudents_with_name_and_best_qualification = list(\n    map(\n        lambda student: {\n            \"name\": student[\"name\"],\n            \"best_qualification\": max(*student[\"qualifications\"]),\n        },\n        students,\n    )\n)\n\nprint(\"\\nStudents with name and best qualification...\\n\")\nfor student in students_with_name_and_best_qualification:\n    print(f\"{student['name']} / {student['best_qualification']}\")\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/idiegorojas.py",
    "content": "\"\"\"\n# 22 Funciones de Orden Superior\n\"\"\"\n\n# Son aquellas que pueden aceptar otras funciones como argumentos y/o como resultado.\n# En python las funciones son objetos de primera clase, son tratadas como otro tipo de dato.\n# Pueden ser asignadas a variables, pasadas como parametros o retornadas\n\n\"\"\"\nComo funciona?\n\"\"\"\n# Imaginemos que tenemos una caja de herramientas.\n# Una funcion de orden superior seria como un ahheramienta que puede usar varias herramientas  o incluso crear otra herramienta para realizar el trabajo\n\n\"\"\"\n1. Pasar una funcion como argumento\n\"\"\"\n# Usamos la funcion map(funcion, iterable)\n# Devuelve \n\ndef doblar(x):\n    return x * 2\n\ndatos = [1, 2, 3, 4, 5]\nresultado = map(doblar, datos)\nprint(list(resultado))\n\n\"\"\"\n2. Devolver una funcion como resultado\n\"\"\"\n# Una funcion crea y devuelve otra funcion\n\ndef saludar(idioma: str):\n\n    def saludo_en_es():\n        return 'Hola...'\n    \n    def saludo_en_en():\n        return 'Hello...'\n    \n    if idioma == 'es':\n        return saludo_en_es\n    else:\n        return saludo_en_en\n\n\nsaludo_es = saludar('es')\nsaludo_en = saludar('en') \nprint(saludo_es())\nprint(saludo_en())\n\n\n\"\"\"\nFunciones comunes en Python\n\"\"\"\n# filter(): Filtra elementos de una lista. Devuelve True o False\n# sorted(): Ordena elementos y se puede personalizar con el parametro \"key\"\n# map(): Aplica una funcion a cada elemento\n\ndef es_par(x):\n    return x % 2 == 0\n\nnumeros = [1, 2, 3, 4, 5, 6]\npares = filter(es_par, numeros)\nprint(list(pares))\n\n\n\"\"\"\nExtra\n\"\"\"\nfrom datetime import datetime\n\nestudiantes =[\n    {\"name\": \"Diego\", \"birthdate\": \"29-04-1987\", \"grades\": [5, 8.5, 3, 10]},\n    {\"name\": \"Andres\", \"birthdate\": \"04-08-2005\", \"grades\": [1, 9.5, 2, 4]},\n    {\"name\": \"Pedro\", \"birthdate\": \"15-12-2000\", \"grades\": [4, 6.5, 5, 2]},\n    {\"name\": \"Maria\", \"birthdate\": \"25-01-1980\", \"grades\": [10, 9, 9.7, 9.9]}\n]\n\ndef promedio(grades):\n    return sum(grades) / len(grades)\nprint('------------')\n\n# Promedio por estudiante\nprint('Promedio por estudiante: ')\nprint(list(map(lambda estudiantes: {'name': estudiantes['name'], 'promedio': promedio(estudiantes['grades'])}, estudiantes)))\nprint('------------')\n\n# Mejor estudiante\nprint('Mejor estudiante: ')\nprint(list(map(lambda estudiantes: estudiantes['name'], filter(lambda estudiantes: promedio(estudiantes['grades']) >= 9, estudiantes))))\nprint('------------')\n\n# Fecha nacimiento ordenada\nprint('Fecha ordenada por estudiante: ')\nprint(sorted(estudiantes, key=lambda estudiantes: datetime.strptime(estudiantes['birthdate'], '%d-%m-%Y'), reverse=True))\nprint('------------')\n\n# Calificacion mas alta\nprint('Calificacion mas lata de cada estudiante: ')\nprint((list(map(lambda estudiantes: {'name': estudiantes['name'], 'max': max(estudiantes['grades'])}, estudiantes))))"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/ignaciovihe.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el concepto de funciones de orden superior en tu lenguaje \n * creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n\"\"\"\n\n#Pasar una funcion como argumento.\ndef aplicar_funcion(f, valor):\n    return f(valor)\n\ndef cuadrado(l):\n    if isinstance(l, list):\n        return [e ** 2 for e in l]\n    else:\n        return l ** 2\n\nresultado = aplicar_funcion(cuadrado, [1, 2, 3, 4, 5, 6, 7, 8]) #Le paso como argumento una función\nprint(resultado)\n\n#Retornar una función\ndef multiplicador(n):\n    def multiplicar(x):\n        return x * n\n    return multiplicar  # Retorna una función\n\ntriplicar = multiplicador(3)\nprint(triplicar(5))\nprint(multiplicador(3)(2))  \n\n#Python ya tiene algunas fucciones de orden superior\n#map\nmy_data_str = [\"1\",\"2\",\"3\",\"4\",\"5\"]\nprint(my_data_str)\nmy_data_int = list(map(int,my_data_str))\nprint(my_data_int)\n\n\n#filter\ndef is_even(number):\n    return number % 2 == 0\n\neven = list(filter(is_even,my_data_int))\nprint(even)\n\n\n#reduce\nfrom functools import reduce\n\nnumeros = [1, 2, 3, 4, 5]\nsuma_total = reduce(lambda x, y: x + y, numeros)\nprint(suma_total)\n\n#sorted con funcion clave\nnombres = [\"Ana\", \"Juan\", \"Pedro\", \"Luis\"]  # Ordena por longitud de nombre\nprint(sorted(nombres, key=len))\nprint(sorted(nombres, reverse=True))\nprint(sorted(nombres, key=lambda x: x[::-1]))# Ordena los nombres segun su version invertida. Pero imprime los elementos normal.\n\n\n\"\"\" * DIFICULTAD EXTRA (opcional):\n * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n * lista de calificaciones), utiliza funciones de orden superior para \n * realizar las siguientes operaciones de procesamiento y análisis:\n * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n *   y promedio de sus calificaciones.\n * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n *   que tienen calificaciones con un 9 o más de promedio.\n * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n * - Mayor calificación: Obtiene la calificación más alta de entre todas las\n *   de los alumnos.\n * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n\"\"\"\n\nfrom datetime import datetime\nimport random\n\nstudents = [\n    {\"name\": \"Ignacio\", \"birth_date\":datetime(1985,2,23).date(), \"grades\": [round(random.uniform(0,10),2) for i in range(4)] },\n    {\"name\": \"Miguel\", \"birth_date\":datetime(1985,2,24).date(), \"grades\": [round(random.uniform(0,10),2) for i in range(4)] },\n    {\"name\": \"Lorena\", \"birth_date\":datetime(1984,1,25).date(), \"grades\": [round(random.uniform(0,10),2) for i in range(4)] },\n    {\"name\": \"Francisca\", \"birth_date\":datetime(2001,12,3).date(), \"grades\": [round(random.uniform(0,10),2) for i in range(4)] }\n]\n\ndef analise_data(data: list, f):\n    return f(data)\n\n\ndef average(grades):\n    return round(sum(grades) / len(grades), 2)\n\ndef students_average(data):\n    return list(map(lambda student: {\"name\": student[\"name\"], \"average\": average(student[\"grades\"])}, data))\n\ndef best_students(data):\n    return list(map(lambda student: student[\"name\"], filter(lambda student: average(student[\"grades\"]) > 6, data)))\n\ndef order_by_date(data):\n    return sorted(data, key=lambda x: x[\"birth_date\"],reverse=True)\n\ndef best_grade(data):\n    return max(list(map(lambda student: max(student[\"grades\"]), data)))\n\n\nprint(analise_data(students, students_average))\nprint(analise_data(students, best_students))\nprint(analise_data(students, order_by_date))\nprint(analise_data(students, best_grade))"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/ikeragi05.py",
    "content": "'''```\n/*\n * EJERCICIO:\n * Explora el concepto de funciones de orden superior en tu lenguaje \n * creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n *\n * DIFICULTAD EXTRA (opcional):\n * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n * lista de calificaciones), utiliza funciones de orden superior para \n * realizar las siguientes operaciones de procesamiento y análisis:\n * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n *   y promedio de sus calificaciones.\n * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n *   que tienen calificaciones con un 9 o más de promedio.\n * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n * - Mayor calificación: Obtiene la calificación más alta de entre todas las\n *   de los alumnos.\n * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n */\n```'''\nestudiantes = [\n    {\n        \"nombre\": \"Juan\",\n        \"fecha_nacimiento\": \"1999-05-10\",\n        \"calificaciones\": [9, 8,9, 10, 9]\n    },\n    {\n        \"nombre\": \"María\",\n        \"fecha_nacimiento\": \"2000-03-15\",\n        \"calificaciones\": [4, 7, 6, 5, 8]\n    },\n    {\n        \"nombre\": \"Pedro\",\n        \"fecha_nacimiento\": \"1998-11-20\",\n        \"calificaciones\": [6, 9, 4, 5, 7]\n    },\n    {\n        \"nombre\": \"Ana\",\n        \"fecha_nacimiento\": \"2001-07-05\",\n        \"calificaciones\": [7, 10, 8, 6, 9]\n    }\n]\n# Promedio calificaciones: Obtiene una lista de estudiantes por nombre y promedio de sus calificaciones.\ndef obtener_promedio(calificaciones):\n    return sum(calificaciones)/ len(calificaciones)\nprint(f\"Los promedios son\", list(map(lambda estudiante: {\"nombre\":estudiante['nombre'], \"promedio\": obtener_promedio(estudiante['calificaciones'])}, estudiantes)))\n# Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes que tienen calificaciones con un 9 o más de promedio.\nmejores_estudiantes= list(filter(lambda estudiante: obtener_promedio(estudiante['calificaciones'])>=9,estudiantes))\nprint(f\"Los mejores estudiantes son\")\nfor i in mejores_estudiantes:\n    print(i['nombre'])\n\n# Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\nprint(\"Lista ordenada por el mas joven: \", sorted(estudiantes, key=lambda estudiante: estudiante['fecha_nacimiento'], reverse=True))\n\n#Mayor calificación: Obtiene la calificación más alta de entre todas las de los alumnos.\ncalificaciones = [calificacion for estudiante in estudiantes for calificacion in estudiante['calificaciones']]\nprint(\"La calificación mas alta es: \", max(calificaciones))\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/isilanes.py",
    "content": "from datetime import datetime\n\n\ndef main():\n    print(\"===== MAIN =====\")\n\n    def add(a: int, b: int) -> int:\n        return a + b\n\n    def subtract(a: int, b: int) -> int:\n        return a - b\n\n    def higher_order_selector(operation: str) -> callable:\n        return {\n            \"plus\": add,\n            \"minus\": subtract,\n        }.get(operation, lambda a, b: None)\n\n    func = higher_order_selector(\"plus\")\n    assert func(1, 1) == 2\n    func = higher_order_selector(\"minus\")\n    assert func(3, 4) == -1\n    func = higher_order_selector(\"petecander\")\n    assert func(3, 4) is None\n    print(\"Función main() completada con éxito.\")\n\n\ndef extra():\n    print(\"\\n===== EXTRA =====\")\n\n    class Student:\n        def __init__(self, name: str, birth: datetime, grades: list[int]):\n            self.name = name\n            self.birth = birth\n            self.grades = grades\n\n        def __str__(self) -> str:\n            return f\"{self.name}: birth_date={self.birth}, grades={self.grades}\"\n\n    def average(values: list[float]) -> float | None:\n        return sum(values)/len(values) if values else None\n\n    students = [\n        Student(name=\"John\", birth=datetime(2000, 1, 1), grades=[10, 10, 9]),\n        Student(name=\"Amelie\", birth=datetime(1999, 12, 1), grades=[10, 10, 9.5]),\n        Student(name=\"Brais\", birth=datetime(1750, 2, 1), grades=[1, 1, 9.8]),\n        Student(name=\"isilanes\", birth=datetime(666, 12, 31), grades=[]),\n    ]\n\n    def grade_averages(student_list: list[Student]) -> None:\n        print(\"Estudiantes ordenados for nombre y notas, de forma ascendente (yo no hago las reglas):\")\n\n        data = [(s.name, average(s.grades), s) for s in student_list if s.grades]\n\n        for fields in sorted(data):\n            print(*fields)\n\n    def best_students(student_list: list[Student]) -> None:\n        print(\"Mejores estudiantes (no se especifica que ordenados):\")\n\n        data = [s.name for s in student_list if average(s.grades) and average(s.grades) >= 9]\n\n        for line in data:\n            print(line)\n\n    def students_by_age(student_list: list[Student]) -> None:\n        print(\"Estudiantes por edad:\")\n\n        data = [(s.birth, s) for s in student_list if s.birth]\n\n        for _, s in sorted(data, reverse=True):\n            print(s)\n\n    def highest_grade(student_list: list[Student]) -> None:\n        print(\"Mayor calificación (no se pide saber de quién es, y no se especifica que sea la media):\")\n\n        max_grade = 0\n        for student in student_list:\n            if not student.grades:\n                continue\n            max_grade = max(max_grade, max(student.grades))\n\n        print(max_grade)\n\n    def higher_order_callback_selector(operation: str) -> callable:\n        f = {\n            \"promedio\": grade_averages,\n            \"mejores\": best_students,\n            \"nacimiento\": students_by_age,\n            \"mayor_calificación\": highest_grade,\n        }.get(operation)\n\n        if f is None:\n            raise ValueError(f\"Operation '{operation}' is not valid.\")\n\n        return f\n\n    for action in (\"promedio\", \"mejores\", \"nacimiento\", \"mayor_calificación\"):\n        higher_order_callback_selector(action)(students)\n\n    print(\"Función extra() completada con éxito.\")\n\n\nif __name__ == \"__main__\":\n    main()\n    extra()\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/jptxaya.py",
    "content": "# #22 FUNCIONES DE ORDEN SUPERIOR\n\n\n# ```\n# /*\n#  * EJERCICIO:\n#  * Explora el concepto de funciones de orden superior en tu lenguaje \n#  * creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n#  * lista de calificaciones), utiliza funciones de orden superior para \n#  * realizar las siguientes operaciones de procesamiento y análisis:\n#  * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n#  *   y promedio de sus calificaciones.\n#  * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n#  *   que tienen calificaciones con un 9 o más de promedio.\n#  * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n#  * - Mayor calificación: Obtiene la calificación más alta de entre todas las\n#  *   de los alumnos.\n#  * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n#  */\n\n\ndef suma(a,b):\n    return a + b\n\ndef resta(a,b):\n    return a - b\n\nmultiplicar = lambda a,b: a*b\n\ndef operacion(action,a,b):\n    print(action(a,b,))\n\noperacion(suma,4,5)\noperacion(resta,5,4)\noperacion(multiplicar,5,4)\n\nlista = [1,2,3,4]\nprint(lista)\nprint(\"filter\")\nfiltered = list(filter(lambda a: a % 2 == 0,lista))\nprint(filtered)\n\nprint(\"map\")\nmapped = list(map(lambda a: a * 3,lista))\nprint(mapped)\n\nfrom functools import reduce\nprint(\"reduce\")\nreduced = reduce(lambda a, b: a+b, lista)\nprint(reduced)\n\nlista_estudiantes = [{\"name\": \"jptx1\",\"age\": 30, \"califications\":[5,6,8,8.7,4.5]},\n                     {\"name\": \"jptx2\",\"age\": 20, \"califications\":[9.2,6,8,9.3,9.5]},\n                     {\"name\": \"jptx3\",\"age\": 35, \"califications\":[4,5.5,8,9.7,4.5]},\n                     {\"name\": \"jptx4\",\"age\": 18, \"califications\":[9,9.3,8.5,9.9]}]\n\n\n\n\nprint(lista_estudiantes)\nprint(\"Promedio calificaciones\")\ndef promedio_calif(calif):\n    return reduce(lambda a,b: a+b,list(filter(lambda a: a >= 0 and a <= 10,calif))) / len(calif)\n\n\npromedio_calificaciones = list(map(lambda estudiante: dict(name = estudiante.get(\"name\"),\n                                                  califications = promedio_calif(estudiante.get(\"califications\"))),\n                                   lista_estudiantes))\n\nprint(promedio_calificaciones)\n\nprint(\"Mejores estudiantes\")\nprint(list(filter(lambda estudiante: estudiante[\"califications\"] >= 9,promedio_calificaciones)))\n\nprint(\"Ordenacion Estudiantes Nacimiento\")\nprint(sorted(lista_estudiantes,key= lambda estudiante: estudiante[\"age\"]))\n\nprint(\"Mayor Calificacion\")\nprint(max(map(lambda estudiante: max(estudiante[\"califications\"]),lista_estudiantes)))\n\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/juanmax2.py",
    "content": "from functools import reduce\nfrom datetime import datetime\n\n\"\"\"\nEjercicio\n\"\"\"\n\n# Función como argumento\n\ndef apply_func(func, x):\n    return func(x)\n\nprint(apply_func(len, \"Juanma\"))\n\n# Retorno de función\n\ndef apply_multiplier(n):\n    def multiplier(x):\n        return x * n\n    return multiplier\n\nmultiplier = apply_multiplier(2)\nprint(multiplier(4))\nprint(apply_multiplier(2)(4))\n\n# Sistema\n\nnumbers = [1, 3 , 5, 2, 4]\n\n# map()\n\ndef apply_duble(n):\n    return n * 2\n\nprint(list(map(apply_duble, numbers)))\n\n# filter()\n\ndef is_even(n):\n    return n % 2 == 0 \n\nprint(list(filter(is_even, numbers)))\n\n# sorted()\n\nprint(sorted(numbers))\nprint(sorted(numbers, reverse=True))\nprint(sorted(numbers, key=lambda x: -x))\n\n# reduce()\n\ndef sum(x, y):\n    return x + y\n\nprint(reduce(sum, numbers))\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n * lista de calificaciones), utiliza funciones de orden superior para \n * realizar las siguientes operaciones de procesamiento y análisis:\n * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n *   y promedio de sus calificaciones.\n * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n *   que tienen calificaciones con un 9 o más de promedio.\n * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n * - Mayor calificación: Obtiene la calificación más alta de entre todas las\n *   de los alumnos.\n * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n\"\"\"\n\nestudiantes = [\n    {\"name\": \"Maria\", \"birthdate\" : \"10-06-1997\", \"notas\" : [10, 9, 8]},\n    {\"name\": \"Juanma\", \"birthdate\" : \"13-11-1992\", \"notas\" : [7, 9, 8]},\n    {\"name\": \"David\", \"birthdate\" : \"24-10-1992\", \"notas\" : [10, 9, 9]},\n    \n]\n\ndef media(notas):\n    suma = 0\n    for nota in notas:\n        suma += nota\n    longitud = len(notas)\n    return suma / longitud\n\n# Promedio\n\nprint(\n    list(map(lambda estudiante: {\n    \"name\" : estudiante[\"name\"], \n    \"media\": media(estudiante[\"notas\"])}, estudiantes)\n         )\n    )\n\n# Los mejores\n\n\nprint(\n    list(\n        map(lambda estudiante: \n            estudiante[\"name\"], \n            filter(lambda estudiante: media(estudiante[\"notas\"]) >= 9, estudiantes)\n            )\n         )\n    )\n\n# Ordenar por mas joven\n\nprint(sorted(estudiantes, key=lambda estudiante: datetime.strptime(\n    estudiante[\"birthdate\"], \"%d-%m-%Y\"), reverse=True))\n\n# Mayor calificación\n\nprint(max(map(lambda estudiante: max(estudiante[\"notas\"]), estudiantes)))\n\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/juanppdev.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el concepto de funciones de orden superior en tu lenguaje \n * creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n\"\"\"\n\ndef aplicar_funcion(func, valor):\n    return func(valor)\n\ndef cuadrado(x):\n    return x * x\n\nresultado = aplicar_funcion(cuadrado, 5)\nprint(resultado)  # Salida: 25\n\n\ndef crear_multiplicador(n):\n    def multiplicar(x):\n        return x * n\n    return multiplicar\n\nmultiplicar_por_3 = crear_multiplicador(3)\nprint(multiplicar_por_3(10))  # Salida: 30\n\nfrom functools import reduce\n\n# `map` aplica una función a cada elemento de una lista\nnumeros = [1, 2, 3, 4, 5]\ncuadrados = list(map(cuadrado, numeros))\nprint(cuadrados)  # Salida: [1, 4, 9, 16, 25]\n\n# `filter` filtra elementos de una lista según una condición\ndef es_par(x):\n    return x % 2 == 0\n\npares = list(filter(es_par, numeros))\nprint(pares)  # Salida: [2, 4]\n\n# `reduce` aplica una función acumulativa a los elementos de una lista\ndef sumar(x, y):\n    return x + y\n\nsuma_total = reduce(sumar, numeros)\nprint(suma_total)  # Salida: 15\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n * lista de calificaciones), utiliza funciones de orden superior para \n * realizar las siguientes operaciones de procesamiento y análisis:\n * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n *   y promedio de sus calificaciones.\n * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n *   que tienen calificaciones con un 9 o más de promedio.\n * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n * - Mayor calificación: Obtiene la calificación más alta de entre todas las\n *   de los alumnos.\n * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n\"\"\"\n\nfrom datetime import datetime\n\n# Lista de estudiantes\nestudiantes = [\n    {\"nombre\": \"Ana\", \"fecha_nacimiento\": \"2005-05-14\", \"calificaciones\": [8.5, 9.0, 7.5]},\n    {\"nombre\": \"Luis\", \"fecha_nacimiento\": \"2004-08-22\", \"calificaciones\": [9.5, 9.0, 9.5]},\n    {\"nombre\": \"Carlos\", \"fecha_nacimiento\": \"2006-01-30\", \"calificaciones\": [6.0, 7.0, 8.0]},\n    {\"nombre\": \"Marta\", \"fecha_nacimiento\": \"2003-12-10\", \"calificaciones\": [9.0, 9.5, 10.0]}\n]\n\n# Promedio calificaciones\npromedios = list(map(lambda est: {\"nombre\": est[\"nombre\"], \"promedio\": sum(est[\"calificaciones\"]) / len(est[\"calificaciones\"])}, estudiantes))\nprint(\"Promedio calificaciones:\", promedios)\n\n# Mejores estudiantes\nmejores_estudiantes = list(filter(lambda est: sum(est[\"calificaciones\"]) / len(est[\"calificaciones\"]) >= 9, estudiantes))\nmejores_estudiantes_nombres = list(map(lambda est: est[\"nombre\"], mejores_estudiantes))\nprint(\"Mejores estudiantes:\", mejores_estudiantes_nombres)\n\n# Nacimiento (ordenado desde el más joven)\nestudiantes_ordenados = sorted(estudiantes, key=lambda est: datetime.strptime(est[\"fecha_nacimiento\"], \"%Y-%m-%d\"), reverse=True)\nprint(\"Estudiantes ordenados por fecha de nacimiento:\", list(map(lambda est: est[\"nombre\"], estudiantes_ordenados)))\n\n# Mayor calificación\nmayor_calificacion = max(map(lambda est: max(est[\"calificaciones\"]), estudiantes))\nprint(\"Mayor calificación:\", mayor_calificacion)\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/kenysdev.py",
    "content": "# ╔═════════════════════════════════════╗\n# ║ Autor:  Kenys Alvarado              ║\n# ║ GitHub: https://github.com/Kenysdev ║\n# ║ 2024 -  Python                      ║\n# ╚═════════════════════════════════════╝\n\n# -----------------------------------\n# * FUNCIONES DE ORDEN SUPERIOR\n# -----------------------------------\n\n\"\"\"\n* EJERCICIO #1:\n* Explora el concepto de funciones de orden superior en tu lenguaje \n* creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n\"\"\"\n\ndef arithmetic_op(func: object):\n    def wrapper(x: int, y: int):\n        return func(x, y)\n    return wrapper\n\ndef add(x: int, y: int):\n    return x + y\n\ndef subtract(x: int, y: int):\n    return x - y\n\ndef multiply(x: int, y: int):\n    return x * y\n\naddition = arithmetic_op(add)\nsubtraction = arithmetic_op(subtract)\nmultiplication = arithmetic_op(multiply)\n\nr_addition = addition(2, 3)\nr_subtraction = subtraction(10, 5)\nr_multip = multiplication(2, 5)\n\n\nprint(f\"\"\"EJERCICIO #1\nResultado de la suma:    {r_addition}\nResultado de la resta:   {r_subtraction}\nResultado de la multip.: {r_multip}\n\"\"\")\n\n# ______________________________________\n\"\"\"\n* EJERCICIO #2:\n* Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n* lista de calificaciones), utiliza funciones de orden superior para \n* realizar las siguientes operaciones de procesamiento y análisis:\n* - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n*   y promedio de sus calificaciones.\n* - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n*   que tienen calificaciones con un 9 o más de promedio.\n* - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n* - Mayor calificación: Obtiene la calificación más alta de entre todas las\n*   de los alumnos.\n* - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n\"\"\"\n\nstudents_list = [\n    {\"name\": \"Ken\", \"dob\": \"2012-04-21\", \"grades\": [9.5, 9.4, 9.3, 9.2]},\n    {\"name\": \"Ben\", \"dob\": \"2012-03-20\", \"grades\": [8.5, 8.4, 8.3, 8.2]},\n    {\"name\": \"Ada\", \"dob\": \"2012-02-19\", \"grades\": [7.5, 7.4, 7.3, 7.2]},\n    {\"name\": \"zoe\", \"dob\": \"2012-01-18\", \"grades\": [9.0, 9.1, 9.0, 9.1]},\n]\n\ndef higher_order_fun(msg: str, print_fn: object) -> object:\n    def wrapper(students: list):\n        print(f\"\\n----\\n{msg}\")\n        for student in students:\n            print_fn(student)\n\n    return wrapper\n\ndef print_gpa(student: dict):\n    grades: list = student[\"grades\"]\n    average_grade: float = sum(grades) / len(grades)\n    print(student[\"name\"], average_grade)\n\ndef print_top(student: dict):\n    grades: list = student[\"grades\"]\n    average: float = sum(grades) / len(grades)\n    if average >= 9: \n        print(student[\"name\"])\n\ndef print_bth(student: dict):\n    print(student[\"name\"], student[\"dob\"])\n\ndef print_hgg(student: dict):\n    max_grade: float = max(student[\"grades\"])\n    name: str = student[\"name\"]\n    print(name, max_grade)\n\ngrade_point_average = higher_order_fun(\"Promedio calificaciones\", print_gpa)\ntop_students = higher_order_fun(\"Mejores estudiantes:\", print_top)\nbirth_order = higher_order_fun(\"Por nacimiento:\", print_bth)\nhighest_grade = higher_order_fun(\"Mayor calificación:\", print_hgg)\n\nprint(\"EJERCICIO #2\")\n\ngrade_point_average(students_list)\ntop_students(students_list)\nbirth_order(sorted(students_list, key=lambda student: student[\"dob\"]))\nhighest_grade(students_list)\n\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/mhayhem.py",
    "content": "# @Author Daniel Grande (Mhayhem)\n\nfrom datetime import date, datetime\n\n# EJERCICIO:\n# Explora el concepto de funciones de orden superior en tu lenguaje \n# creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n\ndef greet(name):\n    return f\"Hola {name}\"\n\ndef process_greeting(text: str, function):\n    return function(text)\n\nprint(process_greeting(\"Dany\", greet))\n    \n# DIFICULTAD EXTRA (opcional):\n# Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n# lista de calificaciones), utiliza funciones de orden superior para \n# realizar las siguientes operaciones de procesamiento y análisis:\n# - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n#   y promedio de sus calificaciones.\n# - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n#   que tienen calificaciones con un 9 o más de promedio.\n# - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n# - Mayor calificación: Obtiene la calificación más alta de entre todas las\n#   de los alumnos.\n# - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n\nstudents = [\n    {\n    \"name\": \"Dany\",\n    \"birth_day\": date(1999, 7, 15),\n    \"grades\": [6, 7.5, 9, 9, 10, 9]\n    },\n    {\n    \"name\": \"Carlos\",\n    \"birth_day\": date(1999, 2, 13),\n    \"grades\": [9, 9, 10, 9, 9, 10]\n    },\n    {\n    \"name\": \"Sandra\",\n    \"birth_day\": date(2000, 12, 31),\n    \"grades\": [9, 8.5, 9, 9, 9, 9.5]\n    }\n]\ndef students_info(func1, func2, func3, func4, array):\n    print(\"Promedios:\")\n    print(func1(array))\n    print(\"Promedios mas altos:\")\n    print(func2(array))\n    print(\"Estudiantes ordenados de menor a mayor:\")\n    print(func3(array))\n    print(\"Mejor promedio:\")\n    print(func4(array))\n\ndef average_grades(array: list):\n    return [\n        f\"{student['name']}; Promedio: {sum(student['grades']) / len(student['grades']):.1f}\" for student in array\n    ]\n\ndef highest_average(array: list):\n    return [\n        student['name']\n        for student in array\n        if (sum(student['grades']) / len(student['grades'])) >= 9\n    ]\ndef youngest(array: list):\n    today = date.today()\n    sorted_list = sorted(array, key=lambda s: s[\"birth_day\"], reverse=True)\n    return [\n        f\"{item['name']} {today.year - (item['birth_day'].year) - ((today.month, today.day) < (item[\"birth_day\"].month, item[\"birth_day\"].day))} años\"\n        for item in sorted_list\n    ]\n\ndef the_best(array: list):\n    return max(array, key=lambda s: sum(s[\"grades\"]) / len(s[\"grades\"]))[\"name\"]\n\nstudents_info(average_grades, highest_average, youngest, the_best, students)"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/mouredev.py",
    "content": "from functools import reduce\nfrom datetime import datetime\n\n\"\"\"\nEjercicio\n\"\"\"\n\n# Función como argumento\n\n\ndef apply_func(func, x):\n    return func(x)\n\n\nprint(apply_func(len, \"MoureDev\"))\n\n# Retorno de función\n\n\ndef apply_multiplier(n):\n    def multiplier(x):\n        return x * n\n    return multiplier\n\n\nmultiplier = apply_multiplier(2)\nprint(multiplier(5))\nprint(apply_multiplier(3)(2))\n\n#  Sistema\n\nnumbers = [1, 3, 4, 2, 5]\n\n# map()\n\n\ndef apply_double(n):\n    return n * 2\n\n\nprint(list(map(apply_double, numbers)))\n\n# filter()\n\n\ndef is_even(n):\n    return n % 2 == 0\n\n\nprint(list(filter(is_even, numbers)))\n\n# sorted()\n\nprint(sorted(numbers))\nprint(sorted(numbers, reverse=True))\nprint(sorted(numbers, key=lambda x: -x))\n\n# reduce()\n\n\ndef sum_values(x, y):\n    return x + y\n\n\nprint(reduce(sum_values, numbers))\n\n\"\"\"\nExtra\n\"\"\"\n\nstudents = [\n    {\"name\": \"Brais\", \"birthdate\": \"29-04-1987\", \"grades\": [5, 8.5, 3, 10]},\n    {\"name\": \"moure\", \"birthdate\": \"04-08-1995\", \"grades\": [1, 9.5, 2, 4]},\n    {\"name\": \"mouredev\", \"birthdate\": \"15-12-2000\", \"grades\": [4, 6.5, 5, 2]},\n    {\"name\": \"supermouredev\", \"birthdate\": \"25-01-1980\",\n        \"grades\": [10, 9, 9.7, 9.9]}\n]\n\n\ndef average(grades):\n    return sum(grades) / len(grades)\n\n# Promedio\n\n\nprint(\n    list(map(lambda student: {\n        \"name\": student[\"name\"],\n        \"average\": average(student[\"grades\"])}, students)\n    )\n)\n\n# Mejores\n\nprint(\n    list(\n        map(lambda student:\n            student[\"name\"],\n            filter(lambda student: average(student[\"grades\"]) >= 9, students)\n            )\n    )\n)\n\n# Fecha de nacimiento ordenada\n\nprint(sorted(students, key=lambda student: datetime.strptime(\n    student[\"birthdate\"], \"%d-%m-%Y\"), reverse=True))\n\n# Califiación más alta\n\nprint(max(map(lambda student: max(student[\"grades\"]), students)))\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/mrodara.py",
    "content": "### FUNCIONES DE ORDEN SUPERIOR EN PYTHON\n\n'''\nUna función de orden superior es aquella que:\n Acepta una función como argumento.\n Devuelve otra función como resultado.\n O ambas cosas.\n'''\n\n# Ejemplo de función que acepta otra como argumento:\ndef calculator(x: float, y: float, operation) -> float:\n    return operation(x, y)\n\ndef sum(a: float, b: float) -> float:\n    return a + b\n\ndef product(a: float, b: float) -> float:\n    return a * b\n\nprint(calculator(10,20, sum)) # Salida 30\nprint(calculator(10,20, product)) # Salida 200\n\n# Ejemplo devolviendo otra función como resultado (lambda):\ndef new_calculator(operation):\n    if operation.lower() == \"sum\":\n        return lambda a, b: a + b\n    elif operation.lower() == \"product\":\n        return lambda a, b: a * b\n    else:\n        return lambda a, b: None\n\nmy_sum = new_calculator(\"sum\")\nmy_product = new_calculator(\"product\")\n\nprint(my_sum(5,5)) # Salida 10\nprint(my_product(5,5)) # Salida 25\n\n# Python ofrece varias funciones de orden superior predefinidas, como map, filter, y reduce.\n\nmy_list = [i for i in range(1,11)]\n\nsquare = map(lambda x: x**2, my_list)\nprint(list(square))\n\npairs = filter(lambda x: x%2 == 0, my_list)\n\nprint(list(pairs))\n\n# Para reduce necesitamos importar functools\nfrom functools import reduce\n\nsum = reduce(lambda x, y: x + y, my_list)\nprint(sum) # Salida 55\n\n### EJERCICIO EXTRA\nstudents = [\n    {\n        \"name\": \"Manuel Rodriguez\",\n        \"birth_date\": \"2002-05-14\",\n        \"grades\": [8.5, 7.0, 9.0, 6.5]\n    },\n    {\n        \"name\": \"Lucia Perez\",\n        \"birth_date\": \"2003-11-22\",\n        \"grades\": [7.5, 9.0, 8.0, 9.5]\n    },\n    {\n        \"name\": \"Pedro Sanchez\",\n        \"birth_date\": \"2001-08-05\",\n        \"grades\": [6.0, 5.5, 7.0, 6.5]\n    },\n    {\n        \"name\": \"Ana Fernandez\",\n        \"birth_date\": \"2004-01-30\",\n        \"grades\": [9.0, 8.5, 9.5, 10.0]\n    },\n    {\n        \"name\": \"Carlos Garcia\",\n        \"birth_date\": \"2002-07-19\",\n        \"grades\": [7.0, 7.5, 6.0, 8.0]\n    }\n]\n\n# Promedio de calificaciones:\ndef analysis(iterable: list, operation):\n    return operation(iterable)\n\ndef avg(iterable: list) ->list:\n    \n    avg_students = []\n    \n    for element in iterable:\n        avg = 0\n        for grade in element[\"grades\"]:\n            avg += grade\n        avg /= len(element[\"grades\"])\n        \n        avg_students.append({\n            \"name\": element[\"name\"],\n            \"avg\": avg\n        })\n        \n    return avg_students\n\navg_students = analysis(students, avg)\n\nprint(list(avg_students))\n\n# Aprovechamos la lista avg_students para obtener los mejores estudiantes, en este caso usaremos filter\nbest_students = filter(lambda x: x['avg'] >=9 and x['avg']<=10, avg_students)\nprint(list(best_students))\n\n# Lista de estudiantes ordenada por fecha de nacimiento\nstudents_by_birthday = sorted(students, key=lambda p: p['birth_date'])\nprint(list(students_by_birthday))\n\n# Obtención de la nota más alta de entre todas las obtenidas por los estudiantes\nmax_grade = reduce(lambda x,y: max(x,y), [grade for student in students for grade in student[\"grades\"]])\nprint(max_grade)\n\n### FIN EJERCICIO EXTRA\n\n\n### FIN FUNCIONES DE ORDEN SUPERIOR EN PYTHON\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/neslarra.py",
    "content": "\"\"\"\n EJERCICIO:\n Explora el concepto de funciones de orden superior en tu lenguaje \n creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n\n DIFICULTAD EXTRA (opcional):\n Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n lista de calificaciones), utiliza funciones de orden superior para \n realizar las siguientes operaciones de procesamiento y análisis:\n - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n   y promedio de sus calificaciones.\n - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n   que tienen calificaciones con un 9 o más de promedio.\n - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n - Mayor calificación: Obtiene la calificación más alta de entre todas las\n   de los alumnos.\n - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n\"\"\"\nfrom functools import reduce\nfrom random import uniform, randint, choice\nfrom datetime import datetime\nfrom typing import Any, Union\n\ntype_number = Union[int, float]\ntype_str_number = Union[oct, hex, bin]\n\nprint(f\"{'#' * 47}\")\nprint(f\"##  Explicación  {'#' * 30}\")\nprint(f\"{'#' * 47}\")\n\nprint(r\"\"\"Para profundizar sobre este tema buscar \"programación funcional en python\".\nLas funciones de orden superior son funciones capaces de recibir como argumento y/o retornar otra función, por ejemplo:\n\n1- función \"operar\" que recibe como argumento la función a ejecutar (\"sumar\" o \"multiplicar\") más sus argumentos:\n    def sumar(*args: type_number) -> type_number:\n        return sum(args)\n    \n    \n    def multiplicar(*args: type_number) -> type_number:\n        return reduce(lambda a, b: a * b, args)\n    \n    \n    def operar(funcion, *args: type_number) -> type_number:\n        return funcion(*args)\n    \n    \n    print(\"Aritmética pasando función como argumento: \")\n    print(f\"\\tSumar: {operar(sumar, 1, 2.1, 3, 4.75)}\")\n    print(f\"\\tMultiplicar: {operar(multiplicar, 1, 2, 3)}\")\n\n2- función \"conversor\" que recibe un string y retorna una función (\"binario\", \"hexadecimal\" o \"octal\"):\n    def conversor(tipo: str) -> type_str_number:\n        def binario(numero: int) -> str:\n            return bin(numero).lstrip(\"0b\")\n    \n        def hexadecimal(numero: int) -> str:\n            return hex(numero).lstrip(\"0x\")\n    \n        def octal(numero: int) -> str:\n            return oct(numero).lstrip(\"0o\")\n    \n        funcion = {\"binario\": binario, \"hexadecimal\": hexadecimal, \"octal\": octal}\n    \n        return funcion[tipo]\n    \n    \n    data = 27\n    print(\"Calculo conversiones numéricas con funcioón que retorna función: \")\n    print(f\"\\tBinario: {conversor('binario')(data)}\")\n    print(f\"\\tHexa: {conversor('hexadecimal')(data)}\")\n    print(f\"\\tOctal: {conversor('octal')(data)}\")\n\n3- usando \"lambda\" que es una función aónima para resolver un paso sencillo:\n    data = 3\n    circulo = lambda r: (3.1416 * pow(r, 2)).__round__(2)\n    area = circulo(data)\n    print(\"Calculo área de círculo usando lambda: \", end=\"\")\n    print(area)\n\n4- usando \"map\" que aplica una función a un iterable:\n    data = [\"2.7178\", \"3.1416\", \"12\", \"123.45678\", \"49\"]\n    mapa = lambda a: float(a).__round__(2)\n    lista_mapeada = map(mapa, data)\n    print(\"Paso a decimal de dos pocisiones con map: \", end=\"\")\n    print(list(lista_mapeada))\n\n5- usando \"filter\" que mantiene o excluye elementos de un iterable:\n    data = [\"Hola\", 123, (1, 2, 3), \"Chau\", 34, 33, \"76\", 3.1416, {\"azul\", \"rojo\", \"amarillo\"}, \"2.7178\"]\n    filtro = lambda a: a.__class__.__name__ in (\"int\", \"float\") or (a.__class__.__name__ == \"str\" and a.replace('.', '', 1).isdecimal())\n    lista_filtrada = filter(filtro, data)\n    print(\"Extraigo tipos numéricos de lista de tipo heterogéneos con filter: \", end=\"\")\n    print(list(lista_filtrada))\n\n6- usando reduce que aplica una función a un iterable tomando de a dos elementos por vez (el resultado de aplicar la función + el elemento que sigue):\n    data = \"lorem ipsum dolor sit amet consectetur adipiscing elit sed do eiusmod tempor\"\n    cuenta_o = lambda a, b: a + sum(1 for x in b if x == 'o')\n    reduccion = reduce(cuenta_o, data, 0)\n    print(\"Cuento 'o' en texto usando reduce: \", end=\"\")\n    print(reduccion)\n\nTodo ésto retorna:\n\nAritmética pasando función como argumento: \n    Sumar: 10.85\n    Multiplicar: 6\n\nCalculo conversiones numéricas con funcioón que retorna función: \n    Binario: 11011\n    Hexa: 1b\n    Octal: 33\n\nCalculo área de círculo usando lambda: 28.27\n\nPaso a decimal de dos pocisiones con map: [2.72, 3.14, 12.0, 123.46, 49.0]\n\nExtraigo tipos numéricos de lista de tipo heterogéneos con filter: [123, 34, 33, '76', 3.1416, '2.7178']\n\nCuento 'o' en texto usando reduce: 7\n\"\"\")\n\nprint(f\"\\n{'#' * 52}\")\nprint(f\"##  Dificultad Extra  {'#' * 30}\")\nprint(f\"{'#' * 52}\")\n\n\ndef get_random_student(function: str) -> Any:\n    def get_valid_name() -> str:\n        import requests\n        api_names_url = \"https://randomuser.me/api/\"\n        lower_letters = list(map(chr, range(ord(\"a\"), ord(\"z\") + 1)))\n\n        while True:\n            req = requests.get(api_names_url)\n            data = req.json()\n            firstname = data[\"results\"][0][\"name\"][\"first\"]\n            lastname = data[\"results\"][0][\"name\"][\"last\"]\n            if all([c.lower() in lower_letters for c in firstname + lastname]):  # evitar otros alfabetos\n                break\n        return firstname + \" \" + lastname\n\n    def get_valid_birthdate() -> datetime:\n        return datetime(randint(1996, 2005), randint(1, 12), randint(1, 28))\n\n    def get_list_grades() -> list:\n        base = choice([0, 5, 8])  # to enforce a better grades sample\n        return list(map(lambda a: uniform(base, 10).__round__(2), range(1, 11)))\n\n    f_name = {\"get_valid_name\": get_valid_name, \"get_valid_birthdate\": get_valid_birthdate, \"get_list_grades\": get_list_grades}\n    return f_name[function]\n\n\ndef get_student_list(total: int) -> list:\n    student_list = []\n    print(f\"\\nAdding {total} students .\", end=\"\")\n    for ind in range(total):\n        student_list.append({\"name\": get_random_student(\"get_valid_name\")(),\n                             \"birthdate\": get_random_student(\"get_valid_birthdate\")(),\n                             \"grades\": get_random_student(\"get_list_grades\")()})\n        print(\".\", end=\"\")\n    print()\n    return student_list\n\n\ndef get_average_grades() -> list:\n    averages = []\n\n    avg_grades = lambda a, b: (a / b).__round__(2)\n    for s in student_list:\n        suma = reduce(lambda a, b: a + b, s[\"grades\"])      # obvio, sum() funciona... es para dar ejemplo de reduce\n        largo = s[\"grades\"].__len__()\n        averages.append({\"name\": s[\"name\"], \"average\": avg_grades(suma, largo)})\n    return averages\n\n\ndef print_stats(function: str) -> None:\n    def list_students():\n        for std in student_list:\n            print(f\"\\tStudent: {std['name']}  /  Birthdata: {std['birthdate'].strftime('%b %d, %Y')}  /  Grades: {std['grades']}\")\n\n    def average_grades_per_student():\n        for avg in sorted(get_average_grades(), key=lambda d: d[\"average\"], reverse=True):\n            print(f\"\\tStudent: {avg['name']}  /  Average: {avg['average']}\")\n\n    def best_averages():\n        for avg in filter(lambda a: a[\"average\"] >= 9.0, sorted(get_average_grades(), key=lambda d: d[\"average\"], reverse=True)):\n            print(f\"\\tStudent: {avg['name']}  /  Average: {avg['average']}\")\n\n    def best_student():\n        std = (sorted(get_average_grades(), key=lambda d: d[\"average\"], reverse=True)[0])\n        print(f\"\\tStudent: {std['name']}  /  Average: {std['average']}\")\n\n    def get_birthdate():\n        for std in sorted(student_list, key=lambda d: d[\"birthdate\"]):\n            print(f\"\\tStudent: {std['name']}  /  Birthdata: {std['birthdate'].strftime('%b %d, %Y')}\")\n\n    f_callable = {\"list_students\": list_students, \"average_grades_per_student\": average_grades_per_student,\n                  \"best_averages\": best_averages, \"get_birthdate\": get_birthdate, \"best_student\": best_student}\n    f_callable[function]()\n\n\nstudent_list = sorted(get_student_list(30), key=lambda d: d[\"name\"])\n\nprint(\"\\nStudents\")\nprint_stats(\"list_students\")\nprint(\"\\nAverage grades\")\nprint_stats(\"average_grades_per_student\")\nprint(\"\\nAverages >= 9.0\")\nprint_stats(\"best_averages\")\nprint(\"\\nBest student\")\nprint_stats(\"best_student\")\nprint(\"\\nBirthdates\")\nprint_stats(\"get_birthdate\")\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/nlarrea.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el concepto de funciones de orden superior en tu lenguaje \n * creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n *\n * DIFICULTAD EXTRA (opcional):\n * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n * lista de calificaciones), utiliza funciones de orden superior para \n * realizar las siguientes operaciones de procesamiento y análisis:\n * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n *   y promedio de sus calificaciones.\n * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n *   que tienen calificaciones con un 9 o más de promedio.\n * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n * - Mayor calificación: Obtiene la calificación más alta de entre todas las\n *   de los alumnos.\n * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n\"\"\"\n\n# Funciones de orden superior -> funciones que toman una función como argumento\n# o que devuelven una función como resultado\n\n# map\n\n\ndef cube(x: int) -> int:\n    return x**3\n\n\nnumbers = [1, 2, 3, 4, 5]\ncube_numbers = list(map(cube, numbers))\nprint(cube_numbers)\n\n\n# filter\n\n\ndef even(x: int) -> bool:\n    return x % 2 == 0\n\n\neven_numbers = list(filter(even, numbers))\nprint(even_numbers)\n\n\n# sorted\n\nnumbers = [1, 4, 2, 6, 9]\nprint(sorted(numbers))\nprint(sorted(numbers, reverse=True))\n\nfruits = [\"banana\", \"apple\", \"melon\", \"pineapple\"]\nprint(sorted(fruits, key=len))  # sorts fruits based on the length of strings\n# ['apple', 'melon', 'banana', 'pineapple']\nprint(sorted(fruits, reverse=True, key=len))\n# ['pineapple', 'banana', 'apple', 'melon']\n\n\n# reduce\n\nfrom functools import reduce\n\n\nnumbers = [1, 2, 3, 4, 5]\nsum_of_values = reduce(lambda a, b: a + b, numbers)\nprint(sum_of_values)  # 15\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n * lista de calificaciones), utiliza funciones de orden superior para \n * realizar las siguientes operaciones de procesamiento y análisis:\n * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n *   y promedio de sus calificaciones.\n * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n *   que tienen calificaciones con un 9 o más de promedio.\n * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n * - Mayor calificación: Obtiene la calificación más alta de entre todas las\n *   de los alumnos.\n * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n\"\"\"\n\nstudents_data: list[dict] = [\n    {\n        \"first_name\": \"Brennan\",\n        \"last_name\": \"Wiza\",\n        \"birth_date\": \"2004, 2, 11\",\n        \"marks\": [5, 6.7, 8, 9.2, 3],\n    },\n    {\n        \"first_name\": \"Hilton\",\n        \"last_name\": \"Schimmel\",\n        \"birth_date\": \"1998, 7, 7\",\n        \"marks\": [8, 7.6, 7.8, 5.5, 9],\n    },\n    {\n        \"first_name\": \"Aditya\",\n        \"last_name\": \"Rowe\",\n        \"birth_date\": \"1999, 5, 2\",\n        \"marks\": [7.6, 8.9, 9.3, 10, 7.8],\n    },\n    {\n        \"first_name\": \"Estella\",\n        \"last_name\": \"King\",\n        \"birth_date\": \"1997, 6, 29\",\n        \"marks\": [9.6, 8.9, 9.3, 10, 7.8],\n    },\n]\n\n\n# Average\n\n\ndef average(grades: list):\n    return round(sum(grades) / len(grades), 2)\n\n\nprint(\n    list(\n        map(\n            lambda student: {\n                \"name\": student[\"first_name\"],\n                \"average\": average(student[\"marks\"]),\n            },\n            students_data,\n        )\n    )\n)\n\n\n# Best students\n\nprint(\n    list(\n        map(\n            lambda student: student[\"first_name\"],\n            filter(\n                lambda student: average(student[\"marks\"]) >= 9, students_data\n            ),\n        )\n    )\n)\n\n\n# Birth Day\n\nfrom datetime import datetime\n\nprint(\n    sorted(\n        students_data,\n        reverse=True,\n        key=lambda student: datetime.strptime(\n            student[\"birth_date\"], \"%Y, %m, %d\"\n        ),\n    )\n)\n\n\n# Highest score\n\nprint(max(map(lambda student: max(student[\"marks\"]), students_data)))\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/oriaj3.py",
    "content": "\"\"\"\n22 - FUNCIONES DE ORDEN SUPERIOR\nAutor de la solución: Oriaj3\n\nTeoría:\nLas funciones de orden superior son funciones que toman una o más funciones como argumentos\ny/o devuelven una función como resultado. En Python, las funciones de orden superior se\npueden utilizar para crear funciones más flexibles y reutilizables.\n\nLas funciones de orden superior se utilizan para abstraer la lógica de un programa y\nhacer que sea más fácil de entender y mantener. También se utilizan para crear funciones\nmás genéricas y reutilizables.\n\nLas funciones de orden superior se utilizan en muchos lenguajes de programación, como\nJavaScript, Java, C++ y Python. En Python, las funciones de orden superior se pueden\nimplementar utilizando funciones o clases.\n\nUn ejemplo de función de orden superior es la función map(), que toma una función y una\nsecuencia como argumentos y aplica la función a cada elemento de la secuencia.\n\nEjemplo de función de orden superior:\ndef cuadrado(x):\n    return x * x\n\nnumeros = [1, 2, 3, 4, 5]\ncuadrados = map(cuadrado, numeros)\nprint(list(cuadrados))\n\n\"\"\"\n\n\"\"\"\n```\n/*\n * EJERCICIO:\n * Explora el concepto de funciones de orden superior en tu lenguaje \n * creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n\"\"\"\n# Ejemplo de función de orden superior:\ndef sumar(x, y):\n    return x + y\n\ndef restar(x, y):\n    return x - y\n\ndef operar(x, y, operacion):\n    return operacion(x, y)\n\nresultado = operar(5, 3, sumar)\nprint(resultado)\n\nresultado = operar(5, 3, restar)\nprint(resultado)\n\n# Ejemplo con map():\ndef cuadrado(x):\n    return x * x\n\nnumeros = [1, 2, 3, 4, 5]\n\ncuadrados = map(cuadrado, numeros)\nprint(list(cuadrados))\n\n# Ejemplo con filter():\ndef es_par(x):\n    return x % 2 == 0\n\nnumeros = [1, 2, 3, 4, 5]\npares = filter(es_par, numeros)\nprint(list(pares))\n\n# Ejemplo con lambda:\nnumeros = [1, 2, 3, 4, 5]\ncuadrados = map(lambda x: x + x, numeros)\nprint(list(cuadrados))\n\n# Retorna una función:\n\ndef aplicar_multiplicador(n: int):\n    def multiplicar(x: int):\n        return x * n\n    return multiplicar\n\nmultiplicar = aplicar_multiplicador(2)\n\nprint(multiplicar(5))\nprint(aplicar_multiplicador(3)(2))\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n * lista de calificaciones), utiliza funciones de orden superior para \n * realizar las siguientes operaciones de procesamiento y análisis:\n * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n *   y promedio de sus calificaciones.\n * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n *   que tienen calificaciones con un 9 o más de promedio.\n * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n * - Mayor calificación: Obtiene la calificación más alta de entre todas las\n *   de los alumnos.\n * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n */\n```\n\"\"\"\nfrom datetime import datetime\nfrom math import e\n\n# Ejemplo con funciones de orden superior y listas de estudiantes:\nlista_estudiantes = [\n    {\"name\": \"Juan\", \"birthdate\": \"2000-01-01\", \"grades\": [8, 9, 7, 10]}, \n    {\"name\": \"Maria\", \"birthdate\": \"2001-02-03\", \"grades\": [9, 9, 9, 9]},\n    {\"name\": \"Pedro\", \"birthdate\": \"1999-03-04\", \"grades\": [7, 8, 6, 9]},\n    {\"name\": \"Ana\", \"birthdate\": \"2002-04-05\", \"grades\": [6, 7, 5, 8]},\n    {\"name\": \"Luis\", \"birthdate\": \"1998-05-06\", \"grades\": [5, 6, 4, 7]},\n    {\"name\": \"Elena\", \"birthdate\": \"2003-06-07\", \"grades\": [4, 5, 3, 6]}\n]\n\n# Promedio calificaciones:\ndef medias(estudiante):\n    notas = estudiante[\"grades\"]\n    return [estudiante[\"name\"], sum(notas)/len(notas)]\n\nmedias_estudiantes = list(map(medias, lista_estudiantes))\nprint(medias_estudiantes)\n\n#Mejores\nmejores_estudiantes = list(sorted(medias_estudiantes, key=lambda x: x[1], reverse=True))\nalfabeticos_estudiantes = list(sorted(medias_estudiantes, key=lambda x: x[0]))\n\nprint(mejores_estudiantes)\nprint(alfabeticos_estudiantes)\n\n#Edad\ndef convertir_a_datetime(estudiante):\n    fecha_str = estudiante[\"birthdate\"]\n    return datetime.strptime(fecha_str, \"%Y-%m-%d\")\n\nestudiantes_ordenados = sorted(lista_estudiantes, key=convertir_a_datetime, reverse=True)\n\nprint(estudiantes_ordenados)\n\n#Obtiene la nota mayor de todos los estudiantes\ndef nota_mayor(estudiante):\n    return [estudiante[\"name\"], max(estudiante[\"grades\"])]\n\nmejores_notas = list(map(nota_mayor, lista_estudiantes))\nmejor_nota = max(mejores_notas, key=lambda x: x[1])\n\nprint(mejor_nota)\n\n\n### Correción de la solución MoureDev\n\nlista_estudiantes = [\n    {\"name\": \"Juan\", \"birthdate\": \"2000-01-01\", \"grades\": [8, 9, 7, 10]}, \n    {\"name\": \"Maria\", \"birthdate\": \"2001-02-03\", \"grades\": [9, 9, 9, 9]},\n    {\"name\": \"Pedro\", \"birthdate\": \"1999-03-04\", \"grades\": [7, 8, 6, 9]},\n    {\"name\": \"Ana\", \"birthdate\": \"2002-04-05\", \"grades\": [6, 7, 5, 8]},\n    {\"name\": \"Luis\", \"birthdate\": \"1998-05-06\", \"grades\": [5, 6, 4, 7]},\n    {\"name\": \"Elena\", \"birthdate\": \"2003-06-07\", \"grades\": [4, 5, 3, 6]}\n]\n\ndef media(grades):\n    return sum(grades) / len(grades)\n\n# Promedio calificaciones\nprint(\n    list(\n        map(\n            lambda estudiante:\n                {\n                    \"name\": estudiante[\"name\"],\n                    \"grades\": media(estudiante[\"grades\"])\n                }, lista_estudiantes\n        )\n    )\n)\n\n#Mejores\"\nprint(\n    list(\n        map(\n            lambda estudiante:\n                    estudiante[\"name\"],\n                    filter(lambda estudiante:\n                            media(estudiante[\"grades\"])>=9, \n                        lista_estudiantes)\n        )\n    )\n)\n\n#Fecha de nacimiento ordenada\nprint(\n    sorted( \n        lista_estudiantes, \n        key=lambda student: \n            datetime.strptime(\n            student[\"birthdate\"], \"%Y-%m-%d\"), \n        reverse=True\n        )\n)"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/pyramsd.py",
    "content": "from datetime import datetime\nfrom functools import reduce\n'''\nLas funciones de orden superior son funciones que cumplen con al menos\nuna de las siguientes características:\n\n1. Reciben una o más funciones como argumentos.\n2. Devuelven una función como resultado.\n'''\n\n# ejemplo 1\ndef aplicar_func_sumar(funcion, valor1, valor2):\n    return funcion(valor1, valor2)\ndef sumar(x, y):\n    return x + y\nresultado = aplicar_func_sumar(sumar, 5, 8)\nprint(resultado)\n\n\n# ejemplo 2\ndef al_cuadrado():\n    def multiplicador(z):\n        return z * z\n    return multiplicador\nd = al_cuadrado()\nprint(d(4))\n\n\n# ejemplo 3\nnums = [1,2,3,4,5]\nresultados = list(map(lambda x: x ** 3, nums))\nprint(list(resultados))\n\n\n# ejemplo 4\ndiccionarios = [{'nombre': 'Ana', 'edad': 25}, {'nombre': 'Juan', 'edad': 22}, {'nombre': 'Luis', 'edad': 30}]\ndiccionarios.sort(key=lambda x: x['edad'])\nprint(diccionarios)  \n\n\n'''\nEXTRA\n'''\nEstudiantes = [\n    {\"nombre\": \"Sergio\", \"nacimiento\":\"12-07-2005\", \"calificaciones\": [8.0, 10.0, 5.0, 7.0]},\n    {\"nombre\": \"Javier\", \"nacimiento\":\"10-05-2003\", \"calificaciones\": [5.0, 10.0, 4.0, 6.0]},\n    {\"nombre\": \"Maria\", \"nacimiento\":\"07-05-2000\", \"calificaciones\": [10.0, 10.0, 8.0, 9.0]},\n    {\"nombre\": \"Julia\", \"nacimiento\":\"20-01-2002\", \"calificaciones\": [5.0, 4.0, 2.0, 10.0]},\n    {\"nombre\": \"Julian\", \"nacimiento\": \"01-01-2001\", \"calificaciones\": [10.0, 8.0, 10.0, 10.0]}\n]\n\ndef promedio(calificaciones):\n    return sum(calificaciones) / len(calificaciones)\n\npromedios = list(map(\n    lambda estudiante: [estudiante['nombre'], promedio(estudiante['calificaciones'])], Estudiantes\n))\n\nfor estudiante in promedios:\n    print(f\"{estudiante[0]}: {estudiante[1]}\")\n\n\ntops = list(filter(lambda estudiante: promedio(estudiante['calificaciones']) >= 9.0, Estudiantes))\ntop_names = list(map(lambda estudiante: estudiante['nombre'], tops))\nprint(top_names)\n\n\ndef dates(date_str):\n    return datetime.strptime(date_str, \"%d-%m-%Y\")\n\nsorted_students_by_age = sorted(Estudiantes, key=lambda estudiante: dates(estudiante[\"nacimiento\"]), reverse=True)\n\nfor student in sorted_students_by_age:\n    print(f\"{student['nombre']} - {student['nacimiento']}\")\n\nmayor_calificacion = max(Estudiantes, key=lambda estudiante: promedio(estudiante['calificaciones']))\nprint(f\"{mayor_calificacion['nombre']} - {sum(mayor_calificacion['calificaciones']) / len(mayor_calificacion['calificaciones'])}\")\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/qwik-zgheib.py",
    "content": "# -- exercise\ndef sum(a: int, b: int) -> int:\n    return a + b\n\n\ndef subtract(a: int, b: int) -> int:\n    return a - b\n\n\ndef multiply(a: int, b: int) -> int:\n    return a * b\n\n\ndef fn_sum(fn: callable, a: int, b: int) -> int:\n    return fn(a, b)\n\n\nprint(fn_sum(sum, 1, 2))\nprint(fn_sum(subtract, 1, 2))\nprint(fn_sum(multiply, 1, 2))\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/rantamhack.py",
    "content": "import math \nfrom datetime import datetime\nfrom functools import reduce\n\n\nprint(\"\\n\\n=======================================EJERCICIO=======================================\\n\\n\")\n\n'''\n* EJERCICIO:\n * Explora el concepto de funciones de orden superior en tu lenguaje \n * creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n'''\n\ndef arithmetic(function, num):\n    return function(num)\n    \ndef cube_root(num):\n    print(f\"La raiz cubica de 125 es: {math.cbrt(num)}\")\n\ndef elevate_cube(num):\n    print(f\"{num} elevado al cubo es: {num**3}\")\n    \n\narithmetic(cube_root, 125)\narithmetic(elevate_cube, 5)\n    \n\nprint(\"\\n\\n=======================================DIFICULTAD EXTRA=======================================\\n\\n\")\n\n'''\n* DIFICULTAD EXTRA (opcional):\n * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n * lista de calificaciones), utiliza funciones de orden superior para \n * realizar las siguientes operaciones de procesamiento y análisis:\n * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n *   y promedio de   sus calificaciones.\n * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n *   que tienen calificaciones con un 9 o mas de promedio.\n * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el mas joven.\n * - Mayor calificación: Obtiene la calificación mas alta de entre todas las\n *   de los alumnos.\n * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n'''\n\n\n# Lista de estudiantes\nstudents = [\n    {\"name\":\"Rantam\", \"born_date\":\"29-05-2000\", \"grades\":[7.2, 9.0, 8.6]},\n    {\"name\":\"Helena\", \"born_date\":\"12-02-2005\", \"grades\":[9.8, 9.2, 8.7]},\n    {\"name\":\"Silvia\", \"born_date\":\"10-07-2003\", \"grades\":[8.5, 8.0, 8.4]}, \n    {\"name\":\"Jose Luis\", \"born_date\":\"22-10-2003\", \"grades\":[7.0, 6.5, 7.4]},\n    {\"name\":\"Fernando\", \"born_date\":\"17-07-1998\", \"grades\":[5.0, 3.8, 4.6]},\n    {\"name\":\"Brais\", \"born_date\":\"11-06-2003\", \"grades\":[8.0, 9.4, 9.7]}\n]\n\n# Función para calcular la media\ndef calculate_average(grades):\n    return round(sum(grades) / len(grades), 2)\n\n# Función para calcular la nota media de los estudiantes\ndef get_average_grades(students, average_func):\n    return list(map(lambda student: {\"name\": student[\"name\"], \"average_grade\": average_func(student[\"grades\"])}, students))\n\n# Función para obtener los mejores estudiantes\ndef get_top_students(students, average_func, threshold=9.0):\n    return list(filter(lambda student: average_func(student[\"grades\"]) >= threshold, students))\n\n# Función para obtener una lista de estudiantes ordenada desde el mas joven\ndef sort_students_by_age(students):\n    return sorted(students, key=lambda student: datetime.strptime(student[\"born_date\"], \"%d-%m-%Y\"), reverse=True)\n\n# Función para obtener la calificación mas alta\ndef get_highest_grade(students):\n    all_grades = reduce(lambda acc, student: acc + student[\"grades\"], students, [])\n    return max(all_grades)\n\n\naverage_grades = get_average_grades(students, calculate_average)\ntop_students = get_top_students(students, calculate_average)\nstudents_sorted_by_age = sort_students_by_age(students)\nhighest_grade = get_highest_grade(students)\n\n\nprint(\"Promedio calificaciones:\")\nfor student in average_grades:\n    print(student)\n\nprint(\"\\nMejores estudiantes:\")\nfor student in top_students:\n    print(student[\"name\"], calculate_average(student[\"grades\"]))\n\nprint(\"\\nEstudiantes ordenados desde el mas joven:\")\nfor student in students_sorted_by_age:\n    print(student[\"name\"], student[\"born_date\"])\n\nprint(\"\\nMayor calificación:\", highest_grade)\n\n\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/raulG91.py",
    "content": "\nfrom datetime import datetime\nfrom functools import reduce\n\n#Funciones de orden superior\nlist1 = [20,8,3,2,13,17,25]\n\n#Python function that receive a function as argument\nnew_list = filter(lambda x: x%2 == 0,list1)\n\nfor element in new_list:\n    print(element)\n\n#FUnction that returns a function\ndef multiply_operation(value1,value2):\n    return value1 * value2\n\ndef operation(value1,value2,function):\n    return multiply_operation(value1,value2)\n\nprint(\"Result: \",operation(2,3,multiply_operation))\n\n#Extra \n\nstudent_list = [\n    {\n        \"name\": \"Raul\",\n        \"birth_date\": \"11/09/1991\",\n        \"qualifications\": [10,9,10,9]\n    },\n    {\n        \"name\":\"Maria\",\n        \"birth_date\": \"19/04/1992\",\n        \"qualifications\": [9,7,8,5.5]\n    },\n    {\n        \"name\":\"Juan\",\n        \"birth_date\": \"20/10/2000\",\n        \"qualifications\": [5,6,3,9.5]\n    }\n]\n\n#Averrage of qualifications\ndef averrage(iterable:list):\n    return sum(iterable) / len(iterable)\n\n#List with student name and averrage qualifications\nlist_averrage = list(map(lambda student: [student[\"name\"],averrage(student[\"qualifications\"])],student_list))\n\nprint(list_averrage)\n\n#List with student with averrage qualifications bigger than 9\nbest_students = filter(lambda value: value[1]>=9,list_averrage)\nprint(list(best_students))\n\n#Order lsit by birth date\nbirth_date_list=sorted(student_list,key=lambda student:datetime.strptime(student[\"birth_date\"],\"%d/%m/%Y\"),reverse=True)\nprint(birth_date_list)\n\n#Bigger qualification\nall_qualifications = reduce(lambda x,y: x+y[\"qualifications\"],student_list,[])\nprint(max(all_qualifications))"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/raynerpv2022.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * Explora el concepto de funciones de orden superior en tu lenguaje \n#  * creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n#  * lista de calificaciones), utiliza funciones de orden superior para \n#  * realizar las siguientes operaciones de procesamiento y análisis:\n#  * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n#  *   y promedio de sus calificaciones.\n#  * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n#  *   que tienen calificaciones con un 9 o más de promedio.\n#  * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n#  * - Mayor calificación: Obtiene la calificación más alta de entre todas las\n#  *   de los alumnos.\n#  * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n#  */\n\n# Pasar una función como argumento a otra función.\n\ndef Get_something(f,x):\n    return f(x)\nd = {\"a\":1,\"b\":2,3:\"c\"}\nk = Get_something(dict.keys,d )\nprint(f\"las Keys son {list(k)}\")\n\n# Retornar funcion\n\ndef Get_etwas():\n    def Get_value(dddd: dict):\n        return dddd.values()\n    return Get_value\n\nvalues = Get_etwas()\nprint(f\"los Valores son {list(values(d))}\")\n\n# oporque Get_etwas retorna una funcion\nprint(Get_etwas()(d))\n\n# funciones del sistema\n# map\na= [9,\"8\",7,True,5,[1,2,3],{11,2,3},(2,4,5),d,0.1]\ntype_all = list(map(type,a))\nprint(type_all)\n\n# filter\ndef only_int(v):\n    return isinstance(v,(int)) and not isinstance(v,(bool))\n\nonly_digi = list(filter(only_int,a))\nprint(only_digi)\n\n# reduce\na = [1,2,3,4,5,6]\nfrom functools import reduce\n\n\ndef sum_all(n,m):\n       \n         return n+m \n# n es el valor acumulativo y el que retorna al final\n       \nsuma = reduce(sum_all,a)\nprint(suma)\n\n\n# sorted\n \nordenado = sorted(a, key=lambda x: -x)\nprint(ordenado)\n\n# EXTRA\nimport datetime,random,string\n\ndef random_name(size = 8):\n     letter = string.ascii_letters\n     return ''.join( random.choice(letter)  for _ in range(size))\n\nclass Student:\n     name: str\n     date_born: datetime.datetime\n     notes: dict\n     average: float\n     best_note: dict\n\n     def __init__(self,name,date,notes, ave = 0, ) -> None:\n          self.name = name\n          self.date_born = date\n          self.notes = notes\n          self.average = ave\n          self.best_note ={}\n           \n\n     def set_best_note(self):\n        \n        best_notes =  (sorted(self.notes.items(), key= lambda x: x[1]))\n        # best_notes.reverse()\n        # print(\"set beste note\", type(best_notes[0]),best_notes[0][0], best_notes[0][1])\n        self.best_note[best_notes[0][0]]  =   best_notes[0][1]\n         \n\n\n     def set_average(self):\n        notes_temp = []\n        for _,i in self.notes.items():\n             notes_temp.append(i)\n        suma_note = reduce(lambda x,y: x+y,notes_temp)\n        result = round(suma_note/len(notes_temp),2)\n        self.average = result\n    \n     def display(self):\n          print(f\" Nombre: {self.name}\\n Fecha Nac: {self.date_born}\\n Notas: {self.notes}\\n Promedio: {self.average}\\n\")\n\nstudent = []\n \nfor i in range(10):\n     \n     student.append(\n          Student(random_name(),\n          datetime.date(random.randint(1990,2020),random.randint(1,12),random.randint(1,30)),\n          {\"mate\":round(random.uniform(5.0,10.0),2), \"L\":round(random.uniform(5.0,10.0),2), \"G\":round(random.uniform(5.0,10.0),2), \"E\":round(random.uniform(5.0,10.0),2)}\n          ))\n\n  \n     \n     \n\nprint(\"Listado Original\")\nfor i in student:\n    i.set_average()\n    i.display()\n\nlist_average = sorted(student, key = lambda x: -x.average)\nprint(\"Listado ordenado por promedio\")\nfor i in list_average:\n    i.display()\n\nprint(\"Listado ordenado alumnos con promedio superior a 9\")\nbest_student = list(filter(lambda x: x.average >=9, student))\nif  len(best_student):\n     \n    for i in best_student:\n        i.display()\nelse:\n     print(\"no hay estudientes con nota mayores a 9\")\n\nprint(\"Listado ordenado por edad\")\nage = sorted(student,key=lambda x: x.date_born)\nage.reverse()\nfor i in age:\n     i.display()\n\n \n\nprint(\"Listado con mejor nota de cada alumno\")\n# for i in student:\n#      i.set_best_note()\n#      print(f\" Nomber: {i.name} mejor nota  { i.best_note}\")\n\nprint(list(map(lambda s:(s.set_best_note(),f\"Nomber: {s.name} mejor nota: { s.best_note}\")[1],student)))\n\n\n\n\n\n\n\n "
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/rigo93acosta.py",
    "content": "'''\n## 22 FUNCIONES DE ORDEN SUPERIOR\n/*\n * EJERCICIO:\n * Explora el concepto de funciones de orden superior en tu lenguaje \n * creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n *\n * DIFICULTAD EXTRA (opcional):\n * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n * lista de calificaciones), utiliza funciones de orden superior para \n * realizar las siguientes operaciones de procesamiento y análisis:\n * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n *   y promedio de sus calificaciones.\n * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n *   que tienen calificaciones con un 9 o más de promedio.\n * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n * - Mayor calificación: Obtiene la calificación más alta de entre todas las\n *   de los alumnos.\n * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n */\n'''\n\nfrom functools import reduce\nfrom datetime import datetime\n\n\"\"\"\nEjercicio\n\"\"\"\n\n# Funcion con argumento\ndef apply_func(func, x):\n    return func(x)\n\nprint(apply_func(len, \"Hola mundo\"))\n\n# Retorno de funcion\n\ndef apply_multiplier(n):\n    def multiplier(x):\n        return x * n\n    return multiplier\n\nx = apply_multiplier(2)\nprint(x(5))\n\n# Sistema\nnumbers = [3, 4, 1, 5, 2]\n\n# map()\ndef applay_double(n):\n    return n*2\n\nprint(list(map(applay_double, numbers)))\n\n# filter()\ndef is_even(n):\n    return n % 2 == 0\n\nprint(list(filter(is_even, numbers)))\n\n# sorted()\nprint(sorted(numbers))\nprint(sorted(numbers, reverse=True))\nprint(sorted(numbers, key=lambda x: -x))\n\n# reduce \n\ndef sum(x, y):\n    return x + y\n\nprint(reduce(sum, numbers))\n\n\"\"\"\nExtra\n\"\"\"\n\nstudents = [\n    {\"name\": \"Rigo\", \"birthdate\": \"25-05-1993\", \"grades\": [10, 9, 10, 7, 10]},\n    {\"name\": \"Mary\", \"birthdate\": \"24-08-1988\", \"grades\": [9, 9, 5, 7, 6]},\n    {\"name\": \"Robe\", \"birthdate\": \"06-05-1986\", \"grades\": [8, 8, 8, 7, 6]}\n]\n\ndef average(grades):\n    return sum(grades)/len(grades)\n\n# Promedio calificaciones\nprint(\n    list(map(lambda student: \n             {\"name\": student[\"name\"], \n              \"average\": average(student[\"grades\"])}, students))\n)\n\n# Mejores estudiantes\nprint(\n    list(\n        map(lambda student: \n             student[\"name\"], \n              filter(lambda student: average(student[\"grades\"]) >= 9, students))\n    )\n)\n\n# Nacimiento\nprint(\n    list(\n        sorted(students, key=lambda student: datetime.strptime(student[\"birthdate\"], \"%d-%m-%Y\"), reverse=True)\n    )\n)\n\n# Mayor calificacion\n\nprint(max(map(lambda student: max(student[\"grades\"]), students)))"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/python/santyjl.py",
    "content": "#22 - FUNCIONES DE ORDEN SUPERIOR\n\"\"\"\n/*\n * EJERCICIO:\n * Explora el concepto de funciones de orden superior en tu lenguaje\n * creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n *\n * DIFICULTAD EXTRA (opcional):\n * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y\n * lista de calificaciones), utiliza funciones de orden superior para\n * realizar las siguientes operaciones de procesamiento y análisis:\n * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n *   y promedio de sus calificaciones.\n * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n *   que tienen calificaciones con un 9 o más de promedio.\n * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n * - Mayor calificación: Obtiene la calificación más alta de entre todas las\n *   de los alumnos.\n * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n */\n\"\"\"\n\n#Ejemplo de funcion de orden superior\ndef multiplicacion_superior(funcion  , num1 : int , num2 : int):\n    return funcion(num1 , num2) * funcion(num2 , num1)\n\ndef multiplicar (num1 , num2):\n    return num1 * num2\n\nprint(multiplicacion_superior(multiplicar , 2 , 2))\n\n# extra\nestudiantes_data = [\n    #nombres\n    [\"Manuel Fernando\" ,\n     \"Fernando Vicente\" ,\n     \"Iker Diaz\",\n     \"Alberto Roja\" ,\n     \"Raúl Fuentes\",\n     \"Gonzalo Sanchez\"],\n    [\n     \"20/01/2010\",\n     \"05/05/2009\",\n     \"31/08/2009\",\n     \"31/12/2009\",\n     \"12/05/2010\",\n     \"23/11/2009\"\n    ],\n    [\n     [5 , 9 , 7 , 6 , 9 , 10],\n     [10 , 10 , 9 , 7 , 10 , 10],\n     [9 , 9 , 8 , 10 , 6 , 10],\n     [8 , 8 , 7 , 10 , 8 , 9],\n     [10 , 9 , 10 , 9 , 10, 9],\n     [8 , 10 , 4 , 2 ,10 , 7]\n    ]\n]\n\ndef Resultados (funcion1 , funcion2 , funcion3 , lista : list):\n    \"\"\"\n    funcion 1 es la de promedios\n    funcion 2 es la de mejores estudiantes\n    funcion 3 es la del mas joven\n    \"\"\"\n    return funcion1(lista) , funcion2(lista , funcion1) , funcion3(lista) ,\n\ndef promedios(lista) -> list:\n    \"\"\"\n    calcula los promedios de cada estudiante y lo muestra en pantalla\n    \"\"\"\n    def calcular_promedio(num , elementos):\n        \"\"\"\n        calcura el promedio\n        \"\"\"\n        return num / elementos\n\n    lista_promedios : list = []\n\n    print(\"\\n =========PROMEDIOS DE LOS ESTUDIANTES=========\")\n    for i in range(len(lista[0])):\n        \"\"\"\n        muestra el promedio de cada estudiante\n        \"\"\"\n        promedio = round(calcular_promedio(sum(lista[2][i]) ,len(lista[2][i])) , 2)\n        print(f\"{lista[0][i]} : {promedio}\")\n\n        lista_promedios.append(promedio)\n\n    return lista_promedios\n\ndef mejores_estudiante(lista , funcion) -> list:\n    \"\"\"\n    con los promedios de la funcion , se mira cual tiene una calificacion de 9 o mayor\n    \"\"\"\n    promedios = funcion(lista)\n    calificacion : list = []\n    calificancion_ordenada : list = []\n\n    for i in range(len(lista[0])):\n\n        if promedios[i] >= 9 :\n            nombre = lista[0][i]\n            promedio = promedios[i]\n            calificacion.append([nombre , promedio]) # se guardan los datos en una lista\n\n        else :\n            pass\n\n    while calificacion:\n        elemento_mayor = max(calificacion, key=lambda x: x[1])\n        calificancion_ordenada.append(elemento_mayor)\n        calificacion.remove(elemento_mayor)\n\n    print(\"\\n =========MEJORES ESTUDIANTES DE MAYOR A MENOR=========\")\n    for estudiante in calificancion_ordenada:\n        print(f\"{estudiante[0]} : {estudiante[1]}\")\n\ndef ordenar_por_edad(lista) -> list:\n    \"\"\"\n    Ordena los estudiantes por fecha de nacimiento del más joven al más viejo.\n    \"\"\"\n    from datetime import datetime\n\n    def convertir_fecha(fecha):\n        return datetime.strptime(fecha, \"%d/%m/%Y\")\n\n    nombres_y_fechas = [(lista[0][i], convertir_fecha(lista[1][i])) for i in range(len(lista[0]))]\n    nombres_y_fechas.sort(key=lambda x: x[1], reverse=True)\n\n    print(\"\\n =========DE MENOR A MAYOR=========\")\n    # Imprimir solo los nombres y las fechas formateadas\n    for nombre, fecha in nombres_y_fechas:\n        print(f\"{nombre}: {fecha.strftime('%d/%m/%Y')}\")\n\n\nResultados(promedios , mejores_estudiante , ordenar_por_edad , estudiantes_data)"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/ruby/Elmer125.rb",
    "content": "#  * EJERCICIO:\n#  * Explora el concepto de funciones de orden superior en tu lenguaje\n#  * creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n# Doc: https://medium.com/@jeffcoh23/eloquent-ruby-achieving-higher-order-functionality-933267a01f36\n#      https://www.rubyguides.com/2016/02/ruby-procs-and-lambdas/\n# Ruby hasn't Higher Order Functions, but it has blocks, procs and lambdas.\n\n# pass a lambda to a method\ndef add_stuff(a, b, my_lambda)\n  c = a + b\n  my_lambda.call(c)\nend\nexample_lambda = lambda { |c| puts \"The sum is #{c}\" }\nadd_stuff(1, 2, example_lambda)\n\ndef multiply_stuff(a, b, my_proc)\n  c = a * b\n  my_proc.call(c)\nend\nmultiply_stuff(2, 3, ->(c) { puts \"The product is #{c}\" })\n\ndef divide_stuff(a, b, &block)\n  c = a / b\n  block.call(c)\nend\n\ndivide_stuff(6, 3) { |c| puts \"The division is #{c}\" }\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y\n#  * lista de calificaciones), utiliza funciones de orden superior para\n#  * realizar las siguientes operaciones de procesamiento y análisis:\n#  * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n#  *   y promedio de sus calificaciones.\n#  * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n#  *   que tienen calificaciones con un 9 o más de promedio.\n#  * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n#  * - Mayor calificación: Obtiene la calificación más alta de entre todas las\n#  *   de los alumnos.\n#  * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n\n# students = [\n#   { name: 'Alice', birthdate: '1990-01-01', grades: [9, 8, 7, 10, 9] },\n#   { name: 'Bob', birthdate: '1991-01-01', grades: [8, 7, 6, 9, 8] },\n#   { name: 'Charlie', birthdate: '1992-01-01', grades: [7, 6, 5, 8, 7] },\n# ]\n\nstudents = [ :name => 'Alice', :birthdate => '1990-01-01', :grades => [9, 8, 9, 10, 9] ] +\n          [ :name => 'Bob', :birthdate => '1991-01-01', :grades => [8, 10, 6, 9, 5] ] +\n          [ :name => 'Charlie', :birthdate => '1992-01-01', :grades => [7, 6, 5, 8, 7] ]\n\ndef average_grades(grades)\n  grades.sum / grades.length\nend\n\nputs \"Average grades:\"\nputs students.map { |student| \"#{student[:name]}: #{average_grades(student[:grades])}\" }\n\nputs \"Best students:\"\nputs students.select { |student| average_grades(student[:grades]) >= 9 }.map { |student| student[:name] }\n\nputs \"Youngest students:\"\nputs students.sort_by { |student| student[:birthdate] }.map { |student| student[:name] }.reverse\n\nputs \"Highest grade:\"\nputs students.map { |student| student[:grades].max }.max"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/rust/kenysdev.rs",
    "content": "/*\n╔═══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado                ║\n║ GitHub: https://github.com/Kenysdev   ║\n║ 2024 -  Rust                          ║\n╚═══════════════════════════════════════╝\n-----------------------------------------\n* FUNCIONES DE ORDEN SUPERIOR\n-----------------------------------------\n\n* EJERCICIO #1:\n* Explora el concepto de funciones de orden superior en tu lenguaje \n* creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n*/\n\ntype ArithmeticOperation = fn(i32, i32) -> i32;\n\nfn arithmetic_op(operation: ArithmeticOperation) -> impl Fn(i32, i32) -> i32 {\n    move |x, y| operation(x, y)\n}\n\nfn add(x: i32, y: i32) -> i32 {\n    x + y\n}\n\nfn subtract(x: i32, y: i32) -> i32 {\n    x - y\n}\n\nfn multiply(x: i32, y: i32) -> i32 {\n    x * y\n}\n\n/*\n* EJERCICIO #2:\n* Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n* lista de calificaciones), utiliza funciones de orden superior para \n* realizar las siguientes operaciones de procesamiento y análisis:\n* - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n*   y promedio de sus calificaciones.\n* - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n*   que tienen calificaciones con un 9 o más de promedio.\n* - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n* - Mayor calificación: Obtiene la calificación más alta de entre todas las\n*   de los alumnos.\n* - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n*/\n\ntype Student = (String, String, Vec<f64>);\n\ntype PrintFunction<'a> = fn(&'a Student);\n\nfn higher_order_fun<'a>(msg: &'static str, print_fn: PrintFunction<'a>) -> impl Fn(&'a Vec<Student>) + 'a {\n    move |students: &'a Vec<Student>| {\n        println!(\"\\n----\\n{}\", msg);\n        for student in students {\n            print_fn(student);\n        }\n    }\n}\nfn print_grade_point_average(student: &Student) {\n    let (name, _, grades) = student;\n    let average_grade: f64 = grades.iter().sum::<f64>() / grades.len() as f64;\n    println!(\"{} {}\", name, average_grade);\n}\n\nfn print_top_students(student: &Student) {\n    let (name, _, grades) = student;\n    let average: f64 = grades.iter().sum::<f64>() / grades.len() as f64;\n    if average >= 9.0 {\n        println!(\"{}\", name);\n    }\n}\n\nfn print_birth_order(student: &Student) {\n    let (name, dob, _) = student;\n    println!(\"{} {}\", name, dob);\n}\n\nfn print_highest_grade(student: &Student) {\n    let (name, _, grades) = student;\n    let max_grade = grades.iter().fold(f64::MIN, |max, &grade| max.max(grade));\n    println!(\"{} {}\", name, max_grade);\n}\n\n\nfn main() {\n\n    println!(\"EJERCICIO #1\");\n\n    let add_func = arithmetic_op(add);\n    let subtract_func = arithmetic_op(subtract);\n    let multiply_func = arithmetic_op(multiply);\n\n    println!(\"{}\", add_func(3, 5));\n    println!(\"{}\", subtract_func(10, 3));\n    println!(\"{}\", multiply_func(2, 4));\n    \n\n    //_______________________________________________________________________________\n    println!(\"EJERCICIO #2\");\n\n    let students_list = vec![\n        (\"Ken\".to_string(), \"2012-04-21\".to_string(), vec![9.5, 9.4, 9.3, 9.2]),\n        (\"Ben\".to_string(), \"2012-03-20\".to_string(), vec![8.5, 8.4, 8.3, 8.2]),\n        (\"Ada\".to_string(), \"2012-02-19\".to_string(), vec![7.5, 7.4, 7.3, 7.2]),\n        (\"Zoe\".to_string(), \"2012-01-18\".to_string(), vec![9.0, 9.1, 9.0, 9.1]),\n    ];\n\n    let grade_point_average = higher_order_fun(\"Promedio calificaciones:\", print_grade_point_average);\n    let top_students = higher_order_fun(\"Mejores estudiantes:\", print_top_students);\n    let highest_grade = higher_order_fun(\"Mayor calificación:\", print_highest_grade);\n\n    grade_point_average(&students_list);\n    top_students(&students_list);\n\n    let sorted_students: Vec<(String, String, Vec<f64>)> = {\n        let mut sorted_students = students_list.clone();\n        sorted_students.sort_by(|a, b| a.1.cmp(&b.1));\n        sorted_students\n    };\n\n    let birth_order = higher_order_fun(\"Por nacimiento:\", print_birth_order);\n    birth_order(&sorted_students);\n\n    highest_grade(&students_list);\n \n}\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/sql/Nicojsuarez2.sql",
    "content": "# #22 FUNCIONES DE ORDEN SUPERIOR\n> #### Dificultad: Difícil | Publicación: 27/05/24 | Corrección: 03/06/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Explora el concepto de funciones de orden superior en tu lenguaje \n * creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n *\n * DIFICULTAD EXTRA (opcional):\n * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n * lista de calificaciones), utiliza funciones de orden superior para \n * realizar las siguientes operaciones de procesamiento y análisis:\n * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n *   y promedio de sus calificaciones.\n * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n *   que tienen calificaciones con un 9 o más de promedio.\n * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n * - Mayor calificación: Obtiene la calificación más alta de entre todas las\n *   de los alumnos.\n * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/swift/allbertoMD.swift",
    "content": "import Foundation\n\n\nlet stringArray: [String] = [\"Swift\", \"Kotlin\", \"Java\", \"Python\", \"Ruby\", \"JavaScript\", \"C#\", \"C++\", \"Go\", \"Rust\", \"256\", \"360\"]\nlet intArray: [Int] = [10, 23, 35, 42, 57, 61, 74, 86, 95, 100]\n\n\n\n\nprint(\"\\nFunciones de orden superior del lenguaje.\")\n// Funciones de orden superior del lenguaje.\n\n\nprint(\"\\nFunción map.\")\n// Multiplica por 10 cada elemento del array lo.\nlet mapIntArray = intArray.map { item in\n    item * 10\n}\nprint(mapIntArray)\n\n\nprint(\"\\nFunción compactMap.\")\n// Conviert todos los Strings del array a entero y si alguno es nil lo descarta.\nlet compactMapStringArray = stringArray.compactMap { item in\n    Int(item)\n}\nprint(compactMapStringArray)\n\n\nprint(\"\\nFunción filter.\")\n// Filtra los elementos del array por la palabra Swift.\nlet filterStringArray = stringArray.filter { item in\n    item == \"Swift\"\n}\nprint(filterStringArray)\n\n\nprint(\"\\nFunción reduce.\")\n// resta el resultado de cada elemento del array empezando en el con el 10 y devuelve el resultado. (10 - 10 = 0) - (0 - 23 = -23) etc\nlet reduceIntArray = intArray.reduce(10) { partialResult, item in\n    item - partialResult\n}\nprint(reduceIntArray)\n\n\nprint(\"\\nFunción forEach.\")\n// Imprime cada elemento del array\nstringArray.forEach { item in\n    print(item)\n}\n\n\nprint(\"\\nFunción sorted.\")\n// Ordena los elementos del array de menor a mayor.\nlet sortedStringArray = stringArray.sorted { first, second in\n    first < second\n}\nprint(sortedStringArray)\n\n\nprint(\"\\nFunción contains.\")\n// Devuelve verdadero o falso si la condicion se cumple.\nlet containsIntArray = intArray.contains { item in\n    item == 10\n}\nprint(containsIntArray)\n\n\nprint(\"\\nFunción satisfy.\")\n// Devuelve verdadero a falso si todos los elementos del array cumplen con la condicion.\nlet satisfyStringArray = stringArray.allSatisfy { item in\n    item.count == 4\n}\nprint(satisfyStringArray)\n\n\nprint(\"\\nFunción first.\")\n// Devuelve el elemento que compla con la condición.\nlet firstIntArray = intArray.first { item in\n    item % 3 == 0\n}\nif let number = firstIntArray {\n    print(number)\n}\n\n\nprint(\"\\nFunción drop.\")\n// Elimina el elemento primero del array si se cumple con la condición.\nlet dropStringArray = stringArray.drop { item in\n    item.first == \"S\"\n}\nprint(dropStringArray)\n\n\nprint(\"\\nFunción prifix\")\n// Devuelve el primer elemento del array si cumple con la condición.\nlet prefixStringArray = stringArray.prefix { item in\n    item.first == \"S\"\n}\nprint(prefixStringArray)\n\n\n\n\nprint(\"\\nFunciones de orden superior personalizadas.\")\n// Funciones de orden superior personalizadas.\n\n\nprint(\"\\nFunción con función como parametro.\")\n// Función con función de parametro.\nfunc applyFunctionToArray(array: [Int], function: (Int) -> Int) -> [Int] {\n    var result: [Int] = []\n    for value in array {\n        result.append(function(value))\n    }\n    return result\n}\n\n// Definición de la variable que se pasara como parametro a la función applyFunctionToArray.\nfunc square(number: Int) -> Int {\n    return number * number\n}\n\n// Uso de la función de orden superior.\nlet squaredNumbers = applyFunctionToArray(array: intArray, function: square)\nprint(squaredNumbers)\n\n\nprint(\"\\nFunción que devuelve una función.\")\n// Función que devuelve una función.\nfunc makeMultiplier(factor: Int) -> (Int) -> Int {\n    return { number in\n        return number * factor\n    }\n}\n\n// Uso de la función de orden superior.\nlet multiplyByThree = makeMultiplier(factor: 3)\nprint(multiplyByThree(5)) // 15\n\n\n\n\n// DIFICULTAD EXTRA.\nprint(\"\\n\\nDIFICULTAD EXTRA.\")\n\n\nstruct Student {\n    let name: String\n    let birthDate: Date\n    let califications: [String : Float]\n    \n    static func createBirthDate(date: String) -> Date {\n        let dateFormater = DateFormatter()\n        dateFormater.dateFormat = \"dd/MM/yyyy\"\n        let birthDate = dateFormater.date(from: date)\n        guard let bd = birthDate else {\n            fatalError()\n        }\n        return bd\n    }\n}\n\nvar studentsList = [Student(name: \"Sara\",\n                            birthDate: Student.createBirthDate(date: \"06/07/2001\"),\n                            califications: [\"Algorithms\" : 7.1,\n                                            \"Operating System\" : 5.9,\n                                            \"Data Base\" : 9.0,\n                                            \"AI\" : 2.5]),\n                    Student(name: \"Helena\",\n                            birthDate: Student.createBirthDate(date: \"27/10/2002\"),\n                            califications: [\"Algorithms\" : 3.9,\n                                            \"Operating System\" : 9.0,\n                                            \"Data Base\" : 7.3,\n                                            \"AI\" : 8.1]),\n                    Student(name: \"Kendrick\",\n                            birthDate: Student.createBirthDate(date: \"11/03/2001\"),\n                            califications: [\"Algorithms\" : 5.0,\n                                            \"Operating System\" : 7.9,\n                                            \"Data Base\" : 5.9,\n                                            \"AI\" : 6.3]),\n                    Student(name: \"Tyler\",\n                            birthDate: Student.createBirthDate(date: \"07/11/2002\"),\n                            califications: [\"Algorithms\" : 9.1,\n                                            \"Operating System\" : 7.5,\n                                            \"Data Base\" : 8.6,\n                                            \"AI\" : 10.0])\n]\n\n\n\n\nprint(\"\\nPromedio de cada estudiante.\")\n// Función promedio de cada estudiante.\nfunc namesAndAverages(to students: [Student], function: ([String]) -> [String]) -> [String] {\n    var califications: [Float] = []\n    var notes: [[Float]] = []\n    for cal in students {\n        for (_, value) in cal.califications {\n            califications.append(value)\n        }\n        notes.append(califications)\n    }\n    var sumNotes: [Float] = []\n    for n in notes {\n        let sum: Float\n        sum = n.reduce(0, { partialResult, float in\n            partialResult + float\n        })\n        sumNotes.append(sum)\n    }\n    var averages: [Float] = []\n    var division: Float = 0.0\n    for n in sumNotes {\n        division = round(n / Float(sumNotes.count))\n        averages.append(Float(division))\n    }\n    var namesAndAverages: [String] = []\n    for item in studentsList {\n        namesAndAverages.append(item.name)\n    }\n    var sttepper = 0\n    for item in averages {\n        namesAndAverages[sttepper] += \": \\(String(item))\"\n        sttepper += 1\n    }\n    let result = function(namesAndAverages)\n    return result\n}\n\nfunc createNamesAndAverages(array: [String]) -> [String] {\n    array\n}\n\nlet namesAndAveragesArray = namesAndAverages(to: studentsList, function: createNamesAndAverages)\nprint(namesAndAveragesArray)\n\n\n\nprint(\"\\nAlumnos con promedios mayor a 9.0\")\n// Función alumnos con promedios superior a 9.0\nfunc averagePluss(to students: [Student], function: ([String]) -> [String]) -> [String] {\n    var averagesPlus: [String] = []\n    for student in students {\n        for (_, value) in student.califications {\n            if value >= 9.0 {\n                averagesPlus.append(student.name)\n                break\n            }\n        }\n    }\n    let result = function(averagesPlus)\n    return result\n}\n\nfunc createAveragePlusArray(array: [String]) -> [String] {\n    array\n}\n\nlet averagePlussArray = averagePluss(to: studentsList, function: createAveragePlusArray)\nprint(averagePlussArray)\n\n\n\n\nprint(\"\\nOrden de fechas de nacimiento.\")\n// Función de orden de fechas de nacimiento.\nfunc datesOrder(to students: [Student], order: ([String]) -> [String]) -> [String] {\n    let dates = students.sorted { first, second in\n        first.birthDate > second.birthDate\n    }\n    let names = dates.map { name in\n        name.name\n    }\n    let result = order(names)\n    return result\n}\n\nfunc orderDates(names: [String]) -> [String] {\n    names\n}\n\nlet datesSorted = datesOrder(to: studentsList, order: orderDates)\nprint(datesSorted)\n\n\n\nprint(\"\\nAlumno con el promedio mas alto.\")\n// Función con la nota mas alta.\nfunc greaterAverage(to students: [Student], function: ([String]) -> [String]) -> [String] {\n    var greaterAverage: [String] = []\n    for student in students {\n        for (_, value) in student.califications {\n            if value == 10.0 {\n                greaterAverage.append(student.name)\n                break\n            }\n        }\n    }\n    let result = function(greaterAverage)\n    return result\n}\n\nfunc createGreaterAverageArray(array: [String]) -> [String] {\n    array\n}\n\nlet greaterAverageArray = greaterAverage(to: studentsList, function: createGreaterAverageArray)\nprint(greaterAverageArray)\n\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/swift/blackriper.swift",
    "content": "import Foundation\n\n/*\n una funcion de orden superior (higher-order function) es una funcion que recibe como argumento una funcion\n o rettorna una funcion.\n\nse usan principalmente para  trabajar con colecciones de datos. estas no permiten que \nalguna coleccion sea modificada por una funcion de orden superior.\n\n */\n\nlet fruits = [\"apple\", \"banana\", \"orange\"]\n\n//usando funcion filter \nif let fruit=fruits.first(where:{$0 == \"apple\"}){\n    print(fruit)\n}\n\n// fomrma iperativa\nfunc findFruit(_ fruits: [String], _ fruit: (String) -> Bool) -> String? {\n    for f in fruits {\n        if fruit(f) {\n            return f\n        }\n    }\n    return nil\n}\n\nif let fruit=findFruit(fruits, {$0 == \"orange\"}){\n    print(fruit)\n}\n\n// ejercicio extra \n\nstruct Student {\n    let name: String\n    let birthday: Date\n    let scores : [Int]\n}\n\nlet formatter = DateFormatter()\nformatter.dateFormat = \"dd/MM/yyyy\"\n\nlet students: [Student] = [\n    Student(name: \"Marco\", birthday: formatter.date(from:\"10/10/1990\")!, scores: [0,9,7,5,10,6]),\n    Student(name: \"Messi\", birthday: formatter.date(from:\"20/05/1994\")!, scores: [1,8,8,8,9,10]),\n    Student(name: \"Cristiano\", birthday: formatter.date(from:\"20/05/1998\")!, scores: [9,10,9,8,9,10]),\n    Student(name: \"Neymar\", birthday: formatter.date(from:\"20/05/2000\")!, scores: [1,8,8,7,9,5]),\n]\n\n\nfunc average(_ scores: [Int]) -> Int {\n    return scores.reduce(0, +) / scores.count\n}\n\n\n\nlet averageStudents =  students.map{ [$0.name: average($0.scores)]}\nprint(averageStudents)\n\nlet majorStudents = averageStudents.filter{$0.values.allSatisfy{$0 >= 9}}\nprint(\"major students: \\(majorStudents)\")\n\nlet orderStudents = students.sorted(by: { $0.birthday > $1.birthday })\nprint(orderStudents)\n\nlet majorScores = students.map{[$0.name: $0.scores.max()!]}\nprint(majorScores)\n\n\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/swift/pedroomar23.swift",
    "content": "import Foundation \n\n/*\n * EJERCICIO:\n * Explora el concepto de funciones de orden superior en tu lenguaje \n * creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n *\n * DIFICULTAD EXTRA (opcional):\n * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n * lista de calificaciones), utiliza funciones de orden superior para \n * realizar las siguientes operaciones de procesamiento y análisis:\n * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n *   y promedio de sus calificaciones.\n * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n *   que tienen calificaciones con un 9 o más de promedio.\n * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n * - Mayor calificación: Obtiene la calificación más alta de entre todas las\n *   de los alumnos.\n * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n */\n\n// Ejemplos simples de funciones de orden superior\n\n// 1. Map: Transforma cada elemento de una colección\nlet numbers = [1, 2, 3, 4, 5]\nlet squaredNumbers = numbers.map { $0 * $0 }\nprint(\"Números al cuadrado: \\(squaredNumbers)\")\n\n// 2. Filter: Filtra elementos de una colección basado en una condición\nlet evenNumbers = numbers.filter { $0 % 2 == 0 }\nprint(\"Números pares: \\(evenNumbers)\")\n\n// 3. Reduce: Combina todos los elementos de una colección en un único valor\nlet sum = numbers.reduce(0, +)\nprint(\"Suma de números: \\(sum)\")\n\n// 4. Función que recibe otra función como parámetro\nfunc applyOperation(_ a: Int, _ b: Int, operation: (Int, Int) -> Int) -> Int {\n    return operation(a, b)\n}\n\nlet result = applyOperation(5, 3, operation: *)\nprint(\"Resultado de la operación: \\(result)\")\n\n// Dificultad Extra\nstruct Student {\n    let name: String\n    let birthDate: Date\n    let grades: [Double]\n}\n\nlet dateFormatter = DateFormatter()\ndateFormatter.dateFormat = \"yyyy-MM-dd\"\n\nlet students = [\n    Student(name: \"Ana\", birthDate: dateFormatter.date(from: \"2000-05-15\")!, grades: [8.5, 9.0, 7.5, 10.0]),\n    Student(name: \"Carlos\", birthDate: dateFormatter.date(from: \"1999-11-22\")!, grades: [7.0, 8.5, 9.5, 8.0]),\n    Student(name: \"Elena\", birthDate: dateFormatter.date(from: \"2001-03-10\")!, grades: [9.5, 9.0, 9.5, 10.0]),\n    Student(name: \"David\", birthDate: dateFormatter.date(from: \"2000-09-05\")!, grades: [6.5, 7.0, 8.0, 7.5])\n]\n\n// 1. Promedio de calificaciones\nlet averageGrades = students.map { student in\n    (name: student.name, average: student.grades.reduce(0, +) / Double(student.grades.count))\n}\nprint(\"Promedio de calificaciones:\")\naverageGrades.forEach { print(\"\\($0.name): \\(String(format: \"%.2f\", $0.average))\") }\n\n// 2. Mejores estudiantes\nlet bestStudents = students.filter { student in\n    student.grades.reduce(0, +) / Double(student.grades.count) >= 9.0\n}.map { $0.name }\nprint(\"\\nMejores estudiantes: \\(bestStudents)\")\n\n// 3. Ordenar por nacimiento (más joven primero)\nlet sortedByAge = students.sorted { $0.birthDate > $1.birthDate }\nprint(\"\\nEstudiantes ordenados por edad (más joven primero):\")\nsortedByAge.forEach { print(\"\\($0.name): \\(dateFormatter.string(from: $0.birthDate))\") }\n\n// 4. Mayor calificación\nlet highestGrade = students.flatMap { $0.grades }.max() ?? 0.0\nprint(\"\\nCalificación más alta: \\(highestGrade)\")"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/typescript/AChapeton.ts",
    "content": "const radios: Array<number> = [1, 2, 3]\n\nconst calcularArea = (radio: number) => {\n  return Math.PI * (radio ** 2)\n}\n\nconst calcularDiametro = (radio: number) => {\n  return 2 * radio\n}\n\nconst calcular = (radios: Array<number>, funcion) => {\n  const resultados: Array<number> = []\n  for (let i: number = 0; i < radios.length; i++){\n    resultados.push(funcion(radios[i]))\n  }\n  return resultados\n}\n\nconsole.log('Areas: ', calcular(radios, calcularArea))\nconsole.log('Diametros: ', calcular(radios, calcularDiametro))"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/typescript/Sac-Corts.ts",
    "content": "// Function that accepts another function as an argument \nfunction processArray<T>(func: (item: T) => T, arr: T[]): T[] {\n    return arr.map(func);\n}\n\nfunction square(x: number): number {\n    return x * x;\n}\n\nconst numbers: number[] = [1, 2, 3, 4];\nconst squares: number[] = processArray(square, numbers);\nconsole.log(squares);\n\n// Function that returns another function\nfunction createSum(x: number): (y: number) => number {\n    return function(y: number): number {\n        return x + y;\n    };\n}\n\nconst sum5 = createSum(5);\nconsole.log(sum5(20));\n\n// Using filter, map and reduce\nconst numbers10: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\nconst evenNumbers: number[] = numbers10.filter(num => num % 2 === 0);\nconst evenSquares: number[] = evenNumbers.map(num => num * num); \nconst sumEvenSquares: number = evenSquares.reduce((total, num) => total + num, 0);\n\nconsole.log(evenNumbers);\nconsole.log(evenSquares);\nconsole.log(sumEvenSquares);\n\n// ** Extra Exercise ** //\ninterface Student {\n    name: string;\n    birthdate: Date;\n    qualifications: number[];\n}\n\nconst students: Student[] =  [{\n    name: 'Isaac',\n    birthdate: new Date(2001, 9, 21),\n    qualifications: [9.0, 10, 9.5, 9.8] \n},\n{\n    name: 'Juan',\n    birthdate: new Date(2001, 6, 22),\n    qualifications: [9, 8, 8.5, 9.5]\n},\n{\n    name: 'Luis',\n    birthdate: new Date(2003, 10, 5),\n    qualifications: [6, 7, 7.5, 8]\n},\n{\n    name: 'María',\n    birthdate: new Date(2000, 4, 20),\n    qualifications: [10, 9.5, 10, 10]\n}]; \n\nconst studentAverage = students.map(student => {\n    const average = student.qualifications.reduce((sum, score) => sum + score, 0) / student.qualifications.length;\n    return { name: student.name, average: parseFloat(average.toFixed(2)) };\n});\nconsole.log(studentAverage);\n\nconst bestStudents = studentAverage.filter(student => student.average >= 9);\nconsole.log(bestStudents);\n\nconst datesOfBirthInOrder = students.sort((a, b) => b.birthdate.getTime() - a.birthdate.getTime());\ndatesOfBirthInOrder.forEach(student => {\n    const date = student.birthdate;\n    console.log(`\\n${student.name}: ${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`);\n});\n\nconst allQualifications = students.flatMap(student => student.qualifications);\nconst highestScore = Math.max(...allQualifications);\n\nconsole.log(`\\nThe highest score is ${highestScore}`);\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/typescript/duendeintemporal.ts",
    "content": "//#22 { retosparaprogramadores } - FUNCIONES DE ORDER SUPERIOR \n/* \n * EJERCICIO:\n * Explora el concepto de funciones de orden superior en tu lenguaje \n * creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n *\n * DIFICULTAD EXTRA (opcional):\n * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n * lista de calificaciones), utiliza funciones de orden superior para\n * realizar las siguientes operaciones de procesamiento y análisis:\n * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n *   y promedio de sus calificaciones.\n * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n *   que tienen calificaciones con un 9 o más de promedio.\n * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n * - Mayor calificación: Obtiene la calificación más alta de entre todas las\n *   de los alumnos.\n * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales). \n * */\n\n//Reference Bibliografy:\n//Eloquent Javascript A Modern Introduction to Programming by Marijn Haverbeke (z-lib.org)\n//GPT & Deepseek\n\nlet log = console.log;\n\n// Conditional check for browser environment\nif (typeof window !== 'undefined') {\n    window.addEventListener('load', () => {\n        const body: HTMLBodyElement | null = document.querySelector('body');\n        const title = document.createElement('h1');\n\n        body?.style.setProperty('background', '#000');\n        body?.style.setProperty('text-align', 'center');\n\n        title.textContent = 'Retosparaprogramadores #22.';\n        title.style.setProperty('font-size', '3.5vmax');\n        title.style.setProperty('color', '#fff');\n        title.style.setProperty('line-height', '100vh');\n\n        body?.appendChild(title);\n\n        setTimeout(() => {\n            alert('Retosparaprogramadores #22. Please open the Browser Developer Tools.');\n        }, 2000);\n        log('Retosparaprogramadores #22');\n});\n} else {\n    log('This code is designed to run in a browser environment. Skipping window-related code.');\n    log('Retosparaprogramadores #22');\n}\n\n\n\n/* Functions that operate on other functions, either by taking them as arguments\nor by returning them, are called higher-order functions. \nThe term comes from mathematics, where the distinction between functions and other values is taken more seriously.\nHigher-order functions allow us to abstract over actions, not just values. */\n\n\n//For example, we can have functions that create new functions.\n\nconst powder = (n: number): (m: number) => number => {\n    return (m: number): number => {\n        if (n === 0) return 1; \n        return m * powder(n - 1)(m);\n    };\n}; \n\nlet powder2 = powder(2);\nconsole.log(powder2(10)); // 100\n\n//And we can have functions that change other functions.\n\nconst applyToArray = (func: (...args: number[]) => number) => {\n    return (...arr: number[]) => func(...arr);\n}\n\nconst totalAmount = (...arg: number[]): number => {\n    return arg.reduce((total, n) => total + n, 0);\n}\n\nlet sales: number[] = [123, 45, 67, 865, 76, 54, 3254, 23];\n\nconsole.log(applyToArray(totalAmount)(...sales)); // 4507\n\n//We can even write functions that provide new types of control flow.\n\nfunction unless(test: boolean, then: () => void): void {\n    if (!test) then();\n}\n\nconst isOddNum = (n: number): boolean => n % 2 !== 0; \n\nconst addOddNums = (n: number): number => {\n    let total = 0;\n    do {\n        unless(!isOddNum(n), () => total += n);\n        n--;\n    } while (n > 0);  \n    return total;\n}\n\nconsole.log(addOddNums(100)); // 2500\n\n//There are some built-in array methods, forEach, map, reduce, some... that provide something like a for/of loop as a higher-order function.\n\n//EXTRA DIFICULTY EXERCISE\n\n// Student class definition\nclass Student {\n    private name: string;\n    private birthday: Date;\n    private calification: number;\n\n    constructor(name: string, birthday: string | Date, calification: number) {\n        this.name = name;\n        this.birthday = new Date(birthday); \n        this.calification = calification; \n    }\n\n    getName(): string {\n        return this.name; \n    }\n\n    getBirthday(): Date {\n        return this.birthday; \n    }\n\n    getCalification(): number {\n        return this.calification;\n    }\n\n    setName(name: string): void {\n        this.name = name; \n    }\n\n    setBirthday(birthday: string | Date): void {\n        this.birthday = new Date(birthday);\n    }\n\n    setCalification(calification: number): void {\n        this.calification = calification; \n    }\n}\n\n\n// List of students\nlet students = [\n    new Student('Juan Rulfo', '1986-06-07', 7),\n    new Student('Moure Dev', '1982-03-08', 8.5),\n    new Student('Calvin Maker', '2000-04-02', 9.8),\n    new Student('Adela Jimenez', '1976-01-09', 7.9),\n    new Student('Crist Renegate', '2001-07-09', 5),\n    new Student('Gautama Buda', '0623-05-23', 9),\n    new Student('Niko Zen', '1983-08-08', 10)\n];\n\n// Function to get a list of students with their average grades\ninterface Student {\n    getName(): string;\n    getCalification(): number;\n}\n\ninterface StudentAverage {\n    name: string;\n    average: number;\n}\n\nconst studentsAverageList = (arr: Student[]): StudentAverage[] => {\n    return arr.map(student => ({\n        name: student.getName(), \n        average: student.getCalification() \n    })).sort((a, b) => b.average - a.average);\n};\n\n\ninterface IStudent {\n    getName(): string;\n    getCalification(): number;\n    getBirthday(): Date;\n}\n\n// Function to get a list of students with grades of 9 or higher\nconst higherThan9Students = (arr: IStudent[]): string[] => {\n    return arr.filter(student => student.getCalification() >= 9)\n              .map(student => student.getName());\n};\n\n// Function to sort students by their birth date\nconst sortStudentsByBirthday = (arr: IStudent[]): string[] => {\n    return arr.slice().sort((a, b) => a.getBirthday().getTime() - b.getBirthday().getTime())\n              .map(student => student.getName());\n};\n\n// Function to find the highest grade among all students\nconst highestCalification = (arr: IStudent[]): number => {\n    return Math.max(...arr.map(student => student.getCalification()));\n};\n\n\n// Execute the functions and store the results\nlet averageList = studentsAverageList(students); \nlet bestStudents = higherThan9Students(students);\nlet sortedStudents = sortStudentsByBirthday(students); \nlet highestGrade = highestCalification(students); \n\n// Display the results in the console\nlog(\"Average grades:\", averageList); /*\nAverage grades:\nArray(7) [ {…}, {…}, {…}, {…}, {…}, {…}, {…} ]\n0: Object { name: \"Niko Zen\", average: 10 }\n1: Object { name: \"Calvin Maker\", average: 9.8 }\n2: Object { name: \"Gautama Buda\", average: 9 }\n3: Object { name: \"Moure Dev\", average: 8.5 }\n4: Object { name: \"Adela Jimenez\", average: 7.9 }\n5: Object { name: \"Juan Rulfo\", average: 7 }\n6: Object { name: \"Crist Renegate\", average: 5 }\n */\nlog(\"Best students (9 or higher):\", bestStudents); // Best students (9 or higher): ['Calvin Maker', 'Gautama Buda', 'Niko Zen']\nlog(\"Students sorted by birth date:\", sortedStudents); // Students sorted by birth date: (7) ['Gautama Buda', 'Adela Jimenez', 'Moure Dev', 'Niko Zen', 'Juan Rulfo', 'Calvin Maker', 'Crist Renegate']\nlog(\"Highest grade:\", highestGrade); // Highest grade: 10\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/typescript/eulogioep.ts",
    "content": "// Interfaces para definir la estructura de datos\ninterface EstudianteInfo {\n  nombre: string;\n  fechaNacimiento: Date;\n  calificaciones: number[];\n}\n\ninterface PromedioEstudiante {\n  nombre: string;\n  promedio: number;\n}\n\ninterface EstudianteEdad {\n  nombre: string;\n  fechaNacimiento: string;\n}\n\n// Clase Estudiante para manejar la información de cada alumno\nclass Estudiante implements EstudianteInfo {\n  readonly nombre: string;\n  readonly fechaNacimiento: Date;\n  readonly calificaciones: number[];\n\n  constructor(\n    nombre: string,\n    fechaNacimiento: string,\n    calificaciones: number[]\n  ) {\n    this.nombre = nombre;\n    this.fechaNacimiento = new Date(fechaNacimiento);\n    // Validamos que las calificaciones estén entre 0 y 10\n    this.calificaciones = calificaciones.filter(\n      (calif) => calif >= 0 && calif <= 10\n    );\n  }\n}\n\n// Datos de ejemplo\nconst estudiantes: Estudiante[] = [\n  new Estudiante(\"Ana García\", \"2000-05-15\", [9.5, 8.7, 9.2, 9.8]),\n  new Estudiante(\"Carlos Pérez\", \"1999-03-20\", [7.5, 8.0, 6.5, 7.8]),\n  new Estudiante(\"María López\", \"2001-08-10\", [9.0, 9.5, 9.3, 9.7]),\n];\n\n// Funciones auxiliares\nconst calcularPromedio = (calificaciones: number[]): number => {\n  return (\n    calificaciones.reduce((acc, curr) => acc + curr, 0) / calificaciones.length\n  );\n};\n\n// 1. Obtener lista de estudiantes con sus promedios\nconst obtenerPromedios = (estudiantes: Estudiante[]): PromedioEstudiante[] => {\n  return estudiantes.map((estudiante) => ({\n    nombre: estudiante.nombre,\n    promedio: calcularPromedio(estudiante.calificaciones),\n  }));\n};\n\n// 2. Obtener mejores estudiantes (promedio >= 9)\nconst obtenerMejoresEstudiantes = (estudiantes: Estudiante[]): string[] => {\n  return estudiantes\n    .filter((estudiante) => calcularPromedio(estudiante.calificaciones) >= 9)\n    .map((estudiante) => estudiante.nombre);\n};\n\n// 3. Obtener lista ordenada por fecha de nacimiento (más joven primero)\nconst ordenarPorEdad = (estudiantes: Estudiante[]): EstudianteEdad[] => {\n  return [...estudiantes]\n    .sort((a, b) => b.fechaNacimiento.getTime() - a.fechaNacimiento.getTime())\n    .map((estudiante) => ({\n      nombre: estudiante.nombre,\n      fechaNacimiento: estudiante.fechaNacimiento.toISOString().split(\"T\")[0],\n    }));\n};\n\n// 4. Obtener la calificación más alta de todos los estudiantes\nconst obtenerMayorCalificacion = (estudiantes: Estudiante[]): number => {\n  return Math.max(\n    ...estudiantes.flatMap((estudiante) => estudiante.calificaciones)\n  );\n};\n\n// Mostrar resultados\nconsole.log(\"1. Promedios de calificaciones:\");\nconsole.log(obtenerPromedios(estudiantes));\n\nconsole.log(\"\\n2. Mejores estudiantes (promedio >= 9):\");\nconsole.log(obtenerMejoresEstudiantes(estudiantes));\n\nconsole.log(\"\\n3. Estudiantes ordenados por edad (más joven primero):\");\nconsole.log(ordenarPorEdad(estudiantes));\n\nconsole.log(\"\\n4. Mayor calificación de todos los estudiantes:\");\nconsole.log(obtenerMayorCalificacion(estudiantes));\n\n// Ejemplos adicionales de funciones de orden superior en TypeScript\nconsole.log(\"\\nEjemplos adicionales de funciones de orden superior:\");\n\n// Ejemplo 1: función que retorna otra función (closure) con tipos\nconst multiplicadorPor = (factor: number): ((numero: number) => number) => {\n  return (numero: number): number => numero * factor;\n};\nconst multiplicarPor2 = multiplicadorPor(2);\nconsole.log(\"Multiplicar 4 por 2:\", multiplicarPor2(4)); // Output: 8\n\n// Ejemplo 2: función que recibe otra función como parámetro\nconst aplicarOperacion = <T, U>(\n  valores: T[],\n  operacion: (valor: T) => U\n): U[] => valores.map(operacion);\n\nconst duplicar = (numero: number): number => numero * 2;\nconsole.log(\"Duplicar números [1,2,3]:\", aplicarOperacion([1, 2, 3], duplicar)); // Output: [2,4,6]\n\n// Ejemplo 3: composición de funciones con tipos genéricos\nconst componerFunciones = <T, U, V>(\n  f: (x: U) => V,\n  g: (x: T) => U\n): ((x: T) => V) => {\n  return (x: T): V => f(g(x));\n};\n\nconst sumar1 = (x: number): number => x + 1;\nconst duplicarYSumar1 = componerFunciones(sumar1, duplicar);\nconsole.log(\"Duplicar 5 y sumar 1:\", duplicarYSumar1(5)); // Output: 11\n\n// Ejemplo 4: Función de orden superior con tipos union\ntype Operacion = \"suma\" | \"resta\" | \"multiplicacion\" | \"division\";\n\nconst crearCalculadora = (\n  operacion: Operacion\n): ((a: number, b: number) => number) => {\n  switch (operacion) {\n    case \"suma\":\n      return (a, b) => a + b;\n    case \"resta\":\n      return (a, b) => a - b;\n    case \"multiplicacion\":\n      return (a, b) => a * b;\n    case \"division\":\n      return (a, b) => (b !== 0 ? a / b : NaN);\n  }\n};\n\nconst calculadoraSuma = crearCalculadora(\"suma\");\nconsole.log(\"Suma de 5 + 3:\", calculadoraSuma(5, 3)); // Output: 8\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/typescript/hozlucas28.ts",
    "content": "/*\n    Higher order functions (HOF)...\n*/\n\nconsole.log('Higher order functions (HOF)...')\n\nfunction toFilter<T>(array: T[], callback: (element: T) => boolean): T[] {\n    const filteredArray: T[] = []\n\n    for (const element of array) {\n        callback(element) && filteredArray.push(element)\n    }\n\n    return filteredArray\n}\n\nconst numbers: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\nconsole.log(`\\nnumbers = [${numbers}]`)\n\nconst oddNumbers: number[] = toFilter(numbers, (element) => element % 2 !== 0)\nconsole.log(`\\noddNumbers = [${oddNumbers}]`)\n\nconst evenNumbers: number[] = toFilter(numbers, (element) => element % 2 === 0)\nconsole.log(`\\nevenNumbers = [${evenNumbers}]`)\n\nconsole.log(\n    '\\n# ---------------------------------------------------------------------------------- #\\n'\n)\n\n/*\n    Additional challenge...\n*/\n\nconsole.log('Additional challenge...\\n')\n\ninterface Student {\n    bornDate: Date\n    name: string\n    qualifications: number[]\n}\n\nfunction getAverageQualification(student: Student): number {\n    const total: number = student.qualifications.reduce(\n        (prevValue, currentValue) => prevValue + currentValue,\n        0\n    )\n\n    const averageQualification: number = total / student.qualifications.length\n\n    return parseFloat(averageQualification.toFixed(2))\n}\n\nconst students: Student[] = [\n    {\n        bornDate: new Date(2002, 20, 2),\n        name: 'Lucas Hoz',\n        qualifications: [7.5, 6.8, 8.2],\n    },\n    {\n        bornDate: new Date(2003, 10, 15),\n        name: 'John Doe',\n        qualifications: [9.1, 8.5, 7.9],\n    },\n    {\n        bornDate: new Date(2001, 5, 30),\n        name: 'Jane Smith',\n        qualifications: [8.7, 9.3, 10.0],\n    },\n    {\n        bornDate: new Date(2004, 2, 12),\n        name: 'Alex Johnson',\n        qualifications: [6.4, 7.2, 8.9],\n    },\n    {\n        bornDate: new Date(2000, 8, 5),\n        name: 'Sarah Brown',\n        qualifications: [9.5, 9.8, 9.2],\n    },\n    {\n        bornDate: new Date(2005, 11, 25),\n        name: 'Michael Davis',\n        qualifications: [7.1, 8.3, 7.7],\n    },\n    {\n        bornDate: new Date(2002, 1, 18),\n        name: 'Emily Wilson',\n        qualifications: [8.9, 9.6, 9.4],\n    },\n    {\n        bornDate: new Date(2003, 6, 9),\n        name: 'Daniel Thompson',\n        qualifications: [7.8, 8.1, 7.5],\n    },\n]\n\nconsole.log('Students...')\nconsole.table(students)\n\nconst studentsWithNameAndAverageQualification = students.map((student) => ({\n    name: student.name,\n    averageQualification: getAverageQualification(student),\n}))\n\nconsole.log('\\nStudents with name and average qualification...')\nconsole.table(studentsWithNameAndAverageQualification)\n\nconst studentsWithAverageQualificationMoreThanNine: Student[] = toFilter(\n    students,\n    (student) => {\n        const qualificationAverage: number = getAverageQualification(student)\n        return qualificationAverage >= 9\n    }\n)\n\nconsole.log('\\nStudents with an average qualification more than nine...')\nconsole.table(studentsWithAverageQualificationMoreThanNine)\n\nconst sortedStudentsByBornDate: Student[] = students.toSorted((a, b) => {\n    return b.bornDate.getTime() - a.bornDate.getTime()\n})\n\nconsole.log('\\nSorted students by born date (youngest to oldest)...')\nconsole.table(sortedStudentsByBornDate)\n\nconst studentsWithNameAndBestQualification = students.map((student) => ({\n    name: student.name,\n    bestQualification: Math.max(...student.qualifications),\n}))\n\nconsole.log('\\nStudents with name and best qualification...')\nconsole.table(studentsWithNameAndBestQualification)\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/typescript/victoriaparraf.ts",
    "content": "/**\n * Características de las funciones de orden superior:\n * Toman funciones como argumentos: Permiten pasar funciones como parámetros, lo que permite modificar o extender su comportamiento.\n * Devuelven funciones: Pueden devolver nuevas funciones, lo que permite la creación de funciones personalizadas y reutilizables.\n * Composición y modularidad: Facilitan la composición de funciones más complejas a partir de funciones más simples.\n */\n\nfunction applyOperation(a: number, b: number, operation: (x: number, y: number) => number): number {\n    return operation(a, b);\n}\n\nconst add = (x: number, y: number): number => x + y;\nconst multiply = (x: number, y: number): number => x * y;\n\nconsole.log(applyOperation(5, 3, add)); // 8\nconsole.log(applyOperation(5, 3, multiply)); // 15\n\nfunction createMultiplier(multiplier: number): (value: number) => number {\n    return (value: number) => value * multiplier;\n}\n\nconst double = createMultiplier(2);\nconst triple = createMultiplier(3);\n\nconsole.log(double(5)); // 10\nconsole.log(triple(5)); // 15\n\nconst numbers = [1, 2, 3, 4, 5];\n\n// map\nconst doubled = numbers.map(num => num * 2);\nconsole.log(doubled); // [2, 4, 6, 8, 10]\n\n// filter\nconst evenNumbers = numbers.filter(num => num % 2 === 0);\nconsole.log(evenNumbers); // [2, 4]\n\n// reduce\nconst sum = numbers.reduce((accumulator, current) => accumulator + current, 0);\nconsole.log(sum); // 15\n"
  },
  {
    "path": "Roadmap/22 - FUNCIONES DE ORDEN SUPERIOR/vb.net/kenysdev.vb",
    "content": "' ╔══════════════════════════════════════╗\n' ║ Autor:  Kenys Alvarado               ║\n' ║ GitHub: https://github.com/Kenysdev  ║\n' ║ 2024 -  VB.NET                       ║\n' ╚══════════════════════════════════════╝\n'-----------------------------------------------\n'* FUNCIONES DE ORDEN SUPERIOR\n'-----------------------------------------------\n\nModule Program\n    '* EJERCICIO #1:\n    '* Explora el concepto de funciones de orden superior en tu lenguaje \n    '* creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n\n    Delegate Function ArithmeticOperation(x As Integer, y As Integer) As Integer\n\n    Function ArithmeticOp(operation As ArithmeticOperation) As Func(Of Integer, Integer, Integer)\n        Return Function(x, y) operation(x, y)\n    End Function\n\n    Function Add(x As Integer, y As Integer) As Integer\n        Return x + y\n    End Function\n\n    Function Subtract(x As Integer, y As Integer) As Integer\n        Return x - y\n    End Function\n\n    Function Multiply(x As Integer, y As Integer) As Integer\n        Return x * y\n    End Function\n\n    '* EJERCICIO #2\n    '* Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n    '* lista de calificaciones), utiliza funciones de orden superior para \n    '* realizar las siguientes operaciones de procesamiento y análisis:\n    '* - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n    '*   y promedio de sus calificaciones.\n    '* - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n    '*   que tienen calificaciones con un 9 o más de promedio.\n    '* - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n    '* - Mayor calificación: Obtiene la calificación más alta de entre todas las\n    '*   de los alumnos.\n    '* - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n\n    ReadOnly studentsList As New List(Of Dictionary(Of String, Object)) From {\n        New Dictionary(Of String, Object) From {{\"name\", \"Ken\"}, {\"dob\", \"2012-04-21\"}, {\"grades\", {9.5, 9.4, 9.3, 9.2}.ToList()}},\n        New Dictionary(Of String, Object) From {{\"name\", \"Ben\"}, {\"dob\", \"2012-03-20\"}, {\"grades\", {8.5, 8.4, 8.3, 8.2}.ToList()}},\n        New Dictionary(Of String, Object) From {{\"name\", \"Ada\"}, {\"dob\", \"2012-02-19\"}, {\"grades\", {7.5, 7.4, 7.3, 7.2}.ToList()}},\n        New Dictionary(Of String, Object) From {{\"name\", \"Zoe\"}, {\"dob\", \"2012-01-18\"}, {\"grades\", {9.0, 9.1, 9.0, 9.1}.ToList()}}\n    }\n\n    Delegate Sub PrintFunction(student As Dictionary(Of String, Object))\n\n    Function HigherOrderFun(msg As String, printFn As PrintFunction) As Action(Of List(Of Dictionary(Of String, Object)))\n        Dim wrapper As Action(Of List(Of Dictionary(Of String, Object))) =\n            Sub(students)\n                Console.WriteLine($\"{vbCrLf}----{vbCrLf}{msg}\")\n                For Each student In students\n                    printFn(student)\n                Next\n            End Sub\n\n        Return wrapper\n    End Function\n\n    Sub PrintGradePointAverage(student As Dictionary(Of String, Object))\n        Dim grades = DirectCast(student(\"grades\"), List(Of Double))\n        Dim averageGrade = grades.Sum() / grades.Count\n        Console.WriteLine($\"{student(\"name\")} {averageGrade}\")\n    End Sub\n\n    Sub PrintTopStudents(student As Dictionary(Of String, Object))\n        Dim grades = DirectCast(student(\"grades\"), List(Of Double))\n        Dim average = grades.Sum() / grades.Count\n        If average >= 9 Then\n            Console.WriteLine(student(\"name\"))\n        End If\n    End Sub\n\n    Sub PrintBirthOrder(student As Dictionary(Of String, Object))\n        Console.WriteLine($\"{student(\"name\")} {student(\"dob\")}\")\n    End Sub\n\n    Sub PrintHighestGrade(student As Dictionary(Of String, Object))\n        Dim maxGrade = DirectCast(student(\"grades\"), List(Of Double)).Max()\n        Console.WriteLine($\"{student(\"name\")} {maxGrade}\")\n    End Sub\n\n    Sub Main()\n        Console.WriteLine(\"EJERCICIO #1\")\n        Dim addFunc = ArithmeticOp(AddressOf Add)\n        Dim subtractFunc = ArithmeticOp(AddressOf Subtract)\n        Dim multiplyFunc = ArithmeticOp(AddressOf Multiply)\n\n        Console.WriteLine(addFunc(3, 5))\n        Console.WriteLine(subtractFunc(10, 3))\n        Console.WriteLine(multiplyFunc(2, 4))\n\n        Console.WriteLine(\"EJERCICIO #2\")\n        Dim gradePointAverage = HigherOrderFun(\"Promedio calificaciones\", AddressOf PrintGradePointAverage)\n        Dim topStudents = HigherOrderFun(\"Mejores estudiantes:\", AddressOf PrintTopStudents)\n        Dim birthOrder = HigherOrderFun(\"Por nacimiento:\", AddressOf PrintBirthOrder)\n        Dim highestGrade = HigherOrderFun(\"Mayor calificación:\", AddressOf PrintHighestGrade)\n\n        gradePointAverage(studentsList)\n        topStudents(studentsList)\n        birthOrder(studentsList.OrderBy(Function(student) CStr(student(\"dob\"))).ToList())\n        highestGrade(studentsList)\n    End Sub\n\nEnd Module\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/bash/rantamhack.sh",
    "content": "#!/bin/bash\n\necho -e \"\\n\\n=======================================EJERCICIO=======================================\\n\\n\"\n\n# * EJERCICIO:\n# * Explora el patron de diseño \"singleton\" y muestra como crearlo\n# * con un ejemplo generico.\n\n# * Bash no es un lenguaje orientado a objetos. Hay que simular el comportamiento de las clases\n\nsingleton_instance=\"\"\n\nfunction get_singleton_instance(){\n    if [[ -z \"$singleton_instance\" ]]; then\n        singleton_instance=\"instance_created\"\n    fi\n}\n\n\ninstance1=$(get_singleton_instance)\ninstance2=$(get_singleton_instance)\n\necho -e \"\\nComprobando que las dos instancias son la misma instancia:\\n\"\n\nif [[ \"$instance1\" == \"$instance2\" ]]; then\n    echo \"True\"\nelse\n    echo \"False\"\nfi\n\n\n\n\necho -e \"\\n\\n=======================================DIFICULTAD EXTRA=======================================\\n\\n\"\n\n\n# * DIFICULTAD EXTRA (opcional):\n# * Utiliza el patron de diseño \"singleton\" para representar una clase que\n# * haga referencia a la sesion de usuario de una aplicacion ficticia.\n# * La sesion debe permitir asignar un usuario (id, username, nombre y email),\n# * recuperar los datos del usuario y borrar los datos de la sesion.\n\n\nsession_id=\"\"\nsession_username=\"\"\nsession_name=\"\"\nsession_email=\"\"\n\nfunction log_in() {\n    if [[ -z \"$session_id\" ]];then\n        session_id=$1\n        session_username=$2\n        session_name=$3\n        session_email=$4\n        echo -e \"\\n\\nEl usuario $2 iniciado sesion\"\n    else\n        echo -e \"\\nYa hay un usuario con sesion iniciada\\n\"\n    fi\n}\n\nfunction logout() {\n    if [[ -n \"$session_id\" ]]; then\n        echo -e \"\\nEl usuario $session_username ha cerrado la sesion\"\n        session_id=\"\"\n        session_username=\"\"\n        session_name=\"\"\n        session_email=\"\"\n    else\n        echo  -e \"\\nNo hay ninguna sesion iniciada\\n\"\n    fi\n}\n\nfunction get_user() {\n    if [[ -n $session_id ]]; then\n        echo -e \"\\n\\nUsuario actual:\"\n        echo -e \"\\tID: $session_id\"\n        echo -e \"\\tUSERNAME: $session_username\"\n        echo -e \"\\tNAME: $session_name\"\n        echo -e \"\\tEMAIL: $session_email\"\n    else\n        echo -e \"\\nNo hay ninguna sesion abierta\"\n    fi\n}\n\n\nuser1_id=1 \nuser1_username=\"Rantam\"\nuser1_name=\"Alex\"\nuser1_email=\"rantam@rantam.es\"\n\n\n\nuser2_id=2\nuser2_username=\"Junior\"\nuser2_name=\"Maria\"\nuser2_email=\"maria@rantam.es\"\n\nlog_in $user1_id $user1_username $user1_name $user1_email\nget_user\n\nlog_in $user2_id $user2_username $user2_name $user2_email\n\nlogout\n\nlog_in $user2_id $user2_username $user2_name $user2_email\nget_user\n\nlogout\n\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/c#/hequebo.cs",
    "content": "class Program\n{\n    static void Main(string[] args)\n    {\n        /*\n         * No creamos un objeto de la clase, en\n         * su lugar accedemos a la instancia ya\n         * existente\n         */\n        var singleton = Singleton.Instance;\n        var singleton2 = Singleton.Instance;\n        /*\n         * Ambas variable acceden a la misma instancia\n         * por lo que si las comparamos podemos ver \n         * que son iguales\n         */\n        Console.WriteLine($\"singleton == singleton2 es {singleton == singleton2}\");\n\n        // Ejercicio Extra\n        var userSession = UserSession.GetInstance();\n        userSession.SetUser(1, \"Hequebo\", \"Emilio Quezada\", \"emilioqzb@gmail.com\");\n        Console.WriteLine(userSession.GetUser());\n\n        var userSession2 = UserSession.GetInstance();\n        Console.WriteLine(userSession2.GetUser());\n        userSession2.ClearUser();\n        \n        var userSession3 = UserSession.GetInstance();\n        userSession3.ClearUser();\n        Console.WriteLine(userSession3.GetUser());\n    }\n}\n/*\n * Singleton es un patrón de diseño para la\n * creación de objetos que consiste en que \n * solo exista un solo objeto en todo la \n * aplicación y no se puedan crear más \n * instancias.\n */\nclass Singleton\n{\n    /*\n     * Creamos un atributo privado solo de \n     * lectura que será del mismo tipo de la \n     * clase en el cual estara el objeto que\n     * se creara una vez se compile la \n     * solución\n     */\n    private static readonly Singleton _instance = new Singleton();\n    /*\n     * Para poder accedera a la instancia \n     * creamos una propiedad que regresa el\n     * atributo privado\n     */\n    public static Singleton Instance {  get { return _instance; } }\n    /*\n     * Para evitar crear objetos de esta clase\n     * agregamos un contructor privado\n     */\n    private Singleton() { }\n}\n\nclass UserSession\n{\n    private static UserSession _instance = null;\n    private int _id;\n    private string _username;\n    private string _name;\n    private string _email;\n\n    /*\n     * Una alternativa a tenere la instancia como\n     * solo de lectura es crearla como nula y a\n     * través de un metodo crear el objeto si es\n     * que no ha sido creado antes\n     */\n    public static UserSession GetInstance()\n    {\n        if (_instance == null)\n            _instance = new UserSession();\n        return _instance;\n    }\n\n    public string GetUser()\n    {\n        return $\"Id: {_id}, Usuario: {_username}, Nombre: {_name},  Correo: {_email}\";\n    }\n    public void SetUser(int id, string username, string name, string emmail)\n    {\n        _id = id;\n        _username = username;\n        _name = name;\n        _email = emmail;\n    }\n    public void ClearUser()\n    {\n        _id = 0;\n        _username = \"\";\n        _name = \"\";\n        _email = \"\";\n    }\n}\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/c#/jamerrq.cs",
    "content": "﻿/*\r\n * EJERCICIO:\r\n * Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\r\n * con un ejemplo genérico.\r\n *\r\n * DIFICULTAD EXTRA (opcional):\r\n * Utiliza el patrón de diseño \"singleton\" para representar una clase que\r\n * haga referencia a la sesión de usuario de una aplicación ficticia.\r\n * La sesión debe permitir asignar un usuario (id, username, nombre y email),\r\n * recuperar los datos del usuario y borrar los datos de la sesión.\r\n */\r\n\r\nusing System;\r\n\r\nnamespace Roadmap23\r\n{\r\n    class Singleton\r\n    {\r\n        private static Singleton? instance;\r\n        private Singleton() { }\r\n\r\n        public static Singleton Instance\r\n        {\r\n            get\r\n            {\r\n                instance ??= new Singleton();\r\n                return instance;\r\n            }\r\n        }\r\n    }\r\n\r\n    class Program\r\n    {\r\n\r\n        // Extra: Clase de sesión de usuario\r\n        class UserSession\r\n        {\r\n            private static UserSession? instance;\r\n            private UserSession()\r\n            {\r\n                Id = 0;\r\n                Username = \"\";\r\n                Name = \"\";\r\n                Email = \"\";\r\n            }\r\n\r\n            public static UserSession Instance\r\n            {\r\n                get\r\n                {\r\n                    instance ??= new UserSession();\r\n                    return instance;\r\n                }\r\n            }\r\n\r\n            public int Id { get; private set; }\r\n            public string Username { get; private set; }\r\n            public string Name { get; private set; }\r\n            public string Email { get; private set; }\r\n\r\n            public void SetUser(int id, string username, string name, string email)\r\n            {\r\n                Id = id;\r\n                Username = username;\r\n                Name = name;\r\n                Email = email;\r\n            }\r\n\r\n            public void ClearUser()\r\n            {\r\n                Id = 0;\r\n                Username = \"\";\r\n                Name = \"\";\r\n                Email = \"\";\r\n            }\r\n        }\r\n        static void Main(string[] args)\r\n        {\r\n            Singleton s1 = Singleton.Instance;\r\n            Singleton s2 = Singleton.Instance;\r\n\r\n            Console.WriteLine(\"Are s1 and s2 the same instance?\");\r\n            Console.WriteLine(s1 == s2);\r\n\r\n            // Extra: Uso de la sesión de usuario\r\n            UserSession session = UserSession.Instance;\r\n            Console.WriteLine(\"\\n *+* Fill user data *+*\\n\");\r\n            session.SetUser(1, \"user\", \"User Name\", \"e@mail.com\");\r\n\r\n            Console.WriteLine(\"User ID: \" + session.Id);\r\n            Console.WriteLine(\"Username: \" + session.Username);\r\n            Console.WriteLine(\"Name: \" + session.Name);\r\n            Console.WriteLine(\"Email: \" + session.Email);\r\n\r\n            session.ClearUser();\r\n            Console.WriteLine(\"\\n *+* User data cleared *+*\\n\");\r\n\r\n            Console.WriteLine(\"User ID: \" + session.Id);\r\n            Console.WriteLine(\"Username: \" + session.Username);\r\n            Console.WriteLine(\"Name: \" + session.Name);\r\n            Console.WriteLine(\"Email: \" + session.Email);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/c#/kenysdev.cs",
    "content": "#pragma warning disable CA1050\n/*\n╔══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado               ║\n║ GitHub: https://github.com/Kenysdev  ║\n║ 2024 -  C#                           ║\n╚══════════════════════════════════════╝\n------------------------------------------\n* PATRONES DE DISEÑO: SINGLETON\n------------------------------------------\n\n* EJERCICIO #1:\n* Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n* con un ejemplo genérico.\n*/\npublic class Singleton {\n    private static Singleton _instance;\n\n    // Constructor privado para evitar la instanciación directa.\n    private Singleton() { }\n\n    // Método estático que devuelve la única instancia de la clase.\n    public static Singleton Instance {\n        get {\n            // Si la instancia aún no ha sido creada, la crea.\n            _instance ??= new Singleton();\n            return _instance;\n        }\n    }\n}\n\n/*\n__________________________________\n* EJERCICIO #2:\n* Utiliza el patrón de diseño \"singleton\" para representar una clase que\n* haga referencia a la sesión de usuario de una aplicación ficticia.\n* La sesión debe permitir asignar un usuario (id, username, nombre y email),\n* recuperar los datos del usuario y borrar los datos de la sesión.\n*/\n\npublic class UserSession {\n    private static UserSession _instance;\n    private int _userId;\n    private string _userName;\n    private string _name;\n    private string _email;\n    private UserSession() { }\n\n    public static UserSession Instance {\n        get {\n            // Si la instancia aún no ha sido creada, la crea.\n            _instance ??= new UserSession();\n            return _instance;\n        }\n    }\n\n    // Método para establecer los detalles del usuario.\n    public void SetUser(int userId, string userName, string name, string email) {\n        _userId = userId;\n        _userName = userName;\n        _name = name;\n        _email = email;\n    }\n\n    public Dictionary<string, object> GetUser() {\n        Dictionary<string, object> userDetails = new() {\n            { \"id\", _userId },\n            { \"username\", _userName },\n            { \"name\", _name },\n            { \"email\", _email }\n        };\n        return userDetails;\n    }\n\n    public void Logout() {\n        _userId = 0;\n        _userName = null;\n        _name = null;\n        _email = null;\n    }\n}\n\n// __________________________________\nclass Program {    \n    static void Main() {\n        Console.WriteLine(\"EJERCICIO #1\");\n\n        Singleton singleton1 = Singleton.Instance;\n        \n        // singleton2 accede a la misma instancia que singleton1.\n        Singleton singleton2 = Singleton.Instance;\n\n        // Comprobación de igualdad de referencias.\n        Console.WriteLine(singleton1 == singleton2);\n\n        // __________________________________\n        Console.WriteLine(\"EJERCICIO #2\");\n        \n        var login_user1 = UserSession.Instance;\n        login_user1.SetUser(1, \"Zoe_1\", \"Zoe\", \"Zoe@gm.com\");\n        Dictionary<string, object> userDetails1 = login_user1.GetUser();\n        foreach (var kvp in userDetails1) {\n            Console.WriteLine($\"{kvp.Key}: {kvp.Value}\");\n        };\n        \n        login_user1.Logout();\n\n        var login_user2 = UserSession.Instance;\n        login_user2.SetUser(2, \"Ben_1\", \"Ben\", \"Ben@gm.com\");\n        Dictionary<string, object> userDetails2 = login_user2.GetUser();\n        foreach (var kvp in userDetails2) {\n            Console.WriteLine($\"{kvp.Key}: {kvp.Value}\");\n        }\n\n        login_user2.Logout();\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/c++/hectorio23.cpp",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\n#include <iostream>\n#include <string>\n#include <optional>\n\n/////////////////////////////////////////////////\n/////////////////// EJERCICIO 1 /////////////////\n/////////////////////////////////////////////////\n\nclass NotDuplicity {\npublic:\n    static NotDuplicity& getInstance() {\n        static NotDuplicity instance;\n        return instance;\n    }\n\n    // Eliminamos los métodos de copia y asignación para evitar múltiples instancias\n    NotDuplicity(NotDuplicity const&) = delete;\n    void operator=(NotDuplicity const&) = delete;\n\nprivate:\n    NotDuplicity() {}  // Constructor privado\n};\n\n/////////////////////////////////////////////////\n///////////////// EJERCICIO EXTRA ///////////////\n/////////////////////////////////////////////////\n\nclass UserSession {\npublic:\n    struct UserData {\n        int id;\n        std::string username;\n        std::string name;\n        std::string email;\n    };\n\n    static UserSession& getInstance() {\n        static UserSession instance;\n        return instance;\n    }\n\n    // Eliminamos los métodos de copia y asignación para evitar múltiples instancias\n    UserSession(UserSession const&) = delete;\n    void operator=(UserSession const&) = delete;\n\n    void setUser(int userId, const std::string& username, const std::string& name, const std::string& email) {\n        userData = UserData{userId, username, name, email};\n    }\n\n    std::optional<UserData> getUser() const {\n        return userData;\n    }\n\n    void clearUser() {\n        userData.reset();\n    }\n\nprivate:\n    std::optional<UserData> userData;\n\n    UserSession() {}  // Constructor privado\n};\n\nint main() {\n    // Ejercicio 1: Singleton Genérico\n    NotDuplicity& obj1 = NotDuplicity::getInstance();\n    NotDuplicity& obj2 = NotDuplicity::getInstance();\n\n    std::cout << \"ID Objeto 1 => \" << &obj1 << std::endl;\n    std::cout << \"ID Objeto 2 => \" << &obj2 << std::endl;\n    std::cout << \"¿Los objetos 1 y 2 son iguales? \" << (&obj1 == &obj2) << std::endl;\n\n    std::cout << \"\\n********************************\\n\";\n\n    // Ejercicio Extra: Sesión de Usuario\n    UserSession& session = UserSession::getInstance();\n    session.setUser(1, \"hectorio23\", \"Adán\", \"adan_example@example.com\");\n\n    auto user = session.getUser();\n    if (user) {\n        std::cout << \"Usuario: \" << user->username << \", Nombre: \" << user->name << \", Email: \" << user->email << std::endl;\n    }\n\n    session.clearUser();\n\n    user = session.getUser();\n    if (!user) {\n        std::cout << \"Datos del usuario borrados\" << std::endl;\n    }\n\n    // Verificación de singleton:\n    UserSession& anotherSession = UserSession::getInstance();\n    std::cout << \"¿Las sesiones son iguales? \" << (&session == &anotherSession) << std::endl;\n\n    return 0;\n}"
  },
  {
    "path": "Roadmap/23 - SINGLETON/ejercicio.md",
    "content": "# #23 PATRONES DE DISEÑO: SINGLETON\n> #### Dificultad: Media | Publicación: 03/06/24 | Corrección: 10/06/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n * con un ejemplo genérico.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el patrón de diseño \"singleton\" para representar una clase que\n * haga referencia a la sesión de usuario de una aplicación ficticia.\n * La sesión debe permitir asignar un usuario (id, username, nombre y email),\n * recuperar los datos del usuario y borrar los datos de la sesión.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/23 - SINGLETON/go/N0HagoNada.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n)\n\ntype Singleton struct {\n\tname string\n}\n\nvar single *Singleton\nvar onceExample sync.Once\n\nfunc getInstanceSingleton() *Singleton {\n\tonceExample.Do(func() {\n\t\tsingle = &Singleton{name: \"Jhon\"}\n\t})\n\treturn single\n}\n\nfunc (single *Singleton) GetName() string {\n\treturn single.name\n}\n\nfunc (single *Singleton) SetName(name string) {\n\tsingle.name = name\n}\n\n// ************************************ RETO ************************************************* //\n\ntype User struct {\n\tID       int\n\tName     string\n\tUsername string\n\tEmail    string\n}\n\ntype session struct {\n\tuser *User\n\tsync.Mutex\n}\n\nvar (\n\tinstance *session\n\tonce     sync.Once\n)\n\nfunc getSessionInstance() *session {\n\tonce.Do(func() {\n\t\tinstance = &session{}\n\t})\n\treturn instance\n}\n\nfunc (s *session) SetUser(u *User) {\n\ts.Lock()\n\tdefer s.Unlock()\n\ts.user = u\n}\n\nfunc (s *session) GetUser() *User {\n\ts.Lock()\n\tdefer s.Unlock()\n\treturn s.user\n}\n\nfunc (s *session) ClearSession() {\n\ts.Lock()\n\tdefer s.Unlock()\n\ts.user = nil\n}\n\nfunc main() {\n\n\tsession := getSessionInstance()\n\n\tuser := &User{\n\t\tID:       1,\n\t\tName:     \"John Doe\",\n\t\tUsername: \"johndoe\",\n\t\tEmail:    \"john.doe@example.com\",\n\t}\n\tsession.SetUser(user)\n\n\tcurrentUser := session.GetUser()\n\tfmt.Println(\"User ID:\", currentUser.ID)\n\tfmt.Println(\"Name:\", currentUser.Name)\n\tfmt.Println(\"Username:\", currentUser.Username)\n\tfmt.Println(\"Email:\", currentUser.Email)\n\n\t// Borrar los datos de la sesión\n\tsession.ClearSession()\n\n\tcurrentUser = session.GetUser()\n\tif currentUser == nil {\n\t\tfmt.Println(\"La sesión ha sido borrada.\")\n\t}\n}\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/go/hozlucas28.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n)\n\n/* -------------------------------------------------------------------------- */\n/*                                   CLASSES                                  */\n/* -------------------------------------------------------------------------- */\n\n/* --------------------------------- Counter -------------------------------- */\n\ntype counter struct {\n\t__count int\n}\n\nvar counterMutex *sync.Mutex = &sync.Mutex{}\n\nvar counterInstance *counter\n\nfunc Counter() *counter {\n\tif counterInstance == nil {\n\t\tcounterMutex.Lock()\n\t\tdefer counterMutex.Unlock()\n\n\t\tif counterInstance == nil {\n\t\t\tcounterInstance = &counter{}\n\t\t}\n\t}\n\n\treturn counterInstance\n}\n\nfunc (counter *counter) getCount() int {\n\treturn counter.__count\n}\n\nfunc (counter *counter) decrement() *counter {\n\tcounter.__count -= 1\n\treturn counter\n}\n\nfunc (counter *counter) increment() *counter {\n\tcounter.__count += 1\n\treturn counter\n}\n\n/* --------------------------------- Session -------------------------------- */\n\ntype session struct {\n\t__email    string\n\t__id       string\n\t__name     string\n\t__userName string\n}\n\nvar sessionMutex *sync.Mutex = &sync.Mutex{}\n\nvar sessionInstance *session\n\ntype SessionParams struct {\n\temail    string\n\tid       string\n\tname     string\n\tuserName string\n}\n\nfunc Session(params SessionParams) *session {\n\n\tif sessionInstance == nil {\n\t\tsessionMutex.Lock()\n\t\tdefer sessionMutex.Unlock()\n\n\t\tif sessionInstance == nil {\n\t\t\tsessionInstance = &session{\n\t\t\t\t__email:    params.email,\n\t\t\t\t__id:       params.id,\n\t\t\t\t__name:     params.name,\n\t\t\t\t__userName: params.userName,\n\t\t\t}\n\t\t}\n\t}\n\n\treturn sessionInstance\n}\n\nfunc (session *session) getEmail() string {\n\treturn session.__email\n}\n\nfunc (session *session) getId() string {\n\treturn session.__id\n}\n\nfunc (session *session) getName() string {\n\treturn session.__name\n}\n\nfunc (session *session) getUserName() string {\n\treturn session.__userName\n}\n\nfunc (session *session) setEmail(newEmail string) *session {\n\tsession.__email = newEmail\n\treturn session\n}\n\nfunc (session *session) setId(newId string) *session {\n\tsession.__id = newId\n\treturn session\n}\n\nfunc (session *session) setName(newName string) *session {\n\tsession.__name = newName\n\treturn session\n}\n\nfunc (session *session) setUserName(newUserName string) *session {\n\tsession.__userName = newUserName\n\treturn session\n}\n\nfunc (session *session) deleteData() *session {\n\tsession.__email = \"\"\n\tsession.__id = \"\"\n\tsession.__name = \"\"\n\tsession.__userName = \"\"\n\n\treturn session\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\nfunc main() {\n\t/*\n\t\tSingleton pattern...\n\t*/\n\n\tfmt.Println(\"Singleton pattern...\")\n\n\tvar counter01 *counter = Counter()\n\tvar counter02 *counter = Counter()\n\n\tfmt.Printf(\"\\nAre `counter01` and `counter02` the same instance of `counter` class? %t\\n\", counter01 == counter02)\n\n\tfmt.Println(\"\\nMethod call of `counter01` instance...\")\n\n\tcounter01.increment().increment().increment()\n\tfmt.Println(\"\\ncounter01.increment().increment().increment()\")\n\n\tfmt.Printf(\"\\nCount attribute of `counter01` instance --> %d\\n\", counter01.getCount())\n\n\tfmt.Println(\"\\nMethod call of `counter02` instance...\")\n\n\tcounter02.decrement()\n\tfmt.Println(\"\\ncounter02.decrement()\")\n\n\tfmt.Printf(\"\\nCount attribute of `counter02` instance --> %d\\n\", counter02.getCount())\n\n\tfmt.Println(\"\\n# ---------------------------------------------------------------------------------- #\")\n\n\t/*\n\t\tAdditional challenge...\n\t*/\n\n\tfmt.Println(\"\\nAdditional challenge...\")\n\n\tvar userSession *session = Session(SessionParams{\n\t\temail:    \"marianogonzales@gmail.com\",\n\t\tid:       \"11U-287O-25ZK\",\n\t\tname:     \"Mariano\",\n\t\tuserName: \"MarianoPro360\",\n\t})\n\n\tfmt.Printf(\"\\nUser session data: %s %s %s %s\\n\", userSession.getId(), userSession.getName(), userSession.getUserName(), userSession.getEmail())\n\n\tuserSession.deleteData()\n\tfmt.Println(\"\\nUser session data deleted!\")\n\n\tfmt.Printf(\"\\nUser session data: %s %s %s %s\", userSession.getId(), userSession.getName(), userSession.getUserName(), userSession.getEmail())\n}\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/go/kodenook.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n)\n\ntype Singleton struct {\n\tdata string\n}\n\nvar instancia *Singleton\n\nvar once sync.Once\n\nfunc GetInstance() *Singleton {\n\tonce.Do(func() {\n\t\tinstancia = &Singleton{data: \"Data example\"}\n\t})\n\treturn instancia\n}\n\nfunc main() {\n\n\tsingleton := GetInstance()\n\tfmt.Println(singleton.data)\n\n\tother := GetInstance()\n\tfmt.Println(other.data)\n\n\tsingleton.data = \"New data\"\n\n\tfmt.Println(other.data)\n}\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/go/qwik-zgheib.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n)\n\ntype Singleton struct {\n\tvalue string\n}\n\nvar (\n\tinstanceA *Singleton\n\tonceA     sync.Once\n)\n\nfunc GetInstanceA() *Singleton {\n\tonceA.Do(func() {\n\t\tinstanceA = &Singleton{value: \"initializing...\"}\n\t})\n\treturn instanceA\n}\n\nfunc (s *Singleton) SetValue(value string) {\n\ts.value = value\n}\n\nfunc (s *Singleton) GetValue() string {\n\treturn s.value\n}\n\n/* extra challenge */\n\ntype User struct {\n\tID       int\n\tUsername string\n\tName     string\n\tEmail    string\n}\n\ntype Session struct {\n\tuser *User\n\tmu   sync.Mutex\n}\n\nvar (\n\tinstance *Session\n\tonce     sync.Once\n)\n\nfunc GetInstance() *Session {\n\tonce.Do(func() {\n\t\tinstance = &Session{}\n\t})\n\treturn instance\n}\n\nfunc (s *Session) SetUser(user *User) {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\ts.user = user\n}\n\nfunc (s *Session) GetUser() *User {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\treturn s.user\n}\n\nfunc (s *Session) ClearUser() {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\ts.user = nil\n}\n\nfunc main() {\n\ts1 := GetInstanceA()\n\tfmt.Println(s1.GetValue())\n\n\ts1.SetValue(\"new value\")\n\n\ts2 := GetInstanceA()\n\tfmt.Println(s2.GetValue())\n\n\tfmt.Printf(\"s1 and s2 are equals: %v\\n\", s1 == s2)\n\n\t/* extra challenge */\n\tsession := GetInstance()\n\n\tuser := &User{\n\t\tID:       1,\n\t\tUsername: \"qwik-zgheib\",\n\t\tName:     \"Qwik Zgheib\",\n\t\tEmail:    \"qwikzgheib@gmail.com\",\n\t}\n\n\tsession.SetUser(user)\n\n\tretrievedUser := session.GetUser()\n\tfmt.Printf(\"User: %v\\n\", retrievedUser)\n\n\tsession.ClearUser()\n\n\tretrievedUser = session.GetUser()\n\tfmt.Printf(\"User after clear: %v\\n\", retrievedUser)\n}\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/go/raynerpv2022.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n)\n\ntype User struct {\n\tName  string\n\tId    int\n\tEmail string\n}\n\nvar einMal sync.Once\nvar UserUser *User\n\nfunc GetI() *User {\n\teinMal.Do(func() {\n\t\tUserUser = &User{\"\", 0, \"\"}\n\t})\n\treturn UserUser\n}\n\nfunc (u *User) SetUser(name string, id int, email string) {\n\tu.Name = name\n\tu.Id = id\n\tu.Email = email\n\n}\n\nfunc (u *User) GetUser() string {\n\tif u != nil {\n\t\treturn fmt.Sprintf(\" Name %v, Id %v, Email %v\", u.Name, u.Id, u.Email)\n\t}\n\treturn \"User is Nil\"\n\n}\n\nfunc (u *User) DeleteUser() {\n\tu.Name = \"\"\n\tu.Id = 0\n\tu.Email = \"\"\n}\n\nfunc main() {\n\tfmt.Println((\"Singleton\"))\n\n\tuser1 := GetI()\n\tuser2 := GetI()\n\tuser1.SetUser(\"Periko\", 10001, \"e@gmail.com\")\n\n\tfmt.Println(user1.GetUser())\n\tfmt.Println(user2.GetUser())\n\tuser3 := GetI()\n\tuser3.DeleteUser()\n\tfmt.Println(user1.GetUser())\n\tfmt.Println(user2.GetUser())\n\tfmt.Println(user3.GetUser())\n}\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/go/thegera4.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n)\n\n// El patrón Singleton garantiza que solo haya una única instancia de una clase en toda la aplicación.\n\n// En GO no hay clases, por lo que se utiliza una estructura para representar la clase Singleton.\ntype Singleton struct {\n\t// Atributos de la estructura.\n}\n// instance representa la instancia única de la estructura Singleton.\nvar instance *Singleton\n// once representa una estructura que permite ejecutar una función una sola vez.\nvar once sync.Once\n// GetInstance devuelve la instancia única de la estructura Singleton.\nfunc GetInstance() *Singleton {\n\tonce.Do(func() {\n\t\tinstance = &Singleton{}\n\t})\n\treturn instance\n}\n\nfunc main() {\n\tinstance1 := GetInstance()\n\tinstance2 := GetInstance()\n\tfmt.Println(instance1 == instance2) // con esto se comprueba que la instancia es única\n\n\t//Extra:\n\textra()\n}\n\n// Extra: User representa la sesión de usuario de la aplicación.\ntype User struct {\n\tID       int\n\tUsername string\n\tName     string\n\tEmail    string\n}\n// Extra: instanceUser representa la instancia única de la estructura User.\nvar instanceUser *User\n// Extra: onceUser representa una estructura que permite ejecutar una función una sola vez.\nvar onceUser sync.Once\n\n// Extra: GetUserInstance devuelve la instancia única de la estructura User.\nfunc GetUserInstance() *User {\n\tonceUser.Do(func() {\n\t\tinstanceUser = &User{}\n\t})\n\treturn instanceUser\n}\n\n// Extra: SetUser asigna los datos del usuario a la instancia Singleton.\nfunc (user *User) SetUser(id int, username, name, email string) {\n\tfmt.Println(\"Datos del usuario asignados:\")\n\tfmt.Println(\"ID:\", id)\n\tfmt.Println(\"Username:\", username)\n\tfmt.Println(\"Nombre:\", name)\n\tfmt.Println(\"Email:\", email)\n}\n\n// Extra: GetUser devuelve los datos del usuario asignados a la instancia Singleton.\nfunc (user *User) GetUser() {\n\tfmt.Println(\"Datos obtenidos del usuario:\")\n\tfmt.Println(\"ID:\", user.ID)\n\tfmt.Println(\"Username:\", user.Username)\n\tfmt.Println(\"Nombre:\", user.Name)\n\tfmt.Println(\"Email:\", user.Email)\n}\n\n// Extra: DeleteUser borra los datos del usuario asignados a la instancia Singleton.\nfunc (user *User) DeleteUser() {\n\tfmt.Println(\"Borrando datos del usuario ahora...\")\n\tuser.ID = 0\n\tuser.Username = \"\"\n\tuser.Name = \"\"\n\tuser.Email = \"\"\n}\n\nfunc extra() {\n\tuserInstance := GetUserInstance()\n\tuserInstance.SetUser(1, \"thegera\", \"Gerardo Medellin\", \"thegera4@hotmail.com\")\n\tuserInstance.GetUser()\n\tuserInstance.DeleteUser()\n\tuserInstance.GetUser()\n}"
  },
  {
    "path": "Roadmap/23 - SINGLETON/java/Abel-ADE.java",
    "content": "public class Main {                                                                                                                                               \n                                                                                                                                                                  \n    /**                                                                                                                                                           \n     * Singleton es un patrón de diseño creacional que permite tener una instancia de una clase o variable,                                                       \n     * al tiempo que proporciona un punto de acceso global a esta instancia.                                                                                      \n     */                                                                                                                                                           \n                                                                                                                                                                  \n    //Tenemos una variable global, que para acceder a ella se deberá usar el método get.                                                                          \n    private static String singleton;                                                                                                                               \n                                                                                                                                                                  \n    //Crea una instancia si no existe y funciona cómo punto de acceso global.                                                                                     \n    public static String getSingleton() {                                                                                                                          \n        if (singleton == null) {                                                                                                                                  \n            singleton = \"singleton\";                                                                                                                              \n        }                                                                                                                                                         \n        return singleton;                                                                                                                                         \n    }                                                                                                                                                             \n                                                                                                                                                                  \n    public static void main(String[] args) {                                                                                                                      \n        //Usamos nuestro singleton.                                                                                                                               \n        System.out.println(getSingleton()+\"\\n\");                                                                                                                  \n                                                                                                                                                                  \n        //DIFICULTAD EXTRA (opcional):                                                                                                                            \n        User sesionUser = Sesion.getUser();                                                                                                                       \n                                                                                                                                                                  \n        System.out.println(\"Iniciando sesión...\\n\");                                                                                                              \n                                                                                                                                                                  \n        System.out.println(\"ID: \"+ sesionUser.getId());                                                                                                           \n        System.out.println(\"Nombre de usuario: \"+ sesionUser.getUserName());                                                                                      \n        System.out.println(\"Nombre: \"+ sesionUser.getName());                                                                                                     \n        System.out.println(\"Correo: \"+ sesionUser.getEmail());                                                                                                    \n                                                                                                                                                                  \n        Sesion.removeUser();                                                                                                                                      \n                                                                                                                                                                  \n        System.out.println(\"\\nSesión eliminada\");                                                                                                                 \n    }                                                                                                                                                             \n}                                                                                                                                                                 \n                                                                                                                                                                  \nclass Sesion {                                                                                                                                                     \n    //Atributo singleton                                                                                                                                          \n    private static User user;                                                                                                                                      \n                                                                                                                                                                  \n    //Método que nos devuelve una instancia única                                                                                                                 \n    public static User getUser() {                                                                                                                                 \n        if (user == null) {                                                                                                                                       \n            user = new User(1, \"Abel-ADE\", \"Abel\", \"Abel-ADE@correo.es\");                                                                                         \n        }                                                                                                                                                         \n        return user;                                                                                                                                              \n    }                                                                                                                                                             \n                                                                                                                                                                  \n    // Método que elimina los datos de la sesión                                                                                                                  \n    public static void removeUser() {                                                                                                                              \n        if (user != null) {                                                                                                                                       \n            user = null;                                                                                                                                          \n        }                                                                                                                                                         \n    }                                                                                                                                                             \n}                                                                                                                                                                 \n                                                                                                                                                                  \nclass User {                                                                                                                                                       \n    //Atributos de un usuario                                                                                                                                     \n    private int id;                                                                                                                                                \n    private String userName;                                                                                                                                       \n    private String name;                                                                                                                                           \n    private String email;                                                                                                                                          \n                                                                                                                                                                  \n    //Métodos get y set para sus atributos                                                                                                                        \n    public int getId() {                                                                                                                                           \n        return id;                                                                                                                                                \n    }                                                                                                                                                             \n                                                                                                                                                                  \n    public String getUserName() {                                                                                                                                  \n        return userName;                                                                                                                                          \n    }                                                                                                                                                             \n                                                                                                                                                                  \n    public String getName() {                                                                                                                                      \n        return name;                                                                                                                                              \n    }                                                                                                                                                             \n                                                                                                                                                                  \n    public String getEmail() {                                                                                                                                     \n        return email;                                                                                                                                             \n    }                                                                                                                                                             \n                                                                                                                                                                  \n    //Constructor                                                                                                                                                 \n    public User(int id, String userName, String name, String email) {                                                                                              \n        this.id = id;                                                                                                                                             \n        this.userName = userName;                                                                                                                                 \n        this.name = name;                                                                                                                                         \n        this.email = email;                                                                                                                                       \n    }                                                                                                                                                             \n}                                                                                                                                                                 \n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/java/AmadorQuispe.java",
    "content": "\n\npublic class Main {\n    public static void main(String[] args) {\n        String singleton1 = Singleton.getInstance();\n        String singleton2 = Singleton.getInstance();\n        //Hace refencia a la misma memoria\n        System.out.println(singleton1 == singleton2);\n\n        Thread thread1 = new Thread(()->{\n            SessionUser sessionUser1 = SessionUser.getInstance(\"0001\",\"user1\",\"user1\",\"user1@gmail.com\");\n            System.out.println(sessionUser1.getEmail());\n        });\n        thread1.start();\n\n        //main thread\n        SessionUser sessionUser = SessionUser.getInstance(\"0002\",\"aquispe\",\"Amador\",\"aquispe@gmail.com\");\n        System.out.println(sessionUser.getEmail());\n\n        Thread thread2 = new Thread(()->{\n            SessionUser sessionUser1 = SessionUser.getInstance(\"0003\",\"user3\",\"user3\",\"user3@gmail.com\");\n            System.out.println(sessionUser1.getEmail());\n        });\n        thread2.start();\n\n    }\n}\n\nclass Singleton {\n    private static String name;\n\n    private Singleton(){\n        name = \"clase singleton\";\n    }\n\n    public static String getInstance(){\n        return name == null ? \"clase singleton\" : name;\n    }\n}\n\nclass SessionUser{\n    private final String id;\n    private final String userName;\n    private final String name;\n    private final String email;\n    private static SessionUser instance;\n\n    private SessionUser(String id, String username, String name, String email) {\n         this.id = id;\n         this.userName = username;\n         this.name = name;\n         this.email = email;\n    }\n\n    //Synchronized, sincroniza la creación en concurrente.\n    public static synchronized SessionUser getInstance(String id, String username, String name, String email) {\n        if (instance == null) instance = new SessionUser(id, username, name, email);\n        return instance;\n    }\n\n    public String getId() {\n        return id;\n    }\n\n    public String getUserName() {\n        return userName;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public String getEmail() {\n        return email;\n    }\n}\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/java/AnaLauDB.java",
    "content": "public class AnaLauDB {\n\n    // Ejemplo genérico de Singleton\n    public static class ConfiguracionSingleton {\n        // Instancia única (static)\n        private static ConfiguracionSingleton instancia;\n\n        // Variable de ejemplo\n        private String configuracion;\n\n        // Constructor privado para evitar instanciación externa\n        private ConfiguracionSingleton() {\n            this.configuracion = \"Configuración por defecto\";\n        }\n\n        // Método público para obtener la instancia única\n        public static ConfiguracionSingleton getInstancia() {\n            if (instancia == null) {\n                instancia = new ConfiguracionSingleton();\n            }\n            return instancia;\n        }\n\n        public String getConfiguracion() {\n            return configuracion;\n        }\n\n        public void setConfiguracion(String configuracion) {\n            this.configuracion = configuracion;\n        }\n    }\n\n    // DIFICULTAD EXTRA: Singleton para sesión de usuario\n    public static class SesionUsuario {\n        private static SesionUsuario instancia;\n\n        // Datos del usuario\n        private Integer id;\n        private String username;\n        private String nombre;\n        private String email;\n        private boolean sesionActiva;\n\n        // Constructor privado\n        private SesionUsuario() {\n            this.sesionActiva = false;\n        }\n\n        // Método para obtener la instancia única\n        public static SesionUsuario getInstancia() {\n            if (instancia == null) {\n                instancia = new SesionUsuario();\n            }\n            return instancia;\n        }\n\n        // Asignar usuario (iniciar sesión)\n        public void asignarUsuario(int id, String username, String nombre, String email) {\n            this.id = id;\n            this.username = username;\n            this.nombre = nombre;\n            this.email = email;\n            this.sesionActiva = true;\n            System.out.println(\"Sesión iniciada para: \" + nombre);\n        }\n\n        // Recuperar datos del usuario\n        public void mostrarDatosUsuario() {\n            if (sesionActiva) {\n                System.out.println(\"=== Datos del Usuario ===\");\n                System.out.println(\"ID: \" + id);\n                System.out.println(\"Username: \" + username);\n                System.out.println(\"Nombre: \" + nombre);\n                System.out.println(\"Email: \" + email);\n            } else {\n                System.out.println(\"No hay sesión activa\");\n            }\n        }\n\n        // Borrar datos de la sesión (cerrar sesión)\n        public void cerrarSesion() {\n            if (sesionActiva) {\n                System.out.println(\"Cerrando sesión de: \" + nombre);\n                this.id = null;\n                this.username = null;\n                this.nombre = null;\n                this.email = null;\n                this.sesionActiva = false;\n                System.out.println(\"Sesión cerrada correctamente\");\n            } else {\n                System.out.println(\"No hay sesión activa para cerrar\");\n            }\n        }\n\n        // Verificar si hay sesión activa\n        public boolean isSesionActiva() {\n            return sesionActiva;\n        }\n\n        // Getters\n        public Integer getId() {\n            return id;\n        }\n\n        public String getUsername() {\n            return username;\n        }\n\n        public String getNombre() {\n            return nombre;\n        }\n\n        public String getEmail() {\n            return email;\n        }\n    }\n\n    public static void main(String[] args) {\n        // Ejemplo básico de Singleton\n        System.out.println(\"=== Ejemplo básico de Singleton ===\");\n        ConfiguracionSingleton config1 = ConfiguracionSingleton.getInstancia();\n        ConfiguracionSingleton config2 = ConfiguracionSingleton.getInstancia();\n\n        System.out.println(\"¿Son la misma instancia? \" + (config1 == config2));\n\n        config1.setConfiguracion(\"Nueva configuración\");\n        System.out.println(\"Config1: \" + config1.getConfiguracion());\n        System.out.println(\"Config2: \" + config2.getConfiguracion());\n\n        System.out.println(\"\\n=== DIFICULTAD EXTRA: Sesión de Usuario ===\");\n\n        // Obtener instancia de sesión\n        SesionUsuario sesion1 = SesionUsuario.getInstancia();\n        SesionUsuario sesion2 = SesionUsuario.getInstancia();\n\n        System.out.println(\"¿Son la misma instancia de sesión? \" + (sesion1 == sesion2));\n\n        // Intentar mostrar datos sin sesión activa\n        sesion1.mostrarDatosUsuario();\n\n        // Asignar usuario (iniciar sesión)\n        sesion1.asignarUsuario(1, \"analau\", \"Ana Laura\", \"ana.laura@email.com\");\n\n        // Mostrar datos del usuario\n        sesion1.mostrarDatosUsuario();\n\n        // Verificar que ambas referencias apuntan al mismo usuario\n        System.out.println(\"\\nVerificando desde sesion2:\");\n        sesion2.mostrarDatosUsuario();\n\n        // Cerrar sesión\n        sesion2.cerrarSesion();\n\n        // Intentar mostrar datos después de cerrar sesión\n        sesion1.mostrarDatosUsuario();\n    }\n}\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/java/FranDev200.java",
    "content": "import java.util.Scanner;\n\npublic class FranDev200 {\n\n\n    static class BBDD{\n\n        private static BBDD bbdd;\n\n        private BBDD(){\n            System.out.println(\"Creando conexion a la BBDD.\");\n        }\n\n        public static BBDD getInstance(){\n            if(bbdd == null){\n                bbdd = new BBDD();\n            }\n            return bbdd;\n        }\n\n        public void crearBBDD(){\n            System.out.println(\"Crear una Base de Datos\");\n        }\n\n        public void eliminarBBDD(){\n            System.out.println(\"Eliminar una Base de Datos\");\n        }\n\n        public void editarBBDD(){\n            System.out.println(\"Editar una Base de Datos\");\n        }\n    }\n\n    static void main() {\n\n        /*\n\n        EJERCICIO:\n         * Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n         * con un ejemplo genérico.\n\n         */\n\n        BBDD bbdd = BBDD.getInstance();\n        bbdd.crearBBDD();\n        bbdd.editarBBDD();\n        bbdd.eliminarBBDD();\n\n        BBDD bbdd2 = BBDD.getInstance();\n        bbdd2.crearBBDD();\n        bbdd2.editarBBDD();\n        bbdd2.eliminarBBDD();\n\n        System.out.println(bbdd == bbdd2); // Nos devuelve True.\n        // Esto quiere decir que ambas referencias de los objetos apuntan a la misma direccion de memoria, donde\n        // está almacenado el objeto\n\n        /*\n\n        bbdd -------- 0xSWEN34          Ambas referencias, apuntan al mismo objeto, almacenado en esa direccion de memoria\n                         /\n        bbdd2 ----------/\n\n         */\n\n        // Esto también sirve para logins por ejemplo en aplicaciones.\n\n\n        /*\n\n        DIFICULTAD EXTRA (opcional):\n         * Utiliza el patrón de diseño \"singleton\" para representar una clase que\n         * haga referencia a la sesión de usuario de una aplicación ficticia.\n         * La sesión debe permitir asignar un usuario (id, username, nombre y email),\n         * recuperar los datos del usuario y borrar los datos de la sesión.\n\n         */\n\n        Scanner sc = new Scanner(System.in);\n\n        Usuario usuario = Usuario.getInstance();\n\n        System.out.println(\"\\n --- EJERCICIO EXTRA ---\");\n        System.out.println();\n\n        System.out.print(\"Introduce el ID del usuario: \");\n        int id = Integer.parseInt(sc.nextLine());\n        System.out.print(\"Introduce el username del usuario: \");\n        String username = sc.nextLine();\n        System.out.print(\"Introduce el nombre del usuario: \");\n        String nombre = sc.nextLine();\n        System.out.print(\"Introduce el email del usuario: \");\n        String email = sc.nextLine();\n\n\n        usuario.iniciarSesion(id, username, nombre, email);\n\n        System.out.println(\"\\nInformacion del usuario\");\n        System.out.println(\"=======================\");\n        usuario.infoUsuario();\n\n        Usuario usuario2 = Usuario.getInstance();\n\n        System.out.println(\"\\nInformacion del usuario\");\n        System.out.println(\"=======================\");\n        usuario2.infoUsuario();\n\n        usuario.cerrarSesion();\n\n\n        System.out.println(\"\\nInformacion del usuario\");\n        System.out.println(\"=======================\");\n        usuario2.infoUsuario();\n\n        /*\n\n        Como podemos comprobar por consola, ambas instancias apuntan al mismo objeto, por eso aunq el nombre de la\n        instancia sea diferente y puedan parecer dos objetos diferentes, vemos que el usuario2 tiene datos\n        sin haberlos rellenado y además coinciden con los de la instancia usuario.\n        También, vemos que al cerrar sesion con la instancia usuario, se borran los datos y si queremos ver\n        los datos de usuario2, vemos que todo es null.\n\n         */\n\n    }\n\n    static class Usuario{\n\n        private static Usuario usuario;\n\n        private String username;\n        private Integer id;\n        private String nombre;\n        private String email;\n\n        private Usuario(){\n            System.out.println(\"Creando usuario. Rellene sus datos.\");\n        }\n\n        public static Usuario getInstance(){\n\n            if(usuario == null){\n                usuario = new Usuario();\n            }\n\n            return usuario;\n        }\n\n        public String getUsername() { return username; }\n\n        public void setUsername(String username) { this.username = username; }\n\n        public Integer getId() { return id; }\n\n        public void setId(Integer id) { this.id = id; }\n\n        public String getNombre() { return nombre; }\n\n        public void setNombre(String nombre) { this.nombre = nombre; }\n\n        public String getEmail() { return email; }\n\n        public void setEmail(String email) { this.email = email; }\n\n        public void infoUsuario(){\n            System.out.println(\"ID: \" + getId());\n            System.out.println(\"Nombre: \" + getNombre());\n            System.out.println(\"Email: \" + getEmail());\n            System.out.println(\"Usuario: \" + getUsername());\n            System.out.println(\"----------------\");\n        }\n\n        public void iniciarSesion(Integer id, String username,\n                                  String nombre, String email){\n            this.id = id;\n            this.username = username;\n            this.nombre = nombre;\n            this.email = email;\n\n            System.out.println(\"\\nSe ha iniciado sesion con el usuario \" + getUsername());\n\n        }\n\n        public void cerrarSesion(){\n\n            System.out.println(\"\\nCerrando sesion...\");\n\n            setUsername(null);\n            setEmail(null);\n            setId(null);\n            setNombre(null);\n\n        }\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/java/JesusWay69.java",
    "content": "package roadmap.ejercicio_23;\n\n/*\n* EJERCICIO:\n * Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n * con un ejemplo genérico.\n */\npublic class JesusWay69 {\n\n    private static JesusWay69 jesusway69;// Variable estática para recibir la unica instancia del Singleton\n\n    private JesusWay69() {\n        System.out.println(\"Creando objeto...\");\n    }\n\n    public static JesusWay69 getJesusway69() {\n\n        if (jesusway69 == null) { //Condicional para crear la instancia si es null\n            jesusway69 = new JesusWay69();//en caso de ser la primera vez es null y se llama al constructor\n        }\n        return jesusway69;// Retorna el objeto único creado\n    }\n\n    public static void main(String[] args) {\n        JesusWay69 instance1 = JesusWay69.getJesusway69();//Creamos un objeto instancia1\n        JesusWay69 instance2 = JesusWay69.getJesusway69();// y otro objeto instancia2\n        System.out.println(\"Instancia1 = \" + instance1);//Observamos que el objeto generado en esta instancia\n        System.out.println(\"Instancia2 = \" + instance2);// es el mismo que el generado en la siguiente instancia\n\n        Session sessionJesus = Singleton.getInstance(1, \"Jesusway69\", \"Jesus\", \"jesusway60@midominio.es\");\n        Session sessionJose = Singleton.getInstance(2, \"Pepe84\", \"Jose\", \"pepepepe@midominio.es\");\n\n        System.out.println(\"\\nSesión de Jesús = \" + sessionJesus + \"\\nID = \" + sessionJesus.id\n                + \"\\nName = \" + sessionJesus.name + \"\\nUsername = \" + sessionJesus.username + \"\\nemail = \" + sessionJesus.email);\n        //Al imprimir los datos solo recupera los datos de la primera instancia que es la de Jesus\n        System.out.println(\"\\nSesión de Jose = \" + sessionJose + \"\\nID = \" + sessionJose.id\n                + \"\\nName = \" + sessionJose.name + \"\\nUsername = \" + sessionJose.username + \"\\nemail = \" + sessionJose.email);\n        //Aunque intentemos imprimir los datos de Jose seguirá imprimiendo los de Jesus porque la sesión es la misma\n        \n        System.out.println(\"\\nBorrando sesion: \" + sessionJesus);\n        Session close = Singleton.deleteInstance();\n        System.out.println(\"Sesión borrada, valor actual = \" + close);\n        //Una vez borrados los datos de la sesión podemos hacer una instancia nueva en este caso de Ana\n        Session sessionAna = Singleton.getInstance(3, \"Ana57\", \"Ana\", \"anagarcia@midominio.es\");\n        System.out.println(\"Nueva instancia para sesión de \" + sessionAna.name + \" = \" + sessionAna);\n        //Imprime correctamente los datos de Ana al haber borrado la sesión anterior de Jesus\n        System.out.println(\"\\nSesión de Ana = \" + sessionAna + \"\\nID = \" + sessionAna.id\n                + \"\\nName = \" + sessionAna.name + \"\\nUsername = \" + sessionAna.username + \"\\nemail = \" + sessionAna.email);\n\n    }\n\n}\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el patrón de diseño \"singleton\" para representar una clase que\n * haga referencia a la sesión de usuario de una aplicación ficticia.\n * La sesión debe permitir asignar un usuario (id, username, nombre y email),\n * recuperar los datos del usuario y borrar los datos de la sesión.\n */\nclass Session {\n\n    public int id;\n    public String username;\n    public String name;\n    public String email;\n\n    public Session(int id, String username, String name, String email) {\n        this.id = id;\n        this.username = username;\n        this.name = name;\n        this.email = email;\n    \n    }\n\n}\n\nclass Singleton {\n\n    private static Session session = null;\n\n    public synchronized static Session getInstance(int id, String username, String name, String email) {\n        if (session == null) {\n            session = new Session(id, username, name, email); // instar el Singleton si no hay todavía\n        }\n        return session;\n    }\n\n    public synchronized static Session deleteInstance() {\n        if (session != null) {\n            session = null;\n        }\n\n        return session;\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/java/JimsimroDev.java",
    "content": "/*\n * EJERCICIO:\n * Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n * con un ejemplo genérico.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el patrón de diseño \"singleton\" para representar una clase que\n * haga referencia a la sesión de usuario de una aplicación ficticia.\n * La sesión debe permitir asignar un usuario (id, username, nombre y email),\n * recuperar los datos del usuario y borrar los datos de la sesión.\n */\n\npublic class JimsimroDev {\n\n  public static class ConfiguracionGlobal {\n\n    private static ConfiguracionGlobal config;\n\n    private ConfiguracionGlobal() {\n    }\n\n    public static ConfiguracionGlobal getConfig() {\n      return (config == null) ? config = new ConfiguracionGlobal() : config;\n    }\n  }\n\n  // Extra\n  public static class SesionUsuario {\n    private static SesionUsuario instancia;\n    private Long id;\n    private String username;\n    private String nombre;\n    private String email;\n\n    private SesionUsuario() {\n    }\n\n    public static SesionUsuario getInstancia() {\n      return instancia == null ? instancia = new SesionUsuario() : instancia;\n    }\n\n    public void registrarUsuario(Long id, String username, String nombre, String email) {\n      this.id = id;\n      this.username = username;\n      this.nombre = nombre;\n      this.email = email;\n    }\n\n    public String mostrarDatosUsuario() {\n      if (this.id == null) {\n        return \"No hay usuario registrado.\";\n      }\n      return String.format(\"ID: %d - Username: %s - Nombre: %s - Email: %s\", this.id, this.username, this.nombre,\n          this.email);\n    }\n\n    public void cerrarSesion() {\n      this.id = null;\n      this.username = null;\n      this.nombre = null;\n      this.email = null;\n    }\n  }\n\n  public static void main(String[] args) {\n    ConfiguracionGlobal config1 = ConfiguracionGlobal.getConfig();\n    ConfiguracionGlobal config2 = ConfiguracionGlobal.getConfig();\n    System.out.println(config1 == config2);\n\n    // Extra\n    System.out.println(\"Creando una nueva instancia de SesionUsuario...\");\n    var sesion1 = SesionUsuario.getInstancia();\n    sesion1.registrarUsuario(1L, \"jimsimro\", \"Jim Simro\", \"prueba@gmail.com\");\n\n    var sesion2 = SesionUsuario.getInstancia();\n\n    System.out.println(sesion2.mostrarDatosUsuario());\n    System.out.println(sesion1.mostrarDatosUsuario());\n\n    System.out.println(\"Creando una nueva instancia de SesionUsuario...\");\n    sesion2.registrarUsuario(2L, \"jhoans\", \"Jhoan\", \"prueba2@gmail.com\");\n    System.out.println(sesion2.mostrarDatosUsuario());\n    System.out.println(sesion1.mostrarDatosUsuario());\n\n    System.out.println(\"Creando una nueva instancia de SesionUsuario...\");\n    var sesion3 = SesionUsuario.getInstancia();\n    System.out.println(sesion3.mostrarDatosUsuario());\n    System.out.println(sesion2.mostrarDatosUsuario());\n    System.out.println(sesion1.mostrarDatosUsuario());\n\n    sesion2.cerrarSesion();\n\n    System.out.println(sesion2.mostrarDatosUsuario());\n    System.out.println(sesion1.mostrarDatosUsuario());\n  }\n}\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/java/Josegs95.java",
    "content": "public class Josegs95 {\n    public static void main(String[] args) {\n        //Ejercicio\n        Singleton s1 = Singleton.getInstance(\"1\");\n        Singleton s2 = Singleton.getInstance(\"2\");\n\n        System.out.println(\"Si tienen el mismo 'id', es la misma instancia:\");\n        System.out.println(s1.getId());\n        System.out.println(s2.getId());\n\n        //Reto\n        retoFinal();\n    }\n\n    public static void retoFinal(){\n        Session session1 = Session.getInstance();\n        session1.setUser(\"1\", \"Josegs95\", \"Jose\", \"user@mail.com\");\n\n        System.out.println(session1);\n\n        Session session2 = Session.getInstance();\n\n        System.out.println(session2);\n\n        session2.clear();\n\n        System.out.println(session1);\n    }\n\n    public static class Singleton{\n        private static Singleton instance;\n        private String id;\n\n        private Singleton(String id){\n            this.id = id;\n        }\n\n        public static Singleton getInstance(String id){\n            if (instance == null)\n                instance = new Singleton(id);\n            return instance;\n        }\n\n        public String getId(){\n            return id;\n        }\n    }\n\n    public static class Session{\n        private static Session session;\n        private String id;\n        private String username;\n        private String name;\n        private String email;\n\n        private Session() {}\n\n        public static Session getInstance(){\n            if (session == null)\n                session = new Session();\n            return session;\n        }\n\n        public void setUser(String id, String username, String name, String email){\n            this.id = id;\n            this.username = username;\n            this.name = name;\n            this.email = email;\n        }\n\n        public String getId() {\n            return id;\n        }\n\n        public String getUsername() {\n            return username;\n        }\n\n        public String getName() {\n            return name;\n        }\n\n        public String getEmail() {\n            return email;\n        }\n\n        public void clear(){\n            id = null;\n            username = null;\n            name = null;\n            email = null;\n        }\n\n        @Override\n        public String toString() {\n            return \"[\" + id + \", \" + username + \", \" + name + \", \" + email + \"]\";\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/java/asjordi.java",
    "content": "/**\n * SINGLETON es un patrón de diseño creacional que nos permite asegurarnos\n * de que una clase tenga una única instancia, a la vez que proporciona un\n * punto de acceso global a dicha instancia.\n * ¿Cómo se implementa?\n * 1. Agregar un campo estático privado a la clase para guardar la instancia Singleton.\n * 2. Declarar un método de creación estático público para obtener la instancia Singleton.\n * 3. Implementar una inicialización diferida dentro del método de estático. Debe crear un nuevo objeto\n * en su primer llamada y colocarlo dentro del campo estático. Debe devolver siempre la misma instancia.\n * 4. Declarar el constructor de la clase como privado. El método estático de la clase todavía podrá llamar al constructor.\n * 5. Modificar todos los clientes de la clase para que usen el método de creación estático, y no el constructor.\n */\npublic class Main {\n\n    public static void main(String[] args) {\n        var s1 = Singleton.getInstance(\"FOO\");\n        var s2 = Singleton.getInstance(\"BAR\");\n        System.out.println(s1.getValue());\n        System.out.println(s2.getValue());\n\n        var session = UserSession.getInstance(1, \"asjordi\", \"Jordi\", \"me@asjordi.dev\");\n        System.out.println(session.getId());\n    }\n\n    /**\n     * EJERCICIO:\n     * Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n     * con un ejemplo genérico.\n     */\n    static class Singleton {\n        private static Singleton instance;\n        private String value;\n\n        private Singleton(String value) {\n            this.value = value;\n        }\n\n        public static Singleton getInstance(String value) {\n            if (instance == null) instance = new Singleton(value);\n            return instance;\n        }\n\n        public String getValue() {\n            return value;\n        }\n\n        public void setValue(String value) {\n            this.value = value;\n        }\n    }\n\n    /**\n     * DIFICULTAD EXTRA (opcional):\n     * Utiliza el patrón de diseño \"singleton\" para representar una clase que\n     * haga referencia a la sesión de usuario de una aplicación ficticia.\n     * La sesión debe permitir asignar un usuario (id, username, nombre y email),\n     * recuperar los datos del usuario y borrar los datos de la sesión.\n     */\n    static class UserSession {\n        private static UserSession instance;\n        private Integer id;\n        private String username;\n        private String name;\n        private String email;\n\n        private UserSession(Integer id, String username, String name, String email) {\n            this.id = id;\n            this.username = username;\n            this.name = name;\n            this.email = email;\n        }\n\n        public static UserSession getInstance(Integer id, String username, String name, String email) {\n            if (instance == null) instance = new UserSession(id, username, name, email);\n            return instance;\n        }\n\n        public void deleteSession() {\n            if (instance != null) instance = null;\n        }\n\n        public void deleteUserData() {\n            if (instance != null) {\n                setId(null);\n                setUsername(null);\n                setName(null);\n                setEmail(null);\n            }\n        }\n\n        public Integer getId() {\n            return id;\n        }\n\n        public String getUsername() {\n            return username;\n        }\n\n        public String getName() {\n            return name;\n        }\n\n        public String getEmail() {\n            return email;\n        }\n\n        public void setId(Integer id) {\n            this.id = id;\n        }\n\n        public void setUsername(String username) {\n            this.username = username;\n        }\n\n        public void setName(String name) {\n            this.name = name;\n        }\n\n        public void setEmail(String email) {\n            this.email = email;\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/java/danhingar.java",
    "content": "public class danhingar {\n\n    public static void main(String[] args) {\n        // Definición de singleton como clase\n        SinglentonClass singlentonClass1 = SinglentonClass.getInstance();\n        System.out.println(singlentonClass1.hashCode());\n\n        SinglentonClass singlentonClass2 = SinglentonClass.getInstance();\n        System.out.println(singlentonClass2.hashCode());\n\n        System.out.println(singlentonClass1 == singlentonClass2);\n\n        // Definición de singleton como enumerado\n        SinglentonEnum singlentonEnum1 = SinglentonEnum.INSTANCE.getInstance();\n        System.out.println(singlentonEnum1.hashCode());\n\n        SinglentonEnum singlentonEnum2 = SinglentonEnum.INSTANCE.getInstance();\n        System.out.println(singlentonEnum2.hashCode());\n\n        System.out.println(singlentonEnum1 == singlentonEnum2);\n\n        // Extra\n        UserSession userSession1 = UserSession.getInstance();\n        userSession1.login(1, \"user1\", \"Pepe\", \"pepe@gmail.com\");\n        System.out.println(userSession1.toString());\n\n        UserSession userSession2 = UserSession.getInstance();\n        System.out.println(userSession2.toString());\n\n        UserSession userSession3 = UserSession.getInstance();\n        userSession3.logout();\n        System.out.println(userSession3.toString());\n        System.out.println(userSession2.toString());\n        System.out.println(userSession1.toString());\n\n        UserSessionEnum userSession4 = UserSessionEnum.INSTANCE.getInstance();\n        userSession4.login(2, \"user2\", \"Juan\", \"juan@gmail.com\");\n\n        System.out.println(\"Session 4\"+userSession4.toString());\n\n        UserSessionEnum userSession5 = UserSessionEnum.INSTANCE.getInstance();\n        userSession4.login(3, \"user3\", \"Mateo\", \"mateo@gmail.com\");\n        System.out.println(\"Session 4\"+userSession4.toString());\n        System.out.println(\"Session 5\"+userSession5.toString());\n\n        UserSessionEnum userSession6 = UserSessionEnum.INSTANCE.getInstance();\n        userSession6.logout();\n        System.out.println(\"Session 4\"+userSession4.toString());\n        System.out.println(\"Session 5\"+userSession5.toString());\n        System.out.println(\"Session 6\"+userSession6.toString());\n    }\n\n}\n\nclass SinglentonClass {\n\n    private static SinglentonClass INSTANCE;\n\n    private SinglentonClass() {\n\n    }\n\n    public static SinglentonClass getInstance() {\n        if (INSTANCE == null) {\n            INSTANCE = new SinglentonClass();\n        }\n\n        return INSTANCE;\n    }\n}\n\nenum SinglentonEnum {\n    INSTANCE();\n\n    public SinglentonEnum getInstance() {\n        return INSTANCE;\n    }\n\n    private SinglentonEnum() {\n    }\n\n}\n\n// EXTRA\nclass UserSession {\n    private static UserSession INSTANCE;\n    private Integer id;\n    private String username;\n    private String name;\n    private String email;\n\n    private UserSession() {\n    }\n\n    public static UserSession getInstance() {\n        if (INSTANCE == null) {\n            INSTANCE = new UserSession();\n        }\n\n        return INSTANCE;\n    }\n\n    public Integer getId() {\n        return id;\n    }\n\n    public void setId(Integer id) {\n        this.id = id;\n    }\n\n    public String getUsername() {\n        return username;\n    }\n\n    public void setUsername(String username) {\n        this.username = username;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public String getEmail() {\n        return email;\n    }\n\n    public void setEmail(String email) {\n        this.email = email;\n    }\n\n    public void login(Integer id, String username, String name, String email) {\n        this.id = id;\n        this.username = username;\n        this.name = name;\n        this.email = email;\n    }\n\n    @Override\n    public String toString() {\n        return \"Session [id=\" + id + \", username=\" + username + \", name=\" + name + \", email=\" + email + \"]\";\n    }\n\n    public void logout() {\n        this.id = null;\n        this.username = null;\n        this.name = null;\n        this.email = null;\n    }\n\n}\n\nenum UserSessionEnum {\n    INSTANCE();\n\n    private Integer id;\n    private String username;\n    private String name;\n    private String email;\n\n    public UserSessionEnum getInstance() {\n        return INSTANCE;\n    }\n\n    private UserSessionEnum() {\n    }\n\n    public Integer getId() {\n        return id;\n    }\n\n    public void setId(Integer id) {\n        this.id = id;\n    }\n\n    public String getUsername() {\n        return username;\n    }\n\n    public void setUsername(String username) {\n        this.username = username;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public String getEmail() {\n        return email;\n    }\n\n    public void setEmail(String email) {\n        this.email = email;\n    }\n\n    public String toString() {\n        return \" [id=\" + id + \", username=\" + username + \", name=\" + name + \", email=\" + email + \"]\";\n    }\n    \n    public void logout() {\n        this.id = null;\n        this.username = null;\n        this.name = null;\n        this.email = null;\n    }\n\n    public void login(Integer id, String username, String name, String email) {\n        this.id = id;\n        this.username = username;\n        this.name = name;\n        this.email = email;\n    }\n\n}"
  },
  {
    "path": "Roadmap/23 - SINGLETON/java/eulogioep.java",
    "content": "/**\n * Implementación del patrón Singleton en Java\n * Archivo: eulogioep.java\n */\npublic class eulogioep {\n    /**\n     * Ejemplo básico del patrón Singleton\n     */\n    public static class BasicSingleton {\n        // Instancia privada estática\n        private static BasicSingleton instance;\n\n        // Constructor privado\n        private BasicSingleton() {}\n\n        // Método público para obtener la instancia (synchronized para thread-safety)\n        public static synchronized BasicSingleton getInstance() {\n            if (instance == null) {\n                instance = new BasicSingleton();\n            }\n            return instance;\n        }\n    }\n\n    /**\n     * Clase para representar los datos del usuario\n     */\n    public static class User {\n        private final int id;\n        private final String username;\n        private final String name;\n        private final String email;\n\n        public User(int id, String username, String name, String email) {\n            this.id = id;\n            this.username = username;\n            this.name = name;\n            this.email = email;\n        }\n\n        // Getters\n        public int getId() { return id; }\n        public String getUsername() { return username; }\n        public String getName() { return name; }\n        public String getEmail() { return email; }\n\n        @Override\n        public String toString() {\n            return \"User{\" +\n                    \"id=\" + id +\n                    \", username='\" + username + '\\'' +\n                    \", name='\" + name + '\\'' +\n                    \", email='\" + email + '\\'' +\n                    '}';\n        }\n    }\n\n    /**\n     * Implementación del Singleton para la sesión de usuario\n     * Utiliza inicialización lazy y es thread-safe\n     */\n    public static class UserSession {\n        // Instancia volátil privada estática\n        private static volatile UserSession instance;\n        // Datos del usuario actual\n        private User currentUser;\n\n        // Constructor privado\n        private UserSession() {\n            if (instance != null) {\n                throw new RuntimeException(\"Use getInstance() method to create\");\n            }\n        }\n\n        // Método público para obtener la instancia (implementación thread-safe con double-checked locking)\n        public static UserSession getInstance() {\n            if (instance == null) {\n                synchronized (UserSession.class) {\n                    if (instance == null) {\n                        instance = new UserSession();\n                    }\n                }\n            }\n            return instance;\n        }\n\n        // Método para establecer el usuario actual\n        public void setUser(User user) {\n            if (user == null) {\n                throw new IllegalArgumentException(\"User cannot be null\");\n            }\n            this.currentUser = user;\n        }\n\n        // Método para obtener el usuario actual\n        public User getUser() {\n            return currentUser;\n        }\n\n        // Método para cerrar la sesión\n        public void logout() {\n            this.currentUser = null;\n        }\n    }\n\n    /**\n     * Método principal para demostrar el uso del patrón Singleton\n     */\n    public static void main(String[] args) {\n        try {\n            // Ejemplo básico\n            BasicSingleton singleton1 = BasicSingleton.getInstance();\n            BasicSingleton singleton2 = BasicSingleton.getInstance();\n            System.out.println(\"Singleton básico - ¿Misma instancia? \" + (singleton1 == singleton2));\n\n            // Ejemplo de sesión de usuario\n            System.out.println(\"\\nProbando sesión de usuario:\");\n            \n            // Obtener instancia de sesión\n            UserSession session = UserSession.getInstance();\n\n            // Crear y establecer usuario\n            User user = new User(1, \"john_doe\", \"John Doe\", \"john@example.com\");\n            session.setUser(user);\n            System.out.println(\"Usuario actual: \" + session.getUser());\n\n            // Obtener otra referencia a la sesión\n            UserSession anotherSession = UserSession.getInstance();\n            System.out.println(\"¿Misma sesión? \" + (session == anotherSession));\n            System.out.println(\"Usuario desde otra referencia: \" + anotherSession.getUser());\n\n            // Cerrar sesión\n            session.logout();\n            System.out.println(\"Después de logout: \" + session.getUser());\n\n            // Intentar crear una nueva instancia directamente (esto lanzará una excepción)\n            // new UserSession(); // Esto lanzaría una RuntimeException\n\n        } catch (Exception e) {\n            System.err.println(\"Error: \" + e.getMessage());\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/23 - SINGLETON/java/martinbohorquez.java",
    "content": "public class martinbohorquez {\n    public static void main(String[] args) {\n        Singleton singleton = Singleton.getInstance();\n        Singleton.message();\n        singleton.message();\n        Singleton.message();\n\n        /*\n         * DIFICULTAD EXTRA\n         */\n\n        UserSession session = UserSession.getUserInstance();\n        session.assignUser(\"1\", \"Martin Bohorquez\", \"mbohorquez\", \"mbohorquez@gmail.com\");\n        System.out.printf(\"Usuario: %s, instancia Singleton: %s%n\", session.getUserData(), session);\n        session.deleteSession();\n        System.out.printf(\"Usuario: %s, instancia Singleton: %s%n\", session.getUserData(), session);\n\n\n    }\n\n    private static class Singleton {\n        private static Singleton instance;\n\n        private Singleton() {\n        }\n\n        public static Singleton getInstance() {\n            instance = (instance == null) ? new Singleton() : instance;\n            return instance;\n        }\n\n        public static void message() {\n            System.out.printf(\"Soy un Singleton: %s%n\", instance);\n        }\n    }\n\n    private static class UserSession {\n        private static UserSession instance;\n\n        private String id;\n        private String name;\n        private String userName;\n        private String email;\n\n        private UserSession() {\n        }\n\n        public static UserSession getUserInstance() {\n            instance = (instance == null) ? new UserSession() : instance;\n            return instance;\n        }\n\n        public void assignUser(String id, String name, String userName, String email) {\n            this.id = id;\n            this.name = name;\n            this.userName = userName;\n            this.email = email;\n        }\n\n        public String getUserData() {\n            return \"{id='\" + id + \"', name='\" + name + \"', userName='\" + userName + \"', email='\" + email + \"'}\";\n        }\n\n        public void deleteSession() {\n            id = null;\n            name = null;\n            userName = null;\n            email = null;\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/java/simonguzman.java",
    "content": "\npublic class simonguzman {\n    public static void main(String[] args) {\n        genericSingleton();\n        additionalExercise();\n    }\n    /**************************** Ejercicio adicional ****************************/\n    public static void additionalExercise(){\n        UserSession session = UserSession.getUserInstance();\n        session.assignUser(\"001\", \"Simon Guzman\", \"sguzman\", \"sguzman@hotmail.com\");\n        System.out.println(session.getUserData());\n        session.deleteSession();\n        System.out.println(session.getClass());\n    }\n\n    public static class UserSession{\n        private static UserSession instance;\n\n        private String id;\n        private String name;\n        private String userName;\n        private String email;\n\n        private UserSession(){\n\n        }\n\n        public static UserSession getUserInstance(){\n            if(instance == null){\n                instance = new UserSession();\n            }\n            return instance;\n        }\n\n        public void assignUser(String id, String name, String userName, String email){\n            this.id = id;\n            this.name = name;\n            this.userName = userName;\n            this.email = email;\n        }\n\n        public String getUserData(){\n            if (id == null){\n                return \"No hay usuarios en la sesion\";\n            }\n            return \"ID: \"+id+\" ,username: \" + userName + \" ,name: \" + name + \" ,email: \" + email;\n        }\n\n        public void deleteSession(){\n            id = null;\n            name = null;\n            userName = null;\n            email = null;\n        }\n    }\n\n    /**************************** Ejemplo de singleton ****************************/\n    public static void genericSingleton(){\n        Singleton singleton = Singleton.getInstance();\n        singleton.showMessage();\n    }\n\n    public static class Singleton{\n        private static Singleton instance;\n\n        private Singleton(){\n\n        }\n\n        public static Singleton getInstance(){\n            if(instance == null){\n                instance = new Singleton();\n            }\n            return instance;\n        }\n\n        public static void showMessage(){\n            System.out.println(\"Soy un Singleton.\");\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/javascript/AChapeton.js",
    "content": "const counter = () => {\n  var instance = null;\n  var count = 0;\n  function printCount() {\n      console.log(\"Numero de instancias activas: \" + count);\n  }\n  function init() {\n      count++;\n      return {};\n  }\n  function createInstance() {\n      if (instance == null) {\n          instance = init();\n      }\n      return instance;\n  }\n  function closeInstance() {\n      count--;\n      instance = null;\n  }\n  return {\n      createInstance: createInstance,\n      closeInstance: closeInstance,\n      printCount: printCount\n  };\n}\nvar foo = counter();\nfoo.printCount();\nfoo.createInstance();\nfoo.printCount();\nfoo.createInstance();\nfoo.printCount();\nfoo.createInstance();\nfoo.printCount();\nfoo.closeInstance();\nfoo.printCount();\nfoo.createInstance();\nfoo.printCount();\nfoo.closeInstance();\nfoo.printCount();\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/javascript/Chrisdev00.js",
    "content": "/*\n* EJERCICIO:\n* Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n* con un ejemplo genérico.\n*\n* DIFICULTAD EXTRA (opcional):\n* Utiliza el patrón de diseño \"singleton\" para representar una clase que\n* haga referencia a la sesión de usuario de una aplicación ficticia.\n* La sesión debe permitir asignar un usuario (id, username, nombre y email),\n* recuperar los datos del usuario y borrar los datos de la sesión.\n*/\n\nclass Singleton{\n    constructor(){\n        if(Singleton.instance){\n            return Singleton.instance;\n        }\n        Singleton.instance = this;\n\n        this.data = \"Some data\";\n    }\n\n    getData(){\n        return this.data;\n    }\n\n    setData(data){\n        this.data = data;\n    }\n}\n\nconst instance1 = new Singleton();\nconst instance2 = new Singleton();\n\nconsole.log(instance1 === instance2);\n\ninstance1.setData(\"New Data\");\n\nconsole.log(instance2.getData());\n\n\n// Otra forma de implementar Singleton usando IIFE\n\nconst Singleton = (function() {\n    let instance;\n\n    function createInstance() {        \n        const object = new Object(\"I am the instance\");\n        return object;\n    }\n\n    return {\n        getInstance: function() {\n            if (!instance) {\n                instance = createInstance();\n            }\n            return instance;\n        }\n    };\n})();\n\nconst instance3 = Singleton.getInstance();\nconst instance4 = Singleton.getInstance();\n\nconsole.log(instance3 === instance4);\n\n\n\n///////////////// ---------------------------------- EXTRA ------------------------------ ///////////////////////\n\nclass UserSession{\n    constructor(){\n        if(UserSession.instance){\n            return UserSession.instance;\n        }\n        UserSession.instance = this;\n\n        this.data = null;\n    }\n\n    getData(){\n        return this.data;\n    }\n\n    setData(userId, username, nombre, email){\n        this.data = {\n            id: userId,\n            username: username,\n            nombre: nombre,\n            email: email\n        };\n    }\n\n    clearSession(){\n        this.data = null;\n    }\n}\n\nconst session1 = new UserSession();\nconst session2 = new UserSession();\n\nconsole.log(session1 === session2);\n\nsession1.setData(1, \"jhon00\", \"Jhon\", \"john.doe@example.com\");\n\nconsole.log(session2.getData());\n\nsession2.clearSession();\n\nconsole.log(session1.getData());"
  },
  {
    "path": "Roadmap/23 - SINGLETON/javascript/DavidMoralesDeveloper.js",
    "content": "//  * EJERCICIO:\n//  * Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n\n\n//  * con un ejemplo genérico.\nclass Sigleton {\n    constructor() {\n    \n        if(Sigleton.instance) { return Sigleton.instance} \n        this.time = Date.now() \n\n        Sigleton.instance= this\n\n        return this\n        \n    }\n\n    static getInstance () {\n       if (!Sigleton.instance) {Sigleton.instance = new Sigleton()}\n       return Sigleton.instance \n    }\n    \n\n}\n\nconst singleton1 = new Sigleton();\nconst singleton2 = new Sigleton();\nconsole.log(singleton1 === singleton2); // true\n\n// * DIFICULTAD EXTRA (opcional):\n//  * Utiliza el patrón de diseño \"singleton\" para representar una clase que\n//  * haga referencia a la sesión de usuario de una aplicación ficticia.\n//  * La sesión debe permitir asignar un usuario (id, username, nombre y email),\n//  * recuperar los datos del usuario y borrar los datos de la sesión.\n//  */\n\nclass Sesion {\n    constructor() {\n        if(Sesion.instance){\n            return Sesion.instance;\n        }\n\n        // Inicializar datos de sesión vacíos\n        this.userData = null;\n        \n        Sesion.instance = this;\n        return this;\n    }\n\n    // Asignar usuario a la sesión\n    setUser(id, username, name, email) {\n        this.userData = {\n            id: id,\n            username: username,\n            name: name,\n            email: email\n        };\n        console.log('Usuario asignado a la sesión');\n    }\n    \n    // Recuperar datos del usuario\n    getUser() {\n        if (!this.userData) {\n            console.log('No hay usuario en la sesión');\n            return null;\n        }\n        return this.userData;\n    }\n\n    // Borrar datos de la sesión\n    clearSession() {\n        this.userData = null;\n        console.log('Sesión borrada');\n    }\n\n    // Verificar si hay usuario logueado\n    isLoggedIn() {\n        return this.userData !== null;\n    }\n\n    static getInstance() {\n        if(!Sesion.instance){\n            Sesion.instance = new Sesion();\n        }\n        return Sesion.instance;\n    }\n}\n\n// Ejemplo de uso\nconst sesion1 = new Sesion();\nconst sesion2 = Sesion.getInstance();\n\n\nconsole.log(sesion1 === sesion2); // true - misma instancia\n\n// Uso de la sesión\nsesion1.setUser(1, 'juan123', 'Juan Pérez', 'juan@email.com');\nconsole.log('Datos desde sesion1:', sesion1.getUser());\nconsole.log('Datos desde sesion2:', sesion2.getUser()); // Mismo usuario\n\nconsole.log('¿Está logueado?', sesion1.isLoggedIn()); // true\n\nsesion2.clearSession();\nconsole.log('Después de borrar:', sesion1.getUser()); // null\nconsole.log('¿Está logueado?', sesion1.isLoggedIn()); // false\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/javascript/Deyvid-10.js",
    "content": "// Patron de diseno singleton\n\nclass Office\n{\n    constructor(name, employees)\n    {\n        this.name = name,\n        this.employees = employees\n\n        if(typeof Office.instance === \"object\")\n        {\n            return Office.instance\n        }\n\n        Office.instance = this\n        return this\n    }\n}\n\nlet office1 = new Office(\"Principal\", 30)\n\nlet office2 = new Office(\"Principal\", 40)\n\nconsole.log(office1);\nconsole.log(office2);\n\n\n// DIFICULTAD EXTRA\n\nclass Usuario\n{\n    constructor(id, username, name, email)\n    {\n        this.id = id\n        this.username = username\n        this.name = name\n        this.email = email\n\n\n        if(typeof Usuario.instance === \"object\")\n        {\n            return Usuario.instance\n        }\n\n        Usuario.instance = this\n        return this\n    }\n\n    getData()\n    {\n        console.log(`Identificador: ${this.id}\\nUsuario: ${this.username}\\nNombre: ${this.name}\\nEmail: ${this.email}`);\n    }\n\n    deleteData()\n    {\n        this.id = \"\"\n        this.username = \"\"\n        this.name = \"\"\n        this.email = \"\"\n    }\n}\n\nlet usuario1 = new Usuario(1, \"Daniel-10\", \"Daniel Ramirez\", \"daniel1524@gmail.com\")\n\nlet usuario2 = new Usuario(2, \"Raquel-20\", \"Raquel Herrera\", \"herrara_2596@gmail.com\")\n\nusuario1.getData()\nusuario2.getData()\n\nusuario2.deleteData()\n\nusuario1.getData()\nusuario2.getData()"
  },
  {
    "path": "Roadmap/23 - SINGLETON/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #23 - JavaScript ->Jesus Antonio Escamilla */\n\n/**\n * El patrón Singleton es uno de los patrones de diseño más utilizados en la industria del desarrollo de software.\n * Singleton es un patrón de diseño creacional que nos permite asegurarnos de que una clase tenga una única instancia, a la vez que proporciona un punto de acceso global a dicha instancia.\n * El patrón de diseño Singleton se utiliza cuando solo se necesita una instancia de una clase en toda la aplicación.\n*/\n\n//---EJERCIÓ---\n// Aquí tenemos una clase para usar el Patron de Diseño Singleton\nclass Singleton {\n    // Se usa un constructor que valida si ya fue instanciado o no\n    constructor() {\n    if (!!Singleton.instance) {\n        return Singleton.instance;\n    }\n\n    // Inicializa las propiedades de la clase aquí\n    // Las propiedades pueden cambiar\n    this.someProperty = 'someValue';\n\n    // Retornamos la instancia creada\n    // Una vez instanciada no se puede volver a instancia o crear nueva\n    Singleton.instance = this;\n    }\n\n    // Un método de la clase\n    someMethod() {\n    console.log('Hola, soy un método del Singleton y ya fue creado.');\n    }\n}\n\n// Ejemplos del Patron de Diseño Singleton\nconst conectarSingleton = new Singleton();\nconectarSingleton.someMethod();\nconsole.log(conectarSingleton.someProperty);\n\nconst desconectarSingleton = new Singleton();\ndesconectarSingleton.someMethod();\ndesconectarSingleton.someProperty = 'newSomeValue';\nconsole.log(desconectarSingleton.someProperty);\n\n// Comprobando si existe\nconsole.log(conectarSingleton === desconectarSingleton);\n\n\n/**-----DIFICULTAD EXTRA-----*/\n\n//  Creo la clase para la sesión de usuario\nclass userLogin {\n    constructor(){\n        if (!!userLogin.instance) {   // Aquí compruebo si existe la instancia\n            return userLogin.instance;\n        }\n\n        this.user = null;   // Aun no se agrega nada entonces los dejo vació\n        userLogin.instance = this;  // Instanciando la clase si tiene datos\n\n        return this;\n    }\n\n    //  Guardo los datos este método\n    setUser(id, username, name, email){\n        this.user = { id, username, name, email }\n    }\n\n    //  Este método retorno los que se guardo\n    getUser(){\n        return this.user;\n    }\n\n    //  Limpio todo de la instancia\n    clearUser(){\n        this.user = null;\n    }\n}\n\n//  Ejemplo de las instancia de sesión de usuario\n//  Creo la instancia por primera vez\nsession1 = new userLogin();\nsession1.setUser(1,\"JesusA\", \"Jesus Antonio\", \"jesus@hola.com\");\nconsole.log(session1.getUser());\n\n//  Se vuelve a crear la instancia pero ya existe\nsession2 = new userLogin();\nconsole.log(session2.getUser());\n\n//  Limpiando la instancia\nsession3 = new userLogin();\nsession3.clearUser();\n\n\n/**-----DIFICULTAD EXTRA-----*/"
  },
  {
    "path": "Roadmap/23 - SINGLETON/javascript/RaulDoezon.js",
    "content": "/*\n  EJERCICIO:\n  Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n  con un ejemplo genérico.\n*/\n\nconsole.log(\"+++++++++ EJEMPLO DE SINGLETON +++++++++\");\n\nclass Singleton {\n  constructor(name, age) {\n    this.name = name;\n    this.age = age;\n\n    if (typeof Singleton.instance === \"object\") {\n      return Singleton.instance;\n    }\n\n    Singleton.instance = this;\n    return this;\n  }\n}\n\nconst singleton1 = new Singleton(\"Raúl\", 32);\nconst singleton2 = new Singleton(\"Armando\", 33);\n\nconsole.log(singleton1);\nconsole.log(singleton2);\n\n/*\n  DIFICULTAD EXTRA (opcional):\n  Utiliza el patrón de diseño \"singleton\" para representar una clase que\n  haga referencia a la sesión de usuario de una aplicación ficticia.\n  La sesión debe permitir asignar un usuario (id, username, nombre y email),\n  recuperar los datos del usuario y borrar los datos de la sesión.\n*/\n\nconsole.log(\"\\n+++++++++ SESIÓN DE USUARIO +++++++++\");\n\nclass UserSession {\n  constructor(id, username, name, email) {\n    this.data = {\n      id: id,\n      username: username,\n      name: name,\n      email: email,\n    }\n\n    if (UserSession.instance) {\n      return UserSession.instance;\n    }\n\n    UserSession.instance = this;\n\n    return this;\n  }\n\n  getsessionData() {\n    if (this.data === undefined) {\n      return `Los datos de la sesión fueron eliminados: ${this.data}`;\n    }\n\n    const userData = `- ID: ${this.data.id}\\n- Usuario: ${this.data.username}\\n- Nombre: ${this.data.name}\\n- Correo electrónico: ${this.data.email}`\n\n    return userData;\n  }\n\n  deleteSessionData() {\n    delete this.data;\n  }\n}\n\nconst session1 = new UserSession(310392, \"RaulDoezon\", \"Raúl\", \"raul@mail.mx\");\nconst session2 = new UserSession(920331, \"Armando\", \"Armando\", \"armando@mail.mx\");\n\nconsole.log(session1.getsessionData());\nconsole.log(session2.getsessionData());\n\nsession1.deleteSessionData();\n\nconsole.log(session1.getsessionData());\nconsole.log(session2.getsessionData());\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/javascript/RicJDev.js",
    "content": "//EJERCICIO\nclass OverkillerCharacter {\n\tconstructor(name) {\n\t\tthis.name = name;\n\n\t\tif (typeof OverkillerCharacter.instance === 'object') {\n\t\t\treturn OverkillerCharacter.instance;\n\t\t}\n\n\t\tOverkillerCharacter.instance = this;\n\t\treturn this;\n\t}\n}\n\nlet villain = new OverkillerCharacter('Jeff');\nconsole.log(villain.name);\n\nlet anotherVillain = new OverkillerCharacter('Henry');\nconsole.log(anotherVillain.name);\n\n//EXTRA\nclass UserSession {\n\tapp = 'Ric-JS-Sandbox';\n\n\tuser = null;\n\n\tconstructor() {\n\t\tif (typeof UserSession.instance === 'object') {\n\t\t\treturn UserSession.instance;\n\t\t}\n\n\t\tUserSession.instance = this;\n\t\treturn this;\n\t}\n\n\tinit(name, username, userID, email) {\n\t\tif (this.user === null) {\n\t\t\tthis.user = {\n\t\t\t\tname: name,\n\t\t\t\tusername: username,\n\t\t\t\tuserID: userID,\n\t\t\t\temail: email,\n\t\t\t};\n\n\t\t\treturn this.user;\n\t\t}\n\t}\n\n\tgetData() {\n\t\tconsole.table(this.user);\n\t}\n\n\tclose() {\n\t\tthis.user = null;\n\t}\n}\n\nconsole.log('\\nIniciamos la sesión, pero no se ha ingresado ningún usuario');\nlet session = new UserSession();\nconsole.log(session);\nsession.getData();\n\nconsole.log('\\nIngresamos un usuario y mostramos sus datos');\nsession.init('Fred', 'CrazyFred4564', 7880003, 'crazyfred@gmail.com');\nconsole.log(session);\nsession.getData();\n\nconsole.log('\\nCerramos la instancia del usuario');\nsession.close();\nconsole.log(session);\nsession.getData();\n\nconsole.log(\n\t'\\nIngresamos a otro usuario. Como ya existe un instancia de este no es posible ingresar uno nuevo, a menos que se cierre la instancia'\n);\nsession.init('Fred', 'CrazyFred4564', 7880003, 'crazyfred@gmail.com');\nsession.getData();\n\nsession.init('Sarah', 'SunshineSarah2435', 6550099, 'sarahmilanesa@gmail.com');\nsession.getData();\n\nconsole.log('\\nY eso hacemos acá');\nsession.close();\nconsole.log(session);\nsession.getData();\n\nsession.init('Sarah', 'SunshineSarah2435', 6550099, 'sarahmilanesa@gmail.com');\nsession.getData();\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/javascript/Sac-Corts.js",
    "content": "class Singleton {\n    constructor() {\n        if (Singleton.instance) {\n            return Singleton.instance;\n        }\n        this.data = \"Singleton instance data\";\n        Singleton.instance = this;\n        return this;\n    }\n\n    getData() {\n        return this.data;\n    }\n\n    static getInstance() {\n        if(!Singleton.instance) {\n            Singleton.instance = new Singleton();\n        }\n        return Singleton.instance;\n    }\n}\n\nconst instance1 = Singleton.getInstance();\nconsole.log(instance1.getData());\n\nconst instance2 = new Singleton();\nconsole.log(instance1 === instance2);\n\n// Extra Exercise //\n\nclass UserSession {\n    constructor() {\n        if (UserSession.instance) {\n            return UserSession.instance;\n        }\n        this.user = null;\n        UserSession.instance = this;\n        return this;\n    }\n\n    static getInstance() {\n        if (!UserSession.instance) {\n            UserSession.instance = new UserSession();\n        }\n        return UserSession.instance;\n    }\n\n    setUser(id, username, name, email) {\n        this.user = { id, username, name, email };\n    }\n    \n    getUser() {\n        if (!this.user) {\n            return \"There is no user in the session\"\n        }\n        return this.user;\n    }\n\n    clearSession() {\n        this.user = null;\n    }\n}\n\nconst session1 = UserSession.getInstance();\nsession1.setUser(1, \"Sac\", \"Isaac\", \"isaac@gmail.com\");\nconsole.log(session1.getUser());\n\nconst session2 = UserSession.getInstance();\nconsole.log(session1 === session2);\n\nsession2.clearSession();\nconsole.log(session1.getUser());\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/javascript/adrs1166ma.js",
    "content": "// 🔥 EJERCICIO:\n// Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n// con un ejemplo genérico.\n\nclass Configuracion {\n    constructor() {\n        // Verifica si ya existe una instancia\n        if (Configuracion.instancia) {\n            return Configuracion.instancia\n        }\n        // Si no existe, crea la instancia\n        this.config = {}\n        Configuracion.instancia = this\n    }\n\n    // Método para establecer configuraciones\n    setConfig(key, value) {\n        this.config[key] = value\n    }\n\n    // Método para obtener configuraciones\n    getConfig(key) {\n        return this.config[key]\n    }\n\n    // Método para mostrar todas las configuraciones\n    mostrarConfiguraciones() {\n        console.log(this.config)\n    }\n}\n\n// Crear una instancia de Configuracion\nconst config1 = new Configuracion()\nconfig1.setConfig(\"tema\", \"oscuro\")\nconfig1.setConfig(\"idioma\", \"es\")\n\n// Intentar crear otra instancia\nconst config2 = new Configuracion()\n\n// Ambas variables apuntan a la misma instancia\nconsole.log(config1 === config2) // true\nconfig2.mostrarConfiguraciones() // { tema: 'oscuro', idioma: 'es' }\n\n// 🔥 DIFICULTAD EXTRA (opcional): ----------------------------------------------------------------------------------\n// Utiliza el patrón de diseño \"singleton\" para representar una clase que\n// haga referencia a la sesión de usuario de una aplicación ficticia.\n// La sesión debe permitir asignar un usuario (id, username, nombre y email),\n// recuperar los datos del usuario y borrar los datos de la sesión.\n\n// Clase SesionUsuario siguiendo el patrón Singleton\nclass SesionUsuario {\n    constructor() {\n        // Verifica si ya existe una instancia\n        if (SesionUsuario.instancia) {\n            return SesionUsuario.instancia\n        }\n        // Si no existe, crea la instancia\n        this.usuario = null\n        SesionUsuario.instancia = this\n    }\n\n    // Método para iniciar sesión\n    iniciarSesion(id, username, nombre, email) {\n        this.usuario = { id, username, nombre, email }\n        console.log(`Sesión iniciada para el usuario: ${username}`)\n    }\n\n    // Método para recuperar los datos del usuario\n    obtenerDatosUsuario() {\n        if (this.usuario) {\n            console.log(\"Datos del usuario:\", this.usuario)\n        } else {\n            console.log(\"No hay sesión activa.\")\n        }\n    }\n\n    // Método para cerrar sesión\n    cerrarSesion() {\n        this.usuario = null\n        console.log(\"Sesión cerrada.\")\n    }\n}\n\n// Crear una instancia de SesionUsuario\nconst sesion1 = new SesionUsuario()\nsesion1.iniciarSesion(1, \"juan123\", \"Juan Pérez\", \"juan@example.com\")\nsesion1.obtenerDatosUsuario()\n\n// Intentar crear otra instancia\nconst sesion2 = new SesionUsuario()\nsesion2.obtenerDatosUsuario() // Muestra los mismos datos que sesion1\n\n// Cerrar sesión desde sesion2\nsesion2.cerrarSesion()\nsesion1.obtenerDatosUsuario() // No hay sesión activa"
  },
  {
    "path": "Roadmap/23 - SINGLETON/javascript/agusrosero.js",
    "content": "/*\n * EJERCICIO:\n * Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n * con un ejemplo genérico.\n */\nclass Office {\n  constructor(name, employees) {\n    this.name = name;\n    this.employees = employees;\n    if (typeof Office.instance === \"object\") {\n      return Office.instance;\n    }\n    Office.instance = this;\n    return this;\n  }\n}\n\nconst office1 = new Office(\"Principal\", 30);\nconsole.log(office1)\n/* DIFICULTAD EXTRA (opcional):\n * Utiliza el patrón de diseño \"singleton\" para representar una clase que\n * haga referencia a la sesión de usuario de una aplicación ficticia.\n * La sesión debe permitir asignar un usuario (id, username, nombre y email),\n * recuperar los datos del usuario y borrar los datos de la sesión.\n */\n\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/javascript/bernatcs.js",
    "content": "// ** EJERCICIO\n\nclass Singleton {\n    constructor() {\n        if (Singleton.instance) {\n            return Singleton.instance;\n        }\n        this.data = \"Información del Singleton\"; // Propiedades de la instancia\n        Singleton.instance = this; // Guardar la instancia\n        Object.freeze(this); // Congelar la instancia para evitar modificaciones\n    }\n}\n\nconst instance = new Singleton();\nconst instance2 = new Singleton()"
  },
  {
    "path": "Roadmap/23 - SINGLETON/javascript/brahiams7.js",
    "content": "// * EJERCICIO:\n//  * Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n//  * con un ejemplo genérico.\nclass singleton{\n    constructor(){\n        if(!singleton.instance){\n            this.valor=\"Soy la unica instancia\"\n            singleton.instance=this\n        }\n        return singleton.instance\n    }\n    obtenerValor(){\n        return this.valor\n    }\n}\n\nconst instancia1=new singleton()\nconst instancia2=new singleton()\n\nconsole.log(instancia1===instancia2);\nconsole.log(instancia1.obtenerValor());\n\nclass Usuario{\n    constructor(id,username,nombre,email){\n        if(!Usuario.instance){\n            this.id=id\n            this.username=username\n            this.nombre=nombre\n            this.email=email\n            Usuario.instance=this\n        }\n        return Usuario.instance\n    }\n    mostrarUsuario(){\n        return this.id\n            ? { id: this.id, username: this.username, nombre: this.nombre, email: this.email }\n            : \"Error: Instancia no definida\";\n    }\n    resetInstance(){\n        Usuario.instance=null\n        this.id=null\n        this.username=null\n        this.nombre=null\n        this.email=null\n        return console.log(('Instancia borrada'));\n        \n    }\n}\nlet usuario1=new Usuario(1,\"Andreskratos\",\"felipe\",\"felipe@gmail\")\n\nconsole.log(`El id del usuario es: ${usuario1.mostrarUsuario().id}\\n el username del usuario es: ${usuario1.mostrarUsuario().username}\\n el nombre del usuario es: ${usuario1.mostrarUsuario().nombre}\\n el email del usuario es: ${usuario1.mostrarUsuario().email}`);\nconsole.log(usuario1.mostrarUsuario());\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/javascript/caterinarodriguezdev.js",
    "content": "/*\n * EJERCICIO:\n * Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n * con un ejemplo genérico.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el patrón de diseño \"singleton\" para representar una clase que\n * haga referencia a la sesión de usuario de una aplicación ficticia.\n * La sesión debe permitir asignar un usuario (id, username, nombre y email),\n * recuperar los datos del usuario y borrar los datos de la sesión.\n */\n\nclass Dni {\n  constructor(nombre, apellido) {\n    this.nombre = nombre;\n    this.apellido = apellido;\n\n    if (typeof Dni.instance === \"object\") {\n      return Dni.instance;\n    }\n\n    Dni.instance = this;\n    return this;\n  }\n\n  getDni() {\n    console.log(`Nombre: ${this.nombre}\\nApellido: ${this.apellido}`);\n  }\n}\n\nconst dni01 = new Dni(\"caterina\", \"rodriguez\");\nconst dni02 = new Dni(\"loki\", \"rodriguez\");\n\ndni02.getDni();\n\nconsole.log(\"------------------DIFICULTAD EXTRA-----------------\");\n\nclass Sesion {\n  constructor(id, username, nombre, email) {\n    this.id = id;\n    this.username = username;\n    this.nombre = nombre;\n    this.email = email;\n\n    if (typeof Sesion.instance === \"object\") {\n      return Sesion.instance;\n    }\n\n    Sesion.instance = this;\n    return this;\n  }\n\n  getDatos() {\n    console.log(\n      `El usuario ${this.username} con id ${this.id} se llama ${this.nombre} y su email es ${this.email}`\n    );\n  }\n\n  borrarDatos() {\n    this.id = \"\";\n    this.username = \"\";\n    this.nombre = \"\";\n    this.email = \"\";\n  }\n}\n\nconst s1 = new Sesion(\"001\", \"gracedurum\", \"grace\", \"grace@grace.com\");\ns1.getDatos();\ns1.borrarDatos();\ns1.getDatos();\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/javascript/duendeintemporal.js",
    "content": "//#23 - PATRONES DE DISEÑO: SINGLETON\n/*\n * EJERCICIO:\n * Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n * con un ejemplo genérico.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el patrón de diseño \"singleton\" para representar una clase que\n * haga referencia a la sesión de usuario de una aplicación ficticia.\n * La sesión debe permitir asignar un usuario (id, username, nombre y email),\n * recuperar los datos del usuario y borrar los datos de la sesión.\n */\n\nlet log = console.log;\n\nwindow.addEventListener('load', ()=>{\n    const body = document.querySelector('body');\n    const title = document.createElement('h1');\n    \n    body.style.setProperty('background', '#000');\n    body.style.setProperty('text-align', 'center');\n    \n    title.textContent = 'Retosparaprogramadores #23.';\n    title.style.setProperty('font-size', '3.5vmax');\n    title.style.setProperty('color', '#fff');\n    title.style.setProperty('line-height', '100vh');\n    \n    body.appendChild(title);\n    \n    setTimeout(()=>{\n    alert('Retosparaprogramadores #23. Please open the Browser Developer Tools.');\n    }, 2000);\n    log( 'Retosparaprogramadores #23'); \n});\n\n\n/* \nThe Singleton design pattern ensures that a class has a single instance and provides a global point of access to that instance. Below, I will show you how to implement the Singleton pattern in JavaScript, followed by an example that represents a class for managing user sessions.\n\n                      Implementation of the Singleton Pattern\n */\n \nclass Singleton{    \n    constructor() {\n        if (Singleton.instance) {\n            return Singleton.instance;\n        }\n        Singleton.instance = this;\n        // Initialize any properties you need here\n    }\n\n    // Example method\n    someMethod() {\n        log(\"This is a method of the singleton.\");\n    }\n}\n\n// Using the Singleton\nconst instance1 = new Singleton();\nconst instance2 = new Singleton();\n\n//Note: both variables point to the same instance\nlog(instance1 === instance2); // true  \n\n//EXTRA DIFICULTY EXERCISE\n\nclass UserSession {\n    constructor() {\n        if (UserSession.instance) {\n            return UserSession.instance;\n        }\n        UserSession.instance = this;\n        this.user = null; \n    }\n\n    setUser(id, username, name, email) {\n        this.user = { id, username, name, email };\n    }\n\n    getUser() {\n        return this.user;\n    }\n\n    clearSession() {\n        this.user = null;\n    }\n}\n\nconst session1 = new UserSession();\nsession1.setUser(1, 'FritzCat', 'Fritz Cat', 'fritzcat@proton.me');\n\nlog(session1.getUser()); // Object { id: 1, username: \"FritzCat\", name: \"Fritz Cat\", email: \"fritzcat@proton.me\" }\n\nconst session2 = new UserSession();\nlog(session2.getUser()); // Object { id: 1, username: \"FritzCat\", name: \"Fritz Cat\", email: \"fritzcat@proton.me\" }\n\nsession2.clearSession();\nlog(session1.getUser()); // null\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/javascript/edalmava.js",
    "content": "let contador = 0\nlet instancia\n\nclass Contador { \n    constructor() {\n      if (instancia) {\n        throw new Error('Solo se puede crear una sola instancia')\n      }\n\n      instancia = this\n    }\n\n    getInstancia() {\n      return this\n    }\n\n    getContador() {\n      return contador\n    }\n\n    incrementar() {\n      return ++contador\n    }\n\n    decrementar() {\n      return --contador\n    }\n}\n\nconst estado = Object.freeze(new Contador())\n//const estado2 = new Contador() // Error: Solo se puede crear una sola instancia\n\nestado.incrementar()  \nestado.incrementar()\nestado.incrementar()\nestado.decrementar()\nconsole.log(`Valor de contador: ${estado.getContador()}`)\n\n// RETO EXTRA\n\nlet instanciaSesion = null\n\nclass Sesion {\n  constructor(id, username, nombre, email) {\n    if (instanciaSesion) {\n      throw new Error('Solo se puede crear una sola instancia')\n    }\n  \n    instanciaSesion = this\n    this.id = id\n    this.username = username\n    this.nombre = nombre\n    this.email = email\n  }\n\n  getSesion() {\n    return instanciaSesion\n           ?({ id: this.id, username: this.username, nombre: this.nombre, email: this.email })\n           :null\n  }\n\n  delSesion() {\n    instanciaSesion = null    \n  }\n}\n\nconst usuario = Object.freeze(new Sesion('1090', 'edalmava', 'Edwin Martinez', 'eamartinezv@gmail.com'))\nconsole.log(JSON.stringify(usuario.getSesion()))\nusuario.delSesion()\nconsole.log(usuario.getSesion())\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/javascript/eugeniasoria.js",
    "content": "\r\n/*\r\n * EJERCICIO:\r\n * Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\r\n * con un ejemplo genérico.\r\n */\r\n\r\n\r\nclass SingletonExample {\r\n  constructor(nombre) {\r\n    this.nombre = nombre;\r\n    if (SingletonExample._instance) {\r\n      return SingletonExample._instance;\r\n    }\r\n    SingletonExample._instance = this;\r\n   \r\n  }\r\n}\r\n\r\nvar instanceOne = new SingletonExample('instanceOne') // Se ejecuta exitosamente\r\nconsole.log(\"Nombre: instanceOne\", instanceOne);\r\n\r\nvar instanceTwo = new SingletonExample('instanceTwo') // Arroja error\r\nconsole.log(\"Nombre instanceTwo\", instanceTwo);\r\n\r\nconsole.log(\"instanceOne === instanceTwo:\" , instanceOne === instanceTwo);\r\n\r\n\r\n/* DIFICULTAD EXTRA (opcional):\r\n* Utiliza el patrón de diseño \"singleton\" para representar una clase que\r\n* haga referencia a la sesión de usuario de una aplicación ficticia.\r\n* La sesión debe permitir asignar un usuario (id, username, nombre y email),\r\n* recuperar los datos del usuario y borrar los datos de la sesión.\r\n*/\r\n\r\nclass SesionUsuario {\r\n  constructor(id, username, name, email) {\r\n    this.id = id;\r\n    this.username = username;\r\n    this.name = name;\r\n    this.email = email;\r\n    if (SesionUsuario._instance) {\r\n      return SesionUsuario._instance;\r\n    }\r\n    SesionUsuario._instance = this;   \r\n  }\r\n\r\n  recuperarUsuario() {\r\n    return `Id: ${this.Id}  UserName: ${this.username}  Name: ${this.name} email: ${this.email} `\r\n  }\r\n\r\n  borrarSesion() {\r\n    this.id = null;\r\n    this.username = null;\r\n    this.name = null;\r\n    this.email = null;\r\n  }\r\n\r\n}\r\n\r\nvar miUsuario = new SesionUsuario(1, 'userX', 'Manolo', \"manolito@gmail.com\");\r\nconsole.log(\">>Con datos: 1, userX, Manolo, manolito@gmail.com\");\r\nconsole.log(miUsuario.recuperarUsuario());\r\n\r\nvar miOtroUsuario = new SesionUsuario(5, 'userB', 'Ramira', \"rrocha@gmail.com\");\r\nconsole.log(\">>Con datos: 5, userB, Ramira, rrocha@gmail.com\");\r\nconsole.log(miOtroUsuario.recuperarUsuario());\r\n\r\nconsole.log(\"miUsuario === miOtroUsuario: \", miUsuario === miOtroUsuario);\r\n\r\nmiUsuario.borrarSesion();\r\nconsole.log(\">>Luego de borrar usuario:\");\r\nconsole.log(miUsuario.recuperarUsuario());\r\n\r\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/javascript/eulogioep.js",
    "content": "/**\n * EJEMPLO BÁSICO DEL PATRÓN SINGLETON\n * ==================================\n * Implementación del patrón Singleton usando una clase ES6\n */\n\n// Implementación básica usando clase ES6\nclass BasicSingleton {\n    constructor() {\n        // Verificar si ya existe una instancia\n        if (BasicSingleton.instance) {\n            return BasicSingleton.instance;\n        }\n        // Si no existe, guardar la instancia en la propiedad estática\n        BasicSingleton.instance = this;\n    }\n\n    // Método estático para obtener la instancia\n    static getInstance() {\n        if (!BasicSingleton.instance) {\n            BasicSingleton.instance = new BasicSingleton();\n        }\n        return BasicSingleton.instance;\n    }\n}\n\n// Congelar el objeto para prevenir modificaciones\nObject.freeze(BasicSingleton);\n\n/**\n * EJERCICIO EXTRA: SINGLETON PARA SESIÓN DE USUARIO\n * ==============================================\n * Implementación de una clase de sesión de usuario usando el patrón Singleton\n * Se incluyen dos implementaciones: una usando clase ES6 y otra usando módulo\n */\n\n// Implementación 1: Usando Clase ES6\nclass UserSession {\n    constructor() {\n        if (UserSession.instance) {\n            return UserSession.instance;\n        }\n\n        // Inicializar propiedades privadas\n        this._userData = null;\n        UserSession.instance = this;\n    }\n\n    // Método estático para obtener la instancia\n    static getInstance() {\n        if (!UserSession.instance) {\n            UserSession.instance = new UserSession();\n        }\n        return UserSession.instance;\n    }\n\n    // Método para establecer los datos del usuario\n    setUser(user) {\n        // Validar que el objeto tenga todas las propiedades requeridas\n        const requiredFields = ['id', 'username', 'name', 'email'];\n        const missingFields = requiredFields.filter(field => !(field in user));\n        \n        if (missingFields.length > 0) {\n            throw new Error(`Campos requeridos faltantes: ${missingFields.join(', ')}`);\n        }\n\n        this._userData = { ...user };\n    }\n\n    // Método para obtener los datos del usuario\n    getUser() {\n        return this._userData ? { ...this._userData } : null;\n    }\n\n    // Método para cerrar la sesión\n    logout() {\n        this._userData = null;\n    }\n}\n\n// Congelar el objeto para prevenir modificaciones\nObject.freeze(UserSession);\n\n// Implementación 2: Usando Módulo (IIFE)\nconst UserSessionModule = (function() {\n    let instance;\n    let userData = null;\n\n    // Constructor privado\n    function createInstance() {\n        return {\n            setUser(user) {\n                const requiredFields = ['id', 'username', 'name', 'email'];\n                const missingFields = requiredFields.filter(field => !(field in user));\n                \n                if (missingFields.length > 0) {\n                    throw new Error(`Campos requeridos faltantes: ${missingFields.join(', ')}`);\n                }\n\n                userData = { ...user };\n            },\n\n            getUser() {\n                return userData ? { ...userData } : null;\n            },\n\n            logout() {\n                userData = null;\n            }\n        };\n    }\n\n    return {\n        getInstance: function() {\n            if (!instance) {\n                instance = createInstance();\n            }\n            return instance;\n        }\n    };\n})();\n\n// Ejemplo de uso:\n// =============\n\n// Ejemplo básico\ntry {\n    // Probar el singleton básico\n    const singleton1 = BasicSingleton.getInstance();\n    const singleton2 = BasicSingleton.getInstance();\n    console.log('¿Son la misma instancia?:', singleton1 === singleton2); // true\n\n    // Probar la sesión de usuario (Implementación con clase)\n    console.log('\\nProbando implementación con clase:');\n    const session = UserSession.getInstance();\n\n    const user = {\n        id: 1,\n        username: 'john_doe',\n        name: 'John Doe',\n        email: 'john@example.com'\n    };\n\n    session.setUser(user);\n    console.log('Usuario actual:', session.getUser());\n\n    const anotherSessionReference = UserSession.getInstance();\n    console.log('¿Misma sesión?:', session === anotherSessionReference); // true\n    console.log('Usuario desde otra referencia:', anotherSessionReference.getUser());\n\n    session.logout();\n    console.log('Después de logout:', session.getUser()); // null\n\n    // Probar la sesión de usuario (Implementación con módulo)\n    console.log('\\nProbando implementación con módulo:');\n    const sessionModule = UserSessionModule.getInstance();\n    sessionModule.setUser(user);\n    console.log('Usuario actual:', sessionModule.getUser());\n\n    const anotherModuleReference = UserSessionModule.getInstance();\n    console.log('¿Misma sesión?:', sessionModule === anotherModuleReference); // true\n    \n    sessionModule.logout();\n    console.log('Después de logout:', sessionModule.getUser()); // null\n\n} catch (error) {\n    console.error('Error:', error.message);\n}"
  },
  {
    "path": "Roadmap/23 - SINGLETON/javascript/hectorio23.js",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\n/*\n- EJERCICIO:\nExplora el patrón de diseño \"singleton\" y muestra cómo crearlo\ncon un ejemplo genérico.\n\n- DIFICULTAD EXTRA (opcional):\nUtiliza el patrón de diseño \"singleton\" para representar una clase que\nhaga referencia a la sesión de usuario de una aplicación ficticia.\nLa sesión debe permitir asignar un usuario (id, username, nombre y email),\nrecuperar los datos del usuario y borrar los datos de la sesión.\n*/\n\n/////////////////////////////////////////////////\n/////////////////// EJERCICIO 1 /////////////////\n/////////////////////////////////////////////////\n\nclass NotDuplicity {\n    constructor() {\n        if (NotDuplicity.instance) {\n            return NotDuplicity.instance;\n        }\n        NotDuplicity.instance = this;\n        return this;\n    }\n}\n\nconst obj1 = new NotDuplicity();\nconst obj2 = new NotDuplicity();\n\nconsole.log(`ID Objeto 1 => ${obj1}`);\nconsole.log(`ID Objeto 2 => ${obj2}`);\nconsole.log(`¿Los objetos 1 y 2 son iguales? ${obj1 === obj2}`);\n\nconsole.log(\"\\n********************************\\n\");\n\n/////////////////////////////////////////////////\n///////////////// EJERCICIO EXTRA ///////////////\n/////////////////////////////////////////////////\n\nclass UserSession {\n    constructor() {\n        if (UserSession.instance) {\n            return UserSession.instance;\n        }\n        UserSession.instance = this;\n        this._user_data = null;\n        return this;\n    }\n\n    setUser(userId, username, name, email) {\n        this._user_data = {\n            id: userId,\n            username: username,\n            name: name,\n            email: email\n        };\n    }\n\n    getUser() {\n        return this._user_data;\n    }\n\n    clearUser() {\n        this._user_data = null;\n    }\n}\n\n// Ejemplo de uso:\nconst session = new UserSession();\nsession.setUser(1, 'hectorio23', 'Adán', 'adan_example@example.com');\n\n// Muestra los datos del usuario\nconsole.log(session.getUser()); \n\nsession.clearUser();\n\n// Muestra null, ya que los datos han sido borrados\nconsole.log(session.getUser()); \n\n// Verificación de singleton:\nconst anotherSession = new UserSession();\n\n// True, ambas variables apuntan a la misma instancia\nconsole.log(session === anotherSession); "
  },
  {
    "path": "Roadmap/23 - SINGLETON/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n_______________________________________\n#23 PATRONES DE DISEÑO: SINGLETON\n---------------------------------------\n* EJERCICIO:\n * Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n * con un ejemplo genérico.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el patrón de diseño \"singleton\" para representar una clase que\n * haga referencia a la sesión de usuario de una aplicación ficticia.\n * La sesión debe permitir asignar un usuario (id, username, nombre y email),\n * recuperar los datos del usuario y borrar los datos de la sesión.\n*/\n// ________________________________________________________\n\nclass Singleton {\n    constructor() {\n        if (Singleton.instance) {\n            return Singleton.instance;\n        }\n        Singleton.instance = this;\n    }\n}\n\nconst singleton1 = new Singleton();\nconst singleton2 = new Singleton();\n\nconsole.log(singleton1 === singleton2); // true\n\n// ________________________________________________________\nconsole.log(\"\\nDIFICULTAD EXTRA\\n\");\n\nclass UserSession {\n    constructor() {\n        if (UserSession.instance) {\n            return UserSession.instance;\n        }\n        this.user = null;\n        UserSession.instance = this;\n    }\n\n    setUser(userId, username, name, email) {\n        this.user = {\n            id: userId,\n            username,\n            name,\n            email,\n        };\n    }\n\n    getUser() {\n        return this.user;\n    }\n\n    logout() {\n        this.user = null;\n    }\n}\n\nconst session1 = new UserSession();\nsession1.setUser(1, \"Zoe_1\", \"Zoe\", \"Zoe@gm.com\");\nconsole.log(session1.getUser());\nsession1.logout();\n\nconst session2 = new UserSession();\nsession2.setUser(2, \"Ben_1\", \"Ben\", \"Ben@gm.com\");\nconsole.log(session2.getUser());\nsession2.logout();\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/javascript/nlarrea.js",
    "content": "/*\n * EJERCICIO:\n * Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n * con un ejemplo genérico.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el patrón de diseño \"singleton\" para representar una clase que\n * haga referencia a la sesión de usuario de una aplicación ficticia.\n * La sesión debe permitir asignar un usuario (id, username, nombre y email),\n * recuperar los datos del usuario y borrar los datos de la sesión.\n */\n\nclass Singleton {\n    constructor() {\n        if (Singleton.instance) {\n            return Singleton.instance;\n        }\n\n        Singleton.instance = this;\n        return this;\n    }\n}\n\n\nconst singleton1 = new Singleton();\nconsole.log(singleton1);\n\nconst singleton2 = new Singleton();\nconsole.log(singleton2);\n\nconsole.log(singleton1 === singleton2);  // true\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el patrón de diseño \"singleton\" para representar una clase que\n * haga referencia a la sesión de usuario de una aplicación ficticia.\n * La sesión debe permitir asignar un usuario (id, username, nombre y email),\n * recuperar los datos del usuario y borrar los datos de la sesión.\n */\n\nclass UserSession {\n    id = undefined\n    username = undefined\n    name = undefined\n    email = undefined\n\n    constructor() {\n        if (UserSession.instance) {\n            return UserSession.instance;\n        }\n\n        UserSession.instance = this;\n        return this;\n    }\n\n    setUser(id, username, name, email) {\n        this.id = id;\n        this.username = username;\n        this.name = name;\n        this.email = email;\n    }\n\n    getUser() {\n        return `${this.id}, ${this.username}, ${this.name}, ${this.email}`;\n    }\n\n    removeData() {\n        this.id = undefined;\n        this.username = undefined;\n        this.name = undefined;\n        this.email = undefined;\n    }\n}\n\n\nconst session1 = new UserSession();\nconsole.log(session1.getUser());\n// undefined, undefined, undefined, undefined\nsession1.setUser(1, 'nlarrea', 'Naia', 'naia@gmail.com');\nconsole.log(session1.getUser());\n// 1, nlarrea, Naia, naia@gmail.com\n\nconst session2 = new UserSession();\nconsole.log(session2.getUser());\n// 1, nlarrea, Naia, naia@gmail.com\n\nconst session3 = new UserSession();\nsession3.removeData();\nconsole.log(session3.getUser());\n// undefined, undefined, undefined, undefined\nconsole.log(session1.getUser());\n// undefined, undefined, undefined, undefined"
  },
  {
    "path": "Roadmap/23 - SINGLETON/javascript/parababire.js",
    "content": "// Ejercicio\n\n/* Patrón de diseño singleton */\n\nclass Person {\n  constructor(name, age) {\n    if (typeof Person.instance === 'object') { /* Si la clase Person existe se devuelve la instancia creada */\n      return Person.instance;\n    } \n    /* Caso contrario se establecen las propiedades */\n    this.name = name;\n    this.age = age;\n\n    Person.instance = this;\n    return this;\n  }\n}\n\nlet person1 = new Person('José', 44);/* El objeto creado solo tendrá una instancia */\nlet person2 = new Person('María', 30);\nconsole.log(person1); // Person { name: 'José', age: 44 }\nconsole.log(person2); // Person { name: 'José', age: 44 }\n\n// Extra\n\nclass UserSession {\n  constructor() {\n\n    if (!!UserSession.instance) {\n      return UserSession.instance;\n    }\n\n    this.user = null;\n\n    UserSession.instance = this;\n  }\n\n  setUser(id, username, name, mail) {\n    this.user = {id, username, name, mail};\n  }\n  \n  getUser() {\n    return `${this.user.id} ${this.user.username} ${this.user.name} ${this.user.mail}`;\n  }\n\n  clearUser() {\n    this.user.id = null;\n    this.user.username = null;\n    this.user.name = null;\n    this.user.mail = null;\n  }\n}\n\nlet newSession = new UserSession();\nnewSession.setUser(212, 'parababire', 'Angel', 'angelnarvaez@gmail.com');\nconsole.log(newSession.getUser());\n\nlet newSession2 = new UserSession();\nconsole.log(newSession2.getUser());\n\nlet newSession3 = new UserSession();\nnewSession3.clearUser();\nconsole.log(newSession3.getUser());\n\nconsole.log(newSession2.getUser() === newSession.getUser()); // true"
  },
  {
    "path": "Roadmap/23 - SINGLETON/javascript/pedamoci.js",
    "content": "class Singleton {\n  constructor(name) {\n    if (!!Singleton.instance) {\n      return Singleton.instance\n    }\n\n    Singleton.instance = this \n    this.name = name\n\n    return this\n  }\n\n  getName() {\n    return this.name\n  }\n}\n\nconst instanceOne = new Singleton('One')\nconst instanceTwo = new Singleton('Two')\nconst instanceThree = new Singleton('Three')\n\nconsole.log(`Nombre de la primera inicialización: ${instanceOne.getName()}`)\nconsole.log(`Nombre de la segunda inicialización: ${instanceTwo.getName()}`)\nconsole.log(`Nombre de la tercera inicialización: ${instanceThree.getName()}`)\n\n// ------------------------------------ DIFICULTAD EXTRA ------------------------------------\nclass Sesion {\n  constructor(id, nombreUsuario, nombre, email) {\n    if (!!Sesion.instance) {\n      return Sesion.instance\n    }\n\n    Sesion.instance = this \n    this.id = id \n    this.nombreUsuario = nombreUsuario \n    this.nombre = nombre \n    this.email = email\n\n    return this\n  }\n\n  recuperarDatos() {\n    return [this.id, this.nombreUsuario, this.nombre, this.email]\n  }\n\n  finalizarSesion() {\n    Sesion.instance = false\n    this.id = null\n    this.nombreUsuario = null\n    this.nombre = null\n    this.email = null\n  }\n}\n\nconst usuario = new Sesion(453289, 'Singleton', 'Keny', 'emailpromedio@gmail.com')\nconsole.log(`${usuario.recuperarDatos().join(', ')}`)\nusuario.finalizarSesion()\nconsole.log(`${usuario}`)"
  },
  {
    "path": "Roadmap/23 - SINGLETON/javascript/victor-Casta.js",
    "content": "/*\n  * EJERCICIO:\n  * Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n  * con un ejemplo genérico.\n*/\n\nclass Singleton {\n  constructor(name) {\n    if(Singleton.instance) {\n      return Singleton.instance\n    }\n\n    this.name = name\n    Singleton.instance = this\n  }\n}\n\nconst singleton1 = new Singleton('Jhon')\nconst singleton2 = new Singleton('Doe')\nconsole.log(singleton1 === singleton2)\n\n/*\n  * DIFICULTAD EXTRA (opcional):\n  * Utiliza el patrón de diseño \"singleton\" para representar una clase que\n  * haga referencia a la sesión de usuario de una aplicación ficticia.\n  * La sesión debe permitir asignar un usuario (id, username, nombre y email),\n  * recuperar los datos del usuario y borrar los datos de la sesión.\n*/\n\nclass Login{\n  constructor(id, username, name, email) {\n    if(Login.instance) {\n      return Login.instance\n    }\n    this.id = id\n    this.username = username\n    this.name = name\n    this.email = email\n    Login.instance = this\n  }\n\n  getUsers() {\n    return `Id: ${this.id}, Usuario: ${this.username}, Nombre: ${this.name}, Email: ${this.email}`\n  }\n\n  clearUsers() {\n    this.id = null\n    this.username = null\n    this.name = null\n    this.email = null\n  }\n}\n\nconst login_1 = new Login(1,'victorCasta', 'Victor', 'victorcasta@gmail.com')\nconsole.log(login_1.getUsers())\nconst login_2 = new Login()\nconsole.log(login_2.getUsers())\nlogin_2.clearUsers()\nconsole.log(login_2.getUsers())"
  },
  {
    "path": "Roadmap/23 - SINGLETON/kotlin/Rikmij.kt",
    "content": "fun main() {\n    val exampleSingleton = SingletonExample.instance\n    val exampleSingleton2 = SingletonExample.instance\n    exampleSingleton.str = \"Soy otro ejemplo, mírame\"\n    println(exampleSingleton2.str)\n\n    println(\"\\n${\"-\".repeat(7)} EJERCICIO EXTRA ${\"-\".repeat(7)}\")\n    UserSession.setUser(\"rickjj97\", \"Rick\", \"mondongo@gmail.com\")\n    UserSession.showUser()\n    UserSession.deleteUser()\n    println(UserSession.user)\n}\n\n//le ponemos el constructor privado para que no pueda crear instancias. Se crean desde dentro\nclass SingletonExample private constructor() {\n    var str = \"Soy un ejemplo\"\n\n    //Un companion object es una forma de que otras clases puedan acceder a ésta sin tener un\n    //objeto creado\n    companion object {\n        //by lazy hace que hasta que no se llame a la variable, ésta no se ejecutará, y\n        //cuando la llamen, devolverá lo de dentro o hará lo que se especifique dentro\n        val instance: SingletonExample by lazy { SingletonExample() }\n    }\n}\n\n//un object es ya un objeto, una instancia que tiene el Singleton por detrás. Te hace el Singleton\nobject UserSession {\n    private var username = \"\"\n    private var name = \"\"\n    private var email = \"\"\n    val user = mutableListOf(chooseId(), username, name, email)\n\n    private fun chooseId(): String {\n        val numID = username.length * name.length * 123\n        val id = \"${numID}R\"\n        return id\n    }\n\n    fun setUser(user: String, name1: String, mail: String)  {\n        username = user\n        name = name1\n        email = mail\n    }\n\n    fun showUser() {\n        println(\"user ID: ${chooseId()}\")\n        println(\"username: $username\")\n        println(\"name: $name\")\n        println(\"email: $email\")\n    }\n\n    fun deleteUser() {\n        user.clear()\n        println(\"Se han borrado los datos del usuario\")\n    }\n}\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/kotlin/blackriper.kt",
    "content": "import java.util.UUID\r\n\r\n/*\r\nLos patrones de diseño son soluciones habituales a problemas que ocurren frecuentemente en el desarollo de software\r\n\r\nestos de clasifican  en\r\n - patrones creacionales\r\n - patrones de comportamiento\r\n - patrones estructurales\r\n\r\nSingleton\r\nes un patron creacional que nos permite crear una  unica instancia de una clase. ala vez que nos proporciona acceso\r\na la instancia de la clase.\r\n\r\nComo implementarlo\r\n\r\n1.- Añadir un capmpo estatico ala clase para almacenar la instancia singlenton\r\n\r\n2.- Crear un metodo estatico publico  que devuelva la instancia de la clase\r\n\r\n3.- Implementa una inicialización diferida dentro del método estático.\r\n debe crear un nuevo objeto en su primera llamada y colocarlo dentro del campo estático.\r\n el método deberá devolver siempre esa instancia en todas las llamadas siguientes.\r\n\r\n4.- Declara el constructor de clase como privado. El método estático de la clase\r\n seguirá siendo capaz de invocar al constructor, pero no a los otros objetos.\r\n\r\n para mas informacion sobre los patrones de diseño revisa https://refactoring.guru/design-patterns/singleton\r\n*/\r\n\r\n\r\n//implementando singleton\r\n\r\n                    //paso 4\r\nclass Configuration private constructor(){\r\n    private var theme = \"dark\"\r\n    private var printer = \"hp\"\r\n   //paso 2\r\n    companion object {\r\n        //paso 1\r\n        private var instance: Configuration? = null\r\n\r\n        //paso 3\r\n        fun getInstance(): Configuration {\r\n            if (instance == null) {\r\n                instance = Configuration()\r\n            }\r\n            return instance!!\r\n        }\r\n    }\r\n   fun getConfiguration() = \"theme:$theme, printer:$printer\"\r\n}\r\n\r\n// en kotlin hay una forma corta de crear una instancia singleton y esta es usando el keyword object\r\n\r\nobject Configuration2 {\r\n    private var theme = \"light\"\r\n    private var printer = \"hp\"\r\n    fun getConfiguration() = \"theme:$theme, printer:$printer\"\r\n}\r\n\r\n// ejercicio extra\r\n\r\ndata class User(val id:UUID, val username:String, val name:String,val email:String)\r\n\r\n\r\nclass Session private constructor(){\r\n   private  var userSession:User?=null\r\n    companion object {\r\n        private var instance: Session? = null\r\n        fun getInstance(): Session {\r\n            if (instance == null) {\r\n                instance = Session()\r\n            }\r\n            return instance!!\r\n        }\r\n    }\r\n    fun login(username:String ,name:String, email: String):User{\r\n         userSession=User(UUID.randomUUID(),username,name,email)\r\n        return userSession!!\r\n    }\r\n\r\n    fun logout() {\r\n        userSession = null\r\n        println(\"closing session\")\r\n    }\r\n}\r\n\r\n\r\n\r\nfun main() {\r\n    // aunque se vuela a llamar el metodo getInstance  esta sera la misma instancia\r\n    val config = Configuration.getInstance()\r\n    println(config.getConfiguration())\r\n\r\n    val config2 = Configuration.getInstance()\r\n    println(config2.getConfiguration())\r\n\r\n    println(config == config2)\r\n\r\n    // forma abreviada del singlenton\r\n    val config3 = Configuration2\r\n    println(config3.getConfiguration())\r\n\r\n    val config4 = Configuration2\r\n    println(config4.getConfiguration())\r\n\r\n    println(config3 == config4)\r\n\r\n    // ejercicio extra\r\n    val session= Session.getInstance()\r\n    val user= session.login(\"blackriper\",\"rodolfo\",\"devgo@gmail.com\")\r\n    println(user)\r\n    session.logout()\r\n\r\n\r\n    val user2 = session.login(\"cisagroups\",\"daniel\",\"company@gmail.com\")\r\n    println(user2)\r\n    session.logout()\r\n\r\n}"
  },
  {
    "path": "Roadmap/23 - SINGLETON/kotlin/eulogioep.kt",
    "content": "// Ejemplo genérico de Singleton\nobject Singleton {\n    init {\n        println(\"Singleton inicializado\")\n    }\n    \n    fun doSomething() {\n        println(\"Singleton está haciendo algo\")\n    }\n}\n\n// Ejemplo de la dificultad extra: Sesión de usuario\nobject UserSession {\n    private var userId: Int? = null\n    private var username: String? = null\n    private var name: String? = null\n    private var email: String? = null\n\n    fun setUser(id: Int, username: String, name: String, email: String) {\n        this.userId = id\n        this.username = username\n        this.name = name\n        this.email = email\n        println(\"Usuario asignado a la sesión\")\n    }\n\n    fun getUserData(): Map<String, Any?> {\n        return mapOf(\n            \"id\" to userId,\n            \"username\" to username,\n            \"name\" to name,\n            \"email\" to email\n        )\n    }\n\n    fun clearSession() {\n        userId = null\n        username = null\n        name = null\n        email = null\n        println(\"Sesión borrada\")\n    }\n}\n\nfun main() {\n    // Uso del Singleton genérico\n    println(\"Usando el Singleton genérico:\")\n    Singleton.doSomething()\n    Singleton.doSomething()\n\n    println(\"\\nUsando el UserSession:\")\n    // Uso del UserSession\n    UserSession.setUser(1, \"eulogioep\", \"Eulogio EP\", \"eulogioep@ex.com\")\n    println(\"Datos del usuario: ${UserSession.getUserData()}\")\n    UserSession.clearSession()\n    println(\"Datos después de borrar: ${UserSession.getUserData()}\")\n}"
  },
  {
    "path": "Roadmap/23 - SINGLETON/ocaml/luishendrix92.ml",
    "content": "open Printf\n\n(******************************************************************************)\n(*                                                                            *)\n(*                           The Singleton Pattern                            *)\n(*                                                                            *)\n(*  Singleton in terms of software design patterns, popularized by the        *)\n(*  'gang of four' in the OOP sphere, is a class that can only have one       *)\n(*  instance in memory and can be shared everywhere in the project.           *)\n(*  This is very useful for stuff like resource pools, dependency injection,  *)\n(*  global state managers, and any situation in which no more than one        *)\n(*  instance of a class needs to be created.                                  *)\n(*                                                                            *)\n(*  In an OOP language like Java, C# or C++, the way we implement this pa-    *)\n(*  ttern is by making the constructor private and instead exposing a method  *)\n(*  that will create the instance if it doesn't exist yet (NULL reference),   *)\n(*  or return the current instance otherwise. However, OCaml is a functional  *)\n(*  language, therefore we need to make use of module-level bindings combi-   *)\n(*  ned with the concet of a mutable reference or a record with mutable       *)\n(*  fields to simulate a global state variable that we can write and read     *)\n(*  to and from. Ideally we'd also need to make use of a Mutex.               *)\n(*                                                                            *)\n(*                                [ N O T E ]                                 *)\n(*  OCaml's built-in class syntax has no concept of a static members and      *)\n(*  private constructors so we can't make use of the [class] keyword here.    *)\n(*                                                                            *)\n(******************************************************************************)\n\nmodule Singleton : sig\n  val get_data : unit -> int\n  val set_data : int -> unit\nend = struct\n  let instance = ref 0\n  let get_data () = !instance\n  let set_data data = instance := data\nend\n\nlet _ =\n  print_endline \"Singleton module [Singleton] has a globally accessible\";\n  print_endline \"value as a mutable reference, emulating a singleton in OOP!\";\n  print_newline ();\n  printf \"Current value: [%d] | Changing to [5]...\\n\" @@ Singleton.get_data ();\n  Singleton.set_data 5;\n  printf \"New current value: [%d]\\n\" @@ Singleton.get_data ();\n  print_newline ()\n;;\n\n(*****************************************************************************)\n(*                                                                           *)\n(*                        Dificultad Extra (Opcional)                        *)\n(*                                                                           *)\n(*  Utiliza el patrón de diseño \"singleton\" para representar una clase que   *)\n(*  haga referencia a la sesión de usuario de una aplicación ficticia.       *)\n(*  La sesión debe permitir asignar un usuario (id, username, nombre y e-    *)\n(*  mail), recuperar los datos del usuario y borrar los datos de la sesión.  *)\n(*                                                                           *)\n(*****************************************************************************)\n\nmodule SessionManager : sig\n  type session\n\n  val set_data : int -> string -> string -> string -> unit\n  val get_data : unit -> session option\n  val clear : unit -> unit\n  val show : unit -> string\nend = struct\n  type session =\n    { id : int\n    ; username : string\n    ; full_name : string\n    ; email : string\n    }\n  [@@deriving show { with_path = false }]\n\n  let data : session option ref = ref None\n\n  let set_data id username full_name email =\n    data := Some { id; username; full_name; email }\n  ;;\n\n  let show () =\n    match !data with\n    | None -> \"{ NO SESSION! }\"\n    | Some session -> show_session session\n  ;;\n\n  let get_data () = !data\n  let clear () = data := None\nend\n\nlet _ =\n  print_endline \"Session management system:\";\n  print_endline \"--------------------------\";\n  printf \"Current session: %s\\n\" @@ SessionManager.show ();\n  print_endline \"Setting the session with a new user...\";\n  SessionManager.set_data\n    2399\n    \"luishendrix92\"\n    \"Luis Felipe Lopez Garay\"\n    \"luishendrix92@gmail.com\";\n  printf \"Current session: %s\\n\" @@ SessionManager.show ();\n  print_endline \"Deleting session data from a different thread...\";\n  Thread.create (fun () -> SessionManager.clear ()) () |> Thread.join;\n  printf \"Current session: %s\\n\" @@ SessionManager.show ()\n;;\n\n(*\n  Output\n  ===========================================================\n  Singleton module [Singleton] has a globally accessible\n  value as a mutable reference, emulating a singleton in OOP!\n\n  Current value: [0] | Changing to [5]...\n  New current value: [5]\n\n  Session management system:\n  --------------------------\n  Current session: { NO SESSION! }\n  Setting the session with a new user...\n  Current session: { id = 2399; username = \"luishendrix92\";\n    full_name = \"Luis Felipe Lopez Garay\"; email = \"luishendrix92@gmail.com\" }\n  Deleting session data from a different thread...\n  Current session: { NO SESSION! }\n  ===========================================================\n*)\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/php/eulogioep.php",
    "content": "<?php\n/**\n * Implementación del patrón Singleton en PHP\n * \n * Nota sobre las etiquetas PHP:\n * - En archivos que contienen solo código PHP, se recomienda omitir la etiqueta de cierre ?>\n * - Esto previene la inclusión accidental de espacios en blanco o caracteres después del cierre\n * - Sin embargo, si el archivo mezcla HTML y PHP, sí debes usar las etiquetas de cierre\n */\n\nclass BasicSingleton {\n    // Instancia privada estática para almacenar la única instancia de la clase\n    private static ?BasicSingleton $instance = null;\n    \n    // Constructor privado para evitar la creación de instancias con 'new'\n    private function __construct() {}\n    \n    // Método público estático que controla el acceso a la instancia\n    public static function getInstance(): BasicSingleton {\n        // Si no existe la instancia, la crea\n        if (self::$instance === null) {\n            self::$instance = new self();\n        }\n        // Retorna la instancia única\n        return self::$instance;\n    }\n    \n    // Evitar la clonación del objeto\n    private function __clone() {}\n    \n    // Evitar la deserialización del objeto\n    public function __wakeup() {\n        throw new Exception(\"No se puede deserializar un singleton.\");\n    }\n}\n\n/**\n * Ejercicio Extra: Singleton para Sesión de Usuario\n * ===============================================\n * Implementación de una clase de sesión de usuario utilizando el patrón Singleton\n */\nclass UserSession {\n    // Instancia privada estática\n    private static ?UserSession $instance = null;\n    \n    // Datos del usuario actual\n    private ?array $userData = null;\n    \n    // Constructor privado\n    private function __construct() {}\n    \n    // Método para obtener la instancia\n    public static function getInstance(): UserSession {\n        if (self::$instance === null) {\n            self::$instance = new self();\n        }\n        return self::$instance;\n    }\n    \n    /**\n     * Método para establecer los datos del usuario\n     * @param array $user Datos del usuario (id, username, name, email)\n     */\n    public function setUser(array $user): void {\n        // Validar que el array contenga todos los campos requeridos\n        $requiredFields = ['id', 'username', 'name', 'email'];\n        foreach ($requiredFields as $field) {\n            if (!isset($user[$field])) {\n                throw new Exception(\"El campo {$field} es requerido\");\n            }\n        }\n        \n        $this->userData = $user;\n    }\n    \n    /**\n     * Método para obtener los datos del usuario\n     * @return array|null Datos del usuario o null si no hay sesión\n     */\n    public function getUser(): ?array {\n        return $this->userData;\n    }\n    \n    /**\n     * Método para cerrar la sesión\n     */\n    public function logout(): void {\n        $this->userData = null;\n    }\n    \n    // Evitar la clonación del objeto\n    private function __clone() {}\n    \n    // Evitar la deserialización del objeto\n    public function __wakeup() {\n        throw new Exception(\"No se puede deserializar un singleton.\");\n    }\n}\n\n// Ejemplo de uso:\n// =============\n\ntry {\n    // Ejemplo básico\n    $singleton1 = BasicSingleton::getInstance();\n    $singleton2 = BasicSingleton::getInstance();\n    var_dump($singleton1 === $singleton2); // true\n    \n    // Ejemplo de sesión de usuario\n    $session = UserSession::getInstance();\n    \n    // Crear un usuario de ejemplo\n    $user = [\n        'id' => 1,\n        'username' => 'john_doe',\n        'name' => 'John Doe',\n        'email' => 'john@example.com'\n    ];\n    \n    // Iniciar sesión\n    $session->setUser($user);\n    var_dump($session->getUser()); // Muestra los datos del usuario\n    \n    // Obtener la misma instancia en otro lugar del código\n    $anotherSessionReference = UserSession::getInstance();\n    var_dump($anotherSessionReference->getUser()); // Muestra los mismos datos\n    \n    // Cerrar sesión\n    $session->logout();\n    var_dump($session->getUser()); // null\n    \n} catch (Exception $e) {\n    echo \"Error: \" . $e->getMessage();\n}\n?>"
  },
  {
    "path": "Roadmap/23 - SINGLETON/php/gabrielmoris.php",
    "content": "<?php\n/*\n* EXERCISE:\n* Explore the \"singleton\" design pattern and show how to create it\n* with a generic example.\n*/\nclass Singleton\n{\n    // private: To dont modify it out of the class\n    // static: Belongs to the class instead of to the instances (Only one ocopyof $instance is shared across all Singleton Objects)\n    // ?self:  $instance can be a object type $self or null\n    private static ?self $instance = null;\n\n    // Private constructor to prevent direct object creation\n    private function __construct()\n    {\n    }\n\n    public static function getInstance(): self\n    {\n        if (self::$instance === null) {\n            self::$instance = new self();\n        }\n        return self::$instance;\n    }\n\n    public function someMethod()\n    {\n        echo \"This is a method from the singleton instance!\\n\";\n    }\n}\n\n// Usage\n\n$instance1 = Singleton::getInstance(); // The construct is provate, so I call the public static function\n$instance2 = Singleton::getInstance();\n\nif ($instance1 === $instance2) {\n    echo \"Both instances are the same object\\n\";\n} else {\n    echo \"Something went wrong - instances are different\\n\";\n}\n\n$instance1->someMethod();\n\n/*\n* EXTRA DIFFICULTY (optional):\n* Use the \"singleton\" design pattern to represent a class that\n* references the user session of a fictitious application.\n* The session should allow assigning a user (id, username, name and email),\n* retrieving the user's data and deleting the session data.\n*/\n\nclass Session\n{\n    private static ?self $instance = null;\n    private int $id;\n    private string $username;\n    private string $name;\n    private string $email;\n\n    private function __construct(int $id, string $username, string $name, string $email)\n    {\n        $this->id = $id;\n        $this->username = $username;\n        $this->name = $name;\n        $this->email = $email;\n    }\n\n    public static function getInstance(): self\n    {\n        if (self::$instance === null) {\n            self::$instance = new self(1, \"\", \"\", \"\"); // Initial empty session\n        }\n        return self::$instance;\n    }\n\n    public function setNewSession(string $username, string $name, string $email): void\n    {\n        $this->username = $username;\n        $this->name = $name;\n        $this->email = $email;\n\n        echo \"Session Updated with id \" . $this->id . \"\\n\";\n    }\n\n    public function getUsername(): string\n    {\n        return $this->username;\n    }\n\n    public function getName(): string\n    {\n        return $this->name;\n    }\n\n    public function getEmail(): string\n    {\n        return $this->email;\n    }\n}\n\n$session1 = Session::getInstance();\n$session1->setNewSession(\"gabrielcmoris\", \"gabriel\", \"gabrielcmoris@gabrielcmoris.com\");\n$dataSession1 = $session1->getUsername(); // Use getId()\nvar_dump($dataSession1);\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/php/miguelex.php",
    "content": "<?php\nclass Singleton {\n    private static $instance = null;\n    private static $contador = 0; // COntador con el numero de instancias que tenemos\n\n    public static function getInstance() {\n        self::$contador++;\n        if (self::$instance === null) {\n            self::$instance = new Singleton();\n        }\n        return self::$instance;\n    }\n\n    public function getContador() {\n        return self::$contador;\n    }\n}\n\n$singleton = Singleton::getInstance();\necho $singleton->getContador() . \"\\n\";  // Debería imprimir 1\n\n$singleton2 = Singleton::getInstance();\necho $singleton2->getContador() . \"\\n\";  // Debería imprimir 2\n\n$singleton3 = Singleton::getInstance();\necho $singleton3->getContador() . \"\\n\";  // Debería imprimir 3\n\n// Extra\n\necho \"\\n\\nEJERCICIO EXTRA\\n\\n\";\n\nclass UserSession {\n    private static $instance = null;\n    private $userData = [];\n\n    public static function getInstance() {\n        if (self::$instance === null) {\n            self::$instance = new UserSession();\n        }\n        return self::$instance;\n    }\n\n    public function setUser($id, $username, $name, $email) {\n        $this->userData[$id] = [\n            'id' => $id,\n            'username' => $username,\n            'name' => $name,\n            'email' => $email\n        ];\n    }\n\n    public function getUser($id) {\n        return isset($this->userData[$id]) ? $this->userData[$id] : null;\n    }\n\n    public function clearUser($id) {\n        if (isset($this->userData[$id])) {\n            unset($this->userData[$id]);\n        }\n    }\n\n    public function getAllUsers() {\n        return $this->userData;\n    }\n\n    public function clearAllUsers() {\n        $this->userData = [];\n    }\n}\n\n\n$session = UserSession::getInstance();\n\n$session->setUser(1, 'miguelex', 'miguelex dm', 'miguelex@example.com');\n$session->setUser(2, 'DrJones', 'Indiana Jones', 'indy@example.com');\n\necho \"\\n\\nCreamos una segunda sesion y mostramos la lista de sesiones\\n\\n\";\n$session2 = UserSession::getInstance();\n$allUsers = $session2->getAllUsers();\nprint_r($allUsers); \n\necho \"\\n\\nRecuperamos los datos del priemr usuario desde la primera sesion\\n\\n\";\n$userData1 = $session->getUser(1);\nprint_r($userData1);  \n\necho \"\\n\\nRecuperamos los datos del segundo usuario desde la segunda sesion\\n\\n\";\n$userData2 = $session2->getUser(2);\nprint_r($userData2);  \n\necho \"\\n\\nBorramos los datos del primer usuario desde la primera sesion\\n\\n\";\n$session->clearUser(1);\n$userData1 = $session->getUser(1);\nprint_r($userData1);  \n\necho \"\\n\\nMostramos la lista de usuarios de la primera sesion\\n\\n\";\n$allUsers = $session->getAllUsers();\nprint_r($allUsers);  \n\necho \"\\n\\nBorramos todos los usuarios de la segunda sesion\\n\\n\";\n$session->clearAllUsers();\n$allUsers = $session2->getAllUsers();\nprint_r($allUsers); "
  },
  {
    "path": "Roadmap/23 - SINGLETON/php/thaishdz.php",
    "content": "<?php\n\n/*\n* Decidí separar responsabilidades (La S de SOLID bien dentro del peshito) por eso tengo 2 clases :\n* User\n* Session\n*/\n\nclass User\n{\n    private string $id;\n    private static $instance = null;\n\n\n    // Constructor con Promoted Properties (no sé me apeteció usarlo)\n    private function __construct(\n        private string $username,\n        private string $name,\n        private string $email,\n    )\n    {\n        $this->id = bin2hex(random_bytes(16)); // \"random_bytes\" genera una cadena de 16 bytes y \"bin2hex\" la convierte a hexadecimal\n    }\n\n    public static function getInstance(string $username,string $name,string $email)\n    {\n        if (is_null(self::$instance))\n        {\n            self::$instance = new self($username, $name, $email);\n        }\n        return self::$instance;\n    }\n\n    public function data(): array\n    {\n        return [\n            'ID'        => $this->id,\n            'Username'  => $this->username,\n            'Name'      => $this->name,\n            'Email'     => $this->email\n        ];\n    }\n\n    public function reset(): void\n    {\n        $this->id = '';\n        $this->username = '';\n        $this->name = '';\n        $this->email = '';\n    }\n\n    private function __clone() {}\n\n    public function __wakeup() \n    {\n        throw new \\Exception('Cannot unserialize a Singleton');\n    }\n}\n\n// --------------------------------------------------------------------\nclass Session\n{\n    private string $id;\n    private User $user;\n\n\n    public function __construct(\n        private string $username,\n        private string $name,\n        private string $email,\n    )\n    {\n        $this->id = bin2hex(random_bytes(16)); \n        $this->user = User::getInstance($username, $name, $email);\n    }\n\n    public function id()\n    {\n        return $this->id;\n    }\n\n    public function user()\n    {\n        $userData = $this->user->data();\n\n        // Solo añadir 'SessionID' si la sesión está activa\n        if ($this->id) {\n            $userData['SessionID'] = $this->id;\n        }\n        return $userData;\n    }\n\n    public function logout()\n    {\n       $this->id = '';\n       return $this->user->reset();\n    }\n\n}\n\n// --------------------------------------------------------------------\n\n$session = new Session(\"toxicPlayer69\", \"Eufemio\", \"toxicPlayer@gmail.com\");\n\nvar_dump($session->user());\n$session->logout();\nvar_dump($session->user());\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/Aldroide.py",
    "content": "\"\"\"\n    Explora el concepto de funciones de orden superior en tu lenguaje \n    creando ejemplos simples (a tu elección) que muestren su funcionamiento.\n\"\"\"\n\n\nclass Singleton():\n    _instance = None\n\n    def __new__(cls):\n        if not cls._instance:\n            cls._instance = super(Singleton, cls).__new__(cls)\n        return cls._instance\n\n\nsingleton1 = Singleton()\nprint(singleton1)\nsingleton2 = Singleton()\nprint(singleton2)\n\n\"\"\"\n    Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y \n    lista de calificaciones), utiliza funciones de orden superior para \n    realizar las siguientes operaciones de procesamiento y análisis:\n        - Promedio calificaciones: Obtiene una lista de estudiantes por nombre\n            y promedio de sus calificaciones.\n        - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes\n            que tienen calificaciones con un 9 o más de promedio.\n        - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven.\n        - Mayor calificación: Obtiene la calificación más alta de entre todas las\n            de los alumnos.\n        - Una calificación debe estar comprendida entre 0 y 10 (admite decimales).\n\n\"\"\"\n\n\nclass UserSession():\n    _instance = None\n\n    id = int\n    username = str\n    name = str\n    email = str\n\n    def __new__(cls):\n        if not cls._instance:\n            cls._instance = super(UserSession, cls).__new__(cls)\n        return cls._instance\n\n    def set_user(self, id, name, username, email):\n        self.id = id\n        self.username = username\n        self.name = name\n        self.email = email\n\n    def get_user(self):\n        return f\"{self.id},{self.username},{self.name},{self.email}\"\n\n    def clear_user(self):\n        self.id = None\n        self.username = None\n        self.name = None\n        self.email = None\n\n\nsession1 = UserSession()\nprint(session1.get_user())\nsession1.set_user(1, \"aldroide\", \"Aldo AC\", \"aldroidegmail.com\")\nprint(session1.get_user())\n\nsession2 = UserSession()\nprint(session2.get_user())\n\nsession3 = UserSession()\nsession3.clear_user()\nprint(session3.get_user())\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/CaveroBrandon.py",
    "content": "\"\"\" EJERCICIO:\nExplora el patrón de diseño \"singleton\" y muestra cómo crearlo\ncon un ejemplo genérico.\n\"\"\"\n\n\nclass Door:\n    _is_door_open = None\n    _initialized = False\n\n    def __new__(cls):\n        if cls._is_door_open is None:\n            cls._is_door_open = super(Door, cls).__new__(cls)\n        return cls._is_door_open\n\n    def __init__(self):\n        if not self._initialized:\n            self.value = None\n\n\nperson1 = Door()\nperson2 = Door()\n\nperson1.value = True  # Person 1 opens the door\nprint(f'Person 1 opens the door, door status = {person1.value}')\nprint(f'Person 2 checks the door, door status = {person2.value}')\nperson2.value = False\nprint(f'Person 2 close the door, door status = {person2.value}')\nprint(f'Person 1 checks the door, door status = {person1.value}')\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\nUtiliza el patrón de diseño \"singleton\" para representar una clase que\nhaga referencia a la sesión de usuario de una aplicación ficticia.\nLa sesión debe permitir asignar un usuario (id, username, nombre y email),\nrecuperar los datos del usuario y borrar los datos de la sesión.\n\"\"\"\n\nprint('\\n---- Extra ----\\n')\nclass UserSession:\n    _instance = None\n    user_id = None\n    username = None\n    name = None\n    email = None\n\n    def __new__(cls):\n        if cls._instance is None:\n            cls._instance = super(UserSession, cls).__new__(cls)\n        return cls._instance\n\n    def create_user_session(self, user_id: int, username: str, name: str, email: str):\n        self.user_id = user_id\n        self.username = username\n        self.name = name\n        self.email = email\n\n    def get_user_session(self) -> dict:\n        user_session = {'user_id': self.user_id, 'username': self.username, 'name': self.name, 'email': self.email}\n        return user_session\n\n    def clear_session(self):\n        self.user_id = None\n        self.username = None\n        self.name = None\n        self.email = None\n\n\nsession1 = UserSession()\nprint('Creating a user session...')\nsession1.create_user_session(user_id=123, username='Brandon123', name='Brandon', email='cc@gmail.com')\nprint(session1.get_user_session())\n\nsession2 = UserSession()\nprint('Overriding user session...')\nsession2.create_user_session(user_id=321, username='Cavero321', name='Andres', email='cavero.brandon94@gmail.com')\nprint(session2.get_user_session())\n\nprint('Clearing the user session')\nsession1.clear_session()\nprint(session1.get_user_session())\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/CesarCarmona30.py",
    "content": "'''\n    EJERCICIO\n'''\n\nclass Singleton:\n    _instance = None\n\n    def __new__(cls):\n        if cls._instance is None:\n            print(\"Creating instance\")\n            cls._instance = super(Singleton, cls).__new__(cls)\n        print(\"Using instance\")    \n        return cls._instance\n\ninstance1 = Singleton()\ninstance2 = Singleton()\n\nprint(instance1 is instance2)\n\n'''\n    EXTRA\n'''\n\nclass Session():\n    _instance = None\n    \n    id = None\n    username = None\n    name = None\n    email = None\n    \n    def __new__(cls):\n        if cls._instance is None:\n            cls._instance = super(Session, cls).__new__(cls)\n        return cls._instance\n\n    def set_user(self, id, username, name, email):\n        self.id = id\n        self.username = username\n        self.name = name\n        self.email = email\n\n    def get_user(self):\n        return f'User: {self.id}, {self.username}, {self.name}, {self.email}'\n    \n    def clear_user(self):\n        self.id = None\n        self.username = None\n        self.name = None\n        self.email = None\n    \nsession1 = Session()\nprint(session1.get_user())\nsession1.set_user(1, \"leroy58\", \"César Leroy\", \"cesarcarmona@gmail.com\")\nprint(session1.get_user())\n\nsession2 = Session()\nprint(session2.get_user())\n\nsession3 = Session()\nsession3.clear_user()\nprint(session3.get_user())"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/Chrisdev00.py",
    "content": "\"\"\"\n* EJERCICIO:\n* Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n* con un ejemplo genérico.\n*\n* DIFICULTAD EXTRA (opcional):\n* Utiliza el patrón de diseño \"singleton\" para representar una clase que\n* haga referencia a la sesión de usuario de una aplicación ficticia.\n* La sesión debe permitir asignar un usuario (id, username, nombre y email),\n* recuperar los datos del usuario y borrar los datos de la sesión.\n\"\"\"\n\nclass Singleton:\n    __instance = None  \n\n    def __new__(cls):\n        if cls.__instance is None:\n            cls.__instance = super(Singleton, cls).__new__(cls)\n            \n            cls.__instance.data = \"Singleton Data\"\n        return cls.__instance\n\n\nif __name__ == \"__main__\":\n    s1 = Singleton()\n    s2 = Singleton()\n    \n    print(s1 is s2)  \n    \n    print(s1.data)  # Salida: Singleton Data\n    print(s2.data)  # Salida: Singleton Data\n    \n    s1.data = \"New Singleton Data\"\n    print(s2.data)  # Salida: New Singleton Data\n\n\n############### ------------------------------ EXTRA --------------------------------- #######################\n\n\nclass UsserSession:\n    __instance = None\n\n    def __new__(cls):\n        if cls.__instance is None:\n            cls.__instance = super(UsserSession, cls).__new__(cls)\n            cls.__instance.user_data = {}\n        return cls.__instance\n\n    def set_user(self, id, username, name, email):\n        self.user_data[\"id\"] = id\n        self.user_data[\"user_name\"] = username\n        self.user_data[\"name\"] = name\n        self.user_data[\"email\"] = email\n\n    def get_user(self):\n        return self.user_data\n    \n    def cler_session(self):\n        self.user_data = {}\n\nif __name__== \"__main__\":\n    session1 = UsserSession()\n\n    session1.set_user(id=1, username=\"jhon00\", name=\"Jhon\", email=\"john.doe@example.com\")\n\n    user_info = session1.get_user()\n    print(user_info)\n\n    session2 = UsserSession()\n    print(session1 is session2)\n\n    user_info = session2.get_user()\n    print(user_info)\n\n    session2.cler_session()\n\n    user_info = session1.get_user()\n    print(user_info)"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/EmmanuelMMontesinos.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n * con un ejemplo genérico.\n */\n\"\"\"\n\n# Singleton\nclass Singleton:\n    _instancia = None\n    def __new__(cls) -> _instancia:\n        if cls._instancia == None:\n            cls._instancia = super(Singleton,cls).__new__(cls)\n        return cls._instancia\n\n# Pruebas \ninstancia_1 = Singleton()\ninstancia_2 = Singleton()\ninstancia_3 = Singleton()\n\nprint(f\"1 es igual a 2: {instancia_1 == instancia_2}\")\nprint(f\"2 es igual a 3: {instancia_2 == instancia_3}\")\nprint(f\"3 es igual a 1: {instancia_3 == instancia_1}\")\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el patrón de diseño \"singleton\" para representar una clase que\n * haga referencia a la sesión de usuario de una aplicación ficticia.\n * La sesión debe permitir asignar un usuario (id, username, nombre y email),\n * recuperar los datos del usuario y borrar los datos de la sesión.\n\"\"\"\n\nclass Sesion:\n    _instancia = None\n    nombre = None\n    id = None\n    username = None\n    email = None\n\n    def __new__(cls,nombre,id,username,email):\n        if cls._instancia is None:\n            cls._instancia = super(Sesion,cls).__new__(cls)\n            cls.nombre = nombre\n            cls.id = id\n            cls.username = username\n            cls.email = email\n        return cls._instancia\n    \n    def mostrar_datos(self):\n        if Sesion._instancia != None:\n            print(f\"Sesión activa por {Sesion.username}\")\n            print(f\"Nombre: {Sesion.nombre}\")\n            print(f\"ID sesión: {Sesion.id}\")\n            print(f\"Email: {Sesion.email}\\n\")\n        else:\n            print(\"Sesión No Activa\\n\")\n    \n    def cerrar_sesion(self):\n        print(f\"Sesión cerrada: {Sesion.username}\\n\")\n        Sesion._instancia = None\n        Sesion.nombre = None\n        Sesion.id = None\n        Sesion.email = None\n        Sesion.username = None\n\n# Pruebas\nsesion_1 = Sesion(\"Emmanuel\",1,\"SrMancoMan\",\"example@email.com\")\nsesion_2 = Sesion(\"Emmanuel2\",2,\"SrMancoMan2\",\"example2@email2.com\")\nsesion_3 = Sesion(\"Emmanuel3\",3,\"SrMancoMan3\",\"example3@email3.com\")\n\nsesion_1.mostrar_datos()\nsesion_2.mostrar_datos()\nsesion_3.mostrar_datos()\n\nsesion_1.cerrar_sesion()\nsesion_1.mostrar_datos()\n\nsesion_2 = Sesion(\"Emmanuel2\",2,\"SrMancoMan2\",\"example2@email2.com\")\n\nsesion_1.mostrar_datos()\nsesion_2.mostrar_datos()\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/FedeAirala.py",
    "content": "# #23 PATRONES DE DISEÑO: SINGLETON\n\"\"\"\n * EJERCICIO:\n * Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n * con un ejemplo genérico.\n\"\"\"\n\nclass Singleton:\n    instance = None\n    \n    def __new__(cls):\n        if not cls.instance:\n            cls.instance = super(Singleton,cls).__new__(cls)\n        return cls.instance\n    \nsesion1 = Singleton()\nprint (sesion1)\nsesion2 = Singleton()\nprint (sesion2)\nprint (sesion1 is sesion2)\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el patrón de diseño \"singleton\" para representar una clase que\n * haga referencia a la sesión de usuario de una aplicación ficticia.\n * La sesión debe permitir asignar un usuario (id, username, nombre y email),\n * recuperar los datos del usuario y borrar los datos de la sesión.\n\"\"\"\n\nclass User:\n    \n    instance = None\n    \n    id : int = None\n    name : str = None\n    email: str = None\n    \n    def __new__(cls):\n        if not cls.instance:\n            cls.instance = super(User,cls).__new__(cls)\n        return cls.instance\n    \n    def set_user(self,id,name,email) -> None:\n        self.id = id\n        self.name = name\n        self.email = email\n    \n    def get_user(self):\n        return f\"{self.id}, {self.name}, {self.email}\"\n    \n    def clear_user(self):\n        self.id = None\n        self.name = None\n        self.email = None\n    \n\nuser1 = User()\nuser1.set_user(1,\"Fede\",\"fede@gmail.com\")\nuser2 = User()\n\nprint (user1.name)\nprint (user2.get_user())\nuser2.clear_user()\nprint (user1.get_user())"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/Gordo-Master.py",
    "content": "# Singleton\n\n# Patron de diseño, donde la clase solo genera una instancia, que es unica y tenga un punto acceso global \n\n\"\"\"\nSirve para:\n1- Gestión de configuración\n2- Conexión a base de datos\n3- Registro de logs\n4- Controladores de cache\n\"\"\"\n\nclass Singleton:\n    _instance = None\n\n    def __new__(cls):\n        if cls._instance is None:\n            cls._instance = super(Singleton, cls).__new__(cls)\n        return cls._instance\n    \n\nobj_1 = Singleton()\nobj_2 = Singleton()\n\nprint(obj_1 is obj_2)\n\n\n\"\"\"\nEjercicio extra\n\"\"\"\n\nclass UserSession:\n    _instance = None\n\n    def __new__(cls):\n        if cls._instance is None:\n            cls._instance = super(UserSession, cls).__new__(cls)\n            cls._instance.init_data()\n        return cls._instance\n    \n    def init_data(self):\n        self._id = None\n        self.user_name = None\n        self._name = None\n        self.email = None\n    \n    def set(self, _id, user_name, _name, email):\n        self._id = _id\n        self.user_name = user_name\n        self._name = _name\n        self.email = email\n\n    def get_data(self):\n        print(\"Datos del usuario: \")\n        print(f\"Id: {self._id}\")\n        print(f\"User name: {self.user_name}\")\n        print(f\"Name: {self._name}\")\n        print(f\"Email: {self.email}\")\n\n    def close_session(cls):\n        print(\"Cerrando sesión...\")\n        cls.init_data()\n\nsesion1 = UserSession()\nsesion1.set(\"01\",\"Gordo-Master\",\"Gordo\",\"gordomaster@gmail.com\")\nsesion1.get_data()\n\nprint(\"Prueba con otro\")\nsesion2 = UserSession()\nsesion2.get_data()\n\nsesion1.close_session()\nsesion1.get_data()\nprint(sesion1)\n\n\n\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/Irenetitor.py",
    "content": "\n#Exercise\nclass Singleton:\n\n    _instance = None\n\n    def __new__(cls):\n        if not cls._instance:\n            cls._instance = super(Singleton, cls).__new__(cls)\n        return cls._instance\n\n\nsingleton1 = Singleton()\nprint(singleton1)\nsingleton2 = Singleton()\nprint(singleton2)\n\nprint(singleton1 is singleton2)\n\n\n#Extra Exercise\n\nclass User_Session:\n\n    _instance = None\n\n\n    id: int = None\n    username: str = None\n    name: str = None\n    email: str = None\n\n    def __new__(cls):\n        if cls._instance is None:\n            cls._instance = super(User_Session, cls).__new__(cls)\n        return cls._instance\n\n    def create_user(self, id, username, name, email):\n        self.id = id\n        self.username = username\n        self.name = name\n        self.email = email\n\n    def get_user(self):\n        return f\"{self.id}, {self.username}, {self.name}, {self.email}\"\n    \n    def clear_user(self):\n        self.id = None\n        self.username = None\n        self.name = None\n        self.email = None\n\n\nsession1 = User_Session()\nsession1.create_user(1, \"irene123\", \"Irene\", \"irene@mail.com\")\n\nprint(session1.get_user())\n\n# New variable but same object(Singleton)\nsession2 = User_Session()\nprint(session2.get_user()) #Same user\n\nsession2.clear_user()\n\nprint(session1.get_user())   #Cleared (None)\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/JesusWay69.py",
    "content": "import os, platform\nfrom importlib import reload \n\nif (platform.platform().startswith(\"macOS\") or platform.platform().startswith(\"Linux\")):\n    os.system('clear')\nelse:\n    os.system('cls')\n\n\n\"\"\" * EJERCICIO:\n * Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n * con un ejemplo genérico.\n *\n\"\"\"\n\n\nclass SingletonMeta(type):\n\n    _instances = {}\n\n    def __call__(cls, *args, **kwargs):\n       \n        if cls not in cls._instances:\n            instance = super().__call__(*args, **kwargs)\n            cls._instances[cls] = instance\n        return cls._instances[cls]\n\nclass Singleton1(metaclass=SingletonMeta):\n    def print_logic(self):\n     print(\"Creando objeto..\", self)\n\nif __name__ == \"__main__\":\n        Singleton1().print_logic()\n        instance1 = Singleton1()\n        instance2 = Singleton1()\n        print (\"Instancia 1 = \", instance1)\n        print (\"Instancia 2 = \", instance2)\n        print(\"\\n\")\n\n\n\"\"\" * DIFICULTAD EXTRA (opcional):\n * Utiliza el patrón de diseño \"singleton\" para representar una clase que\n * haga referencia a la sesión de usuario de una aplicación ficticia.\n * La sesión debe permitir asignar un usuario (id, username, nombre y email),\n * recuperar los datos del usuario y borrar los datos de la sesión.\"\"\"\n\n\ndef singleton (class_instance):\n    instances = {}\n    def get_instance(*args, **kwargs):\n        if class_instance == None:\n            instances.clear()\n            instances[class_instance] = class_instance(*args, **kwargs)\n            return instances[class_instance]\n        if class_instance not in instances:\n            instances[class_instance] = class_instance(*args, **kwargs)\n            return instances[class_instance]\n        if class_instance in instances:\n            return instances[class_instance]\n        \n    return get_instance\n\ndef singleton_off(singleton:singleton):\n    singleton = None\n    Session(singleton)\n    return singleton\n\n@singleton\nclass Session:\n    def __init__(self,id=None,username=None,name=None,email=None):\n            self.id = id\n            self.username = username\n            self.name = name\n            self.email = email\n    def setter(self,id=None,username=None,name=None,email=None):\n            self.id = id\n            self.username = username\n            self.name = name\n            self.email = email\n\njesus = Session(1, \"Jesusway69\", \"Jesus\", \"jesusway60@midominio.es\")\njose = Session(2, \"Pepe84\", \"Jose\", \"pepepepe@midominio.es\")\nprint(f\"Jesus = id: {jesus.id}, username: {jesus.username}, name: {jesus.name}, email: {jesus.email}\")\nprint(f\"Jose = id: {jose.id}, username: {jose.username}, name: {jose.name}, email: {jose.email}\")\nprint(\"Sesión de jesus: \", jesus)\nprint(\"Sesión de jose: \", jose)\njesus = singleton_off(jesus)\nprint(\"Eliminando sesión de jesus...\")\nprint(\"Sesión de jesus: \", jesus)\njesus = singleton(jesus)\nprint(\"Nueva sesión de jesus: \", jesus)\nana = Session()\nana.setter(3, \"Ana57\", \"Ana\", \"anagarcia@midominio.es\")\nprint(f\"Ana = id:{ana.id}, username: {ana.username}, name: {ana.name}, email: {ana.email}, sesión singleton: {ana}\")\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/JheisonQuiroga.py",
    "content": "# Author: Jheison Duban Quiroga Quintero\n# Github: https://github.com/JheisonQuiroga\n\n\"\"\"/*\n * EJERCICIO:\n * Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n * con un ejemplo genérico.\n *\n\"\"\"\n\n\n# Implementación básica\nclass Singleton:\n    _instance = None\n\n    def __new__(cls):\n        if cls._instance == None:\n            cls._instance = super(Singleton, cls).__new__(cls)\n\n        return cls._instance\n    \nsin1 = Singleton()\nprint(sin1)\nsin2 = Singleton()\nprint(sin2)\nprint(sin1 is sin2) # True\n\n\n\"\"\"* DIFICULTAD EXTRA (opcional):\n * Utiliza el patrón de diseño \"singleton\" para representar una clase que\n * haga referencia a la sesión de usuario de una aplicación ficticia.\n * La sesión debe permitir asignar un usuario (id, username, nombre y email),\n * recuperar los datos del usuario y borrar los datos de la sesión.\n */\"\"\"\n\nclass UserSession():\n    _instance = None\n\n    def __new__(cls):\n        if cls._instance is None:\n            print(\"Creando nueva sesión de usuario!\")\n            cls._instance = super(UserSession, cls).__new__(cls)\n            # Inicializar el estado de la sesión vacia\n            cls._instance._user_data = None\n        return  cls._instance\n\n    def set_user(self, user_id, username, name, email):\n        self._user_data = {\n            \"id\": user_id,\n            \"username\": username,\n            \"name\": name,\n            \"email\": email,\n            \"is_authenticated\": True\n        }\n        \n        print(f\"Usuario {username} ha iniciado sesión.\")\n        return self._user_data\n    \n    def get_user(self):\n        \"\"\"Método para obtener los datos del usuario\"\"\"\n        if not self._user_data:\n            print(\"No hay ningún usuario en la sesión.\")\n            return None\n        else:\n            return self._user_data\n\n    def is_authenticated(self):\n        \"\"\"Verifica si hay un usuario autenticado en la sesión\"\"\"\n        return self._user_data is not None and self._user_data.get(\"is_authenticated\", False)\n\n    def logout(self):\n        \"\"\"Borra todos los datos de la sesión\"\"\"\n        if self._user_data:\n            username = self._user_data[\"username\"]\n            self._user_data.clear()\n            print(f\"Usuario {username} ha cerrado la sesión\")\n            return True\n        else:\n            return False\n\nif __name__ == \"__main__\":\n\n    # Caso de uso sesión usuario\n    user1 = UserSession()\n    print(\"Usuario Autenticado?:\", user1.is_authenticated())\n\n    # Establecemos un usuario\n    user1.set_user(1, \"johndoe\", \"John Doe\", \"johndoe@fake.com\")\n    print(\"Usuario Autenticado?:\", user1.is_authenticated())\n    print(user1.get_user())\n\n    # Creamos otra instancia de la sesión (DEBE SER LA MISMA)\n    user2 = UserSession()\n    print(\"Sesión 1 es sesión 2?:\", user1 is user2)\n\n    print(\"Usuario en sesion 1:\", user1.get_user()[\"username\"])\n    print(\"Usuario en sesion 2:\", user2.get_user()[\"username\"])\n\n    # Cerramos sesión\n    user2.logout()\n\n    # Verificamos en ambas sesiones\n    print(\"sesion 1 Autenticado?:\", user1.is_authenticated())\n    print(\"sesion 2 Autenticado?:\", user2.is_authenticated())"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/JuanDAW37.py",
    "content": "\"\"\"* EJERCICIO:\n * Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n * con un ejemplo genérico.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el patrón de diseño \"singleton\" para representar una clase que\n * haga referencia a la sesión de usuario de una aplicación ficticia.\n * La sesión debe permitir asignar un usuario (id, username, nombre y email),\n * recuperar los datos del usuario y borrar los datos de la sesión.\"\"\"\n\nfrom tkinter import S\n\nclass Singleton:\n    \n    \"\"\"Creamos un atributo de clase y lo declaramos a nulo.\"\"\"\n    instance = None\n    \n    \"\"\"Constructor de clase\"\"\"\n    def __new__(cls):\n        \"\"\"Si no existe una instancia de la clase, la creamos\n        y la devolvemos. Si ya existe, devolvemos la instancia ya\n        creada.\n        \"\"\"        \n        if not cls.instance:\n            \"\"\"De no existir la instancia, la instanciamos enviando nuestra la\n            clase como instancia de clase usando el contructor __new__.\"\"\"\n            cls.instance = super(Singleton, cls).__new__(cls)\n        return cls.instance\n\nsingleton1 = Singleton()\nprint(singleton1)\nsingleton2 = Singleton()\nprint(singleton2)\n\nclass Session:    \n    instance = None\n    \n    id = None\n    username = None\n    name = None\n    email = None\n    \n    def __new__(session):\n        if not session.instance:            \n            session.instance = super(Session, session).__new__(session)\n        return session.instance\n    \n    def set_user(self, id, username, name, email):\n        self.id = id\n        self.username = username\n        self.name = name\n        self.email = email\n\n    def get_user(self):\n        return self.id, self.username, self.name, self.email\n    \n    def clear_user(self):\n        self.id = None\n        self.username = None\n        self.name = None\n        self.email = None\n\n\"\"\"Login de usuario\"\"\"\nuser = Session()\nprint(user)\nuser.set_user(1, \"Juan\", \"Juan\", \"jymtr1968@gmail.com\")\nprint(user.get_user())\n\n\"\"\"Datos de usuario logueado\"\"\"\nuser2 = Session()\nprint(user2)\nprint(user2.get_user())\n\n\"\"\"Cerrar sesión\"\"\"\nuser3 = Session()\nprint(user3)\nprint(user3.get_user())\nuser3.clear_user()\nprint(user3.get_user())"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/LucasRebuffo.py",
    "content": "from os import name\n\n\nclass Singleton:\n\n    _instance = None\n\n    def __new__(cls):\n        if not cls._instance:\n            cls._instance = super(Singleton, cls).__new__(cls)\n\n        return cls._instance\n\n\nsingleton1 = Singleton()\nprint(singleton1)\nsingleton2 = Singleton()\nprint(singleton2)\n\n\"\"\" Ejrcicio \"\"\"\n\n\nclass Sesion:\n\n    _instance = None\n    id: str = None\n    name: str = None\n    username: str = None\n    email: str = None\n\n    def __new__(cls):\n        if not cls._instance:\n            cls._instance = super(Sesion, cls).__new__(cls)\n\n        return cls._instance\n\n    def set_user(self, id, name, username, email):\n        self.id = id\n        self.name = name\n        self.username = username\n        self.email = email\n\n    def get_user(self):\n        return f\"{self.id},{self.username},{self.name},{self.email}\"\n\n    def clear_user(self):\n        self.id = None\n        self.name = None\n        self.username = None\n        self.email = None\n\n\nsesion1 = Sesion()\n\nsesion1.set_user(\"1\", \"lucas\", \"lucasdev\", \"lucasdev@gmail.com\")\nprint(sesion1.get_user())\n\nsesion2 = Sesion()\nprint(sesion2.get_user())\n\nsesion3 = Sesion()\nsesion3.clear_user()\nprint(sesion3.get_user())\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/LuisOlivaresJ.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n * con un ejemplo genérico.\n\"\"\"\n\nclass Singleton:\n    _instance = None\n    \n    def __new__(cls, *args, **kgargs):\n\n        if cls._instance is None:\n            cls._instance = super().__new__(cls)\n\n        return cls._instance\n    \ns1 = Singleton()\nprint(f\"First instance: {s1}\")\ns2 = Singleton()\nprint(f\"Second instance: {s2}\")\nprint(f\"s1 is s2?: {s1 is s2}\")\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el patrón de diseño \"singleton\" para representar una clase que\n * haga referencia a la sesión de usuario de una aplicación ficticia.\n * La sesión debe permitir asignar un usuario (id, username, nombre y email),\n * recuperar los datos del usuario y borrar los datos de la sesión.\n\"\"\"\n\nclass User:\n    _instance = None\n\n    def __new__(cls, id: str, username: str, name: str, email: str):\n\n        if cls._instance is None:\n\n            cls._instance = super().__new__(cls)\n\n            cls.id = id\n            cls.name = name\n            cls.username = username\n            cls.email = email\n\n        return cls._instance\n    \n\n    # These are instance attributes. If __init__ exist, get_user() method will point to these instance attributes istead the class attributes.\n    \"\"\"\n    def __init__(self, id: str, username: str, name: str, email: str):\n        print(\"Inside init\")\n        self.id = id\n        self.username= username\n        self.name = name\n        self.email = email\n    \"\"\"\n\n\n    def get_user(self):\n        return {\n            \"id\": self.id,\n            \"username\": self.username,\n            \"name\": self.name,\n            \"email\": self.email,\n        }\n    \n    def clean_user(self):\n        User._instance = None\n\n\n###################\n# Testing the class\n###################\n\nprint(\"\")\nprint(\"### Testing: Dificultad extra\\n\")\n\nluis = User(id= \"01\", username=\"LuisOlivares\", name=\"Luis\", email=\"alfonso@dev\")\nprint(f\"User luis: {luis.get_user()}\")\n\nprint(\"Trying to create a new user...\")\nluis2 = User(\"1\", \"2\", \"3\", \"4\")\n\nprint(f\"luis is luis2?: {luis is luis2}\")\n\nprint(f\"User luis: {luis.get_user()}\")\nprint(f\"User luis2: {luis2.get_user()}\")\n\nprint(\"\\nUsing clear_user method...:\\n\")\nluis.clean_user()\noscar = User(\"2\", \"OscarOlivares\", \"Oscar\", \"oscar@Dev\")\nprint(f\"User oscar: {oscar.get_user()}\")\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/Nicojsuarez2.py",
    "content": "# #23 PATRONES DE DISEÑO: SINGLETON\n> #### Dificultad: Media | Publicación: 03/06/24 | Corrección: 10/06/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n * con un ejemplo genérico.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el patrón de diseño \"singleton\" para representar una clase que\n * haga referencia a la sesión de usuario de una aplicación ficticia.\n * La sesión debe permitir asignar un usuario (id, username, nombre y email),\n * recuperar los datos del usuario y borrar los datos de la sesión.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/Pipe281.py",
    "content": "'''\n * EJERCICIO:\n * Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n * con un ejemplo genérico.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el patrón de diseño \"singleton\" para representar una clase que\n * haga referencia a la sesión de usuario de una aplicación ficticia.\n * La sesión debe permitir asignar un usuario (id, username, nombre y email),\n * recuperar los datos del usuario y borrar los datos de la sesión.\n'''\nclass Singleton:\n\n    _instance = None\n\n    def __new__(cls):\n        if not cls._instance:\n            cls._instance = super(Singleton, cls).__new__(cls)\n        return cls._instance\n\n\nsingleton1 = Singleton()\nprint(singleton1)\nsingleton2 = Singleton()\nprint(singleton2)\n\nprint(singleton1 is singleton2)"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/RRcoder.py",
    "content": " EJERCICIO:\n Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n con un ejemplo genérico.\n\n DIFICULTAD EXTRA (opcional):\n Utiliza el patrón de diseño \"singleton\" para representar una clase que\n haga referencia a la sesión de usuario de una aplicación ficticia.\n La sesión debe permitir asignar un usuario (id, username, nombre y email),\n recuperar los datos del usuario y borrar los datos de la sesión.\n\"\"\"\n\nfrom threading import Lock\n\nclass SingletonMeta(type):\n    _instancias = {}\n    _lock: Lock = Lock()\n    def __call__(cls, *args, **kwargs):\n        with cls._lock:\n            if cls not in cls._instancias:\n                instancia = super().__call__(*args, **kwargs)\n                cls._instancias[cls]= instancia\n        return cls._instancias[cls]\n\nclass ContadorSingleton(metaclass=SingletonMeta):\n    valor: int = None\n    def __init__ (self, valor: int):\n        self.valor = valor\n        return None\n    def get(self):\n        return self.valor\n    def incrementar(self):\n        self.valor+=1\n    def decrementar(self):\n        self.valor-=1\nclass SessionSingleton(metaclass=SingletonMeta):\n    id =None\n    username = None\n    nombre = None\n    email = None\n    def __init__(self, id, username, nombre, email):\n        self.id= id\n        self.username= username\n        self.nombre= nombre\n        self.email= email\n    def get_id(self):\n        return self.id\n    def set_id(self, id):\n        self.id = id\n    def get_username(self):\n        return self.username\n    def set_username(self, username):\n        self.username = username\n    def get_nombre(self):\n        return self.nombre\n    def set_nombre(self, nombre):\n        self.nombre = nombre\n    def get_email(self):\n        return self.email\n    def set_email(self, email):\n        self.email = email\n    def delete(self):\n        self.id =None\n        self.username = None\n        self.nombre = None\n        self.email = None\n    def __str__(self):\n        mostrar = \"La session id: {} es del username: {}, nombre:{} email: {}\".format(self.id, self.username, self.nombre, self.email)\n        return mostrar\n\ncontador = ContadorSingleton(10)\nprint(\"el contador tiene: {}\".format(contador.get()))\n\ncontador.decrementar()\n\ncontador2 = ContadorSingleton(20)\nprint(\"contador= {}  y contador2={}\".format(contador.get(), contador2.get()))\n\ncontador2.decrementar()\nprint(\"contador= {}  y contador2={}\".format(contador.get(), contador2.get()))\n\n\ns1=SessionSingleton(5, 'pepe', 'Juan', 'juan@gmail.com')\ns2=SessionSingleton(66, 'thor', 'Thor Pedo', 'thor@gmail.com')\n\nprint(s1)\nprint(s2)\n\n\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/Sac-Corts.py",
    "content": "class Singleton:\n    _instance = None\n\n    def __new__(cls):\n        if not cls._instance:\n            cls._instance = super(Singleton, cls).__new__(cls)\n        return cls._instance\n\nsingleton1 = Singleton()\nprint(singleton1)\nsingleton2 = Singleton()\nprint(singleton2)\n\n### Ejercicio Extra ###\n\nclass UserSession:\n    \n    _instance = None\n    id: int = None\n    username: str = None\n    name: str = None\n    email: str = None\n\n    def __new__(cls):\n        if not cls._instance:\n            cls._instance = super(UserSession, cls).__new__(cls)\n        return cls._instance \n        \n    def set_user(self, id, username, name, email):\n        self.id = id\n        self.username = username\n        self.name = name\n        self.email = email\n\n    def get_user(self):\n        return f\"{self.id}, {self.username}, {self.name}, {self.email}\"\n\n    def clear_user(self):\n        self.id = None\n        self.username = None\n        self.name = None\n        self.email = None\n\nsession1 = UserSession()\nsession1.set_user(1, \"Sac\", \"Isaac Cortés\", \"isaacgeo125@gmail.com\")\nprint(session1.get_user())\n\nsession2 = UserSession()\nprint(session2.get_user())\n\nsession3 = UserSession()\nsession3.clear_user()\nprint(session3.get_user())"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/SooHav.py",
    "content": "# 23 PATRONES DE DISEÑO: SINGLETON\n\n# Ejercicio\n\nclass SingletonMeta(type):\n\n    _instance = None\n\n    def __call__(cls, *args, **kwargs):\n        if cls._instance is None:\n            cls._instance = super().__call__(*args, **kwargs)\n        return cls._instance\n\n\nclass Singleton(metaclass=SingletonMeta):\n    def __init__(self) -> None:\n        super().__init__()\n\n\nif __name__ == '__main__':\n\n    singleton1 = Singleton()\n    singleton2 = Singleton()\n    singleton3 = Singleton()\n\n    print(singleton1 is singleton2)\n    print(singleton1 is singleton3)\n\n\n# Extra\nclass SingletonMeta(type):\n    _instances = {}\n\n    def __call__(cls, *args, **kwargs):\n        if cls not in cls._instances:\n            instance = super().__call__(*args, **kwargs)\n            cls._instances[cls] = instance\n            sesion_instance = instance\n        else:\n            sesion_instance = cls._instances[cls]\n        return sesion_instance\n\n\nclass sesion_usuario(metaclass=SingletonMeta):\n    def __init__(self, id, username, nombre, email):\n        if not hasattr(self, 'inicializada'):\n            self.sesion_instance = {\n                \"id\": id,\n                \"username\": username,\n                \"nombre\": nombre,\n                \"email\": email,\n                \"autenticacion\": False\n            }\n        self.inicializada = True\n\n    def autenticacion(self, password):\n        self.sesion_instance[\"autenticacion\"] = True\n        print(f\"Usuario {self.sesion_instance['username']} autenticado.\")\n\n    def desconexion(self):\n        print(f\"Usuario {self.sesion_instance['username']} desconectado.\")\n        self.sesion_instance[\"id\"] = None\n        self.sesion_instance[\"username\"] = None\n        self.sesion_instance[\"nombre\"] = None\n        self.sesion_instance[\"email\"] = None\n        self.sesion_instance[\"autenticacion\"] = False\n\n    def info_usuario(self):\n        return self.sesion_instance\n\n\n# Ejemplo de uso\nsesion1 = sesion_usuario(\"1\", \"juani\", \"Juan\", \"juan@ejemplo.com\")\n# para corroborar que es una unica instancia\nsesion2 = sesion_usuario(\"2\", \"juanita\", \"juana\", \"juana@ejemplo.com\")\n\nprint(sesion1.info_usuario())\nprint(sesion2.info_usuario())\n\nsesion1.autenticacion(\"password123\")\nprint(sesion1.info_usuario())\n\nsesion1.desconexion()\nprint(sesion1.info_usuario())\nprint(sesion1 is sesion2)\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/Trufoplus.py",
    "content": "###############################################################################\n### EJERCICIO\n###############################################################################\n\n# creamos un decorador singleton para nuestra clase.\n# crear este decorador nos permitira reutilizarlo sin volver a escribir\ndef singleton(cls):\n    \"\"\"\n    Decorador singleton que nos asegurara tener solo una instancia de una clase\n    para aquella clases decoradas\n    \"\"\"\n    __instances = dict() \n    \n    def wrap(*args, **kwargs):\n        if cls not in __instances:\n            __instances[cls] = cls(*args, **kwargs)\n        \n        return __instances[cls]\n    \n    return wrap\n\n@singleton \nclass User():    \n    def __init__(self, username):\n        self.username = username\n    def __str__(self):\n        return self.username\n\n@singleton\nclass Admin():\n    def __init__(self, username):\n        self.username = username\n    def __str__(self):\n        return f'{self.username}(Admin)'\n\n\n# Creamos la primera instancia\ninstance_1 = User('Pepe Grillo')\nprint(f'Usuario = {instance_1}')\n# La segunda instancia no se crea pues ya hay una creada\ninstance_2 = User('Naruto')\nprint(f'Usuario = {instance_1}, Usuario 2 = {instance_2}')\n\n\nadmin_1 = Admin('Vegeta')\nadmin_2 = Admin('Goku')\nprint(f'admin_1 = {admin_1}, admin_2 = {admin_2}')\n\n\n###############################################################################\n### DIFICULTAD EXTRA\n###############################################################################\nprint('\\nDificutad Extra:\\n')\n\n\nclass Session:\n    __instances = dict()\n    \n    def __new__(cls, *args, **kwargs):\n        \"\"\"\n        Garantiza que solo se crea una instancia de la clase\n        \"\"\"\n        if cls not in cls.__instances:\n            cls.__instances[cls] = super().__new__(cls)\n        \n        return cls.__instances[cls]  \n    \n    \n    def __init__(self, id, username, name, email):\n        self.user_data = {\n            'id': id,\n            'username': username,\n            'name': name,\n            'email': email\n        }\n    \n    \n    def __str__(self):\n        \"\"\"\n        Imprime informacion del usuario\n        \"\"\"\n        if self.user_data:\n            return f\"id:{self.user_data['id']}\\nusername:{self.user_data['username']}\\nname:{self.user_data['name']}\\nemail:{self.user_data['email']}\"\n        else:\n            return \"Datos de usuario vacio.\"\n    \n    \n    def delete_session(self):\n        \"\"\"\n        borra los datos del usuario y elimina la instancia\n        \"\"\"\n        self.user_data = {}\n        del Session.__instances[self.__class__]\n    \n    \n    def __del__(self):\n        \"\"\"\n        Impremie mensaje despues de eliminar un objeto\n        \"\"\"\n        print('Las sesion a sido eliminada')\n\n\n\n# Creamos instancia con los datos de usuario\nsession_1 = Session(2, 'vegetta777', 'fran', 'fran@gmail.com')\n\n# Obtenemos los datos del usuario\nprint(\"Datos del usuario:\")\nprint(session_1)\n\n# Borramos los datos del usuario\nsession_1.delete_session()\n\n# Intentamos acceder a los datos del usuario\nprint(\"\\nDespués de borrar la sesión:\")\nprint(session_1)\n\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/adra-dev.py",
    "content": "\"\"\"\nEJERCICIO:\nExplora el patrón de diseño \"singleton\" y muestra cómo crearlo con un\nejemplo genérico.\n\nDIFICULTAD EXTRA(opcional):\nUtiliza el patrón de diseño \"singleton\" para representar una clase \nque haga referencia a la sesión de usuario de una aplicación ficticia.\nLa sesión debe permitir asignar un usuario (id, username, nombre y \nemail), recuperar los datos del ususario y borrar los datos de la \nsesión.sesión\n\nby adra-dev\n\"\"\"\n\n\"\"\"\nEJERCICIO:\n\"\"\"\n\n\n\"\"\"\n¿Qué es un patrón de diseño?:\n    Los patrones de diseño son soluciones habituales a problemas que \n    ocurren con frecuencia en el diseño de software. Son como planos \n    prefabricados que se pueden personalizar para resolver un \n    problema de diseño recurrente en tu código.\n\n    url: https://refactoring.guru/es/design-patterns/what-is-pattern \n\"\"\"\n\n\"\"\"\nSingleton: Es un patrón de diseño creacional que nos permite \nasegurarnos de que una clase tenga una única instancia, a la vez que \nproporciona un punto de acceso global a dicha instancia.\n\"\"\"\n\nclass SingletonMeta(type):\n    \"\"\"\n    The Singleton class can be implemented in different ways in Python. Some\n    possible methods include: base class, decorator, metaclass. We will use the\n    metaclass because it is best suited for this purpose.\n    \"\"\"\n\n    _instances = {}\n\n    def __call__(cls, *args, **kwargs):\n        \"\"\"\n        Possible changes to the value of the `__init__` argument do not affect\n        the returned instance.\n        \"\"\"\n        if cls not in cls._instances:\n            instance = super().__call__(*args, **kwargs)\n            cls._instances[cls] = instance\n        return cls._instances[cls]\n\n\nclass Singleton(metaclass=SingletonMeta):\n    def some_business_logic(self):\n        \"\"\"\n        Finally, any singleton should define some business logic, which can be\n        executed on its instance.\n        \"\"\"\n\n        # ...\n\n\nif __name__ == \"__main__\":\n    # The client code.\n\n    s1 = Singleton()\n    s2 = Singleton()\n\n    if id(s1) == id(s2):\n        print(\"Singleton works, both variables contain the same instance.\")\n    else:\n        print(\"Singleton failed, variables contain different instances.\")\n\n\n\"\"\"\nExtra\n\"\"\"\n\nclass UserSession:\n    \n    _instance = None\n\n    id: int = None\n    username: str = None\n    name: str = None\n    email: str = None\n\n    def __new__(cls):\n        if not cls._instance:\n            cls._instance = super(UserSession, cls).__new__(cls)\n        return cls._instance\n    \n\n    def set_user(self, id, username, name, email):\n        self.id = id\n        self.username = username\n        self.name = name\n        self.email = email\n\n    def get_user(self):\n        return f\"{self.id}, {self.username}, {self.name}, {self.email},\"\n\n    def clear_user(self):\n        self.id = None\n        self.username = None\n        self.name = None\n        self.email = None\n\nsession1 = UserSession()\nprint(session1.get_user())\nsession1.set_user(1, \"adra-dev\", \"Adrian R\", \"aralfaro98@gmail.com\")\nprint(session1.get_user())\n\nsession2 = UserSession()\nprint(session2.get_user())\n\nsession3 = UserSession()\nsession3.clear_user()\nprint(session3.get_user())\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/agusrosero.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n * con un ejemplo genérico.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el patrón de diseño \"singleton\" para representar una clase que\n * haga referencia a la sesión de usuario de una aplicación ficticia.\n * La sesión debe permitir asignar un usuario (id, username, nombre y email),\n * recuperar los datos del usuario y borrar los datos de la sesión.\n */\n\"\"\"\n\n# EJERCICIO:\n\n\nclass Singleton:\n    _instancia = None\n\n    def __new__(cls):\n        if cls._instancia is None:\n            cls._instancia = super(Singleton, cls).__new__(cls)\n        return cls._instancia\n\n\nsingleton1 = Singleton()\nsingleton2 = Singleton()\n\nprint(singleton1 is singleton2)\n\n# DIFICULTAD EXTRA:\n\n\nclass Sesion:\n    _id = \"\"\n    _username = \"\"\n    _nombre = \"\"\n    _email = \"\"\n\n    def __init__(self, id, username, nombre, email):\n        self._id = id\n        self._username = username\n        self._nombre = nombre\n        self._email = email\n\n    def get_id(self):\n        return self._id\n\n    def get_username(self):\n        return self._username\n\n    def get_name(self):\n        return self._nombre\n\n    def get_email(self):\n        return self._email\n\n    def delete_data(self):\n        self._id = \"\"\n        self._username = \"\"\n        self._nombre = \"\"\n        self._email = \"\"\n        return self\n\n\nsesion1 = Sesion(id=\"1\", username=\"test1\",\n                 nombre=\"Agustin\", email=\"test@gmail.com\")\n\nprint(f\"User: {sesion1.get_username()}\")\nprint(f\"Eliminando datos: {sesion1.delete_data()}\")\nprint(f\"User id: {sesion1.get_id()}\")\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/alanshakir.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n * con un ejemplo genérico.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el patrón de diseño \"singleton\" para representar una clase que\n * haga referencia a la sesión de usuario de una aplicación ficticia.\n * La sesión debe permitir asignar un usuario (id, username, nombre y email),\n * recuperar los datos del usuario y borrar los datos de la sesión.\n */\n\"\"\"\n\nfrom typing import Any\n\n\nclass Singleton:\n    class __Singleton:\n        def __init__(self) -> None:\n            self.nombre = None\n    \n        def __str__(self):\n            return f\"{self.nombre}\"\n        \n    instance = None\n\n    def __new__(cls):\n        if not Singleton.instance:\n            Singleton.instance = Singleton.__Singleton()\n        return Singleton.instance\n    \n    \nmy_singleton = Singleton()\nmy_singleton.nombre = \"Alan Ramirez\"\nprint(my_singleton)\n\n# Extra\nclass UserSession:\n    _instance = None\n    id = None\n    username = None\n    nombre = None\n    email = None\n\n    def __new__(cls):\n        if not cls._instance:\n            cls._instance = super(UserSession, cls).__new__(cls)\n        return cls._instance\n    \n                \n    def setuser(self, id, username, nombre, email):\n        self.id = id\n        self.username = username\n        self.nombre = nombre\n        self.email = email        \n        \n    def getuser(self):\n        return f\"Sesion: {self.id}, {self.username}, {self.nombre}, {self.email}\"\n    \n    def clearuser(self):\n        self.id = None\n        self.username = None\n        self.nombre = None\n        self.email = None\n        \n    \nmy_usersession = UserSession()\nmy_usersession.setuser(1, \"alanshakir\", \"alan Ramirez\", \"alan2085@gmail.com\")\nprint(my_usersession.getuser())\nmy_usersession.clearuser()\nprint(my_usersession.getuser())\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/avcenal.py",
    "content": "\"\"\"\nEJERCICIO:\n * Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n * con un ejemplo genérico.\n\"\"\"\n\nclass Singleton (object):\n    instance = None       \n    def __new__(cls): \n        if cls.instance is None:\n            print(\"Creo la instancia\")\n            cls.instance = object.__new__(cls)\n            #sin añadir object que es algo que en Python 3 no es necesario, sería cls.instance = super(Singleton,cls).__new__(cls)\n        else:\n            print(\"No creo la instancia\")\n        return cls.instance\n\ntest = Singleton()\ntest2 = Singleton()\n\nprint(test == test2)\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n * Utiliza el patrón de diseño \"singleton\" para representar una clase que\n * haga referencia a la sesión de usuario de una aplicación ficticia.\n * La sesión debe permitir asignar un usuario (id, username, nombre y email),\n * recuperar los datos del usuario y borrar los datos de la sesión.\n\"\"\"\n\nclass Session():\n    instance = None\n\n    id: int = 0\n    username:str = None\n    name:str = None\n    email:str = None\n\n    def __new__(cls): \n        if cls.instance is None:\n            cls.instance = super().__new__(cls)\n\n        return cls.instance\n    \n    def set_user(self,id:int,username:str,name:str,email:str):\n        self.id = id\n        self.username = username\n        self.name = name\n        self.email = email\n\n    def get_data(self):\n        print(f\"- ID: {self.id}\\n- Username: {self.username}\\n- Nombre: {self.name}\\n- Email: {self.email}\")\n\n    def erase_data(self):\n            self.id = 0\n            self.username = None\n            self.name = None\n            self.email = None\n            print(f\"Usuario borrado\")\n\n\nmy_session = Session()\nmy_session.set_user(117,\"avcenal\",\"Alex Valderrama\",\"a@a.com\")\nmy_session.get_data()\nmy_session_2 = Session() #No crea la instancia con estos datos\nmy_session_2.get_data()\nmy_session_2.erase_data()\nmy_session.get_data()\n\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/barrancus.py",
    "content": "#23 - Python\n# \n# EJERCICIO:\n# Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n# con un ejemplo genérico.\n# \n# DIFICULTAD EXTRA (opcional):\n# Utiliza el patrón de diseño \"singleton\" para representar una clase que\n# haga referencia a la sesión de usuario de una aplicación ficticia.\n# La sesión debe permitir asignar un usuario (id, username, nombre y email),\n# recuperar los datos del usuario y borrar los datos de la sesión.\n# \nclass Counter:\n    def __iter__(self):\n        self.a = 1\n        return self\n    \n    def __next__(self):\n        x = self.a\n        self.a += 1\n        return x\n\ndef serparacion(cadena) -> str:\n    global contador\n    print(f'\\nEjercicio {next(contador)}. {cadena * 20}')\n\ncontador = iter(Counter())\n\nclass Singleton:\n    _instances = {}\n    \n    def __new__(cls, *args, **kwargs):\n        if cls not in cls._instances:\n            cls._instances[cls] = super().__new__(cls)\n        return cls._instances[cls]\n    \nclass Logger(Singleton):\n    def log(self, message):\n        print(f\"LOG: {message}\")\n\nclass UserSession(Singleton):\n\n    def __init__(self):\n        if not hasattr(self, 'user'):\n            self.user = None\n\n    def set_user(self, user_id, username, name, email):\n        self.user = {\n            'id': user_id,\n            'username': username,\n            'name': name,\n            'email': email\n        }\n\n    def get_user(self):\n        return self.user\n\n    def clear_session(self):\n        self.user = None\n\ndef excercise_singleton() -> None:\n    serparacion('-:-')\n    \n    # Primera vez que se crea una instancia\n    logger1 = Logger()\n    logger1.log(\"Este es el primer mensaje\")\n\n    # Se crea otra instancia, pero se devuelve la misma que la primera\n    logger2 = Logger()\n    logger2.log(\"Este es el segundo mensaje\")\n\n    # Se verifica que ambas variables apuntan a la misma instancia\n    print(f'Es logger1 = logger2: {logger1 is logger2}')  # Imprime: True\n\ndef extra_user_session() -> None:\n    serparacion('-:-')\n    \n    # Crear una sesión de usuario\n    print('\\nCreando sesión de usuario...')\n    session1 = UserSession()\n    session1.set_user(1, 'jdoe', 'John Doe', 'jdoe@mail.com')\n    print(f'Usuario en session: {session1.get_user()}')\n    # Crear otra sesión de usuario\n    print('\\nCreando otra sesión de usuario...')\n    session2 = UserSession()\n    session2.set_user(2, 'mkart', 'Mikael Kart', 'mkart@mail.com')\n    print(f'Usuario en session2 antes de borrar: {session2.get_user()}')\n    # Verificar que ambas sesiones son la misma instancia\n    print(f'\\nEs session1 = session2: {session1 is session2}')  # Imprime: True\n    # Borrar la sesión de usuario\n    session2.clear_session()\n    print('\\nBorrando sesión de usuario...')\n    print(f'Usuario en session1: {session1.get_user()}')\n    print(f'Usuario en session2: {session2.get_user()}')\n    \n    \ndef main():\n    excercise_singleton()\n    extra_user_session()\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/cristianfloyd.py",
    "content": "# EJERCICIO:\n# Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n# con un ejemplo genérico.\nfrom typing import Optional\n\n\nclass Singleton:\n    _instance = None\n\n    def __new__(cls, name: Optional[str] = None):\n        if cls._instance is None:\n            if name is None:\n                raise ValueError(\"El primer Singleton debe tener un nombre\")\n            cls._instance = super(Singleton, cls).__new__(cls)\n            cls._instance.name = name\n        elif name is not None:\n            raise ValueError(\n                \"El Singleton ya esta inicializado, no puedes pasar nuevos parametros\"\n            )\n        return cls._instance\n\n    def __init__(self, name: Optional[str] = None):\n        pass  # la inicializacion se hace en __new__\n\n    def get_name(self):\n        return self.name\n\n    def set_name(self, name):\n        self.name = name\n\n    def __str__(self):\n        return f\"Singleton instance: {self.name}\"\n\n\nsingleton = Singleton(name=\"Cristian Floyd\")\nprint(singleton.get_name())\nprint(singleton)\nsingleton2 = Singleton()\nprint(f\"Singleton2 nombre: {singleton2.get_name()}\")\nprint(f\"¿Son la misma instancia? {singleton is singleton2}\")\n\n\n#\n# DIFICULTAD EXTRA (opcional):\n# Utiliza el patrón de diseño \"singleton\" para representar una clase que\n# haga referencia a la sesión de usuario de una aplicación ficticia.\n# La sesión debe permitir asignar un usuario (id, username, nombre y email),\n# recuperar los datos del usuario y borrar los datos de la sesión.\n\n\nclass UserSession:\n    \"\"\"\n    Clase que representa la sesión de usuario de una aplicación ficticia.\n    \"\"\"\n    _instance = None\n    \n    def __new__(cls):\n        if cls._instance is None:\n            cls._instance = super(UserSession, cls).__new__(cls)\n            cls._instance._initialized = False\n        return cls._instance\n    \n    def __init__(self) -> None:\n        # inicializar solo una vez\n        if not self._initialized:\n            self._initialized = True\n            self.id = None\n            self.username = None\n            self.name = None\n            self.email = None\n        \n    def set_user(self, id, username, name, email):\n        self.id = id\n        self.username = username\n        self.name = name\n        self.email = email\n\n    def get_user(self):\n        return {\n            \"id\": self.id,\n            \"username\": self.username,\n            \"name\": self.name,\n            \"email\": self.email\n        }\n\n    def clear_session(self):\n        self.id = None\n        self.username = None\n        self.name = None\n        self.email = None\n        print(\"Sesión limpiada\")\n\n    def is_active(self):\n        \"\"\"\n        Verifica si la sesión está activa.\n        \"\"\"\n        return self.id is not None\n\nif __name__ == \"__main__\":\n    # Primera instancia\n    session1 = UserSession()\n    session1.set_user(1, \"cristianfloyd\", \"Cristian Floyd\", \"cristian@example.com\")\n    \n    # Segunda \"instancia\" (realmente es la misma)\n    session2 = UserSession()\n    \n    # Verificar que son la misma instancia\n    print(f\"¿Son la misma instancia? {session1 is session2}\")  # True\n    \n    # Los datos están disponibles desde cualquier referencia\n    print(f\"Datos desde session2: {session2.get_user()}\")\n    \n    # Limpiar sesión\n    session1.clear_session()\n    print(f\"Sesión activa: {session2.is_active()}\")  # False"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/cyberdidac.py",
    "content": "import random\n\n\nclass Session:\n    _instance = None\n\n    def __new__(cls, *args, **kwargs):\n        if cls._instance is None:\n            cls._instance = super(Session, cls).__new__(cls)\n            cls._instance.__init__(*args, **kwargs)\n        return cls._instance\n\n    def __init__(self, id=None, username=None, name=None, email=None):\n        if not hasattr(self, 'id'):\n            self.id = id\n        if not hasattr(self, 'username'):\n            self.username = username\n        if not hasattr(self, 'name'):\n            self.name = name\n        if not hasattr(self, 'email'):\n            self.email = email\n\n    @classmethod\n    def clear_session(cls):\n        cls._instance = None\n\n\ndef main():\n    print(\"Iniciando sesión...\")\n    name = input(\"Nombre: \")\n    username = input(\"Username: \")\n    email = input(\"Email: \")\n\n    session = Session(random.randint(1, 1000), username, name, email)\n\n    quit = False\n\n    while not quit:\n        print(\"\\nSeleccione una opción: \"\n              \"\\n1- Ver datos de sesión\"\n              \"\\n2- Borrar sesión\\n\")\n\n        choice = input(\"> \")\n\n        match choice:\n            case \"1\":\n                print(f\"Id: {session.id}\")\n                print(f\"Username: {session.username}\")\n                print(f\"Name: {session.name}\")\n                print(f\"Email: {session.email}\")\n            case \"2\":\n                Session.clear_session()\n                quit = True\n                print(\"Hasta pronto\")\n            case _:\n                print(\"Opción no válida\")\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/davidrguez98.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n * con un ejemplo genérico.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el patrón de diseño \"singleton\" para representar una clase que\n * haga referencia a la sesión de usuario de una aplicación ficticia.\n * La sesión debe permitir asignar un usuario (id, username, nombre y email),\n * recuperar los datos del usuario y borrar los datos de la sesión.\n */ \"\"\"\n\n#EJERCICIO\n\nclass Singleton:\n\n    _instance = None\n\n    def __new__(cls):\n        if not cls._instance:\n            cls._instance = super(Singleton, cls).__new__(cls)\n        \n        return  cls._instance\n    \nSingleton1 = Singleton()\nprint(Singleton1)\nSingleton2 = Singleton()\nprint(Singleton2)\n\nprint(Singleton1 is Singleton2)\n\n#DIFICULTAD EXTRA\n\nclass user:\n\n    instance = None\n\n    id: int = None\n    username: str = None\n    name: str = None\n    email: str = None\n\n    def __new__(cls):\n        if not cls.instance:\n            cls.instance = super(user, cls).__new__(cls)\n        \n        return  cls.instance\n    \n    def set_user(self, id, username, name, email):\n\n        self.id = id\n        self.username = username\n        self.name = name\n        self.email = email\n\n    def get_user(self):\n        return f\"{self.id}, {self.username}, {self.name}, {self.email}\"\n    \n    def clear_user(self):\n        self.id = None\n        self.username = None\n        self.name = None\n        self.email = None\n\nsession1 = user()\nsession1.set_user(00, \"davidrguez98\", \"David Rodríguez\", \"david@gmail.com\")\nprint(session1.get_user())\n\nsession2 = user()\nprint(session2.get_user())\n\nsession3 = user()\nsession3.clear_user()\nprint(session3.get_user())"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/duendeintemporal.py",
    "content": "#23 { Retos para Programadores } PATRONES DE DISEÑO: SINGLETON\n\n# Bibliography reference\n# I use GPT as a reference and sometimes to correct or generate proper comments.\n\n\"\"\"  \n * EJERCICIO:\n * Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n * con un ejemplo genérico.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el patrón de diseño \"singleton\" para representar una clase que\n * haga referencia a la sesión de usuario de una aplicación ficticia.\n * La sesión debe permitir asignar un usuario (id, username, nombre y email),\n * recuperar los datos del usuario y borrar los datos de la sesión.\n\n\"\"\"\n\nlog = print\nlog('Retos para Programadores #23')\n\n# The Singleton design pattern ensures that a class has a single instance\n# and provides a global point of access to that instance. Below, I will show\n# you how to implement the Singleton pattern in Python, followed by an example\n# that represents a class for managing user sessions.\n\n# Implementation of the Singleton Pattern\n\nclass Singleton:\n    _instance = None  # Class variable to hold the single instance\n\n    def __new__(cls):\n        if cls._instance is None:\n            cls._instance = super(Singleton, cls).__new__(cls)\n            # Initialize any properties you need here\n        return cls._instance\n\n    # Example method\n    def some_method(self):\n        print(\"This is a method of the singleton.\")\n\n# Using the Singleton\ninstance1 = Singleton()\ninstance2 = Singleton()\n\n# Note: both variables point to the same instance\nlog(instance1.some_method()) # This is a method of the singleton.\nlog(instance1 is instance2)  # True\n\n# EXTRA DIFFICULTY EXERCISE\n\nclass UserSession:\n    _instance = None  # Class variable to hold the single instance\n\n    def __new__(cls):\n        if cls._instance is None:\n            cls._instance = super(UserSession, cls).__new__(cls)\n            cls._instance.user = None  # Initialize user property\n        return cls._instance\n\n    def set_user(self, id, username, name, email):\n        self.user = {'id': id, 'username': username, 'name': name, 'email': email}\n\n    def get_user(self):\n        return self.user\n\n    def clear_session(self):\n        self.user = None\n\n# Example usage of UserSession\nsession1 = UserSession()\nsession1.set_user(1, 'FritzCat', 'Fritz Cat', 'fritzcat@proton.me')\n\nlog(session1.get_user())  # {'id': 1, 'username': 'FritzCat', 'name': 'Fritz Cat', 'email': 'fritzcat@proton.me'}\n\nsession2 = UserSession()\nlog(session2.get_user())  # {'id': 1, 'username': 'FritzCat', 'name': 'Fritz Cat', 'email': 'fritzcat@proton.me'}\n\nsession2.clear_session()\nlog(session1.get_user())  \n    \n    # Note: \n\"\"\"  \nWhen you call session2.clear_session(), it sets the user attribute to None. Since both session1 and session2 refer to the same instance, calling session1.get_user() afterward will also return None.\n\n\"\"\"\n\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/fborjalv.py",
    "content": "\n\"\"\"\n/*\n * EJERCICIO:\n * Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n * con un ejemplo genérico.\n *\n\"\"\"\n\nclass Singleton():\n    \n    _instance = None\n\n    def __new__(cls):\n        if not cls._instance:\n            cls._instance = super(Singleton, cls).__new__(cls)\n        return cls._instance\n\nclass SonSingleton(Singleton):\n    pass\n\nmy_singleton1 = Singleton()\nmy_singleton2 = Singleton()\nmy_singleton3 = SonSingleton()\nprint(my_singleton1)\nprint(my_singleton2)\nprint(my_singleton3)\n\n\"\"\"\n\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el patrón de diseño \"singleton\" para representar una clase que\n * haga referencia a la sesión de usuario de una aplicación ficticia.\n * La sesión debe permitir asignar un usuario (id, username, nombre y email),\n * recuperar los datos del usuario y borrar los datos de la sesión.\n */\n\n\"\"\"\n\nclass UserSession: \n\n    id = None\n    username = None\n    nombre = None\n    email = None\n    _instance = None\n\n    def __new__(cls):\n        if not cls._instance:\n            cls._instance = super(UserSession, cls).__new__(cls)\n        return cls._instance\n\n    def new_user(self, id, username, nombre, email):\n        self.id = id\n        self.username = username\n        self.nombre = nombre\n        self.email = email\n    def show_data_user(self):\n        print(f\"{self.id , self.username, self.nombre, self.email}\")\n\n    def clean_data(self):\n        self.id = None\n        self.username = None\n        self.nombre = None\n        self.email = None\n        \n\n\n\nsession1 = UserSession()\nsession2 = UserSession()\nprint(session1)\nprint(session2)\n\nsession3 = UserSession()\nsession3.new_user(1, \"fborjalv\", \"Borja\", \"xxxxx@gmail.com\")\nsession3.show_data_user()\nsession3.clean_data()\n\nsession4 = UserSession()\nsession4.show_data_user()\n\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/franxiscodev.py",
    "content": "'''\nPatrones de diseño\nSINGLETON\nCompartir una misma instancia de un objeto\nejemplo al llamar la sesión de usuario\n'''\n\n\nclass My_Singleton:\n    _my_instance = None\n\n    def __new__(cls):\n        if not cls._my_instance:\n            cls._my_instance = super(My_Singleton, cls).__new__(cls)\n\n        return cls._my_instance\n\n\nsingleton1 = My_Singleton()\nsingleton2 = My_Singleton()\nprint(singleton1 is singleton2)\n\n\n'''\nExtra\n'''\n\n\nclass UserSession:\n\n    _instance = None\n\n    id: int = None\n    username: str = None\n    name: str = None\n    email: str = None\n\n    def __new__(cls):\n        if not cls._instance:\n            cls._instance = super(UserSession, cls).__new__(cls)\n\n        return cls._instance\n\n    def set_user(self, id, username, name, email):\n        self.id = id\n        self.username = username\n        self.name = name\n        self.email = email\n\n    def get_user(self):\n        return f\"{self.id},{self.username},{self.name},{self.email}\"\n\n    def clear_user(self):\n        self.id: int = None\n        self.username: str = None\n        self.name: str = None\n        self.email: str = None\n\n\nsession1 = UserSession()\nsession1.set_user(11, \"franxiscodev\", \"Francisco A R\",\n                  \"franxiscodev@gmail.com\")\nprint(session1.get_user())\n\n# simular navegación\nsession2 = UserSession()\n\nprint(session2.get_user())\n\n# logout\nsession3 = UserSession()\nsession3.clear_user()\nprint(session1.get_user())\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/ggilperez.py",
    "content": "# Singleton\nfrom dataclasses import dataclass\n\n\n# With Class method\nclass MySingleton:\n    __instance = None\n\n    @classmethod\n    def build(cls, *args, **kwargs):\n        if cls.__instance is not None:\n            return cls.__instance\n\n        cls.__instance = cls(*args, **kwargs)\n        return cls.__instance\n\n    def __init__(self, *args, **kwargs):\n        self.args = args\n        self.kwargs = kwargs\n\n\nobj1 = MySingleton.build(1, 2, 3, one=1, two=2, three=3)\nprint(f\"{obj1.__dict__ = }\")\n\nobj2 = MySingleton.build(4, 5, 6)\nprint(f\"{obj2.__dict__ = }\")\nprint(f\"{obj1.__dict__ = }\")\n\nprint(f\"{obj1 is obj2 = }\")\nprint(\"__innit__ doesnt call again on second build, so gets old data\")\n\nprint()\nprint()\n\n\nclass MyOtherSingleton:\n    __instance = None\n\n    def __new__(cls, *args, **kwargs):\n        if cls.__instance is not None:\n            return cls.__instance\n\n        cls.__instance = super(MyOtherSingleton, cls).__new__(cls)\n        return cls.__instance\n\n    def __init__(self, *args, **kwargs):\n        self.args = args\n        self.kwargs = kwargs\n\n\nobj1 = MyOtherSingleton(1, 2, 3, one=1, two=2, three=3)\nprint(f\"{obj1.__dict__ = }\")\n\nobj2 = MyOtherSingleton(4, 5, 6)\nprint(f\"{obj2.__dict__ = }\")\nprint(f\"{obj1.__dict__ = }\")\n\nprint(f\"{obj1 is obj2 = }\")\nprint(\"__innit__ called again on second build, so gets new data\")\n\n\n# EXTRA\nclass Singleton(type):\n    _instances = {}\n\n    def __call__(cls, *args, **kwargs):\n        if cls not in cls._instances:\n            cls._instances[cls] = super().__call__(*args, **kwargs)\n        return cls._instances[cls]\n\n\n@dataclass()\nclass Session(metaclass=Singleton):\n    id: int\n    username: str\n    name: str\n    email: str\n\n    def asign__user(self, id, username, name, email):\n        self.id = id\n        self.username = username\n        self.name = name\n        self.email = email\n\n    def recover(self):\n        print(self.__dict__)\n\n    def clean(self):\n        self.id = None\n        self.username = None\n        self.name = None\n        self.email = None\n\n\nsession = Session(1, \"ggilperez\", \"Guillermo\", \"ggilperezalcazar@gmail.com\")\nsession.recover()\nsession.clean()\nsession.recover()\n\nsession2 = Session(2, \"mouredev\", \"Brais\", \"mouredev@gmail.com\")\nsession2.recover()\nprint(\"With singleton as metaclass, innit is not called again so new values are not set\")\nsession2.asign__user(2, \"mouredev\", \"Brais\", \"mouredev@gmail.com\")\nsession2.recover()\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/gringoam.py",
    "content": "\"\"\"\nEjercicio\n\"\"\"\n\nclass Singleton:\n    _instancia= None\n\n    def __new__(cls):\n        if not cls._instancia:\n            cls._instancia= super(Singleton, cls).__new__(cls)\n        return cls._instancia\n    \nsingleton1= Singleton()\nprint(singleton1)\nsingleton2=Singleton()\nprint(singleton2)\n\n\nclass Sesion:\n    _instancia= None\n    id=None\n    nombre_usuario=None\n    nombre= None\n    email=None\n            \n    def __new__(cls):\n        if not cls._instancia:\n            cls._instancia= super(Sesion, cls).__new__(cls)\n            \n        return cls._instancia\n    \n    def cargar_usuario(self, id, nombre_usurio, nombre, email):\n        self.id=id\n        self.nombre_usuario=nombre_usurio\n        self.nombre=nombre\n        self.email= email\n\n    def obter_datos_usuario(self):\n        print(f\"id: {self.id} usuario: {self.nombre_usuario} nombre: {self.nombre} email: {self.email}\")\n\n    def cerrar_sesion(self):\n        self.cargar_usuario_instancia= None\n        self.id=None\n        self.nombre_usuario=None\n        self.nombre= None\n        self.email=None\n\nsesion1=Sesion()\n\nsesion1.cargar_usuario(1, \"gringoam\",\"Diego\", \"diego@gemil.com\")\nsesion1.obter_datos_usuario()\nsesion1.cerrar_sesion()\nsesion1.obter_datos_usuario()\n\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/h4ckxel.py",
    "content": "# ╔═════════════════════════════════════╗\n# ║ Autor:  h4ckxel                     ║\n# ║ GitHub: https://github.com/h4ckxel  ║\n# ║ 2024 -  Python                      ║\n# ╚═════════════════════════════════════╝\n\n# -----------------------------------\n# * PATRONES DE DISEÑO: SINGLETON\n# -----------------------------------\n\n\"\"\"\n* EJERCICIO #1:\n* Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n* con un ejemplo genérico.\n\"\"\"\n\nclass Singleton:\n    __instance = None\n\n    def __new__(cls):\n        if cls.__instance is None:\n            cls.__instance = super().__new__(cls)\n        return cls.__instance\n\nsingleton1 = Singleton()\n# singleton2 accede a la misma instancia que singleton1.\nsingleton2 = Singleton()\nprint(singleton1 is singleton2)\n\n\"\"\"\n* EJERCICIO #2:\n* Utiliza el patrón de diseño \"singleton\" para representar una clase que\n* haga referencia a la sesión de usuario de una aplicación ficticia.\n* La sesión debe permitir asignar un usuario (id, username, nombre y email),\n* recuperar los datos del usuario y borrar los datos de la sesión.\n\"\"\"\n\nclass UserSession:\n    __instance = None\n    __user_id: int = None\n    __user_name: str = None\n    __name: str = None\n    __email: str = None\n\n    def __new__(cls):\n        if cls.__instance is None:\n            cls.__instance = super().__new__(cls)\n        return cls.__instance\n\n    def set_user(self, user_id, user_name, name, email):\n        self.__user_id = user_id\n        self.__user_name = user_name\n        self.__name = name\n        self.__email = email\n\n    def get_user(self) -> dict:\n        return {\n            \"id\": self.__user_id,\n            \"username\": self.__user_name,\n            \"name\": self.__name,\n            \"email\": self.__email\n        }\n    \n    def logout(self):\n        self.__instance = None\n        self.__user_id = None\n        self.__user_name = None\n        self.__name = None\n        self.__email = None\n\nlogin_user1 = UserSession()\nlogin_user1.set_user(1, \"Zoe_1\", \"Zoe\", \"Zoe@gm.com\")\nprint(login_user1.get_user())\nlogin_user1.logout()\n\nlogin_user2 = UserSession()\nlogin_user2.set_user(1, \"Ben_1\", \"Ben\", \"Ben@gm.com\")\nprint(login_user2.get_user())\nlogin_user2.logout()\n\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/hectorio23.py",
    "content": "# Autor: Héctor Adán\n# GitHub: https://github.com/hectorio23\n\n'''\n- EJERCICIO:\nExplora el patrón de diseño \"singleton\" y muestra cómo crearlo\ncon un ejemplo genérico.\n\n- DIFICULTAD EXTRA (opcional):\nUtiliza el patrón de diseño \"singleton\" para representar una clase que\nhaga referencia a la sesión de usuario de una aplicación ficticia.\nLa sesión debe permitir asignar un usuario (id, username, nombre y email),\nrecuperar los datos del usuario y borrar los datos de la sesión.\n'''\n\n##################################################\n################# EJERCICIO 1 ####################\n##################################################\n\nclass Not_Duplicity:\n    _instance = { }\n\n    def __new__(cls):\n        if cls._instance is None:\n            cls._instance = super().__new__(cls)\n        \n        return cls._instance\n\nobj1 = Not_Duplicity()\nobj2 = Not_Duplicity()\n\nprint(f\"ID Objeto 1 => { id(obj1) }\")\nprint(f\"ID Objeto 2 => { id(obj2) }\")\nprint(f\"¿Los objetos 1 y dos son iguales? { id(obj1) == id(obj2) }\")\n\nprint(\"\\n********************************\\n\")\n\n\n##################################################\n############### EJERCICIO EXTRA ##################\n##################################################\n\nclass UserSession:\n    _instance = None\n    _user_data = None\n\n    def __new__(cls):\n        if cls._instance is None:\n            cls._instance = super(UserSession, cls).__new__(cls)\n        return cls._instance\n\n    def set_user(self, user_id, username, name, email):\n        self._user_data = {\n            'id': user_id,\n            'username': username,\n            'name': name,\n            'email': email\n        }\n\n    def get_user(self):\n        return self._user_data\n\n    def clear_user(self):\n        self._user_data = None\n\n# Ejemplo de uso:\nsession = UserSession()\nsession.set_user(1, 'hectorio23', 'Adán', 'adan_example@example.com')\n\nprint(session.get_user())  # Muestra los datos del usuario\n\nsession.clear_user()\n\nprint(session.get_user())  # Muestra None, ya que los datos han sido borrados\n\n# Verificación de singleton:\nanother_session = UserSession()\nprint(session is another_session)  # True, ambas variables apuntan a la misma instancia\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/hozlucas28.py",
    "content": "# pylint: disable=pointless-string-statement,missing-class-docstring,missing-function-docstring\n\n\"\"\"\n    Singleton pattern...\n\"\"\"\n\nfrom typing import Any, Self\n\n\nprint(\"Singleton pattern...\")\n\n\nclass SingletonMeta(type):\n    __instances: dict[Any, Any] = {}\n\n    def __call__(cls, *args: Any, **kwds: Any) -> Any:\n        if cls not in cls.__instances:\n            instance: Any = super().__call__(*args, **kwds)\n            cls.__instances[cls] = instance\n\n        return cls.__instances[cls]\n\n\nclass Counter(metaclass=SingletonMeta):\n    def __init__(self) -> None:\n        self.__count: int = 0\n\n    def get_count(self) -> int:\n        return self.__count\n\n    def increment(self) -> Self:\n        self.__count += 1\n        return self\n\n    def decrement(self) -> Self:\n        self.__count -= 1\n        return self\n\n\ncounter_01: Counter = Counter()\ncounter_02: Counter = Counter()\n\nprint(\n    \"\\nAre `counter_01` and `counter_02` the same instance of `Counter` class?\"\n    + f\" {counter_01 == counter_02}\",\n)\n\nprint(\"\\nMethod call of `counter_01` instance...\")\n\ncounter_01.increment().increment().increment()\nprint(\"\\ncounter01.increment().increment().increment()\")\n\nprint(f\"\\nCount attribute of `counter_01` instance --> {counter_01.get_count()}\")\n\n\nprint(\"\\nMethod call of `counter_02` instance...\")\n\ncounter_02.decrement()\nprint(\"\\ncounter02.decrement()\")\n\nprint(f\"\\nCount attribute of `counter_02` instance --> {counter_02.get_count()}\")\n\nprint(\n    \"\\n# ---------------------------------------------------------------------------------- #\\n\"\n)\n\n\n\"\"\"\n    Additional challenge...\n\"\"\"\n\nprint(\"Additional challenge...\")\n\n\nclass UserSession(metaclass=SingletonMeta):\n    __email: str\n    __uid: str\n    __name: str\n    __user_name: str\n\n    def __init__(self, *, email=\"\", uid=\"\", name=\"\", user_name=\"\") -> None:\n        self.__email = email\n        self.__uid = uid\n        self.__name = name\n        self.__user_name = user_name\n\n    def get_email(self) -> str:\n        return self.__email\n\n    def get_uid(self) -> str:\n        return self.__uid\n\n    def get_name(self) -> str:\n        return self.__name\n\n    def get_user_name(self) -> str:\n        return self.__user_name\n\n    def set_email(self, new_email: str) -> Self:\n        self.__email = new_email\n        return self\n\n    def set_uid(self, new_uid: str) -> Self:\n        self.__uid = new_uid\n        return self\n\n    def set_name(self, new_name: str) -> Self:\n        self.__name = new_name\n        return self\n\n    def set_user_name(self, new_user_name: str) -> Self:\n        self.__user_name = new_user_name\n        return self\n\n    def delete_data(self) -> Self:\n        self.__email = \"\"\n        self.__uid = \"\"\n        self.__name = \"\"\n        self.__user_name = \"\"\n        return self\n\n\nuser_session: UserSession = UserSession(\n    email=\"juansmith16@gmail.com\",\n    name=\"Juan\",\n    uid=\"15H4G-A5D-1Y7\",\n    user_name=\"JuanGamer16\",\n)\n\nprint(\n    \"\\nUser: \"\n    + f\"{user_session.get_uid()} {user_session.get_name()} \"\n    + f\"{user_session.get_user_name()} {user_session.get_email()}\"\n)\n\nuser_session.delete_data()\nprint(\"\\nUser data deleted!\")\n\nprint(\n    \"\\nUser: \"\n    + f\"{user_session.get_uid()} {user_session.get_name()} \"\n    + f\"{user_session.get_user_name()} {user_session.get_email()}\"\n)\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/idiegorojas.py",
    "content": "\"\"\"\n#23 - Patron de diseño Singleton\n\"\"\"\n# Es un patron de diseño que se asegura que una clase solamente tenga una instancia\n# Proporciona un punto de acceso global a esa instancia\n# En pocas palabras es tener algo que todos usan\n# Ejemplo: Un telefono fijo en la casa\n\n\"\"\"\nEstrucutra basica\n\"\"\"\n# _instance: Variable para guardar un objeto unico\n# __new__: Controla si ya existe un objeto o si hay que crearlo\n# Si hay un objeto, no se crea otro, solo se devuelve\n\nclass AlgoUnico:\n    _instance = None # Caja donde guardamos el objeto unico\n\n    def __new__(cls): # Funcion que decide que hacer\n        if cls._instance is None: # Si la caja esta vacia\n            cls._instance = super().__new__(cls) # Crea el objeto si no existe\n        return cls._instance # Devuelve lo que hay en la caja\n    \n\"\"\"\nComo se compone\n\"\"\"\n# La clase: Define que cosa unica estamos creando(telefono, una impresora...)\n# Variable estatica _instance: Almacena el unico objeto y compoartida por toda la clase\n# Control de creacion __new__: Asegura que no se hagan copias extras\n# Atributos o metodos: Lo que quiero que haga el Singleton\n\n\n\"\"\"\nPara que se usa\n\"\"\"\n# Cuando se necesita un solo recurso compartido en todo el programa\n# Se quiere que todos accedan a lo mismo y vean los mismo cambios\n# Evitar desperdiciar memoria creando muchas copias innecesarias\n\n\n\"\"\"\nEjemplo 1\n\"\"\"\n# Cafetera compartida en una oficina\n\nclass Cafetera:\n    _instance = None\n\n    def __new__(cls):\n        if cls._instance is None:\n            cls._instance = super().__new__(cls)\n            cls._instance.tipo_cafe = 'expresso' # Sabor inicial\n        return cls._instance\n    \n    def cambiar_cafe(self, nuevo_tipo):\n        self.tipo_cafe = nuevo_tipo\n        print(f'La cafetera ahora tiene {self.tipo_cafe}')\n\ncafetera1 = Cafetera()\ncafetera2 = Cafetera()\n\nprint(cafetera1.tipo_cafe)\ncafetera2.cambiar_cafe('Americano')\nprint(cafetera1.tipo_cafe)\nprint(cafetera1 is cafetera2)\n\n\n\"\"\"\nEjemplo 2\n\"\"\"\n# Control tv en casa\n\nclass ControlTv:\n    _instance = None\n\n    def __new__(cls):\n        if cls._instance is None:\n            cls._instance = super().__new__(cls)\n            cls._instance.volumen_tv = 10\n        return cls._instance\n    \n    def subir_volumen(self):\n        self.volumen_tv += 5\n        print(f'El volumen ahora es de {self.volumen_tv}')\n\n\ncontrol1 = ControlTv()\ncontrol2 = ControlTv()\n\nprint(control1.subir_volumen())\nprint(control2.subir_volumen())\n\n\n\"\"\"\nExtra\n\"\"\"\n\nclass SesionUsuario:\n    _instance = None\n\n    id: int = None\n    uesername: str = None\n    name: str = None\n    mail: str = None\n\n    def __new__(cls):\n        if not cls._instance:\n            cls._instance = super(SesionUsuario, cls).__new__(cls)\n        return cls._instance\n\n    \n    def set_user(self, id, username, name, mail):\n        self.id = id\n        self.uesername = username\n        self.name = name\n        self.mail = mail\n\n    def get_user(self):\n        return f'ID: {self.id}, Username: {self.uesername}, Nombre: {self.name}, Email: {self.mail}'\n    \n    def clear_user(self):\n        self.id = None\n        self.uesername = None\n        self.name = None\n        self.mail = None\n\n\nsession1 = SesionUsuario()\nprint(session1.get_user())\nsession1.set_user(1, \"mouredev\", \"Brais Moure\", \"mouredev@gmail.com\")\nprint(session1.get_user())\n\nsession2 = SesionUsuario()\nprint(session2.get_user())\n\nsession3 = SesionUsuario()\nsession3.clear_user()\nprint(session3.get_user())"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/ignaciovihe.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n * con un ejemplo genérico.\n\"\"\"\n\nclass Singleton:\n    _instance = None    # Aqui se guarda la instancia. Sera unica y todos los que intenten crear un Singleton se les devolvera esta.\n\n    def __new__(cls):   # Se ejecuta antes de init.\n        if cls._instance == None:                                   # Si la instancia no esta creada.\n            cls._instance = super(Singleton, cls).__new__(cls)      # Lo creo usando en metodo new de su clase superior y pasandole cls\n        return cls._instance                                        # Devuelvo la instancia. Siempre la misma.  \n\na = Singleton()\nprint(a)\nb = Singleton()\nprint(b)  \nprint(a is b)\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el patrón de diseño \"singleton\" para representar una clase que\n * haga referencia a la sesión de usuario de una aplicación ficticia.\n * La sesión debe permitir asignar un usuario (id, username, nombre y email),\n * recuperar los datos del usuario y borrar los datos de la sesión.\n\"\"\"\n# Version simple con una sola clase. Si queremos hacer otras clases singleton deberemos modificar su metodo new en cada una\nclass UserSession():\n    _instance = None\n\n    def __new__(cls):\n        if cls._instance == None:\n            cls._instance = super(UserSession, cls).__new__(cls)\n            cls._instance.user = None # Se crea un atributo de instacia desde new para no usar init cada vez y tener que controlar la inicialización con un flag.\n        return cls._instance\n    \n    def set_user(self, id, username, name, email):\n            self.user = {\n                \"id\": id,\n                \"username\": username,\n                \"name\": name,\n                \"email\": email\n            }\n\n    def get_user_data(self):\n        if self.user:\n            return f\"{self.user[\"id\"]} - {self.user[\"username\"]} - {self.user[\"name\"]} - {self.user[\"email\"]}\"\n        else:\n            print(\"Sesión sin usuario\")\n        \n    def delete_session(self):\n        self.user = None\n\nprint(\"------------------con clase simple-------------------------\")\nsession1 = UserSession()\nprint(session1.get_user_data())\nsession1.set_user(1, \"culiembres\", \"ignacio\", \"email@email.com\")\nprint(session1.get_user_data())\n\nsession2 = UserSession()\nprint(session2.get_user_data())\n\nsession3 = UserSession()\nsession3.set_user(2, \"pepeluis\", \"Pepe\", \"mielamil@email.com\")\nprint(session3.get_user_data())\n\nsession3.delete_session()\nsession3.get_user_data()\n\n\n# Version con metaclase para varias clases singleton. Siguiento las indicaciones de https://refactoring.guru/\n\nclass SingletonMeta(type):                              # Se utiliza una metaclase para modificar el comportamiento de call\n                                                        # Todas las clases tienen la metaclase type por defecto\n    _instances = {}                                     # Se crea un dict para guardas las instacias unicas de las clases que queremos que sean singleton.\n\n    def __call__(cls, *args, **kwds):\n        \n        if cls not in cls._instances:\n            instance = super().__call__(*args, **kwds)  # Creamos la instancia llamando al metodo call de type(metaclase base)\n            cls._instances[cls] = instance              # internamente type.call llama a los metodos new y init de las clases(ej:UsserConnection, BBDDconnection)\n        return cls._instances[cls]\n    \n\nclass UserConnection(metaclass=SingletonMeta):          # Le indicamos que la calse tiene una metaclase definida opor nosotros(por defecto seria type)\n\n    def __init__(self):\n        self.user = None\n\n    def set_user(self, id, username, name, email):\n        self.user = {\n            \"id\": id,\n            \"username\": username,\n            \"name\": name,\n            \"email\": email\n        }\n\n    def get_user_data(self):\n        if self.user:\n            return f\"{self.user['id']} - {self.user['username']} - {self.user['name']} - {self.user['email']}\"\n        else:\n            return \"Sesión sin usuario\"\n\n    def delete_session(self):\n        self.user = None\n\n\nclass BBDDConnection(metaclass=SingletonMeta):\n    \n    def __init__(self):\n        self.bbdd = {\n            \"name\": \"Pedro\",\n            \"edad\": 35\n        }\n\n    def get_data(self):\n        return self.bbdd\n    \n\n\nprint(\"------------------con metaclass------------------------\")\n    \nconnection1 = UserConnection()\nconnection1.set_user(1, \"pepito\", \"Pepe\", \"pepe@email.com\")\nprint(connection1.get_user_data())\n\nconnection2 = UserConnection()\nprint(connection2.get_user_data())\n\nprint(connection1 is connection2)\n\nbbddc1 = BBDDConnection()\nprint(bbddc1.get_data())\n\nbbddc2 = BBDDConnection()\nprint(bbddc2.get_data())\n\nprint(bbddc1 is bbddc2)\n\n\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/isilanes.py",
    "content": "class SingletonMeta(type):\n    __instances = {}\n\n    def __call__(cls, *args, **kwargs):\n        if cls not in cls.__instances:\n            cls.__instances[cls] = super().__call__(*args, **kwargs)\n\n        return cls.__instances[cls]\n\n\nclass Patata(metaclass=SingletonMeta):\n\n    def __init__(self, size: int = 10, color: str = \"yellow\") -> None:\n        self.size = size\n        self.color = color\n\n    def __str__(self) -> str:\n        return f\"Patata(s={self.size}, c='{self.color}')\"\n\n\nclass User:\n\n    def __init__(self, user_id: int, username: str, name: str, email: str) -> None:\n        self.user_id = user_id\n        self.username = username\n        self.name = name\n        self.email = email\n\n    def __str__(self) -> str:\n        return f\"User(user_id={self.user_id}, username='{self.username}', name='{self.name}', email='{self.email}')\"\n\n\nclass SingletonByUserMeta(type):\n    __instances = {}\n\n    def __new__(cls, *args, **kwargs):\n        obj = super().__new__(cls, *args, **kwargs)\n\n        def remove_user_from_instances(self) -> None:\n            SingletonByUserMeta.delete(self.__class__, user=self.user)\n            self.user = None\n\n        obj.clear = remove_user_from_instances\n\n        @property\n        def instances(klass) -> list[str]:\n            return [f\"{klass.__name__}(user={u})\" for u in SingletonByUserMeta.__instances[klass]]\n\n        cls.instances = instances\n\n        return obj\n\n    def __call__(cls, user: User | None, *args, **kwargs):\n        if user is None:\n            return\n\n        if cls not in cls.__instances:\n            cls.__instances[cls] = {}\n\n        if user.user_id not in cls.__instances[cls]:\n            cls.__instances[cls][user.user_id] = super().__call__(user, *args, **kwargs)\n\n        return cls.__instances[cls][user.user_id]\n\n    def delete(cls, user: User) -> None:\n        if cls not in cls.__instances or user.user_id not in cls.__instances[cls]:\n            return\n\n        return cls.__instances[cls].pop(user.user_id)\n\n\nclass Session(metaclass=SingletonByUserMeta):\n\n    def __init__(self, user: User | None) -> None:\n        self.user = user\n\n\ndef main():\n    print(\"===== MAIN =====\")\n    print(\"Creamos un objeto de la clase Patata\")\n    print('>>> p1 = Patata()')\n    p1 = Patata()\n    print(f\"p1 == {p1}\")\n    print(\"Intentamos crear una segunda Patata, inicializada con valores diferentes:\")\n    print('>>> p2 = Patata(size=20, color=\"red\")')\n    p2 = Patata(size=20, color=\"red\")\n    print(\"Sin embargo, p2 es idéntica a p1:\")\n    print(f\"p2 == {p2}\")\n    print(\"Esto es porque Patata es una clase singleton, y por tanto p2 no se ha instanciado, sino tomado de p1:\")\n    print(\">>> p1 is p2\")\n    print(p1 is p2)\n    print(\"Cambiar un atributo de cualquiera de los dos objetos lo cambia en ambos:\")\n    print('p1.size = 100')\n    p1.size = 100\n    print(f\"p2 == {p2}\")\n    print('>>> p2.color = \"green\"')\n    p2.color = \"green\"\n    print(f\"p1 == {p1}\")\n\n\ndef extra():\n    print(\"\\n===== EXTRA =====\")\n\n    print(\"Creamos un usuario:\")\n    print('>>> user1 = User(user_id=1, username=\"juan\", name=\"Juan Andahalf\", email=\"juan@example.com\")')\n    user1 = User(user_id=1, username=\"juan\", name=\"Juan Andahalf\", email=\"juan@example.com\")\n\n    print(\"Creamos una sesión para ese usuario:\")\n    print('>>> session1 = Session(user=user1)')\n    session1 = Session(user=user1)\n\n    print(\"Vemos que esta sesión se ha registrado:\")\n    print(\">>> Session.instances\")\n    print(Session.instances)\n\n    print(\"Intentamos crear otra sesión para ese usuario:\")\n    print('>>> session2 = Session(user=user1)')\n    session2 = Session(user=user1)\n\n    print(\"Sin embargo, esta es idéntica a la anterior (es session1):\")\n    print('>>> session2 is session1')\n    print(session2 is session1)\n\n    print(\"Podemos ver que sólo hay una sesión en total:\")\n    print(\">>> Session.instances\")\n    print(Session.instances)\n\n    print(\"Ahora creamos un segundo usuario:\")\n    print('>>> user2 = User(user_id=2, username=\"illo\", name=\"Juan Otro\", email=\"otro@example.com\")')\n    user2 = User(user_id=2, username=\"illo\", name=\"Juan Otro\", email=\"otro@example.com\")\n\n    print(\"Y también creamos una sesión para ese usuario:\")\n    print('>>> session3 = Session(user=user2)')\n    session3 = Session(user=user2)\n\n    print(\"Como el usuario es distinto, se ha creado una sesión distinta para él:\")\n    print('>>> session3 is session1')\n    print(session3 is session1)\n\n    print(\"En efecto, ahora las dos sesiones están registradas:\")\n    print(\">>> Session.instances\")\n    print(Session.instances)\n\n    print(\"Tal y como se requiere, podemos extraer la información de usuario de una sesión:\")\n    print('>>> session1.user')\n    print(session1.user)\n\n    print(\"También podemos borrar una sesión:\")\n    print('>>> session1.clear()')\n    session1.clear()\n    print(\"Ahora sólo estará registrada la tercera sesión (la del usuario 2):\")\n    print('>>> Session.instances')\n    print(Session.instances)\n    print(\"Y los objetos session1 Y TAMBIÉN session2 (puesto que son el mismo objeto) han sido vaciados:\")\n    print('>>> session1.user')\n    print(session1.user)\n    print('>>> session2.user')\n    print(session2.user)\n\n    print(\"Obviamente, podemos volver a generar una sesión para el usuario 1:\")\n    print('>>> session4 = Session(user1)')\n    session4 = Session(user1)\n    print(\">>> Session.instances\")\n    print(Session.instances)\n\n\nif __name__ == \"__main__\":\n    main()\n    extra()\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/juanmax2.py",
    "content": "\"\"\"\nEjercicio\n\"\"\"\n\nfrom tkinter import S\n\nclass Singleton:\n    \n    _instance = None\n    \n    def __new__(cls):\n        if not cls._instance:\n            cls._instance = super(Singleton, cls).__new__(cls)\n\n        return cls._instance\n\n\nsingleton1 = Singleton()\nprint(singleton1)\nsingleton2 = Singleton()\nprint(singleton2)\n\nprint(singleton1 is singleton2)\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el patrón de diseño \"singleton\" para representar una clase que\n * haga referencia a la sesión de usuario de una aplicación ficticia.\n * La sesión debe permitir asignar un usuario (id, username, nombre y email),\n * recuperar los datos del usuario y borrar los datos de la sesión.\n\"\"\"\n\nclass UserSession:\n    \n    _instance = None\n    \n    id : int = None\n    username: str = None\n    name: str = None\n    email: str = None\n    \n    def __new__(cls):\n        \n        if not cls._instance:\n            cls._instance = super(UserSession, cls).__new__(cls)\n        return cls._instance\n    \n    def set_user(self, id, username, name, email):\n        \n        self.id = id\n        self.username = username\n        self.name = name\n        self.email = email\n        \n    def get_user(self):\n        \n        return f\"{self.id}, {self.username}, {self.name}, {self.email}\"\n    \n    def clear_user(self):\n        \n        self.id = None\n        self.username = None\n        self.name = None\n        self.email = None\n        \nsession1 = UserSession()\nprint(session1)\nsession1.set_user(1, \"juanmax2\", \"Juanma\", \"juanma@gmail.com\")\nprint(session1.get_user())\n\nsession2 = UserSession()\nprint(session2.get_user())\n\nsession3 = UserSession()\nsession3.clear_user()\nprint(session3.get_user())\n\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/juanppdev.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n * con un ejemplo genérico.\n\"\"\"\n\nclass Singleton:\n    _instance = None\n\n    def __new__(cls, *args, **kwargs):\n        if not cls._instance:\n            cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)\n        return cls._instance\n\n# Ejemplo de uso\nsingleton1 = Singleton()\nsingleton2 = Singleton()\n\nprint(singleton1 is singleton2)  # Esto imprimirá True, ya que ambas variables apuntan a la misma instancia\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el patrón de diseño \"singleton\" para representar una clase que\n * haga referencia a la sesión de usuario de una aplicación ficticia.\n * La sesión debe permitir asignar un usuario (id, username, nombre y email),\n * recuperar los datos del usuario y borrar los datos de la sesión.\n\"\"\"\n\nclass UserSession:\n    _instance = None\n\n    def __new__(cls, *args, **kwargs):\n        if not cls._instance:\n            cls._instance = super(UserSession, cls).__new__(cls, *args, **kwargs)\n            cls._instance.user_data = None\n        return cls._instance\n\n    def set_user(self, user_id, username, name, email):\n        self.user_data = {\n            'id': user_id,\n            'username': username,\n            'name': name,\n            'email': email\n        }\n\n    def get_user(self):\n        return self.user_data\n\n    def clear_session(self):\n        self.user_data = None\n\n# Ejemplo de uso\nsession1 = UserSession()\nsession2 = UserSession()\n\n# Asignar un usuario a la sesión\nsession1.set_user(1, 'jdoe', 'John Doe', 'jdoe@example.com')\n\n# Recuperar los datos del usuario\nprint(session1.get_user())  # {'id': 1, 'username': 'jdoe', 'name': 'John Doe', 'email': 'jdoe@example.com'}\n\n# Verificar que session1 y session2 son la misma instancia\nprint(session1 is session2)  # True\n\n# Borrar los datos de la sesión\nsession2.clear_session()\nprint(session1.get_user())  # None\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/kenysdev.py",
    "content": "# ╔═════════════════════════════════════╗\n# ║ Autor:  Kenys Alvarado              ║\n# ║ GitHub: https://github.com/Kenysdev ║\n# ║ 2024 -  Python                      ║\n# ╚═════════════════════════════════════╝\n\n# -----------------------------------\n# * PATRONES DE DISEÑO: SINGLETON\n# -----------------------------------\n\n\"\"\"\n* EJERCICIO #1:\n* Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n* con un ejemplo genérico.\n\"\"\"\n\nclass Singleton:\n    __instance = None\n\n    def __new__(cls):\n        if cls.__instance is None:\n            cls.__instance = super().__new__(cls)\n        return cls.__instance\n\nsingleton1 = Singleton()\n# singleton2 accede a la misma instancia que singleton1.\nsingleton2 = Singleton()\nprint(singleton1 is singleton2)\n\n\"\"\"\n* EJERCICIO #2:\n* Utiliza el patrón de diseño \"singleton\" para representar una clase que\n* haga referencia a la sesión de usuario de una aplicación ficticia.\n* La sesión debe permitir asignar un usuario (id, username, nombre y email),\n* recuperar los datos del usuario y borrar los datos de la sesión.\n\"\"\"\n\nclass UserSession:\n    __instance = None\n    __user_id: int = None\n    __user_name: str = None\n    __name: str = None\n    __email: str = None\n\n    def __new__(cls):\n        if cls.__instance is None:\n            cls.__instance = super().__new__(cls)\n        return cls.__instance\n\n    def set_user(self, user_id, user_name, name, email):\n        self.__user_id = user_id\n        self.__user_name = user_name\n        self.__name = name\n        self.__email = email\n\n    def get_user(self) -> dict:\n        return {\n            \"id\": self.__user_id,\n            \"username\": self.__user_name,\n            \"name\": self.__name,\n            \"email\": self.__email\n        }\n    \n    def logout(self):\n        self.__instance = None\n        self.__user_id = None\n        self.__user_name = None\n        self.__name = None\n        self.__email = None\n\nlogin_user1 = UserSession()\nlogin_user1.set_user(1, \"Zoe_1\", \"Zoe\", \"Zoe@gm.com\")\nprint(login_user1.get_user())\nlogin_user1.logout()\n\nlogin_user2 = UserSession()\nlogin_user2.set_user(1, \"Ben_1\", \"Ben\", \"Ben@gm.com\")\nprint(login_user2.get_user())\nlogin_user2.logout()\n\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/mhayhem.py",
    "content": "# EJERCICIO:\n# Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n# con un ejemplo genérico.\n\nclass Singlenton:\n    _instance = None  # Variable de clase para guardar la instancia\n    \n    def __new__(cls):\n        # Si no existe una instancia se crerara\n        if cls._instance is None:\n            cls._instance = super().__new__(cls)\n        return cls._instance # Siempre devolvemos la misma instancia\n    def __init__(self, value=None):\n        # Solo inicializamos una vez\n        if not hasattr(self, \"initialized\"):\n            self.initialized = True\n            self.value = value\n            \n\n\n# DIFICULTAD EXTRA (opcional):\n# Utiliza el patrón de diseño \"singleton\" para representar una clase que\n# haga referencia a la sesión de usuario de una aplicación ficticia.\n# La sesión debe permitir asignar un usuario (id, username, nombre y email),\n# recuperar los datos del usuario y borrar los datos de la sesión.\n\nclass User:\n    _instance = None\n    \n    \n    def __new__(cls,*args, **kwargs):\n        if cls._instance is None:\n            cls._instance = super().__new__(cls)\n        return cls._instance\n    \n    def __init__(self, id, username, name, mail):\n        self.id: int = id\n        self.username: str = username\n        self.name: str = name.capitalize()\n        self.mail: str = mail\n    def __str__(self):\n        return f\"ID: {self.id}, Username: {self.username}, Nombre: {self.name}, Email: {self.mail}\"\n    \n    def clear_session(self):\n        self.id = None\n        self.username = None\n        self.name = None\n        self.mail = None\n\n\nedu = User(23, \"vastmind\", \"eduardo\", \"cocinas_del_sur@cds.com\")\nsundy = User(24, \"bruja\", \"sundy\", \"buja@witch.com\")\n\nprint(edu.__str__())"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/mouredev.py",
    "content": "\"\"\"\nEjercicio\n\"\"\"\n\n\nclass Singleton:\n\n    _instance = None\n\n    def __new__(cls):\n        if not cls._instance:\n            cls._instance = super(Singleton, cls).__new__(cls)\n        return cls._instance\n\n\nsingleton1 = Singleton()\nprint(singleton1)\nsingleton2 = Singleton()\nprint(singleton2)\n\nprint(singleton1 is singleton2)\n\n\"\"\"\nExtra\n\"\"\"\n\n\nclass UserSession:\n\n    _instance = None\n\n    id: int = None\n    username: str = None\n    name: str = None\n    email: str = None\n\n    def __new__(cls):\n        if not cls._instance:\n            cls._instance = super(UserSession, cls).__new__(cls)\n        return cls._instance\n\n    def set_user(self, id, username, name, email):\n        self.id = id\n        self.username = username\n        self.name = name\n        self.email = email\n\n    def get_user(self):\n        return f\"{self.id}, {self.username}, {self.name}, {self.email}\"\n\n    def clear_user(self):\n        self.id = None\n        self.username = None\n        self.name = None\n        self.email = None\n\n\nsession1 = UserSession()\nprint(session1.get_user())\nsession1.set_user(1, \"mouredev\", \"Brais Moure\", \"mouredev@gmail.com\")\nprint(session1.get_user())\n\nsession2 = UserSession()\nprint(session2.get_user())\n\nsession3 = UserSession()\nsession3.clear_user()\nprint(session3.get_user())\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/mrodara.py",
    "content": "#### PATRONES DE DISEÑO: SINGLETON\n\n'''\nEl patrón Singleton es un patrón de diseño que asegura que una clase tenga una única instancia en todo el programa \ny proporciona un punto de acceso global a esa instancia. Es útil en casos como la gestión de configuraciones, \nrecursos compartidos (como conexiones a bases de datos) o registros de logs.\n\nPython ofrece varias formas de implementar este patrón, la más sencilla es usando variables de clase\n'''\n\n# Implementación básica: usando variables de clase\nclass Configuration:\n    _instance = None # Variable de clase para almacenar la única instancia\n    \n    # Método para controla la construcción de la instancia\n    def __new__(cls, *args, **kwargs):\n        if not cls._instance:\n            cls._instance = super().__new__(cls, *args, **kwargs) #Nueva instancia usando clase base\n            cls._instance.settings = {} #Creamos un diccionario para almacenar nuestra configuración\n        \n        return cls._instance # Devolvemos la instáncia única (nueva o ya creada)\n    \n    def set(self, key, value):\n        self.settings[key] = value\n    \n    def get(self, key):\n        return self.settings.get(key, None)        \n\n# Uso de singleton\nconfig1 = Configuration()\nconfig2 = Configuration()\n\nconfig1.set(\"db_host\", \"192.168.20.10\")\nconfig1.set(\"db_name\", \"my_db\")\nconfig1.set(\"db_user\", \"user_db\")\nconfig1.set(\"port\", 3306)\n\nprint(config1.get(\"db_host\")) # 192.168.20.10\nprint(config2.get(\"db_host\"))\n\nprint(config1 is config2)\n\n### EJERCICIO EXTRA\nclass Session():\n    __instance = None\n    \n    def __new__(cls, *args, **kwargs):\n        if not cls.__instance:\n            cls.__instance = super().__new__(cls, *args, **kwargs)\n            cls.__instance.username = None\n            cls.__instance.session_id = None\n            cls.__instance.name = None\n            cls.__instance.email = None\n        \n        return cls.__instance\n    \n    def set_username(self, username):\n        self.username = username\n    \n    def set_session_id(self, session_id):\n        self.session_id = session_id\n    \n    def set_name(self, name):\n        self.name = name\n    \n    def set_email(self, email):\n        self.email = email\n    \n    def get_username(self):\n        return self.username\n    \n    def get_session_id(self):\n        return self.session_id\n    \n    def get_name(self):\n        return self.name\n    \n    def get_email(self):\n        return self.email\n    \n    def end_session(self):\n        self.username = None\n        self.session_id = None\n        self.name = None\n        self.email = None\n        Session.__instance = None\n        \n        print(\"Sesión finalizada, con éxito...\")\n    \nsession1 = Session()    \nsession2 = Session()\n\nsession1.set_name('Manu')\nsession1.set_session_id(1)\nsession1.set_username(\"mrodara\")\nsession1.set_email(\"manueljesus.rodriguez@iesalandalus.org\")\n\nprint(session2.get_name())\nprint(session2.get_username())\nprint(session2.get_session_id())\nprint(session2.get_email())\n\nsession2.end_session()\n\nprint(session1.get_name())\nprint(session1.get_username())\nprint(session1.get_session_id())\nprint(session1.get_email())\n    \n### FIN EJERCICIO EXTRA\n\n#### FIN PATRONES DE DISEÑO: SINGLETON\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/neslarra.py",
    "content": "\"\"\"\n EJERCICIO:\n Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n con un ejemplo genérico.\n\n DIFICULTAD EXTRA (opcional):\n Utiliza el patrón de diseño \"singleton\" para representar una clase que\n haga referencia a la sesión de usuario de una aplicación ficticia.\n La sesión debe permitir asignar un usuario (id, username, nombre y email),\n recuperar los datos del usuario y borrar los datos de la sesión.\n\"\"\"\nfrom time import sleep\n\nprint(f\"{'#' * 47}\")\nprint(f\"##  Explicación  {'#' * 30}\")\nprint(f\"{'#' * 47}\")\n\nprint(r\"\"\"\nSingleton es un patrón de diseño que sirve para garantizar que una clase tendrá \"una y sola una\" instancia de la misma.\n\nclass Singleton(object):\n    single_object = None\n\n    def __new__(cls, *args, **kwargs):\n        if cls.single_object is None:\n            cls.single_object = super().__new__(cls)\n            cls.single_object._initialized = False\n        return cls.single_object\n\n    def __init__(self, value=None):\n        if not self._initialized:\n            self.value = value\n            self._initialized = True\n\n    def set_value(self, value):\n        self.value = value\n\n    def get_value(self):\n        return self.value\n\n\nobj1 = Singleton(17)\nobj2 = Singleton(\"Mundo\")\nobj3 = Singleton([1, 2, 3])\n\nprint(f\"obj1, obj2 y obj3 ¿Son el mismo objeto? <=> {id(obj1) == id(obj2) == id(obj3)}\")\nprint(f\"obj1 type = {obj1.__class__.__name__} value = {obj1.get_value()}\")\nprint(f\"obj2 type = {obj2.__class__.__name__} value = {obj2.get_value()}\")\nprint(f\"obj3 type = {obj3.__class__.__name__} value = {obj3.get_value()}\")\n\nobj1, obj2 y obj3 ¿Son el mismo objeto? <=> True\nobj1 type = int value = 17  \\\nobj2 type = int value = 17   |---> tomó SOLAMENTE el primer objeto en instanciar (probar cambiando el orden)\nobj3 type = int value = 17  /\n\nOpero sobre el objeto\nobj2.set_value(obj2.get_value() * 3)\nobj3.set_value(obj3.get_value() - 2)\nobj1.set_value(pow(obj1.get_value(), 0.5))\nprint(f\"obj1, obj2 y obj3 ¿Son el mismo objeto? <=> {id(obj1) == id(obj2) == id(obj3)}\")\nprint(f\"obj1 type = {obj1.__class__.__name__} value = {obj1.get_value()}\")\nprint(f\"obj2 type = {obj2.__class__.__name__} value = {obj2.get_value()}\")\nprint(f\"obj3 type = {obj3.__class__.__name__} value = {obj3.get_value()}\")\n\nobj1, obj2 y obj3 ¿Son el mismo objeto? <=> True\nobj1 type = int value = 7.0  \\\nobj2 type = int value = 7.0   |---> operé sobre obj1, 2 y 3 PERO, como es el MISMO objeto, fue una operación equivalente a raíz_2(17 * 3 - 2) = 7\nobj3 type = int value = 7.0  /\n\"\"\")\n\n\nprint(f\"{'#' * 63}\")\nprint(f\"##  Dificultad extra 1 - Logger  {'#' * 30}\")\nprint(f\"{'#' * 63}\\n\")\n\n\n\nclass Singleton(object):\n    single_object = None\n\n    def __new__(cls, *args, **kwargs):\n        if cls.single_object is None:\n            cls.single_object = super().__new__(cls)\n            cls.single_object._initialized = False\n        return cls.single_object\n\n    def __init__(self, value=None):\n        if not self._initialized:\n            self.value = value\n            self._initialized = True\n\n    def set_value(self, value):\n        self.value = value\n\n    def get_value(self):\n        return self.value\n\n\nclass Logger(Singleton):\n\n    def add_entry(self, message):\n        from datetime import datetime\n        self.set_value(self.get_logger()  + datetime.now().strftime(\"%Y-%b-%d %H%M%S.%f\")[:-3] + \": \" + message + \"\\n\")\n\n    def get_logger(self):\n        return self.get_value()\n\n\nclass Task:\n    def __init__(self, username: str, task: str = \"Starting logger\"):\n        from datetime import datetime\n        self.username = username\n        self.logger = Logger(datetime.now().strftime(\"%Y-%b-%d %H%M%S.%f\")[:-3] + \": \" + self.username + \" - \" + task + \"\\n\")\n        self.add_task(\"Login\")\n\n    def add_task(self, task:str):\n        self.logger.add_entry(self.username + \" - \" + task)\n\n    def view_tasks(self):\n        return self.logger.get_logger()\n\n\ntask_nestor = Task(\"Nestor\")\nsleep(0.25)\ntask_nestor.add_task(\"Formatear disco G\")\nsleep(0.25)\ntask_neslarra = Task(\"Neslarra\")\nsleep(0.25)\ntask_nestor.add_task(\"Copiar ISOs a disco G\")\nsleep(0.25)\ntask_nestor.add_task(\"Hacer flash booteable con ISO Linux Mint\")\nsleep(0.25)\ntask_neslarra.add_task(\"Cargar SO Linux Mint en laptop AX103\")\nsleep(0.25)\ntask_delivery = Task(\"Delivery\")\nsleep(0.25)\ntask_neslarra.add_task(\"Bootear laptop AX103\")\nsleep(0.25)\ntask_nestor.add_task(\"Registar laptop AX103 como OK\")\nsleep(0.25)\ntask_delivery.add_task(\"Retiro de laptop AX103 para entrega\")\n\nprint(f\"Contenido del logger: \\n{task_nestor.view_tasks()}\")\n\nprint(f\"¿Son las instancias de 'Task.logger' la misma instancia? <=> {id(task_nestor.logger) == id(task_neslarra.logger) == id(task_delivery.logger)}\")\n\nprint(f\"\\n{'#' * 63}\")\nprint(f\"##  Dificultad extra 2 - UserId  {'#' * 30}\")\nprint(f\"{'#' * 63}\\n\")\n\nclass Login(Singleton):\n    _id = 1000\n\n    def user_login(self, username: str, name: str, email: str):\n        from datetime import datetime\n        data = {\"username\": username,\n                \"name\": name,\n                \"email\": email,\n                \"login_time\": datetime.now().strftime(\"%Y-%b-%d %H%M%S.%f\")[:-3],\n                \"session_id\": self.get_session_id()\n                }\n        self.get_logged_users().append(data)\n\n    def get_logged_users(self):\n        return self.get_value()\n\n    @classmethod\n    def get_session_id(cls):\n        cls._id += 1\n        return cls._id\n\n\nclass User:\n\n    def __init__(self, username: str, name: str, email: str):\n        self.username = username\n        self.name = name\n        self.email = email\n        self.user = Login([])\n        self.add_user()\n\n    def add_user(self):\n        self.user.user_login(self.username, self.name, self.email)\n\n    def view_logged_users(self):\n        return self.user.get_logged_users()\n\n\nnestor = User(\"nestor\", \"Nestor Larralde\", \"nestor.larralde@yahoo.com\")\nsleep(1.27)\nneslarra = User(\"neslarra\", \"Nestor Omar Larralde\", \"neslarra@ibm.com\")\nsleep(0.98)\notro = User(\"otro)\", \"Otro Nestor\", \"otro_mail@turulo.net\")\n\nprint(f\"¿Son los objetos User.user iguales? <=> {id(nestor.user) == id(neslarra.user) == id(otro.user)}\")\n\nfor lu in nestor.view_logged_users():\n    print(f\"\\n\")\n    for k, v in lu.items():\n        print(f\"\\t{k}: {v}\")\n\nprint(\"\"\"\nEn los tres casos (el de la explicación y las dos dificultades extra (Logger y User) se usó la misma clase Singleton: en la explicación instanció\nun entero, en el Logger un string y en el User un dict. \n\"\"\")\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/nlarrea.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n * con un ejemplo genérico.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el patrón de diseño \"singleton\" para representar una clase que\n * haga referencia a la sesión de usuario de una aplicación ficticia.\n * La sesión debe permitir asignar un usuario (id, username, nombre y email),\n * recuperar los datos del usuario y borrar los datos de la sesión.\n\"\"\"\n\n\nclass Singleton:\n    _instance = None\n\n    def __new__(cls):\n        \"\"\"Constructor of the Singleton.\"\"\"\n\n        if not cls._instance:\n            cls._instance = super(Singleton, cls).__new__(cls)\n\n        return cls._instance\n\n\nsingleton_1 = Singleton()\nprint(singleton_1)\nsingleton_2 = Singleton()\nprint(singleton_2)\n\nprint(singleton_1 is singleton_2)  # True\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el patrón de diseño \"singleton\" para representar una clase que\n * haga referencia a la sesión de usuario de una aplicación ficticia.\n * La sesión debe permitir asignar un usuario (id, username, nombre y email),\n * recuperar los datos del usuario y borrar los datos de la sesión.\n\"\"\"\n\n\nclass UserSession:\n    _instance = None\n\n    id: str = None\n    username: str = None\n    name: str = None\n    email: str = None\n\n    def __new__(cls):\n        if not cls._instance:\n            cls._instance = super(UserSession, cls).__new__(cls)\n\n        return cls._instance\n\n    def set_user(self, id, username, name, email):\n        self.id = id\n        self.username = username\n        self.name = name\n        self.email = email\n\n    def get_user(self):\n        return f\"{self.id}, {self.username}, {self.name}, {self.email}\"\n\n    def remove_data(self):\n        self.id = None\n        self.username = None\n        self.name = None\n        self.email = None\n\n\nsession_1 = UserSession()\nprint(session_1.get_user())\n# None, None, None, None\n\nsession_1.set_user(1, \"nlarrea\", \"Naia\", \"naia@gmail.com\")\nprint(session_1.get_user())\n# 1, nlarrea, Naia, naia@gmail.com\n\nsession_2 = UserSession()\nprint(session_2.get_user())\n# 1, nlarrea, Naia, naia@gmail.com\n\nsession_3 = UserSession()\nsession_3.remove_data()\nprint(session_3.get_user())\n# None, None, None, None\nprint(session_1.get_user())\n# None, None, None, None\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/oriaj3.py",
    "content": "\"\"\"\n23 - SINGLETON\nAutor de la solución: Oriaj3\n\nTeoría:\nEl patrón Singleton es un patrón de diseño creacional que garantiza que una clase\ntiene una única instancia y proporciona un punto de acceso global a ella.\n\nEl patrón Singleton se utiliza cuando se necesita una única instancia de una clase\nen todo el programa. Por ejemplo, se puede utilizar para representar una conexión\na una base de datos o un archivo de registro.\n\nEl patrón Singleton se implementa creando una clase con un método estático que\ndevuelve una instancia única de la clase. La instancia única se crea la primera\nvez que se llama al método estático y se reutiliza en llamadas posteriores al\nmétodo.\n\nEjemplo de patrón Singleton:\nclass Singleton:\n    _instance = None\n\n    def __new__(cls):\n        if cls._instance is None:\n            cls._instance = super().__new__(cls)\n        return cls._instance\n\n\n\"\"\"\n\n\"\"\"\n/*\n * EJERCICIO:\n * Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n * con un ejemplo genérico.\n\"\"\"\n\nclass Unica:\n    _instancia = None\n    \n    def __new__(cls):\n        if not cls._instancia:\n            cls._instancia = super().__new__(cls)\n            print(\"Creado Objeto\")\n        else:\n            print(\"El objeto ya existe\")\n        return cls._instancia\n\nins1 = Unica()\nins2 = Unica()\nprint(ins1)\nprint(ins2)\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el patrón de diseño \"singleton\" para representar una clase que\n * haga referencia a la sesión de usuario de una aplicación ficticia.\n * La sesión debe permitir asignar un usuario (id, username, nombre y email),\n * recuperar los datos del usuario y borrar los datos de la sesión.\n */\n\"\"\"\n\nclass Sesion_usuario:\n    _instancia = None \n    id: int\n    usuario: str\n    name: str\n    email: str\n    \n    \n    \n    def __new__(cls):\n        if not cls._instancia:\n            cls._instancia = super().__new__(cls)\n        return cls._instancia\n    \n    def set_user(self, id, username, name, email):\n        self.id = id\n        self.username = username\n        self.name = name\n        self.email = email \n        \n    def get_user(self):\n        return f\"{self.id}, {self.username}, {self.name}, {self.email}\"\n    \n    def cerrar_sesion(self):\n        self.id = None\n        self.username = None\n        self.name = None\n        self.email = None\n    \nsesion1 = Sesion_usuario()\nsesion1.set_user(1, \"oriaj\", \"Jairo\", \"oriaj@gmail.com\")    \n\nprint(sesion1.get_user())\n\nsesion2 = Sesion_usuario()\nprint(sesion2.get_user())\n\nsesion1.cerrar_sesion()\nprint(sesion2.get_user())\n\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/pyramsd.py",
    "content": "def singleton(cls):\n    instances = dict()\n\n    def wrap(*args, **kwargs):\n        if cls not in instances:\n            instances[cls] = cls(*args, **kwargs)\n        return instances[cls]\n\n    return wrap\n\n\n@singleton\nclass UserSession:\n    def __init__(self):\n        self.user_data = {}\n\n    def set_user(self, user_id, username, name, email):\n        self.user_data[user_id] = {\n            'username': username,\n            'name': name,\n            'email': email\n        }\n\n    def get_user(self, user_id):\n        if user_id in self.user_data:\n            return self.user_data.get(user_id, None)\n        return f'ID {user_id} not found'\n\n    def clear_user(self, user_id):\n        if user_id in self.user_data:\n            del self.user_data[user_id]\n            return f'ID {user_id} deleted'\n        return f'ID {user_id} not found'\n\n\nif __name__ == '__main__':\n    sessions = UserSession()\n    sessions.set_user(\n        1,\n        'Juan',\n        'Juan Perez',\n        'juan@juan.com'\n    )\n    print(sessions.get_user(1))\n\n    sessions.set_user(\n        2,\n        'Maria',\n        'Maria Perez',\n        'maria@maria.com'\n    )\n    print(sessions.get_user(2))\n\n    print(sessions.get_user(3))\n\n    print(sessions.clear_user(1))\n\n    print(sessions.get_user(1))\n\n    sessions2 = UserSession()\n\n    print(sessions is sessions2)\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/qwik-zgheib.py",
    "content": "class Singleton:\n    _instance = None\n\n    def __new__(cls):\n        if cls._instance is None:\n            cls._instance = super().__new__(cls)\n        return cls._instance\n\n\ns1 = Singleton()\ns2 = Singleton()\n\nprint(s1 is s2) \n\n\n# -- extra challenge\nclass UserSession:\n    _instance = None\n\n    def __new__(cls):\n        if cls._instance is None:\n            cls._instance = super().__new__(cls)\n            cls._instance.user_data = None\n        return cls._instance\n\n    def set_user(self, user_id, username, name, email):\n        self.user_data = {\n            \"user_id\": user_id,\n            \"username\": username,\n            \"name\": name,\n            \"email\": email,\n        }\n\n    def get_user_data(self):\n        return self.user_data\n\n    def clear_session(self):\n        self.user_data = None\n\n\nsession1 = UserSession()\nsession2 = UserSession()\n\nsession1.set_user(1, \"qwik\", \"Qwik Zgheib\", \"qwikzgheib@gmail.com\")\n\nprint(session1.get_user_data())\nprint(session2.get_user_data())\n\nsession2.clear_session()\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/rantamhack.py",
    "content": "\nprint(\"\\n\\n=======================================EJERCICIO=======================================\\n\\n\")\n\n\"\"\"\n * EJERCICIO:\n * Explora el patrón de diseño \"singleton\" y muestra como crearlo\n * con un ejemplo genérico.\n\"\"\"\n\"\"\"\n * El patron Singleton es un patrón de creación \n * Los patrones de creación abstraen la forma en la que se crean los objetos, \n * permitiendo tratar las clases a crear de forma genérica dejando para mas \n * tarde la decisión de que clases crear o como crearlas.\n \n * El patrón Singleton asegura que una clase tenga solo una instancia \n * y proporciona un punto de acceso global a ella\n\"\"\"\n\nclass Singleton:\n\n    __instance = None\n    \n    def __new__(cls, *args, **kwargs):\n        if cls.__instance == None:\n            cls.__instance = super(Singleton, cls).__new__(cls)\n            \n        return cls.__instance\n            \n\n\ninstance1 = Singleton()\ninstance2 = Singleton()\n\nprint(\"Comprobando que las dos instancias son la misma instancia:\\n\")\nprint(instance1 is instance2)\n\n\n\n\n\nprint(\"\\n\\n=======================================DIFICULTAD EXTRA=======================================\\n\\n\")\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el patrón de diseño \"singleton\" para representar una clase que\n * haga referencia a la sesión de usuario de una aplicación ficticia.\n * La sesión debe permitir asignar un usuario (id, username, nombre y email),\n * recuperar los datos del usuario y borrar los datos de la sesión.\n\"\"\"\n\n# Clase para definir el Singleton\nclass User_Session:\n    \n    __instance = None\n    __user_data = None\n    \n    def __new__(cls):\n        if cls.__instance is None:\n            cls.__instance = super(User_Session, cls).__new__(cls)\n            \n        return cls.__instance\n    \n    # Funcion para establecer los datos de los usuarios y marcar como abrir sesion    \n    def new_user(self, id, username, name, email):\n        if self.__user_data is None:\n            self.__user_data = {\n                'id': id,\n                'username': username,\n                'name': name,\n                'email': email\n            }\n            print(f\"El usuario con el\\n\\tid: {id}\\n\\tusername: {username}\\n\\tname: {name}\\n\\temail:{email}\\nHa iniciado sesion\")\n        else:\n            print(f\"Ya hay una sesion activa con el usuario {self.__user_data['username']}. Cierra la sesion actual antes de iniciar una nueva.\")\n            return\n    \n    # Devolvemos los datos del usuario que esta activo        \n    def get_user(self):\n        return self.__user_data\n    \n    # Borramos los datos del usuario y marca como cerrar sesion\n    def logout(self):\n        if self.__user_data:\n            print(f\"El usuario {self.__user_data['username']} ha cerrado la sesion\")\n            self.__user_data = None\n        else:\n            print(\"No hay sesiones abiertas\")\n            \n# Definimos la clase usuario\nclass User():\n    def __init__(self, id, username, name, email):\n        self.id = id\n        self.username = username\n        self.name = name\n        self.email = email\n        \n# Damos nombre a la instancia de User_Session        \nsession = User_Session()\n\n# Iniciamos sesion\ndef log_in(user):\n    session.new_user(user.id, user.username, user.name, user.email)\n    \n# Cerramos sesion\ndef logout():\n    session.logout()\n    \n    \n# Operativa    \nuser1 = User(1, \"Rantam\", \"Alex\", \"rantam@rantam.es\")\nlog_in(user1)\n\n# Sin este logout no se podría abrir sesion con el siguiente usuario\nlogout()       \n\nuser2 = User(2, \"Junior\", \"Maria\", \"maria@rantam.es\")\nlog_in(user2)\n\nlogout()\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/raulG91.py",
    "content": "class SingletonMeta(type):\n\n    _instances = {}\n    def __call__(cls,*args,**kwargs):\n        if cls not in cls._instances:\n            instance = super().__call__(*args,**kwargs)\n            cls._instances[cls] = instance\n        return cls._instances[cls]    \n    def clear(cls):\n        cls._instances.pop(cls)\n\nclass Singleton(metaclass=SingletonMeta):\n    def syHello(self):\n        print(\"Hello from Singleton class\") \n\ns1 = Singleton()\ns2 = Singleton() \n\nif id(s1) == id(s2):\n    print(\"Both instances have same id\")\nelse:\n    print(\"Intances are different\")    \n\nclass User(metaclass=SingletonMeta):\n    def __init__(self,id,username,name,email):\n        self.id = id\n        self.username = username\n        self.name = name\n        self.email = email \n    def get_name(self):\n        return self.name\n    def get_id(self):\n        return self.id\n    def get_username(self):\n        return self.username     \n    def get_email(self):\n        return self.email\n    def close_session(self):\n        User.clear()\n \n\nuser = User(1,\"user1\",\"Juan\",\"juan@test.com\")\nid1 = id(user)\nprint(f'Id for object: {id1}')\nprint(f'User Id {user.get_id()}')\nprint(f'User name {user.get_name()}')\nuser.close_session()\nuser2 = User(2,\"user2\",\"Luna\",\"luna@test.com\")\nid2 = id(user2)\nprint(f'Id for object: {id2}')\nprint(f'User Id {user2.get_id()}')\nprint(f'User name {user2.get_name()}')\nuser2.close_session()"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/raynerpv2022.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n#  * con un ejemplo genérico.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Utiliza el patrón de diseño \"singleton\" para representar una clase que\n#  * haga referencia a la sesión de usuario de una aplicación ficticia.\n#  * La sesión debe permitir asignar un usuario (id, username, nombre y email),\n#  * recuperar los datos del usuario y borrar los datos de la sesión.\n#  */\n\nclass PaternSin:\n\n    _inst = None\n    \n\n    def __new__(qq):\n        if qq._inst == None:\n            qq._inst = super(PaternSin,qq).__new__(qq)\n            qq._inst.name = [\"tiburcio\"] #name es variable de instancia\n         \n        return qq._inst\n    \n    def SetName(self, name):\n        self.name.append(name)\n\np1 = PaternSin()\np2 = PaternSin()\np3 = PaternSin()\n\nprint(p1,p2,p3)\nprint(p1 is p2 is p3)\nprint(\"p1\", p1.name)\np1.SetName(\"segundo\")\nprint(\"p2\", p2.name)\np3.SetName(\"tercero\")\nprint(\"p3\", p3.name)\nprint(\"p1\", p1.name)\nprint(\"p2\", p2.name)\n\n# EXTRA \n\nclass User:\n\n    _instance = None\n\n    def __new__(cls):\n        if cls._instance == None:\n            cls._instance = super(User,cls).__new__(cls)\n            cls._instance.ID = 1001\n            cls._instance.Name = \"Federico\"\n            cls._instance.User_Name = \"fedrico_makiavelo\"\n            cls._instance._instance.email = \"fede@gmail.com\"\n        return cls._instance\n    \n    def Get_User(self):\n        return f\" Name {self.Name} User {self .User_Name} ID {self.ID} email {self.email}\"\n\n    def Delete_User(self):\n        self.ID = None\n        self.Name = None\n        self.User_Name = None\n        self.email = None\n    \n    \n\nU1 = User()\nU2 = User()\n\nprint(U1.Get_User())\nprint(U2.Get_User())\nU1.Delete_User()\nprint(U1.Get_User())\nprint(U2.Get_User())\n    "
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/rigo93acosta.py",
    "content": "## 23 - SINGLETON\n'''\n * EJERCICIO:\n * Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n * con un ejemplo genérico.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el patrón de diseño \"singleton\" para representar una clase que\n * haga referencia a la sesión de usuario de una aplicación ficticia.\n * La sesión debe permitir asignar un usuario (id, username, nombre y email),\n * recuperar los datos del usuario y borrar los datos de la sesión.\n */\n'''\n## refactoring -- guru\n\n## SINGLETON: unica instancia de una clase\n'''\nEjercicio\n'''\n\n\nclass Singleton:\n\n    _instance = None\n\n    def __new__(cls):\n        # Estructura común para implementar Singleton\n        if not cls._instance:\n            cls._instance = super(Singleton, cls).__new__(cls)\n\n        return cls._instance\n    \nsingleton_1 = Singleton()\nsingleton_2 = Singleton()\n\nprint(singleton_1 is singleton_2) # Es la misma clase\n\n'''\nExtra\n'''\n\nclass UserSession:\n\n    _instance = None\n    id: str = None\n    username: str = None\n    name: str = None\n    email: str = None\n\n    def __new__(cls):\n        if not cls._instance:\n            cls._instance = super(UserSession, cls).__new__(cls)\n        \n        return cls._instance\n    \n    def set_user(self, id, username, name, email):\n        self.id = id\n        self.username = username\n        self.name = name\n        self.email = email\n\n    def get_user(self):\n        return f\"{self.id}, {self.username}, {self.name}, {self.email}\"\n    \n    def clear_user(self):\n        self.id = None\n        self.username = None\n        self.name = None\n        self.email = None\n\nsesssion1 = UserSession()\nprint(sesssion1)\nsesssion1.set_user(1, \"rigo93\", \"Rigo\", \"rigo93acosta@gmail.com\")\nprint(sesssion1.get_user())\n\nsesssion2 = UserSession()\nprint(sesssion2.get_user())\n\nsesssion3 = UserSession()\nsesssion3.clear_user()\nprint(sesssion3.get_user())"
  },
  {
    "path": "Roadmap/23 - SINGLETON/python/santyjl.py",
    "content": "#23 PATRONES DE DISEÑO: SINGLETON\n\n\"\"\"\n/*\n * EJERCICIO:\n * Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n * con un ejemplo genérico.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el patrón de diseño \"singleton\" para representar una clase que\n * haga referencia a la sesión de usuario de una aplicación ficticia.\n * La sesión debe permitir asignar un usuario (id, username, nombre y email),\n * recuperar los datos del usuario y borrar los datos de la sesión.\n */\n\"\"\"\n\nclass sigleton:\n    # Variable de clase que almacenará la única instancia de la clase\n    __instancia = None\n\n    # Método especial que se llama para crear una nueva instancia de la clase\n    def __new__(cls, *args, **kwargs):\n        # Si no existe ninguna instancia de la clase, se crea una\n        if cls.__instancia is None:\n            cls.__instancia = super(sigleton, cls).__new__(cls)\n        # Se devuelve la instancia única de la clase\n        return cls.__instancia\n\n# Creación de dos variables que apuntan a la instancia única de la clase sigleton\ninstancia1 = sigleton()\ninstancia2 = sigleton()\n\n# Comprobación de que ambas variables apuntan a la misma instancia\nprint(\"\\n-----------------Comprobacion de que las instancias son las mismas-------------------\")\nprint(\"instancia1 == instancia2:\", instancia1 is instancia2, \"\\n\")\n\n## Extra\n\nclass seccionDeUsuario:\n    # Variable de clase que almacenará la única instancia de la clase\n    __instancia = None\n\n    # Método especial que se llama para crear una nueva instancia de la clase\n    def __new__(cls):\n        # Si no existe ninguna instancia de la clase, se crea una\n        if cls.__instancia is None:\n            cls.__instancia = super().__new__(cls)\n            cls.__instancia.datos_de_usuario = None  # Inicialización de la variable de instancia\n        # Se devuelve la instancia única de la clase\n        return cls.__instancia\n\n    # Método para iniciar sesión con los datos del usuario\n    def iniciar_seccion(self, id, username, nombre, email):\n        self.datos_de_usuario = {\n            \"id\": id,\n            \"username\": username,\n            \"nombre\": nombre,\n            \"email\": email\n        }\n\n    # Método para recuperar los datos del usuario\n    def recuperar_datos(self):\n        if self.datos_de_usuario:\n            return self.datos_de_usuario\n        return \"no hay datos\"\n\n    # Método para cerrar la sesión del usuario\n    def cerrar_seccion(self):\n        self.datos_de_usuario = None\n\n# Creación de dos variables que apuntan a la instancia única de la clase seccionDeUsuario\nusuario1 = seccionDeUsuario()\nusuario1.iniciar_seccion(1, \"santyjl\", \"santiago\", \"algo@gmail.com\")\nprint(usuario1.recuperar_datos())\nprint(usuario1.cerrar_seccion())\n\nusuario2 = seccionDeUsuario()\nusuario2.iniciar_seccion(2, \"shechiremark\", \"justin\", \"cosa@gmail.com\")\nprint(usuario2.recuperar_datos())\nprint(usuario1.recuperar_datos())\n\nprint(usuario1 is usuario2)\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/rust/kenysdev.rs",
    "content": "/*\n╔═══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado                ║\n║ GitHub: https://github.com/Kenysdev   ║\n║ 2024 -  Rust                          ║\n╚═══════════════════════════════════════╝\n-----------------------------------------\n* PATRONES DE DISEÑO: SINGLETON\n-----------------------------------------\n\n* EJERCICIO #1:\n* Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n* con un ejemplo genérico.\n*/\n\n// https://doc.rust-lang.org/std/sync/struct.Once.html\nuse std::sync::Once;\n\nstruct Singleton {\n    field1: u32,\n    field2: String,\n}\n\nimpl Singleton {\n    // Función asociada que devuelve la única instancia de la estructura\n    fn instance() -> &'static Singleton {\n        static mut INSTANCE: *const Singleton = 0 as *const Singleton;\n        static ONCE: Once = Once::new();\n\n        unsafe {\n            ONCE.call_once(|| {\n                // Inicialización de la instancia única\n                let instance = Singleton {\n                    field1: 42,\n                    field2: String::from(\"str\"),\n                };\n                INSTANCE = Box::into_raw(Box::new(instance));\n            });\n            &*INSTANCE\n        }\n    }\n}\n\n/*\n____________________________________\n* EJERCICIO #2:\n* Utiliza el patrón de diseño \"singleton\" para representar una clase que\n* haga referencia a la sesión de usuario de una aplicación ficticia.\n* La sesión debe permitir asignar un usuario (id, username, nombre y email),\n* recuperar los datos del usuario y borrar los datos de la sesión.\n*/\n\nuse std::collections::HashMap;\n\nstruct UserSession {\n    user_id: i32,\n    user_name: String,\n    name: String,\n    email: String,\n}\n\nimpl UserSession {\n    fn instance() -> &'static mut UserSession {\n        static mut INSTANCE: *mut UserSession = std::ptr::null_mut();\n        static ONCE: std::sync::Once = std::sync::Once::new();\n\n        unsafe {\n            ONCE.call_once(|| {\n                let instance = UserSession {\n                    user_id: 0,\n                    user_name: String::new(),\n                    name: String::new(),\n                    email: String::new(),\n                };\n                INSTANCE = Box::into_raw(Box::new(instance));\n            });\n            &mut *INSTANCE\n        }\n    }\n\n    fn set_user(&mut self, user_id: i32, user_name: &str, name: &str, email: &str) {\n        self.user_id = user_id;\n        self.user_name = user_name.to_string();\n        self.name = name.to_string();\n        self.email = email.to_string();\n    }\n\n    fn get_user(&self) -> HashMap<String, String> {\n        let mut user_details = HashMap::new();\n        user_details.insert(String::from(\"id\"), self.user_id.to_string());\n        user_details.insert(String::from(\"username\"), self.user_name.clone());\n        user_details.insert(String::from(\"name\"), self.name.clone());\n        user_details.insert(String::from(\"email\"), self.email.clone());\n        user_details\n    }\n\n    fn logout(&mut self) {\n        self.user_id = 0;\n        self.user_name.clear();\n        self.name.clear();\n        self.email.clear();\n    }\n}\n\n//____________________________________\nfn main() {\n    println!(\"EJERCICIO #1\");\n    let singleton1 = Singleton::instance();\n    // singleton2 accede a la misma instancia que singleton1.\n    let singleton2 = Singleton::instance();\n\n    println!(\"Singleton campo1: {}\", singleton1.field1);\n    println!(\"Singleton campo2: {}\", singleton2.field2);\n    \n    // Comprobación de igualdad de referencias.\n    println!(\"{:?}\", std::ptr::eq(singleton1, singleton2));   \n\n    //____________________________________\n    println!(\"EJERCICIO #2\");\n\n    let login_user1 = UserSession::instance();\n\n    login_user1.set_user(1, \"Zoe_1\", \"Zoe\", \"Zoe@gm.com\");\n\n    let user_details1 = login_user1.get_user();\n    for (key, value) in user_details1.iter() {\n        println!(\"{}: {}\", key, value);\n    }\n\n    login_user1.logout();\n\n    //____________________________________\n\n    let login_user2 = UserSession::instance();\n\n    login_user2.set_user(2, \"Ben_1\", \"Ben\", \"Ben@gm.com\");\n\n    let user_details2 = login_user2.get_user();\n    for (key, value) in user_details2.iter() {\n        println!(\"{}: {}\", key, value);\n    }\n\n    login_user2.logout();\n    \n}\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/sql/Nicojsuarez2.sql",
    "content": "# #23 PATRONES DE DISEÑO: SINGLETON\n> #### Dificultad: Media | Publicación: 03/06/24 | Corrección: 10/06/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n * con un ejemplo genérico.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el patrón de diseño \"singleton\" para representar una clase que\n * haga referencia a la sesión de usuario de una aplicación ficticia.\n * La sesión debe permitir asignar un usuario (id, username, nombre y email),\n * recuperar los datos del usuario y borrar los datos de la sesión.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/swift/allbertoMD.swift",
    "content": "import Foundation\n\n\n\nclass Singleton {\n    // Propiedad estática que contiene la única instancia de la clase\n    static let shared = Singleton()\n    \n    // Inicializador privado para prevenir la creación de otras instancias\n    private init() {}\n    \n    // Métodos y propiedades de la clase\n    func sayHi(to name: String) {\n        print(\"Hi, \\(name)\")\n    }\n}\n\n// Acceso global desde cualquier parte del código\nlet instance1 = Singleton.shared\ninstance1.sayHi(to: \"Charly\")\n\nlet instance2 = Singleton.shared\ninstance2.sayHi(to: \"Marta\")\n\n// Verificar que ambas referencias apuntan a la misma instancia\nprint(instance1 === instance2)  // true\n\n\n\n\n// DIFICULTAD EXTRA\nprint(\"\\nDificultad Extra.\\n\")\n\n\nclass UserSession {\n    static let shared = UserSession()\n    \n    private init() {}\n    \n    var id: String = \"\"\n    var userName: String = \"\"\n    var name: String = \"\"\n    var email: String = \"\"\n    \n    func assigntID(_ id: String) {\n        self.id = id\n    }\n    \n    func assigntUserName(_ userName: String) {\n        self.userName = userName\n    }\n    \n    func assigntName(_ name: String) {\n        self.name = name\n    }\n    \n    func assignEmail(_ email: String) {\n        self.email = email\n    }\n    \n    func showSessionInfo() {\n        print(\"id: \\(id)\")\n        print(\"User Name: \\(userName)\")\n        print(\"Name: \\(name)\")\n        print(\"email: \\(email)\")\n    }\n    \n    func removeSession() {\n        id = \"\"\n        userName = \"\"\n        name = \"\"\n        email = \"\"\n        print(\"\\nSession Removed\")\n    }\n}\n\n\nlet userSession = UserSession.shared\n\nuserSession.assigntID(UUID().uuidString)\nuserSession.assigntUserName(\"Teophilus\")\nuserSession.assigntName(\"Pablo\")\nuserSession.assignEmail(\"tphls@gmail.com\")\n\nuserSession.showSessionInfo()\nuserSession.removeSession()\n\n\n\n\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/swift/blackriper.swift",
    "content": "import Foundation\n\n/*\n El patron singleton es un patron de diseño creacional que nos permite garantizar la unica instancia de una clase.\n para implementar este patron la clase o estructura debe cumplir los siguientes requisitos:\n\n 1. Debe tener un constructor privado\n 2. Debe tener un metodo de inicializacion estatico que devuelva una instancia de la clase\n\n para mas informacion puedes checar mi solucion en kotlin o visitar https://refactoring.guru/es/design-patterns/singleton \n \n */\n\n class IngredientSinglenton {\n    private var ingredients: [String] = []\n    static let shared = IngredientSinglenton()\n    private init() {}\n\n    func add(ingredient: String) {\n        ingredients.append(ingredient)\n    }\n\n    func showIngredients() {\n        print(ingredients)\n    }\n }\n\n // aunque creamos dos instancias diferentes  siguen utilizando la misma instancia de la clase IngredientSinglenton\n\n let singleton = IngredientSinglenton.shared\n singleton.add(ingredient: \"onions\")\n singleton.showIngredients()\n\n let singleton2 = IngredientSinglenton.shared\n singleton2.add(ingredient: \"chicken\")\n singleton2.showIngredients()\n\n\n// ejercicio extra \n\nstruct User{\n  let id : UUID\n  let username : String\n  let name : String\n  let email : String\n}\n\nlet mockDatabase = [\n  User(id: UUID(), username: \"blackriper\", name: \"Rodolfo\", email: \"devswift@apple.com\"),\n  User(id: UUID(), username: \"janedoe\", name: \"Jane\", email: \"janedoe@me.com\")\n]\n\nenum MockError: Error {\n  case userNotFound\n}\n\n\n\nclass SessionSingleton {\n  static let shared = SessionSingleton()\n  var currentSessionUser : User?\n\n  private init() {}\n\n  func login(username: String) throws {\n    if let user = mockDatabase.first(where: {$0.username == username}) {\n      currentSessionUser = user\n      print(\"logged in with session user: \\(currentSessionUser!)\")\n    }\n }\n\n  func logout() {\n    currentSessionUser = nil\n    print(\"logged out session user\")\n  }\n}\n\ndo {\n  let session = SessionSingleton.shared\n  try session.login(username: \"blackriper\")\n  session.logout()\n\n  try session.login(username: \"janedoe\")\n  session.logout()\n\n} catch MockError.userNotFound {\n  print(\"user not registered\")\n}\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/swift/pedroomar23.swift",
    "content": "import Foundation \n\nx/*\n * EJERCICIO:\n * Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n * con un ejemplo genérico.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el patrón de diseño \"singleton\" para representar una clase que\n * haga referencia a la sesión de usuario de una aplicación ficticia.\n * La sesión debe permitir asignar un usuario (id, username, nombre y email),\n * recuperar los datos del usuario y borrar los datos de la sesión.\n */\n\n class Singlenton {\n    static let shared: Singleton = Singlenton() \n\n    private init() {}\n\n    func someMethod() {\n        print(\"Este es un metodo generico Singlenton\")\n    }\n }\n\n// Ejemplo genérico de Singleton\nclass GenericSingleton {\n    static let shared = GenericSingleton()\n    \n    private init() {}\n    \n    func someMethod() {\n        print(\"This is a method of the Singleton\")\n    }\n}\n\n// Ejemplo de Singleton para una sesión de usuario\nclass UserSession {\n    static let shared = UserSession()\n    \n    private init() {}\n    \n    private var user: User?\n    \n    struct User {\n        let id: String\n        let username: String\n        let name: String\n        let email: String\n    }\n    \n    func assignUser(id: String, username: String, name: String, email: String) {\n        user = User(id: id, username: username, name: name, email: email)\n    }\n    \n    func getUserData() -> User? {\n        return user\n    }\n    \n    func clearSession() {\n        user = nil\n    }\n}\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/typescript/AChapeton.ts",
    "content": "interface fooType {\n  createInstance: () => {};\n  closeInstance: () => void;\n  printCount: () => void;\n}\n\nconst counter = () => {\n\n  let instance: {} | null = null;\n  let count: number = 0;\n\n  function printCount() {\n      console.log(\"Numero de instancias activas: \" + count);\n  }\n\n  function init() {\n      count++;\n      return {}\n  }\n\n  function createInstance() {\n      if (instance == null) {\n        instance = init();\n      }\n      return instance;\n  }\n\n  function closeInstance() {\n      count--;\n      instance = null;\n  }\n\n  return {\n      createInstance,\n      closeInstance,\n      printCount\n  }\n}\n\nlet foo: fooType = counter();\n\nfoo.printCount()  \nfoo.createInstance()\nfoo.printCount() \nfoo.createInstance()\nfoo.printCount() \nfoo.createInstance()\nfoo.printCount() \nfoo.closeInstance()\nfoo.printCount() \nfoo.createInstance();\nfoo.printCount();\nfoo.closeInstance();\nfoo.printCount();"
  },
  {
    "path": "Roadmap/23 - SINGLETON/typescript/Sac-Corts.ts",
    "content": "class Singleton {\n    private static instance: Singleton | null = null;\n    private data: string;\n\n    private constructor() {\n        this.data = \"Singleton instance data\";\n    }\n\n    public static getInstance(): Singleton {\n        if (!Singleton.instance) {\n            Singleton.instance = new Singleton();\n        }\n        return Singleton.instance;\n    }\n\n    public getData(): string {\n        return this.data;\n    }\n}\n\nconst instance1 = Singleton.getInstance();\nconsole.log(instance1.getData());\n\nconst instance2 = Singleton.getInstance();\nconsole.log(instance1 === instance2);\n\n\n// ** Extra Exercise ** //\n\nclass UserSession {\n    private static instance: UserSession | null = null;\n    private user: { id: number; username: string; name: string; email: string } | null;\n\n    private constructor() {\n        this.user = null;\n    }\n\n    public static getInstance(): UserSession {\n        if (!UserSession.instance) {\n            UserSession.instance = new UserSession();\n        }\n        return UserSession.instance;\n    }\n\n    public setUser(id: number, username: string, name: string, email: string): void {\n        this.user = { id, username, name, email };\n    }\n\n    public getUser(): { id: number; username: string; name: string; email: string } | string {\n        if (!this.user) {\n            return \"There is no user in the session\";\n        }\n        return this.user;\n    }\n\n    public clearSession(): void {\n        this.user = null;\n    }\n}\n\nconst session1 = UserSession.getInstance();\nsession1.setUser(1, \"Sac\", \"Isaac\", \"isaac@gmail.com\");\nconsole.log(session1.getUser());\n\nconst session2 = UserSession.getInstance();\nconsole.log(session1 === session2);\n\nsession2.clearSession();\nconsole.log(session1.getUser());\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/typescript/duendeintemporal.ts",
    "content": "//#23 { retosparaprogramadores } - PATRONES DE DISEÑO: SINGLETON\n/*\n * EJERCICIO:\n * Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n * con un ejemplo genérico.\n *\n * DIFICULTAD EXTRA (opcional):\n * Utiliza el patrón de diseño \"singleton\" para representar una clase que\n * haga referencia a la sesión de usuario de una aplicación ficticia.\n * La sesión debe permitir asignar un usuario (id, username, nombre y email),\n * recuperar los datos del usuario y borrar los datos de la sesión.\n */\n\nlet log = console.log;\n\n// Conditional check for browser environment\nif (typeof window !== 'undefined') {\n    window.addEventListener('load', () => {\n        const body: HTMLBodyElement | null = document.querySelector('body');\n        const title = document.createElement('h1');\n\n        body?.style.setProperty('background', '#000');\n        body?.style.setProperty('text-align', 'center');\n\n        title.textContent = 'Retosparaprogramadores #23.';\n        title.style.setProperty('font-size', '3.5vmax');\n        title.style.setProperty('color', '#fff');\n        title.style.setProperty('line-height', '100vh');\n\n        body?.appendChild(title);\n\n        setTimeout(() => {\n            alert('Retosparaprogramadores #23. Please open the Browser Developer Tools.');\n        }, 2000);\n        log('Retosparaprogramadores #23');\n    });\n} else {\n    log('This code is designed to run in a browser environment. Skipping window-related code.');\n    log('Retosparaprogramadores #23');\n}\n\n/* \nThe Singleton design pattern ensures that a class has a single instance and provides\na global point of access to that instance. Below, I will show you how to implement the \nSingleton pattern in TypeScript, followed by an example that represents a class for \nmanaging user sessions.\n*/\n\nclass Singleton {\n    private static instance: Singleton;\n\n    private constructor() {\n        // Initialize any properties you need here\n    }\n\n    public static getInstance(): Singleton {\n        if (!Singleton.instance) {\n            Singleton.instance = new Singleton();\n        }\n        return Singleton.instance;\n    }\n\n    // Example method\n    public someMethod(): void {\n        log(\"This is a method of the singleton.\");\n    }\n}\n\n// Using the Singleton\nconst instance1 = Singleton.getInstance();\nconst instance2 = Singleton.getInstance();\n\n// Note: both variables point to the same instance\nlog(instance1 === instance2); // true  \n\n// EXTRA DIFICULTY EXERCISE\n\nclass UserSession {\n    private static instance: UserSession;\n    private user: { id: number; username: string; name: string; email: string } | null;\n\n    private constructor() {\n        this.user = null; \n    }\n\n    public static getInstance(): UserSession {\n        if (!UserSession.instance) {\n            UserSession.instance = new UserSession();\n        }\n        return UserSession.instance;\n    }\n\n    public setUser(id: number, username: string, name: string, email: string): void {\n        this.user = { id, username, name, email };\n    }\n\n    public getUser(): { id: number; username: string; name: string; email: string } | null {\n        return this.user;\n    }\n\n    public clearSession(): void {\n        this.user = null;\n    }\n}\n\nconst session1 = UserSession.getInstance();\nsession1.setUser(1, 'FritzCat', 'Fritz Cat', 'fritzcat@proton.me');\n\nlog(session1.getUser()); // Object { id: 1, username: \"FritzCat\", name: \"Fritz Cat\", email: \"fritzcat@proton.me\" }\n\nconst session2 = UserSession.getInstance();\nlog(session2.getUser()); // Object { id: 1, username: \"FritzCat\", name: \"Fritz Cat\", email: \"fritzcat@proton.me\" }\n\nsession2.clearSession();\nlog(session1.getUser()); // null\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/typescript/eulogioep.ts",
    "content": "// Ejemplo básico del patrón Singleton\n// ===================================\n// El patrón Singleton asegura que una clase tenga una única instancia y proporciona\n// un punto de acceso global a ella. Esto es útil cuando exactamente un objeto \n// necesita coordinar acciones en todo el sistema.\n\nclass BasicSingleton {\n    // Instancia privada estática para almacenar la única instancia de la clase\n    private static instance: BasicSingleton;\n    \n    // Constructor privado para evitar la creación de instancias con 'new'\n    private constructor() {}\n    \n    // Método público estático que controla el acceso a la instancia\n    public static getInstance(): BasicSingleton {\n        // Si no existe la instancia, la crea\n        if (!BasicSingleton.instance) {\n            BasicSingleton.instance = new BasicSingleton();\n        }\n        // Retorna la instancia única\n        return BasicSingleton.instance;\n    }\n}\n\n// Ejercicio Extra: Singleton para Sesión de Usuario\n// ===============================================\n\n// Interfaz para definir la estructura de un usuario\ninterface User {\n    id: number;\n    username: string;\n    name: string;\n    email: string;\n}\n\nclass UserSession {\n    // Instancia privada estática\n    private static instance: UserSession;\n    \n    // Datos del usuario actual\n    private userData: User | null = null;\n    \n    // Constructor privado\n    private constructor() {}\n    \n    // Método para obtener la instancia\n    public static getInstance(): UserSession {\n        if (!UserSession.instance) {\n            UserSession.instance = new UserSession();\n        }\n        return UserSession.instance;\n    }\n    \n    // Método para establecer los datos del usuario\n    public setUser(user: User): void {\n        this.userData = user;\n    }\n    \n    // Método para obtener los datos del usuario\n    public getUser(): User | null {\n        return this.userData;\n    }\n    \n    // Método para cerrar la sesión\n    public logout(): void {\n        this.userData = null;\n    }\n}\n\n// Ejemplo de uso:\n// =============\n\n// Ejemplo básico\nconst singleton1 = BasicSingleton.getInstance();\nconst singleton2 = BasicSingleton.getInstance();\nconsole.log(singleton1 === singleton2); // true\n\n// Ejemplo de sesión de usuario\nconst session = UserSession.getInstance();\n\n// Crear un usuario de ejemplo\nconst user: User = {\n    id: 1,\n    username: \"john_doe\",\n    name: \"John Doe\",\n    email: \"john@example.com\"\n};\n\n// Iniciar sesión\nsession.setUser(user);\nconsole.log(session.getUser()); // Muestra los datos del usuario\n\n// Obtener la misma instancia en otro lugar del código\nconst anotherSessionReference = UserSession.getInstance();\nconsole.log(anotherSessionReference.getUser()); // Muestra los mismos datos\n\n// Cerrar sesión\nsession.logout();\nconsole.log(session.getUser()); // null"
  },
  {
    "path": "Roadmap/23 - SINGLETON/typescript/hozlucas28.ts",
    "content": "/*\n    Singleton pattern...\n*/\n\nconsole.log('Singleton pattern...')\n\ninterface ICounter {\n    getCount(): Counter['count']\n    decrement(): this\n    increment(): this\n}\n\nclass Counter implements ICounter {\n    private static instance: Counter\n\n    private count: number\n\n    private constructor() {\n        this.count = 0\n    }\n\n    public static getInstance(): Counter {\n        if (!Counter.instance) {\n            Counter.instance = new Counter()\n        }\n\n        return Counter.instance\n    }\n\n    public getCount(): number {\n        return this.count\n    }\n\n    public decrement(): this {\n        this.count--\n        return this\n    }\n\n    public increment(): this {\n        this.count++\n        return this\n    }\n}\n\nconst counter01: Counter = Counter.getInstance()\nconst counter02: Counter = Counter.getInstance()\n\nconsole.log(\n    '\\nAre `counter01` and `counter02` the same instance of `Counter` class?',\n    counter01 === counter02\n)\n\nconsole.log('\\nMethod call of `counter01` instance...')\n\ncounter01.increment().increment().increment()\nconsole.log('\\ncounter01.increment().increment().increment()')\n\nconsole.log(\n    '\\nCount attribute of `counter01` instance -->',\n    counter01.getCount()\n)\n\nconsole.log('\\nMethod call of `counter02` instance...')\n\ncounter02.decrement()\nconsole.log('\\ncounter02.decrement()')\n\nconsole.log(\n    '\\nCount attribute of `counter02` instance -->',\n    counter02.getCount()\n)\n\nconsole.log(\n    '\\n# ---------------------------------------------------------------------------------- #\\n'\n)\n\n/*\n    Additional challenge...\n*/\n\nconsole.log('Additional challenge...')\n\ninterface IUserSession {\n    getEmail(): UserSession['email']\n    getId(): UserSession['id']\n    getName(): UserSession['name']\n    getUserName(): UserSession['userName']\n\n    setEmail(newEmail: UserSession['email']): this\n    setId(newId: UserSession['id']): this\n    setName(newName: UserSession['name']): this\n    setUserName(newUserName: UserSession['userName']): this\n\n    deleteData(): this\n}\n\ninterface AUserSession {\n    email: string\n    id: string\n    name: string\n    userName: string\n}\n\nclass UserSession implements IUserSession {\n    private static instance: UserSession\n\n    private email: AUserSession['email']\n    private id: AUserSession['email']\n    private name: AUserSession['email']\n    private userName: AUserSession['email']\n\n    private constructor({email, id, name, userName}: AUserSession) {\n        this.email = email\n        this.id = id\n        this.name = name\n        this.userName = userName\n    }\n\n    public static getInstance(\n        {\n            email = '',\n            id = '',\n            name = '',\n            userName = '',\n        }: Partial<AUserSession> = {\n            email: '',\n            id: '',\n            name: '',\n            userName: '',\n        }\n    ): UserSession {\n        if (!UserSession.instance) {\n            UserSession.instance = new UserSession({\n                email,\n                id,\n                name,\n                userName,\n            })\n        }\n\n        return UserSession.instance\n    }\n\n    public getEmail(): AUserSession['email'] {\n        return this.email\n    }\n\n    public getId(): AUserSession['id'] {\n        return this.id\n    }\n\n    public getName(): AUserSession['name'] {\n        return this.name\n    }\n\n    public getUserName(): AUserSession['userName'] {\n        return this.userName\n    }\n\n    public setEmail(newEmail: AUserSession['email']): this {\n        this.email = newEmail\n        return this\n    }\n\n    public setId(newId: AUserSession['id']): this {\n        this.id = newId\n        return this\n    }\n\n    public setName(newName: AUserSession['name']): this {\n        this.name = newName\n        return this\n    }\n\n    public setUserName(newUserName: AUserSession['userName']): this {\n        this.userName = newUserName\n        return this\n    }\n\n    public deleteData(): this {\n        this.email = ''\n        this.id = ''\n        this.name = ''\n        this.userName = ''\n\n        return this\n    }\n}\n\nconst userSession: UserSession = UserSession.getInstance({\n    email: 'gomezjuan69@gmail.com',\n    id: '155-AV25-12Z',\n    name: 'Juan',\n    userName: 'Juanceto01',\n})\n\nconsole.log(\n    '\\nUser:',\n    userSession.getId(),\n    userSession.getName(),\n    userSession.getUserName(),\n    userSession.getEmail()\n)\n\nuserSession.deleteData()\nconsole.log('\\nUser data deleted!')\n\nconsole.log(\n    '\\nUser:',\n    userSession.getId(),\n    userSession.getName(),\n    userSession.getUserName(),\n    userSession.getEmail()\n)\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/typescript/marialunatito.ts",
    "content": "// Dominio\ninterface IUser {\n  id: number;\n  first_name: string;\n  last_name: string;\n  email: string;\n  birthday: Date;\n}\n\n// Entidad inmutable\nclass User implements IUser {\n  readonly id: number;\n  readonly first_name: string;\n  readonly last_name: string;\n  readonly email: string;\n  readonly birthday: Date;\n\n  constructor(props: IUser) {\n    this.id = props.id;\n    this.first_name = props.first_name;\n    this.last_name = props.last_name;\n    this.email = props.email;\n    this.birthday = new Date(props.birthday); // defensivo\n    Object.freeze(this); // inmutabilidad superficial\n  }\n}\n\n// Singleton: único gestor de sesiones en el proceso\nclass SessionManager {\n  private static instance?: SessionManager;\n  private store = new Map<number, User>();\n\n  private constructor() {}\n\n  static getInstance(): SessionManager {\n    if (!this.instance) this.instance = new SessionManager();\n    return this.instance;\n  }\n\n  // Crea o retorna sesión existente para el user.id\n  login(userData: IUser): User {\n    const existing = this.store.get(userData.id);\n    if (existing) return existing;\n\n    const user = new User(userData);\n    this.store.set(user.id, user);\n    return user;\n  }\n\n  getById(userId: number): User | undefined {\n    return this.store.get(userId);\n  }\n\n  // true si removió, false si no existía\n  logout(userId: number): boolean {\n    return this.store.delete(userId);\n  }\n\n  // lectura segura\n  list(): ReadonlyArray<User> {\n    return [...this.store.values()];\n  }\n\n  clear(): void {\n    this.store.clear();\n  }\n}\n\n// ================== DEMO ==================\nconst session = SessionManager.getInstance();\n\nconst user1: IUser = {\n  id: 1,\n  first_name: \"Maria\",\n  last_name: \"Luna\",\n  birthday: new Date(\"2020-01-02\"),\n  email: \"maria@example.com\",\n};\n\nconst user2: IUser = {\n  id: 2,\n  first_name: \"Carmen\",\n  last_name: \"Luna\",\n  birthday: new Date(\"2022-04-10\"),\n  email: \"carmen@example.com\",\n};\n\nconst s1 = session.login(user1);\nconst s2 = session.login(user2);\nconst s3 = session.login(user1);\n\nconsole.log(\"s1 === s2 ?\", s1 === s2); // false\nconsole.log(\"s1 === s3 ?\", s1 === s3); // true\nconsole.log(\"list before logout:\", session.list());\n\nsession.logout(2);\nconsole.log(\"list after logout:\", session.list());\n\n// script for run\n// npx ts-node \"Roadmap/23 - SINGLETON/typescript/marialunatito.ts\"\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/typescript/victoriaparraf.ts",
    "content": "class Singleton {\n    // Atributo estático que mantendrá la instancia única\n    private static instance: Singleton;\n\n    // Un ejemplo de un atributo de la clase\n    public data: string;\n\n    // Constructor privado para evitar instancias directas\n    private constructor() {\n        this.data = \"Singleton Instance Data\";\n    }\n\n    // Método estático para obtener la instancia única\n    public static getInstance(): Singleton {\n        if (!Singleton.instance) {\n            Singleton.instance = new Singleton();\n        }\n        return Singleton.instance;\n    }\n\n    // Un método ejemplo de la clase Singleton\n    public displayData(): void {\n        console.log(this.data);\n    }\n}\n\n// Intentando obtener la instancia del Singleton\nconst singleton1 = Singleton.getInstance();\nconst singleton2 = Singleton.getInstance();\n\n// Modificando el atributo data a través de la primera instancia\nsingleton1.data = \"New Data\";\n\n// Ambas instancias deberían ser iguales y reflejar el mismo estado\nsingleton1.displayData(); // Output: New Data\nsingleton2.displayData(); // Output: New Data\n\n// Verificando que ambas referencias son iguales\nconsole.log(singleton1 === singleton2); // Output: true\n\n\n/************************************************ */\n\ninterface User {\n    id: number;\n    username: string;\n    nombre: string;\n    email: string;\n}\n\nclass UserSession {\n    // Atributo estático que mantendrá la instancia única\n    private static instance: UserSession;\n\n    // Atributo que almacenará los datos del usuario\n    private user: User | null = null;\n\n    // Constructor privado para evitar instancias directas\n    private constructor() {}\n\n    // Método estático para obtener la instancia única\n    public static getInstance(): UserSession {\n        if (!UserSession.instance) {\n            UserSession.instance = new UserSession();\n        }\n        return UserSession.instance;\n    }\n\n    // Método para asignar un usuario a la sesión\n    public setUser(user: User): void {\n        this.user = user;\n    }\n\n    // Método para recuperar los datos del usuario\n    public getUser(): User | null {\n        return this.user;\n    }\n\n    // Método para borrar los datos de la sesión\n    public clearSession(): void {\n        this.user = null;\n    }\n}\n\n// Uso de la clase UserSession\nconst session1 = UserSession.getInstance();\nconst session2 = UserSession.getInstance();\n\n// Verificando que ambas referencias son iguales\nconsole.log(session1 === session2); // Output: true\n\n// Asignando un usuario a la sesión\nsession1.setUser({\n    id: 1,\n    username: \"john_doe\",\n    nombre: \"John Doe\",\n    email: \"john.doe@example.com\"\n});\n\n// Recuperando los datos del usuario\nconsole.log(session1.getUser()); // Output: { id: 1, username: 'john_doe', nombre: 'John Doe', email: 'john.doe@example.com' }\nconsole.log(session2.getUser()); // Output: { id: 1, username: 'john_doe', nombre: 'John Doe', email: 'john.doe@example.com' }\n\n// Borrando los datos de la sesión\nsession1.clearSession();\n\n// Verificando que los datos se han borrado\nconsole.log(session1.getUser()); // Output: null\nconsole.log(session2.getUser()); // Output: null\n"
  },
  {
    "path": "Roadmap/23 - SINGLETON/vb.net/kenysdev.vb",
    "content": "' ╔══════════════════════════════════════╗\n' ║ Autor:  Kenys Alvarado               ║\n' ║ GitHub: https://github.com/Kenysdev  ║\n' ║ 2024 -  VB.NET                       ║\n' ╚══════════════════════════════════════╝\n'-----------------------------------------------\n'* PATRONES DE DISEÑO: SINGLETON\n'-----------------------------------------------\n\n'* EJERCICIO #1:\n'* Explora el patrón de diseño \"singleton\" y muestra cómo crearlo\n'* con un ejemplo genérico.\n\nPublic Class Singleton\n\n    ' Constructor privado para evitar la instanciación directa.\n    Private Sub New()\n    End Sub\n\n    ' Propiedad compartida que devuelve la única instancia de la clase.\n    Public Shared ReadOnly Property Instance As Singleton = New Singleton()\nEnd Class\n\n\n'-----------------------------------------------\n'* EJERCICIO #2\n'* Utiliza el patrón de diseño \"singleton\" para representar una clase que\n'* haga referencia a la sesión de usuario de una aplicación ficticia.\n'* La sesión debe permitir asignar un usuario (id, username, nombre y email),\n'* recuperar los datos del usuario y borrar los datos de la sesión.\n\nPublic Class UserSession\n    Private _userId As Integer\n    Private _userName As String\n    Private _name As String\n    Private _email As String\n\n    Private Sub New()\n    End Sub\n\n    Public Shared ReadOnly Property Instance As UserSession = New UserSession()\n\n    Public Sub SetUser(userId As Integer, userName As String, name As String, email As String)\n        _userId = userId\n        _userName = userName\n        _name = name\n        _email = email\n    End Sub\n\n    Public Function GetUser() As Dictionary(Of String, Object)\n        Dim userDetails As New Dictionary(Of String, Object) From {\n            {\"id\", _userId},\n            {\"username\", _userName},\n            {\"name\", _name},\n            {\"email\", _email}\n        }\n        Return userDetails\n    End Function\n\n    Public Sub Logout()\n        _userId = 0\n        _userName = Nothing\n        _name = Nothing\n        _email = Nothing\n    End Sub\nEnd Class\n\n'-----------------------------------------------\nModule Program\n\n    Sub Main()\n        Console.WriteLine(\"EJERCICIO #1\")\n        Dim singleton1 As Singleton = Singleton.Instance\n        ' singleton2 accede a la misma instancia que singleton1.\n        Dim singleton2 As Singleton = Singleton.Instance\n\n        ' Comprobación de igualdad de referencias.\n        Console.WriteLine(singleton1 Is singleton2)\n\n        '-----------------------------------------------\n        Console.WriteLine(\"EJERCICIO #2\")\n        Dim login_user1 As UserSession = UserSession.Instance\n        login_user1.SetUser(1, \"Zoe_1\", \"Zoe\", \"Zoe@gm.com\")\n        Dim userDetails1 As Dictionary(Of String, Object) = login_user1.GetUser()\n        For Each kvp In userDetails1\n            Console.WriteLine($\"{kvp.Key}: {kvp.Value}\")\n        Next\n\n        login_user1.Logout()\n\n        Dim login_user2 As UserSession = UserSession.Instance\n        login_user2.SetUser(2, \"Ben_1\", \"Ben\", \"Ben@gm.com\")\n        Dim userDetails2 As Dictionary(Of String, Object) = login_user2.GetUser()\n        For Each kvp In userDetails2\n            Console.WriteLine($\"{kvp.Key}: {kvp.Value}\")\n        Next\n\n        login_user2.Logout()\n\n    End Sub\n\nEnd Module\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/bash/rantamhack.sh",
    "content": "#!/bin/bash\n\n\n# Bash no tiene soporte para decoradores por lo que hay que simularlos\n# en base a funciones y variable globales\n\n\necho -e \"\\n\\n=======================================EJERCICIO=======================================\\n\\n\"\n\n\n# * EJERCICIO:\n# * Explora el concepto de \"decorador\" y muestra como crearlo\n# * con un ejemplo generico.\n\n\nfunction decorator() {\n    local function=\"$1\"\n    shift\n    echo -e \"\\nEste texto se imprime antes de realizar un calculo \"\n    \"$function\" \"$@\"\n    echo -e \"Este texto se imprime despues de realizar el calculo\\n\"\n}\n\n\nfunction sum() {\n    local num1=$1\n    local num2=$2\n    echo \"El resultado de la suma es $(($1 + $2))\"\n}    \n  \nfunction subtract() {\n    local num1=$1\n    local num2=$2\n    echo \"El resultado de la resta es $(($1 - $2))\"\n}\n \nfunction pow() {\n    local base=$1\n    local exponente=$2\n    echo -e \"El resultado de elevar la base $1 a la potencia $2 es: $(($1**$2))\"\n}\n\n\n\ndecorator sum 10 5\ndecorator subtract 10 6\ndecorator pow 5 3\n\n\necho -e \"\\n\\n=======================================DIFICULTAD EXTRA=======================================\\n\\n\"\n\n\n\n# * DIFICULTAD EXTRA (opcional):\n# * Crea un decorador que sea capaz de contabilizar cuantas veces\n# * se ha llamado a una funcion y aplicalo a una funcion de tu eleccion.\n\ndeclare -A COUNTER\n\n\nfunction decorator_counter() {\n    local function=\"$1\"\n    shift\n    \n    COUNTER[\"$function\"]=$(( ${COUNTER[\"$function\"]} +1 ))\n    if [ ${COUNTER[\"$function\"]} == 1 ]; then\n         echo \"La funcion ha sido llamada ${COUNTER[\"$function\"]} vez\"\n    else\n        echo \"La funcion ha sido llamada ${COUNTER[\"$function\"]} veces\"\n    fi\n    \"$function\" \"$@\"\n}\n\nfunction multiply() {\n    local a=\"$1\"\n    local b=\"$2\"\n    echo $(($1 * $2))\n}\n\nfunction multiply_decorated() {\n    decorator_counter multiply \"$@\"\n}\n\n\nmultiply_decorated 5 3\nmultiply_decorated 7 2\nmultiply_decorated 15 17\nmultiply_decorated 24 42\n\n\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/c#/hequebo.cs",
    "content": "class Program\n{\n    static void Main(string[] args)\n    {\n        // Componente original\n        Console.WriteLine(\"---Componente original---\");\n        IComponent component = new ConcreteComponent();\n        component.Operation();\n        // Decorator\n        Console.WriteLine(\"---Decorator---\");\n        Decorator decorator = new ConcreteDecorator();\n        decorator.SetComponent(component);\n        decorator.Operation();\n\n        // Ejercicio extra\n        Console.WriteLine(\"---Ejercicio extra---\");\n        CountDecorator countDecorator = new ConcreteCountDecorator();\n        countDecorator.SetComponent(component);\n        countDecorator.Operation();\n        countDecorator.Operation();\n        countDecorator.Operation();\n        countDecorator.Operation();\n        countDecorator.Operation();\n\n    }\n}\n/*\n * El patrón Decorator es un patrón de \n * diseño que nos permite agregar \n * comportamiento a un objeto sin afectar\n * el comportamiento de otros objetos de \n * la misma clase.\n */\n\n/*\n * Definimos la interface base que define\n * la funcionalidad del objeto\n */\ninterface IComponent\n{\n    public void Operation();\n}\n/* \n * Se crea el componente concreto, una \n * clase que implementa el metodo de\n * la interface\n */\nclass ConcreteComponent : IComponent\n{\n    public void Operation() => Console.WriteLine(\"Ejecutando operación...\");\n}\n/* \n * Se crea el decorador base, una clase\n * abstracta que implementa la interface\n * y permite agregar funcionalidad, no\n * es obligatorio crear el decorador base\n */\nabstract class Decorator : IComponent\n{\n    protected IComponent _component;\n\n    public void SetComponent(IComponent component) => _component = component;\n    public virtual void Operation()\n    {\n        if (_component != null) \n            _component.Operation();\n    }\n}\n/*\n * Se crea el decorador concreto, hereda de\n * la clase abstracta Decorator y agrega la \n * funcionalidad extra al objeto\n */\nclass ConcreteDecorator : Decorator\n{\n    public override void Operation()\n    {\n        base.Operation();\n        Console.WriteLine(\"Se expande funcionalidad con Decorator...\");\n    }\n}\nabstract class CountDecorator : IComponent\n{\n    protected IComponent _component;\n    protected int count;\n    public void SetComponent(IComponent component) \n    {\n        _component = component;\n        count = 0;\n    }\n    public virtual void Operation()\n    {\n        if (_component != null) \n            _component.Operation();\n    }\n}\nclass ConcreteCountDecorator : CountDecorator\n{\n    public override void Operation()\n    {\n        base.Operation();\n        count++;\n        Console.WriteLine($\"Se ha llamado a la función {count} veces\");\n    }\n}\n    \n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/c#/kenysdev.cs",
    "content": "#pragma warning disable CA1050\n/*\n╔══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado               ║\n║ GitHub: https://github.com/Kenysdev  ║\n║ 2024 -  C#                           ║\n╚══════════════════════════════════════╝\n------------------------------------------\n* DECORADORES\n------------------------------------------\nMas info: https://bytehide.com/blog/decorator-pattern-csharp\n\n* EJERCICIO #1:\n* Explora el concepto de \"decorador\" y muestra cómo crearlo\n* con un ejemplo genérico.\n*/\n\n// Interfaz\npublic interface ISayHello {\n    void SayHello(string first_name, string last_name);\n}\n\n// Componente Concreto\npublic class HelloSpeaker : ISayHello {\n    public void SayHello(string first_name, string last_name) {\n        Console.WriteLine($\"Hola, {first_name} {last_name}!\");\n    }\n}\n\n// Decorador Base\npublic abstract class DecoratorBase : ISayHello {\n    protected ISayHello _helloSpeaker;\n\n    public DecoratorBase(ISayHello helloSpeaker) {\n        _helloSpeaker = helloSpeaker;\n    }\n\n    public virtual void SayHello(string first_name, string last_name) {\n        _helloSpeaker.SayHello(first_name, last_name);\n    }\n}\n\n// Decorador Concreto\npublic class MyDecorator : DecoratorBase {\n    public MyDecorator(ISayHello helloSpeaker) : base(helloSpeaker) { }\n\n    public override void SayHello(string first_name, string last_name) {\n        Console.WriteLine(\"\\nAntes de llamar a la función.\");\n        base.SayHello(first_name, last_name);\n        Console.WriteLine(\"Después de llamarla\");\n    }\n}\n\n/*\n__________________________________\n* EJERCICIO #2:\n* Crea un decorador que sea capaz de contabilizar cuántas veces\n* se ha llamado a una función y aplícalo a una función de tu elección.\n*/\npublic interface IFunction{\n    void Execute(params object[] args);\n}\n\npublic class Function : IFunction{\n    private readonly string _name;\n\n    public Function(string name) {\n        _name = name;\n    }\n\n    public void Execute(params object[] args) {\n        Console.WriteLine($\"\\nLa función '{_name}':\");\n    }\n}\n\npublic abstract class CallCountDecorator : IFunction {\n    protected IFunction _function;\n    protected int _calls;\n\n    public CallCountDecorator(IFunction function) {\n        _function = function;\n        _calls = 0;\n    }\n\n    public void Execute(params object[] args) {\n        _calls++;\n        _function.Execute(args);\n        Console.WriteLine($\"Ha sido llamada {_calls} veces\");\n    }\n}\n\npublic class CountCallsDecorator : CallCountDecorator {\n    public CountCallsDecorator(IFunction function) : base(function) { }\n}\n\n// __________________________________\nclass Program {    \n    static void Main() {\n        Console.WriteLine(\"EJERCICIO #1\");\n\n        ISayHello helloSpeaker = new HelloSpeaker();\n        ISayHello decoratedHelloSpeaker = new MyDecorator(helloSpeaker);\n        decoratedHelloSpeaker.SayHello(\"Zoe\", \"Roy\");\n\n        // __________________________________\n        Console.WriteLine(\"\\nEJERCICIO #2\");\n\n        IFunction functionA = new CountCallsDecorator(new Function(\"A\"));\n        IFunction functionB = new CountCallsDecorator(new Function(\"B\"));\n\n        functionA.Execute();\n        functionA.Execute();\n        functionA.Execute();\n\n        functionB.Execute();\n        functionB.Execute();\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/c++/hectorio23.cpp",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23 \n#include <iostream>\n#include <functional>\n\n// Función que actúa como un decorador genérico\nstd::function<void()> customDecorator(std::function<void()> func) {\n    return [func]() {\n        std::cout << \"Algo se está haciendo antes de llamar a la función\" << std::endl;\n        func();\n        std::cout << \"Algo se está haciendo después de llamar a la función\" << std::endl;\n    };\n}\n\n// Función que queremos decorar\nvoid doSomething() {\n    std::cout << \"Esta es mi función\" << std::endl;\n}\n\n// Clase que actúa como un contador de llamadas\nclass Counter {\npublic:\n    Counter(std::function<void()> func) : func(func), llamadas(0) {}\n\n    void operator()() {\n        llamadas++;\n        std::cout << \"Se ha llamado a la función \" << llamadas << \" veces\" << std::endl;\n        func();\n    }\n\nprivate:\n    std::function<void()> func;\n    int llamadas;\n};\n\n// Función que queremos decorar con el contador\nvoid saludar() {\n    std::cout << \"¡Hola Mundo!\" << std::endl;\n}\n\nint main() {\n    // Aplica el decorador customDecorator a doSomething\n    auto doSomethingDecorado = customDecorator(doSomething);\n    doSomethingDecorado(); // Llama a la función decorada\n\n    // Aplica el contador a saludar\n    Counter saludarDecorado(saludar);\n    saludarDecorado(); // Primera llamada\n    saludarDecorado(); // Segunda llamada\n    saludarDecorado(); // Tercera llamada\n\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/ejercicio.md",
    "content": "# #24 PATRONES DE DISEÑO: DECORADORES\n> #### Dificultad: Fácil | Publicación: 10/06/24 | Corrección: 17/06/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Explora el concepto de \"decorador\" y muestra cómo crearlo\n * con un ejemplo genérico.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un decorador que sea capaz de contabilizar cuántas veces\n * se ha llamado a una función y aplícalo a una función de tu elección.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/24 - DECORADORES/go/AmadorQuispe.go",
    "content": "package main\n\nimport \"fmt\"\n\ntype ICoffee interface {\n\tgetPrice() uint\n}\n\ntype CoffeeSimple struct{}\n\nfunc (c *CoffeeSimple) getPrice() uint {\n\treturn 25\n}\n\ntype CoffeeWithMilk struct {\n\tcoffee ICoffee\n}\n\nfunc (c *CoffeeWithMilk) getPrice() uint {\n\tadditional := 5\n\treturn c.coffee.getPrice() + uint(additional)\n}\n\ntype CoffeeWithSugar struct {\n\tcoffee ICoffee\n}\n\nfunc (c *CoffeeWithSugar) getPrice() uint {\n\tadditional := 2\n\treturn c.coffee.getPrice() + uint(additional)\n}\n\n//EXTRA\ntype CoffeeWithCounting struct {\n\tcoffee ICoffee\n\tcount  uint\n}\n\nfunc (c *CoffeeWithCounting) getPrice() uint {\n\tc.count++\n\treturn c.coffee.getPrice()\n}\n\nfunc main() {\n\t//Coffee Simple\n\tcoffee := &CoffeeSimple{}\n\tfmt.Println(\"Price coffee normal\", coffee.getPrice())\n\t//Add Milk\n\tcoffeeWithMilk := CoffeeWithMilk{\n\t\tcoffee: coffee,\n\t}\n\tfmt.Println(\"Price coffee with milk\", coffeeWithMilk.getPrice())\n\t//Add sugar\n\tcoffeeWithSugar := CoffeeWithSugar{\n\t\tcoffee: &coffeeWithMilk,\n\t}\n\tfmt.Println(\"Price coffee with milk and sugar\", coffeeWithSugar.getPrice())\n\t//Add  counting calls\n\tcoffeeWithCounting := CoffeeWithCounting{\n\t\tcoffee: &coffeeWithSugar,\n\t}\n\tcoffeeWithCounting.getPrice()\n\tcoffeeWithCounting.getPrice()\n\tcoffeeWithCounting.getPrice()\n\tfmt.Println(\"getPrice method has been called \", coffeeWithCounting.count)\n\n}\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/go/N0HagoNada.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n\t\"runtime\"\n)\n\n// Explorando el concepto de Decorador\n\n// Interfaz del componente\ntype IPizza interface {\n\tgetPrice() int\n}\n\n// Componente concreto\ntype VeggieMania struct {\n}\n\nfunc (p *VeggieMania) getPrice() int {\n\treturn 12\n}\n\n// Decorador concreto\ntype TomatoTopping struct {\n\tpizza IPizza\n}\n\nfunc (c *TomatoTopping) getPrice() int {\n\tpizzaPrice := c.pizza.getPrice()\n\treturn pizzaPrice + 7\n}\n\n// Decorador 2\ntype CheeseTopping struct {\n\tpizza IPizza\n}\n\nfunc (c *CheeseTopping) getPrice() int {\n\tpizzaPrice := c.pizza.getPrice()\n\treturn pizzaPrice + 10\n}\n\nfunc main() {\n\n\tpizza := &VeggieMania{}\n\n\t//Añadir queso\n\tpizzaWithCheese := &CheeseTopping{\n\t\tpizza: pizza,\n\t}\n\t//Añadir tomate\n\tpizzaWithCheeseAndTomato := &TomatoTopping{\n\t\tpizza: pizzaWithCheese,\n\t}\n\n\tfmt.Printf(\"Price of veggeMania with tomato and cheese topping is %d\\n\", pizzaWithCheeseAndTomato.getPrice())\n\tfmt.Println(\"-------------------------------------- RETO ------------------------------------------------\")\n\t// Aplicamos el decorador CountCalls a nuestra función de ejemplo ExampleFunction\n\tDecoratedFunction := CountCalls(ExampleFunction)\n\n\t// Llamamos a la función decorada varias veces para ver el conteo en acción\n\tDecoratedFunction(2, 3)\n\tDecoratedFunction(5, 7)\n\tDecoratedFunction(1, 1)\n}\n\n// **************** RETO **********************//\n\n// Definimos un tipo de función que toma dos enteros y devuelve un entero\ntype ExampleFunc func(a, b int) int\n\n// Definimos un tipo de función decoradora que también toma dos enteros y devuelve un entero\ntype DecoratedFunc func(a, b int) int\n\ntype AnyFunc func(...interface{}) []interface{}\n\nfunc CountCalls(fn ExampleFunc) DecoratedFunc {\n\tcallCount := make(map[string]int)\n\n\t// Devolvemos una nueva función que envuelve la función original\n\treturn func(a, b int) int {\n\t\t// Obtenemos el nombre de la función original usando reflexión\n\t\tfnName := runtime.FuncForPC(reflect.ValueOf(fn).Pointer()).Name()\n\n\t\t// Incrementamos el contador de llamadas para esta función\n\t\tcallCount[fnName]++\n\n\t\t// Imprimimos el mensaje de conteo\n\t\tfmt.Printf(\"Llamada a %s: %d veces\\n\", fnName, callCount[fnName])\n\n\t\t// Llamamos a la función original y devolvemos el resultado\n\t\treturn fn(a, b)\n\t}\n}\n\n// Función de ejemplo a la cual aplicaremos el decorador\nfunc ExampleFunction(a, b int) int {\n\treturn a + b\n}\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/go/kodenook.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"time\"\n)\n\nfunc main() {\n\ttimeTrack(func() { fmt.Println(\"Hello, Go\") })\n}\n\nfunc timeTrack(callback func()) {\n\tstart := time.Now()\n\n\tcallback()\n\n\tfmt.Printf(\"time: %v\", time.Since(start))\n}\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/go/qwik-zgheib.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n)\n\ntype Greeter interface {\n\tGreet(name string) string\n}\n\ntype SimpleGreeter struct{}\n\nfunc (g SimpleGreeter) Greet(name string) string {\n\treturn fmt.Sprintf(\"Hello, %s!\", name)\n}\n\ntype ExcitedDecorator struct {\n\tGreeter Greeter\n}\n\nfunc (e ExcitedDecorator) Greet(name string) string {\n\treturn e.Greeter.Greet(name) + \" How are you doing today?\"\n}\n\ntype AddGreetingCountDecorator struct {\n\tGreeter   Greeter\n\tCallCount int\n}\n\nfunc (c *AddGreetingCountDecorator) Greet(name string) string {\n\tc.CallCount++\n\treturn c.Greeter.Greet(name)\n}\n\nfunc (c *AddGreetingCountDecorator) GetCallCount() int {\n\treturn c.CallCount\n}\n\nfunc main() {\n\tgreeter := SimpleGreeter{}\n\n\texcitedGreeter := ExcitedDecorator{Greeter: greeter}\n\n\tcountingGreeter := &AddGreetingCountDecorator{Greeter: excitedGreeter}\n\n\tfmt.Println(countingGreeter.Greet(\"qwik\"))\n\tfmt.Println(countingGreeter.Greet(\"zgheib\"))\n\tfmt.Println(countingGreeter.Greet(\"mossad\"))\n\n\tfmt.Printf(\"Greet method has been called %d times\\n\", countingGreeter.GetCallCount())\n}\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/go/raynerpv2022.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"time\"\n)\n\ntype root_function func()\n\nfunc func_1(f root_function) root_function {\n\tstunden := 0\n\treturn func() {\n\t\tf()\n\t\ttime.Sleep(time.Duration(stunden) * time.Second)\n\t\tstunden += 1\n\t\tfmt.Printf(\"Stunden %v\\n\", stunden)\n\n\t}\n}\n\nfunc qq() {\n\tfmt.Print(\"function qq\")\n}\n\nfunc cc() {\n\tfmt.Print(\"function cc\")\n}\n\nfunc aa() {\n\tfmt.Print(\"function aa\")\n}\n\nfunc main() {\n\tqqq := func_1(qq)\n\tccc := func_1(cc)\n\taaa := func_1(aa)\n\tqqq()\n\tccc()\n\taaa()\n\tccc()\n\tccc()\n\tccc()\n\tccc()\n\tccc()\n\tqqq()\n\tqqq()\n\taaa()\n}\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/go/thegera4.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n)\n\n// El patrón de diseño Decorador es una forma elegante de agregar funcionalidad a un objeto existente \n// sin modificar su estructura. El Decorador permite envolver un objeto con otros objetos que agregan \n// responsabilidades adicionales.\n\ntype Drink interface {\n    Cost() float64\n    Description() string\n}\n\ntype BlackCoffee struct{}\n\nfunc (coffee *BlackCoffee) Cost() float64 {\n    return 2.0\n}\n\nfunc (coffee *BlackCoffee) Description() string {\n    return \"Café negro\"\n}\n\n// Decorador: Leche\ntype Milk struct {\n    beverage Drink\n}\n\nfunc (milk *Milk) Cost() float64 {\n    return milk.beverage.Cost() + 1.0\n}\n\nfunc (milk *Milk) Description() string {\n    return milk.beverage.Description() + \", con leche\"\n}\n\n// Decorador: Azúcar\ntype Sugar struct {\n    beverage Drink\n}\n\nfunc (sugar *Sugar) Cost() float64 {\n    return sugar.beverage.Cost() + 0.5\n}\n\nfunc (sugar *Sugar) Description() string {\n    return sugar.beverage.Description() + \", con azúcar\"\n}\n\n// Uso:\nfunc main() {\n    café := &BlackCoffee{}\n    caféConLeche := &Milk{beverage: café}\n    caféConLecheYAzúcar := &Sugar{beverage: caféConLeche}\n\n\tfmt.Println(café.Description())\n\tfmt.Println(\"Costo:\", café.Cost())\n\tfmt.Println(caféConLeche.Description())\n\tfmt.Println(\"Costo:\", caféConLeche.Cost())\n    fmt.Println(caféConLecheYAzúcar.Description())\n    fmt.Println(\"Costo total:\", caféConLecheYAzúcar.Cost())\n\n\t// Extra:\n\tsaludoConContador := NewFunctionCounter(Saludar)\n\tsaludoConContador.Increment()\n\tsaludoConContador.Increment()\n\tfmt.Println(\"Número de veces que se llama a Saludar:\", saludoConContador.GetCount())\n\n}\n\n// Extra:\ntype Counter interface {\n    Increment()\n    GetCount() int\n}\n\ntype FunctionCounter struct {\n    fn    func()\n    count int\n}\n\nfunc NewFunctionCounter(fn func()) *FunctionCounter {\n    return &FunctionCounter{\n        fn: fn,\n    }\n}\n\nfunc (fc *FunctionCounter) Increment() {\n    fc.count++\n    fc.fn()\n}\n\nfunc (fc *FunctionCounter) GetCount() int {\n    return fc.count\n}\n\nfunc Saludar() {\n    fmt.Println(\"¡Hola, mundo!\")\n}"
  },
  {
    "path": "Roadmap/24 - DECORADORES/java/AmadorQuispe.java",
    "content": "\npublic class Main {\n    public static void main(String[] args) {\n        ConcreteComponent component = new ConcreteComponent();\n        ConcreteDecoratorA componentDecorateA = new ConcreteDecoratorA(component);\n        ConcreteDecoratorB componentDecorateB = new ConcreteDecoratorB(componentDecorateA);\n        componentDecorateB.operation();\n        System.out.println(\"EXTRA\");\n        System.out.println(\"========================\");\n        Arithmetic operable = new Arithmetic();\n        //Llamada sin el decorador\n        double result = operable.sumTwoNumbers(5.6,7.8);\n        System.out.println(\"Resultado llamada sin decorar :\" + result);\n        //Llamada con decorador\n        CountCallDecorator operationDecorated = new CountCallDecorator(operable);\n        result = operationDecorated.sumTwoNumbers(2d,4d);\n        System.out.println(\"Resultado llamada con decorador :\" + result);\n        result = operationDecorated.sumTwoNumbers(4.5,6.7);\n        System.out.println(\"Resultado llamada con decorador :\" + result);\n    }\n\n}\n//Classes Generic\ninterface Component{\n    void operation();\n}\nclass ConcreteComponent implements Component{\n    @Override\n    public void operation() {\n        System.out.println(\"Concrete Component Operation\");\n    }\n}\nabstract class Decorator implements Component{\n    protected Component component;\n    public Decorator(Component component){\n        this.component = component;\n    }\n    @Override\n    public void operation() {\n        component.operation();\n    }\n}\nclass ConcreteDecoratorA extends Decorator{\n    public ConcreteDecoratorA(Component component) {\n        super(component);\n    }\n    protected void otherOperation(){\n        System.out.println(\"Concrete Decorator A\");\n    }\n\n    @Override\n    public void operation() {\n        otherOperation();\n        super.operation();\n    }\n}\nclass ConcreteDecoratorB extends Decorator{\n    public ConcreteDecoratorB(Component component) {\n        super(component);\n    }\n    protected void otherOperation(){\n        System.out.println(\"Concrete Decorator B\");\n    }\n\n    @Override\n    public void operation() {\n        otherOperation();\n        super.operation();\n    }\n}\n\n//EXTRA\ninterface Operable{\n    double sumTwoNumbers(Double num1, Double num2);\n}\nclass Arithmetic implements Operable {\n    @Override\n    public double sumTwoNumbers(Double num1, Double num2) {\n        return num1 + num2;\n    }\n}\nabstract class OperableDecorator implements Operable{\n    protected Operable operable;\n    OperableDecorator(Operable operable){\n        this.operable = operable;\n    }\n}\n\nclass CountCallDecorator extends OperableDecorator{\n    private static int countCall = 0;\n    public CountCallDecorator(Operable operable) {\n        super(operable);\n    }\n\n\n    @Override\n    public double sumTwoNumbers(Double num1, Double num2) {\n        countCall++;\n        System.out.println(\"La función se ha llamado : \" + countCall + (countCall>1?\" veces\":\" vez\"));\n        return operable.sumTwoNumbers(num1,num2);\n    }\n}"
  },
  {
    "path": "Roadmap/24 - DECORADORES/java/AnaLauDB.java",
    "content": "public class AnaLauDB {\n\n    // -------------------------------\n    // 1. Interfaz base\n    // -------------------------------\n    interface Bebida {\n        String getDescripcion();\n\n        double getPrecio();\n    }\n\n    // -------------------------------\n    // 2. Clase concreta\n    // -------------------------------\n    static class Cafe implements Bebida {\n        @Override\n        public String getDescripcion() {\n            return \"Café solo\";\n        }\n\n        @Override\n        public double getPrecio() {\n            return 20.0;\n        }\n    }\n\n    // -------------------------------\n    // 3. Clase decoradora base\n    // -------------------------------\n    static abstract class BebidaDecorador implements Bebida {\n        protected Bebida bebida;\n\n        public BebidaDecorador(Bebida bebida) {\n            this.bebida = bebida;\n        }\n    }\n\n    // -------------------------------\n    // 4. Decorador concreto: Leche\n    // -------------------------------\n    static class Leche extends BebidaDecorador {\n        public Leche(Bebida bebida) {\n            super(bebida);\n        }\n\n        @Override\n        public String getDescripcion() {\n            return bebida.getDescripcion() + \", leche\";\n        }\n\n        @Override\n        public double getPrecio() {\n            return bebida.getPrecio() + 5.0;\n        }\n    }\n\n    // -------------------------------\n    // 5. Decorador concreto: Chocolate\n    // -------------------------------\n    static class Chocolate extends BebidaDecorador {\n        public Chocolate(Bebida bebida) {\n            super(bebida);\n        }\n\n        @Override\n        public String getDescripcion() {\n            return bebida.getDescripcion() + \", chocolate\";\n        }\n\n        @Override\n        public double getPrecio() {\n            return bebida.getPrecio() + 7.0;\n        }\n    }\n\n    // -------------------------------\n    // 6. NUEVO: Decorador Contador\n    // -------------------------------\n    static class ContadorLlamadas extends BebidaDecorador {\n        private int contadorGetDescripcion = 0;\n        private int contadorGetPrecio = 0;\n\n        public ContadorLlamadas(Bebida bebida) {\n            super(bebida);\n        }\n\n        @Override\n        public String getDescripcion() {\n            contadorGetDescripcion++;\n            System.out.println(\"  [Contador] getDescripcion() llamado \" + contadorGetDescripcion + \" vez(es)\");\n            return bebida.getDescripcion();\n        }\n\n        @Override\n        public double getPrecio() {\n            contadorGetPrecio++;\n            System.out.println(\"  [Contador] getPrecio() llamado \" + contadorGetPrecio + \" vez(es)\");\n            return bebida.getPrecio();\n        }\n\n        public void mostrarEstadisticas() {\n            System.out.println(\"\\n=== Estadísticas de llamadas ===\");\n            System.out.println(\"getDescripcion(): \" + contadorGetDescripcion + \" llamadas\");\n            System.out.println(\"getPrecio(): \" + contadorGetPrecio + \" llamadas\");\n        }\n    }\n\n    // -------------------------------\n    // 7. Programa principal\n    // -------------------------------\n    public static void main(String[] args) {\n        System.out.println(\"=== Ejemplo básico de Decorador ===\");\n\n        // Café simple\n        Bebida cafe = new Cafe();\n\n        // Agregar leche (decorador)\n        cafe = new Leche(cafe);\n\n        // Agregar chocolate (decorador)\n        cafe = new Chocolate(cafe);\n\n        // Resultado final\n        System.out.println(\"Descripción: \" + cafe.getDescripcion());\n        System.out.println(\"Precio total: $\" + cafe.getPrecio());\n\n        System.out.println(\"\\n=== Ejemplo con Contador de llamadas ===\");\n\n        // Café con contador de llamadas\n        Bebida cafeConContador = new Cafe();\n        cafeConContador = new ContadorLlamadas(cafeConContador);\n        cafeConContador = new Leche(cafeConContador);\n        cafeConContador = new Chocolate(cafeConContador);\n\n        // Hacer varias llamadas para probar el contador\n        System.out.println(\"Primera llamada:\");\n        System.out.println(\"Descripción: \" + cafeConContador.getDescripcion());\n\n        System.out.println(\"\\nSegunda llamada:\");\n        System.out.println(\"Precio: $\" + cafeConContador.getPrecio());\n\n        System.out.println(\"\\nTercera llamada:\");\n        System.out.println(\"Descripción: \" + cafeConContador.getDescripcion());\n\n        System.out.println(\"\\nCuarta llamada:\");\n        System.out.println(\"Precio: $\" + cafeConContador.getPrecio());\n\n        // Mostrar estadísticas finales\n        if (cafeConContador instanceof ContadorLlamadas) {\n            // Necesitamos acceder al decorador contador directamente\n            // Para esto, creamos una referencia específica\n        }\n\n        // Alternativa: crear el contador en una variable separada\n        System.out.println(\"\\n=== Ejemplo con referencia directa al contador ===\");\n        Bebida cafe2 = new Cafe();\n        ContadorLlamadas contador = new ContadorLlamadas(cafe2);\n        Bebida cafeCompleto = new Chocolate(new Leche(contador));\n\n        System.out.println(\"Llamadas de prueba:\");\n        cafeCompleto.getDescripcion();\n        cafeCompleto.getPrecio();\n        cafeCompleto.getDescripcion();\n        cafeCompleto.getPrecio();\n        cafeCompleto.getDescripcion();\n\n        // Mostrar estadísticas\n        contador.mostrarEstadisticas();\n    }\n}\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/java/FranDev200.java",
    "content": "public class FranDev200 {\n\n\n    interface Cafe{\n\n        public String descripcion();\n\n        public double precio();\n\n    }\n\n    // Objeto a decorar\n    public static class CafeSolo implements  Cafe{\n\n\n        @Override\n        public String descripcion() {\n            return \"Cafe solo\";\n        }\n\n        @Override\n        public double precio() {\n            return 1.50;\n        }\n    }\n\n    // Decorador\n    public static abstract class CafeDecorador implements  Cafe{\n\n        protected Cafe cafe;\n\n        public CafeDecorador(Cafe cafe) {\n            this.cafe = cafe;\n        }\n\n        @Override\n        public String descripcion() {\n            return cafe.descripcion();\n        }\n\n        @Override\n        public double precio() {\n            return cafe.precio();\n        }\n    }\n\n    // Decoraciones\n    public static class Leche extends CafeDecorador {\n\n        public Leche(Cafe cafe) {\n            super(cafe);\n        }\n\n        @Override\n        public String descripcion() {\n            return cafe.descripcion() + \", leche\";\n        }\n\n        @Override\n        public double precio() {\n            return cafe.precio() + 0.15;\n        }\n\n    }\n\n    public static class Chocolate extends CafeDecorador {\n\n        public Chocolate(Cafe cafe) {\n            super(cafe);\n        }\n\n        @Override\n        public String descripcion() {\n            return cafe.descripcion() + \", chocolate\";\n        }\n\n        @Override\n        public double precio() {\n            return cafe.precio() + 0.50;\n        }\n\n    }\n\n    public static class Nata extends CafeDecorador {\n\n        public Nata(Cafe cafe) {\n            super(cafe);\n        }\n\n        @Override\n        public String descripcion() {\n            return cafe.descripcion() + \", nata\";\n        }\n\n        @Override\n        public double precio() {\n            return cafe.precio() + 0.25;\n        }\n\n    }\n\n    public static class Azucar extends CafeDecorador {\n\n        public Azucar(Cafe cafe) {\n            super(cafe);\n        }\n\n        @Override\n        public String descripcion() {\n            return cafe.descripcion() + \", azucar\";\n        }\n\n        @Override\n        public double precio() {\n            return cafe.precio() + 0.10;\n        }\n\n    }\n\n    static void main() {\n\n\n        /*\n\n        EJERCICIO:\n         * Explora el concepto de \"decorador\" y muestra cómo crearlo\n         * con un ejemplo genérico.\n\n         */\n        Cafe cafe = new CafeSolo();\n\n        System.out.println(\"Tabla de precios de Cafés\");\n        System.out.println(\"=========================\");\n        System.out.println(cafe.descripcion() + \" --> \" + cafe.precio());\n        cafe = new Leche(cafe);\n        System.out.println(cafe.descripcion() + \" --> \" + cafe.precio());\n        cafe = new Chocolate(cafe);\n        System.out.println(cafe.descripcion() + \" --> \" + cafe.precio());\n        cafe = new Nata(cafe);\n        System.out.println(cafe.descripcion() + \" --> \" + cafe.precio());\n        cafe = new Azucar(cafe);\n        System.out.println(cafe.descripcion() + \" --> \" + cafe.precio());\n\n\n        /*\n\n         * DIFICULTAD EXTRA (opcional):\n         * Crea un decorador que sea capaz de contabilizar cuántas veces\n         * se ha llamado a una función y aplícalo a una función de tu elección.\n\n         */\n\n        System.out.println(\"\\nEJERCICIO EXTRA\");\n        System.out.println(\"===============\\n\");\n\n        Saludo saludo = new Mensaje();\n        System.out.println(saludo.saludar()); // Saludo normal sin numero\n\n\n        saludo = new SaludoContabilizado(saludo);\n\n        for(int i = 0; i < 20; i++){\n            System.out.println(saludo.saludar());\n        }\n\n\n    }\n\n    interface Saludo{\n        String saludar();\n    }\n\n    static class Mensaje implements Saludo{\n\n        @Override\n        public String saludar() {\n            return \"Saludo\";\n        }\n\n    }\n\n    static abstract class Implementacion implements Saludo{\n\n        Saludo saludo;\n\n        public Implementacion(Saludo saludo) {\n            this.saludo = saludo;\n        }\n\n        @Override\n        public String saludar() {\n\n            return saludo.saludar();\n        }\n    }\n\n    static class SaludoContabilizado extends Implementacion{\n\n\n        private int nroSaludo = 0;\n        public SaludoContabilizado(Saludo saludo) {\n            super(saludo);\n        }\n\n        @Override\n        public String saludar() {\n\n            nroSaludo++;\n            return saludo.saludar() + \" \" +  nroSaludo;\n        }\n    }\n\n\n}\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/java/JesusWay69.java",
    "content": "package ejercicio24;\n\n/*\n* EJERCICIO:\n* Explora el concepto de \"decorador\" y muestra cómo crearlo\n* con un ejemplo genérico.\n */\npublic class JesusWay69 {\n\n    public static void main(String[] args) {\n        Developer frontend = new FrontEndDeveloper();\n        frontend.skills();\n        System.out.println(\"\\n----------------------------------------------------------------------\");\n\n        Developer backend = new BackEndDeveloper(new FrontEndDeveloper());\n        backend.skills();\n        System.out.println(\"\\n----------------------------------------------------------------------\");\n        //Podemos instaciar metiendo todas las clases al constructor tal que así:\n        Developer fullstack1 = new FullStackDeveloper(new BackEndDeveloper(new FrontEndDeveloper())); \n        \n        //O podemos instanciar la última pasándole sólo la primera (la que implementaba el decorador),\n        //al guardar con super el método anterior nos ejecutará todos los métodos sobreescritos de todas las clases que haya entre ellas\n        Developer fullstack = new FullStackDeveloper(new FrontEndDeveloper());\n        fullstack.skills();\n        System.out.println(\"                      |--------------|                      \");\n        fullstack1.skills();\n        System.out.println(\"\\n----------------------------------------------------------------------\");\n\n        Sum sum = new Counter(new MainSum());\n        System.out.println(sum.sumtwo(5, 8));\n        System.out.println(sum.sumtwo(7, 9));\n        System.out.println(sum.sumtwo(3, 1));\n        System.out.println(sum.sumtwo(6, 2));\n        System.out.println(sum.sumtwo(0, 3));\n\n    }\n\n}\n\ninterface Developer {//Declaramos una interfaz\n\n    void skills();// con el método principal que luego sobreescribiremos\n}\n\nabstract class DevDecorator implements Developer {//Creamos una clase abstracta para implementar la interfaz\n\n    private final Developer developer;//Convertimos en constante y encapsulamos la interfaz para que no pueda tener subclases\n\n    public DevDecorator(Developer developer) {//Creamos el método decorador\n        this.developer = developer;\n    }\n\n    @Override\n    public void skills() {//Sobreescribimos el método principal\n        this.developer.skills();\n    }\n}\n\nclass FrontEndDeveloper implements Developer {//Creamos una clase normal para implementar el decorador de la clase abstracta\n\n    @Override\n    public void skills() {//Sobreescribimos el método principal para que empiece a añadir texto\n        System.out.print(\" El programador frontend tiene conocimientos en: \");\n        this.addHTML();\n        this.addCSS();\n    }\n\n    private void addHTML() {//Creamos más métodos para añadir lenguajes dentro de esta clase frontend\n        System.out.print(\" HTML \");\n    }\n\n    private void addCSS() {\n        System.out.print(\"y CSS\");\n    }\n}\n\nclass BackEndDeveloper extends DevDecorator {//Creamos otra clase que hereda de la anterior\n\n    public BackEndDeveloper(Developer developer) {\n        super(developer);//Creamos un método de clase propia cuyo argumento de clase Developer pasamos al método de lenguaje super\n    }\n\n    @Override\n    public void skills() {//Sobreescribimos de nuevo el método skills para añadir otro tipo de programador al texto\n        super.skills();//Con super nos aseguramos que el texto del método antes de la sobreescritura se imprima también\n        System.out.print(\"\\n El programador backend conoce lenguajes como: \");\n        this.addJava();\n        this.addPython();\n        this.addPhp();\n        this.addTypescript();\n        this.addJavascript();\n    }\n\n    private void addTypescript() {\n        System.out.print(\", Typescript\");\n    }\n\n    private void addJavascript() {\n        System.out.print(\" o Javascript \");\n    }\n\n    private void addJava() {\n        System.out.print(\"Java\");\n\n    }\n\n    private void addPhp() {\n        System.out.print(\", PhP\");\n    }\n\n    private void addPython() {\n        System.out.print(\", Python\");\n    }\n}\n\nclass FullStackDeveloper extends DevDecorator {//Seguimos añadiendo clases heredando del decorador\n\n    public FullStackDeveloper(Developer developer) {\n        super(developer);//Si queremos que se ejecuten los métodos anteriores de impresión de texto debemos seguir\n        // añadiendo el método de clase propia y añadirle a super nuestro argumento Developer\n    }\n\n    @Override\n    public void skills() {//Así podemos seguir añadiendo tantas clases como queramos\n        super.skills();\n        System.out.println(\"\\n El programador senior añade a esos conocimientos los de frameworks como: \");\n        this.addAngular();\n        this.addReact();\n        this.addTailwind();\n        this.addSpring();\n        this.addDjango();\n    }\n\n    private void addAngular() {\n        System.out.print(\" Angular, \");\n    }\n\n    private void addReact() {\n        System.out.print(\"React, \");\n    }\n\n    private void addTailwind() {\n        System.out.print(\"Tailwind CSS, \");\n    }\n\n    private void addSpring() {\n        System.out.print(\"Spring/SpringBoot, \");\n    }\n\n    private void addDjango() {\n        System.out.println(\"o Django\");\n    }\n\n}\n\n/*\n* DIFICULTAD EXTRA (opcional):\n* Crea un decorador que sea capaz de contabilizar cuántas veces\n* se ha llamado a una función y aplícalo a una función de tu elección.\n */\n\ninterface Sum {\n\n    String sumtwo(int a, int b);\n}\n\nabstract class SumDecorator implements Sum {\n\n    private final Sum sum;\n\n    public SumDecorator(Sum sum) {\n        this.sum = sum;\n    }\n\n    @Override\n    public String sumtwo(int a, int b) {\n\n        return this.sum.sumtwo(a, b);\n\n    }\n}\n\nclass MainSum implements Sum {\n\n    int result;\n\n    @Override\n    public String sumtwo(int a, int b) {\n        result = a + b;\n        return Integer.toString(result);\n\n    }\n}\n\nclass Counter extends SumDecorator {\n\n    private static int calls = 0;\n\n    public Counter(Sum sum) {\n        super(sum);\n    }\n\n    @Override\n    public String sumtwo(int a, int b) {\n        super.sumtwo(a, b);\n        ++calls;\n        return \"Resultado de \" + a + \" + \" + b + \" = \" + super.sumtwo(a, b) + \" , llamada Nº: \" + Integer.toString(calls);\n        \n\n    }\n}\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/java/JimsimroDev.java",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de \"decorador\" y muestra cómo crearlo\n * con un ejemplo genérico.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un decorador que sea capaz de contabilizar cuántas veces\n * se ha llamado a una función y aplícalo a una función de tu elección.\n */\npublic class JimsimroDev {\n  public static interface EncenderAutomovil {\n    void encender(String mensaje);\n  }\n\n  // Clase concreta que implementa la interfaz\n  public static class Automovil implements EncenderAutomovil {\n    @Override\n    public void encender(String mensaje) {\n      System.out.println(\"El automóvil se ha encendido: \" + mensaje);\n    }\n\n  }\n\n  public static class DecoradorAutomovil implements EncenderAutomovil {\n    private EncenderAutomovil wrappee;\n    private String nombreMetodo;\n    private int contadorLlamadas = 0;\n\n    private DecoradorAutomovil(EncenderAutomovil wrappee, String nombreMetodo) {\n      this.wrappee = wrappee;\n      this.nombreMetodo = nombreMetodo;\n    }\n\n    @Override\n    public void encender(String mensaje) {\n      contadorLlamadas++;\n      System.out.printf(\"función %s ha sido llamda %d veces \\n\", nombreMetodo, getContadorLlamadas());\n      wrappee.encender(mensaje);\n    }\n\n    public int getContadorLlamadas() {\n      return contadorLlamadas;\n    }\n  }\n\n  public static void main(String[] args) {\n    var automóvilPrueba = new Automovil();\n    var testlaModelY = new DecoradorAutomovil(automóvilPrueba, \"testlaModelY\");\n    var testlaModelS = new DecoradorAutomovil(automóvilPrueba, \"testlaModelS\");\n\n    testlaModelY.encender(\"Arrancando el motor V8\");\n    testlaModelY.encender(\"Arrancando el motor V8\");\n    testlaModelY.encender(\"Arrancando el motor V8\");\n\n    testlaModelS.encender(\"Arrancando el motor V6\");\n    testlaModelS.encender(\"Arrancando el motor V6\");\n    testlaModelS.encender(\"Arrancando el motor V6\");\n\n    testlaModelY.encender(\"Arrancando el motor V8\");\n  }\n}\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/java/Josegs95.java",
    "content": "public class Josegs95 {\n    public static void main(String[] args) {\n        //Ejercicio\n        //En java es un poco engorroso los decoradores porque necesitas muchas clases\n        //e interfaces para implementar el patrón de diseño\n        Interface instance1 = new DefaultImplClass();\n        System.out.println(instance1.getString());\n\n        Interface instance2 = new Decorator(new DefaultImplClass());\n        System.out.println(instance2.getString());\n\n        //Reto\n        retoFinal();\n    }\n\n    public static void retoFinal(){\n        //Voy a reutilizar la interfaz y las clases usadas en el ejercicio para evitar\n        //crear demasiado código \"dummy\"\n        Interface instance = new ChallengeDecorator(new DefaultImplClass());\n\n        System.out.println(\"Veces que se ha llamado a 'getString()': \" + ((ChallengeDecorator)instance).getCounter());\n        instance.getString();\n        instance.getString();\n        instance.getString();\n        System.out.println(\"Veces que se ha llamado a 'getString()': \" + ((ChallengeDecorator)instance).getCounter());\n    }\n\n    public interface Interface{\n        String getString();\n    }\n\n    public static class DefaultImplClass implements Interface{\n        @Override\n        public String getString() {\n            return \"Cadena por defecto\";\n        }\n    }\n\n    public static abstract class BaseDecorator implements Interface{\n        private Interface interfaceInstance;\n\n        public BaseDecorator(Interface interfaceInstance) {\n            this.interfaceInstance = interfaceInstance;\n        }\n\n        @Override\n        public String getString() {\n            return interfaceInstance.getString();\n        }\n    }\n\n    public static class Decorator extends BaseDecorator{\n        public Decorator(Interface interfaceInstance) {\n            super(interfaceInstance);\n        }\n\n        @Override\n        public String getString() {\n            return super.getString() + \", mas la cadena del decorador\";\n        }\n    }\n\n    public static class ChallengeDecorator extends BaseDecorator{\n\n        private int counter;\n\n        public ChallengeDecorator(Interface interfaceInstance) {\n            super(interfaceInstance);\n            counter = 0;\n        }\n\n        @Override\n        public String getString() {\n            counter++;\n            return super.getString();\n        }\n\n        public int getCounter() {\n            return counter;\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/java/asjordi.java",
    "content": "/**\n * En Java se puede implementar el concepto de decorador utilizando el patrón de diseño Decorator.\n * Decorator es un patrón de diseño estructural que permite añadir funcionalidades a objetos\n * colocando estos objetos dentro de objetos encapsuladores especiales que contienen estas funcionalidades.\n * Más información en: https://refactoring.guru/es/design-patterns/decorator\n */\npublic class Main {\n\n    public static void main(String[] args) {\n\n        Car sportsCar = new SportsCar(new BasicCar());\n        sportsCar.assemble();\n\n        BaseFunction baseFunction = new BaseFunction();\n        CountingFunctionDecorator decorator = new CountingFunctionDecorator(baseFunction);\n        decorator.call();\n        System.out.println(\"Function called \" + decorator.getCount() + \" times\");\n    }\n\n    /**\n     * EJERCICIO:\n     * Explora el concepto de \"decorador\" y muestra cómo crearlo\n     * con un ejemplo genérico.\n     */\n\n    // Interfaz que define el comportamiento de un coche\n    public interface Car {\n        void assemble();\n    }\n\n    // Implementación básica de un coche\n    public static class BasicCar implements Car {\n        @Override\n        public void assemble() {\n            System.out.println(\"Basic Car!\");\n        }\n    }\n\n    // Decorador con referencia a un coche\n    public abstract static class CarDecorator implements Car {\n        protected Car car;\n\n        protected CarDecorator(Car c){\n            this.car=c;\n        }\n\n        public void assemble(){\n            this.car.assemble();\n        }\n    }\n\n    // Decorador que añade funcionalidades de un coche deportivo\n    public static class SportsCar extends CarDecorator {\n        public SportsCar(Car c) {\n            super(c);\n        }\n\n        public void assemble(){\n            super.assemble();\n            System.out.println(\"Adding features of Sports Car.\");\n        }\n    }\n\n    /**\n     * DIFICULTAD EXTRA (opcional):\n     * Crea un decorador que sea capaz de contabilizar cuántas veces\n     * se ha llamado a una función y aplícalo a una función de tu elección.\n     */\n\n    // Interfaz para la función\n    public interface Function {\n        void call();\n    }\n\n    // Implementación base de la función\n    public static class BaseFunction implements Function {\n        @Override\n        public void call() {\n            System.out.println(\"Base function called\");\n        }\n    }\n\n    // Decorador que agrega la funcionalidad de contabilizar las llamadas\n    public static class CountingFunctionDecorator implements Function {\n        private Function baseFunction;\n        private Integer count = 0;\n\n        public CountingFunctionDecorator(Function baseFunction) {\n            this.baseFunction = baseFunction;\n        }\n\n        @Override\n        public void call() {\n            count++;\n            baseFunction.call();\n        }\n\n        public Integer getCount() {\n            return this.count;\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/java/danhingar.java",
    "content": "public class danhingar {\n    public static void main(String[] args) {\n        Function function1 = new FunctionNameDecorator(new ExampleFunction(\"function1\"));\n        function1.execute();\n\n        Function function2 = new FunctionNameDecorator(new ExampleFunction(\"function2\"));\n        function2.execute();\n\n        Function function3 = new FunctionNameDecorator(new ExampleFunction(\"function3\"));\n        function3.execute();\n\n        Function function4 = new FunctionCounterDecorator(new ExampleFunction(\"function4\"));\n        function4.execute();\n        function4.execute();\n\n        Function function5 = new FunctionCounterDecorator(new ExampleFunction(\"function5\"));\n        function5.execute();\n\n        function4.execute();\n        function4.execute();\n        function5.execute();\n\n        //EJEMPLO EXTRA\n        BaseDecorator notifier = new SMSDecorator(new FacebookDecorator(new SlackDecorator(new basicNotifier())));\n\n        notifier.send(\"HELLO!!\");\n\n        \n        Notifier basicNotifier = new basicNotifier();\n\n        Notifier smsNotifier = new SMSDecorator(basicNotifier);\n        Notifier facebookNotifier = new FacebookDecorator(smsNotifier);\n        Notifier slackNotifier = new SlackDecorator(facebookNotifier);\n\n        slackNotifier.send(\"GOODBYE!!\");\n    }\n\n}\n\ninterface Function {\n    void execute();\n}\n\nclass ExampleFunction implements Function {\n    private String nameFunction;\n\n    public ExampleFunction(String nameFunction) {\n        this.nameFunction = nameFunction;\n    }\n\n    @Override\n    public void execute() {\n        System.out.println(\"Ejecutando la función \" + this.nameFunction);\n    }\n\n    public String getNameFunction() {\n        return nameFunction;\n    }\n\n}\n\nclass FunctionNameDecorator implements Function {\n    private final ExampleFunction function;\n\n    public FunctionNameDecorator(ExampleFunction function) {\n        this.function = function;\n    }\n\n    @Override\n    public void execute() {\n\n        System.out.println(\"La función '\" + function.getNameFunction() + \"' ha sido llamada.\");\n\n        function.execute();\n\n    }\n}\n\nclass FunctionCounterDecorator implements Function {\n    private final ExampleFunction function;\n    private int callCounter = 0;\n\n    public FunctionCounterDecorator(ExampleFunction function) {\n        this.function = function;\n    }\n\n    @Override\n    public void execute() {\n        callCounter++;\n\n        System.out.println(\"La función '\" + function.getNameFunction() + \"' se ha llamado \" + callCounter);\n\n        function.execute();\n\n    }\n}\n\ninterface Notifier {\n    void send(String message);\n}\n\nclass basicNotifier implements Notifier {\n\n    @Override\n    public void send(String message) {\n        System.out.println(\"Enviando notificacion básica por correo:  \" + message);\n    }\n}\n\nabstract class BaseDecorator implements Notifier {\n    protected Notifier wrapper;\n\n    public BaseDecorator(Notifier notifier) {\n        this.wrapper = notifier;\n    }\n\n    @Override\n    public void send(String message) {\n        wrapper.send(message);\n    }\n}\n\nclass SMSDecorator extends BaseDecorator {\n\n    public SMSDecorator(Notifier wrappee) {\n        super(wrappee);\n    }\n\n    @Override\n    public void send(String message) {\n        super.send(message);\n        sendSMS(message);\n    }\n\n    private void sendSMS(String message) {\n        System.out.println(\"Enviando notificacion mediante SMS: \" + message);\n    }\n\n}\n\nclass FacebookDecorator extends BaseDecorator {\n\n    public FacebookDecorator(Notifier wrappee) {\n        super(wrappee);\n    }\n\n    @Override\n    public void send(String message) {\n        super.send(message);\n        sendFacebook(message);\n    }\n\n    private void sendFacebook(String message) {\n        System.out.println(\"Enviando notificación mediante Facebook: \" + message);\n    }\n\n}\n\nclass SlackDecorator extends BaseDecorator {\n\n    public SlackDecorator(Notifier wrappee) {\n        super(wrappee);\n    }\n\n    @Override\n    public void send(String message) {\n        super.send(message);\n        sendSlack(message);\n    }\n\n    private void sendSlack(String message) {\n        System.out.println(\"Enviando notificación mediante Slack: \" + message);\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/java/eulogioep.java",
    "content": "/*\n * TEORÍA DE DECORADORES (ANOTACIONES) EN JAVA\n * \n * En Java, los decoradores se llaman \"anotaciones\" y se definen usando @interface.\n * Las anotaciones permiten añadir metadatos a:\n * - Clases\n * - Métodos\n * - Campos\n * - Parámetros\n * \n * Características principales:\n * - Se definen con @interface\n * - Pueden tener elementos con valores por defecto\n * - Se procesan en tiempo de compilación o ejecución\n * - Se pueden consultar mediante Reflection\n */\n\nimport java.lang.annotation.*;\nimport java.lang.reflect.*;\n\n// Definición del decorador para clases\n@Retention(RetentionPolicy.RUNTIME)\n@Target(ElementType.TYPE)\n@interface LogClass {\n    String value() default \"\"; // Mensaje personalizado\n}\n\n// Definición del decorador para métodos\n@Retention(RetentionPolicy.RUNTIME)\n@Target(ElementType.METHOD)\n@interface LogMethod {\n    String value() default \"\"; // Mensaje personalizado\n}\n\n// Definición del decorador contador para el ejercicio extra\n@Retention(RetentionPolicy.RUNTIME)\n@Target(ElementType.METHOD)\n@interface ContadorLlamadas {\n}\n\npublic class eulogioep {\n    // Clase principal que contiene el método main\n    public static void main(String[] args) {\n        try {\n            System.out.println(\"=== Pruebas de los decoradores ===\");\n\n            // Prueba del decorador de clase\n            Ejemplo ejemplo = new Ejemplo();\n            procesarDecoradoresClase(ejemplo.getClass());\n\n            // Prueba del decorador de método\n            ejemplo.saludar(\"Java\");\n\n            // Prueba del decorador contador\n            Calculadora calc = new Calculadora();\n            System.out.println(\"Resultado suma: \" + calc.sumar(5, 3));        // Primera llamada\n            System.out.println(\"Resultado suma: \" + calc.sumar(2, 4));        // Segunda llamada\n            System.out.println(\"Resultado multiplicación: \" + calc.multiplicar(3, 4));  // Primera llamada\n            System.out.println(\"Resultado suma: \" + calc.sumar(1, 1));        // Tercera llamada\n\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n    }\n\n    // Clase de ejemplo con decoradores\n    @LogClass(\"Esta es una clase de ejemplo\")\n    static class Ejemplo {\n        @LogMethod(\"Método de saludo\")\n        public String saludar(String nombre) {\n            return \"¡Hola \" + nombre + \"!\";\n        }\n    }\n\n    // Clase Calculadora con el decorador contador\n    static class Calculadora {\n        private static java.util.Map<String, Integer> contadores = new java.util.HashMap<>();\n\n        @ContadorLlamadas\n        public int sumar(int a, int b) {\n            contarLlamada(\"sumar\");\n            return a + b;\n        }\n\n        @ContadorLlamadas\n        public int multiplicar(int a, int b) {\n            contarLlamada(\"multiplicar\");\n            return a * b;\n        }\n\n        private void contarLlamada(String metodo) {\n            int contador = contadores.getOrDefault(metodo, 0) + 1;\n            contadores.put(metodo, contador);\n            System.out.println(\"El método \" + metodo + \" ha sido llamado \" + contador + \" veces\");\n        }\n    }\n\n    // Método para procesar decoradores de clase\n    private static void procesarDecoradoresClase(Class<?> clase) {\n        if (clase.isAnnotationPresent(LogClass.class)) {\n            LogClass anotacion = clase.getAnnotation(LogClass.class);\n            System.out.println(\"Clase creada: \" + clase.getSimpleName() + \n                             \" - Mensaje: \" + anotacion.value());\n        }\n    }\n\n    // Método para procesar decoradores de método\n    private static void procesarDecoradoresMetodo(Method metodo) {\n        if (metodo.isAnnotationPresent(LogMethod.class)) {\n            LogMethod anotacion = metodo.getAnnotation(LogMethod.class);\n            System.out.println(\"Método llamado: \" + metodo.getName() + \n                             \" - Mensaje: \" + anotacion.value());\n        }\n    }\n\n    // Procesador de aspectos (simulado con Reflection)\n    static {\n        // Interceptamos los métodos con decoradores usando Reflection\n        try {\n            Method[] metodos = Ejemplo.class.getDeclaredMethods();\n            for (Method metodo : metodos) {\n                if (metodo.isAnnotationPresent(LogMethod.class)) {\n                    // Aquí normalmente usaríamos un framework como AspectJ\n                    // Esta es una simulación simplificada\n                    procesarDecoradoresMetodo(metodo);\n                }\n            }\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/24 - DECORADORES/java/martinbohorquez.java",
    "content": "/*\n * #24 PATRONES DE DISEÑO: DECORADORES\n *\n * @author martinbohorquez\n */\npublic class martinbohorquez {\n    public static void main(String[] args) {\n        Component component = new ConcreteComponent();\n        Component smsConcreteDecorated = new SmsDecorator(component);\n        Component facebookConcreteDecorated = new FacebookDecorator(component);\n        component.notification();\n        smsConcreteDecorated.notification();\n        facebookConcreteDecorated.notification();\n\n        /*\n         * DIFICULTAD EXTRA\n         */\n        ComponentExtra componente = new ConcreteComponentExtra();\n        CountDecorator contadorDecorador = new CountDecorator(componente);\n\n        contadorDecorador.operation();\n        contadorDecorador.operation();\n        contadorDecorador.operation();\n\n        System.out.printf(\"Total de invocaciones: %s%n\", contadorDecorador.getContador());\n    }\n\n    //Interfaz base\n    interface Component {\n        void notification();\n    }\n\n    //Componente concreto\n    static class ConcreteComponent implements Component {\n        @Override\n        public void notification() {\n            System.out.println(\"Notificación por defecto!\");\n        }\n    }\n\n    //Decorador abstracto\n    abstract static class Decorator implements Component {\n        private final Component component;\n\n        private Decorator(Component component) {\n            this.component = component;\n        }\n\n        public void notification() {\n            this.component.notification();\n            System.out.printf(\"Notificación por %s!%n\", this.getClass().getSimpleName());\n        }\n    }\n\n    //Decorador concreto que añade funcionalidad\n    static class SmsDecorator extends Decorator {\n        private SmsDecorator(Component component) {\n            super(component);\n        }\n\n        @Override\n        public void notification() {\n            super.notification();\n            addFunctionality();\n        }\n\n        private void addFunctionality() {\n            System.out.printf(\"Funcionalidad adicional de %s!%n\", this.getClass().getSimpleName());\n        }\n    }\n\n    //Decorador concreto que añade funcionalidad\n    static class FacebookDecorator extends Decorator {\n        private FacebookDecorator(Component component) {\n            super(component);\n        }\n\n        @Override\n        public void notification() {\n            super.notification();\n            addFunctionality();\n        }\n\n        private void addFunctionality() {\n            System.out.printf(\"Funcionalidad adicional de %s!%n\", this.getClass().getSimpleName());\n        }\n    }\n\n    // DIFICULTAD EXTRA\n    interface ComponentExtra {\n        void operation();\n    }\n\n    //Componente concreto\n    static class ConcreteComponentExtra implements ComponentExtra {\n        @Override\n        public void operation() {\n            System.out.println(\"Ejecutando operación base!\");\n        }\n    }\n\n    //Decorador abstracto\n    abstract static class DecoratorExtra implements ComponentExtra {\n        private final ComponentExtra component;\n\n        private DecoratorExtra(ComponentExtra component) {\n            this.component = component;\n        }\n\n        public void operation() {\n            this.component.operation();\n        }\n    }\n\n    // Decorador concreto que cuenta las veces que se llama a la operación\n    static class CountDecorator extends DecoratorExtra {\n        private int contador = 0;\n\n        private CountDecorator(ComponentExtra component) {\n            super(component);\n        }\n\n        @Override\n        public void operation() {\n            System.out.println(\"La operación se ha llamado \" + ++contador + \" vez/veces.\");\n            super.operation();\n        }\n\n        private int getContador() {\n            return contador;\n        }\n    }\n}\n\n\n\n\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/java/simonguzman.java",
    "content": "\nimport java.util.HashMap;\nimport java.util.Map;\n\n\n\npublic class simonguzman {\n    public  static void main(String[] args) {\n        genericExample();\n        example();\n        adittionalExercise();\n    }\n\n    /***************************** Ejercicio adicional*****************************/\n\n    static void adittionalExercise(){\n        ComponentExtra componente = new ConcreteComponentExtra();\n        CountDecorator contadorDecorador = new CountDecorator(componente);\n\n        contadorDecorador.operation();  \n        contadorDecorador.operation();  \n        contadorDecorador.operation();  \n\n        System.out.println(\"Total de invocaciones: \" + contadorDecorador.getContador());\n    }\n    static interface ComponentExtra{\n        void operation();\n    }\n\n    //Componente concreto\n    static class ConcreteComponentExtra implements ComponentExtra{\n        @Override\n        public void operation() {\n            System.out.println(\"Ejecutando operacion base...\");\n        }\n    }\n\n    //Decorador abstracto\n    static abstract class DecoratorExtra implements ComponentExtra{\n        protected ComponentExtra component;\n\n        public DecoratorExtra(ComponentExtra component){\n            this.component = component;\n        }\n\n        public void operation() {\n            this.component.operation();\n        }\n    }\n    // Decorador concreto que cuenta las veces que se llama a la operación\n    static class CountDecorator extends DecoratorExtra {\n        private int contador = 0;\n    \n        public CountDecorator(ComponentExtra component) {\n            super(component);\n        }\n    \n        @Override\n        public void operation() {\n            contador++;\n            System.out.println(\"La operación se ha llamado \" + contador + \" veces.\");\n            super.operation();\n        }\n    \n        public int getContador() {\n            return contador;\n        }\n    }\n\n    /***************************** Ejemplo de implemetacion mas complejo *****************************/\n    /*Se realizo un ejemplo adicional para mostrar mejor y poner en practica la sintaxis\n     * del patron decorador, en el cual se busco simular lo que seria un login de una cuenta\n     * de un usuario, con sus respectivas validaciones\n     */\n    static void example(){\n\n        //Simulacion de inicio de sesion.\n        UserService userService = new LoginAttemptsDecorator(new BasicUserService(), 3);\n        userService.login(\"user1\", \"password\");\n        userService.login(\"user1\", \"wrongpassword\");\n        userService.login(\"user1\", \"wrongpassword\");\n        userService.login(\"user1\", \"wrongpassword\");\n        userService.login(\"user1\", \"wrongpassword\");\n    }\n    //Interfaz base del servicio de usuario\n    static interface UserService{\n        boolean login(String username, String password);\n    }\n\n    //implementacion basica del servicio de usuario\n    static class BasicUserService implements UserService{\n        private Map<String, String> userDatabase = new HashMap<>();\n\n        public BasicUserService(){\n            //Simulacion de una base de datos de usuarios\n            userDatabase.put(\"user1\", \"password\");\n            userDatabase.put(\"user2\", \"12345\");\n        }\n\n        @Override\n        public boolean login(String username, String password){\n            String storedPassword = userDatabase.get(username);\n            if(storedPassword != null && storedPassword.equals(password)){\n                System.out.println(\"Inicio de sesion exitoso para \"+username);\n                return true;\n            }else{\n                System.out.println(\"Credenciales incorrectas para \"+username);\n                return false;\n            }\n        }\n    }\n\n    //Decorador para contar los intentos de inicio de sesion\n    static class LoginAttemptsDecorator implements UserService{\n        private UserService userService;\n        private Map<String, Integer> loginAttempts;\n        private int maxAttempts;\n\n        public LoginAttemptsDecorator(UserService userService, int maxAttempts) {\n            this.userService = userService;\n            this.maxAttempts = maxAttempts;\n            this.loginAttempts = new HashMap<>();\n        }\n\n        @Override\n        public boolean login(String username, String password) {\n            if(loginAttempts.getOrDefault(username, 0) >= maxAttempts){\n                System.out.println(\"Cuenta bloqueada para \"+username+\" por exceder los intentos permitidos\");\n                return false;\n            }\n\n            boolean success = userService.login(username, password);\n            if(!success){\n                loginAttempts.put(username, loginAttempts.getOrDefault(username, 0)+1);\n                System.out.println(\"Intentos fallidos para \"+username+\":\" + loginAttempts.get(username));\n            }else{\n                loginAttempts.put(username, 0);\n            }\n            return success;\n        }\n        \n    }\n\n    /***************************** Ejemplo generico *****************************/\n    static void genericExample(){\n        Component component = new ConcreteComponent();\n        Component decorated = new ConcreteDecorator(component);\n        decorated.operation();\n    }\n    \n    //Interfaz base\n    static interface Component{\n        void operation();\n    }\n\n    //Componente concreto\n    static class ConcreteComponent implements Component{\n        @Override\n        public void operation() {\n            System.out.println(\"Ejecutando operacion base...\");\n        }\n    }\n\n    //Decorador abstracto\n    static abstract class Decorator implements Component{\n        protected Component component;\n\n        public Decorator(Component component){\n            this.component = component;\n        }\n\n        public void operation() {\n            this.component.operation();\n        }\n    }\n\n    //Decorador concreto que añade funcionalidad\n    static class ConcreteDecorator extends Decorator{\n        public ConcreteDecorator(Component component){\n            super(component);\n        }\n\n        @Override\n        public void operation() {\n            super.operation();\n            addFunctionality();\n        }\n\n        private void addFunctionality(){\n            System.out.println(\"Funcionalidad adicional del decorador.\");\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/java/vandresca.java",
    "content": "public class vandresca {\n    public static void main(String[] args) {\n\n        //EJERCICIO\n        Insurance myInsurance = new FloodFareDecorator(new FireFareDecorator(new ThirdPartyInsurance()));\n        System.out.println(\"COST -> \"+ myInsurance.getPrice());\n        System.out.println();\n        System.out.println(\"==============================\");\n        System.out.println();\n\n        //EXTRA\n        Operable sum = new Sum();\n        CountDecorator counter = new CountDecorator(sum);\n        System.out.println(\"\\tSUM--> \"+sum.operation());\n        System.out.println(\"\\tSUM--> \"+sum.operation());\n        System.out.println(\"COUNT_DECORATOR-> \"+counter.operation());\n        System.out.println(\"\\tSUM--> \"+sum.operation());\n        System.out.println(\"COUNT_DECORATOR-> \"+counter.operation());\n        System.out.println(\"\\tSUM--> \"+sum.operation());\n        System.out.println(\"COUNT_DECORATOR-> \"+counter.operation());\n        System.out.println(\"\\tSUM--> \"+sum.operation());\n        System.out.println(\"COUNT_DECORATOR-> \"+counter.operation());\n        System.out.println(\"COUNT_DECORATOR-> \"+counter.operation());\n        System.out.println(\"\\tSUM--> \"+sum.operation());\n    }\n}\n\n\n////////////////////\n//                //\n//   EJERCICIO    //\n//                //\n////////////////////\n\ninterface Insurance{\n    double getPrice();\n}\n\nclass ThirdPartyInsurance implements Insurance{\n    double price;\n\n    @Override\n    public double getPrice(){\n        return 100.0;\n    }\n}\n\nabstract class AbstractInsuranceDecorator implements Insurance{\n    protected Insurance component;\n\n    public AbstractInsuranceDecorator(Insurance component){\n        this.component = component;\n    }\n\n    @Override\n    public double getPrice(){\n        return this.component.getPrice();\n    }\n}\n\nclass FireFareDecorator extends AbstractInsuranceDecorator{\n    public FireFareDecorator(Insurance component){\n        super(component);\n    }\n\n    @Override\n    public double getPrice() {\n        return component.getPrice() + 50.0;\n    }\n}\n\nclass FloodFareDecorator extends AbstractInsuranceDecorator{\n    public FloodFareDecorator(Insurance component){\n        super(component);\n    }\n\n    @Override\n    public double getPrice() {\n        return component.getPrice() + 30.0;\n    }\n}\n\n/////////////////////////\n//                     //\n//       EXTRA         //\n//                     //\n/////////////////////////\n\n\ninterface Operable{\n    int operation();\n}\n\nclass Sum implements Operable{\n    private static int c;\n    int a=4;\n\n    @Override\n    public int operation() {\n        c = c + a;\n        return c;\n    }\n}\n\nabstract class AbstractOperationDecorator implements Operable{\n    Operable component;\n    public AbstractOperationDecorator(Operable component){\n        this.component = component;\n    }\n}\n\nclass CountDecorator extends AbstractOperationDecorator{\n\n    private static int countNumExecOp = 0;\n\n    public CountDecorator(Operable component){\n        super(component);\n    }\n\n    @Override\n    public int operation() {\n        component.operation();\n        countNumExecOp++;\n        return countNumExecOp;\n    }\n}\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/javascript/AChapeton.js",
    "content": "class BasicMath {\n  sumar(a, b){\n    return a + b\n  }\n\n  restar(a, b){\n    return a - b\n  }\n\n  multiplicar(a, b){\n    return a * b\n  }\n\n  dividir(a, b){\n    if (b === 0) {\n      throw new Error('Division by zero is not allowed')\n    }\n    return a / b\n  }\n}\n\nconst mathDecorator = (fun) => {\n  return function(...args){\n    console.log(`Llamando a la funcion ${fun.name} con argumentos`, args)\n    return fun.apply(this, args)\n  }\n}\n\nBasicMath.prototype.sumar = mathDecorator(BasicMath.prototype.sumar)\nBasicMath.prototype.restar = mathDecorator(BasicMath.prototype.restar)\nBasicMath.prototype.multiplicar = mathDecorator(BasicMath.prototype.multiplicar)\nBasicMath.prototype.dividir = mathDecorator(BasicMath.prototype.dividir)\n\nconst test = new BasicMath()\n\nconsole.log(test.sumar(2, 3))\nconsole.log(test.restar(5, 3))\nconsole.log(test.multiplicar(4, 3)) \nconsole.log(test.dividir(10, 2)) "
  },
  {
    "path": "Roadmap/24 - DECORADORES/javascript/Chrisdev00.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de \"decorador\" y muestra cómo crearlo\n * con un ejemplo genérico.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un decorador que sea capaz de contabilizar cuántas veces\n * se ha llamado a una función y aplícalo a una función de tu elección.\n */\n\nvar Car = function() {\n    var car = {ruedas: 4};\n    pintar('red')(car);\n    return car\n};\n\nfunction pintar (c){\n    return function(car){\n        car.color= c;\n    };\n}\n\n\nvar myCar = Car()\nconsole.log(myCar)\n\n\n\n/////////// ------------------------------ EXTRA ---------------------------------------- /////////////////\n\nfunction contador(func) {\n    function funcionModificada(...args) {\n        funcionModificada.llamadas += 1;\n        console.log(`La función ${func.name} ha sido llamada ${funcionModificada.llamadas} veces`);\n        return func(...args);\n    }\n    funcionModificada.llamadas = 0;\n    return funcionModificada;\n}\n\nfunction factorial(num) {\n    let res = 1;\n    for (let i = 1; i <= num; i++) {\n        res *= i;\n    }\n    return res;\n}\n\n// Decorar la función factorial\nconst factorialConContador = contador(factorial);\n\nconsole.log(factorialConContador(5)); \nconsole.log(factorialConContador(4));  \nconsole.log(factorialConContador(3));"
  },
  {
    "path": "Roadmap/24 - DECORADORES/javascript/DavidMoralesDeveloper.js",
    "content": "// decora otra funcion, esto quiere decir que la funcion original no cambia, podemos añadir un comportamiento a una funcion\n// Decoradores: Se crean objetos decoradores que \"envuelven\" el objeto base o a otros decoradores. como cebolla en capas\n// PATRONES DECORATIVAS CON CLASS \nclass Cafe {\n   costo (){\n    return 10\n   }\n}\n\nclass Leche {\n    constructor(cafe){\n        this.cafe = cafe\n    }\n\n    costo() {\n        return this.cafe.costo() + 2\n    }\n}\n\nclass Azucar {\n    constructor(cafe) {\n        this.cafe = cafe\n    }\n    costo (){\n        return this.cafe.costo() + 1\n    }\n}\n\nconst cafe = new Cafe()\nconst cafeConLeche = new Leche(cafe)\nconst cafeConAzucar = new Azucar(cafe)\nconst cafeConLecheYAzucar= new Azucar(cafeConLeche)\nconsole.log(cafe.costo())\nconsole.log(cafeConAzucar.costo())\nconsole.log(cafeConLeche.costo())\nconsole.log(cafeConLecheYAzucar.costo())\n\nconsole.log(\"-------------------------TERMINA PATRONES DECORATIVOS\")\n\nconsole.log(\"-------------------------COMIENZAN FUNCIONES DECORATIVAS\")\n\nfunction logFunction(func) {\n    return function(...args) {\n        console.log(`🔍 Ejecutando función: ${func.name}`);\n        const result = func.apply(this, args);\n        console.log(`✅ Función ${func.name} completada`);\n        return result;\n    };\n}\n\n// Aplicar el decorador\nconst saludar = logFunction(function saludar(nombre) {\n    return `¡Hola, ${nombre}!`;\n});\n\nconst sumar = logFunction(function sumar(a, b) {\n    return a + b;\n});\n\n\n\n// Usar las funciones decoradas\nconsole.log(saludar(\"Juan\"));\nconsole.log(sumar(5, 3));\n\nconsole.log('-------------------comienza ejercicio extra');\n\nfunction contadorDeFunciones(func) {\n  let contador = 0; // This 'contador' is in the outer scope and will persist across calls\n\n  const decoradorFunciones = function (...args) {\n    contador += 1; // Correctly increments the persistent 'contador'\n    console.log(`La función ${func.name} se ha ejecutado ${contador} vez(es).`); // More accurate phrasing for single/plural\n\n    const result = func.apply(this, args); // Execute the original function\n\n    return result;\n  };\n\n  // Attach a method to the decorated function to get the current count\n  decoradorFunciones.getCount = () => contador;\n\n  return decoradorFunciones;\n}\n\nconst saludare = (nombre) => {\n  console.log(`Hola ${nombre}`);\n};\n\nconst saludarContador = contadorDeFunciones(saludare); // Decorate 'saludare'\n\n// --- IMPORTANT: Call the *decorated* function here ---\nsaludarContador(\"David\");\nsaludarContador(\"Jhon\");\nsaludarContador(\"Juan\");\n\nconsole.log(`Total de ejecuciones de 'saludar': ${saludarContador.getCount()} vez(es).`);\n\nconst multiplicar = (a, b) => { a*b}\nmultiplicarContador = contadorDeFunciones(multiplicar)\nmultiplicarContador(5,2)\nmultiplicarContador(5,5)\nconsole.log(multiplicarContador.getCount()+ \"veces se a usado la funcion multiplicar\")\n\n\nconst countFunc = contadorDeFunciones(function miFuncion() {\n    console.log('Ejecutando mi función...');\n    return 'Resultado';\n});\n\nconsole.log(countFunc()); // Llamada #1\nconsole.log(countFunc()); // Llamada #2\n\n\nconsole.log('Total de llamadas en la funcion mi cuncion:', countFunc.getCount());"
  },
  {
    "path": "Roadmap/24 - DECORADORES/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #24 - JavaScript ->Jesus Antonio Escamilla */\n\n/**\n * Los decoradores en JavaScript son funciones que permiten agregar nuevas funcionalidades a clases, métodos o propiedades sin cambiar su código original.\n * Funcionan envolviendo el elemento original con una nueva función que añade o modifica su comportamiento.\n * Esto es útil porque permite extender las capacidades de un objeto de manera flexible y reutilizable, siguiendo el patrón de diseño.\n * Decorator que consiste en añadir funcionalidades adicionales a un objeto colocándolo dentro de otro objeto especial que contiene estas funcionalidades.\n*/\n\n//---EJERCIÓ---\n/*Decorador de Validación y Registro Cambiando*/\n// Decorador\nfunction loginUserAction(service) {\n    return {\n        createUser(user){\n            //Validación\n            if (!user.name || !user.email) {\n                throw new Error('Datos dek usuario no validos');\n            }\n            console.log(`Intentando crear usuario: ${JSON.stringify(user)}`);\n\n            // Llamando a la función original\n            const result = service.createUser(user);\n\n            console.log(`Resultado: ${result}`);\n            return result;\n        }\n    }\n}\n\n// Clase Original\nclass UserService{\n    createUser(user){\n        return `Usuario ${user.name} ha sido creado con éxito.`;\n    }\n}\n\n// Creando ña instancia de Clase y aplicando el decorador\nlet userService = new UserService();\nuserService = loginUserAction(userService);\n\n// Usar la clase del decorador\nconst user = { name: \"Jesus\", email: \"JesusAEE@outlook.com\" };\n    try {\n        console.log(userService.createUser(user));\n    } catch (error) {\n        console.error(error.message);\n    }\n\n\n\n/**-----DIFICULTAD EXTRA-----*/\n\n/*Decorador Contabilizar */\n//  Decorador\nfunction contadorLlamadas(func) {\n    let count = 0;\n\n    function decorador(...args) {\n        count++;\n        console.log(`La función ${func.name} ha sido llamada ${count} veces`);\n        return func(...args);\n    }\n    return decorador;\n}\n\n//  Función de suma\nfunction suma(a, b) {\n    return a + b;\n}\n\n//  Aplicamos el decorador\nconst sumaDecorador = contadorLlamadas(suma);\n\n//  Probamos la función decorador\nconsole.log(sumaDecorador(2, 4));\nconsole.log(sumaDecorador(7, 1));\nconsole.log(sumaDecorador(5, 6));\n\n/**-----DIFICULTAD EXTRA-----*/"
  },
  {
    "path": "Roadmap/24 - DECORADORES/javascript/RaulDoezon.js",
    "content": "/*\n  EJERCICIO:\n  Explora el concepto de \"decorador\" y muestra cómo crearlo\n  con un ejemplo genérico.\n*/\n\nconsole.log(\"+++++++++ EJEMPLO DE DECORADOR +++++++++\");\n\nfunction decoratorMyName(callback) {\n  return function(myName) {\n    callback(myName);\n  };\n}\n\nfunction sayHello(name) {\n  console.log(`¡Hola, me llamo ${name}!`);\n}\n\nconst decoratedSayHello = decoratorMyName(sayHello);\n\ndecoratedSayHello(\"Samus Aran\");\n\n/*\n  DIFICULTAD EXTRA (opcional):\n  Crea un decorador que sea capaz de contabilizar cuántas veces\n  se ha llamado a una función y aplícalo a una función de tu elección.\n*/\n\nconsole.log(\"\\n+++++++++ CONTADOR DE LLAMADAS EN FUNCIONES +++++++++\");\n\nfunction decoratorCounter(callback) {\n  let counter = 0;\n\n  return function() {\n    counter++;\n\n    console.log(`La cantidad de veces que la funcion \"${callback.name}\" se ha llamado es de: ${counter}`);\n  }\n}\n\nfunction metroid() {\n  return;\n}\n\nfunction residentEvil() {\n  return;\n}\n\nconst decoratedMetroid = decoratorCounter(metroid);\nconst decoratedResidentEvil = decoratorCounter(residentEvil);\n\ndecoratedMetroid();\ndecoratedResidentEvil();\ndecoratedMetroid();\ndecoratedMetroid();\ndecoratedMetroid();\ndecoratedResidentEvil();\ndecoratedResidentEvil();\ndecoratedMetroid();\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/javascript/RicJDev.js",
    "content": "//EJERCICIO\nfunction steveDecorator(fun) {\n\treturn function (...arg) {\n\t\tlet result = fun(...arg);\n\t\tconsole.log('Soy Steve, el decorador');\n\t\treturn result;\n\t};\n}\n\nfunction greeting(name) {\n\tconsole.log(`\\nHola, ${name}`);\n}\n\ngreeting('Jeff');\n\ngreeting = steveDecorator(greeting);\n\ngreeting('Gerard');\n\n//EXTRA\nfunction counterDecorator(fun) {\n\tlet count = 0;\n\n\treturn function (...arg) {\n\t\tcount++;\n\t\tresult = fun(...arg);\n\t\tconsole.log(`Conteo de llamadas de ${fun.name}(): ${count}`);\n\t\treturn result;\n\t};\n}\n\nfunction addTwoNumbers(a, b) {\n\tconsole.log(`\\nEl resultado de sumar ${a} y ${b} es ${a + b}`);\n}\n\naddTwoNumbers = counterDecorator(addTwoNumbers);\n\naddTwoNumbers(10, 23);\naddTwoNumbers(14, 3);\n\nfunction square(a) {\n\tconsole.log(`\\nEl cuadrado de ${a} es igual a ${a * a}`);\n}\n\nsquare = counterDecorator(square);\n\nsquare(9);\nsquare(5);\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/javascript/Sac-Corts.js",
    "content": "function greet(name) {\n    return `Hello, ${name}!`;\n}\n\nfunction logDecorator(fn) {\n    return function(...args) {\n        console.log(`Calling function: ${fn.name}`);\n        const result = fn(...args);\n        console.log(`Function ${fn.name} executed with result: ${result}`);\n        return result;\n    };\n}\n\nconst decoratedGreet = logDecorator(greet);\nconsole.log(decoratedGreet(\"Isaac\"));\n\n// Extra Exercise //\nfunction callCountDecorator(fn) {\n    let count = 0;\n    \n    return function(...args) {\n        count++;\n        console.log(`Function ${fn.name} has been called ${count} times`);\n        return fn(...args);\n    };\n}\n\nconst decoratedGreet2 = callCountDecorator(greet);\nconsole.log(decoratedGreet2(\"Hiel\"));\nconsole.log(decoratedGreet2(\"Kurama\"));\nconsole.log(decoratedGreet2(\"Yusuke\"));\nconsole.log(decoratedGreet2(\"Kuwabara\"));"
  },
  {
    "path": "Roadmap/24 - DECORADORES/javascript/adrs1166ma.js",
    "content": "/* 🔥 EJERCICIO:\nExplora el concepto de \"decorador\" y muestra cómo crearlo\ncon un ejemplo genérico.\n*/\n\nfunction decoradorEjemplo(funcionOriginal) {\n    return function(...args) {\n        console.log(`Antes de ejecutar la función: ${funcionOriginal.name}`)\n        const resultado = funcionOriginal(...args)\n        console.log(`Después de ejecutar la función: ${funcionOriginal.name}`)\n        return resultado\n    }\n}\n\n// Función a decorar\nfunction saludar(nombre) {\n    console.log(`¡Hola, ${nombre}!`)\n}\n\n// Crear una versión decorada de la función\nconst saludarDecorado = decoradorEjemplo(saludar)\n\n// Uso de la función decorada\nsaludarDecorado(\"Anderson\")\n// Antes de ejecutar la función: saludar\n// ¡Hola, Anderson!\n// Después de ejecutar la función: saludar\n\n\n\n/* 🔥 DIFICULTAD EXTRA (opcional): --------------------------------------------------------------------------\nCrea un decorador que sea capaz de contabilizar cuántas veces\nse ha llamado a una función y aplícalo a una función de tu elección.\n */\n\nfunction contadorDeLlamadas(funcionOriginal) {\n    let contador = 0\n    return function(...args) {\n        contador++\n        console.log(`Llamada ${contador} a la función: ${funcionOriginal.name}`)\n        return funcionOriginal(...args)\n    }\n}\n\nfunction sumar(a, b) {\n    return a + b\n}\n\n// Crear una versión decorada de la función\nconst sumarContada = contadorDeLlamadas(sumar)\n\nconsole.log(sumarContada(2, 3))\nconsole.log(sumarContada(5, 5))\nconsole.log(sumarContada(10, 10))\n// Llamada 1 a la función: sumar\n// 5\n// Llamada 2 a la función: sumar\n// 10\n// Llamada 3 a la función: sumar\n// 20"
  },
  {
    "path": "Roadmap/24 - DECORADORES/javascript/agusrosero.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de \"decorador\" y muestra cómo crearlo\n * con un ejemplo genérico.\n */\nclass Math {\n  add(a, b) {\n    return a + b;\n  }\n}\n\nfunction decoratorLog(f) {\n  let oldValue = f;\n\n  f = function () {\n    console.log(`Calling \"${f.name}\" with`, arguments);\n    return oldValue.apply(null, arguments);\n  };\n}\n\nMath.prototype.add = decoratorLog(Math.prototype.add);\n\n/* DIFICULTAD EXTRA (opcional):\n * Crea un decorador que sea capaz de contabilizar cuántas veces\n * se ha llamado a una función y aplícalo a una función de tu elección.\n */\n\nfunction contadorLlamadas(fn) {\n  let contador = 0;\n\n  return function (...args) {\n    contador++;\n    console.log(`La función ha sido llamada ${contador} veces`);\n\n    return fn.apply(this, args);\n  };\n}\n\nfunction saludo(nombre) {\n  console.log(`Hola, ${nombre}!`);\n}\n\nconst saludoConContador = contadorLlamadas(saludo);\n\nsaludoConContador(\"Hernan\");\nsaludoConContador(\"Agustin\");\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/javascript/bernatcs.js",
    "content": "// ** EJERCICIO\n\nfunction timeLogger(targetFunction) {\n    return function(...args) {\n        console.time('Execution Time');\n        const result = targetFunction.apply(this, args);\n        console.timeEnd('Execution Time');\n        return result;\n    };\n}\n\nfunction sayHello(name) { // Función original\n    console.log(`Hola, ${name}!`);\n}\n\nconst timedSayHello = timeLogger(sayHello); // Decorar la función\n\n//timedSayHello('Pepe'); // Llamar a la función decorada\n\n// ** DIFICULTAD EXTRA ** ------------------------------------------------------------------------------------------------------------------------------------------------\n\n\nfunction timeCounter(targetFunction) {\n    let functionCount = 0\n\n    return function(...args) {\n        const result = targetFunction.apply(this, args);\n        functionCount++\n        console.log('La función sayHello se ha ejecutado ' + functionCount + ' veces.')\n    };\n}\nfunction sayHello(name) { // Función original\n    console.log(`Hola, ${name}!`);\n}\nconst countedSayHello = timeCounter(sayHello)\n\ncountedSayHello('Juan')\ncountedSayHello('María')\ncountedSayHello('Julián')"
  },
  {
    "path": "Roadmap/24 - DECORADORES/javascript/caterinarodriguezdev.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de \"decorador\" y muestra cómo crearlo\n * con un ejemplo genérico.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un decorador que sea capaz de contabilizar cuántas veces\n * se ha llamado a una función y aplícalo a una función de tu elección.\n */\n\n/*  \n\nEsta es la propuesta de decoradores de Javascript, aún en stage 3\nfunction logger(value, context) {\n    console.log(value, context);\n}\n\n@logger\nclass Persona {\n\n    altura = 1.75;\n\n    @logger\n    getAltura() {\n        return this.altura;\n    }\n} \n*/\n\n// Implementación del Patrón Decorador sin sintaxis de decorador\nfunction logger(metodo) {\n\n    return function (...arg) {\n    \n        let result = metodo.apply(this, ...arg);\n        console.log('El decorador se ha ejecutado');\n\n        return result;\n    };\n}\n\nclass Persona {\n\n    altura = 1.75;\n\n    getAltura() {\n        console.log('Altura', this.altura);\n        return this.altura;\n    }\n}\n\np1 = new Persona();\n\np1.getAltura = logger(p1.getAltura);\np1.getAltura();\n\n\nconsole.log('---------------------------DIFICULTAD EXTRA------------------------');\n\nlet numLlamadas = 0;\n\nconst contador = (metodo) => {\n\n    return function (...arg) {\n\n        numLlamadas++;\n        metodo.apply(this, ...arg);\n    }\n}\n\nlet antonioRecio = () => {\n    console.log('Antonio Recio, mayorista, no limpio pescado');\n}\n\nantonioRecio = contador(antonioRecio);\n\nlet i = 0;\nwhile (i < Math.floor(Math.random() * 10) + 1) {\n    antonioRecio();\n    i++;\n}\n\nconsole.log(`La función ha sido llamada ${numLlamadas} veces`);"
  },
  {
    "path": "Roadmap/24 - DECORADORES/javascript/duendeintemporal.js",
    "content": "//#24 - PATRONES DE DISEÑO: DECORADORES\n/*\n * EJERCICIO:\n * Explora el concepto de \"decorador\" y muestra cómo crearlo\n * con un ejemplo genérico.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un decorador que sea capaz de contabilizar cuántas veces\n * se ha llamado a una función y aplícalo a una función de tu elección.\n*/\n\nlet log = console.log;\n\nwindow.addEventListener('load', ()=>{\n    const body = document.querySelector('body');\n    const title = document.createElement('h1');\n    \n    body.style.setProperty('background', '#000');\n    body.style.setProperty('text-align', 'center');\n    \n    title.textContent = 'Retosparaprogramadores #24.';\n    title.style.setProperty('font-size', '3.5vmax');\n    title.style.setProperty('color', '#fff');\n    title.style.setProperty('line-height', '100vh');\n    \n    body.appendChild(title);\n    \n    setTimeout(()=>{\n    alert('Retosparaprogramadores #24. Please open the Browser Developer Tools.');\n    }, 2000);\n    log( 'Retosparaprogramadores #24'); \n});\n\n\n/* The decorator pattern is a structural design pattern that allows behavior to be added to individual objects, either statically or dynamically, without affecting the behavior of other objects from the same class. In JavaScript, decorators can be implemented using higher-order functions. */\n\n// Generic decorator function\nfunction decorator(fn) {\n    return function(...args) {\n        log(\"Before calling the function\");\n        const result = fn(...args);\n        log(\"After calling the function\");\n        return result;\n    };\n}\n\n// Decorator to log execution time\nfunction logExecutionTime(fn) {\n    return async function(...args) {\n        const start = performance.now(); // Start time\n        const result = await fn(...args); \n        const end = performance.now(); // End time\n        log(`Execution time for ${fn.name}: ${end - start} milliseconds`);\n        return result; \n    };\n}\n\n// Example function that simulates a time-consuming task\nfunction fetchData() {\n    return new Promise((resolve) => {\n        setTimeout(() => {\n            resolve(\"Data fetched!\");\n        }, 3000);\n    });\n}\n\n// Decorated function\nconst loggedFetchData = logExecutionTime(fetchData); // Execution time for fetchData: 10732 milliseconds\n\n//Note: the fetchData() has delate of 3 seconds so the previus msj will be logged at the end after that time.\n\n// Using the decorated function\nloggedFetchData().then(result => log(result)); // Data fetched!\n\n\n//EXTRA DIFICULTY EXERCISE\n\n// Decorator to count function calls\nfunction countCalls(fn) {\n    let callCount = 0; // Private variable to keep track of calls through closure\n\n    return function(...args) {\n        callCount++; \n        log(`Function has been called ${callCount} times.`);\n        return fn(...args); \n    };\n}\n\n// Original function\nfunction hiGirl() {\n    log('Hi Girl! \\uD83C\\uDF39');\n    return '\\uD83C\\uDF3C';\n}\n\n// Decorated function\nconst countedhiGirl = countCalls(hiGirl);\n\n// Using the decorated function\nlog(countedhiGirl()); // Function has been called 1 times. Hi Girl! 🌹 \nlog(countedhiGirl()); // Function has been called 2 times. Hi Girl! 🌹\nlog(countedhiGirl()); // Function has been called 3 times. Hi Girl! 🌹\n\n// Trying to access countedhiGirl directly will result in an error\n// log(countedhiGirl); // Uncaught ReferenceError: countedhiGirl is not defined\n\n\n\n/* NOTE: When you define a function inside another function, the inner function creates a private scope. This means that the inner function has access to the variables and parameters of the outer function, but those variables are not accessible from outside the outer function. This is a key feature of closures in JavaScript.\n\nExplanation of Private Scope with Closures\nIn the context of the decorator pattern, this private scope allows us to maintain state (like the callCount in the counting decorator) without exposing it to the outside world. Here’s a breakdown of how this works:\n\nClosure: When the inner function is returned from the outer function, it retains access to the outer function's variables. This is known as a closure. The inner function can use and modify these variables even after the outer function has finished executing.\nPrivate Variables: Variables defined in the outer function (like callCount) are not accessible from outside the function. This means that you cannot directly modify or read callCount from outside the countCalls function, which effectively makes it private.*/"
  },
  {
    "path": "Roadmap/24 - DECORADORES/javascript/eugeniasoria.js",
    "content": "/*\r\n * EJERCICIO:\r\n * Explora el concepto de \"decorador\" y muestra cómo crearlo\r\n * con un ejemplo genérico.\r\n*/\r\nlet alumno = function (nombre) {\r\n  this.nombre = nombre;\r\n  this.mostrar = function () {\r\n    console.log(`Alumno: ${this.nombre}`);\r\n  };\r\n}\r\n\r\nlet alumnoDecorado = function (alumno, promedio, curso) {\r\n  this.alumno = alumno;\r\n  this.nombre = alumno.nombre; //igual a nombre de alumno\r\n  this.promedio = promedio;\r\n  this.curso = curso;\r\n\r\n  this.mostrar = function() {\r\n    console.log(`Alumno decorado: ${this.nombre}. Promedio: ${this.promedio}. Curso: ${this.curso}`);\r\n  };\r\n}\r\nconsole.log('>>>Ejemplo Genérico')\r\nlet miAlumno = new alumno('Jaimito');\r\nmiAlumno.mostrar();\r\n\r\nlet miAlumnoDecorado = new alumnoDecorado(miAlumno, 7, \"4to A\");\r\nmiAlumnoDecorado.mostrar();\r\n\r\n/*\r\n* DIFICULTAD EXTRA (opcional):\r\n* Crea un decorador que sea capaz de contabilizar cuántas veces\r\n* se ha llamado a una función y aplícalo a una función de tu elección.\r\n*/\r\n\r\nlet numeroAleatorio = function (top = 10) {\r\n  console.log(Math.floor(Math.random() * top));\r\n}\r\n\r\nlet contarEjecuciones = function (func) {\r\n  let count = 0;\r\n  this.ejecutar = function (param){\r\n    count ++;\r\n    console.log(`Funcion <${func.name}> ejecutada ${count} veces`);\r\n    func(param);\r\n  }\r\n}\r\n\r\nconsole.log('\\n>>>Dificultad Extra')\r\nlet contador = new contarEjecuciones(numeroAleatorio)\r\ncontador.ejecutar(5);\r\ncontador.ejecutar(3);\r\ncontador.ejecutar(4);\r\ncontador.ejecutar(10);\r\ncontador.ejecutar();\r\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/javascript/eulogioep.js",
    "content": "/*\n * TEORÍA DE DECORADORES EN JAVASCRIPT\n * \n * Los decoradores son funciones especiales que pueden modificar el comportamiento\n * de clases, métodos y propiedades. En JavaScript, son una característica que\n * permite añadir funcionalidad adicional de manera declarativa.\n * \n * Tipos principales de decoradores:\n * 1. Decoradores de clase\n * 2. Decoradores de método\n * 3. Decoradores de propiedad\n * \n * Para usar decoradores necesitas:\n * 1. Un entorno que soporte la sintaxis de decoradores (Node.js moderno o Babel)\n * 2. Configurar el compilador para soportar decoradores\n */\n\n// Ejemplo 1: Decorador de clase\nfunction logClass(target) {\n    // Este decorador registra cuando se crea una instancia de la clase\n    console.log(`Clase creada: ${target.name}`);\n    return target;\n}\n\n// Ejemplo 2: Decorador de método\nfunction logMethod(target, key, descriptor) {\n    // Guardamos la función original\n    const originalMethod = descriptor.value;\n    \n    // Reemplazamos el método con una nueva función\n    descriptor.value = function(...args) {\n        console.log(`Llamando al método ${key}`);\n        return originalMethod.apply(this, args);\n    }\n    \n    return descriptor;\n}\n\n// Ejercicio Extra: Decorador contador de llamadas\nfunction contadorLlamadas(target, key, descriptor) {\n    // Creamos un mapa para almacenar los contadores de cada método\n    if (!target.constructor._contadores) {\n        target.constructor._contadores = new Map();\n    }\n    \n    // Guardamos la función original\n    const originalMethod = descriptor.value;\n    \n    // Reemplazamos el método con una nueva función que incluye el contador\n    descriptor.value = function(...args) {\n        // Obtenemos el contador actual o inicializamos en 0\n        const contador = (target.constructor._contadores.get(key) || 0) + 1;\n        target.constructor._contadores.set(key, contador);\n        \n        console.log(`La función ${key} ha sido llamada ${contador} veces`);\n        \n        // Llamamos a la función original\n        return originalMethod.apply(this, args);\n    }\n    \n    return descriptor;\n}\n\n// Aplicamos el decorador a una clase\n@logClass\nclass Ejemplo {\n    constructor() {\n        console.log('Constructor de Ejemplo ejecutado');\n    }\n    \n    @logMethod\n    saludar(nombre) {\n        return `¡Hola ${nombre}!`;\n    }\n}\n\n// Clase con el decorador contador\nclass Calculadora {\n    @contadorLlamadas\n    sumar(a, b) {\n        return a + b;\n    }\n    \n    @contadorLlamadas\n    multiplicar(a, b) {\n        return a * b;\n    }\n}\n\n// Código de prueba\nconsole.log(\"=== Pruebas de los decoradores ===\");\n\n// Prueba del decorador de clase y método\nconst ejemplo = new Ejemplo();\nconsole.log(ejemplo.saludar(\"JavaScript\"));\n\n// Prueba del decorador contador\nconst calc = new Calculadora();\nconsole.log(\"Resultado suma:\", calc.sumar(5, 3));        // Primera llamada a sumar\nconsole.log(\"Resultado suma:\", calc.sumar(2, 4));        // Segunda llamada a sumar\nconsole.log(\"Resultado multiplicación:\", calc.multiplicar(3, 4));   // Primera llamada a multiplicar\nconsole.log(\"Resultado suma:\", calc.sumar(1, 1));        // Tercera llamada a sumar\n\n// Ejemplo de uso de decoradores con clases ES6 modernas\n// Decorador que añade un método a la clase\nfunction añadirMetodo(target) {\n    target.prototype.nuevoMetodo = function() {\n        return \"Este es un método añadido por el decorador\";\n    }\n    return target;\n}\n\n@añadirMetodo\nclass EjemploModerno {\n    constructor() {\n        console.log(\"Clase moderna creada\");\n    }\n}\n\nconst ejemploModerno = new EjemploModerno();\nconsole.log(ejemploModerno.nuevoMetodo());"
  },
  {
    "path": "Roadmap/24 - DECORADORES/javascript/hectorio23.js",
    "content": "\"use strict\";\n// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23 \n\n// Definición del decorador genérico\nfunction customDecorator(func) {\n    // Retorna una función que envuelve la función original\n    return function() {\n        console.log(\"Algo se está haciendo antes de llamar a la función\");\n        func();\n        console.log(\"Algo se está haciendo después de llamar a la función\");\n    };\n}\n\n// Define la función doSomething\nfunction doSomething() {\n    console.log(\"Esta es mi función\");\n}\n\n// Aplica el decorador customDecorator a la función doSomething\nconst doSomethingDecorado = customDecorator(doSomething);\n\n// Llamada a la función doSomething decorada\ndoSomethingDecorado(); // Output esperado: Algo se está haciendo antes de llamar a la función\n                       //                Esta es mi función\n                       //                Algo se está haciendo después de llamar a la función\n\n// Definición del decorador contador\nfunction counter(func) {\n    // Inicializa el contador de llamadas en 0\n    let llamadas = 0;\n\n    // Retorna una función que envuelve la función original\n    return function(...args) {\n        llamadas++;\n        console.log(`Se ha llamado a ${func.name} ${llamadas} veces`);\n        // Llama a la función original con los argumentos proporcionados\n        return func.apply(this, args);\n    };\n}\n\n// Define la función saludar\nfunction saludar() {\n    console.log(\"¡Hola Mundo!\");\n}\n\n// Aplica el decorador counter a la función saludar\nconst saludarDecorado = counter(saludar);\n\n// Llamadas a la función saludar decorada\nsaludarDecorado(); // Output esperado: Se ha llamado a saludar 1 veces\n                   //                ¡Hola Mundo!\nsaludarDecorado(); // Output esperado: Se ha llamado a saludar 2 veces\n                   //                ¡Hola Mundo!\nsaludarDecorado(); // Output esperado: Se ha llamado a saludar 3 veces\n                   //                ¡Hola Mundo!\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n_______________________________________\n#24 DECORADORES\n---------------------------------------\n * EJERCICIO:\n * Explora el concepto de \"decorador\" y muestra cómo crearlo\n * con un ejemplo genérico.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un decorador que sea capaz de contabilizar cuántas veces\n * se ha llamado a una función y aplícalo a una función de tu elección.\n*/\n// ________________________________________________________\nfunction myDecorator(func) {\n    return function (...args) {\n      console.log(\"\\nAntes de que se llame a la función.\");\n      func(...args);\n      console.log(\"Después de llamarla.\");\n    };\n  }\n  \n  function sayHello(firstName, lastName) {\n    console.log(`Hola, ${firstName} ${lastName}!`);\n  }\n  \n  const decoratedSayHello = myDecorator(sayHello);\n  decoratedSayHello(\"Zoe\", \"Roy\");\n  \n  console.log(\"\\n______________________\");\n  function classDecorator(Class) {\n    return class extends Class {\n      greet() {\n        console.log(\"\\nAntes de llamar al método\");\n        super.greet();\n        console.log(\"Después de llamar al método\");\n      }\n    };\n  }\n  \n  // ________________________________________________________\n  console.log(\"DIFICULTAD EXTRA\");\n  \n  function countCalls(func) {\n    const wrapper = function (...args) {\n      wrapper.calls++;\n      func(...args);\n      console.log(`Ha sido llamada ${wrapper.calls} veces.`);\n    };\n    wrapper.calls = 0;\n    return wrapper;\n  }\n  \n  const functionA = countCalls(function (funcName) {\n    console.log(`\\nLa función '${funcName}':`);\n  });\n  \n  const functionB = countCalls(function (funcName, example) {\n    console.log(`\\nLa función ${funcName} - ${example}:`);\n  });\n  \n  functionA(\"A\");\n  functionA(\"A\");\n  functionA(\"A\");\n  \n  functionB(\"B\", \"args\");\n  functionB(\"B\", \"args\");\n  "
  },
  {
    "path": "Roadmap/24 - DECORADORES/javascript/nlarrea.js",
    "content": "/**\n * EJERCICIO:\n * Explora el concepto de \"decorador\" y muestra cómo crearlo\n * con un ejemplo genérico.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un decorador que sea capaz de contabilizar cuántas veces\n * se ha llamado a una función y aplícalo a una función de tu elección.\n */\n\nfunction measureTime(func) {\n    return function (...args) {\n        const start = performance.now();\n        const result = func(...args);\n        const end = performance.now();\n        console.log(`Required time: ${Math.round(((end - start) / 1000 * 100) / 100)} seconds`);\n\n        return result;\n    }\n}\n\n\nfunction sumTwoValues(numOne, numTwo) {\n    const wait = ms => {\n        const start = new Date().getTime();\n        let end = start;\n\n        while (end <= start + ms) {\n            end = new Date().getTime();\n        }\n    }\n\n    wait(3000);\n    return numOne + numTwo;\n}\n// Decorate function\nconst decoratedSumTwoValues = measureTime(sumTwoValues);\n\nconsole.log(decoratedSumTwoValues(10, 5));\n/** This call prints:\n * Required time: 3 seconds\n * 15\n */\n\n\n/**\n * DIFICULTAD EXTRA (opcional):\n * Crea un decorador que sea capaz de contabilizar cuántas veces\n * se ha llamado a una función y aplícalo a una función de tu elección.\n */\n\nfunction callCounter(func) {\n    function wrapper(...args) {\n        wrapper.counter++;\n        const result = func(...args);\n        console.log(\n            `Calls number for function \"${func.name}\": ${wrapper.counter}`\n        );\n        \n        return result;\n    }\n\n    wrapper.counter = 0;\n    return wrapper;\n}\n\n\n// First function to test\nfunction printMessage(message = 'Hello there!') {\n    console.log(message);\n}\n// Decorate the new function\nconst decoratedPrintMessage = callCounter(printMessage);\n\n\n// Second function to test\nfunction multiply(a, b) {\n    return a * b;\n}\nconst decoratedMultiply = callCounter(multiply);\n\ndecoratedPrintMessage('Hello JS');  // 1\ndecoratedPrintMessage();  // 2\ndecoratedMultiply(3, 2);  // 1\ndecoratedPrintMessage('Hello JavaScript');  // 3\ndecoratedMultiply(10, 10);  // 2\n/** All of this calls print:\n * Hello JS\n * Calls number for function \"printMessage\": 1\n * Hello there!\n * Calls number for function \"printMessage\": 2\n * Calls number for function \"multiply\": 1\n * Hello JavaScript\n * Calls number for function \"printMessage\": 3\n * Calls number for function \"multiply\": 2\n */"
  },
  {
    "path": "Roadmap/24 - DECORADORES/javascript/parababire.js",
    "content": "// Ejecicio\n\n// El decorador es una función que modifica la funcionalidad de otra función sin alterar su código.\n// Un decorador implementa una función 'print_call()' que ejecute la lógica.\n\nfunction decorator(func) {\n  function print_call() {\n    console.log(`La función ${func.name} ha sido llamada.`)\n    return func;\n  }\n  return print_call();\n}\n\nfunction example() {\n}\nfunction example_2() {\n}\nfunction example_3() {\n}\n\ndecorator(example)\ndecorator(example_2)\ndecorator(example_3)\n\n// Extra\n\n/* Aun JS no soporta decoradores, el código funciona con Typescript */\n\nfunction Log(target, {kind, name}) {\n  function counter_function(...args) {\n    counter_function.call_count += 1\n    console.log(`inside ${name}, ${kind} log, se ha llamado ${counter_function.call_count} vez/veces`)\n    return target(args)\n  }\n  counter_function.call_count = 0\n  return counter_function\n}\n\nclass MyClass {\n\n  @Log\n  mymethod(arg) {\n    console.log('arg', arg)\n  }\n  @Log\n  othermethod() {\n    console.log('Hola España');\n  }\n}\n\nlet x\n\nx = new MyClass()\nx.mymethod(true)\nx.mymethod(false)\nx.mymethod(44)\nx.othermethod()\nx.mymethod('Ángel')\nx.othermethod()"
  },
  {
    "path": "Roadmap/24 - DECORADORES/javascript/pedamoci.js",
    "content": "class Notificacion {\n  notificacion() {\n    console.log('Notificación de la empresa a través de Facebook')\n  }\n}\n\nclass NotificacionDecorator {\n  constructor(base) {\n    this.base = base\n  }\n\n  notificacion() {\n    this.base.notificacion()\n  }\n}\n\nclass NotificacionSMS extends NotificacionDecorator {\n  constructor(base) {\n    super(base)\n  }\n  notificacion() {\n    console.log('Notificación de la empresa a través de SMS')\n    super.notificacion()\n  }\n}\n\nclass NotificacionTelegram extends NotificacionDecorator {\n  constructor(base) {\n    super(base)\n  }\n  notificacion() {\n    console.log('Notificación de la empresa a través de Telegram')\n    super.notificacion()\n  }\n}\n\nlet base = new Notificacion()\nbase = new NotificacionSMS(base)\nbase = new NotificacionTelegram(base)\nbase.notificacion()\n\n// --------------------------------- DIFUCULTAD EXTRA ---------------------------------\nfunction sumar(num1, num2) {\n  console.log(num1 + num2)\n}\n\nfunction contador(fn) {\n  let count = 0\n  return function(...args) {\n    count++\n    console.log(`Llamada número ${count}`);\n    return fn(...args);\n  };\n}\n\nlet result = contador(sumar)\nresult(2, 3)\nresult(2545, 321)\nresult(58, 21)\nresult(97, 68)\nresult(12, 345)"
  },
  {
    "path": "Roadmap/24 - DECORADORES/javascript/victor-Casta.js",
    "content": "/*\n  * EJERCICIO:\n  * Explora el concepto de \"decorador\" y muestra cómo crearlo\n  * con un ejemplo genérico.\n*/\n\nfunction withprintResult(func) {\n  return function (...parameters) {\n    console.log(\"Parámetros:\", parameters)\n    const result = func(...parameters)\n    console.log(\"Resultado:\", result)\n    return result\n  }\n}\n\nfunction sum(a, b) {\n  return a + b\n}\n\nfunction multiply(a, b) {\n  return a * b\n}\n\nconst sumDecorator = withprintResult(sum)\nconst multiplyDecorator = withprintResult(multiply)\n\nsumDecorator(2, 1)\nmultiplyDecorator(2, 3)\n\n/*\n  * DIFICULTAD EXTRA (opcional):\n  * Crea un decorador que sea capaz de contabilizar cuántas veces\n  * se ha llamado a una función y aplícalo a una función de tu elección.\n*/\n\nfunction counterDecorator(func) {\n  let counter = 0;\n  return function (...parameters) {\n    counter++;\n    console.log(`La función ha sido llamada ${counter} veces`)\n    return func(...parameters)\n  };\n}\n\nfunction firstFunction() {\n  console.log(\"Función ejecutada\")\n}\n\nconst decoratedFunction = counterDecorator(firstFunction)\n\ndecoratedFunction()\ndecoratedFunction()\ndecoratedFunction()\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/kotlin/blackriper.kt",
    "content": "\r\n\r\n/*\r\nPatron decorador\r\nEs un patron de diseño estructural que agrega funcionalidades a objetos existentes, sin modificar su comportamiento original.\r\nesto se logra utilizandp objetos encapsulados  que contienen estas funcionalidades.\r\n\r\ncuando queremos agregar funcionalidades a un objeto la primera solucion es usar la herencia\r\npero la herencia tiene  varias limitaciones\r\n\r\nla herencia es estatica no se puede alterar su comportamiento en tiempo de ejecucion\r\ny solo se puede sustituir un objeto por otro creando una subclase diferente.\r\n\r\nlas subclases solo pueden tener una clase padre la mayoria de los lenguajes no permiten la herencia multiple\r\ny la herencia multiple solo permite una subclase por clase padre. hay lenguajes como python que permiten la herencia multiple.\r\n\r\nuna forma de mitigar esto es usando la composicion esto en palabra simples es un objeto que contiene otro objeto al\r\ncual le delega una parte del trabajo\r\n\r\npara mas informacion revisa https://refactoring.guru/design-patterns/decorator\r\n\r\n*/\r\n\r\n//ejemplo de patron decorador\r\n\r\n//1.- primero creamos una interface que defina la funcionalidad que queremos agregar\r\ninterface ChrimasTree{\r\n   fun decorate():String\r\n}\r\n\r\n//2.- creamos la clase que implementa la interface\r\nclass PineTree: ChrimasTree{\r\n    override fun decorate() =\"Christmas tree\"\r\n\r\n}\r\n\r\n// alternativa 1 usando composicion\r\n\r\n//3.- creaamos una clase abstracta para que actue como  decorador de nuestro objeto\r\nabstract class TreeDecorator(protected val tree: ChrimasTree): ChrimasTree{\r\n    override fun decorate()=tree.decorate()\r\n\r\n}\r\n\r\n\r\n//4.- ahora creamos el metodo que va ser decorado por nuestro decorador\r\nclass BubbleLight(tree: ChrimasTree): TreeDecorator(tree) {\r\n    override fun decorate() = tree.decorate() + decoratedWithBubbleLight()\r\n    private fun decoratedWithBubbleLight() = \" decorating with Bubble Light\"\r\n}\r\n\r\n//alternativa 2 usando delegacion de kotlin\r\nclass Garlans(private val tree: ChrimasTree): ChrimasTree by tree{\r\n    override fun decorate(): String {\r\n        return tree.decorate() + decoratedWithGarlands()\r\n    }\r\n\r\n    private fun decoratedWithGarlands() = \" decorated with Garland\"\r\n}\r\n\r\nfun christmasTreeWithDecorator() {\r\n    println(\"using composition\")\r\n    val christmasTree = BubbleLight(PineTree())\r\n    val decoratedChristmasTree = christmasTree.decorate()\r\n    println(decoratedChristmasTree)\r\n\r\n    println(\"using delegation\")\r\n    val decoratedChristmasTree2 = Garlans(PineTree()).decorate()\r\n    println(decoratedChristmasTree2)\r\n\r\n}\r\n\r\n//ejercicio extra\r\n\r\ninterface Counter{\r\n    fun counterInvokes()\r\n}\r\n\r\nclass Count: Counter{\r\n   private  var count = 0\r\n    override fun counterInvokes() {\r\n        count++\r\n        println(\"the funcion was invoked $count times\")\r\n    }\r\n}\r\n\r\nclass Hello(private val counter: Counter): Counter by counter{\r\n    override fun counterInvokes() {\r\n        hello()\r\n        counter.counterInvokes()\r\n    }\r\n    private fun hello() {\r\n        println(\"hello\")\r\n    }\r\n}\r\n\r\n\r\n\r\n\r\nfun main() {\r\n    christmasTreeWithDecorator()\r\n\r\n    val hello = Hello(Count())\r\n    hello.counterInvokes()\r\n    hello.counterInvokes()\r\n}"
  },
  {
    "path": "Roadmap/24 - DECORADORES/kotlin/eulogioep.kt",
    "content": "/*\n * Decoradores en Kotlin (Versión simplificada)\n *\n * Los decoradores son un patrón de diseño estructural que permite añadir\n * nuevas funcionalidades a objetos existentes sin alterar su estructura.\n * En Kotlin, podemos implementar decoradores de manera sencilla utilizando\n * funciones de orden superior.\n *\n * En esta implementación, nos centraremos en decorar funciones específicas\n * en lugar de intentar crear un decorador genérico para cualquier tipo de función.\n */\n\n// Función que queremos decorar\nfun operation(x: Int, y: Int): Int = x + y\n\n// Decorador simple\nfun decorateOperation(func: (Int, Int) -> Int, before: () -> Unit, after: () -> Unit): (Int, Int) -> Int {\n    return { x, y ->\n        before()\n        val result = func(x, y)\n        after()\n        result\n    }\n}\n\n// Decorador para contar llamadas a función\nfun countCallsOperation(func: (Int, Int) -> Int): (Int, Int) -> Int {\n    var count = 0\n    return { x, y ->\n        count++\n        println(\"La función ha sido llamada $count veces\")\n        func(x, y)\n    }\n}\n\nfun main() {\n    // Ejemplo de uso del decorador simple\n    val decoratedOperation = decorateOperation(\n        ::operation,\n        before = { println(\"Antes de la operación\") },\n        after = { println(\"Después de la operación\") }\n    )\n\n    println(\"Resultado: ${decoratedOperation(5, 3)}\")\n\n    // Ejemplo de uso del decorador que cuenta llamadas\n    val countedOperation = countCallsOperation(::operation)\n\n    repeat(3) {\n        println(\"Resultado: ${countedOperation(it, it + 1)}\")\n    }\n}"
  },
  {
    "path": "Roadmap/24 - DECORADORES/ocaml/luishendrix92.ml",
    "content": "open Printf\n\n(******************************************************************************)\n(*                                                                            *)\n(*                                 Decorators                                 *)\n(*                                                                            *)\n(*  A {b decorator} is, in essence, a function that wraps another function    *)\n(*  in order to grant it additional behaviour without modifying the original  *)\n(*  code, oftentimes even preserving the function's signature where the only  *)\n(*  noticeable change is a side-effect that doesn't alter the return type.    *)\n(*  The most popular language that uses this technique is Python, which has   *)\n(*  dedicated syntax for decorators ({[ @decorator_name(arguments...) ]}),    *)\n(*  however, this pattern can be applied by any language that can return      *)\n(*  functions (Higher Order Functions).                                       *)\n(*                                                                            *)\n(*  In OCaml this is easy to achieve, and there are already some functions    *)\n(*  in the standard library that can be considered \"decorators\", one example  *)\n(*  is [Fun.protect] which accepts a (potentially failing) function and a     *)\n(*  function that frees the used resources in case the function fails.        *)\n(*                                                                            *)\n(*  Another potential use case of decorators is to introduce new code into    *)\n(*  the project based on existing code that has been \"annotated\" with         *)\n(*  decorators. Java annotations are a good example of this practise and we   *)\n(*  can achieve a similar behaviour using custom pre-processors (PPX). It is  *)\n(*  fairly complex but a simple demonstration wouldn't hurt.                  *)\n(*                                                                            *)\n(******************************************************************************)\n\nmodule Decorators : sig\n  val tap : f:('a -> unit) -> ('a -> 'b) -> 'a -> 'b\n  (** [tap ~f g x] runs the consumer function [f] with [x] as argument\n      before returning whatever it is that [g x] returned. *)\n\n  val timed : (unit -> 'a) -> 'a\n  (** [timed f] measures the execution time of [f ()] and prints it to the\n      console (in seconds) while also returning the value it produced. *)\n\n  val counted : ('a -> 'b) -> 'a -> 'b\n  (** [counted f x] returns the result of invoking [f] with argument [x] after\n      printing the amount of times it's been invoked with any argument.\n\n      {b NOTE}: In order for this to work, you need to partially apply\n      [counted] with a function [f] and then keep running the same partially\n      applied function; otherwise the closure counter will be lost. *)\nend = struct\n  let tap ~f g x =\n    f x;\n    g x\n  ;;\n\n  let timed f =\n    let start_time = Sys.time () in\n    let result = f () in\n    let end_time = Sys.time () in\n    printf \"Execution time in seconds: %f\\n\" @@ (end_time -. start_time);\n    result\n  ;;\n\n  let counted f =\n    let i : int ref = ref 0 in\n    fun x ->\n      incr i;\n      printf \"Function has been invoked [%d] times!\\n\" !i;\n      f x\n  ;;\nend\n\nlet rec fib = function\n  | 0 -> 0\n  | 1 -> 1\n  | n -> fib (n - 1) + fib (n - 2)\n;;\n\nlet _ =\n  let open Decorators in\n  print_endline \"Decorator [tap] example:\";\n  [ 1; 2; 3; 4; 5 ]\n  |> List.map (tap ~f:(printf \"[succ] input: %d\\n\") succ)\n  |> List.iter (printf \"After increment: %d\\n\");\n  print_endline \"Decorator [timed] example (performance measure):\";\n  printf \"fib n=45 is equal to: %d\\n\" @@ timed (fun () -> fib 45);\n  print_endline \"Decorator [counted] example:\";\n  (******************************************************************)\n  (*                                                                *)\n  (*                   Dificultad Extra (Opcional)                  *)\n  (*                                                                *)\n  (*  Crear un decorador que sea acpaz de contabilizar cuántas      *)\n  (*  veces se ha llamado a una función y aplícalo a una función    *)\n  (*  de tu elección.                                               *)\n  (*                                                                *)\n  (******************************************************************)\n  let run_me () = print_endline \"I keep running\" in\n  let run_me = counted run_me in\n  for i = 1 to 5 do\n    run_me ()\n  done\n;;\n\n(* Output:\n   -------\n   Decorator [tap] example:\n   [succ] input: 1\n   [succ] input: 2\n   [succ] input: 3\n   [succ] input: 4\n   [succ] input: 5\n   After increment: 2\n   After increment: 3\n   After increment: 4\n   After increment: 5\n   After increment: 6\n   Decorator [timed] example (performance measure):\n   Execution time in seconds: 8.358457\n   fib n=45 is equal to: 1134903170\n   Decorator [counted] example:\n   Function has been invoked [1] times!\n   I keep running\n   Function has been invoked [2] times!\n   I keep running\n   Function has been invoked [3] times!\n   I keep running\n   Function has been invoked [4] times!\n   I keep running\n   Function has been invoked [5] times!\n   I keep running\n*)\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/php/eulogioep.php",
    "content": "<?php\n\n/**\n * TEORÍA DE DECORADORES (ATRIBUTOS) EN PHP\n * \n * En PHP 8.0+ los decoradores se implementan como \"Atributos\" y permiten añadir\n * metadatos a las clases, métodos, propiedades y parámetros.\n * \n * Los atributos en PHP:\n * - Se definen como clases con el atributo #[Attribute]\n * - Se aplican usando la sintaxis #[NombreAtributo]\n * - Pueden recibir parámetros en su constructor\n * - Se pueden consultar usando la API de Reflection\n */\n\n// Ejemplo 1: Decorador simple para una clase\n#[Attribute]\nclass LogClass {\n    public function __construct(public string $message = \"\") {}\n}\n\n// Ejemplo 2: Decorador para métodos que registra la ejecución\n#[Attribute]\nclass LogMethod {\n    public function __construct(public string $message = \"\") {}\n}\n\n// Ejemplo 3: Decorador contador de llamadas (para el ejercicio extra)\n#[Attribute]\nclass ContadorLlamadas {\n    private static array $contadores = [];\n    \n    public static function incrementar(string $metodo): int {\n        if (!isset(self::$contadores[$metodo])) {\n            self::$contadores[$metodo] = 0;\n        }\n        self::$contadores[$metodo]++;\n        return self::$contadores[$metodo];\n    }\n}\n\n// Clase de ejemplo con decoradores\n#[LogClass(\"Esta es una clase de ejemplo\")]\nclass Ejemplo {\n    #[LogMethod(\"Método de saludo\")]\n    public function saludar(string $nombre): string {\n        return \"¡Hola $nombre!\";\n    }\n}\n\n// Clase Calculadora con el decorador contador\nclass Calculadora {\n    #[ContadorLlamadas]\n    public function sumar(int $a, int $b): int {\n        return $a + $b;\n    }\n\n    #[ContadorLlamadas]\n    public function multiplicar(int $a, int $b): int {\n        return $a * $b;\n    }\n}\n\n// Clase Helper para procesar los decoradores\nclass DecoratorHelper {\n    // Método para procesar decoradores de clase\n    public static function processClassDecorators(string $className): void {\n        $reflection = new ReflectionClass($className);\n        $attributes = $reflection->getAttributes();\n        \n        foreach ($attributes as $attribute) {\n            if ($attribute->getName() === LogClass::class) {\n                $instance = $attribute->newInstance();\n                echo \"Clase {$className} creada: {$instance->message}\\n\";\n            }\n        }\n    }\n\n    // Método para procesar decoradores de método\n    public static function processMethodDecorators(string $className, string $methodName): void {\n        $reflection = new ReflectionMethod($className, $methodName);\n        $attributes = $reflection->getAttributes();\n        \n        foreach ($attributes as $attribute) {\n            if ($attribute->getName() === LogMethod::class) {\n                $instance = $attribute->newInstance();\n                echo \"Método {$methodName} llamado: {$instance->message}\\n\";\n            } elseif ($attribute->getName() === ContadorLlamadas::class) {\n                $contador = ContadorLlamadas::incrementar($className . \"::\" . $methodName);\n                echo \"El método {$methodName} ha sido llamado {$contador} veces\\n\";\n            }\n        }\n    }\n}\n\n// Clase Proxy para interceptar llamadas y procesar decoradores\nclass CalculadoraProxy {\n    private Calculadora $calculadora;\n\n    public function __construct() {\n        $this->calculadora = new Calculadora();\n    }\n\n    public function __call(string $method, array $arguments) {\n        DecoratorHelper::processMethodDecorators(Calculadora::class, $method);\n        return $this->calculadora->$method(...$arguments);\n    }\n}\n\n// Código de prueba\necho \"=== Pruebas de los decoradores ===\\n\";\n\n// Prueba del decorador de clase\nDecoratorHelper::processClassDecorators(Ejemplo::class);\n\n// Prueba del decorador de método\n$ejemplo = new Ejemplo();\nDecoratorHelper::processMethodDecorators(Ejemplo::class, 'saludar');\necho $ejemplo->saludar(\"PHP\") . \"\\n\";\n\n// Prueba del decorador contador\n$calc = new CalculadoraProxy();\necho \"Resultado suma: \" . $calc->sumar(5, 3) . \"\\n\";      // Primera llamada a sumar\necho \"Resultado suma: \" . $calc->sumar(2, 4) . \"\\n\";      // Segunda llamada a sumar\necho \"Resultado multiplicación: \" . $calc->multiplicar(3, 4) . \"\\n\";  // Primera llamada a multiplicar\necho \"Resultado suma: \" . $calc->sumar(1, 1) . \"\\n\";      // Tercera llamada a sumar"
  },
  {
    "path": "Roadmap/24 - DECORADORES/php/miguelex.php",
    "content": "<?php\n\n\n    interface Vehicle {\n        public function wheels();\n    }\n\n    class Car implements Vehicle {\n        public function wheels() {\n            return 4;\n        }\n    }\n\n    class Bike implements Vehicle {\n        public function wheels() {\n            return 2;\n        }\n    }\n\n    class VehicleDecorator implements Vehicle {\n        protected $vehicle;\n\n        public function __construct(Vehicle $vehicle) {\n            $this->vehicle = $vehicle;\n        }\n\n        public function wheels() {\n            return $this->vehicle->wheels();\n        }\n    }\n\n    // Vamos a usar el patron decorador para definir ahora un tipo especial de coche que sol otien 2 puertas\n    class Coupe extends VehicleDecorator {\n        public function doors() {\n            return 2;\n        }\n    }\n\n    $car = new Car();\n    $bike = new Bike();\n    echo \"Un coche tiene \".$car->wheels().\" ruedas\\n\";\n    echo \"Una bicicleta tiene \".$bike->wheels(). \" ruedas\\n\";\n    $carWithDoors = new Coupe($car);\n    echo \"Prueba de uso de decorador\\n\";    \n    echo \"Un coche modelo Coupe tiene \".$carWithDoors->wheels(). \" ruedas pero solo tiene \".$carWithDoors->doors().\" puertas\\n\";\n\n    // Ejercicio extra\n\n    echo \"\\n\\nEjercicio extra\\n\";\n    \n\n    interface Funcion {\n        public function ejecutar();\n    }\n\n    class Suma implements Funcion {\n        private $a;\n        private $b;\n\n        public function __construct($a, $b) {\n            $this->a = $a;\n            $this->b = $b;\n        }\n\n        public function ejecutar() {\n            return $this->a + $this->b;\n        }\n    }\n\n    class ContadorDeLlamadas implements Funcion {\n        private $funcion;\n        private static $contador = 0;\n\n        public function __construct(Funcion $funcion) {\n            $this->funcion = $funcion;\n        }\n\n        public function ejecutar() {\n            self::$contador++;\n            echo \"La función ha sido llamada \" . self::$contador . \" veces.\\n\";\n            return $this->funcion->ejecutar();\n        }\n    }\n\n    $suma = new Suma(2, 2);\n    $sumaContada = new ContadorDeLlamadas($suma);\n\n    echo $sumaContada->ejecutar() . \"\\n\";\n    echo $sumaContada->ejecutar() . \"\\n\";\n    echo $sumaContada->ejecutar() . \"\\n\";\n\n\n\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/Aldroide.py",
    "content": "\"\"\" \n    Ejercicio\n    Explora el concepto de \"decorador\" y muestra cómo crearlo con un ejemplo genérico\n\"\"\"\n\n\ndef mi_decorador(func):\n    def funcion_(a, b):\n        print(\"Antes de llamar a la función\")\n        resultado = func(a, b)\n        print(\"Se llamo la función\")\n        return resultado\n    return funcion_\n\n\n@mi_decorador\ndef suma(a, b):\n    print(\"Entró a funcion suma\")\n    return a+b\n\n\n@mi_decorador\ndef resta(a, b):\n    print(\"Entró a función resta\")\n    return a-b\n\n\nr = suma(4, 5)\nprint(r)\nr = resta(5, 3)\nprint(r)\n\n\n\"\"\"\n    Crea un decorador que sea capaz de contabilizar cuántas veces\n    se ha llamado a una función y aplícalo a una función de tu elección.\n\"\"\"\n\n\ndef count_call(func):\n    def new_func():\n        new_func.contador += 1\n        print(\n            f\"La función '{func.__name__}' ha sido llamada {new_func.contador} veces\")\n        return func\n    new_func.contador = 0\n    return new_func\n\n\n@count_call\ndef my_func():\n    print(\"Ejecutanto la funcion\")\n\n\nmy_func()\nmy_func()\nmy_func()\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/CaveroBrandon.py",
    "content": "\"\"\"EJERCICIO:\nExplora el concepto de \"decorador\" y muestra cómo crearlo\ncon un ejemplo genérico\"\"\"\nfrom datetime import datetime\n\n\ndef do_not_disturb(func):\n    def wrapper_do_not_disturb(*args):\n        if 19 <= datetime.now().hour < 24:\n            print(f'- The action \"{func}\" cannot be completed at this time -')\n            print(f'Time when the action was attempted: {datetime.now().hour}:{datetime.now().minute}')\n        else:\n            func(*args)\n\n    return wrapper_do_not_disturb\n\n\n@do_not_disturb\ndef turn_lights_on(room='Hall'):\n    print(f'The lights of \"{room}\" were turned on')\n\n\n@do_not_disturb\ndef ring_the_bell(bell='Front door'):\n    print(f'The bell from \"{bell}\" was ringed')\n\n\nturn_lights_on('Bedroom')\nring_the_bell()\n\n\"\"\"DIFICULTAD EXTRA (opcional):\n * Crea un decorador que sea capaz de contabilizar cuántas veces\n * se ha llamado a una función y aplícalo a una función de tu elección.\"\"\"\n\n\ndef function_caller_counter(func):\n    def wrapper_function_caller_counter():\n        function_caller_counter.counter += 1\n        func()\n        print(f'This decorator was used {function_caller_counter.counter} times')\n    function_caller_counter.counter = 0\n    return wrapper_function_caller_counter\n\n\n@function_caller_counter\ndef show_time():\n    print(f'The current time is: {datetime.now().hour}:{datetime.now().minute}')\n\n\nshow_time()\nshow_time()\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/CesarCarmona30.py",
    "content": "'''\n  EJERCICIO\n'''\n\n\"\"\"\nEjercicio\n\"\"\"\n\n\ndef print_call(function):\n    def print_function():\n        print(f\"La función '{function.__name__}' ha sido llamada.\")\n        return function\n    return print_function\n\n\n@print_call\ndef example_function():\n    pass\n\n\n@print_call\ndef example_function_2():\n    pass\n\n\n@print_call\ndef example_function_3():\n    pass\n\nexample_function()\nexample_function_2()\nexample_function_3()\n\n\n'''\n  EXTRA\n'''\n\ndef call_counter(function):\n    def counter_function():\n        counter_function.call_count += 1\n        print(\n            f\"La función '{function.__name__} se ha llamado {counter_function.call_count}' veces.\")\n        return function\n\n    counter_function.call_count = 0\n    return counter_function\n\n\n@call_counter\ndef example_function_4():\n    pass\n\n\n@call_counter\ndef example_function_5():\n    pass\n\n\nexample_function_4()\nexample_function_4()\nexample_function_4()\nexample_function_4()\nexample_function_5()\nexample_function_4()\nexample_function_5()\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/Chrisdev00.py",
    "content": "\"\"\"\n* EJERCICIO:\n* Explora el concepto de \"decorador\" y muestra cómo crearlo\n* con un ejemplo genérico.\n*\n* DIFICULTAD EXTRA (opcional):\n* Crea un decorador que sea capaz de contabilizar cuántas veces\n* se ha llamado a una función y aplícalo a una función de tu elección.\n\"\"\"\n\nimport time\n\ndef calcularTiempo(fun):\n\n    def funcionModificada(*args, **kwargs):\n        inicio = time.time()\n        resultado = fun(*args, **kwargs)\n        final = time.time()\n        print(f\"El tiempo de ejecucion es: {final - inicio} segundos\")\n        return resultado\n\n    return funcionModificada\n\n@calcularTiempo\ndef sum_numeros(a, b):\n    return a + b\n\n@calcularTiempo\ndef imprimirNumeros(num):\n    for i in range(num):\n        print(i)\n\nprint(sum_numeros(16556301655659919911, 896474544))\nimprimirNumeros(8)\n\n\n########### --------------------------------- EXTRA ---------------------------------- ##################\n\ndef contador(fun):\n\n    def funcion_modificada(*args, **kwargs):\n        funcion_modificada.llamadas += 1\n        print(f\"La funcion {fun.__name__} ha sido llamada {funcion_modificada.llamadas} veces\")\n        return fun(*args, **kwargs)\n    \n    funcion_modificada.llamadas = 0\n    return funcion_modificada\n\n@contador\ndef factorial(num):\n    res = 1\n    for i in range(1, num+1):\n        res = res * i\n    return res\n\n\nprint(factorial(5))\nprint(factorial(4))\nprint(factorial(3))"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/EmmanuelMMontesinos.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Explora el concepto de \"decorador\" y muestra cómo crearlo\n * con un ejemplo genérico.\n */\n\"\"\"\n\n# Decoradores\ndef decorador(funcion):\n    nombre_funcion = funcion.__name__.title()\n    def parametros(*args,**kwargs):\n        if not kwargs:\n            print(f\"Decorando la función {nombre_funcion}\")\n        else:\n            print(f\"Decorando la función Doble {nombre_funcion}\")\n            print(f\"Argumentos nominales: {kwargs}\")\n        print(f\"Argumentos posicionales: {args}\")\n        resultado = funcion(*args,**kwargs)\n        print(f\"Fin del Decorado, resultado de {nombre_funcion}: {resultado}\\n\")\n        return resultado\n    return parametros\n\n@decorador\ndef suma(a,b,doble=None):\n    resultado = a + b\n    if doble:\n        resultado *= 2\n    print(resultado)\n    return resultado\n\n# Pruebas\nsuma(2,3)\nsuma(16.5,500)\nsuma(10,6,doble=\"Es doble suma\")\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un decorador que sea capaz de contabilizar cuántas veces\n * se ha llamado a una función y aplícalo a una función de tu elección.\n\"\"\"\ncontador = {}\ndef nueva_llamada(funcion):\n    def parametros(*args,**kwargs):\n        if args and kwargs:\n            resultado = funcion(*args,**kwargs)\n        elif args:\n            resultado = funcion(*args)\n        elif kwargs:\n            resultado = funcion(**kwargs)\n        else:\n            resultado = funcion()\n\n        nombre = funcion.__name__\n        if nombre in contador:\n            contador[nombre] += 1\n        else:\n            contador[nombre] = 1\n        print(contador)\n        return resultado\n    return parametros\n\n@nueva_llamada\ndef primera():\n    resultado = \"Primera Función: sin ningun tipo de argumento\"\n    print(resultado)\n    return resultado\n\n@nueva_llamada\ndef segunda(posicional):\n    resultado = f\"Segunda Función: con argumento posicional -> {posicional}\"\n    print(resultado)\n    return resultado\n\n@nueva_llamada\ndef tercera(nominal=True):\n    resultado = f\"Terccera Función: con argumento nominal -> {nominal}\"\n    print(resultado)\n    return resultado\n\n@nueva_llamada\ndef cuarta(posicional,nominal=False):\n    resultado = f\"Cuarta Función: ambos tipos de argumentos\\nposinional -> {posicional}\\nnominal -> {nominal}\"\n    print(resultado)\n    return resultado\n\n# Pruebas\nprimera()\n\nsegunda(\"Posicional\")\nsegunda(\"Posicional\")\n\ntercera(nominal=True)\ntercera(nominal=True)\ntercera(nominal=True)\n\ncuarta(\"Posicional\",nominal=True)\ncuarta(\"Posicional\",nominal=True)\ncuarta(\"Posicional\",nominal=True)\ncuarta(\"Posicional\",nominal=True)"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/FedeAirala.py",
    "content": "# #24 PATRONES DE DISEÑO: DECORADORES\n\n\"\"\"\n * EJERCICIO:\n * Explora el concepto de \"decorador\" y muestra cómo crearlo\n * con un ejemplo genérico.\n\"\"\"\n\ndef decorador(funcion):\n    def saludar():\n        print (\"-\"*60)\n        print (f\"{funcion.__name__}\")\n        return funcion()\n    return saludar\n\n@decorador\ndef hola_mundo():\n    print (\"Saludo en Español\")\n\n@decorador\ndef hello_world():\n    print (\"Saludo en Inglés\")\n\n@decorador\ndef hasta_luego():\n    print (\"Despedida en Español\")\n\n@decorador\ndef goodbye():\n    print (\"Despedida en Inglés\")\n    \nhola_mundo()\ngoodbye()\nhasta_luego()\nhasta_luego()\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un decorador que sea capaz de contabilizar cuántas veces\n * se ha llamado a una función y aplícalo a una función de tu elección.\n\"\"\"\n# Esta parte la copié de Moure porque no entendí muy bien la manera de contar las llamadas\n\ndef call_counter(function):\n    def counter_function():\n        counter_function.call_count += 1\n        print(\n            f\"La función '{function.__name__} se ha llamado {counter_function.call_count}' veces.\")\n        return function\n\n    counter_function.call_count = 0\n    return counter_function\n\n@call_counter\ndef hola_mundo():\n    print (\"Saludo en Español\")\n\n@call_counter\ndef hello_world():\n    print (\"Saludo en Inglés\")\n\n@call_counter\ndef hasta_luego():\n    print (\"Despedida en Español\")\n\n@call_counter\ndef goodbye():\n    print (\"Despedida en Inglés\")\n    \nhola_mundo()\ngoodbye()\nhasta_luego()\nhasta_luego()\ngoodbye()\ngoodbye()\nhola_mundo()"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/Gordo-Master.py",
    "content": "\"\"\"\nDecoradores\n\"\"\"\n\n# Sirven para agregar funcionalidades a una funcion o metodo, y ademas no se crea una nueva instancia.\n# Tambien tiene la caracteristica que van responsabilizando la ejecución de las funciones a la envoltura.\n\ndef decorator(func):\n    \n    def wrapper():\n        print(\"Comenzando el proceso...\")\n        func()\n        print(\"Terminado el proceso...\")\n    \n    return wrapper()\n\n@decorator\ndef count_to_ten():\n    for i in range(10):\n        print(i+1)\n\ncount_to_ten\n\ndef print_call(func):\n    def print_funtion():\n        print(f\"La función '{func.__name__}' ha sido llamada\")\n    return print_funtion\n\n@print_call\ndef example_funtion1():\n    pass\n\n@print_call\ndef example_funtion2():\n    pass\n\n@print_call\ndef example_funtion3():\n    pass\n\n\nexample_funtion1()\nexample_funtion2()\nexample_funtion3()\n\n\"\"\"\nEjercicio extra\n\"\"\"\n\ndef call_counter(func):\n    def counter_func():\n        func.call_count += 1\n        print(f\"La función '{func.__name__}'ha sido llamada {func.call_count} veces\")\n        return func\n\n    func.call_count = 0\n    return counter_func\n\n@call_counter\ndef example_funtion4():\n    pass\n\n@call_counter\ndef example_funtion5():\n    pass\n\nexample_funtion4()\nexample_funtion4()\nexample_funtion4()\nexample_funtion5()\nexample_funtion4()\nexample_funtion5()"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/Hyromy.py",
    "content": "# funcion decoradora que recibe otra funcion como parametro\ndef decorador(funcion):\n    # crear otra funcion\n    def f():\n        print('Antes de ejecutar la función') # hacer algo antes\n        funcion() # ejecutar la funcion recibida como argumento\n        print('Después de ejecutar la función') # hacer algo después\n    \n    # retornar funcion f\n    # f = funcion decoradora + funcion recibida como argumento\n    return f\n\n# decorar la funcion saludo\n@decorador\ndef saludo():\n    print('Hola!')\n\n# ejecutar la funcion con el decorador aplicado\nsaludo()\n\nprint(\"\\n\")\n\n# ---- DIFICULTAD EXTRA ----\n\nfrom random import choice, randint\n\ndef contador(funcion):\n    # *args: argumentos posicionales variables\n    # **kwargs: diccionario de argumentos variables\n    def f(*args, **kwargs):\n        f.contador += 1\n        return funcion(*args, **kwargs)\n\n    # a la funcion le añado una propiedad contador\n    f.contador = 0\n    return f\n\n@contador\ndef sumatoria(m, M):\n    return sum(range(m, M))\n\n@contador\ndef factorial(n):\n    if n == 0:\n        return 1\n    return n * factorial(n - 1)\n\nfor _ in range(10):\n    bin_choice = choice([0, 1])\n    if bin_choice:\n        m = randint(-10, 10)\n        M = abs(m) * 2\n        print(f\"Sumatoria de {m} a {M}: {sumatoria(m, M)}\")\n    else:\n        n = randint(0, 10)\n        print(f\"Factorial de {n}: {factorial(n)}\")\n\nprint()\nprint(f\"Cantidad de sumas: {sumatoria.contador}\")\n\n# el factorial se ejecuta mas veces porque es recursivo\nprint(f\"Cantidad de factoriales: {factorial.contador}\")"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/Irenetitor.py",
    "content": "from functools import wraps\n\n#Exercise\n\ndef operator(func):\n    def wrapper(*args, **kwargs):\n        print(f\"Calling {func.__name__}...\")\n        result = func(*args, **kwargs)\n        print(\"Finished.\")\n        return result\n    return wrapper\n\n@operator\ndef add(a, b):\n    return a + b\n\nprint(add(3, 4))\n\n@operator\ndef multi(*nums):\n    if not nums:\n        return 0\n    total = 1\n    for num in nums:\n        total *= num\n    return total\n    \nprint(multi(2, 5, 7))\nprint(multi(8, 4, 1, 9))\n\n@operator\ndef greet(name: str):\n    return f\"Hi {name}, how are you today?\" \n\nprint(greet(\"Holly\"))\n\n\n#Extra Exercise\n\ndef counting_calls(func):\n    @wraps(func)\n    def wrapper(*args, **kwargs):\n        wrapper.calls += 1\n        print(f\"{func.__name__} called {wrapper.calls} times\")\n        return func(*args, **kwargs)\n    \n    wrapper.calls = 0\n    return wrapper\n\n@counting_calls\ndef ice_cream_shop(flavour):\n    print(f\"Your {flavour} ice cream is ready. Enjoy it ! :)\")\n\n\nice_cream_shop(\"Vanilla\")\nice_cream_shop(\"Chocolate\")\nice_cream_shop(\"Cream and cookies\")\n\n#Creating a different function to verify it takes its own counter\n\n@counting_calls\ndef multi_counted(*nums):\n    if not nums:\n        return 0\n    total = 1\n    for num in nums:\n        total *= num\n    return total\n    \nprint(multi_counted(2, 5, 7))\nprint(multi_counted(8, 4, 1, 9))\nprint(multi_counted(23, 45, 2))\nprint(multi_counted(3, 56, 4))"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/JesusWay69.py",
    "content": "import os, platform\n\nif (platform.platform().startswith(\"macOS\") or platform.platform().startswith(\"Linux\")):\n    os.system('clear')\nelse:\n    os.system('cls')\n\n\n\"\"\" \n* EJERCICIO:\n* Explora el concepto de \"decorador\" y muestra cómo crearlo\n* con un ejemplo genérico.\"\"\"\n\n\ndef make_title(func):#Función decoradora a la que le pasamos la función principal\n    def wrapper()->str:#Subfunción decoradora (envolvente)\n        return func().title()#La subfunción decora la función principal y la devuelve\n    return wrapper#La función decoradora devuelve la subfunción envolvente\n\ndef add_javascript(func):\n    def wrapper()->str:\n        return func() + \" y jAVasCrIpT\"\n    return wrapper\n\ndef hello_world_es()->str:#Función principal a decorar\n    return \"hOlA mUnDo\"\nhello_world_es = make_title(hello_world_es)  #Llamada a la función decoradora pasándole la función a decorar\nprint(hello_world_es)#Si llamamos a la función sin paréntesis nos devolverá sólo la referencia de la función decoradora\n                     # con su función interna y su posición en memoria\nprint(hello_world_es())#Al ponerle los paréntesis nos devuelve la función original decorada\n\n\n@make_title #Anotando antes de la función a decorar el nombre de la función decoradora precedido de @ nos ahorramos la llamada\ndef hello_python_es()->str:#Función principal a decorar\n    return \"hOLa pYThON\"\nprint(hello_python_es())\n\ndef hello_java_es()->str:#La anotación solo servirá para la primera función bajo esta, en la siguiente no se aplica\n    return \"hOLA jaVA\"\nprint(hello_java_es())\n\n\n@add_javascript#Se pueden anotar varios decoradores pero estos se aplicarán en modo FIFO\n@make_title#Este se aplica primero su decoración que formatea el texto a .title y luego el @add_javascript\n           # que añade ' y jAVasCrIpT' al texto ya formateado por @make_title pero sin decorar por este.\ndef hello_java_es_2()->str:\n    return \"hOLA jAvA\"\nprint(hello_java_es_2())\nprint()\n\n\n\"\"\" \n* DIFICULTAD EXTRA (opcional):\n* Crea un decorador que sea capaz de contabilizar cuántas veces\n* se ha llamado a una función y aplícalo a una función de tu elección.\"\"\"\n\n\ndef call_counter(fun):\n    calls=[]\n    def counter(a:int, b:int)->str:\n        calls.append(fun)\n        calls_counter = len(calls)\n        return '{:<25}'.format(fun(a, b)) + \", Llamada Nª: \" + (str(calls_counter))\n    return counter\n    \n@call_counter  \ndef my_call(a:int, b:int)->str:\n    result = a + b\n    return f\"Resultado de {a} + {b} = {result}\"\n\nprint(my_call(3, 8))\nprint(my_call(14, 9))\nprint(my_call(9, 7))\nprint(my_call(42, 4))\nprint(my_call(6, 13))\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/JheisonQuiroga.py",
    "content": "# Author: Jheison Duban Quiroga Quintero\n# Github: https://github.com/JheisonQuiroga\n\n\"\"\"/*\n * EJERCICIO:\n * Explora el concepto de \"decorador\" y muestra cómo crearlo\n * con un ejemplo genérico.\"\"\"\n\nfrom abc import ABC, abstractmethod\n\n# Creamos la interfaz o clase base\nclass Pokemon(ABC):\n    @abstractmethod\n    def get_data(self):\n        pass\n\n\n# Componente Concreto\nclass Pikachu(Pokemon):\n    def get_data(self):\n        return \"Pikachu: Tipo eléctrico\"\n    \n\n# Decorador Abstracto: Envuelve un objeto de tipo Pokemon\nclass PokemonDecorator(Pokemon):\n\n    _pokemon: Pokemon\n\n    def __init__(self, pokemon: Pokemon):\n        self._pokemon = pokemon\n\n    @property\n    def pokemon(self) -> Pokemon:\n        return self._pokemon\n    \n    def get_data(self):\n        return self._pokemon.get_data()\n    \n# Decorador Concreto: Añade responsabilidades al objeto\nclass PokemonWithMoves(PokemonDecorator):\n    def get_data(self):\n        data = self.pokemon.get_data()\n        return f\"{data}, Movimientos: Impactrueno, Cola de Hierro.\"\n\n\n\"\"\"*\n * DIFICULTAD EXTRA (opcional):\n * Crea un decorador que sea capaz de contabilizar cuántas veces\n * se ha llamado a una función y aplícalo a una función de tu elección.\n */\"\"\"\n\ndef count_calls(func):\n    count = 0\n    def wrapper(*args, **kwargs):\n        print(\"Iniciando\")\n        result = func(*args, **kwargs)\n        nonlocal count\n        count += 1\n        print(f\"La función {func.__name__} ha sido llamada {count} veces.\")\n        print(\"Finalizando\")\n        return result\n    return wrapper\n\n\n@count_calls\ndef add_numbers(n1, n2):\n    return n1 + n2\n\n\nif __name__ == \"__main__\":\n    # Creamos un Pokémon simple\n    pikachu = Pikachu()\n    print(pikachu.get_data())\n\n    # Se decora el pokémon agregandole movimientos\n    pikachu_with_moves = PokemonWithMoves(pikachu)\n    print(pikachu_with_moves.get_data())\n\n    # Extra\n\n    print(add_numbers(5, 2))\n    print(add_numbers(2, 2))\n    print(add_numbers(3, 2))\n    print(add_numbers(8, 6))\n    print(add_numbers(7, 13))"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/JuanDAW37.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el concepto de \"decorador\" y muestra cómo crearlo\n * con un ejemplo genérico. \n *\n\"\"\"\n\n# Definimos el decorador, va a redecorar la función que le pasemos\n# como argumento\ndef decorador(funcion):\n    def envoltura(nombre:str, edad:int):\n        print(f\"Yo soy {nombre} y tengo {edad}\")            \n        return funcion       \n    return envoltura\n\n# Decoramos las funciones\n@decorador\ndef imprimeLuis():\n    pass   \n\n# Decoramos las funciones\n@decorador\ndef imprimePepe():\n    pass\n\n# Decoramos las funciones\n@decorador\ndef imprimeJuan():\n    pass\n\n# Llamamos a las funciones\nimprimeLuis(\"Luis\", 34)\nimprimePepe(\"Pepe\", 40)\nimprimeJuan(\"Juan\", 30)\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\nCrea un decorador que sea capaz de contabilizar cuántas veces\nse ha llamado a una función y aplícalo a una función de tu elección.\n\"\"\"\n\n# Definimos el decorador, va a redecorar la función que le pasemos\n# como argumento\ndef decoradorContador2(funcion):\n    contador = 0  \n    def envoltura(nombre:str, edad:int):\n        nonlocal contador\n        contador += 1        \n        print(f\"Yo soy {nombre}, tengo {edad} y he llamado a la función {funcion.__name__} {contador} veces\")            \n        return funcion\n    return envoltura\n\n# Decoramos las funciones, cada función va a tener su propia instancia\n@decoradorContador2\ndef imprimeLuis2():\n    pass\n\n# Decoramos las funciones\n@decoradorContador2\ndef imprimePepe2():\n    pass\n\n# Decoramos las funciones\n@decoradorContador2\ndef imprimeJuan2():\n    pass\n\n# Llamamos a las funciones\nimprimeLuis2(\"Luis\", 34)\nimprimeLuis2(\"Luis\", 34)\nimprimePepe2(\"Pepe\", 40)\nimprimeJuan2(\"Juan\", 30)"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/LucasRebuffo.py",
    "content": "def imprimir_funcion(func):\n\n    def imprimir():\n        print(f\"La funcion {func.__name__} se llamo\")\n        return func\n\n    return imprimir\n\n\n@imprimir_funcion\ndef funcion_de_ejemplo():\n    pass\n\n\n@imprimir_funcion\ndef funcion_de_ejemplo_2():\n    pass\n\n\n@imprimir_funcion\ndef funcion_de_ejemplo_3():\n    pass\n\n\nfuncion_de_ejemplo()\nfuncion_de_ejemplo_2()\nfuncion_de_ejemplo_2()\n\n\"\"\" Extra \"\"\"\n\n\ndef contador_de_llamadas(func):\n    def counter():\n        counter.llamadas_counter += 1\n        print(f\"La funcion {func.__name__} se llamo {counter.llamadas_counter} veces\")\n        return func\n\n    counter.llamadas_counter = 0\n    return counter\n\n@contador_de_llamadas\ndef funcion_de_ejemplo_4():\n    pass\n\n@contador_de_llamadas\ndef funcion_de_ejemplo_5():\n    pass\n\nfuncion_de_ejemplo_4()\nfuncion_de_ejemplo_4()\nfuncion_de_ejemplo_4()\nfuncion_de_ejemplo_4()\n\nfuncion_de_ejemplo_5()\nfuncion_de_ejemplo_5()\nfuncion_de_ejemplo_5()\n\nfuncion_de_ejemplo_4()\nfuncion_de_ejemplo_4()\nfuncion_de_ejemplo_4()\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/LuisOlivaresJ.py",
    "content": "\"\"\"\n* Explora el concepto de \"decorador\" y muestra cómo crearlo\n* con un ejemplo genérico.\n\"\"\" \n\n#Decorator wraps a function, modifying its behavior.\n\n#Example\nimport functools\n\n\ndef do_twice(func):\n    @functools.wraps(func)  # Used to preserve information about the original function.\n    def wraper(*args, **kwargs):\n        func(*args, **kwargs)\n        return func(*args, **kwargs)\n        \n    return wraper\n\n@do_twice\ndef say_something(name):\n    print(f\"Hello, {name}!\")\n    return f\"Goodbye {name}!\"\n\n\nmsg = say_something(\"Luis\")  # Hello!\\nHello!\nprint(msg)\n\n\n\"\"\"\n * Crea un decorador que sea capaz de contabilizar cuántas veces\n * se ha llamado a una función y aplícalo a una función de tu elección.\n\"\"\"\n\ncalls_to_my_function = 0\n\ndef decorator(func):\n    def wraper():\n        global calls_to_my_function\n\n        func()\n        calls_to_my_function += 1\n        print(f\"Number of calls to my_function: {calls_to_my_function}\")\n    return wraper\n    #return func\n    \n@decorator\ndef my_function():\n    print(\"Inside my function!\")\n\nmy_function()\nmy_function()\nmy_function()"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/Nicojsuarez2.py",
    "content": "# #24 PATRONES DE DISEÑO: DECORADORES\n> #### Dificultad: Fácil | Publicación: 10/06/24 | Corrección: 17/06/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Explora el concepto de \"decorador\" y muestra cómo crearlo\n * con un ejemplo genérico.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un decorador que sea capaz de contabilizar cuántas veces\n * se ha llamado a una función y aplícalo a una función de tu elección.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/Pipe281.py",
    "content": "'''\n * EJERCICIO:\n * Explora el concepto de \"decorador\" y muestra cómo crearlo\n * con un ejemplo genérico.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un decorador que sea capaz de contabilizar cuántas veces\n * se ha llamado a una función y aplícalo a una función de tu elección.\n\n'''\ndef mi_decorador(func):\n    def envoltura():\n        print(\"Algo se está ejecutando antes de la función.\")\n        func()\n        print(\"Algo se está ejecutando después de la función.\")\n    return envoltura\n\n@mi_decorador\ndef saludar():\n    print(\"¡Hola!\")\n\nsaludar()\n\n\n'''\nDificultad extra\n'''\n\ndef call_counter(funcion):\n    def counter_function():\n        counter_function.call_count += 1\n        print(\n            f\"La función '{funcion.__name__} se ha llamado {counter_function.call_count}' vez/veces.\")\n        return funcion\n    \n    counter_function.call_count = 0\n    return counter_function\n\n\n@call_counter\ndef example_function():\n    pass\n\nexample_function()\nexample_function()\nexample_function()"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/RRcoder.py",
    "content": "\"\"\"\nEJERCICIO:\nExplora el concepto de \"decorador\" y muestra cómo crearlo\ncon un ejemplo genérico.\n\nDIFICULTAD EXTRA (opcional):\nCrea un decorador que sea capaz de contabilizar cuántas veces\nse ha llamado a una función y aplícalo a una función de tu elección.\n\"\"\"\nfrom threading import Lock\nfrom random import randint\n\n\ndef decora_string(fun_parametro):\n    \"\"\" \n    Creo un decorador que adorna funciones que retornan un string de manera aleatorea.\n    \"\"\"\n    def fun_interna():\n        ladornos=['･｡+☆+｡･ﾟ･','○+●+○+●', '+* ﾟ ゜ﾟ *+', '♥｡･ﾟ♡ﾟ･｡♥｡･', '★・・・・・・・★']\n        i= randint(0,len(ladornos)-1)\n        a= fun_parametro()\n        return ladornos[i]+a+ ladornos[i]\n    return fun_interna\n\nclass SingletonMeta(type):\n    _instancias = {}\n    _lock: Lock = Lock()\n    def __call__(cls, *args, **kwargs):\n        with cls._lock:\n            if cls not in cls._instancias:\n                instancia = super().__call__(*args, **kwargs)\n                cls._instancias[cls]= instancia\n        return cls._instancias[cls]\n\nclass ContadorSingleton(metaclass=SingletonMeta):\n    valor: int = 0 \n    def get(self):\n        return self.valor\n    def incrementar(self):\n        self.valor+=1\n    def decrementar(self):\n        self.valor-=1\n\n\ndef decorador_cuenta(fun_parametro):\n    def fun_interna(s):\n        cont=ContadorSingleton()\n        a=fun_parametro(s)\n        cont.incrementar()\n        print(\"Llamaste a la funcion {} veces.\".format(cont.get())  )\n        return a\n    return fun_interna\n\n@decora_string\ndef DameNombre():\n    return \"Juan\"\n\n@decora_string\ndef DameDia():\n    return \"Hoy es Navidad\"\n\n@decorador_cuenta\ndef DuplicaString(s):\n    return s*2\n\n\n\ndef main():\n    print(\"Hola \" + DameNombre())\n    print(DameDia())\n    print()\n    print(DameNombre())\n    print()\n    print(DuplicaString(\"CHAU\"))\n    print(DuplicaString(\"Nos Vemos!\"))\n    print(DuplicaString(\"PE\"))\n\n\nif __name__==\"__main__\":\n    main()\n\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/Sac-Corts.py",
    "content": "def print_call(function):\n    def print_function():\n        print(f\"La función '{function.__name__}' ha sido llamada.\")\n        return function\n    return print_function\n\n\n@print_call\ndef example_function():\n    pass\n\n\n@print_call\ndef example_function_2():\n    pass\n\n\n@print_call\ndef example_function_3():\n    pass\n\n\nexample_function()\nexample_function_2()\nexample_function_3()\n\n## Ejercicio Extra ##\n\ndef call_counter(function):\n    def counter_function():\n        counter_function.call_count += 1\n        print(\n            f\"La función '{function.__name__} se ha llamado {counter_function.call_count}' veces.\")\n        return function\n\n    counter_function.call_count = 0\n    return counter_function\n\n\n@call_counter\ndef example_function_4():\n    pass\n\n\n@call_counter\ndef example_function_5():\n    pass\n\n\nexample_function_4()\nexample_function_4()\nexample_function_4()\nexample_function_4()\nexample_function_5()\nexample_function_4()\nexample_function_5()"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/SooHav.py",
    "content": "# 24 PATRONES DE DISEÑO: DECORADORES\n\n# Ejercicio\n\n\"\"\"\nEstructura: Se crea una función llamada decorador que toma como argumento a otra función llamada func.\nAl interior del decorador, se crea otra función que se llama wrapper, \nque tiene como objetivo “envolver” la función func.\n\nLos argumentos de la función wrapper son *args y **kwargs, porque no se sabe que argumentos específicos\ntendran las funciones a las que se aplica el decorador. \n*args y **kwargs garantizan que el resultado del decorador va a usar esos mismos argumentos.\n\nDentro de la función wrapper se definen las acciones que vas a implementar antes o después \nde la función original.\n\"\"\"\n\n\ndef decorador(func):\n    # Definir una nueva función que \"envuelve\" la función original\n    def wrapper(*args, **kwargs):\n        # Hacer algo antes de llamar la función original\n        print(\"Se inicia el proceso...\")\n        resultado = func(*args, **kwargs)\n        # Hacer algo después de llamar la función original\n        print(\"Finaliza el proceso\")\n        return resultado\n    # Devolver la nueva función\n    return wrapper\n\n\n@decorador\ndef mi_funcion(nombre):\n    # Mi función creada\n    nombre = nombre\n    return print(f\"Hola {nombre}!\")\n\n\nmi_funcion(\"Juan\")\n\n# Extra\n\n# Ejemplo 1\n\n\ndef operacion(funcion):\n    def nueva_funcion(a, b):\n        c = funcion(a, b)\n        nueva_funcion.contador += 1\n        print(f\"Resultado número: {nueva_funcion.contador}\")\n        return c\n    nueva_funcion.contador = 0\n    return nueva_funcion\n\n\ndef redondeo_decimales(funcion):\n    def nueva_funcion(a, b):\n        c = funcion(a, b)\n        return round(c, ndigits=None)\n    return nueva_funcion\n\n\n@operacion\n@redondeo_decimales\ndef suma(a, b):\n    print(\"Funcion suma\")\n    return a + b\n\n\n@operacion\n@redondeo_decimales\ndef resta(a, b):\n    print(\"Funcion resta\")\n    return a - b\n\n\nprint(suma(5.5, 3))\nprint(suma(1, 8.2))\nprint(resta(6.1, 3))\nprint(resta(5.9, 3))\n\n# Ejemplo 2\n\n\ndef contador_llamadas(func):\n    def wrapper(*args, **kwargs):\n        wrapper.contador += 1\n        print(f\"Llamada número: {wrapper.contador}\")\n        return func(*args, **kwargs)\n    wrapper.contador = 0\n    return wrapper\n\n\n@contador_llamadas\ndef say_hello(name):\n    print(f\"Hola, {name}!\")\n\n\nsay_hello(\"SooHav\")\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/Trufoplus.py",
    "content": "###############################################################################\n###  EJERCICIO: DECORADORES\n###############################################################################\n\n### Decorador simple:\ndef my_decorator(func):\n    \"\"\"\n    Un decorador que agregar funcionalidades a tus funciones, la \n    funcion se le pasa como argumento.\n    \"\"\"\n    def wrap ():\n        \"\"\"\n        wrap significa envolver, es lo que envuelve a la funcion\n        \"\"\"\n        print(\"Inicializando la funcion...\")\n        func()\n        print(\"Terminando el tema que ya es hora...\")\n    return wrap\n\n@my_decorator #Con el @ aplico el decorador creado a la funcion\ndef my_func():\n    \"\"\"\n    Una funcion chorra para probar que el decorador funciona\n    \"\"\"\n    print(\"Esta es mi funcion que hace cosas molonas\")\n\nprint('\\nDecorador simple:')\nmy_func()\n\n\n\n### Decorador con argumentos:\ndef my_decorator_with_argument(argument):\n    \"\"\"\n    Un decorador al que se le pueden pasar argumentos\n    \"\"\"\n    def my_decorator(func):\n        def wrap():\n            print(f\"{argument}, Inicializando la funcion...\")\n            func()\n            print(\"Terminando el tema que ya es hora...\")\n        return wrap\n    return my_decorator\n\n@my_decorator_with_argument(\"Hola\") #Decorador con argumentos\ndef my_func():\n    print(\"Esta es mi funcion que hace cosas molonas\")\n\nprint('\\nDecorador con argumentos:')\nmy_func()\n\n\n\n### Decorador para funciones con argumentos\ndef my_decorator(func):\n    def wrap(*args, **kwargs):\n        print(\"Inicializando la funcion...\")\n        result = func(*args, **kwargs)\n        print(\"La funcion ha terminado\")\n        return result\n    return wrap\n\n@my_decorator \ndef my_func(a:int, b:int):\n    print(f'{a} + {b} = {a + b}')\n\n\nprint('\\nDecorador para una funcion con argumentos:')\nmy_func(4, 5)\n\n\n### Aplicando decoradores a una clase:\nclass MyClass:\n    @my_decorator\n    def method(self, value:int):\n        print(f'Su valor es {value}')\n\n\nprint('\\nAplicando un decorador a una clase:')\nobject = MyClass()\nobject.method(1980)\n\n\n\n### Aplicando varios decoradores a una misma funcion (Decoradores anidados)\ndef my_first_decorator(func):\n    def wrap():\n        print('Este es mi primer decorador: ')\n        func()\n        print('fin del primer decorador')\n    return wrap\n\ndef my_second_decorator(func):\n    def wrap():\n        print('Este es mi segundo decorador: ')\n        func()\n        print('fin del segundo decorador')\n    return wrap\n\n\n@my_first_decorator\n@my_second_decorator\ndef my_func():\n    print('Esta es mi funcion')\n\nprint('\\nUsando varios decoradores para en una funcion: ')\nmy_func()\n\n\n\n###############################################################################\n### DIFICULTAD EXTRA\n###############################################################################\ndef my_counter():\n    counts = 0\n    def decorator(func):\n        def wrap():\n            nonlocal counts\n            func()\n            counts += 1\n            if counts == 1:\n                print(f'\\t** Se ha llamado {counts} vez a la funcion **')\n            else:\n                print(f'\\t** Se ha llamado {counts} veces a la funcion **')\n        return wrap\n    return decorator\n\n@my_counter()\ndef my_func():\n    print('\\nEsta funcion hace cosas alucinantes que no puedes ver')\n\n\nmy_func()\nmy_func() \nmy_func() \nmy_func()     \n\n\n    \n\n\n        \n        \n    \n    "
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/adra-dev.py",
    "content": "\"\"\"\nEJERCICIO:\nExplora el concepto de \"decorador\" y muestra cómo crearlo con un \nejemplo genérico. \n\nDIFICULTAD EXTRA(opcional):\nCrea un decorador que sea capaz de contabilizar cuántas veces se ha \nllamado a una función y aplicalo a una función de tu elección.\n\nby adra-dev\n\"\"\"\n\n\"\"\"\nDecoradores:\nUn decorador es un modificador de un metodo o funcion que \"envuelve\"\nel codigo de dicho metodo con instrucciones adicionales. Regularmente\nvamos a hacer uso de los decoradores para extender el uso de una \nfuncion ya sea porque no podemos modificar la funcion o no es \nconveniente hacerlo.\n\nLos decoradores nos sirven para realizar tareas muy complejas y \nrepetitivas como lo son conectarse a una BD, enviar un email, \nleer un archivo excel o cualquier tarea que se necesite realizar \nantes o despues de llamar a la funcion a decorar.\n\"\"\"\n\ndef funcion_a(funcion_b):\n\n    def funcion_c():\n        print(\">>> Antes del llamado.\")\n        funcion_b()\n        print(\">>> Despues del llamado.\")\n\n    return funcion_c\n\n\n@funcion_a\ndef saludar():\n    print('Hola, nos encontramos en una fucnion') \n\nsaludar()\n\n\n\"\"\"\nExtra\n\"\"\"\n\ndef print_call_counter(function):\n    def counter_function():\n        counter_function.call_count += 1\n        print(\n            f\"La funcion '{function.__name__}' se ha llamado {counter_function.call_count} veces.\")\n        return function\n        \n    counter_function.call_count = 0\n    return counter_function\n\n\n\n@print_call_counter\ndef example_function():\n    pass\n\n\n@print_call_counter\ndef saludar():\n    print('Hola, nos encontramos en una fucnion') \n\n\nexample_function()\nsaludar()\nsaludar()\nsaludar()\nexample_function()\nsaludar()\nsaludar()"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/agusrosero.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Explora el concepto de \"decorador\" y muestra cómo crearlo\n * con un ejemplo genérico.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un decorador que sea capaz de contabilizar cuántas veces\n * se ha llamado a una función y aplícalo a una función de tu elección.\n */\n\"\"\"\n# EJERCICIO:\n\n\ndef mi_decorador(fn):\n    def wrapper(*args, **kwargs):\n        print(\"Mi decorador...\")\n        return fn(*args, **kwargs)\n    return wrapper\n\n\n@mi_decorador\ndef suma(a, b):\n    return a + b\n\n\nprint(suma(10, 20))\n\n# DIFICULTAD EXTRA:\n\n\ndef counter(fn):\n    def wrapper(*args, **kwargs):\n        wrapper.count += 1\n        return fn(*args, **kwargs)\n    wrapper.count = 0\n    return wrapper\n\n\n@counter\ndef resta():\n    return 10 - 5\n\n\nresta()\nresta()\nresta()\nprint(resta.count)\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/alanshakir.py",
    "content": "\"\"\"\"\n/*\n * EJERCICIO:\n * Explora el concepto de \"decorador\" y muestra cómo crearlo\n * con un ejemplo genérico.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un decorador que sea capaz de contabilizar cuántas veces\n * se ha llamado a una función y aplícalo a una función de tu elección.\n */\n\"\"\"\n\ndef mi_decorador(funcion):    \n    def nueva_funcion(a, b):\n        print(\"se va a llamar\")\n        c = funcion(a, b)\n        print(\"se ha llamado\")\n        return c    \n    return nueva_funcion\n    \n@mi_decorador\ndef suma(a, b):\n    print(f\"La Suma de {a} + {b} es igual a: \", a + b)\n\nsuma(5,8)\nsuma(9,8)\n\n#Extra\n\ndef call_dec(funcion):\n    def count_dec(a ,b):\n        count_dec.call_deco += 1\n        c = funcion(a, b)\n        print(f\"la funcion {funcion.__name__} se ha contabilizado {count_dec.call_deco} veces\")\n        return funcion\n    count_dec.call_deco = 0\n    return count_dec\n\n@call_dec\ndef suma(a, b):\n    print(f\"La Suma de {a} + {b} es igual a: \", a + b)\n\n@call_dec\ndef resta(a, b):\n    print(f\"La Suma de {a} - {b} es igual a: \", a - b)\n\n@call_dec\ndef mutiplica(a, b):\n    print(f\"La Suma de {a} * {b} es igual a: \", a * b)\n\nsuma(8,5)\nsuma(8,9)\nsuma(8,65)\nresta(9,8)\nresta(10,8)\nmutiplica(2,5)\nmutiplica(2,9)\nmutiplica(58,5)\nmutiplica(8,2)\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/avcenal.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el concepto de \"decorador\" y muestra cómo crearlo\n * con un ejemplo genérico.\n\"\"\"\n\nfrom functools import reduce\n\ndef decorador(funcion):\n    def nueva_funcion(*args):\n        print(\"Se va a llamar\")\n        c = funcion(*args)\n        print(\"Se ha llamado\")\n        return c\n    return nueva_funcion\n\n#@decorador\ndef suma (*args:int):\n    print(\"Entra en suma\")\n    return reduce(lambda x,y:x+y,[*args])\n\n#print(f\"El resultado de la suma es: {suma (7,9,3,1,2)}\")\n\n@decorador\ndef resta(*args:int):\n    print(\"Entra en la resta\")\n    return reduce(lambda x,y:x-y,[*args])\n\nprint(f\"El resultado de la resta es: {resta(7,3)}\")\n\nfuncion_decorada = decorador(suma)\nfuncion_decorada(3,5,7)\n\n\"\"\"DIFICULTAD EXTRA (opcional):\n * Crea un decorador que sea capaz de contabilizar cuántas veces\n * se ha llamado a una función y aplícalo a una función de tu elección.\n\"\"\"\ndef count_decorator(function):\n    def original_function(*args:int):\n        original_function.count += 1\n        print(f\"La función {function.__name__} se ha llamado {original_function.count} vez/veces\")\n        return function(*args)\n\n    original_function.count = 0 #es una variable que declaro para la función original_function llamada count\n    return original_function\n#el decorador es capaz de diferenciar entre funciones a las que llama\n#genera un ámbito de ejecución para la misma función que se ejecuta\n#la instancia de \"multiplicar\" es diferente de otras funciones como \"suma_2\"\n\n@count_decorator\ndef multiplicar(*args:int):\n    return reduce(lambda x,y: x*y,[*args])\n\n@count_decorator\ndef suma_2(*args:int):\n    return reduce(lambda x,y: x+y,[*args])\n\nprint(multiplicar(3,2))\nprint(multiplicar(4,2))\nprint(multiplicar(5,2))\nprint(suma_2(3,8))\nprint(suma_2(9,1,5))\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/barrancus.py",
    "content": "#24 - Python - Patrones de Diseño - Decoradores\n# EJERCICIO:\n# Explora el concepto de \"decorador\" y muestra cómo crearlo\n# con un ejemplo genérico.\n# \n# DIFICULTAD EXTRA (opcional):\n# Crea un decorador que sea capaz de contabilizar cuántas veces\n# se ha llamado a una función y aplícalo a una función de tu elección.\n# \nclass Counter:\n    def __iter__(self):\n        self.a = 1\n        return self\n    \n    def __next__(self):\n        x = self.a\n        self.a += 1\n        return x\n\ndef serparacion(cadena) -> str:\n    global contador\n    print(f'\\nEjercicio {next(contador)}. {cadena * 20}')\n\ncontador = iter(Counter())\n\ndef my_decorator(func):\n    \"\"\"Decorador propio\"\"\"\n    def print_pre_post(*args, **kwargs):\n        print('Comenzamos la ejecución.\\n')\n        func(*args, **kwargs)\n        print('\\nFinalizamos la ejecución.')\n    return print_pre_post\n\ndef call_counter(func):\n    \"\"\"Decorador que cuenta las llamadas a una función.\"\"\"\n    def wrapper(*args, **kwargs):\n        wrapper.calls += 1\n        print(f'La función \"{func.__name__}\" ha sido llamada {wrapper.calls} veces.')\n        return func(*args, **kwargs)\n    wrapper.calls = 0\n    return wrapper\n\n@call_counter\ndef greet(name):\n    \"\"\"Función que saluda a una persona.\"\"\"\n    print(f'Hola, {name}!')\n\n@my_decorator\ndef calculator(x: int, y: int) -> None:\n    \"\"\"Función que ejecuta varias operaciones aritméticas.\"\"\"\n    print(f'Núm1  | OP | Núm2 |   | Result')\n    print(f'{\"-\"*35}')\n    print(f'{x:<5} | +  | {y:<5}  =   {x+y:6<.2f}')\n    print(f'{\"-\"*35}')\n    print(f'{x:<5} | -  | {y:<5}  =   {x-y:6<.2f}')\n    print(f'{\"-\"*35}')\n    print(f'{x:<5} | *  | {y:<5}  =   {x*y:6<.2f}')\n    print(f'{\"-\"*35}')\n    print(f'{x:<5} | /  | {y:<5}  =   {x/y:6<.2f}')\n    print(f'{\"-\"*35}')\n    print(f'{x:<5} | // | {y:<5}  =   {x//y:6<.2f}')\n    print(f'{\"-\"*35}')\n    print(f'{x:<5} | %  | {y:<5}  =   {x%y:6<.2f}')\n    print(f'{\"-\"*35}')\n\ndef main():\n    serparacion('-:-')\n    calculator(20, 7)\n    serparacion('-:-')\n    greet('Alice')\n    greet('Bob')\n    greet('Charlie')\n    greet('Diana')\n    greet('Eve')\n    \nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/bytecodesky.py",
    "content": "#Angel Barre | Bytecodesky\n#Este codigo para el reto de programacion #24 fue realizado en python usando decoradores, en pocas palabras un decorador es una funcion que recibe otra funcion y retorna una nueva funcion, en este caso el decorador recibe una funcion y retorna la misma funcion, pero antes de retornarla incrementa una variable global llamada contador, la cual se incrementa cada vez que se llama a la funcion decorada, de esta manera se lleva un conteo de cuantas veces se ha llamado a la funcion decorada.\n\ndef contarfunciones(function):\n    def wrapper(*args, **kwargs):\n        return function(*args, **kwargs)\n\n    return wrapper\n\ncontador = 0\n@contarfunciones\ndef foo():\n    global contador\n    contador += 1\n    return contador\nprint(foo())"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/cristianfloyd.py",
    "content": "# EJERCICIO:\n# Explora el concepto de \"decorador\" y muestra cómo crearlo\n# con un ejemplo genérico.\nfrom functools import wraps\nfrom typing import Callable, Any\n\ndef mi_decorador(funcion_original):\n    def nueva_funcionalidad():\n        print(\"Estoy antes de la ejecución de la función original\")\n        funcion_original()\n        print(\"Estoy después de la ejecución de la función original\")\n\n    return nueva_funcionalidad\n\n\n@mi_decorador\ndef funcion_original():\n    print(\"\\tEstoy dentro de la función original\")\n\n\n@mi_decorador\ndef funcion_original_2():\n    print(\"\\tEstoy dentro de la función original 2\")\n\n\n@mi_decorador\ndef funcion_original_3():\n    print(\"\\tEstoy dentro de la función original 3\")\n\n\nfuncion_original()\nfuncion_original_2()\nfuncion_original_3()\n\n\n#\n# DIFICULTAD EXTRA (opcional):\n# Crea un decorador que sea capaz de contabilizar cuántas veces\n# se ha llamado a una función y aplícalo a una función de tu elección.\n\n\n\n\nclass ContadorDeLlamadas:\n    \"\"\"\n    Decorador que cuenta cuantas veces se ha llamado a una funcion.\n    \"\"\"\n    def __init__(self, funcion: Callable[..., Any]) -> None:\n        wraps(funcion)(self)\n        self.funcion = funcion\n        self.contador: int = 0\n        \n    def __call__(self, *args: Any, **kwds: Any) -> Any:\n        self.contador += 1\n        print(f\"Llamada #{self.contador} a '{self.funcion.__name__}'\")\n        return self.funcion(*args, **kwds)\n        \n\n@ContadorDeLlamadas\ndef saludar(nombre: str) -> None:\n    print(f\"Hola, {nombre}!\")\n\n@ContadorDeLlamadas\ndef multiplicar(a: int, b: int) -> int:\n    return a * b\n\n\nprint(\"-\" * 100)\nprint(\"Testeando el decorador contador de llamadas\")\nprint(\"-\" * 100)\nsaludar(\"Cristian\")\nsaludar(\"Floyd\")\nsaludar(\"Cristian\")\n\nprint(f\"Total de llamadas: {saludar.contador}\")\n\nprint(\"-\" * 100)\nprint(\"Testeando el decorador contador de llamadas con una funcion que retorna un valor\")\nprint(\"-\" * 100)\nprint(f\"Resultado de la multiplicacion de 2 y 3: {multiplicar(2, 3)}\")\nprint(f\"Resultado de la multiplicacion de 4 y 5: {multiplicar(4, 5)}\")\nprint(f\"Total de llamadas: {multiplicar.contador}\")"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/cyberdidac.py",
    "content": "def count_calls(func):\n    def wrapper():\n        wrapper.count += 1\n        print(f\"La función {func.__name__} ha sido llamada {wrapper.count} veces\")\n        return func()\n\n    wrapper.count = 0\n    return wrapper\n\n\n@count_calls\ndef say_hello():\n    print(\"Hola!\")\n\n\ndef main():\n    say_hello()\n    say_hello()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/davidrguez98.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Explora el concepto de \"decorador\" y muestra cómo crearlo\n * con un ejemplo genérico.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un decorador que sea capaz de contabilizar cuántas veces\n * se ha llamado a una función y aplícalo a una función de tu elección.\n */ \"\"\"\n\n#EJERCICIO\n\ndef print_call(function):\n    def print_function():\n        print(f\"La función {function.__name__} ha sido llamada.\")\n        return function\n    return print_function\n\n@print_call\ndef example_function():\n    pass\n\n@print_call\ndef example_function2():\n    pass\n\n@print_call\ndef example_function3():\n    pass\n\nexample_function()\nexample_function2()\nexample_function3()\n\n#DIFICULTAD EXTRA\n\ndef function_call(function):\n    def function_counter():\n        function_counter.function_call += 1\n        print(f\"La función {function.__name__} ha sido llamada {function_counter.function_call} veces.\")\n        return function\n    \n    function_counter.function_call = 0\n    return function_counter\n\n\n@function_call\ndef example_function4():\n    pass\n\n@function_call\ndef example_function5():\n    pass\n\nexample_function4()\nexample_function4()\nexample_function4()\nexample_function5()"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/duendeintemporal.py",
    "content": "#24 { Retos para Programadores } PATRONES DE DIESEÑO: DECORADORES \n\n# Bibliography reference\n# I use GPT as a reference and sometimes to correct or generate proper comments.\n\n\"\"\"  \n* EJERCICIO:\n * Explora el concepto de \"decorador\" y muestra cómo crearlo\n * con un ejemplo genérico.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un decorador que sea capaz de contabilizar cuántas veces\n * se ha llamado a una función y aplícalo a una función de tu elección.\n\n\"\"\"\n\nlog = print\nlog('Retos para Programadores #24')\n\n# The decorator pattern is a structural design pattern that allows behavior to be added\n# to individual objects, either statically or dynamically, without affecting the behavior\n# of other objects from the same class. In Python, decorators are implemented using\n# higher-order functions.\n\nimport time\nimport functools\n\n# Generic decorator function\ndef decorator(fn):\n    @functools.wraps(fn)\n    def wrapper(*args, **kwargs):\n        print(\"Before calling the function\")\n        result = fn(*args, **kwargs)\n        print(\"After calling the function\")\n        return result\n    return wrapper\n\n# Decorator to log execution time\ndef log_execution_time(fn):\n    @functools.wraps(fn)\n    async def wrapper(*args, **kwargs):\n        start = time.time()  # Start time\n        result = await fn(*args, **kwargs)\n        end = time.time()  # End time\n        print(f\"Execution time for {fn.__name__}: {(end - start) * 1000:.2f} milliseconds\")\n        return result\n    return wrapper\n\n# Example function that simulates a time-consuming task\nasync def fetch_data():\n    await asyncio.sleep(3)  # Simulate a delay of 3 seconds\n    return \"Data fetched!\"\n\n# Decorated function\nlogged_fetch_data = log_execution_time(fetch_data)\n\n# Using the decorated function\nimport asyncio\n\nasync def main():\n    result = await logged_fetch_data()\n    print(result)  # Data fetched!\n    \n\n# Run the main function\nasyncio.run(main()) # Data fetched!\n    # Execution time for fetch_data: 3008.05 milliseconds\n\n# EXTRA DIFFICULTY EXERCISE\n\n# Decorator to count function calls\ndef count_calls(fn):\n    call_count = 0  # Private variable to keep track of calls through closure\n\n    @functools.wraps(fn)\n    def wrapper(*args, **kwargs):\n        nonlocal call_count\n        call_count += 1\n        print(f\"Function has been called {call_count} times.\")\n        return fn(*args, **kwargs)\n    return wrapper\n\n# Original function\n@count_calls\ndef hi_girl():\n    print('Hi Girl! 🌹')\n    return '🌼'\n\n# Using the decorated function\nprint(hi_girl())  # Function has been called 1 times. Hi Girl! 🌹\nprint(hi_girl())  # Function has been called 2 times. Hi Girl! 🌹\nprint(hi_girl())  # Function has been called 3 times. Hi Girl! 🌹\n\n# Trying to access hi_girl directly will not result in an error, but the call count will still be tracked.\n\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/edalmava.py",
    "content": "def decorador(funcion):\n    def wrapper(*a, **b):\n        print(\"La función no se ha llamado\")\n        funcion(*a, **b)\n        print(\"La función ha sido llamada\")\n        return \n    return wrapper\n       \n@decorador\ndef funcion(a, b):\n    pass\n\nfuncion(1, 2)\n        \nprint(\"\")\nprint(\"***RETO EXTRA***\")\nprint(\"\")\n\ndef contar(funcion):\n    def wrapper(*a):\n        wrapper.contador += 1\n        funcion(*a)\n        veces = 'vez' if wrapper.contador == 1 else 'veces'\n        print(f\"La función ha sido llamada { wrapper.contador } { veces }\")\n        \n    wrapper.contador = 0\n    return wrapper\n\n@contar\ndef sumar(a, b):\n    return a + b\n\nsumar(1, 2)\nsumar(3, 4)\nsumar(5, 6)\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/fborjalv.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Explora el concepto de \"decorador\" y muestra cómo crearlo\n * con un ejemplo genérico.\n\n\"\"\"\n\ndef decorator_operations(function):\n    def show_name(*args):\n        print(f\"Estás utilizando la función {function.__name__}:\")\n        return function(*args)\n    return show_name\n\n\n@decorator_operations\ndef sumar(a, b):\n    print(f\"{a} + {b} = {a+b}\") \n\ndef resta(a, b):\n    print(f\"{a} - {b} = {a-b}\")  \n\ndef multiplica(a, b):\n    print(f\"{a} x {b} = {a*b}\") \n\nsumar(2, 4)\nresta(2, 4)\nmultiplica(2, 4)\n\n\"\"\"\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un decorador que sea capaz de contabilizar cuántas veces\n * se ha llamado a una función y aplícalo a una función de tu elección.\n */\n\n\"\"\"\n\n\ndef func_counter(function):\n    \n    def counter(*args):\n        counter.call_counter +=1\n        print(f\"La función {function.__name__} se ha ejecutado {counter.call_counter} veces\")\n        return function(*args)\n    counter.call_counter = 0\n    return counter\n\n\n@func_counter\ndef saludo(name):\n    print(f\"Hola, {name} ¿Cómo estás?\")\n\n\nfor name in [\"Brais\", \"Borja\", \"Sonia\"]:\n    saludo(name)\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/franxiscodev.py",
    "content": "'''\nPatrones de diseño\nDECORADORES - decorator - wrapper\nExtender la funcionalidad de una función sin modificar la original\n'''\n\n\ndef print_call(function):\n    def print_function():\n        print(f\"La función *{function.__name__}* ha sido llamada \")\n        return function\n    return print_function\n\n\n@print_call\ndef example_function_1():\n    # print(\"La función example_function ha sido llamada interna\")\n    pass\n\n\ndef example_function_2():\n    # print(\"La función example_function_2 ha sido llamada\")\n    pass\n\n\ndef example_function_3():\n    # print(\"La función example_function_3 ha sido llamada\")\n    pass\n\n\nexample_function_1()\nexample_function_2()\nexample_function_3()\n'''\nExtra\ndecorator crea una instancia única por eso al volver a llamarlo no se reinicia la variable\n'''\n\n\ndef call_counter(function):\n    def counter_function():\n        counter_function.call_count += 1\n        print(\n            f\"La función *{function.__name__}* se ha llamado {counter_function.call_count} veces \")\n        return function\n\n    counter_function.call_count = 0\n    return counter_function\n\n\n@call_counter\ndef example_function_4():\n    pass\n\n\n@call_counter\ndef example_function_5():\n    pass\n\n\nexample_function_4()\nexample_function_4()\nexample_function_4()\nexample_function_5()\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/ggilperez.py",
    "content": "# Decorators\n\ndef my_decorator(func):\n    print(\"inside my_decorator\")\n\n    def wrapper(*args, **kwargs):\n        print(\"inside wrapper - before func\")\n        result = func(*args, **kwargs)\n        print(\"inside wrapper - after func\")\n        return result\n\n    return wrapper\n\n\n@my_decorator\ndef my_func(*args, **kwargs):\n    print(\"inside my_func\")\n    print(args, kwargs)\n\nmy_func(1, 2, three=3)\n\n# EXTRA\n\ndef call_count(func):\n    def wrapper(*args, **kwargs):\n        wrapper.calls += 1\n        print(f\"Function {func.__name__} called {wrapper.calls} times.\")\n        return func(*args, **kwargs)\n\n    wrapper.calls = 0\n    return wrapper\n\n@call_count\ndef sum(num1, num2):\n    return num1 + num2\n\n@call_count\ndef mult(num1, num2):\n    return num1 * num2\n\nsum(1,2)\nsum(2,3)\nsum(3,4)\nmult(5,6)\nsum(8,9)\nsum(1,5)\nmult(2,6)"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/gringoam.py",
    "content": "\"\"\"\nEjercicio\n\"\"\"\n\n\ndef funcion_decoradora(func):\n    def imprime_func():\n        print(f\"Se imrime {func.__name__}\")\n        return func\n    return imprime_func\n\n\n\n\n@funcion_decoradora\ndef funcion1():\n    print(\"se imprime  primero\")\n\n@funcion_decoradora\ndef funcion2():\n    pass\n\nfuncion1()\nfuncion2()\n\n\"\"\"\nExtra\n\"\"\"\n\ndef contador_llamado(func):\n    \n    def llamados():\n        llamados.llamado+=1\n        print(f\"La funcion {func.__name__} se llamo {llamados.llamado}\")\n        return func\n    llamados.llamado=0\n    return llamados\n\n@contador_llamado\ndef funcion3():\n    pass\n\n@contador_llamado\ndef funcion4():\n    pass\n\nfuncion4()\nfuncion3()\nfuncion4()"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/hectorio23.py",
    "content": "#!/usr/bin/python3.11\n# Autor: Héctor Adán\n# GitHub: https://github.com/hectorio23 \n\n'''\nEJERCICIO:\nExplora el concepto de \"decorador\" y muestra cómo crearlo\ncon un ejemplo genérico.\n\nDIFICULTAD EXTRA \nCrea un decorador que sea capaz de contabilizar cuántas veces\nse ha llamado a una función y aplícalo a una función de tu elección.\n'''\n\ndef custom_decorator(func):\n    def envoltura():\n        print(\"Algo se está haciendo antes de llamar a la función\")\n        func()\n        print(\"Algo se está haciendo después de llamar a la función\")\n    return envoltura\n\n@custom_decorator\ndef do_something():\n    print(\"Esta es mi función\")\n\ndo_something()\n\n\ndef counter(func):\n    def container(*args, **kwargs):\n        container.llamadas += 1\n        print(f\"Se ha llamado a {func.__name__} {container.llamadas} veces\")\n        return func(*args, **kwargs)\n    container.llamadas = 0\n    return container\n\n@counter\ndef saludar():\n    print(\"¡Hola Mundo!\")\n\nsaludar()\nsaludar()\nsaludar()\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/idiegorojas.py",
    "content": "\"\"\"\n24 - Patrones de Diseño: Decoradores\n\"\"\"\n# Es un patron estructural que permite agregar funcionalidad a un objeto \n# No modifica la estrucura original del objeto\n# Se usa para extender el comportamiento de clases sin usar herencia\n\n\n\"\"\"\nEstructura basica\n\"\"\"\n# Componente base: La funcionalidad basica que se desea extender\n# Decorador: Funcion o clase que toma un componente y le añade nuevas funcionalidades\n# Uso del decorador: Se aplica a un objeto, una funcion o metodo para modificar su comportamiento\n\n\n\"\"\"\nEjemplo:\n\"\"\"\n\n# Cafeteria\n# Tenemos una cafetería donde vendemos café. Un café básico cuesta $2, pero los clientes pueden agregar extras como leche, azúcar o canela.\n\nclass Cafe:\n    def costo(self):\n        return 2 # Precio base del cafe\n    \n    def descripcion(self):\n        return 'Cafe basico'\n    \nclass Leche:\n    def __init__(self, cafe) -> None:\n        self.cafe = cafe\n\n    def costo(self):\n        return self.cafe.costo() + 0.5 \n    \n    def descripcion(self):\n        return self.cafe.descripcion() + ' con leche'\n\nclass Azucar:\n    def __init__(self, cafe) -> None:\n        self.cafe = cafe\n\n    def costo(self):\n        return self.cafe.costo() + 0.2\n    \n    def descripcion(self):\n        return self.cafe.descripcion() + ' con azucar'\n    \n\n# Cafe basico\ncafe_basico = Cafe()\nprint(f'El cafe que pediste es: {cafe_basico.descripcion()} y tiene un costo de: ${cafe_basico.costo()}')\n\n# Cafe con leche\ncafe_leche = Leche(cafe_basico)\nprint(f'El cafe que pediste es: {cafe_leche.descripcion()} y tiene un costo de: ${cafe_leche.costo()}')\n\n# Cafe con leche y azucar\ncafe_leche_azucar = Azucar(cafe_leche)\nprint(f'El cafe que pediste es: {cafe_leche_azucar.descripcion()} y tiene un costo de: ${cafe_leche_azucar.costo()}')\n\n\"\"\"\n¿Cuándo usar el patrón decorador?\n\"\"\"\n# Cuando queremos extender funcionalidades sin modificar el código original.\n# Para modularizar y reutilizar código fácilmente.\n# Cuando necesitamos aplicar múltiples comportamientos dinámicos (Ej: logging, permisos, validaciones, caching).\n\n\"\"\"\nExtra\n\"\"\"\n\ndef call_counter(function):\n    def counter_function():\n        counter_function.call_count += 1\n        print(\n            f\"La función '{function.__name__} se ha llamado {counter_function.call_count}' veces.\")\n        return function\n\n    counter_function.call_count = 0\n    return counter_function\n\n\n@call_counter\ndef example_function_1():\n    pass\n\n\n@call_counter\ndef example_function_2():\n    pass\n\n\nexample_function_1()\nexample_function_1()\nexample_function_1()\nexample_function_2()\nexample_function_1()\nexample_function_2()\nexample_function_2()"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/ignaciovihe.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el concepto de \"decorador\" y muestra cómo crearlo\n * con un ejemplo genérico.\n\"\"\"\nimport time\n\n# Decorador para medir el tiempo de ejecución de la funcion que decore.\ndef measure_time(funcion):                  # Se crea una funcion externa a la que le pasamos la funcion.  \n    def wrapper(*args, **kwargs):      # Definimos una nueva fucnion que sera la que sustituya a la original, añadiendo nueva fucnionalidad. Aqui pasamos los parametros.\n        inicio = time.perf_counter()\n        funcion(*args, **kwargs)            # dentro llamamos a la funcion.\n        fin = time.perf_counter()  \n        print(f\"\\nTiempo total de ejecución de la funcion '{funcion.__name__}': {fin - inicio:.10f} segundos\")\n    return wrapper                     # retornamos la nueva funcion\n\n@measure_time                               # Con esto le decimos que hay una funcion decaradora. Para entenderlo facil: cambia la funcion que decora por la interna del decorador.\ndef saludar(name):                          # la cual contiene la funcion que se la pasamos como parametro.\n    print(f\"hola {name}\")\n\n@measure_time                               # podemos decorar varias funciones con el mismo decorador.\ndef sumar(num1, num2):\n    print(f\"{num1} + {num2} = {num1 + num2}\")\n\nsaludar(\"Pedro\")\nsumar(4, 8)\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un decorador que sea capaz de contabilizar cuántas veces\n * se ha llamado a una función y aplícalo a una función de tu elección.\n\"\"\"\n\ndef count_calls(function):\n    def wrapper(*args, **kwargs):\n        function(*args, **kwargs)\n        wrapper.counter += 1\n        print(f\"La funcion {function.__name__} se ha llamado {wrapper.counter} veces.\")\n    wrapper.counter = 0\n    return wrapper\n\n@count_calls\ndef saludar(name):\n    print(f\"hola {name}\")\n\n@count_calls                               \ndef sumar(num1, num2):\n    print(f\"{num1} + {num2} = {num1 + num2}\")\n\nsaludar(\"Ignacio\")\nsaludar(\"Lorena\")\nsumar(2,8)\nsumar(2,8)\nsaludar(\"Pedro\")\n\n\n\"\"\"\nEstudio extra patrón decorator con clases (https://refactoring.guru/)\n\"\"\"\nprint(\"-------------------decorador con clases----------------------\")\n\nclass Notificador:\n    def enviar(self, mensaje: str):\n        pass\n\nclass NotificadorEmail(Notificador):\n    def enviar(self, mensaje: str):\n        print(f\"Enviando notificación por correo: {mensaje}\")\n\n\nclass NotificadorDecorator(Notificador):\n    def __init__(self, notificador: Notificador):\n        self._notificador = notificador\n\n    @property\n    def notificador(self) -> Notificador:\n        return self._notificador\n\n    def enviar(self, mensaje: str):\n        self._notificador.enviar(mensaje)\n\nclass NotificadorSMS(NotificadorDecorator):\n    def enviar(self, mensaje: str):\n        self.notificador.enviar(mensaje)\n        print(f\"Enviando notificación por SMS: {mensaje}\")\n\n\nclass NotificadorSlack(NotificadorDecorator):\n    def enviar(self, mensaje: str):\n        self.notificador.enviar(mensaje)\n        print(f\"Enviando notificación por Slack: {mensaje}\")\n\n\nif __name__ == \"__main__\":\n    notificador_base = NotificadorEmail()\n    \n    notificador_con_sms = NotificadorSMS(notificador_base)\n    notificador_con_slack_y_sms = NotificadorSlack(notificador_con_sms)\n\n    notificador_con_slack_y_sms.enviar(\"¡Hola! Esto es un mensaje importante.\")\n\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/isilanes.py",
    "content": "def verbose(func: callable) -> callable:\n\n    def wrapper(*args, **kwargs):\n        print(f\"Llamamos a {func.__name__}() con argumentos: {args} y {kwargs}\")\n\n        return func(*args, **kwargs)\n\n    # Hacemos esto para preservar el nombre de la función decorada, si se usan múltiples decoradores:\n    wrapper.__name__ = func.__name__\n\n    return wrapper\n\n\n@verbose\ndef suma(a: int, b: int) -> int:\n    return a + b\n\n\n@verbose\ndef resta(a: int, b: int) -> int:\n    return a - b\n\n\ndef count(func: callable) -> callable:\n\n    def wrapper(*args, **kwargs):\n        c = getattr(func, \"count\", 0)\n        func.count = c + 1\n\n        x = func(*args, **kwargs)\n\n        print(f\"Veces que se ha llamado a {func.__name__}(): {func.count}\")\n\n        return x\n\n    # Hacemos esto para preservar el nombre de la función decorada, si se usan múltiples decoradores:\n    wrapper.__name__ = func.__name__\n\n    return wrapper\n\n\n@count\ndef print_good_morning() -> None:\n    print(\"Buenos días\")\n\n\n@count\ndef print_good_afternoon() -> None:\n    print(\"Buenas tardes\")\n\n\n@count\n@verbose\ndef print_good_night() -> None:\n    print(\"Buenas noches\")\n\n\n@verbose\n@count\ndef print_good_bye() -> None:\n    print(\"Que te den\")\n\n\ndef main():\n    print(\"===== MAIN =====\")\n\n    print(suma(1, 2))\n    print(suma(a=1, b=3))\n    print(resta(1, 2))\n\n\ndef extra():\n    print(\"\\n===== EXTRA =====\")\n    print_good_morning()\n    print_good_morning()\n    print_good_morning()\n    print_good_afternoon()\n\n    print(\"\\nLos decoradores se pueden componer, como con esta función que hemos decorado con @count y @verbose:\")\n    print_good_night()\n    print_good_night()\n    print_good_night()\n\n    print(\"\\nEn este caso, nuestros decoradores tienen la propiedad conmutativa (no siempre es el caso):\")\n    print(\"(print_good_bye() se ha decorado primero con @verbose y luego con @count)\")\n    print_good_bye()\n    print_good_bye()\n\n    print(\"\\nLos decoradores también se pueden usar on-the-fly, sin tener que definir la función con ellos.\")\n    print(\"Por ejemplo, podemos aplicar @verbose a print_good_afternoon(), que ya usa @count de por sí:\")\n    print(\"(Notablemente, en este caso la cuenta sigue, porque hemos decorado la función que ya estaba decorada con @count)\")\n    f = verbose(print_good_afternoon)\n    f()\n    f()\n    f()\n\n    print(\"\\nO podemos aplicar @count y @verbose a una función que no usaba decoradores:\")\n\n    def naked():\n        print(\"Soy una función definida sin decoradores\")\n\n    f = count(verbose(naked))\n    f()\n\n\nif __name__ == \"__main__\":\n    main()\n    extra()\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/juanmax2.py",
    "content": "\n\"\"\"\nEjercicio\n\"\"\"\ndef print_call(func):\n    \n    def print_function():\n        print(f\"La función {func.__name__} ha sido llamada\")\n        return func\n    return print_function\n\n@print_call\ndef example_function():\n    pass\n\n@print_call\ndef example_function_1():\n    pass\n\n@print_call\ndef example_function_2():\n    pass\n\nexample_function()\nexample_function_1()\nexample_function_2()\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un decorador que sea capaz de contabilizar cuántas veces\n * se ha llamado a una función y aplícalo a una función de tu elección.\n\"\"\"\n\ndef count_func(func):\n    \n    def contador():\n        contador.count_func += 1\n        print(f\"La funcion {func.__name__} se ha llamado {contador.count_func} veces\")\n        return func\n    contador.count_func = 0\n    return contador\n\n@count_func\ndef example_function_3():\n    pass\n\n@count_func\ndef example_function_4():\n    pass\n\nexample_function_3()\nexample_function_3()\nexample_function_3()\nexample_function_4()\nexample_function_3()\nexample_function_4()"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/juanppdev.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el concepto de \"decorador\" y muestra cómo crearlo\n * con un ejemplo genérico.\n\"\"\"\n\n# Los decoradores en Python son una forma de modificar el comportamiento de una función o método. \n# Son muy útiles para añadir funcionalidades adicionales de manera concisa y reutilizable.\n\n# Definimos el decorador\ndef mi_decorador(func):\n    def envoltura(*args, **kwargs):\n        print(\"Algo se está haciendo antes de llamar a la función\")\n        resultado = func(*args, **kwargs)\n        print(\"Algo se está haciendo después de llamar a la función\")\n        return resultado\n    return envoltura\n\n# Usamos el decorador en una función\n@mi_decorador\ndef saludar(nombre):\n    print(f\"Hola, {nombre}!\")\n\n# Llamamos a la función decorada\nsaludar(\"Mundo\")\n\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un decorador que sea capaz de contabilizar cuántas veces\n * se ha llamado a una función y aplícalo a una función de tu elección.\n\"\"\"\n\n# Definimos el decorador\ndef contador_llamadas(func):\n    def envoltura(*args, **kwargs):\n        envoltura.contador += 1\n        print(f\"La función {func.__name__} ha sido llamada {envoltura.contador} veces\")\n        return func(*args, **kwargs)\n    envoltura.contador = 0\n    return envoltura\n\n# Usamos el decorador en una función\n@contador_llamadas\ndef saludar(nombre):\n    print(f\"Hola, {nombre}!\")\n\n# Llamamos a la función decorada varias veces\nsaludar(\"Mundo\")\nsaludar(\"Python\")\nsaludar(\"Decoradores\")\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/kenysdev.py",
    "content": "# ╔═════════════════════════════════════╗\n# ║ Autor:  Kenys Alvarado              ║\n# ║ GitHub: https://github.com/Kenysdev ║\n# ║ 2024 -  Python                      ║\n# ╚═════════════════════════════════════╝\n\n# -----------------------------------\n# * DECORADORES\n# -----------------------------------\n# Mas info: https://geekflare.com/es/python-decorators/\n\n\"\"\"\n* EJERCICIO #1:\n* Explora el concepto de \"decorador\" y muestra cómo crearlo\n* con un ejemplo genérico.\n\"\"\"\nprint(\"EJERCICIO #1:\")\n\n# ______________________\n# Decorando una funcion:\n\ndef my_decorator(func):\n    # *args para manejar un número variable de argumentos posicionales.\n    # **kwargs para argumentos de palabras clave.\n    def wrapper(*args, **kwargs):\n        print(\"\\nAntes de que se llame a la función.\")\n        func(*args, **kwargs)\n        print(\"Despues de llamarla\")\n    return wrapper\n\n@my_decorator\ndef say_hello(first_name: str, last_name: str):\n    print(f\"Hola, {first_name} {last_name}!\")\n\nsay_hello(\"Zoe\", \"Roy\")\n\n# NOTA: Sin el decorador, esto seria el equivalente:\nmy_decorator(say_hello(\"Ben\", \"Yun\"))\n\n# ______________________\n# Decorando una clase:\n\ndef class_decorator(cls):\n    class Wrapper(cls):\n        def greet(self):\n            print(\"\\nAntes de llamar al método\")\n            super().greet()\n            print(\"Después de llamar al método\")\n    return Wrapper\n\n@class_decorator\nclass MyClass:\n    def greet(self):\n        print(\"Hola!\")\n\nobj = MyClass()\nobj.greet()\n\n\"\"\" \n* EJERCICIO #2:\n* Crea un decorador que sea capaz de contabilizar cuántas veces\n* se ha llamado a una función y aplícalo a una función de tu elección.\n\"\"\"\nprint(\"\\nEJERCICIO #2:\")\n\ndef count_calls(func):\n    def wrapper(*args):\n        wrapper.calls += 1\n        func(*args)\n        print(f\"Ha sido llamada {wrapper.calls} veces\")\n        \n    wrapper.calls = 0\n    return wrapper\n\n@count_calls\ndef function_a(func_name: str):\n    print(f\"\\nLa función '{func_name}':\")\n\n@count_calls\ndef function_b(func_name: str, example: str):\n    print(f\"\\nLa función{func_name} - {example}:\")\n\nfunction_a(\"A\")\nfunction_a(\"A\")\nfunction_a(\"A\")\n\nfunction_b(\"B\", \"args_ejm\")\nfunction_b(\"B\", \"args_ejm\")\n\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/mhayhem.py",
    "content": "# @Author Daniel Grande (Mhayhem)\n\nfrom functools import wraps\n\n# EJERCICIO:\n# Explora el concepto de \"decorador\" y muestra cómo crearlo\n# con un ejemplo genérico.\n\ndef decorator(func):\n    @wraps(func)\n    def wrapper(*args, **kwargs):\n        print(\"This is a rwapper.\")\n        return func(*args, **kwargs)\n    return wrapper\n\n@decorator\ndef simple_function():\n    return \"Tihs is a simple function\"\n\nprint(simple_function())\n\n# DIFICULTAD EXTRA (opcional):\n# Crea un decorador que sea capaz de contabilizar cuántas veces\"\n# se ha llamado a una función y aplícalo a una función de tu elección.\n\ndef calls_counter(func):\n    @wraps(func) \n    def wrapper(*args, **kwargs):\n        wrapper.calls += 1 # añadimos una nueva llamada\n        print(f\"La {func.__name__} ha sido llamada {wrapper.calls}\") # mostramos nombre de función y veces que la llamamos\n        return func(*args, **kwargs) # retornamos la función\n    wrapper.calls = 0 # inicializamos la variable de veces llamada\n    return wrapper \n\n@calls_counter\ndef greet():\n    pass # evitamos demasiadas líneas en terminal ya que no necesitamos ningún retorno en este ejemplo."
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/mouredev.py",
    "content": "\"\"\"\nEjercicio\n\"\"\"\n\n\ndef print_call(function):\n    def print_function():\n        print(f\"La función '{function.__name__}' ha sido llamada.\")\n        return function\n    return print_function\n\n\n@print_call\ndef example_function():\n    pass\n\n\n@print_call\ndef example_function_2():\n    pass\n\n\n@print_call\ndef example_function_3():\n    pass\n\n\nexample_function()\nexample_function_2()\nexample_function_3()\n\n\"\"\"\nExtra\n\"\"\"\n\n\ndef call_counter(function):\n    def counter_function():\n        counter_function.call_count += 1\n        print(\n            f\"La función '{function.__name__} se ha llamado {counter_function.call_count}' veces.\")\n        return function\n\n    counter_function.call_count = 0\n    return counter_function\n\n\n@call_counter\ndef example_function_4():\n    pass\n\n\n@call_counter\ndef example_function_5():\n    pass\n\n\nexample_function_4()\nexample_function_4()\nexample_function_4()\nexample_function_4()\nexample_function_5()\nexample_function_4()\nexample_function_5()\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/mrodara.py",
    "content": "#### PATRONES DE DISEÑO: DECORADORES\n\n'''\nEl Patrón Decorador es un patrón estructural que permite añadir funcionalidades a un objeto dinámicamente sin modificar su estructura original. \nEs especialmente útil cuando necesitas extender las capacidades de una clase de manera flexible y reutilizable.\n\nEn Python, este concepto también está integrado en el lenguaje a través de la sintaxis de decoradores, \nque simplifica el uso del patrón.\n'''\n\n# Ejemplo básico con una función decoradora\ndef decorador(funcion):\n    def wrapper(*args, **kwargs):\n        print(\"Antes de ejecutar la función\")\n        result = funcion(*args, **kwargs)\n        print(\"Después de ejecutar la función\")\n        \n        return result\n    \n    return wrapper\n\n@decorador\ndef saludo(name):\n    print(f'Hola {name}, estás siendo saludado desde un decorador')\n    \nsaludo(\"Manuel\")\n\n# En lugar de funciones también se pueden usar decoradores con Clases\nclass DecoradorClase():\n    def __init__(self, function):\n        self.function = function\n    \n    def __call__(self, *args, **kwargs):\n        print(\"Antes de ejecutar la función\")\n        result = self.function(*args, **kwargs)\n        print(\"Después de ejecutar la función\")\n        \n        return result\n\n@DecoradorClase\ndef saludo(name: str):\n    print(f'Hola {name}, ahora el decorador es de clase')\n\nsaludo(\"Otra vez Manuel\")\n\n### EJERCICIO EXTRA\nclass DecoradorContador():\n    \n    count = 0\n    \n    def __init__(self, function):\n        self.function = function\n        \n    def __call__(self, *args, **kwds):\n        result = self.function(*args, **kwds)\n        self.count += 1\n        print(f'La función se ha ejecutado {self.count} veces')\n        return result\n\n@DecoradorContador    \ndef saludo(name: str):\n    print(f'Hola {name}')\n\nnames = ['Antonio', 'Rita', 'Gabriel']\n\nfor name in names:\n    saludo(name)\n\n\n### FIN EJERCICIO EXTRA\n#### FIN PATRONES DE DISEÑO: DECORADORES\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/neslarra.py",
    "content": "\"\"\"\n EJERCICIO:\n Explora el concepto de \"decorador\" y muestra cómo crearlo\n con un ejemplo genérico.\n DIFICULTAD EXTRA (opcional):\n Crea un decorador que sea capaz de contabilizar cuántas veces\n se ha llamado a una función y aplícalo a una función de tu elección.\n\"\"\"\n\nprint(f\"{'#' * 47}\")\nprint(f\"##  Explicación  {'#' * 30}\")\nprint(f\"{'#' * 47}\")\n\nprint(r\"\"\"\nLos decoradores son funciones que modifican el comportamiento de otras funciones. Pueden ser los que entrega Python por default (por ejemplo\nstaticmethod y classmethod) o funciones creadas para determinada función.\n\nPor ejemplo, creo una clase Turno para entregar turnos de una tienda con varios sectores. La clase Turno tendrá tres métodos decorados:\n  1- hora_de_emision decorado con  \"staticmethod\" indicando que es de clase PERO no recive ni entrega argumentos de la clase.\n  2- localiza_sector decorado con \"classmethod\" indicanco que es de clase y entregando el contenido de una variable de la clase.\n  3- entrega_de_turno decorado con \"classmethod\" indicando que es de clase y modificando y entregando una variable de clase.\n\nLuego tenemos el decorador \"asesor\" el cual se encarga de ejecutar comandos pre y post callback de la función decorada (va a dar instrucciones\nde localización, va a llamar a la función que muestra el turno y luego va a hacer un saludo final).\n\nLos decoradores se invocan con un \"@\"<nombre_de_la_función_decoradora> justo antes de definir la función decorada.\n\n    def mi_decorador(callback_func):\n        def wrapper(*args, **kwargs)\n            <ejecuto PRE operaciones>\n            callback_func(*args, **kwargs)\n            <ejecuto POST operaciones>\n        return wrapper\n\n    @mi_decorador\n    def funcion_decorada():\n        ...\n\nEjemplo:\n\nfrom time import sleep\n\n\nclass Turno:\n    turno: int = 1000\n    ubicacion = {\"Farmacia\": \"por pasillo central al fondo\",\n                 \"Perfumería\": \"por escalera primer piso\",\n                 \"Gabinete\": \"por pasillo de la derecha\"}\n\n    def __init__(self, sector):\n        self.sector = sector\n        self.hora = self.hora_de_emision()\n        self.turno = Turno.entrega_turno()\n\n    @staticmethod\n    def hora_de_emision():\n        from datetime import datetime\n        return datetime.now().strftime('%H:%M:%S')\n\n    @classmethod\n    def localiza_sector(cls, sector):\n        return cls.ubicacion[sector]\n\n    @classmethod\n    def entrega_turno(cls):\n        cls.turno += 1\n        return cls.turno\n\n\ndef asesor(funcion_decorada):\n    def wrapper(*args, **kwargs):\n        # *args, **kwargs son los argumentos de la función decorada \"ver_turno: args[0] = nombre y args[1] L instancia del objeto Turno\"\n        print(f\"{args[0]} dirijase {args[1].localiza_sector(args[1].sector)}\")\n        funcion_decorada(*args, **kwargs)\n        print(\"Gracias por su visita.\\n\")\n\n    return wrapper\n\n\n@asesor\ndef ver_turno(nombre, turno):\n    print(f\"Tiene el turno {turno.turno} de la hora {turno.hora} para {turno.sector}\")\n\n\nnestor = Turno(\"Farmacia\")\nsleep(1)\nneslarra = Turno(\"Farmacia\")\nsleep(1)\nnesla = Turno(\"Perfumería\")\nsleep(1)\notro_nestor = Turno(\"Gabinete\")\n\nver_turno(\"Néstor\", nestor)\nver_turno(\"Neslarra\", neslarra)\nver_turno(\"Nesla\", nesla)\nver_turno(\"Otro Néstor\", otro_nestor)\n\nÉsto devuelve:\n\nNéstor dirijase por pasillo central al fondo                # decorador PRE operación\nTiene el turno 1001 de la hora 18:28:14 para Farmacia       # función decorada\nGracias por su visita.                                      # decorador POST operación\n\nNeslarra dirijase por pasillo central al fondo              # decorador PRE operación\nTiene el turno 1002 de la hora 18:28:15 para Farmacia       # función decorada\nGracias por su visita.                                      # decorador POST operación\n\nNesla dirijase por escalera primer piso                     # decorador PRE operación\nTiene el turno 1003 de la hora 18:28:16 para Perfumería     # función decorada\nGracias por su visita.                                      # decorador POST operación\n\nOtro Néstor dirijase por pasillo de la derecha              # decorador PRE operación\nTiene el turno 1004 de la hora 18:28:17 para Gabinete       # función decorada\nGracias por su visita.                                      # decorador POST operación\n\"\"\")\n\nprint(f\"{'#' * 52}\")\nprint(f\"##  Dificultad Extra  {'#' * 30}\")\nprint(f\"{'#' * 52}\\n\")\n\ndef contador_de_ejecuciones(funcion):\n    ejecuciones = {}\n    def wrapper(*args, **kwargs):\n        ejecuciones[funcion.__name__] = ejecuciones[funcion.__name__] if funcion.__name__ in ejecuciones.keys() else 0\n        print(f\"Ejecutando {funcion.__name__}\", end=\"\\n\\t\")\n        funcion(*args)\n        ejecuciones[funcion.__name__] += 1\n        print(f\"{funcion.__name__} se ha ejecutado {ejecuciones[funcion.__name__]} veces.\\n\")\n    return wrapper\n\n\n@contador_de_ejecuciones\ndef saludo_espaniol(nombre):\n    print(f\"{nombre} Hola Mundo\")\n\n\n@contador_de_ejecuciones\ndef saludo_ingles(nombre):\n\n    print(f\"{nombre} Hello World\")\n@contador_de_ejecuciones\ndef saludo_frances(nombre):\n    print(f\"{nombre} Alo Monde\")\n\n@contador_de_ejecuciones\ndef saludo_italiano(nombre):\n    print(f\"{nombre} Ciao Mondo\")\n\n\nsaludo_ingles(\"Pete\")\nsaludo_italiano(\"Peppo\")\nsaludo_ingles(\"Joe\")\nsaludo_ingles(\"Jhonny\")\nsaludo_espaniol(\"Tonio\")\nsaludo_espaniol(\"Pepe\")\nsaludo_italiano(\"Gianni\")\nsaludo_frances(\"Peppete\")\nsaludo_frances(\"Jean\")\nsaludo_italiano(\"Carletto\")\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/nlarrea.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el concepto de \"decorador\" y muestra cómo crearlo\n * con un ejemplo genérico.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un decorador que sea capaz de contabilizar cuántas veces\n * se ha llamado a una función y aplícalo a una función de tu elección.\n\"\"\"\n\n\ndef measure_time(function):\n    def wrapper(*args, **kwargs):\n        \"\"\"Función de lógica del decorador.\"\"\"\n\n        import time\n\n        start = time.time()\n        result = function(*args, **kwargs)\n        end = time.time()\n        print(f\"Required time: {round(end - start, 4)} seconds\")\n\n        return result\n\n    # Las variables del decorador se colocarían aquí\n    # ...\n\n    return wrapper\n\n\n\"\"\" Cada decorador funciona como una instancia diferente para cada función\ndecorada, por eso podemos crear \"variables\" dentro del decorador.\nCada vez que se llame a la misma función, la variable no se resetea. \"\"\"\n\n\n@measure_time\ndef sum_two_values(num_one: int, num_two: int):\n    import time\n\n    time.sleep(3)\n\n    return num_one + num_two\n\n\nprint(sum_two_values(10, 5))\n\"\"\" prints:\nRequired time: 3.0013 seconds\n15\n\"\"\"\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un decorador que sea capaz de contabilizar cuántas veces\n * se ha llamado a una función y aplícalo a una función de tu elección.\n\"\"\"\n\ncounter = 0\n\n\ndef count_calls(function):\n    def wrapper(*args, **kwargs):\n        wrapper.counter += 1\n        function(*args, **kwargs)\n        print(\n            f\"Calls number for function '{function.__name__}': {wrapper.counter}\"\n        )\n\n        return function\n\n    # Variable del decorador -> se ejecuta 1 vez por función decorada\n    wrapper.counter = 0\n\n    return wrapper\n\n\n@count_calls\ndef print_message(message: str = \"Hello there!\"):\n    print(message)\n\n\n@count_calls\ndef another_function():\n    pass\n\n\nprint_message()\nprint_message()\nanother_function()\nprint_message()\nanother_function()\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/oriaj3.py",
    "content": "\"\"\"\n24 - DECORADORES\nAutor de la solución: Oriaj3\n\nTeoría: \nLos decoradores son funciones que envuelven a otras funciones o métodos para extender\no modificar su comportamiento. Los decoradores son una característica poderosa de Python\nque permite añadir funcionalidades a una función sin modificar su código.\n\nEn la vida real, un decorador se puede comparar con un envoltorio de regalo. El regalo  \nes la función original y el envoltorio es el decorador que añade funcionalidades al regalo.\n\nPor ejemplo, se puede utilizar un decorador para medir el tiempo de ejecución de una función,\npara comprobar si el usuario tiene permisos para ejecutar una función o para registrar la\nentrada y salida de una función.\n\nEjemplo: \ndef decorador(funcion):\n    def envoltura():\n        print(\"Antes de ejecutar la función\")\n        funcion()\n        print(\"Después de ejecutar la función\")\n    return envoltura\n    \n@decorador\ndef saludo():\n    print(\"Hola, mundo!\")\n    \nsaludo()\n\nEn este ejemplo, el decorador \"decorador\" envuelve la función \"saludo\" y añade un mensaje\nantes y después de ejecutar la función. Al llamar a la función \"saludo\", se ejecuta la\nfunción envuelta por el decorador.\n\"\"\"\n\n\"\"\"\n/*\n * EJERCICIO:\n * Explora el concepto de \"decorador\" y muestra cómo crearlo\n * con un ejemplo genérico.\n\"\"\"\n\n##Ejemplo propio\ndef mi_decorador(funcion):\n    def decorar():\n        print('Antes de la ejecución de la función a decorar')\n        funcion()\n        print('Después de la ejecución de la función a decorar')\n\n    return decorar\n\n@mi_decorador\ndef saludar():\n    print('Hola mundo!!')\n\nsaludar()\n\n#Ejemplo Mouredev\ndef mostrar_llamada(funcion):\n    def mostrar_funcion():\n        print(f\"[{funcion.__name__}]\")\n        return funcion\n    return mostrar_funcion\n\n@mostrar_llamada    \ndef ejemplo_funcion1():\n    pass\n\n@mostrar_llamada\ndef ejemplo_funcion2():\n    pass\n\nejemplo_funcion1()\nejemplo_funcion2()\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un decorador que sea capaz de contabilizar cuántas veces\n * se ha llamado a una función y aplícalo a una función de tu elección.\n */\n\"\"\"\nimport time \n\ndef mostrar_llamadas(funcion):\n    def contador_funciones():\n        contador_funciones.contador += 1\n        print(f\"[{funcion.__name__}]- {contador_funciones.contador}\")\n    contador_funciones.contador=0\n    return contador_funciones\n\n@mostrar_llamadas\ndef ejemplo_1():\n    pass\n\n@mostrar_llamadas\ndef ejemplo_2():\n    pass\n\nejemplo_1()\nejemplo_1()\nejemplo_2()\nejemplo_1()\nejemplo_2()\n\n#Ejemplo de decorador que cuenta el tiempo\n\ndef contador_tiempo(funcion):\n    def contador():\n        start_time = time.time()\n        funcion ()\n        final_time = time.time()\n        total = final_time - start_time\n        print(f\"[{funcion.__name__}]- ha tardado {total} segundos\")\n\n    return contador\n\n@contador_tiempo\ndef ejemplo_tiempo():\n    for i in range (0, 20):\n        time.sleep(0.1)\n        pass\n\nejemplo_tiempo()\n\n#DEcorador con argumentos que cuenta el tiempo\n\ndef contador_tiempo_args(funcion):\n    def contador(*args, **kwargs):\n        start_time = time.time()\n        funcion(*args, **kwargs)\n        final_time = time.time()\n        total = final_time - start_time\n        print(f\"[{funcion.__name__}]- ha tardado {total} segundos\")\n\n    return contador\n\n@contador_tiempo_args\ndef ejemplo_tiempo_args(n):\n    for i in range (0, n):\n        time.sleep(0.1)\n        pass\n    \nejemplo_tiempo_args(10)\n\n#Decorador que comprueba si el usuario tiene permisos\ndef comprobar_permisos(permisos_requeridos):\n    \"\"\"Decorador que comprueba si el usuario tiene los permisos necesarios.\n\n    Args:\n        permisos_requeridos: Una lista de permisos necesarios para ejecutar la función.\n    \"\"\"\n    def decorador(funcion):\n        def comprobar(*args, **kwargs):\n            if all(permiso in permisos_usuario for permiso in permisos_requeridos):\n                return funcion(*args, **kwargs)  # Ejecutar la función original\n            else:\n                print(\"No tienes permisos para ejecutar esta función.\")\n        return comprobar\n    return decorador\n\n# Ejemplo de uso:\n\npermisos_usuario = [\"leer\"]  # Permisos del usuario actual\n\n@comprobar_permisos([\"leer\"])\ndef funcion_lectura():\n    print(\"Función de lectura ejecutada con éxito.\")\n\n@comprobar_permisos([\"escribir\"])\ndef funcion_escritura():\n    print(\"Función de escritura ejecutada con éxito.\")\n\n@comprobar_permisos([\"leer\", \"escribir\"])\ndef funcion_lectura_escritura():\n    print(\"Función de lectura y escritura ejecutada con éxito.\")\n\nfuncion_lectura()      # Se ejecuta\nfuncion_escritura()   # Se ejecuta\nfuncion_lectura_escritura() # Se ejecuta"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/pyramsd.py",
    "content": "def decorador(func):\n    def opp(a, b):\n        print(f'llamada a la funcion {func.__name__}')\n        resultado = func(a, b)\n        return ''.join([f'Resultado de la funcion {func.__name__}: ', str(resultado)])\n    return opp\n\n@decorador\ndef suma(a,b):\n    return a+b\n\n@decorador\ndef resta(a,b):\n    return a-b\n\nprint(suma(5, 5))\nprint(resta(5, 5))\n\n\n'''\nEXTRA\n'''\ndef contador_de_llamada(func):\n    func.contador = 0\n    def counter():\n        func.contador += 1\n        print(f'Se ha llamado {func.contador} veces a la funcion {func.__name__}')\n        return func\n    return counter\n\n@contador_de_llamada\ndef llamar_funcion():\n    print()\n\nllamar_funcion()\nllamar_funcion()\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/qwik-zgheib.py",
    "content": "def call_counter(func):\n    count = 0\n\n    def wrapper(*args, **kwargs):\n        nonlocal count\n        count += 1\n        print(f\"Function '{func.__name__}' has been called {count} times.\")\n        return func(*args, **kwargs)\n\n    return wrapper\n\n\n@call_counter\ndef add(a, b):\n    return a + b\n\n\n@call_counter\ndef subtract(a, b):\n    return a - b\n\n\nprint(add(3, 5))\nprint(subtract(10, 2))\nprint(add(4, 4))\nprint(subtract(8, 3))\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/rantamhack.py",
    "content": "\n\n\nprint(\"\\n\\n=======================================EJERCICIO=======================================\\n\\n\")\n\n\"\"\"\n * EJERCICIO:\n * Explora el concepto de \"decorador\" y muestra como crearlo\n * con un ejemplo generico.\n\"\"\"\n\ndef func_decorator(func_parameter):\n    def internal_function(*args, **kwargs):\n        print(\"\\nEste texto se imprime antes de realizar un calculo \")\n        func_parameter(*args, **kwargs)\n        print(\"Este texto se imprime despues de realizar el calculo\\n\")\n        \n    return internal_function\n\n\n@func_decorator\ndef suma(num1, num2):\n    print(f\"El resultado de la suma es {num1 + num2}\")\n    \n@func_decorator    \ndef resta(num1, num2):\n    print(f\"El resultado de la resta es {num1 - num2}\")\n    \n@func_decorator    \ndef potencia(base, exponente):\n    print(f\"El resultado de elevar {base} a la potencia {exponente} es: {pow(base, exponente)}\")\n\nsuma(10, 5)\nresta(10, 5)\npotencia(base=5, exponente=3)\n\n\nprint(\"\\n\\n=======================================DIFICULTAD EXTRA=======================================\\n\\n\")\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un decorador que sea capaz de contabilizar cuantas veces\n * se ha llamado a una funcion y aplicalo a una funcion de tu eleccion.\n\"\"\"\n\ndef decorator_counter(func_parameter):\n    def func_counter(*args):\n        func_counter.counter += 1\n        if func_counter.counter == 1:\n            print(f\"La funcion ha sido llamada {func_counter.counter} vez\")\n        else:\n            print(f\"La funcion ha sido llamada {func_counter.counter} veces\")\n        return func_parameter(*args)\n            \n    func_counter.counter = 0    \n    return func_counter\n\n@decorator_counter\ndef multiply(a, b):\n    print(a * b)\n    \nmultiply(5, 3)\nmultiply(7, 2)\nmultiply(15, 17)\nmultiply(24, 31)\n\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/raulG91.py",
    "content": "#Basic decorator\ndef my_decorator(function):\n    def my_wrapper(*args,**kwargs):\n        print(\"Initialize wrapper\")\n        result = function(*args,**kwargs)\n        print(\"Finishing wrapper\")\n        return result\n\n    return my_wrapper    \n\n@my_decorator\ndef suma(a,b):\n    return a + b\n\nprint(suma(2,3))\n\n#Extra\ndef my_decorator2(function):\n    execution = 0\n    def my_wrapper2(*args,**kwargs):\n        nonlocal execution\n        execution += 1\n        function(*args,**kwargs)\n        return execution\n    return my_wrapper2\n\n@my_decorator2\ndef multiply(value1,value2):\n    print(f'Value of multiplication {value1 * value2}')\n\nprint(f'Number of executions {multiply(4,2)}')\nprint(f'Number of executions {multiply(8,7)}')\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/raynerpv2022.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * Explora el concepto de \"decorador\" y muestra cómo crearlo\n#  * con un ejemplo genérico.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea un decorador que sea capaz de contabilizar cuántas veces\n#  * se ha llamado a una función y aplícalo a una función de tu elección.\n#  */\nimport time\n\ndef root_fonction(f):\n    \n    def rein_function():\n         \n        rein_function.aufruf += 1\n        rein_function.Stunden *=2\n        time.sleep(rein_function.Stunden)\n        print(f\"Name {f.__name__} Mal {rein_function.aufruf} Stunden {rein_function.Stunden}\")\n\n        return f\n    \n    rein_function.aufruf = 0\n    rein_function.Stunden = 1\n    return rein_function\n\n@root_fonction\ndef function_1():\n    pass\n@root_fonction\ndef function_2():\n    pass\n\nfunction_1()\nfunction_2()\nfunction_1()\nfunction_1()\nfunction_1()\nfunction_2()"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/rigo93acosta.py",
    "content": "# #24 PATRONES DE DISEÑO: DECORADORES\n'''\n/*\n * EJERCICIO:\n * Explora el concepto de \"decorador\" y muestra cómo crearlo\n * con un ejemplo genérico.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un decorador que sea capaz de contabilizar cuántas veces\n * se ha llamado a una función y aplícalo a una función de tu elección.\n */\n'''\n\n## Ejercicio\n\ndef print_call(func):\n    def print_function():\n        print(f\"La funcion '{func.__name__}' ha sido llamada\")\n        return func    \n    return print_function\n\n@print_call\ndef example_function():\n    # print(\"La funcion 'example_function' ha sido llamada\")\n    pass\n\n@print_call\ndef example_function_2():\n    # print(\"La funcion 'example_function_2' ha sido llamada\")\n    pass\n\n@print_call\ndef example_function_3():\n    # print(\"La funcion 'example_function_3' ha sido llamada\")\n    pass\n\nexample_function()\nexample_function_2()\nexample_function_3()\n\n## Dificultad extra\n\ndef call_counter(func):\n    \n    def counter_function():\n        counter_function.call_counter += 1\n        if counter_function.call_counter == 1:\n            print(f\"La funcion '{func.__name__}' ha sido llamada {counter_function.call_counter} vez\")\n        else:\n            print(f\"La funcion '{func.__name__}' ha sido llamada {counter_function.call_counter} veces\")\n        return func\n    \n    counter_function.call_counter = 0\n    return counter_function\n\n@call_counter\ndef example_function_4():\n    pass\n\n@call_counter\ndef example_function_5():\n    pass\n\nexample_function_4()\nexample_function_4()\nexample_function_5()\nexample_function_4()"
  },
  {
    "path": "Roadmap/24 - DECORADORES/python/santyjl.py",
    "content": "#24 PATRONES DE DISEÑO: DECORADORES\n\"\"\"\n/*\n * EJERCICIO:\n * Explora el concepto de \"decorador\" y muestra cómo crearlo\n * con un ejemplo genérico.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un decorador que sea capaz de contabilizar cuántas veces\n * se ha llamado a una función y aplícalo a una función de tu elección.\n */\n\"\"\"\n\n# Definición de un decorador llamado 'decorador'\ndef decorador(funcion):\n    # Definición de una función interna que envuelve la función original\n    def pintar_terminal(a, b):\n        for i in range(3):\n            print(f\"=================={i}==================\")\n\n        # Llama a la función original con los argumentos proporcionados\n        func = funcion(a, b)\n        return func\n\n    # Devuelve la función interna, que ahora es una versión decorada de la función original\n    return pintar_terminal\n\n# Aplicación del decorador 'decorador' a la función 'multiplicar'\n@decorador\ndef multiplicar(a, b):\n    return a * b\n\nprint(multiplicar(5, 5))\n\n#extra\n\n# Definición de un decorador llamado 'contador'\ndef contador(funcion):\n    cantidad: int = 1\n\n    def contar():\n        nonlocal cantidad  # Utiliza la variable 'cantidad' definida en el ámbito del decorador\n        print(\"Se ha llamado esta función un total de\", cantidad, \"veces\")\n        cantidad += 1\n\n        func = funcion()\n        return func\n\n    return contar\n\n@contador\ndef saludar():\n    print(\"Hola mundo\")\n\nsaludar()\nsaludar()\nsaludar()\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/rust/kenysdev.rs",
    "content": "/*\n╔═══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado                ║\n║ GitHub: https://github.com/Kenysdev   ║\n║ 2024 -  Rust                          ║\n╚═══════════════════════════════════════╝\n-----------------------------------------\n* DECORADORES\n-----------------------------------------\n\n* EJERCICIO #1:\n* Explora el concepto de \"decorador\" y muestra cómo crearlo\n* con un ejemplo genérico.\n*/\n\n// Rasgo Componente\ntrait Component {\n    fn operation(&self, first_name: &str, last_name: &str);\n}\n\n// Implementar este rasgo\nstruct ConcreteComponent;\n\nimpl Component for ConcreteComponent {\n    fn operation(&self, first_name: &str, last_name: &str) {\n        println!(\"Hola, {} {}!\", first_name, last_name);\n    }\n}\n\n// Definir una estructura Decorator con su implementación:\nstruct MyDecorator<T: Component> {\n    component: T,\n}\n\nimpl<T: Component> MyDecorator<T> {\n    fn new(component: T) -> Self {\n        MyDecorator { component }\n    }\n}\n\nimpl<T: Component> Component for MyDecorator<T> {\n    fn operation(&self, first_name: &str, last_name: &str) {\n        println!(\"Antes de llamar a la función.\");\n        self.component.operation(first_name, last_name);\n        println!(\"Después de llamarla.\");\n    }\n}\n\n/*\n* EJERCICIO #2:\n* Crea un decorador que sea capaz de contabilizar cuántas veces\n* se ha llamado a una función y aplícalo a una función de tu elección.\n*/\n\ntrait FunctionTrait {\n    fn call(&mut self, func_name: &str);\n}\n\nstruct Function {\n    calls: usize,\n}\n\nimpl Function {\n    fn new() -> Self {\n        Function { calls: 0 }\n    }\n}\n\nimpl FunctionTrait for Function {\n    fn call(&mut self, func_name: &str) {\n        self.calls += 1;\n        println!(\"\\nLa función '{}' ha sido llamada {} veces\", func_name, self.calls);\n    }\n}\nstruct CountCalls<T: FunctionTrait> {\n    wrapped_function: T,\n}\n\nimpl<T: FunctionTrait> CountCalls<T> {\n    fn new(wrapped_function: T) -> Self {\n        CountCalls { wrapped_function }\n    }\n}\n\nimpl<T: FunctionTrait> FunctionTrait for CountCalls<T> {\n    fn call(&mut self, func_name: &str) {\n        self.wrapped_function.call(func_name);\n    }\n}\n\n//____________________________________\nfn main() {\n    println!(\"EJERCICIO #1\");\n\n    let component = ConcreteComponent;\n    let decorated_component = MyDecorator::new(component);\n\n    decorated_component.operation(\"Zoe\", \"Roy\");\n\n    //____________________________________\n    println!(\"EJERCICIO #2\");\n\n    let function_a = Function::new();\n    let mut function_a = CountCalls::new(function_a);\n\n    function_a.call(\"A\");\n    function_a.call(\"A\");\n    function_a.call(\"A\");\n\n    let function_b = Function::new();\n    let mut function_b = CountCalls::new(function_b);\n\n    function_b.call(\"B\");\n    function_b.call(\"B\");\n    \n}\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/sql/Nicojsuarez2.sql",
    "content": "# #24 PATRONES DE DISEÑO: DECORADORES\n> #### Dificultad: Fácil | Publicación: 10/06/24 | Corrección: 17/06/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Explora el concepto de \"decorador\" y muestra cómo crearlo\n * con un ejemplo genérico.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un decorador que sea capaz de contabilizar cuántas veces\n * se ha llamado a una función y aplícalo a una función de tu elección.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/swift/allbertoMD.swift",
    "content": "import Foundation\n\n\nfunc greet() {\n    print(\"Hola, Mundo!\")\n}\n\n// Decorador\nfunc decorateGreet(originalFunction: @escaping () -> Void) -> () -> Void {\n    return {\n        print(\"Iniciando Saludo\")\n        originalFunction()\n        print(\"Saludo Finalizado\\n\")\n    }\n}\n\n// Usando el decorador\nlet decoratedGreet = decorateGreet(originalFunction: greet)\ndecoratedGreet()\n\n\nfunc add(a: Int, b: Int) -> Int {\n    return a + b\n}\n\n// Decorador\nfunc decorateAdd(originalFunction: @escaping (Int, Int) -> Int) -> (Int, Int) -> Int {\n    return { a, b in\n        print(\"Sumando \\(a) and \\(b)\")\n        let result = originalFunction(a, b)\n        print(\"El Resultado Es: \\(result)\")\n        return result\n    }\n}\n\n// Usando el decorador\nlet decoratedAdd = decorateAdd(originalFunction: add)\nlet result = decoratedAdd(3, 4)\nprint(\"Resultado Final: \\(result)\\n\")\n\n\n\n\n// DIFICULTAD EXTRA\nprint(\"\\nDificultad Extra\\n\")\n\n\nfunc sayHi(to personName: String) {\n    print(\"Hola, \\(personName)\")\n}\n\n\nfunc decorateSayHi(originFunction: @escaping (String) -> Void) -> (String) -> Void {\n    var callCount = 0\n\n    return { personName in\n        originFunction(personName)\n        callCount += 1\n        \n        if callCount < 2 {\n            print(\"Función ejecutada \\(callCount) vez.\\n\")\n        } else {\n            print(\"Función ejecutada \\(callCount) veces.\\n\")\n        }\n        \n    }\n}\n\nlet decoratedSayHi = decorateSayHi(originFunction: sayHi)\ndecoratedSayHi(\"Sergio\")\ndecoratedSayHi(\"Alberto\")\ndecoratedSayHi(\"Arturo\")\ndecoratedSayHi(\"Angeles\")\ndecoratedSayHi(\"Yaiza\")\ndecoratedSayHi(\"Carmen\")\n\n\n\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/swift/blackriper.swift",
    "content": "import Foundation\n/*\n Decorator es un patron de diseño estructural que permite añadir \n dinamicamente  nuevos comportamientos a un objeto  colocandolo\n dentro de objetos que los envuelven.(wrapper)\n\n para mas informacion https://refactoring.guru/es/design-patterns/decorator\n\n\n */\n\n // 1.- creamos un protocolo(interface) para las operaciones que vamos a modificar \n protocol MacComputer{\n     func getDataComputer() -> String\n }\n\n //2.- creamos una clase que implemente el protocolo\n class MacbookPro: MacComputer{\n     func getDataComputer() -> String {\n         return \"MackbookPro has \"\n     }\n }\n\n //3.- creamos la clase que va a ser el wrapper de la clase MacbookPro\n class MacDecorator: MacComputer{\n     private var macbookPro: MacComputer\n\n     init(_ macbookPro: MacComputer){\n         self.macbookPro = macbookPro\n     }\n     func getDataComputer() -> String {\n         return macbookPro.getDataComputer()\n     }\n    }\n\n   //4.-creamos los diferentes objetos  que va envolver nuestro wrapper \n class MacDecoratorCpu: MacDecorator{\n     override func getDataComputer() -> String {\n         return super.getDataComputer() + \"M3 pro processor\"\n     }\n }\n\n class MacDecoratorRam: MacDecorator{\n     override func getDataComputer() -> String {\n         return super.getDataComputer() + \" and 16 GB ram\"\n     }\n }\n\n //5.- creamos una instancia de la clase MacDecorator\n let macbookPro = MacbookPro()\n let macDecoratorCpu = MacDecoratorCpu(macbookPro)\n let macDecoratorRam = MacDecoratorRam(macDecoratorCpu)\n print(macDecoratorRam.getDataComputer())\n\n// reto extra\n\nprotocol Count{\n    func getCount() -> Int\n}\n\nclass CountExucution: Count{\n    private var count = 0\n    func getCount() -> Int {\n        count += 1\n        return count\n    }\n}\n\nclass CountDecorator: Count{\n    private var countExucution: Count\n    init(_ countExucution: Count){\n        self.countExucution = countExucution\n    }\n    func getCount() -> Int {\n        return countExucution.getCount()\n    }\n}\n\nclass SwiftVersion: CountDecorator{\n\n   func getSwiftVersion() -> String {\n      print(\"function invoke \\(getCount()) times\")\n      return \"5.10.1\"\n    }\n\n    override  func getCount() -> Int {\n        return super.getCount() \n    }\n}\n\nlet swiftVersion = SwiftVersion(CountExucution())\nprint(swiftVersion.getSwiftVersion())\nprint(swiftVersion.getSwiftVersion())\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/typescript/AChapeton.ts",
    "content": "class BasicMath {\n  sumar(a: number, b: number){\n    return a + b\n  }\n\n  restar(a: number, b: number){\n    return a - b\n  }\n\n  multiplicar(a: number, b: number){\n    return a * b\n  }\n\n  dividir(a: number, b: number){\n    if (b === 0) {\n      throw new Error('No se puede dividir entre 0')\n    }\n    return a / b\n  }\n}\n\nconst mathDecorator = (fun) => {\n  return function(...args){\n    console.log(`Llamando a la funcion ${fun.name} con argumentos`, args)\n    return fun.apply(this, args)\n  }\n}\n\nBasicMath.prototype.sumar = mathDecorator(BasicMath.prototype.sumar)\nBasicMath.prototype.restar = mathDecorator(BasicMath.prototype.restar)\nBasicMath.prototype.multiplicar = mathDecorator(BasicMath.prototype.multiplicar)\nBasicMath.prototype.dividir = mathDecorator(BasicMath.prototype.dividir)\n\nconst test = new BasicMath()\n\nconsole.log(test.sumar(2, 3))\nconsole.log(test.restar(5, 3))\nconsole.log(test.multiplicar(4, 3)) \nconsole.log(test.dividir(10, 2)) "
  },
  {
    "path": "Roadmap/24 - DECORADORES/typescript/Sac-Corts.ts",
    "content": "function greet(name: string): string {\n    return `Hello, ${name}!`;\n}\n\nfunction logDecorator<T extends (...args: any[]) => any>(fn: T): (...args: Parameters<T>) => ReturnType<T> {\n    return function(...args: Parameters<T>): ReturnType<T> {\n        console.log(`Calling function: ${fn.name}`);\n        const result = fn(...args);\n        console.log(`Function ${fn.name} executed with result: ${result}`);\n        return result;\n    };\n}\n\nconst decoratedGreet = logDecorator(greet);\nconsole.log(decoratedGreet(\"Isaac\"));\n\n// ** Extra Exercise ** //\nfunction callCountDecorator<T extends (...args: any[]) => any>(fn: T): (...args: Parameters<T>) => ReturnType<T> {\n    let count = 0;\n\n    return function(...args: Parameters<T>): ReturnType<T> {\n        count++;\n        console.log(`Function ${fn.name} has been called ${count} times`);\n        return fn(...args);\n    };\n}\n\nconst decoratedGreet2 = callCountDecorator(greet);\nconsole.log(decoratedGreet2(\"Hiel\"));\nconsole.log(decoratedGreet2(\"Kurama\"));\nconsole.log(decoratedGreet2(\"Yusuke\"));\nconsole.log(decoratedGreet2(\"Kuwabara\"));\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/typescript/duendeintemporal.ts",
    "content": "//#24 { retosparaprogramadores } - PATRONES DE DISEÑO: DECORADORES\n/*\n * EJERCICIO:\n * Explora el concepto de \"decorador\" y muestra cómo crearlo\n * con un ejemplo genérico.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un decorador que sea capaz de contabilizar cuántas veces\n * se ha llamado a una función y aplícalo a una función de tu elección.\n*/\n\n/* Explanation Note for Decorators(from DeepSeek): \nWhat Are Decorators?\n\nDecorators are special functions that can be attached to classes, methods, properties, or parameters. \nThey are prefixed with the @ symbol and are executed at runtime when the class or method is defined.\n\nTypeScript supports the following types of decorators:\n\n    Class Decorators: Applied to a class.\n\n    Method Decorators: Applied to a method.\n\n    Property Decorators: Applied to a property.\n\n    Parameter Decorators: Applied to a parameter of a method.\n    \n    Why Use Decorators?\n\n    Separation of Concerns: Decorators allow you to add functionality (e.g., logging, validation)\n     without modifying the core logic of your classes or methods.\n\n    Reusability: You can reuse decorators across multiple classes or methods.\n\n    Readability: Decorators make it clear what additional behavior is being applied to a class or method.\n\n    Metadata: Decorators can be used to attach metadata to classes or methods, which can be used later \n    (e.g., for dependency injection frameworks).\n\n    When to Use Decorators?\n\n    Logging: Automatically log method calls or property changes.\n\n    Validation: Validate inputs or properties.\n\n    Dependency Injection: Mark classes or properties for automatic injection.\n\n    Metadata: Attach metadata for frameworks or libraries.\n\n    Performance Monitoring: Measure execution time of methods.\n    */\n\nlet log = console.log;\n\n// Conditional check for browser environment\nif (typeof window !== 'undefined') {\n    window.addEventListener('load', () => {\n        const body: HTMLBodyElement | null = document.querySelector('body');\n        const title = document.createElement('h1');\n\n        body?.style.setProperty('background', '#000');\n        body?.style.setProperty('text-align', 'center');\n\n        title.textContent = 'Retosparaprogramadores #24.';\n        title.style.setProperty('font-size', '3.5vmax');\n        title.style.setProperty('color', '#fff');\n        title.style.setProperty('line-height', '100vh');\n\n        body?.appendChild(title);\n\n        setTimeout(() => {\n            alert('Retosparaprogramadores #24. Please open the Browser Developer Tools.');\n        }, 2000);\n        log('Retosparaprogramadores #24');\n    });\n} else {\n    log('This code is designed to run in a browser environment. Skipping window-related code.');\n    log('Retosparaprogramadores #24');\n}\n\n/* \nThe decorator pattern is a structural design pattern that allows behavior to be added to individual objects, either statically or dynamically, without affecting the behavior of other objects from the same class. In TypeScript, decorators can be implemented using higher-order functions.\n*/\n\n// Generic decorator function\nfunction decorator(fn: (...args: any[]) => void) {\n    return function(...args: any[]): void {\n        log(\"Before calling the function\");\n        const result = fn(...args);\n        log(\"After calling the function\");\n        return result;\n    };\n}\n\n// Decorator to log execution time\nfunction logExecutionTime(fn: (...args: any[]) => Promise<any>) {\n    return async function(...args: any[]): Promise<any> {\n        const start = performance.now(); // Start time\n        const result = await fn(...args); \n        const end = performance.now(); // End time\n        log(`Execution time for ${fn.name}: ${end - start} milliseconds`);\n        return result; \n    };\n}\n\n// Example function that simulates a time-consuming task\nfunction fetchData(): Promise<string> {\n    return new Promise((resolve) => {\n        setTimeout(() => {\n            resolve(\"Data fetched!\");\n        }, 3000);\n    });\n}\n\n// Decorated function\nconst loggedFetchData = logExecutionTime(fetchData);\n\n// Using the decorated function\nloggedFetchData().then(result => log(result)); \n// Data fetched!Execution time for fetchData: 3164.9740999999995 milliseconds\n// Data fetched!\n\n// EXTRA DIFICULTY EXERCISE\n\n// Decorator to count function calls\nfunction countCalls(fn: (...args: any[]) => any) {\n    let callCount = 0; // Private variable to keep track of calls through closure\n\n    return function(...args: any[]): any {\n        callCount++; \n        log(`Function has been called ${callCount} times.`);\n        return fn(...args); \n    };\n}\n\n// Original function\nfunction hiGirl(): string {\n    log('Hi Girl! 🌹');\n    return '🌼';\n}\n\n// Decorated function\nconst countedHiGirl = countCalls(hiGirl);\n\n// Using the decorated function\nlog(countedHiGirl()); // Function has been called 1 times. Hi Girl! 🌹\n// 🌼\nlog(countedHiGirl()); // Function has been called 2 times. Hi Girl! 🌹\n// 🌼\nlog(countedHiGirl()); // Function has been called 3 times. Hi Girl! 🌹\n// 🌼\n\n/* \nNOTE: When you define a function inside another function, the inner function creates a private scope. This means that the inner function has access to the variables and parameters of the outer function, but those variables are not accessible from outside the outer function. This is a key feature of closures in JavaScript.\n\nExplanation of Private Scope with Closures\nIn the context of the decorator pattern, this private scope allows us to maintain state (like the callCount in the counting decorator) without exposing it to the outside world. Here’s a breakdown of how this works:\n\nClosure: When the inner function is returned from the outer function, it retains access to the outer function's variables. This is known as a closure. The inner function can use and modify these variables even after the outer function has finished executing.\nPrivate Variables: Variables defined in the outer function (like callCount) are not accessible from outside the function. This means that you cannot directly modify or read callCount from outside the countCalls function, which effectively makes it private.\n*/\n"
  },
  {
    "path": "Roadmap/24 - DECORADORES/typescript/eulogioep.ts",
    "content": "/*\n * TEORÍA DE DECORADORES EN TYPESCRIPT\n * \n * Los decoradores son un patrón de diseño que nos permite añadir funcionalidad\n * adicional a clases, métodos, propiedades o parámetros de manera declarativa.\n * \n * En TypeScript, un decorador es una función especial que puede ser adjuntada a:\n * - Declaraciones de clase\n * - Métodos\n * - Propiedades\n * - Parámetros\n * \n * Para usar decoradores en TypeScript, necesitamos:\n * 1. Habilitar la opción \"experimentalDecorators\" en tsconfig.json\n * 2. Definir una función decoradora\n * 3. Aplicar el decorador usando el símbolo @ \n */\n\n// Ejemplo 1: Decorador simple para una clase\nfunction logClass(target: any) {\n    // Este decorador simplemente registra el nombre de la clase\n    console.log(`Clase creada: ${target.name}`);\n}\n\n// Aplicamos el decorador a una clase\n@logClass\nclass Ejemplo {\n    constructor() {\n        console.log('Constructor de Ejemplo ejecutado');\n    }\n}\n\n// Ejemplo 2: Decorador de método que registra la ejecución\nfunction logMethod(target: any, propertyKey: string, descriptor: PropertyDescriptor) {\n    // Guardamos la función original\n    const originalMethod = descriptor.value;\n\n    // Reemplazamos el método con una nueva función\n    descriptor.value = function(...args: any[]) {\n        console.log(`Llamando al método ${propertyKey}`);\n        return originalMethod.apply(this, args);\n    }\n\n    return descriptor;\n}\n\nclass EjemploMetodo {\n    @logMethod\n    saludar(nombre: string) {\n        return `¡Hola ${nombre}!`;\n    }\n}\n\n// EJERCICIO EXTRA: Decorador contador de llamadas\nfunction contadorLlamadas(target: any, propertyKey: string, descriptor: PropertyDescriptor) {\n    // Variable para almacenar el contador\n    let contador = 0;\n    \n    // Guardamos la función original\n    const originalMethod = descriptor.value;\n    \n    // Reemplazamos el método con una nueva función que incluye el contador\n    descriptor.value = function(...args: any[]) {\n        contador++;\n        console.log(`La función ${propertyKey} ha sido llamada ${contador} veces`);\n        return originalMethod.apply(this, args);\n    }\n    \n    return descriptor;\n}\n\n// Ejemplo de uso del decorador contador\nclass Calculadora {\n    @contadorLlamadas\n    sumar(a: number, b: number): number {\n        return a + b;\n    }\n\n    @contadorLlamadas\n    multiplicar(a: number, b: number): number {\n        return a * b;\n    }\n}\n\n// Código de prueba\nconsole.log(\"=== Pruebas de los decoradores ===\");\n\n// Prueba del decorador de clase\nconst ejemplo = new Ejemplo();\n\n// Prueba del decorador de método\nconst ejemploMetodo = new EjemploMetodo();\nconsole.log(ejemploMetodo.saludar(\"TypeScript\"));\n\n// Prueba del decorador contador\nconst calc = new Calculadora();\nconsole.log(calc.sumar(5, 3));        // Primera llamada a sumar\nconsole.log(calc.sumar(2, 4));        // Segunda llamada a sumar\nconsole.log(calc.multiplicar(3, 4));   // Primera llamada a multiplicar\nconsole.log(calc.sumar(1, 1));        // Tercera llamada a sumar"
  },
  {
    "path": "Roadmap/24 - DECORADORES/vb.net/kenysdev.vb",
    "content": "' ╔══════════════════════════════════════╗\n' ║ Autor:  Kenys Alvarado               ║\n' ║ GitHub: https://github.com/Kenysdev  ║\n' ║ 2024 -  VB.NET                       ║\n' ╚══════════════════════════════════════╝\n'-----------------------------------------------\n'* DECORADORES\n'-----------------------------------------------\n\n'* EJERCICIO #1:\n'* Explora el concepto de \"decorador\" y muestra cómo crearlo\n'* con un ejemplo genérico.\n\n' Interfaz\nPublic Interface ISayHello\n    Sub SayHello(ByVal first_name As String, ByVal last_name As String)\nEnd Interface\n\n' Componente Concreto\nPublic Class HelloSpeaker\n    Implements ISayHello\n\n    Public Sub SayHello(ByVal first_name As String, ByVal last_name As String) Implements ISayHello.SayHello\n        Console.WriteLine($\"Hola, {first_name} {last_name}!\")\n    End Sub\nEnd Class\n\n' Decorador Base\nPublic MustInherit Class DecoratorBase\n    Implements ISayHello\n    Protected _helloSpeaker As ISayHello\n\n    Public Sub New(ByVal helloSpeaker As ISayHello)\n        _helloSpeaker = helloSpeaker\n    End Sub\n\n    Public Overridable Sub SayHello(ByVal first_name As String, ByVal last_name As String) Implements ISayHello.SayHello\n        _helloSpeaker.SayHello(first_name, last_name)\n    End Sub\nEnd Class\n\n' Decorador Concreto\nPublic Class MyDecorator\n    Inherits DecoratorBase\n\n    Public Sub New(ByVal helloSpeaker As ISayHello)\n        MyBase.New(helloSpeaker)\n    End Sub\n\n    Public Overrides Sub SayHello(ByVal first_name As String, ByVal last_name As String)\n        Console.WriteLine(\"Antes de llamar a la función.\")\n        MyBase.SayHello(first_name, last_name)\n        Console.WriteLine(\"Después de llamarla.\")\n    End Sub\nEnd Class\n\n'-----------------------------------------------\n'* EJERCICIO #2\n'* Utiliza el patrón de diseño \"singleton\" para representar una clase que\n'* haga referencia a la sesión de usuario de una aplicación ficticia.\n'* La sesión debe permitir asignar un usuario (id, username, nombre y email),\n'* recuperar los datos del usuario y borrar los datos de la sesión.\n\n' Interfaz\nPublic Interface IFunction\n    Sub Execute(ParamArray args As Object())\nEnd Interface\n\n' Componente Concreto\nPublic Class FunctionComponent\n    Implements IFunction\n    Private ReadOnly _name As String\n\n    Public Sub New(ByVal name As String)\n        _name = name\n    End Sub\n\n    Public Sub Execute(ParamArray args As Object()) Implements IFunction.Execute\n        Console.WriteLine(vbCrLf + $\"La función '{_name}':\")\n    End Sub\nEnd Class\n\n' Decorador Base\nPublic MustInherit Class CallCountDecorator\n    Implements IFunction\n    Protected _function As IFunction\n    Protected _calls As Integer\n\n    Public Sub New(ByVal functionComponent As IFunction)\n        _function = functionComponent\n        _calls = 0\n    End Sub\n\n    Public Sub Execute(ParamArray args As Object()) Implements IFunction.Execute\n        _calls += 1\n        _function.Execute(args)\n        Console.WriteLine($\"Ha sido llamada {_calls} veces\")\n    End Sub\nEnd Class\n\n' Decorador Concreto\nPublic Class CountCallsDecorator\n    Inherits CallCountDecorator\n\n    Public Sub New(ByVal functionComponent As IFunction)\n        MyBase.New(functionComponent)\n    End Sub\nEnd Class\n\n'-----------------------------------------------\nModule Program\n    Sub Main()\n        Console.WriteLine(\"EJERCICIO #1\")\n\n        Dim helloSpeaker As ISayHello = New HelloSpeaker()\n        Dim decoratedHelloSpeaker As ISayHello = New MyDecorator(helloSpeaker)\n        decoratedHelloSpeaker.SayHello(\"Zoe\", \"Roy\")\n\n        '-----------------------------------------------\n        Console.WriteLine(vbCrLf + \"EJERCICIO #2\")\n\n        Dim functionA As IFunction = New CountCallsDecorator(New FunctionComponent(\"A\"))\n        Dim functionB As IFunction = New CountCallsDecorator(New FunctionComponent(\"B\"))\n\n        functionA.Execute()\n        functionA.Execute()\n        functionA.Execute()\n\n        functionB.Execute()\n        functionB.Execute()\n\n    End Sub\nEnd Module\n"
  },
  {
    "path": "Roadmap/25 - LOGS/bash/rantamhack.sh",
    "content": "#!/bin/bash\n\n# * EJERCICIO:\n# * Explora el concepto de \"logging\" en tu lenguaje. Configuralo y muestra\n# * un ejemplo con cada nivel de \"severidad\" disponible.\n\n\necho -e \"\\n\\n=======================================EJERCICIO=======================================\\n\\n\"\n\n\n\n# * Emergency: El sistema esta inutilizable\n# * Alert :    Se debe de actuar inmediatemente\n# * Critical:  El sistema esta en condiciones criticas\n# * Error:     Se ha producido un error \n# * Warning:   Aviso en condiciones de peligro\n# * Notice:    Aviso normal pero condiciones notables\n# * Info:      Aviso de informacion, mensajes informatiovs\n# * Debug:     Depuracion, mensajes de bajo nive\n\n\nlog_message() {\n    local log_level=$1\n    local log_message=$2\n    local log_date=$(date '+%Y-%m-%d %H:%M:%S')\n    \n\n    case $log_level in\n        DEBUG)\n            echo \"$log_date - DEBUG - $log_message\"\n            ;;\n        INFO)\n            echo \"$log_date - INFO - $log_message\"\n            ;;\n        NOTICE)\n            echo \"$log_date - NOTICE - $log_message\"\n            ;;\n        WARNING)\n            echo \"$log_date - WARNING - $log_message\"\n            ;;\n        ERROR)\n            echo \"$log_date - ERROR - $log_message\"\n            ;;\n        CRITICAL)\n            echo \"$log_date - CRITICAL - $log_message\"\n            ;;\n        ALERT)\n            echo \"$log_date - ALERT - $log_message\"\n            ;;\n        EMERGENCY)\n            echo \"$log_date - EMERGENCY - $log_message\"\n            ;;\n        *)\n            echo \"$log_date - UNKNOWN - $log_message\"\n            ;;\n    esac\n}\n\n\nlog_message \"DEBUG\" \"[+] Entramos a la funcion\"\nlog_message \"INFO\" \"[+] La conexion con el servidor fue exitosa\"\nlog_message \"NOTICE\" \"[+] Es importante que revises el archivo syslog\"\nlog_message \"WARNING\" \"[!] Queda poco espacio en disco\"\nlog_message \"ERROR\" \"[!] Bloque de sangria previsto\"\nlog_message \"CRITICAL\" \"[!] Hay un error critico. Saliendo de la aplicacion ....\"\nlog_message \"ALERT\" \"[!] Se debe de actuar inmediatemente\"\nlog_message \"EMERGENCY\" \"[!] El sistema esta inutilizable\"\n\n# Los logs se pueden generar con el comando 'logger' y se pueden ver en el archivo de logs dependiendo de la distribucion (syslog, rsyslog,...)\n# Este script se ha hecho para que aparezcan en la salida por terminal cuando se ejecuta\n# con el comando 'logger' sustituimos en el case, tampoco necesitamos la variable 'log_date' ya que el archivo de logs proporciona la fecha y hora. QuedarÃ­a asi:\n\n        \n#   logger -p user.debug \"$log_message\"\n#   logger -p user.info \"$log_message\"\n#   logger -p user.notice \"$log_message\"\n#   logger -p user.warn \"$log_message\"\n#   logger -p user.err \"$log_message\"\n#   logger -p user.crit \"$log_message\"\n#   logger -p user.alert \"$log_message\"\n#   logger -p user.emerg \"$log_message\"\n\n\n\n\necho -e \"\\n\\n=======================================DIFICULTAD EXTRA=======================================\\n\\n\"\n\n\n# * DIFICULTAD EXTRA (opcional):\n# * Crea un programa ficticio de gestion de tareas que permita añadir, eliminar\n# * y listar dichas tareas.\n# * - Añadir: recibe nombre y descripcion.\n# * - Eliminar: por nombre de la tarea.\n# * Implementa diferentes mensajes de log que muestren informacion segun la \n# * tarea ejecutada (a tu eleccion).\n# * Utiliza el log para visualizar el tiempo de ejecucion de cada tarea. \n\n\nfunction time_spent() {\n    local star_time=$(date +%s.%N)    \n    \"$@\"\n    local end_time=$(date +%s.%N)\n    local elapsed_time=$(echo \"$end_time - $star_time\" | bc)\n    local formatted_time=$(LC_NUMERIC=C printf \"%.4f\" \"$elapsed_time\")\n    echo -e \"La funcion $1 ha tardado $formatted_time en ejecutarse\\n\"\n}\n\n\ndeclare -a list_task=()\n\nfunction add_task() {\n    local task=\"$1\"\n    local description=\"$2\"\n    local now=$(date '+%Y-%m-%d %H:%M:%S')\n    logger -p user.debug \"[*] Comienza la funcion para 'añadir tareas'\"\n    echo -e \"[$now] (user.debug) [*] Comienza la funcion para 'añadir tareas'\"\n    sleep 1\n    for t in \"${list_task[@]}\"; do\n        if [[ \"$t\" == \"$task\" ]]; then\n            logger -p user.warn \"[!] La tarea ya esta en la lista\"\n            echo -e \"[$now](user.warn) [!] La tarea ya esta en la lista\"\n            return\n        fi\n    done\n    list_task+=(\"$task\")\n    sleep 1\n    logger -p user.info \"[+] Se agrega nueva tarea $task - $description\"\n    echo -e \"[$now](user.info) [+] Se agrega nueva tarea $task - $description\"\n    logger -p user.debug \"[*] Finaliza la funcion 'añadir tareas'\"\n    echo -e \"[$now](user.debug) [*] Finaliza la funcion 'añadir tareas'\"\n}\n    \n    \nfunction del_task() {\n    local task=\"$1\"\n    local description=\"$2\"\n    local now=$(date '+%Y-%m-%d %H:%M:%S')\n    logger -p user.debug \"[*] Comienza la funcion para 'borrar tareas'\"\n    echo -e \"[$now](user.debug) [*] Comienza la funcion para 'borrar tareas'\"\n    sleep 1\n    local new_list=()\n    local task_found=0\n    for t in \"${list_task[@]}\"; do\n        if [[ \"$t\" == \"$task\" ]]; then\n            task_found=1\n        else\n            new_list+=(\"$t\")\n        fi\n    done\n    if [[ $task_found -eq 1 ]]; then\n        list_task=(\"${new_list[@]}\")\n        logger -p user.info \"[-] Se elimino la tarea: $task - $description\"\n        echo -e \"[$now](user.info) [-] Se elimino la tarea: $task - $description\"\n    else\n        logger -p user.warn \"[!] La tarea a eliminar $task - $description no existe\"\n        echo -e \"[$now](user.warn) [!] La tarea a eliminar $task - $description no existe\"\n    fi\n    sleep 1\n    logger -p user.debug \"[*] Finaliza la funcion 'eliminar tareas'\"\n    echo -e \"[$now](user.debug) [*] Finaliza la funcion 'eliminar tareas'\"\n}\n   \n           \nfunction list_tasks() {\n    local now=$(date '+%Y-%m-%d %H:%M:%S')\n    logger -p user.debug \"[*] Comienza la funcion para 'listar tareas'\"\n    echo -e \"[$now](user.debug) [*] Comienza la funcion para 'listar tareas'\"\n    sleep 3\n    for t in \"${list_task[@]}\"; do\n        echo -e \"[$now](user.info) [+] La lista de tareas programadas: $t\"\n        logger -p user.info \"[+] La lista de tareas programadas: $t\"\n    done\n    logger -p user.debug \"[*] Finaliza la funcion 'listar tareas'\" \n    echo -e \"[$now}(user.debug) [*] Finaliza la funcion 'listar tareas'\"    \n            \n}            \n    \n\nfunction decorator() {\n    time_spent \"$@\"\n}\n\n\n\ndecorator add_task \"task1\" \"recepcionar pedidos\"\ndecorator add_task \"task2\" \"preparar pedidos\"\ndecorator add_task \"task3\" \"enviar pedidos\"\ndecorator add_task \"task2\" \"preparar pedidos\"\n\ndecorator list_tasks\n\ndecorator del_task \"task4\" \"ordenar pedidos\"\ndecorator del_task \"task3\" \"enviar pedidos\"\n\ndecorator list_tasks \n"
  },
  {
    "path": "Roadmap/25 - LOGS/c#/hequebo.cs",
    "content": "using Microsoft.Extensions.Logging;\nusing System.Diagnostics;\nusing System.Globalization;\n\npartial class Program\n{\n    static void Main(string[] args)\n    {\n        /*\n         * En .Net se puede hacer uso de la API ILogger\n         * para registrer el comportamiento de la \n         * aplicación y detectar errores.\n         * Usamos la interface ILoggerFactory para \n         * configurar donde queremos enviar los mensajes\n         * del log, en este caso se envían a la consola\n         */\n        using ILoggerFactory factory = LoggerFactory.Create(builder => builder.AddConsole());\n        /*\n         * Creamos un ILogger e indicamos la categoria\n         * (Program). La categoria es un string asociada\n         * a cada mensaje del log. Se usa para agrupar\n         * mensajes de una misma clase.\n         */\n        ILogger logger = factory.CreateLogger(\"Program\");\n        /*\n         * Cada uno de los metodos siguientes realizan\n         * el registro  en cada uno de los diferentes\n         * niveles dependiendo de la gravedad del \n         * evento registrado.\n         */\n        logger.LogTrace(\"Trace Log\");\n        logger.LogDebug(\"Debug Log\");\n        logger.LogInformation(\"Information Log\");\n        logger.LogWarning(\"Warning Log\");\n        logger.LogError(\"Error Log\");\n        logger.LogCritical(\"Critical Log\");\n\n        // Ejercicio\n\n        Console.ReadLine();\n        Console.Clear();\n        var tasks = new Dictionary<string, string>();\n        bool salir = false;\n        do\n        {\n            Menu();\n            int option = 0;\n            int.TryParse(Console.ReadLine(), out option);\n\n            switch (option)\n            {\n                case 1:\n                    AddTask(ref tasks, logger);\n                    break;\n                case 2:\n                    RemoveTask(ref tasks, logger);\n                    break;\n                case 3:\n                    salir = true;\n                    Console.Clear();\n                    Console.WriteLine(\"Hasta la proxima...\");\n                    Thread.Sleep(1000);\n                    break;\n                default:\n                    Console.WriteLine(\"Opción no válida...\");\n                    break;\n            }\n        } while (!salir);\n\n\n    }\n    static void Menu()\n    {\n        Console.WriteLine(\"---Gestión de tareas---\");\n        Console.WriteLine(\"1.- Agregar tarea\");\n        Console.WriteLine(\"2.- Eliminar tarea\");\n        Console.WriteLine(\"3.- Salir\");\n        Console.WriteLine(\"Elija la opción deseada...\");\n    }\n    static void AddTask(ref Dictionary<string, string> tasks, ILogger logger)\n    {\n        Console.Clear();\n        Stopwatch sp = new Stopwatch();\n        sp.Start();\n        Console.WriteLine(\"Ingresa nombre de tarea\");\n        string name = Console.ReadLine();\n        Console.WriteLine(\"Ingresa descripción de la tarea\");\n        string description = Console.ReadLine();\n        tasks.Add(name, description);\n        sp.Stop();\n        LogAddedTask(logger, (int) sp.ElapsedMilliseconds / 1000);\n        \n    }\n\n    [LoggerMessage(level: LogLevel.Information, Message = \"Se agrega tarea en {time} segundos\")]\n    static partial void LogAddedTask(ILogger logger, int time);\n    static void RemoveTask(ref Dictionary<string, string> tasks, ILogger logger)\n    {\n        Console.Clear();\n        if (tasks.Count == 0)\n        {\n            Console.WriteLine(\"No hay tareas registradas...\");\n            return;\n        }\n        Stopwatch sp = new Stopwatch();\n        sp.Start();\n        Console.WriteLine(\"Ingresa nombre de tarea\");\n        string name = Console.ReadLine();\n        tasks.Remove(name);\n        sp.Stop();\n        LogTaskDeleted(logger, (int) sp.ElapsedMilliseconds / 1000);\n        \n    }\n    [LoggerMessage(level: LogLevel.Information, Message = \"Se elimina tarea en {time} segundos\")]\n    static partial void LogTaskDeleted(ILogger logger, int time);\n}\n    \n"
  },
  {
    "path": "Roadmap/25 - LOGS/c#/kenysdev.cs",
    "content": "#pragma warning disable CA1050 // for namespace Name\n/*\n╔══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado               ║\n║ GitHub: https://github.com/Kenysdev  ║\n║ 2024 -  C#                           ║\n╚══════════════════════════════════════╝\n------------------------------------------\n* LOGS\n------------------------------------------\nMas info: https://nlog-project.org/\n          \n*/\nusing NLog;\n\n// __________________________________\nclass Program {\n\n    private static readonly Logger logger = LogManager.GetCurrentClassLogger();\n    static void Main() {\n        /*\n        * EJERCICIO #1:\n        * Explora el concepto de \"logging\" en tu lenguaje. Configúralo y muestra\n        * un ejemplo con cada nivel de \"severidad\" disponible.\n        */\n        logger.Trace(\"Trace\");\n        logger.Debug(\"Debug\");\n        logger.Info(\"Info\");\n        logger.Warn(\"Warnin\");\n        logger.Error(\"Error\");\n        logger.Fatal(\"Fatal\");\n\n        //__________________________________\n        Console.WriteLine(\"\\nEJERCICIO #2\");\n        ProgramTask tasks = new();\n\n        tasks.Add(\"a\", \"1\");\n        tasks.Add(\"b\", \"2\");\n        tasks.Add(\"c\", \"3\");\n\n        tasks.Delete(\"b\");\n        tasks.ShowList();\n    }\n}\n\n/*\n__________________________________\n* EJERCICIO #2:\n* Crea un programa ficticio de gestión de tareas que permita añadir, eliminar\n* y listar dichas tareas.\n* - Añadir: recibe nombre y descripción.\n* - Eliminar: por nombre de la tarea.\n* Implementa diferentes mensajes de log que muestren información según la \n* tarea ejecutada (a tu elección).\n* Utiliza el log para visualizar el tiempo de ejecución de cada tarea. \n*/\nclass ProgramTask {\n    private static readonly Logger logger = LogManager.GetCurrentClassLogger();\n    private readonly Dictionary<string, string> tasks;\n\n    public ProgramTask() {\n        tasks = [];\n        logger.Debug(\"Se inició instancia de la clase ProgramTask.\");\n    }\n\n    public void Add(string name, string description) {\n        tasks[name] = description;\n        logger.Info(\"Se agregó una tarea.\");\n    }\n\n    public void Delete(string name) {\n        if (tasks.Remove(name)) {\n            logger.Info($\"Tarea '{name}' eliminada.\");\n        } else {\n            Console.WriteLine();\n            logger.Warn($\"No se encontró la tarea '{name}'.\");\n        }\n    }\n\n    public void ShowList() {\n        logger.Info(\"Lista de tareas\");\n        foreach (var task in tasks) {\n            Console.WriteLine($\"{task.Key} -- {task.Value}\");\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/25 - LOGS/c++/hectorio23.cpp",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <chrono>\n#include <spdlog/spdlog.h>\n#include <spdlog/sinks/stdout_color_sinks.h> // Incluir el encabezado correcto\n\nstruct Tarea {\n    std::string nombre;\n    std::string descripcion;\n};\n\nstd::vector<Tarea> tareas;\n\nvoid añadirTarea(const std::string& nombre, const std::string& descripcion) {\n    auto start = std::chrono::high_resolution_clock::now();\n    spdlog::info(\"Añadiendo tarea: {}\", nombre);\n    tareas.push_back({nombre, descripcion});\n    spdlog::debug(\"Tareas actuales: {}\", tareas.size());\n    auto end = std::chrono::high_resolution_clock::now();\n    std::chrono::duration<double> elapsed = end - start;\n    spdlog::info(\"Tarea añadida en {} segundos\", elapsed.count());\n}\n\nvoid eliminarTarea(const std::string& nombre) {\n    auto start = std::chrono::high_resolution_clock::now();\n    spdlog::info(\"Eliminando tarea: {}\", nombre);\n    tareas.erase(std::remove_if(tareas.begin(), tareas.end(), [&nombre](const Tarea& t) {\n        return t.nombre == nombre;\n    }), tareas.end());\n    spdlog::debug(\"Tareas actuales: {}\", tareas.size());\n    auto end = std::chrono::high_resolution_clock::now();\n    std::chrono::duration<double> elapsed = end - start;\n    spdlog::info(\"Tarea eliminada en {} segundos\", elapsed.count());\n}\n\nvoid listarTareas() {\n    spdlog::info(\"Listando todas las tareas\");\n    if (tareas.empty()) {\n        spdlog::warn(\"No hay tareas para listar\");\n    } else {\n        for (const auto& tarea : tareas) {\n            spdlog::info(\"Tarea: {}, Descripción: {}\", tarea.nombre, tarea.descripcion);\n        }\n    }\n}\n\nint main() {\n    try {\n        // Crear una consola para logging con colores\n        auto console = spdlog::stdout_color_mt(\"console\");\n        spdlog::set_level(spdlog::level::debug); // Establece el nivel de logging\n        spdlog::set_default_logger(console);\n\n        // Ejemplo de uso del programa de gestión de tareas\n        añadirTarea(\"Comprar pan\", \"Ir a la panadería y comprar una barra de pan\");\n        añadirTarea(\"Estudiar C++\", \"Completar el ejercicio de logging en C++\");\n        listarTareas();\n        eliminarTarea(\"Comprar pan\");\n        listarTareas();\n\n    } catch (const spdlog::spdlog_ex& ex) {\n        std::cout << \"Log init failed: \" << ex.what() << std::endl;\n    }\n\n    return 0;\n}\n\n// Execute: g++ -std=c++17 -o hectorio23 hectorio23.cpp -lspdlog -lfmt"
  },
  {
    "path": "Roadmap/25 - LOGS/ejercicio.md",
    "content": "# #25 LOGS\n> #### Dificultad: Fácil | Publicación: 17/06/24 | Corrección: 24/06/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Explora el concepto de \"logging\" en tu lenguaje. Configúralo y muestra\n * un ejemplo con cada nivel de \"severidad\" disponible.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa ficticio de gestión de tareas que permita añadir, eliminar\n * y listar dichas tareas.\n * - Añadir: recibe nombre y descripción.\n * - Eliminar: por nombre de la tarea.\n * Implementa diferentes mensajes de log que muestren información según la \n * tarea ejecutada (a tu elección).\n * Utiliza el log para visualizar el tiempo de ejecución de cada tarea. \n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/25 - LOGS/go/AmadorQuispe.go",
    "content": "package main\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"log/slog\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n)\n\nfunc main() {\n\t//logging 'slog' estándar de go (desde la versión 1.21)\n\tslog.SetLogLoggerLevel(slog.LevelDebug)\n\tslog.Debug(\"log debug\")\n\tslog.Info(\"log info\")\n\tslog.Warn(\"log warn\")\n\tslog.Error(\"log error\")\n\ttaskManager()\n}\n\nfunc taskManager() {\n\n\tlogger := slog.Default()\n\ttasks := make(map[string]string)\n\tlogger.Info(\"administrador de tareas iniciado.\")\n\treader := bufio.NewReader(os.Stdin)\n\tvar option string\n\tfor option != \"4\" {\n\t\tprintMenu()\n\t\tfmt.Print(\"Ingrese la opción :\")\n\t\toption, _ = reader.ReadString('\\n')\n\t\toption = strings.TrimSpace(option)\n\t\tswitch option {\n\t\tcase \"1\":\n\t\t\tfmt.Println(\"Tareas registradas\")\n\t\t\ttimeStart := time.Now()\n\t\t\tif len(tasks) == 0 {\n\t\t\t\tfmt.Println(\"No hay tareas registradas\")\n\t\t\t}\n\t\t\tfor k, v := range tasks {\n\t\t\t\tfmt.Println(k, \"-\", v)\n\t\t\t}\n\t\t\ttimeEnd := time.Now()\n\t\t\ttimeDuration := timeEnd.Compare(timeStart)\n\t\t\tlogger.Info(\"Tiempo de ejecución en listado \" + strconv.Itoa(timeDuration) + \"ms\")\n\t\tcase \"2\":\n\t\t\tfmt.Println(\"Agregar una tarea\")\n\t\t\ttimeStart := time.Now()\n\t\t\tfmt.Print(\"Ingrese nombre de la tarea:\")\n\t\t\tname, _ := reader.ReadString('\\n')\n\t\t\tname = strings.TrimSpace(name)\n\t\t\tfmt.Print(\"Ingrese descripción de la tarea:\")\n\t\t\tdescription, _ := reader.ReadString('\\n')\n\t\t\tdescription = strings.TrimSpace(description)\n\t\t\ttasks[name] = description\n\t\t\ttimeEnd := time.Now()\n\t\t\ttimeDuration := timeEnd.Compare(timeStart)\n\t\t\tlogger.Info(\"Tarea creada \" + name + \" Tiempo de ejecución \" + strconv.Itoa(timeDuration) + \"ms\")\n\t\tcase \"3\":\n\t\t\tfmt.Println(\"Eliminar una tarea\")\n\t\t\ttimeStart := time.Now()\n\t\t\tfmt.Print(\"Ingrese nombre de la tarea a eliminar:\")\n\t\t\tnameToDelete, _ := reader.ReadString('\\n')\n\t\t\tnameToDelete = strings.TrimSpace(nameToDelete)\n\t\t\tif _, ok := tasks[nameToDelete]; ok {\n\t\t\t\tdelete(tasks, nameToDelete)\n\t\t\t\ttimeEnd := time.Now()\n\t\t\t\ttimeDuration := timeEnd.Compare(timeStart)\n\t\t\t\tlogger.Info(\"Tarea eliminada \" + nameToDelete + \" ,tiempo de ejecución \" + strconv.Itoa(timeDuration) + \"ms\")\n\t\t\t} else {\n\t\t\t\ttimeEnd := time.Now()\n\t\t\t\ttimeDuration := timeEnd.Compare(timeStart)\n\t\t\t\tlogger.Info(\"Tarea no registrada \" + nameToDelete + \" ,tiempo de ejecución \" + strconv.Itoa(timeDuration) + \"ms\")\n\t\t\t}\n\t\tcase \"4\":\n\t\t\tlogger.Info(\"saliendo del sistema, gracias por usar\")\n\t\tdefault:\n\t\t\tlogger.Warn(\"opción no valida\")\n\t\t}\n\t}\n}\n\nfunc printMenu() {\n\tfmt.Println(strings.Repeat(\"-\", 29))\n\tfmt.Println(\"|| ADMINISTRADOR DE TAREAS ||\")\n\tfmt.Println(strings.Repeat(\"-\", 29))\n\tfmt.Println(\"Opciones disponibles\")\n\tfmt.Println(\"[1] Mostrar tareas\")\n\tfmt.Println(\"[2] Agregar una tarea\")\n\tfmt.Println(\"[3] Eliminar una tarea\")\n\tfmt.Println(\"[4] Salir\")\n}\n"
  },
  {
    "path": "Roadmap/25 - LOGS/go/N0HagoNada.go",
    "content": "package main\n\nimport (\n\t\"log\"\n\t\"os\"\n\t\"sync\"\n\t\"time\"\n)\n\nvar (\n\tlogger *log.Logger\n\tonce   sync.Once\n)\n\nfunc GetLogger() *log.Logger {\n\tonce.Do(func() {\n\t\tlogger = log.New(os.Stdout, \"\", log.LstdFlags|log.Lshortfile)\n\t})\n\treturn logger\n}\n\ntype Tarea struct {\n\tNombre      string\n\tDescripcion string\n}\n\ntype GestorTareas struct {\n\ttareas []Tarea\n}\n\nfunc (g *GestorTareas) AñadirTarea(nombre, descripcion string) {\n\tl := GetLogger()\n\tinicio := time.Now()\n\n\tg.tareas = append(g.tareas, Tarea{Nombre: nombre, Descripcion: descripcion})\n\n\tl.Printf(\"Tarea añadida: %s - %s\", nombre, descripcion)\n\tl.Printf(\"Tiempo de ejecución para añadir tarea: %v\", time.Since(inicio))\n}\n\nfunc (g *GestorTareas) EliminarTarea(nombre string) {\n\tl := GetLogger()\n\tinicio := time.Now()\n\n\tfor i, tarea := range g.tareas {\n\t\tif tarea.Nombre == nombre {\n\t\t\tg.tareas = append(g.tareas[:i], g.tareas[i+1:]...)\n\t\t\tl.Printf(\"Tarea eliminada: %s\", nombre)\n\t\t\tl.Printf(\"Tiempo de ejecución para eliminar tarea: %v\", time.Since(inicio))\n\t\t\treturn\n\t\t}\n\t}\n\n\tl.Printf(\"No se encontró la tarea: %s\", nombre)\n\tl.Printf(\"Tiempo de ejecución para buscar tarea: %v\", time.Since(inicio))\n}\n\nfunc (g *GestorTareas) ListarTareas() {\n\tl := GetLogger()\n\tinicio := time.Now()\n\n\tl.Println(\"Lista de tareas:\")\n\tfor _, tarea := range g.tareas {\n\t\tl.Printf(\"- %s: %s\", tarea.Nombre, tarea.Descripcion)\n\t}\n\n\tl.Printf(\"Tiempo de ejecución para listar tareas: %v\", time.Since(inicio))\n}\n\nfunc main() {\n\n\tl := GetLogger()\n\tl.Println(\"Iniciando programa de gestión de tareas\")\n\n\tgestor := &GestorTareas{}\n\n\tgestor.AñadirTarea(\"Comprar víveres\", \"Ir al supermercado y comprar alimentos para la semana\")\n\tgestor.AñadirTarea(\"Hacer ejercicio\", \"Realizar 30 minutos de cardio\")\n\tgestor.ListarTareas()\n\tgestor.EliminarTarea(\"Hacer ejercicio\")\n\tgestor.ListarTareas()\n\tgestor.EliminarTarea(\"Tarea inexistente\")\n\n\tl.Println(\"Finalizando programa de gestión de tareas\")\n\n}\n"
  },
  {
    "path": "Roadmap/25 - LOGS/go/hozlucas28.go",
    "content": "package main\n\nimport (\n\t\"bufio\"\n\t\"errors\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\t\"strings\"\n\t\"time\"\n)\n\n/* -------------------------------------------------------------------------- */\n/*                                   CLASSES                                  */\n/* -------------------------------------------------------------------------- */\n\n/* ------------------------------ Task Manager ------------------------------ */\n\ntype Task struct {\n\tdescription string\n\ttitle       string\n}\n\ntype TaskManager struct {\n\ttasks           []Task\n\tshouldPrintLogs bool\n}\n\nfunc (taskManager *TaskManager) addTask(newTask Task) error {\n\tvar startTime time.Time = time.Now()\n\n\tif taskManager.shouldPrintLogs {\n\t\tfmt.Println()\n\t\tlog.Println(\"addTask (method) start execution...\")\n\t}\n\n\ttaskManager.tasks = append(taskManager.tasks, newTask)\n\n\tif taskManager.shouldPrintLogs {\n\t\tlog.Println(\"addTask (method) ends execution!\")\n\t\tlog.Printf(\"addTask: %v\\n\", time.Since(startTime))\n\t}\n\n\treturn nil\n}\n\nfunc (taskManager *TaskManager) deleteTaskByTitle(title string) error {\n\tvar startTime time.Time = time.Now()\n\n\tif taskManager.shouldPrintLogs {\n\t\tfmt.Println()\n\t\tlog.Println(\"deleteTaskByTitle (method) start execution...\")\n\t}\n\n\tvar uppercasedTitle string = strings.ToUpper(title)\n\n\tvar sanitizedTasks []Task\n\n\tfor _, task := range taskManager.tasks {\n\t\tvar uppercasedTaskTitle string = strings.ToUpper(task.title)\n\n\t\tif uppercasedTaskTitle != uppercasedTitle {\n\t\t\tsanitizedTasks = append(sanitizedTasks, task)\n\n\t\t}\n\t}\n\n\tif len(taskManager.tasks) == len(sanitizedTasks) {\n\t\treturn errors.New(\"The task title was not found!\")\n\t}\n\n\ttaskManager.tasks = sanitizedTasks\n\n\tif taskManager.shouldPrintLogs {\n\t\tlog.Printf(\"deleteTaskByTitle (method) ends execution!\\n\")\n\t\tlog.Printf(\"deleteTaskByTitle: %v\\n\", time.Since(startTime))\n\t}\n\n\treturn nil\n}\n\nfunc (taskManager *TaskManager) printTasks() {\n\tvar startTime time.Time = time.Now()\n\n\tif taskManager.shouldPrintLogs {\n\t\tlog.Printf(\"printTasks (method) start execution...\\n\\n\")\n\t}\n\n\tfor _, task := range taskManager.tasks {\n\t\tfmt.Printf(\"%+v\\n\", task)\n\t}\n\n\tif taskManager.shouldPrintLogs {\n\t\tfmt.Println()\n\t\tlog.Printf(\"printTasks (method) ends execution!\\n\")\n\t\tlog.Printf(\"printTasks: %v\", time.Since(startTime))\n\t}\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\nfunc main() {\n\t/*\n\t\tLogging...\n\t*/\n\n\tfmt.Println(\"Logging...\")\n\n\tfmt.Printf(\"\\nlog.Print(<MESSAGE>)...\\n\\n\")\n\n\tlog.Print(\"logger message!\")\n\n\tfmt.Printf(\"\\nlog.Printf(<MESSAGE>)...\\n\\n\")\n\n\tlog.Printf(\"Formatted logger message!\")\n\n\tfmt.Printf(\"\\nlog.Println(<MESSAGE>)...\\n\\n\")\n\n\tlog.Println(\"Logger message with line break at the end!\")\n\n\tfmt.Println(\"\\n# ---------------------------------------------------------------------------------- #\")\n\n\t/*\n\t\tAdditional challenge...\n\t*/\n\n\tfmt.Printf(\"\\nAdditional challenge...\\n\")\n\n\tvar taskManager TaskManager = TaskManager{shouldPrintLogs: true}\n\n\tvar exit bool = false\n\tvar reader *bufio.Reader = bufio.NewReader(os.Stdin)\n\n\tfor !exit {\n\t\tfmt.Print(\"\\nWrite an operation ('Add task', 'Delete task by title', 'Print tasks', or 'Exit'): \")\n\t\toperation, readerErr := reader.ReadString('\\n')\n\t\tif readerErr != nil {\n\t\t\tcontinue\n\t\t}\n\n\t\toperation = strings.TrimSpace(operation)\n\t\toperation = strings.ToUpper(operation)\n\n\toperationActions:\n\t\tswitch operation {\n\t\tcase \"ADD TASK\":\n\t\t\tfmt.Print(\"\\nTask title: \")\n\t\t\ttaskTitle, readerErr := reader.ReadString('\\n')\n\t\t\tif readerErr != nil {\n\t\t\t\tbreak operationActions\n\t\t\t}\n\n\t\t\tfmt.Print(\"Task description: \")\n\t\t\ttaskDescription, readerErr := reader.ReadString('\\n')\n\t\t\tif readerErr != nil {\n\t\t\t\tbreak operationActions\n\t\t\t}\n\n\t\t\ttaskManager.addTask(Task{\n\t\t\t\tdescription: strings.TrimSpace(taskDescription),\n\t\t\t\ttitle:       strings.TrimSpace(taskTitle),\n\t\t\t})\n\n\t\tcase \"DELETE TASK BY TITLE\":\n\t\t\tfmt.Print(\"\\nTask title: \")\n\t\t\ttaskTitle, readerErr := reader.ReadString('\\n')\n\t\t\tif readerErr != nil {\n\t\t\t\tbreak operationActions\n\t\t\t}\n\n\t\t\ttaskManager.deleteTaskByTitle(taskTitle)\n\n\t\tcase \"PRINT TASKS\":\n\t\t\tfmt.Println()\n\t\t\ttaskManager.printTasks()\n\n\t\tcase \"EXIT\":\n\t\t\texit = true\n\t\t\tfmt.Print(\"\\nApplication closed!\")\n\n\t\tdefault:\n\t\t\tfmt.Print(\"\\nInvalid operation! Try again...\\n\")\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Roadmap/25 - LOGS/go/kodenook.go",
    "content": "package main\n\nimport \"log\"\n\nfunc main() {\n\tlog.Println(\"error\")\n}\n"
  },
  {
    "path": "Roadmap/25 - LOGS/go/qwik-zgheib.go",
    "content": "package main\n\nimport (\n\t\"log\"\n\t\"os\"\n\t\"time\"\n)\n\n// -- exercise\nfunc setupLogging() {\n\tlogFile, err := os.OpenFile(\"log.txt\", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)\n\tif err != nil {\n\t\tlog.Fatal(\"Failed to open log file:\", err)\n\t}\n\n\tlog.SetOutput(logFile)\n\tlog.SetFlags(log.Ldate | log.Ltime | log.Lmicroseconds)\n}\n\n// -- extra challenge\ntype Task struct {\n\tName        string\n\tDescription string\n}\n\ntype TaskManager struct {\n\tTasks []Task\n}\n\nfunc (tm *TaskManager) AddTask(name, description string) {\n\tstart := time.Now()\n\ttm.Tasks = append(tm.Tasks, Task{Name: name, Description: description})\n\telapsed := time.Since(start)\n\tlog.Printf(\"Task '%s' added successfully. Elapsed time: %s\", name, elapsed)\n}\n\nfunc (tm *TaskManager) DeleteTask(name string) {\n\tstart := time.Now()\n\tfor i, task := range tm.Tasks {\n\t\tif task.Name == name {\n\t\t\ttm.Tasks = append(tm.Tasks[:i], tm.Tasks[i+1:]...)\n\t\t\telapsed := time.Since(start)\n\t\t\tlog.Printf(\"Task '%s' deleted successfully. Elapsed time: %s\", name, elapsed)\n\t\t\treturn\n\t\t}\n\t}\n\tlog.Printf(\"Task '%s' not found.\", name)\n}\n\nfunc (tm *TaskManager) ListTasks() {\n\tstart := time.Now()\n\tif len(tm.Tasks) == 0 {\n\t\tlog.Println(\"No tasks found.\")\n\t\treturn\n\t}\n\tlog.Println(\"Tasks:\")\n\tfor _, task := range tm.Tasks {\n\t\tlog.Printf(\"Name: %s, Description: %s\", task.Name, task.Description)\n\t}\n\telapsed := time.Since(start)\n\tlog.Printf(\"Listed all tasks. Elapsed time: %s\", elapsed)\n}\n\nfunc main() {\n\tsetupLogging()\n\n\tlog.Println(\"This is a log message.\")\n\tlog.Printf(\"This is a log message with formatted output: %s\", \"Hello, World!\")\n\n\tlog.Println(\"This is an informational message.\")\n\n\tlog.Printf(\"This is an informational message with formatted output: %s\", \"Hello, World!\")\n\n\n\tlog.Println(\"This is a warning message.\")\n\n\tlog.Printf(\"This is a warning message with formatted output: %s\", \"Hello, World!\")\n\n\tlog.Println(\"This is an error message.\")\n\tlog.Printf(\"This is an error message with formatted output: %s\", \"Hello, World!\")\n\n\tlog.Println(\"This is a fatal message.\")\n\tlog.Printf(\"This is a fatal message with formatted output: %s\", \"Hello, World!\")\n\tlog.Fatal(\"Fatal error occurred.\")\n\n\ttaskManager := TaskManager{}\n\n\ttaskManager.AddTask(\"Task 1\", \"Description 1\")\n\ttaskManager.AddTask(\"Task 2\", \"Description 2\")\n\ttaskManager.AddTask(\"Task 3\", \"Description 3\")\n\n\ttaskManager.ListTasks()\n\n\ttaskManager.DeleteTask(\"Task 2\")\n\n\ttaskManager.ListTasks()\n}\n"
  },
  {
    "path": "Roadmap/25 - LOGS/go/raynerpv2022.go",
    "content": "package main\n\n/*\n#  * EJERCICIO:\n#  * Explora el concepto de \"logging\" en tu lenguaje. Configúralo y muestra\n#  * un ejemplo con cada nivel de \"severidad\" disponible.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea un programa ficticio de gestión de tareas que permita añadir, eliminar\n#  * y listar dichas tareas.\n#  * - Añadir: recibe nombre y descripción.\n#  * - Eliminar: por nombre de la tarea.\n#  * Implementa diferentes mensajes de log que muestren información según la\n#  * tarea ejecutada (a tu elección).\n#  * Utiliza el log para visualizar el tiempo de ejecución de cada tarea.\n#  */\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"math/rand\"\n\t\"os\"\n\t\"time\"\n)\n\nconst (\n\tDEBUG = iota\n\tINFO\n\tWARN\n\tERROR\n\tCRITICAL\n)\n\nvar loglevel = DEBUG\n\nfunc getLoggingMessage(level int, message string) {\n\tif level >= loglevel {\n\t\tswitch level {\n\t\tcase DEBUG:\n\t\t\tlog.Println(\"DEBUG: \", message)\n\t\tcase INFO:\n\t\t\tlog.Println(\"INFO: \", message)\n\t\tcase WARN:\n\t\t\tlog.Println(\"WARN: \", message)\n\t\tcase ERROR:\n\t\t\tlog.Println(\"ERROR: \", message)\n\t\tcase CRITICAL:\n\t\t\tlog.Println(\"CRITICAL: \", message)\n\n\t\t}\n\t}\n\n}\n\ntype TaskManager struct {\n\ttasks map[string]string\n}\n\nfunc (t *TaskManager) Create(name, desc string) {\n\t_, exist := t.tasks[name]\n\tif exist {\n\t\tgetLoggingMessage(ERROR, fmt.Sprintf(\" Task %v already created\\n\", name))\n\t} else {\n\t\tt.tasks[name] = desc\n\t\tgetLoggingMessage(INFO, fmt.Sprintf(\" Task %v  created succesfully\\n\", name))\n\t}\n\n}\n\nfunc (t *TaskManager) Delete(name string) {\n\t_, exist := t.tasks[name]\n\tif !exist {\n\t\tgetLoggingMessage(ERROR, fmt.Sprintf(\" Task %v Not Found\\n\", name))\n\t} else {\n\t\tdelete(t.tasks, name)\n\t\tgetLoggingMessage(INFO, fmt.Sprintf(\" Task %v delete succesfully\\n\", name))\n\t}\n\n}\n\nfunc (t *TaskManager) Display() {\n\n\tgetLoggingMessage(INFO, fmt.Sprintf(\" Task %v  \\n\", t.tasks))\n}\n\nfunc (t *TaskManager) Execute(name string) {\n\t_, exist := t.tasks[name]\n\tif exist {\n\t\tgetLoggingMessage(INFO, fmt.Sprintf(\" Task %v EXECUTING ... \\n\", name))\n\t\tstart := time.Now().Second()\n\t\tgetLoggingMessage(DEBUG, fmt.Sprintf(\" Task %v START TIME %v ... \\n\", name, start))\n\t\trandom_sleep := rand.Intn(10)\n\t\ttime.Sleep((time.Second * time.Duration(random_sleep)))\n\t\tend := time.Now().Second()\n\t\tgetLoggingMessage(DEBUG, fmt.Sprintf(\" Task %v END TIME %v ... \\n\", name, end))\n\t\tgetLoggingMessage(DEBUG, fmt.Sprintf(\" Task %v  DURATION TIME %v ... \\n\", name, random_sleep))\n\t\tgetLoggingMessage(INFO, fmt.Sprintf(\" Task %v DEAD ... \\n\", name))\n\t} else {\n\t\tgetLoggingMessage(CRITICAL, fmt.Sprintf(\" Task %v NOT EXECUTED, CRITICAL PARAMETER, NUCLEAR WAR is comming... \\n\", name))\n\t}\n\n}\n\nfunc main() {\n\t// log.Println(\"Error Normalito\")\n\n\t// log.Panic(\"Error Panic\")\n\t// log.Fatalln(\"Error Fatal\")\n\tfmt.Println(\"Loggin in  File (F) or Display (D)\")\n\tvar op string\n\t_, e := fmt.Scan(&op)\n\tif e != nil {\n\t\tlog.Fatal(e)\n\t}\n\tif op == \"F\" {\n\n\t\tf, e := os.OpenFile(\"app.log\", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)\n\t\tif e != nil {\n\t\t\tgetLoggingMessage(ERROR, \"Message ERROR, opening log file\")\n\t\t}\n\t\tdefer f.Close()\n\t\tlog.SetOutput(f)\n\t\tlog.SetFlags(log.Ldate | log.Ltime)\n\t}\n\n\tgetLoggingMessage(INFO, \"Message INFO\")\n\tgetLoggingMessage(DEBUG, \"Message DEBUG\")\n\tgetLoggingMessage(WARN, \"Message WARNING\")\n\tgetLoggingMessage(ERROR, \"Message ERROR\")\n\tgetLoggingMessage(CRITICAL, \"Message CRITICAL\")\n\tlog.Println(\"Errores\")\n\n\t// ?Extra\n\ttask_task := TaskManager{map[string]string{}}\n\ttask_task.Create(\"t1\", \"ggggg\")\n\ttask_task.Create(\"t1\", \"ggggg\")\n\ttask_task.Create(\"t2\", \"ggggg\")\n\ttask_task.Create(\"t3\", \"ggggg\")\n\ttask_task.Delete(\"tqq1\")\n\ttask_task.Delete(\"t1\")\n\ttask_task.Display()\n\ttask_task.Execute(\"t1\")\n\ttask_task.Execute(\"t3\")\n\ttask_task.Execute(\"t4\")\n\ttask_task.Display()\n\n}\n"
  },
  {
    "path": "Roadmap/25 - LOGS/java/ASJordi.java",
    "content": "/*\n    El Api de Java Logging proporciona una serie de métodos para registrar mensajes de aplicación (logs).\n    Esto permite registrar mensajes que se pueden usar para monitorear y diagnosticar una aplicación.\n    java.util.logging.Level define 7 niveles de registro de mensajes:\n        - SEVERE (el más alto)\n        - WARNING\n        - INFO\n        - CONFIG\n        - FINE\n        - FINER\n        - FINEST (el más bajo)\n    Existen otros 2 niveles: ALL y OFF. El primero se utiliza para habilitar todos los niveles de registro y el segundo para deshabilitar todos los niveles de registro.\n    El Api de Java Logging proporciona una serie de clases para registrar mensajes de aplicación:\n        - Logger: es la clase principal para registrar mensajes de aplicación.\n        - Handler: es una clase que maneja los mensajes de registro.\n        - Formatter: es una clase que formatea los mensajes de registro.\n        - Filter: es una clase que filtra los mensajes de registro.\n */\n\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.Scanner;\nimport java.util.logging.FileHandler;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport java.util.logging.XMLFormatter;\n\npublic class Main {\n\n    public static void main(String[] args) {\n//        useLogger();\n        tasksManager();\n    }\n\n    /**\n     * EJERCICIO:\n     * Explora el concepto de \"logging\" en tu lenguaje. Configúralo y muestra\n     * un ejemplo con cada nivel de \"severidad\" disponible.\n     */\n    static void useLogger() {\n        // Crear un Logger\n        Logger logger = Logger.getLogger(Main.class.getName());\n        // Habilitar todos los niveles de registro\n        logger.setLevel(Level.ALL);\n\n        try {\n            // Crear un FileHandler para registrar mensajes en un archivo\n            FileHandler fileHandler = new FileHandler(\"logs.log\");\n            // Asignar el formateador XML al FileHandler\n            fileHandler.setFormatter(new XMLFormatter());\n            // Agregar el FileHandler al Logger\n            logger.addHandler(fileHandler);\n\n            // Registrar mensajes\n            logger.severe(\"Mensaje de nivel SEVERE\");\n            logger.warning(\"Mensaje de nivel WARNING\");\n            logger.info(\"Mensaje de nivel INFO\");\n            logger.config(\"Mensaje de nivel CONFIG\");\n            logger.fine(\"Mensaje de nivel FINE\");\n            logger.finer(\"Mensaje de nivel FINER\");\n            logger.finest(\"Mensaje de nivel FINEST\");\n        } catch (Exception e) {\n            logger.log(Level.SEVERE, \"Mensaje de nivel SEVERE\", e);\n        }\n    }\n\n    /**\n     * DIFICULTAD EXTRA (opcional):\n     * Crea un programa ficticio de gestión de tareas que permita añadir, eliminar y listar dichas tareas.\n     * - Añadir: recibe nombre y descripción.\n     * - Eliminar: por nombre de la tarea.\n     * Implementa diferentes mensajes de log que muestren información según la\n     * tarea ejecutada (a tu elección).\n     * Utiliza el log para visualizar el tiempo de ejecución de cada tarea.\n     */\n    static void tasksManager() {\n        Logger logger = Logger.getLogger(Main.class.getName());\n        logger.setLevel(Level.ALL);\n        Scanner sc = new Scanner(System.in);\n        sc.useDelimiter(\"\\n\");\n        List<Task> tasks = new LinkedList<>();\n        String option = \"\";\n\n        while (!option.equals(\"4\")) {\n            showMenu();\n            option = sc.nextLine();\n            switch (option) {\n                case \"1\" -> {\n                    long s = System.currentTimeMillis();\n                    System.out.println(\"Introduce el título de la tarea:\");\n                    String title = sc.nextLine();\n                    System.out.println(\"Introduce la descripción de la tarea:\");\n                    String description = sc.nextLine();\n                    Task task = new Task(title, description);\n                    tasks.add(task);\n                    long e = System.currentTimeMillis();\n                    logger.log(Level.INFO, \"Tarea creada: \" + task);\n                    logger.log(Level.INFO, \"Tiempo de ejecución: \" + (e - s) + \"ms\");\n                }\n                case \"2\" -> {\n                    long s = System.currentTimeMillis();\n                    System.out.println(\"Introduce el título de la tarea a eliminar:\");\n                    String title = sc.nextLine();\n                    Task task = tasks.stream().filter(t -> t.title().equalsIgnoreCase(title)).findFirst().orElse(null);\n                    if (task != null) {\n                        tasks.remove(task);\n                        logger.log(Level.INFO, \"Tarea eliminada: \" + task);\n                    } else logger.log(Level.WARNING, \"Tarea no encontrada\");\n                    long e = System.currentTimeMillis();\n                    logger.log(Level.INFO, \"Tiempo de ejecución: \" + (e - s) + \"ms\");\n                }\n                case \"3\" -> {\n                    long s = System.currentTimeMillis();\n                    if (tasks.isEmpty()) logger.log(Level.WARNING, \"No hay tareas\");\n                    else tasks.forEach(task -> logger.log(Level.INFO, task.toString()));\n                    long e = System.currentTimeMillis();\n                    logger.log(Level.INFO, \"Tiempo de ejecución: \" + (e - s) + \"ms\");\n                }\n                case \"4\" -> logger.log(Level.INFO, \"Saliendo...\");\n                default -> logger.log(Level.WARNING, \"Opción no válida\");\n            }\n        }\n    }\n\n    public record Task(String title, String description) {}\n\n    static void showMenu() {\n        System.out.println(\"Selecciona una opción:\");\n        System.out.println(\"1. Crear tarea\");\n        System.out.println(\"2. Eliminar tarea\");\n        System.out.println(\"3. Mostar tareas\");\n        System.out.println(\"4. Salir\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/25 - LOGS/java/AmadorQuispe.java",
    "content": "package com.amsoft.roadmap.example25;\n\nimport java.io.IOException;\nimport java.text.SimpleDateFormat;\nimport java.util.Date;\nimport java.util.Map;\nimport java.util.Scanner;\nimport java.util.TreeMap;\nimport java.util.logging.Logger;\nimport java.util.logging.Formatter;\nimport java.util.logging.LogRecord;\nimport java.util.logging.FileHandler;\nimport java.util.logging.ConsoleHandler;\nimport java.util.logging.LogManager;\nimport java.util.logging.Level;\n\npublic class ExampleMain {\n    private final static Logger LOGGER = LoggerConfig.getLogger(ExampleMain.class);\n    public static void logs() {\n        LOGGER.severe(\"Severe Log\");\n        LOGGER.warning(\"Warning Log\");\n        LOGGER.info(\"Info Log\");\n        LOGGER.config(\"Config Log\");\n        LOGGER.fine(\"Fine Log\");\n        LOGGER.finer(\"Finer Log\");\n        LOGGER.finest(\"Finest Log\");\n    }\n\n    public static void main(String[] args) {\n        logs();\n        TaskManager taskManager =  new TaskManager();\n        taskManager.init();\n    }\n}\n\nclass TaskManager {\n    Logger logger = LoggerConfig.getLogger(TaskManager.class);\n    public void init(){\n        logger.info(\"administrador de tareas iniciado.\");\n        Scanner sc = new Scanner(System.in);\n        sc.useDelimiter(\"\\n\");\n        TreeMap<String,String> tasks = new TreeMap<>();\n        String  option = \"\";\n        while (!option.equals(\"4\")){\n            long timeStart;\n            long timeEnd;\n            menu();\n            System.out.println(\"Ingrese en número de la opción:\");\n            option = sc.nextLine();\n            switch (option){\n                case \"1\":\n                    System.out.println(\"Tareas registradas\");\n                    timeStart = System.currentTimeMillis();\n                    if(tasks.isEmpty()) System.out.println(\"No hay tareas registradas\");\n                    tasks.forEach((k,v)->System.out.println(k + \" - \" + v ));\n                    timeEnd = System.currentTimeMillis();\n                    logger.info(\"Tiempo de ejecución en listado \" + (timeEnd - timeStart) + \"ms\");\n                    break;\n                case \"2\":\n                    System.out.println(\"Agregar una tarea\");\n                    timeStart = System.currentTimeMillis();\n                    System.out.print(\"Ingrese nombre de la tarea:\");\n                    String name = sc.nextLine();\n                    System.out.print(\"Ingrese descripción de la tarea:\");\n                    String description = sc.nextLine();\n                    tasks.put(name,description);\n                    timeEnd = System.currentTimeMillis();\n                    logger.info(\"Tarea creada \" + name + \" Tiempo de ejecución \" + (timeEnd - timeStart) + \"ms\");\n                    break;\n                case \"3\":\n                    System.out.println(\"Eliminar una tarea\");\n                    timeStart = System.currentTimeMillis();\n                    System.out.print(\"Ingrese nombre de la tarea a eliminar:\");\n                    String nameToDelete = sc.nextLine();\n                    if(tasks.remove(nameToDelete)!=null){\n                        timeEnd = System.currentTimeMillis();\n                        logger.info(\"Tarea eliminada \" + nameToDelete + \" Tiempo de ejecución \" + (timeEnd - timeStart) + \"ms\");\n                    }else{\n                        timeEnd = System.currentTimeMillis();\n                        logger.info(\"Tarea no registrada \" + nameToDelete + \" Tiempo de ejecución \" + (timeEnd - timeStart) + \"ms\");\n                    }\n                    break;\n                case \"4\":\n                    System.out.println(\"Gracias por usar\");\n                    logger.info(\"Saliendo del sistema\");\n                    break;\n                default:\n                    System.out.println(\"Opción no disponible\");\n                    logger.warning(\"Opción no valida :\"+option);\n                    break;\n            }\n        }\n    }\n    private void menu(){\n        System.out.println(\"=\".repeat(29));\n        System.out.println(\"|| ADMINISTRADOR DE TAREAS ||\");\n        System.out.println(\"=\".repeat(29));\n        System.out.println(\"Opciones disponibles\");\n        System.out.println(\"[1] Mostrar tareas\");\n        System.out.println(\"[2] Agregar una tarea\");\n        System.out.println(\"[3] Eliminar una tarea\");\n        System.out.println(\"[4] Salir\");\n    }\n}\n\nclass LogFormatter extends Formatter {\n    private static final String PATTERN = \"yyyy-MM-dd'T'HH:mm:ss.SSSZ\";\n    private final SimpleDateFormat dateFormat = new SimpleDateFormat(PATTERN);\n    private static final int LEVEL_NAME_LENGTH = 7;\n\n    @Override\n    public String format(LogRecord record) {\n        StringBuilder sb = new StringBuilder();\n        String formattedDate = dateFormat.format(new Date(record.getMillis()));\n        sb.append(\"\\u001B[30m\");\n        sb.append(formattedDate).append(\" \");\n        String levelName = record.getLevel().getLocalizedName();\n        sb.append(padRight(levelName)).append(\" \");\n        sb.append(record.getLongThreadID()).append(\" --- \");\n        sb.append(\"[\").append(record.getLoggerName()).append(\"] \");\n        sb.append(\": \").append(formatMessage(record));\n        sb.append(\"\\u001B[0m\");\n        sb.append(\"\\n\");\n        return sb.toString();\n    }\n\n    private String padRight(String s) {\n        return String.format(\"%1$-\" + LEVEL_NAME_LENGTH + \"s\", s);\n    }\n}\n\nclass LoggerConfig {\n    static {\n        try {\n            FileHandler fileHandler = new FileHandler(\"Logging.txt\");\n            fileHandler.setFormatter(new LogFormatter());\n            ConsoleHandler consoleHandler = new ConsoleHandler();\n            consoleHandler.setFormatter(new LogFormatter());\n            LogManager.getLogManager().reset();\n            Logger rootLogger = Logger.getLogger(\"\");\n            rootLogger.setLevel(Level.ALL);\n            rootLogger.addHandler(fileHandler);\n            rootLogger.addHandler(consoleHandler);\n        } catch (IOException e) {\n            throw new RuntimeException(\"Error al configurar el logger\", e);\n        }\n    }\n\n    public static Logger getLogger(Class<?> clazz) {\n        return Logger.getLogger(clazz.getName());\n    }\n}"
  },
  {
    "path": "Roadmap/25 - LOGS/java/AnaLauDB.java",
    "content": "import java.util.logging.*;\nimport java.util.*;\nimport java.io.IOException;\n\npublic class AnaLauDB {\n\n    // Logger para la clase\n    private static final Logger logger = Logger.getLogger(AnaLauDB.class.getName());\n\n    // Clase para representar una tarea\n    static class Tarea {\n        private String nombre;\n        private String descripcion;\n        private Date fechaCreacion;\n\n        public Tarea(String nombre, String descripcion) {\n            this.nombre = nombre;\n            this.descripcion = descripcion;\n            this.fechaCreacion = new Date();\n        }\n\n        // Getters\n        public String getNombre() {\n            return nombre;\n        }\n\n        public String getDescripcion() {\n            return descripcion;\n        }\n\n        public Date getFechaCreacion() {\n            return fechaCreacion;\n        }\n\n        @Override\n        public String toString() {\n            return String.format(\"Tarea{nombre='%s', descripcion='%s', fecha=%s}\",\n                    nombre, descripcion, fechaCreacion);\n        }\n    }\n\n    // Gestor de tareas\n    static class GestorTareas {\n        private List<Tarea> tareas;\n        private Logger logger;\n\n        public GestorTareas() {\n            this.tareas = new ArrayList<>();\n            this.logger = Logger.getLogger(GestorTareas.class.getName());\n            configurarLogger();\n        }\n\n        private void configurarLogger() {\n            try {\n                // Crear handler para archivo\n                FileHandler fileHandler = new FileHandler(\"tareas.log\", true);\n                fileHandler.setFormatter(new SimpleFormatter());\n                logger.addHandler(fileHandler);\n\n                // Handler para consola\n                ConsoleHandler consoleHandler = new ConsoleHandler();\n                consoleHandler.setFormatter(new SimpleFormatter());\n                logger.addHandler(consoleHandler);\n\n                logger.setLevel(Level.ALL);\n\n            } catch (IOException e) {\n                System.err.println(\"Error configurando logger: \" + e.getMessage());\n            }\n        }\n\n        public void añadirTarea(String nombre, String descripcion) {\n            long inicio = System.currentTimeMillis();\n\n            logger.info(\"Iniciando proceso de añadir tarea: \" + nombre);\n\n            // Validaciones\n            if (nombre == null || nombre.trim().isEmpty()) {\n                logger.warning(\"Intento de añadir tarea con nombre vacío\");\n                throw new IllegalArgumentException(\"El nombre no puede estar vacío\");\n            }\n\n            // Verificar si ya existe\n            for (Tarea t : tareas) {\n                if (t.getNombre().equals(nombre)) {\n                    logger.warning(\"Intento de añadir tarea duplicada: \" + nombre);\n                    throw new IllegalArgumentException(\"La tarea ya existe\");\n                }\n            }\n\n            // Simular procesamiento\n            try {\n                Thread.sleep(100); // Simular trabajo\n            } catch (InterruptedException e) {\n                logger.severe(\"Proceso interrumpido al añadir tarea: \" + e.getMessage());\n                return;\n            }\n\n            Tarea nuevaTarea = new Tarea(nombre, descripcion);\n            tareas.add(nuevaTarea);\n\n            long fin = System.currentTimeMillis();\n            logger.info(String.format(\"Tarea '%s' añadida exitosamente en %d ms\",\n                    nombre, (fin - inicio)));\n            logger.fine(\"Detalles de la tarea: \" + nuevaTarea);\n        }\n\n        public boolean eliminarTarea(String nombre) {\n            long inicio = System.currentTimeMillis();\n\n            logger.info(\"Iniciando proceso de eliminar tarea: \" + nombre);\n\n            if (nombre == null || nombre.trim().isEmpty()) {\n                logger.warning(\"Intento de eliminar tarea con nombre vacío\");\n                return false;\n            }\n\n            Iterator<Tarea> iterator = tareas.iterator();\n            while (iterator.hasNext()) {\n                Tarea tarea = iterator.next();\n                if (tarea.getNombre().equals(nombre)) {\n                    iterator.remove();\n                    long fin = System.currentTimeMillis();\n                    logger.info(String.format(\"Tarea '%s' eliminada exitosamente en %d ms\",\n                            nombre, (fin - inicio)));\n                    logger.fine(\"Tarea eliminada: \" + tarea);\n                    return true;\n                }\n            }\n\n            long fin = System.currentTimeMillis();\n            logger.warning(String.format(\"Tarea '%s' no encontrada para eliminar (tiempo: %d ms)\",\n                    nombre, (fin - inicio)));\n            return false;\n        }\n\n        public void listarTareas() {\n            long inicio = System.currentTimeMillis();\n\n            logger.info(\"Iniciando listado de tareas\");\n            logger.finer(\"Número total de tareas: \" + tareas.size());\n\n            if (tareas.isEmpty()) {\n                logger.info(\"No hay tareas para mostrar\");\n                System.out.println(\"No hay tareas registradas.\");\n                return;\n            }\n\n            System.out.println(\"=== Lista de Tareas ===\");\n            for (int i = 0; i < tareas.size(); i++) {\n                Tarea tarea = tareas.get(i);\n                System.out.printf(\"%d. %s - %s%n\",\n                        i + 1, tarea.getNombre(), tarea.getDescripcion());\n                logger.finest(\"Mostrando tarea: \" + tarea.getNombre());\n            }\n\n            long fin = System.currentTimeMillis();\n            logger.info(String.format(\"Listado completado en %d ms (%d tareas mostradas)\",\n                    (fin - inicio), tareas.size()));\n        }\n    }\n\n    public static void ejemplosNivelesLog() {\n        System.out.println(\"=== Ejemplos de niveles de logging ===\");\n\n        // Configurar logger para mostrar todos los niveles\n        logger.setLevel(Level.ALL);\n\n        // Crear handler para ver todos los mensajes\n        ConsoleHandler handler = new ConsoleHandler();\n        handler.setLevel(Level.ALL);\n        handler.setFormatter(new SimpleFormatter());\n        logger.addHandler(handler);\n\n        // Ejemplos de cada nivel\n        logger.severe(\"SEVERE: Error crítico del sistema\");\n        logger.warning(\"WARNING: Situación que requiere atención\");\n        logger.info(\"INFO: Información general del proceso\");\n        logger.config(\"CONFIG: Información de configuración\");\n        logger.fine(\"FINE: Información detallada para debugging\");\n        logger.finer(\"FINER: Información más detallada para debugging\");\n        logger.finest(\"FINEST: Información muy detallada para debugging\");\n    }\n\n    public static void main(String[] args) {\n        // Ejemplos básicos de logging\n        ejemplosNivelesLog();\n\n        System.out.println(\"\\n=== DIFICULTAD EXTRA: Gestor de Tareas ===\");\n\n        GestorTareas gestor = new GestorTareas();\n        Scanner scanner = new Scanner(System.in);\n\n        while (true) {\n            System.out.println(\"\\n--- Menú ---\");\n            System.out.println(\"1. Añadir tarea\");\n            System.out.println(\"2. Eliminar tarea\");\n            System.out.println(\"3. Listar tareas\");\n            System.out.println(\"4. Salir\");\n            System.out.print(\"Seleccione una opción: \");\n\n            try {\n                int opcion = scanner.nextInt();\n                scanner.nextLine(); // Consumir el salto de línea\n\n                switch (opcion) {\n                    case 1:\n                        System.out.print(\"Nombre de la tarea: \");\n                        String nombre = scanner.nextLine();\n                        System.out.print(\"Descripción: \");\n                        String descripcion = scanner.nextLine();\n                        try {\n                            gestor.añadirTarea(nombre, descripcion);\n                            System.out.println(\"Tarea añadida exitosamente.\");\n                        } catch (Exception e) {\n                            System.out.println(\"Error: \" + e.getMessage());\n                        }\n                        break;\n\n                    case 2:\n                        System.out.print(\"Nombre de la tarea a eliminar: \");\n                        String nombreEliminar = scanner.nextLine();\n                        boolean eliminada = gestor.eliminarTarea(nombreEliminar);\n                        if (eliminada) {\n                            System.out.println(\"Tarea eliminada exitosamente.\");\n                        } else {\n                            System.out.println(\"Tarea no encontrada.\");\n                        }\n                        break;\n\n                    case 3:\n                        gestor.listarTareas();\n                        break;\n\n                    case 4:\n                        logger.info(\"Cerrando aplicación de gestión de tareas\");\n                        System.out.println(\"¡Hasta luego!\");\n                        scanner.close();\n                        return;\n\n                    default:\n                        logger.warning(\"Opción inválida seleccionada: \" + opcion);\n                        System.out.println(\"Opción inválida.\");\n                }\n            } catch (Exception e) {\n                logger.severe(\"Error inesperado en el menú principal: \" + e.getMessage());\n                System.out.println(\"Error: Entrada inválida.\");\n                scanner.nextLine(); // Limpiar buffer\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/25 - LOGS/java/JimsimroDev.java",
    "content": "import java.util.HashSet;\nimport java.util.Set;\nimport java.util.logging.ConsoleHandler;\nimport java.util.logging.FileHandler;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport java.util.logging.SimpleFormatter;\n\npublic class JimsimroDev {\n  private static final Logger logger = Logger.getLogger(JimsimroDev.class.getName());\n\n  static {\n    try {\n      FileHandler archivo = new FileHandler(\"miApp.log\", true);\n      archivo.setFormatter(new SimpleFormatter());\n      logger.addHandler(archivo);\n      logger.setLevel(Level.ALL);\n    } catch (Exception e) {\n      logger.severe(() -> \"No se pudo crear el FileHandler: \" + e.getMessage());\n    }\n  }\n\n  public void usoLogger() {\n    logger.setUseParentHandlers(false);\n\n    ConsoleHandler handler = new ConsoleHandler();\n    handler.setLevel(Level.ALL);\n    logger.addHandler(handler);\n\n    logger.config(\"Mensajes de Cofiguración\");\n\n    logger.info(\"información general\");\n\n    logger.fine(\"debug detallado\");\n\n    logger.finer(\"debug muy detallada\");\n\n    logger.finest(() -> \"debug más detallado\");\n\n    logger.warning(\"Este es un logger de warning\");\n\n    logger.severe(\"Error critico\");\n  }\n\n  interface TareaService {\n\n    void mostrarTareas();\n\n    void crearTarea(Tarea tarea);\n\n    void eliminarTarea(String titulo);\n  }\n\n  static class TareaServiceImpl implements TareaService {\n    static Set<Tarea> listaTareas = new HashSet<>();\n\n    @Override\n    public void mostrarTareas() {\n      listaTareas.stream().forEach(System.out::println);\n      logger.info(() -> \"Mostrando lista de tarea \\n\" + listaTareas);\n    }\n\n    @Override\n    public void crearTarea(Tarea tarea) {\n      if (listaTareas.stream().anyMatch(t -> t.titulo.equals(tarea.titulo))) {\n        logger.log(Level.SEVERE, String.format(\"La tarea %s ya existe \", tarea.titulo));\n        return;\n      }\n      listaTareas.add(tarea);\n      logger.info(() -> \"tarea creada \" + tarea.getTitulo());\n    }\n\n    @Override\n    public void eliminarTarea(String titulo) {\n      if (listaTareas.stream().anyMatch(t -> t.titulo.equals(titulo))) {\n        listaTareas.removeIf(t -> t.titulo.toLowerCase().contains(titulo.toLowerCase()));\n        logger.log(Level.INFO, String.format(\"La tarea %s se elimino\", titulo));\n        return;\n      }\n      logger.log(Level.SEVERE, String.format(\"La tarea %s no existe \", titulo));\n    }\n  }\n\n  static class Tarea {\n    private String titulo;\n    private String descripcion;\n\n    public Tarea() {\n    }\n\n    public String getTitulo() {\n      return titulo;\n    }\n\n    public void setTitulo(String titulo) {\n      this.titulo = titulo;\n    }\n\n    public String getDescripcion() {\n      return descripcion;\n    }\n\n    public void setDescripcion(String descripcion) {\n      this.descripcion = descripcion;\n    }\n\n    @Override\n    public String toString() {\n      return String.format(\" Tarea - Título: %s | Descripción: %s%n\", titulo, descripcion);\n    }\n  }\n\n  // Patron de diseño builder, crea objetos de tarea\n  static class TareaBuilder {\n    private String titulo;\n    private String descripcion;\n\n    public TareaBuilder setTitulo(String titulo) {\n      this.titulo = titulo;\n      return this;\n    }\n\n    public TareaBuilder setDescripcion(String descripcion) {\n      this.descripcion = descripcion;\n      return this;\n    }\n\n    public Tarea build() {\n      Tarea t = new Tarea();\n      t.setTitulo(this.titulo);\n      t.setDescripcion(this.descripcion);\n      return t;\n    }\n  }\n\n  public static void main(String[] args) {\n    new JimsimroDev().usoLogger();\n\n    var listaTarea = new TareaServiceImpl();\n\n    Tarea tarea1 = new TareaBuilder()\n        .setTitulo(\"Comprar alimentos\")\n        .setDescripcion(\"Ir al supermercado y comprar leche,pan,frutas\")\n        .build();\n    listaTarea.crearTarea(tarea1);\n\n    Tarea tarea2 = new TareaBuilder()\n        .setTitulo(\"Lavar la ropa\")\n        .setDescripcion(\"Separar ropa blanca y de color, lavar y tender\")\n        .build();\n    listaTarea.crearTarea(tarea2);\n\n    Tarea tarea3 = new TareaBuilder()\n        .setTitulo(\"Sacar la basura\")\n        .setDescripcion(\"Sacar los residuos orgánicos y reciclables\")\n        .build();\n    listaTarea.crearTarea(tarea3);\n\n    Tarea tarea4 = new TareaBuilder()\n        .setTitulo(\"Pagar facturas\")\n        .setDescripcion(\"Pagar la luz, agua e internet antes del fin de semana\")\n        .build();\n    listaTarea.crearTarea(tarea4);\n\n    Tarea tarea5 = new TareaBuilder()\n        .setTitulo(\"Pagar facturas\")\n        .setDescripcion(\"Agendar cita de revisión anual\")\n        .build();\n    listaTarea.crearTarea(tarea5);\n\n    listaTarea.mostrarTareas();\n    listaTarea.eliminarTarea(\"Sacar la basura\");\n    listaTarea.mostrarTareas();\n  }\n}\n"
  },
  {
    "path": "Roadmap/25 - LOGS/java/Josegs95.java",
    "content": "import java.util.HashMap;\nimport java.util.Map;\nimport java.util.Random;\nimport java.util.logging.ConsoleHandler;\nimport java.util.logging.Handler;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\n\npublic class Josegs95 {\n    private static final Logger logger = Logger.getLogger(Josegs95.class.getName());\n\n    public static void main(String[] args) {\n        //Ejercicio\n        //Desactivo el uso de los handlers por defecto para que no salga duplicado\n        //los mensajes por consola\n        logger.setUseParentHandlers(false);\n\n        Handler consoleHandler = new ConsoleHandler();\n        logger.setLevel(Level.ALL); //Le digo que maneje todos los tipos de mensajes\n        consoleHandler.setLevel(Level.ALL); //Idem, pero en concreto al handler que muestra por consola\n        logger.addHandler(consoleHandler);\n\n//        System.out.println(\"Tipos de mensaje 'logging' de mas leve a mas grave:\");\n//        logger.finest(\"Mensaje Finest\");\n//        logger.finer(\"Mensaje Finer\");\n//        logger.fine(\"Mensaje Fine\");\n//        logger.config(\"Mensaje Config\");\n//        logger.info(\"Mensaje Info\");\n//        logger.warning(\"Mensaje Warning\");\n//        logger.severe(\"Mensaje Severe\");\n\n        //Reto\n        retoFinal();\n    }\n\n    private static Random rnd;\n    private static Map<String, String> taskMap;\n\n    public static void retoFinal(){\n        rnd = new Random();\n        taskMap = new HashMap<>();\n\n        addTask(\"Limpiar\", \"Limpiar la casa\");\n        addTask(\"Cocinar\", \"Preparar el almuerzo\");\n        addTask(\"Comprar\", \"Comprar lo que haga falta\");\n        addTask(\"Lavadora\", \"Hacer una lavadora\");\n\n        showTasks();\n\n        deleteTask(\"Afeitarse\");\n        deleteTask(\"Comprar\");\n\n        showTasks();\n    }\n\n    private static void addTask(String name, String description){\n        long start = System.currentTimeMillis();\n        try{\n            Thread.sleep(rnd.nextInt(3) * 1000);\n            taskMap.put(name, description);\n            logger.fine(\"Tarea \" + name + \" añadida correctamente.\");\n        } catch (InterruptedException e) {\n            logger.warning(e.getMessage());\n        }\n        long end = System.currentTimeMillis();\n        logger.finest(String.format(\"Tiempo de ejecución %.4fs.\", (end - start) / 1000.0));\n    }\n\n    private static void deleteTask(String name){\n        long start = System.currentTimeMillis();\n        try{\n            Thread.sleep(rnd.nextInt(3) * 1000);\n            if (taskMap.get(name) == null){\n                logger.info(\"No se ha borrado la tarea \" + name + \" porque no existe en el registro\");\n                return;\n            }\n            taskMap.remove(name);\n            logger.fine(\"Tarea \" + name + \" añadida correctamente.\");\n        } catch (InterruptedException e) {\n            logger.warning(e.getMessage());\n        }\n        long end = System.currentTimeMillis();\n        logger.finest(String.format(\"Tiempo de ejecución %.4fs.\", (end - start) / 1000.0));\n    }\n\n    private static void showTasks(){\n        long start = System.currentTimeMillis();\n        if (taskMap.size() == 0){\n            logger.info(\"El registro de tareas está vacío\");\n            return;\n        }\n        try{\n            Thread.sleep(rnd.nextInt(3) * 1000);\n            for(Map.Entry<String, String> entry : taskMap.entrySet())\n                System.out.println(\"Tarea: \" + entry.getKey() + \", \" + entry.getValue());\n        } catch (InterruptedException e) {\n            logger.warning(e.getMessage());\n        }\n        long end = System.currentTimeMillis();\n        logger.finest(String.format(\"Tiempo de ejecución %.4fs.\", (end - start) / 1000.0));\n    }\n}\n"
  },
  {
    "path": "Roadmap/25 - LOGS/java/danhingar.java",
    "content": "import java.text.SimpleDateFormat;\nimport java.time.Duration;\nimport java.time.LocalTime;\nimport java.util.Date;\nimport java.util.HashSet;\nimport java.util.Set;\nimport java.util.logging.ConsoleHandler;\nimport java.util.logging.Formatter;\nimport java.util.logging.Handler;\nimport java.util.logging.Level;\nimport java.util.logging.LogRecord;\nimport java.util.logging.Logger;\n\npublic class danhingar {\n    private final static Logger log = Logger.getLogger(danhingar.class.getName());\n\n    public static void main(String[] args) {\n\n        configLog();\n\n        log.info(\"LOG INFO\");\n        log.warning(\"LOG WARNING\");\n        log.severe(\"LOG SEVERE\");\n        log.config(\"LOG CONFIG\");\n        log.fine(\"LOG FINE\");\n        log.finest(\"LOG FINEST\");\n        log.finer(\"LOG FINER\");\n\n        TaskManager taskManager = new TaskManager();\n        taskManager.listTasks();\n        taskManager.addTask(\"Pan\", \"Comprar 5 barras de pan\");\n        taskManager.addTask(\"Python\", \"Estudiar Python\");\n        taskManager.listTasks();\n        taskManager.deleteTask(\"Python\");\n        taskManager.listTasks();\n        taskManager.addTask(\"Pan\", \"Comprar 5 barras de pan\");\n        taskManager.deleteTask(\"Python\");\n        taskManager.addTask(\"Task1\", \"Busqueda\");\n    }\n\n    static void configLog() {\n\n        ConsoleHandler consoleHandler = new ConsoleHandler();\n        consoleHandler.setLevel(Level.ALL);\n\n        consoleHandler.setFormatter(new CustomFormatter());\n\n        log.addHandler(consoleHandler);\n\n        log.setLevel(Level.ALL);\n\n        // Eliminando los handler existentes\n        Logger parentLogger = log.getParent();\n        for (Handler handler : parentLogger.getHandlers()) {\n            parentLogger.removeHandler(handler);\n        }\n\n    }\n\n}\n\nclass CustomFormatter extends Formatter {\n    @Override\n    public String format(LogRecord record) {\n        // Formato personalizado: timestamp - level - mensaje\n        String timestamp = new SimpleDateFormat(\"yyyy-MM-dd HH:mm:ss\").format(new Date(record.getMillis()));\n        String level = record.getLevel().getName();\n        String message = formatMessage(record);\n\n        return String.format(\"%s - %s - %s%n\", timestamp, level, message);\n    }\n}\n\n// EXTRA\nclass TaskManager {\n\n    private final static Logger log = Logger.getLogger(danhingar.class.getName());\n\n    private Set<Task> tasks;\n\n    public TaskManager() {\n        tasks = new HashSet<>();\n    }\n\n    public void addTask(String name, String description) {\n        LocalTime start = LocalTime.now();\n        if (tasks.stream().anyMatch(t -> t.getName().equals(name))) {\n            log.warning(String.format(\"Se ha intentado añadir una tarea que ya existe: %s\", name));\n        }\n        Task task = new Task(name, description);\n        tasks.add(task);\n        log.info(String.format(\"Tarea añadida: %s\", name));\n        log.fine(String.format(\"Número de tareas: %d\", tasks.size()));\n        LocalTime end = LocalTime.now();\n        printTime(start, end);\n    }\n\n    public void listTasks() {\n        LocalTime start = LocalTime.now();\n        if (tasks.size() > 0) {\n            log.info(\"Se va a imprimir el listado de tareas\");\n            for (Task task : tasks) {\n                System.out.println(task.toString());\n            }\n        } else {\n            log.info(\"No hay tareas para mostrar.\");\n        }\n        LocalTime end = LocalTime.now();\n        printTime(start, end);\n\n    }\n\n    public void deleteTask(String name) {\n        LocalTime start = LocalTime.now();\n        if (!tasks.stream().anyMatch(t -> t.getName().equals(name))) {\n            log.warning(String.format(\"Se ha intentado eliminar una tarea que no existe:\", name));\n        } else {\n            tasks.remove(tasks.stream().filter(t -> t.getName().equals(name)).findFirst().get());\n            log.info(String.format(\"Se ha eliminado la tarea: %s\", name));\n            log.fine(String.format(\"Número de tareas: %d\", tasks.size()));\n        }\n        LocalTime end = LocalTime.now();\n        printTime(start, end);\n\n    }\n\n    private void printTime(LocalTime start, LocalTime end) {\n        float time = (float) Duration.between(start, end).toNanos()/1000000000;\n        log.finest(String.format(\"Tiempo de ejecución: %.6f\", time));\n    }\n\n    static void configLog() {\n\n        ConsoleHandler consoleHandler = new ConsoleHandler();\n        consoleHandler.setLevel(Level.ALL);\n\n        consoleHandler.setFormatter(new CustomFormatter());\n\n        log.addHandler(consoleHandler);\n\n        log.setLevel(Level.ALL);\n\n        // Eliminando los handler existentes\n        Logger parentLogger = log.getParent();\n        for (Handler handler : parentLogger.getHandlers()) {\n            parentLogger.removeHandler(handler);\n        }\n\n    }\n}\n\nclass Task {\n    private String name;\n    private String description;\n\n    public Task(String name, String description) {\n        this.name = name;\n        this.description = description;\n    }\n\n    @Override\n    public String toString() {\n        return \"Task [name=\" + name + \", description=\" + description + \"]\";\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public String getDescription() {\n        return description;\n    }\n\n    public void setDescription(String description) {\n        this.description = description;\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/25 - LOGS/java/eulogioep.java",
    "content": "/**\n * Implementación de un sistema de logging y gestión de tareas en Java.\n * \n * TEORÍA SOBRE LOGGING EN JAVA:\n * Java proporciona un framework de logging nativo (java.util.logging) que ofrece:\n * - Diferentes niveles de severidad (SEVERE, WARNING, INFO, etc.)\n * - Capacidad de escribir en múltiples destinos (consola, archivo)\n * - Formato personalizable de mensajes\n * - Filtros y handlers configurables\n * \n * Niveles de logging en java.util.logging:\n * - SEVERE: Para errores críticos\n * - WARNING: Para advertencias\n * - INFO: Para información general\n * - CONFIG: Para mensajes de configuración\n * - FINE, FINER, FINEST: Para depuración con diferentes niveles de detalle\n */\n\n import java.io.IOException;\n import java.time.LocalDateTime;\n import java.time.format.DateTimeFormatter;\n import java.util.ArrayList;\n import java.util.List;\n import java.util.logging.*;\n import java.util.stream.Collectors;\n \n public class eulogioep {\n     /**\n      * Clase para manejar el logging personalizado\n      */\n     static class CustomLogger {\n         private static final Logger LOGGER = Logger.getLogger(CustomLogger.class.getName());\n         \n         static {\n             try {\n                 // Configurar el logger para escribir en un archivo\n                 FileHandler fileHandler = new FileHandler(\"tareas.log\", true);\n                 fileHandler.setFormatter(new SimpleFormatter());\n                 LOGGER.addHandler(fileHandler);\n                 \n                 // Configurar el logger para escribir en consola\n                 ConsoleHandler consoleHandler = new ConsoleHandler();\n                 consoleHandler.setFormatter(new SimpleFormatter());\n                 LOGGER.addHandler(consoleHandler);\n                 \n                 // Establecer el nivel de logging\n                 LOGGER.setLevel(Level.ALL);\n             } catch (IOException e) {\n                 e.printStackTrace();\n             }\n         }\n         \n         public static void severe(String message) {\n             LOGGER.severe(formatMessage(message));\n         }\n         \n         public static void warning(String message) {\n             LOGGER.warning(formatMessage(message));\n         }\n         \n         public static void info(String message) {\n             LOGGER.info(formatMessage(message));\n         }\n         \n         public static void config(String message) {\n             LOGGER.config(formatMessage(message));\n         }\n         \n         public static void fine(String message) {\n             LOGGER.fine(formatMessage(message));\n         }\n         \n         private static String formatMessage(String message) {\n             return String.format(\"[%s] %s\",\n                 LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME),\n                 message);\n         }\n     }\n     \n     /**\n      * Clase que representa una tarea\n      */\n     static class Task {\n         private final String name;\n         private final String description;\n         private final LocalDateTime createdAt;\n         \n         public Task(String name, String description) {\n             this.name = name;\n             this.description = description;\n             this.createdAt = LocalDateTime.now();\n         }\n         \n         public String getName() {\n             return name;\n         }\n         \n         public String getDescription() {\n             return description;\n         }\n         \n         public LocalDateTime getCreatedAt() {\n             return createdAt;\n         }\n         \n         @Override\n         public String toString() {\n             return String.format(\"Tarea: %s - %s (Creada: %s)\",\n                 name,\n                 description,\n                 createdAt.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));\n         }\n     }\n     \n     /**\n      * Clase para la gestión de tareas\n      */\n     static class TaskManager {\n         private final List<Task> tasks;\n         \n         public TaskManager() {\n             this.tasks = new ArrayList<>();\n         }\n         \n         /**\n          * Mide el tiempo de ejecución de una operación\n          */\n         private void measureExecutionTime(Runnable operation, String operationName) {\n             long startTime = System.nanoTime();\n             try {\n                 operation.run();\n                 long endTime = System.nanoTime();\n                 double executionTime = (endTime - startTime) / 1_000_000.0; // Convertir a millisegundos\n                 CustomLogger.fine(String.format(\"Tiempo de ejecución %s: %.2fms\", \n                     operationName, executionTime));\n             } catch (Exception e) {\n                 CustomLogger.severe(String.format(\"Error en %s: %s\", \n                     operationName, e.getMessage()));\n             }\n         }\n         \n         /**\n          * Añade una nueva tarea\n          */\n         public void addTask(String name, String description) {\n             measureExecutionTime(() -> {\n                 // Verificar si ya existe una tarea con el mismo nombre\n                 if (tasks.stream().anyMatch(t -> t.getName().equals(name))) {\n                     CustomLogger.warning(String.format(\"La tarea '%s' ya existe\", name));\n                     return;\n                 }\n                 \n                 Task task = new Task(name, description);\n                 tasks.add(task);\n                 CustomLogger.info(String.format(\"Tarea '%s' añadida exitosamente\", name));\n             }, \"addTask\");\n         }\n         \n         /**\n          * Elimina una tarea por su nombre\n          */\n         public void removeTask(String name) {\n             measureExecutionTime(() -> {\n                 int initialSize = tasks.size();\n                 tasks.removeIf(task -> task.getName().equals(name));\n                 \n                 if (tasks.size() == initialSize) {\n                     CustomLogger.warning(String.format(\"No se encontró la tarea '%s'\", name));\n                 } else {\n                     CustomLogger.info(String.format(\"Tarea '%s' eliminada exitosamente\", name));\n                 }\n             }, \"removeTask\");\n         }\n         \n         /**\n          * Lista todas las tareas existentes\n          */\n         public void listTasks() {\n             measureExecutionTime(() -> {\n                 if (tasks.isEmpty()) {\n                     CustomLogger.info(\"No hay tareas registradas\");\n                     return;\n                 }\n                 \n                 CustomLogger.info(\"Lista de tareas:\");\n                 tasks.forEach(task -> CustomLogger.info(\"- \" + task.toString()));\n             }, \"listTasks\");\n         }\n     }\n     \n     /**\n      * Método principal para demostrar el uso del sistema\n      */\n     public static void main(String[] args) {\n         CustomLogger.info(\"Iniciando sistema de gestión de tareas\");\n         \n         // Demostración de diferentes niveles de logging\n         CustomLogger.severe(\"Ejemplo de mensaje SEVERE\");\n         CustomLogger.warning(\"Ejemplo de mensaje WARNING\");\n         CustomLogger.info(\"Ejemplo de mensaje INFO\");\n         CustomLogger.config(\"Ejemplo de mensaje CONFIG\");\n         CustomLogger.fine(\"Ejemplo de mensaje FINE\");\n         \n         // Crear instancia del gestor de tareas\n         TaskManager taskManager = new TaskManager();\n         \n         // Ejemplos de uso del sistema\n         taskManager.addTask(\"Estudiar Java\", \"Aprender sobre logging y POO\");\n         taskManager.addTask(\"Hacer ejercicio\", \"30 minutos de cardio\");\n         taskManager.addTask(\"Estudiar Java\", \"Tarea duplicada\"); // Intentar añadir duplicada\n         taskManager.listTasks();\n         taskManager.removeTask(\"Estudiar Java\");\n         taskManager.listTasks();\n         taskManager.removeTask(\"Tarea inexistente\");\n         \n         CustomLogger.info(\"Finalizando sistema de gestión de tareas\");\n     }\n }"
  },
  {
    "path": "Roadmap/25 - LOGS/java/martinbohorquez.java",
    "content": "import java.time.Duration;\nimport java.time.LocalTime;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.logging.*;\n\npublic class martinbohorquez {\n    private static final Logger logger = Logger.getLogger(martinbohorquez.class.getName());\n\n    public static void main(String[] args) {\n        loggerLevel();\n        /*\n         * DIFICULTAD EXTRA\n         */\n        Task task1 = new Task(\"tarea 1\", \"Diseño de BBDD\");\n        Task task2 = new Task(\"tarea 2\", \"Desarrollo de API\");\n        Task task4 = new Task(\"tarea 2\", \"Conexión a la BBDD\");\n        Task task3 = new Task(\"tarea 3\", \"Despliegue en AWS\");\n\n        TaskManager tm = new TaskManager();\n        tm.listTask();\n        tm.addTask(task1)\n                .addTask(task2)\n                .addTask(task4)\n                .addTask(task3);\n        tm.listTask();\n        tm.deleteTask(\"tarea 2\");\n        tm.listTask();\n        tm.deleteTask(\"tarea 2\");\n        tm.listTask();\n\n\n    }\n\n    private static void loggerLevel() {\n        // Eliminar manejadores predeterminados\n        for (Handler handler : logger.getHandlers()) {\n            logger.removeHandler(handler);\n        }\n        // Configuración del logger\n        ConsoleHandler consoleHandler = new ConsoleHandler();\n        consoleHandler.setLevel(Level.ALL);\n        consoleHandler.setFormatter(new SimpleFormatter() {\n            @Override\n            public synchronized String format(LogRecord lr) {\n                return String.format(\"%1$tF %1$tT - %2$s - %3$s%n\", lr.getMillis(), lr.getLevel(), lr.getMessage());\n            }\n        });\n        logger.addHandler(consoleHandler);\n        logger.setLevel(Level.ALL);\n\n        // Eliminar manejadores de loggers padres\n        Logger parentLogger = logger.getParent();\n        for (Handler handler : parentLogger.getHandlers()) {\n            parentLogger.removeHandler(handler);\n        }\n\n        // Mensajes de log\n        logger.fine(\"Esto es un mensaje de FINE\");\n        logger.finer(\"Esto es un mensaje de FINER\");\n        logger.finest(\"Esto es un mensaje de FINEST\");\n        logger.config(\"Esto es un mensaje de CONFIG\");\n        logger.info(\"Esto es un mensaje de INFO\");\n        logger.warning(\"Esto es un mensaje de WARNING\");\n        logger.severe(\"Esto es un mensaje de SEVERE\");\n        logger.log(Level.OFF, \"Esto es un mensaje de OFF\");\n    }\n\n    private record Task(String name, String description) {\n\n        @Override\n        public String toString() {\n            return \"Task{name='\" + name + \"', description='\" + description + \"'}\";\n        }\n    }\n\n    private static class TaskManager {\n        private final List<Task> taskSet;\n\n        public TaskManager() {\n            this.taskSet = new LinkedList<>();\n        }\n\n        private TaskManager addTask(Task task) {\n            List<String> taskNames = taskSet.stream().map(Task::name).toList();\n            LocalTime startTime = LocalTime.now();\n            if (!taskNames.contains(task.name())) {\n                taskSet.add(task);\n                logger.info(\"Tarea añadida: \" + task);\n            } else logger.warning(\"Se ha intentado añadir una tarea que ya existe!\");\n            logger.fine(\"Número de tareas: \" + taskSet.size());\n            LocalTime endtTime = LocalTime.now();\n            printExecutionTime(startTime, endtTime);\n            return this;\n        }\n\n        private void deleteTask(String name) {\n            List<String> taskNames = taskSet.stream().map(Task::name).toList();\n            LocalTime startTime = LocalTime.now();\n            if (taskNames.contains(name)) {\n                this.taskSet.removeIf(t -> t.name().equals(name));\n                logger.info(\"Tarea eliminada: \" + name);\n            } else logger.severe(\"Se ha intentado eliminar una tarea que no existe: \" + name);\n            logger.fine(\"Número de tareas: \" + taskSet.size());\n            LocalTime endtTime = LocalTime.now();\n            printExecutionTime(startTime, endtTime);\n        }\n\n        private void listTask() {\n            LocalTime startTime = LocalTime.now();\n            if (!taskSet.isEmpty()) {\n                logger.info(\"Se va imprimir la lista de tareas.\");\n                this.taskSet.forEach(System.out::println);\n            } else logger.warning(\"No hay tareas para mostrar!\");\n            LocalTime endtTime = LocalTime.now();\n            printExecutionTime(startTime, endtTime);\n        }\n\n        private void printExecutionTime(LocalTime startTime, LocalTime endtTime) {\n            float time = (float) Duration.between(startTime, endtTime).toNanos() / (1000 * 1000);\n            System.out.printf(\"El tiempo de ejecución es: %.3f%n\", time);\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/25 - LOGS/java/simonguzman.java",
    "content": "\nimport java.util.ArrayList;\nimport java.util.InputMismatchException;\nimport java.util.List;\nimport java.util.Scanner;\nimport java.util.concurrent.TimeUnit;\nimport java.util.logging.ConsoleHandler;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\n\npublic class simonguzman{\n    public static void main(String[] args) {\n        sintaxisLogger();\n        exampleLog();\n        advancedLoggingExample();\n        adittionalExercise();\n    }\n    /************************ ejercicio adicional************************/\n    public static void adittionalExercise(){\n        List<Task> tasks = new ArrayList<>();\n        Logger logger = Logger.getLogger(simonguzman.class.getName());\n        Scanner sc = new Scanner(System.in);\n        int option = 0;\n        do{\n            menu();\n            System.out.println(\"Ingrese una opcion\");\n            try {\n                option = sc.nextInt();\n                sc.nextLine();\n                optionsMenu(option, sc, tasks, logger);\n            } catch (InputMismatchException e) {\n                System.out.println(\"ERROR: Entrada invalida, solo ingresar valores numericos\");\n                sc.next();\n            }\n        }while(option != 4);    \n        sc.close();\n    }\n\n    public static void optionsMenu(int option, Scanner sc, List<Task> tasks, Logger logger){\n        \n        switch (option) {\n            case 1:\n                addTaskMenu(sc, tasks, logger);\n                break;\n            case 2:\n                removeTaskMenu(sc, tasks, logger);\n                break;\n            case 3:\n                listTasks(tasks, logger);\n                break;\n            case 4:\n                outSystem();\n                break;\n            default:\n                System.out.println(\"ERROR: Opcion no valida...\");\n        }\n    }\n\n    public static void outSystem(){\n        System.out.println(\"Saliendo....\");\n    }\n\n    public static void menu(){\n        System.out.println(\"------------Gestion de tareas------------\");\n        System.out.println(\"1. Añadir tarea\");\n        System.out.println(\"2. Eliminar tarea\");\n        System.out.println(\"3. Listar tareas\");\n        System.out.println(\"4. Salir\");\n    }\n\n    public static void addTaskMenu(Scanner sc, List<Task> tasks, Logger logger){\n        System.out.print(\"Introduce el nombre de la tarea: \");\n        String name = sc.next();\n        System.out.print(\"Introduce la descripción de la tarea: \");\n        String description = sc.next();\n        addTask(name, description, tasks, logger);\n    }\n\n    public static void removeTaskMenu(Scanner sc, List<Task> tasks, Logger logger){\n        System.out.println(\"Introduce el nombre de la tarea a eliminar: \");\n        String name = sc.next();\n        removeTask(name, tasks, logger);\n    }\n\n    public static void addTask(String name, String description, List<Task> tasks, Logger logger){\n        long startTime = System.currentTimeMillis();\n        Task task = new Task(name, description);\n        tasks.add(task);\n        logger.info(\"Tarea añadida: \"+task.getName()+ \", Description: \"+task.getDescription());\n        long endTime = System.currentTimeMillis();\n        logger.info(\"Tiempo de ejecucion para añadir la tarea: \"+(endTime - startTime));\n    }\n\n    public static  void removeTask(String name, List<Task> tasks, Logger logger){\n        long startTime = System.currentTimeMillis();\n        boolean removed = tasks.removeIf(task -> task.getName().equalsIgnoreCase(name));\n        if(removed){\n            logger.info(\"Tarea eliminada: \"+name);\n        }else{\n            logger.warning(\"No se encontro la tarea con nombre: \"+name);\n        }\n        long endTime = System.currentTimeMillis();\n        logger.info(\"Tiempo de ejecucion para eliminar la tarea: \"+(endTime - startTime)+ \" ms\");\n    }\n\n    public static void listTasks(List<Task> tasks, Logger logger) {\n        long startTime = System.currentTimeMillis();\n        if(tasks.isEmpty()){\n            logger.warning(\"No hay tareas para listar.\");\n        }else{\n            logger.info(\"Listado de tareas: \");\n            tasks.forEach(task -> logger.info(task.toString()));\n        }\n        long endTime = System.currentTimeMillis();\n        logger.info(\"Tiempo de ejecucion para listar tareas \" +(endTime - startTime)+ \" ms\");\n    }\n\n    static class Task{\n        private String name;\n        private String description;\n\n        public Task(){\n\n        }\n\n        public Task(String name, String description){\n            this.name = name;\n            this.description = description;\n        }\n\n        public String getName() {\n            return name;\n        }\n\n        public String getDescription() {\n            return description;\n        }\n\n        @Override\n        public String toString() {\n            return \"Tarea: \"+ name +\", Descripcion: \"+description;\n        }\n        \n    }\n    /************************ ejemplo del log mas avanzado************************/\n    public static void advancedLoggingExample(){\n        Logger logger = Logger.getLogger(simonguzman.class.getName());\n        logger.setLevel(Level.ALL);\n        try {\n            startTask(\"Tarea 1\");\n            TimeUnit.SECONDS.sleep(2);\n            endTask(\"Tarea 1\");\n            \n            startTask(\"Tarea 2\");\n            TimeUnit.SECONDS.sleep(1);\n            endTask(\"Tarea 2\");\n        } catch (InterruptedException e) {\n            logger.severe(\"Error en la ejecucion de las tareas...\"+e.getMessage());\n        }\n    }\n\n    public static void startTask(String taskName){\n        System.out.println(\"Iniciando \"+taskName);\n    }\n\n    public static void endTask(String taskName){\n        System.out.println(\"Finalizando \"+taskName);\n    }\n    /************************ ejemplo del log************************/\n    public static void exampleLog(){\n        Logger logger = Logger.getLogger(simonguzman.class.getName());\n        logger.setLevel(Level.ALL);\n\n        // Configuracion del handler para que se acepten todos los niveles\n        ConsoleHandler handler = new ConsoleHandler();\n        handler.setLevel(Level.ALL);\n        logger.addHandler(handler);\n\n        logger.info(\"Inicio del programa.\");\n        logger.config(\"Configuracion de la aplicacion completada.\");\n\n        try {\n            int result = split(10, 2, logger);\n            logger.info(\"Resultado de la division: \"+result);\n\n            result = split(10, 0, logger);\n            logger.info(\"Resultado de la segunda division: \"+result);\n\n        } catch (ArithmeticException e) {\n            logger.severe(\"ERROR: Division por cero...\"+e.getMessage());\n        }\n\n        logger.fine(\"Operaciones menores completadas.\");\n        logger.finer(\"Nivel de depuracion mas detallado\");\n        logger.finest(\"Nivel de depuracion mas minucioso\");\n        logger.warning(\"Advertencia: fin del programa\");\n    }\n    \n    public static int split(int num1, int num2, Logger logger){\n        logger.fine(\"Dividiendo \"+num1+\" entre \"+num2);\n        return num1 / num2;\n    }\n\n\n    /************************ Sintaxis del log************************/\n    static void sintaxisLogger(){\n        //Creacion del logger\n        Logger logger = Logger.getLogger(simonguzman.class.getName());\n        //Habilitar todos los niveles de registro\n        logger.setLevel(Level.ALL);\n        logger.severe(\"Mensaje de nivel SEVERE\");\n        logger.warning(\"Mensaje de nivel WARNING\");\n        logger.info(\"Mensaje de nivel INFO\");\n        logger.config(\"Mensaje de nivel CONFIG\");\n        logger.fine(\"Mensaje de nivel FINE\");\n        logger.finer(\"Mensaje de nivel FINER\");\n        logger.finest(\"Mensaje de nivel FINEST\");\n    }\n}"
  },
  {
    "path": "Roadmap/25 - LOGS/javascript/AChapeton.js",
    "content": "// Mensaje de texto generico\nconsole.log('Mensaje general')\n\n// Mensaje informativo\nconsole.info('Mensaje informativo')\n\n// Mensaje de advertencia\nconsole.warn('Mensaje de advertencia')\n\n// Mensaje de error\nconsole.error('Mensaje de error')\n\n// Limpiar consola\nconsole.clear()\n\n// Grupo de mensajes\nconsole.group('Titulo del grupo de logs')\nconsole.log('Primera linea')\nconsole.info('Segunda linea')\nconsole.error('Tercera linea')\nconsole.groupEnd()\n\n// Logs para tomar tiempo de procesos\nconsole.time('Inicio de proceso')\n  // Proceso para testear\nconsole.timeEnd()\n\n// Tablas\nconsole.table([\"manzanas\", \"peraas\", \"bananas\"]);"
  },
  {
    "path": "Roadmap/25 - LOGS/javascript/Chrisdev00.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de \"logging\" en tu lenguaje. Configúralo y muestra\n * un ejemplo con cada nivel de \"severidad\" disponible.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa ficticio de gestión de tareas que permita añadir, eliminar\n * y listar dichas tareas.\n * - Añadir: recibe nombre y descripción.\n * - Eliminar: por nombre de la tarea.\n * Implementa diferentes mensajes de log que muestren información según la \n * tarea ejecutada (a tu elección).\n * Utiliza el log para visualizar el tiempo de ejecución de cada tarea. \n */\n\n\n// instalar la biblioteca de logging 'winston'\n\nconst winston = require('winston')\n\nconst logger1 = winston.createLogger({\n    level: 'debug',\n    format: winston.format.json(),\n    transports: [\n        new winston.transports.Console(),\n        new winston.transports.File({filename: 'app.log'}),\n    ]\n})\n\nlogger1.info(\"An info log\")\nlogger1.error(\"An error log\")\n\n\n\n/////////////// --------------------------------- EXTRA ---------------------------------- ///////////////////\n\nconst readline = require('readline');\nconst winston = require('winston');\nconst { format } = require('path');\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\n// configuracion del logger con winston\n\nconst logger = winston.createLogger({\n    level: 'debug',\n    format: winston.format.combine(\n        winston.format.timestamp({format: 'YYYY-MM-DD HH:mm:ss' }),\n        winston.format.printf(({ timestamp, level, message}) => {\n            return `${timestamp} - ${level.toUpperCase()} - ${message}`;\n        })\n    ),\n    transports: [\n        new winston.transports.Console(),\n        new winston.transports.File({ filename: 'test.log' })\n    ]\n});\n\n\nclass TaskManager {\n    constructor() {\n        this.tasks = {};\n        logger.info(\"Gestor de Tareas inicializado.\");\n    }\n\n    addTask() {\n        rl.question(\"Ingrese el nombre de la tarea: \", name => {\n            rl.question(\"Ingrese la descripción de la tarea: \", description => {\n                if (this.tasks[name]) {\n                    logger.warn(`Intento de añadir una tarea ya existente: ${name}`);\n                    return;\n                }\n                const execution_time = Math.floor(Math.random() * 5) + 1;\n                this.tasks[name] = {\n                    description,\n                    execution_time\n                };\n                logger.info(`Tarea '${name}' añadida.`);\n                logger.debug(`Tiempo de ejecución de la tarea '${name}': ${execution_time} segundos.`);\n            });\n        });\n    }\n\n    deleteTask() {\n        rl.question(\"Ingrese el nombre de la tarea a eliminar: \", name => {\n            if (!this.tasks[name]) {\n                logger.warn(`Intento de eliminar una tarea inexistente: ${name}`);\n                return;\n            }\n            delete this.tasks[name];\n            logger.info(`Tarea '${name}' eliminada.`);\n        });\n    }\n\n    listTasks() {\n        if (Object.keys(this.tasks).length === 0) {\n            logger.info(\"No hay tareas para listar.\");\n            return;\n        }\n        for (const [name, info] of Object.entries(this.tasks)) {\n            console.log(`Tarea: ${name} - Descripción: ${info.description} - Tiempo de ejecución: ${info.execution_time} segundos`);\n            logger.info(`Tiempo de ejecución de la tarea '${name}' es ${info.execution_time} segundos.`);\n        }\n    }\n}\n\n\nconst manager = new TaskManager();\n\nfunction mainMenu(){\n    rl.question(\"\\nGestor de Tareas\\n1. Añadir Tarea\\n2. Eliminar Tarea\\n3. Listar Tareas\\n4. Salir\\n Seleccione una opcion: \", choice => {\n        if (choice === '1'){\n            manager.addTask();\n        }else if (choice === '2'){\n            manager.deleteTask();\n        }else if (choice === '3'){\n            manager.listTasks();\n        }else if (choice === '4'){\n            rl.close();\n            return;\n        }else{\n            logger.error(\"Opción no válida, por favor intente nuevamente.\");\n        }\n        mainMenu();\n    });\n}\n\nmainMenu();\n"
  },
  {
    "path": "Roadmap/25 - LOGS/javascript/DavidMoralesDeveloper.js",
    "content": "// console.warn(), console.error(), console.info() console.log(first)\n\n// El Tiempo de ejecución\nconsole.time('Se ejecuto el programa tiempo:');\n// Errror\nlet error = new Error(\"error en la coneccion\")\nconsole.warn(\"fallo en el internet\")\nconsole.error(`Error grave: ${error} `)\n\n\n\n\n\n//table\nconst tabla = [1,2,3,4]\ntabla.map(num => console.table(num))\n//count\nfunction countData(item){\n    console.count(\"some data\")\n}\n countData(\"item1\")\n countData(\"item2\")\n countData(\"item3\")\nconsole.count(\"comenzar un nuevo contador\")\n\ncountData(\"nuevoItem1\")\ncountData(\"nuevoItem2\")\nconsole.count(\"comenzar un nuevo contador\")\n\nconsole.countReset(\"some data\"); // Resets the \"some data\" counter de mu funcion \ncountData(\"Newitem1\");\n\nconsole.timeEnd('Se ejecuto el programa tiempo:');\n \n// * DIFICULTAD EXTRA (opcional):\n//  * Crea un programa ficticio de gestión de tareas que permita añadir, eliminar\n//  * y listar dichas tareas.\n//  * - Añadir: recibe nombre y descripción.\n//  * - Eliminar: por nombre de la tarea.\n//  * Implementa diferentes mensajes de log que muestren información según la\n//  * tarea ejecutada (a tu elección).\n//  * Utiliza el log para visualizar el tiempo de ejecución de cada tarea.\n\nclass Tareas {\n    constructor() {\n        \n        this.tareas = []\n    }\n    \n    getTareas(){\n               \n        return console.table(this.tareas)\n        \n    }\n\n    addTarea(tarea, descripcionDeTarea){\n        this.tareas.push({nombre:tarea, descripcion: descripcionDeTarea})\n    }\n    deleteTarea(nombre){\n        console.time(\"funcion deleteTarea Ejecutando\")\n        const inicialContador = this.tareas.length\n        this.tareas = this.tareas.filter(nom => nom. nombre !== nombre)\n    //   let deleteTarea = this.tareas.filter(nom => nom.nombre !== nombre )\n        \n        if ( this.tareas.length < inicialContador ) {\n            console.warn(`la tarea: ${nombre} fue eleiminada`)\n        }  else{\n            console.error(\"no se encontro tarea, verifique su lista de tareas \")\n        } \n        console.timeEnd(\"funcion deleteTarea Ejecutando\")\n      return this.tareas\n    }\n}\n\nconst tarea1 = new Tareas()\n\ntarea1.addTarea(\"barrer\", \"tomarmar una escoba y dejar limpio el espacio\")\ntarea1.addTarea(\"trapear\", \"se trapea despues de barrer para dejar brilloso el piso\")\ntarea1.getTareas()\ntarea1.deleteTarea(\"barrer\")\ntarea1.getTareas()\ntarea1.deleteTarea(\"comprar\")\ntarea1.addTarea(\"comprar\", \"pan y leche\")\ntarea1.getTareas()\n\n\n"
  },
  {
    "path": "Roadmap/25 - LOGS/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #25 - JavaScript ->Jesus Antonio Escamilla */\n\n/**\n * El concepto de \"logging\" en JavaScript se refiere al proceso de registrar información\n * sobre la ejecución de un programa. Esto es crucial para el desarrollo y mantenimiento\n * de software, ya que ayuda a los desarrolladores a entender lo que está sucediendo en\n * su código en tiempo real, diagnosticar errores y mejorar el rendimiento.\n */\n\n//---EJERCIÓ---\n// Registra un mensaje informativo en la consola\nconsole.log('Esto es un mensaje informativo');\n\n// Es un mensaje error en consola\nconsole.error('Error en la linea xx, corregirla');\n\n// Advertencia del código en la consola\nconsole.warn('Alto aun no has declaro la variable');\n\n// Un mensaje informativo en la consola (similar al `console.log`)\nconsole.info('Te informo que esta quedando super');\n\n// Mensaje depuración en la consola (no siempre esta disponible en todos los navegadores)\nconsole.debug('Mensaje Depurador en tu Proyecto');\n\n// Muestra datos tabulares como tabla en la consola\nconst usuario = [\n    { nombre: 'Jesus', edad: 24},\n    { nombre: 'Fatima', edad: 20}\n];\nconsole.table(usuario);\n\n// Agrupa los mensajes en la consola\nconsole.group('Detalles del Usuario');\nconsole.log('Nombre: Antonio');\nconsole.log('Edad: 24');\nconsole.groupEnd();\n\n// El Tiempo de ejecución\nconsole.time('Se ejecuto el programa');\n//  COGIDO DE LLENO\nconsole.timeEnd('Se ejecuto el programa');\n\n\n\n/**-----DIFICULTAD EXTRA-----*/\n\n//Clase de Tareas\nclass TaskManager{\n    constructor(){\n        this.tasks = [];\n    }\n\n    //  Agregar Tarea\n    addTask(nombre, descripción){\n        console.time(`Tiempo de Ejecución - Añadir tarea: ${nombre}`);\n        const nameTasks = this.tasks.find(tasks => tasks.nombre === nombre);\n        if (nameTasks) {\n            console.error(`La Tarea \"${nombre}\" ya existe`);\n        } else {\n            const task = {nombre, descripción};\n            this.tasks.push(task);\n            console.log(`Tarea añadida: \"${nombre}\" - \"${descripción}\"`);\n        }\n        console.timeEnd(`Tiempo de Ejecución - Añadir tarea: ${nombre}`);\n        return\n    }\n\n    //  Borrar Tarea\n    removeTask(nombre){\n        console.time(`Tiempo de Ejecución - Eliminar tarea: ${nombre}`);\n        const initialLength = this.tasks.length;\n        this.tasks = this.tasks.filter(task => task.nombre !== nombre);\n        if (this.tasks.length === initialLength) {\n            console.error(`No se encontró la tarea con el nombre \"${nombre}\"`);\n        } else {\n            console.log(`Tarea eliminada: ${nombre}`);\n        }\n        console.timeEnd(`Tiempo de Ejecución - Eliminar tarea: ${nombre}`);\n    }\n\n    //  Listar las Tareas\n    listTasks(){\n        console.log('Listado de tareas:');\n        console.table(this.tasks);\n    }\n}\n\n//  Ejemplo de las Tareas\nconst tasksManager = new TaskManager();\ntasksManager.addTask('Caminar', 'Caminar todos los días para bajar de peso');\ntasksManager.addTask('Leer un libro', 'Leer por 10 minutos un libro');\ntasksManager.addTask('Leer un libro', 'Leer por 10 minutos un libro');\ntasksManager.listTasks();\ntasksManager.removeTask('Caminar');\ntasksManager.listTasks();\n\n/**-----DIFICULTAD EXTRA-----*/"
  },
  {
    "path": "Roadmap/25 - LOGS/javascript/Rafacv23.js",
    "content": "// Hecho por @Rafacv23 | https://github.com/Rafacv23 | https://twitter.com/rafacanosa  | https://www.rafacanosa.dev\n\n// Tipos de logs que hay en JavaScript\nconsole.log(\"Esto es un console.log() sirve para mostrar mensajes por consola.\")\nconsole.warn(\n  \"Esto es un console.warn(), sirve para mostrar mensajes de aviso ante posibles errores o áreas a las que haya que prestar especial atención.\"\n)\nconsole.error(\n  \"Esto es un console.error(), sirve para mostrar errores por consola.\"\n)\nconsole.info(\n  \"Esto es un console.info(), sirve para aportar información adicional a un mensaje.\"\n)\nconsole.debug(\n  \"Esto es un console.debug(), sirve para mostrar un mensaje por consola pero con el modo debug activado.\"\n)\n\n// Dificultad opcional\nconsole.log(\"Iniciando programa de gestión de tareas...\")\nclass Task {\n  // Sirve para crear nuevas tareas\n  constructor(name, description) {\n    console.time(\"Tiempo para añadir tarea\")\n    this.name = name\n    this.description = description\n    console.timeEnd(\"Tiempo para añadir tarea\")\n  }\n\n  deleteTask(name, taskList) {\n    console.time(\"Tiempo para eliminar tarea\")\n\n    // check if name is provided\n    if (!name) {\n      console.error(\"No se ha introducido el nombre de la tarea\")\n      return\n    }\n\n    //Check if task exists\n    const taskExists = taskList.some((task) => task.name === name)\n\n    if (!taskExists) {\n      console.error(\n        `Error: No se encontró ninguna tarea con el nombre \"${name}\".`\n      )\n      return taskList // Retornar el array original si no se encuentra el item\n    }\n\n    const updatedTaskList = taskList.filter((task) => task.name !== name)\n    console.log(`Tarea con nombre \"${name}\" eliminada correctamente.`)\n\n    console.timeEnd(\"Tiempo para eliminar tarea\")\n    return updatedTaskList // Devolver la lista actualizada\n  }\n\n  showTasks(taskList) {\n    console.time(\"Tiempo para listar tareas\")\n    console.log(\"Tareas actuales:\")\n    for (let i = 0; i < taskList.length; i++) {\n      console.log(`${i + 1}. ${taskList[i].name} - ${taskList[i].description}`)\n    }\n    console.timeEnd(\"Tiempo para listar tareas\")\n  }\n}\n\nconst taskList = [\n  new Task(\"Lavar la ropa\", \"Separar blanco de color\"),\n  new Task(\"Hacer la compra\", \"Comprar pan, leche y huevos\"),\n  new Task(\"Estudiar\", \"Estudiar para el examen de JavaScript\"),\n]\n\nconst taskManager = new Task()\n\ntaskManager.showTasks(taskList)\n\ntaskManager.deleteTask(\"Estudiar\", taskList)\n"
  },
  {
    "path": "Roadmap/25 - LOGS/javascript/RaulDoezon.js",
    "content": "/*\n  EJERCICIO:\n  Explora el concepto de \"logging\" en tu lenguaje. Configúralo y muestra\n  un ejemplo con cada nivel de \"severidad\" disponible.\n*/\n\nconsole.log(\"+++++++++ NIVELES DE LOGGING +++++++++\");\n\nconsole.log(\"Soy un console.log()\");\nconsole.info(\"Soy un console.info()\");\nconsole.warn(\"Soy un console.warn()\");\nconsole.debug(\"Soy un console.debug()\");\nconsole.error(\"Soy un console.error()\");\n\n/*\n  DIFICULTAD EXTRA (opcional):\n  Crea un programa ficticio de gestión de tareas que permita añadir, eliminar\n  y listar dichas tareas.\n  - Añadir: recibe nombre y descripción.\n  - Eliminar: por nombre de la tarea.\n  Implementa diferentes mensajes de log que muestren información según la \n  tarea ejecutada (a tu elección).\n  Utiliza el log para visualizar el tiempo de ejecución de cada tarea. \n*/\n\nconsole.log(\"\\n+++++++++ SISTEMA DE GESTIÓN DE TAREAS +++++++++\");\n\nclass TaskManagement {\n  constructor() {\n    this.tasks = [];\n    this.taskName;\n    this.taskDescription;\n  }\n\n  add(taskName, taskDescription) {\n    const starTime = Date.now();\n\n    if (taskName !== undefined && taskDescription !== undefined) {\n      this.tasks.push({taskName, taskDescription});\n\n      console.info(`La tarea ${taskName} ha sido añadida.`);\n    } else {\n      console.warn(\"Debes definir el nombre de la tarea o la descripción\");\n    }\n\n    const endTime = Date.now();\n\n    console.log(`Tiempo de ejecución para añadir: ${(endTime - starTime) / 1000}s`);\n  }\n\n  delete(taskName) {\n    const starTime = Date.now();\n    const objectIndex = this.tasks.findIndex((task) => {\n      return task.taskName === taskName;\n    });\n\n    if (objectIndex > -1) {\n      this.tasks.splice(objectIndex, 1);\n\n      console.info(`La tarea ${taskName} ha sido eliminada.`);\n    } else {\n      console.error(\"La tarea que deseas eliminar no existe\");\n    }\n\n    const endTime = Date.now();\n\n    console.log(`Tiempo de ejecución para eliminar: ${(endTime - starTime) / 1000}s`);\n  }\n\n  show() {\n    const starTime = Date.now();\n\n    console.log(\"Listado de tareas:\");\n\n    if (this.tasks.length > 0) {\n      for (let index = 0; index < this.tasks.length; index++) {\n        const tasks = this.tasks[index];\n  \n        console.log(`- Tarea: ${tasks.taskName}. Descripción: ${tasks.taskDescription}`);\n      }\n    } else {\n      console.warn(\"No hay tareas para mostrar.\");\n    }\n\n    const endTime = Date.now();\n\n    console.log(`Tiempo de ejecución para mostrar: ${(endTime - starTime) / 1000}s`);\n  }\n}\n\nlet myTasks = new TaskManagement();\n\nmyTasks.show();\nmyTasks.add(\"Roadmap\", \"Realizar el ejercicio número 25.\");\nmyTasks.add(\"Tianguis\", \"Acompañar a mis papás al tianguis.\");\nmyTasks.add(\"Tianguis\");\nmyTasks.show();\nmyTasks.delete(\"Tianjis\");\nmyTasks.delete(\"Tianguis\");\nmyTasks.show();\n"
  },
  {
    "path": "Roadmap/25 - LOGS/javascript/RicJDev.js",
    "content": "/*\n- Se ejecuta en Node.js\n- Se ha instalado Winston para crear el sitema de logs (https://www.npmjs.com/package/winston)\n*/\n\n//EJERCICIO\nconst winston = require('winston');\n\nconst logger = winston.createLogger({\n\tlevel: 'debug',\n\tformat: winston.format.combine(\n\t\twinston.format.timestamp({ format: 'DD-MM-YYYY HH:mm:ss' }),\n\t\twinston.format.printf(({ timestamp, level, message }) => {\n\t\t\treturn `[${level.toUpperCase()}] - ${timestamp} : ${message}`;\n\t\t})\n\t),\n\ttransports: [new winston.transports.Console()],\n});\n\nlogger.log('info', 'mensaje de INFO');\nlogger.debug('mensaje de DEBUG');\nlogger.info('mensaje de INFO');\nlogger.warn('mensaje de WARN');\nlogger.error('mensaje de ERROR');\n\nconst customLevels = {\n\tlevels: {\n\t\t'Alerta roja': 0,\n\t\t'Alerta amarilla': 1,\n\t\t'Alerta verde': 2,\n\t},\n\tcolors: {\n\t\t'Alerta roja': 'red',\n\t\t'Alerta amarilla': 'yellow',\n\t\t'Alerta verde': 'green',\n\t},\n};\n\nwinston.addColors(customLevels.colors);\n\nconst customLevelsLogger = winston.createLogger({\n\tlevel: 'Alerta verde',\n\tlevels: customLevels.levels,\n\tformat: winston.format.combine(winston.format.colorize(), winston.format.simple()),\n\ttransports: [new winston.transports.Console()],\n});\n\ncustomLevelsLogger.log('Alerta roja', 'se muestra en rojo');\ncustomLevelsLogger.log('Alerta amarilla', 'se muestra en amarillo');\ncustomLevelsLogger.log('Alerta verde', 'se muestra en verde');\n\n//EXTRA\nconst taskManagerLogs = winston.createLogger({\n\tlevel: 'debug',\n\tformat: winston.format.combine(\n\t\twinston.format.timestamp({ format: 'DD-MM-YYYY HH:mm:ss' }),\n\t\twinston.format.printf(({ timestamp, level, message }) => {\n\t\t\treturn `[${level.toUpperCase()}] - ${timestamp} : ${message}`;\n\t\t})\n\t),\n\ttransports: [new winston.transports.Console()],\n});\n\nfunction timeLog(fun, log) {\n\treturn function (...arg) {\n\t\tconst start = new Date();\n\t\tconst execute = fun.apply(this, arg);\n\t\tconst end = new Date();\n\n\t\tlog.debug(\n\t\t\t`tiempo de ejecución de ${fun.name}: ${end.getTime() - start.getTime()} milisegundos`\n\t\t);\n\n\t\treturn execute;\n\t};\n}\nclass TaskManager {\n\t#taskList = new Map();\n\n\taddTask(task, description) {\n\t\tif (this.#taskList.has(task)) {\n\t\t\ttaskManagerLogs.warn(`se esta intentando agregar una tarea existente: ${task}`);\n\t\t\ttaskManagerLogs.debug(`cantidad de tareas ${this.#taskList.size}`);\n\t\t} else {\n\t\t\tthis.#taskList.set(task, description);\n\n\t\t\ttaskManagerLogs.info(`se ha agregado una tarea a la lista: ${task}`);\n\t\t\ttaskManagerLogs.debug(`cantidad de tareas ${this.#taskList.size}`);\n\t\t}\n\t}\n\n\tdeleteTask(task) {\n\t\tif (this.#taskList.has(task)) {\n\t\t\tthis.#taskList.delete(task);\n\n\t\t\ttaskManagerLogs.info(`se ha eliminado una tarea de la lista: ${task}`);\n\t\t\ttaskManagerLogs.debug(`cantidad de tareas ${this.#taskList.size}`);\n\t\t} else {\n\t\t\ttaskManagerLogs.error(`se esta intentando eliminar una tarea que no existe: ${task}`);\n\t\t\ttaskManagerLogs.debug(`cantidad de tareas ${this.#taskList.size}`);\n\t\t}\n\t}\n\n\tlistTasks() {\n\t\tif (this.#taskList.size > 0) {\n\t\t\tconsole.log('\\n---- LISTA DE TAREAS ----');\n\t\t\tthis.#taskList.forEach((description, task) => {\n\t\t\t\tconsole.log(`- ${task}: ${description}`);\n\t\t\t});\n\t\t\tconsole.log('-------------------------\\n');\n\n\t\t\ttaskManagerLogs.info('se ha mostrado la lista de tareas al usuario');\n\t\t\ttaskManagerLogs.debug(`cantidad de tareas ${this.#taskList.size}`);\n\t\t} else {\n\t\t\ttaskManagerLogs.info('no hay tareas para mostrar');\n\t\t\ttaskManagerLogs.debug(`cantidad de tareas ${this.#taskList.size}`);\n\t\t}\n\t}\n}\n\nTaskManager.prototype.addTask = timeLog(TaskManager.prototype.addTask, taskManagerLogs);\nTaskManager.prototype.deleteTask = timeLog(TaskManager.prototype.deleteTask, taskManagerLogs);\nTaskManager.prototype.listTasks = timeLog(TaskManager.prototype.listTasks, taskManagerLogs);\n\nconst myTaskManager = new TaskManager();\n\nmyTaskManager.addTask('Juan', 'felicitar a Juan por su cumpleaños');\nmyTaskManager.addTask('Pan', 'ir a comprar pan');\nmyTaskManager.addTask('Pan', 'ir a comprar pan');\nmyTaskManager.listTasks();\nmyTaskManager.deleteTask('Juan');\nmyTaskManager.listTasks();\nmyTaskManager.deleteTask('Juan');\nmyTaskManager.deleteTask('Pan');\nmyTaskManager.listTasks();\n"
  },
  {
    "path": "Roadmap/25 - LOGS/javascript/Sac-Corts.js",
    "content": "console.log(\"This is a general message\");\nconsole.info(\"This is an infomational message\");\nconsole.warn(\"Warning: This is a warning message\");\nconsole.error(\"Error: This is an error message\");\nconsole.debug(\"Debug: This is a debug message\");\n\n// Extra Exercise //\nclass TaskManager {\n    constructor() {\n        this.tasks = [];\n    }\n\n    addTask(name, description) {\n        console.time(`addTask`);\n        console.log(`Trying add task: ${name}`);\n\n        this.tasks.push({name, description})\n\n        console.info(`Task \"${name}\" added successfully`);\n        console.timeEnd(`addTask`);\n    }\n\n    removeTask(name) {\n        console.time(`removeTask`);\n        console.log(`Trying remove task: ${name}`);\n\n        const index = this.tasks.findIndex(task => task.name === name);\n\n        if (index !== -1) {\n            this.tasks.splice(index, 1);\n            console.info(`Task \"${name}\" removed successfully`);\n        } else {\n            console.warn(`The task with the name \"${name}\" was not found`);\n        }\n        console.timeEnd(`removeTask`);\n    }\n\n    listTasks() {\n        console.time(`listTasks`);\n        console.log(`Showing all tasks:`);\n\n        if (this.tasks.length === 0) {\n            console.warn(\"No tasks available\");\n        } else {\n            this.tasks.forEach(task => {\n                console.info(`Task: ${task.name}, Description: ${task.description}`);\n            });\n        }\n        console.timeEnd(`listTasks`);\n    }\n}\n\nconst taskManager = new TaskManager();\ntaskManager.addTask(\"Task 1\", \"Do something\");\ntaskManager.addTask(\"Task 2\", \"Do anything\");\n\ntaskManager.listTasks();\n\ntaskManager.removeTask(\"Task 2\");\nconsole.log(taskManager);"
  },
  {
    "path": "Roadmap/25 - LOGS/javascript/adrs1166ma.js",
    "content": "/*  🔥EJERCICIO:\nExplora el concepto de \"logging\" en tu lenguaje. Configúralo y muestra\nun ejemplo con cada nivel de \"severidad\" disponible.\n\n/*Logging con Winston (Node.js) */\n// Verificar si estamos en Node.js\nif (typeof process !== 'undefined' && process.versions?.node) {\n    const winston = require('winston');\n\n    const niveles = {\n        error: 0,\n        warn: 1,\n        info: 2,\n        http: 3,\n        debug: 4\n    };\n\n    const colores = {\n        error: 'red',\n        warn: 'yellow',\n        info: 'green',\n        http: 'blue',\n        debug: 'white'\n    };\n\n    winston.addColors(colores);\n\n    const logger = winston.createLogger({\n        levels: niveles,\n        format: winston.format.combine(\n            winston.format.colorize(),\n            winston.format.timestamp(),\n            winston.format.printf(({ timestamp, level, message }) => {\n                return `${timestamp} [${level}]: ${message}`;\n            })\n        ),\n        transports: [\n            new winston.transports.Console(),\n            new winston.transports.File({ filename: 'logs/error.log', level: 'error' }),\n            new winston.transports.File({ filename: 'logs/all.log' })\n        ]\n    });\n\n    logger.info('Este es un mensaje informativo.');\n    logger.warn('Este es un mensaje de advertencia.');\n    logger.error('Este es un mensaje de error.');\n    logger.http('Este es un mensaje HTTP.');\n    logger.debug('Este es un mensaje de depuración.');\n}\n\n/* 🔥 DIFICULTAD EXTRA (opcional):\nCrea un programa ficticio de gestión de tareas que permita añadir, eliminar\ny listar dichas tareas.\n- Añadir: recibe nombre y descripción.\n- Eliminar: por nombre de la tarea.\nImplementa diferentes mensajes de log que muestren información según la \ntarea ejecutada (a tu elección).\nUtiliza el log para visualizar el tiempo de ejecución de cada tarea. \n */\n// Logger para entornos sin Node.js (navegador)\nconst loggerBrowser = {\n    info: (message) => console.log(`[%cINFO%c] ${message}`, 'color: green', 'color: default'),\n    warn: (message) => console.log(`[%cWARN%c] ${message}`, 'color: yellow', 'color: default'),\n    error: (message) => console.log(`[%cERROR%c] ${message}`, 'color: red', 'color: default'),\n    debug: (message) => console.log(`[%cDEBUG%c] ${message}`, 'color: blue', 'color: default')\n};\n\n// Ejemplos en navegador\nloggerBrowser.info('Este es un mensaje informativo.');\nloggerBrowser.warn('Este es un mensaje de advertencia.');\nloggerBrowser.error('Este es un mensaje de error.');\n\n/*  (compatible con ambos entornos) */\nclass GestorTareas {\n    constructor() {\n        this.tareas = [];\n        // Usar Winston en Node.js o loggerBrowser en navegador\n        this.logger = typeof process !== 'undefined' && process.versions?.node\n            ? require('winston').loggers.get('default') // Asume que Winston ya está configurado\n            : loggerBrowser;\n    }\n\n    añadirTarea(nombre, descripcion) {\n        const inicio = typeof performance !== 'undefined' ? performance.now() : Date.now();\n        this.tareas.push({ nombre, descripcion });\n        const duracion = typeof performance !== 'undefined' ? performance.now() - inicio : Date.now() - inicio;\n        this.logger.info(`Tarea añadida: ${nombre} (Tiempo: ${duracion.toFixed(2)}ms)`);\n    }\n\n    eliminarTarea(nombre) {\n        const inicio = typeof performance !== 'undefined' ? performance.now() : Date.now();\n        const indice = this.tareas.findIndex(t => t.nombre === nombre);\n        if (indice === -1) {\n            this.logger.warn(`Tarea no encontrada: ${nombre} (Tiempo: ${Date.now() - inicio}ms)`);\n            return;\n        }\n        this.tareas.splice(indice, 1);\n        this.logger.info(`Tarea eliminada: ${nombre} (Tiempo: ${Date.now() - inicio}ms)`);\n    }\n\n    listarTareas() {\n        const inicio = typeof performance !== 'undefined' ? performance.now() : Date.now();\n        if (this.tareas.length === 0) {\n            this.logger.warn(\"No hay tareas para listar. (Tiempo: 0ms)\");\n            return;\n        }\n        this.logger.info(`Listando ${this.tareas.length} tareas... (Tiempo: ${Date.now() - inicio}ms)`);\n        this.tareas.forEach(tarea => {\n            this.logger.http(`- ${tarea.nombre}: ${tarea.descripcion}`);\n        });\n    }\n}\n\n// Ejemplo de uso\nconst gestor = new GestorTareas();\ngestor.añadirTarea(\"Tarea 1\", \"Estudiar JavaScript\");\ngestor.añadirTarea(\"Tarea 2\", \"Hacer ejercicio\");\ngestor.listarTareas();\ngestor.eliminarTarea(\"Tarea 1\");\ngestor.eliminarTarea(\"Tarea Inexistente\");\n\n/*\ndictionary 📗 = {\n    if (typeof process !== 'undefined' && process.versions?.node)\n    : En el navegador, se usa loggerBrowser para simular niveles de severidad con console.log.,\n    npm install winston : Instala Winston,\n    node logging.js : Ejecuta el archivo,\n}\n*/"
  },
  {
    "path": "Roadmap/25 - LOGS/javascript/agusrosero.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de \"logging\" en tu lenguaje. Configúralo y muestra\n * un ejemplo con cada nivel de \"severidad\" disponible.\n */\nconsole.log(\"Mensaje log..\");\n\nconsole.error(\"Mensaje error..\");\n\nconsole.warn(\"Mensaje warm..\");\n\nconsole.info(\"Mensaje info..\");\n\nconsole.debug(\"Mensaje debug..\");\n\nconsole.table(\"Mensaje table..\");\n\nconsole.time(\"Controlar el tiempo que tarda una operación..\");\nconsole.timeLog(\"tiempo de respuesta\");\nconsole.timeEnd(\"tiempo de respuesta\");\n\n/* DIFICULTAD EXTRA (opcional):\n * Crea un programa ficticio de gestión de tareas que permita añadir, eliminar\n * y listar dichas tareas.\n * - Añadir: recibe nombre y descripción.\n * - Eliminar: por nombre de la tarea.\n * Implementa diferentes mensajes de log que muestren información según la\n * tarea ejecutada (a tu elección).\n * Utiliza el log para visualizar el tiempo de ejecución de cada tarea.\n */\n"
  },
  {
    "path": "Roadmap/25 - LOGS/javascript/bernatcs.js",
    "content": "// ** EJERCICIO \n\nconsole.trace('TRACE envía mensajes detallados sobre la ejecución del programa' )\nconsole.debug('DEBUG son mensajes destinados a la depuración del software, prueba de código...')\nconsole.info('INFO son mensajes informativos que indican funcionamiento normal del código')\nconsole.warn('WARN son mensajes de advertencia que indican situaciones potencialmente problemáticas')\nconsole.error('ERROR son errores que han ocurrido en la aplicación')\n\n// además, hay más tipos de logs\n\nconsole.log(\"Mensaje informativo\");\n\nconsole.group(\"Grupo de mensajes\");\nconsole.log(\"Mensaje dentro del grupo\"); // Este mensaje sale como si fuera en un tabulador\nconsole.groupEnd();\n\nconsole.time(\"Tiempo de ejecución\");\n// Código cuya ejecución quieres medir\nconsole.timeEnd(\"Tiempo de ejecución\");\n\nconsole.trace(\"Traza de pila\"); // Output: stack trace\n\n// ** DIFICULTAD EXTRA ** -------------------------------------------------------------------------------------------------------------------------------------------------------\n\nconst readline = require('node:readline')\n\nconst gestorTareas = [\n    {Nombre: 'Tarea1', Descripcion: 'Esta es una tarea de prueba'}\n]\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n  });\n\nfunction preguntaInicio() {\n    rl.question('\\n¿Qué quieres hacer?\\n[Añadir] - [Eliminar]\\n', (respuestaInicio) => {\n        if (respuestaInicio === 'Añadir') {\n            rl.question('Introduzca el nombre de la tarea que desea agregar: ', (tareaAgregar) => {\n                rl.question(`Introduzca la descripción de la tarea ${tareaAgregar}: `, (descripcionAgregar) => {\n                    console.time('Tiempo de ejecución')\n                    gestorTareas.push({Nombre: tareaAgregar, Descripcion: descripcionAgregar})\n                    console.group(`\\nLa tarea ${tareaAgregar} se ha agregado satisfactoriamente`)\n                    console.timeEnd('Tiempo de ejecución')\n                    console.groupEnd()\n                    preguntaInicio()\n                })\n            })\n        } else if (respuestaInicio === 'Eliminar') {\n            rl.question('Introduzca el nombre de la tarea que desea eliminar: ', (tareaEliminar) => {\n                console.time('Tiempo de ejecución')\n                gestorTareas.splice((gestorTareas.findIndex((tarea) => tarea.Nombre === tareaEliminar)), 1);\n                console.group(`\\nLa tarea ${tareaEliminar} se ha eliminado satisfactoriamente`)\n                console.timeEnd('Tiempo de ejecución')\n                console.groupEnd()\n                preguntaInicio()\n            })\n            preguntaInicio()\n        } else {\n            console.warn('\\nPor favor, introduzca una respuesta válida')\n            preguntaInicio()\n        }\n    });\n}\n\npreguntaInicio()"
  },
  {
    "path": "Roadmap/25 - LOGS/javascript/caterinarodriguezdev.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de \"logging\" en tu lenguaje. Configúralo y muestra\n * un ejemplo con cada nivel de \"severidad\" disponible.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa ficticio de gestión de tareas que permita añadir, eliminar\n * y listar dichas tareas.\n * - Añadir: recibe nombre y descripción.\n * - Eliminar: por nombre de la tarea.\n * Implementa diferentes mensajes de log que muestren información según la\n * tarea ejecutada (a tu elección).\n * Utiliza el log para visualizar el tiempo de ejecución de cada tarea.\n */\n\nconsole.log(\"Mensaje general 💚\");\nconsole.error(\"Mensaje de error 🔴\");\nconsole.warn(\"Mensaje de alerta 🚩\");\nconsole.info(\"Mensaje informativo ℹ️\");\nconsole.debug(\"Mensaje de depuración\");\nconsole.trace(\"Mensaje detallado sobre la ejecución del programa 🔢\");\n\nconsole.group(\"Lista de mensajes\");\nconsole.log(\"M1\");\nconsole.log(\"M2\");\nconsole.log(\"M3\");\nconsole.groupEnd();\n\nconsole.time(\"tiempoEjecucion\");\nconsole.timeEnd(\"tiempoEjecucion\");\n\nconsole.log(\"-----------------DIFICULTAD EXTRA-------------\");\n\nconst readline = require(\"readline\");\nconst rl = readline.createInterface(process.stdin, process.stdout);\n\nlet tareas = [];\n\nconst gestorTareas = () => {\n  console.log(`Menú:\n        1. Añadir tarea\n        2. Eliminar tarea\n        3. Listar tareas\\n`);\n\n  rl.question(\n    \"Bienvenido al gestor de tareas, elija una opción -> \",\n    (resp) => {\n      switch (resp) {\n        case \"1\":\n          rl.question(\"\\n¿Qué tarea quieres añadir? -> \", (resp) => {\n            tareas.push(resp);\n            console.log(\"Añadiendo tarea: \", resp);\n            gestorTareas();\n          });\n          break;\n        case \"2\":\n          rl.question(\"\\n¿Qué tarea deseas eliminar? -> \", (resp) => {\n            console.log(\"\\n\");\n            tareas = tareas.filter((tarea) => tarea !== resp);\n            console.log(\"Se ha eliminado la tarea: \", resp);\n            gestorTareas();\n          });\n          break;\n        case \"3\":\n          tareas.forEach((tarea) => console.log(`- ${tarea}\\n`));\n          gestorTareas();\n          break;\n        default:\n          console.log(\"\\nElija una opción disponible\");\n          gestorTareas();\n      }\n    }\n  );\n};\n\ngestorTareas();\n"
  },
  {
    "path": "Roadmap/25 - LOGS/javascript/duendeintemporal.js",
    "content": "// #25 - LOGS\n/* EJERCICIO:\n * Explora el concepto de \"logging\" en tu lenguaje. Configúralo y muestra\n * un ejemplo con cada nivel de \"severidad\" disponible.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa ficticio de gestión de tareas que permita añadir, eliminar\n * y listar dichas tareas.\n * - Añadir: recibe nombre y descripción.\n * - Eliminar: por nombre de la tarea.\n * Implementa diferentes mensajes de log que muestren información según la\n * tarea ejecutada (a tu elección).\n * Utiliza el log para visualizar el tiempo de ejecución de cada tarea. */\n\n\n//(Node.js is required to run the Extra Dificulty Exercise example)\n\nlet log = console.log;\nlog(\"Retosparaprogramadores #14.\");\n\nconst logDebug = (message) => console.debug(`DEBUG: ${message}`);\nconst logInfo = (message) => console.info(`INFO: ${message}`);\nconst logWarning = (message) => console.warn(`WARNING: ${message}`);\nconst logError = (message) => console.error(`ERROR: ${message}`);\nconst logCritical = (message) => console.error(`CRITICAL: ${message}`);\n\nlogDebug(\"This is a debug message.\");\nlogInfo(\"This is an informational message.\");\nlogWarning(\"This is a warning message.\");\nlogError(\"This is an error message.\");\nlogCritical(\"This is a critical message.\");\n\n\n//EXTRA DIFICULTY EXERCISE  (Node.js is required to run this example)\n\nconst readline = require('readline');\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nclass TaskManager {\n    constructor() {\n        this.tasks = {};\n    }\n\n    addTask(name, description) {\n        const startTime = Date.now();\n        if (this.tasks[name]) {\n            logWarning(`The task '${name}' already exists.`);\n            this.promptEditTask(name);\n            return;\n        }\n        this.tasks[name] = description;\n        logInfo(`Task added: ${name} - ${description}`);\n        const endTime = Date.now();\n        logDebug(`Execution time for adding task: ${(endTime - startTime) / 1000} seconds`);\n    }\n\n    promptEditTask(name) {\n        rl.question(`The task '${name}' already exists. Do you want to edit it? (yes/no): `, (answer) => {\n            if (answer.toLowerCase() === 'yes') {\n                rl.question('Enter the new description: ', (newDescription) => {\n                    this.editTask(name, newDescription);\n                    rl.close();\n                });\n            } else {\n                logInfo(`No changes made to the task '${name}'.`);\n                rl.close();\n            }\n        });\n    }\n\n    editTask(name, newDescription) {\n        const startTime = Date.now();\n        if (!this.tasks[name]) {\n            logError(`Could not edit the task '${name}' because it does not exist.`);\n            return;\n        }\n        this.tasks[name] = newDescription;\n        logInfo(`Task edited: ${name} - New Description: ${newDescription}`);\n        const endTime = Date.now();\n        logDebug(`Execution time for editing task: ${(endTime - startTime) / 1000} seconds`);\n    }\n\n    removeTask(name) {\n        const startTime = Date.now();\n        if (!this.tasks[name]) {\n            logError(`Could not remove the task '${name}' because it does not exist.`);\n            return;\n        }\n        delete this.tasks[name];\n        logInfo(`Task removed: ${name}`);\n        const endTime = Date.now();\n        logDebug(`Execution time for removing task: ${(endTime - startTime) / 1000} seconds`);\n    }\n\n    listTasks() {\n        const startTime = Date.now();\n        if (Object.keys(this.tasks).length === 0) {\n            logWarning(\"No tasks to display.\");\n            return;\n        }\n        logInfo(\"Task list:\");\n        for (const [name, description] of Object.entries(this.tasks)) {\n            logInfo(`- ${name}: ${description}`);\n        }\n        const endTime = Date.now();\n        logDebug(`Execution time for listing tasks: ${(endTime - startTime) / 1000} seconds`);\n    }\n}\n\nconst manager = new TaskManager();\nmanager.addTask(\"Implement User Authentication\", \"Develop a user authentication system that allows users to register, log in, and log out securely.\");\nmanager.addTask(\"Fix Bug in Feature Resize window\", \"Fix Bug in Feature Resize window\");\nmanager.addTask(\"Write Unit Tests\", \"Write Unit Tests - Create tests for the user authentication module using Jest.\");\nmanager.addTask(\"Refactor Code for Module Lang_translation\", \"Refactor Code for Module Lang_translation - Simplify the logic and remove redundant code.\");\nmanager.addTask(\"Deploy Application to Production\", \"Deploy Application to Production - Set up CI/CD pipeline and deploy the latest build.\");\nmanager.listTasks();\nmanager.removeTask(\"Implement User Authentication\");\nmanager.editTask(\"Fix Bug in Feature Resize window\", \"Fix Bug in Feature Resize window - Resolve the issue causing the application to crash on submission.\" );\nmanager.listTasks();\n\n/*  Output: DEBUG: This is a debug message.\nINFO: This is an informational message.\nWARNING: This is a warning message.\nERROR: This is an error message.\nCRITICAL: This is a critical message.\nINFO: Task added: Implement User Authentication - Develop a user authentication system that allows users to register, log in, and log out securely.\nDEBUG: Execution time for adding task: 0 seconds\nINFO: Task added: Fix Bug in Feature Resize window - Fix Bug in Feature Resize window\nDEBUG: Execution time for adding task: 0 seconds\nINFO: Task added: Write Unit Tests - Write Unit Tests - Create tests for the user authentication module using Jest.\nDEBUG: Execution time for adding task: 0 seconds\nINFO: Task added: Refactor Code for Module Lang_translation - Refactor Code for Module Lang_translation - Simplify the logic and remove redundant code.\nDEBUG: Execution time for adding task: 0.001 seconds\nINFO: Task added: Deploy Application to Production - Deploy Application to Production - Set up CI/CD pipeline and deploy the latest build.\nDEBUG: Execution time for adding task: 0.001 seconds\nINFO: Task list:\nINFO: - Implement User Authentication: Develop a user authentication system that allows users to register, log in, and log out securely.\nINFO: - Fix Bug in Feature Resize window: Fix Bug in Feature Resize window\nINFO: - Write Unit Tests: Write Unit Tests - Create tests for the user authentication module using Jest.\nINFO: - Refactor Code for Module Lang_translation: Refactor Code for Module Lang_translation - Simplify the logic and remove redundant code.\nINFO: - Deploy Application to Production: Deploy Application to Production - Set up CI/CD pipeline and deploy the latest build.\nDEBUG: Execution time for listing tasks: 0.006 seconds\nINFO: Task removed: Implement User Authentication\nDEBUG: Execution time for removing task: 0 seconds\nINFO: Task edited: Fix Bug in Feature Resize window - New Description: Fix Bug in Feature Resize window - Resolve the issue causing the application to crash on submission.\nDEBUG: Execution time for editing task: 0.004 seconds\nINFO: Task list:\nINFO: - Fix Bug in Feature Resize window: Fix Bug in Feature Resize window - Resolve the issue causing the application to crash on submission.\nINFO: - Write Unit Tests: Write Unit Tests - Create tests for the user authentication module using Jest.\nINFO: - Refactor Code for Module Lang_translation: Refactor Code for Module Lang_translation - Simplify the logic and remove redundant code.\nINFO: - Deploy Application to Production: Deploy Application to Production - Set up CI/CD pipeline and deploy the latest build.\nDEBUG: Execution time for listing tasks: 0.005 seconds  */\n\n\n/*Info Note: \nContinuous Integration is a development practice where developers frequently integrate their code changes into a shared repository, usually several times a day.\nEach integration is automatically tested to detect errors quickly. This helps ensure that the codebase remains stable and that new changes do not break existing functionality.\nTools commonly used for CI include Jenkins, Travis CI, CircleCI, GitHub Actions, and GitLab CI.\nCD (Continuous Delivery or Continuous Deployment):\n\nContinuous Delivery is an extension of CI that ensures that the code is always in a deployable state. This means that after passing automated tests, the code can be deployed to production at any time.\nContinuous Deployment takes it a step further by automatically deploying every change that passes the tests to production without manual intervention.\nThis practice allows for faster release cycles and more frequent updates to the application. */"
  },
  {
    "path": "Roadmap/25 - LOGS/javascript/eulogioep.js",
    "content": "/**\n * TEORÍA SOBRE LOGGING EN JAVASCRIPT\n * \n * JavaScript proporciona varios métodos nativos de logging a través del objeto console:\n * - console.error(): Para errores críticos\n * - console.warn(): Para advertencias\n * - console.info(): Para información general\n * - console.debug(): Para información de depuración\n * - console.trace(): Para stack traces\n * \n * Ventajas del logging:\n * 1. Facilita la depuración\n * 2. Permite monitorear el estado de la aplicación\n * 3. Ayuda a diagnosticar problemas en producción\n * 4. Proporciona información sobre el rendimiento\n */\n\n// Clase para manejar el logging con niveles de severidad y timestamps\nclass Logger {\n    /**\n     * Añade timestamp y formato al mensaje de log\n     * @param {string} level - Nivel de severidad\n     * @param {string} message - Mensaje a registrar\n     * @returns {string} - Mensaje formateado\n     */\n    static formatMessage(level, message) {\n        const timestamp = new Date().toISOString();\n        return `[${timestamp}] [${level}] ${message}`;\n    }\n\n    static error(message) {\n        console.error(this.formatMessage('ERROR', message));\n    }\n\n    static warn(message) {\n        console.warn(this.formatMessage('WARN', message));\n    }\n\n    static info(message) {\n        console.info(this.formatMessage('INFO', message));\n    }\n\n    static debug(message) {\n        console.debug(this.formatMessage('DEBUG', message));\n    }\n\n    static trace(message) {\n        console.trace(this.formatMessage('TRACE', message));\n    }\n}\n\n/**\n * Clase que representa una tarea\n */\nclass Task {\n    /**\n     * @param {string} name - Nombre de la tarea\n     * @param {string} description - Descripción de la tarea\n     */\n    constructor(name, description) {\n        this.name = name;\n        this.description = description;\n        this.createdAt = new Date();\n        this.id = crypto.randomUUID(); // Generamos un ID único para cada tarea\n    }\n}\n\n/**\n * Clase para la gestión de tareas\n */\nclass TaskManager {\n    constructor() {\n        this.tasks = new Map(); // Usamos Map para almacenar las tareas por su nombre\n    }\n\n    /**\n     * Mide el tiempo de ejecución de una función\n     * @param {Function} fn - Función a ejecutar\n     * @param {string} operationName - Nombre de la operación\n     * @returns {*} - Resultado de la función\n     */\n    async measureExecutionTime(fn, operationName) {\n        const startTime = performance.now();\n        try {\n            const result = await fn();\n            const endTime = performance.now();\n            Logger.debug(`Tiempo de ejecución ${operationName}: ${(endTime - startTime).toFixed(2)}ms`);\n            return result;\n        } catch (error) {\n            Logger.error(`Error en ${operationName}: ${error.message}`);\n            throw error;\n        }\n    }\n\n    /**\n     * Añade una nueva tarea\n     * @param {string} name - Nombre de la tarea\n     * @param {string} description - Descripción de la tarea\n     */\n    async addTask(name, description) {\n        await this.measureExecutionTime(async () => {\n            if (this.tasks.has(name)) {\n                Logger.warn(`La tarea \"${name}\" ya existe`);\n                return;\n            }\n\n            const task = new Task(name, description);\n            this.tasks.set(name, task);\n            Logger.info(`Tarea \"${name}\" añadida exitosamente`);\n        }, 'addTask');\n    }\n\n    /**\n     * Elimina una tarea por su nombre\n     * @param {string} name - Nombre de la tarea a eliminar\n     */\n    async removeTask(name) {\n        await this.measureExecutionTime(async () => {\n            if (!this.tasks.has(name)) {\n                Logger.warn(`No se encontró la tarea \"${name}\"`);\n                return;\n            }\n\n            this.tasks.delete(name);\n            Logger.info(`Tarea \"${name}\" eliminada exitosamente`);\n        }, 'removeTask');\n    }\n\n    /**\n     * Lista todas las tareas existentes\n     */\n    async listTasks() {\n        await this.measureExecutionTime(async () => {\n            if (this.tasks.size === 0) {\n                Logger.info(\"No hay tareas registradas\");\n                return;\n            }\n\n            Logger.info(\"Lista de tareas:\");\n            for (const task of this.tasks.values()) {\n                Logger.info(\n                    `- ${task.name}: ${task.description} ` +\n                    `(Creada: ${task.createdAt.toISOString()}) ` +\n                    `[ID: ${task.id}]`\n                );\n            }\n        }, 'listTasks');\n    }\n}\n\n/**\n * Función principal para demostrar el uso del sistema\n */\nasync function main() {\n    try {\n        Logger.info(\"Iniciando sistema de gestión de tareas\");\n\n        // Demostración de diferentes niveles de logging\n        Logger.error(\"Ejemplo de mensaje de error\");\n        Logger.warn(\"Ejemplo de mensaje de advertencia\");\n        Logger.info(\"Ejemplo de mensaje informativo\");\n        Logger.debug(\"Ejemplo de mensaje de depuración\");\n        Logger.trace(\"Ejemplo de mensaje de trace\");\n\n        // Crear instancia del gestor de tareas\n        const taskManager = new TaskManager();\n\n        // Ejemplos de uso del sistema\n        await taskManager.addTask(\n            \"Aprender JavaScript\", \n            \"Estudiar conceptos avanzados de JS\"\n        );\n        \n        await taskManager.addTask(\n            \"Hacer ejercicio\", \n            \"30 minutos de cardio\"\n        );\n\n        // Intentar añadir una tarea duplicada\n        await taskManager.addTask(\n            \"Aprender JavaScript\", \n            \"Tarea duplicada\"\n        );\n\n        // Listar tareas\n        await taskManager.listTasks();\n\n        // Eliminar una tarea\n        await taskManager.removeTask(\"Aprender JavaScript\");\n\n        // Listar tareas actualizadas\n        await taskManager.listTasks();\n\n        // Intentar eliminar una tarea que no existe\n        await taskManager.removeTask(\"Tarea inexistente\");\n\n        Logger.info(\"Finalizando sistema de gestión de tareas\");\n    } catch (error) {\n        Logger.error(`Error en la ejecución principal: ${error.message}`);\n    }\n}\n\n// Ejecutar el programa\nmain().catch(error => {\n    Logger.error(`Error crítico: ${error.message}`);\n});"
  },
  {
    "path": "Roadmap/25 - LOGS/javascript/hectorio23.js",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\n\"use strict\";\nconst winston = require('winston'); // npm install winston\nconst { combine, timestamp, printf } = winston.format;\n\n// Configuración de winston para logging\nconst myFormat = printf(({ level, message, timestamp }) => {\n  return `${timestamp} - ${level.toUpperCase()}: ${message}`;\n});\n\nconst logger = winston.createLogger({\n  level: 'debug',\n  format: combine(\n    timestamp(),\n    myFormat\n  ),\n  transports: [\n    new winston.transports.Console()\n  ]\n});\n\n// Lista para almacenar las tareas\nlet tareas = [];\n\nfunction addTask(nombre, descripcion) {\n  const startTime = Date.now();\n  logger.info(`Añadiendo tarea: ${nombre}`);\n  const tarea = { nombre, descripcion };\n  tareas.push(tarea);\n  logger.debug(`Tareas actuales: ${JSON.stringify(tareas)}`);\n  const endTime = Date.now();\n  logger.info(`Tarea añadida en ${(endTime - startTime) / 1000} segundos`);\n}\n\nfunction deleteTask(nombre) {\n  const startTime = Date.now();\n  logger.info(`Eliminando tarea: ${nombre}`);\n  tareas = tareas.filter(tarea => tarea.nombre !== nombre);\n  logger.debug(`Tareas actuales: ${JSON.stringify(tareas)}`);\n  const endTime = Date.now();\n  logger.info(`Tarea eliminada en ${(endTime - startTime) / 1000} segundos`);\n}\n\nfunction showTask() {\n  logger.info(\"Listando todas las tareas\");\n  if (tareas.length === 0) {\n    logger.warning(\"No hay tareas para listar\");\n  } else {\n    tareas.forEach(tarea => {\n      logger.info(`Tarea: ${tarea.nombre}, Descripción: ${tarea.descripcion}`);\n    });\n  }\n}\n\n// Ejemplo de uso del programa de gestión de tareas\naddTask(\"Comprar pan\", \"Ir a la panadería y comprar una barra de pan\");\naddTask(\"Estudiar JavaScript\", \"Completar el ejercicio de logging en JavaScript\");\nshowTask();\ndeleteTask(\"Comprar pan\");\nshowTask();\n"
  },
  {
    "path": "Roadmap/25 - LOGS/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n_______________________________________\n#25 LOGS\n---------------------------------------\n* EJERCICIO:\n * Explora el concepto de \"logging\" en tu lenguaje. Configúralo y muestra\n * un ejemplo con cada nivel de \"severidad\" disponible.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa ficticio de gestión de tareas que permita añadir, eliminar\n * y listar dichas tareas.\n * - Añadir: recibe nombre y descripción.\n * - Eliminar: por nombre de la tarea.\n * Implementa diferentes mensajes de log que muestren información según la\n * tarea ejecutada (a tu elección).\n * Utiliza el log para visualizar el tiempo de ejecución de cada tarea.\n*/\n// ________________________________________________________\n\nimport { createLogger, transports, format } from 'winston';\n\nconst logger = createLogger({\n    level: 'debug',\n    format: format.combine(\n        format.timestamp(),\n        format.printf(({ timestamp, level, message }) => {\n            return `${timestamp} - ${level} - ${message}`;\n        })\n    ),\n    transports: [\n        new transports.Console()\n    ]\n});\n\nlogger.debug('Depuración');\n\nlogger.info('Informativo');\n\nlogger.warn('Advertencia');\n\nlogger.error('Error');\nlogger.error('Error crítico');\n\n// ________________________________________________________\nconsole.log(\"\\nDIFICULTAD EXTRA\");\n\nfunction showTime(func) {\n    return async function (...args) {\n        const startTime = Date.now();\n        await func.apply(this, args);\n        const endTime = Date.now();\n        const executionTime = (endTime - startTime) / 1000;\n        logger.debug(`Tiempo de ejecución de ${func.name}: ${executionTime.toFixed(21)} segundos.`);\n    };\n}\n\nclass Program {\n    constructor() {\n        this.tasks = {};\n        logger.debug('Se inició instancia de la clase.');\n    }\n\n    add = showTime(async function (name, description) {\n        this.tasks[name] = description;\n        logger.info('Se agregó una tarea.');\n    });\n\n    delete = showTime(async function (name) {\n        if (name in this.tasks) {\n            delete this.tasks[name];\n            logger.info(`Tarea '${name}' eliminada.`);\n        } else {\n            logger.warn(`No se encontró la tarea '${name}'.`);\n        }\n    });\n\n    showList = showTime(async function () {\n        logger.info('Lista de tareas');\n        for (const [task, des] of Object.entries(this.tasks)) {\n            console.log(`${task} -- ${des}`);\n        }\n    });\n}\n\nconst tasks = new Program();\n\n(async () => {\n    await tasks.add(\"a\", \".1\");\n    await tasks.add(\"b\", \"2\");\n    await tasks.add(\"c\", \"3\");\n\n    await tasks.delete(\"a\");\n    await tasks.showList();\n\n    await tasks.delete(\"a\");\n})();\n"
  },
  {
    "path": "Roadmap/25 - LOGS/javascript/miguelex.js",
    "content": "const fs = require('fs');\n\n// Habilitar registro de errores\nconst logFile = './log.txt';\nconst logError = (message) => {\n    fs.appendFileSync(logFile, message + '\\n');\n};\n\n// Error fatal\nif (false) {\n    // Este código nunca se ejecutará\n    logError(\"Este es un ejemplo de mensaje de error fatal\");\n}\n\n// Advertencia\ntry {\n    const result = fs.readFileSync('non_existing_file.txt', 'utf8');\n} catch (err) {\n    logError(\"Este es un ejemplo de mensaje de advertencia\");\n}\n\n// Notificación\nlet undefinedVar;\nlogError(\"Este es un ejemplo de mensaje de notificación\");\n\n// Deprecado\nconst oldFunction = () => {\n    logError(\"Este es un ejemplo de mensaje de función obsoleta\");\n};\n\noldFunction();\n\n// Estricto\nclass MyClass {\n    constructor() {\n        logError(\"Este es un ejemplo de mensaje de nivel estricto\");\n    }\n}\nconst obj = new MyClass();\n\n// Mensaje personalizado\nlogError(\"Este es un ejemplo de mensaje de log personalizado\");\n\nconsole.log(\"Logs enviados al archivo configurado.\");\n\n\n// Extra\n\nclass TaskManager {\n    constructor() {\n        this.tasks = {};\n    }\n\n    addTask(name, description) {\n        const startTime = process.hrtime();\n\n        if (this.tasks[name]) {\n            logError(`Advertencia: La tarea '${name}' ya existe.`);\n            return false;\n        }\n\n        this.tasks[name] = description;\n        logError(`Información: Tarea '${name}' añadida.`);\n\n        const endTime = process.hrtime(startTime);\n        const executionTime = endTime[0] + endTime[1] / 1e9;\n        logError(`Tiempo de ejecución para añadir tarea '${name}': ${executionTime} segundos.`);\n\n        return true;\n    }\n\n    deleteTask(name) {\n        const startTime = process.hrtime();\n\n        if (!this.tasks[name]) {\n            logError(`Advertencia: La tarea '${name}' no existe.`);\n            return false;\n        }\n\n        delete this.tasks[name];\n        logError(`Información: Tarea '${name}' eliminada.`);\n\n        const endTime = process.hrtime(startTime);\n        const executionTime = endTime[0] + endTime[1] / 1e9;\n        logError(`Tiempo de ejecución para eliminar tarea '${name}': ${executionTime} segundos.`);\n\n        return true;\n    }\n\n    listTasks() {\n        const startTime = process.hrtime();\n\n        if (Object.keys(this.tasks).length === 0) {\n            logError(\"Información: No hay tareas para listar.\");\n            return [];\n        }\n\n        const endTime = process.hrtime(startTime);\n        const executionTime = endTime[0] + endTime[1] / 1e9;\n        logError(`Tiempo de ejecución para listar tareas: ${executionTime} segundos.`);\n\n        return this.tasks;\n    }\n}\n\nconst taskManager = new TaskManager();\n\nconsole.log(\"\\n\\nEJERCICIO EXTRA\\n\\n\");\n\nconst showMenu = () => {\n    console.log(\"\\nGestión de Tareas\");\n    console.log(\"1. Añadir tarea\");\n    console.log(\"2. Eliminar tarea\");\n    console.log(\"3. Listar tareas\");\n    console.log(\"4. Salir\");\n    console.log(\"Seleccione una opción: \");\n};\n\nconst addTask = async (taskManager) => {\n    const readline = require('readline').createInterface({\n        input: process.stdin,\n        output: process.stdout\n    });\n\n    readline.question(\"Ingrese el nombre de la tarea: \", (name) => {\n        readline.question(\"Ingrese la descripción de la tarea: \", (description) => {\n            if (taskManager.addTask(name, description)) {\n                console.log(`Tarea '${name}' añadida con éxito.`);\n            } else {\n                console.log(`Error al añadir la tarea '${name}'.`);\n            }\n            readline.close();\n        });\n    });\n};\n\nconst deleteTask = async (taskManager) => {\n    const readline = require('readline').createInterface({\n        input: process.stdin,\n        output: process.stdout\n    });\n\n    readline.question(\"Ingrese el nombre de la tarea a eliminar: \", (name) => {\n        if (taskManager.deleteTask(name)) {\n            console.log(`Tarea '${name}' eliminada con éxito.`);\n        } else {\n            console.log(`Error al eliminar la tarea '${name}'.`);\n        }\n        readline.close();\n    });\n};\n\nconst listTasks = (taskManager) => {\n    const tasks = taskManager.listTasks();\n    if (tasks.length === 0) {\n        console.log(\"No hay tareas.\");\n    } else {\n        console.log(\"Lista de Tareas:\");\n        for (const [name, description] of Object.entries(tasks)) {\n            console.log(` - ${name}: ${description}`);\n        }\n    }\n};\n\nconst main = async () => {\n    const readline = require('readline').createInterface({\n        input: process.stdin,\n        output: process.stdout\n    });\n\n    const getChoice = () => {\n        return new Promise((resolve) => {\n            showMenu();\n            readline.question(\"\", (choice) => {\n                resolve(choice);\n            });\n        });\n    };\n\n    while (true) {\n        const choice = await getChoice();\n        switch (choice) {\n            case '1':\n                await addTask(taskManager);\n                break;\n            case '2':\n                await deleteTask(taskManager);\n                break;\n            case '3':\n                listTasks(taskManager);\n                break;\n            case '4':\n                console.log(\"Saliendo...\");\n                readline.close();\n                process.exit();\n            default:\n                console.log(\"Opción no válida. Por favor, intente de nuevo.\");\n        }\n    }\n};\n\nmain();\n"
  },
  {
    "path": "Roadmap/25 - LOGS/javascript/parababire.js",
    "content": "// The console object is a property of the window object.\n// Console severity levels\n  /* \n    .- Verbose: console.debug()\n    .- Info: console.info(), console.log()\n    .- Warnings: console.warn()\n    .- Errors: console.error()\n  */\n\n/* Filtrar cuales logs aparecen en consola, dependiendo de la severidad, solo puede ser seteado en el devtool del browser */\n\n/* Métodos del objeto console comunmente usados. Los métodos .group, .groupEnd, .table; así como, el uso de especificadores de formato, nos permiten configurar nuestros loggings */\n\nlet gretting = 'Hola Javascript'\n\nconsole.group('Inicio logging')\n// Consejo: Darle contexto a las salidas por consola. \nconsole.debug('Esto es un console.debug():','Message debug process')\nconsole.log('Esto es un console.log():', 'Hola Javascript')\nconsole.log({gretting}) // Mejora el contexto de la salida por consola\nconsole.info('Esto es un console.info():','No Fumar')\nconsole.warn('Esto es un console.warn():','Atención')\nconsole.error('Esto es un console.error():','Syntax error')\nconsole.groupEnd()\nconsole.log('Otro log más, que no pertebnece al grupò anterior')\n\nlet users = [\n  {\n    id: 1,\n    name: 'José',\n    phone: 12365478\n  },\n  {\n    id: 2,\n    name: 'María',\n    phone: 85641239\n  },\n  {\n    id: 3,\n    name: 'Luisa',\n    phone: 12574598\n  }\n]\n\nconsole.table(users)\n\nlet fecha = new Date().toLocaleDateString('es-es', {day: 'numeric', month: 'numeric', year: 'numeric'})\n\nconsole.log(\n  '%c Un día como hoy %s aprendí a formatear mensajes por consola',\n  'color: green; background:black; font-size: 20pt',\n  fecha\n)\n\n// Extra\n\nclass TaskManager {\n  constructor() {\n    this.tasks = {}\n  }\n\n  add_task(name, description) {\n    console.time('test1')\n    if (!this.tasks.hasOwnProperty(name)) {\n      this.tasks[name] = description\n      console.info(`Tarea añadida: ${name}`)\n      let length = Object.entries(this.tasks).length\n      console.debug('DEBUG:', `Número de tareas: ${length}`)\n      this.tasks\n    } else {\n      console.warn(`Se ha intentado ingresar una tarea que ya existe: ${name}`)\n    }\n    console.timeEnd('test1')\n  }\n\n  delete_task(name) {\n    console.time('test2')\n    if (this.tasks.hasOwnProperty(name)) {\n      delete this.tasks[name]\n      console.info(`Tarea eliminada: ${name}`)\n      let length = Object.entries(this.tasks).length\n      console.debug('DEBUG:', `Número de tareas: ${length}`)\n    } else {\n      console.error(`Se está intentado eliminar una tarea que no existe: ${name}`)\n    }\n    console.timeEnd('test2')\n  }\n\n  get list_task() {\n    console.time('time3')\n    Object.entries(this.tasks).forEach(([key, value]) => {\n      console.log(`${key}: ${value}`)\n    })\n    console.timeEnd('time3')\n  }\n}\nlet taskList = new TaskManager()\ntaskList.add_task('Comprar Pan', 'Compra 5 panes')\ntaskList.add_task('Comprar sixpack', 'Compra 2 sixpack')\ntaskList.list_task\ntaskList.delete_task('Comprar sixpack')\ntaskList.list_task"
  },
  {
    "path": "Roadmap/25 - LOGS/javascript/pedamoci.js",
    "content": "const niveles = {\n  DEBUG: 'DEBUG',\n  INFO: 'INFO',\n  WARNING: 'WARNING',\n  ERROR: 'ERROR'\n};\n\nfunction log(nivel, mensaje) {\n  const fecha = new Date().toISOString()\n  const formato = `${fecha} - ${nivel} - ${mensaje}`\n\n  switch (nivel) {\n    case niveles.DEBUG:\n      console.debug(formato)\n      break\n    case niveles.INFO:\n      console.info(formato)\n      break\n    case niveles.WARNING:\n      console.warn(formato)\n      break\n    case niveles.ERROR:\n      console.error(formato)\n      break\n    default:\n      console.log(formato)\n  }\n}\n\nlog(niveles.DEBUG, \"Esto es un mensaje de DEBUG\")\nlog(niveles.INFO, \"Esto es un mensaje de INFO\")\nlog(niveles.WARNING, \"Esto es un mensaje de WARNING\")\nlog(niveles.ERROR, \"Esto es un mensaje de ERROR\")\n\n// ---------------------------------------- DIFICULTAD EXTRA ----------------------------------------\nclass TaskManager {\n  constructor() {\n    this.tasks = {}\n  }\n\n  addTask(nameTask, description) {\n    const startTime = performance.now()\n    if (Object.hasOwn(this.tasks, nameTask)) console.warn('Ya existe una tarea con ese nombre')\n    else {\n      Object.assign(this.tasks, {[nameTask]: description})\n      console.info('La tarea se ha agregado correctamente')\n    }\n    console.debug(`tenes ${Object.keys(this.tasks).length} tarea/s pendiente/s`)\n    const endTime = performance.now()\n    console.log(`Tiempo de ejecución: ${(endTime - startTime).toFixed(2)}s`)\n  }\n\n  deleteTask(nameTask) {\n    const startTime = performance.now()\n    if (Object.hasOwn(this.tasks, nameTask)) {\n      delete this.tasks[nameTask]\n      console.info('La tarea se ha borrado correctamente')\n    }\n    else console.error('La tarea que desea eliminar no existe')\n    const endTime = performance.now()\n    console.log(`Tiempo de ejecución: ${(endTime - startTime).toFixed(2)}s`)\n  }\n\n  viewTaks() {\n    const startTime = performance.now()\n    console.info(this.tasks)\n    const endTime = performance.now()\n    console.log(`Tiempo de ejecución: ${(endTime - startTime).toFixed(2)}s`)\n  }\n}\n\nconst taskManager = new TaskManager\ntaskManager.addTask('javascript', 'terminar el ejercicio 25 de javascript')\ntaskManager.addTask('papel', 'comprar todo el papel higienico por si se viene el apocalipsis')\ntaskManager.viewTaks()\ntaskManager.deleteTask('noExisto')\ntaskManager.deleteTask('papel')\ntaskManager.viewTaks()"
  },
  {
    "path": "Roadmap/25 - LOGS/javascript/victor-Casta.js",
    "content": "/*\n * EJERCICIO:\n * Explora el concepto de \"logging\" en tu lenguaje. Configúralo y muestra\n * un ejemplo con cada nivel de \"severidad\" disponible.\n */\n\nlet x = 5\nconsole.assert(x > 10, \"El valor de x no es mayor que 10\")\n\nconsole.clear()\n\nconsole.log(\"Este es un mensaje de log\")\n\nconsole.info(\"Información: el programa ha iniciado correctamente\")\n\nconsole.warn(\"Advertencia: estás a punto de alcanzar el límite de uso\")\n\nconsole.error(\"Error: el archivo no pudo ser encontrado\")\n\nconsole.debug(\"Debug: se está calculando el valor\")\n\nfunction greeting(user) {\n  console.count(\"Llamadas a greeting\")\n  return `Hi ${user}`\n}\n\ngreeting('user_1')\ngreeting('user_1')\ngreeting('user_1')\n\nconsole.countReset(\"Llamadas a greeting\")\ngreeting('user_1')\n\nfunction addition(a, b) {\n  console.debug(\"Debug: calculando el total de \", a, b)\n  return a + b\n}\n\naddition(1, 2)\n\nlet users = {\n  name: \"Victor\",\n  age: 21,\n  address: {\n    city: \"Madrid\",\n    country: \"España\",\n  },\n}\n\nconsole.dir(users, { depth: 1, colors: true })\n\nif (typeof document !== 'undefined') {\n  console.dirxml(document.body)\n}\n\n/*\n  * DIFICULTAD EXTRA (opcional):\n  * Crea un programa ficticio de gestión de tareas que permita añadir, eliminar\n  * y listar dichas tareas.\n  * - Añadir: recibe nombre y descripción.\n  * - Eliminar: por no mbre de la tarea.\n  * Implementa diferentes mensajes de log que muestren información según la\n  * tarea ejecutada (a tu elección).\n  * Utiliza el log para visualizar el tiempo de ejecución de cada tarea.\n*/\n\nconst readline = require('node:readline')\nconst { stdin: input, stdout: output } = require('node:process')\n\nconst rl = readline.createInterface({ input, output })\nlet tasks = []\n\nfunction schedule() {\n  console.log('- Gestor de tareas -')\n  console.log('1 - Añadir')\n  console.log('2 - Eliminar')\n  console.log('3 - Listar')\n  console.log('4 - Salir')\n\n  rl.question('Ingresa una opción: ', (response) => {\n    if (response === '1') {\n      rl.question('Ingrese el nombre de la Tarea: ', (taskName) => {\n        rl.question('Ingresa la descripción de la tarea: ', (taskDescription) => {\n          if (taskName && taskDescription) {\n            console.time('Tiempo de ejecución')\n            console.log(`Tarea añadida: ${taskName} - ${taskDescription}`)\n            tasks.push({ name: taskName, description: taskDescription })\n            console.timeEnd('Tiempo de ejecución')\n          } else {\n            console.log('El nombre y la descripción de la tarea son obligatorios.')\n          }\n          schedule()\n        })\n      })\n    } else if (response === '2') {\n      rl.question('Ingresa el nombre de la tarea a eliminar: ', (taskName) => {\n        console.time('Tiempo de ejecución')\n        const originalLength = tasks.length\n        tasks = tasks.filter(item => !item.name.toLowerCase().includes(taskName.toLowerCase()))\n        if (tasks.length < originalLength) {\n          console.log(`Tarea eliminada: ${taskName}`)\n        } else {\n          console.log(`No se encontró la tarea: ${taskName}`)\n        }\n        console.timeEnd('Tiempo de ejecución')\n        schedule()\n      })\n    } else if (response === '3') {\n      console.time('Tiempo de ejecución')\n      if (tasks.length > 0) {\n        console.table(tasks)\n      } else {\n        console.log('No hay tareas para mostrar.')\n      }\n      console.timeEnd('Tiempo de ejecución')\n      schedule()\n    } else if (response === '4') {\n      console.log('Saliendo del gestor de tareas...')\n      rl.close()\n    } else {\n      console.log('Opción no válida. Intente de nuevo.')\n      schedule()\n    }\n  })\n}\n\nschedule()"
  },
  {
    "path": "Roadmap/25 - LOGS/kotlin/blackriper.kt",
    "content": "import io.github.oshai.kotlinlogging.KotlinLogging\r\n\r\n\r\n/*\r\nLogs\r\nLos logs son mensajes que sirven como historial de eventos sucedidos en la aplicacion\r\nestos sirven para informar  a los desarrolladores sobre diferentes eventos que ocurren en la aplicacion\r\n\r\nlos logs se clasifican en\r\n- Debug\r\n- Trace\r\n- Info\r\n- Warning\r\n- Error\r\n\r\ncomo sus nombres los indican estos  son eventos que ocurren en la aplicacion al clasficarlos\r\ntambien se les puede dar prioridad esto ayuda a configurar parametros para dar a conocer a los\r\ndesarrolladores eventos que ocurren en la aplicacion. por lo general los Error tienen mayor prioridad\r\n\r\ndepedencias\r\nhttps://github.com/oshai/kotlin-logging logger\r\nhttps://mvnrepository.com/artifact/org.slf4j/slf4j-api depedencia padre\r\nhttps://mvnrepository.com/artifact/ch.qos.logback/logback-classic/1.5.6  formateo y prioridada de los logs\r\nhttps://github.com/Tuxdude/logback-colorizer dar color a los logs opcional pero quedan bonitos con colores\r\n\r\narchivo basico de formatos de logs src/main/resources/logback.xml\r\n    <property scope=\"context\" name=\"COLORIZER_COLORS\" value=\"red@,yellow@,green@,blue@,cyan@\" />\r\n    <conversionRule conversionWord=\"colorize\" converterClass=\"org.tuxdude.logback.extensions.LogColorizer\" />\r\n    <appender name=\"STDOUT\" class=\"ConsoleAppender\">\r\n        <encoder class=\"PatternLayoutEncoder\">\r\n            <pattern>%colorize(%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} -- %msg%n) </pattern>\r\n        </encoder>\r\n    </appender>\r\n\r\n    <root level=\"trace\">\r\n        <appender-ref ref=\"STDOUT\" />\r\n    </root>\r\n</configuration>\r\n\r\ntutorial basico\r\nhttps://saltnlight5.blogspot.com/2013/08/how-to-configure-slf4j-with-different.html\r\n\r\n */\r\n\r\nval logger= KotlinLogging.logger {  }\r\n\r\nfun exampleWithLogs() {\r\n    // probando alguna funcion\r\n    logger.debug { \"debug message\" }\r\n    // seguimientos de eventos en la aplicacion conexion de base de datos etc\r\n    logger.trace { \"trace message\" }\r\n    // informamos sobre  cosas que ocurren en la aplicacion\r\n    logger.info { \"info message\" }\r\n    // informamos sobre eventos que podrian generar error en caso de no atederse\r\n    logger.warn { \"warn message\" }\r\n    // informamos sobre eventos  de error en la aplicacion\r\n    logger.error { \"error message\" }\r\n}\r\n\r\n// ejercicio extra\r\ndata class Task(val name:String,val description:String,var done:Boolean=false)\r\n\r\ninterface TaskRepository{\r\n    fun save(task:Task)\r\n    fun delete(name:String)\r\n    fun completedTask(name: String)\r\n    fun getAll():List<Task>\r\n    fun getTaskBy(predicate:(Task)->Boolean):List<Task>\r\n}\r\n\r\nclass TaskManager:TaskRepository{\r\n    private val tasks= mutableListOf<Task>()\r\n    override fun save(task: Task) {\r\n        logger.trace { \"new task recived for add list\" }\r\n        val registred=tasks.add(task)\r\n        if(registred) logger.info { \"task ${task.name} was added to the list\" }\r\n     }\r\n\r\n    override fun delete(name: String) {\r\n       logger.trace { \"task $name recived for deleted\" }\r\n       val deleted=tasks.removeIf { it.name==name }\r\n       if(deleted) logger.info { \"task $name was deleted\" }\r\n       else logger.error { \"task $name not found\" }\r\n    }\r\n\r\n    override fun completedTask(name: String) {\r\n        logger.trace { \"task $name recived for completed\" }\r\n        tasks.find { it.name==name }.let {\r\n            if (it==null) logger.warn {\"task name is null value\"  }\r\n            it?.done=true\r\n            logger.info { \"task $name was completed\" }\r\n        }\r\n    }\r\n\r\n    override fun getAll(): List<Task> {\r\n        logger.trace { \"get all tasks\" }\r\n        return tasks\r\n    }\r\n\r\n    override fun  getTaskBy(predicate: (Task) -> Boolean): List<Task>{\r\n        logger.trace {\"find task with predicate\"}\r\n        return tasks.filter { predicate(it) }\r\n    }\r\n\r\n}\r\n\r\n\r\n\r\nfun main() {\r\n    exampleWithLogs()\r\n    val task1=Task(\"Clean my room\",\"clean my room\")\r\n    val task3=Task(\"migration\",\"migrate maven to kotlin dsl\")\r\n    val task4=Task(\"solution for programming roadmap\",\"create a solution for programming roadmap\")\r\n    val manager=TaskManager()\r\n    manager.save(task1)\r\n    manager.save(task3)\r\n    manager.save(task4)\r\n    manager.delete(\"migration\")\r\n    manager.completedTask(\"Clean my room\")\r\n    manager.getAll().forEach { println(it) }\r\n    manager.getTaskBy { it.done==true }.forEach { println(it) }\r\n\r\n}"
  },
  {
    "path": "Roadmap/25 - LOGS/kotlin/eulogioep.kt",
    "content": "import java.time.LocalDateTime\nimport java.time.Duration\n\n// Concepto de LOGS (Logging):\n// Los logs son registros de eventos que ocurren durante la ejecución de un programa.\n// Son cruciales para el diagnóstico de problemas, monitoreo del rendimiento y\n// seguimiento de la actividad del sistema. En este ejemplo, implementaremos\n// un sistema de logging simple para evitar problemas de permisos.\n\n// Enum para los niveles de log\nenum class LogLevel {\n    INFO, WARNING, ERROR, DEBUG, TRACE\n}\n\n// Clase simple para manejar logging\nclass SimpleLogger(private val name: String) {\n    fun log(level: LogLevel, message: String) {\n        println(\"${LocalDateTime.now()} [$level] $name: $message\")\n    }\n\n    fun info(message: String) = log(LogLevel.INFO, message)\n    fun warning(message: String) = log(LogLevel.WARNING, message)\n    fun error(message: String) = log(LogLevel.ERROR, message)\n    fun debug(message: String) = log(LogLevel.DEBUG, message)\n    fun trace(message: String) = log(LogLevel.TRACE, message)\n}\n\nclass TaskManager {\n    private val logger = SimpleLogger(TaskManager::class.java.simpleName)\n    private val tasks = mutableListOf<Task>()\n\n    fun addTask(name: String, description: String) {\n        val startTime = LocalDateTime.now()\n        logger.info(\"Iniciando añadir tarea: $name\")\n        \n        tasks.add(Task(name, description))\n        \n        val endTime = LocalDateTime.now()\n        val duration = Duration.between(startTime, endTime)\n        logger.info(\"Tarea añadida: $name. Tiempo de ejecución: ${duration.toMillis()} ms\")\n    }\n\n    fun removeTask(name: String) {\n        val startTime = LocalDateTime.now()\n        logger.warning(\"Iniciando eliminación de tarea: $name\")\n        \n        val removed = tasks.removeIf { it.name == name }\n        if (removed) {\n            logger.info(\"Tarea eliminada: $name\")\n        } else {\n            logger.error(\"No se encontró la tarea: $name\")\n        }\n        \n        val endTime = LocalDateTime.now()\n        val duration = Duration.between(startTime, endTime)\n        logger.debug(\"Tiempo de ejecución para eliminar tarea: ${duration.toMillis()} ms\")\n    }\n\n    fun listTasks() {\n        val startTime = LocalDateTime.now()\n        logger.info(\"Listando todas las tareas\")\n        \n        tasks.forEach { task ->\n            logger.debug(\"Tarea: ${task.name}, Descripción: ${task.description}\")\n        }\n        \n        val endTime = LocalDateTime.now()\n        val duration = Duration.between(startTime, endTime)\n        logger.trace(\"Tiempo de ejecución para listar tareas: ${duration.toMillis()} ms\")\n    }\n}\n\ndata class Task(val name: String, val description: String)\n\nfun main() {\n    val taskManager = TaskManager()\n\n    // Ejemplos de uso con diferentes niveles de severidad\n    taskManager.addTask(\"Comprar víveres\", \"Ir al supermercado y comprar alimentos\")\n    taskManager.addTask(\"Hacer ejercicio\", \"30 minutos de cardio\")\n    taskManager.listTasks()\n    taskManager.removeTask(\"Hacer ejercicio\")\n    taskManager.removeTask(\"Tarea inexistente\")\n    taskManager.listTasks()\n}"
  },
  {
    "path": "Roadmap/25 - LOGS/ocaml/luishendrix92.ml",
    "content": "(******************************************************************************)\n(*                                                                            *)\n(*                                  Logging                                   *)\n(*                                                                            *)\n(*  Logging is a practise where the developers of an application display      *)\n(*  information about what's going on at runtime to an output channel, which  *)\n(*  can be either the standard output channel (aka, the console window), or   *)\n(*  a file writter so that we can create and manage log files that can be     *)\n(*  used by both developers and users alike to debug a particular problem.    *)\n(*                                                                            *)\n(*  Logging libraries exist in every language and they all have some things   *)\n(*  in common, especially the important concept of a {b level}. A level is    *)\n(*  a tier of severity for a message displayed on the channel. For example,   *)\n(*  a user can be concerned only with log messages written by the developer   *)\n(*  for the end user (also known as \"application level\"); or maybe it's set   *)\n(*  to {e debug} which will display messages intended for displaying the      *)\n(*  flow of data structures in a readable manner, which should not be shown   *)\n(*  to the end user. That's why loggers have a function to set this level.    *)\n(*                                                                            *)\n(******************************************************************************)\n\nlet stamp_tag : Mtime.span Logs.Tag.def =\n  Logs.Tag.def \"stamp\" ~doc:\"Relative monotonic time stamp\" Mtime.Span.pp\n;;\n\nlet stamp c = Logs.Tag.(empty |> add stamp_tag (Mtime_clock.count c))\n\nlet log_levels () =\n  Logs.app (fun m -> m \"This message is only shown at the Logs.App level.\");\n  (* This message won't be displayed! I set the level to Logs.Info, which is\n     one level above Debug. To show it I'd have to change it to Logs.Debug. *)\n  Logs.debug (fun m -> m \"Only shown during Logs.Debug, ideal for development.\");\n  Logs.info (fun m -> m \"Normal message with information about the processes.\");\n  Logs.warn (fun m -> m \"The ozone layer is in danger :(\");\n  Logs.err (fun m -> m \"Error reporting, recoverable or caught\");\n  Logs.info (fun m ->\n    m \"Message with a custom header called 'DONUT'...\" ?header:(Some \"DONUT\"))\n;;\n\n(* DIFICULTAD EXTRA (opcional):\n   ============================\n   Crea un programa ficticio de gestión de tareas que permita añadir, eliminar\n   y listar dichas tareas.\n   - Añadir: recibe nombre y descripción.\n   - Eliminar: por nombre de la tarea.\n\n   Implementa diferentes mensajes de log que muestren información según la\n   tarea ejecutada (a tu elección).\n   Utiliza el log para visualizar el tiempo de ejecución de cada tarea. *)\nmodule TaskRepository = struct\n  type task =\n    { name : string\n    ; description : string\n    }\n  [@@deriving show { with_path = false }]\n\n  let tasks : (string, task) Hashtbl.t =\n    Logs.info (fun m -> m \"TaskRepository hash table initialized\");\n    Hashtbl.create 100\n  ;;\n\n  let add task =\n    if Hashtbl.mem tasks task.name\n    then\n      Logs.warn (fun m ->\n        m \"Task [%s] already exists so it will be replaced.\" task.name);\n    Hashtbl.replace tasks task.name task;\n    Logs.info (fun m -> m \"Task [%s] added to the repository.\" (show_task task))\n  ;;\n\n  let remove_by_name name =\n    if not (Hashtbl.mem tasks name)\n    then\n      Logs.err (fun m ->\n        m \"Task [%s] doesn't exist, therefore it can't be deleted.\" name)\n    else begin\n      let task = Hashtbl.find tasks name in\n      Hashtbl.remove tasks name;\n      Logs.info (fun m -> m \"Task %s successfully deleted.\" (show_task task))\n    end\n  ;;\n\n  let print_all () =\n    Logs.app (fun m -> m \"List of pending tasks:\");\n    Hashtbl.iter\n      (fun _ { name; description } ->\n        Logs.app (fun m -> m \"- %s (#%s)\" description name))\n      tasks\n  ;;\nend\n\nlet extra_exercise () =\n  let c = Mtime_clock.counter () in\n  Logs.info (fun m ->\n    m \"======> Starting 4-task insertion for time measuring...\");\n  TaskRepository.add\n    { name = \"milk\"; description = \"Buy milk at the grocery store\" };\n  TaskRepository.add\n    { name = \"exercise\"; description = \"Have some abdominal exercise b4 sleep\" };\n  TaskRepository.add\n    { name = \"email\"; description = \"Send an email to my parents down south\" };\n  TaskRepository.add\n    { name = \"milk\"; description = \"Borrow milk from grandma instead\" };\n  (* Adding a tag with the [stamp] function (using the [c] clock counter will\n     cause the 2nd header of this particualr log line to display the elapsed\n     time (in microseconds) since the task started (counter created)!\n\n     NOTE: On average, inserting these 4 tasks took 40 microseconds. *)\n  Logs.info (fun m -> m \"...Finished 4-task insertion <======\" ~tags:(stamp c));\n  TaskRepository.add { name = \"delete\"; description = \"Please delete this!\" };\n  TaskRepository.remove_by_name \"delete\";\n  TaskRepository.remove_by_name \"ghost\";\n  TaskRepository.print_all ()\n;;\n\n(* Boilerplate code for a custom reporter with a timestamp tag\n   ----------------------------------------------------------------------------\n   This function is a custom reporter that looks through the set of tags and\n   extracts the specific one that handles the elapsed span of time since a\n   given stimestamp [c] (Monotonic clock tick counter). *)\nlet reporter ppf =\n  let report _src level ~over k msgf =\n    let k _ =\n      over ();\n      k ()\n    in\n    let with_stamp h tags k ppf fmt =\n      let dt =\n        Option.(\n          bind tags (Logs.Tag.find stamp_tag)\n          |> map (fun s -> Mtime.Span.to_float_ns s /. 1_000.0)\n          |> map (fun dt -> Printf.sprintf \"[%0+4.0fus]\" dt)\n          |> value ~default:\"\")\n      in\n      Format.kfprintf\n        k\n        ppf\n        (\"%a%s @[\" ^^ fmt ^^ \"@]@.\")\n        Logs.pp_header\n        (level, h)\n        dt\n    in\n    msgf @@ fun ?header ?tags fmt -> with_stamp header tags k ppf fmt\n  in\n  { Logs.report }\n;;\n\nlet _ =\n  Logs.set_reporter (reporter Format.std_formatter);\n  Logs.set_level (Some Logs.Info);\n  log_levels ();\n  print_newline ();\n  extra_exercise ();\n  ()\n;;\n"
  },
  {
    "path": "Roadmap/25 - LOGS/php/eulogioep.php",
    "content": "<?php\n/**\n * TEORÍA SOBRE LOGGING EN PHP\n * \n * PHP proporciona varias formas de implementar logging:\n * 1. error_log() - Función nativa de PHP para logging\n * 2. syslog() - Para logging en el sistema operativo\n * 3. file_put_contents() - Para escribir logs en archivos\n * 4. Librerías como Monolog - Soluciones más completas\n * \n * Niveles de severidad estándar (PSR-3):\n * - EMERGENCY: Sistema inutilizable\n * - ALERT: Acción inmediata requerida\n * - CRITICAL: Condiciones críticas\n * - ERROR: Condiciones de error\n * - WARNING: Condiciones de advertencia\n * - NOTICE: Eventos normales pero significativos\n * - INFO: Mensajes informativos\n * - DEBUG: Información detallada de depuración\n */\n\n/**\n * Clase Logger personalizada para manejar diferentes niveles de logging\n */\nclass Logger {\n    private string $logFile;\n    \n    public function __construct(string $logFile = 'app.log') {\n        $this->logFile = $logFile;\n    }\n    \n    /**\n     * Método privado para escribir el log\n     */\n    private function writeLog(string $level, string $message): void {\n        $timestamp = date('Y-m-d H:i:s');\n        $logMessage = \"[$timestamp] [$level] $message\" . PHP_EOL;\n        \n        // Escribir en archivo\n        file_put_contents($this->logFile, $logMessage, FILE_APPEND);\n        \n        // También mostrar en consola para este ejemplo\n        echo $logMessage;\n    }\n    \n    public function emergency(string $message): void {\n        $this->writeLog('EMERGENCY', $message);\n    }\n    \n    public function alert(string $message): void {\n        $this->writeLog('ALERT', $message);\n    }\n    \n    public function critical(string $message): void {\n        $this->writeLog('CRITICAL', $message);\n    }\n    \n    public function error(string $message): void {\n        $this->writeLog('ERROR', $message);\n    }\n    \n    public function warning(string $message): void {\n        $this->writeLog('WARNING', $message);\n    }\n    \n    public function notice(string $message): void {\n        $this->writeLog('NOTICE', $message);\n    }\n    \n    public function info(string $message): void {\n        $this->writeLog('INFO', $message);\n    }\n    \n    public function debug(string $message): void {\n        $this->writeLog('DEBUG', $message);\n    }\n}\n\n/**\n * Clase que representa una Tarea\n */\nclass Task {\n    public function __construct(\n        public string $name,\n        public string $description,\n        public DateTime $createdAt\n    ) {}\n}\n\n/**\n * Clase para la gestión de tareas con logging integrado\n */\nclass TaskManager {\n    private array $tasks = [];\n    private Logger $logger;\n    \n    public function __construct(Logger $logger) {\n        $this->logger = $logger;\n    }\n    \n    /**\n     * Añade una nueva tarea al sistema\n     */\n    public function addTask(string $name, string $description): void {\n        $startTime = microtime(true);\n        \n        try {\n            // Verificar si ya existe una tarea con el mismo nombre\n            foreach ($this->tasks as $task) {\n                if ($task->name === $name) {\n                    $this->logger->error(\"La tarea '$name' ya existe\");\n                    return;\n                }\n            }\n            \n            $task = new Task($name, $description, new DateTime());\n            $this->tasks[] = $task;\n            \n            $this->logger->info(\"Tarea '$name' añadida exitosamente\");\n            \n            $endTime = microtime(true);\n            $executionTime = ($endTime - $startTime) * 1000; // Convertir a millisegundos\n            $this->logger->debug(\"Tiempo de ejecución addTask: {$executionTime}ms\");\n            \n        } catch (Exception $e) {\n            $this->logger->error(\"Error al añadir tarea: \" . $e->getMessage());\n        }\n    }\n    \n    /**\n     * Elimina una tarea por su nombre\n     */\n    public function removeTask(string $name): void {\n        $startTime = microtime(true);\n        \n        try {\n            $initialCount = count($this->tasks);\n            $this->tasks = array_filter(\n                $this->tasks,\n                fn($task) => $task->name !== $name\n            );\n            \n            if (count($this->tasks) === $initialCount) {\n                $this->logger->warning(\"No se encontró la tarea '$name'\");\n            } else {\n                $this->logger->info(\"Tarea '$name' eliminada exitosamente\");\n            }\n            \n            $endTime = microtime(true);\n            $executionTime = ($endTime - $startTime) * 1000;\n            $this->logger->debug(\"Tiempo de ejecución removeTask: {$executionTime}ms\");\n            \n        } catch (Exception $e) {\n            $this->logger->error(\"Error al eliminar tarea: \" . $e->getMessage());\n        }\n    }\n    \n    /**\n     * Lista todas las tareas existentes\n     */\n    public function listTasks(): void {\n        $startTime = microtime(true);\n        \n        try {\n            if (empty($this->tasks)) {\n                $this->logger->info(\"No hay tareas registradas\");\n                return;\n            }\n            \n            $this->logger->info(\"Lista de tareas:\");\n            foreach ($this->tasks as $task) {\n                $createdAt = $task->createdAt->format('Y-m-d H:i:s');\n                $this->logger->info(\"- {$task->name}: {$task->description} (Creada: $createdAt)\");\n            }\n            \n            $endTime = microtime(true);\n            $executionTime = ($endTime - $startTime) * 1000;\n            $this->logger->debug(\"Tiempo de ejecución listTasks: {$executionTime}ms\");\n            \n        } catch (Exception $e) {\n            $this->logger->error(\"Error al listar tareas: \" . $e->getMessage());\n        }\n    }\n}\n\n// Ejemplo de uso del sistema\nfunction main() {\n    // Crear instancia del logger\n    $logger = new Logger('tareas.log');\n    $logger->info(\"Iniciando sistema de gestión de tareas\");\n    \n    // Crear instancia del gestor de tareas\n    $taskManager = new TaskManager($logger);\n    \n    // Demostrar diferentes niveles de logging\n    $logger->emergency(\"Ejemplo de mensaje emergency\");\n    $logger->alert(\"Ejemplo de mensaje alert\");\n    $logger->critical(\"Ejemplo de mensaje critical\");\n    $logger->error(\"Ejemplo de mensaje error\");\n    $logger->warning(\"Ejemplo de mensaje warning\");\n    $logger->notice(\"Ejemplo de mensaje notice\");\n    $logger->info(\"Ejemplo de mensaje info\");\n    $logger->debug(\"Ejemplo de mensaje debug\");\n    \n    // Ejemplos de uso del gestor de tareas\n    $taskManager->addTask(\"Estudiar PHP\", \"Aprender sobre logging y POO\");\n    $taskManager->addTask(\"Hacer ejercicio\", \"30 minutos de cardio\");\n    $taskManager->listTasks();\n    $taskManager->removeTask(\"Estudiar PHP\");\n    $taskManager->listTasks();\n    $taskManager->removeTask(\"Tarea inexistente\");\n    \n    $logger->info(\"Finalizando sistema de gestión de tareas\");\n}\n\n// Ejecutar el programa\nmain();"
  },
  {
    "path": "Roadmap/25 - LOGS/php/miguelex.php",
    "content": "<?php\nini_set('display_errors', 1);\nini_set('display_startup_errors', 1);\nerror_reporting(E_ALL);\n\nini_set('log_errors', 1);\nini_set('error_log', './log.txt');\n\n// Error fatal\nif (false) {\n    // Este código nunca se ejecutará\n    error_log(\"Este es un ejemplo de mensaje de error fatal\", 0);\n}\n\n// Advertencia\n$result = @file_get_contents('non_existing_file.txt');\nif ($result === false) {\n    error_log(\"Este es un ejemplo de mensaje de advertencia\", 0);\n}\n\n// Notificación\n$undefined_var;\nerror_log(\"Este es un ejemplo de mensaje de notificación\", 0);\n\n// Deprecado\nfunction oldFunction() {\n    error_log(\"Este es un ejemplo de mensaje de función obsoleta\", 0);\n}\n\noldFunction();\n\n// 5. Estricto\nclass MyClass {\n    function MyClass() {\n        error_log(\"Este es un ejemplo de mensaje de nivel estricto\", 0);\n    }\n}\n$obj = new MyClass();\n\n// 6. Mensaje personalizado\nerror_log(\"Este es un ejemplo de mensaje de log personalizado\", 0);\n\necho \"Logs enviados al archivo configurado.\";\n\n\n// Extra\n\nclass TaskManager {\n    private $tasks = [];\n\n    public function addTask($name, $description) {\n        $start_time = microtime(true);\n\n        if (isset($this->tasks[$name])) {\n            error_log(\"Advertencia: La tarea '$name' ya existe.\", 0);\n            return false;\n        }\n\n        $this->tasks[$name] = $description;\n        error_log(\"Información: Tarea '$name' añadida.\", 0);\n\n        $end_time = microtime(true);\n        $execution_time = $end_time - $start_time;\n        error_log(\"Tiempo de ejecución para añadir tarea '$name': $execution_time segundos.\", 0);\n\n        return true;\n    }\n\n    public function deleteTask($name) {\n        $start_time = microtime(true);\n\n        if (!isset($this->tasks[$name])) {\n            error_log(\"Advertencia: La tarea '$name' no existe.\", 0);\n            return false;\n        }\n\n        unset($this->tasks[$name]);\n        error_log(\"Información: Tarea '$name' eliminada.\", 0);\n\n        $end_time = microtime(true);\n        $execution_time = $end_time - $start_time;\n        error_log(\"Tiempo de ejecución para eliminar tarea '$name': $execution_time segundos.\", 0);\n\n        return true;\n    }\n\n    public function listTasks() {\n        $start_time = microtime(true);\n\n        if (empty($this->tasks)) {\n            error_log(\"Información: No hay tareas para listar.\", 0);\n            return [];\n        }\n\n        $end_time = microtime(true);\n        $execution_time = $end_time - $start_time;\n        error_log(\"Tiempo de ejecución para listar tareas: $execution_time segundos.\", 0);\n\n        return $this->tasks;\n    }\n}\n\n$taskManager = new TaskManager();\n\necho \"\\n\\nEJERCICIO EXTRA\\n\\n\";\n\nfunction showMenu() {\n    echo \"\\nGestión de Tareas\\n\";\n    echo \"1. Añadir tarea\\n\";\n    echo \"2. Eliminar tarea\\n\";\n    echo \"3. Listar tareas\\n\";\n    echo \"4. Salir\\n\";\n    echo \"Seleccione una opción: \";\n}\n\nfunction addTask($taskManager) {\n    echo \"Ingrese el nombre de la tarea: \";\n    $name = trim(fgets(STDIN));\n    echo \"Ingrese la descripción de la tarea: \";\n    $description = trim(fgets(STDIN));\n\n    if ($taskManager->addTask($name, $description)) {\n        echo \"Tarea '$name' añadida con éxito.\\n\";\n    } else {\n        echo \"Error al añadir la tarea '$name'.\\n\";\n    }\n}\n\nfunction deleteTask($taskManager) {\n    echo \"Ingrese el nombre de la tarea a eliminar: \";\n    $name = trim(fgets(STDIN));\n\n    if ($taskManager->deleteTask($name)) {\n        echo \"Tarea '$name' eliminada con éxito.\\n\";\n    } else {\n        echo \"Error al eliminar la tarea '$name'.\\n\";\n    }\n}\n\nfunction listTasks($taskManager) {\n    $tasks = $taskManager->listTasks();\n    if (empty($tasks)) {\n        echo \"No hay tareas.\\n\";\n    } else {\n        echo \"Lista de Tareas:\\n\";\n        foreach ($tasks as $name => $description) {\n            echo \" - $name: $description\\n\";\n        }\n    }\n}\n\nwhile (true) {\n    showMenu();\n    $choice = trim(fgets(STDIN));\n\n    switch ($choice) {\n        case '1':\n            addTask($taskManager);\n            break;\n        case '2':\n            deleteTask($taskManager);\n            break;\n        case '3':\n            listTasks($taskManager);\n            break;\n        case '4':\n            echo \"Saliendo...\\n\";\n            exit;\n        default:\n            echo \"Opción no válida. Por favor, intente de nuevo.\\n\";\n    }\n}\n\n\n\n"
  },
  {
    "path": "Roadmap/25 - LOGS/python/AChapeton.py",
    "content": "import logging\n\n# Mensaje generico\nlogging.debug('Este es un mensaje generico')\n\n# Mensaje informativo\nlogging.info('Este es un mensaje informativo')\n\n# Mensaje de advertencia\nlogging.warning('Este es un log para mostrar una advertencia')\n\n# Mensaje de error\nlogging.error('Este es un mensaje de error')\n\n# Mensaje critico\nlogging.critical('Este es un mensaje de error critico')"
  },
  {
    "path": "Roadmap/25 - LOGS/python/Aldroide.py",
    "content": "\"\"\"\n    Ejercicio: Explora el concepto de \"logging\" en tu lenguaje. configuralo\n    y muestra un ejemplo con cada nivel de \"severidad\" disponible.\n\"\"\"\n\nimport logging\nimport time\n\nlogging.basicConfig(level=logging.DEBUG,\n                    format=\"%(asctime)s - %(levelname)s - %(message)s\",\n                    handlers=[logging.StreamHandler()])\n\nlogging.debug(\"Esto es un mensaje de DEBUG\")\nlogging.info(\"Esto es un mensaje de INFO\")\nlogging.warning(\"Esto es un mensaje de warning\")\nlogging.error(\"Esto es un mensaje de ERROR\")\nlogging.critical(\"Esto es un mensaje de CRITICAL\")\n\n\"\"\"\n    Dificultad Extra (opcional):\n    Crea un programa ficticio de gestión de tareas que permita añadir, eliminar \n    y listar dichas tareas.\n    - Añadir: recibe nombre y descripción.\n    - Eliminar: por nombre de la tarea.\n    Implementa diferentes mensajes de log que muestren información según \n    la tarea ejecutada (a tu elección)\n    Utiliza el log para visualizar el tiempo de ejecución de cada tarea.\n\"\"\"\n\n\nclass TaskManager:\n    def __init__(self) -> None:\n        self.tasks = {}\n\n    def add_task(self, name: str, description: str):\n        start_time = time.time()\n        if name not in self.tasks:\n            self.tasks[name] = description\n            logging.info(f\"Tarea añadida: {name}.\")\n        else:\n            logging.warning(f\"Se ha intentado una tarea existente: {name}.\")\n        logging.debug(f\"Número de tareas: {len(self.tasks)}\")\n        end_time = time.time()\n        self._print_time(start_time, end_time)\n\n    def delete_task(self, name: str):\n        start_time = time.time()\n        if name in self.tasks:\n            del self.tasks[name]\n            logging.info(f\"se ha eliminmado la tarea: {name}.\")\n        else:\n            logging.warning(\n                f\"Se ha intentado eliminar una tarea que no existe {name}\")\n        logging.debug(f\"Numero de tareas: {len(self.tasks)}\")\n        end_time = time.time()\n        self._print_time(start_time, end_time)\n\n    def list_tasks(self):\n        star_time = time.time()\n        if self.tasks:\n            logging.info(f\"Se va aimprimir la lista de tareas.\")\n            for name, description in self.tasks.items():\n                print(f\"{name} - {description}\")\n        else:\n            logging.info(\"No hay tareas que mostrar.\")\n        end_time = time.time()\n        self._print_time(star_time, end_time)\n\n    def _print_time(self, start_time, end_time):\n        logging.debug(\n            f\"Tiempo de ejecución: {end_time - start_time:.6f} segundos.\")\n\n\ntask_manager = TaskManager()\ntask_manager.list_tasks()\ntask_manager.add_task(\"Fotografía\", \"Revelar fotos de Lia\")\ntask_manager.add_task(\"Python\", \"Estudiar Python para ciencia de datos\")\ntask_manager.list_tasks()\ntask_manager.delete_task(\"Python\")\ntask_manager.list_tasks()\ntask_manager.add_task(\"Historia\", \"Leer los hornos de Hitler\")\ntask_manager.delete_task(\"Python\")\n"
  },
  {
    "path": "Roadmap/25 - LOGS/python/CaveroBrandon.py",
    "content": "\"\"\"\"EJERCICIO:\nExplora el concepto de \"logging\" en tu lenguaje. Configúralo y muestra\nun ejemplo con cada nivel de \"severidad\" disponible.\"\"\"\n\nimport logging\nimport time\n\nlogging.basicConfig(level=logging.DEBUG)\nlogger = logging.getLogger(__name__)\n\nlogging.debug('Detailed information, typically of interest only when diagnosing problems.')\nlogging.info('Confirmation that things are working as expected.')\nlogging.warning('An indication that something unexpected happened, or indicative of some problem in the near future'\n                ' (e.g. ‘disk space low’). The software is still working as expected.')\nlogging.error('Due to a more serious problem, the software has not been able to perform some function.')\nlogging.critical('A serious error, indicating that the program itself may be unable to continue running.')\n\n\"\"\"DIFICULTAD EXTRA (opcional):\nCrea un programa ficticio de gestión de tareas que permita añadir, eliminar y listar dichas tareas.\n- Añadir: recibe nombre y descripción.\n- Eliminar: por nombre de la tarea.\nImplementa diferentes mensajes de log que muestren información según la tarea ejecutada (a tu elección).\nUtiliza el log para visualizar el tiempo de ejecución de cada tarea.\"\"\"\n\n\nclass TaskManager:\n    def __init__(self):\n        self.tasks = {'Some': '123', 'other': '133'}\n\n    def add_task(self, name: str, description: str):\n        start_time = time.time()\n        try:\n            self.tasks[name] = description\n            logging.info(f'New task successfully added: {name}')\n        except Exception as e:\n            logging.error(f'Error adding a new task: {e}')\n        end_time = time.time()\n        self.execution_time(start_time, end_time)\n\n    def list_tasks(self):\n        start_time = time.time()\n        logging.info(f'The available tasks are:')\n        try:\n            for task, description in self.tasks.items():\n                logging.info(f'{task}: {description}')\n            logging.info('Task list was successfully printed')\n        except Exception as e:\n            logging.error(f'Error: {e}')\n        end_time = time.time()\n        self.execution_time(start_time, end_time)\n\n    def remove_task(self, name: str):\n        start_time = time.time()\n        if name not in self.tasks:\n            logging.info(f'The task \"{name}\" was not found in the task list')\n            return\n        else:\n            del self.tasks[name]\n            logging.info(f'The task \"{name}\" was successfully removed from the task list')\n        end_time = time.time()\n        self.execution_time(start_time, end_time)\n\n    def execution_time(self, start_time, end_time):\n        logging.debug(f'Execution time: {end_time - start_time:.6f} seconds')\n\n\ndef select_option():\n    try:\n        logging.info('Enter an option: ')\n        option = int(input())\n        if option == 1:\n            logging.info('***** TASK LIST *****')\n            task_manager.list_tasks()\n            show_menu()\n        elif option == 2:\n            logging.info('***** ADD A NEW TASK *****')\n            logging.info('Enter the task name: ')\n            name = input()\n            logging.info('Enter the task description: ')\n            description = input()\n            task_manager.add_task(name=name, description=description)\n            show_menu()\n        elif option == 3:\n            logging.info('***** REMOVE A TASK *****')\n            logging.info('Enter the task name to remove: ')\n            name = input()\n            task_manager.remove_task(name=name)\n            show_menu()\n        elif option == 4:\n            logging.info('Program terminated')\n        else:\n            logging.warning('Incorrect option was entered')\n            show_menu()\n    except ValueError:\n        logging.warning('Incorrect value entered, try again')\n        show_menu()\n\n\ndef show_menu():\n    logging.info('********** MENU ************')\n    logging.info('1. Show available tasks')\n    logging.info('2. Add new task')\n    logging.info('3. Remove task')\n    logging.info('4. Exit')\n    select_option()\n\n\ntask_manager = TaskManager()\nshow_menu()\n"
  },
  {
    "path": "Roadmap/25 - LOGS/python/CesarCarmona30.py",
    "content": "import logging\nimport time\n\n'''\n  EJERCICIO\n'''\n\nlogging.basicConfig(level=logging.DEBUG,\n                    format='%(asctime)s - %(levelname)s - %(message)s',\n                    handlers=[logging.StreamHandler()])\n\nlogging.debug('Esto es un mensaje de DEBUG')\nlogging.info('Esto es un mensaje de INFO')\nlogging.warning('Esto es un mensaje de WARNING')\nlogging.error('Esto es un mensaje de ERROR')\nlogging.critical('Esto es un mensaje de CRITICAL')\n\n'''\n  EXTRA\n'''\n\nclass TaskManager:\n  def __init__(self) -> None:\n    self.tasks = {}\n\n  def add_task(self, name, description):\n    start_time = time.time()\n    if name not in self.tasks:\n      self.tasks[name] = description\n      logging.info(f\"Tarea añadida: {name}.\")\n    else:\n      logging.warning(\n        f\"Se ha intentado añadir una tarea que ya existe: {name}.\")\n    logging.debug(f\"Número de tareas: {len(self.tasks)}\")\n    end_time = time.time()\n    self._print_time(start_time, end_time)\n\n  def delete_task(self, name):\n    start_time = time.time()\n    if name in self.tasks:\n      del self.tasks[name]\n      logging.info(f\"Se ha eliminado la tarea: {name}.\")\n    else:\n      logging.error(\n        f\"Se ha intentado eliminar una tarea que no existe: {name}.\")\n    logging.debug(f\"Número de tareas: {len(self.tasks)}\")\n    end_time = time.time()\n    self._print_time(start_time, end_time)\n\n  def list_tasks(self):\n    start_time = time.time()\n    if self.tasks:\n      logging.info(f\"Lista de tareas: \")\n      for name, description in self.tasks.items():\n        print(f\"{name} - {description}\")\n    else:\n      logging.info(\"No hay tareas para mostrar.\")\n    end_time = time.time()\n    self._print_time(start_time, end_time)\n\n  def _print_time(self, start_time, end_time):\n    logging.debug(\n      f\"Tiempo de ejecución {end_time - start_time:.6f} seg.\" )\n    \ntask_manager = TaskManager()\ntask_manager.list_tasks()\ntask_manager.add_task(\"Pan\", \"Comprar 5 barras de pan\")\ntask_manager.add_task(\"Python\", \"Estudiar Python\")\ntask_manager.list_tasks()\ntask_manager.delete_task(\"Python\")\ntask_manager.list_tasks()\ntask_manager.add_task(\"Pan\", \"Comprar 5 barras de pan\")\ntask_manager.delete_task(\"Python\")"
  },
  {
    "path": "Roadmap/25 - LOGS/python/Chrisdev00.py",
    "content": "\"\"\"\n* EJERCICIO:\n* Explora el concepto de \"logging\" en tu lenguaje. Configúralo y muestra\n* un ejemplo con cada nivel de \"severidad\" disponible.\n*\n* DIFICULTAD EXTRA (opcional):\n* Crea un programa ficticio de gestión de tareas que permita añadir, eliminar\n* y listar dichas tareas.\n* - Añadir: recibe nombre y descripción.\n* - Eliminar: por nombre de la tarea.\n* Implementa diferentes mensajes de log que muestren información según la \n* tarea ejecutada (a tu elección).\n* Utiliza el log para visualizar el tiempo de ejecución de cada tarea. \n\"\"\"\n\nimport logging\n\nlogging.basicConfig(\n    level=logging.DEBUG,\n    #filename=\"test.log\", filemode=\"w\",      # Crea un archivo.log con los diferentes mensajes o logs\n    format=\"%(asctime)s - %(levelname)s - %(message)s\",\n    datefmt=\"%Y-%m-%d %H:%M:%S\"\n)\n\nlogger = logging.getLogger(__name__)\n\nlogger.debug('Este es un mensaje de depuración (DEBUG)')\nlogger.info('Este es un mensaje informativo (INFO)')\nlogger.warning('Este es un mensaje de advertencia (WARNING)')\nlogger.error('Este es un mensaje de error (ERROR)')   # Usado normalmente en try/catch\nlogger.critical('Este es un mensaje crítico (CRITICAL)')\n\n\n#############------------------------------------ EXTRA ------------------------------ #####################\n\nimport random\n\nclass TaskManager:\n\n    def __init__(self):\n        self.tasks = {}\n        logger.info(\"Gestor de Tareas inicializado.\")\n\n    def add_task(self):\n        name = input(\"Ingrese el nombre de la tarea: \")\n        description = input(\"Ingrese la descripcion de la tarea: \")\n        if name in self.tasks:\n            logger.warning(f\"Intento de añadir una tarea ya existente: {name}\")\n            return\n        execution_time = random.randint(1, 5)\n        self.tasks[name] = {\n            \"description\": description,\n            \"execution_time\": execution_time\n        }\n        logger.info(f\"Tarea '{name}' añadida.\")\n        logger.debug(f\"Tiempo de ejecucion de la tarea: '{name}': {execution_time} segundos.\")\n\n    def delete_task(self):\n        name = input(\"Ingrese el nombre de la tarea a eliminar: \")        \n        if name not in self.tasks:\n            logger.warning(f\"Intento de eliminar una tarea inexistente: {name}\")\n            return\n        del self.tasks[name]        \n        logger.info(f\"Tarea '{name}' eliminada.\")\n\n    def list_tasks(self):\n        if not self.tasks:\n            logger.info(\"No hay tareas para listar\")\n            return\n        for name, info in self.tasks.items():\n            print(f\"Tarea: {name} - Descripcion: {info['description']} - Tiempo de ejecucion: {info['execution_time']} segundos\")\n            logger.info(f\"Tiempo de ejecucion de la tarea '{name}' es {info['execution_time']} segundos.\")\n\nmanager = TaskManager()\n\nwhile True:\n    print(\"\\nGestor de Tareas\")\n    print(\"1. Añadir tarea\")\n    print(\"2. Eliminar tarea\")\n    print(\"3. Listar tareas\")\n    print(\"4. Salir\")\n    choice = input(\"Seleccione una opción: \")\n    if choice == '1':\n        manager.add_task()\n    elif choice == '2':\n        manager.delete_task()\n    elif choice == '3':\n        manager.list_tasks()\n    elif choice == '4':\n        break\n    else:\n        print(\"Opción no válida, por favor intente nuevamente.\")"
  },
  {
    "path": "Roadmap/25 - LOGS/python/EmmanuelMMontesinos.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Explora el concepto de \"logging\" en tu lenguaje. Configúralo y muestra\n * un ejemplo con cada nivel de \"severidad\" disponible.\n */\n\"\"\"\n# Logging\nimport logging\n\n# Creando mi propio Log\nlog = logging.getLogger(\"Mi Log\")\nlog.setLevel(level=logging.DEBUG) # Lo pongo en modo DEBUG para que capture todos los mensajes\n\nformato = logging.Formatter(\"%(asctime)s - %(levelname)s - %(message)s\")\n\narchivo = logging.FileHandler(filename=\"mi_log.log\",mode=\"a\")\nconsola = logging.StreamHandler()\n\narchivo.setFormatter(formato)\nconsola.setFormatter(formato)\n\nlog.addHandler(archivo)\nlog.addHandler(consola)\n\n# Pruebas\nlog.debug(\"Esto es un mensaje de depuración\")\nlog.info(\"Esto es un mensaje informativo\")\nlog.warning(\"Esto es una advertencia\")\nlog.error(\"Esto es un mensaje de error\")\nlog.critical(\"Esto es un mensaje critico\")\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa ficticio de gestión de tareas que permita añadir, eliminar\n * y listar dichas tareas.\n * x Añadir: recibe nombre y descripción.\n * x Eliminar: por nombre de la tarea.\n * Implementa diferentes mensajes de log que muestren información según la \n * tarea ejecutada (a tu elección).\n * Utiliza el log para visualizar el tiempo de ejecución de cada tarea.\n\"\"\"\n\nclass Tarea:\n    _lista_tareas = {}\n    def agregar(self,nombre,descripcion):\n        self._lista_tareas[nombre] = descripcion\n        log.info(f\"{nombre} añadido\")\n\n    def borrar(self,nombre):\n        if nombre in self._lista_tareas:\n            del self._lista_tareas[nombre]\n            log.info(f\"{nombre} eliminado\")\n\n    def mostrar(self):\n        print()\n        log.info(\"Mostrando Lista Actual:\")\n        for nombre, descripcion in self._lista_tareas.items():\n            log.info(f\"{nombre}\\n{descripcion}\")    \n        log.info(f\"Lista mostrada\")\n\n# Pruebas\nhoy = Tarea()\nhoy.agregar(\"Programar\",\"Hacer este ejercicio\")\nhoy.agregar(\"Comer\",\"Pizza Barbacoa\")\nhoy.agregar(\"Dormir\",\"Recuperar fuerzas\")\n\nhoy.mostrar()\nhoy.borrar(\"Comer\")\nhoy.mostrar()"
  },
  {
    "path": "Roadmap/25 - LOGS/python/Gordo-Master.py",
    "content": "### Logs ###\n\nimport logging\nimport time\n\n\"\"\"\nEjercicio\n\"\"\"\n\nlogging.basicConfig(\n    level=logging.DEBUG,\n    format=\"%(asctime)s - %(levelname)s - %(message)s \",\n    handlers=[logging.StreamHandler()]\n)\n\n# logging.debug(\"Esto es un mensaje de DEBUG\")\n# logging.info(\"Esto es un mensaje de INFO\")\n# logging.warning(\"Esto es un mensaje de WARNING\")\n# logging.error(\"Esto es un mensaje de ERROR\")\n# logging.critical(\"Esto es un mensaje de ERROR\")\n\n\"\"\"\nExtra\n\"\"\"\n\n\nclass TaskManager:\n\n    def __init__(self) -> None:\n        self.tasks = {}\n\n    def duration(func):\n        def time_laps(*args, **kwargs):\n            start_time = time.time()\n            result = func(*args, **kwargs)\n            end_time = time.time()\n            logging.debug(f\"Tiempo de ejecución: {end_time - start_time:.6f} segundos.\")\n            return result\n        return time_laps\n\n    @duration\n    def add_task(self, name: str, description: str):\n        if name not in self.tasks:\n            self.tasks[name] = description\n            logging.info(f\"Tarea añadida: {name}.\")\n        else:\n            logging.warning(f\"Se a intentado añadir una tarea que ya existe: {name}.\")\n        logging.debug(f\"Numero de tareas: {len(self.tasks)}\")\n\n    @duration\n    def delete_task(self, name: str):\n        if name in self.tasks:\n            del self.tasks[name]\n            logging.info(f\"Se ha eliminado la tarea: {name}.\")\n        else:\n            logging.error(f\"Se ha intentado eliminar una tarea que no existe: {name}.\")\n        logging.debug(f\"Numero de tareas: {len(self.tasks)}\")\n\n\n    @duration    \n    def list_tasks(self):\n        if self.tasks:\n            logging.info(f\"Se va a imprimir la lista de tareas.\")\n            for name, description in self.tasks.items():\n                print (f\"{name} - {description}\")\n        else:\n            logging.info(f\"No hay tareas para mostrar.\")\n\ntask_manager = TaskManager()\ntask_manager.list_tasks()\ntask_manager.add_task(\"Pan\", \"Comprar 5 barras de pan\")\ntask_manager.add_task(\"Python\", \"Estudiar Python\")\ntask_manager.list_tasks()\ntask_manager.delete_task(\"Python\")\ntask_manager.list_tasks()\ntask_manager.add_task(\"Pan\", \"Comprar 5 barras de pan\")\ntask_manager.delete_task(\"Python\")\n\n"
  },
  {
    "path": "Roadmap/25 - LOGS/python/Irenetitor.py",
    "content": "import logging\nimport time\nfrom functools import wraps\n\n#Exercise\n\nlogging.basicConfig(\n    level=logging.DEBUG,\n    format=\"%(asctime)s - %(levelname)s - %(message)s\",\n    handlers=[logging.StreamHandler()]\n)\n\nlogging.debug(\"This is a DEBUG message\")\nlogging.info(\"This is an INFO message\")\nlogging.warning(\"This is a WARNING message\")\nlogging.error(\"This is an ERROR message\")\nlogging.critical(\"This is a CRITICAL message\")\n\n\n#Extra Exercise\n\n\nlogger = logging.getLogger(__name__)\n\n#Decorator\ndef log_execution_time(func):\n    @wraps(func)\n    def inner(*args, **kwargs):\n        start_time = time.perf_counter()\n        result = func(*args, **kwargs)\n        duration = time.perf_counter() - start_time\n        logger.debug(\n            f\"Method '{func.__name__}' completed in {duration:.6f} seconds\"\n        )\n        return result\n    return inner\n\n\nclass TaskRegistry:\n    def __init__(self):\n        self._storage: dict[str, str] = {}\n\n    @log_execution_time\n    def create(self, title: str, details: str) -> None:\n        if title in self._storage:\n            logger.warning(f\"Task '{title}' already exists.\")\n            return\n\n        self._storage[title] = details\n        logger.info(f\"Task '{title}' successfully created.\")\n        logger.debug(f\"Current task count: {len(self._storage)}\")\n\n    @log_execution_time\n    def remove(self, title: str) -> None:\n        if title not in self._storage:\n            logger.error(f\"Task '{title}' was not found.\")\n            return\n\n        del self._storage[title]\n        logger.info(f\"Task '{title}' removed.\")\n        logger.debug(f\"Current task count: {len(self._storage)}\")\n\n    @log_execution_time\n    def show_all(self) -> None:\n        if not self._storage:\n            logger.info(\"Task list is empty.\")\n            return\n\n        logger.info(\"Displaying registered tasks:\")\n        for title, details in self._storage.items():\n            print(f\"* {title} -> {details}\")\n\n\nif __name__ == \"__main__\":\n    registry = TaskRegistry()\n\n    registry.show_all()\n    registry.create(\"Groceries\", \"Buy fruits and vegetables\")\n    registry.create(\"Workout\", \"30 minutes of cardio\")\n    registry.show_all()\n    registry.remove(\"Workout\")\n    registry.show_all()\n    registry.create(\"Groceries\", \"Duplicate test\")\n    registry.remove(\"Reading\")\n"
  },
  {
    "path": "Roadmap/25 - LOGS/python/JesusWay69.py",
    "content": "import os, platform,logging\n\nif (platform.platform().startswith(\"macOS\") or platform.platform().startswith(\"Linux\")):\n    os.system('clear')\nelse:\n    os.system('cls')\n\n\n\"\"\" * EJERCICIO:\n * Explora el concepto de \"logging\" en tu lenguaje. Configúralo y muestra\n * un ejemplo con cada nivel de \"severidad\" disponible.\n *\n\"\"\"\n\n\n#Valores representativos en número de cada nivel de severidad\n#NONSET = 0\n#DEBUG = 10\n#INFO = 20\n#WARNING = 30\n#ERROR = 40\n#CRITICAL = 50\n\nLEVELS = {\n\t'notset': logging.NOTSET,\n    'debug': logging.DEBUG,\n    'info': logging.INFO,\n    'warning': logging.WARNING,\n    'error': logging.ERROR,\n    'critical': logging.CRITICAL,\n}\n\nlevel = LEVELS.get('debug')#Podemos establecer el nivel mínimo de severidad desde una variable\n    \n\nlogging.basicConfig(\n\t#filename=\"#25.log\", #Podemos creal un fichero con extensión .log para almacenar los mensajes de logging\n\t#filemode= \"a\", # Con el modo \"a\" añadimos siempre al final del fichero los nuevos mensajes, con \"w\" solo se guradan los últimos mensajes\n\tencoding=\"utf-8\",\n\tlevel=level,#Tambien podemos asignar a la clave level del diccionario de configuración básico el propio nivel\n\t# así: level=logging.DEBUG o con su valor numérico así: level=10\n\tformat=\"%(asctime)s,%(msecs)1d - %(levelname)s %(message)s\",#En format determinamos el formato del mensaje de logging\n\tdatefmt='%d-%B-%Y,%H:%M:%S'#En datefmt le damos formato concreto a la fecha y hora igual que haríamos con datetime.datetime.strftime()\n)\n\n\ndef division(a:int, b:int)->int:\n\ttry:\n\t\tresult = round((a / b),2)\n\t\tlogging.info(f\"División de {a} entre {b}. Resultado: {result} , operación correcta\")\n\t\t#Mensaje de logging formateado para mostrar si el resultado de la función es correcto\n\texcept ZeroDivisionError as zero:\n\t\tresult = None\n\t\tlogging.error(zero)\n\texcept TypeError as type:\n\t\tresult = None\n\t\tlogging.error(type)\n\n\treturn result\n\ndef to_upper(text:str)->str: #Podemos prevenir los posibles errores dentro de las funciones con generación de mensajes de logging\n\ttry:\n\t\ttext = text*2\n\t\ttext = text.upper()\n\t\t\n\t\tlogging.info(text)\n\texcept ValueError as val:\n\t\ttext = None\n\t\tlogging.warning(val) #Dentro de una excepción específica..\n\texcept Exception as ex:\n\t\ttext = None\n\t\tlogging.warning(ex) # o dentro de una excepción genérica\n\t\n\treturn text\n\ndef show_element(my_list:list,index:int)->int:\n\ttry:\n\t\tnum = my_list[index]\n\t\tlogging.info(f\"El índice {index} de la lista {my_list} es {num}\")\n\t\t#Mensaje de logging formateado para mostrar si el resultado de la función es correcto\n\texcept IndexError as indexerr:\n\t\tnum = None\n\t\tlogging.critical(indexerr)\n\t\n    \n\ntry:\n\tdivision(8, 3)#Función con valores válidos para una división\n\tdivision(2, 0)#Aquí provocamos un error de division entre cero\n\tdivision(9, \"3\")#Aquí provocamos un error de tipo de dato\n\tprint()\n\tshow_element([1,2,3],2)#Función con valores correctos para mostrar un elemento de una lista\n\tshow_element([1,2,3],3)#Aquí provocamos un error de fuera de índice\n\tprint()\n\tto_upper(45)#Provocamos un error porque aunque un int admite multiplicación no admite el método .upper()\n\tto_upper(\"Hola Python \")#Aquí le pasamos un string que admite multiplicación y método .upper()\n\tto_upper(\"Hola\", \"Python\")#Aquí provocamos que no se pueda ejecutar la función y el programa salta al except,\n\t# si pusiéramos esta llamada al principio de esta lista no se ejecutaría ninguna llamada\n\t\nexcept Exception as ex:\n\tlogging.warning(ex)\n\tprint(\"excepción general antes de la función\")\n\t#Tambien podemos prevenir los errores que no permiten ejecutar la función como en el caso de\n\t# to_upper() al que le estamos pasando 2 argumentos cuando requiere solo uno\n\n\n\t#Tambien podemos generar mensajes de logging no relacionados con la propia ejecución como este que\n\t# nos da información del sistema operativo , su versión y la versión en este caso de python que estamos usando\nlogging.info(f\"Runnig at: {platform.platform()} with Python {platform.python_version()}\")\n\n\n\"\"\" * DIFICULTAD EXTRA (opcional):\n * Crea un programa ficticio de gestión de tareas que permita añadir, eliminar\n * y listar dichas tareas.\n * - Añadir: recibe nombre y descripción.\n * - Eliminar: por nombre de la tarea.\n * Implementa diferentes mensajes de log que muestren información según la\n * tarea ejecutada (a tu elección).\n * Utiliza el log para visualizar el tiempo de ejecución de cada tarea.\"\"\"\n\n\ntasks = {}\n\ndef add_task(task:str,description:str):\n\ttasks[task]= description\n\tlogging.info(f\"La tarea {task} se ha añadido correctamente\\n\")\n\ndef show_tasks():\n\t[print(\"Tarea: \", t ,\"- Descripción: \", d , end = '\\n') for t,d in tasks.items()]\nprint()\n\t\ndef delete_task(task:str):\n\tif task in tasks:\n\t\ttasks.pop(task)\n\t\tlogging.info(f\"La tarea {task} ha sido eliminada correctamente\\n\")\n\telse:\n\t\tlogging.warning(f\"Tarea {task} no encontrada\\n\")\n\n\nwhile True:\n\toption = input(\"-1 Mostrar tareas \\n-2 Añadir tarea \\n-3 Borrar tarea \\n-4 Salir\\nSeleccione una opción: \")\n\tif not option.isdigit():\n\t\tlogging.error(\": Sólo se pueden introducir caracteres numéricos, intente de nuevo\\n\")\n\telif int(option)<1 or int(option)>4:\n\t\tlogging.warning(\": El número no debe ser diferente a las opciones mostradas, intente de nuevo\\n\")\n\telse:\t\n\t\toption = int(option)\n\n\t\tif option == 1:\n\t\t\tlogging.debug(\"listado de tareas:\")\n\t\t\tshow_tasks()\n\t\t\tcontinue\n\t\telif option == 2:\n\t\t\ttask_name = input(\"Escriba el nombre de la tarea: \")\n\t\t\ttask_desc = input(\"Describa la tarea: \")\n\t\t\tadd_task(task_name,task_desc)\n\t\t\tcontinue\n\t\telif option == 3:\n\t\t\ttask_name = input(\"Escriba el nombre de la tarea a borrar: \")\n\t\t\tdelete_task(task_name)\n\t\t\tcontinue\n\t\telif option == 4:\n\t\t\tlogging.warning(\": Está saliendo del programa\")\n\t\t\tbreak\n\t\t\n\t\t"
  },
  {
    "path": "Roadmap/25 - LOGS/python/JheisonQuiroga.py",
    "content": "# Author: Jheison Duban Quiroga Quintero\n# Github: https://github.com/JheisonQuiroga\n\"\"\"\n/*\n * EJERCICIO:\n * Explora el concepto de \"logging\" en tu lenguaje. Configúralo y muestra\n * un ejemplo con cada nivel de \"severidad\" disponible.\n\"\"\"\n\n\"\"\" Logging\n\nEs un modulo poderoso para el seguimiento de eventos. Tiene diferentes niveles de\nseveridad para los eventos.\n\"\"\"\nimport logging\n\n# Configuración básica, se establece el nivel, el formato, y se indica que los logs\n# se envíen a la consola\nlogging.basicConfig(\n    level=logging.DEBUG, \n    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')\n    # filename = \"app.log\" Opcionalmente se puede guardar en un archivo\n\n# Niveles de severida\nlogging.debug(\"Este es un mensaje de debug\")\nlogging.info(\"Este es un mensaje de información\")\nlogging.warning(\"Este es un mensaje de advertencia\")\nlogging.error(\"Este es un mensaje de error\")\nlogging.critical(\"Este es un mensaje crítico\")\n\n# Logger personalizado\n\nlogger = logging.getLogger(\"my_logger\")\nlogger.setLevel(logging.DEBUG)\n\n# Creamos un handler para la consola\nconsole_handler = logging.StreamHandler()\nconsole_handler.setLevel(logging.INFO)\n\n# Formato personalizado\nformatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')\nconsole_handler.setFormatter(formatter)\n\n# Anadir handler al logger\nlogger.addHandler(console_handler)\n\n# Registrar mensajes\nlogger.debug(\"Este es un mensaje de debug\")\nlogger.info(\"Informacion importante\")\n\n\"\"\"\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa ficticio de gestión de tareas que permita añadir, eliminar\n * y listar dichas tareas.\n * - Añadir: recibe nombre y descripción.\n * - Eliminar: por nombre de la tarea.\n * Implementa diferentes mensajes de log que muestren información según la\n * tarea ejecutada (a tu elección).\n * Utiliza el log para visualizar el tiempo de ejecución de cada tarea.\n */\n\"\"\"\nimport logging\nimport time\nfrom typing import Dict\n\n# Configuración básica del logging\nlogging.basicConfig(\n    level=logging.DEBUG,\n    format=\"%(asctime)s - %(name)s - %(levelname)s - %(message)s\",\n    datefmt=\"%Y-%m-%d %H:%M:%S\",\n    handlers=[logging.StreamHandler()]\n)\n\nclass TaskManager:\n    def __init__(self):\n        self.tasks: Dict[str, str] = {}\n        self._logger = logging.getLogger(\"TaskManagerLogger\")\n        self._logger.info(\"Se ha creado una instancia de la clase\")\n\n    @staticmethod\n    def _log_execution_time(func):\n        def wrapper(*args):\n            start_time: float = time.time()\n            logging.info(f\"Iniciando {func.__name__}...\")\n            result = func(*args)\n            duration = time.time() - start_time\n            logging.info(f\"{func.__name__} ejecutada en {duration:.8f}\")\n            return result\n        return wrapper\n        \n\n    @_log_execution_time\n    def add_task(self, task_name:str, task_description:str) -> bool:\n        if task_name not in self.tasks: \n            self.tasks.update({task_name: task_description})\n            self._logger.info(f\"Tarea {task_name} agregada satisfactoriamente\")\n            return True\n        else:\n            self._logger.warning(f'La tarea {task_name} ya existe!')\n            return False\n\n    @_log_execution_time\n    def remove_task(self, task_name) -> bool:\n        if task_name in self.tasks:\n            self.tasks.pop(task_name)\n            self._logger.info(f\"Tarea {task_name} eliminada con éxito\")\n            return True\n        else:\n            self._logger.warning(f\"Tarea {task_name} no encontrada\")\n            return False\n\n    @property\n    @_log_execution_time\n    def list_tasks(self) -> None:\n        if not self.tasks:\n            self._logger.info(\"No hay tareas registradas\")\n            return\n        for key, value in self.tasks.items():\n            print(f\"{key}: {value}\")\n        self._logger.info(f\"Tareas listada con éxito\")\n\n\nif __name__ == \"__main__\":\n\n    print(f\"Ejecutando el programa {TaskManager.__name__}\")\n    t1 = TaskManager()\n    # Agregando tareas\n    t1.add_task(\"Tarea 1\", \"Esta es la tarea 1\")\n    t1.add_task(\"Tarea 2\", \"Esta es la tarea 2\")\n    t1.add_task(\"Tarea 3\", \"Esta es la tarea 3\")\n\n    # Listando tareas\n    t1.list_tasks\n\n    t1.add_task(\"Tarea 1\", \"Esta es una nueva tarea 1\")\n    t1.list_tasks\n    # Eliminando tareas\n    t1.remove_task(\"Tarea 1\")\n    t1.remove_task(\"Tarea 1\")"
  },
  {
    "path": "Roadmap/25 - LOGS/python/LucasRebuffo.py",
    "content": "import logging\nimport time\n\n\"\"\" Ejercicio \"\"\"\n\nlogging.basicConfig(\n    level=logging.DEBUG,\n    format=\"%(asctime)s - %(levelname)s - %(message)s\",\n    handlers=[logging.StreamHandler()],\n)\n\"\"\" \nlogging.debug(\"Esto es un mensaje de DEBUG\")\nlogging.info(\"Esto es un mensaje de INFORMACION\")\nlogging.warning(\"Esto es un mensaje de AVISO\")\nlogging.error(\"Esto es un mensaje de ERROR\")\nlogging.critical(\"Esto es un mensaje CRITICO\")\n \"\"\"\n\n\"\"\" EXTRA \"\"\"\n\n\ndef time_exec_decorator(function):\n\n    def time_exec(*args):\n        start_time = time.time()\n        c = function(*args)\n        end_time = time.time()\n        print(f\"Execution time: {end_time-start_time:.6f}\")\n        return c\n\n    return time_exec\n\n\nclass Gestor_de_Tareas:\n\n    def __init__(self) -> None:\n        self.tareas = {}\n\n    @time_exec_decorator\n    def agregar_tarea(self, name, description):\n\n        if name not in self.tareas:\n            self.tareas[name] = description\n            logging.info(f\"Tarea agregada: {name}\")\n        else:\n            logging.warning(f\"La tarea que se quiere agregar ya existe\")\n        logging.debug(f\"Numero de tareas: {len(self.tareas)}\")\n\n    @time_exec_decorator\n    def borrar_tarea(self, name):\n        if name in self.tareas:\n            del self.tareas[name]\n            logging.info(f\"Tarea borrada: {name}\")\n        else:\n            logging.error(f\"La tarea que se quiere borrar no existe\")\n\n    @time_exec_decorator\n    def listar_tareas(self):\n        if self.tareas:\n            logging.info(f\"Se imprimen la tareas\")\n            for name, description in self.tareas.items():\n                print(f\"{name} - {description}\")\n        else:\n            logging.info(f\"No hay tareas que mostrar\")\n\n\ngestor_de_tareas = Gestor_de_Tareas()\ngestor_de_tareas.agregar_tarea(\"Estudiar Python\", \"Aprender conceptos bases\")\ngestor_de_tareas.agregar_tarea(\n    \"Estudiar curso fullstack\", \"Profundizar en la parte de backend\"\n)\ngestor_de_tareas.listar_tareas()\n\ngestor_de_tareas.borrar_tarea(\"Estudiar Python\")\n\ngestor_de_tareas.listar_tareas()\n"
  },
  {
    "path": "Roadmap/25 - LOGS/python/LuisOlivaresJ.py",
    "content": "\"\"\"\n * Explora el concepto de \"logging\" en tu lenguaje. Configúralo y muestra\n * un ejemplo con cada nivel de \"severidad\" disponible.\n\"\"\"\n\nimport logging\n\n# Logging configuration\nlogging.basicConfig(level=logging.DEBUG,\n                    filename='example.log',\n                    filemode='a',\n                    format='%(asctime)s - %(levelname)s - %(message)s'\n                    )\n\n# Examples of each level of severity\nlogging.debug('This is a DEBUG message')\nlogging.info('This is a INFO message')\nlogging.warning('This is a WARNING message')\nlogging.error('This is a ERROR message')\nlogging.critical('This is a CRITICAL message')\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa ficticio de gestión de tareas que permita añadir, eliminar\n * y listar dichas tareas.\n * - Añadir: recibe nombre y descripción.\n * - Eliminar: por nombre de la tarea.\n * Implementa diferentes mensajes de log que muestren información según la \n * tarea ejecutada (a tu elección).\n * Utiliza el log para visualizar el tiempo de ejecución de cada tarea. \n\"\"\"\n\nclass Task:\n    def __init__(self, name, description, finalized=False, final_date=None):\n        self.name = name\n        self.description = description\n        self.finalized = finalized\n        self.final_date = final_date\n        \n\nclass Task_manager():\n\n    def __init__(self):\n        self.tasks = []  # List to store tasks as dictionaries\n\n\n    def add_task(self, task: Task):\n        self.tasks.append(\n            {\n                'name': task.name,\n                'description': task.description,\n                'finalized': task.finalized,\n                'final_date': task.final_date\n             }\n             )\n        logging.info(f'Task added.')\n\n\n    def delete_task(self, name: str):\n        for task in self.tasks:\n            if task['name'] == name:\n                self.tasks.remove(task)\n                logging.info(f'Task deleted.')\n                return\n        logging.warning(f'Task was not fouded.')\n\n\n    def list_tasks(self):\n        for task in self.tasks:\n            print(task)\n\n    def change_to_finalized(self, name: str):\n        for task in self.tasks:\n            if task['name'] == name:\n                task['finalized'] = True\n                logging.info(f'Task finalized.')\n                return\n        logging.warning(f'Task was not fouded.')\n\ntask1 = Task('Task1', 'Description of task 1')\ntask2 = Task('Task2', 'Description of task 2', final_date='2024-06-23')\n\ntask_manager = Task_manager()\ntask_manager.add_task(task1)\ntask_manager.add_task(task2)\ntask_manager.list_tasks()\ntask_manager.delete_task('Task1') # Task deleted\ntask_manager.list_tasks()\ntask_manager.delete_task('Task3') # Task not found\ntask_manager.change_to_finalized('Task2')\n\ntask_manager.list_tasks()"
  },
  {
    "path": "Roadmap/25 - LOGS/python/Nicojsuarez2.py",
    "content": "# #25 LOGS\n> #### Dificultad: Fácil | Publicación: 17/06/24 | Corrección: 24/06/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Explora el concepto de \"logging\" en tu lenguaje. Configúralo y muestra\n * un ejemplo con cada nivel de \"severidad\" disponible.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa ficticio de gestión de tareas que permita añadir, eliminar\n * y listar dichas tareas.\n * - Añadir: recibe nombre y descripción.\n * - Eliminar: por nombre de la tarea.\n * Implementa diferentes mensajes de log que muestren información según la \n * tarea ejecutada (a tu elección).\n * Utiliza el log para visualizar el tiempo de ejecución de cada tarea. \n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/25 - LOGS/python/Sac-Corts.py",
    "content": "import logging\nimport time\n\n# Configurar el logging\nlogging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')\n\n# Ejemplos de mensajes de logging en diferentes niveles de severidad\nlogging.debug('Este es un mensaje de depuración.')\nlogging.info('Este es un mensaje informativo.')\nlogging.warning('Este es un mensaje de advertencia.')\nlogging.error('Este es un mensaje de error.')\nlogging.critical('Este es un mensaje crítico.')\n\n### Ejercicio Extra ###\n\nclass TaskManager:\n    \n    def __init__(self):\n        self.tasks = []\n\n    def add_task(self, name, description):\n        start_time = time.time()\n        self.tasks.append({'name': name, 'description': description})\n        logging.info(f'Task added: {name}')\n        logging.debug(f'Time taken to add task: {time.time() - start_time} seconds')\n\n    def remove_task(self, name):\n        start_time = time.time()\n        for task in self.tasks:\n            if task['name'] == name:\n                self.tasks.remove(task)\n                logging.info(f'Task remove: {name}')\n                logging.debug(f'Time taken to remove task: {time.time() - start_time} seconds')\n                return\n            \n        logging.warninig(f'Task not found: {name}')\n        logging.debug(f'Time taken to attempt to remove task: {time.time() - start_time} seconds')\n\n    def list_tasks(self):\n        start_time = time.time()\n        for task in self.tasks:\n            print(f\"Task: {task['name']}, Description: {task['description']}\")\n        logging.info(f'Listed {len(self.tasks)} tasks')\n        logging.debug(f'Time taken to list tasks: {time.time() - start_time} seconds')\n\n\nmanager = TaskManager()\nmanager.add_task('Task 1', 'Study Python')\nmanager.add_task('Task 2', 'Study JavaScript')\nmanager.add_task('Task 3', 'Study Java')\nmanager.list_tasks()\nmanager.remove_task('Task 1')\nmanager.list_tasks()\n\n\n"
  },
  {
    "path": "Roadmap/25 - LOGS/python/SooHav.py",
    "content": "# 25 LOGS\n\n# Ejercicio\n\nimport logging\nimport requests\nimport time\n\n\n# Niveles de log\n# -----------------------------------------------------------------------------\n# DEBUG = 10\n# INFO = 20\n# WARNING = 30\n# ERROR = 40\n# CRITICAL = 50\n\n# Definición del logger root\n# -----------------------------------------------------------------------time.sleep------\nlogging.basicConfig(\n    level=logging.DEBUG,\n    format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s'\n)\n\n# ========================== SCRIPT ============================================\n\n\ndef info_pokemon(id=None, name=None):\n    logging.debug(\n        \"Comienza el proceso de recopilación de información con la función info_pokemon con un ID o nombre\")\n    if id is not None:\n        url = f'https://pokeapi.co/api/v2/pokemon/{id}'\n    elif name is not None:\n        url = f'https://pokeapi.co/api/v2/pokemon/{name.lower()}'\n    else:\n        logging.warning(\"Debes proporcionar un ID o un nombre.\")\n        return\n\n    response = requests.get(url)\n\n    if response.status_code == 200:\n        logging.info(\"La respuesta fue exitosa\")\n        pokemon = response.json()\n        try:\n            print(f\"Nombre: {pokemon['name']}\")\n            print(f\"ID: {pokemon['id']}\")\n            print(f\"Peso: {pokemon['weight']} hectogramos\")\n            print(f\"Altura: {pokemon['height']} decímetros\")\n            print(\"Tipos:\")\n            for tipo in pokemon['types']:\n                print(f\"  - {tipo['type']['name']}\")\n            logging.debug(\"Información básica del Pokémon mostrada con éxito.\")\n        except KeyError as e:\n            logging.error(f'Error al extraer información del Pokémon: {e}')\n\n    elif response.status_code == 404:\n        logging.critical(\n            \"El Pokémon no fue encontrado. Revisa el ID o el nombre proporcionado.\")\n    else:\n        logging.error(f'Error: {response.status_code}')\n\n\n# Ejemplo de uso\ninfo_pokemon(25)\ninfo_pokemon(name=\"pikachu\")\ninfo_pokemon(name=\"pokefalso\")\nlogging.debug(\"Fin del script\")\n\n# Extra\n\n# Definición del logger root\n# -----------------------------------------------------------------------------\n\n# Create a logger object\nlogger = logging.getLogger(__name__)\n\n# Setear el nivel DEBUG\nlogger.setLevel(logging.DEBUG)\n\n# Formatter\nf_format = logging.Formatter(\n    '%(asctime)s - %(name)s - %(levelname)s - %(message)s')\n\n# Asignar formatter a 'formatter'\nlogger.formatter = f_format\n\n# Handlers\nc_handler = logging.StreamHandler()\nc_handler.setLevel(logging.DEBUG)\nlogger.addHandler(c_handler)\n\n# ========================== SCRIPT ============================================\n\n\ndef medir_tiempo(func):\n    \"\"\"\n    Función para medir el tiempo de ejecución de las funciones.\n    \"\"\"\n    def wrapper(*args, **kwargs):\n        inicio = time.time()\n        funcion = func(*args, **kwargs)\n        fin = time.time()\n        logging.debug(f\"Tiempo de ejecución de '{func.__name__}': {\n                      fin - inicio:.6f} segundos\")\n        return funcion\n    return wrapper\n\n\nclass Tarea:\n    \"\"\"\n    Clase que representa una tarea con nombre y descripción.\n    \"\"\"\n\n    def __init__(self, nombre, descripcion):\n        self.nombre = nombre\n        self.descripcion = descripcion\n\n\nclass GestorTareas:\n    \"\"\"\n    Clase que gestiona una lista de tareas.\n    \"\"\"\n\n    def __init__(self):\n        self.tareas = []\n\n    @medir_tiempo\n    def agregar_tarea(self, nombre, descripcion):\n        \"\"\"\n        Agrega una nueva tarea a la lista.\n        \"\"\"\n        nueva_tarea = Tarea(nombre, descripcion)\n        self.tareas.append(nueva_tarea)\n        time.sleep(5)\n        logging.info(f\"Tarea '{nombre}' agregada con éxito.\")\n\n    @medir_tiempo\n    def eliminar_tarea(self, nombre):\n        \"\"\"\n        Elimina una tarea de la lista por su nombre.\n        \"\"\"\n        tarea_eliminada = None\n        for tarea in self.tareas:\n            if tarea.nombre == nombre:\n                tarea_eliminada = tarea\n                break\n        if tarea_eliminada:\n            self.tareas.remove(tarea_eliminada)\n            time.sleep(3)\n            logging.info(f\"Tarea '{nombre}' eliminada con éxito.\")\n        else:\n            logging.warning(f\"Tarea '{nombre}' no encontrada.\")\n\n    @medir_tiempo\n    def listar_tareas(self):\n        \"\"\"\n        Muestra una lista de todas las tareas.\n        \"\"\"\n        if self.tareas:\n            logging.debug(\"Lista de tareas:\")\n            for tarea in self.tareas:\n                logging.info(f\"- {tarea.nombre}: {tarea.descripcion}\")\n        else:\n            logging.warning(\"No hay tareas pendientes.\")\n\n\n# Ejemplo de uso\ngestor = GestorTareas()\n\n# Agregar tareas\ngestor.agregar_tarea(\"Comprar\", \"Hacer la compra semanal en el super.\")\ngestor.agregar_tarea(\n    \"Limpiar\", \"Limpiar todos los ambientes de la casa y ordenar el placard.\")\ngestor.agregar_tarea(\"Ejercitar\", \"Hacer los ejercicios de Roadmap.\")\n\n# Listar tareas\ngestor.listar_tareas()\n\n# Eliminar tarea\ngestor.eliminar_tarea(\"Limpiar\")\n\n# Listar tareas nuevamente\ngestor.listar_tareas()\n"
  },
  {
    "path": "Roadmap/25 - LOGS/python/Trufoplus.py",
    "content": "###############################################################################\n###     EJERCICIO\n###############################################################################\nimport logging\nfrom datetime import datetime\n\n# Configuracion basica de un logginf\nlogging.basicConfig(\n    #filename='my_log.log',          # Nombre del archivo de log, si no lo especificas se mostrara por consola \n    filemode='w',                   # Modo fe apertura del archivo\n    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',  #Formato del mesaje\n    datefmt='%d/%m/%Y %H:%M:%S',    # Formato de la fecha\n    level=logging.DEBUG             # Nivel de severidad minimo\n    )\n\n\n# Uso del logging\n\nlogging.debug('Esto es un mensaje de depuración')\nlogging.info('Esto es un mensaje informativo')\nlogging.warning('Esto es una advertencia')\nlogging.error('Esto es un mensaje de error')\nlogging.critical('Esto es un mensaje crítico')\n# Para separar los ejerccios en la consola\nprint()\nprint()\nprint()\n###############################################################################\n###     DIFICULTAD EXTRA\n###############################################################################\nclass TaskManagement():\n    \"\"\"\n    Programa de gestion de tareas\n    \"\"\"\n    def __init__(self):\n        self.tasks = {}\n        logging.info(\"Inicialización del programa de gestión de tareas\")\n\n    def add_task(self, name: str, description: str):\n        start_time = datetime.now()\n        if name in self.tasks:\n            logging.warning(f\"La tarea '{name}' ya existe. No se puede agregar de nuevo.\")\n            return\n        self.tasks[name] = description\n        logging.info(f\"Tarea '{name}' añadida con éxito.\")\n        logging.debug(f\"Descripción: {description}\")\n        end_time = datetime.now()\n        logging.info(f\"Tiempo de ejecución para añadir tarea: {end_time - start_time}\")\n\n    def delete_task(self, name: str):\n        start_time = datetime.now()\n        if name not in self.tasks:\n            logging.error(f\"La tarea '{name}' no existe. No se puede eliminar.\")\n            return\n        del self.tasks[name]\n        logging.info(f\"Tarea '{name}' eliminada con éxito.\")\n        end_time = datetime.now()\n        logging.info(f\"Tiempo de ejecución para eliminar tarea: {end_time - start_time}\")\n    \n    def __str__(self):\n        print(\"\\nLISTA DE TAREAS: \")\n        return \"\\n\".join([f\"{name}: {desc}\" for name, desc in self.tasks.items()])\n    \n\n# Probando el codigo\nmis_tareas = TaskManagement()\nmis_tareas.add_task('Tarea_1', 'Limpiar el polvo')\nmis_tareas.add_task('Tarea_2', 'Limpiar los baños')\nmis_tareas.add_task('Tarea_2', 'Limpiar los baños')\nprint(mis_tareas)\nmis_tareas.delete_task('Tarea_1')\nmis_tareas.add_task('Tarea_3', 'Limpiar la cocina')\nprint(mis_tareas)\nmis_tareas.delete_task('Tarea_4')"
  },
  {
    "path": "Roadmap/25 - LOGS/python/adra-dev.py",
    "content": "\"\"\"\nEJERCICIO:\nExplora el concepto de \"logging\" en tu lenguaje. Configúralo y muestra\nun ejemplo con cada nivel de \"severidad\" disponible.\n\nDIFICULTAD EXTRA(opcional):\nCrea un programa ficticio de gestión de tareas que permita añadir, \neliminar y listar dichas tareas.\n- Añadir: recibe nombre y descripción.\n- Eliminar: por nombre de la tarea.\nImplementa diferentes mensajes de log que muestren información según\nla tarea ejecutada (a tu elección).\nUtiliza el log apra visualizar el tiempo de ejecución de cada tarea.\n\nby adra-dev\n\"\"\"\n\n\"\"\"\nLoggin:\nRegistrar información relevante durante la ejecución de un programa \nes una buena práctica como desarrollador cuando buscas obtener un \nmejor entendimiento de tu código. Esta práctica es llamada  logging, \ny es una herramienta muy útil para ti como desarrollador, esta te \npuede ayudar a descubrir escenarios que tal vez no hayas tenido en \ncuenta.\n\nEstos registros son llamados logs, y pueden servir como un par extra \nde ojos que constantemente están mirando al flujo de tu aplicación. \nLos logs pueden guardar información, como qué  usuarios o IP \naccedieron a la aplicación. Si ocurre un error, entonces los logs \npueden proporcionar más información que un seguimiento de pila, ya \nque indican el estado del programa antes del error y la línea de \ncódigo en la que se produjo.\n\nPython provee a un sistema de logins como parte de su librería estándar. \ndocumentacion: \"https://realpython.com/python-logging/\" \n\nSeveridad:\nExisten  5 niveles de logs por default, en orden de severidad \ncreciente serían: DEBUG, INFO, WARNING, ERROR, CRITICAL.\n\n\"\"\"\n\nimport logging\nimport time \n\nlogging.basicConfig(level=logging.ERROR, format=\"%(asctime)s - %(levelname)s - %(message)s\",\n                    handlers= [logging.StreamHandler()])\n\nlogging.debug(\"This is a debug message\")\nlogging.info(\"This is an info message\")\nlogging.warning(\"This is a warning message\")\nlogging.error(\"This is an error message\")\nlogging.critical(\"This is a critical message\")\n\n\n\"\"\"\nExtra\n\"\"\"\n\nclass TaskManager:\n\n    def __init__(self) -> None:\n        self.tasks = {}\n\n    def addTask(self, name: str, description: str):\n        start_time = time.time()\n        if name not in self.tasks:\n            self.tasks[name] = description\n            logging.info(f\"Tarea agregada: {name}.\")\n        else:\n            logging.warning(f\"Se ha intentando agregar una tarea que ya existe: {name}.\")\n        logging.debug(f\"Numero de tareas {len(self.tasks)}\")\n        end_time = time.time()\n        self._print_time(start_time, end_time)\n\n    def deleteTask(self, name: str):\n        start_time = time.time()\n        if name in self.tasks:\n            del self.tasks[name]\n            logging.info(f\"Se ha eliminado la tarea: {name}.\")\n        else:\n            logging.error(\n                f\"Se a intentando eliminar una tarea que no existe: {name}.\")\n        logging.debug(f\"Numero de tareas {len(self.tasks)}\")\n        end_time = time.time()\n        self._print_time(start_time, end_time)\n\n    def list_tasks(self):\n        start_time = time.time()\n        if self.tasks:\n            logging.info(f\"Se va imprimir la lista de tareas\")\n            for name, description in self.tasks.items():\n                print(f\"{name} - {description}\")\n        else:\n            logging.info(\"No hay tareas para mostrar\")\n        end_time = time.time()\n        self._print_time(start_time, end_time)\n\n    def _print_time(self, start_time, end_time):\n        logging.debug(\n            f\"Tiempo de ejecucion: {end_time - start_time:.6f} segundos.\")\n\n\ntask_manager = TaskManager()\ntask_manager.list_tasks()\ntask_manager.addTask(\"Pan\", \"Comprar 5 barras de pan\")\ntask_manager.addTask(\"Python\", \"Estudiar Python\")\ntask_manager.list_tasks()\ntask_manager.deleteTask(\"Python\")\ntask_manager.list_tasks()\ntask_manager.addTask(\"Pan\", \"Comprar 5 barras de pan\")\ntask_manager.deleteTask(\"Python\")"
  },
  {
    "path": "Roadmap/25 - LOGS/python/agusrosero.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Explora el concepto de \"logging\" en tu lenguaje. Configúralo y muestra\n * un ejemplo con cada nivel de \"severidad\" disponible.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa ficticio de gestión de tareas que permita añadir, eliminar\n * y listar dichas tareas.\n * - Añadir: recibe nombre y descripción.\n * - Eliminar: por nombre de la tarea.\n * Implementa diferentes mensajes de log que muestren información según la \n * tarea ejecutada (a tu elección).\n * Utiliza el log para visualizar el tiempo de ejecución de cada tarea. \n */\n\"\"\"\n\n# EJERCICIO:\nimport time\nimport logging\n\nlogging.debug(\"Mensaje a nivel debug.\")\nlogging.info(\"Mensaje a nivel info.\")\nlogging.warning(\"Mensaje a nivel warning.\")\nlogging.error(\"Mensaje a nivel error.\")\nlogging.critical(\"Mensaje a nivel critical.\")\n\n# DIFICULTAD EXTRA:\nlogging.basicConfig(level=logging.INFO,\n                    format='%(asctime)s - %(levelname)s - %(message)s')\n\n\nclass TaskManager:\n    def __init__(self):\n        self.tasks = {}\n\n    def add_task(self, name, description):\n        start_time = time.time()\n        if name in self.tasks:\n            logging.warning(f'La tarea \"{name}\" ya existe.')\n        else:\n            self.tasks[name] = description\n            logging.info(f'Tarea \"{name}\" añadida.')\n        end_time = time.time()\n        logging.debug(f'Tiempo de ejecución para añadir tarea: {\n                      end_time - start_time} segundos')\n\n    def remove_task(self, name):\n        start_time = time.time()\n        if name in self.tasks:\n            del self.tasks[name]\n            logging.info(f'Tarea \"{name}\" eliminada.')\n        else:\n            logging.warning(f'La tarea \"{name}\" no existe.')\n        end_time = time.time()\n        logging.debug(f'Tiempo de ejecución para eliminar tarea: {\n                      end_time - start_time} segundos')\n\n    def list_tasks(self):\n        start_time = time.time()\n        if not self.tasks:\n            logging.info('No hay tareas disponibles.')\n        else:\n            for name, description in self.tasks.items():\n                logging.info(f'Tarea: {name} - Descripción: {description}')\n        end_time = time.time()\n        logging.debug(f'Tiempo de ejecución para listar tareas: {\n                      end_time - start_time} segundos')\n\n\nif __name__ == \"__main__\":\n    manager = TaskManager()\n\n    manager.add_task(\"Tarea 1\", \"Descripción de la Tarea 1\")\n    manager.add_task(\"Tarea 2\", \"Descripción de la Tarea 2\")\n\n    manager.list_tasks()\n\n    manager.remove_task(\"Tarea 1\")\n\n    manager.list_tasks()\n"
  },
  {
    "path": "Roadmap/25 - LOGS/python/alanshakir.py",
    "content": "\"\"\"\n*\n * EJERCICIO:\n * Explora el concepto de \"logging\" en tu lenguaje. Configúralo y muestra\n * un ejemplo con cada nivel de \"severidad\" disponible.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa ficticio de gestión de tareas que permita añadir, eliminar\n * y listar dichas tareas.\n * - Añadir: recibe nombre y descripción.\n * - Eliminar: por nombre de la tarea.\n * Implementa diferentes mensajes de log que muestren información según la \n * tarea ejecutada (a tu elección).\n * Utiliza el log para visualizar el tiempo de ejecución de cada tarea. \n */\n\"\"\"\nimport logging\nimport random\n\nlogging.basicConfig(format=\"%(process)d %(levelname)s %(message)s\", level=logging.DEBUG)\nlogging.debug(\"esto es una depuracion\")\nlogging.info(\"esto es una confirmacion\") \nlogging.warning(\"esto es una advertencia\")\nlogging.error(\"esto es un mensaje de error\")\nlogging.critical(\"esto es un mensaje critico\")\n\n#Extra\n\nclass GestionTareas:\n    def __init__(self):\n        self.tareas = {}\n        \n\n    \n    def agg_tarea(self):\n        name = input(\"Introduzca nombre: \")\n        description = input(\"Introduzca breve descripcion de la tarea: \")\n        if name in self.tareas:\n            logging.error(\"La tarea ya existe\")\n        execution_time = random.randint(1,5)\n        self.tareas[name]= {\n            \"description\":description, \n            \"execution_time\":execution_time}\n        logging.info(\"tarea agregada\")\n    \n    def list_tareas(self):\n        if not self.tareas:\n            logging.error(\"La tarea no existe\")\n        for name, description  in self.tareas.items():\n            logging.info(f\"nombre de la tarea: {name}\")\n            logging.info(f\"Descripcion: {description['description']}\")\n            logging.info(f\"Tiempo de ejecucion: {description['execution_time']} segundos\")\n    \n    def del_tareas(self):\n        name = input(\"Introduzca nombre: \")\n        if name not in self.tareas:\n            logging.error(\"La tarea no existe\")\n        else:\n            del self.tareas[name]\n            logging.info(f\"la tarea {name} fue eliminada\")\n\n\n        \ntask = GestionTareas()     \nwhile True:\n    print(\"--------->Gestor de Tareas<------------------\")\n    print(\"---->Elija una de las siguientes opciones<---\")\n    print(\"1. Agregar: \")\n    print(\"2. Listar: \")\n    print(\"3. Eliminar: \")\n    print(\"4. Salir: \")\n\n    option = int(input(\"Seleccione una opcion: \"))\n\n    if option == 1:\n        task.agg_tarea()\n    elif option == 2:\n        task.list_tareas()\n    elif option == 3:\n        task.del_tareas()\n    elif option == 4:\n        print(\"Has elegido salir del programa, Hasta luego\")\n        break\n    else:\n        print(\"elija una de las opciones indicadas\")\n"
  },
  {
    "path": "Roadmap/25 - LOGS/python/avcenal.py",
    "content": "import logging\n\n\"\"\"\n * EJERCICIO:\n * Explora el concepto de \"logging\" en tu lenguaje. Configúralo y muestra\n * un ejemplo con cada nivel de \"severidad\" disponible.\n\"\"\"\nlogging.basicConfig(level=logging.DEBUG,\n                    format=\"%(asctime)s -- %(levelname)s: %(message)s\",\n                    datefmt=\"%d/%m/%Y - %H:%M:%S\",\n                    handlers=[logging.StreamHandler()])\n\nlogging.debug(\"Info para hacer debugging\")\nlogging.info(\"Todo funciona correctamente\")\nlogging.warning(\"Ha pasado algo inesperado o está a punto de ocurrir algo\")\nlogging.error(\"Error, no se ha podido realizar la acción\")\nlogging.critical(\"Error grave, posiblemente el programa no pueda continuar\")\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa ficticio de gestión de tareas que permita añadir, eliminar\n * y listar dichas tareas.\n * - Añadir: recibe nombre y descripción.\n * - Eliminar: por nombre de la tarea.\n * Implementa diferentes mensajes de log que muestren información según la\n * tarea ejecutada (a tu elección).\n * Utiliza el log para visualizar el tiempo de ejecución de cada tarea. DECORADORES??\n\"\"\"\nfrom time import sleep\nimport time\n\ndef task_number_decorator(function):\n    def original_function(tasks:list):\n        result = function(tasks)\n        logging.debug(f\"Número de tareas: {len(tasks)}\")\n        return result\n    return original_function\n\ndef time_decorator(function):\n    def original_function(*args):\n        start_time = time.time()\n        result = function(*args)\n        end_time = time.time()\n        print(f\"La ejecución ha tardado {end_time - start_time:.6} segundos\")\n        print(\"\\n\")\n        sleep(1)\n        return result\n    return original_function\n\n@time_decorator\n@task_number_decorator\ndef add_task(tasks:list):\n    task:dict = {\"name\":\"\",\"description\":\"\"}\n    task[\"name\"] = input(\"Dime el nombre para esta tarea: \")\n    for element in tasks: #busco si la tarea ya existe en el sistema\n        if element[\"name\"] == task[\"name\"]:\n            logging.warning(\"La tarea ya existe en el sistema\")#si existe lanzo un logging.error\n            break\n    else: #si no existe añado la descripción y continúa la ejecución\n        task[\"description\"] = input(\"Y ahora la descripción: \")\n        tasks.append(task)\n        logging.info(f\"Tarea {task[\"name\"]} guardada en el sistema.\")\n    return tasks\n\n@time_decorator\n@task_number_decorator\ndef erase_task(tasks:list):\n    if len(tasks) == 0:\n        logging.warning(f\"No hay tareas registradas en el sistema.\")\n    else:\n        name:str = input(\"Dime el nombre de la tarea que quieres borrar: \")\n        for element in tasks:\n            if element[\"name\"] == name:\n                tasks.remove(element)\n                logging.error(f\"-- La tarea {name} ha sido borrada del sistema.\")\n                break\n        else:\n            logging.error(f\"La tarea {name} no existe en el sistema.\")\n    return tasks\n\n@time_decorator\ndef list_tasks(tasks):\n    if len(tasks) == 0:\n        logging.warning(\"No hay tareas registradas en el sistema\")\n    else:\n        print(\"Estas son las tareas que hay en el sistema:\")\n        for element in tasks:\n            print(f\" - Nombre: {element[\"name\"]}\\n - Descripción: {element[\"description\"]}\\n\")\n\n\nprint(\"\\n\\nTe doy la bienvenida al progranma de gestión de tareas\")\ntasks = list() #uso una lista aunque lo suyo sería usar un archivo externo para el log\n#esta lista va a contener diccionarios con los elementos name y description.\nwhile True:\n    option = input(\"Por favor elije una de las opciones:\\n - Añadir tarea(A)\\n - Listar tareas(L)\\n - Eliminar tarea(E)\\n - Salir(S)\\nTu opción --->\").upper()\n    if option == \"A\":\n        add_task(tasks)\n    elif option == \"E\":\n        erase_task(tasks)\n    elif option == \"L\":\n        list_tasks(tasks)\n    elif option == \"S\":\n        print(\"Gracias por usar el sistema. Hasta pronto.\")\n        sleep(1)\n        break\n    else:\n        print(\"La opción no es correcta\\n\")\n        sleep(1)\n"
  },
  {
    "path": "Roadmap/25 - LOGS/python/barrancus.py",
    "content": "#25 - Pyton - Logs \n# EJERCICIO:\n# Explora el concepto de \"logging\" en tu lenguaje. Configúralo y muestra\n# un ejemplo con cada nivel de \"severidad\" disponible.\n# \n# DIFICULTAD EXTRA (opcional):\n# Crea un programa ficticio de gestión de tareas que permita añadir, eliminar\n# y listar dichas tareas.\n# - Añadir: recibe nombre y descripción.\n# - Eliminar: por nombre de la tarea.\n# Implementa diferentes mensajes de log que muestren información según la\n# tarea ejecutada (a tu elección).\n# Utiliza el log para visualizar el tiempo de ejecución de cada tarea.\n# \nimport logging as log\nimport os\n\nclass Counter:\n    def __iter__(self):\n        self.a = 1\n        return self\n    \n    def __next__(self):\n        x = self.a\n        self.a += 1\n        return x\n\nidentifier = iter(Counter())\n\nclass Task:\n    def __init__(self, name: str, description: str):\n        self.name = name\n        self.description = description\n        self.identifier = f'{next(identifier):03}'\n\n    def __str__(self):\n        return f'{self.identifier} - {self.name}: {self.description}'\n    \n    def show_task(self):\n        print(self)\n\ndef separacion(cadena) -> str:\n    global contador\n    print(f'\\nEjercicio {next(contador)}. {cadena * 20}')\n\ncontador = iter(Counter())\n\nlog.basicConfig(filename=r'.\\25_logs.log',\n                level=log.DEBUG,\n                format='%(asctime)s - %(name)s - %(funcName)-8s - %(levelname)-8s - %(message)s',\n                encoding='utf-8')\n\ndef mensages_log() -> None:\n    separacion('-:-')\n    log.debug('Este es un mensaje de DEBUG')\n    log.info('Este es un mensaje de INFO')\n    log.warning('Este es un mensaje de WARNING')\n    log.error('Este es un mensaje de ERROR')\n    log.critical('Este es un mensaje de CRITICAL')\n    print('Mensajes de log generados. Revisar el archivo 25_logs.log')\n\ndef task_manager() -> None:\n    separacion('-:-')\n    tasks = []\n    while True:\n        print(\"\\nGestor de Tareas\")\n        print(\"1. Añadir tarea\")\n        print(\"2. Eliminar tarea\")\n        print(\"3. Listar tareas\")\n        print(\"0. Salir\")\n        option = input(\"Selecciona una opción: \")\n        \n        match option:\n            case'1':\n                name = input(\"\\nNombre de la tarea: \")\n                description = input(\"Descripción de la tarea: \")\n                tasks.append(Task(name, description))\n                log.info(f'Tarea añadida: {tasks[-1].name} - {tasks[-1].description}')\n                print(f'Tarea \"{tasks[-1].name}\" añadida.')\n            case'2':\n                name = input(\"\\nNombre de la tarea a eliminar: \")\n                for task in tasks:\n                    if task.name == name:\n                        tasks.remove(task)\n                        break\n                log.warning(f'Tarea eliminada: {name}')\n                print(f'Tarea \"{name}\" eliminada.')\n                print(f'Tareas pendientes: {len(tasks)}')\n            case '3':\n                log.info('Listado de tareas solicitado')\n                for task in tasks:\n                    task.show_task()\n            case'0':\n                log.info('Salida del gestor de tareas')\n                print(\"Saliendo del gestor de tareas.\")\n                break\n            case _:\n                log.error('Opción inválida seleccionada')\n                print(\"Opción inválida. Inténtalo de nuevo.\")\n\ndef main():\n    mensages_log()\n    task_manager()\n    log.shutdown()\n    print(\"\\nQuieres borrar el archivo de logs? (s/n): \", end='')\n    if input().lower() == 's':\n        os.remove(r'.\\25_logs.log')\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Roadmap/25 - LOGS/python/bytecodesky.py",
    "content": "'''\n/*\n * EJERCICIO:\n * Explora el concepto de \"logging\" en tu lenguaje. Configúralo y muestra\n * un ejemplo con cada nivel de \"severidad\" disponible.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa ficticio de gestión de tareas que permita añadir, eliminar\n * y listar dichas tareas.\n * - Añadir: recibe nombre y descripción.\n * - Eliminar: por nombre de la tarea.\n * Implementa diferentes mensajes de log que muestren información según la \n * tarea ejecutada (a tu elección).\n * Utiliza el log para visualizar el tiempo de ejecución de cada tarea. \n */\n'''\n#https://docs.python.org/3/library/logging.html\nimport logging\n#https://docs.python.org/3/library/logging.html#logging.basicConfig\nlogging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')\n\nlogging.debug('This is a debug message') #https://docs.python.org/3/library/logging.html#logging.debug\nlogging.info('This is an info message') #https://docs.python.org/3/library/logging.html#logging.info\nlogging.warning('This is a warning message') #https://docs.python.org/3/library/logging.html#logging.warning\nlogging.error('This is an error message') #https://docs.python.org/3/library/logging.html#logging.error\nlogging.critical('This is a critical message') #https://docs.python.org/3/library/logging.html#logging.critical\n\n#DIFICULTAD EXTRA, GESTION DE TAREAS\nimport time\nclass Tarea:\n    def __init__(self, nombre, descripcion):\n        self.nombre = nombre\n        self.descripcion = descripcion\n\n    def __str__(self):\n        return f'{self.nombre} - {self.descripcion}'\n\nclass GestorTareas:\n    def __init__(self):\n        self.tareas = []\n\n    def agregar_tarea(self, tarea):\n        logging.info(f'Tarea añadida: {tarea}')\n        self.tareas.append(tarea)\n\n    def eliminar_tarea(self, nombre):\n        for tarea in self.tareas:\n            if tarea.nombre == nombre:\n                self.tareas.remove(tarea)\n                logging.info(f'Tarea eliminada: {tarea}')\n                break\n\ngestor = GestorTareas()\nlogging.info('Gestor de tareas creado')\ntime.sleep(2)\ntarea1 = Tarea('Tarea 1', 'Salir a correr')\ngestor.agregar_tarea(tarea1)\ntime.sleep(1)\ntarea2 = Tarea('Tarea 2', 'Terminar mi sitio web')\ngestor.agregar_tarea(tarea2)\ntime.sleep(1)\ntarea3 = Tarea('Tarea 3', 'Estudiar Python')\ngestor.agregar_tarea(tarea3)\ntime.sleep(2)\nlogging.info('Tareas añadidas')\ntime.sleep(1)\nlogging.info('Eliminando tareas')\ntime.sleep(2)\ngestor.eliminar_tarea('Tarea 2')\ntime.sleep(1)\ngestor.eliminar_tarea('Tarea 1')\ntime.sleep(1)\ngestor.eliminar_tarea('Tarea 3')\ntime.sleep(1)"
  },
  {
    "path": "Roadmap/25 - LOGS/python/cristianfloyd.py",
    "content": "# EJERCICIO:\n# Explora el concepto de \"logging\" en tu lenguaje. Configúralo y muestra\n# un ejemplo con cada nivel de \"severidad\" disponible.\nimport logging\nfrom typing import Dict\nimport time\n\nlogging.basicConfig(\n    level=logging.DEBUG,\n    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',  # Formato del mensaje\n    datefmt='%Y-%m-%d %H:%M:%S'\n)\n\nlogging.debug(\"Esto es un mensaje de debug\")\nlogging.info(\"Esto es un mensaje de info\")\nlogging.warning(\"Esto es un mensaje de warning\")\nlogging.error(\"Esto es un mensaje de error\")\nlogging.critical(\"Esto es un mensaje de critical\")\n\n#\n# DIFICULTAD EXTRA (opcional):\n# Crea un programa ficticio de gestión de tareas que permita añadir, eliminar\n# y listar dichas tareas.\n# - Añadir: recibe nombre y descripción.\n# - Eliminar: por nombre de la tarea.\n# Implementa diferentes mensajes de log que muestren información según la\n# tarea ejecutada (a tu elección).\n# Utiliza el log para visualizar el tiempo de ejecución de cada tarea.\n\ndef medir_tiempo(func):\n    \"\"\"Decorador para medir el tiempo de ejecución de una función.\"\"\"\n    def wrapper(*args, **kwargs):\n        logger = logging.getLogger(__name__)\n        inicio = time.time()\n\n        resultado = func(*args, **kwargs)\n\n        tiempo_ejecucion = (time.time() - inicio) * 1000\n        logger.info(f\"{func.__name__} se ejecuto en {tiempo_ejecucion:.2f} milisegundos\")\n\n        return resultado\n    return wrapper\n\n\nclass GestorTareas:\n    def __init__(self):\n        self.tareas: Dict[str, str] = {} # Diccionario para almacenar las tareas\n        self.logger = logging.getLogger(__name__)\n\n    @medir_tiempo\n    def add_task(self, name: str, descripcion: str):\n        self.logger.debug(f\"Intentando añadir tarea: {name}\")\n        name = name.lower().strip()\n        descripcion = descripcion.lower().strip()\n        if name in self.tareas:\n            self.logger.warning(f\"Tarea ya existe: {name}. Sobreescribiendo tarea\")\n            del self.tareas[name]\n        \n        self.tareas[name] = descripcion\n        \n        self.logger.info(f\"Tarea añadida: {name}\")\n        self.logger.debug(f\"Total de tareas: {len(self.tareas)}\")\n    \n    @medir_tiempo\n    def delete_task(self, name: str):\n        self.logger.debug(f\"Intentando eliminar tarea: '{name}'\")\n        name = name.lower().strip()\n\n        if name not in self.tareas:\n            self.logger.error(f\"No se puede eliminar. La tarea '{name}' no existe\")\n            return\n        \n        del self.tareas[name]\n        \n        self.logger.info(f\"Tarea '{name}' eliminada correctamente\")\n        self.logger.debug(f\"Tareas restantes: {len(self.tareas)}\")\n\n    @medir_tiempo\n    def listar_tareas(self):\n        self.logger.info(\"=== Listando tareas ===\")\n        \n        if not self.tareas:\n            self.logger.warning(\"No hay tareas en el sistema\")\n            return\n        \n        self.logger.debug(f\"Se encontraron {len(self.tareas)} tareas\")\n        \n        for name, descripcion in self.tareas.items():\n            print(f\"- {name}: {descripcion}\")\n            self.logger.debug(f\"Tarea listada: {name}\")\n        \n\n\n\ndef main():\n    gestor = GestorTareas()\n\n\n    print(\"\\n=== Añadiendo tareas ===\")\n    gestor.add_task(\"Estudiar Python\", \"Repasar logging y decoradores\")\n    gestor.add_task(\"Hacer ejercicio\", \"30 minutos de cardio\")\n    gestor.add_task(\"Leer libro\", \"Continuar con Clean Code\")\n    gestor.add_task(\"Estudiar Python\", \"Nueva descripción\")\n\n    \n    print(\"\\n=== Listando tareas ===\")\n    gestor.listar_tareas()\n    \n    print(\"\\n=== Eliminando tarea ===\")\n    gestor.delete_task(\"Hacer ejercicio\")\n    gestor.delete_task(\"Leer\")\n    \n    print(\"\\n=== Intentando eliminar tarea inexistente ===\")\n    gestor.delete_task(\"Tarea que no existe\")\n    \n    print(\"\\n=== Listando tareas actualizadas ===\")\n    gestor.listar_tareas()\n    \n    print(\"\\n=== Añadiendo tarea duplicada ===\")\n    gestor.add_task(\"Estudiar Python\", \"Nueva descripción\")\n\nif __name__ == \"__main__\":\n    main()"
  },
  {
    "path": "Roadmap/25 - LOGS/python/cyberdidac.py",
    "content": "import logging\nfrom datetime import datetime\n\nlogger = logging.getLogger(__name__)\nlogging.basicConfig(filename=\"cyberdidac.log\", encoding='utf-8', level=logging.DEBUG)\n\ntasks = []\n\n\nclass Task:\n    name: str\n    date: datetime\n    description: str\n\n    def __init__(self, name, date, description):\n        self.name = name\n        self.date = date\n        self.description = description\n\n\ndef add_task(name, date, description):\n    new_task = Task(name=name, date=date, description=description)\n    tasks.append(new_task)\n    logger.info(f\"Tarea '{name}' añadida: {datetime.now()}\")\n\n\ndef delete_task(name):\n    find = False\n\n    for i, task in enumerate(tasks):\n        if task.name == name:\n            tasks.pop(i)\n            print(\"Tarea eliminada\")\n            logger.info(f\"Tarea '{name}' eliminada: {datetime.now()}\")\n            find = True\n            break\n\n    if not find:\n        print(f\"La tarea '{name}' no existe\")\n        logger.warning(f\"La tarea '{name}' no existe: {datetime.now()}\")\n\n\ndef list_tasks():\n    logger.info(f\"Tareas listadas: {datetime.now()}\")\n    for task in tasks:\n        print(f\"\\n> {task.name}\")\n        print(f\"{task.date}\")\n        print(f\"{task.description}\")\n\n\ndef main():\n    print(\"\\nBienvenido a gestor de tareas\")\n\n    quit = False\n\n    while not quit:\n        print(\"\\n¿Qué deseas realizar?\"\n              \"\\n1 - Añadir tarea\"\n              \"\\n2 - Eliminar tarea\"\n              \"\\n3 - Mostrar tareas\"\n              \"\\n4 - Finalizar\")\n\n        choice = input(\"> \")\n\n        match choice:\n            case \"1\":\n                try:\n                    name = input(\"Nombre: \")\n\n                    day = int(input(\"Day: \"))\n                    month = int(input(\"Month: \"))\n                    year = int(input(\"Year: \"))\n                    hour = int(input(\"Hour: \"))\n                    minute = int(input(\"Minute: \"))\n                    date = datetime(year=year, month=month, day=day, hour=hour, minute=minute)\n\n                    description = input(\"Description: \")\n\n                    add_task(name, date, description)\n                except Exception as e:\n                    print(\"Error: datos incorrectos\")\n                    logger.error(f\"Datos introducidos incorrectos: {datetime.now()}\")\n            case \"2\":\n                name = input(\"Nombre: \")\n                delete_task(name)\n            case \"3\":\n                list_tasks()\n            case \"4\":\n                quit = True\n                print(\"Hasta pronto\")\n                logger.info(f\"Sesión finalizada: {datetime.now()}\")\n            case _:\n                print(\"Acción no válida\")\n                logger.error(f\"Intento de ejecución de acción inválida: {datetime.now()}\")\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Roadmap/25 - LOGS/python/davidrguez98.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Explora el concepto de \"logging\" en tu lenguaje. Configúralo y muestra\n * un ejemplo con cada nivel de \"severidad\" disponible.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa ficticio de gestión de tareas que permita añadir, eliminar\n * y listar dichas tareas.\n * - Añadir: recibe nombre y descripción.\n * - Eliminar: por nombre de la tarea.\n * Implementa diferentes mensajes de log que muestren información según la \n * tarea ejecutada (a tu elección).\n * Utiliza el log para visualizar el tiempo de ejecución de cada tarea. \n */ \"\"\"\n\n#EJERCICIO\n\nimport logging\n\nlogging.debug(\"Esto es un mensaje de debug\")\nlogging.info(\"Esto es un mensaje de información\")\nlogging.warning(\"Esto es un mensaje de warning\")\nlogging.error(\"Esto es un mensaje de error\")\nlogging.critical(\"Esto es un mensaje critico\")\n\n#DIFICULTAD EXTRA\n\nlogging.basicConfig(level=logging.INFO, format=\"\\n%(levelname)s: %(message)s\")\n\nclass TaskManager:\n\n    def __init__(self):\n        self.tasks = {}\n\n    def new_task(self, name: str, description: str):\n        if name not in self.tasks:\n            self.tasks[name] = description\n            logging.info(f\"La tarea {name} ha sido añadida.\")\n        elif name in self.tasks:\n                logging.error(f\"La tarea {name} ya estaba añadida a la lista de tareas.\")\n        else:\n            print(\"La tarea no ha podido ser creada.\")\n            logging.debug(f\"Error al añadir la tarea {name}.\")\n\n    def delete_task(self, name):\n        if name in self.tasks:\n            del self.tasks[name]\n            logging.info(f\"La tarea {name} ha sido eliminada\")\n        elif name not in self.tasks:\n                logging.error(f\"La tarea {name} no existe.\")\n        else:\n            print(\"La tarea no ha podido ser eliminada.\")\n            logging.debug(f\"Error al eliminar la tarea {name}.\")\n\n    def list_tasks(self):\n        if self.tasks:\n            print(\"\\nLISTADO DE TAREAS:\\n\")\n            for name, description in self.tasks.items():\n                print(f\"{name}: {description}\")\n        else:\n            print(\"La lista de tarea no ha podido ser mostrada.\")\n            logging.debug(f\"Error al visualizar la lista de tareas.\")\n\n\ntask_manager = TaskManager()\ntask_manager.new_task(\"Pan\", \"Comprar una barra de pan integral\")\ntask_manager.new_task(\"Pan\", \"Comprar una barra de pan integral\")\ntask_manager.new_task(\"Ejercicio\", \"Hacer 30 minutos de yoga\")\ntask_manager.new_task(\"Estudio\", \"Repasar conceptos básicos de React\")\ntask_manager.new_task(\"Trabajo\", \"Enviar el informe mensual al supervisor\")\ntask_manager.new_task(\"Cita médica\", \"Pedir cita para revisión anual\")\ntask_manager.new_task(\"Tomates\", \"Comprar 6 tomates\")\ntask_manager.list_tasks()\ntask_manager.delete_task(\"Estudio\")\ntask_manager.delete_task(\"Cebolla\")\ntask_manager.list_tasks()"
  },
  {
    "path": "Roadmap/25 - LOGS/python/duendeintemporal.py",
    "content": "#25 { Retos para Programadores } LOGS \n\n# Bibliography reference\n# I use GPT as a reference and sometimes to correct or generate proper comments.\n\n\"\"\"  \n* EJERCICIO:\n * Explora el concepto de \"logging\" en tu lenguaje. Configúralo y muestra\n * un ejemplo con cada nivel de \"severidad\" disponible.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa ficticio de gestión de tareas que permita añadir, eliminar\n * y listar dichas tareas.\n * - Añadir: recibe nombre y descripción.\n * - Eliminar: por nombre de la tarea.\n * Implementa diferentes mensajes de log que muestren información según la\n * tarea ejecutada (a tu elección).\n * Utiliza el log para visualizar el tiempo de ejecución de cada tarea.\n\n \"\"\"\n\nlog = print\nlog('Retos para Programadores #25')\n\nimport logging\nimport time\n\n# Set up logging configuration\nlogging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')\n\n# Define logging functions\ndef log_debug(message):\n    logging.debug(f\"DEBUG: {message}\")\n\ndef log_info(message):\n    logging.info(f\"INFO: {message}\")\n\ndef log_warning(message):\n    logging.warning(f\"WARNING: {message}\")\n\ndef log_error(message):\n    logging.error(f\"ERROR: {message}\")\n\ndef log_critical(message):\n    logging.critical(f\"CRITICAL: {message}\")\n\n# Example usage of logging\nlog_info(\"Retosparaprogramadores #25.\") # 2024-12-25 11:54:13,185 - INFO - INFO: Retosparaprogramadores #25.\nlog_debug(\"This is a debug message.\") # 2024-12-25 11:54:13,186 - DEBUG - DEBUG: This is a debug message.\nlog_info(\"This is an informational message.\") # 2024-12-25 11:54:13,186 - INFO - INFO: This is an informational message.\nlog_warning(\"This is a warning message.\") # 2024-12-25 11:54:13,186 - WARNING - WARNING: This is a warning message.\nlog_error(\"This is an error message.\") # 2024-12-25 11:54:13,186 - ERROR - ERROR: This is an error message.\nlog_critical(\"This is a critical message.\") # 2024-12-25 11:54:13,186 - CRITICAL - CRITICAL: This is a critical message.\n\n# Task Manager class\nclass TaskManager:\n    def __init__(self):\n        self.tasks = {}\n\n    def add_task(self, name, description):\n        start_time = time.time()\n        if name in self.tasks:\n            log_warning(f\"The task '{name}' already exists.\")\n            self.prompt_edit_task(name)\n            return\n        self.tasks[name] = description\n        log_info(f\"Task added: {name} - {description}\")\n        end_time = time.time()\n        log_debug(f\"Execution time for adding task: {(end_time - start_time):.2f} seconds\")\n\n    def prompt_edit_task(self, name):\n        answer = input(f\"The task '{name}' already exists. Do you want to edit it? (yes/no): \")\n        if answer.lower() == 'yes':\n            new_description = input('Enter the new description: ')\n            self.edit_task(name, new_description)\n        else:\n            log_info(f\"No changes made to the task '{name}'.\")\n\n    def edit_task(self, name, new_description):\n        start_time = time.time()\n        if name not in self.tasks:\n            log_error(f\"Could not edit the task '{name}' because it does not exist.\")\n            return\n        self.tasks[name] = new_description\n        log_info(f\"Task edited: {name} - New Description: {new_description}\")\n        end_time = time.time()\n        log_debug(f\"Execution time for editing task: {(end_time - start_time):.2f} seconds\")\n\n    def remove_task(self, name):\n        start_time = time.time()\n        if name not in self.tasks:\n            log_error(f\"Could not remove the task '{name}' because it does not exist.\")\n            return\n        del self.tasks[name]\n        log_info(f\"Task removed: {name}\")\n        end_time = time.time()\n        log_debug(f\"Execution time for removing task: {(end_time - start_time):.2f} seconds\")\n\n    def list_tasks(self):\n        start_time = time.time()\n        if not self.tasks:\n            log_warning(\"No tasks to display.\")\n            return\n        log_info(\"Task list:\")\n        for name, description in self.tasks.items():\n            log_info(f\"- {name}: {description}\")\n        end_time = time.time()\n        log_debug(f\"Execution time for listing tasks: {(end_time - start_time):.2f} seconds\")\n\n# Example usage of TaskManager\nmanager = TaskManager()\nmanager.add_task(\"Implement User Authentication\", \"Develop a user authentication system that allows users to register, log in, and log out securely.\")\nmanager.add_task(\"Fix Bug in Feature Resize window\", \"Fix Bug in Feature Resize window\")\nmanager.add_task(\"Write Unit Tests\", \"Write Unit Tests - Create tests for the user authentication module using Jest.\")\nmanager.add_task(\"Refactor Code for Module Lang_translation\", \"Refactor Code for Module Lang_translation - Simplify the logic and remove redundant code.\")\nmanager.add_task(\"Deploy Application to Production\", \"Deploy Application to Production - Set up CI/CD pipeline and deploy the latest build.\")\nmanager.list_tasks()\nmanager.remove_task(\"Implement User Authentication\")\nmanager.edit_task(\"Fix Bug in Feature Resize window\", \"Fix Bug in Feature Resize window - Resolve the issue causing the application to crash on submission.\")\nmanager.list_tasks()\n\n# Output:\n\"\"\"  \n2024-12-25 11:54:13,187 - INFO - INFO: Task added: Implement User Authentication - Develop a user authentication system that allows users to register, log in, and log out securely.\n2024-12-25 11:54:13,187 - DEBUG - DEBUG: Execution time for adding task: 0.00 seconds\n2024-12-25 11:54:13,187 - INFO - INFO: Task added: Fix Bug in Feature Resize window - Fix Bug in Feature Resize window\n2024-12-25 11:54:13,187 - DEBUG - DEBUG: Execution time for adding task: 0.00 seconds\n2024-12-25 11:54:13,188 - INFO - INFO: Task added: Write Unit Tests - Write Unit Tests - Create tests for the user authentication module using Jest.\n2024-12-25 11:54:13,188 - DEBUG - DEBUG: Execution time for adding task: 0.00 seconds\n2024-12-25 11:54:13,188 - INFO - INFO: Task added: Refactor Code for Module Lang_translation - Refactor Code for Module Lang_translation - Simplify the logic and remove redundant code.\n2024-12-25 11:54:13,188 - DEBUG - DEBUG: Execution time for adding task: 0.00 seconds\n2024-12-25 11:54:13,188 - INFO - INFO: Task added: Deploy Application to Production - Deploy Application to Production - Set up CI/CD pipeline and deploy the latest build.\n2024-12-25 11:54:13,188 - DEBUG - DEBUG: Execution time for adding task: 0.00 seconds\n2024-12-25 11:54:13,189 - INFO - INFO: Task list:\n2024-12-25 11:54:13,189 - INFO - INFO: - Implement User Authentication: Develop a user authentication system that allows users to register, log in, and log out securely.\n2024-12-25 11:54:13,189 - INFO - INFO: - Fix Bug in Feature Resize window: Fix Bug in Feature Resize window\n2024-12-25 11:54:13,189 - INFO - INFO: - Write Unit Tests: Write Unit Tests - Create tests for the user authentication module using Jest.\n2024-12-25 11:54:13,189 - INFO - INFO: - Refactor Code for Module Lang_translation: Refactor Code for Module Lang_translation - Simplify the logic and remove redundant code.\n2024-12-25 11:54:13,189 - INFO - INFO: - Deploy Application to Production: Deploy Application to Production - Set up CI/CD pipeline and deploy the latest build.\n2024-12-25 11:54:13,191 - DEBUG - DEBUG: Execution time for listing tasks: 0.00 seconds\n2024-12-25 11:54:13,191 - INFO - INFO: Task removed: Implement User Authentication\n2024-12-25 11:54:13,191 - DEBUG - DEBUG: Execution time for removing task: 0.00 seconds\n2024-12-25 11:54:13,191 - INFO - INFO: Task edited: Fix Bug in Feature Resize window - New Description: Fix Bug in Feature Resize window - Resolve the issue causing the application to crash on submission.\n2024-12-25 11:54:13,191 - DEBUG - DEBUG: Execution time for editing task: 0.00 seconds\n2024-12-25 11:54:13,191 - INFO - INFO: Task list:\n2024-12-25 11:54:13,191 - INFO - INFO: - Fix Bug in Feature Resize window: Fix Bug in Feature Resize window - Resolve the issue causing the application to crash on submission.\n2024-12-25 11:54:13,192 - INFO - INFO: - Write Unit Tests: Write Unit Tests - Create tests for the user authentication module using Jest.\n2024-12-25 11:54:13,192 - INFO - INFO: - Refactor Code for Module Lang_translation: Refactor Code for Module Lang_translation - Simplify the logic and remove redundant code.\n2024-12-25 11:54:13,192 - INFO - INFO: - Deploy Application to Production: Deploy Application to Production - Set up CI/CD pipeline and deploy the latest build.\n2024-12-25 11:54:13,192 - DEBUG - DEBUG: Execution time for listing tasks: 0.00 seconds \n\n\"\"\"\n"
  },
  {
    "path": "Roadmap/25 - LOGS/python/fborjalv.py",
    "content": "import logging\nimport time\n\"\"\"\n * EJERCICIO:\n * Explora el concepto de \"logging\" en tu lenguaje. Configúralo y muestra\n * un ejemplo con cada nivel de \"severidad\" disponible.\n\n\"\"\"\n\n\n# CONFIGURACIÓN\nlogging.basicConfig(level=logging.DEBUG,\n                    format = \"%(asctime)s - %(levelname)s - %(message)s\")\n\n# NIVELES DE SEVERIDAD\nlogging.debug(\"Este es un mensaje de debug\")\nlogging.info(\"Este es un mensaje de info\")\nlogging.warning(\"Este es un mensaje de warning\")\nlogging.error(\"Este es un mensaje de error\")\nlogging.critical(\"Este es un mensaje critical\")\n\n\n\"\"\"\nDIFICULTAD EXTRA (opcional):\n * Crea un programa ficticio de gestión de tareas que permita añadir, eliminar\n * y listar dichas tareas.\n * - Añadir: recibe nombre y descripción.\n * - Eliminar: por nombre de la tarea.\n * Implementa diferentes mensajes de log que muestren información según la\n * tarea ejecutada (a tu elección).\n * Utiliza el log para visualizar el tiempo de ejecución de cada tarea.\n */\n\n\"\"\"\n\n\nclass TaskManager:\n\n    def __init__(self) -> None:\n        self.task = {}\n\n    def _print_time_(function):\n        def count_time(*args):\n            start_time = time.time()\n            result = function(*args)\n            end_time = time.time()\n            logging.debug(f\"Tiempo de ejecución {end_time-start_time:.6f} segundos.\")\n            return result\n        return count_time\n        \n    @_print_time_\n    def add_task(self, name, description):\n        if name in self.task.keys():\n            logging.error(f\"Se ha intentado agregar la tarea {name} que ya existía\")\n        else: \n            self.task[name] = description\n            logging.info(f\"La tarea {name} se ha añadido exitosamente\")\n        logging.info(f\"Hay {len(self.task)} tareas almacenadas\")\n        end_time = time.time()\n\n    @_print_time_\n    def show_task(self):\n        if not self.task: \n            logging.warning(\"No había tareas para mostrar\")\n        else: \n            for key, value in self.task.items():\n                print(f\"Task: {key} - Description: {value}\")\n            logging.info(f\"Se han mostrado correctamente {len(self.task)} tareas\")\n\n    @_print_time_\n    def delete_task(self, name):\n        if name in self.task.keys():\n            del self.task[name]\n            logging.info(f\"La tarea {name} se ha eliminado exitosamente\")\n        else: \n            logging.error(\"Se ha intentado eliminar una tarea que no existe\")\n        logging.info(f\"Hay {len(self.task)} tareas almacenadas\")\n\n\n    \n\n\nmanager = TaskManager()\nmanager.add_task(\"programacion\", \"ejercicios\")\nmanager.add_task(\"programacion\", \"ejercicios\")\nmanager.add_task(\"Machine learning\", \"ejercicios\")\nmanager.add_task(\"Python\", \"ejercicios\")\nmanager.add_task(\"estadistica\", \"ejercicios\")\nmanager.show_task()\nmanager.delete_task(\"maths\")\nmanager.delete_task(\"estadistica\")\nmanager.delete_task(\"programacion\")\nmanager.show_task()"
  },
  {
    "path": "Roadmap/25 - LOGS/python/franxiscodev.py",
    "content": "'''\nLOGS\n'''\nimport logging\nimport time\n\n# niveles de severidad\n# cuando paso a producción level=logging.ERROR\nlogging.basicConfig(level=logging.DEBUG,\n                    format=\"%(asctime)s - %(levelname)s - %(message)s\")\n\nlogging.debug(\"Esto es un mensaje de DEBUG\")\nlogging.info(\"Esto es un mensajito de INFO\")\n# solo imprime por default warning error critical\nlogging.warning(\"mensaje de WARNING\")\nlogging.error(\"cuidado cuidado ERROR\")\nlogging.critical(\"esto es grave CRITICAL\")\n\n'''\nExtra\n'''\n\n\nclass TaskManager:\n\n    def __init__(self) -> None:\n        self.tasks = {}\n        # print(type(self.tasks))\n\n    def _medir_tiempo(funcion):\n        \"\"\"Decorador para medir el tiempo de ejecución de una función.\"\"\"\n\n        def wrapper(self, *args, **kwargs):\n            inicio = time.time()\n            resultado = funcion(self, *args, **kwargs)\n            tiempo_ejecucion = time.time() - inicio\n            logging.info(\n                f\"TIEMPO ejecución {funcion.__name__}: {tiempo_ejecucion:.6f} segundos\")\n            return resultado\n        return wrapper\n\n    @_medir_tiempo\n    def add_task(self, name: str, description: str):\n        if name not in self.tasks:\n            self.tasks[name] = description\n            logging.info(f\"Tarea agregada ok: {name}\")\n        else:\n            logging.warning(\n                f\"Se ha intentado agregar una tarea existente: {name}\")\n        logging.debug(f\"Número de tareas actuales: {len(self.tasks)}\")\n\n    @_medir_tiempo\n    def delete_task(self, name: str):\n        if name in self.tasks:\n            del self.tasks[name]\n            logging.info(f\"Tarea eliminada ok: {name}\")\n        else:\n            logging.error(\n                f\"Se ha intentado eliminar una tarea NO existente: {name} 💥\")\n        logging.debug(f\"Número de tareas actuales: {len(self.tasks)}\")\n\n    @_medir_tiempo\n    def list_tasks(self):\n        if self.tasks:\n            # print(self.tasks)\n            logging.info(\"Imprimir Lista de tareas\")\n            for name, description in self.tasks.items():\n                print(f\"{name} - {description}\")\n        else:\n            logging.info(\"No hay tareas para mostrar\")\n\n\nprint(\"-- Tareas --\")\ntask_manager = TaskManager()\ntask_manager.add_task(\"Panecillos\", \"Comprar pancitos para picoteo\")\ntask_manager.add_task(\"Python\", \"Estudiar con picoteo\")\n\ntask_manager.list_tasks()\ntask_manager.delete_task(\"Python\")\ntask_manager.list_tasks()\n\ntask_manager.add_task(\"Panecillos\", \"Comprar +\")\n"
  },
  {
    "path": "Roadmap/25 - LOGS/python/ggilperez.py",
    "content": "# Logs\nimport logging\nimport time\n\nlogging.basicConfig()  # By default warning level\n\n\ndef print_logs():\n    logging.debug(\"This is a debug level log\")\n    logging.info(\"This is a info level log\")\n    logging.warning(\"This is a warning level log\")\n    logging.error(\"This is a error level log\")\n    logging.critical(\"This is a critical level log\")\n\nprint_logs()\n\nlogging.getLogger().setLevel(logging.DEBUG)\nprint_logs()\n\n# EXTRA\n\nclass TaskManager:\n\n    def __init__(self):\n        self.tasks = {}\n\n    def add_task(self, name, description):\n        start = time.time()\n        if name not in self.tasks:\n            logging.info(f\"adding task {name}\")\n            self.tasks[name] = description\n        else:\n            logging.error(f\"task {name} already exists\")\n        end = time.time()\n        logging.debug(f\"adding task time {end-start}s\")\n\n    def remove_tasks(self, name):\n        start = time.time()\n        if name in self.tasks:\n            logging.info(f\"removing task {name}\")\n            self.tasks.pop(name)\n        else:\n            logging.error(f\"task {name} not found\")\n        end = time.time()\n        logging.debug(f\"removing task time {end-start}s\")\n\n    def list_tasks(self):\n        start = time.time()\n        for key, value in self.tasks.items():\n            print(f\"Task: {key}. Description: {value}\")\n        end = time.time()\n        logging.debug(f\"listing task time {end-start}s\")\n\n\ntask_manager = TaskManager()\ntask_manager.add_task(\"SW Acolyte\", \"New episode wednesday\")\ntask_manager.add_task(\"Do house\", \"Clean\")\ntask_manager.list_tasks()\ntask_manager.remove_tasks(\"SW Acolyte\")\ntask_manager.list_tasks()\ntask_manager.add_task(\"Acolyte\", \"Create review\")\ntask_manager.remove_tasks(\"Do house\")\n"
  },
  {
    "path": "Roadmap/25 - LOGS/python/h4ckxel.py",
    "content": "import logging\nimport time\n\n'''\n  EJERCICIO\n'''\n\nlogging.basicConfig(level=logging.DEBUG,\n                    format='%(asctime)s - %(levelname)s - %(message)s',\n                    handlers=[logging.StreamHandler()])\n\nlogging.debug('Esto es un mensaje de DEBUG')\nlogging.info('Esto es un mensaje de INFO')\nlogging.warning('Esto es un mensaje de WARNING')\nlogging.error('Esto es un mensaje de ERROR')\nlogging.critical('Esto es un mensaje de CRITICAL')\n\n'''\n  EXTRA\n'''\n\nclass TaskManager:\n  def __init__(self) -> None:\n    self.tasks = {}\n\n  def add_task(self, name, description):\n    start_time = time.time()\n    if name not in self.tasks:\n      self.tasks[name] = description\n      logging.info(f\"Tarea añadida: {name}.\")\n    else:\n      logging.warning(\n        f\"Se ha intentado añadir una tarea que ya existe: {name}.\")\n    logging.debug(f\"Número de tareas: {len(self.tasks)}\")\n    end_time = time.time()\n    self._print_time(start_time, end_time)\n\n  def delete_task(self, name):\n    start_time = time.time()\n    if name in self.tasks:\n      del self.tasks[name]\n      logging.info(f\"Se ha eliminado la tarea: {name}.\")\n    else:\n      logging.error(\n        f\"Se ha intentado eliminar una tarea que no existe: {name}.\")\n    logging.debug(f\"Número de tareas: {len(self.tasks)}\")\n    end_time = time.time()\n    self._print_time(start_time, end_time)\n\n  def list_tasks(self):\n    start_time = time.time()\n    if self.tasks:\n      logging.info(f\"Lista de tareas: \")\n      for name, description in self.tasks.items():\n        print(f\"{name} - {description}\")\n    else:\n      logging.info(\"No hay tareas para mostrar.\")\n    end_time = time.time()\n    self._print_time(start_time, end_time)\n\n  def _print_time(self, start_time, end_time):\n    logging.debug(\n      f\"Tiempo de ejecución {end_time - start_time:.6f} seg.\" )\n    \ntask_manager = TaskManager()\ntask_manager.list_tasks()\ntask_manager.add_task(\"Pan\", \"Comprar 5 barras de pan\")\ntask_manager.add_task(\"Python\", \"Estudiar Python\")\ntask_manager.list_tasks()\ntask_manager.delete_task(\"Python\")\ntask_manager.list_tasks()\ntask_manager.add_task(\"Pan\", \"Comprar 5 barras de pan\")\ntask_manager.delete_task(\"Python\")"
  },
  {
    "path": "Roadmap/25 - LOGS/python/hectorio23.py",
    "content": "# Autor: Héctor Adán \n# GitHub: https://github.com/hectorio23 \nimport logging\nimport time\n\n\n#################################################\n################# EJERCICIO #####################\n#################################################\n\n# Configuración básica del logging\nlogging.basicConfig(level=logging.DEBUG,\n                    format='%(asctime)s - %(levelname)s - %(message)s')\n\n# Ejemplos de mensajes con cada nivel de severidad\nlogging.debug(\"Este es un mensaje de depuración.\")\nlogging.info(\"Este es un mensaje informativo.\")\nlogging.warning(\"Este es un mensaje de advertencia.\")\nlogging.error(\"Este es un mensaje de error.\")\nlogging.critical(\"Este es un mensaje crítico.\")\n\n\n\n#################################################\n############## EJERCICIO EXTRA ##################\n#################################################\n\n# Configuración del logging\nlogging.basicConfig(level=logging.DEBUG,\n                    format='%(asctime)s - %(levelname)s - %(message)s')\n\n# Lista para almacenar las tareas\ntareas = []\n\ndef add_task(nombre, descripcion):\n    start_time = time.time()\n    logging.info(f\"Añadiendo tarea: {nombre}\")\n    tarea = {\"nombre\": nombre, \"descripcion\": descripcion}\n    tareas.append(tarea)\n    logging.debug(f\"Tareas actuales: {tareas}\")\n    end_time = time.time()\n    logging.info(f\"Tarea añadida en {end_time - start_time} segundos\")\n\ndef delete_task(nombre):\n    start_time = time.time()\n    logging.info(f\"Eliminando tarea: {nombre}\")\n    global tareas\n    tareas = [tarea for tarea in tareas if tarea[\"nombre\"] != nombre]\n    logging.debug(f\"Tareas actuales: {tareas}\")\n    end_time = time.time()\n    logging.info(f\"Tarea eliminada en {end_time - start_time} segundos\")\n\ndef show_tasks():\n    logging.info(\"Listando todas las tareas\")\n    for tarea in tareas:\n        logging.info(f\"Tarea: {tarea['nombre']}, Descripción: {tarea['descripcion']}\")\n    if not tareas:\n        logging.warning(\"No hay tareas para listar\")\n\n# Ejemplo de uso del programa de gestión de tareas\nadd_task(\"Comprar pan\", \"Ir a la panadería y comprar una barra de pan\")\nadd_task(\"Estudiar Python\", \"Completar el ejercicio de logging en Python\")\nshow_tasks()\ndelete_task(\"Comprar pan\")\nshow_tasks()\n"
  },
  {
    "path": "Roadmap/25 - LOGS/python/hozlucas28.py",
    "content": "# pylint: disable=pointless-string-statement,missing-module-docstring,missing-class-docstring,missing-function-docstring\n\nimport logging\n\nfrom time import time\nfrom typing import TypedDict, Self\n\n\n\"\"\"\n    Logging...\n\"\"\"\n\nprint(\"Logging...\")\n\nlogging.basicConfig(\n    level=logging.DEBUG, format=\"%(asctime)s (%(levelname)s): %(message)s\"\n)\n\nprint(\"\\nlogging.critical(msg=<MESSAGE>)...\\n\")\nlogging.critical(msg=\"Critical log message!\")\n\nprint(\"\\nlogging.debug(msg=<MESSAGE>)...\\n\")\nlogging.debug(msg=\"Debug log message!\")\n\nprint(\"\\nlogging.error(msg=<MESSAGE>)...\\n\")\nlogging.error(msg=\"Error log message!\")\n\nprint(\"\\nlogging.info(msg=<MESSAGE>)...\\n\")\nlogging.info(msg=\"Information log message!\")\n\nprint(\"\\nlogging.warning(msg=<MESSAGE>)...\\n\")\nlogging.warning(msg=\"Warning log message!\")\n\n\nprint(\n    \"\\n# ---------------------------------------------------------------------------------- #\\n\"\n)\n\n\n\"\"\"\n    Additional challenge...\n\"\"\"\n\nprint(\"Additional challenge...\")\n\ntype Description = str\ntype Title = str\n\nTask = TypedDict(\n    \"Task\",\n    {\n        \"description\": Description,\n        \"title\": Title,\n    },\n)\n\n\nclass TaskManager:\n    __debug: bool\n    __tasks: list[Task]\n\n    def __init__(\n        self, *, initial_tasks: None | list[Task] = None, enableDebug=False\n    ) -> None:\n        self.__debug = enableDebug\n        self.__tasks = [] if initial_tasks is None else initial_tasks\n\n    def add_task(self, *, new_task: Task) -> Self:\n        if self.__debug:\n            print()\n            logging.debug(msg=\"addTask (method) start execution...\")\n            start_time: float = time()\n\n        self.__tasks.append(new_task)\n\n        if self.__debug:\n            logging.debug(msg=\"addTask (method) ends execution!\")\n            print(f\"addTask: {time()-start_time} seconds\")\n\n        return self\n\n    def delete_task_by_title(self, *, title: Title) -> Self:\n        if self.__debug:\n            print()\n            start_time: float = time()\n            logging.debug(msg=\"delete_task_by_title (method) start execution...\")\n\n        sanitized_tasks: list[Task] = []\n        sanitized_title: str = title.strip().upper()\n\n        for task in self.__tasks:\n            if task[\"title\"].strip().upper() != sanitized_title:\n                sanitized_tasks.append(task)\n\n        self.__tasks = sanitized_tasks\n\n        if self.__debug:\n            logging.debug(msg=\"delete_task_by_title (method) ends execution!\")\n            print(f\"delete_task_by_title: {time()-start_time} seconds\")\n\n        return self\n\n    def print_tasks(self) -> Self:\n        if self.__debug:\n            print()\n            logging.debug(msg=\"print_tasks (method) start execution...\")\n            start_time: float = time()\n            print()\n\n        for task in self.__tasks:\n            print(task)\n\n        if self.__debug:\n            print()\n            logging.debug(msg=\"print_tasks (method) ends execution!\")\n            print(f\"print_tasks: {time()-start_time} seconds\")\n\n        return self\n\n\ntask_manager: TaskManager = TaskManager(enableDebug=True)\n\nEXIT_: bool = False\n\nwhile not EXIT_:\n    operation: str = input(\n        \"\\nWrite an operation ('Add task', 'Delete task by title', 'Print tasks', or 'Exit'): \"\n    )\n\n    sanitized_operation: str = operation.strip().upper()\n\n    match sanitized_operation:\n        case \"ADD TASK\":\n\n            task_title: str = input(\"\\nTask title: \")\n            task_description: str = input(\"Task description: \")\n\n            task_manager.add_task(\n                new_task={\n                    \"title\": task_title.strip(),\n                    \"description\": task_description.strip(),\n                }\n            )\n\n        case \"DELETE TASK BY TITLE\":\n            task_title: str = input(\"\\nTask title: \")\n\n            task_manager.delete_task_by_title(title=task_title)\n\n        case \"PRINT TASKS\":\n            task_manager.print_tasks()\n\n        case \"EXIT\":\n            EXIT_ = True\n            print(\"\\nApplication closed!\")\n\n        case _:\n            print(\"\\nInvalid operation! Try again...\")\n"
  },
  {
    "path": "Roadmap/25 - LOGS/python/idiegorojas.py",
    "content": "\"\"\"\n25 - Logs\n\"\"\"\n# Es uan herramienta para rastrear enventos que ocurren cuando se ejecuta un software\n# Se puede usar para:\n    # Depurar codigo\n    # Monitorear el comportamiento de una aplicacion\n    # Mantener registros historicos\n\n\"\"\"\nEstructura\n\"\"\"\n# DEBUG: Informacion detallada cuando ocurre un problema\n# INFO: Confirmacion de que este funcionando como se espera\n# WARNING: Indicacion que algo inesperado ocurrio o podria ocurrir\n# Error: Problemas mas grabe, el software no realiza alguna funcion\n# CRITICAL: Un error muy grave, no permite que el programa se ejecute\n\n\"\"\"\nUsos y Funcionalidad\n\"\"\"\n# Depuración: Ayuda a rastrear y diagnosticar problemas en el código.\n# Monitoreo: Permite monitorear la actividad de la aplicación en tiempo real.\n# Auditoría: Mantiene un registro histórico de eventos importantes y errores.\n# Mantenimiento: Facilita el mantenimiento y la mejora del software al proporcionar un historial de eventos y errores.\n\n\"\"\"\nEjemplos:\n\"\"\"\n# Configuracion de un login\nimport logging\n\n# Configura el logger\nlogging.basicConfig(level=logging.DEBUG,\n                    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', # fecha, nombre del logger, nivel de severidad, mensaje.\n                    handlers=[logging.FileHandler(\"app.log\"),\n                              logging.StreamHandler()])\n\nlogger = logging.getLogger(__name__)\n\n# Ejemplos de logging\nlogger.debug('Esto es un mensaje de depuración')\nlogger.info('Esto es un mensaje de información')\nlogger.warning('Esto es una advertencia')\nlogger.error('Esto es un mensaje de error')\nlogger.critical('Esto es un mensaje crítico')\n\n\n# Procesar pedidos een una tienda en linea\ndef procesar_pedidos(order_id):\n    logger.info(f'Procesando el pedido: {order_id}')\n    try:\n        if order_id == 0:\n            raise ValueError('El ID del pedido no puede ser 0')\n        logger.info(f'El pedido: {order_id} procesado exitosamante')\n    except ValueError as e:\n        logger.error(f'Error al procesar el pedido {order_id}: {e}')\n    except Exception as e:\n        logger.critical(f'Error critico al procesar el pedido {order_id}: {e}')\n\nprint(procesar_pedidos(1))\nprint(procesar_pedidos(0))\n\n\n\"\"\"\nExtra\n\"\"\"\n# Añadir, eliminar, listar tareas\n\n\nclass GestorTareas:\n\n    def __init__(self) -> None:\n        self.tareas = {}\n        # Puedes usar el logger que ya configuraste\n        self.logger = logging.getLogger(__name__)\n\n    def añadir(self, nombre: str, descripcion: str):\n        if not nombre or not descripcion:\n            print(\"El nombre y la descripción no pueden estar vacíos\")\n            self.logger.warning(\"Intento de añadir tarea con campos vacíos\")\n            return\n            \n        if nombre not in self.tareas:\n            self.tareas[nombre] = descripcion\n            print(f'Se añadió la tarea {nombre}')\n            self.logger.info(f'Tarea añadida: {nombre}')\n        else:\n            print(f'Lo sentimos, ya existe la tarea {nombre}.')\n            self.logger.warning(f'Intento de añadir tarea duplicada: {nombre}')\n\n    def listar(self, nombre: str):\n        if nombre in self.tareas:\n            print(f'La tarea {nombre} tiene la siguiente descripción: {self.tareas[nombre]}')\n            self.logger.info(f'Tarea consultada: {nombre}')\n        else:\n            print(f'No existe la tarea con el nombre: {nombre}')\n            self.logger.warning(f'Intento de consultar tarea inexistente: {nombre}')\n            \n    def listar_todas(self):\n        if not self.tareas:\n            print(\"No hay tareas registradas\")\n            return\n            \n        print(\"Lista de todas las tareas:\")\n        for nombre, descripcion in self.tareas.items():\n            print(f\"- {nombre}: {descripcion}\")\n        self.logger.info('Listado completo de tareas solicitado')\n\n    def modificar(self, nombre: str, nueva_descripcion: str):\n        if nombre in self.tareas:\n            self.tareas[nombre] = nueva_descripcion\n            print(f'La tarea {nombre} ha sido modificada')\n            self.logger.info(f'Tarea modificada: {nombre}')\n        else:\n            print(f'No existe la tarea con el nombre: {nombre}')\n            self.logger.warning(f'Intento de modificar tarea inexistente: {nombre}')\n\n    def eliminar(self, nombre: str):\n        if nombre in self.tareas:\n            del self.tareas[nombre]\n            print(f'La tarea {nombre} ha sido eliminada')\n            self.logger.info(f'Tarea eliminada: {nombre}')\n        else:\n            print('Lo sentimos, la tarea no ha sido eliminada porque no existe')\n            self.logger.warning(f'Intento de eliminar tarea inexistente: {nombre}')\n\n\ngestor = GestorTareas()\ngestor.añadir('Comprar leche', 'Comprar 2 litros de leche en el supermercado')\ngestor.añadir('Llamar al médico', 'Concertar cita para el próximo mes')\ngestor.listar_todas()\ngestor.modificar('Comprar leche', 'Comprar 1 litro de leche deslactosada')\ngestor.listar('Comprar leche')\ngestor.eliminar('Comprar leche')"
  },
  {
    "path": "Roadmap/25 - LOGS/python/ignaciovihe.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el concepto de \"logging\" en tu lenguaje. Configúralo y muestra\n * un ejemplo con cada nivel de \"severidad\" disponible.\n\"\"\"\n\n# ─────────────────────────────────────────────────────────────────────────────────\n#   Claves comunes del logging y sus tipos de formato\n#\n# | Clave            | Qué representa                         | Tipo     | Formato |\n# |------------------|----------------------------------------|----------|---------|\n# | asctime          | Fecha y hora (como texto)              | str      | %s      |\n# | levelname        | Nivel del log (DEBUG, INFO, etc.)      | str      | %s      |\n# | message          | El mensaje que escribes                | str      | %s      |\n# | name             | Nombre del logger                      | str      | %s      |\n# | filename         | Nombre del archivo                     | str      | %s      |\n# | module           | Nombre del módulo (sin .py)            | str      | %s      |\n# | pathname         | Ruta completa del archivo              | str      | %s      |\n# | funcName         | Nombre de la función                   | str      | %s      |\n# | processName      | Nombre del proceso                     | str      | %s      |\n# | threadName       | Nombre del hilo                        | str      | %s      |\n# | lineno           | Número de línea                        | int      | %d      |\n# | process          | ID del proceso (PID)                   | int      | %d      |\n# | thread           | ID del hilo                            | int      | %d      |\n# | created          | Timestamp (segundos desde epoch)       | float    | %f      |\n# | msecs            | Milisegundos de `asctime`              | float    | %f      |\n# | relativeCreated  | Tiempo desde inicio del logging        | float    | %f      |\n# ─────────────────────────────────────────────────────────────────────────────────\n\nimport logging\nfrom logging.handlers import RotatingFileHandler\n\n\"\"\"Configuracion básica. Cop logger raiz.\"\"\"\n\nlogging.basicConfig(filename= 'mi_basic_log.log',filemode= 'a',level=logging.INFO, format= '%(asctime)s - %(levelname)s - %(message)s')\n#Se configura logger por defecto\nlogging.debug(\"Este es un mensaje de depuración (DEBUG).\") #Se imprimen los mensajes segun la configuración\nlogging.info(\"Este es un mensaje informativo (INFO).\")\nlogging.warning(\"Este es un mensaje de advertencia (WARNING).\")\nlogging.error(\"Este es un mensaje de error (ERROR).\")\nlogging.critical(\"Este es un mensaje crítico (CRITICAL).\")\n\n\n\n\"\"\"Configuracion con logger y handlers\"\"\"\n\n#Se crea un logger. Si no le pongo nombre se considera tambien el raiz.\nlogger = logging.getLogger(\"mi_logguer\") #Se le puede dar un nombre al crear y funcionan como jerarquia. logguer.sublogger.subsublogger\nlogger.setLevel(logging.DEBUG) # Si no lo configuro manualmente, por defecto se establece en Warning\n\n# Configuración para la consola\nconsole_handler = logging.StreamHandler()\nconsole_handler.setLevel(logging.INFO)\n\n# Configuración para un archivo\nfile_handler = logging.FileHandler('logfile.log')\nfile_handler.setLevel(logging.DEBUG)\n\n# Creo un formato\nformatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')\nconsole_handler.setFormatter(formatter)\nfile_handler.setFormatter(formatter)\n\n# Añadir los handlers al Logger\nlogger.addHandler(console_handler)\nlogger.addHandler(file_handler)\nlogger.propagate = False\n\n# Ahora, los logs se enviarán tanto a la consola como al archivo\nlogger.debug(\"Mensaje de debug.\")\nlogger.info(\"Mensaje informativo.\")\n\n\n\n\"\"\"Configuracion de handler de fichero con rotación\"\"\"\n\nlogger1 = logging.getLogger(\"mi_logger_rotacion\")\nlogger1.setLevel(logging.DEBUG)\n\nfile_handler_rot = RotatingFileHandler('rotate_log.log', mode='a', maxBytes= 1000, backupCount= 3)\nfile_handler_rot.setLevel(logging.DEBUG)\nformatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')\nfile_handler_rot.setFormatter(formatter)\nlogger1.addHandler(file_handler_rot)\nlogger1.propagate = False # Evitas que el log se propague y llegue al raiz. Lo que imprime mensajes duplicados.\nlogger1.debug(\"Este es un mensaje de depuración (DEBUG).\") #Se imprimen los mensajes segun la configuración\nlogger1.info(\"Este es un mensaje informativo (INFO).\")\nlogger1.warning(\"Este es un mensaje de advertencia (WARNING).\")\nlogger1.error(\"Este es un mensaje de error (ERROR).\")\nlogger1.critical(\"Este es un mensaje crítico (CRITICAL).\")\n\n\n\n\"\"\"Configuracion de handler con jerarquia\"\"\"\n\n# ----------------------------\n# Configuración del logger raíz\n# ----------------------------\n\nlogger_principal = logging.getLogger('mi_aplicacion')\nlogger_principal.setLevel(logging.DEBUG)\n\n# Handler para consola\nconsole_handler = logging.StreamHandler()\nconsole_handler.setLevel(logging.DEBUG)\n\n# Formato\nformatter = logging.Formatter('%(name)s - %(levelname)s - %(message)s')\nconsole_handler.setFormatter(formatter)\n\n# Añadimos el handler al logger principal\nlogger_principal.addHandler(console_handler)\nlogger_principal.propagate = False\n\n# ----------------------------\n# Simulación de modulo1\n# ----------------------------\n\nlogger_modulo1 = logging.getLogger('mi_aplicacion.modulo1')\n\ndef ejecutar_modulo1():\n    logger_modulo1.debug(\"Debug desde módulo 1\")\n    logger_modulo1.info(\"Info desde módulo 1\")\n\n\n# ----------------------------\n# Simulación de modulo2\n# ----------------------------\n\nlogger_modulo2 = logging.getLogger('mi_aplicacion.modulo2')\n\ndef ejecutar_modulo2():\n    logger_modulo2.warning(\"Warning desde módulo 2\")\n    logger_modulo2.error(\"Error desde módulo 2\")\n\n# ----------------------------\n# Ejecutamos todo\n# ----------------------------\n\nejecutar_modulo1()\nejecutar_modulo2()\n\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa ficticio de gestión de tareas que permita añadir, eliminar\n * y listar dichas tareas.\n * - Añadir: recibe nombre y descripción.\n * - Eliminar: por nombre de la tarea.\n * Implementa diferentes mensajes de log que muestren información según la \n * tarea ejecutada (a tu elección).\n * Utiliza el log para visualizar el tiempo de ejecución de cada tarea. \n\"\"\"\n\nimport time\n\n#Creo un decorador para medir el tiempo de ejecucion de las tareas.\ndef measure_time(function):\n    def wrapper(*args, **kwargs):\n        start = time.perf_counter()\n        result = function(*args, **kwargs)\n        end = time.perf_counter()\n        logger.debug(f\"Tiempo de ejecucion de {function.__name__}: {end - start:.10f} segundos\")\n        return result\n    return wrapper\n\n\n\n#Configuramos el logger\ndef setup_logger():\n    logger = logging.getLogger(\"task_list\")\n    logger.setLevel(logging.DEBUG)\n\n    console_handler = logging.StreamHandler()\n    console_handler.setLevel(logging.INFO)\n\n    file_handler = logging.FileHandler(\"task_list_log.log\", \"w\")\n    file_handler.setLevel(logging.DEBUG)\n\n    formater = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')\n    console_handler.setFormatter(formater)\n    file_handler.setFormatter(formater)\n\n    logger.addHandler(console_handler)\n    logger.addHandler(file_handler)\n    logger.propagate = False\n    return logger\n\nlogger = setup_logger()\n\nclass TaskManager():\n\n    def __init__(self):\n        self.tasks = {}\n\n    @measure_time\n    def insert_task(self):\n        print(\"--Añadir tarea--\")\n        logger.debug(\"Opción Insert task\")\n        name = input(\"Introduce el nombre de la tarea: \").lower()\n        if not name in self.tasks:\n            description = input(\"Introduce la descripción: \")\n            self.tasks[name] = description\n            logger.info(f\"Se introdujo correctamente la tarea: {name}\")\n            logger.debug(f\"Número de tareas en la lista: {len(self.tasks)}\")\n        else:\n            logger.error(f\"La tarea {name} ya existe.\")\n\n    @measure_time\n    def delete_task(self):\n        print(\"--Eliminar tarea--\")\n        logger.debug(\"Opción Delete task\")\n        name = input(\"Introduce el nombre de la tareaa eliminar: \").lower()\n        if name in self.tasks:\n            del self.tasks[name]\n            logger.info(f\"Se borro la tarea {name} correctamente.\")\n            logger.debug(f\"Número de tareas en la lista: {len(self.tasks)}\")\n        else:\n            logger.error(f\"La tarea {name} no esta en la lista.\")\n\n    @measure_time\n    def list_tasks(self):\n        logger.debug(\"Opción List tasks\")\n        if self.tasks:\n            for name, task in self.tasks.items():\n                print(f\"{name}:{task}\")\n            logger.debug(f\"Número de tareas en la lista: {len(self.tasks)}\")\n        else:\n            logger.error(f\"La lista esta vacía.\")\n\n\nprint(\"Bienvenido a tu lista de tareas.\")\ntask_manager = TaskManager()\nwhile True:\n    print(\"Menu:\")\n    print(\"\\t1. Añadir tarea.\")\n    print(\"\\t2. Eliminar tarea.\")\n    print(\"\\t3. Listar tareas.\")\n    print(\"\\t4. Salir.\")\n    try:\n        option = int(input(\"Elige una opción: \"))\n\n        match option:\n            case 1:\n                task_manager.insert_task()\n            case 2:\n                task_manager.delete_task()\n            case 3:\n                task_manager.list_tasks()\n            case 4:\n                print(\"Adios\")\n                logger.debug(\"Se cerro la aplicación.\")\n                break\n    except ValueError as e:\n        logger.error(f\"Has introducido una opcion invalida: {option}. Vuelve a intentarlo.\")\n        logger.debug(f\"El usuario introdujo una opción invalida: {type(e)} - {e}\")\n        continue\n\n    except Exception as e:\n        logger.critical(f\"Error critico: {type(e)} - {e}\")\n        \n"
  },
  {
    "path": "Roadmap/25 - LOGS/python/isilanes.py",
    "content": "import logging\nimport os\nimport re\nfrom datetime import datetime\n\nLOGFILE = \"isilanes.log\"\n\n\ndef get_logger(name: str) -> logging.Logger:\n    logger = logging.getLogger(name)\n\n    # Fijamos el nivel mínimo de logs a DEBUG:\n    logger.setLevel(logging.DEBUG)\n\n    # Console handler (salida a pantalla):\n    handler = logging.StreamHandler()\n    handler.setLevel(logging.DEBUG)\n\n    # Formateador para consola:\n    formatter = logging.Formatter('%(asctime)s - %(levelname)s: %(message)s')\n    handler.setFormatter(formatter)\n\n    # Añadir el console handler al logger:\n    logger.addHandler(handler)\n\n    # File handler (salida a fichero):\n    handler = logging.FileHandler(filename=LOGFILE)\n    handler.setLevel(logging.WARNING)\n\n    # Formateador para fichero:\n    formatter = logging.Formatter('%(asctime)s:%(name)s:%(levelname)s:%(message)s')\n    handler.setFormatter(formatter)\n\n    # Añadir el console handler al logger:\n    logger.addHandler(handler)\n\n    return logger\n\n\ndef get_logger_extra(filename: str) -> logging.Logger:\n    logger = logging.getLogger(\"TaskManager\")\n\n    logger.setLevel(logging.DEBUG)\n    handler = logging.FileHandler(filename=filename)\n    formatter = logging.Formatter('%(asctime)s|%(name)s|%(levelname)s|%(message)s')\n    handler.setFormatter(formatter)\n    logger.addHandler(handler)\n\n    return logger\n\n\nlog = get_logger(__name__)\n\n\nclass TaskManager:\n    log_filename = \"task_manager.log\"\n    log = get_logger_extra(log_filename)\n\n    def __init__(self):\n        self.tasks = {}\n\n    def contains(self, name: str) -> bool:\n        return name in self.tasks\n\n    def add(self, name: str, description: str) -> None:\n        if self.contains(name):\n            self.log.warning(\n                \"Pasamos de añadir la tarea '%s', porque ya existe en TaskManager.\",\n                name,\n            )\n            return\n\n        self.tasks[name] = description\n        self.log.info(\"La tarea '%s' fue añadida al TaskManager\", name)\n\n    def remove(self, name: str) -> None:\n        if not self.contains(name):\n            self.log.warning(\"No podemos eliminar la tarea '%s', puesto que no existe.\", name)\n            return\n\n        del self.tasks[name]\n        self.log.info(\"La tarea '%s' fue eliminada del TaskManager\", name)\n\n    def list(self) -> None:\n        print(\"Lista de tareas pendientes:\")\n        for i, (task, desc) in enumerate(self.tasks.items()):\n            print(f\" {i+1:2d} - {task}: {desc}\")\n\n    def summary(self) -> None:\n        \"\"\"\n        Nótese que parsear el log de esta manera es frágil, y podría ser buena\n        idea usar algún tipo de log estructurado.\n        \"\"\"\n        tasks = {}\n        if not os.path.exists(self.log_filename):\n            self.log.info(\"No hay log disponible.\")\n            return\n\n        with open(self.log_filename, \"r\", encoding=\"utf-8\") as f:\n            for line in f:\n                fields = line.split(\"|\")\n                if len(fields) != 4:\n                    continue\n\n                ts = fields[0]\n                try:\n                    t = datetime.strptime(ts, \"%Y-%m-%d %H:%M:%S,%f\")\n                except ValueError:\n                    continue\n\n                msg = fields[-1]\n                patt = re.compile(r\"'(?P<task>\\w+)'\")\n                match = patt.search(msg)\n\n                if not match:\n                    continue\n\n                task = match.group(\"task\")\n\n                if task not in tasks:\n                    tasks[task] = {\"start\": None, \"end\": None}\n\n                if \"fue añadida\" in line:\n                    tasks[task][\"start\"] = t\n                elif \"fue eliminada\" in line:\n                    tasks[task][\"end\"] = t\n                else:\n                    continue\n\n        now = datetime.now()\n        for i, (task, data) in enumerate(tasks.items()):\n            start: datetime = data.get(\"start\")\n            if not start:\n                continue\n\n            end = data.get(\"end\")\n            if end:\n                dt_ms = (end - start).total_seconds() * 1000  # noqa\n                print(f\" {i:2d} - {task}: ha durado {dt_ms:.2f} ms.\")\n            else:\n                dt_ms = (now - start).total_seconds() * 1000  # noqa\n                print(f\" {i:2d} - {task}: aún no ha terminado. Lleva {dt_ms:.2f} ms desde que se añadió.\")\n\n\ndef main():\n    print(\"===== MAIN =====\")\n    who = \"Iñaki\"\n    log.debug(\n        \"Hemos configurado el logger para usar loguear por pantalla todo, y por fichero todo\"\n        \" lo que sea WARNING o más grave.\"\n    )\n    log.debug(\n        \"Mencionar que los formatos del mensaje en fichero y por pantalla pueden configurarse\"\n        \" por separado (y lo hemos hecho).\"\n    )\n    log.debug(\"%s, un mensaje de nivel DEBUG sólo saldrá por pantalla\", who)\n    log.info(\"%s, un mensaje de nivel INFO sólo saldrá por pantalla\", who)\n    log.warning(\n        \"%s, un mensaje de nivel WARNING saldrá por pantalla y también irá a fichero (%s)\",\n        who,\n        LOGFILE,\n    )\n    log.error(\n        \"%s, un mensaje de nivel ERORR saldrá por pantalla y también irá a fichero (%s)\",\n        who,\n        LOGFILE,\n    )\n    log.critical(\n        \"%s, un mensaje de nivel ERROR saldrá por pantalla y también irá a fichero (%s)\",\n        who,\n        LOGFILE,\n    )\n\n\ndef extra():\n    print(\"\\n===== EXTRA =====\")\n    print(\"Inicializamos el gestor de tareas:\")\n    print('>>> tm = TaskManager()')\n    tm = TaskManager()\n\n    print(\"\\nAñadimos tareas:\")\n    print('>>> tm.add(name=\"fregar\", description=\"Fregar los platos\")')\n    print('>>> tm.add(name=\"leer\", description=\"Dedicar un rato a leer un libro\")')\n    tm.add(name=\"fregar\", description=\"Fregar los platos\")\n    tm.add(name=\"leer\", description=\"Dedicar un rato a leer un libro\")\n\n    print(\"\\nHemos configurado TaskManager para que esas acciones sólo guarden log a fichero.\")\n    print(\"Podemos listar las tareas activas (esto no guarda log, y sólo imprime por pantalla):\")\n    print('>>> tm.list()')\n    tm.list()\n\n    print(\"\\nSi intentamos añadir una tarea repetida, será ignorada (y un aviso añadido al log):\")\n    print('>>> tm.add(name=\"fregar\", description=\"Quiero fregar más\")')\n    tm.add(name=\"fregar\", description=\"Quiero fregar más\")\n    print('>>> tm.list()')\n    tm.list()\n\n    print(\"\\nPodemos eliminar una tarea:\")\n    print('>>> tm.remove(name=\"fregar\")')\n    tm.remove(name=\"fregar\")\n    print('>>> tm.list()')\n    tm.list()\n\n    print(\"\\nIntentar eliminar una tarea no existente no hará nada (y guardará aviso en log):\")\n    print('>>> tm.remove(name=\"bailar\")')\n    tm.remove(name=\"bailar\")\n    print('>>> tm.list()')\n    tm.list()\n\n    print(\"\\nImprimimos un resumen de las tareas añadidas:\")\n    print('>>> tm.summary()')\n    tm.summary()\n\n\nif __name__ == \"__main__\":\n    main()\n    extra()\n"
  },
  {
    "path": "Roadmap/25 - LOGS/python/juanmax2.py",
    "content": "import logging\nimport time\n\"\"\"\nEjercicio\n\"\"\"\n\nlogging.basicConfig(level=logging.DEBUG, \n                    format=\"%(asctime)s - %(levelname)s - %(message)s\",\n                    handlers=[logging.StreamHandler()]\n                    )\n\nlogging.debug(\"Esto es un mensaje de DEBUG\")\nlogging.info(\"Esto es un mensaje de INFO\")\nlogging.warning(\"Esto es un mensaje de WARNING\")\nlogging.error(\"Esto es un mensaje de ERROR\")\nlogging.critical(\"Esto es un mensaje de CRITICAL\")\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa ficticio de gestión de tareas que permita añadir, eliminar\n * y listar dichas tareas.\n * - Añadir: recibe nombre y descripción.\n * - Eliminar: por nombre de la tarea.\n * Implementa diferentes mensajes de log que muestren información según la \n * tarea ejecutada (a tu elección).\n * Utiliza el log para visualizar el tiempo de ejecución de cada tarea. \n */\n\"\"\"\n\n    \nclass TaskManager:\n    \n    def __init__(self) -> None:\n        self.tasks = {}\n    \n    def add_task(self, name: str, description: str):\n        star_time = time.time()\n        if name not in self.tasks:\n           self.tasks[name] = description\n           logging.info(f\"Tarea añadida: {name}\") \n        else:\n            logging.warning(f\"Se ha intentado añadir una tarea existente {name}\")\n        end_time = time.time()\n        print(end_time - star_time)\n    def delete_task(self, name: str):\n        star_time = time.time()\n        if name in self.tasks:\n            del self.tasks[name]\n            logging.info(f\"Tarea eliminada: {name}\")\n        else:\n            logging.error(f\"Se ha intentando eliminar una tarea que no existe: {name}\")\n        end_time = time.time() \n        print(end_time - star_time) \n    def list_task(self):\n        star_time = time.time()\n        if self.tasks:\n            logging.info(f\"Se va a imprimir la lista de tareas\")\n            for name, description in self.tasks.items():\n                print(f\"{name} - {description}\")\n        else:\n            logging.error(\"Lista de tareas inexistente\")\n        end_time = time.time()  \n        print(end_time - star_time)\n         \ntask_manager = TaskManager()\ntask_manager.list_task()\ntask_manager.add_task(\"Pan\", \"Comprar 5 barras de pan\")\ntask_manager.add_task(\"Python\", \"Estudiar python\")\ntask_manager.add_task(\"Python\", \"Estudiar python\")\ntask_manager.list_task()\ntask_manager.delete_task(\"Python\")\ntask_manager.list_task()"
  },
  {
    "path": "Roadmap/25 - LOGS/python/juanppdev.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el concepto de \"logging\" en tu lenguaje. Configúralo y muestra\n * un ejemplo con cada nivel de \"severidad\" disponible.\n\"\"\"\n\n# El concepto de “logging” en Python es muy útil para rastrear eventos que ocurren mientras se ejecuta un programa.\n#  Python tiene un módulo incorporado llamado logging que permite registrar mensajes con diferentes niveles de severidad.\n\nimport logging\n\n# Configuración básica del logging\nlogging.basicConfig(level=logging.DEBUG,\n                    format='%(asctime)s - %(levelname)s - %(message)s')\n\n# Ejemplos de mensajes con diferentes niveles de severidad\nlogging.debug('Este es un mensaje de depuración (debug)')\nlogging.info('Este es un mensaje informativo (info)')\nlogging.warning('Este es un mensaje de advertencia (warning)')\nlogging.error('Este es un mensaje de error (error)')\nlogging.critical('Este es un mensaje crítico (critical)')\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa ficticio de gestión de tareas que permita añadir, eliminar\n * y listar dichas tareas.\n * - Añadir: recibe nombre y descripción.\n * - Eliminar: por nombre de la tarea.\n * Implementa diferentes mensajes de log que muestren información según la \n * tarea ejecutada (a tu elección).\n * Utiliza el log para visualizar el tiempo de ejecución de cada tarea. \n\"\"\"\n\nimport logging\nimport time\n\n# Configuración básica del logging\nlogging.basicConfig(level=logging.DEBUG,\n                    format='%(asctime)s - %(levelname)s - %(message)s')\n\n# Lista para almacenar las tareas\ntareas = []\n\ndef añadir_tarea(nombre, descripcion):\n    inicio = time.time()\n    tareas.append({'nombre': nombre, 'descripcion': descripcion})\n    logging.info(f'Tarea añadida: {nombre}')\n    fin = time.time()\n    logging.debug(f'Tiempo de ejecución de añadir_tarea: {fin - inicio:.4f} segundos')\n\ndef eliminar_tarea(nombre):\n    inicio = time.time()\n    global tareas\n    tareas = [tarea for tarea in tareas if tarea['nombre'] != nombre]\n    logging.info(f'Tarea eliminada: {nombre}')\n    fin = time.time()\n    logging.debug(f'Tiempo de ejecución de eliminar_tarea: {fin - inicio:.4f} segundos')\n\ndef listar_tareas():\n    inicio = time.time()\n    if not tareas:\n        logging.warning('No hay tareas para listar')\n    else:\n        for tarea in tareas:\n            logging.info(f\"Tarea: {tarea['nombre']}, Descripción: {tarea['descripcion']}\")\n    fin = time.time()\n    logging.debug(f'Tiempo de ejecución de listar_tareas: {fin - inicio:.4f} segundos')\n\n# Ejemplo de uso\nañadir_tarea('Comprar pan', 'Comprar pan en la panadería')\nañadir_tarea('Estudiar Python', 'Completar el ejercicio de logging')\nlistar_tareas()\neliminar_tarea('Comprar pan')\nlistar_tareas()\n"
  },
  {
    "path": "Roadmap/25 - LOGS/python/kenysdev.py",
    "content": "# ╔═════════════════════════════════════╗\n# ║ Autor:  Kenys Alvarado              ║\n# ║ GitHub: https://github.com/Kenysdev ║\n# ║ 2024 -  Python                      ║\n# ╚═════════════════════════════════════╝\n\n# -----------------------------------\n# * LOGS\n# -----------------------------------\n# Mas info: https://medium.com/@sachinsoni600517/logging-in-python-a-step-by-step-tutorial-086a617f4eaa\n\nimport logging\nimport time\n\n\"\"\"\n * EJERCICIO #1:\n * Explora el concepto de \"logging\" en tu lenguaje. Configúralo y muestra\n * un ejemplo con cada nivel de \"severidad\" disponible.\n\"\"\"\n\n# Para registrar mensajes en diferentes niveles.\nlogging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')\n\n# 1. DEBUG\nlogging.debug('depuración')\n    \n# 2. INFORMACIÓN:\nlogging.info('informativo')\n\n# 3. ADVERTENCIA:\nlogging.warning('Ddvertencia')\n\n# 4. ERRORES:\nlogging.error('Error')\nlogging.critical('Error crítico')\n\n\"\"\"\n * EJERCICIO #2:\n* Crea un programa ficticio de gestión de tareas que permita añadir, eliminar\n* y listar dichas tareas.\n* - Añadir: recibe nombre y descripción.\n* - Eliminar: por nombre de la tarea.\n* Implementa diferentes mensajes de log que muestren información según la \n* tarea ejecutada (a tu elección).\n* Utiliza el log para visualizar el tiempo de ejecución de cada tarea. \n\"\"\"\n\nclass Program():\n    def __init__(self):\n        self.tasks: dict = {}\n        logging.debug('Se inició instancia de la clase.')\n    \n    def _show_time(func: object):\n        def wraper(*args):\n            start_time: float = time.time()\n            func(*args)\n            end_time: float = time.time()\n            logging.debug(f\"Tiempo de ejecución: {(end_time - start_time):.21f} segundos.\")\n\n        return wraper\n\n    @_show_time\n    def add(self, name: str, description: str):\n        self.tasks[name] = description\n        logging.info('Se agregó una tarea.')\n\n    @_show_time\n    def delete(self, name: str):\n        if name in self.tasks:\n            del self.tasks[name]\n            logging.info(f\"Tarea '{name}' eliminada.\")\n        else:\n            print()\n            logging.warning(f\"No se encontró la tarea '{name}'.\")\n\n    @_show_time\n    def show_list(self):\n        logging.info('Lista de tareas')\n        for task, des in self.tasks.items():\n            print(f\"{task} -- {des}\")\n        \nprint(\"\\nEJERCICIO #2\")\n\ntasks = Program()\n\ntasks.add(\"a\", \".1\")\ntasks.add(\"b\", \"2\")\ntasks.add(\"c\", \"3\")\n\ntasks.delete(\"a\")\ntasks.show_list()\n\ntasks.delete(\"a\")\n\n"
  },
  {
    "path": "Roadmap/25 - LOGS/python/mhayhem.py",
    "content": "#@Author Daniel Grande (Mhayhem)\n\n# EJERCICIO:\n# Explora el concepto de \"logging\" en tu lenguaje. Configúralo y muestra\n# un ejemplo con cada nivel de \"severidad\" disponible.\n\nimport logging\n\nlogging.basicConfig(level=logging.DEBUG)\n\nlogging.debug(\"Esto es un mensaje de debuging.\")\nlogging.info(\"Esto es un mensaje de información.\")\nlogging.warning(\"Esto es un mensaje de advertencía.\")\nlogging.error(\"Esto es un mensaje de error.\")\nlogging.fatal(\"Esto es un mensaje crítico.\")\n\n\n# DIFICULTAD EXTRA (opcional):\n# Crea un programa ficticio de gestión de tareas que permita añadir, eliminar\n# y listar dichas tareas.\n# - Añadir: recibe nombre y descripción.\n# - Eliminar: por nombre de la tarea.\n# Implementa diferentes mensajes de log que muestren información según la \n# tarea ejecutada (a tu elección).\n# Utiliza el log para visualizar el tiempo de ejecución de cada tarea. \n\nimport logging\nfrom time import time \nfrom functools import wraps\n\nclass Task:\n    def __init__(self, name: str, description: str):\n        self.name = name\n        self.description = description\n\ndef calculate_time(func):\n    @wraps(func)\n    def timer(*args, **kwargs):\n        star = time()\n        result = func(*args, **kwargs)\n        end = time()\n        total_time = end - star\n        logging.info(f\"La función {func.__name__} se ejecuto en {total_time:.2f} s\") \n        return result\n    return timer\n\ntasks = []\n\n@calculate_time\ndef created_task(array: list) -> list:\n    logging.info(\"inicializando Creador de tareas.\")\n    print(\"Tarea a crear.\")\n    name = input(\"Nombre:\\n\")\n    description = input(\"Descripción:\\n\")\n    if not name or not description:\n        logging.warning(\"No se puede crear tareas sin nombre o sin descripción.\")\n    else:\n        task = Task(name, description)\n        array.append(task)\n    return array\n\n@calculate_time\ndef delete_task(array: list) -> list:\n    logging.info(\"inicializando Eliminacion de tareas\")\n    del_task = input(\"Tarea a eliminar:\\n\")\n\n    if del_task in tasks:\n        logging.info(f\"Tarea {del_task} sera eliminada.\")\n        array.pop(del_task)\n    else:\n        logging.error(f\"La tarea: {del_task} no se encuentra. Cancelando eliminación.\")\n    return array\n\n@calculate_time\ndef display_tasks(array) -> list:\n    logging.info(\"Inicializando Listar tareas.\")\n    if not array:\n        logging.error(\"No existen tareas\")\n    else:\n        for i, task in enumerate(array):\n            print(f\"{i+ 1}: {task.name}\")\n        print(f\"Listadas {len(array)}\")\n        \n    return array\n\ndef task_manager(array):\n    print(\"TASK MANAGER V 1.01\")\n    print(\"=\" * 40)\n    try:\n        while True:\n            print(\"1. Crear tarea.\\n\"\n                \"2. Eliminar tarea.\\n\"\n                \"3. Listar tareas.\\n\"\n                \"4. Salir.\")\n            option = int(input())\n            match option:\n                case 1:\n                    created_task(array)\n                    print(\"\\n\")\n                case 2:\n                    delete_task(array)\n                    print(\"\\n\")\n                case 3:\n                    display_tasks(array)\n                    print(\"\\n\")\n                case 4:\n                    logging.info(\"Saliendo del Task Manager\")\n                    break\n                case _:\n                    logging.warning(\"Opción inválida.\\n\")\n    except ValueError as e:\n        logging.critical(f\"ERROR: {e}; Solo se aceptan números. Cerrando programa.\")\n    except KeyboardInterrupt as e:\n        logging.critical(f\"ERROR: {e}; El usuario interrumpió la ejecución. Cerrando programa.\")\n\nif __name__ == \"__main__\":\n    task_manager(tasks)"
  },
  {
    "path": "Roadmap/25 - LOGS/python/mouredev.py",
    "content": "import logging\nimport time\n\n\"\"\"\nEjercicio\n\"\"\"\n\nlogging.basicConfig(level=logging.DEBUG,\n                    format=\"%(asctime)s - %(levelname)s - %(message)s\",\n                    handlers=[logging.StreamHandler()])\n\nlogging.debug(\"Esto es un mensaje de DEBUG\")\nlogging.info(\"Esto es un mensaje de INFO\")\nlogging.warning(\"Esto es un mensaje de WARNING\")\nlogging.error(\"Esto es un mensaje de ERROR\")\nlogging.critical(\"Esto es un mensaje de CRITICAL\")\n\n\"\"\"\nExtra\n\"\"\"\n\n\nclass TaskManager:\n\n    def __init__(self) -> None:\n        self.tasks = {}\n\n    def add_task(self, name: str, description: str):\n        start_time = time.time()\n        if name not in self.tasks:\n            self.tasks[name] = description\n            logging.info(f\"Tarea añadida: {name}.\")\n        else:\n            logging.warning(\n                f\"Se ha intentado añadir una tarea que ya existe: {name}.\")\n        logging.debug(f\"Número de tareas: {len(self.tasks)}\")\n        end_time = time.time()\n        self._print_time(start_time, end_time)\n\n    def delete_task(self, name: str):\n        start_time = time.time()\n        if name in self.tasks:\n            del self.tasks[name]\n            logging.info(f\"Se ha eliminado la tarea: {name}.\")\n        else:\n            logging.error(\n                f\"Se ha intentado eliminar una tarea que no existe: {name}.\")\n        logging.debug(f\"Número de tareas: {len(self.tasks)}\")\n        end_time = time.time()\n        self._print_time(start_time, end_time)\n\n    def list_tasks(self):\n        start_time = time.time()\n        if self.tasks:\n            logging.info(f\"Se va a imprimir la lista de tareas.\")\n            for name, description in self.tasks.items():\n                print(f\"{name} - {description}\")\n        else:\n            logging.info(\"No hay tareas para mostrar.\")\n        end_time = time.time()\n        self._print_time(start_time, end_time)\n\n    def _print_time(self, start_time, end_time):\n        logging.debug(\n            f\"Tiempo de ejecución: {end_time - start_time:.6f} segundos.\")\n\n\ntask_manager = TaskManager()\ntask_manager.list_tasks()\ntask_manager.add_task(\"Pan\", \"Comprar 5 barras de pan\")\ntask_manager.add_task(\"Python\", \"Estudiar Python\")\ntask_manager.list_tasks()\ntask_manager.delete_task(\"Python\")\ntask_manager.list_tasks()\ntask_manager.add_task(\"Pan\", \"Comprar 5 barras de pan\")\ntask_manager.delete_task(\"Python\")\n"
  },
  {
    "path": "Roadmap/25 - LOGS/python/mrodara.py",
    "content": "### LOGS EN PYTHON\n\n'''\nEl módulo logging en Python proporciona una forma flexible y potente de registrar mensajes en tus aplicaciones. \nEs especialmente útil para depurar, monitorear y registrar eventos importantes en aplicaciones pequeñas o grandes.\n'''\n\n# Permite monitorear eventos para niveles de registro, salidas de registro y formato.\nimport logging\n\n# Configuración básica de logging con basicConfig\nlogging.basicConfig(level=logging.DEBUG)\n\n# Mostramos ejemplos de todos los niveles\nlogging.debug('Este mensaje es de nivel DEBUG')\nlogging.info('Este mensaje es de nivel INFO')\nlogging.warning('Este mensaje es de nivel WARNING')\nlogging.error('Este mensaje es de nivel ERROR')\nlogging.critical('Este mensaje es de nivel CRITICAL')\n\n# Podemos darle formato a los mensajes de log, por ejemplo para indicar fechas del mensaje\nlogging.basicConfig(\n    level=logging.INFO,\n    format=\"%(asctime)s - %(levelname)s - %(message)s\",\n    datefmt=\"%d-%m-%Y %H:%M:%S\"\n)\n\nlogging.info('Este mensaje es de nivel INFO')\nlogging.warning('Este mensaje es de nivel WARNING')\nlogging.error('Este mensaje es de nivel ERROR')\n\n\n### EJERCICIO EXTRA\nclass Tareas():\n    \n    def __init__(self):\n        self.tasks = []\n        \n    def list_tasks(self):\n        \n        if len(self.tasks) > 0:\n            logging.info(\"Solictud listar tareas\")\n            print(list(self.tasks))\n            logging.info(\"Fin Solictud listar tareas\")\n        else:\n            logging.warning(\"Solicitud listar tareas\")\n            print(\"No hay tareas para mostrar\")\n            logging.warning(\"Fin Solicitud listar tareas\")\n\n    def add_task(self, name: str, description: str):\n        logging.info(\"Solicitud agregar tarea\")\n        self.tasks.append({\"name\": name, \"description\": description})\n        print(f\"Tarea agregada: {name} - {description}\")\n        logging.info(\"Fin Solicitud agregar tarea\")\n        \n    def delete_task(self, name: str):\n        \n        logging.warning(\"Inicio solicitud eliminar tarea\")\n        \n        for task in self.tasks:\n                      \n            if task['name'].lower() == name.lower():\n                    self.tasks.remove(task)\n                    print(f\"Tarea eliminada: {name}\")\n                    break\n                        \n        logging.warning(\"Fin solicitud eliminar tarea\")\n\n\nmy_tasks = Tareas()\n\nmy_tasks.list_tasks()\nmy_tasks.add_task(\"Tarea 1\", \"Actualizar gestor de dependencias\")\nmy_tasks.add_task(\"Tarea 2\", \"Instalar paquetes necesarios\")\nmy_tasks.list_tasks()\nmy_tasks.delete_task(\"Tarea 2\")\n### FIN EJERCICIO EXTRA\n\n### FIN LOGS EN PYTHON\n\n"
  },
  {
    "path": "Roadmap/25 - LOGS/python/neslarra.py",
    "content": "\"\"\"\n EJERCICIO:\n Explora el concepto de \"logging\" en tu lenguaje. Configúralo y muestra\n un ejemplo con cada nivel de \"severidad\" disponible.\n\n DIFICULTAD EXTRA (opcional):\n Crea un programa ficticio de gestión de tareas que permita añadir, eliminar\n y listar dichas tareas.\n - Añadir: recibe nombre y descripción.\n - Eliminar: por nombre de la tarea.\n Implementa diferentes mensajes de log que muestren información según la\n tarea ejecutada (a tu elección).\n Utiliza el log para visualizar el tiempo de ejecución de cada tarea.\n\"\"\"\nimport logging\nfrom os import remove\nfrom time import sleep\n\nprint(f\"{'#' * 47}\")\nprint(f\"##  Explicación  {'#' * 30}\")\nprint(f\"{'#' * 47}\")\n\nprint(r\"\"\"\nhttps://docs.python.org/es/3/howto/logging.html  <= en este link se haya una muy buena explicación de qué es y cuándo se usa \"logging\".\n\n-----------------------------------------------------------------------------------------------------------------------------\n\nEjemplo de logging \"sencillo\":\n\n    logger = logging.getLogger(\"reto_25_neslarra\")\n    logging.basicConfig(filename=logger.name + '.log', encoding='utf-8', filemode='a',\n                        format='%(asctime)s - %(levelname)s: %(message)s', level=logging.DEBUG,\n                        datefmt='%Y-%b-%d %H:%M:%S')\n    \n    logger.debug('This message should go to the log file')\n    logger.info('So should this') \n    logger.warning('And this, too')\n    logger.error('And non-ASCII stuff, too, like Øresund and Malmö')\n    logger.critical('Oopsie doopsie!!!')\n\n-----------------------------------------------------------------------------------------------------------------------------\n\nEjemplo de logging desviando, formateando y filtrando eventos:\n\n    def filter_console(reg):\n        if reg.levelname in (\"INFO\", \"DEBUG\"):\n            return True\n        return False\n    \n    \n    def filter_logfile(reg):\n        if reg.levelname in (\"WARNING\", \"ERROR\", \"CRITICAL\"):\n            return True\n        return False\n    \n    \n    log_format = logging.Formatter('%(asctime)s - %(levelname)s %(funcName)s (%(lineno)d) %(message)s', datefmt='%Y-%b-%d %H:%M:%S')\n    logFile = 'reto_25_neslarra.log'\n    \n    file_handler = logging.FileHandler(logFile, encoding='utf-8')\n    file_handler.setFormatter(log_format)\n    file_handler.setLevel(logging.WARNING)\n    # file_handler.addFilter(filter_logfile)     # NO hace falta filtrar pque el level ya sólo toma WARNING, ERROR y CRITICAL <= SOLO EJEMPLO\n    \n    stream_handler = logging.StreamHandler()\n    stream_handler.setFormatter(log_format)\n    stream_handler.setLevel(logging.DEBUG)\n    stream_handler.addFilter(filter_console)\n    \n    logger = logging.getLogger('root')\n    logger.setLevel(logging.DEBUG)\n    \n    logger.addHandler(file_handler)\n    logger.addHandler(stream_handler)\n    \n    logger.debug('Se muestra SÓLO por consola')\n    logger.info('Se muestra SÓLO por consola')\n    logger.warning('Se muestra SÓLO por  fichero de log')\n    logger.error('Se muestra SÓLO por  fichero de log')\n    logger.critical('Se muestra SÓLO por  fichero de log')\n    \n    _ = input(\"Revisar el fichero de log => apretar cualquier tecla para borarrlo y salir.\")\n    logging.shutdown()\n    remove(logFile)\n\"\"\")\n\nprint(f\"{'#' * 52}\")\nprint(f\"##  Dificultad Extra  {'#' * 30}\")\nprint(f\"{'#' * 52}\\n\")\n\n\nclass Task:\n\n    logger = logging.getLogger(\"root\")\n    log_file = \"reto_25_\" + logger.name + '.log'\n    logging.basicConfig(filename=log_file, encoding='utf-8', filemode='a',\n                        format='%(asctime)s - %(levelname)s: %(message)s', level=logging.DEBUG,\n                        datefmt='%Y-%b-%d %H:%M:%S')\n\n    def __init__(self, taskname: str):\n        self.taskname = taskname\n        Task.log_task(self.taskname)\n\n    @classmethod\n    def log_task(cls, taskname):\n        cls.logger.info(taskname)\n\n    @classmethod\n    def log_shutdown(cls):\n        logging.shutdown()\n        remove(cls.log_file)\n\n\ntask1 = Task(\"Salir de la cama\")\nsleep(1)\ntask2 = Task(\"Ventilar\")\nsleep(1)\ntask3 = Task(\"Ordenar la habitación\")\nsleep(1)\ntask4 = Task(\"Bañarme\")\nsleep(1)\ntask5 = Task(\"Vestirme\")\nsleep(1)\ntask6 = Task(\"Desayunar\")\nsleep(1)\ntask7 = Task(\"Ponerme a trabajar\")\n\n_ = input(\"Revisar el fichero de log => apretar cualquier tecla para borarrlo y salir.\")\nTask.log_shutdown()\n"
  },
  {
    "path": "Roadmap/25 - LOGS/python/oriaj3.py",
    "content": "\"\"\" \n25 - LOGS\nAutor de la solución: Oriaj3\n\nTeoría:\nLos logs son mensajes que se utilizan para registrar información sobre la ejecución de un programa.\nLos logs son útiles para depurar errores, monitorizar el comportamiento de una aplicación y registrar\nla actividad del sistema.\n\nEn Python, se puede utilizar el módulo \"logging\" para añadir logs a un programa. El módulo \"logging\"\nproporciona una interfaz flexible y fácil de usar para registrar mensajes de log en diferentes niveles\nde severidad.\n\nLos niveles de severidad de los logs son:\n- DEBUG: Mensajes detallados para depurar problemas.\n- INFO: Mensajes informativos sobre la ejecución del programa.\n- WARNING: Mensajes de advertencia sobre posibles problemas.\n- ERROR: Mensajes de error que indican un problema en la ejecución del programa.\n- CRITICAL: Mensajes críticos que indican un fallo grave en el programa.\n\nEjemplo:\nimport logging\n\n# Configurar el logger\nlogging.basicConfig(level=logging.DEBUG)\n\n# Registrar mensajes de log\nlogging.debug(\"Este es un mensaje de debug\")\nlogging.info(\"Este es un mensaje informativo\")\nlogging.warning(\"Este es un mensaje de advertencia\")\nlogging.error(\"Este es un mensaje de error\")\nlogging.critical(\"Este es un mensaje crítico\")\n\"\"\"\n\n\"\"\"\n/*\n * EJERCICIO:\n * Explora el concepto de \"logging\" en tu lenguaje. Configúralo y muestra\n * un ejemplo con cada nivel de \"severidad\" disponible.\n\"\"\"\nimport logging\n\n#Añadir tiempo a los mensajes\nlogging.basicConfig(format='%(asctime)s [%(levelname)s]  %(message)s', datefmt='%d-%b-%y %H:%M:%S', level=logging.DEBUG, handlers = [logging.StreamHandler()])\n\nlogging.debug(\"Este es un mensaje de debug\")\nlogging.info(\"Este es un mensaje informativo\")\nlogging.warning(\"Este es un mensaje de advertencia\")\nlogging.error(\"Este es un mensaje de error\")\nlogging.critical(\"Este es un mensaje crítico\")\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa ficticio de gestión de tareas que permita añadir, eliminar\n * y listar dichas tareas.\n * - Añadir: recibe nombre y descripción.\n * - Eliminar: por nombre de la tarea.\n * Implementa diferentes mensajes de log que muestren información según la \n * tarea ejecutada (a tu elección).\n * Utiliza el log para visualizar el tiempo de ejecución de cada tarea. \n */\n\"\"\"\n\n\n\nclass gestor_tareas:\n    tareas = []\n    \n    def anadir(self, nombre, descripcion):\n        self.tareas.append([nombre, descripcion])\n        logging.info(f\"Se ha añadido la tarea: {nombre}\")\n        \n    def eliminar(self, nombre):\n        encontrado = False\n        for tarea in self.tareas:\n            if tarea[0] == nombre:\n                self.tareas.remove(tarea)\n                logging.info(f\"Se ha eliminado la tarea: {nombre}\")    \n                encontrado = True\n                break\n        if not encontrado:\n            logging.warning(f\"No se ha encontrado la tarea: {nombre}\")\n            \n                \n    def listar(self):\n        if len(self.tareas) == 0:\n            logging.warning(\"No hay tareas para mostrar\")\n            return\n        for tarea in self.tareas:\n            print(f\"Nombre: {tarea[0]} - Descripción: {tarea[1]}\")\n    \n\n# Crear un gestor de tareas\ngestor = gestor_tareas()\ngestor.listar()\n\ngestor.anadir(\"Tarea1\", \"Descripción de la tarea 1\")\ngestor.anadir(\"Tarea2\", \"Descripción de la tarea 2\")\ngestor.listar()\n\ngestor.eliminar(\"Tarea1\")\ngestor.eliminar(\"Tarea3\")\n"
  },
  {
    "path": "Roadmap/25 - LOGS/python/pyramsd.py",
    "content": "import logging\n\n# Configurar logger\nlogging.basicConfig(level=logging.DEBUG,\n                    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',\n                    datefmt='%Y-%m-%d %H:%M:%S')\n\n# Crear logger\nlogger = logging.getLogger(__name__)\n\n# Mensajes de logs\nlogger.debug('Mensaje de depuración')\nlogger.info('Mensaje de información')\nlogger.warning('Mensaje de advertencia')\nlogger.error('Mensaje de error')\nlogger.critical('Mensaje crítico')\n\n'''\nEXTRA\n'''\nimport random\n\nclass TaskManager:\n    def __init__(self) -> None:\n        self.tasks={}\n        logger.info('Gestor de tareas iniciado')\n\n    def add_task(self):\n        name = input('Nombre de la tarea a agregar: ')\n        description = input('Descripción de la tarea: ')\n        if name in self.tasks:\n            logger.warning(f'Tarea ya existente: {name}')\n            return\n        exec_time = random.randint(1, 5)\n        self.tasks[name] = {\n            'description': description,\n            'exec_time': exec_time\n        }\n        logger.info(f'Tarea{name} añadida')\n        logger.debug(f'tiempo de ejecución de la tarea {name}: {exec_time} segundos')\n    \n    def delete_task(self):\n        name = input('Ingrese tarea a eliminar: ')\n        if name not in self.tasks:\n            logger.warning(f'Tarea inexistente: {name}')\n            return\n        del self.tasks[name]\n        logger.info(f'Tarea {name} eliminada')\n\n    def get_task(self):\n        name = input('Buscar tarea: ')\n        if name not in self.tasks:\n            logger.warning(f'Tarea inexistente: {name}')\n            return\n        task = self.tasks[name]\n        print(f\"Tarea: {name}\\n\\tDescripción: {task['description']}\\n\\tTiempo de ejecución: {task['exec_time']} segundos\")\n        logger.info(f'Información de la tarea {name} proporcionada')\n        \n    \n    def list_tasks(self):\n        if not self.tasks:\n            logger.info('No se encontraron tareas')\n            return\n        for name, info in self.tasks.items():\n            print(f\"Tarea: {name}:\\n\\tDescripción: {info['description']}\\n\\tTiempo de ejecución: {info['exec_time']} segundos\")\n            logger.info(f\"Tiempo de ejecucion de la tarea '{name}' es {info['exec_time']} segundos.\")\n\nmanagment = TaskManager()\n\nwhile True:\n    print('Gestor de tareas')\n    print('1. Añadir tarea')\n    print('2. Eliminar tarea')\n    print('3. Buscar tera')\n    print('4. Listar tareas')\n    print('5. Salir')\n\n    choice = input('>>> ')\n    if choice == '1':\n        managment.add_task()\n    elif choice == '2':\n        managment.delete_task()\n    elif choice == '3':\n        managment.get_task()\n    elif choice == '4':\n        managment.list_tasks()\n    elif choice == '5':\n        break\n    else:\n        print('Opción no válida')\n"
  },
  {
    "path": "Roadmap/25 - LOGS/python/qwik-zgheib.py",
    "content": "import logging\n\n# -- exercise\nlogging.basicConfig(level=logging.DEBUG)\n\n# Log messages with different severity levels\nlogging.debug(\"This is a debug message\")\nlogging.info(\"This is an info message\")\nlogging.warning(\"This is a warning message\")\nlogging.error(\"This is an error message\")\nlogging.critical(\"This is a critical message\")\n\n\n# -- extra challenge\nclass TaskManager:\n    def __init__(self):\n        self.tasks = []\n\n    def add_task(self, name, description):\n        task = {\"name\": name, \"description\": description}\n        self.tasks.append(task)\n        logging.info(f\"Task '{name}' added\")\n\n    def delete_task(self, name):\n        for task in self.tasks:\n            if task[\"name\"] == name:\n                self.tasks.remove(task)\n                logging.info(f\"Task '{name}' deleted\")\n                break\n        else:\n            logging.warning(f\"Task '{name}' not found\")\n\n    def list_tasks(self):\n        for task in self.tasks:\n            logging.info(f\"Task: {task['name']}, Description: {task['description']}\")\n\n\ntask_manager = TaskManager()\n\ntask_manager.add_task(\"Task 1\", \"Description 1\")\ntask_manager.add_task(\"Task 2\", \"Description 2\")\n\ntask_manager.delete_task(\"Task 1\")\n\ntask_manager.list_tasks()\n"
  },
  {
    "path": "Roadmap/25 - LOGS/python/rantamhack.py",
    "content": "\nprint(\"\\n\\n=======================================EJERCICIO=======================================\\n\\n\")\n\n\"\"\"\n * EJERCICIO:\n * Explora el concepto de \"logging\" en tu lenguaje. Configuralo y muestra\n * un ejemplo con cada nivel de \"severidad\" disponible.\n \n * CRITICAL: El nivel mas alto de registro, se utiliza para mensajes de error cri­ticos que pueden hacer que el programa se detenga.\n * ERROR:    Se utiliza para mensajes de error que pueden ser recuperables, pero que indican un problema importante en el programa.\n * WARNING:  Se utiliza para mensajes de advertencia que no son cri­ticos, pero que indican un comportamiento inesperado o problemático.\n * INFO:     Se utiliza para mensajes informativos que indican el estado del programa o el progreso de la ejecución.\n * DEBUG:    Se utiliza para mensajes de depuraciÃ³n que proporcionan información detallada sobre el funcionamiento interno del programa.\n\"\"\"\n\n# Importamos el modulo\nimport logging\n\n# Indicamos el nivel de severidad a partir del cual queremos que nos muestre el mensaje\n# En este caso desde el mas bajo. Si no pusieramos nada mostrarÃ­a solo los de \"Error\" y \"Critical\"\n# Tambien se le puede configurar como queremos que salga el mensaje. Vamos a poner que salga con la fecha, nivel de severidad y mensaje \nlogging.basicConfig(level=logging.DEBUG,\n                    format='%(asctime)s - %(levelname)s - %(message)s')\n\n\n# Registro de un mensaje de depuracion\nlogging.debug(\"[+] Entramos a la funcion\\n\")\n\n# Registro de un mensaje de informacion\nlogging.info(\"[+] La conexion con el servidor fue exitosa\\n\")\n\n# Registro de un mensaje de advertencia\nlogging.warning(\"[!] Queda poco espacio en disco\\n\")\n\n# Registro de un mensaje de error\nlogging.error(\"[!] Bloque de sangria previsto\\n\")\n\n# Registro de un mensaje de depuraciÃ³n\nlogging.critical(\"[!] Hay un error critico. Saliendo de la aplicacion ....\\n\")\n\n\nprint(\"\\n\\n=======================================DIFICULTAD EXTRA=======================================\\n\\n\")\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa ficticio de gestion de tareas que permita añadir, eliminar\n * y listar dichas tareas.\n * - Añadir: recibe nombre y descripcion.\n * - Eliminar: por nombre de la tarea.\n * Implementa diferentes mensajes de log que muestren informacion segun la \n * tarea ejecutada (a tu eleccion).\n * Utiliza el log para visualizar el tiempo de ejecucion de cada tarea. \n\"\"\"\nimport time\n\n#logging.basicConfig(level=logging.DEBUG,\n#                    format='%(asctime)s - %(levelname)s - %(message)s')\n\ndef time_spent(function):\n    def time_used(*args, **kwargs):\n        init = time.time()\n        result = function(*args, **kwargs)\n        elapsed_time = time.time() - init\n        logging.info(f\"[+] El tiempo empleado en {function.__name__} es {elapsed_time:.4f} segundos\")\n        return result\n    return time_used\n\nclass Task:\n    def __init__(self, name, description):\n        self.name = name\n        self.description = description\n\n\nclass Task_Manager:\n    def __init__(self):\n        self.tasks = []\n\n    @time_spent\n    def add_task(self, task):\n        logging.debug(\"[*] Comienza la funcion para 'añadir tareas'\")\n        time.sleep(1)\n        if any(t['name'] == task.name for t in self.tasks):\n            logging.warning(\"[!] La tarea ya esta en la lista\")\n        else:\n            self.tasks.append({\n                'name': task.name,\n                'description': task.description\n            })\n            time.sleep(1)\n            logging.info(\"[+] Se agrega nueva tarea\")\n            logging.debug(\"[*] Finaliza la funcion 'añadir tareas'\")\n    \n    \n    @time_spent\n    def del_task(self, task_name):\n        logging.debug(\"[*] Comienza la funcion para 'borrar tareas'\")\n        time.sleep(1)\n        self.tasks = [task for task in self.tasks if task['name'] != task_name]\n        logging.info(f\"[-] Se elimino la tarea: {task_name}\")\n        logging.debug(\"[*] Finaliza la funcion 'borrar tareas'\")\n    \n    @time_spent            \n    def list_tasks(self):\n        logging.debug(\"[*] Comienza la funcion para 'listar tareas'\")\n        time.sleep(1)\n        for task in self.tasks:\n            logging.info(f\"[+] Tarea: {task['name']} - Descripcion: {task['description']}\")\n        logging.debug(\"[*] Finaliza la funcion 'listar tareas'\")    \n            \n            \n    \nif __name__ == \"__main__\":\n    task_manager = Task_Manager()\n\n    task1 = Task(\"Tarea 1\", \"Descripcion de la tarea 1\")\n    task2 = Task(\"Tarea 2\", \"Descripcion de la tarea 2\")\n    task3 = Task(\"Tarea 3\", \"Descripcion de la tarea 3\")\n    \n    \n    task_manager.add_task(task1)  \n    task_manager.add_task(task2)\n    task_manager.add_task(task3)\n    task_manager.add_task(task1)\n\n\n    task_manager.list_tasks()\n    task_manager.del_task(\"Tarea 2\")\n    task_manager.list_tasks()\n\n\n\n    \n"
  },
  {
    "path": "Roadmap/25 - LOGS/python/raulG91.py",
    "content": "import logging\n\nFORMAT = '%(asctime)s %(message)s'\nlogger = logging.getLogger(__name__)\nlogging.basicConfig(format=FORMAT,level=logging.INFO)\n\nlogger.info(\"Info %s\",\"message\")\nlogger.debug(\"Debug %s\",\"message\")\nlogger.warning(\"Warning %s\",\"message\")\nlogger.error(\"Error %s\",\"message\")\nlogger.critical(\"Critical %s\", \"message\")\nlogger.exception(\"Exception %s\",\"message\")\n\n#Extra\n\nclass Task:\n    def __init__(self):\n        self.tasks = []\n    def add_task(self,name,description):\n        logger.info(\"%s\",\"Starting adding task\")\n        object ={\n            'name':name,\n            'description':description\n        }\n        self.tasks.append(object) \n        logger.info(\"%s\",\"Ending adding task\")\n    def remove_task(self,name):\n        logger.info(\"%s\",\"Starting removing task\")\n        for element in self.tasks:\n            if element[\"name\"]==name:\n                self.tasks.remove(element)\n        logger.info(\"%s\",\"Ending removing task\")    \n    def list_tasks(self):\n        logger.info(\"%s\",\"Starting listing task\")\n        for element in self.tasks:\n            print(f'Task {element[\"name\"]} with description {element[\"description\"]}')\n        logger.info(\"%s\",\"Ending listing task\")\n\n\n\nmyTaskObj = Task()\nmyTaskObj.add_task(\"Program\",\"Create a program\")\nmyTaskObj.add_task(\"Sleep\",\"Sleep for 8 hours\")\nmyTaskObj.add_task(\"Game\",\"Playing videogames\")\nmyTaskObj.list_tasks()\nmyTaskObj.remove_task(\"Game\")\nmyTaskObj.remove_task(\"Sleep\")\nmyTaskObj.add_task(\"Game\",\"Playing videogames\")\n\n\n\n"
  },
  {
    "path": "Roadmap/25 - LOGS/python/raynerpv2022.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * Explora el concepto de \"logging\" en tu lenguaje. Configúralo y muestra\n#  * un ejemplo con cada nivel de \"severidad\" disponible.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea un programa ficticio de gestión de tareas que permita añadir, eliminar\n#  * y listar dichas tareas.\n#  * - Añadir: recibe nombre y descripción.\n#  * - Eliminar: por nombre de la tarea.\n#  * Implementa diferentes mensajes de log que muestren información según la \n#  * tarea ejecutada (a tu elección).\n#  * Utiliza el log para visualizar el tiempo de ejecución de cada tarea. \n#  */\n\nimport logging\n\nprint(\"Logging in File (F) or Display (D)\")\nop = input()\nif op == \"F\":\n    logging.basicConfig(filename=\"log_my.log\",level=logging.DEBUG, \n                    format='%(asctime)s - %(levelname)s - %(message)s')\nelse :\n     logging.basicConfig(level=logging.DEBUG, \n                    format='%(asctime)s - %(levelname)s - %(message)s')\n\n \nlogging.debug(\"Mensaje de Error en Debug\")\nlogging.warning(\"Esto es una Warning\")\nlogging.critical(\"Esta critica la cosa\")\nlogging.info(\"Solo es info\")\nlogging.error(\"Error se formo el despelote\")\n\n\n# EXTRA\nimport time, datetime, random\n\nclass Dutty:\n\n     \n    \n    def __init__(self):\n        self.dutty = {}\n        \n\n    def create(self, dutty: str, desc: str ):\n            if dutty in self.dutty:\n                 logging.error(f\"Tarea {dutty} is already created\")\n            else:\n                 \n                self.dutty[dutty] = desc\n                logging.info(f\"Tarea {dutty} Succesfully created \")\n            logging.debug(f\"Numero de tareas {len (self.dutty)}\")\n            \n\n    def delete(self,name: str):\n          \n         if name in self.dutty:\n              \n              del self.dutty[name]\n              logging.info(f\"Tarea {name} Delete succesfully\")\n         else:\n              logging.error(f\"Tarea {name} Not Found\")\n         logging.debug(f\"Numero de tareas {len (self.dutty)}\")\n          \n\n    def display(self):\n         logging.info(\"Lista de tareas\")\n         for i,v in   self.dutty.items():\n                logging.info(f\" Tarea {i} Descripcion {v}\")\n\n   \n    \n    def execute (self,name):\n        if name in self.dutty:\n              logging.debug(f\"Tarea {name} executandose... \")\n              start = datetime.datetime.now()\n              logging.warning(f\"Tarea {name} Inicio {start.strftime(\"%H:%M:%S\")} \")\n              time_exec = random.randint(1,10)\n              logging.warning(f\"duracion estimada  {time_exec}s\")\n              time.sleep(time_exec)\n              end = datetime.datetime.now()\n              logging.warning(f\"fin {end.strftime(\"%H:%M:%S\")} \")\n              logging.debug(f\"Tarea {name} terminada\")\n              \n        else:\n             logging.error(f\"Tarea {name} Not found\")\\\n             \n\n     \nlist_dutty = Dutty()\n\nlist_dutty.create(\"t1\",\"asasasass\")\nlist_dutty.create(\"t2\", \"asasasass\")\nlist_dutty.create(\"t2\", \"asasasass\")\nlist_dutty.delete(\"t10\")\nlist_dutty.create(\"t3\", \"asasasass\")\nlist_dutty.delete(\"t1\")\nlist_dutty.create(\"t4\", \"asasasass\")\nlist_dutty.create(\"t5\", \"asasasass\")\nlist_dutty.create(\"t6\", \"asasasass\")\nlist_dutty.create(\"t7\", \"asasasass\")\n\nlist_dutty.execute(\"t3\" )\nlist_dutty.execute(\"t2\" )\nlist_dutty.execute(\"t1\" )\nlist_dutty.execute(\"t5\" )\nlist_dutty.execute(\"t11\" )\n\nlist_dutty.display()\n\n         \n\n  \n \n \n\n\n"
  },
  {
    "path": "Roadmap/25 - LOGS/python/rigo93acosta.py",
    "content": "'''\n/*\n * EJERCICIO:\n * Explora el concepto de \"logging\" en tu lenguaje. Configúralo y muestra\n * un ejemplo con cada nivel de \"severidad\" disponible.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa ficticio de gestión de tareas que permita añadir, eliminar\n * y listar dichas tareas.\n * - Añadir: recibe nombre y descripción.\n * - Eliminar: por nombre de la tarea.\n * Implementa diferentes mensajes de log que muestren información según la \n * tarea ejecutada (a tu elección).\n * Utiliza el log para visualizar el tiempo de ejecución de cada tarea. \n */\n'''\n\n'''\nEjercicio\n'''\n\nimport logging\nimport time\n\n# # logging.basicConfig(level=logging.DEBUG, \n# #                     format=\"%(asctime)s - %(levelname)s - %(message)s\",\n# #                     handlers=[logging.StreamHandler()])\n\nlogging.basicConfig(level=logging.DEBUG, \n                    format=\"%(asctime)s - %(levelname)s - %(message)s\")\n\n# logging.debug('This is a debug message')\n# logging.info('This is an info message')\n# logging.warning('This is a warning message')\n# logging.error('This is an error message')\n# logging.critical('This is a critical message')\n\n\n'''\nExtra\n'''\ndef print_time(func):\n    def wrapper(*args, **kwargs):\n        start_time = time.time()\n        func(*args, **kwargs)\n        end_time = time.time()\n        logging.debug(f\"Execution time: {end_time - start_time:.2e} seconds\")\n    return wrapper\n\nclass TaskManager:\n\n    def __init__(self) -> None:\n        self.tasks = {}\n    \n    @print_time\n    def add_task(self, name: str, description: str) -> None:\n        if name not in self.tasks:\n            self.tasks[name] = description\n            logging.info(f\"Task {name} added\")\n        else:\n            logging.warning(f\"Task {name} already exists\")\n\n        logging.debug(f\"Total tasks: {len(self.tasks)}\")\n\n    @print_time\n    def remove_task(self, name: str) -> None:\n        if name in self.tasks:\n            del self.tasks[name]\n            logging.info(f\"Task {name} removed\")\n        else:\n            logging.error(f\"Task {name} not found\")\n\n        logging.debug(f\"Total tasks: {len(self.tasks)}\")\n    \n    @print_time\n    def list_tasks(self) -> None:\n        if self.tasks:\n            logging.info(\"Listing tasks\")\n            for name, description in self.tasks.items():\n                print(f\"{name}: {description}\")\n        else:\n            logging.warning(\"No tasks to list\")\n\ntask_manager = TaskManager()\ntask_manager.list_tasks()\ntask_manager.add_task(\"Python\", \"Estudiar Python\")\ntask_manager.add_task(\"C\", \"Estudiar C\")\ntask_manager.add_task(\"Python\", \"Estudiar Python\")\ntask_manager.add_task(\"C++\", \"Estudiar C++\")\ntask_manager.add_task(\"Java\", \"Estudiar Java\")\ntask_manager.list_tasks()\ntask_manager.remove_task(\"Python\")\ntask_manager.remove_task(\"C++\")\ntask_manager.list_tasks()"
  },
  {
    "path": "Roadmap/25 - LOGS/python/santyjl.py",
    "content": "# 25 - LOGS\n\n\"\"\"\n/*\n * EJERCICIO:\n * Explora el concepto de \"logging\" en tu lenguaje. Configúralo y muestra\n * un ejemplo con cada nivel de \"severidad\" disponible.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa ficticio de gestión de tareas que permita añadir, eliminar\n * y listar dichas tareas.\n * - Añadir: recibe nombre y descripción.\n * - Eliminar: por nombre de la tarea.\n * Implementa diferentes mensajes de log que muestren información según la\n * tarea ejecutada (a tu elección).\n * Utiliza el log para visualizar el tiempo de ejecución de cada tarea.\n */\n\"\"\"\n\nimport logging  # El logging es prácticamente un depurador de código\nimport os\nimport time\n\nlogging.basicConfig(\n    encoding='utf-8',\n    format=\"%(levelname)s == %(message)s\",\n    level=logging.DEBUG\n)\n\n# Por defecto el level es Warning\nlogging.debug(\"Este es un mensaje de debug\")\nlogging.critical(\"Este es un mensaje crítico\")\nlogging.error(\"Este es un mensaje de error\")\nlogging.info(\"Este es un mensaje de info\")\nlogging.warning(\"Este es un mensaje de advertencia\")\n\n\nclass GestorDeTareas:\n    _instancia = None\n\n    def __new__(cls):\n        if cls._instancia is None:\n            cls._instancia = super().__new__(cls)\n            cls._instancia.datos_json = {}\n        return cls._instancia\n\n    def añadir_datos(self, nombre: str, descripcion: str):\n        self.datos_json[nombre] = descripcion\n        logging.info(\"Los datos fueron añadidos correctamente\")\n\n    def mostrar_datos(self):\n        if self.datos_json:\n            for nombre, descripcion in self.datos_json.items():\n                logging.info(f\"{nombre}: {descripcion}\")\n        else:\n            logging.info(\"No hay tareas para mostrar\")\n\n    def eliminar_datos(self):\n        tarea = input(\"Escribe el nombre de la tarea a eliminar: \")\n\n        if tarea in self.datos_json:\n            self.datos_json.pop(tarea)\n            logging.info(\"La tarea ha sido eliminada\")\n        else:\n            logging.warning(f\"No hay tarea que se llame: {tarea}\")\n\n\ndef añadir_datos() -> tuple:\n    nombre = input(\"Escribe el nombre de la tarea: \")\n    descripcion = input(\"Escribe una descripción breve de la tarea: \")\n    logging.info(\"Todo ha salido perfectamente\")\n    return nombre, descripcion\n\n\ndef limpiar_pantalla():\n    os.system('cls')\n\n\nwhile True:\n    logging.debug(\"Inicialización del gestor de tareas\")\n    time.sleep(0.3)\n    logging.debug(\"Añade las tareas\")\n\n    gestor_de_tareas = GestorDeTareas()\n    logging.info(\"\"\"\n                 1. Ver tareas\n                 2. Añadir tarea\n                 3. Eliminar tarea\n                 \"\"\")\n\n    try:\n        opcion = int(input(\"Elige según el índice: \"))\n    except ValueError:\n        logging.error(\"La opción tiene que ser un número\")\n        continue\n\n    if opcion == 1:\n        logging.info(\"Se mostrarán las tareas\")\n        gestor_de_tareas.mostrar_datos()\n        input(\"Toque 'Enter' para continuar: \")\n        limpiar_pantalla()\n\n    elif opcion == 2:\n        logging.info(\"Se añadirá una tarea\")\n        tarea = añadir_datos()\n        nombre, descripcion = tarea\n        gestor_de_tareas.añadir_datos(nombre, descripcion)\n        time.sleep(1)\n        limpiar_pantalla()\n\n    elif opcion == 3:\n        logging.info(\"Se eliminará una tarea\")\n        gestor_de_tareas.eliminar_datos()\n        time.sleep(1)\n        limpiar_pantalla()\n\n    else:\n        logging.warning(\"El número que seleccionaste no es una opción\")\n"
  },
  {
    "path": "Roadmap/25 - LOGS/rust/kenysdev.rs",
    "content": "/*\n╔═══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado                ║\n║ GitHub: https://github.com/Kenysdev   ║\n║ 2024 -  Rust                          ║\n╚═══════════════════════════════════════╝\n-----------------------------------------\n* LOGS\n-----------------------------------------\nDependencia: https://crates.io/crates/log\n             https://crates.io/crates/env_logger\n\n[dependencies]\nenv_logger = \"0.11.3\"\nlog = \"0.4.21\"\n*/\n\nuse log::{error, warn, info, debug, trace};\n\nfn main() {\n    /*\n    * EJERCICIO #1:\n    * Explora el concepto de \"logging\" en tu lenguaje. Configúralo y muestra\n    * un ejemplo con cada nivel de \"severidad\" disponible.\n    */\n\n    env_logger::Builder::from_default_env()\n        .filter_level(log::LevelFilter::Trace)\n        .init();\n        \n    debug!(\"msg {}\", \"debug\");\n    warn!(\"msg warn\");\n    info!(\"msg info\");\n    trace!(\"msg trace\");\n    error!(\"msg error\");\n\n    //____________________________________\n    println!(\"EJERCICIO #2\");\n\n    let mut tasks = Program::new();\n\n    tasks.add(\"a\", \"1\");\n    tasks.add(\"b\", \"2\");\n    tasks.add(\"c\", \"3\");\n\n    tasks.delete(\"a\");\n    tasks.show_list();\n\n}\n\n/*\n* EJERCICIO #2:\n* Crea un programa ficticio de gestión de tareas que permita añadir, eliminar\n* y listar dichas tareas.\n* - Añadir: recibe nombre y descripción.\n* - Eliminar: por nombre de la tarea.\n* Implementa diferentes mensajes de log que muestren información según la \n* tarea ejecutada (a tu elección).\n* Utiliza el log para visualizar el tiempo de ejecución de cada tarea. \n*/\n\nstruct Program {\n    tasks: std::collections::HashMap<String, String>,\n}\n\nimpl Program {\n    fn new() -> Self {\n        debug!(\"Se inició instancia.\");\n        Program {\n            tasks: std::collections::HashMap::new(),\n        }\n    }\n\n    fn add(&mut self, name: &str, description: &str) {\n        self.tasks.insert(name.to_string(), description.to_string());\n        info!(\"Se agregó una tarea.\");\n    }\n\n    fn delete(&mut self, name: &str) {\n        if self.tasks.remove(name).is_some() {\n            info!(\"Tarea '{}' eliminada.\", name);\n        } else {\n            println!();\n            warn!(\"No se encontró la tarea '{}'.\", name);\n        }\n    }\n\n    fn show_list(&self) {\n        info!(\"Lista de tareas\");\n        for (task, des) in &self.tasks {\n            println!(\"{} -- {}\", task, des);\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/25 - LOGS/sql/Nicojsuarez2.sql",
    "content": "# #25 LOGS\n> #### Dificultad: Fácil | Publicación: 17/06/24 | Corrección: 24/06/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Explora el concepto de \"logging\" en tu lenguaje. Configúralo y muestra\n * un ejemplo con cada nivel de \"severidad\" disponible.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa ficticio de gestión de tareas que permita añadir, eliminar\n * y listar dichas tareas.\n * - Añadir: recibe nombre y descripción.\n * - Eliminar: por nombre de la tarea.\n * Implementa diferentes mensajes de log que muestren información según la \n * tarea ejecutada (a tu elección).\n * Utiliza el log para visualizar el tiempo de ejecución de cada tarea. \n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/25 - LOGS/swift/blackriper.swift",
    "content": "/*\n Logs \n Los logs  son mensajes que sirven como historial de eventos de nuestra aplicacion en el tiempo \n los logs se clasifican en \n - debug\n - info\n - warning\n - error\n\n para mas informacion te invito a revisar mi ejercicio blackriper.kt donde explico mas sobre los logs\n \n recursos \n\n documentacion https://www.swift.org/documentation/server/guides/libraries/log-levels.html\n package swift log https://github.com/apple/swift-log\n\n */\n \n import Logging\n \n \n\n \n  func exampleWithLogging() {\n         // declaramos la clase Logger y pasamos el paquete/nombre del archivo\n         let logger = Logger(label: \"blackriper \")\n  \n        // seguimiento de un evento \n        logger.trace(\"Trace message\")\n        // informar sobre alguna prueba \n        logger.debug(\"Debug message\")\n        // informar sobre un evento \n        logger.info(\"Info message\")\n        // notifcar sobre algo ocurrido\n        logger.notice(\"Notice message\")\n        //informar sobre algun evento que eventualmente puede causar un errorº\n        logger.warning(\"Warning message\")\n        // informar sobre un error\n        logger.error(\"Error message\")\n        // informar sobre un error critico maxima prioridad\n        logger.critical(\"Critical message\")\n        \n    }\n    \n    exampleWithLoggin()\n    \n    \n    // ejercicio extra \n    \n    protocol ManagerTask{\n    func addTask(_ task:Task)->Bool\n    func removeTask(name:String)->Bool\n    func completeTask(name:String)->Bool\n }\n\n struct Task{\n      let name :String \n      let description :String\n      var done :Bool = false\n    }\n\n\nclass TaskManager:ManagerTask{\n    private let logger = Logger(label: \"logs \")\n    var tasks:[Task] = []\n\n    func addTask(_ task:Task)->Bool{\n      tasks.append(task)\n      logger.notice(\"Task \\(task.name) added\")\n      return true\n    }\n    func removeTask(name:String)->Bool{\n     tasks.removeAll(where: {$0.name == name})\n     logger.notice(\"Task \\(name) removed\")\n     return true\n    }\n    func completeTask(name:String)->Bool{\n       if var task = tasks.first(where: {$0.name == name}){\n           task.done = true\n           logger.info(\"Task \\(name) completed\")\n           return true\n       }\n       logger.error(\"Task \\(name) not found\")\n        return false\n    }\n}\n    \nlet manager = TaskManager()    \nmanager.addTask(Task( name:\"Swift Data module\",description: \"write module swift data\"))\nmanager.addTask(Task(name: \"Swift UI module\", description: \"write module swift ui\"))\nmanager.completeTask(name: \"Swift UI module\")\nmanager.completeTask(name: \"Kotlin\")\n\n    \n    \n    \n"
  },
  {
    "path": "Roadmap/25 - LOGS/typescript/AChapeton.ts",
    "content": "// Mensaje de texto generico\nconsole.log('Mensaje general')\n\n// Mensaje informativo\nconsole.info('Mensaje informativo')\n\n// Mensaje de advertencia\nconsole.warn('Mensaje de advertencia')\n\n// Mensaje de error\nconsole.error('Mensaje de error')\n\n// Limpiar consola\nconsole.clear()\n\n// Grupo de mensajes\nconsole.group('Titulo del grupo de logs')\nconsole.log('Primera linea')\nconsole.info('Segunda linea')\nconsole.error('Tercera linea')\nconsole.groupEnd()\n\n// Logs para tomar tiempo de procesos\nconsole.time('Inicio de proceso')\n  // Proceso para testear\nconsole.timeEnd()\n\n// Tablas\nconsole.table([\"manzanas\", \"peraas\", \"bananas\"]);"
  },
  {
    "path": "Roadmap/25 - LOGS/typescript/Rafacv23.ts",
    "content": "// Hecho por @Rafacv23 | https://github.com/Rafacv23 | https://twitter.com/rafacanosa  | https://www.rafacanosa.dev\n\n// Tipos de logs que hay en JavaScript\nconsole.log(\"Esto es un console.log() sirve para mostrar mensajes por consola.\")\nconsole.warn(\n  \"Esto es un console.warn(), sirve para mostrar mensajes de aviso ante posibles errores o áreas a las que haya que prestar especial atención.\"\n)\nconsole.error(\n  \"Esto es un console.error(), sirve para mostrar errores por consola.\"\n)\nconsole.info(\n  \"Esto es un console.info(), sirve para aportar información adicional a un mensaje.\"\n)\nconsole.debug(\n  \"Esto es un console.debug(), sirve para mostrar un mensaje por consola pero con el modo debug activado.\"\n)\n\n// Dificultad opcional\nconsole.log(\"Iniciando programa de gestión de tareas...\")\n\n// Clase Task\nclass Task {\n  name: string\n  description: string\n\n  constructor(name: string, description: string) {\n    this.name = name\n    this.description = description\n  }\n}\n\n// TaskManager: para gestionar las tareas\nclass TaskManager {\n  taskList: Task[] = []\n\n  // Añadir tarea\n  addTask(name: string, description: string): void {\n    console.time(\"Tiempo para añadir tarea\")\n    const newTask = new Task(name, description)\n    this.taskList.push(newTask)\n    console.log(`Tarea \"${name}\" añadida correctamente.`)\n    console.timeEnd(\"Tiempo para añadir tarea\")\n  }\n\n  // Eliminar tarea\n  deleteTask(name: string): void {\n    console.time(\"Tiempo para eliminar tarea\")\n\n    // Check if name is provided\n    if (!name) {\n      console.error(\"No se ha introducido el nombre de la tarea\")\n      console.timeEnd(\"Tiempo para eliminar tarea\")\n      return\n    }\n\n    // Check if task exists\n    const taskExists = this.taskList.some((task) => task.name === name)\n    if (!taskExists) {\n      console.error(\n        `Error: No se encontró ninguna tarea con el nombre \"${name}\".`\n      )\n      console.timeEnd(\"Tiempo para eliminar tarea\")\n      return\n    }\n\n    this.taskList = this.taskList.filter((task) => task.name !== name)\n    console.log(`Tarea con nombre \"${name}\" eliminada correctamente.`)\n    console.timeEnd(\"Tiempo para eliminar tarea\")\n  }\n\n  // Listar tareas\n  showTasks(): void {\n    console.time(\"Tiempo para listar tareas\")\n    if (this.taskList.length === 0) {\n      console.warn(\"No hay tareas para mostrar.\")\n    } else {\n      console.log(\"Tareas actuales:\")\n      this.taskList.forEach((task, index) => {\n        console.log(`${index + 1}. ${task.name} - ${task.description}`)\n      })\n    }\n    console.timeEnd(\"Tiempo para listar tareas\")\n  }\n}\n\n// Crear una instancia del administrador de tareas\nconst taskManager = new TaskManager()\n\n// Añadir algunas tareas\ntaskManager.addTask(\"Lavar la ropa\", \"Separar blanco de color\")\ntaskManager.addTask(\"Hacer la compra\", \"Comprar pan, leche y huevos\")\ntaskManager.addTask(\"Estudiar\", \"Estudiar para el examen de JavaScript\")\n\n// Listar todas las tareas\ntaskManager.showTasks()\n\n// Eliminar una tarea y mostrar el listado actualizado\ntaskManager.deleteTask(\"Estudiar\")\ntaskManager.showTasks()\n"
  },
  {
    "path": "Roadmap/25 - LOGS/typescript/Sac-Corts.ts",
    "content": "console.log(\"This is a general message\");\nconsole.info(\"This is an informational message\");\nconsole.warn(\"Warning: This is a warning message\");\nconsole.error(\"Error: This is an error message\");\nconsole.debug(\"Debug: This is a debug message\");\n\n// ** Extra Exercise ** //\ninterface Task {\n    name: string;\n    description: string;\n}\n\nclass TaskManager {\n    private tasks: Task[];\n\n    constructor() {\n        this.tasks = [];\n    }\n\n    addTask(name: string, description: string): void {\n        console.time(`addTask`);\n        console.log(`Trying to add task: ${name}`);\n\n        this.tasks.push({ name, description });\n\n        console.info(`Task \"${name}\" added successfully`);\n        console.timeEnd(`addTask`);\n    }\n\n    removeTask(name: string): void {\n        console.time(`removeTask`);\n        console.log(`Trying to remove task: ${name}`);\n\n        const index = this.tasks.findIndex(task => task.name === name);\n\n        if (index !== -1) {\n            this.tasks.splice(index, 1);\n            console.info(`Task \"${name}\" removed successfully`);\n        } else {\n            console.warn(`The task with the name \"${name}\" was not found`);\n        }\n        console.timeEnd(`removeTask`);\n    }\n\n    listTasks(): void {\n        console.time(`listTasks`);\n        console.log(`Showing all tasks:`);\n\n        if (this.tasks.length === 0) {\n            console.warn(\"No tasks available\");\n        } else {\n            this.tasks.forEach(task => {\n                console.info(`Task: ${task.name}, Description: ${task.description}`);\n            });\n        }\n        console.timeEnd(`listTasks`);\n    }\n}\n\nconst taskManager = new TaskManager();\ntaskManager.addTask(\"Task 1\", \"Do something\");\ntaskManager.addTask(\"Task 2\", \"Do anything\");\n\ntaskManager.listTasks();\n\ntaskManager.removeTask(\"Task 2\");\nconsole.log(taskManager);\n"
  },
  {
    "path": "Roadmap/25 - LOGS/typescript/duendeintemporal.ts",
    "content": "// #25 { retosparaprogramadores } - LOGS\n/* EJERCICIO:\n * Explora el concepto de \"logging\" en tu lenguaje. Configúralo y muestra\n * un ejemplo con cada nivel de \"severidad\" disponible.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un programa ficticio de gestión de tareas que permita añadir, eliminar\n * y listar dichas tareas.\n * - Añadir: recibe nombre y descripción.\n * - Eliminar: por nombre de la tarea.\n * Implementa diferentes mensajes de log que muestren información según la\n * tarea ejecutada (a tu elección).\n * Utiliza el log para visualizar el tiempo de ejecución de cada tarea. */\n\n\n//(Node.js is required to run the Extra Dificulty Exercise example)\n\nlet log = console.log;\nlog(\"Retosparaprogramadores #25.\");\n\n// Conditional check for browser environment\nif (typeof window !== 'undefined') {\n    window.addEventListener('load', () => {\n        const body: HTMLBodyElement | null = document.querySelector('body');\n        const title = document.createElement('h1');\n\n        body?.style.setProperty('background', '#000');\n        body?.style.setProperty('text-align', 'center');\n\n        title.textContent = 'Retosparaprogramadores #25.';\n        title.style.setProperty('font-size', '3.5vmax');\n        title.style.setProperty('color', '#fff');\n        title.style.setProperty('line-height', '100vh');\n\n        body?.appendChild(title);\n\n        setTimeout(() => {\n            alert('Retosparaprogramadores #25. Please open the Browser Developer Tools.');\n        }, 2000);\n        log('Retosparaprogramadores #25');\n    });\n} else {\n    log('This code is designed to run in a browser environment. Skipping window-related code.');\n    log('Retosparaprogramadores #25');\n}\n\n// Logging functions with TypeScript type annotations\nconst logDebug = (message: string) => console.debug(`DEBUG: ${message}`);\nconst logInfo = (message: string) => console.info(`INFO: ${message}`);\nconst logWarning = (message: string) => console.warn(`WARNING: ${message}`);\nconst logError = (message: string) => console.error(`ERROR: ${message}`);\nconst logCritical = (message: string) => console.error(`CRITICAL: ${message}`);\n\nlogDebug(\"This is a debug message.\");\nlogInfo(\"This is an informational message.\");\nlogWarning(\"This is a warning message.\");\nlogError(\"This is an error message.\");\nlogCritical(\"This is a critical message.\");\n\n// EXTRA DIFFICULTY EXERCISE (Node.js is required to run this example)\n\nimport * as readline from 'readline';\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nclass TaskManager {\n    private tasks: { [key: string]: string };\n\n    constructor() {\n        this.tasks = {};\n    }\n\n    addTask(name: string, description: string): void {\n        const startTime = Date.now();\n        if (this.tasks[name]) {\n            logWarning(`The task '${name}' already exists.`);\n            this.promptEditTask(name);\n            return;\n        }\n        this.tasks[name] = description;\n        logInfo(`Task added: ${name} - ${description}`);\n        const endTime = Date.now();\n        logDebug(`Execution time for adding task: ${(endTime - startTime) / 1000} seconds`);\n    }\n\n    promptEditTask(name: string): void {\n        const askQuestion = () => {\n            rl.question(`The task '${name}' already exists. Do you want to edit it? (yes/no): `, (answer) => {\n                if (answer.toLowerCase() === 'yes' || answer.toLowerCase() === 'y') {\n                    rl.question('Enter the new description: ', (newDescription) => {\n                        this.editTask(name, newDescription);\n                        rl.close();\n                    });\n                } else if (answer.toLowerCase() === 'no' || answer.toLowerCase() === 'n') {\n                    logInfo(`No changes made to the task '${name}'.`);\n                    rl.close();\n                } else {\n                    logWarning(\"Invalid input. Please answer with 'yes' or 'no'.\");\n                    askQuestion(); // Re-ask the question if the input is invalid\n                }\n            });\n        };\n    \n        askQuestion(); // Initial call to start the questioning\n    }\n    \n\n    editTask(name: string, newDescription: string): void {\n        const startTime = Date.now();\n        if (!this.tasks[name]) {\n            logError(`Could not edit the task '${name}' because it does not exist.`);\n            return;\n        }\n        this.tasks[name] = newDescription;\n        logInfo(`Task edited: ${name} - New Description: ${newDescription}`);\n        const endTime = Date.now();\n        logDebug(`Execution time for editing task: ${(endTime - startTime) / 1000} seconds`);\n    }\n\n    removeTask(name: string): void {\n        const startTime = Date.now();\n        if (!this.tasks[name]) {\n            logError(`Could not remove the task '${name}' because it does not exist.`);\n            return;\n        }\n        delete this.tasks[name];\n        logInfo(`Task removed: ${name}`);\n        const endTime = Date.now();\n        logDebug(`Execution time for removing task: ${(endTime - startTime) / 1000} seconds`);\n    }\n\n    listTasks(): void {\n        const startTime = Date.now();\n        if (Object.keys(this.tasks).length === 0) {\n            logWarning(\"No tasks to display.\");\n            return;\n        }\n        logInfo(\"Task list:\");\n        for (const [name, description] of Object.entries(this.tasks)) {\n            logInfo(`- ${name}: ${description}`);\n        }\n        const endTime = Date.now();\n        logDebug(`Execution time for listing tasks: ${(endTime - startTime) / 1000} seconds`)\n    }\n}\n\n// Example usage of the TaskManager class\nconst manager = new TaskManager();\nmanager.addTask(\"Implement User Authentication\", \"Develop a user authentication system that allows users to register, log in, and log out securely.\");\nmanager.addTask(\"Fix Bug in Feature Resize window\", \"Fix Bug in Feature Resize window\");\nmanager.addTask(\"Write Unit Tests\", \"Write Unit Tests - Create tests for the user authentication module using Jest.\");\nmanager.addTask(\"Refactor Code for Module Lang_translation\", \"Refactor Code for Module Lang_translation - Simplify the logic and remove redundant code.\");\nmanager.addTask(\"Deploy Application to Production\", \"Deploy Application to Production - Set up CI/CD pipeline and deploy the latest build.\");\nmanager.listTasks();\nmanager.removeTask(\"Implement User Authentication\");\nmanager.editTask(\"Fix Bug in Feature Resize window\", \"Fix Bug in Feature Resize window - Resolve the issue causing the application to crash on submission.\");\nmanager.listTasks();\n   // After all task operations\n   rl.close();\n   // process.exit(0); // This method is explicitly used to terminate the Node.js process. \n\n/* Output:\nThis code is designed to run in a browser environment. Skipping window-related code.\nRetosparaprogramadores #25\nDEBUG: This is a debug message.\nINFO: This is an informational message.\nWARNING: This is a warning message.\nERROR: This is an error message.\nCRITICAL: This is a critical message.\nINFO: Task added: Implement User Authentication - Develop a user authentication system that allows users to register, log in, and log out securely.\nDEBUG: Execution time for adding task: 0.004 seconds\nINFO: Task added: Fix Bug in Feature Resize window - Fix Bug in Feature Resize window\nDEBUG: Execution time for adding task: 0.002 seconds\nINFO: Task added: Write Unit Tests - Write Unit Tests - Create tests for the user authentication module using Jest.\nDEBUG: Execution time for adding task: 0.001 seconds\nINFO: Task added: Refactor Code for Module Lang_translation - Refactor Code for Module Lang_translation - Simplify the logic and remove redundant code.\nDEBUG: Execution time for adding task: 0.002 seconds\nINFO: Task added: Deploy Application to Production - Deploy Application to Production - Set up CI/CD pipeline and deploy the latest build.\nDEBUG: Execution time for adding task: 0.002 seconds\nINFO: Task list:\nINFO: - Implement User Authentication: Develop a user authentication system that allows users to register, log in, and log out securely.\nINFO: - Fix Bug in Feature Resize window: Fix Bug in Feature Resize window\nINFO: - Write Unit Tests: Write Unit Tests - Create tests for the user authentication module using Jest.\nINFO: - Refactor Code for Module Lang_translation: Refactor Code for Module Lang_translation - Simplify the logic and remove redundant code.\nINFO: - Deploy Application to Production: Deploy Application to Production - Set up CI/CD pipeline and deploy the latest build. \nDEBUG: Execution time for listing tasks: 0.006 seconds\nINFO: Task removed: Implement User Authentication\nDEBUG: Execution time for removing task: 0.002 seconds\nINFO: Task edited: Fix Bug in Feature Resize window - New Description: Fix Bug in Feature Resize window - Resolve the issue causing the application to crash on submission.\nDEBUG: Execution time for editing task: 0.007 seconds\nINFO: Task list:\nINFO: - Fix Bug in Feature Resize window: Fix Bug in Feature Resize window - Resolve the issue causing the application to crash \non submission.\nINFO: - Write Unit Tests: Write Unit Tests - Create tests for the user authentication module using Jest.\nINFO: - Refactor Code for Module Lang_translation: Refactor Code for Module Lang_translation - Simplify the logic and remove redundant code.\nINFO: - Deploy Application to Production: Deploy Application to Production - Set up CI/CD pipeline and deploy the latest build.\nDEBUG: Execution time for listing tasks: 0.026 seconds*/\n\n/*Info Note: \nContinuous Integration is a development practice where developers frequently integrate their code changes into a shared repository, usually several times a day.\nEach integration is automatically tested to detect errors quickly. This helps ensure that the codebase remains stable and that new changes do not break existing functionality.\nTools commonly used for CI include Jenkins, Travis CI, CircleCI, GitHub Actions, and GitLab CI.\nCD (Continuous Delivery or Continuous Deployment):\n\nContinuous Delivery is an extension of CI that ensures that the code is always in a deployable state. This means that after passing automated tests, the code can be deployed to production at any time.\nContinuous Deployment takes it a step further by automatically deploying every change that passes the tests to production without manual intervention.\nThis practice allows for faster release cycles and more frequent updates to the application. */"
  },
  {
    "path": "Roadmap/25 - LOGS/typescript/eulogioep.ts",
    "content": "/**\n * TEORÍA SOBRE LOGGING EN TYPESCRIPT\n * \n * El logging es una práctica fundamental en el desarrollo de software que permite:\n * - Registrar eventos y estados durante la ejecución del programa\n * - Facilitar la depuración y el diagnóstico de problemas\n * - Monitorear el rendimiento y comportamiento de la aplicación\n * \n * Niveles de severidad comunes:\n * - ERROR: Errores críticos que impiden el funcionamiento correcto\n * - WARN: Advertencias sobre situaciones potencialmente problemáticas\n * - INFO: Información general sobre el flujo del programa\n * - DEBUG: Información detallada útil para depuración\n * - TRACE: Información muy detallada sobre el flujo de ejecución\n */\n\n// Importamos la biblioteca de logging (en este caso usaremos console por simplicidad)\nclass Logger {\n    static error(message: string) {\n        console.error(`[ERROR] ${new Date().toISOString()} - ${message}`);\n    }\n\n    static warn(message: string) {\n        console.warn(`[WARN] ${new Date().toISOString()} - ${message}`);\n    }\n\n    static info(message: string) {\n        console.info(`[INFO] ${new Date().toISOString()} - ${message}`);\n    }\n\n    static debug(message: string) {\n        console.debug(`[DEBUG] ${new Date().toISOString()} - ${message}`);\n    }\n\n    static trace(message: string) {\n        console.trace(`[TRACE] ${new Date().toISOString()} - ${message}`);\n    }\n}\n\n// Ejemplo básico de uso de diferentes niveles de logging\nfunction demonstrateLogging() {\n    Logger.error(\"Error crítico en la conexión a la base de datos\");\n    Logger.warn(\"El espacio en disco está por debajo del 20%\");\n    Logger.info(\"Aplicación iniciada correctamente\");\n    Logger.debug(\"Valor de la variable x: 42\");\n    Logger.trace(\"Entrando en la función calculateTotal()\");\n}\n\n// Definición de la interfaz para una tarea\ninterface Task {\n    name: string;\n    description: string;\n    createdAt: Date;\n}\n\n// Clase para la gestión de tareas\nclass TaskManager {\n    private tasks: Task[] = [];\n\n    /**\n     * Añade una nueva tarea al sistema\n     * @param name Nombre de la tarea\n     * @param description Descripción de la tarea\n     */\n    addTask(name: string, description: string): void {\n        const startTime = performance.now();\n        \n        try {\n            // Verificar si ya existe una tarea con el mismo nombre\n            if (this.tasks.some(task => task.name === name)) {\n                Logger.error(`Tarea \"${name}\" ya existe`);\n                return;\n            }\n\n            const newTask: Task = {\n                name,\n                description,\n                createdAt: new Date()\n            };\n\n            this.tasks.push(newTask);\n            Logger.info(`Tarea \"${name}\" añadida exitosamente`);\n            \n            const endTime = performance.now();\n            Logger.debug(`Tiempo de ejecución addTask: ${endTime - startTime}ms`);\n        } catch (error) {\n            Logger.error(`Error al añadir tarea: ${error}`);\n        }\n    }\n\n    /**\n     * Elimina una tarea por su nombre\n     * @param name Nombre de la tarea a eliminar\n     */\n    removeTask(name: string): void {\n        const startTime = performance.now();\n        \n        try {\n            const initialLength = this.tasks.length;\n            this.tasks = this.tasks.filter(task => task.name !== name);\n\n            if (this.tasks.length === initialLength) {\n                Logger.warn(`No se encontró la tarea \"${name}\"`);\n            } else {\n                Logger.info(`Tarea \"${name}\" eliminada exitosamente`);\n            }\n\n            const endTime = performance.now();\n            Logger.debug(`Tiempo de ejecución removeTask: ${endTime - startTime}ms`);\n        } catch (error) {\n            Logger.error(`Error al eliminar tarea: ${error}`);\n        }\n    }\n\n    /**\n     * Lista todas las tareas existentes\n     */\n    listTasks(): void {\n        const startTime = performance.now();\n        \n        try {\n            if (this.tasks.length === 0) {\n                Logger.info(\"No hay tareas registradas\");\n                return;\n            }\n\n            Logger.info(\"Lista de tareas:\");\n            this.tasks.forEach(task => {\n                Logger.info(`- ${task.name}: ${task.description} (Creada: ${task.createdAt})`);\n            });\n\n            const endTime = performance.now();\n            Logger.debug(`Tiempo de ejecución listTasks: ${endTime - startTime}ms`);\n        } catch (error) {\n            Logger.error(`Error al listar tareas: ${error}`);\n        }\n    }\n}\n\n// Ejemplo de uso\nfunction main() {\n    Logger.info(\"Iniciando sistema de gestión de tareas\");\n\n    const taskManager = new TaskManager();\n\n    // Ejemplo de uso del sistema\n    taskManager.addTask(\"Estudiar TypeScript\", \"Aprender sobre tipos y interfaces\");\n    taskManager.addTask(\"Hacer ejercicio\", \"30 minutos de cardio\");\n    taskManager.listTasks();\n    taskManager.removeTask(\"Estudiar TypeScript\");\n    taskManager.listTasks();\n    taskManager.removeTask(\"Tarea inexistente\");\n\n    Logger.info(\"Finalizando sistema de gestión de tareas\");\n}\n\n// Ejecutar el programa\nmain();"
  },
  {
    "path": "Roadmap/25 - LOGS/typescript/hozlucas28.ts",
    "content": "/*\n    Logging...\n*/\n\nimport readline from 'node:readline/promises'\n\nconsole.log('Logging...')\n\nconsole.clear()\n\nconsole.log('\\nconsole.dir(<Object>)...\\n')\n\nconsole.dir({\n    age: 22,\n    userName: 'Lucas Hoz',\n    address: {\n        city: 'Buenas Aires',\n        country: 'Argentina',\n    },\n})\n\nconsole.log('\\nconsole.error(<String>)...')\n\nconsole.error('\\nAn error occurred!')\n\nconsole.log(`\\nconsole.group(<Label>)\\n<...Logs>\\nconsole.groupEnd()...`)\n\nconsole.group('\\nLog group')\nconsole.log('Log inside the group')\nconsole.groupEnd()\n\nconsole.log(\n    `\\nconsole.groupCollapsed(<Label>)\\n<...Logs>\\nconsole.groupEnd()...`\n)\n\nconsole.groupCollapsed('\\nLog group (collapsed)')\nconsole.log('Log inside the group')\nconsole.groupEnd()\n\nconsole.log('\\nconsole.info(<MESSAGE>)...')\n\nconsole.info('\\nNew information!')\n\nconsole.log('\\nconsole.log(<MESSAGE>)...')\n\nconsole.log('\\nCommon log')\n\nconsole.log('\\nconsole.table(<Array>)...\\n')\n\nconsole.table([\n    'Buenos Aires',\n    'Catamarca',\n    'Santa Fe',\n    'Jujuy',\n    'Santiago del Estero',\n])\n\nconsole.log('\\nconsole.warn(<MESSAGE>)...')\n\nconsole.warn('\\nWarning!')\n\nconsole.log(\n    `\\nconsole.time(<Label>)\\nconsole.timeLog(<Label>)\\nconsole.timeEnd(<Label>)...\\n`\n)\n\nconsole.time('Timer')\nconsole.timeLog('Timer')\nconsole.timeEnd('Timer')\n\nconsole.log(\n    '\\n# ---------------------------------------------------------------------------------- #\\n'\n)\n\n/*\n    Additional challenge...\n*/\n\nconsole.log('Additional challenge...')\n\ninterface Task {\n    description: string\n    title: string\n}\n\ninterface ITaskManager {\n    getShouldPrintLogs(): boolean\n\n    setShouldPrintLogs(newValue: boolean): this\n\n    addTask(newTask: Task): this\n    deleteTaskByTitle(title: string): this\n    printTasks(): this\n}\n\nclass TaskManager implements ITaskManager {\n    private shouldPrintLogs: boolean\n    private tasks: Task[]\n\n    constructor({\n        shouldPrintLogs,\n        initialTasks,\n    }: {\n        shouldPrintLogs: boolean\n        initialTasks: Task[]\n    }) {\n        this.shouldPrintLogs = shouldPrintLogs\n        this.tasks = initialTasks\n    }\n\n    getShouldPrintLogs(): boolean {\n        return this.shouldPrintLogs\n    }\n\n    setShouldPrintLogs(newValue: boolean): this {\n        this.shouldPrintLogs = newValue\n        return this\n    }\n\n    addTask(newTask: Task): this {\n        if (this.shouldPrintLogs) {\n            console.log('\\naddTask (method) start execution...')\n            console.time('addTask')\n        }\n\n        this.tasks.push(newTask)\n\n        if (this.shouldPrintLogs) {\n            console.log('\\naddTask (method) ends execution!')\n            console.timeEnd('addTask')\n        }\n        return this\n    }\n\n    deleteTaskByTitle(title: string): this {\n        if (this.shouldPrintLogs) {\n            console.log('\\ndeleteTaskByTitle (method) start execution...')\n            console.time('deleteTaskByTitle')\n        }\n\n        this.tasks = this.tasks.filter(\n            (task) =>\n                task.title.trim().toUpperCase() !== title.trim().toUpperCase()\n        )\n\n        if (this.shouldPrintLogs) {\n            console.log('\\ndeleteTaskByTitle (method) ends execution!')\n            console.timeEnd('deleteTaskByTitle')\n        }\n        return this\n    }\n\n    printTasks(): this {\n        if (this.shouldPrintLogs) {\n            console.log('\\nprintTasks (method) start execution...\\n')\n            console.time('printTasks')\n        }\n\n        for (const task of this.tasks) console.dir(task)\n\n        if (this.shouldPrintLogs) {\n            console.log('\\nprintTasks (method) ends execution!')\n            console.timeEnd('printTasks')\n        }\n        return this\n    }\n}\n\ntype Operation = 'add task' | 'delete task by title' | 'print tasks' | 'exit'\n;(async () => {\n    const taskManager: TaskManager = new TaskManager({\n        initialTasks: [],\n        shouldPrintLogs: true,\n    })\n\n    const rl = readline.createInterface({\n        input: process.stdin,\n        output: process.stdout,\n    })\n\n    let exit: boolean = false\n\n    while (!exit) {\n        const operation = (await rl.question(\n            \"\\nWrite an operation ('Add task', 'Delete task by title', 'Print tasks', or 'Exit'): \"\n        )) as Operation\n\n        switch (operation.trim().toUpperCase() as Uppercase<Operation>) {\n            case 'ADD TASK':\n                const newTaskTitle = await rl.question('\\nTask title: ')\n\n                const newTaskDescription = await rl.question(\n                    'Task description: '\n                )\n\n                taskManager.addTask({\n                    description: newTaskDescription,\n                    title: newTaskTitle,\n                })\n                break\n\n            case 'DELETE TASK BY TITLE':\n                const taskTitleToDelete = await rl.question('\\nTask title: ')\n                taskManager.deleteTaskByTitle(taskTitleToDelete)\n                break\n\n            case 'PRINT TASKS':\n                taskManager.printTasks()\n                break\n\n            case 'EXIT':\n                exit = true\n                console.log('\\nApplication closed!')\n                break\n\n            default:\n                console.log('\\nInvalid operation! Try again...')\n        }\n    }\n\n    rl.close()\n})()\n"
  },
  {
    "path": "Roadmap/25 - LOGS/vb.net/kenysdev.vb",
    "content": "' ╔══════════════════════════════════════╗\n' ║ Autor:  Kenys Alvarado               ║\n' ║ GitHub: https://github.com/Kenysdev  ║\n' ║ 2024 -  VB.NET                       ║\n' ╚══════════════════════════════════════╝\n'-----------------------------------------------\n'* LOGS\n'-----------------------------------------------\n'Mas info: https://nlog-project.org/\n\nImports NLog\nImports NLog.Config\nImports NLog.Targets\n\nModule Program\n\n    Private Logger As Logger = LogManager.GetCurrentClassLogger()\n\n    Sub Main()\n        '* EJERCICIO #1:\n        '* Explora el concepto de \"logging\" en tu lenguaje. Configúralo y muestra\n        '* un ejemplo con cada nivel de \"severidad\" disponible.\n\n        ' Configuración manual\n        Dim config As New LoggingConfiguration()\n\n        ' Definir el destino del log)\n        Dim consoleTarget As New ConsoleTarget(\"console\")\n        config.AddTarget(\"console\", consoleTarget)\n\n        ' Definir las reglas de log\n        config.AddRuleForAllLevels(consoleTarget)\n\n        ' Aplicar la configuración\n        LogManager.Configuration = config\n\n        ' Ejemplo de uso:\n        Logger.Trace(\"msg Trace\")\n        Logger.Debug(\"msg Debug\")\n        Logger.Info(\"msg Info\")\n        Logger.Warn(\"msg Warn\")\n        Logger.Error(\"msg Error\")\n        Logger.Fatal(\"msg Fatal\")\n\n        '_________________________________________________\n        Console.WriteLine(vbLf & \"EJERCICIO #2\")\n        Dim tasks As New ProgramTask()\n\n        tasks.Add(\"a\", \"1\")\n        tasks.Add(\"b\", \"2\")\n        tasks.Add(\"c\", \"3\")\n\n        tasks.Delete(\"b\")\n        tasks.ShowList()\n\n    End Sub\n\n    '-----------------------------------------------\n    '* EJERCICIO #2\n    '* Crea un programa ficticio de gestión de tareas que permita añadir, eliminar\n    '* y listar dichas tareas.\n    '* - Añadir: recibe nombre y descripción.\n    '* - Eliminar: por nombre de la tarea.\n    '* Implementa diferentes mensajes de log que muestren información según la \n    '* tarea ejecutada (a tu elección).\n    '* Utiliza el log para visualizar el tiempo de ejecución de cada tarea. \n\n    Public Class ProgramTask\n        Private Shared ReadOnly logger As Logger = LogManager.GetCurrentClassLogger()\n        Private ReadOnly tasks As Dictionary(Of String, String)\n\n        Public Sub New()\n            tasks = New Dictionary(Of String, String)()\n            logger.Debug(\"Se inició instancia de la clase ProgramTask.\")\n        End Sub\n\n        Public Sub Add(name As String, description As String)\n            tasks(name) = description\n            logger.Info(\"Se agregó una tarea.\")\n        End Sub\n\n        Public Sub Delete(name As String)\n            If tasks.Remove(name) Then\n                logger.Info($\"Tarea '{name}' eliminada.\")\n            Else\n                Console.WriteLine()\n                logger.Warn($\"No se encontró la tarea '{name}'.\")\n            End If\n        End Sub\n\n        Public Sub ShowList()\n            logger.Info(\"Lista de tareas\")\n            For Each task In tasks\n                Console.WriteLine($\"{task.Key} -- {task.Value}\")\n            Next\n        End Sub\n    End Class\nEnd Module\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/bash/rantamhack.sh",
    "content": "#!/bin/bash\n\n\n# BASH NO ESTA ORIENTADO A OBJETOS Y NO TIENE CLASES, ESTE EJERCICIO ES UNA SIMULACION DE LAS CLASES\n\necho -e \"\\n\\n=======================================EJERCICIO SIN SRP=======================================\\n\\n\"\n\n# * EJERCICIO:\n# * Explora el \"Principio SOLID de Responsabilidad Unica (Single Responsibility\n# * Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n# * de forma correcta e incorrecta.\n\n\n# * Sin aplicar el principio \"SRP\"\n\nstudents=()\nsubscriptions=()\npayments=()\n\n\nfunction mouredev_academy() {\n    local user_id=\"$1\"\n    local name=\"$2\"\n    local surname=\"$3\"\n    local email=\"$4\"\n\n    read -p \"Introduce tu nombre de usuario:  \" nick\n    read -p \"introduce tu contraseña:  \" passwd\n\n    students+=(\"$user_id, $name, $surname, $email, $username, $password\")\n    echo -e \"[+] El estudiante $username se ha añadido a la base de datos\" \n\n    if [[ $nick == $username && $passwd == $password ]]; then\n        echo -e \"[*] Bienvenido a la academia $username\"\n    else\n        echo -e \"[!] Los datos introducidos no son correctos\"\n    fi  \n}\n\nfunction subs_type(){\n    local monthly=\"$1\"\n    local quarterly=\"$2\"\n    local half_yearly=\"$3\"\n    local yearly=\"$4\"\n    subscriptions+=(\"$monthly, $quarterly, $half_yearly, $yearly\")\n    echo -e \"[-] Los tipos de suscripcion se han aÃ±adido\"\n}\n        \nfunction payment() {\n    local credit_card=\"$1\"\n    local debit_card=\"$2\"\n    local bizum=\"$3\"\n    local bank_transfer=\"$4\"\n    payments+=(\"$credit_card, $debit_card, $bizum, $bank_transfer\")\n    echo -e \"[-] Los metodos de pago se han añadido\" \n}\n\n\nmouredev_academy \"username\" \"password\"\nmouredev_academy 1 \"Luis\" \"Ramos\" \"rantam@rantam.com\" \"fake\" \"126354\"\nsubs_type \"Monthly\" \"Quarterly\" \"Half_yearly\" \"Yearly\"\npayment \"credit_card\" \"debit_card\" \"bizum\" \"bank_transfer\"\n\n\necho -e \"\\n\\n=======================================EJERCICIO CON SRP=======================================\\n\\n\"\n\n\n\n# * Aplicando el principio \"SRP\"\n\nstudents=()\nsubscriptions=()\npayments=()\n\nfunction auth(){\n    local username=\"$1\"\n    local password=\"$2\"\n\n    read -p \"Introduce tu nombre de usuario:  \" nick\n    read -p \"introduce tu contraseña:  \" passwd\n\n    echo -e \"[-] Autenticando al usuario $nick\"\n\n    if [[ $nick == \"$username\" && $passwd == \"$password\" ]]; then\n        echo -e \"[*] Bienvenido a la academia $username\"\n    else\n        echo -e \"[!] Los datos introducidos no son correctos\"\n    fi  \n\n}\n\nfunction add_students(){\n    local user_id=\"$1\"\n    local name=\"$2\"\n    local surname=\"$3\"\n    local email=\"$4\"\n    local username=$5\n\n    students+=(\"$user_id, $name, $surname, $email, $username\")\n\n    for student in \"${students[@]}\";do\n        echo -e \"[+] La lista de estudiantes es $student\"\n    done\n    \n}\n\nfunction add_subs(){\n    local monthly=\"$1\"\n    local quarterly=\"$2\"\n    local half_yearly=\"$3\"\n    local yearly=\"$4\"\n    subscriptions+=(\"$monthly, $quarterly, $half_yearly, $yearly\")\n    echo -e \"[-] Los tipos de suscripcion se han añadido\"\n}\n\nfunction add_payment() {\n    local credit_card=\"$1\"\n    local debit_card=\"$2\"\n    local bizum=\"$3\"\n    local bank_transfer=\"$4\"\n    payments+=(\"$credit_card, $debit_card, $bizum, $bank_transfer\")\n    echo -e \"[-] Los metodos de pago se han añadido\" \n}\n\nfunction moure_academy(){\n    local command=\"$1\"\n    shift\n    \n    case \"$command\" in\n        auth)\n            auth \"$@\"\n            ;;\n        add_students)\n            add_students \"$@\"\n            ;;\n        add_subs)\n            add_subs \"$@\"\n            ;;\n        add_payment)\n            add_payment \"$@\"\n            ;;\n        *)\n            echo -e \"[!] Comando no reconocido\"\n            ;;\n    esac\n}\n\nmoure_academy add_students 1 \"Rosa\" \"Lopez\" \"rosa@moureacademy.com\" \"rantam\"\nmoure_academy add_students 2 \"Mario\" \"Bros\" \"mario@moureacademy.com\" \"Ka_OS\"\nmoure_academy auth \"rantam\" \"123456\"\nmoure_academy auth \"Ka_Os\" \"654321\"\nmoure_academy add_subs \"Monthly\" \"Quarterly\" \"Half_yearly\" \"Yearly\"\nmoure_academy add_payment \"credit_card\" \"debit_card\" \"bizum\" \"bank_transfer\"\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/c#/hequebo.cs",
    "content": "/*\n * El Principio de Resposabilidad Única (SRP)\n * de los principios SOLID nos dice que una\n * clase solo debe de encargarse de una \n * responsabilidad, para que sea más fácil\n * su modificación y correción de errores\n */\nclass Program\n{\n    static int idUser = 1;\n    static int idLoan = 1;\n    static void Main(string[] args)\n    {\n        var post = new Post(\"hequebo\", \"Hola Mundo\", DateTime.Now);\n        post.SavePost();\n        post.SharePost();\n\n        var postSRP = new PostSRP(\"hequebo\", \"Hola Mundo\", DateTime.Now);\n        var postDB = new PostDB(postSRP);\n        var postReq = new PostRequest(postSRP);\n        postDB.SavePost();\n        postReq.SharePost();\n\n        Console.ReadLine();\n        Console.Clear();\n\n        LibrarySRP library = new LibrarySRP();\n        bool salir = false;\n\n        do\n        {\n            Menu();\n            int option = 0;\n            int.TryParse(Console.ReadLine(), out option);\n            switch (option)\n            {\n                case 1:\n                    RegisterBook(ref library);\n                    break;\n                case 2:\n                    RegisterUser(ref library);\n                    break;\n                case 3:\n                    LoanBook(ref library);\n                    break;\n                case 4:\n                    ReturnBook(ref library);\n                    break;\n                case 5:\n                    salir = true;\n                    Console.Clear();\n                    Console.WriteLine(\"Hasta la próxima...\");\n                    Thread.Sleep(1000);\n                    break;\n                default:\n                    Console.WriteLine(\"Opción no válida...\");\n                    break;\n            }\n        } while (!salir);\n\n    }\n    static void Menu()\n    {\n        Console.WriteLine(\"---Sistema de biblioteca---\");\n        Console.WriteLine(\"1.- Agregar libro\");\n        Console.WriteLine(\"2.- Agregar Usuario\");\n        Console.WriteLine(\"3.- Pedir libro\");\n        Console.WriteLine(\"4.- Devolver libro\");\n        Console.WriteLine(\"5.- Salir\");\n        Console.WriteLine(\"Elija opción deseada\");\n    }\n    static void RegisterBook(ref LibrarySRP library)\n    {\n        Console.Clear();\n        Console.WriteLine(\"Ingrsa titulo del libro\");\n        string title = Console.ReadLine();\n        Console.WriteLine(\"Ingresa Nombre del autor\");\n        string author = Console.ReadLine();\n        Console.WriteLine(\"Ingresa número de copias a registrar\");\n        int copies = int.Parse(Console.ReadLine());\n        var book = new Book(title, author, copies);\n        library.RegisterBook(book);\n        Console.Clear();\n        Console.WriteLine(\"Libro registrado correctamente...\");\n        Console.WriteLine($\"Título: {title}, Autor: {author}, Copias: {copies}\");\n    }\n    static void RegisterUser(ref  LibrarySRP library)\n    {\n        Console.Clear();\n        Console.WriteLine(\"Ingresa Nombre del usuario\");\n        string name = Console.ReadLine();\n        Console.WriteLine(\"Ingresa Correo del usuario\");\n        string email = Console.ReadLine();\n        var user = new User(name, email, idUser);\n        library.RegisterUser(user);\n        \n        Console.Clear();\n        Console.WriteLine(\"Usuario registrado correctamente...\");\n        Console.WriteLine($\"ID: {idUser}, Nombre: {name}, Correo: {email}\");\n\n        idUser++;\n    }\n    static void LoanBook(ref LibrarySRP library)\n    {\n        Console.Clear();\n        Console.WriteLine(\"Ingresa título de libro a pedir\");\n        string title = Console.ReadLine();\n        if (!library.SearchBook(title))\n            return;\n        if (library.GetCopies(title) == 0)\n        {\n            Console.WriteLine($\"No hay copias disponibles de {title}\");\n            return;\n        }\n        Console.WriteLine(\"Ingresa nombre de usuario\");\n        string name = Console.ReadLine();\n        var user = library.SearchUser(name);\n        if (user == null)\n            return;\n        var loan = new Loan(idLoan, title, user.Id);\n        library.LoanBook(loan);\n        Console.Clear();\n        Console.WriteLine(\"Se realizó préstamo correctamente...\");\n        Console.WriteLine($\"Titulo {title}, Usuario: {user.Name}\");\n        idLoan++;\n    }\n    static void ReturnBook(ref  LibrarySRP library)\n    {\n        Console.Clear();\n        Console.WriteLine(\"Ingresa nombre de libro a regresar\");\n        string title = Console.ReadLine();\n        Console.WriteLine(\"Ingresa nombre de usuario que regresa el libro\");\n        string name = Console.ReadLine();\n        var user = library.SearchUser(name);\n        if (user == null)\n            return;\n        var loan = library.SearchLoan(title, user.Id);\n        if (loan == null)\n        {\n            Console.WriteLine(\"No existe el préstamo\");\n            return;\n        }\n        library.ReturnBook(loan);\n        Console.Clear();\n        Console.WriteLine(\"El libro se regresó correctamente...\");\n    }\n}\n#region Incorrecto\n/*\n * INCORRECTO\n * La siguiente clase tiene tres responsabilidades\n * diferentes:\n * 1.- Tener la información de la publicación\n * 2.- Guardar la publicación en Base de Datos\n * 3.- Compartir la publicación\n */\n\nclass Post\n{\n    private string _username;\n    private string _content;\n    private DateTime _postDate;\n\n    public Post(string username, string content, DateTime postDate)\n    {\n        _username = username;\n        _content = content;\n        _postDate = postDate;\n    }\n\n    public void SavePost() => Console.WriteLine(\"Se guarda publicación en base de datos...\");\n    \n\n    public void SharePost() => Console.WriteLine(\"Se comparte publicación...\");\n}\n#endregion\n#region Correcto\n/*\n * CORRECTO\n * Como en el ejemplo anterior existen\n * tres responsaibilidades, siguiendo\n * el princicipio SRP se deben de crear\n * tres clases diferentes\n */\nclass PostSRP\n{\n    private string _username;\n    private string _content;\n    private DateTime _postDate;\n\n    public PostSRP(string username, string content, DateTime postDate)\n    {\n        _username = username;\n        _content = content;\n        _postDate = postDate;\n    }\n}\n\n/*\n * La clases que no se encargan\n * de la información reciben en su \n * constructor un objeto de la clase\n * con esa responsabilidad\n */\nclass PostDB\n{\n    private PostSRP _post;\n    \n    public PostDB(PostSRP post)\n    {\n        _post = post;\n    }\n    public void SavePost() => Console.WriteLine(\"Guardando en BD...\");\n}\nclass PostRequest\n{\n    private PostSRP _post;\n\n    public PostRequest(PostSRP post)\n    {\n        _post = post;\n    }\n\n    public void SharePost() => Console.WriteLine(\"Se comparte publicación...\");\n}\n#endregion\n// Ejercicio Extra\n// Incorrecto\n#region ExtraIncorrecto\nclass Library\n{\n    private List<(string Title, string Author, int Copies)> _books;\n    private List<(string Name, string Email, int Id)> _users;\n    private List<(int IdLoan, string BookTitle, int IdUser)> _loans;\n    private int _id = 0;\n    private int _idLoan = 0;\n\n    public Library()\n    {\n        _books = new List<(string, string, int)> ();\n        _users = new List<(string, string, int)> ();\n        _loans = new List<(int, string, int)> ();\n    }\n\n    public void RegisterBook(string title, string author, int copies) =>\n        _books.Add((title, author, copies));\n    public void RegisterUser(string name, string email)\n    {\n        _id++;\n        _users.Add((name, email, _id));\n    }\n    public void LoanBook(string title, int idUser) \n    {\n        if (_books.Where(b => b.Title == title).Count() == 0) \n        {\n            Console.WriteLine(\"No existe el libro\");\n            return;\n        }\n        if (_books.Where(b => b.Title == title).Select(b => b.Copies).FirstOrDefault() == 0)\n        {\n            Console.WriteLine(\"No hay copias disponibles..\");\n        }\n        if (_users.Where(u => u.Id == idUser).Count() == 0)\n        {\n            Console.WriteLine(\"Usuario no existe\");\n            return;\n        }\n        _loans.Add((_idLoan, title, idUser));\n    }\n    public void ReturnBook(string title, int idUser)\n    {\n        if (_loans.Where(l => l.BookTitle == title && l.IdUser == idUser).Count() == 0) \n        {\n            Console.WriteLine(\"No hay registro de este préstamo\");\n            return;\n        }\n        int idLoan = _loans.Where(l => l.BookTitle == title && l.IdUser == idUser).Select(l => l.IdLoan).FirstOrDefault();\n        var book = _books.Where(b => b.Title == title).Select(b => b).FirstOrDefault();\n        book.Copies++;\n        _loans.Remove((idLoan, title, idUser));\n\n    }\n}\n#endregion\n// Correcto\nclass Book\n{\n    private string _title;\n    private string _author;\n    private int _copies;\n\n    public string Title\n    {\n        get\n        {\n            return _title;\n        }\n        set\n        {\n            _title = value;\n        }\n    }\n\n    public string Author\n    {\n        get\n        {\n            return _author;\n        }\n        set\n        {\n            _author = value;\n        }\n    }\n\n    public int Copies\n    {\n        get\n        {\n            return _copies;\n        }\n        set\n        {\n            _copies = value;\n        }\n    }\n\n    public Book(string title, string author, int copies)\n    {\n        _title = title;\n        _author = author;\n        _copies = copies;\n    }\n}\nclass BookService\n{\n    private List<Book> _books;\n    public BookService()\n    {\n        _books = new List<Book>();\n    }\n\n    public void RegisterBook(Book book)\n    {\n        _books.Add(book);\n    }\n    public bool SearchBook(string title)\n    {\n        if (string.IsNullOrEmpty(title))\n            return false;\n        if (_books.Where(b => b.Title == title).Count() == 0)\n        {\n            Console.WriteLine($\"No se encontro el libro: {title}\");\n            return false;\n        }\n        return true;\n    }\n    public int GetCopies(string title) =>\n        _books.Where(b => b.Title == title).Select(b => b.Copies).FirstOrDefault();\n    public void LoanBook(string title)\n    {\n        var book = _books.Where(b => b.Title == title).FirstOrDefault();\n        book.Copies--;\n    }\n    public void ReturnBook(string title)\n    {\n        var book = _books.Where(b => b.Title == title).FirstOrDefault();\n        book.Copies++;\n    }\n}\n\nclass User\n{\n    private string _name;\n    private string _email;\n    private int _id;\n\n    public string Name\n    {\n        get\n        {\n            return _name;\n        }\n        set\n        {\n            _name = value;\n        }\n    }\n    public string Email\n    {\n        get\n        {\n            return _email;\n        }\n        set\n        {\n            _email = value;\n        }\n    }\n\n    public int Id\n    {\n        get\n        {\n            return _id;\n        }\n    }\n\n    public User(string name, string email, int id)\n    {\n        _name = name;\n        _email = email;\n        _id = id;\n    }\n}\nclass UserService\n{\n    private List<User> _users;\n    public UserService()\n    {\n        _users = new List<User>();\n    }\n    public void RegisterUser(User user) => _users.Add(user);\n    public User SearchUser(string name)\n    {\n        if (_users.Where(u  => u.Name == name).Count() == 0)\n        {\n            Console.WriteLine($\"No existe usuario {name}\");\n            return null;\n        }\n        return _users.Where(u => u.Name == name).FirstOrDefault();\n    }\n    \n}\n\nclass Loan\n{\n    private int _id;\n    private string _title;\n    private int _userId;\n\n    public int Id { get { return _id; } }\n    public string Title { get { return _title; } }\n    public int UserId {  get { return _userId; } }\n\n    public Loan(int id, string title, int userId)\n    {\n        _id = id;\n        _title = title;\n        _userId = userId;\n    }\n}\n\nclass LoanService\n{\n    private List<Loan> _loans;\n\n    public LoanService()\n    {\n        _loans = new List<Loan>();\n    }\n\n    public void LoanBook(Loan loan)\n    {\n        _loans.Add(loan);\n    }\n\n    public void ReturnBook(Loan loan)\n    {\n        _loans.Remove(loan);\n    }\n    public Loan SearchLoan(string title, int id)\n    {\n        if (_loans.Count == 0)\n        {\n            Console.WriteLine(\"No hay préstamos activos\");\n            return null;\n        }\n        var loan = _loans.Where(l => l.Title == title && l.UserId == id).FirstOrDefault();\n        return loan;\n    }\n}\n\nclass LibrarySRP\n{\n    private BookService _bookService;\n    private UserService _userService;\n    private LoanService _loanService;\n\n    public LibrarySRP()\n    {\n        _bookService = new BookService();\n        _userService = new UserService();\n        _loanService = new LoanService();\n    }\n\n    public void RegisterBook(Book book) => _bookService.RegisterBook(book);\n    public bool SearchBook(string title) => _bookService.SearchBook(title);\n    public int GetCopies(string title) => _bookService.GetCopies(title);\n    public void RegisterUser(User user) => _userService.RegisterUser(user);  \n    public User SearchUser(string name) => _userService.SearchUser(name);\n    public void LoanBook(Loan loan)\n    {\n        _loanService.LoanBook(loan);\n        _bookService.LoanBook(loan.Title);\n    }\n    public Loan SearchLoan(string title, int id) => _loanService.SearchLoan(title, id);\n    public void ReturnBook(Loan loan)\n    {\n        _loanService.ReturnBook(loan);\n        _bookService.ReturnBook(loan.Title);\n    }\n    \n}\n    \n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/c#/kenysdev.cs",
    "content": "#pragma warning disable CA1050 //namespace\n/*\n╔══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado               ║\n║ GitHub: https://github.com/Kenysdev  ║\n║ 2024 -  C#                           ║\n╚══════════════════════════════════════╝\n-------------------------------------------------\n* SOLID: PRINCIPIO DE RESPONSABILIDAD ÚNICA (SRP)\n-------------------------------------------------\n# Se centra en la claridad, la cohesión y la separación de intereses.\n# Cada clase debe tener una única razón para cambiar.\n# Los metodos de una clase deben estar estrechamente relacionadas.\n\n__________________________________\n* EJERCICIO:\n* Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n* Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n* de forma correcta e incorrecta.\n*/\n\n// # SIN APLICAR EL PRINCIPIO:\nusing System.Collections.Generic;\n\npublic class NoSRP {\n    private readonly List<string> customers;\n    private readonly List<string> suppliers;\n\n    public NoSRP() {\n        customers = [];\n        suppliers = [];\n    }\n\n    public void AddCustomer(string name) {\n        customers.Add(name);\n    }\n\n    public void AddSupplier(string name) {\n        suppliers.Add(name);\n    }\n\n    public void RemoveCustomer(string name) {\n        customers.Remove(name);\n    }\n\n    public void RemoveSupplier(string name) {\n        suppliers.Remove(name);\n    }\n}\n\n// _______________________________________\n// APLICANDO EL PRINCIPIO:\n\npublic class Customers {\n    private readonly List<string> customers;\n\n    public Customers() {\n        customers = [];\n    }\n\n    public void Add(string name) {\n        customers.Add(name);\n    }\n\n    public void Remove(string name) {\n        customers.Remove(name);\n    }\n}\n\npublic class Suppliers {\n    private readonly List<string> suppliers;\n\n    public Suppliers() {\n        suppliers = [];\n    }\n\n    public void Add(string name) {\n        suppliers.Add(name);\n    }\n\n    public void Remove(string name) {\n        suppliers.Remove(name);\n    }\n}\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/c++/hectorio23.cpp",
    "content": "// Autor: Héctor Adán \n// GitHub: https://github.com/hectorio23\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <cstdlib>\n\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n * Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA:\n * Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n * manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n * y el procesamiento de préstamos de libros.\n * Requisitos:\n * 1. Registrar libros: El sistema debe permitir agregar nuevos libros con \n * información básica como título, autor y número de copias disponibles.\n * 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n * información básica como nombre, número de identificación y correo electrónico.\n * 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n * tomar prestados y devolver libros.\n*/\n\nclass Book {\npublic:\n    std::string title;\n    std::string author;\n    int copies;\n\n    Book(const std::string& _title, const std::string& _author, int _copies) : title(_title), author(_author), copies(_copies) {}\n};\n\n\nclass BookManager {\nprivate:\n    std::vector<Book> books;\n\npublic:\n\n    void addBook() {\n        std::system(\"clear\");\n        std::string title, author;\n        int copies;\n        std::cout << \"Ingrese el título del libro: \";\n        std::cin.ignore();\n        std::getline(std::cin, title);\n        std::cout << \"Ingrese el autor del libro: \";\n        std::getline(std::cin, author);\n        std::cout << \"Ingrese el número de copias: \";\n        std::cin >> copies;\n        books.push_back(Book(title, author, copies));\n        std::cout << \"Libro agregado exitosamente.\\n\";\n    }\n\n    void listBooks() const {\n        std::system(\"clear\");\n        if (books.empty()) {\n            std::cout << \"No hay libros disponibles.\\n\";\n            return;\n        }\n        for (const auto& book : books) {\n            std::cout << \"Título: \" << book.title << \", Autor: \" << book.author << \", Copias: \" << book.copies << std::endl;\n        }\n    }\n};\n\n\nclass User {\npublic:\n    std::string name;\n    long id;\n    std::string email;\n\n    User(const std::string& n, long i, const std::string& e) : name(n), id(i), email(e) {}\n};\n\n\nclass UserManager {\nprivate:\n    std::vector<User> users;\n\npublic:\n    void addUser() {\n        std::system(\"clear\");\n        std::string name, email;\n        long id;\n        std::cout << \"Ingrese el nombre del usuario: \";\n        std::cin.ignore();\n        std::getline(std::cin, name);\n        std::cout << \"Ingrese el ID del usuario: \";\n        std::cin >> id;\n        std::cout << \"Ingrese el correo electrónico del usuario: \";\n        std::cin.ignore();\n        std::getline(std::cin, email);\n        users.push_back(User(name, id, email));\n        std::cout << \"Usuario agregado exitosamente.\\n\";\n    }\n\n    void listUsers() const {\n        std::system(\"clear\");\n        if (users.empty()) {\n            std::cout << \"No hay usuarios registrados.\\n\";\n            return;\n        }\n        for (const auto& user : users) {\n            std::cout << \"Nombre: \" << user.name << \", ID: \" << user.id << \", Correo: \" << user.email << std::endl;\n        }\n    }\n};\n\n\nclass LoanManager {\npublic:\n    void lendBook(UserManager& userManager, BookManager& bookManager) {\n        std::system(\"clear\");\n        std::string bookTitle;\n        long userId;\n        std::cout << \"Ingrese el ID del usuario: \";\n        std::cin >> userId;\n        std::cout << \"Ingrese el título del libro a prestar: \";\n        std::cin.ignore();\n        std::getline(std::cin, bookTitle);\n\n        // Lógica de préstamo\n        std::cout << \"Libro '\" << bookTitle << \"' prestado al usuario ID \" << userId << \".\\n\";\n    }\n\n    void returnBook(UserManager& userManager, BookManager& bookManager) {\n        std::system(\"clear\");\n        std::string bookTitle;\n        long userId;\n        std::cout << \"Ingrese el ID del usuario: \";\n        std::cin >> userId;\n        std::cout << \"Ingrese el título del libro a devolver: \";\n        std::cin.ignore();\n        std::getline(std::cin, bookTitle);\n\n        // Lógica de devolución\n        std::cout << \"Libro '\" << bookTitle << \"' devuelto por el usuario ID \" << userId << \".\\n\";\n    }\n};\n\nvoid displayMenu() {\n    // std::system(\"clear\");\n    std::cout << \"******** Menú de la Biblioteca ********\\n\";\n    std::cout << \"[1] - Agregar un libro\\n\";\n    std::cout << \"[2] - Listar libros\\n\";\n    std::cout << \"[3] - Agregar un usuario\\n\";\n    std::cout << \"[4] - Listar usuarios\\n\";\n    std::cout << \"[5] - Prestar un libro\\n\";\n    std::cout << \"[6] - Devolver un libro\\n\";\n    std::cout << \"[7] - Salir\\n\";\n    std::cout << \"Seleccione una opción: \";\n}\n\n\nint main() {\n    BookManager bookManager;\n    UserManager userManager;\n    LoanManager loanManager;\n    int option;\n\n    do {\n        displayMenu();\n        std::cin >> option;\n\n        switch (option) {\n            case 1:\n                bookManager.addBook();\n                break;\n            case 2:\n                bookManager.listBooks();\n                break;\n            case 3:\n                userManager.addUser();\n                break;\n            case 4:\n                userManager.listUsers();\n                break;\n            case 5:\n                loanManager.lendBook(userManager, bookManager);\n                break;\n            case 6:\n                loanManager.returnBook(userManager, bookManager);\n                break;\n            case 7:\n                std::cout << \"Saliendo del sistema...\\n\";\n                break;\n            default:\n                std::cout << \"Opción no válida. Intente de nuevo.\\n\";\n        }\n\n    } while (option != 7);\n\n    return EXIT_SUCCESS;\n}\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/dart/EmilianoAngel.dart",
    "content": "// Incorrecto\n// class User {\n//   String name;\n//   String email;\n\n//   User(this.name, this.email);\n\n//   void saveToDatabase(String name, String email) {\n//     print('User $name with email $email saved to database.');\n//   }\n\n//   void sendWelcomeEmail(String email) {\n//     print('Welcome email sent to $email');\n//   }\n\n// }\n\n// Corecto\n\nclass User {\n  String name;\n  String email;\n\n  User(this.name, this.email);\n}\n\nclass UserSeervice {\n  void saveToDatabase(String name, String email) {\n    print('User $name with email $email saved to database.');\n  }\n}\n\nclass EmailService {\n  void sendWelcomeEmail(String email) {\n    print('Welcome email sent to $email');\n  }\n}\n\n// Ejercicio de biblioteca\n\n// Icorrecto\n// class Biblioteca {\n//   List<Map<String, dynamic>> books = [];\n//   List<Map<String, dynamic>> users = [];\n//   List<String> loans = [];\n\n//   void addBook(String title, String author, int copies) {\n//     books.add({'title': title, 'author': author, 'copies': copies});\n//     print('Book \"$title\" added to the library.');\n//   }\n\n//   void addUser(String name, String userId, int email) {\n//     users.add({'name': name, 'userId': userId, 'email': email});\n//     print('User \"$userId\" added to the database.');\n//   }\n\n//   void loanBook(String userId, String bookTitle) {\n//     var user = users.firstWhere((u) => u['userId'] == userId, orElse: () => {});\n//     var book = books.firstWhere((b) => b['title'] == bookTitle, orElse: () => {});\n\n//     if (user.isEmpty) {\n//       print('User not found.');\n//       return;\n//     }\n\n//     if (book.isEmpty || book['copies'] <= 0) {\n//       print('Book not available.');\n//       return;\n//     }\n\n//     book['copies'] -= 1;\n//     loans.add('User $userId loaned \"$bookTitle\"');\n//     print('Book \"$bookTitle\" loaned to user $userId.');\n//   }\n\n//   void returnBook(String userId, String bookTitle) {\n//     var book = books.firstWhere((b) => b['title'] == bookTitle, orElse: () => {});\n\n//     if (book.isEmpty) {\n//       print('Book not found in the library.');\n//       return;\n//     }\n\n//     book['copies'] += 1;\n//     loans.remove('User $userId loaned \"$bookTitle\"');\n//     print('Book \"$bookTitle\" returned by user $userId.');\n//   }\n// }\n\n// Correcto \nclass Book {\n  String title;\n  String author;\n  int copies;\n\n  Book(this.title, this.author, this.copies);\n}\n\nclass LibraryUser {\n  String name;\n  String userId;\n  String email;\n\n  LibraryUser(this.name, this.userId, this.email);\n}\n\nclass Loan {\n  List<Map<String, dynamic>> loans = [];\n\n  void loanBook(LibraryUser user, Book book) {\n    if (book.copies <= 0) {\n      print('Book not available.');\n      return;\n    }\n\n    book.copies -= 1;\n    loans.add({'userId': user.userId, 'bookTitle': book.title});\n    print('Book \"${book.title}\" loaned to user ${user.userId}.');\n  }\n\n  void returnBook(LibraryUser user, Book book) {\n    book.copies += 1;\n    loans.removeWhere((loan) => loan['userId'] == user.userId && loan['bookTitle'] == book.title);\n    print('Book \"${book.title}\" returned by user ${user.userId}.');\n  }\n}\n\nclass Library {\n  List<Book> books = [];\n  List<LibraryUser> users = [];\n  Loan loanService = Loan();\n\n  void addBook(Book book) {\n    books.add(book);\n    print('Book \"$book.title\" added to the library.');\n  }\n\n  void addUser(LibraryUser user) {\n    users.add(user);\n    print('User \"${user.userId}\" added to the database.');\n  }\n\n  loanBook(LibraryUser user, Book book) {\n    loanService.loanBook(user, book);\n  }\n\n  returnBook(LibraryUser user, Book book) {\n    loanService.returnBook(user, book);\n  }\n}"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/ejercicio.md",
    "content": "# #26 SOLID: PRINCIPIO DE RESPONSABILIDAD ÚNICA (SRP)\n> #### Dificultad: Media | Publicación: 24/06/24 | Corrección: 01/07/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n * Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n * manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n * y el procesamiento de préstamos de libros.\n * Requisitos:\n * 1. Registrar libros: El sistema debe permitir agregar nuevos libros con \n * información básica como título, autor y número de copias disponibles.\n * 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n * información básica como nombre, número de identificación y correo electrónico.\n * 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n * tomar prestados y devolver libros.\n * Instrucciones:\n * 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n * los tres aspectos mencionados anteriormente (registro de libros, registro de\n * usuarios y procesamiento de préstamos).\n * 2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n * siguiendo el Principio de Responsabilidad Única.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/26 - SOLID SRP/go/AmadorQuispe.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n)\n\n//APLICANDO SRP\n\ntype Employee struct {\n\tid    int\n\tname  string\n\temail string\n}\n\nfunc (e *Employee) GetId() int {\n\treturn e.id\n}\n\nfunc (e *Employee) GetName() string {\n\treturn e.name\n}\n\nfunc (e *Employee) GetEmail() string {\n\treturn e.email\n}\n\n// Repository\ntype EmployeeRepository struct {\n\t// Database connection or other storage-related fields\n}\n\nfunc (repo *EmployeeRepository) Save(employee *Employee) error {\n\t// Save user to the database\n\tfmt.Println(\"saving data...\", employee)\n\treturn nil\n}\n\n// Service\ntype EmployeeService struct {\n\t//Repositories and other services\n}\n\nfunc (svc *EmployeeService) Notification(employee *Employee) error {\n\tfmt.Println(\"Sending notification\", employee.GetEmail())\n\treturn nil\n}\n\n//EXTRA\n// APLICANDO SRP\n\ntype User struct {\n\tdoi   string\n\tname  string\n\temail string\n}\n\ntype UserRepository struct {\n\tusers []User\n}\n\nfunc (userRepo *UserRepository) Register(user User) {\n\tuserRepo.users = append(userRepo.users, user)\n\tfmt.Println(\"usuario registrado\")\n}\n\nfunc (userRepo *UserRepository) FindByDoi(doi string) *User {\n\tfor i, user := range userRepo.users {\n\t\tif user.doi == doi {\n\t\t\treturn &userRepo.users[i]\n\t\t}\n\t}\n\treturn nil\n}\n\ntype Book struct {\n\ttitle  string\n\tauthor string\n\tcopies int\n}\n\ntype BookRepository struct {\n\tbooks []Book\n}\n\nfunc (bookRepo *BookRepository) Register(book Book) {\n\tbookRepo.books = append(bookRepo.books, book)\n\tfmt.Println(\"libro registrado\")\n}\n\nfunc (bookRepo *BookRepository) FindByTitle(title string) *Book {\n\tfor i, book := range bookRepo.books {\n\t\tif book.title == title {\n\t\t\treturn &bookRepo.books[i]\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (bookRepo *BookRepository) IncreaseCopies(title string, delta int) {\n\tbook := bookRepo.FindByTitle(title)\n\tbook.copies += delta\n}\n\ntype LoanRepository struct {\n\tloanBooks map[string][]string\n}\n\nfunc (loanRepo *LoanRepository) LoanBook(userDoi, bookTitle string) {\n\tif v, ok := loanRepo.loanBooks[userDoi]; ok {\n\t\tv = append(v, bookTitle)\n\t\tloanRepo.loanBooks[userDoi] = v\n\t} else {\n\t\tloanRepo.loanBooks[userDoi] = []string{bookTitle}\n\t}\n\tfmt.Println(\"préstamo del libro registrado\")\n}\n\nfunc (loanRepo *LoanRepository) ReturnBook(userDoi, bookTitle string) {\n\tfor key, values := range loanRepo.loanBooks {\n\t\tif key == userDoi {\n\t\t\tvar newList []string\n\t\t\tfor _, v := range values {\n\t\t\t\tif v != bookTitle {\n\t\t\t\t\tnewList = append(newList, v)\n\t\t\t\t}\n\t\t\t}\n\t\t\tloanRepo.loanBooks[userDoi] = newList\n\t\t\tfmt.Println(\"Libro devuelto correctamente\")\n\t\t\tbreak\n\t\t}\n\t}\n}\n\ntype Library struct {\n\tbookRepo BookRepository\n\tuserRepo UserRepository\n\tloanRepo LoanRepository\n}\n\nfunc (lib *Library) CreateBook(book Book) {\n\tlib.bookRepo.Register(book)\n}\n\nfunc (lib *Library) CreateUser(user User) {\n\tlib.userRepo.Register(user)\n}\n\nfunc (lib *Library) RegisterLoanBook(userDoi, bookTitle string) {\n\tuser := lib.userRepo.FindByDoi(userDoi)\n\tbook := lib.bookRepo.FindByTitle(bookTitle)\n\tif user == nil && book == nil {\n\t\tfmt.Println(\"usuario o book no está registrado\")\n\t}\n\tlib.loanRepo.LoanBook(userDoi, bookTitle)\n\tlib.bookRepo.IncreaseCopies(bookTitle, -1)\n}\n\nfunc (lib *Library) RegisterReturnBook(userDoi, bookTitle string) {\n\tuser := lib.userRepo.FindByDoi(userDoi)\n\tbook := lib.bookRepo.FindByTitle(bookTitle)\n\tif user == nil && book == nil {\n\t\tfmt.Println(\"usuario o book no está registrado\")\n\t}\n\tlib.loanRepo.ReturnBook(userDoi, bookTitle)\n\tlib.bookRepo.IncreaseCopies(bookTitle, +1)\n\n}\n\nfunc main() {\n\t/*library := Library{\n\t\tbooks:     []Book{},\n\t\tusers:     []User{},\n\t\tloanBooks: make(map[string][]string),\n\t}\n\tlibrary.AddUser(&User{doi: \"44557855\", name: \"Amador\", email: \"aquispe@gmail.com\"})\n\tlibrary.AddBook(&Book{title: \"clean code\", author: \"Robert C. Martin\", copies: 4})\n\tlibrary.LoanBook(\"clean code\", \"44557855\")\n\tfmt.Println(library.books)\n\tlibrary.ReturnBook(\"clean code\", \"44557855\")\n\tfmt.Println(library.books)*/\n\tbookRepo := BookRepository{\n\t\tbooks: []Book{},\n\t}\n\n\tuserRepo := UserRepository{\n\t\tusers: []User{},\n\t}\n\n\tloanRepo := LoanRepository{\n\t\tloanBooks: make(map[string][]string),\n\t}\n\n\tlibrary := Library{\n\t\tbookRepo: bookRepo,\n\t\tuserRepo: userRepo,\n\t\tloanRepo: loanRepo,\n\t}\n\n\tlibrary.CreateBook(Book{title: \"clean code\", author: \"Robert C. Martin\", copies: 4})\n\tlibrary.CreateBook(Book{title: \"clean architecture\", author: \"Robert C. Martin\", copies: 4})\n\n\tlibrary.CreateUser(User{doi: \"44557855\", name: \"Amador\", email: \"aquispe@gmail.com\"})\n\tlibrary.CreateUser(User{doi: \"44775588\", name: \"Alex\", email: \"alex@gmail.com\"})\n\n\tlibrary.RegisterLoanBook(\"44557855\", \"clean code\")\n\tfmt.Println(library.bookRepo.books)\n\n\tlibrary.RegisterReturnBook(\"44557855\", \"clean code\")\n\tfmt.Println(library.bookRepo.books)\n\n}\n\n//Viola SRP\n/*type Employee struct {\n\tid    int\n\tname  string\n\temail string\n}\n\nfunc (e *Employee) GetName() string {\n\treturn e.name\n}\n\nfunc (e *Employee) GetEmail() string {\n\treturn e.email\n}\n\nfunc (e *Employee) SaveToDatabase() {\n\tfmt.Println(\"saving data in database!! \", e)\n}\n\nfunc (e *Employee) SendNotification() {\n\tfmt.Println(\"sending notification \", e.email)\n}*/\n\n//EXTRA\n//Viola SRP\n/*\ntype Book struct {\n\ttitle  string\n\tauthor string\n\tcopies uint\n}\n\ntype User struct {\n\tdoi   string\n\tname  string\n\temail string\n}\n\ntype Library struct {\n\tbooks     []Book\n\tusers     []User\n\tloanBooks map[string][]string\n}\n\nfunc (l *Library) AddUser(user *User) {\n\tl.users = append(l.users, *user)\n}\n\nfunc (l *Library) AddBook(book *Book) {\n\tl.books = append(l.books, *book)\n}\n\nfunc (l *Library) LoanBook(bookTitle, userDoi string) {\n\tvar userFound *User\n\tvar bookFound *Book\n\tfor i, user := range l.users {\n\t\tif user.doi == userDoi {\n\t\t\tuserFound = &l.users[i]\n\t\t\tbreak\n\t\t}\n\t}\n\n\tfor i, book := range l.books {\n\t\tif book.title == bookTitle {\n\t\t\tbookFound = &l.books[i]\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif userFound == nil || bookFound == nil {\n\t\tfmt.Println(\"usuario o libro no está registrada\")\n\t\treturn\n\t}\n\n\tif bookFound.copies <= 0 {\n\t\tfmt.Println(\"no copias disponibles\")\n\t\treturn\n\t}\n\n\tif v, ok := l.loanBooks[userDoi]; ok {\n\t\tv = append(v, bookTitle)\n\t\tl.loanBooks[userDoi] = v\n\t} else {\n\t\tl.loanBooks[userDoi] = []string{bookTitle}\n\t}\n\tbookFound.copies--\n\tfmt.Println(\"préstamo del libro \", bookTitle, \" al usuario \", userDoi, \"fué registrado.\")\n}\n\nfunc (l *Library) ReturnBook(bookTitle, userDoi string) {\n\tvar bookFound *Book\n\tfor i, book := range l.books {\n\t\tif book.title == bookTitle {\n\t\t\tbookFound = &l.books[i]\n\t\t\tbreak\n\t\t}\n\t}\n\tfor key, values := range l.loanBooks {\n\t\tif key == userDoi {\n\t\t\tvar newList []string\n\t\t\tfor _, v := range values {\n\t\t\t\tif v != bookTitle {\n\t\t\t\t\tnewList = append(newList, v)\n\t\t\t\t}\n\t\t\t}\n\t\t\tbookFound.copies++\n\t\t\tl.loanBooks[userDoi] = newList\n\t\t\tfmt.Println(\"Libro devuelto correctamente\")\n\t\t\tbreak\n\t\t}\n\t}\n}\n*/\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/go/hozlucas28.go",
    "content": "package main\n\nimport \"fmt\"\n\n/* -------------------------------------------------------------------------- */\n/*                                   CLASSES                                  */\n/* -------------------------------------------------------------------------- */\n\n/* --------------------------------- BadUser -------------------------------- */\n\ntype BadUser struct {\n\tEmail     string\n\tFirstName string\n\tLastName  string\n}\n\nfunc (user *BadUser) Save() error {\n\tfmt.Println(\"User saved!\")\n\treturn nil\n}\n\nfunc (user *BadUser) SendEmail() error {\n\tfmt.Println(\"Email sent!\")\n\treturn nil\n}\n\n/* -------------------------------- GoodUser -------------------------------- */\n\ntype GoodUser struct {\n\tEmail     string\n\tFirstName string\n\tLastName  string\n}\n\n/* ------------------------------ EmailService ------------------------------ */\n\ntype EmailService struct{}\n\nfunc (emailService *EmailService) Send() error {\n\tfmt.Println(\"Email sent!\")\n\treturn nil\n}\n\n/* ----------------------------- DatabaseService ---------------------------- */\n\ntype DatabaseService struct{}\n\nfunc (databaseService *DatabaseService) SaveUser() error {\n\tfmt.Println(\"User saved!\")\n\treturn nil\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\nfunc main() {\n\t/*\n\t\tSingle Responsibility Principle (SRP)...\n\t*/\n\n\tfmt.Println(\"Single Responsibility Principle (SRP)...\")\n\n\tfmt.Println(\n\t\t\"\\n```\",\n\t\t\"\\ntype BadUser struct {\\n  Email  string\\n  FirstName  string\\n  LastName  string\\n}\",\n\t\t\"\\n\\nfunc (user *BadUser) Save() error {\\n  fmt.Println(\\\"User saved!\\\")\\n  return nil\\n}\",\n\t\t\"\\n\\nfunc (user *BadUser) SendEmail() error {\\n  fmt.Println(\\\"Email sent!\\\")\\n  return nil\\n}\",\n\t\t\"\\n```\",\n\t)\n\n\tfmt.Println(\"\\nBad implementation of Single Responsibility Principle (SRP)...\")\n\n\tfmt.Println(\n\t\t\"\\n```\",\n\t\t\"\\ntype GoodUser struct {\\n  Email  string\\n  FirstName  string\\n  LastName string\\n}\",\n\t\t\"\\n\\ntype EmailService struct{}\",\n\t\t\"\\n\\nfunc (emailService *EmailService) Send() error {\\n  fmt.Println(\\\"Email sent!\\\")\\n  return nil\\n}\",\n\t\t\"\\n\\ntype DatabaseService struct{}\",\n\t\t\"\\n\\nfunc (databaseService *DatabaseService) SaveUser() error {\\n  fmt.Println(\\\"User saved!\\\")\\n  return nil\\n}\",\n\t\t\"\\n```\",\n\t)\n\n\tfmt.Println(\n\t\t\"\\nThis is a bad implementation of Single Responsibility Principle (SRP),\",\n\t\t\"\\nbecause the class 'BadUser' has three responsibilities:\",\n\t\t\"\\n\\n1°) User creation.\",\n\t\t\"\\n2°) Data persistence of the user.\",\n\t\t\"\\n3°) User notification.\",\n\t)\n\n\tfmt.Println(\"\\nGood implementation of Single Responsibility Principle (SRP)...\")\n\n\tfmt.Print(\n\t\t\"\\nThis is a good implementation of Single Responsibility Principle (SRP),\",\n\t\t\"\\nbecause each class ('GoodUser', 'EmailService', and 'DatabaseService') has only\",\n\t\t\"\\none responsability (user creation, notifications service, and data persistance).\",\n\t)\n}\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/go/kodenook.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\ntype TextStorage struct {\n\tcontent string\n}\n\nfunc (ts *TextStorage) AddText(text string) {\n\tts.content += text + \"\\n\"\n}\n\nfunc (ts *TextStorage) GetText() string {\n\treturn ts.content\n}\n\ntype TextFormatter struct{}\n\nfunc (tf *TextFormatter) UpperCase(text string) string {\n\treturn strings.ToUpper(text)\n}\n\nfunc (tf *TextFormatter) LowerCase(text string) string {\n\treturn strings.ToLower(text)\n}\n\nfunc main() {\n\tstorage := &TextStorage{}\n\tformatter := &TextFormatter{}\n\n\tstorage.AddText(\"Hello, Go\")\n\tstorage.AddText(\"This is a example\")\n\n\tfmt.Println(\"Text:\")\n\tfmt.Println(storage.GetText())\n\n\tfmt.Println(\"Text on uppercase:\")\n\tfmt.Println(formatter.UpperCase(storage.GetText()))\n\n\tfmt.Println(\"Text on lowercase:\")\n\tfmt.Println(formatter.LowerCase(storage.GetText()))\n}\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/go/qwik-zgheib.go",
    "content": "package main\n\nimport \"fmt\"\n\n/* -- Exercise */\n\ntype User struct {\n\tName  string\n\tEmail string\n}\n\n/* -- exercise -- incorrect */\n\nfunc (u *User) Save() {\n\tfmt.Printf(\"Saving user %s to the database\\n\", u.Name)\n}\n\nfunc (u *User) SendEmail() {\n\tfmt.Printf(\"Sending email to %s\\n\", u.Email)\n}\n\n/* -- exercise -- correct */\n\ntype UserRepository struct{}\n\nfunc (repo *UserRepository) Save(user User) {\n\tfmt.Printf(\"Saving user %s to the database\\n\", user.Name)\n}\n\ntype EmailService struct{}\n\nfunc (service *EmailService) SendEmail(user User) {\n\tfmt.Printf(\"Sending email to %s\\n\", user.Email)\n}\n\n/* -- Extra Challenge */\n\ntype Book struct {\n\tTitle  string\n\tAuthor string\n\tCopies int\n}\n\ntype UserT struct {\n\tName  string\n\tID    string\n\tEmail string\n}\n\n/* -- extra challenge - incorrect */\n\ntype Library struct {\n\tBooks []Book\n\tUsers []UserT\n\tLoans map[string]string // map[userID]bookTitle\n}\n\nfunc (lib *Library) AddBook(book Book) {\n\tlib.Books = append(lib.Books, book)\n\tfmt.Printf(\"Book '%s' by '%s' added to the library.\\n\", book.Title, book.Author)\n}\n\nfunc (lib *Library) AddUser(user UserT) {\n\tlib.Users = append(lib.Users, user)\n\tfmt.Printf(\"User '%s' added to the library.\\n\", user.Name)\n}\n\nfunc (lib *Library) LoanBook(userID, bookTitle string) {\n\tlib.Loans[userID] = bookTitle\n\tfmt.Printf(\"User '%s' loaned book '%s'.\\n\", userID, bookTitle)\n}\n\n/* -- extra challenge - correct */\n\ntype BookRepositoryC struct {\n\tBooks []Book\n}\n\nfunc (repo *BookRepositoryC) AddBook(book Book) {\n\trepo.Books = append(repo.Books, book)\n\tfmt.Printf(\"Book '%s' by '%s' added to the library.\\n\", book.Title, book.Author)\n}\n\ntype UserRepositoryC struct {\n\tUsers []UserT\n}\n\nfunc (repo *UserRepositoryC) AddUserC(user UserT) {\n\trepo.Users = append(repo.Users, user)\n\tfmt.Printf(\"User '%s' added to the library.\\n\", user.Name)\n}\n\ntype LoanService struct {\n\tLoans map[string]string // map[userID]bookTitle\n}\n\nfunc (service *LoanService) LoanBook(userID, bookTitle string) {\n\tservice.Loans[userID] = bookTitle\n\tfmt.Printf(\"User '%s' loaned book '%s'.\\n\", userID, bookTitle)\n}\n\nfunc main() {\n\t/* Exercise */\n\tuser := User{Name: \"Legion Commander\", Email: \"legioncommander@gmail.com\"}\n\t/* -- incorrect use */\n\tuser.Save()\n\tuser.SendEmail()\n\n\t/* -- correct use */\n\tuserRepo := UserRepository{}\n\tuserRepo.Save(user)\n\n\temailService := EmailService{}\n\temailService.SendEmail(user)\n\n\t/* Extra Challenge */\n\t/* -- incorrect use */\n\tlibrary := &Library{\n\t\tBooks: []Book{},\n\t\tUsers: []UserT{},\n\t\tLoans: make(map[string]string),\n\t}\n\n\tlibrary.AddBook(Book{Title: \"1984\", Author: \"George Orwell\", Copies: 3})\n\tlibrary.AddUser(UserT{Name: \"Legion Commander\", ID: \"xyz-123\", Email: \"legioncommander@gmail.com\"})\n\tlibrary.LoanBook(\"xyz-123\", \"1984\")\n\n\t/* -- correct use */\n\tbookRepoC := &BookRepositoryC{Books: []Book{}}\n\tuserRepoC := &UserRepositoryC{Users: []UserT{}}\n\tloanService := &LoanService{Loans: make(map[string]string)}\n\n\tbookRepoC.AddBook(Book{Title: \"1984\", Author: \"George Orwell\", Copies: 3})\n\tuserRepoC.AddUserC(UserT{Name: \"Legion Commander\", ID: \"xyz-123\", Email: \"legioncommander@gmail.com\"})\n\tloanService.LoanBook(\"123\", \"1984\")\n}\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/go/raynerpv2022.go",
    "content": "package main\n\nimport \"fmt\"\n\n// * EJERCICIO:\n//  * Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n//  * Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n//  * de forma correcta e incorrecta.\n//  *\n//  * DIFICULTAD EXTRA (opcional):\n//  * Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n//  * manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n//  * y el procesamiento de préstamos de libros.\n//  * Requisitos:\n//  * 1. Registrar libros: El sistema debe permitir agregar nuevos libros con\n//  * información básica como título, autor y número de copias disponibles.\n//  * 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n//  * información básica como nombre, número de identificación y correo electrónico.\n//  * 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n//  * tomar prestados y devolver libros.\n//  * Instrucciones:\n//  * 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n//  * los tres aspectos mencionados anteriormente (registro de libros, registro de\n//  * usuarios y procesamiento de préstamos).\n//  * 2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n//  * siguiendo el Principio de Responsabilidad Única.\n\ntype Book struct {\n\ttitle  string\n\tauthor string\n\tcopie  int\n}\n\n// *********************************\n\ntype User struct {\n\tname  string\n\tid    int\n\temail string\n}\n\n// ***********************\n\ntype Loan struct {\n\tloans map[string][]string\n}\n\nfunc (l *Loan) CreateLoan(u string, b string) {\n\tl.loans[b] = append(l.loans[b], u)\n}\n\nfunc (l *Loan) DeleteLoan(b string) {\n\tif len((l.loans[b])) == 1 {\n\t\tdelete(l.loans, b)\n\n\t} else {\n\t\tl.loans[b] = l.loans[b][1:]\n\t}\n\n}\n\n// ***********************\ntype Library struct {\n\tbooks []Book\n\tusers []User\n\tloans Loan\n}\n\nfunc (l *Library) AddLoan(b *Book, u User) {\n\tif b.copie == 0 {\n\t\tfmt.Printf(\"Libro %v No hay copias disponibles para Prestar : copias %v\\n\", b.title, b.copie)\n\t\treturn\n\t} else {\n\t\tb.copie -= 1\n\t}\n\n\tif l.loans.loans == nil {\n\t\tl.loans.loans = map[string][]string{}\n\t}\n\n\tl.loans.CreateLoan(u.name, b.title)\n}\n\nfunc (l *Library) DeleteLoan(b *Book) {\n\n\tl.loans.DeleteLoan(b.title)\n\tb.copie += 1\n}\n\nfunc (l *Library) AddUser(u User) {\n\n\tl.users = append(l.users, u)\n}\n\nfunc (l *Library) AddBook(b Book) {\n\n\tl.books = append(l.books, b)\n}\n\n// **********************************\n\ntype PrintService struct {\n}\n\nfunc (p PrintService) PrintBook(b Book) {\n\tfmt.Printf(\"Libro ** Titulo : %v Autor %v, Copias %v\\n\", b.title, b.author, b.copie)\n}\n\nfunc (p PrintService) PrintUser(u User) {\n\tfmt.Printf(\"Usuario ** Nombre : %s, Id %v, email %s\\n\", u.name, u.id, u.email)\n}\n\nfunc (p PrintService) ListUser(lu []User) {\n\tfmt.Println(\"Lista de Usuarios\")\n\tfor _, v := range lu {\n\t\tp.PrintUser(v)\n\t}\n\n}\n\nfunc (p PrintService) ListBook(lb []Book) {\n\tfmt.Println(\"Lista de Libros\")\n\tfor _, v := range lb {\n\t\tp.PrintBook(v)\n\t}\n}\nfunc (p PrintService) ListLoan(ln Loan) {\n\tfmt.Println(\"Lista de Prestamos\")\n\tfor i, v := range ln.loans {\n\t\tfmt.Printf(\"Libro: %v : \", i)\n\t\tfor _, l := range v {\n\t\t\tfmt.Printf(\"%v, \", l)\n\t\t}\n\t}\n\tfmt.Println()\n}\n\nfunc main() {\n\tB1 := Book{\"b1\", \"www\", 3}\n\tU1 := User{\"U1\", 111, \"dd@dsds\"}\n\tB2 := Book{\"B2\", \"www\", 3}\n\tU2 := User{\"U2\", 111, \"dd@dsds\"}\n\tL := Library{}\n\tL.AddBook(B1)\n\tL.AddBook(B2)\n\tL.AddUser(U1)\n\tL.AddUser(U2)\n\tL.AddLoan(&B1, U1)\n\tL.AddLoan(&B2, U2)\n\tPrintService{}.ListBook(L.books)\n\tPrintService{}.ListUser(L.users)\n\tPrintService{}.PrintBook(B1)\n\tPrintService{}.PrintUser(U1)\n\tPrintService{}.ListLoan(L.loans)\n\tPrintService{}.ListLoan(L.loans)\n\tL.AddLoan(&B1, U1)\n\tL.AddLoan(&B2, U1)\n\tL.AddLoan(&B1, U1)\n\tL.AddLoan(&B1, U1)\n\tL.AddLoan(&B2, U1)\n\tL.AddLoan(&B2, U1)\n\tPrintService{}.ListLoan(L.loans)\n\tPrintService{}.PrintBook(B1)\n\tPrintService{}.PrintBook(B2)\n\tL.DeleteLoan(&B2) // elimina el primer prestado, no es objetivo este paso en este ejercicio\n\tPrintService{}.ListLoan(L.loans)\n\tPrintService{}.PrintBook(B1)\n\tPrintService{}.PrintBook(B2)\n\n}\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/java/AmadorQuispe.java",
    "content": "package com.amsoft.roadmap.example26;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\npublic class Example26 {\n    public static void main(String[] args) {\n        Employee employee = new Employee(100, \"Amador Quispe\", \"correo@gmail.com\");\n        EmployeeRepository userRepository = new EmployeeRepository();\n        userRepository.save(employee);\n        EmployeeService userService = new EmployeeService();\n        userService.sendMail(employee);\n\n        /*Library library = new Library();\n        library.registerUser(new User(\"47229145\", \"Amador Quispe\", \"aquispe@gmail.com\"));\n        library.registerBook(new Book(\"Clean Code\", \"Robert C. Martin\", 4));\n        library.registerBook(new Book(\"Clean Architecture\", \"Robert C. Martin\", 5));\n        library.registerBook(new Book(\"Clean Agile\", \"Robert C. Martin\", 8));\n        library.loanBook(\"Clean Code\", \"47229145\");\n        library.books.forEach(s -> System.out.println(s.getCopiesAvailable()));\n        library.returnLoanBook(\"Clean Code\", \"47229145\");\n        library.books.forEach(s -> System.out.println(s.getCopiesAvailable()));*/\n        SRPLibrary srpLibrary = new SRPLibrary();\n        srpLibrary.run();\n    }\n\n}\n\n//Viola SRP\n/*class User {\n    private Integer id;\n    private String names;\n    private String email;\n\n    public User(Integer id, String names, String email) {\n        this.id = id;\n        this.names = names;\n        this.email = email;\n    }\n\n    @Override\n    public String toString() {\n        return \"User{\" +\n                \"id=\" + id +\n                \", names='\" + names + '\\'' +\n                \", email='\" + email + '\\'' +\n                '}';\n    }\n\n    public void saveInDB(){\n        System.out.println(\"Guardando en la base de datos : \" + this);\n    }\n    public void sendNotification(){\n        System.out.println(\"Enviando notificación al correo: \" + email);\n    }\n\n    public Integer getId() {\n        return id;\n    }\n\n    public void setId(Integer id) {\n        this.id = id;\n    }\n\n    public String getNames() {\n        return names;\n    }\n\n    public void setNames(String names) {\n        this.names = names;\n    }\n\n    public String getEmail() {\n        return email;\n    }\n\n    public void setEmail(String email) {\n        this.email = email;\n    }\n}*/\nclass Employee {\n    private Integer id;\n    private String names;\n    private String email;\n\n    public Employee(Integer id, String names, String email) {\n        this.id = id;\n        this.names = names;\n        this.email = email;\n    }\n\n    @Override\n    public String toString() {\n        return \"User{\" +\n                \"id=\" + id +\n                \", names='\" + names + '\\'' +\n                \", email='\" + email + '\\'' +\n                '}';\n    }\n\n    public Integer getId() {\n        return id;\n    }\n\n    public void setId(Integer id) {\n        this.id = id;\n    }\n\n    public String getNames() {\n        return names;\n    }\n\n    public void setNames(String names) {\n        this.names = names;\n    }\n\n    public String getEmail() {\n        return email;\n    }\n\n    public void setEmail(String email) {\n        this.email = email;\n    }\n}\n\nclass EmployeeRepository {\n    public void save(Employee employee) {\n        System.out.println(\"Guardando user en base de datos : \" + employee.toString());\n    }\n}\n\nclass EmployeeService {\n    public void sendMail(Employee employee) {\n        System.out.println(\"Enviando mensaje de notificación al correo :\" + employee.getEmail());\n    }\n}\n\n//Viola SRP\n/*class Library {\n    private final Map<String, List<String>> loanBooks;\n    public List<Book> books;\n    public List<User> users;\n\n    Library() {\n        this.books = new ArrayList<>();\n        this.users = new ArrayList<>();\n        this.loanBooks = new HashMap<>();\n    }\n\n    public void registerBook(Book book) {\n        books.add(book);\n    }\n\n    public void registerUser(User user) {\n        users.add(user);\n    }\n\n    public void loanBook(String bookTitle, String userDoi) {\n        User user = users.stream().filter(u -> u.getDoi().equals(userDoi)).findFirst().orElse(null);\n        Book book = books.stream().filter(b -> b.getTitle().equalsIgnoreCase(bookTitle)).findFirst().orElse(null);\n        if (user == null || book == null) {\n            System.out.println(\"Usuario o Libro no está registrado\");\n            return;\n        }\n\n        if (book.getCopiesAvailable() == 0) {\n            System.out.println(\"No hay copias disponibles\");\n        } else {\n            var loanUsers = loanBooks.get(userDoi);\n            if (loanUsers == null) {\n                loanUsers = new ArrayList<>();\n            }\n            loanUsers.add(bookTitle);\n            loanBooks.put(userDoi, loanUsers);\n            book.setCopiesAvailable(book.getCopiesAvailable() - 1);\n        }\n    }\n\n    public void returnLoanBook(String bookTitle, String userDoi) {\n        User user = users.stream().filter(u -> u.getDoi().equals(userDoi)).findFirst().orElse(null);\n        Book book = books.stream().filter(b -> b.getTitle().equalsIgnoreCase(bookTitle)).findFirst().orElse(null);\n        if (user == null || book == null) {\n            System.out.println(\"Usuario o Libro no está registrado\");\n            return;\n        }\n        var loanUsers = loanBooks.get(userDoi);\n        if (loanUsers == null) {\n            System.out.println(\"El préstamo no está registrada\");\n        } else {\n            loanBooks.put(userDoi, loanUsers.stream().filter(lu -> !lu.equalsIgnoreCase(bookTitle)).toList());\n            book.setCopiesAvailable(book.getCopiesAvailable() + 1);\n        }\n    }\n}\n*/\nclass Book {\n    private String title;\n    private String author;\n    private int copiesAvailable;\n\n    public Book() {\n    }\n\n    public Book(String title, String author, int copiesAvailable) {\n        this.title = title;\n        this.author = author;\n        this.copiesAvailable = copiesAvailable;\n    }\n\n    public String getTitle() {\n        return title;\n    }\n\n    public void setTitle(String title) {\n        this.title = title;\n    }\n\n    public String getAuthor() {\n        return author;\n    }\n\n    public void setAuthor(String author) {\n        this.author = author;\n    }\n\n    public int getCopiesAvailable() {\n        return copiesAvailable;\n    }\n\n    public void setCopiesAvailable(int copiesAvailable) {\n        this.copiesAvailable = copiesAvailable;\n    }\n}\n\nclass User {\n    private String doi;\n    private String name;\n    private String email;\n\n    public User() {\n    }\n\n    public User(String doi, String name, String email) {\n        this.name = name;\n        this.doi = doi;\n        this.email = email;\n    }\n\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public String getDoi() {\n        return doi;\n    }\n\n    public void setDoi(String doi) {\n        this.doi = doi;\n    }\n\n    public String getEmail() {\n        return email;\n    }\n\n    public void setEmail(String email) {\n        this.email = email;\n    }\n}\n\nclass SRPLibrary{\n    private final LoanService loanService;\n    private final UserService userService;\n    private final BookService bookService;\n    public SRPLibrary(){\n        UserRepository userRepository = new UserRepository();\n        BookRepository bookRepository =  new BookRepository();\n        LoanBookRepository loanBookRepository =  new LoanBookRepository();\n        this.loanService = new LoanService(userRepository,bookRepository,loanBookRepository);\n        this.userService = new UserService(userRepository);\n        this.bookService = new BookService(bookRepository);\n    }\n    public void run(){\n        userService.register(new User(\"44445555\",\"Amador Quispe\",\"amador@gmail.com\"));\n        userService.register(new User(\"44446666\",\"Alex\",\"alex@gmail.com\"));\n        bookService.register(new Book(\"Clean Code\", \"Robert C. Martin\", 4));\n        bookService.register(new Book(\"Clean Architecture\", \"Robert C. Martin\", 5));\n        bookService.register(new Book(\"Clean Agile\", \"Robert C. Martin\", 8));\n\n        loanService.registerLoan(\"Clean Code\",\"44445555\");\n        loanService.registerLoan(\"Clean Architecture\",\"44446666\");\n        System.out.println(\"PRESTAMOS\");\n        loanService.findAll().forEach((k,v)-> System.out.println(k + \" tiene en préstamo los libros: \"+v));\n    }\n}\n//SERVICIOS, LÓGICA DE NEGOCIO\nclass UserService {\n    private final UserRepository userRepository;\n    public UserService(UserRepository userRepository){\n        this.userRepository = userRepository;\n    }\n    public void register(User user){\n        userRepository.register(user);\n    }\n    public void findByDoi( String doi ){\n        userRepository.findByDoi(doi);\n    }\n}\nclass BookService {\n    private final BookRepository bookRepository;\n    public BookService(BookRepository bookRepository){\n        this.bookRepository = bookRepository;\n    }\n    public void register(Book book){\n        bookRepository.register(book);\n    }\n    public void findByDoi( String doi ){\n        bookRepository.findByTitle(doi);\n    }\n}\nclass LoanService {\n    private final UserRepository userRepository;\n    private final BookRepository bookRepository;\n    private final LoanBookRepository loanBookRepository;\n\n    public LoanService(UserRepository userRepository, BookRepository bookRepository, LoanBookRepository loanBookRepository) {\n        this.userRepository = userRepository;\n        this.bookRepository = bookRepository;\n        this.loanBookRepository = loanBookRepository;\n    }\n\n    public void registerLoan(String bookTitle, String userDoi) {\n        User user = userRepository.findByDoi(userDoi);\n        Book book = bookRepository.findByTitle(bookTitle);\n        System.out.println(user);\n        System.out.println(book);\n        if (user == null || book == null) {\n            System.out.println(\"Usuario o Libro no está registrado\");\n            return;\n        }\n        if (book.getCopiesAvailable() == 0) {\n            System.out.println(\"No hay copias disponibles\");\n        } else {\n            loanBookRepository.registerLoan(bookTitle,userDoi);\n            book.setCopiesAvailable(book.getCopiesAvailable() - 1);\n        }\n    }\n    public void registerReturn(String bookTitle, String userDoi) {\n        User user = userRepository.findByDoi(userDoi);\n        Book book = bookRepository.findByTitle(bookTitle);\n        if (user == null || book == null) {\n            System.out.println(\"Usuario o Libro no está registrado\");\n            return;\n        }\n        loanBookRepository.registerReturn(bookTitle,userDoi);\n        book.setCopiesAvailable(book.getCopiesAvailable() + 1);\n    }\n    public Map<String, List<String>> findAll(){\n        return loanBookRepository.findAll();\n    }\n}\n//REPOSITORIOS, ENCARGADOS DE GUARDAR\nclass UserRepository {\n    private final List<User> userList = new ArrayList<>();\n\n    public void register(User user) {\n        userList.add(user);\n    }\n\n    public User findByDoi(String doi) {\n        return userList.stream().filter(u -> u.getDoi().equals(doi)).findFirst().orElse(null);\n    }\n}\nclass BookRepository {\n    private final List<Book> bookList = new ArrayList<>();\n\n    public void register(Book book) {\n        bookList.add(book);\n    }\n\n    public Book findByTitle(String title) {\n        return bookList.stream().filter(b -> b.getTitle().equalsIgnoreCase(title))\n                .findFirst().orElse(null);\n    }\n}\nclass LoanBookRepository {\n    private final Map<String, List<String>> loanBooks;\n\n    public LoanBookRepository() {\n        this.loanBooks = new HashMap<>();\n    }\n\n    public void registerLoan(String bookTitle, String userDoi) {\n        List<String> loanUsers = loanBooks.get(userDoi);\n        if (loanUsers == null) {\n            loanUsers = new ArrayList<>();\n        }\n        loanUsers.add(bookTitle);\n        loanBooks.put(userDoi, loanUsers);\n    }\n    public void registerReturn(String bookTitle, String userDoi){\n        List<String> loanUsers = loanBooks.get(userDoi);\n        if (loanUsers == null) {\n            System.out.println(\"El préstamo no está registrada\");\n        } else {\n            loanBooks.put(userDoi, loanUsers.stream().filter(lu -> !lu.equalsIgnoreCase(bookTitle)).toList());\n        }\n    }\n    public Map<String, List<String>> findAll(){\n        return loanBooks;\n    }\n}\n\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/java/AnaLauDB.java",
    "content": "import java.util.logging.*;\nimport java.util.*;\nimport java.io.IOException;\n\npublic class AnaLauDB {\n\n    // Logger para la clase\n    private static final Logger logger = Logger.getLogger(AnaLauDB.class.getName());\n\n    // ==========================================================================\n    // 1. DISEÑO QUE NO CUMPLE SRP - CLASE MONOLÍTICA\n    // ==========================================================================\n    static class LibraryViolaSRP {\n        private List<String[]> libros; // [titulo, autor, copias_disponibles]\n        private List<String[]> usuarios; // [nombre, id, email]\n        private List<String[]> prestamos; // [usuario_id, libro_titulo, fecha]\n        private Logger logger;\n\n        public LibraryViolaSRP() {\n            this.libros = new ArrayList<>();\n            this.usuarios = new ArrayList<>();\n            this.prestamos = new ArrayList<>();\n            this.logger = Logger.getLogger(LibraryViolaSRP.class.getName());\n        }\n\n        // Responsabilidad 1: Gestión de libros\n        public void registrarLibro(String titulo, String autor, int copias) {\n            logger.info(\"Registrando libro: \" + titulo);\n            libros.add(new String[] { titulo, autor, String.valueOf(copias) });\n            System.out.println(\"Libro registrado: \" + titulo + \" por \" + autor);\n        }\n\n        public void mostrarLibros() {\n            logger.info(\"Mostrando todos los libros\");\n            System.out.println(\"=== Libros Disponibles ===\");\n            for (String[] libro : libros) {\n                System.out.printf(\"Título: %s, Autor: %s, Copias: %s%n\",\n                        libro[0], libro[1], libro[2]);\n            }\n        }\n\n        // Responsabilidad 2: Gestión de usuarios\n        public void registrarUsuario(String nombre, String id, String email) {\n            logger.info(\"Registrando usuario: \" + nombre);\n            usuarios.add(new String[] { nombre, id, email });\n            System.out.println(\"Usuario registrado: \" + nombre);\n        }\n\n        public void mostrarUsuarios() {\n            logger.info(\"Mostrando todos los usuarios\");\n            System.out.println(\"=== Usuarios Registrados ===\");\n            for (String[] usuario : usuarios) {\n                System.out.printf(\"Nombre: %s, ID: %s, Email: %s%n\",\n                        usuario[0], usuario[1], usuario[2]);\n            }\n        }\n\n        // Responsabilidad 3: Gestión de préstamos\n        public boolean prestarLibro(String usuarioId, String tituloLibro) {\n            logger.info(\"Procesando préstamo: \" + tituloLibro + \" para usuario \" + usuarioId);\n\n            // Verificar si el usuario existe\n            boolean usuarioExiste = false;\n            for (String[] usuario : usuarios) {\n                if (usuario[1].equals(usuarioId)) {\n                    usuarioExiste = true;\n                    break;\n                }\n            }\n\n            if (!usuarioExiste) {\n                logger.warning(\"Usuario no encontrado: \" + usuarioId);\n                return false;\n            }\n\n            // Verificar disponibilidad del libro\n            for (String[] libro : libros) {\n                if (libro[0].equals(tituloLibro)) {\n                    int copias = Integer.parseInt(libro[2]);\n                    if (copias > 0) {\n                        libro[2] = String.valueOf(copias - 1);\n                        prestamos.add(new String[] { usuarioId, tituloLibro, new Date().toString() });\n                        System.out.println(\"Préstamo realizado exitosamente\");\n                        return true;\n                    }\n                }\n            }\n\n            logger.warning(\"Libro no disponible: \" + tituloLibro);\n            return false;\n        }\n\n        public boolean devolverLibro(String usuarioId, String tituloLibro) {\n            logger.info(\"Procesando devolución: \" + tituloLibro + \" del usuario \" + usuarioId);\n\n            // Buscar el préstamo\n            for (int i = 0; i < prestamos.size(); i++) {\n                String[] prestamo = prestamos.get(i);\n                if (prestamo[0].equals(usuarioId) && prestamo[1].equals(tituloLibro)) {\n                    prestamos.remove(i);\n\n                    // Aumentar copias disponibles\n                    for (String[] libro : libros) {\n                        if (libro[0].equals(tituloLibro)) {\n                            int copias = Integer.parseInt(libro[2]);\n                            libro[2] = String.valueOf(copias + 1);\n                            break;\n                        }\n                    }\n                    System.out.println(\"Devolución realizada exitosamente\");\n                    return true;\n                }\n            }\n\n            logger.warning(\"Préstamo no encontrado para devolución\");\n            return false;\n        }\n    }\n\n    // ==========================================================================\n    // 2. REFACTORIZACIÓN SIGUIENDO SRP\n    // ==========================================================================\n\n    // Clase para representar un Libro\n    static class Libro {\n        private String titulo;\n        private String autor;\n        private int copiasDisponibles;\n\n        public Libro(String titulo, String autor, int copiasDisponibles) {\n            this.titulo = titulo;\n            this.autor = autor;\n            this.copiasDisponibles = copiasDisponibles;\n        }\n\n        // Getters y setters\n        public String getTitulo() {\n            return titulo;\n        }\n\n        public String getAutor() {\n            return autor;\n        }\n\n        public int getCopiasDisponibles() {\n            return copiasDisponibles;\n        }\n\n        public void setCopiasDisponibles(int copias) {\n            this.copiasDisponibles = copias;\n        }\n\n        @Override\n        public String toString() {\n            return String.format(\"Libro{titulo='%s', autor='%s', copias=%d}\",\n                    titulo, autor, copiasDisponibles);\n        }\n    }\n\n    // Clase para representar un Usuario\n    static class Usuario {\n        private String nombre;\n        private String id;\n        private String email;\n\n        public Usuario(String nombre, String id, String email) {\n            this.nombre = nombre;\n            this.id = id;\n            this.email = email;\n        }\n\n        // Getters\n        public String getNombre() {\n            return nombre;\n        }\n\n        public String getId() {\n            return id;\n        }\n\n        public String getEmail() {\n            return email;\n        }\n\n        @Override\n        public String toString() {\n            return String.format(\"Usuario{nombre='%s', id='%s', email='%s'}\",\n                    nombre, id, email);\n        }\n    }\n\n    // Clase para representar un Préstamo\n    static class Prestamo {\n        private String usuarioId;\n        private String tituloLibro;\n        private Date fechaPrestamo;\n\n        public Prestamo(String usuarioId, String tituloLibro) {\n            this.usuarioId = usuarioId;\n            this.tituloLibro = tituloLibro;\n            this.fechaPrestamo = new Date();\n        }\n\n        // Getters\n        public String getUsuarioId() {\n            return usuarioId;\n        }\n\n        public String getTituloLibro() {\n            return tituloLibro;\n        }\n\n        public Date getFechaPrestamo() {\n            return fechaPrestamo;\n        }\n\n        @Override\n        public String toString() {\n            return String.format(\"Prestamo{usuarioId='%s', libro='%s', fecha=%s}\",\n                    usuarioId, tituloLibro, fechaPrestamo);\n        }\n    }\n\n    // Responsabilidad 1: Gestión de Libros\n    static class GestorLibros {\n        private List<Libro> libros;\n        private Logger logger;\n\n        public GestorLibros() {\n            this.libros = new ArrayList<>();\n            this.logger = Logger.getLogger(GestorLibros.class.getName());\n        }\n\n        public void registrarLibro(String titulo, String autor, int copias) {\n            logger.info(\"Registrando libro: \" + titulo);\n            Libro nuevoLibro = new Libro(titulo, autor, copias);\n            libros.add(nuevoLibro);\n            System.out.println(\"Libro registrado: \" + nuevoLibro);\n        }\n\n        public Libro buscarLibro(String titulo) {\n            for (Libro libro : libros) {\n                if (libro.getTitulo().equalsIgnoreCase(titulo)) {\n                    return libro;\n                }\n            }\n            return null;\n        }\n\n        public void mostrarLibros() {\n            logger.info(\"Mostrando todos los libros\");\n            System.out.println(\"=== Libros Disponibles ===\");\n            for (Libro libro : libros) {\n                System.out.println(libro);\n            }\n        }\n\n        public List<Libro> getLibros() {\n            return new ArrayList<>(libros);\n        }\n    }\n\n    // Responsabilidad 2: Gestión de Usuarios\n    static class GestorUsuarios {\n        private List<Usuario> usuarios;\n        private Logger logger;\n\n        public GestorUsuarios() {\n            this.usuarios = new ArrayList<>();\n            this.logger = Logger.getLogger(GestorUsuarios.class.getName());\n        }\n\n        public void registrarUsuario(String nombre, String id, String email) {\n            logger.info(\"Registrando usuario: \" + nombre);\n            Usuario nuevoUsuario = new Usuario(nombre, id, email);\n            usuarios.add(nuevoUsuario);\n            System.out.println(\"Usuario registrado: \" + nuevoUsuario);\n        }\n\n        public Usuario buscarUsuario(String id) {\n            for (Usuario usuario : usuarios) {\n                if (usuario.getId().equals(id)) {\n                    return usuario;\n                }\n            }\n            return null;\n        }\n\n        public void mostrarUsuarios() {\n            logger.info(\"Mostrando todos los usuarios\");\n            System.out.println(\"=== Usuarios Registrados ===\");\n            for (Usuario usuario : usuarios) {\n                System.out.println(usuario);\n            }\n        }\n    }\n\n    // Responsabilidad 3: Gestión de Préstamos\n    static class GestorPrestamos {\n        private List<Prestamo> prestamos;\n        private Logger logger;\n\n        public GestorPrestamos() {\n            this.prestamos = new ArrayList<>();\n            this.logger = Logger.getLogger(GestorPrestamos.class.getName());\n        }\n\n        public boolean prestarLibro(Usuario usuario, Libro libro) {\n            logger.info(\"Procesando préstamo: \" + libro.getTitulo() + \" para \" + usuario.getNombre());\n\n            if (libro.getCopiasDisponibles() > 0) {\n                libro.setCopiasDisponibles(libro.getCopiasDisponibles() - 1);\n                Prestamo nuevoPrestamo = new Prestamo(usuario.getId(), libro.getTitulo());\n                prestamos.add(nuevoPrestamo);\n                System.out.println(\"Préstamo realizado exitosamente: \" + nuevoPrestamo);\n                return true;\n            } else {\n                logger.warning(\"Libro no disponible: \" + libro.getTitulo());\n                System.out.println(\"No hay copias disponibles del libro: \" + libro.getTitulo());\n                return false;\n            }\n        }\n\n        public boolean devolverLibro(String usuarioId, String tituloLibro, Libro libro) {\n            logger.info(\"Procesando devolución: \" + tituloLibro + \" del usuario \" + usuarioId);\n\n            for (int i = 0; i < prestamos.size(); i++) {\n                Prestamo prestamo = prestamos.get(i);\n                if (prestamo.getUsuarioId().equals(usuarioId) &&\n                        prestamo.getTituloLibro().equalsIgnoreCase(tituloLibro)) {\n                    prestamos.remove(i);\n                    libro.setCopiasDisponibles(libro.getCopiasDisponibles() + 1);\n                    System.out.println(\"Devolución realizada exitosamente\");\n                    return true;\n                }\n            }\n\n            logger.warning(\"Préstamo no encontrado para devolución\");\n            System.out.println(\"No se encontró el préstamo para devolución\");\n            return false;\n        }\n\n        public void mostrarPrestamos() {\n            System.out.println(\"=== Préstamos Activos ===\");\n            for (Prestamo prestamo : prestamos) {\n                System.out.println(prestamo);\n            }\n        }\n    }\n\n    // Clase coordinadora que usa los gestores especializados\n    static class SistemaBiblioteca {\n        private GestorLibros gestorLibros;\n        private GestorUsuarios gestorUsuarios;\n        private GestorPrestamos gestorPrestamos;\n        private Logger logger;\n\n        public SistemaBiblioteca() {\n            this.gestorLibros = new GestorLibros();\n            this.gestorUsuarios = new GestorUsuarios();\n            this.gestorPrestamos = new GestorPrestamos();\n            this.logger = Logger.getLogger(SistemaBiblioteca.class.getName());\n        }\n\n        public void registrarLibro(String titulo, String autor, int copias) {\n            gestorLibros.registrarLibro(titulo, autor, copias);\n        }\n\n        public void registrarUsuario(String nombre, String id, String email) {\n            gestorUsuarios.registrarUsuario(nombre, id, email);\n        }\n\n        public boolean prestarLibro(String usuarioId, String tituloLibro) {\n            Usuario usuario = gestorUsuarios.buscarUsuario(usuarioId);\n            if (usuario == null) {\n                System.out.println(\"Usuario no encontrado\");\n                return false;\n            }\n\n            Libro libro = gestorLibros.buscarLibro(tituloLibro);\n            if (libro == null) {\n                System.out.println(\"Libro no encontrado\");\n                return false;\n            }\n\n            return gestorPrestamos.prestarLibro(usuario, libro);\n        }\n\n        public boolean devolverLibro(String usuarioId, String tituloLibro) {\n            Libro libro = gestorLibros.buscarLibro(tituloLibro);\n            if (libro == null) {\n                System.out.println(\"Libro no encontrado\");\n                return false;\n            }\n\n            return gestorPrestamos.devolverLibro(usuarioId, tituloLibro, libro);\n        }\n\n        public void mostrarTodo() {\n            gestorLibros.mostrarLibros();\n            System.out.println();\n            gestorUsuarios.mostrarUsuarios();\n            System.out.println();\n            gestorPrestamos.mostrarPrestamos();\n        }\n    }\n\n    public static void main(String[] args) {\n        // Configurar logging\n        Logger.getLogger(\"\").setLevel(Level.INFO);\n\n        System.out.println(\"=== DEMOSTRACIÓN: CLASE QUE VIOLA SRP ===\");\n        LibraryViolaSRP bibliotecaMala = new LibraryViolaSRP();\n\n        bibliotecaMala.registrarLibro(\"El Quijote\", \"Cervantes\", 3);\n        bibliotecaMala.registrarUsuario(\"Ana Laura\", \"001\", \"ana@email.com\");\n        bibliotecaMala.prestarLibro(\"001\", \"El Quijote\");\n        bibliotecaMala.mostrarLibros();\n\n        System.out.println(\"\\n\" + \"=\".repeat(50));\n        System.out.println(\"=== DEMOSTRACIÓN: REFACTORIZACIÓN CON SRP ===\");\n\n        SistemaBiblioteca sistema = new SistemaBiblioteca();\n\n        // Registrar datos\n        sistema.registrarLibro(\"Cien años de soledad\", \"Gabriel García Márquez\", 2);\n        sistema.registrarLibro(\"1984\", \"George Orwell\", 1);\n        sistema.registrarUsuario(\"Ana Laura\", \"001\", \"ana@email.com\");\n        sistema.registrarUsuario(\"Carlos\", \"002\", \"carlos@email.com\");\n\n        // Realizar préstamos\n        sistema.prestarLibro(\"001\", \"1984\");\n        sistema.prestarLibro(\"002\", \"Cien años de soledad\");\n\n        // Mostrar estado actual\n        System.out.println(\"\\n=== Estado actual del sistema ===\");\n        sistema.mostrarTodo();\n\n        // Devolver un libro\n        System.out.println(\"\\n=== Devolución ===\");\n        sistema.devolverLibro(\"001\", \"1984\");\n\n        System.out.println(\"\\n=== Estado final ===\");\n        sistema.mostrarTodo();\n    }\n}\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/java/FranDev200.java",
    "content": "package com.amsoft.roadmap.example26;\n\nimport java.util.ArrayList;\nimport java.util.Scanner;\n\npublic class FranDev200 {\n\n    static class Refresco{\n\n        private String nombre;\n        private double precio;\n\n        public Refresco(String nombre, double precio){\n            this.nombre = nombre;\n            this.precio = precio;\n        }\n\n        /*\n\n        EJEMPLO INCORRECTO\n\n        // Funcionalidad 1\n        public void aumentarPrecio(double precio){\n            this.precio += precio;\n        }\n\n        // Funcionalidad 2\n        public void infoRefresco(){\n            System.out.println(this.nombre + \" --> \" + this.precio + \"€\");\n        }\n        */\n\n        // Funcionalidad 1\n        public void aumentarPrecio(double precio){\n            this.precio += precio;\n        }\n\n    }\n\n    static class Carta{\n\n        Refresco refresco;\n\n        public Carta(Refresco refresco){\n            this.refresco = refresco;\n        }\n\n        //Funcionalidad 2\n        public void verCarta(){\n            System.out.println(this.refresco.nombre + \" ---> \" +  this.refresco.precio + \"€\");\n        }\n\n    }\n    static void main() {\n\n        /*\n\n        EJERCICIO:\n         * Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n         * Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n         * de forma correcta e incorrecta.\n\n         */\n\n        Refresco refresco = new Refresco(\"Fanta de naranja\", 2.50);\n        Carta carta = new Carta(refresco);\n        carta.verCarta();\n\n        refresco.aumentarPrecio(0.20);\n        carta.verCarta();\n\n\n        /*\n\n        DIFICULTAD EXTRA (opcional):\n         * Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n         * manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n         * y el procesamiento de préstamos de libros.\n         * Requisitos:\n         * 1. Registrar libros: El sistema debe permitir agregar nuevos libros con\n         * información básica como título, autor y número de copias disponibles.\n         * 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n         * información básica como nombre, número de identificación y correo electrónico.\n         * 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n         * tomar prestados y devolver libros.\n         * Instrucciones:\n         * 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n         * los tres aspectos mencionados anteriormente (registro de libros, registro de\n         * usuarios y procesamiento de préstamos).\n         * 2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n         * siguiendo el Principio de Responsabilidad Única.\n\n         */\n\n\n        System.out.println(\"\\n===============\");\n        System.out.println(\"EJERCICIO EXTRA\");\n        System.out.println(\"===============\");\n\n        menuAcciones();\n\n        try {\n            Thread.sleep(1500);\n        } catch (InterruptedException e) {\n            System.out.println(e.getMessage());\n        }\n\n        System.out.println(\"Programa finalizado.\");\n\n    }\n\n    static final ArrayList<Usuario> usuarios = new ArrayList<>();\n    static final ArrayList<Libro> libros = new ArrayList<>();\n    static final ArrayList<Prestamo> prestamos = new ArrayList<>();\n\n\n    static class Libro{\n        private String titulo;\n        private String autor;\n        private int nroCopias;\n\n        public Libro(String titulo, String autor, int nroCopias){\n            this.titulo = titulo;\n            this.autor = autor;\n            this.nroCopias = nroCopias;\n        }\n\n        public Libro(){ }\n\n        public String getTitulo() { return titulo; }\n\n        public void setTitulo(String titulo) { this.titulo = titulo; }\n\n        public String getAutor() { return autor; }\n\n        public void setAutor(String autor) { this.autor = autor; }\n\n        public int getNroCopias() { return nroCopias; }\n\n        public void setNroCopias(int nroCopias) { this.nroCopias = nroCopias; }\n\n    }\n\n    static class Usuario{\n        private String nombre;\n        private String dni;\n        private String correo;\n\n        public Usuario(String nombre, String dni, String correo) {\n            this.nombre = nombre;\n            this.dni = dni;\n            this.correo = correo;\n        }\n\n        public Usuario() { }\n\n        public String getNombre() { return nombre; }\n\n        public void setNombre(String nombre) { this.nombre = nombre; }\n\n        public String getDni() { return dni; }\n\n        public void setDni(String dni) { this.dni = dni; }\n\n        public String getCorreo() { return correo; }\n\n        public void setCorreo(String correo) { this.correo = correo; }\n\n    }\n\n    static class Prestamo{\n\n        private Libro libro;\n        private Usuario usuario;\n        private int nroCopias;\n\n        public Prestamo(Usuario usuario, Libro libro, int nroCopias) {\n            this.usuario = usuario;\n            this.libro = libro;\n            this.nroCopias = nroCopias;\n        }\n\n        public Prestamo() { }\n\n        public Libro getLibro() { return libro; }\n\n        public void setLibro(Libro libro) { this.libro = libro; }\n\n        public Usuario getUsuario() { return usuario; }\n\n        public void setUsuario(Usuario usuario) { this.usuario = usuario; }\n\n        public int getNroCopias() { return nroCopias; }\n\n        public void setNroCopias(int nroCopias) { this.nroCopias = nroCopias; }\n    }\n\n/*\n\n    // CLASE ERRONEA\n    static class Library{\n\n        public void registroUsuario(){\n\n            Usuario user = null;\n\n            Scanner scan =  new Scanner(System.in);\n            System.out.print(\"Introduzca su nombre: \");\n            String nombre = scan.nextLine();\n\n\n            System.out.print(\"Introduzca su dni: \");\n            String dni = scan.nextLine();\n\n            for (Usuario u : usuarios){\n                if(u.getDni().equals(dni)){\n                    System.out.println(\"Este DNI ya está registrado.\");\n                    System.out.println(\"ERROR al registar un nuevo usuario.\");\n                    return;\n                }\n            }\n\n            System.out.print(\"Introduzca su correo electrónico: \");\n            String correo = scan.nextLine();\n\n            for (Usuario u : usuarios){\n                if(u.getCorreo().equals(correo)){\n                    System.out.println(\"Este correo ya está en uso.\");\n                    System.out.println(\"ERROR al registar un nuevo usuario.\");\n                    return;\n                }\n            }\n\n            user = new Usuario(nombre, dni, correo);\n            usuarios.add(user);\n\n            System.out.println(\"Usuario \" + user.getNombre() + \" registrado con exito.\");\n        }\n\n        public void eliminarUsuario(){\n\n            Scanner scan =  new Scanner(System.in);\n            System.out.print(\"Introduzca el DNI del usuario a eliminar: \");\n            String dni = scan.nextLine();\n\n            for (Usuario u : usuarios){\n                if(u.getDni().equals(dni)){\n                    System.out.println(\"Usuario \" + u.getNombre() + \" eliminado con exito.\");\n                    usuarios.remove(u);\n                    break;\n                }else{\n                    System.out.println(\"Este dni no está registrado.\");\n                }\n            }\n\n        }\n\n        public void registroLibro(){\n\n            Libro libro = null;\n\n            Scanner scan =  new Scanner(System.in);\n            System.out.print(\"Introduzca el título del libro: \");\n            String titulo = scan.nextLine();\n\n            for(Libro l : libros){\n                if(l.getTitulo().equals(titulo)){\n                    System.out.println(\"Este título ya está registrado.\");\n                    return;\n                }\n            }\n\n            System.out.print(\"Introduce el nombre del autor: \");\n            String autor = scan.nextLine();\n            System.out.println(\"Indica el número de copias\");\n            int  nroCopias = scan.nextInt();\n\n            libro = new Libro(titulo, autor, nroCopias);\n            libros.add(libro);\n            System.out.println(\"Libro \" + libro.getTitulo() + \" registrado con exito.\");\n\n        }\n\n        public void eliminarLibro(){\n\n            Scanner scan =  new Scanner(System.in);\n\n            System.out.print(\"Introduce el título del libro a eliminar: \");\n            String titulo = scan.nextLine();\n\n            for(Libro l : libros){\n                if(l.getTitulo().equals(titulo)){\n                    System.out.println(\"Libro \" + l.getTitulo() + \" eliminado con exito.\");\n                    libros.remove(l);\n                    break;\n                }\n            }\n\n        }\n\n        public void registroPrestamo(){\n\n            Usuario usuario = null;\n            Libro libro = null;\n            Prestamo prestamo = null;\n\n            Scanner scan =  new Scanner(System.in);\n            System.out.print(\"Introduzca el correo del usuario: \");\n            String correo = scan.nextLine();\n\n            for(Usuario u : usuarios){\n                if(u.getCorreo().equals(correo)){\n                    usuario = u;\n                }else{\n                    System.out.println(\"Este usuario no se ha encontrado.\");\n                    return;\n                }\n            }\n\n            System.out.print(\"Introduzca el título del libro: \");\n            String titulo = scan.nextLine();\n\n            for(Libro l : libros){\n                if(l.getTitulo().equals(correo)){\n                    libro = l ;\n                }else{\n                    System.out.println(\"Este libro no se ha encontrado.\");\n                    return;\n                }\n            }\n\n            System.out.print(\"Cuantas copias quieres llevarte: \");\n            int copias = scan.nextInt();\n\n            if(libro.getNroCopias() < copias){\n                System.out.println(\"No ha suficiente stock.\");\n                return;\n            }else{\n                libro.setNroCopias(libro.getNroCopias() - copias);\n            }\n\n            prestamo = new Prestamo(usuario, libro, copias);\n            System.out.println(\" *** RESUMEN DEL PRESTAMO ***\");\n            System.out.println(\"=============================\");\n            System.out.println(\"Cliente: \" + usuario.getNombre() + \" [\" + usuario.getCorreo() + \"]\");\n            System.out.println(\"DNI: \" + usuario.getDni());\n            System.out.println(\"------------------------------\");\n            System.out.println(\"Libro a llevarse: \" + libro.getTitulo() + \" [\" + libro.getAutor() + \"]\");\n            System.out.println(\"Nro de copias: \" + copias);\n            System.out.println(\"==============================\");\n            System.out.println(\"Prestamo realizado con exito. Gracias por su compra.\");\n\n            prestamos.add(prestamo);\n\n\n        }\n\n        public void infoLibreria(){\n\n            System.out.println(\"LIBROS DISPONIBLES\");\n            System.out.println(\"==================\\n\");\n\n            for(Libro l : libros){\n\n                System.out.println(l.getTitulo() + \" [\" + l.getAutor() + \"]\");\n                System.out.println(\"Nro de copias: \" + l.getNroCopias());\n                System.out.println(\"----------------------\\n\");\n\n            }\n        }\n\n        public void infoPrestamos(){\n\n            System.out.println(\"PRESTAMOS REALIZADOS\");\n            System.out.println(\"-_-_-_-_-_-_-_-_-_-_-\");\n\n            for(Prestamo p : prestamos){\n                System.out.println(\" - \" + p.getUsuario().getNombre() + \" ---> \" + p.getLibro().getTitulo()\n                        + \"   [\" + p.getNroCopias() + \"]\" );\n            }\n\n        }\n\n    }\n\n  */\n\n    static class FuncionesUsuarios{\n\n        public void registroUsuario(){\n\n            Usuario user = null;\n\n            Scanner scan =  new Scanner(System.in);\n            System.out.print(\"Introduzca su nombre: \");\n            String nombre = scan.nextLine();\n\n\n            System.out.print(\"Introduzca su dni: \");\n            String dni = scan.nextLine();\n\n            for (Usuario u : usuarios){\n                if(u.getDni().equals(dni)){\n                    System.out.println(\"Este DNI ya está registrado.\");\n                    System.out.println(\"ERROR al registar un nuevo usuario.\");\n                    return;\n                }\n            }\n\n            System.out.print(\"Introduzca su correo electrónico: \");\n            String correo = scan.nextLine();\n\n            for (Usuario u : usuarios){\n                if(u.getCorreo().equals(correo)){\n                    System.out.println(\"Este correo ya está en uso.\");\n                    System.out.println(\"ERROR al registar un nuevo usuario.\");\n                    return;\n                }\n            }\n\n            user = new Usuario(nombre, dni, correo);\n            usuarios.add(user);\n\n            System.out.println(\"Usuario \" + user.getNombre() + \" registrado con exito.\");\n        }\n\n        public void eliminarUsuario(){\n\n            Scanner scan =  new Scanner(System.in);\n            System.out.print(\"Introduzca el DNI del usuario a eliminar: \");\n            String dni = scan.nextLine();\n\n            for (Usuario u : usuarios){\n                if(u.getDni().equals(dni)){\n                    System.out.println(\"Usuario \" + u.getNombre() + \" eliminado con exito.\");\n                    usuarios.remove(u);\n                    break;\n                }else{\n                    System.out.println(\"Este dni no está registrado.\");\n                }\n            }\n\n        }\n\n    }\n\n    static class FuncionesLibros{\n\n        public void registroLibro(){\n\n            Libro libro = null;\n\n            Scanner scan =  new Scanner(System.in);\n            System.out.print(\"Introduzca el título del libro: \");\n            String titulo = scan.nextLine();\n\n            for(Libro l : libros){\n                if(l.getTitulo().equals(titulo)){\n                    System.out.println(\"Este título ya está registrado.\");\n                    return;\n                }\n            }\n\n            System.out.print(\"Introduce el nombre del autor: \");\n            String autor = scan.nextLine();\n            System.out.print(\"Indica el número de copias: \");\n            int  nroCopias = scan.nextInt();\n\n            libro = new Libro(titulo, autor, nroCopias);\n            libros.add(libro);\n            System.out.println(\"Libro \\\"\" + libro.getTitulo() + \"\\\" registrado con exito.\");\n\n        }\n\n        public void eliminarLibro(){\n\n            Scanner scan =  new Scanner(System.in);\n\n            System.out.print(\"Introduce el título del libro a eliminar: \");\n            String titulo = scan.nextLine();\n\n            for(Libro l : libros){\n                if(l.getTitulo().equals(titulo)){\n                    System.out.println(\"Libro \" + l.getTitulo() + \" eliminado con exito.\");\n                    libros.remove(l);\n                    break;\n                }\n            }\n\n        }\n\n        public void infoLibreria(){\n\n            System.out.println(\"LIBROS DISPONIBLES\");\n            System.out.println(\"==================\");\n\n            for(Libro l : libros){\n\n                System.out.println(\" - \" + l.getTitulo() + \" [\" + l.getAutor() + \"]\");\n                System.out.println(\"    Nro de copias: \" + l.getNroCopias());\n                System.out.println(\"----------------------\");\n\n            }\n        }\n\n    }\n\n    static class FuncionesPrestamos{\n\n        public void registroPrestamo(){\n\n            Usuario usuario = null;\n            Libro libro = null;\n            Prestamo prestamo = null;\n\n            Scanner scan =  new Scanner(System.in);\n            System.out.print(\"Introduzca el correo del usuario: \");\n            String correo = scan.nextLine();\n\n            for(Usuario u : usuarios){\n                if(u.getCorreo().equals(correo)){\n                    usuario = u;\n                }else{\n                    System.out.println(\"Este usuario no se ha encontrado.\");\n                    return;\n                }\n            }\n\n            System.out.print(\"Introduzca el título del libro: \");\n            String titulo = scan.nextLine();\n\n            for(Libro l : libros){\n                if(l.getTitulo().equalsIgnoreCase(titulo)){\n                    libro = l ;\n                }else{\n                    System.out.println(\"Este libro no se ha encontrado.\");\n                    return;\n                }\n            }\n\n            System.out.print(\"Cuantas copias quieres llevarte: \");\n            int copias = scan.nextInt();\n\n            if(libro.getNroCopias() < copias){\n                System.out.println(\"No ha suficiente stock.\");\n                return;\n            }else{\n                libro.setNroCopias(libro.getNroCopias() - copias);\n            }\n\n            prestamo = new Prestamo(usuario, libro, copias);\n            System.out.println(\" *** RESUMEN DEL PRESTAMO ***\");\n            System.out.println(\"=============================\");\n            System.out.println(\"Cliente: \" + usuario.getNombre() + \" [\" + usuario.getCorreo() + \"]\");\n            System.out.println(\"DNI: \" + usuario.getDni());\n            System.out.println(\"------------------------------\");\n            System.out.println(\"Libro a llevarse: \" + libro.getTitulo() + \" [\" + libro.getAutor() + \"]\");\n            System.out.println(\"Nro de copias: \" + copias);\n            System.out.println(\"==============================\");\n            System.out.println(\"Prestamo realizado con exito. Gracias por su compra.\");\n\n            prestamos.add(prestamo);\n\n\n        }\n\n        public void infoPrestamos(){\n\n            System.out.println(\"PRESTAMOS REALIZADOS\");\n            System.out.println(\"-_-_-_-_-_-_-_-_-_-_-\");\n\n            for(Prestamo p : prestamos){\n                System.out.println(\" - \" + p.getUsuario().getNombre() + \" ---> \" + p.getLibro().getTitulo()\n                        + \"   [\" + p.getNroCopias() + \"] ud.\" );\n            }\n\n        }\n\n    }\n\n    public static void menuAcciones(){\n\n        FuncionesLibros funcionesLibros = new FuncionesLibros();\n        FuncionesPrestamos funcionesPrestamos = new FuncionesPrestamos();\n        FuncionesUsuarios funcionesUsuarios = new FuncionesUsuarios();\n\n        int  opcion = 0;\n        int  opcion2 = 0;\n        Scanner scan =  new Scanner(System.in);\n\n        while (opcion != 4){\n            System.out.println(\" *** LIBRERÍA FRANDEV ***\");\n            System.out.println(\"=========================\");\n            System.out.println(\" 1 - Libros.\");\n            System.out.println(\" 2 - Usuarios.\");\n            System.out.println(\" 3 - Prestamos.\");\n            System.out.println(\" 4 - Desconectar.\");\n            System.out.println(\"==============\");\n            System.out.print(\"Respuesta (escriba el número): \");\n            opcion = scan.nextInt();\n\n            switch(opcion){\n                case 1:\n\n                    System.out.println(\"-------------------\");\n                    System.out.println(\"1. Añadir un libro.\");\n                    System.out.println(\"2. Eliminar un libro.\");\n                    System.out.println(\"3. Info de los libros.\");\n                    System.out.println(\"--------------------\");\n                    System.out.print(\"Respuesta: \");\n                    opcion2 = scan.nextInt();\n\n                    switch (opcion2){\n                        case 1:\n                            funcionesLibros.registroLibro();\n                            break;\n                        case 2:\n                            funcionesLibros.eliminarLibro();\n                            break;\n                        case 3:\n                            funcionesLibros.infoLibreria();\n                            break;\n                    }\n\n                    break;\n\n                case 2:\n\n                    System.out.println(\"-------------------\");\n                    System.out.println(\"1. Añadir un usuario.\");\n                    System.out.println(\"2. Eliminar un usuario.\");\n                    System.out.println(\"--------------------\");\n                    System.out.print(\"Respuesta: \");\n                    opcion2 = scan.nextInt();\n\n                    switch (opcion2){\n                        case 1:\n                            funcionesUsuarios.registroUsuario();\n                            break;\n                        case 2:\n                            funcionesUsuarios.eliminarUsuario();\n                            break;\n                    }\n\n                    break;\n\n                case 3:\n\n                    System.out.println(\"-------------------\");\n                    System.out.println(\"1. Hacer un prestamo.\");\n                    System.out.println(\"2. Info de los prestamos.\");\n                    System.out.println(\"--------------------\");\n                    System.out.print(\"Respuesta: \");\n                    opcion2 = scan.nextInt();\n\n                    switch (opcion2){\n                        case 1:\n                            funcionesPrestamos.registroPrestamo();\n                            break;\n                        case 2:\n                            funcionesPrestamos.infoPrestamos();\n                            break;\n                    }\n\n                    break;\n\n                case 4:\n\n                    System.out.println(\"Saliendo...\");\n\n                    break;\n            }\n\n\n\n        }\n\n\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/java/Josegs95.java",
    "content": "import java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\npublic class Josegs95 {\n    public static void main(String[] args) {\n        //Ejercicio\n        //Forma incorrecta\n        IncorrectStudent student1 = new IncorrectStudent(678, \"Pepe\");\n        student1.addScore(8);\n\n        //Forma correcta\n        CorrectStudent student2 = new CorrectStudent(551, \"Rocío\");\n        Exam exam1 = new Exam();\n        exam1.addScore(student2, 8.25);\n\n        //Si por ejemplo hay algún problema con un exámen y hay que subir la nota a una\n        //o varios estudiantes, es mucho mas claro y fácil de la forma correcta que la incorrecta\n    }\n\n    public static class IncorrectStudent{\n        private int id;\n        private String name;\n        private List<Double> scoreList;\n\n        public IncorrectStudent(int id, String name) {\n            this.id = id;\n            this.name = name;\n            scoreList = new ArrayList<>();\n        }\n\n        public void addScore(double newScore){\n            scoreList.add(newScore);\n        }\n    }\n\n    public static class CorrectStudent{\n        private int id;\n        private String name;\n\n        public CorrectStudent(int id, String name) {\n            this.id = id;\n            this.name = name;\n        }\n    }\n\n    public static class Exam{\n        private Map<CorrectStudent, Double> scores;\n\n        public Exam(){\n            scores = new HashMap<>();\n        }\n\n        public void addScore(CorrectStudent student, Double score){\n            scores.put(student, score);\n        }\n    }\n\n    //Reto\n    //Si queremos guardar varios datos datos de libros y usuario, debemos crear una\n    //clase para ambos, aunque queramos hacerlo mal aposta.\n\n    public static class IncorrectLibrary {\n\n        private List<Book> bookList;\n        private List<User> userList;\n        private List<Loan> loanList;\n\n        public IncorrectLibrary(){\n            bookList = new ArrayList<>();\n            userList = new ArrayList<>();\n            loanList = new ArrayList<>();\n        }\n\n        public void registerBook(String title, String author, int nCopies){\n            //Código para registrar un libro\n        }\n\n        public void registerUser(Integer id, String name, String email){\n            //Código para registrar un usuario\n        }\n\n        public void lendBook(Integer idUser, String bookName, boolean returnBook){\n            //Código para prestar un libro a un usuario\n        }\n\n        public static void returnBook(Integer idUser, String bookName){\n            //Código para prestar un libro a un usuario\n        }\n    }\n\n    public static class CorrectLibrary{\n        private List<Book> bookList;\n        private List<User> userList;\n        private List<Loan> loanList;\n\n        public CorrectLibrary() {\n            bookList = new ArrayList<>();\n            userList = new ArrayList<>();\n            loanList = new ArrayList<>();\n        }\n\n        public void lendBook(Integer idUser, String bookName){\n            //Código para prestar un libro a un usuario\n        }\n\n        public void returnBook(Integer idUser, String bookName){\n            //Código para que un usuario devuelva un libro\n        }\n\n        public boolean registerUser(Integer id, String name, String email){\n            return userList.add(Register.registerUser(id, name, email));\n        }\n\n        public boolean registerBook(String title, String author, int nCopies){\n            return bookList.add(Register.registerBook(title, author, nCopies));\n        }\n    }\n\n    public static class Register{\n\n        public static Book registerBook(String title, String author, int nCopies){\n            //Código para registrar un libro\n            return null;\n        }\n\n        public static User registerUser(Integer id, String name, String email){\n            //Código para registrar un usuario\n            return null;\n        }\n    }\n\n    public static class Book{\n        private String title;\n        private String author;\n        private Integer nCopies;\n\n        public Book(String title, String author, Integer nCopies) {\n            this.title = title;\n            this.author = author;\n            this.nCopies = nCopies;\n        }\n\n        public String getTitle() {\n            return title;\n        }\n\n        public String getAuthor() {\n            return author;\n        }\n\n        public Integer getnCopies() {\n            return nCopies;\n        }\n    }\n\n    public static class User{\n        private int id;\n        private String name;\n        private String email;\n\n        public User(int id, String name, String email) {\n            this.id = id;\n            this.name = name;\n            this.email = email;\n        }\n\n        public int getId() {\n            return id;\n        }\n\n        public String getName() {\n            return name;\n        }\n\n        public String getEmail() {\n            return email;\n        }\n    }\n\n    public static class Loan{\n        private User user;\n        private Book book;\n\n        public Loan(User user, Book book) {\n            this.user = user;\n            this.book = book;\n        }\n\n        public User getUser() {\n            return user;\n        }\n\n        public Book getBook() {\n            return book;\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/java/asjordi.java",
    "content": "/*\n    El Principio de Responsabilidad Única dice que, una clase debe hacer una sola cosa y, por lo tanto, debe tener una sola razón para cambiar.\n    De esta manera, solo un cambio potencial en la especificación del software debería poder afectar la especificación de la clase.\n */\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class Main {\n\n    public static void main(String[] args) {\n        Revista revista = new Revista(\"Revista de Prueba\", \"Autor de Prueba\", 10.0);\n        Factura factura = new Factura(revista, 2, 0.1, 0.16);\n        FacturaImpresion facturaImpresion = new FacturaImpresion(factura);\n        FacturaPersistencia facturaPersistencia = new FacturaPersistencia(factura);\n    }\n\n    /*\n     * EJERCICIO:\n     * Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n     * Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n     * de forma correcta e incorrecta.\n     */\n    static class Revista {\n        String nombre;\n        String autor;\n        double precio;\n\n        public Revista(String nombre, String autor, double precio) {\n            this.nombre = nombre;\n            this.autor = autor;\n            this.precio = precio;\n        }\n    }\n\n    static class Factura {\n        private Revista revista;\n        private int cantidad;\n        private double descuento;\n        private double impuesto;\n        private double total;\n\n        public Factura(Revista revista, int cantidad, double descuento, double impuesto) {\n            this.revista = revista;\n            this.cantidad = cantidad;\n            this.descuento = descuento;\n            this.impuesto = impuesto;\n            this.total = this.calcularTotal();\n        }\n\n        public double calcularTotal() {\n            double precio = ((revista.precio - revista.precio - descuento) * this.cantidad);\n            double precionConImpuesto = precio * (1 + this.impuesto);\n            return precionConImpuesto;\n        }\n\n        /*\n        public void imprimirFactura() {\n            System.out.println(cantidad + \"x \" + revista.nombre + \" \" + revista.precio + \"$\");\n            System.out.println(\"Tasa de Descuento: \" + descuento);\n            System.out.println(\"Tasa de Impuesto: \" + impuesto);\n            System.out.println(\"Total: \" + total);\n        }*/\n\n        /*\n        public void guardarArchivo() {\n            // Crea un archivo con un nombre dado y guarda la factura\n        }*/\n    }\n\n    /*\n        La clase Factura viola el principio de responsabilidad única, ya que tiene más de una razón para cambiar.\n        La primera violación es el método imprimirFactura(), el cual contiene la lógica para imprimir la factura.\n        La segunda violación es el método guardarArchivo(), el cual contiene la lógica para guardar la factura en un archivo, y mezcla lógica de persistencia con lógica de negocios.\n        Para corregir esto, se puede crear una clase separada para imprimir la factura y otra para guardar la factura en un archivo.\n     */\n    static class FacturaImpresion {\n        private Factura factura;\n\n        public FacturaImpresion(Factura factura) {\n            this.factura = factura;\n        }\n\n        public void imprimir() {\n            System.out.println(factura.cantidad + \"x \" + factura.revista.nombre + \" \" + factura.revista.precio + \" $\");\n            System.out.println(\"Tasa de Descuento: \" + factura.descuento);\n            System.out.println(\"Tasa de Impuesto: \" + factura.impuesto);\n            System.out.println(\"Total: \" + factura.total + \" $\");\n        }\n    }\n\n    static class FacturaPersistencia {\n        Factura factura;\n\n        public FacturaPersistencia(Factura factura) {\n            this.factura = factura;\n        }\n\n        public void guardarArchivo(String nombreArchivo) {\n            // Crea un archivo con un nombre dado y guarda la factura\n        }\n    }\n\n    /*\n     * DIFICULTAD EXTRA (opcional):\n     * Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n     * manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n     * y el procesamiento de préstamos de libros.\n     * Requisitos:\n     * 1. Registrar libros: El sistema debe permitir agregar nuevos libros con\n     * información básica como título, autor y número de copias disponibles.\n     * 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n     * información básica como nombre, número de identificación y correo electrónico.\n     * 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n     * tomar prestados y devolver libros.\n     * Instrucciones:\n     * 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n     * los tres aspectos mencionados anteriormente (registro de libros, registro de\n     * usuarios y procesamiento de préstamos).\n     * 2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n     * siguiendo el Principio de Responsabilidad Única.\n     */\n\n    static class Libro {\n        private String titulo;\n        private String autor;\n        private Integer copiasDisponibles;\n\n        public Libro(String titulo, String autor, Integer copiasDisponibles) {\n            this.titulo = titulo;\n            this.autor = autor;\n            this.copiasDisponibles = copiasDisponibles;\n        }\n\n        public String getTitulo() {\n            return titulo;\n        }\n\n        public void setTitulo(String titulo) {\n            this.titulo = titulo;\n        }\n\n        public String getAutor() {\n            return autor;\n        }\n\n        public void setAutor(String autor) {\n            this.autor = autor;\n        }\n\n        public Integer getCopiasDisponibles() {\n            return copiasDisponibles;\n        }\n\n        public void setCopiasDisponibles(Integer copiasDisponibles) {\n            this.copiasDisponibles = copiasDisponibles;\n        }\n    }\n\n    static class Usuario {\n        private String nombre;\n        private int identificacion;\n        private String email;\n\n        public Usuario(String nombre, int identificacion, String email) {\n            this.nombre = nombre;\n            this.identificacion = identificacion;\n            this.email = email;\n        }\n\n        public String getNombre() {\n            return nombre;\n        }\n\n        public void setNombre(String nombre) {\n            this.nombre = nombre;\n        }\n\n        public int getIdentificacion() {\n            return identificacion;\n        }\n\n        public void setIdentificacion(int identificacion) {\n            this.identificacion = identificacion;\n        }\n\n        public String getEmail() {\n            return email;\n        }\n\n        public void setEmail(String email) {\n            this.email = email;\n        }\n    }\n\n    static class Library {\n        private List<Libro> libros;\n        private List<Usuario> usuarios;\n\n        public Library() {\n            this.libros = new ArrayList<>();\n            this.usuarios = new ArrayList<>();\n        }\n\n        public void registrarLibro(String titulo, String autor, int copiasDisponibles) {\n            this.libros.add(new Libro(titulo, autor, copiasDisponibles));\n        }\n\n        public void registrarUsuario(String nombre, int identificacion, String email) {\n            this.usuarios.add(new Usuario(nombre, identificacion, email));\n        }\n\n        public void prestarLibro(String titulo, int identificacion) {\n            Libro libro = this.libros.stream().filter(l -> l.getTitulo().equals(titulo)).findFirst().orElse(null);\n            Usuario usuario = this.usuarios.stream().filter(u -> u.getIdentificacion() == identificacion).findFirst().orElse(null);\n\n            if (libro != null && usuario != null && libro.getCopiasDisponibles() > 0) {\n                libro.setCopiasDisponibles(libro.getCopiasDisponibles() - 1);\n                System.out.println(\"Libro prestado a \" + usuario.getNombre());\n            } else System.out.println(\"No se pudo realizar el préstamo\");\n        }\n\n        public void devolverLibro(String titulo, int identificacion) {\n            Libro libro = this.libros.stream().filter(l -> l.getTitulo().equals(titulo)).findFirst().orElse(null);\n            Usuario usuario = this.usuarios.stream().filter(u -> u.getIdentificacion() == identificacion).findFirst().orElse(null);\n\n            if (libro != null && usuario != null) {\n                libro.setCopiasDisponibles(libro.getCopiasDisponibles() + 1);\n                System.out.println(\"Libro devuelto por \" + usuario.getNombre());\n            } else System.out.println(\"No se pudo realizar la devolución\");\n        }\n    }\n\n    static class LibroRegistro {\n        private List<Libro> libros;\n\n        public LibroRegistro() {\n            this.libros = new ArrayList<>();\n        }\n\n        public void registrarLibro(Libro libro) {\n            this.libros.add(libro);\n        }\n\n        public Libro buscarLibro(String titulo) {\n            return this.libros.stream().filter(l -> l.getTitulo().equals(titulo)).findFirst().orElse(null);\n        }\n    }\n\n    static class UsuarioRegistro {\n        private List<Usuario> usuarios;\n\n        public UsuarioRegistro() {\n            this.usuarios = new ArrayList<>();\n        }\n\n        public void registrarUsuario(Usuario u) {\n            this.usuarios.add(u);\n        }\n\n        public Usuario buscarUsuario(int identificacion) {\n            return this.usuarios.stream().filter(u -> u.getIdentificacion() == identificacion).findFirst().orElse(null);\n        }\n    }\n\n    static class PrestamoProcesador {\n        private LibroRegistro libroRegistro;\n        private UsuarioRegistro usuarioRegistro;\n\n        public PrestamoProcesador(LibroRegistro libroRegistro, UsuarioRegistro usuarioRegistro) {\n            this.libroRegistro = libroRegistro;\n            this.usuarioRegistro = usuarioRegistro;\n        }\n\n        public void prestarLibro(String titulo, int identificacion) {\n            Libro libro = libroRegistro.buscarLibro(titulo);\n            Usuario usuario = usuarioRegistro.buscarUsuario(identificacion);\n\n            if (libro != null && usuario != null && libro.getCopiasDisponibles() > 0) {\n                libro.setCopiasDisponibles(libro.getCopiasDisponibles() - 1);\n                System.out.println(\"Libro prestado a \" + usuario.getNombre());\n            } else {\n                System.out.println(\"No se pudo realizar el préstamo\");\n            }\n        }\n\n        public void devolverLibro(String titulo, int identificacion) {\n            Libro libro = libroRegistro.buscarLibro(titulo);\n            Usuario usuario = usuarioRegistro.buscarUsuario(identificacion);\n\n            if (libro != null && usuario != null) {\n                libro.setCopiasDisponibles(libro.getCopiasDisponibles() + 1);\n                System.out.println(\"Libro devuelto por \" + usuario.getNombre());\n            } else {\n                System.out.println(\"No se pudo realizar la devolución\");\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/java/danhingar.java",
    "content": "import java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Optional;\n\npublic class danhingar {\n\n    // Incorrecto\n    public class User {\n\n        private String name;\n        private String email;\n\n        public User(String name, String email) {\n            this.email = email;\n            this.name = name;\n        }\n\n        public void save(User user) {\n\n        }\n\n        public void sendEmail(User user) {\n\n        }\n\n    }\n\n    // Correcto\n    public class User1 {\n\n        private String name;\n        private String email;\n\n        public User1(String name, String email) {\n            this.name = name;\n            this.email = email;\n        }\n\n    }\n\n    public class UserService {\n\n        public void save(User1 user1) {\n\n        }\n\n    }\n\n    public class EmailService {\n\n        public void sendEmail(String email, String message) {\n\n        }\n    }\n\n    public static void main(String[] args) {\n        // WITHOUT SRP\n        Library library = new Library();\n        library.addUser(1, \"Daniel\", \"example@gmail.com\");\n        library.addUser(2, \"Pepe\", \"example@gmail.com\");\n        System.out.println(library.toString());\n        library.addBook(\"Libro 1\", \"Autor 1\", 5);\n        library.addBook(\"Libro 2\", \"Autor 2\", 3);\n        System.out.println(library.toString());\n        library.loanBook(1, \"Libro 1\");\n        library.loanBook(2, \"Libro 1\");\n        System.out.println(library.toString());\n        library.returnBook(2, \"Libro 1\");\n        System.out.println(library.toString());\n\n        // WITH SRP\n        Library2 library2 = new Library2();\n        library2.addUser(new User2(1, \"Daniel\", \"example@gmail.com\"));\n        library2.addUser(new User2(2, \"Pepe\", \"example@gmail.com\"));\n        System.out.println(library2.toString());\n        library2.addBook(new Book(\"Libro 1\", \"Autor 1\", 5));\n        library2.addBook(new Book(\"Libro 2\", \"Autor 2\", 3));\n        System.out.println(library2.toString());\n        library2.loanBook(1, \"Libro 1\");\n        library2.loanBook(2, \"Libro 1\");\n        System.out.println(library2.toString());\n        library2.returnBook(2, \"Libro 1\");\n        System.out.println(library2.toString());\n    }\n\n}\n\n// Extra\n\n// Incorrecto\n\nclass Library {\n    private List<Map<String, Object>> users;\n    private List<Map<String, Object>> books;\n    private Map<Integer, List<String>> loans;\n\n    public Library() {\n        this.users = new ArrayList<>();\n        this.books = new ArrayList<>();\n        this.loans = new HashMap<>();\n    }\n\n    public void addBook(String title, String author, Integer copies) {\n        Map<String, Object> book = new HashMap<>();\n        book.put(\"title\", title);\n        book.put(\"author\", author);\n        book.put(\"copies\", copies);\n        books.add(book);\n    }\n\n    public void addUser(Integer id, String name, String email) {\n        Map<String, Object> user = new HashMap<>();\n        user.put(\"id\", id);\n        user.put(\"name\", name);\n        user.put(\"email\", email);\n        users.add(user);\n    }\n\n    public void loanBook(Integer userId, String bookTitle) {\n        for (Map<String, Object> book : books) {\n            if (book.get(\"title\").equals(bookTitle) && (Integer) book.get(\"copies\") > 0) {\n                book.put(\"copies\", (Integer) book.get(\"copies\") - 1);\n                List<String> booksUser = loans.get(userId) != null ? loans.get(userId) : new ArrayList<>();\n                booksUser.add(bookTitle);\n                loans.put(userId, booksUser);\n            }\n        }\n    }\n\n    public void returnBook(Integer userId, String bookTitle) {\n        boolean exist = this.loans.get(userId).stream().anyMatch(b -> b.equals(bookTitle));\n        if (exist) {\n            this.books.stream().filter(b -> b.get(\"title\").equals(bookTitle))\n                    .forEach(b -> b.put(\"copies\", (Integer) b.get(\"copies\") + 1));\n            this.loans.get(userId).remove(bookTitle);\n        }\n    }\n\n    @Override\n    public String toString() {\n        return \"Library [users=\" + users.toString() + \", books=\" + books.toString() + \", loans=\" + loans.toString() + \"]\";\n    }\n}\n\n// Correcto\n\nclass Library2 {\n\n    private List<User2> users;\n    private List<Book> books;\n    private Loan loans;\n\n    public Library2() {\n        users = new ArrayList<>();\n        books = new ArrayList<>();\n        loans = new Loan();\n    }\n\n    public void addBook(Book book) {\n        books.add(book);\n    }\n\n    public void addUser(User2 user) {\n        users.add(user);\n    }\n\n    public void loanBook(Integer userId, String bookTitle) {\n        Optional<User2> user = users.stream().filter(u -> u.getId().equals(userId)).findFirst();\n        Optional<Book> book = books.stream().filter(b -> b.getTitle().equals(bookTitle)).findFirst();\n        if (user.isPresent() && book.isPresent()) {\n            loans.loanBook(user.get(), book.get());\n        }\n\n    }\n\n    public void returnBook(Integer userId, String bookTitle) {\n        Optional<User2> user = users.stream().filter(u -> u.getId().equals(userId)).findFirst();\n        Optional<Book> book = books.stream().filter(b -> b.getTitle().equals(bookTitle)).findFirst();\n        if (user.isPresent() && book.isPresent()) {\n            loans.returnBook(user.get(), book.get());\n        }\n    }\n\n    @Override\n    public String toString() {\n        return \"Library [users=\" + users + \", books=\" + books.toString() + \", loans=\" + loans + \"]\";\n    }\n\n}\n\nclass Book {\n\n    private String author;\n    private String title;\n    private Integer copies;\n\n    public Book(String title, String author, Integer copies) {\n        this.title = title;\n        this.author = author;\n        this.copies = copies;\n    }\n\n    public String getAuthor() {\n        return author;\n    }\n\n    public void setAuthor(String author) {\n        this.author = author;\n    }\n\n    public String getTitle() {\n        return title;\n    }\n\n    public void setTitle(String title) {\n        this.title = title;\n    }\n\n    public Integer getCopies() {\n        return copies;\n    }\n\n    public void setCopies(Integer copies) {\n        this.copies = copies;\n    }\n\n    @Override\n    public String toString() {\n        return \"Book [author=\" + author + \", title=\" + title + \", copies=\" + copies + \"]\";\n    }\n\n}\n\nclass User2 {\n    private String name;\n    private Integer id;\n    private String email;\n\n    public User2(Integer id, String name, String email) {\n        this.name = name;\n        this.id = id;\n        this.email = email;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public Integer getId() {\n        return id;\n    }\n\n    public void setId(Integer id) {\n        this.id = id;\n    }\n\n    public String getEmail() {\n        return email;\n    }\n\n    public void setEmail(String email) {\n        this.email = email;\n    }\n\n}\n\nclass Loan {\n\n    private Map<Integer, List<String>> loans;\n\n    public Loan() {\n        this.loans = new HashMap<>();\n    }\n\n    public void loanBook(User2 user, Book book) {\n        if (book.getCopies() > 0) {\n            book.setCopies(book.getCopies() - 1);\n            List<String> booksUser = loans.get(user.getId()) != null ? loans.get(user.getId()) : new ArrayList<>();\n            booksUser.add(book.getTitle());\n            loans.put(user.getId(), booksUser);\n        }\n\n    }\n\n    public void returnBook(User2 user, Book book) {\n        boolean exist = this.loans.get(user.getId()).stream().anyMatch(b -> b.equals(book.getTitle()));\n        if (exist) {\n            book.setCopies(book.getCopies() + 1);\n            this.loans.get(user.getId()).remove(book.getTitle());\n        }\n    }\n\n    public Map<Integer, List<String>> getLoans() {\n        return loans;\n    }\n\n    @Override\n    public String toString() {\n        return \"Loan [loans=\" + loans.toString() + \"]\";\n    }\n\n    \n\n}"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/java/diegosilval.java",
    "content": "import java.util.ArrayList;\nimport java.util.List;\nimport java.util.Optional;\nimport java.util.function.Consumer;\n\npublic interface diegosilval {\n\n    static void main(String... args) {\n        System.out.println(\"** Usando una clase para todo **\");\n        var libraryUtil = new LibraryUtil();\n        libraryUtil.addUser(\"01\", \"Alex\", \"alex@mail.com\");\n        libraryUtil.addUser(\"02\", \"Bob\", \"bob@mnail.com\");\n        libraryUtil.addUser(\"03\", \"Cark\", \"carl@mnail.com\");\n\n        libraryUtil.addBook(\"To Kill a Mockingbird\", \"Harper Lee\", 2);\n        libraryUtil.addBook(\"1984\", \"George Orwell\", 1);\n        libraryUtil.addBook(\"Pride and Prejudice\", \"Jane Austen\", 0);\n\n        libraryUtil.bookBorrow(\"1984\", \"01\").ifPresentOrElse(showBorrowSuccess, showBorrowFail);\n        libraryUtil.bookBorrow(\"To Kill a Mockingbird\", \"02\").ifPresentOrElse(showBorrowSuccess, showBorrowFail);\n        libraryUtil.bookBorrow(\"1984\", \"03\").ifPresentOrElse(showBorrowSuccess, showBorrowFail);\n\n        libraryUtil.returnBookAndShowResult(\"1984\", \"01\");\n        libraryUtil.returnBookAndShowResult(\"To Kill a Mockingbird\", \"02\");\n        libraryUtil.returnBookAndShowResult(\"1984\", \"03\");\n\n        // Usando SRP\n        System.out.println(\"** Usando una clase por cada responsabilidad\");\n        var usersRepository = new UsersRepository();\n        var booksRepository = new BooksRepository();\n        var srpLibraryUtil = new SrpLibraryUtil(usersRepository, booksRepository); // inyectando\n        usersRepository.addUser(\"01\", \"Alex\", \"alex@mail.com\");\n        usersRepository.addUser(\"02\", \"Bob\", \"bob@mnail.com\");\n        usersRepository.addUser(\"03\", \"Cark\", \"carl@mnail.com\");\n\n        booksRepository.addBook(\"To Kill a Mockingbird\", \"Harper Lee\", 2);\n        booksRepository.addBook(\"1984\", \"George Orwell\", 1);\n        booksRepository.addBook(\"Pride and Prejudice\", \"Jane Austen\", 0);\n\n        srpLibraryUtil.bookBorrow(\"1984\", \"01\").ifPresentOrElse(showBorrowSuccess, showBorrowFail);\n        srpLibraryUtil.bookBorrow(\"To Kill a Mockingbird\", \"02\").ifPresentOrElse(showBorrowSuccess, showBorrowFail);\n        srpLibraryUtil.bookBorrow(\"1984\", \"03\").ifPresentOrElse(showBorrowSuccess, showBorrowFail);\n\n        srpLibraryUtil.returnBookAndShowResult(\"1984\", \"01\", showResult);\n        srpLibraryUtil.returnBookAndShowResult(\"To Kill a Mockingbird\", \"02\", showResult);\n        srpLibraryUtil.returnBookAndShowResult(\"1984\", \"03\", showResult);\n    }\n\n    static Consumer<BookLoan> showBorrowSuccess = (bookLoan) -> {\n        System.out.println(String.format(\"Se prestó correctamente %s a %s\", bookLoan.getBook().getTitle(),\n                bookLoan.getUser().getName()));\n    };\n    static Runnable showBorrowFail = () -> System.err.println(\n            \"El usuario no existe, el nombre del libro no existe, o no existen libros disponibles para prestar\");\n    static ShowResult showResult = (returnBookStatus, title, userId) -> {\n        if (returnBookStatus)\n            System.out.println(String.format(\"%s  retornó el libro \\\"%s\\\" correctamente\", userId, title));\n        else\n            System.err.println(String.format(\n                    \"No se encontró el libro \\\"%s\\\", no se encontró el usuario %s o el libro no se encuentra prestado al usuario\",\n                    title, userId));\n\n    };\n\n}\n\n/**\n * Book Class\n */\nclass Book {\n    private String title;\n    private String author;\n    private int available;\n\n    public Book() {\n    }\n\n    public Book(String title, String author, int available) {\n        this.title = title;\n        this.author = author;\n        this.available = available;\n    }\n\n    public String getTitle() {\n        return title;\n    }\n\n    public void setTitle(String title) {\n        this.title = title;\n    }\n\n    public String getAuthor() {\n        return author;\n    }\n\n    public void setAuthor(String author) {\n        this.author = author;\n    }\n\n    public int getAvailable() {\n        return available;\n    }\n\n    public void setAvailable(int available) {\n        this.available = available;\n    }\n\n    public void addAvailable(int delta) {\n        this.available += delta;\n    }\n\n    public void removeAvailable(int delta) {\n        this.available -= delta;\n    }\n\n    @Override\n    public int hashCode() {\n        final int prime = 31;\n        int result = 1;\n        result = prime * result + ((title == null) ? 0 : title.hashCode());\n        return result;\n    }\n\n    @Override\n    public boolean equals(Object obj) {\n        if (this == obj)\n            return true;\n        if (obj == null)\n            return false;\n        if (getClass() != obj.getClass())\n            return false;\n        Book other = (Book) obj;\n        if (title == null) {\n            if (other.title != null)\n                return false;\n        } else if (!title.equals(other.title))\n            return false;\n        return true;\n    }\n\n}\n\n/**\n * User Class\n */\nclass User {\n    private String name;\n    private String id;\n    private String email;\n\n    public User() {\n    }\n\n    public User(String name, String id, String email) {\n        this.name = name;\n        this.id = id;\n        this.email = email;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public String getId() {\n        return id;\n    }\n\n    public void setId(String id) {\n        this.id = id;\n    }\n\n    public String getEmail() {\n        return email;\n    }\n\n    public void setEmail(String email) {\n        this.email = email;\n    }\n\n    @Override\n    public int hashCode() {\n        final int prime = 31;\n        int result = 1;\n        result = prime * result + ((id == null) ? 0 : id.hashCode());\n        return result;\n    }\n\n    @Override\n    public boolean equals(Object obj) {\n        if (this == obj)\n            return true;\n        if (obj == null)\n            return false;\n        if (getClass() != obj.getClass())\n            return false;\n        User other = (User) obj;\n        if (id == null) {\n            if (other.id != null)\n                return false;\n        } else if (!id.equals(other.id))\n            return false;\n        return true;\n    }\n\n}\n\nclass BookLoan {\n    private final Book book;\n    private final User user;\n\n    public BookLoan(Book book, User user) {\n        this.book = book;\n        this.user = user;\n    }\n\n    public Book getBook() {\n        return book;\n    }\n\n    public User getUser() {\n        return user;\n    }\n\n    @Override\n    public int hashCode() {\n        final int prime = 31;\n        int result = 1;\n        result = prime * result + ((book == null) ? 0 : book.hashCode());\n        result = prime * result + ((user == null) ? 0 : user.hashCode());\n        return result;\n    }\n\n    @Override\n    public boolean equals(Object obj) {\n        if (this == obj)\n            return true;\n        if (obj == null)\n            return false;\n        if (getClass() != obj.getClass())\n            return false;\n        BookLoan other = (BookLoan) obj;\n        if (book == null) {\n            if (other.book != null)\n                return false;\n        } else if (!book.equals(other.book))\n            return false;\n        if (user == null) {\n            if (other.user != null)\n                return false;\n        } else if (!user.equals(other.user))\n            return false;\n        return true;\n    }\n\n}\n\nclass LibraryUtil {\n    private List<Book> books = new ArrayList<>();\n    private List<User> users = new ArrayList<>();\n    private List<BookLoan> bookLoans = new ArrayList<>();\n\n    public void addBook(String title, String author, int available) {\n        books.add(new Book(title, author, available));\n    }\n\n    public void addUser(String id, String name, String email) {\n        users.add(new User(name, id, email));\n    }\n\n    public Optional<BookLoan> bookBorrow(String title, String userId) {\n        var user = users.stream().filter(aUser -> aUser.getId().equals(userId)).findFirst();\n        if (user.isEmpty())\n            return Optional.empty();\n        var book = books.stream().filter(aBook -> aBook.getTitle().equalsIgnoreCase(title)).findFirst();\n        if (book.isEmpty() || book.get().getAvailable() == 0)\n            return Optional.empty();\n        book.get().removeAvailable(1);\n        var bookLoan = new BookLoan(book.get(), user.get());\n        bookLoans.add(bookLoan);\n        return Optional.of(bookLoan);\n    }\n\n    /**\n     * Ejecuta la devolución del libro, y muestra el resultado\n     * \n     * @param title  título del libro\n     * @param userId id del usuario\n     */\n    public void returnBookAndShowResult(String title, String userId) {\n        var status = returnBook(title, userId);\n        if (status)\n            System.out.println(String.format(\"%s  retornó el libro \\\"%s\\\" correctamente\", userId, title));\n        else\n            System.err.println(String.format(\n                    \"No se encontró el libro \\\"%s\\\", no se encontró el usuario %s o el libro no se encuentra prestado al usuario\",\n                    title, userId));\n    }\n\n    /**\n     * \n     * @param title\n     * @param userId\n     * @return false is not found user, book or bookLoan. Should be better handled\n     *         with exceptions, but would be far from the scope of the problem\n     */\n    public boolean returnBook(String title, String userId) {\n        var user = users.stream().filter(aUser -> aUser.getId().equals(userId)).findFirst();\n        if (user.isEmpty())\n            return false;\n        var book = books.stream().filter(aBook -> aBook.getTitle().equalsIgnoreCase(title)).findFirst();\n        if (book.isEmpty())\n            return false;\n        var loan = bookLoans.stream()\n                .filter(bookLoan -> bookLoan.getBook().equals(book.get()) && bookLoan.getUser().equals(user.get()))\n                .findFirst();\n        loan.ifPresent(bookLoan -> {\n\n            var removed = bookLoans.removeIf(aBookLoan -> aBookLoan.equals(bookLoan));\n            if (removed)\n                book.get().addAvailable(1);\n        });\n        return loan.isPresent();\n    }\n}\n\n/**\n * Clase LibraryUtil aplicando SRP\n */\nclass SrpLibraryUtil {\n    private final UsersRepository usersRepository;\n    private final BooksRepository booksRepository;\n    private List<BookLoan> bookLoans = new ArrayList<>();\n\n    public SrpLibraryUtil(UsersRepository usersRepository, BooksRepository booksRepository) {\n        this.usersRepository = usersRepository;\n        this.booksRepository = booksRepository;\n    }\n\n    public Optional<BookLoan> bookBorrow(String title, String userId) {\n        var user = usersRepository.findById(userId);\n        var book = booksRepository.findByTitle(title);\n        if (user.isEmpty() || book.isEmpty())\n            return Optional.empty();\n        book.get().removeAvailable(1);\n        var bookLoan = new BookLoan(book.get(), user.get());\n        bookLoans.add(bookLoan);\n        return Optional.of(bookLoan);\n    }\n\n    /**\n     * \n     * @param title\n     * @param userId\n     * @return false is not found user, book or bookLoan. Should be better handled\n     *         with exceptions, but would be far from the scope of the problem\n     */\n    public boolean returnBook(String title, String userId) {\n        var user = usersRepository.findById(userId);\n        if (user.isEmpty())\n            return false;\n        var book = booksRepository.findByTitle(title);\n        if (book.isEmpty())\n            return false;\n        var loan = bookLoans.stream()\n                .filter(bookLoan -> bookLoan.getBook().equals(book.get()) && bookLoan.getUser().equals(user.get()))\n                .findFirst();\n        loan.ifPresent(bookLoan -> {\n\n            var removed = bookLoans.removeIf(aBookLoan -> aBookLoan.equals(bookLoan));\n            if (removed)\n                book.get().addAvailable(1);\n        });\n        return loan.isPresent();\n    }\n\n    /**\n     * Realiza la devolución del libro, y muestra el resultado.\n     * La responsalidad de mostrar el resultado está en otra clase\n     * \n     * @param title      Título del libro\n     * @param userId     ID del usuario\n     * @param showResult Instancia que muestra el resultado de la devolución del\n     *                   libro\n     */\n    public void returnBookAndShowResult(String title, String userId, ShowResult showResult) {\n        showResult.showResult(returnBook(title, userId), title, userId);\n    }\n}\n\n/**\n * Repositorio de usuarios\n */\nclass UsersRepository {\n    private List<User> users = new ArrayList<>();\n\n    public void addUser(String id, String name, String email) {\n        users.add(new User(name, id, email));\n    }\n\n    public Optional<User> findById(String userId) {\n        return users.stream().filter(aUser -> aUser.getId().equals(userId)).findFirst();\n    }\n}\n\nclass BooksRepository {\n    private List<Book> books = new ArrayList<>();\n\n    public void addBook(String title, String author, int available) {\n        books.add(new Book(title, author, available));\n    }\n\n    public Optional<Book> findByTitle(String title) {\n        return books.stream().filter(aBook -> aBook.getTitle().equalsIgnoreCase(title) && aBook.getAvailable() > 0)\n                .findFirst();\n    }\n}\n\n@FunctionalInterface\ninterface ShowResult {\n\n    void showResult(boolean returnBookStatus, String title, String userId);\n}"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/java/eulogioep.java",
    "content": "// Archivo: eulogioep.java\n\n/**\n * PRINCIPIO DE RESPONSABILIDAD ÚNICA (SRP)\n * \n * El Principio de Responsabilidad Única establece que:\n * \"Una clase debe tener una única razón para cambiar\"\n * \n * Este principio nos ayuda a:\n * - Crear código más mantenible\n * - Facilitar las pruebas unitarias\n * - Reducir el acoplamiento\n * - Mejorar la cohesión del código\n * - Facilitar la reutilización\n */\n\n import java.util.ArrayList;\n import java.util.Date;\n import java.util.List;\n import java.util.UUID;\n import java.util.stream.Collectors;\n \n public class eulogioep {\n     public static void main(String[] args) {\n         // Ejemplo de uso del sistema\n         try {\n             // Creación de los managers\n             BookManager bookManager = new BookManager();\n             UserManager userManager = new UserManager();\n             LoanManager loanManager = new LoanManager(bookManager, userManager);\n \n             // Agregar un libro\n             Book book = bookManager.addBook(\"El Quijote\", \"Miguel de Cervantes\", 5);\n             System.out.println(\"Libro agregado: \" + book);\n \n             // Registrar un usuario\n             User user = userManager.registerUser(\"Juan Pérez\", \"USER001\", \"juan@email.com\");\n             System.out.println(\"Usuario registrado: \" + user);\n \n             // Realizar un préstamo\n             Loan loan = loanManager.loanBook(user.getId(), book.getId());\n             System.out.println(\"Préstamo realizado: \" + loan);\n \n             // Devolver el libro\n             loanManager.returnBook(user.getId(), book.getId());\n             System.out.println(\"Libro devuelto exitosamente\");\n \n             // Verificar el estado del libro\n             Book updatedBook = bookManager.findBook(book.getId());\n             System.out.println(\"Estado actual del libro: \" + updatedBook);\n \n         } catch (Exception e) {\n             System.err.println(\"Error: \" + e.getMessage());\n         }\n     }\n }\n \n // ========== IMPLEMENTACIÓN INCORRECTA (Violando SRP) ==========\n \n /**\n  * Esta implementación viola el SRP porque la clase Library maneja múltiples responsabilidades:\n  * 1. Gestión de libros\n  * 2. Gestión de usuarios\n  * 3. Gestión de préstamos\n  */\n class Library {\n     private List<Book> books;\n     private List<User> users;\n     private List<Loan> loans;\n \n     public Library() {\n         this.books = new ArrayList<>();\n         this.users = new ArrayList<>();\n         this.loans = new ArrayList<>();\n     }\n \n     // Gestión de libros\n     public void addBook(String title, String author, int copies) {\n         Book book = new Book(title, author, copies);\n         books.add(book);\n     }\n \n     public void removeBook(String bookId) {\n         books.removeIf(book -> book.getId().equals(bookId));\n     }\n \n     // Gestión de usuarios\n     public void registerUser(String name, String id, String email) {\n         User user = new User(name, id, email);\n         users.add(user);\n     }\n \n     public void removeUser(String userId) {\n         users.removeIf(user -> user.getId().equals(userId));\n     }\n \n     // Gestión de préstamos\n     public void loanBook(String userId, String bookId) throws Exception {\n         Book book = books.stream()\n                         .filter(b -> b.getId().equals(bookId))\n                         .findFirst()\n                         .orElseThrow(() -> new Exception(\"Libro no encontrado\"));\n \n         User user = users.stream()\n                         .filter(u -> u.getId().equals(userId))\n                         .findFirst()\n                         .orElseThrow(() -> new Exception(\"Usuario no encontrado\"));\n \n         if (book.getAvailableCopies() <= 0) {\n             throw new Exception(\"No hay copias disponibles\");\n         }\n \n         book.decrementCopies();\n         loans.add(new Loan(userId, bookId, new Date()));\n     }\n \n     public void returnBook(String userId, String bookId) throws Exception {\n         Loan loan = findLoan(userId, bookId);\n         if (loan == null) {\n             throw new Exception(\"Préstamo no encontrado\");\n         }\n \n         Book book = books.stream()\n                         .filter(b -> b.getId().equals(bookId))\n                         .findFirst()\n                         .orElse(null);\n \n         if (book != null) {\n             book.incrementCopies();\n         }\n \n         loans.removeIf(l -> l.getUserId().equals(userId) && l.getBookId().equals(bookId));\n     }\n \n     private Loan findLoan(String userId, String bookId) {\n         return loans.stream()\n                    .filter(l -> l.getUserId().equals(userId) && l.getBookId().equals(bookId))\n                    .findFirst()\n                    .orElse(null);\n     }\n }\n \n // ========== IMPLEMENTACIÓN CORRECTA (Siguiendo SRP) ==========\n \n /**\n  * BookManager: Responsable únicamente de la gestión de libros\n  */\n class BookManager {\n     private List<Book> books;\n \n     public BookManager() {\n         this.books = new ArrayList<>();\n     }\n \n     public Book addBook(String title, String author, int copies) {\n         Book book = new Book(title, author, copies);\n         books.add(book);\n         return book;\n     }\n \n     public void removeBook(String bookId) {\n         books.removeIf(book -> book.getId().equals(bookId));\n     }\n \n     public Book findBook(String bookId) {\n         return books.stream()\n                    .filter(book -> book.getId().equals(bookId))\n                    .findFirst()\n                    .orElse(null);\n     }\n \n     public void updateBookCopies(String bookId, int change) {\n         Book book = findBook(bookId);\n         if (book != null) {\n             if (change > 0) {\n                 book.incrementCopies();\n             } else {\n                 book.decrementCopies();\n             }\n         }\n     }\n \n     public List<Book> getAllBooks() {\n         return new ArrayList<>(books);\n     }\n }\n \n /**\n  * UserManager: Responsable únicamente de la gestión de usuarios\n  */\n class UserManager {\n     private List<User> users;\n \n     public UserManager() {\n         this.users = new ArrayList<>();\n     }\n \n     public User registerUser(String name, String id, String email) {\n         User user = new User(name, id, email);\n         users.add(user);\n         return user;\n     }\n \n     public void removeUser(String userId) {\n         users.removeIf(user -> user.getId().equals(userId));\n     }\n \n     public User findUser(String userId) {\n         return users.stream()\n                    .filter(user -> user.getId().equals(userId))\n                    .findFirst()\n                    .orElse(null);\n     }\n \n     public List<User> getAllUsers() {\n         return new ArrayList<>(users);\n     }\n }\n \n /**\n  * LoanManager: Responsable únicamente de la gestión de préstamos\n  */\n class LoanManager {\n     private List<Loan> loans;\n     private final BookManager bookManager;\n     private final UserManager userManager;\n \n     public LoanManager(BookManager bookManager, UserManager userManager) {\n         this.loans = new ArrayList<>();\n         this.bookManager = bookManager;\n         this.userManager = userManager;\n     }\n \n     public Loan loanBook(String userId, String bookId) throws Exception {\n         Book book = bookManager.findBook(bookId);\n         User user = userManager.findUser(userId);\n \n         if (book == null || user == null) {\n             throw new Exception(\"Libro o usuario no encontrado\");\n         }\n \n         if (book.getAvailableCopies() <= 0) {\n             throw new Exception(\"No hay copias disponibles\");\n         }\n \n         bookManager.updateBookCopies(bookId, -1);\n         Loan loan = new Loan(userId, bookId, new Date());\n         loans.add(loan);\n         return loan;\n     }\n \n     public void returnBook(String userId, String bookId) throws Exception {\n         Loan loan = findLoan(userId, bookId);\n         if (loan == null) {\n             throw new Exception(\"Préstamo no encontrado\");\n         }\n \n         bookManager.updateBookCopies(bookId, 1);\n         loans.removeIf(l -> l.getUserId().equals(userId) && l.getBookId().equals(bookId));\n     }\n \n     private Loan findLoan(String userId, String bookId) {\n         return loans.stream()\n                    .filter(loan -> loan.getUserId().equals(userId) && loan.getBookId().equals(bookId))\n                    .findFirst()\n                    .orElse(null);\n     }\n \n     public List<Loan> getAllLoans() {\n         return new ArrayList<>(loans);\n     }\n }\n \n // Clases de modelo\n class Book {\n     private final String id;\n     private final String title;\n     private final String author;\n     private int availableCopies;\n \n     public Book(String title, String author, int availableCopies) {\n         this.id = UUID.randomUUID().toString();\n         this.title = title;\n         this.author = author;\n         this.availableCopies = availableCopies;\n     }\n \n     public String getId() {\n         return id;\n     }\n \n     public String getTitle() {\n         return title;\n     }\n \n     public String getAuthor() {\n         return author;\n     }\n \n     public int getAvailableCopies() {\n         return availableCopies;\n     }\n \n     public void incrementCopies() {\n         this.availableCopies++;\n     }\n \n     public void decrementCopies() {\n         this.availableCopies--;\n     }\n \n     @Override\n     public String toString() {\n         return \"Book{\" +\n                \"id='\" + id + '\\'' +\n                \", title='\" + title + '\\'' +\n                \", author='\" + author + '\\'' +\n                \", availableCopies=\" + availableCopies +\n                '}';\n     }\n }\n \n class User {\n     private final String id;\n     private final String name;\n     private final String email;\n \n     public User(String name, String id, String email) {\n         this.name = name;\n         this.id = id;\n         this.email = email;\n     }\n \n     public String getId() {\n         return id;\n     }\n \n     public String getName() {\n         return name;\n     }\n \n     public String getEmail() {\n         return email;\n     }\n \n     @Override\n     public String toString() {\n         return \"User{\" +\n                \"id='\" + id + '\\'' +\n                \", name='\" + name + '\\'' +\n                \", email='\" + email + '\\'' +\n                '}';\n     }\n }\n \n class Loan {\n     private final String userId;\n     private final String bookId;\n     private final Date loanDate;\n \n     public Loan(String userId, String bookId, Date loanDate) {\n         this.userId = userId;\n         this.bookId = bookId;\n         this.loanDate = loanDate;\n     }\n \n     public String getUserId() {\n         return userId;\n     }\n \n     public String getBookId() {\n         return bookId;\n     }\n \n     public Date getLoanDate() {\n         return loanDate;\n     }\n \n     @Override\n     public String toString() {\n         return \"Loan{\" +\n                \"userId='\" + userId + '\\'' +\n                \", bookId='\" + bookId + '\\'' +\n                \", loanDate=\" + loanDate +\n                '}';\n     }\n }"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/java/martinbohorquez.java",
    "content": "import java.util.*;\n\n/**\n * #26 SOLID: PRINCIPIO DE RESPONSABILIDAD ÚNICA (SRP)\n *\n * @author martinbohorquez\n */\npublic class martinbohorquez {\n    static List<User> users = new ArrayList<>();\n    static List<Usuario> usuarios = new ArrayList<>();\n\n    public static void main(String[] args) {\n        incorrectSrp();\n        correctSrp();\n        /*\n         * DIFICULTAD EXTRA\n         */\n        addExerciseNoSrp();\n\n    }\n\n    private static void addExerciseNoSrp() {\n        Library library = new Library();\n        library.addBook(\"Libro 1\", \"Autor 1\", 2);\n        library.addBook(\"Libro 2\", \"Autor 2\", 1);\n        System.out.printf(\"La lista de libros es: %s%n\", library.books);\n        library.addUser(\"User 1\", 1, \"user1@gmail.com\");\n        library.addUser(\"User 2\", 2, \"user2@gmail.com\");\n        library.addUser(\"User 3\", 3, \"user3@gmail.com\");\n        System.out.printf(\"La lista de usuarios es: %s%n\", library.users);\n        library.loanBook(2, \"Libro 1\");\n        library.loanBook(3, \"Libro 2\");\n        library.loanBook(1, \"Libro 2\");\n        library.loanBook(1, \"Libro 1\");\n        System.out.printf(\"La lista de prestámos es: %s%n\", library.loans);\n        library.returnBook(2, \"Libro 2\");\n        library.returnBook(2, \"Libro 1\");\n        System.out.printf(\"La lista de prestámos es: %s%n\", library.loans);\n    }\n\n    private static void addExerciseSrp() {\n        Biblioteca biblioteca = new Biblioteca();\n        Book book1 = new Book(\"Libro 1\", \"Autor 1\", 2);\n        Book book2 = new Book(\"Libro 2\", \"Autor 2\", 1);\n        biblioteca.addBook(book1);\n        biblioteca.addBook(book2);\n        System.out.printf(\"La lista de libros es: %s%n\", biblioteca.books);\n        Usero user1 = new Usero(\"User 1\", 1, \"user1@gmail.com\");\n        Usero user2 = new Usero(\"User 2\", 2, \"user2@gmail.com\");\n        Usero user3 = new Usero(\"User 3\", 3, \"user3@gmail.com\");\n        biblioteca.addUser(user1);\n        biblioteca.addUser(user2);\n        biblioteca.addUser(user3);\n        System.out.printf(\"La lista de usuarios es: %s%n\", biblioteca.users);\n        biblioteca.loanBook(2, \"Libro 1\");\n        biblioteca.loanBook(3, \"Libro 2\");\n        biblioteca.loanBook(1, \"Libro 2\");\n        biblioteca.loanBook(1, \"Libro 1\");\n        System.out.printf(\"La lista de prestámos es: %s%n\", biblioteca.loans);\n        biblioteca.returnBook(2, \"Libro 2\");\n        biblioteca.returnBook(2, \"Libro 1\");\n        System.out.printf(\"La lista de prestámos es: %s%n\", biblioteca.loans);\n    }\n\n    private static void incorrectSrp() {\n        User user1 = new User(\"Jose\", \"josesc3@gmail.com\");\n        User user2 = new User(\"Luis\", \"luisc5@gmail.com\");\n        user1.saveDatabase();\n        user2.saveDatabase();\n        user1.sendEmail(\"Mensaje enviado desde la una instancia que no aplica el principio de SRP!\");\n        user2.sendEmail(\"Mensaje 2 enviado desde la una instancia que no aplica el principio de SRP!\");\n    }\n\n    private static void correctSrp() {\n        Usuario usuario1 = new Usuario(\"Jose\", \"josesc3@gmail.com\");\n        Usuario usuario2 = new Usuario(\"Luis\", \"luisc5@gmail.com\");\n        UsuarioService usuarioService = new UsuarioService();\n        usuarioService.saveDatabase(usuario1)\n                .saveDatabase(usuario2);\n        EmailService emailService = new EmailService();\n        emailService.sendEmail(usuario1,\n                \"Mensaje enviado desde la una instancia que aplica el principio de SRP!\");\n        emailService.sendEmail(usuario2,\n                \"Mensaje 2 enviado desde la una instancia que aplica el principio de SRP!\");\n    }\n\n    static class User {\n        private final String name;\n        private final String email;\n\n        User(String name, String email) {\n            this.name = name;\n            this.email = email;\n        }\n\n        protected void saveDatabase() {\n            users.add(this);\n            System.out.printf(\"Se ha creado el usuario con nombre %s%n\", name);\n        }\n\n        protected void sendEmail(String message) {\n            System.out.printf(\"Se envía correo desde '%s':%n%s%n\", email, message);\n        }\n    }\n\n    static class Usuario {\n        private final String name;\n        private final String email;\n\n        Usuario(String name, String email) {\n            this.name = name;\n            this.email = email;\n        }\n    }\n\n    static class UsuarioService {\n        protected UsuarioService saveDatabase(Usuario usuario) {\n            usuarios.add(usuario);\n            System.out.printf(\"Se ha creado el usuario con nombre %s (usando SRP)%n\", usuario.name);\n            return this;\n        }\n    }\n\n    static class EmailService {\n        protected void sendEmail(Usuario usuario, String message) {\n            System.out.printf(\"Se envía correo desde '%s':%n%s%n\", usuario.email, message);\n        }\n    }\n\n    static class Library {\n        private List<Map<String, Object>> books;\n        private List<Map<String, Object>> users;\n        private List<Map<String, Object>> loans;\n\n        public Library() {\n            this.books = new ArrayList<>();\n            this.users = new ArrayList<>();\n            this.loans = new ArrayList<>();\n        }\n\n        private void addBook(String title, String author, Integer copies) {\n            Map<String, Object> book = new HashMap<>();\n            book.put(\"title\", title);\n            book.put(\"author\", author);\n            book.put(\"copies\", copies);\n            books.add(book);\n        }\n\n        private void addUser(String name, Integer id, String email) {\n            Map<String, Object> user = new HashMap<>();\n            user.put(\"name\", name);\n            user.put(\"id\", id);\n            user.put(\"email\", email);\n            users.add(user);\n        }\n\n        private void loanBook(Integer userId, String bookTitle) {\n            books.stream()\n                    .filter(b -> b.get(\"title\").equals(bookTitle) && (Integer) b.get(\"copies\") > 0)\n                    .findFirst()\n                    .ifPresent(b -> {\n                        b.put(\"copies\", (Integer) b.get(\"copies\") - 1);\n                        Map<String, Object> loan = new HashMap<>();\n                        loan.put(\"userId\", userId);\n                        loan.put(\"bookTitle\", bookTitle);\n                        loans.add(loan);\n                    });\n        }\n\n        private void returnBook(Integer userId, String bookTitle) {\n            loans.stream()\n                    .filter(l -> l.get(\"userId\").equals(userId) && l.get(\"bookTitle\").equals(bookTitle))\n                    .findFirst()\n                    .ifPresent(l -> {\n                        loans.remove(l);\n                        books.stream()\n                                .filter(b -> b.get(\"title\").equals(bookTitle))\n                                .findFirst()\n                                .ifPresent(b -> b.put(\"copies\", (Integer) b.get(\"copies\") + 1));\n                    });\n        }\n    }\n\n    static class Biblioteca {\n        private List<Book> books;\n        private List<Usero> users;\n        private Loan loans;\n\n        public Biblioteca() {\n            this.books = new ArrayList<>();\n            this.users = new ArrayList<>();\n            this.loans = new Loan();\n        }\n\n        private void addBook(Book book) {\n            books.add(book);\n        }\n\n        private void addUser(Usero user) {\n            users.add(user);\n        }\n\n        private void loanBook(Integer userId, String bookTitle) {\n            Optional<Usero> user = users.stream().filter(u -> u.id.equals(userId)).findAny();\n            Optional<Book> book = books.stream().filter(b -> b.title.equals(bookTitle)).findAny();\n            if (user.isPresent() && book.isPresent()) loans.loanBook(user.get(), book.get());\n\n        }\n\n        private void returnBook(Integer userId, String bookTitle) {\n            Optional<Usero> user = users.stream().filter(u -> u.id.equals(userId)).findAny();\n            Optional<Book> book = books.stream().filter(b -> b.title.equals(bookTitle)).findAny();\n            if (user.isPresent() && book.isPresent()) loans.returnBook(user.get(), book.get());\n        }\n    }\n\n    static class Book {\n        private String title;\n        private String author;\n        private Integer copies;\n\n        public Book(String title, String author, Integer copies) {\n            this.title = title;\n            this.author = author;\n            this.copies = copies;\n        }\n    }\n\n    static class Usero {\n        private String name;\n        private Integer id;\n        private String email;\n\n        public Usero(String name, Integer id, String email) {\n            this.name = name;\n            this.id = id;\n            this.email = email;\n        }\n    }\n\n    static class Loan {\n        private List<Map<String, Object>> loans;\n\n        public Loan() {\n            List<Loan> loans = new ArrayList<>();\n        }\n\n        private void loanBook(Usero user, Book book) {\n            if (book.copies > 0) {\n                book.copies--;\n                Map<String, Object> loan = new HashMap<>();\n                loan.put(\"userId\", user.id);\n                loan.put(\"bookTitle\", book.title);\n                loans.add(loan);\n            }\n        }\n\n        private void returnBook(Usero user, Book book) {\n            loans.stream()\n                    .filter(loan -> loan.get(\"userId\").equals(user.id) && loan.get(\"bookTitle\").equals(book.title))\n                    .findFirst()\n                    .ifPresent(loan -> {\n                        loans.remove(loan);\n                        book.copies++;\n                    });\n        }\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/java/simonguzman.java",
    "content": "\nimport java.io.FileWriter;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\npublic class simonguzman {\n    public static void main(String[] args) {\n        //incorrectSrp();\n        //correctSrp();\n        //additionalExerciseNoSrp();\n        additionalExerciseSrp();\n    }\n    /****************************** Ejercicio adicional(Con srp) ******************************/\n    public static void additionalExerciseSrp(){\n        BookManager bookManager = new BookManager();\n        UserManager userManager = new UserManager();\n        LoanManager loanManager = new LoanManager();\n\n        bookManager.registerBook(\"1984\", \"George Orwell\", 3);\n        userManager.registerUser(\"John Doe\", \"001\", \"johndoe@example.com\");\n\n        User user = userManager.findUserById(\"001\");\n        Book book = bookManager.findBookByTitle(\"1984\");\n\n        loanManager.borrowBook(user, book);\n        loanManager.returnBook(user, book);\n    }\n\n    class BookSrp {\n        private String title;\n        private String author;\n        private int copies;\n    \n        public BookSrp(){\n\n        }\n\n        public BookSrp(String title, String author, int copies) {\n            this.title = title;\n            this.author = author;\n            this.copies = copies;\n        }\n    \n        public String getTitle() {\n            return title;\n        }\n    \n        public int getCopies() {\n            return copies;\n        }\n    \n        public void setCopies(int copies) {\n            this.copies = copies;\n        }\n    }\n    \n    class UserSrp {\n        private String name;\n        private String id;\n        private String email;\n    \n        public UserSrp(){\n\n        }\n\n        public UserSrp(String name, String id, String email) {\n            this.name = name;\n            this.id = id;\n            this.email = email;\n        }\n    \n        public String getName() {\n            return name;\n        }\n    \n        public String getId() {\n            return id;\n        }\n    }\n    \n    static class BookManager{\n        private List<Book> books = new ArrayList<>();\n        \n        public void registerBook(String title, String author, int copies){\n            books.add(new Book(title, author, copies));\n            System.out.println(\"Libro registrado: \" + title);\n        }\n\n        public Book findBookByTitle(String title){\n            return books.stream().filter(b -> b.getTitle().equals(title)).findFirst().orElse(null);\n        }\n    }\n\n    static class UserManager{\n        private List<User> users = new ArrayList<>();\n\n        public void registerUser(String name, String id, String email){\n            users.add(new User(name, id, email));\n            System.out.println(\"Usuario registrado: \" + name);\n        }\n\n        public User findUserById(String id){\n            return users.stream().filter(u -> u.getId().equals(id)).findFirst().orElse(null);\n        }\n    }\n\n    static class LoanManager{\n        private Map<User, List<Book>> borrowedBooks = new HashMap<>();\n\n        public void borrowBook(User user, Book book) {\n            if (book != null && book.getCopies() > 0) {\n                borrowedBooks.computeIfAbsent(user, k -> new ArrayList<>()).add(book);\n                book.setCopies(book.getCopies() - 1);\n                System.out.println(\"Libro prestado: \" + book.getTitle() + \" a \" + user.getName());\n            } else {\n                System.out.println(\"No se pudo procesar el préstamo.\");\n            }\n        }\n\n        public void returnBook(User user, Book book) {\n            List<Book> borrowed = borrowedBooks.get(user);\n            if (borrowed != null && borrowed.contains(book)) {\n                borrowed.remove(book);\n                book.setCopies(book.getCopies() + 1);\n                System.out.println(\"Libro devuelto: \" + book.getTitle());\n            } else {\n                System.out.println(\"No se pudo devolver el libro.\");\n            }\n        }\n    }\n\n    /****************************** Ejercicio adicional(Sin srp) ******************************/\n    public static void additionalExerciseNoSrp(){\n        Library library = new Library();\n\n        library.registerBook(\"1984\", \"George Orwell\", 3);\n        library.registerUser(\"John Doe\", \"001\", \"johndoe@example.com\");\n\n        library.borrowBook(\"001\", \"1984\");\n        library.returnBook(\"001\", \"1984\");\n    }\n\n    static class Library{\n        private List<Book> books = new ArrayList<>();\n        private List<User> users = new ArrayList<>();\n        private Map<User, List<Book>> borrowedBooks = new HashMap<>();\n\n        public void registerBook(String title, String author, int copies){\n            books.add(new Book(title, author, copies));\n            System.out.println(\"Libro registrado: \"+title);\n        }\n\n        public void registerUser(String name, String id, String email){\n            users.add(new User(name, id, email));\n            System.out.println(\"Usuario registrado: \"+name);\n        }\n\n        public void borrowBook(String userId, String bookTitle){\n            User user = users.stream().filter(u -> u.getId().equals(userId)).findFirst().orElse(null);\n            Book book = books.stream().filter(b -> b.getTitle().equals(bookTitle)).findFirst().orElse(null);\n\n            if(user != null && book != null && book.getCopies() > 0){\n                borrowedBooks.computeIfAbsent(user, k -> new ArrayList<>()).add(book);\n                book.setCopies(book.getCopies()-1);\n                System.out.println(\"Libro prestado: \" + bookTitle + \" a \" + user.getName());\n            }else{\n                System.out.println(\"No se pudo procesar el prestamo.\");\n            }\n        }\n\n        public void returnBook(String userId, String bookTitle){\n            User user = users.stream().filter(u -> u.getId().equals(userId)).findFirst().orElse(null);\n            List<Book> borrowed = borrowedBooks.get(user); \n\n            if(borrowed != null){\n                Book book = borrowed.stream().filter(b -> b.getTitle().equals(bookTitle)).findFirst().orElse(null);\n                if(book != null){\n                    borrowed.remove(book);\n                    book.setCopies(book.getCopies() + 1);\n                    System.out.println(\"Libro devuelto: \"+bookTitle);\n                }\n            }else{\n                System.out.println(\"ERROR: No se pudo devolver el libro.\");\n            }\n        }\n    }\n\n    static class Book{\n        private String title;\n        private String author;\n        private int copies;\n\n        public Book(){\n\n        }\n\n        public Book(String title, String author, int copies){\n            this.title = title;\n            this.author = author;\n            this.copies = copies;\n        }\n\n        public String getTitle() {\n            return title;\n        }\n\n        public int getCopies() {\n            return copies;\n        }\n\n        public void setCopies(int copies) {\n            this.copies = copies;\n        }\n\n    }\n\n    static class User{\n        private String name;\n        private String id;\n        private String email;\n\n        public User(){\n\n        }\n\n        public User(String name, String id, String email){\n            this.name = name;\n            this.id = id;\n            this.email = email;\n        }\n\n        public String getName() {\n            return name;\n        }\n\n        public String getId() {\n            return id;\n        }\n\n        public String getEmail() {\n            return email;\n        }\n    }\n\n    /****************************** ejemplo con srp(Correcto) ******************************/\n    public static void correctSrp() {\n        InvoiceSrp invoice = new InvoiceSrp(\"Laptop\",2,1200.00);\n\n        InvoicePrinter printer = new InvoicePrinter();\n        printer.printInvoice(invoice);\n\n        InvoiceSaver saver = new InvoiceSaver();\n        saver.saveToFile(invoice);\n    }\n    static class InvoiceSrp{\n        private String product;\n        private int quantity;\n        private double price;\n\n        public InvoiceSrp(){\n            \n        }\n\n        public InvoiceSrp(String product, int quantity, double price){\n            this.product = product;\n            this.quantity = quantity;\n            this.price = price;\n        }\n\n        public double calculateTotal(){\n            return quantity * price;\n        }\n\n        public String getProduct() {\n            return product;\n        }\n\n        public int getQuantity() {\n            return quantity;\n        }\n\n        public double getPrice() {\n            return price;\n        }\n    }\n\n    static class InvoicePrinter {\n        public void printInvoice(InvoiceSrp invoice){\n            System.out.println(\"Producto: \"+invoice.getProduct());\n            System.out.println(\"Cantidad: \"+invoice.getQuantity());\n            System.out.println(\"Precio: \"+invoice.getPrice());\n            System.out.println(\"Total: \"+invoice.calculateTotal());\n        }\n    }\n\n    static class InvoiceSaver{\n        public void saveToFile(InvoiceSrp invoice){\n            try (FileWriter writer = new FileWriter(\"invoice.txt\")){\n                writer.write(\"Producto: \" + invoice.getProduct() + \"\\n\");\n                writer.write(\"Cantidad: \" + invoice.getQuantity() + \"\\n\");\n                writer.write(\"Precio unitario: \" + invoice.getPrice() + \"\\n\");\n                writer.write(\"Total: \" + invoice.calculateTotal() + \"\\n\");\n            } catch (Exception e) {\n                System.out.println(\"ERROR: no se pudo generar la factura...\"+e.getMessage());\n            }\n        }\n    }\n    /****************************** ejemplo sin srp(Incorrecto) ******************************/\n    public static void incorrectSrp(){\n        Invoice invoice = new Invoice(\"Laptop\",2,1200.00);\n        invoice.printInvoice();\n        invoice.saveToFile();\n    }\n\n    static class Invoice{\n        private String product;\n        private int quantity;\n        private double price;\n\n        public Invoice(){\n\n        }\n\n        public Invoice(String product, int quantity, double price){\n            this.product = product;\n            this.quantity = quantity;\n            this.price = price;\n        }\n\n        public double calculateTotal(){\n            return quantity * price;\n        }\n\n        public void printInvoice(){\n            System.out.println(\"Producto: \"+product);\n            System.out.println(\"Cantidad: \"+quantity);\n            System.out.println(\"Precio: \"+price);\n            System.out.println(\"Total: \"+calculateTotal());\n        }\n        \n        public void saveToFile(){\n            try (FileWriter writer = new FileWriter(\"invoice.txt\")){\n                writer.write(\"Producto: \" + product + \"\\n\");\n                writer.write(\"Cantidad: \" + quantity + \"\\n\");\n                writer.write(\"Precio Unitario: \" + price + \"\\n\");\n                writer.write(\"Total: \" + calculateTotal() + \"\\n\");\n            } catch (Exception e) {\n                System.out.println(\"Error al guardar la factura: \"+e.getMessage());\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/javascript/Chrisdev00.js",
    "content": "/*\n* EJERCICIO:\n* Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n* Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n* de forma correcta e incorrecta.\n*\n* DIFICULTAD EXTRA (opcional):\n* Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n* manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n* y el procesamiento de préstamos de libros.\n* Requisitos:\n* 1. Registrar libros: El sistema debe permitir agregar nuevos libros con \n* información básica como título, autor y número de copias disponibles.\n* 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n* información básica como nombre, número de identificación y correo electrónico.\n* 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n* tomar prestados y devolver libros.\n* Instrucciones:\n* 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n* los tres aspectos mencionados anteriormente (registro de libros, registro de\n* usuarios y procesamiento de préstamos).\n* 2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n* siguiendo el Principio de Responsabilidad Única.\n*/\n\n// Ejemplo de Forma incorrecta \n\nclass Order {\n  constructor(items, taxRate){\n    this.items = items;\n    this.taxRate = taxRate;\n  }\n\n  calculateTotal() {\n    let total = this.items.reduce((sum, item) => sum + item[1], 0);\n    const discount = 5\n    let tax = (total - discount) * this.taxRate\n    return total - discount + tax;\n  }\n\n  generateInvoice(){\n    const total = this.calculateTotal()\n    let invoice = \"Factura:\\n\";\n    this.items.forEach(([item, price]) => {\n      invoice += `${item}: $${price}\\n`;\n    });\n    invoice += `Total (incluyendo impuestos): $${total.toFixed(2)}\\n`;\n    return invoice;\n  }\n\n  sendConfirmationEmail(email){\n    const invoice = this.generateInvoice();\n    console.log(`Enviando email a ${email} con la siguiente Factura:\\n${invoice}`);\n\n  }\n}\n\nconst order1 = new Order([['item1', 10], ['item2', 20]], 0.1);\nconsole.log(order1.generateInvoice());\norder1.sendConfirmationEmail('example@example.com');\n\n\n// Manera Correcta cumpliendo el Principio de Responsabilidad Única (SRP)\n\nclass Order {\n  constructor(items){\n    this.items = items;\n  }\n\n  getTotal() {\n    return this.items.reduce((sum, item) => sum + item[1], 0);\n  }\n}\n\nclass TaxCalculator {\n  constructor(taxRate, discount = 5) {\n    this.taxRate = taxRate;\n    this.discount = discount;\n  }\n\n  calculateTax(total) {\n    return (total - this.discount) * this.taxRate;\n  }\n\n  calculateFinalTotal(total) {\n    const tax = this.calculateTax(total);\n    return total - this.discount + tax;\n  }\n}\n\nclass InvoiceGenerator {\n  generateInvoice(order, finalTotal) {\n    let invoice = \"Factura:\\n\";\n    order.items.forEach(([item, price]) => {\n      invoice += `${item}: $${price}\\n`;\n    });\n    invoice += `Total (incluyendo impuestos): $${finalTotal.toFixed(2)}\\n`;\n    return invoice;\n  }\n}\n\nclass EmailSender {\n  sendConfirmationEmail(email, invoice) {\n    console.log(`Enviando email a ${email} con la siguiente Factura:\\n${invoice}`);\n  }\n}\n\n// Uso del código\nconst order = new Order([['item1', 10], ['item2', 20]]);\nconst taxCalculator = new TaxCalculator(0.1);\nconst invoiceGenerator = new InvoiceGenerator();\nconst emailSender = new EmailSender();\n\nconst total = order.getTotal();\nconst finalTotal = taxCalculator.calculateFinalTotal(total);\nconst invoice = invoiceGenerator.generateInvoice(order, finalTotal);\n\nconsole.log(invoice);\nemailSender.sendConfirmationEmail('example@example.com', invoice);\n\n\n\n/////////////-------------------------- EXTRA --------------------------- ////////////////////////////////\n\n\n// Manera Incorrecta del ejercicio\n\nclass LibraryOne{\n\n  constructor(){\n    this.books = []\n    this.users = []\n    this.loans = []\n  }\n\n  addBook(title, author, copies){\n    let book = {\"title\": title, \"author\": author, \"copies\": copies};\n    this.books.push(book)\n  }\n\n  addUser(name, userId, email){\n    let user = {\"name\": name, \"userId\": userId, \"email\": email};\n    this.users.push(user)\n  }\n\n  borrowBook(userId, title){\n    for (let book of this.books){\n      if (book.title === title && book.copies > 0){\n        book.copies -= 1;\n        const loan = {\"userId\": userId, \"title\": title};\n        this.loans.push(loan);\n        return `El usuario '${userId}' se presto el libro '${title}'.`;\n      }\n    }\n    return `Libro '${title}' no esta disponible.`\n  }\n\n  returnBook(userId, title){\n    for (let loan of this.loans){\n      if(loan.userId === userId && loan.title === title){\n        this.loans = this.loans.filter(1 >= 1 !== loan);\n        for (let book of this.books){\n          if(book.title === title){\n            book.copies += 1;\n          }\n        }\n        return `Libro '${title}' retornado por el usuario '${userId}'.`;\n      }\n    }\n    return `No hay registro de que el usuario '${userId}' se haya prestado el libro '${title}'.`;\n  }\n}\n\nconst library1 = new LibraryOne();\n\nlibrary1.addBook(\"Lord of the Rings\", \"JRR Tolkien\", 4);\nlibrary1.addBook(\"Harry Potter\", \"JK Rowling\", 2);\n\nlibrary1.addUser(\"Alice\", \"1\", \"alice@example.com\");\nlibrary1.addUser(\"Matias\", \"2\", \"matias@example.com\");\n\nconsole.log(library1.borrowBook(\"1\", \"Lord of the Rings\"));\nconsole.log(library1.borrowBook(\"2\", \"Harry Potter\"));\nconsole.log(library1.borrowBook(\"1\", \"Lord of the Rings\"));\nconsole.log(library1.returnBook(\"2\", \"The Great Gatsby\"));\n\n\n// Manera Correcta cumpliendo el Principio de Responsabilidad Única (SRP)\n\n\nclass Library{\n    constructor(){\n      this.books = [];\n      this.users = [];\n    }\n  \n    addBook(book){\n      this.books.push(book)\n    }\n  \n    addUser(user){\n      this.users.push(user);\n    }\n  \n    findBook(title){\n      return this.books.find(book => book.title === title) || null;\n    }\n  \n    findUser(userId){\n      return this.users.find(user => user.userId === userId) || null;\n    }\n  \n    totalBooks(){\n      return this.books.reduce((sum, book) => sum + book.copies, 0);\n    }\n  \n    getLibraryInfo(){\n      const totalBooks = this.totalBooks();\n      const booksInfo = this.books.map(book => book.showInfo());\n      return {totalBooks, booksInfo};\n    }\n  \n}\n  \nclass Book{\n    constructor(title, author, copies){\n      this.title = title;\n      this.author = author;\n      this.copies = copies;\n    }\n  \n    showInfo(){\n      return `'${this.title}' por '${this.author}', numero de copias '${this.copies}'`;\n    }\n}\n  \nclass User{\n    constructor(name, userId, email){\n      this.name = name\n      this.userId = userId\n      this.email = email\n      this.loans = []\n    }\n}\n  \nclass LoanProcess{\n    borrowBook(library, userId, title){\n      let user = library.findUser(userId);\n      let book = library.findBook(title);\n      if(book && user){\n        if(book.copies >0){\n          user.loans.push(book)\n          book.copies -= 1\n          console.log(`Libro '${book.title}' prestado a '${user.name}'`)\n        }else{\n          console.log(\"Este libro no esta disponible para prestamo\")\n        }\n      }else{\n        console.log(\"Usuario o libro no encontrado\")\n      }\n    }\n  \n    returnBook(library, userId, title){\n      let user = library.findUser(userId);\n      let book = library.findBook(title);\n      if (book && user){\n        const loanIndex = user.loans.indexOf(book);\n        if(loanIndex !== -1){\n          user.loans.splice(loanIndex, 1);\n          book.copies += 1\n          console.log(`Libro '${book.title}' devuelto por '${user.name}'.`)\n        }else{\n          console.log(`No hay registro de que el libro '${book.title}' haya sido prestado a '${user.name}'`)\n        }\n      }else{\n        console.log(\"Usuario o libro no encontrado\")\n      }\n    }\n}\n  \n  \nconst library = new Library();\nconst book1 = new Book(\"Lord of the Rings\", \"JRR Tolkien\", 4);\nconst book2 = new Book(\"1984\", \"George Orwell\", 5);\nconst user = new User(\"Alice\", \"1\", \"alice@example.com\");\n\nlibrary.addBook(book1);\nlibrary.addBook(book2);\nlibrary.addUser(user);\n\nconst loanProcessor = new LoanProcess();\nloanProcessor.borrowBook(library, \"1\", \"Lord of the Rings\");\nloanProcessor.returnBook(library, \"1\", \"Lord of the Rings\");\n\n// Total de libros en la biblioteca\nconst { totalBooks, booksInfo } = library.getLibraryInfo();\nconsole.log(`Total de libros en la biblioteca: ${totalBooks}`);\nconsole.log(\"Información de la biblioteca:\");\nbooksInfo.forEach(info => console.log(info));\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/javascript/DavidMoralesDeveloper.js",
    "content": "// SRP(single responsability principel) uns clase o funcion solo tiene una razon para cambiar\n\nclass AutoServico {\n    constructor(compras, total) {\n        this.compras = compras,\n        this.total = total\n    }\n\n    getCompras (){\n        return this.compras\n    }\n    getTotal(){\n        return this.total\n    }\n}\n\nclass Descuentos {\n    descuentoDelTotal(total){\n        // const diezporciento = total - total * 0.10 \n        return total - total * 0.10\n    }\n}\n\nclass ProductoGratisExtra {\n    productoDeRegalo(carrito, regalo){\n        carrito.getCompras().push(regalo)\n        return carrito.getCompras()\n    }\n}\n\nconst miPrimeraCompra = new AutoServico([\"queso\", \"jamon\", \"tortillas\"], 100)\n\nconsole.log(miPrimeraCompra.getCompras())\nconsole.log(miPrimeraCompra.getTotal())\nconst descuento = new Descuentos()\nconsole.log(\"su descuento del 10% se resto de su total :\" + descuento.descuentoDelTotal(miPrimeraCompra.getTotal()))\nconst regaloEnCompra = new ProductoGratisExtra()\nconsole.log(\"su producto de regalo se agreso a su carrito de compras \" + regaloEnCompra.productoDeRegalo(miPrimeraCompra, \"aguacate\") )\nconsole.log(\"--------------------------------------Libreria -------------------------------------\")\n\n//  Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n//  * manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n//  * y el procesamiento de préstamos de libros.\n//  * Requisitos:\n\n// 1. Registrar libros: El sistema debe permitir agregar nuevos libros con \n//    información básica como título, autor y número de copias disponibles.\n\n\n//  * 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n//    información básica como nombre, número de identificación y correo electrónico.\n\n// * 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n//   tomar prestados y devolver libros.\n\n// * 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n//   los tres aspectos mencionados anteriormente (registro de libros, registro de\n//   usuarios y procesamiento de préstamos).\n\nclass Libreria {\n    constructor( libros, usuarios, prestamos ){\n        this.libros= [\n            {titulo: \"100 años de soledad\",\n             autor: \"Gabriel Marquez\",\n             copiasDisponibles: 15,\n             usuariosConEsteLibro: []\n             },\n            {titulo: \"Don Quijote\",\n             autor: \"Miguel de Cervantes\",\n             copiasDisponibles: 10,\n             usuariosConEsteLibro: []\n             },\n            {titulo: \"El Principito\",\n             autor: \"Saint-Exupery\",\n             copiasDisponibles: 5,\n             usuariosConEsteLibro: []\n             }\n        ]\n        this.usuarios = [\n            {nombre: \"Juan\",\n             id: 1,\n             email: \"Juan@gmail\",\n             misLibros:[]\n             },\n            {nombre: \"Pedro\",\n             id: 2,\n             email: \"Pedor@gmail\",\n             misLibros:[]\n             },\n            {nombre: \"Julio\",\n             id: 3,\n             email: \"Julio@gmail\",\n             misLibros:[]\n             },\n        ]\n        this.prestamos =[]\n    }\n    getLibro (){\n        return this.libros\n    }\n    getusuarios (){\n        return console.log(this.usuarios)\n    }\n    getPrestamos (){\n        return console.log(this.prestamos)\n    }\n    addLibro ( newLibro ) {\n        return this.libros.push(newLibro)\n    }\n    addUsurio (newUsuario) {\n        return this.usuarios.push(newUsuario)\n    }\n\n    // validaciones si el usuario tiene el libro no puede volver a pedirlo\n    //si el libro ya esta agitado regresar mensaje\n    addPestamo(tituloaBuscar, idUsuario){\n        const libroEncontrado =this.libros.find(libro => libro.titulo === tituloaBuscar)\n        const idEncontrado = this.usuarios.find(usuario => usuario.id === idUsuario )\n         \n        if(libroEncontrado && idEncontrado){\n            libroEncontrado.copiasDisponibles-=1\n            libroEncontrado.usuariosConEsteLibro.push(idEncontrado.id)\n            idEncontrado.misLibros.push(libroEncontrado.titulo)\n            this.prestamos.push(libroEncontrado)\n        }\n        \n        return this.prestamos\n    }\n\n    addDevolver(tituloADevolver, idUsusario){\n        const libroEncontrado =this.libros.find(libro => libro.titulo === tituloADevolver)\n        const idEncontrado = this.usuarios.find(usuario => usuario.id === idUsusario )\n        const devolver = [libroEncontrado, idEncontrado]\n        if(libroEncontrado.usuariosConEsteLibro.find(ids => ids === idUsusario)){\n            libroEncontrado.copiasDisponibles +=1\n            libroEncontrado.usuariosConEsteLibro = libroEncontrado.usuariosConEsteLibro.filter(id => id !== idUsusario)\n            idEncontrado.misLibros = idEncontrado.misLibros.filter(nombre => nombre !== tituloADevolver)\n        }\n        return devolver\n    }\n\n\n}\n\nconst libreria = new Libreria()\n\nconsole.log(\"-------------------addlibros-----------------\")\nlibreria.addLibro({\n    titulo: 'mil y una noche',\n    autor: 'Desconocido',\n    copiasDisponibles: 10,\n    usuariosConEsteLibro: []\n  },)\n  \n  libreria.addUsurio({ nombre: 'Julian', id: 4, email: 'Julian@gmail', misLibros: [] })\n  console.log(\"--------------------prestamos----------------------\")\n  console.log(libreria.addPestamo('El Principito', 1))\n  console.log(libreria.addPestamo('El Principito', 3))\n  console.log(libreria.addPestamo('Don Quijote', 1))\n  console.log(\"-----------Prestamos &&&&&&&&&&&&&&&&&&66\")\n  libreria.getPrestamos()\n  console.log(\"---------------------get libros y usuarios modificados------------------\")\n  console.log(libreria.getLibro())\n  libreria.getusuarios()\n  console.log(\"------------------------Devolver libros-----------\")\n  console.log(libreria.addDevolver('El Principito', 1))\n console.log(libreria.getLibro())\n  libreria.getusuarios()\n\n\n\n\n\n\n\n  "
  },
  {
    "path": "Roadmap/26 - SOLID SRP/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #26 - JavaScript -> Jesus Antonio Escamilla */\n\n/**\n * Los principios SOLID son un conjunto de cinco principios de diseño orientados a objetos que buscan hacer\n    el software más comprensible, flexible y mantenible.\n * Principio de Responsabilidad Única (Single Responsibility Principle - SRP)\n * Una clase debe tener una, y solo una, razón para cambiar. En otras palabras, una clase debe tener una \n    única responsabilidad o propósito.\n */\n\n//---EJERCIÓ---\n// INCORRECTA\nclass User_Incorrecto{\n    constructor(nombre, email){\n        this.nombre = nombre,\n        this.email = email\n    };\n\n    getUserData(){\n        return{\n            nombre: this.nombre,\n            email: this.email\n        };\n    }\n\n    saveToDatabase(){\n        console.log(`Guardando el usuario ${this.nombre} en la base de datos`);\n    }\n}\n\n// Uso del ejemplo Incorrecto\nconst user1 = new User_Incorrecto('Jesus', 'jesus_20@gmail.com');\nconsole.log(user1.getUserData());\nuser1.saveToDatabase();\n\n// CORRECTO\nclass User_Correcto{\n    constructor(nombre, email){\n        this.nombre = nombre;\n        this.email = email;\n    }\n\n    getUserData(){\n        return{\n            nombre: this.nombre,\n            email: this.email\n        };\n    }\n}\n\nclass UserRepository{\n    saveToDatabase(user){\n        console.log(`Guardando el usuario ${user.nombre} en la base de datos`);\n    }\n}\n\n// Uso de Ejemplo Correcto\nconst user = new User_Correcto('Antonio', 'antonio_25@hotmail.com');\nconsole.log(user.getUserData());\n\nconst userRepository = new UserRepository();\nuserRepository.saveToDatabase(user);\n\n\n\n/**-----DIFICULTAD EXTRA-----*/\n\n//La Clase no cumple SRP de los principios SOLID de forma Incorrecta\nclass Library {\n    constructor(){\n        this.books = [];\n        this.users = [];\n        this.loans = [];\n    }\n\n    // Registro de Libro\n    addBooks(title, author, copies){\n        const book = {title, author, copies};\n        this.books.push(book);\n    }\n\n    // Registro de Usuario\n    addUsers(name, id_user, email){\n        const user = {name, id_user, email};\n        this.users.push(user);\n    }\n\n    // Registro de Préstamo de Libro\n    loanBock(userId, bookTitle){\n        const user = this.users.find(user => user.id_user === userId);\n        const book = this.books.find(book => book.title === bookTitle);\n\n        if(user && book && book.copies > 0){\n            book.copies--;\n            this.loans.push({userId, bookTitle, data: new Date()});\n            console.log(`El libro \"${bookTitle}\" ha sido prestado a ${user.name}`);\n        } else{\n            console.log('No se proceso el préstamo');\n        }\n    }\n\n    // Devolver el Libro\n    returnBook(userId, bookTitle){\n        const loanIndex = this.loans.findIndex(\n            loan => loan.userId === userId && loan.bookTitle === bookTitle\n        );\n\n        if (loanIndex !== -1) {\n            const book = this.books.find(book => book.title === bookTitle);\n            book.copies++;\n            this.loans.splice(loanIndex, 1);\n            console.log(`El libro \"${bookTitle}\" ha sido devuelto`);\n        } else {\n            console.log('No se puede procesar la devolución');\n        }\n    }\n}\n\n\n// Uso de SRP de SOLID de forma Incorrecta\nconst library = new Library();\nlibrary.addBooks('Hábitos Atómicos', 'James Clear', 3);\nlibrary.addUsers('Jesus', '123', 'jesus@ejemplo.com');\nlibrary.loanBock('123', 'Hábitos Atómicos');\nlibrary.returnBook('123', 'Hábitos Atómicos');\n\n\n\n// Agora con el Uso de SRP con los principios de SOLID de forma Correcta\n// Gestión de Libros\nclass BookManager{\n    constructor(){\n        this.books = [];\n    }\n\n    // Registrar el Libro\n    addBook(title, author, copies){\n        const book = {title, author, copies};\n        this.books.push(book);\n        console.log(`El Libro \"${title}\" fue creado`);\n    }\n\n    // Obtener el Titulo del Libro\n    getBook(title){\n        return this.books.find(book => book.title === title);\n    }\n}\n\n// Gestión de Usuarios\nclass UserManager{\n    constructor(){\n        this.users = [];\n    }\n\n    // Registrar Usuario\n    addUser(name, id_user, email){\n        const user = {name, id_user, email};\n        this.users.push(user);\n        console.log(`El Usuario \"${name}\" fue creado`);\n    }\n\n    // Obtener el Id del Usuario\n    getUser(Id_user){\n        return this.users.find(user => user.id_user === Id_user);\n    }\n}\n\n// Gestión de Préstamo de Libro\nclass LoanManager{\n    constructor(userManager,bookManager){\n        this.loans = [];\n        this.userManager = userManager;\n        this.bookManager = bookManager;\n    }\n\n    // Registrar el Préstamo del Libro\n    addLoan(userId, bookTitle){\n        const book = this.bookManager.getBook(bookTitle);\n        const user = this.userManager.getUser(userId);\n\n        if (user && book && book.copies > 0) {\n            book.copies--;\n            this.loans.push({ userId, bookTitle, data: new Date() });\n            console.log(`El libro \"${bookTitle}\" ha sido prestado a ${user.name}`);\n        } else {\n            console.log('No se proceso el préstamo');\n        }\n    }\n\n    // Devuelve el Préstamo del Libro\n    returnBook(userId, bookTitle){\n        const loanIndex = this.loans.findIndex(\n            loan => loan.userId === userId && loan.bookTitle === bookTitle\n        );\n\n        if (loanIndex !== -1) {\n            const book = this.bookManager.getBook(bookTitle);\n            book.copies++;\n            this.loans.splice(loanIndex, 1);\n            console.log(`El libro \"${bookTitle}\" ha sido devuelto`);\n        } else {\n            console.log('No se puede procesar la devolución');\n        }\n    }\n}\n\n\n// Uso de SRP de SOLID de forma Correcta\nconst bookManager = new BookManager();\nconst userManager = new UserManager();\nconst loanManager = new LoanManager(userManager, bookManager);\n\nbookManager.addBook('Git & GitHub desde Cero', 'Brais Moure', 1);\nbookManager.addBook('La teoría del todo', 'Stephen W. Hawking', 1);\n\nuserManager.addUser('Fatima', '01', 'faty@ejemplo.com');\nuserManager.addUser('Antonio', '02', 'toño@ejemplo.com');\n\nloanManager.addLoan('02', 'Git & GitHub desde Cero');\nloanManager.addLoan('01', 'La teoría del todo');\nloanManager.returnBook('02', 'Git & GitHub desde Cero');\nloanManager.returnBook('01', 'La teoría del todo');\n\n/**-----DIFICULTAD EXTRA-----*/"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/javascript/RaulDoezon.js",
    "content": "// https://medium.com/@diego.coder/principios-solid-en-javascript-1c734e3554fd\n// https://dev.to/ruben_alapont/solid-principles-series-understanding-the-single-responsibility-principle-srp-in-nodejs-with-typescript-57e8\n\n/*\n  EJERCICIO:\n  Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n  Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n  de forma correcta e incorrecta.\n*/\n\nconsole.log(\"+++++++++ PRINCIPIO SOLID SRP IMPLEMENTADO DE FORMA INCORRECTA +++++++++\");\n\nclass UserService {\n  constructor(userName, password, user, subject, message) {\n    this.userName = userName;\n    this.password = password;\n    this.user = user;\n    this.subject = subject;\n    this.message = message;\n  }\n\n  authenticateUser() {\n    console.log(`Nombre de usuario: ${this.userName}. Contraseña: ${this.password}`);\n  }\n\n  sendEmail() {\n    console.log(`- Usuario: ${this.user}.`);\n    console.log(`- Asunto: ${this.subject}.`);\n    console.log(`- Mensaje: ${this.message}`);\n  }\n}\n\nlet userService = new UserService(\"4rm4ndo\", \"12345678\", \"Armando\", \"SOLID SRP\", \"IMPLEMENTACIÓN INCORRECTA.\");\nuserService.authenticateUser();\nuserService.sendEmail();\n\nconsole.log(\"\\n+++++++++ PRINCIPIO SOLID SRP IMPLEMENTADO DE FORMA CORRECTA +++++++++\");\n\nclass AuthenticationService {\n  authenticate(userName, password) {\n    console.log(`- Nombre de usuario: ${userName}.\\n- Contraseña: ${password}`);\n  }\n}\n\nclass EmailService {\n  send(user, subject, message) {\n    console.log(`- Usuario: ${user}.\\n- Asunto: ${subject}.\\n- Mensaje: ${message}`);\n  }\n}\n\nlet authentication = new AuthenticationService();\nlet email = new EmailService();\n\nauthentication.authenticate(\"RaulDoezon\", \"urue764h^<d\");\nemail.send(\"Raúl\", \"Principio SOLID SRP\", \"El objetivo principal del SRP es promover la cohesión y la modularidad en el diseño de software. Al asignar una sola responsabilidad a cada clase, se facilita la comprensión, el mantenimiento y la evolución del código, ya que cada clase se enfoca en una tarea específica y limitada.\");\n\n/*\n  DIFICULTAD EXTRA (opcional):\n  Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n  manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n  y el procesamiento de préstamos de libros.\n  Requisitos:\n  1. Registrar libros: El sistema debe permitir agregar nuevos libros con \n  información básica como título, autor y número de copias disponibles.\n  2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n  información básica como nombre, número de identificación y correo electrónico.\n  3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n  tomar prestados y devolver libros.\n  Instrucciones:\n  1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n  los tres aspectos mencionados anteriormente (registro de libros, registro de\n  usuarios y procesamiento de préstamos).\n  2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n  siguiendo el Principio de Responsabilidad Única.\n*/\n\n// https://www.youtube.com/watch?v=7NM8FK9G91M&list=PLv0dxH7HRDx_kQRNoldG7iPvydy8DyvE3&index=28\n\nconsole.log(\"\\nDIFICULTAD EXTRA +++++++++\");\n\n// INCORRECTO\n/*\nclass Library {\n  constructor() {\n    this.books = [];\n    this.users = [];\n    this.loans = [];\n  }\n\n  bookRegister(title, author, numberCopies) {\n    this.books.push({title, author, numberCopies});\n\n    console.log(`- Libro: ${title}. Autor: ${author}. Número de copias: ${numberCopies}`);\n  }\n\n  userRegister(name, idNumber, email) {\n    this.users.push({name, idNumber, email});\n\n    console.log(`- Usuario: ${name}. ID: ${idNumber}. Correo electrónico: ${email}`);\n  }\n\n  lendBook(loanBook, userID) {\n    const checkBook = this.books.find((book) => book.title === loanBook && book.numberCopies > 0);\n    const checkUser = this.users.find((user) => user.idNumber === userID);\n\n    if (checkBook && checkUser) {\n      this.loans.push({title: checkBook.title, userId: checkUser.idNumber});\n      checkBook.numberCopies -= 1;\n\n      console.log(`El libro ${checkBook.title} ha sido prestado al usuario ${checkUser.name} con ID: ${checkUser.idNumber}`);\n    } else {\n      console.log(`Lo sentimos ${checkUser.name}, el libro ${loanBook} no está disponible.`);\n    }\n  }\n\n  returnBook(returnbook, userID) {\n    const checkBorrowedBook = this.loans.findIndex((book) => book.title === returnbook && book.userId === userID);\n\n    if (checkBorrowedBook > -1) {\n      this.loans.splice(checkBorrowedBook, 1);\n      this.books.find((book) => book.numberCopies += 1);\n\n      console.log(`El libro ${returnbook} ha sido devuelto.`);\n    } else {\n      console.log(`El libro ${returnbook} o el ID de usuario ${userID} no corresponden al préstamo.`);\n    }\n  }\n}\n\nlet library = new Library();\nlibrary.bookRegister(\"Corre Nicky Corre\", \"Nicky Cruz\", 1);\nlibrary.bookRegister(\"La Cruz y el Puñal\", \"David Wilkerson\", 4);\nlibrary.userRegister(\"Raúl\", 112233, \"raul@email.com\");\nlibrary.userRegister(\"Armando\", 445566, \"armando@email.com\");\nlibrary.lendBook(\"Corre Nicky Corre\", 112233);\nlibrary.lendBook(\"Corre Nicky Corre\", 445566);\nlibrary.returnBook(\"Corre Nicky Corre\", 112233);\n\nconsole.log(library.books);\nconsole.log(library.users);\nconsole.log(library.loans);\n*/\n\n// CORRECTO\nclass Library {\n  constructor() {\n    this.books = [];\n    this.users = [];\n  }\n\n  bookRegister(book) {\n    this.books.push(book);\n\n    console.log(`- Libro: ${book.title}. Autor: ${book.author}. Número de copias: ${book.numberCopies}`);\n  }\n\n  userRegister(user) {\n    this.users.push(user);\n\n    console.log(`- Usuario: ${user.name}. ID: ${user.idNumber}. Correo electrónico: ${user.email}`);\n  }\n\n  findBook(bookTitle) {\n    return this.books.find((book) => book.title === bookTitle && book.numberCopies > 0);\n  }\n\n  findUser(userID) {\n    return this.users.find((user) => user.idNumber === userID);\n  }\n}\n\nclass Books {\n  constructor(title, author, numberCopies) {\n    this.title = title;\n    this.author = author;\n    this.numberCopies = numberCopies;\n  }\n}\n\nclass Users {\n  constructor(name, idNumber, email) {\n    this.name = name;\n    this.idNumber = idNumber;\n    this.email = email;\n  }\n}\n\nclass Loans {\n  constructor() {\n    this.loans = [];\n  }\n\n  lendBook(booksInformation, bookName, userID) {\n    const checkBook = booksInformation.findBook(bookName);\n    const checkUser = booksInformation.findUser(userID);\n\n    if (checkBook && checkUser) {\n      this.loans.push({title: checkBook.title, userId: checkUser.idNumber});\n      checkBook.numberCopies -= 1;\n\n      console.log(`El libro ${checkBook.title} ha sido prestado al usuario ${checkUser.name} con ID: ${checkUser.idNumber}`);\n    } else {\n      console.log(`Lo sentimos ${checkUser.name}, el libro ${bookName} no está disponible.`);\n    }\n  }\n\n  returnBook(booksInformation, returnbook, userID) {\n    const checkBorrowedBook = this.loans.findIndex((book) => book.title === returnbook && book.userId === userID);\n\n    if (checkBorrowedBook > -1) {\n      this.loans.splice(checkBorrowedBook, 1);\n      booksInformation.books.find((book) => book.numberCopies += 1);\n\n      console.log(`El libro ${returnbook} ha sido devuelto.`);\n    } else {\n      console.log(`El libro ${returnbook} o el ID de usuario ${userID} no corresponden al préstamo.`);\n    }\n  }\n}\n\nconst library = new Library();\nconst book1 = new Books(\"Las Crónicas de Narnia: El Sobrino del Mago\", \"C. S. Lewis\", 1);\nconst book2 = new Books(\"Cartas del diablo a su sobrino\", \"C. S. Lewis\", 4);\nconst user1 = new Users(\"Raúl\", 112233, \"raul@email.com\");\nconst user2 = new Users(\"Armando\", 445566, \"armando@email.com\");\nconst loan = new Loans();\n\nlibrary.bookRegister(book1);\nlibrary.bookRegister(book2);\nlibrary.userRegister(user1);\nlibrary.userRegister(user2);\nloan.lendBook(library, \"Las Crónicas de Narnia: El Sobrino del Mago\", 112233);\nloan.lendBook(library, \"Las Crónicas de Narnia: El Sobrino del Mago\", 445566);\nloan.returnBook(library, \"Las Crónicas de Narnia: El Sobrino del Mago\", 112233);\n\nconsole.log(library.books);\nconsole.log(library.users);\nconsole.log(loan.loans);\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/javascript/RicJDev.js",
    "content": "//EJERCICIO\n/*\nCUANDO NO SE SIGUE EL PRINCIPIO DE RESPONSABILIDAD ÚNICA:\n\n- Se complica la tarea de implementar procesos en otras clases.\n- De la misma manera la clase vendrá con métodos que no necesitará en todos los casos que será implementada.\n- Complica el mantenimiento, al juntar demasiados procesos.\n- Hace más difícil definir los test unitarios.\n- El código es algo más ilegible, pues no queda claro para qué es la clase.\n\nEn general, este principio busca simplificar y facilitar el desarrollo, sobre todo si se trabaja con código que luego será leído y editado por otras personas.\n*/\n\nclass Users {\n\tconstructor(username, password, email, id) {\n\t\tthis.username = username;\n\t\tthis.password = password;\n\t\tthis.email = email;\n\t\tthis.id = id;\n\t}\n\n\tregisterUser() {\n\t\t//Registrar el usuario\n\t}\n\n\tvalidateUser() {\n\t\t//Validar la contraseña del usuario\n\t}\n\n\tsendEmail() {\n\t\t//Enviar un email al ususario\n\t}\n}\n\n/*\nPRINCIPIO DE RESPONSABILIDAD ÚNICA (SRP):\n\n\"Una clase debe hacer una cosa y, por lo tanto, debe tener una sola razón para cambiar\"\n\nEsto quiere decir que cada clase tiene un objetivo y una sola razón de ser. El único motivo por el que se debería modificar una clase es que este objetivo o la manera en que debe cumplirse sean modificados también.\n*/\n\nclass User {\n\tconstructor(username, password, email, id) {\n\t\tthis.username = username;\n\t\tthis.password = password;\n\t\tthis.email = email;\n\t\tthis.id = id;\n\t}\n\n\t//Crear al usuario\n}\n\nclass UserValidation {\n\tconstructor(user) {\n\t\tthis.user = user;\n\t}\n\n\t//Validar contraseñas o permisos del usuario\n}\n\nclass EmailService {\n\tconstructor(emailAddress, emailObject, emailContent) {\n\t\tthis.emailAddress = emailAddress;\n\t\tthis.emailObject = emailObject;\n\t\tthis.emailContent = emailContent;\n\t}\n\n\t//Enviar un correo\n}\n\n//EXTRA\nclass LibraryNoSRP {\n\t#users = [];\n\t#books = [];\n\t#loans = [];\n\n\tregisterBook(title, author, avalaibleCopies) {\n\t\tlet newBook = {\n\t\t\tid: this.#books.length + 1,\n\t\t\ttitle: title,\n\t\t\tauthor: author,\n\t\t\tavalaibleCopies: avalaibleCopies,\n\t\t};\n\n\t\tthis.#books.push(newBook);\n\t}\n\n\tregisterUser(name, emailAddress) {\n\t\tlet newUser = {\n\t\t\tid: this.#users.length + 1,\n\t\t\tname: name,\n\t\t\temailAddress: emailAddress,\n\t\t};\n\n\t\tthis.#users.push(newUser);\n\t}\n\n\t#searchByID(arr, item) {\n\t\treturn arr.find((obj) => obj.id === item);\n\t}\n\n\tloanBook(userID, bookID) {\n\t\tlet user = this.#searchByID(this.#users, userID);\n\t\tlet book = this.#searchByID(this.#books, bookID);\n\n\t\tlet loan = {\n\t\t\tid: this.#loans.length + 1,\n\t\t\tuserID: user.id,\n\t\t\tbookID: book.id,\n\t\t};\n\n\t\tif (user && book) {\n\t\t\tif (book.avalaibleCopies > 0) {\n\t\t\t\tconsole.log(`Se ha prestado el libro \\\"${book.title}\\\" a ${user.name}`);\n\n\t\t\t\tbook.avalaibleCopies--;\n\n\t\t\t\tthis.#loans.push(loan);\n\t\t\t} else {\n\t\t\t\tconsole.log('No hay copias disponibles');\n\t\t\t}\n\t\t} else {\n\t\t\tconsole.log('No existe el usuario o el libro solicitado');\n\t\t}\n\t}\n\n\treturnBook(userID, bookID) {\n\t\tlet loan = this.#loans.find((obj) => {\n\t\t\treturn obj.userID === userID && obj.bookID === bookID;\n\t\t});\n\n\t\tif (loan) {\n\t\t\tlet user = this.#searchByID(this.#users, loan.userID);\n\t\t\tlet book = this.#searchByID(this.#books, loan.bookID);\n\n\t\t\tconsole.log(`${user.name} ha regresado el libro \\\"${book.title}\\\"`);\n\n\t\t\tbook.avalaibleCopies++;\n\n\t\t\tthis.#loans.splice(this.#loans.indexOf(loan), 1);\n\t\t} else {\n\t\t\tconsole.log('Ese préstamo no está en el registro');\n\t\t}\n\t}\n}\n\nlet libraryNoSRP = new LibraryNoSRP();\n\nlibraryNoSRP.registerBook('Dracula', 'Bram Stoker', 3);\nlibraryNoSRP.registerUser('Juan', 'juanloquillo16@gmail.com');\n\nlibraryNoSRP.loanBook(1, 1);\n\nlibraryNoSRP.returnBook(1, 1);\nlibraryNoSRP.returnBook(1, 1);\n\n//REFACTORIZANDO\nclass Book {\n\tconstructor(title, author, avalaibleCopies) {\n\t\tthis.title = title;\n\t\tthis.author = author;\n\t\tthis.avalaibleCopies = avalaibleCopies;\n\t}\n}\n\nclass LibraryUser {\n\tconstructor(name, emailAddress) {\n\t\tthis.name = name;\n\t\tthis.emailAddress = emailAddress;\n\t}\n}\n\nclass LoansService {\n\tloans = [];\n\n\tloanBook(user, book) {\n\t\tlet loan = {\n\t\t\tuserID: user.id,\n\t\t\tbookID: book.id,\n\t\t};\n\n\t\tif (book.avalaibleCopies > 0) {\n\t\t\tloan.id = this.loans.length + 1;\n\t\t\tthis.loans.push(loan);\n\t\t\tbook.avalaibleCopies--;\n\n\t\t\tconsole.log(`Se le ha prestado el libro \\\"${book.title}\\\" a ${user.name}`);\n\t\t}\n\t}\n\n\treturnBook(user, book) {\n\t\tlet result;\n\n\t\tthis.loans.forEach((loan) => {\n\t\t\tif (loan.userID === user.id && loan.bookID === book.id) {\n\t\t\t\tresult = loan;\n\t\t\t}\n\t\t});\n\n\t\tif (result) {\n\t\t\tthis.loans.splice(this.loans.indexOf(result, 1));\n\t\t\tbook.avalaibleCopies++;\n\t\t\tconsole.log(`${user.name} ha regresado el libro \\\"${book.title}\\\"`);\n\t\t} else {\n\t\t\tconsole.log('Préstamo no registrado');\n\t\t}\n\t}\n}\n\nclass Library {\n\t#users = [];\n\t#books = [];\n\t#loans = new LoansService();\n\n\taddUser(user) {\n\t\tuser.id = this.#users.length + 1;\n\t\tthis.#users.push(user);\n\t}\n\n\taddBook(book) {\n\t\tbook.id = this.#books.length + 1;\n\t\tthis.#books.push(book);\n\t}\n\n\t#searchByID(database, itemID) {\n\t\treturn database.find((obj) => obj.id === itemID);\n\t}\n\n\tloanBook(userID, bookID) {\n\t\tlet user = this.#searchByID(this.#users, userID);\n\t\tlet book = this.#searchByID(this.#books, bookID);\n\n\t\tif (user && book) {\n\t\t\tthis.#loans.loanBook(user, book);\n\t\t} else {\n\t\t\tconsole.log('No existe el libro o el usuario solicitados');\n\t\t}\n\t}\n\n\treturnBook(userID, bookID) {\n\t\tlet user = this.#searchByID(this.#users, userID);\n\t\tlet book = this.#searchByID(this.#books, bookID);\n\n\t\tthis.#loans.returnBook(user, book);\n\t}\n}\n\nconst library = new Library();\n\nlibrary.addUser(new LibraryUser('Lissa', 'lissalunita2003@gmail.com'));\nlibrary.addBook(new Book('La Milla Verde', 'Stephen King', 4));\n\nlibrary.loanBook(1, 1);\n\nlibrary.returnBook(1, 1);\nlibrary.returnBook(1, 1);\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/javascript/Sac-Corts.js",
    "content": "// Invalid way\nclass User {\n    constructor(name, email) {\n        this.name = name;\n        this.email = email;\n    }\n\n    getUserInfo() {\n        return {\n            name: this.name,\n            email: this.email\n        };\n    }\n\n    formatUserInfo() {\n        return `Name: ${this.name}, Email: ${this.email}`;\n    }\n}\n\nconst user = new User('Isaac Morales', 'isaac@gmail.com');\nconsole.log(user.formatUserInfo());\n\n// Correct way\nclass UserInfo {\n    constructor(name, email) {\n        this.name = name;\n        this.email = email;\n    }\n\n    getUserInfo() {\n        return {\n            name: this.name,\n            email: this.email\n        };\n    }\n}\n\nclass FormatUser {\n    static format(user) {\n        return `Name: ${user.name}, Email: ${user.email}`;\n    }\n}\n\nconst newUser = new UserInfo('Isaac Cortés', 'isaac@gmail.com');\nconsole.log(FormatUser.format(newUser));\n\n// Extra Exercise //\nclass BookManager {\n    constructor() {\n        this.books = [];\n    }\n\n    addBook(title, author, copies) {\n        this.books.push({ title, author, copies });\n    }\n\n    findBook(title) {\n        return this.books.find(book => book.title === title);\n    }\n}\n\nclass UserManager {\n    constructor() {\n        this.users = [];\n    }\n\n    addUser(name, id, email) {\n        this.users.push({ name, id, email });\n    }\n\n    findUser(id) {\n        return this.users.find(user => user.id === id); \n    }\n}\n\nclass LoanManager {\n    constructor(bookManager, userManager) {\n        this.bookManager = bookManager;\n        this.userManager = userManager;    \n        this.loans = [];\n    }\n\n    borrowBook(userId, bookTitle) {\n        const user = this.userManager.findUser(userId);\n        const book = this.bookManager.findBook(bookTitle);\n\n        if (user && book && book.copies > 0) {\n            book.copies--;\n            this.loans.push({ userId, bookTitle });\n            console.log(`${user.name} borrowed \"${book.title}\"`);\n        } else {\n            console.log(`Book is unavailable or user not found`);\n        }\n    }\n\n    returnBook(userId, bookTitle) {\n        const loanIndex = this.loans.findIndex(\n            loan => loan.userId === userId && loan.bookTitle === bookTitle\n        );\n        const book = this.bookManager.findBook(bookTitle);\n\n        if (loanIndex !== -1 && book) {\n            book.copies++;\n            this.loans.splice(loanIndex, 1);\n            console.log(`\"${book.title}\" has been returned`);\n        } else {\n            console.log('Loan not found or book not available');\n        }\n    }\n}\n\nconst bookManager = new BookManager();\nconst userManager = new UserManager();\nconst loanManager = new LoanManager(bookManager, userManager);\n\nbookManager.addBook('The Great Gatsby', 'F. Scott Fitzgerald', 5);\nuserManager.addUser('Isaac', 1, 'isaac@gmail.com');\n\nloanManager.borrowBook(1, 'The Great Gatsby');\nloanManager.returnBook(1, 'The Great Gatsby');\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/javascript/adrs1166ma.js",
    "content": "// 🔥 EJERCICIO:\n// Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n// Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n// de forma correcta e incorrecta.\n\n// * Ejemplo Incorrecto (viola SRP): Una sola clase maneja múltiples responsabilidades\n// --------------------------------------------------------------------------------------------------------------\n\nclass SistemaIncorrecto {\n    constructor() {\n        this.usuarios = [];\n        this.log = [];\n    }\n\n    // Responsabilidad 1: Registrar usuarios\n    registrarUsuario(nombre, email) {\n        this.usuarios.push({ nombre, email });\n        this.log.push(`Usuario ${nombre} registrado.`);\n    }\n\n    // Responsabilidad 2: Autenticar usuarios\n    autenticarUsuario(email, password) {\n        const usuario = this.usuarios.find(u => u.email === email);\n        if (usuario) {\n            this.log.push(`Autenticación exitosa para ${email}.`);\n            return true;\n        }\n        return false;\n    }\n\n    // Responsabilidad 3: Mostrar logs\n    mostrarLogs() {\n        console.log(\"Logs del sistema:\", this.log);\n    }\n}\n\nconst sistemaIncorrecto = new SistemaIncorrecto();\nsistemaIncorrecto.registrarUsuario(\"Anderson\", \"anderson@example.com\");\nsistemaIncorrecto.autenticarUsuario(\"anderson@example.com\", \"1234\");\nsistemaIncorrecto.mostrarLogs();\n\n\n// * Ejemplo Correcto (cumple SRP): Clases separadas por responsabilidad\n// --------------------------------------------------------------------------------------------------------------\nclass RegistroUsuarios {\n    constructor() {\n        this.usuarios = [];\n    }\n\n    registrarUsuario(nombre, email) {\n        this.usuarios.push({ nombre, email });\n        return `Usuario ${nombre} registrado.`;\n    }\n}\n\nclass Autenticacion {\n    autenticarUsuario(email, password, usuarios) {\n        const usuario = usuarios.find(u => u.email === email);\n        if (usuario) {\n            return `Autenticación exitosa para ${email}.`;\n        }\n        return \"Autenticación fallida.\";\n    }\n}\n\nclass Logger {\n    constructor() {\n        this.log = [];\n    }\n\n    agregarLog(mensaje) {\n        this.log.push(mensaje);\n    }\n\n    mostrarLogs() {\n        console.log(\"Logs del sistema:\", this.log);\n    }\n}\n\nconst registro = new RegistroUsuarios();\nconst auth = new Autenticacion();\nconst logger = new Logger();\n\nlogger.agregarLog(registro.registrarUsuario(\"María\", \"maria@example.com\"));\nlogger.agregarLog(auth.autenticarUsuario(\"maria@example.com\", \"1234\", registro.usuarios));\nlogger.mostrarLogs();\n\n\n// * 🔥 DIFICULTAD EXTRA: Sistema de biblioteca\n// --------------------------------------------------------------------------------------------------------------\n\n// 1. Clase que viola SRP (maneja libros, usuarios y préstamos)\nclass LibraryIncorrecta {\n    constructor() {\n        this.libros = [];\n        this.usuarios = [];\n        this.prestamos = [];\n    }\n\n    // Responsabilidad 1: Registrar libros\n    agregarLibro(titulo, autor, copias) {\n        this.libros.push({ titulo, autor, copias });\n    }\n\n    // Responsabilidad 2: Registrar usuarios\n    agregarUsuario(nombre, identificacion, email) {\n        this.usuarios.push({ nombre, identificacion, email });\n    }\n\n    // Responsabilidad 3: Procesar préstamos\n    prestarLibro(titulo, identificacionUsuario) {\n        const libro = this.libros.find(libro => libro.titulo === titulo);\n        if (!libro || libro.copias <= 0) return \"Libro no disponible.\";\n        libro.copias--;\n        this.prestamos.push({ titulo, identificacionUsuario });\n        return `Libro \"${titulo}\" prestado.`;\n    }\n\n    // Responsabilidad 4: Devolver libros\n    devolverLibro(titulo, identificacionUsuario) {\n        const index = this.prestamos.findIndex(p => p.titulo === titulo && p.identificacionUsuario === identificacionUsuario);\n        if (index === -1) return \"Préstamo no encontrado.\";\n        const libro = this.libros.find(libro => libro.titulo === titulo);\n        libro.copias++;\n        this.prestamos.splice(index, 1);\n        return `Libro \"${titulo}\" devuelto.`;\n    }\n}\n\n// 2. Refactorización siguiendo SRP\nclass LibroManager {\n    constructor() {\n        this.libros = [];\n    }\n\n    agregarLibro(titulo, autor, copias) {\n        this.libros.push({ titulo, autor, copias });\n        return `Libro \"${titulo}\" agregado.`;\n    }\n\n    actualizarCopias(titulo, delta) {\n        const libro = this.libros.find(libro => libro.titulo === titulo);\n        if (libro) libro.copias += delta;\n        return !!libro;\n    }\n}\n\nclass UsuarioManager {\n    constructor() {\n        this.usuarios = [];\n    }\n\n    agregarUsuario(nombre, identificacion, email) {\n        this.usuarios.push({ nombre, identificacion, email });\n        return `Usuario ${nombre} registrado.`;\n    }\n}\n\nclass PrestamoManager {\n    constructor() {\n        this.prestamos = [];\n    }\n\n    prestarLibro(titulo, identificacionUsuario, libroManager) {\n        const libro = libroManager.libros.find(libro => libro.titulo === titulo);\n        if (!libro || libro.copias <= 0) return \"Libro no disponible.\";\n        libroManager.actualizarCopias(titulo, -1);\n        this.prestamos.push({ titulo, identificacionUsuario });\n        return `Libro \"${titulo}\" prestado.`;\n    }\n\n    devolverLibro(titulo, identificacionUsuario, libroManager) {\n        const index = this.prestamos.findIndex(p => p.titulo === titulo && p.identificacionUsuario === identificacionUsuario);\n        if (index === -1) return \"Préstamo no encontrado.\";\n        libroManager.actualizarCopias(titulo, 1);\n        this.prestamos.splice(index, 1);\n        return `Libro \"${titulo}\" devuelto.`;\n    }\n}\n\nclass Library {\n    constructor() {\n        this.libroManager = new LibroManager();\n        this.usuarioManager = new UsuarioManager();\n        this.prestamoManager = new PrestamoManager();\n    }\n}\n\nconst library = new Library();\nlibrary.libroManager.agregarLibro(\"1984\", \"George Orwell\", 3);\nlibrary.usuarioManager.agregarUsuario(\"Ana\", \"001\", \"ana@example.com\");\nconsole.log(library.prestamoManager.prestarLibro(\"1984\", \"001\", library.libroManager));\nconsole.log(library.prestamoManager.devolverLibro(\"1984\", \"001\", library.libroManager));"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/javascript/agusrosero.js",
    "content": "/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n * Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n */\n\n// Ejemplo de Forma incorrecta\nclass Auto {\n  constructor(marca, modelo) {\n    this.marca = marca;\n    this.modelo = modelo;\n  }\n\n  obtenerGuardarMarca() {\n    this.marca = marca;\n    return this.marca;\n  }\n\n  obtenerGuardarModelo() {\n    this.modelo = modelo;\n    return this.modelo;\n  }\n}\n\n\n// Ejemplo de Forma correcta\nclass Auto {\n  constructor(marca, modelo) {\n    this.marca = marca;\n    this.modelo = modelo;\n  }\n\n  obtenerMarca() {\n    return this.marca;\n  }\n\n  obtenerModelo() {\n    return this.modelo;\n  }\n\n  guardarMarca(marca) {\n    this.marca = marca;\n  }\n\n  guardarModelo(modelo) {\n    this.modelo = modelo;\n  }\n}\n\n\n/* DIFICULTAD EXTRA (opcional):\n * Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n * manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n * y el procesamiento de préstamos de libros.\n * Requisitos:\n * 1. Registrar libros: El sistema debe permitir agregar nuevos libros con\n * información básica como título, autor y número de copias disponibles.\n * 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n * información básica como nombre, número de identificación y correo electrónico.\n * 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n * tomar prestados y devolver libros.\n * Instrucciones:\n * 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n * los tres aspectos mencionados anteriormente (registro de libros, registro de\n * usuarios y procesamiento de préstamos).\n * 2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n * siguiendo el Principio de Responsabilidad Única.\n */\n\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/javascript/bernatcs.js",
    "content": "// ** EJERCICIO\n\n// correcta\n\nconst basededatos = ['Pepe', 'Pepa']\n\nclass User {\n    constructor(name, email) {\n        this.name = name;\n        this.email = email;\n    }\n\n    getUserData() {\n        return `Name: ${this.name}, Email: ${this.email}`;\n    }\n}\n\nclass UserRepository {\n    save(user) {\n        basededatos.push(user.name)\n    }\n}\n\nconst user = new User('Bernat', 'bernat@gmail.com');\nconsole.log(user.getUserData());\n\nconst userRepository = new UserRepository();\nuserRepository.save(user);\nconsole.log(basededatos)\n\n// incorrecta\n\nclass User2 {\n    constructor(name, email) {\n        this.name = name;\n        this.email = email;\n    }\n\n    getUserData() {\n        return `Name: ${this.name}, Email: ${this.email}`;\n    }\n\n    saveToDatabase() {\n        basededatos.push(user2.name)\n    }\n}\n\n// Uso\nconst user2 = new User2('Bernat', 'bernat@example.com');\nconsole.log(user2.getUserData());\nuser2.saveToDatabase();"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/javascript/caterinarodriguezdev.js",
    "content": "/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n * Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n * manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n * y el procesamiento de préstamos de libros.\n * Requisitos:\n * 1. Registrar libros: El sistema debe permitir agregar nuevos libros con\n * información básica como título, autor y número de copias disponibles.\n * 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n * información básica como nombre, número de identificación y correo electrónico.\n * 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n * tomar prestados y devolver libros.\n * Instrucciones:\n * 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n * los tres aspectos mencionados anteriormente (registro de libros, registro de\n * usuarios y procesamiento de préstamos).\n * 2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n * siguiendo el Principio de Responsabilidad Única.\n */\n\n// Uso incorrecto del SRP, esta función tiene más de una razón para cambiar:\n// 1. Imprimir el usuario\n// 2. Devolver un objeto usuario\nconst imprimirUsuario = (nombre, edad, hobby) => {\n  console.log(\n    `El usuario se llama ${nombre} tiene ${edad} años y le gusta ${hobby}`\n  );\n  return {\n    nombre: nombre,\n    edad: edad,\n    hobby: hobby,\n  };\n};\n\n// Uso correcto del SRP, estas 2 funciones tienen una única responsabilidad\nconst imprimirUsuarioSRP = (nombre, edad, hobby) => {\n  console.log(\n    `El usuario se llama ${nombre} tiene ${edad} años y le gusta ${hobby}`\n  );\n};\n\nconst crearUsuarioSRP = (nombre, edad, hobby) => {\n  return {\n    nombre: nombre,\n    edad: edad,\n    hobby: hobby,\n  };\n};\n\n// Uso incorrecto\nconst usuario = imprimirUsuario(\"JJ\", \"20\", \"motocross\");\n\n// Uso correcto\nimprimirUsuarioSRP(\"JJ\", \"20\", \"motocross\");\nconst usuarioSRP = crearUsuarioSRP(\"JJ\", \"20\", \"motocross\");\n\nconsole.log(\"-------------DIFICULTAD EXTRA-----------\");\n// CLASES NO SRP\nclass Library {\n  constructor() {\n    this.libros = [];\n    this.usuarios = [];\n    this.prestamos = [];\n  }\n\n  registrarLibro(titulo, autor, copiasDisponibles) {\n    this.libros.push({\n      titulo: titulo,\n      autor: autor,\n      copiasDisponibles: copiasDisponibles,\n    });\n    console.log(\"Libro registrado\");\n  }\n\n  registrarUsuario(nombre, dni, email) {\n    this.usuarios.push({\n      nombre: nombre,\n      dni: dni,\n      email: email,\n    });\n    console.log(\"Usuario registrado\");\n  }\n\n  prestarLibro(libro, usuario) {\n    const libroEncontrado = this.libros.find((l) => l.titulo === libro);\n    const usuarioEncontrado = this.usuarios.find((u) => u.dni === usuario);\n\n    if (\n      libroEncontrado &&\n      usuarioEncontrado &&\n      libroEncontrado.copiasDisponibles > 0\n    ) {\n      this.prestamos.push({\n        libro: libroEncontrado,\n        usuario: usuarioEncontrado,\n      });\n      libroEncontrado.copiasDisponibles--;\n      console.log(\n        `Se ha prestado el libro ${libro} para el usuario ${usuario}`\n      );\n    } else {\n      console.log(\n        \"Error, no se ha encontrado el libro y/o usuario o no existen copias disponibles\"\n      );\n    }\n  }\n\n  devolverLibro(libro, usuario) {\n    const index = this.prestamos.find(\n      (p) => p.libro.titulo === libro && p.usuario.dni === usuario\n    );\n    const libroEncontrado = this.libros.find(l => l.titulo === libro);\n\n    if (index !== -1) {\n      this.prestamos.splice(index, 1);\n      libroEncontrado && libroEncontrado.copiasDisponibles++;\n      console.log(\"El libro ha sido devuelto y el préstamo cancelado, gracias\");\n    } else {\n      console.log(\"No se ha encontrado el préstamo\");\n    }\n  }\n}\n\n// CLASES SRP\nclass LibrarySRP {\n  constructor() {\n    this.libros = [];\n    this.usuarios = [];\n    this.prestamos = [];\n  }\n\n  registrarUsuario(nombre, dni, email) {\n    const newUser = new User(nombre, dni, email);\n    this.usuarios.push(newUser);\n  }\n\n  registrarLibro(titulo, autor, copiasDisponibles) {\n    const newLibro = new Book(titulo, autor, copiasDisponibles);\n    this.libros.push(newLibro);\n  }\n\n  prestarLibro(libro, usuario) {\n    const libroEncontrado = this.libros.find((l) => l.titulo === libro);\n    const usuarioEncontrado = this.usuarios.find((u) => u.dni === usuario);\n\n    if (\n      libroEncontrado &&\n      usuarioEncontrado &&\n      libroEncontrado.copiasDisponibles > 0\n    ) {\n      this.prestamos.push({\n        libro: libroEncontrado,\n        usuario: usuarioEncontrado,\n      });\n      libroEncontrado.copiasDisponibles--;\n      console.log(\n        `Se ha prestado el libro ${libro} para el usuario ${usuario}`\n      );\n    } else {\n      console.log(\n        \"Error, no se ha encontrado el libro y/o usuario o no existen copias disponibles\"\n      );\n    }\n  }\n\n  devolverLibro(libro, usuario) {\n    const index = this.prestamos.find(\n      (p) => p.libro.titulo === libro && p.usuario.nombre === usuario\n    );\n    const libroEncontrado = this.libros.find(l => l.titulo === libro);\n\n    if (index !== -1) {\n      this.prestamos.splice(index, 1);\n      libroEncontrado && libroEncontrado.copiasDisponibles++;\n      console.log(\"El libro se ha devuelto correctamente\");\n    } else {\n      console.log(\"Préstamo no encontrado\");\n    }\n  }\n}\n\nclass Book {\n  constructor(titulo, autor, copiasDisponibles) {\n    this.titulo = titulo;\n    this.autor = autor;\n    this.copiasDisponibles = copiasDisponibles;\n  }\n}\n\nclass User {\n  constructor(nombre, dni, email) {\n    this.nombre = nombre;\n    this.dni = dni;\n    this.email = email;\n  }\n}\n\nconsole.log('-------------Ejemplo con la clase NO SRP-----------');\n\nconst biblioteca = new Library();\n\n// Registrar libros\nbiblioteca.registrarLibro('1984', 'George Orwell', 3);\nbiblioteca.registrarLibro('El Principito', 'Antoine de Saint-Exupéry', 2);\n\n// Registrar usuarios\nbiblioteca.registrarUsuario('Juan Pérez', '123456', 'juan@example.com');\nbiblioteca.registrarUsuario('María López', '654321', 'maria@example.com');\n\n// Prestar libros\nbiblioteca.prestarLibro('1984', '123456'); // Juan toma prestado '1984'\nbiblioteca.prestarLibro('El Principito', '654321'); // María toma prestado 'El Principito'\n\n// Intentar prestar un libro que no está disponible\nbiblioteca.prestarLibro('1984', '654321'); // María intenta tomar '1984', pero no hay copias disponibles\n\n// Devolver libros\nbiblioteca.devolverLibro('1984', '123456'); // Juan devuelve '1984'\nbiblioteca.devolverLibro('El Principito', '654321'); // María devuelve 'El Principito'\n\nconsole.log('-------------Ejemplo con la clase SRP-----------');\n\nconst bibliotecaSRP = new LibrarySRP();\n\n// Registrar libros\nbibliotecaSRP.registrarLibro('Cien años de soledad', 'Gabriel García Márquez', 5);\nbibliotecaSRP.registrarLibro('Crónica de una muerte anunciada', 'Gabriel García Márquez', 2);\n\n// Registrar usuarios\nbibliotecaSRP.registrarUsuario('Carlos Ruiz', '111222', 'carlos@example.com');\nbibliotecaSRP.registrarUsuario('Ana Torres', '333444', 'ana@example.com');\n\n// Prestar libros\nbibliotecaSRP.prestarLibro('Cien años de soledad', '111222'); // Carlos toma prestado 'Cien años de soledad'\nbibliotecaSRP.prestarLibro('Crónica de una muerte anunciada', '333444'); // Ana toma prestado 'Crónica de una muerte anunciada'\n\n// Intentar prestar un libro que no está disponible\nbibliotecaSRP.prestarLibro('Cien años de soledad', '333444'); // Ana intenta tomar 'Cien años de soledad', pero no hay copias disponibles\n\n// Devolver libros\nbibliotecaSRP.devolverLibro('Cien años de soledad', '111222'); // Carlos devuelve 'Cien años de soledad'\nbibliotecaSRP.devolverLibro('Crónica de una muerte anunciada', '333444'); // Ana devuelve 'Crónica de una muerte anunciada'\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/javascript/duendeintemporal.js",
    "content": "//#26 - Principio SOLID de Responsabilidad Única (Single Responsibility Principle, SRP)\n//Bibliografy: The Web Development Glossary (Jens Oliver Meiert) (Z-Library)\n//GPT\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n * Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n * manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n * y el procesamiento de préstamos de libros.\n * Requisitos:\n * 1. Registrar libros: El sistema debe permitir agregar nuevos libros con\n * información básica como título, autor y número de copias disponibles.\n * 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n * información básica como nombre, número de identificación y correo electrónico.\n * 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n * tomar prestados y devolver libros.\n * Instrucciones:\n * 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n * los tres aspectos mencionados anteriormente (registro de libros, registro de\n * usuarios y procesamiento de préstamos).\n * 2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n * siguiendo el Principio de Responsabilidad Única.\n */\n\n\n/*  Single Responsibility Principle\nA computer programming principle that states that every module, class, or\nfunction should have responsibility over a single part of the functionality\nprovided by the software, and that responsibility should be entirely\nencapsulated by the module, class, or function. All its services should be\nnarrowly aligned with that responsibility.  */\n\n//Not Following the Single Responsibility Principle (SRP)\n\nlet log = console.log;\n\nwindow.addEventListener('load', ()=>{\n    const body = document.querySelector('body');\n    const title = document.createElement('h1');\n    \n    body.style.setProperty('background', '#000');\n    body.style.setProperty('text-align', 'center');\n    \n    title.textContent = 'Retosparaprogramadores #26.';\n    title.style.setProperty('font-size', '3.5vmax');\n    title.style.setProperty('color', '#fff');\n    title.style.setProperty('line-height', '100vh');\n    \n    body.appendChild(title);\n    \n    setTimeout(()=>{\n    alert('Retosparaprogramadores #26. Please open the Browser Developer Tools.');\n    }, 2000);\n    log( 'Retosparaprogramadores #26'); \n});\n\nclass Library {\n    constructor() {\n        this.books = [];\n        this.users = [];\n        this.loans = [];\n    }\n\n    addBook(title, author, copies) {\n        this.books.push({ title, author, copies });\n    }\n\n    registerUser(name, id, email) {\n        this.users.push({ name, id, email });\n    }\n\n    loanBook(userId, bookTitle) {\n        const user = this.users.find(u => u.id === userId);\n        const book = this.books.find(b => b.title === bookTitle);\n\n        if (user && book && book.copies > 0) {\n            this.loans.push({ userId, bookTitle });\n            book.copies--;\n            log(`Book \"${bookTitle}\" loaned to ${user.name}`);\n        } else {\n            log(\"Loan failed: User or book not found, or no copies available.\");\n        }\n    }\n}\n\n\nconst library = new Library();\nlibrary.addBook(\"Learn Bash the Hard Way\", \"Ian Miell\", 2);\nlibrary.addBook(\"MATLAB Notes for Professionals\", \"GoalKicker.com\", 4);\nlibrary.registerUser(\"Royer Rabit\", \"006\", \"happyrabbit@proton.me\");\nlibrary.loanBook(\"006\", \"MATLAB Notes for Professionals\"); //Book \"MATLAB Notes for Professionals\" loaned to Royer Rabit\n\n\n//Extra difiiculty Excercise\n//Following the Single Responsibility Principle (SRP)\n\nclass Book {\n    constructor(title, author, copies) {\n        this.title = title;\n        this.author = author;\n        this.copies = copies;\n    }\n}\n\nclass User {\n    constructor(name, id, email) {\n        this.name = name;\n        this.id = id;\n        this.email = email;\n    }\n}\n\nclass BookManager {\n    constructor() {\n        this.books = [];\n    }\n\n    addBook(title, author, copies) {\n        this.books.push(new Book(title, author, copies));\n    }\n\n    getBooks() {\n        return this.books; \n    }\n\n    findBook(title) {\n        return this.books.find(b => b.title === title);\n    }\n\n    increaseCopies(bookTitle) {\n        const book = this.findBook(bookTitle);\n        if (book) {\n            book.copies++;\n        }\n    }\n}\n\nfunction searchBooksByPartialTitle(books, searchTerm) {\n    return books.filter(book => \n        book.title.toLowerCase().includes(searchTerm.toLowerCase())\n    );\n}\n\nclass UserManager {\n    constructor() {\n        this.users = [];\n    }\n\n    registerUser(name, id, email) {\n        this.users.push(new User(name, id, email));\n    }\n\n    findUser(id) {\n        return this.users.find(u => u.id === id);\n    }\n}\n\nclass LoanManager {\n    constructor() {\n        this.loans = [];\n        this.nextLoanId = 1;\n    }\n\n    loanBook(user, book) {\n        if (book.copies > 0) {\n            const loanId = this.nextLoanId++;\n            this.loans.push({loanId, userId: user.id, bookTitle: book.title });\n            book.copies--;\n            log(`Book \"${book.title}\" loaned to ${user.name} with Loan ID: ${loanId}`);\n        } else {\n            log(\"Loan failed: No copies available.\");\n        }\n    }\n\n    returnBook(loanId, bookManager) {\n        const loanIndex = this.loans.findIndex(loan => loan.loanId === loanId);\n\n        if (loanIndex !== -1) {\n            const loan = this.loans[loanIndex];\n            const book = bookManager.findBook(loan.bookTitle);\n            if (book) {\n                book.copies++;\n            }\n\n            // Remove the loan from the loans array\n            this.loans.splice(loanIndex, 1);\n            log(`Book \"${loan.bookTitle}\" returned with Loan ID: ${loanId}`);\n        } else {\n            log(\"Return failed: No loan record found for this Loan ID.\");\n        }\n    }\n\n    getLoansByPartialBookTitle(searchTerm, userId) {\n        return this.loans.filter(loan => \n            loan.bookTitle.toLowerCase().includes(searchTerm.toLowerCase()) && loan.userId === userId\n        );\n    }\n}\n\n\nconst bookManager = new BookManager();\nconst userManager = new UserManager();\nconst loanManager = new LoanManager();\n\nbookManager.addBook(\"300 JavaScript Interview Mastery Questions Dive Deep into JavaScript Theory, Syntax, and APIs, and Interview with Confidence\", \"Middaugh, Jonathan\", 3);\nbookManager.addBook(\"Javascript Interview Questions and Answers\", \"Bandal, Pratik\", 7);\nbookManager.addBook(\"100 MOST ASKED JOB READY QUESTIONS ANSWERS IN THE TECH SPACE Here are the most asked questions in PYTHON, SQL, JAVASCRIPT...\", \"Aimee Mills\", 2);\nuserManager.registerUser(\"Niko Zen\", \"008\", \"duendeintemporal@hotmail.com\");\n\nconst searchTerm1 = \"JavaScript\";\nconst searchTerm2 = \"Interview Questions\";\n\nconst searchResults1 = searchBooksByPartialTitle(bookManager.getBooks(), searchTerm1);\nconst searchResults2 = searchBooksByPartialTitle(bookManager.getBooks(), searchTerm2);\n\nlog(searchResults1); \n/*\nBook {title: '300 JavaScript Interview Mastery Questions Dive De…, Syntax, and APIs, and Interview with Confidence', author: 'Middaugh, Jonathan', copies: 3}\nBook {title: 'Javascript Interview Questions and Answers', author: 'Bandal, Pratik', copies: 7} \nBook {title: '100 MOST ASKED JOB READY QUESTIONS ANSWERS IN THE …ost asked questions in PYTHON, SQL, JAVASCRIPT...', author: 'Aimee Mills', copies: 2}\n  */\nlog(searchResults2); \n/* {author:\"Bandal, Pratik\", copies:7, title:\"Javascript Interview Questions and Answers\"} */\n\nconst user = userManager.findUser(\"008\");\nconst bookTitle = searchResults1[2]?.title; \nconst book = bookManager.findBook(bookTitle); \n\nif (book) {\n    loanManager.loanBook(user, book); // Book \"100 MOST ASKED JOB READY QUESTIONS ANSWERS IN THE TECH SPACE Here are the most asked questions in PYTHON, SQL, JAVASCRIPT...\" loaned to Niko Zen with Loan ID: 1\n    const loans = loanManager.getLoansByPartialBookTitle(book.title, user.id);\n    loanManager.returnBook(loans[0].loanId, bookManager); // Book \"100 MOST ASKED JOB READY QUESTIONS ANSWERS IN THE TECH SPACE Here are the most asked questions in PYTHON, SQL, JAVASCRIPT...\" returned with Loan ID: 1\n} else {\n    log(\"Book not found for loan.\");\n}\n\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/javascript/eulogioep.js",
    "content": "/**\n * PRINCIPIO DE RESPONSABILIDAD ÚNICA (SRP)\n * \n * El Principio de Responsabilidad Única establece que:\n * \"Una clase debe tener una única razón para cambiar\"\n * \n * Este principio nos ayuda a:\n * - Crear código más mantenible\n * - Facilitar las pruebas unitarias\n * - Reducir el acoplamiento\n * - Mejorar la cohesión del código\n * - Facilitar la reutilización\n */\n\n// ========== IMPLEMENTACIÓN INCORRECTA (Violando SRP) ==========\n\n/**\n * Esta implementación viola el SRP porque la clase Library maneja múltiples responsabilidades:\n * 1. Gestión de libros\n * 2. Gestión de usuarios\n * 3. Gestión de préstamos\n */\nclass Library {\n    constructor() {\n        this.books = [];\n        this.users = [];\n        this.loans = [];\n    }\n\n    // Gestión de libros\n    addBook(title, author, copies) {\n        const book = new Book(title, author, copies);\n        this.books.push(book);\n    }\n\n    removeBook(bookId) {\n        this.books = this.books.filter(book => book.id !== bookId);\n    }\n\n    // Gestión de usuarios\n    registerUser(name, id, email) {\n        const user = new User(name, id, email);\n        this.users.push(user);\n    }\n\n    removeUser(userId) {\n        this.users = this.users.filter(user => user.id !== userId);\n    }\n\n    // Gestión de préstamos\n    loanBook(userId, bookId) {\n        const book = this.books.find(b => b.id === bookId);\n        const user = this.users.find(u => u.id === userId);\n\n        if (!book || !user) {\n            throw new Error(\"Libro o usuario no encontrado\");\n        }\n\n        if (book.availableCopies <= 0) {\n            throw new Error(\"No hay copias disponibles\");\n        }\n\n        book.availableCopies--;\n        this.loans.push(new Loan(userId, bookId, new Date()));\n    }\n\n    returnBook(userId, bookId) {\n        const loan = this.loans.find(\n            l => l.userId === userId && l.bookId === bookId\n        );\n        \n        if (!loan) {\n            throw new Error(\"Préstamo no encontrado\");\n        }\n\n        const book = this.books.find(b => b.id === bookId);\n        if (book) {\n            book.availableCopies++;\n        }\n\n        this.loans = this.loans.filter(l => l !== loan);\n    }\n}\n\n// ========== IMPLEMENTACIÓN CORRECTA (Siguiendo SRP) ==========\n\n/**\n * BookManager: Responsable únicamente de la gestión de libros\n */\nclass BookManager {\n    constructor() {\n        this.books = [];\n    }\n\n    addBook(title, author, copies) {\n        const book = new Book(title, author, copies);\n        this.books.push(book);\n        return book;\n    }\n\n    removeBook(bookId) {\n        this.books = this.books.filter(book => book.id !== bookId);\n    }\n\n    findBook(bookId) {\n        return this.books.find(book => book.id === bookId);\n    }\n\n    updateBookCopies(bookId, change) {\n        const book = this.findBook(bookId);\n        if (book) {\n            book.availableCopies += change;\n        }\n    }\n\n    getAllBooks() {\n        return [...this.books];\n    }\n}\n\n/**\n * UserManager: Responsable únicamente de la gestión de usuarios\n */\nclass UserManager {\n    constructor() {\n        this.users = [];\n    }\n\n    registerUser(name, id, email) {\n        const user = new User(name, id, email);\n        this.users.push(user);\n        return user;\n    }\n\n    removeUser(userId) {\n        this.users = this.users.filter(user => user.id !== userId);\n    }\n\n    findUser(userId) {\n        return this.users.find(user => user.id === userId);\n    }\n\n    getAllUsers() {\n        return [...this.users];\n    }\n}\n\n/**\n * LoanManager: Responsable únicamente de la gestión de préstamos\n */\nclass LoanManager {\n    constructor(bookManager, userManager) {\n        this.loans = [];\n        this.bookManager = bookManager;\n        this.userManager = userManager;\n    }\n\n    loanBook(userId, bookId) {\n        const book = this.bookManager.findBook(bookId);\n        const user = this.userManager.findUser(userId);\n\n        if (!book || !user) {\n            throw new Error(\"Libro o usuario no encontrado\");\n        }\n\n        if (book.availableCopies <= 0) {\n            throw new Error(\"No hay copias disponibles\");\n        }\n\n        this.bookManager.updateBookCopies(bookId, -1);\n        const loan = new Loan(userId, bookId, new Date());\n        this.loans.push(loan);\n        return loan;\n    }\n\n    returnBook(userId, bookId) {\n        const loan = this.findLoan(userId, bookId);\n        \n        if (!loan) {\n            throw new Error(\"Préstamo no encontrado\");\n        }\n\n        this.bookManager.updateBookCopies(bookId, 1);\n        this.removeLoan(userId, bookId);\n    }\n\n    findLoan(userId, bookId) {\n        return this.loans.find(\n            loan => loan.userId === userId && loan.bookId === bookId\n        );\n    }\n\n    removeLoan(userId, bookId) {\n        this.loans = this.loans.filter(\n            loan => !(loan.userId === userId && loan.bookId === bookId)\n        );\n    }\n\n    getAllLoans() {\n        return [...this.loans];\n    }\n}\n\n// Clases de modelo\nclass Book {\n    constructor(title, author, availableCopies) {\n        this.id = Math.random().toString(36).substr(2, 9);\n        this.title = title;\n        this.author = author;\n        this.availableCopies = availableCopies;\n    }\n}\n\nclass User {\n    constructor(name, id, email) {\n        this.name = name;\n        this.id = id;\n        this.email = email;\n    }\n}\n\nclass Loan {\n    constructor(userId, bookId, loanDate) {\n        this.userId = userId;\n        this.bookId = bookId;\n        this.loanDate = loanDate;\n    }\n}\n\n// Ejemplo de uso del sistema\n// Creación de los managers\nconst bookManager = new BookManager();\nconst userManager = new UserManager();\nconst loanManager = new LoanManager(bookManager, userManager);\n\n// Ejemplo de uso\ntry {\n    // Agregar un libro\n    const book = bookManager.addBook(\"El Quijote\", \"Miguel de Cervantes\", 5);\n    console.log(\"Libro agregado:\", book);\n\n    // Registrar un usuario\n    const user = userManager.registerUser(\"Juan Pérez\", \"USER001\", \"juan@email.com\");\n    console.log(\"Usuario registrado:\", user);\n\n    // Realizar un préstamo\n    const loan = loanManager.loanBook(user.id, book.id);\n    console.log(\"Préstamo realizado:\", loan);\n\n    // Devolver el libro\n    loanManager.returnBook(user.id, book.id);\n    console.log(\"Libro devuelto exitosamente\");\n\n    // Verificar el estado del libro\n    const updatedBook = bookManager.findBook(book.id);\n    console.log(\"Estado actual del libro:\", updatedBook);\n} catch (error) {\n    console.error(\"Error:\", error.message);\n}"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/javascript/hectorio23.js",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\n\"use strict\";\n\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n * Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA:\n * Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n * manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n * y el procesamiento de préstamos de libros.\n * Requisitos:\n * 1. Registrar libros: El sistema debe permitir agregar nuevos libros con \n * información básica como título, autor y número de copias disponibles.\n * 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n * información básica como nombre, número de identificación y correo electrónico.\n * 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n * tomar prestados y devolver libros.\n*/\n\nconst readline = require('readline');\n\nclass Book {\n    constructor(title, author, copies) {\n        this.title = title;\n        this.author = author;\n        this.copies = copies;\n    }\n}\n\nclass BookManager {\n    constructor() {\n        this.books = [];\n    }\n\n    addBook(rl, callback) {\n        console.clear();\n        rl.question('Ingrese el título del libro: ', (title) => {\n            rl.question('Ingrese el autor del libro: ', (author) => {\n                rl.question('Ingrese el número de copias: ', (copies) => {\n                    this.books.push(new Book(title, author, parseInt(copies)));\n                    console.log('Libro agregado exitosamente.');\n                    callback();\n                });\n            });\n        });\n    }\n\n    listBooks() {\n        console.clear();\n        if (this.books.length === 0) {\n            console.log('No hay libros disponibles.');\n            return;\n        }\n        this.books.forEach(book => {\n            console.log(`Título: ${book.title}, Autor: ${book.author}, Copias: ${book.copies}`);\n        });\n    }\n}\n\nclass User {\n    constructor(name, id, email) {\n        this.name = name;\n        this.id = id;\n        this.email = email;\n    }\n}\n\nclass UserManager {\n    constructor() {\n        this.users = [];\n    }\n\n    addUser(rl, callback) {\n        console.clear();\n        rl.question('Ingrese el nombre del usuario: ', (name) => {\n            rl.question('Ingrese el ID del usuario: ', (id) => {\n                rl.question('Ingrese el correo electrónico del usuario: ', (email) => {\n                    this.users.push(new User(name, parseInt(id), email));\n                    console.log('Usuario agregado exitosamente.');\n                    callback();\n                });\n            });\n        });\n    }\n\n    listUsers() {\n        console.clear();\n        if (this.users.length === 0) {\n            console.log('No hay usuarios registrados.');\n            return;\n        }\n        this.users.forEach(user => {\n            console.log(`Nombre: ${user.name}, ID: ${user.id}, Correo: ${user.email}`);\n        });\n    }\n}\n\nclass LoanManager {\n    lendBook(rl, userManager, bookManager, callback) {\n        console.clear();\n        rl.question('Ingrese el ID del usuario: ', (userId) => {\n            rl.question('Ingrese el título del libro a prestar: ', (bookTitle) => {\n                // Lógica de préstamo\n                console.log(`Libro '${bookTitle}' prestado al usuario ID ${userId}.`);\n                callback();\n            });\n        });\n    }\n\n    returnBook(rl, userManager, bookManager, callback) {\n        console.clear();\n        rl.question('Ingrese el ID del usuario: ', (userId) => {\n            rl.question('Ingrese el título del libro a devolver: ', (bookTitle) => {\n                // Lógica de devolución\n                console.log(`Libro '${bookTitle}' devuelto por el usuario ID ${userId}.`);\n                callback();\n            });\n        });\n    }\n}\n\nfunction displayMenu() {\n    console.clear();\n    console.log('******** Menú de la Biblioteca ********');\n    console.log('[1] - Agregar un libro');\n    console.log('[2] - Listar libros');\n    console.log('[3] - Agregar un usuario');\n    console.log('[4] - Listar usuarios');\n    console.log('[5] - Prestar un libro');\n    console.log('[6] - Devolver un libro');\n    console.log('[7] - Salir');\n    console.log('Seleccione una opción: ');\n}\n\nfunction main() {\n    const rl = readline.createInterface({\n        input: process.stdin,\n        output: process.stdout\n    });\n\n    const bookManager = new BookManager();\n    const userManager = new UserManager();\n    const loanManager = new LoanManager();\n\n    function menu() {\n        displayMenu();\n        rl.question('', (option) => {\n            switch (parseInt(option)) {\n                case 1:\n                    bookManager.addBook(rl, menu);\n                    break;\n                case 2:\n                    bookManager.listBooks();\n                    pause(menu);\n                    break;\n                case 3:\n                    userManager.addUser(rl, menu);\n                    break;\n                case 4:\n                    userManager.listUsers();\n                    pause(menu);\n                    break;\n                case 5:\n                    loanManager.lendBook(rl, userManager, bookManager, menu);\n                    break;\n                case 6:\n                    loanManager.returnBook(rl, userManager, bookManager, menu);\n                    break;\n                case 7:\n                    console.log('Saliendo del sistema...');\n                    rl.close();\n                    break;\n                default:\n                    console.log('Opción no válida. Intente de nuevo.');\n                    pause(menu);\n            }\n        });\n    }\n\n    function pause(callback) {\n        rl.question('Presione Enter para continuar...', () => {\n            callback();\n        });\n    }\n\n    menu();\n}\n\nmain();\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n___________________________________________________\n#26 SOLID: PRINCIPIO DE RESPONSABILIDAD ÚNICA (SRP)\n---------------------------------------------------\n* EJERCICIO:\n * Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n * Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un sistema de gestión para una biblioteca. El sistema necesit\n * manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n * y el procesamiento de préstamos de libros.\n * Requisitos:\n * 1. Registrar libros: El sistema debe permitir agregar nuevos libros con\n * información básica como título, autor y número de copias disponibles.\n * 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n * información básica como nombre, número de identificación y correo electrónico.\n * 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n * tomar prestados y devolver libros.\n * Instrucciones:\n * 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n * los tres aspectos mencionados anteriormente (registro de libros, registro de\n * usuarios y procesamiento de préstamos).\n * 2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n * siguiendo el Principio de Responsabilidad Única.\n*/\n// ________________________________________________________\n// SIN APLICAR SRP\n// ---------------\nclass Program {\n    constructor() {\n      this.customers = [];\n      this.suppliers = [];\n    }\n  \n    addCustomer(name) {\n      this.customers.push(name);\n    }\n  \n    removeCustomer(name) {\n      this.customers = this.customers.filter((customer) => customer !== name);\n    }\n  \n    addSupplier(name) {\n      this.suppliers.push(name);\n    }\n  \n    removeSupplier(name) {\n      this.suppliers = this.suppliers.filter((supplier) => supplier !== name);\n    }\n  \n    printData() {\n      console.log(\"Clientes:\", this.customers);\n      console.log(\"Proveedores:\", this.suppliers);\n    }\n  }\n\n// ________________________________________________________\n// APLICANDO SRP\n// ---------------\n\nclass Customers {\n    constructor() {\n      this.customers = [];\n    }\n  \n    add(name) {\n      this.customers.push(name);\n    }\n  \n    remove(name) {\n      this.customers = this.customers.filter((customer) => customer !== name);\n    }\n  \n    print() {\n      console.log(\"Clientes:\", this.customers);\n    }\n  }\n  \n  class Suppliers {\n    constructor() {\n      this.suppliers = [];\n    }\n  \n    add(name) {\n      this.suppliers.push(name);\n    }\n  \n    remove(name) {\n      this.suppliers = this.suppliers.filter((supplier) => supplier !== name);\n    }\n  \n    print() {\n      console.log(\"Proveedores:\", this.suppliers);\n    }\n  }\n  \n  const customers = new Customers();\n  const suppliers = new Suppliers();\n  \n  customers.add(\"Cliente A\");\n  customers.add(\"Cliente B\");\n  suppliers.add(\"Proveedor X\");\n  \n  customers.print();\n  suppliers.print();\n  \n  customers.remove(\"Cliente A\");\n  suppliers.remove(\"Proveedor X\");\n  \n  customers.print();\n  suppliers.print();\n  \n\n// ________________________________________________________\n// DIFICULTAD EXTRA\n// ---------------\n// SIN APLICAR SRP\n// ---------------\nclass Library {\n    constructor() {\n        this.books = {};\n        this.users = {};\n        this.borrowed = {};\n    }\n\n    addBook(id, title, author, stock) {\n        if (this.books[id]) {\n            this.books[id].stock += stock;\n            this.books[id].available += stock;\n            console.log(\"El libro ya existe, se actualizó el inventario.\");\n        } else {\n            this.books[id] = { title, author, stock, available: stock };\n            console.log(`Libro '${title}' agregado.`);\n        }\n    }\n\n    addUser(id, name, email) {\n        if (this.users[id]) {\n            console.log(\"El usuario ya existe.\");\n        } else {\n            this.users[id] = { name, email };\n            console.log(`Usuario '${name}' agregado.`);\n        }\n    }\n\n    lendBook(borrowId, userId, bookId) {\n        if (!this.books[bookId]) return console.log(\"El libro no existe.\");\n        if (!this.users[userId]) return console.log(\"El usuario no existe.\");\n        if (this.books[bookId].available <= 0)\n            return console.log(\"El libro no está disponible.\");\n\n        this.borrowed[borrowId] = { userId, bookId };\n        this.books[bookId].available -= 1;\n        console.log(`Libro '${bookId}' prestado.`);\n    }\n\n    returnBook(borrowId) {\n        if (!this.borrowed[borrowId]) return console.log(\"No existe el préstamo.\");\n\n        const { bookId } = this.borrowed[borrowId];\n        this.books[bookId].available += 1;\n        delete this.borrowed[borrowId];\n        console.log(`Libro '${bookId}' devuelto.`);\n    }\n}\n\n// ________________________________________________________\n// Aplicando SRP:\n// ---------------\n\n// Singleton\nclass LibraryData {\n    constructor() {\n        if (!LibraryData.instance) {\n            this.books = {};\n            this.users = {};\n            this.borrowed = {};\n            LibraryData.instance = this;\n        }\n        return LibraryData.instance;\n    }\n}\n\nconst data = new LibraryData();\n\nclass Books {\n    add(id, title, author, stock) {\n        if (data.books[id]) {\n            data.books[id].stock += stock;\n            data.books[id].available += stock;\n            console.log(\"El libro ya existe, se actualizó el inventario.\");\n        } else {\n            data.books[id] = { title, author, stock, available: stock };\n            console.log(`Libro '${title}' agregado.`);\n        }\n    }\n\n    print() {\n        console.log(\"Libros:\", data.books);\n    }\n}\n\nclass Users {\n    add(id, name, email) {\n        if (data.users[id]) {\n            console.log(\"El usuario ya existe.\");\n        } else {\n            data.users[id] = { name, email };\n            console.log(`Usuario '${name}' agregado.`);\n        }\n    }\n\n    print() {\n        console.log(\"Usuarios:\", data.users);\n    }\n}\n\nclass BorrowedBooks {\n    lend(borrowId, userId, bookId) {\n        if (!data.books[bookId]) return console.log(\"El libro no existe.\");\n        if (!data.users[userId]) return console.log(\"El usuario no existe.\");\n        if (data.books[bookId].available <= 0)\n            return console.log(\"El libro no está disponible.\");\n\n        data.borrowed[borrowId] = { userId, bookId };\n        data.books[bookId].available -= 1;\n        console.log(`Libro '${bookId}' prestado.`);\n    }\n\n    returnBook(borrowId) {\n        if (!data.borrowed[borrowId]) return console.log(\"No existe el préstamo.\");\n\n        const { bookId } = data.borrowed[borrowId];\n        data.books[bookId].available += 1;\n        delete data.borrowed[borrowId];\n        console.log(`Libro '${bookId}' devuelto.`);\n    }\n\n    print() {\n        console.log(\"Préstamos:\", data.borrowed);\n    }\n}\n\n// ---------------\nconst books = new Books();\nconst users = new Users();\nconst borrowed = new BorrowedBooks();\nconsole.log(\"\\nDIFICULTAD EXTRA\\n\")\nbooks.add(1, \"Libro A\", \"Autor A\", 2);\nbooks.add(2, \"Libro B\", \"Autor B\", 3);\n\nusers.add(101, \"Usuario 1\", \"user1@example.com\");\nusers.add(102, \"Usuario 2\", \"user2@example.com\");\n\nborrowed.lend(201, 101, 1);\nborrowed.lend(202, 102, 2);\n\nbooks.print();\nusers.print();\nborrowed.print();\n\nborrowed.returnBook(201);\nbooks.print();\nborrowed.print();\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/javascript/nlarrea.js",
    "content": "/* EJERCICIO:\n * Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n * Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n * manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n * y el procesamiento de préstamos de libros.\n * Requisitos:\n * 1. Registrar libros: El sistema debe permitir agregar nuevos libros con \n * información básica como título, autor y número de copias disponibles.\n * 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n * información básica como nombre, número de identificación y correo electrónico.\n * 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n * tomar prestados y devolver libros.\n * Instrucciones:\n * 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n * los tres aspectos mencionados anteriormente (registro de libros, registro de\n * usuarios y procesamiento de préstamos).\n * 2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n * siguiendo el Principio de Responsabilidad Única.\n */\n\n\n// Incorrect\n\n\nclass User1 {\n    constructor(name, email) {\n        this.name = name;\n        this.email = email;\n    }\n\n    addUser() {\n        // add user\n    }\n\n    sendEmail() {\n        // send an email\n    }\n};\n\n\n// Correct\n\n\nclass User2 {\n    constructor(name, email) {\n        this.name = name;\n        this.email = email;\n    }\n}\n\n\nclass UserService {\n    addUser(user) {\n        // add user to database\n    }\n}\n\n\nclass EmailService {\n    sendEmail(email, message) {\n        // send an email\n    }\n}\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n * manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n * y el procesamiento de préstamos de libros.\n * Requisitos:\n * 1. Registrar libros: El sistema debe permitir agregar nuevos libros con \n * información básica como título, autor y número de copias disponibles.\n * 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n * información básica como nombre, número de identificación y correo electrónico.\n * 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n * tomar prestados y devolver libros.\n * Instrucciones:\n * 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n * los tres aspectos mencionados anteriormente (registro de libros, registro de\n * usuarios y procesamiento de préstamos).\n * 2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n * siguiendo el Principio de Responsabilidad Única.\n */\n\n\n// Incorrect\n\n\nclass LibraryWrong {\n    constructor() {\n        this.books = [];\n        this.users = [];\n        this.loans = [];\n    }\n\n    addBook(title, author, copies) {\n        this.books.push({title, author, copies});\n    }\n\n    addUser(id, name, email) {\n        this.users.push({id, name, email});\n    }\n\n    loanBook(userId, bookTitle) {\n        for (const book of this.books) {\n            if (book.title === bookTitle && book.copies > 0) {\n                book.copies--;\n                this.loans.push({userId, bookTitle});\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    returnBook(userId, bookTitle) {\n        for (const loan of this.loans) {\n            if (loan.userId === userId && loan.bookTitle === bookTitle) {\n                const currentIndex = this.loans.indexOf(loan);\n                this.loans.splice(currentIndex, 1);\n                \n                for (const book of this.books) {\n                    if (book.title === bookTitle) {\n                        book.copies++;\n                        return true;\n                    }\n                }\n            }\n        }\n\n        return false;\n    }\n}\n\n\n// Correct\n\n\nclass User {\n    constructor(id, name, email) {\n        this.id = id;\n        this.name = name;\n        this.email = email;\n    }\n}\n\n\nclass Book {\n    constructor(title, author, copies) {\n        this.title = title;\n        this.author = author;\n        this.copies = copies;\n    }\n}\n\n\nclass BookLending {\n    constructor() {\n        this.loans = [];\n    }\n\n    loanBook(user, book) {\n        if (book.copies > 0) {\n            book.copies--;\n            this.loans.push({userId: user.id, bookTitle: book.title});\n            return true;\n        }\n\n        return false;\n    }\n\n    returnBook(user, book) {\n        for (const loan of this.loans) {\n            if (loan.userId === user.id && loan.bookTitle === book.title) {\n                const currentIndex = this.loans.indexOf(loan);\n                this.loans.splice(currentIndex, 1);\n                book.copies++;\n                return true;\n            }\n        }\n\n        return false;\n    }\n}\n\n\nclass Library {\n    constructor() {\n        this.books = [];\n        this.users = [];\n        this.loansService = new BookLending();\n    }\n\n    addBook(book) {\n        this.books.push(book);\n    }\n\n    addUser(user) {\n        this.users.push(user);\n    }\n\n    loanBook(userId, bookTitle) {\n        const user = this.users.find(u => u.id === userId);\n        const book = this.books.find(b => b.title === bookTitle);\n\n        if (user && book) {\n            return this.loansService.loanBook(user, book);\n        }\n\n        return false;\n    }\n\n    returnBook(userId, bookTitle) {\n        const user = this.users.find(u => u.id === userId);\n        const book = this.books.find(b => b.title === bookTitle);\n\n        if (user && book) {\n            return this.loansService.returnBook(user, book);\n        }\n\n        return false;\n    }\n}\n\n\nconst library = new Library();\nlibrary.addUser(new User(id='a11', name='Naia', email='naia@email.com'));\nlibrary.addBook(new Book(title='The Lord Of The Rings', author='J.R.R. Tolkien', copies=10));\n\nconsole.log(library.loanBook('a11', 'The Lord Of The Rings'));  // true\nconsole.log(library.loanBook('123', 'Not existing book'));  // false\n\nconsole.log(library.returnBook('a11', 'The Lord Of The Rings'));  // true\nconsole.log(library.returnBook('123', 'Not existing book'));  // false"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/javascript/parababire.js",
    "content": "// Forma incorrecta\n\nclass Person_Incorrect {\n  constructor(name, mail) {\n    this.name = name,\n    this.mail = mail\n  }\n  show_name() {\n    console.log(this.name)\n  }\n  show_mail() {\n    console.log(this.mail)\n  }\n}\n\nlet user = new Person_Incorrect('Ángel', 'angelenarvaez@gmail.com')\nuser.show_name()\nuser.show_mail()\n\n// Forma correcta\n\nclass Person {\n  constructor(name, mail) {\n    this.name = name,\n    this.mail = mail\n  }\n}\nclass Person_Name {\n  saludo(person) {\n    return `Hola mi nombre es ${person.name}`\n  }\n}\nclass Send_Mail {\n  send(person, message) {\n    return `${person.mail} ${message}`\n  }\n}\n\nlet person1 = new Person('Ángel', 'angelenarvaez@gmail.com')\n\nlet message = new Send_Mail()\nconsole.log(message.send(person1, 'Bienvenido a nuestra plataforma'))\n\nlet bienvenida = new Person_Name()\nconsole.log(bienvenida.saludo(person1))\n\n// Extra\n\n// Forma incorrecta\n\nclass Library_Incorrect {\n  constructor() {\n    this.books = []\n    this.users = []\n    this.loans = []\n  }\n  add_book (bookName, author, copies) {\n    return this.books.push({\n      Title: bookName,\n      Author: author,\n      Copies: copies\n    })\n  }\n  add_user (userName, id, mail) {\n    return this.users.push({\n      User: userName,\n      Id_Number: id,\n      Mail: mail\n    })\n  }\n  loan_book (user_id, book_title) {\n    for (const book of this.books) {\n      if (book.Title == book_title && book.Copies > 0) {\n        book.Copies -= 1\n        this.loans.push({\n          User_Id: user_id,\n          Book_Title: book_title\n        })\n        return true\n      }\n      return false\n    }\n  }\n  return_book (user_id, book_title) {\n    for (const loan of this.loans) {\n      if (loan.User_Id == user_id && loan.Book_Title == book_title) {\n        this.loans = this.loans.filter(function (el) {\n          return el.User_Id != user_id\n        })\n        for (const book of this.books) {\n          if (book.Title == book_title) {\n            book.Copies += 1\n          }\n        }\n        return true\n      }\n      return false\n    }\n  }\n}\n\n// Forma correcta\n\nclass Book {\n  constructor(title, author, copies) {\n    this.title = title,\n    this.author = author,\n    this.copies = copies\n  }\n}\n\nclass User {\n  constructor(name, id, mail) {\n    this.name = name,\n    this.id = id,\n    this.mail = mail\n  }\n}\n// Gestión de prestamos\nclass Loans {\n  constructor() {\n    this.loans = []\n  }\n  loan_book (user, book) {\n      if (book.copies > 0) {\n        book.copies -= 1\n        this.loans.push({\n          User_Id: user.id,\n          Book_Title: book.title\n        })\n        return true\n      }\n      return false\n  }\n  return_book (user, book) {\n    for (const loan of this.loans) {\n      if (loan.User_Id == user.id && loan.Book_Title == book.title) {\n        this.loans = this.loans.filter(function (el) {\n          return el.User_Id != user_id\n        })\n        book.copies += 1\n        return true\n      }\n      return false\n    }\n  }\n}\n\nclass Library {\n  constructor() {\n    this.books = []\n    this.users = []\n    this.loans_service = new Loans()\n  }\n  add_book (book) {\n    return this.books.push(book)\n  }\n  add_user (user) {\n    return this.users.push(user)\n  }\n  loan_book (user_id, book_title) {\n    let user = this.users.find((user) => user.id == user_id)\n    let book = this.books.find((book) => book.title == book_title)\n    if (user && book) {\n      return this.loans_service.loan_book(user, book)\n    }\n    return false\n  }\n\n  return_book (user_id, book_title) {\n    let user = this.users.find((user) => user.id == user_id)\n    let book = this.books.find((book) => book.title == book_title)\n    if (user && book) {\n      return this.loans_service.return_book(user, book)\n    }\n    return false\n  }\n}\n\nlet someBook = new Book('100 Años de Soledad', 'Gabo', 10)\nlet principalLibrary = new Library()\nprincipalLibrary.add_book(someBook)\n\nlet someUser = new User('Ángel', 15154142, 'anarvamon@gmail.com')\nprincipalLibrary.add_user(someUser)\n\nprincipalLibrary.loan_book(15154142, '100 Años de Soledad')\nconsole.log(principalLibrary)\nconsole.log(principalLibrary.loans_service)"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/javascript/pedamoci.js",
    "content": "// SRP MAL HECHO\nclass WrongSRP {\n  sumar(num1, num2) {\n    console.log(num1 + num2)\n  }\n\n  dateNow() {\n    const date = new Date \n    console.log(date.toDateString())\n  }\n}\n\nconst wrongSRP = new WrongSRP\nwrongSRP.sumar(45, 321)\nwrongSRP.dateNow()\n\n// SRP BIEN HECHO\nclass SumarSRP {\n  sumar(num1, num2) {\n    console.log(num1 + num2)\n  }\n}\n\nclass DateNowSRP {\n  dateNow() {\n    const date = new Date \n    console.log(date.toDateString())\n  }\n}\n\nconst sumarSRP = new SumarSRP\nsumarSRP.sumar(56, 987)\n\nconst dateNowSRP = new DateNowSRP\ndateNowSRP.dateNow()\n\n// ------------------------------------------------ DIFICULTAD EXTRA ------------------------------------------------\nclass ManagementLibrary {\n  constructor() {\n    this.books = new Map()\n    this.users = new Map()\n    this.loans = []\n  }\n\n  addBook(title, writer, numberCopies) {\n    if (this.books.has(title)) console.warn('El libro que desea agregar ya está en la biblioteca')\n    else {\n      this.books.set(title, {writer: writer, copies: numberCopies})\n      console.log('El libro se ha agregado al catálogo de la biblioteca')\n    }\n  }\n\n  addUser(idUser, name, number) {\n    if (this.users.has(idUser)) console.warn('El usuario ya está registrado en la biblioteca')\n    else {\n      this.users.set(idUser, {name: name, number: number})\n      console.log('El usuario se ha registrado correctamente en la biblioteca')\n    }\n  }\n\n  loanBook(title, idUser) {\n    if (!this.books.has(title)) return console.warn('El libro que desea no está en esta biblioteca')\n    if (!this.users.has(idUser)) return console.warn('El usuario no esta registrado en esta biblioteca')\n    const book = this.books.get(title) \n    if (book.copies > 0) {\n      this.loans.push([idUser, title])\n      book.copies--\n      console.log('Recuerda devolver el libro cuando lo termines, gracias!')\n    } else {\n      console.warn('No quedan existencias del libro que desea\\nPregunte nuevamente en otro momento o elija otro')\n    }\n  }\n\n  returnBook(title, idUser) {\n    if (this.books.has(title) && this.users.has(idUser)) {\n      let booksLoanedUser = this.loans.filter((loan) => loan[0] === idUser)  // devuelde los libros retirados por el usuario\n      if (booksLoanedUser.length > 0 && booksLoanedUser.map((loan) => loan[1] === title)) {  // verifica que haya libros retirado por el usuario y que coincida con el titulo ingresado\n        let index = this.loans.findIndex((loan) => {return loan[0] === idUser && loan[1] === title})  // devuelve el index del array donde esta el libro retirado y el id del usuario\n        this.loans.splice(index, 1)\n        const book = this.books.get(title) \n        book.copies++\n        console.log('Has devuelto el libro!! Gracias!!')\n      } else console.warn('Id o titulo del libro incorrectos')\n    }\n    else {\n      console.error('Datos incorrectos, vuelve a chequear que escribiste bien el nombre del libro o tu id')\n    }\n  }\n}\n\nconst library = new ManagementLibrary()\n\n//Creación de libros\nconsole.log('----------------- CREACION DE LIBROS -----------------')\nlibrary.addBook('Cien años de soledad', 'Gabriel García Márquez', 5); library.addBook('1984', 'George Orwell', 7); library.addBook('Orgullo y Prejuicio', 'Jane Austen', 3); library.addBook('El Principito', 'Antoine de Saint-Exupéry', 10); library.addBook('Don Quijote de la Mancha', 'Miguel de Cervantes', 2); library.addBook('Crimen y Castigo', 'Fiódor Dostoievski', 4); library.addBook('Moby Dick', 'Herman Melville', 6); library.addBook('Ensayo sobre la ceguera', 'José Saramago', 8)\n\n//Creación de usuarios\nconsole.log('\\n----------------- CREACION DE USUARIOS -----------------')\nlibrary.addUser(10001, 'Martina López', 987654321); library.addUser(10002, 'Javier Ríos', 912345678); library.addUser(10003, 'Sofía Giménez', 900112233); library.addUser(10004, 'Andrés Castro', 945612378); library.addUser(10005, 'Valeria Torres', 998877665); library.addUser(10006, 'Ricardo Paz', 965432101); library.addUser(10007, 'Elena Ruiz', 955544433); library.addUser(10008, 'Felipe Díaz', 933322211); library.addUser(10009, 'Carla Méndez', 977788899); library.addUser(10010, 'Pablo Núñez', 921234567); library.addUser(10011, 'Luisa Vargas', 987123456); library.addUser(10012, 'Diego Soto', 911223344); library.addUser(10013, 'Catalina Vega', 950505050); library.addUser(10014, 'Hugo Ferrer', 930303030); library.addUser(10015, 'Micaela Gil', 970707070)\n\n// Creación de prestamos\n  console.log('\\n----------------- CREACION DE PRESTAMOS -----------------')\n  // AGOTANDO EXISTENCIAS: 'Don Quijote de la Mancha' y 'Orgullo y Prejuicio'\n  library.loanBook('Don Quijote de la Mancha', 10001); library.loanBook('Don Quijote de la Mancha', 10002)\n  library.loanBook('Orgullo y Prejuicio', 10003); library.loanBook('Orgullo y Prejuicio', 10004); library.loanBook('Orgullo y Prejuicio', 10005)\n\n  // PETICIONES EXITOSAS\n  library.loanBook('1984', 10006); library.loanBook('Cien años de soledad', 10007); library.loanBook('Ensayo sobre la ceguera', 10008); library.loanBook('Moby Dick', 10009); library.loanBook('Crimen y Castigo', 10010)\n\n  // PETICIONES FALLIDAS\n    console.log('\\n----------------- CREACION DE PRESTAMOS ERRONEOS -----------------')\n    //Libros agotados\n    library.loanBook('Don Quijote de la Mancha', 10011); library.loanBook('Orgullo y Prejuicio', 10012)\n    //Libros inexistentes\n    library.loanBook('El Código Da Vinci', 10013); library.loanBook('Frieren', 10014)\n\n// Creación de devoluciones\n  // Devoluciones exitosas\n  console.log('\\n----------------- CREACION DE DEVOLUCIONES -----------------')\n  library.returnBook('Don Quijote de la Mancha', 10001); library.returnBook('Orgullo y Prejuicio', 10005); library.returnBook('1984', 10006); library.returnBook('Cien años de soledad', 10007); library.returnBook('Moby Dick', 10009)\n\n  // Devolución con ID de usuario incorrecto (posiblemente fallida)\n  console.log('\\n----------------- CREACION DE DEVOLUCIONES ERRONEAS -----------------')\n  library.returnBook('Crimen y Castigo', 32465)\n\n\n\n// ---------------------------------------------------------------- REFACTORIZACION ----------------------------------------------------------------\nclass AddBook {\n  constructor() {\n    this.books = new Map()\n  }\n\n  addBook(title, writer, numberCopies) {\n    if (this.books.has(title)) console.warn('El libro que desea agregar ya está en la biblioteca')\n    else {\n      this.books.set(title, {writer: writer, copies: numberCopies})\n      console.log('El libro se ha agregado al catálogo de la biblioteca')\n    }\n  }\n}\n\nclass AddUser {\n  constructor() {\n    this.users = new Map()\n  }\n\n  addUser(idUser, name, number) {\n    if (this.users.has(idUser)) console.warn('El usuario ya está registrado en la biblioteca')\n    else {\n      this.users.set(idUser, {name: name, number: number})\n      console.log('El usuario se ha registrado correctamente en la biblioteca')\n    }\n  }\n}\n\nclass Loans {\n  constructor() {\n    this.loans = []\n  }\n\n  loanBook(title, idUser) {\n    if (!inventory.books.has(title)) return console.warn('El libro que desea no está en esta biblioteca')\n    if (!clients.users.has(idUser)) return console.warn('El usuario no esta registrado en esta biblioteca')\n    const book = inventory.books.get(title) \n    if (book.copies > 0) {\n      this.loans.push([idUser, title])\n      book.copies--\n      console.log('Recuerda devolver el libro cuando lo termines, gracias!')\n    }\n    else {\n      console.warn('No quedan existencias del libro que desea\\nPregunte nuevamente en otro momento o elija otro')\n    }\n  }\n\n  returnBook(title, idUser) {\n    if (inventory.books.has(title) && clients.users.has(idUser)) {\n      let booksLoanedUser = this.loans.filter((loan) => loan[0] === idUser) // devuelde los libros retirados por el usuario\n      if (booksLoanedUser.length > 0 && booksLoanedUser.map((loan) => loan[1] === title)) { // verifica que haya libros retirado por el usuario y que coincida con el titulo ingresado\n        let index = this.loans.findIndex((loan) => {return loan[0] === idUser && loan[1] === title}) // devuelve el index del array donde esta el libro retirado y el id del usuario\n        this.loans.splice(index, 1)\n        const book = inventory.books.get(title) \n        book.copies++\n        console.log('Has devuelto el libro!! Gracias!!')\n      } else console.warn('Id o titulo del libro incorrectos')\n    }\n    else {\n      console.error('Datos incorrectos, vuelve a chequear que escribiste bien el nombre del libro o tu id')\n    }\n  }\n}\n\nconst inventory = new AddBook()\nconst clients = new AddUser()\nconst loans = new Loans()\n\n//Creación de libros\nconsole.log('----------------- CREACION DE LIBROS -----------------')\ninventory.addBook('Cien años de soledad', 'Gabriel García Márquez', 5); inventory.addBook('1984', 'George Orwell', 7); inventory.addBook('Orgullo y Prejuicio', 'Jane Austen', 3); inventory.addBook('El Principito', 'Antoine de Saint-Exupéry', 10); inventory.addBook('Don Quijote de la Mancha', 'Miguel de Cervantes', 2); inventory.addBook('Crimen y Castigo', 'Fiódor Dostoievski', 4); inventory.addBook('Moby Dick', 'Herman Melville', 6); inventory.addBook('Ensayo sobre la ceguera', 'José Saramago', 8)\n\n//Creación de usuarios\nconsole.log('\\n----------------- CREACION DE USUARIOS -----------------')\nclients.addUser(10001, 'Martina López', 987654321); clients.addUser(10002, 'Javier Ríos', 912345678); clients.addUser(10003, 'Sofía Giménez', 900112233); clients.addUser(10004, 'Andrés Castro', 945612378); clients.addUser(10005, 'Valeria Torres', 998877665); clients.addUser(10006, 'Ricardo Paz', 965432101); clients.addUser(10007, 'Elena Ruiz', 955544433); clients.addUser(10008, 'Felipe Díaz', 933322211); clients.addUser(10009, 'Carla Méndez', 977788899); clients.addUser(10010, 'Pablo Núñez', 921234567); clients.addUser(10011, 'Luisa Vargas', 987123456); clients.addUser(10012, 'Diego Soto', 911223344); clients.addUser(10013, 'Catalina Vega', 950505050); clients.addUser(10014, 'Hugo Ferrer', 930303030); clients.addUser(10015, 'Micaela Gil', 970707070)\n\n// Creación de prestamos\n  console.log('\\n----------------- CREACION DE PRESTAMOS -----------------')\n  // AGOTANDO EXISTENCIAS: 'Don Quijote de la Mancha' y 'Orgullo y Prejuicio'\n  loans.loanBook('Don Quijote de la Mancha', 10001); loans.loanBook('Don Quijote de la Mancha', 10002)\n  loans.loanBook('Orgullo y Prejuicio', 10003); loans.loanBook('Orgullo y Prejuicio', 10004); loans.loanBook('Orgullo y Prejuicio', 10005)\n\n  // PETICIONES EXITOSAS\n  loans.loanBook('1984', 10006); loans.loanBook('Cien años de soledad', 10007); loans.loanBook('Ensayo sobre la ceguera', 10008); loans.loanBook('Moby Dick', 10009); loans.loanBook('Crimen y Castigo', 10010)\n\n  // PETICIONES FALLIDAS\n    console.log('\\n----------------- CREACION DE PRESTAMOS ERRONEOS -----------------')\n    //Libros agotados\n    loans.loanBook('Don Quijote de la Mancha', 10011); loans.loanBook('Orgullo y Prejuicio', 10012)\n    //Libros inexistentes\n    loans.loanBook('El Código Da Vinci', 10013); loans.loanBook('Frieren', 10014)\n\n// Creación de devoluciones\n  // Devoluciones exitosas\n  console.log('\\n----------------- CREACION DE DEVOLUCIONES -----------------')\n  loans.returnBook('Don Quijote de la Mancha', 10001); loans.returnBook('Orgullo y Prejuicio', 10005); loans.returnBook('1984', 10006); loans.returnBook('Cien años de soledad', 10007); loans.returnBook('Moby Dick', 10009)\n\n  // Devolución con ID de usuario incorrecto (posiblemente fallida)\n  console.log('\\n----------------- CREACION DE DEVOLUCIONES ERRONEAS -----------------')\n  loans.returnBook('Crimen y Castigo', 32465)"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/javascript/victor-Casta.js",
    "content": "/*\n  * EJERCICIO:\n  * Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n  * Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n  * de forma correcta e incorrecta.\n*/\n\n// Correcto\nclass User {\n  constructor(name, age, email) {\n    this.name = name\n    this.age = age\n    this.email = email\n  }\n}\n\nclass SaveUser {\n  save(user) {\n    return\n  }\n}\n\nclass GetUsers {\n  getUsers() {\n    return\n  }\n}\n\n// Incorrecto\nclass User_2 {\n  constructor(name, age, email) {\n    this.name = name\n    this.age = age\n    this.email = email\n  }\n\n  save(user) {\n    return\n  }\n\n  getUsers() {\n    return\n  }\n}\n\n/*\n  * DIFICULTAD EXTRA (opcional):\n  * Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n  * manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n  * y el procesamiento de préstamos de libros.\n  * Requisitos:\n  * 1. Registrar libros: El sistema debe permitir agregar nuevos libros con\n  * información básica como título, autor y número de copias disponibles.\n  * 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n  * información básica como nombre, número de identificación y correo electrónico.\n  * 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n  * tomar prestados y devolver libros.\n  * Instrucciones:\n  * 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n  * los tres aspectos mencionados anteriormente (registro de libros, registro de\n  * usuarios y procesamiento de préstamos).\n  * 2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n  * siguiendo el Principio de Responsabilidad Única.\n*/\n\nclass Library {\n  constructor() {\n    this.books = []\n    this.users = []\n    this.loans = []\n  }\n\n  booksRegister(title, author, availableCopies) {\n    if (availableCopies > 0) {\n      this.books.push({ title, author, availableCopies })\n    } else {\n      console.log('Cantidad de copias debe ser mayor a 0')\n    }\n  }\n\n  usersRegister(name, id, email) {\n    this.users.push({ name, id, email })\n  }\n\n  booksLoan(state, quantity, bookTitle, userId) {\n    if (state === 'prestar') {\n      let bookFound = false\n\n      this.books.forEach(book => {\n        if (book.title === bookTitle) {\n          bookFound = true\n          if (quantity > 0 && book.availableCopies >= quantity) {\n            console.log('Libro prestado')\n            book.availableCopies -= quantity\n            this.loans.push({ bookTitle, userId, quantity })\n          } else {\n            console.log('No hay suficientes copias disponibles para prestar')\n          }\n        }\n      })\n\n      if (!bookFound) {\n        console.log('Libro no encontrado')\n      }\n\n    } else if (state === 'devolver') {\n      let loanFound = false\n\n      this.loans = this.loans.filter(item => {\n        if (item.bookTitle === bookTitle && item.userId === userId) {\n          loanFound = true\n          this.books.forEach(book => {\n            if (book.title === bookTitle) {\n              console.log('Libro devuelto')\n              book.availableCopies += item.quantity\n            }\n          })\n          return false\n        }\n        return true\n      })\n\n      if (!loanFound) {\n        console.log('No se encontró un préstamo correspondiente para devolver')\n      }\n\n    } else {\n      console.log('Opción no válida')\n    }\n  }\n}\n\nconst library = new Library()\nlibrary.booksRegister('Harry Potter', 'J.K. Rowling', 12)\nlibrary.booksRegister('Harry Potter 2', 'J.K. Rowling', 7)\nlibrary.booksRegister('Harry Potter 3', 'J.K. Rowling', 6)\nlibrary.usersRegister('Victor', 123, 'victor@gmail.com')\nlibrary.usersRegister('Juan', 124, 'juan@gmail.com')\nlibrary.booksLoan('prestar', 2, 'Harry Potter', 123)\nlibrary.booksLoan('prestar', 1, 'Harry Potter', 124)\nlibrary.booksLoan('devolver', 2, 'Harry Potter', 123)\nconsole.log(library)\n\n// Refactor SRP\n\nclass LibraryContent {\n  constructor(books = [], users = [], loans = []) {\n    this.books = books\n    this.users = users\n    this.loans = loans\n  }\n}\n\nclass BooksRegister {\n  constructor() {\n    this.books = []\n  }\n\n  booksRegister(title, author, availableCopies) {\n    if (availableCopies > 0) {\n      this.books.push({ title, author, availableCopies })\n    } else {\n      console.log('Cantidad de copias debe ser mayor a 0')\n    }\n  }\n}\n\nclass UsersRegister {\n  constructor() {\n    this.users = []\n  }\n\n  usersRegister(name, id, email) {\n    this.users.push({ name, id, email })\n  }\n}\n\nclass BooksLoans {\n  constructor(library) {\n    this.library = library\n  }\n\n  booksLoan(state, quantity, bookTitle, userId) {\n    if (state === 'prestar') {\n      const book = this.library.books.find(book => book.title === bookTitle)\n      const user = this.library.users.find(user => user.id === userId)\n\n      if (book && user) {\n        if (quantity > 0 && book.availableCopies >= quantity) {\n          console.log('Libro prestado')\n          book.availableCopies -= quantity\n          this.library.loans.push({ bookTitle, userId, quantity })\n        } else {\n          console.log('No hay suficientes copias disponibles para prestar')\n        }\n      } else {\n        console.log(book ? 'Usuario no encontrado' : 'Libro no encontrado')\n      }\n\n    } else if (state === 'devolver') {\n      const loanIndex = this.library.loans.findIndex(\n        loan => loan.bookTitle === bookTitle && loan.userId === userId\n      )\n\n      if (loanIndex !== -1) {\n        const loan = this.library.loans[loanIndex]\n        const book = this.library.books.find(book => book.title === bookTitle)\n\n        if (book) {\n          console.log('Libro devuelto')\n          book.availableCopies += loan.quantity\n          this.library.loans.splice(loanIndex, 1)\n        }\n      } else {\n        console.log('No se encontró un préstamo correspondiente para devolver')\n      }\n\n    } else {\n      console.log('Opción no válida')\n    }\n  }\n}\n\n\nlet bookRegister = new BooksRegister()\nbookRegister.booksRegister('Harry Potter', 'J.K. Rowling', 12)\nbookRegister.booksRegister('Harry Potter 2', 'J.K. Rowling', 22)\nbookRegister.booksRegister('Harry Potter 3', 'J.K. Rowling', 2)\n\nlet userRegister = new UsersRegister()\nuserRegister.usersRegister('Victor', 1231, 'victor@gmail.com')\nuserRegister.usersRegister('Juan', 1232, 'juan@gmail.com')\nuserRegister.usersRegister('John', 1233, 'john@gmail.com')\nuserRegister.usersRegister('Alfred', 1234, 'alfred@gmail.com')\n\n\nlet myLibrary = new LibraryContent(bookRegister.books, userRegister.users)\n\n\nlet loansSystem = new BooksLoans(myLibrary)\nloansSystem.booksLoan('prestar', 2, 'Harry Potter', 1231)\nloansSystem.booksLoan('prestar', 1, 'Harry Potter', 1232)\nloansSystem.booksLoan('devolver', 2, 'Harry Potter', 1231)\n\nconsole.log(myLibrary.books)\nconsole.log(myLibrary.users)\nconsole.log(myLibrary.loans)"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/kotlin/blackriper.kt",
    "content": "import io.github.oshai.kotlinlogging.KotlinLogging\r\nimport java.lang.System.exit\r\nimport java.util.UUID\r\n\r\n/*\r\nSingle Responsibility Principle\r\nestablece que cada módulo o clase debe tener responsabilidad sobre una sola parte de la funcionalidad proporcionada por el software\r\ny esta responsabilidad debe estar encapsulada en su totalidad por la clase. Todos sus servicios deben estar estrechamente alineados\r\ncon esa responsabilidad. Este principio está incluido en el acrónimo mnemotécnico SOLID. Robert C. Martin expresa el principio de la siguiente forma:\r\n\r\n\r\nUna clase debe tener solo una razón para cambiar.\r\n\r\n*/\r\n\r\n// lo que no debe de hacerce\r\nclass AutoWash(var nameCar:String, private var registrationNumber: String) {\r\n    private val costWashing=135.34\r\n\r\n    fun startWashing(){\r\n        println(\"Car ${nameCar} with registration number ${registrationNumber} was washed\")\r\n    }\r\n\r\n    fun recivedPaymented(moneyRecived:Double) {\r\n        println(\"the total cost of washing car ${nameCar} with registration number ${registrationNumber} was ${costWashing + moneyRecived}\")\r\n    }\r\n}\r\n\r\n// lo que debe de hacerce\r\n\r\n// separamos las funcionalidades en  varias clases\r\ndata class Car(var nameCar:String,var registrationNumber:String){\r\n    fun startWashing(){\r\n        println(\"Car ${nameCar} with registration number ${registrationNumber} was washed\")\r\n    }\r\n}\r\n\r\n\r\nclass Payment{\r\n    private val costWashing=135.34\r\n    fun recivedPaymented(car : Car,moneyRecived:Double) {\r\n        val(nameCar,registrationNumber)=car\r\n        println(\"the total cost of washing car ${nameCar} with registration number ${registrationNumber} was ${costWashing + moneyRecived}\")\r\n    }\r\n}\r\n\r\n// podemos usar una clase manager\r\nclass AutoWashSRP{\r\n   private lateinit var car:Car\r\n   private val payment=Payment()\r\n\r\n\r\n    fun reciveCar(nameCar:String ,registrationNumber:String){\r\n        car=Car(nameCar,registrationNumber)\r\n        car.startWashing()\r\n    }\r\n\r\n    fun recivedPaymented(moneyRecived:Double){\r\n        payment.recivedPaymented(car, moneyRecived)\r\n    }\r\n}\r\n\r\nfun exampleSRP(){\r\n    //antes\r\n    val autoWash1=AutoWash(\"Nissan\",\"ABC123\")\r\n    autoWash1.startWashing()\r\n    autoWash1.recivedPaymented(155.34)\r\n    // despues\r\n    val autoWash=AutoWashSRP()\r\n    autoWash.reciveCar(\"Ferrari\",\"ABC1456\")\r\n    autoWash.recivedPaymented(455.34)\r\n}\r\n\r\n//ejercicio extra\r\n\r\n//1.- defnir identidades\r\ndata class Book(\r\n    val title: String,\r\n    val author: String,\r\n    var numCopies: Int\r\n)\r\n\r\ndata class UserLib(\r\n    val idUserLib: String,\r\n    val name: String,\r\n    val email: String\r\n)\r\n\r\ndata class Loan(\r\n    val idLoan:String,\r\n    val nameUser:String,\r\n    val nameBook:String\r\n)\r\n\r\nval logging= KotlinLogging.logger {  }\r\n\r\n\r\n//2.-Crear clase monolito\r\nclass Library{\r\n    private val books= mutableListOf<Book>()\r\n    private val users= mutableListOf<UserLib>()\r\n    private val loans= mutableListOf<Loan>()\r\n\r\n   fun showMenu(){\r\n      var option:Int=0\r\n     while (option!=5) {\r\n         println(\"1. Add book\")\r\n         println(\"2. Add user\")\r\n         println(\"3. Create loan\")\r\n         println(\"4. Return loan\")\r\n         println(\"5. Exit\")\r\n         println(\"Choose an option:\")\r\n          option = readLine()!!.toInt()\r\n         when (option) {\r\n             1 -> registerBook()\r\n             2 -> registerUser()\r\n             3 -> createLoan()\r\n             4 -> returnLoan()\r\n             else -> println(\"exit\")\r\n         }\r\n     }\r\n    }\r\n\r\n   private fun registerBook(){\r\n        println(\"title of the book:\")\r\n        val title= readLine()!!.toString()\r\n        println(\"author of the book:\")\r\n        val author= readLine()!!.toString()\r\n        println(\"number of copies:\")\r\n        val numCopies= readLine()!!.toInt()\r\n        val book=Book(title,author,numCopies)\r\n        books.add(book)\r\n        logging.info {  \"The book ${book.title} was added successfully\"}\r\n    }\r\n\r\n    private fun registerUser(){\r\n        println(\"name of the user:\")\r\n        val name= readLine()!!.toString()\r\n        println(\"email of the user:\")\r\n        val email= readLine()!!.toString()\r\n        val id=UUID.randomUUID().toString().substring(0, 8)\r\n        val user=UserLib(id,name,email)\r\n        users.add(user)\r\n        logging.info {  \"The user ${user.name} was added successfully\"}\r\n    }\r\n\r\n   private  fun createLoan(){\r\n        println(\"name of the user:\")\r\n        val nameUser= readLine()!!.toString()\r\n        val existUser=users.find { it.name==nameUser }\r\n\r\n        if(existUser==null){\r\n          logging.warn { \"user ${nameUser} not found\" }\r\n           println(\"user not found, please register first\")\r\n           return\r\n        }\r\n        var idx=1\r\n        books.forEach {\r\n            println(\"${idx}-${it.title}\")\r\n            idx++\r\n        }\r\n\r\n        println(\"choose de book to loan:\")\r\n        val bookIndice= readLine()!!.toInt()\r\n        val book=books[bookIndice-1]\r\n       if (book.numCopies>0) {\r\n           val id = UUID.randomUUID().toString().substring(0, 8)\r\n           val loan = Loan(id, nameUser, book.title)\r\n           book.numCopies -= 1\r\n           loans.add(loan)\r\n           logging.info { \"The loan ${loan.nameUser} was added successfully\" }\r\n       }else{\r\n           logging.warn { \"The book ${book.title} is not available\" }\r\n           println(\"The book ${book.title} is not available\")\r\n           return\r\n       }\r\n    }\r\n\r\n   private  fun returnLoan() {\r\n        println(\"name of the user:\")\r\n        val userName= readLine()!!.toString()\r\n        val loan=loans.find { it.nameUser==userName }\r\n        println(\"The book ${loan?.nameBook} was returned\")\r\n        logging.info { \"The book ${loan?.nameBook} was returned\" }\r\n        val book=books.find { it.title==loan?.nameBook }\r\n        book?.numCopies?.let { it + 1 }\r\n        loan?.let { loans.remove(it) }\r\n\r\n    }\r\n\r\n}\r\n\r\n// refactorizando codigo\r\n\r\n//1.- vamos a definir el comportamiento que van a tener nuestras clases de acuerdo a su funcionalidad\r\n\r\nenum class CopiesStatus{\r\n    MINUS,PLUS\r\n}\r\n\r\n\r\ninterface ForBooks{\r\n    fun registerBook()\r\n    fun selectedBooks():Book\r\n    fun findBook(title: String):Book?\r\n    fun updateCopies(title: String,op: CopiesStatus)\r\n}\r\n\r\ninterface ForUsers{\r\n  fun registerUser()\r\n  fun findUser(name: String):UserLib?\r\n}\r\n\r\ninterface ForLoans{\r\n    fun createLoan(nameUser:String,title:String):Boolean\r\n    fun getAllLoans():List<Loan>\r\n    fun deleteLoan(repo:ForBooks)\r\n}\r\n\r\n\r\n\r\n//1.1.- Definir fake data pero esto es opcional y funcion auxiliar para ids\r\n\r\nval generateIds={UUID.randomUUID().toString().substring(0, 8)}\r\n\r\n\r\nvar mockBooks= mutableListOf(\r\n    Book(\"El principito\",\"Antoine de Saint-Exupery\",10),\r\n    Book(\"El señor de los anillos\",\"JRR Tolkien\",5),\r\n    Book(\"El Código da Vinci\",\"Dan Brown\",3),\r\n    Book(\"Don Quijote de la Mancha\",\"Miguel de Cervantes\",2),\r\n    Book(\"Harry Potter \",\"J.K. Rowling\",1),\r\n    Book(\"El resplandor\",\"Stephen King\",3),\r\n    Book(\"El Alquimista\",\"Paulo Coelho\",4),\r\n)\r\n\r\nvar mockUsers= mutableListOf(\r\n    UserLib(generateIds(),\"blackriper\",\"XHqKm@example.com\"),\r\n    UserLib(generateIds(),\"hdeleon\",\"XHqKm@net.com\"),\r\n  )\r\n\r\n//2.- Crear nuevas clases\r\n\r\nclass BookRepository:ForBooks{\r\n    override fun registerBook() {\r\n        println(\"title of the book:\")\r\n        val title= readLine()!!.toString()\r\n        println(\"author of the book:\")\r\n        val author= readLine()!!.toString()\r\n        println(\"number of copies:\")\r\n        val numCopies= readLine()!!.toInt()\r\n        val book=Book(title,author,numCopies)\r\n        mockBooks.add(book)\r\n        logging.info {  \"The book ${book.title} was added successfully\"}\r\n    }\r\n\r\n    override fun selectedBooks():Book {\r\n        var idx=1\r\n        mockBooks.forEach {\r\n            println(\"${idx}-${it.title}\")\r\n            idx++\r\n        }\r\n\r\n        println(\"choose de book to loan:\")\r\n        val bookIndice= readLine()!!.toInt()\r\n        val book= mockBooks[bookIndice-1]\r\n        logging.trace { \"The book ${book.title} selected successfully\"}\r\n        return book\r\n    }\r\n\r\n    override fun findBook(title: String): Book? {\r\n        val book= mockBooks.find { it.title==title }\r\n        logging.info { \"The book ${book?.title} was found successfully\" }\r\n        return book\r\n\r\n    }\r\n\r\n    override fun updateCopies(title: String, op: CopiesStatus) {\r\n       val bookFind=findBook(title)?:return\r\n         when(op){\r\n            CopiesStatus.PLUS ->{\r\n                bookFind.numCopies+=1\r\n                logging.info { \"The book ${bookFind.title} has ${bookFind.numCopies}\" }\r\n            }\r\n            CopiesStatus.MINUS -> {\r\n                bookFind.numCopies-=1\r\n                logging.info { \"The book ${bookFind.title} has ${bookFind.numCopies}\" }\r\n            }\r\n        }\r\n    }\r\n\r\n}\r\n\r\nclass RepositoryUser:ForUsers{\r\n     override fun registerUser() {\r\n        println(\"name of the user:\")\r\n        val name= readLine()!!.toString()\r\n        println(\"email of the user:\")\r\n        val email= readLine()!!.toString()\r\n        val user=UserLib(generateIds(),name,email)\r\n        mockUsers.add(user)\r\n        logging.info {  \"The user ${user.name} was added successfully\"}\r\n    }\r\n\r\n    override fun findUser(name: String): UserLib? {\r\n        val user= mockUsers.find { it.name==name }\r\n        logging.info { \"The user ${user?.name} was found successfully\" }\r\n        return user\r\n    }\r\n\r\n}\r\n\r\n\r\nclass RepositoryLoans:ForLoans{\r\n    private val loans= mutableListOf<Loan>()\r\n\r\n    override fun createLoan(nameUser: String, title: String):Boolean {\r\n        val loan = Loan(generateIds(), nameUser, title)\r\n        loans.add(loan)\r\n        logging.info { \"The loan ${loan.nameUser} was added successfully\" }\r\n        return true\r\n    }\r\n\r\n    override fun getAllLoans(): List<Loan> = loans\r\n\r\n    override fun deleteLoan(repo:ForBooks) {\r\n        println(\"name of the user:\")\r\n        val userName= readLine()!!.toString()\r\n        loans.find { it.nameUser==userName }.let {\r\n            println(\"The book ${it?.nameBook} was returned\")\r\n            logging.info { \"The book ${it?.nameBook} was returned\" }\r\n            repo.updateCopies(it?.nameBook!!, CopiesStatus.PLUS)\r\n            loans.remove(it)\r\n        }\r\n    }\r\n\r\n}\r\n\r\n class LibrarySRP {\r\n     // hacemos la instancia de cada clase\r\n     private val bookRepo = BookRepository()\r\n     private val userRepo = RepositoryUser()\r\n     private val loanRepo = RepositoryLoans()\r\n\r\n     fun showMenu() {\r\n         var option: Int = 0\r\n         while (option != 6) {\r\n             println(\"1. Add book\")\r\n             println(\"2. Add user\")\r\n             println(\"3. Create loan\")\r\n             println(\"4. Return loan\")\r\n             println(\"5.-List loans\")\r\n             println(\"6. Exit\")\r\n             println(\"Choose an option:\")\r\n             option = readLine()!!.toInt()\r\n             when (option) {\r\n                 1 -> bookRepo.registerBook()\r\n                 2 -> userRepo.registerUser()\r\n                 3 -> createLoan()\r\n                 4 -> loanRepo.deleteLoan(bookRepo)\r\n                 5 -> showLoans()\r\n                 else -> println(\"exit\")\r\n             }\r\n         }\r\n     }\r\n\r\n     private fun createLoan() {\r\n         println(\"name of the user:\")\r\n         val nameUser = readLine()!!.toString()\r\n         val existUser = userRepo.findUser(nameUser)\r\n         if (existUser == null) {\r\n             logging.error { \"The user ${nameUser} not found\" }\r\n             return\r\n         }\r\n         val book = bookRepo.selectedBooks()\r\n         if (book.numCopies > 0) {\r\n             loanRepo.createLoan(existUser.name, book.title).run {\r\n                 if (this) bookRepo.updateCopies(book.title, CopiesStatus.MINUS)\r\n             }\r\n         } else {\r\n             logging.warn { \"The book ${book.title} is not available\" }\r\n             println(\"The book ${book.title} is not available\")\r\n             return\r\n         }\r\n     }\r\n\r\n     private fun showLoans() {\r\n         loanRepo.getAllLoans().forEach {\r\n             println(\"id: ${it.idLoan} - User: ${it.nameUser} - Book: ${it.nameBook}\")\r\n         }\r\n     }\r\n }\r\n\r\nfun main() {\r\n   exampleSRP()\r\n  // val library=Library()\r\n   //library.showMenu()\r\n    val library=LibrarySRP()\r\n    library.showMenu()\r\n}\r\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/kotlin/eulogioep.kt",
    "content": "/*\n * Principio de Responsabilidad Única (SRP)\n * \n * El Principio de Responsabilidad Única es el primer principio de SOLID y establece que una clase\n * debe tener una, y solo una, razón para cambiar. En otras palabras, una clase debe tener una\n * única responsabilidad bien definida.\n *\n * Este principio promueve la modularidad, facilita el mantenimiento y mejora la legibilidad del código.\n * Cuando una clase tiene múltiples responsabilidades, se vuelve más difícil de entender, modificar y probar.\n */\n\n// Definiciones de datos comunes\ndata class Book(val title: String, val author: String, var availableCopies: Int)\ndata class User(val name: String, val id: String, val email: String)\ndata class Loan(val user: User, val book: Book)\n\n// Versión que no cumple con SRP\nclass LibraryWithoutSRP {\n    private val books = mutableListOf<Book>()\n    private val users = mutableListOf<User>()\n    private val loans = mutableListOf<Loan>()\n\n    fun addBook(title: String, author: String, copies: Int) {\n        books.add(Book(title, author, copies))\n    }\n\n    fun registerUser(name: String, id: String, email: String) {\n        users.add(User(name, id, email))\n    }\n\n    fun loanBook(userId: String, bookTitle: String) {\n        val user = users.find { it.id == userId }\n        val book = books.find { it.title == bookTitle }\n        if (user != null && book != null && book.availableCopies > 0) {\n            loans.add(Loan(user, book))\n            book.availableCopies--\n        }\n    }\n\n    fun returnBook(userId: String, bookTitle: String) {\n        val loan = loans.find { it.user.id == userId && it.book.title == bookTitle }\n        if (loan != null) {\n            loans.remove(loan)\n            loan.book.availableCopies++\n        }\n    }\n}\n\n// Versión refactorizada que cumple con SRP\nclass BookManager {\n    private val books = mutableListOf<Book>()\n\n    fun addBook(title: String, author: String, copies: Int) {\n        books.add(Book(title, author, copies))\n    }\n\n    fun findBook(title: String): Book? = books.find { it.title == title }\n}\n\nclass UserManager {\n    private val users = mutableListOf<User>()\n\n    fun registerUser(name: String, id: String, email: String) {\n        users.add(User(name, id, email))\n    }\n\n    fun findUser(id: String): User? = users.find { it.id == id }\n}\n\nclass LoanManager {\n    private val loans = mutableListOf<Loan>()\n\n    fun loanBook(user: User, book: Book) {\n        if (book.availableCopies > 0) {\n            loans.add(Loan(user, book))\n            book.availableCopies--\n        }\n    }\n\n    fun returnBook(user: User, book: Book) {\n        val loan = loans.find { it.user == user && it.book == book }\n        if (loan != null) {\n            loans.remove(loan)\n            book.availableCopies++\n        }\n    }\n}\n\nclass Library(\n    private val bookManager: BookManager,\n    private val userManager: UserManager,\n    private val loanManager: LoanManager\n) {\n    fun addBook(title: String, author: String, copies: Int) {\n        bookManager.addBook(title, author, copies)\n    }\n\n    fun registerUser(name: String, id: String, email: String) {\n        userManager.registerUser(name, id, email)\n    }\n\n    fun loanBook(userId: String, bookTitle: String) {\n        val user = userManager.findUser(userId)\n        val book = bookManager.findBook(bookTitle)\n        if (user != null && book != null) {\n            loanManager.loanBook(user, book)\n        }\n    }\n\n    fun returnBook(userId: String, bookTitle: String) {\n        val user = userManager.findUser(userId)\n        val book = bookManager.findBook(bookTitle)\n        if (user != null && book != null) {\n            loanManager.returnBook(user, book)\n        }\n    }\n}\n\n// Uso del sistema refactorizado\nfun main() {\n    val bookManager = BookManager()\n    val userManager = UserManager()\n    val loanManager = LoanManager()\n    val library = Library(bookManager, userManager, loanManager)\n\n    library.addBook(\"1984\", \"George Orwell\", 5)\n    library.registerUser(\"EulogioEP\", \"001\", \"eulogioep@email.com\")\n    library.loanBook(\"001\", \"1984\")\n    library.returnBook(\"001\", \"1984\")\n}"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/ocaml/luishendrix92.ml",
    "content": "open Printf\n\nlet ( let* ) = Result.bind\n\n(******************************************************************************)\n(*                                                                            *)\n(*                      Single Responsibility Principle                       *)\n(*                                                                            *)\n(*  The 'S' in {b SOLID}, says that classes and functions should only do one  *)\n(*  thing and they should do it very well; meaning, have a single responsi-   *)\n(*  bility. It discourages mixing concerns in a class or function and         *)\n(*  encourages the developer to separate these concerns into classes that     *)\n(*  only {e have one reason to change}, as Bob Martin said in his book,       *)\n(*  Clean Code, which is the originator of the SOLID principles.              *)\n(*                                                                            *)\n(******************************************************************************)\n\nmodule ViolatesSRP = struct\n  let responsibility_1 () = print_endline \"I do one thing\"\n  let responsibility_2 () = print_endline \"I do another thing\"\n  let responsibility_3 () = print_endline \"And yet another thing...\"\n\n  let use_all_three () =\n    responsibility_1 ();\n    responsibility_2 ();\n    responsibility_3 ()\n  ;;\nend\n\n(* The module above is in violation of the SRP, it defines three different\n   functions that should exist on their own, otherwise whenever we wanted\n   to change any of them, we'd have to modify the same module, potentially\n   introducing bugs and making them exclusive to the host module.\n\n   The solution is to create a module for each responsibility so that if\n   such code has to change, I know exactly where to go. *)\n\nmodule ResponsibilityOne = struct\n  let one_thing () = print_endline \"I do one thing\"\nend\n\nmodule ResponsibilityTwo = struct\n  let another_thing () = print_endline \"I do another thing\"\nend\n\nmodule ResponsibilityThree = struct\n  let yet_another () = print_endline \"And yet another thing...\"\nend\n\nmodule SRPCompliant = struct\n  let use_all_three () =\n    ResponsibilityOne.one_thing ();\n    ResponsibilityTwo.another_thing ();\n    ResponsibilityThree.yet_another ()\n  ;;\nend\n\n(*****************************************************************************)\n(*                                                                           *)\n(* DIFICULTAD EXTRA (opcional):                                              *)\n(*                                                                           *)\n(* Desarrolla un sistema de gestión para una biblioteca. El sistema necesita *)\n(* manejar diferentes aspectos como el registro de libros, la gestión de     *)\n(* usuarios y el procesamiento de préstamos de libros.                       *)\n(*                                                                           *)\n(* Requisitos:                                                               *)\n(* 1. Registrar libros: El sistema debe permitir agregar nuevos libros con   *)\n(*    información básica como título, autor y número de copias disponibles. *)\n(* 2. Registrar usuarios: Debe permitir agregar nuevos usuarios con info *)\n(*    básica como nombre, número de identificación y correo electrónico. *)\n(* 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios  *)\n(*    tomar prestados y devolver libros.                                     *)\n(*                                                                           *)\n(* Instrucciones:                                                            *)\n(* 1. Diseña una clase que no cumple: Crea una clase Library que maneje      *)\n(*    los tres aspectos mencionados anteriormente (registro de libros,       *)\n(*    usuarios y procesamiento de préstamos).                                *)\n(* 2. Refactoriza el código: Separa las responsabilidades en diferentes      *)\n(*    clases siguiendo el Principio de Responsabilidad Única.                *)\n(*                                                                           *)\n(*****************************************************************************)\n\nmodule Library = struct\n  type book =\n    { title : string\n    ; author : string\n    ; mutable stock : int\n    }\n\n  type user =\n    { id : int\n    ; name : string\n    ; email : string\n    }\n\n  module LendingSet = Set.Make (struct\n      type t = int * string\n\n      let compare = Stdlib.compare\n    end)\n\n  let books : book list ref =\n    ref\n      [ { title = \"Dune\"; author = \"Frank Herbert\"; stock = 5 }\n      ; { title = \"Lord of the Rings\"; author = \"J.R.R Tolkien\"; stock = 2 }\n      ; { title = \"Eye of the world\"; author = \"Robert Jordan\"; stock = 3 }\n      ; { title = \"It\"; author = \"Stephen King\"; stock = 8 }\n      ; { title = \"Develop a second brain\"; author = \"Thiago Forte\"; stock = 6 }\n      ]\n  ;;\n\n  let users : user list ref =\n    ref [ { id = 1; name = \"Luis Lopez\"; email = \"luishendrix92@gmail.com\" } ]\n  ;;\n\n  let lendings : LendingSet.t ref = ref LendingSet.empty\n  let register_user user = users := user :: !users\n  let add_book book = books := book :: !books\n\n  let lend_book user_id book_title =\n    let book =\n      match List.find_opt (fun book -> book.title = book_title) !books with\n      | None -> failwith (sprintf \"Book [%s] not found\" book_title)\n      | Some book -> book\n    in\n    if book.stock > 0\n    then begin\n      lendings := LendingSet.add (user_id, book_title) !lendings;\n      book.stock <- book.stock - 1\n    end\n    else failwith (sprintf \"Not enough stock for [%s]\" book_title)\n  ;;\n\n  let return_book user_id book_title =\n    let should_return = LendingSet.mem (user_id, book_title) !lendings in\n    if should_return\n    then begin\n      let book =\n        match List.find_opt (fun book -> book.title = book_title) !books with\n        | None -> failwith (sprintf \"Book [%s] not found\" book_title)\n        | Some book -> book\n      in\n      lendings := LendingSet.remove (user_id, book_title) !lendings;\n      book.stock <- book.stock + 1\n    end\n    else\n      failwith\n        (sprintf \"User #%d doesn't need to return [%s]\" user_id book_title)\n  ;;\nend\n\n(* Refactoring Opportunity\n   -----------------------\n   I can apply SRP to separate the monolith of code into modules that do one\n   thing only, and very well. For this particular case I can implement an\n   entity data module for books, lendings, and users; then create a repository\n   functor to have a static storage (Hashtbl) interfaced through convenient\n   functions for retrieving, deleting, and adding these entities. *)\n\nmodule type Entity = sig\n  type id\n  type t\n\n  val get_id : t -> id\nend\n\nmodule Repository (E : Entity) = struct\n  let data : (E.id, E.t) Hashtbl.t = Hashtbl.create 100\n  let save elt = Hashtbl.replace data (E.get_id elt) elt\n\n  let add elt =\n    if Hashtbl.mem data (E.get_id elt)\n    then Error \"Unable to add entity, already exists.\"\n    else (\n      save elt;\n      Ok ())\n  ;;\n\n  let delete_by_id elt_id =\n    if Hashtbl.mem data elt_id\n    then Ok (Hashtbl.remove data elt_id)\n    else Error \"Can't delete, id doesn't exit.\"\n  ;;\n\n  let get_by_id elt_id =\n    match Hashtbl.find_opt data elt_id with\n    | Some elt -> Ok elt\n    | None -> Error \"Entity not found with the provided id.\"\n  ;;\nend\n\nmodule User = struct\n  type id = int\n\n  type t =\n    { id : int\n    ; name : string\n    ; email : string\n    }\n\n  let get_id user = user.id\nend\n\nmodule Book = struct\n  type id = string\n\n  type t =\n    { title : string\n    ; author : string\n    ; mutable stock : int\n    }\n\n  let get_id book = book.title\nend\n\nmodule Lending = struct\n  type id = User.id * Book.id\n\n  type t =\n    { user_id : User.id\n    ; book_id : Book.id\n    ; return_date : string\n    }\n\n  let get_id lending = lending.user_id, lending.book_id\nend\n\nmodule SRPCompliantLibrary = struct\n  (* Ideally, we should be able to use dependency injection here and while\n     technically we can by using functors, the syntax isn't very intuitive\n     and extension-friendly so I'll stick with this code for now. *)\n  module Users = Repository (User)\n  module Books = Repository (Book)\n  module Lendings = Repository (Lending)\n\n  let borrow user_id book_id =\n    (* Given I'm not using a proper ORM or writing relationship-aware database\n       code, I need to make sure both entities (user and book) exist before\n       adding the lending entity, otherwise I'd be violating what in the DB\n       world is called a \"foreign key\" constraint. *)\n    let* _user = Users.get_by_id user_id in\n    let* book = Books.get_by_id book_id in\n    let return_date =\n      Core.Date.(\n        add_days (today ~zone:Core.Time_float.Zone.utc) 7 |> to_string_american)\n    in\n    if book.stock > 0\n    then begin\n      book.stock <- book.stock - 1;\n      Lendings.add { user_id; book_id; return_date }\n    end\n    else Error \"Can't lend book, not enough stock\"\n  ;;\n\n  let return user_id book_id =\n    let* _user = Users.get_by_id user_id in\n    let* book = Books.get_by_id book_id in\n    let* _ = Lendings.delete_by_id (user_id, book_id) in\n    Ok (book.stock <- book.stock + 1)\n  ;;\nend\n\nlet _ =\n  let open SRPCompliantLibrary in\n  let inventory : Book.t list =\n    [ { title = \"Blood Meridian\"; author = \"John McCarthy\"; stock = 5 }\n    ; { title = \"The Outsider\"; author = \"Stephen King\"; stock = 2 }\n    ; { title = \"The Philosopher's Stone\"; author = \"J.K Rowling\"; stock = 0 }\n    ]\n  in\n  List.iter (fun book -> Books.add book |> Result.get_ok) inventory;\n  Users.add { id = 1; name = \"Luis Lopez\"; email = \"luishendrix92@gmail.com\" }\n  |> Result.get_ok;\n  let res =\n    let user_id = 1 in\n    let book_title = \"The Outsider\" in\n    let* _ = borrow user_id book_title in\n    printf \"User #%d successfully borrowed '%s'\\n\" user_id book_title;\n    let* _ = return user_id book_title in\n    printf \"User #%d successfully returned '%s'\\n\" user_id book_title;\n    Ok ()\n  in\n  match res with\n  | Ok _ ->\n    print_endline \"Let's try borrowing a book with no stock!\";\n    borrow 1 \"The Philosopher's Stone\" |> Result.get_error |> print_endline\n  | Error err -> print_endline err\n;;\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/php/eulogioep.php",
    "content": "<?php\n/**\n * PRINCIPIO DE RESPONSABILIDAD ÚNICA (SRP)\n * \n * El Principio de Responsabilidad Única establece que:\n * \"Una clase debe tener una única razón para cambiar\"\n * \n * Este principio nos ayuda a:\n * - Crear código más mantenible\n * - Facilitar las pruebas unitarias\n * - Reducir el acoplamiento\n * - Mejorar la cohesión del código\n * - Facilitar la reutilización\n */\n\n// ========== IMPLEMENTACIÓN INCORRECTA (Violando SRP) ==========\n\n/**\n * Esta implementación viola el SRP porque la clase Library maneja múltiples responsabilidades:\n * 1. Gestión de libros\n * 2. Gestión de usuarios\n * 3. Gestión de préstamos\n */\nclass Library {\n    private array $books = [];\n    private array $users = [];\n    private array $loans = [];\n\n    // Gestión de libros\n    public function addBook(string $title, string $author, int $copies): void {\n        $book = new Book($title, $author, $copies);\n        $this->books[] = $book;\n    }\n\n    public function removeBook(string $bookId): void {\n        $this->books = array_filter(\n            $this->books,\n            fn($book) => $book->getId() !== $bookId\n        );\n    }\n\n    // Gestión de usuarios\n    public function registerUser(string $name, string $id, string $email): void {\n        $user = new User($name, $id, $email);\n        $this->users[] = $user;\n    }\n\n    public function removeUser(string $userId): void {\n        $this->users = array_filter(\n            $this->users,\n            fn($user) => $user->getId() !== $userId\n        );\n    }\n\n    // Gestión de préstamos\n    public function loanBook(string $userId, string $bookId): void {\n        $book = $this->findBook($bookId);\n        $user = $this->findUser($userId);\n\n        if (!$book || !$user) {\n            throw new Exception(\"Libro o usuario no encontrado\");\n        }\n\n        if ($book->getAvailableCopies() <= 0) {\n            throw new Exception(\"No hay copias disponibles\");\n        }\n\n        $book->decrementCopies();\n        $this->loans[] = new Loan($userId, $bookId, new DateTime());\n    }\n\n    public function returnBook(string $userId, string $bookId): void {\n        $loan = $this->findLoan($userId, $bookId);\n        if (!$loan) {\n            throw new Exception(\"Préstamo no encontrado\");\n        }\n\n        $book = $this->findBook($bookId);\n        if ($book) {\n            $book->incrementCopies();\n        }\n\n        $this->removeLoan($userId, $bookId);\n    }\n\n    private function findBook(string $bookId): ?Book {\n        foreach ($this->books as $book) {\n            if ($book->getId() === $bookId) {\n                return $book;\n            }\n        }\n        return null;\n    }\n\n    private function findUser(string $userId): ?User {\n        foreach ($this->users as $user) {\n            if ($user->getId() === $userId) {\n                return $user;\n            }\n        }\n        return null;\n    }\n\n    private function findLoan(string $userId, string $bookId): ?Loan {\n        foreach ($this->loans as $loan) {\n            if ($loan->getUserId() === $userId && $loan->getBookId() === $bookId) {\n                return $loan;\n            }\n        }\n        return null;\n    }\n\n    private function removeLoan(string $userId, string $bookId): void {\n        $this->loans = array_filter(\n            $this->loans,\n            fn($loan) => !($loan->getUserId() === $userId && $loan->getBookId() === $bookId)\n        );\n    }\n}\n\n// ========== IMPLEMENTACIÓN CORRECTA (Siguiendo SRP) ==========\n\n/**\n * BookManager: Responsable únicamente de la gestión de libros\n */\nclass BookManager {\n    private array $books = [];\n\n    public function addBook(string $title, string $author, int $copies): void {\n        $book = new Book($title, $author, $copies);\n        $this->books[] = $book;\n    }\n\n    public function removeBook(string $bookId): void {\n        $this->books = array_filter(\n            $this->books,\n            fn($book) => $book->getId() !== $bookId\n        );\n    }\n\n    public function findBook(string $bookId): ?Book {\n        foreach ($this->books as $book) {\n            if ($book->getId() === $bookId) {\n                return $book;\n            }\n        }\n        return null;\n    }\n\n    public function updateBookCopies(string $bookId, int $change): void {\n        $book = $this->findBook($bookId);\n        if ($book) {\n            if ($change > 0) {\n                $book->incrementCopies();\n            } else {\n                $book->decrementCopies();\n            }\n        }\n    }\n}\n\n/**\n * UserManager: Responsable únicamente de la gestión de usuarios\n */\nclass UserManager {\n    private array $users = [];\n\n    public function registerUser(string $name, string $id, string $email): void {\n        $user = new User($name, $id, $email);\n        $this->users[] = $user;\n    }\n\n    public function removeUser(string $userId): void {\n        $this->users = array_filter(\n            $this->users,\n            fn($user) => $user->getId() !== $userId\n        );\n    }\n\n    public function findUser(string $userId): ?User {\n        foreach ($this->users as $user) {\n            if ($user->getId() === $userId) {\n                return $user;\n            }\n        }\n        return null;\n    }\n}\n\n/**\n * LoanManager: Responsable únicamente de la gestión de préstamos\n */\nclass LoanManager {\n    private array $loans = [];\n\n    public function __construct(\n        private BookManager $bookManager,\n        private UserManager $userManager\n    ) {}\n\n    public function loanBook(string $userId, string $bookId): void {\n        $book = $this->bookManager->findBook($bookId);\n        $user = $this->userManager->findUser($userId);\n\n        if (!$book || !$user) {\n            throw new Exception(\"Libro o usuario no encontrado\");\n        }\n\n        if ($book->getAvailableCopies() <= 0) {\n            throw new Exception(\"No hay copias disponibles\");\n        }\n\n        $this->bookManager->updateBookCopies($bookId, -1);\n        $this->loans[] = new Loan($userId, $bookId, new DateTime());\n    }\n\n    public function returnBook(string $userId, string $bookId): void {\n        $loan = $this->findLoan($userId, $bookId);\n        if (!$loan) {\n            throw new Exception(\"Préstamo no encontrado\");\n        }\n\n        $this->bookManager->updateBookCopies($bookId, 1);\n        $this->removeLoan($userId, $bookId);\n    }\n\n    private function findLoan(string $userId, string $bookId): ?Loan {\n        foreach ($this->loans as $loan) {\n            if ($loan->getUserId() === $userId && $loan->getBookId() === $bookId) {\n                return $loan;\n            }\n        }\n        return null;\n    }\n\n    private function removeLoan(string $userId, string $bookId): void {\n        $this->loans = array_filter(\n            $this->loans,\n            fn($loan) => !($loan->getUserId() === $userId && $loan->getBookId() === $bookId)\n        );\n    }\n}\n\n// Clases de modelo\nclass Book {\n    private string $id;\n\n    public function __construct(\n        private string $title,\n        private string $author,\n        private int $availableCopies\n    ) {\n        $this->id = uniqid();\n    }\n\n    public function getId(): string {\n        return $this->id;\n    }\n\n    public function getTitle(): string {\n        return $this->title;\n    }\n\n    public function getAuthor(): string {\n        return $this->author;\n    }\n\n    public function getAvailableCopies(): int {\n        return $this->availableCopies;\n    }\n\n    public function incrementCopies(): void {\n        $this->availableCopies++;\n    }\n\n    public function decrementCopies(): void {\n        $this->availableCopies--;\n    }\n}\n\nclass User {\n    public function __construct(\n        private string $name,\n        private string $id,\n        private string $email\n    ) {}\n\n    public function getId(): string {\n        return $this->id;\n    }\n\n    public function getName(): string {\n        return $this->name;\n    }\n\n    public function getEmail(): string {\n        return $this->email;\n    }\n}\n\nclass Loan {\n    public function __construct(\n        private string $userId,\n        private string $bookId,\n        private DateTime $loanDate\n    ) {}\n\n    public function getUserId(): string {\n        return $this->userId;\n    }\n\n    public function getBookId(): string {\n        return $this->bookId;\n    }\n\n    public function getLoanDate(): DateTime {\n        return $this->loanDate;\n    }\n}\n\n// Ejemplo de uso del sistema refactorizado\n$bookManager = new BookManager();\n$userManager = new UserManager();\n$loanManager = new LoanManager($bookManager, $userManager);\n\n// Registrar un libro\n$bookManager->addBook(\"El Quijote\", \"Miguel de Cervantes\", 5);\n\n// Registrar un usuario\n$userManager->registerUser(\"Juan Pérez\", \"USER001\", \"juan@email.com\");\n\n// Realizar un préstamo\n$loanManager->loanBook(\"USER001\", \"BOOK001\");\n?>"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/php/miguelex.php",
    "content": "<?php\n\n    // Ejercicio básico\n\n    class User {\n        private $name;\n        private $role;\n\n        public function __construct($name, $role){\n            $this->name = $name;\n            $this->role = $role;\n        }\n\n        public function getName(){\n            return $this->name;\n        }\n\n        public function getRole(){\n            return $this->role;\n        }\n\n        public function saveUser(){\n            $file = fopen('usersBD.txt', 'a');\n            fwrite($file, $this->name . ' is a  ' . $this->role . PHP_EOL);\n            fclose($file);\n        }\n    }\n\n    echo \"\\n\\nVamos a mostrar primero una clase que no cumple el SRP. Esto se debe a que la clase, ademas de gestionar el usuario, realizar la inserccion en BD (en este caso simualdo con un txt)\\n\\n\";\n    $user1 = new User('Miguel', 'Admin');\n    $user1->saveUser();\n    $user2 = new User('Maria', 'user');\n    $user2->saveUser();\n    echo \"\\nSe ha creado el archivo y podemos ver se ha ineertado correctamente. Vamos a refactorizar ahora para cumplir el SRP\\n\\n\";\n\n\n    class Users {\n        private $name;\n        private $role;\n\n        public function __construct($name, $role){\n            $this->name = $name;\n            $this->role = $role;\n        }\n\n        public function getName(){\n            return $this->name;\n        }\n\n        public function getRole(){\n            return $this->role;\n        }\n    }\n\n    class UsersBD {\n        private $path;\n\n        public function __construct($path){\n            $this->path = $path;\n        }\n\n        public function saveUser(Users $users){\n            $file = fopen($this->path, 'a');\n            fwrite($file, $users->getName() . ' is a  ' . $users->getRole() . PHP_EOL);\n            fclose($file);\n        }\n    }\n\n    echo \"\\n\\nHemos refactorizado el codigo anterior, separando la parte de usuarios de la parte de BD\\n\\n\";\n    $user1 = new Users('Miguel', 'Admin');\n    $user2 = new Users('Maria', 'user');\n    $userBD = new UsersBD('userBDSRP.txt');\n    $userBD->saveUser($user1);\n    $userBD->saveUser($user2);\n    echo \"\\nSe ha creado el archivo y podemos ver se ha insertado correctamente. A efectos de funcionamiento ambas solucioens funcionan igual pero la segunda es mas legible y mantenible\\n\\n\";\n\n    echo \"\\n\\nEjercicio Extra\\n\\n\";\n\n    // Extra\n\n   class Library {\n    private $books = [];\n    private $users = [];\n    private $loans = [];\n\n    public function addBook ($title, $author, $copies){\n        $this->books[] = ['title' => $title, 'author' => $author, 'copies' => $copies];\n    }\n\n    public function addUser ($name, $id, $email){\n        $this->users[] = ['name' => $name, 'id' => $id, 'email' => $email];\n    }\n\n    public function loanBook($userId, $bookTitle) {\n        foreach ($this->books as &$book) {\n            if ($book['title'] === $bookTitle && $book['copies'] > 0) {\n                $this->loans[] = [\n                    'userId' => $userId,\n                    'bookTitle' => $bookTitle,\n                    'date' => date('Y-m-d H:i:s')\n                ];\n                $book['copies']--;\n                return \"El libro ha sido prestado.\";\n            }\n        }\n        return \"El libro no está disponible.\";\n    }\n\n    public function returnBook($userId, $bookTitle) {\n        foreach ($this->loans as $key => $loan) {\n            if ($loan['userId'] === $userId && $loan['bookTitle'] === $bookTitle) {\n                unset($this->loans[$key]);\n                foreach ($this->books as &$book) {\n                    if ($book['title'] === $bookTitle) {\n                        $book['copies']++;\n                        return \"El libro ha sido devuelto.\";\n                    }\n                }\n            }\n        }\n        return \"No se encontró el préstamo.\";\n   }\n\n   public function getBooks(){\n        return $this->books;\n   }\n\n   public function getUsers(){\n        return $this->users;\n   }\n\n    public function getLoans(){\n          return $this->loans;\n    }\n}\n\n$myLibrary = new Library();\n\necho \"\\n\\nVamos a mostrar un ejemplo de una clase que no cumple el SRP. En este caso es una clase que gestiona una biblioteca\\n\\n\";\n\ndo {\n    echo \"\\n\\nMENÚ\\n\\n\";\n    echo \"\";\n    echo \"1. Añadir libro\\n\";\n    echo \"2. Añadir usuario\\n\";\n    echo \"3. Prestar libro\\n\";\n    echo \"4. Devolver libro\\n\";\n    echo \"5. Mostrar libros\\n\";\n    echo \"6. Mostrar usuarios\\n\";\n    echo \"7. Mostrar préstamos\\n\";\n    echo \"8. Salir\\n\";\n    echo \"\";\n    echo \"Elija una opción: \";\n\n    $option = readline();\n    echo \"\";\n    \n    switch ($option) {\n        case 1:\n            echo \"Título: \";\n            $title = readline();\n            echo \"Autor: \";\n            $author = readline();\n            echo \"Copias: \";\n            $copies = readline();\n            $myLibrary->addBook($title, $author, $copies);\n            break;\n        case 2:\n            echo \"Nombre: \";\n            $name = readline();\n            echo \"ID: \";\n            $id = readline();\n            echo \"Email: \";\n            $email = readline();\n            $myLibrary->addUser($name, $id, $email);\n            break;\n        case 3:\n            echo \"ID del usuario: \";\n            $userId = readline();\n            echo \"Título del libro: \";\n            $bookTitle = readline();\n            echo $myLibrary->loanBook($userId, $bookTitle) . \"\\n\";\n            break;\n        case 4:\n            echo \"ID del usuario: \";\n            $userId = readline();\n            echo \"Título del libro: \";\n            $bookTitle = readline();\n            echo $myLibrary->returnBook($userId, $bookTitle) . \"\\n\";\n            break;\n        case 5:\n            print_r($myLibrary->getBooks());\n            break;\n        case 6:\n            print_r($myLibrary->getUsers());\n            break;\n        case 7:\n            print_r($myLibrary->getLoans());\n            break;\n    }\n    \n} while (($option != 8));\n\n\n// Vamos ahora a refactorizar para aplicar el SRP. Ahora tnedremos una clase para los libros, otra para los autores y otra para los prestamos, asi como sus respectivos managers\n\nclass Books {\n    private $title;\n    private $author;\n    private $copies;\n\n    public function __construct($title, $author, $copies){\n        $this->title = $title;\n        $this->author = $author;\n        $this->copies = $copies;\n    }\n\n    public function getTitle(){\n        return $this->title;\n    }\n\n    public function getAuthor(){\n        return $this->author;\n    }\n\n    public function getCopies(){\n        return $this->copies;\n    }\n\n    public function loanBook(){\n        if ($this->copies > 0) {\n            $this->copies--;\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    public function returnBook(){\n        $this->copies++;\n    }\n}\n\nclass UsersLibrary {\n    private $name;\n    private $id;\n    private $email;\n\n    public function __construct($name, $id, $email){\n        $this->name = $name;\n        $this->id = $id;\n        $this->email = $email;\n    }\n\n    public function getName(){\n        return $this->name;\n    }\n\n    public function getId(){\n        return $this->id;\n    }\n\n    public function getEmail(){\n        return $this->email;\n    }\n\n}\n\nclass Loan {\n    private $userId;\n    private $bookTitle;\n    private $date;\n\n    public function __construct($userId, $bookTitle){\n        $this->userId = $userId;\n        $this->bookTitle = $bookTitle;\n        $this->date = date('Y-m-d H:i:s');\n    }\n\n    public function getUserId(){\n        return $this->userId;\n    }\n\n    public function getBookTitle(){\n        return $this->bookTitle;\n    }\n\n    public function getDate(){\n        return $this->date;\n    }\n}\n\nclass BookManager {\n    private $books = [];\n\n    public function addBook(Books $book){\n        $this->books[] = $book;\n    }\n\n    public function getBooks(){\n        return $this->books;\n    }\n\n    public function findBookByTitle($title){\n        foreach ($this->books as $book) {\n            if ($book->getTitle() === $title) {\n                return $book;\n            }\n        }\n        return null;\n    }\n}\n\nclass UserManager{\n    private $users = [];\n\n    public function addUser(UsersLibrary $user){\n        $this->users[] = $user;\n    }\n\n    public function getUsers(){\n        return $this->users;\n    }\n\n    public function findUserById($id){\n        foreach ($this->users as $user) {\n            if ($user->getId() === $id) {\n                return $user;\n            }\n        }\n        return null;\n    }\n}\n\nclass LoanManager{\n    private $loans = [];\n\n    public function loanBook(UsersLibrary $user, Books $book){\n        if ($book->loanBook()) {\n            $this->loans[] = new Loan($user->getId(), $book->getTitle());\n        } else {\n            echo \"No hay copias disponibles para el libro: \" . $book->getTitle() . \"\\n\";\n        }\n    }\n\n    public function returnBook(UsersLibrary $user, Books $book){\n        foreach ($this->loans as $key => $loan) {\n            if ($loan->getUserId() === $user->getId() && $loan->getBookTitle() === $book->getTitle()) {\n                $book->returnBook();\n                unset($this->loans[$key]);\n                echo \"Libro devuelto correctamente.\\n\";\n                return;\n            }\n        }\n        echo \"No se encontró el préstamo del libro para el usuario especificado.\\n\";\n    }\n\n    public function getLoans(){\n        return $this->loans;\n    }\n}\n\n$myBookManager = new BookManager();\n$myUserManager = new UserManager();\n$myLoanManager = new LoanManager();\n\necho \"\\n\\nVamos a mostrar un ejemplo que si cumple SRP. En este caso es una clase que gestiona una biblioteca\\n\\n\";\n\ndo {\n    echo \"\\n\\nMENÚ\\n\\n\";\n    echo \"\";\n    echo \"1. Añadir libro\\n\";\n    echo \"2. Añadir usuario\\n\";\n    echo \"3. Prestar libro\\n\";\n    echo \"4. Devolver libro\\n\";\n    echo \"5. Mostrar libros\\n\";\n    echo \"6. Mostrar usuarios\\n\";\n    echo \"7. Mostrar préstamos\\n\";\n    echo \"8. Salir\\n\";\n    echo \"\";\n    echo \"Elija una opción: \";\n\n    $option = readline();\n    echo \"\";\n    \n    switch ($option) {\n        case 1:\n            echo \"Título: \";\n            $title = readline();\n            echo \"Autor: \";\n            $author = readline();\n            echo \"Copias: \";\n            $copies = readline();\n            $myBookManager->addBook(new Books($title, $author, $copies));\n            break;\n        case 2:\n            echo \"Nombre: \";\n            $name = readline();\n            echo \"ID: \";\n            $id = readline();\n            echo \"Email: \";\n            $email = readline();\n            $myUserManager->addUser(new UsersLibrary($name, $id, $email));\n            break;\n        case 3:\n            echo \"ID del usuario: \";\n            $userId = readline();\n            echo \"Título del libro: \";\n            $bookTitle = readline();\n            $user = $myUserManager->findUserById($userId);\n            $book = $myBookManager->findBookByTitle($bookTitle);\n            if ($user && $book) {\n                $myLoanManager->loanBook($user, $book);\n            } else {\n                echo \"Usuario o libro no encontrado.\\n\";\n            }\n            break;\n        case 4:\n            echo \"ID del usuario: \";\n            $userId = readline();\n            echo \"Título del libro: \";\n            $bookTitle = readline();\n            $user = $myUserManager->findUserById($userId);\n            $book = $myBookManager->findBookByTitle($bookTitle);\n            if ($user && $book) {\n                $myLoanManager->returnBook($user, $book);\n            } else {\n                echo \"Usuario o libro no encontrado.\\n\";\n            }\n            break;\n        case 5:\n            print_r($myBookManager->getBooks());\n            break;\n        case 6:\n            print_r($myUserManager->getUsers());\n            break;\n        case 7:\n            print_r($myLoanManager->getLoans());\n            break;\n    }\n    \n} while (($option != 8));\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/Aldroide.py",
    "content": "\"\"\"\n    SOLID: Principio de Responsibilidad Única (SRP)\n    Ejercicio\n    Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n    Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n    de forma correcta e incorrecta.\n\"\"\"\n# Uso incorrecto del SRP\nfrom typing import Any\n\n\nclass User:\n    def __init__(self, name, email):\n        self.name = name\n        self.email = email\n\n    def save_user(self):\n        print(f\"El usuario {self.name} ha sido guardado.\")\n\n    def print_report(self):\n        print(f\"Imprimiendo reporte para {self.name} con email {self.email}.\")\n\n\nuser = User(\"Aldroide\", \"aldroide@dev.com.\")\nuser.save_user()\nuser.print_report()\n\n# Uso correcto del SRP\n\n\nclass User1:\n    def __init__(self, name, email):\n        self.name = name\n        self.email = email\n\n    def save(self):\n        print(f\"Guardando usuario {self.name}.\")\n\n\nclass Info():\n    def __init__(self, user):\n        self.user = user\n\n    def print_inform(self):\n        print(\n            f\"Imprimiendo informe  para {self.user.name} con email {self.user.email}.\")\n\n\nuser = User1(\"Emmanuel\", \"emma@dev.com\")\nuser.save()\n\ninforme = Info(user)\ninforme.print_inform()\n\n\"\"\"\n    DIFICULTAD EXTRA (opcional):\n    Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n    manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n    y el procesamiento de préstamos de libros.\n    Requisitos:\n        1. Registrar libros: El sistema debe permitir agregar nuevos libros con \n            información básica como título, autor y número de copias disponibles.\n        2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n            información básica como nombre, número de identificación y correo electrónico.\n        3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n            tomar prestados y devolver libros.\n    Instrucciones:\n        1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n            los tres aspectos mencionados anteriormente (registro de libros, registro de\n            usuarios y procesamiento de préstamos).\n        2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n            siguiendo el Principio de Responsabilidad Única.\n\"\"\"\n\n# No cumple con el SRP\n\n\nclass Library:\n    def __init__(self):\n        self.books = []\n        self.users = []\n        self.loans = []\n\n    def Register_book(self, title, author, copies):\n        book = {'title': title, \"author\": author, \"copies\": copies}\n        self.books.append(book)\n        print(f\"Titulo registrado: {title}.\")\n\n    def Register_user(self, id, name, email):\n        user = {'id': id, \"name\": name, \"email\": email}\n        self.users.append(user)\n        print(f\"Usuario registrado: {name}.\")\n\n    def Process_Loans(self, id, title):\n        for book in self.books:\n            if book[\"title\"] == title and book['copies'] > 0:\n                book['copies'] -= 1\n                self.loans.append({'id': id, 'title': title})\n                print(f\"Libro prestado: {book['title']} a {id}.\")\n                return\n        print(f\"No existen copias disponibles de {title}.\")\n\n    def Return_book(self, id, title):\n        for loan in self.loans:\n            if loan[\"id\"] == id and loan[\"title\"] == title:\n                self.loans.remove(loan)\n                for book in self.books:\n                    if book[\"title\"] == title:\n                        book[\"copies\"] += 1\n                        print(f\"Libro devuelto: {title} por {id}.\")\n                        return\n        print(f\"No se encontró el prestamo del {title} para {id}. \")\n\n\nlibrary = Library()\nlibrary.Register_book(\"Baluarte\", \"Elvira Sastre\", 5)\nlibrary.Register_book(\"Dias sin ti\", \"Elvira Sastre\", 3)\nlibrary.Register_book(\n    \"Cuarenta y tres maneras de soltarse el pelo\", \"Elvira Sastre\", 5)\nlibrary.Register_user(\"Aldo\", 1, \"aldo@dev.com\")\nlibrary.Register_user(\"Emmanuel\", 2, \"emma@dev.com\")\nlibrary.Register_user(\"Samira\", 3, \"sami@dev.com\")\nlibrary.Process_Loans(2, \"Baluarte\")\nlibrary.Process_Loans(3, \"Baluarte\")\nlibrary.Return_book(2, \"Baluarte\")\n\n\n# Codigo Refactorizado cumple con el SRP\nclass Book_Manager:\n    def __init__(self):\n        self.books = []\n\n    def Register_book(self, title, author, copies):\n        book = {'title': title, 'author': author, 'copies': copies}\n        self.books.append(book)\n        print(f\"Libro Registrado: {title}.\")\n\n    def Search_book(self, title):\n        for book in self.books:\n            if book['title'] == title:\n                return book\n        return None\n\n\nclass User_Manager:\n    def __init__(self):\n        self.users = []\n\n    def Register_user(self, id, name, email):\n        user = {'id': id, \"name\": name, \"email\": email}\n        self.users.append(user)\n        print(f\"Usuario registrado: {name}.\")\n\n    def Search_user(self, id):\n        for user in self.users:\n            if user['id'] == id:\n                return user\n        return None\n\n\nclass Loan_manager:\n    def __init__(self, book_manager, user_manager):\n        self.loans = []\n        self.book_manager = book_manager\n        self.user_manager = user_manager\n\n    def Process_loan(self, id, title):\n        user = self.user_manager.Search_user(id)\n        book = self.book_manager.Search_book(title)\n\n        if user and book and book['copies'] > 0:\n            book['copies'] -= 1\n            self.loans.append({'id': id, 'title': title})\n            print(f\"Libro prestado {book['title']} a {user['name']}.\")\n        else:\n            print(f\"No se puede presta el libro {title}.\")\n\n    def Return_book(self, id, title):\n        for loan in self.loans:\n            if loan['id'] == id and loan['title'] == title:\n                self.loans.remove(loan)\n                book = self.book_manager.Search_book(title)\n                if book:\n                    book['copies'] += 1\n                    print(f\"Libro devuelto: {title} por {id}.\")\n                return\n        print(f\"No se encontro el prestamo de {title} para {id}.\")\n\n\nbook_manager = Book_Manager()\nuser_manager = User_Manager()\nloan_manager = Loan_manager(book_manager, user_manager)\n\nbook_manager.Register_book(\"El Quijote\", \"Cervantes\", 5)\nbook_manager.Register_book(\"La panza del tepozteco\", \"José Agustin\", 3)\n\nuser_manager.Register_user(name=\"Sebastian\", id=1, email=\"sebas@dev.com\")\nuser_manager.Register_user(name=\"Erwin\", id=2, email=\"erwin@dev.com\")\nloan_manager.Process_loan(1, \"El Quijote\")\nloan_manager.Return_book(1, \"El Quijote\")\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/BastianAlq.py",
    "content": "import time\nimport logging\n# ---------------------------------------------\n# | Principio de Responsabilidad Unica (SRP)  |  Información extraída de -> https://devexpert.io/principios-solid-guia-gratis/ \n# ---------------------------------------------\n\n# - Una clase o modulo debe tener solo una razon para cambiar\n# - el SRP se cumple cuando una clase hace una única \"cosa\"\n\n# ¿CÓMO DETECTAR QUE SE ESTA VIOLANDO EL PRINCIPIO DE RESPONSABILIDAD ÚNICA? aquí algunos puntos para guiarse\n# R. se pueden detectar situaciones en las que se viola el principio como por ejemplo:\n# - cuando en una misma clase se involucran dos capas de arquitectura | (Ej: mezclar capa logica de negocio y persistencia)\n# - numero de metodos publicos | (si la clase tiene muchos metodos, posiblemente tenga muchas responsabilidades)\n# - numero de imports | (si se importan demasiadas clases, es posible que se este haciendo trabajo demas)\n# - cuesta testear la clase | (si no es posible hacer test unitarios, es posible replantear en dividir la clase en dos )\n# - cada vez que se se escribe una nueva funcionalidad, la clase se ve afectada | \n#  (si la clase se modifica a menudo, es porque esta involucrada en demasiadas cosas)\n# - numero de lineas. (Si la clase es demasiado grande, dividir en clases mas manejables)\n\n\n#  -------------------------- INICIO FUNCIONAMIENTO INCORRECTO DEL SRP --------------------------\n#   en este ejemplo se esta mezclando la logica de negocio con la de presentación\n#   posible problema: si se quiere mostrar de otra forma los datos del vehiculo (texto plano, html, etc)\n#   la clase Vehicle tendrá dos responsabilidades, la cual es:\n#       (1) representar los datos del objeto\n#       (2) mostrarlos en distintos formatos\n#\n#\n\nprint(\"------------ FUNCIONAMIENTO INCORRECTO ------------\")\nclass Vehicle:\n    \n    def __init__(self,wheelCount,maxSpeed) -> None:\n        self.wheelCount = wheelCount\n        self.maxSpeed = maxSpeed\n    \n    def printVehicle(self):\n        print(f\"wheelCount = {self.wheelCount}, maxSpeed = {self.maxSpeed} km/h\")\n\n\nvehicle = Vehicle(4,120)\nvehicle.printVehicle()\n\n#  -------------------------- FIN FUNCIONAMIENTO CORRECTO DEL SRP --------------------------\n\ntime.sleep(2)\n\n#  -------------------------- INICIO FUNCIONAMIENTO CORRECTO DEL SRP --------------------------\n#   Solución: \n#   Crear una clase VehiclePrinter que reciba el objeto vehiculo para mostrar sus datos.\n#   al realizar esto, la clase Vehicle solo se encargará de representar los datos del vehiculo \n#   y la clase VehiclePrinter solo se encargará de mostrar los datos del vehiculo en distintos formatos.\n\nprint(\"------------ FUNCIONAMIENTO CORRECTO ------------\")\nclass Vehicle:\n    def __init__(self,wheelCount,maxSpeed) -> None:\n        self.wheelCount = wheelCount\n        self.maxSpeed = maxSpeed\n\nclass VehiclePrinter:\n    \n    @staticmethod\n    def printVehicle(vehicle: Vehicle):\n        print(f\"wheelCount = {vehicle.wheelCount}, maxSpeed = {vehicle.maxSpeed} km/h\")\n        \n    def printVehicleHtml(vehicle: Vehicle):\n        print(\"Renderizar datos en un html\")\n    \n    # etc...\nvehicle = Vehicle(2,200)\nvehiclePrinter = VehiclePrinter()\nvehiclePrinter.printVehicle(vehicle)\n\n#  -------------------------- FIN FUNCIONAMIENTO CORRECTO DEL SRP --------------------------\n\n\n#  DIFICULTAD EXTRA (opcional):\n#  * Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n#  * manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n#  * y el procesamiento de préstamos de libros.\n#  * Requisitos:\n#  * 1. Registrar libros: El sistema debe permitir agregar nuevos libros con \n#  * información básica como título, autor y número de copias disponibles.\n#  * 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n#  * información básica como nombre, número de identificación y correo electrónico.\n#  * 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n#  * tomar prestados y devolver libros.\n#  * Instrucciones:\n#  * 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n#  * los tres aspectos mencionados anteriormente (registro de libros, registro de\n#  * usuarios y procesamiento de préstamos).\n#  * 2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n#  * siguiendo el Principio de Responsabilidad Única.\n#  *\n\n\nlogging.basicConfig(level=logging.DEBUG,\n                    format=\"%(asctime)s - %(levelname)s - %(message)s\",\n                    handlers=[logging.StreamHandler()])\n\n#     _____________________\n#     |                    |\n#     | Dificultad Extra   |\n#     |____________________|\n#\n#    Sistema gestion de prestamos de libros y de usuarios\n#    Incumplimiento de SRP\n\nprint(\"Dificultad extra\")\nprint(\"---------- FORMA INCORRECTA ----------\")\n\nclass Library:\n    \n    def __init__(self) -> None:\n        \n        self.books = []\n        self.users = []\n        self.loans = []\n        pass\n    \n    def addNewBook(self, title: str , author: str , copies: int):\n        self.books.append({\"title\": title , \"author\": author, \"copies\": copies})\n        logging.info(f\"El libro {title} se ha añadido correctamente\")\n    \n    def addNewUser(self, userId: int, name: str, email: str):\n        self.users.append({\"id\": userId, \"name\": name, \"email\": email})\n        logging.info(f\"Usuario {name} registrado correctamente\")\n    \n    def lendBook(self, bookTitle: str, userId: int):\n        for book in self.books:\n            if book[\"title\"] == bookTitle and book[\"copies\"] >0:\n                book[\"copies\"] -= 1\n                self.loans.append({\"userId\": userId, \"bookTitle\": bookTitle})\n                logging.info(f\"Se ha prestado el libro {bookTitle} al usuario con id {userId}\")\n    \n    \n    def returnBook(self, bookTitle: str, userId: str):\n        for loan in self.loans:\n            if loan[\"userId\"] == userId and loan[\"bookTitle\"] == bookTitle:\n                self.loans.remove(loan)\n                for book in self.books:\n                    if book[\"title\"] == bookTitle:\n                        book[\"copies\"] +=1\n                        logging.info(f\"el libro {bookTitle} ha sido devuelto por el usuario con id: {userId}\")\n\nlibrary = Library()\nlibrary.addNewBook(\"Habitos atomicos\", \"James Clear\",6)\nlibrary.addNewUser(12,\"Pedro\", \"pedro@gmail.com\")\nlibrary.lendBook(\"Habitos atomicos\",12)\nlibrary.returnBook(\"Habitos atomicos\",12)\n\n\nprint(\"---------- FORMA CORRECTA ----------\")\n\n\nclass User:\n    def __init__(self, id: int, name: str, email: str) -> None:\n        self.id = id\n        self.name = name\n        self.email = email\n\nclass Book: \n    def __init__(self, title: str, author: str, copies: int) -> None:\n        self.title = title\n        self.author = author\n        self.copies = copies\n\n\nclass UserService:\n    def __init__(self) -> None:\n        self.users = []\n    \n    def addUser(self, user: User):\n        self.users.append(user)\n        return True\n        \n        \n    def findUserById(self, id: int):\n        for user in self.users:\n            if user.id == id:\n                return user\n        return None\n    \n\nclass BookService:\n    def __init__(self) -> None:\n        self.books = []\n        \n    def addBook(self, book: Book):\n        self.books.append(book)\n        return True\n        \n    \n    def findBookByTitle(self, title: str):\n        for book in self.books:\n            if book.title == title:\n                return book\n        return None\n        \nclass Loan:\n    def __init__(self) -> None:\n        self.loans = []\n        \n    \n    def loanBook(self, user: User, book: Book):\n        if book.copies > 0:\n            self.loans.append({\"userId\": user.id, \"bookTitle\": book.title})\n            book.copies -= 1\n            return True\n        return False\n        \n    \n    def returnBook(self, user: User, book: Book):\n        for loan in self.loans:\n            if loan[\"userId\"] == user.id and loan[\"bookTitle\"] == book.title:\n                self.loans.remove(loan)\n                book.copies += 1\n                return True\n                \n        return False\n    \nclass Library:\n    def __init__(self) -> None:\n        self.loanService = Loan()\n        self.bookService = BookService()\n        self.userService = UserService()\n        \n    def loanBook(self, userId: int, bookTitle: str):\n        added = False\n        user = self.userService.findUserById(userId)\n        book = self.bookService.findBookByTitle(bookTitle)\n        if user and book:\n                added = self.loanService.loanBook(user,book)\n                if added:\n                    logging.info(f\"Se ha registrado un prestamo del libro {book.title} al usuario {user.name}\")\n                else:\n                    logging.error(\"el libro esta agotado\")\n        else:\n            logging.error(\"usuario o libro no existen\")\n                    \n    \n    def returnBook(self, userId: int, bookTitle: str):\n        user = self.userService.findUserById(userId)\n        book = self.bookService.findBookByTitle(bookTitle)\n        if user and book:\n            returned = self.loanService.returnBook(user,book)\n            if returned:\n                logging.info(f\"el usuario {user.name} ha devuelto el libro {book.title}\")\n            else:\n                logging.error(f\"No se encontró prestamo del usuario {user.name} con el libro {book.title}\")\n        else:\n            logging.error(\"el libro o usuario no existen\")\n            \n    def addUser(self, user: User):\n        self.userService.addUser(user)\n        logging.info(f\"Usuario {user.name} añadido correctamente\")\n    \n    def addBook(self, book: Book):\n        self.bookService.addBook(book)\n        logging.info(f\"Libro {book.title} añadido correctamente\")\n        \n\ntime.sleep(2)\n\n\nlibrary = Library()\nlibrary.addBook(Book(\"Habitos atomicos\", \"James Clear\", 10))\nlibrary.addUser(User(23,\"Pedro Pablo\",\"pp@gmail.com\"))\n\nlibrary.loanBook(23,\"Habitos atomicos\")\nlibrary.returnBook(23,\"Habitos atomicos\")\nlibrary.returnBook(23,\"Habitos atomicos\")\nlibrary.loanBook(23,\"Perico trepa por Chile\")"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/CesarCarmona30.py",
    "content": "'''\n  EJERCICIO\n'''\n\n# Incorrecto\n\nclass User:\n  \n  def __init__(self, name, email) -> None:\n    self.name = name\n    self.email = email\n\n  def save_to_database(self):\n    pass\n\n  def send_email(self):\n    pass\n\n\n# Correcto\n\nclass User:\n  \n  def __init__(self, name, email) -> None:\n    self.name = name\n    self.email = email\n\nclass UserService:\n\n  def save_to_database(self, user):\n    pass\n\nclass EmailService:\n  \n  def send_email(self, email, message):\n    pass\n\n'''\n  EXTRA\n'''\n\n# Incorrecto\n\nclass Library:\n  def __init__(self) -> None:\n    self.books = []\n    self.users = []\n    self.loans = []\n\n  def add_book(self, title, author, copies):\n    self.books.append({\"title\": title, \"author\": author, \"copies\": copies})\n\n  def add_user(self, name, id, email):\n    self.users.append({\"id\": id, \"name\": name, \"email\": email})\n\n  def loan_book(self, user_id, book_title):\n    for book in self.books:\n      if book[\"title\"] == book_title and book[\"copies\"] > 0:\n        book[\"copies\"] -= 1\n        self.loans.append(\n          {\"user_id\": user_id, \"book_title\": book_title})\n        return True\n    return False\n  \n  def return_book(self, user_id, book_title):\n    for loan in self.loans:\n      if loan[\"user_id\"] == user_id and loan[\"book_title\"] == book_title:\n        self.loans.remove(loan)\n        for book in self.books:\n          if book[\"title\"] == book_title:\n            book[\"copies\"] += 1\n          return True\n    return False\n  \n# Correcto\n\nclass Book:\n\n  def __init__(self, title, author, copies):\n    self.title = title\n    self.author = author\n    self.copies = copies\n\nclass User:\n\n  def __init__(self, name, id, email):\n    self.name = name\n    self.id = id\n    self.email = email\n\nclass Loan:\n\n  def __init__(self):\n    self.loans = []\n\n  def loan_bool(self, user, book):\n    if book.copies > 0:\n      book.copies -= 1\n      self.loans.append(\n        {\"user_id\": user.id, \"book_title\": book.title})\n      return True\n    return False\n  \n  def return_book(self, user, book):\n    for loan in self.loans:\n      if loan[\"user_id\"] == user.id and loan[\"book_title\"] == book.title:\n        self.loans.remove(loan)\n        book.copies += 1\n        return True\n    return False\n  \nclass Library:\n\n  def __init__(self) -> None:\n    self.books = []\n    self.users = []\n    self.loans_service = Loan()\n\n  def add_book(self, book):\n    self.books.append(book)\n\n  def add_user(self, user):\n    self.users.append(user)\n\n  def loan_book(self, user_id, book_title):\n    user = next((u for u in self.users if u.id == user_id), None)\n    book = next((b for b in self.books if b.title == book_title), None)\n    if user and book:\n      return self.loans_service.loan_book(user, book)\n    return False\n  \n  def return_book(self, user_id, book_title):\n    user = next((u for u in self.users if u.id == user_id), None)\n    book = next((b for b in self.books if b.title == book_title), None)\n    if user and book:\n      return self.loans_service.return_book(user, book)\n    return False"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/Chrisdev00.py",
    "content": "\"\"\"\n* EJERCICIO:\n* Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n* Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n* de forma correcta e incorrecta.\n*\n* DIFICULTAD EXTRA (opcional):\n* Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n* manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n* y el procesamiento de préstamos de libros.\n* Requisitos:\n* 1. Registrar libros: El sistema debe permitir agregar nuevos libros con \n* información básica como título, autor y número de copias disponibles.\n* 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n* información básica como nombre, número de identificación y correo electrónico.\n* 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n* tomar prestados y devolver libros.\n* Instrucciones:\n* 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n* los tres aspectos mencionados anteriormente (registro de libros, registro de\n* usuarios y procesamiento de préstamos).\n* 2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n* siguiendo el Principio de Responsabilidad Única.\n\"\"\"\n\n# El Principio de Responsabilidad Única (Single Responsibility Principle, SRP) es uno de los cinco principios de \n# diseño de software SOLID, que fue definido por Robert C. Martin. \n# Este principio establece que una clase debe tener una, y solo una, razón para cambiar, \n# es decir, una única responsabilidad o propósito.\n\n# Ejemplo (Forma incorrecta)\n\nclass Order:\n    def __init__(self, items, tax_rate):\n        self.items = items # tupla (item: precio)\n        self.tax_rate = tax_rate\n    \n    def calculate_total(self):\n        total = sum(price for item, price in self.items)\n        discount = 5  # Añadir un descuento fijo\n        tax = (total - discount) * self.tax_rate\n        return total - discount + tax\n    \n    def generate_invoice(self):\n        total = self.calculate_total()\n        invoice = \"Factura:\\n\"\n        for item, price in self.items:\n            invoice += f\"{item}: ${price}\\n\"\n        invoice += f\"Total (incluyendo impuestos): ${total}\\n\"\n        return invoice\n    \n    def send_confirmation_email(self, email):\n        invoice = self.generate_invoice()\n        print(f\"Enviando email a {email} con la siguiente Factura:\\n{invoice}\")\n\n\norder = Order([(\"Libro\", 12.99), (\"Lapicero\", 0.99)], 0.1)\nprint(order.calculate_total())\nprint(order.generate_invoice())\norder.send_confirmation_email(\"customer@example.com\")\n\n\n# Ejemplo (Forma correcta cumpliendo con el SRP)\n\n\nclass Order:\n    def __init__(self, items):\n        self.items = items\n    \n    def get_total(self):\n        return sum(price for item, price in self.items)\n\nclass TaxCalculator:\n    def calculate_tax(self, total, tax_rate, discount=0):\n        return (total - discount) * tax_rate\n\nclass InvoiceGenerator:\n    def generate_invoice(self, order, total, tax):\n        invoice = \"Factura:\\n\"\n        for item, price in order.items:\n            invoice += f\"{item}: ${price}\\n\"\n        invoice += f\"Subtotal: ${total}\\n\"\n        invoice += f\"Impuesto: ${tax}\\n\"\n        invoice += f\"Total (incluyendo impuestos): ${total + tax}\\n\"\n        return invoice\n\nclass EmailSender:\n    def send_email(self, email, content):\n        print(f\"Enviando email a {email} con el siguiente contenido:\\n{content}\")\n\n\norder = Order([(\"Libro\", 12.99), (\"Lapiz\", 0.99)])\ntax_calculator = TaxCalculator()\ninvoice_generator = InvoiceGenerator()\nemail_sender = EmailSender()\n\ntotal = order.get_total()\ntax = tax_calculator.calculate_tax(total, 0.1, discount=5)\nsubtotal = total - 5\n\nfactura = invoice_generator.generate_invoice(order, subtotal, tax)\n\nemail_sender.send_email(\"comprador@example.com\", factura)\n\n\n########## ------------------------------- EXTRA ---------------------------------- #######################\n\n# Forma Incorrecta\n\nclass Library:\n\n    def __init__(self):\n        self.books = []\n        self.users = []\n        self.loans = []\n\n    def add_book(self, title, author, copies):\n        book = {\"title\": title, \"author\": author, \"copies\": copies}\n        self.books.append(book)\n\n    def add_usser(self, name, user_id, email):\n        user = {\"name\": name, \"user_id\": user_id, \"email\": email}\n        self.users.append(user)\n\n    def borrow_book(self, user_id, title):\n        for book in self.books:\n            if book[\"title\"] == title and book[\"copies\"] > 0:\n                book[\"copies\"] -= 1\n                loan = {\"user_id\": user_id, \"title\": title}\n                self.loans.append(loan)\n                return f\"El usuario '{user_id}' se presto el libro '{title}'.\"\n        return f\"Libro '{title}' no esta disponible.\"\n    \n    def return_book(self, user_id, title):\n        for loan in self.loans:\n            if loan[\"user_id\"] == user_id and loan[\"title\"] == title:\n                self.loans.remove(loan)\n                for book in self.books:\n                    if book[\"title\"] == title:\n                        book[\"copies\"] += 1\n                return f\"Libro '{title}' retornado por el usuario '{user_id}'.\"\n        return f\"No hay registro de que el usuario '{user_id}' se haya prestado el libro '{title}'\"\n    \n\nlibrary = Library()\n\nlibrary.add_book(\"Lord of the Rings\", \"JRR Tolkien\", 4)\nlibrary.add_book(\"Harry Potter\", \"JK Rowling\", 2)\n\nlibrary.add_usser(\"Alice\", \"1\", \"alice@example.com\")\nlibrary.add_usser(\"Matias\", \"2\", \"matias@example.com\")\n\nprint(library.borrow_book(\"1\", \"Lord of the Rings\"))\nprint(library.borrow_book(\"2\", \"Harry Potter\"))\nprint(library.borrow_book(\"1\", \"Lord of the Rings\"))\nprint(library.return_book(\"2\", \"The Great Gatsby\"))\n\n\n# Forma correcta (usando SRP)\n\nclass Library:\n    def __init__(self):\n        self.books = []\n        self.users = []        \n\n    def add_book(self, book):\n        self.books.append(book)\n\n    def add_user(self, user):\n        self.users.append(user)\n\n    def find_book(self, title):\n        for book in self.books:\n            if book.title == title:\n                return book\n        return None\n    \n    def find_user(self, user_id):\n        for user in self.users:\n            if user.user_id == user_id:\n                return user\n        return None\n    \n    def total_books(self):\n        return sum(book.copies for book in self.books)\n    \n    def get_library_info(self):\n        total_books = self.total_books()\n        books_info = [book.show_info() for book in self.books]\n        return total_books, books_info\n\nclass Book:\n    def __init__(self, title, author, copies):\n        self.title = title\n        self.author = author\n        self.copies = copies\n\n    def show_info(self):\n        return f\"'{self.title}' por '{self.author}', numero de copias {self.copies}\"\n    \nclass User:\n    def __init__(self, name, user_id, email):\n        self.name = name\n        self.user_id = user_id\n        self.email = email\n        self.loans = []\n\nclass LoanProcess:\n    \n    def borrow_book(self, library, user_id, title):\n        user = library.find_user(user_id)\n        book = library.find_book(title)\n        if book and user:\n            if book.copies > 0:\n                user.loans.append(book)\n                book.copies -= 1\n                print(f\"Libro '{book.title}' prestado a '{user.name}'\")\n            else:\n                print(f\"Este libro no esta disponible para prestamo\")\n        else:\n            print(f\"Usuario o libro no encontrado\")\n\n    def return_book(self, library, user_id, title):\n        user = library.find_user(user_id)\n        book = library.find_book(title)\n        if book and user:\n            if book in user.loans:\n                user.loans.remove(book)\n                book.copies += 1\n                print(f\"Libro '{book.title}' devuelto por '{user.name}'.\")\n            else:\n                print(f\"No hay registro de que el libro '{book.title}' haya sido prestado a '{user.name}'.\")\n        else:\n            print(\"Usuario o libro no encontrado.\")\n\n\nlibrary = Library()\nbook1 = Book(\"Lord of the Rings\", \"JRR Tolkien\", 4)\nbook2 = Book(\"1984\", \"George Orwell\", 5)\nuser = User(\"Alice\", \"1\", \"alice@example.com\")\nlibrary.add_book(book1)\nlibrary.add_book(book2)\nlibrary.add_user(user)\n\nloan_processor = LoanProcess()\nloan_processor.borrow_book(library, \"1\", \"Lord of the Rings\")\nloan_processor.return_book(library, \"1\", \"Lord of the Rings\")\n\n\n# Total de libros en la biblioteca\ntotal_libros, info_libros = library.get_library_info()\nprint(f\"Total de libros en la biblioteca: {total_libros}\")\nprint(\"Informacion de la biblioteca:\")\nfor info in info_libros:\n    print(info)\n\n\n\n\n    \n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/EmmanuelMMontesinos.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n * Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n */\n\"\"\"\n# SOLID: Principio de responsabilidad única\n\n'''Sin aplicar'''\nclass Pedido:\n    def __init__(self,plato,numero,precio) -> None:\n        self.comanda = []\n        self.total = 0\n        self.comanda.append((plato,precio,numero))\n        self.total += precio * numero\n    \n# Prueba\nmi_pedido = Pedido(\"pollo\",1,5.2)\nprint(mi_pedido.total)\n\n'''Aplicado'''\nclass Pedido_2:\n    def __init__(self) -> None:\n        self.comanda = []\n    \n    def agregar_plato(self,plato,precio,numero):\n        self.comanda.append((plato,precio,numero))\n        self.calcula_total()\n\n    def calcula_total(self):\n        total = 0\n        for plato,precio,numero in self.comanda:\n            parte = precio*numero\n            total += parte\n            print(f\"{plato} -> Precio: {precio} X {numero} -> {parte}\")\n        print(f\"------------Total: {total}€-------------\\n\")\n\n# Prueba\nmi_pedido_2 = Pedido_2()\nmi_pedido_2.agregar_plato(\"Pollo\",5.20,1)\nmi_pedido_2.agregar_plato(\"Coca Cola\",2.50,4)\nmi_pedido_2.agregar_plato(\"Cafe\",1.20,6)\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n * manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n * y el procesamiento de préstamos de libros.\n * Requisitos:\n * 1. Registrar libros: El sistema debe permitir agregar nuevos libros con \n * información básica como título, autor y número de copias disponibles.\n * 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n * información básica como nombre, número de identificación y correo electrónico.\n * 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n * tomar prestados y devolver libros.\n * Instrucciones:\n * 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n * los tres aspectos mencionados anteriormente (registro de libros, registro de\n * usuarios y procesamiento de préstamos).\n * 2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n * siguiendo el Principio de Responsabilidad Única.\n\"\"\"\n\n'''Sin Aplicar'''\n\nclass Librery:\n    def __init__(self) -> None:\n        self.users = {}\n        self.books = {}\n    \n    def add_book(self,name,autor,n_copy):\n        self.books[name.lower()] = [autor.lower(),n_copy]\n    \n    def add_user(self,user,id,email):\n        self.users[user.lower()] = [id,email.lower()]\n\n    def lend_book(self,name_book,user):\n        if user.lower() in self.users.keys():\n            if name_book.lower() in self.books.keys():\n                autor,copy = self.books[name_book.lower()]\n                if copy > 0:\n                    self.books[name_book.lower()][1] -= 1\n                    print(f\"{name_book} de {autor.title()} prestado a {user} con id {self.users[user.lower()][0]}\\n\")\n\n\n# Prueba\nmy_librery = Librery()\nmy_librery.add_book(\"Git y Github desde cero\",\"Brais Moure\", 5)\nmy_librery.add_user(\"Emmanuel\",1,\"emmanuelmmontesinos@xmail.com\")\nmy_librery.lend_book(\"Git y Github desde cero\",\"Emmanuel\")\n\n'''Aplicado'''\n\nclass User:\n    list_users = {}\n    def add_user(self,user,id,email):\n        User.list_users[user.lower()] = [id,email.lower()]\n\nclass Book:\n    list_books = {}\n    def add_book(self,name,autor,n_copy):\n        Book.list_books[name.lower()] = [autor.lower(),n_copy]\n    \n\nclass Librery_2:\n    list_users = User().list_users\n    list_books = Book().list_books\n\n    def add_book(self,name,autor,n_copy):\n        Book.add_book(Book,name,autor,n_copy)\n    \n    def add_user(self,user,id,email):\n        User.add_user(User,user,id,email)\n\n    def lend_book(self,name_book,user):\n        if user.lower() in Librery_2.list_users.keys():\n            if name_book.lower() in Librery_2.list_books.keys():\n                autor,copy = Librery_2.list_books[name_book.lower()]\n                if copy > 0:\n                    Librery_2.list_books[name_book.lower()][1] -= 1\n                    print(f\"{name_book} de {autor.title()} prestado a {user} con id {Librery_2.list_users[user.lower()][0]}\")\n\n# Prueba\n\nmy_librery_2 = Librery_2()\nmy_librery_2.add_book(\"Git y Github desde cero\",\"Brais Moure\", 5)\nmy_librery_2.add_user(\"Emmanuel\",17,\"emmanuelmmontesinos@xmail.com\")\nmy_librery_2.lend_book(\"Git y Github desde cero\",\"Emmanuel\")\n\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/Gordo-Master.py",
    "content": "# Solid SRP: Single Responsability Principle\n\n# Forma incorrecta: la clase usuario solo debe almacenar los datos del mismo, verificar si el email es correcto.\n\nclass Usuario():\n    \n    def __init__(self, name, email):\n        self.name = name\n        self.email = email\n\n    def check_email(self):\n        if \"@\" not in self.email:\n            raise ValueError(\"El email es invalido.\")\n\n# Forma correcta: se debe separar en dos clases\n\nclass Usuario2():\n    def __init__(self, name, email):\n        self.name = name\n        self.email = email\n    \nclass check_email():\n    def check(self, email):\n        if \"@\" not in email:\n            print(\"El email es invalido.\")\n        else:\n            print(\"Email correcto\")\n\nboy = Usuario2(\"Gordo-Master\", \"gordomastergmail.com\")\n\ndata_email = check_email()\n\ndata_email.check(boy.email)\n\n\"\"\"\nEjercicio extra\n\"\"\"\n\n\"\"\"\nclass Library():\n\n    def __init__(self, books = [], users = []):\n        self.books = books\n        self.users = users\n\n    def new_book(self, title: str, author: str, amount: int):\n        self.books.append([title, author, amount])\n\n    \n    def new_user(self, name: str, id: int, email: str):\n        self.users.append([name, id, email])\n\n    def borrow_book(self, user, book):\n        self.book_ubi = user\n        pass\n        \n\n    def return_book(self):\n        pass\n\nsanson = Library()\n\nsanson.new_book(\"One\", \"Carlos\", 5)\nsanson.new_book(\"Two\", \"Carlos\", 7)\nsanson.new_book(\"ABC\", \"Jose\", 5)\n\nsanson.new_user(\"Maria\",1,\"maria@gmail.com\")\nsanson.new_user(\"Belén\",2,\"belen@gmail.com\")\nsanson.new_user(\"Vanesa\",3,\"vanesa@gmail.com\")\n\nprint(sanson.books)\nprint(sanson.users)\n\n\"\"\"\n\n## Refactorización\n\nclass User():\n    def __init__(self, name: str, id: int, email: str):\n        self.name = name\n        self.id = id\n        self.email = email\n        self.book_borrowed = []\n    \n    def show(self):\n        print(f\"{self.name}, {self.id}, {self.email}\")\n\nclass Book():\n    def __init__(self, title: str, author: str, copies: int):\n        self.title = title\n        self.author = author\n        self.copies = copies\n\n    def show(self):\n        print(f\"{self.title}, {self.author}, {self.copies}\")\n\n\nclass Loan():\n    def __init__(self):\n        self.loans = []\n\n    def loan_book(self, user: User, book: Book):\n        if book.copies > 0:\n            book.copies -= 1\n            self.loans.append({\"id_user\": user.id, \"book_title\": book.title})\n            return True\n        return False\n    \n    def return_book(self, user: User, book: Book):\n        for loan in self.loans:\n            if loan[\"id_user\"] == user.id and loan[\"book_title\"] == book.title:\n                self.loans.remove(loan)\n                book.copies += 1\n                return True\n        return False\n    \n\n\nclass Library():\n    \n    def __init__(self):\n        self.books = []\n        self.users = []\n        self.loans_service = Loan()\n\n    def add_book(self, book):\n        self.books.append(book)\n\n    def add_user(self, user):\n        self.users.append(user)\n\n\n    def loan_book(self, user_id, book_title):\n        user = next((u for u in self.users if u.id == user_id),None)\n        book = next((b for b in self.books if b.title == book_title),None)  \n        if user and book:\n            return self.loans_service.loan_book(user,book)\n        return False\n    \n    def return_book(self, user_id, book_title):\n        user = next((u for u in self.users if u.id == user_id),None)\n        book = next((u for u in self.books if u.title == book_title),None)\n        if user and book:\n            return self.loans_service.return_book(user,book)\n        return False\n    \n\n\n\nu_1 = User(\"Jorge\", 1, \"jorge@gmail.com\")\nu_2 = User(\"Francisco\", 2, \"francisco@gmail.com\")\nu_3 = User(\"Lorenzo\", 3, \"lorenzo@gmail.com\")\n\nb_1 = Book(\"Harry Potter\", \"J. K. Rowling\", 7)\nb_2 = Book(\"Percy Jackson\", \"Rick Riordan\", 4)\nb_3 = Book(\"El mago de los libros\", \"JIM C. HINES \", 2)\n\nlibrary = Library()\n\nlibrary.add_book(b_1)\nlibrary.add_book(b_2)\nlibrary.add_book(b_3)\n\nlibrary.add_user(u_1)\nlibrary.add_user(u_2)\nlibrary.add_user(u_3)\n\nprint(library.loan_book(u_1.id,\"Harry Potter\"))\nprint(library.loan_book(u_1.id,\"HarryPotter\"))\n\nprint()\n\nprint(library.loan_book(u_1.id,\"El mago de los libros\"))\nprint(library.loan_book(u_2.id,\"El mago de los libros\"))\nprint(library.loan_book(u_3.id,\"El mago de los libros\"))"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/Jairo-Alejandro.py",
    "content": "\"\"\"*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n * Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n * manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n * y el procesamiento de préstamos de libros.\n * Requisitos:\n * 1. Registrar libros: El sistema debe permitir agregar nuevos libros con\n * información básica como título, autor y número de copias disponibles.\n * 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n * información básica como nombre, número de identificación y correo electrónico.\n * 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n * tomar prestados y devolver libros.\n * Instrucciones:\n * 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n * los tres aspectos mencionados anteriormente (registro de libros, registro de\n * usuarios y procesamiento de préstamos).\n * 2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n * siguiendo el Principio de Responsabilidad Única.\n *\"\"\"\n\n#-----------------------------------------------------------------------------\n#SRP Principio de responsabilidad unica \n# Las clases deben encargarse de una única responsabilidad; es decir, cada clase debe manejar una única tarea en el funcionamiento del sistema\n# ----------------------------------------------------------------------------\n\n# Ejemplo de uso incorrecto \nimport random\n\nclass SensorTemperature:\n    def __init__(self):\n        pass  \n\n    def read_sensor(self):\n        # Simulación de lectura del sensor\n        temperature = random.uniform(15.0, 50.0)\n        return round(temperature , 2)\n    \n    def alert(self):\n        temperature = self.read_sensor()\n        if temperature > 35.0:\n            print(f\"Critical temperature state: {temperature} °C\")\n        else :\n            print(f\"Stable temperature: {temperature} °c\")\n\nsensor = SensorTemperature()\nsensor.alert()\n\n# Ejemplo de uso correcto\n\nclass ReadTemperature: \n    def __init__(self):\n        pass \n\n    def read_sensor(self):\n        # Simulación de lectura del sensor\n        temperature = random.uniform(15.0, 50.0)\n        return round(temperature , 2)\n\nclass AlertTemperature:\n    def __init__(self):\n        pass\n\n    def alert(self, temperature):\n        \n        if temperature > 35.0:\n            print(f\"Critical temperature state: {temperature} °C\")\n        else :\n            print(f\"Stable temperature: {temperature} °c\")\n\n# Uso de las clases de manera correcta\nsensor = ReadTemperature()\nalert = AlertTemperature()\n\ntemperature = sensor.read_sensor()\nalert.alert(temperature)\n\n\n# DIFICULTAD EXTRA \n\nclass Library :\n\n    def __init__(self):\n         self.books = []\n         self.users = []\n         self.borrowedBooks = []\n    \n    def add_books(self, title , author , copies):\n        self.books.append({\"Title\": title, \"Author\": author, \"Copies\": copies})\n    \n    def add_users(self, name , Id , email):\n        self.users.append({\"Name\": name, \"Identification number\": Id , \"Email\":email })\n    \n    def borrow_books(self , user , title ):\n\n        for book in self.books :\n            if book[\"title\"] == title and book[\"copies\"] > 0:\n                book[\"copies\"] -= 1\n                self.borrowedBooks.append({\"user_id\": user, \"book_title\": title, \"action\": \"borrow\"})\n                return True\n        return False\n    \n    def return_books(self , user , title):\n\n        for book in self.books :\n            if book[\"title\"] == title and book[\"Copies\"] > 0:\n                book[\"copies\"] += 1\n                self.borrowedBooks.append({\"user_id\": user, \"book_title\": title, \"action\": \"borrow\"})\n                return True\n        return False\n    \n# usando el principio de responsabilidad unica \nclass Book:\n    def __init__(self, title, author, copies):\n        self.title = title\n        self.author = author\n        self.copies_available = copies\n\n    def borrow(self):\n        if self.copies_available > 0:\n            self.copies_available -= 1\n            return True\n        else:\n            return False\n\n    def return_book(self):\n        self.copies_available += 1\n\nclass User:\n    def __init__(self, name, id_number, email):\n        self.name = name\n        self.id_number = id_number\n        self.email = email\n\nclass Loan:\n    def __init__(self, user, book):\n        self.user = user\n        self.book = book\n\n    def borrow_book(self):\n        if self.book.borrow():\n            print(f\"Book '{self.book.title}' borrowed successfully by {self.user.name}.\")\n            return True\n        else:\n            print(\"Unable to borrow the book. Please check availability.\")\n            return False\n\n    def return_book(self):\n        self.book.return_book()\n        print(f\"Book '{self.book.title}' returned successfully.\")\n\n# Ejemplo de uso\nbook1 = Book(\"El principito\", \"Antoine de Saint-Exupéry\", 3)\nbook2 = Book(\"Cien años de soledad\", \"Gabriel García Márquez\", 5)\n\nuser1 = User(\"Juan Perez\", \"12345\", \"juan@example.com\")\nuser2 = User(\"María López\", \"54321\", \"maria@example.com\")\n\nloan1 = Loan(user1, book1)\nloan2 = Loan(user2, book2)\n\n# Procesar préstamos\nloan1.borrow_book()  \nloan2.borrow_book()  \n\n# Devolver libros\nloan1.return_book()  \n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/JheisonQuiroga.py",
    "content": "# Author: Jheison Duban Quiroga Quintero\n# Github: https://github.com/JheisonQuiroga\n\n\"\"\"/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n * Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n * \"\"\"\n\n# Violación del Single Responsibility Principle\n\nclass User:\n    users = []\n\n    def __init__(self, name, age, country):\n        self.name = name\n        self.age = age\n        self.country = country\n        print(\"Usuario creado!\")\n\n    def get_info(self):\n        return f\"{self.name}, {self.age}, {self.country}\"\n    \n    def save_to_db(self):\n        User.users.append(User(self.name, self.age, self.country))\n        print(\"Usuario guardado en la base de datos!\")\n\n\n# Siguiendo el SRP\n\nclass UserSRP:\n    def __init__(self, name, age, country):\n        self.name = name\n        self.age = age\n        self.country = country\n        print(\"Usuario creado!\")\n\n    def get_info(self):\n        return f\"{self.name}, {self.age}, {self.country}\"\n\nclass UserDB:\n    users = []\n\n    @classmethod\n    def save_user(cls, user: UserSRP) -> None:\n        cls.users.append(user)\n        print(\"Usuario guardado en la base de datos!\")\n\n    @classmethod\n    def get_users(cls):\n        for user in cls.users:\n            print(f\"{user.name}, {user.age}, {user.country}\")\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n * manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n * y el procesamiento de préstamos de libros.\n * Requisitos:\n * 1. Registrar libros: El sistema debe permitir agregar nuevos libros con\n * información básica como título, autor y número de copias disponibles.\n * 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n * información básica como nombre, número de identificación y correo electrónico.\n * 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n * tomar prestados y devolver libros.\n * Instrucciones:\n * 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n * los tres aspectos mencionados anteriormente (registro de libros, registro de\n * usuarios y procesamiento de préstamos).\n * 2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n * siguiendo el Principio de Responsabilidad Única.\n */\n\"\"\"\n\nclass Library:\n    def __init__(self):\n        self.books = {}\n        self.users = {}\n        self.rented_books = {}\n\n    def add_book(self, book_id, title, author, copies):\n        if book_id in self.books:\n            self.books[book_id]['copies'] += copies\n            print(f\"El libro {title}, ha sido guardado con {copies} copias.\")\n        else:\n            self.books[book_id] = {\n                \"title\": title,\n                \"author\": author,\n                \"copies\": copies\n            }\n            print(f\"El libro {title}, ha sido guardado con {copies} copias.\")\n        \n\n    def add_user(self, user_id, name, ni, email):\n        if user_id in self.users:\n            print(\"El usuario ya se encuentra registrado\")\n        else:\n            self.users[user_id] = {\n                \"name\": name,\n                \"document\": ni,\n                \"email\": email\n            }\n\n    def borrow_book(self, user_id, book_id):\n        if user_id not in self.users:\n            print(\"El usuario no existe\")\n            return False    # Detiene el método aquí\n        elif book_id not in self.books:\n            print(\"El libro no existe... :(\")\n            return False\n        \n        book = self.books[book_id]\n        if book['copies'] <= 0:\n            print(f\"No hay copias disponibles del libro {book['title']}\")\n            return False\n        \n        if book_id in self.rented_books.get(user_id, set()):\n            print(\"El usuario ya tiene el libro prestado!\")\n            return False\n            \n        book['copies'] -= 1\n        if user_id not in self.rented_books:\n            self.rented_books[user_id] = set()\n        self.rented_books[user_id].add(book_id)\n        \n        print(f\"El libro {book_id} ha sido prestado a {self.users[user_id]['name']}\")\n        return True\n    \n    def return_book(self, user_id, book_id):\n        if user_id not in self.rented_books or book_id not in self.rented_books[user_id]:\n            print(\"El usuario no tiene el libro registrado\")\n            return False\n        self.rented_books[user_id].remove(book_id)\n        self.books[book_id]['copies'] += 1\n        if not self.rented_books[user_id]:\n            del self.rented_books[user_id]\n        print(\"Libro devuelto correctamente\")\n        return True\n\n\n\n# Refactorizando el código siguiente el SRP\nclass Library2:\n    def __init__(self):\n        self.books = {}\n\n    def add_book(self, book_id, title, author, copies):\n        if book_id in self.books:\n            self.books[book_id]['copies'] += copies\n            print(f\"El libro {title}, ha sido guardado con {copies} copias.\")\n        else:\n            self.books[book_id] = {\n                \"title\": title,\n                \"author\": author,\n                \"copies\": copies\n            }\n            print(f\"El libro {title}, ha sido guardado con {copies} copias.\")\n\nclass LibraryUsers:\n    def __init__(self):\n        self.users = {}\n\n    def add_user(self, user_id, name, ni, email):\n        if user_id in self.users:\n            print(\"El usuario ya se encuentra registrado\")\n        else:\n            self.users[user_id] = {\n                \"name\": name,\n                \"document\": ni,\n                \"email\": email\n            }\n\nclass LoanLibrary:\n    def __init__(self, users, library):\n        self.rented_books = {}\n        self.user_manager: LibraryUsers = users\n        self.book_manager: Library2 = library\n    \n    def borrow_book(self, user_id, book_id):\n        if user_id not in self.user_manager.users:\n            print(\"El usuario no existe\")\n            return False    # Detiene el método aquí\n        elif book_id not in self.book_manager.books:\n            print(\"El libro no existe... :(\")\n            return False\n        \n        book = self.book_manager.books[book_id]\n        if book['copies'] <= 0:\n            print(f\"No hay copias disponibles del libro {book['title']}\")\n            return False\n        \n        if book_id in self.rented_books.get(user_id, set()):\n            print(\"El usuario ya tiene el libro prestado!\")\n            return False\n            \n        book['copies'] -= 1\n        if user_id not in self.rented_books:\n            self.rented_books[user_id] = set()\n        self.rented_books[user_id].add(book_id)\n        \n        print(f\"El libro {book_id} ha sido prestado a {self.user_manager.users[user_id]['name']}\")\n        return True\n    \n    def return_book(self, user_id, book_id):\n        if user_id not in self.rented_books or book_id not in self.rented_books[user_id]:\n            print(\"El usuario no tiene el libro registrado\")\n            return False\n        self.rented_books[user_id].remove(book_id)\n        self.book_manager.books[book_id]['copies'] += 1\n        if not self.rented_books[user_id]:\n            del self.rented_books[user_id]\n        print(\"Libro devuelto correctamente\")\n        return True\n\n\n\n# Clase principal que orquesta la gestión\nclass LibraryManager:\n    def __init__(self):\n        self.library = Library2()\n        self.user_manager = LibraryUsers()\n        self.loan_manager = LoanLibrary(self.user_manager, self.library)\n\n    def add_book(self, book_id, name, author, copies):\n        self.library.add_book(book_id, name, author, copies)\n\n    def add_user(self, user_id, name, ni, email):\n        self.user_manager.add_user(user_id, name, ni, email)\n\n    def borrow_book(self, user_id, book_id):\n        self.loan_manager.borrow_book(user_id, book_id)\n\n    def return_book(self, user_id, book_id):\n        self.loan_manager.return_book(user_id, book_id)\n\n\nif __name__ == \"__main__\":\n\n    l2 = LibraryManager()\n    l2.add_book(\"B000\", \"Python\", \"Yo\", 2)\n\n    l2.add_user(\"U001\", \"Duban\",1, \"jheison@\")\n    l2.borrow_book(\"U001\", \"B000\")\n    print(l2.library.books)\n    l2.return_book(\"U001\", \"B000\")\n    print(l2.library.books)"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/LuisOlivaresJ.py",
    "content": "# ---------------------------------------------\n# Ejemplo de Principio de responsabilidad única\n# ---------------------------------------------\n\n# El siguiente ejemplo muestra un código que viola el principio de responsabilidad única.\n# La clase ImageManager tiene dos responsabilidades: \n#   1.- Obtener estadísticas de una imagen\n#   2.- Graficar una imagen\n\nimport matplotlib.pyplot as plt\nimport numpy as np\n\nimport logging\n\n\nclass ImageManager:\n    def __init__(self, array):\n        self.array = array\n\n    def get_statistics(self):\n        return {\n            \"mean\": np.mean(self.array),\n            \"std\": np.std(self.array),\n        }\n    \n    def plot(self):\n        fig, ax = plt.subplots()\n        ax.plot(self.array)\n        plt.show()\n\n# Para cumplir con el principio de responsabilidad única, separamos las responsabilidades en dos clases diferentes.\n\nclass ImageStatistics:\n    def __init__(self, array):\n        self.array = array\n\n    def get_statistics(self):\n        return {\n            \"mean\": np.mean(self.array),\n            \"std\": np.std(self.array),\n        }\n    \nclass ImagePlotter:\n    def __init__(self, array):\n        self.array = array\n\n    def plot(self):\n        fig, ax = plt.subplots()\n        ax.plot(self.array)\n        plt.show()\n\n\n# ---------------------------------------------\n# Dificultad extra\n# Sistema de gestion para una bibioteca\n#\n# FORMA INCORRECTA\n#\n# ---------------------------------------------\n\nlogging.basicConfig(level=logging.INFO, format=\"%(asctime)s - %(message)s\")\n\nclass Library:\n    def __init__(self):\n        self.books = []\n        self.users = []\n\n    def add_user(self, name: str, id: int, email: str):\n        self.users.append({\n            \"name\": name,\n            \"id\": id,\n            \"email\": email,\n            \"books\": [],\n            }\n        )\n        logging.info(f\"User {name} added successfully\")\n\n    def add_book(self, title: str, author: str, copies: int):\n        self.books.append({\n            \"title\": title,\n            \"author\": author,\n            \"copies\": copies\n            }\n        )\n        logging.info(f\"Book {title} added successfully\")\n        \n    def print_books(self):\n        for book in self.books:\n            print(f\"\\tTitle: {book['title']}, Author: {book['author']}, Copies: {book['copies']}\")\n\n    def print_users(self):\n        for user in self.users:\n            print(f\"\\tName: {user['name']}, ID: {user['id']}, Email: {user['email']}, Books: {user['books']}\")\n\n    \n    def lend_book(self, title: str, name: str):\n\n        for book in self.books:\n            if book[\"title\"] == title:\n                if book[\"copies\"] > 0:\n                    book[\"copies\"] -= 1\n                    logging.info(f\"Book {title} borrowed by user {name}\")\n                else:\n                    logging.info(f\"Book {title} is not available\")\n                break\n            else:\n                logging.warning(f\"Book {title} not found\")\n\n        for user in self.users:\n            if user[\"name\"] == name:\n                user[\"books\"].append(\n                    {\n                        \"title\": title,\n                    }\n                )\n                logging.info(f\"Book {title} added to user {name}\")\n                break\n        \n    def return_book(self, title: str, name: str):\n\n        for book in self.books:\n            if book[\"title\"] == title:\n                book[\"copies\"] += 1\n                logging.info(f\"Book {title} returned by user {name}\")\n                break\n            else:\n                logging.warning(f\"Book {title} not found\")\n\n        for user in self.users:\n            if user[\"name\"] == name:\n                for book in user[\"books\"]:\n                    if book[\"title\"] == title:\n                        user[\"books\"].remove(book)\n                        logging.info(f\"Book {title} removed from user {name}\")\n                        break\n\n\n# Testing the class\nprint(\"\\n\"*3)\nprint(\"### Testing: Dificultad extra (FORMA INCORRECTA)\\n\")\nmy_library = Library()\nmy_library.add_user(\"Alice\", 1, \"alice@dev\")\nmy_library.add_user(\"Bob\", 2, \"bob@dev\")\n\nmy_library.add_book(\"The Hobbit\", \"J.R.R. Tolkien\", 5)\nmy_library.add_book(\"The Lord of the Rings\", \"J.R.R. Tolkien\", 3)\n\nprint(\"\\nBooks in the library:\")\nmy_library.print_books()\n\nmy_library.lend_book(\"The Hobbit\", \"Alice\")\n\nprint(\"\\nBooks in the library:\")\nmy_library.print_books()\nmy_library.print_users()\n\n\nmy_library.return_book(\"The Hobbit\", \"Alice\")\nmy_library.print_books()\nmy_library.print_users()\n\n\n# ---------------------------------------------\n# Dificultad extra\n# Sistema de gestion para una bibioteca\n#\n# Forma CORRECTA\n# \n# Se crean dos clases diferentes, BooksManager y UsersManager, para manejar los libros y a los usuarios.\n# Se crea una clase que maneja la biblioteca y delega las responsabilidades a las clases BooksManeger y UsersManager.\n# ---------------------------------------------\n\nclass BooksManeger:\n    def __init__(self):\n        self.books = []\n\n    def add_book(self, title: str, author: str, copies: int):\n        self.books.append(\n            {\"title\": title, \"author\": author, \"copies\": copies}\n        )\n        logging.info(f\"Book {title} added successfully\")\n\n    def print_books(self):\n        for book in self.books:\n            print(f\"\\tTitle: {book['title']}, Author: {book['author']}, Copies: {book['copies']}\")\n\n    def lend_book(self, title: str):\n        for book in self.books:\n            if book[\"title\"] == title:\n                if book[\"copies\"] > 0:\n                    book[\"copies\"] -= 1\n                    logging.info(f\"Book {title} borrowed\")\n                else:\n                    logging.info(f\"Book {title} is not available\")\n                break\n            else:\n                logging.warning(f\"Book {title} not found\")\n\n    def return_book(self, title: str):\n        for book in self.books:\n            if book[\"title\"] == title:\n                book[\"copies\"] += 1\n                logging.info(f\"Book {title} returned\")\n                break\n            else:\n                logging.warning(f\"Book {title} not found\")\n\n\nclass UsersManager:\n    def __init__(self):\n        self.users = []\n\n    def add_user(self, name: str, id: int, email: str):\n        self.users.append(\n            {\"name\": name, \"id\": id, \"email\": email, \"books\": []}\n        )\n        logging.info(f\"User {name} added successfully\")\n\n    def print_users(self):\n        for user in self.users:\n            print(f\"\\tName: {user['name']}, ID: {user['id']}, Email: {user['email']}, Books: {user['books']}\")\n\n    def lend_book(self, title: str, name: str):\n        for user in self.users:\n            if user[\"name\"] == name:\n                user[\"books\"].append({\"title\": title})\n                logging.info(f\"Book {title} added to user {name}\")\n                break\n            else:\n                logging.warning(f\"User {name} not found\")\n\n    def return_book(self, title: str, name: str):\n        for user in self.users:\n            if user[\"name\"] == name:\n                for book in user[\"books\"]:\n                    if book[\"title\"] == title:\n                        user[\"books\"].remove(book)\n                        logging.info(f\"Book {title} removed from user {name}\")\n                        break\n                break\n            else:\n                logging.warning(f\"User {name} not found\")\n\nclass Library_v2:\n    def __init__(self):\n        self.books_m = BooksManeger()\n        self.users_m = UsersManager()\n\n    def add_user(self, name: str, id: int, email: str):\n        self.users_m.add_user(name, id, email)\n\n    def add_book(self, title: str, author: str, copies: int):\n        self.books_m.add_book(title, author, copies)\n        \n    def print_books(self):\n        self.books_m.print_books()\n\n    def print_users(self):\n        self.users_m.print_users()\n\n    def lend_book(self, title: str, name: str):\n        self.books_m.lend_book(title)\n        self.users_m.lend_book(title, name)\n        \n    def return_book(self, title: str, name: str):\n        self.books_m.return_book(title)\n        self.users_m.return_book(title, name)\n\n\n# Testing the classes\nprint(\"\\n\"*3)\nprint(\"### Testing: Dificultad extra (FORMA CORRECTA)\\n\")\n\nmy_library_v2 = Library_v2()\nmy_library_v2.add_user(\"Alice\", 1, \"alice@dev\")\nmy_library_v2.add_user(\"Bob\", 2, \"bob@dev\")\n\nmy_library_v2.add_book(\"The Hobbit\", \"J.R.R. Tolkien\", 5)\nmy_library_v2.add_book(\"The Lord of the Rings\", \"J.R.R. Tolkien\", 3)\n\nprint(\"\\nBooks in the library:\")\nmy_library_v2.print_books()\n\nmy_library_v2.lend_book(\"The Hobbit\", \"Alice\")\n\nprint(\"\\nBooks in the library:\")\nmy_library_v2.print_books()\n\nprint(\"\\nUsers in the library:\")\nmy_library_v2.print_users()\n\nmy_library_v2.return_book(\"The Hobbit\", \"Alice\")\n\nprint(\"\\nBooks in the library:\")\nmy_library_v2.print_books()\n\nprint(\"\\nUsers in the library:\")\nmy_library_v2.print_users()"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/Mauricio-Leyva.py",
    "content": "# Implementación que viola SRP\nclass Library:\n    def __init__(self):\n        self.books = {}\n        self.users = {}\n        self.loans = {}\n\n    def add_book(self, title, author, copies):\n        if title not in self.books:\n            self.books[title] = {\"author\": author, \"copies\": copies, \"available\": copies}\n            print(f\"Libro '{title}' agregado con {copies} copias.\")\n        else:\n            print(f\"El libro '{title}' ya existe en el sistema.\")\n\n    def register_user(self, name, user_id, email):\n        if user_id not in self.users:\n            self.users[user_id] = {\"name\": name, \"email\": email}\n            print(f\"Usuario {name} registrado con ID {user_id}.\")\n        else:\n            print(f\"El usuario con ID {user_id} ya existe en el sistema.\")\n\n    def lend_book(self, user_id, title):\n        if user_id not in self.users:\n            print(f\"Usuario con ID {user_id} no encontrado.\")\n            return\n        if title not in self.books:\n            print(f\"Libro '{title}' no encontrado.\")\n            return\n        if self.books[title][\"available\"] == 0:\n            print(f\"No hay copias disponibles de '{title}'.\")\n            return\n        \n        self.books[title][\"available\"] -= 1\n        if user_id not in self.loans:\n            self.loans[user_id] = []\n        self.loans[user_id].append(title)\n        print(f\"Libro '{title}' prestado a usuario {user_id}.\")\n\n    def return_book(self, user_id, title):\n        if user_id not in self.loans or title not in self.loans[user_id]:\n            print(f\"El usuario {user_id} no tiene prestado el libro '{title}'.\")\n            return\n        \n        self.books[title][\"available\"] += 1\n        self.loans[user_id].remove(title)\n        print(f\"Libro '{title}' devuelto por usuario {user_id}.\")\n\n# Implementación que cumple con SRP\nclass Book:\n    def __init__(self, title, author, copies):\n        self.title = title\n        self.author = author\n        self.copies = copies\n        self.available = copies\n\nclass User:\n    def __init__(self, name, user_id, email):\n        self.name = name\n        self.user_id = user_id\n        self.email = email\n\nclass BookManager:\n    def __init__(self):\n        self.books = {}\n\n    def add_book(self, book):\n        if book.title not in self.books:\n            self.books[book.title] = book\n            print(f\"Libro '{book.title}' agregado con {book.copies} copias.\")\n        else:\n            print(f\"El libro '{book.title}' ya existe en el sistema.\")\n\nclass UserManager:\n    def __init__(self):\n        self.users = {}\n\n    def register_user(self, user):\n        if user.user_id not in self.users:\n            self.users[user.user_id] = user\n            print(f\"Usuario {user.name} registrado con ID {user.user_id}.\")\n        else:\n            print(f\"El usuario con ID {user.user_id} ya existe en el sistema.\")\n\nclass LoanManager:\n    def __init__(self, book_manager, user_manager):\n        self.loans = {}\n        self.book_manager = book_manager\n        self.user_manager = user_manager\n\n    def lend_book(self, user_id, title):\n        if user_id not in self.user_manager.users:\n            print(f\"Usuario con ID {user_id} no encontrado.\")\n            return\n        if title not in self.book_manager.books:\n            print(f\"Libro '{title}' no encontrado.\")\n            return\n        book = self.book_manager.books[title]\n        if book.available == 0:\n            print(f\"No hay copias disponibles de '{title}'.\")\n            return\n        \n        book.available -= 1\n        if user_id not in self.loans:\n            self.loans[user_id] = []\n        self.loans[user_id].append(title)\n        print(f\"Libro '{title}' prestado a usuario {user_id}.\")\n\n    def return_book(self, user_id, title):\n        if user_id not in self.loans or title not in self.loans[user_id]:\n            print(f\"El usuario {user_id} no tiene prestado el libro '{title}'.\")\n            return\n        \n        book = self.book_manager.books[title]\n        book.available += 1\n        self.loans[user_id].remove(title)\n        print(f\"Libro '{title}' devuelto por usuario {user_id}.\")\n\n# Uso del sistema refactorizado\nbook_manager = BookManager()\nuser_manager = UserManager()\nloan_manager = LoanManager(book_manager, user_manager)\n\nbook_manager.add_book(Book(\"1984\", \"George Orwell\", 5))\nbook_manager.add_book(Book(\"To Kill a Mockingbird\", \"Harper Lee\", 3))\n\nuser_manager.register_user(User(\"Ana García\", \"001\", \"ana@email.com\"))\nuser_manager.register_user(User(\"Pedro López\", \"002\", \"pedro@email.com\"))\n\nloan_manager.lend_book(\"001\", \"1984\")\nloan_manager.lend_book(\"002\", \"To Kill a Mockingbird\")\nloan_manager.return_book(\"001\", \"1984\")\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/Nicojsuarez2.py",
    "content": "# #26 SOLID: PRINCIPIO DE RESPONSABILIDAD ÚNICA (SRP)\n> #### Dificultad: Media | Publicación: 24/06/24 | Corrección: 01/07/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n * Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n * manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n * y el procesamiento de préstamos de libros.\n * Requisitos:\n * 1. Registrar libros: El sistema debe permitir agregar nuevos libros con \n * información básica como título, autor y número de copias disponibles.\n * 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n * información básica como nombre, número de identificación y correo electrónico.\n * 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n * tomar prestados y devolver libros.\n * Instrucciones:\n * 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n * los tres aspectos mencionados anteriormente (registro de libros, registro de\n * usuarios y procesamiento de préstamos).\n * 2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n * siguiendo el Principio de Responsabilidad Única.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/Pipe281.py",
    "content": "''' EJERCICIO:\n * Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n * Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n '''\n#SRP de forma Incorrecta\nclass Report:\n    def __init__(self, data):\n        self.data = data\n\n    def generate_report(self):\n        # Lógica para generar un reporte\n        return f\"Report data: {self.data}\"\n\n    def save_to_file(self, filename):\n        # Lógica para guardar el reporte en un archivo\n        with open(filename, 'w') as file:\n            file.write(self.generate_report())\n\n    def send_via_email(self, email):\n        # Lógica para enviar el reporte por correo electrónico\n        print(f\"Sending report to {email}\")\n\n# Uso de la clase\nreport = Report(\"Some important data\")\nreport.save_to_file(\"report.txt\")\nreport.send_via_email(\"example@example.com\")\n\n# SRP de Forma Correcta\nclass Report:\n    def __init__(self, data):\n        self.data = data\n\n    def generate_report(self):\n        return f\"Report data: {self.data}\"\n\nclass ReportSaver:\n    def save_to_file(self, report, filename):\n        with open(filename, 'w') as file:\n            file.write(report.generate_report())\n\nclass ReportSender:\n    def send_via_email(self, report, email):\n        print(f\"Sending report to {email}\")\n        # Aquí puedes agregar la lógica para enviar el correo electrónico\n\n# Uso de las clases refactorizadas\nreport = Report(\"Some important data\")\nsaver = ReportSaver()\nsender = ReportSender()\n\nsaver.save_to_file(report, \"report.txt\")\nsender.send_via_email(report, \"example@example.com\")"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/Sac-Corts.py",
    "content": "# Incorrecto\nclass Report:\n    def __init__(self, title, content):\n        self.title = title\n        self.content = content\n\n    def generate_report(self):\n        return f\"Title: {self.title}\\nContent: {self.content}\"\n\n    def save_to_file(self, filename):\n        with open(filename, 'w') as file:\n            file.write(self.generate_report())\n\nreport = Report(\"Monthly Report\", \"This is the content of the monthly report.\")\nprint(report.generate_report())\nreport.save_to_file(\"report.txt\")\n\n# Correcto\nclass Report:\n    def __init__(self, title, content):\n        self.title = title\n        self.content = content\n\n    def generate_report(self):\n        return f\"Title: {self.title}\\nContent: {self.content}\"\n\nclass ReportSaver:\n    @staticmethod\n    def save_to_file(report, filename):\n        with open(filename, 'w') as file:\n            file.write(report.generate_report())\n\nreport = Report(\"Monthly Report\", \"This is the content of the monthly report.\")\nprint(report.generate_report())\nReportSaver.save_to_file(report, \"report.txt\")\n\n### Ejercicio Extra ###\n\n# Incorrecto\n\nclass Library:\n    def __init__(self):\n        self.books = []\n        self.users = []\n        self.loans = []\n\n    def register_book(self, title, author, copies):\n        self.books[title] = {'author': author, 'copies': copies}\n\n    def register_user(self, user_id, name, email):\n        self.users[user_id] = {'name': name, 'email': email}\n\n    def borrow_book(self, user_id, title):\n        if title in self.books and self.books[title]['copies'] > 0:\n            self.books[title]['copies'] -= 1\n            self.loans.append({'user_id': user_id, 'title': title})\n        else: \n            print(\"Book not available\")\n\n    def return_book(self, user_id, title):\n        for loan in self.loans:\n            if loan['user_id'] == user_id and loan['title'] == title:\n                self.books[title]['copies'] += 1\n                self.loans.remove(loan)\n                break\n        else:\n            print(\"Loan record not found\")\n\n# Correcto\n\nclass BookManager:\n    def __init__(self):\n        self.books = {}\n\n    def register_book(self, title, author, copies):\n        self.books[title] = {'author': author, 'copies': copies}\n\n    def is_book_available(self, title):\n        return title in self.books and self.books[title]['copies'] > 0\n\n    def borrow_book(self, title):\n        if self.is_book_available(title):\n            self.books[title]['copies'] -= 1\n        else:\n            raise ValueError(\"Book not available\")\n\n    def return_book(self, title):\n        if title in self.books:\n            self.books[title]['copies'] += 1\n        else:\n            raise ValueError(\"Book not found\")\n        \nclass UserManager:\n    def __init__(self):\n        self.users = {}\n\n    def register_user(self, user_id, name, email):\n        self.users[user_id] = {'name': name, 'email': email}\n\n    def is_user_registered(self, user_id):\n        return user_id in self.users\n    \nclass LoanManager:\n    def __init__(self, book_manager, user_manager):\n        self.book_manager = book_manager\n        self.user_manager = user_manager\n        self.loans = []\n\n    def borrow_book(self, user_id, title):\n        if self.user_manager.is_user_registered(user_id):\n            self.book_manager.borrow_book(title)\n            self.loans.append({'user_id': user_id, 'title': title})\n        else:\n            raise ValueError(\"User not registered\")\n        \n    def return_book(self, user_id, title):\n        for loan in self.loans:\n            if loan['user_id'] == user_id and loan['title'] == title:\n                self.book_manager.return_book(title) \n                self.loans.remove(loan)\n                return\n        raise ValueError(\"Loan record not found\")\n\n\nbook_manager = BookManager()\nuser_manager = UserManager()\nloan_manager = LoanManager(book_manager, user_manager)\n\nbook_manager.register_book(\"The Great Gatsby\", \"F. Scott Fitzgerald\", 5)\n\nuser_manager.register_user(1, \"Isaac\", \"isaacgeo125@gmail.com\")\n\nloan_manager.borrow_book(1, \"The Great Gatsby\")\nloan_manager.return_book(1, \"The Great Gatsby\")"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/SooHav.py",
    "content": "# 26 SOLID: PRINCIPIO DE RESPONSABILIDAD ÚNICA (SRP)\nimport logging\n# Ejercicio\n# Ejemplo Pato sin SRP\n\n\nclass Pato:\n\n    def __init__(self, nombre):\n        self.nombre = nombre\n\n    def vuela(self):\n        print(f\"{self.nombre} vuela.\")\n\n    def nada(self):\n        print(f\"{self.nombre} nada.\")\n\n    def dice(self) -> str:\n        return \"Quack\"\n\n    def saluda(self, pato2):\n        print(f\"{self.nombre}: {self.dice()}, hola {pato2.nombre}\")\n\n\n# Uso\nprint(\"Sin SRP\")\npato1 = Pato(nombre=\"Daisy\")\npato2 = Pato(nombre=\"Donald\")\npato1.vuela()\npato1.nada()\npato1.saluda(pato2)\nprint(\"\\n\")\n\n# Ejemplo Pato con SRP\n\n\nclass Pato():\n    \"\"\"Clase que define los patos\"\"\"\n\n    def __init__(self, nombre):\n        self.nombre = nombre\n\n    def vuela(self):\n        print(f\"{self.nombre} vuela.\")\n\n    def nada(self):\n        print(f\"{self.nombre} nada.\")\n\n    def dice(self) -> str:\n        return \"Quack\"\n\n\nclass Dialogo():\n    \"\"\"Clase que define la comunicacion entre patos\"\"\"\n\n    def __init__(self, formato):\n        self.formato = formato\n\n    def conversacion(self, pato1: Pato, pato2: Pato):\n        frase1 = f\"{pato1.nombre}: {pato1.dice()}, ¡Ay, {\n            pato2.nombre}! ¡Casi me caigo al intentar atrapar un pez!\"\n        frase2 = f\"{pato2.nombre}: {pato2.dice()}, ¡Otra vez, {\n            pato1.nombre}? Ten más cuidado la próxima vez.\"\n        conversacion = [frase1, frase2]\n        print(*conversacion,\n              f\"(Extracto de {self.formato})\",\n              sep='\\n')\n\n\n# Uso\nprint(\"Con SRP\")\npato1 = Pato(nombre=\"Donald\")\npato2 = Pato(nombre=\"Daisy\")\npato1.vuela()\npato2.nada()\nformato1 = Dialogo(formato=\"historieta\")\nformato1.conversacion(pato1, pato2)\n\n# Extra\n# Programa sin SRP\n\n\nclass GestorBiblioteca():\n    \"\"\"\n    Clase que gestiona una biblioteca.\n    \"\"\"\n\n    def __init__(self):\n        self.registro = {}\n        self.usuarios = {}\n\n    def registro_libros(self, id, titulo, autor, cantidad_copias, max_prestamo):\n        \"\"\"\n        Funcion que registra un libro.\n        \"\"\"\n        nuevo_libro = {\n            \"titulo\": titulo,\n            \"autor\": autor,\n            \"cantidad_copias\": cantidad_copias,\n            \"max_prestamo\": max_prestamo\n        }\n        self.registro[id] = nuevo_libro\n        print(f\"Libro '{titulo}' agregado con éxito.\")\n\n    def agregar_usuario(self,  id, nombre, dni, email):\n        \"\"\"\n        Funcion que permite agregar nuevos usuarios con información básica.\n        \"\"\"\n        nuevo_usuario = {\n            \"nombre\": nombre,\n            \"dni\": dni,\n            \"email\": email\n        }\n        self.usuarios[id] = nuevo_usuario\n        print(f\"Usuario '{nombre}' agregado con éxito.\")\n\n    def prestamo_libro(self, titulo, nombre):\n        \"\"\"\n        Funcion para que los usuarios puedan tomar prestados libros.\n        \"\"\"\n        usuario_registrado = False\n        for usuario in self.usuarios.values():\n            if usuario[\"nombre\"] == nombre:\n                usuario_registrado = True\n                break\n\n        if not usuario_registrado:\n            print(f\"Usuario '{\n                  nombre}' no está registrado. No puede tomar prestado libros para llevar a casa.\")\n            return\n\n        libro_prestado = None\n        cantidad_actual = None\n\n        for id, nuevo_registro in self.registro.items():\n            if nuevo_registro[\"titulo\"] == titulo:\n                libro_prestado = nuevo_registro\n                cantidad_actual = nuevo_registro[\"cantidad_copias\"]\n                max_prestamo = nuevo_registro[\"max_prestamo\"]\n                break\n\n        if libro_prestado:\n            if cantidad_actual > 0 and cantidad_actual <= max_prestamo:\n                cantidad_actual -= 1\n                libro_prestado[\"cantidad_copias\"] = cantidad_actual\n                print(f\"Libro '{titulo}' prestado con éxito a {nombre}.\")\n            else:\n                print(f\"Libro '{\n                      titulo}' no tiene copias disponibles o se ha excedido el máximo préstamo.\")\n        else:\n            print(f\"Libro '{titulo}' sin existencias.\")\n\n    def devolucion_libro(self, titulo, nombre):\n        \"\"\"\n        Funcion para que los usuarios puedan devolver libros.\n        \"\"\"\n        usuario_registrado = False\n        for usuario in self.usuarios.values():\n            if usuario[\"nombre\"] == nombre:\n                usuario_registrado = True\n                break\n\n        if not usuario_registrado:\n            print(f\"Usuario '{\n                  nombre}' no está registrado. Pida el nombre o id de la persona que tomo prestado el libro.\")\n            return\n\n        libro_devuelto = None\n\n        for id, nuevo_registro in self.registro.items():\n            if nuevo_registro[\"titulo\"] == titulo:\n                libro_devuelto = nuevo_registro\n                cantidad_actual = nuevo_registro[\"cantidad_copias\"]\n                max_prestamo = nuevo_registro[\"max_prestamo\"]\n                break\n\n        if libro_devuelto:\n            cantidad_actual_nueva = cantidad_actual + 1\n            if cantidad_actual_nueva <= max_prestamo:\n                cantidad_actual += 1\n                libro_devuelto[\"cantidad_copias\"] = cantidad_actual\n                print(f\"Libro '{titulo}' devuelto con éxito por {nombre}.\")\n            else:\n                print(\n                    f\"Se ha superado el límite máximo de libros para '{titulo}'.\")\n        else:\n            print(f\"Libro '{titulo}' no pertenece a la biblioteca.\")\n\n    def listar_libros(self):\n        \"\"\"\n        Muestra una lista de los libros en existencia.\n        \"\"\"\n        if self.registro:\n            print(\"Lista de Libros:\")\n            for id, nuevo_registro in self.registro.items():\n                titulo = nuevo_registro[\"titulo\"]\n                cantidad_copias = nuevo_registro[\"cantidad_copias\"]\n                print(f\"- {titulo}: {cantidad_copias}\")\n        else:\n            print(\"No hay libros registrados.\")\n\n\n# Uso\ngestor = GestorBiblioteca()\n\n# Registrar libros\ngestor.registro_libros(1, \"Cien años de Soledad\", \"Garcia Marquez\", 3, 3)\ngestor.registro_libros(\n    2, \"Harry Potter: la píedra filosofal\", \"Jk Rowling\", 3, 3)\ngestor.registro_libros(\n    3, \"El señor de los anillos: la comunidad del anillo\", \"JRR Tolkien\", 3, 2)\n\n# Agregar usuario\ngestor.agregar_usuario(1, \"Sofia\", 456789, \"soo@soo.com\")\ngestor.agregar_usuario(2, \"Juan\", 456789, \"juan@juan.com\")\n\n# Transaccion\ngestor.prestamo_libro(\"Cien años de Soledad\", \"Sofia\")\ngestor.prestamo_libro(\"Cien años de Soledad\", \"Sofia\")\ngestor.prestamo_libro(\"Cien años de Soledad\", \"Juan\")\ngestor.prestamo_libro(\n    \"El señor de los anillos: la comunidad del anillo\", \"Lucas\")\ngestor.prestamo_libro(\"Harry Potter: la píedra filosofal\", \"Sofia\")\ngestor.prestamo_libro(\"Harry Potter: la píedra filosofal\", \"Juan\")\ngestor.prestamo_libro(\"Harry Potter: la píedra filosofal\", \"Juan\")\ngestor.prestamo_libro(\"Harry Potter: la píedra filosofal\", \"Juan\")\ngestor.devolucion_libro(\"Cien años de Soledad\", \"Sofia\")\ngestor.devolucion_libro(\"Cien años de Soledad\", \"Sofia\")\n\n# Lista\ngestor.listar_libros()\n\n# Gestor de Biblioteca con SRP\n# Configurar Logger\nlogger = logging.getLogger(__name__)\nlogger.setLevel(logging.WARNING)\nconsole_handler = logging.StreamHandler()\nconsole_handler.setLevel(logging.WARNING)\nconsole_format = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')\nconsole_handler.setFormatter(console_format)\nlogger.addHandler(console_handler)\n\n\nclass RegistroError(Exception):\n    pass\n\n\nclass RegistroBiblioteca():\n    def __init__(self):\n        self.biblioteca = {}\n        self.usuarios = {}\n\n    def registro_libros(self, id, titulo, autor, cantidad_copias, max_prestamo):\n        logger.debug(\"Iniciando el registro de un libro.\")\n        nuevo_libro = {\n            \"titulo\": titulo,\n            \"autor\": autor,\n            \"cantidad_copias\": cantidad_copias,\n            \"max_prestamo\": max_prestamo\n        }\n        self.biblioteca[id] = nuevo_libro\n        logger.info(f\"Libro '{titulo}' agregado con éxito.\")\n\n    def registro_usuario(self, id, nombre, dni, email):\n        logger.debug(\"Iniciando el registro de un usuario.\")\n        nuevo_usuario = {\n            \"nombre\": nombre,\n            \"dni\": dni,\n            \"email\": email\n        }\n        self.usuarios[id] = nuevo_usuario\n        logger.info(f\"Usuario '{nombre}' agregado con éxito.\")\n\n    def verificacion_registro(self, tipo, titulo_o_nombre):\n        logger.debug(\"Iniciando la verificación de un registro.\")\n        if tipo == \"libro\":\n            for libro in self.biblioteca.values():\n                if libro[\"titulo\"] == titulo_o_nombre:\n                    logger.info(\"Libro registrado\")\n                    return True\n        elif tipo == \"usuario\":\n            for usuario in self.usuarios.values():\n                if usuario[\"nombre\"] == titulo_o_nombre:\n                    logger.info(\"Usuario registrado\")\n                    return True\n        logger.error(f\"{tipo.capitalize()} '{titulo_o_nombre}' no registrado\")\n        return False\n\n\nclass TransaccionBiblioteca():\n    \"\"\"\n    Clase que gestiona las transacciones de prestamo y devolucion de una biblioteca.\n    \"\"\"\n\n    def __init__(self, registro_biblioteca):\n        self.registro_biblioteca = registro_biblioteca\n\n    def prestamo_libro(self, titulo, nombre):\n        logger.debug(\"Iniciando el prestamo de un libro.\")\n        try:\n            if not self.registro_biblioteca.verificacion_registro(\"usuario\", nombre):\n                logger.error(f\"Usuario '{nombre}' no está registrado.\")\n                return\n\n            libro_prestado = None\n            for id, nuevo_registro in self.registro_biblioteca.biblioteca.items():\n                if nuevo_registro[\"titulo\"] == titulo:\n                    libro_prestado = nuevo_registro\n                    logger.info(\"Coincidencia en la busqueda\")\n                    break\n            if libro_prestado:\n                if libro_prestado[\"cantidad_copias\"] > 0:\n                    libro_prestado[\"cantidad_copias\"] -= 1\n                    print(\n                        f\"Libro '{titulo}' prestado con éxito a {nombre}.\")\n                else:\n                    logger.warning(\n                        f\"Libro '{titulo}' no tiene copias disponibles.\")\n            else:\n                logger.error(f\"Libro '{titulo}' no pertenece a la biblioteca.\")\n        except RegistroError as e:\n            print(e)\n\n    def devolucion_libro(self, titulo, nombre):\n        logger.debug(\"Iniciando la devoluciòn de un libro.\")\n        try:\n            if not self.registro_biblioteca.verificacion_registro(\"usuario\", nombre):\n                logger.error(f\"Usuario '{nombre}' no está registrado.\")\n                return\n\n            libro_devuelto = None\n            for id, nuevo_registro in self.registro_biblioteca.biblioteca.items():\n                if nuevo_registro[\"titulo\"] == titulo:\n                    libro_devuelto = nuevo_registro\n                    logger.info(\"Coincidencia en la busqueda\")\n                    break\n            if libro_devuelto:\n                libro_devuelto[\"cantidad_copias\"] += 1\n                print(\n                    f\"Libro '{titulo}' devuelto con éxito por {nombre}.\")\n            else:\n                logger.error(f\"Libro '{titulo}' no pertenece a la biblioteca.\")\n        except RegistroError as e:\n            print(e)\n\n\nclass Existencias():\n    def __init__(self, registro_biblioteca):\n        self.registro_biblioteca = registro_biblioteca\n\n    def listar_libros(self):\n        \"\"\"\n        Muestra una lista de los libros en existencia.\n        \"\"\"\n        logger.debug(\"Recopilando los libros registrados en la biblioteca.\")\n        if self.registro_biblioteca.biblioteca:\n            print(\"Lista de Libros:\")\n            for id, nuevo_registro in self.registro_biblioteca.biblioteca.items():\n                titulo = nuevo_registro[\"titulo\"]\n                cantidad_copias = nuevo_registro[\"cantidad_copias\"]\n                print(f\"- {titulo}: {cantidad_copias}\")\n        else:\n            logger.warning(\"No hay libros registrados.\")\n\n\n# Uso\nregistro = RegistroBiblioteca()\ntransaccion = TransaccionBiblioteca(registro)\nexistencias = Existencias(registro)\n\n# Registro libros\nregistro.registro_libros(1, \"Cien años de Soledad\", \"Garcia Marquez\", 3, 3)\nregistro.registro_libros(\n    2, \"Harry Potter: la piedra filosofal\", \"Jk Rowling\", 3, 3)\nregistro.registro_libros(\n    3, \"El señor de los anillos: la comunidad del anillo\", \"JRR Tolkien\", 3, 2)\n\n# Registro usuarios\nregistro.registro_usuario(1, \"Sofia\", 456789, \"soo@soo.com\")\nregistro.registro_usuario(2, \"Juan\", 456789, \"juan@juan.com\")\n\n# Transacciones\ntransaccion.prestamo_libro(\"Cien años de Soledad\", \"Sofia\")\ntransaccion.prestamo_libro(\"Cien años de Soledad\", \"Sofia\")\ntransaccion.prestamo_libro(\"Cien años de Soledad\", \"Juan\")\ntransaccion.prestamo_libro(\"Harry Potter: la piedra filosofal\", \"Sofia\")\ntransaccion.prestamo_libro(\"Harry Potter: la piedra filosofal\", \"Juan\")\ntransaccion.devolucion_libro(\"Cien años de Soledad\", \"Sofia\")\ntransaccion.devolucion_libro(\"Cien años de Soledad\", \"Sofia\")\n\n# Listar libros\nexistencias.listar_libros()\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/Trufoplus.py",
    "content": "###############################################################################\n### EJERCICIO\n###############################################################################\n# Una clase que gestiona 3 responsabilidades, sin aplicar SRP.\nclass shop:\n    \"\"\"\n    Una clase que gestiona las diferentes responsabilidades de una tienda.\n    \"\"\"\n    def __init__(self):\n        self.products = {}\n    \n    def add_product(self, product:str, price:str, amount:int):\n        \"\"\"\n        Agrega un producto a la tienda\n        \"\"\"\n        self.products[product] = (price, amount)\n    \n    def del_product(self, product:str):\n        \"\"\"\n        Elimina un producto de la tienda\n        \"\"\"\n        if product in self.products:\n            del self.products[product]\n        else:\n            print(f\"El producto {product} no existe en la tienda.\")\n    \n    def search_product(self, product:str):\n        \"\"\"\n        Busca si un producto en la tienda\n        \"\"\"\n        if product in self.products:\n            return self.products[product]\n        else:\n            print(f\"El producto {product} no existe en la tienda.\")\n\n\n\n# Refactorizamos aplicando SRP, separando las tres responsabilidades en diferentes clases.\nclass Shop:\n    \"\"\"\n    Responsabilidad de los productos de la tienda\n    \"\"\"\n    def __init__(self):\n        self.products = {}\n\n        \nclass AddProduct:\n    \"\"\"\n    Responsabilidad de agregar un producto a la tienda\n    \"\"\" \n    @staticmethod\n    def add_product(shop: Shop, product:str, price:str, amount:int):\n        Shop.products[product] = (price, amount)\n\n\nclass DelProduct:\n    \"\"\"\n    Responsabilidad de borrar un producto de la tienda\n    \"\"\"\n    @staticmethod\n    def del_product(shop: Shop, product:str):\n        if product in Shop.products:\n            del Shop.products[product]\n        else:\n            print(f\"El producto {product} no existe en la tienda.\")\n\n\nclass SearchProduct: \n    \"\"\"\n    Responsabilidad de buscar si un producto esta en la tienda\n    \"\"\"\n    @staticmethod   \n    def search_product(shop: Shop, product:str):\n        if product in Shop.products:\n            return Shop.products[product]\n        else:\n            print(f\"El producto {product} no existe en la tienda.\")\n\n\n\n\n###############################################################################\n### DIFICULTAD EXTRA\n###############################################################################\nimport logging\n\nlogging.basicConfig(level=logging.INFO)\n\n\nclass Library:\n    \"\"\"\n    Registro de libros y usuarios de la biblioteca\n    \"\"\"\n    def __init__(self):\n        self.books = {}\n        self.users = {}\n        self.books_loaned = {}\n\n\nclass RegisterBooks:\n    \"\"\"\n    Registra un libro en la biblioteca\n    \"\"\"\n    @staticmethod\n    def register_book(library: Library, title: str, author: str, amount: int):\n        library.books[title] = [author, amount]\n        logging.info(f\"Book '{title}' by {author} has been registered with {amount} copies.\")\n\n\nclass RegisterUser:\n    \"\"\"\n    Registra a un usuario en la base de datos\n    \"\"\"\n    def register_user(library: Library, user_name: str, user_id: int, email: str):\n        library.users[user_name] = [user_id, email]\n        logging.info(f\"User '{user_name}' has been registered with ID {user_id} and email {email}.\")\n\n\nclass LoanBooks:\n    \"\"\"\n    Presta un libro a un usuario\n    \"\"\"\n    @staticmethod\n    def loan(library: Library, title, user_name):\n        if title not in library.books:\n            logging.info(f\"The book '{title}' is not available in the library.\")\n            return\n        if library.books[title][1] <= 0:\n            logging.info(f\"No copies of the book '{title}' are available.\")\n            return\n        if user_name not in library.users:\n            logging.info(f\"The user '{user_name}' is not registered.\")\n            return       \n        library.books_loaned[title] = user_name\n        library.books[title][1] -= 1\n        logging.info(f'The book \"{title}\" has been loaned to \"{user_name}\".')\n        logging.info(f'{title}: {library.books[title]}')\n\n\nclass GiveBack:\n    \"\"\"\n    Devuelve un libro prestado\n    \"\"\"\n    @staticmethod\n    def give_back(library: Library, title, user_name):\n        if title not in library.books_loaned:\n            logging.info(f'The book \"{title}\" is not currently loaned.')\n            return\n        if library.books_loaned[title] != user_name:\n            logging.info(f'The book \"{title}\" was not loaned to \"{user_name}\".')\n            return\n        del library.books_loaned[title]\n        library.books[title][1] += 1\n        logging.info(f'The book \"{title}\" has been returned by \"{user_name}\".')\n        logging.info(f'{title}: {library.books[title]}')\n   \n\n# Creamos nuestra biblioteca\nmi_biblioteca = Library()\n# Registramos un libro\nRegisterBooks.register_book(mi_biblioteca, 'Atomic Habits', 'James Clear', 5)\n# Registramos a un usuario\nRegisterUser.register_user(mi_biblioteca, 'Dani', 1, 'dani@gmail.com')\n# Le prestamos un libro\nLoanBooks.loan(mi_biblioteca, 'Atomic Habits', 'Dani')\n# Devuelve el libro\nGiveBack.give_back(mi_biblioteca, 'Atomic Habits', 'Dani')"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/adra-dev.py",
    "content": "\"\"\"\nEJERCICIO:\nExplora el \"Principio SOLID de Responsabilidad Única (Single \nResponsability Principle, SRP)\" y crea un ejemplo simple donde se \nmuestre su funcionamienot de forma correcta e incorrecta.\n\nDIFICULTAD EXTRA(opcional):\nDesarrolla un sistema de gestión para una biblioteca. El sistema \nnecesita manejar diferentes aspectos como el registro de libros, la \ngestión de usuarios y el procesamiento de préstamos de libros.\nRequisitos:\n1. Registrar libros: El sistema debe permitir agregar nuevos libros \ncon información básica como título, autor y número de copias \ndisponibles.\n2. Registrar usuarios: El sistema debe permitir agregar nuevos \nusuarios con información básica como nombre, número de identificación\ny correo electrónico.\n3. Procesar préstamos de libros: El sistema debe permitir a los \nusuarios tomar prestados y devolver libros.\nInstrucciones:\n1. Diseña una clase que no cumple el SRP: Crea una clase Library que \nmaneje los tres aspectos mencionados anteriormente (registro de \nlibros, registro de usuarios y procesamiento de préstamos).\n2. Refactoriza el código: Separa las responsabilidades en diferentes \nclases siguiendo el Principio de Responsabilidad Única.\n\nby adra-dev\n\"\"\"\n\n\"\"\"\nSingle Responsability Principle (SRP):\nCreado por Robert C. Martin, mejor conocido como tío bob, y declarado\nen el Manifiesto Ágil establece lo siguiente:\n\n\"Una clase debe tener una única razón para cambiar.\"\n\nEsto significa que una clase solo debe tener una responsabilidad, si \nuna clase toma más de una tarea entonces dicha clase debe separarse en \n2 clases diferentes.\n\ndocumentacion:\"https://realpython.com/solid-principles-python/\"\n\n\"\"\"\n\nfrom pathlib import Path\nfrom zipfile import ZipFile\n\nclass FileManager:\n    def __init__(self, filename):\n        self.path = Path(filename)\n\n    def read(self, encoding=\"utf-8\"):\n        return self.path.read_text(encoding)\n    \n    def write(self, data, encoding=\"utf-8\"):\n        return self.path.write_text(data, encoding)\n    \n    def compress(self):\n        with ZipFile(self.path.with_suffix(\".zip\"), mode=\"w\") as archive:\n            archive.write(self.path)\n\n    def decompress(self):\n        with ZipFile(self.path.with_suffix(\".zip\"), mode=\"r\") as archive:\n            archive.extractall()\n\n\"\"\"\nEn el ejemplo se puede observar que la calse FileManager tiene 2 \nresponsabilidades diferentes. Esta usa los metodos .read() y .write()\npara manejar los archivos. Pero tambien maneja la compression y \ndescompresion de los archivos usando .compress() y decompress() por \nlo que esta clase viola el principio de responsabilidad unica debido \na que tiene 2 razones por las cules cambiar su implementacion interna.\n\"\"\"\n\nclass FileManager:\n    def __init__(self, filename) -> None:\n        self.path = Path(filename)\n\n    def read(self, encoding=\"utf-8\"):\n        return self.path.read_text(encoding)\n    \n    def write(self, data, encoding=\"utf-8\"):\n        return self.path.write_text(data, encoding)\n    \nclass ZipFileManager:\n    def __init__(self, filename) -> None:\n        self.path = Path(filename)\n\n    def compress(self):\n        with ZipFile(self.path.with_suffix(\".zip\"), mode=\"w\") as archive:\n            archive.write(self.path)\n\n    def decompress(self):\n        with ZipFile(self.path.with_suffix(\".zip\"), mode=\"r\") as archive:\n            archive.extractall()\n\n# Ahora de manera correcta se tienen 2 clases con una sola responsabilidad.\n\n\n\"\"\"\nExtra\n\"\"\"\n\n# Incorrecto\n\nclass Library:\n\n    def __init__(self) -> None:\n        self.books = []\n        self.users = []\n        self.loans = []\n\n    def add_book(self, title, author, copies):\n        self.books.append({\"title\": title, \"author\": author, \"copies\":copies})\n\n    def add_user(self, name, id, email):\n        self.users.append({\"name\": name, \"id\": id, \"email\":email})\n\n    def loan_book(self, user_id, book_title):\n        for book in self.books:\n            if book[\"title\"] == book_title and book[\"copies\"] > 0:\n                book[\"copies\"] -= 1\n                self.loans.append(\n                    {\"user_id\": user_id, \"book_title\": book_title}) \n                return True\n        return False\n    \n    def return_book(self, user_id, book_title):\n        for loan in self.loans:\n            if loan[\"user_id\"] == user_id and loan[\"book_title\"] == book_title:\n                self.loans.remove(loan)\n                for book in self.books:\n                    if book[\"title\"] == book_title:\n                        book[\"copies\"] += 1\n                    return True\n        return False\n    \n\n# Correcto\n\n\nclass Book:\n\n    def __init__(self, title, author, copies):\n        self.title = title\n        self.author = author\n        self.copies = copies\n\n\nclass User:\n\n    def __init__(self, name, id, email):\n        self.name = name\n        self.id = id\n        self.email = email\n\n\nclass Loan:\n\n    def __init__(self):\n        self.loans = []\n\n    def loan_book(self, user, book):\n        if book.copies > 0:\n            book.copies -= 1\n            self.loans.append(\n                    {\"user_id\": user.id, \"book_title\": book.title}) \n            return True\n        return False\n    \n\n    def return_book(self, user, book):\n        for loan in self.loans:\n            if loan[\"user_id\"] == user.id and loan[\"book_title\"] == book.title:\n                self.loans.remove(loan)\n                book.copies +=1\n                return True\n        return False\n    \n\nclass Library:\n\n    def __init__(self) -> None:\n        self.books = []\n        self.users = []\n        self.loans_service = Loan()\n\n    def add_book(self, book):\n        self.books.append(book)\n\n    def add_user(self, user):\n        self.users.append(user)\n\n    def loan_book(self, user_id, book_title):\n        user = next((u for u in self.users if u.id == user_id), None)\n        book = next((b for b in self.books if b.title == book_title), None)\n        if user and book:\n            return self.loans_service.loan_book(user, book)\n        return False\n    \n    def return_book(self, user_id, book_title):\n        user = next((u for u in self.users if u.id == user_id), None)\n        book = next((b for b in self.books if b.title == book_title), None)\n        if user and book:\n            return self.loans_service.return_book(user, book)\n        return False"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/agusrosero.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n * Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n\"\"\"\n\n# Forma incorrecta\n\n\nclass Incorrecta:\n    def __init__(self, name, position):\n        self.name = name\n        self.position = position\n\n    def get_details(self):\n        return f\"Empleado: {self.name}, Posicion: {self.position}\"\n\n    def generate_report(self):\n        return f\"Generando reporte para empleado: {self.name}\"\n\n# Forma correcta\n\n\nclass Correcta:\n    def __init__(self, name, position):\n        self.name = name\n        self.position = position\n\n    def get_details(self):\n        return f\"Empleado: {self.name}, Posicion: {self.position}\"\n\n\nclass Correcta2:\n    def __init__(self, employee):\n        self.employee = employee\n\n    def generate_report(self):\n        return f\"Generando reporte para empleado: {self.employee.name}\"\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n * manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n * y el procesamiento de préstamos de libros.\n * Requisitos:\n * 1. Registrar libros: El sistema debe permitir agregar nuevos libros con \n * información básica como título, autor y número de copias disponibles.\n * 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n * información básica como nombre, número de identificación y correo electrónico.\n * 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n * tomar prestados y devolver libros.\n * Instrucciones:\n * 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n * los tres aspectos mencionados anteriormente (registro de libros, registro de\n * usuarios y procesamiento de préstamos).\n * 2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n * siguiendo el Principio de Responsabilidad Única.\n */\n\"\"\"\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/alanshakir.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n * Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n * manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n * y el procesamiento de préstamos de libros.\n * Requisitos:\n * 1. Registrar libros: El sistema debe permitir agregar nuevos libros con \n * información básica como título, autor y número de copias disponibles.\n * 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n * información básica como nombre, número de identificación y correo electrónico.\n * 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n * tomar prestados y devolver libros.\n * Instrucciones:\n * 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n * los tres aspectos mencionados anteriormente (registro de libros, registro de\n * usuarios y procesamiento de préstamos).\n * 2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n * siguiendo el Principio de Responsabilidad Única.\n */\n\"\"\"\n\n#incorrecta\n\nclass Employees:\n\n    def __init__(self) -> None:\n        self.dni\n        self.name\n        self.surname\n        self.birthdate\n        self.date_of_hire\n        \n    \n    def employee(self, dni, name, surname, birthdate, date_of_hire):\n        self.dni = dni\n        self.name = name\n        self.surname = surname\n        self.birthdate = birthdate\n        self.date_of_hire = date_of_hire\n        \n\n    def salary(self, dni, hours_worked, hours_price):\n        return f\"El salario del {dni} es: {hours_worked * hours_price}\"\n    \n    def vacations(self, dni, start_time, end_time):\n        return f\"Dias de vacaciones pendientes para {dni} es: {end_time-start_time}\"\n\n#Correcta\nclass Employees:\n\n    def __init__(self) -> None:\n        self.dni\n        self.name\n        self.surname\n        self.birthdate\n        self.date_of_hire\n        \n    \n    def employee(self, dni, name, surname, birthdate, date_of_hire):\n        self.dni = dni\n        self.name = name\n        self.surname = surname\n        self.birthdate = birthdate\n        self.date_of_hire = date_of_hire\n\nclass payroll:\n    def __init__(self) -> None:\n        self.hours_worked\n        self.hours_price\n        self.start_time\n        self.end_time\n        DAYSVACATION = 21  #vacaciones proporcionadas por la empresa\n    \n    def salary(self, hours_worked, hours_price):\n        return f\"El salario es: {hours_worked * hours_price}\"\n    \n    def vacations(self, start_time,end_time):\n        return f\"Dias de vacaciones a disfrutar {end_time-start_time}\"\n    \n    def pending_vacancies(self, start_time,end_time, DAYSVACATION):\n        return f\"Cantidad de dias pendientes de vacaciones: {DAYSVACATION -(end_time-start_time) }\"\n    \n#EXTRA\n\nclass LibraryManager:\n\n    def __init__(self) -> None:\n        self.list_book = {}\n        self.list_users = {}\n        self.list_loans = {}\n        \n    def add_book(self, title, author, copies):\n        if title in self.list_book:\n            print(f\"Titulo {title} ya existe\")\n            return\n        self.list_book[title] = {\"author\": author,\n                                 \"copies\": copies}\n        print(f\"Titulo {title} fue agregado correctamente\")\n    \n    def add_user(self, name, dni, email):\n        if name in self.list_users:\n            print(f\"Usuario {name} ya se encuentra registrado\")\n            return\n        self.list_users[name] = {\"dni\": dni, \n                                 \"email\": email}\n        print(f\"Usuario {name} fue agregado correctamente\")\n\n    def process_loans(self,dni, titles):\n        for title, copies in self.list_book.items():\n            if title == titles and copies['copies'] > 0:\n                self.list_loans[dni] =  titles\n                print(f\"Libro {title} fue prestado al dni {dni} y quedan {copies['copies']-1} disponibles\")\n                return\n        print(f\"No exiten copias disponibles para el Libro {title}\")\n    \n    def return_loans(self, dni, title):\n        for dnis, titles in self.list_loans.items():\n            if dnis == dni and titles == title:\n                del self.list_loans[dni]\n                for titles, copies in self.list_book.items():\n                    if titles == title:\n                        print(f\"Libro {title} fue devuelto por el id {dni}, quedan {copies['copies']} disponibles\")\n                        return\n        print(f\"No exite prestamo para el Libro {title}\")\n\nlibrary = LibraryManager()\nlibrary.add_user(\"alan\", 124578, \"alan2085@gmail.com\")\nlibrary.add_user(\"alan\", 124578, \"alan2085@gmail.com\")\nlibrary.add_book(\"La culpa es de la vaca\", \"Jaime Lopera\", 5)\nlibrary.add_book(\"Clean Code\", \"Robert Martin\", 10)\nlibrary.process_loans(124578, \"La culpa es de la vaca\")\nlibrary.process_loans(2124578, \"Clean Code\")\nlibrary.return_loans(2124578, \"Clean Code\")\nlibrary.return_loans(124578, \"La culpa es de la vaca\")\n\n\n#Aplicando principio Single Responsibility Principle, SRP\n\nclass Book:\n    def __init__(self) -> None:\n        self.list_book = {}\n    \n    def add_book(self, title, author, copies):\n        if title in self.list_book:\n            print(f\"Titulo {title} ya existe\")\n            return\n        self.list_book[title] = {\"author\": author,\n                                 \"copies\": copies}\n        print(f\"Titulo {title} fue agregado correctamente\")\n    \n    def search_book(self, title):\n        for titles, book in self.list_book.items():\n            if titles == title:\n                return titles, book\n        print(f\"Titulo {title} no fue encontrado\")\n\nclass User:\n    def __init__(self) -> None:\n        self.list_user = {}\n    \n    def add_user(self, name, dni, email):\n        if name in self.list_user:\n            print(f\"Usuario {name} ya se encuentra registrado\")\n            return\n        self.list_user[dni] = {\"name\": name, \n                                 \"email\": email}\n        print(f\"Usuario {name} fue agregado correctamente\")\n    \n    def search_user(self , dni):\n        for dnis, user in self.list_user.items():\n            if dnis == dni:\n                return dnis, user\n        print(f\"Identificador {dni} no fue encontrado\")\n\nclass LibraryManager:\n    def __init__(self, book_manager, user_manager) -> None:\n        self.list_loans = {}\n        self.book_manager = book_manager\n        self.user_manager = user_manager\n\n    def process_loans(self,dni, titles):\n        book = self.book_manager.search_book(titles)\n        user = self.user_manager.search_user(dni)\n        if user and book and book[1]['copies'] > 0:\n            self.list_loans[dni] =  titles\n            book[1]['copies'] -= 1\n            print(f\"Libro {titles} fue prestado al dni {dni} y quedan {book[1]['copies']} disponibles\")\n            return\n        print(f\"Ha ocurrido un error\")\n    \n    def return_loans(self, dni, title):\n        for dnis, titles in self.list_loans.items():\n            if dnis == dni and titles == title:\n                del self.list_loans[dni]\n                book = self.book_manager.search_book(title)\n                if book:\n                    book[1]['copies']+=1\n                    print(f\"Libro {title} fue devuelto por el id {dni}, quedan {book[1]['copies']} disponibles\")\n                    return\n        print(f\"Ha ocurrido un error al retornar el libro\")\nbook_manager = Book()\nbook_manager.add_book(\"La culpa es de la vaca\", \"Jaime Lopera\", 15)\nbook_manager.add_book(\"El programador pragmatico\", \"Andrew Hunt\", 20)\n\nuser_manager = User()\nuser_manager.add_user(\"alan\", 123456, \"alan2085@gmail.com\")\nuser_manager.add_user(\"matheo\", 852963, \"matheo0301@gmail.com\")\n\nlibrary_manager = LibraryManager(book_manager, user_manager)\nlibrary_manager.process_loans(123456, \"El programador pragmatico\")\nlibrary_manager.process_loans(852963, \"El programador pragmatico\")\nlibrary_manager.return_loans(123456, \"El programador pragmatico\")\nlibrary_manager.return_loans(852963, \"El programador pragmatico\")\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/avcenal.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n * Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n\"\"\"\n#EJEMPLO INCORRECTO\nclass Book2():\n    def __init__(self,name:str,price:float,quantity:int):\n        self.name = name\n        self.price = price\n        self.quantity = quantity\n    \n    def print_invoice(self): #si quisiéramos cambiar el formato de impresión, hay que modificar la clase\n        print(f\"FACTURA DEL LIBRO \\\"{self.name.upper()}\\\"\\n\\n - Precio(s.IVA): {self.price} EUR || Precio (IVA incl.): {self.price*1.04} EUR\\n\\n ---- TOTAL: {self.price*1.04*self.quantity} EUR\")\n        \nbook2 = Book2(\"El Señor de los Anillos\",25,2)\nbook2.print_invoice()\n\n#EJEMPLO CORRECTO\nclass Book1(): #clase responsable de crear el libro que vas a comprar (nombre, precio y unidades)\n    def __init__(self,name:str,price:float,quantity:int):\n        self.name = name\n        self.price = price\n        self.quantity = quantity\n\nclass BookInvoice(): #clase encargada de imprimir la factura de los libros que vas a comprar\n    def __init__(self,book:Book1):\n        self.book = book\n\n    def print_invoice(self):\n        print(f\"FACTURA DEL LIBRO \\\"{self.book.name.upper()}\\\"\\n\\n - Precio(s.IVA): {self.book.price} EUR || Precio (IVA incl.): {self.book.price*1.04} EUR\\n\\n ---- TOTAL: {self.book.price*1.04*self.book.quantity} EUR\")\n\nbook = Book1(\"El Señor de los Anillos\",25,3)\nbook_invoce = BookInvoice(book)\nbook_invoce.print_invoice()\nprint(\"\\n\")\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n * manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n * y el procesamiento de préstamos de libros.\n * Requisitos:\n * 1. Registrar libros: El sistema debe permitir agregar nuevos libros con\n * información básica como título, autor y número de copias disponibles.\n * 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n * información básica como nombre, número de identificación y correo electrónico.\n * 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n * tomar prestados y devolver libros.\n * Instrucciones:\n * 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n * los tres aspectos mencionados anteriormente (registro de libros, registro de\n * usuarios y procesamiento de préstamos).\n * 2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n * siguiendo el Principio de Responsabilidad Única.\n\"\"\"\nimport logging\nfrom time import time,sleep\nlogging.basicConfig(level=logging.DEBUG,\n                    format = \"%(asctime)s -- %(levelname)s - %(message)s\",\n                    datefmt=\"%d/%m/%Y - %H:%M:%S\",\n                    handlers=[logging.StreamHandler()])\n\ndef books_number_decorator1(function):\n    def original_function(library):\n        result = function(library)\n        logging.debug(f\"Hay almacenados {len(library.books)} libro(s) en la biblioteca\")\n        return result\n    return original_function\n\ndef users_number_decorator1(function):\n    def original_function(library):\n        result = function(library)\n        logging.debug(f\"Hay {len(library.users)} usuarios almancenados en el sistema\")\n        return result\n    return original_function\n\"\"\"\n#1 - NO CUMPLE SRP\nclass Library1():\n    def __init__(self):\n            self.books=list()\n            self.users=list()\n\n    @books_number_decorator1\n    def register_book(self):\n        book = {\"name\":str(\"\"),\n                \"author\":str(\"\"),\n                \"copies\":int(0)}\n        book[\"name\"] = input(\"Introduce el nombre del libro: \")\n        for element in self.books:\n            if element[\"name\"] == book[\"name\"]:\n                logging.warning(\"Ya existe un libro almacenado con este título\") #posibilidad de pedirle al usuario que añada las unidades?\n                break\n        else:\n            book[\"author\"] = input(\"Ahora introduce el nombre del autor del libro: \")\n            book[\"copies\"] = int(input(\"Y para acabar introduce el número de copias de las que disponemos: \"))\n            self.books.append(book)\n\n    @users_number_decorator1\n    def register_user(self):\n        user = {\"name\":str(\"\"),\n                \"id_number\":int,\n                \"email\":\"str\"}\n        user[\"name\"] = input(\"Introduce el nombre del usuario a agregar: \")\n        for element in self.users:\n            if element[\"name\"] == user[\"name\"]:\n                logging.warning(\"El usuario ya existe en el sistema\")\n                break\n        else:\n            user[\"id_number\"] = int(input(\"Introduce ahora el número de identificación: \"))\n            user[\"email\"] = input(\"Y para acabar el email: \")\n            self.users.append(user)\n\n    def __find_user(self,id):\n        for element in self.users:\n            if element[\"id_number\"] == id:\n                return True\n        else:\n            return False\n\n    @books_number_decorator1\n    def pick_book(self):\n        if len(self.users) == 0:\n            logging.warning(\"No hay usuarios en el sistema\")\n            print(\"No es posible sacar préstamos porque no hay usuarios registrados en el sistema\")\n        else:\n            id = int(input(\"Para poder sacar un préstamo, por favor, introduce tu número de identificación: \"))\n            logging.debug(f\"El usuario existe: {self.__find_user(id)}\")\n            if self.__find_user(id):\n                book_name = input(\"Introduce por favor el título del libro que quieres sacar de préstamo: \")\n                for element in self.books:\n                    if element[\"name\"] == book_name:\n                        logging.debug(\"Libro encontrado\")\n                        if element[\"copies\"] == 0:\n                            logging.warning(f\"No hay unidades de {book_name}\")\n                            print(f\"No hay libros disponnibles del título {book_name}\")\n                            break\n                        else:\n                            print(f\"Entendido sacarás de préstamo el libro {book_name}\")\n                            element[\"copies\"] -= 1\n                            break\n                else:\n                    logging.warning(\"Título no disponible\")\n                    print (\"No tenemos ese título en la biblioteca, por tanto no se puede sacar de préstamo\")\n            else:\n                logging.info(\"El usuario no está dado de alta\")\n                new_user_option = input(\"Parece que no hay ningún usuario dado de alta con ese id. ¿Quieres registrarlo?(S/N): \").upper()\n                if new_user_option == \"S\":\n                    logging.debug(\"Registrando nuevo usuario\")\n                    self.register_user()\n                else:\n                    print(\"Entendido\")\n            \n    @books_number_decorator1\n    def return_book(self):\n        if len(self.users) == 0:\n            logging.warning(\"No hay usuarios en el sistema\")\n            print(\"No es posible devolver ningún libro porque no hay usuarios registrados en el sistema\")\n        else:\n            id = int(input(\"Para poder sacar un préstamo, por favor, introduce tu número de identificación: \"))\n            logging.debug(f\"El usuario existe: {self.__find_user(id)}\")\n            if self.__find_user(id):\n                book_name = input(\"Introduce por favor el título del libro a devolver: \")\n                for element in self.books:\n                    if element[\"name\"] == book_name:\n                        logging.debug(\"Libro encontrado\")\n                        element[\"copies\"] +=1\n                        break\n                else:\n                    logging.warning(\"El título no pertenece a esta biblioteca\")\n                    new_book_option = input(\"El libro que estás tratando de devolver no es un título de esta biblioteca ¿Quieres añadirlo?(S/N): \").upper()\n                    if new_book_option == \"S\":\n                        logging.debug(\"registrando nuevo libro\")\n                        self.register_book()\n                    else:\n                        print(\"Entendido\")\n            else:\n                print(\"Parece que no hay ningún usuario dado de alta con ese id, por tanto no es posible devolver ningún libro.\")\n    \n    def show_books(self):\n        if len(self.books) == 0:\n            logging.warning(\"No hay libros en la biblioteca\")\n            print(\"No hay ningún libro almacenado en la biblioteca\")\n        else:\n            for element in self.books:\n                print(element)\n\n    def show_users(self):\n        if len(self.users) == 0:\n            logging.warning(\"No hay usuarios registrados\")\n            print(\"No hay usuarios registrados en la biblioteca\")\n        else:\n            for element in self.users:\n                print(element)\n\nmy_library_1 = Library1()\nprint(\"------- Te doy la bievnenida al sistema de la Biblioteca NO-SRP -------\")\nwhile True:\n    option = input(\"¿Que deseas hacer?:\\n- Registrar un nuevo libro(L)\\n- Registrar un nuevo usuario/a(U)\\n- Sacar un préstamo(P)\\n- Devolver un préstamo(D)\\n- Mostrar todos los libros(M)\\n- Mostrar todos los usuarios/as(A)\\n- Salir(S)\\n-----> \").upper()\n    if option == \"L\":\n        my_library_1.register_book()\n    elif option == \"U\":\n        my_library_1.register_user()\n    elif option == \"P\":\n        my_library_1.pick_book()\n    elif option == \"D\":\n        my_library_1.return_book()\n    elif option == \"M\":\n        my_library_1.show_books()\n    elif option == \"A\":\n        my_library_1.show_users()\n    elif option == \"S\":\n        print(\"Gracias por usar el sistema de la Biblioteca NO-SRP\")\n        break\n    else:\n        logging.warning(\"Opción no válida\")\n        print(\"La opción que has elegido no es válida, prueba de nuevo: \")\"\"\"\n\n#CUMPLE CON SRP\n\ndef books_number_decorator(function):\n    def original_function(reg_book):\n        result = function(reg_book)\n        if type(reg_book) == Library:\n            logging.debug(f\"Hay almacenados {len(reg_book.books)} libro(s) en la biblioteca\")\n        else:\n            logging.debug(f\"Hay almacenados {len(reg_book.library.books)} libro(s) en la biblioteca\")\n        return result\n    return original_function\n\ndef users_number_decorator(function):\n    def original_function(reg_user):\n        result = function(reg_user)\n        if type(reg_user) == Library:\n            logging.debug(f\"Hay almacenados {len(reg_user.books)} libro(s) en la biblioteca\")\n        else:\n            logging.debug(f\"Hay {len(reg_user.library.users)} usuarios almancenados en el sistema\")\n        return result\n    return original_function\n\nclass Book():\n    def __init__(self,name,author,copies) -> None:\n        self.name:str = name\n        self.author:str = author\n        self.copies:int = copies\n\n    def show_data(self):\n        print(f\"- Título: {self.name}\\n- Author: {self.author}\\n- Copias Disponibles: {self.copies}\")\n        print(\"\\n\")\n\nclass User():\n    def __init__(self,name,id_number,email) -> None:\n        self.name:str = name\n        self.id_number:int = id_number\n        self.email:str = email\n\n    def show_data(self):\n        print(f\"- Nombre: {self.name}\\n- ID: {self.id_number}\\n- Email: {self.email}\")\n        print(\"\\n\")\n\nclass Library():\n    def __init__(self):\n        self.books = list()\n        self.users = list()\n\n    def show_books(self):\n        if len(self.books) == 0:\n            logging.warning(\"No hay libros en la biblioteca\")\n            print(\"No hay ningún libro almacenado en la biblioteca\")\n        else:\n            for element in self.books:\n                element.show_data()\n    \n    def show_users(self):\n        if len(self.users) == 0:\n            logging.warning(\"No hay usuarios registrados\")\n            print(\"No hay usuarios registrados en la biblioteca\")\n        else:\n            for element in self.users:\n                element.show_data()\n\nclass Loan():\n    def __init__(self,library:Library):\n        self.library = library\n\n    def __find_user(self,id):\n        for element in self.library.users:\n            if element.id_number == id:\n                return True\n        else:\n            return False\n    \n    def pick_book(self):\n        if len(self.library.users) == 0:\n            logging.warning(\"No hay usuarios en el sistema\")\n            print(\"No es posible sacar préstamos porque no hay usuarios registrados en el sistema\")\n        else:\n            id = int(input(\"Para poder sacar un préstamo, por favor, introduce tu número de identificación: \"))\n            logging.debug(f\"El usuario existe: {self.__find_user(id)}\")\n            if self.__find_user(id):\n                book_name = input(\"Introduce por favor el título del libro que quieres sacar de préstamo: \")\n                for element in self.library.books:\n                    if element.name == book_name:\n                        logging.debug(\"Libro encontrado\")\n                        if element.copies == 0:\n                            logging.warning(f\"No hay unidades de {book_name}\")\n                            print(f\"No hay libros disponnibles del título {book_name}\")\n                            break\n                        else:\n                            print(f\"Entendido sacarás de préstamo el libro {book_name}\")\n                            element.copies -= 1\n                            break\n                else:\n                    logging.warning(\"Título no disponible\")\n                    print (\"No tenemos ese título en la biblioteca, por tanto no se puede sacar de préstamo\")\n            else:\n                logging.info(\"El usuario no está dado de alta\")\n                new_user_option = input(\"Parece que no hay ningún usuario dado de alta con ese id. ¿Quieres registrarlo?(S/N): \").upper()\n                if new_user_option == \"S\":\n                    logging.debug(\"Registrando nuevo usuario\")\n                    new_user = Register_User(self)\n                    new_user.register_user()\n                else:\n                    print(\"Entendido\")\n\n    def return_book(self):\n        if len(self.library.users) == 0:\n            logging.warning(\"No hay usuarios en el sistema\")\n            print(\"No es posible devolver ningún libro porque no hay usuarios registrados en el sistema\")\n        else:\n            id = int(input(\"Para poder devolver un préstamo, por favor, introduce tu número de identificación: \"))\n            logging.debug(f\"El usuario existe: {self.__find_user(id)}\")\n            if self.__find_user(id):\n                book_name = input(\"Introduce por favor el título del libro a devolver: \")\n                for element in self.library.books:\n                    if element.name == book_name:\n                        logging.debug(\"Libro encontrado\")\n                        element.copies += 1\n                        break\n                else:\n                    logging.warning(\"El título no pertenece a esta biblioteca\")\n                    new_book_option = input(\"El libro que estás tratando de devolver no es un título de esta biblioteca ¿Quieres añadirlo?(S/N): \").upper()\n                    if new_book_option == \"S\":\n                        logging.debug(\"registrando nuevo libro\")\n                        new_book = Register_Book(self)\n                        new_book.register_book()\n                    else:\n                        print(\"Entendido\")\n            else:\n                print(\"Parece que no hay ningún usuario dado de alta con ese id, por tanto no es posible devolver ningún libro.\")\n    \n\nclass Register_Book():\n    def __init__(self,library:Library) -> None:\n        self.library = library\n\n    @books_number_decorator\n    def register_book(self):\n        name = input(\"Introduce el nombre del libro: \")\n        for element in self.library.books:\n            if element.name == name:\n                logging.warning(\"Ya existe un libro almacenado con este título\") #posibilidad de pedirle al usuario que añada las unidades?\n                break\n        else:\n            author = input(\"Ahora introduce el nombre del autor del libro: \")\n            copies = int(input(\"Y para acabar introduce el número de copias de las que disponemos: \"))\n            book = Book(name,author,copies)\n            self.library.books.append(book)\n\nclass Register_User():\n    def __init__(self,library) -> None:\n        self.library = library\n\n    @users_number_decorator\n    def register_user(self):\n        name = input(\"Introduce el nombre del usuario a agregar: \")\n        if type(self.library) == Library: #si el tipo del dato es \"library\"\n            for element in self.library.users:\n                if element.name == name:\n                    logging.warning(\"El usuario ya existe en el sistema\")\n                    break\n            else:  #si el tipo del dato es \"loan\", esto solo pasa si el usuario se registra desde la clase Loan()\n                id_number = int(input(\"Introduce ahora el número de identificación: \"))\n                email = input(\"Y para acabar el email: \")\n                user = User(name,id_number,email)\n                self.library.users.append(user)\n        else:\n            for element in self.library.library.users:\n                if element.name == name:\n                    logging.warning(\"El usuario ya existe en el sistema\")\n                    break\n            else:\n                id_number = int(input(\"Introduce ahora el número de identificación: \"))\n                email = input(\"Y para acabar el email: \")\n                user = User(name,id_number,email)\n                self.library.library.users.append(user)\n\nmy_srp_library = Library()\nregister_book = Register_Book(my_srp_library)\nregister_user = Register_User(my_srp_library)\nmy_loan = Loan(my_srp_library)\nprint(\"------- Te doy la bievnenida al sistema de la Biblioteca SI-SRP -------\")\nwhile True:\n    option = input(\"¿Que deseas hacer?:\\n- Registrar un nuevo libro(L)\\n- Registrar un nuevo usuario/a(U)\\n- Sacar un préstamo(P)\\n- Devolver un préstamo(D)\\n- Mostrar todos los libros(M)\\n- Mostrar todos los usuarios/as(A)\\n- Salir(S)\\n-----> \").upper()\n    if option == \"L\":\n        register_book.register_book()\n    elif option == \"U\":\n        register_user.register_user()\n    elif option == \"P\":\n        my_loan.pick_book()\n    elif option == \"D\":\n        my_loan.return_book()\n    elif option == \"M\":\n        my_srp_library.show_books()\n    elif option == \"A\":\n        my_srp_library.show_users()\n    elif option == \"S\":\n        print(\"Gracias por usar el sistema de la Biblioteca SI-SRP\")\n        break\n    else:\n        logging.warning(\"Opción no válida\")\n        print(\"La opción que has elegido no es válida, prueba de nuevo: \")\n\"\"\"\nPOSIBLES MEJORAS\n- Regex tanto en nombres como en los emails\n- Manejo de excepciones, sobre todo en datos int.\n- Dentro de usuario, parámetro \"prestamo\" para guardar el préstamo y no preguntarlo\n\"\"\"\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/barrancus.py",
    "content": "#26 - Python - Principio de Responsabilidad Única (SRP)\n# EJERCICIO:\n# Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n# Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n# de forma correcta e incorrecta.\n# \n# DIFICULTAD EXTRA (opcional):\n# Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n# manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n# y el procesamiento de préstamos de libros.\n# Requisitos:\n# 1. Registrar libros: El sistema debe permitir agregar nuevos libros con \n# información básica como título, autor y número de copias disponibles.\n# 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n# información básica como nombre, número de identificación y correo electrónico.\n# 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n# tomar prestados y devolver libros.\n# Instrucciones:\n# 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n# los tres aspectos mencionados anteriormente (registro de libros, registro de\n# usuarios y procesamiento de préstamos).\n# 2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n# siguiendo el Principio de Responsabilidad Única.\n# \n\nclass Counter:\n    def __iter__(self):\n        self.a = 1\n        return self\n    \n    def __next__(self):\n        x = self.a\n        self.a += 1\n        return x\n\nidentifier = iter(Counter())\n\ndef separacion(cadena) -> str:\n    global contador\n    print(f'\\nEjercicio {next(contador)}. {cadena} {'-.-' * 20}')\n\n# Incorrecto\n\nclass User:\n    \n    def __init__(self, name, email) -> None:\n        self.name = name\n        self.emmail = email\n\n    def save_to_datababase(self):\n        pass\n\n    def send_email(self):\n        pass\n\n# Correcto\n\nclass User:\n\n    def __init__(self, name, email) -> None:\n        self.name = name\n        self.emmail = email\n\nclass UserService:\n\n    def save_to_datababase(self, user):\n        pass\n\nclass EmailServie:\n\n    def send_email(self, email, message):\n        pass\n\n\n# DIFICULTAD EXTRA (opcional):\n\nclass Book:\n\n    def __init__(self, title: str, author: str, ncopies: int):\n        self.title = title\n        self.author = author\n        self.ncopies = ncopies\n        self.borrow = 0\n\n    def __str__(self):\n        return f'Libro: {self.title}.\\n Autor: {self.author}.\\n Número de copias: {self.ncopies}.\\n En préstamo: {self.borrow}'\n    \nuser_lib_id = iter(Counter())\nclass UserLibrary:\n\n    def __init__(self, name: str, email: str):\n        self.name = name\n        self.codeid = f'{next(user_lib_id):06}'\n        self.email = email\n        self.borrowed = []\n\n    def __str__(self):\n        return f'ID: {self.codeid}\\n Nombre: {self.name}.\\n Mail: {self.email}\\n Libros: {self.borrowed}'\n\n# 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje los tres aspectos mencionados anteriormente (registro de libros, registro de usuarios y procesamiento de préstamos).\nclass LibraryManagement:\n\n    def __init__(self):\n        self.books = []\n        self.users = []\n\n    def add_book(self, title: str, author: str, ncopies: int | None = 0) -> tuple[bool, str]:\n        book = self.search_book(title)\n        if book != None:\n            if ncopies == 0: ncopies = 1\n            book.ncopies += ncopies\n            return True, f'Se añaden {ncopies} copias al listado.'\n        else:\n            self.books.append(Book(title, author, ncopies))\n            return True, f'Libro {title} añadido al catálogo.'\n\n    def delete_book(self, title: str) -> tuple[bool, str]:\n        book = self.search_book(title)\n        if book != None:\n            self.books.remove(book)\n            return True, 'Libro borrado del catálogo.'\n        else:\n            return False, 'El libro no existe en el catálogo.'\n    \n    def search_book(self, search_title: str):\n        for book in self.books:\n            if book.title == search_title:\n                return book\n        return None\n\n    def show_stock(self):\n        for element in self.books:\n            print(element)\n\n    def borrow_book(self, title: str, inout: bool) -> tuple[bool, str]:\n        book = self.search_book(title)\n        if inout:\n            if book != None:\n                if book.ncopies >= book.borrow + 1:\n                    book.borrow += 1\n                    return True, 'Libro prestado'\n                else:\n                    return False, 'No hay libros disponibles'\n        else:\n            if book != None:\n                book.borrow -= 1\n                return True, 'Libro devuelto'\n\n    def add_user(self, name: str, email: str) -> tuple[bool, str]:\n        user = self.search_user(name)\n        if user != None:\n            if name == user.name and email == user.email:\n                print(user)\n                return False, 'El usuario ya existe.'\n        else:\n            self.users.append(UserLibrary(name, email))\n            return True, 'Usuario añadido.'\n\n    def delete_user(self, name: str) -> tuple[bool, str]:\n        user = self.search_user(name)\n        if user != None:\n            self.users.remove(user)\n            return True, 'Usuario borrado.'\n        else:\n            return False, 'El usuario no existe.'\n\n    def search_user(self, search_name: str):\n        for user in self.users:\n            if user.name == search_name:\n                return user\n        return None\n\n    def show_list(self):\n        for element in self.users:\n            print(element)\n\n    def borrow_book(self, search_name: str, title: str, inout: bool) -> None:\n        if inout:\n            user = self.search_user(search_name)\n            user.borrowed.append(title)\n        else:\n            user = self.search_user(search_name)\n            user.borrowed.remove(title)\n\n# 2. Refactoriza el código: Separa las responsabilidades en diferentes clases siguiendo el Principio de Responsabilidad Única.\nclass BookManager:\n\n    def __init__(self):\n        self.books = []\n\n    def add_book(self, title: str, author: str, ncopies: int | None = 0) -> tuple[bool, str]:\n        book = self.search_book(title)\n        if book != None:\n            if ncopies == 0: ncopies = 1\n            book.ncopies += ncopies\n            return True, f'Se añaden {ncopies} copias al listado.'\n        else:\n            self.books.append(Book(title, author, ncopies))\n            return True, f'Libro {title} añadido al catálogo.'\n\n    def delete_book(self, title: str) -> tuple[bool, str]:\n        book = self.search_book(title)\n        if book != None:\n            self.books.remove(book)\n            return True, 'Libro borrado del catálogo.'\n        else:\n            return False, 'El libro no existe en el catálogo.'\n    \n    def search_book(self, search_title: str):\n        for book in self.books:\n            if book.title == search_title:\n                return book\n        return None\n\n    def show_stock(self):\n        for element in self.books:\n            print(element)\n\n    def borrow_book(self, title: str, inout: bool) -> tuple[bool, str]:\n        book = self.search_book(title)\n        if inout:\n            if book != None:\n                if book.ncopies >= book.borrow + 1:\n                    book.borrow += 1\n                    return True, 'Libro prestado'\n                else:\n                    return False, 'No hay libros disponibles'\n        else:\n            if book != None:\n                book.borrow -= 1\n                return True, 'Libro devuelto'\n        \nclass UserLibraryManager:\n\n    def __init__(self):\n        self.users = []\n\n    def add_user(self, name: str, email: str) -> tuple[bool, str]:\n        user = self.search_user(name)\n        if user != None:\n            if name == user.name and email == user.email:\n                print(user)\n                return False, 'El usuario ya existe.'\n        else:\n            self.users.append(UserLibrary(name, email))\n            return True, 'Usuario añadido.'\n\n    def delete_user(self, name: str) -> tuple[bool, str]:\n        user = self.search_user(name)\n        if user != None:\n            self.users.remove(user)\n            return True, 'Usuario borrado.'\n        else:\n            return False, 'El usuario no existe.'\n\n    def search_user(self, search_name: str):\n        for user in self.users:\n            if user.name == search_name:\n                return user\n        return None\n\n    def show_list(self):\n        for element in self.users:\n            print(element)\n\n    def borrow_book(self, search_name: str, title: str, inout: bool) -> None:\n        if inout:\n            user = self.search_user(search_name)\n            user.borrowed.append(title)\n        else:\n            user = self.search_user(search_name)\n            user.borrowed.remove(title)\n        \n        \nusuarios = [\n    {\"nombre\": \"Juan Pérez\", \"email\": \"juan.perez@example.com\"},\n    {\"nombre\": \"María García\", \"email\": \"maria.garcia@test.com\"},\n    {\"nombre\": \"Carlos López\", \"email\": \"carlos.lopez@dominio.net\"},\n    {\"nombre\": \"Ana Martínez\", \"email\": \"ana.martinez@web.org\"},\n    {\"nombre\": \"Luis González\", \"email\": \"luis.gonzalez@example.com\"},\n    {\"nombre\": \"Elena Rodríguez\", \"email\": \"elena.rodriguez@test.com\"},\n    {\"nombre\": \"Pedro Sánchez\", \"email\": \"pedro.sanchez@dominio.net\"},\n    {\"nombre\": \"Laura Fernández\", \"email\": \"laura.fernandez@web.org\"},\n    {\"nombre\": \"Miguel Ramírez\", \"email\": \"miguel.ramirez@example.com\"},\n    {\"nombre\": \"Sofía Torres\", \"email\": \"sofia.torres@test.com\"},\n    {\"nombre\": \"David Díaz\", \"email\": \"david.diaz@dominio.net\"},\n    {\"nombre\": \"Carmen Ruiz\", \"email\": \"carmen.ruiz@web.org\"},\n    {\"nombre\": \"Javier Morales\", \"email\": \"javier.morales@example.com\"}\n]\n\nlibros = [\n    {\"titulo\": \"Cien años de soledad\", \"autor\": \"Gabriel García Márquez\", \"cantidad\": 2},\n    {\"titulo\": \"1984\", \"autor\": \"George Orwell\", \"cantidad\": 1},\n    {\"titulo\": \"El Principito\", \"autor\": \"Antoine de Saint-Exupéry\", \"cantidad\": 3},\n    {\"titulo\": \"El Señor de los Anillos\", \"autor\": \"J.R.R. Tolkien\", \"cantidad\": 1},\n    {\"titulo\": \"Don Quijote de la Mancha\", \"autor\": \"Miguel de Cervantes\", \"cantidad\": 2},\n    {\"titulo\": \"Orgullo y Prejuicio\", \"autor\": \"Jane Austen\", \"cantidad\": 3},\n    {\"titulo\": \"Crónica de una muerte anunciada\", \"autor\": \"Gabriel García Márquez\", \"cantidad\": 1},\n    {\"titulo\": \"Crimen y Castigo\", \"autor\": \"Fiódor Dostoyevski\", \"cantidad\": 2},\n    {\"titulo\": \"La Odisea\", \"autor\": \"Homero\", \"cantidad\": 3},\n    {\"titulo\": \"Fahrenheit 451\", \"autor\": \"Ray Bradbury\", \"cantidad\": 1},\n    {\"titulo\": \"El Gran Gatsby\", \"autor\": \"F. Scott Fitzgerald\", \"cantidad\": 2},\n    {\"titulo\": \"En busca del tiempo perdido\", \"autor\": \"Marcel Proust\", \"cantidad\": 1},\n    {\"titulo\": \"El nombre de la rosa\", \"autor\": \"Umberto Eco\", \"cantidad\": 3},\n    {\"titulo\": \"La sombra del viento\", \"autor\": \"Carlos Ruiz Zafón\", \"cantidad\": 2},\n    {\"titulo\": \"Rayuela\", \"autor\": \"Julio Cortázar\", \"cantidad\": 1},\n    {\"titulo\": \"Matar a un ruiseñor\", \"autor\": \"Harper Lee\", \"cantidad\": 3},\n    {\"titulo\": \"Los Miserables\", \"autor\": \"Victor Hugo\", \"cantidad\": 2},\n    {\"titulo\": \"La Metamorfosis\", \"autor\": \"Franz Kafka\", \"cantidad\": 1},\n    {\"titulo\": \"El Retrato de Dorian Gray\", \"autor\": \"Oscar Wilde\", \"cantidad\": 3},\n    {\"titulo\": \"Un mundo feliz\", \"autor\": \"Aldous Huxley\", \"cantidad\": 2},\n    {\"titulo\": \"El Alquimista\", \"autor\": \"Paulo Coelho\", \"cantidad\": 1},\n    {\"titulo\": \"Cumbres Borrascosas\", \"autor\": \"Emily Brontë\", \"cantidad\": 3},\n    {\"titulo\": \"Drácula\", \"autor\": \"Bram Stoker\", \"cantidad\": 2},\n    {\"titulo\": \"El Código Da Vinci\", \"autor\": \"Dan Brown\", \"cantidad\": 1},\n    {\"titulo\": \"Sapiens\", \"autor\": \"Yuval Noah Harari\", \"cantidad\": 3},\n    {\"titulo\": \"La Divina Comedia\", \"autor\": \"Dante Alighieri\", \"cantidad\": 2},\n    {\"titulo\": \"Frankenstein\", \"autor\": \"Mary Shelley\", \"cantidad\": 1},\n    {\"titulo\": \"El viejo y el mar\", \"autor\": \"Ernest Hemingway\", \"cantidad\": 3},\n    {\"titulo\": \"Hamlet\", \"autor\": \"William Shakespeare\", \"cantidad\": 2},\n    {\"titulo\": \"Madame Bovary\", \"autor\": \"Gustave Flaubert\", \"cantidad\": 1}\n]\n\ndef main() -> None:\n    user_lib_manager = UserLibraryManager()\n    for element in usuarios:\n        print(user_lib_manager.add_user(element[\"nombre\"], element[\"email\"]))\n    book_manager = BookManager()\n    for element in libros:\n        print(book_manager.add_book(title=element[\"titulo\"], author=element[\"autor\"], ncopies=element[\"cantidad\"]))\n    #user_lib_manager.show_list()\n    #book_manager.show_stock()\n    while True:\n        print(\"\\nBienvenido al servicio de gestión de la librería.\\nSeleccione la operación a realizar.\")\n        print(\"1.- Para añadir libro.\")\n        print(\"2.- Para añadir usuario.\")\n        print(\"3.- Para sacar un libro.\")\n        print(\"4.- Para devolver un libro.\")\n        print(\"5.- Para buscar un libro.\")\n        print(\"6.- Para buscar un usuario.\")\n        print(\"7.- Para listar los libros.\")\n        print(\"8.- Para listar los usuarios.\")\n        print(\"0.- Para terminar la sesion.\")\n        option = (input(\"Opcion: \")).strip()\n        print(option)\n\n        match option:\n            case \"1\":\n                title = (input(\"\\nIngrese el título del libro: \")).strip().title()\n                author = (input(\"Ingrese el autor del libro: \")).strip().title()\n                ncopies = (input(\"Ingrese número de copias: \")).strip()\n                if ncopies == \"\":\n                    ncopies = 0\n                else:\n                    ncopies = int(ncopies)\n                print(book_manager.add_book(title=title, author=author, ncopies=ncopies))\n            case \"2\":\n                name = (input(\"\\nIngrese el nombre del usuario: \")).strip().title()\n                email = (input(\"Ingrese email del usuario: \")).strip()\n                print(user_lib_manager.add_user(name, email))\n            case \"3\":\n                title = (input(\"\\nIngrese el título del libro: \")).strip().title()\n                borrowed, mensage = book_manager.borrow_book(title, True)\n                if borrowed:\n                    name = (input(\"\\nIngrese el nombre del usuario: \")).strip().title()\n                    user_lib_manager.borrow_book(name, title, True)\n                    print(mensage)\n                else:\n                    print(mensage)\n            case \"4\":\n                title = (input(\"\\nIngrese el título del libro: \")).strip().title()\n                borrowed, mensage = book_manager.borrow_book(title, False)\n                if borrowed:\n                    name = (input(\"\\nIngrese el nombre del usuario: \")).strip().title()\n                    user_lib_manager.borrow_book(name, title, False)\n                    print(mensage)\n                else:\n                    print(mensage)\n            case \"5\":\n                title = (input(\"\\nIngrese el título del libro a buscar: \")).strip().title()\n                print(book_manager.search_book(search_title=title))\n            case \"6\":\n                name = (input(\"\\nIngrese el nombre del usuario: \")).strip().title()\n                print(name)\n                print(user_lib_manager.search_user(search_name=name))\n            case \"7\":\n                book_manager.show_stock()\n            case \"8\":\n                user_lib_manager.show_list()\n            case \"0\":\n                print(\"\\nHasta la próxima.\")\n                break\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/bytecodesky.py",
    "content": "'''\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n * Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n * manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n * y el procesamiento de préstamos de libros.\n * Requisitos:\n * 1. Registrar libros: El sistema debe permitir agregar nuevos libros con\n * información básica como título, autor y número de copias disponibles.\n * 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n * información básica como nombre, número de identificación y correo electrónico.\n * 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n * tomar prestados y devolver libros.\n * Instrucciones:\n * 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n * los tres aspectos mencionados anteriormente (registro de libros, registro de\n * usuarios y procesamiento de préstamos).\n * 2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n * siguiendo el Principio de Responsabilidad Única.\n */\n'''\n\n#El principio de SRP consiste en que una clase debe tener una única responsabilidad, es decir, una clase debe tener una única razón para cambiar. Si una clase tiene más de una responsabilidad, entonces la clase debe ser dividida en clases más pequeñas, cada una con una única responsabilidad.\n\n#Ejemplo incorrecto\nclass Rectangulo:\n    def __init__(self, ancho, alto):\n        self.ancho = ancho\n        self.alto = alto\n    \n    def calcular_area(self):\n        return self.ancho * self.alto\n    \n    def dibujar(self):\n        for i in range(self.alto):\n            print('*' * self.ancho)\n#Es incorrecto porque la clase Rectangulo tiene dos responsabilidades: calcular el área y dibujar el rectángulo, por lo que no cumple con el principio SRP.\n\n#Ejemplo correcto\n\nclass Rectangulo:\n    def __init__(self, ancho, alto):\n        self.ancho = ancho\n        self.alto = alto\n    \n    def calcular_area(self):\n        return self.ancho * self.alto\n\nclass DibujarRectangulo:\n    def __init__(self, rectangulo):\n        self.rectangulo = rectangulo\n    \n    def dibujar(self):\n        for i in range(self.rectangulo.alto):\n            print('*' * self.rectangulo.ancho)\n\n#En este ejemplo, la clase Rectangulo tiene la responsabilidad de calcular el área, mientras que la clase DibujarRectangulo tiene la responsabilidad de dibujar el rectángulo. Cada clase tiene una única responsabilidad, por lo que cumple con el principio SRP.\n\n#Ejemplo de sistema de gestión de biblioteca incorrecto\n\nclass Library:\n    def __init__(self):\n        self.libros = []\n        self.usuarios = []\n        self.prestamos = []\n    \n    def agregar_libro(self, libro):\n        self.libros.append(libro)\n    \n    def agregar_usuario(self, usuario):\n        self.usuarios.append(usuario)\n    \n    def prestar_libro(self, libro, usuario, fecha_prestamo, fecha_devolucion):\n        prestamo = (libro, usuario, fecha_prestamo, fecha_devolucion)\n        self.prestamos.append(prestamo)\n    \n    def devolver_libro(self, prestamo):\n        self.prestamos.remove(prestamo)\n\n#Es incorrecto porque la clase Library tiene tres responsabilidades: registrar libros, registrar usuarios y procesar préstamos de libros, por lo que no cumple con el principio SRP.\n\n#Ejemplo de sistema de gestión de biblioteca corecto\n\nclass Library:\n    def __init__(self, titulo, autor, copias_disponibles):\n        self.titulo = titulo\n        self.autor = autor\n        self.copias_disponibles = copias_disponibles\n\nclass Usuario:\n    def __init__(self, nombre, identificacion, correo):\n        self.nombre = nombre\n        self.identificacion = identificacion\n        self.correo = correo\n\nclass Prestamo:\n    def __init__(self, libro, usuario, fecha_prestamo, fecha_devolucion):\n        self.libro = libro\n        self.usuario = usuario\n        self.fecha_prestamo = fecha_prestamo\n        self.fecha_devolucion = fecha_devolucion\n\nclass RegistroLibros:\n    def __init__(self):\n        self.libros = []\n    \n    def agregar_libro(self, libro):\n        self.libros.append(libro)\n\nclass RegistroUsuarios:\n    def __init__(self):\n        self.usuarios = []\n    \n    def agregar_usuario(self, usuario):\n        self.usuarios.append(usuario)\n\nclass ProcesarPrestamos:\n    def __init__(self):\n        self.prestamos = []\n    \n    def prestar_libro(self, libro, usuario, fecha_prestamo, fecha_devolucion):\n        prestamo = Prestamo(libro, usuario, fecha_prestamo, fecha_devolucion)\n        self.prestamos.append(prestamo)\n    \n    def devolver_libro(self, prestamo):\n        self.prestamos.remove(prestamo)\n\n#En este ejemplo, se han creado diferentes clases para manejar las responsabilidades de registrar libros, registrar usuarios y procesar préstamos de libros. Cada clase tiene una única responsabilidad, por lo que cumple con el principio SRP.\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/cristianfloyd.py",
    "content": "# EJERCICIO:\n# Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n# Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n# de forma correcta e incorrecta.\n\n# --- EJEMPLO INCORRECTO ---\n\n\nclass UserIncorrect:\n    def __init__(self, name: str, email: str):\n        self.name = name\n        self.email = email\n\n    def save_to_db(self):\n        # Responsabilidad 1: Manejo de persistencia\n        print(f\"Guardando usuario {self.name} en la base de datos...\")\n\n    def send_welcome_email(self):\n        # Responsabilidad 2: Manejo de notificaciones/email\n        print(f\"Enviando correo de bienvenida a {self.email}...\")\n\n    def generate_report(self):\n        # Responsabilidad 3: Generación de documentos/formateo\n        print(f\"Generando reporte PDF para el usuario {self.name}...\")\n\n\n# --- EJEMPLO CORRECTO ---\nclass User:\n    \"\"\"Clase que solo maneja los datos del usuario.\"\"\"\n\n    def __init__(self, name: str, email: str):\n        self.name = name\n        self.email = email\n\n\nclass UserRepository:\n    \"\"\"Clase encargada exclusivamente de la persistencia.\"\"\"\n\n    def save(self, user: User):\n        print(f\"Guardando usuario {user.name} en la base de datos...\")\n\n\nclass EmailService:\n    \"\"\"Clase encargada exclusivamente de enviar correos.\"\"\"\n\n    def send_welcome_email(self, user: User):\n        print(f\"Enviando correo de bienvenida a {user.email}...\")\n\n\nclass UserReportGenerator:\n    \"\"\"Clase encargada de generar reportes.\"\"\"\n\n    def generate(self, user: User):\n        print(f\"Generando reporte PDF para el usuario {user.name}...\")\n\n\n# Uso correcto:\nuser = User(\"Cristian\", \"cristian@example.com\")\nrepo = UserRepository()\nemail_service = EmailService()\n\nrepo.save(user)\nemail_service.send_welcome_email(user)\n\n\n#\n# DIFICULTAD EXTRA (opcional):\n# Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n# manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n# y el procesamiento de préstamos de libros.\n# Requisitos:\n# 1. Registrar libros: El sistema debe permitir agregar nuevos libros con\n# información básica como título, autor y número de copias disponibles.\n# 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n# información básica como nombre, número de identificación y correo electrónico.\n# 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n# tomar prestados y devolver libros.\n# Instrucciones:\n# 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n# los tres aspectos mencionados anteriormente (registro de libros, registro de\n# usuarios y procesamiento de préstamos).\n# 2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n# siguiendo el Principio de Responsabilidad Única.\n\n\n# --- EJEMPLO INCORRECTO ---\nclass LibraryIncorrect:\n    def __init__(self):\n        self.libros = []\n        self.users = []\n        self.prestamos = []\n\n    def add_libro(self, titulo: str, autor: str, copias: int):\n        self.libros.append({\"titulo\": titulo, \"autor\": autor, \"copias\": copias})\n\n    def registrar_usuario(self, nombre: str, id: int, email: str):\n        usuario = {\"nombre\": nombre, \"id\": id, \"email\": email}\n        self.users.append(usuario)\n\n    def libro_prestado(self, usuario_id: int, libro_title: str):\n        for libro in self.libros:\n            if libro[\"titulo\"] == libro_title and libro[\"copias\"] > 0:\n                libro[\"copias\"] -= 1\n                self.prestamos.append(\n                    {\"usuario_id\": usuario_id, \"libro_title\": libro_title}\n                )\n                return True\n        return False\n\n    def libro_devolver(self, usuario_id: int, libro_title: str):\n        for prestamo in self.prestamos:\n            if (\n                prestamo[usuario_id] == usuario_id\n                and prestamo[\"libro_title\"] == libro_title\n            ):\n                self.prestamos.remove(prestamo)\n                for libro in self.libros:\n                    if libro[\"titulo\"] == libro_title:\n                        libro[\"copias\"] += 1\n                    return True\n        return False\n\n\n# --- EJEMPLO REFACTORIZADO ---\n# Entidades\nclass Libro:\n    def __init__(self, id: int, title: str, author: str, copies: int):\n        self.id = id\n        self.title = title\n        self.author = author\n        self.copies = copies\n\n    def __repr__(self):\n        return f\"Libro(id={self.id}, title='{self.title}', copies={self.copies})\"\n\n\nclass Usuario:\n    def __init__(self, id: int, name: str, email: str):\n        self.name = name\n        self.id = id\n        self.email = email\n\n    def __repr__(self):\n        return f\"Usuario(id={self.id}, name='{self.name}', email='{self.email}')\"\n\n\nclass Prestamo:\n    def __init__(self, libro_id: int, user_id: int):\n        self.id = libro_id\n        self.user_id = user_id\n\n    def __repr__(self):\n        return f\"Prestamo(libro_id={self.id}, user_id={self.user_id})\"\n\n\n# Repositorios\nclass LibroRepository:\n    def __init__(self):\n        self.libros = []\n\n    def add_libro(self, libro: Libro):\n        self.libros.append(libro)\n\n\n    def find_by_id(self, id: int):\n        for libro in self.libros:\n            if libro.id == id:\n                return libro\n        return None\n\n    def update_libro(self, libro: Libro):\n        for i, lib in enumerate(self.libros):\n            if lib.id == libro.id:\n                self.libros[i] = libro\n                return True\n        return False\n\n    def last_id(self) -> int:\n        return self.libros[-1].id\n\n\nclass UsuarioRepository:\n    def __init__(self):\n        self.usuarios = []\n\n    def registrar(self, usuario: Usuario):\n        if usuario in self.usuarios:\n            print(f\"Usuario {usuario.name} ya se encuentra registrado\")\n            return\n        self.usuarios.append(usuario)\n        print(f\"Usuario {usuario.name} registrado correctamente\")\n\n    def find_by_id(self, usuario_id: int):\n        for usuario in self.usuarios:\n            if usuario.id == usuario_id:\n                return usuario\n        return None\n\n    def last_id(self) -> int:\n        return self.usuarios[-1].id\n\n\n# Servicio\nclass PrestamoService:\n    def __init__(\n        self, libro_repository: LibroRepository, usuario_repository: UsuarioRepository\n    ):\n        self.prestamos = []\n        self.usuario_repository = usuario_repository\n        self.libro_repository = libro_repository\n\n    def prestar_libro(self, usuario_id: int, libro_id: int):\n        usuario = self.usuario_repository.find_by_id(usuario_id)\n        libro = self.libro_repository.find_by_id(libro_id)\n        if usuario and libro:\n            if libro.copies > 0:\n                libro.copies -= 1\n                self.prestamos.append(Prestamo(libro_id, usuario_id))\n                print(f\"Libro {libro.title} prestado a {usuario.name}\")\n                return True\n            print(f\"No hay copias disponibles del libro {libro.title}\")\n            return False\n        print(\"Usuario o libro no encontrado\")\n        return False\n\n    def devolver_libro(self, usuario_id: int, libro_id: int):\n        for prestamo in self.prestamos:\n            if prestamo.user_id == usuario_id and prestamo.id == libro_id:\n                libro = self.libro_repository.find_by_id(libro_id)\n                if libro:\n                    libro.copies += 1\n                    self.prestamos.remove(prestamo)\n                    print(f\"Libro {libro.title} devuelto por {usuario_id}\")\n                    return True\n                print(\"Libro no encontrado\")\n                return False\n        print(\"Prestamo no encontrado\")\n        return False\n\n    def last_id(self) -> int:\n        return self.prestamos[-1].id\n\n\n# ORQUESTADOR DEL SISTEMA\nclass LibraryManager:\n    \"\"\"\n    Responsabilidad: Orquestar el sistema de gestión de la biblioteca.\n    \"\"\"\n\n    def __init__(self):\n        self.libro_repository = LibroRepository()\n        self.usuario_repository = UsuarioRepository()\n        self.prestamo_service = PrestamoService(\n            self.libro_repository, self.usuario_repository\n        )\n\n    def add_libro(self, id: int, title: str, author: str, copies: int):\n        libro = Libro(id, title, author, copies)\n        return self.libro_repository.add_libro(libro)\n\n    def registrar_usuario(self, user_id: int, name: str, email: str):\n        usuario = Usuario(user_id, name, email)\n        return self.usuario_repository.registrar(usuario)\n\n    def prestar_libro(self, user_id: int, book_id: int):\n        return self.prestamo_service.prestar_libro(user_id, book_id)\n\n    def devolver_libro(self, user_id: int, book_id: int):\n        return self.prestamo_service.devolver_libro(user_id, book_id)\n\n\ndef main():\n    print(\"=\" * 100)\n    print(\"Iniciando sistema de gestión de biblioteca...\")\n    library_manager = LibraryManager()\n    library_manager.add_libro(1, \"Libro 1\", \"Autor 1\", 10)\n    library_manager.add_libro(2, \"Libro 2\", \"Autor 2\", 10)\n    library_manager.add_libro(3, \"Libro 3\", \"Autor 3\", 10)\n    library_manager.registrar_usuario(1, \"arca\", \"usuario1@example.com\")\n    library_manager.registrar_usuario(2, \"cristian\", \"usuario2@example.com\")\n    library_manager.prestar_libro(1, 1)\n    library_manager.devolver_libro(1, 1)\n    library_manager.devolver_libro(1, 2)\n    library_manager.prestar_libro(2, 2)\n    print(library_manager.libro_repository.libros)\n    print(library_manager.usuario_repository.usuarios)\n    print(library_manager.prestamo_service.prestamos)\n    print(\"=\" * 100)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/cyberdidac.py",
    "content": "from typing import List\n\n\nclass Book:\n    id: int\n    name: str\n    author: str\n    stock: int\n\n    def __init__(self, id, name, author, stock):\n        self.id = id\n        self.name = name\n        self.author = author\n        self.stock = stock\n\n\nclass User:\n    id: int\n    name: str\n    email: str\n    books: List[Book]\n\n    def __init__(self, id, name, email):\n        self.id = id\n        self.name = name\n        self.email = email\n        self.books = []\n\n    def remove_book(self, book):\n        self.books.remove(book)\n\n\nclass UserRegister:\n    users: List[User]\n    next_id: int\n\n    def __init__(self):\n        self.users = []\n        self.next_id = 1\n\n    def add_user(self, name: str, email: str):\n        new_user = User(self.next_id, name, email)\n        self.users.append(new_user)\n        self.next_id += 1\n\n    def search_user(self, book_id):\n        for user in self.users:\n            return user if user.id == book_id else None\n\n\nclass BookRegister:\n    books: List[Book]\n    next_id: int\n\n    def __init__(self):\n        self.books = []\n        self.next_id = 1\n\n    def add_book(self, name: str, author: str, stock: int):\n        new_book = Book(self.next_id, name, author, stock)\n        self.books.append(new_book)\n        self.next_id += 1\n\n    def search_book(self, id):\n        for book in self.books:\n            return book if book.id == id else None\n\n\nclass BookBorrower:\n    book_register: BookRegister\n    user_register: UserRegister\n\n    def __init__(self):\n        self.book_register = BookRegister()\n        self.user_register = UserRegister()\n\n    def borrow_book(self, user_id: int, book_id: int):\n        book = self.book_register.search_book(book_id)\n        user = self.user_register.search_user(user_id)\n\n        if book and user:\n\n            if book.stock > 0:\n                user.books.append(book)\n                book.stock -= 1\n            else:\n                raise Exception(\"No hay stock disponible\")\n        else:\n            raise Exception(\"El libro o el usuario no existe\")\n\n    def return_book(self, user_id: int, book_id: int):\n        book = self.book_register.search_book(book_id)\n        user = self.user_register.search_user(user_id)\n\n        if book and user:\n            user.remove_book(book)\n            book.stock += 1\n        else:\n            raise Exception(\"El libro o el usuario no existe\")\n\n    def list_users(self):\n        users = self.user_register.users\n\n        for user in users:\n            borrowed_books = ', '.join([book.name for book in user.books])\n            print(f\"{user.id} - {user.name} - {user.email} - Libros prestados: {borrowed_books}\")\n\n    def list_books(self):\n        books = self.book_register.books\n\n        for book in books:\n            print(f\"{book.id} - {book.name} - {book.author} – {book.stock}\")\n\n\ndef main():\n    book_borrower = BookBorrower()\n    quit = False\n\n    print(\"Bienvenido a la librería\")\n\n    while not quit:\n        print(\"\\nSelecciona una opción\")\n        print(\"\\n1 - Añadir usuario\"\n              \"\\n2 - Añadir libro\"\n              \"\\n3 - Prestar libro\"\n              \"\\n4 - Devolver libro\"\n              \"\\n5 - Listar libros\"\n              \"\\n6 - Listar usuarios\"\n              \"\\n7 - Salir\")\n        choice = input(\"> \")\n\n        match choice:\n            case \"1\":\n                name = input(\"Nombre: \")\n                email = input(\"Email: \")\n                book_borrower.user_register.add_user(name, email)\n            case \"2\":\n                name = input(\"Nombre: \")\n                author = input(\"Autor: \")\n                stock = int(input(\"Stock: \"))\n                book_borrower.book_register.add_book(name, author, stock)\n            case \"3\":\n                try:\n                    book_id = int(input(\"ID del libro: \"))\n                    user_id = int(input(\"ID del usuario: \"))\n                    book_borrower.borrow_book(user_id, book_id)\n                except Exception as e:\n                    print(e)\n            case \"4\":\n                try:\n                    book_id = int(input(\"ID del libro: \"))\n                    user_id = int(input(\"ID del usuario: \"))\n                    book_borrower.return_book(user_id, book_id)\n                except Exception as e:\n                    print(e)\n            case \"5\":\n                book_borrower.list_books()\n            case \"6\":\n                book_borrower.list_users()\n            case \"7\":\n                print(\"Hasta pronto\")\n                quit = True\n            case _:\n                print(\"Opción incorrecta\")\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/davidrguez98.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n * Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n * manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n * y el procesamiento de préstamos de libros.\n * Requisitos:\n * 1. Registrar libros: El sistema debe permitir agregar nuevos libros con \n * información básica como título, autor y número de copias disponibles.\n * 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n * información básica como nombre, número de identificación y correo electrónico.\n * 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n * tomar prestados y devolver libros.\n * Instrucciones:\n * 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n * los tres aspectos mencionados anteriormente (registro de libros, registro de\n * usuarios y procesamiento de préstamos).\n * 2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n * siguiendo el Principio de Responsabilidad Única.\n */ \"\"\"\n\n#EJERCICIO\n\n#Forma incorrecta\n\nclass User:\n\n    def __init__(self, name, email):\n        self.name = name\n        self.email = email\n\n    def save_to_database(self):\n        pass\n\n    def send_email(self):\n        pass\n\n#Forma correcta\n\nclass User:\n\n    def __init__(self, name, email):\n        self.name = name\n        self.email = email\n\nclass UserService:\n    \n    def save_to_database(self, user):\n        pass\n\nclass EmailService:\n\n    def send_email(self, email, message):\n        pass\n\n#DIFICULTAD EXTRA\n\nclass Book:\n\n    def __init__(self, title, author, copies):\n        self.title = title\n        self.author = author\n        self.copies = copies\n\nclass User:\n\n    def __init__(self, name, id, email):\n        self.name = name\n        self.id = id\n        self.email = email\n\nclass Loan:\n\n    def __init__(self):\n        self.loans = []\n\n    def loan_book(self, user, book):\n        if book.copies > 0:\n                book.copies -= 1\n                self.loans.append({\"user_id\": user.id, \"book_title\": book.title})\n                return True\n        return False\n\n    def return_book(self, user, book):\n        for loan in self.loans:\n            if loan[\"user_id\"] == user.id and loan[\"book_title\"] == book.title:\n                self.loans.remove(loan)\n                book.copies += 1\n                return True\n        return False\n\nclass library:\n    \n    def __init__(self):\n        self.books = []\n        self.users = []\n        self.loans = Loan()\n\n    def new_book(self, book):\n        self.books.append(book)\n\n    def new_user(self, user):\n        self.users.append(user)\n\n    def loan_book(self, user_id, book_title):\n        user = next((u for u in self.users if u.id == user_id), None)\n        book = next((b for b in self.books if b.title == book_title), None)\n        if user in book:\n            return self.loan_book(user, book)\n        return False\n\n    \n    def return_book(self, user_id, book_title):\n        user = next((u for u in self.users if u.id == user_id), None)\n        book = next((b for b in self.books if b.title == book_title), None)\n        if user and book:\n            return self.return_book(user, book)\n        return False"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/duendeintemporal.py",
    "content": "#26 { Retos para Programadores } Principio SOLID de Responsabilidad Única (Single Responsibility Principle, SRP) \n\n# Bibliography reference\n# I use GPT as a reference and sometimes to correct or generate proper comments.\n\n\"\"\"  \n * EJERCICIO:\n * Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n * Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n * manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n * y el procesamiento de préstamos de libros.\n * Requisitos:\n * 1. Registrar libros: El sistema debe permitir agregar nuevos libros con\n * información básica como título, autor y número de copias disponibles.\n * 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n * información básica como nombre, número de identificación y correo electrónico.\n * 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n * tomar prestados y devolver libros.\n * Instrucciones:\n * 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n * los tres aspectos mencionados anteriormente (registro de libros, registro de\n * usuarios y procesamiento de préstamos).\n * 2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n * siguiendo el Principio de Responsabilidad Única.\n \n \"\"\"\n\n\"\"\"  Single Responsibility Principle\nA computer programming principle that states that every module, class, or\nfunction should have responsibility over a single part of the functionality\nprovided by the software, and that responsibility should be entirely\nencapsulated by the module, class, or function. All its services should be\nnarrowly aligned with that responsibility.  \"\"\"\n\nlog = print\nlog('Retos para Programadores #26')\n\n# Not Following the Single Responsibility Principle (SRP)\n\nclass Library:\n    def __init__(self):\n        self.books = []\n        self.users = []\n        self.loans = []\n\n    def add_book(self, title, author, copies):\n        self.books.append({'title': title, 'author': author, 'copies': copies})\n\n    def register_user(self, name, user_id, email):\n        self.users.append({'name': name, 'id': user_id, 'email': email})\n\n    def loan_book(self, user_id, book_title):\n        user = next((u for u in self.users if u['id'] == user_id), None)\n        book = next((b for b in self.books if b['title'] == book_title), None)\n\n        if user and book and book['copies'] > 0:\n            self.loans.append({'userId': user_id, 'bookTitle': book_title})\n            book['copies'] -= 1\n            log(f'Book \"{book_title}\" loaned to {user[\"name\"]}')\n        else:\n            log(\"Loan failed: User or book not found, or no copies available.\")\n\n# Example usage\nlibrary = Library()\nlibrary.add_book(\"Learn Bash the Hard Way\", \"Ian Miell\", 2)\nlibrary.add_book(\"MATLAB Notes for Professionals\", \"GoalKicker.com\", 4)\nlibrary.register_user(\"Royer Rabit\", \"006\", \"happyrabbit@proton.me\")\nlibrary.loan_book(\"006\", \"MATLAB Notes for Professionals\")  # Book \"MATLAB Notes for Professionals\" loaned to Royer Rabit\n\n\nimport logging\n\n# Set up logging configuration\nlogging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')\n\n# Define logging functions\ndef log_info(message):\n    logging.info(message)\n\ndef log_warning(message):\n    logging.warning(message)\n\ndef log_error(message):\n    logging.error(message)\n\n# Book class\nclass Book:\n    def __init__(self, title, author, copies):\n        self.title = title\n        self.author = author\n        self.copies = copies\n\n# User class\nclass User:\n    def __init__(self, name, user_id, email):\n        self.name = name\n        self.id = user_id\n        self.email = email\n\n# BookManager class\nclass BookManager:\n    def __init__(self):\n        self.books = []\n\n    def add_book(self, title, author, copies):\n        self.books.append(Book(title, author, copies))\n        log_info(f\"Book added: {title} by {author} with {copies} copies.\")\n\n    def get_books(self):\n        return self.books\n\n    def find_book(self, title):\n        return next((book for book in self.books if book.title == title), None)\n\n    def increase_copies(self, book_title):\n        book = self.find_book(book_title)\n        if book:\n            book.copies += 1\n            log_info(f\"Increased copies for book: {book_title}\")\n\n# Function to search books by partial title\ndef search_books_by_partial_title(books, search_term):\n    return [book for book in books if search_term.lower() in book.title.lower()]\n\n# UserManager class\nclass UserManager:\n    def __init__(self):\n        self.users = []\n\n    def register_user(self, name, user_id, email):\n        self.users.append(User(name, user_id, email))\n        log_info(f\"User registered: {name} with ID: {user_id}\")\n\n    def find_user(self, user_id):\n        return next((user for user in self.users if user.id == user_id), None)\n\n# LoanManager class\nclass LoanManager:\n    def __init__(self):\n        self.loans = []\n        self.next_loan_id = 1\n\n    def loan_book(self, user, book):\n        if book.copies > 0:\n            loan_id = self.next_loan_id\n            self.loans.append({'loan_id': loan_id, 'user_id': user.id, 'book_title': book.title})\n            book.copies -= 1\n            log_info(f\"Book \\\"{book.title}\\\" loaned to {user.name} with Loan ID: {loan_id}\")\n            self.next_loan_id += 1\n        else:\n            log_warning(\"Loan failed: No copies available.\")\n\n    def return_book(self, loan_id, book_manager):\n        loan_index = next((index for index, loan in enumerate(self.loans) if loan['loan_id'] == loan_id), None)\n\n        if loan_index is not None:\n            loan = self.loans[loan_index]\n            book = book_manager.find_book(loan['book_title'])\n            if book:\n                book.copies += 1\n                log_info(f\"Book \\\"{loan['book_title']}\\\" returned with Loan ID: {loan_id}\")\n            del self.loans[loan_index]\n        else:\n            log_error(\"Return failed: No loan record found for this Loan ID.\")\n\n    def get_loans_by_partial_book_title(self, search_term, user_id):\n        return [loan for loan in self.loans if search_term.lower() in loan['book_title'].lower() and loan['user_id'] == user_id]\n\n# Example usage of the library system\nbook_manager = BookManager()\nuser_manager = UserManager()\nloan_manager = LoanManager()\n\nbook_manager.add_book(\"300 JavaScript Interview Mastery Questions Dive Deep into JavaScript Theory, Syntax, and APIs, and Interview with Confidence\", \"Middaugh, Jonathan\", 3)\nbook_manager.add_book(\"Javascript Interview Questions and Answers\", \"Bandal, Pratik\", 7)\nbook_manager.add_book(\"100 MOST ASKED JOB READY QUESTIONS ANSWERS IN THE TECH SPACE Here are the most asked questions in PYTHON, SQL, JAVASCRIPT...\", \"Aimee Mills\", 2)\nuser_manager.register_user(\"Niko Zen\", \"008\", \"duendeintemporal@hotmail.com\")\n\nsearch_term1 = \"JavaScript\"\nsearch_term2 = \"Interview Questions\"\n\nsearch_results1 = search_books_by_partial_title(book_manager.get_books(), search_term1)\nsearch_results2 = search_books_by_partial_title(book_manager.get_books(), search_term2)\n\nlog_info(f\"Search results for '{search_term1}': {[book.title for book in search_results1]}\")\nlog_info(f\"Search results for '{search_term2}': {[book.title for book in search_results2]}\")\n\nuser = user_manager.find_user(\"008\")\nbook_title = search_results1[2].title if len(search_results1) > 2 else None\nbook = book_manager.find_book(book_title)\n\nif book:\n    loan_manager.loan_book(user, book)  # Loan the book to the user\n    loans = loan_manager.get_loans_by_partial_book_title(book.title, user.id)\n    if loans:\n        loan_manager.return_book(loans[0]['loan_id'], book_manager)  # Return the book\nelse:\n    log_warning(\"Book not found for loan.\")\n\n# Output:\n    \"\"\"  \n2024-12-25 12:09:59,513 - INFO - Book added: 300 JavaScript Interview Mastery Questions Dive Deep into JavaScript Theory, Syntax, and APIs, and Interview with Confidence by Middaugh, Jonathan with 3 copies.\n2024-12-25 12:09:59,513 - INFO - Book added: Javascript Interview Questions and Answers by Bandal, Pratik with 7 copies.\n2024-12-25 12:09:59,513 - INFO - Book added: 100 MOST ASKED JOB READY QUESTIONS ANSWERS IN THE TECH SPACE Here are the most asked questions in PYTHON, SQL, JAVASCRIPT... by Aimee Mills with 2 copies.\n2024-12-25 12:09:59,513 - INFO - User registered: Niko Zen with ID: 008\n2024-12-25 12:09:59,514 - INFO - Search results for 'JavaScript': ['300 JavaScript Interview Mastery Questions Dive Deep into JavaScript Theory, Syntax, and APIs, and Interview with Confidence', 'Javascript Interview Questions and Answers', '100 MOST ASKED JOB READY QUESTIONS ANSWERS IN THE TECH SPACE Here are the most asked questions in PYTHON, SQL, JAVASCRIPT...']\n2024-12-25 12:09:59,514 - INFO - Search results for 'Interview Questions': ['Javascript Interview Questions and Answers']\n2024-12-25 12:09:59,515 - INFO - Book \"100 MOST ASKED JOB READY QUESTIONS ANSWERS IN THE TECH SPACE Here are the most asked questions in PYTHON, SQL, JAVASCRIPT...\" loaned to Niko Zen with Loan ID: 1\n2024-12-25 12:09:59,515 - INFO - Book \"100 MOST ASKED JOB READY QUESTIONS ANSWERS IN THE TECH SPACE Here are the most asked questions in PYTHON, SQL, JAVASCRIPT...\" returned with Loan ID: 1\n    \n    \"\"\"\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/fborjalv.py",
    "content": "\n\n'''\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n * Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n\n\n'''\n'''\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n * manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n * y el procesamiento de préstamos de libros.\n * Requisitos:\n * 1. Registrar libros: El sistema debe permitir agregar nuevos libros con\n * información básica como título, autor y número de copias disponibles.\n * 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n * información básica como nombre, número de identificación y correo electrónico.\n * 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n * tomar prestados y devolver libros.\n * Instrucciones:\n * 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n * los tres aspectos mencionados anteriormente (registro de libros, registro de\n * usuarios y procesamiento de préstamos).\n * 2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n * siguiendo el Principio de Responsabilidad Única.\n\n'''\n\n# Incorrecto \n\nclass Library: \n\n    books = []\n    users = []\n    loans = []\n\n    def new_book(self, author, title, n_copies):\n        self.books.append({\"author\": author,\n                            \"title\": title,\n                            \"n_copies\": n_copies})\n\n    def new_user(self, name, id, email):\n        self.users.append({\"name\": name,\n                            \"id\": id,\n                            \"email\": email})\n\n    def loan_book(self, user_id, book_title):\n        for book in self.books:\n            if book[\"title\"] == book_title and book[\"n_copies\"] > 0:\n                self.loans.append({\"user_id\": user_id,\n                                    \"title_book\": book_title})\n                book[\"n_copies\"] -=1\n\n\n    def return_book(self, user_id, book_title):\n        for loan in self.loans:\n            if loan[\"user_id\"] == user_id and loan[\"title_book\"] == book_title:\n                self.loans.remove(loan)\n                for books in self.books:\n                    if books[\"title\"] == book_title:\n                        books[\"n_copies\"] += 1\n                        \n\n\n\nmy_library = Library()\nmy_library.new_book(\"Cervantes\", \"El quijote\", 10)\nmy_library.new_book(\"Rowling\", \"Harry Potter\", 10)\nmy_library.new_book(\"Tolkien\", \"El señor de los anillos\", 20)\n\nmy_library.new_user(\"Brais\", 105, \"mouredev@gmail.com\")\nmy_library.new_user(\"Borja\", 120, \"xxxxx@gmail.com\")\n\nprint(my_library.books)\nprint(my_library.users)\n\nmy_library.loan_book(120, \"Harry Potter\")\nprint(my_library.loans)\nprint(my_library.books)\n\nmy_library.return_book(120, \"Harry Potter\")\nprint(my_library.books)\n\n\n\n\n# Correcto \nclass Book:\n    def __init__(self, title, author, n_copies):\n        self.title = title\n        self.author = author\n        self.n_copies = n_copies\n\n\nclass User:\n    def __init__(self, name, id, email):\n        self.name = name\n        self.id = id\n        self.email = email\n\nclass BookLoanProcesing:\n    \n    def __init__(self):\n        self.loans = []\n\n    def book_borrowing(self, book, user):\n        if book.n_copies > 0:\n            book.n_copies -= 1\n            self.loans.append({\"user_id\": user.id,\n                                \"title_book\": book.title })\n        else:\n            print(\"No hay libros suficientes\")\n\n    def book_returning(self, user, book):\n        for loan in self.loans:\n            if loan[\"user_id\"] == user.id and loan[\"title_book\"] == book.title:\n                book.n_copies += 1\n                self.loans.remove(loan)\n\n\nclass Library():\n    def __init__(self) -> None:\n        self.books = []\n        self.users = []\n        self.loans = BookLoanProcesing()\n    \n    def new_book(self, book):\n        self.books.append(book)\n    \n    def new_user(self, user):\n        self.users.append(user)\n\n    def new_loan_book(self, user_id, title_book):\n        user = next((user for user in self.users if user.id == user_id), None)\n        book = next((book for book in self.books if book.title == title_book), None)\n        if user and book:\n            return self.loans.book_borrowing(user, book)\n    \n    def return_book(self, user_id, title_book):\n        user = next((user for user in self.user if user_id == user.id),None)\n        book = next((book for book in self.books if book.title == title_book), None)\n        if user and book:\n            return self.loans.book_returning(user, book)\n\n\n\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/franxiscodev.py",
    "content": "\"\"\"\nSOLID\nSRP: principio de responsabilidad única\n\"\"\"\n# NO solid\n\n\nclass User:\n    def __init__(self, name, email) -> None:\n        self.name = name\n        self.email = email\n\n    # no son responsabilidad de una clase usuario\n    def save_to_database(self):\n        pass\n\n    def sen_email():\n        pass\n\n# SOLID\n\n\nclass User:\n\n    def __init__(self, name, email) -> None:\n        self.name = name\n        self.email = email\n\n\nclass UserService:\n    def save_to_database(self, user):\n        pass\n\n\nclass EmailService:\n    def sen_email(self, email, message):\n        pass\n\n\n\"\"\"\nExtra \n\"\"\"\n# Incorrecto\n\n\nclass Library:\n    def __init__(self) -> None:\n        self.books = []\n        self.users = []\n        self.loans = []\n\n    def add_book(self, title: str, author: str, copies: int):\n        self.books.append({\"title\": title, \"author\": author, \"copies\": copies})\n\n    def add_user(self, name: str, user_id: int, email: str):\n        self.users.append({\"name\": name, \"user_id\": user_id, \"email\": email})\n\n    def loan_book(self, user_id: int, book_title: str):\n        for book in self.books:\n            if book[\"title\"] == book_title and book[\"copies\"] > 0:\n                book[\"copies\"] -= 1\n                self.loans.append(\n                    {\"user_id\": user_id, \"book_title\": book_title})\n                return True\n        return False\n\n    def return_book(self, user_id: int, book_title: str):\n        for loan in self.loans:\n            if loan[\"user_id\"] == user_id and loan[\"book_title\"] == book_title:\n                self.loans.remove(loan)\n                for book in self.books:\n                    if book[\"title\"] == book_title:\n                        book[\"copies\"] += 1\n                        return True\n        return False\n\n\n# Correcto\nclass Book:\n    def __init__(self, title: str, author: str, copies: int) -> None:\n        self.title = title\n        self.author = author\n        self.copies = copies\n\n\nclass User:\n    def __init__(self, name: str, user_id: int, email: str) -> None:\n        self.name = name\n        self.user_id = user_id\n        self.email = email\n\n\nclass Loan:\n    def __init__(self) -> None:\n        self.loans = []\n\n    def loan_book(self, user: User, book: Book):\n        if book.copies > 0:\n            book.copies -= 1\n            self.loans.append(\n                {\"user_id\": user.user_id, \"book_title\": book.title})\n            return True\n        return False\n\n    def return_book(self, user: User, book: Book):\n        for loan in self.loans:\n            if loan[\"user_id\"] == user.user_id and loan[\"book_title\"] == book.title:\n                # Remove the loan from the list\n                self.loans.remove(loan)\n                book.copies += 1\n                return True\n        return False\n\n\nclass Library:\n    def __init__(self) -> None:\n        self.books = []\n        self.users = []\n        self.loans_service = Loan()\n\n    def add_book(self, book: Book):\n        self.books.append(book)\n\n    def add_user(self, user: User):\n        self.users.append(user)\n\n    def loan_book(self, user_id: int, book_title: str):\n        user = next(\n            (user for user in self.users if user.user_id == user_id), None)\n        book = next(\n            (book for book in self.books if book.title == book_title), None)\n        if user and book:\n            return self.loans_service.loan_book(user, book)\n        return False\n\n    def return_book(self, user_id: int, book_title: str):\n        user = next(\n            (user for user in self.users if user.user_id == user_id), None)\n        book = next(\n            (book for book in self.books if book.title == book_title), None)\n        if user and book:\n            return self.loans_service.return_book(user, book)\n        return False\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/gringoam.py",
    "content": "\n\n\"\"\"\nExtra\n\"\"\"\n\n\"\"\" class Library:\n    def __init__(self):\n        self.books=[]\n        self.users=[]\n        self.loans=[]\n    \n    \n    def addBook(self, title, author, copies):\n        self.books.append({\"Title\":title, \"Author\": author, \"Copies\":copies})\n\n    def addUser(self, name, id_user, mail):\n        self.users.append({\"name\":name, \"id usuer\": id_user, \"e-mail\":mail})\n\n    def loan_book(self, title_book, id_user):\n        for book in self.books:\n            if book[\"Title\"]== title_book and book[\"Copies\"]> 0:\n                self.loans.append({\"id_user\": id_user, \"Title book\": title_book})\n                book[\"Copies\"]-=1\n                return True\n        return False\n\n    def return_book(self, title_book, id_user):\n        for loan in self.loans:\n            if loan[\"Title book\"]== title_book and loan[\"id_uaser\"]== id_user:\n                self.loans.remove(loan)\n                for book in self.books: \n                    if book[\"Title\"]== title_book:\n                        book[\"Copies\"]+=1\n                    return True\n        return False   \"\"\"\n\n#Correcto\n\nclass Book:\n    def __init__(self, title, author, copies): \n        self.title= title\n        self.author=author\n        self.copies=copies\n    \nclass User:\n      def __init__(self, name, id, mail): \n        self.name= name\n        self.id=id\n        self.mail= mail\n\nclass Loan:\n     \n     def __init__(self):\n        self.loans = []\n\n     def loan_book(self, book, user):\n        if book.copies> 0:\n            self.loans.append({\"id_user\": user.id , \"Title book\": book.title})\n            book.copies-=1\n            return True\n        return False\n     \n     def return_book(self, book, user):\n        for loan in self.loans:\n            if loan[\"Title book\"]== book.tilte and loan[\"id_uaser\"]== user.id:\n                self.loans.remove(loan)\n                book.copies+=1\n                return True\n        return False\n       \n     def see_loans(self):\n        print(self.loans)\n    \nclass Library:\n\n    def __init__(self):\n        self.books=[]\n        self.users=[]\n        self.loans_service= Loan()\n    \n\n    def addBook(self, book):\n        self.books.append(book)\n\n    def addUser(self, user):\n        self.users.append(user)\n\n\n    def loan_book(self, user_id, book_title):\n        user= next((u for u in self.users if user_id == u.id), None)\n        book= next((b for b in self.books if book_title == b.title), None)\n        if user and book:\n            return self.loans_service.loan_book(book, user)\n        return False  \n\n    def return_book(self, user_id, book_title):\n        user= next((u for u in self.users if user_id == u.id), None)\n        book= next((b for b in self.books if book_title == b.title), None)\n        if user and book:\n            return self.loans_service.return_book(book, user)\n        return False    \n    \n    \n\n\nbook= Book(\"Progamador\", \"Diego\", 2)\nuser= User(\"Ariel\", 1, \"ari@hot.com\")\n\nlibrary= Library()\n\nlibrary.addBook(book)\nlibrary.addUser(user)\nlibrary.loan_book(user.id, book.title)\n#library.loans_service.see_loans()\n\nbook1= Book(\"Desarrollador\", \"Ariel\", 3)\nuser1= User(\"Diego\", 2, \"ari@hot.com\")\n\nlibrary.addBook(book1)\nlibrary.addUser(user1)\nlibrary.loan_book(user1.id, book1.title)\nlibrary.loans_service.see_loans()\n\nlibrary.loans_service.see_loans()\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/h4ckxel.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n * Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n\"\"\"\n#EJEMPLO INCORRECTO\nclass Book2():\n    def __init__(self,name:str,price:float,quantity:int):\n        self.name = name\n        self.price = price\n        self.quantity = quantity\n    \n    def print_invoice(self): #si quisiéramos cambiar el formato de impresión, hay que modificar la clase\n        print(f\"FACTURA DEL LIBRO \\\"{self.name.upper()}\\\"\\n\\n - Precio(s.IVA): {self.price} EUR || Precio (IVA incl.): {self.price*1.04} EUR\\n\\n ---- TOTAL: {self.price*1.04*self.quantity} EUR\")\n        \nbook2 = Book2(\"El Señor de los Anillos\",25,2)\nbook2.print_invoice()\n\n#EJEMPLO CORRECTO\nclass Book1(): #clase responsable de crear el libro que vas a comprar (nombre, precio y unidades)\n    def __init__(self,name:str,price:float,quantity:int):\n        self.name = name\n        self.price = price\n        self.quantity = quantity\n\nclass BookInvoice(): #clase encargada de imprimir la factura de los libros que vas a comprar\n    def __init__(self,book:Book1):\n        self.book = book\n\n    def print_invoice(self):\n        print(f\"FACTURA DEL LIBRO \\\"{self.book.name.upper()}\\\"\\n\\n - Precio(s.IVA): {self.book.price} EUR || Precio (IVA incl.): {self.book.price*1.04} EUR\\n\\n ---- TOTAL: {self.book.price*1.04*self.book.quantity} EUR\")\n\nbook = Book1(\"El Señor de los Anillos\",25,3)\nbook_invoce = BookInvoice(book)\nbook_invoce.print_invoice()\nprint(\"\\n\")\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n * manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n * y el procesamiento de préstamos de libros.\n * Requisitos:\n * 1. Registrar libros: El sistema debe permitir agregar nuevos libros con\n * información básica como título, autor y número de copias disponibles.\n * 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n * información básica como nombre, número de identificación y correo electrónico.\n * 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n * tomar prestados y devolver libros.\n * Instrucciones:\n * 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n * los tres aspectos mencionados anteriormente (registro de libros, registro de\n * usuarios y procesamiento de préstamos).\n * 2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n * siguiendo el Principio de Responsabilidad Única.\n\"\"\"\nimport logging\nfrom time import time,sleep\nlogging.basicConfig(level=logging.DEBUG,\n                    format = \"%(asctime)s -- %(levelname)s - %(message)s\",\n                    datefmt=\"%d/%m/%Y - %H:%M:%S\",\n                    handlers=[logging.StreamHandler()])\n\ndef books_number_decorator1(function):\n    def original_function(library):\n        result = function(library)\n        logging.debug(f\"Hay almacenados {len(library.books)} libro(s) en la biblioteca\")\n        return result\n    return original_function\n\ndef users_number_decorator1(function):\n    def original_function(library):\n        result = function(library)\n        logging.debug(f\"Hay {len(library.users)} usuarios almancenados en el sistema\")\n        return result\n    return original_function\n\"\"\"\n#1 - NO CUMPLE SRP\nclass Library1():\n    def __init__(self):\n            self.books=list()\n            self.users=list()\n\n    @books_number_decorator1\n    def register_book(self):\n        book = {\"name\":str(\"\"),\n                \"author\":str(\"\"),\n                \"copies\":int(0)}\n        book[\"name\"] = input(\"Introduce el nombre del libro: \")\n        for element in self.books:\n            if element[\"name\"] == book[\"name\"]:\n                logging.warning(\"Ya existe un libro almacenado con este título\") #posibilidad de pedirle al usuario que añada las unidades?\n                break\n        else:\n            book[\"author\"] = input(\"Ahora introduce el nombre del autor del libro: \")\n            book[\"copies\"] = int(input(\"Y para acabar introduce el número de copias de las que disponemos: \"))\n            self.books.append(book)\n\n    @users_number_decorator1\n    def register_user(self):\n        user = {\"name\":str(\"\"),\n                \"id_number\":int,\n                \"email\":\"str\"}\n        user[\"name\"] = input(\"Introduce el nombre del usuario a agregar: \")\n        for element in self.users:\n            if element[\"name\"] == user[\"name\"]:\n                logging.warning(\"El usuario ya existe en el sistema\")\n                break\n        else:\n            user[\"id_number\"] = int(input(\"Introduce ahora el número de identificación: \"))\n            user[\"email\"] = input(\"Y para acabar el email: \")\n            self.users.append(user)\n\n    def __find_user(self,id):\n        for element in self.users:\n            if element[\"id_number\"] == id:\n                return True\n        else:\n            return False\n\n    @books_number_decorator1\n    def pick_book(self):\n        if len(self.users) == 0:\n            logging.warning(\"No hay usuarios en el sistema\")\n            print(\"No es posible sacar préstamos porque no hay usuarios registrados en el sistema\")\n        else:\n            id = int(input(\"Para poder sacar un préstamo, por favor, introduce tu número de identificación: \"))\n            logging.debug(f\"El usuario existe: {self.__find_user(id)}\")\n            if self.__find_user(id):\n                book_name = input(\"Introduce por favor el título del libro que quieres sacar de préstamo: \")\n                for element in self.books:\n                    if element[\"name\"] == book_name:\n                        logging.debug(\"Libro encontrado\")\n                        if element[\"copies\"] == 0:\n                            logging.warning(f\"No hay unidades de {book_name}\")\n                            print(f\"No hay libros disponnibles del título {book_name}\")\n                            break\n                        else:\n                            print(f\"Entendido sacarás de préstamo el libro {book_name}\")\n                            element[\"copies\"] -= 1\n                            break\n                else:\n                    logging.warning(\"Título no disponible\")\n                    print (\"No tenemos ese título en la biblioteca, por tanto no se puede sacar de préstamo\")\n            else:\n                logging.info(\"El usuario no está dado de alta\")\n                new_user_option = input(\"Parece que no hay ningún usuario dado de alta con ese id. ¿Quieres registrarlo?(S/N): \").upper()\n                if new_user_option == \"S\":\n                    logging.debug(\"Registrando nuevo usuario\")\n                    self.register_user()\n                else:\n                    print(\"Entendido\")\n            \n    @books_number_decorator1\n    def return_book(self):\n        if len(self.users) == 0:\n            logging.warning(\"No hay usuarios en el sistema\")\n            print(\"No es posible devolver ningún libro porque no hay usuarios registrados en el sistema\")\n        else:\n            id = int(input(\"Para poder sacar un préstamo, por favor, introduce tu número de identificación: \"))\n            logging.debug(f\"El usuario existe: {self.__find_user(id)}\")\n            if self.__find_user(id):\n                book_name = input(\"Introduce por favor el título del libro a devolver: \")\n                for element in self.books:\n                    if element[\"name\"] == book_name:\n                        logging.debug(\"Libro encontrado\")\n                        element[\"copies\"] +=1\n                        break\n                else:\n                    logging.warning(\"El título no pertenece a esta biblioteca\")\n                    new_book_option = input(\"El libro que estás tratando de devolver no es un título de esta biblioteca ¿Quieres añadirlo?(S/N): \").upper()\n                    if new_book_option == \"S\":\n                        logging.debug(\"registrando nuevo libro\")\n                        self.register_book()\n                    else:\n                        print(\"Entendido\")\n            else:\n                print(\"Parece que no hay ningún usuario dado de alta con ese id, por tanto no es posible devolver ningún libro.\")\n    \n    def show_books(self):\n        if len(self.books) == 0:\n            logging.warning(\"No hay libros en la biblioteca\")\n            print(\"No hay ningún libro almacenado en la biblioteca\")\n        else:\n            for element in self.books:\n                print(element)\n\n    def show_users(self):\n        if len(self.users) == 0:\n            logging.warning(\"No hay usuarios registrados\")\n            print(\"No hay usuarios registrados en la biblioteca\")\n        else:\n            for element in self.users:\n                print(element)\n\nmy_library_1 = Library1()\nprint(\"------- Te doy la bievnenida al sistema de la Biblioteca NO-SRP -------\")\nwhile True:\n    option = input(\"¿Que deseas hacer?:\\n- Registrar un nuevo libro(L)\\n- Registrar un nuevo usuario/a(U)\\n- Sacar un préstamo(P)\\n- Devolver un préstamo(D)\\n- Mostrar todos los libros(M)\\n- Mostrar todos los usuarios/as(A)\\n- Salir(S)\\n-----> \").upper()\n    if option == \"L\":\n        my_library_1.register_book()\n    elif option == \"U\":\n        my_library_1.register_user()\n    elif option == \"P\":\n        my_library_1.pick_book()\n    elif option == \"D\":\n        my_library_1.return_book()\n    elif option == \"M\":\n        my_library_1.show_books()\n    elif option == \"A\":\n        my_library_1.show_users()\n    elif option == \"S\":\n        print(\"Gracias por usar el sistema de la Biblioteca NO-SRP\")\n        break\n    else:\n        logging.warning(\"Opción no válida\")\n        print(\"La opción que has elegido no es válida, prueba de nuevo: \")\"\"\"\n\n#CUMPLE CON SRP\n\ndef books_number_decorator(function):\n    def original_function(reg_book):\n        result = function(reg_book)\n        if type(reg_book) == Library:\n            logging.debug(f\"Hay almacenados {len(reg_book.books)} libro(s) en la biblioteca\")\n        else:\n            logging.debug(f\"Hay almacenados {len(reg_book.library.books)} libro(s) en la biblioteca\")\n        return result\n    return original_function\n\ndef users_number_decorator(function):\n    def original_function(reg_user):\n        result = function(reg_user)\n        if type(reg_user) == Library:\n            logging.debug(f\"Hay almacenados {len(reg_user.books)} libro(s) en la biblioteca\")\n        else:\n            logging.debug(f\"Hay {len(reg_user.library.users)} usuarios almancenados en el sistema\")\n        return result\n    return original_function\n\nclass Book():\n    def __init__(self,name,author,copies) -> None:\n        self.name:str = name\n        self.author:str = author\n        self.copies:int = copies\n\n    def show_data(self):\n        print(f\"- Título: {self.name}\\n- Author: {self.author}\\n- Copias Disponibles: {self.copies}\")\n        print(\"\\n\")\n\nclass User():\n    def __init__(self,name,id_number,email) -> None:\n        self.name:str = name\n        self.id_number:int = id_number\n        self.email:str = email\n\n    def show_data(self):\n        print(f\"- Nombre: {self.name}\\n- ID: {self.id_number}\\n- Email: {self.email}\")\n        print(\"\\n\")\n\nclass Library():\n    def __init__(self):\n        self.books = list()\n        self.users = list()\n\n    def show_books(self):\n        if len(self.books) == 0:\n            logging.warning(\"No hay libros en la biblioteca\")\n            print(\"No hay ningún libro almacenado en la biblioteca\")\n        else:\n            for element in self.books:\n                element.show_data()\n    \n    def show_users(self):\n        if len(self.users) == 0:\n            logging.warning(\"No hay usuarios registrados\")\n            print(\"No hay usuarios registrados en la biblioteca\")\n        else:\n            for element in self.users:\n                element.show_data()\n\nclass Loan():\n    def __init__(self,library:Library):\n        self.library = library\n\n    def __find_user(self,id):\n        for element in self.library.users:\n            if element.id_number == id:\n                return True\n        else:\n            return False\n    \n    def pick_book(self):\n        if len(self.library.users) == 0:\n            logging.warning(\"No hay usuarios en el sistema\")\n            print(\"No es posible sacar préstamos porque no hay usuarios registrados en el sistema\")\n        else:\n            id = int(input(\"Para poder sacar un préstamo, por favor, introduce tu número de identificación: \"))\n            logging.debug(f\"El usuario existe: {self.__find_user(id)}\")\n            if self.__find_user(id):\n                book_name = input(\"Introduce por favor el título del libro que quieres sacar de préstamo: \")\n                for element in self.library.books:\n                    if element.name == book_name:\n                        logging.debug(\"Libro encontrado\")\n                        if element.copies == 0:\n                            logging.warning(f\"No hay unidades de {book_name}\")\n                            print(f\"No hay libros disponnibles del título {book_name}\")\n                            break\n                        else:\n                            print(f\"Entendido sacarás de préstamo el libro {book_name}\")\n                            element.copies -= 1\n                            break\n                else:\n                    logging.warning(\"Título no disponible\")\n                    print (\"No tenemos ese título en la biblioteca, por tanto no se puede sacar de préstamo\")\n            else:\n                logging.info(\"El usuario no está dado de alta\")\n                new_user_option = input(\"Parece que no hay ningún usuario dado de alta con ese id. ¿Quieres registrarlo?(S/N): \").upper()\n                if new_user_option == \"S\":\n                    logging.debug(\"Registrando nuevo usuario\")\n                    new_user = Register_User(self)\n                    new_user.register_user()\n                else:\n                    print(\"Entendido\")\n\n    def return_book(self):\n        if len(self.library.users) == 0:\n            logging.warning(\"No hay usuarios en el sistema\")\n            print(\"No es posible devolver ningún libro porque no hay usuarios registrados en el sistema\")\n        else:\n            id = int(input(\"Para poder devolver un préstamo, por favor, introduce tu número de identificación: \"))\n            logging.debug(f\"El usuario existe: {self.__find_user(id)}\")\n            if self.__find_user(id):\n                book_name = input(\"Introduce por favor el título del libro a devolver: \")\n                for element in self.library.books:\n                    if element.name == book_name:\n                        logging.debug(\"Libro encontrado\")\n                        element.copies += 1\n                        break\n                else:\n                    logging.warning(\"El título no pertenece a esta biblioteca\")\n                    new_book_option = input(\"El libro que estás tratando de devolver no es un título de esta biblioteca ¿Quieres añadirlo?(S/N): \").upper()\n                    if new_book_option == \"S\":\n                        logging.debug(\"registrando nuevo libro\")\n                        new_book = Register_Book(self)\n                        new_book.register_book()\n                    else:\n                        print(\"Entendido\")\n            else:\n                print(\"Parece que no hay ningún usuario dado de alta con ese id, por tanto no es posible devolver ningún libro.\")\n    \n\nclass Register_Book():\n    def __init__(self,library:Library) -> None:\n        self.library = library\n\n    @books_number_decorator\n    def register_book(self):\n        name = input(\"Introduce el nombre del libro: \")\n        for element in self.library.books:\n            if element.name == name:\n                logging.warning(\"Ya existe un libro almacenado con este título\") #posibilidad de pedirle al usuario que añada las unidades?\n                break\n        else:\n            author = input(\"Ahora introduce el nombre del autor del libro: \")\n            copies = int(input(\"Y para acabar introduce el número de copias de las que disponemos: \"))\n            book = Book(name,author,copies)\n            self.library.books.append(book)\n\nclass Register_User():\n    def __init__(self,library) -> None:\n        self.library = library\n\n    @users_number_decorator\n    def register_user(self):\n        name = input(\"Introduce el nombre del usuario a agregar: \")\n        if type(self.library) == Library: #si el tipo del dato es \"library\"\n            for element in self.library.users:\n                if element.name == name:\n                    logging.warning(\"El usuario ya existe en el sistema\")\n                    break\n            else:  #si el tipo del dato es \"loan\", esto solo pasa si el usuario se registra desde la clase Loan()\n                id_number = int(input(\"Introduce ahora el número de identificación: \"))\n                email = input(\"Y para acabar el email: \")\n                user = User(name,id_number,email)\n                self.library.users.append(user)\n        else:\n            for element in self.library.library.users:\n                if element.name == name:\n                    logging.warning(\"El usuario ya existe en el sistema\")\n                    break\n            else:\n                id_number = int(input(\"Introduce ahora el número de identificación: \"))\n                email = input(\"Y para acabar el email: \")\n                user = User(name,id_number,email)\n                self.library.library.users.append(user)\n\nmy_srp_library = Library()\nregister_book = Register_Book(my_srp_library)\nregister_user = Register_User(my_srp_library)\nmy_loan = Loan(my_srp_library)\nprint(\"------- Te doy la bievnenida al sistema de la Biblioteca SI-SRP -------\")\nwhile True:\n    option = input(\"¿Que deseas hacer?:\\n- Registrar un nuevo libro(L)\\n- Registrar un nuevo usuario/a(U)\\n- Sacar un préstamo(P)\\n- Devolver un préstamo(D)\\n- Mostrar todos los libros(M)\\n- Mostrar todos los usuarios/as(A)\\n- Salir(S)\\n-----> \").upper()\n    if option == \"L\":\n        register_book.register_book()\n    elif option == \"U\":\n        register_user.register_user()\n    elif option == \"P\":\n        my_loan.pick_book()\n    elif option == \"D\":\n        my_loan.return_book()\n    elif option == \"M\":\n        my_srp_library.show_books()\n    elif option == \"A\":\n        my_srp_library.show_users()\n    elif option == \"S\":\n        print(\"Gracias por usar el sistema de la Biblioteca SI-SRP\")\n        break\n    else:\n        logging.warning(\"Opción no válida\")\n        print(\"La opción que has elegido no es válida, prueba de nuevo: \")\n\"\"\"\nPOSIBLES MEJORAS\n- Regex tanto en nombres como en los emails\n- Manejo de excepciones, sobre todo en datos int.\n- Dentro de usuario, parámetro \"prestamo\" para guardar el préstamo y no preguntarlo\n\"\"\"\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/hectorio23.py",
    "content": "# Autor: Héctor Adán \n# GitHub: https://github.com/hectorio23\nimport os\n\n'''\n * EJERCICIO:\n * Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n * Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA:\n * Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n * manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n * y el procesamiento de préstamos de libros.\n * Requisitos:\n * 1. Registrar libros: El sistema debe permitir agregar nuevos libros con \n * información básica como título, autor y número de copias disponibles.\n * 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n * información básica como nombre, número de identificación y correo electrónico.\n * 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n * tomar prestados y devolver libros.\n'''\n\nclass Book:\n    def __init__(self, title, author, copies):\n        self.title = title\n        self.author = author\n        self.copies = copies\n\nclass BookManager:\n    def __init__(self):\n        self.books = []\n\n    def add_book(self):\n        os.system('clear')\n        title = input(\"Ingrese el título del libro: \")\n        author = input(\"Ingrese el autor del libro: \")\n        copies = int(input(\"Ingrese el número de copias: \"))\n        self.books.append(Book(title, author, copies))\n        print(\"Libro agregado exitosamente.\")\n\n    def list_books(self):\n        os.system('clear')\n        if not self.books:\n            print(\"No hay libros disponibles.\")\n            return\n        for book in self.books:\n            print(f\"Título: {book.title}, Autor: {book.author}, Copias: {book.copies}\")\n\nclass User:\n    def __init__(self, name, user_id, email):\n        self.name = name\n        self.id = user_id\n        self.email = email\n\nclass UserManager:\n    def __init__(self):\n        self.users = []\n\n    def add_user(self):\n        os.system('clear')\n        name = input(\"Ingrese el nombre del usuario: \")\n        user_id = int(input(\"Ingrese el ID del usuario: \"))\n        email = input(\"Ingrese el correo electrónico del usuario: \")\n        self.users.append(User(name, user_id, email))\n        print(\"Usuario agregado exitosamente.\")\n\n    def list_users(self):\n        os.system('clear')\n        if not self.users:\n            print(\"No hay usuarios registrados.\")\n            return\n        for user in self.users:\n            print(f\"Nombre: {user.name}, ID: {user.id}, Correo: {user.email}\")\n\nclass LoanManager:\n    def lend_book(self, user_manager, book_manager):\n        os.system('clear')\n        user_id = int(input(\"Ingrese el ID del usuario: \"))\n        book_title = input(\"Ingrese el título del libro a prestar: \")\n        # Lógica de préstamo\n        print(f\"Libro '{book_title}' prestado al usuario ID {user_id}.\")\n\n    def return_book(self, user_manager, book_manager):\n        os.system('clear')\n        user_id = int(input(\"Ingrese el ID del usuario: \"))\n        book_title = input(\"Ingrese el título del libro a devolver: \")\n        # Lógica de devolución\n        print(f\"Libro '{book_title}' devuelto por el usuario ID {user_id}.\")\n\ndef display_menu():\n    os.system('clear')\n    print(\"******** Menú de la Biblioteca ********\")\n    print(\"[1] - Agregar un libro\")\n    print(\"[2] - Listar libros\")\n    print(\"[3] - Agregar un usuario\")\n    print(\"[4] - Listar usuarios\")\n    print(\"[5] - Prestar un libro\")\n    print(\"[6] - Devolver un libro\")\n    print(\"[7] - Salir\")\n    return int(input(\"Seleccione una opción: \"))\n\ndef main():\n    book_manager = BookManager()\n    user_manager = UserManager()\n    loan_manager = LoanManager()\n    option = 0\n\n    while option != 7:\n        option = display_menu()\n        if option == 1:\n            book_manager.add_book()\n        elif option == 2:\n            book_manager.list_books()\n        elif option == 3:\n            user_manager.add_user()\n        elif option == 4:\n            user_manager.list_users()\n        elif option == 5:\n            loan_manager.lend_book(user_manager, book_manager)\n        elif option == 6:\n            loan_manager.return_book(user_manager, book_manager)\n        elif option == 7:\n            print(\"Saliendo del sistema...\")\n        else:\n            print(\"Opción no válida. Intente de nuevo.\")\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/hozlucas28.py",
    "content": "# pylint: disable=missing-module-docstring,missing-class-docstring,missing-function-docstring,pointless-string-statement,line-too-long\n\nfrom typing import Self\n\n\n\"\"\"\n    Single Responsibility Principle (SRP)...\n\"\"\"\n\nprint(\"Single Responsibility Principle (SRP)...\")\n\nprint(\"\\nBad implementation of Single Responsibility Principle (SRP)...\")\n\n\nclass BadOrder:\n    dish: str\n    owner: str\n    price: float\n    uid: int\n\n    def __init__(self, *, dish: str, owner: str, price: float, uid: int) -> None:\n        self.dish = dish\n        self.owner = owner\n        self.price = price\n        self.uid = uid\n\n    def process(self) -> Self:\n        print(f\"\\nOrder {self.uid} processed!\")\n        return self\n\n    def send_invoice(self) -> Self:\n        print(f\"\\nInvoice of order {self.uid} sent!\")\n        return self\n\n\nprint(\n    \"\\n```\",\n    \"\"\"class BadOrder:\n    dish: str\n    owner: str\n    price: float\n    uid: int\n\n    def __init__(self, *, dish: str, owner: str, price: float, uid: int) -> None:\n        self.dish = dish\n        self.owner = owner\n        self.price = price\n        self.uid = uid\n\n    def process(self) -> Self:\n        print(f\"\\\\nOrder {self.uid} processed!\")\n        return self\n\n    def send_invoice(self) -> Self:\n        print(f\"\\\\nInvoice of order {self.uid} sent!\")\n        return self\"\"\",\n    \"```\",\n    sep=\"\\n\",\n)\n\nprint(\n    \"\\nThis is a bad implementation of Single Responsibility Principle (SRP), \",\n    \"because the class 'BadOrder' has three responsibilities:\\n\",\n    \"1°) Order creation.\",\n    \"2°) Order process.\",\n    \"3°) Invoice communication.\",\n    sep=\"\\n\",\n)\n\n\nprint(\"\\nGood implementation of Single Responsibility Principle (SRP)...\")\n\n\nclass GoodOrder:\n    dish: str\n    owner: str\n    price: float\n    uid: int\n\n    def __init__(self, *, dish: str, owner: str, price: float, uid: int) -> None:\n        self.dish = dish\n        self.owner = owner\n        self.price = price\n        self.uid = uid\n\n\nclass GoodOrderProcessor:\n    order: GoodOrder\n\n    def __init__(self, *, order: GoodOrder) -> None:\n        self.order = order\n\n    def process(self) -> Self:\n        print(f\"\\nOrder {self.order.uid} processed!\")\n        return self\n\n\nclass GoodOrderInvoice:\n    order: GoodOrder\n\n    def __init__(self, *, order: GoodOrder) -> None:\n        self.order = order\n\n    def send(self) -> Self:\n        print(f\"\\nInvoice of order {self.order.uid} sent!\")\n        return self\n\n\nprint(\n    \"\\n```\",\n    \"\"\"class GoodOrder:\n    dish: str\n    owner: str\n    price: float\n    uid: int\n\n    def __init__(self, *, dish: str, owner: str, price: float, uid: int) -> None:\n        self.dish = dish\n        self.owner = owner\n        self.price = price\n        self.uid = uid\n\n\nclass GoodOrderProcessor:\n    order: GoodOrder\n\n    def __init__(self, *, order: GoodOrder) -> None:\n        self.order = order\n\n    def process(self) -> Self:\n        print(f\"\\\\nOrder {self.order.uid} processed!\")\n        return self\n\n\nclass GoodOrderInvoice:\n    order: GoodOrder\n\n    def __init__(self, *, order: GoodOrder) -> None:\n        self.order = order\n\n    def send(self) -> Self:\n        print(f\"\\\\nInvoice of order {self.order.uid} sent!\")\n        return self\"\"\",\n    \"```\",\n    sep=\"\\n\",\n)\n\nprint(\n    \"\\nThis is a good implementation of Single Responsibility Principle (SRP), \",\n    \"because each class ('GoodOrder', 'GoodOrderProcessor', and 'GoodOrderInvoice') \",\n    \"has only one responsability (order creation, order processing, and order invoice communication).\",\n    sep=\"\\n\",\n)\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/idiegorojas.py",
    "content": "\"\"\"\n26 - Principios de Responsabilidad Unica (SRP)\n\"\"\"\n# \"Una clase debe tener una, y solo una, razon para cambiar.\"\n# Una clase solamente debe tener una unica responsbilidad o funcion en el sistema.\n\n\"\"\"\nBeneficios\n\"\"\"\n# Mantenibilidad mejorada: Cada clase es más pequeña y enfocada, lo que facilita la comprensión y modificación.\n# Código más testeable: Es más fácil escribir pruebas unitarias para clases con una sola responsabilidad.\n# Reducción de acoplamiento: Las clases dependen menos unas de otras.\n# Mayor reutilización: Servicios como el de email pueden reutilizarse en diferentes contextos.\n# Cambios más localizados: Si cambia la forma de autenticación, solo necesitamos modificar ServicioAutenticacion.\n\n\"\"\"\n¿Cómo identificar si una clase viola el SRP?\n\"\"\"\n# Si al describir lo que hace la clase usas \"y\" o \"también\", probablemente tenga más de una responsabilidad.\n# Si los métodos de la clase manipulan diferentes tipos de datos o recursos.\n# Si los cambios en una parte del código afectan a funcionalidades no relacionadas.\n\n\"\"\"\nEjemplo\n\"\"\"\n\nclass Usuario:\n    def __init__(self, nombre: str, email:str):\n        self.nombre = nombre\n        self.email = email\n        self.esta_logueado = False\n\n    def actualizar_estado_login(self, esta_logueado: bool):\n        self.esta_logueado = esta_logueado\n\n    \nclass Autenticacion:\n    def login(self, usuario: Usuario):\n        print(f'El usuario {usuario.nombre} ha iniciado sesion.')\n        usuario.actualizar_estado_login(True)\n\n    def logout(self, usuario: Usuario):\n        print(f'El usuario {usuario.nombre} ha cerrado sesion.')\n        usuario.actualizar_estado_login(False)\n\nusuario = Usuario('Diego', 'diego@example.com')\nautenticacion_usuario = Autenticacion()\n\nautenticacion_usuario.login(usuario)\nautenticacion_usuario.logout(usuario)\n\n\n\"\"\"\nExtra\n\"\"\"\n# Gestion sistema de biblioteca\n# Resgistrar libros\n# Registrar usuarios\n# Prestamo de libro\n\n\nclass Users:\n    def __init__(self, name: str, id: int, email: str):\n        self.name = name\n        self.id = id\n        self.email = email\n\nclass Books:\n    def __init__(self, title: str, author:str, available_copies: int):\n        self.title = title\n        self.author = author\n        self.available_copies = available_copies\n\nclass BookLoans:\n    def __init__(self):\n        self.loans = []\n    \n    def lend_book(self, user: Users, book: Books):\n        if book.available_copies > 0:\n            book.available_copies -= 1\n            self.loans.append({'user_id': user.id, 'title_book': book.title})\n            print(f'El libro {book.title} a sido prestado con exito')\n        else:\n            print(f'Lo sentimos el libro {book.title} no tiene copias actualmente.')\n\n    def return_book(self, user: Users, book:Books):\n        for loan in self.loans:\n            if loan['user_id'] == user.id and loan['title_book'] == book.title:\n                self.loans.remove(loan)\n                book.available_copies += 1\n                print(f'El libro {book.title} ha sido devuelto con exito.')\n            else:\n                print(f'El libro no se ha devuelto.')\n\n\nusuario_1 = Users('Diego', 1, 'diego@example.com')\nusuario_2 = Users('Andres', 2, 'andres@example.com')\nlibro_1 = Books('El Hobbit', 'J.R.R. Tolkien', 1)\n\nprestamo_libro = BookLoans()\nprestamo_libro.lend_book(usuario_1, libro_1)\nprestamo_libro.lend_book(usuario_2, libro_1)\nprestamo_libro.return_book(usuario_1, libro_1)\nprestamo_libro.lend_book(usuario_2, libro_1)"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/ignaciovihe.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n * Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n\"\"\"\n\n\n#Esta clase no cumple SRP (Single Responsibility Principle)\n#La clase tiene 3 responsabilidades:\n    #Contener los datos del estudiante\n    #Registrar un estudiante\n    #Enviar email de bienvenida.\n# Si se necesita modificar cualquiera de las tres hay que modificar la misma clase\n# lo que podría romper todo\nclass Student:\n\n    def __init__(self, name: str, email: str):\n        self.name = name\n        self.email = email\n\n    def register_student(self):\n        print(f\"Registrando el estudiante {self.name} en la base de datos.\") #Simulamos el registro en la base de datos.\n\n    def send_email(self):\n        print(f\"Enviando email de bienbenida a {self.email}\") # simulamos el envio de correo.\n\nstudent = Student(\"Pedro\", \"pedro@email.com\")\nstudent.register_student()\nstudent.send_email()\n\n\n# Mismo caso cumpliendo SRP.\n# Separamos resposabilidades. De esta forma si tenemos que modificar alguna solo tocamos esa parte.\n\nclass Student:\n    def __init__(self, name: str, email: str):\n        self.name = name\n        self.email = email\n\nclass RegisterService:\n    def register_DDBB(self, student: Student):\n        print(f\"Registrando el estudiante {student.name} en la base de datos.\") #Simulamos el registro en la base de datos.\n\nclass EmailService:\n    def send_email(self, student: Student):\n        print(f\"Enviando email de bienbenida a {student.email}\") # simulamos el envio de correo.\n\nstudent = Student(\"Ignacio\", \"ignacio@email.com\")\n\nregister = RegisterService()\nregister.register_DDBB(student)\n\nsender = EmailService()\nsender.send_email(student)\n\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n * Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n * manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n * y el procesamiento de préstamos de libros.\n * Requisitos:\n * 1. Registrar libros: El sistema debe permitir agregar nuevos libros con \n * información básica como título, autor y número de copias disponibles.\n * 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n * información básica como nombre, número de identificación y correo electrónico.\n * 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n * tomar prestados y devolver libros.\n * Instrucciones:\n * 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n * los tres aspectos mencionados anteriormente (registro de libros, registro de\n * usuarios y procesamiento de préstamos).\n * 2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n * siguiendo el Principio de Responsabilidad Única.\n\"\"\"\n# No cumple SRP\nclass Library:\n\n    def __init__(self):\n        self.books = {}\n        self.users = {}\n        self.book_loans = {}\n\n    def register_book(self, title: str, writer: str, copies_available: int):\n        if title not in self.books:\n            self.books[title] = {\"writer\": writer, \"copies_available\": copies_available}\n        else:\n            print(f\" El libro {title} ya esta registrado.\")\n\n    def register_user(self, name, email):\n        self.users[len(self.users)] = {\"name\": name, \"email\": email}\n\n    def borrowBook(self, title, user_id):\n        if title in self.books and user_id in self.users:\n            if self.books[title][\"copies_available\"] > 0:\n                if user_id not in self.book_loans:\n                    self.book_loans[user_id] = [title]\n                    self.books[title][\"copies_available\"] -= 1\n                else:\n                    if title not in self.book_loans[user_id]:\n                        self.book_loans[user_id].append(title)\n                        self.books[title][\"copies_available\"] -= 1\n                    else:\n                        print(f\"El usuario {user_id} ya tiene prestado el libro {title}\")\n            else:\n                print(f\"El libro {title} no esta disponible temporalmente.\")\n        else:\n            print(F\"El libro no esta disponible en la biblioteca o usuario no registrado\")\n\n    def return_book(self, title, user_id):\n        if user_id in self.book_loans:\n            if title in self.book_loans[user_id]:\n                self.book_loans[user_id].remove(title)\n                self.books[title][\"copies_available\"] += 1\n            else:\n                print(f\"El usuario con id {user_id} no tiene prestado el libro {title}\")\n        else:\n            print(f\"Id usuario incorrecto\")\n\n\n\nmy_library = Library()\nmy_library.register_book(\"La comunidad del anillo\", \"JRR Tolkien\", 3)\nmy_library.register_user(\"Pedro\",\"pedro@email.com\")\nmy_library.register_book(\"Las dos Torres\", \"JRR Tolkien\", 2)\nmy_library.register_user(\"Ignacio\",\"ignacio@email.com\")\nmy_library.register_user(\"Lore\",\"lore@email.com\")\nmy_library.register_user(\"Jaun\",\"juan@email.com\")\nmy_library.borrowBook(\"La comunidad del anillo\", 1)\nmy_library.borrowBook(\"Las dos Torres\", 0)\nmy_library.borrowBook(\"La comunidad del anillo\", 0)\nmy_library.borrowBook(\"La comunidad del anillo\", 0)\nmy_library.borrowBook(\"La comunidad del anillo\", 2)\nmy_library.borrowBook(\"La comunidad del anillo\", 3)\nmy_library.borrowBook(\"Las dos Torres\", 3)\nprint(my_library.books)\nprint(my_library.users)\nprint(my_library.book_loans)\n\nmy_library.return_book(\"La comunidad del anillo\", 1)\nmy_library.borrowBook(\"La comunidad del anillo\", 3)\nprint(my_library.books)\nprint(my_library.users)\nprint(my_library.book_loans)\n\n\n# Cumple SRP\n\nclass Book: #Contiene la info de un libro y modifica su número de copias.\n\n    def __init__(self, title: str, writer: str, copies: int):\n        self.title = title\n        self.writer = writer\n        self.copies = copies\n    \n    def increment_copies(self):\n        self.copies += 1\n\n    def decrement_copies(self):\n        self.copies -= 1\n\n\n\nclass User: #Contiene la info de un usuario creando su identificador automaticamente.\n\n    index = 1\n    def __init__(self, name: str, email: str):\n        self.name = name\n        self.email = email\n        self.user_id = User.index\n        User.index += 1\n\n\n\nclass Loan: # Contiene la info de un prestamo uniendo un libro con un usuario.\n\n    def __init__(self, user: User, book: Book):\n        self.user = user\n        self.book = book\n\n\n\nclass Library:  # Contiene la info de libros usuarios y prestamos. Se podria ser mas estricto separando el registro\n                # de usuarios y libros en otras clases UserManager y BookManager, pero es aceptable.\n    def __init__(self):\n        self.books = {}\n        self.users = {}\n        self.loans = {}\n\n    def register_user(self, user: User):\n        self.users[user.user_id] = user\n\n    def register_book(self, book : Book):\n        self.books[book.title] = book\n\n\n\nclass LoanManager: # Se encarga de gestionar la logica de los prestamos.\n\n    def __init__(self, library: Library):\n        self.library = library\n\n    def _check_borrowed(self, title: str, loans):\n        for loan in loans:\n            if title == loan.book.title:\n                return True\n        return False\n\n    def borrow_book(self, loan: Loan):\n        if self.library.books[loan.book.title].copies > 0:\n            if loan.user.user_id not in self.library.loans:\n                self.library.loans[loan.user.user_id] = []\n                self.library.loans[loan.user.user_id].append(loan)\n                self.library.books[loan.book.title].decrement_copies()\n            else:\n                if not self._check_borrowed(loan.book.title, self.library.loans[loan.user.user_id]):\n                    self.library.loans[loan.user.user_id].append(loan)\n                    self.library.books[loan.book.title].decrement_copies()\n                else:\n                    print(f\"El usuario ya tiene una copia del libro '{loan.book.title}'\")\n        else:\n            print(f\"El libro {loan.book.title} no esta disponible temporalmente.\")\n\n    def return_book(self, loan: Loan):\n            for l in self.library.loans[loan.user.user_id]:\n                if loan.book.title == l.book.title:\n                    self.library.loans[loan.user.user_id].remove(l)\n                    self.library.books[loan.book.title].increment_copies()\n                    return True\n            print(f\"El usuario no tiene el libro {loan.book.title}.\")\n            return False\n\n\n\nclass LibraryPrinter: #Imprime los datos de la biblioteca pasada.\n\n    def __init__(self, library: Library):\n        self.library = library\n\n    def print_users(self):\n        for key, user in self.library.users.items():\n            print(f\"USER_ID: {key} - NAME: {user.name} - EMAIL: {user.email}\")\n\n    def print_books(self):\n        for key, book in self.library.books.items():\n            print(f\"TITLE: {key} - WRITER: {book.writer} - COPIES: {book.copies}\")\n\n    def print_loans(self):\n        for user_id, loans in self.library.loans.items():\n            print(f\"USER_ID: {user_id}:\")\n            for loan in loans:\n                print(f\"\\t{loan.book.title}\")\n\n\n\nmy_library = Library()\nlibrary_printer = LibraryPrinter(my_library)\nloan_manager = LoanManager(my_library)\n\nbook1 = Book(\"La comunidad del anillo\", \"JRR Tolkien\", 3)\nmy_library.register_book(book1)\nbook2 = Book(\"Las dos torres\", \"JRR Tolkien\", 2)\nmy_library.register_book(book2)\nbook3 = Book(\"El rotorno del rey\", \"JRR Tolkien\", 1)\nmy_library.register_book(book3)\nuser1 = User(\"Pedro\",\"pedro@email.com\")\nmy_library.register_user(user1)\nuser2 = User(\"Ignacio\",\"ignacio@email.com\")\nmy_library.register_user(user2)\nuser3 = User(\"Lore\",\"lore@email.com\")\nmy_library.register_user(user3)\nuser4 = User(\"Juan\",\"juan@email.com\")\nmy_library.register_user(user4)\nloan = Loan(user1, book1)\nloan_manager.borrow_book(loan)\nloan = Loan(user1, book2)\nloan_manager.borrow_book(loan)\nloan = Loan(user1, book1)\nloan_manager.borrow_book(loan)\nloan = Loan(user2, book1)\nloan_manager.borrow_book(loan)\nloan = Loan(user3, book1)\nloan_manager.borrow_book(loan)\nloan = Loan(user4, book1)\nloan_manager.borrow_book(loan)\nloan = Loan(user4, book2)\nloan_manager.borrow_book(loan)\nlibrary_printer.print_loans()\nloan = Loan(user1, book1)\nloan_manager.return_book(loan)\nloan = Loan(user4, book1)\nloan_manager.borrow_book(loan)\nloan = Loan(user1, book2)\nloan_manager.return_book(loan)\nloan = Loan(user3, book1)\nloan_manager.return_book(loan)\n\nlibrary_printer.print_users()\nlibrary_printer.print_books()\nlibrary_printer.print_loans()"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/isilanes.py",
    "content": "from datetime import datetime\n\n\ndef bill_amount(amount: float, tax_rate: float = 21.0, book: str = \"default_book.log\") -> float:\n    total_amount = amount * (1 + tax_rate / 100)\n\n    print(f\"Facturamos {total_amount:.2f} eur ({amount:.2f} + tasas) en '{book}'\")\n\n\ndef get_taxable_data(amount: float, tax_rate: float = 21.0) -> dict:\n    taxes = amount * tax_rate / 100\n\n    return {\n        \"base\": amount,\n        \"taxes\": taxes,\n        \"total\": amount + taxes,\n    }\n\n\ndef save_bill(taxable: dict, book: str = \"default_book.log\"):\n    base = taxable.get(\"base\")\n    total = taxable.get(\"total\")\n    if not base or not total:\n        return\n\n    print(f\"Facturamos {total:.2f} eur ({base:.2f} + tasas) en '{book}'\")\n\n\nclass Library:\n    def __init__(self):\n        self.books = {}\n        self.users = {}\n\n    def register_book(self, book_id: int, title: str | None = None, author: str | None = None, amount: int = 1):\n        if book_id in self.books:\n            self.books[book_id][\"amount\"] += amount\n            if amount == 1:\n                print(f\"Nuevo ejemplar del libro '{title}' con ID {book_id} añadido.\")\n            else:\n                print(f\"{amount} ejemplares del libro '{title}' con ID {book_id} añadidos.\")\n            return\n\n        self.books[book_id] = {\n            \"title\": title,\n            \"author\": author,\n            \"amount\": amount,\n            \"borrowed\": 0,\n        }\n        if amount == 1:\n            print(f\"Libro '{title}' registrado con ID {book_id}\")\n        else:\n            print(f\"{amount} ejemplares del libro '{title}' con ID {book_id} registrados.\")\n\n    def register_user(self, user_id: int, name: str, email: str):\n        self.users[user_id] = {\n            \"name\": name,\n            \"email\": email,\n            \"borrowed_books\": {},\n        }\n        print(f\"Usuario '{name}' registrado con ID {user_id}\")\n\n    def borrow_book(self, user_id: int, book_id: int):\n        if book_id not in self.books:\n            print(f\"No hay libro con ID {book_id}\")\n            return\n\n        if self.books[book_id][\"amount\"] == 0:\n            print(f\"No hay copias disponibles de libro con ID {book_id}\")\n            return\n\n        if book_id in self.users[user_id][\"borrowed_books\"]:\n            print(f\"El usuario con ID {user_id} ya tiene un ejemplar del libro con ID {book_id}\")\n            return\n\n        self.books[book_id][\"amount\"] -= 1\n        self.books[book_id][\"borrowed\"] += 1\n        self.users[user_id][\"borrowed_books\"][book_id] = datetime.now()\n        print(f\"Libro con ID {book_id} prestado a {self.users[user_id]['name']}\")\n\n    def return_book(self, user_id: int, book_id: int):\n        if book_id not in self.books:\n            print(f\"No conocemos un libro con ID {book_id}\")\n            return\n\n        if user_id not in self.users:\n            print(f\"No conocemos a un usuario con ID {user_id}\")\n            return\n\n        self.books[book_id][\"amount\"] += 1\n        self.books[book_id][\"borrowed\"] -= 1\n        print(f\"Libro con ID {book_id} devuelto por {self.users[user_id]['name']}\")\n\n\nclass User:\n\n    def __init__(self, user_id: int, name: str, email: str):\n        self.user_id = user_id\n        self.name = name\n        self.email = email\n\n\nclass Book:\n\n    def __init__(self, book_id: int, title: str, author: str):\n        self.book_id = book_id\n        self.title = title\n        self.author = author\n\n\nclass UserRegistry:\n\n    def __init__(self):\n        self.users = {}\n\n    def register_user(self, user: User) -> None:\n        if user.user_id in self.users:\n            print(f\"El usuario con ID {user.user_id} ya existe en el registro.\")\n            return\n\n        self.users[user.user_id] = user\n        print(f\"Usuario '{user.name}' registrado con ID {user.user_id}\")\n\n    def is_registered(self, user: User) -> bool:\n        return user.user_id in self.users\n\n\nclass BookRegistry:\n\n    def __init__(self):\n        self.books = {}\n        self.borrowed = {}\n        self.amount = {}\n\n    def register_book(self, book: Book):\n        if book.book_id in self.books:\n            self.amount[book.book_id] += 1\n            print(f\"Registramos un nuevo ejemplar del libro '{book.title}' con ID {book.book_id}\")\n            return\n\n        self.books[book.book_id] = book\n        self.amount[book.book_id] = 1\n        print(f\"Primer ejemplar del libro '{book.title}' registrado con ID {book.book_id}\")\n\n    def borrow_book(self, book: Book, user: User, user_registry: UserRegistry) -> None:\n        if not user_registry.is_registered(user):\n            print(f\"El usuario con ID {user.user_id} no está registrado.\")\n            return\n\n        if book.book_id not in self.books:\n            print(f\"No hay libro con ID {book.book_id}\")\n            return\n\n        if self.amount[book.book_id] == 0:\n            print(f\"No hay copias disponibles de libro con ID {book.book_id}\")\n            return\n\n        borrowed = self.borrowed.get(book.book_id)\n        if borrowed and user.user_id in borrowed:\n            print(f\"El usuario con ID {user.user_id} ya tiene un ejemplar del libro con ID {book.book_id}\")\n            return\n\n        self.amount[book.book_id] -= 1\n        self.borrowed[book.book_id] = self.borrowed.get(book.book_id, {})\n        self.borrowed[book.book_id][user.user_id] = datetime.now()\n        print(f\"Prestamos el libro '{book.title}' con ID {book.book_id} a {user.name}\")\n\n    def return_book(self, book: Book, user: User, user_registry: UserRegistry) -> None:\n        if not user_registry.is_registered(user):\n            print(f\"El usuario con ID {user.user_id} no está registrado.\")\n            return\n\n        if book.book_id not in self.books:\n            print(f\"No conocemos un libro con ID {book.book_id}\")\n            return\n\n        borrowed = self.borrowed.get(book.book_id)\n        if not borrowed:\n            print(f\"No hay ejemplares prestados de libro con ID {book.book_id}\")\n            return\n\n        if user.user_id not in borrowed:\n            print(f\"El usuario con ID {user.user_id} no tiene un ejemplar del libro con ID {book.book_id}\")\n            return\n\n        self.amount[book.book_id] += 1\n        del self.borrowed[book.book_id][user.user_id]\n        print(f\"El usuario con ID {user.user_id} devuelve el libro '{book.title}' con ID {book.book_id}\")\n\n\ndef main():\n    print(\"===== MAIN =====\")\n    print(\"Con la implementación no-SRP, tenemos una función que hace dos cosas:\")\n    print(\"1. calcula los impuestos\")\n    print(\"2. guarda la factura.\")\n    print(\">>> bill_amount(100, 21)\")\n    bill_amount(100, 21)\n\n    print(\"\\nAquí el problema es que tendremos que modificar bill_amount() en dos circunstancias:\")\n    print(\"1. Si se modifica algo relativo a cómo se calculan los impuestos (por ejemplo,\")\n    print(\"   que en lugar de aplicar un porcentaje fijo, se sume una constante, o que\")\n    print(\"   el procentaje dependa de la cantidad base).\")\n    print(\"2. Si se modifica algo relacionado con cómo se guarda la factura (por ejemplo,\")\n    print(\"   que en lugar de guardar la factura en un archivo, se guarde en una base de datos,\")\n    print(\"   o que se quiera guardar la información en otro formato).\")\n\n    print(\"\\nCon una implementación SRP, hemos separado las dos responsabilidades en dos funciones:\")\n    print('taxable_data = get_taxable_data(250, 15)')\n    print('save_bill(taxable_data)')\n    taxable_data = get_taxable_data(250, 15)\n    save_bill(taxable_data)\n\n    print(\"\\nDe esta manera, si el cálculo de los impuestos cambia, sólo tendremos que modificar la\")\n    print(\"función get_taxable_data(). Por otro lado, si se quiere cambiar cómo se guarda la factura,\")\n    print(\"sólo tendremos que modificar la función save_bill().\")\n    print(\"El único requisito común es que ambas funciones respeten el contrato de que get_taxable_data()\")\n    print(\"devuelva un diccionario compatible con lo que save_bill() espera. En un caso real, podríamos usar\")\n    print(\"una clase ad hoc para esto, y forzar que una función devuelva un objeto de esa clase, y la otra lo use.\")\n\n\ndef extra():\n    print(\"\\n===== EXTRA =====\")\n    print(\"Versión monolítica. Todo ocurrirá en un objeto de la clase Library:\")\n    print('>>> library = Library()')\n    library = Library()\n\n    print(\"\\nRegistramos un libro y un usuario:\")\n    print('>>> library.register_book(1, \"El Quijote de la Mancha\", \"Yo\", 5)')\n    library.register_book(1, \"El Quijote de la Mancha\", \"Yo\", 5)\n    print('>>> library.register_user(1, \"Chiquito\", \"chiquito@example.com\")')\n    library.register_user(1, \"Chiquito\", \"chiquito@example.com\")\n\n    print(\"\\nPrestamos un libro al usuario:\")\n    print('library.borrow_book(user_id=1, book_id=1)')\n    library.borrow_book(user_id=1, book_id=1)\n\n    print(\"\\nEl mismo usuario no puede sacar otro ejemplar del libro:\")\n    print('>>> library.borrow_book(user_id=1, book_id=1)')\n    library.borrow_book(user_id=1, book_id=1)\n\n    print(\"\\nEl usuario devuelve el libro:\")\n    print('>>> library.return_book(user_id=1, book_id=1)')\n    library.return_book(user_id=1, book_id=1)\n\n    print(\"\\nEn la versión SRP tendremos que instanciar varios objetos:\")\n    print('>>> book_registry = BookRegistry()')\n    book_registry = BookRegistry()\n    print('>>> user_registry = UserRegistry()')\n    user_registry = UserRegistry()\n    print('>>> book = Book(1, \"El lazarillo de Tormes\", \"Yo\")')\n    book = Book(1, \"El lazarillo de Tormes\", \"Yo\")\n    print('>>> user = User(1, \"Carl Sagan\", \"carl@example.com\")')\n    user = User(1, \"Carl Sagan\", \"carl@example.com\")\n\n    print(\"\\nRegistraremos el libro y el usuario creados en sus respectivos registros:\")\n    print('>>> book_registry.register_book(book)')\n    book_registry.register_book(book)\n    print('>>> user_registry.register_user(user)')\n    user_registry.register_user(user)\n\n    print(\"\\nPrestamos un libro al usuario:\")\n    print('>>> book_registry.borrow_book(user=user, book=book, user_registry=user_registry)')\n    book_registry.borrow_book(user=user, book=book, user_registry=user_registry)\n\n    print(\"\\nCreamos y registramos a un segundo usuario:\")\n    print('>>> user2 = User(2, \"Isaac Asimov\", \"isaac@example.com\")')\n    user2 = User(2, \"Isaac Asimov\", \"isaac@example.com\")\n    print('>>> user_registry.register_user(user2)')\n    user_registry.register_user(user2)\n\n    print(\"\\nRegistramos un segundo ejemplar del libro:\")\n    print('>>> book_registry.register_book(book)')\n    book_registry.register_book(book)\n\n    print(\"\\nEl primer usuario no puede sacar otro ejemplar del libro\")\n    print('>>> book_registry.borrow_book(user=user, book=book, user_registry=user_registry)')\n    book_registry.borrow_book(user=user, book=book, user_registry=user_registry)\n\n    print(\"\\nPero el segundo usuario sí puede:\")\n    print('>>> book_registry.borrow_book(user=user2, book=book, user_registry=user_registry)')\n    book_registry.borrow_book(user=user2, book=book, user_registry=user_registry)\n\n    print(\"\\nSi el primer usuario devuelve el libro, luego puede volver a sacarlo:\")\n    print('>>> book_registry.return_book(user=user, book=book, user_registry=user_registry)')\n    book_registry.return_book(user=user, book=book, user_registry=user_registry)\n    print('>>> book_registry.borrow_book(user=user, book=book, user_registry=user_registry)')\n    book_registry.borrow_book(user=user, book=book, user_registry=user_registry)\n\n    print(\"\\nUn tercer usuario no registrado no puede sacar libros:\")\n    print('>>> user3 = User(3, \"Isaac Newton\", \"isaac2@example.com\")')\n    user3 = User(3, \"Isaac Newton\", \"isaac2@example.com\")\n    print('>>> book_registry.borrow_book(user=user3, book=book, user_registry=user_registry)')\n    book_registry.borrow_book(user=user3, book=book, user_registry=user_registry)\n\n    print(\"\\nSi lo registramos, ahora sí podrá sacar libros (pero no del libro 1,\")\n    print(\"puesto que los dos ejemplares que hay están prestados).\")\n    print('>>> user_registry.register_user(user3)')\n    user_registry.register_user(user3)\n    print('>>> book_registry.borrow_book(user=user3, book=book, user_registry=user_registry)')\n    book_registry.borrow_book(user=user3, book=book, user_registry=user_registry)\n\n\nif __name__ == \"__main__\":\n    main()\n    extra()\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/javierfiestasbotella.py",
    "content": "'''/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n * Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n * manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n * y el procesamiento de préstamos de libros.\n * Requisitos:\n * 1. Registrar libros: El sistema debe permitir agregar nuevos libros con \n * información básica como título, autor y número de copias disponibles.\n * 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n * información básica como nombre, número de identificación y correo electrónico.\n * 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n * tomar prestados y devolver libros.\n * Instrucciones:\n * 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n * los tres aspectos mencionados anteriormente (registro de libros, registro de\n * usuarios y procesamiento de préstamos).\n * 2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n * siguiendo el Principio de Responsabilidad Única.\n */'''\n\n#Ejemplo de SOLID Creamos 3 clases cada una con una funcion\nclass Factura:\n    def __init__(self, items):\n        self.items = items \n    def calcular_total(self):\n        return sum(item['precio'] for item in self.items)\n\nclass ImpresoraDeFacturas:\n    def imprimir_factura(self, factura):\n        print(\"Factura:\")\n        for item in factura.items:\n            print(f\"{item['nombre']}: {item['precio']}\")\n        print(f\"Total: {factura.calcular_total()}\")\n\nclass GuardarFactura:\n    def guardar_en_bd(self, factura):\n        print(\"Guardando la factura en la base de datos...\")\n   \n#Ahora creamos lo que no se debería hacer una sola clase con las trés funciones\nclass Factura:\n    def __init__(self, items):\n        self.items = items\n\n    def calcular_total(self):\n        return sum(item['precio'] for item in self.items)\n\n    def imprimir_factura(self):\n        print(\"Factura:\")\n        for item in self.items:\n            print(f\"{item['nombre']}: {item['precio']}\")\n        print(f\"Total: {self.calcular_total()}\")\n\n    def guardar_en_bd(self):\n        print(\"Guardando la factura en la base de datos...\")\n\n\n#EJEMPLO DE LA BIBLIOTECA\n\n'''* 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n * los tres aspectos mencionados anteriormente (registro de libros, registro de\n * usuarios y procesamiento de préstamos).'''\n \nclass Biblioteca:\n    def __init__(self, items):\n        self.items = items\n\n    def registrar_libro(self):\n        registro=[]\n        for item in self.items:\n            registro.append(item['numero_libro']+item['titulo_libro']+item['autor_libro'])\n    def registrar_usuario(self):\n        bbdd=[]\n        for item in self.items:\n            bbdd.append(item['dni']+item['nombre'])\n    def prestamos(self):\n        prestamos_note=[]\n        for item in self.items:\n            prestamos_note.append(item['dni']+item['titulo_libro'])\n\n'''* 2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n * siguiendo el Principio de Responsabilidad Única.'''\n\nclass RegistroLibros:\n    def __init__(self):\n        self.libros = []\n\n    def registrar_libro(self, numero_libro, titulo_libro, autor_libro):\n        libro = {\n            'numero_libro': numero_libro,\n            'titulo_libro': titulo_libro,\n            'autor_libro': autor_libro,\n            'copias_disponibles': 1\n        }\n        self.libros.append(libro)\n\n    def listar_libros(self):\n        return self.libros\n\nclass RegistroUsuarios:\n    def __init__(self):\n        self.usuarios = []\n\n    def registrar_usuario(self, dni, nombre, correo):\n        usuario = {\n            'dni': dni,\n            'nombre': nombre,\n            'correo': correo\n        }\n        self.usuarios.append(usuario)\n\n    def listar_usuarios(self):\n        return self.usuarios\n\n\nclass GestionPrestamos:\n    def __init__(self, registro_libros, registro_usuarios):\n        self.prestamos = []\n        self.registro_libros = registro_libros\n        self.registro_usuarios = registro_usuarios\n\n    def prestar_libro(self, dni, numero_libro):\n        usuario = next((u for u in self.registro_usuarios.listar_usuarios() if u['dni'] == dni), None)\n        libro = next((l for l in self.registro_libros.listar_libros() if l['numero_libro'] == numero_libro), None)\n\n        if usuario and libro and libro['copias_disponibles'] > 0:\n            self.prestamos.append({'dni': dni, 'numero_libro': numero_libro})\n            libro['copias_disponibles'] -= 1\n            print(f\"Libro {numero_libro} prestado a {usuario['nombre']}\")\n        else:\n            print(\"Préstamo no disponible\")\n\n    def devolver_libro(self, dni, numero_libro):\n        prestamo = next((p for p in self.prestamos if p['dni'] == dni and p['numero_libro'] == numero_libro), None)\n        if prestamo:\n            self.prestamos.remove(prestamo)\n            libro = next((l for l in self.registro_libros.listar_libros() if l['numero_libro'] == numero_libro), None)\n            libro['copias_disponibles'] += 1\n            print(f\"Libro {numero_libro} devuelto por {dni}\")\n        else:\n            print(\"No se encontró el préstamo\")\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/juanmax2.py",
    "content": "\"\"\"\nEjercicio\n\"\"\"\n\n# Incorrecta\n\nclass Usuario():\n    \n    def __init__(self, name, email) -> None:\n        self.name = name\n        self.email = email\n        \n    def save_to_database(self):\n        pass\n    \n    def send_email(self):\n        pass\n\n# Correcta\n    \nclass User:\n    \n    def __init__(self, name, email) -> None:\n        self.name = name\n        self.email = email\n        \n\nclass DataBase:\n    data = {}\n    def save_to_database(self, user):\n        pass\n    \nclass EmailService:\n    \n    def send_email(self, email, message):\n        pass\n    \n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n * manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n * y el procesamiento de préstamos de libros.\n * Requisitos:\n * 1. Registrar libros: El sistema debe permitir agregar nuevos libros con \n * información básica como título, autor y número de copias disponibles.\n * 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n * información básica como nombre, número de identificación y correo electrónico.\n * 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n * tomar prestados y devolver libros.\n * Instrucciones:\n * 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n * los tres aspectos mencionados anteriormente (registro de libros, registro de\n * usuarios y procesamiento de préstamos).\n * 2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n * siguiendo el Principio de Responsabilidad Única.\n */\n\"\"\"\n\nclass Library:\n    \n    def __init__(self):\n        self.libros = []\n        self.users = []\n        self.prestamos = []\n        \n    def añadir_libro(self, titulo, autor, copias):\n        self.libros.append({\"titulo\" : titulo, \"autor\" : autor, \"copias\" : copias})\n        \n    def registrar_users(self, name, user_id, email):\n        self.users.append({\"nombre\" : name, \"id\" : user_id, \"email\" : email})\n        \n    def prestar_libro(self, user_id, titulo):\n        for libro in self.libros:\n            if libro[\"titulo\"] == titulo and libro[\"copias\"] > 0:\n                libro[\"copias\"] -= 1\n                self.prestamos.append(\n                    {\"user_id\" : user_id, \"titulo\" : titulo}\n                )\n                return True\n        return False\n\n    def retornar_libro(self, user_id, titulo):\n        for prestamo in self.prestamos:\n            if prestamo[\"user_id\"] ==  user_id and prestamo[\"titulo\"] == titulo:\n                self.prestamos.remove(prestamo)\n                for libro in self.libros:\n                    if libro[\"titulo\"] == titulo:\n                        libro[\"copias\"] += 1\n                    return True\n        return False\n\n# Correcta\n\n    \n    \nclass Libro:\n    \n    def __init__(self, titulo, autor, copias):\n        self.titulo = titulo\n        self.autor = autor\n        self.copias = copias\n        \n    \nclass User:\n    \n    def __init__(self, nombre, user_id, email):\n        self.nombre = nombre\n        self.user_id = user_id\n        self.email = email\n        \nclass Prestamo:\n    \n    def __init__(self):\n        self.prestamos = []\n    \n    def prestar_libro(self, usuario, libro):\n        if libro.copias > 0:\n            libro.copias -= 1\n            self.prestamos.append(\n                {\"user_id\" : usuario.id, \"titulo\" : libro.titulo}\n            )\n            return True\n        return False\n    \n    def devolver_libro(self, usuario, libro):\n        for prestamo in self.prestamos:\n            if prestamo[\"user_id\"] == usuario.id and prestamo[\"titulo\"] == libro.titulo:\n                self.prestamos.remove(prestamo)\n                libro.copias += 1\n                return True\n        return False\n\nclass Library:\n    \n    def _init__(self):\n        self.libros = []\n        self.usuarios = []\n        self.prestamos = Prestamo() \n        \n    def añadir_libro(self, libro):\n        self.libros.append(libro)\n\n    def añadir_usuario(self, usuario):\n        self.usuarios.append(usuario)\n        \n    def prestar_libro(self, user_id, titulo_libro):\n        user = next((u for u in self.usuarios if u.user_id == user_id), None)\n        book = next((b for b in self.libros if b.titulo == titulo_libro), None)\n        if user and book:\n            return self.prestamos.prestar_libro(user, book)\n        return False\n    \n    def retornar_libro(self, user_id, titulo_libro):\n        user = next((u for u in self.usuarios if u.user_id == user_id), None)\n        book = next((b for b in self.libros if b.titulo == titulo_libro), None)\n        if user and book:\n            return self.prestamos.devolver_libro(user, book)\n        return False\n\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/juanppdev.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n * Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n\"\"\"\n\n# Incorrecto\n\nclass Report:\n    def __init__(self, data):\n        self.data = data\n\n    def calculate_statistics(self):\n        # Calcula estadísticas\n        return {\"mean\": sum(self.data) / len(self.data)}\n\n    def print_report(self):\n        # Imprime el reporte\n        stats = self.calculate_statistics()\n        print(f\"Mean: {stats['mean']}\")\n\n    def save_to_file(self, filename):\n        # Guarda el reporte en un archivo\n        with open(filename, 'w') as file:\n            file.write(str(self.data))\n\n\n# Correcto\n\nclass Report:\n    def __init__(self, data):\n        self.data = data\n\nclass StatisticsCalculator:\n    def __init__(self, data):\n        self.data = data\n\n    def calculate_statistics(self):\n        # Calcula estadísticas\n        return {\"mean\": sum(self.data) / len(self.data)}\n\nclass ReportPrinter:\n    def __init__(self, report):\n        self.report = report\n\n    def print_report(self):\n        # Imprime el reporte\n        stats = StatisticsCalculator(self.report.data).calculate_statistics()\n        print(f\"Mean: {stats['mean']}\")\n\nclass ReportSaver:\n    def __init__(self, report):\n        self.report = report\n\n    def save_to_file(self, filename):\n        # Guarda el reporte en un archivo\n        with open(filename, 'w') as file:\n            file.write(str(self.report.data))\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n * manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n * y el procesamiento de préstamos de libros.\n * Requisitos:\n * 1. Registrar libros: El sistema debe permitir agregar nuevos libros con \n * información básica como título, autor y número de copias disponibles.\n * 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n * información básica como nombre, número de identificación y correo electrónico.\n * 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n * tomar prestados y devolver libros.\n * Instrucciones:\n * 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n * los tres aspectos mencionados anteriormente (registro de libros, registro de\n * usuarios y procesamiento de préstamos).\n * 2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n * siguiendo el Principio de Responsabilidad Única.\n\"\"\"\n\nclass Library:\n    def __init__(self):\n        self.books = []\n        self.users = []\n        self.loans = []\n\n    def register_book(self, title, author, copies):\n        book = {\"title\": title, \"author\": author, \"copies\": copies}\n        self.books.append(book)\n\n    def register_user(self, name, user_id, email):\n        user = {\"name\": name, \"user_id\": user_id, \"email\": email}\n        self.users.append(user)\n\n    def loan_book(self, user_id, title):\n        for book in self.books:\n            if book[\"title\"] == title and book[\"copies\"] > 0:\n                book[\"copies\"] -= 1\n                self.loans.append({\"user_id\": user_id, \"title\": title})\n                return f\"Book '{title}' loaned to user {user_id}\"\n        return f\"Book '{title}' not available\"\n\n    def return_book(self, user_id, title):\n        for loan in self.loans:\n            if loan[\"user_id\"] == user_id and loan[\"title\"] == title:\n                self.loans.remove(loan)\n                for book in self.books:\n                    if book[\"title\"] == title:\n                        book[\"copies\"] += 1\n                return f\"Book '{title}' returned by user {user_id}\"\n        return f\"No record of loan for book '{title}' by user {user_id}\"\n\n\nclass Book:\n    def __init__(self, title, author, copies):\n        self.title = title\n        self.author = author\n        self.copies = copies\n\nclass User:\n    def __init__(self, name, user_id, email):\n        self.name = name\n        self.user_id = user_id\n        self.email = email\n\nclass BookRegistry:\n    def __init__(self):\n        self.books = []\n\n    def register_book(self, title, author, copies):\n        book = Book(title, author, copies)\n        self.books.append(book)\n\nclass UserRegistry:\n    def __init__(self):\n        self.users = []\n\n    def register_user(self, name, user_id, email):\n        user = User(name, user_id, email)\n        self.users.append(user)\n\nclass LoanProcessor:\n    def __init__(self, book_registry, user_registry):\n        self.book_registry = book_registry\n        self.user_registry = user_registry\n        self.loans = []\n\n    def loan_book(self, user_id, title):\n        for book in self.book_registry.books:\n            if book.title == title and book.copies > 0:\n                book.copies -= 1\n                self.loans.append({\"user_id\": user_id, \"title\": title})\n                return f\"Book '{title}' loaned to user {user_id}\"\n        return f\"Book '{title}' not available\"\n\n    def return_book(self, user_id, title):\n        for loan in self.loans:\n            if loan[\"user_id\"] == user_id and loan[\"title\"] == title:\n                self.loans.remove(loan)\n                for book in self.book_registry.books:\n                    if book.title == title:\n                        book.copies += 1\n                return f\"Book '{title}' returned by user {user_id}\"\n        return f\"No record of loan for book '{title}' by user {user_id}\"\n\n\n# Interacción desde la consola\nif __name__ == \"__main__\":\n    book_registry = BookRegistry()\n    user_registry = UserRegistry()\n    loan_processor = LoanProcessor(book_registry, user_registry)\n\n    # Registrar libros\n    book_registry.register_book(\"1984\", \"George Orwell\", 5)\n    book_registry.register_book(\"To Kill a Mockingbird\", \"Harper Lee\", 3)\n\n    # Registrar usuarios\n    user_registry.register_user(\"Alice\", 1, \"alice@example.com\")\n    user_registry.register_user(\"Bob\", 2, \"bob@example.com\")\n\n    # Procesar préstamos\n    print(loan_processor.loan_book(1, \"1984\"))\n    print(loan_processor.loan_book(2, \"To Kill a Mockingbird\"))\n    print(loan_processor.loan_book(1, \"To Kill a Mockingbird\"))\n\n    # Devolver libros\n    print(loan_processor.return_book(1, \"1984\"))\n    print(loan_processor.return_book(2, \"To Kill a Mockingbird\"))"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/kenysdev.py",
    "content": "# ╔═════════════════════════════════════╗\n# ║ Autor:  Kenys Alvarado              ║\n# ║ GitHub: https://github.com/Kenysdev ║\n# ║ 2024 -  Python                      ║\n# ╚═════════════════════════════════════╝\n\n# -------------------------------------------------\n# * SOLID: PRINCIPIO DE RESPONSABILIDAD ÚNICA (SRP)\n# -------------------------------------------------\n# Se centra en la claridad, la cohesión y la separación de intereses.\n# Cada clase debe tener una única razón para cambiar.\n# Los metodos de una clase deben estar estrechamente relacionadas.\n\n\"\"\"\n* EJERCICIO #1:\n* Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n* Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n* de forma correcta e incorrecta.\n\"\"\"\n\n#_______________________________________\n# SIN APLICAR EL PRINCIPIO:\n\nclass Program():\n    def __init__(self):\n        self.customers: list = []\n        self.suppliers: list = []\n\n    def add_customer(self, name):\n        self.customers.append(name)\n\n    def add_supplier(self, name):\n        self.suppliers.append(name)\n\n    def remove_customer(self, name):\n        self.customers.remove(name)\n\n    def remove_supplier(self, name):\n        self.suppliers.remove(name)\n\n\n#_______________________________________\n# APLICANDO EL PRINCIPIO:\n\nclass Customers():\n    def __init__(self):\n        self.customers: list = []\n    \n    def add(self, name: str):\n        self.customers.append(name)\n    \n    def remove(self, name: str):\n        self.customers.remove(name)\n\n    # ... más métodos relacionados.\n\nclass Suppliers():\n    def __init__(self):\n        self.suppliers: list = []\n    \n    def add(self, name: str):\n        self.suppliers.append(name)\n\n    def remove(self, name: str):\n        self.suppliers.remove(name)\n\n    # ... más métodos relacionados.\n\n\n\"\"\"\n* EJERCICIO #2:\n* Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n* manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n* y el procesamiento de préstamos de libros.\n* Requisitos:\n* 1. Registrar libros: El sistema debe permitir agregar nuevos libros con \n* información básica como título, autor y número de copias disponibles.\n* 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n* información básica como nombre, número de identificación y correo electrónico.\n* 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n* tomar prestados y devolver libros.\n* Instrucciones:\n* 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n* los tres aspectos mencionados anteriormente (registro de libros, registro de\n* usuarios y procesamiento de préstamos).\n* 2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n* siguiendo el Principio de Responsabilidad Única.\n\"\"\"\n\n#____________________________________________________________________________\n# SIN APLICAR SRP:\n\nclass Library():\n    def __init__(self):\n        self.books: dict = {}\n        self.users: dict = {}\n        self.borrowed: dict = {}\n    \n    def add_book(self, id_book: int, title: str, author: str, stock: int):\n        if id_book in self.books:\n            self.books[id_book]['stock'] += stock\n            self.books[id_book]['available'] += stock\n            print(\"El libro ya existe, se actualizó el inventario.\")\n\n        else:\n            self.books[id_book] = {\n                'title': title,\n                'author': author,\n                'stock': stock,\n                'available': stock\n            }\n            print(f\"\\nSe agrego el libro '{title}'.\") \n\n    def add_user(self, id_user: int, name: str, email: str):\n        if id_user in self.users:\n            print(\"Usuario ya existee\")\n\n        else:\n            self.users[id_user] = {\n                'name': name,\n                'email': email\n            }\n            print(f\"\\nSe agrego a '{name}'.\") \n\n    def lend_book(self, id_borrowed: int, id_user: int, id_book: int):\n        if id_book not in self.books:\n            print(\"Este libro no existe\")\n            return\n        \n        if id_user not in self.users:\n            print(\"Este usuario no existe\")\n            return\n        \n        if self.books[id_book]['available'] > 0:\n            self.borrowed[id_borrowed] = {  \n                'id_user': id_user,\n                'id_book': id_book\n            }\n            self.books[id_book]['available'] -= 1\n            print(f\"\\nSe presto el libro '{id_book}'.\") \n\n        else:\n            print(f\"No hay libro disponible.\")\n\n    def return_book(self, id_borrowed: int):\n        if id_user not in self.borrowed:\n            print(\"No está registrado.\")\n        \n        else:\n            self.books[id_borrowed[id_book]]['available'] += 1\n            del self.borrowed[id_borrowed]\n            print(\"Retorno exitoso.\")\n\n    def print_books(self):\n        print(\"Lista de libros:\\n\", self.books)\n\n    def print_users(self):\n        print(\"Lista de usuarios\", self.users)\n\n    def print_borrowed(self):\n        print(\"Lista de libros prestados\", self.borrowed)\n\n#____________________________________________________________________________\n# APLICANDO SRP:\n\nclass LibraryData: # uso de SINGLETON para tener datos globales\n    _instance = None\n    \n    def __new__(cls):\n        if not cls._instance:\n            cls._instance = super().__new__(cls)\n            cls.books = {}\n            cls.users = {}\n            cls.borrowed = {}\n\n        return cls._instance\n\n#___________________\nclass Books:\n    def __init__(self):\n        self.data = LibraryData()\n\n    def add(self, id_book: int, title: str, author: str, stock: int):\n        if id_book in self.data.books:\n            self.data.books[id_book]['stock'] += stock\n            self.data.books[id_book]['available'] += stock\n            print(\"El libro ya existe, se actualizó el inventario.\")\n            return\n\n        self.data.books[id_book] = {\n            'title': title,\n            'author': author,\n            'stock': stock,\n            'available': stock\n        }\n        print(f\"\\nSe agrego el libro '{title}'.\") \n\n    def print_dic(self):\n        print(\"\\nLibros:\")\n        if self.data.books:\n            for ky, values in self.data.books.items():\n                print(f\"{ky}: {values}\")\n        else:\n            print(\"- Vacio\")\n\n#___________________      \nclass Users:\n    def __init__(self):\n        self.data = LibraryData()\n\n    def add(self, id_user: int, name: str, email: str):\n        if id_user in self.data.users:\n            print(\"Usuario ya existe.\")\n            return\n\n        self.data.users[id_user] = {\n            'name': name,\n            'email': email\n        }\n        print(f\"\\nSe agrego a '{name}'.\") \n\n    def print_dic(self):\n        print(\"\\nUsuarios:\")\n        if self.data.users:\n            for ky, values in self.data.users.items():\n                print(f\"{ky}: {values}\")\n        else:\n            print(\"- Vacio\")\n\n#___________________\nclass BorrowedBooks:\n    def __init__(self):\n        self.data = LibraryData()\n\n    def _verify(self, id_user: int, id_book: int) -> bool:\n        if id_book not in self.data.books:\n            print(\"Este libro no existe\")\n            return False\n        \n        if id_user not in self.data.users:\n            print(\"Este usuario no existe\")\n            return False\n        \n        if self.data.books[id_book]['available'] <= 0:\n            print(f\"El libro no está disponible.\")\n            return False\n        \n        return True\n\n    def lend(self, id_borrowed: int, id_user: int, id_book: int):\n        if self._verify(id_user, id_book) == False:\n            return\n        \n        self.data.borrowed[id_borrowed] = {  \n            'id_user': id_user,\n            'id_book': id_book\n        }\n        self.data.books[id_book]['available'] -= 1\n        print(f\"\\nSe presto el libro '{id_book}'.\")           \n\n    def return_book(self, id_borrowed: int):\n        if id_borrowed not in self.data.borrowed:\n            print(\"No está registrado.\")\n            return\n        \n        id_book =  self.data.borrowed[id_borrowed]['id_book']\n        self.data.books[id_book]['available'] += 1\n        del self.data.borrowed[id_borrowed]\n        print(f\"\\nRetorno exitoso del libro '{id_book}'.\")\n\n    def print_dic(self):\n        print(\"\\nLibros prestados:\")\n        if self.data.borrowed:\n            for ky, values in self.data.borrowed.items():\n                print(f\"{ky}: {values}\")\n        else:\n            print(\"- Vacio\")\n\n#_________________________________\n# Pruebas positivas\n\nbooks = Books()\nusers = Users()\nborrowed_books = BorrowedBooks()\n\n# id, title, author, stock\nbooks.add(1, \"Libro A\", \"Ben\", 1)\nbooks.add(2, \"Libro B\", \"Dan\", 3)\n\n# id, name, email\nusers.add(10, \"Zoe\", \"Zoe@a.com\")\nusers.add(11, \"Ana\", \"Ana@a.com\")\n\nbooks.print_dic()\nusers.print_dic()\nborrowed_books.print_dic()\n\n# id_borrowed, id_user, id_book\nborrowed_books.lend(100, 10, 1)\nborrowed_books.lend(101, 11, 2)\n\nbooks.print_dic()\nborrowed_books.print_dic()\n\n# id_borrowed\nborrowed_books.return_book(100)\nborrowed_books.return_book(101)\n\nbooks.print_dic()\nborrowed_books.print_dic()\n\nborrowed_books.lend(103, 11, 1)\n\n#_________________________________\n# Pruebas negativas\nprint(\"\\n_____\\nPruebas negativas\")\nbooks.add(2, \"..\", \"..\", 1)\nusers.add(11, \"..\", \"..\")\nborrowed_books.lend(104, 10, 1)\nborrowed_books.return_book(100)\n\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/mhayhem.py",
    "content": "# @Author Daniel Grande (mhayhem)\n\n# EJERCICIO:\n# Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n# Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n# de forma correcta e incorrecta.\n\n\"\"\"\nnot SRP\n\"\"\"\nclass User:\n    def __init__(self, name: str, mail: str):\n        self.name = name\n        self.mail = mail\n    \n    def save_data_base(self):\n        return f\"{self.name} añadido a base de datos.\"\n    \n    def sent_mail(self):\n        return f\"Correo enviado a {self.mail}.\"\n    \n    def user_registration(self):\n        return f\"{self.name} registrado.\"\n\n\"\"\" \nSRP\n\"\"\"\n\nclass User:\n    def __init__(self, name: str, mail: str):\n        self.name = name\n        self.mail = mail\n\nclass UserRepository:\n    \n    @staticmethod\n    def save(user: User):\n        return f\"EL usuario: {user.name} se ha guardado en la base de datos.\"\n\nclass EmailService:\n    \n    @staticmethod\n    def sent_mail(user: User):\n        return f\"Correo enviado a {user.mail}\"\n\nclass UserRegistration:\n    \n    @staticmethod\n    def registration(user: User):\n        return f\"Usuario: {user.name} Registrado con exito.\"\n\n\n# DIFICULTAD EXTRA (opcional):\n# Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n# manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n# y el procesamiento de préstamos de libros.\n# Requisitos:\n# 1. Registrar libros: El sistema debe permitir agregar nuevos libros con \n# información básica como título, autor y número de copias disponibles.\n# 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n# información básica como nombre, número de identificación y correo electrónico.\n# 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n# tomar prestados y devolver libros.\n# Instrucciones:\n# 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n# los tres aspectos mencionados anteriormente (registro de libros, registro de\n# usuarios y procesamiento de préstamos).\n# 2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n# siguiendo el Principio de Responsabilidad Única.\n\n\n\"\"\" not SRP \"\"\"\nclass Library:\n    def __init__(self):\n        self.books = []\n        self.users = []\n        self.loans = []\n    \n    def add_book(self, title: str, author: str, stock: int) -> None:\n        self.books.append({\"title\": title,\n                        \"author\": author.capitalize(),\n                        \"stock\": stock})\n    \n    def add_user(self, name: str, id: int, mail: str) -> None:\n        self.users.append({\"Name\": name.capitalize(),\n                        \"ID\": id,\n                        \"Mail\": mail})\n    \n    def loan_book(self, book_title: str, user_name: str) -> None:\n        book = None\n        for b in self.books:\n            if b[\"title\"] == book_title:\n                book = b\n                break\n        if not book:\n            return f\"EL libro '{book_title}' no encontrado.\"\n        if book[\"stock\"] <= 0:\n            return f\"No hay stock del libro '{book_title}'.\"\n\n        user = None\n        for u in self.users:\n            if u[\"name\"] == user_name:\n                user = u\n                break\n        \n        for loan in self.loans:\n            if loan[0] == book_title and loan[1] == user_name:\n                return f\"El usuario {user_name} ya tiene el libro '{book_title}.\"\n        \n        self.loans.append((book_title, user_name))\n        book[\"stock\"] -= 1\n\n    def return_book(self, book_title, user_name) -> None:\n        loan_found = None\n        for i ,loan in enumerate(self.loans):\n            if loan[0] == book_title and loan[1] == user_name:\n                loan_found = i\n                break\n        \n        if not loan_found:\n            return f\"El usuario {user_name} no tiene el libro '{book_title}.\"\n        \n        del self.loans[loan_found]\n        \n        for book in self.books:\n            if book[\"title\"] == book_title:\n                book[\"stock\"] += 1\n                break\n\n\n\"\"\" SRP \"\"\"\n\nclass Book:\n    def __init__(self, title: str, author: str, stock: int) -> None:\n        self.title = title\n        self.author = author\n        self.stock = stock\n\n    def book(self):\n        return {\"titlte\": self.title,\n                \"author\": self.author, \n                \"stock\": self.stock\n                }\n\nclass User:\n    def __init__(self, name: str, mail: str, id: int) -> None:\n        self.name = name\n        self.mail = mail\n        self.id = id\n\n    def user(self):\n        return {\n            \"name\": self.name,\n            \"mail\": self.mail,\n            \"ID\": self.id\n        }\n\nclass Library:\n    def __init__(self) -> None:\n        self.books = []\n        self.users = []\n        self.loans = []\n\n    def add_book(self):\n        self.books.append(Book())\n\nlibrary = Library()\nbook1 = Book(\"death\", \"dany\", 2)\n\nlibrary.add_book(book1)"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/mouredev.py",
    "content": "\"\"\"\nEjercicio\n\"\"\"\n\n# Incorrecto\n\n\nclass User:\n\n    def __init__(self, name, email) -> None:\n        self.name = name\n        self.email = email\n\n    def save_to_database(self):\n        pass\n\n    def send_email(self):\n        pass\n\n# Correcto\n\n\nclass User:\n\n    def __init__(self, name, email) -> None:\n        self.name = name\n        self.email = email\n\n\nclass UserService:\n\n    def save_to_database(self, user):\n        pass\n\n\nclass EmailService:\n\n    def send_email(self, email, message):\n        pass\n\n\n\"\"\"\nExtra\n\"\"\"\n\n# Incorrecto\n\n\nclass Library:\n\n    def __init__(self) -> None:\n        self.books = []\n        self.users = []\n        self.loans = []\n\n    def add_book(self, title, author, copies):\n        self.books.append({\"title\": title, \"author\": author, \"copies\": copies})\n\n    def add_user(self, name, id, email):\n        self.users.append({\"name\": name, \"id\": id, \"email\": email})\n\n    def loan_book(self, user_id, book_title):\n        for book in self.books:\n            if book[\"title\"] == book_title and book[\"copies\"] > 0:\n                book[\"copies\"] -= 1\n                self.loans.append(\n                    {\"user_id\": user_id, \"book_title\": book_title})\n                return True\n        return False\n\n    def return_book(self, user_id, book_title):\n        for loan in self.loans:\n            if loan[\"user_id\"] == user_id and loan[\"book_title\"] == book_title:\n                self.loans.remove(loan)\n                for book in self.books:\n                    if book[\"title\"] == book_title:\n                        book[\"copies\"] += 1\n                    return True\n        return False\n\n# Correcto\n\n\nclass Book:\n\n    def __init__(self, title, author, copies):\n        self.title = title\n        self.author = author\n        self.copies = copies\n\n\nclass User:\n\n    def __init__(self, name, id, email):\n        self.name = name\n        self.id = id\n        self.email = email\n\n\nclass Loan:\n\n    def __init__(self):\n        self.loans = []\n\n    def loan_book(self, user, book):\n        if book.copies > 0:\n            book.copies -= 1\n            self.loans.append(\n                {\"user_id\": user.id, \"book_title\": book.title})\n            return True\n        return False\n\n    def return_book(self, user, book):\n        for loan in self.loans:\n            if loan[\"user_id\"] == user.id and loan[\"book_title\"] == book.title:\n                self.loans.remove(loan)\n                book.copies += 1\n                return True\n        return False\n\n\nclass Library:\n\n    def __init__(self) -> None:\n        self.books = []\n        self.users = []\n        self.loans_service = Loan()\n\n    def add_book(self, book):\n        self.books.append(book)\n\n    def add_user(self, user):\n        self.users.append(user)\n\n    def loan_book(self, user_id, book_title):\n        user = next((u for u in self.users if u.id == user_id), None)\n        book = next((b for b in self.books if b.title == book_title), None)\n        if user and book:\n            return self.loans_service.loan_book(user, book)\n        return False\n\n    def return_book(self, user_id, book_title):\n        user = next((u for u in self.users if u.id == user_id), None)\n        book = next((b for b in self.books if b.title == book_title), None)\n        if user and book:\n            return self.loans_service.return_book(user, book)\n        return False\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/mrodara.py",
    "content": "### SOLID PRINCPIO DE RESPONSABILIDAD ÚNICA (SRP)\n\n'''\nEl Principio de Responsabilidad Única (SRP) es uno de los cinco principios SOLID en la programación orientada a objetos. \nEste principio establece que una clase debe tener una única razón para cambiar, es decir, una sola responsabilidad o \npropósito.\nEn términos simples, cada clase debe encargarse de una sola tarea y hacerlo bien.\n'''\n\n'''\nVENTAJAS:\n- Facilita la comprensión y el mantenimiento del código.\n- Reduce la complejidad del código.\n- Mejora la reutilización del código.\n'''\n\n# Ejemplo que viola este principio\n#class User():\n#    \n#    def __init__(self, name, email):\n#        self.name = name\n#        self.email = email\n#        \n#    def save_to_file(self):\n#        with open('users.txt', 'w') as file:\n#            file.write(f\"Name: {self.name}, Email: {self.email}\")\n\n# El ejemplo anterior viola el SRP, ya que gestiona tanto los datos del usuario como su almacenamiento en un registro.\n\n# Vamos a reestructuar el diseño para cumplir con SRP con dos clases separadas\n#class User():\n#    \n#    def __init__(self, name, email):\n#        self.name = name\n#        self.email = email\n#\n#class UserFileHandler():\n#    @staticmethod\n#    def save_to_file(user, filename):\n#        with open(filename, 'w') as file:\n#            file.write(f\"Name: {user.name}, Email: {user.email}\")\n\n\n# Prueba de funcionamiento\n#user = User(\"Manuel\", \"manuel@example.com\")\n#UserFileHandler.save_to_file(user, \"user_data.txt\")\n\n\n## EJERCICIO EXTRA\n\n# Clase que incumple el principio SRP\n#class Library():\n#    \n#    users = []\n#    loans = []\n#    \n#    def __init__(self, title, author, copies):\n#                \n#        self.books.append({'title': title, 'author':author, 'copies': copies})\n#        \n#    def register_book(self, title, author, copies):\n#        self.books.append({'title': title, 'author': author, 'copies': copies})\n#        print(f\"Registro de libro realizado con éxito\")\n#    \n#    def register_user(self, name, id, email):\n#        self.users.append({'name': name, 'id': id, 'email': email})\n#        print(f\"Registro de usuario realizado con éxito\")\n#    \n#    def loan_book(self, user, book):\n#        if book['copies'] > 0:\n#            self.loans.append({'user': user, 'book': book})\n#            book['copies'] -= 1\n#            print(f\"Préstamo de libro realizado con éxito\")\n#        else:\n#            print(f\"No hay copias disponibles del libro {book['title']}\")\n#    \n#    def return_book(self, user, book):\n#        if user in [loan['user'] for loan in self.loans] and book in [book['name'] for book in self.books]:\n#            self.loans.remove({'user': user, 'book': book})\n#            book['copies'] += 1\n#            print(f\"Devolución de libro realizada con éxito\")\n#        else:\n#            print(f\"No hay préstamos activos del libro {book['title']}\")\n\n# Aplicando SRP\nclass User():\n    \n    def __init__(self, name, id, email):\n        self.name = name\n        self.id = id\n        self.email = email\n    \nclass Book():\n    \n    def __init__(self, name, author, copies):\n        self.name = name\n        self.author = author\n        self.copies = copies\n        \nclass Library():\n    \n    def __init__(self, users = [], books = [], loans=[]):\n        self.users = users\n        self.books = books\n        self.loans = loans\n        \n    def register_user(self, user: User):\n        self.users.append(user)\n        print(f\"Registro de usuario realizado con éxito\")\n    \n    def register_book(self, book: Book):\n        self.books.append(book)\n        print(f\"Registro de libro realizado con éxito\")\n        \n    def register_loan(self, user: User, book: Book):\n        if book.copies > 0:\n            self.loans.append({\"user\": user, \"book\" : book})\n            book.copies -= 1\n            print(f\"Préstamo de libro realizado con éxito\")\n        else:\n            print(f\"No hay copias disponibles del libro {book.name}\")\n    \n    def return_loan(self, user: User, book: Book):\n        if user in [loan['user'] for loan in self.loans] and book in [loan['book'] for loan in self.loans]:\n            self.loans.remove({'user': user, 'book': book})\n            book.copies += 1\n            print(f\"Devolución de libro realizada con éxito\")\n\n# Pruebas del programa          \nuser1 = User(name=\"Manuel\", id=1, email=\"manuel@correo.es\")\nuser2 = User(name=\"Pedro\", id=2, email=\"pedro@correo.es\")\nbook1 = Book(name=\"Libro 1\", author=\"Autor 1\", copies=2)\nbook2 = Book(name=\"Libro 2\", author=\"Autor 2\", copies=1)\nlibrary = Library()\nlibrary.register_user(user1)\nlibrary.register_user(user2)\nlibrary.register_book(book1)\nlibrary.register_book(book2)\nlibrary.register_loan(user1, book1)\nlibrary.register_loan(user2, book2)\nlibrary.register_loan(user1, book2)\nlibrary.return_loan(user2, book2)\nlibrary.register_loan(user1, book2)\n\n# Fin Aplicando SRP\n    \n## FIN EJERCICIO EXTRA\n\n### FIN SOLID PRINCPIO DE RESPONSABILIDAD ÚNICA (SRP)"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/neslarra.py",
    "content": "\"\"\"\n EJERCICIO:\n Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n de forma correcta e incorrecta.\n\n DIFICULTAD EXTRA (opcional):\n Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n y el procesamiento de préstamos de libros.\n Requisitos:\n 1. Registrar libros: El sistema debe permitir agregar nuevos libros con\n información básica como título, autor y número de copias disponibles.\n 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n información básica como nombre, número de identificación y correo electrónico.\n 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n tomar prestados y devolver libros.\n Instrucciones:\n 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n los tres aspectos mencionados anteriormente (registro de libros, registro de\n usuarios y procesamiento de préstamos).\n 2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n siguiendo el Principio de Responsabilidad Única.\n\"\"\"\n\nprint(f\"{'#' * 47}\")\nprint(f\"##  Explicación  {'#' * 30}\")\nprint(f\"{'#' * 47}\")\n\nprint(r\"\"\"\nPara entender fácilmente los 5 ppios SOLID recomiendo leer:\n\n    https://blog.damavis.com/los-principios-solid-ilustrados-en-ejemplos-sencillos-de-python/\n\nen donde se explican de manera ordenada uno por uno, de manera sencilla y ejemplicada de manera progresiva (de hecho, de acá\nvoy a tomar el ejemplo).\n\nEl primer de los ppios SOLID es \"Single Responsibility Principle\" <= una clase SOLO debe ser responsable de una única cosa.\n\n    class Duck:\n       \n        def __init__(self, name):\n            self.name = name\n       \n        def fly(self):\n            print(f\"{self.name} is flying not very high\")\n    \n        def swim(self):\n            print(f\"{self.name} swims in the lake and quacks\")\n    \n        def do_sound(self) -> str:\n            return \"Quack\"\n    \n        def greet(self, duck2: Duck):\n            print(f\"{self.name}: {self.do_sound()}, hello {duck2.name}\")\n\nEsta clase Duck es responsable por definir los atributos de un pato, PERO, además, se encarga de definir como un pato\nsaluda a otro => esta otra responsabilidad viola el ppio SRP => debe estar en otra clase específica.\n\n    class Duck:\n       \n        def __init__(self, name):\n            self.name = name\n       \n        def fly(self):\n            print(f\"{self.name} is flying not very high\")\n    \n        def swim(self):\n            print(f\"{self.name} swims in the lake and quacks\")\n    \n        def do_sound(self) -> str:\n            return \"Quack\"\n    \n    class Communicator:\n    \n        def __init__(self, channel):\n            self.channel = channel\n    \n        def communicate(self, duck1 : Duck, duck2: Duck):\n            sentence1 = f\"{duck1.name}: {duck1.do_sound()}, hello {duck2.name}\"\n            sentence2 = f\"{duck2.name}: {duck2.do_sound()}, hello {duck1.name}\"\n            conversation = [sentence1, sentence2]\n            print(*conversation,\n                  f\"(via {self.channel})\",\n                  sep = '\\n')\n\nAhora sí, ambas clases, cumplen con SRP (Duck solo de los atributos de los patos y Communicator solo de la\ncomunicación entre ellos).\n\"\"\")\n\nprint(f\"{'#' * 52}\")\nprint(f\"##  Dificultad Extra  {'#' * 30}\")\nprint(f\"{'#' * 52}\\n\")\n\nprint(f\"\"\"\\n##  Libreria SRP  {'#' * 50}\nAcá LibraryNoSRP se encarga de todo: los libros, los socios y el mvto de libros.\nAsí, si es necesario, por ejemplo, cambiar la política de préstamos se afecta a TODA la clase.\n\"\"\")\n\n\nclass LibraryNoSRP:\n    library = None\n    books = {}\n    authors = []\n    members = {}\n\n    def __new__(cls, *args, **kwargs):\n        if not cls.library:\n            cls.library = super().__new__(cls)\n            cls.library._initialized = False\n        return cls.library\n\n    def __init__(self, name: str = None):\n        if not self._initialized:\n            self.value = name\n            self._initialized = True\n\n    @classmethod\n    def add_book(cls, title: str, author: str, book_copies: int = 1):\n\n        full_name = title + \"_\" + author\n        if full_name in cls.books.keys():\n            cls.books[full_name][\"copies\"] += book_copies\n        else:\n            if author not in cls.authors:\n                cls.authors.append(author)\n            cls.books[full_name] = {\"copies\": book_copies}\n\n    @classmethod\n    def add_member(cls, name: str, id: int):\n\n        if id not in cls.members.keys():\n            cls.members[id] = {\"name\": name, \"borroughts\": []}\n\n    @classmethod\n    def receive_book(cls, title: str, author: str, member: int):\n        full_name = title + \"_\" + author\n        cls.add_book(title, author, 1)\n        cls.members[member][\"borroughts\"].remove(full_name)\n        print(f\"{cls.members[member]['name']} devolvió {title} de {author}\")\n\n    @classmethod\n    def lend_book(cls, title: str, author: str, member: int):\n\n        full_name = title + \"_\" + author\n        if member not in cls.members.keys():\n            print(f\"El socio {member} no está registrado\")\n            return False\n        if author not in cls.authors:\n            print(f\"No hay libros para el autor {author}\")\n            return False\n        if full_name not in cls.books.keys():\n            print(f\"No tenemos el libro {title} del autor {author}\")\n            return False\n        if cls.books[full_name][\"copies\"] <= 0:\n            print(f\"No hay copias disponibles de {title} de {author}\")\n            return False\n        print(f\"{title} de {author} prestado a {cls.members[member]['name']}\")\n        cls.books[full_name][\"copies\"] -= 1\n        cls.members[member][\"borroughts\"].append(full_name)\n        return True\n\n\nlibrary = LibraryNoSRP(\"Public\")\nlibrary.add_book(\"Romi y Julito\", \"Willie Shakes\", 3)\nlibrary.add_book(\"Quique Quinto\", \"Willie Shakes\", 2)\nlibrary.add_book(\"Romi y Julito\", \"Willie Shakes\", 1)\nlibrary.add_book(\"Mi Vida con Álvarez\", \"Alberto Borges\", 1)\n\nlibrary.add_member(\"Tito\", 12345678)\nlibrary.add_member(\"Pepe\", 87654321)\n\nprint(f\"\\nBooks: {library.books}\")\nprint(f\"Members: {library.members}\\n\")\n\nlibrary.lend_book(\"Romi y Julito\", \"Willie Shakes\", 12345678)\nlibrary.lend_book(\"Romi y Julito\", \"Willie Shakes\", 87654321)\nlibrary.lend_book(\"Quique Quinto\", \"Alberto Borges\", 12345678)\nlibrary.lend_book(\"Mi Vida con Álvarez\", \"Alberto Borges\", 12345678)\nlibrary.lend_book(\"Mi Vida con Álvarez\", \"Alberto Borges\", 87654321)\n\nprint(f\"\\nBooks: {library.books}\")\nprint(f\"Members: {library.members}\\n\")\n\nlibrary.receive_book(\"Romi y Julito\", \"Willie Shakes\", 12345678)\nlibrary.receive_book(\"Mi Vida con Álvarez\", \"Alberto Borges\", 12345678)\nlibrary.lend_book(\"Mi Vida con Álvarez\", \"Alberto Borges\", 87654321)\nlibrary.lend_book(\"Quique Quinto\", \"Willie Shakes\", 12345678)\n\nprint(f\"\\nBooks: {library.books}\")\nprint(f\"Members: {library.members}\\n\")\n\nprint(f\"\"\"\\n##  Libreria SRP  {'#' * 50}\nAcá se separan las responsabilidades: LibrarySRP se encarga de los libros, Member de los socios y BooksInOut del mvto de libros.\nAsí, si es necesario, por ejemplo, cambiar la política de préstamos NO se afecta Library ni Members.\n\"\"\")\n\n\nclass LibrarySRP:\n    library = None\n    books = {}\n    authors = []\n\n    def __new__(cls, *args, **kwargs):\n        if not cls.library:\n            cls.library = super().__new__(cls)\n            cls.library._initialized = False\n        return cls.library\n\n    def __init__(self, name: str = None):\n        if not self._initialized:\n            self.value = name\n            self._initialized = True\n\n    @classmethod\n    def add_book(cls, title: str, author: str, book_copies: int = 1):\n\n        full_name = title + \"_\" + author\n        if full_name in cls.books.keys():\n            cls.books[full_name][\"copies\"] += book_copies\n        else:\n            if author not in cls.authors:\n                cls.authors.append(author)\n            cls.books[full_name] = {\"copies\": book_copies}\n\n\nclass Member:\n    member_id = []\n\n    def __init__(self, name: str, id: int):\n        if id not in self.member_id:\n            self.name = name\n            self.id = id\n            self.borroughts = []\n            self.new_member(self.id)\n        else:\n            self.id = self.member_id[id]\n\n    def __str__(self):\n        return {self.id: {\"name\": self.name, \"borroughts\": self.borroughts}}    # no devuelve str para mantener la misma salida que antes.\n\n    @classmethod\n    def new_member(cls, id):\n        cls.member_id.append(id)\n\n    @classmethod\n    def is_member(cls, id):\n        return id in cls.member_id\n\n\nclass BooksInOut:\n    books_movement = None\n\n    def __new__(cls, *args, **kwargs):\n        if not cls.books_movement:\n            cls.books_movement = super().__new__(cls)\n            cls.books_movement._initialized = False\n        return cls.books_movement\n\n    def __init__(self, library: LibrarySRP):\n        if not self._initialized:\n            self.library = library\n\n    def lend_book(self, title: str, author: str, member: Member):\n        full_name = title + \"_\" + author\n        if author not in self.library.authors:\n            print(f\"No tenemos libros del autor {author}\")\n            return False\n        if full_name not in self.library.books.keys():\n            print(f\"No tenemos el libro {title} del autor {author}\")\n            return False\n        if self.library.books[full_name][\"copies\"] <= 0:\n            print(f\"No hay copias disponibles de {title} de {author}\")\n            return False\n        print(f\"{title} de {author} prestado a {member.name}\")\n        self.library.books[full_name][\"copies\"] -= 1\n        member.borroughts.append(full_name)\n        return True\n\n    def receive_book(self, title: str, author: str, member: Member):\n        full_name = title + \"_\" + author\n        self.library.add_book(title, author, 1)\n        member.borroughts.remove(full_name)\n        print(f\"{member.name} devolvió {title} de {author}\")\n\n\nlibrary = LibrarySRP(\"Public\")\nlibrary.add_book(\"Romi y Julito\", \"Willie Shakes\", 3)\nlibrary.add_book(\"Quique Quinto\", \"Willie Shakes\", 2)\nlibrary.add_book(\"Romi y Julito\", \"Willie Shakes\", 1)\nlibrary.add_book(\"Mi Vida con Álvarez\", \"Alberto Borges\", 1)\n\nlog_book = BooksInOut(library)\n\ntito = Member(\"Tito\", 12345678)\npepe = Member(\"Pepe\", 87654321)\n\nprint(f\"\\nBooks: {library.books}\")\nprint(f\"Members: {tito.__str__()} - {pepe.__str__()}\\n\")\n\nlog_book.lend_book(\"Romi y Julito\", \"Willie Shakes\", tito)\nlog_book.lend_book(\"Romi y Julito\", \"Willie Shakes\", pepe)\nlog_book.lend_book(\"Quique Quinto\", \"Alberto Borges\", tito)\nlog_book.lend_book(\"Mi Vida con Álvarez\", \"Alberto Borges\", tito)\nlog_book.lend_book(\"Mi Vida con Álvarez\", \"Alberto Borges\", pepe)\n\nprint(f\"\\nBooks: {library.books}\")\nprint(f\"Members: {tito.__str__()} - {pepe.__str__()}\\n\")\n\nlog_book.receive_book(\"Romi y Julito\", \"Willie Shakes\", tito)\nlog_book.receive_book(\"Mi Vida con Álvarez\", \"Alberto Borges\", tito)\nlog_book.lend_book(\"Mi Vida con Álvarez\", \"Alberto Borges\", pepe)\nlog_book.lend_book(\"Quique Quinto\", \"Willie Shakes\", tito)\n\nprint(f\"\\nBooks: {library.books}\")\nprint(f\"Members: {tito.__str__()} - {pepe.__str__()}\\n\")\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/nlarrea.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n * Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n * manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n * y el procesamiento de préstamos de libros.\n * Requisitos:\n * 1. Registrar libros: El sistema debe permitir agregar nuevos libros con \n * información básica como título, autor y número de copias disponibles.\n * 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n * información básica como nombre, número de identificación y correo electrónico.\n * 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n * tomar prestados y devolver libros.\n * Instrucciones:\n * 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n * los tres aspectos mencionados anteriormente (registro de libros, registro de\n * usuarios y procesamiento de préstamos).\n * 2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n * siguiendo el Principio de Responsabilidad Única.\n */\n\"\"\"\n\n# Incorrect\n\n\nclass User:\n    def __init__(self, name, email) -> None:\n        self.name = name\n        self.email = email\n\n    def add_user(self):\n        pass\n\n    def send_email(self):\n        pass\n\n\n# Correct\n\n\nclass User:\n    def __init__(self, name, email) -> None:\n        self.name = name\n        self.email = email\n\n\nclass UserService:\n    def add_user(self, user: User):\n        # add user to database\n        pass\n\n\nclass EmailService:\n    def send_email(self, email: str, message: str):\n        # send an email\n        pass\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n * manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n * y el procesamiento de préstamos de libros.\n * Requisitos:\n * 1. Registrar libros: El sistema debe permitir agregar nuevos libros con \n * información básica como título, autor y número de copias disponibles.\n * 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n * información básica como nombre, número de identificación y correo electrónico.\n * 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n * tomar prestados y devolver libros.\n * Instrucciones:\n * 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n * los tres aspectos mencionados anteriormente (registro de libros, registro de\n * usuarios y procesamiento de préstamos).\n * 2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n * siguiendo el Principio de Responsabilidad Única.\n\"\"\"\n\n# Incorrect\n\n\nclass Library:\n    def __init__(self) -> None:\n        self.books: list[dict] = []\n        self.users: list[dict] = []\n        self.loans: list[dict] = []\n\n    def add_book(self, title: str, author: str, copies: int):\n        self.books.append({\"title\": title, \"author\": author, \"copies\": copies})\n\n    def add_user(self, id: str, name: str, email: str):\n        self.users.append({\"id\": id, \"name\": name, \"email\": email})\n\n    def loan_book(self, user_id: str, book_title: str):\n        for book in self.books:\n            if book[\"title\"] == book_title and book[\"copies\"] > 0:\n                book[\"copies\"] -= 1\n                self.loans.append(\n                    {\"user_id\": user_id, \"book_title\": book_title}\n                )\n\n                return True\n\n            return False\n\n    def return_book(self, user_id: str, book_title: str):\n        for loan in self.loans:\n            if loan[\"user_id\"] == user_id and loan[\"book_title\"] == book_title:\n                # Remove current loan\n                self.loans.remove(loan)\n                # Add a copy of the book to the library\n                for book in self.books:\n                    if book[\"title\"] == book_title:\n                        book[\"copies\"] += 1\n                        return True\n\n        return False\n\n\n# Correct\n\n\nclass Book:\n    def __init__(self, title: str, author: str, copies: int = 1) -> None:\n        self.title = title\n        self.author = author\n        self.copies = copies\n\n\nclass User:\n    def __init__(self, id: str, name: str, email: str) -> None:\n        self.id = id\n        self.name = name\n        self.email = email\n\n\nclass BookLending:\n    def __init__(self) -> None:\n        self.loans = []\n\n    def loan_book(self, user: User, book: Book) -> bool:\n        if book.copies > 0:\n            book.copies -= 1\n            self.loans.append({\"user_id\": user.id, \"book_title\": book.title})\n            return True\n\n        return False\n\n    def return_book(self, user: User, book: Book) -> bool:\n        for loan in self.loans:\n            if loan[\"user_id\"] == user.id and loan[\"book_title\"] == book.title:\n                self.loans.remove(loan)\n                book.copies += 1\n                return True\n\n            return False\n\n\nclass Library:\n    def __init__(self) -> None:\n        self.books: list[Book] = []\n        self.users: list[User] = []\n        self.loans_service = BookLending()\n\n    def add_book(self, book: Book):\n        self.books.append(book)\n\n    def add_user(self, user: User):\n        self.users.append(user)\n\n    def loan_book(self, user_id: str, book_title: str) -> bool:\n        user = next((u for u in self.users if u.id == user_id), None)\n        book = next((b for b in self.books if b.title == book_title), None)\n\n        if user and book:\n            return self.loans_service.loan_book(user, book)\n\n        return False\n\n    def return_book(self, user_id: str, book_title: str) -> bool:\n        user = next((u for u in self.users if u.id == user_id), None)\n        book = next((b for b in self.books if b.title == book_title), None)\n\n        if user and book:\n            return self.loans_service.return_book(user, book)\n\n        return False\n\n\n# Execution to check if it works:\nlibrary = Library()\n\nlibrary.add_book(\n    Book(title=\"The Lord Of The Rings\", author=\"J.R.R. Tolkien\", copies=10)\n)\nlibrary.add_user(User(id=\"a11\", name=\"Naia\", email=\"naia@email.com\"))\n\nprint(\n    \"loan book:\",\n    library.loan_book(user_id=\"a11\", book_title=\"The Lord Of The Rings\"),\n)  # loan book: True\nprint(\n    \"loan book:\",\n    library.loan_book(user_id=\"123\", book_title=\"This doesn't exist\"),\n)  # loan book: False\n\nprint(\n    \"return book:\",\n    library.return_book(user_id=\"a11\", book_title=\"The Lord Of The Rings\"),\n)  # return book: True\nprint(\n    \"return book:\",\n    library.return_book(user_id=\"123\", book_title=\"This doesn't exist\"),\n)  # return book: False\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/oriaj3.py",
    "content": "\"\"\"\n26 - SOLID SRP\n\nTeoría - Single Responsibility Principle\n\nEl principio de responsabilidad única (SRP) establece que una clase debe tener una única razón para cambiar, es decir, una clase debe tener una única responsabilidad.\nEn otras palabras, una clase debe tener un único trabajo, una única responsabilidad, una única razón para cambiar.\nSi una clase tiene más de una responsabilidad, entonces los cambios en una responsabilidad podrían afectar a las otras responsabilidades.\n\nEn este ejemplo, la clase `User` tiene dos responsabilidades:\n- Crear un usuario\n- Mostrar un usuario\n\nPara cumplir con el principio de responsabilidad única, se debe dividir la clase `User` en dos clases:\n- `UserCreator` que se encargará de crear un usuario\n- `UserViewer` que se encargará de mostrar un usuario\n\nEl principio de responsabilidad única es uno de los cinco principios SOLID de la programación orientada a objetos.\n\n\"\"\"\n\"\"\"\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n * Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n\"\"\"\n\n# Clase con dos responsabilidades\nclass UserBad:\n    def __init__(self, name, email):\n        self.name = name\n        self.email = email\n\n    def create_user(self):\n        print(f\"Usuario creado: {self.name} - {self.email}\")\n\n    def show_user(self):\n        print(f\"Nombre: {self.name}\")\n        print(f\"Email: {self.email}\")\n\n# Crear usuario con dos responsabilidades\nuserbad = UserBad(\"John Doe\", \"john@email.com\")\nuserbad.create_user()\nuserbad.show_user()\n\n# Clase con una responsabilidad correcta\nclass User:\n    def __init__(self, name, email):\n        self.name = name\n        self.email = email\n    \nclass UserService:\n    def show(user):\n        print(f\"{user.name}-{user.email}\")\n\nclass EmailService:\n    def send_email(self, email, message):\n        pass\n    \n# Crear un usuario con una responsabilidad\nuser = User(\"John Doe\", \"jonh@email.com\")\nUserService.show(user)\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n * manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n * y el procesamiento de préstamos de libros.\n * Requisitos:\n * 1. Registrar libros: El sistema debe permitir agregar nuevos libros con \n * información básica como título, autor y número de copias disponibles.\n * 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n * información básica como nombre, número de identificación y correo electrónico.\n * 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n * tomar prestados y devolver libros.\n * Instrucciones:\n * 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n * los tres aspectos mencionados anteriormente (registro de libros, registro de\n * usuarios y procesamiento de préstamos).\n * 2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n * siguiendo el Principio de Responsabilidad Única.\n */\n\"\"\"\n\n# Clase con múltiples responsabilidades\nclass Library:\n    def __init__(self):\n        self.books = []\n        self.users = []\n        self.loans = []\n\n    def add_book(self, title, author, copies):\n        self.books.append({\"title\": title, \"author\": author, \"copies\": copies})\n\n    def add_user(self, name, id, email):\n        self.users.append({\"name\": name, \"id\": id, \"email\": email})\n\n    def loan_book(self, user_id, book_title):\n        for book in self.books:\n            if book[\"title\"] == book_title and book[\"copies\"] > 0:\n                book[\"copies\"] -= 1 \n                return True\n        return False\n    \n    def return_book(self, user_id, book_title):\n        for book in self.books:\n            if book[\"title\"] == book_title:\n                book[\"copies\"] += 1\n                return True\n        return False\n    \n\n\n# Principio de responsabilidad única\nclass Book:\n    \n    def __init__(self, title, author, copies):\n        self.title = title\n        self.author = author\n        self.copies = copies\n\nclass User:\n    id = 0\n\n    def __init__(self, name, email):\n        self.name = name\n        self.id = User.id\n        self.email = email\n        User.id += 1\n\nclass Loan:\n    \n    def __init__(self):\n        self.loans=[]\n\n    def loan_book(self, user:User, book: Book):\n        if (book.copies > 0):\n            book.copies -= 1\n            self.loans.append({\"user_id\":user.id, \"book_title\":book.title}) \n            return True\n        return False\n    \n    def return_book(self, user: User, book: Book):\n        \n        for loan in self.loans:\n            if loan[\"user_id\"] == user.id and loan[\"book_title\"] == book.title:\n                self.loans.remove(loan)\n                book.copies+=1\n                return True\n            \n        return False\n\nclass Library:\n\n    def __init__(self):\n        self.books = []\n        self.users = []\n        self.loans = Loan()\n\n    def add_book(self, book: Book):\n        self.books.append(book)\n    \n    def add_user(self, user: User):\n        self.users.append(user)\n        print(f\"Usuario añadido {user.id}\")\t\n    \n    # Presta un libro usando fors.\n    def loan_book(self, user_id, book_title):\n        for user in self.users:\n            if user.id == user_id:\n                for book in self.books:\n                    if book.title == book_title:\n                        return self.loans.loan_book(user, book)\n                return False\n    \n    # Devuelve un libro usando operación generadora \n    def return_book(self, user_id, book_title):\n        user = next((user for user in self.users if user.id == user_id), None)\n        book = next((book for book in self.books if book.title == book_title), None)\n        if user and book:\n            return self.loans.return_book(user, book) \n        return False \n\n# Crear objetos\nbook1 = Book(\"Python Programming\", \"John Doe\", 2)\nbook2 = Book(\"JavaScript Programming\", \"Jane Doe\", 1)\nuser1 = User(\"Alice\", \"Alice@gmail.com\")\nuser2 = User(\"Bob\", \"Bob@gmail.com\")\n\n# Crear biblioteca\nlibrary = Library()\nlibrary.add_book(book1)\nlibrary.add_book(book2)\nlibrary.add_user(user1)\nlibrary.add_user(user2)\n\n# Prestar libros\nprint(f'{library.loan_book(0, \"Python Programming\")}, Alice-Python') # True\nprint(f'{library.loan_book(1, \"JavaScript Programming\")}, Bob-Jav') # True\nprint(f'{library.loan_book(0, \"JavaScript Programming\")}, Alice-Jav') # False\n\n# Devolver libros\nprint(f'{library.return_book(0, \"Python Programming\")}, Alice-Python') # True\nprint(f'{library.return_book(1, \"JavaScript Programming\")}, Bob-Java') # True\nprint(f'{library.return_book(0, \"JavaScript Programming\")}, Alice-Java') # False\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/pyramsd.py",
    "content": "# USO CORRECTO\nclass Order:\n    def __init__(self, order_id, items):\n        self.order_id = order_id\n        self.items = items\n\n    def calculate_total(self):\n        total = sum(item.price for item in self.items)\n        return total\n\nclass OrderRepository:\n    def save(self, order):\n        # Código para guardar la orden en la base de datos\n        pass\n\nclass OrderEmailer:\n    def send_confirmation_email(self, order):\n        # Código para enviar un email de confirmación al cliente\n        pass\n\n\nclass Items:\n    def __init__(self, name: str, price: int) -> None:\n        self.name: str = name\n        self.price: str = price\n\nitem1 = Items(\"Agenda\", 20)\nitem2 = Items(\"Libro\", 10)\nitem3 = Items(\"Cuaderno\", 30)\n\norder = Order(order_id=1, items=[item1, item2, item3])\n\ntotal = order.calculate_total()\nprint(total)\n\norder_repo = OrderRepository()\norder_repo.save(order)\n\nemalier = OrderEmailer()\nemalier.send_confirmation_email(order)\n\n# USO INCORRECTO\nclass Order:\n    def __init__(self, order_id, items):\n        self.order_id = order_id\n        self.items = items\n\n    def calculate_total(self):\n        total = sum(item.price for item in self.items)\n        return total\n\n    def save_to_database(self):\n        # Código para guardar la orden en la base de datos\n        pass\n\n    def send_confirmation_email(self):\n        # Código para enviar un email de confirmación al cliente\n        pass\n\n\n\"\"\"\nEXTRA\n\"\"\"\n# USO INCORRECTO\nclass Library:\n    def __init__(self) -> None:\n        self.libros: list[dict] = []\n        self.usuarios: list[dict] = []\n        self.prestamos: dict = {}\n\n\n    def registrar_libros(self, titulo: str, autor: str, copias: int) -> None:\n        libro = {\"Titulo\":titulo, \"Autor\":autor, \"Copias\":copias}\n        self.libros.append(libro)\n\n    def registrar_usuario(self, nombre: str, user_id: int, email: str) -> None:\n        usuario = {\"Nombre\":nombre, \"ID\":user_id, \"Email\":email}\n        self.usuarios.append(usuario)\n\n    def prestar_libro(self, user_id: int, titulo_libro: str) -> bool:\n        for libro in self.libros:\n            if libro[\"Titulo\"] == titulo_libro and libro[\"Copias\"] > 0:\n                self.prestamos[user_id] = titulo_libro\n                libro[\"Copias\"] -= 1\n                return True\n        return False\n    \n    def devolver_libro(self, user_id: int) -> bool:\n        if user_id in self.prestamos:\n            titulo_libro = self.prestamos.pop(user_id)\n            for libro in self.libros:\n                if libro[\"Titulo\"] == titulo_libro:\n                    libro[\"Copias\"] += 1\n                    return True\n        return False\n    \n\nlibreria = Library()\nlibreria.registrar_libros(\"La pata del pato\", \"Sergio Ruiz\", 10)\nlibreria.registrar_usuario(\"Maicol\", 5, \"maicol@gmail.com\")\nprint(libreria.libros)\nlibreria.prestar_libro(5, \"La pata del pato\")\nprint(libreria.libros)\nprint(libreria.usuarios)\nprint(libreria.prestamos)\nlibreria.devolver_libro(5)\nprint(libreria.libros)\n\n\n# USO CORRECTO\nclass Libro:\n    def __init__(self) -> None:\n        self.libros: dict = {}\n\n    def registrar_libro(self, titulo: str, autor: str, copias: int):\n        if titulo in self.libros:\n            print(f\"Titulo {titulo} ya existe\")\n            return\n        self.libros[titulo] = {\"Autor\": autor,\n                                 \"Copias\": copias}\n        print(f\"Titulo {titulo} fue agregado correctamente\")\n\n    def buscar_libro(self, titulo: str):\n        for titulos, libro in self.libros.items():\n            if titulos == titulo:\n                return titulos, libro\n        print(f\"Titulo {titulo} no fue encontrado\")\n\n\nclass User:\n    def __init__(self) -> None:\n        self.usuarios = {}\n\n    def registrar_usuario(self, nombre: str, id: int, email: str):\n        if nombre in self.usuarios:\n            print(f\"Usuario {nombre} ya se encuentra registrado\")\n            return\n        \n        self.usuarios[id] = {\"nombre\": nombre, \"Correo\": email}\n        print(f\"Usuario {nombre} fue agregado correctamente\")\n\n    def buscar_usuario(self , id: int):\n        for ids, user in self.usuarios.items():\n            if ids == id:\n                return ids, user\n        print(f\"Identificador {id} no fue encontrado\")\n\nclass LibraryManager:\n    def __init__(self, book_manager, user_manager) -> None:\n        self.list_loans = {}\n        self.book_manager = book_manager\n        self.user_manager = user_manager\n\n    def prestamo(self, id, titulos):\n        libro = self.book_manager.buscar_libro(titulos)\n        usuario = self.user_manager.buscar_usuario(id)\n        if usuario and libro and libro[1]['Copias'] > 0:\n            self.list_loans[id] =  titulos\n            libro[1]['Copias'] -= 1\n            print(f\"Libro {titulos} fue prestado al dni {id} y quedan {libro[1]['Copias']} disponibles\")\n            return\n        print(f\"Ha ocurrido un error\")\n    \n    def retornar(self, id, titulo):\n        for ids, titles in self.list_loans.items():\n            if ids == id and titles == titulo:\n                del self.list_loans[id]\n                book = self.book_manager.buscar_libro(titulo)\n                if book:\n                    book[1]['Copias']+=1\n                    print(f\"Libro {titulo} fue devuelto por el id {id}, quedan {book[1]['Copias']} disponibles\")\n                    return\n        print(f\"Ha ocurrido un error al retornar el libro\")\nbook_manager = Libro()\nbook_manager.registrar_libro(\"La culpa es de la vaca\", \"Jaime Lopera\", 15)\nbook_manager.registrar_libro(\"El programador pragmatico\", \"Andrew Hunt\", 20)\n\nuser_manager = User()\nuser_manager.registrar_usuario(\"alan\", 123456, \"alan2085@gmail.com\")\nuser_manager.registrar_usuario(\"matheo\", 852963, \"matheo0301@gmail.com\")\n\nlibrary_manager = LibraryManager(book_manager, user_manager)\nlibrary_manager.prestamo(123456, \"El programador pragmatico\")\nlibrary_manager.prestamo(852963, \"El programador pragmatico\")\nlibrary_manager.retornar(123456, \"El programador pragmatico\")\nlibrary_manager.retornar(852963, \"El programador pragmatico\")"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/qwik-zgheib.py",
    "content": "# -- exercise\n# incorrect\nclass HeroI:\n    def __init__(self, name, primary_attribute, base_damage, health):\n        self.name = name;\n        self.primary_attribute = primary_attribute;\n        self.base_damage = base_damage;\n        self.health = health;\n\n    def calculate_damage(self, additional_damage):\n        return self.base_damage + additional_damage;\n\n    def display_info(self):\n        info = f\"Hero: {self.name}\\n\";\n        info += f\"Primary Attribute: {self.primary_attribute}\\n\";\n        info += f\"Base Damage: {self.base_damage}\\n\";\n        info += f\"Health: {self.health}\";\n        return info;\n\nhero = HeroI(\"Axe\", \"Strength\", 50, 1000);\nprint(hero.display_info());\nprint(f\"Damage: {hero.calculate_damage(20)}\");\n\n# correct\nclass HeroC:\n    def __init__(self, name, primary_attribute, base_damage, health):\n        self.name = name;\n        self.primary_attribute = primary_attribute;\n        self.base_damage = base_damage;\n        self.health = health;\n\nclass DamageCalculator:\n    def calculate_damage(self, hero, additional_damage):\n        return hero.base_damage + additional_damage;\n\nclass HeroDisplay:\n    def display_info(self, hero):\n        info = f\"Hero: {hero.name}\\n\"\n        info += f\"Primary Attribute: {hero.primary_attribute}\\n\";\n        info += f\"Base Damage: {hero.base_damage}\\n\";\n        info += f\"Health: {hero.health}\";\n        return info;\n\nprint(\"------------------------------------------------\")\nhero = HeroC(\"Axe\", \"Strength\", 50, 1000);\ndamage_calculator = DamageCalculator();\nhero_display = HeroDisplay();\n\nprint(hero_display.display_info(hero))\nprint(f\"Damage: {damage_calculator.calculate_damage(hero, 20)}\");\n\n# -- extra challenge\n# incorrect\nclass Library:\n    def __init__(self):\n        self.books = [];\n        self.users = [];\n        self.loans = [];\n\n    def add_book(self, title, author, copies):\n        book = {\"title\": title, \"author\": author, \"copies\": copies};\n        self.books.append(book);\n\n    def add_user(self, name, user_id, email):\n        user = {\"name\": name, \"user_id\": user_id, \"email\": email};\n        self.users.append(user);\n\n    def loan_book(self, user_id, book_title):\n        for book in self.books:\n            if book[\"title\"] == book_title and book[\"copies\"] > 0:\n                self.loans.append({\"user_id\": user_id, \"book_title\": book_title});\n                book[\"copies\"] -= 1;\n                return True;\n        return False;\n\n    def return_book(self, user_id, book_title):\n        for loan in self.loans:\n            if loan[\"user_id\"] == user_id and loan[\"book_title\"] == book_title:\n                self.loans.remove(loan);\n                for book in self.books:\n                    if book[\"title\"] == book_title:\n                        book[\"copies\"] += 1;\n                        return True;\n        return False;\n\nlibrary = Library()\nlibrary.add_book(\"1996\", \"Ahmed Khedr\", 4);\nlibrary.add_user(\"Legion Commander\", 1, \"legioncommander@gmail.com\");\nlibrary.loan_book(1, \"1996\");\nlibrary.return_book(1, \"1996\");\n\n\n# correct\nclass BookManager:\n    def __init__(self):\n        self.books = [];\n\n    def add_book(self, title, author, copies):\n        book = {\"title\": title, \"author\": author, \"copies\": copies};\n        self.books.append(book);\n\n    def update_copies(self, book_title, copies):\n        for book in self.books:\n            if book[\"title\"] == book_title:\n                book[\"copies\"] += copies;\n                return True;\n        return False;\n\n    def get_book(self, book_title):\n        for book in self.books:\n            if book[\"title\"] == book_title:\n                return book;\n        return None;\n\nclass UserManager:\n    def __init__(self):\n        self.users = [];\n\n    def add_user(self, name, user_id, email):\n        user = {\"name\": name, \"user_id\": user_id, \"email\": email};\n        self.users.append(user);\n\n    def get_user(self, user_id):\n        for user in self.users:\n            if user[\"user_id\"] == user_id:\n                return user;\n        return None;\n\nclass LoanManager:\n    def __init__(self, book_manager):\n        self.loans = [];\n        self.book_manager = book_manager;\n\n    def loan_book(self, user_id, book_title):\n        book = self.book_manager.get_book(book_title);\n        if book and book[\"copies\"] > 0:\n            self.loans.append({\"user_id\": user_id, \"book_title\": book_title});\n            self.book_manager.update_copies(book_title, -1);\n            return True;\n        return False;\n\n    def return_book(self, user_id, book_title):\n        for loan in self.loans:\n            if loan[\"user_id\"] == user_id and loan[\"book_title\"] == book_title:\n                self.loans.remove(loan);\n                self.book_manager.update_copies(book_title, 1);\n                return True;\n        return False;\n\n# Uso correcto\nbook_manager = BookManager();\nuser_manager = UserManager();\nloan_manager = LoanManager(book_manager);\n\nbook_manager.add_book(\"1996\", \"Ahmed Khedr\", 4);\nuser_manager.add_user(\"Legion Commander\", 1, \"legioncommander@gmail.com\");\nloan_manager.loan_book(1, \"1996\");\nloan_manager.return_book(1, \"1996\");\n\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/rantamhack.py",
    "content": "\n\nprint(\"\\n\\n=======================================EJERCICIOa=======================================\\n\\n\")\n\n\"\"\"\n * EJERCICIO:\n * Explora el \"Principio SOLID de Responsabilidad Unica (Single Responsibility\n * Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n\"\"\"\n\n# * Ejemplo sin aplicar el principio \"SRP\". La clase tiene la responsabilidad sobre cualquier cambio que queramos hacer\n    \n\nclass MouredevAcademy:\n\n    def __init__(self) -> None:\n        self.students = []\n        \n    def auth(self, name: str, password: str):\n        self.name = name\n        self.password = password\n        \n    def students_db(self, id: int, username: str, name: str, surname: str, email: str):\n        self.id = id\n        self.username = username\n        self.name = name\n        self.surname = surname\n        self.email = email\n        \n    def subs_type(self, monthly: any, quarterly: any, half_yearly: any, yearly: any):\n        self.monthly = monthly\n        self.quarterly = quarterly\n        self.half_yearly = half_yearly\n        self.yearly = yearly\n        \n    def payment(self, credit_card: dict, debit_card: dict, bizum: dict, bank_transfer: dict):\n        self.credit_card = credit_card\n        self.debit_card = debit_card\n        self.bizum = bizum\n        self.bank_transfer = bank_transfer\n        \n\n# * Aplicando el principio \"SRP\"\n\n\nclass auth:\n    def __init__(self, name: str, password: str):\n        self.name = name\n        self.password = password\n        \n    def authenticate():\n        # Logica de autenticacion\n        pass\n        \nclass Student:\n    def __init__(self, id: int, username: str, name: str, surname:str, email: str):\n        self.id = id\n        self.username = username\n        self.name = name\n        self.surname = surname\n        self.email = email\n        \nclass Subscription:\n    def __init__(self, monthly: any, quarterly: any, half_yearly: any, yearly: any):\n        self.monthly = monthly\n        self.quarterly = quarterly\n        self.half_yearly = half_yearly\n        self.yearly = yearly\n        \nclass Payment:\n    def __init__(self, credit_card: dict, debit_card: dict, bizum: dict, bank_transfer: dict):\n        self.credit_card = credit_card\n        self.debit_card = debit_card\n        self.bizum = bizum\n        self.bank_transfer = bank_transfer\n        \n    def process_payment(self):\n        # Logica de procesamiento de pagos\n        pass\n    \nclass MouredevAcademy:\n    def __init__(self):\n        self.students = []\n        self.subscription = []\n        self.payment = []\n        \n    def add_students(self, student: Student):\n        self.students.append(student)\n        \n    def add_subscription(self, subscription: Subscription):\n        self.subscription.append(subscription)\n        \n    def add_payment(self, payment: Payment):\n        self.payment.append(payment)\n         \n    \n\n\n\nprint(\"\\n\\n=======================================DIFICULTAD EXTRA SIN 'SRP'=======================================\\n\\n\")\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un sistema de gestionn para una biblioteca. El sistema necesita\n * manejar diferentes aspectos como el registro de libros, la gestion de usuarios\n * y el procesamiento de prestamos de libros.\n * Requisitos:\n * 1. Registrar libros: El sistema debe permitir agregar nuevos libros con \n * informacion basica como ti­tulo, autor y numero de copias disponibles.\n * 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n * informacion basica como nombre, numero de identificacion y correo electronico.\n * 3. Procesar prestamos de libros: El sistema debe permitir a los usuarios\n * tomar prestados y devolver libros.\n * Instrucciones:\n * 1. Diseñ±a una clase que no cumple el SRP: Crea una clase Library que maneje\n * los tres aspectos mencionados anteriormente (registro de libros, registro de\n * usuarios y procesamiento de prestamos).\n * 2. Refactoriza el codigo: Separa las responsabilidades en diferentes clases\n * siguiendo el Principio de Responsabilidad Ãšnica.\n\"\"\"\n\n# * Ejemplo sin aplicar el principio \"SRP\"\n\n\nclass Library:\n    def __init__(self):\n        self.books = []\n        self.users = []\n        self.lending = []\n    \n    def add_book(self, title: str, author: str, n_copies: int):\n\n        new_book = {\"title\": title, \"author\": author, \"n_copies\": n_copies}    \n        self.books.append(new_book)\n        print(f\"[+] Se ha aÃ±adido {new_book} a la biblioteca\")\n        \n        book_found = False\n        for book in self.books:\n            if book[\"title\"] == title:\n                book[\"n_copies\"] += n_copies\n                book_found = True\n                print(f\"Ahora hay {n_copies} en la biblioteca del libro {title}\")\n            else:\n                n_copies += 1\n                print(f\"Hay un titulo nuevo en la biblioteca: {title}\")\n    \n    def add_user(self, name: str, user_id: int, email: str):\n        \n        new_user = {\"name\": name, \"id\": user_id, \"email\": email }\n        \n        if new_user not in self.users:\n            self.users.append(new_user)\n            print(f\"[+] Se ha aÃ±adido el nuevo usuario {new_user} a la biblioteca\")\n        else:\n            print(f\"[!] {new_user} ya es usuario de la biblioteca\")\n    \n    def book_lending(self, title: str, user_id: int):\n        \n        user_found = False\n        for user in self.users:\n            if user[\"id\"] == user_id:\n                user_found = True\n                break\n            \n        if not user_found:\n            print(\"[!] No estas registrado en la biblioteca, no puedes llevarte ningun libro\")\n            return\n                \n        for book in self.books:\n            if book[\"title\"] == title:\n                if book[\"n_copies\"] > 0:\n                    book[\"n_copies\"] -= 1\n                    print(f\"[!] El usuario con el id {user_id} ha recogido el libro {title}\")\n                else: \n                    print(f\"[!] Ahora mismo no hay ninguna copia disponible del libro {title}\")\n                return\n            \n        print(f\"[!] El libro {title} no lo tenemos en la biblioteca\")\n                \n\nmy_library = Library()\n\nmy_library.add_book(\"git & github desde cero\", \"Brais Moure\", 4)\nmy_library.add_book(\"Codigo limpio\", \"Robert C. Martin\", 2)\nmy_library.add_book(\"Ultimate Python\", \"Nicolas shurmann\", 3)\n\nmy_library.add_user(\"Rantam\", 1, \"rantam@rantam.com\")\nmy_library.add_user(\"Pablo\", 2, \"Pablo@rantam.com\")\n\nprint(f\"[+] Libros en la biblioteca: {my_library.books}\")\nprint(f\"[+] Usuarios de la biblioteca: {my_library.users}\")\n\nmy_library.book_lending(\"git & github desde cero\", 1)\nmy_library.book_lending(\"Codigo limpio\", 2)\nmy_library.book_lending(\"git & github desde cero\", 3)\nmy_library.book_lending(\"Ultimate Python\", 1)\n\nprint(f\"[+] Libros en la biblioteca: {my_library.books}\")\n\n\nprint(\"\\n\\n=======================================DIFICULTAD EXTRA CON 'SRP'=======================================\\n\\n\")\n\n\n# * Ejemplo aplicando el principio \"SRP\"\n\n\nclass Book:\n    def __init__(self, title: str, author: str, n_copies: int):\n        self.title = title\n        self.author = author\n        self.n_copies = n_copies\n        \n    def lend_book(self):\n        if self.n_copies > 0:\n            self.n_copies -= 1\n            return True\n        return False\n    \n    def return_book(self):\n        self.n_copies += 1\n    \nclass User:\n    def __init__(self, name, user_id, email):\n        self.name = name\n        self.user_id = user_id\n        self.email = email\n\n\n\nclass Library:\n    def __init__(self):\n        self.books = []\n        self.users = []\n                \n    def add_book(self, book: Book):\n        self.books.append(book)\n        print(f\"[+] Se ha aÃ±adido {book.title} a la biblioteca\")\n        \n    def add_user(self, user: User):\n        if user not in self.users:\n            self.users.append(user)\n            print(f\"[+] Se ha aÃ±adido el nuevo usuario {user.name} a la biblioteca\")\n        else:\n            print(f\"[!] {user.name} ya es usuario de la biblioteca\")\n    \n\n        \n    \nclass BookLending:\n    def __init__(self, library: Library):\n        self.library = library\n        self.lending_records = []\n        \n    def lend_book(self, title: str, user_id: int):\n        \n        user_found = False\n        for user in self.library.users:\n            if user.user_id == user_id:\n                user_found = True\n                break\n            \n        if not user_found:\n            print(\"[!] No estas registrado en la biblioteca, no puedes llevarte ningun libro\")\n            return\n                \n        for book in self.library.books:\n            if book.title == title:\n                if book.lend_book():\n                    self.lending_records.append((title, user_id))\n                    print(f\"[!] El usuario con el id {user_id} ha recogido el libro {title}\")\n                else: \n                    print(f\"[!] Ahora mismo no hay ninguna copia disponible del libro {title}\")\n                return\n            \n        print(f\"[!] El libro {title} no lo tenemos en la biblioteca\")\n        \n    def return_book(self, title: str, user_id: int):\n        if (title, user_id) in self.lending_records:\n            for book in self.library.books:\n                if book.title == title:\n                    book.return_book()\n                    self.lending_records.remove((title, user_id))\n                    print(f\"[+] El ususario con el id {user_id} ha devuelto el libro {title}\")\n                    return\n        print(f\"[!] No se encontro el registro de prestamo para el libro {title} por el usuario con el id {user_id}\")\n                \n\nmy_library = Library()\n\nbook1 = Book(\"git & github desde cero\", \"Brais Moure\", 4)\nbook2 = Book(\"Codigo limpio\", \"Robert C. Martin\", 2)\nbook3 = Book(\"Ultimate Python\", \"Nicolas shurmann\", 3)\n\nmy_library.add_book(book1)\nmy_library.add_book(book2)\nmy_library.add_book(book3)\n\nuser1 = User(\"Rantam\", 1, \"rantam@rantam.com\")\nuser2 = User(\"Pablo\", 2, \"Pablo@rantam.com\")\n\nmy_library.add_user(user1)\nmy_library.add_user(user2)\n\nbook_lending = BookLending(my_library)\n\n\nprint(f\"[+] Libros en la biblioteca: {[book.title for book in my_library.books]}\")\nprint(f\"[+] Usuarios de la biblioteca: {[user.name for user in my_library.users]}\")\n\nbook_lending.lend_book(\"git & github desde cero\", 1)\nbook_lending.lend_book(\"Codigo limpio\", 2)\nbook_lending.lend_book(\"git & github desde cero\", 3)\n\nbook_lending.return_book(\"git & github desde cero\", 1)\nbook_lending.return_book(\"Codigo limpio\", 2)\nbook_lending.return_book(\"git & github desde cero\", 3)\n\n\nprint(f\"[+] Libros en la biblioteca: {[book.title for book in my_library.books]}\")\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/raulG91.py",
    "content": "#Solid\n\n#Incorrect behaviour\n\nclass Invoice:\n    def addInvoice(self):\n        pass\n    def removeInvoice(self):\n        pass\n    def generateInvoiceReport(self):\n        pass\n    def sendInvoiceEmail(self):\n        pass\n\n# Same using single responsability Principle\n\nclass Invoice:\n    def addInvoice(self):\n        pass\n    def removeInvoice(self):\n        pass\n\nclass InvoiceReport:\n    def generateInvoiceReport(self):\n        pass\n\nclass InvoiceEmail:\n    def sendInvoiceEmail(self):\n        pass\n\n#Extra\n\nclass Library:\n    def __init__(self):\n       self.books = []\n       self.users = []\n       self.loan = []\n    def addBook(self,title,author,units):\n        new_book = {\n            \"title\":title,\n            \"author\": author,\n            \"units\" : units\n        }\n        self.books.append(new_book)\n    def addUser(self,name,id,email):\n        new_user ={\n            \"name\": name,\n            \"id\" : id,\n            \"email\": email\n        }\n        self.users.append(new_user)\n\n    def add_loan(self,title,name):\n\n        num_loans = 0\n        for element in self.loan:\n            if element[\"title\"] == title:\n                num_loans+=1\n        stock = 0\n        for book in self.books:\n            if book[\"title\"] == title:\n                stock = book[\"units\"]\n\n        if num_loans + 1 <= stock:\n            new_loan = {\n                \"title\":title,\n                \"name\":name\n            }       \n            self.loan.append(new_loan) \n            print(f'New loan {title} user {name}')\n        else:\n            print(\"Loan is not possible since there is not stock available\")    \n    def remove_loan(self,title,name):\n        for element in self.loan:\n            if element[\"title\"] == title and element[\"name\"] == name:\n                self.loan.remove(element)      \n                break\n        print(self.loan)    \n\nlibrary = Library()\nlibrary.addUser(\"Raul\",\"12345678N\",\"raul@test.com\")\nlibrary.addUser(\"Maria\",\"23450098T\",\"maria@test.com\")\nlibrary.addUser(\"Pepe\",\"12344500V\",\"pepe@test.com\")\nlibrary.addBook(\"Harry Potter\",\"JK Rowling\",2)\nlibrary.addBook(\"El quijote\",\"Miguel de Cervantes\",5)\n\nlibrary.add_loan(\"Harry Potter\",\"Raul\")\nlibrary.add_loan(\"Harry Potter\",\"Maria\")\nlibrary.add_loan(\"El quijote\",\"Pepe\")\nlibrary.remove_loan(\"El quijote\",\"Pepe\")\nlibrary.remove_loan(\"Harry Potter\",\"Maria\")\nlibrary.add_loan(\"Harry Potter\",\"Pepe\")\n\nclass Book:\n    def __init__(self,title,author,units):\n        self.title = title\n        self.author = author\n        self.units = units\n    def getTitle(self):\n        return self.title\n    def getAuthor(self):\n        return self.author\n    def getUnits(self):\n        return self.units    \n\nclass BooksDB:\n    def __init__(self):\n        self.books=[]\n    def add_book_db(self,book:Book):\n        self.books.append(book)\n    def remove_book_db(self,book:Book):\n        self.books.remove(book)  \n\nclass User:\n    def __init__(self,name,id,email):\n        self.name = name\n        self.id = id\n        self.email = email\n    def getName(self):\n        return self.name\n    def getId(self):\n        return self.id\n    def getEmail(self):\n        return self.email\n\nclass UserDB:\n    def __init__(self):\n        self.users = []    \n    def addUserDB(self,user:User):\n        self.users.append(user)   \n       \nclass BookLoan:\n    def __init__(self):\n        self.loans = []\n    def addLoand(self,book:Book,user:User):\n        num_loans = 0\n        for loan in self.loans:\n            if loan[0].getTitle() == book.getTitle():\n                num_loans+=1\n\n        if num_loans + 1 <= book.getUnits():\n            self.loans.append((book,user))\n            print(f'New loan {book.getTitle()} to user {user.getName()}')\n        else:\n            print(\"Loan is not possible since there is not stock available\")\n    def removeLoan(self,book:Book,user:User):\n        for loan in self.loans:\n            if loan[0].getTitle() == book.getTitle() and user.getName()==loan[1].getName():\n                print(f'Removing loan {loan[0].getTitle()} user {loan[1].getName()}')        \n                self.loans.remove(loan)\ndbUser = UserDB() \ndbBooks = BooksDB()   \nloan_handler = BookLoan()\nuser1 = User(\"Raul\",\"25350036B\",\"raul@test.com\")\ndbUser.addUserDB(user1)\nuser2 = User(\"Maria\",\"15233454T\",\"maria@test.com\")\ndbUser.addUserDB(user2)\nbook = Book(\"Harry Potter\",\"JK Rowling\",2)\ndbBooks.add_book_db(book)\nbook2 = Book(\"El Quijote\",\"Miguel de Cervantes\",5)\ndbBooks.add_book_db(book2)\nloan_handler.addLoand(book,user1)\nloan_handler.addLoand(book,user2)\nloan_handler.removeLoan(book,user1)"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/raynerpv2022.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n#  * Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n#  * de forma correcta e incorrecta.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n#  * manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n#  * y el procesamiento de préstamos de libros.\n#  * Requisitos:\n#  * 1. Registrar libros: El sistema debe permitir agregar nuevos libros con \n#  * información básica como título, autor y número de copias disponibles.\n#  * 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n#  * información básica como nombre, número de identificación y correo electrónico.\n#  * 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n#  * tomar prestados y devolver libros.\n#  * Instrucciones:\n#  * 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n#  * los tres aspectos mencionados anteriormente (registro de libros, registro de\n#  * usuarios y procesamiento de préstamos).\n#  * 2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n#  * siguiendo el Principio de Responsabilidad Única.\n#  */\n\n# incorrect\nclass Number_I:\n    def __init__(self,n1 = 0,n2 =0) -> None:\n        self.n1 = n1\n        self.n2 = n2\n\n    def sum_numbers(self):\n        self.sum = self.n1+self.n2\n        \n    def rest_numbers(self):\n        self.rest = self.n1-self.n2\n    \n    def mult_number(self):\n        self.mult = self.n1*self.n2\n\n    def div_number(self):\n        if self.n2 == 0:\n            self.div = 0\n        else:\n            self.div = self.n1/self.n2\n\n    def print_result(self):\n        print(self.div)\n        print(self.mult)\n        print(self.sum)\n        print(self.rest)\n\n     \n\n#correct\nclass Number_c:\n    def __init__(self, n1,n2) -> None:\n        self.n1 = n1\n        self.n2 = n2\n\nclass Operation:\n\n    def sum_number(self,n: Number_c):\n        self.sum =  n.n1+ n.n2\n        \n    def rest_number(self,n: Number_c):\n        self.rest =  n.n1- n.n2\n    \n    def mult_number(self,n: Number_c):\n        self.mult =  n.n1* n.n2\n\n    def div_number(self,n: Number_c):\n        if  n.n2 == 0:\n            self.div = 0\n        else:\n            self.div =  n.n1/ n.n2\n\nclass Print:\n    \n     def print_result(self,result, operation):\n            print(f\"El resultado de la {operation} es {result}\")\n\n         \n\n\n  \n\nnumber = Number_I(12,12)\nnumber.rest_numbers()\nnumber.mult_number()\nnumber.sum_numbers()\nnumber.div_number()\nnumber.print_result()\n\nnumber_1 = Number_c(33,33)\noperation = Operation()\np = Print()\noperation.div_number(number_1)\noperation.mult_number(number_1)\noperation.rest_number(number_1)\noperation.sum_number(number_1)\np.print_result(operation.div,\"division\")\np.print_result(operation.mult,\"multiplicacion\")\np.print_result(operation.rest,\"resta\")\np.print_result(operation.sum,\"suma\")\n\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n#  * manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n#  * y el procesamiento de préstamos de libros.\n#  * Requisitos:\n#  * 1. Registrar libros: El sistema debe permitir agregar nuevos libros con \n#  * información básica como título, autor y número de copias disponibles.\n#  * 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n#  * información básica como nombre, número de identificación y correo electrónico.\n#  * 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n#  * tomar prestados y devolver libros.\n#  * Instrucciones:\n#  * 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n#  * los tres aspectos mencionados anteriormente (registro de libros, registro de\n#  * usuarios y procesamiento de préstamos).\n#  * 2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n#  * siguiendo el Principio de Responsabilidad Única.\n#  */\n\n\n# SIn usar SRP\nclass Book:\n\n    def __init__(self, title, author,copies) -> None:\n        self.title = title\n        self.author = author\n        self.copies = copies\n    def print_book(self):\n        print(f\"Titulo : {self.title}, Autor {self.author}, Copias {self.copies}\")\n\nclass User:\n    def __init__(self,name, id, email) -> None:\n        self.name = name\n        self.id = id\n        self. email = email\n\n    def print_user(self):\n        print(f\"Nombre : {self.name}, Id {self.id}, email {self.email}\")\n\nclass library:\n    \n    prestamo = {}\n    user  = []\n    book = []\n\n    def Add_user(self, *user: User):\n        self.user = list(user)\n    \n    def Add_book(self, *book:Book):\n        self.book = list(book)\n\n\n\n    def get_user(self,user ):\n        if not user in self.user:\n            print(f\"Usuario {user.name} no resgistrado, registrese primero\")\n            return False\n        return True\n             \n\n    \n    def get_book(self,book ):\n        if not book in self.book:\n            print(f\"Libro {book.title} no resgistrado, registrelo primero\")\n            return False\n        return True\n             \n    \n    def get_book_prestamo(self, book: Book):\n        for i,v in self.prestamo.items():\n            \n            if book.title == i.title:\n                 print(f\"Libro {book.title} actualmente en prestamos, imposible volver a prestar\")\n                 return True\n        return False\n    \n    def Set_Prestamo(self, user: User, book: Book):\n        if not self.get_user(user):\n            return\n        if not self.get_book(book):\n            return\n        \n        if self.get_book_prestamo(book):\n            return\n        self.prestamo[book] = user \n        print(f\" Libro {book.title } ha sido prestado a {user.name }\")\n        \n    def back_prestamo(self,book: Book):\n        \n        if not self.get_book(book):\n            return\n        \n        if  not self.get_book_prestamo(book):\n            print(f\"Libro {book.title} no esta en  prestamos, imposible devolver\")\n            return\n         \n        self.prestamo.pop(book)\n        print(f\"El libro {book.title} se ha devuelto correctamente\")\n    \n    def list_user(self):\n        print(\"Lista de Usuarios\")\n        for i in self.user:\n            print(i.print_user())\n    \n    def list_book(self):\n        print(\"Lista de libros\")\n        for i in self.book:\n            print(i.print_book())\n\n    def list_prestamos(self):\n        print(\"Lista de prestamos\")\n        if len(self.prestamo) == 0:\n            print(f\" NO existen prestamos\")\n        for i, v in self.prestamo.items():\n            print(f\" Libro {i.title} Usuario {v.name}\")\n\nu1 = User(\"pepe1\",123,\"aa@aa\")\nu2 = User(\"pepe2\",123,\"aa@aa\")\nu3 = User(\"pepe3\",123,\"aa@aa\")\nu4 = User(\"pepe4\",123,\"aa@aa\")\n\nb1 = Book(\"b1\",\"cc\",12)\nb2 = Book(\"b2\",\"cc\",12)\nb3 = Book(\"b3\",\"cc\",12)\nb4 = Book(\"b4\",\"cc\",12)\n\n\n\nlibrary = library()\nlibrary.Add_user(u1,u2,u3)\nlibrary.Add_book(b1,b2,b3)\nlibrary.list_book()\nlibrary.list_user()\n\nlibrary.Set_Prestamo(u1 ,b1 )\nlibrary.list_prestamos()\nlibrary.Set_Prestamo(u2 ,b1 )\nlibrary.list_prestamos()\nlibrary.Set_Prestamo(u2 ,b2)\nlibrary.list_prestamos()\n\nlibrary.back_prestamo(b3 )\nlibrary.list_prestamos()\nlibrary.back_prestamo(b4 )\nlibrary.list_prestamos()\nlibrary.Set_Prestamo(u2 ,b3)\nlibrary.list_prestamos()\nlibrary.back_prestamo(b3 )\nlibrary.list_prestamos()\n\nlibrary.Set_Prestamo(u3 ,b2 )\nlibrary.Set_Prestamo(u3 ,b3 )\nlibrary.list_prestamos()\n\n\n#  RSP\n\nclass Book1:\n\n    def __init__(self, title, author,copies) -> None:\n        self.title = title\n        self.author = author\n        self.copies = copies\n    \n    \n\nclass User1:\n    def __init__(self,name, id, email) -> None:\n        self.name = name\n        self.id = id\n        self. email = email\n\n    def print_user(self):\n        print(f\"Nombre : {self.name}, Id {self.id}, email {self.email}\")\n\n\n\n\nclass Library1:\n    \n    \n\n    def __init__(self) -> None:\n        self.user = []\n        self.book = []\n        self.loans = Lending()\n\n    def Add_user(self,*user: User):\n        self.user = list(user)\n\n \n    def Add_book(self,*book:Book ):\n        self.book = list(book)\n\n    def is_user_in(self,user):\n        return user in self.user\n\n    def is_book_in(self,book):\n        return book in self.book\n\n    def loan_book(self, user:User,book:Book):\n        if not self.is_user_in(user):\n            print(f\"Usuario {user.name} no resgistrado, registrese primero\")\n            return\n        if not self.is_book_in(book):\n            print(f\"Libro {book.title} no resgistrado, registrelo primero\")\n            return \n        \n        self.loans.Set_loans(user,book)\n    \n    def return_book(self,book):\n        if not self.is_book_in(book):\n            print(f\"Libro {book.title} no resgistrado, registrelo primero\")\n            return \n        self.loans.Back_loans(book)\n\n    \n   \n\n\nclass Lending:\n\n    def __init__(self) -> None:\n        self.loans =  {}\n    \n\n    def Set_loans(self, user: User, book: Book, ):\n         \n        if book.title in self.loans:\n                 print(f\"Libro {book.title} actualmente en prestamos, imposible volver a prestar\")\n                 return True \n\n        self.loans[book] = user \n        print(f\" Libro {book.title } ha sido prestado a {user.name }\")\n        \n    def Back_loans(self,book: Book):\n         \n        if  not book in self.loans:\n            print(f\"Libro {book.title} no esta en  prestamos, imposible devolver\")\n            return\n         \n        self.loans.pop(book)\n        print(f\"El libro {book.title} se ha devuelto correctamente\")\n\n     \n\nclass PrintService:\n\n    # @staticmethod  puede llamarse al metodo sin necesidad de instanciar la clase\n    @staticmethod\n    def print_book(book: Book1):\n        print(f\"Titulo : {book.title}, Autor {book.author}, Copias {book.copies}\")\n\n    @staticmethod\n    def print_user(user: User1):\n        print(f\"Nombre : {user.name}, Id {user.id}, email {user.email}\")\n\n    @staticmethod  \n    def list_loans(loans):\n        print(\"Lista de prestamos\")\n        if len(loans.loans) == 0:\n            print(f\" NO existen prestamos\")\n        for i, v in loans.loans.items():\n            print(f\" Libro {i.title} Usuario {v.name}\")\n\n    @staticmethod\n    def list_user(users):\n        print(\"Lista de Usuarios\")\n        for i in users:\n           PrintService.print_user(i)\n\n    @staticmethod\n    def list_book(books):\n        print(\"Lista de libros\")\n        for i in books:\n            PrintService.print_book(i)\n    \n    \n\n\n\n\nu11 = User1(\"user 1\",123,\"aa@aa\")\nu22 = User1(\"user 2\",123,\"aa@aa\")\nu33 = User1(\"user 3\",123,\"aa@aa\")\nu44 = User1(\"user 4\",123,\"aa@aa\")\n\nb11 = Book1(\"book 1\",\"cc\",12)\nb22 = Book1(\"book 2\",\"cc\",12)\nb33 = Book1(\"book 3\",\"cc\",12)\nb44 = Book1(\"book 4\",\"cc\",12)\n\nprint(\"Refactorizando ... RSP\")\n\nl1 = Library1()\n\n \nl1.Add_user(u11,u22,u33)\nl1.Add_book(b11,b2,b33)\nPrintService.list_book(l1.book)\nPrintService.list_user(l1.user)\nPrintService.list_loans(l1.loans)\n\nl1.loan_book(u44,b1)\nl1.loan_book(u1,b44)\nl1.loan_book(u11,b11)\nl1.loan_book(u22,b33)\nPrintService.list_loans(l1.loans)\nl1.loan_book(u22,b22)\nPrintService.list_loans(l1.loans)\n \n \n\nl1.return_book(b44)\nPrintService.list_loans(l1.loans)\nl1.return_book(b11)\nPrintService.list_loans(l1.loans)\n \n \n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/rigo93acosta.py",
    "content": "'''\n * EJERCICIO:\n * Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n * Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n * manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n * y el procesamiento de préstamos de libros.\n * Requisitos:\n * 1. Registrar libros: El sistema debe permitir agregar nuevos libros con \n * información básica como título, autor y número de copias disponibles.\n * 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n * información básica como nombre, número de identificación y correo electrónico.\n * 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n * tomar prestados y devolver libros.\n * Instrucciones:\n * 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n * los tres aspectos mencionados anteriormente (registro de libros, registro de\n * usuarios y procesamiento de préstamos).\n * 2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n * siguiendo el Principio de Responsabilidad Única.\n */\n'''\n\n'''\n Basico\n'''\n\n# Incorrecto\n\nclass Usuario:\n    \n    def __init__(self, name, email) -> None:\n        self.name = name\n        self.email = email\n\n    def save_to_database(self):\n        ...\n\n    def send_email(self):\n        ...\n\n\n# Correcto\nclass Usuario:\n    \n    def __init__(self, name, email) -> None:\n        self.name = name\n        self.email = email\n\nclass UserService:\n    \n    def save_to_database(self, user):\n        ...\n\nclass EmailService:\n\n    def send_email(self, user, message):\n        ...\n\n\n'''\nExtra\n'''\n\n# Incorrecto\nclass Library:\n    \n    def __init__(self) -> None:\n        self.books = []\n        self.users = []\n        self.loans = []\n\n    def add_book(self, title, author, copies):\n        self.books.append({'title': title, 'author': author, 'copies': copies})\n\n    def add_user(self, name, user_id, email):\n        self.users.append({'name': name, 'id': user_id, 'email': email})\n\n    def loan_book(self, user_id, book_title):\n        for book in self.books:\n            if book['title'] == book_title and book['copies'] > 0:\n                book['copies'] -= 1\n                self.loans.append({'user_id': user_id, 'book_title': book_title})\n                return True\n        return False\n    \n    def return_book(self, user_id, book_title):\n        for loan in self.loans:\n            if loan['user_id'] == user_id and loan['book_title'] == book_title:\n                self.loans.remove(loan)\n                for book in self.books:\n                    if book['title'] == book_title:\n                        book['copies'] += 1\n                return True\n        return False\n\n\n# Correcto\nclass Book:  \n    def __init__(self, title, author, copies) -> None:\n        self.title = title\n        self.author = author\n        self.copies = copies\n\nclass User:\n    def __init__(self, name, user_id, email) -> None:\n        self.name = name\n        self.user_id = user_id\n        self.email = email\n\nclass Loan:\n    def __init__(self) -> None:\n        self.loans = []\n \n    def loan_book(self, user, book):\n        if book.copies > 0:\n            book.copies -= 1\n            self.loans.append(\n                {'user_id': user.user_id, 'book_title': book.title})\n            return True\n    \n    def return_book(self, user, book):\n        for loan in self.loans:\n            if loan['user_id'] == user.user_id and loan['book_title'] == book.title:\n                self.loans.remove(loan)\n                book.copies += 1\n                return True\n        return False\n\n\nclass Library:\n    def __init__(self) -> None:\n        self.books = []\n        self.users = []\n        self.loans_service = Loan()\n\n    def add_book(self, book):\n        self.books.append(book)\n\n    def add_user(self, user):\n        self.users.append(user)\n\n    def loan_book(self, user_id, book_title):\n        user = next((u for u in self.users if u.user_id == user_id), None)\n        book = next((b for b in self.books if b.title == book_title), None)\n        if user and book:\n            return self.loans_service.loan_book(user, book)\n        return False\n    \n    def return_book(self, user_id, book_title):\n        user = next((u for u in self.users if u.user_id == user_id), None)\n        book = next((b for b in self.books if b.title == book_title), None)\n        if user and book:\n            return self.loans_service.return_book(user, book)\n        return False\n\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/python/santyjl.py",
    "content": "#26 SOLID: PRINCIPIO DE RESPONSABILIDAD ÚNICA (SRP)\n\"\"\"\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n * Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n * manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n * y el procesamiento de préstamos de libros.\n * Requisitos:\n * 1. Registrar libros: El sistema debe permitir agregar nuevos libros con\n * información básica como título, autor y número de copias disponibles.\n * 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n * información básica como nombre, número de identificación y correo electrónico.\n * 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n * tomar prestados y devolver libros.\n * Instrucciones:\n * 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n * los tres aspectos mencionados anteriormente (registro de libros, registro de\n * usuarios y procesamiento de préstamos).\n * 2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n * siguiendo el Principio de Responsabilidad Única.\n */\n\"\"\"\n\nimport os\n\n\n#uso incorrecto\nclass AdministradorDeEmpleados:\n    def __init__(self):\n        self.empleados = []\n\n    def agregar_empleado(self, empleado):\n        self.empleados.append(empleado)\n\n    def eliminar_empleado(self, empleado):\n        self.empleados.remove(empleado)\n\n    def guardar_en_archivo(self, nombre_archivo):\n        with open(nombre_archivo, 'w') as archivo:\n            for empleado in self.empleados:\n                archivo.write(f'{empleado}\\n')\n\n    def cargar_desde_archivo(self, nombre_archivo):\n        with open(nombre_archivo, 'r') as archivo:\n            self.empleados = [linea.strip() for linea in archivo]\n\n#uso correcto\nclass AdministradorDeEmpleados:\n    def __init__(self):\n        self.empleados = []\n\n    def agregar_empleado(self, empleado):\n        self.empleados.append(empleado)\n\n    def eliminar_empleado(self, empleado):\n        self.empleados.remove(empleado)\n\nclass AlmacenamientoDeEmpleadosEnArchivo:\n    def guardar_en_archivo(self, empleados, nombre_archivo):\n        with open(nombre_archivo, 'w') as archivo:\n            for empleado in empleados:\n                archivo.write(f'{empleado}\\n')\n\n    def cargar_desde_archivo(self, nombre_archivo):\n        with open(nombre_archivo, 'r') as archivo:\n            return [linea.strip() for linea in archivo]\n\n# Uso del código\nadministrador = AdministradorDeEmpleados()\nadministrador.agregar_empleado('Juan Perez')\nadministrador.agregar_empleado('Ana Gomez')\n\nalmacenamiento = AlmacenamientoDeEmpleadosEnArchivo()\nalmacenamiento.guardar_en_archivo(administrador.empleados, 'empleados.txt')\nadministrador.empleados = almacenamiento.cargar_desde_archivo('empleados.txt')\nprint(administrador.empleados)\nos.remove('empleados.txt')\n\n\"\"\"\ncada clase solo tiene que cumplir una funcionalidad y no sobrecargar una clase en su lugar hacer\notras clases o funciones aparte para que cada una cumpla una funcion especifica en ves de que una\nclase lo haga o tenga todo\n\"\"\"\n\n#Extra\n\n#No usando SRP\nclass Librery:\n    libros = []\n    usuario = []\n    prestamos = []\n\n    def registrar_libro(self , titulo , autor , copias_disponibles):\n        datos = [titulo , autor , copias_disponibles]\n        info_libro = \"--\".join(datos)\n        self.libros.append(f\"Informacion del libro : {info_libro}\")\n\n    def registrar_usuario(self , nombre , id , correo):\n        datos = [nombre , id , correo]\n        info_usuario = \"==\".join(datos)\n        self.usuario.append(f\"Informacion del usuario : {info_usuario}\")\n\n    def registrar_prestamos(self , usuario , libro):\n        self.formato = f\"el usuario : {usuario} iso un prestamo del libro {libro}\"\n        self.prestamos.append(self.formato)\n\n    def devolver(self , usuario , libro):\n        if self.formato in self.prestamos:\n            print(f\"el usuario {usuario} regreso el libro {libro}\")\n\n        else :\n            print(f\"el usuario {usuario} no ha prestado el libro {libro}\")\n\n#usando SRP\nclass GestionLibros:\n    def __init__(self):\n        self.libros = []\n\n    def registrar_libro(self, titulo, autor, copias_disponibles):\n        datos = [titulo, autor, copias_disponibles]\n        info_libro = \"--\".join(datos)\n        self.libros.append(f\"Información del libro: {info_libro}\")\n\nclass GestionUsuarios:\n    def __init__(self):\n        self.usuarios = []\n\n    def registrar_usuario(self, nombre, id, correo):\n        datos = [nombre, id, correo]\n        info_usuario = \"==\".join(datos)\n        self.usuarios.append(f\"Información del usuario: {info_usuario}\")\n\nclass GestionPrestamos:\n    def __init__(self):\n        self.prestamos = []\n\n    def registrar_prestamo(self, usuario, libro):\n        formato = f\"el usuario: {usuario} hizo un préstamo del libro {libro}\"\n        self.prestamos.append(formato)\n        return formato\n\n    def devolver(self, usuario, libro):\n        formato = f\"el usuario: {usuario} hizo un préstamo del libro {libro}\"\n        if formato in self.prestamos:\n            self.prestamos.remove(formato)\n            print(f\"el usuario {usuario} regresó el libro {libro}\")\n        else:\n            print(f\"el usuario {usuario} no ha prestado el libro {libro}\")\n\n# Crear instancias de las clases\ngestion_libros = GestionLibros()\ngestion_usuarios = GestionUsuarios()\ngestion_prestamos = GestionPrestamos()\n\n# Registrar libros\ngestion_libros.registrar_libro('Cien Años de Soledad', 'Gabriel García Márquez', '5')\ngestion_libros.registrar_libro('Don Quijote', 'Miguel de Cervantes', '3')\n\n# Registrar usuarios\ngestion_usuarios.registrar_usuario('Juan Pérez', '1', 'juan.perez@example.com')\ngestion_usuarios.registrar_usuario('Ana Gómez', '2', 'ana.gomez@example.com')\n\n# Registrar préstamos\nformato_prestamo = gestion_prestamos.registrar_prestamo('Juan Pérez', 'Cien Años de Soledad')\n\n# Devolver libros\ngestion_prestamos.devolver('Juan Pérez', 'Cien Años de Soledad')\ngestion_prestamos.devolver('Ana Gómez', 'Don Quijote')\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/rust/kenysdev.rs",
    "content": "/*\n╔═══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado                ║\n║ GitHub: https://github.com/Kenysdev   ║\n║ 2024 -  Rust                          ║\n╚═══════════════════════════════════════╝\n-----------------------------------------\n* SOLID: PRINCIPIO DE RESPONSABILIDAD ÚNICA (SRP)\n-----------------------------------------\n\n* EJERCICIO:\n* Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n* Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n* de forma correcta e incorrecta.\n*/\n\n// # SIN APLICAR EL PRINCIPIO:\n\npub struct Program {\n    customers: Vec<String>,\n    suppliers: Vec<String>,\n}\n\nimpl Program {\n    pub fn new() -> Self {\n        Program {\n            customers: Vec::new(),\n            suppliers: Vec::new(),\n        }\n    }\n\n    pub fn add_customer(&mut self, name: String) {\n        self.customers.push(name);\n    }\n\n    pub fn add_supplier(&mut self, name: String) {\n        self.suppliers.push(name);\n    }\n\n    pub fn remove_customer(&mut self, name: &str) {\n        self.customers.retain(|x| x != name);\n    }\n\n    pub fn remove_supplier(&mut self, name: &str) {\n        self.suppliers.retain(|x| x != name);\n    }\n}\n\n// _______________________________________\n// APLICANDO SRP:\n\npub struct Customers {\n    customers: Vec<String>,\n}\n\nimpl Customers {\n    pub fn new() -> Self {\n        Customers {\n            customers: Vec::new(),\n        }\n    }\n\n    pub fn add(&mut self, name: String) {\n        self.customers.push(name);\n    }\n\n    pub fn remove(&mut self, name: &str) {\n        self.customers.retain(|x| x != name);\n    }\n}\n\npub struct Suppliers {\n    suppliers: Vec<String>,\n}\n\nimpl Suppliers {\n    pub fn new() -> Self {\n        Suppliers {\n            suppliers: Vec::new(),\n        }\n    }\n\n    pub fn add(&mut self, name: String) {\n        self.suppliers.push(name);\n    }\n\n    pub fn remove(&mut self, name: &str) {\n        self.suppliers.retain(|x| x != name);\n    }\n}\n\n//____________________________________\nfn main() {\n    let mut customers = Customers::new();\n    let mut suppliers = Suppliers::new();\n\n    customers.add(String::from(\"C A\"));\n    customers.add(String::from(\"C B\"));\n\n    suppliers.add(String::from(\"S X\"));\n    suppliers.add(String::from(\"S Y\"));\n\n    println!(\"Clientes: {:?}\", customers.customers);\n    println!(\"Proveedores: {:?}\", suppliers.suppliers);\n\n    customers.remove(\"C A\");\n    suppliers.remove(\"S X\");\n\n    println!(\"Clientes: {:?}\", customers.customers);\n    println!(\"Proveedores: {:?}\", suppliers.suppliers);\n    \n}\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/sql/Nicojsuarez2.sql",
    "content": "# #26 SOLID: PRINCIPIO DE RESPONSABILIDAD ÚNICA (SRP)\n> #### Dificultad: Media | Publicación: 24/06/24 | Corrección: 01/07/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n * Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n * manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n * y el procesamiento de préstamos de libros.\n * Requisitos:\n * 1. Registrar libros: El sistema debe permitir agregar nuevos libros con \n * información básica como título, autor y número de copias disponibles.\n * 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n * información básica como nombre, número de identificación y correo electrónico.\n * 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n * tomar prestados y devolver libros.\n * Instrucciones:\n * 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n * los tres aspectos mencionados anteriormente (registro de libros, registro de\n * usuarios y procesamiento de préstamos).\n * 2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n * siguiendo el Principio de Responsabilidad Única.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/swift/blackriper.swift",
    "content": "import Foundation\n\n/*\n Single Responsability Principle (SRP):\n\nestablece que cada módulo o clase debe tener responsabilidad sobre una sola parte de la funcionalidad\nproporcionada por el software y esta responsabilidad debe estar encapsulada en su totalidad por la clase. \n\nEn programación orientada a objetos, se suele definir como principio de diseño que cada clase debe tener una única responsabilidad, y que esta debe estar contenida únicamente en la clase. Así:\n\nUna clase debería tener solo una razón para cambiar\nCada responsabilidad es el eje del cambio\nPara contener la propagación del cambio, debemos separar las responsabilidades.\nSi una clase asume más de una responsabilidad, será más sensible al cambio.\nSi una clase asume más de una responsabilidad, las responsabilidades se acoplan.\n*/\n\n// forma incorrecta\n class CheckingHours{\n    private var horaries:[String:[[String:String]]] = [\"Monday\":[],\"Tuesday\":[],\"Wednesday\":[],\"Thursday\":[],\"Friday\":[]]\n\n    func registerEmployee(name:String,day:String){\n        horaries[day]?.append([UUID().uuidString:name])\n    }\n\n    func changeDay(day:String,name:String,oldDay:String){\n        horaries[day]?.append([UUID().uuidString:name])\n        horaries[oldDay]?.removeAll(where: {$0.values.contains(name)})\n    }\n\n    func showHorary(){\n        print(\"Horaries Empleoyee\")\n        horaries.forEach { day in\n            print(day.key)\n            print(\"_____________\")\n            day.value.forEach { employee in\n                employee.values.forEach{\n                        print($0)\n                    }            \n        }\n    }\n  }\n}\n\nlet checking = CheckingHours()\nchecking.registerEmployee(name: \"John\", day: \"Monday\")\nchecking.registerEmployee(name: \"blackriper\", day: \"Friday\")\nchecking.showHorary()\nchecking.changeDay(day: \"Monday\", name: \"blackriper\", oldDay: \"Friday\")\nchecking.showHorary()\n\n\n// forma correcta\nstruct Empleoyee{\n        let id:String=UUID().uuidString\n        let name:String \n\n        func getInfo()->String{\n            return \"\\(id) \\(name)\"\n                \n        }\n }\n\n enum Day{\n    case Monday\n    case Tuesday\n    case Wednesday\n    case Thursday\n    case Friday\n }\n\n class ManagerHours{\n      private var hours:[Day:[Empleoyee]] = [.Monday:[],.Tuesday:[],.Wednesday:[],.Thursday:[],.Friday:[]]\n\n      func registerEmployee(emp:Empleoyee,day:Day){\n          hours[day]?.append(emp)\n      }\n\n      func changeDay(empleoyee:Empleoyee,day:Day,oldDay:Day){\n          hours[day]?.append(empleoyee)\n          hours[oldDay]?.removeAll(where: {$0.id == empleoyee.id})\n      }\n\n\n      func showHorary(){\n          hours.forEach { day in\n              print(day.key)\n              print(\"_____________\")\n              day.value.forEach { employee in\n                  print(employee.getInfo())\n              }\n          }\n      }\n }\n\nlet checkSRP = ManagerHours()\nlet emp1=Empleoyee(name: \"John\")\nlet emp2=Empleoyee(name: \"blackriper\")\n\ncheckSRP.registerEmployee(emp: emp1, day: .Monday)\ncheckSRP.registerEmployee(emp: emp2, day: .Friday)\nprint(\"Horaries Empleoyee 1\")\ncheckSRP.showHorary()\ncheckSRP.changeDay(empleoyee: emp2, day: .Tuesday, oldDay: .Friday)\nprint(\"Horaries Empleoyee 2\")\ncheckSRP.showHorary()\n\n// ejercicio extra\n\n//generar fechas \nfunc generateDate()->String{\n let format=DateFormatter()\n format.dateFormat=\"dd/MM/yyyy\"\n let date=Date()\n return  format.string(from: date)\n }\n\n\n\nstruct Book{\n    let title:String\n    let author:String\n    var numCopies:Int\n\n}\n\n\nstruct User{\n    let userId:String=UUID().uuidString.substring(to: 8)\n    let name:String\n    let email:String\n }\n\nstruct Loan{\n   let id:String=UUID().uuidString.substring(to: 8)\n   let dateLoan:String=generateDate()\n   let nameUser:String\n   let numUser:String\n   let titleBooks:[String]\n }\n\nclass Library{\n    private var books:[Book] = []\n    private var users:[User] = []\n    private var loans:[Loan] = []\n\n    private func registerBook(){\n        print(\"Enter book title\")\n        let title=readLine()!\n        print(\"Enter book author\")\n        let author=readLine()!\n        print(\"Enter number of copies\")\n        let numCopies=readLine() ?? \"1\"\n        let book=Book(title: title, author: author, numCopies: Int(numCopies) ?? 1)\n        books.append(book)\n    }\n\n   private  func registerUser(){\n        print(\"Enter user name\")\n        let name=readLine()!\n        print(\"Enter user email\")\n        let email=readLine()!\n        let user=User(name: name, email: email)\n        users.append(user)\n    }\n\n\n   private func registerLoan(){\n\n        var titlesBooks:[String] = []\n        var option:String=\"\"\n\n        print(\"Enter username or  userId\")\n        let input=readLine()!\n        guard let user=users.first(where: {$0.name == input || $0.userId == input}) else{\n            print(\"User not found\")\n            return\n        }\n        while option != \"n\"{\n        var idx=1             \n        books.forEach{ book in \n            print(\"\\(idx)   \\(book.title)\")\n            idx+=1\n        }\n        print(\"Enter book number\")\n        let inputBook=Int(readLine()!) ?? 0\n        var book=books[inputBook-1] \n\n          titlesBooks.append(book.title)\n          book.numCopies-=1\n          print(\"Do you want to add another book? (y/n)\")\n          option=readLine() ?? \"n\"\n        }\n\n        let loan=Loan(nameUser: user.name, numUser: user.userId, titleBooks: titlesBooks)\n        loans.append(loan)\n\n    }\n\n   private func returnigBooks(){\n        print(\"Enter username or  userId\")\n        let input=readLine()!\n        guard let user=users.first(where: {$0.name == input || $0.userId == input}) else{\n            print(\"User not found\")\n            return\n        }\n\n        guard let loan=loans.first(where: {$0.nameUser == user.name}) else{\n            print(\"Loan not found\")\n            return\n        }\n\n        loan.titleBooks.forEach{ (title) in\n            guard var book=books.first(where: {$0.title == title}) else{\n                print(\"Book not found\")\n                return\n            }\n            book.numCopies+=1\n        }\n        loans.removeAll(where: {$0.id == loan.id})\n        print(\"Loans \\(loan.id) returned successfully\")\n    \n    }\n\n    func showMenu(){\n        var option:Int = 0 \n        while option != 5{\n             print(\"Library Menu\")\n             print(\"_________________\")\n             print(\"1. Register book\")\n             print(\"2. Register user\")\n             print(\"3. Register loan\")\n             print(\"4. Returnig books\")\n             print(\"5. Exit\")\n\n             print(\"Enter option\")\n             option=Int(readLine() ?? \"5\") ?? 5\n             if option == 1{\n                registerBook()\n             }else if option == 2{\n                registerUser()\n             }else if option == 3{\n                registerLoan()\n             }else if option == 4{\n                returnigBooks()\n             }\n\n        }\n    }\n\n}\n\n//let library=Library()\n//library.showMenu()\n\n// aplicando el principio de responsabilidad unica\n\n//1.- Creamos un mock de pruebas  opcional\nvar books: [Book] = [\n    Book(title: \"El Señor de los Anillos\", author: \"J.R.R. Tolkien\", numCopies: 10),\n    Book(title: \"Cien Años de Soledad\", author: \"Gabriel García Márquez\", numCopies: 15),\n    Book(title: \"One Piece\", author: \"Eiichiro Oda\", numCopies: 20), \n    Book(title: \"Dragon Ball\", author: \"Akira Toriyama\", numCopies: 30),\n    Book(title: \"Fundación\", author: \"Isaac Asimov\", numCopies: 5)\n]\n\nvar users: [User] = [\n    User(name: \"John\", email: \"pNzJG@example.com\"),\n    User(name: \"blackriper\", email: \"pNzJG@example.com\")\n]\n\n//2.- delegar responsabilidades a las estructuras  de datos y controlar comportamientos con protocols\n \nprotocol ForBooks{\n   func insertBooks()\n   func showAllBooks()\n   func findBook(filter:(Book) ->Bool)->Book\n   func findBookByIndex(index:Int)->Book\n}\n\nprotocol ForUsers{\n   func insertUsers() \n   func findUser(value:String)->User\n }\n\nprotocol ForLoans{\n   func insertLoans(nameUser:String,numUser:String,titleBooks:[String]) \n   func showLoans()\n   func findLoan(filter:(Loan) ->Bool)->Loan\n   func deleteLoan(idLoan:String)\n  }\n\n\n  class BookRepository:ForBooks{\n   \n    func insertBooks() {\n        print(\"Enter book title\")\n        let title=readLine()!\n        print(\"Enter book author\")\n        let author=readLine()!\n        print(\"Enter number of copies\")\n        let numCopies=readLine() ?? \"1\"\n        let book=Book(title: title, author: author, numCopies: Int(numCopies) ?? 1)\n        books.append(book) \n   }\n\n    func showAllBooks() {\n        var idx=1\n        books.forEach{ book in \n            print(\"ID:\\(idx) Title: \\(book.title) Author: \\(book.author) Copies: \\(book.numCopies)\")\n            idx+=1\n        }\n   }\n\n    func findBook(filter: (Book) -> Bool) -> Book {\n           guard let book=books.first(where: filter ) else{\n            print(\"Book not found\")\n            return Book(title: \"\", author: \"\", numCopies: 0)\n        }\n         return book\n   }\n\n    func findBookByIndex(index: Int) -> Book {\n       return books[index-1]\n   }\n }\n\n\n class UserRepository:ForUsers{\n     \n       func insertUsers() {\n        print(\"Enter user name\")\n        let name=readLine()!\n        print(\"Enter user email\")\n        let email=readLine()!\n        let user=User(name: name, email: email)\n        users.append(user)\n        print(\"User with id \\(user.userId) created successfully\")\n        \n     }\n\n      func findUser(value:String )-> User {\n       guard let user = users.first(where: {$0.name == value || $0.userId == value}) else{\n           print(\"User not found\")\n           return User(name: \"\", email: \"\")\n       }\n       return user\n     }\n }\n\n class LoanRepository:ForLoans{\n    private var loans:[Loan] = []\n\n    func insertLoans(nameUser: String, numUser: String, titleBooks: [String]) {\n      let loan=Loan(nameUser: nameUser, numUser:numUser, titleBooks: titleBooks)\n      loans.append(loan) \n    }\n\n    func showLoans() {\n        loans.forEach{ loan in\n            print(\"ID: \\(loan.id) Date: \\(loan.dateLoan) User: \\(loan.nameUser) Books: \\(loan.titleBooks)\")\n        }\n    }\n\n    func findLoan(filter: (Loan)  -> Bool) -> Loan {\n        guard let loan=loans.first(where: filter ) else{\n           print(\"Loan not found\")\n           return Loan(nameUser: \"\", numUser: \"\", titleBooks: [])\n       }\n        return loan\n    }\n\n     func deleteLoan(idLoan: String) {\n        loans.removeAll(where: {$0.id == idLoan})\n    }\n\n }\n\n class SRPLibrary{\n    private var bookRepository=BookRepository()\n    private var userRepository=UserRepository()\n    private var loanRepository=LoanRepository()\n\n   private func lendBooks(){\n        var titlesBooks:[String] = []\n        var option:String=\"\"\n\n        print(\"Enter username or  userId\")\n        let input=readLine()!\n        let user = userRepository.findUser(value: input)\n        if user.name == \"\"{\n            return\n         }\n        \n         while option != \"n\"{\n            bookRepository.showAllBooks()\n            print(\"Enter book number\")\n            let inputBook=Int(readLine()!) ?? 0\n            var book=bookRepository.findBookByIndex(index: inputBook)\n            titlesBooks.append(book.title)\n            book.numCopies-=1\n            books[inputBook-1]=book\n\n            print(\"Do you want to add another book? (y/n)\")\n            option=readLine() ?? \"n\"\n        }\n        loanRepository.insertLoans(nameUser: user.name, numUser: user.userId, titleBooks: titlesBooks)\n    }\n\n   private  func returnigBooks(){\n        print(\"Enter username or  userId\")\n        let input=readLine()!\n        let loan=loanRepository.findLoan(filter: {$0.nameUser == input || $0.numUser == input})\n        if loan.nameUser == \"\"{\n            return\n        }\n        retryBooks(titleBooks: loan.titleBooks)\n        loanRepository.deleteLoan(idLoan: loan.id)\n        print(\"Loans \\(loan.id) returned successfully\")\n\n     }\n\n     func showMenu(){\n        var option:Int = 0 \n        while option != 6{\n             print(\"Library Menu\")\n             print(\"_________________\")\n             print(\"1. Register book\")\n             print(\"2. Register user\")\n             print(\"3. Register loan\")\n             print(\"4. Show loans\")\n             print(\"5. Returnig books\")\n             print(\"6. Exit\")\n\n             print(\"Enter option\")\n             option=Int(readLine() ?? \"6\") ?? 6\n             switch option {\n             case 1:\n                bookRepository.insertBooks()\n             case 2:\n                userRepository.insertUsers()\n             case 3:\n                lendBooks()\n             case 4:\n                loanRepository.showLoans()\n             case 5:\n                returnigBooks()\n             default:\n                break\n             }\n        }\n    }\n\n   private func retryBooks(titleBooks :[String]){\n       Task{\n         titleBooks.forEach{ (title) in\n            var book=bookRepository.findBook(filter: {$0.title == title})\n             book.numCopies+=1\n      }\n    }\n  }\n }\n\n let library=SRPLibrary()\n library.showMenu()\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/typescript/Sac-Corts.ts",
    "content": "// Invalid way\nclass User {\n    name: string;\n    email: string;\n\n    constructor(name: string, email: string) {\n        this.name = name;\n        this.email = email;\n    }\n\n    getUserInfo(): { name: string; email: string } {\n        return {\n            name: this.name,\n            email: this.email\n        };\n    }\n\n    formatUserInfo(): string {\n        return `Name: ${this.name}, Email: ${this.email}`;\n    }\n}\n\nconst user = new User('Isaac Morales', 'isaac@gmail.com');\nconsole.log(user.formatUserInfo());\n\n// Correct way\nclass UserInfo {\n    name: string;\n    email: string;\n\n    constructor(name: string, email: string) {\n        this.name = name;\n        this.email = email;\n    }\n\n    getUserInfo(): { name: string; email: string } {\n        return {\n            name: this.name,\n            email: this.email\n        };\n    }\n}\n\nclass FormatUser {\n    static format(user: UserInfo): string {\n        return `Name: ${user.name}, Email: ${user.email}`;\n    }\n}\n\nconst newUser = new UserInfo('Isaac Cortés', 'isaac@gmail.com');\nconsole.log(FormatUser.format(newUser));\n\n// ** Extra Exercise ** //\ninterface Book {\n    title: string;\n    author: string;\n    copies: number;\n}\n\nclass BookManager {\n    private books: Book[];\n\n    constructor() {\n        this.books = [];\n    }\n\n    addBook(title: string, author: string, copies: number): void {\n        this.books.push({ title, author, copies });\n    }\n\n    findBook(title: string): Book | undefined {\n        return this.books.find(book => book.title === title);\n    }\n}\n\ninterface UserDetails {\n    name: string;\n    id: number;\n    email: string;\n}\n\nclass UserManager {\n    private users: UserDetails[];\n\n    constructor() {\n        this.users = [];\n    }\n\n    addUser(name: string, id: number, email: string): void {\n        this.users.push({ name, id, email });\n    }\n\n    findUser(id: number): UserDetails | undefined {\n        return this.users.find(user => user.id === id);\n    }\n}\n\nclass LoanManager {\n    private bookManager: BookManager;\n    private userManager: UserManager;\n    private loans: { userId: number; bookTitle: string }[];\n\n    constructor(bookManager: BookManager, userManager: UserManager) {\n        this.bookManager = bookManager;\n        this.userManager = userManager;    \n        this.loans = [];\n    }\n\n    borrowBook(userId: number, bookTitle: string): void {\n        const user = this.userManager.findUser(userId);\n        const book = this.bookManager.findBook(bookTitle);\n\n        if (user && book && book.copies > 0) {\n            book.copies--;\n            this.loans.push({ userId, bookTitle });\n            console.log(`${user.name} borrowed \"${book.title}\"`);\n        } else {\n            console.log(`Book is unavailable or user not found`);\n        }\n    }\n\n    returnBook(userId: number, bookTitle: string): void {\n        const loanIndex = this.loans.findIndex(\n            loan => loan.userId === userId && loan.bookTitle === bookTitle\n        );\n        const book = this.bookManager.findBook(bookTitle);\n\n        if (loanIndex !== -1 && book) {\n            book.copies++;\n            this.loans.splice(loanIndex, 1);\n            console.log(`\"${book.title}\" has been returned`);\n        } else {\n            console.log('Loan not found or book not available');\n        }\n    }\n}\n\nconst bookManager = new BookManager();\nconst userManager = new UserManager();\nconst loanManager = new LoanManager(bookManager, userManager);\n\nbookManager.addBook('The Great Gatsby', 'F. Scott Fitzgerald', 5);\nuserManager.addUser('Isaac', 1, 'isaac@gmail.com');\n\nloanManager.borrowBook(1, 'The Great Gatsby');\nloanManager.returnBook(1, 'The Great Gatsby');\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/typescript/duendeintemporal.ts",
    "content": "//#26 { retosparaprogramadores } - Principio SOLID de Responsabilidad Única (Single Responsibility Principle, SRP)\n//Bibliografy: The Web Development Glossary (Jens Oliver Meiert) (Z-Library)\n//GPT & Deepseek\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n * Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla un sistema de gestión para una biblioteca. El sistema necesita\n * manejar diferentes aspectos como el registro de libros, la gestión de usuarios\n * y el procesamiento de préstamos de libros.\n * Requisitos:\n * 1. Registrar libros: El sistema debe permitir agregar nuevos libros con\n * información básica como título, autor y número de copias disponibles.\n * 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con\n * información básica como nombre, número de identificación y correo electrónico.\n * 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios\n * tomar prestados y devolver libros.\n * Instrucciones:\n * 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje\n * los tres aspectos mencionados anteriormente (registro de libros, registro de\n * usuarios y procesamiento de préstamos).\n * 2. Refactoriza el código: Separa las responsabilidades en diferentes clases\n * siguiendo el Principio de Responsabilidad Única.\n */\n\n\n/*  Single Responsibility Principle\nA computer programming principle that states that every module, class, or\nfunction should have responsibility over a single part of the functionality\nprovided by the software, and that responsibility should be entirely\nencapsulated by the module, class, or function. All its services should be\nnarrowly aligned with that responsibility.  */\n\n//Not Following the Single Responsibility Principle (SRP)\n\nlet log = console.log;\n\n// Conditional check for browser environment\nif (typeof window !== 'undefined') {\n    window.addEventListener('load', () => {\n        const body: HTMLBodyElement | null = document.querySelector('body');\n        const title = document.createElement('h1');\n\n        body?.style.setProperty('background', '#000');\n        body?.style.setProperty('text-align', 'center');\n\n        title.textContent = 'Retosparaprogramadores #26.';\n        title.style.setProperty('font-size', '3.5vmax');\n        title.style.setProperty('color', '#fff');\n        title.style.setProperty('line-height', '100vh');\n\n        body?.appendChild(title);\n\n        setTimeout(() => {\n            alert('Retosparaprogramadores #26. Please open the Browser Developer Tools.');\n        }, 2000);\n        log('Retosparaprogramadores #26');\n    });\n} else {\n    log('This code is designed to run in a browser environment. Skipping window-related code.');\n    log('Retosparaprogramadores #26');\n}\n\ninterface IBook {\n    title: string;\n    author: string;\n    copies: number;\n}\n\ninterface IUser {\n    name: string;\n    id: string;\n    email: string;\n}\n\ninterface ILoan {\n    loanId: number;\n    userId: string;\n    bookTitle: string;\n}\n\nclass Library {\n    private books: IBook[];\n    private users: IUser[];\n    private loans: ILoan[];\n\n    constructor() {\n        this.books = [];\n        this.users = [];\n        this.loans = [];\n    }\n\n    addBook(title: string, author: string, copies: number): void {\n        this.books.push({ title, author, copies });\n    }\n\n    registerUser(name: string, id: string, email: string): void {\n        this.users.push({ name, id, email });\n    }\n\n    loanBook(userId: string, bookTitle: string): void {\n        const user = this.users.find(u => u.id === userId);\n        const book = this.books.find(b => b.title === bookTitle);\n\n        if (user && book && book.copies > 0) {\n            const loanId = this.loans.length + 1; // Generate a new loan ID\n            this.loans.push({ loanId, userId, bookTitle });\n            book.copies--;\n            log(`Book \"${bookTitle}\" loaned to ${user.name}`);\n        } else {\n            log(\"Loan failed: User or book not found, or no copies available.\");\n        }\n    }\n}\n\nconst library = new Library();\nlibrary.addBook(\"Learn Bash the Hard Way\", \"Ian Miell\", 2);\nlibrary.addBook(\"MATLAB Notes for Professionals\", \"GoalKicker.com\", 4);\nlibrary.registerUser(\"Royer Rabit\", \"006\", \"happyrabbit@proton.me\");\nlibrary.loanBook(\"006\", \"MATLAB Notes for Professionals\"); // Book \"MATLAB Notes for Professionals\" loaned to Royer Rabit\n\n// Extra difficulty exercise\n// Following the Single Responsibility Principle (SRP)\n\nclass Book {\n    title: string;\n    author: string;\n    copies: number;\n\n    constructor(title: string, author: string, copies: number) {\n        this.title = title;\n        this.author = author;\n        this.copies = copies;\n    }\n}\n\nclass User {\n    name: string;\n    id: string;\n    email: string;\n\n    constructor(name: string, id: string, email: string) {\n        this.name = name;\n        this.id = id;\n        this.email = email;\n    }\n}\n\nclass BookManager {\n    private books: Book[];\n\n    constructor() {\n        this.books = [];\n    }\n\n    addBook(title: string, author: string, copies: number): void {\n        this.books.push(new Book(title, author, copies));\n    }\n\n    getBooks(): Book[] {\n        return this.books; \n    }\n\n    findBook(title: string): Book | undefined {\n        return this.books.find(b => b.title === title);\n    }\n\n    increaseCopies(bookTitle: string): void {\n        const book = this.findBook(bookTitle);\n        if (book) {\n            book.copies++;\n        }\n    }\n}\n\nfunction searchBooksByPartialTitle(books: Book[], searchTerm: string): Book[] {\n    return books.filter(book => \n        book.title.toLowerCase().includes(searchTerm.toLowerCase())\n    );\n}\n\nclass UserManager {\n    private users: User[];\n\n    constructor() {\n        this.users = [];\n    }\n\n    registerUser(name: string, id: string, email: string): void {\n        this.users.push(new User(name, id, email));\n    }\n\n    findUser(id: string): User | undefined {\n        return this.users.find(u => u.id === id);\n    }\n}\n\nclass LoanManager {\n    private loans: ILoan[];\n    private nextLoanId: number;\n\n    constructor() {\n        this.loans = [];\n        this.nextLoanId = 1;\n    }\n\n    loanBook(user: User, book: Book): void {\n        if (book.copies > 0) {\n            const loanId = this.nextLoanId++; // Use the nextLoanId for the new loan\n            this.loans.push({ loanId, userId: user.id, bookTitle: book.title });\n            book.copies--;\n            log(`Book \"${book.title}\" loaned to ${user.name} with Loan ID: ${loanId}`);\n        } else {\n            log(\"Loan failed: No copies available.\");\n        }\n    }\n\n    returnBook(loanId: number, bookManager: BookManager): void {\n        const loanIndex: number = this.loans.findIndex(loan => loan.loanId === loanId);\n\n        if (loanIndex !== -1) {\n            const loan = this.loans[loanIndex];\n            const book = bookManager.findBook(loan.bookTitle);\n            if (book) {\n                book.copies++;\n            }\n\n            // Remove the loan from the loans array\n            this.loans.splice(loanIndex, 1);\n            log(`Book \"${loan.bookTitle}\" returned with Loan ID: ${loanId}`);\n        } else {\n            log(\"Return failed: No loan record found for this Loan ID.\");\n        }\n    }\n\n    getLoansByPartialBookTitle(searchTerm: string, userId: string): ILoan[] {\n        return this.loans.filter(loan => \n            loan.bookTitle.toLowerCase().includes(searchTerm.toLowerCase()) && loan.userId === userId\n        );\n    }\n}\n\n// Example usage of the BookManager, UserManager, and LoanManager classes\nconst bookManager = new BookManager();\nconst userManager = new UserManager();\nconst loanManager = new LoanManager();\n\nbookManager.addBook(\"300 JavaScript Interview Mastery Questions Dive Deep into JavaScript Theory, Syntax, and APIs, and Interview with Confidence\", \"Middaugh, Jonathan\", 3);\nbookManager.addBook(\"Javascript Interview Questions and Answers\", \"Bandal, Pratik\", 7);\nbookManager.addBook(\"100 MOST ASKED JOB READY QUESTIONS ANSWERS IN THE TECH SPACE Here are the most asked questions in PYTHON, SQL, JAVASCRIPT...\", \"Aimee Mills\", 2);\nuserManager.registerUser(\"Niko Zen\", \"008\", \"duendeintemporal@hotmail.com\");\n\nconst searchTerm1 = \"JavaScript\";\nconst searchTerm2 = \"Interview Questions\";\n\nconst searchResults1 = searchBooksByPartialTitle(bookManager.getBooks(), searchTerm1);\nconst searchResults2 = searchBooksByPartialTitle(bookManager.getBooks(), searchTerm2);\n\nlog(searchResults1); \n/*\n Book {\n    title: '300 JavaScript Interview Mastery Questions Dive Deep into JavaScript Theory, Syntax, and APIs, and Interview with Confidence',\n    author: 'Middaugh, Jonathan',\n    copies: 3\n  },\n  Book {\n    title: 'Javascript Interview Questions and Answers',\n    author: 'Bandal, Pratik',\n    copies: 7\n  },\n  Book {\n    title: '100 MOST ASKED JOB READY QUESTIONS ANSWERS IN THE TECH SPACE Here are the most asked questions in PYTHON, SQL, JAVASCRIPT...',\n    author: 'Aimee Mills',\n    copies: 2\n  }\n]\n*/\nlog(searchResults2); \n/* [\n  Book {\n    title: 'Javascript Interview Questions and Answers',\n    author: 'Bandal, Pratik',\n    copies: 7\n  }\n] */\n\nconst user = userManager.findUser(\"008\");\nconst bookTitle = searchResults1[2]?.title; \nconst book = bookManager.findBook(bookTitle); \n\nif (user && book) { // Ensure user is defined before proceeding\n    loanManager.loanBook(user, book); // Book \"100 MOST ASKED JOB READY QUESTIONS ANSWERS IN THE TECH SPACE Here are the most asked questions in PYTHON, SQL, JAVASCRIPT...\" loaned to Niko Zen with Loan ID: 1\n    const loans = loanManager.getLoansByPartialBookTitle(book.title, user.id);\n    if (loans.length > 0) {\n        loanManager.returnBook(loans[0].loanId, bookManager); // Book \"100 MOST ASKED JOB READY QUESTIONS ANSWERS IN THE TECH SPACE Here are the most asked questions in PYTHON, SQL, JAVASCRIPT...\" returned with Loan ID: 1\n    } else {\n        log(\"No loans found for this book.\");\n    }\n} else {\n    log(\"User or book not found for loan.\");\n}\n\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/typescript/eulogioep.ts",
    "content": "/**\n * PRINCIPIO DE RESPONSABILIDAD ÚNICA (SRP)\n * \n * El Principio de Responsabilidad Única es el primer principio de SOLID y establece que:\n * \"Una clase debe tener una única razón para cambiar\"\n * \n * Esto significa que una clase debe tener una sola responsabilidad o tarea principal.\n * Los beneficios de aplicar SRP incluyen:\n * - Código más mantenible y fácil de entender\n * - Mejor testabilidad\n * - Menor acoplamiento\n * - Facilita la reutilización de código\n */\n\n// ========== IMPLEMENTACIÓN INCORRECTA (Violando SRP) ==========\n\n/**\n * Esta implementación viola el SRP porque la clase Library tiene múltiples responsabilidades:\n * 1. Gestionar libros\n * 2. Gestionar usuarios\n * 3. Gestionar préstamos\n */\nclass Library {\n    private books: Book[] = [];\n    private users: User[] = [];\n    private loans: Loan[] = [];\n\n    // Gestión de libros\n    public addBook(title: string, author: string, copies: number): void {\n        const book = new Book(title, author, copies);\n        this.books.push(book);\n    }\n\n    public removeBook(bookId: string): void {\n        this.books = this.books.filter(book => book.id !== bookId);\n    }\n\n    // Gestión de usuarios\n    public registerUser(name: string, id: string, email: string): void {\n        const user = new User(name, id, email);\n        this.users.push(user);\n    }\n\n    public removeUser(userId: string): void {\n        this.users = this.users.filter(user => user.id !== userId);\n    }\n\n    // Gestión de préstamos\n    public loanBook(userId: string, bookId: string): void {\n        const book = this.books.find(b => b.id === bookId);\n        const user = this.users.find(u => u.id === userId);\n\n        if (!book || !user) throw new Error(\"Libro o usuario no encontrado\");\n        if (book.availableCopies <= 0) throw new Error(\"No hay copias disponibles\");\n\n        book.availableCopies--;\n        this.loans.push(new Loan(user.id, book.id, new Date()));\n    }\n\n    public returnBook(userId: string, bookId: string): void {\n        const loan = this.loans.find(l => l.userId === userId && l.bookId === bookId);\n        if (!loan) throw new Error(\"Préstamo no encontrado\");\n\n        const book = this.books.find(b => b.id === bookId);\n        if (book) book.availableCopies++;\n\n        this.loans = this.loans.filter(l => l !== loan);\n    }\n}\n\n// ========== IMPLEMENTACIÓN CORRECTA (Siguiendo SRP) ==========\n\n/**\n * BookManager: Responsable únicamente de la gestión de libros\n */\nclass BookManager {\n    private books: Book[] = [];\n\n    public addBook(title: string, author: string, copies: number): void {\n        const book = new Book(title, author, copies);\n        this.books.push(book);\n    }\n\n    public removeBook(bookId: string): void {\n        this.books = this.books.filter(book => book.id !== bookId);\n    }\n\n    public getBook(bookId: string): Book | undefined {\n        return this.books.find(book => book.id === bookId);\n    }\n\n    public updateBookCopies(bookId: string, change: number): void {\n        const book = this.getBook(bookId);\n        if (book) {\n            book.availableCopies += change;\n        }\n    }\n}\n\n/**\n * UserManager: Responsable únicamente de la gestión de usuarios\n */\nclass UserManager {\n    private users: User[] = [];\n\n    public registerUser(name: string, id: string, email: string): void {\n        const user = new User(name, id, email);\n        this.users.push(user);\n    }\n\n    public removeUser(userId: string): void {\n        this.users = this.users.filter(user => user.id !== userId);\n    }\n\n    public getUser(userId: string): User | undefined {\n        return this.users.find(user => user.id === userId);\n    }\n}\n\n/**\n * LoanManager: Responsable únicamente de la gestión de préstamos\n */\nclass LoanManager {\n    private loans: Loan[] = [];\n\n    constructor(\n        private bookManager: BookManager,\n        private userManager: UserManager\n    ) {}\n\n    public loanBook(userId: string, bookId: string): void {\n        const book = this.bookManager.getBook(bookId);\n        const user = this.userManager.getUser(userId);\n\n        if (!book || !user) throw new Error(\"Libro o usuario no encontrado\");\n        if (book.availableCopies <= 0) throw new Error(\"No hay copias disponibles\");\n\n        this.bookManager.updateBookCopies(bookId, -1);\n        this.loans.push(new Loan(user.id, book.id, new Date()));\n    }\n\n    public returnBook(userId: string, bookId: string): void {\n        const loan = this.loans.find(l => l.userId === userId && l.bookId === bookId);\n        if (!loan) throw new Error(\"Préstamo no encontrado\");\n\n        this.bookManager.updateBookCopies(bookId, 1);\n        this.loans = this.loans.filter(l => l !== loan);\n    }\n}\n\n// Clases de modelo\nclass Book {\n    public id: string;\n    constructor(\n        public title: string,\n        public author: string,\n        public availableCopies: number\n    ) {\n        this.id = Math.random().toString(36).substr(2, 9);\n    }\n}\n\nclass User {\n    constructor(\n        public name: string,\n        public id: string,\n        public email: string\n    ) {}\n}\n\nclass Loan {\n    constructor(\n        public userId: string,\n        public bookId: string,\n        public loanDate: Date\n    ) {}\n}\n\n// Ejemplo de uso del sistema refactorizado\nconst bookManager = new BookManager();\nconst userManager = new UserManager();\nconst loanManager = new LoanManager(bookManager, userManager);\n\n// Registrar un libro\nbookManager.addBook(\"El Quijote\", \"Miguel de Cervantes\", 5);\n\n// Registrar un usuario\nuserManager.registerUser(\"Juan Pérez\", \"USER001\", \"juan@email.com\");\n\n// Realizar un préstamo\nloanManager.loanBook(\"USER001\", \"BOOK001\");"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/typescript/hozlucas28.ts",
    "content": "/*\n    Single Responsibility Principle (SRP)...\n*/\n\nconsole.log('Single Responsibility Principle (SRP)...')\n\nconsole.log('\\nBad implementation of Single Responsibility Principle (SRP)...')\n\ninterface User {\n    email: string\n    firstName: string\n    lastName: string\n}\n\ninterface IBadUser extends User {\n    saveUser(): this\n}\n\nclass BadUser implements IBadUser {\n    email: string\n    firstName: string\n    lastName: string\n\n    constructor({email, firstName, lastName}: User) {\n        this.email = email\n        this.firstName = firstName\n        this.lastName = lastName\n    }\n\n    saveUser(): this {\n        console.log('User saved!')\n        return this\n    }\n}\n\nconsole.log(`\\n\\`\\`\\`\\ninterface User {\n    email: string\n    firstName: string\n    lastName: string\n}\n\ninterface IBadUser extends User {\n    saveUser(): this\n}\n\nclass BadUser implements IBadUser {\n    email: string\n    firstName: string\n    lastName: string\n\n    constructor({email, firstName, lastName}: User) {\n        this.email = email\n        this.firstName = firstName\n        this.lastName = lastName\n    }\n\n    saveUser(): this {\n        console.log('User saved!')\n        return this\n    }\n}\\n\\`\\`\\``)\n\nconsole.log(\n    '\\nThis is a bad implementation of Single Responsibility Principle (SRP), \\n' +\n        'because the class \"BadUser\" has two responsibilities:\\n\\n' +\n        '1°) User creation.\\n' +\n        '2°) Data persistence of the user.'\n)\n\nconsole.log('\\nGood implementation of Single Responsibility Principle (SRP)...')\n\ninterface IGoodUser extends User {}\n\nclass GoodUser implements IGoodUser {\n    email: string\n    firstName: string\n    lastName: string\n\n    constructor({email, firstName, lastName}: User) {\n        this.email = email\n        this.firstName = firstName\n        this.lastName = lastName\n    }\n}\n\ninterface IGoodUserDatabase {\n    user: GoodUser\n    saveUser(): this\n}\n\nclass GoodUserDatabase implements IGoodUserDatabase {\n    user: GoodUser\n\n    constructor(user: GoodUser) {\n        this.user = user\n    }\n\n    saveUser(): this {\n        console.log('User saved!')\n        return this\n    }\n}\n\nconsole.log(`\\n\\`\\`\\`\\ninterface IGoodUser extends User {}\n\nclass GoodUser implements IGoodUser {\n    email: string\n    firstName: string\n    lastName: string\n\n    constructor({email, firstName, lastName}: User) {\n        this.email = email\n        this.firstName = firstName\n        this.lastName = lastName\n    }\n}\n\ninterface IGoodUserDatabase {\n    user: GoodUser\n    saveUser(): this\n}\n\nclass GoodUserDatabase implements IGoodUserDatabase {\n    user: GoodUser\n\n    constructor(user: GoodUser) {\n        this.user = user\n    }\n\n    saveUser(): this {\n        console.log('User saved!')\n        return this\n    }\n}\\n\\`\\`\\``)\n\nconsole.log(\n    '\\nThis is a good implementation of Single Responsibility Principle (SRP), \\n' +\n        'because the class \"GoodUser\" has only one responsability and \\n' +\n        'the class \"GoodUserDatabase\" too.'\n)\n"
  },
  {
    "path": "Roadmap/26 - SOLID SRP/vb.net/kenysdev.vb",
    "content": "' ╔══════════════════════════════════════╗\n' ║ Autor:  Kenys Alvarado               ║\n' ║ GitHub: https://github.com/Kenysdev  ║\n' ║ 2024 -  VB.NET                       ║\n' ╚══════════════════════════════════════╝\n'-----------------------------------------------\n'* SOLID: PRINCIPIO DE RESPONSABILIDAD ÚNICA (SRP)\n'-----------------------------------------------\n'# Se centra en la claridad, la cohesión y la separación de intereses.\n'# Cada clase debe tener una única razón para cambiar.\n'# Los metodos de una clase deben estar estrechamente relacionadas.\n\n'_______________________________________________\n'* EJERCICIO\n'* Explora el \"Principio SOLID de Responsabilidad Única (Single Responsibility\n'* Principle, SRP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n'* de forma correcta e incorrecta.\n\n'__________________________\n' SIN APLICAR EL PRINCIPIO:\nPublic Class NoSRP\n    Private ReadOnly customers As New List(Of String)()\n    Private ReadOnly suppliers As New List(Of String)()\n\n    Public Sub AddCustomer(name As String)\n        customers.Add(name)\n    End Sub\n\n    Public Sub AddSupplier(name As String)\n        suppliers.Add(name)\n    End Sub\n\n    Public Sub RemoveCustomer(name As String)\n        customers.Remove(name)\n    End Sub\n\n    Public Sub RemoveSupplier(name As String)\n        suppliers.Remove(name)\n    End Sub\nEnd Class\n\n'__________________________\n' APLICANDO SRP:\nPublic Class Customers\n    Private ReadOnly customers As New List(Of String)()\n\n    Public Sub Add(name As String)\n        customers.Add(name)\n    End Sub\n\n    Public Sub Remove(name As String)\n        customers.Remove(name)\n    End Sub\nEnd Class\n\nPublic Class Suppliers\n    Private ReadOnly suppliers As New List(Of String)()\n\n    Public Sub Add(name As String)\n        suppliers.Add(name)\n    End Sub\n\n    Public Sub Remove(name As String)\n        suppliers.Remove(name)\n    End Sub\nEnd Class\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/bash/rantamhack.sh",
    "content": "#!/bin/bash\n\necho -e \"\\n\\n=======================================EJERCICIO=======================================\\n\\n\"\n# * EJERCICIO:\n# * Explora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\" \n# * y crea un ejemplo simple donde se muestre su funcionamiento\n# * de forma correcta e incorrecta.\n\nfunction triangle(){\n    local base=$1\n    local height=$2\n    echo -e \"scale=2; ($base * $height) / 2\" | bc\n}\n\n\nfunction square(){\n    local side=\"$1\"\n    echo -e \"scale=2; $side ^ 2\" | bc\n}\n\n\nfunction rectangle(){\n    local base=\"$1\"\n    local height=\"$2\"\n    echo -e \"scale=2; $base * $height\" | bc\n}\n        \n\nfunction calculate_area(){\n    local shape=$1\n    shift\n    case $shape in\n        triangle)\n            triangle \"$@\"\n            ;;\n        square)\n            square \"$@\"\n            ;;\n        rectangle)\n            rectangle \"$@\"\n            ;;\n        *)\n            \"forma no reconocida\"\n    esac\n}\n\necho -e \"\\n[+] El area del triangulo es:\" \"$(calculate_area triangle 7 5)\"\n\necho -e \"\\n[+] El area del cuadrado es:\" \"$(calculate_area square 6)\" \n\necho -e \"\\n[+] El area del rectangulo es:\" \"$(calculate_area rectangle 8 6)\" \n\n\n# SI QUEREMOS AÑADIR NUEVAS FUNCIONALIDADES SOLO AÑADIMOS LA NUEVA FUNCION Y LA AGREGAMOS AL \"CASE\"\n# EXTENDIENDO EL CODIGO SIN MODIFICAR EL EXISTENTE\n\n\nfunction circle(){\n    local radius=\"$1\"\n    echo \"scale=2; ($radius ^ 2) * 3.1416\" | bc\n\n}\n\nfunction calculate_area(){\n    local shape=$1\n    shift\n    case $shape in\n        triangle)\n            triangle \"$@\"\n            ;;\n        square)\n            square \"$@\"\n            ;;\n        rectangle)\n            rectangle \"$@\"\n            ;;\n        circle)\n            circle \"$@\"\n            ;;\n        *)\n            \"formula no reconocida\"\n    esac\n}\n\n\necho -e \"\\n[+] El area del triangulo es:\" \"$(calculate_area triangle 7 5)\"\n\necho -e \"\\n[+] El area del cuadrado es:\" \"$(calculate_area square 6)\" \n\necho -e \"\\n[+] El area del rectangulo es:\" \"$(calculate_area rectangle 8 6)\" \n\necho -e \"\\n[+] El area del circulo es:\" \"$(calculate_area circle 5)\"\n\n\n\n\n\necho -e \"\\n\\n=======================================DIFICULTAD EXTRA=======================================\\n\\n\"\n\n\n\n\n# * DIFICULTAD EXTRA (opcional):\n# * Desarrolla una calculadora que necesita realizar diversas operaciones matematicas. \n# * Requisitos:\n# * - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n# * Instrucciones:\n# * 1. Implementa las operaciones de suma, resta, multiplicacion y division.\n# * 2. Comprueba que el sistema funciona.\n# * 3. Agrega una quinta operacion para calcular potencias.\n# * 4. Comprueba que se cumple el OCP.\n\n    \nfunction sum(){\n    local num1=\"$1\"\n    local num2=\"$2\"\n    echo \"scale=2; $num1 + $num2\" | bc\n}        \n    \n\nfunction subtract(){\n    local num1=\"$1\"\n    local num2=\"$2\"\n    echo \"scale=2; $num1 - $num2\" | bc\n}\n\n\nfunction multiply(){\n    local num1=\"$1\"\n    local num2=\"$2\"\n    echo \"scale=2; $num1 * $num2\" | bc\n}\n\n        \nfunction division(){\n    local num1=\"$1\"\n    local num2=\"$2\"\n    echo \"scale=2; $num1 / $num2\" | bc\n}\n        \n    \nfunction calculator(){\n    local shape=\"$1\"\n    shift\n    case $shape in\n        sum)\n            sum \"$@\"\n            ;;\n        subtract)\n            subtract \"$@\"\n            ;;\n        multiply)\n            multiply \"$@\"\n            ;;\n        division)\n            division \"$@\"\n            ;;\n        *)\n            echo \"forma no reconocida\"\n            ;;\n    esac\n}\n\necho -e \"\\n[+] El resultado de la suma es:\" \"$(calculator sum 9 5)\"\necho -e \"\\n[+] El resultado de la resta es:\" \"$(calculator subtract 10 6)\" \necho -e \"\\n[+] El resultado de la multiplicacion es:\" \"$(calculator multiply 9 7)\"\necho -e \"\\n[+] El resultado de la division es:\" \"$(calculator division 15 4)\"\n\n\n# AHORA VAMOS A AÑADIR LA FUNCION POTENCIA NO HAY QUE MODIFICAR EL CODIGO\n# EXISTENTE SOLO ESCRIBIR LA NUEVA FUNCION Y AÑADIRLA AL \"CASE\"\n\nfunction pow(){    \n    local base=\"$1\"\n    local exponent=\"$2\"\n    echo \"scale=2; $base ^ $exponent\" | bc\n}\n\nfunction calculator(){\n    local shape=\"$1\"\n    shift\n    case $shape in\n        sum)\n            sum \"$@\"\n            ;;\n        subtract)\n            subtract \"$@\"\n            ;;\n        multiply)\n            multiply \"$@\"\n            ;;\n        division)\n            division \"$@\"\n            ;;\n        pow)\n            pow \"$@\"\n            ;;\n        *)\n            echo \"forma no reconocida\"\n            ;;\n    esac \n}\n\necho -e \"\\n[+] El resultado de la suma es:\" \"$(calculator sum 25 16)\"\necho -e \"\\n[+] El resultado de la resta es:\" \"$(calculator subtract 30 10)\" \necho -e \"\\n[+] El resultado de la multiplicacion es:\" \"$(calculator multiply 46 54)\"\necho -e \"\\n[+] El resultado de la division es:\" \"$(calculator division 1523 41)\"\necho -e \"\\n[+] El resultado de la potencia es:\" \"$(calculator pow 5 3)\"\n \n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/c#/eulogioep.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\n\n/*\n * PRINCIPIO ABIERTO-CERRADO (OCP)\n * \n * El principio establece que las entidades de software (clases, módulos, funciones, etc.) \n * deberían estar:\n * - ABIERTAS para la extensión: Podemos agregar nuevo comportamiento\n * - CERRADAS para la modificación: No debemos modificar el código existente\n * \n * Beneficios:\n * 1. Código más mantenible y escalable\n * 2. Reduce el riesgo de bugs en código existente\n * 3. Facilita la adición de nuevas funcionalidades\n */\n\nnamespace OCP.Calculator\n{\n    // EJEMPLO INCORRECTO (Violando OCP)\n    // ❌ Cada vez que queremos agregar una nueva operación, debemos modificar la clase existente\n    public class BadCalculator\n    {\n        public decimal Calculate(decimal a, decimal b, string operation)\n        {\n            switch (operation)\n            {\n                case \"sum\":\n                    return a + b;\n                case \"subtract\":\n                    return a - b;\n                case \"multiply\":\n                    return a * b;\n                case \"divide\":\n                    return a / b;\n                // Si queremos agregar una nueva operación, debemos modificar esta clase\n                // violando el principio OCP\n                default:\n                    throw new ArgumentException(\"Operación no soportada\");\n            }\n        }\n    }\n\n    // EJEMPLO CORRECTO (Siguiendo OCP)\n    // Definimos una interfaz para las operaciones\n    public interface IOperation\n    {\n        decimal Execute(decimal a, decimal b);\n        string Symbol { get; }\n        string Name { get; }\n    }\n\n    // Implementamos cada operación como una clase separada\n    public class Addition : IOperation\n    {\n        public decimal Execute(decimal a, decimal b) => a + b;\n        public string Symbol => \"+\";\n        public string Name => \"Suma\";\n    }\n\n    public class Subtraction : IOperation\n    {\n        public decimal Execute(decimal a, decimal b) => a - b;\n        public string Symbol => \"-\";\n        public string Name => \"Resta\";\n    }\n\n    public class Multiplication : IOperation\n    {\n        public decimal Execute(decimal a, decimal b) => a * b;\n        public string Symbol => \"*\";\n        public string Name => \"Multiplicación\";\n    }\n\n    public class Division : IOperation\n    {\n        public decimal Execute(decimal a, decimal b)\n        {\n            if (b == 0)\n                throw new DivideByZeroException(\"No se puede dividir por cero\");\n            return a / b;\n        }\n        public string Symbol => \"/\";\n        public string Name => \"División\";\n    }\n\n    // Podemos agregar nuevas operaciones sin modificar el código existente\n    public class Power : IOperation\n    {\n        public decimal Execute(decimal a, decimal b)\n        {\n            return (decimal)Math.Pow((double)a, (double)b);\n        }\n        public string Symbol => \"^\";\n        public string Name => \"Potencia\";\n    }\n\n    // Clase para resultados de operaciones\n    public class OperationResult\n    {\n        public decimal Value { get; set; }\n        public string Operation { get; set; }\n        public decimal FirstOperand { get; set; }\n        public decimal SecondOperand { get; set; }\n        public bool IsSuccess { get; set; }\n        public string ErrorMessage { get; set; }\n\n        public override string ToString() =>\n            IsSuccess\n                ? $\"{FirstOperand} {Operation} {SecondOperand} = {Value}\"\n                : $\"Error: {ErrorMessage}\";\n    }\n\n    // La calculadora que cumple con OCP\n    public class Calculator\n    {\n        private readonly Dictionary<string, IOperation> _operations;\n\n        public Calculator()\n        {\n            _operations = new Dictionary<string, IOperation>();\n        }\n\n        // Método para registrar nuevas operaciones\n        public void RegisterOperation(IOperation operation)\n        {\n            _operations[operation.Symbol] = operation;\n        }\n\n        // Método para realizar cálculos con manejo de errores\n        public OperationResult Calculate(decimal a, decimal b, string symbol)\n        {\n            try\n            {\n                if (!_operations.TryGetValue(symbol, out var operation))\n                {\n                    return new OperationResult\n                    {\n                        IsSuccess = false,\n                        ErrorMessage = $\"Operación {symbol} no soportada\"\n                    };\n                }\n\n                return new OperationResult\n                {\n                    IsSuccess = true,\n                    Value = operation.Execute(a, b),\n                    Operation = symbol,\n                    FirstOperand = a,\n                    SecondOperand = b\n                };\n            }\n            catch (Exception ex)\n            {\n                return new OperationResult\n                {\n                    IsSuccess = false,\n                    ErrorMessage = ex.Message,\n                    Operation = symbol,\n                    FirstOperand = a,\n                    SecondOperand = b\n                };\n            }\n        }\n\n        // Método para obtener operaciones disponibles\n        public IEnumerable<(string Symbol, string Name)> GetAvailableOperations()\n        {\n            return _operations.Values.Select(op => (op.Symbol, op.Name));\n        }\n    }\n\n    // Clase principal para demostración\n    public class Program\n    {\n        public static void Main()\n        {\n            // Creamos una instancia de la calculadora\n            var calculator = new Calculator();\n\n            // Registramos las operaciones básicas\n            calculator.RegisterOperation(new Addition());\n            calculator.RegisterOperation(new Subtraction());\n            calculator.RegisterOperation(new Multiplication());\n            calculator.RegisterOperation(new Division());\n\n            // Mostramos las operaciones disponibles\n            Console.WriteLine(\"Operaciones disponibles:\");\n            foreach (var (symbol, name) in calculator.GetAvailableOperations())\n            {\n                Console.WriteLine($\"- {name} ({symbol})\");\n            }\n\n            // Probamos las operaciones básicas\n            var testCases = new[]\n            {\n                (a: 10m, b: 5m, symbol: \"+\"),\n                (a: 10m, b: 5m, symbol: \"-\"),\n                (a: 10m, b: 5m, symbol: \"*\"),\n                (a: 10m, b: 5m, symbol: \"/\")\n            };\n\n            Console.WriteLine(\"\\nProbando operaciones básicas:\");\n            foreach (var (a, b, symbol) in testCases)\n            {\n                var result = calculator.Calculate(a, b, symbol);\n                Console.WriteLine(result);\n            }\n\n            // Agregamos una nueva operación (potencia) sin modificar el código existente\n            calculator.RegisterOperation(new Power());\n            \n            Console.WriteLine(\"\\nProbando nueva operación (potencia):\");\n            var powerResult = calculator.Calculate(2, 3, \"^\");\n            Console.WriteLine(powerResult);\n\n            // Probamos el manejo de errores\n            Console.WriteLine(\"\\nProbando manejo de errores:\");\n            \n            // División por cero\n            var divByZeroResult = calculator.Calculate(5, 0, \"/\");\n            Console.WriteLine(divByZeroResult);\n\n            // Operación no existente\n            var invalidOpResult = calculator.Calculate(5, 2, \"%\");\n            Console.WriteLine(invalidOpResult);\n        }\n    }\n}\n\n/*\n * EXPLICACIÓN DE POR QUÉ ESTE DISEÑO CUMPLE CON OCP:\n * \n * 1. ABIERTO PARA EXTENSIÓN:\n *    - Podemos agregar nuevas operaciones implementando la interfaz IOperation\n *    - No necesitamos modificar ninguna clase existente\n *    - Cada operación está encapsulada en su propia clase\n * \n * 2. CERRADO PARA MODIFICACIÓN:\n *    - La clase Calculator no necesita ser modificada para agregar nuevas operaciones\n *    - El código existente permanece intacto cuando agregamos nuevas funcionalidades\n *    - La interfaz IOperation define un contrato claro que no cambia\n * \n * 3. VENTAJAS DE ESTE DISEÑO:\n *    - Fácil de mantener y extender\n *    - Cada operación está aislada y puede ser probada independientemente\n *    - Reduce el acoplamiento entre componentes\n *    - Facilita la adición de nuevas operaciones sin riesgo de afectar las existentes\n * \n * 4. CARACTERÍSTICAS ESPECÍFICAS DE LA IMPLEMENTACIÓN EN C#:\n *    - Uso de interfaces y genéricos\n *    - Manejo de errores con try-catch y tipos específicos de excepciones\n *    - Uso de tipos decimales para precisión en cálculos\n *    - Clase específica para resultados con estado de éxito/error\n *    - Uso de características modernas de C# como tuplas y expression-bodied members\n *    - Organización en namespace\n *    - Uso de LINQ para consultas\n */"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/c#/hequebo.cs",
    "content": "/*\n * El Principio Abierto Cerrado (SRP)\n * nos dice que una clase tiene que estar\n * abierta para su extensión pero cerrada\n * para su modificación\n */\nclass Program\n{\n    static void Main(string[] args)\n    {\n        // Incorrecto \n        Shape square = new Shape();\n        square.Width = 3; \n        square.Height = 3;\n        AreaCalculator areaCalculator = new AreaCalculator();\n        double area = areaCalculator.CalculateArea(square);\n        Console.WriteLine($\"El área es de {area}m2\");\n\n        // Correcto\n        Rectangle rectangle = new Rectangle();\n        rectangle.Width = 3;\n        rectangle.Height = 5;\n        AreaCalculatorOCP areaCalculatorOCP = new AreaCalculatorOCP();\n        area = areaCalculatorOCP.CalculateArea(rectangle);\n        Console.WriteLine($\"El área es de {area}m2\");\n\n        Circle circle = new Circle();\n        circle.Radius = 5.2;\n        area = areaCalculatorOCP.CalculateArea(circle);\n        Console.WriteLine($\"El área es de {area}m2\");\n\n        // Ejercicio Extra\n        Console.WriteLine(\"---Ejercicio Extra---\");\n        Calculator calculator = new Calculator();\n        calculator.AddOperation(\"Suma\", new Addition());\n        calculator.AddOperation(\"Resta\", new Substraction());\n        calculator.AddOperation(\"Multiplicación\", new Multiplication());\n        calculator.AddOperation(\"División\", new Division());\n        calculator.AddOperation(\"Potencia\", new Pow());\n\n        Console.WriteLine($\"2 + 3 = {calculator.ExecuteOperation(\"Suma\", 2, 3)}\");\n        Console.WriteLine($\"2 - 3 = {calculator.ExecuteOperation(\"Resta\", 2, 3)}\");\n        Console.WriteLine($\"2 * 3 = {calculator.ExecuteOperation(\"Multiplicación\", 2, 3)}\");\n        Console.WriteLine($\"2 / 3 = {calculator.ExecuteOperation(\"División\", 2, 3)}\");\n        Console.WriteLine($\"2^3 = {calculator.ExecuteOperation(\"Potencia\", 2, 3)}\");\n\n    }\n}\n\n// Incorrecto \nclass Shape\n{\n    public double Width {  get; set; }\n    public double Height { get; set; }\n\n}\nclass AreaCalculator\n{\n    /*\n     * La función CalculateArea solo funciona\n     * para rectangulos. Si quisieramos calcular\n     * el área de otras formas la función tendría\n     * que ser modificada, lo cual rompe el principio\n     * de Abierto Cerrado\n     */\n    public double CalculateArea(Shape shape) => shape.Width * shape.Height;\n}\n\n// Correcto\n/*\n * Para cumplir con el principio Abierto Cerrado\n * podemos utilizar abstracción y herencia para\n * crear clases separadas para cada tipo de forma\n * y proveer un metodo consistente para el cálculo\n * de su area\n */\ninterface IShape\n{\n    public double CalculateArea();\n}\nclass Rectangle : IShape\n{\n    public double Height { get; set; }\n    public double Width { get; set; }\n\n    public double CalculateArea() => Height * Width;\n}\nclass Circle : IShape\n{\n    public double Radius { get; set; }\n\n    public double CalculateArea() => Math.PI * Math.Pow(Radius, 2);\n}\nclass AreaCalculatorOCP\n{\n    public double CalculateArea(IShape shape) => shape.CalculateArea();\n}\n\n// Ejercicio Extra\ninterface IOperation\n{\n    public double Execute(double a, double b);\n}\nclass Addition : IOperation\n{\n\n    public double Execute(double a, double b) => a + b; \n}\nclass Substraction : IOperation\n{\n    public double Execute(double a, double b) => a - b;\n}\nclass Multiplication : IOperation\n{\n    public double Execute(double a, double b) => a * b;\n}\nclass Division : IOperation\n{\n    public double Execute(double a, double b) => a / b;\n}\nclass Pow : IOperation\n{\n    public double Execute(double a, double b) => Math.Pow(a, b);\n}\nclass Calculator\n{\n    private Dictionary<string, IOperation> _operations;\n\n    public Calculator()\n    {\n        _operations = new Dictionary<string, IOperation>();\n    }\n\n    public void AddOperation(string name, IOperation operation) => _operations.Add(name, operation);\n    public double ExecuteOperation(string name, double a, double b)\n    {\n        if (!_operations.ContainsKey(name))\n        {\n            Console.WriteLine(\"La operación no existe\");\n            return 0; \n        }\n        return _operations[name].Execute(a, b);\n    }\n}"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/c#/kenysdev.cs",
    "content": "namespace exs27;\n/*\n╔══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado               ║\n║ GitHub: https://github.com/Kenysdev  ║\n║ 2024 -  C#                           ║\n╚══════════════════════════════════════╝\n-------------------------------------------------\n* SOLID: PRINCIPIO ABIERTO-CERRADO (OCP)\n-------------------------------------------------\n- Una entidad de software que está abierta a extensión, pero cerrada a modificación, \n  esto significa que debemos poder extender el comportamiento de una clase sin \n  necesidad de modificar su código fuente original.\n\n_______________\n* EJERCICIO #1:\n* Explora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\" \n* y crea un ejemplo simple donde se muestre su funcionamiento\n* de forma correcta e incorrecta.\n*/\n\n// Abstract base class Product\npublic abstract class Product(string name, decimal price)\n{\n    public string Name { get; set; } = name;\n    public decimal Price { get; set; } = price;\n\n    // Abstract method\n    public abstract decimal ApplyDiscount();\n\n    // Concrete metho\n    public decimal FinalPrice()\n    {\n        return Price - ApplyDiscount();\n    }\n}\n\n// Concrete class\npublic class ElectronicsProduct(string name, decimal price) : Product(name, price)\n{\n    public override decimal ApplyDiscount()\n    {\n        return Price * 0.05m; // Discount of 5%\n    }\n}\n\n\n// Concrete class\npublic class ClothingProduct(string name, decimal price) : Product(name, price)\n{\n    public override decimal ApplyDiscount()\n    {\n        if (Price > 50)\n            return 10; // Discount of $10 if price is over $50\n        else\n            return 0; // No discount otherwise\n    }\n}\n\n/*\n_______________\n* EJERCICIO #2:\n* Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas. \n* Requisitos:\n* - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n* Instrucciones:\n* 1. Implementa las operaciones de suma, resta, multiplicación y división.\n* 2. Comprueba que el sistema funciona.\n* 3. Agrega una quinta operación para calcular potencias.\n* 4. Comprueba que se cumple el OCP.\n*/\n\n// Abstract base\npublic abstract class Calculator(double a, double b)\n{\n    protected double a = a;\n    protected double b = b;\n\n    // Abstract method\n    public abstract double MathOperation();\n\n    // Concrete method\n    public void PrintResult()\n    {\n        Console.WriteLine($\"Es: {MathOperation()}\");\n    }\n}\n\npublic class Sum(double a, double b) : Calculator(a, b)\n{\n    public override double MathOperation()\n    {\n        Console.WriteLine($\"\\nSuma de {a} + {b}:\");\n        return a + b;\n    }\n}\n\npublic class Subtraction(double a, double b) : Calculator(a, b)\n{\n    public override double MathOperation()\n    {\n        Console.WriteLine($\"\\nResta de {a} - {b}:\");\n        return a - b;\n    }\n}\n\npublic class Multiplication(double a, double b) : Calculator(a, b)\n{\n    public override double MathOperation()\n    {\n        Console.WriteLine($\"\\nMultiplicación de {a} * {b}:\");\n        return a * b;\n    }\n}\n\npublic class Division(double a, double b) : Calculator(a, b)\n{\n    public override double MathOperation()\n    {\n        Console.WriteLine($\"\\nDivisión de {a} / {b}:\");\n        if (b != 0)\n            return a / b;\n        else\n            throw new ArgumentException(\"DivisionErrorbyZero.\");\n    }\n}\n\npublic class Pow(double a, double b) : Calculator(a, b)\n{\n    public override double MathOperation()\n    {\n        Console.WriteLine($\"\\nPotencia de {a} ^ {b}:\");\n        return Math.Pow(a, b);\n    }\n}\n\n//__________________\npublic class Program\n{\n    public static void ProcessProduct(Product product)\n    {\n        Console.WriteLine($\"Producto: {product.Name}, Precio final: {product.FinalPrice()}\");\n    }\n\n    static void Main()\n    {\n        ElectronicsProduct laptop = new(\"Laptop\", 700 );\n        ClothingProduct pants = new(\"Pants\", 55);\n\n        ProcessProduct(laptop);\n        ProcessProduct(pants);\n\n        //___________________________\n        // exs 2\n\n        Sum sum = new(2, 2);\n        sum.PrintResult();\n\n        Subtraction subtraction = new(2, 2);\n        subtraction.PrintResult();\n\n        Multiplication multiplication = new(2, 2);\n        multiplication.PrintResult();\n\n        Division division = new(2, 2);\n        division.PrintResult();\n\n        Pow pow = new(2, 2);\n        pow.PrintResult();\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/c++/hectorio23.cpp",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\n#include <iostream>\n#include <unordered_map>\n#include <memory>\n#include <cmath>\n\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA:\n * Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas. \n * Requisitos:\n * - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n * Instrucciones:\n * 1. Implementa las operaciones de suma, resta, multiplicación y división.\n * 2. Comprueba que el sistema funciona.\n * 3. Agrega una quinta operación para calcular potencias.\n * 4. Comprueba que se cumple el OCP.\n*/\n\nclass Operacion {\npublic:\n    virtual double calcular(double a, double b) const = 0;\n    virtual ~Operacion() = default;\n};\n\nclass Suma : public Operacion {\npublic:\n    double calcular(double a, double b) const override {\n        return a + b;\n    }\n};\n\nclass Resta : public Operacion {\npublic:\n    double calcular(double a, double b) const override {\n        return a - b;\n    }\n};\n\nclass Multiplicacion : public Operacion {\npublic:\n    double calcular(double a, double b) const override {\n        return a * b;\n    }\n};\n\nclass Division : public Operacion {\npublic:\n    double calcular(double a, double b) const override {\n        if (b == 0) {\n            throw std::invalid_argument(\"División por cero\");\n        }\n        return a / b;\n    }\n};\n\nclass Potencia : public Operacion {\npublic:\n    double calcular(double a, double b) const override {\n        return std::pow(a, b);\n    }\n};\n\nclass Calculadora {\nprivate:\n    std::unordered_map<char, std::unique_ptr<Operacion>> operaciones;\n\npublic:\n    void agregarOperacion(char simbolo, std::unique_ptr<Operacion> operacion) {\n        operaciones[simbolo] = std::move(operacion);\n    }\n\n    double calcular(char operacion, double a, double b) const {\n        auto it = operaciones.find(operacion);\n        if (it != operaciones.end()) {\n            return it->second->calcular(a, b);\n        } else {\n            throw std::invalid_argument(\"Operación no soportada\");\n        }\n    }\n};\n\nint main() {\n    Calculadora calc;\n    calc.agregarOperacion('+', std::make_unique<Suma>());\n    calc.agregarOperacion('-', std::make_unique<Resta>());\n    calc.agregarOperacion('*', std::make_unique<Multiplicacion>());\n    calc.agregarOperacion('/', std::make_unique<Division>());\n    calc.agregarOperacion('^', std::make_unique<Potencia>());\n\n    std::cout << \"[+] - Suma: \" << calc.calcular('+', 5, 3) << std::endl;\n    std::cout << \"[+] - Resta: \" << calc.calcular('-', 5, 3) << std::endl;\n    std::cout << \"[+] - Multiplicación: \" << calc.calcular('*', 5, 3) << std::endl;\n    std::cout << \"[+] - División: \" << calc.calcular('/', 5, 3) << std::endl;\n    std::cout << \"[+] - Potencia: \" << calc.calcular('^', 5, 3) << std::endl;\n\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/dart/EmilianoAngel.dart",
    "content": "// Incorrecto\n// class Form {\n\n//   void drawSquare() {\n//     print('Dibujar un cuadrado');\n//   }\n\n//   void drawCircle() {\n//     print('Dibujar un círculo');\n//   }\n// }\n\n// Correcto\nabstract class Form {\n  void draw();\n}\n\nclass Square implements Form {\n  @override\n  void draw() {\n    print('Dibujar un cuadrado');\n  }\n}\n\nclass Circle implements Form {\n  @override\n  void draw() {\n    print('Dibujar un círculo');\n  }\n}\n\nclass Triangle implements Form {\n  @override\n  void draw() {\n    print('Dibujar un triángulo');\n  }\n}\n\n// Ejercicio de calculadora\n\nabstract class Operation {\n  double execute(double a, double b) {\n    return 0;\n  }\n}\n\nclass Addition implements Operation {\n  @override\n  double execute(double a, double b) {\n    return a + b;\n  }\n}\n\nclass Subtraction implements Operation {\n  @override\n  double execute(double a, double b) {\n    return a - b;\n  }\n}\n\nclass Multiplication implements Operation {\n  @override\n  double execute(double a, double b) {\n    return a * b;\n  }\n}\n\nclass Division implements Operation {\n  @override\n  double execute(double a, double b) {\n    if (b == 0) {\n      throw Exception('Division by zero is not allowed.');\n    }\n    return a / b;\n  }\n}\n\nclass Power implements Operation {\n  @override\n  double execute(double a, double b) {\n    double result = 1;\n    for(int i = 0; i < b; i++) {\n      result *= a;\n    }\n    return result;\n  }\n}\n\nclass Calculator {\n  final Map<String, dynamic> _operations = {};\n\n  void addOperation(String name, Operation operation) {\n    _operations[name] = operation;\n  }\n  double calculate(String name, double a, double b) {\n    final operation = _operations[name];\n    if (operation == null) {\n      throw ArgumentError('Operation $name not supported.');\n    }\n    return operation.execute(a,b);\n  }\n}\n\nvoid main () {\n  Calculator calculator = Calculator();\n\n  calculator.addOperation('addition', Addition());\n  calculator.addOperation('substraction', Subtraction());\n  calculator.addOperation('multiplication', Multiplication());\n  calculator.addOperation('division', Division());\n  calculator.addOperation('power', Power());\n\n  print(calculator.calculate('addition', 5, 3));\n  print(calculator.calculate('substraction', 6, 3));\n  print(calculator.calculate('multiplication', 5, 2));\n  print(calculator.calculate('division', 12, 6));\n  print(calculator.calculate('power', 2, 3));\n \n}\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/ejercicio.md",
    "content": "# #27 SOLID: PRINCIPIO ABIERTO-CERRADO (OCP)\n> #### Dificultad: Media | Publicación: 01/07/24 | Corrección: 08/07/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas. \n * Requisitos:\n * - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n * Instrucciones:\n * 1. Implementa las operaciones de suma, resta, multiplicación y división.\n * 2. Comprueba que el sistema funciona.\n * 3. Agrega una quinta operación para calcular potencias.\n * 4. Comprueba que se cumple el OCP.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/27 - SOLID OCP/go/AmadorQuispe.go",
    "content": "package main\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"math\"\n)\n\ntype ReportServiceBad[T any] struct {\n\tdata T\n}\n\nfunc (rs *ReportServiceBad[T]) ReportGenerator(typeReport string) {\n\tif typeReport == \"PDF\" {\n\t\tfmt.Println(rs.data)\n\t\tfmt.Println(\"Generando reporte PDF\")\n\t} else if typeReport == \"HTML\" {\n\t\tfmt.Println(rs.data)\n\t\tfmt.Println(\"Generando reporte HTML\")\n\t}\n}\n\n// Re factorización para cumplir el OCP\n// ReportGenerator, interfaz que define el comportamiento de un generador de reportes\ntype ReportGenerator interface {\n\tGenerateReport(data interface{})\n}\n\n// PDFReportGenerator, implementación de ReportGenerator para reportes PDF\ntype PDFReportGenerator struct{}\n\nfunc (p *PDFReportGenerator) GenerateReport(data interface{}) {\n\tfmt.Println(data)\n\tfmt.Println(\"Generando reporte PDF\")\n}\n\n// HTMLReportGenerator, implementación de ReportGenerator para reportes HTML\ntype HTMLReportGenerator struct{}\n\nfunc (h *HTMLReportGenerator) GenerateReport(data interface{}) {\n\tfmt.Println(data)\n\tfmt.Println(\"Generando reporte HTML\")\n}\n\n// ReportService usa un generador de reportes para generar reportes\ntype ReportService struct {\n\tdata      interface{}\n\treportGen ReportGenerator\n}\n\nfunc (rs *ReportService) GenerateReport() {\n\trs.reportGen.GenerateReport(rs.data)\n}\n\n// EXTRA\ntype Operation interface {\n\tApply(num1, num2 float32) (float32, error)\n}\n\n// SUMA\ntype Addition struct{}\n\nfunc (a *Addition) Apply(num1, num2 float32) (float32, error) {\n\treturn num1 + num2, nil\n}\n\n// RESTA\ntype Subtraction struct{}\n\nfunc (a *Subtraction) Apply(num1, num2 float32) (float32, error) {\n\treturn num1 - num2, nil\n}\n\n// MULTIPLICACIÓN\ntype Multiplication struct{}\n\nfunc (a *Multiplication) Apply(num1, num2 float32) (float32, error) {\n\treturn num1 * num2, nil\n}\n\n// DIVISIÓN\ntype Division struct{}\n\nfunc (a *Division) Apply(num1, num2 float32) (float32, error) {\n\tif num2 == 0 {\n\t\treturn 0, errors.New(\"division by zero\")\n\t}\n\treturn num1 / num2, nil\n}\n\n// POTENCIA\ntype Pow struct{}\n\nfunc (a *Pow) Apply(num1, num2 float32) (float32, error) {\n\treturn float32(math.Pow(float64(num1), float64(num2))), nil\n}\n\n// Calculator usa una operación para calcular un resultado\ntype Calculator struct{}\n\nfunc (c *Calculator) Calculate(operation Operation, num1, num2 float32) (float32, error) {\n\treturn operation.Apply(num1, num2)\n}\n\nfunc main() {\n\t//VIOLA OCP\n\treportServiceBad := ReportServiceBad[string]{data: \"data de ejemplo bad\"}\n\treportServiceBad.ReportGenerator(\"PDF\")\n\n\t//OCP\n\tdata := \"Datos de ejemplo\"\n\tpdfGenerator := &PDFReportGenerator{}\n\thtmlGenerator := &HTMLReportGenerator{}\n\n\tpdfReportService := &ReportService{data: data, reportGen: pdfGenerator}\n\thtmlReportService := &ReportService{data: data, reportGen: htmlGenerator}\n\n\tpdfReportService.GenerateReport()\n\thtmlReportService.GenerateReport()\n\n\t//CALCULATOR\n\tnum1 := float32(10)\n\tnum2 := float32(5)\n\n\tcalculator := &Calculator{}\n\n\taddition := &Addition{}\n\tsubtraction := &Subtraction{}\n\tmultiplication := &Multiplication{}\n\tdivision := &Division{}\n\n\tresult, err := calculator.Calculate(addition, num1, num2)\n\tif err != nil {\n\t\tfmt.Println(\"Error:\", err)\n\t} else {\n\t\tfmt.Println(\"Suma:\", result)\n\t}\n\n\tresult, err = calculator.Calculate(subtraction, num1, num2)\n\tif err != nil {\n\t\tfmt.Println(\"Error:\", err)\n\t} else {\n\t\tfmt.Println(\"Resta:\", result)\n\t}\n\n\tresult, err = calculator.Calculate(multiplication, num1, num2)\n\tif err != nil {\n\t\tfmt.Println(\"Error:\", err)\n\t} else {\n\t\tfmt.Println(\"Multiplicación:\", result)\n\t}\n\n\tresult, err = calculator.Calculate(division, num1, num2)\n\tif err != nil {\n\t\tfmt.Println(\"Error:\", err)\n\t} else {\n\t\tfmt.Println(\"División:\", result)\n\t}\n\n\t//Potencia\n\tpow := &Pow{}\n\tresult, err = calculator.Calculate(pow, num1, num2)\n\tif err != nil {\n\t\tfmt.Println(\"Error:\", err)\n\t} else {\n\t\tfmt.Println(\"Potencia:\", result)\n\t}\n}\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/go/hozlucas28.go",
    "content": "package main\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"math\"\n)\n\n/* -------------------------------------------------------------------------- */\n/*                           CLASSES AND INTERFACES                           */\n/* -------------------------------------------------------------------------- */\n\n/* ---------------------------- BadCircle (class) --------------------------- */\n\ntype BadCircle struct {\n\tradius float64\n\t_      struct{}\n}\n\n/* -------------------------- BadRectangle (class) -------------------------- */\n\ntype BadRectangle struct {\n\theight float64\n\twidth  float64\n\t_      struct{}\n}\n\n/* -------------------------- BadCalculator (class) ------------------------- */\n\ntype BadCalculator struct{}\n\nfunc (calculator BadCalculator) GetArea(shape interface{}) float64 {\n\tswitch shape := shape.(type) {\n\tcase BadCircle:\n\t\treturn math.Pi * math.Pow(shape.radius, 2)\n\n\tcase BadRectangle:\n\t\treturn shape.height * shape.width\n\n\tdefault:\n\t\treturn -1\n\t}\n}\n\n/* ---------------------------- Shape (interface) --------------------------- */\n\ntype Shape interface {\n\tGetArea() float64\n}\n\n/* --------------------------- GoodCircle (class) --------------------------- */\n\ntype goodCircle struct {\n\tradius float64\n\t_      struct{}\n}\n\nfunc NewGoodCircle(radius float64) Shape {\n\tvar circle goodCircle = goodCircle{radius: radius}\n\treturn &circle\n}\n\nfunc (circle *goodCircle) GetArea() float64 {\n\treturn math.Pi * math.Pow(circle.radius, 2)\n}\n\n/* -------------------------- GoodRectangle (class) ------------------------- */\n\ntype goodRectangle struct {\n\theight float64\n\twidth  float64\n\t_      struct{}\n}\n\nfunc NewGoodRectangle(height float64, width float64) Shape {\n\tvar rectangle goodRectangle = goodRectangle{height: height, width: width}\n\treturn &rectangle\n}\n\nfunc (rectangle *goodRectangle) GetArea() float64 {\n\treturn rectangle.height * rectangle.width\n}\n\n/* ------------------ GoodCalculator (class And Interface) ------------------ */\n\ntype IGoodCalculator interface {\n\tGetArea(shape Shape) float64\n}\n\ntype goodCalculator struct{}\n\nfunc NewGoodCalculator() IGoodCalculator {\n\tvar calculator goodCalculator = goodCalculator{}\n\treturn &calculator\n}\n\nfunc (calculator *goodCalculator) GetArea(shape Shape) float64 {\n\treturn shape.GetArea()\n}\n\n/* -------------------------- Operation (interface) ------------------------- */\n\ntype Operation interface {\n\tExecute(a float64, b float64) (float64, error)\n}\n\n/* -------------------------- AddOperation (class) -------------------------- */\n\ntype addOperation struct{}\n\nfunc NewAddOperation() Operation {\n\tvar add addOperation = addOperation{}\n\treturn &add\n}\n\nfunc (operation *addOperation) Execute(a float64, b float64) (float64, error) {\n\treturn a + b, nil\n}\n\n/* ------------------------- DivideOperation (class) ------------------------ */\n\ntype divideOperation struct{}\n\nfunc NewDivideOperation() Operation {\n\tvar divide divideOperation = divideOperation{}\n\treturn &divide\n}\n\nfunc (operation *divideOperation) Execute(a float64, b float64) (float64, error) {\n\tif b == 0 {\n\t\treturn 0, errors.New(\"The second parameter must not be zero\")\n\t}\n\n\treturn a / b, nil\n\n}\n\n/* ------------------------ MultiplyOperation (class) ----------------------- */\n\ntype multiplyOperation struct{}\n\nfunc NewMultiplyOperation() Operation {\n\tvar multiply multiplyOperation = multiplyOperation{}\n\treturn &multiply\n}\n\nfunc (operation *multiplyOperation) Execute(a float64, b float64) (float64, error) {\n\treturn a * b, nil\n\n}\n\n/* -------------------------- PowOperation (class) -------------------------- */\n\ntype powOperation struct{}\n\nfunc NewPowOperation() Operation {\n\tvar pow powOperation = powOperation{}\n\treturn &pow\n}\n\nfunc (operation *powOperation) Execute(a float64, b float64) (float64, error) {\n\treturn math.Pow(a, b), nil\n\n}\n\n/* ------------------------ SubtractOperation (class) ----------------------- */\n\ntype subtractOperation struct{}\n\nfunc NewSubtractOperation() Operation {\n\tvar subtract subtractOperation = subtractOperation{}\n\treturn &subtract\n}\n\nfunc (operation *subtractOperation) Execute(a float64, b float64) (float64, error) {\n\treturn a - b, nil\n\n}\n\n/* ------------------------------- Calculator ------------------------------- */\n\ntype ICalculator interface {\n\tAddOperation(name string, operation *Operation) error\n\tExecuteOperation(name string, a float64, b float64) (float64, error)\n}\n\ntype calculator struct {\n\toperations map[string](*Operation)\n\t_          struct{}\n}\n\nfunc NewCalculator() ICalculator {\n\tvar calculator calculator = calculator{operations: map[string]*Operation{}}\n\treturn &calculator\n}\n\nfunc (calculator *calculator) AddOperation(name string, operation *Operation) error {\n\t_, operationExist := calculator.operations[name]\n\tif operationExist {\n\t\treturn fmt.Errorf(\"The operation with '%s' name already exist\", name)\n\t}\n\n\tcalculator.operations[name] = operation\n\treturn nil\n}\n\nfunc (calculator *calculator) ExecuteOperation(name string, a float64, b float64) (float64, error) {\n\toperation, operationExist := calculator.operations[name]\n\tif !operationExist {\n\t\treturn 0, fmt.Errorf(\"There is not operation with '%s' name\", name)\n\t}\n\n\toperationResult, err := (*operation).Execute(a, b)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\n\treturn operationResult, nil\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\nfunc main() {\n\t/*\n\t\tOpen-Close Principle (OCP)...\n\t*/\n\n\tfmt.Println(\"Open-Close Principle (OCP)...\")\n\n\tfmt.Println(\"\\nBad implementation of Open-Close Principle (OCP)...\")\n\n\tfmt.Println(\"\\n```\\n\" + `type BadCircle struct {\n  radius float64\n  _      struct{}\n}\n\ntype BadRectangle struct {\n  height float64\n  width  float64\n  _      struct{}\n}\n\ntype BadCalculator struct{}\n\nfunc (calculator BadCalculator) GetArea(shape interface{}) float64 {\n  switch shape := shape.(type) {\n  case BadCircle:\n    return math.Pi * math.Pow(shape.radius, 2)\n\n  case BadRectangle:\n    return shape.height * shape.width\n\n  default:\n    return -1\n  }\n}` + \"\\n```\")\n\n\tfmt.Println(\n\t\t\"\\nThis is a bad implementation of Open-Close Principle (OCP),\\n\" +\n\t\t\t\"because the method 'getArea' of struct 'BadCalculator' will must\\n\" +\n\t\t\t\"change if we have to add more shapes types.\",\n\t)\n\n\tfmt.Println(\"\\nGood implementation of Open-Close Principle (OCP)...\")\n\n\tfmt.Println(\"\\n```\\n\" + `type Shape interface {\n  GetArea() float64\n}\n\ntype goodCircle struct {\n  radius float64\n  _      struct{}\n}\n\nfunc NewGoodCircle(radius float64) Shape {\n  var circle goodCircle = goodCircle{radius: radius}\n  return &circle\n}\n\nfunc (circle *goodCircle) GetArea() float64 {\n  return math.Pi * math.Pow(circle.radius, 2)\n}\n\ntype goodRectangle struct {\n  height float64\n  width  float64\n  _      struct{}\n}\n\nfunc NewGoodRectangle(height float64, width float64) Shape {\n  var rectangle goodRectangle = goodRectangle{height: height, width: width}\n  return &rectangle\n}\n\nfunc (rectangle *goodRectangle) GetArea() float64 {\n  return rectangle.height * rectangle.width\n}\n\ntype IGoodCalculator interface {\n  GetArea(shape Shape) float64\n}\n\ntype goodCalculator struct{}\n\nfunc NewGoodCalculator() IGoodCalculator {\n  var calculator goodCalculator = goodCalculator{}\n  return &calculator\n}\n\nfunc (calculator *goodCalculator) GetArea(shape Shape) float64 {\n  return shape.GetArea()\n}` + \"\\n```\")\n\n\tfmt.Println(\n\t\t\"\\nThis is a good implementation of Open-Close Principle (OCP),\\n\" +\n\t\t\t\"because the method 'getArea' of struct 'GoodCalculator' will must\\n\" +\n\t\t\t\"not change if we have to add more shapes. So, 'getArea' is closed to modification\\n\" +\n\t\t\t\"but it is open to extension throw any shape which implements 'Shape' interface.\",\n\t)\n\n\tfmt.Println(\n\t\t\"\\n# ---------------------------------------------------------------------------------- #\",\n\t)\n\n\t/*\n\t   Additional challenge...\n\t*/\n\n\tfmt.Println(\"\\nAdditional challenge...\")\n\n\tfmt.Println(\"\\nTesting the OCP system without a pow operation...\")\n\n\tvar calculator ICalculator = NewCalculator()\n\n\tvar addOperation Operation = NewAddOperation()\n\tvar divideOperation Operation = NewDivideOperation()\n\tvar multiplyOperation Operation = NewMultiplyOperation()\n\tvar subtractOperation Operation = NewSubtractOperation()\n\n\tcalculator.AddOperation(\"add\", &addOperation)\n\tcalculator.AddOperation(\"add\", &divideOperation)\n\tcalculator.AddOperation(\"multiply\", &multiplyOperation)\n\tcalculator.AddOperation(\"subtract\", &subtractOperation)\n\n\tvar a float64 = 11\n\tvar b float64 = 8.2\n\n\taddOperationResult, _ := calculator.ExecuteOperation(\"add\", a, b)\n\tfmt.Printf(\"\\nAdd operation result (%.2f + %.2f): %f\", a, b, addOperationResult)\n\n\ta, b = 5, 4.2\n\tdivideOperationResult, _ := calculator.ExecuteOperation(\"divide\", a, b)\n\tfmt.Printf(\"\\nDivide operation result (%.2f / %.2f): %f\", a, b, divideOperationResult)\n\n\ta, b = 2, 6.6\n\tmultiplyOperationResult, _ := calculator.ExecuteOperation(\"multiply\", a, b)\n\tfmt.Printf(\"\\nMultiply operation result (%.2f * %.2f): %f\", a, b, multiplyOperationResult)\n\n\ta, b = -1, -6.888\n\tsubtractOperationResult, _ := calculator.ExecuteOperation(\"subtract\", a, b)\n\tfmt.Printf(\"\\nSubtract operation result (%.2f - %.3f): %f\", a, b, subtractOperationResult)\n\n\tfmt.Println(\"\\n\\nTesting the OCP system with a pow operation...\")\n\n\tvar powOperation Operation = NewPowOperation()\n\n\tcalculator.AddOperation(\"pow\", &powOperation)\n\n\ta, b = 2, 10\n\tpowOperationResult, _ := calculator.ExecuteOperation(\"pow\", a, b)\n\tfmt.Printf(\"\\nPow operation result (%.2f^%.2f): %f\", a, b, powOperationResult)\n}\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/go/kodenook.go",
    "content": "package main\n\nimport \"fmt\"\n\ntype PaymentMethod interface {\n\tPay(amount float64) string\n}\n\ntype CreditCard struct{}\n\nfunc (cc CreditCard) Pay(amount float64) string {\n\treturn fmt.Sprintf(\"Paid %.2f using Credit Card\", amount)\n}\n\ntype PayPal struct{}\n\nfunc (pp PayPal) Pay(amount float64) string {\n\treturn fmt.Sprintf(\"Paid %.2f using PayPal\", amount)\n}\n\nfunc ProcessPayment(pm PaymentMethod, amount float64) {\n\tfmt.Println(pm.Pay(amount))\n}\n\nfunc main() {\n\tcc := CreditCard{}\n\tpp := PayPal{}\n\n\tProcessPayment(cc, 100.0)\n\tProcessPayment(pp, 150.0)\n}\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/go/qwik-zgheib.go",
    "content": "package main\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"math\"\n)\n\n/* -- exercise */\n/* incorrect */\n\ntype Invoice struct {\n\tAmount       float64\n\tIsDiscounted bool\n}\n\nfunc (i *Invoice) CalculateTotal() float64 {\n\tif i.IsDiscounted {\n\t\treturn i.Amount * 0.9\n\t}\n\treturn i.Amount\n}\n\n/* correct */\n\ntype InvoiceC interface {\n\tCalculateTotal() float64\n}\n\ntype RegularInvoice struct {\n\tAmount float64\n}\n\nfunc (i RegularInvoice) CalculateTotal() float64 {\n\treturn i.Amount\n}\n\ntype DiscountedInvoice struct {\n\tAmount       float64\n\tDiscountRate float64\n}\n\nfunc (i DiscountedInvoice) CalculateTotal() float64 {\n\treturn i.Amount * (1 - i.DiscountRate)\n}\n\n/* -- extra challenge */\n\ntype Operation interface {\n\tCalculate(a, b float64) (float64, error)\n}\n\ntype Addition struct{}\n\nfunc (Addition) Calculate(a, b float64) (float64, error) {\n\treturn a + b, nil\n}\n\ntype Subtraction struct{}\n\nfunc (Subtraction) Calculate(a, b float64) (float64, error) {\n\treturn a - b, nil\n}\n\ntype Multiplication struct{}\n\nfunc (Multiplication) Calculate(a, b float64) (float64, error) {\n\treturn a * b, nil\n}\n\ntype Division struct{}\n\nfunc (Division) Calculate(a, b float64) (float64, error) {\n\tif b == 0 {\n\t\treturn 0, errors.New(\"cannot divide by zero\")\n\t}\n\treturn a / b, nil\n}\n\ntype Calculator struct {\n\toperations map[string]Operation\n}\n\nfunc NewCalculator() *Calculator {\n\treturn &Calculator{\n\t\toperations: make(map[string]Operation),\n\t}\n}\n\nfunc (c *Calculator) AddOperation(name string, operation Operation) {\n\tc.operations[name] = operation\n}\n\nfunc (c *Calculator) Calculate(name string, a, b float64) (float64, error) {\n\toperation, found := c.operations[name]\n\tif !found {\n\t\treturn 0, fmt.Errorf(\"operation %s not found\", name)\n\t}\n\treturn operation.Calculate(a, b)\n}\n\ntype Power struct{}\n\nfunc (Power) Calculate(a, b float64) (float64, error) {\n\treturn math.Pow(a, b), nil\n}\n\nfunc main() {\n\t/* -- exercise */\n\t/* exercise -- incorrect */\n\tinvoice := Invoice{Amount: 100, IsDiscounted: true}\n\tfmt.Printf(\"Total: %.2f\\n\", invoice.CalculateTotal())\n\n\t/* exercise -- correct */\n\tregularInvoice := RegularInvoice{Amount: 100}\n\tdiscountedInvoice := DiscountedInvoice{Amount: 100, DiscountRate: 0.1}\n\n\tinvoices := []InvoiceC{regularInvoice, discountedInvoice}\n\n\tfor _, invoice := range invoices {\n\t\tfmt.Printf(\"Total: %.2f\\n\", invoice.CalculateTotal())\n\t}\n\n\t/* extra challenge */\n\tcalculator := NewCalculator()\n\n\tcalculator.AddOperation(\"add\", Addition{})\n\tcalculator.AddOperation(\"subtract\", Subtraction{})\n\tcalculator.AddOperation(\"multiply\", Multiplication{})\n\tcalculator.AddOperation(\"divide\", Division{})\n\tcalculator.AddOperation(\"power\", Power{})\n\n\ta, b := 6.0, 2.0\n\n\tresult, _ := calculator.Calculate(\"add\", a, b)\n\tfmt.Printf(\"Add: %.2f + %.2f = %.2f\\n\", a, b, result)\n\n\tresult, _ = calculator.Calculate(\"subtract\", a, b)\n\tfmt.Printf(\"Subtract: %.2f - %.2f = %.2f\\n\", a, b, result)\n\n\tresult, _ = calculator.Calculate(\"multiply\", a, b)\n\tfmt.Printf(\"Multiply: %.2f * %.2f = %.2f\\n\", a, b, result)\n\n\tresult, err := calculator.Calculate(\"divide\", a, b)\n\tif err != nil {\n\t\tfmt.Println(\"Error:\", err)\n\t} else {\n\t\tfmt.Printf(\"Divide: %.2f / %.2f = %.2f\\n\", a, b, result)\n\t}\n\n\tresult, _ = calculator.Calculate(\"power\", a, b)\n\tfmt.Printf(\"Power: %.2f ^ %.2f = %.2f\\n\", a, b, result)\n}\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/go/raynerpv2022.go",
    "content": "/*\n#  * EJERCICIO:\n#  * Explora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\"\n#  * y crea un ejemplo simple donde se muestre su funcionamiento\n#  * de forma correcta e incorrecta.\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas.\n#  * Requisitos:\n#  * - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n#  * Instrucciones:\n#  * 1. Implementa las operaciones de suma, resta, multiplicación y división.\n#  * 2. Comprueba que el sistema funciona.\n#  * 3. Agrega una quinta operación para calcular potencias.\n#  * 4. Comprueba que se cumple el OCP.\n#\n*/\npackage main\n\nimport (\n\t\"fmt\"\n\t\"math\"\n)\n\n// incorrect\n\ntype Shape struct {\n\ta    float64\n\tb    float64\n\tarea float64\n\tname string\n}\n\nfunc (s *Shape) Area() {\n\tif s.name == \"rectangle\" {\n\t\ts.area = s.a * s.b\n\t}\n\tif s.name == \"triangle\" {\n\t\ts.area = s.a * s.b / 2\n\t}\n\tif s.name == \"square\" {\n\t\ts.area = math.Pow((s.a), 2)\n\t}\n}\n\nfunc (s *Shape) Result() {\n\tfmt.Printf(\"Shape %v, Area %v\\n\", s.name, s.area)\n}\n\n// Correct\n\ntype AreaCalculator interface {\n\tArea()\n\tResult() // no debe serpero es como unico pincha\n}\n\ntype BaseForm struct {\n\tarea float64\n\tname string\n}\n\ntype square struct {\n\ta float64\n\tBaseForm\n}\n\nfunc (s *square) Area() {\n\ts.area = math.Pow(s.a, 2)\n}\n\ntype rectangle struct {\n\ta, b float64\n\tBaseForm\n}\n\nfunc (r *rectangle) Area() {\n\tr.area = r.a * r.b\n}\n\ntype triangle struct {\n\ta, b float64\n\tBaseForm\n}\n\nfunc (t *triangle) Area() {\n\tt.area = t.a * t.b / 2\n}\n\nfunc (bf *BaseForm) Result() {\n\tfmt.Printf(\"Form %v, Area %v\\n\", bf.name, bf.area)\n}\n\nfunc (bf *BaseForm) Area() {\n\t// NO debe ser pero es como unico pincha\n}\n\n// Extra\n\ntype Operation interface {\n\tExecute(a, b float64) float64\n}\n\ntype Sum struct{}\n\nfunc (s *Sum) Execute(a, b float64) float64 {\n\treturn a + b\n}\n\ntype Rest struct{}\n\nfunc (r *Rest) Execute(a, b float64) float64 {\n\treturn a - b\n}\n\ntype Mult struct{}\n\nfunc (r *Mult) Execute(a, b float64) float64 {\n\treturn a * b\n}\n\ntype Dv struct{}\n\nfunc (r *Dv) Execute(a, b float64) float64 {\n\treturn a / b\n}\n\ntype Pw struct{}\n\nfunc (r *Pw) Execute(a, b float64) float64 {\n\treturn math.Pow(a, b)\n}\n\ntype Calculator struct {\n\tregistry map[string]Operation\n}\n\nfunc (c *Calculator) Init() {\n\tc.registry = map[string]Operation{}\n\n}\n\nfunc (c *Calculator) Registry(key string, value Operation) {\n\tc.registry[key] = value\n\n}\n\nfunc (c *Calculator) Calculus(key string, a float64, b float64) float64 {\n\tv, ok := c.registry[key]\n\tif !ok {\n\t\tfmt.Printf(\" Operation %v not yet allowed\\n\", key)\n\t\treturn 0.0\n\n\t} else {\n\t\treturn v.Execute(a, b)\n\t}\n\n}\n\nfunc main() {\n\t// falsch\n\tfmt.Println((\"InCorrect\"))\n\tshape := []Shape{\n\t\t{a: 12.0, b: 13.0, name: \"rectangle\"},\n\t\t{a: 11, b: 3, name: \"triangle\"},\n\t\t{a: 2, b: 2, name: \"square\"},\n\t}\n\n\tfor _, v := range shape {\n\t\tv.Area()\n\t\tv.Result()\n\n\t}\n\n\t// Richtig\n\tfmt.Println((\"Correct\"))\n\n\tsquare := &square{a: 12, BaseForm: BaseForm{name: \"square\"}}\n\ttriangle := &triangle{a: 2, b: 5, BaseForm: BaseForm{name: \"triangle\"}}\n\trectangle := &rectangle{a: 5, b: 6, BaseForm: BaseForm{name: \"rectangle\"}}\n\n\tform := []AreaCalculator{square, triangle, rectangle}\n\n\tfor _, i := range form {\n\t\ti.Area()\n\t\ti.Result()\n\t}\n\n\t// extra\n\tfmt.Println(\"EXTRA\")\n\tcalculator := Calculator{}\n\tcalculator.Init()\n\n\tcalculator.Registry(\"+\", &Sum{})\n\tcalculator.Registry(\"-\", &Rest{})\n\tcalculator.Registry(\"*\", &Mult{})\n\tcalculator.Registry(\"/\", &Dv{})\n\tcalculator.Registry(\"^\", &Pw{})\n\n\tfmt.Println(calculator.Calculus(\"+\", 20, 40))\n\tfmt.Println(calculator.Calculus(\"-\", 20, 40))\n\tfmt.Println(calculator.Calculus(\"*\", 20, 40))\n\tfmt.Println(calculator.Calculus(\"/\", 20, 40))\n\tfmt.Println(calculator.Calculus(\"^\", 20, 4))\n}\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/java/AmadorQuispe.java",
    "content": "package com.amsoft.roadmap.example27;\n\nimport java.util.Map;\n\npublic class Example27 {\n    public static void main(String[] args) {\n        Report report = new HTMLReport();\n        report.generate();\n\n        Calculator calculator = new Calculator();\n        System.out.println(\"La suma de 5 + 6 es: \" + calculator.calculate(new Addition(),5,6));\n        System.out.println(\"La resta de 10 - 6 es: \" + calculator.calculate(new Subtraction(),10,6));\n        System.out.println(\"La multiplicación de 10 * 6 es: \" + calculator.calculate(new Multiplication(),10,6));\n        System.out.println(\"La división de 10 / 2 es: \" + calculator.calculate(new Division(),10,2));\n        System.out.println(\"La potencia de 9 elevado 3 es: \" + calculator.calculate(new Pow(),9,3));\n    }\n}\n//Viola OCP, si queremos agregar un reporte Excel debemos modificar la clase, agregando un if\n/*class ReportGenerator{\n    public void generateReport(String type){\n        if(type.equals(\"PDF\")){\n            System.out.println(\"Generando reporte PDF\");\n        } else if (type.equals(\"HTML\")) {\n            System.out.println(\"Generando reporte HTML\");\n        }\n    }\n}*/\n\n\n//Cumple OCP, declaramos un interfaz con un método que debe implementar las clases concretas\n//Si queremos agregar un reporte Excel simplemente creamos una clase que implementa la interfaz\ninterface Report{\n    void generate();\n}\n\nclass PDFReport implements Report{\n\n    @Override\n    public void generate() {\n        System.out.println(\"Generando reporte PDF\");\n    }\n}\n\nclass HTMLReport implements Report{\n\n    @Override\n    public void generate() {\n        System.out.println(\"Generando reporte HTML\");\n    }\n}\n\n\n\n\n//EXTRA\ninterface Operable {\n    double calculate(double num1,double num2);\n}\n\nclass Addition implements Operable {\n\n    @Override\n    public double calculate(double num1, double num2) {\n        return num1 + num2;\n    }\n}\n\nclass Subtraction implements Operable {\n\n    @Override\n    public double calculate(double num1, double num2) {\n        return num1 - num2;\n    }\n}\n\nclass Multiplication implements Operable{\n\n    @Override\n    public double calculate(double num1, double num2) {\n        return num1 * num2;\n    }\n}\n\nclass Division implements Operable {\n\n    @Override\n    public double calculate(double num1, double num2) {\n        return num1/num2;\n    }\n}\n\nclass Calculator {\n    public double calculate(Operable operation, double num1, double num2){\n        return operation.calculate(num1,num2);\n    }\n}\nclass Pow implements Operable {\n\n    @Override\n    public double calculate(double num1, double num2) {\n        return Math.pow(num1,num2);\n    }\n}"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/java/AnaLauDB.java",
    "content": "import java.util.*;\n\npublic class AnaLauDB {\n\n    // ==========================================================================\n    // IMPLEMENTACIÓN QUE CUMPLE EL PRINCIPIO ABIERTO/CERRADO (OCP)\n    // ==========================================================================\n\n    // Interfaz que define el contrato para las operaciones\n    interface Operacion {\n        double calcular(double a, double b);\n\n        String getNombre();\n\n        String getSimbolo();\n    }\n\n    // Implementación de la operación Suma\n    static class Suma implements Operacion {\n        @Override\n        public double calcular(double a, double b) {\n            return a + b;\n        }\n\n        @Override\n        public String getNombre() {\n            return \"Suma\";\n        }\n\n        @Override\n        public String getSimbolo() {\n            return \"+\";\n        }\n    }\n\n    // Implementación de la operación Resta\n    static class Resta implements Operacion {\n        @Override\n        public double calcular(double a, double b) {\n            return a - b;\n        }\n\n        @Override\n        public String getNombre() {\n            return \"Resta\";\n        }\n\n        @Override\n        public String getSimbolo() {\n            return \"-\";\n        }\n    }\n\n    // Implementación de la operación Multiplicación\n    static class Multiplicacion implements Operacion {\n        @Override\n        public double calcular(double a, double b) {\n            return a * b;\n        }\n\n        @Override\n        public String getNombre() {\n            return \"Multiplicación\";\n        }\n\n        @Override\n        public String getSimbolo() {\n            return \"*\";\n        }\n    }\n\n    // Implementación de la operación División\n    static class Division implements Operacion {\n        @Override\n        public double calcular(double a, double b) {\n            if (b == 0) {\n                throw new ArithmeticException(\"No se puede dividir por cero\");\n            }\n            return a / b;\n        }\n\n        @Override\n        public String getNombre() {\n            return \"División\";\n        }\n\n        @Override\n        public String getSimbolo() {\n            return \"/\";\n        }\n    }\n\n    // ==========================================================================\n    // NUEVA OPERACIÓN AGREGADA SIN MODIFICAR CÓDIGO EXISTENTE (OCP)\n    // ==========================================================================\n\n    // Implementación de la operación Potencia - NUEVA OPERACIÓN\n    static class Potencia implements Operacion {\n        @Override\n        public double calcular(double a, double b) {\n            return Math.pow(a, b);\n        }\n\n        @Override\n        public String getNombre() {\n            return \"Potencia\";\n        }\n\n        @Override\n        public String getSimbolo() {\n            return \"^\";\n        }\n    }\n\n    // Calculadora que utiliza las operaciones - CERRADA PARA MODIFICACIÓN\n    static class Calculadora {\n        private Map<String, Operacion> operaciones;\n\n        public Calculadora() {\n            this.operaciones = new HashMap<>();\n        }\n\n        // Método para registrar nuevas operaciones - ABIERTA PARA EXTENSIÓN\n        public void registrarOperacion(String codigo, Operacion operacion) {\n            operaciones.put(codigo.toLowerCase(), operacion);\n            System.out.println(\"Operación registrada: \" + operacion.getNombre() +\n                    \" (\" + operacion.getSimbolo() + \")\");\n        }\n\n        // Método para realizar cálculos\n        public double calcular(String tipoOperacion, double a, double b) {\n            Operacion operacion = operaciones.get(tipoOperacion.toLowerCase());\n\n            if (operacion == null) {\n                throw new IllegalArgumentException(\"Operación no soportada: \" + tipoOperacion);\n            }\n\n            double resultado = operacion.calcular(a, b);\n            System.out.printf(\"%.2f %s %.2f = %.2f%n\",\n                    a, operacion.getSimbolo(), b, resultado);\n\n            return resultado;\n        }\n\n        // Método para mostrar operaciones disponibles\n        public void mostrarOperacionesDisponibles() {\n            System.out.println(\"\\n=== Operaciones Disponibles ===\");\n            for (Map.Entry<String, Operacion> entry : operaciones.entrySet()) {\n                Operacion op = entry.getValue();\n                System.out.printf(\"Código: '%s' - %s (%s)%n\",\n                        entry.getKey(), op.getNombre(), op.getSimbolo());\n            }\n            System.out.println();\n        }\n    }\n\n    // ==========================================================================\n    // EJEMPLO DE EXTENSIBILIDAD - OPERACIONES ADICIONALES\n    // ==========================================================================\n\n    // Operación de módulo - OTRA NUEVA OPERACIÓN\n    static class Modulo implements Operacion {\n        @Override\n        public double calcular(double a, double b) {\n            if (b == 0) {\n                throw new ArithmeticException(\"No se puede calcular módulo con divisor cero\");\n            }\n            return a % b;\n        }\n\n        @Override\n        public String getNombre() {\n            return \"Módulo\";\n        }\n\n        @Override\n        public String getSimbolo() {\n            return \"%\";\n        }\n    }\n\n    // Operación de raíz cuadrada - OPERACIÓN UNARIA (usa solo el primer parámetro)\n    static class RaizCuadrada implements Operacion {\n        @Override\n        public double calcular(double a, double b) {\n            // Ignora el segundo parámetro para operaciones unarias\n            if (a < 0) {\n                throw new ArithmeticException(\"No se puede calcular raíz cuadrada de número negativo\");\n            }\n            return Math.sqrt(a);\n        }\n\n        @Override\n        public String getNombre() {\n            return \"Raíz Cuadrada\";\n        }\n\n        @Override\n        public String getSimbolo() {\n            return \"√\";\n        }\n    }\n\n    public static void main(String[] args) {\n        System.out.println(\"=== DEMOSTRACIÓN DEL PRINCIPIO ABIERTO/CERRADO (OCP) ===\");\n\n        // Crear calculadora\n        Calculadora calc = new Calculadora();\n\n        // 1. Implementar las operaciones básicas\n        System.out.println(\"1. Registrando operaciones básicas:\");\n        calc.registrarOperacion(\"suma\", new Suma());\n        calc.registrarOperacion(\"resta\", new Resta());\n        calc.registrarOperacion(\"multiplicacion\", new Multiplicacion());\n        calc.registrarOperacion(\"division\", new Division());\n\n        // 2. Comprobar que el sistema funciona\n        System.out.println(\"\\n2. Probando operaciones básicas:\");\n        calc.mostrarOperacionesDisponibles();\n\n        try {\n            calc.calcular(\"suma\", 10, 5);\n            calc.calcular(\"resta\", 10, 5);\n            calc.calcular(\"multiplicacion\", 10, 5);\n            calc.calcular(\"division\", 10, 5);\n        } catch (Exception e) {\n            System.out.println(\"Error: \" + e.getMessage());\n        }\n\n        // 3. Agregar quinta operación (Potencia) SIN MODIFICAR código existente\n        System.out.println(\"\\n3. Agregando nueva operación (Potencia) - SIN MODIFICAR código existente:\");\n        calc.registrarOperacion(\"potencia\", new Potencia());\n\n        // 4. Comprobar que se cumple el OCP\n        System.out.println(\"\\n4. Verificando OCP - La calculadora ahora soporta potencias:\");\n        calc.mostrarOperacionesDisponibles();\n\n        try {\n            calc.calcular(\"potencia\", 2, 3); // 2^3 = 8\n            calc.calcular(\"potencia\", 5, 2); // 5^2 = 25\n        } catch (Exception e) {\n            System.out.println(\"Error: \" + e.getMessage());\n        }\n\n        // Demostrar extensibilidad adicional\n        System.out.println(\"\\n5. Demostrando extensibilidad adicional:\");\n        calc.registrarOperacion(\"modulo\", new Modulo());\n        calc.registrarOperacion(\"raiz\", new RaizCuadrada());\n\n        calc.mostrarOperacionesDisponibles();\n\n        try {\n            calc.calcular(\"modulo\", 10, 3); // 10 % 3 = 1\n            calc.calcular(\"raiz\", 16, 0); // √16 = 4 (ignora segundo parámetro)\n        } catch (Exception e) {\n            System.out.println(\"Error: \" + e.getMessage());\n        }\n\n        // Demostrar manejo de errores\n        System.out.println(\"\\n6. Demostrando manejo de errores:\");\n        try {\n            calc.calcular(\"division\", 10, 0); // Error: división por cero\n        } catch (Exception e) {\n            System.out.println(\"Error capturado: \" + e.getMessage());\n        }\n\n        try {\n            calc.calcular(\"raiz\", -4, 0); // Error: raíz de número negativo\n        } catch (Exception e) {\n            System.out.println(\"Error capturado: \" + e.getMessage());\n        }\n\n        System.out.println(\"\\n=== CONCLUSIÓN ===\");\n        System.out.println(\"El sistema cumple el OCP porque:\");\n        System.out.println(\"   - CERRADO para modificación: No modificamos la clase Calculadora\");\n        System.out.println(\"   - ABIERTO para extensión: Agregamos nuevas operaciones fácilmente\");\n        System.out.println(\"   - Cada nueva operación implementa la interfaz Operacion\");\n        System.out.println(\"   - El comportamiento se extiende sin romper código existente\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/java/DiegoSilvaL.java",
    "content": "public interface DiegoSilvaL {\n    static void main(String... args) {\n        // Ejemplo sin usar OCP\n        var triangle = new Triangle(10, 3);\n        System.out.printf(\"El área del triángulo es: %f%n\", getArea(triangle));\n        var circle = new Circle(10);\n        System.out.printf(\"El área del círculo es  : %f%n\", getArea(circle));\n\n        // Ejemplo usando OCP\n        var ocpTriangle = new OcpTriangle(10, 3);\n        System.out.printf(\"El área del triángulo es: %f%n\", getArea(ocpTriangle));\n        var ocpCircle = new OcpCircle(10);\n        System.out.printf(\"El área del círculo es  : %f%n\", getArea(ocpCircle));\n\n        // Dificultad Extra\n        System.out.printf(\"La suma     es:%f%n\", getCalculate(new Addition(), 10, 20));\n        System.out.printf(\"La resta    es:%f%n\", getCalculate(new Subtraction(), 10, 20));\n        System.out.printf(\"El producto es:%f%n\", getCalculate(new Multiplication(), 10, 20));\n        System.out.printf(\"El cociente es:%f%n\", getCalculate(new Division(), 10, 20));\n        System.out.printf(\"La potencia es:%f%n\", getCalculate(new Power(), 10, 20));\n\n    }\n\n    /**\n     * Obteniendo el área de una figura sin usar OCP.\n     * Cada vez que hay una nueva figura, se deberá modificar esta función agregando\n     * una condición más\n     * \n     * @param iShape\n     * @return el área de la figura\n     */\n    static double getArea(IShape iShape) {\n        if (iShape instanceof Circle circle)\n            return circle.getRadius() * circle.getRadius() * Math.PI;\n        if (iShape instanceof Triangle triangle)\n            return triangle.getBase() * triangle.getHeight() / 2.0;\n        return 0.0;\n    }\n\n    /**\n     * Obteniendo el área de una figura usando OCP.\n     * Como se ve en el código, no necesita conocerse cómo se cálcula cada área.\n     * Éste está en la implementación de cada figura.\n     * \n     * @param iShape\n     * @return el área de la figura\n     */\n    static double getArea(IOcpShape iShape) {\n        return iShape.getArea();\n    }\n\n    static double getCalculate(CalculatorTwoNumbers calculator, double a, double b) {\n        return calculator.calculate(a, b);\n    }\n}\n\n/**\n * Interfaz genérica para que se puedan utilizar las figuras\n */\ninterface IShape {\n\n}\n\nclass Triangle implements IShape {\n    private final double base;\n    private final double height;\n\n    public Triangle(double base, double height) {\n        this.base = base;\n        this.height = height;\n    }\n\n    public double getBase() {\n        return base;\n    }\n\n    public double getHeight() {\n        return height;\n    }\n\n}\n\nclass Circle implements IShape {\n    private final double radius;\n\n    public Circle(double radius) {\n        this.radius = radius;\n    }\n\n    public double getRadius() {\n        return radius;\n    }\n\n}\n\n/**\n * Interfaz preparada para aplicar OCP\n * \n */\ninterface IOcpShape {\n    /**\n     * El cálculo del área de cada figura depende de la implementación de la figura\n     * \n     * @return\n     */\n    double getArea();\n}\n\nclass OcpTriangle implements IOcpShape {\n    private final double base;\n    private final double height;\n\n    public OcpTriangle(double base, double height) {\n        this.base = base;\n        this.height = height;\n    }\n\n    public double getBase() {\n        return base;\n    }\n\n    public double getHeight() {\n        return height;\n    }\n\n    @Override\n    public double getArea() {\n        return height * base / 2.0;\n    }\n\n}\n\nclass OcpCircle implements IOcpShape {\n    private final double radius;\n\n    public OcpCircle(double radius) {\n        this.radius = radius;\n    }\n\n    public double getRadius() {\n        return radius;\n    }\n\n    @Override\n    public double getArea() {\n        return radius * radius * Math.PI;\n    }\n\n}\n\n/**\n * Interfaz de calculadora que permite el cálculo con dos números\n */\ninterface CalculatorTwoNumbers {\n    double calculate(double a, double b);\n}\n\nclass Addition implements CalculatorTwoNumbers {\n\n    @Override\n    public double calculate(double a, double b) {\n        return a + b;\n    }\n\n}\n\nclass Subtraction implements CalculatorTwoNumbers {\n    @Override\n    public double calculate(double a, double b) {\n        return a - b;\n    }\n}\n\nclass Multiplication implements CalculatorTwoNumbers {\n    @Override\n    public double calculate(double a, double b) {\n        return a * b;\n    }\n}\n\nclass Division implements CalculatorTwoNumbers {\n    @Override\n    public double calculate(double a, double b) {\n        return a / b;\n    }\n}\n\nclass Power implements CalculatorTwoNumbers {\n    @Override\n    public double calculate(double a, double b) {\n        return Math.pow(a, b);\n    }\n}"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/java/FranDev200.java",
    "content": "package com.amsoft.roadmap.example27;\n\npublic class FranDev200 {\n\n\n    interface MetodoPago{\n        public void pago();\n    }\n\n    static class PagoBizum implements MetodoPago{\n        public void pago(){\n            System.out.println(\"Pagando con bizum.\");\n        }\n    }\n\n    static class PagoTarjeta implements MetodoPago{\n        public void pago(){\n            System.out.println(\"Pagando con tarjeta.\");\n        }\n    }\n\n    static class PagoPayPal implements MetodoPago{\n        public void pago(){\n            System.out.println(\"Pagando con paypal.\");\n        }\n    }\n\n    static class PagoTransaccion implements MetodoPago{\n        public void pago(){\n            System.out.println(\"Pagando con transaccion.\");\n        }\n    }\n\n    static class Datafono{\n\n        public void pagar(MetodoPago metodoPago){\n            metodoPago.pago();\n        }\n\n    }\n\n    static void main() {\n\n        /*\n\n        EJERCICIO:\n         * Explora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\"\n         * y crea un ejemplo simple donde se muestre su funcionamiento\n         * de forma correcta e incorrecta.\n\n         */\n\n        Datafono df = new Datafono();\n        df.pagar(new PagoBizum());\n        df.pagar(new PagoTarjeta());\n        df.pagar(new PagoPayPal());\n\n        // AÑADO UN METODO MÁS DE PAGO. SOLO TENGO QUE AÑADIR UNA CLASE QUE IMPLEMENTE LA INTERFAZ, CUMPLO OCP\n        df.pagar(new PagoTransaccion());\n\n\n        /*\n\n            DIFICULTAD EXTRA (opcional):\n             * Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas.\n             * Requisitos:\n             * - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n             * Instrucciones:\n             * 1. Implementa las operaciones de suma, resta, multiplicación y división.\n             * 2. Comprueba que el sistema funciona.\n             * 3. Agrega una quinta operación para calcular potencias.\n             * 4. Comprueba que se cumple el OCP.\n\n         */\n\n        Calculadora calculadora = new Calculadora();\n\n        System.out.println(\"\\n===============\");\n        System.out.println(\"EJERCICIO EXTRA\");\n        System.out.println(\"===============\");\n\n        System.out.println(\"-SUMA\");\n        System.out.println(\"-----------\");\n        System.out.println(\"4 + 7 = \" + calculadora.calcular(new Suma(), 4, 7));\n        System.out.println(\"===========\");\n        System.out.println(\"-RESTA\");\n        System.out.println(\"-----------\");\n        System.out.println(\"4 - 7 = \" + calculadora.calcular(new Resta(), 4, 7));\n        System.out.println(\"===========\");\n        System.out.println(\"-MULTIPLICACION\");\n        System.out.println(\"-----------\");\n        System.out.println(\"4 * 7 = \" + calculadora.calcular(new Multiplicacion(), 4, 7));\n        System.out.println(\"===========\");\n        System.out.println(\"-DIVISION\");\n        System.out.println(\"-----------\");\n        System.out.println(\"7 / 4 = \" + calculadora.calcular(new Division(), 7, 4));\n        System.out.println(\"===========\");\n        System.out.println(\"-POTENCIA\");\n        System.out.println(\"-----------\");\n        System.out.println(\"2 ^ 3 = \" + calculadora.calcular(new Potencia(), 2, 3));\n        System.out.println(\"===========\");\n\n    }\n\n    interface Calculo{\n        public double calcular(int a,  int b);\n    }\n\n    static class Suma implements Calculo{\n        @Override\n        public double calcular(int a, int b) {\n            return a + b;\n        }\n    }\n\n    static class Resta implements Calculo{\n        @Override\n        public double calcular(int a, int b) {\n            return a - b;\n        }\n    }\n\n    static class Multiplicacion implements Calculo{\n        @Override\n        public double calcular(int a, int b) {\n            return a * b;\n        }\n    }\n\n    static class Division implements Calculo{\n        @Override\n        public double calcular(int a, int b) {\n            return (double) a / b;\n        }\n    }\n\n    static class Potencia implements Calculo{\n        @Override\n        public double calcular(int a, int b) {\n            return Math.pow(a, b);\n        }\n    }\n\n    static class Calculadora{\n\n        public double calcular(Calculo calculo, int a, int b) {\n            return calculo.calcular(a, b);\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/java/Josegs95.java",
    "content": "public class Josegs95 {\n    public static void main(String[] args) {\n        //Ejercicio\n        //Forma incorrecta\n        Object object1 = new WrongHuman();\n        if (object1 instanceof WrongHuman)\n            System.out.println(\"Los humanos se mueven a dos patas\");\n        else if (object1 instanceof WrongCat)\n            System.out.println(\"Los gatos se mueven a cuatro patas\");\n        else if (object1 instanceof WrongPigeon)\n            System.out.println(\"Las palomas se mueven por el aire volando\");\n        else\n            System.out.println(\"Animal desconocido\");\n\n        //Forma correcta\n        Object object2 = new Cat();\n        if (object2 instanceof Animal)\n            ((Animal) object2).move();\n        else\n            System.out.println(\"Animal desconocido\");\n\n        //Reto\n        retoFinal();\n    }\n\n    public static void retoFinal(){\n        double result = Calculator.calculate(Calculator.Operations.SUMAR, 7, 8);\n        System.out.println(\"7 + 8 = \" + result);\n\n        result = Calculator.calculate(Calculator.Operations.RESTAR, 1, 2.5);\n        System.out.println(\"1 - 2.5 = \" + result);\n\n        result = Calculator.calculate(Calculator.Operations.MULTIPLICAR, 1.3, 4.6);\n        System.out.println(\"1.3 * 4.6 = \" + result);\n\n        result = Calculator.calculate(Calculator.Operations.DIVIDIR, 2, 1.5);\n        System.out.println(\"2 / 1.5 = \" + result);\n\n        result = Calculator.calculate(Calculator.Operations.POTENCIA, 5, 5);\n        System.out.println(\"5 ^ 5 = \" + result);\n    }\n\n    public static class WrongHuman{}\n    public static class WrongCat{}\n    public static class WrongPigeon {}\n\n    public interface Animal{\n        public void move();\n    }\n    public static class Human implements Animal{\n        public void move(){\n            System.out.println(\"Los humanos se mueven a dos patas\");\n        }\n    }\n    public static class Cat implements Animal{\n        public void move(){\n            System.out.println(\"Los gatos se mueven a cuatro patas\");\n        }\n    }\n    public static class Pigeon implements Animal{\n        public void move(){\n            System.out.println(\"Las palomas se mueven por el aire volando\");\n        }\n    }\n\n    public class Calculator{\n        public enum Operations{\n            SUMAR(new Sum()),\n            RESTAR(new Subtract()),\n            MULTIPLICAR(new Multiply()),\n            DIVIDIR(new Divide()),\n            POTENCIA(new Power());\n\n            private Operation operation;\n\n            Operations (Operation operation){\n                this.operation = operation;\n            }\n\n            public Operation getOperation(){\n                return operation;\n            }\n\n        }\n\n        public static double calculate(Operations operation, double n1, double n2){\n            return operation.getOperation().execute(n1, n2);\n        }\n\n    }\n    public interface Operation{\n        public double execute(double n1, double n2);\n    }\n    public static class Sum implements Operation{\n\n        public double execute(double n1, double n2) {\n            return n1 + n2;\n        }\n    }\n    public static class Subtract implements Operation{\n\n        @Override\n        public double execute(double n1, double n2) {\n            return n1 - n2;\n        }\n    }\n    public static class Multiply implements Operation{\n\n        @Override\n        public double execute(double n1, double n2) {\n            return n1 * n2;\n        }\n    }\n    public static class Divide implements Operation{\n\n        @Override\n        public double execute(double n1, double n2) {\n            return n1 / n2;\n        }\n    }\n    public static class Power implements Operation{\n\n        @Override\n        public double execute(double n1, double n2) {\n            double result = 1;\n            for (int i = 0; i < n2; i++)\n                result *= n1;\n            return result;\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/java/asjordi.java",
    "content": "/*\n    El Principio Abierto/Cerrado (OCP) establece que una clase debe estar abierta para extensión, pero cerrada para modificación.\n    Modificación significa cambiar el código de una clase ya existente, mientras que extensión significa agregar nuevas funcionalidades.\n    Por lo general, esto se realizará con interfaces y clases abstractas.\n */\n\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class Main {\n\n    public static void main(String[] args) {\n        Calculadora calculadora = new Calculadora();\n        calculadora.agregarOperacion(\"suma\", new Suma());\n        calculadora.agregarOperacion(\"resta\", new Resta());\n        calculadora.agregarOperacion(\"multiplicacion\", new Multiplicacion());\n        calculadora.agregarOperacion(\"division\", new Division());\n        calculadora.agregarOperacion(\"potencia\", new Potencia());\n\n        System.out.println(calculadora.ejecutarOperacion(\"suma\", 5, 3));\n        System.out.println(calculadora.ejecutarOperacion(\"resta\", 5, 3));\n        System.out.println(calculadora.ejecutarOperacion(\"multiplicacion\", 5, 3));\n        System.out.println(calculadora.ejecutarOperacion(\"division\", 5, 3));\n        System.out.println(calculadora.ejecutarOperacion(\"potencia\", 5, 3));\n    }\n\n    /*\n        EJERCICIO:\n        Explora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\"\n        y crea un ejemplo simple donde se muestre su funcionamiento de forma correcta e incorrecta.\n     */\n    static class Factura {\n        // Atributos\n        // Constructor\n        // Métodos\n    }\n\n    static class FacturaPersistencia {\n        Factura factura;\n\n        public FacturaPersistencia(Factura factura) {\n            this.factura = factura;\n        }\n\n        public void guardarEnArchivo(String nombre) {\n            // Guardar la factura en un archivo con el nombre especificado\n        }\n\n        public void guardarEnBaseDeDatos() {\n            // Guardar la factura en la base de datos\n        }\n    }\n\n    /*\n        Aplicando el Principio Abierto/Cerrado (OCP) se puede crear una interfaz IFacturaPersistencia con un método guardar(Factura factura)\n        y dos clases que implementen esta interfaz, una para guardar en la base de datos y otra para guardar en un archivo.\n        De esta forma, si se quiere agregar una nueva forma de persistencia, se puede crear una nueva clase que implemente la interfaz\n        sin tener que modificar las clases existentes.\n        Incluso, crear una clase que administre diferentes formas de persistencia, como se muestra en el ejemplo.\n     */\n    interface IFacturaPersistencia {\n        void guardar(Factura factura);\n    }\n\n    interface ILibroPersistencia {\n        void guardar(Factura factura);\n    }\n\n    static class BaseDeDatosPersistencia implements IFacturaPersistencia {\n        @Override\n        public void guardar(Factura factura) {\n            // Guardar la factura en la base de datos\n        }\n    }\n\n    public class ArchivoPersistencia implements IFacturaPersistencia {\n        @Override\n        public void guardar(Factura factura) {\n            // Guardar la factura en un archivo con el nombre especificado\n        }\n    }\n\n    static class AdministradorPersistencia {\n        IFacturaPersistencia facturaPersistencia;\n        ILibroPersistencia libroPersistencia;\n\n        public AdministradorPersistencia(IFacturaPersistencia facturaPersistencia, ILibroPersistencia libroPersistencia) {\n            this.facturaPersistencia = facturaPersistencia;\n            this.libroPersistencia = libroPersistencia;\n        }\n    }\n\n    /*\n        DIFICULTAD EXTRA (opcional):\n        Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas.\n        Requisitos:\n        - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n        Instrucciones:\n        1. Implementa las operaciones de suma, resta, multiplicación y división.\n        2. Comprueba que el sistema funciona.\n        3. Agrega una quinta operación para calcular potencias.\n        4. Comprueba que se cumple el OCP.\n     */\n\n    interface IOperacion {\n        double calcular(double a, double b);\n    }\n\n    static class Suma implements IOperacion {\n        @Override\n        public double calcular(double a, double b) {\n            return a + b;\n        }\n    }\n\n    static class Resta implements IOperacion {\n        @Override\n        public double calcular(double a, double b) {\n            return a - b;\n        }\n    }\n\n    static class Multiplicacion implements IOperacion {\n        @Override\n        public double calcular(double a, double b) {\n            return a * b;\n        }\n    }\n\n    static class Division implements IOperacion {\n        @Override\n        public double calcular(double a, double b) {\n            if (b == 0) throw new IllegalArgumentException(\"No se puede dividir por cero\");\n            return a / b;\n        }\n    }\n\n    static class Potencia implements IOperacion {\n        @Override\n        public double calcular(double a, double b) {\n            return Math.pow(a, b);\n        }\n    }\n\n    static class Calculadora {\n        private Map<String, IOperacion> operaciones;\n\n        public Calculadora() {\n            this.operaciones = new HashMap<>();\n        }\n\n        public void agregarOperacion(String nombre, IOperacion operacion) {\n            if (!this.operaciones.containsKey(nombre)) this.operaciones.put(nombre, operacion);\n            else throw new IllegalArgumentException(\"La operación ya existe\");\n        }\n\n        public double ejecutarOperacion(String nombre, double a, double b) {\n            IOperacion op = this.operaciones.get(nombre);\n            if (op == null) throw new IllegalArgumentException(\"Operación no encontrada\");\n            return op.calcular(a, b);\n        }\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/java/danhingar.java",
    "content": "import java.util.HashMap;\nimport java.util.Map;\n\npublic class danhingar {\n\n    public static void main(String[] args) {\n        Form1 square = new Square();\n        square.draw();\n\n        Form1 circle = new Circle();\n        circle.draw();\n\n        Form1 triangle = new Triangle();\n        triangle.draw();\n\n        //Extra \n        Calculator calculator = new Calculator();\n\n        calculator.addOperation(\"addition\", new Addition());\n        calculator.addOperation(\"substration\", new Substration());\n        calculator.addOperation(\"multiplication\", new Multiplication());\n        calculator.addOperation(\"division\", new Division());\n        calculator.addOperation(\"power\", new Power());\n\n        System.out.printf(\"Resultado %f\\n\",calculator.calculate(\"addition\",5.0,3.5));\n        System.out.printf(\"Resultado %f\\n\",calculator.calculate(\"substration\",10.0,4.0));\n        System.out.printf(\"Resultado %f\\n\",calculator.calculate(\"multiplication\",5.0,3.0));\n        System.out.printf(\"Resultado %f\\n\",calculator.calculate(\"division\",20.0,5.0));\n        System.out.printf(\"Resultado %f\\n\",calculator.calculate(\"power\",2.0,2.0));\n        System.out.printf(\"Resultado %f\\n\",calculator.calculate(\"example\",2.0,2.0));\n    }\n    \n\n}\n\n//Incorrecta\nclass Form {\n\n    public void drawSquare(){\n        System.out.println(\"Dibujar un cuadrado\");\n    }\n\n    public void drawCircle(){\n        System.out.println(\"Dibujar un círculo\");\n    }\n\n    public void drawTriangle(){\n        System.out.println(\"Dibujar un círculo\");\n    }\n    \n}\n\n//Forma correcta\n\ninterface Form1 {\n\n    void draw();\n}  \n\n\nclass Square implements Form1 {\n\n    @Override\n    public void draw() {\n        System.out.println(\"Dibuja un cuadrado\");\n    }\n\n    \n}\n\nclass Circle implements Form1 {\n\n    @Override\n    public void draw() {\n        System.out.println(\"Dibuja un círculo\");\n    }\n\n    \n}\n\nclass Triangle implements Form1 {\n\n    @Override\n    public void draw() {\n        System.out.println(\"Dibuja un triángulo\");\n    }\n\n    \n}\n\n\n\n//EXTRA\n\ninterface Operation {\n\n    Double operate(Double num1,Double num2);\n    \n}\n    \nclass Addition implements Operation {\n\n    @Override\n    public Double operate(Double num1, Double num2) {\n        return num1+num2;\n    }\n}\n\nclass Substration implements Operation {\n\n    @Override\n    public Double operate(Double num1, Double num2) {\n        return num1-num2;\n    }\n}\n\nclass Multiplication implements Operation {\n\n    @Override\n    public Double operate(Double num1, Double num2) {\n        return num1*num2;\n    }\n}\n\nclass Division implements Operation {\n\n    @Override\n    public Double operate(Double num1, Double num2) {\n        return num1/num2;\n    }\n}\n\nclass Power implements Operation {\n\n    @Override\n    public Double operate(Double num1, Double num2) {\n        return Math.pow(num1, num2);\n    }\n}\n\n class Calculator {\n\n    Map<String,Operation> operations;\n    \n    public Calculator(){\n        this.operations = new HashMap<>();\n    }\n\n    public void addOperation(String name, Operation operation){\n        operations.put(name, operation);\n    }\n\n    public double calculate(String name, double num1, double num2){\n        if(!operations.containsKey(name)){\n            throw new IllegalArgumentException(\"La operación \"+name+\" no es válida\");\n        }\n        return operations.get(name).operate(num1, num2);\n    }\n\n    \n}\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/java/eulogioep.java",
    "content": "/*\n * PRINCIPIO ABIERTO-CERRADO (OCP)\n * \n * El principio establece que las entidades de software (clases, módulos, funciones, etc.) \n * deberían estar:\n * - ABIERTAS para la extensión: Podemos agregar nuevo comportamiento\n * - CERRADAS para la modificación: No debemos modificar el código existente\n * \n * Beneficios:\n * 1. Código más mantenible y escalable\n * 2. Reduce el riesgo de bugs en código existente\n * 3. Facilita la adición de nuevas funcionalidades\n */\n\n import java.util.HashMap;\n import java.util.Map;\n import java.util.Set;\n import java.util.stream.Collectors;\n \n public class eulogioep {\n     public static void main(String[] args) {\n         // Creamos una instancia de la calculadora\n         Calculator calculator = new Calculator();\n \n         // Registramos las operaciones básicas\n         calculator.registerOperation(new Addition());\n         calculator.registerOperation(new Subtraction());\n         calculator.registerOperation(new Multiplication());\n         calculator.registerOperation(new Division());\n \n         // Mostramos las operaciones disponibles\n         System.out.println(\"Operaciones disponibles:\");\n         calculator.getAvailableOperations().forEach(op -> \n             System.out.println(\"- \" + op.getName() + \" (\" + op.getSymbol() + \")\")\n         );\n \n         // Probamos las operaciones básicas\n         System.out.println(\"\\nProbando operaciones básicas:\");\n         testOperation(calculator, 10.0, 5.0, \"+\");\n         testOperation(calculator, 10.0, 5.0, \"-\");\n         testOperation(calculator, 10.0, 5.0, \"*\");\n         testOperation(calculator, 10.0, 5.0, \"/\");\n \n         // Agregamos una nueva operación (potencia) sin modificar el código existente\n         calculator.registerOperation(new Power());\n         System.out.println(\"\\nProbando nueva operación (potencia):\");\n         testOperation(calculator, 2.0, 3.0, \"^\");\n \n         // Probamos el manejo de errores\n         System.out.println(\"\\nProbando manejo de errores:\");\n         testOperation(calculator, 5.0, 0.0, \"/\");  // División por cero\n         testOperation(calculator, 5.0, 2.0, \"%\");  // Operación no existente\n     }\n \n     private static void testOperation(Calculator calculator, double a, double b, String symbol) {\n         try {\n             OperationResult result = calculator.calculate(a, b, symbol);\n             System.out.println(result);\n         } catch (Exception e) {\n             System.out.println(\"Error: \" + e.getMessage());\n         }\n     }\n }\n \n // EJEMPLO INCORRECTO (Violando OCP)\n class BadCalculator {\n     public double calculate(double a, double b, String operation) {\n         switch (operation) {\n             case \"sum\":\n                 return a + b;\n             case \"subtract\":\n                 return a - b;\n             case \"multiply\":\n                 return a * b;\n             case \"divide\":\n                 return a / b;\n             // Si queremos agregar una nueva operación, debemos modificar esta clase\n             // violando el principio OCP\n             default:\n                 throw new IllegalArgumentException(\"Operación no soportada\");\n         }\n     }\n }\n \n // EJEMPLO CORRECTO (Siguiendo OCP)\n // Definimos una interfaz para las operaciones\n interface Operation {\n     double execute(double a, double b) throws ArithmeticException;\n     String getSymbol();\n     String getName();\n }\n \n // Implementamos cada operación como una clase separada\n class Addition implements Operation {\n     @Override\n     public double execute(double a, double b) {\n         return a + b;\n     }\n \n     @Override\n     public String getSymbol() {\n         return \"+\";\n     }\n \n     @Override\n     public String getName() {\n         return \"Suma\";\n     }\n }\n \n class Subtraction implements Operation {\n     @Override\n     public double execute(double a, double b) {\n         return a - b;\n     }\n \n     @Override\n     public String getSymbol() {\n         return \"-\";\n     }\n \n     @Override\n     public String getName() {\n         return \"Resta\";\n     }\n }\n \n class Multiplication implements Operation {\n     @Override\n     public double execute(double a, double b) {\n         return a * b;\n     }\n \n     @Override\n     public String getSymbol() {\n         return \"*\";\n     }\n \n     @Override\n     public String getName() {\n         return \"Multiplicación\";\n     }\n }\n \n class Division implements Operation {\n     @Override\n     public double execute(double a, double b) {\n         if (b == 0) {\n             throw new ArithmeticException(\"No se puede dividir por cero\");\n         }\n         return a / b;\n     }\n \n     @Override\n     public String getSymbol() {\n         return \"/\";\n     }\n \n     @Override\n     public String getName() {\n         return \"División\";\n     }\n }\n \n // Podemos agregar nuevas operaciones sin modificar el código existente\n class Power implements Operation {\n     @Override\n     public double execute(double a, double b) {\n         return Math.pow(a, b);\n     }\n \n     @Override\n     public String getSymbol() {\n         return \"^\";\n     }\n \n     @Override\n     public String getName() {\n         return \"Potencia\";\n     }\n }\n \n // Clase para almacenar resultados de operaciones\n class OperationResult {\n     private final double value;\n     private final String operation;\n     private final double firstOperand;\n     private final double secondOperand;\n \n     public OperationResult(double value, String operation, double firstOperand, double secondOperand) {\n         this.value = value;\n         this.operation = operation;\n         this.firstOperand = firstOperand;\n         this.secondOperand = secondOperand;\n     }\n \n     @Override\n     public String toString() {\n         return String.format(\"%.2f %s %.2f = %.2f\", \n             firstOperand, operation, secondOperand, value);\n     }\n }\n \n // La calculadora que cumple con OCP\n class Calculator {\n     private final Map<String, Operation> operations;\n \n     public Calculator() {\n         this.operations = new HashMap<>();\n     }\n \n     // Método para registrar nuevas operaciones\n     public void registerOperation(Operation operation) {\n         operations.put(operation.getSymbol(), operation);\n     }\n \n     // Método para realizar cálculos\n     public OperationResult calculate(double a, double b, String symbol) {\n         Operation operation = operations.get(symbol);\n         if (operation == null) {\n             throw new IllegalArgumentException(\"Operación \" + symbol + \" no soportada\");\n         }\n         double result = operation.execute(a, b);\n         return new OperationResult(result, symbol, a, b);\n     }\n \n     // Método para obtener operaciones disponibles\n     public Set<Operation> getAvailableOperations() {\n         return operations.values().stream().collect(Collectors.toSet());\n     }\n }\n \n /*\n  * EXPLICACIÓN DE POR QUÉ ESTE DISEÑO CUMPLE CON OCP:\n  * \n  * 1. ABIERTO PARA EXTENSIÓN:\n  *    - Podemos agregar nuevas operaciones implementando la interfaz Operation\n  *    - No necesitamos modificar ninguna clase existente\n  *    - Cada operación está encapsulada en su propia clase\n  * \n  * 2. CERRADO PARA MODIFICACIÓN:\n  *    - La clase Calculator no necesita ser modificada para agregar nuevas operaciones\n  *    - El código existente permanece intacto cuando agregamos nuevas funcionalidades\n  *    - La interfaz Operation define un contrato claro que no cambia\n  * \n  * 3. VENTAJAS DE ESTE DISEÑO:\n  *    - Fácil de mantener y extender\n  *    - Cada operación está aislada y puede ser probada independientemente\n  *    - Reduce el acoplamiento entre componentes\n  *    - Facilita la adición de nuevas operaciones sin riesgo de afectar las existentes\n  * \n  * 4. CARACTERÍSTICAS ESPECÍFICAS DE LA IMPLEMENTACIÓN EN JAVA:\n  *    - Uso de interfaces\n  *    - Manejo de errores con excepciones específicas\n  *    - Uso de genéricos con Map y Set\n  *    - Clase específica para resultados inmutable\n  *    - Uso de Streams para operaciones con colecciones\n  *    - Formato de números con precisión decimal\n  */"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/java/martinbohorquez.java",
    "content": "import java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\n/**\n * #27 SOLID: PRINCIPIO ABIERTO-CERRADO (OCP)\n *\n * @author martinbohorquez\n */\npublic class martinbohorquez {\n    public static void main(String[] args) {\n        drawFormaTest();\n        drawFormOCPTest();\n\n        /*\n         * DIFICULTAD EXTRA\n         */\n        calculatorOCPTest();\n\n    }\n\n    private static void drawFormaTest() {\n        Forma forma = new Forma();\n        forma.drawSquare();\n        forma.drawCircle();\n        forma.drawTriangle();\n    }\n\n    private static void drawFormOCPTest() {\n        Form square = new Square();\n        square.draw();\n        Form circle = new Circle();\n        circle.draw();\n        Form triangle = new Triangle();\n        triangle.draw();\n    }\n\n    static class Forma {\n        private void drawSquare() {\n            System.out.println(\"Dibuja un cuadrado!\");\n        }\n\n        private void drawCircle() {\n            System.out.println(\"Dibuja un círculo!\");\n        }\n\n        private void drawTriangle() {\n            System.out.println(\"Dibuja un triángulo!\");\n        }\n    }\n\n    interface Form {\n        void draw();\n    }\n\n    static class Square implements Form {\n\n        @Override\n        public void draw() {\n            System.out.println(\"Dibuja un cuadrado!\");\n        }\n    }\n\n    static class Circle implements Form {\n\n        @Override\n        public void draw() {\n            System.out.println(\"Dibuja un círculo!\");\n        }\n    }\n\n    static class Triangle implements Form {\n\n        @Override\n        public void draw() {\n            System.out.println(\"Dibuja un triángulo!\");\n        }\n    }\n\n    private static void calculatorOCPTest() {\n        Calculator calculator = new Calculator();\n        calculator.addOperation(\"addition\", new Addition());\n        calculator.addOperation(\"subtraction\", new Subtraction());\n        calculator.addOperation(\"multiplication\", new Multiplication());\n        calculator.addOperation(\"division\", new Division());\n        calculator.addOperation(\"power\", new Power());\n\n        calculator.calculate(\"addition\", 10, 5);\n        calculator.calculate(\"subtraction\", 10, 5);\n        calculator.calculate(\"multiplication\", 10, 5);\n        calculator.calculate(\"division\", 10, 2.5);\n        calculator.calculate(\"power\", 5, 3);\n\n    }\n\n    interface Operation {\n        double execute(double a, double b);\n    }\n\n    static class Addition implements Operation {\n\n        @Override\n        public double execute(double a, double b) {\n            return a + b;\n        }\n    }\n\n    static class Subtraction implements Operation {\n\n        @Override\n        public double execute(double a, double b) {\n            return a - b;\n        }\n    }\n\n    static class Multiplication implements Operation {\n\n        @Override\n        public double execute(double a, double b) {\n            return a * b;\n        }\n    }\n\n    static class Division implements Operation {\n\n        @Override\n        public double execute(double a, double b) {\n            return a / b;\n        }\n    }\n\n    static class Power implements Operation {\n\n        @Override\n        public double execute(double a, double b) {\n            return Math.pow(a, b);\n        }\n    }\n\n    static class Calculator {\n        List<Map<String, Operation>> operations;\n\n        public Calculator() {\n            operations = new ArrayList<>();\n        }\n\n        private void addOperation(String name, Operation operation) {\n            Map<String, Operation> operationMap = new HashMap<>();\n            operationMap.put(name, operation);\n            operations.add(operationMap);\n        }\n\n        private void calculate(String name, double a, double b) {\n            operations.stream()\n                    .filter(o -> o.containsKey(name))\n                    .findFirst()\n                    .ifPresentOrElse(operation ->\n                                    System.out.printf(\"%s de %.1f y %.1f: %.2f%n\",\n                                            name, a, b, operation.get(name).execute(a, b)),\n                            () -> System.out.printf(\"La operación '%s' no está soportada\", name));\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/java/simonguzman.java",
    "content": "\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class simonguzman {\n    public static void main(String[] args) {\n        libraryViolationOcp();\n        libraryFollowOCP();\n        calculatorTest();\n        calculatorOCPTest();\n    }\n    /*************************** Ejercicio adicional con ocp(Correcto) ***************************/\n    static void calculatorOCPTest(){\n        CalculatorOCP calculator = new CalculatorOCP();\n\n        double resultAdd = calculator.Calculate(new Addition(), 10, 5);\n        System.out.println(\"Suma: \" + resultAdd);\n\n        double resultSub = calculator.Calculate(new Subtraction(), 10, 5);\n        System.out.println(\"Resta: \" + resultSub);\n\n        double resultMul = calculator.Calculate(new Multiplication(), 10, 5);\n        System.out.println(\"Multiplicación: \" + resultMul);\n\n        double resultDiv = calculator.Calculate(new Division(), 10, 5);\n        System.out.println(\"División: \" + resultDiv);\n\n        double resultPow = calculator.Calculate(new Power(), 2, 3);\n        System.out.println(\"Potencia: \" + resultPow);\n    }\n    interface Operation{\n        double function(double num1, double num2);\n    }\n\n    static class Addition implements Operation{\n        @Override\n        public double function(double num1, double num2) {\n            return num1 + num2; \n        }\n    }\n\n    static class Subtraction implements Operation{\n        @Override\n        public double function(double num1, double num2) {\n            return num1 - num2;\n        }  \n    }\n\n    static class Multiplication implements Operation{\n        @Override\n        public double function(double num1, double num2) {\n            return num1 * num2;\n        }  \n    }\n\n    static class Division implements Operation{\n        @Override\n        public double function(double num1, double num2) {\n            return num1 /  num2;\n        }      \n    }\n\n    static class Power implements Operation{\n        @Override\n        public double function(double num1, double num2) {\n            return Math.pow(num1, num2);\n        }\n    }\n\n    static class CalculatorOCP{\n        public double Calculate(Operation operation, double num1, double num2){\n            return operation.function(num1, num2);\n        }\n    }\n\n\n    /*************************** Ejercicio adicional sin ocp(Incorrecto) ***************************/\n    static void calculatorTest(){\n        Calculator calculator = new Calculator();\n\n        double resultAdd = calculator.calculate(\"sum\", 10, 5);\n        System.out.println(\"Suma: \" + resultAdd);\n\n        double resultSub = calculator.calculate(\"substract\", 10, 5);\n        System.out.println(\"Resta: \" + resultSub);\n\n        double resultMul = calculator.calculate(\"multiply\", 10, 5);\n        System.out.println(\"Multiplicación: \" + resultMul);\n\n        double resultDiv = calculator.calculate(\"divide\", 10, 5);\n        System.out.println(\"División: \" + resultDiv);\n\n        try {\n            double resultPow = calculator.calculate(\"power\", 2, 3);\n            System.out.println(\"Potencia: \" + resultPow);\n        } catch (UnsupportedOperationException e) {\n            System.out.println(\"Error: \" + e.getMessage());\n        }\n    }\n\n    static class Calculator{\n        public double calculate(String operation, double num1, double num2){\n            switch (operation) {\n                case \"sum\": return  num1 + num2; \n                case \"substract\": return  num1 - num2; \n                case \"multiply\": return  num1 * num2; \n                case \"divide\": return  num1 / num2; \n                default:\n                    throw new UnsupportedOperationException(\"Operacion no soportada\");\n            }\n        }\n    }\n\n    /*************************** Ejemplo con ocp(Correcto) ***************************/\n    static void libraryFollowOCP(){\n        List<String> books = new ArrayList<>();\n        List<String> users = new ArrayList<>();\n        LibraryOcp library = new LibraryOcp();\n\n        LibraryOperation registerBook = new RegisterBookOperation(\"El Quijote\", books);\n        library.performOperation(registerBook);\n\n        LibraryOperation registerUser = new RegisterUserOperation(\"Juan Perez\", users);\n        library.performOperation(registerUser);\n\n        LibraryOperation loanBook = new LoanBookOperation(\"El Quijote\", \"Juan Perez\", books);\n        library.performOperation(loanBook);\n\n        LibraryOperation renewLoan = new RenewLoanOperation(\"El Quijote\", \"Juan Perez\");\n        library.performOperation(renewLoan);\n    }\n\n    interface LibraryOperation{\n        void execute();\n    }\n\n    static class RegisterBookOperation implements LibraryOperation{\n        private String book;\n        private List<String> books;\n\n        public RegisterBookOperation(){\n            \n        }\n\n        public RegisterBookOperation(String book, List<String> books){\n            this.book = book;\n            this.books = books;\n        }\n\n        @Override\n        public void execute() {\n            books.add(book);\n            System.out.println(\"Libro registrado: \" + book);\n        }\n    }\n\n    static class RegisterUserOperation implements LibraryOperation{\n        private String user;\n        private List<String> users;\n\n        public RegisterUserOperation(){\n\n        }\n\n        public RegisterUserOperation(String user, List<String> users){\n            this.user = user;\n            this.users = users;\n        }\n        @Override\n        public void execute() {\n            users.add(user);\n            System.out.println(\"Usuario registrado: \"+user);\n        }\n    }\n\n    static class LoanBookOperation implements LibraryOperation{\n        private String book;\n        private String user;\n        private List<String> books;\n\n        public LoanBookOperation(){\n\n        }\n\n        public LoanBookOperation(String book, String user, List<String> books){\n            this.book = book;\n            this.user = user;\n            this.books = books;\n        }\n\n        @Override\n        public void execute() {\n            if(books.contains(book)){\n                System.out.println(\"Libro: \" + book + \" usuario \" + user);\n            }else{\n                System.out.println(\"El libro no esta disponible.\");\n            }\n        }\n        \n    }\n\n    static class RenewLoanOperation implements LibraryOperation{\n        private String book;\n        private String user;\n\n        public RenewLoanOperation(){\n\n        }\n\n        public RenewLoanOperation(String book, String user){\n            this.book = book;\n            this.user = user;\n        }\n\n        @Override\n        public void execute() {\n            System.out.println(\"El prestamo del libro \" + book + \" a sido renovado por \" + user);\n        }\n    }\n\n    static class LibraryOcp{\n        public void performOperation(LibraryOperation operation){\n            operation.execute();\n        }\n    }\n    /*************************** Ejemplo sin ocp(Incorrecto) ***************************/\n    static void libraryViolationOcp(){\n        Library library = new Library();\n        library.registerBook(\"El quijote\");\n        library.registerUser(\"Juan Perez\");\n        library.loanBook(\"El quijote\", \"Juan Perez\");\n        library.returnBook(\"El quijote\", \"Juan Perez\");\n    }\n\n    static class Library{\n        private List<String> books = new ArrayList<>();\n        private List<String> users = new ArrayList<>();\n\n        public void registerBook(String book){\n            books.add(book);\n            System.out.println(\"Libro registrado: \" + book);\n        }\n\n        public void registerUser(String user){\n            users.add(user);\n            System.out.println(\"Usuario registrado: \"+user);\n        }\n\n        public void loanBook(String book, String user){\n            if(books.contains(book)){\n                System.out.println(\"Libro: \" + book + \" prestado a \" + user);\n            }else{\n                System.out.println(\"El libro no esta disponible\");\n            }\n        }\n\n        public void returnBook(String book, String user){\n            System.out.println(\"Libro: \" + book + \" devuelto por \" + user);\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/javascript/Chrisdev00.js",
    "content": "/*\n * EJERCICIO:\n * Explora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas. \n * Requisitos:\n * - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n * Instrucciones:\n * 1. Implementa las operaciones de suma, resta, multiplicación y división.\n * 2. Comprueba que el sistema funciona.\n * 3. Agrega una quinta operación para calcular potencias.\n * 4. Comprueba que se cumple el OCP.\n */\n\n// Forma Incorrecta de aplicar el principio OCP\n\nclass Order {\n    constructor() {\n        this.items = [];\n        this.quantities = [];\n        this.prices = [];\n        this.status = \"open\";\n    }\n\n    addItem(name, quantity, price) {\n        this.items.push(name);\n        this.quantities.push(quantity);\n        this.prices.push(price);\n    }\n\n    totalPrice() {\n        let total = 0;\n        for (let i = 0; i < this.prices.length; i++) {\n            total += this.quantities[i] * this.prices[i];\n        }\n        return total;\n    }\n}\n\nclass PaymentProcessor {\n    payDebit(order, securityCode) {\n        console.log(\"Procesando el tipo de pago 'débito'\");\n        console.log(`Verificando código de seguridad: ${securityCode}`);\n        order.status = \"paid\";\n    }\n\n    payCredit(order, securityCode) {\n        console.log(\"Procesando el tipo de pago 'crédito'\");\n        console.log(`Verificando código de seguridad: ${securityCode}`);\n        order.status = \"paid\";\n    }\n\n    payPaypal(order, securityCode) {\n        console.log(\"Procesando el tipo de pago 'Paypal'\");\n        console.log(`Verificando código de seguridad: ${securityCode}`);\n        order.status = \"paid\";\n    }\n}\n\nconst order1 = new Order();\norder1.addItem(\"Keyboard\", 1, 50);\norder1.addItem(\"SSD\", 1, 150);\norder1.addItem(\"USB Cable\", 2, 5);\n\nconsole.log(`El precio total es: ${order1.totalPrice()}`);\nconst processor = new PaymentProcessor();\nprocessor.payDebit(order1, \"0372846\");\nconsole.log(`Estatus: ${order1.status}`);\n\n// Forma Correcta de aplicar el principio OCP\n\nclass Order {\n    constructor() {\n        this.items = [];\n        this.quantities = [];\n        this.prices = [];\n        this.status = \"open\";\n    }\n\n    addItem(name, quantity, price) {\n        this.items.push(name);\n        this.quantities.push(quantity);\n        this.prices.push(price);\n    }\n\n    totalPrice() {\n        let total = 0;\n        for (let i = 0; i < this.prices.length; i++) {\n            total += this.quantities[i] * this.prices[i];\n        }\n        return total;\n    }\n}\n\nclass PaymentProcessor {\n    pay(order, securityCode) {\n        throw new Error(\"This method should be overridden\");\n    }\n}\n\nclass DebitPaymentProcessor extends PaymentProcessor {\n    pay(order, securityCode) {\n        console.log(\"Procesando el tipo de pago 'débito'\");\n        console.log(`Verificando código de seguridad: ${securityCode}`);\n        order.status = \"paid\";\n    }\n}\n\nclass CreditPaymentProcessor extends PaymentProcessor {\n    pay(order, securityCode) {\n        console.log(\"Procesando el tipo de pago 'crédito'\");\n        console.log(`Verificando código de seguridad: ${securityCode}`);\n        order.status = \"paid\";\n    }\n}\n\nclass PaypalPaymentProcessor extends PaymentProcessor {\n    pay(order, securityCode) {\n        console.log(\"Procesando el tipo de pago 'Paypal'\");\n        console.log(`Verificando código de seguridad: ${securityCode}`);\n        order.status = \"paid\";\n    }\n}\n\nconst order = new Order();\norder.addItem(\"Keyboard\", 1, 50);\norder.addItem(\"SSD\", 1, 150);\norder.addItem(\"USB Cable\", 2, 5);\n\nconsole.log(`El precio total es: ${order.totalPrice()}`);\n\nconst debitProcessor = new DebitPaymentProcessor();\ndebitProcessor.pay(order, \"0372846\");\nconsole.log(`Estatus: ${order.status}`);\n\nconst creditProcessor = new CreditPaymentProcessor();\ncreditProcessor.pay(order, \"1234567\");\nconsole.log(`Estatus: ${order.status}`);\n\nconst paypalProcessor = new PaypalPaymentProcessor();\npaypalProcessor.pay(order, \"7654321\");\nconsole.log(`Estatus: ${order.status}`);\n\n\n//////////// ------------------------------ EXTRA ------------------------------------------- //////////////////////\n\n\nclass Calculator{\n    constructor(){\n        this.operations = {\n            \"suma\": new SumaOperation(),\n            \"resta\": new RestaOperation(),\n            \"multiplicacion\": new MultiOperation(),\n            \"division\": new DivisionOperation()\n        };\n    }\n\n    addOperation(name,operation){\n        this.operations[name] = operation;\n    }\n\n    getOperation(name){\n        return this.operations[name];\n    }\n\n    execute(name,num1,num2){\n        const operation = this.getOperation(name);\n        if(operation){\n            return operation.calculate(num1,num2);\n        }else{\n            throw new error(`Operacion '${name}' no soportada.`);\n        }\n    }\n}\n\nclass Operation {\n    calculate(num1, num2){\n        throw new Error(\"This method should be overridden\");\n    }\n}\n\nclass SumaOperation extends Operation{\n    calculate(num1,num2){\n        return num1 + num2;\n    }\n}\n\nclass RestaOperation extends Operation{\n    calculate(num1, num2){\n        return num1 - num2;\n    }\n}\n\nclass MultiOperation extends Operation{\n    calculate(num1, num2){\n        return num1 * num2;\n    }\n}\n\nclass DivisionOperation extends Operation{\n    calculate(num1,num2){\n        if(num2===0){\n            throw new Error(\"Cannot divide by zero\");\n        }\n        return num1 / num2;\n    }\n}\n\nclass PotenciaOperation extends Operation{\n    calculate(num1,num2){\n        return num1 ** num2;\n    }\n}\n\nconst calculadora = new Calculator();\ncalculadora.addOperation(\"potencia\", new PotenciaOperation());\n\nconsole.log(`Suma: ${calculadora.execute('suma', 4,3)}`)\nconsole.log(`Resta: ${calculadora.execute('resta', 10,5)}`)\nconsole.log(`Multiplicacion: ${calculadora.execute('multiplicacion', 7,6)}`)\nconsole.log(`Division: ${calculadora.execute('division', 8,2)}`)\nconsole.log(`Potencia: ${calculadora.execute('potencia', 2,3)}`)\n\ntry {\n    console.log(`Mod: ${calculadora.execute('mod', 10, 3)}`);\n} catch (e) {\n    console.error(e.message);\n}"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/javascript/DavidMoralesDeveloper.js",
    "content": "//  * Explora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\" \n//  * y crea un ejemplo simple donde se muestre su funcionamiento\n//  * de forma correcta e incorrecta.\n\nclass CalcularAreas {\n    ecuacionDeAreas(){\n\n    }\n}\n\nclass Cuadrado extends CalcularAreas{\n    constructor(lado){\n        super()\n        this.lado=lado\n        \n    }\n    ecuacionDeAreas(lado){\n        return lado * lado\n    }\n}\n\nclass Circulo extends CalcularAreas{\n    constructor (radio) {\n        super()\n        this.radio=radio\n    }\n    ecuacionDeAreas(radio){\n        return 3.14 *radio*radio\n    }\n}\n// esta clase es SRP \nclass SumatoriaDeAreas {\n    \n    sumarAreas(formas){\n        if(Array.isArray(formas)){\n            \n            return formas.reduce((num1, num2) => num1 + num2, 0)\n        }else console.log(\"solo acepta Arr\")\n    }\n}\n\n\n\nconst areaCuadrado = new Cuadrado()\nconst cuadrado1 = areaCuadrado.ecuacionDeAreas(2)\nconst cuadrado2 = areaCuadrado.ecuacionDeAreas(5)\n\nconst areaCirculo = new Circulo()\nconst circulo1 = areaCirculo.ecuacionDeAreas(5)\n\nconst sumAreas = new SumatoriaDeAreas()\n\nconst formas = [cuadrado1, cuadrado2,circulo1]\nconsole.log(formas)\nconsole.log(sumAreas.sumarAreas(formas))\n\nconsole.log(\"-------------------------Extra-----------------------\")\n\n// Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas. \n//  * Requisitos:\n//  * - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n//  * Instrucciones:\n//  * 1. Implementa las operaciones de suma, resta, multiplicación y división.\n//  * 2. Comprueba que el sistema funciona.\n//  * 3. Agrega una quinta operación para calcular potencias.\n//  * 4. Comprueba que se cumple el OCP.\n\nclass Calculadora {\n    constructor(){\n\n    }\n    operacionesMatematicas(){\n\n    }\n}\n\nclass Suma extends Calculadora {\n    constructor(num1, num2){\n        super()\n        this.num1 = num1\n        this.num2= num2\n    }\n\n    mas (num1, num2){\n        return num1 + num2\n    }\n    \n}\nclass Resta extends Calculadora {\n    constructor(num1, num2){\n        super()\n        this.num1 = num1\n        this.num2= num2\n    }\n\n    menos (num1, num2){\n        return num1 - num2\n    }\n\n}\nclass Multiplicar extends Calculadora {\n    constructor(num1, num2){\n        super()\n        this.num1 = num1\n        this.num2= num2\n    }\n\n    por (num1, num2){\n        return num1 * num2\n    }\n\n}\nclass Dividir extends Calculadora {\n    constructor(num1, num2){\n        super()\n        this.num1 = num1\n        this.num2= num2\n    }\n\n    entre (num1, num2){\n        return num1 / num2\n    }\n\n}\n\nclass Potencia extends Calculadora {\n    constructor(base, exponente) {\n        super();\n        this.base = base;\n        this.exponente = exponente;\n    }\n    elevar(base, exponente) {\n        return Math.pow(base, exponente);\n    }\n}\n\n\nconst sumas = new Suma();\nconst resta = new Resta()\nconst multiplcacion = new Multiplicar()\nconst divicion = new Dividir()\n\nconsole.log(sumas.mas(5,5))\nconsole.log(resta.menos(5,5))\nconsole.log(multiplcacion.por(5,5))\nconsole.log(divicion.entre(5,5))"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #27 - JavaScript -> Jesus Antonio Escamilla */\n\n/**\n * El principio abierto-cerrado dice que el código debe estar abierto a la ampliación,\n   pero cerrado a la modificación.\n * Lo que esto significa es que si queremos añadir funcionalidad adicional, deberíamos\n   poder hacerlo simplemente ampliando la funcionalidad original, sin necesidad de modificarla.\n * El Principio de Abierto/Cerrado (Open/Closed Principle, OCP) establece que las entidades de software\n   (como clases, módulos, funciones, etc.) deben estar abiertas para extensión, pero cerradas para modificación.\n * Esto significa que debemos ser capaces de agregar nuevo comportamiento al código existente sin modificarlo.\n */\n\n//---EJERCIÓ---\n//  INCORRECTO\nclass Employee__{\n   constructor(nombre, tipo){\n      this.nombre = nombre;\n      this.tipo = tipo;\n   }\n\n   calculatePay(){\n      if (this.tipo === 'fulltime') {\n         return 4000;\n      } else if(this.tipo === 'parttime'){\n         return 2000;\n      } else if (this.tipo === 'intern') {\n         return 1000;\n      }\n      // Si agregamos un nuevo tipo, tenemos que modificar este método\n   }\n}\n\n// Ejemplo de uso de forma Incorrecta\nconst fulltimeEmployee__ = new Employee__('Lizette', 'fulltime');\nconsole.log(fulltimeEmployee__.calculatePay());\n\nconst partTimeEmployee__ = new Employee__('Antonio', 'parttime');\nconsole.log(partTimeEmployee__.calculatePay());\n\n\n//  CORRECTO\nclass Employee{\n   constructor(nombre){\n      this.nombre = nombre;\n   }\n\n   calculatePay(){\n      throw new Error('You have implement the method calculatePay');\n   }\n}\n\nclass FullTimeEmployee extends Employee{\n   calculatePay(){\n      return 4000;\n   }\n}\n\nclass PartTimeEmployee extends Employee{\n   calculatePay(){\n      return 2000;\n   }\n}\n\nclass InternEmployee extends Employee{\n   calculatePay(){\n      return 1000;\n   }\n}\n\n// Ejemplo de uso de forma Correcta\nconst fulltimeEmployee = new FullTimeEmployee('Jesus');\nconsole.log(fulltimeEmployee.calculatePay());\n\nconst partTimeEmployee = new PartTimeEmployee('Fatima');\nconsole.log(partTimeEmployee.calculatePay());\n\nconst internEmployee = new InternEmployee('Enrique');\nconsole.log(internEmployee.calculatePay());\n\n// Si necesitamos agregar un nuevo tipo de empleado, simplemente creamos una nueva clase que herede de Employee.\nclass ContractorEmployee extends Employee{\n   calculatePay(){\n      return 3000;\n   }\n}\n\nconst contractorEmployee = new ContractorEmployee('Mari');\nconsole.log(contractorEmployee.calculatePay());\n\n\n/**-----DIFICULTAD EXTRA-----*/\n\n// Interface para la operaciones\nclass Operation{\n   execute(a, b){\n      throw new Error('Método no implementado')\n   }\n}\n\n// Suma\nclass Addition extends Operation{\n   execute(a, b){\n      return a + b;\n   }\n}\n\n// Resta\nclass Subtraction extends Operation{\n   execute(a, b){\n      return a - b;\n   }\n}\n\n// Multiplicación\nclass Multiplication extends Operation{\n   execute(a, b){\n      return a * b;\n   }\n}\n\n// Division\nclass Division extends Operation{\n   execute(a, b){\n      if (b === 0) {\n         throw new Error('Nose puede dividir entre 0');\n      }\n      return a / b;\n   }\n}\n\n\n// Clase Calculadora\nclass Calculator{\n   constructor() {\n      this.operations = {};\n   }\n\n   addOperation(nombre, operación){\n      this.operations[nombre] = operación;\n   }\n\n   calculate(nombre, a, b){\n      if (!this.operations[nombre]) {\n         throw new Error(`Operación ${nombre} no es valida`);\n      }\n      return this.operations[nombre].execute(a, b);\n   }\n}\n\n\n//Creando la instancia de la calculadora\nconst calculator = new Calculator();\ncalculator.addOperation('add', new Addition());\ncalculator.addOperation('subtract', new Subtraction());\ncalculator.addOperation('multiply', new Multiplication());\ncalculator.addOperation('divide', new Division());\n\n// Test de opresiones básicas\nconsole.log('Suma', calculator.calculate('add', 5, 4));\nconsole.log('Resta', calculator.calculate('subtract', 9, 6));\nconsole.log('Multiplicación', calculator.calculate('multiply', 3, 7));\nconsole.log('Division', calculator.calculate('divide', 8, 2));\n\n// Agregamos la potencia\nclass Power extends Operation{\n   execute(a, b){\n      return a ** b;\n   }\n}\n\n// Agregamos la operación de potencia\ncalculator.addOperation('power', new Power());\nconsole.log('Potencia', calculator.calculate('power', 2, 5));\n\n/**-----DIFICULTAD EXTRA-----*/"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/javascript/RaulDoezon.js",
    "content": "/*\n  EJERCICIO:\n  Explora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\" \n  y crea un ejemplo simple donde se muestre su funcionamiento\n  de forma correcta e incorrecta.\n*/\n\nconsole.log(\"+++++++++ IMPLEMENTACIÓN INCORRECTA +++++++++\");\n\nclass IncorrectForm {\n  constructor(type) {\n    this.type = type;\n  }\n\n  calcArea() {\n    if (this.type === 'circle') {\n      console.log(`Área de círculo π x r²`);\n      console.log(`3.1416 * (6 * 6) = ${Math.PI * (6 * 6)}`);\n    } else if (this.type === 'rectangle') {\n      // Lógica para calcular el área de un rectángulo.\n    } else if (this.type === 'triangle') {\n      // Lógica para calcular el área de un triángulo.\n    }\n  }\n}\n\nconst incorrectForm = new IncorrectForm('circle');\nincorrectForm.calcArea();\n\nconsole.log(\"\\n+++++++++ IMPLEMENTACIÓN CORRECTA +++++++++\");\n\nclass Form {\n  calcArea() {\n    throw new Error('Cálculo no implementado');\n  }\n}\n\nclass Circle extends Form {\n  calcArea() {\n    console.log(`Área de círculo π x r²`);\n    console.log(`3.1416 * (6 * 6) = ${Math.PI * (6 * 6)}`);\n  }\n}\n\nclass Triangle extends Form {\n  // Lógica para calcular el área de un triángulo.\n}\n\n/*\n  SI ESTE CÓDIGO SE EJECUTA MOSTRARÁ EL ERROR DEBIDO A QUE LA CLASE TRIANGLE NO TIENE DEFINIDO EL MÉTODO calcArea()\n\n  const triangle = new Triangle();\n  triangle.calcArea();\n*/\n\nconst circle = new Circle();\ncircle.calcArea();\n\n/*\n  DIFICULTAD EXTRA (opcional):\n  Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas. \n  Requisitos:\n  - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n  Instrucciones:\n  1. Implementa las operaciones de suma, resta, multiplicación y división.\n  2. Comprueba que el sistema funciona.\n  3. Agrega una quinta operación para calcular potencias.\n  4. Comprueba que se cumple el OCP.\n*/\n\nconsole.log(\"\\n+++++++++ CALCULADORA +++++++++\");\n\nclass OperationValidation {\n  operation() {\n    throw new Error (`La operación ${this.constructor.name} no existe`);\n  }\n}\n\nclass Calculator {\n  showResult(operationData) {\n    const operationName = operationData[0];\n    const value1 = operationData[1];\n    const value2 = operationData[2];\n    const result = operationData[3];\n\n    console.log(`La ${operationName} de los valores ${value1} y ${value2} es: ${result}`);\n  }\n}\n\nclass Addition extends OperationValidation {\n  operation(a, b) {\n    const operationType = \"Suma\";\n\n    return [operationType, a, b, a + b];\n  }\n}\n\nclass Substraction extends OperationValidation {\n  operation(a, b) {\n    const operationType = \"Resta\";\n\n    return [operationType, a, b, a - b];\n  }\n}\n\nclass Multiplication extends OperationValidation {\n  operation(a, b) {\n    const operationType = \"Multiplicación\";\n\n    return [operationType, a, b, a * b];\n  }\n}\n\nclass Division extends OperationValidation {\n  operation(a, b) {\n    const operationType = \"División\";\n\n    return [operationType, a, b, a / b];\n  }\n}\n\nclass Power extends OperationValidation {\n  operation(a, b) {\n    const operationType = \"Potencia\";\n\n    return [operationType, a, b, a ** b];\n  }\n}\n\nconst calculator = new Calculator();\nconst addition = new Addition();\nconst substraction = new Substraction();\nconst multiplication = new Multiplication();\nconst division = new Division();\nconst power = new Power();\n\ncalculator.showResult(addition.operation(1, 2));\ncalculator.showResult(substraction.operation(3, 4));\ncalculator.showResult(multiplication.operation(5, 6));\ncalculator.showResult(division.operation(7, 8));\ncalculator.showResult(power.operation(9, 10));\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/javascript/RicJDev.js",
    "content": "//EJERCICIO\n/*\nIncorrecto ❎\n\nDado a que no se ha diseñado siguiendo el principio, habría que modificar clases para que el sistema de cálculo de áreas pueda soportar otras figuras geométricas. En un caso más complejo este sería un problema, ya que dificulta el agregar funcionalidades o realizar cambios.\n\n*/\nconsole.log('\\nSin OCP');\nclass RectangleNoOCP {\n\tconstructor(height, width) {\n\t\tthis.height = height;\n\t\tthis.width = width;\n\t}\n}\nclass AreaCalculatorNoOCP {\n\tcalculateArea(rectangle) {\n\t\tlet area = rectangle.height * rectangle.width;\n\n\t\treturn area;\n\t}\n}\n\nclass AppNoOCP {\n\trectangle = new RectangleNoOCP(12, 20.33);\n\tsquare = new RectangleNoOCP(21, 21);\n\n\tareaCalc = new AreaCalculatorNoOCP();\n\n\tdisplayAreas() {\n\t\tconsole.log('Rectangulo:', this.areaCalc.calculateArea(this.rectangle));\n\t\tconsole.log('Cuadrado:', this.areaCalc.calculateArea(this.square));\n\t}\n}\n\nconst appNoOCP = new AppNoOCP();\nappNoOCP.displayAreas();\n\n/*\nCorrecto ✅\n\n\"Las entidades de software (clases, módulos, funciones, etc) deben de estar abierta para su extensión, pero cerradas para su modificación.\"\n\nDiseñado de esta manera resulta más fácil añadir figuras geométricas al sistema de cálculo de áreas. Este ejemplo abstrae el método getArea y lo hace común para cada figura, pero cada una cuenta con su propio método concreto para calcular el área.\n\n*/\nconsole.log('\\nCon OCP');\n\nclass GeometricShape {\n\tconstructor() {\n\t\tthis.area = this.getArea();\n\t}\n\n\tgetArea() {\n\t\treturn 1;\n\t}\n}\n\nclass Rectangle extends GeometricShape {\n\tconstructor(height, width) {\n\t\tsuper();\n\t\tthis.height = height;\n\t\tthis.width = width;\n\t\tthis.area = this.getArea();\n\t}\n\n\tgetArea() {\n\t\treturn this.height * this.width;\n\t}\n}\n\nclass Square extends GeometricShape {\n\tconstructor(height) {\n\t\tsuper();\n\t\tthis.height = height;\n\t\tthis.area = this.getArea();\n\t}\n\n\tgetArea() {\n\t\treturn this.height ** 2;\n\t}\n}\n\nclass Circle extends GeometricShape {\n\tconstructor(radius) {\n\t\tsuper();\n\t\tthis.radius = radius;\n\t\tthis.area = this.getArea();\n\t}\n\n\tgetArea() {\n\t\treturn this.radius * 2 * Math.PI;\n\t}\n}\n\nclass App {\n\trectangle = new Rectangle(12, 20);\n\tsquare = new Square(20);\n\tcircle = new Circle(5);\n\n\tcalculateArea(geometricShape) {\n\t\treturn geometricShape.area;\n\t}\n\n\tdisplayAreas() {\n\t\tconsole.log('Rectángulo:', this.calculateArea(this.rectangle));\n\t\tconsole.log('Cuadrado:', this.calculateArea(this.square));\n\t\tconsole.log('Círculo:', this.calculateArea(this.circle));\n\t}\n}\n\nconst app = new App();\n\napp.displayAreas();\n\n//EXTRA\nconsole.log('\\nCalculadora');\nclass Operation {\n\tcalculate(a, b) {\n\t\tthrow new Error('Operación no soportada');\n\t}\n}\n\nclass Addition extends Operation {\n\tcalculate(a, b) {\n\t\treturn a + b;\n\t}\n}\n\nclass Substraction extends Operation {\n\tcalculate(a, b) {\n\t\treturn a - b;\n\t}\n}\n\nclass Multiplication extends Operation {\n\tcalculate(a, b) {\n\t\treturn a * b;\n\t}\n}\n\nclass Division extends Operation {\n\tcalculate(a, b) {\n\t\treturn a / b;\n\t}\n}\n\nclass Calculator {\n\toperations = {};\n\n\taddOperation(name, operation) {\n\t\tthis.operations[name] = operation;\n\t}\n\n\tcalculate(operation, a, b) {\n\t\tlet op = this.operations[operation] || new Operation();\n\n\t\ttry {\n\t\t\treturn op.calculate(a, b);\n\t\t} catch (error) {\n\t\t\tconsole.log(`Se produjo un error. ${error.message}: ${operation}`);\n\t\t\treturn NaN;\n\t\t}\n\t}\n}\n\nconst calculator = new Calculator();\ncalculator.addOperation('Addition', new Addition());\ncalculator.addOperation('Substraction', new Substraction());\ncalculator.addOperation('Multiplication', new Multiplication());\ncalculator.addOperation('Division', new Division());\n\nlet result = calculator.calculate('Addition', 12, 10);\nconsole.log('Suma:', result);\n\nresult = calculator.calculate('Substraction', 10, 2);\nconsole.log('Resta:', result);\n\nresult = calculator.calculate('Multiplication', 10, 2);\nconsole.log('Multiplicación:', result);\n\nresult = calculator.calculate('Division', 10, 2);\nconsole.log('División:', result);\n\nresult = calculator.calculate('Pow', 10, 2);\nconsole.log('Potencia:', result);\n\nclass Pow extends Operation {\n\tcalculate(a, b) {\n\t\treturn a ** b;\n\t}\n}\n\ncalculator.addOperation('Pow', new Pow());\n\nresult = calculator.calculate('Pow', 10, 2);\nconsole.log('Potencia:', result);\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/javascript/Sac-Corts.js",
    "content": "// Wrong way\nclass ShapeCalculator {\n    calculateArea(shape) {\n        if (shape.type === 'circle'){\n            return Math.PI * Math.pow(shape.radius, 2);\n        } else if (shape.type === 'square') {\n            return Math.pow(shape.side, 2);\n        } else {\n            throw new Error('Shape not supported');\n        }\n    }\n}\n\nconst calculator = new ShapeCalculator();\nconsole.log(calculator.calculateArea({ type: 'circle', radius: 5 }));\nconsole.log(calculator.calculateArea({ type: 'square', side: 4 }));\n\n// Correct way\nclass Shape {\n    calculateArea(shape) {\n        throw new Error('calculateArea() must be implemented');\n    }\n}\n\nclass Circle extends Shape {\n    constructor(radius) {\n        super();\n        this.radius = radius;\n    }\n\n    calculateArea() {\n        return Math.PI * Math.pow(this.radius, 2);\n    }\n}\n\nclass Square extends Shape {\n    constructor(side) {\n        super();\n        this.side = side;\n    }\n\n    calculateArea() {\n        return Math.pow(this.side, 2);\n    }\n}\n\nfunction printArea(shape) {\n    console.log(`Area: ${shape.calculateArea()}`);\n}\n\nconst circle = new Circle(5);\nconst square = new Square(4);\nprintArea(circle);\nprintArea(square);\n\n// Extra Exercise //\nclass Operation {\n    calculate(a, b) {\n        throw new Error('calculateOperation() must be implemented');\n    }\n}\n\nclass Addition extends Operation {\n    calculate(a, b) {\n        return a + b;\n    }\n}\n\nclass Subtraction extends Operation {\n    calculate(a, b) {\n        return a - b;\n    }\n}\n\nclass Multiplication extends Operation {\n    calculate(a, b) {\n        return a * b;\n    }\n}\n\nclass Division extends Operation {\n    calculate(a, b) {\n        if (b === 0) throw new Error('Division by zero is not allowed');\n        return a / b;\n    }\n}\n\nclass Pow extends Operation {\n    calculate(a, b) {\n        return Math.pow(a, b);\n    }\n}\n\nclass Calculator {\n    constructor() {\n        this.operations = {};\n    }\n\n    addOperation(name, operation) {\n        this.operations[name] = operation;\n    }\n\n    calculate(name, a, b) {\n        const operation = this.operations[name];\n        if (!operation) throw new Error(`Operation \"${name}\" not supported`);\n        return operation.calculate(a, b);\n    }\n}\n\nconst calculator2 = new Calculator();\ncalculator2.addOperation('addition', new Addition());\ncalculator2.addOperation('subtraction', new Subtraction());\ncalculator2.addOperation('multiplication', new Multiplication());\ncalculator2.addOperation('division', new Division());\ncalculator2.addOperation('pow', new Pow());\n\nconsole.log(calculator2.calculate('addition', 2, 10));\nconsole.log(calculator2.calculate('subtraction', 2, 10));\nconsole.log(calculator2.calculate('multiplication', 2, 10));\nconsole.log(calculator2.calculate('division', 10, 5));\nconsole.log(calculator2.calculate('pow', 10, 2));\n\n\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/javascript/adrs1166ma.js",
    "content": "/* 🔥 EJERCICIO:\nExplora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\" \ny crea un ejemplo simple donde se muestre su funcionamiento\nde forma correcta e incorrecta.\n*/\nconsole.log(\"----- EJEMPLO SIMPLE -----\");\n\n//  * Ejemplo Incorrecto: Clase no extensible sin modificar código existente\n// --------------------------------------------------------------------------------------------------------------\nclass CalculadoraIncorrecta {\n    calcular(operacion, a, b) {\n        switch(operacion) {\n            case 'suma':\n                return a + b;\n            case 'resta':\n                return a - b;\n            default:\n                throw new Error(\"Operación no soportada.\");\n        }\n    }\n}\n\n// Uso incorrecto\nconst calcIncorrecta = new CalculadoraIncorrecta();\nconsole.log(\"Suma (incorrecto):\", calcIncorrecta.calcular('suma', 5, 3)); // 8\nconsole.log(\"Resta (incorrecto):\", calcIncorrecta.calcular('resta', 5, 3)); // 2\n// ¡Problema!: Para añadir \"multiplicación\", debemos editar la clase CalculadoraIncorrecta\n\n//  * Ejemplo Correcto: Clases abiertas para extensión\n// --------------------------------------------------------------------------------------------------------------\nclass Operacion {\n    ejecutar(a, b) {\n        throw new Error(\"Operación no implementada.\");\n    }\n}\n\nclass Suma extends Operacion {\n    ejecutar(a, b) {\n        return a + b;\n    }\n}\n\nclass Resta extends Operacion {\n    ejecutar(a, b) {\n        return a - b;\n    }\n}\n\nclass CalculadoraCorrecta {\n    constructor(operacion) {\n        this.operacion = operacion;\n    }\n\n    calcular(a, b) {\n        return this.operacion.ejecutar(a, b);\n    }\n}\n\n// Uso correcto\nconst suma = new Suma();\nconst resta = new Resta();\nconst calcSuma = new CalculadoraCorrecta(suma);\nconst calcResta = new CalculadoraCorrecta(resta);\n\nconsole.log(\"Suma (correcto):\", calcSuma.calcular(5, 3)); // 8\nconsole.log(\"Resta (correcto):\", calcResta.calcular(5, 3)); // 2\n\n// Nueva operación sin modificar clases existentes\nclass Multiplicacion extends Operacion {\n    ejecutar(a, b) {\n        return a * b;\n    }\n}\n\nconst multiplicacion = new Multiplicacion();\nconst calcMultiplicacion = new CalculadoraCorrecta(multiplicacion);\nconsole.log(\"Multiplicación (correcto):\", calcMultiplicacion.calcular(5, 3)); // 15\n\n// --------------------------------------------------------------------------------------------------------------\n/* 🔥 DIFICULTAD EXTRA (opcional):\nDesarrolla una calculadora que necesita realizar diversas operaciones matemáticas. \nRequisitos:\n- Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\nInstrucciones:\n1. Implementa las operaciones de suma, resta, multiplicación y división.\n2. Comprueba que el sistema funciona.\n3. Agrega una quinta operación para calcular potencias.\n4. Comprueba que se cumple el OCP.\n*/\nconsole.log(\"\\n----- SISTEMA DE CALCULADORA EXTENSIBLE -----\");\n\nclass OperacionBase {\n    ejecutar(a, b) {\n        throw new Error(\"Operación no implementada.\");\n    }\n}\n\nclass SumaOp extends OperacionBase {\n    ejecutar(a, b) { return a + b; }\n}\n\nclass RestaOp extends OperacionBase {\n    ejecutar(a, b) { return a - b; }\n}\n\nclass MultiplicacionOp extends OperacionBase {\n    ejecutar(a, b) { return a * b; }\n}\n\nclass DivisionOp extends OperacionBase {\n    ejecutar(a, b) {\n        if (b === 0) throw new Error(\"División por cero.\");\n        return a / b;\n    }\n}\n\nclass Calculadora {\n    constructor() {\n        this.operaciones = {};\n    }\n\n    registrarOperacion(nombre, operacion) {\n        this.operaciones[nombre] = operacion;\n    }\n\n    calcular(operacion, a, b) {\n        if (!this.operaciones[operacion]) {\n            throw new Error(`Operación \"${operacion}\" no registrada.`);\n        }\n        return this.operaciones[operacion].ejecutar(a, b);\n    }\n}\n\n// Registrar operaciones iniciales\nconst calc = new Calculadora();\ncalc.registrarOperacion('suma', new SumaOp());\ncalc.registrarOperacion('resta', new RestaOp());\ncalc.registrarOperacion('multiplicacion', new MultiplicacionOp());\ncalc.registrarOperacion('division', new DivisionOp());\n\n// Ejemplos de uso\nconsole.log(\"Suma:\", calc.calcular('suma', 10, 5)); // 15\nconsole.log(\"Resta:\", calc.calcular('resta', 10, 5)); // 5\nconsole.log(\"Multiplicación:\", calc.calcular('multiplicacion', 10, 5)); // 50\nconsole.log(\"División:\", calc.calcular('division', 10, 5)); // 2\n\n//  * Agregar nueva operación (OCP cumplido)\n// --------------------------------------------------------------------------------------------------------------\nclass Potencia extends OperacionBase {\n    ejecutar(a, b) {\n        return Math.pow(a, b);\n    }\n}\n\n// Registrar potencia sin modificar la clase Calculadora\ncalc.registrarOperacion('potencia', new Potencia());\nconsole.log(\"Potencia:\", calc.calcular('potencia', 2, 3)); // 8"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/javascript/agusrosero.js",
    "content": "/*\n * EJERCICIO:\n * Explora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\"\n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n */\n\n// Forma incorrecta\nclass Form {\n  constructor(name) {\n    this.name = name;\n  }\n\n  calcName() {\n    if (this.name === \"Hernan\") {\n      return `Hola Hernan...!`;\n    } else if (this.name === \"Agustin\") {\n      return \"Hola Agustin...!\";\n    } else {\n      return `Chau ${this.name}`;\n    }\n  }\n}\n\nconst form = new Form(\"Hernan\");\nform.calcName();\n\n// Forma correcta\nclass Form {\n  calcName() {\n    throw new Error(\"Metodo no implementado\");\n  }\n}\n\nclass Saludo1 extends Form {\n  calcName() {\n    return \"Hola Hernan...!\";\n  }\n}\n\nclass Saludo2 extends Form {\n  calcName() {\n    return \"Hola Agustin\";\n  }\n}\n\nclass Saludo3 extends Form {\n  calcName() {\n    return `Hola ${this.name}`;\n  }\n}\n\nconst saludo = new Saludo1();\nsaludo.calcName();\n\n/* DIFICULTAD EXTRA (opcional):\n * Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas.\n * Requisitos:\n * - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n * Instrucciones:\n * 1. Implementa las operaciones de suma, resta, multiplicación y división.\n * 2. Comprueba que el sistema funciona.\n * 3. Agrega una quinta operación para calcular potencias.\n * 4. Comprueba que se cumple el OCP.\n */\nclass Calculadora {\n  constructor() {\n    this.operations = {};\n  }\n\n  agregarOperacion(nombre, operacion) {\n    this.operations[nombre] = operacion;\n  }\n\n  calculate(nombre, a, b) {\n    return this.operations[nombre].execute(a, b);\n  }\n}\n\nclass Operation {\n  execute(a, b) {\n    throw new Error(\"Método no implementado\");\n  }\n}\n\nclass Sumar extends Operation {\n  execute(a, b) {\n    return a + b;\n  }\n}\n\nclass Restar extends Operation {\n  execute(a, b) {\n    return a - b;\n  }\n}\n\nclass Multiplicar extends Operation {\n  execute(a, b) {\n    return a * b;\n  }\n}\n\nclass Dividir extends Operation {\n  execute(a, b) {\n    if (a === 0) {\n      throw new Error(\"Error!, No se puede divir por 0.\");\n    }\n    return a / b;\n  }\n}\n\nconst calculadora = new Calculadora();\ncalculadora.agregarOperacion(\"sumar\", new Sumar());\ncalculadora.agregarOperacion(\"restar\", new Restar());\ncalculadora.agregarOperacion(\"multiplicar\", new Multiplicar());\ncalculadora.agregarOperacion(\"dividir\", new Dividir());\n\nconsole.log(calculadora.calculate(\"sumar\", 10, 5));\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/javascript/caterinarodriguezdev.js",
    "content": "/*\n * EJERCICIO:\n * Explora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\"\n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas.\n * Requisitos:\n * - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n * Instrucciones:\n * 1. Implementa las operaciones de suma, resta, multiplicación y división.\n * 2. Comprueba que el sistema funciona.\n * 3. Agrega una quinta operación para calcular potencias.\n * 4. Comprueba que se cumple el OCP.\n */\n\n// Violación del OCP\nclass AreaCalculator {\n    calculateRectangleArea(width, height) {\n        return width * height;\n    }\n\n    calculateCircleArea(radius) {\n        return Math.PI ** radius;\n    }\n}\n\nconst calculator = new AreaCalculator();\nconsole.log(calculator.calculateRectangleArea(5, 10)); \nconsole.log(calculator.calculateCircleArea(7));\n\n// OCP\nclass Shape {\n    area() {\n        throw new Error(\"Método area debe ser implementado\");\n    }\n}\n\nclass Rectangle extends Shape {\n    constructor(width, height) {\n        super();\n        this.width = width;\n        this.height = height;\n    }\n\n    area() {\n        return this.width * this.height;\n    }\n}\n\nclass Circle extends Shape {\n    constructor(radius) {\n        super();\n        this.radius = radius;\n    }\n\n    area() {\n        return Math.PI ** this.radius;\n    }\n}\n\nclass AreaCalculatorOCP {\n    calculateArea(shape) {\n        return shape.area();\n    }\n}\n\nconst calculatorOCP = new AreaCalculator();\nconst rectangle = new Rectangle(10, 10);\nconst circle = new Circle(10);\n\nconsole.log(rectangle.area());\nconsole.log(circle.area());\n\n\nconsole.log('--------------DIFICULTAD EXTRA------------');\n\nclass Calculadora {\n\n    sumar(n1, n2) {\n        return n1 + n2\n    }\n\n    restar(n1, n2) {\n        return n1 - n2\n    }\n\n    multiplicar(n1, n2) {\n        return n1 * n2\n    }\n\n    dividir(n1, n2) {\n       return n1 / n2\n    }\n}\n\nconst calculadora = new Calculadora();\nconsole.log(calculadora.sumar(1, 1));\nconsole.log(calculadora.restar(1, 1));\nconsole.log(calculadora.multiplicar(1, 1));\nconsole.log(calculadora.dividir(1, 1));\n\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/javascript/duendeintemporal.js",
    "content": "//#27 - Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\n\n//https://en.wikipedia.org/wiki/Open%E2%80%93closed_principle\n/*In object-oriented programming, the open–closed principle (OCP) states \"software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification\";[1] that is, such an entity can allow its behaviour to be extended without modifying its source code.\n\nThe name open–closed principle has been used in two ways. Both ways use generalizations (for instance, inheritance or delegate functions) to resolve the apparent dilemma, but the goals, techniques, and results are different.*/\n\nlet log = console.log;\n\n//Not using Open-Close Principle (OCP)\n\nclass SimpleCalculator {\n    calculate(operation, a, b) {\n        switch (operation) {\n            case 'add':\n                return a + b;\n            case 'subtract':\n                return a - b;\n            case 'multiply':\n                return a * b;\n            case 'divide':\n                return a / b;\n            default:\n                throw new Error('Operation not supported');\n        }\n    }\n}\n\nconst calculator1 = new SimpleCalculator();\nconsole.log(calculator1.calculate('add', 856, 30)); // 886\nconsole.log(calculator1.calculate('divide', 220, 4423)); // 0.04973999547818223\n\n//Using Open-Close Principle (OCP)\n\n\n    const title = document.createElement('h1');\n    title.textContent = 'Retosparaprogramadores #20.';\n    title.style.setProperty('font-size', '3.5vmax');\n    title.style.setProperty('color', '#fff');\n    title.style.setProperty('line-height', '20vh');\n    title.style.setProperty('margin', '5vw 0');\n\n    document.body.appendChild(title);    \n\n    log('Retosparaprogramadores #27'); \n\nfunction createCalculator() {\n    const calcWrapper = document.createElement('div');\n    calcWrapper.id = 'calc_wrapper';\n    document.body.appendChild(calcWrapper);\n\n    const display = document.createElement('input');\n    display.type = 'text';\n    display.id = 'display';\n    display.disabled = true;\n    calcWrapper.appendChild(display);\n\n    const buttonBox = document.createElement('div');\n    buttonBox.id = 'button_box';\n    calcWrapper.appendChild(buttonBox);\n\n    const addOperationSection = document.createElement('div');\n    const operationNameInput = document.createElement('input');\n    operationNameInput.placeholder = 'Operation Name';\n    const operationActionInput = document.createElement('input');\n    operationActionInput.placeholder = 'Operation Action (e.g., a + b)';\n    const operationSignInput = document.createElement('input');\n    operationSignInput.placeholder = 'Operation Sign';\n    const addOperationButton = document.createElement('button');\n    addOperationButton.innerText = 'Add Operation';\n\n    addOperationSection.appendChild(operationNameInput);\n    addOperationSection.appendChild(operationActionInput);\n    addOperationSection.appendChild(operationSignInput);\n    addOperationSection.appendChild(addOperationButton);\n    calcWrapper.appendChild(addOperationSection);\n\n    const style = document.createElement('style');\n    style.innerHTML = `\n        body{\n        text-align: center;\n        background: #070707;\n        }\n        #calc_wrapper {\n          position: relative;\n          top: 50%;\n          left: 50%;\n          transform: translate(-50%, -20%);\n          background: rgba(0,0,0,0.2);\n          width: 40vw;\n          min-height: 200px;\n          display: flex;\n          flex-direction: column;\n          justify-content: center;\n          align-items: center;\n          padding: 10px;\n          border: 1px solid yellow;\n          border-radius: 15px;\n        }\n\n        #display {\n        background: #c7c7c7;\n            width: 38vw;\n            height: 18px;\n            border: 1px solid #fff;\n            border-radius: 5px;\n            padding-left: 10px;\n            margin-botton: 5px;\n        }\n\n        #button_box{\n            width: 38vw;\n            min-height: 180px;\n            display: flex;\n            flex-flow: row wrap;\n            justify-content: flex-start;\n            align-items: flex-start;\n            padding: 2px 5px;\n            border: 1px solid #fff;\n            border-radius: 5px; \n            margin-botton: 5px;       \n        }\n\n        .button {\n            flex: 1 1 20%;\n            display: flex;\n            justify-content: center;\n            align-items: center;\n            padding: 5px;\n            border: 1px solid #fff;\n            border-radius: 2px;        \n        }\n    `;\n    document.head.appendChild(style);\n\n    return { display, buttonBox, addOperationButton, operationNameInput, operationActionInput, operationSignInput };\n}\n\nclass Operation {\n    execute(a, b) {\n        throw new Error('Method not implemented');\n    }\n}\n\nclass Addition extends Operation {\n    execute(a, b) {\n        return a + b;\n    }\n}\n\nclass Subtraction extends Operation {\n    execute(a, b) {\n        return a - b;\n    }\n}\n\nclass Multiplication extends Operation {\n    execute(a, b) {\n        return a * b;\n    }\n}\n\nclass Division extends Operation {\n    execute(a, b) {\n        return a / b;\n    }\n}\n\nclass Calculator {\n    constructor() {\n        this.operations = {};\n    }\n\n    addOperation(name, sign, operation) {\n        this.operations[name] = operation;\n        this.addButton(name, sign);\n    }\n\n    calculate(operationName, a, b) {\n        const operation = this.operations[operationName];\n        if (!operation) {\n            throw new Error('Operation not supported');\n        }\n        return operation.execute(a, b);\n    }\n\n    addButton(name, sign) {\n        const buttonBox = document.getElementById('button_box');\n        const button = document.createElement('button');\n        button.innerText = sign;\n        button.className = 'button';\n        button.onclick = () => this.handleButtonClick(name);\n        button.title = name;\n        buttonBox.appendChild(button);\n    }\n\n    handleButtonClick(operationName) {\n        const a = parseFloat(prompt(\"Enter first number:\"));\n        const b = parseFloat(prompt(\"Enter second number:\"));\n        const result = this.calculate(operationName, a, b);\n        document.getElementById('display').value = result;\n    }\n}\n\nconst { display, buttonBox, addOperationButton, operationNameInput, operationActionInput, operationSignInput } = createCalculator();\n\nconst calculator = new Calculator();\ncalculator.addOperation('add', '+', new Addition());\ncalculator.addOperation('sustract', '-', new Subtraction());\ncalculator.addOperation('multiply', '*', new Multiplication());\ncalculator.addOperation('divide', '/', new Division());\n\nsetTimeout(()=>{\n    class CustomOperation extends Operation {\n        execute(a, b) {\n            return a ** b; \n        }\n    }\n    calculator.addOperation('powder', '**', new CustomOperation());\n    alert('Class Powder added!')\n}, 2000)\n\naddOperationButton.onclick = function() {\n    const name = operationNameInput.value;\n    const action = operationActionInput.value;\n    const sign = operationSignInput.value;\n\n    if(!name || !action || !sign){\n        alert('You have to fill all the fields name, operation and sign to add a new operation!');\n        return;\n    }\n\n    // Create a new operation class dynamically\n    class CustomOperation extends Operation {\n        execute(a, b) {\n            return eval(action); // Use eval to execute the action\n        }\n    }\n\n    //Note: The use of eval(action) to execute the action is a flexible approach, but it comes with security risks, especially if the input can be influenced by users. If the action string contains malicious code, it could lead to vulnerabilities. Consider using a safer alternative if possible.\n\n    // Add the new operation to the calculator\n    calculator.addOperation(name, sign, new CustomOperation());\n\n    // Clear input fields\n   \n    // Clear input fields\n    operationNameInput.value = '';\n    operationActionInput.value = '';\n    operationSignInput.value = '';\n};\n\n\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/javascript/eulogioep.js",
    "content": "/*\n * PRINCIPIO ABIERTO-CERRADO (OCP)\n * \n * El principio establece que las entidades de software (clases, módulos, funciones, etc.) \n * deberían estar:\n * - ABIERTAS para la extensión: Podemos agregar nuevo comportamiento\n * - CERRADAS para la modificación: No debemos modificar el código existente\n * \n * Beneficios:\n * 1. Código más mantenible y escalable\n * 2. Reduce el riesgo de bugs en código existente\n * 3. Facilita la adición de nuevas funcionalidades\n */\n\n// EJEMPLO INCORRECTO (Violando OCP)\n// ❌ Cada vez que queremos agregar una nueva operación, debemos modificar la clase existente\nclass BadCalculator {\n    calculate(a, b, operation) {\n        switch (operation) {\n            case 'sum':\n                return a + b;\n            case 'subtract':\n                return a - b;\n            case 'multiply':\n                return a * b;\n            case 'divide':\n                return a / b;\n            // Si queremos agregar una nueva operación, debemos modificar esta clase\n            // violando el principio OCP\n            default:\n                throw new Error('Operación no soportada');\n        }\n    }\n}\n\n// EJEMPLO CORRECTO (Siguiendo OCP)\n// Definimos una clase base para las operaciones\nclass Operation {\n    execute(a, b) {\n        throw new Error('Método execute debe ser implementado');\n    }\n\n    getSymbol() {\n        throw new Error('Método getSymbol debe ser implementado');\n    }\n}\n\n// Implementamos cada operación como una clase separada\nclass Addition extends Operation {\n    execute(a, b) {\n        return a + b;\n    }\n\n    getSymbol() {\n        return '+';\n    }\n}\n\nclass Subtraction extends Operation {\n    execute(a, b) {\n        return a - b;\n    }\n\n    getSymbol() {\n        return '-';\n    }\n}\n\nclass Multiplication extends Operation {\n    execute(a, b) {\n        return a * b;\n    }\n\n    getSymbol() {\n        return '*';\n    }\n}\n\nclass Division extends Operation {\n    execute(a, b) {\n        if (b === 0) {\n            throw new Error('No se puede dividir por cero');\n        }\n        return a / b;\n    }\n\n    getSymbol() {\n        return '/';\n    }\n}\n\n// Podemos agregar nuevas operaciones sin modificar el código existente\nclass Power extends Operation {\n    execute(a, b) {\n        return Math.pow(a, b);\n    }\n\n    getSymbol() {\n        return '^';\n    }\n}\n\n// La calculadora que cumple con OCP\nclass Calculator {\n    constructor() {\n        this.operations = new Map();\n    }\n\n    // Método para registrar nuevas operaciones\n    registerOperation(operation) {\n        if (!(operation instanceof Operation)) {\n            throw new Error('La operación debe ser una instancia de Operation');\n        }\n        this.operations.set(operation.getSymbol(), operation);\n    }\n\n    // Método para realizar cálculos\n    calculate(a, b, symbol) {\n        const operation = this.operations.get(symbol);\n        if (!operation) {\n            throw new Error(`Operación ${symbol} no soportada`);\n        }\n        return operation.execute(a, b);\n    }\n\n    // Método para listar operaciones disponibles\n    getAvailableOperations() {\n        return Array.from(this.operations.keys());\n    }\n}\n\n// Clase para formatear los resultados\nclass ResultFormatter {\n    static format(a, b, symbol, result) {\n        return `${a} ${symbol} ${b} = ${result}`;\n    }\n}\n\n// Ejemplo de uso con manejo de errores\nfunction runCalculatorDemo() {\n    try {\n        // Creamos una instancia de la calculadora\n        const calculator = new Calculator();\n\n        // Registramos las operaciones básicas\n        calculator.registerOperation(new Addition());\n        calculator.registerOperation(new Subtraction());\n        calculator.registerOperation(new Multiplication());\n        calculator.registerOperation(new Division());\n\n        // Mostramos las operaciones disponibles\n        console.log('Operaciones disponibles:', calculator.getAvailableOperations());\n\n        // Probamos las operaciones básicas\n        const testCases = [\n            { a: 2, b: 3, symbol: '+' },\n            { a: 5, b: 2, symbol: '-' },\n            { a: 4, b: 3, symbol: '*' },\n            { a: 8, b: 2, symbol: '/' }\n        ];\n\n        testCases.forEach(({ a, b, symbol }) => {\n            const result = calculator.calculate(a, b, symbol);\n            console.log(ResultFormatter.format(a, b, symbol, result));\n        });\n\n        // Agregamos una nueva operación (potencia) sin modificar el código existente\n        calculator.registerOperation(new Power());\n        console.log('\\nNueva operación agregada:');\n        console.log(ResultFormatter.format(2, 3, '^', calculator.calculate(2, 3, '^')));\n\n        // Probamos el manejo de errores\n        console.log('\\nProbando manejo de errores:');\n        console.log(ResultFormatter.format(5, 0, '/', calculator.calculate(5, 0, '/')));\n    } catch (error) {\n        console.error('Error:', error.message);\n    }\n}\n\n// Ejecutamos la demostración\nrunCalculatorDemo();\n\n/*\n * EXPLICACIÓN DE POR QUÉ ESTE DISEÑO CUMPLE CON OCP:\n * \n * 1. ABIERTO PARA EXTENSIÓN:\n *    - Podemos agregar nuevas operaciones creando nuevas clases que extiendan de Operation\n *    - No necesitamos modificar ninguna clase existente\n *    - Cada operación está encapsulada en su propia clase\n * \n * 2. CERRADO PARA MODIFICACIÓN:\n *    - La clase Calculator no necesita ser modificada para agregar nuevas operaciones\n *    - El código existente permanece intacto cuando agregamos nuevas funcionalidades\n *    - La clase base Operation define un contrato claro que no cambia\n * \n * 3. VENTAJAS DE ESTE DISEÑO:\n *    - Fácil de mantener y extender\n *    - Cada operación está aislada y puede ser probada independientemente\n *    - Reduce el acoplamiento entre componentes\n *    - Facilita la adición de nuevas operaciones sin riesgo de afectar las existentes\n * \n * 4. CARACTERÍSTICAS ESPECÍFICAS DE LA IMPLEMENTACIÓN EN JAVASCRIPT:\n *    - Uso de clases ES6\n *    - Uso de Map para almacenar las operaciones\n *    - Validación de tipos en tiempo de ejecución\n *    - Clase auxiliar para formateo de resultados\n *    - Manejo de errores con try-catch\n *    - Uso de métodos estáticos y arrow functions\n */"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/javascript/hectorio23.js",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\n\"use strict\";\n\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA:\n * Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas. \n * Requisitos:\n * - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n * Instrucciones:\n * 1. Implementa las operaciones de suma, resta, multiplicación y división.\n * 2. Comprueba que el sistema funciona.\n * 3. Agrega una quinta operación para calcular potencias.\n * 4. Comprueba que se cumple el OCP.\n*/\n\nclass Operacion {\n    calcular(a, b) {\n        throw new Error('Método calcular debe ser implementado');\n    }\n}\n\nclass Suma extends Operacion {\n    calcular(a, b) {\n        return a + b;\n    }\n}\n\nclass Resta extends Operacion {\n    calcular(a, b) {\n        return a - b;\n    }\n}\n\nclass Multiplicacion extends Operacion {\n    calcular(a, b) {\n        return a * b;\n    }\n}\n\nclass Division extends Operacion {\n    calcular(a, b) {\n        if (b === 0) {\n            throw new Error('División por cero');\n        }\n        return a / b;\n    }\n}\n\nclass Potencia extends Operacion {\n    calcular(a, b) {\n        return Math.pow(a, b);\n    }\n}\n\nclass Calculadora {\n    constructor() {\n        this.operaciones = {};\n    }\n\n    agregarOperacion(nombre, operacion) {\n        this.operaciones[nombre] = operacion;\n    }\n\n    calcular(nombre, a, b) {\n        const operacion = this.operaciones[nombre];\n        if (!operacion) {\n            throw new Error('Operación no soportada');\n        }\n        return operacion.calcular(a, b);\n    }\n}\n\nconst calc = new Calculadora();\ncalc.agregarOperacion('+', new Suma());\ncalc.agregarOperacion('-', new Resta());\ncalc.agregarOperacion('*', new Multiplicacion());\ncalc.agregarOperacion('/', new Division());\ncalc.agregarOperacion('^', new Potencia());\n\nconsole.log(\"[+] - Suma:\", calc.calcular('+', 5, 3));\nconsole.log(\"[+] - Resta:\", calc.calcular('-', 5, 3));\nconsole.log(\"[+] - Multiplicación:\", calc.calcular('*', 5, 3));\nconsole.log(\"[+] - División:\", calc.calcular('/', 5, 3));\nconsole.log(\"[+] - Potencia:\", calc.calcular('^', 5, 3));\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n__________________________________________\n#27 SOLID: PRINCIPIO ABIERTO-CERRADO (OCP)\n------------------------------------------\n * EJERCICIO:\n * Explora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\"\n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas.\n * Requisitos:\n * - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n * Instrucciones:\n * 1. Implementa las operaciones de suma, resta, multiplicación y división.\n * 2. Comprueba que el sistema funciona.\n * 3. Agrega una quinta operación para calcular potencias.\n * 4. Comprueba que se cumple el OCP.\n*/\n\n// ________________________________________________________\n// SIN APLICAR OCP\n// ---------------\nclass Product_ {\n    constructor(name, price, type) {\n        this.name = name;\n        this.price = price;\n        this.type = type;\n    }\n\n    finalPrice() {\n        let discount = 0;\n\n        if (this.type === \"electronics\") {\n            discount = this.price * 0.05;\n        } else if (this.type === \"clothing\") {\n            discount = this.price > 50 ? 10 : 0;\n        }\n        // Si se necesita un nuevo tipo, habría que añadir más condicionales aquí\n\n        return this.price - discount;\n    }\n}\n\nfunction processProduct_(product) {\n    console.log(`Producto: ${product.name}, Precio final: ${product.finalPrice()}`);\n}\n\n\n// ________________________________________________________\n// APLICANDO OCP\n// ---------------\nclass Product {\n    constructor(name, price) {\n        if (new.target === Product) {\n            throw new Error(\"Cannot instantiate an abstract class.\");\n        }\n        this.name = name;\n        this.price = price;\n    }\n\n    applyDiscount() {\n        throw new Error(\"Method 'applyDiscount()' must be implemented.\");\n    }\n\n    finalPrice() {\n        return this.price - this.applyDiscount();\n    }\n}\n\n// Clase concreta\nclass ElectronicsProduct extends Product {\n    applyDiscount() {\n        return this.price * 0.05; // Descuento del 5%\n    }\n}\n\n// Clase concreta\nclass ClothingProduct extends Product {\n    applyDiscount() {\n        return this.price > 50 ? 10 : 0; // Descuento basado en la condición\n    }\n}\n\nfunction processProduct(product) {\n    console.log(`Producto: ${product.name}, Precio final: ${product.finalPrice()}`);\n}\n\n// Pruebas\nconst laptop = new ElectronicsProduct(\"Laptop\", 700);\nconst pants = new ClothingProduct(\"Pants\", 55);\n\nprocessProduct(laptop); // Producto: Laptop, Precio final: 665\nprocessProduct(pants);  // Producto: Pants, Precio final: 45\n\n// ________________________________________________________\n// DIFICULTAD EXTRA\n// ---------------\n\n// Clase base\nclass Calculator {\n    constructor(a, b) {\n        if (typeof a === \"number\" && typeof b === \"number\") {\n            this.a = a;\n            this.b = b;\n        } else {\n            this.a = null;\n            this.b = null;\n            console.error(\"Operación inválida.\");\n        }\n    }\n\n    // Método abstracto simulado\n    mathOperation() {\n        throw new Error(\"El método 'mathOperation()' debe ser implementado.\");\n    }\n\n    printResult() {\n        if (this.a !== null && this.b !== null) {\n            console.log(`Es: ${this.mathOperation()}`);\n        } else {\n            console.error(\"Campos incorrectos.\");\n        }\n    }\n}\n\n// Clases concretas\nclass Sum extends Calculator {\n    mathOperation() {\n        console.log(`\\nSuma de ${this.a} + ${this.b}:`);\n        return this.a + this.b;\n    }\n}\n\nclass Subtraction extends Calculator {\n    mathOperation() {\n        console.log(`\\nResta de ${this.a} - ${this.b}:`);\n        return this.a - this.b;\n    }\n}\n\nclass Multiplication extends Calculator {\n    mathOperation() {\n        console.log(`\\nMultiplicación de ${this.a} * ${this.b}:`);\n        return this.a * this.b;\n    }\n}\n\nclass Division extends Calculator {\n    mathOperation() {\n        console.log(`\\nDivisión de ${this.a} / ${this.b}:`);\n        return this.a / this.b;\n    }\n}\n\nclass Pow extends Calculator {\n    mathOperation() {\n        console.log(`\\nPotencia de ${this.a} ^ ${this.b}:`);\n        return this.a ** this.b;\n    }\n}\n\n// Pruebas\nconst sum = new Sum(2, 2);\nsum.printResult();\n\nconst subtraction = new Subtraction(2, 2);\nsubtraction.printResult();\n\nconst multiplication = new Multiplication(2, 2);\nmultiplication.printResult();\n\nconst division = new Division(2, 2);\ndivision.printResult();\n\nconst power = new Pow(2, 2);\npower.printResult();\n\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/javascript/nlarrea.js",
    "content": "/*\n * EJERCICIO:\n * Explora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas. \n * Requisitos:\n * - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n * Instrucciones:\n * 1. Implementa las operaciones de suma, resta, multiplicación y división.\n * 2. Comprueba que el sistema funciona.\n * 3. Agrega una quinta operación para calcular potencias.\n * 4. Comprueba que se cumple el OCP.\n */\n\n\n// Incorrect\n\nclass BadGeometricForm {\n    drawSquare() {\n        console.log('Drawing a square');\n    }\n\n    drawCircle() {\n        console.log('Drawing a circle');\n    }\n}\n\n\n// Correct\n\nclass GeometricForm {\n    constructor() {\n        if (this.constructor === GeometricForm) {\n            throw new Error('You can\\'t create an instance from GeometricForm class!')\n        }\n    }\n\n    draw() {\n        throw new Error('The method \"draw\" must be implemented!')\n    }\n}\n\n\nclass Square extends GeometricForm {\n    draw() {\n        console.log('Drawing a square!');\n    }\n}\n\n\nclass Circle extends GeometricForm {\n    draw() {\n        console.log('Drawing a circle!');\n    }\n}\n\n\nconst circle = new Circle();\ncircle.draw();  // Drawing a circle!\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas. \n * Requisitos:\n * - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n * Instrucciones:\n * 1. Implementa las operaciones de suma, resta, multiplicación y división.\n * 2. Comprueba que el sistema funciona.\n * 3. Agrega una quinta operación para calcular potencias.\n * 4. Comprueba que se cumple el OCP.\n */\n\n\n/* Create an abstract class -> avoid creating instances of this class, but\nstill allows inherit from it */\nclass Operation {\n    constructor() {\n        if (this.constructor === Operation) {\n            throw new Error('The class Operation can not be instantiated!');\n        }\n    }\n\n    calculate(numOne, numTwo) {\n        throw new Error('The method calculate() must be implemented!');\n    }\n}\n\n\n// Create the different operations\n\n\nclass Sum extends Operation {\n    calculate(numOne, numTwo) {\n        return numOne + numTwo;\n    }\n}\n\n\nclass Subtraction extends Operation {\n    calculate(numOne, numTwo) {\n        return numOne - numTwo;\n    }\n}\n\n\nclass Multiplication extends Operation {\n    calculate(numOne, numTwo) {\n        return numOne * numTwo;\n    }\n}\n\n\nclass Division extends Operation {\n    calculate(numOne, numTwo) {\n        return numOne / numTwo;\n    }\n}\n\n\n// Create the Calculator class\n\n\nclass Calculator {\n    constructor() {\n        this.operations = {};\n    }\n\n    /**\n     * Allows setting a new operation to the Calculator.\n     * @param {String} name The name of the operation to set\n     * @param {Operation} operation The operation that must be implemented\n     */\n    setOperation(name, operation) {\n        this.operations[name] = operation;\n    }\n\n    /**\n     * @param {String} name The name of the operation to use\n     * @param {Number} numOne The first number to use by the operation\n     * @param {Number} numTwo The second number to use by the operation\n     * @returns {Number} The result of the implemented operation\n     */\n    calculate(name, numOne, numTwo) {\n        if (!Object.keys(this.operations).includes(name)) {\n            throw new Error(`The operation \"${name}\" does not exist!`)\n        }\n        return this.operations[name].calculate(numOne, numTwo);\n    }\n}\n\n\n// Create the calculator instance and add the different operations\nconst calculator = new Calculator();\ncalculator.setOperation('sum', new Sum());\ncalculator.setOperation('subtract', new Subtraction());\ncalculator.setOperation('multiply', new Multiplication());\ncalculator.setOperation('divide', new Division());\n\n// Check if the current operations work\nconsole.log(calculator.calculate('sum', 10, 2));  // 12\nconsole.log(calculator.calculate('subtract', 10, 2));  // 8\nconsole.log(calculator.calculate('multiply', 10, 2));  // 20\nconsole.log(calculator.calculate('divide', 10, 2));  // 5\n// console.log(calculator.calculate('pow', 10, 2));  // Error -> The operation \"pow\" does not exist!\n\n\n// Create the Pow operation\n\n\nclass Pow extends Operation {\n    calculate(numOne, numTwo) {\n        return numOne ** numTwo;\n    }\n}\n\n\n// Add the Pow operation to the calculator and check if it works\ncalculator.setOperation('pow', new Pow());\nconsole.log(calculator.calculate('pow', 10, 2));  // 100"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/javascript/parababire.js",
    "content": "// Ejercicio\n\n/* Incorrecto */\n\nclass Animal {\n  constructor(sound) {\n    this.sound = sound\n  }\n\n  makeSound () {\n    switch (this.sound) {\n      case 'meau':\n        console.log(`The animal makes meau!!!`);\n        break;\n      case 'woof':\n        console.log(`The animal makes woof!!!`);\n        break;\n      default:\n        console.log('Please incert an animal sound!');\n        break;\n    }\n  }\n}\nconst animal = new Animal('meau')\nanimal.makeSound()\n\n/* Correcto */\n\nclass Person {\n  constructor(name, occupation) {\n    this.name = name\n    this.occupation = occupation\n  }\n\n  getOccupation() {\n    return this.occupation.getOccupation()\n  }\n}\n\nclass PersonOccupation {\n  getOccupation() {}\n}\n\nclass IndustrialEngineer extends PersonOccupation {\n  getOccupation() {\n    return 'I am an industrial engineer.'\n  }\n}\n\nconst engineer = new Person('Yojan', new IndustrialEngineer())\nconsole.log(`Hola mi nombre es ${engineer.name} soy ${engineer.getOccupation()}`)\n\n// Extra\n\n/* Clase abstracta. No puede ser instanciada directamente pero es capaz de ser heredada por la descendencia */\n\nclass Operation {\n  constructor() {\n    if (new.target === Operation) {\n      throw new TypeError(\"No puedes instanciar la clase abstracta 'Operation' directamente\")\n    }\n  }\n  execute() {\n    throw new Error(\"Método 'execute()' debe ser implementado en la clase hija\")\n  }\n}\n\nclass Addition extends Operation{\n  constructor(a, b) {\n    super()\n    this.a = a\n    this.b = b\n  }\n  execute() {\n    return this.a + this.b\n  }\n}\n\nclass Subtract extends Operation{\n  constructor(a, b) {\n    super()\n    this.a = a\n    this.b = b\n  }\n  execute() {\n    return this.a - this.b\n  }\n}\n\nclass Multiply extends Operation{\n  constructor(a, b) {\n    super()\n    this.a = a\n    this.b = b\n  }\n  execute() {\n    return this.a * this.b\n  }\n}\n\nclass Divide extends Operation{\n  constructor(a, b) {\n    super()\n    this.a = a\n    this.b = b\n  }\n  execute() {\n    return this.a / this.b\n  }\n}\n\nclass Power extends Operation{\n  constructor(a, b) {\n    super()\n    this.a = a\n    this.b = b\n  }\n  execute() {\n    return this.a ** this.b\n  }\n}\n\nclass Calculator {\n  constructor() {\n    this.operations = {}\n  }\n  \n  addOperation(name, operation) {\n    this.operations[name] = operation\n  }\n\n  calculate(name) {\n    if (!this.operations[name]) {\n      throw new Error(`Operación ${name} no es valida`)\n    }\n    return this.operations[name].execute()\n  }\n}\n\nconst calculadora = new Calculator()\ncalculadora.addOperation('addition', new Addition(10, 2))\ncalculadora.addOperation('subtraction', new Subtract(5, 2))\ncalculadora.addOperation('multiplication', new Multiply(9, 2))\ncalculadora.addOperation('division', new Divide(9, 2))\ncalculadora.addOperation('power', new Power(5, 4))\n\nconsole.log(calculadora.calculate('subtraction'))\nconsole.log(calculadora.calculate('addition'))\nconsole.log(calculadora.calculate('multiplication'))\nconsole.log(calculadora.calculate('division'))\nconsole.log(calculadora.calculate('power'))"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/javascript/pedamoci.js",
    "content": "// OCP MAL HECHO\n  class DateNow {\n    getDateNow(info) {\n      const date = new Date\n      switch (info) {\n        case 'day':\n          console.log(`El día es: ${date.getDay()}`)\n          break;\n        case 'month':\n          console.log(`El mes es: ${date.getMonth()}`)\n          break;\n        default:\n          break;\n      }\n    }\n  }\n  console.log('------------- OCP MAL HECHO -------------')\n  const dateNow = new DateNow\n  dateNow.getDateNow('day')\n  dateNow.getDateNow('month')\n\n  // Si necesito agregar una función tengo que modificar el switch\n\n  class DateNow2 {\n    getDateNow(info) {\n      const date = new Date\n      switch (info) {\n        case 'day':\n          console.log(`El día es: ${date.getDay()}`)\n          break;\n        case 'month':\n          console.log(`El mes es: ${date.getMonth()}`)\n          break;\n        case 'year':\n          console.log(`El año es: ${date.getFullYear()}`)\n          break;\n        default:\n          break;\n      }\n    }\n  }\n\n  const dateNow2 = new DateNow2\n  dateNow2.getDateNow('day')\n  dateNow2.getDateNow('month')\n  dateNow2.getDateNow('year')\n\n// OCP BIEN HECHO\nclass DateNow3 {\n  constructor(getDate) {\n    this.getDate = getDate\n  }\n\n  getDateNow() {\n    return this.getDate.getDateNow()\n  }\n}\n\nclass GetDateNow {\n  getDateNow() {}\n}\n\nclass GetDay extends GetDateNow{\n  getDateNow() {\n    const date = new Date\n    return date.getDay()\n  }\n}\n\nclass GetMonth extends GetDateNow{\n  getDateNow() {\n    const date = new Date\n    return date.getMonth()\n  }\n}\n\nconsole.log('\\n------------- OCP BIEN HECHO -------------')\nconst getDay = new DateNow3(new GetDay())\nconsole.log(`El día es: ${getDay.getDateNow()}`)\nconst getMonth = new DateNow3(new GetMonth())\nconsole.log(`El mes es: ${getMonth.getDateNow()}`)\n\n// Si quiero agregar una función \nclass GetYear extends GetDateNow {\n  getDateNow() {\n    const date = new Date\n    return date.getFullYear()\n  }\n}\n\nconst getYear = new DateNow3(new GetYear())\nconsole.log(`El año es: ${getYear.getDateNow()}`)\n\n// -------------------------------------------------- EJERCICIO EXTRA --------------------------------------------------\nclass Calculator {\n  constructor(calculation) {\n    this.calculation = calculation\n  }\n\n  operation(num1, num2) {\n    return this.calculation.operation(num1, num2)\n  }\n}\n\nclass Operations {\n  operation() {}\n}\n\nclass Addition extends Operations{\n  operation(num1, num2) {\n    return num1 + num2\n  }\n}\n\nclass Subtraction extends Operations{\n  operation(num1, num2) {\n    return num1 - num2\n  }\n}\n\nclass Division extends Operations{\n  operation(num1, num2) {\n    if (num2 === 0) return 'No se puede dividir por cero'\n    return num1 / num2\n  }\n}\n\n// Comprobación de que el sistema funciona\nconsole.log('\\n--------------- COMPROBACION DE FUNCIONAMIENTO ---------------')\nconst addition = new Calculator(new Addition())\nconsole.log(`Suma: ${addition.operation(55, 32)}`)\n\nconst subtraction = new Calculator(new Subtraction())\nconsole.log(`Resta: ${subtraction.operation(55, 32)}`)\n\nconst division = new Calculator(new Division())\nconsole.log(`Divición: ${division.operation(55, 5)}`)\n\nclass Exponentiation extends Operations{\n  operation(num1, num2) {\n    return num1 ** num2\n  }\n}\n\nconsole.log('\\n--------------- COMPROBACION DE FUNCIONAMIENTO FINAL ---------------')\nconst exponentiation = new Calculator(new Exponentiation())\nconsole.log(`Suma: ${addition.operation(5465, 3245)}`)\nconsole.log(`Resta: ${subtraction.operation(35480, 54982)}`)\nconsole.log(`Divición: ${division.operation(8464, 154)}`)\nconsole.log(`Exponenciación: ${exponentiation.operation(55, 4)}`)"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/javascript/victor-Casta.js",
    "content": "const readline = require('readline')\n\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout\n})\n\n/*\n  * EJERCICIO:\n  * Explora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\"\n  * y crea un ejemplo simple donde se muestre su funcionamiento\n  * de forma correcta e incorrecta.\n*/\n\n// Funcionamiento incorrecto\n\n/*\nclass ShopVehicles {\n  saleBus() {\n    console.log('Se ha vendido un Bus')\n  }\n\n  saleCar() {\n    console.log('Se ha vendido un auto')\n  }\n}\n*/\n\n// Funcionamiento correcto:\n\nclass ShopVehicles {\n  sale() {\n    console.log('Se ha vendido un auto')\n  }\n}\n\nclass saleTruck extends ShopVehicles {\n  sale() {\n    console.log('Se ha vendido un camión')\n  }\n}\n\nclass saleBus extends ShopVehicles {\n  sale() {\n    console.log('Se ha vendido un bus')\n  }\n}\n\nconst saleTruck1 = new saleTruck()\nsaleTruck1.sale()\n\nconst saleBus1 = new saleBus()\nsaleBus1.sale()\n\n/*\n  * DIFICULTAD EXTRA (opcional):\n  * Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas.\n  * Requisitos:\n  * - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n  * Instrucciones:\n  * 1. Implementa las operaciones de suma, resta, multiplicación y división.\n  * 2. Comprueba que el sistema funciona.\n  * 3. Agrega una quinta operación para calcular potencias.\n  * 4. Comprueba que se cumple el OCP.\n*/\n\nclass Calculator {\n  operation() { return }\n}\n\nclass AdditionOperation extends Calculator {\n  operation(a, b) {\n    return `${a} + ${b} = ${a + b}`\n  }\n}\n\nclass SubtractionOperation extends Calculator {\n  operation(a, b) {\n    return `${a} - ${b} = ${a - b}`\n  }\n}\n\nclass MultiplyOperation extends Calculator {\n  operation(a, b) {\n    return `${a} * ${b} = ${a * b}`\n  }\n}\n\nclass DivideOperation extends Calculator {\n  operation(a, b) {\n    if (b === 0) throw new Error('No se puede dividir por cero')\n    return `${a} / ${b} = ${a / b}`\n  }\n}\n\nclass ExponentiationOperation extends Calculator {\n  operation(a, b) {\n    return `${a} ** ${b} = ${a ** b}`\n  }\n}\n\nfunction MenuCalculator() {\n  console.log('1 - Sumar')\n  console.log('2 - Restar')\n  console.log('3 - Multiplicar')\n  console.log('4 - Dividir')\n  console.log('5 - Potencia')\n  console.log('0 - Salir')\n\n  rl.question('Selección: ', (option) => {\n    if (option == '1') {\n      rl.question('Ingresa el numero A: ', (numberA) => {\n        rl.question('Ingresa el numero B: ', (numberB) => {\n          const addition = new AdditionOperation()\n          console.log(addition.operation(parseInt(numberA), parseInt(numberB)))\n          MenuCalculator()\n        })\n      })\n    } else if (option == '2') {\n      rl.question('Ingresa el numero A: ', (numberA) => {\n        rl.question('Ingresa el numero B: ', (numberB) => {\n          const substraction = new SubtractionOperation()\n          console.log(substraction.operation(parseInt(numberA), parseInt(numberB)))\n          MenuCalculator()\n        })\n      })\n    } else if (option == '3') {\n      rl.question('Ingresa el numero A: ', (numberA) => {\n        rl.question('Ingresa el numero B: ', (numberB) => {\n          const multiply = new MultiplyOperation()\n          console.log(multiply.operation(parseInt(numberA), parseInt(numberB)))\n          MenuCalculator()\n        })\n      })\n    } else if (option == '4') {\n      rl.question('Ingresa el numero A: ', (numberA) => {\n        rl.question('Ingresa el numero B: ', (numberB) => {\n          const divide = new DivideOperation()\n          console.log(divide.operation(parseInt(numberA), parseInt(numberB)))\n          MenuCalculator()\n        })\n      })\n    } else if (option == '5') {\n      rl.question('Ingresa el numero A: ', (numberA) => {\n        rl.question('Ingresa el numero B: ', (numberB) => {\n          const exponentiation = new ExponentiationOperation()\n          console.log(exponentiation.operation(parseInt(numberA), parseInt(numberB)))\n          MenuCalculator()\n        })\n      })\n    } else if (option == '0') {\n      rl.close()\n    } else {\n      console.log('Opción inválida')\n      MenuCalculator()\n    }\n  })\n}\n\nMenuCalculator()"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/kotlin/blackriper.kt",
    "content": "@file:Suppress(\"UNCHECKED_CAST\")\r\n\r\nimport java.util.UUID\r\nimport kotlin.math.pow\r\n\r\n/*\r\nOpen Closed Principle\r\n\r\nEste principio establece que una entidad de software (clase, módulo, función, etc)\r\ndebe quedar abierta para su extensión, pero cerrada para su modificación.\r\n\r\nCon abierta para su extensión, nos quiere decir que una entidad de software debe tener la capacidad\r\nde adaptarse a los cambios y nuevas necesidades de una aplicación, pero con la segunda parte de “cerrada\r\npara su modificación” nos da a entender que la adaptabilidad de la entidad no debe darse\r\ncomo resultado de la modificación del core de dicha entidad si no como resultado de un diseño\r\nque facilite la extensión sin modificaciones.\r\n\r\n*/\r\n\r\n// ejemplo de lo que no debe hacerse\r\n\r\nenum class AuthProviders{\r\n    GOOGLE,\r\n    FACEBOOK,\r\n    GITHUB,\r\n    APPLE\r\n}\r\n\r\ndata class UserData(val userID:UUID,var name:String)\r\n\r\n\r\nclass AuthService{\r\n     fun loginProvider(provider:AuthProviders):UserData{\r\n         return when(provider){\r\n             AuthProviders.GOOGLE-> signInWithGoogle()\r\n             AuthProviders.FACEBOOK-> signInWithFacebook()\r\n             AuthProviders.GITHUB-> signInWithGithub()\r\n             AuthProviders.APPLE-> signInWithApple()\r\n         }\r\n     }\r\n\r\n     private fun signInWithGoogle():UserData{\r\n         return UserData(UUID.randomUUID(),\"Google User\")\r\n     }\r\n\r\n     private fun signInWithFacebook():UserData{\r\n         return UserData(UUID.randomUUID(),\"Facebook User\")\r\n     }\r\n\r\n     private fun signInWithGithub():UserData{\r\n         return UserData(UUID.randomUUID(),\"Github User\")\r\n     }\r\n\r\n     private fun signInWithApple():UserData{\r\n         return UserData(UUID.randomUUID(),\"Apple User\")\r\n     }\r\n}\r\n\r\n/* El Principio SOLID Open Closed se suele resolver utilizando polimorfismo,\r\n clases abstractas, herencia y interfaces en el ejemplo usando herencia*/\r\n\r\nopen class AuthProvider{\r\n    open fun login():UserData{\r\n        return UserData(UUID.randomUUID(),\"User\")\r\n    }\r\n}\r\n\r\n// creamos los diferentes provedores\r\nclass GoogleProvider:AuthProvider(){\r\n    override fun login():UserData{\r\n        return UserData(UUID.randomUUID(),\"Google User\")\r\n    }\r\n}\r\n\r\nclass AppleProvider:AuthProvider(){\r\n    override fun login():UserData{\r\n        return UserData(UUID.randomUUID(),\"Apple User\")\r\n    }\r\n}\r\n\r\n// refactorizamos la clase autService\r\nclass AuthProdService{\r\n    fun loginProvider(provider:AuthProvider):UserData{\r\n        return provider.login()\r\n    }\r\n}\r\n// opcional crear singlenton\r\nobject ProvidersSinglenton{\r\n    val apple=AppleProvider()\r\n    val google=GoogleProvider()\r\n\r\n}\r\n\r\n\r\n\r\nfun exampleOpenClosed(){\r\n    val authService = AuthService()\r\n    val userData = authService.loginProvider(AuthProviders.GOOGLE)\r\n    println(userData)\r\n    // usando principio\r\n    val authProd=AuthProdService()\r\n    val userApple=authProd.loginProvider(ProvidersSinglenton.apple)\r\n    val useGoogle=authProd.loginProvider(ProvidersSinglenton.google)\r\n    println(userApple)\r\n    println(useGoogle)\r\n}\r\n\r\n//ejercicio extra experimiento con genericos sustituir la T por el tipo que quieras\r\ninterface Operation{\r\n    fun<T> execute(num1:T,num2:T):T\r\n}\r\n//crear clases de las operaciones borrar los ifs y solo dejar la suma\r\nclass Add:Operation{\r\n    override fun <T> execute(num1: T, num2: T): T {\r\n      if(num1 is Int && num2 is Int) return  (num1+num2) as T\r\n      if (num1 is Double && num2 is Double) return (num1+num2) as T\r\n      if (num1 is Float && num2 is Float) return (num1+num2) as T\r\n      if (num1 is Long && num2 is Long) return (num1+num2) as T\r\n      throw Exception(\"calculate type not supported\")\r\n    }\r\n\r\n}\r\n\r\nclass Rest:Operation {\r\n    override fun <T> execute(num1: T, num2: T): T {\r\n        if (num1 is Int && num2 is Int) return (num1 - num2) as T\r\n        if (num1 is Double && num2 is Double) return (num1 - num2) as T\r\n        if (num1 is Float && num2 is Float) return (num1 - num2) as T\r\n        if (num1 is Long && num2 is Long) return (num1 - num2) as T\r\n        throw Exception(\"calculate type not supported\")\r\n    }\r\n}\r\n\r\nclass Mul:Operation {\r\n    override fun <T> execute(num1: T, num2: T): T {\r\n        if (num1 is Int && num2 is Int) return (num1 * num2) as T\r\n        if (num1 is Double && num2 is Double) return (num1 * num2) as T\r\n        if (num1 is Float && num2 is Float) return (num1 * num2) as T\r\n        if (num1 is Long && num2 is Long) return (num1 * num2) as T\r\n        throw Exception(\"calculate type not supported\")\r\n    }\r\n}\r\n\r\nclass Div:Operation {\r\n    override fun <T> execute(num1: T, num2: T): T {\r\n        if (num1 is Int && num2 is Int) return (num1 / num2) as T\r\n        if (num1 is Double && num2 is Double) return (num1 / num2) as T\r\n        if (num1 is Float && num2 is Float) return (num1 / num2) as T\r\n        if (num1 is Long && num2 is Long) return (num1 / num2) as T\r\n        throw Exception(\"calculate type not supported\")\r\n    }\r\n}\r\n\r\nclass Calculate{\r\n    fun <T>caculate(num1:T,num2:T,operation:Operation):T{\r\n        if (num1 is Int && num2 is Int) return operation.execute(num1,num2)\r\n        if (num1 is Double && num2 is Double) return operation.execute(num1,num2)\r\n        if (num1 is Float && num2 is Float) return operation.execute(num1,num2)\r\n        if (num1 is Long && num2 is Long) return operation.execute(num1,num2)\r\n        throw Exception(\"calculate type not supported\")\r\n    }\r\n}\r\n\r\n// se cumple el principio open closed porque la clase operation puede ser extendida pero la\r\n//clase calculate no puede ser extendida y no cambia su funcionamiento\r\n\r\nclass Pow:Operation{\r\n    override fun <T> execute(num1: T, num2: T): T {\r\n        if (num1 is Int && num2 is Int) return (num1.toDouble().pow(num2.toDouble())) as T\r\n        if (num1 is Double && num2 is Double) return (num1.pow(num2)) as T\r\n        if (num1 is Float && num2 is Float) return (num1.pow(num2)) as T\r\n        if (num1 is Long && num2 is Long) return (num1.toFloat().pow(num2.toFloat())) as T\r\n        throw Exception(\"calculate type not supported\")\r\n    }\r\n\r\n}\r\n\r\n\r\n\r\n// encapsular las operaciones en un singlenton para mayor comodidad opcional\r\nobject OperationSingleton{\r\n    val add=Add()\r\n    val rest=Rest()\r\n    val mul=Mul()\r\n    val div=Div()\r\n    val pow=Pow()\r\n}\r\n\r\nfun calculatorExamples(){\r\n    val calculator=Calculate()\r\n    println(\"Add: \"+calculator.caculate<Double>(2.5,2.5,OperationSingleton.add))\r\n    println(\"Mul: \"+calculator.caculate<Float>(2.5f,2.5f,OperationSingleton.mul))\r\n    println(\"Div: \"+calculator.caculate<Int>(2,2,OperationSingleton.div))\r\n    println(\"Pow: \"+calculator.caculate<Int>(2,2,OperationSingleton.pow))\r\n}\r\n\r\n\r\n\r\n\r\nfun main() {\r\n    exampleOpenClosed()\r\n    calculatorExamples()\r\n}\r\n\r\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/kotlin/eulogioep.kt",
    "content": "/*\n * Principio Abierto-Cerrado (OCP) de SOLID\n * \n * El principio OCP establece que las entidades de software (clases, módulos, funciones, etc.) \n * deben estar abiertas para la extensión, pero cerradas para la modificación. Esto significa \n * que debemos poder extender el comportamiento de una clase sin modificar su código existente.\n * \n * En este ejemplo, demostraremos cómo aplicar el OCP en el diseño de una calculadora,\n * permitiendo agregar nuevas operaciones sin modificar el código existente.\n */\n\n// Interfaz que define la operación matemática\ninterface Operation {\n    fun execute(a: Double, b: Double): Double\n}\n\n// Implementaciones de las operaciones básicas\nclass Addition : Operation {\n    override fun execute(a: Double, b: Double) = a + b\n}\n\nclass Subtraction : Operation {\n    override fun execute(a: Double, b: Double) = a - b\n}\n\nclass Multiplication : Operation {\n    override fun execute(a: Double, b: Double) = a * b\n}\n\nclass Division : Operation {\n    override fun execute(a: Double, b: Double): Double {\n        if (b == 0.0) throw IllegalArgumentException(\"Cannot divide by zero\")\n        return a / b\n    }\n}\n\n// Calculadora que utiliza el principio OCP\nclass Calculator {\n    private val operations = mutableMapOf<String, Operation>()\n\n    fun addOperation(name: String, operation: Operation) {\n        operations[name] = operation\n    }\n\n    fun calculate(a: Double, b: Double, operationName: String): Double {\n        val operation = operations[operationName] \n            ?: throw IllegalArgumentException(\"Operation not supported\")\n        return operation.execute(a, b)\n    }\n}\n\n// Ejemplo de uso y prueba\nfun main() {\n    val calculator = Calculator()\n\n    // Agregar operaciones básicas\n    calculator.addOperation(\"add\", Addition())\n    calculator.addOperation(\"subtract\", Subtraction())\n    calculator.addOperation(\"multiply\", Multiplication())\n    calculator.addOperation(\"divide\", Division())\n\n    // Probar operaciones básicas\n    println(\"5 + 3 = ${calculator.calculate(5.0, 3.0, \"add\")}\")\n    println(\"5 - 3 = ${calculator.calculate(5.0, 3.0, \"subtract\")}\")\n    println(\"5 * 3 = ${calculator.calculate(5.0, 3.0, \"multiply\")}\")\n    println(\"6 / 3 = ${calculator.calculate(6.0, 3.0, \"divide\")}\")\n\n    // Agregar una nueva operación (potencia) sin modificar el código existente\n    class Power : Operation {\n        override fun execute(a: Double, b: Double) = Math.pow(a, b)\n    }\n    calculator.addOperation(\"power\", Power())\n\n    // Probar la nueva operación\n    println(\"2^3 = ${calculator.calculate(2.0, 3.0, \"power\")}\")\n}\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/kotlin/rikmij.kt",
    "content": "import kotlin.math.pow\n\nfun main() {\n    //Forma incorrecta\n\n    class Specie {\n\n        fun specifySpecie(specie: String) {\n            when (specie) {\n                \"humano\" -> println(\"Hola soy un humano\")\n                \"perro\" -> println(\"Hola soy un perro\")\n                \"gato\" -> println(\"Soy un gato\")\n            }\n        }\n    }\n    val subject1 = Specie()\n    subject1.specifySpecie(\"humano\")\n    val subject2 = Specie()\n    subject2.specifySpecie(\"perro\")\n    /*\n    Esta forma es incorrecta para el OCP porque si hay que añadir especies hay que ir retocando la clase,\n    lo que es lo contrario al principio Open/Closed\n     */\n\n    //Forma correcta\n    abstract class Speciee {\n        abstract fun identifySpecie(): String\n    }\n\n    class Humano(): Speciee() {\n        override fun identifySpecie() = \"Soy un humano con OCP\"\n        }\n    class Perro(): Speciee() {\n        override fun identifySpecie() = \"Soy un perro con OCP\"\n        }\n    class Gato(): Speciee() {\n        override fun identifySpecie() = \"Soy un gato con OCP\"\n        }\n    val human = Humano()\n    println(human.identifySpecie())\n    val dog = Perro()\n    println(dog.identifySpecie())\n    val cat = Gato()\n    println(cat.identifySpecie())\n\n    /*\n    Esta sí es buena forma de aplicar el OCP, pues enemos la clase base, con las funciones y ya\n    a cada especie le crearíamos su clase con sus atributos y sobreescribiendo los métodos comunes\n    que queramos.\n    Estamos añadiendo funcionalidades sin tener que modificar la clase\n     */\n\n    println(\"\\n ${\"*\".repeat(7)} EJERCICIO EXTRA ${\"*\".repeat(7)}\")\n    fun calculator() {\n        print(\"Ingrese el primer número: \")\n        val num1 = readln().toDouble()\n        println(\"¿Qué operación quieres realizar con esos números?\\n\" +\n                \"Suma(+)\\n\" +\n                \"Resta(-)\\n\" +\n                \"Multiplicación(*)\\n\" +\n                \"División(/)\" +\n                \"Exponente(**)\")\n        val operation = readln()\n        when (operation) {\n            \"+\" -> {val op = Sum()\n                println(op.operation(num1))\n            }\n            \"-\" -> {val op = Subst()\n                println(op.operation(num1))\n            }\n            \"*\" -> {val op = Mult()\n                println(op.operation(num1))\n            }\n            \"/\" -> {val op = Div()\n                println(op.operation(num1))\n            }\n            \"**\" -> {val op = PowMat()\n                println(op.operation(num1))\n            }\n            else -> println(\"Opción no válida. Elige una de las disponibles\")\n\n        }\n    }\n    calculator()\n}\n\n\ninterface Calculator {\n    fun operation(num1: Double): Double\n}\n\nclass Sum: Calculator{\n    override fun operation(num1: Double): Double {\n        print(\"Elige un segundo número: \")\n        val num2 = readln().toInt()\n        return num1 + num2\n    }\n}\n\nclass Subst: Calculator {\n    override fun operation(num1: Double): Double {\n        print(\"Elige un segundo número: \")\n        val num2 = readln().toInt()\n        return num1 - num2\n    }\n}\nclass Mult: Calculator {\n    override fun operation(num1: Double): Double {\n        print(\"Elige un segundo número: \")\n        val num2 = readln().toInt()\n        return num1 * num2\n    }\n}\nclass Div: Calculator {\n    override fun operation(num1: Double): Double {\n        print(\"Elige un segundo número: \")\n        val num2 = readln().toInt()\n        return num1 / num2\n    }\n}\n\nclass PowMat: Calculator {\n    override fun operation(num1: Double): Double {\n        print(\"A qué potencia quieres elevarlo? : \")\n        val exp = readln().toDouble()\n\n        return num1.pow(exp)\n    }\n}\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/ocaml/luishendrix92.ml",
    "content": "open Printf\n\n(******************************************************************************)\n(*                                                                            *)\n(*                            Open-Close Principle                            *)\n(*                                                                            *)\n(*  It states that entities (methods, functions, modules, classes) should     *)\n(*  not be altered while adding new functionality (unless for a bug). Means   *)\n(*  that existing code should be open for extension and closed for modifica-  *)\n(*  tion. Altering existing code while adding new functionalities requires    *)\n(*  features to be tested again.                                              *)\n(*                                                                            *)\n(*  In OCaml, a primarily functional language, this principle is interpreted  *)\n(*  very differently than the OOP counterpart as it does not offer easy       *)\n(*  ways to leverage the module system to play around with modules the same   *)\n(*  way we'd play with classes in a language like Java or C#. However, the    *)\n(*  language's way of extending things comes in the form of module functors,  *)\n(*  function composition, variants and pattern matching; along with simple    *)\n(*  {e class types} that can be thought of as interfaces.                     *)\n(*                                                                            *)\n(******************************************************************************)\n\ntype action =\n  | Payment\n  | SomethingElse\n[@@deriving show]\n\nmodule CloudLogService = struct\n  let save_error msg = printf \"Letting CloudLog save this error: %s\\n\" msg\nend\n\nmodule PaymentBroker = struct\n  let inform_error msg =\n    printf \"Letting our payment broker know something went wrong: %s\\n\" msg\n  ;;\nend\n\nmodule AppLogger : sig\n  (* One of the most frequent examples is a logger with different strategies\n     that grows bigger when the developer adds new functionality in the form\n     of a very large if statement (or switch). To refactor this, OOP uses\n     inheritance or interfaces but in OCaml we use functors. *)\n\n  val log_error : origin:action -> string -> unit\nend = struct\n  let log_error ~origin msg =\n    begin\n      match origin with\n      | Payment -> PaymentBroker.inform_error msg\n      | SomethingElse -> ()\n    end;\n    CloudLogService.save_error msg;\n    printf \"[ERROR] [%s] %s\\n\" (show_action origin) msg\n  ;;\nend\n\n(* We can now refactor and maybe achieve something similar to inheritance using\n   functors (modules that return modules) in order to comply with the OCP.\n   Another possible solution would be to use the strategy pattern and/or higher\n   -order functions that we pass everytime we use the base logger. *)\n\nmodule BaseLogger (Extended : sig\n    val log_error : string -> unit\n  end) =\nstruct\n  let log_error ~origin msg =\n    CloudLogService.save_error msg;\n    printf \"[ERROR] [%s] %s\\n\" (show_action origin) msg;\n    Extended.log_error msg\n  ;;\nend\n\nmodule PaymentLogger = BaseLogger (struct\n    let log_error = PaymentBroker.inform_error\n  end)\n\n(* Another common example is creating interfaced classes for every concrete\n   type of a particular abstract type and have them override a method that\n   clients will use regardless of what subtype it belongs to.\n\n   This is handled with pattern-matching in OCaml and it's exactly the type\n   of code that OCP tries to avoid, but all the developer has to do is be\n   smart about where the decision making is done and if modifying it can\n   break things that aren't supposed to break. *)\n\nmodule Shape = struct\n  type t =\n    | Rectangle of float * float\n    | Triangle of float * float\n    | Circle of float\n    | Square of float\n\n  let area = function\n    (* Technically these could be broken into separate functions that maybe live\n       in a module. This declutters the decision making code and enforces SRP. *)\n    | Circle radius -> Float.pi *. radius *. radius\n    | Square length -> length *. length\n    | Triangle (b, h) -> b *. h /. 2.0\n    | Rectangle (w, h) -> w *. h\n  ;;\nend\n\n(* OCaml has had classes (although limited) for a while now and I believe it's\n   wise to use them when your code is heavily reliant on mutable state. *)\nclass type shape = object\n  method area : float\nend\n\nclass rectangle (w : float) (h : float) =\n  object\n    val mutable height = h\n    val mutable width = w\n    method area = width *. height\n  end\n\nclass triangle (b : float) (h : float) =\n  object\n    val mutable base = b\n    val mutable height = h\n    method area = base *. height\n  end\n\nclass circle (r : float) =\n  object\n    val mutable radius = r\n    method area = Float.pi *. radius *. radius\n  end\n\nclass square (l : float) =\n  object\n    val mutable length = l\n    method area = length *. length\n  end\n\nlet _ =\n  let shapes : shape list =\n    [ new rectangle 5.0 3.0\n    ; new triangle 10.0 5.0\n    ; new circle 2.0\n    ; new square 7.0\n    ]\n  in\n  print_endline \"Shape areas:\";\n  shapes\n  |> List.map (fun s -> s#area)\n  |> List.map string_of_float\n  |> List.iter print_endline\n;;\n\n(******************************************************************************)\n(*                                                                            *)\n(*                        DIFICULTAD EXTRA (Opcional)                         *)\n(*                                                                            *)\n(******************************************************************************)\ntype token =\n  | Add\n  | Subtract\n  | Multiply\n  | Divide\n  | Power\n\nlet add a b = a +. b\nlet subtract a b = a -. b\nlet multiply a b = a *. b\nlet divide a b = a /. b\nlet power a b = a ** b\n\ntype binop = token * float * float\n\nlet compute ((op, a, b) : binop) =\n  match op with\n  | Add -> add a b\n  | Subtract -> subtract a b\n  | Multiply -> multiply a b\n  | Divide -> divide a b\n  | Power -> power a b\n;;\n\nlet _ =\n  let ops =\n    [ Add, 3.0, 5.5\n    ; Subtract, 10.0, 11.0\n    ; Multiply, 5.0, 3.0\n    ; Divide, 3.0, 2.0\n    ; Power, 3.0, 2.0\n    ]\n  in\n  print_newline ();\n  print_endline \"Binary operation results:\";\n  ops |> List.map compute |> List.map string_of_float |> List.iter print_endline\n;;\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/php/eulogioep.php",
    "content": "<?php\n/*\n * PRINCIPIO ABIERTO-CERRADO (OCP)\n * \n * El principio establece que las entidades de software (clases, módulos, funciones, etc.) \n * deberían estar:\n * - ABIERTAS para la extensión: Podemos agregar nuevo comportamiento\n * - CERRADAS para la modificación: No debemos modificar el código existente\n * \n * Beneficios:\n * 1. Código más mantenible y escalable\n * 2. Reduce el riesgo de bugs en código existente\n * 3. Facilita la adición de nuevas funcionalidades\n */\n\n// EJEMPLO INCORRECTO (Violando OCP)\n// ❌ Cada vez que queremos agregar una nueva operación, debemos modificar la clase existente\nclass BadCalculator {\n    public function calculate(float $a, float $b, string $operation): float {\n        switch ($operation) {\n            case 'sum':\n                return $a + $b;\n            case 'subtract':\n                return $a - $b;\n            case 'multiply':\n                return $a * $b;\n            case 'divide':\n                return $a / $b;\n            // Si queremos agregar una nueva operación, debemos modificar esta clase\n            // violando el principio OCP\n            default:\n                throw new Exception('Operación no soportada');\n        }\n    }\n}\n\n// EJEMPLO CORRECTO (Siguiendo OCP)\n// Definimos una interfaz para las operaciones\ninterface Operation {\n    public function execute(float $a, float $b): float;\n    public function getSymbol(): string;\n}\n\n// Implementamos cada operación como una clase separada\nclass Addition implements Operation {\n    public function execute(float $a, float $b): float {\n        return $a + $b;\n    }\n\n    public function getSymbol(): string {\n        return '+';\n    }\n}\n\nclass Subtraction implements Operation {\n    public function execute(float $a, float $b): float {\n        return $a - $b;\n    }\n\n    public function getSymbol(): string {\n        return '-';\n    }\n}\n\nclass Multiplication implements Operation {\n    public function execute(float $a, float $b): float {\n        return $a * $b;\n    }\n\n    public function getSymbol(): string {\n        return '*';\n    }\n}\n\nclass Division implements Operation {\n    public function execute(float $a, float $b): float {\n        if ($b === 0.0) {\n            throw new Exception('No se puede dividir por cero');\n        }\n        return $a / $b;\n    }\n\n    public function getSymbol(): string {\n        return '/';\n    }\n}\n\n// Podemos agregar nuevas operaciones sin modificar el código existente\nclass Power implements Operation {\n    public function execute(float $a, float $b): float {\n        return pow($a, $b);\n    }\n\n    public function getSymbol(): string {\n        return '^';\n    }\n}\n\n// La calculadora que cumple con OCP\nclass Calculator {\n    private array $operations;\n\n    public function __construct() {\n        $this->operations = [];\n    }\n\n    // Método para registrar nuevas operaciones\n    public function registerOperation(Operation $operation): void {\n        $this->operations[$operation->getSymbol()] = $operation;\n    }\n\n    // Método para realizar cálculos\n    public function calculate(float $a, float $b, string $symbol): float {\n        if (!isset($this->operations[$symbol])) {\n            throw new Exception(\"Operación $symbol no soportada\");\n        }\n        return $this->operations[$symbol]->execute($a, $b);\n    }\n}\n\n// Ejemplo de uso\ntry {\n    // Creamos una instancia de la calculadora\n    $calculator = new Calculator();\n\n    // Registramos las operaciones básicas\n    $calculator->registerOperation(new Addition());\n    $calculator->registerOperation(new Subtraction());\n    $calculator->registerOperation(new Multiplication());\n    $calculator->registerOperation(new Division());\n\n    // Probamos las operaciones básicas\n    echo \"2 + 3 = \" . $calculator->calculate(2, 3, '+') . PHP_EOL;\n    echo \"5 - 2 = \" . $calculator->calculate(5, 2, '-') . PHP_EOL;\n    echo \"4 * 3 = \" . $calculator->calculate(4, 3, '*') . PHP_EOL;\n    echo \"8 / 2 = \" . $calculator->calculate(8, 2, '/') . PHP_EOL;\n\n    // Agregamos una nueva operación (potencia) sin modificar el código existente\n    $calculator->registerOperation(new Power());\n    \n    // Probamos la nueva operación\n    echo \"2 ^ 3 = \" . $calculator->calculate(2, 3, '^') . PHP_EOL;\n\n    // Probamos un error (división por cero)\n    echo \"5 / 0 = \" . $calculator->calculate(5, 0, '/') . PHP_EOL;\n} catch (Exception $e) {\n    echo \"Error: \" . $e->getMessage() . PHP_EOL;\n}\n\n/*\n * EXPLICACIÓN DE POR QUÉ ESTE DISEÑO CUMPLE CON OCP:\n * \n * 1. ABIERTO PARA EXTENSIÓN:\n *    - Podemos agregar nuevas operaciones creando nuevas clases que implementen la interfaz Operation\n *    - No necesitamos modificar ninguna clase existente\n *    - Cada operación está encapsulada en su propia clase\n * \n * 2. CERRADO PARA MODIFICACIÓN:\n *    - La clase Calculator no necesita ser modificada para agregar nuevas operaciones\n *    - El código existente permanece intacto cuando agregamos nuevas funcionalidades\n *    - La interfaz Operation define un contrato claro que no cambia\n * \n * 3. VENTAJAS DE ESTE DISEÑO:\n *    - Fácil de mantener y extender\n *    - Cada operación está aislada y puede ser probada independientemente\n *    - Reduce el acoplamiento entre componentes\n *    - Facilita la adición de nuevas operaciones sin riesgo de afectar las existentes\n * \n * 4. DIFERENCIAS CON LA VERSIÓN TYPESCRIPT:\n *    - Uso de array asociativo en lugar de Map\n *    - Manejo de tipos flotantes en lugar de number\n *    - Uso de try-catch para el manejo de excepciones\n *    - Sintaxis específica de PHP para declaración de tipos\n */"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/php/miguelex.php",
    "content": "<?php\n\n// Ejercicio Básico\n\nclass Rectangle {\n    public $width;\n    public $height;\n\n    public function __construct($width, $height) {\n        $this->width = $width;\n        $this->height = $height;\n    }\n}\n\nclass Circle {\n    public $radius;\n\n    public function __construct($radius) {\n        $this->radius = $radius;\n    }\n}\n\nclass AreaCalculator {\n    public function calculate($shapes) {\n        $area = 0;\n        foreach ($shapes as $shape) {\n            if ($shape instanceof Rectangle) {\n                echo \"\\nEl area del rectangulo es: \". $shape->width * $shape->height;\n            } elseif ($shape instanceof Circle) {\n                echo \"\\nEl area del circulo es: \". pi() * $shape->radius * $shape->radius;\n            }\n        }\n    }\n}\n\n$shapes = [\n    new Rectangle(5, 10),\n    new Circle(7)\n];\n\necho \"Ejercicio básico (sin cumplir OCP)\";\n$calculator = new AreaCalculator();\necho $calculator->calculate($shapes);\n\n// El problema de esta solución es que si ahroa creamos una clase triangle (por ejemplo) y queremos calcualr su área, debemos modificar AreaCalculator para tener en cuenta la nueva forma\n\ninterface Shape {\n    public function area();\n}\n\nclass Rectangle2 implements Shape {\n    private $width;\n    private $height;\n\n    public function __construct($width, $height) {\n        $this->width = $width;\n        $this->height = $height;\n    }\n\n    public function area() {\n        return $this->width * $this->height;\n    }\n}\n\nclass Circle2 implements Shape {\n    private $radius;\n\n    public function __construct($radius) {\n        $this->radius = $radius;\n    }\n\n    public function area() {\n        return pi() * $this->radius * $this->radius;\n    }\n}\n\nclass AreaCalculator2 {\n    public function calculate($shapes) {\n        \n        foreach ($shapes as $shape) {\n            echo \"\\nEl área de la forma es: \". $shape->area();\n        }\n    }\n}\n\n$shapes = [\n    new Rectangle2(5, 10),\n    new Circle2(7)\n];\n\necho \"\\nEjercicio básico (cumpliendo OCP)\";\n$calculator = new AreaCalculator2();\necho $calculator->calculate($shapes);\n\n// Con este enfoque, la clase Triangle tendría su propia definición de como calcular el área y AreaCalculator2 no se tendría que modificar\n\n// Ejercicio Extra\n\ninterface Operation {\n    public function calculate ($a, $b);\n}\n\nclass Sum implements Operation {\n    public function calculate($a, $b) {\n        return $a + $b;\n    }\n}\n\nclass Substract implements Operation {\n    public function calculate($a, $b) {\n        return $a - $b;\n    }\n}\n\nclass Multiply implements Operation {\n    public function calculate($a, $b) {\n        return $a * $b;\n    }\n}\n\nclass Divition implements Operation{\n    public function calculate($a, $b) {\n        return $a / $b;\n    }\n}\n\nclass Calculator {\n    public function calculate($operation, $a, $b) {\n        return $operation->calculate($a, $b);\n    }\n}\n\n$calculator = new Calculator();\necho \"\\nEjercicio extra\";\necho \"\\nLa suma de 5 y 10 es: \". $calculator->calculate(new Sum(), 5, 10);\necho \"\\nLa resta de 5 y 10 es: \". $calculator->calculate(new Substract(), 5, 10);\necho \"\\nLa multiplicación de 5 y 10 es: \". $calculator->calculate(new Multiply(), 5, 10);\necho \"\\nLa división de 5 y 10 es: \". $calculator->calculate(new Divition(), 5, 10);\n\n// A continuación vamos a añadir la operación potencia.\n\nclass Power implements Operation {\n    public function calculate($a, $b) {\n        return pow($a, $b);\n    }\n}\n\necho \"\\nLa potencia de 5 y 10 es: \". $calculator->calculate(new Power(), 5, 10);\n\n// Como vemos, no hemos tenido que modificar nada en la clase Calculator"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/Aldroide.py",
    "content": "\"\"\"\n    Princpicio Abierto Cerrado (OCP)\n    Explora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\" \n    y crea un ejemplo simple donde se muestre su funcionamiento\n    de forma correcta e incorrecta.\n\"\"\"\n# Ejemplo calculo de salario de un empleado\nfrom abc import ABC, abstractmethod\nfrom typing import Any\n\n\nclass Employee:\n    def __init__(self, name, base_salary):\n        self.name = name\n        self.base_salary = base_salary\n\n    def calculate_salary(self):\n        return self.base_salary\n\n\nclass Part_time_employee(Employee):\n    def __init__(self, name, base_salary, hr_worked):\n        super().__init__(name, base_salary)\n        self.hr_worked = hr_worked\n\n    def calculate_salary(self):\n        return self.base_salary*self.hr_worked\n\n\nclass Comissioned_employee(Employee):\n    def __init__(self, name, base_salary, comission):\n        super().__init__(name, base_salary)\n        self.comission = comission\n\n    def calculate_salary(self):\n        return self.base_salary+self.comission\n\n\nempleado = Employee(\"Aldroide\", 3000)\nempleado_tiempo_parcial = Part_time_employee(\"Emmanuel\", 15, 80)\nempleado_con_comision = Comissioned_employee(\"Samira\", 2500, 500)\n\nprint(f\"Salario de {empleado.name}: {empleado.calculate_salary()}\")\nprint(\n    f\"Salario de {empleado_tiempo_parcial.name}: {empleado_tiempo_parcial.calculate_salary()}\")\nprint(\n    f\"Salario de {empleado_con_comision.name}: {empleado_con_comision.calculate_salary()}\")\n\n\n\"\"\"\n    Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas. \n    Requisitos:\n        - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n    Instrucciones:\n        1. Implementa las operaciones de suma, resta, multiplicación y división.\n        2. Comprueba que el sistema funciona.\n        3. Agrega una quinta operación para calcular potencias.\n        4. Comprueba que se cumple el OCP.\n\"\"\"\n\n\nclass Operation(ABC):\n    @abstractmethod\n    def calculate(self, a, b):\n        pass\n\n\nclass Add(Operation):\n    def calculate(self, a, b):\n        return a + b\n\n\nclass Subtraction(Operation):\n    def calculate(self, a, b):\n        return a - b\n\n\nclass Multiplication(Operation):\n    def calculate(self, a, b):\n        return a * b\n\n\nclass Division(Operation):\n    def calculate(self, a, b):\n        if b == 0:\n            raise ValueError(\"No se puede dividir por cero\")\n        return a / b\n\n\nclass Power(Operation):\n    def calculate(self, a, b):\n        return a ** b\n\n\nclass Calculator:\n    def __init__(self):\n        self.operations = {}\n\n    def add_operation(self, name, operation):\n        if not issubclass(type(operation), Operation):\n            raise TypeError(\n                \"La operacion debe ser una estancia de la clase operación\")\n        self.operations[name] = operation\n\n    def calculate(self, name, a, b):\n        if name not in self.operations:\n            raise ValueError(f\"Operacion {name} no econtrada\")\n        return self.operations[name].calculate(a, b)\n\n\ncalculadora = Calculator()\ncalculadora.add_operation('suma', Add())\ncalculadora.add_operation('resta', Subtraction())\ncalculadora.add_operation('multiplicacion', Multiplication())\ncalculadora.add_operation('division', Division())\ncalculadora.add_operation('potencia', Power())\n\n\nprint(calculadora.calculate('suma', 5, 3))  # 8\nprint(calculadora.calculate('resta', 5, 3))  # 2\nprint(calculadora.calculate('multiplicacion', 5, 3))  # 15\nprint(calculadora.calculate('division', 5, 3))    # 1.666...\nprint(calculadora.calculate('potencia', 5, 3))     # 125\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/BastianAlq.py",
    "content": "from enum import Enum\n\n#  * EJERCICIO:\n#  * Explora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\" \n#  * y crea un ejemplo simple donde se muestre su funcionamiento\n#  * de forma correcta e incorrecta.\n\n\n\"\"\"\n# -------------------------------\n# | OPEN-CLOSE PRINCIPLE (OCP)  |  Información extraída de -> https://devexpert.io/principios-solid-guia-gratis/ \n# -------------------------------\n\n\nOPEN-CLOSE PRINCIPLE (OCP) \nEste prinicipio indica que una entidad de software debe estar abierta para extension pero cerrada para modificaciones.\n\nla forma de llegar a esto está muy relacionada con el principio SRP, aunque decir que se cumple el principio OPEN-CLOSE no \nnecesariamente determinará que se cumpla el SRP y viceversa.\n\nEl principio OPEN-CLOSE generalmente se resuelve utilizando HERENCIA/POLIMORFISMO. en vez de obligar a la clase principal a saber\ncómo realizar una operación, delega esta a los objetos que utiliza, de tal forma que no necesita saber explícitamente cómo\nllevarla a cabo. Estos objetos tendrán una interfaz común que implementarán de forma específica segun sus requerimientos.\n\n¿CÓMO DETECTAR QUE ESTAMOS VIOLANDO EL PRINCIPIO OPEN/CLOSED?\n\nR. una de las formas más sencillas para detectarlo es darnos cuenta de qué clases modificamos a menudo. Si cada vez que hay\nun nuevo requisito o una modificación de los existentes, las mismas clases se ven afectadas, podemos empezar a entender que se\nestá violando este principio.\n\n\"\"\"\n\n#  -------------------------- INICIO FUNCIONAMIENTO INCORRECTO DEL OCP --------------------------\n\n\"\"\"\nEn este ejemplo existe la clase Vehicle, la cual puede representar un vehículo de tipo CAR o de tipo MOTORBIKE.\nImagina que hay una clase con un metodo que se encarga de dibujar un vehiculo por pantalla, por supuesto cada vehiculo\ntiene su forma de ser pintado.\n\n\"\"\"\n\nprint(\"------------ FUNCIONAMIENTO INCORRECTO OCP ------------\")\n\nclass VehicleType(Enum):\n    CAR = 1\n    MOTORBIKE = 2\n\nclass Vehicle:\n    def __init__(self, vehicleType: VehicleType) -> None:\n        self.type = vehicleType\n        \nclass VehiclePrinter:\n    \n    @staticmethod\n    def draw(vehicle: Vehicle):\n        if vehicle.type == VehicleType.CAR:\n            VehiclePrinter.draw_car(vehicle)\n        elif vehicle.type == VehicleType.MOTORBIKE:\n            VehiclePrinter.draw_motorbike(vehicle)\n    \n    @staticmethod\n    def draw_car(vehicle: Vehicle):\n        print(\"Drawing a car\")\n    \n    @staticmethod\n    def draw_motorbike(vehicle: Vehicle):\n        print(\"Drawing a motorbike\")\n    \n\ncar_bmw = Vehicle(VehicleType.CAR)\nmotorbike_ninja = Vehicle(VehicleType.MOTORBIKE)\n\nVehiclePrinter.draw(car_bmw)\nVehiclePrinter.draw(motorbike_ninja)\n\n\n\"\"\"\nMientras no se necesiten pintar otros tipos de vehiculos ni veamos que la secuencia de \n\"if vehicle.type == VehicleType.CAR / MOTORBIKE\" se repita mucho en el codigo, esto deberia estar bien, pero:\n\n¿QUE PASA SI SE NECESITA AGREGAR UN NUEVO TIPO DE VEHICULO? Y LUEGO OTRO, Y OTRO Y OTRO.. \n\nsi esto ocurre, el metodo draw crecerá cada vez que se registre un nuevo tipo de vehiculo y a la vez, \nse deberá crear un nuevo metodo para que dicho tipo de vehiculo sea pintado: ejemplo - draw_truck() - draw_airplane(), etc... \n\nesto implica:\n- Un nuevo enumerado\n- nuevo case o ifs anidados\n- nuevo metodo para pintar el nuevo tipo de vehiculo\n\nEn este caso seria buena idea aplicar el principio OPEN/CLOSED\n\"\"\"\n#  -------------------------- INICIO FUNCIONAMIENTO CORRECTO DEL OCP --------------------------\nprint(\"------------ FUNCIONAMIENTO CORRECTO OCP ------------\")\n\n\"\"\"\nSolucion:\n- Crear una interface Vehicle que contenga el metodo draw (que luego se definirá en la clase concreta)\n- las clases concretas representaran al tipo de vehiculo (Car,Truck,Motorbike,etc)\n- el metodo estatico draw_vehicle de VehiclePrinter recibe cualquier vehiculo identificandolo por su interface Vehicle.\n\ncada vez que se cree un nuevo tipo de vehiculo, debe implementar la interface Vehicle e sobreescribir el metodo draw.\nel metodo estatico draw_vehicle de VehiclePrinter recibe un objeto vehicle: Vehicle que llama a su metodo draw.\n\nesto cumple el principio OPEN-CLOSED ya que si se ingresa un nuevo tipo de vehiculo solo debe implementar la interface \nVehicle y hacer un override al metodo. no se modifica ninguna otra clase, a diferencia del ejemplo anterior.\n\"\"\"\n\nfrom abc import ABC, abstractmethod\n\nclass Vehicle(ABC):\n    \n    @abstractmethod\n    def draw(self):\n        pass \n    \nclass Car(Vehicle):\n    \n    def draw(self):\n        print(\"Drawing car\")\n    \nclass MotorBike(Vehicle):\n    \n    def draw(self):\n        print(\"Drawing motorbike\")\n        \nclass Truck(Vehicle):\n    \n    def draw(self):\n        print(\"Drawing truck\")\n        \n        \nclass VehiclePrinter():\n    \n    @staticmethod\n    def draw_vehicle(vehicle: Vehicle):\n        vehicle.draw()\n\n\ntruck = Truck()\ncar = Car()\nmotorbike = MotorBike()\n\nVehiclePrinter.draw_vehicle(truck)\nVehiclePrinter.draw_vehicle(car)\nVehiclePrinter.draw_vehicle(motorbike)\n\n#  *\n#  * DIFICULTAD EXTRA (opcional):\n#  * Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas. \n#  * Requisitos:\n#  * - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n#  * Instrucciones:\n#  * 1. Implementa las operaciones de suma, resta, multiplicación y división.\n#  * 2. Comprueba que el sistema funciona.\n#  * 3. Agrega una quinta operación para calcular potencias.\n#  * 4. Comprueba que se cumple el OCP.\n\nprint(\"------------- DIFICULTAD EXTRA ----------------\")\n    \nclass Operation(ABC):\n    \n    @abstractmethod\n    def execute(a,b):\n        pass\n\n    \nclass Calculator:\n    \n    def __init__(self) -> None:\n        self.operations = {}\n    \n    def add_operation(self, name: str ,operation: Operation):\n        self.operations[name] = operation\n        \n    def calculate(self, operation_name,a,b):\n        if operation_name not in self.operations:\n            raise ValueError(f\"La operación {operation_name} no está soportada.\")\n        return self.operations[operation_name].execute(a, b)\n        \n\nclass Addition(Operation):\n    def execute(self, a, b):\n        return a + b\n\nclass Substraction(Operation):\n    def execute(self, a, b):\n        return a - b\n\nclass Multiplication(Operation):\n    def execute(self, a, b):\n        return a * b\n    \n    \ncalculator = Calculator()\ncalculator.add_operation(\"addition\", Addition())\ncalculator.add_operation(\"substraction\", Substraction())\ncalculator.add_operation(\"multiplication\", Multiplication())\n\nprint(calculator.calculate(\"addition\",2,5))         # 7\nprint(calculator.calculate(\"substraction\",2,5))     # -3\nprint(calculator.calculate(\"multiplication\",2,5))   # 10"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/CesarCarmona30.py",
    "content": "from abc import ABC, abstractmethod\nimport math\n'''\n  EJERCICIO\n'''\n# Incorrecto \n\nclass Circle:\n  \n  def __init__(self, radius):\n    self.radius = radius\n\nclass Rectangle:\n\n  def __init__(self, height, width):\n    self.height = height\n    self.width = width\n\nclass Square:\n\n  def __init__(self, side):\n    self.side = side\n\nclass AreaCalculator:\n  def calculate_area(self, shape):\n    if isinstance(shape, Circle):\n      return math.pi * shape.radius ** 2\n    elif isinstance(shape, Rectangle):\n      return shape.height * shape.width\n\n# Correcto\n\nclass Shape(ABC):\n  @abstractmethod\n  def area(self):\n    pass\n\nclass Circle(Shape):\n  def __init__(self, radius):\n    self.radius = radius\n\n  def area(self):\n    return math.pi * self.radius ** 2\n  \nclass Rectangle(Shape):\n  def __init__(self, height, width):\n    self.height = height\n    self.width = width\n\n  def area(self):\n    return self.height * self.width\n  \nclass Square(Shape):\n  def __init__(self, side):\n    self.side = side\n\n  def area(self):\n    return self.side ** 2;\n\nclass AreaCalculator:\n  def calculateArea(self, shape):\n    return shape.area()\n  \n\ncircle = Circle(7)\nrectangle = Rectangle(4, 8)\nsquare = Square(13)\n\ncalculator = AreaCalculator()\n\nprint(f\"Área del círculo: {calculator.calculateArea(circle)}\")\nprint(f\"Área del rectangulo: {calculator.calculateArea(rectangle)}\")\nprint(f\"Área del cuadrado: {calculator.calculateArea(square)}\")\n\n\n'''\n  EXTRA\n'''\n\nclass Operation(ABC):\n  def __init__(self, value_a, value_b):\n    self.value_a = value_a\n    self.value_b = value_b\n\n  @abstractmethod\n  def result(self):\n    pass\n\nclass Add(Operation):\n  def result(self):\n    return self.value_a + self.value_b\n\nclass Subtract(Operation):\n  def result(self):\n    return self.value_a - self.value_b\n  \nclass Multiply(Operation):\n  def result(self):\n    return self.value_a * self.value_b\n  \nclass Divide(Operation):\n  def result(self):\n    return self.value_a / self.value_b\n  \nclass Calculator:\n  def operation(self, operation: Operation):\n    return operation.result()\n  \nadd = Add(5, 8)\nsub = Subtract(5, 8)\nmult = Multiply(5, 8)\ndivd = Divide(5, 8)\n\ncalculator = Calculator()\n\nprint(f\"La suma, 5 + 8 es: {calculator.operation(add)}\")\nprint(f\"La resta, 5 - 8 es: {calculator.operation(sub)}\")\nprint(f\"La multiplicación, 5 * 8 es: {calculator.operation(mult)}\")\nprint(f\"La división, 5 / 8 es: {calculator.operation(divd)}\")\n\nclass Exponentiation(Operation):\n  def result(self):\n    return self.value_a ** self.value_b\n\nexp = Exponentiation(5, 8)\nprint(f\"La potencia, 5 ^ 8 es: {calculator.operation(exp)}\")"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/Chrisdev00.py",
    "content": "\"\"\"\n* EJERCICIO:\n* Explora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\" \n* y crea un ejemplo simple donde se muestre su funcionamiento\n* de forma correcta e incorrecta.\n*\n* DIFICULTAD EXTRA (opcional):\n* Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas. \n* Requisitos:\n* - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n* Instrucciones:\n* 1. Implementa las operaciones de suma, resta, multiplicación y división.\n* 2. Comprueba que el sistema funciona.\n* 3. Agrega una quinta operación para calcular potencias.\n* 4. Comprueba que se cumple el OCP.\n\"\"\"\n\n# Forma Incorrecta de aplicar el OCP(Open Close Principle)\n\nclass Order:\n\n    items= []\n    quantities = []\n    prices = []\n    status = \"open\"\n\n    def add_item(self, name, quantity, price):\n        self.items.append(name)\n        self.quantities.append(quantity)\n        self.prices.append(price)\n\n    def total_price(self):\n        total = 0\n        for i in range(len(self.prices)):\n            total += self.quantities[i] * self.prices[i]\n        return total\n    \nclass PaymentProcessor:\n    def pay_debit(self, order, security_code):\n        print(\"Procesando el tipo de pago 'débito'\")\n        print(f\"Verificando codigo de seguridad: {security_code}\")\n        order.status = \"paid\"\n    def pay_credit(self, order, security_code):\n        print(\"Procesando el tipo de pago 'credito'\")\n        print(f\"Verificando codigo de seguridad: {security_code}\")\n        order.status = \"paid\"\n    def pay_paypal(self, order, security_code):\n        print(\"Procesando el tipo de pago 'Paypal'\")\n        print(f\"Verificando codigo de seguridad: {security_code}\")\n        order.status = \"paid\"\n\n\norder = Order()\norder.add_item(\"Keyboard\", 1, 50)\norder.add_item(\"SSD\", 1, 150)\norder.add_item(\"USB Cable\", 2, 5)\n\nprint(order.total_price())\nprocessor = PaymentProcessor()\nprocessor.pay_debit(order, \"0372846\")\n\n# Forma correcta de aplicar el principio (OCP)\n\nfrom abc import ABC, abstractmethod\n\nclass Order:\n\n    def __init__(self):\n        self.items= []\n        self.quantities = []\n        self.prices = []\n        self.status = \"open\"\n\n    def add_item(self, name, quantity, price):\n        self.items.append(name)\n        self.quantities.append(quantity)\n        self.prices.append(price)\n\n    def total_price(self):\n        total = 0\n        for i in range(len(self.prices)):\n            total += self.quantities[i] * self.prices[i]\n        return total\n    \nclass PaymentProcessor(ABC):\n    @abstractmethod\n    def pay (self, order, security_code):\n        pass\n\nclass DebitPaymentProcessor(PaymentProcessor):\n    def pay(self, order, security_code):\n        print(\"Procesando el tipo de pago 'débito'\")\n        print(f\"Verificando codigo de seguridad: {security_code}\")\n        order.status = \"paid\"\n\nclass CreditPaymentProcessor(PaymentProcessor):\n    def pay(self, order, security_code):\n        print(\"Procesando el tipo de pago 'credito'\")\n        print(f\"Verificando codigo de seguridad: {security_code}\")\n        order.status = \"paid\"\n\nclass PaypalPaymentProcessor(PaymentProcessor):\n    def pay(self, order, security_code):\n        print(\"Procesando el tipo de pago 'Paypal'\")\n        print(f\"Verificando codigo de seguridad: {security_code}\")\n        order.status = \"paid\"\n\n\norder = Order()\norder.add_item(\"Keyboard\", 1, 50)\norder.add_item(\"SSD\", 1, 150)\norder.add_item(\"USB Cable\", 2, 5)\n\nprint(f\"El precio total es: {order.total_price()}\")\nprocessor = PaypalPaymentProcessor()\nprocessor.pay(order, \"0372846\")\nprint(f\"Estatus: {order.status}\")\n\n\n########### ---------------------------------- EXTRA ------------------------------------------ #############\n\nfrom abc import ABC, abstractmethod\n\nclass Calculator:\n    \n    def __init__(self):\n        self.operations = {\n            \"suma\": SumaOperation(),\n            \"resta\": RestaOperation(),\n            \"multiplicacion\": MultiOperation(),\n            \"division\": DivisionOperation()\n        }\n\n    def add_operation(self, name, operation):\n        self.operations[name] = operation\n\n    def get_operation(self, name):\n        return self.operations.get(name)\n    \n    def execute(self, name, num1, num2):\n        operation = self.get_operation(name)\n        if operation:\n            return operation.calculate(num1, num2)\n        else:\n            raise ValueError(f\"Operacion '{name}' no soportada.\")\n\nclass Operation(ABC):\n    @abstractmethod\n    def calculate(self, num1, num2):\n        pass\n\nclass SumaOperation(Operation):\n    def calculate(self, num1, num2):\n        return num1 + num2\n    \nclass RestaOperation(Operation):\n    def calculate(self, num1, num2):\n        return num1 - num2\n    \nclass MultiOperation(Operation):\n    def calculate(self, num1, num2):\n        return num1 * num2\n    \nclass DivisionOperation(Operation):\n    def calculate(self, num1, num2):\n        if num2 == 0:\n            raise ValueError(\"Cannot divide by zero\")\n        return num1 / num2\n    \nclass PoteciaOperation(Operation):\n    def calculate(self, num1, num2):\n        return num1 ** num2\n    \n\ncalculator = Calculator()\ncalculator.add_operation(\"potencia\", PoteciaOperation())\n\nprint(f\"Suma: {calculator.execute('suma', 4, 3)}\")\nprint(f\"Resta: {calculator.execute('resta', 10, 5)}\")\nprint(f\"Multiplicación: {calculator.execute('multiplicacion', 7, 6)}\")\nprint(f\"División: {calculator.execute('division', 8, 2)}\")\nprint(f\"Potencia: {calculator.execute('potencia', 2, 3)}\")\n\ntry:\n    print(f\"Mod: {calculator.execute('mod', 10, 3)}\")\nexcept ValueError as e:\n    print(e)\n\n\n\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/EmmanuelMMontesinos.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n */\n\"\"\"\n'Sin Aplicar'\nclass Programador_0:\n    def __init__(self,nombre,salario,puesto) -> None:\n        self.nombre = nombre\n        self.salario = salario\n        self.puesto = puesto\n\n\n    def pagar_nomina(self):\n        print(f\"{self.nombre} recibe su nomina de {self.puesto}: {self.salario}€\")\n\n# Prueba\n\nemmanuel = Programador_0(\"Emmanuel\",1000,\"Traini\")\nemmanuel.pagar_nomina()\n\nmoure = Programador_0(\"Brais\",5000,\"Senior\")\nmoure.pagar_nomina()\n\n'Aplicado'\nclass Programador:\n    def __init__(self, nombre) -> None:\n        self.nombre = nombre\n    def pagar_nomina(self):\n        raise NotImplementedError(\"Esta es la clase base\")\n    \nclass Traini(Programador):\n    def __init__(self, nombre) -> None:\n        super().__init__(nombre)\n        self.salario = 1000\n    def pagar_nomina(self):\n        print(f\"{self.nombre} recibe su nomina de Traini: {self.salario}€\")\n\nclass Senior(Programador):\n    def __init__(self, nombre) -> None:\n        super().__init__(nombre)\n        self.salario = 5000\n    def pagar_nomina(self):\n        print(f\"{self.nombre} recibe su nomina de Senior: {self.salario + 200}€\")\n\n# Prueba\nemmanuel = Traini(\"Emmanuel\")\nemmanuel.pagar_nomina()\n\nmoure = Senior(\"Brais\")\nmoure.pagar_nomina()\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas. \n * Requisitos:\n * - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n * Instrucciones:\n * 1. Implementa las operaciones de suma, resta, multiplicación y división.\n * 2. Comprueba que el sistema funciona.\n * 3. Agrega una quinta operación para calcular potencias.\n * 4. Comprueba que se cumple el OCP.\n\"\"\"\nclass Calculo:\n    def __init__(self) -> None:\n        self.operaciones = {}\n\n    def agregar_operacion(self,nombre,operacion):\n        self.operaciones[nombre] = operacion\n\n    def resultado(self,a,b,operacion):\n        print(f\"Resultado de {operacion}: {self.operaciones[operacion].hacer_calculo(a,b)}\")\n        \nclass Operacion:\n    def hacer_calculo(self,a,b):\n        raise NotImplementedError(\"Clase Base de operaciones\")\n    \nclass Sumar(Operacion):\n    def hacer_calculo(self, a, b):\n        return a + b\n    \nclass Restar(Operacion):\n    def hacer_calculo(self, a, b):\n        return a - b\n    \nclass Multiplicar(Operacion):\n    def hacer_calculo(self, a, b):\n        return a * b\n    \nclass Dividir(Operacion):\n    def hacer_calculo(self, a, b):\n        return a / b\n\nclass Potencia(Operacion):\n    def hacer_calculo(self, a, b):\n        return a ** b\n\n# Pruebas\n\ncalculadora = Calculo()\ncalculadora.agregar_operacion(\"sumar\",Sumar())\ncalculadora.agregar_operacion(\"restar\",Restar())\ncalculadora.agregar_operacion(\"multiplicar\",Multiplicar())\ncalculadora.agregar_operacion(\"dividir\",Dividir())\ncalculadora.agregar_operacion(\"potencia\",Potencia())\n\ncalculadora.resultado(5,5,\"sumar\")\ncalculadora.resultado(5,5,\"restar\")\ncalculadora.resultado(5,5,\"multiplicar\")\ncalculadora.resultado(5,5,\"dividir\")\ncalculadora.resultado(5,5,\"potencia\")"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/Gordo-Master.py",
    "content": "# 27 - Solid OCP\n\n# Significado de Abierto-Cerrado (Open-Close Principle, OCP):\n# La clase debe estar cerrado a modificación, pero abierto a ampliacion del codigo.\n\n# Incorrecta\n\nfrom abc import ABC, abstractmethod\n\n\"\"\"\nclass CalculadoraEnvio():\n    \n    def calcular(self, tipo_envio, peso: float):\n        \n        if tipo_envio == \"Normal\":\n            return f\"{1.05 * peso :.2f}\"\n        \n        elif tipo_envio == \"Express\":\n            return f\"{1.1 * peso:.2f}\"\n        \n        else:\n            return False\n        \n\ncal_envios = CalculadoraEnvio()\n\nprint(cal_envios.calcular(\"Normal\", 20.5))\nprint(cal_envios.calcular(\"Express\",20.5))\nprint(cal_envios.calcular(\"VIP\", 20.5))\n\"\"\"\n\n# Correcta\n\nclass Envio(ABC):\n\n    @abstractmethod\n    def cal_costo(self, peso):\n        pass\n\n\nclass EnvioNormal(Envio):\n\n    def cal_costo(self, peso):\n        return f\"{1.05 * peso :.2f}\"\n    \n\n\nclass EnvioExpress(Envio):\n\n    def cal_costo(self, peso):\n        return f\"{1.5 * peso :.2f}\"\n    \n\nprint(EnvioNormal().cal_costo(20.5))\nprint(EnvioExpress().cal_costo(20.5))\n\nprint()\n\n\n\"\"\"\nEjercicio Extra\n\"\"\"\n\nclass Operat(ABC):\n\n    @abstractmethod\n    def operation(self, num_1, num_2):\n        pass\n\n\nclass Suma(Operat):\n\n    def operation(self, num_1, num_2):\n        return num_1 + num_2\n\n\nclass Resta(Operat):\n\n    def operation(self, num_1, num_2):\n        return num_1 - num_2\n    \n\nclass Multiplicacion(Operat):\n\n    def operation(self, num_1, num_2):\n        return num_1 * num_2\n    \n\nclass Division(Operat):\n\n    def operation(self, num_1, num_2):\n        return num_1 / num_2\n    \n\nclass Calculadora():\n\n    def calc(self, operat: Operat, num_1, num_2):\n        return operat.operation(num_1,num_2)\n    \n\ncalculdora = Calculadora()\n\nprint(calculdora.calc(Suma(), 5, 8))\nprint(calculdora.calc(Resta(), 5, 8))\nprint(calculdora.calc(Multiplicacion(), 5, 8))\nprint(calculdora.calc(Division(), 5, 8))\n\nclass Potencia(Operat):\n\n    def operation(self, num_1, num_2):\n        return num_1 ** num_2\n    \nprint(calculdora.calc(Potencia(), 5, 8))"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/Jairo-Alejandro.py",
    "content": "\n\"\"\"\nPrincipio OCP (Abierto-Cerrado)\nEstablece que una clase debe estar abierta para su extension pero cerrada a la hora  de modificarla \n\"\"\"\n\n# Ejemplo incorrecto\n\n#lectura de sensores \n\nclass ReadSensors():\n    def read_sensors(self, sensor_type):\n        if sensor_type == 'temperature':\n            return self.read_sensors_temperature()\n        elif sensor_type == 'humidity':\n            return self.read_sensors_humidity()\n        # en caso de querer agregar otro sensor se debe modificar esta clase \n\n    def read_sensors_temperature(self):\n        return 'Temperature 25 C '\n    \n    def read_sensors_humidity(self):\n        return 'Humidity 50% '\n\nRead = ReadSensors()\n\nprint(Read.read_sensors('temperature'))\nprint(Read.read_sensors('humidity'))\n\n# Ejemplo correcto \n\n# clase comun para todos los sensores\nclass Sensor():\n    def read(self):\n        pass\n\nclass ReadTemperature(Sensor):\n    def read(self):\n        return 'Temperature 34 C'\n\nclass ReadHumidity(Sensor):\n    def read(self):\n        return 'Humidity 70%'\n\nclass ReadSensors():\n    def __init__(self, sensor):\n        self.sensor = sensor\n    \n    def read_sensor(self):\n        return self.sensor.read()\n    \ntemperature = ReadSensors(ReadTemperature())\nprint(temperature.read_sensor())\n\nhumidity = ReadSensors(ReadHumidity())\nprint(humidity.read_sensor())\n\n\"\"\"Dificultad Extra \"\"\"\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas. \n * Requisitos:\n * - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n * Instrucciones:\n * 1. Implementa las operaciones de suma, resta, multiplicación y división.\n * 2. Comprueba que el sistema funciona.\n * 3. Agrega una quinta operación para calcular potencias.\n * 4. Comprueba que se cumple el OCP.        \n\"\"\"\n\n# Clase comun para totas las operaciones \nclass Operation():\n    def execute(self,a,b):\n        pass\n# Clases con las operaciones\nclass Addition(Operation):\n    def execute(self, a, b):\n        return a + b \n\nclass Subtraction(Operation):\n    def execute(self, a, b):\n        return a - b\n\nclass Multiplication(Operation):\n    def execute(self, a, b):\n        return a*b \n\nclass Division(Operation):\n    def execute(self, a, b):\n        if b == 0 : \n            raise ValueError(\"Cannot divide by zero\")\n        return a / b \n\n# clases de la interfaz \n\nclass Calculator():\n    def __init__(self, operation):\n        self.operation = operation\n    \n    def calculate(self , a , b):\n        return self.operation.execute(a,b)\n\naddition = Calculator(Addition())\nprint(addition.calculate(10, 5))  \n\nsubtraction = Calculator(Subtraction())\nprint(subtraction.calculate(10, 5))  \n\nmultiplication = Calculator(Multiplication())\nprint(multiplication.calculate(10, 5))  \n\ndivision = Calculator(Division())\nprint(division.calculate(10, 5))  \n\n#agregando la operacion potencia     \nclass power(Operation):\n    def execute(self, a, b):\n        return a**b\n\npower = Calculator(power())\nprint(power.calculate(2, 2))\n\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/JesusWay69.py",
    "content": "import os, platform\nfrom math import pi\n\nif (platform.platform().startswith(\"macOS\") or platform.platform().startswith(\"Linux\")):\n    os.system('clear')\nelse:\n    os.system('cls')\n\"\"\"\n * EJERCICIO:\n * Explora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\"\n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n \"\"\"\n    \nclass Figure:\n    def __init__(self, data1, data2):#Creamos una clase para generar objetos de figuras geométricas\n        self.data1 = data1 # que se crearán aportando 2 medidas, base y altura si es un rectángulo\n        self.data2 = data2 # o radio y PI si se trata de un círculo por ejemplo\n\nclass RectangleArea: # Al crear una clase con una función específica para calcular el área de un rectángulo\n    def calc(object:Figure):  # no nos serviría para calcular el área de otra figura geométrica\n        return object.data1 * object.data2\n    \nrectangle = Figure(2,4)\nprint(f\"El área del rectángulo es: {RectangleArea.calc(rectangle)}\")\n\n\nclass CalulateArea(Figure):#Si creamos una clase genérica que herede los objetos de la clase padre Figure\n    def rectangle(object:Figure) -> int: # podremos ampliar el cálculo de áreas de más figuras añadiendo más métodos a esa clase hija\n        return object.data1 * object.data2 # añadiendo a esta directamente los objetos creados en la clase padre y llamando\n                                            # a su correspondiente método\n    def circle_for_radius(object):\n        if object.data2 == None or (object.data1 == object.data2):\n            return round((object.data1 ** 2 * pi),2)\n        else:\n            return \"Operación incorrecta\"\n        \n    def circle_for_diameter(object:Figure):\n        if object.data2 == None or (object.data1 == object.data2):\n            return round(((object.data1 / 2) ** 2 * pi),2)\n        else:\n            return \"Operación incorrecta\"\n        \n    def circle_for_perimeter(object:Figure):\n        if object.data2 == None or (object.data1 == object.data2):\n            return round((object.data1 * 2),2)\n        else:\n            return \"Operación incorrecta\"\n        \n    def square(object:Figure):\n        if object.data2 == None or (object.data1 == object.data2):\n            return object.data1 ** 2\n        else:\n            return \"Operación incorrecta\"\n    \n    def triangle(object:Figure) -> int:\n        return round((object.data1 * object.data2 / 2), 2)\n    \nsquare1 = Figure(4,None)\ncircle1 = Figure(4, None)\ncircle2 = Figure(circle1.data1 * 2, None)\ncircle3 = Figure(circle2.data1 * pi, None)\ntriangle1 = Figure(3,7)\nprint (f\"El área del cuadrado es: {CalulateArea.square(square1)}\")\nprint (f\"El área del círculo por su radio es: {CalulateArea.circle_for_radius(circle1)}\")\nprint (f\"El área del círculo por su diámetro es: {CalulateArea.circle_for_diameter(circle2)}\")\nprint (f\"El área del círculo por su perímetro es: {CalulateArea.circle_for_perimeter(circle3)}\")\nprint (f\"El área del triángulo es: {CalulateArea.triangle(triangle1)}\")\nprint()\n\n \n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n* Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas.\n* Requisitos:\n* - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n* Instrucciones:\n* 1. Implementa las operaciones de suma, resta, multiplicación y división.\n* 2. Comprueba que el sistema funciona.\n* 3. Agrega una quinta operación para calcular potencias.\n* 4. Comprueba que se cumple el OCP.\"\"\"\n    \nclass Operator:\n    def __init__(self,num1:int, num2:int) -> None:\n        self.num1 = num1\n        self.num2 = num2\n\n    def my_sum(self) -> int:\n        return self.num1 + self.num2\n    def my_subt(self) -> int:\n        return self.num1 - self.num2\n    def my_mult(self) -> int:\n        return self.num1 * self.num2\n    def my_div(self) -> float:\n        return round((self.num1 / self.num2),2)\n        \nop1 = Operator(2,3)\nprint(\"Suma de 2 + 3 desde clase Operator:\", op1.my_sum())\nprint(\"Resta de 2 - 3 desde clase Operator:\",op1.my_subt())\nprint(\"División de 2 entre 3 desde clase Operator:\",op1.my_div())\nprint(\"Multiplicación de 2 x 3 desde clase Operator:\",op1.my_mult())\nprint()\n\nclass Power(Operator):\n    def __init__(self,num1:int, num2:int) -> None:\n        self.num1 = num1\n        self.num2 = num2     \n\n    def my_pow(self) -> int:\n        acc = self.num1\n        for i in range(1, self.num2):\n            acc = Operator(self.num1 , acc).my_mult()   \n        return acc\n    \nop2 = Power(2,3)\nprint(\"Suma de 2 + 3 desde clase Power:\",op2.my_sum())\nprint(\"Resta de 2 - 3 desde clase Power:\",op2.my_subt())\nprint(\"División de 2 entre 3 desde clase Power:\",op2.my_div())\nprint(\"Multiplicación de 2 x 3 desde clase Power:\",op2.my_mult())\nprint(\"Cálculo de 2 elevado a 3 desde clase Power:\",op2.my_pow())\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/JheisonQuiroga.py",
    "content": "# Author: Jheison Duban Quiroga Quintero\n# Github: https://github.com/JheisonQuiroga\n\n\"\"\"/*\n * EJERCICIO:\n * Explora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\"\n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\"\"\"\n\n# Violación del OCP\n\nclass AreaCalculator:\n    def get_area(self, shape, *args):\n        match shape:\n            case \"circulo\": \n                return 3.14 * args[0] ** 2\n            case \"cuadrado\":\n                return args[0] ** 2\n            \n\n# Siguiendo el OCP\n\nfrom abc import ABC, abstractmethod\nimport math\n\nclass Shape(ABC):\n    @abstractmethod\n    def get_area(self) -> float:\n        ...\n\nclass Circle(Shape):\n    def __init__(self, radio) -> None:\n        self.radio = radio\n\n    def get_area(self) -> float:\n        return math.pi * self.radio ** 2\n    \nclass Square(Shape):\n    def __init__(self, side):\n        self.side = side\n\n    def get_area(self):\n        return self.side ** 2\n\n# Clase que calcula la forma\nclass AreaCalculator:\n    def get_area(self, shape:Shape):\n        return shape.get_area()\n    \n\n\nc1 = Circle(5)\nprint(AreaCalculator().get_area(c1))\n\n\n\"\"\"*\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas.\n * Requisitos:\n * - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n * Instrucciones:\n * 1. Implementa las operaciones de suma, resta, multiplicación y división.\n * 2. Comprueba que el sistema funciona.\n * 3. Agrega una quinta operación para calcular potencias.\n * 4. Comprueba que se cumple el OCP.\n */\"\"\"\n\n# Clase Base\nclass Operation(ABC):\n    @abstractmethod\n    def calculate(self, n1, n2):\n        ...\n\n# Operaciones Concretas\nclass Add(Operation):\n    def calculate(self, n1, n2):\n        return n1 + n2\n    \n\nclass Subtract(Operation):\n    def calculate(self, n1, n2):\n        return n1 - n2\n    \nclass Multiply(Operation):\n    def calculate(self, n1 , n2):\n        return n1 * n2\n    \nclass Division(Operation):\n    def calculate(self, n1, n2):\n        if n2 == 0:\n            raise ValueError(\"El divisor no puede ser 0\")\n        return n1 / n2\n\n# Clase que delega de las operaciones\nclass Calculator:\n    def calculate(self, n1, n2, operation: Operation):\n        return operation.calculate(n1, n2)\n    \nif __name__ == \"__main__\":\n\n    calculator1 = Calculator()\n    print(calculator1.calculate(10, 2, Add()))\n        \n    # Agregando una quinta operación (Potencia)\n    class Power(Operation):\n        def calculate(self, n1, n2):\n            return n1 ** n2\n        \n\n    print(calculator1.calculate(5, 2, Power()))"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/Mauricio-Leyva.py",
    "content": "\"\"\"\nMauricio Leyva\n\n\nCalculadora interactiva que cumple con el Principio Abierto-Cerrado (OCP)\n\nDescripción:\nDesarrolla una calculadora que necesita realizar diversas operaciones matemáticas.\n\nRequisitos:\n- Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n\nInstrucciones:\n1. Implementa las operaciones de suma, resta, multiplicación y división.\n2. Comprueba que el sistema funciona.\n3. Agrega una quinta operación para calcular potencias.\n4. Comprueba que se cumple el OCP.\n\nEste código implementa una calculadora interactiva que cumple con todos estos requisitos,\npermitiendo fácilmente la adición de nuevas operaciones sin modificar el código existente.\n\"\"\"\n\n\nfrom abc import ABC, abstractmethod\n\nclass Operation(ABC):\n    @abstractmethod\n    def execute(self, a, b):\n        pass\n\n    @abstractmethod\n    def get_symbol(self):\n        pass\n\nclass Addition(Operation):\n    def execute(self, a, b):\n        return a + b\n    \n    def get_symbol(self):\n        return \"+\"\n\nclass Subtraction(Operation):\n    def execute(self, a, b):\n        return a - b\n    \n    def get_symbol(self):\n        return \"-\"\n\nclass Multiplication(Operation):\n    def execute(self, a, b):\n        return a * b\n    \n    def get_symbol(self):\n        return \"*\"\n\nclass Division(Operation):\n    def execute(self, a, b):\n        if b == 0:\n            raise ValueError(\"No se puede dividir por cero\")\n        return a / b\n    \n    def get_symbol(self):\n        return \"/\"\n\nclass Power(Operation):\n    def execute(self, a, b):\n        return a ** b\n    \n    def get_symbol(self):\n        return \"^\"\n\nclass Calculator:\n    def __init__(self):\n        self.operations = {}\n\n    def register_operation(self, operation):\n        self.operations[operation.get_symbol()] = operation\n\n    def get_available_operations(self):\n        return list(self.operations.keys())\n\n    def calculate(self, operation_symbol, a, b):\n        if operation_symbol not in self.operations:\n            raise ValueError(f\"Operación '{operation_symbol}' no soportada\")\n        return self.operations[operation_symbol].execute(a, b)\n\ndef get_user_input():\n    while True:\n        try:\n            a = float(input(\"Ingrese el primer número: \"))\n            b = float(input(\"Ingrese el segundo número: \"))\n            return a, b\n        except ValueError:\n            print(\"Por favor, ingrese números válidos.\")\n\ndef main():\n    calc = Calculator()\n    \n    # Registro de operaciones\n    calc.register_operation(Addition())\n    calc.register_operation(Subtraction())\n    calc.register_operation(Multiplication())\n    calc.register_operation(Division())\n    calc.register_operation(Power())\n\n    while True:\n        print(\"\\nOperaciones disponibles:\")\n        for op in calc.get_available_operations():\n            print(f\"  {op}\")\n        \n        operation = input(\"Elija una operación (o 'q' para salir): \")\n        \n        if operation.lower() == 'q':\n            break\n        \n        if operation not in calc.get_available_operations():\n            print(\"Operación no válida. Intente de nuevo.\")\n            continue\n        \n        a, b = get_user_input()\n        \n        try:\n            result = calc.calculate(operation, a, b)\n            print(f\"Resultado: {a} {operation} {b} = {result}\")\n        except ValueError as e:\n            print(f\"Error: {e}\")\n\nif __name__ == \"__main__\":\n    main()"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/Nicojsuarez2.py",
    "content": "# #27 SOLID: PRINCIPIO ABIERTO-CERRADO (OCP)\n> #### Dificultad: Media | Publicación: 01/07/24 | Corrección: 08/07/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas. \n * Requisitos:\n * - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n * Instrucciones:\n * 1. Implementa las operaciones de suma, resta, multiplicación y división.\n * 2. Comprueba que el sistema funciona.\n * 3. Agrega una quinta operación para calcular potencias.\n * 4. Comprueba que se cumple el OCP.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/Sac-Corts.py",
    "content": "from abc import ABC, abstractmethod\n\n# Correcto\n\nclass Shape(ABC):\n    @abstractmethod\n    def area(self):\n        pass\n\nclass Circle(Shape):\n    def __init__(self, radius):\n        self.radius = radius\n    \n    def area(self):\n        return 3.14 * self.radius * self.radius\n\nclass Square(Shape):\n    def __init__(self, side):\n        self.side = side\n    \n    def area(self):\n        return self.side * self.side\n    \nclass Triangle(Shape):\n    def __init__(self, base, height):\n        self.base = base\n        self.height = height\n    \n    def area(self):\n        return 0.5 * self.base * self.height\n\nclass AreaCalculator:\n    def calculate_area(self, shape: Shape):\n        return shape.area()\n\nshapes = [Circle(2), Square(3), Triangle(4, 5)]\ncalculator = AreaCalculator()\nfor shape in shapes:\n    print(calculator.calculate_area(shape))\n\n    \n# Incorrecto\n\nclass Circle:\n    def __init__(self, radius):\n        self.radius = radius\n\nclass Square:\n    def __init__(self, side):\n        self.side = side\n\nclass AreaCalculator:\n    def calculate_area(self, shape):\n        if isinstance(shape, Circle):\n            return 3.14 * shape.radius * shape.radius\n        elif isinstance(shape, Square):\n            return shape.side * shape.side\n        # Si queremos agregar una nueva forma, necesitamos modificar esta clase.\n\n\n### Ejercicio Extra ###\n\nclass Operation(ABC):\n    @abstractmethod\n    def execute(self, a, b):\n        pass\n\nclass Addition(Operation):\n    def execute(self, a, b):\n        return a + b\n    \nclass Subtraction(Operation):\n    def execute(self, a, b):\n        return a - b\n    \nclass Multiplication(Operation):\n    def execute(self, a, b):\n        return a * b\n    \nclass Division(Operation):\n    def execute(self, a, b):\n        return a / b\n    \nclass Power(Operation):\n    def execute(self, a, b):\n        return a ** b\n    \nclass Calculator:\n    def __init__(self):\n        self.operations = {}\n    \n    def add_operation(self, name, operation):\n        self.operations[name] = operation\n\n    def execute_operation(self, name, a, b):\n        if name not in self.operations:\n            raise ValueError(f\"Operation {name} Not Found\")\n        return self.operations[name].execute(a, b)\n\naddition = Addition()\nsubtraction = Subtraction()\nmultiplication = Multiplication()\ndivision = Division()\npower = Power()\ncalculator = Calculator()\n\ncalculator.add_operation(\"add\", addition)\ncalculator.add_operation(\"subtract\", subtraction)\ncalculator.add_operation(\"multiply\", multiplication)\ncalculator.add_operation(\"divide\", division)\ncalculator.add_operation(\"power\", power)\n\nprint(calculator.execute_operation(\"add\", 5, 3))        \nprint(calculator.execute_operation(\"subtract\", 5, 3))   \nprint(calculator.execute_operation(\"multiply\", 5, 3))   \nprint(calculator.execute_operation(\"divide\", 5, 3))     \nprint(calculator.execute_operation(\"power\", 4, 2))     \n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/SooHav.py",
    "content": "# 27 SOLID: PRINCIPIO ABIERTO-CERRADO (OCP)\nfrom abc import ABC, abstractmethod\nimport logging\n\n# Ejercicio\n# Ejemplo Pato sin SRP\n\n\nclass Pato():\n\n    def __init__(self, nombre):\n        self.nombre = nombre\n\n    def vuela(self):\n        print(f\"{self.nombre} vuela.\")\n\n    def nada(self):\n        print(f\"{self.nombre} nada.\")\n\n    def dice(self) -> str:\n        return \"Quack\"\n\n    def saluda(self, pato2):\n        print(f\"{self.nombre}: {self.dice()}, hola {pato2.nombre}\")\n\n\n# Uso\nprint(\"Sin SRP\")\npato1 = Pato(nombre=\"Daisy\")\npato2 = Pato(nombre=\"Donald\")\npato1.vuela()\npato1.nada()\npato1.saluda(pato2)\nprint(\"\\n\")\n\n# Ejemplo Pato con SRP\n\n\nclass Pato():\n    \"\"\"Clase que define los patos\"\"\"\n\n    def __init__(self, nombre):\n        self.nombre = nombre\n\n    def vuela(self):\n        print(f\"{self.nombre} vuela.\")\n\n    def nada(self):\n        print(f\"{self.nombre} nada.\")\n\n    def dice(self) -> str:\n        return \"Quack\"\n\n\nclass Dialogo():\n    \"\"\"Clase que define la comunicacion entre patos\"\"\"\n\n    def __init__(self, formato):\n        self.formato = formato\n\n    def conversacion(self, pato1: Pato, pato2: Pato):\n        frase1 = f\"{pato1.nombre}: {pato1.dice()}, ¡Ay, {\n            pato2.nombre}! ¡Casi me caigo al intentar atrapar un pez!\"\n        frase2 = f\"{pato2.nombre}: {pato2.dice()}, ¡Otra vez, {\n            pato1.nombre}? Ten más cuidado la próxima vez.\"\n        conversacion = [frase1, frase2]\n        print(*conversacion,\n              f\"(Extracto de {self.formato})\",\n              sep='\\n')\n\n\n# Uso\nprint(\"Con SRP\")\npato1 = Pato(nombre=\"Donald\")\npato2 = Pato(nombre=\"Daisy\")\npato1.vuela()\npato2.nada()\nformato1 = Dialogo(formato=\"historieta\")\nformato1.conversacion(pato1, pato2)\n\n# Ejemplo Pato con SRP y OCP\n\n\nclass Pato():\n    \"\"\"Clase que define los patos\"\"\"\n\n    def __init__(self, nombre, color, edad):\n        self.nombre = nombre\n        self.color = color\n        self.edad = edad\n\n    def vuela(self) -> str:\n        print(f\"{self.nombre} vuela.\")\n\n    def nada(self) -> str:\n        print(f\"{self.nombre} nada.\")\n\n    def dice(self) -> str:\n        return \"Quack\"\n\n    def describe(self) -> str:\n        print(f\"{self.nombre} es un pato de color {\n              self.color} de {self.edad} años.\")\n\n\nclass Dialogo(ABC):\n    \"\"\"Clase base abstracta que define la comunicación entre patos\"\"\"\n    @abstractmethod\n    def conversacion(self, pato1: Pato, pato2: Pato, mensaje1: str, mensaje2: str):\n        pass\n\n\nclass DialogoHistorieta(Dialogo):\n    \"\"\"Clase para el diálogo en formato historieta\"\"\"\n\n    def conversacion(self, pato1: Pato, pato2: Pato, mensaje1: str, mensaje2: str):\n        frase1 = f\"{pato1.nombre}: {pato1.dice()}, {mensaje1}\"\n        frase2 = f\"{pato2.nombre}: {pato2.dice()}, {mensaje2}\"\n        conversacion = [frase1, frase2]\n        print(*conversacion,\n              f\"(Extracto de historieta)\",\n              sep='\\n')\n\n\nclass DialogoFormal(Dialogo):\n    \"\"\"Clase para el diálogo en un formato más formal\"\"\"\n\n    def conversacion(self, pato1: Pato, pato2: Pato, mensaje1: str, mensaje2: str):\n        frase1 = f\"{pato1.nombre}: Buen día, {pato2.nombre}. {mensaje1}\"\n        frase2 = f\"{pato2.nombre}: Estoy bien, {pato1.nombre}. {mensaje2}\"\n        conversacion = [frase1, frase2]\n        print(*conversacion,\n              f\"(Extracto de diálogo formal)\",\n              sep='\\n')\n\n\n# Uso\nprint(\"Con SRP y OCP\")\npato1 = Pato(nombre=\"Donald\", color=\"blanco\", edad=5)\npato2 = Pato(nombre=\"Daisy\", color=\"amarillo\", edad=4)\npato1.vuela()\npato2.nada()\npato1.describe()\nprint()\n\n# DialogoHistorieta\nformato_historieta = DialogoHistorieta()\nformato_historieta.conversacion(pato1, pato2,\n                                mensaje1=\"¡Ay, Daisy! ¡Casi me caigo al intentar atrapar un pez!\",\n                                mensaje2=\"¡Otra vez, Donald? Ten más cuidado la próxima vez.\")\nprint()\n# DialogoFormal\nformato_formal = DialogoFormal()\nformato_formal.conversacion(pato1, pato2,\n                            mensaje1=\"¿Cómo estás?\",\n                            mensaje2=\"Gracias por preguntar.\")\nprint()\n\n\"\"\"\nObservaciones:\nImplementar ABC, y en particular abstractmethod, en las clases ayuda a seguir el principio OCP,\nporque define clases que pueden agregar nuevas funcionalidades sin alterar el código existente\nmediante un diseño modular.\n\nAl usar clases abstractas, se definen comportamientos comunes en una clase base y\nse permite que las clases derivadas personalicen o extiendan esos comportamientos.\nEsto facilita la adición de nuevas funcionalidades sin modificar el código existente.\n\"\"\"\n\n# Extra\n\n# Configurar Logger\nlogging.basicConfig(level=logging.WARNING,\n                    format='%(asctime)s - %(levelname)s - %(message)s')\n\n\nclass Calculadora(ABC):\n    \"\"\"Clase base abstracta que define la aplicación de cálculos\"\"\"\n    @abstractmethod\n    def operacion(self):\n        pass\n\n    @abstractmethod\n    def impresion(self):\n        pass\n\n\ndef redondeo(funcion):\n    def nueva_funcion(*args, **kwargs):\n        logging.debug(\"Implementando funcion de redondeo\")\n        try:\n            resultado = funcion(*args, **kwargs)\n            if resultado is None:\n                return None\n            elif isinstance(resultado, tuple):\n                return tuple(round(val, 2) for val in resultado)\n            else:\n                return round(resultado, 2)\n        except Exception as e:\n            logging.error(f\"Error en la función '{funcion.__name__}': {e}\")\n            return None\n    return nueva_funcion\n\n\nclass Suma(Calculadora):\n    logging.debug(\"Implementando funcion de Suma\")\n\n    def __init__(self, sumando1: float, sumando2: float) -> float:\n        self.sumando1 = sumando1\n        self.sumando2 = sumando2\n\n    @redondeo\n    def operacion(self):\n        try:\n            suma_total = self.sumando1 + self.sumando2\n            return suma_total\n        except Exception as e:\n            logging.error(f\"Error al calcular la suma: {e}\")\n            return None\n\n    def impresion(self):\n        suma_total = self.operacion()\n        if suma_total is not None:\n            print(f\"La suma de {self.sumando1} y {\n                  self.sumando2} dio como resultado {suma_total}\")\n            logging.debug(\"La implementación de suma fue exitosa\")\n        else:\n            logging.warning(\"No se pudo realizar la suma.\")\n\n\nclass Resta(Calculadora):\n    logging.debug(\"Implementando funcion de Resta\")\n\n    def __init__(self, minuendo: float, sustraendo: float) -> float:\n        self.minuendo = minuendo\n        self.sustraendo = sustraendo\n\n    @redondeo\n    def operacion(self):\n        try:\n            resto = self.minuendo - self.sustraendo\n            return resto\n        except Exception as e:\n            logging.error(f\"Error al calcular la resta: {e}\")\n            return None\n\n    def impresion(self):\n        resto = self.operacion()\n        if resto is not None:\n            print(f\"La resta de {self.minuendo} y {\n                  self.sustraendo} dio como resultado {resto}\")\n            logging.debug(\"La implementación de resta fue exitosa\")\n        else:\n            logging.warning(\"No se pudo realizar la resta.\")\n\n\nclass Multiplicacion(Calculadora):\n    logging.debug(\"Implementando funcion de Multiplicación\")\n\n    def __init__(self, factor1: float, factor2: float) -> float:\n        self.factor1 = factor1\n        self.factor2 = factor2\n\n    @redondeo\n    def operacion(self):\n        try:\n            producto = self.factor1 * self.factor2\n            return producto\n        except Exception as e:\n            logging.error(f\"Error al calcular la multiplicación: {e}\")\n            return None\n\n    def impresion(self):\n        producto = self.operacion()\n        if producto is not None:\n            print(f\"La multiplicación de {self.factor1} y {\n                  self.factor2} dio como resultado {producto}\")\n            logging.debug(\"La implementación de multiplicació fue exitosa\")\n        else:\n            logging.warning(\"No se pudo realizar la multiplicación.\")\n\n\nclass Division(Calculadora):\n    logging.debug(\"Implementando funcion de división\")\n\n    def __init__(self, dividendo: float, divisor: float) -> float:\n        self.dividendo = dividendo\n        self.divisor = divisor\n\n    @redondeo\n    def operacion(self):\n        try:\n            if self.divisor == 0:\n                raise ValueError(\"División por cero no está permitida.\")\n            cociente = self.dividendo / self.divisor\n            resto = self.dividendo % self.divisor\n            return cociente, resto\n        except Exception as e:\n            logging.error(f\"Error al calcular la división: {e}\")\n            return None\n\n    def impresion(self):\n        resultado = self.operacion()\n        if resultado is not None:\n            cociente, resto = resultado\n            print(f\"La división de {self.dividendo} y {\n                  self.divisor} dio como resultado cociente {cociente} y resto {resto}\")\n            logging.debug(\"La implementación de división fue exitosa\")\n        else:\n            logging.warning(f\"No se puede realizar la división de {\n                            self.dividendo} por {self.divisor}.\")\n\n\nclass Potencia(Calculadora):\n    logging.debug(\"Implementando funcion de potencia\")\n\n    def __init__(self, base: int, exponente: float) -> float:\n        self.base = base\n        self.exponente = exponente\n\n    @redondeo\n    def operacion(self):\n        try:\n            resultado = self.base ** self.exponente\n            return resultado\n        except Exception as e:\n            logging.error(f\"Error al calcular la potencia: {e}\")\n            return None\n\n    def impresion(self):\n        resultado = self.operacion()\n        if resultado is not None:\n            print(f\"La potenciación de {self.base} y {\n                  self.exponente} dio como resultado {resultado}.\")\n            logging.debug(\"La implementación de potencia fue exitosa\")\n        else:\n            logging.warning(\"No se pudo realizar la potenciación.\")\n\n\n# Uso\ns = Suma(4, 5)\ns.impresion()\n\nr = Resta(9, 3)\nr.impresion()\n\nm = Multiplicacion(7, 6)\nm.impresion()\n\nd = Division(20, 0)\nd.impresion()\n\nd = Division(20, 4)\nd.impresion()\n\np = Potencia(2, 2)\np.impresion()\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/Trufoplus.py",
    "content": "###############################################################################\n###   EJERCICIO\n###############################################################################\nclass Animal:\n    \"\"\"\n    Ejemplo incorrecto de usar OCP\n    \"\"\"\n    def sonido(self, animal):\n        if animal == \"perro\":\n            print('Guau guau!')\n        elif animal == \"gato\":\n            print('miauuuu!')\n        else:\n            print(\"Ese animal no lo conozco\")\n\n\n\nfrom abc import ABC, abstractmethod\n\nclass Animal(ABC):\n    \"\"\"\n    Ejemplo correcto de usar OCP\n    \"\"\"\n    @abstractmethod\n    def sonido(self):\n        pass\n\n\nclass Perro(Animal):\n    def sonido(self):\n        return 'Guau!'\n\nclass Gato(Animal):\n    def sonido(self):\n        return 'Miauuu!'\n    \n# Uso\ndef emitir_sonido(animal: Animal):\n    print(animal.sonido())\n\nperro = Perro()\ngato = Gato()\n\nemitir_sonido(perro) \nemitir_sonido(gato) \n\n\n###############################################################################\n###   DIFICULTAD EXTRA\n###############################################################################\nfrom abc import ABC, abstractmethod\n\n\nclass Calculadora(ABC):\n    \"\"\"\n    Una calculadora expectacular\n    Definimos Calculadora como una clase abstracta usando ABC y decoramos el \n    método resultado con @abstractmethod. Esto asegura que Calculadora no pueda \n    ser instanciada directamente y que cualquier subclase deba implementar el \n    método resultado.\n    \"\"\"\n    @abstractmethod            \n    def resultado(self, a, b):\n        pass\n    \n\nclass Suma(Calculadora):\n    def resultado(self, a, b):\n        return a + b\n\n\nclass Resta(Calculadora):\n    def resultado(self, a, b):\n        return a - b\n    \n\nclass Multiplicacion(Calculadora):\n    def resultado(self, a, b):\n        return a * b\n    \n\nclass Division(Calculadora):\n    def resultado(self, a, b):\n        return a/b\n    \n\n\n#Uso\ndef calcular(operacion: Calculadora, a, b):\n    return operacion.resultado(a, b)\n\n# Instanciando las operaciones\nsuma = Suma()\nresta = Resta()\nmultiplicacion = Multiplicacion()\ndivision = Division()\n\n# Variables para las operaciones\na = 5\nb = 10\nprint(\"\\nSuma: \", calcular(suma, a, b))\nprint(\"Resta:\", calcular(resta, a, b))          \nprint(\"Multiplicación:\", calcular(multiplicacion, a, b))  \nprint(\"División:\", calcular(division, a, b))     "
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/adra-dev.py",
    "content": "\"\"\"\nEJERCICIO:\nExplora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, \nOCP)\" y crea un ejemplo simple donde se muestre su funcionamiento de \nforma correcta e incorrecta.\n\nDIFICULTAD EXTRA(opcional):\nDesarrolla una calculadora que necesita realizar diversas operaciones\nmatemáticas.\nRequisitos:\n- Debes diseñar un sistema que permita agregar nuevas operaciones \nutilizando el OCP.\n\nInstrucciones:\n1. Implementa las operaciones de suma, resta, multiplicación y \ndivisión.\n2. Comprueba que el sistema funciona.\n3. Agrega una quinta operación para calcular potencias.\n4. Comprueba que se cumple el OCP.\n\nby adra-dev\n\"\"\"\n\n\"\"\"\nOpen-Closed Principle (OCP):\nEl principio open closed para el diseño orientado a objetos fue \nintroducido por Bertran Meyer en 1988 y este declara:\n\n    \"Las entidades del software(clases, módulos, funciones. etc.)\n    deberían estar abiertas para extender su funcionalidad pero \n    cerradas para su modificación.\"\n\ndocumentacion:\"https://realpython.com/solid-principles-python/\"\n    \nPara entender a que se refiere el principio open-closed considera el \nsiguiente ejemplo.\n\"\"\"\n\n\nfrom math import pi\n\nclass Shape:\n    def __init__(self, shape_type, **kwargs):\n        self.shape_type = shape_type\n        if self.shape_type == \"rectangle\":\n            self.width = kwargs[\"width\"]\n            self.height = kwargs[\"height\"]\n        elif self.shape_type == \"circle\":\n            self.radius = kwargs[\"radius\"]\n\n    def calculate_area(self):\n        if self.shape_type == \"rectangle\":\n            return self.width * self.height\n        elif self.shape_type == \"circle\":\n            return pi * self.radius**2\n        \n\nrectangle = Shape(\"rectangle\", width=10, height=5)\nprint(rectangle.calculate_area())\n\ncircle = Shape(\"circle\", radius=5)\nprint(circle.calculate_area())\n\n\"\"\"\nLa clase shape funciona. Tu puedes crear circulos y rectangulos, \ncalcular su área, etc. a pesar de eso la clase luce muy mal. algo se \nve mal a primera vista.\n\nImagina que necesitas agregar una nueva figura cuadrado, ¿cómo sería?\nBueno, la opcion aqui seria agregar más cláusulas elif al método .__\ninit__() y al método .calculate_area(), para que así puedas agregar \nlos requerimientos a la figura cuadrado.\n\nTener que realizar estos cambias para agregar una nueva figura \nsignifica que tu clase está abierta a modificación lo cual viola el\nprincipio open-closed. aquí hay una posible corrección del código \n\n\n\"\"\"\n\nfrom abc import ABC, abstractmethod\n\nclass Shape(ABC):\n    def __init__(self, shape_type):\n        self.shape_type = shape_type\n\n    @abstractmethod\n    def calculate_area(self):\n        pass\n\n\nclass Circle(Shape):\n    def __init__(self, radius):\n        super().__init__(\"Circle\")\n        self.radius = radius\n\n    def calculate_area(self):\n        return pi * self.radius**2\n\n\nclass Rectangle(Shape):\n    def __init__(self, width, height):\n        super().__init__(\"rectangle\")\n        self.width = width\n        self.height = height\n\n    def calculate_area(self):\n        return self.width * self.height\n    \n\nclass Square(Shape):\n    def __init__(self, side):\n        super().__init__(\"square\")\n        self.side = side\n\n    def calculate_area(self):\n        return self.side **2\n    \n\n\"\"\"\nEn este código, se le ha realizado un refactor a la clase Shape, \nconvirtiéndola en una clase de base abstracta(ABC). Esta clase provee\nde una interfaz api para cualquier tipo de forma que se quiera \ndefinir. Esta interfaz consiste del atributo .shape_type y del método \n.calculate_area() que se pueden sobrescribir en todas las subclases.\n\nEste refactor cierra la clase a modificaciones. Ahora puedes agregar \nnuevas figuras al diseño de tu clase sin la necesidad de modificar la\nclase shape en. En cualquier caso, tendrías que modificar la interfaz \nnecesario, lo cual también convierte la clase a un tipo polimórfica.\n\n\"\"\"\n\n\"\"\"\nExtra\n\"\"\"\n\nclass Operation(ABC):\n    @abstractmethod\n    def execute(self, a, b):\n        pass\n\n\nclass Addition(Operation):\n    def execute(self, a,b):\n        return a + b\n\n\nclass Substract(Operation):\n    def execute(self, a, b):\n        return a - b\n    \n\nclass Multiply(Operation):\n    def execute(self, a, b):\n        return a * b\n    \n\nclass Division(Operation):    \n    def execute(self, a, b):\n        return a / b\n    \n\nclass Power(Operation):\n    def execute(self, a, b):\n        return a ** b\n\n\nclass Calculator:\n    def __init__(self) -> None:\n        self.operations = {}\n\n    def add_operation(self, name, operation):\n        self.operations[name] = operation\n\n    def calculate(self, name, a, b):\n        if name not in self.operations:\n            raise ValueError(f\"La operacion {name} no esta soportada.\")\n        return self.operations[name].execute(a,b)\n\n\ncalculator = Calculator()\ncalculator.add_operation(\"addition\", Addition())\ncalculator.add_operation(\"substract\", Substract())\ncalculator.add_operation(\"multiply\", Multiply())\ncalculator.add_operation(\"division\", Division())\ncalculator.add_operation(\"power\", Power())\n\nprint(calculator.calculate(\"addition\", 10,2))\nprint(calculator.calculate(\"substract\", 10,5))\nprint(calculator.calculate(\"multiply\", 10,5))\nprint(calculator.calculate(\"division\", 10,5))\nprint(calculator.calculate(\"power\", 10,5))"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/agusrosero.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n\"\"\"\n\n\nclass Animal:\n    def __init__(self, name):\n        self.name = name\n\n\nclass Sonido(Animal):\n    def sonido(self):\n        print(f\"{self.name} hace ruidos!\")\n\n\nclass Comer(Animal):\n    def comer(self):\n        print(f\"{self.name} come su comida...\")\n\n\nclass Saludar(Animal):\n    def saludar(self):\n        print(f\"{self.name} saluda!!!\")\n\n\nanimal1 = Animal(\"Leon\")\nprint(animal1.name)\nsonido1 = Sonido(\"Leon\")\nsonido1.sonido()\ncomer1 = Comer(\"Elefante\")\ncomer1.comer()\nsaludar1 = Saludar(\"Tigre\")\nsaludar1.saludar()\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas. \n * Requisitos:\n * - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n * Instrucciones:\n * 1. Implementa las operaciones de suma, resta, multiplicación y división.\n * 2. Comprueba que el sistema funciona.\n * 3. Agrega una quinta operación para calcular potencias.\n * 4. Comprueba que se cumple el OCP.\n */\n\"\"\"\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/alanshakir.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas. \n * Requisitos:\n * - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n * Instrucciones:\n * 1. Implementa las operaciones de suma, resta, multiplicación y división.\n * 2. Comprueba que el sistema funciona.\n * 3. Agrega una quinta operación para calcular potencias.\n * 4. Comprueba que se cumple el OCP.\n */\n\"\"\"\n#Incorrecta\n\nclass Vehicule:\n    def __init__(self, car, motobike):\n        self.car = car\n        self. motobike = motobike\n    \n    def draw_vehicule(self, vehicule):\n        print(f\"Se prepara a pintar un {vehicule}\")\n\n\nclass Car:\n    def draw_vehicule(self):\n        print(f\"Se esta dibujando un auto\")\n\nmy_vehicule = Vehicule(\"mustang\", \"Yamaha\")\nmy_vehicule.draw_vehicule(\"mustang\")\nmy_vehicule.draw_vehicule(\"Yamaha\")\n\n#Correcta\n\nclass Vehicule:\n    def __init__(self) -> None:\n        self.vehicule\n\n    def draw_vehicule(self, vehicule):\n        print(f\"Se esta dibujando {vehicule}\")\n\nclass Car(Vehicule):\n    def draw_vehicule(self):\n        print(f\"Se esta dibujando un auto\")\n\n#Extra\n\nfrom abc import ABC, abstractmethod\n\n\nclass Operation(ABC):\n    @abstractmethod\n    def execute(self, num1, num2):\n        pass\n\nclass Adition(Operation):\n    def execute(self, num1, num2):\n        return num1 + num2\n\nclass Substration(Operation):\n    def execute(self, num1, num2):\n        return num1 - num2\n    \nclass Multiplication(Operation):\n    def execute(self, num1, num2):\n        return num1 * num2\n    \nclass Division(Operation):\n    def execute(self, num1, num2):\n        try:\n            return num1 / num2\n            \n        except ZeroDivisionError:\n            print(\"No se puede dividir entre cero\")\n        \n    \nclass Power(Operation):\n    def execute(self, num1, num2):\n        return num1 ** num2\n\nclass Calculator:\n    def __init__(self) -> None:\n        self.operations = {\"suma\": Adition(),\n                           \"resta\": Substration(),\n                           \"multiplicacion\": Multiplication(),\n                           \"division\": Division(),\n                           \"potencia\": Power()\n                           }\n    \n    def add_operation(self, name, operation):\n        self.operations[name] = operation\n    \n    def calculate(self, name, num1, num2):\n        if name not in self.operations:\n            raise ValueError(\"operacion no soportada\")\n        else:\n            return self.operations[name].execute(num1, num2)\n        \ncalculator = Calculator()\ncalculator.add_operation(\"addition\", Adition())\ncalculator.add_operation(\"substration\", Substration())\ncalculator.add_operation(\"multiplication\", Multiplication())\ncalculator.add_operation(\"division\", Division())\ncalculator.add_operation(\"power\", Power())\n\nprint(calculator.calculate(\"suma\", 20, 15))\nprint(calculator.calculate(\"resta\", 10, 3))\nprint(calculator.calculate(\"multiplicacion\", 4, 4))\nprint(calculator.calculate(\"division\", 30, 0))\nprint(calculator.calculate(\"potencia\", 2, 5))\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/avcenal.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\"\n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n\"\"\"\nfrom abc import ABC, abstractmethod\nfrom math import pi\n\n#EJEMPLO SIN OCP\nclass Area_1():\n    def __init__(self):\n        pass\n\n    def rectangle(self,side:int|float,high:int|float):\n        return side*high\n    \n    def circle(self,radius:int|float):\n        return pi*radius*radius\n    \nrectangle_no_ocp = Area_1()\nprint(f\"El área del Rectángulo NO OCP es: {rectangle_no_ocp.rectangle(side=7,high=2)}\")\ncircle_no_ocp = Area_1()\nprint(f\"El área del Circulo NO OCP es: {circle_no_ocp.circle(radius=4):.2f}\")\nprint(\"\\n\")\n\n#EJEMPLO CON OCP\n\nclass Area(ABC):\n    @abstractmethod\n    def area():\n        pass\n\nclass Rectangle(Area):\n    def area(self,side:int|float,high:int|float):\n        return side*high\n\nclass Circle(Area):\n    def area(self,radius:int|float):\n        return pi*radius*radius\n\nrectangle_ocp = Rectangle()\nprint(f\"El área del Rectángulo OCP es: {rectangle_ocp.area(side=7,high=2)}\")\ncircle_ocp = Circle()\nprint(f\"El área del Círculo OCP es: {circle_ocp.area(radius=4):.2f}\")\nprint(\"\\n\")\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas.\n * Requisitos:\n * - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n * Instrucciones:\n * 1. Implementa las operaciones de suma, resta, multiplicación y división.\n * 2. Comprueba que el sistema funciona.\n * 3. Agrega una quinta operación para calcular potencias.\n * 4. Comprueba que se cumple el OCP.\n\"\"\"\n\nfrom functools import reduce\n\nclass Operation(ABC): #Operation pasa a ser una interfaz con un método abstracto\n    @abstractmethod   #es decir la clase no puede ser instanciada ni el método podrá ser utilizado\n    def calculate():\n        pass\n\nclass Sum(Operation):\n    def calculate(self,args:list):\n        print(f\"El resultado es: {reduce(lambda x,y:x+y,args)}\\n\")\n    \nclass Substract(Operation):\n    def calculate(self,args:list):\n        print(f\"El resultado es: {reduce(lambda x,y:x-y,args)}\\n\")\n\nclass Multiply(Operation):\n    def calculate(self,args:list):\n        print(f\"El resultado es: {reduce(lambda x,y:x*y,args)}\\n\")\n\nclass Divide(Operation):\n    def calculate(self,args:list):\n        print(f\"El restultado es: {reduce(lambda x,y:x/y,args)}\\n\")\n\nclass Power(Operation):\n    def calculate(self,args:list):\n        if len(args)>2:\n            raise ValueError(\"Para poder calcular una potencia has de pasar solo dos operandos como base y exponente\")\n        else:\n            print(f\"El resultado es: {pow(args[0],args[1])}\\n\")\n\nclass Calculator():\n    def __init__(self) -> None:\n        self.operations = {\n            \"sum\":Sum(),\n            \"substract\":Substract(),\n            \"multiply\":Multiply(),\n            \"divide\":Divide()\n        }\n\n    def add_operation(self,name:str,operation:Operation):\n        self.operations[name] = operation\n\n    def execute(self,name):\n        if name not in self.operations:\n            raise ValueError(\"La operación no está contemplada en esta calculadora\")\n        else:\n            num_operators = list()\n            operators = input(\"Dime los operandos separados por coma: \")\n            operators = operators.strip()\n            list_operators = operators.split(\",\")\n            try:\n                for element in list_operators:\n                    if element.__contains__(\".\"):\n                        num_operators.append(float(element))\n                    else:\n                        num_operators.append(int(element))\n            except ValueError:\n                print(\"Los valores introducidos han de ser números...\")\n            else:\n                self.operations[name].calculate(num_operators)\n\ndef calculator():\n    my_calculator = Calculator()\n    my_calculator.add_operation(name=\"power\",operation=Power()) #añado la potencia con Power()\n    options = {\n        \"S\":\"sum\",\n        \"R\":\"substract\",\n        \"M\":\"multiply\",\n        \"D\":\"divide\",\n        \"P\":\"power\"\n    }\n    print(\" --- TE DOY LA BIENVENIDA AL SISTEMA DE CALCULADORA --- \")\n    while True:\n        option = input(\"Elige una opción por favor:\\n- Suma (S)\\n- Resta (R)\\n- Multiplicación (M)\\n- División (D)\\n- Potencia (P)\\n- Salir (O)\\n-----> \").upper()\n        if option == \"O\":\n            print(\"Gracias por usar el sistema de calculadora. ¡Hasta pronto!\")\n            break\n        elif option not in options:\n            print(\"La opción elegida no es válida...\\n\")\n        else:\n            my_calculator.execute(options[option])\n\ncalculator()\n\n#en si la función calculator no cumpliría con el OCP, si añadimos otra operación\n#hemos de modificar el menú y la variable options\n#no obstante todas las clases que incluye el programa si lo cumplen\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/bytecodesky.py",
    "content": "\"\"\"/*\n * EJERCICIO:\n * Explora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n */\"\"\"\n\n#EL PRINCIPIO SOLID OCP (OPEN-CLOSED PRINCIPLE) ESTABLECE QUE UNA CLASE DEBE ESTAR ABIERTA PARA SU EXTENSIÓN, PERO CERRADA PARA SU MODIFICACIÓN. EN OTRAS PALABRAS, DEBE SER POSIBLE AGREGAR NUEVAS FUNCIONALIDADES A UNA CLASE SIN NECESIDAD DE MODIFICAR SU CÓDIGO FUENTE.\n\n# Ejemplo incorrecto\n# En este ejemplo es incorrecto porque si se quiere agregar un nuevo animal, se tendría que modificar la clase Granja para agregar un nuevo método sonido() para el nuevo animal. Esto viola el principio OCP, ya que no se puede extender la funcionalidad de la clase Granja sin modificar su código fuente.\nclass Animal:\n    def __init__(self, nombre, sonido):\n        self.nombre = nombre\n        self.sonido = sonido\n\nclass Granja:\n    def __init__(self):\n        self.animales = []\n        \n    def agregar_animal(self, animal):\n        self.animales.append(animal)\n        \n    def sonidos(self):\n        for animal in self.animales:\n            print(animal.sonido)\n\ngranja = Granja()\ngranja.agregar_animal(Animal(\"Firulais\", \"Guau\"))\ngranja.agregar_animal(Animal(\"Garfield\", \"Miau\"))\ngranja.agregar_animal(Animal(\"Manchitas\", \"Muu\"))\ngranja.sonidos()\n\n\n# Ejemplo correcto\n# En este ejemplo, se utiliza el principio OCP para permitir la extensión de la funcionalidad de la clase Granja sin modificar su código fuente. Se crea una clase base Animal con un método sonido() que es implementado por las subclases Perro, Gato y Vaca. De esta manera, se puede agregar nuevos animales sin modificar la clase Granja.\nclass Animal:\n    def __init__(self, nombre):\n        self.nombre = nombre\n\n    def sonido(self):\n        pass\n\nclass Perro(Animal):\n    def sonido(self):\n        return \"Guau\"\n    \nclass Gato(Animal):\n    def sonido(self):\n        return \"Miau\"\n\nclass Vaca(Animal):\n    def sonido(self):\n        return \"Muu\"\n    \nclass Granja:\n    def __init__(self):\n        self.animales = []\n        \n    def agregar_animal(self, animal):\n        self.animales.append(animal)\n        \n    def sonidos(self):\n        for animal in self.animales:\n            print(animal.sonido())\n\ngranja = Granja()\ngranja.agregar_animal(Perro(\"Firulais\"))\ngranja.agregar_animal(Gato(\"Garfield\"))\ngranja.agregar_animal(Vaca(\"Manchitas\"))\ngranja.sonidos()\n\n\"\"\" * DIFICULTAD EXTRA (opcional):\n * Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas. \n * Requisitos:\n * - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n * Instrucciones:\n * 1. Implementa las operaciones de suma, resta, multiplicación y división.\n * 2. Comprueba que el sistema funciona.\n * 3. Agrega una quinta operación para calcular potencias.\n * 4. Comprueba que se cumple el OCP.\"\"\"\n\n# IMPLEMENTACIÓN DE UNA CALCULADORA QUE CUMPLE CON EL PRINCIPIO OCP\nclass Calculadora:\n    def __init__(self):\n        self.operaciones = []\n        \n    def agregar_operacion(self, operacion):\n        self.operaciones.append(operacion)\n        \n    def calcular(self, operacion, a, b):\n        for op in self.operaciones:\n            if op.nombre == operacion:\n                return op.calcular(a, b)\n        return None\n    \nclass Operacion:\n    def __init__(self, nombre):\n        self.nombre = nombre\n        \n    def calcular(self, a, b):\n        pass\n        \nclass Suma(Operacion):\n    def calcular(self, a, b):\n        return a + b\n    \nclass Resta(Operacion):\n    def calcular(self, a, b):\n        return a - b\n    \nclass Multiplicacion(Operacion):\n    def calcular(self, a, b):\n        return a * b\n    \nclass Division(Operacion):\n    def calcular(self, a, b):\n        return a / b\n    \n# COMPROBACIÓN DE FUNCIONAMIENTO CON LAS OPERACIONES BÁSICAS\ncalc = Calculadora()\ncalc.agregar_operacion(Suma(\"Suma\"))\ncalc.agregar_operacion(Resta(\"Resta\"))\ncalc.agregar_operacion(Multiplicacion(\"Multiplicación\"))\ncalc.agregar_operacion(Division(\"División\"))\n\nprint(calc.calcular(\"Suma\", 5, 3))\nprint(calc.calcular(\"Resta\", 5, 3))\nprint(calc.calcular(\"Multiplicación\", 5, 3))\nprint(calc.calcular(\"División\", 5, 3))\n\n# AGREGAR UNA NUEVA OPERACIÓN (POTENCIA)\nclass Potencia(Operacion):\n    def calcular(self, a, b):\n        return a ** b\n\ncalc.agregar_operacion(Potencia(\"Potencia\"))\nprint(calc.calcular(\"Potencia\", 5, 3))\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/cristianfloyd.py",
    "content": "# EJERCICIO:\n# Explora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\"\n# y crea un ejemplo simple donde se muestre su funcionamiento\n# de forma correcta e incorrecta.\nfrom abc import ABC, abstractmethod\n\n# Incorrecto:\nclass SistemaNotificaciones:\n    def enviar_notificaciones(self, tipo, mensaje):\n        if tipo == \"email\":\n            print(f\"Enviando notificacion por email: {mensaje}\")\n        elif tipo == \"sms\":\n            print(f\"Enviando notificacion por sms: {mensaje}\")\n        # Si quiero agregar whatsapp, tendria que agregar un elif para whatsapp\n        # estaria modificando y no extendiendo la clase\n    \n# Correcto:\nclass Notificador(ABC):\n    @abstractmethod\n    def enviar(self, mensaje):\n        pass\n\nclass NotificadorEmail(Notificador):\n    def enviar(self, mensaje):\n        print(f\"Enviando notificacion por email: {mensaje}\")\nclass NotificadorSms(Notificador):\n    def enviar(self, mensaje):\n        print(f\"Enviando notificacion por sms: {mensaje}\")\n\n# Aqui extendi sin modificar el codigo existente\nclass NotificadorWhatsapp(Notificador):\n    def enviar(self, mensaje):\n        print(f\"Enviando notificacion por whatsapp: {mensaje}\")\n\n\n# uso\ndef notificar_usuario(notificador: Notificador, mensaje: str):\n    notificador.enviar(mensaje)\n\n\n\nnotificar_usuario(NotificadorEmail(), \"Hola, este es un mensaje de prueba\")\nnotificar_usuario(NotificadorSms(), \"Hola, este es un mensaje de prueba\")\nnotificar_usuario(NotificadorWhatsapp(), \"Hola, este es un mensaje de prueba\")\n\n\n#\n# DIFICULTAD EXTRA (opcional):\n# Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas.\n# Requisitos:\n# - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n# Instrucciones:\n# 1. Implementa las operaciones de suma, resta, multiplicación y división.\n# 2. Comprueba que el sistema funciona.\n# 3. Agrega una quinta operación para calcular potencias.\n# 4. Comprueba que se cumple el OCP.\n\nclass Operacion:\n    def calcular(self, a, b):\n        pass\n\nclass Suma(Operacion):\n    def calcular(self, a, b):\n        return a + b\nclass Resta(Operacion):\n    def calcular(self, a, b):\n        return a - b\nclass Multiplicacion(Operacion):\n    def calcular(self, a, b):\n        return a * b\nclass Division(Operacion):\n    def calcular(self, a, b):\n        return a / b\n\n\n\nclass Calculadora:\n    operaciones = []\n    def calcular(self, operacion, a, b):\n        return operacion.calcular(a, b)\n    def agregar_operacion(self, operacion):\n        self.operaciones.append(operacion)\n# Uso\nprint(\"------------- DIFICULTAD EXTRA ----------------\")\ncalc = Calculadora()\ncalc.agregar_operacion(Suma())\ncalc.agregar_operacion(Resta())\ncalc.agregar_operacion(Multiplicacion())\ncalc.agregar_operacion(Division())\nprint(\"Resultado de la suma: \", calc.calcular(Suma(), 1, 2))\nprint(\"Resultado de la resta: \", calc.calcular(Resta(), 1, 2))\nprint(\"Resultado de la multiplicacion: \", calc.calcular(Multiplicacion(), 1, 2))\nprint(\"Resultado de la division: \", calc.calcular(Division(), 1, 2))\n\n# Aqui extendi sin modificar el codigo existente\nclass Potencia(Operacion):\n    def calcular(self, a, b):\n        return a**b\n        \n        \ncalc.agregar_operacion(Potencia())\nprint(\"Resultado de la potencia: \", calc.calcular(Potencia(), 1, 2))"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/cyberdidac.py",
    "content": "from abc import ABC, abstractmethod\n\n\nclass Operation(ABC):\n    @abstractmethod\n    def execute(self, operand1, operand2):\n        pass\n\n\nclass Addition(Operation):\n    def execute(self, operand1, operand2):\n        return operand1 + operand2\n\n\nclass Substraction(Operation):\n    def execute(self, operand1, operand2):\n        return operand1 - operand2\n\n\nclass Multiplication(Operation):\n    def execute(self, operand1, operand2):\n        return operand1 * operand2\n\n\nclass Division(Operation):\n    def execute(self, operand1, operand2):\n        if operand2 != 0:\n            return operand1 / operand2\n        else:\n            raise ValueError(\"Cannot divide by zero\")\n\n\nclass Power(Operation):\n    def execute(self, operand1, operand2):\n        return operand1 ** operand2\n\n\nclass Calculator:\n    def perform_operation(self, operation, operand1, operand2):\n        return operation.execute(operand1, operand2)\n\n\ndef main():\n    add = Addition()\n    sub = Substraction()\n    mult = Multiplication()\n    div = Division()\n    power = Power()\n\n    calc = Calculator()\n\n    print(calc.perform_operation(add, 1, 2))\n    print(calc.perform_operation(sub, 1, 2))\n    print(calc.perform_operation(mult, 1, 2))\n    print(calc.perform_operation(div, 1, 2))\n    print(calc.perform_operation(power, 3, 2))\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/davidrguez98.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Explora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas. \n * Requisitos:\n * - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n * Instrucciones:\n * 1. Implementa las operaciones de suma, resta, multiplicación y división.\n * 2. Comprueba que el sistema funciona.\n * 3. Agrega una quinta operación para calcular potencias.\n * 4. Comprueba que se cumple el OCP.\n */ \"\"\"\n\n#EJERCICIO\n\n\"\"\" \nIncorrecta\n\"\"\"\n\nclass Form:\n\n    def draw_square(self):\n        print(\"Dibujar un cuadrado.\")\n\n    def draw_circle(self):\n        print(\"Dibujar un círculo.\")\n\n\"\"\" \nCorrecta\n\"\"\"\n\nclass Form:\n\n    def draw(self):\n        pass\n\nclass Square(Form):\n\n    def draw(self):\n        print(\"Dibuja un cuadrado.\")\n\nclass Circle(Form):\n\n    def draw(self):\n        print(\"Dibuja un círculo.\")\n\nclass Triangle(Form):\n\n    def draw(self):\n        print(\"Dibuja un triángulo.\")\n\n#EJERCICIO EXTRA\n\nclass Operation:\n    def operation(self, number1: int, number2: int):\n        pass\n\nclass Sum(Operation):\n\n    def operation(self, number1: int, number2: int):\n        return number1 + number2\n\nclass Rest(Operation):\n\n    def operation(self, number1: int, number2: int):\n        return number1 - number2\n\nclass Multiplication(Operation):\n\n    def operation(self, number1: int, number2: int):\n        return number1 * number2\n\nclass Divide(Operation):\n\n    def operation(self, number1: int, number2: int):\n        return number1 / number2\n\nclass Power(Operation):\n\n    def operation(self, number1: int, number2: int):\n        return number1 ** number2\n\nclass Calculator:\n\n    def __init__(self):\n        self.operations = {}\n\n    def add_operation(self, name, operation_):\n        self.operations[name] = operation_\n\n    def calculate(self, name, number1, number2):\n        if name not in self.operations:\n            raise ValueError(f\"La operación {name} no se encuentra en la calculadora.\")\n        return self.operations[name].operation(number1, number2)\n\ncalculator = Calculator()\n\ncalculator.add_operation(\"Sumar\", Sum())\ncalculator.add_operation(\"Restar\", Rest())\ncalculator.add_operation(\"Multiplicar\", Multiplication())\ncalculator.add_operation(\"Dividir\", Divide())\ncalculator.add_operation(\"Potencia de dos\", Power())\n\nprint(calculator.calculate(\"Sumar\", 2, 2))\nprint(calculator.calculate(\"Restar\", 2, 2))\nprint(calculator.calculate(\"Multiplicar\", 2, 2))\nprint(calculator.calculate(\"Dividir\", 2, 2))\nprint(calculator.calculate(\"Potencia de dos\", 2, 2))"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/duendeintemporal.py",
    "content": "#27 { Retos para Programadores } Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP) \n\n# Bibliography reference:\n# https://en.wikipedia.org/wiki/Open%E2%80%93closed_principle\n# I use GPT as a reference and sometimes to correct or generate proper comments.\n\n\"\"\"  \n * EJERCICIO:\n * Explora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\"\n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas.\n * Requisitos:\n * - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n * Instrucciones:\n * 1. Implementa las operaciones de suma, resta, multiplicación y división.\n * 2. Comprueba que el sistema funciona.\n * 3. Agrega una quinta operación para calcular potencias.\n * 4. Comprueba que se cumple el OCP.\n  \n \"\"\"\n\n\n\"\"\" In object-oriented programming, the open–closed principle (OCP) states \"software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification\";[1] that is, such an entity can allow its behaviour to be extended without modifying its source code.\n\nThe name open–closed principle has been used in two ways. Both ways use generalizations (for instance, inheritance or delegate functions) to resolve the apparent dilemma, but the goals, techniques, and results are different. \"\"\"\n\n# Not using Open-Close Principle (OCP)\n\nclass SimpleCalculator:\n    def calculate(self, operation, a, b):\n        if operation == 'add':\n            return a + b\n        elif operation == 'subtract':\n            return a - b\n        elif operation == 'multiply':\n            return a * b\n        elif operation == 'divide':\n            if b == 0:\n                raise ValueError(\"Cannot divide by zero\")\n            return a / b\n        else:\n            raise ValueError(\"Operation not supported\")\n\n# Example usage\ncalculator1 = SimpleCalculator()\nprint(calculator1.calculate('add', 856, 30))  # 886\nprint(calculator1.calculate('divide', 220, 4423))  # 0.04973999547818223\n\n# Using Open-Close Principle (OCP)\n\nimport logging\n\n# Set up logging\nlogging.basicConfig(level=logging.INFO)\nlog = logging.getLogger(__name__)\n\nlog.info('Retos para Programadores #27')  # Retos para Programadores #27\n\n# Base class for operations\nclass Operation:\n    def execute(self, a: float, b: float) -> float:\n        raise NotImplementedError(\"Method not implemented\")\n\n# Concrete operation classes\nclass Addition(Operation):\n    def execute(self, a: float, b: float) -> float:\n        return a + b\n\nclass Subtraction(Operation):\n    def execute(self, a: float, b: float) -> float:\n        return a - b\n\nclass Multiplication(Operation):\n    def execute(self, a: float, b: float) -> float:\n        return a * b\n\nclass Division(Operation):\n    def execute(self, a: float, b: float) -> float:\n        if b == 0:\n            raise ValueError(\"Cannot divide by zero\")\n        return a / b\n\nclass Power(Operation):\n    def execute(self, a: float, b: float) -> float:\n        return a ** b\n\n# Calculator class that uses the operations\nclass Calculator:\n    def __init__(self):\n        self.operations = {}\n\n    def add_operation(self, name: str, operation: Operation):\n        self.operations[name] = operation\n        log.info(f\"Added operation: [ {name} ]\")\n\n    def calculate(self, operation_name: str, a: float, b: float) -> float:\n        operation = self.operations.get(operation_name)\n        if not operation:\n            raise ValueError(f\"Operation '{operation_name}' not supported\")\n        return operation.execute(a, b)\n\ndef setup_calculator() -> Calculator:\n    calculator = Calculator()\n    calculator.add_operation('add', Addition())\n    calculator.add_operation('subtract', Subtraction())\n    calculator.add_operation('multiply', Multiplication())\n    calculator.add_operation('divide', Division())\n    calculator.add_operation('power', Power())\n    return calculator\n\ndef add_custom_operation(calculator: Calculator):\n    name = input(\"Enter operation name: \")\n    action = input(\"Enter operation action (use 'a' and 'b' for inputs, e.g., a + b): \")\n    sign = input(\"Enter operation sign: \")\n\n    if not name or not action or not sign:\n        log.warning(\"You have to fill all the fields: name, operation, and sign to add a new operation!\")\n        return\n\n    # Create a new operation class for the custom operation\n    class CustomOperation(Operation):\n        def __init__(self, action: str):\n            self.action = action\n\n        def execute(self, a: float, b: float) -> float:\n            try:\n                # Replace 'a' and 'b' in the action string with the actual values\n                expression = self.action.replace('a', str(a)).replace('b', str(b))\n                return eval(expression)\n            except Exception as e:\n                log.error(f\"Error in operation: {e}\")\n                return None\n\n    # Add the new operation to the calculator\n    calculator.add_operation(name, CustomOperation(action))\n    log.info(f\"Custom operation '{name}' added successfully!\")\n\ndef get_float_input(prompt: str) -> float:\n    while True:\n        try:\n            value = float(input(prompt))\n            return value\n        except ValueError:\n            log.error(\"Invalid input. Please enter a valid number.\")\n\nif __name__ == \"__main__\":\n    calculator = setup_calculator()\n\n    # Example calculations\n    try:\n        result_add = calculator.calculate('add', 856, 30)\n        log.info(f\"Result of addition: {result_add}\")  # 886\n\n        result_divide = calculator.calculate('divide', 220, 4423)\n        log.info(f\"Result of division: {result_divide}\")  # 0.04973999547818223\n    except ValueError as e:\n        log.error(e)\n\n    # Adding a custom operation\n    add_custom_operation(calculator)\n\n    # Example of using the custom operation\n    custom_operation_name = input(\"Enter the name of the custom operation to use: \")\n    a = get_float_input(\"Enter first number: \")\n    b = get_float_input(\"Enter second number: \")\n\n    try:\n        result_custom = calculator.calculate(custom_operation_name, a, b)\n        log.info(f\"Result of custom operation '{custom_operation_name}': {result_custom}\")\n    except ValueError as e:\n        log.error(e)\n\n# Output:\n\"\"\"  \nINFO:__main__:Retos para Programadores #27\nINFO:__main__:Added operation: [ add ]\nINFO:__main__:Added operation: [ subtract ]\nINFO:__main__:Added operation: [ multiply ]\nINFO:__main__:Added operation: [ divide ]\nINFO:__main__:Added operation: [ power ]\nINFO:__main__:Result of addition: 886\nINFO:__main__:Result of division: 0.04973999547818223\nEnter operation name: add4\nEnter operation action (use 'a' and 'b' for inputs, e.g., a + b): a + 4 + b\nEnter operation sign: +4+\nINFO:__main__:Added operation: [ add4 ]\nINFO:__main__:Custom operation 'add4' added successfully!\nEnter the name of the custom operation to use: add4\nEnter first number: 12\nEnter second number: 4\nINFO:__main__:Result of custom operation 'add4': 20.0\n\n\"\"\""
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/fborjalv.py",
    "content": "\n\"\"\"\n\n * EJERCICIO:\n * Explora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\"\n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n\"\"\"\n\n# Forma incorrecta\n\nclass Product():\n    def __init__(self, name) -> None:\n        self.name = name\n    \n    def update_stock(self):\n        if self.name == \"zapatos\":\n            print(\"Actualizado el stock de zapatos\")\n        elif self.name == \"camisas\":\n            print(\"Actualizado el stock de camisas\")\n\n# Forma correcta\n\nfrom abc import ABC, abstractmethod\n\nclass Product(ABC):\n    @abstractmethod\n    def update_stock(self):\n        pass\n\nclass Shoes(Product):\n\n    def update_stock(self):\n        print(\"Actualizado el stock de zapatos\")\n\nclass Shirts(Product):\n\n    def update_stock(self):\n        print(\"Actualizado el stock de camisas\")\n\n\nmy_products = [Shoes(), Shirts()]\n\nfor i in my_products:\n    i.update_stock()\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas.\n * Requisitos:\n * - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n * Instrucciones:\n * 1. Implementa las operaciones de suma, resta, multiplicación y división.\n * 2. Comprueba que el sistema funciona.\n * 3. Agrega una quinta operación para calcular potencias.\n * 4. Comprueba que se cumple el OCP.\n\n\"\"\"\nfrom abc import ABC, abstractmethod\n\nclass Calculator(ABC):\n\n    @abstractmethod\n    def calculate_operation(self, a, b):\n        pass\n\nclass Sum(Calculator):\n\n    def calculate_operation(self, a, b):\n        return a + b\n\nclass Subtract(Calculator):\n\n    def calculate_operation(self, a, b):\n        return a - b\n\nclass Multiply(Calculator):\n\n    def calculate_operation(self, a, b):\n        return a * b\n\nclass Division(Calculator):\n    def calculate_operation(self, a, b):\n        return a / b\n\nclass Pow(Calculator):\n\n    def calculate_operation(self, a, b):\n        return a**b\n\n\nsum_op = Sum()\nsubstract_op = Subtract()\nmultiply_op = Multiply()\npow_op = Pow()\ndivision_op = Division()\n\nprint(sum_op.calculate_operation(4, 5))\nprint(substract_op.calculate_operation(4,5))\nprint(multiply_op.calculate_operation(4, 5))\nprint(pow_op.calculate_operation(4,5))\nprint(division_op.calculate_operation(4, 5))\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/franxiscodev.py",
    "content": "\"\"\"\nSOLID\nOCP: principio abierto-cerrado\nOpened-Closed Principle \nAbierto para la extensión, cerrado para la modificación\nSe puede ampliar, pero lo que ya tenemos no lo tocamos\n\"\"\"\n# Explicación\n# El principio OCP establece que una clase debe estar abierta para la extensión, pero cerrada para la modificación.\n# Esto significa que deberíamos poder agregar nuevas funcionalidades a una clase sin modificar su código existente.\n# En otras palabras, el comportamiento de una clase debe poder extenderse sin cambiar su implementación original.\n\n\nfrom abc import ABC, abstractmethod\n\n\nclass Shape:\n    def draw(self):\n        raise NotImplementedError(\"Subclasses must implement this method\")\n\n\nclass Square(Shape):\n    def draw(self):\n        return \"Drawing a square\"\n\n\nclass Circle(Shape):\n    def draw(self):\n        return \"Drawing a circle\"\n\n\nclass Rectangle(Shape):\n    def draw(self):\n        return \"Drawing a rectangle\"\n\n\n# Extra\n# clases abstractas\n# Se pueden crear clases abstractas para definir métodos que deben ser implementados por las subclases\n# y así evitar la implementación de métodos vacíos en las subclases.\n# En Python, esto se puede hacer utilizando el módulo abc (Abstract Base Classes).\n# Esto permite definir una clase base abstracta y especificar métodos abstractos que deben ser implementados por las subclases.\n# Esto ayuda a garantizar que las subclases sigan un contrato específico y proporciona una forma de crear jerarquías de clases más estructuradas.\n\nclass Operation(ABC):\n    @abstractmethod\n    def execute(self, a, b):\n        pass\n\n\nclass Addition(Operation):\n    def execute(self, a, b):\n        return a + b\n\n\nclass Subtraction(Operation):\n    def execute(self, a, b):\n        return a - b\n\n\nclass Multiplication(Operation):\n    def execute(self, a, b):\n        return a * b\n\n\nclass Division(Operation):\n    def execute(self, a, b):\n        if b == 0:\n            raise ValueError(\"No se puede dividir por zero\")\n        return a / b\n\n\nclass Power(Operation):\n    def execute(self, a, b):\n        return a ** b\n\n\nclass Calculator:\n    def __init__(self):\n        self.operations = {\n            \"addition\": Addition(),\n            \"subtraction\": Subtraction(),\n            \"multiplication\": Multiplication(),\n            \"division\": Division()\n        }\n\n    def add_operation(self, operation_name, operation):\n        if not isinstance(operation, Operation):\n            raise ValueError(\n                \"La operación debe ser una instancia de la clase Operation\")\n        self.operations[operation_name] = operation\n\n    def calculate(self, operation_name, a, b):\n        if operation_name not in self.operations:\n            raise ValueError(f\"Operación '{operation_name}' no soportada\")\n        return self.operations[operation_name].execute(a, b)\n\n\ncalculator = Calculator()\nprint(calculator.calculate(\"addition\", 5, 3))  # Output: 8\nprint(calculator.calculate(\"subtraction\", 5, 3))  # Output: 2\nprint(calculator.calculate(\"multiplication\", 5, 3))  # Output: 15\nprint(calculator.calculate(\"division\", 5, 3))  # Output: 1.6666666666666667\n# Output: ValueError: No se puede dividir por zero\n# print(calculator.calculate(\"division\", 5, 0))\ncalculator.add_operation(\"power\", Power())\n\nprint(calculator.calculate(\"power\", 5, 3))\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/hectorio23.py",
    "content": "# Autor: Héctor Adán\n# GitHub: https://github.com/hectorio23\n\nfrom abc import ABC, abstractmethod\nimport math\n\n\"\"\"\nEJERCICIO:\nExplora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\" \ny crea un ejemplo simple donde se muestre su funcionamiento\nde forma correcta e incorrecta.\n\nDIFICULTAD EXTRA:\nDesarrolla una calculadora que necesita realizar diversas operaciones matemáticas. \nRequisitos:\n- Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\nInstrucciones:\n1. Implementa las operaciones de suma, resta, multiplicación y división.\n2. Comprueba que el sistema funciona.\n3. Agrega una quinta operación para calcular potencias.\n4. Comprueba que se cumple el OCP.\n\"\"\"\n\nclass Operacion(ABC):\n    @abstractmethod\n    def calcular(self, a, b):\n        pass\n\nclass Suma(Operacion):\n    def calcular(self, a, b):\n        return a + b\n\nclass Resta(Operacion):\n    def calcular(self, a, b):\n        return a - b\n\nclass Multiplicacion(Operacion):\n    def calcular(self, a, b):\n        return a * b\n\nclass Division(Operacion):\n    def calcular(self, a, b):\n        if b == 0:\n            raise ValueError(\"División por cero\")\n        return a / b\n\nclass Potencia(Operacion):\n    def calcular(self, a, b):\n        return math.pow(a, b)\n\nclass Calculadora:\n    def __init__(self):\n        self.operaciones = {}\n\n    def agregar_operacion(self, nombre, operacion):\n        self.operaciones[nombre] = operacion\n\n    def calcular(self, nombre, a, b):\n        if nombre in self.operaciones:\n            return self.operaciones[nombre].calcular(a, b)\n        else:\n            raise ValueError(\"Operación no soportada\")\n\n\nif __name__ == \"__main__\":\n    calc = Calculadora()\n    calc.agregar_operacion('+', Suma())\n    calc.agregar_operacion('-', Resta())\n    calc.agregar_operacion('*', Multiplicacion())\n    calc.agregar_operacion('/', Division())\n    calc.agregar_operacion('^', Potencia())\n\n    print(\"[+] - Suma:\", calc.calcular('+', 5, 3))\n    print(\"[+] - Resta:\", calc.calcular('-', 5, 3))\n    print(\"[+] - Multiplicación:\", calc.calcular('*', 5, 3))\n    print(\"[+] - División:\", calc.calcular('/', 5, 3))\n    print(\"[+] - Potencia:\", calc.calcular('^', 5, 3))\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/hozlucas28.py",
    "content": "# pylint: disable=pointless-string-statement,missing-class-docstring,missing-function-docstring,missing-module-docstring,too-few-public-methods,useless-parent-delegation\n\nfrom typing import Union, Literal, Self\nfrom abc import abstractmethod, ABCMeta\n\n\"\"\"\n    Open-Close Principle (OCP)...\n\"\"\"\n\nprint(\"Open-Close Principle (OCP)...\")\n\nprint(\"\\nBad implementation of Open-Close Principle (OCP)...\")\n\n\nclass AbcProduct(metaclass=ABCMeta):\n    name: str\n    price: float\n\n    def __init__(self, *, name: str, price: float) -> None:\n        self.name = name\n        self.price = price\n\n\nclass Product(AbcProduct):\n    def __init__(self, *, name: str, price: float) -> None:\n        super().__init__(name=name, price=price)\n\n\nDiscountStrategy = Union[Literal[\"holyday\"], Literal[\"seasonal\"]]\n\n\nclass BadDiscountCalculator:\n    def __init__(self) -> None:\n        pass\n\n    def get_discount(\n        self, *, product: AbcProduct, discount_strategy: DiscountStrategy\n    ) -> float:\n        if discount_strategy == \"holyday\":\n            return product.price * 0.15\n\n        if discount_strategy == \"seasonal\":\n            return product.price * 0.21\n\n        return -1\n\n\nprint(\n    \"\\n```\",\n    \"\"\"class AbcProduct(metaclass=ABCMeta):\n    name: str\n    price: float\n\n    def __init__(self, *, name: str, price: float) -> None:\n        self.name = name\n        self.price = price\n\n\nclass Product(AbcProduct):\n    def __init__(self, *, name: str, price: float) -> None:\n        super().__init__(name=name, price=price)\n\n\nDiscountStrategy = Union[Literal[\"holyday\"], Literal[\"seasonal\"]]\n\n\nclass BadDiscountCalculator:\n    def __init__(self) -> None:\n        pass\n\n    def get_discount(\n        self, *, product: AbcProduct, discount_strategy: DiscountStrategy\n    ) -> float:\n        if discount_strategy == \"holyday\":\n            return product.price * 0.15\n\n        if discount_strategy == \"seasonal\":\n            return product.price * 0.21\n\n        return -1\"\"\",\n    \"```\",\n    sep=\"\\n\",\n)\n\nprint(\n    \"\\nThis is a bad implementation of Open-Close Principle (OCP),\",\n    \"because the method 'get_discount' of class 'BadDiscountCalculator'\",\n    \"will must change if we have to add more discount strategies\",\n    sep=\"\\n\",\n)\n\nprint(\"\\nGood implementation of Open-Close Principle (OCP)...\")\n\n\nclass AbcDiscountService(metaclass=ABCMeta):\n    product: AbcProduct\n\n    def __init__(self, *, product: AbcProduct) -> None:\n        self.product = product\n\n    @abstractmethod\n    def get_discount(self) -> float:\n        pass\n\n\nclass HolidayDiscountService(AbcDiscountService):\n    def __init__(self, *, product: AbcProduct) -> None:\n        super().__init__(product=product)\n\n    def get_discount(self) -> float:\n        return self.product.price * 0.15\n\n\nclass SeasonalDiscountService(AbcDiscountService):\n    def __init__(self, *, product: AbcProduct) -> None:\n        super().__init__(product=product)\n\n    def get_discount(self) -> float:\n        return self.product.price * 0.21\n\n\nclass AbcGoodDiscountCalculator(metaclass=ABCMeta):\n    @abstractmethod\n    def get_discount(self, *, discount_service: AbcDiscountService) -> float:\n        pass\n\n\nclass GoodDiscountCalculator(AbcGoodDiscountCalculator):\n    def __init__(self) -> None:\n        pass\n\n    def get_discount(self, *, discount_service: AbcDiscountService) -> float:\n        return discount_service.get_discount()\n\n\nprint(\n    \"\\n```\",\n    \"\"\"class AbcDiscountService(metaclass=ABCMeta):\n    product: AbcProduct\n\n    def __init__(self, *, product: AbcProduct) -> None:\n        self.product = product\n\n    @abstractmethod\n    def get_discount(self) -> float:\n        pass\n\n\nclass HolidayDiscountService(AbcDiscountService):\n    def __init__(self, *, product: AbcProduct) -> None:\n        super().__init__(product=product)\n\n    def get_discount(self) -> float:\n        return self.product.price * 0.15\n\n\nclass SeasonalDiscountService(AbcDiscountService):\n    def __init__(self, *, product: AbcProduct) -> None:\n        super().__init__(product=product)\n\n    def get_discount(self) -> float:\n        return self.product.price * 0.21\n\n\nclass AbcGoodDiscountCalculator(metaclass=ABCMeta):\n    @abstractmethod\n    def get_discount(self, *, discount_service: AbcDiscountService) -> float:\n        pass\n\n\nclass GoodDiscountCalculator(AbcGoodDiscountCalculator):\n    def __init__(self) -> None:\n        pass\n\n    def get_discount(self, *, discount_service: AbcDiscountService) -> float:\n        return discount_service.get_discount()\"\"\",\n    \"```\",\n    sep=\"\\n\",\n)\n\nprint(\n    \"\\nThis is a good implementation of Open-Close Principle (OCP),\",\n    \"because the method 'get_discount' of class 'GoodDiscountCalculator' will must\",\n    \"not change if we have to add more discount services. So, 'get_discount' is closed\",\n    \"to modification but it is open to extension throw any discount service which implements\",\n    \"'AbcDiscountService' abstract class.\",\n    sep=\"\\n\",\n)\n\nprint(\n    \"\\n# ---------------------------------------------------------------------------------- #\\n\"\n)\n\n\"\"\"\n    Additional challenge...\n\"\"\"\n\nprint(\"Additional challenge...\")\n\n\nclass AbcMathOperation(metaclass=ABCMeta):\n    @abstractmethod\n    def execute(self, *, a: float, b: float) -> float:\n        pass\n\n\nclass AddOperation(AbcMathOperation):\n    def __init__(self) -> None:\n        pass\n\n    def execute(self, *, a: float, b: float) -> float:\n        return a + b\n\n\nclass DivideOperation(AbcMathOperation):\n    def __init__(self) -> None:\n        pass\n\n    def execute(self, *, a: float, b: float) -> float:\n        if b == 0:\n            raise ValueError(\"The second parameter must not be zero\")\n\n        return a / b\n\n\nclass MultiplyOperation(AbcMathOperation):\n    def __init__(self) -> None:\n        pass\n\n    def execute(self, *, a: float, b: float) -> float:\n        return a * b\n\n\nclass SubtractOperation(AbcMathOperation):\n    def __init__(self) -> None:\n        pass\n\n    def execute(self, *, a: float, b: float) -> float:\n        return a - b\n\n\nclass AbcCalculator(metaclass=ABCMeta):\n    operations: dict[str, AbcMathOperation]\n\n    def __init__(self, *, operations) -> None:\n        self.operations = operations\n\n    @abstractmethod\n    def add_operation(self, *, name: str, operation: AbcMathOperation) -> Self:\n        pass\n\n    @abstractmethod\n    def execute_operation(self, *, name: str, a: float, b: float) -> float:\n        pass\n\n\nclass Calculator(AbcCalculator):\n    operations: dict[str, AbcMathOperation]\n\n    def __init__(\n        self, *, operations: None | dict[str, AbcMathOperation] = None\n    ) -> None:\n        if operations is None:\n            operations = {}\n\n        super().__init__(operations=operations)\n\n    def add_operation(self, *, name: str, operation: AbcMathOperation) -> Self:\n        operation_exist: bool = self.operations.get(name) is not None\n\n        if operation_exist:\n            raise ValueError(f\"The operation with '{name}' name already exist\")\n\n        self.operations[name] = operation\n        return self\n\n    def execute_operation(self, *, name: str, a: float, b: float) -> float:\n        operation_not_exist: bool = self.operations.get(name) is None\n\n        if operation_not_exist:\n            raise ValueError(f\"There is not operation with '${name}' name\")\n\n        return self.operations[name].execute(a=a, b=b)\n\n\nprint(\"\\nTesting the OCP system without a pow operation...\")\n\nCALCULATOR: Calculator = Calculator()\n\nCALCULATOR.add_operation(name=\"add\", operation=AddOperation())\nCALCULATOR.add_operation(name=\"divide\", operation=DivideOperation())\nCALCULATOR.add_operation(name=\"multiply\", operation=MultiplyOperation())\nCALCULATOR.add_operation(name=\"subtract\", operation=SubtractOperation())\n\nA: float = 4.5\nB: float = 6.1\n\nprint(\n    f\"\\nAdd operation result ({A} + {B}):\",\n    CALCULATOR.execute_operation(name=\"add\", a=A, b=B),\n)\n\nA = 5\nB = 2.2\n\nprint(\n    f\"Divide operation result ({A} / {B}):\",\n    CALCULATOR.execute_operation(name=\"divide\", a=A, b=B),\n)\n\nA = 3\nB = 1.75\n\nprint(\n    f\"Multiply operation result ({A} * {B}):\",\n    CALCULATOR.execute_operation(name=\"multiply\", a=A, b=B),\n)\n\nA = 10\nB = 8.7\n\nprint(\n    f\"Subtract operation result ({A} - {B}):\",\n    CALCULATOR.execute_operation(name=\"subtract\", a=A, b=B),\n)\n\nprint(\"\\nTesting the OCP system with a pow operation...\")\n\n\nclass PowOperation(AbcMathOperation):\n    def __init__(self) -> None:\n        pass\n\n    def execute(self, *, a: float, b: float) -> float:\n        return pow(base=a, exp=b)\n\n\nCALCULATOR.add_operation(name=\"pow\", operation=PowOperation())\n\nA = 11\nB = 2\n\nprint(\n    f\"\\nPow operation result ({A}^{B}):\",\n    CALCULATOR.execute_operation(name=\"pow\", a=A, b=B),\n)\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/idiegorojas.py",
    "content": "\"\"\"\n27 - Principio SOLID: Abierto - Cerrado\n\"\"\"\n# Las entidades de software (clases, modulos, funciones) deberian estar abiertas para extensión pero cerradas para modificación.\n# Deberiamos poder añadir nuevas funcionalidades sin tener que modificar el codigo\n\n# Forma incorrecta\n# Calcular areas\n\nclass Reactangulo:\n    def __init__(self, ancho: float, alto: float):\n        self.ancho = ancho\n        self.alto = alto\n        \n\n\nclass Circulo:\n    def __init__(self, radio: float):\n        self.radio = radio\n\n\nclass CalculadorArea:\n    def calcular_area(self, figuras):\n        area_total = 0\n        for figura in figuras:\n            if isinstance(figura, Reactangulo):\n                area_total += figura.ancho * figura.alto\n            elif isinstance(figura, Circulo):\n                area_total += 3.1416 * figura.radio * figura.radio\n        return area_total\n    \nrectangulo = Reactangulo(5, 10)\ncirculo = Circulo(7)\ncalculador = CalculadorArea()\nprint(calculador.calcular_area([rectangulo, circulo]))\n\n# Cada vez que querramos añadir una nueva forma geometrica tenemos que modificar la clase Calculador Area\n\n\n# Forma correcta\nfrom abc import ABC, abstractmethod\nimport math\n\nclass Figura(ABC):\n    @abstractmethod\n    def calcular_area(self):\n        pass\n\n\nclass Rectangulo:\n    def __init__(self, ancho: float, alto: float):\n        self.ancho = ancho\n        self.alto = alto\n\n    def calcular_area(self):\n        return self.ancho * self.alto\n\nclass Circulo:\n    def __init__(self, radio: float):\n        self.radio = radio\n    \n    def calcular_area(self):\n        return math.pi * self.radio * self.radio\n\nclass CalculadorArea:\n    def calcular_area(self, figuras):\n        return sum(figura.calcular_area() for figura in figuras)\n    \n\nrectangulo = Rectangulo(5, 10)\ncirculo = Circulo(7)\ncalculador = CalculadorArea()\nprint(calculador.calcular_area([rectangulo, circulo]))\n\n\n\"\"\"\nExtra\n\"\"\"\nfrom abc import ABC, abstractmethod\n\nclass Operation:\n    @abstractmethod\n    def execute(self, a, b):\n        pass\n\nclass Sum:\n    def execute(self, a, b):\n        return a + b\n\nclass Subtract:\n    def execute(self, a, b):\n        return a - b\n\n\nclass Multiply:\n    def execute(self, a, b):\n        return a * b\n\n\nclass Divide:\n    def execute(self, a, b):\n        return a / b\n    \n\nclass Power:\n    def execute(self, a, b):\n        return a ** b\n    \n\nclass Calculator:\n    def __init__(self) -> None:\n        self.operations = {}\n\n    def add_operation(self, name, operation):\n        self.operations[name] = operation\n\n    def calculate(self, name, a, b):\n        if name not in self.operations:\n            raise ValueError(f\"La operación {name} no está soportada.\")\n        return self.operations[name].execute(a, b)\n\n\ncalculator = Calculator()\ncalculator.add_operation(\"sum\", Sum())\ncalculator.add_operation(\"subtract\", Subtract())\ncalculator.add_operation(\"multiply\", Multiply())\ncalculator.add_operation(\"divide\", Divide())\ncalculator.add_operation(\"power\", Power())\n\nprint(calculator.calculate(\"sum\", 10, 5))\nprint(calculator.calculate(\"subtract\", 10, 5))\nprint(calculator.calculate(\"multiply\", 10, 5))\nprint(calculator.calculate(\"divide\", 10, 5))\nprint(calculator.calculate(\"power\", 10, 5))"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/ignaciovihe.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n\"\"\"\n\n# NO cumple OCP\n# Si quiero ampliar otro tipo de cliente, debo modificar toda la clase.\nclass CalculadoraDescuentos:\n    def calcular(self, tipo_cliente, monto):\n        if tipo_cliente == \"regular\":\n            return monto * 0.95\n        elif tipo_cliente == \"vip\":\n            return monto * 0.90\n        elif tipo_cliente == \"super_vip\":\n            return monto * 0.85\n        else:\n            return monto\n        \ndiscount = CalculadoraDescuentos()\nmonto = 18\ncliente = \"super_vip\"\nprint(f\"Calculado descuento: Monto total: {monto} - Tipo cliente: {cliente} - Total tras descuento: {discount.calcular(cliente, monto)}\")\n\n\n# Cumpliendo OCP\n\nfrom abc import ABC, abstractmethod #Modulo que contiene clases, metodos y decoradores para crear clases abstractas\n                                    #Estas sirven para crear como un contrato o interfaz y decirle a las subclases que deben\n                                    #tener un metodo calcular\n\nclass EstrategiaDescuento(ABC): # Defino la clase como abstracta. No se puden crear instancias de ellas directamente, deben ser heredadas.\n    @abstractmethod             # Indico que este metodo es abstracto y que debe ser implementado en las sublases.\n    def calcular(self, monto):\n        pass\n\nclass DescuentoRegular(EstrategiaDescuento): # Estrategis de descuento. Si quiero añadir blackFriday añado otra clase sin modificar nada.\n    def calcular(self, monto):\n        return monto * 0.95\n    \nclass DescuentoVip(EstrategiaDescuento):\n    def calcular(self, monto):\n        return monto * 0.90\n    \nclass DescuentoSuperVip(EstrategiaDescuento):\n    def calcular(self, monto):\n        return monto * 0.85\n    \nclass CalculadoraDescuentos: # Clase calculadora que recibe una estrategia y llama al metodo calcular de esa estrategia.\n    def __init__(self, estrategia: EstrategiaDescuento):\n        self.estrategia = estrategia\n\n    def calcular(self, monto): # No sabe a que esta llamando simplemente llama al metodo de la estrategia guardada.\n        return self.estrategia.calcular(monto)\n    \ncliente_regular = DescuentoRegular()\ncliente_vip = DescuentoVip()\ncliente_super_vip = DescuentoSuperVip()\n\ncalculadora = CalculadoraDescuentos(cliente_regular)\nprint(f\"Descuento regular: {calculadora.calcular(100)}\")\ncalculadora = CalculadoraDescuentos(cliente_vip)\nprint(f\"Descuento vip: {calculadora.calcular(100)}\")\ncalculadora = CalculadoraDescuentos(cliente_super_vip)\nprint(f\"Descuento super vip: {calculadora.calcular(100)}\")\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas. \n * Requisitos:\n * - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n * Instrucciones:\n * 1. Implementa las operaciones de suma, resta, multiplicación y división.\n * 2. Comprueba que el sistema funciona.\n * 3. Agrega una quinta operación para calcular potencias.\n * 4. Comprueba que se cumple el OCP.\n\"\"\"\n\n# Diccionario donde se van a registrar automáticamente las operaciones.\ncommand_registry = {}\n\n# Decorador que registra una clase comando con un símbolo (como \"+\", \"-\", etc.)\ndef register_command(symbol):\n    def decorator(cls):\n        command_registry[symbol] = cls() # Guarda una instancia de la clase\n        return cls # Devuelve la clase sin modificarla para que se pueda seguir utilizando la clase en el reto del codigo despues de decorarla.\n    return decorator\n\nclass Command(ABC):\n    @abstractmethod\n    def execute(self, *args):\n        pass\n\n@register_command(\"+\")      #Python realmente hace esto: AddCommand = register_command(\"+\") -->decorator(AddCommand) --> AddComand\nclass AddCommand(Command):  # entonces Addcomand sigue siendo Addcomand aunque se haya decorado.\n    def execute(self, a, b):\n        return a + b\n\n@register_command(\"-\")    \nclass SubCommand(Command):\n    def execute(self, a, b):\n        return a - b\n\n@register_command(\"*\")    \nclass MulCommand(Command):\n    def execute(self, a, b):\n        return a * b\n\n@register_command(\"/\")    \nclass DivCommand(Command):\n    def execute(self, a, b):\n        return a / b\n\n@register_command(\"**\")    \nclass ExpCommand(Command):\n    def execute(self, a, b):\n        return a ** b\n    \nclass Invoker:\n    #def __init__(self):  ya no necesito el init para inicializar el diccionario de operaciones.\n        #self.commands = {}\n\n    #def add_command(self, name:str, command: Command): y tampoco el metodo para registraroperacione manualmente.\n        #self.commands[name] = command\n\n    def calculate(self, name, *args):\n        if name in command_registry:\n            return command_registry[name].execute(*args)\n        else:\n            raise ValueError(f\"La operación {name} no esta soportada.\")\n    \n\nnum1 = 6\nnum2 = 3\n\ncalculator = Invoker()\n#Ya no es necesario registrar las operaciones manualmente ya que se hace con el decorador de clase.\n#calculator.add_command(\"+\", AddCommand()) # Realmente no se pasa la clase, sino que se crea una instacia en el momento\n#calculator.add_command(\"-\", SubCommand())# Es como hacer add = Addition() y luego pasar add.\n#calculator.add_command(\"*\", MulCommand())\n#calculator.add_command(\"/\", DivCommand())\n#calculator.add_command(\"**\", ExpCommand())\n\ntry:\n    print(f\"{num1} + {num2} = {calculator.calculate(\"+\", num1, num2)}\")\n    print(f\"{num1} - {num2} = {calculator.calculate(\"-\", num1, num2)}\")\n    print(f\"{num1} * {num2} = {calculator.calculate(\"*\", num1, num2)}\")\n    print(f\"{num1} / {num2} = {calculator.calculate(\"/\", num1, num2)}\")\n    print(f\"{num1} ** {num2} = {calculator.calculate(\"**\", num1, num2)}\")\nexcept ValueError as e:\n    print(e)\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/javi-kl.py",
    "content": "# incorrecta\nclass ErroneaAnimal:\n    def emitir_sonido1(self, tipo_animal, sonido):\n        if tipo_animal == \"gallina\":\n            return sonido * 2\n        elif tipo_animal == \"perro\":\n            return sonido * 1\n\n\nanimal1 = ErroneaAnimal()\nanimal1.emitir_sonido1(\"perro\", \"guau\")\nanimal2 = ErroneaAnimal()\nanimal2.emitir_sonido1(\"gallina\", \"kikiriki\")\n# Si quisiermos añadir mas animales tendrimos que modificar la clase.\n\n# correcta\nfrom abc import ABC, abstractmethod\n\n\nclass Animal(ABC):\n    @abstractmethod\n    def emitir_sonido(self) -> str:\n        pass\n\n\nclass Perro(Animal):\n    def emitir_sonido(self):\n        return \"guauu\"\n\n\nclass Gallina(Animal):\n    def emitir_sonido(self):\n        return \"kikiriki\"\n\n\n# Nuevo animal sin modificar clases existentes\nclass Gato(Animal):\n    def emitir_sonido(self):\n        return \"miau\"\n\n\n# Uso\nanimales = [Perro(), Gallina(), Gato()]\nfor animal in animales:\n    print(animal.emitir_sonido())\n\n\n\"\"\"\nextra\n\"\"\"\n\n\nclass Operaciones(ABC):\n    @abstractmethod\n    def operar(self, a, b):\n        pass\n\n\nclass Sumar(Operaciones):\n    def operar(self, a, b):\n        return a + b\n\n\nclass Restar(Operaciones):\n    def operar(self, a, b):\n        return a - b\n\n\nclass Multiplicar(Operaciones):\n    def operar(self, a, b):\n        return a * b\n\n\nclass Dividir(Operaciones):\n    def operar(self, a, b):\n        return a / b\n\n\n# Comprobamos que se cumple el OCP si al agregar una nueva operación no tenemos que modificar las actuales.\n# Para añádir calcular potencias, agregar una nueva subclase \"Potencia\"\nclass Potencia(Operaciones):\n    def operar(self, a, b):\n        return a**b\n\n\n# Esta es la forma correcta.Recuerda, las clases y metodos deberían hacer una sola cosa(1 sola responsabilidad)\nclass Calculadora:\n\n    def calcular(self, operacion: Operaciones, a, b):\n        print(operacion.operar(a, b))\n\n\ncalculadora = Calculadora()\ncalculadora.calcular(Sumar(), 4, 5)\ncalculadora.calcular(Restar(), 4, 5)\ncalculadora.calcular(Multiplicar(), 4, 5)\ncalculadora.calcular(Dividir(), 4, 5)\ncalculadora.calcular(Potencia(), 4, 5)\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/juanmax2.py",
    "content": "\"\"\"\nEjercicio\n\"\"\"\n\n\nclass Form:\n    \n    def draw(self):\n        pass\n        \nclass Cuadrado(Form):\n    \n    def draw(self):\n        print(\"Dibujar un cuadrado\")\n        \nclass Circulo(Form):\n    \n    def draw(self):\n        print(\"Dibujar un círculo\")\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas. \n * Requisitos:\n * - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n * Instrucciones:\n * 1. Implementa las operaciones de suma, resta, multiplicación y división.\n * 2. Comprueba que el sistema funciona.\n * 3. Agrega una quinta operación para calcular potencias.\n * 4. Comprueba que se cumple el OCP.\n */\n\"\"\"\nfrom abc import ABC, abstractmethod\n    \nclass Operacion(ABC):\n    \n    @abstractmethod\n    def operar(self, a, b):\n        pass\n    \nclass Suma(Operacion):\n    \n    def operar(self, a, b):\n        return a + b\n    \nclass Resta(Operacion):\n    \n    def operar(self, a ,b):\n        return a - b\nclass Multiplicacion(Operacion):\n    \n    def operar(self, a ,b):\n        return a * b\n    \nclass Division(Operacion):\n    \n    def operar(self, a ,b):\n        return a / b\n\nclass Potencia(Operacion):\n    \n    def operar(self, a ,b):\n        return a ** b\n    \nclass Calculadora:\n    \n    def __init__(self) -> None:\n        self.operaciones = {}\n        \n    def añadir_operaciones(self, nombre, operacion):\n        self.operaciones[nombre] = operacion\n        \n    def calcular(self, nombre, a, b):\n        if nombre not in self.operaciones:\n            raise ValueError(f\"La operación {nombre} no esta soportada\")\n        return self.operaciones[nombre].operar(a, b)\n    \ncalculadora = Calculadora()\n\ncalculadora.añadir_operaciones(\"sumar\", Suma())\ncalculadora.añadir_operaciones(\"restar\", Resta())\ncalculadora.añadir_operaciones(\"multiplicar\", Multiplicacion())\ncalculadora.añadir_operaciones(\"dividir\", Division())\ncalculadora.añadir_operaciones(\"potencia\", Potencia())\n\nprint(calculadora.calcular(\"sumar\", 10, 5))\nprint(calculadora.calcular(\"restar\", 10, 5))\nprint(calculadora.calcular(\"multiplicar\", 10, 5))\nprint(calculadora.calcular(\"dividir\", 10, 5))\nprint(calculadora.calcular(\"potencia\", 10, 5))\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/juanppdev.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n\"\"\"\n\n# Incorrecto\n\nclass Calculadora:\n    def __init__(self):\n        pass\n\n    def calcular(self, operacion, a, b):\n        if operacion == \"suma\":\n            return a + b\n        elif operacion == \"resta\":\n            return a - b\n        # Si queremos agregar una nueva operación, tendríamos que modificar esta clase\n        elif operacion == \"multiplicacion\":\n            return a * b\n        else:\n            raise ValueError(\"Operación no soportada\")\n\n# Uso\ncalc = Calculadora()\nprint(calc.calcular(\"suma\", 5, 3))  # Salida: 8\nprint(calc.calcular(\"resta\", 5, 3))  # Salida: 2\nprint(calc.calcular(\"multiplicacion\", 5, 3))  # Salida: 15\n\n\n# Correcto\n\nfrom abc import ABC, abstractmethod\n\nclass Operacion(ABC):\n    @abstractmethod\n    def calcular(self, a, b):\n        pass\n\nclass Suma(Operacion):\n    def calcular(self, a, b):\n        return a + b\n\nclass Resta(Operacion):\n    def calcular(self, a, b):\n        return a - b\n\n# Ahora podemos agregar nuevas operaciones sin modificar la clase Calculadora\nclass Multiplicacion(Operacion):\n    def calcular(self, a, b):\n        return a * b\n\nclass Calculadora:\n    def __init__(self):\n        self.operaciones = {}\n\n    def registrar_operacion(self, nombre, operacion):\n        self.operaciones[nombre] = operacion\n\n    def calcular(self, nombre, a, b):\n        if nombre in self.operaciones:\n            return self.operaciones[nombre].calcular(a, b)\n        else:\n            raise ValueError(\"Operación no soportada\")\n\n# Uso\ncalc = Calculadora()\ncalc.registrar_operacion(\"suma\", Suma())\ncalc.registrar_operacion(\"resta\", Resta())\ncalc.registrar_operacion(\"multiplicacion\", Multiplicacion())\n\nprint(calc.calcular(\"suma\", 5, 3))  # Salida: 8\nprint(calc.calcular(\"resta\", 5, 3))  # Salida: 2\nprint(calc.calcular(\"multiplicacion\", 5, 3))  # Salida: 15\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas. \n * Requisitos:\n * - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n * Instrucciones:\n * 1. Implementa las operaciones de suma, resta, multiplicación y división.\n * 2. Comprueba que el sistema funciona.\n * 3. Agrega una quinta operación para calcular potencias.\n * 4. Comprueba que se cumple el OCP.\n\"\"\"\n\nfrom abc import ABC, abstractmethod\n\nclass Operacion(ABC):\n    @abstractmethod\n    def calcular(self, a, b):\n        pass\n\nclass Suma(Operacion):\n    def calcular(self, a, b):\n        return a + b\n\nclass Resta(Operacion):\n    def calcular(self, a, b):\n        return a - b\n\nclass Multiplicacion(Operacion):\n    def calcular(self, a, b):\n        return a * b\n\nclass Division(Operacion):\n    def calcular(self, a, b):\n        if b == 0:\n            raise ValueError(\"No se puede dividir por cero\")\n        return a / b\n\nclass Calculadora:\n    def __init__(self):\n        self.operaciones = {}\n\n    def registrar_operacion(self, nombre, operacion):\n        self.operaciones[nombre] = operacion\n\n    def calcular(self, nombre, a, b):\n        if nombre in self.operaciones:\n            return self.operaciones[nombre].calcular(a, b)\n        else:\n            raise ValueError(\"Operación no soportada\")\n\n# Uso\ncalc = Calculadora()\ncalc.registrar_operacion(\"suma\", Suma())\ncalc.registrar_operacion(\"resta\", Resta())\ncalc.registrar_operacion(\"multiplicacion\", Multiplicacion())\ncalc.registrar_operacion(\"division\", Division())\n\nprint(calc.calcular(\"suma\", 5, 3))  # Salida: 8\nprint(calc.calcular(\"resta\", 5, 3))  # Salida: 2\nprint(calc.calcular(\"multiplicacion\", 5, 3))  # Salida: 15\nprint(calc.calcular(\"division\", 5, 3))  # Salida: 1.6666666666666667\n\n\nclass Potencia(Operacion):\n    def calcular(self, a, b):\n        return a ** b\n\n# Registrar la nueva operación\ncalc.registrar_operacion(\"potencia\", Potencia())\n\nprint(calc.calcular(\"potencia\", 2, 3))  # Salida: 8\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/kenysdev.py",
    "content": "# ╔═════════════════════════════════════╗\n# ║ Autor:  Kenys Alvarado              ║\n# ║ GitHub: https://github.com/Kenysdev ║\n# ║ 2024 -  Python                      ║\n# ╚═════════════════════════════════════╝\n\n# -------------------------------------------------\n# * SOLID: PRINCIPIO ABIERTO-CERRADO (OCP)\n# -------------------------------------------------\n# - Una entidad de software debería estar abierta a extensión pero cerrada a \n#   modificación, esto significa que debemos poder extender el comportamiento de \n#   una clase sin necesidad de modificar su código fuente original.\n\n\"\"\"\n* EJERCICIO #1:\n * Explora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n\"\"\"\n\n# ABC (Abstract Base Class): \n# Para establecer contratos entre clases base y sus 'subclases'.\n# https://www.geeksforgeeks.org/abstract-classes-in-python/\nfrom abc import ABC, abstractmethod\n\n# Clase base\nclass Product(ABC):\n    def __init__(self, name, price):\n        self.name = name\n        self.price = price\n    \n    @abstractmethod\n    def apply_discount(self):\n        pass\n\n    def final_price(self):\n        return self.price - self.apply_discount()\n\n# Clases concretas (Nuevas extenciones)\nclass ElectronicsProduct(Product):\n    def apply_discount(self):\n        return self.price * 0.05 # Descuento del 5%\n\nclass ClothingProduct(Product):\n    def apply_discount(self):\n        if self.price > 50:\n            return 10 \n        else:\n            return 0\n\ndef process_product(product):\n    print(f\"Producto: {product.name}, Precio final: {product.final_price()}\")\n\nlaptop = ElectronicsProduct(\"Laptop\", 700)\npants = ClothingProduct(\"Pants\", 55)\n\nprocess_product(laptop) # Output: Producto: Laptop, Precio final: 665.0\nprocess_product(pants)  # Output: Producto: Pants, Precio final: 45\n\n\"\"\"\n* EJERCICIO #2:\n* Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas. \n* Requisitos:\n* - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n* Instrucciones:\n* 1. Implementa las operaciones de suma, resta, multiplicación y división.\n* 2. Comprueba que el sistema funciona.\n* 3. Agrega una quinta operación para calcular potencias.\n* 4. Comprueba que se cumple el OCP.\n\"\"\"\n\n# Clase base\nclass Calculator(ABC):\n    def __init__(self, a, b):\n        if isinstance(a, (int, float)) and isinstance(b, (int, float)):\n            self.a = a\n            self.b = b\n        else:\n            self.a = None\n            self.b = None\n            print(\"Operación invalida.\")\n            \n    @abstractmethod\n    def math_operation(self):\n        pass\n    \n    def print_result(self):\n        if self.a is not None and self.b is not None:\n            print(f\"Es: {self.math_operation()}\")\n        else:\n            print(\"Campos incorrectos.\")\n\n# Clases concretas\nclass Sum(Calculator):\n    def math_operation(self):\n        print(f\"\\nSuma de {self.a} + {self.b}:\")\n        return self.a + self.b\n\nclass Subtraction(Calculator):\n    def math_operation(self):\n        print(f\"\\nResta de {self.a} - {self.b}:\")\n        return self.a - self.b\n\nclass Multiplication(Calculator):\n    def math_operation(self):\n        print(f\"\\nMultiplicación de {self.a} * {self.b}:\")\n        return self.a * self.b\n\nclass Division(Calculator):\n    def math_operation(self):\n        print(f\"\\nDivisión de {self.a} / {self.b}:\")\n        return self.a / self.b\n\nclass Pow(Calculator):\n    def math_operation(self):\n        print(f\"\\nPotencia de {self.a} ^ {self.b}:\")\n        return self.a ** self.b\n\nsum_ = Sum(2, 2)\nsum_.print_result()\n\nsubtraction = Subtraction(2, 2)\nsubtraction.print_result()\n\nmultip = Multiplication(2, 2)\nmultip.print_result()\n\ndiv = Division(2, 2)\ndiv.print_result()\n\npow_ = Pow(2, 2)\npow_.print_result()\n\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/mhayhem.py",
    "content": "# @Author daniel Grande (Mhayhem)\n\n# EJERCICIO:\n# Explora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\" \n# y crea un ejemplo simple donde se muestre su funcionamiento\n# de forma correcta e incorrecta.\n\n# INCORRECTO\nclass CalculateArea:\n    def calculate_area(self, shape: str, **kwargs):\n        if shape == \"circulo\":\n            return 3.14 * kwargs['radio'] ** 2\n        elif shape == \"cuadrado\":\n            return kwargs['width'] * kwargs['height']\n\n\"\"\" para añadir triangulo tendriamos que modificar la clase\"\"\"\n\n\n\n# CORRECTO\n\nclass GeometricShape:\n    def calculate_area(self):\n        raise NotImplementedError(\"Debes inplementar calculate_area\")\n\nclass Circle(GeometricShape):\n    def __init__(self, radio: float):\n        self.radio = radio\n    \n    def calculate_area(self) -> float:\n        return 3.14 * self.radio ** 2\n\nclass Square(GeometricShape):\n    def __init__(self, width: float, height: float):\n        self.width = width\n        self.height = height\n    \n    def calculate_area(self) -> float:\n        return self.width * self.height\n\n\"\"\" ahora si queremos incorporar el triangulo solo debemos crear otra clase \"\"\"\n\nclass Triangle(GeometricShape):\n    def __init__(self, base: float, height: float):\n        self.base = base\n        self.height = height\n    \n    def calculate_area(self) -> float:\n        return (self.base * self.height) / 2\n\n\n\n# DIFICULTAD EXTRA (opcional):\n# Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas. \n# Requisitos:\n# - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n# Instrucciones:\n# 1. Implementa las operaciones de suma, resta, multiplicación y división.\n# 2. Comprueba que el sistema funciona.\n# 3. Agrega una quinta operación para calcular potencias.\n# 4. Comprueba que se cumple el OCP.\n\n\nclass Calculator:\n    def __init__(self, n1: float, n2: float):\n        self.n1 = n1\n        self.n2 = n2\n    \n    def operation(self):\n        pass\n\nclass Add(Calculator):\n    def operation(self):\n        return self.n1 + self.n2\n\nclass Subtract(Calculator):\n    def operation(self):\n        return self.n1 - self.n2\n\nclass Multiply(Calculator):\n    def operation(self):\n        return  self.n1 * self.n2\n\nclass Division(Calculator):\n    def operation(self):\n        if self.n2 == 0:\n            raise ValueError(\"No se puede dividir por cero\")\n        return self.n1 / self.n2\n\nclass Raised(Calculator):\n    def operation(self):\n        return self.n1 ** self.n2\n    \n\nadd = Add(3, 5)\nprint(add.operation())"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/mouredev.py",
    "content": "\"\"\"\nEjercicio\n\"\"\"\n\n\nfrom abc import ABC, abstractmethod\n\n\nclass Form:\n    def draw(self):\n        pass\n\n\nclass Square(Form):\n    def draw(self):\n        print(\"Dibuja un cuadrado\")\n\n\nclass Circle(Form):\n    def draw(self):\n        print(\"Dibuja un círculo\")\n\n\nclass Triangle(Form):\n    def draw(self):\n        print(\"Dibuja un triángulo\")\n\n\n\"\"\"\nExtra\n\"\"\"\n\n\nclass Operation(ABC):\n    @abstractmethod\n    def execute(self, a, b):\n        pass\n\n\nclass Addition(Operation):\n    def execute(self, a, b):\n        return a + b\n\n\nclass Substration(Operation):\n    def execute(self, a, b):\n        return a - b\n\n\nclass Multiplication(Operation):\n    def execute(self, a, b):\n        return a * b\n\n\nclass Division(Operation):\n    def execute(self, a, b):\n        return a / b\n\n\nclass Power(Operation):\n    def execute(self, a, b):\n        return a ** b\n\n\nclass Calculator:\n    def __init__(self) -> None:\n        self.operations = {}\n\n    def add_operation(self, name, operation):\n        self.operations[name] = operation\n\n    def calculate(self, name, a, b):\n        if name not in self.operations:\n            raise ValueError(f\"La operación {name} no está soportada.\")\n        return self.operations[name].execute(a, b)\n\n\ncalculator = Calculator()\ncalculator.add_operation(\"addition\", Addition())\ncalculator.add_operation(\"substration\", Substration())\ncalculator.add_operation(\"multiplication\", Multiplication())\ncalculator.add_operation(\"division\", Division())\ncalculator.add_operation(\"power\", Power())\n\nprint(calculator.calculate(\"addition\", 10, 5))\nprint(calculator.calculate(\"substration\", 10, 5))\nprint(calculator.calculate(\"multiplication\", 10, 5))\nprint(calculator.calculate(\"division\", 10, 5))\nprint(calculator.calculate(\"power\", 10, 5))\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/mrodara.py",
    "content": "#### SOLID PRINCIPIO ABIERTO-CERRADO (OCP)\n\n'''\nEste principio establece que las clases deben estar abiertas para la extensión, pero cerradas para la modificación.\n\nEn otras palabras, puedes agregar nuevas funcionalidades a una clase sin modificar su código existente. \nEsto ayuda a evitar errores inesperados en el código ya probado y a facilitar la escalabilidad.\n'''\n\n'''\nVentajas:\n\nProtege el código existente\nFacilita la extensión\nFavorece el diseño modular\n'''\n\n# Ejemplo que inclumple OCP\n\n#class CalculadoraArea():\n#    def calcular_area(self, forma):\n#        if forma.lower() == \"circulo\":\n#            radio = float(input(\"Introduce el radio de la circunferencia: \"))\n#            return 3.14 * (radio ** 2)\n#        elif forma.lower() == \"cuadrado\":\n#            lado = float(input(\"Introduce longitud de lado: \"))\n#            return lado ** 2\n#\n#print(CalculadoraArea().calcular_area(\"Circulo\"))\n#print(CalculadoraArea().calcular_area(\"cuadrado\"))\n\n# Fin Ejemplo que inclumple OCP\n\n# Podemos usar polimorfismo para cumplir con el OCP, creando una clase base o interfaz que permita \n# a las formas geométricas implementar su propio método de cálculo de área.\n\nfrom abc import ABC, abstractmethod\n\n# Clase abstracta para formas geométricas\n#class Forma(ABC):\n#    @abstractmethod\n#    def calcular_area(self):\n#        pass\n#\n## Implementaciones específicas de formas\n#class Circulo(Forma):\n#    def __init__(self, radius):\n#        self.radius = radius\n#        \n#    def calcular_area(self):\n#        return 3.14 * (self.radius ** 2)\n#\n#class Cuadrado(Forma):\n#    def __init__(self, side):\n#        self.side = side\n#    \n#    def calcular_area(self):\n#        return self.side ** 2\n#\n## Prueba\n#formas = [\n#    Circulo(5),\n#    Cuadrado(4)\n#]\n#\n#for forma in formas:\n#    print(forma.calcular_area())  # Output: 78.5, 16\n\nclass Calculadora(ABC):\n    \n    @abstractmethod\n    def calcular(self):\n        pass\n\nclass Suma(Calculadora):\n    \n    def calcular(self, a, b):\n        return a + b\n\nclass Resta(Calculadora):\n    def calcular(self, a, b):\n        return a - b\n\nclass Multiplicacion(Calculadora):\n    def calcular(self, a, b):\n        return a * b\n\nclass Division(Calculadora):\n    def calcular(self, a, b):\n        if b == 0:\n            raise ValueError(\"No se puede dividir por cero\")\n        return a / b\n\n# Para añadir una quinta operación es sencillo creando un nuevo método abstracto y su correspondiente clase\nclass Potencia2(Calculadora):\n    def calcular(self, a):\n        return a ** 2\n\n# Pruebas de calculadora\na = 560\nb = 12\n\noperaciones = [\n    Suma(),\n    Resta(),\n    Multiplicacion(),\n    Division(),\n    Potencia2()\n]\n\nfor operacion in operaciones:\n    if isinstance(operacion, Suma):\n        print(f\"La suma de {a} y {b} es: {operacion.calcular(a, b)}\")\n    elif isinstance(operacion, Resta):\n        print(f\"La resta de {a} y {b} es: {operacion.calcular(a,b)}\")\n    elif isinstance(operacion, Multiplicacion):\n        print(f\"La multiplicación de {a} y {b} es: {operacion.calcular(a,b)}\")\n    elif isinstance(operacion, Division):\n        print(f\"La división de {a} y {b} es: {operacion.calcular(a,b)}\")\n    else:\n        print(f\"El cuadrado de {a} es: {operacion.calcular(a)}\")\n#\n#suma = Suma()\n#print(suma.calcular(a, b))\n#\n#resta = Resta()\n#print(resta.calcular(a, b))\n#\n#multiplicacion = Multiplicacion()\n#print(multiplicacion.calcular(a, b))\n#\n#division = Division()\n#print(division.calcular(a, b))\n#\n#potencia2 = Potencia2()\n#print(potencia2.calcular(a))\n\n#### FIN SOLID PRINCIPIO ABIERTO-CERRADO (OCP)"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/neslarra.py",
    "content": "from functools import reduce\nfrom typing import final\n\n\"\"\"\n EJERCICIO:\n Explora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\"\n y crea un ejemplo simple donde se muestre su funcionamiento\n de forma correcta e incorrecta.\n\n DIFICULTAD EXTRA (opcional):\n Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas.\n Requisitos:\n - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n Instrucciones:\n 1. Implementa las operaciones de suma, resta, multiplicación y división.\n 2. Comprueba que el sistema funciona.\n 3. Agrega una quinta operación para calcular potencias.\n 4. Comprueba que se cumple el OCP.\n\"\"\"\n\nprint(f\"{'#' * 47}\")\nprint(f\"##  Explicación  {'#' * 30}\")\nprint(f\"{'#' * 47}\")\n\nprint(r\"\"\"\nPara entender fácilmente los 5 ppios SOLID recomiendo leer:\n\n    https://blog.damavis.com/los-principios-solid-ilustrados-en-ejemplos-sencillos-de-python/\n\nen donde se explican de manera ordenada uno por uno, de manera sencilla y ejemplificada de manera progresiva (de hecho, de ahí\nvoy a tomar el ejemplo).\n\nEl segundo de los ppios SOLID es \"Open Close Principle\" el cual establece que las clases deberían estar abiertas para su extensión\npero cerradas para su modificación.\n\nRetomando el caso anterior, tenemos la clase Calculate: \n\n    class Communicator:\n    \n        def __init__(self, channel):\n            self.channel = channel\n    \n        def communicate(self, duck1 : Duck, duck2: Duck):\n            sentence1 = f\"{duck1.name}: {duck1.do_sound()}, hello {duck2.name}\"\n            sentence2 = f\"{duck2.name}: {duck2.do_sound()}, hello {duck1.name}\"\n            conversation = [sentence1, sentence2]\n            print(*conversation,\n                  f\"(via {self.channel})\",\n                  sep = '\\n')\n\nEn esta clase No se puede extender la funcionalidad de Calculate para añadir diferentes tipos de conversaciones sin modificar \nel método communicate(). Para cumplir con el segundo principio, se crea una clase AbstractConversation que se encargará de definir \ndiferentes tipos de conversaciones en sus subclases con implementaciones de do_conversation(). De esta manera, el método communicate() \nde Calculate solo se regirá a llevar a cabo la comunicación a través de una canal y nunca se requerirá de su modificación (es un método final).\n\nfrom typing import final\n\n\n    class Duck:\n    \n        def __init__(self, name):\n            self.name = name\n    \n        def fly(self):\n            print(f\"{self.name} is flying not very high\")\n    \n        def swim(self):\n            print(f\"{self.name} swims in the lake and quacks\")\n    \n        @staticmethod\n        def do_sound() -> str:\n            return \"Quack\"\n    \n    \n    class AbstractConversation:\n    \n        def do_conversation(self) -> list:\n            pass\n    \n    \n    class DuckConversation(AbstractConversation):\n    \n        def __init__(self, duck1: Duck, duck2: Duck):\n            self.duck1 = duck1\n            self.duck2 = duck2\n    \n        def do_conversation(self) -> list:\n            sentence1 = f\"{self.duck1.name}: {self.duck1.do_sound()}, hello {self.duck2.name}\"\n            sentence2 = f\"{self.duck2.name}: {self.duck2.do_sound()}, hello {self.duck1.name}\"\n            return [sentence1, sentence2]\n    \n    \n    class Communicator:\n    \n        def __init__(self, channel):\n            self.channel = channel\n    \n        @final\n        def communicate(self, conversation: AbstractConversation):\n            print(*conversation.do_conversation(), sep=\"\\n\")\n    \n    \n    lucas = Duck(\"Lucas\")\n    donald = Duck(\"Donald\")\n    comm = Calculate(DuckConversation(lucas, donald))\n    comm.Communicator(comm.channel)\n\n    Lucas: Quack, hello Donald\n    Donald: Quack, hello Lucas\n\nAhora, si necesito extender Communicator para que puedan conversar dos perros, entonces solo tengo que agregar una clase DogConversation\n(subclase de AbstractConversation) que implemente SU versión canina de \"do_conversation\" dejando \"Communicator.communicate sin cambio.\n\n    class Dog:\n        \n        def __init__(self, name):\n            self.name = name\n    \n        def jump(self):\n            print(f\"{self.name} is jumpping not very high\")\n    \n        def run(self):\n            print(f\"{self.name} runs behind the cars\")\n    \n        @staticmethod\n        def do_sound() -> str:\n            return \"Guau\"\n        \n    \n    class DogConversation(AbstractConversation):\n    \n        def __init__(self, dog1: Dog, dog2: Dog):\n            self.dog1 = dog1\n            self.dog2 = dog2\n    \n        def do_conversation(self) -> list:\n            sentence1 = f\"{self.dog1.name}: {self.dog1.do_sound()}, hello {self.dog2.name}\"\n            sentence2 = f\"{self.dog2.name}: {self.dog2.do_sound()}, hello {self.dog1.name}\"\n            return [sentence1, sentence2]\n    \n    \n    scooby = Dog(\"Scooby\")\n    pluto = Dog(\"Pluto\")\n    comm = Communicator(DogConversation(scooby, pluto))\n    comm.communicate(comm.channel)\n\n    Scooby: Guau, hello Pluto\n    Pluto: Guau, hello Scooby\n\"\"\")\n\nprint(f\"{'#' * 52}\")\nprint(f\"##  Dificultad Extra  {'#' * 30}\")\nprint(f\"{'#' * 52}\\n\")\n\nprint(f\"\\nNO OCP Way {'-' * 27}\\n\")\n\n\nclass OperationNoOCP:\n\n    def __init__(self, name: str):\n        self.name = name\n\n    def addition(self, *args):\n        return self.name + \" addition = \" + str(sum(args))\n\n    def substraction(self, *args):\n        return self.name + \" substraction = \" + str(args[0] + (-1 * sum(args[1:])))\n\n    def product(self, *args):\n        return self.name + \" product = \" + str(reduce(lambda a, b: a * b, args))\n\n    def division(self, dividend: float, divisor: float):\n        if divisor == 0:\n            return self.name + \" Illegal operation: Divisor cannot be zero\"\n        return self.name + \" division = \" + str(dividend / divisor)\n\n\noperaciones = OperationNoOCP(\"NoOCP\")\nprint(operaciones.addition(1, 2, 3, -4))\nprint(operaciones.substraction(15, 2, 3, -4))\nprint(operaciones.product(1, 2, 3, -4))\nprint(operaciones.division(12, -4))\n\nprint(f\"\\nOCP Way {'-' * 30}\\n\")\n\n\nclass AbstractOperation:\n\n    def calculate(self):\n        pass\n\n\nclass Addition:\n\n    def __init__(self, *args):\n        self.name = \"OCP addition\"\n        self.args = args\n\n    def calculate(self):\n        return self.name + \" = \" + str(sum(self.args))\n\n\nclass Substraction:\n\n    def __init__(self, *args):\n        self.name = \"OCP substraction\"\n        self.args = args\n\n    def calculate(self):\n        return self.name + \" = \" + str(self.args[0] + (-1 * sum(self.args[1:])))\n\n\nclass Product:\n    def __init__(self, *args):\n        self.name = \"OCP product\"\n        self.args = args\n\n    def calculate(self):\n        return self.name + \" = \" + str(reduce(lambda a, b: a * b, self.args))\n\n\nclass Division:\n\n    def __init__(self, dividend: float, divisor: float):\n        self.name = \"OCP division\"\n        self.dividend = dividend\n        self.divisor = divisor\n\n    def calculate(self):\n        if self.divisor == 0:\n            return self.name + \" Illegal operation: Divisor cannot be zero\"\n        return self.name + \" = \" + str(self.dividend / self.divisor)\n\n\nclass DoAddition(AbstractOperation):\n\n    def __init__(self, operation: Addition):\n        self.operation = operation\n\n    def calculate(self, *args):\n        return self.operation.calculate()\n\n\nclass DoSubstraction(AbstractOperation):\n\n    def __init__(self, operation: Substraction):\n        self.operation = operation\n\n    def calculate(self, *args):\n        return self.operation.calculate()\n\n\nclass DoProduct(AbstractOperation):\n\n    def __init__(self, operation: Product):\n        self.operation = operation\n\n    def calculate(self, *args):\n        return self.operation.calculate()\n\n\nclass DoDivision(AbstractOperation):\n\n    def __init__(self, operation: Division):\n        self.operation = operation\n\n    def calculate(self, *args):\n        return self.operation.calculate()\n\n\nclass Calculate:\n\n    def __init__(self, channel):\n        self.channel = channel\n\n    @final\n    def calculate(self, operation: AbstractOperation):\n        print(operation.calculate())\n\n\nsuma = Addition(1, 2, 3, -4)\ncalc = Calculate(DoAddition(suma))\ncalc.calculate(calc.channel)\n\nresta = Substraction(15, 2, 3, -4)\ncalc = Calculate(DoSubstraction(resta))\ncalc.calculate(calc.channel)\n\nproducto = Product(1, 2, 3, -4)\ncalc = Calculate(DoProduct(producto))\ncalc.calculate(calc.channel)\n\ndivision = Division(12, -4)\ncalc = Calculate(DoDivision(division))\ncalc.calculate(calc.channel)\n\nprint(f\"\"\"\nEstá claro que si ahora quiero agregar la operación \"potencia\", para el caso NoOCP tendría que modificar\nla clase OperationNoOCP agragando el nuevo método (con las posibles consecuencias de modificar una clase que está en \nuso para las otras cuatro operaciones).\n\nEn cambio, para el caso OCP, agregar la nueva operación es solo agregar el la clase y el método abstracto correspondiente\nsin \"tocar\" las operaciones que ya están en uso.\n\"\"\")\n\n\nclass Power:\n    def __init__(self, base: int, exponent: int):\n        self.name = \"OCP power\"\n        self.base = base\n        self.exponent = exponent\n\n    def calculate(self):\n        return self.name + \" = \" + str(pow(self.base, self.exponent))\n\n\nclass DoPower(AbstractOperation):\n\n    def __init__(self, operation: Power):\n        self.operation = operation\n\n    def calculate(self, *args):\n        return self.operation.calculate()\n\n\npotencia = Power(4, 3)\ncalc = Calculate(DoPower(potencia))\ncalc.calculate(calc.channel)\n\nprint(f\"\"\"\n¿Se ve..? ahora \"Calculate\" puede llamar a Power de la misma manera que llama a las otras operaciones PERO \"Calcualte\" NUNCA fue modificada.\"\"\")\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/nlarrea.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas. \n * Requisitos:\n * - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n * Instrucciones:\n * 1. Implementa las operaciones de suma, resta, multiplicación y división.\n * 2. Comprueba que el sistema funciona.\n * 3. Agrega una quinta operación para calcular potencias.\n * 4. Comprueba que se cumple el OCP.\n\"\"\"\n\n# Incorrecto\n\n\nclass GeometricForm:\n    def draw_square(self):\n        print(\"Drawing a square\")\n\n    def draw_circle(self):\n        print(\"Drawing a circle\")\n\n\n# Correcto\n\n\nclass GeometricForm:\n    def draw(self):\n        pass\n\n\nclass Square(GeometricForm):\n    def draw(self):\n        print(\"Drawing a square!\")\n\n\nclass Circle(GeometricForm):\n    def draw(self):\n        print(\"Drawing a circle!\")\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas. \n * Requisitos:\n * - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n * Instrucciones:\n * 1. Implementa las operaciones de suma, resta, multiplicación y división.\n * 2. Comprueba que el sistema funciona.\n * 3. Agrega una quinta operación para calcular potencias.\n * 4. Comprueba que se cumple el OCP.\n\"\"\"\n\n\n# Import Abstract Base Class and abstractmethod decorator\nfrom abc import ABC, abstractmethod\n\n\n# Create the abstract class -> avoid's creating instances of this class, but\n# still allows to inherit from it\nclass Operation(ABC):\n    @abstractmethod\n    def calculate(self, num_one, num_two):\n        pass\n\n\n# Create the different operations\n\n\nclass Sum(Operation):\n    def calculate(self, num_one, num_two):\n        return num_one + num_two\n\n\nclass Subtraction(Operation):\n    def calculate(self, num_one, num_two):\n        return num_one - num_two\n\n\nclass Multiplication(Operation):\n    def calculate(self, num_one, num_two):\n        return num_one * num_two\n\n\nclass Division(Operation):\n    def calculate(self, num_one, num_two):\n        return num_one / num_two\n\n\n# Create the Calculator class\nclass Calculator:\n    def __init__(self) -> None:\n        self.operations = dict()\n\n    def set_operation(self, name: str, operation: object):\n        \"\"\"Allow adding new operations to the current calculator instance.\"\"\"\n\n        if not isinstance(name, str):\n            raise ValueError(\"The operation name must be an string!\")\n        self.operations[name] = operation\n\n    def calculate(self, name: str, num_one, num_two):\n        \"\"\"Checks if the given operation name exists and returns the value of\n        the operation.\"\"\"\n\n        if name not in self.operations:\n            raise ValueError(f\"The operation '{name}' doesn't exist!\")\n        return self.operations[name].calculate(num_one, num_two)\n\n\n# Create the Calculator's instance and set different operations\ncalculator = Calculator()\ncalculator.set_operation(\"sum\", Sum())\ncalculator.set_operation(\"subtract\", Subtraction())\ncalculator.set_operation(\"multiply\", Multiplication())\ncalculator.set_operation(\"divide\", Division())\n\n# Check if operations work\nprint(calculator.calculate(\"sum\", 10, 2))  # 12\nprint(calculator.calculate(\"subtract\", 10, 2))  # 8\nprint(calculator.calculate(\"multiply\", 10, 2))  # 20\nprint(calculator.calculate(\"divide\", 10, 2))  # 5.0\n# print(calculator.calculate(\"pow\", 10, 2))  # The operation 'pow' doesn't exist\n\n\n# Create the new Pow operation\nclass Pow(Operation):\n    def calculate(self, num_one, num_two):\n        return num_one**num_two\n\n\n# Set it to the calculator\ncalculator.set_operation(\"pow\", Pow())\n\n# Check if operation works\nprint(calculator.calculate(\"pow\", 10, 2))  # 100\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/oriaj3.py",
    "content": "\"\"\"\n27 - SOLID OCP\nTeoría - OCP (Open/Closed Principle)\n\nEl principio abierto/cerrado (OCP) establece que una entidad de software debe estar abierta para su extensión, \npero cerrada para su modificación. Esto significa que una clase debe ser extensible sin modificar su código fuente.\n\nEn otras palabras, el principio OCP establece que una clase debe ser abierta para la extensión, pero cerrada para la modificación.\n\nExtender una clase significa agregar nuevas funcionalidades a una clase existente. \nY modificar una clase significa cambiar su código fuente.\n\nEl principio OCP se puede lograr mediante el uso de interfaces y clases abstractas.\n\"\"\"\n\n## Ejercicio\n\n\"\"\"\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n\"\"\"\n# Ejemplo incorrecto\nclass FormBad:\n\n    def draw_square(self):\n        print(\"Drawing square\")\n\n    def draw_circle(self):\n        print(\"Drawing circle\")\n\n    def draw_triangle(self):\n        print(\"Drawing triangle\")\n\n# Ejemplo correcto\nclass Form:\n    def draw(self):\n        pass\n\nclass Square(Form):\n    def draw(self):\n        print(\"+----+\")\n        print(\"| ** |\")\n        print(\"| ** |\")\n        print(\"+----+\")\n\nclass Triangle(Form):\n    def draw(self):\n        print(\"  /\\\\\")\n        print(\" /  \\\\\")\n        print(\"/____\\\\\")\n\nclass Circle(Form):\n    def draw(self):\n        print(\"  ****\")\n        print(\" *    *\")\n        print(\" *    *\")\n        print(\"  ****\")\n\nforms = [Square(), Triangle(), Circle()]\nfor form in forms:\n    form.draw()\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas. \n * Requisitos:\n * - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n * Instrucciones:\n * 1. Implementa las operaciones de suma, resta, multiplicación y división.\n * 2. Comprueba que el sistema funciona.\n * 3. Agrega una quinta operación para calcular potencias.\n * 4. Comprueba que se cumple el OCP.\n */\n\"\"\"\n\n# Ejemplo incorrecto\nclass CalculatorBad:\n\n    def sum(self, a, b):\n        return a + b\n\n    def subtract(self, a, b):\n        return a - b\n\n    def multiply(self, a, b):\n        return a * b\n\n    def divide(self, a, b):\n        return a / b\n\n# Ejemplo correcto\nclass Operation:\n    def operate(self, a, b):\n        pass\n\nclass Sum(Operation):\n    def operate(self, a, b):\n        return a + b\n\nclass Subtract(Operation):\n    def operate(self, a, b):\n        return a - b\n\nclass Multiply(Operation):\n    def operate(self, a, b):\n        return a * b\n    \nclass Divide(Operation):\n    def operate(self, a, b):\n        return a / b\n\nclass Power(Operation):\n    def operate(self, a, b):\n        return a ** b\n\n#Ejemplo de uso\noperations = [Sum(), Subtract(), Multiply(), Divide(), Power()]\n\nfor operation in operations:\n    print(f\"{operation.__class__.__name__} => {operation.operate(2, 3)}\")\n\n# Ejempo mejorado con abstracción\n# La clase Operation es una clase abstracta que define un método abstracto operate.\n# Las clases Sum, Subtract, Multiply, Divide y Power heredan de Operation y sobreescriben el método operate.\n# La mejora es que en las clases hijo es obligatorio implementar el método operate, \n# lo que garantiza que todas las operaciones tengan la misma firma.\n\nfrom abc import ABC, abstractmethod\nfrom typing import Any\n\n#ABC = Abstract Base Class (Clase Base Abstracta)\n\nclass Operation(ABC):\n    @abstractmethod\n    def operate(self, a, b):\n        pass\n\nclass Sum(Operation):\n    def operate(self, a, b):\n        return a + b\n\nclass Subtract(Operation):\n    def operate(self, a, b):\n        return a - b\n\nclass Multiply(Operation):\n    def operate(self, a, b):\n        return a * b\n    \nclass Divide(Operation):\n    def operate(self, a, b):\n        return a / b\n\nclass Power(Operation):\n    def operate(self, a, b):\n        return a ** b\n\n# CLASE CALCULADORA QUE SOLICITA AL USUARIO QUE INGRESE DOS NÚMEROS Y UNA OPERACIÓN MATEMÁTICA\nclass Calculator:\n    def __init__(self):\n        self.operations = {}\n\n    def add_operation(self, name, operation):\n        self.operations[name] = operation\n\n    def run(self):\n        a = float(input(\"Enter a number: \"))\n        b = float(input(\"Enter another number: \"))\n        for name, operation in self.operations.items():\n            print(f\"{name} => {operation.operate(a, b)}\")\n\ncalculator = Calculator()\ncalculator.add_operation(\"Sum\", Sum())\ncalculator.add_operation(\"Subtract\", Subtract())\ncalculator.add_operation(\"Multiply\", Multiply())\ncalculator.add_operation(\"Divide\", Divide())\ncalculator.add_operation(\"Power\", Power())\n\ncalculator.run()"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/pyramsd.py",
    "content": "from abc import ABC, abstractmethod\n\n# USO CORRECTO\nclass Area:\n    @abstractmethod\n    def area(self):\n        pass\n\nclass Rectangulo(Area):\n    def __init__(self, width, height) -> None:\n        self.width = width\n        self.height = height\n    \n    def area(self):\n        return self.width * self.height\n    \nclass Circulo(Area):\n    def __init__(self, radius) -> None:\n        self.radius = radius    \n    def area(self):\n        return 3.14159 * (self.radius ** 2)\n    \n\ndef total_area(shapes):\n    return sum(shape.area() for shape in shapes)\n\n\nshapes = [Rectangulo(3, 4), Circulo(5)]\nprint(f\"Area Total: {total_area(shapes)}\")\n\n\n# USO INCORRECTO\nclass Area_1():\n    def __init__(self):\n        pass\n\n    def rectangle(self, side, high):\n        return side*high\n    \n    def circle(self, radius):\n        return 3.14159*radius*radius\n    \n\n\"\"\"\nEXTRA\n\"\"\"\nfrom functools import reduce\n\nclass Operacion(ABC):\n    @abstractmethod\n    def calcular():\n        pass\n\nclass Sum(Operacion):\n    def calcular(self, args: list):\n        print(f\"El resultado es: {reduce(lambda x, y:  x+ y, args)}\\n\")\n\nclass Resta(Operacion):\n    def calcular(self, args: list):\n        print(f\"El resultado es: {reduce(lambda x, y: x - y, args)}\\n\")\n\nclass Multiplicacion(Operacion):\n    def calcular(self, args: list):\n        print(f\"El resultado es: {reduce(lambda x, y: x * y, args)}\\n\")\n\nclass Division(Operacion):\n    def calcular(self, args: list):\n        print(f\"El restultado es: {reduce(lambda x, y: x / y, args)}\\n\")\n\nclass Potencia(Operacion):\n    def calcular(self, args: list):\n        if len(args) > 2:\n            raise ValueError(\"Pasar solo dos argumentos. base y exponente\")\n        else:\n            print(f\"El resultado es: {pow(args[0], args[1])}\\n\")\n\nclass Calculator():\n    def __init__(self) -> None:\n        self.operaciones = {\n            \"suma\": Sum(),\n            \"resta\": Resta(),\n            \"multiplicacion\": Multiplicacion(),\n            \"division\": Division()\n        }\n\n    def add_operation(self, nombre: str, operacion: Operacion):\n        self.operaciones[nombre] = operacion\n\n    def execute(self, nombre):\n        if nombre not in self.operaciones:\n            raise ValueError(\"La operación no está contemplada en esta calculadora\")\n        else:\n            num_operators = list()\n            operators = input(\"Operandos separados por coma: \")\n            operators = operators.strip()\n            list_operators = operators.split(\",\")\n            try:\n                for element in list_operators:\n                    if element.__contains__(\".\"):\n                        num_operators.append(float(element))\n                    else:\n                        num_operators.append(int(element))\n            except ValueError:\n                print(\"Los valores introducidos han de ser números\")\n            else:\n                self.operaciones[nombre].calcular(num_operators)\n\n\ndef calculator():\n    my_calculator = Calculator()\n    my_calculator.add_operation(nombre=\"potencia\", operacion=Potencia()) #añado la potencia con Power()\n    options = {\n        \"S\": \"suma\",\n        \"R\": \"resta\",\n        \"M\": \"multiplicacion\",\n        \"D\": \"division\",\n        \"P\": \"potencia\"\n    }\n    print(\" --- Calculadora --- \")\n    while True:\n        option = input(\"Elige una opción por favor:\\n- Suma (S)\\n- Resta (R)\\n- Multiplicación (M)\\n- División (D)\\n- Potencia (P)\\n- Salir (O)\\n>>> \").upper()\n        if option == \"O\":\n            print(\"Programa cerrado\")\n            break\n        elif option not in options:\n            print(\"La opción no es válida\\n\")\n        else:\n            my_calculator.execute(options[option])\n\ncalculator()\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/qwik-zgheib.py",
    "content": "# -- exercise \n# incorrect\nclass LegionCommander:\n    def __init__(self, name):\n        self.name = name\n        self.skills = []\n\n    def add_skill(self, skill_name, damage):\n        skill = {\"skill_name\": skill_name, \"damage\": damage}\n        self.skills.append(skill)\n\n    def use_skill(self, skill_name):\n        for skill in self.skills:\n            if skill[\"skill_name\"] == skill_name:\n                print(f\"{self.name} uses {skill_name} dealing {skill['damage']} damage\")\n                return\n        print(f\"{self.name} does not have the skill {skill_name}\")\n\nlegion = LegionCommander(\"Legion Commander\")\nlegion.add_skill(\"Overwhelming Odds\", 100)\nlegion.add_skill(\"Press the Attack\", 50)\nlegion.use_skill(\"Overwhelming Odds\")\nlegion.use_skill(\"Duel\")\n\n# If we want to add a new skill, we have to modify the class.\nlegion.add_skill(\"Duel\", 150)\nlegion.use_skill(\"Duel\")\n\n\n# correct\nclass Skill:\n    def use(self):\n        raise NotImplementedError(\"This method should be overridden by subclasses\")\n\nclass OverwhelmingOdds(Skill):\n    def use(self, hero_name):\n        print(f\"{hero_name} uses Overwhelming Odds dealing 100 damage\")\n\nclass PressTheAttack(Skill):\n    def use(self, hero_name):\n        print(f\"{hero_name} uses Press the Attack healing 50 health\")\n\nclass Duel(Skill):\n    def use(self, hero_name):\n        print(f\"{hero_name} uses Duel dealing 150 damage\")\n\nclass LegionCommander:\n    def __init__(self, name):\n        self.name = name\n        self.skills = {}\n\n    def add_skill(self, skill_name, skill):\n        self.skills[skill_name] = skill\n\n    def use_skill(self, skill_name):\n        skill = self.skills.get(skill_name)\n        if skill:\n            skill.use(self.name)\n        else:\n            print(f\"{self.name} does not have the skill {skill_name}\")\n\nprint(\"----------------------------------------------------------------\")\nlegion = LegionCommander(\"Legion Commander\")\nlegion.add_skill(\"Overwhelming Odds\", OverwhelmingOdds())\nlegion.add_skill(\"Press the Attack\", PressTheAttack())\nlegion.use_skill(\"Overwhelming Odds\")\nlegion.use_skill(\"Duel\")\n\n# We can add new skills without modifying the LegionCommander class\nlegion.add_skill(\"Duel\", Duel())\nlegion.use_skill(\"Duel\")\n\n\n# -- extra challenge\nimport math\n\nclass Operation:\n    def calculate(self, a, b):\n        raise NotImplementedError(\"Subclasses should implement this method\")\n\nclass Addition(Operation):\n    def calculate(self, a, b):\n        return a + b\n\nclass Subtraction(Operation):\n    def calculate(self, a, b):\n        return a - b\n\nclass Multiplication(Operation):\n    def calculate(self, a, b):\n        return a * b\n\nclass Division(Operation):\n    def calculate(self, a, b):\n        if b == 0:\n            raise ValueError(\"Division by zero is not allowed\")\n        return a / b\n\nclass Power(Operation):\n    def calculate(self, a, b):\n        return math.pow(a, b)\n\nclass Calculator:\n    def __init__(self):\n        self.operations = {}\n\n    def add_operation(self, operator, operation):\n        self.operations[operator] = operation\n\n    def calculate(self, operator, a, b):\n        if operator in self.operations:\n            return self.operations[operator].calculate(a, b)\n        else:\n            raise ValueError(f\"Operation '{operator}' not supported\")\n\nprint(\"----------------------------------------------------------------\")\ncalculator = Calculator()\n\n# add basic operations\ncalculator.add_operation('+', Addition())\ncalculator.add_operation('-', Subtraction())\ncalculator.add_operation('*', Multiplication())\ncalculator.add_operation('/', Division())\n\na, b = 10, 5\nprint(f\"Addition: {a} + {b} = {calculator.calculate('+', a, b)}\")\nprint(f\"Subtraction: {a} - {b} = {calculator.calculate('-', a, b)}\")\nprint(f\"Multiplication: {a} * {b} = {calculator.calculate('*', a, b)}\")\nprint(f\"Division: {a} / {b} = {calculator.calculate('/', a, b)}\")\n\n# add new operation - power\ncalculator.add_operation('^', Power())\nprint(f\"Power: {a} ^ {b} = {calculator.calculate('^', a, b)}\")\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/rantamhack.py",
    "content": "\n\nprint(\"\\n\\n=======================================EJERCICIO=======================================\\n\\n\")\n\n\"\"\"\n * EJERCICIO:\n * Explora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n\"\"\"\n\nfrom abc import ABC, abstractmethod\n\nclass Area(ABC):\n    def __init__(self, base: float, height: float):\n        self.base = base\n        self.height = height\n        \n    @abstractmethod\n    def calculate_area(self):\n        pass\n        \nclass Triangle(Area):\n        \n    def calculate_area(self): \n        result = (self.base * self.height) / 2\n        return result\n    \nclass Square(Area):\n    def __init__(self, side):\n        self.side = side\n        super().__init__(side, side)\n        \n    def calculate_area(self):\n        result = self.side ** 2\n        return result\n    \n\"\"\"    \n * SI AHORA QUISIERAMOS AÑADIR MAS POLIGONOS A LOS QUE CALCULAR EL AREA NO TENDRIAMOS QUE TOCAR NADA DE LO ESCRITO\n * SOLAMENTE AÑADIR LAS NUEVAS SUBCLASES COMO POR EJEMPLO LA SUBCLASE \"RECTANGULO\"\n\"\"\" \n\nclass Rectangle(Area):\n    \n    def calculate_area(self):\n        result = self.base * self.height\n        return result\n    \n\nmy_triangle = Triangle(3 ,5)\nprint(f\"\\n[+] El area del triangulo es: {my_triangle.calculate_area()}\")\n\nmy_square = Square(9)\nprint(f\"\\n[+] El area del triangulo es: {my_square.calculate_area()}\")\n\nmy_rectangle = Rectangle(7, 5)\nprint(f\"\\n[+] El area del triangulo es: {my_rectangle.calculate_area()}\\n\")\n\nprint(\"\\n\\n=======================================DIFICULTAD EXTRA=======================================\\n\\n\")\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla una calculadora que necesita realizar diversas operaciones matemÃ¡ticas. \n * Requisitos:\n * - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n * Instrucciones:\n * 1. Implementa las operaciones de suma, resta, multiplicacion y division.\n * 2. Comprueba que el sistema funciona.\n * 3. Agrega una quinta operacion para calcular potencias.\n * 4. Comprueba que se cumple el OCP.\n\"\"\"\n\nclass Calculator(ABC):\n    def __init__(self, num1: float, num2: float):\n        self.num1 = num1\n        self.num2 = num2\n        \n    @abstractmethod\n    def solution(self):\n        pass\n    \nclass Add(Calculator):\n    \n    def solution(self):        \n        return (self.num1 + self.num2)\n        \n    \nclass Subtract(Calculator):\n    \n    def solution(self):\n        return (self.num1 - self.num2)\n        \n        \n        \nclass Multiply(Calculator):\n    \n    def solution(self):\n        return  self.num1 * self.num2\n        \n        \nclass Division(Calculator):\n    \n    def solution(self):\n        return self.num1 / self.num2\n        \n        \n    \nmy_add = Add(5.2, 7)\nprint(f\"\\n[+] El resultado de la suma es: {my_add.solution()}\")\n\nmy_subtract = Subtract(12, 7)\nprint(f\"\\n[+] El resultado de la resta es: {my_subtract.solution()}\")\n\nmy_multiply = Multiply(9, 7)\nprint(f\"\\n[+] El resultado de la multiplicacion es: {my_multiply.solution()}\")\n\nmy_division = Division(12, 2)\nprint(f\"\\n[+] El resultado de la division es: {my_division.solution()}\")\n\n\n# Ahora vamos a añadir la operacion que permite hacer potencias\n\nclass Pow(Calculator):\n    \n    def solution(self):\n        return pow(self.num1, self.num2)\n    \nmy_pow = Pow(5, 3)\nprint(f\"\\n[+] El resultado de la potencia es: {my_pow.solution()}\\n\")\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/raulG91.py",
    "content": "\nfrom abc import ABC, abstractmethod\n#Bad example: Open for mofification but not closed\nclass Character:\n    def __init__(self,type):\n        self.type = type\n    def attack(self):\n        if self.type == \"Fire\":\n            print(\"Fire attack\")\n        elif self.type == \"Water\":\n            print(\"Water attack\")\n        elif self.type == \"Electricity\":\n            print(\"Electrical attack\")\n\n#Correct example\n\nclass Character2(ABC):\n    def __init__(self,type):\n        self.type = type\n    @abstractmethod\n    def attack(self):\n        pass\n\nclass FireCharacter(Character2):\n    def attack(self):\n        print(\"Fire attack\")\n\nclass WaterCharacter(Character2):\n    def attack(self):\n        print(\"Water attack\")\n\nclass ElectricityCharacter(Character2):\n    def attack(self):\n        print(\"Electrical attack\")\n\n#Extra\n\nclass Operation(ABC):\n    @abstractmethod\n    def operate(self,a,b):\n        pass\n\nclass Sum(Operation):\n    def operate(self, a, b):\n        return a +b\nclass Diff(Operation):\n    def operate(self, a, b):\n        return a - b\nclass Multiply(Operation):\n    def operate(self, a, b):\n        return a*b\nclass Division(Operation):\n    def operate(self, a, b):\n        if not b==0:\n            return a/b\n\nclass Calculator:\n    def __init__(self) -> None:\n        self.operations = []\n\n    def add_operation(self,name,op):\n        self.operations.append((name,op))\n    def operate(self,operation,a,b):\n        element = list(filter(lambda x: x[0]==operation,self.operations))\n        if element:\n            return element[0][1].operate(a,b)    \ncalc = Calculator()\ncalc.add_operation(\"Sum\",Sum())\ncalc.add_operation(\"Diff\",Diff())\ncalc.add_operation(\"Multiply\",Multiply())\ncalc.add_operation(\"Division\",Division())\nprint(\"Sum\",calc.operate(\"Sum\",3,5))\nprint(\"Diff\",calc.operate(\"Diff\",4,3))\nprint(\"Multiply\",calc.operate(\"Multiply\",4,3))\nprint(\"Division\",calc.operate(\"Division\",4,2))\n\nclass Pow(Operation):\n    def operate(self, a, b):\n        return a**b\n\ncalc.add_operation(\"Pow\",Pow())\nprint(\"Pow\",calc.operate(\"Pow\",2,2))    "
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/raynerpv2022.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * Explora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\" \n#  * y crea un ejemplo simple donde se muestre su funcionamiento\n#  * de forma correcta e incorrecta.\n#  *\n\n\n# Incorrect\nclass Shape:\n    def __init__(self,s: str,a,b : int) -> None:\n        self.shape = s\n        self.a = a\n        self.b = b\n        self.area = 0\n        \n\n    def Area(self):\n        if self.shape == \"r\":\n            self.area = self.a*self.b\n        if self.shape == \"q\":\n            self.area = self.a**2\n        if self.shape == \"t\":\n            self.area = self.a*self.b/2\n    \n    def result(self):\n        if self.area ==0:\n            print(\"there is not Area calculated\")\n            return\n        print(f\" Area is {self.area}\")\n\nprint(\"incorrect\")\nshape = [Shape(\"r\",12,23),Shape(\"t\", 34,7),Shape(\"q\",12,12)]\n \n\nfor i in shape:\n    i.Area()\n    i.result()\n\n# correct\n\nfrom abc import ABC, abstractmethod\nfrom functools import reduce\n\nclass Shape(ABC):\n    def __init__(self,name: str) -> None:\n        self.name = name\n        self.area = 0\n        super().__init__()\n    \n    @abstractmethod\n    def Area(self):\n        \"\"\"Método abstracto que calcula el área de la figura. Obliga a redefinirlo\"\"\"\n        pass\n\n    def Result(self):\n        print(f\"Shape {self.name} with Area   {self.area}\")\n     \n\nclass square(Shape):\n    def __init__(self, a : int) -> None:\n        self.a = a\n        super().__init__(\"square\")\n    \n    def Area(self):\n        self.area = self.a **2\n         \n    \nclass triangle(Shape):\n    def __init__(self, a,b :int) -> None:\n        self.a = a\n        self.b = b\n        super().__init__(\"triangle\")\n\n    def Area(self):\n        self.area = self.a*self.b/2\n         \n    \nclass rectangle(Shape):\n    def __init__(self, a,b: int) -> None:\n        super().__init__(\"Rectangle\")\n        self.a = a\n        self.b = b\n        \n\n    def Area(self):\n        self.area = self.a*self.b\n         \n        \nprint(\"Correct\")\nshape = [triangle(12,13),square(12),triangle(34,55),square(99), rectangle(12,13)]\nfor i in shape:\n    i.Area()\n    i.Result()\n\n\n    # Extra\n\n    #  * DIFICULTAD EXTRA (opcional):\n#  * Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas. \n#  * Requisitos:\n#  * - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n#  * Instrucciones:\n#  * 1. Implementa las operaciones de suma, resta, multiplicación y división.\n#  * 2. Comprueba que el sistema funciona.\n#  * 3. Agrega una quinta operación para calcular potencias.\n#  * 4. Comprueba que se cumple el OCP.\n#  */\n\n\n# version sencilla\n\nclass Calculator(ABC):\n    @abstractmethod\n    def operator(self, *a ):\n        pass\n\nclass Sum(Calculator):\n    def operator(self, *a):\n        return sum(a)\n\nclass Rest(Calculator):\n    def operator(self, *a):\n        return reduce(lambda x,y:x-y,a)\n    \nclass Mult(Calculator):\n    def operator(self, *a):\n        return  reduce(lambda x,y:x*y,a)\n    \nclass Div(Calculator): \n    # no DIV 0 checked\n    def operator(self, *a):\n        return reduce(lambda x,y:x/y,a)\nclass Power(Calculator):\n    def operator(self, *a):\n        return reduce(lambda x,y:x**y,a)\n\nSUMA1 = print(Sum.operator(12,13,12,3,4))\nRESTA1 = print(Rest.operator(1,2,3,4,5,6,7,8,9))\nMULT1 = print(Mult.operator(1,2,3,4,5,6,7,8,9))\nDIV1 = print(Div.operator(1,2,3,4,5,6,7,8,9))\nPOWER1 = print(Power.operator(1,2,3 ))\n\n\n# Version complicada\n# clase base para calculadora\nclass Calculator(ABC) :\n    def __init__(self,symbol: str,n1,n2: float) -> None:\n        self.n1 = n1 \n        self.n2 = n2\n        self.result = 0\n        self.symbol = symbol\n        \n        super().__init__()\n    \n    @abstractmethod\n    def Execute(self):\n        pass\n     \n# clase para operacion suma, solo executa la suma\nclass Sum(Calculator):\n    def __init__(self, n1 = None, n2 = None) -> None:\n        super().__init__(\"+\",n1,n2)\n        \n    def Execute(self):\n        self.result = self.n1+self.n2\n    \n# # clase similar a suma\nclass Rest(Calculator):\n    def __init__(self, n1 = None, n2 = None) -> None:\n        super().__init__(\"-\", n1, n2)\n\n    def Execute(self):\n        self.result = self.n1-self.n2\n    \nclass Mult(Calculator):\n    def __init__(self, n1 = None, n2 = None) -> None:\n        super().__init__(\"*\", n1, n2)\n\n    def Execute(self):\n        self.result = self.n1*self.n2\n\nclass Div(Calculator):\n    def __init__(self, n1 = None, n2 = None) -> None:\n        super().__init__(\"/\", n1, n2)\n\n    def Execute(self):\n        if self.n2 == 0:\n             self.result = None # div por 0 lo pongo None\n        else:\n            self.result = self.n1/self.n2\n\nclass Power(Calculator):\n    def __init__(self, n1 = None, n2 = None) -> None:\n        super().__init__(\"^\", n1, n2)\n\n    def Execute(self):\n            self.result = self.n1**self.n2\n\n\n# clase para imprimir resultados\nclass Result:\n    def Print_result(self, c :Calculator):\n        print(f\" {c.n1} {c.symbol} {c.n2} = {c.result} \")\n\n    def Print_error(self, o: str):\n        print(o)\n\n# clase para validar la entrada  \nclass Validate_Operation:\n    def __init__(self) -> None:\n        self.n1, self.n2,self.op = None,None,None\n  \n    def validate(self,op):\n         match = re.match(r\"(-?\\d+)([+^\\-*/])(-?\\d+)\", op)\n         if match:\n            self.n1 = int(match.group(1))\n            self.op = match.group(2)\n            self.n2 = int(match.group(3))\n             \n    def get_validation(self):\n        return self.n1, self.op, self.n2\n\n# clase para registrar los operadores permitidos\nclass Registry_Operation:\n    def __init__(self) -> None:\n        self.registry = {}\n\n    def add_operation(self, key, value):\n        self.registry[key] = value\n\n    def get_registry(self, key):\n        return self.registry.get(key,None)\n\n\nresult = Result()\nregistry = Registry_Operation()\n\n# Nueva operacion ? adicionar aqui\nregistry.add_operation(\"+\",Sum)\nregistry.add_operation(\"-\",Rest)\nregistry.add_operation(\"*\",Mult)\nregistry.add_operation(\"/\",Div)\nregistry.add_operation(\"^\",Power)\n\nwhile True:\n    print(\"Calculator v1\")\n\n    print(\"calc> \")\n    op = input()\n    if op == \"exit\":\n        break\n    op = op.strip()\n    validate_operation = Validate_Operation()\n    validate_operation.validate(op)\n    n1,op,n2 = validate_operation.get_validation()\n\n    if not op:\n        result.Print_error(\"Error de  sintaxis , debe ser (n1 operador n2) ejemplo 2+4\")\n        continue\n    \n    if   not  registry.get_registry(op):\n        result.Print_error(f\"Error operation {op} not yet allowed\")\n        continue\n\n    operation_class = registry.get_registry(op)\n    actual_operation = operation_class(n1,n2) \n    actual_operation.Execute()\n    \n    result.Print_result(actual_operation)\n\n\n    \n\n    \n    \n   \n\n     \n\n\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/rigo93acosta.py",
    "content": "'''\n * EJERCICIO:\n * Explora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas. \n * Requisitos:\n * - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n * Instrucciones:\n * 1. Implementa las operaciones de suma, resta, multiplicación y división.\n * 2. Comprueba que el sistema funciona.\n * 3. Agrega una quinta operación para calcular potencias.\n * 4. Comprueba que se cumple el OCP.\n */\n'''\n\n'''\nBasic\n'''\n\nclass Form:\n\n    def draw(self):\n        ...\n\nclass Square(Form):\n    def draw(self):\n        print(\"Square\")\n\nclass Circle(Form):\n    def draw(self):\n        print(\"Circle\")\n\nclass Triangle(Form):\n    def draw(self):\n        print(\"Triangle\")\n\n\n'''\nExtra\n'''\n\nfrom abc import ABC, abstractmethod\n\nclass Operation(ABC):\n    @abstractmethod\n    def execute(self, a, b):\n        pass\n\nclass Sum(Operation):\n    def execute(self, a, b):\n        return a + b\n    \nclass Subtraction(Operation):\n    def execute(self, a, b):\n        return a - b\n    \nclass Multiplication(Operation):\n    def execute(self, a, b):\n        return a * b\n    \nclass Division(Operation):\n    def execute(self, a, b):\n        return a / b\n\nclass Power(Operation):\n    def execute(self, a, b):\n        return a ** b\n\nclass Calculator:\n\n    def __init__(self) -> None:\n        self.operations = {}\n\n    def add_operation(self, name, operation):\n        self.operations[name] = operation\n\n    def calculate(self, name, a, b):\n        if name not in self.operations:\n            raise ValueError(f'Operation {name} not found')\n        return self.operations[name].execute(a, b)\n\ncalculator = Calculator()\ncalculator.add_operation('sum', Sum())\ncalculator.add_operation('subtraction', Subtraction())\ncalculator.add_operation('multiplication', Multiplication())\ncalculator.add_operation('division', Division())\ncalculator.add_operation('power', Power())\n\nprint(calculator.calculate('sum', 2, 3))\nprint(calculator.calculate('subtraction', 15, 3))\nprint(calculator.calculate('multiplication', 2, 3))\nprint(calculator.calculate('division', 10, 5))\nprint(calculator.calculate('power', 2, 3))"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/rikmij.py",
    "content": "#Forma incorrecta\nclass Specie:\n\n    def define_specie(self, specie):\n        match specie:\n            case \"Humano\":\n                print(\"Soy un humano\")\n            case \"Perro\":\n                print(\"Soy un perro\")\n            case \"Gato\":\n                print(\"Soy un gato\")\n\nsubject1 = Specie()\nsubject1.define_specie(\"Humano\")\nsubject2 = Specie()\nsubject2.define_specie(\"Perro\")\n\n'''\n    Esta forma es incorrecta para el OCP porque si hay que añadir especies hay que ir retocando la clase,\n    lo que es lo contrario al principio Open/Closed\n'''\n\n#Forma correcta\n\nclass Speciee:\n    def identify_specie(self):\n        pass\n\nclass Human(Speciee):\n    def identify_specie(self):\n        return \"Soy un humano con OCP\"\n\nclass Dog(Speciee):\n    def identify_specie(self):\n        return \"Soy un perro con OCP\"\n\nclass Cat(Speciee):\n    def identify_specie(self):\n        return \"Soy un gato con OCP\"\n\nhuman = Human()\nprint(human.identify_specie())\ndog = Dog()\nprint(dog.identify_specie())\ncat = Cat()\nprint(cat.identify_specie())\n\n'''\n    Esta sí es buena forma de aplicar el OCP, pues enemos la clase base, con las funciones y ya\n    a cada especie le crearíamos su clase con sus atributos y sobreescribiendo los métodos comunes que\n    queramos.\n    Estamos añadiendo funcionalidades sin tener que modificar la clase\n'''\n\nprint(\"\\n\", \"*\"*7, \"EJERCICIO EXTRA\", \"*\"*7)\nclass Calculator:\n    def operation(self):\n        pass\n\nclass Sum(Calculator):\n    def operation(self, num):\n        num2 = int(input(\"Elige un 2º número: \"))\n        return num + num2\n\nclass Subst(Calculator):\n    def operation(self, num):\n        num2 = int(input(\"Elige un 2º número: \"))\n        return num - num2\n\nclass Mult(Calculator):\n    def operation(self, num):\n        num2 = int(input(\"Elige un 2º número: \"))\n        return num * num2\n\nclass Div(Calculator):\n    def operation(self, num):\n        num2 = int(input(\"Elige un 2º número: \"))\n        return num / num2\n\nclass Pow(Calculator):\n    def operation(self, num):\n        num2 = int(input(\"¿A qué potencia quieres elevar? \"))\n        return pow(num, num2)\n\ndef calculator():\n    num1 = int(input(\"Elige un número: \"))\n\n    op = input(\"¿Qué operación quieres realizar?\\n\"+\n            \"Suma(+)\\n\"+\n            \"Resta(-)\\n\"+\n            \"Multiplicar(*)\\n\"+\n            \"División(/)\\n\"+\n            \"Potencia(**)\\n\")\n\n    match op:\n        case \"+\":\n            opt = Sum()\n            print(opt.operation(num1))\n        case \"-\":\n            opt = Subst()\n            print(opt.operation(num1))\n        case \"*\":\n            opt = Mult()\n            print(opt.operation(num1))\n        case \"/\":\n            opt = Div()\n            print(opt.operation(num1))\n        case \"**\":\n            opt = Pow()\n            print(opt.operation(num1))\n\ncalculator()\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/python/santyjl.py",
    "content": "#27 SOLID: PRINCIPIO ABIERTO-CERRADO (OCP)\n\"\"\"\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\"\n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas.\n * Requisitos:\n * - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n * Instrucciones:\n * 1. Implementa las operaciones de suma, resta, multiplicación y división.\n * 2. Comprueba que el sistema funciona.\n * 3. Agrega una quinta operación para calcular potencias.\n * 4. Comprueba que se cumple el OCP.\n */\n\"\"\"\n\nclass Usuario:\n    def __init__(self, nombre, email=None, sms=None):\n        self.nombre = nombre\n        self.email = email\n        self.sms = sms\n\nclass Notificar:\n    def __init__(self, usuario, mensaje):\n        self.usuario = usuario\n        self.mensaje = mensaje\n\n    def notificar(self):\n        raise NotImplementedError(\"Este método debe ser sobrescrito por una subclase.\")\n\nclass NotificarEmail(Notificar):\n    def notificar(self):\n        if self.usuario.email:\n            return f\"Enviamos el mensaje: '{self.mensaje}' por Email a {self.usuario.email}\"\n        else:\n            return \"Este usuario no tiene email registrado.\"\n\nclass NotificarSMS(Notificar):\n    def notificar(self):\n        if self.usuario.sms:\n            return f\"Enviamos el mensaje: '{self.mensaje}' por SMS a {self.usuario.sms}\"\n        else:\n            return \"Este usuario no tiene número de SMS registrado.\"\n\n# Ejemplo de uso:\nusuario_uno = Usuario(\"Santiago\", email=\"santiago@correo.com\")\nusuario_dos = Usuario(\"George\", sms=\"123456789\")\n\nnotificacion_uno = NotificarEmail(usuario_uno, \"Los números amigos no sirven de nada.\")\nnotificacion_dos = NotificarSMS(usuario_dos, \"Enseñame a soldar.\")\n\nprint(notificacion_uno.notificar())  # Correcto, tiene email\nprint(notificacion_dos.notificar())  # Correcto, tiene SMS\n\n# Extra\n\nclass Calculadora:\n    \"\"\"\n    Clase base para operaciones de cálculo.\n    Esta clase debe ser heredada para implementar operaciones específicas.\n    \"\"\"\n\n    def calcular(self, valores: list[float]) -> float:\n        \"\"\"\n        Método que debe ser sobrescrito en las clases derivadas.\n\n        :param valores: Lista de valores a operar.\n        :return: Resultado de la operación.\n        \"\"\"\n        raise NotImplementedError(\"Este método debe ser sobrescrito por una clase derivada.\")\n\nclass Sumar(Calculadora):\n    \"\"\"\n    Clase que implementa la operación de suma.\n    \"\"\"\n\n    def calcular(self, valores: list[float]) -> float:\n\n        return sum(valores)\n\nclass Resta(Calculadora):\n    \"\"\"\n    Clase que implementa la operación de resta.\n    \"\"\"\n\n    def calcular(self, valores: list[float]) -> float:\n\n        resultado = valores[0]\n        for valor in valores[1:]:\n            resultado -= valor\n        return resultado\n\nclass Multiplicar(Calculadora):\n    \"\"\"\n    Clase que implementa la operación de multiplicación.\n    \"\"\"\n\n    def calcular(self, valores: list[float]) -> float:\n\n        resultado = 1\n        for valor in valores:\n            resultado *= valor\n        return resultado\n\nclass Division(Calculadora):\n    \"\"\"\n    Clase que implementa la operación de división.\n    \"\"\"\n\n    def calcular(self, valores: list[float]) -> float:\n\n        resultado = valores[0]\n        for valor in valores[1:]:\n            if valor == 0:\n                raise ZeroDivisionError(\"No se puede dividir por cero.\")\n            resultado /= valor\n        return resultado\n\nclass Potencia(Calculadora):\n    \"\"\"\n    Clase que implementa la operación de potencia.\n    \"\"\"\n\n    def calcular(self, valores: list[float]) -> float:\n\n        resultado = valores[0]\n        for valor in valores[1:]:\n            resultado **= valor\n        return resultado\n\n# Ejemplo de uso\n\nsuma = Sumar()\nresta = Resta()\nmultiplicacion = Multiplicar()\ndivision = Division()\npotencia = Potencia()\n\n# Valores para operar\nvalores = [10, 2, 3]\n\n# Realizar las operaciones y mostrar los resultados\nprint(f\"Suma: {suma.calcular(valores)}\")          # Suma: 15\nprint(f\"Resta: {resta.calcular(valores)}\")        # Resta: 5\nprint(f\"Multiplicación: {multiplicacion.calcular(valores)}\")  # Multiplicación: 60\nprint(f\"División: {division.calcular([100, 2, 5])}\")  # División: 10.0\nprint(f\"Potencia: {potencia.calcular([2, 3, 2])}\")    # Potencia: 64\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/rust/kenysdev.rs",
    "content": "/*\n╔═══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado                ║\n║ GitHub: https://github.com/Kenysdev   ║\n║ 2024 -  Rust                          ║\n╚═══════════════════════════════════════╝\n-----------------------------------------\n* SOLID: PRINCIPIO ABIERTO-CERRADO (OCP)\n-----------------------------------------\n\n- Una entidad de software que está abierta a extensión, pero cerrada a modificación, \n  esto significa que debemos poder extender el comportamiento de una clase sin \n  necesidad de modificar su código fuente original.\n\n_______________\n* EJERCICIO #1:\n* Explora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\" \n* y crea un ejemplo simple donde se muestre su funcionamiento\n* de forma correcta e incorrecta.\n*/\n\n// Trait base\ntrait Product {\n    fn new(name: &str, price: f64) -> Self where Self: Sized;\n    fn name(&self) -> &str;\n    fn price(&self) -> f64;\n    fn apply_discount(&self) -> f64;\n    fn final_price(&self) -> f64 {\n        self.price() - self.apply_discount()\n    }\n}\n\n//____________________________________\n// Estructuras concretas\nstruct ElectronicsProduct {\n    name: String,\n    price: f64,\n}\n\nimpl Product for ElectronicsProduct {\n    fn new(name: &str, price: f64) -> Self {\n        ElectronicsProduct {\n            name: name.to_string(),\n            price,\n        }\n    }\n\n    fn name(&self) -> &str {&self.name}\n\n    fn price(&self) -> f64 {self.price}\n\n    fn apply_discount(&self) -> f64 {\n        self.price * 0.05 // 5% discount\n    }\n}\n\n//____________________________________\nstruct ClothingProduct {\n    name: String,\n    price: f64,\n}\n\nimpl Product for ClothingProduct {\n    fn new(name: &str, price: f64) -> Self {\n        ClothingProduct {\n            name: name.to_string(),\n            price,\n        }\n    }\n\n    fn name(&self) -> &str {&self.name}\n\n    fn price(&self) -> f64 {self.price}\n\n    fn apply_discount(&self) -> f64 {\n        if self.price > 50.0 {\n            10.0\n        } else {\n            0.0\n        }\n    }\n}\n\n/*\n_______________\n* EJERCICIO #2:\n* Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas. \n* Requisitos:\n* - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n* Instrucciones:\n* 1. Implementa las operaciones de suma, resta, multiplicación y división.\n* 2. Comprueba que el sistema funciona.\n* 3. Agrega una quinta operación para calcular potencias.\n* 4. Comprueba que se cumple el OCP.\n*/\n\n// Trait base\ntrait Calculator {\n    fn new(a: f64, b: f64) -> Self where Self: Sized;\n    fn operation_result(&self);\n}\n\n// __________________________________________\n// Estructuras concretas\nstruct Sum { a: f64, b: f64 }\n\nimpl Calculator for Sum {\n    fn new(a: f64, b: f64) -> Sum {Sum { a, b }}\n    \n    fn operation_result(&self) {\n        println!(\"\\nSuma:\");\n        println!(\"{} + {} = {}\", self.a, self.b, self.a + self.b);\n    }\n}\n\n// __________________________________________\nstruct Subtraction { a: f64, b: f64 }\n\nimpl Calculator for Subtraction {\n    fn new(a: f64, b: f64) -> Subtraction {Subtraction { a, b }}\n    \n    fn operation_result(&self) {\n        println!(\"\\nResta:\");\n        println!(\"{} - {} = {}\", self.a, self.b, self.a - self.b);\n    }\n}\n\n// __________________________________________\nstruct Multiplication { a: f64, b: f64 }\n\nimpl Calculator for Multiplication {\n    fn new(a: f64, b: f64) -> Multiplication {Multiplication { a, b }}\n    \n    fn operation_result(&self) {\n        println!(\"\\nMultiplicación:\");\n        println!(\"{} * {} = {}\", self.a, self.b, self.a * self.b);\n    }\n}\n\n// __________________________________________\nstruct Division { a: f64, b: f64 }\n\nimpl Calculator for Division {\n    fn new(a: f64, b: f64) -> Division {Division { a, b }}\n    \n    fn operation_result(&self) {\n        println!(\"\\nDivisión:\");\n        println!(\"{} / {} = {}\", self.a, self.b, self.a / self.b);\n    }\n}\n\n// __________________________________________\nstruct Pow { a: f64, b: f64 }\n\nimpl Calculator for Pow {\n    fn new(a: f64, b: f64) -> Pow {Pow { a, b }}\n    \n    fn operation_result(&self) {\n        println!(\"\\nPotencia:\");\n        println!(\"{} ^ {} = {}\", self.a, self.b, self.a.powf(self.b));\n    }\n}\n\nfn main() {\n    //____________________________________\n    fn process_product<T: Product>(product: T) {\n        println!(\n            \"Producto: {}, Precio final: {}\",\n            product.name(),\n            product.final_price()\n        );\n    }\n\n    process_product(ElectronicsProduct::new(\"Laptop\", 700.0));\n    process_product(ClothingProduct::new(\"Pants\", 55.0));\n\n    // _______________________________________________\n    // exs 2\n\n    Sum::new(2.0, 2.0).operation_result();\n    Subtraction::new(2.0, 2.0).operation_result();\n    Multiplication::new(2.0, 2.0).operation_result();\n    Division::new(2.0, 2.0).operation_result();\n    Pow::new(2.0, 2.0).operation_result();\n\n}\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/sql/Nicojsuarez2.sql",
    "content": "# #27 SOLID: PRINCIPIO ABIERTO-CERRADO (OCP)\n> #### Dificultad: Media | Publicación: 01/07/24 | Corrección: 08/07/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas. \n * Requisitos:\n * - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n * Instrucciones:\n * 1. Implementa las operaciones de suma, resta, multiplicación y división.\n * 2. Comprueba que el sistema funciona.\n * 3. Agrega una quinta operación para calcular potencias.\n * 4. Comprueba que se cumple el OCP.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/swift/blackriper.swift",
    "content": "import Foundation\n\n/*\nOpen Closed Principle\n\nEste principio establece que una entidad de software (clase, módulo, función, etc)\ndebe quedar abierta para su extensión, pero cerrada para su modificación.\n\nCon abierta para su extensión, nos quiere decir que una entidad de software debe tener la capacidad\nde adaptarse a los cambios y nuevas necesidades de una aplicación, pero con la segunda parte de “cerrada\npara su modificación” nos da a entender que la adaptabilidad de la entidad no debe darse\ncomo resultado de la modificación del core de dicha entidad si no como resultado de un diseño\nque facilite la extensión sin modificaciones.\n\n*/\n\n// lo que  no debe de hacerce\nenum DriverDatabase {\n    case sqlite\n    case postgres\n    case mysql\n}\n\nstruct Product {\n    let id:UUID=UUID() \n    let name: String\n    let price: Double\n}\n\n\nfinal class DatabaseService{\n\n   func saveProduct(product: Product, database: DriverDatabase) {\n       switch database {\n       case .sqlite:\n             insertProductinSQLite(product: product)\n       case .postgres:\n             insertProductinPostgres(product: product)\n       case .mysql:\n             insertProductinMySQL(product: product)\n           \n       }\n   }\n\n}\n\nextension DatabaseService {\n    func insertProductinSQLite(product: Product) {\n        print(\"Insert \\(product) in SQLite\")\n    }\n    func insertProductinPostgres(product: Product) {\n        print(\"Insert \\(product) in Postgres\")\n    }\n    func insertProductinMySQL(product: Product) {\n        print(\"Insert \\(product) in MySQL\")\n    }\n}\n\n/* las desventaja es que al  querer hacer un cambio hay que modificar el core de la clase */\n\nlet db = DatabaseService()\ndb.saveProduct(product: Product(name: \"macbook pro\", price: 100.0), database: .sqlite)\n\n\n// aplicando el principio open closed principle esto se puede usar aplicando protocolos, herencia , polimorfismo\n\n// usando herencia creamos nuestra clase padre \nclass DatabaseRepository{\n    func saveProduct(product: Product) {\n        print(\"Insert \\(product) in database\")\n    }\n}\n\n// creamos los diferentes drivers como subclases de la clase padre \nclass MongoDB: DatabaseRepository{\n    override func saveProduct(product: Product) {\n        print(\"Insert product id \\(product.id) in MongoDB\")\n    }\n}\n\nclass RedisDB: DatabaseRepository{\n    override func saveProduct(product: Product) {\n        print(\"Insert product id \\(product.id) in Redis\")\n    }\n}\n\nclass cockroachDB: DatabaseRepository{\n    override func saveProduct(product: Product) {\n        print(\"Insert product id \\(product.id) in cockroachDB\")\n    }\n}\n\n// creamos la clase que implementa la logica \nclass DatabaseServiceOPC {\n        func saveDataInDatabase(product: Product, database: DatabaseRepository) {\n            database.saveProduct(product: product)\n        }\n }\n// utlizaando el principio podemos extender la clase sin modificar su core \nlet dbOPC = DatabaseServiceOPC()\ndbOPC.saveDataInDatabase(product: Product(name: \"macbook pro\", price: 100.0), database: MongoDB())\ndbOPC.saveDataInDatabase(product: Product(name: \"iphone15\", price: 400.00), database: RedisDB())\n\n// ejercicio extra \n\n// implemementar operaciones y manteniendo el principio cerrado  controlado mediante un protocolo\nprotocol Operation{\n    func executeOperation(num1:Int, num2:Int)->Int\n}\n\nstruct Add:Operation{\n        func executeOperation(num1: Int, num2: Int) -> Int {\n           return num1+num2\n        }\n}\n\nstruct Sub:Operation{\n    func executeOperation(num1: Int, num2: Int) -> Int {\n       return num1-num2\n    }\n}\n\nstruct Mul:Operation{\n    func executeOperation(num1: Int, num2: Int) -> Int {\n       return num1*num2\n    }\n}\n\nstruct Div:Operation{\n    func executeOperation(num1: Int, num2: Int) -> Int {\n       return num1/num2\n    }\n}\n\nclass Calculator{\n    func calculate(num1:Int, num2:Int, operation:Operation) -> Int {\n        return operation.executeOperation(num1: num1, num2: num2)\n    }\n}\n\n// primera implementacion \nlet calc = Calculator()\nlet sum = Add()\nlet res = Sub()\nlet mul = Mul()\nlet div = Div()\nprint(\"Sum: \\(calc.calculate(num1: 10, num2: 5, operation: sum))\")\nprint(\"Res: \\(calc.calculate(num1: 10, num2: 5, operation: res))\")\nprint(\"Mult: \\(calc.calculate(num1: 10, num2: 5, operation: mul))\")\nprint(\"Div: \\(calc.calculate(num1: 10, num2: 5, operation: div))\")\n\n// agregando nueva operacion  sin alterar el core de la clase por lo que el principio n se cumple\n\nstruct MathPow:Operation{\n    func executeOperation(num1: Int, num2: Int) -> Int {\n      return Int(pow(Double(num1), Double(num2)))\n      \n    }\n}\n\n// segunda implementacion\nlet powM = MathPow()\nprint(\"Pow: \\(calc.calculate(num1: 2, num2: 4, operation: powM))\")\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/typescript/Sac-Corts.ts",
    "content": "// Wrong way\n// interface Shape {\n//     type: string;\n// }\n\n// class ShapeCalculator {\n//     calculateArea(shape: Shape): number {\n//         if (shape.type === 'circle') {\n//             return Math.PI * Math.pow((shape as Circle).radius, 2);\n//         } else if (shape.type === 'square') {\n//             return Math.pow((shape as Square).side, 2);\n//         } else {\n//             throw new Error('Shape not supported');\n//         }\n//     }\n// }\n\n// const calculator = new ShapeCalculator();\n// console.log(calculator.calculateArea({ type: 'circle', radius: 5 } as Circle));\n// console.log(calculator.calculateArea({ type: 'square', side: 4 } as Square));\n\n// Correct way\nabstract class ShapeBase {\n    abstract calculateArea(): number;\n}\n\nclass Circle extends ShapeBase {\n    radius: number;\n\n    constructor(radius: number) {\n        super();\n        this.radius = radius;\n    }\n\n    calculateArea(): number {\n        return Math.PI * Math.pow(this.radius, 2);\n    }\n}\n\nclass Square extends ShapeBase {\n    side: number;\n\n    constructor(side: number) {\n        super();\n        this.side = side;\n    }\n\n    calculateArea(): number {\n        return Math.pow(this.side, 2);\n    }\n}\n\nfunction printArea(shape: ShapeBase): void {\n    console.log(`Area: ${shape.calculateArea()}`);\n}\n\nconst circle = new Circle(5);\nconst square = new Square(4);\nprintArea(circle);\nprintArea(square);\n\n// ** Extra Exercise ** //\nabstract class Operation {\n    abstract calculate(a: number, b: number): number;\n}\n\nclass Addition extends Operation {\n    calculate(a: number, b: number): number {\n        return a + b;\n    }\n}\n\nclass Subtraction extends Operation {\n    calculate(a: number, b: number): number {\n        return a - b;\n    }\n}\n\nclass Multiplication extends Operation {\n    calculate(a: number, b: number): number {\n        return a * b;\n    }\n}\n\nclass Division extends Operation {\n    calculate(a: number, b: number): number {\n        if (b === 0) throw new Error('Division by zero is not allowed');\n        return a / b;\n    }\n}\n\nclass Pow extends Operation {\n    calculate(a: number, b: number): number {\n        return Math.pow(a, b);\n    }\n}\n\nclass Calculator {\n    private operations: { [key: string]: Operation };\n\n    constructor() {\n        this.operations = {};\n    }\n\n    addOperation(name: string, operation: Operation): void {\n        this.operations[name] = operation;\n    }\n\n    calculate(name: string, a: number, b: number): number {\n        const operation = this.operations[name];\n        if (!operation) throw new Error(`Operation \"${name}\" not supported`);\n        return operation.calculate(a, b);\n    }\n}\n\nconst calculator2 = new Calculator();\ncalculator2.addOperation('addition', new Addition());\ncalculator2.addOperation('subtraction', new Subtraction());\ncalculator2.addOperation('multiplication', new Multiplication());\ncalculator2.addOperation('division', new Division());\ncalculator2.addOperation('pow', new Pow());\n\nconsole.log(calculator2.calculate('addition', 2, 10));\nconsole.log(calculator2.calculate('subtraction', 2, 10));\nconsole.log(calculator2.calculate('multiplication', 2, 10));\nconsole.log(calculator2.calculate('division', 10, 5));\nconsole.log(calculator2.calculate('pow', 10, 2));\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/typescript/duendeintemporal.ts",
    "content": "//#27 - { retosparaprogramadores } Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\n\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\"\n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas.\n * Requisitos:\n * - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n * Instrucciones:\n * 1. Implementa las operaciones de suma, resta, multiplicación y división.\n * 2. Comprueba que el sistema funciona.\n * 3. Agrega una quinta operación para calcular potencias.\n * 4. Comprueba que se cumple el OCP.\n */\n\n// https://en.wikipedia.org/wiki/Open%E2%80%93closed_principle\n/* In object-oriented programming, the open–closed principle (OCP) states \"software entities (classes,\n modules, functions, etc.) should be open for extension, but closed for modification\"; that is, such \n an entity can allow its behaviour to be extended without modifying its source code.\n\nThe name open–closed principle has been used in two ways. Both ways use generalizations (for instance,\n inheritance or delegate functions) to resolve the apparent dilemma, but the goals, techniques, and\n  results are different. */\n\nlet log = console.log;\n\n// Check if running in a browser environment\nconst isBrowser = typeof window !== 'undefined';\n\n// Conditional check for browser environment\nif (isBrowser) {\n    window.addEventListener('load', () => {\n        const body: HTMLBodyElement | null = document.querySelector('body');\n        const title = document.createElement('h1');\n\n        body?.style.setProperty('background', '#000');\n        body?.style.setProperty('text-align', 'center');\n\n        title.textContent = 'Retosparaprogramadores #27.';\n        title.style.setProperty('font-size', '3.5vmax');\n        title.style.setProperty('color', '#fff');\n        title.style.setProperty('line-height', '100vh');\n\n        body?.appendChild(title);\n\n        setTimeout(() => {\n            alert('Retosparaprogramadores #27. Please open the Browser Developer Tools.');\n        }, 2000);\n        log('Retosparaprogramadores #27');\n    });\n} else {\n    log('This code is designed to run in a browser environment. Skipping window-related code.');\n    log('Retosparaprogramadores #27');\n}\n\n\n// Base Operation class\nabstract class Operation {\n    abstract execute(a: number, b: number): number;\n}\n\n// Concrete operations\nclass Addition extends Operation {\n    execute(a: number, b: number): number {\n        return a + b;\n    }\n}\n\nclass Subtraction extends Operation {\n    execute(a: number, b: number): number {\n        return a - b;\n    }\n}\n\nclass Multiplication extends Operation {\n    execute(a: number, b: number): number {\n        return a * b;\n    }\n}\n\nclass Division extends Operation {\n    execute(a: number, b: number): number {\n        if (b === 0) throw new Error('Division by zero');\n        return a / b;\n    }\n}\n\n// Custom operation for dynamically added operations\nclass CustomOperation extends Operation {\n    private action: (a: number, b: number) => number;\n\n    constructor(action: string) {\n        super();\n        // Use a safe function constructor to evaluate the action\n        this.action = new Function('a', 'b', `return ${action};`) as (a: number, b: number) => number;\n    }\n\n    execute(a: number, b: number): number {\n        return this.action(a, b);\n    }\n}\n\n// Calculator class\nclass Calculator {\n    private operations: { [key: string]: Operation } = {};\n\n    addOperation(name: string, operation: Operation) {\n        this.operations[name] = operation;\n    }\n\n    calculate(operationName: string, a: number, b: number): number {\n        const operation = this.operations[operationName];\n        if (!operation) {\n            throw new Error('Operation not supported');\n        }\n        return operation.execute(a, b);\n    }\n\n    // Browser-specific method to add a button for the operation\n    addButton(name: string, sign: string) {\n        if (!isBrowser) return; // Only run in the browser\n\n        const buttonBox = document.getElementById('button_box');\n        if (!buttonBox) return;\n\n        const button = document.createElement('button');\n        button.innerText = sign;\n        button.className = 'button';\n        button.onclick = () => this.handleButtonClick(name);\n        button.title = name;\n        buttonBox.appendChild(button);\n    }\n\n    // Browser-specific method to handle button clicks\n    handleButtonClick(operationName: string) {\n        const a = parseFloat(prompt(\"Enter first number:\") || \"0\");\n        const b = parseFloat(prompt(\"Enter second number:\") || \"0\");\n        const result = this.calculate(operationName, a, b);\n        const display = document.getElementById('display') as HTMLInputElement;\n        if (display) {\n            display.value = result.toString();\n        }\n    }\n}\n\n// Browser-specific UI logic\nif (isBrowser) {\n    const calculator = new Calculator();\n    calculator.addOperation('add', new Addition());\n    calculator.addOperation('subtract', new Subtraction());\n    calculator.addOperation('multiply', new Multiplication());\n    calculator.addOperation('divide', new Division());\n\n    // Create the calculator UI\n    const { display, buttonBox, addOperationButton, operationNameInput, operationActionInput, operationSignInput } = createCalculator();\n\n    // Add buttons for the default operations\n    calculator.addButton('add', '+');\n    calculator.addButton('subtract', '-');\n    calculator.addButton('multiply', '*');\n    calculator.addButton('divide', '/');\n\n    // Handle adding new operations\n    addOperationButton.onclick = function () {\n        const name = operationNameInput.value;\n        const action = operationActionInput.value;\n        const sign = operationSignInput.value;\n\n        if (!name || !action || !sign) {\n            alert('You have to fill all the fields: name, operation, and sign!');\n            return;\n        }\n\n        // Add the new operation\n        calculator.addOperation(name, new CustomOperation(action));\n        calculator.addButton(name, sign);\n\n        // Clear input fields\n        operationNameInput.value = '';\n        operationActionInput.value = '';\n        operationSignInput.value = '';\n    };\n}\n\n// Node.js specific logic\nif (!isBrowser) {\n    const readline = require('readline');\n    const rl = readline.createInterface({\n        input: process.stdin,\n        output: process.stdout\n    });\n\n    const calculator = new Calculator();\n    calculator.addOperation('add', new Addition());\n    calculator.addOperation('subtract', new Subtraction());\n    calculator.addOperation('multiply', new Multiplication());\n    calculator.addOperation('divide', new Division());\n\n    function promptUser() {\n        rl.question('Enter operation (add, subtract, multiply, divide, or \"add-operation\" to add a new operation): ', (operation: string) => {\n            if (operation === 'exit') {\n                rl.close();\n                return;\n            }\n\n            if (operation === 'add-operation') {\n                rl.question('Enter operation name: ', (name: string) => {\n                    rl.question('Enter operation action (e.g., a + b): ', (action: string) => {\n                        rl.question('Enter operation sign: ', (sign: string) => {\n                            calculator.addOperation(name, new CustomOperation(action));\n                            console.log(`Operation \"${name}\" added successfully!`);\n                            promptUser(); // Prompt again for the next operation\n                        });\n                    });\n                });\n            } else {\n                rl.question('Enter first number: ', (firstNum: string) => {\n                    rl.question('Enter second number: ', (secondNum: string) => {\n                        const a = parseFloat(firstNum);\n                        const b = parseFloat(secondNum);\n                        try {\n                            const result = calculator.calculate(operation, a, b);\n                            console.log(`Result: ${result}`);\n                        } catch (error) {\n                            if (error instanceof Error) {\n                                console.error(error.message);\n                            } else {\n                                console.error('An unknown error occurred');\n                            }\n                        }\n                        promptUser(); // Prompt again for the next operation\n                    });\n                });\n            }\n        });\n    }\n\n    promptUser();\n}\n\n// Factory function to create calculator UI in the browser\nfunction createCalculator() {\n    if (!isBrowser) {\n        throw new Error(\"This function can only be run in a browser environment.\");\n    }\n\n    const calcWrapper = document.createElement('div');\n    calcWrapper.id = 'calc_wrapper';\n    document.body.appendChild(calcWrapper);\n\n    const display = document.createElement('input');\n    display.type = 'text';\n    display.id = 'display';\n    display.disabled = true;\n    calcWrapper.appendChild(display);\n\n    const buttonBox = document.createElement('div');\n    buttonBox.id = 'button_box';\n    calcWrapper.appendChild(buttonBox);\n\n    const addOperationSection = document.createElement('div');\n    const operationNameInput = document.createElement('input');\n    operationNameInput.placeholder = 'Operation Name';\n    const operationActionInput = document.createElement('input');\n    operationActionInput.placeholder = 'Operation Action (e.g., a + b)';\n    const operationSignInput = document.createElement('input');\n    operationSignInput.placeholder = 'Operation Sign';\n    const addOperationButton = document.createElement('button');\n    addOperationButton.innerText = 'Add Operation';\n\n    addOperationSection.appendChild(operationNameInput);\n    addOperationSection.appendChild(operationActionInput);\n    addOperationSection.appendChild(operationSignInput);\n    addOperationSection.appendChild(addOperationButton);\n    calcWrapper.appendChild(addOperationSection);\n\n    const style = document.createElement('style');\n    style.innerHTML = `\n        body {\n            text-align: center;\n            background: #070707;\n        }\n        #calc_wrapper {\n            position: relative;\n            top: 50%;\n            left: 50%;\n            transform: translate(-50%, -20%);\n            background: rgba(0,0,0,0.2);\n            width: 40vw;\n            min-height: 200px;\n            display: flex;\n            flex-direction: column;\n            justify-content: center;\n            align-items: center;\n            padding: 10px;\n            border: 1px solid yellow;\n            border-radius: 15px;\n        }\n        #display {\n            background: #c7c7c7;\n            width: 38vw;\n            height: 18px;\n            border: 1px solid #fff;\n            border-radius: 5px;\n            padding-left: 10px;\n            margin-bottom: 5px;\n        }\n        #button_box {\n            width: 38vw;\n            min-height: 180px;\n            display: flex;\n            flex-flow: row wrap;\n            justify-content: flex-start;\n            align-items: flex-start;\n            padding: 2px 5px;\n            border: 1px solid #fff;\n            border-radius: 5px; \n            margin-bottom: 5px;       \n        }\n        .button {\n            flex: 1 1 20%;\n            display: flex;\n            justify-content: center;\n            align-items: center;\n            padding: 5px;\n            border: 1px solid #fff;\n            border-radius: 2px;        \n        }\n    `;\n    document.head.appendChild(style);\n\n    return { display, buttonBox, addOperationButton, operationNameInput, operationActionInput, operationSignInput };\n}"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/typescript/eulogioep.ts",
    "content": "/*\n * PRINCIPIO ABIERTO-CERRADO (OCP)\n * \n * El principio establece que las entidades de software (clases, módulos, funciones, etc.) \n * deberían estar:\n * - ABIERTAS para la extensión: Podemos agregar nuevo comportamiento\n * - CERRADAS para la modificación: No debemos modificar el código existente\n * \n * Beneficios:\n * 1. Código más mantenible y escalable\n * 2. Reduce el riesgo de bugs en código existente\n * 3. Facilita la adición de nuevas funcionalidades\n */\n\n// EJEMPLO INCORRECTO (Violando OCP)\n// ❌ Cada vez que queremos agregar una nueva operación, debemos modificar la clase existente\nclass BadCalculator {\n    calculate(a: number, b: number, operation: string): number {\n        switch (operation) {\n            case 'sum':\n                return a + b;\n            case 'subtract':\n                return a - b;\n            case 'multiply':\n                return a * b;\n            case 'divide':\n                return a / b;\n            // Si queremos agregar una nueva operación, debemos modificar esta clase\n            // violando el principio OCP\n            default:\n                throw new Error('Operación no soportada');\n        }\n    }\n}\n\n// EJEMPLO CORRECTO (Siguiendo OCP)\n// Definimos una interfaz para las operaciones\ninterface Operation {\n    execute(a: number, b: number): number;\n    getSymbol(): string;\n}\n\n// Implementamos cada operación como una clase separada\nclass Addition implements Operation {\n    execute(a: number, b: number): number {\n        return a + b;\n    }\n    getSymbol(): string {\n        return '+';\n    }\n}\n\nclass Subtraction implements Operation {\n    execute(a: number, b: number): number {\n        return a - b;\n    }\n    getSymbol(): string {\n        return '-';\n    }\n}\n\nclass Multiplication implements Operation {\n    execute(a: number, b: number): number {\n        return a * b;\n    }\n    getSymbol(): string {\n        return '*';\n    }\n}\n\nclass Division implements Operation {\n    execute(a: number, b: number): number {\n        if (b === 0) throw new Error('No se puede dividir por cero');\n        return a / b;\n    }\n    getSymbol(): string {\n        return '/';\n    }\n}\n\n// Podemos agregar nuevas operaciones sin modificar el código existente\nclass Power implements Operation {\n    execute(a: number, b: number): number {\n        return Math.pow(a, b);\n    }\n    getSymbol(): string {\n        return '^';\n    }\n}\n\n// La calculadora que cumple con OCP\nclass Calculator {\n    private operations: Map<string, Operation>;\n\n    constructor() {\n        this.operations = new Map();\n    }\n\n    // Método para registrar nuevas operaciones\n    registerOperation(operation: Operation): void {\n        this.operations.set(operation.getSymbol(), operation);\n    }\n\n    // Método para realizar cálculos\n    calculate(a: number, b: number, symbol: string): number {\n        const operation = this.operations.get(symbol);\n        if (!operation) {\n            throw new Error(`Operación ${symbol} no soportada`);\n        }\n        return operation.execute(a, b);\n    }\n}\n\n// Ejemplo de uso\nfunction main() {\n    // Creamos una instancia de la calculadora\n    const calculator = new Calculator();\n\n    // Registramos las operaciones básicas\n    calculator.registerOperation(new Addition());\n    calculator.registerOperation(new Subtraction());\n    calculator.registerOperation(new Multiplication());\n    calculator.registerOperation(new Division());\n\n    // Probamos las operaciones básicas\n    console.log('2 + 3 =', calculator.calculate(2, 3, '+'));\n    console.log('5 - 2 =', calculator.calculate(5, 2, '-'));\n    console.log('4 * 3 =', calculator.calculate(4, 3, '*'));\n    console.log('8 / 2 =', calculator.calculate(8, 2, '/'));\n\n    // Agregamos una nueva operación (potencia) sin modificar el código existente\n    calculator.registerOperation(new Power());\n    \n    // Probamos la nueva operación\n    console.log('2 ^ 3 =', calculator.calculate(2, 3, '^'));\n}\n\n// Ejecutamos el programa\nmain();\n\n/*\n * EXPLICACIÓN DE POR QUÉ ESTE DISEÑO CUMPLE CON OCP:\n * \n * 1. ABIERTO PARA EXTENSIÓN:\n *    - Podemos agregar nuevas operaciones creando nuevas clases que implementen la interfaz Operation\n *    - No necesitamos modificar ninguna clase existente\n *    - Cada operación está encapsulada en su propia clase\n * \n * 2. CERRADO PARA MODIFICACIÓN:\n *    - La clase Calculator no necesita ser modificada para agregar nuevas operaciones\n *    - El código existente permanece intacto cuando agregamos nuevas funcionalidades\n *    - La interfaz Operation define un contrato claro que no cambia\n * \n * 3. VENTAJAS DE ESTE DISEÑO:\n *    - Fácil de mantener y extender\n *    - Cada operación está aislada y puede ser probada independientemente\n *    - Reduce el acoplamiento entre componentes\n *    - Facilita la adición de nuevas operaciones sin riesgo de afectar las existentes\n */"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/typescript/hozlucas28.ts",
    "content": "/*\n    Open-Close Principle (OCP)...\n*/\n\nconsole.log('Open-Close Principle (OCP)...')\n\nconsole.log('\\nBad implementation of Open-Close Principle (OCP)...')\n\ninterface IBadCircle {\n    radius: number\n}\n\nclass BadCircle implements IBadCircle {\n    public radius: number\n\n    public constructor({radius}: {radius: number}) {\n        this.radius = radius\n    }\n}\n\ninterface IBadRectangle {\n    height: number\n    width: number\n}\n\nclass BadRectangle implements IBadRectangle {\n    public height: number\n    public width: number\n\n    public constructor({height, width}: {height: number; width: number}) {\n        this.height = height\n        this.width = width\n    }\n}\n\ninterface IBadShapeCalculator {\n    getArea(shape: BadCircle | BadRectangle): number\n}\n\nclass BadShapeCalculator implements IBadShapeCalculator {\n    public constructor() {}\n\n    public getArea(shape: BadCircle | BadRectangle): number {\n        if (shape instanceof BadCircle) {\n            return Math.PI * Math.pow(shape.radius, 2)\n        } else if (shape instanceof BadRectangle) {\n            return shape.height * shape.width\n        } else {\n            return -1\n        }\n    }\n}\n\nconsole.log(`\\n\\`\\`\\`\\ninterface IBadCircle {\n    radius: number\n}\n\nclass BadCircle implements IBadCircle {\n    public radius: number\n\n    public constructor({radius}: {radius: number}) {\n        this.radius = radius\n    }\n}\n\ninterface IBadRectangle {\n    height: number\n    width: number\n}\n\nclass BadRectangle implements IBadRectangle {\n    public height: number\n    public width: number\n\n    public constructor({height, width}: {height: number; width: number}) {\n        this.height = height\n        this.width = width\n    }\n}\n\ninterface IBadShapeCalculator {\n    getArea(shape: BadCircle | BadRectangle): number\n}\n\nclass BadShapeCalculator implements IBadShapeCalculator {\n    public constructor() {}\n\n    public getArea(shape: BadCircle | BadRectangle): number {\n        if (shape instanceof BadCircle) {\n            return Math.PI * Math.pow(shape.radius, 2)\n        } else if (shape instanceof BadRectangle) {\n            return shape.height * shape.width\n        } else {\n            return -1\n        }\n    }\n}\\n\\`\\`\\``)\n\nconsole.log(\n    '\\nThis is a bad implementation of Open-Close Principle (OCP),\\n' +\n        'because the method \"getArea\" of class \"BadShapeCalculator\" will must change\\n' +\n        'if we have to add more shapes.'\n)\n\nconsole.log('\\nGood implementation of Open-Close Principle (OCP)...')\n\ninterface Shape {\n    getArea(): number\n}\n\ninterface IGoodCircle extends Shape {\n    radius: number\n}\n\nclass GoodCircle implements IGoodCircle {\n    public radius: number\n\n    public constructor({radius}: {radius: number}) {\n        this.radius = radius\n    }\n\n    public getArea(): number {\n        return Math.PI * Math.pow(this.radius, 2)\n    }\n}\n\ninterface IGoodRectangle extends Shape {\n    width: number\n    height: number\n}\n\nclass GoodRectangle implements IGoodRectangle {\n    public height: number\n    public width: number\n\n    public constructor({height, width}: {height: number; width: number}) {\n        this.height = height\n        this.width = width\n    }\n\n    public getArea(): number {\n        return this.height * this.width\n    }\n}\n\ninterface IGoodShapeCalculator {\n    getArea(shape: Shape): number\n}\n\nclass GoodShapeCalculator implements IGoodShapeCalculator {\n    public constructor() {}\n\n    public getArea(shape: Shape): number {\n        return shape.getArea()\n    }\n}\n\nconsole.log(`\\n\\`\\`\\`\\ninterface Shape {\n    getArea(): number\n}\n\ninterface IGoodCircle extends Shape {\n    radius: number\n}\n\nclass GoodCircle implements IGoodCircle {\n    public radius: number\n\n    public constructor({radius}: {radius: number}) {\n        this.radius = radius\n    }\n\n    public getArea(): number {\n        return Math.PI * Math.pow(this.radius, 2)\n    }\n}\n\ninterface IGoodRectangle extends Shape {\n    width: number\n    height: number\n}\n\nclass GoodRectangle implements IGoodRectangle {\n    public height: number\n    public width: number\n\n    public constructor({height, width}: {height: number; width: number}) {\n        this.height = height\n        this.width = width\n    }\n\n    public getArea(): number {\n        return this.height * this.width\n    }\n}\n\ninterface IGoodShapeCalculator {\n    getArea(shape: Shape): number\n}\n\nclass GoodShapeCalculator implements IGoodShapeCalculator {\n    public constructor() {}\n\n    public getArea(shape: Shape): number {\n        return shape.getArea()\n    }\n}\\n\\`\\`\\``)\n\nconsole.log(\n    '\\nThis is a good implementation of Open-Close Principle (OCP),\\n' +\n        'because the method \"getArea\" of class \"GoodShapeCalculator\" will must\\n' +\n        'not change if we have to add more shapes. So, \"getArea\" is closed to modification\\n' +\n        'but it is open to extension throw any shape which implements \"Shape\" interface.'\n)\n\nconsole.log(\n    '\\n# ---------------------------------------------------------------------------------- #\\n'\n)\n\n/*\n    Additional challenge...\n*/\n\nconsole.log('Additional challenge...')\n\ninterface MathOperation {\n    execute(a: number, b: number): number\n}\n\nclass AddOperation implements MathOperation {\n    public constructor() {}\n\n    public execute(a: number, b: number): number {\n        return a + b\n    }\n}\n\nclass DivideOperation implements MathOperation {\n    public constructor() {}\n\n    public execute(a: number, b: number): number {\n        if (b === 0) {\n            throw new Error('The second parameter must not be zero')\n        }\n\n        return a / b\n    }\n}\n\nclass MultiplyOperation implements MathOperation {\n    public constructor() {}\n\n    public execute(a: number, b: number): number {\n        return a * b\n    }\n}\n\nclass SubtractOperation implements MathOperation {\n    public constructor() {}\n\n    public execute(a: number, b: number): number {\n        return a - b\n    }\n}\n\ninterface ICalculator {\n    addOperation(name: string, operation: MathOperation): this\n    executeOperation(name: string, a: number, b: number): number\n}\n\nclass Calculator implements ICalculator {\n    private operations: Record<string, MathOperation> = {}\n\n    public addOperation(name: string, operation: MathOperation): this {\n        const operationExist: boolean = !!this.operations[name]\n        if (operationExist) {\n            throw new Error(`The operation with '${name}' name already exist`)\n        }\n\n        this.operations[name] = operation\n        return this\n    }\n\n    public executeOperation(name: string, a: number, b: number): number {\n        const operation: undefined | MathOperation = this.operations[name]\n        if (!operation) {\n            throw new Error(`There is not operation with '${name}' name`)\n        }\n\n        return operation.execute(a, b)\n    }\n}\n\nconsole.log('\\nTesting the OCP system without a pow operation...')\n\nconst calculator: Calculator = new Calculator()\ncalculator.addOperation('add', new AddOperation())\ncalculator.addOperation('divide', new DivideOperation())\ncalculator.addOperation('multiply', new MultiplyOperation())\ncalculator.addOperation('subtract', new SubtractOperation())\n\nlet a: number = 10\nlet b: number = 5\n\nconsole.log(\n    `\\nAdd operation result (${a} + ${b}): ${calculator.executeOperation(\n        'add',\n        a,\n        b\n    )}`\n)\n\na = 10\nb = 2\n\nconsole.log(\n    `Divide operation result (${a} / ${b}): ${calculator.executeOperation(\n        'divide',\n        a,\n        b\n    )}`\n)\n\na = 5\nb = 10\n\nconsole.log(\n    `Multiply operation result (${a} * ${b}): ${calculator.executeOperation(\n        'multiply',\n        a,\n        b\n    )}`\n)\n\na = 6\nb = 6\n\nconsole.log(\n    `Subtract operation result (${a} - ${b}): ${calculator.executeOperation(\n        'subtract',\n        a,\n        b\n    )}`\n)\n\nconsole.log('\\nTesting the OCP system with a pow operation...')\n\nclass PowOperation implements MathOperation {\n    public constructor() {}\n\n    public execute(a: number, b: number): number {\n        return Math.pow(a, b)\n    }\n}\n\ncalculator.addOperation('pow', new PowOperation())\n\na = 2\nb = 10\n\nconsole.log(\n    `\\nPow operation result (${a}^${b}): ${calculator.executeOperation(\n        'pow',\n        a,\n        b\n    )}`\n)\n"
  },
  {
    "path": "Roadmap/27 - SOLID OCP/vb.net/kenysdev.vb",
    "content": "' ╔══════════════════════════════════════╗\n' ║ Autor:  Kenys Alvarado               ║\n' ║ GitHub: https://github.com/Kenysdev  ║\n' ║ 2024 -  VB.NET                       ║\n' ╚══════════════════════════════════════╝\n'-----------------------------------------------\n'* SOLID: PRINCIPIO ABIERTO-CERRADO (OCP)\n'-----------------------------------------------\n'- Una entidad de software que está abierta a extensión, pero cerrada a modificación, \n'  esto significa que debemos poder extender el comportamiento de una clase sin \n'  necesidad de modificar su código fuente original.\n\n'_______________________________________________\n'* EJERCICIO #1\n'* Explora el \"Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)\" \n'* y crea un ejemplo simple donde se muestre su funcionamiento\n'* de forma correcta e incorrecta.\n\nPublic MustInherit Class Product\n    Public Property Name As String\n    Public Property Price As Decimal\n\n    Public Sub New(name As String, price As Decimal)\n        Me.Name = name\n        Me.Price = price\n    End Sub\n\n    Public MustOverride Function ApplyDiscount() As Decimal\n\n    Public Function FinalPrice() As Decimal\n        Return Price - ApplyDiscount()\n    End Function\nEnd Class\n\n' Extensión\nPublic Class ElectronicsProduct\n    Inherits Product\n\n    Public Sub New(name As String, price As Decimal)\n        MyBase.New(name, price)\n    End Sub\n\n    Public Overrides Function ApplyDiscount() As Decimal\n        Return Price * 0.05D ' Descuento del 5%\n    End Function\nEnd Class\n\n' Extensión\nPublic Class ClothingProduct\n    Inherits Product\n\n    Public Sub New(name As String, price As Decimal)\n        MyBase.New(name, price)\n    End Sub\n\n    Public Overrides Function ApplyDiscount() As Decimal\n        If Price > 50 Then\n            Return 10\n        Else\n            Return 0\n        End If\n    End Function\nEnd Class\n\n'__________________________\n'* EJERCICIO #2\n'* Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas. \n'* Requisitos:\n'* - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP.\n'* Instrucciones:\n'* 1. Implementa las operaciones de suma, resta, multiplicación y división.\n'* 2. Comprueba que el sistema funciona.\n'* 3. Agrega una quinta operación para calcular potencias.\n'* 4. Comprueba que se cumple el OCP.\n\nPublic MustInherit Class Calculator\n    Protected a As Double\n    Protected b As Double\n\n    Public Sub New(a As Double, b As Double)\n        Me.a = a\n        Me.b = b\n    End Sub\n\n    Public MustOverride Function MathOperation() As Double\n\n    Public Sub PrintResult()\n        Console.WriteLine($\"Es: {MathOperation()}\")\n    End Sub\nEnd Class\n\nPublic Class Sum\n    Inherits Calculator\n\n    Public Sub New(a As Double, b As Double)\n        MyBase.New(a, b)\n    End Sub\n\n    Public Overrides Function MathOperation() As Double\n        Console.WriteLine($\"Suma de {a} + {b}:\")\n        Return a + b\n    End Function\nEnd Class\n\nPublic Class Subtraction\n    Inherits Calculator\n\n    Public Sub New(a As Double, b As Double)\n        MyBase.New(a, b)\n    End Sub\n\n    Public Overrides Function MathOperation() As Double\n        Console.WriteLine($\"Resta de {a} - {b}:\")\n        Return a - b\n    End Function\nEnd Class\n\nPublic Class Multiplication\n    Inherits Calculator\n\n    Public Sub New(a As Double, b As Double)\n        MyBase.New(a, b)\n    End Sub\n\n    Public Overrides Function MathOperation() As Double\n        Console.WriteLine($\"Multiplicación de {a} * {b}:\")\n        Return a * b\n    End Function\nEnd Class\n\nPublic Class Division\n    Inherits Calculator\n\n    Public Sub New(a As Double, b As Double)\n        MyBase.New(a, b)\n    End Sub\n\n    Public Overrides Function MathOperation() As Double\n        Console.WriteLine($\"División de {a} / {b}:\")\n        If b <> 0 Then\n            Return a / b\n        Else\n            Throw New ArgumentException(\"DivisionErrorbyZero.\")\n        End If\n    End Function\nEnd Class\n\n' Extensión\nPublic Class Pow\n    Inherits Calculator\n\n    Public Sub New(a As Double, b As Double)\n        MyBase.New(a, b)\n    End Sub\n\n    Public Overrides Function MathOperation() As Double\n        Console.WriteLine($\"Potencia de {a} ^ {b}:\")\n        Return Math.Pow(a, b)\n    End Function\nEnd Class\n\n\n'__________________________\nPublic Module Program\n    Public Sub ProcessProduct(product As Product)\n        Console.WriteLine($\"Producto: {product.Name}, Precio final: {product.FinalPrice()}\")\n    End Sub\n\n    Public Sub Main()\n        Dim laptop As New ElectronicsProduct(\"Laptop\", 700)\n        Dim pants As New ClothingProduct(\"Pants\", 55D)\n\n        ProcessProduct(laptop)\n        ProcessProduct(pants)\n\n        '__________________________________________________\n        ' exs 2\n        Dim Sum As New Sum(2, 2)\n        Sum.PrintResult()\n\n        Dim Subtraction As New Subtraction(2, 2)\n        Subtraction.PrintResult()\n\n        Dim Multiplication As New Multiplication(2, 2)\n        Multiplication.PrintResult()\n\n        Dim Division As New Division(2, 2)\n        Division.PrintResult()\n\n        Dim Pow As New Pow(2, 2)\n        Pow.PrintResult()\n\n    End Sub\nEnd Module\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/bash/rantamhack.sh",
    "content": "#!/bin/bash\n\necho -e \"\\n\\n=======================================EJERCICIO=======================================\\n\\n\"\n\n\n# * EJERCICIO:\n# * Explora el \"Principio SOLID de Sustitucion de Liskov (Liskov Substitution Principle, LSP)\" \n# * y crea un ejemplo simple donde se muestre su funcionamiento\n# * de forma correcta e incorrecta.\n\n\n# FORMA INCORRECTA LSP\n\n    \nfunction bird_have_beak(){\n    echo -e \"\\n\\tSoy un $1, soy un pajaro y mi boca es un pico\" \n}      \n\nfunction bird_fly(){\n    echo -e  \"\\n\\tSoy un $1, soy un pajaro y vuelo\\n\"\n}\n\nfunction  hawk_have_beak(){\n    bird_have_beak \"$1\"\n}\n\nfunction hawk_fly(){\n    bird_fly \"$1\"\n}\n\nfunction penguin_have_beak(){\n    bird_have_beak \"$1\"\n}\n\nfunction penguin_fly(){\n    echo -e \"\\n\\tSoy un pingüino, soy un pajaro y nado, no vuelo\\n\"\n    return 1\n}\n\n\necho \"Hawk:\"\nhawk_have_beak halcon\nhawk_fly halcon\n\necho \"Penguin\"\npenguin_have_beak pingüino\npenguin_fly pingüino\n\n\n# FORMA CORRECTA LSP\n\nfunction bird_have_beak(){\n    echo -e \"\\n\\tSoy un $1, soy un pajaro y mi boca es un pico\" \n}      \n\nfunction flying_bird_have_beak(){\n    bird_have_beak \"$1\"\n}\n\nfunction flying_bird_fly(){\n    echo -e \"\\n\\tSoy un $1, soy un pajaro y vuelo\\n\"\n}\n\nfunction  hawk_have_beak(){\n    flying_bird_have_beak \"$1\"\n}\n\nfunction hawk_fly(){\n    flying_bird_fly \"$1\"\n}\n\nfunction non_flying_bird_have_beak(){\n    bird_have_beak \"$1\"\n}\n\nfunction penguin_have_beak(){\n    non_flying_bird_have_beak \"$1\"\n}\n\nfunction penguin_swim(){\n     echo -e \"\\n\\tSoy un $1, soy un pajaro y nado, no vuelo\\n\"\n}\n\n\n\necho \"Hawk\"\nhawk_have_beak halcon\nhawk_fly halcon\n\necho \"Penguin\"\npenguin_have_beak pingüino\npenguin_swim pingüino\n\n\n\n\necho -e \"\\n\\n=======================================DIFICULTAD EXTRA=======================================\\n\\n\"\n\n\n\n# * DIFICULTAD EXTRA (opcional):\n# * Crea una jerarquia de vehiculos. Todos ellos deben poder acelerar y frenar, asi como\n# * cumplir el LSP.\n# * Instrucciones:\n# * 1. Crea la clase Vehiculo.\n# * 2. Añade tres subclases de Vehiculo.\n# * 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n# * 4. Desarrolla un codigo que compruebe que se cumple el LSP.\n\n\nfunction vehicle_init(){\n    local name=$1\n    echo $1\n}\nfunction vehicle_accelerate(){\n    pass\n}\n    \nfunction vehicle_brake(){\n    pass\n}\n    \nfunction engine_vehicle(){\n    local name=$1\n    echo -e \"$1 es un vehi­culo de motor\"\n}   \n    \n    \nfunction engine_vehicle_brake(){\n    local name=$1\n    echo -e \"$1 esta frenando con los discos de freno\"\n}\n\nfunction electric_motor_accelerate(){\n    local name=$1\n    echo -e \"$1 está acelerando con el motor electrico\"\n}\n\nfunction gas_motor_accelerate(){\n    local name=$1\n    echo -e \"$1 está acelerando con el motor de gasoil\"\n}\n\nfunction non_engine_vehicle(){\n    local name=$1\n    echo -e \"$1 es un vehiculo sin motor\"\n}\n\nfunction non_engine_accelerate(){\n    local name=$1\n    echo -e \"$1 está acelerando con los pedales\"\n}\n\nfunction non_engine_brake(){\n    local name=$1\n    echo -e \"$1 está frenando con las zapatas\"\n}\n\ncamion_name=$(vehicle_init \"camion\")\nengine_vehicle $camion_name\ngas_motor_accelerate $camion_name\nengine_vehicle_brake $camion_name\n\ncoche_name=$(vehicle_init \"coche\")\nengine_vehicle $coche_name\nelectric_motor_accelerate $coche_name\nengine_vehicle_brake $coche_name\n\nbici_name=$(vehicle_init \"bicicleta\")\nnon_engine_vehicle $bici_name\nnon_engine_accelerate $bici_name\nnon_engine_brake $bici_name\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/c#/hequebo.cs",
    "content": "/*\n * El principio de sustitución de Liskov (LSP)\n * establece que los objetos de una clase padre\n * deben poder ser reemplazados por objetos de \n * clases hijas sin alterar la integridad del \n * programa\n */\nclass Program\n{\n    static void Main(string[] args)\n    {\n        Console.WriteLine(\"---Principio de Sustitución de Liskov---\");\n        // Incorrecto\n        AbstractSale sale = new Sale(500);\n        sale.Generate();\n        Console.WriteLine($\"El impuesto es de ${sale.CalculateTax()}\");\n        Console.WriteLine($\"El total es de ${sale.GetTotal()}\");\n        Console.WriteLine();\n\n        AbstractSale saleWithoutTax = new SaleWithoutTax(500);\n        saleWithoutTax.Generate();\n        /*\n         * Si se intenta ejecutar estos métodos el sistema se\n         * rompe por lo que se rompería el principio de sustutución de Liskov\n         */\n        // Console.WriteLine($\"El impuesto es de ${saleWithoutTax.CalculateTax()}\");\n        // Console.WriteLine($\"El total es de ${saleWithoutTax.GetTotal()}\");\n        Console.WriteLine();\n        // Correcto\n\n        SaleWithTaxes localSale = new LocalSale(500);\n        localSale.Generate();\n        Console.WriteLine($\"El impuesto es de ${localSale.CalculateTax()}\");\n        Console.WriteLine($\"El total es de ${localSale.GetTotal()}\");\n        Console.WriteLine();\n\n        AbstractSaleLSP saleLSP = new SaleWithoutTaxes(500);\n        saleLSP.Generate();\n        Console.WriteLine();\n\n        // Ejercicio extra\n        Console.WriteLine(\"---Ejercicio Extra---\");\n        Vehicle car = new Car(50);\n        car.Accelerate(15);\n        car.Brake(5); \n        Console.WriteLine();\n\n        Vehicle moto = new Motorcycle(40);\n        moto.Accelerate(20);\n        moto.Brake(30);\n        Console.WriteLine();\n\n        Vehicle truck = new Truck(80);\n        truck.Accelerate(30);\n        truck.Brake(110);\n\n        Console.ReadLine();\n    }\n}\n// Incorecto\n/*\n * Creamos una clase padre para ventas\n * con tres campos para el importe, el\n * impuesto y el total y tres métodos\n * para generar la venta, calcular el \n * impuesto y obtener el total \n */\nabstract class AbstractSale\n{\n    protected decimal _amount;\n    protected decimal _tax;\n    protected decimal _total;\n\n    public abstract void Generate();\n    public abstract decimal CalculateTax();\n    public abstract decimal GetTotal();\n}\n\n/*\n * Se crea una clase hija la cual\n * implementa los metodos de la clase\n * padre\n */\nclass Sale : AbstractSale\n{\n    public Sale(decimal amount)\n    {\n        _amount = amount;\n    }\n    public override void Generate()\n    {\n        Console.WriteLine(\"Se genera venta\");\n    }\n    public override decimal CalculateTax()\n    {\n        _tax = _amount * 0.16m;\n        return _tax;\n    }\n    public override decimal GetTotal()\n    {\n        _total = _amount + _tax;\n        return _total;\n    }\n}\n/*\n * Se crea una segunda clase la cual\n * está pensada para no calcular \n * impuestos, por lo que al no tener\n * una implementación de estos métodos\n * se arrojará una excepción\n */\nclass SaleWithoutTax: AbstractSale\n{\n    public SaleWithoutTax(decimal amount)\n    {\n        _amount = amount;\n    }\n\n    public override void Generate()\n    {\n        Console.WriteLine(\"Se genera venta sin Impuestos\");\n    }\n    public override decimal CalculateTax()\n    {\n        throw new NotImplementedException();\n    }\n    public override decimal GetTotal()\n    {\n        throw new NotImplementedException();\n    }\n}\n\n// Correcto \n/*\n * Se crea la clase padre con lo mínimo que \n * necesita una venta, en este ejemplo el monto\n * y el método generar\n */\nabstract class AbstractSaleLSP\n{\n    protected decimal _amount;\n    public abstract void Generate();\n}\n/*\n * Podemos crear una segunada clase abstracta\n * que incluya el impuesto y un metodo que lo\n * genere, esta a su vez hereda de la clase\n * AbstractSaleLSP\n */\nabstract class SaleWithTaxes : AbstractSaleLSP\n{\n    protected decimal _tax;\n    protected decimal _total;\n\n    public abstract decimal CalculateTax();\n    public abstract decimal GetTotal();\n}\n/*\n * La clase LocalSale hereda de la clase SaleWithTaxes\n * y a su ves de AbstractSaleLSP por lo que implementa\n * todos los métodos que tiene estas clases padre\n */\nclass LocalSale: SaleWithTaxes\n{\n    public LocalSale(decimal amount)\n    {\n        _amount = amount;\n    }\n    public override void Generate()\n    {\n        Console.WriteLine(\"Se genera la venta con impuestos\");\n    }\n    public override decimal CalculateTax()\n    {\n        _tax = _amount * 0.16m;\n        return _tax;\n    }\n    public override decimal GetTotal()\n    {\n        _total = _amount + _tax;\n        return _total;\n    }\n}\n/*\n * Ahora podemos crear una clase que solo herede de\n * AbstractSaleLSP por lo que solo debe de implementar\n * el método Generate()\n */\nclass SaleWithoutTaxes : AbstractSaleLSP\n{\n    public SaleWithoutTaxes(decimal amount)\n    {\n        _amount = amount;\n    }\n    public override void Generate() => Console.WriteLine(\"Se genera venta sin impuestos\");\n}\n\n// Ejercicio Extra\nclass Vehicle\n{\n    public int Speed;\n    public Vehicle(int speed)\n    {\n        Speed = speed;\n    }\n\n    public virtual void Accelerate(int speed) => Speed += speed;\n    public virtual void Brake(int speed)\n    {\n        Speed += speed;\n        if (Speed > 0)\n            Speed = 0;\n    }\n}\nclass Car : Vehicle\n{\n    public Car(int speed) : base(speed) { }\n    public override void Accelerate(int speed)\n    {\n        Console.WriteLine(\"El auto acelera\");\n        base.Accelerate(speed);\n        Console.WriteLine($\"La velocidad del auto es de {Speed}km/h\");\n    }\n    public override void Brake(int speed)\n    {\n        Console.WriteLine(\"El auto frena\");\n        base.Brake(speed);\n        if (Speed == 0)\n            Console.WriteLine(\"El auto se ha detenido por completo\");\n    }\n}\n\nclass Motorcycle : Vehicle\n{\n    public Motorcycle(int speed) : base(speed) { }\n    public override void Accelerate(int speed)\n    {\n        Console.WriteLine(\"La moto acelera\");\n        base.Accelerate(speed);\n        Console.WriteLine($\"La velocidad de la moto es de {Speed}km/h\");\n    }\n    public override void Brake(int speed)\n    {\n        Console.WriteLine(\"La moto frena\");\n        base.Brake(speed);\n        if (Speed == 0)\n            Console.WriteLine(\"La moto se ha detenido por completo\");\n    }\n}\n\nclass Truck : Vehicle\n{\n    public Truck(int speed) : base(speed) { }\n    public override void Accelerate(int speed)\n    {\n        Console.WriteLine(\"El camión acelera\");\n        base.Accelerate(speed);\n        Console.WriteLine($\"La velocidad del camión es de {Speed}km/h\");\n    }\n    public override void Brake(int speed)\n    {\n        Console.WriteLine(\"El camión frena\");\n        base.Brake(speed);\n        if (Speed == 0)\n            Console.WriteLine(\"El camión se ha detenido por completo\");\n    }\n}"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/c#/kenysdev.cs",
    "content": "namespace exs28;\n/*\n╔══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado               ║\n║ GitHub: https://github.com/Kenysdev  ║\n║ 2024 -  C#                           ║\n╚══════════════════════════════════════╝\n-------------------------------------------------\n* SOLID: PRINCIPIO DE SUSTITUCIÓN DE LISKOV (LSP)\n-------------------------------------------------\n*/\n\n// clase base\npublic abstract class Animal(string name)\n{\n    protected string name = name;\n\n    public abstract string MakeSound();\n}\n\n// Clases derivadas\npublic class Dog(string name) : Animal(name)\n{\n    public override string MakeSound()\n    {\n        return $\"{name} hace Woof\";\n    }\n}\n\npublic class Cat(string name) : Animal(name)\n{\n    public override string MakeSound()\n    {\n        return $\"{name} hace Meow\";\n    }\n}\n\n/*\n_______________\n* EJERCICIO:\n* Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n* cumplir el LSP.\n* Instrucciones:\n* 1. Crea la clase Vehículo.\n* 2. Añade tres subclases de Vehículo.\n* 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n* 4. Desarrolla un código que compruebe que se cumple el LSP.\n*/\n\n// Clase base abstracta\npublic abstract class Vehicle(string brand, string model)\n{\n    // Propiedades\n    public string Brand { get; } = brand;\n    public string Model { get; } = model;\n\n    // Métodos abstractos\n    public abstract string Accelerate();\n    public abstract string Brake();\n}\n\n// Clases derivadas\npublic class Car(string brand, string model) : Vehicle(brand, model)\n{\n    public override string Accelerate()\n    {\n        string properties = $\"{Brand} - {Model}\";\n        return $\"Acelerando auto: {properties}\";\n    }\n\n    public override string Brake()\n    {\n        string properties = $\"{Brand} - {Model}\";\n        return $\"Frenando auto: {properties}\";\n    }\n}\n\npublic class Motorcycle(string brand, string model) : Vehicle(brand, model)\n{\n    public override string Accelerate()\n    {\n        string properties = $\"{Brand} - {Model}\";\n        return $\"Acelerando Motocicleta: {properties}\";\n    }\n\n    public override string Brake()\n    {\n        string properties = $\"{Brand} - {Model}\";\n        return $\"Frenando Motocicleta: {properties}\";\n    }\n}\n\npublic class Truck(string brand, string model) : Vehicle(brand, model)\n{\n    public override string Accelerate()\n    {\n        string properties = $\"{Brand} - {Model}\";\n        return $\"Acelerando Camión: {properties}\";\n    }\n\n    public override string Brake()\n    {\n        string properties = $\"{Brand} - {Model}\";\n        return $\"Frenando Camión: {properties}\";\n    }\n}\n\n//__________________\npublic class Program\n{\n    static void Main()\n    {\n        Dog perro = new(\"Max\");\n        Cat gato = new(\"Milo\");\n        Animal Ncat = new Cat(\"Dex\");\n\n        Console.WriteLine(perro.MakeSound());\n        Console.WriteLine(gato.MakeSound());\n        Console.WriteLine(Ncat.MakeSound());\n        \n        //___________________________\n        // exs 2\n        \n        Car car = new(\"Honda\", \"Civic\");\n        TestSubClass(car);\n\n        Vehicle motorcycle = new Motorcycle(\"Kawasaki\", \"Ninja\");\n        TestSubClass(motorcycle);\n\n        Vehicle truck = new Truck(\"Ford\", \"Raptor\");\n        TestSubClass(truck);\n\n    }\n\n    static void TestSubClass(Vehicle subClass)\n    {\n        Console.WriteLine(\"\\nPropiedades:\");\n        Console.WriteLine($\"{subClass.Brand} - {subClass.Model}\");\n\n        Console.WriteLine(\"\\nMétodos:\");\n        Console.WriteLine(subClass.Accelerate());\n        Console.WriteLine(subClass.Brake());\n    }\n}\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/c++/hectorio23.cpp",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23 \n#include <cstdlib>\n#include <iostream>\n#include <vector>\n#include <memory>\n\n// Clase base abstracta para todos los vehículos. Define dos métodos virtuales\n// puros que deben ser implementados por las subclases: acelerar y frenar.\nclass Vehiculo {\npublic:\n    virtual ~Vehiculo() = default;\n\n    /**\n     * Método virtual puro para acelerar. Debe ser implementado por las subclases.\n     */\n    virtual std::string acelerar() const = 0;\n\n    /**\n     * Método virtual puro para frenar. Debe ser implementado por las subclases.\n     */\n    virtual std::string frenar() const = 0;\n};\n\n// Clase que representa un coche. Implementa los métodos acelerar y frenar\n// de acuerdo a la interfaz definida por la clase base Vehiculo.\nclass Coche : public Vehiculo {\npublic:\n    std::string acelerar() const override {\n        return \"[+] - El coche está acelerando.\";\n    }\n\n    std::string frenar() const override {\n        return \"[+] - El coche está frenando.\";\n    }\n};\n\n// Clase que representa una bicicleta. Implementa los métodos acelerar y frenar\n// de acuerdo a la interfaz definida por la clase base Vehiculo.\nclass Bicicleta : public Vehiculo {\npublic:\n    std::string acelerar() const override {\n        return \"[+] - La bicicleta está acelerando.\";\n    }\n\n    std::string frenar() const override {\n        return \"[+] - La bicicleta está frenando.\";\n    }\n};\n\n// Clase que representa un avión. Implementa los métodos acelerar y frenar\n// de acuerdo a la interfaz definida por la clase base Vehiculo.\nclass Avion : public Vehiculo {\npublic:\n    std::string acelerar() const override {\n        return \"[+] - El avión está acelerando.\";\n    }\n\n    std::string frenar() const override {\n        return \"[+] - El avión está frenando.\";\n    }\n};\n\n/**\n * Función para probar el principio de sustitución de Liskov (LSP). \n * Toma un puntero a Vehiculo y llama a sus métodos acelerar y frenar.\n * \n * @param vehiculo Un puntero a una instancia de una subclase de Vehiculo.\n */\nvoid testLSP(const std::unique_ptr<Vehiculo>& vehiculo) {\n    std::cout << vehiculo->acelerar() << std::endl;\n    std::cout << vehiculo->frenar() << std::endl;\n}\n\nint main() {\n    // Crear una lista de diferentes vehículos que cumplen con el LSP\n    std::vector<std::unique_ptr<Vehiculo>> vehiculos;\n    vehiculos.push_back(std::make_unique<Coche>());\n    vehiculos.push_back(std::make_unique<Bicicleta>());\n    vehiculos.push_back(std::make_unique<Avion>());\n\n    // Probar cada vehículo para asegurar que cumplen con el LSP\n    for (const auto& vehiculo : vehiculos) {\n        testLSP(vehiculo);\n    }\n\n    return EXIT_SUCCESS;\n}\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/dart/EmilianoAngel.dart",
    "content": "// Icorrecto\n// class Bird {\n//   String fly() {\n//     return 'Flying';\n//   }\n// }\n\n// class Chicken extends Bird {\n//   fly() {\n//     throw Exception('Los pollos no vuela');  \n//   }\n// }\n\n// Correcto\n\nclass Bird {\n  String move() {\n    return 'Moving';\n  }\n}\n\nclass Chicken extends Bird {\n  String move() {\n    return 'Walking';\n  }\n}\n\n// Ejercicio de jerarquia de vehiculos\n\nclass Vehicle {\n  int speed = 0;\n\n  void accelerate(int increment) {\n    speed += increment;\n    print('Velocidad = $speed');\n  }\n\n  void brake(int decrement) {\n    speed -= decrement;\n    print('Velocidad = $speed');\n  }\n}\n\nclass Car extends Vehicle {\n  @override\n  void accelerate(int increment) {\n    print('El coche esta acelerando');\n    super.accelerate(increment);\n  }\n\n  @override\n  void brake(int decrement) {\n    print('El coche esta frendando');\n    super.brake(decrement);\n  }\n}\n\nclass Bycicle extends Vehicle {\n  @override\n  void accelerate(int increment) {\n    print('La bici esta acelerando');\n    super.accelerate(increment);\n  }\n\n  @override\n  void brake(int decrement) {\n    print('La bici esta frendando');\n    super.brake(decrement);\n  }\n}\n\nclass Motorcycle extends Vehicle {\n  @override\n  void accelerate(int increment) {\n    print('La moto esta acelerando');\n    super.accelerate(increment);\n  }\n\n  @override\n  void brake(int decrement) {\n    print('La moto esta frendando');\n    super.brake(decrement);\n  }\n}\n\nvoid testVehicle(Vehicle vehicle) {\n  vehicle.accelerate(5);\n  vehicle.brake(3);\n}\n\nvoid main() {\n\n  Bird bird = Bird();\n  print(bird.move());\n  Chicken chicken = Chicken();\n  print(chicken.move());\n  \n  bird = Chicken();\n  print(bird.move());\n\n  // Ejercicio de jerarquia de vehiculos\n\n  Car car = Car();\n  Motorcycle motorcycle = Motorcycle();\n  Bycicle bycile = Bycicle();\n\n  testVehicle(car);\n  testVehicle(motorcycle);\n  testVehicle(bycile);\n\n}\n\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/ejercicio.md",
    "content": "# #28 SOLID: PRINCIPIO DE SUSTITUCIÓN DE LISKOV (LSP)\n> #### Dificultad: Media | Publicación: 08/07/24 | Corrección: 15/07/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n * cumplir el LSP.\n * Instrucciones:\n * 1. Crea la clase Vehículo.\n * 2. Añade tres subclases de Vehículo.\n * 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n * 4. Desarrolla un código que compruebe que se cumple el LSP.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/28 - SOLID LSP/go/ddaniel27.go",
    "content": "package main\n\n// La interfaz Vehicle define el comportamiento de un vehículo\n// \"Clase\" Vehicle\ntype Vehicle interface {\n\tAccelerate()\n\tBrake()\n}\n\n// Car implementa la interfaz Vehicle\ntype Car struct{}\n\nfunc (c Car) Accelerate() {\n\tprintln(\"Acelerando carro\")\n}\n\nfunc (c Car) Brake() {\n\tprintln(\"Frenando carro\")\n}\n\n// Boat implementa la interfaz Vehicle\ntype Boat struct{}\n\nfunc (b Boat) Accelerate() {\n\tprintln(\"Acelerando bote\")\n}\n\nfunc (b Boat) Brake() {\n\tprintln(\"Frenando bote\")\n}\n\n// Boat implementa una funcion para Unmoor, por lo tanto estamos agregando un objeto S sin afectar al comportamiento\nfunc (b Boat) Unmoor() {\n\tprintln(\"Desamarrando bote\")\n}\n\n// DriveVehicle acelera y frena un vehículo\nfunc DriveVehicle(v Vehicle) {\n\tv.Accelerate()\n\tv.Brake()\n}\n\nfunc main() {\n\tcar := Car{}\n\tboat := Boat{}\n\n\tDriveVehicle(car)\n\tDriveVehicle(boat)\n\n\t// Llamados particulares\n\tboat.Unmoor()\n}\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/go/hozlucas28.go",
    "content": "package main\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"math\"\n)\n\n/* -------------------------------------------------------------------------- */\n/*                                 INTERFACES                                 */\n/* -------------------------------------------------------------------------- */\n\ntype BadShape interface {\n\tGetArea() (float64, error)\n}\n\ntype GoodShape interface {\n\tGetArea() float64\n}\n\ntype Vehicle interface {\n\tBrake()\n\tSpeedUp()\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                  FUNCTIONS                                 */\n/* -------------------------------------------------------------------------- */\n\nfunc BadGetArea(shape BadShape) (float64, error) {\n\treturn shape.GetArea()\n}\n\nfunc GoodGetArea(shape GoodShape) float64 {\n\treturn shape.GetArea()\n}\n\nfunc Brake(vehicle Vehicle) {\n\tvehicle.Brake()\n}\n\nfunc SpeedUp(vehicle Vehicle) {\n\tvehicle.SpeedUp()\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                   CLASSES                                  */\n/* -------------------------------------------------------------------------- */\n\n/* ------------------------------ BadRectangle ------------------------------ */\n\ntype badRectangle struct {\n\tHeight float64\n\tWidth  float64\n\t_      struct{}\n}\n\nfunc NewBadRectangle(height float64, width float64) BadShape {\n\tvar rectangle badRectangle = badRectangle{Height: height, Width: width}\n\treturn &rectangle\n}\n\nfunc (rectangle *badRectangle) GetArea() (float64, error) {\n\treturn rectangle.Height * rectangle.Width, nil\n}\n\n/* -------------------------------- BadCircle ------------------------------- */\n\ntype badCircle struct {\n\tRadius float64\n\t_      struct{}\n}\n\nfunc NewBadCircle(radius float64) BadShape {\n\tvar circle badCircle = badCircle{Radius: radius}\n\treturn &circle\n}\n\nfunc (circle *badCircle) GetArea() (float64, error) {\n\treturn 0, errors.New(\"Area calculation method of circle is not implemented\")\n}\n\n/* ------------------------------ GoodRectangle ----------------------------- */\n\ntype goodRectangle struct {\n\tHeight float64\n\tWidth  float64\n\t_      struct{}\n}\n\nfunc NewGoodRectangle(height float64, width float64) GoodShape {\n\tvar rectangle goodRectangle = goodRectangle{Height: height, Width: width}\n\treturn &rectangle\n}\n\nfunc (rectangle *goodRectangle) GetArea() float64 {\n\treturn rectangle.Height * rectangle.Width\n}\n\n/* ------------------------------- GoodCircle ------------------------------- */\n\ntype goodCircle struct {\n\tRadius float64\n\t_      struct{}\n}\n\nfunc NewGoodCircle(radius float64) GoodShape {\n\tvar circle goodCircle = goodCircle{Radius: radius}\n\treturn &circle\n}\n\nfunc (circle *goodCircle) GetArea() float64 {\n\treturn math.Pi * math.Pow(circle.Radius, 2)\n}\n\n/* ----------------------------------- Car ---------------------------------- */\n\ntype car struct{}\n\nfunc NewCar() Vehicle {\n\tvar car car = car{}\n\treturn &car\n}\n\nfunc (car *car) Brake() {\n\tfmt.Println(\"Car braking!\")\n}\n\nfunc (car *car) SpeedUp() {\n\tfmt.Println(\"Car speeding up!\")\n}\n\n/* ---------------------------------- Truck --------------------------------- */\n\ntype truck struct{}\n\nfunc NewTruck() Vehicle {\n\tvar truck truck = truck{}\n\treturn &truck\n}\n\nfunc (truck *truck) Brake() {\n\tfmt.Println(\"Truck braking!\")\n}\n\nfunc (truck *truck) SpeedUp() {\n\tfmt.Println(\"Truck speeding up!\")\n}\n\n/* ---------------------------------- Boat ---------------------------------- */\n\ntype boat struct{}\n\nfunc NewBoat() Vehicle {\n\tvar boat boat = boat{}\n\treturn &boat\n}\n\nfunc (boat *boat) Brake() {\n\tfmt.Println(\"Boat braking!\")\n}\n\nfunc (boat *boat) SpeedUp() {\n\tfmt.Println(\"Boat speeding up!\")\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\nfunc main() {\n\t/*\n\t\tLiskov Substitution Principle (LCP)...\n\t*/\n\n\tfmt.Println(\"Liskov Substitution Principle (LCP)...\")\n\n\tfmt.Println(\"\\nBad implementation of Liskov Substitution Principle (LCP)...\")\n\n\tfmt.Println(\"\\n```\\n\" + `type BadShape interface {\n  GetArea() (float64, error)\n}\n\nfunc BadGetArea(shape BadShape) (float64, error) {\n  return shape.GetArea()\n}\n\ntype badRectangle struct {\n  Height float64\n  Width  float64\n  _      struct{}\n}\n\nfunc NewBadRectangle(height float64, width float64) BadShape {\n  var rectangle badRectangle = badRectangle{Height: height, Width: width}\n  return &rectangle\n}\n\nfunc (rectangle *badRectangle) GetArea() (float64, error) {\n  return rectangle.Height * rectangle.Width, nil\n}\n\ntype badCircle struct {\n  Radius float64\n  _      struct{}\n}\n\nfunc NewBadCircle(radius float64) BadShape {\n  var circle badCircle = badCircle{Radius: radius}\n  return &circle\n}\n\nfunc (circle *badCircle) GetArea() (float64, error) {\n  return 0, errors.New(\"Area calculation method of circle is not implemented\")\n}` + \"\\n```\")\n\n\tfmt.Println(\n\t\t\"\\nThis is a bad implementation of Liskov Substitution Principle (LCP),\\n\" +\n\t\t\t\"because the 'BadGetArea' method of 'badCircle' is no implemented. So, if we\\n\" +\n\t\t\t\"execute the 'BadGetArea' function with both classes ('badRectangle', and 'badCircle')\\n\" +\n\t\t\t\"the function will produce different side effects that could be break the function execution.\\n\" +\n\t\t\t\"Thus the 'BadShape' interface can not be replaced by 'badCircle' class.\",\n\t)\n\n\tfmt.Println(\"\\nGood implementation of Liskov Substitution Principle (LCP)...\")\n\n\tfmt.Println(\"\\n```\\n\" + `type GoodShape interface {\n  GetArea() float64\n}\n\nfunc GoodGetArea(shape GoodShape) float64 {\n  return shape.GetArea()\n}\n\ntype goodRectangle struct {\n  Height float64\n  Width  float64\n  _      struct{}\n}\n\nfunc NewGoodRectangle(height float64, width float64) GoodShape {\n  var rectangle goodRectangle = goodRectangle{Height: height, Width: width}\n  return &rectangle\n}\n\nfunc (rectangle *goodRectangle) GetArea() float64 {\n  return rectangle.Height * rectangle.Width\n}\n\ntype goodCircle struct {\n  Radius float64\n  _      struct{}\n}\n\nfunc NewGoodCircle(radius float64) GoodShape {\n  var circle goodCircle = goodCircle{Radius: radius}\n  return &circle\n}\n\nfunc (circle *goodCircle) GetArea() float64 {\n  return math.Pi * math.Pow(circle.Radius, 2)\n}` + \"\\n```\")\n\n\tfmt.Println(\n\t\t\"\\nThis is a good implementation of Liskov Substitution Principle (LCP),\\n\" +\n\t\t\t\"because all classes which implements 'GoodShape' interface implements the\\n\" +\n\t\t\t\"'GoodGetArea' method with the same side effect. So, if we execute the 'GoodGetArea'\\n\" +\n\t\t\t\"function with both classes ('GoodRectangle', and 'GoodCircle'), we are not going to\\n\" +\n\t\t\t\"have side effects that could break the function execution. Thus the 'GoodShape' interface\\n\" +\n\t\t\t\"can be replaced by any of these classes.\",\n\t)\n\n\tfmt.Println(\n\t\t\"\\n# ---------------------------------------------------------------------------------- #\",\n\t)\n\n\t/*\n\t   Additional challenge...\n\t*/\n\n\tfmt.Println(\"\\nAdditional challenge...\")\n\n\tvar car Vehicle = NewCar()\n\tvar truck Vehicle = NewTruck()\n\tvar boat Vehicle = NewBoat()\n\n\tfmt.Println()\n\tSpeedUp(car)\n\tSpeedUp(truck)\n\tSpeedUp(boat)\n\n\tfmt.Println()\n\tBrake(car)\n\tBrake(truck)\n\tBrake(boat)\n}\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/go/raynerpv2022.go",
    "content": "package main\n\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)\"\n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n * cumplir el LSP.\n * Instrucciones:\n * 1. Crea la clase Vehículo.\n * 2. Añade tres subclases de Vehículo.\n * 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n * 4. Desarrolla un código que compruebe que se cumple el LSP.\n */\n\nimport \"fmt\"\n\n// incorrecto\ntype vehiculo interface {\n\tavanzar()\n\tretroceder()\n}\n\ntype autobus struct {\n}\n\nfunc (m autobus) avanzar() {\n\tfmt.Println(\"avanzar\")\n}\n\nfunc (m autobus) retroceder() {\n\tfmt.Println(\"retrocediendo\")\n}\n\ntype tranvia struct {\n}\n\nfunc (t tranvia) avanzar() {\n\tfmt.Println(\"avanzar\")\n}\n\nfunc (m tranvia) retroceder() {\n\tfmt.Println(\"retrocediendo\")\n}\n\nfunc creartransporte(tt vehiculo) {\n\n\ttt.avanzar()\n\ttt.retroceder()\n\n}\n\n// correcto\n\ntype moverAdelante interface {\n\tadelante()\n}\n\ntype moverAtras interface {\n\tatras()\n}\n\ntype tren struct{}\n\nfunc (t tren) adelante() {\n\tfmt.Println(\"moviendo adelante\")\n}\nfunc (t tren) atras() {\n\tfmt.Println(\"moviendo atras\")\n}\n\ntype tranvia1 struct{}\n\nfunc (t tranvia1) adelante() {\n\tfmt.Println(\"moviendo adelante\")\n}\n\nfunc avanceTransporte(t1 moverAdelante) {\n\tt1.adelante()\n\n}\n\nfunc retrocesoTransporte(t1 moverAtras) {\n\tt1.atras()\n}\n\n// ***************************** ejercicio\n\ntype Freno interface {\n\tfrenar(velo int)\n}\n\ntype Acelerador interface {\n\tacelerar(velo int)\n}\n\ntype bicicleta struct {\n\tspeed int\n}\ntype patinete struct {\n\tspeed int\n}\ntype triciclo struct {\n\tspeed int\n}\n\nfunc (b *bicicleta) frenar(velo int) {\n\tb.speed -= velo\n\tfmt.Printf(\" Frenando la bici... velocidad :%v \\n\", b.speed)\n}\n\nfunc (b *bicicleta) acelerar(velo int) {\n\tb.speed += velo\n\tfmt.Printf(\" Acelerando la bici... velocidad :%v \\n\", b.speed)\n}\n\nfunc (p *patinete) acelerar(velo int) {\n\tp.speed += velo\n\tfmt.Printf(\" Acelerando el Patinete... velocidad :%v \\n\", p.speed)\n}\n\nfunc (p *patinete) frenar(velo int) {\n\tp.speed -= velo\n\tfmt.Printf(\" Frenado el Patinete... velocidad :%v \\n\", p.speed)\n}\n\nfunc (t *triciclo) acelerar(velo int) {\n\tt.speed += velo\n\tfmt.Printf(\" Acelerando el triciclo... velocidad :%v \\n\", t.speed)\n}\n\nfunc test_acelerar(v Acelerador, vel int) {\n\tv.acelerar(vel)\n\n}\n\nfunc test_frenar(v Freno, vel int) {\n\tv.frenar(vel)\n\n}\n\nfunc main() {\n\tfmt.Println(\"Reto 28 LSP\")\n\tautobus := autobus{}\n\ttranvia := tranvia{}\n\tcreartransporte((autobus))\n\tcreartransporte((tranvia))\n\n\ttren := tren{}\n\ttranvia1 := tranvia1{}\n\n\tavanceTransporte(tren)\n\tretrocesoTransporte(tren)\n\tavanceTransporte(tranvia1)\n\n\tbici := &bicicleta{}\n\tpati := &patinete{}\n\ttri := &triciclo{}\n\n\ttest_acelerar(bici, 10)\n\ttest_frenar(bici, 3)\n\n\ttest_acelerar(pati, 4)\n\ttest_frenar(pati, 1)\n\n\ttest_acelerar(tri, 100)\n\n}\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/java/AmadorQuispe.java",
    "content": "package com.amsoft.roadmap.example28;\n\n/*\nEl Principio de Substitución de Liskov es uno de los principios SOLID y hace referencia a cómo usamos\nla herencia de forma adecuada. El principio dice algo como lo siguiente si S es un subtipo de T ,\nT puede ser reemplazado con objetos de tipo S sin alterar el comportamiento esperado en el programa.\n* */\npublic class Example28 {\n    public static void main(String[] args) {\n        Person person = new Child(\"Juan\",\"2233 3333 3333 5555\");\n        Payable citizen = new Citizen(\"Amador\",\"1111 2222 3333 4444\");\n        citizen.pay();\n\n        //EXTRA\n        Vehicle car = new Car();\n        Vehicle motorbike = new Motorbike();\n        Vehicle truck = new Truck();\n        TestVehicle testVehicle = new TestVehicle();\n        testVehicle.accelerate(car);\n        testVehicle.accelerate(motorbike);\n        testVehicle.accelerate(truck);\n\n        testVehicle.brake(car);\n        testVehicle.brake(motorbike);\n        testVehicle.brake(truck);\n    }\n}\n/*\nLa clase Person, se viola el Principio de Sustitución de Liskov porque la subclase Child hereda el método pay()\nde Person, lo que permite que un objeto Child realice pagos, aunque lógicamente un niño no debería poder hacerlo.\nLa solución propuesta introduce una interfaz Payable que define el método pay(), y solo la subclase Citizen\nimplementa esta interfaz, mientras que Child no.\nEsto garantiza que solo los objetos de Citizen puedan realizar pagos, respetando así el LSP y asegurando que los\nobjetos de Child no se comporten de manera inapropiada al sustituir objetos de la clase base Person.\n */\nclass Person {\n    private String name;\n    private String bankAccount;\n\n    public Person(String name, String bankAccount) {\n        this.name = name;\n        this.bankAccount = bankAccount;\n    }\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public String getBankAccount() {\n        return bankAccount;\n    }\n\n    public void setBankAccount(String bankAccount) {\n        this.bankAccount = bankAccount;\n    }\n}\ninterface  Payable {\n    void pay();\n}\nclass Child extends Person {\n    public Child(String name, String bankAccount) {\n        super(name, bankAccount);\n    }\n}\nclass Citizen extends Person implements Payable {\n    public Citizen(String name, String bankAccount) {\n        super(name, bankAccount);\n    }\n\n    @Override\n    public void pay() {\n        System.out.println(this.getName() + \" pay with number account bank number \" + this.getBankAccount());\n    }\n}\n\n/*VIOLA LSP*/\n/* class Person {\n    private String name;\n    private String bankAccount;\n\n    public Person(String name, String bankAccount) {\n        this.name = name;\n        this.bankAccount = bankAccount;\n    }\n\n    public void pay(){\n        System.out.println(name + \" pay with number account bank number \" + bankAccount);\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public String getBankAccount() {\n        return bankAccount;\n    }\n\n    public void setBankAccount(String bankAccount) {\n        this.bankAccount = bankAccount;\n    }\n}\nclass Child extends Person {\n\n    public Child(String name, String bankAccount) {\n        super(name, bankAccount);\n    }\n\n    @Override\n    public void pay() {\n        throw new UnsupportedOperationException(\"Cannot pay\");\n    }\n}\nclass Citizen extends Person {\n    public Citizen(String name, String bankAccount) {\n        super(name, bankAccount);\n    }\n}*/\n\n/*EXTRA*/\nclass TestVehicle {\n    public void accelerate(Vehicle vehicle){\n        vehicle.accelerate();\n    }\n    public void brake(Vehicle vehicle){\n        vehicle.brake();\n    }\n}\nabstract class Vehicle {\n    abstract void accelerate();\n    abstract void brake();\n}\n\nclass Car extends Vehicle {\n\n    @Override\n    void accelerate() {\n        System.out.println(\"Acelerando el coche\");\n    }\n\n    @Override\n    void brake() {\n        System.out.println(\"Frenando el coche\");\n    }\n}\n\nclass Motorbike extends Vehicle{\n\n    @Override\n    void accelerate() {\n        System.out.println(\"Acelerando la motocicleta\");\n    }\n\n    @Override\n    void brake() {\n        System.out.println(\"Frenando la motocicleta\");\n    }\n}\n\nclass Truck extends Vehicle {\n\n    @Override\n    void accelerate() {\n        System.out.println(\"Acelerando el camión\");\n    }\n\n    @Override\n    void brake() {\n        System.out.println(\"Frenando el camión\");\n    }\n}\n\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/java/AnaLauDB.java",
    "content": "public class AnaLauDB {\n\n    // ==========================================================================\n    // IMPLEMENTACIÓN QUE CUMPLE EL PRINCIPIO DE SUSTITUCIÓN DE LISKOV (LSP)\n    // ==========================================================================\n\n    // 1. Clase base Vehículo\n    static abstract class Vehiculo {\n        protected String marca;\n        protected String modelo;\n        protected double velocidad;\n        protected double velocidadMaxima;\n        protected boolean encendido;\n\n        public Vehiculo(String marca, String modelo, double velocidadMaxima) {\n            this.marca = marca;\n            this.modelo = modelo;\n            this.velocidadMaxima = velocidadMaxima;\n            this.velocidad = 0;\n            this.encendido = false;\n        }\n\n        // Método para encender el vehículo\n        public void encender() {\n            if (!encendido) {\n                encendido = true;\n                System.out.println(marca + \" \" + modelo + \" encendido.\");\n            }\n        }\n\n        // Método para apagar el vehículo\n        public void apagar() {\n            if (encendido && velocidad == 0) {\n                encendido = false;\n                System.out.println(marca + \" \" + modelo + \" apagado.\");\n            } else if (velocidad > 0) {\n                System.out.println(\"No se puede apagar el vehículo en movimiento.\");\n            }\n        }\n\n        // Método acelerar - debe ser implementado por las subclases\n        public abstract void acelerar(double incremento);\n\n        // Método frenar - debe ser implementado por las subclases\n        public abstract void frenar(double decremento);\n\n        // Método para mostrar estado actual\n        public void mostrarEstado() {\n            System.out.printf(\"%s %s - Velocidad: %.1f km/h, Estado: %s%n\",\n                    marca, modelo, velocidad, encendido ? \"Encendido\" : \"Apagado\");\n        }\n\n        // Getters\n        public double getVelocidad() {\n            return velocidad;\n        }\n\n        public double getVelocidadMaxima() {\n            return velocidadMaxima;\n        }\n\n        public boolean isEncendido() {\n            return encendido;\n        }\n\n        public String getMarca() {\n            return marca;\n        }\n\n        public String getModelo() {\n            return modelo;\n        }\n    }\n\n    // ==========================================================================\n    // 2. SUBCLASES DE VEHÍCULO QUE CUMPLEN LSP\n    // ==========================================================================\n\n    // Subclase: Automóvil\n    static class Automovil extends Vehiculo {\n        private int numeroPuertas;\n\n        public Automovil(String marca, String modelo, double velocidadMaxima, int numeroPuertas) {\n            super(marca, modelo, velocidadMaxima);\n            this.numeroPuertas = numeroPuertas;\n        }\n\n        @Override\n        public void acelerar(double incremento) {\n            if (!encendido) {\n                System.out.println(\"Error: Debe encender el automóvil primero.\");\n                return;\n            }\n\n            if (incremento < 0) {\n                System.out.println(\"Error: El incremento de velocidad debe ser positivo.\");\n                return;\n            }\n\n            double nuevaVelocidad = velocidad + incremento;\n            if (nuevaVelocidad <= velocidadMaxima) {\n                velocidad = nuevaVelocidad;\n                System.out.printf(\"Automóvil acelerando: %.1f km/h%n\", velocidad);\n            } else {\n                velocidad = velocidadMaxima;\n                System.out.printf(\"Automóvil alcanzó velocidad máxima: %.1f km/h%n\", velocidad);\n            }\n        }\n\n        @Override\n        public void frenar(double decremento) {\n            if (decremento < 0) {\n                System.out.println(\"Error: El decremento de velocidad debe ser positivo.\");\n                return;\n            }\n\n            double nuevaVelocidad = velocidad - decremento;\n            if (nuevaVelocidad >= 0) {\n                velocidad = nuevaVelocidad;\n                System.out.printf(\"Automóvil frenando: %.1f km/h%n\", velocidad);\n            } else {\n                velocidad = 0;\n                System.out.println(\"Automóvil detenido completamente.\");\n            }\n        }\n\n        public int getNumeroPuertas() {\n            return numeroPuertas;\n        }\n    }\n\n    // Subclase: Motocicleta\n    static class Motocicleta extends Vehiculo {\n        private int cilindrada;\n\n        public Motocicleta(String marca, String modelo, double velocidadMaxima, int cilindrada) {\n            super(marca, modelo, velocidadMaxima);\n            this.cilindrada = cilindrada;\n        }\n\n        @Override\n        public void acelerar(double incremento) {\n            if (!encendido) {\n                System.out.println(\"Error: Debe encender la motocicleta primero.\");\n                return;\n            }\n\n            if (incremento < 0) {\n                System.out.println(\"Error: El incremento de velocidad debe ser positivo.\");\n                return;\n            }\n\n            // Las motocicletas aceleran más rápido que los automóviles\n            double aceleracionReal = incremento * 1.2;\n            double nuevaVelocidad = velocidad + aceleracionReal;\n\n            if (nuevaVelocidad <= velocidadMaxima) {\n                velocidad = nuevaVelocidad;\n                System.out.printf(\"Motocicleta acelerando rápidamente: %.1f km/h%n\", velocidad);\n            } else {\n                velocidad = velocidadMaxima;\n                System.out.printf(\"Motocicleta alcanzó velocidad máxima: %.1f km/h%n\", velocidad);\n            }\n        }\n\n        @Override\n        public void frenar(double decremento) {\n            if (decremento < 0) {\n                System.out.println(\"Error: El decremento de velocidad debe ser positivo.\");\n                return;\n            }\n\n            // Las motocicletas pueden frenar más bruscamente\n            double frenadoReal = decremento * 1.1;\n            double nuevaVelocidad = velocidad - frenadoReal;\n\n            if (nuevaVelocidad >= 0) {\n                velocidad = nuevaVelocidad;\n                System.out.printf(\"Motocicleta frenando: %.1f km/h%n\", velocidad);\n            } else {\n                velocidad = 0;\n                System.out.println(\"Motocicleta detenida completamente.\");\n            }\n        }\n\n        public int getCilindrada() {\n            return cilindrada;\n        }\n    }\n\n    // Subclase: Camión\n    static class Camion extends Vehiculo {\n        private double capacidadCarga;\n\n        public Camion(String marca, String modelo, double velocidadMaxima, double capacidadCarga) {\n            super(marca, modelo, velocidadMaxima);\n            this.capacidadCarga = capacidadCarga;\n        }\n\n        @Override\n        public void acelerar(double incremento) {\n            if (!encendido) {\n                System.out.println(\"Error: Debe encender el camión primero.\");\n                return;\n            }\n\n            if (incremento < 0) {\n                System.out.println(\"Error: El incremento de velocidad debe ser positivo.\");\n                return;\n            }\n\n            // Los camiones aceleran más lento debido a su peso\n            double aceleracionReal = incremento * 0.7;\n            double nuevaVelocidad = velocidad + aceleracionReal;\n\n            if (nuevaVelocidad <= velocidadMaxima) {\n                velocidad = nuevaVelocidad;\n                System.out.printf(\"Camión acelerando lentamente: %.1f km/h%n\", velocidad);\n            } else {\n                velocidad = velocidadMaxima;\n                System.out.printf(\"Camión alcanzó velocidad máxima: %.1f km/h%n\", velocidad);\n            }\n        }\n\n        @Override\n        public void frenar(double decremento) {\n            if (decremento < 0) {\n                System.out.println(\"Error: El decremento de velocidad debe ser positivo.\");\n                return;\n            }\n\n            // Los camiones necesitan más distancia para frenar\n            double frenadoReal = decremento * 0.8;\n            double nuevaVelocidad = velocidad - frenadoReal;\n\n            if (nuevaVelocidad >= 0) {\n                velocidad = nuevaVelocidad;\n                System.out.printf(\"Camión frenando gradualmente: %.1f km/h%n\", velocidad);\n            } else {\n                velocidad = 0;\n                System.out.println(\"Camión detenido completamente.\");\n            }\n        }\n\n        public double getCapacidadCarga() {\n            return capacidadCarga;\n        }\n    }\n\n    // ==========================================================================\n    // 4. CÓDIGO QUE COMPRUEBA EL CUMPLIMIENTO DEL LSP\n    // ==========================================================================\n\n    // Método que trabaja con la clase base Vehículo\n    public static void probarVehiculo(Vehiculo vehiculo) {\n        System.out.println(\"\\n--- Probando vehículo: \" + vehiculo.getMarca() + \" \" + vehiculo.getModelo() + \" ---\");\n\n        // Encender vehículo\n        vehiculo.encender();\n        vehiculo.mostrarEstado();\n\n        // Acelerar varias veces\n        vehiculo.acelerar(20);\n        vehiculo.mostrarEstado();\n\n        vehiculo.acelerar(30);\n        vehiculo.mostrarEstado();\n\n        vehiculo.acelerar(40);\n        vehiculo.mostrarEstado();\n\n        // Frenar\n        vehiculo.frenar(25);\n        vehiculo.mostrarEstado();\n\n        vehiculo.frenar(50);\n        vehiculo.mostrarEstado();\n\n        // Apagar vehículo\n        vehiculo.apagar();\n    }\n\n    // Método que demuestra el polimorfismo y LSP\n    public static void simularCarrera(Vehiculo[] vehiculos) {\n        System.out.println(\"\\n=== SIMULACIÓN DE CARRERA ===\");\n\n        // Encender todos los vehículos\n        for (Vehiculo v : vehiculos) {\n            v.encender();\n        }\n\n        // Acelerar todos por igual\n        System.out.println(\"\\n ¡Comienza la carrera! Todos aceleran 50 km/h\");\n        for (Vehiculo v : vehiculos) {\n            v.acelerar(50);\n        }\n\n        // Mostrar velocidades después de la aceleración\n        System.out.println(\"\\n Velocidades después de acelerar:\");\n        for (Vehiculo v : vehiculos) {\n            System.out.printf(\"%-15s: %.1f km/h%n\",\n                    v.getMarca() + \" \" + v.getModelo(), v.getVelocidad());\n        }\n\n        // Frenar todos\n        System.out.println(\"\\n Todos frenan 30 km/h\");\n        for (Vehiculo v : vehiculos) {\n            v.frenar(30);\n        }\n\n        // Mostrar velocidades finales\n        System.out.println(\"\\n Velocidades después de frenar:\");\n        for (Vehiculo v : vehiculos) {\n            System.out.printf(\"%-15s: %.1f km/h%n\",\n                    v.getMarca() + \" \" + v.getModelo(), v.getVelocidad());\n        }\n    }\n\n    public static void main(String[] args) {\n        System.out.println(\"=== DEMOSTRACIÓN DEL PRINCIPIO DE SUSTITUCIÓN DE LISKOV (LSP) ===\");\n\n        // Crear instancias de diferentes tipos de vehículos\n        Vehiculo auto = new Automovil(\"Toyota\", \"Corolla\", 180, 4);\n        Vehiculo moto = new Motocicleta(\"Honda\", \"CBR600\", 250, 600);\n        Vehiculo camion = new Camion(\"Volvo\", \"FH16\", 120, 40000);\n\n        // 4. Comprobar que se cumple el LSP\n        System.out.println(\"1. Probando cada vehículo individualmente:\");\n\n        // Cada subclase puede ser sustituida por la clase base sin romper la\n        // funcionalidad\n        probarVehiculo(auto); // LSP: Automóvil puede sustituir a Vehículo\n        probarVehiculo(moto); // LSP: Motocicleta puede sustituir a Vehículo\n        probarVehiculo(camion); // LSP: Camión puede sustituir a Vehículo\n\n        // Demostrar polimorfismo y LSP con un array de vehículos\n        Vehiculo[] vehiculos = { auto, moto, camion };\n        simularCarrera(vehiculos);\n\n        // Verificar que todas las subclases mantienen las postcondiciones de la clase\n        // base\n        System.out.println(\"\\n=== VERIFICACIÓN LSP ===\");\n        System.out.println(\"Todas las subclases pueden ser sustituidas por la clase base\");\n        System.out.println(\"Los métodos acelerar() y frenar() funcionan correctamente\");\n        System.out.println(\"Las precondiciones no son fortalecidas en las subclases\");\n        System.out.println(\"Las postcondiciones no son debilitadas en las subclases\");\n        System.out.println(\"Los invariantes de la clase base se mantienen en todas las subclases\");\n\n        // Ejemplo de uso polimórfico adicional\n        System.out.println(\"\\n=== EJEMPLO POLIMÓRFICO ADICIONAL ===\");\n        for (Vehiculo v : vehiculos) {\n            System.out.println(\"\\nTipo: \" + v.getClass().getSimpleName());\n            v.encender();\n            v.acelerar(60);\n            v.frenar(60);\n            v.apagar();\n        }\n\n        System.out.println(\"\\n CONCLUSIÓN: El LSP se cumple correctamente!\");\n        System.out.println(\"   - Cualquier instancia de Vehículo puede ser reemplazada por sus subclases\");\n        System.out.println(\"   - El comportamiento del programa sigue siendo correcto\");\n        System.out.println(\"   - No hay efectos secundarios inesperados\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/java/FranDev200.java",
    "content": "package com.amsoft.roadmap.example28;\n\nimport java.util.ArrayList;\n\npublic class FranDev200 {\n\n\n    abstract static class Vehiculo{\n\n        public void acelerar(){\n        }\n\n        public String girar(){ return null; }\n\n    }\n\n    abstract static class VehiculoConMotor extends Vehiculo{\n\n        public void repostar(){ }\n\n    }\n\n    static class Bicicleta extends Vehiculo{\n\n        @Override\n        public void acelerar() {\n            System.out.println(\"La bicicleta esta acelerando.\");\n        }\n\n        @Override\n        public String girar() {\n            return \"La bicicleta ha girado\";\n        }\n\n\n    }\n\n    static class Coche extends VehiculoConMotor{\n\n        @Override\n        public void acelerar() {\n            System.out.println(\"El coche esta acelerando.\");\n        }\n\n        @Override\n        public String girar() {\n            return \"El coche ha girado\";\n        }\n\n        @Override\n        public void repostar() {\n            System.out.println(\"El coche esta repostando.\");\n        }\n    }\n\n    static class Furgoneta extends VehiculoConMotor{\n\n        @Override\n        public void acelerar() {\n            System.out.println(\"La furgoneta esta acelerando.\");\n        }\n\n        @Override\n        public String girar() {\n            return \"La furgoneta ha girado\";\n        }\n\n        @Override\n        public void repostar() {\n            System.out.println(\"La furgoneta esta repostando.\");\n        }\n\n    }\n\n    static class ControlVehiculo{\n\n        public void arrancar(Vehiculo vehiculo){\n\n            vehiculo.acelerar();\n\n        }\n        public void girarDerecha(Vehiculo vehiculo){\n\n            System.out.println(vehiculo.girar() + \" a la derecha\");\n\n        }\n        public void girarIzquierda(Vehiculo vehiculo){\n\n            System.out.println(vehiculo.girar() + \" a la izquierda\");\n\n        }\n        public void repostar(VehiculoConMotor vehiculoConMotor){\n\n            vehiculoConMotor.repostar();\n\n        }\n\n    }\n\n    static void main() {\n\n        /*\n\n        EJERCICIO:\n         * Explora el \"Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)\"\n         * y crea un ejemplo simple donde se muestre su funcionamiento\n         * de forma correcta e incorrecta.\n\n         */\n\n        ControlVehiculo controlVehiculo = new ControlVehiculo();\n\n        // ACELERRAR\n        controlVehiculo.arrancar(new Bicicleta());\n        controlVehiculo.arrancar(new Furgoneta());\n        controlVehiculo.arrancar(new Coche());\n        System.out.println();\n\n        // GIRAR\n        controlVehiculo.girarDerecha(new Bicicleta());\n        controlVehiculo.girarIzquierda(new Bicicleta());\n        controlVehiculo.girarIzquierda(new Coche());\n        controlVehiculo.girarDerecha(new Coche());\n        controlVehiculo.girarIzquierda(new Furgoneta());\n        controlVehiculo.girarDerecha(new Furgoneta());\n        System.out.println();\n\n        // REPOSTAR\n        controlVehiculo.repostar(new Coche());\n        controlVehiculo.repostar(new Furgoneta());\n        // controlVehiculo.repostar(new Bicicleta()); // Da error, xq no tiene ese metodo heredado\n\n\n        /*\n\n        DIFICULTAD EXTRA (opcional):\n         * Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n         * cumplir el LSP.\n         * Instrucciones:\n         * 1. Crea la clase Vehículo.\n         * 2. Añade tres subclases de Vehículo.\n         * 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n         * 4. Desarrolla un código que compruebe que se cumple el LSP.\n\n         */\n        System.out.println(\"\\n===============\");\n        System.out.println(\"EJERCICIO EXTRA\");\n        System.out.println(\"===============\\n\");\n\n\n\n        ArrayList<Vehiculo2> vehiculos = new ArrayList<Vehiculo2>();\n        for (int i = 0; i < 3; i++) {\n            vehiculos.add(new Bici());\n            vehiculos.add(new Camion());\n            vehiculos.add(new Coche2());\n        }\n\n        for(Vehiculo2 vehiculo : vehiculos){\n            vehiculo.acelerar();\n        }\n\n        System.out.println();\n\n        for(Vehiculo2 vehiculo : vehiculos){\n            vehiculo.frenar();\n        }\n\n    }\n\n    abstract static class Vehiculo2{\n\n        public void acelerar(){ }\n        public void frenar(){ }\n\n    }\n\n    static class Coche2 extends Vehiculo2{\n\n        @Override\n        public void acelerar() {\n            System.out.println(\"El coche esta acelerando.\");\n        }\n\n        @Override\n        public void frenar() {\n            System.out.println(\"El coche está frenando.\");\n        }\n    }\n\n    static class Bici extends Vehiculo2{\n\n        @Override\n        public void acelerar() {\n            System.out.println(\"La bici esta acelerando.\");\n        }\n\n        @Override\n        public void frenar() {\n            System.out.println(\"La bici está frenando.\");\n        }\n    }\n\n    static class Camion extends Vehiculo2{\n\n        @Override\n        public void acelerar() {\n            System.out.println(\"El camion esta acelerando.\");\n        }\n\n        @Override\n        public void frenar() {\n            System.out.println(\"El camion está frenando.\");\n        }\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/java/Jesusway69.java",
    "content": "package roadmap.ejercicio28\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n */\npublic class Jesusway69 {\n\n    public static void main(String[] args) {\n        Figure1 rectangle = new Figure1();\n        Rectangle1 rectangle1 = new Rectangle1();\n        Square1 square1 = new Square1();\n        Rectangle2 rectangle2 = new Rectangle2(2, 9);\n        Square2 square2 = new Square2(5);\n        Circle2 circle2 = new Circle2(4);\n        Car car = new Car();\n        Motorcycle motorcycle = new Motorcycle();\n        Truck truck = new Truck();\n        System.out.println(\"rectangle1 = \" + rectangle1.calculateArea(4, 2));\n        System.out.println(\"rectangle = \" + rectangle.calculateArea(3, 5));\n        System.out.println(\"square1 = \" + square1.calculateArea(4, 6));\n        System.out.println(\"rectangle2 = \" + rectangle2.calculateArea());\n        System.out.println(\"square2 = \" + square2.calculateArea());\n        System.out.println(\"circle2 = \" + circle2.calculateArea());\n        System.out.println(\"car = \" + car.accelerate());\n        vehicleTest(car);\n        vehicleTest(motorcycle);\n        vehicleTest(truck);\n\n    }\n\n    public static void vehicleTest(Object object) {\n        String name = \"\";\n        boolean accelerate = false;\n        if (object instanceof Car) {\n            name = ((Car) object).name;\n            accelerate = ((Car) object).accelerate();\n        } else if (object instanceof Motorcycle) {\n            name = ((Motorcycle) object).name;\n            accelerate = ((Motorcycle) object).accelerate();\n        } else if (object instanceof Truck) {\n            name = ((Truck) object).name;\n            accelerate = ((Truck) object).accelerate();\n        }\n\n        System.out.println(\"El Vehículo \" + name + \" acelera?: \" + accelerate);\n\n    }\n\n}\n\n/*\n  El Principio de Sustitución de Liskov establece que las subclases deben ser sustituibles por sus clases base.\n  En el caso de  no se cumple este principio porque para calcular el área de un cuadrado es innecesario\n   el aporte de 2 argumentos (base y altura) aunque en este caso concreto hemos \"trampeado\" la clase para que multiplique\n   sólo un valor e ignore el otro, aun así siguen siendo obligatorios los 2 argumentos aunque el 2do sea innecesario, además\n   al tener la misma fórmula de multiplicación simple para calcular el área el método calculate_area nos valdría pero si\n   quisiéramos ampliar el programa y añadir una clase que cree objetos circulares y calcular su área ya no nos serviría\n   la clase padre y llamar a su método calculate_area \n */\n\nclass Figure1 {\n\n    public int base;\n    public int height;\n\n    public Figure1() {\n    }\n\n    public Figure1(int base, int height) {\n        this.base = base;\n        this.height = height;\n    }\n\n    protected int calculateArea(int base, int height) {\n\n        return base * height;\n    }\n}\n\nclass Rectangle1 extends Figure1 {\n\n    public Rectangle1() {\n    }\n\n    public Rectangle1(int base, int height) {\n        super.base = base;\n        super.height = height;\n        super.calculateArea(super.base, super.height);\n\n    }\n}\n\nclass Square1 extends Figure1 {\n\n    public Square1() {\n    }\n\n    @Override\n    protected int calculateArea(int base, int height) {\n        return base * base;\n    }\n}\n\n/*\n  En este caso creamos una clase abstracta que defina los métodos a usar en las subclases\n   de esta manera podemos seguir creando sublases con diferentes formas geométricas aplicando a cada una\n   de ellas las funcionalidades concretas de esos métodos tanto los argumentos requeridos al iniciar la instancia\n   como el cálculo del área para cada forma y así respetamos el LSP ya que aunque las clases abstractas en Java\n   no se pueden instanciar nos sirve como plantilla para el resto de clases\n */\n\nabstract class Figure2 {\n\n    public abstract double calculateArea();\n}\n\nclass Rectangle2 extends Figure2 {\n\n    public int base2;\n    public int height2;\n\n    public Rectangle2() {\n\n    }\n\n    public Rectangle2(int base2, int height2) {\n        this.base2 = base2;\n        this.height2 = height2;\n    }\n\n    @Override\n    public double calculateArea() {\n        return base2 * height2;\n    }\n\n}\n\nclass Square2 extends Figure2 {\n\n    public int side2;\n\n    public Square2() {\n    }\n\n    public Square2(int side2) {\n        this.side2 = side2;\n    }\n\n    @Override\n    public double calculateArea() {\n        return side2 * side2;\n\n    }\n}\n\nclass Circle2 extends Figure2 {\n\n    public int radius;\n\n    public Circle2() {\n    }\n\n    public Circle2(int radius) {\n        this.radius = radius;\n    }\n\n    @Override\n    public double calculateArea() {\n        return Math.round(Math.pow(radius, 2) * Math.PI * 100d) / 100d;\n    }\n\n}\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n * cumplir el LSP.\n * Instrucciones:\n * 1. Crea la clase Vehículo.\n * 2. Añade tres subclases de Vehículo.\n * 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n * 4. Desarrolla un código que compruebe que se cumple el LSP.\n */\n\nclass Vehicle {\n\n    public String name;\n    public boolean accelerate = true;\n    public boolean brake = true;\n\n    public Vehicle() {\n\n    }\n\n    public boolean accelerate() {\n        return accelerate;\n    }\n\n    public boolean brake() {\n        return brake;\n    }\n\n}\n\nclass Car extends Vehicle {\n\n    public String name;\n\n    public Car() {\n        this.name = \"coche\";\n\n    }\n\n    @Override\n    public boolean accelerate() {\n        return accelerate;\n    }\n\n    @Override\n    public boolean brake() {\n        return brake;\n    }\n\n}\n\nclass Motorcycle extends Vehicle {\n\n    public String name;\n\n    public Motorcycle() {\n        this.name = \"moto\";\n    }\n\n    @Override\n    public boolean accelerate() {\n        return accelerate;\n    }\n\n    @Override\n    public boolean brake() {\n        return brake;\n    }\n\n}\n\nclass Truck extends Vehicle {\n\n    public String name;\n\n    public Truck() {\n        this.name = \"camión\";\n    }\n\n    @Override\n    public boolean accelerate() {\n        return accelerate;\n    }\n\n    @Override\n    public boolean brake() {\n        return brake;\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/java/Josegs95.java",
    "content": "import java.util.Random;\n\npublic class Josegs95 {\n    public static void main(String[] args) {\n        //Ejercicio\n        //Forma incorrecta\n        WrongAnimal animal1 = new WrongAnimal();\n        WrongAnimal snake1 = new WrongSnake();\n        WrongAnimal tiger1 = new WrongTiger();\n\n        animal1.putEggs();\n        snake1.putEggs();\n        tiger1.putEggs();\n        //Forma correcta\n        OviparousAnimal animal2 = new OviparousAnimal();\n        OviparousAnimal snake2 = new Snake();\n        MammalAnimal animal3 = new MammalAnimal();\n        MammalAnimal tiger2 = new Tiger();\n\n        animal2.putEggs();\n        snake2.putEggs();\n        animal3.breastfeed();\n        tiger2.breastfeed();\n\n        //Reto\n        new Josegs95().retoFinal();\n    }\n\n    public void retoFinal(){\n        Random rnd = new Random();\n        Vehicle vehicle1 = new Car(50);\n        Vehicle vehicle2 = new Train(100);\n        Vehicle vehicle3 = new Plane(150);\n        Vehicle[] vehicles = {vehicle1, vehicle2, vehicle3};\n\n        for (int i = 0; i < 50; i++){\n            if (rnd.nextBoolean())\n                vehicles[rnd.nextInt(vehicles.length)].accelerate();\n            else\n                vehicles[rnd.nextInt(vehicles.length)].brake();\n        }\n    }\n\n    //Clases incorrectas\n    public static class WrongAnimal{\n        public void putEggs(){\n            System.out.println(\"El animal pone huevos\");\n        }\n    }\n    public static class WrongSnake extends WrongAnimal{\n        @Override\n        public void putEggs() {\n            System.out.println(\"La serpiente pone huevos\");\n        }\n    }\n    public static class WrongTiger extends WrongAnimal{\n        @Override\n        public void putEggs() {\n            //throw new UnsupportedOperationException(\"Los tigres no ponen huevos\");\n        }\n    }\n    //Clases correctas\n    public static class Animal{}\n    public static class OviparousAnimal extends Animal{\n        public void putEggs() {\n            System.out.println(\"El animal ovíparo pone huevos\");\n        }\n    }\n    public static class MammalAnimal extends Animal{\n        public void breastfeed() {\n            System.out.println(\"El animal mamífero da de mamar\");\n        }\n    }\n    public static class Snake extends OviparousAnimal{\n        @Override\n        public void putEggs() {\n            System.out.println(\"La serpiente pone huevos\");\n        }\n    }\n    public static class Tiger extends MammalAnimal{\n        @Override\n        public void breastfeed() {\n            System.out.println(\"El tigre da de mamar\");\n        }\n    }\n    //Reto\n    public class Vehicle{\n        private double speed;\n\n        public Vehicle(double speed){\n            this.speed = speed;\n        }\n\n        public void accelerate(){\n            ++speed;\n        }\n        public void brake(){\n            if (speed > 0)\n                --speed;\n        }\n\n        public double getSpeed() {\n            return speed;\n        }\n    }\n    public class Car extends Vehicle{\n\n        public Car(double speed) {\n            super(speed);\n        }\n\n        @Override\n        public void accelerate() {\n            super.accelerate();\n            System.out.println(\"El coche acelera y su velocidad es de \" + super.getSpeed() + \"Km/h\");\n        }\n\n        @Override\n        public void brake() {\n            super.brake();\n            System.out.println(\"El coche frena y su velocidad es de \" + super.getSpeed() + \"Km/h\");\n        }\n    }\n    public class Train extends Vehicle{\n        public Train(double speed) {\n            super(speed);\n        }\n\n        @Override\n        public void accelerate() {\n            super.accelerate();\n            System.out.println(\"El tren acelera y su velocidad es de \" + super.getSpeed() + \"Km/h\");\n        }\n\n        @Override\n        public void brake() {\n            super.brake();\n            System.out.println(\"El tren frena y su velocidad es de \" + super.getSpeed() + \"Km/h\");\n        }\n    }\n    public class Plane extends Vehicle{\n        public Plane(double speed) {\n            super(speed);\n        }\n\n        @Override\n        public void accelerate() {\n            super.accelerate();\n            System.out.println(\"El avión acelera y su velocidad es de \" + super.getSpeed() + \"Km/h\");\n        }\n\n        @Override\n        public void brake() {\n            super.brake();\n            System.out.println(\"El avión frena y su velocidad es de \" + super.getSpeed() + \"Km/h\");\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/java/asjordi.java",
    "content": "/*\n    El Principio de Sustitución de Liskov (LSP) establece que las subclases deben ser sustituibles por sus clases base.\n    Es decir, dado que la clase B es una subclase de la clase A, deberíamos poder pasar un objeto de la clase B a cualquier método que espere un objeto de la clase A sin que se produzca un error.\n    Este es el comportamiento esperado, dado que cuando se utiliza la herencia se asume que la subclase hereda todos los comportamientos de la superclase.\n    La subclase extiende el comportamiento, pero nunca lo reduce.\n */\n\npublic class Main {\n\n    public static void main(String[] args) {\n        // Comprobación LSP\n        Vehiculo vehiculoDeportivo = new VehiculoDeportivo();\n        Vehiculo vehiculoFamiliar = new VehiculoFamiliar();\n        Vehiculo vehiculoCarga = new VehiculoCarga();\n\n        vehiculoDeportivo.acelerar();\n        vehiculoDeportivo.frenar();\n\n        vehiculoFamiliar.acelerar();\n        vehiculoFamiliar.frenar();\n\n        vehiculoCarga.acelerar();\n        vehiculoCarga.frenar();\n    }\n\n    /*\n        EJERCICIO:\n        Explora el \"Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)\"\n        y crea un ejemplo simple donde se muestre su funcionamiento\n        de forma correcta e incorrecta.\n     */\n\n    interface Animal {\n        void comer();\n        void nadar();\n    }\n\n    static class Jirafa implements Animal {\n        @Override\n        public void comer() {\n            System.out.println(\"La jirafa come hojas de los árboles\");\n        }\n\n        @Override\n        public void nadar() {\n            throw new UnsupportedOperationException(\"La jirafa no puede nadar\");\n        }\n    }\n\n    static class Pato implements Animal {\n        @Override\n        public void comer() {\n            System.out.println(\"El pato come pan\");\n        }\n\n        @Override\n        public void nadar() {\n            System.out.println(\"El pato nada en el agua\");\n        }\n    }\n\n    /*\n        En este caso, la clase Jirafa no puede nadar, por lo que se lanza una excepción UnsupportedOperationException.\n        Esto viola el principio de sustitución de Liskov, ya que la clase Jirafa no puede ser sustituida por la clase Animal.\n        Para solucionar este problema, se puede crear una interfaz separada para los animales que pueden nadar, y hacer que la clase Pato implemente esa interfaz. Mientras que la clase Jirafa no implementará la interfaz AnimalAcuatico, pero sí la interfaz Animal.\n     */\n\n    interface Animal2 {\n        void comer();\n    }\n\n    interface AnimalAcuatico extends Animal2 {\n        void nadar();\n    }\n\n    static class Jirafa2 implements Animal2 {\n        @Override\n        public void comer() {\n            System.out.println(\"La jirafa come hojas de los árboles\");\n        }\n    }\n\n    static class Pato2 implements AnimalAcuatico {\n        @Override\n        public void comer() {\n            System.out.println(\"El pato come pan\");\n        }\n\n        @Override\n        public void nadar() {\n            System.out.println(\"El pato nada en el agua\");\n        }\n    }\n\n    /*\n        DIFICULTAD EXTRA (opcional):\n        Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como cumplir el LSP.\n        Instrucciones:\n        1. Crea la clase Vehículo.\n        2. Añade tres subclases de Vehículo.\n        3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n        4. Desarrolla un código que compruebe que se cumple el LSP.\n     */\n\n    abstract static class Vehiculo {\n        abstract void acelerar();\n        abstract void frenar();\n    }\n\n    static class VehiculoDeportivo extends Vehiculo {\n        @Override\n        void acelerar() {\n            System.out.println(\"El vehículo deportivo acelera rápidamente\");\n        }\n\n        @Override\n        void frenar() {\n            System.out.println(\"El vehículo deportivo frena bruscamente\");\n        }\n    }\n\n    static class VehiculoFamiliar extends Vehiculo {\n        @Override\n        void acelerar() {\n            System.out.println(\"El vehículo familiar acelera suavemente\");\n        }\n\n        @Override\n        void frenar() {\n            System.out.println(\"El vehículo familiar frena de forma segura\");\n        }\n    }\n\n    static class VehiculoCarga extends Vehiculo {\n        @Override\n        void acelerar() {\n            System.out.println(\"El vehículo de carga acelera lentamente\");\n        }\n\n        @Override\n        void frenar() {\n            System.out.println(\"El vehículo de carga frena con precaución\");\n        }\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/java/danhingar.java",
    "content": "public class danhingar {\n\n    public static void main(String[] args) throws Exception {\n        /*\n         * Bird bird = new Bird();\n         * bird.fly();\n         * Chicken chicken = new Chicken();\n         * chicken.fly();\n         */\n\n        Bird1 bird1 = new Bird1();\n        bird1.move();\n        bird1 = new Chicken1();\n        bird1.move();\n\n        Bird1 chicken1 = new Chicken1();\n        chicken1.move();\n        chicken1 = new Bird1();\n        chicken1.move();\n\n        // Extra\n        Motorbike motorbike = new Motorbike();\n        Car car = new Car();\n        Bike bicycle = new Bike();\n\n        Vehicle.test(motorbike);\n        Vehicle.test(car);\n        Vehicle.test(bicycle);\n\n        \n    }\n\n}\n\n// Incorrecto\nclass Bird {\n    public void fly() throws Exception {\n        System.out.println(\"Flying\");\n    }\n}\n\nclass Chicken extends Bird {\n    @Override\n    public void fly() throws Exception {\n        throw new Exception(\"Los pollos no vuelan\");\n    }\n}\n\nclass Bird1 {\n\n    public void move() {\n        System.out.println(\"Moving\");\n    }\n\n}\n\nclass Chicken1 extends Bird1 {\n\n    public void move() {\n        System.out.println(\"Walking\");\n    }\n}\n\n// EXTRA\n\nclass Vehicle {\n    private Integer speed = 0;\n\n    public Vehicle() {\n    }\n\n    public void accelerate(Integer increment) {\n        speed = speed + increment;\n        System.out.printf(\"Velocidad: %d Km/h\\n\", speed);\n    }\n\n    public void brake(Integer decrement) {\n        speed = speed - decrement;\n        if (speed < 0)\n            speed = 0;\n        System.out.printf(\"Velocidad: %d Km/h\\n\", speed);\n    }\n\n    public static void test(Vehicle vehicle){\n        vehicle.accelerate(5);\n        vehicle.brake(1);\n    }\n\n}\n\nclass Motorbike extends Vehicle {\n\n\n    @Override\n    public void accelerate(Integer increment) {\n        System.out.println(\"La moto está acelerando\");\n        super.accelerate(increment);\n    }\n\n    @Override\n    public void brake(Integer decrement) {\n        System.out.println(\"La moto está frenando\");\n        super.brake(decrement);\n    }\n\n}\n\nclass Bike extends Vehicle {\n\n    @Override\n    public void accelerate(Integer increment) {\n        System.out.println(\"La bicicleta está acelerando\");\n        super.accelerate(increment);\n    }\n\n    @Override\n    public void brake(Integer decrement) {\n        System.out.println(\"La bicicleta está frenando\");\n        super.brake(decrement);\n    }\n\n}\n\nclass Car extends Vehicle {\n\n    @Override\n    public void accelerate(Integer increment) {\n        System.out.println(\"El coche está acelerando\");\n        super.accelerate(increment);\n    }\n\n    @Override\n    public void brake(Integer decrement) {\n        System.out.println(\"El coche está frenando\");\n        super.brake(decrement);\n    }\n\n}"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/java/martinbohorquez.java",
    "content": "import java.util.Random;\n\npublic class martinbohorquez {\n\n    public static void main(String[] args) {\n//        incorrectLSP();\n        correctLSP();\n        /*\n         * DIFICULTAD EXTRA\n         */\n        vehicleLSP();\n\n    }\n\n    /*\n    private static void incorrectLSP() {\n        Bird sparrow = new Sparrow();\n        makeBirdFly(sparrow); // Funciona correctamente\n\n        Bird ostrich = new Ostrich();\n        makeBirdFly(ostrich); // Lanza excepción, lo cual es un error de LSP\n    }\n\n    public static void makeBirdFly(Bird bird) {\n        bird.fly();\n    }\n    */\n\n    private static void correctLSP() {\n        FlyingBird sparrow = new Sparrow();\n        makeBirdFly(sparrow); // Funciona correctamente\n\n        // Ostrich no puede ser pasado a makeBirdFly, ya que no implementa FlyingBird.\n    }\n\n    private static void makeBirdFly(FlyingBird bird) {\n        bird.fly();\n    }\n\n    private static void vehicleAccelerateBrake(Vehicule vehicule) {\n        Random random = new Random();\n        vehicule.accelerate(random.nextInt(10));\n        vehicule.brake(random.nextInt(5));\n    }\n\n    private static void vehicleLSP() {\n        Vehicule car = new Car(60);\n        vehicleAccelerateBrake(car);\n        Vehicule bicycle = new Bicycle(0);\n        vehicleAccelerateBrake(bicycle);\n        Vehicule motorcycle = new Motorcycle(40);\n        vehicleAccelerateBrake(motorcycle);\n\n    }\n}\n\n/*\n// Clase base\nclass Bird {\n    public void fly() {\n        System.out.println(\"El pájaro vuela.\");\n    }\n}\n\n// Clase derivada\nclass Sparrow extends Bird {\n    @Override\n    public void fly() {\n        System.out.println(\"El gorrión vuela.\");\n    }\n}\n\n// Clase derivada que no vuela\nclass Ostrich extends Bird {\n    @Override\n    public void fly() {\n        throw new UnsupportedOperationException(\"El avestruz no puede volar.\");\n    }\n}*/\n\n// Interfaz base\ninterface Bird {\n    // Métodos comunes\n}\n\ninterface FlyingBird extends Bird {\n    void fly();\n}\n\nclass Sparrow implements FlyingBird {\n    @Override\n    public void fly() {\n        System.out.println(\"El gorrión vuela.\");\n    }\n}\n\nclass Ostrich implements Bird {\n    // No implementa fly()\n}\n\nabstract class Vehicule {\n    private Integer speed;\n\n    protected Vehicule() {\n        this(0);\n    }\n\n    protected Vehicule(Integer speed) {\n        this.speed = speed;\n        System.out.printf(\"Se crea un %s un con velocidad %d.%n\", getClass().getSimpleName(), speed);\n    }\n\n    void accelerate(Integer increment) {\n        speed += increment;\n        System.out.printf(\"Velocidad: %d Km/h.%n\", speed);\n    }\n\n    void brake(Integer decrement) {\n        speed -= decrement;\n        if (speed < 0) speed = 0;\n        System.out.printf(\"Velocidad: %d Km/h.%n\", speed);\n    }\n}\n\nclass Car extends Vehicule {\n    protected Car() {\n        super();\n    }\n\n    protected Car(Integer speed) {\n        super(speed);\n    }\n\n    @Override\n    void accelerate(Integer increment) {\n        System.out.printf(\"El auto está acelerando en %d.%n\", increment);\n        super.accelerate(increment);\n    }\n\n    @Override\n    void brake(Integer decrement) {\n        System.out.printf(\"El auto está frenando en %d.%n\", decrement);\n        super.brake(decrement);\n    }\n}\n\nclass Bicycle extends Vehicule {\n    protected Bicycle() {\n        super();\n    }\n\n    protected Bicycle(Integer speed) {\n        super(speed);\n    }\n\n    @Override\n    void accelerate(Integer increment) {\n        System.out.printf(\"La bicicleta está acelerando en %d.%n\", increment);\n        super.accelerate(increment);\n    }\n\n    @Override\n    void brake(Integer decrement) {\n        System.out.printf(\"La bicicleta está frenando en %d.%n\", decrement);\n        super.brake(decrement);\n    }\n}\n\nclass Motorcycle extends Vehicule {\n    protected Motorcycle() {\n        super();\n    }\n\n    protected Motorcycle(Integer speed) {\n        super(speed);\n    }\n\n    @Override\n    void accelerate(Integer increment) {\n        System.out.printf(\"La moto está acelerando en %d.%n\", increment);\n        super.accelerate(increment);\n    }\n\n    @Override\n    void brake(Integer decrement) {\n        System.out.printf(\"La moto está frenando en %d.%n\", decrement);\n        super.brake(decrement);\n    }\n}\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/java/simonguzman.java",
    "content": "\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\npublic class simonguzman {\n    public static void main(String[] args) {\n        //libraryManagementSystemLiskovViolation();\n        //libraryLSP();\n        //LiskovIncorrectTest();\n        LiskovCorrectTest();\n    }\n    /****************************** ejercicio adicional con lsp (Correcto) ******************************/\n    public static void LiskovCorrectTest() {\n        VehiculoLsp coche = new Coche();\n        VehiculoLsp bicicleta = new Bicicleta();\n        VehiculoLsp motocicleta = new Motocicleta();\n\n        // Probar comportamiento de los vehículos\n        acelerarYFrenarLsp(coche);\n        acelerarYFrenarLsp(bicicleta);\n        acelerarYFrenarLsp(motocicleta);\n    }\n\n    public static void acelerarYFrenarLsp(VehiculoLsp vehiculo) {\n        vehiculo.acelerar();\n        vehiculo.frenar();\n    }\n\n    static class VehiculoLsp {\n        public void acelerar() {\n            System.out.println(\"El vehículo está acelerando.\");\n        }\n\n        public void frenar() {\n            System.out.println(\"El vehículo está frenando.\");\n        }\n    }\n\n    static class Coche extends VehiculoLsp {\n        @Override\n        public void acelerar() {\n            System.out.println(\"El coche está acelerando rápidamente.\");\n        }\n\n        @Override\n        public void frenar() {\n            System.out.println(\"El coche está frenando suavemente.\");\n        }\n    }\n\n    static class Bicicleta extends VehiculoLsp {\n        @Override\n        public void acelerar() {\n            System.out.println(\"La bicicleta está acelerando lentamente.\");\n        }\n\n        @Override\n        public void frenar() {\n            System.out.println(\"La bicicleta está frenando manualmente.\");\n        }\n    }\n    static class Motocicleta extends VehiculoLsp {\n        @Override\n        public void acelerar() {\n            System.out.println(\"La motocicleta está acelerando con potencia.\");\n        }\n\n        @Override\n        public void frenar() {\n            System.out.println(\"La motocicleta está frenando rápidamente.\");\n        }\n    }\n    /****************************** ejercicio adicional sin lsp (Incorrecto) ******************************/\n    public static void LiskovIncorrectTest() {\n        Vehiculo cocheElectrico = new CocheElectrico();\n        acelerarYFrenar(cocheElectrico);\n\n        ((CocheElectrico) cocheElectrico).recargarBateria();\n    }\n\n    public static void acelerarYFrenar(Vehiculo vehiculo) {\n        vehiculo.acelerar();\n        vehiculo.frenar();\n    }\n\n    static class Vehiculo {\n        public void acelerar() {\n            System.out.println(\"El vehículo está acelerando.\");\n        }\n\n        public void frenar() {\n            System.out.println(\"El vehículo está frenando.\");\n        }\n    }\n\n// Subclase CocheEléctrico que viola LSP\n    static class CocheElectrico extends Vehiculo {\n        @Override\n        public void acelerar() {\n            System.out.println(\"El coche eléctrico está acelerando silenciosamente.\");\n        }\n\n        @Override\n        public void frenar() {\n            System.out.println(\"El coche eléctrico está frenando regenerativamente.\");\n        }\n\n        // Método adicional que viola el LSP\n        public void recargarBateria() {\n            System.out.println(\"Recargando la batería del coche eléctrico.\");\n        }\n    }\n    /****************************** ejemplo con lsp (Correcto) ******************************/\n    static void libraryLSP(){\n        LibraryManager libraryManager = new LibraryManager();\n        UserManager userManager = new UserManager();\n        LoanManagerLsp loanManager = new LoanManagerLsp();\n\n        libraryManager.registerBook(new PhysicalBook(\"1984\", \"George Orwell\", 3));\n        libraryManager.registerBook(new EBookLsp(\"Clean Code\", \"Robert Martin\"));\n\n        userManager.registerUser(\"John Doe\", \"001\", \"johndoe@example.com\");\n\n        User user = userManager.findUserById(\"001\");\n        BookLsp book1 = libraryManager.findBookByTitle(\"1984\");\n        BookLsp book2 = libraryManager.findBookByTitle(\"Clean Code\");\n\n        loanManager.borrowBook(user, book1);\n        loanManager.borrowBook(user, book2);\n\n        loanManager.returnBook(user, book1);\n        loanManager.returnBook(user, book2);\n    }\n\n    static abstract class BookLsp{\n        protected String title;\n        protected String author;\n\n        public BookLsp(){\n\n        }\n\n        public BookLsp(String title, String author){\n            this.title = title;\n            this.author = author;\n        }\n\n        public String getTitle() {\n            return title;\n        }\n\n        public abstract boolean isAvailable();\n        public abstract void borrow();\n        public abstract void returnBook(); \n    }\n\n    static class PhysicalBook extends BookLsp{\n        private int copies;\n\n        public PhysicalBook(){\n\n        }\n\n        public PhysicalBook(String title, String author, int copies){\n            super(title, author);\n            this.copies = copies;\n        }\n\n        @Override\n        public boolean isAvailable(){\n            return copies > 0;\n        }\n\n        @Override\n        public void borrow(){\n            if(copies > 0){\n                copies--;\n            }\n        }\n\n        @Override\n        public void returnBook(){\n            copies++;\n        }\n    }\n\n    static class EBookLsp extends BookLsp {\n\n        public EBookLsp(String title, String author) {\n            super(title, author);\n        }\n\n        @Override\n        public boolean isAvailable() {\n            return true; // Siempre disponible\n        }\n\n        @Override\n        public void borrow() {\n            System.out.println(\"Descargando eBook...\");\n        }\n\n        @Override\n        public void returnBook() {\n            System.out.println(\"El eBook ha sido devuelto.\");\n        }\n    }\n    static class LibraryManager{\n        private List<BookLsp> books = new ArrayList<>();\n\n        public void registerBook(BookLsp book){\n            books.add(book);\n            System.out.println(\"Libro registrado: \" + book.getTitle());\n        }\n\n        public BookLsp findBookByTitle(String title){\n            return books.stream().filter(b -> b.getTitle().equals(title)).findFirst().orElse(null);\n        }\n    }\n\n    static class UserManager{\n        private List<User> users = new ArrayList<>();\n\n        public void registerUser(String name, String id, String email){\n            users.add(new User(name, id, email));\n            System.out.println(\"Usuario registrado: \" + name);\n        }\n\n        public User findUserById(String id){\n            return users.stream().filter(u -> u.getId().equals(id)).findFirst().orElse(null);\n        }\n    }\n\n    static class LoanManagerLsp{\n        private Map<User, List<BookLsp>> borrowedBooks = new HashMap<>();\n\n        public void borrowBook(User user, BookLsp book){\n            if(book.isAvailable()){\n                borrowedBooks.computeIfAbsent(user, k -> new ArrayList<>()).add(book);\n                book.borrow();\n                System.out.println(\"Libro prestado: \" + book.getTitle() + \" a \" + user.getName());\n            } else {\n                System.out.println(\"El libro no está disponible para préstamo.\");\n            }\n        }\n\n        public void returnBook(User user, BookLsp book) {\n            List<BookLsp> borrowed = borrowedBooks.get(user);\n            if (borrowed != null && borrowed.contains(book)) {\n                borrowed.remove(book);\n                book.returnBook();\n                System.out.println(\"Libro devuelto: \" + book.getTitle());\n            } else {\n                System.out.println(\"No se pudo devolver el libro.\");\n            }\n        }\n    }\n\n    static class User{\n        private String name;\n        private String id;\n        private String email;\n\n        public User(){\n\n        }\n\n        public User(String name, String id, String email){\n            this.name = name;\n            this.id = id;\n            this.email = email;\n        }\n\n        public String getName() {\n            return name;\n        }\n\n        public String getId() {\n            return id;\n        }\n    }\n\n    /****************************** ejemplo sin lsp (Incorrecto) ******************************/\n    public static void libraryManagementSystemLiskovViolation(){\n        Book physicalBook = new Book(\"1984\", \"George Orwell\", 3);\n        EBook ebook = new EBook(\"Digital Fortress\", \"Dan Brown\", \"www.download.com\");\n\n        LoanManager loanManager = new LoanManager();\n\n        loanManager.borrowBook(physicalBook);\n        \n        loanManager.borrowBook(ebook);\n    }\n\n    static class Book{\n        private String title;\n        private String author;\n        private int copies;\n\n        public Book(){\n\n        }\n\n        public Book(String title, String author, int copies){\n            this.title = title;\n            this.author = author;\n            this.copies = copies;\n        }\n\n        public String getTitle() {\n            return title;\n        }\n\n        public int getCopies() {\n            return copies;\n        }\n\n        public void setCopies(int copies) {\n            this.copies = copies;\n        }\n\n        public void borrow(){\n            if (copies > 0){\n                copies--;\n                System.out.println(\"Libro prestado: \" + title);\n            } else {\n                System.out.println(\"No hay copias disponibles de: \" + title);\n            }\n        }        \n    }\n\n    static class EBook extends Book {\n        private String downloadLink;\n\n        public EBook(String title, String author,String downloadLink) {\n            super(title, author, 1);\n            this.downloadLink = downloadLink;\n        }\n\n        @Override\n        public void borrow(){\n            System.out.println(\"No se puede prestar el eBook, pero puedes descargarlo aquí: \" + downloadLink);\n        }\n    }\n\n    static class LoanManager{\n        public void borrowBook(Book book){\n            book.borrow();\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/javascript/Chrisdev00.js",
    "content": "/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n * cumplir el LSP.\n * Instrucciones:\n * 1. Crea la clase Vehículo.\n * 2. Añade tres subclases de Vehículo.\n * 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n * 4. Desarrolla un código que compruebe que se cumple el LSP.\n */\n\n// Forma incorrecta sin aplicar el principio LSP\n\nclass Content{\n    render(){\n        throw new Error(\"Method 'render' must be implemented.\");\n    }\n\n    getSummary(){\n        throw new Error(\"Method 'summary' must be implemented.\");\n    }\n}\n\nclass Article extends Content{\n    constructor(title, body){\n        super();\n        this.title = title;\n        this.body = body\n    }\n    render(){\n        return `${this.title}<p>${this.body}</p> `;\n    }\n    getSummary(){\n        return this.body.substring(0, 100) + \"...\";\n    }\n}\n\nclass Video extends Content{\n    constructor(title,videoUrl){\n        super();\n        this.title = title;\n        this.videoUrl = videoUrl\n    }\n    render(){\n        return `${this.title}<video src='${this.videoUrl}' controls></video>`;\n    }\n    getSummary(){\n        return `${this.title} (Video)`;\n    }\n}\n\nclass ImageGallery extends Content{\n    constructor(title, images){\n        super();\n        this.title = this.title;\n        this.images = images;\n    }\n    render(){\n        const imageTags = this.images.map(image => `<img src='${image}' />`).join('');\n        return `${this.title}${imageTags}`;\n    }\n    getSummary(){\n        return `${this.title} (${this.images.length} images)`;\n    }\n}\n\nfunction displayContent(content){\n    if(content instanceof Article){\n        console.log(\"Rendering Article:\");\n        console.log(content.render());\n        console.log(\"Summary:\");\n        console.log(content.getSummary());\n    } else if(content instanceof Video){\n        console.log(\"Rendering Video:\");\n        console.log(content.render());\n        console.log(\"Summary:\");\n        console.log(content.getSummary());\n    } else if(content instanceof ImageGallery){\n        console.log(\"Rendering Image Gallery:\");\n        console.log(content.render());\n        console.log(\"Summary:\");\n        console.log(content.getSummary());\n    } else {\n        console.log(\"Unknown content type\");\n    }\n}\n\nconst article = new Article(\"My Article\", \"This is the body of my article.\");\nconst video = new Video(\"My Video\", \"http://example.com/video.mp4\");\nconst imageGallery = new ImageGallery(\"My Gallery\", [\"http://example.com/image1.jpg\", \"http://example.com/image2.jpg\"]);\n\ndisplayContent(article);\ndisplayContent(video);\ndisplayContent(imageGallery);\n\n\n// Forma correcta de aplicar el principio LSP\n\nclass Content {\n    render() {\n        throw new Error(\"Method 'render()' must be implemented.\");\n    }\n    getSummary() {\n        throw new Error(\"Method 'getSummary()' must be implemented.\");\n    }\n}\n\nclass Article extends Content {\n    constructor(title, body) {\n        super();\n        this.title = title;\n        this.body = body;\n    }\n    render() {\n        return `${this.title}<p>${this.body}</p>`;\n    }\n    getSummary() {\n        return this.body.substring(0, 100) + \"...\";\n    }\n}\n\nclass Video extends Content {\n    constructor(title, videoUrl) {\n        super();\n        this.title = title;\n        this.videoUrl = videoUrl;\n    }\n    render() {\n        return `${this.title}<video src='${this.videoUrl}' controls></video>`;\n    }\n    getSummary() {\n        return `${this.title} (Video)`;\n    }\n}\n\nclass ImageGallery extends Content {\n    constructor(title, images) {\n        super();\n        this.title = title;\n        this.images = images;\n    }\n    render() {\n        const imageTags = this.images.map(image => `<img src='${image}' />`).join('');\n        return `${this.title}${imageTags}`;\n    }\n    getSummary() {\n        return `${this.title} (${this.images.length} images)`;\n    }\n}\n\nclass Audio extends Content {\n    constructor(title, audioUrl) {\n        super();\n        this.title = title;\n        this.audioUrl = audioUrl;\n    }\n    render() {\n        return `${this.title}<audio src='${this.audioUrl}' controls></audio>`;\n    }\n    getSummary() {\n        return `${this.title} (Audio)`;\n    }\n}\n\nfunction displayContent(content) {\n    console.log(\"Rendering content:\");\n    console.log(content.render());\n    console.log(\"Summary:\");\n    console.log(content.getSummary());\n}\n\nconst article1 = new Article(\"My Article\", \"This is the body of my article.\");\nconst video1 = new Video(\"My Video\", \"http://example.com/video.mp4\");\nconst imageGallery1 = new ImageGallery(\"My Gallery\", [\"http://example.com/image1.jpg\", \"http://example.com/image2.jpg\"]);\nconst audio1 = new Audio(\"My Audio\", \"http://example.com/audio.mp3\");\n\ndisplayContent(article1);\ndisplayContent(video1);\ndisplayContent(imageGallery1);\ndisplayContent(audio1);\n\n\n////////// ---------------------------------------- EXTRA ---------------------------------------- ////////////////////\n\nclass Vehicle{\n    constructor(maxSpeed){\n        if(new.target === Vehicle){\n            throw new TypeError(\"Cannot construct Vehicle instances directly\");\n        }\n        this.currentSpeed = 0;\n        this.maxSpeed = maxSpeed\n    }\n    accelerate(increment){\n        throw new Error(\"Method 'accelerate()' must be implemented.\");\n    }\n    brake(decrement){\n        throw new Error(\"Method 'brake()' must be implemented.\");\n    }\n    toString() {\n        return \"Vehicle\"\n    }    \n}\n\nclass Car extends Vehicle{\n    constructor(maxSpeed){\n        super(maxSpeed);\n    }\n    accelerate(increment){\n        const newSpeed = this.currentSpeed + increment;\n        if(newSpeed <= this.maxSpeed){\n            this.currentSpeed = newSpeed;\n        }else{\n            this.currentSpeed = this.maxSpeed;\n        }\n    }\n    brake(decrement){\n        const newSpeed = this.currentSpeed - decrement;\n        if(newSpeed >=0){\n            this.currentSpeed = newSpeed;\n        }else{\n            this.currentSpeed = 0;\n        }\n    }\n    toString(){\n        return \"Auto\"\n    }\n}\n\nclass Motorcycle extends Vehicle{\n    constructor(maxSpeed){\n        super(maxSpeed);\n    }\n    accelerate(increment){\n        const newSpeed = this.currentSpeed + increment;\n        if(newSpeed <= this.maxSpeed){\n            this.currentSpeed = newSpeed;\n        }else{\n            this.currentSpeed = this.maxSpeed;\n        } \n    }\n    brake(decrement){\n        const newSpeed = this.currentSpeed - decrement;\n        if(newSpeed >=0){\n            this.currentSpeed = newSpeed;\n        }else{\n            this.currentSpeed = 0;\n        }\n    }\n    toString(){\n        return \"Motocicleta\"\n    }\n}\n\nclass Boat extends Vehicle{\n    constructor(maxSpeed){\n        super(maxSpeed);\n    }\n    accelerate(increment){\n        const newSpeed = this.currentSpeed + increment;\n        if(newSpeed <= this.maxSpeed){\n            this.currentSpeed = newSpeed;\n        }else{\n            this.currentSpeed = this.maxSpeed;\n        }\n    }\n    brake(decrement){\n        const newSpeed = this.currentSpeed - decrement;\n        if(newSpeed >=0){\n            this.currentSpeed = newSpeed;\n        }else{\n            this.currentSpeed = 0;\n        }\n    }\n    toString(){\n        return \"Bote\"\n    }\n}\n\nfunction testVehicle(vehicle){\n    console.log(`Datos: ${vehicle.toString()}:`);\n    console.log(`Velocidad inicial: ${vehicle.currentSpeed} km/h`);\n    vehicle.accelerate(50);\n    console.log(`Velocidad despues de acelerar: ${vehicle.currentSpeed} km/h`);\n    vehicle.brake(20);\n    console.log(`Velocidad despues de frenar: ${vehicle.currentSpeed} km/h`);\n}\n\nconst car = new Car(180);\nconst motorcycle = new Motorcycle(150);\nconst boat = new Boat(40);\n\ntestVehicle(car);\ntestVehicle(motorcycle);\ntestVehicle(boat);\n\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/javascript/DavidMoralesDeveloper.js",
    "content": "// Principio de Sustitución de Liskov (LSP) \n// \"Los objetos de un programa deben ser reemplazables por instancias de sus subtipos (o subclases) sin alterar la corrección de ese programa.\"\n\n// * DIFICULTAD EXTRA (opcional):\n//  * Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n//  * cumplir el LSP.\n//  * Instrucciones:\n//  * 1. Crea la clase Vehículo.\n//  * 2. Añade tres subclases de Vehículo.\n//  * 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n//  * 4. Desarrolla un código que compruebe que se cumple el LSP.\n\n// donde el subtipo puede sustituir completamente al tipo base sin cambiar su comportamiento observable para los clientes.\n\nclass Veiculo{\n\n}\nclass Volvo extends Veiculo{\n    acelerar(){console.log(\"acelerar\")}\n frenar(){console.log(\"frenarx\")}\n}\nclass Bmw extends Veiculo{\n    acelerar(){console.log(\"acelerar\")}\n frenar(){console.log(\"frenarx\")}\n}\nclass Renol extends Veiculo{\n    acelerar(){console.log(\"acelerar\")}\n frenar(){console.log(\"frenarx\")}\n}\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #28 - JavaScript -> Jesus Antonio Escamilla */\n\n/**\n * Principio de Segregación de Interfaces: Una clase no debe estar obligada a implementar interfaces que no usa.\n * En lugar de tener una interfaz grande y general, se deben tener varias interfaces específicas y pequeñas.\n * Este principio establece que los objetos de una clase derivada deben poder ser sustituidos por objetos de la\n   clase base sin alterar el funcionamiento del programa.\n */\n\n//---EJERCIÓ---\n//INCORRECTO\nclass Bird_{\n   fly(){\n      throw new Error(\"This method should be overridden\");\n   }\n}\n\nclass Eagle_ extends Bird_{\n   fly(){\n      return \"Eagle flying high!\";\n   }\n}\n\nclass Penguin_ extends Bird_{\n   fly(){\n      return\"Penguin can't flying!\";\n   }\n}\n\nconst eagle_ = new Eagle_();\nconst penguin_ = new Penguin_();\n\nconsole.log(eagle_.fly());\nconsole.log(penguin_.fly());\n\n\n//CORRECTO\nclass Bird{\n   move(){\n      throw new Error(\"This method should be overridden\");\n   }\n}\n\nclass Eagle extends Bird{\n   move(){\n      console.log(\"Eagle is Walking!!\");\n   }\n}\n\nclass Penguin extends Bird{\n   move(){\n      console.log(\"Penguin is Walking!!\");\n   }\n}\n\nfunction makeBirdMove(bird) {\n   bird.move();\n}\n\nconst eagle = new Eagle();\nconst penguin = new Penguin();\n\nmakeBirdMove(eagle);\nmakeBirdMove(penguin);\n\n\n\n/**-----DIFICULTAD EXTRA-----*/\n\n// Creando la clase\nclass Vehículos{\n   constructor(){\n      this.speed = 0;\n   }\n\n   acelerar(){\n      throw new Error(\"Método 'acelerar' debe ser implementado\");\n   }\n\n   frenar(){\n      throw new Error(\"Método 'frenar' debe ser implementado\");\n   }\n\n   getSpeed(){\n      return this.speed;\n   }\n}\n\n// Sub-clases la clase principal\nclass Coche extends Vehículos{\n   acelerar(speed){\n      console.log(`El coche esta acelerando, con ${speed} km/h`);\n   }\n\n   frenar(speed){\n      console.log(`El coche esta frenando, con ${speed} km/h`);\n   }\n}\n\nclass Trailer extends Vehículos{\n   acelerar(speed){\n      console.log(`El tailer esta acelerando, con ${speed} km/h`);\n   }\n\n   frenar(speed){\n      console.log(`El trailer esta frenando, con ${speed} km/h`);\n   }\n}\n\nclass Moto extends Vehículos{\n   acelerar(speed){\n      console.log(`El moto esta acelerando, con ${speed} km/h`);\n   }\n\n   frenar(speed){\n      console.log(`El moto esta frenando, con ${speed} km/h`);\n   }\n}\n\n// Comprobación del LSP\nfunction pruebaLSP(vehículo) {\n   vehículo.acelerar(2);\n   vehículo.frenar(1);\n}\n\n// Ejemplo LSP\nconst coche = new Coche();\nconst trailer = new Trailer();\nconst moto = new Moto();\n\n// console.log(\"Prueba con Coche:\");\npruebaLSP(coche);\n\n// console.log(\"Prueba con Trailer:\");\npruebaLSP(trailer);\n\n// console.log(\"Prueba con Moto:\");\npruebaLSP(moto);\n\n/**-----DIFICULTAD EXTRA-----*/"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/javascript/RaulDoezon.js",
    "content": "/*\n  EJERCICIO:\n  Explora el \"Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)\" \n  y crea un ejemplo simple donde se muestre su funcionamiento\n  de forma correcta e incorrecta.\n*/\n\nconsole.log(\"+++++++++ FORMA INCORRECTA +++++++++\");\n\nclass AnimalProof {\n  eat() {\n    console.log('El animal está comiendo');\n  }\n}\n\nclass BirdProof extends AnimalProof {\n  fly() {\n    console.log('El ave está volando');\n  }\n}\n\nclass OstrichProof extends BirdProof {\n  fly() {\n    throw new Error('Las avestruces no pueden volar');\n  }\n}\n\nconst birdProof = new OstrichProof();\nbirdProof.eat();\n// birdProof.fly();\n\nconsole.log(\"\\n+++++++++ FORMA CORRECTA +++++++++\");\n\nclass Animal {\n  eat() {\n    console.log('El animal está comiendo');\n  }\n}\n\nclass Bird extends Animal {\n  fly() {\n    console.log('El ave está volando');\n  }\n}\n\nclass Ostrich extends Animal {}\n\nconst bird = new Bird();\nbird.eat();\nbird.fly();\n\nconst ostrich = new Ostrich();\nostrich.eat();\n\n/*\n  DIFICULTAD EXTRA (opcional):\n  Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n  cumplir el LSP.\n  Instrucciones:\n  1. Crea la clase Vehículo.\n  2. Añade tres subclases de Vehículo.\n  3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n  4. Desarrolla un código que compruebe que se cumple el LSP.\n*/\n\nconsole.log(\"\\n+++++++++ JERARQUÍA DE VEHÍCULOS +++++++++\");\n\nclass Vehiculo {\n  constructor() {\n    this.speed = 0;\n  }\n\n  speedUp(acceleration) {\n    this.speed += acceleration;\n\n    console.log(`Acelerando. Velocidad a ${this.speed} km/h`);\n  }\n\n  curb(deceleration) {\n    this.speed -= deceleration;\n\n    console.log(`Frenando. Velocidad a ${this.speed} km/h`);\n  }\n}\n\nclass Carro extends Vehiculo {\n  constructor(acceleration, deceleration) {\n    super(acceleration, deceleration);\n  }\n}\n\nclass Bicicleta extends Vehiculo {\n  constructor(acceleration, deceleration) {\n    super(acceleration, deceleration);\n  }\n}\n\nclass Patineta extends Vehiculo {\n  constructor(acceleration, deceleration) {\n    super(acceleration, deceleration);\n  }\n}\n\nconst car = new Carro();\nconst skateboard = new Patineta();\nconst bicycle =  new Bicicleta();\n\nfunction testingVehicle(vehicle) {\n  console.log(`\\n- ${vehicle.constructor.name}:`);\n\n  vehicle.speedUp(10);\n  vehicle.curb(5);\n}\n\ntestingVehicle(bicycle);\ntestingVehicle(skateboard);\ntestingVehicle(car);\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/javascript/RicJDev.js",
    "content": "//EJERCICIO\nconsole.log('\\nSin LSP');\nclass RectangleNoLSP {\n\tconstructor(height, width) {\n\t\tthis.height = height;\n\t\tthis.width = width;\n\t}\n\n\tgetArea() {\n\t\treturn this.height * this.width;\n\t}\n\n\trotateToVerticalPosition() {\n\t\tlet changeValue = this.height;\n\n\t\tif (this.width > this.height) {\n\t\t\tthis.height = this.width;\n\t\t\tthis.width = changeValue;\n\t\t}\n\t}\n\n\tcheckVerticalPosition() {\n\t\tif (this.height > this.width) {\n\t\t\tconsole.log('Está en posición vertical');\n\t\t} else {\n\t\t\tconsole.log('No está en posición vertical');\n\t\t}\n\t}\n}\n\nclass SquareNoLSP extends RectangleNoLSP {\n\tconstructor(side) {\n\t\tsuper(side, side);\n\t}\n}\n\nconst rectangleNoLSP = new RectangleNoLSP(3, 4);\nconst squareNoLSP = new SquareNoLSP(5);\n\nconsole.log('Área del círculo:', squareNoLSP.getArea());\nconsole.log('Área del rectángulo:', rectangleNoLSP.getArea());\n\nconsole.log(rectangleNoLSP.height);\nrectangleNoLSP.checkVerticalPosition();\n\nrectangleNoLSP.rotateToVerticalPosition();\n\nconsole.log(rectangleNoLSP.height);\nrectangleNoLSP.checkVerticalPosition();\n\nconsole.log(squareNoLSP.height);\nsquareNoLSP.checkVerticalPosition();\n\nsquareNoLSP.rotateToVerticalPosition();\n\nconsole.log(squareNoLSP.height);\nsquareNoLSP.checkVerticalPosition();\n\n/*\nEn el ejemplo anterior vemos que, si bien un cuadrado podría ser similar a un rectángulo, no son exactamente lo mismo y no se comportan igual. Como esto no se ha tenido en cuenta para el diseño de las clases, al invocar los métodos para ponerlo en posición vertical y verificar si ya lo está, el programa no funciona como debería, lo que en un caso más complejo acarrearía problemas para la reutilización del código y su mantenimiento.\n*/\n\nconsole.log('\\nCon LSP');\nclass Quadrilateral {\n\tconstructor(height, width) {\n\t\tthis.height = height;\n\t\tthis.width = width;\n\t}\n\n\tgetArea() {\n\t\treturn this.height * this.width;\n\t}\n}\n\nclass Rectangle extends Quadrilateral {\n\tconstructor(height, width) {\n\t\tsuper(height, width);\n\t}\n\n\trotateToVerticalPosition() {\n\t\tlet changeValue = this.height;\n\n\t\tif (this.width > this.height) {\n\t\t\tthis.height = this.width;\n\t\t\tthis.width = changeValue;\n\t\t}\n\t}\n\n\tcheckVerticalPosition() {\n\t\tif (this.height > this.width) {\n\t\t\tconsole.log('Está en posición vertical');\n\t\t} else {\n\t\t\tconsole.log('No está en posición vertical');\n\t\t}\n\t}\n}\n\nclass Square extends Quadrilateral {\n\tconstructor(side) {\n\t\tsuper(side, side);\n\t}\n}\n\nconst quadrilateral = new Quadrilateral(12, 10);\nconst rectangle = new Rectangle(10, 23);\nconst square = new Square(10);\n\nconsole.log('Área de un cuadrilátero abstracto:', quadrilateral.getArea());\nconsole.log('Área de un rectángulo:', rectangle.getArea());\nconsole.log('Área de un cuadrado:', square.getArea());\n\n/*\n\"Si S es un subtipo de T, entonces los objetos de tipo T en un programa de computadora pueden ser sustituidos por objetos de tipo S, sin alterar ninguna de las propiedades deseables de ese programa.\"\n\nEn este caso, la capacidad de ponerse en posición vertical es única del rectángulo, y si fuera necesario sustituir un cuadrilátero cualquiera por un rectángulo, seguirán funcionando todos los métodos de la clase del cuadrilátero. Cierto que aquí solo se calcula el área de la figura, pero en un caso más complejo esto es de mucha ayuda y ahorra trabajo. \n*/\n\n//EXTRA\nconsole.log('\\nJerarquía de vehículos');\nclass Vehicle {\n\tconstructor() {\n\t\tthis.speed = 0;\n\t}\n\n\taccelerate(amount) {\n\t\tthis.speed += amount * 1.2;\n\t}\n\n\tbrake(amount) {\n\t\tthis.speed -= amount * 0.8;\n\n\t\tif (this.speed < 0) {\n\t\t\tthis.speed = 0;\n\t\t}\n\t}\n}\n\nclass Motorcycle extends Vehicle {\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\taccelerate(amount) {\n\t\tthis.speed += amount * 1.5;\n\t}\n\n\tbrake(amount) {\n\t\tthis.speed -= amount * 1.2;\n\n\t\tif (this.speed < 0) {\n\t\t\tthis.speed = 0;\n\t\t}\n\t}\n}\n\nclass Car extends Vehicle {\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\taccelerate(amount) {\n\t\tthis.speed += amount * 1.6;\n\t}\n\n\tbrake(amount) {\n\t\tthis.speed -= amount * 1.3;\n\n\t\tif (this.speed < 0) {\n\t\t\tthis.speed = 0;\n\t\t}\n\t}\n}\n\nclass SciFiTurboCar extends Vehicle {\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\taccelerate(amount) {\n\t\tthis.speed += amount * 3;\n\t}\n\n\tbrake(amount) {\n\t\tthis.speed -= amount * 2.5;\n\n\t\tif (this.speed < 0) {\n\t\t\tthis.speed = 0;\n\t\t}\n\t}\n}\n\nfunction checkLSP(vehicle) {\n\tif (!vehicle.accelerate || !vehicle.brake) {\n\t\tthrow new Error('El objeto no cumple con la interfaz de Vehículo');\n\t}\n\n\tvehicle.accelerate(78);\n\tvehicle.brake(4);\n\n\tconsole.log(vehicle);\n}\n\nconst vehicle = new Vehicle();\nconst toyota = new Car();\nconst jaguar = new Motorcycle();\nconst hypercar3000 = new SciFiTurboCar();\n\ncheckLSP(vehicle);\ncheckLSP(toyota);\ncheckLSP(jaguar);\ncheckLSP(hypercar3000);\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/javascript/Sac-Corts.js",
    "content": "// Wrong way\nclass Bird { \n    fly() {\n        console.log('Flying!');\n    }\n}\n\nclass Penguin extends Bird {\n    fly() {\n        throw new Error('Penguins cannot fly!');\n    }\n}\n\nfunction makeBirdFly(bird) {\n    bird.fly();\n}\n\nconst bird = new Bird();\nconst penguin = new Penguin();\n\nmakeBirdFly(bird);\n// makeBirdFly(penguin); // Not working //\n\n// Correct way\nclass Bird2 {\n    eat() {\n        console.log('Eating...');\n    }\n}\n\nclass FlyingBird extends Bird2 {\n    fly() {\n        console.log('Flying!');\n    }\n}\n\nclass Penguin2 extends Bird2 {\n    swin() {\n        console.log('Swimming!');\n    }\n}\n\nfunction makeFlyingBirdFly(bird) {\n    bird.fly();\n}\n\nconst eagle = new FlyingBird();\nconst penguin2 = new Penguin2();\n\nmakeFlyingBirdFly(eagle);\n// makeBirdFly(penguin); // Not working //\n\n// Extra Exercise //\nclass Vehicle {\n    accelerate() {\n        throw new Error('accelerate() must be implemented');\n    }\n\n    brake() {\n        throw new Error('brake() must be implemented'); \n    }\n}\n\nclass Car extends Vehicle {\n    accelerate() {\n        console.log('Car is accelerating');\n    }\n\n    brake() {\n        console.log('Car is braking');\n    }\n}\n\nclass Motorcycle extends Vehicle {\n    accelerate() {\n        console.log('Motorcycle is accelerating');\n    }\n\n    brake() {\n        console.log('Motorcycle is braking');\n    }\n}\n\nclass Bicycle extends Vehicle {\n    accelerate() {\n        console.log('Bicycle is accelerating');\n    }\n\n    brake() {\n        console.log('Bicycle is braking');\n    }\n}\n\nfunction testVehicle(vehicle) {\n    vehicle.accelerate();\n    vehicle.brake();\n}\n\nconst car = new Car();\nconst motorcycle = new Motorcycle();\nconst bicycle = new Bicycle();\n\ntestVehicle(car);\ntestVehicle(motorcycle);\ntestVehicle(bicycle);\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/javascript/adrs1166ma.js",
    "content": "/* 🔥 EJERCICIO:\nExplora el \"Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)\" \ny crea un ejemplo simple donde se muestre su funcionamiento\nde forma correcta e incorrecta.\n*/\n\nconsole.log(\"----- EJEMPLO SIMPLE -----\");\n\n//  * Ejemplo Incorrecto (viola LSP)\n// --------------------------------------------------------------------------------------------------------------\nclass Rectangle {\n    constructor(width, height) {\n        this.width = width;\n        this.height = height;\n    }\n\n    setWidth(width) {\n        this.width = width;\n    }\n\n    setHeight(height) {\n        this.height = height;\n    }\n\n    area() {\n        return this.width * this.height;\n    }\n}\n\nclass Square extends Rectangle {\n    constructor(side) {\n        super(side, side);\n    }\n\n    // Override que rompe el comportamiento esperado\n    setWidth(side) {\n        this.width = side;\n        this.height = side; // Modifica ambos lados\n    }\n\n    setHeight(side) {\n        this.width = side;\n        this.height = side; // Modifica ambos lados\n    }\n}\n\n// Función que espera un Rectangle (pero falla con Square)\nfunction printArea(rectangle) {\n    rectangle.setWidth(5);\n    rectangle.setHeight(4);\n    console.log(`Área esperada: 20, Área real: ${rectangle.area()}`);\n}\n\n// Violación de LSP: El cuadrado no se comporta como un rectángulo\nconst rect = new Rectangle(5, 5);\nconst square = new Square(5);\nprintArea(rect); // Área: 20 (correcto)\nprintArea(square); // Área: 16 (incorrecto, viola LSP)\n\n//  * Ejemplo Correcto (cumple LSP)\n// --------------------------------------------------------------------------------------------------------------\nclass Shape {\n    area() {\n        throw new Error(\"Método no implementado.\");\n    }\n}\n\nclass RectangleCorrecto extends Shape {\n    constructor(width, height) {\n        super();\n        this.width = width;\n        this.height = height;\n    }\n\n    setWidth(width) {\n        this.width = width;\n    }\n\n    setHeight(height) {\n        this.height = height;\n    }\n\n    area() {\n        return this.width * this.height;\n    }\n}\n\nclass SquareCorrecto extends Shape {\n    constructor(side) {\n        super();\n        this.side = side;\n    }\n\n    setSide(side) {\n        this.side = side;\n    }\n\n    area() {\n        return this.side * this.side;\n    }\n}\n\n// Función que cumple LSP\nfunction printAreaLSP(shape) {\n    console.log(`Área: ${shape.area()}`);\n}\n\n// Uso correcto\nconst rectLSP = new RectangleCorrecto(5, 4);\nconst squareLSP = new SquareCorrecto(5);\nprintAreaLSP(rectLSP); // Área: 20\nprintAreaLSP(squareLSP); // Área: 25\n\n// --------------------------------------------------------------------------------------------------------------\n/* 🔥 DIFICULTAD EXTRA (opcional):\nCrea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\ncumplir el LSP.\nInstrucciones:\n1. Crea la clase Vehículo.\n2. Añade tres subclases de Vehículo.\n3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n4. Desarrolla un código que compruebe que se cumple el LSP.\n*/\nconsole.log(\"\\n----- JERARQUÍA DE VEHÍCULOS (LSP) -----\");\n\n// Clase base: Vehículo\nclass Vehiculo {\n    constructor() {\n        this.velocidad = 0;\n    }\n\n    acelerar() {\n        throw new Error(\"Método no implementado.\");\n    }\n\n    frenar() {\n        throw new Error(\"Método no implementado.\");\n    }\n\n    mostrarVelocidad() {\n        return `Velocidad: ${this.velocidad} km/h`;\n    }\n}\n\n// Subclase 1: Coche\nclass Coche extends Vehiculo {\n    acelerar() {\n        this.velocidad += 10;\n        console.log(\"Coche acelerando...\");\n    }\n\n    frenar() {\n        this.velocidad -= 5;\n        if (this.velocidad < 0) this.velocidad = 0;\n        console.log(\"Coche frenando...\");\n    }\n}\n\n// Subclase 2: Bicicleta\nclass Bicicleta extends Vehiculo {\n    acelerar() {\n        this.velocidad += 3;\n        console.log(\"Bicicleta pedaleando...\");\n    }\n\n    frenar() {\n        this.velocidad -= 2;\n        if (this.velocidad < 0) this.velocidad = 0;\n        console.log(\"Bicicleta frenando...\");\n    }\n}\n\n// Subclase 3: Motocicleta\nclass Motocicleta extends Vehiculo {\n    acelerar() {\n        this.velocidad += 15;\n        console.log(\"Motocicleta acelerando...\");\n    }\n\n    frenar() {\n        this.velocidad -= 7;\n        if (this.velocidad < 0) this.velocidad = 0;\n        console.log(\"Motocicleta frenando...\");\n    }\n}\n\n// Función que cumple LSP: Trabaja con cualquier vehículo\nfunction probarVehiculo(vehiculo) {\n    console.log(`Probando ${vehiculo.constructor.name}:`);\n    vehiculo.acelerar();\n    vehiculo.acelerar();\n    vehiculo.frenar();\n    console.log(vehiculo.mostrarVelocidad());\n}\n\n// Crear vehículos\nconst coche = new Coche();\nconst bicicleta = new Bicicleta();\nconst moto = new Motocicleta();\n\n// Probar cada vehículo (sin errores)\nprobarVehiculo(coche); // Velocidad: 15 km/h\nprobarVehiculo(bicicleta); // Velocidad: 4 km/h\nprobarVehiculo(moto); // Velocidad: 23 km/h\n\n//  * Comprobación de LSP\n// --------------------------------------------------------------------------------------------------------------\n// Si sustituimos Vehiculo por cualquier subclase, el comportamiento es consistente\nconst vehiculos = [coche, bicicleta, moto];\nvehiculos.forEach(vehiculo => {\n    probarVehiculo(vehiculo);\n    console.log(\"-----\");\n});"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/javascript/caterinarodriguezdev.js",
    "content": "/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)\"\n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n * cumplir el LSP.\n * Instrucciones:\n * 1. Crea la clase Vehículo.\n * 2. Añade tres subclases de Vehículo.\n * 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n * 4. Desarrolla un código que compruebe que se cumple el LSP.\n */\n\nclass Ball {\n  bounce() {\n    console.log('La pelota rebota');\n  }\n}\n\nclass BowlingBall extends Ball {\n  bounce() {\n    throw new Error('La bola de bolos no puede rebotar')\n  }\n} \n\nclass BallLSP {\n  throw() {\n    console.log('Tira la bola');\n  }\n}\n\nclass BowlingBallLSP extends Ball {\n  throw() {\n    console.log('Tira la bola hacia los bolos');\n  }\n}\n\nclass Vehiculo {\n  constructor() {\n      this.velocidad = 0;\n  }\n\n  acelerar(incremento) {\n      this.velocidad += incremento;\n      console.log(`Acelerando: Velocidad actual = ${this.velocidad} km/h`);\n  }\n\n  frenar(decremento) {\n      this.velocidad = Math.max(0, this.velocidad - decremento);\n      console.log(`Frenando: Velocidad actual = ${this.velocidad} km/h`);\n  }\n}\n\nclass Coche extends Vehiculo {\n  constructor(marca) {\n      super();\n      this.marca = marca;\n  }\n\n  acelerar(incremento) {\n      super.acelerar(incremento);\n      console.log(`El coche ${this.marca} ha acelerado.`);\n  }\n}\n\nclass Bicicleta extends Vehiculo {\n  constructor(tipo) {\n      super();\n      this.tipo = tipo;\n  }\n\n  acelerar(incremento) {\n      super.acelerar(incremento);\n      console.log(`La bicicleta de tipo ${this.tipo} ha acelerado.`);\n  }\n}\n\nclass Motocicleta extends Vehiculo {\n  constructor(modelo) {\n      super();\n      this.modelo = modelo;\n  }\n\n  acelerar(incremento) {\n      super.acelerar(incremento);\n      console.log(`La motocicleta modelo ${this.modelo} ha acelerado.`);\n  }\n}\n\nfunction probarVehiculo(vehiculo) {\n  vehiculo.acelerar(20);\n  vehiculo.frenar(10);\n}\n\nconst miCoche = new Coche('Toyota');\nconst miBicicleta = new Bicicleta('Montaña');\nconst miMotocicleta = new Motocicleta('Yamaha');\n\nprobarVehiculo(miCoche);\nprobarVehiculo(miBicicleta);\nprobarVehiculo(miMotocicleta);"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/javascript/duendeintemporal.js",
    "content": "//#28 - Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)\"\n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n * cumplir el LSP.\n * Instrucciones:\n * 1. Crea la clase Vehículo.\n * 2. Añade tres subclases de Vehículo.\n * 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n * 4. Desarrolla un código que compruebe que se cumple el LSP.\n */\n\n/* The Liskov Substitution Principle (LSP) is one of the five SOLID principles of object-oriented programming. This principle states that objects of a derived class should be able to replace objects of the base class without altering the correctness of the program. */\n\nlet log = console.log;\n\nwindow.addEventListener('load', ()=>{\n    const body = document.querySelector('body');\n    const title = document.createElement('h1');\n    \n    body.style.setProperty('background', '#000');\n    body.style.setProperty('text-align', 'center');\n    \n    title.textContent = 'Retosparaprogramadores #28.';\n    title.style.setProperty('font-size', '3.5vmax');\n    title.style.setProperty('color', '#fff');\n    title.style.setProperty('line-height', '100vh');\n    \n    body.appendChild(title);\n    \n    setTimeout(()=>{\n    alert('Retosparaprogramadores #28. Please open the Browser Developer Tools.');\n    }, 2000);\n    log( 'Retosparaprogramadores #28'); \n});\n\n\nclass Shape {\n    area() {\n        throw new Error(\"Method 'area' must be implemented\");\n    }\n}\n\nclass Rectangle extends Shape {\n    constructor(width, height) {\n        super();\n        this.width = width;\n        this.height = height;\n    }\n\n    area() {\n        return this.width * this.height;\n    }\n}\n\nclass Square extends Shape {\n    constructor(side) {\n        super();\n        this.side = side;\n    }\n\n    area() {\n        return this.side * this.side;\n    }\n}\n\nconst calculateArea = (shape)=> {\n    return shape.area();\n}\n\nconst rectangle = new Rectangle(83, 105);\nconst square = new Square(40);\n\nlog(calculateArea(rectangle)); // 8715\nlog(calculateArea(square)); // 1600   \n\n//Extra Dificulty Exercise\n\nclass Car {\n    constructor(brand, model, maxSpeed, acceleration, deceleration) {\n        this.brand = brand;\n        this.model = model;\n        this.maxSpeed = maxSpeed; // Maximum speed in km/h\n        this.acceleration = acceleration; // Acceleration in km/h per second\n        this.deceleration = deceleration; // Deceleration in km/h per second\n        this.currentSpeed = 0; // Current speed in km/h\n    }\n\n    accelerate(seconds) {\n        const newSpeed = this.currentSpeed + (this.acceleration * seconds);\n        this.currentSpeed = Math.min(newSpeed, this.maxSpeed);\n        log(`${this.brand} ${this.model} accelerated to ${this.currentSpeed} km/h.`);\n    }\n\n    brake(seconds) {\n        const newSpeed = this.currentSpeed - (this.deceleration * seconds);\n        this.currentSpeed = Math.max(newSpeed, 0);\n        log(`${this.brand} ${this.model} braked to ${this.currentSpeed} km/h.`);\n    }\n}\n\nclass SportsCar extends Car {\n    constructor(brand, model) {\n        super(brand, model, 300, 30, 20); \n    }\n}\n\nclass FamilyCar extends Car {\n    constructor(brand, model) {\n        super(brand, model, 200, 15, 10); \n    }\n}\n\nfunction testCar(car) {\n    car.accelerate(5); \n    car.brake(2);      \n}\n\n\n\nconst sportsCars = [\n    {\n        brand: \"Ferrari\",\n        model: \"488\",\n        maxSpeed: 330,\n        acceleration: 30, \n        deceleration: 20,            \n    },\n    {\n        brand: \"Porsche\",\n        model: \"911 Turbo S\",\n        maxSpeed: 320, \n        acceleration: 28, \n        deceleration: 18,            \n    },\n    {\n        brand: \"Lamborghini\",\n        model: \"Huracán\",\n        maxSpeed: 325,\n        acceleration: 32, \n        deceleration: 22,            \n    }\n];\n\nconst familyCars = [\n    {\n        brand: \"Toyota\",\n        model: \"Sienna\",\n        maxSpeed: 180,\n        acceleration: 10, \n        deceleration: 8,           \n    },\n    {\n        brand: \"Honda\",\n        model: \"Odyssey\",\n        maxSpeed: 175,\n        acceleration: 9,  \n        deceleration: 7,              \n    },\n    {\n        brand: \"Chrysler\",\n        model: \"Pacifica\",\n        maxSpeed: 180,\n        acceleration: 9,  \n        deceleration: 7,              \n    }\n];\n\n\nconst sportsCar = new SportsCar(...Object.values(sportsCars[0]));\nconst familyCar = new FamilyCar(...Object.values(familyCars[1]));\n\ntestCar(sportsCar); //Ferrari 488 accelerated to 150 km/h.\n// Ferrari 488 braked to 110 km/h.\ntestCar(familyCar); // Honda Odyssey accelerated to 75 km/h.\n// Honda Odyssey braked to 55 km/h.\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/javascript/hectorio23.js",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\n\"use strict\";\n\n// Clase base abstracta para todos los vehículos. Define dos métodos abstractos\n// que deben ser implementados por las subclases: acelerar y frenar.\nclass Vehiculo {\n    /**\n     * Método abstracto para acelerar. Debe ser implementado por las subclases.\n     * @throws {Error} Si no se implementa en una subclase.\n     */\n    acelerar() {\n        throw new Error(\"Este método debe ser implementado por una subclase.\");\n    }\n\n    /**\n     * Método abstracto para frenar. Debe ser implementado por las subclases.\n     * @throws {Error} Si no se implementa en una subclase.\n     */\n    frenar() {\n        throw new Error(\"Este método debe ser implementado por una subclase.\");\n    }\n}\n\n// Clase que representa un coche. Implementa los métodos acelerar y frenar\n// de acuerdo a la interfaz definida por la clase base Vehiculo.\nclass Coche extends Vehiculo {\n    acelerar() {\n        return \"[+] - El coche está acelerando.\";\n    }\n\n    frenar() {\n        return \"[+] - El coche está frenando.\";\n    }\n}\n\n// Clase que representa una bicicleta. Implementa los métodos acelerar y frenar\n// de acuerdo a la interfaz definida por la clase base Vehiculo.\nclass Bicicleta extends Vehiculo {\n    acelerar() {\n        return \"[+] - La bicicleta está acelerando.\";\n    }\n\n    frenar() {\n        return \"[+] - La bicicleta está frenando.\";\n    }\n}\n\n// Clase que representa un avión. Implementa los métodos acelerar y frenar\n// de acuerdo a la interfaz definida por la clase base Vehiculo.\nclass Avion extends Vehiculo {\n    acelerar() {\n        return \"[+] - El avión está acelerando.\";\n    }\n\n    frenar() {\n        return \"[+] - El avión está frenando.\";\n    }\n}\n\n/**\n * Función para probar el principio de sustitución de Liskov (LSP). \n * Toma un objeto Vehiculo y llama a sus métodos acelerar y frenar.\n * \n * @param {Vehiculo} vehiculo - Una instancia de una subclase de Vehiculo.\n */\nfunction testLSP(vehiculo) {\n    console.log(vehiculo.acelerar());\n    console.log(vehiculo.frenar());\n}\n\n// Lista de diferentes vehículos que cumplen con el LSP\nconst vehiculos = [new Coche(), new Bicicleta(), new Avion()];\n\n// Probar cada vehículo para asegurar que cumplen con el LSP\nvehiculos.forEach(vehiculo => testLSP(vehiculo));\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/javascript/jjaljuria.js",
    "content": "/**\n * Principio de sustitución de Liskov\n * puede definirse como: Cada clase que hereda de otra puede usarse como su padre sin necesidad de conocer las diferencias entre ellas.\n *\n * Fuente: https://es.wikipedia.org/wiki/Principio_de_sustituci%C3%B3n_de_Liskov\n */\n\n// Tenemos una clase Cocinero que prepara los diferentes platillos de un restaurante,\n// una clase Comida que sirve de base para todos los tipos de platillos,\n// una clase Pizza y Sopa que heredan de la clase Comida\n\n// INCORRECTA\nclass Comida{\n    constructor(ingredientes){\n        if(!Array.isArray(ingredientes)) throw new Error('ingredientes debe ser un arreglo de strings')\n\n        this.ingredientes = ingredientes\n    }\n}\n\nclass Pizza extends Comida{\n    hornear(){\n        console.log('Horneando...');\n        console.log('Horneado Terminado!')\n    }\n}\n\nclass Sopa extends Comida{\n    hervir(){\n        console.log('Hirviendo...');\n        console.log('Hervido Terminado!')\n    }\n}\n\nclass Cocinero{\n    hacerPlatillo(comida){\n        // agregar ingredientes\n        console.log(`Preparando ${comida.constructor.name}`);\n\n\n        comida.ingredientes.forEach((ingrediente) => console.log(`añadir ${ingrediente}`))\n\n        /**\n         *  Al tener Pizza y Sopa métodos diferentes necesarios para su preparación\n         *  tenemos que rompemos el LSP debido a que no podemos usarlas indistintamente sino\n         *  que debemos diferenciarlas.\n         */\n        if(comida instanceof Pizza) comida.hornear()\n\n        if(comida instanceof Sopa) comida.hervir()\n\n        console.log('Platillo listo!!!');\n    }\n}\n\nconst cocinero = new Cocinero()\n\ncocinero.hacerPlatillo(new Pizza(['harina', 'agua', 'queso', 'peperoni']))\ncocinero.hacerPlatillo(new Sopa(['agua', 'papa', 'zanahoria', 'sal']))\n\nCORRECTA\nclass Comida{\n    constructor(ingredientes){\n        if(!Array.isArray(ingredientes)) throw new Error('ingredientes debe ser un arreglo de strings')\n\n        this.ingredientes = ingredientes\n    }\n\n    preparar(){ }\n}\n\nclass Pizza extends Comida{\n    preparar() {\n        this.hornear()\n    }\n\n    hornear(){\n        console.log('Horneando...');\n        console.log('Horneado Terminado!')\n    }\n}\n\nclass Sopa extends Comida{\n    preparar(){\n        this.hervir()\n    }\n\n    hervir(){\n        console.log('Hirviendo...');\n        console.log('Hervido Terminado!')\n    }\n}\n\nclass Cocinero{\n    cocinarPlatillo(comida){\n        // agregar ingredientes\n        console.log(`Preparando ${comida.constructor.name}`);\n\n\n        comida.ingredientes.forEach((ingrediente) => console.log(`añadir ${ingrediente}`))\n\n        /**\n         *  Agregando el método preparar en la clase Comida y abstrayendo el cómo se prepara la comida\n         *  podemos cumplir con el LSP, de modo de que no nos preocupamos por el tipo de la comida.\n         */\n        comida.preparar()\n\n        console.log('Platillo listo!!!');\n    }\n}\n\nconst cocinero = new Cocinero()\n\ncocinero.hacerPlatillo(new Pizza(['harina', 'agua', 'queso', 'peperoni']))\ncocinero.hacerPlatillo(new Sopa(['agua', 'papa', 'zanahoria', 'sal']))\n\n\n// EXTRA\n\nclass Vehiculo {\n    constructor({maxVelocidad, unidadVelocidad}){\n        if(typeof(maxVelocidad) !== 'number') throw new Error('maxVelocidad debe ser un number')\n        if(typeof(unidadVelocidad) !== 'string') throw new Error('unidadVelocidad debe ser un string')\n\n        this.maxVelocidad = maxVelocidad\n        this.unidadVelocidad = unidadVelocidad\n        this.velocidad = 0\n    }\n\n    acelerar(aumento){\n        if(this.velocidad + aumento > this.maxVelocidad){\n            console.log('Velocidad Maxima alcanzada no se puede acelerar más')\n            return\n        }\n        \n        this.velocidad += aumento\n        console.log(`Velocidad actual ${this.velocidad} ${this.unidadVelocidad}`)\n    }\n\n    frenar(){\n        this.velocidad = 0\n        console.log('Frenado Exitoso')\n    }\n}\n\nclass NaveEspacial extends Vehiculo{\n    constructor(props){\n        super(props)\n    }\n    despegar(){\n        console.log('Despegue')\n    }\n}\n\nclass Automovil extends Vehiculo{\n    constructor(props){\n        super(props)\n    }\n}\n\nclass Barco extends Vehiculo{\n    constructor(props){\n        super(props)\n    }\n    subirAncla(){\n        console.log('Ancla subida')\n    }\n    bajarAncla(){\n        console.log('Ancla bajada')\n    }\n}\n\nconst vehiculos = []\n\nvehiculos.push(new NaveEspacial({\n    maxVelocidad: 10,\n    unidadVelocidad: 'años luz'\n}))\n\nvehiculos.push(new Automovil({\n    maxVelocidad: 200,\n    unidadVelocidad: 'kilomentos'\n}))\n\nvehiculos.push(new NaveEspacial({\n    maxVelocidad: 100,\n    unidadVelocidad: 'milla nautica'\n}))\n\n// Como se puede ver aunque cada subclase tiene suspropios metodos, todas pueden ser reemplazadas por su \n// clase base de ser necesario sin problemas.\n\nvehiculos.forEach(vehiculo => {\n    vehiculo.acelerar(10)\n    vehiculo.frenar()\n    vehiculo.acelerar(100)\n})\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n___________________________________________________\n#28 SOLID: PRINCIPIO DE SUSTITUCIÓN DE LISKOV (LSP)\n---------------------------------------------------\n * EJERCICIO:\n * Explora el \"Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)\"\n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n * cumplir el LSP.\n * Instrucciones:\n * 1. Crea la clase Vehículo.\n * 2. Añade tres subclases de Vehículo.\n * 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n * 4. Desarrolla un código que compruebe que se cumple el LSP.\n*/\n// ________________________________________________________\n// Base\nclass Animal {\n    constructor(name) {\n        if (new.target === Animal) {\n            throw new Error(\"No se puede instanciar una clase abstracta.\");\n        }\n        this.name = name;\n    }\n\n    makeSound() {\n        throw new Error(\"El método 'makeSound' debe ser implementado.\");\n    }\n}\n\n// Clases derivadas\nclass Dog extends Animal {\n    makeSound() {\n        return `${this.name} hace Woof`;\n    }\n}\n\nclass Cat extends Animal {\n    makeSound() {\n        return `${this.name} hace Meow`;\n    }\n}\n\n// _____________________\n// Pruebas\nconst dog = new Dog(\"Max\");\nconsole.log(dog.makeSound()); // Max hace Woof\n\nconst cat = new Cat(\"Milo\");\nconsole.log(cat.makeSound()); // Milo hace Meow\n\n// ________________________________________________________\n// DIFICULTAD EXTRA\n// ----------------\n// Clase base\nclass Vehicle {\n    constructor(brand, model) {\n        if (this.constructor === Vehicle) {\n            throw new Error(\"No se puede instanciar la clase abstracta 'Vehicle'\");\n        }\n        this._brand = brand;\n        this._model = model;\n    }\n\n    get brand() {\n        return this._brand;\n    }\n\n    get model() {\n        return this._model;\n    }\n\n    accelerate() {\n        throw new Error(\"Método 'accelerate' no implementado\");\n    }\n\n    brake() {\n        throw new Error(\"Método 'brake' no implementado\");\n    }\n}\n\n// Clases derivadas\nclass Car extends Vehicle {\n    accelerate() {\n        return `Acelerando auto: ${this.brand} - ${this.model}`;\n    }\n\n    brake() {\n        return `Frenando auto: ${this.brand} - ${this.model}`;\n    }\n}\n\nclass Motorcycle extends Vehicle {\n    accelerate() {\n        return `Acelerando Motocicleta: ${this.brand} - ${this.model}`;\n    }\n\n    brake() {\n        return `Frenando Motocicleta: ${this.brand} - ${this.model}`;\n    }\n}\n\nclass Truck extends Vehicle {\n    accelerate() {\n        return `Acelerando Camión: ${this.brand} - ${this.model}`;\n    }\n\n    brake() {\n        return `Frenando Camión: ${this.brand} - ${this.model}`;\n    }\n}\n\n// Verificar cumplimiento de LSP\nfunction testSubClass(subClass) {\n    console.log(\"\\nPropiedades:\");\n    console.log(`${subClass.brand} - ${subClass.model}`);\n\n    console.log(\"\\nMétodos:\");\n    console.log(subClass.accelerate());\n    console.log(subClass.brake());\n}\n\n// Instanciando\nconst car = new Car(\"Honda\", \"Civic\");\ntestSubClass(car);\n\nconst motorcycle = new Motorcycle(\"Kawasaki\", \"Ninja\");\ntestSubClass(motorcycle);\n\nconst truck = new Truck(\"Ford\", \"Raptor\");\ntestSubClass(truck);\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/javascript/nlarrea.js",
    "content": "/**\n * EJERCICIO:\n * Explora el \"Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n * cumplir el LSP.\n * Instrucciones:\n * 1. Crea la clase Vehículo.\n * 2. Añade tres subclases de Vehículo.\n * 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n * 4. Desarrolla un código que compruebe que se cumple el LSP.\n */\n\n\n// Incorrect\n\n\nclass BirdWrong {\n    fly() {\n        return 'Flying';\n    }\n};\n\n\nclass OstrichWrong extends BirdWrong {\n    fly() {\n        throw new Error('Ostriches can\\'t fly');\n    }\n};\n\n\n// let bird = new BirdWrong();\n// console.log(bird.fly());  // Flying\n// let ostrich = new OstrichWrong();\n// console.log(ostrich.fly());  // Error\n\n\n// Correct\n\n\nclass Bird {\n    move() {\n        return 'FLying';\n    }\n};\n\n\nclass Ostrich extends Bird {\n    move() {\n        return 'Walking';\n    }\n};\n\n\nconst bird = new Bird();\nconsole.log(bird.move());  // Flying\nconst ostrich = new Ostrich();\nconsole.log(ostrich.move());  // Walking\n\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n * cumplir el LSP.\n * Instrucciones:\n * 1. Crea la clase Vehículo.\n * 2. Añade tres subclases de Vehículo.\n * 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n * 4. Desarrolla un código que compruebe que se cumple el LSP.\n */\n\n\nclass Vehicle {\n    constructor(speed=0) {\n        this.speed = speed;\n    }\n\n    accelerate(increment) {\n        this.speed += increment;\n        console.log(`Speed: ${this.speed} km/h`);\n    }\n\n    brake(decrement) {\n        this.speed -= decrement;\n        console.log(`Speed: ${this.speed} km/h`);\n    }\n};\n\n\nclass Motorbike extends Vehicle {\n    constructor(speed=0) {\n        super(speed);\n    }\n\n    accelerate(increment) {\n        console.log('Motorbike is accelerating...');\n        super.accelerate(increment);\n    }\n\n    brake(decrement) {\n        console.log('Motorbike is braking...');\n        super.brake(decrement);\n    }\n};\n\n\nclass Car extends Vehicle {\n    constructor(speed=0) {\n        super(speed);\n    }\n\n    accelerate(increment) {\n        console.log('Car is accelerating...');\n        super.accelerate(increment);\n    }\n\n    brake(decrement) {\n        console.log('Car is braking...');\n        super.brake(decrement);\n    }\n};\n\n\nclass Bicycle extends Vehicle {\n    constructor(speed=0) {\n        super(speed);\n    }\n\n    accelerate(increment) {\n        console.log('Bicycle is accelerating...');\n        super.accelerate(increment);\n    }\n\n    brake(decrement) {\n        console.log('Bicycle is braking...');\n        super.brake(decrement);\n    }\n};\n\n\nfunction testVehicle(vehicle) {\n    vehicle.accelerate(10);\n    vehicle.brake(2);\n    console.log('');\n};\n\n\nconst motorbike = new Motorbike();\nconst car = new Car();\nconst bicycle = new Bicycle();\n\ntestVehicle(motorbike);\ntestVehicle(car);\ntestVehicle(bicycle);"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/javascript/parababire.js",
    "content": "// Ejercicio\n\n/* Incorrecto */\n\n/* class Ball {\n  bounce() {\n    console.log(`The ball bounce!!!`);\n  }\n}\n\nclass BowlingBall extends Ball {\n  bounce() {\n    throw new Error(`Bowling ball can't bounce!!!`)\n  }\n} */\n\n/* const ball = new Ball()\nconst bowlingBall = new BowlingBall()\nball.bounce()\nbowlingBall.bounce() */\n\n/* Correcto */\n\nclass Ball {\n  throw() {\n    console.log(`Throw the ball`);\n  }\n}\n\nclass BowlingBall extends Ball {\n  throw() {\n    console.log(`Throw the ball toward pins`);\n  }\n}\n\nlet ball = new Ball()\nlet bowlingBall = new BowlingBall()\nball.throw()\nbowlingBall.throw()\n\n/* Comprobación del principio de sustitución de Likov */\n\nball = new BowlingBall()\nbowlingBall = new Ball()\nball.throw()\nbowlingBall.throw()\n\n// Extra\n\nclass Vehicle {\n  constructor(speed = 0) {\n    this.speed = speed\n  }\n\n  accelerate(increment) {\n    this.speed += increment\n    console.log(this.speed);\n    \n  }\n  break(decrement) {\n    this.speed -= decrement\n    if (this.speed <= 0) {\n      console.log(this.speed = 0)\n    }\n    console.log(this.speed)\n  }\n}\n\nclass Car extends Vehicle {\n  accelerate(increment) {\n    console.log(`El carro está acelerando`)\n    super.accelerate(increment)\n  }\n  break(decrement) {\n    console.log(`El carro está frenando`)\n    super.break(decrement)\n  }\n}\nclass Bike extends Vehicle {\n  accelerate(increment) {\n    console.log(`La bicicleta está acelerando`)\n    super.accelerate(increment)\n  }\n  break(decrement) {\n    console.log(`La bicicleta está frenando`)\n    super.break(decrement)\n  }\n}\nclass Motocycle extends Vehicle {\n  accelerate(increment) {\n    console.log(`La moto está acelerando`)\n    super.accelerate(increment)\n  }\n  break(decrement) {\n    console.log(`La moto está frenando`)\n    super.break(decrement)\n  }\n}\n\nfunction testVehicle(vehicle) {\n  vehicle.accelerate(2)\n  vehicle.break(1)\n}\n\nconst car = new Car()\nconst bike = new Bike()\nconst motocycle = new Motocycle()\n\ntestVehicle(car)\ntestVehicle(bike)\ntestVehicle(motocycle)"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/javascript/pedamoci.js",
    "content": "// LSP MAL HECHO\nclass WrongPersona {\n  constructor(idCard, name, lastName, card) {\n    this.idCard = idCard\n    this.name = name\n    this.lastName = lastName\n    this.card = card\n  }\n\n  pagar(price) {\n    console.log(`Se ha usado para pagar $${price} la tarjeta ${this.card}`)\n  }\n}\n\nconst wrongAdulto = new WrongPersona(84987, 'Raul', 'Hectorio', 762456342464)\nwrongAdulto.pagar(543)\n\n// No cumple con el LSP ya que si queremos asignar un niño a persona tenemos que poner valores nulos y estonces un niño no cumpliria con lo de persona\nconst wrongNiño = new WrongPersona(null, 'Caterina', 'Escamilla', null)\n\n\n// LSP BIEN HECHO\nclass Persona {\n  constructor(name, lastName) {\n    this.name = name\n    this.lastName = lastName\n  }\n}\n\nclass Adulto extends Persona {\n  constructor(name, lastName, idCard, card) {\n    super(name, lastName)\n    this.idCard = idCard\n    this.card = card\n  }\n\n  pagar(price) {\n    console.log(`Se ha usado para pagar $${price} la tarjeta ${this.card}`)\n  }\n}\n\nclass Niño extends Persona {\n  constructor(name, lastName) {\n    super(name, lastName)\n  }\n}\n\nconst adulto = new Adulto(84987, 'Raul', 'Hectorio', 762456342464)\nadulto.pagar(543)\nconst niño = new Niño('Caterina', 'Escamilla')\n\n// ------------------------------------------------- DIFICULTAD EXTRA -------------------------------------------------\nclass Vehicle {\n  constructor(acceleration, deceleration) {\n    this.acceleration = acceleration\n    this.deceleration = deceleration\n    this.speed = 0\n  }\n\n  accelerate(targetSpeed) {\n    if (this.speed >= targetSpeed) return Promise.reject('ERROR ingresaste una velocidad igual o menor a la actual')\n    const startTime = performance.now()\n    return new Promise(resolve => {\n      setTimeout(() => {\n        this.speed = targetSpeed\n        const endTime = performance.now()\n        console.log(`Tardo en acelerar hasta ${targetSpeed}km/h ${((endTime - startTime)/1000).toFixed(2)}s`)\n        resolve()\n      }, 1000 * ((targetSpeed - this.speed)/this.acceleration))\n    })\n  }\n\n  decelerate(targetSpeed) {\n    if (this.speed <= targetSpeed) return Promise.reject('ERROR ingresaste una velocidad igual o menor a la actual')\n    const startTime = performance.now()\n    return new Promise(resolve => {\n      setTimeout(() => {\n        this.speed = targetSpeed\n        const endTime = performance.now()\n        console.log(`Tardo en desacelerar hasta ${targetSpeed}km/h ${((endTime - startTime)/1000).toFixed(2)}s`)\n        resolve()\n      }, (targetSpeed === 0) ? 1000 * (this.speed/this.deceleration)\n                              : 1000 * (targetSpeed/this.deceleration))\n    })\n  }\n}\n\nclass Bicycle extends Vehicle{\n  constructor(acceleration, deceleration) {\n    super(acceleration, deceleration)\n  }\n\n  tocarBocina() {\n    console.log('¡Ting ting!')\n  }\n}\n\nclass Car extends Vehicle{\n  constructor(acceleration, deceleration) {\n    super(acceleration, deceleration)\n  }\n\n  ponerGuiño(direction) {\n    if (direction === 'derecha') console.log('→')\n    if (direction === 'izquierda') console.log('←')\n  }\n}\n\nclass Plane extends Vehicle{\n  constructor(acceleration, deceleration) {\n    super(acceleration, deceleration)\n  }\n\n  notificarPorAltavoz() {\n    console.log('Señores pasajeros tengan la amabilidad de abrocharse el cinturon')\n  }\n}\n\nasync function program() {\n  const bicycle = new Bicycle(10, 5)\n  const car = new Car(100, 50)\n  const plane = new Plane(400, 150)\n\n  plane.notificarPorAltavoz()\n\n  await Promise.all([\n    plane.accelerate(2500),\n    car.accelerate(120),\n    bicycle.accelerate(30)\n  ])\n  \n  await plane.accelerate(4000)\n  \n  car.ponerGuiño('derecha')\n  await car.decelerate(80)\n  car.ponerGuiño('izquierda')\n\n  await bicycle.decelerate(0)\n  bicycle.tocarBocina()\n}\n\nprogram()"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/javascript/victor-Casta.js",
    "content": "/*\n  * EJERCICIO:\n  * Explora el \"Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)\"\n  * y crea un ejemplo simple donde se muestre su funcionamiento\n  * de forma correcta e incorrecta.\n*/\n\nclass Worker {\n  work() {\n    return 'Realizando tareas generales'\n  }\n}\n\nclass Developer extends Worker {\n  work() {\n    return 'Escribiendo código'\n  }\n}\n\nclass Designer extends Worker {\n  work() {\n    return 'Creando diseños'\n  }\n}\n\nlet worker = new Worker()\nconsole.log(worker.work())\n\nlet developer = new Developer()\nconsole.log(developer.work())\n\nlet designer = new Designer()\nconsole.log(designer.work())\n\n\nworker = new Developer()\nconsole.log(worker.work())\n\nworker = new Designer()\nconsole.log(worker.work())\n\n\n/*\n  * DIFICULTAD EXTRA (opcional):\n  * Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n  * cumplir el LSP.\n  * Instrucciones:\n  * 1. Crea la clase Vehículo.\n  * 2. Añade tres subclases de Vehículo.\n  * 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n  * 4. Desarrolla un código que compruebe que se cumple el LSP.\n*/\nconsole.log('--Extra--')\n\nclass Vehicle {\n  speed = 0\n  constructor(speed) {\n    this.speed = speed\n  }\n\n  speedUp() {\n    this.speed += 1\n    return `Velocidad: ${this.speed}`\n  }\n\n  slowDown() {\n    if (this.speed > 0) {\n      this.speed -= 1\n      return `Velocidad: ${this.speed}`\n    } else {\n      this.speed = 0\n      return `Velocidad: ${this.speed}`\n    }\n  }\n}\n\nclass Car extends Vehicle {\n  speedUp() {\n    this.speed += 4\n    return `Velocidad: ${this.speed}`\n  }\n}\n\nclass Plane extends Vehicle {\n  speedUp() {\n    this.speed += 10\n    return `Velocidad: ${this.speed}`\n  }\n\n  slowDown() {\n    if (this.speed > 0) {\n      this.speed -= 5\n      return `Velocidad: ${this.speed}`\n    } else {\n      return `El avión ya está detenido`\n    }\n  }\n}\n\n\nclass Bus extends Vehicle {\n  speedUp() {\n    this.speed += 3\n    return `Velocidad: ${this.speed}`\n  }\n}\n\nlet vehicle = new Vehicle(0)\n\nlet car = new Car(10)\nconsole.log(car.speedUp())\nconsole.log(car.slowDown())\n\nlet plane = new Plane(50)\nconsole.log(plane.speedUp())\nconsole.log(plane.slowDown())\n\nlet bus = new Bus(20)\nconsole.log(bus.speedUp())\nconsole.log(bus.slowDown())\n\nvehicle = new Car(0)\nconsole.log(vehicle.speedUp())\nconsole.log(vehicle.slowDown())\n\nvehicle = new Plane(0)\nconsole.log(vehicle.speedUp())\nconsole.log(vehicle.slowDown())\n\nvehicle = new Bus(0)\nconsole.log(vehicle.speedUp())\nconsole.log(vehicle.slowDown())"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/kotlin/blackriper.kt",
    "content": "/*\r\nLiskov Sustitucion Principle\r\nEl Principio de Substitución de Liskov es uno de los principios SOLID y hace referencia a cómo usamos\r\nla herencia de forma adecuada. El principio dice algo como lo siguiente si S es un subtipo de T , T\r\npuede ser reemplazado con objetos de tipo S sin alterar el comportamiento esperado en el programa.\r\n*/\r\n\r\n// lo que no debe de hacer\r\nopen class BankAccount {\r\n    private var balance = 0.0\r\n\r\n    fun deposit(amount: Double){\r\n        balance+=amount\r\n    }\r\n    open fun withdraw(amount: Double){\r\n        balance-=amount\r\n    }\r\n    fun getBalance(): Double=balance\r\n}\r\n\r\nclass NormalAccount: BankAccount()\r\n// esta cuenta solo es de ahorro no permite hacer retiros por lo tanto\r\nclass SavingsAccount: BankAccount(){\r\n    override fun withdraw(amount: Double) {\r\n        throw Exception(\"Savings accounts cannot withdraw\")\r\n    }\r\n}\r\n\r\n// utilizando el principio de Liskov\r\n// quitamos la clase witdraw de la clase BankAccount\r\nopen class BankAtm {\r\n    protected var balance = 0.0\r\n\r\n    fun deposit(amount: Double){\r\n        balance+=amount\r\n    }\r\n\r\n    fun getBalanceAtm(): Double=balance\r\n}\r\n// delegamos la tarea a la cuenta corriente de poder hacer el deposito\r\nclass NormalAtm:BankAtm(){\r\n    // nuevo objeto tipo S que no afecta el funcionamiento de la superclase\r\n     fun withdraw(amount: Double){\r\n        balance-=amount\r\n    }\r\n}\r\n// ahora la cuenta de ahorro no necesita lanzar una excepcion\r\nclass SavingsAtm:BankAtm()\r\n\r\n\r\nfun examplesLiskovSubstitution() {\r\n    val account = NormalAccount()\r\n    account.deposit(100.0)\r\n    account.withdraw(50.0)\r\n    println(account.getBalance())\r\n\r\n    //val account2=SavingsAccount()\r\n    //account2.withdraw(50.0)\r\n\r\n    // nueva implementacion\r\n    val atm = NormalAtm()\r\n    atm.deposit(100.0)\r\n    atm.withdraw(50.0)\r\n    println(atm.getBalanceAtm())\r\n\r\n    val atm2 = SavingsAtm()\r\n    atm2.deposit(100.0)\r\n    println(atm2.getBalanceAtm())\r\n}\r\n\r\n// ejercicio extra\r\n\r\nopen class Vehicle(protected val model:String,private val speed :Int){\r\n    open fun accelerate(){\r\n        println(\"$model accelerating at $speed km/h\")\r\n    }\r\n    open fun brake(){\r\n        println(\"brake $model\")\r\n    }\r\n }\r\n\r\n// creando  subclases\r\n class Bus (model:String,speed:Int):Vehicle(model,speed){\r\n     override fun accelerate(){\r\n         super.accelerate()\r\n     }\r\n     override fun brake(){\r\n         super.brake()\r\n     }\r\n }\r\n// el bote tiene una funcion para desanclar por lo tanto estamos agregando un objeto S sin afectar al\r\n// comportamiento\r\nclass Boots(model:String,speed:Int):Vehicle(model,speed){\r\n    override fun accelerate(){\r\n        super.accelerate()\r\n    }\r\n    override fun brake(){\r\n        super.brake()\r\n    }\r\n    fun anchorBoots(){\r\n        println(\"anchor the boot $model\")\r\n    }\r\n}\r\n// el camion  de carga tambien necesita delegar el comportamiento a su clase y\r\n// el objeto S no afecta el comportamiento\r\nenum class Load{ COCONUTS,GRAVE,SUGAR}\r\n\r\nclass TruckLoad(model:String,speed:Int,val loadType:Load):Vehicle(model,speed){\r\n    override fun accelerate(){\r\n        super.accelerate()\r\n    }\r\n    override fun brake(){\r\n        super.brake()\r\n    }\r\n    fun downLoad(){\r\n        println(\"downloading $loadType\")\r\n    }\r\n}\r\n\r\nfun consumeVehicle(vehicle: Vehicle){\r\n    vehicle.accelerate()\r\n    vehicle.brake()\r\n}\r\n\r\nfun exampleLsp(){\r\n    // crenado instancias\r\n    val bus = Bus(\"Scania\",120)\r\n    val boot = Boots(\"Bayliner\",250)\r\n    val truck = TruckLoad(\"Kenworth\",100,Load.GRAVE)\r\n    // comprobando que el comportamiento no sea mutado\r\n    consumeVehicle(bus)\r\n    consumeVehicle(boot)\r\n    consumeVehicle(truck)\r\n    // llamndo objetos s particulares de cada  subclase\r\n    truck.downLoad()\r\n    boot.anchorBoots()\r\n}\r\n\r\n\r\nfun main() {\r\n    examplesLiskovSubstitution()\r\n    exampleLsp()\r\n}"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/kotlin/eulogioep.kt",
    "content": "/*\n * Principio de Sustitución de Liskov (LSP):\n * \n * El LSP establece que los objetos de una superclase deben poder ser reemplazados\n * por objetos de sus subclases sin afectar la corrección del programa. En otras palabras,\n * las subclases deben ser completamente sustituibles por sus clases base.\n *\n * Este principio asegura que una subclase puede asumir el lugar de su superclase\n * sin causar errores o comportamientos inesperados en el programa.\n */\n\n// Clase base Vehiculo\nabstract class Vehiculo {\n    abstract fun acelerar(incrementoVelocidad: Int)\n    abstract fun frenar(decrementoVelocidad: Int)\n    abstract fun obtenerVelocidadActual(): Int\n}\n\n// Subclase Coche\nclass Coche : Vehiculo() {\n    private var velocidad = 0\n\n    override fun acelerar(incrementoVelocidad: Int) {\n        velocidad += incrementoVelocidad\n        println(\"Coche acelerando. Velocidad actual: $velocidad km/h\")\n    }\n\n    override fun frenar(decrementoVelocidad: Int) {\n        velocidad = maxOf(0, velocidad - decrementoVelocidad)\n        println(\"Coche frenando. Velocidad actual: $velocidad km/h\")\n    }\n\n    override fun obtenerVelocidadActual(): Int = velocidad\n}\n\n// Subclase Motocicleta\nclass Motocicleta : Vehiculo() {\n    private var velocidad = 0\n\n    override fun acelerar(incrementoVelocidad: Int) {\n        velocidad += incrementoVelocidad\n        println(\"Motocicleta acelerando. Velocidad actual: $velocidad km/h\")\n    }\n\n    override fun frenar(decrementoVelocidad: Int) {\n        velocidad = maxOf(0, velocidad - decrementoVelocidad)\n        println(\"Motocicleta frenando. Velocidad actual: $velocidad km/h\")\n    }\n\n    override fun obtenerVelocidadActual(): Int = velocidad\n}\n\n// Subclase Bicicleta\nclass Bicicleta : Vehiculo() {\n    private var velocidad = 0\n\n    override fun acelerar(incrementoVelocidad: Int) {\n        velocidad += incrementoVelocidad\n        println(\"Bicicleta acelerando. Velocidad actual: $velocidad km/h\")\n    }\n\n    override fun frenar(decrementoVelocidad: Int) {\n        velocidad = maxOf(0, velocidad - decrementoVelocidad)\n        println(\"Bicicleta frenando. Velocidad actual: $velocidad km/h\")\n    }\n\n    override fun obtenerVelocidadActual(): Int = velocidad\n}\n\n// Función para probar el LSP\nfun probarLSP(vehiculo: Vehiculo) {\n    vehiculo.acelerar(20)\n    vehiculo.frenar(10)\n    println(\"Velocidad final: ${vehiculo.obtenerVelocidadActual()} km/h\")\n    println()\n}\n\nfun main() {\n    val coche = Coche()\n    val motocicleta = Motocicleta()\n    val bicicleta = Bicicleta()\n\n    println(\"Probando Coche:\")\n    probarLSP(coche)\n\n    println(\"Probando Motocicleta:\")\n    probarLSP(motocicleta)\n\n    println(\"Probando Bicicleta:\")\n    probarLSP(bicicleta)\n}"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/kotlin/rikmij.kt",
    "content": "fun main() {\n    //Forma incorrecta\n    open class Pokes(val nAme: String) {\n        open fun aTtack(aTtack: String): String {\n            return \"$nAme usó $aTtack\"\n        }\n        open fun evoluciona(): String {\n            return \"Tu $nAme está evolucionando\"\n        }\n    }\n\n    class Seel(nAme: String): Pokes(nAme) {\n        override fun evoluciona(): String {\n            return \"Tu $nAme está evolucionando en Dewgong\"\n        }\n    }\n\n    class Sableye(nAme: String): Pokes(nAme) {\n        override fun evoluciona(): String {\n            throw Exception(\"Tauros no evoluciona\")\n        }\n    }\n\n    val seel = Seel(\"Seel\")\n    println(seel.evoluciona())\n    val sableye = Sableye(\"Sableye\")\n    println(sableye.aTtack(\"Rayo Confuso\"))\n    //println(taur.evolucionar())\n\n    /*\n    Como vemos, no todos los pokémon evolucionan, por lo que la función evoluciona() no debería estar\n    en la clase general, sino en otra específica de los que sí evolucionen\n     */\n\n//Forma correcta\n    open class Pokemon(val name: String) {\n        open fun attack(attack: String): String {\n            return \"$name usó $attack\"\n        }\n    }\n\n    class Charmander(name: String): Pokemon(name) {\n        fun evolve(): String {\n            return \"Tu $name está evolucionando en Charmeleon\"\n        }\n    }\n\n    class Tauros(name: String): Pokemon(name)\n\n    val charmander = Charmander(\"Charmander\")\n    println(charmander.attack(\"Ascuas\"))\n    println(charmander.evolve())\n    val tauros = Tauros(\"Tauros\")\n    println(tauros.attack(\"Derribo\"))\n    val krabby = Pokemon(\"Krabby\")\n    println(krabby.attack(\"Martillazo\"))\n\n    /*\n    Aquí es correcto. Un pokémon que no evoluciona no tiene el método de evolucionar, y la superclase sólo\n    tiene los métodos generales, lo que pueden hacer todos los pokémon\n     */\n\n    println(\"\\n${\"*\".repeat(7)} EJERCICIO EXTRA ${\"*\".repeat(7)}\")\n    val coche = Car()\n    println(coche.brake())\n    println(coche.openTrunk())\n    val moto = Moto()\n    println(moto.speedUp())\n    println(moto.makeNoise())\n    val tractor = Tractor()\n    println(tractor.sow())\n    /*\n    Las funciones openTrunk, makeNoise y sow son propias de cada tipo de vehículo, pero la de arrancar\n    y frenar son comunes. Para brake() y speedUp() se podría usar cualquiera de las subclases o la propia\n    clase Vehicle, pero para sus métodos específicos no\n     */\n}\n\nopen class Vehicle {\n    open fun speedUp(): String {\n        return \"El vehículo está acelerando\"\n    }\n    open fun brake(): String {\n        return \"El vehículo está frenando\"\n    }\n}\n\nclass Car: Vehicle() {\n    override fun speedUp(): String {\n        return \"El coche está acelerando\"\n    }\n    override fun brake(): String {\n        return \"El coche está frenando\"\n    }\n    fun openTrunk(): String {\n        return \"El maletero se ha abierto\"\n    }\n}\n\nclass Moto: Vehicle() {\n    override fun speedUp(): String {\n        return \"La moto está acelerando\"\n    }\n    override fun brake(): String {\n        return \"La moto está frenando\"\n    }\n    fun makeNoise(): String {\n        return \"BRRRRRUM BRRRRRUM\"\n    }\n}\n\nclass Tractor: Vehicle() {\n    override fun speedUp(): String {\n        return \"El tractor está acelerando\"\n    }\n    override fun brake(): String {\n        return \"El tractor está frenando\"\n    }\n    fun sow(): String {\n        return \"El tractor ha plantado semillas\"\n    }\n}\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/ocaml/luishendrix92.ml",
    "content": "open Printf\n\n(******************************************************************************)\n(*                                                                            *)\n(*                       Liskov Substitution Principle                        *)\n(*                                                                            *)\n(*  The LSP states that subclasses of a parent class should be able to beha-  *)\n(*  ve just like their parent classes. Or the official statement: let phi(x)  *)\n(*  be a property provable about objects of type T, then phi(y) should be     *)\n(*  true for objects y ofthe type S where S is a subtype of T.                *)\n(*  All of this means that we should be able to replace objects of a super-   *)\n(*  class with objects of its subclasses without breaking the client's code.  *)\n(*                                                                            *)\n(*  It also states some rules:                                                *)\n(*  1. A subclasss method should not strengthen its pre-condition: In human-  *)\n(*     readable terms: overriden methods should not change their parameters   *)\n(*     for subtypes of those parameter types.                                 *)\n(*  2. A subclass method should not weaken its post-condition: We should not  *)\n(*     return a more abstract type than the specified return type, but we     *)\n(*     can definitely return a subtype of the return type.                    *)\n(*  3. Methods should not break the invariance of the superclass' method.     *)\n(*                                                                            *)\n(******************************************************************************)\n\nclass virtual lsp_non_compliant_acount (owner' : string) =\n  object\n    val mutable balance = 0.0\n    val owner = owner'\n    method virtual deposit : float -> unit\n    method virtual withdraw : float -> unit\n    method show_balance = printf \"Current balance for %s: $%f\\n\" owner balance\n  end\n\nclass savings_account (owner' : string) =\n  object\n    inherit lsp_non_compliant_acount owner'\n\n    method deposit amount =\n      balance <- balance +. amount;\n      printf \"%s deposited %f into their account!\\n\" owner amount\n\n    method withdraw amount =\n      if balance < amount\n      then failwith \"Not enough funds for withdrawal\"\n      else begin\n        balance <- balance -. amount;\n        printf \"%s withdrew %f from their account!\\n\" owner amount\n      end\n  end\n\nclass fixed_term_account (owner' : string) =\n  object\n    inherit lsp_non_compliant_acount owner'\n\n    method deposit amount =\n      balance <- balance +. amount;\n      printf \"%s deposited %f into a fixed term!\\n\" owner amount\n\n    method withdraw = failwith \"Unsupported method\"\n  end\n\nlet _ =\n  (* Client Code for an LSP-breaking example *)\n  let acct : lsp_non_compliant_acount ref =\n    ref @@ new savings_account \"Luis Lopez\"\n  in\n  !acct#deposit 456.53;\n  !acct#withdraw 245.35;\n  !acct#show_balance;\n  (* The code above worked great, but what if I were to swap the account ref\n     value for a subclass that doen't do withdrawals and instead throws an\n     exception which completely breaks the LSP. *)\n  acct := new fixed_term_account \"Moure Dev\";\n  !acct#deposit 456.53;\n  begin\n    try !acct#withdraw 245.35 with\n    | Failure msg -> print_endline msg\n  end;\n  !acct#show_balance\n;;\n\n(* Let's try to make the example LSP compliant. The most feasible solution is\n   to stop making assumptions about the withdrawal capabilities of these accts.\n   Next step is to break a superclass [Account] (or interface) into their own\n   subclasses or subinterfaces with extended capabilities that other concrete\n   classes can inherit or extend in turn. This way if the client code requires\n   accounts that have withdrawal capabilities, then we can start using our\n   specialized subtype that performs a withdrawal operation. *)\n\nclass virtual account (owner' : string) =\n  object\n    val mutable balance = 0.0\n    val owner = owner'\n    method virtual deposit : float -> unit\n    method show_balance = printf \"Current balance for %s: $%f\\n\" owner balance\n  end\n\nclass virtual withdrawable owner' =\n  object\n    inherit account owner'\n    method virtual withdraw : float -> unit\n  end\n\nclass fixed_term owner' =\n  object\n    inherit account owner'\n\n    (* Any other methods or members corresponding to a specialized fixed-term\n       class go here, otherwise there  would be no point in extending.*)\n    method deposit amount =\n      balance <- balance +. amount;\n      printf \"%s deposited %f into their fixed term!\\n\" owner amount\n  end\n\nclass savings owner' =\n  object\n    inherit withdrawable owner'\n\n    method deposit amount =\n      balance <- balance +. amount;\n      printf \"%s deposited %f into their savings account!\\n\" owner amount\n\n    method withdraw amount =\n      if balance < amount\n      then failwith \"Not enough funds for withdrawal\"\n      else begin\n        balance <- balance -. amount;\n        printf \"%s withdrew %f from their savings account!\\n\" owner amount\n      end\n  end\n\nlet _ =\n  (* Client Code for an LSP-compliant example *)\n  let acct : withdrawable = new savings_account \"Luis Lopez\" in\n  acct#deposit 319.35;\n  acct#withdraw 300.00;\n  acct#show_balance\n;;\n\n(* Now, the client code is specific in that it only accepts subclasses that\n   are 'withdrawable' and if I were to pass it an instance of [fixed_term]\n   then the compiler would let us know, thus not breaking the LSP.\n\n   The compiler error says:\n   - This expression has type fixed_term but an expression was expdected of\n     type withdrawable The first object type has no method withdraw. *)\n(* let acct2 : withdrawable = new fixed_term \"John Doe\" in *)\n(* acct#withdraw 100.0 *)\n\n(* \n * DIFICULTAD EXTRA (opcional):\n * ============================\n * Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n * cumplir el LSP.\n * Instrucciones:\n * 1. Crea la clase Vehículo.\n * 2. Añade tres subclases de Vehículo.\n * 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n * 4. Desarrolla un código que compruebe que se cumple el LSP.\n *)\n\nlet clamp a b x = if x < a then a else if x > b then b else x\n\nclass virtual vehicle (top_speed' : float) (accel : float) =\n  object\n    val top_speed = top_speed'\n    val acceleration = accel\n    val mutable speed = 0.0\n\n    method accelerate' =\n      let clamp_speed = clamp 0.0 top_speed in\n      speed <- clamp_speed (speed +. acceleration)\n\n    method virtual accelerate : unit\n    method get_speed = speed\n    method brake = speed <- 0.0\n  end\n\nclass boat =\n  object (self)\n    inherit vehicle 80.0 1.52\n    method anchor = print_endline \"Anchoring boat...\"\n\n    method accelerate =\n      self#accelerate';\n      print_endline \"Boat accelerated\"\n  end\n\nclass motorbike =\n  object (self)\n    inherit vehicle 186.0 25.4\n\n    method accelerate =\n      self#accelerate';\n      print_endline \"Motorbike accelerated\"\n  end\n\nclass tesla =\n  object (self)\n    inherit vehicle 200.0 9.82\n    val mutable charge = 0\n\n    method accelerate =\n      self#accelerate';\n      charge <- clamp 0 100 (charge - 1);\n      print_endline \"Tesla accelerated\"\n\n    method recharge = charge <- 100\n  end\n\nlet _ =\n  let v : vehicle = new motorbike in\n  print_newline ();\n  for i = 1 to 10 do\n    v#accelerate;\n    printf \"Motorbike's speed: %f\\n\" v#get_speed\n  done;\n  v#brake;\n  print_endline \"Invoking #brake on a motorbike\";\n  printf \"Motorbike's speed: %f\\n\" v#get_speed\n;;\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/php/miguelex.php",
    "content": "<?php\n\n    // Ejercicio basico sin LSP\n\n    class Bird {\n        public function fly() {\n            return \"Puedo volar\\n\";\n        }\n    }\n\n    class Canary extends Bird {\n\n        public function name(){\n            return \"Soy un canario\\n\";\n        }\n    }\n\n    class Ostrich extends Bird {\n\n        public function name(){\n            return \"Soy un avestruz\\n\";\n        }\n\n        public function fly() {\n            return \"No puedo volar (sobreescribi el método)\\n\";\n        }\n    }\n\n    echo \"Sin LSP\\n\";\n    $canary = new Canary();\n    echo $canary->name();\n    echo $canary->fly();\n\n    $ostrich = new Ostrich();\n    echo $ostrich->name();\n    echo $ostrich->fly();\n\n    // Vemos que hemos tenido que sobreescribir el metodo fly para el avestruz. Esto incumple el LSP\n\n    // Ejercicio basico con LSP\n\n    interface Bird2 {\n        public function fly();\n    }\n\n    class Canary2 implements Bird2 {\n\n        public function name(){\n            return \"Soy un canario\\n\";\n        }\n\n        public function fly() {\n            return \"Puedo volar\\n\";\n        }\n    }\n\n    class Ostrich2 implements Bird2 {\n\n        public function name(){\n            return \"Soy un avestruz\\n\";\n        }\n\n        public function fly() {\n            return \"No puedo volar\\n\";\n        }\n    }\n\n    echo \"\\n\";\n    echo \"Con LSP\\n\";\n    $canary2 = new Canary2();\n    echo $canary2->name();\n    echo $canary2->fly();\n    echo \"\\n\";\n    $ostrich2 = new Ostrich2();\n    echo $ostrich2->name();\n    echo $ostrich2->fly();\n\n    //Al tener la interface no me ha sido necesario sobreescribir nada. Lo implemento (o no) segun mis necesidades\n\n    // Ejercicio Extra\n\n    echo \"\\n\";\n    echo \"Ejercicio Extra\\n\";\n\n    interface Vehicle {\n        public function speed();\n        public function accelerate();\n        public function brake();\n    }\n\n    class Car implements Vehicle {\n        private $speed;\n\n        public function __construct(){\n            $this->speed = 0;\n        }\n\n        public function speed(){\n            return $this->speed;\n        }\n\n        public function accelerate(){\n            $this->speed += 10;\n        }\n\n        public function brake(){\n            $this->speed -= 10;\n        }\n    }\n\n    class Bicycle implements Vehicle {\n        private $speed;\n\n        public function __construct(){\n            $this->speed = 0;\n        }\n\n        public function speed(){\n            return $this->speed;\n        }\n\n        public function accelerate(){\n            $this->speed += 5;\n        }\n\n        public function brake(){\n            $this->speed -= 5;\n        }\n    }\n\n    class Truck implements Vehicle {\n        private $speed;\n\n        public function __construct(){\n            $this->speed = 0;\n        }\n\n        public function speed(){\n            return $this->speed;\n        }\n\n        public function accelerate(){\n            $this->speed += 2;\n        }\n\n        public function brake(){\n            $this->speed -= 2;\n        }\n    }\n\n    function testVehicle(Vehicle $vehicle){\n        echo \"Velocidad: \".$vehicle->speed().\"\\n\";\n        $vehicle->accelerate();\n        echo \"Velocidad: \".$vehicle->speed().\"\\n\";\n        $vehicle->accelerate();\n        echo \"Velocidad: \".$vehicle->speed().\"\\n\";\n        $vehicle->brake();\n        echo \"Velocidad: \".$vehicle->speed().\"\\n\";\n    }\n\n    $car = new Car();\n    $bike = new Bicycle();\n    $truck = new Truck();\n\n    echo \"Vamos a probar el coche:\\n\";\n    testVehicle($car);\n    echo \"Vamos a probar la bicicleta:\\n\";\n    testVehicle($bike);\n    echo \"Vamos a probar el camion:\\n\";\n    testVehicle($truck);\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/Aldroide.py",
    "content": "\"\"\"\n    Explora el concepto de Principio de Sustitución de Liskov (Liskov Substitution Principle, LSP)\n    crea un ejemplo siemple donde se muestre su funcionamiento de forma correcta e incorrecta.\n\"\"\"\n\n\nclass Bird:\n    def volar(self):\n        raise NotImplementedError(\"Este metodo permite al ave volar\")\n\n\nclass Duck(Bird):\n    def volar(self):\n        print(\"El pato sabe volar\")\n\n\nclass Penguin(Bird):\n    def volar(self):\n        print(\"El pinguino no sabe volar\")\n\n\ndef hacer_volar(ave: Bird):\n    ave.volar()\n\n\npato = Duck()\npinguino = Penguin()\nhacer_volar(pato)\nhacer_volar(pinguino)\n\n\"\"\"\n    Extra:\n    Crear una jerarquia de vehiculos, Todos deben llevar el poder \n    acelerar y frenar y cumplir el LSP.\n    Instrucciónes:\n    1.- Crea la clase vehículo\n    2.- Añade tres subclases de vehículo\n    3.- Implementa operacion acelerar y frenar como corresponda\n    4.- Desarrolla un codigo que compruebe que se cumple el LSP\n\"\"\"\n\n\nclass Vehicle():\n    def __init__(self, speed=0):\n        self.speed = speed\n\n    def speed_up(self, increment):\n        self.speed += increment\n        print(f\"Velocidad: {self.speed} km\\h\")\n\n    def brake(self, decrement):\n        self.speed -= decrement\n        if self.speed <= 0:\n            self.speed = 0\n        print(f\"Velocidad: {self.speed} km\\h\")\n\n\nclass Truck(Vehicle):\n    def speed_up(self, increment):\n        print(\"El camion esta acelerando\")\n        super().speed_up(increment)\n\n    def brake(self, decrement):\n        print(\"El camion esta frenando\")\n        super().brake(decrement)\n\n\nclass Motorcycle(Vehicle):\n    def speed_up(self, increment):\n        print(\"La motocicleta esta acelerando\")\n        super().speed_up(increment)\n\n    def brake(self, decrement):\n        print(\"La motocicleta esta frenando\")\n        super().brake(decrement)\n\n\nclass Airplane(Vehicle):\n    def speed_up(self, increment):\n        print(\"El avion esta acelerando\")\n        super().speed_up(increment)\n\n    def brake(self, decrement):\n        print(\"El avion esta frenando\")\n        super().brake(decrement)\n\n\ndef test_vehicle(vehicle):\n    vehicle.speed_up(2)\n    vehicle.brake(1)\n\n\ncamion = Truck()\nmoto = Motorcycle()\navion = Airplane()\n\ntest_vehicle(camion)\ntest_vehicle(moto)\ntest_vehicle(avion)\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/BastianAlq.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * Explora el \"Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)\" \n#  * y crea un ejemplo simple donde se muestre su funcionamiento\n#  * de forma correcta e incorrecta.\n#  *\n# ---------------------------------------\n# | LISKOV SUBSTITUTION PRINCIPLE (LSP)  |  Información extraída de -> https://devexpert.io/principios-solid-guia-gratis/ \n# ---------------------------------------\n\n# El principio de sustitucion de liskov (LSP) dice que si en alguna parte del codigo una clase extiende de otra, tenemos\n# que poder utilizar cualquiera de las clases hijas y el programa debe seguir siendo válido, esto asegura que cuando extendamos\n# una clase, no se esté alterando el comportamiento del padre.\n#\n# ¿COMO DETECTAR QUE ESTAMOS VIOLANDO EL PRINCIPIO DE SUSTITUCION DE LISKOV?\n#  - cuando en una clase que extiende de otra, existen metodos que sobran, y no sabes que hacer con ellos\n#  - si un metodo escrito no hace nada o lanza una excepcion, lo mas probable es que estes violando el (LSP)\n#  - otra forma de identificarlo son los test. si los test funcionan para la clase padre pero no para la clase hija\n#    entonces estas violando dicho principio\n\n\n# FORMA INCORRECTA\nprint(\"------------ FUNCIONAMIENTO INCORRECTO LSP ------------\")\n\nprint()\nclass Animal:\n    def jump(self):\n        print(\"Ha saltado\")\n    \n    def walk(self):\n        print(\"Está caminando\")\n\nclass Dog(Animal):\n    def __init__(self) -> None:\n        super().__init__()\n\nclass Elephant(Animal):\n    def jump(self):\n        raise Exception(\"Los elefantes no pueden saltar\")\n\nelephant_noLiskov  = Elephant()\ndog_noLiskov = Dog()\n\ndog_noLiskov.jump()\ndog_noLiskov.walk()\n\nelephant_noLiskov.walk()\n# elephant_noLiskov.jump() error ya que no pueden saltar los elefantes\n\n\n# FORMA CORRECTA\nprint(\"------------ FUNCIONAMIENTO CORRECTO LSP ------------\")\n\nclass Animal:\n    def walk(self):\n        print(\"Esta caminando\")\n\nclass lightWeightAnimal(Animal):\n    def jump(self):\n        print(\"Ha saltado\")\n\nclass Dog(lightWeightAnimal):\n    def __init__(self) -> None:\n        super().__init__()\n\nclass Elephant(Animal):\n    def __init__(self) -> None:\n        super().__init__()\n\ndog_liskov  = Dog()\nelephant_liskov = Elephant()\n\ndog_liskov.jump()\ndog_liskov.walk()\n\nelephant_liskov.walk()\n\n# DIFICULTAD EXTRA\n\nprint(\"------------ DIFICULTAD EXTRA ------------\")\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n#  * cumplir el LSP.\n#  * Instrucciones:\n#  * 1. Crea la clase Vehículo.\n#  * 2. Añade tres subclases de Vehículo.\n#  * 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n#  * 4. Desarrolla un código que compruebe que se cumple el LSP.\n#  */\n\nclass Vehicle:\n    def __init__(self, speed = 0) -> None:\n        self.speed = speed\n\n    def accelerate(self,increment):\n        self.speed = self.speed + increment\n        print(f\"velocidad: {self.speed} km/h\")\n    \n    def brake(self, decrement):\n        self.speed = self.speed - decrement\n        if self.speed < 0:\n            self.speed = 0\n        print(f\"velocidad: {self.speed} km/h\")\n\n\nclass Car(Vehicle):\n    def __init__(self) -> None:\n        super().__init__()\n    \n    def brake(self,decrement):\n        print(\"el auto esta frenando...\")\n        super().brake(decrement)\n    \n    def accelerate(self,increment):\n        print(\"el auto ha acelerado\")\n        super().accelerate(increment)\n        \n\nclass Truck(Vehicle):\n    def __init__(self) -> None:\n        super().__init__()\n    \n    def brake(self, decrement):\n        print(\"el camion esta frenando...\")\n        super().brake(decrement)\n    \n    def accelerate(self,increment):\n        print(\"el camion esta acelerando...\")\n        super().accelerate(increment)\n\nclass MotorBike(Vehicle):\n    def __init__(self) -> None:\n        super().__init__()\n        \n    def brake(self,decrement):\n        print(\"la moto esta frenando...\")\n        super().brake(decrement)\n    \n    def accelerate(self,increment):\n        print(\"la moto esta acelerando...\")\n        super().accelerate(increment)\n\n\ndef testVehicles(vehicle):\n    vehicle.accelerate(10)\n    vehicle.brake(3)\n\ncar = Car()\ntruck = Truck()\nmotorBike = MotorBike()\n\ntestVehicles(car)\ntestVehicles(truck)\ntestVehicles(motorBike)"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/CesarCarmona30.py",
    "content": "'''\n  EJERCICIO\n'''\n\n# Incorrecto\n\nclass Bird:\n  def fly(self):\n    return \"Flying\"\n  \n\nclass Chicken(Bird):\n  def fly(self):\n    raise Exception(\"Los pollos no vuelan\")\n  \n# bird = Bird()\n# bird.fly()\n# chicken = Chicken()\n# chicken.fly()\n\n# Correcto\n\nclass Bird:\n  def move(self):\n    return \"Moving\"\n  \nclass Chicken(Bird):\n  def move(self):\n    return \"Walking\"\n\nclass Crow(Bird):\n  def move(self):\n    return \"Flying\"\n  \nbird = Bird()\nprint(bird.move())\nchicken = Chicken()\nprint(chicken.move())\ncrow = Crow()\nprint(crow.move())\n\nbird = Chicken()\nprint(bird.move())\nchicken = Crow()\nprint(chicken.move())\ncrow = Bird()\nprint(bird.move())\n\n'''\n  EXTRA\n'''\n\nclass Vehicle:\n  def __init__(self, speed = 0):\n    self.speed = speed\n\n  def accelerate(self, increment):\n    self.speed += increment\n    print(f'Velocidad: {self.speed} Km/h')\n\n  def brake(self, decrement):\n    self.speed -= decrement\n    if self.speed <= 0:\n      self.speed = 0\n    print(f'Velocidad: {self.speed} Km/h')\n\nclass Car(Vehicle):\n  def accelerate(self, increment):\n    print(\"El coche está acelerando\")\n    super().accelerate(increment)\n\n  def brake(self, decrement):\n    print(\"El coche está frenando\")\n    super().brake(decrement)\n\n\nclass Bicycle(Vehicle):\n  def accelerate(self, increment):\n    print(\"La bicicleta está acelerando\")\n    super().accelerate(increment)\n  \n  def brake(self, decrement):\n    print(\"La bicicleta está frenando\")\n    super().brake(decrement)\n\nclass Motorcycle(Vehicle):\n  def accelerate(self, increment):\n    print(\"La motocicleta está acelerando\")\n    super().accelerate(increment)\n  \n  def brake(self, decrement):\n    print(\"La motocicleta está frenando\")\n    super().brake(decrement)\n\ndef test_vehicle(vehicle):\n  vehicle.accelerate(2)\n  vehicle.brake(1)\n\ncar = Car()\nbicycle = Bicycle()\nmotorcycle = Motorcycle()\n\ntest_vehicle(car)\ntest_vehicle(bicycle)\ntest_vehicle(motorcycle)"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/Chrisdev00.py",
    "content": "\"\"\"\n* EJERCICIO:\n* Explora el \"Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)\" \n* y crea un ejemplo simple donde se muestre su funcionamiento\n* de forma correcta e incorrecta.\n*\n* DIFICULTAD EXTRA (opcional):\n* Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n* cumplir el LSP.\n* Instrucciones:\n* 1. Crea la clase Vehículo.\n* 2. Añade tres subclases de Vehículo.\n* 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n* 4. Desarrolla un código que compruebe que se cumple el LSP.\n\"\"\"\n\n# Forma incorrecta sin aplicar el principio LSP\n\nclass Content:\n    def render(self):\n        pass\n    def get_summary(self):\n        pass\n\nclass Article(Content):\n    def __init__(self, title, body):\n        self.title = title\n        self.body = body\n    def render(self):\n        return f\"{self.title}<p>{self.body}</p>\"    \n    def get_summary(self):\n        return self.body[:100] + \"...\"\n    \nclass Video(Content):\n    def __init__(self, title, video_url):\n        self.title = title\n        self.video_url = video_url\n    def render(self):\n        return f\"{self.title}<video src='{self.video_url}' controls></video>\"    \n    def get_summary(self):\n        return f\"{self.title} (Video)\"\n    \nclass ImageGallery(Content):\n    def __init__(self, title, images):\n        self.title = title\n        self.images = images\n    def render(self):\n        image_tags = \"\".join([f\"imgagen '{image}' \" for image in self.images])\n        return f\"{self.title}{image_tags}\"    \n    def get_summary(self):\n        return f\"{self.title} ({len(self.images)} images)\"\n    \nclass Audio(Content):\n    def __init__(self, title, audio_url):\n        self.title = title\n        self.audio_url = audio_url\n    def render(self):\n        return f\"{self.title}<audio src='{self.audio_url}' controls></audio>\"    \n    def get_summary(self):\n        return f\"{self.title} (Audio)\"    \n\ndef display_content(content):\n    if isinstance(content, Article):\n        print(\"Rendering Article:\")\n        print(content.render())\n        print(\"Summary:\")\n        print(content.get_summary())\n    elif isinstance(content, Video):\n        print(\"Rendering Video:\")\n        print(content.render())\n        print(\"Summary:\")\n        print(content.get_summary())\n    elif isinstance(content, ImageGallery):\n        print(\"Rendering Image Gallery:\")\n        print(content.render())\n        print(\"Summary:\")\n        print(content.get_summary())\n    elif isinstance(content, Audio):\n        print(\"Rendering Audio:\")\n        print(content.render())\n        print(\"Summary:\")\n        print(content.get_summary())\n    else:\n        print(\"Unknown content type\")\n\narticle = Article(\"My Article\", \"This is the body of my article.\")\nvideo = Video(\"My Video\", \"http://example.com/video.mp4\")\nimage_gallery = ImageGallery(\"My Gallery\", [\"http://example.com/image1.jpg\", \"http://example.com/image2.jpg\"])\naudio = Audio(\"My Audio\", \"http://example.com/audio.mp3\")\n\ndisplay_content(article)\ndisplay_content(video)\ndisplay_content(image_gallery)\ndisplay_content(audio)\n\n\n# Forma correcta de aplicar el principio LSP\n\nfrom abc import ABC, abstractmethod\n\nclass Content(ABC):\n    @abstractmethod\n    def render(self):\n        pass\n    @abstractmethod\n    def get_summary(self):\n        pass\n\nclass Article(Content):\n    def __init__(self,title,body):\n        self.title = title\n        self.body = body\n    def render(self):\n        return f\"Titulo: {self.title} // Parrafo: {self.body}\"    \n    def get_summary(self):\n        return self.body[:100] + \"...\"\n    \nclass Video(Content):\n    def __init__(self, title, video_url):\n        self.title = title\n        self.video_url = video_url\n    def render(self):\n        return f\"{self.title} - <url='{self.video_url}'>\"    \n    def get_summary(self):\n        return f\"{self.title} (Video)\"\n    \nclass ImageGallery(Content):\n    def __init__(self, title, images):\n        self.title = title\n        self.images = images\n    def render(self):\n        image_tags = \"\".join([f\"<img src='{image}' />\" for image in self.images])\n        return f\"{self.title}:{image_tags}\"    \n    def get_summary(self):\n        return f\"{self.title} ({len(self.images)} images)\"\n    \nclass Audio(Content):\n    def __init__(self, title, audio_url):\n        self.title = title\n        self.audio_url = audio_url\n    def render(self):\n        return f\"{self.title} - <url='{self.audio_url}'>\"    \n    def get_summary(self):\n        return f\"{self.title} (Audio)\"\n    \n\ndef display_content(content: Content):\n    print(\"Rendering content:\")\n    print(content.render())\n    print(\"Summary:\")\n    print(content.get_summary())\n\n\narticle = Article(\"My Article\", \"This is the body of my article.\")\nvideo = Video(\"My Video\", \"http://example.com/video.mp4\")\nimage_gallery  = ImageGallery(\"My Gallery\", [\"http://example.com/image1.jpg\", \"http://example.com/image2.jpg\"])\naudio = Audio(\"My Audio\", \"http://example.com/audio.mp3\")\n\ndisplay_content(article)\ndisplay_content(video)\ndisplay_content(image_gallery)\ndisplay_content(audio)\n\n\n################ ------------------------------ EXTRA ---------------------------------- ##############################\n\nfrom abc import ABC, abstractmethod\n\nclass Vehicle(ABC):\n    def __init__(self, max_speed):\n        self.current_speed = 0\n        self.max_speed = max_speed\n\n    @abstractmethod\n    def accelerate(self, increment):\n        pass\n\n    @abstractmethod\n    def brake(self, decrement):\n        pass\n\n    def __str__(self):\n        return \"Vehicle\"\n\nclass Car(Vehicle):\n    def __init__(self, max_speed):\n        super().__init__(max_speed)\n\n    def accelerate(self, increment):\n        new_speed = self.current_speed + increment\n        if new_speed <= self.max_speed:\n            self.current_speed = new_speed\n        else:\n            self.current_speed = self.max_speed\n\n    def brake(self, decrement):\n        new_speed = self.current_speed - decrement\n        if new_speed >= 0:\n            self.current_speed = new_speed\n        else:\n            self.current_speed = 0\n\n    def __str__(self):\n        return \"Auto\"\n\nclass Motorcycle(Vehicle):\n    def __init__(self, max_speed):\n        super().__init__(max_speed)\n\n    def accelerate(self, increment):\n        new_speed = self.current_speed + increment\n        if new_speed <= self.max_speed:\n            self.current_speed = new_speed\n        else:\n            self.current_speed = self.max_speed\n\n    def brake(self, decrement):\n        new_speed = self.current_speed - decrement\n        if new_speed >= 0:\n            self.current_speed = new_speed\n        else:\n            self.current_speed = 0\n\n    def __str__(self):\n        return \"Motocicleta\"\n\nclass Bicycle(Vehicle):\n    def __init__(self, max_speed):\n        super().__init__(max_speed)\n\n    def accelerate(self, increment):\n        new_speed = self.current_speed + increment\n        if new_speed <= self.max_speed:\n            self.current_speed = new_speed\n        else:\n            self.current_speed = self.max_speed\n\n    def brake(self, decrement):\n        new_speed = self.current_speed - decrement\n        if new_speed >= 0:\n            self.current_speed = new_speed\n        else:\n            self.current_speed = 0\n\n    def __str__(self):\n        return \"Bicicleta\"\n\ndef test_vehicle(vehicle: Vehicle):\n    print(f\"Datos {vehicle}:\")\n    print(f\"Velocidad inicial: {vehicle.current_speed} km/h\")\n    vehicle.accelerate(50)\n    print(f\"Velocidad despues de acelerar: {vehicle.current_speed} km/h\")\n    vehicle.brake(20)\n    print(f\"Velocidad despues de frenar: {vehicle.current_speed} km/h\")\n    print()\n\ncar = Car(180)\nmotorcycle = Motorcycle(150)\nbicycle = Bicycle(40)\n\ntest_vehicle(car)\ntest_vehicle(motorcycle)\ntest_vehicle(bicycle)"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/EmmanuelMMontesinos.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n * cumplir el LSP.\n * Instrucciones:\n * 1. Crea la clase Vehículo.\n * 2. Añade tres subclases de Vehículo.\n * 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n * 4. Desarrolla un código que compruebe que se cumple el LSP.\n */\n\"\"\"\n'Sin Aplicar'\nclass Pedido:\n    def __init__(self,id:int, productos:list[str,int,int]) -> None:\n        self.id = id\n        self.productos = productos\n\n    def calcular_total(self):\n        total = 0\n        for producto,precio,cantidad in self.productos:\n            parcial = precio * cantidad\n            print(f\"{producto} - {precio} * {cantidad} = {parcial}\")\n            total += parcial\n        print(f\"\\nTotal: {total}\")\n\nclass PedidoVip(Pedido):\n    def __init__(self, id: int, productos: list[str,int,int]) -> None:\n        super().__init__(id, productos)\n\n    def calcular_total(self,descuento:float):\n        total = 0\n        for producto,precio,cantidad in self.productos:\n            parcial = precio * cantidad\n            print(f\"{producto} - {precio} * {cantidad} = {parcial}\")\n            total += parcial\n        print(f\"\\nTotal: {total / descuento}\")\n\n# Prueba\npedido_1 = Pedido(1,[[\"Pizza\", 9.50, 4]])\npedido_vip = PedidoVip(2,[[\"Pizza Baracoa\", 12.50, 2]])\ntry:\n    pedido_1.calcular_total()\n    pedido_vip.calcular_total()\n\nexcept TypeError as e:\n    print(f\"Error: {e}\")\n\n'Aplicado'\nclass Pedido2:\n    def __init__(self,id:int, productos:list[str,int,int]) -> None:\n        self.id = id\n        self.productos = productos\n\n    def calcular_total(self):\n        total = 0\n        for producto,precio,cantidad in self.productos:\n            parcial = precio * cantidad\n            print(f\"{producto} - {precio} * {cantidad} = {parcial}\")\n            total += parcial\n        print(f\"\\nTotal: {total}\")\n        return total\n\nclass Pedido2Vip(Pedido2):\n    def __init__(self, id: int, productos: list[str]) -> None:\n        super().__init__(id, productos)\n\n    def calcular_total(self):\n        total =  super().calcular_total()\n        total_descuento = total - total * 0.10\n        print(f\"Total con descuento Vip (10% = {total * 0.10}): {total_descuento}€\")\n\n# Prueba\npedido2_1 = Pedido2(1,[[\"Pizza\", 9.50, 4]])\npedido2_vip = Pedido2Vip(2,[[\"Pizza Baracoa\", 12.50, 2]])\npedido2_1.calcular_total()\npedido2_vip.calcular_total()\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n * cumplir el LSP.\n * Instrucciones:\n * 1. Crea la clase Vehículo.\n * 2. Añade tres subclases de Vehículo.\n * 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n * 4. Desarrolla un código que compruebe que se cumple el LSP.\n\"\"\"\nclass Vehiculo:\n    def __init__(self,nombre) -> None:\n        self.nombre = nombre\n        self.velocidad = 0\n        self.medida_vel = None\n\n    def acelerar(self):\n        print(f\"{self.nombre} acelerando\")\n\n    def frenar(self):\n        print(f\"{self.nombre} frenando\")\n\n    def mostrar_velocidad(self):\n        print(f\"Velocidad actual: {self.velocidad}{self.medida_vel}\\n\")\n\nclass Coche(Vehiculo):\n    def __init__(self, nombre) -> None:\n        super().__init__(nombre)\n        self.medida_vel = \"Km/h\"\n\n    def acelerar(self):\n        if self.velocidad < 120:\n            super().acelerar()\n            self.velocidad += 10\n\n        else:\n            print(f\"{self.nombre} esta en la velocidad máxima\")\n\n        self.mostrar_velocidad()\n\n    def frenar(self):\n        if self.velocidad > 0:\n            super().frenar()\n            self.velocidad -= 10\n\n        else:\n            print(f\"{self.nombre} esta quieto\")\n        self.mostrar_velocidad()\n\n    def mostrar_velocidad(self):\n        super().mostrar_velocidad()\n        \n    \nclass Avion(Vehiculo):\n    def __init__(self, nombre) -> None:\n        super().__init__(nombre)\n        self.medida_vel = \"mph\"\n\n    def acelerar(self):\n        if self.velocidad < 500:\n            super().acelerar()\n            self.velocidad += 20\n\n        else:\n            print(f\"{self.nombre} esta en la velocidad máxima\")\n\n        self.mostrar_velocidad()\n\n    def frenar(self):\n        if self.velocidad > 135:\n            super().frenar()\n            self.velocidad -= 20\n\n        else:\n            print(f\"{self.nombre} esta entrando en perdida, acelere!\")\n        self.mostrar_velocidad()\n\n    def mostrar_velocidad(self):\n        super().mostrar_velocidad()\n\nclass Barco(Vehiculo):\n    def __init__(self, nombre) -> None:\n        super().__init__(nombre)\n        self.medida_vel = \"nudos\"\n\n    def acelerar(self):\n        if self.velocidad < 40:\n            super().acelerar()\n            self.velocidad += 5\n\n        else:\n            print(f\"{self.nombre} esta en la velocidad máxima\")\n\n        self.mostrar_velocidad()\n\n    def frenar(self):\n        if self.velocidad > 0:\n            super().frenar()\n            self.velocidad -= 5\n\n        else:\n            print(f\"{self.nombre} esta a la deriva\")\n        self.mostrar_velocidad()\n\n    def mostrar_velocidad(self):\n        super().mostrar_velocidad()\n\n# Prueba\nmi_vehiculo = Vehiculo(\"Generico\")\nmi_coche = Coche(\"Toyota\")\nmi_avion = Avion(\"Jumbo\")\nmi_barco = Barco(\"Zodiac\")\n\nfor n in range(1,10):\n    mi_coche.acelerar()\n    mi_avion.acelerar()\n    mi_barco.acelerar()\n    mi_vehiculo.acelerar()\n\nfor n in range(1,10):\n    mi_coche.frenar()\n    mi_avion.frenar()\n    mi_barco.frenar()\n    mi_vehiculo.frenar()"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/Gordo-Master.py",
    "content": "# 28 - Solid LSP (Liskov Substitution Principle)\n\n# El principio habla de que una clase hija puede reemplazar a una clase padre.\n# Es un indicador de que si se esta utilizando bien la herencia. Pues si no se cumple, significa que esta mal implementada la herencia\n\nfrom abc import ABC, abstractmethod\n\n# Incorrecto\n\n\"\"\"\nclass Ave:\n    def volar(self):\n        return \"Vuelo\"\n    \nclass Pinguino(Ave):\n    pass\n\npingu = Pinguino()\n\nprint(pingu.volar())\n\"\"\"\n\n# Correcto\n\nclass Ave(ABC):\n\n    @abstractmethod\n    def comer(self):\n        pass\n\nclass Pinguino(Ave):\n\n    def comer(self):\n        return \"Estoy comiendo pescado\"\n    \n    def nadar(self):\n        return \"Nadando\"\n    \n\nclass Aguila(Ave):\n\n    def comer(self):\n        return \"Estoy comiendo raton\"\n    \n    def volar(self):\n        return \"Volando\"\n\n\n\n\"\"\"\nEjercicio Extra\n\"\"\"\n\nclass Vehicle(ABC):\n\n    def __init__(self, speed = 0):\n        self.speed = speed\n    \n    @abstractmethod\n    def accelerate(self, increment):\n        self.speed += increment\n        print(f\"Velocidad: {self.speed} km/h\")\n\n    @abstractmethod\n    def brake(self, decrement):\n        self.speed -= decrement\n        if self.speed <= 0:\n            self.speed = 0\n        print(f\"Velocidad: {self.speed} km/h\")\n\n\nclass Car(Vehicle):\n\n    def accelerate(self, increment):\n        print(\"El auto esta acelerando\")\n        super().accelerate(increment)\n\n    def brake(self, decrement):\n        print(\"El auto esta frenando\")\n        super().brake(decrement)\n\n\nclass Bus(Vehicle):\n\n    def accelerate(self, increment):\n        print(\"El bus esta acelerando\")\n        super().accelerate(increment)\n\n    def brake(self, decrement):\n        print(\"El bus esta frenando\")\n        super().brake(decrement)\n\nclass Skate(Vehicle):\n\n    def accelerate(self, increment):\n        print(\"La patineta esta acelerando\")\n        super().accelerate(increment)\n\n    def brake(self, decrement):\n        print(\"La patineta esta frenando\")\n        super().brake(decrement)\n\ndef test_vehiculo(vehiculo: Vehicle):\n    vehiculo.accelerate(5)\n    vehiculo.brake(3)\n\ncar = Car(50)\nbus = Bus(40)\nskate = Skate(10)\n\ntest_vehiculo(car)\ntest_vehiculo(bus)\ntest_vehiculo(skate)\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/Jairo-Alejandro.py",
    "content": "\"\"\"\nPrincipio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)\n\nSi se tiene una clase base y una subclase que hereda la clase base , se debe poder usar la subclase sin afectar el programa \n\"\"\"\n# Ejemplo incorrecto\nclass Animal():\n\n    def fly(self):\n        pass\n\nclass Bird(Animal):\n\n    def fly(self):\n        print(\"the bird is fly\")\n\nclass Penguin(Animal):\n\n    def fly(self):\n        raise Exception(\"the penguin can't fly\")\n\ndef fly_animal(animal: Animal):\n    animal.fly()\n\nmy_bird = Bird()\nmy_penguin = Penguin()\n\n#fly_animal(my_bird)\n#fly_animal(my_penguin)\n\n# Ejemplo correcto \n\nclass Animal():\n    def move(self):\n        pass\n\nclass can_fly():\n    def fly(self):\n        pass\n\nclass Bird(Animal, can_fly):\n    def move(self):\n        print(\"The Bird is moving\")\n\n    def fly(self):\n        print(\"The Bird is fly\")\n\nclass Penguin(Animal):\n    def move(self):\n        print(\"The penguin is moving\")\n\ndef move_animal(animal: Animal):\n    animal.move()\n\ndef fly_animal(animal: can_fly):\n    animal.fly()\n\nmy_bird = Bird()\nmy_penguin = Penguin()\n\nmove_animal(my_bird)\nmove_animal(my_penguin)\n\nfly_animal(my_bird)\n\n# Dificultad extra \n\nclass Vehicle():\n\n    def accelerate(self):\n        pass\n\n    def brake(self):\n        pass\n\nclass Car(Vehicle):\n\n    def accelerate(self):\n        print(\"the car is accelerate\")\n\n    def brake(self):\n        print(\"the car is braking\")\n\nclass Bicycle(Vehicle):\n\n    def accelerate(self):\n        print(\"the Bicycle is accelerate\")\n    \n    def brake(self):\n        print(\"the Bicycle is braking\")\n\nclass Motorcycle(Vehicle):\n\n    def accelerate(self):\n        print(\"the Motorcycle is accelerate\")\n    \n    def brake(self):\n        print(\"the Motorcycle is braking\")\n\ndef test_vehicle(vehicle: Vehicle):\n    vehicle.accelerate()\n    vehicle.brake()\n\nmy_car = Car()\nmy_bicycle = Bicycle()\nmy_motorcycle = Motorcycle()\n\ntest_vehicle(my_car)\ntest_vehicle(my_bicycle)\ntest_vehicle(my_motorcycle)\n\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/JesusWay69.py",
    "content": "import os, platform\nfrom math import pi\nfrom abc import ABC\nif (platform.platform().startswith(\"macOS\") or platform.platform().startswith(\"Linux\")):\n    os.system('clear')\nelse:\n    os.system('cls')\n\n\"\"\" \n * EJERCICIO:\n * Explora el \"Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n\"\"\"\n\nclass Figure1:\n    def __init__(self, base, height) -> None:\n        self.base = base\n        self.height = height\n    def calculate_area(self):\n        return self.base * self.height\n    \nclass Rectangle1(Figure1):\n    def __init__(self, base, height) -> None:\n        super().__init__(base, height)\n    def calculate_area(self):\n        return super().calculate_area()\n\nclass Square1(Figure1):\n    def __init__(self, base, height) -> None:\n        super().__init__(base, height)\n        self.height = base\n    def calculate_area(self):\n        return super().calculate_area()\n    \nrectangle1 = Rectangle1(2,5).calculate_area()\nsquare1 = Square1(2,5).calculate_area()\nprint(rectangle1)\nprint(square1)\n\n\"\"\"\nEl Principio de Sustitución de Liskov establece que las subclases deben ser sustituibles por sus clases base.\nEn el caso de  no se cumple este principio porque para calcular el área de un cuadrado es innecesario\nel aporte de 2 argumentos (base y altura) aunque en este caso concreto hemos \"trampeado\" la clase para que tome sólo\nun valor e ignore el otro, aun así siguen siendo obligatorios los 2 argumentos aunque el 2do sea innecesario, además\nal tener la misma fórmula de multiplicación simple para calcular el área el método calculate_area nos valdría pero si\nquisiéramos ampliar el programa y añadir una clase que cree objetos circulares y calcular su área ya no nos serviría\nla clase padre y llamar a su método calculate_area \"\"\"\n\n\nclass Figure2(ABC):\n    def __init__(self) -> None:\n        pass\n    def calculate_area(self):\n        return \"Figura no definida\"\n\nclass Rectangle2(Figure2):\n    def __init__(self, arg1, arg2) -> None:\n        self.arg1 = arg1\n        self.arg2 = arg2       \n    def calculate_area(self):\n        return f\"El área del rectángulo con base {self.arg1} y altura {self.arg2} es: {self.arg1 * self.arg2}\"                       \n    \nclass Square2(Figure2):\n    def __init__(self, side) -> None:\n        self.side = side\n    def calculate_area(self):\n        return f\"El área del cuadrado con lado {self.side} es: {self.side ** 2}\"\n    \nclass Circle2(Figure2):\n     def __init__(self, radius) -> None:\n        self.radius = radius\n     def calculate_area(self):\n         return f\"El área del círculo con radio {self.radius} es: {round((self.radius ** 2 * pi),2)}\"\n          \nrectangle2 = Rectangle2(2,5).calculate_area()\nsquare2 = Square2(5).calculate_area()\ncircle2 = Circle2(5).calculate_area()\nfigure2 = Figure2().calculate_area()\n\nprint(rectangle2)\nprint(square2)\nprint(circle2)\nprint(figure2)\nprint()\n\n\"\"\"En este caso creamos una clase abstracta con ABC que defina los métodos a usar en las subclases\n   de esta manera podemos seguir creando sublases con diferentes formas geométricas aplicando a cada una\n   de ellas las funcionalidades concretas de esos métodos tanto los argumentos requeridos al iniciar la instancia\n   como el cálculo del área para cada forma y así respetamos el LSP aunque la clase padre sea sólamente una especie de\n   interface (en python no se pueden declarar como tal) que sirva como plantilla para el resto de clases\"\"\"\n\n\n\n\"\"\" \n * DIFICULTAD EXTRA (opcional):\n * Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n * cumplir el LSP.\n * Instrucciones:\n * 1. Crea la clase Vehículo.\n * 2. Añade tres subclases de Vehículo.\n * 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n * 4. Desarrolla un código que compruebe que se cumple el LSP.\"\"\"\n\n\nclass Vehicle:\n    name = \"vehículo en general\"\n    def accelerate(self):\n        return True\n    def brake(self):\n        return True\n    \nclass Car(Vehicle):\n    name = \"coche\"\n    def accelerate(self):\n        return super().accelerate()\n    def brake(self):\n        return super().brake()\n       \nclass Motorbike(Vehicle):\n    name = \"moto\"\n    def accelerate(self):\n        return super().accelerate()\n    def brake(self):\n        return super().brake()\n      \nclass Truck(Vehicle):\n    name = \"camión\"\n    def accelerate(self):\n        return super().accelerate()\n    def brake(self):\n        return super().brake()\n    \nvehicle = Vehicle()\ncar = Car()\ntruck = Truck()\nmotorbike = Motorbike()\n\ndef lsp(object):\n    print(f\"¿El vehículo '{object.name}' acelera? : {object.accelerate()}\")\n    print(f\"¿El vehículo '{object.name}' frena? : {object.brake()}\")\n\nlsp(vehicle)\nlsp(car)\nlsp(truck)\nlsp(motorbike)\n\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/JheisonQuiroga.py",
    "content": "# Author: Jheison Duban Quiroga Quintero\n# Github: https://github.com/JheisonQuiroga\n\n\"\"\"\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)\"\n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\"\"\"\n\n\n# Violando el LSP\nimport pytest\n\nclass Rectangle:\n    def __init__(self, width=0, height=0):\n        self._width = width\n        self._height = height\n\n    @property\n    def width(self):\n        return self._width\n\n    @width.setter\n    def width(self, value):\n        self._width = value\n\n    @property\n    def height(self):\n        return self._height\n\n    @height.setter\n    def height(self, value):\n        self._height = value\n\n    def get_area(self):\n        return self._width * self._height\n\n\nclass Square(Rectangle):\n    def __init__(self, side):\n        super().__init__(side, side)\n\n    @Rectangle.width.setter\n    def width(self, value):\n        self._width = self._height = value\n\n    @Rectangle.height.setter\n    def height(self, value):\n        self._width = self._height = value\n\n\ndef get_area_test(r: Rectangle):\n    ancho = r.width\n    r.height = 10\n    print(f\"Área esperada de {ancho * 10}, tiene {r.get_area()}\")\n\n\n@pytest.mark.xfail(\"La figura viola el LSP\")\ndef test(r: Rectangle):\n    r.width = 4\n    r.height = 5\n    assert r.get_area() == 20\n\n\nrc = Rectangle(2, 3)\nget_area_test(rc) # Área esperada de 20, tiene 20\n\nsq = Square(5)\nget_area_test(sq) # Área esperada de 50, tiene 100\n# test(sq)\n\n\n# Aplicando el LSP\n# La solución es evitar en este caso la herencia y utilizar clases separadas\n# o una interfaz \n\nfrom abc import ABC, abstractmethod\n\nclass Shape(ABC):\n    @abstractmethod\n    def get_area(self) -> float:\n        pass\n\n\nclass Rectangle(Shape):\n    def __init__(self, width, height):\n        self.width = width\n        self.height = height\n\n    def get_area(self) -> float:\n        return self.width * self.height\n\n\nclass Square(Shape):\n    def __init__(self, side) -> None:\n        self.side = side\n\n    def get_area(self) -> float:\n        return self.side ** 2\n    \n\ndef get_area(shape: Shape):\n    return shape.get_area()\n\n\nfor shape in [Rectangle(5, 4), Square(4)]:\n    print(get_area(shape))\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n * cumplir el LSP.\n * Instrucciones:\n * 1. Crea la clase Vehículo.\n * 2. Añade tres subclases de Vehículo.\n * 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n * 4. Desarrolla un código que compruebe que se cumple el LSP.\n */\n\"\"\"\n\nclass Vehicle(ABC):\n    @abstractmethod\n    def accelerate(self, value) -> str:\n        ...\n\n    @abstractmethod\n    def slow_down(self, value) -> str:\n        ...\n\nclass Car(Vehicle):\n    def __init__(self, speed=0):\n        self.speed = speed\n\n    def accelerate(self, value):\n        if value <= 0:\n            raise ValueError(\"La aceleración no pueden ser cero o inferior\")\n        self.speed += value\n        return f\"Coche acelerando. Velocidad: {self.speed} km/h\"\n    \n    def slow_down(self, value):\n        self.speed = max(0, self.speed - value)\n        return f\"Frenando, velocidad {self.speed} km/h\"\n    \n\nclass Motorcycle(Vehicle):\n    def __init__(self, speed=0):\n        self.speed = speed\n\n    def accelerate(self, value):\n        if value <= 0:\n            raise ValueError(\"La aceleración no pueden ser cero o inferior\")\n        self.speed += value\n        return f\"Moto acelerando. Velocidad: {self.speed} km/h\"\n    \n    def slow_down(self, value):\n        self.speed = max(0, self.speed - value)\n        return f\"Moto frenando, velocidad {self.speed} km/h\"\n\n\nclass Bike(Vehicle):\n    def __init__(self, speed=0):\n        self.speed = speed\n\n    def accelerate(self, value):\n        if value <= 0:\n            raise ValueError(\"La aceleración no pueden ser cero o inferior\")\n        self.speed += value\n        return f\"Bicicleta acelerando. Velocidad: {self.speed} km/h\"\n    \n    def slow_down(self, value):\n        self.speed = max(0, self.speed - value)\n        return f\"Bicicleta frenando, velocidad {self.speed} km/h\"\n\n\ndef test_vehicle(obj: Vehicle):\n    print(obj.accelerate(10))\n    print(obj.slow_down(5))\n\n\nif __name__ == \"__main__\":\n    \n    vehicles = [Car(), Motorcycle(), Bike()]\n    for vehicle in vehicles:\n        print(type(vehicle).__name__)\n        test_vehicle(vehicle)"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/LucasRebuffo.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)\"\n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n * cumplir el LSP.\n * Instrucciones:\n * 1. Crea la clase Vehículo.\n * 2. Añade tres subclases de Vehículo.\n * 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n * 4. Desarrolla un código que compruebe que se cumple el LSP.\n */ \"\"\"\n\n\"\"\" Principio de Sustitucion de Liskov\n\n    El principio de Liskov platea que si tenemos una clase A y una clase B que hereda de A\n    Las instacias de A pueden ser reemplazadas por instacias de la clase B sin afectar a la\n    integridad del programa\n \"\"\"\n\n\"\"\" Ejemplo forma incorrecta \"\"\"\n\n\nclass Pajaro:\n\n    def comer(self):\n        return \"comida\"\n\n    def cantar(self):\n        return \"canto\"\n\n    def volar(self):\n        if type(self) == type(Avestruz()):\n            raise Exception(\"El avestruz no puede volar\")\n        pass\n\n\nclass Aguila(Pajaro):\n\n    def comer(self):\n        return \"pescado\"\n\n    def cantar(self):\n        return \"chillido\"\n\n\nclass Avestruz(Pajaro):\n\n    def comer(self):\n        return \"comida de avestruz?\"\n\n    def cantar(self):\n        return \"graznido\"\n\n    def volar(self):\n        raise Exception(\"El avestruz no puede volar\")\n\n\n\"\"\" Aca vemos que con el Aguila no hay poblema ya que es intercambiable con Pajaro, pero\n    con el avestruz no, ya que un aveztruz no puede volar. Lo intentamos corregir con la\n    excepcion y agregando un chqeueo en la calse Pajaro pero ahi rompemos el pricipio \n    ya que la clases se tienen que conocer.  \"\"\"\n\n\"\"\" Ejemplo forma correcta \"\"\"\n\n\"\"\" Lo que podemos hacer para solucionar es agregar otra clase PajaroVolador y agreagr el metodo volar alli\"\"\"\n\n\nclass Pajaro:\n\n    def comer(self):\n        return \"comida\"\n\n    def cantar(self):\n        return \"canto\"\n\n\nclass PajaroVolador(Pajaro):\n    def volar(self):\n        # Logica para volar\n        pass\n\n\nclass Aguila(PajaroVolador):\n\n    def comer(self):\n        return \"pescado\"\n\n    def cantar(self):\n        return \"chillido\"\n\n\nclass Avestruz(Pajaro):\n\n    def comer(self):\n        return \"comida de avestruz?\"\n\n    def cantar(self):\n        return \"graznido\"\n\n\n\"\"\" Ahora no necesitamos las excepciones ya que las clases son intercambiables entre si \"\"\"\n\n\"\"\" \n * DIFICULTAD EXTRA (opcional):\n * Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n * cumplir el LSP.\n * Instrucciones:\n * 1. Crea la clase Vehículo.\n * 2. Añade tres subclases de Vehículo.\n * 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n * 4. Desarrolla un código que compruebe que se cumple el LSP.\n */  \"\"\"\n\n\nclass Vehiculo:\n\n    def acelerar(self):\n        pass\n\n    def frenar(self):\n        pass\n\n\nclass Bicicleta(Vehiculo):\n\n    def acelerar(self):\n        print(\"Pedaleando muy fuerte !!!\")\n\n    def frenar(self):\n        print(\"Clavo los frenos !!!\")\n\n\nclass Automovil(Vehiculo):\n\n    def acelerar(self):\n        print(\"Pisteando como un campeon ;)\")\n\n    def frenar(self):\n        print(\"Uff casi te llevas puesto una viejita\")\n\n\nclass Motocicleta(Vehiculo):\n\n    def acelerar(self):\n        print(\"Estas para el rally Dakar \")\n\n    def frenar(self):\n        print(\"Darrapas 5 metros y te frenas\")\n\n\nbici = Bicicleta()\nmoto = Motocicleta()\nauto = Automovil()\n\nbici.acelerar()\nbici.frenar()\n\nauto.acelerar()\nauto.frenar()\n\nmoto.acelerar()\nmoto.frenar()\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/Mauricio-Leyva.py",
    "content": "\"\"\"\nMauricio Leyva\n\nJerarquía de vehículos que cumple con el Principio de Sustitución de Liskov (LSP).\nTodos los vehículos deben poder acelerar y frenar.\n\nInstrucciones:\n1. Crea la clase Vehículo.\n2. Añade tres subclases de Vehículo.\n3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n4. Desarrolla un código que compruebe que se cumple el LSP.\n\"\"\"\n\nfrom abc import ABC, abstractmethod\n\nclass Vehiculo(ABC):\n    def __init__(self):\n        self.velocidad = 0\n\n    @abstractmethod\n    def acelerar(self, incremento):\n        pass\n\n    @abstractmethod\n    def frenar(self, decremento):\n        pass\n\n    def obtener_velocidad(self):\n        return self.velocidad\n\nclass Coche(Vehiculo):\n    def acelerar(self, incremento):\n        self.velocidad += incremento\n        return f\"Coche acelerando. Velocidad actual: {self.velocidad} km/h\"\n\n    def frenar(self, decremento):\n        self.velocidad = max(0, self.velocidad - decremento)\n        return f\"Coche frenando. Velocidad actual: {self.velocidad} km/h\"\n\nclass Motocicleta(Vehiculo):\n    def acelerar(self, incremento):\n        self.velocidad += incremento * 1.2  # Las motos aceleran un poco más rápido\n        return f\"Motocicleta acelerando. Velocidad actual: {self.velocidad} km/h\"\n\n    def frenar(self, decremento):\n        self.velocidad = max(0, self.velocidad - decremento * 1.1)  # Las motos frenan un poco más rápido\n        return f\"Motocicleta frenando. Velocidad actual: {self.velocidad} km/h\"\n\nclass Camion(Vehiculo):\n    def acelerar(self, incremento):\n        self.velocidad += incremento * 0.8  # Los camiones aceleran más lento\n        return f\"Camión acelerando. Velocidad actual: {self.velocidad} km/h\"\n\n    def frenar(self, decremento):\n        self.velocidad = max(0, self.velocidad - decremento * 0.9)  # Los camiones frenan más lento\n        return f\"Camión frenando. Velocidad actual: {self.velocidad} km/h\"\n\ndef probar_vehiculo(vehiculo):\n    print(vehiculo.acelerar(30))\n    print(vehiculo.acelerar(20))\n    print(vehiculo.frenar(10))\n    print(vehiculo.frenar(15))\n    print(f\"Velocidad final: {vehiculo.obtener_velocidad()} km/h\")\n    print(\"-\" * 50)\n\n# Comprobación del LSP\nvehiculos = [Coche(), Motocicleta(), Camion()]\n\nfor v in vehiculos:\n    print(f\"Probando {v.__class__.__name__}:\")\n    probar_vehiculo(v)"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/Nicojsuarez2.py",
    "content": "# #28 SOLID: PRINCIPIO DE SUSTITUCIÓN DE LISKOV (LSP)\n> #### Dificultad: Media | Publicación: 08/07/24 | Corrección: 15/07/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n * cumplir el LSP.\n * Instrucciones:\n * 1. Crea la clase Vehículo.\n * 2. Añade tres subclases de Vehículo.\n * 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n * 4. Desarrolla un código que compruebe que se cumple el LSP.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/Sac-Corts.py",
    "content": "# Correcto\nclass Bird:\n    def fly(self):\n        return \"Bird is flying\"\n    \nclass Sparrow(Bird):\n    def fly(self):\n        return \"Sparrow is flying\"\n    \nclass Eagle(Bird):\n    def fly(self):\n        return \"Eagle is flying\"\n\ndef make_bird_fly(bird: Bird):\n    print(bird.fly())\n\nsparrow = Sparrow()\neagle = Eagle()\n\nmake_bird_fly(sparrow)\nmake_bird_fly(eagle)\n\n# Incorrecto\nclass Penguin(Bird):\n    def fly(self):\n        raise Exception(\"Penguins can't fly\")\n\npenguin = Penguin()\ntry:\n    make_bird_fly(penguin)\nexcept Exception as e:\n    print(e) \n\n\n### Ejercicio Extra ###\nclass Vehicle:\n    def accelerate(self):\n        raise NotImplementedError(\"You must implement the accelerate method\")\n\n    def brake(self):\n        raise NotImplementedError(\"You must implement the brake method\")\n\nclass Car(Vehicle):\n    def accelerate(self):\n        return \"Car is accelerating\"\n    \n    def brake(self):\n        return \"Car is braking\"\n\nclass Motorcycle(Vehicle):\n    def accelerate(self):\n        return \"Motorcycle is accelerating\"\n    \n\n    def brake(self):\n        return \"Motorcycle is braking\"\n    \nclass Bike(Vehicle):\n    def accelerate(self):\n        return \"Bike is accelerating\"\n    \n    def brake(self):\n        return \"Bike is braking\"\n\n\ndef test_vehicle(vehicle: Vehicle):\n    print(vehicle.accelerate())\n    print(vehicle.brake())\n\ncar = Car()\nmotorcycle = Motorcycle()\nbike = Bike()\n\ntest_vehicle(car)\ntest_vehicle(motorcycle)\ntest_vehicle(bike)"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/SooHav.py",
    "content": "# 28 SOLID: PRINCIPIO DE SUSTITUCIÓN DE LISKOV (LSP)\nfrom abc import ABC, abstractmethod\n# Ejercicio\n\n\nclass Pato:\n    def __init__(self, tipo):\n        self.tipo = tipo\n\n\nclass Pato_Acciones(Pato):\n    def vuela(self):\n        if self.tipo in [\"domestico\", \"salvaje\"]:\n            print(f\"El pato {self.tipo} vuela.\")\n        else:\n            print(f\"El pato {self.tipo} no puede volar.\")\n\n    def nada(self):\n        if self.tipo in [\"domestico\", \"salvaje\"]:\n            print(f\"El pato {self.tipo} nada.\")\n        else:\n            print(f\"El pato {self.tipo} no puede nadar.\")\n\n    def dice(self):\n        if self.tipo in [\"domestico\", \"salvaje\", \"plastico\"]:\n            print(f\"El pato {self.tipo} dice Quack.\")\n        else:\n            print(f\"El pato {self.tipo} no puede hacer Quack.\")\n\n\n# Uso\nprint(\"Sin LSP\")\npato1 = Pato_Acciones(tipo=\"salvaje\")\npato2 = Pato_Acciones(tipo=\"domestico\")\npato3 = Pato_Acciones(tipo=\"plastico\")\n\npato1.vuela()\npato1.nada()\npato1.dice()\n\npato2.vuela()\npato2.nada()\npato2.dice()\n\npato3.vuela()\npato3.nada()\npato3.dice()\n\n# Ejemplo Pato con LSP\n\n\nclass Pato (ABC):\n    def __init__(self, tipo):\n        self.tipo = tipo\n\n    @abstractmethod\n    def vuela(self):\n        pass\n\n    @abstractmethod\n    def nada(self):\n        pass\n\n    @abstractmethod\n    def dice(self):\n        pass\n\n\nclass PatoSalvaje(Pato):\n    def __init__(self):\n        super().__init__(\"salvaje\")\n\n    def vuela(self):\n        print(\"El pato salvaje vuela.\")\n\n    def nada(self):\n        print(\"El pato salvaje nada.\")\n\n    def dice(self):\n        print(\"El pato salvaje dice Quack.\")\n\n\nclass PatoDomestico(Pato):\n    def __init__(self):\n        super().__init__(\"domestico\")\n\n    def vuela(self):\n        print(\"El pato doméstico vuela.\")\n\n    def nada(self):\n        print(\"El pato doméstico nada.\")\n\n    def dice(self):\n        print(\"El pato doméstico dice Quack.\")\n\n\nclass PatoPlastico(Pato):\n    def __init__(self):\n        super().__init__(\"plastico\")\n\n    def vuela(self):\n        print(\"El pato de plástico no puede volar.\")\n\n    def nada(self):\n        print(\"El pato de plástico no puede nadar.\")\n\n    def dice(self):\n        print(\"El pato de plástico dice Squeak.\")\n\n\n# Uso\nprint(\"Con LSP\")\npato1 = PatoSalvaje()\npato2 = PatoDomestico()\npato3 = PatoPlastico()\n\npato1.vuela()\npato1.nada()\npato1.dice()\n\npato2.vuela()\npato2.nada()\npato2.dice()\n\npato3.vuela()\npato3.nada()\npato3.dice()\n\n# Extra\n\n\nclass Vehiculo (ABC):\n    def __init__(self, tipo):\n        self.tipo = tipo\n\n    @abstractmethod\n    def acelera(self, velocidad, tiempo):\n        pass\n\n    @abstractmethod\n    def frena(self, velocidad, tiempo):\n        pass\n\n\nclass Moto(Vehiculo):\n    def __init__(self):\n        super().__init__(\"moto\")\n\n    def acelera(self, velocidad_inicial, tiempo):\n        aceleracion = 25  # km/h/s\n        velocidad_final = velocidad_inicial + aceleracion * tiempo\n        return min(velocidad_final, 220)\n\n    def frena(self, velocidad_inicial, tiempo):\n        desaceleracion = 30  # km/h/s\n        velocidad_final = velocidad_inicial - desaceleracion * tiempo\n        return max(velocidad_final, 0)\n\n\nclass Auto(Vehiculo):\n    def __init__(self):\n        super().__init__(\"auto\")\n\n    def acelera(self, velocidad_inicial, tiempo):\n        aceleracion = 15  # km/h/s\n        velocidad_final = velocidad_inicial + aceleracion * tiempo\n        return min(velocidad_final, 240)\n\n    def frena(self, velocidad_inicial, tiempo):\n        desaceleracion = 25  # km/h/s\n        velocidad_final = velocidad_inicial - desaceleracion * tiempo\n        return max(velocidad_final, 0)\n\n\nclass Camion(Vehiculo):\n    def __init__(self):\n        super().__init__(\"camion\")\n\n    def acelera(self, velocidad_inicial, tiempo):\n        aceleracion = 4  # km/h/s\n        velocidad_final = velocidad_inicial + aceleracion * tiempo\n        return min(velocidad_final, 110)\n\n    def frena(self, velocidad_inicial, tiempo):\n        desaceleracion = 12  # km/h/s\n        velocidad_final = velocidad_inicial - desaceleracion * tiempo\n        return max(velocidad_final, 0)\n\n\n# Uso\nprint(\"Con LSP\")\nmoto = Moto()\nauto = Auto()\ncamion = Camion()\n\n# Ejemplo  para acelerar y frenar\nvelocidad_inicial = 25\ntiempo_acelerar = 4\ntiempo_frenar = 2\n\nvelocidad_acelerada = moto.acelera(velocidad_inicial, tiempo_acelerar)\nvelocidad_frenada = moto.frena(velocidad_acelerada, tiempo_frenar)\nprint(f\"La velocidad de la moto después de acelerar durante {\n      tiempo_acelerar} segundos es de {velocidad_acelerada} km/h\")\nprint(f\"La velocidad de la moto después de frenar durante {\n      tiempo_frenar} segundos es de {velocidad_frenada} km/h\")\n\nvelocidad_acelerada = auto.acelera(velocidad_inicial, tiempo_acelerar)\nvelocidad_frenada = auto.frena(velocidad_acelerada, tiempo_frenar)\nprint(f\"La velocidad del auto después de acelerar durante {\n      tiempo_acelerar} segundos es de {velocidad_acelerada} km/h\")\nprint(f\"La velocidad del auto después de frenar durante {\n      tiempo_frenar} segundos es de {velocidad_frenada} km/h\")\n\nvelocidad_acelerada = camion.acelera(velocidad_inicial, tiempo_acelerar)\nvelocidad_frenada = camion.frena(velocidad_acelerada, tiempo_frenar)\nprint(f\"La velocidad del camion después de acelerar durante {\n      tiempo_acelerar} segundos es de {velocidad_acelerada} km/h\")\nprint(f\"La velocidad del camion después de frenar durante {\n      tiempo_frenar} segundos es de {velocidad_frenada} km/h\")\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/Trufoplus.py",
    "content": "###############################################################################\n### EJERCICIO\n###############################################################################\n### FORMA INCORRECTA\n\nclass Notifier:\n    \"\"\"\n    Clase base abstracta para notificaciones. \n    Define el método send_message que debe ser implementado por las subclases.\n    \"\"\"\n\n    def send_message(self):\n        \"\"\"\n        Método abstracto que debe ser implementado por las subclases.\n        Lanza una excepción NotImplementedError si no se implementa.\n        \"\"\"\n        raise NotImplementedError(\"Este método debe ser anulado\")\n\n\nclass Mobile(Notifier):\n    \"\"\"\n    Clase derivada que implementa el método send_message para enviar un mensaje al móvil.\n    \"\"\"\n\n    def send_message(self):\n        \"\"\"\n        Implementa el método send_message para enviar un mensaje al móvil.\n        \"\"\"\n        return \"Enviando mensaje al móvil\"\n\n\nclass Phone(Notifier):\n    \"\"\"\n    Clase derivada que intenta implementar el método send_message.\n    Sin embargo, no puede enviar mensajes de texto y por lo tanto viola el \n    principio de sustitución de Liskov (LSP).\n    \"\"\"\n\n    def send_message(self):\n        \"\"\"\n        Implementa el método send_message pero no puede enviar mensajes de texto.\n        Esta implementación viola el principio LSP porque Phone no puede \n        ser sustituido por Notifier sin alterar la funcionalidad esperada.\n        \"\"\"\n        return \"Phone can't send messages\"\n\n\n\n### FORMA CORRECTA\n\nclass Notifier:\n    \"\"\"\n    Define un método notify que debe ser implementado por las clases derivadas. \n    Este método se asegura de que cualquier subclase implemente la \n    funcionalidad de notificación.\n    \"\"\"\n    def notify(self):\n        raise NotImplementedError(\"Este método debe ser anulado\")\n\nclass Mobile(Notifier):\n    \"\"\"\n    Hereda de Notifier e implementa el método notify para enviar mensajes.\n    \"\"\"\n    def notify(self):\n        return \"Enviando mensaje al móvil\"\n\nclass Phone(Notifier):\n    \"\"\"\n    Hereda de Notifier e implementa el método notify para hacer llamadas\n    \"\"\"\n    def notify(self):\n        return \"Haciendo llamada con un robot\"\n\n\"\"\"\nEl principio LSP establece que una subclase debe poder ser sustituida por su \nclase base sin alterar el funcionamiento del programa. En este caso, tanto \nMobile como Phone pueden ser tratadas como instancias de Notifier y llamadas \nal método notify se comportarán de manera esperada sin errores. \n\"\"\"\n\n\n\n\n\n###############################################################################\n### DIFICULTAD EXTRA\n###############################################################################\n\"\"\"\n*** Principio de Sustitución de Liskov (LSP):\nPara seguir el principio LSP, las subclases (Car, Motorbike, Bicycle) deben poder \nsustituir a la clase base (Vehicle) sin alterar la funcionalidad esperada del \nprograma. Cada subclase debe implementar los métodos de la clase base de manera \ncoherente.\n\"\"\"\n\n\nclass Vehicle:\n    \"\"\"\n    Clase base para vehículos que define métodos para acelerar y detener.\n    \"\"\"\n\n    def accelerate(self):\n        \"\"\"\n        Método para acelerar el vehículo.\n        \"\"\"\n        return \"The vehicle is accelerating\"\n    \n    def stop(self):\n        \"\"\"\n        Método para detener el vehículo.\n        \"\"\"\n        return \"The vehicle is stopped\"\n\n\nclass Car(Vehicle):\n    \"\"\"\n    Clase derivada que representa un coche, hereda de Vehicle.\n    \"\"\"\n\n    def accelerate(self):\n        \"\"\"\n        Método para acelerar el coche.\n        \"\"\"\n        return \"The car is accelerating\"\n    \n    def stop(self):\n        \"\"\"\n        Método para detener el coche.\n        \"\"\"\n        return \"The car is stopped\"\n\n\nclass Motorbike(Vehicle):\n    \"\"\"\n    Clase derivada que representa una motocicleta, hereda de Vehicle.\n    \"\"\"\n\n    def accelerate(self):\n        \"\"\"\n        Método para acelerar la motocicleta.\n        \"\"\"\n        return \"The motorbike is accelerating\"\n    \n    def stop(self):\n        \"\"\"\n        Método para detener la motocicleta.\n        \"\"\"\n        return \"The motorbike is stopped\"\n\n\nclass Bicycle(Vehicle):\n    \"\"\"\n    Clase derivada que representa una bicicleta, hereda de Vehicle.\n    \"\"\"\n\n    def accelerate(self):\n        \"\"\"\n        Método para acelerar la bicicleta.\n        \"\"\"\n        return \"The bicycle is accelerating\"\n    \n    def stop(self):\n        \"\"\"\n        Método para detener la bicicleta.\n        \"\"\"\n        return \"The bicycle is stopped\"\n\n\n\n# USO:\nvehicles = [Car(), Motorbike(), Bicycle()]\n\nfor vehicle in vehicles:\n    print(vehicle.accelerate())\n    print(vehicle.stop())\n    \n\n\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/adra-dev.py",
    "content": "\"\"\"\nEJERCICIO:\nExplora el \"Principio SOLID de Sustitución de Liskov (Liskov \nSubstitution Principle, LSP)\" y crea un ejemplo simple donde se \nmuestre su funcionamiento de forma correcta e incorrecta.\n\nDIFICULTAD EXTRA(opcional):\nCrea una jerarquía de vehículos. Todos ellos deben poder acelerar y \nfrenar, así como cumplir el LSP.\n\nInstrucciones:\n1. Crea la clase Vehículo.\n2. Añade tres subclases de Vehículo.\n3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n4. Desarrolla un código que compruebe que se cumple el LSP.\n\nby adra-dev\n\"\"\"\n\n\n\"\"\"\nLiskov substitution principle (LSP):\nEl Principio de Sustitución de Liskov  fue introducido por Barbara \nLiskov en la conferencia OOPSLA en 1987. Desde entonces, este \nprincipio ha sido una parte fundamental de la programación orientada \nobjetos. El principio  declara:\n\n    \"Los subtipos deben ser sustituibles por sus tipos base.\"\n\ndocumentacion:\"https://realpython.com/solid-principles-python/\"\n    \nPor ejemplo, si tienes un fragmento de código que funciona con una \nclase Figura, deberías poder sustituir esa clase con cualquiera de sus\nsubclases, como Circulo o Rectangulo, sin romper el código.\n\nEn la práctica, este principio consiste en hacer que las subclases se \ncomporten como sus clases base sin romper las expectativas de nadie \ncuando llaman a los mismos métodos. Para continuar con ejemplos \nrelacionados con las Figuras, supongamos que tiene una clase Rectangle \ncomo la siguiente\n\"\"\"\n# shapes_lsp.py\n\nclass Rectangle:\n    def __init__(self, width, height):\n        self.width = width\n        self.height = height\n\n    def calculate_area(self):\n        return self.width * self.height\n\n\n\"\"\"\nDebido a que un cuadrado es un caso especial de un rectángulo con \nlados iguales, piensaa en derivar una clase Square de Rectangle para\nreutilizar el código. A continuación, se invalida el método setter \npara los atributos .width y .height de modo que cuando cambie un \nlado, también cambie el otro lado\n\"\"\"\n\n# shapes_lsp.py\n\n# ...\n\nclass Square(Rectangle):\n    def __init__(self, side):\n        super().__init__(side, side)\n\n    def __setattr__(self, key, value):\n        super().__setattr__(key, value)\n        if key in (\"width\", \"height\"):\n            self.__dict__[\"width\"] = value\n            self.__dict__[\"height\"] = value\n\n\nsquare = Square(5)\nprint(vars(square))\n\nsquare.width = 7\nprint(vars(square))\n\nsquare.height = 9\nprint(vars(square))\n\n\n\"\"\"\nAhora te has asegurado de que el objeto Square siempre siga siendo un \ncuadrado válido, lo que le facilita la vida por el módico precio de \nun poco de memoria desperdiciada. Desafortunadamente, esto viola el \nprincipio de sustitución de Liskov porque no se pueden reemplazar las\ninstancias de Rectangle con sus contrapartes Square. \n\nCuando alguien espera un objeto Rectangle en su código, puede \nsuponer que se comportará como uno exponiendo dos atributos .width y \n.height independientes. Mientras tanto, la clase Square rompe esa \nsuposición al cambiar el comportamiento prometido por la interfaz del\nobjeto. Eso podría tener consecuencias sorprendentes y no deseadas, \nque probablemente serían difíciles de depurar.\n\nMientras que un cuadrado es un tipo específico de rectángulo en \nmatemáticas, las clases que representan esas formas no deben estar en\nuna relación padre-hijo si desea que cumplan con el principio de \nsustitución de Liskov. Una forma de resolver este problema es crear \nuna clase base para que Rectangle y Square se extiendan\n\n\"\"\"\n\nfrom abc import ABC, abstractmethod\n\nclass Shape(ABC):\n    @abstractmethod\n    def calculate_area(self):\n        pass\n\nclass Rectangle(Shape):\n    def __init__(self, width, height):\n        self.width = width\n        self.height = height\n\n    def calculate_area(self):\n        return self.width * self.height\n\nclass Square(Shape):\n    def __init__(self, side):\n        self.side = side\n\n    def calculate_area(self):\n        return self.side ** 2\n    \n\ndef get_total_area(shapes):\n    return sum(shape.calculate_area() for shape in shapes)\n\nprint(get_total_area([Rectangle(10, 5), Square(5)]))\n\n\n\"\"\"\nExtra\n\"\"\"\n\n\nclass Vehicle:\n\n    def __init__(self, speed=0):\n        self.speed = speed\n\n    def accelerate(self, increment):\n        self.speed += increment\n        print(f\"Velocidad: {self.speed} Km/h\")\n\n    def brake(self, decrement):\n        self.speed -= decrement\n        if self.speed <= 0:\n            self.speed = 0\n        print(f\"Velocidad: {self.speed} Km/h\")\n\n\nclass Car(Vehicle):\n    def accelerate(self, increment):\n        print(\"El coche está acelerando\")\n        super().accelerate(increment)\n\n    def brake(self, decrement):\n        print(\"El coche está frenando\")\n        super().brake(decrement)\n\n\nclass Bicycle(Vehicle):\n    def accelerate(self, increment):\n        print(\"La bicicleta está acelerando\")\n        super().accelerate(increment)\n\n    def brake(self, decrement):\n        print(\"La bicicleta está frenando\")\n        super().brake(decrement)\n\n\nclass Motorcycle(Vehicle):\n    def accelerate(self, increment):\n        print(\"La moto está acelerando\")\n        super().accelerate(increment)\n\n    def brake(self, decrement):\n        print(\"La moto está frenando\")\n        super().brake(decrement)\n\n\ndef test_vehicle(vehicle):\n    vehicle.accelerate(2)\n    vehicle.brake(1)\n\n\ncar = Car()\nbicycle = Bicycle()\nmotorcycle = Motorcycle()\n\ntest_vehicle(car)\ntest_vehicle(bicycle)\ntest_vehicle(motorcycle)\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/agusrosero.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n\"\"\"\n\n# Forma correcta\nclass Bird:\n    def fly(self):\n        return \"Flying\"\n\n\nclass Sparrow(Bird):\n    pass\n\n# Forma incorrecta\nclass Ostrich(Bird):\n    def fly(self):\n        raise NotImplementedError(\"Ostriches can't fly\")\n\n\ndef make_bird_fly(bird):\n    try:\n        return bird.fly()\n    except NotImplementedError as e:\n        return str(e)\n\n\nsparrow = Sparrow()\nostrich = Ostrich()\n\nprint(make_bird_fly(sparrow))\nprint(make_bird_fly(ostrich))\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n * cumplir el LSP.\n * Instrucciones:\n * 1. Crea la clase Vehículo.\n * 2. Añade tres subclases de Vehículo.\n * 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n * 4. Desarrolla un código que compruebe que se cumple el LSP.\n */\n\"\"\"\n\nclass Vehiculos:\n    def __init__(self, name):\n        self.name = name\n\n    def acelerar(self):\n        raise NotImplementedError\n\n    def frenar(self):\n        raise NotImplementedError\n\n\nclass Auto(Vehiculos):\n    def acelerar(self):\n        print(f\"{self.name} esta acelerando..\")\n\n    def frenar(self):\n        print(f\"{self.name} frenando...\")\n\nclass Bicicleta(Vehiculos):\n    def acelerar(self):\n        print(f\"{self.name} esta acelerando\")\n\n    def frenar(self):\n        print(f\"{self.name} estas frenando\")\n\ndef operar_vehiculo(vehiculo):\n    vehiculo.acelerar()\n    vehiculo.frenar()\n\nauto1 = Auto(\"BMW\")\nbici1 = Bicicleta(\"BMX\")\n\noperar_vehiculo(auto1)\noperar_vehiculo(bici1)\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/alanshakir.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n * cumplir el LSP.\n * Instrucciones:\n * 1. Crea la clase Vehículo.\n * 2. Añade tres subclases de Vehículo.\n * 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n * 4. Desarrolla un código que compruebe que se cumple el LSP.\n */\n\"\"\"\n#Incorrecto\n\nclass Animal:\n    def walk():\n        print(\"caminar\")\n    \n    def jump():\n        print(\"saltar\")\n\nclass Elephant(Animal):\n    def jump():\n        raise Exception(\"los elefantes no pueden saltar\")\n\n#Correcto\nclass Animal:\n    def walk():\n        print(\"caminar\")\n\nclass AnimalLiviano(Animal):    \n    def jump():\n        print(\"saltar\")\n\nclass Dog(AnimalLiviano):\n    pass\n\nclass Elephant(Animal):\n    pass\n\n#Extra\n\nclass Vehicle:\n\n    def __init__(self, speed = 0):\n        self.speed = speed\n    \n    def accelerate(self, increment):\n        self.speed += increment\n        print(f\"acelera: {self.speed}\")\n    \n    def brake(self, decrement):\n        self.speed += decrement\n        if self.speed <= 0:\n            self.speed = 0\n        print(f\"frena: {self.speed}\")\n\n\nclass Automobile(Vehicle):\n    def accelerate(self, increment):\n        print(\"El automovil esta acelerando\")\n        super().accelerate(increment)\n    \n    def brake(self, decrement):\n        print(\"El automovil esta frenando\")\n        super().brake(decrement)\n\nclass Motorcycle(Vehicle):\n    def accelerate(self, increment):\n        print(\"La motocicleta esta acelerando\")\n        super().accelerate(increment)\n    \n    def brake(self, decrement):\n        print(\"La motocicleta esta frenando\")\n        super().brake(decrement)\n\nclass Truck(Vehicle):\n    def accelerate(self, increment):\n        print(\"El Camion esta acelerando\")\n        super().accelerate(increment)\n    \n    def brake(self, decrement):\n        print(\"El Camion esta frenando\")\n        super().brake(decrement)\n\ndef drive(vehicle, accelerated, braked):\n    vehicle.accelerate(accelerated)\n    vehicle.brake(braked)\n\n\nauto = Automobile()\nmoto = Motorcycle()\ncamion = Truck()\n\ndrive(auto, 3, 1)\ndrive(moto, 5, 4)\ndrive(camion, 8, 6)\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/avcenal.py",
    "content": "\"\"\"\n* EJERCICIO:\n * Explora el \"Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)\"\n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n\"\"\"\n#LSP incorrecto\nclass Felines():\n    def sound(self):\n        print(\"roar\")\n\nclass Cats(Felines):\n    def sound(self):\n        raise Exception(\"Los gatos no pueden rugir\")\n\none_feline = Felines()\none_feline.sound()\none_cat = Cats()\n#one_cat.sound() Lanza la excepción\n\n#LSP Correcto\nfrom abc import ABC,abstractmethod\n\nclass Feline(ABC):\n    @abstractmethod\n    def sound(self):\n        pass\n\nclass Big_Feline(Feline):\n    def sound(self):\n        print(\"roar\")\n\nclass Small_Feline(Feline):\n    def sound(self):\n        print(\"miau\")\n\nclass Tiger(Big_Feline):\n    pass\n\nclass Cat(Small_Feline):\n    pass\n\nmy_tiger = Tiger()\nmy_tiger.sound()\n\nmy_cat = Cat()\nmy_cat.sound()\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n * cumplir el LSP.\n * Instrucciones:\n * 1. Crea la clase Vehículo.\n * 2. Añade tres subclases de Vehículo.\n * 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n * 4. Desarrolla un código que compruebe que se cumple el LSP.\n\"\"\"\nclass Vehicle(ABC):\n    def __init__(self,speed = 0):\n        super().__init__()\n        self.speed = speed\n\n    @abstractmethod\n    def accelerate(self):\n        pass\n\n    @abstractmethod\n    def slow_down(self):\n        pass\n\nclass F1_Car(Vehicle):\n    def accelerate(self,increment):\n        self.speed += increment + 100\n        return f\"velocidad de {self.speed}\"\n\n    def slow_down(self,decrement):\n        self.speed -= decrement + 15\n        if self.speed <= 0:\n            self.speed = 0\n        return f\"decelera y va a una velocidad de {self.speed}\"\n\nclass Regular_Car(Vehicle):\n    def accelerate(self,increment):\n        self.speed += increment + 50\n        return f\"velocidad de {self.speed}\"\n\n    def slow_down(self,decrement):\n        self.speed -= decrement + 10\n        if self.speed <= 0:\n            self.speed = 0\n        return f\"decelera y va a una velocidad de {self.speed}\"\n\nclass Truck(Vehicle):\n    def accelerate(self,increment):\n        self.speed += increment + 35\n        return f\"velocidad de {self.speed}\"\n\n    def slow_down(self,decrement):\n        self.speed -= decrement + 5\n        if self.speed <= 0:\n            self.speed = 0\n        return f\"decelera y va a una velocidad de {self.speed}\"\n\ndef show_vehicle(name:str,vehicle:Vehicle):\n    print(f\"El vehículo {name} va a una {vehicle.accelerate(20)} km/h. Después {vehicle.slow_down(15)} km/h\")\n\nmy_f1 = F1_Car()\nshow_vehicle(name=\"McLaren\",vehicle=my_f1)\nmy_car = Regular_Car()\nshow_vehicle(name=\"Seat Leon\",vehicle=my_car)\nmy_truck = Truck()\nshow_vehicle(name=\"Mac\",vehicle=my_truck)\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/bytecodesky.py",
    "content": "#28 SOLID: PRINCIPIO DE SUSTITUCIÓN DE LISKOV (LSP)\n\n#  * EJERCICIO:\n#  * Explora el \"Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)\" \n#  * y crea un ejemplo simple donde se muestre su funcionamiento\n#  * de forma correcta e incorrecta.\n\n#El principio LSP establece que los objetos de un programa deben ser reemplazables por instancias de sus subtipos sin alterar la corrección del programa.\n#En otras palabras, si S es un subtipo de T, entonces los objetos de tipo T en un programa pueden ser reemplazados por objetos de tipo S sin alterar el comportamiento del programa.\n\n\n# Ejemplo de código que viola el principio LSP:\n\nclass Bird :\n    def __init__(self, name):\n        self.name = name\n\n    def fly(self):\n        print(f\"{self.name} is flying\")\n\nclass Ostrich(Bird):\n    def fly(self):\n        raise Exception(\"Ostriches can't fly\")\n    \ndef make_bird_fly(bird):\n    bird.fly()\n\nbird = Bird(\"Bird\")\nostrich = Ostrich(\"Ostrich\")\n\nmake_bird_fly(bird)\nmake_bird_fly(ostrich)\n#En este ejemplo, el método fly() de la clase Ostrich viola el principio LSP, ya que el método fly() de la clase Bird lanza una excepción en lugar de volar.\n#Por lo tanto, el objeto de tipo Ostrich no puede reemplazar al objeto de tipo Bird sin alterar el comportamiento del programa.\n\n# Ejemplo de código que cumple con el principio LSP:\n\nclass Bird:\n    def __init__(self, name):\n        self.name = name\n\n    def fly(self):\n        print(f\"{self.name} is flying\")\n\nclass Ostrich:\n    def __init__(self, name):\n        self.name = name\n\n    def fly(self):\n        print(f\"{self.name} can't fly\")\n\ndef make_bird_fly(bird):\n    bird.fly()\n\nbird = Bird(\"Bird\")\nostrich = Ostrich(\"Ostrich\")\n\nmake_bird_fly(bird)\nmake_bird_fly(ostrich)\n#En este ejemplo, el método fly() de la clase Ostrich no viola el principio LSP, ya que el método fly() de la clase Ostrich simplemente imprime que el avestruz no puede volar.\n#Por lo tanto, el objeto de tipo Ostrich puede reemplazar al objeto de tipo Bird sin alterar el comportamiento del programa.\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n#  * cumplir el LSP.\n#  * Instrucciones:\n#  * 1. Crea la clase Vehículo.\n#  * 2. Añade tres subclases de Vehículo.\n#  * 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n#  * 4. Desarrolla un código que compruebe que se cumple el LSP.\n\nclass Vehicle:\n    def __init__(self, name):\n        self.name = name\n\n    def accelerate(self):\n        raise NotImplementedError\n\n    def brake(self):\n        raise NotImplementedError\n    \nclass Car(Vehicle):\n    def accelerate(self):\n        print(f\"{self.name} is accelerating\")\n\n    def brake(self):\n        print(f\"{self.name} is braking\")\n\nclass Bicycle(Vehicle):\n    def accelerate(self):\n        print(f\"{self.name} is pedaling faster\")\n\n    def brake(self):\n        print(f\"{self.name} is braking\")\n\nclass Plane(Vehicle):\n    def accelerate(self):\n        print(f\"{self.name} is taking off\")\n\n    def brake(self):\n        print(f\"{self.name} is landing\")\n\ndef operate_vehicle(vehicle):\n    vehicle.accelerate()\n    vehicle.brake()\n\ncar = Car(\"Car\")\nbicycle = Bicycle(\"Bicycle\")\nplane = Plane(\"Plane\")\n\noperate_vehicle(car)\noperate_vehicle(bicycle)\noperate_vehicle(plane)\n\n#En este ejemplo, la clase Vehicle define los métodos accelerate() y brake() como métodos abstractos que deben ser implementados por las subclases. Las clases Car, Bicycle y Plane implementan estos métodos de acuerdo con el comportamiento esperado de cada vehículo. Por lo tanto, el principio LSP se cumple en este caso, ya que los objetos de las subclases pueden reemplazar a los objetos de la superclase sin alterar el comportamiento del programa."
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/cristianfloyd.py",
    "content": "# EJERCICIO:\n# Explora el \"Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)\"\n# y crea un ejemplo simple donde se muestre su funcionamiento\n# de forma correcta e incorrecta.\nfrom abc import ABC, abstractmethod\n\n\"\"\"\nExplicación del Principio de Sustitución de Liskov (LSP):\nEste principio establece que los objetos de una clase padre deben poder ser reemplazados\npor objetos de sus subclases sin alterar el correcto funcionamiento del programa.\nEn otras palabras, si la clase B es una subclase de la clase A, entonces deberíamos\npoder usar instancias de B en cualquier lugar donde se espere una instancia de A\nsin que el código falle o se comporte de manera inesperada.\n\"\"\"\n\n# --- Ejemplo INCORRECTO ---\nprint(\"--- Ejemplo INCORRECTO ---\")\n\n\nclass Ave:\n    def volar(self):\n        return \"Estoy volando!\"\n\n\nclass Pato(Ave):\n    def volar(self):\n        return \"Estoy volando!\"\n\n\nclass Pinguino(Ave):\n    def volar(self):\n        # Los pingüinos no vuelan, así que esto rompe la expectativa de la clase padre\n        raise Exception(\"Los pingüinos no pueden volar\")\n\n\ndef hacer_volar_ave(ave: Ave):\n    try:\n        print(ave.volar())\n    except Exception as e:\n        print(f\"Error: {e}\")\n\n\npato = Pato()\npinguino = Pinguino()\n\nhacer_volar_ave(pato)  # Funciona: \"Estoy volando!\"\nhacer_volar_ave(pinguino)  # Falla\n\n\n# --- Ejemplo CORRECTO (Cumpliendo LSP) ---\nprint(\"\\n--- Ejemplo CORRECTO ---\")\n\n\nclass AveV2:\n    \"\"\"Clase abstracta para todos los tipos de aves\"\"\"\n\n    @abstractmethod\n    def comer(self) -> str:\n        pass\n\n    @abstractmethod\n    def moverse(self) -> str:\n        \"\"\"metodo mas generico, todas las aves pueden moverse\"\"\"\n        pass\n\n\nclass AveVoladora(AveV2):\n    \"\"\"subclase para aves que pueden volar\"\"\"\n\n    def volar(self) -> str:\n        return \"Estoy volando!\"\n\n    def moverse(self) -> str:\n        return \"Estoy moviendome volando!\"\n\n    def comer(self) -> str:\n        return \"Estoy comiendo!\"\n\n\nclass AveNoVoladora(AveV2):\n    \"\"\"subclase para aves que no pueden volar\"\"\"\n\n    def moverse(self) -> str:\n        return \"Estoy moviendome caminando!\"\n\n    def comer(self) -> str:\n        return \"Estoy comiendo!\"\n\n\nclass Aguila(AveVoladora):\n    def moverse(self) -> str:\n        return \"Estoy moviendome volando!\"\n\n\nclass PinguinoV2(AveNoVoladora):\n    def moverse(self) -> str:\n        return \"Estoy moviendome nadando!\"\n\n\ndef mover_ave(ave: AveV2):\n    print(f\"ave: {ave.__class__.__name__} - {ave.moverse()}\")\n    print(f\"ave: {ave.__class__.__name__} - {ave.comer()}\")\n\n\n# Ejemplo de uso\naguila = Aguila()\npinguino = PinguinoV2()\nmover_ave(aguila)\nmover_ave(pinguino)\n\n\n# DIFICULTAD EXTRA (opcional):\n# Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n# cumplir el LSP.\n# Instrucciones:\n# 1. Crea la clase Vehículo.\n# 2. Añade tres subclases de Vehículo.\n# 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n# 4. Desarrolla un código que compruebe que se cumple el LSP.\n\n\nclass Vehiculo(ABC):\n    def __init__(self, marca: str, modelo: str):\n        self.marca = marca\n        self.modelo = modelo\n        self._velocidad = 0\n        self._velocidad_maxima = 0\n\n    @abstractmethod\n    def acelerar(self) -> str:\n        return \"Acelerando\"\n\n    @abstractmethod\n    def frenar(self) -> str:\n        return \"Frenando\"\n\n    def get_velocidad(self):\n        return self._velocidad\n\n    def get_info(self):\n        return f\"{self.__class__.__name__} - {self.marca} {self.modelo}\"\n\n\nclass Coche(Vehiculo):\n    def __init__(self, marca: str, modelo: str):\n        super().__init__(marca, modelo)\n        self._velocidad_maxima = 200\n\n    def acelerar(self, incremento: int = 10) -> str:\n        velocidad_anterior = self._velocidad\n        self._velocidad = min(self._velocidad + incremento, self._velocidad_maxima)\n\n        if self._velocidad == self._velocidad_maxima:\n            return f\"Velocidad máxima alcanzada: {self._velocidad} km/h\"\n        else:\n            return f\"Acelerando de {velocidad_anterior} a {self._velocidad} km/h\"\n\n    def frenar(self, decremento: int = 10) -> str:\n        velocidad_anterior = self._velocidad\n        self._velocidad = max(self._velocidad - decremento, 0)\n\n        if self._velocidad == 0:\n            return f\"Coche frenando: {velocidad_anterior} -> {self._velocidad} km/h (Detenido)\"\n\n        return f\"Coche frenando: {velocidad_anterior} -> {self._velocidad} km/h\"\n\n\nclass Moto(Vehiculo):\n    def __init__(self, marca: str, modelo: str):\n        super().__init__(marca, modelo)\n        self._velocidad_maxima = 180\n\n    def acelerar(self, incremento: int = 10) -> str:\n        velocidad_anterior = self._velocidad\n        self._velocidad = min(self._velocidad + incremento, self._velocidad_maxima)\n\n        if self._velocidad == self._velocidad_maxima:\n            return f\"Velocidad máxima alcanzada: {self._velocidad} km/h\"\n        else:\n            return f\"Acelerando de {velocidad_anterior} a {self._velocidad} km/h\"\n\n    def frenar(self, decremento: int = 10) -> str:\n        velocidad_anterior = self._velocidad\n        self._velocidad = max(self._velocidad - decremento, 0)\n\n        if self._velocidad == 0:\n            return f\"Moto frenando: {velocidad_anterior} -> {self._velocidad} km/h (Detenido)\"\n\n        return f\"Moto frenando: {velocidad_anterior} -> {self._velocidad} km/h\"\n\n\nclass Camion(Vehiculo):\n    def __init__(self, marca: str, modelo: str, carga_maxima: int):\n        super().__init__(marca, modelo)\n        self._velocidad_maxima = 110\n        self._carga_maxima = carga_maxima\n        self._carga = 0\n\n    def acelerar(self, incremento: int = 10) -> str:\n        velocidad_anterior = self._velocidad\n        self._velocidad = min(self._velocidad + incremento, self._velocidad_maxima)\n\n        if self._velocidad == self._velocidad_maxima:\n            return f\"Velocidad máxima alcanzada: {self._velocidad} km/h\"\n        else:\n            return f\"Acelerando de {velocidad_anterior} a {self._velocidad} km/h\"\n\n    def frenar(self, decremento: int = 10) -> str:\n        velocidad_anterior = self._velocidad\n        self._velocidad = max(self._velocidad - decremento, 0)\n\n        if self._velocidad == 0:\n            return f\"Camion frenando: {velocidad_anterior} -> {self._velocidad} km/h (Detenido)\"\n\n        return f\"Camion frenando: {velocidad_anterior} -> {self._velocidad} km/h\"\n\n    def cargar(self, carga: int) -> str:\n        self._carga += carga\n        return f\"Carga actual: {self._carga}\"\n\n    def descargar(self) -> str:\n        self._carga = 0\n        return \"Carga descargada\"\n\n\ndef probar_vehiculo(vehiculo: Vehiculo) -> None:\n    \"\"\"\n    Funcion que trabaja con cualquier tipo de vehiculo.\n    \"\"\"\n    print(f\"Probando {vehiculo.__class__.__name__}:\")\n    print(f\"Velocidad inicial: {vehiculo.get_velocidad()}\")\n    print(\"Acelerando 3 veces:\")\n    for i in range(3):\n        print(f\"Acelerando {i + 1} vez: {vehiculo.acelerar()}\")\n\n    print(f\"Velocidad actual: {vehiculo.get_velocidad()}\")\n\n    print(\"Frenando 3 veces:\")\n    for i in range(3):\n        print(f\"Frenando {i + 1} vez: {vehiculo.frenar()}\")\n\n    print(f\"Velocidad actual: {vehiculo.get_velocidad()}\")\n\n    print(f\"Info: {vehiculo.get_info()}\")\n\n\ndef verificar_lsp() -> None:\n    \"\"\"\n    Funcion que verifica el LSP.\n    \"\"\"\n    vehiculos: list[Vehiculo] = [\n        Coche(\"Renault\", \"Clio\"),\n        Moto(\"Zanella\", \"Zanella 350\"),\n        Camion(\"Fiat\", \"Doblò\", 10000),\n    ]\n\n    # si es un camion, cargar 5000kg\n    if isinstance(vehiculos[2], Camion):\n        vehiculos[2].cargar(5000)\n\n    # pruebo cada vehiculo con la misma funcion\n    for vehiculo in vehiculos:\n        probar_vehiculo(vehiculo)\n\n    print(\"Verificacion del LSP:\")\n    print(\"Todas las subclases pueden sustituir a la clase base\")\n    print(\"La función probar_vehiculo() funciona con cualquier vehículo\")\n    print(\"No hay excepciones ni comportamientos inesperados\")\n    print(\"Se cumple el Principio de Sustitución de Liskov\")\n\n\nif __name__ == \"__main__\":\n    verificar_lsp()\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/cyberdidac.py",
    "content": "class Vehicle:\n    model: str\n    brand: str\n\n    def __init__(self, model, brand):\n        self.model = model\n        self.brand = brand\n\n    def acelerate(self):\n        pass\n\n    def brake(self):\n        pass\n\n\nclass Car(Vehicle):\n    wheels: int\n    doors: int\n\n    def __init__(self, doors, brand, model):\n        super().__init__(model, brand)\n        self.doors = doors\n        self.wheels = 4\n\n    def acelerate(self):\n        print(\"Acelerando 20 km/h\")\n\n    def brake(self):\n        print(\"Frenando 10 km/h\")\n\n\nclass Motorbike(Vehicle):\n    wheels: int\n\n    def __init__(self, model, brand):\n        super().__init__(model, brand)\n        self.wheels = 2\n\n    def acelerate(self):\n        print(\"Acelerando 30 km/h\")\n\n    def brake(self):\n        print(\"Frenando 40 km/h\")\n\n\nclass ElectricScooter(Vehicle):\n    wheels: int\n\n    def __init__(self, model, brand):\n        super().__init__(model, brand)\n        self.wheels = 2\n\n    def acelerate(self):\n        print(\"Acelerando 5 km/h\")\n\n    def brake(self):\n        print(\"Frenando 10 km/h\")\n\n\ndef main():\n    coche = Car(doors=5, brand=\"ford\", model=\"fiesta\")\n    motorbike = Motorbike(brand=\"honda\", model=\"2001\")\n    scooter = ElectricScooter(brand=\"Xiaomi\", model=\"2020\")\n\n    coche.acelerate()\n    scooter.brake()\n    motorbike.acelerate()\n\n    print(f\"El {coche.brand} {coche.model} tiene {coche.doors} puertas\")\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/davidrguez98.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n * cumplir el LSP.\n * Instrucciones:\n * 1. Crea la clase Vehículo.\n * 2. Añade tres subclases de Vehículo.\n * 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n * 4. Desarrolla un código que compruebe que se cumple el LSP.\n */ \"\"\"\n\n#EJERCICIO\n\n\"\"\" \nIncorrecta\n\"\"\"\n\nclass Bird:\n    def fly(self):\n        return \"Flying\"\n    \nclass Chicken(Bird):\n    def fly(self):\n        raise Exception(\"Los pollos no vuelan.\")\n\n\n\"\"\" \nCorrecta \n\"\"\"\n\nclass Bird:\n    def move(self):\n        return \"Moving\"\n    \nclass Chicken(Bird):\n    def move(self):\n        return \"walk\"\n    \nbird = Bird()\nprint(bird.move())\nchicken = Chicken()\nprint(chicken.move())\n\nbird = Chicken()\nprint(bird.move())\nchicken = Bird()\nprint(chicken.move())\n\n#DIFICULTAD EXTRA\n\nclass Vehicle:\n\n    def accelerate(self):\n        return \"Gas\"\n    \n    def brake(self):\n        return \"Break\"\n\nclass Motorbike(Vehicle):\n\n    def accelerate(self):\n        return \"Motorbike gas\"\n    \n    def brake(self):\n        return \"Motorbike break\"\n\nclass Car(Vehicle):\n    \n    def accelerate(self):\n        return \"Car gas\"\n    \n    def brake(self):\n        return \"Car break\"\n\nclass Truck(Vehicle):\n\n    def accelerate(self):\n        return \"Truck gas\"\n    \n    def brake(self):\n        return \"Truck break\"\n    \nvehicle = Vehicle()\nprint(vehicle.accelerate())\nprint(vehicle.brake())\nmotorbike = Motorbike()\nprint(motorbike.accelerate())\nprint(motorbike.brake())\ncar = Car()\nprint(car.accelerate())\nprint(car.brake())\ntruck = Truck()\nprint(truck.accelerate())\nprint(truck.brake())\n\nvehicle = Motorbike()\nprint(vehicle.accelerate())\nprint(vehicle.brake())\nmotorbike = Car()\nprint(motorbike.accelerate())\nprint(motorbike.brake())\ncar = Truck()\nprint(car.accelerate())\nprint(car.brake())\ntruck = Vehicle()\nprint(truck.accelerate())\nprint(truck.brake())"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/duendeintemporal.py",
    "content": "#28 { Retos para Programadores } Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP) \n\n# Bibliography reference:\n# The Web Development Glossary (Jens Oliver Meiert) (Z-Library)\n# I use GPT as a reference and sometimes to correct or generate proper comments.\n\n\"\"\"  \n * EJERCICIO:\n * Explora el \"Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)\"\n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n * cumplir el LSP.\n * Instrucciones:\n * 1. Crea la clase Vehículo.\n * 2. Añade tres subclases de Vehículo.\n * 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n * 4. Desarrolla un código que compruebe que se cumple el LSP.\n\n \"\"\"\nimport time\n\n# Shorthan for print\nlog = print\n\n# Simulate the loading of the application\ndef main():\n    # Simulate a delay before showing an alert\n    time.sleep(2)\n    log('Retosparaprogramadores #28.')\n\n# Base class for shapes\nclass Shape:\n    def area(self):\n        raise NotImplementedError(\"Method 'area' must be implemented\")\n\n# Rectangle class inheriting from Shape\nclass Rectangle(Shape):\n    def __init__(self, width, height):\n        self.width = width\n        self.height = height\n\n    def area(self):\n        return self.width * self.height\n\n# Square class inheriting from Shape\nclass Square(Shape):\n    def __init__(self, side):\n        self.side = side\n\n    def area(self):\n        return self.side * self.side\n\n# Function to calculate the area of a shape\ndef calculate_area(shape):\n    return shape.area()\n\n# Create instances of Rectangle and Square\nrectangle = Rectangle(83, 105)\nsquare = Square(40)\n\n# Log the areas of the shapes\nlog(calculate_area(rectangle))  # 8715\nlog(calculate_area(square))      # 1600   \n\n# Extra Difficulty Exercise\n\n# Car class definition\nclass Car:\n    def __init__(self, brand, model, max_speed, acceleration, deceleration):\n        self.brand = brand\n        self.model = model\n        self.max_speed = max_speed  # Maximum speed in km/h\n        self.acceleration = acceleration  # Acceleration in km/h per second\n        self.deceleration = deceleration  # Deceleration in km/h per second\n        self.current_speed = 0  # Current speed in km/h\n\n    def accelerate(self, seconds):\n        new_speed = self.current_speed + (self.acceleration * seconds)\n        self.current_speed = min(new_speed, self.max_speed)\n        log(f\"{self.brand} {self.model} accelerated to {self.current_speed} km/h.\")\n\n    def brake(self, seconds):\n        new_speed = self.current_speed - (self.deceleration * seconds)\n        self.current_speed = max(new_speed, 0)\n        log(f\"{self.brand} {self.model} braked to {self.current_speed} km/h.\")\n\n# SportsCar class inheriting from Car\nclass SportsCar(Car):\n    def __init__(self, brand, model):\n        super().__init__(brand, model, 300, 30, 20)  # Hardcoded values for sports cars\n\n# FamilyCar class inheriting from Car\nclass FamilyCar(Car):\n    def __init__(self, brand, model):\n        super().__init__(brand, model, 200, 15, 10)  # Hardcoded values for family cars\n\n# Function to test the car's acceleration and braking\ndef test_car(car):\n    car.accelerate(5) \n    car.brake(2)      \n\n# List of sports cars\nsports_cars = [\n    {\"brand\": \"Ferrari\", \"model\": \"488\", \"max_speed\": 330, \"acceleration\": 30, \"deceleration\": 20},\n    {\"brand\": \"Porsche\", \"model\": \"911 Turbo S\", \"max_speed\": 320, \"acceleration\": 28, \"deceleration\": 18},\n    {\"brand\": \"Lamborghini\", \"model\": \"Huracán\", \"max_speed\": 325, \"acceleration\": 32, \"deceleration\": 22}\n]\n\n# List of family cars\nfamily_cars = [\n    {\"brand\": \"Toyota\", \"model\": \"Sienna\", \"max_speed\": 180, \"acceleration\": 10, \"deceleration\": 8},\n    {\"brand\": \"Honda\", \"model\": \"Odyssey\", \"max_speed\": 175, \"acceleration\": 9, \"deceleration\": 7},\n    {\"brand\": \"Chrysler\", \"model\": \"Pacifica\", \"max_speed\": 180, \"acceleration\": 9, \"deceleration\": 7}\n]\n\n# Create instances of SportsCar and FamilyCar\nsports_car = SportsCar(sports_cars[0]['brand'], sports_cars[0]['model'])  # Using the first sports car from the list\nfamily_car = FamilyCar(family_cars[1]['brand'], family_cars[1]['model'])  # Using the second family car from the list\n\n# Test the cars\ntest_car(sports_car)  # Example output: Ferrari 488 accelerated to 150 km/h.\ntest_car(family_car)  # Example output: Honda Odyssey accelerated to 75 km/h.\n\n# Call the main function to simulate the loading of the application\nif __name__ == \"__main__\":\n    main()\n\n# Output:\n\"\"\"  \nFerrari 488 accelerated to 150 km/h.\nFerrari 488 braked to 110 km/h.\nHonda Odyssey accelerated to 75 km/h.\nHonda Odyssey braked to 55 km/h.\nRetosparaprogramadores #28.\n\n\"\"\""
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/fborjalv.py",
    "content": "\"\"\"\n* DIFICULTAD EXTRA (opcional):\n * Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n * cumplir el LSP.\n * Instrucciones:\n * 1. Crea la clase Vehículo.\n * 2. Añade tres subclases de Vehículo.\n * 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n * 4. Desarrolla un código que compruebe que se cumple el LSP.\n\n\"\"\"\n\nclass Vehiculo:\n    def __init__(self, velocidad=0) -> None:\n        self.velocidad = velocidad\n\n    def acelera(self, aceleracion):\n        self.velocidad += aceleracion\n        print(f\"Velocidad {self.velocidad}\")\n\n    def frena(self, frenado):\n        if self.velocidad <= 0:\n            self.velocidad = 0\n        self.velocidad -= frenado\n        print(f\"Velocidad {self.velocidad}\")\n        \n\nclass Turismo(Vehiculo):\n    def acelera(self, aceleracion):\n        print(\"El turismo está acelerando\")\n        super().acelera(aceleracion)\n    def frena(self, frenado):\n        print(\"El turismo está frenando\")\n        super().frena(frenado)\n\nclass Furgoneta(Vehiculo):\n    def acelera(self, aceleracion):\n        print(\"La furgoneta está acelerando\")\n        super().acelera(aceleracion)\n    def frena(self, frenado):\n        print(\"La furgoneta está frenando\")\n        super().frena(frenado)\n\nclass Camion(Vehiculo):\n    def acelera(self, aceleracion):\n        print(\"El camión está acelerando\")\n        super().acelera(aceleracion)\n    def frena(self, frenado):\n        print(\"El camión está frenando\")\n        super().frena(frenado)\n\n\ndef aplica_LSP(vehiculo):\n    vehiculo.acelera(10)\n    vehiculo.frena(5)\n\nmi_vehiculo = Vehiculo()\nturismo = Turismo()\nfurgoneta = Furgoneta()\ncamion = Camion()\n\naplica_LSP(mi_vehiculo)\naplica_LSP(turismo)\naplica_LSP(furgoneta)\naplica_LSP(camion)"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/franxiscodev.py",
    "content": "\"\"\"\nSOLID\nLSP: principio de sustitución de Liskov\n    \n\"\"\"\n# NO solid\n# incorrecto\n\n\nclass Bird:\n    def fly(self):\n        return \"El ave vuela\"\n\n\nclass Penguin(Bird):\n    def fly(self):\n        raise Exception(\"Los pingüinos no pueden volar\")\n\n# bird = Bird()\n# penguin = Penguin()\n# print(bird.fly()) # Output: El ave vuela\n# print(penguin.fly()) # Output: Exception: Los pingüinos no pueden volar\n# al ser una Excepción no se puede usar el principio de sustitución de Liskov\n\n# SOLID\n# correcto\n\n\nclass Bird:\n    def move(self):\n        return \"El ave se mueve\"\n\n\nclass Penguin(Bird):\n    def move(self):\n        return \"El pingüino nada\"\n\n\nbird = Bird()\npenguin = Penguin()\nprint(bird.move())  # Output: El ave se mueve\nprint(penguin.move())  # Output: El pingüino nada\n# al ser un método diferente no se rompe el principio de sustitución de Liskov\n# se puede usar el principio de sustitución de Liskov\n\n# Extra\n\n\nclass Vehicle:\n    def __init__(self, speed=0) -> None:\n        self.speed = speed\n\n    def accelerate(self, amount):\n        self.speed += amount\n        if self.speed > 120:\n            self.speed = 120\n        return self.speed\n\n    def brake(self, amount):\n        self.speed -= amount\n        if self.speed < 0:\n            self.speed = 0\n        return self.speed\n\n\nclass Car(Vehicle):\n    def accelerate(self, amount):\n        print(f\"Acelerando el coche a {amount} km/h \")\n        super().accelerate(amount)\n\n    def brake(self, amount):\n        print(f\"Frenando el coche a {amount} km/h \")\n        super().brake(amount)\n\n\nclass Bicycle(Vehicle):\n    def accelerate(self, amount):\n        print(f\"Acelerando la bicicleta a {amount} km/h \")\n        super().accelerate(amount / 2)  # Bicicleta acelera más lentamente\n\n    def brake(self, amount):\n        print(f\"Frenando la bicicleta a {amount} km/h \")\n        super().brake(amount / 2)  # Bicicleta frena más lentamente\n\n\nclass Motorcycle(Vehicle):\n    def accelerate(self, amount):\n        print(f\"Acelerando la motocicleta a {amount} km/h \")\n        super().accelerate(amount * 2)  # Motocicleta acelera más rápido\n\n    def brake(self, amount):\n        print(f\"Frenando la motocicleta a {amount} km/h \")\n        super().brake(amount * 2)  # Motocicleta frena más rápido\n\n\ndef test_vehicle(vehicle: Vehicle, acc_amount: int, des_amount: int = 0):\n    vehicle.accelerate(acc_amount)\n    vehicle.brake(des_amount)\n    print(f\"Velocidad final: {vehicle.speed} km/h\")\n\n\ncoche = Car()\nbici = Bicycle()\nmoto = Motorcycle()\n\ntest_vehicle(coche, 135, 5)\ntest_vehicle(bici, 5, 2)\ntest_vehicle(moto, 50, 10)\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/hectorio23.py",
    "content": "# Autor: Héctor Adán\n# GitHub: https://github.com/hectorio23\n\n''' \n- EJERCICIO:\nExplora el \"Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)\" \ny crea un ejemplo simple donde se muestre su funcionamiento\nde forma correcta e incorrecta.\n\n-  DIFICULTAD EXTRA:\nCrea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\ncumplir el LSP.\nInstrucciones:\n1. Crea la clase Vehículo.\n2. Añade tres subclases de Vehículo.\n3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n4. Desarrolla un código que compruebe que se cumple el LSP.\n'''\n\nclass Vehiculo:\n    \"\"\"\n    Clase base abstracta para todos los vehículos. Define dos métodos abstractos\n    que deben ser implementados por las subclases: acelerar y frenar.\n    \"\"\"\n    def acelerar(self):\n        \"\"\"\n        Método abstracto para acelerar. Debe ser implementado por las subclases.\n        \"\"\"\n        raise NotImplementedError(\"Este método debe ser implementado por una subclase.\")\n    \n    def frenar(self):\n        \"\"\"\n        Método abstracto para frenar. Debe ser implementado por las subclases.\n        \"\"\"\n        raise NotImplementedError(\"Este método debe ser implementado por una subclase.\")\n\nclass Coche(Vehiculo):\n    \"\"\"\n    Clase que representa un coche. Implementa los métodos acelerar y frenar\n    de acuerdo a la interfaz definida por la clase base Vehiculo.\n    \"\"\"\n    def acelerar(self):\n        return \"[+] - El coche está acelerando.\"\n    \n    def frenar(self):\n        return \"[+] - El coche está frenando.\"\n\nclass Bicicleta(Vehiculo):\n    \"\"\"\n    Clase que representa una bicicleta. Implementa los métodos acelerar y frenar\n    de acuerdo a la interfaz definida por la clase base Vehiculo.\n    \"\"\"\n    def acelerar(self):\n        return \"[+] - La bicicleta está acelerando.\"\n    \n    def frenar(self):\n        return \"[+] - La bicicleta está frenando.\"\n\nclass Avion(Vehiculo):\n    \"\"\"\n    Clase que representa un avión. Implementa los métodos acelerar y frenar\n    de acuerdo a la interfaz definida por la clase base Vehiculo.\n    \"\"\"\n    def acelerar(self):\n        return \"[+] - El avión está acelerando.\"\n    \n    def frenar(self):\n        return \"[+] - El avión está frenando.\"\n\ndef test_lsp(vehiculo: Vehiculo):\n    \"\"\"\n    Función para probar el principio de sustitución de Liskov (LSP). \n    Toma un objeto Vehiculo y llama a sus métodos acelerar y frenar.\n    \n    Parámetros:\n        vehiculo (Vehiculo): Una instancia de una subclase de Vehiculo.\n    \"\"\"\n    print(vehiculo.acelerar())\n    print(vehiculo.frenar())\n\n# Lista por comprension de diferentes vehículos que cumplen con el LSP\nvehiculos = [Coche(), Bicicleta(), Avion()]\n\n# Probar cada vehículo para asegurar que cumplen con el LSP\nfor v in vehiculos:\n    test_lsp(v)\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/hozlucas28.py",
    "content": "# pylint: disable=pointless-string-statement,missing-class-docstring,missing-function-docstring,missing-module-docstring,too-few-public-methods,broad-exception-raised,line-too-long\n\nfrom abc import ABCMeta, abstractmethod\n\n\"\"\"\n    Liskov Substitution Principle (LCP)...\n\"\"\"\n\nprint(\"Liskov Substitution Principle (LCP)...\")\n\nprint(\"\\nBad implementation of Liskov Substitution Principle (LCP)...\")\n\n\nclass AbcBadVehicle(metaclass=ABCMeta):\n    @abstractmethod\n    def start_engine(self) -> None:\n        pass\n\n\ndef start_engine(vehicle: AbcBadVehicle) -> None:\n    vehicle.start_engine()\n\n\nclass BadCar(AbcBadVehicle):\n    def start_engine(self) -> None:\n        print(\"Car engine started!\")\n\n\nclass BadBicycle(AbcBadVehicle):\n    def start_engine(self) -> None:\n        raise Exception(\"Bicycles don't have engines\")\n\n\nprint(\n    \"\\n```\",\n    \"\"\"class AbcBadVehicle(metaclass=ABCMeta):\n    @abstractmethod\n    def start_engine(self) -> None:\n        pass\n\n\ndef start_engine(vehicle: AbcBadVehicle) -> None:\n    vehicle.start_engine()\n\n\nclass BadCar(AbcBadVehicle):\n    def start_engine(self) -> None:\n        print(\"Car engine started!\")\n\n\nclass BadBicycle(AbcBadVehicle):\n    def start_engine(self) -> None:\n        raise Exception(\"Bicycles don't have engines\")\"\"\",\n    \"```\",\n    sep=\"\\n\",\n)\n\nprint(\n    \"\\nThis is a bad implementation of Liskov Substitution Principle (LCP),\",\n    'because the \"BadBicycle\" class implements the \"start_engine\" method which',\n    'produces a different side effect than the \"start_engine\" method inside the \"BadCar\" class.',\n    'So, if we execute the \"start_engine\" function with both classes (\"BadCar\", and \"BadBicycle\")',\n    \"the function will produce different side effects that could be break the function execution.\",\n    sep=\"\\n\",\n)\n\nprint(\"\\nGood implementation of Liskov Substitution Principle (LCP)...\")\n\n\nclass AbcGoodVehicle(metaclass=ABCMeta):\n    @abstractmethod\n    def move(self) -> None:\n        pass\n\n\ndef start_move(vehicle: AbcGoodVehicle) -> None:\n    vehicle.move()\n\n\nclass GoodCar(AbcGoodVehicle):\n    def move(self) -> None:\n        self.start_engine()\n        print(\"Car is moving!\")\n\n    def start_engine(self) -> None:\n        print(\"Car engine started!\")\n\n\nclass GoodBicycle(AbcGoodVehicle):\n    def move(self) -> None:\n        print(\"Bicycle is moving!\")\n\n\nprint(\n    \"\\n```\",\n    \"\"\"class AbcGoodVehicle(metaclass=ABCMeta):\n    @abstractmethod\n    def move(self) -> None:\n        pass\n\n\ndef start_move(vehicle: AbcGoodVehicle) -> None:\n    vehicle.move()\n\n\nclass GoodCar(AbcGoodVehicle):\n    def move(self) -> None:\n        self.start_engine()\n        print(\"Car is moving!\")\n\n    def start_engine(self) -> None:\n        print(\"Car engine started!\")\n\n\nclass GoodBicycle(AbcGoodVehicle):\n    def move(self) -> None:\n        print(\"Bicycle is moving!\")\"\"\",\n    \"```\",\n    sep=\"\\n\",\n)\n\nprint(\n    \"\\nThis is a good implementation of Liskov Substitution Principle (LCP),\",\n    'because all child classes of \"AbcGoodVehicle\" class implements each method',\n    'with the same side effect. So, if we execute the \"move\" function with both',\n    'classes (\"GoodCar\", and \"GoodBicycle\"), we are not going to have side effects',\n    \"that could break the function execution.\",\n    sep=\"\\n\",\n)\n\nprint(\n    \"\\n# ---------------------------------------------------------------------------------- #\\n\"\n)\n\n\"\"\"\n    Additional challenge...\n\"\"\"\n\nprint(\"Additional challenge...\")\n\n\nclass AbcVehicle(metaclass=ABCMeta):\n    @abstractmethod\n    def brake(self) -> None:\n        pass\n\n    @abstractmethod\n    def speed_up(self) -> None:\n        pass\n\n\ndef brake(*, vehicle: AbcVehicle) -> None:\n    vehicle.brake()\n\n\ndef speed_up(*, vehicle: AbcVehicle) -> None:\n    vehicle.speed_up()\n\n\nclass Car(AbcVehicle):\n    def brake(self) -> None:\n        print(\"Car braking!\")\n\n    def speed_up(self) -> None:\n        print(\"Car speeding up!\")\n\n\nclass Truck(AbcVehicle):\n    def brake(self) -> None:\n        print(\"Truck braking!\")\n\n    def speed_up(self) -> None:\n        print(\"Truck speeding up!\")\n\n\nclass Boat(AbcVehicle):\n    def brake(self) -> None:\n        print(\"Boat braking!\")\n\n    def speed_up(self) -> None:\n        print(\"Boat speeding up!\")\n\n\ncar: Car = Car()\ntruck: Truck = Truck()\nboat: Boat = Boat()\n\nprint()\nspeed_up(vehicle=car)\nspeed_up(vehicle=truck)\nspeed_up(vehicle=boat)\n\nprint()\nbrake(vehicle=car)\nbrake(vehicle=truck)\nbrake(vehicle=boat)\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/idiegorojas.py",
    "content": "\"\"\"\n28 - Principios SOLID: Sustitucion de Liskov\n\"\"\"\n# Si B es un subtipo de A, entonces los objetos de tipo T pueden ser reemplazados por objetos de tipo S\n# Las subclases deben poder sustituir a sus clases base sin que el programa falle o se ocmporte de manera inesperada.\n\n\"\"\"\nBeneficios\n\"\"\"\n# Garantiza la interoperabilidad: Las subclases pueden utilizarse donde se espera una clase base.\n# Mejora la robustez: Reduce errores inesperados cuando se extienden las clases.\n# Facilita el testing: Las pruebas funcionan correctamente tanto con la clase base como con sus derivadas.\n# Promueve un mejor diseño: Te obliga a pensar cuidadosamente en las relaciones entre clases.\n\n\"\"\"\nEjemplo:\n\"\"\"\n\nfrom abc import ABC, abstractmethod\nfrom typing import List, Optional\n\n# Definimos interfaces separadas con contratos claros\nclass Notificador(ABC):\n    @abstractmethod\n    def enviar_notificacion_simple(self, destinatario: str, asunto: str, mensaje: str) -> bool:\n        \"\"\"Envía una notificación básica sin archivos\"\"\"\n        pass\n\nclass NotificadorConAdjuntos(Notificador):\n    @abstractmethod\n    def enviar_con_adjuntos(self, destinatario: str, asunto: str, mensaje: str, archivos: List[str]) -> bool:\n        \"\"\"Envía una notificación con archivos adjuntos\"\"\"\n        pass\n\n# Implementaciones concretas\nclass NotificadorEmail(NotificadorConAdjuntos):\n    def enviar_notificacion_simple(self, destinatario, asunto, mensaje):\n        print(f\"Email enviado a {destinatario}: {asunto}\")\n        return True\n        \n    def enviar_con_adjuntos(self, destinatario, asunto, mensaje, archivos):\n        print(f\"Email enviado a {destinatario}: {asunto}\")\n        print(f\"  Con {len(archivos)} archivos adjuntos\")\n        return True\n\nclass NotificadorSMS(Notificador):\n    def enviar_notificacion_simple(self, destinatario, asunto, mensaje):\n        # Los SMS tienen límite de caracteres\n        if len(mensaje) > 160:\n            # En lugar de fallar, truncamos el mensaje\n            mensaje = mensaje[:156] + \"...\"\n        \n        print(f\"SMS enviado a {destinatario}: {mensaje[:20]}...\")\n        return True\n\nclass NotificadorPush(Notificador):\n    def enviar_notificacion_simple(self, destinatario, asunto, mensaje):\n        print(f\"Notificación push enviada a {destinatario}\")\n        return True\n\n# Código cliente adaptado a las capacidades de cada notificador\ndef enviar_alerta_seguridad(usuario, notificadores):\n    mensaje_completo = \"Se detectó un inicio de sesión desde una ubicación desconocida. Por favor verifica tu cuenta.\"\n    \n    for notificador in notificadores:\n        if isinstance(notificador, NotificadorConAdjuntos):\n            notificador.enviar_con_adjuntos(\n                destinatario=usuario.contacto,\n                asunto=\"Alerta de seguridad\",\n                mensaje=mensaje_completo,\n                archivos=[\"mapa.png\"]\n            )\n        else:\n            notificador.enviar_notificacion_simple(\n                destinatario=usuario.contacto,\n                asunto=\"Alerta de seguridad\",\n                mensaje=mensaje_completo\n            )\n    \n    print(\"Alertas de seguridad enviadas por todos los canales disponibles\")\n\n# Simulación de usuario\nclass Usuario:\n    def __init__(self, contacto):\n        self.contacto = contacto\n\n# Uso del sistema\nusuario = Usuario(\"usuario@email.com\")\n\n# Configuramos múltiples notificadores\nnotificadores = [\n    NotificadorEmail(),\n    NotificadorSMS(),\n    NotificadorPush()\n]\n\n# Esto funciona para todos los notificadores\nenviar_alerta_seguridad(usuario, notificadores)\n\n\nprint(\"----------------------------\")\n\n\n\"\"\"\nExtra\n\"\"\"\nfrom abc import ABC, abstractmethod\n\n\nclass Motor(ABC):\n    @abstractmethod\n    def acelerar(self):\n        pass\n\n    @abstractmethod\n    def frenar(self):\n        pass\n    \n\nclass MotorGasolina:\n    def acelerar(self):\n        return \"Motor de gasolina en movimiento\"\n    \n    def frenar(self):\n        return \"Motor de gasolina deteniendose.\"\n\n\nclass MotorDisel:\n    def acelerar(self):\n        return \"Motor de Disel en movimiento\"\n    \n    def frenar(self):\n        return \"Motor de Disel deteniendose.\"\n\n\nclass MotorElectrico:\n    def acelerar(self):\n        return \"Motor Electrico en movimiento\"\n    \n    def frenar(self):\n        return \"Motor Electrico deteniendose.\"\n\n\nclass Vehiculo:\n    def __init__(self, motor: Motor):\n        self.motor = motor\n\n    def iniciar_marcha(self):\n        resultado = self.motor.acelerar()\n        return f'Vehiculo en marcha: {resultado}'\n    \n    def detener_marcha(self):\n        resultado = self.motor.frenar()\n        return f'Vehiculo deteniendose: {resultado}'\n    \n\ncoche_gasolina = Vehiculo(MotorGasolina())\ncoche_disel = Vehiculo(MotorDisel())\ncoche_electrico = Vehiculo(MotorElectrico())\n\n# Avanzando\nprint(coche_gasolina.iniciar_marcha())\nprint(coche_disel .iniciar_marcha())\nprint(coche_electrico.iniciar_marcha())\n\n# Deteniendose\nprint(coche_gasolina.detener_marcha())\nprint(coche_disel .detener_marcha())\nprint(coche_electrico.detener_marcha())"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/ignaciovihe.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el \"Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n\"\"\"\n# No cumple LSP\n\nclass CuentaBancaria:\n    def __init__(self, saldo):\n        self.saldo = saldo\n\n    def retirar(self, monto):\n        if monto > self.saldo:\n            raise Exception(\"Fondos insuficientes\")\n        self.saldo -= monto\n        return self.saldo\n    \n\nclass CuentaAhorro(CuentaBancaria): # La clase cuenta de ahorro no cumple la promera que hace su padre. Lanza una excepción.\n    def retirar(self, monto):       # No podria sustituir las clases base por su subclase\n        raise Exception(\"No se puede retirar de una cuenta de ahorro\")\n    \n\n\n# Cumple LSP\n\n# Con composición\n\nclass CuentaBancaria:\n    def __init__(self, saldo, comportamiento):\n        self.saldo = saldo\n        self.comportamiento = comportamiento\n\n    def retirar(self, monto):\n        self.saldo = self.comportamiento.retirar(monto, self.saldo)\n        return self.saldo\n\nclass ComportamientoCorriente:\n    def retirar(self, monto, saldo):\n        if monto > saldo:\n            raise Exception(\"Fondos insuficientes\")\n        saldo -= monto\n        return saldo\n    \nclass ComportamientoAhorro:\n    def retirar(self, monto, saldo):\n        raise Exception(\"No se puede retirar de una cuenta de ahorro\")\n    \n\ncuenta_corriente = CuentaBancaria(1000, ComportamientoCorriente())\ncuenta_ahorro = CuentaBancaria(12000, ComportamientoAhorro())\n\ntry:\n    print(cuenta_corriente.retirar(200))\n    print(cuenta_ahorro.retirar(1000))\nexcept Exception as e:\n    print(e)\n\n# con herecia y clases abstractas\n\nfrom abc import ABC,abstractmethod\n\nclass CuentaBancaria(ABC):\n    def __init__(self, saldo):\n        self.saldo = saldo\n\n    @abstractmethod\n    def retirar(self, monto):\n        pass\n\nclass CuentaCorriente(CuentaBancaria):\n    def retirar(self, monto):\n        if monto >self.saldo:\n            raise Exception(\"Fondos insuficientes\")\n        self.saldo -= monto\n        return self.saldo\n    \nclass CuentaAhorro(CuentaBancaria):\n    def retirar(self, monto):\n        raise Exception(\"No se puede retirar de una cuenta de ahorro\")\n    \n\ncuenta_corriente = CuentaCorriente(1000)\ncuenta_ahorro = CuentaAhorro(12000)\n\ntry:\n    print(cuenta_corriente.retirar(200))\n    print(cuenta_ahorro.retirar(1000))\nexcept Exception as e:\n    print(e)\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n * cumplir el LSP.\n * Instrucciones:\n * 1. Crea la clase Vehículo.\n * 2. Añade tres subclases de Vehículo.\n * 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n * 4. Desarrolla un código que compruebe que se cumple el LSP.\n\"\"\"\n\nclass Vehicle():\n    def __init__(self):\n        self.speed = 0\n\n    def brake(self, decrement: int):\n        self.speed = max(0,self.speed - decrement)\n        return self.speed\n\n    def accelerate(self, increment: int):\n        self.speed += increment\n        return self.speed\n\nclass Car(Vehicle):\n    def brake(self, decrement):\n        print(\"El coche frena:\")\n        return super().brake(decrement)\n    \n    def accelerate(self,increment):\n        print(\"El coche acelera\")\n        return super().accelerate(increment)\n\nclass Bus(Vehicle):\n    def brake(self, decrement):\n        print(\"El bus frena:\")\n        return super().brake(decrement)\n    \n    def accelerate(self,increment):\n        print(\"El bus acelera\")\n        return super().accelerate(increment)\n\nclass Bycicle(Vehicle):\n    def brake(self, decrement):\n        print(\"La bicicleta frena:\")\n        return super().brake(decrement)\n    \n    def accelerate(self,increment):\n        print(\"La bicicleta acelera\")\n        return super().accelerate(increment)\n\n\ndef move_vehicle(vehicle: Vehicle):\n    print(f\"{vehicle.accelerate(10)}Km/h\")\n    print(f\"{vehicle.brake(15)}Km/h\")\n    print(f\"{vehicle.accelerate(5)}Km/h\")\n\nmove_vehicle(Car())\nmove_vehicle(Bycicle())\nmove_vehicle(Bus())"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/javi-kl.py",
    "content": "# incorrecto\nfrom abc import ABC, abstractmethod\n\n\nclass Animal(ABC):\n    @abstractmethod\n    def correr(self):\n        pass\n\n\nclass Perro(Animal):\n    def correr(self):\n        print(\"El perror esta corriendo\")\n\n\n# No se respeta el comportamiento esperado\nclass Halcon(Animal):\n    def correr(self):\n        raise NotImplementedError(\"Los Halcones no pueden correr\")\n\n\n# Correcto\nclass Animal(ABC):\n    @abstractmethod\n    def moverse(self):\n        pass\n\n\nclass Perro(Animal):\n    def moverse(self):\n        print(\"El perro se esta moviendo\")\n\n\n# Si se respeta el comportamiento esperado\nclass Halcon(Animal):\n    def moverse(self):\n        print(\"El halcon se esta moviendo\")\n\n\nperro = Perro()\nperro.moverse()\n\nhalcon = Halcon()\nhalcon.moverse()\n\n\n\"\"\"\nextra\n\"\"\"\n\n\n# Solo puede tener metodos que sean utilizables por todas las clases(No podría tener 'despegar').\nclass Vehiculo(ABC):\n    @abstractmethod\n    def acelerar(self):\n        pass\n\n    @abstractmethod\n    def frenar(self):\n        pass\n\n\nclass Coche(Vehiculo):\n    def acelerar(self):\n        print(\"El coche está acelerando\")\n\n    def frenar(self):\n        print(\"El coche está frenando\")\n\n\n# Si quisiera implementar 'despegar/aterrizar' lo haría dentro de esta clase y no en la clase padre.\nclass Avion(Vehiculo):\n    def acelerar(self):\n        print(\"El avion está acelerando\")\n\n    def frenar(self):\n        print(\"El avion está frenando\")\n\n\n# Si quisiera implementar 'pedalear' lo haría dentro de esta clase y no en la clase padre.\nclass Bicicleta(Vehiculo):\n    def acelerar(self):\n        print(\"La bicicleta está acelerando\")\n\n    def frenar(self):\n        print(\"La bicicleta está frenando\")\n\n\n# instanciamos vehiculos\ncoche = Coche()\navion = Avion()\nbici = Bicicleta()\n\n\n# comprobar LSP\ndef prueba_vehiculo(vehiculo: Vehiculo):\n    vehiculo.acelerar()\n    vehiculo.frenar()\n\n\nprueba_vehiculo(coche)\nprueba_vehiculo(avion)\nprueba_vehiculo(bici)\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/juanmax2.py",
    "content": "\"\"\"\nEjercicio\n\"\"\"\n\n# Incorrecto \n\nclass Ave:\n    \n    def fly(self):\n        return \"Fly\"\n    \nclass Pollo(Ave):\n    \n    def fly(self):\n        raise Exception(\"Los pollos no vuelan\")\n    \n\n#bird = Ave()\n#print(bird.fly())\n\n#pollo = Pollo()\n#print(pollo.fly())\n\n# Correcto\n\nclass Aves:\n    \n    def moving(self):\n        return \"Moving\"\n\nclass Pollito(Aves):\n    \n    def moving(self):\n        return \"Walking\"\n    \nbird = Aves()\nprint(bird.moving())\n\npollo = Pollito()\nprint(pollo.moving())\n\n    \nbird = Pollito()\nprint(bird.moving())\n\npollo = Aves()\nprint(pollo.moving())\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n * cumplir el LSP.\n * Instrucciones:\n * 1. Crea la clase Vehículo.\n * 2. Añade tres subclases de Vehículo.\n * 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n * 4. Desarrolla un código que compruebe que se cumple el LSP.\n\"\"\"\n\nclass Vehiculo:\n    \n    def __init__(self, velocidad = 0):\n        self.velocidad = velocidad\n        \n    def acelerar(self, incremento):\n        self.velocidad += incremento\n        print(f\"Velocidad: {self.velocidad} km/h\")\n        \n    def frenar(self, decremento):\n        \n        self.velocidad -= decremento\n        if self.velocidad <= 0:\n            self.velocidad = 0\n        \n        print(f\"Velocidad: {self.velocidad} km/h\")\n        \nclass Coche(Vehiculo):\n    def acelerar(self, incremento):\n        print(\"El coche esta acelerando\")\n        super().acelerar(incremento)\n    \n    def frenar(self, decremento):\n        print(\"El coche esta frenando\")\n        super().frenar(decremento)\n    \nclass Moto(Vehiculo):\n    \n    def acelerar(self, incremento):\n        print(\"La moto esta acelerando\")\n        super().acelerar(incremento)\n    \n    def frenar(self, decremento):\n        print(\"La moto esta frenando\")\n        super().frenar(decremento)\n    \nclass Avion(Vehiculo):\n    \n    def acelerar(self, incremento):\n        print(\"El avion esta acelerando\")\n        super().acelerar(incremento)\n    \n    def frenar(self, decremento):\n        print(\"El avion esta frenando\")\n        super().frenar(decremento)\n    \ndef test_vehiculo(vehiculo):\n    vehiculo.acelerar(2)\n    vehiculo.frenar(1)\n    \ncar = Coche()\nmoto = Moto()\navion = Avion()\n\ntest_vehiculo(car)\ntest_vehiculo(moto)\ntest_vehiculo(avion)"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/juanppdev.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el \"Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n\"\"\"\n\n# Correcto\n\nclass Bird:\n    def fly(self):\n        return \"Flying\"\n\nclass Sparrow(Bird):\n    def fly(self):\n        return \"Sparrow flying\"\n\nclass Eagle(Bird):\n    def fly(self):\n        return \"Eagle flying\"\n\ndef make_bird_fly(bird: Bird):\n    print(bird.fly())\n\n# Uso correcto del principio de sustitución de Liskov\nsparrow = Sparrow()\neagle = Eagle()\n\nmake_bird_fly(sparrow)  # Output: Sparrow flying\nmake_bird_fly(eagle)    # Output: Eagle flying\n\n\n# Incorrecto\n\nclass Bird:\n    def fly(self):\n        return \"Flying\"\n\nclass Ostrich(Bird):\n    def fly(self):\n        raise Exception(\"Ostriches can't fly\")\n\ndef make_bird_fly(bird: Bird):\n    print(bird.fly())\n\n# Uso incorrecto del principio de sustitución de Liskov\nostrich = Ostrich()\n\n# make_bird_fly(ostrich)  # Esto lanzará una excepción: \"Ostriches can't fly\"\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n * cumplir el LSP.\n * Instrucciones:\n * 1. Crea la clase Vehículo.\n * 2. Añade tres subclases de Vehículo.\n * 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n * 4. Desarrolla un código que compruebe que se cumple el LSP.\n\"\"\"\n\nclass Vehiculo:\n    def acelerar(self):\n        raise NotImplementedError(\"Este método debe ser implementado por la subclase\")\n\n    def frenar(self):\n        raise NotImplementedError(\"Este método debe ser implementado por la subclase\")\n\nclass Coche(Vehiculo):\n    def acelerar(self):\n        return \"El coche está acelerando\"\n\n    def frenar(self):\n        return \"El coche está frenando\"\n\nclass Bicicleta(Vehiculo):\n    def acelerar(self):\n        return \"La bicicleta está acelerando\"\n\n    def frenar(self):\n        return \"La bicicleta está frenando\"\n\nclass Motocicleta(Vehiculo):\n    def acelerar(self):\n        return \"La motocicleta está acelerando\"\n\n    def frenar(self):\n        return \"La motocicleta está frenando\"\n\ndef probar_vehiculo(vehiculo: Vehiculo):\n    print(vehiculo.acelerar())\n    print(vehiculo.frenar())\n\n# Crear instancias de cada subclase\ncoche = Coche()\nbicicleta = Bicicleta()\nmotocicleta = Motocicleta()\n\n# Probar cada vehículo\nprobar_vehiculo(coche)        # Output: El coche está acelerando, El coche está frenando\nprobar_vehiculo(bicicleta)    # Output: La bicicleta está acelerando, La bicicleta está frenando\nprobar_vehiculo(motocicleta)  # Output: La motocicleta está acelerando, La motocicleta está frenando\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/kenysdev.py",
    "content": "# ╔═════════════════════════════════════╗\n# ║ Autor:  Kenys Alvarado              ║\n# ║ GitHub: https://github.com/Kenysdev ║\n# ║ 2024 -  Python                      ║\n# ╚═════════════════════════════════════╝\n\n# -------------------------------------------------\n# * SOLID: PRINCIPIO DE SUSTITUCIÓN DE LISKOV (LSP)\n# -------------------------------------------------\n\n# mas info:\n# https://blog.nonstopio.com/liskov-substitution-principle-in-python-b68d62924f7b\n\n# _________________\nfrom abc import ABC, abstractmethod\n\n# Clase base, con contrato:\nclass Animal(ABC): \n    def __init__(self, name: str):\n        self.name = name\n    \n    @abstractmethod\n    def make_sound(self) -> str:\n        pass\n\n# _________________\n# clases derivadas:\nclass Dog(Animal):\n    def make_sound(self) -> str:\n        return (f\"{self.name} hace Woof\")\n\nclass Cat(Animal):\n    def make_sound(self) -> str:\n        return (f\"{self.name} hace Meow\")\n\n# _________________\ndog = Dog(\"Max\")\nprint(dog.make_sound())\n\ncat = Cat(\"Milo\")\nprint(cat.make_sound())\n\n\n\"\"\"\n* EJERCICIO \n* Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n* cumplir el LSP.\n* Instrucciones:\n* 1. Crea la clase Vehículo.\n* 2. Añade tres subclases de Vehículo.\n* 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n* 4. Desarrolla un código que compruebe que se cumple el LSP.\n\"\"\"\n\n# _________________\n# Clase base abstracta\nclass Vehicle(ABC):\n    def __init__(self, brand: str, model: str):\n        self._brand = brand\n        self._model = model\n\n    @property\n    def brand(self) -> str:\n        return self._brand\n\n    @property\n    def model(self) -> str:\n        return self._model\n\n    @abstractmethod\n    def accelerate(self):\n        pass\n    \n    @abstractmethod\n    def brake(self):\n        pass\n\n# _________________\n# clases derivadas:\nclass Car(Vehicle):\n    def accelerate(self) -> str:\n        propertys: str = f\"{self.brand} - {self.model}\"\n        return (f\"Acelerando auto: {propertys}\")\n\n    def brake(self) -> str:\n        propertys: str = f\"{self.brand} - {self.model}\"\n        return (f\"Frenando auto:  {propertys}\")\n\nclass Motorcycle(Vehicle):\n    def accelerate(self) -> str:\n        propertys: str = f\"{self.brand} - {self.model}\"\n        return (f\"Acelerando Motocicleta: {propertys}\")\n\n    def brake(self) -> str:\n        propertys: str = f\"{self.brand} - {self.model}\"\n        return (f\"Frenando Motocicleta: {propertys}\")\nclass Truck(Vehicle):\n    def accelerate(self) -> str:\n        propertys: str = f\"{self.brand} - {self.model}\"\n        return (f\"Acelerando Camión: {propertys}\")\n\n    def brake(self) -> str:\n        propertys: str = f\"{self.brand} - {self.model}\"\n        return (f\"Frenando Camión: {propertys}\")\n\n# _________________\n# Verificar cumplimiento de LSP\ndef test_sub_class(sub_class: Vehicle):\n    print(\"\\nPropiedades:\")\n    print(f\"{sub_class.brand} - {sub_class.model}\")\n\n    print(\"\\nMetodos:\")\n    print(sub_class.accelerate())\n    print(sub_class.brake())\n\n# _________________\n\ncar = Car(\"Honda\", \"Civic\")\ntest_sub_class(car)\n\nmotorcycle = Motorcycle(\"Kawasaki\", \"Ninja\")\ntest_sub_class(motorcycle)\n\ntruck = Truck(\"Ford\", \"Raptor\")\ntest_sub_class(truck)\n\n# end\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/mhayhem.py",
    "content": "# @Author Daniel Grande (Mhayhem)\n\nfrom abc import ABC, abstractmethod\n\n# EJERCICIO:\n# Explora el \"Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)\" \n# y crea un ejemplo simple donde se muestre su funcionamiento\n# de forma correcta e incorrecta.\n\nclass Rectengle:\n    def __init__(self, width: float, height: float):\n        self.width = width\n        self.height = height\n    \n    def set_width(self, width: float):\n        self.width = width\n    \n    def set_height(self, height: float):\n        self.height = height\n    \n    def area(self) -> float:\n        return self.width * self.height\n\n# clase hijo que no cumple el principio Liskov Substitution Principle (LSP)\n\nclass Square(Rectengle):\n    # el cuadrado todos sus lados son iguales\n    def set_width(self, width: float):\n        self.width = width\n        self.height = width\n    \n    def set_height(self, height: float):\n        self.height = height\n        self.width = height\n    \ndef test_area(rectangle: Rectengle):\n    rectangle.set_width(6)\n    rectangle.set_height(5)\n    \n    # hacemos un assert para comprobar si cumple o no el LSP\n    \n    assert rectangle.area() == 30, \"El area debe ser 30\"\n\n\n# correcto\nclass Form(ABC):\n    @abstractmethod\n    def area(self) -> float:\n        pass\n\nclass Rectangle(Form):\n    def __init__(self, width: float, height: float):\n        self.width = width\n        self.height = height\n    \n    def set_width(self, width: float):\n        self.width = width \n    \n    def set_height(self, height: float):\n        self.height = height\n    \n    def area(self) -> float:\n        return self.height * self.width\n\nclass Square(Form):\n    def __init__(self, side: float):\n        self.side = side\n    \n    def set_side(self, side: float):\n        self.side = side\n    \n    def area(self) -> float:\n        return self.side ** 2\n\ndef display_area(form: Form):\n    return form.area()\n\n\n\n\n# DIFICULTAD EXTRA (opcional):\n# Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n# cumplir el LSP.\n# Instrucciones:\n# 1. Crea la clase Vehículo.\n# 2. Añade tres subclases de Vehículo.\n# 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n# 4. Desarrolla un código que compruebe que se cumple el LSP\n\nclass Vehicle(ABC):\n    \n    def accelerate(self, speed_increment):\n        self._current_speed += speed_increment\n        \n        # the current speed can´t be higher than maximun speed\n        if self._current_speed > self.max_speed:\n            self._current_speed = self.max_speed\n            return f\"Velocidad máxima alcanzada, {self._current_speed} km/h.\"\n        return f\"Acelerando hasta {self._current_speed} km/h.\"\n\n    def brake(self, reduce_speed: int):\n        self._current_speed -= reduce_speed\n        \n        # the current speed can´t be a negative value\n        if self._current_speed < 0:\n            self._current_speed = 0\n            return \"Se ha detenido por completo.\"\n        return f\"Velocidad reducida a {self._current_speed} km/h.\"\n\n    def get_current_speed(self):\n        return f\"{self.model}: {self._current_speed} km/h.\"\n\n    @abstractmethod\n    def get_vehicle_info(self):\n        pass\n\nclass Car(Vehicle):\n    def __init__(self, brand: str, model: str, type: str, max_speed: int):\n        self.brand = brand.capitalize()\n        self.model = model.capitalize()\n        self.type = type\n        self.max_speed = max_speed\n        self._current_speed = 0\n\n    def get_vehicle_info(self):\n        return f\"Marca {self.brand} - Modelo {self.model} - Segmento {self.type} - Velocidad máxima {self.max_speed} km/h.\"\n    \nclass Truck(Vehicle):\n    def __init__(self, brand: str, model: str, max_speed: int, num_axles: int):\n        self.brand = brand\n        self.model = model\n        self.max_speed = max_speed\n        self.num_axles = num_axles\n        self._current_speed = 0\n\n    def get_vehicle_info(self):\n        return f\"Marca {self.brand} - Modelo {self.model} - Numero ejes {self.num_axles} - Velocidad máxima {self.max_speed} km/h.\"\n\nclass Motorcycle(Vehicle):\n    def __init__(self, brand: str, model: str, max_speed: int, cubic_centimeters: int):\n        self.brand = brand\n        self.model = model\n        self.max_speed = max_speed\n        self.cubic_centimeters = cubic_centimeters\n        self._current_speed = 0\n\n    def get_vehicle_info(self):\n        return f\"Marca {self.brand} - Modelo {self.model} - Cilindrada {self.cubic_centimeters} CC - Velocidad máxima {self.max_speed} km/h.\"\n\ndef test_accelerate(vehicle: Vehicle):\n    vehicle._current_speed = 0\n    vehicle.accelerate(20)\n\n    assert vehicle._current_speed == 20\n\n\ndef test_brake(vehicle: Vehicle):\n    vehicle._current_speed = 100\n    vehicle.brake(50)\n\n    assert vehicle._current_speed == 50"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/mouredev.py",
    "content": "\"\"\"\nEjercicio\n\"\"\"\n\n# Incorrecto\n\n\nclass Bird:\n    def fly(self):\n        return \"Flying\"\n\n\nclass Chicken(Bird):\n    def fly(self):\n        raise Exception(\"Los pollos no vuelan\")\n\n\n# bird = Bird()\n# bird.fly()\n# chicken = Chicken()\n# chicken.fly()\n\n# Correcto\n\nclass Bird:\n    def move(self):\n        return \"Moving\"\n\n\nclass Chicken(Bird):\n    def move(self):\n        return \"Walking\"\n\n\nbird = Bird()\nprint(bird.move())\nchicken = Chicken()\nprint(chicken.move())\n\nbird = Chicken()\nprint(bird.move())\nchicken = Bird()\nprint(chicken.move())\n\n\"\"\"\nExtra\n\"\"\"\n\n\nclass Vehicle:\n\n    def __init__(self, speed=0):\n        self.speed = speed\n\n    def accelerate(self, increment):\n        self.speed += increment\n        print(f\"Velocidad: {self.speed} Km/h\")\n\n    def brake(self, decrement):\n        self.speed -= decrement\n        if self.speed <= 0:\n            self.speed = 0\n        print(f\"Velocidad: {self.speed} Km/h\")\n\n\nclass Car(Vehicle):\n    def accelerate(self, increment):\n        print(\"El coche está acelerando\")\n        super().accelerate(increment)\n\n    def brake(self, decrement):\n        print(\"El coche está frenando\")\n        super().brake(decrement)\n\n\nclass Bicycle(Vehicle):\n    def accelerate(self, increment):\n        print(\"La bicicleta está acelerando\")\n        super().accelerate(increment)\n\n    def brake(self, decrement):\n        print(\"La bicicleta está frenando\")\n        super().brake(decrement)\n\n\nclass Motorcycle(Vehicle):\n    def accelerate(self, increment):\n        print(\"La moto está acelerando\")\n        super().accelerate(increment)\n\n    def brake(self, decrement):\n        print(\"La moto está frenando\")\n        super().brake(decrement)\n\n\ndef test_vehicle(vehicle):\n    vehicle.accelerate(2)\n    vehicle.brake(1)\n\n\ncar = Car()\nbicycle = Bicycle()\nmotorcycle = Motorcycle()\n\ntest_vehicle(car)\ntest_vehicle(bicycle)\ntest_vehicle(motorcycle)\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/mrodara.py",
    "content": "### Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)\n\n'''\nLSP establece que: Un objeto de una subclase debe ser sustituible por un objeto de su clase base \nsin alterar el correcto funcionamiento del programa.\n\nLSP se centra en garantizar que las subclases no modifiquen el comportamiento esperado de la clase base. \nEn otras palabras, cualquier clase hija debe ser capaz de reemplazar a su clase padre sin introducir errores o \ncomportamientos inesperados.\n'''\n'''\nVentajas:\n- Mejora la reutilización de código.\n- Aporta coherencia en la jerarquía de clases.\n- Ayuda a evitar la dependencia de la implementación.\n'''\n\n# Ejemplo que viola LSP\n# Clase Base\nclass CuentaBancaria():\n    def __init__(self, saldo):\n        self.saldo = saldo\n    \n    def retirar(self, monto):\n        if monto <= self.saldo:\n            self.saldo -= monto\n        else:\n            raise ValueError(\"Saldo insuficiente para retirar de la cuenta\")\n\n# Clase Derivada\nclass CuentaAhorros(CuentaBancaria):\n    \n    def retirar(self, monto):\n        raise NotImplementedError(\"No se puede realizar retirada de la cuenta ahorro\")\n\n# Al aplicar polimorfismo en este caso está violando el principio de Sustitución de Liskov\n'''\nCuentaAhorros no puede ser sustituida por CuentaBancaria sin alterar\n\ndef procesar_retiro(cuenta, monto):\n    cuenta.retirar(monto)\n\ncuenta = CuentaBancaria(1000)\nprocesar_retiro(cuenta, 100)  # Funciona correctamente\n\ncuenta_ahorros = CuentaAhorros(1000)\nprocesar_retiro(cuenta_ahorros, 100)  # Lanza NotImplementedError\n'''\n\n# Arreglemos el ejemplo empleando abstracciones para restricciones específicas\nfrom abc import ABC, abstractmethod\n\nclass CuentaBancaria(ABC):\n\n    def __init__(self, saldo):\n        self.saldo = saldo\n    \n    @abstractmethod\n    def retirar(self, monto):\n        pass\n\nclass CuentaCorriente(CuentaBancaria):\n    def retirar(self, monto):\n        if monto <= self.saldo:\n            self.saldo -= monto\n            print(\"Retirada de efectivo realizada correctamente\")\n        else:\n            raise ValueError(\"Su saldo es inferior a la cantidad a retirar, abortando operación\")\n\nclass CuentaAhorros(CuentaBancaria):\n    def retirar(self, monto):\n        if monto > self.saldo:\n            raise ValueError(\"Saldo insuficiente, abortando operación\")\n        \n        if monto >= 500:\n            raise ValueError(\"La retirada máxima para este tipo de cuenta es de 500€\") # Restricción específica para esta clase\n\n        self.saldo -= monto\n\n# Prueba de funcionamiento correcto\ndef procesar_retirada(cuenta, monto):\n    try:\n        cuenta.retirar(monto)\n        print(f\"Proceso finalizado, su saldo actual tras la operación es de {cuenta.saldo} €\")\n    except ValueError as e:\n        print(e)\n        \nc1 = CuentaCorriente(1000)\nc2 = CuentaAhorros(2000)\n\nprocesar_retirada(c1, 500)  # Funciona correctamente\nprocesar_retirada(c2, 200)  # Funciona correctamente\nprocesar_retirada(c2, 700)  # Lanza ValueError\n\n### EJERCICIO EXTRA\n\nfrom abc import ABC, abstractmethod\n\nclass Vehicle(ABC):\n    def __init__(self, type, max_speed, speed=0):\n        self.type = type\n        self.max_speed = max_speed\n        self.speed = speed if speed <= max_speed else max_speed\n\n    @abstractmethod\n    def speed_up(self, qty):\n        pass\n\n    @abstractmethod\n    def speed_down(self, qty):\n        pass\n\n\nclass Car(Vehicle):\n    def speed_up(self, qty):\n        if self.speed + qty <= self.max_speed:\n            self.speed += qty\n            print(f\"Acelerar terminado, velocidad actual: {self.speed}\")\n        else:\n            raise ValueError(\"La cantidad a acelerar supera la velocidad máxima del vehículo\")\n\n    def speed_down(self, qty):\n        if self.speed - qty >= 0:\n            self.speed -= qty\n            print(f\"Frenar terminado, velocidad actual: {self.speed}\")\n        else:\n            self.speed = 0\n            print(\"Vehículo parado\")\n\n\nclass Truck(Vehicle):\n    def speed_up(self, qty):\n        if self.speed + qty <= self.max_speed:\n            self.speed += qty\n            print(f\"Acelerar terminado, velocidad actual: {self.speed}\")\n        else:\n            raise ValueError(\"La cantidad a acelerar supera la velocidad máxima del camión\")\n\n    def speed_down(self, qty):\n        if self.speed - qty >= 0:\n            self.speed -= qty\n            print(f\"Frenar terminado, velocidad actual: {self.speed}\")\n        else:\n            self.speed = 0\n            print(\"Vehículo parado\")\n\n\nclass ElectricCar(Vehicle):\n    def speed_up(self, qty):\n        if self.speed + qty <= self.max_speed:\n            self.speed += qty\n            print(f\"Acelerar terminado, velocidad actual: {self.speed}\")\n        else:\n            raise ValueError(\"La cantidad a acelerar supera la velocidad máxima del vehículo eléctrico\")\n\n    def speed_down(self, qty):\n        if self.speed - qty >= 0:\n            self.speed -= qty\n            print(f\"Frenar terminado, velocidad actual: {self.speed}\")\n        else:\n            self.speed = 0\n            print(\"Vehículo parado\")\n\n\n# Realización de pruebas\ndef test_speed(vehicle):\n    print(f\"Inicio de las pruebas con {vehicle.type}\")\n    try:\n        vehicle.speed_up(25)\n        vehicle.speed_down(5)\n        vehicle.speed_up(vehicle.max_speed + 1)\n        vehicle.speed_down(vehicle.speed)\n    except ValueError as e:\n        print(e)\n    print(\"-\" * 60)\n        \ncars = [\n        Car(\"Ferrari F50\", 300, 125),\n        Truck(\"Mercedes-Benz Actros\", 150, 80),\n        ElectricCar(\"Tesla Model S\", 120, 125)\n    ]\n\nfor car in cars:\n    test_speed(car)  # Realizar pruebas con cada tipo de vehículo\n\n    \n### FIN EJERCICIO EXTRA\n\n        \n### FIN Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/neslarra.py",
    "content": "\"\"\"\nEJERCICIO:\n Explora el \"Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)\"\n y crea un ejemplo simple donde se muestre su funcionamiento\n de forma correcta e incorrecta.\n\n DIFICULTAD EXTRA (opcional):\n Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n cumplir el LSP.\n Instrucciones:\n 1. Crea la clase Vehículo.\n 2. Añade tres subclases de Vehículo.\n 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n 4. Desarrolla un código que compruebe que se cumple el LSP.\n\"\"\"\nfrom abc import ABC, abstractmethod\nfrom typing import final\n\nprint(f\"{'#' * 47}\")\nprint(f\"##  Explicación  {'#' * 30}\")\nprint(f\"{'#' * 47}\")\n\nprint(r\"\"\"\nPara entender fácilmente los 5 ppios SOLID recomiendo leer:\n\n    https://blog.damavis.com/los-principios-solid-ilustrados-en-ejemplos-sencillos-de-python/\n\nen donde se explican de manera ordenada uno por uno, de manera sencilla y ejemplificada de manera progresiva (de hecho, de ahí\nvoy a tomar el ejemplo).\n\nEl tercero de los ppios SOLID es el \"Liskov Sustitution Principle\" (Barbara Jane Liskov) establece que toda clase base debe poder\nsubstituirse por instancias de sus subclases.\n\nRetomando el caso anterior, podríamos hacer que la clase \"Duck\" herede de una clase base Bird, por lo tanto, luego podríamos ampliar\na una clase Crow:\n\n    from abc import ABC, abstractmethod\n    from typing import final\n    \n    \n    class Bird(ABC):\n    \n        def __init__(self, name):\n            self.name = name\n    \n        @abstractmethod\n        def fly(self):\n            pass\n    \n        @abstractmethod\n        def swim(self):\n            pass\n    \n        @abstractmethod\n        def do_sound(self) -> str:\n            pass\n    \n    \n    class Crow(Bird):\n    \n        def fly(self):\n            print(f\"{self.name} is flying high and fast!\")\n    \n        def swim(self):\n            raise NotImplementedError(\"Crows don't swim!\")\n    \n        def do_sound(self) -> str:\n            return \"Caw\"\n    \n    \n    class Duck(Bird):\n    \n        def fly(self):\n            print(f\"{self.name} is flying not very high\")\n    \n        def swim(self):\n            print(f\"{self.name} swims in the lake and quacks\")\n    \n        def do_sound(self) -> str:\n            return \"Quack\"\n \nAhora bien, la clase Conversation depende de la clase \"Duck\", por lo tanto sería incapaz de aceptar a la clase \"Crow\". Para ello\nla clase Conversation debiera recibir a la clase \"Bird\" en lugar de \"Duck\":\n  \n    class AbstractConversation:\n    \n        def do_conversation(self) -> list:\n            pass\n    \n    \n    class Conversation(AbstractConversation):\n    \n        def __init__(self, bird1: Bird, bird2: Bird):\n            self.bird1 = bird1\n            self.bird2 = bird2\n    \n        def do_conversation(self) -> list:\n            sentence1 = f\"{self.bird1.name}: {self.bird1.do_sound()}, hello {self.bird2.name}\"\n            sentence2 = f\"{self.bird2.name}: {self.bird2.do_sound()}, hello {self.bird1.name}\"\n            return [sentence1, sentence2]\n    \n    \n    class Communicator:\n    \n        def __init__(self, channel):\n            self.channel = channel\n    \n        @final\n        def communicate(self, conversation: AbstractConversation):\n            print(*conversation.do_conversation(), sep = '\\n')\n\nDe esta manera Bird puede ser sustituida por cualquiera de sus subclase (Duck o Crow).\n\n    lucas = Duck(\"Lucas\")\n    saturnino = Duck(\"Saturnino\")\n    channel = Communicator(Conversation(lucas, saturnino))\n    channel.communicate(channel.channel)\n    \n    dandy = Crow(\"Dandy\")\n    gordo = Crow(\"Gordo\")\n    channel = Communicator(Conversation(dandy, gordo))\n    channel.communicate(channel.channel)\n    \n    Lucas: Quack, hello Saturnino\n    Saturnino: Quack, hello Lucas\n    \n    Dandy: Caw, hello Gordo\n    Gordo: Caw, hello Dandy\n\"\"\")\n\nprint(f\"{'#' * 52}\")\nprint(f\"##  Dificultad Extra  {'#' * 30}\")\nprint(f\"{'#' * 52}\\n\")\n\n\nclass Vehicle(ABC):\n\n    def __init__(self, vehicle_type: str):\n        self.vehicle_type = vehicle_type\n\n    @abstractmethod\n    def accelerate(self, degree: int):\n        pass\n\n    @abstractmethod\n    def stop(self, degree: int):\n        pass\n\n\nclass Sedan(Vehicle):\n\n    def __init__(self):\n        super().__init__(\"Sedan\")\n        self.doors = 4\n        self.max_velocity = 180\n        self.current_velocity = 0\n\n    def accelerate(self, degree: int):\n        if degree < 0:\n            degree = 0\n        elif degree >= self.max_velocity:\n            degree = self.max_velocity\n\n        self.current_velocity = degree\n        return self.current_velocity if self.current_velocity <= self.max_velocity else self.max_velocity\n\n    def stop(self, degree: int):\n        if degree < 0:\n            degree = 0\n        elif degree > self.current_velocity:\n            degree = self.current_velocity\n\n        self.current_velocity = degree\n        return self.current_velocity\n\n\nclass PickUp(Vehicle):\n\n    def __init__(self, cabin: int):\n        super().__init__(\"PickUp\")\n        if cabin in (1, 2):\n            self.cabin = cabin\n            self.doors = 2 * cabin\n        else:\n            raise ValueError(\"Cabin mut be 1 (single) or 2 (double\")\n        self.max_velocity = 150\n        self.current_velocity = 0\n\n    def accelerate(self, degree: int):\n        if degree < 0:\n            degree = 0\n        elif degree >= self.max_velocity:\n            degree = self.max_velocity\n\n        self.current_velocity = degree\n        return self.current_velocity if self.current_velocity <= self.max_velocity else self.max_velocity\n\n    def stop(self, degree: int):\n        if degree < 0:\n            degree = 0\n        elif degree > self.current_velocity:\n            degree = self.current_velocity\n\n        self.current_velocity = degree\n        return self.current_velocity\n\n\nclass Coupe(Vehicle):\n\n    def __init__(self, roof: str):\n        super().__init__(\"Coupe\")\n        self.roof = roof\n        self.doors = 2\n        self.max_velocity = 250\n        self.current_velocity = 0\n\n    def accelerate(self, degree: int):\n        if degree < 0:\n            degree = 0\n        elif degree >= self.max_velocity:\n            degree = self.max_velocity\n\n        self.current_velocity = degree\n        return self.current_velocity if self.current_velocity <= self.max_velocity else self.max_velocity\n\n    def stop(self, degree: int):\n        if degree < 0:\n            degree = 0\n        elif degree > self.current_velocity:\n            degree = self.current_velocity\n\n        self.current_velocity = degree\n        return self.current_velocity\n\n\nclass AbstractMovement:\n\n    def move(self, degree: int):\n        pass\n\n\nclass VehicleMovement(AbstractMovement):\n\n    def __init__(self, vehicle: Vehicle):\n        self.vehicle = vehicle\n\n    def move(self, degree: int):\n        if degree < 0:\n            velocity = self.vehicle.stop(abs(degree))\n        else:\n            velocity = self.vehicle.accelerate(degree)\n        return velocity\n\n\nclass MoveVehicle:\n\n    def __init__(self, control):\n        self.control = control\n\n    @final\n    def move(self, movement: AbstractMovement, degree: int = 0):\n        print(movement.move(degree))\n\n\na3 = Sedan()\ncontrol_a3 = MoveVehicle(VehicleMovement(a3))\nprint(f\"Acelero A3 {control_a3.control.move(100)}\")\nprint(f\"Acelero A3 {control_a3.control.move(120)}\")\nprint(f\"Desacelero A3 {control_a3.control.move(-80)}\")\nprint(f\"Acelero A3 {control_a3.control.move(250)}\")\nprint(f\"Descelero A3 {control_a3.control.move(-30)}\")\n\nhilux = PickUp(2)\ncontrol_hilux = MoveVehicle(VehicleMovement(hilux))\nprint(f\"\\nAcelero Hilux {control_hilux.control.move(100)}\")\nprint(f\"Acelero Hilux {control_hilux.control.move(220)}\")\nprint(f\"Desacelero Hilux {control_hilux.control.move(-100)}\")\nprint(f\"Acelero Hilux {control_hilux.control.move(250)}\")\nprint(f\"Descelero Hilux {control_hilux.control.move(0)}\")\n\nfuego = Coupe(\"sliding\")\ncontrol_fuego = MoveVehicle(VehicleMovement(fuego))\nprint(f\"\\nAcelero Fuego {control_fuego.control.move(100)}\")\nprint(f\"Acelero Fuego {control_fuego.control.move(220)}\")\nprint(f\"Desacelero Fuego {control_fuego.control.move(150)}\")\nprint(f\"Acelero Fuego {control_fuego.control.move(250)}\")\nprint(f\"Descelero Fuego {control_fuego.control.move(0)}\")\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/nikorasu-d.py",
    "content": "from abc import ABC, abstractmethod\n\n\"\"\"\nPrincipio de sustitucion de Liskov\n\nCada clase que hereda de otra puede usarse como su padre sin necesidad de conocer las diferencias entre ellas. \n\n\"\"\"\n\n\n# El siguiente ejemplo es un ejemplo erroneo donde no se cumple el principio\n\nclass ProductoWrong(ABC):\n\n    def __init__(self, marca):\n      self.marca = marca\n\n    @abstractmethod\n    def comer(self):\n        print(\"Comiendo: \" + self.marca)\n    \nclass PolloAsadoWrong(ProductoWrong):\n\n    def __init__(self, marca, calories):\n        self.calories = calories\n        self.marca = marca\n    \n    def comer(self):\n        return super().comer()\n\nclass LejiaWrong(ProductoWrong):\n    def __init__(self, marca, liters):\n        self.liters = liters\n        self.marca = marca\n\n    def comer(self):\n        raise ValueError(\"No puedes comer Lejia\")\n    \n\n# A continuacion se deja expreso una version del mismo codigo pero que cumple el principio de sustitucion de liskov\n\nclass Producto(ABC):\n\n    def __init__(self, name ,marca, price, categoria):\n      self.name = name\n      self.marca = marca\n      self.price = price\n      self.categoria =categoria\n    \n    @abstractmethod\n    def comprar(self):\n        print (f\"Comprando {self.name} \\nMarca: {self.marca} \\nCategoria {self.categoria} \\nPrecio ${self.price}\")\n        pass\n\n\nclass ProductoDeAseo(Producto):\n    \n    def __init__(self, name ,marca, price, categoria, porcentajeAccionDesinfectante):\n        super().__init__(name ,marca, price, categoria)\n        self.porcentajeAccionDesinfectante = porcentajeAccionDesinfectante\n    \n    def comprar (self):\n        super().comprar()\n        print(f\"Accion desinfectante al %{self.porcentajeAccionDesinfectante}\")\n\n    def asear (self):\n        print(f\"Aseando con {self.name} al %{self.porcentajeAccionDesinfectante}\")\n\nclass Comida(Producto):\n\n    def __init__(self, name ,marca, price, categoria, calories):\n        super().__init__(name ,marca, price, categoria)\n        self.calories = calories\n\n    def comprar(self):\n        super().comprar()\n        print(f\"Calorias por porcion: {self.calories}\\n\")\n\n    def comer(self):\n        print(f\"Comiendo {self.name} que aporta {self.calories} calorias por porción\")\n\n\npolloAsado = Comida(\"Pollo Asado 1 Kilo\",\"Ariztia\",5000,\"Platos Preparados\",\"800 Calorias\")\npure = Comida(\"Pure Rustico con Bistec\",\"Genial\",3490,\"Platos Preparados\",\"600 Calorias\")\nabrillantadorPisoFlotante = ProductoDeAseo(\"Abrillantador de Piso Flotante\",\"Brillantina\",3200,\"Pisos\", 0)\n\n\"\"\"\nprint(\"\\n\")\npolloAsado.comprar()\nprint(\"\\n\")\npure.comprar()\nprint(\"\\n\")\nabrillantadorPisoFlotante.comprar()\n\nprint(\"\\n\")\npolloAsado.comer()\nprint(\"\\n\")\nabrillantadorPisoFlotante.asear()\nprint(\"\\n\")\npure.comer()\n\"\"\"\n\n\n\n\n\"\"\"\nEjercicio Extra:\n\nCrea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n * cumplir el LSP.\n * Instrucciones:\n * 1. Crea la clase Vehículo.\n * 2. Añade tres subclases de Vehículo.\n * 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n * 4. Desarrolla un código que compruebe que se cumple el LSP.\n\n\"\"\"\n\nclass Vehiculo:\n    def __init__(self, name, marca, category):\n      self.name = name\n      self.marca = marca\n      self.category= category\n\n    def frenar(self):\n        print (f\"Frenando: {self.name}\")\n        pass\n\n    def acelerar(self):\n        print(f\"Acelerando: {self.name} \")\n        pass\n\n\n\nclass VehiculoManual(Vehiculo):\n\n    def __init__(self, name, marca, category, maxWeight, minimumAge):\n        super().__init__(name, marca, category)\n        self.maxWeight = maxWeight\n        self.minimumAge = minimumAge\n    \n    def acelerar(self):\n        print(\"Moviendo los pies muy rapido\")\n        super().acelerar()\n    \n    def frenar(self):\n        print(\"Dejando de Acelerar y tratar de poner los pies en el piso\")\n        super().frenar()\n\n    def subirAlVehiculo(self, weight, age):\n        if(weight >= self.maxWeight):\n            print(\"Atencion el vehiculo lleva mucho peso!\")\n        if(age < self.minimumAge):\n            print(f\"Eres muy pequeño para este Vehiculo\")\n        elif(age >= self.minimumAge and weight < self.maxWeight):\n            print(f\"Eres adecuado para este vehiculo, siga movilizandose! :)\")\n\n\nclass VehiculoACombustion(Vehiculo):\n\n    def __init__(self, name, marca, category, cilinders, fuelType):\n        super().__init__(name, marca, category)\n        self.cilinders = cilinders\n        self.fuel = fuelType\n\n    def acelerar(self):\n        print(\"Pisando el Acelerador!\")\n        self.subirMarchas()\n        super().acelerar()\n    \n    def frenar(self):\n        print(\"Presionar el Pedal de freno y Lentamente el Embrague\")\n        self.bajarMarchas()\n        super().frenar()\n\n    def subirMarchas(self):\n        print(\"Subiendo Marchas\")\n    \n    def bajarMarchas(self):\n        print(\"Bajando Marchas\")\n\n    \n    \nclass VehiculoElectrico(Vehiculo):\n\n    def __init__(self, name, marca, category, electricMotorsQuantity, fastCharge):\n        super().__init__(name, marca, category)\n        self.electricMotorsQuantity = electricMotorsQuantity\n        self.fastCharge = fastCharge\n\n    def acelerar(self):\n        print(\"Pisando el Acelerador de forma Cool!\")\n        super().acelerar()\n    \n    def frenar(self):\n        print(\"Presionando el Freno igual de Cool!\")\n        super().frenar()\n\n    def cargarEnElPoste(self):\n        print(\"Cargando el Vehiculo electrico de una forma muy Cool!\")\n        if(self.fastCharge): print(\"Wow!, tenemos Fast Charging!!!\")\n    \n\n\nbicicleta = VehiculoManual(\"Bicicleta BMX\",\"Oddysey\",\"Deporte Extremo\", 80, 15)\nskate = VehiculoManual(\"Skate\",\"Plan B\",\"Deporte Extremo\", 80, 5)\n\nmotocicleta = VehiculoACombustion(\"Motocicleta\", \"Honda\", \"City\", 1, \"Gasolina\" )\nauto = VehiculoACombustion(\"Skyline\", \"Nissan\", \"Sportcar\", 8, \"Gasolina\")\n\ntesla = VehiculoElectrico(\"Model S\",\"Tesla\",\"Cool Electric Car\", 4, True)\n\nprint(\"Bicicleta BMX\")\nbicicleta.subirAlVehiculo(90,13)\nbicicleta.acelerar()\nbicicleta.frenar()\n\nprint(\"\\nSkate PlanB\")\nskate.subirAlVehiculo(75, 15)\nskate.acelerar()\nskate.frenar()\n\nprint(\"\\nMotocicleta Honda\")\nmotocicleta.acelerar()\nmotocicleta.frenar()\nprint(\"\\nNissan Skyline\")\nauto.acelerar()\nauto.frenar()\n\n\nprint(\"\\nTesla Model S\")\ntesla.cargarEnElPoste()\ntesla.acelerar()\ntesla.frenar()\n\n\n\n\n    \n\n\n\n    "
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/nlarrea.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el \"Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n * cumplir el LSP.\n * Instrucciones:\n * 1. Crea la clase Vehículo.\n * 2. Añade tres subclases de Vehículo.\n * 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n * 4. Desarrolla un código que compruebe que se cumple el LSP.\n\"\"\"\n\n# Incorrect\n\n\nclass Bird:\n    def fly(self):\n        return \"Flying\"\n\n\nclass Ostrich(Bird):\n    def fly(self):\n        raise Exception(\"Ostriches can't fly.\")\n\n\n# bird = Bird()\n# print(bird.move())\n# ostrich = Ostrich()\n# print(ostrich.move())  # throws error\n\n\n# Correct\n\n\nclass Bird:\n    def move(self):\n        return \"Flying\"\n\n\nclass Ostrich(Bird):\n    def move(self):\n        return \"Walking\"\n\n\nbird = Bird()\nprint(bird.move())\nostrich = Ostrich()\nprint(ostrich.move())\n\nbird = Ostrich()\nprint(bird.move())\nostrich = Bird()\nprint(ostrich.move())\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n * cumplir el LSP.\n * Instrucciones:\n * 1. Crea la clase Vehículo.\n * 2. Añade tres subclases de Vehículo.\n * 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n * 4. Desarrolla un código que compruebe que se cumple el LSP.\n\"\"\"\n\n\nclass Vehicle:\n    def __init__(self, speed=0):\n        self.speed = speed\n\n    def accelerate(self, increment: int):\n        self.speed += increment\n        print(f\"Speed: {self.speed} km/h\")\n\n    def brake(self, decrement: int):\n        self.speed -= decrement\n\n        if self.speed <= 0:\n            self.speed = 0\n\n        print(f\"Speed: {self.speed} km/h\")\n\n\nclass Motorbike(Vehicle):\n    def accelerate(self, increment):\n        print(\"Motorbike is accelerating...\")\n        super().accelerate(increment)\n\n    def brake(self, decrement):\n        print(\"Motorbike is braking...\")\n        super().brake(decrement)\n\n\nclass Car(Vehicle):\n    def accelerate(self, increment):\n        print(\"Car is accelerating...\")\n        super().accelerate(increment)\n\n    def brake(self, decrement):\n        print(\"Car is braking...\")\n        super().brake(decrement)\n\n\nclass Bicycle(Vehicle):\n    def accelerate(self, increment):\n        print(\"Bicycle is accelerating...\")\n        super().accelerate(increment)\n\n    def brake(self, decrement):\n        print(\"Bicycle is braking...\")\n        super().brake(decrement)\n\n\ndef test_vehicle(vehicle):\n    vehicle.accelerate(10)\n    vehicle.brake(2)\n    print()\n\n\nmotorbike = Motorbike()\ncar = Car()\nbicycle = Bicycle()\n\ntest_vehicle(motorbike)\ntest_vehicle(car)\ntest_vehicle(bicycle)\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/oriaj3.py",
    "content": "\"\"\"\n\n28 - SOLID LSP - Liskov Substitution Principle\nAutor de la solución: oriaj3 \n\nEl principio de sustitución de Liskov (Liskov Substitution Principle, LSP) establece que los objetos de una clase derivada \ndeben poder sustituirse por objetos de la clase base sin afectar el comportamiento del programa. En otras palabras, una \nclase derivada debe extender la clase base sin cambiar su comportamiento.\n\nEl principio LSP se puede lograr mediante el uso de interfaces y clases abstractas.\n\nUn ejemplo sería una clase Cuadrado que hereda de una clase Rectángulo. Un cuadrado es un tipo de rectángulo, pero no\ntodos los rectángulos son cuadrados. Por lo tanto, la clase Cuadrado no debería heredar de la clase Rectángulo.\n\nEn Python no hay una forma directa de implementar interfaces, pero se pueden usar clases abstractas para lograr un comportamiento similar.\nSe usa la librería abc (Abstract Base Classes) para definir clases abstractas.\n\n\"\"\"\n\n\"\"\"\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n\"\"\"\n\n# Ejemplo incorrecto\nclass animal:\n    def __init__(self, nombre):\n        self.nombre = nombre\n\n    def hacer_sonido(self):\n        return \"sonido\"\n    \nclass jirafa(animal):\n    def __init__(self, nombre):\n        super().__init__(nombre)\n\n    def hacer_sonido(self):\n        raise Exception(\"Las jirafas no hacen sonidos. \")\n    \nclass gato(animal):\n    def __init__(self, nombre):\n        super().__init__(nombre)\n\n    def hacer_sonido(self):\n        return \"miau\"\n    \n\"\"\" animal = animal(\"animal\")\nanimal.hacer_sonido()\n\ngato = gato(\"gato\")\ngato.hacer_sonido()\n\njirafa = jirafa(\"jirafa\")\njirafa.hacer_sonido() \"\"\"\n\n# Ejemplo correcto\nfrom abc import ABC, abstractmethod\n\nclass animal(ABC):\n    def __init__(self, nombre):\n        self.nombre = nombre\n\n    @abstractmethod\n    def comunicate(self):\n        pass\n\nclass gato(animal):\n    def __init__(self, nombre):\n        super().__init__(nombre)\n\n    def comunicate(self):\n        return \"El gato hizo miau\"\n\nclass jirafa(animal):\n    def __init__(self, nombre):\n        super().__init__(nombre)\n\n    def comunicate(self):\n        return \"La jirafa hizo un señal con su cuello\"\n    \nanimales = [gato(\"gato\"), jirafa(\"jirafa\")]\n\nfor animal in animales:\n    print(animal.comunicate())\n        \n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n * cumplir el LSP.\n * Instrucciones:\n * 1. Crea la clase Vehículo.\n * 2. Añade tres subclases de Vehículo.\n * 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n * 4. Desarrolla un código que compruebe que se cumple el LSP.\n */\n\"\"\"\nfrom abc import ABC, abstractmethod\n\n# Clase abstracta Vehículo\n\nclass Vehicle(ABC):\n    def __init__(self, speed=0) -> None:\n        self.speed = speed\n\n    def accelerate(self, increment=1):\n        self.speed += increment\n        return self.speed        \n\n    def brake(self, increment=1):\n        self.speed -= increment\n        return self.speed\n    \n    def get_speed(self):\n        print(self.speed)\n    \nclass Car(Vehicle):\n    \n    def accelerate(self, increment=3):\n        print(\"El coche está acelerando\")\n        super().accelerate(increment)\n\n    def brake(self, increment=3):\n        print(\"El coche está frenando\")\n        super().brake(increment)\n    \n    def get_speed(self):\n        super().get_speed()\n        \nclass Bicycle(Vehicle):\n    \n    def accelerate(self, increment=1):\n        print(\"La bicicleta está acelerando\")\n        super().accelerate(increment)\n\n\n    def brake(self, increment=1):\n        print(\"La bicicleta está frenando\")\n        super().brake(increment)\n\n    def get_speed(self):\n        super().get_speed()\n\nclass Motorcycle(Vehicle):\n    \n    def accelerate(self, increment=4):\n        print(\"La moto está acelerando\")\n        super().accelerate(increment)\n\n    def brake(self, increment=2):\n        print(\"La moto está frenando\")\n        super().brake(increment)\n        \n\ndef test_vehicle(vehicle):\n    vehicle.accelerate()\n    vehicle.get_speed()\n    vehicle.brake()\n    vehicle.get_speed()\n\ncar = Car()\ncycle = Bicycle()\nbyke = Motorcycle()\n\nvehicles = [car, cycle, byke]\n\ntest_vehicle(Car())\ntest_vehicle(Bicycle())\ntest_vehicle(Motorcycle())\n\n\"\"\" print(\"\\nVehículos: \")\nfor vehicle in vehicles:\n    test_vehicle(vehicle)\n    print(\"\\n\") \"\"\"\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/pyramsd.py",
    "content": "# USO CORRECTO\nclass Shape:\n    def area(self):\n        pass\n\nclass Rectangulo:\n    def __init__(self, width, height):\n        self.width = width\n        self.height = height\n\n    def area(self):\n        return self.width * self.height\n    \nclass Cuadrado(Rectangulo):\n    def __init__(self, side):\n        super().__init__(side, side)\n\ndef print_area(shape: Shape):\n    print(f\"Area: {shape.area()}\")\n\n\nrectangulo = Rectangulo(5, 10)\ncuadrado = Cuadrado(10)\n\nprint_area(rectangulo)\nprint_area(cuadrado)\n\n\n# USO INCORRECTO\nclass Square(Rectangulo):\n    def __init__(self, width, height):\n        if width != height:\n            raise ValueError(\"Un cuadrado debe tener lados iguales.\")\n        super().__init__(width, height)\n\n# Uso incorrecto del principio LSP\ndef print_area(shape: Shape):\n    print(f\"Área: {shape.area()}\")\n\nrectangle = Rectangulo(5, 10)\nsquare = Square(7, 7)\n\nprint_area(rectangle)\nprint_area(square)\n\n\"\"\"\nEl principio LSP establece que la subclase debe poder reemplazar a la superclase sin cambiar \nel comportamiento esperado del programa. En este caso, la subclase Square está introduciendo \nuna restricción adicional que podría causar problemas en el código que espera que Square se \ncomporte como un Rectangulo.\n\"\"\"\n\n\"\"\"\nEXTRA\n\"\"\"\nclass Vehiculo:\n    def acelerar(self):\n        raise NotImplementedError(\"Este método debe ser implementado por la subclase.\")\n\n    def frenar(self):\n        raise NotImplementedError(\"Este método debe ser implementado por la subclase.\")\n\nclass Coche(Vehiculo):\n    def __init__(self, velocidad):\n        self.velocidad = velocidad\n\n    def acelerar(self):\n        self.velocidad += 10\n        return self.velocidad\n\n    def frenar(self):\n        self.velocidad -= 10\n        return self.velocidad\n\nclass Bicicleta(Vehiculo):\n    def __init__(self, velocidad):\n        self.velocidad = velocidad\n\n    def acelerar(self):\n        self.velocidad += 2\n        return self.velocidad\n\n    def frenar(self):\n        self.velocidad -= 2\n        return self.velocidad\n\nclass Avion(Vehiculo):\n    def __init__(self, velocidad):\n        self.velocidad = velocidad\n\n    def acelerar(self):\n        self.velocidad += 50\n        return self.velocidad\n\n    def frenar(self):\n        self.velocidad -= 50\n        return self.velocidad\n\n\ndef test_vehiculo(vehiculo: Vehiculo):\n    print(f\"Velocidad inicial: {vehiculo.velocidad}\")\n    vehiculo.acelerar()\n    print(f\"Después de acelerar: {vehiculo.velocidad}\")\n    vehiculo.frenar()\n    print(f\"Después de frenar: {vehiculo.velocidad}\")\n\n# Crear instancias de cada tipo de vehículo\ncoche = Coche(50)\nbicicleta = Bicicleta(10)\navion = Avion(200)\n\n# Probar con diferentes vehículos\nprint(\"Coche\")\ntest_vehiculo(coche) # Coche debe cumplir con el comportamiento esperado\nprint(\"Bicicleta\")\ntest_vehiculo(bicicleta) # Bicicleta debe cumplir con el comportamiento esperado\nprint(\"Avion\")\ntest_vehiculo(avion) # Avion debe cumplir con el comportamiento esperado\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/rantamhack.py",
    "content": "\nprint(\"\\n\\n=======================================EJERCICIO=======================================\\n\\n\")\n\n'''\n * EJERCICIO:\n * Explora el \"Principio SOLID de Sustitucion de Liskov (Liskov Substitution Principle, LSP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n'''\n# FORMA CORRECTA\n'''\nclass Bird:\n    \n    def have_beak(self):\n        return \"Soy un pajaro y mi boca es un pico\"\n         \n    def fly(self):\n        return \"Soy un pajaro y vuelo\"\n    \nclass Hawk(Bird):\n    pass\n\nclass Penguin(Bird):\n    def fly(self):\n        raise NotImplementedError(\"penguins swim not fly\")\n\nhawk = Hawk()\npenguin = Penguin()\n\nprint(hawk.have_beak())\nprint(hawk.fly())\nprint(penguin.have_beak())\nprint(penguin.fly())\n'''\n# FORMA CORRECTA\n\nfrom abc import ABC, abstractmethod\n\nclass Bird(ABC):\n    \n    def have_beak(self):\n        return \"Soy un pajaro y mi boca es un pico\"\n         \nclass FlyingBird(Bird):\n    @abstractmethod\n    def fly(self):\n        pass\n    \nclass NonFlyingBird(Bird):\n    pass\n    \nclass Hawk(FlyingBird):\n    def fly(self):\n        return \"Soy un halcon y vuelo\"\n\nclass Penguin(NonFlyingBird):\n    def swim(self):\n        return \"Soy un pingÃ¼ino y nado, no vuelo\"\n\n\nhawk = Hawk()\npenguin = Penguin()\n\nprint(hawk.have_beak())\nprint(hawk.fly())\nprint(penguin.have_beak())\nprint(penguin.swim())\n\n\n\n\n\nprint(\"\\n\\n=======================================DIFICULTAD EXTRA=======================================\\n\\n\")\n\n'''\n * DIFICULTAD EXTRA (opcional):\n * Crea una jerarquia de vehiculos. Todos ellos deben poder acelerar y frenar, asi como\n * cumplir el LSP.\n * Instrucciones:\n * 1. Crea la clase Vehiculo.\n * 2. Añade tres subclases de Vehiculo.\n * 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n * 4. Desarrolla un codigo que compruebe que se cumple el LSP.\n'''\nfrom abc import ABC, abstractmethod\n\nclass Vehicle(ABC):\n    def __init__(self, name):\n            self.name = name        \n\n    @abstractmethod    \n    def accelerate(self):\n        pass\n    \n    @abstractmethod\n    def brake(self):\n        pass\n    \n    \nclass EngineVehicle(Vehicle):\n    def have_engine(self):\n        return f\"{self.name} es un vehÃ­culo de motor\"\n    \n    @abstractmethod\n    def accelerate(self):\n        pass\n    \n    def brake(self):\n        return f\"{self.name} esta frenando con los discos de freno\"\n\nclass ElectricMotor(EngineVehicle):\n    def accelerate(self):\n        return f\"{self.name} esta acelerando con el motor electrico\"\n\nclass GasMotor(EngineVehicle):\n    def accelerate(self):\n        return f\"{self.name} esta acelerando con el motor de gasoil\"\n\nclass NonEngineVehicle(Vehicle):\n    def no_engine(self):\n        return f\"{self.name} es un vehiculo sin motor\"\n    \n    def accelerate(self):\n        return f\"{self.name} esta acelerando con los pedales\"\n    \n    def brake(self):\n        return f\"{self.name} esta frenando con las zapatas\"\n\nclass Bicycle(NonEngineVehicle):\n    pass\n\n\ncamion = GasMotor(\"Camion\")\ncoche = ElectricMotor(\"Coche\")\nbici = Bicycle(\"Bicicleta\")\n\n\nprint(camion.have_engine())\nprint(camion.accelerate())\nprint(camion.brake())\n\nprint(coche.have_engine())\nprint(coche.accelerate())\nprint(coche.brake())\n\nprint(bici.no_engine())\nprint(bici.accelerate())\nprint(bici.brake())\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/raynerpv2022.py",
    "content": "\n# /*\n#  * EJERCICIO:\n#  * Explora el \"Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)\" \n#  * y crea un ejemplo simple donde se muestre su funcionamiento\n#  * de forma correcta e incorrecta.\n#  *\n\n\nclass Figura:\n    def __init__(self ):\n        pass\n\n    \n    def Area(self):\n        pass\n        \n\n\nclass Rectangle(Figura):\n    def __init__(self, x, y):\n         if  x<= 0 and y <= 0:\n             raise ValueError(\"Valores deben ser mayores q que 0\")\n         self.x = x\n         self.y = y\n\n    \n    \n    \n    def Area(self):\n         \n        return self.x*self.y\n         \n            \n    \n\nclass Square(Figura):\n    def __init__(self, x):\n        if  x <= 0 :\n             raise ValueError(\"Valores deben ser mayoresq que 0\")\n        self.x = x\n     \n    \n    def Area(self):\n         return self.x ** 2\n         \n        \nclass Circle(Figura):\n    def __init__(self, r):\n        if  r <= 0 :\n            raise ValueError(\"Valores deben ser mayores q que 0\")\n        self.r = r\n    \n    def Area(self):\n            return 3.14*self.r ** 2\n         \n            \n        \ndef Calcular_Area(f: Figura):\n    print(f.Area())\n    \nR =  Rectangle(12,14) \nS =  Square(7) \n\nC = Circle(10)\n\n\n\n\nFigurillas = [R,S,C]\nfor i in Figurillas:\n    Calcular_Area(i)\n\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n#  * cumplir el LSP.\n#  * Instrucciones:\n#  * 1. Crea la clase Vehículo.\n#  * 2. Añade tres subclases de Vehículo.\n#  * 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n#  * 4. Desarrolla un código que compruebe que se cumple el LSP.\n#  */\n\nclass Vehiculo:\n    def __init__(self, speed = 0):\n        self.speed = speed\n\n    def acelerar(self, i):\n        self.speed += i\n\n    def frenar(self, d):\n        self.speed -= d\n        if self.speed <= 0 :\n            self.speed = 0\n            \n        \n\nclass carricoche(Vehiculo):\n    def __init__(self, speed=0):\n        super().__init__(speed)\n    \n    def acelerar(self,i):\n        super().acelerar(i)\n        return f\" Carricoche ACELERAR Velocidad {self.speed}\"\n\n    def frenar(self,d):\n       super().frenar(d)\n       return f\" Carricoche FRENO Velocidad {self.speed}\"\n\n    \nclass riquimbili(Vehiculo):\n     def __init__(self, speed=0):\n        super().__init__(speed)\n    \n     def acelerar(self, i):\n        super().acelerar(i)\n        return f\" Rikimbili ACELERAR Velocidad {self.speed}\"\n\n     def frenar(self,d):\n       super().frenar(d)\n       return f\" Rikimbili FRENO Velocidad {self.speed}\"\n\nC = carricoche()\nR = riquimbili()\nV = [C,R]\n\ndef test_LSP(v: Vehiculo):\n    print(v.acelerar(100))\n    print(v.acelerar(12))\n    print(v.acelerar(1))\n    print(v.acelerar(45))\n    print(v.frenar(34))\n\n\n\nprint(\"EXTRA\")\n \n\ntest_LSP(C)    \ntest_LSP(R )\ntest_LSP(C )\ntest_LSP(C )\ntest_LSP(R )\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/rigo93acosta.py",
    "content": "'''\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n * cumplir el LSP.\n * Instrucciones:\n * 1. Crea la clase Vehículo.\n * 2. Añade tres subclases de Vehículo.\n * 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n * 4. Desarrolla un código que compruebe que se cumple el LSP.\n */\n'''\n\n'''\nBasic\n'''\n\n# Ejemplo Incorrecto\nclass Bird:\n    def fly(self):\n        return \"Flying\"\n\nclass Chicken(Bird):\n    def fly(self):\n        raise Exception(\"Los pollos no vuelan\")\n    \n# bird = Bird()\n# print(bird.fly())\n# chicken = Chicken()\n# print(chicken.fly())\n\n# Correcto\nclass Bird:\n    def move(self) -> str:\n        return \"Moving\"\n    \nclass Chicken(Bird):\n    def move(self) -> str:\n        return \"Walking\"\n    \nbird = Bird()\nprint(bird.move())\nchicken = Chicken()\nprint(chicken.move())\n\n'''\nExtra\n'''\n\nclass Vehicle:\n    \n    def __init__(self, speed=0) -> None:\n        self.speed = speed\n\n    def accelerate(self, increment) -> str:\n        self.speed += increment\n        return f\"Velocidad {self.__class__.__name__}: {self.speed} km/h\"\n\n    def brake(self, decrement) -> str:\n        self.speed -= decrement\n        if self.speed < 0:\n            self.speed = 0\n        return f\"Velocidad {self.__class__.__name__}: {self.speed} km/h\"\n    \nclass Car(Vehicle):\n    def accelerate(self, increment) -> str:\n        print(f\"{self.__class__.__name__} acelerando\")\n        return super().accelerate(increment)\n    \n    def brake(self, decrement) -> str:\n        print(f\"{self.__class__.__name__} frenando\")\n        return super().brake(decrement)\n\nclass Bicycle(Vehicle):\n    def accelerate(self, increment) -> str:\n        print(f\"{self.__class__.__name__} acelerando\")\n        return super().accelerate(increment)\n    \n    def brake(self, decrement) -> str:\n        print(f\"{self.__class__.__name__} frenando\")\n        return super().brake(decrement)\n\n\nclass Motorcycle(Vehicle):\n    def accelerate(self, increment) -> str:\n        print(f\"{self.__class__.__name__} acelerando\")\n        return super().accelerate(increment)\n    \n    def brake(self, decrement) -> str:\n        print(f\"{self.__class__.__name__} frenando\")\n        return super().brake(decrement)\n\ncar = Car()\nprint(car.accelerate(10))\nprint(car.brake(5))\n\nbicycle = Bicycle()\nprint(bicycle.accelerate(3))\nprint(bicycle.brake(1))\n\nmotorcycle = Motorcycle()\nprint(motorcycle.accelerate(5))\nprint(motorcycle.brake(2))"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/rikmij.py",
    "content": "#Uso incorrecto\nclass Pokes:\n    def __init__(self, name):\n        self.name = name\n    \n    def attack(self, attack):\n        return f\"{self.name} usó {attack}\"\n    \n    def evolve(self):\n        return f\"{self.name} está evolucionando\"\n\nclass Seel(Pokes):\n    def __init__(self, name):\n        super().__init__(name)\n    \n    def evolve(self):\n        return f\"{self.name} está evolucionando a Dewgong\"\n\nclass Sableye(Pokes):\n    def __init__(self, name):\n        super().__init__(name)\n    \n    def evolve(self):\n        raise Exception(\"Sableye no tiene evolución\")\n\ncharmander = Seel(\"Seel\")\nprint(charmander.attack(\"Rayo Hielo\"))\nprint(charmander.evolve())\n\nsableye = Sableye(\"Sableye\")\n#print(sableye.evolve())\n\n'''\nNo todos los pokémon tienen evolución, por lo que este principio se estarñia incumpliendo aquí.\nLa superclase debe tener todos los métodos comunes a todos los hijos, y éstos poder tener sus propios métodos\nademás de los heredados\n'''\n\n#Uso correcto\nclass Pokemon:\n    def __init__(self, name):\n        self.name = name\n    \n    def attack(self, attack):\n        return f\"{self.name} usó {attack}\"\n\nclass Charmander(Pokemon):\n    def __init__(self, name):\n        super().__init__(name)\n    \n    def evolve(self):\n        return f\"{self.name} está evolucionando a Charmeleon\"\n\nclass Tauros(Pokemon):\n    pass\n\ncharmander = Charmander(\"Charmander\")\nprint(charmander.attack(\"Ascuas\"))\nprint(charmander.evolve())\n\ntauros = Tauros(\"Tauros\")\nprint(tauros.attack(\"Derribo\"))\n\nprint(\"\\n\" + \"*\"*7 + \" EJERCICIO EXTRA \" + \"*\"*7)\nclass Vehicle:\n    def speed_up(self):\n        return \"El vehículo está acelerando\"\n    \n    def brake(self):\n        return \"El vehículo está frenando\"\n\nclass Car(Vehicle):\n    def  speed_up(self):\n        return \"El coche está acelerando\"\n    \n    def brake(self):\n        return \"El coche está frenando\"\n    \n    def open_trunk(self):\n        return \"El maletero se ha abierto\"\n\nclass Moto(Vehicle):\n    def  speed_up(self):\n        return \"La moto está acelerando\"\n    \n    def brake(self):\n        return \"La moto está frenando\"\n    \n    def make_noise(self):\n        return \"BRRRRUM BRUUUUM\"\n\nclass Tractor(Vehicle):\n    def  speed_up(self):\n        return \"El tractor está acelerando\"\n    \n    def brake(self):\n        return \"El tractor está frenando\"\n    \n    def sow(self):\n        return \"El tractor ha plantado semillas\"\n\ncoche = Car()\nprint(coche.open_trunk())\nprint(coche.brake())\n\nmoto = Moto()\nprint(moto.speed_up())\nprint(moto.make_noise())\n\ntractor = Tractor()\nprint(tractor.sow())\n\n'''\nComo Vehicle tiene todos los métodos comunes, en esos métodos comunes podría usarse la clase Vehicle en vez de las\nsubclases (aunque cambie el texto, pero es lo mismo), pero para los métodos específicos no.\nAsí, se cumple el LSP\n'''\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/python/santyjl.py",
    "content": "#28 SOLID: PRINCIPIO DE SUSTITUCIÓN DE LISKOV (LSP)\n\"\"\"\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)\"\n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n * cumplir el LSP.\n * Instrucciones:\n * 1. Crea la clase Vehículo.\n * 2. Añade tres subclases de Vehículo.\n * 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n * 4. Desarrolla un código que compruebe que se cumple el LSP.\n */\n\"\"\"\n\n'''\nLa L de SOLID alude al apellido de quien lo creó, Barbara Liskov, y dice que “las clases derivadas\ndeben poder sustituirse por sus clases base”.\n'''\n\n#Mal uso\nclass Ave:\n    def volar(self):\n        return \"El ave está volando\"\n\nclass Pinguino(Ave):\n    def volar(self):\n        # Los pingüinos no pueden volar, pero al ser una subclase de Ave,\n        # nos vemos obligados a implementar este método de una forma ilógica.\n        raise Exception(\"Los pingüinos no pueden volar\")\n\n# Función que espera cualquier ave\ndef mover_ave(ave: Ave):\n    return ave.volar()\n\n# Creamos un objeto de la clase Pinguino\npinguino = Pinguino()\n\n# Intentamos volar con el pingüino, pero causa un error\nprint(mover_ave(pinguino))  # Error: Los pingüinos no pueden volar\n\n#Buen uso\nclass Ave:\n    def mover(self):\n        return \"El ave se está moviendo\"\n\nclass AveVoladora(Ave):\n    def volar(self):\n        return \"El ave está volando\"\n\nclass Pinguino(Ave):\n    def mover(self):\n        return \"El pingüino está nadando\"\n\nclass Aguila(AveVoladora):\n    def volar(self):\n        return \"El águila está volando alto\"\n\n# Función que puede aceptar cualquier tipo de ave para moverse\ndef mover_ave(ave: Ave):\n    return ave.mover()\n\n# Función específica para aves voladoras\ndef volar_ave(ave: AveVoladora):\n    return ave.volar()\n\n# Creamos un pingüino y un águila\npinguino = Pinguino()\naguila = Aguila()\n\n# Llamamos a la función mover para ambas aves\nprint(mover_ave(pinguino))  # Salida: El pingüino está nadando\nprint(mover_ave(aguila))    # Salida: El ave se está moviendo\n\n# Llamamos a la función volar solo para aves voladoras\nprint(volar_ave(aguila))    # Salida: El águila está volando alto\n\n#Extra\nclass Vehiculo:\n    def acelerar():\n        return f\"El Vehiculo esta Acelerando\"\n\n    def frenar():\n        return f\"El vehiculo esta Frenando\"\n\nclass Moto(Vehiculo):\n    def acelerar():\n        return f\"La Moto esta Acelerando\"\n\n    def frenar():\n        return f\"La Moto esta Frenando\"\n\nclass Carro(Vehiculo):\n    def acelerar():\n        return f\"El Carro esta Acelerando\"\n\n    def frenar():\n        return f\"El Carro esta Frenando\"\n\nclass Bus(Vehiculo):\n    def acelerar():\n        return f\"El Bus esta Acelerando\"\n\n    def frenar():\n        return f\"El Bus esta Frenando\"\n\nmoto = Moto\ncarro = Carro\nbus = Bus\n\nprint(moto.acelerar())\nprint(moto.frenar())\n\nprint(carro.acelerar())\nprint(carro.frenar())\n\nprint(bus.acelerar())\nprint(bus.frenar())"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/rust/kenysdev.rs",
    "content": "/*\n╔═══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado                ║\n║ GitHub: https://github.com/Kenysdev   ║\n║ 2024 -  Rust                          ║\n╚═══════════════════════════════════════╝\n-------------------------------------------------\n* SOLID: PRINCIPIO DE SUSTITUCIÓN DE LISKOV (LSP)\n-------------------------------------------------\n*/\n\ntrait BaseT {\n    fn method_base(&self);\n}\n\n// Implementación\nstruct Sub1;\n\nimpl BaseT for Sub1 {\n    fn method_base(&self) {\n        println!(\"Sub1\");\n    }\n}\n\n// Implementación\nstruct Sub2;\n\nimpl BaseT for Sub2 {\n    fn method_base(&self) {\n        println!(\"Sub2\");\n    }\n}\n\n/*\n_______________\n* EJERCICIO:\n* Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n* cumplir el LSP.\n* Instrucciones:\n* 1. Crea la clase Vehículo.\n* 2. Añade tres subclases de Vehículo.\n* 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n* 4. Desarrolla un código que compruebe que se cumple el LSP.\n*/\n\n// Trait base\ntrait Vehicle {\n    fn brand(&self) -> &str;\n    fn model(&self) -> &str;\n    fn accelerate(&self) -> String;\n    fn brake(&self) -> String;\n}\n\n// ___________________________________________\n// Implementación\nstruct Car {\n    brand: String,\n    model: String,\n}\n\nimpl Car {\n    fn new(brand: &str, model: &str) -> Car {\n        Car {\n            brand: brand.to_string(),\n            model: model.to_string(),\n        }\n    }\n}\n\nimpl Vehicle for Car {\n    fn brand(&self) -> &str {\n        &self.brand\n    }\n\n    fn model(&self) -> &str {\n        &self.model\n    }\n\n    fn accelerate(&self) -> String {\n        format!(\"Acelerando auto: {} - {}\", self.brand, self.model)\n    }\n\n    fn brake(&self) -> String {\n        format!(\"Frenando auto: {} - {}\", self.brand, self.model)\n    }\n}\n\n// ___________________________________________\n// Implementación\nstruct Motorcycle {\n    brand: String,\n    model: String,\n}\n\nimpl Motorcycle {\n    fn new(brand: &str, model: &str) -> Motorcycle {\n        Motorcycle {\n            brand: brand.to_string(),\n            model: model.to_string(),\n        }\n    }\n}\n\nimpl Vehicle for Motorcycle {\n    fn brand(&self) -> &str {\n        &self.brand\n    }\n\n    fn model(&self) -> &str {\n        &self.model\n    }\n\n    fn accelerate(&self) -> String {\n        format!(\"Acelerando Motocicleta: {} - {}\", self.brand, self.model)\n    }\n\n    fn brake(&self) -> String {\n        format!(\"Frenando Motocicleta: {} - {}\", self.brand, self.model)\n    }\n}\n\n// ___________________________________________\n// Implementación\nstruct Truck {\n    brand: String,\n    model: String,\n}\n\nimpl Truck {\n    fn new(brand: &str, model: &str) -> Truck {\n        Truck {\n            brand: brand.to_string(),\n            model: model.to_string(),\n        }\n    }\n}\n\nimpl Vehicle for Truck {\n    fn brand(&self) -> &str {\n        &self.brand\n    }\n\n    fn model(&self) -> &str {\n        &self.model\n    }\n\n    fn accelerate(&self) -> String {\n        format!(\"Acelerando Camión: {} - {}\", self.brand, self.model)\n    }\n\n    fn brake(&self) -> String {\n        format!(\"Frenando Camión: {} - {}\", self.brand, self.model)\n    }\n}\n\n// ___________________________________________\nfn test_impls(vehicle: &dyn Vehicle) {\n    println!(\"\\nPropiedades:\");\n    println!(\"{} - {}\", vehicle.brand(), vehicle.model());\n\n    println!(\"\\nMétodos:\");\n    println!(\"{}\", vehicle.accelerate());\n    println!(\"{}\", vehicle.brake());\n}\n\nfn main() {\n    let s1 = Sub1;\n    let s2 = Sub2;\n\n    s1.method_base();\n    s2.method_base();\n\n    // _______________________________________________\n    // EXS\n    let car = Car::new(\"Honda\", \"Civic\");\n    test_impls(&car);\n\n    let motorcycle = Motorcycle::new(\"Kawasaki\", \"Ninja\");\n    test_impls(&motorcycle);\n\n    let truck = Truck::new(\"Ford\", \"Raptor\");\n    test_impls(&truck);\n\n}\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/sql/Nicojsuarez2.sql",
    "content": "# #28 SOLID: PRINCIPIO DE SUSTITUCIÓN DE LISKOV (LSP)\n> #### Dificultad: Media | Publicación: 08/07/24 | Corrección: 15/07/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n * cumplir el LSP.\n * Instrucciones:\n * 1. Crea la clase Vehículo.\n * 2. Añade tres subclases de Vehículo.\n * 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n * 4. Desarrolla un código que compruebe que se cumple el LSP.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/swift/blackriper.swift",
    "content": "import Foundation\n/*\n LSP liskov substitution principle\n El Principio de Substitución de Liskov es uno de los principios SOLID y hace referencia a cómo usamos\n la herencia de forma adecuada. El principio dice algo como lo siguiente si S es un subtipo de T , T\n puede ser reemplazado con objetos de tipo S sin alterar el comportamiento esperado en el programa.\n\n  para mas informmacion \n   escrito: https://www.arquitecturajava.com/el-principio-de-substitucion-de-liskov/\n   video: https://youtu.be/JQX7wrCzxFA?si=fr3SxQXPWeg0qyfN\n */\n\n// ejemplo de  lo que no debe se hacerce\n\nclass Person{\n   var dni:String?\n   var fullName:String\n   var creditCard:String?\n\n   init(dni:String?,fullName:String,creditCard:String?) {\n      self.dni = dni\n      self.fullName = fullName\n      self.creditCard = creditCard \n   }\n\n   func realizePayment(){\n     let dniPerson = self.dni ??  \"dni is nil\"\n     let creditCardPerson = self.creditCard ?? \"creditCard is nil\"\n     print(\"my dni is \\(dniPerson) and payment with \\(creditCardPerson) was done\")\n   }\n}\n// un niño no puede tener dni ni tarjeta  y para no modificar la superclase se usa nil\nclass Boy:Person{\n    init(fullName:String) {\n       super.init(dni: nil, fullName: fullName, creditCard: nil)\n    }\n\n    override func realizePayment() {\n        print(\"iam a boy icant dni and creditCard\")\n        \n    }\n }\n// lo que debe de hacerce \n\n// la superclase people debe delegar comportamiento a alguna superclase \nclass People {\n  let name:String\n  let lastName:String \n\n  init(name:String,lastName:String) {\n    self.name = name\n    self.lastName = lastName\n  }\n}\n\n// ahora la subclase adulto agrega objetos S que no son parte de la superclase y ahora ya no es necesario\n// que estos datos sean nulos ya que el adulto si cuenta con una tarjeta y dni\nclass Adult:People{\n  var dni:String\n  var creditCard:String\n\n   init(name:String,lastName:String,dni:String,creditCard:String) {\n     self.dni = dni\n     self.creditCard = creditCard\n     super.init(name: name, lastName: lastName)\n   }\n\n    func realizePayment() {\n     print(\"my dni is \\(self.dni) and payment with \\(self.creditCard) was done\")\n   }\n}\n\n// ahora la subclase niño queda mas limpia y esta puede delegar e pago a las clase Adulto\n class Kid :People{\n    var adult:Adult\n    init(name:String,lastName:String,adul:Adult) {\n      self.adult = adul  \n      super.init(name: name, lastName: lastName)\n    }\n }\n\n// probando la implementacion\n let adult = Adult(name: \"jose\", lastName: \"perez\", dni: \"12345678\", creditCard: \"123456789\")\n adult.realizePayment()\n\n let kid = Kid(name: \"rodolfo\", lastName: \"perez\",adul: adult)\n kid.adult.realizePayment()\n\n\n // ejercicio extra \n // nuestra superclase vehiculo \n class Vehicle{\n     var model :String \n     var speed : Int\n\n     init(model:String,speed:Int) {\n        self.model = model\n        self.speed = speed\n     }\n    \n    func accelerate() {\n        print(\"The \\(self.model) is accelerating \\(self.speed) km/h\")\n    }\n\n    func brake() {\n        print(\"The \\(self.model) is braking \")\n    }\n     \n }\n\n// creamos nuestras subclases\n class Car:Vehicle{\n    override init(model:String,speed:Int) {\n       super.init(model: model, speed: speed)\n    }\n }\n\n // como la clase truck necesita dejar su mercaderia estos nuevos objetos s no son parte de la superclase\n \n enum Burden {\n  case Grave , Fruit, Metal ,Rocks \n }\n\n class Truck:Vehicle{\n    var burden: Burden\n    init(model:String,speed:Int,burd:Burden) {\n       self.burden = burd\n       super.init(model: model, speed: speed)\n    }\n\n    func deliver() {\n        print(\"The \\(self.model) is delivering \\(self.burden)\")\n    }\n }\n// la clase bote puede anclar en algun lado por lo tanto este metodo se agrega \nclass Boot:Vehicle{\n    override init(model:String,speed:Int) {\n       super.init(model: model, speed: speed)\n    }\n\n    func anchor() {\n        print(\"The \\(self.model) is anchoring in hawaii island\")\n    }\n}\n\n\n// comprobar que la clase principal puede ser consumida  por sus subclases\n\nfunc consumeVehicle(vehicle:Vehicle){\n  vehicle.accelerate()\n  vehicle.brake()\n}\n\nlet car = Car(model: \"Bmw\", speed: 120)\nlet truck = Truck(model: \"Scania\", speed: 100, burd: .Grave)\nlet boot = Boot(model: \"Dometic\", speed: 250)\nconsumeVehicle(vehicle: car)\nconsumeVehicle(vehicle: truck)\nconsumeVehicle(vehicle: boot)\ntruck.deliver()\nboot.anchor()\n\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/typescript/Sac-Corts.ts",
    "content": "// Wrong way\nclass Bird {\n    fly(): void {\n        console.log('Flying!');\n    }\n}\n\nclass Penguin extends Bird {\n    fly(): void {\n        throw new Error('Penguins cannot fly!');\n    }\n}\n\nfunction makeBirdFly(bird: Bird): void {\n    bird.fly();\n}\n\nconst bird = new Bird();\nconst penguin = new Penguin();\n\nmakeBirdFly(bird);\n// makeBirdFly(penguin); // Not working //\n\n// Correct way\nclass Bird2 {\n    eat(): void {\n        console.log('Eating...');\n    }\n}\n\nclass FlyingBird extends Bird2 {\n    fly(): void {\n        console.log('Flying!');\n    }\n}\n\nclass Penguin2 extends Bird2 {\n    swim(): void {\n        console.log('Swimming!');\n    }\n}\n\nfunction makeFlyingBirdFly(bird: FlyingBird): void {\n    bird.fly();\n}\n\nconst eagle = new FlyingBird();\nconst penguin2 = new Penguin2();\n\nmakeFlyingBirdFly(eagle);\n// makeFlyingBirdFly(penguin2); // Not working //\n\n// ** Extra Exercise ** //\nabstract class Vehicle {\n    abstract accelerate(): void;\n    abstract brake(): void; \n}\n\nclass Car extends Vehicle {\n    accelerate(): void {\n        console.log('Car is accelerating');\n    }\n\n    brake(): void {\n        console.log('Car is braking');\n    }\n}\n\nclass Motorcycle extends Vehicle {\n    accelerate(): void {\n        console.log('Motorcycle is accelerating');\n    }\n\n    brake(): void {\n        console.log('Motorcycle is braking');\n    }\n}\n\nclass Bicycle extends Vehicle {\n    accelerate(): void {\n        console.log('Bicycle is accelerating');\n    }\n\n    brake(): void {\n        console.log('Bicycle is braking');\n    }\n}\n\nfunction testVehicle(vehicle: Vehicle): void {\n    vehicle.accelerate();\n    vehicle.brake();\n}\n\nconst car = new Car();\nconst motorcycle = new Motorcycle();\nconst bicycle = new Bicycle();\n\ntestVehicle(car);\ntestVehicle(motorcycle);\ntestVehicle(bicycle);\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/typescript/duendeintemporal.ts",
    "content": "//#28 - Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)\"\n * y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n * cumplir el LSP.\n * Instrucciones:\n * 1. Crea la clase Vehículo.\n * 2. Añade tres subclases de Vehículo.\n * 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n * 4. Desarrolla un código que compruebe que se cumple el LSP.\n */\n\n/* The Liskov Substitution Principle (LSP) is one of the five SOLID principles of object-oriented programming. This principle states that objects of a derived class should be able to replace objects of the base class without altering the correctness of the program. */\n\nlet log = console.log;\n\n// Check if running in a browser environment\nconst isBrowser = typeof window !== 'undefined';\n\n// Conditional check for browser environment\nif (isBrowser) {\n    window.addEventListener('load', () => {\n        const body: HTMLBodyElement | null = document.querySelector('body');\n        const title = document.createElement('h1');\n\n        body?.style.setProperty('background', '#000');\n        body?.style.setProperty('text-align', 'center');\n\n        title.textContent = 'Retosparaprogramadores #28.';\n        title.style.setProperty('font-size', '3.5vmax');\n        title.style.setProperty('color', '#fff');\n        title.style.setProperty('line-height', '100vh');\n\n        body?.appendChild(title);\n\n        setTimeout(() => {\n            alert('Retosparaprogramadores #28. Please open the Browser Developer Tools.');\n        }, 2000);\n        log('Retosparaprogramadores #28');\n    });\n} else {\n    log('This code is designed to run in a browser environment. Skipping window-related code.');\n    log('Retosparaprogramadores #28');\n}\n\n\n// Liskov Substitution Principle (LSP) Example\n\nclass Shape {\n    area(): number {\n        return 0; // Default implementation\n    }\n}\n\nclass Rectangle extends Shape {\n    constructor(private width: number, private height: number) {\n        super();\n    }\n\n    area(): number {\n        return this.width * this.height;\n    }\n}\n\nclass Square extends Shape {\n    constructor(private side: number) {\n        super();\n    }\n\n    area(): number {\n        return this.side * this.side;\n    }\n}\n\nconst calculateArea = (shape: Shape): number => {\n    return shape.area();\n};\n\nconst rectangle = new Rectangle(83, 105);\nconst square = new Square(40);\n\nlog(calculateArea(rectangle)); // 8715\nlog(calculateArea(square)); // 1600\n\n// Extra Difficulty Exercise\n\n// Define the ICar interface\ninterface ICar {\n    brand: string;\n    model: string;\n    maxSpeed: number;\n    acceleration: number;\n    deceleration: number;\n}\n\n// Define the Car class\nclass Car {\n    constructor(\n        public brand: string,\n        public model: string,\n        public maxSpeed: number,\n        public acceleration: number,\n        public deceleration: number,\n        public currentSpeed: number = 0\n    ) {}\n\n    accelerate(seconds: number): void {\n        const newSpeed = this.currentSpeed + this.acceleration * seconds;\n        this.currentSpeed = Math.min(newSpeed, this.maxSpeed);\n        log(`${this.brand} ${this.model} accelerated to ${this.currentSpeed} km/h.`);\n    }\n\n    brake(seconds: number): void {\n        const newSpeed = this.currentSpeed - this.deceleration * seconds;\n        this.currentSpeed = Math.max(newSpeed, 0);\n        log(`${this.brand} ${this.model} braked to ${this.currentSpeed} km/h.`);\n    }\n}\n\n// Define the SportsCar class\nclass SportsCar extends Car {\n    constructor(brand: string, model: string, maxSpeed: number, acceleration: number, deceleration: number) {\n        super(brand, model, maxSpeed, acceleration, deceleration);\n    }\n}\n\n// Define the FamilyCar class\nclass FamilyCar extends Car {\n    constructor(brand: string, model: string, maxSpeed: number, acceleration: number, deceleration: number) {\n        super(brand, model, maxSpeed, acceleration, deceleration);\n    }\n}\n\n/* Note: Originally, the code used the spread operator (...) with Object.values to pass properties to \nthe constructor, like this:\n\nconst sportsCar = new SportsCar(...Object.values(sportsCars[0]) \nas [string, string, number, number, number]);\n\nWhile this approach works in some cases, it has a critical flaw: Object.values does not guarantee the\n order of properties. This can lead to runtime errors if the order of properties in the object does\n  not match the order of parameters in the constructor.*/\n// That's why switched to using a factory function:\n\n// Factory function for SportsCar\nfunction createSportsCar(carProps: ICar): SportsCar {\n    const { brand, model, maxSpeed, acceleration, deceleration } = carProps;\n    return new SportsCar(brand, model, maxSpeed, acceleration, deceleration);\n}\n\n// Factory function for FamilyCar\nfunction createFamilyCar(carProps: ICar): FamilyCar {\n    const { brand, model, maxSpeed, acceleration, deceleration } = carProps;\n    return new FamilyCar(brand, model, maxSpeed, acceleration, deceleration);\n}\n\n// Example data\nconst sportsCars: ICar[] = [\n    { brand: \"Ferrari\", model: \"488\", maxSpeed: 330, acceleration: 30, deceleration: 20 },\n    { brand: \"Porsche\", model: \"911 Turbo S\", maxSpeed: 320, acceleration: 28, deceleration: 18 },\n    { brand: \"Lamborghini\", model: \"Huracán\", maxSpeed: 325, acceleration: 32, deceleration: 22 }\n];\n\nconst familyCars: ICar[] = [\n    { brand: \"Toyota\", model: \"Sienna\", maxSpeed: 180, acceleration: 10, deceleration: 8 },\n    { brand: \"Honda\", model: \"Odyssey\", maxSpeed: 175, acceleration: 9, deceleration: 7 },\n    { brand: \"Chrysler\", model: \"Pacifica\", maxSpeed: 180, acceleration: 9, deceleration: 7 }\n];\n\n// Create instances using the factory function\nconst sportsCar = createSportsCar(sportsCars[0]);\nconst familyCar = createFamilyCar(familyCars[1]);\n\n// Test the cars\nfunction testCar(car: Car, accelerateSeconds: number, brakeSeconds: number): void {\n    car.accelerate(accelerateSeconds);\n    car.brake(brakeSeconds);\n}\n\ntestCar(sportsCar, 5, 2); // Ferrari 488 accelerated to 150 km/h. Ferrari 488 braked to 110 km/h.\ntestCar(familyCar, 5, 2); // Honda Odyssey accelerated to 45 km/h. Honda Odyssey braked to 31 km/h."
  },
  {
    "path": "Roadmap/28 - SOLID LSP/typescript/hozlucas28.ts",
    "content": "/*\n    Liskov Substitution Principle (LCP)...\n*/\n\nconsole.log('Liskov Substitution Principle (LCP)...')\n\nconsole.log('\\nBad implementation of Liskov Substitution Principle (LCP)...')\n\ninterface IBadAnimal {\n    walk(): void\n}\n\nabstract class BadAnimal implements IBadAnimal {\n    public abstract walk(): void\n}\n\nfunction walk(animal: BadAnimal) {\n    animal.walk()\n}\n\nclass BadDog extends BadAnimal {\n    public walk(): void {\n        console.log('Dog walking!')\n    }\n}\n\nclass BadFish extends BadAnimal {\n    public walk(): void {\n        throw new Error('Fish can not fly')\n    }\n}\n\nconsole.log(`\\n\\`\\`\\`\\ninterface IBadAnimal {\n    walk(): void\n}\n\nabstract class BadAnimal implements IBadAnimal {\n    public abstract walk(): void\n}\n\nfunction walk(animal: BadAnimal) {\n    animal.walk()\n}\n\nclass BadDog extends BadAnimal {\n    public walk(): void {\n        console.log('Dog walking!')\n    }\n}\n\nclass BadFish extends BadAnimal {\n    public walk(): void {\n        throw new Error('Fish can not fly')\n    }\n}\\n\\`\\`\\``)\n\nconsole.log(\n    '\\nThis is a bad implementation of Liskov Substitution Principle (LCP),\\n' +\n        'because the \"BadFish\" class implements the \"walk\" method which produces a\\n' +\n        'different side effect than the \"walk\" method inside the \"BadDog\" class. So,\\n' +\n        'if we execute the \"walk\" function with both classes (\"BadDog\", and \"BadFish\") the\\n' +\n        'function will produce different side effects that could be break the function execution.'\n)\n\nconsole.log('\\nGood implementation of Liskov Substitution Principle (LCP)...')\n\ninterface IGoodAnimal {\n    move(): void\n}\n\nabstract class GoodAnimal implements IGoodAnimal {\n    public abstract move(): void\n}\n\nfunction move(animal: GoodAnimal): void {\n    animal.move()\n}\n\nclass GoodDog extends GoodAnimal {\n    public move(): void {\n        console.log('Dog walking!')\n    }\n}\n\nclass GoodFish extends GoodAnimal {\n    public move(): void {\n        console.log('Fish swimming!')\n    }\n}\n\nconsole.log(`\\n\\`\\`\\`\\ninterface IGoodAnimal {\n    move(): void\n}\n\nabstract class GoodAnimal implements IGoodAnimal {\n    public abstract move(): void\n}\n\nfunction move(animal: GoodAnimal): void {\n    animal.move()\n}\n\nclass GoodDog extends GoodAnimal {\n    public move(): void {\n        console.log('Dog walking!')\n    }\n}\n\nclass GoodFish extends GoodAnimal {\n    public move(): void {\n        console.log('Fish swimming!')\n    }\n}\\n\\`\\`\\``)\n\nconsole.log(\n    '\\nThis is a good implementation of Liskov Substitution Principle (LCP),\\n' +\n        'because all child classes of \"GoodAnimal\" class implements each method\\n' +\n        'with the same side effect. So, if we execute the \"move\" function with both\\n' +\n        'classes (\"GoodDog\", and \"GoodFish\"), we are not going to have side effects that\\n' +\n        'could break the function execution.'\n)\n\nconsole.log(\n    '\\n# ---------------------------------------------------------------------------------- #\\n'\n)\n\n/*\n    Additional challenge...\n*/\n\nconsole.log('Additional challenge...')\n\ninterface IVehicle {\n    brake(): void\n    speedUp(): void\n}\n\nabstract class Vehicle implements IVehicle {\n    public abstract brake(): void\n    public abstract speedUp(): void\n}\n\nfunction brake(vehicle: Vehicle) {\n    vehicle.brake()\n}\n\nfunction speedUp(vehicle: Vehicle) {\n    vehicle.speedUp()\n}\n\nclass Car extends Vehicle {\n    public brake(): void {\n        console.log('Car braking!')\n    }\n\n    public speedUp(): void {\n        console.log('Car speeding up!')\n    }\n}\n\nclass Truck extends Vehicle {\n    public brake(): void {\n        console.log('Truck braking!')\n    }\n\n    public speedUp(): void {\n        console.log('Truck speeding up!')\n    }\n}\n\nclass Boat extends Vehicle {\n    public brake(): void {\n        console.log('Boat braking!')\n    }\n\n    public speedUp(): void {\n        console.log('Boat speeding up!')\n    }\n}\n\nconst car: Car = new Car()\nconst truck: Truck = new Truck()\nconst boat: Boat = new Boat()\n\nconsole.log()\nspeedUp(car)\nspeedUp(truck)\nspeedUp(boat)\n\nconsole.log()\nbrake(car)\nbrake(truck)\nbrake(boat)\n"
  },
  {
    "path": "Roadmap/28 - SOLID LSP/vb.net/kenysdev.vb",
    "content": "' ╔══════════════════════════════════════╗\n' ║ Autor:  Kenys Alvarado               ║\n' ║ GitHub: https://github.com/Kenysdev  ║\n' ║ 2024 -  VB.NET                       ║\n' ╚══════════════════════════════════════╝\n'-------------------------------------------------\n'* SOLID: PRINCIPIO DE SUSTITUCIÓN DE LISKOV (LSP)\n'-------------------------------------------------\n' - Cualquier objeto de una subclase debe comportarse de manera consistente con los objetos de\n'   la clase base, cumpliendo con los contratos definidos por la interfaz de la clase base.\n\n\nPublic MustInherit Class ClassBase\n    Public MustOverride Sub MethodBase()\nEnd Class\n\nPublic Class SubClass1\n    Inherits ClassBase\n\n    Public Overrides Sub MethodBase()\n        Console.WriteLine(\"SubClass1\")\n    End Sub\nEnd Class\n\nPublic Class SubClass2\n    Inherits ClassBase\n\n    Public Overrides Sub MethodBase()\n        Console.WriteLine(\"SubClass2\")\n    End Sub\nEnd Class\n\n'__________________________\n'* EJERCICIO\n'* Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como\n'* cumplir el LSP.\n'* Instrucciones:\n'* 1. Crea la clase Vehículo.\n'* 2. Añade tres subclases de Vehículo.\n'* 3. Implementa las operaciones \"acelerar\" y \"frenar\" como corresponda.\n'* 4. Desarrolla un código que compruebe que se cumple el LSP.\n\n' ____________________________________________________\n' Clase Base\nPublic MustInherit Class Vehicle\n    ' Propiedades\n    Public ReadOnly Property Brand As String\n    Public ReadOnly Property Model As String\n\n    ' Constructor\n    Public Sub New(brand As String, model As String)\n        Me.Brand = brand\n        Me.Model = model\n    End Sub\n\n    ' Métodos abstractos\n    Public MustOverride Function Accelerate() As String\n    Public MustOverride Function Brake() As String\nEnd Class\n\n' ____________________________________________________\n' Clase derivadas\nPublic Class Car\n    Inherits Vehicle\n\n    Public Sub New(brand As String, model As String)\n        MyBase.New(brand, model)\n    End Sub\n\n    Public Overrides Function Accelerate() As String\n        Dim properties As String = $\"{Brand} - {Model}\"\n        Return $\"Acelerando auto: {properties}\"\n    End Function\n\n    Public Overrides Function Brake() As String\n        Dim properties As String = $\"{Brand} - {Model}\"\n        Return $\"Frenando auto: {properties}\"\n    End Function\nEnd Class\n\n' ____________________________________________________\nClass Motorcycle\n    Inherits Vehicle\n\n    Public Sub New(brand As String, model As String)\n        MyBase.New(brand, model)\n    End Sub\n\n    Public Overrides Function Accelerate() As String\n        Dim properties As String = $\"{Brand} - {Model}\"\n        Return $\"Acelerando Motocicleta: {properties}\"\n    End Function\n\n    Public Overrides Function Brake() As String\n        Dim properties As String = $\"{Brand} - {Model}\"\n        Return $\"Frenando Motocicleta: {properties}\"\n    End Function\nEnd Class\n\n' ____________________________________________________\nPublic Class Truck\n    Inherits Vehicle\n\n    Public Sub New(brand As String, model As String)\n        MyBase.New(brand, model)\n    End Sub\n\n    Public Overrides Function Accelerate() As String\n        Dim properties As String = $\"{Brand} - {Model}\"\n        Return $\"Acelerando Camión: {properties}\"\n    End Function\n\n    Public Overrides Function Brake() As String\n        Dim properties As String = $\"{Brand} - {Model}\"\n        Return $\"Frenando Camión: {properties}\"\n    End Function\nEnd Class\n\n' ____________________________________________________\nPublic Module Program\n    Public Sub Main()\n        ' Exs 1\n\n        Dim TrySubClass1 As ClassBase = New SubClass1\n        Dim TrySubClass2 As ClassBase = New SubClass2\n\n        TrySubClass1.MethodBase()\n        TrySubClass2.MethodBase()\n\n        '_____________________________________________\n        ' Exs 2\n\n        Dim Car As Vehicle = New Car(\"Honda\", \"Civic\")\n        TestSubClass(Car)\n\n        Dim Motorcycle As Vehicle = New Motorcycle(\"Kawasaki\", \"Ninja\")\n        TestSubClass(Motorcycle)\n\n        Dim Truck As Vehicle = New Truck(\"Ford\", \"Raptor\")\n        TestSubClass(Truck)\n\n    End Sub\n\n    Public Sub TestSubClass(SubClass As Vehicle)\n        Console.WriteLine(vbCrLf + \"Propiedades:\")\n        Console.WriteLine($\"{SubClass.Brand} - {SubClass.Model}\")\n\n        Console.WriteLine(vbCrLf + \"Métodos:\")\n        Console.WriteLine(SubClass.Accelerate())\n        Console.WriteLine(SubClass.Brake())\n    End Sub\nEnd Module\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/bash/rantamhack.sh",
    "content": "#!/bin/bash\n\n\n\necho -e \"\\n\\n=======================================EJERCICIO=======================================\\n\\n\"\n\n\n#  * EJERCICIO:\n#  * Explora el \"Principio SOLID de Segregacion de Interfaces (Interface Segregation Principle, ISP)\" \n#  * y crea un ejemplo simple donde se muestre su funcionamiento de forma correcta e incorrecta.\n\n\n\n# function go_to(){\n#     echo \"Llendo a trabajar\"\n# }\n\n# function park(){\n#     echo \"El coche esta aparcando\"\n# }\n\n# function refueling(){\n#     echo \"El coche esta repostando\"\n# }\n        \n# function charging_batery(){\n#     echo \"El coche esta cargando las baterias\"\n# }\n        \n# function gas_car_actions(){\n#     go_to\n#     park\n#     refueling\n#     charging_batery               # ESTA FUNCION NO DEBERIA APARECER AQUI\n# }\n    \n# function electric_car_actions(){\n#     go_to\n#     park\n#     refueling                    # ESTA FUNCION NO DEBERIA APARECER AQUI\n#     charging_batery\n# }\n\n# # Ejecutar acciones vehiculos combustion\n# gas_car_actions\n\n# # Ejecutar acciones vehiculos electricos\n# electric_car_actions    \n    \n\n\nfunction go_to(){\n    echo \"Llendo a trabajar\"\n}\n\nfunction park(){\n    echo \"El coche esta aparcando\"\n}\n\n# Funcion para Gas-car\nfunction refueling(){\n    echo \"El coche esta repostando\"\n}\n        \n# Funcion para Electric-car\nfunction charging_batery(){\n    echo \"El coche esta cargando las baterias\"\n}\n\n\n# My gas-car\nfunction my_gas_car_actions(){\n    go_to\n    park\n    refueling\n}\n    \n\n# My Electric-car\nfunction my_electric_car_actions(){\n    go_to\n    park\n    charging_batery\n}\n\n\n\necho -e \"***********************************\"\n# Ejecutar acciones vehiculos combustion\nmy_gas_car_actions\n\n\necho -e \"***********************************\"\n\n# Ejecutar acciones vehiculos electricos\nmy_electric_car_actions    \n\n\n\n\n\necho -e \"\\n\\n=======================================DIFICULTAD EXTRA=======================================\\n\\n\"\n\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea un gestor de impresoras.\n#  * Requisitos:\n#  * 1. Algunas impresoras solo imprimen en blanco y negro.\n#  * 2. Otras solo a color.\n#  * 3. Otras son multifuncion, pueden imprimir, escanear y enviar fax.\n#  * Instrucciones:\n#  * 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n#  * 2. Aplica el ISP a la implementacion.\n#  * 3. Desarrolla un codigo que compruebe que se cumple el principio.\n\n\n\nfunction standby(){\n    echo -e \"Printer is on standby\"\n}\n\nfunction print_bw(){\n    echo -e \"Printer is printing in black and white\"\n}\n                \nfunction color_print(){\n    echo -e \"Printer is printing in color\"\n}\n    \nfunction scan(){\n    echo -e \"Multifunction printer is scannig a document\"\n}\n        \nfunction send_fax(){\n    echo -e \"Multifunction printer is faxing\"\n}\n    \n# Acciones de la impresora de blanco y negro\nfunction my_bw_printer_standby(){\n    standby\n}\n\nfunction my_bw_printer_print(){\n    print_bw\n}\n\n# Acciones de la impresora de color\nfunction my_color_printer_standby(){\n    standby\n}\n\nfunction my_color_printer_print(){\n    color_print\n}\n\n# Acciones de la impresora multifuncion\nfunction my_multifunction_printer_standby(){\n    standby\n}\n\nfunction my_multifunction_printer_print_bw(){\n    print_bw\n}\n\nfunction my_multifunction_printer_print_color(){\n    color_print\n}\n\nfunction my_multifunction_printer_scan(){\n    scan\n}\n\nfunction my_multifunction_printer_send_fax(){\n    send_fax\n}\necho -e \"****************************************************\"\nmy_bw_printer_standby\nmy_bw_printer_print\necho -e \"****************************************************\"\nmy_color_printer_standby\nmy_color_printer_print\necho -e \"****************************************************\"\nmy_multifunction_printer_standby\nmy_multifunction_printer_print_bw\nmy_multifunction_printer_print_color\nmy_multifunction_printer_scan\nmy_multifunction_printer_send_fax\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/c#/hequebo.cs",
    "content": "/*\n * El principio de Segregación de Interfaces dice que\n * \"Los clientes no deben de ser forzados a depender\n * de métodos que no utilizan\". Esto evita crear interfaces\n * con demasiados métodos que no todas las clases que implementen\n * la interfas van a utilizar, por lo que estos métodos no tendrán\n * implementación. Es un principio parecido al de Sustitución de \n * Liskov pero enfocado a las interfaces.\n */\n\n// Incorrecto\n/*\n * Creamos una interfaz que contiene varios métodos\n * para realizar un CRUD para diferentes tipos de \n * entidades\n */\ninterface ICrud<T>\n{\n    public List<T> GetList();\n    public T Get(int id);\n    public void Add(T entity);\n    public void Update(T entity);\n    public void Delete(T entity);\n\n}\n/*\n * Este primer servicio encargado de la clase User\n * implementa todas las operaciones de la interfaz\n * ICrud\n */\nclass UserService : ICrud<User>\n{\n    public List<User> GetList()\n    {\n        Console.WriteLine(\"Se obtiene lista de usuarios\");\n        return new List<User>();\n    }\n    public User Get(int id)\n    {\n        Console.WriteLine(\"Se obtiene usuario\");\n        return new User();\n    }\n    public void Add(User user) => Console.WriteLine($\"Se agrega nuevo usuario {user.Name}.- {user.Name}\");\n    public void Update(User user) => Console.WriteLine($\"Se actualiza usuario {user.Id}.- {user.Name}\");\n    public void Delete(User user) => Console.WriteLine($\"Se elimina usuario {user.Id}.- {user.Name}\");\n}\n/*\n * El siguiente servicio encargado de las transacción\n * realmente solo implementa los métodos de obtener y\n * agregar nuevas transacciones que por lógica de \n * negocio no es posible modificarlas o eliminarlas\n */\nclass TransactionsService : ICrud<Transaction>\n{\n    public List<Transaction> GetList()\n    {\n        Console.WriteLine(\"Se obtiene lista de transacciones\");\n        return new List<Transaction>();\n    }\n    public Transaction Get(int id)\n    {\n        Console.WriteLine(\"Se obtiene transacción\");\n        return new Transaction();\n    }\n    public void Add(Transaction transaction)\n    {\n        Console.WriteLine(\"Se guardó transacción\");\n    }\n\n    /*\n     * Los métodos Delete() y Update() arrojarán una excepción ya \n     * que no se tiene una implementación debido a reglas de negocio\n     */\n    public void Delete(Transaction transaction)\n    {\n        throw new NotImplementedException();\n    }\n    public void Update(Transaction transaction)\n    {\n        throw new NotImplementedException();\n    }\n}\n// Correcto\n/*\n * Separamos la interfaz anterior en dos, una que\n * contenga los método que ambos servicio implementan\n * y otra que contenga los métodos de actualizar y\n * eliminar\n */\ninterface IBasicCrud<T>\n{\n    public List<T> GetList();\n    public T Get(int id);\n    public void Add(T entity);\n}\ninterface IEditableCrud<T>\n{\n    public void Update(T entity);\n    public void Delete(T entity);\n}\n/*\n * Ahora los nuevos servicios pueden implementar la intrefaz\n * que contenga solo los métodos requeridos\n */\nclass UserServiceISP : IBasicCrud<User>, IEditableCrud<User>\n{\n    public List<User> GetList()\n    {\n        Console.WriteLine(\"Se obtiene lista de usuarios\");\n        return new List<User>();\n    }\n    public User Get(int id)\n    {\n        Console.WriteLine(\"Se obtiene usuario\");\n        return new User();\n    }\n    public void Add(User user) => Console.WriteLine($\"Se agrega nuevo usuario {user.Name}.- {user.Name}\");\n    public void Update(User user) => Console.WriteLine($\"Se actualiza usuario {user.Id}.- {user.Name}\");\n    public void Delete(User user) => Console.WriteLine($\"Se elimina usuario {user.Id}.- {user.Name}\");\n}\nclass TransactionServiceISP : IBasicCrud<Transaction>\n{\n    public List<Transaction> GetList()\n    {\n        Console.WriteLine(\"Se obtiene lista de transacciones\");\n        return new List<Transaction>();\n    }\n    public Transaction Get(int id)\n    {\n        Console.WriteLine(\"Se obtiene transacción\");\n        return new Transaction();\n    }\n    public void Add(Transaction transaction)\n    {\n        Console.WriteLine(\"Se guardó transacción\");\n    }\n}\n\n/*\n * Las siguientes clases representan modelos en la base de \n * datos, uno para una tabla de usuarios y otra para \n * transacciones realizadas en el sistema.\n */\nclass User\n{\n    public int Id { get; set; }\n    public string Name { get; set; }\n    public string Email { get; set; }\n}\nclass Transaction\n{\n    public int Id { get; set; }\n    public int UserId { get; set; }\n    public DateTime Date { get; set; }\n}\n// Ejercicio Extra\ninterface IPrinter\n{\n    public void Print(string doc);\n}\ninterface IColorPrinter\n{\n    public void PrintColor(string doc);\n}\ninterface IScanner\n{\n    public void Scan(string doc);\n}\ninterface IFax\n{\n    public void SendFax(string doc);\n}\n\nclass Printer : IPrinter\n{\n    public void Print(string doc) => Console.WriteLine($\"Imprimiendo documento {doc} en blanco y negro...\");\n}\nclass ColorPrinter : IColorPrinter\n{\n    public void PrintColor(string doc) => Console.WriteLine($\"Imprimiendo documento {doc} a color...\");\n}\nclass MultiFunctionPrinter : IPrinter, IColorPrinter, IScanner, IFax\n{\n    public void Print(string doc) => Console.WriteLine($\"Imprimiendo documento {doc} en blanco y negro...\");\n    public void PrintColor(string doc) => Console.WriteLine($\"Imprimiendo documento {doc} a color...\");\n    public void Scan(string doc) => Console.WriteLine($\"Esanenado documento {doc}...\");\n    public void SendFax(string doc) => Console.WriteLine($\"Envíando documento {doc} por fax...\");\n\n}\nclass Program\n{\n    static void Main(string[] args)\n    {\n        Console.WriteLine(\"----Principio de Segregación de Interfaces----\");\n        Console.WriteLine(\"---Incorrecto---\");\n        // Incorrecto\n        UserService userService = new UserService();\n        var userList = userService.GetList();\n        var user = userService.Get(1);\n        userService.Add(new User());\n        userService.Update(user);\n        userService.Delete(user);\n\n        TransactionsService transactionsService = new TransactionsService();\n        var transactionList = transactionsService.GetList();\n        var transaction = transactionsService.Get(1);\n        transactionsService.Add(new Transaction());\n        try\n        {\n            transactionsService.Update(transaction);\n        }\n        catch (Exception ex)\n        {\n            Console.WriteLine(ex.Message);\n        }\n        try\n        {\n            transactionsService.Delete(transaction);\n        } \n        catch (Exception ex)\n        {\n            Console.WriteLine(ex.Message);\n        }\n\n        Console.WriteLine(\"---Correcto---\");\n        UserServiceISP userServiceISP = new UserServiceISP();\n        userList = userServiceISP.GetList();\n        user = userServiceISP.Get(1);\n        userServiceISP.Add(new User());\n        userServiceISP.Update(user);\n        userServiceISP.Delete(user);\n\n        TransactionServiceISP transactionServiceISP = new TransactionServiceISP();\n        transactionList = transactionServiceISP.GetList();\n        transaction = transactionServiceISP.Get(1);\n        transactionServiceISP.Add(new Transaction());\n\n        // Ejercicio Extra\n        Console.WriteLine(\"---Ejercicio Extra---\");\n        Printer printer = new Printer();\n        printer.Print(\"holamundo.pdf\");\n        \n        ColorPrinter colorPrinter = new ColorPrinter();\n        colorPrinter.PrintColor(\"holamundo.pdf\");\n\n        MultiFunctionPrinter multiFunctionPrinter = new MultiFunctionPrinter();\n        multiFunctionPrinter.Print(\"holamundo.pdf\");\n        multiFunctionPrinter.PrintColor(\"holamundo.pdf\");\n        multiFunctionPrinter.Scan(\"holamundo.pdf\");\n        multiFunctionPrinter.SendFax(\"holamundo.txt\");\n        Console.ReadLine();\n    }\n}"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/c#/kenysdev.cs",
    "content": "namespace exs29;\n/*\n╔══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado               ║\n║ GitHub: https://github.com/Kenysdev  ║\n║ 2024 -  C#                           ║\n╚══════════════════════════════════════╝\n-----------------------------------------------------\n* SOLID: PRINCIPIO DE SEGREGACIÓN DE INTERFACES (ISP)\n-----------------------------------------------------\n- Una clase no debería estar obligada a implementar interfaces que no utiliza.\n  Evitando crear grandes clases monolíticas.\n*/\n\n// NOTA: Este ejemplo muestra el uso CORRECTO. Para suponer un ejemplo que viole el principio, sería. \n//       Imaginar todos los métodos siguientes, en una sola interfaz, entonces algunos animales\n//       implementarían una interfaz que no utilizarían.\n\npublic interface IFlyable\n{\n    void Fly();\n}\n\npublic interface ISwimmable\n{\n    void Swim();\n}\n\n// ____________________________\n// Implementar\npublic class Fish : ISwimmable\n{\n    public void Swim()\n    {\n        Console.WriteLine(\"El pez está nadando.\");\n    }\n}\n\npublic class Duck : IFlyable, ISwimmable\n{\n    public void Fly()\n    {\n        Console.WriteLine(\"El pato está volando.\");\n    }\n\n    public void Swim()\n    {\n        Console.WriteLine(\"El pato está nadando.\");\n    }\n}\n\n/*\n_______________\n * EJERCICIO:\n * Crea un gestor de impresoras.\n * Requisitos:\n * 1. Algunas impresoras sólo imprimen en blanco y negro.\n * 2. Otras sólo a color.\n * 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n * Instrucciones:\n * 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n * 2. Aplica el ISP a la implementación.\n * 3. Desarrolla un código que compruebe que se cumple el principio.\n*/\n\npublic interface IPrinter\n{\n    void PrintFile(string file);\n}\n\npublic interface IScanner\n{\n    void ToScan(string pathSave);\n}\n\npublic interface IFax\n{\n    void SendFile(string file, int phoneNumber);\n}\n\n// ____________________________\n// Implementar\npublic class MonoPrinter : IPrinter\n{\n    public void PrintFile(string file)\n    {\n        Console.WriteLine(\"\\nImpresora blanco y negro:\");\n        Console.WriteLine(file + \" se imprimió.\");\n    }\n}\n\npublic class ColorPrinter : IPrinter\n{\n    public void PrintFile(string file)\n    {\n        Console.WriteLine(\"\\nImpresora a color:\");\n        Console.WriteLine(file + \" se imprimió.\");\n    }\n}\n\npublic class Scanner : IScanner\n{\n    public void ToScan(string pathSave)\n    {\n        Console.WriteLine(\"\\nEscaneo realizado, Guardado en: \" + pathSave);\n    }\n}\n\npublic class Fax : IFax\n{\n    public void SendFile(string file, int phoneNumber)\n    {\n        Console.WriteLine(\"\\n-\" + file + \" Fue enviado a: \" + phoneNumber);\n    }\n}\n\npublic class MultiFunctionPrinter\n{\n    public IPrinter monoPrinter = new MonoPrinter();\n    public IPrinter colorPrinter = new ColorPrinter();\n    public IScanner theScanner = new Scanner();\n    public IFax fax = new Fax();\n}\n\n//__________________\npublic class Program\n{\n    static void Main()\n    {\n        Fish theFish = new();\n        Duck theDuck = new();\n        theFish.Swim();\n        theDuck.Swim();\n        theDuck.Fly();\n        \n        //___________________________\n        // exs 2\n        MonoPrinter monoPrinter = new();\n        monoPrinter.PrintFile(\"filex.pdf\");\n\n        ColorPrinter colorPrinter = new();\n        colorPrinter.PrintFile(\"filex.pdf\");\n\n        Scanner theScanner = new ();\n        theScanner.ToScan(\"c:\\\\docs\");\n\n        Fax fax = new();\n        fax.SendFile(\"filex.pdf\", 12345678);\n\n        Console.WriteLine(\"\\n___________\\nMultifunción:\");\n\n        MultiFunctionPrinter multiFunctionPrinter = new();\n        multiFunctionPrinter.monoPrinter.PrintFile(\"filex.pdf\");\n        multiFunctionPrinter.colorPrinter.PrintFile(\"filex.pdf\");\n        multiFunctionPrinter.theScanner.ToScan(\"c:\\\\docs\");\n        multiFunctionPrinter.fax.SendFile(\"filex.pdf\", 12345678);\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/c++/hectorio23.cpp",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23 \n\n#include <cstdlib>\n#include <iostream>\n#include <memory>\n\n// Define una interfaz abstracta para la funcionalidad de impresión\nclass Printer {\npublic:\n    virtual void print() const = 0;\n    virtual ~Printer() = default;\n};\n\n// Define una interfaz abstracta para la funcionalidad de escaneo\nclass Scanner {\npublic:\n    virtual void scan() const = 0;\n    virtual ~Scanner() = default;\n};\n\n// Define una interfaz abstracta para la funcionalidad de fax\nclass Fax {\npublic:\n    virtual void fax() const = 0;\n    virtual ~Fax() = default;\n};\n\n// Implementa una impresora en blanco y negro que solo necesita la interfaz de impresión\nclass BlackAndWhitePrinter : public Printer {\npublic:\n    void print() const override {\n        std::cout << \"[+] - Imprimiendo en blanco y negro\" << std::endl;\n    }\n};\n\n// Implementa una impresora a color que solo necesita la interfaz de impresión\nclass ColorPrinter : public Printer {\npublic:\n    void print() const override {\n        std::cout << \"[+] - Imprimiendo en color\" << std::endl;\n    }\n};\n\n// Implementa una impresora multifunción que necesita todas las interfaces: impresión, escaneo y fax\nclass MultiFunctionPrinter : public Printer, public Scanner, public Fax {\npublic:\n    void print() const override {\n        std::cout << \"[+] - Imprimiendo en multifunción\" << std::endl;\n    }\n    void scan() const override {\n        std::cout << \"[+] - Escaneando en multifunción\" << std::endl;\n    }\n    void fax() const override {\n        std::cout << \"[+] - Enviando fax en multifunción\" << std::endl;\n    }\n};\n\n// Función que prueba la funcionalidad de impresión de una impresora\nvoid testPrinter(const Printer& printer) {\n    printer.print();\n}\n\n// Función que prueba la funcionalidad de escaneo de un escáner\nvoid testScanner(const Scanner& scanner) {\n    scanner.scan();\n}\n\n// Función que prueba la funcionalidad de fax de un dispositivo de fax\nvoid testFax(const Fax& fax) {\n    fax.fax();\n}\n\nint main() {\n    // Crear instancias de las impresoras\n    BlackAndWhitePrinter b_and_w_printer;\n    ColorPrinter color_printer;\n    MultiFunctionPrinter multi_printer;\n\n    // Probar las impresoras\n    testPrinter(b_and_w_printer);\n    testPrinter(color_printer);\n    testPrinter(multi_printer);\n    testScanner(multi_printer);\n    testFax(multi_printer);\n\n    return EXIT_SUCCESS;\n}\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/dart/EmilianoAngel.dart",
    "content": "// Incorrecto \n// abstract class WorkerInterface {\n//   void work();\n//   void eat();\n// }\n\n// class Human implements WorkerInterface {\n//   @override\n//   void work() {\n//     print('Trabajando');\n//   }\n//   @override\n//   void eat() {\n//     print('Comiendo');\n//   }\n// }\n\n// class Robot implements WorkerInterface {\n//   @override\n//   void work() {\n//     print('Trabajando');\n//   }\n//   @override\n//   void eat() {\n//     // los robots no comen\n//   }\n// }\n\n// Correcto\n\nabstract class WorkInterface {\n  void work();\n}\n\nabstract class EatInterface {\n  void eat();\n}\n\nclass Human implements WorkInterface, EatInterface {\n  @override\n  void work() {\n    print('Trabajando');\n  }\n\n  @override\n  void eat() {\n    print('Comiendo');\n  }\n}\n\nclass Robot implements WorkInterface {\n  @override\n  void work() {\n    print('Trabajando');\n  }\n}\n\n// Ejercicio gestor de impresoras \n\nabstract class PrinterInterface {\n  void printBlackWhite(String document);\n}\n\nabstract class ScannerInterface {\n  void scan(String document);\n}\n\nabstract class FaxInterface {\n  void sendFax(String document);\n}\n\nabstract class ColorPrinterInterface {\n  void printColor(String document);\n}\n\nclass Printer implements PrinterInterface {\n  @override\n  void printBlackWhite(String document) {\n    print('Imprimiendo en blanco y negro el documento $document');\n  }\n}\n\nclass ColorPrinter implements ColorPrinterInterface {\n  @override\n  void printColor(String document) {\n    print('Imprimiendo a color el documento $document');\n  }\n}\n\nclass MultiFunctionPrinter implements PrinterInterface, ColorPrinterInterface, FaxInterface, ScannerInterface {\n  @override\n  void printBlackWhite(String document) {\n    print('Imprimiendo en blanco y negro el documento $document');\n  }\n\n  @override\n  void printColor(String document) {\n    print('Imprimiendo a color el documento $document');\n  }\n\n  @override\n  void sendFax(String document) {\n    print('Enviando por fax el documento $document');\n  }\n\n  @override\n  void scan(String document) {\n    print('Escaneando el documento $document');\n  }\n}\n\nvoid testPrinters() {\n  Printer printer = Printer();\n  ColorPrinter colorPrinter = ColorPrinter();\n  MultiFunctionPrinter multiFunctionPrinter = MultiFunctionPrinter();\n\n  printer.printBlackWhite('doc.pdf');\n  colorPrinter.printColor('doc.pdf');\n  multiFunctionPrinter.printBlackWhite('doc.pdf');\n  multiFunctionPrinter.printColor('doc.pdf');\n  multiFunctionPrinter.scan('doc.pdf');\n  multiFunctionPrinter.sendFax('doc.pdf');\n}\n\nvoid main() {\n\n  // Human human = Human();\n  // human.work();\n  // human.eat();\n\n  // Robot robot = Robot();\n  // robot.work();\n  // robot.eat(); // error\n\n\n  Human human = Human();\n  human.work();\n  human.eat();\n\n  Robot robot = Robot();\n  robot.work();\n\n  // Ejercicio gestor de impresoras \n\n  testPrinters();\n\n}"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/ejercicio.md",
    "content": "# #29 SOLID: PRINCIPIO DE SEGREGACIÓN DE INTERFACES (ISP)\n> #### Dificultad: Media | Publicación: 15/07/24 | Corrección: 22/07/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Segregación de Interfaces (Interface Segregation Principle, ISP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un gestor de impresoras.\n * Requisitos:\n * 1. Algunas impresoras sólo imprimen en blanco y negro.\n * 2. Otras sólo a color.\n * 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n * Instrucciones:\n * 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n * 2. Aplica el ISP a la implementación.\n * 3. Desarrolla un código que compruebe que se cumple el principio.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/29 - SOLID ISP/go/hozlucas28.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n)\n\n/* -------------------------------------------------------------------------- */\n/*                                 INTERFACES                                 */\n/* -------------------------------------------------------------------------- */\n\ntype BadVehicle interface {\n\tDrive()\n\tFly()\n}\n\ntype AirVehicle interface {\n\tFly()\n}\n\ntype LandVehicle interface {\n\tDrive()\n}\n\ntype BlackAndWhitePrinter interface {\n\tPrint()\n}\n\ntype ColorPrinter interface {\n\tPrint()\n}\n\ntype MultifunctionalPrinter interface {\n\tPrint()\n\tScan()\n\tSendFax()\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                   CLASSES                                  */\n/* -------------------------------------------------------------------------- */\n\n/* ------------------------------- BadAirplane ------------------------------ */\n\ntype badAirplane struct{}\n\nfunc NewBadAirplane() BadVehicle {\n\tvar airplane badAirplane = badAirplane{}\n\treturn &airplane\n}\n\nfunc (airplane *badAirplane) Drive() {\n\tpanic(\"Airplanes do not drive\")\n\n}\n\nfunc (airplane *badAirplane) Fly() {\n\tfmt.Println(\"The airplane is flying!\")\n}\n\n/* --------------------------------- BadCar --------------------------------- */\n\ntype badCar struct{}\n\nfunc NewBadCar() BadVehicle {\n\tvar car badCar = badCar{}\n\treturn &car\n}\n\nfunc (car *badCar) Drive() {\n\tfmt.Println(\"The car is driving!\")\n}\n\nfunc (car *badCar) Fly() {\n\tpanic(\"Cars do not fly\")\n}\n\n/* ------------------------------ GoodAirplane ------------------------------ */\n\ntype goodAirplane struct{}\n\nfunc NewGoodAirplane() AirVehicle {\n\tvar airplane goodAirplane = goodAirplane{}\n\treturn &airplane\n}\n\nfunc (airplane *goodAirplane) Fly() {\n\tfmt.Println(\"The airplane is flying!\")\n}\n\n/* --------------------------------- GoodCar -------------------------------- */\n\ntype goodCar struct{}\n\nfunc NewGoodCar() LandVehicle {\n\tvar car goodCar = goodCar{}\n\treturn &car\n}\n\nfunc (car *goodCar) Drive() {\n\tfmt.Println(\"The car is driving!\")\n}\n\n/* -------------------------- BlackAndWhitePrinter -------------------------- */\n\ntype blackAndWhitePrinter struct{}\n\nfunc NewBlackAndWhitePrinter() BlackAndWhitePrinter {\n\tvar printer blackAndWhitePrinter = blackAndWhitePrinter{}\n\treturn &printer\n}\n\nfunc (printer *blackAndWhitePrinter) Print() {\n\tfmt.Println(\"Paper printed in black and white!\")\n}\n\n/* ------------------------------ ColorPrinter ------------------------------ */\n\ntype colorPrinter struct{}\n\nfunc NewColorPrinter() ColorPrinter {\n\tvar printer colorPrinter = colorPrinter{}\n\treturn &printer\n}\n\nfunc (printer *colorPrinter) Print() {\n\tfmt.Println(\"Paper printed in color!\")\n}\n\n/* ------------------------- MultifunctionalPrinter ------------------------- */\n\ntype multifunctionalPrinter struct{}\n\nfunc NewMultifunctionalPrinter() MultifunctionalPrinter {\n\tvar printer multifunctionalPrinter = multifunctionalPrinter{}\n\treturn &printer\n}\n\nfunc (printer *multifunctionalPrinter) Print() {\n\tfmt.Println(\"Paper printed!\")\n}\n\nfunc (printer *multifunctionalPrinter) Scan() {\n\tfmt.Println(\"Scan completed!\")\n}\n\nfunc (printer *multifunctionalPrinter) SendFax() {\n\tfmt.Println(\"Fax sent!\")\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\nfunc main() {\n\t/*\n\t\tInterface Segregation Principle (ISP)...\n\t*/\n\n\tfmt.Println(\"Interface Segregation Principle (ISP)...\")\n\n\tfmt.Println(\"\\nBad implementation of Interface Segregation Principle (ISP)...\")\n\n\tfmt.Println(\"\\n```\\n\" + `type BadVehicle interface {\n  Drive()\n  Fly()\n}\n\ntype badAirplane struct{}\n\nfunc NewBadAirplane() BadVehicle {\n  var airplane badAirplane = badAirplane{}\n  return &airplane\n}\n\nfunc (airplane *badAirplane) Drive() {\n  panic(\"Airplanes do not drive\")\n\n}\n\nfunc (airplane *badAirplane) Fly() {\n  fmt.Println(\"The airplane is flying!\")\n}\n\ntype badCar struct{}\n\nfunc NewBadCar() BadVehicle {\n  var car badCar = badCar{}\n  return &car\n}\n\nfunc (car *badCar) Drive() {\n  fmt.Println(\"The car is driving!\")\n}\n\nfunc (car *badCar) Fly() {\n  panic(\"Cars do not fly\")\n}` + \"\\n```\")\n\n\tfmt.Println(\n\t\t\"\\nThis is a bad implementation of Interface Segregation Principle (ISP),\\n\" +\n\t\t\t\"because the 'badAirplane' class and the 'badCar' class should not implement\\n\" +\n\t\t\t\"an interface with methods that they are going to never use. So, the implemented\\n\" +\n\t\t\t\"interface ('BadVehicle') is to general for both classes.\",\n\t)\n\n\tfmt.Println(\"\\nGood implementation of Interface Segregation Principle (ISP)...\")\n\n\tfmt.Println(\"\\n```\\n\" + `type AirVehicle interface {\n  Fly()\n}\n\ntype LandVehicle interface {\n  Drive()\n}\n\ntype goodAirplane struct{}\n\nfunc NewGoodAirplane() AirVehicle {\n  var airplane goodAirplane = goodAirplane{}\n  return &airplane\n}\n\nfunc (airplane *goodAirplane) Fly() {\n  fmt.Println(\"The airplane is flying!\")\n}\n\ntype goodCar struct{}\n\nfunc NewGoodCar() LandVehicle {\n  var car goodCar = goodCar{}\n  return &car\n}\n\nfunc (car *goodCar) Drive() {\n  fmt.Println(\"The car is driving!\")\n}` + \"\\n```\")\n\n\tfmt.Println(\n\t\t\"\\nThis is a good implementation of Interface Segregation Principle (ISP),\\n\" +\n\t\t\t\"because the 'goodAirplane' class and the 'goodCar' class only implements\\n\" +\n\t\t\t\"the necessary methods, without any extras.\",\n\t)\n\n\tfmt.Println(\n\t\t\"\\n# ---------------------------------------------------------------------------------- #\",\n\t)\n\n\t/*\n\t   Additional challenge...\n\t*/\n\n\tfmt.Println(\"\\nAdditional challenge...\")\n\n\tvar blackAndWhitePrinter BlackAndWhitePrinter = NewBlackAndWhitePrinter()\n\tvar colorPrinter ColorPrinter = NewColorPrinter()\n\tvar multifunctionalPrinter MultifunctionalPrinter = NewMultifunctionalPrinter()\n\n\tfmt.Println()\n\tblackAndWhitePrinter.Print()\n\n\tfmt.Println()\n\tcolorPrinter.Print()\n\n\tfmt.Println()\n\tmultifunctionalPrinter.Print()\n\n\tfmt.Println()\n\tmultifunctionalPrinter.Scan()\n\n\tfmt.Println()\n\tmultifunctionalPrinter.SendFax()\n}\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/go/raynerpv2022.go",
    "content": "package main\n\nimport \"fmt\"\n\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Segregación de Interfaces (Interface Segregation Principle, ISP)\"\n * y crea un ejemplo simple donde se muestre su funcionamiento de forma correcta e incorrecta.\n *\n\n */\n\n// Imagina que estás diseñando un sistema para distintos tipos de trabajadores en una empresa:\n\n//     Trabajador oficina\n\n//     Trabajador remoto\n\n//     Robot de fábrica\n\n// Tu interfaz base (o clase abstracta) define:\n\n//     trabajar()\n\n//     asistir_a_reunion()\n\n//     comer_en_cafeteria()\n\n// ❌ Problema:\n\n//     El Robot también hereda esta interfaz.\n\n//     Pero... ¿tiene sentido que un robot tenga que:\n\n//         asistir a reuniones\n\n//         o comer en la cafetería?\n\n// ¡No!, pero el diseño lo obliga a implementar esos métodos.\n\n// Incorrect\ntype Task interface {\n\tWorking()\n\tMeeting()\n\tEating()\n}\n\ntype OfficeWorker struct{}\n\nfunc (OW *OfficeWorker) Working() {\n\tfmt.Println(\"Trabajando...soy un trabajador de oficina\")\n}\n\nfunc (OW *OfficeWorker) Meeting() {\n\tfmt.Println(\"Asistiendo a reunion...soy un trabajador de oficina\")\n}\n\nfunc (OW *OfficeWorker) Eating() {\n\tfmt.Println(\"Comiendo en cafeteria...soy un trabajador de oficina\")\n}\n\ntype RemoteWorker struct{}\n\nfunc (RW *RemoteWorker) Working() {\n\tfmt.Println(\"Trabajando...soy un trabajador remoto\")\n}\n\nfunc (OW *RemoteWorker) Meeting() {\n\tfmt.Println(\"Asistiendo a reunion...soy un trabajador remoto\")\n}\n\nfunc (OW *RemoteWorker) Eating() {\n\tfmt.Println(\"Comiendo en cafeteria...soy un trabajador remoto\")\n}\n\ntype RobotFabric struct{}\n\nfunc (RB *RobotFabric) Working() {\n\tfmt.Println(\"Trabajando...soy un robot\")\n}\n\nfunc (RB *RobotFabric) Meeting() {\n\tfmt.Println(\"Asistiendo a reunion... pero no puedo, me obligas a hacerlo, soy un robot\")\n}\n\nfunc (OW *RobotFabric) Eating() {\n\tfmt.Println(\"Comiendo en cafeteria...pero no puedo, me obligas a hacerlo, soy un robot\")\n}\n\nfunc Orquester(w Task) {\n\tw.Working()\n\tw.Meeting()\n\tw.Eating()\n}\n\n// correcto\n\ntype workingVirtual interface {\n\tworking()\n}\ntype eatingVirtual interface {\n\teating()\n}\ntype meetingVirtual interface {\n\tmeeting()\n}\n\ntype WorkerOficce struct{}\n\nfunc (wo *WorkerOficce) working() {\n\tfmt.Println(\"Trabajando...soy un trabajador de oficina\")\n}\n\nfunc (wo *WorkerOficce) eating() {\n\tfmt.Println(\"Comiendo...soy un trabajador de oficina\")\n}\n\nfunc (wo *WorkerOficce) meeting() {\n\tfmt.Println(\"En Reunion...soy un trabajador de oficina\")\n}\n\ntype WorkerRemote struct{}\n\nfunc (wo *WorkerRemote) working() {\n\tfmt.Println(\"Trabajando...soy un trabajador   Remoto\")\n}\n\nfunc (wo *WorkerRemote) eating() {\n\tfmt.Println(\"Comiendo...soy un trabajador   Remoto\")\n}\n\nfunc (wo *WorkerRemote) meeting() {\n\tfmt.Println(\"En Reunion...soy un trabajador   Remoto\")\n}\n\ntype WorkerRobot struct{}\n\nfunc (wo *WorkerRobot) working() {\n\tfmt.Println(\"Trabajando...soy un Robot\")\n}\n\nfunc AllWorking(w workingVirtual) {\n\tw.working()\n}\n\nfunc AllMeeting(w meetingVirtual) {\n\tw.meeting()\n}\n\nfunc AllEating(w eatingVirtual) {\n\tw.eating()\n}\n\nfunc Orquester1(o interface{}) {\n\tw, ok := o.(workingVirtual)\n\tif ok {\n\t\tAllWorking(w)\n\t}\n\n\tif w, ok := o.(meetingVirtual); ok {\n\t\tAllMeeting(w)\n\t}\n\n\tif w, ok := o.(eatingVirtual); ok {\n\t\tAllEating(w)\n\t}\n}\n\n// * DIFICULTAD EXTRA (opcional):\n//  * Crea un gestor de impresoras.\n//  * Requisitos:\n//  * 1. Algunas impresoras sólo imprimen en blanco y negro.\n//  * 2. Otras sólo a color.\n//  * 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n//  * Instrucciones:\n//  * 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n//  * 2. Aplica el ISP a la implementación.\n//  * 3. Desarrolla un código que compruebe que se cumple el principio.\n\ntype impresionBN interface {\n\tPrintBn()\n}\ntype impresionColor interface {\n\tPrintColor()\n}\ntype scanner interface {\n\tScaner()\n}\ntype fax interface {\n\tFax()\n}\n\ntype epsonBN struct{}\n\nfunc (e *epsonBN) PrintBn() {\n\tfmt.Println(\"Soy Epson que imprime solo en Blanco y Negro\")\n}\n\ntype hPcolor struct{}\n\nfunc (e *hPcolor) PrintColor() {\n\tfmt.Println(\"Soy HP que imprime En color\")\n}\n\ntype multiFunction struct{}\n\nfunc (m *multiFunction) PrintBn() {\n\tfmt.Println(\"Soy Multi funcion que ahora imprime en Blanco y Negro \")\n}\n\nfunc (m *multiFunction) PrintColor() {\n\tfmt.Println(\"Soy Multi funcion que ahora imprime a Color \")\n}\n\nfunc (m *multiFunction) Scaner() {\n\tfmt.Println(\"Soy Multi funcion que ahora Scanea  \")\n}\n\nfunc (m *multiFunction) Fax() {\n\tfmt.Println(\"Soy Multi funcion que ahora envia Fax  \")\n}\n\nfunc ExecutePrintBN(bn impresionBN) {\n\tbn.PrintBn()\n}\n\nfunc ExecutePrintColor(pc impresionColor) {\n\tpc.PrintColor()\n}\n\nfunc ExecuteScanner(s scanner) {\n\ts.Scaner()\n}\n\nfunc ExecuteFaxer(f fax) {\n\tf.Fax()\n}\n\n// func ExtraOrquester(o interface{}, action int) {\n\n// \tif bn, ok := o.(impresionBN); ok {\n\n// \t\tPrintBN(bn)\n// \t}\n\n// \tif cl, ok := o.(impresionColor); ok {\n// \t\tPrintColor(cl)\n// \t}\n\n// \tif action == 1 {\n// \t\tif pnt, ok := o.(impresionBN); ok {\n// \t\t\tPrintBN(pnt)\n// \t\t}\n// \t}\n\n// \tif action == 2 {\n// \t\tif c, ok := o.(impresionColor); ok {\n// \t\t\tPrintColor(c)\n// \t\t}\n// \t}\n\n// \tif action == 3 {\n// \t\tif scan, ok := o.(scanner); ok {\n// \t\t\tScanner(scan)\n// \t\t}\n// \t}\n\n// \tif action == 4 {\n// \t\tif fax, ok := o.(fax); ok {\n// \t\t\tFaxer(fax)\n// \t\t}\n// \t}\n\nfunc main() {\n\tfmt.Println(\"ISP Solid\")\n\n\tfmt.Println(\"Mal Disenno\")\n\n\tow := &OfficeWorker{}\n\trw := &RemoteWorker{}\n\trf := &RobotFabric{}\n\tOrquester(ow)\n\tOrquester(rw)\n\tOrquester(rf)\n\n\tfmt.Println(\"Buen Disenno\")\n\n\two := &WorkerOficce{}\n\twr := &WorkerRemote{}\n\tfr := &WorkerRobot{}\n\tOrquester1(wo)\n\tOrquester1(wr)\n\tOrquester1(fr)\n\n\tfmt.Println(\"Extra\")\n\n\tepson := &epsonBN{}\n\thp := &hPcolor{}\n\tmf := &multiFunction{}\n\n\tExecutePrintBN(epson)\n\tExecuteScanner(mf)\n\tExecuteFaxer(mf)\n\tExecutePrintBN(mf)\n\tExecutePrintColor(hp)\n\tExecutePrintColor(mf)\n\n}\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/java/AmadorQuispe.java",
    "content": "package com.amsoft.roadmap.example29;\n\nimport javax.naming.OperationNotSupportedException;\n\n/**\n * ISP: Este principio establece que los clientes no deberían estar obligados a depender de interfaces que no usan\n *\n * */\npublic class Example29 {\n    public static void main(String[] args) {\n        NotifiableEmail emailNotification = new EmailNotification();\n        emailNotification.sendEmail(\"hello\");\n        /*EXTRA*/\n        Printer printer = new Printer();\n        ColorPrinter colorPrinter = new ColorPrinter();\n        MultiFunctionalPrinter multiFunctionalPrinter = new MultiFunctionalPrinter();\n\n        printer.print();\n        colorPrinter.colorPrint();\n        multiFunctionalPrinter.colorPrint();\n        multiFunctionalPrinter.scan();\n        multiFunctionalPrinter.sendFax();\n    }\n}\n\n/*Viola ISP*/\ninterface Notifiable {\n    void sendEmail(String message);\n    void sendSMS(String message);\n}\n\n/*\n* Supongamos que solo quiero implementar el envio de notificación por email\n* */\nclass EmailNotificationBad implements Notifiable {\n\n    @Override\n    public void sendEmail(String message) {\n        System.out.println(\"Notification sending email: \" + message);\n    }\n\n    @Override\n    public void sendSMS(String message)  {\n        // No necesito implementar pero me obliga y debe lanzar un error\n        throw new RuntimeException(\"Not support\");\n    }\n}\n\n/*\n* Para solucionar separamos la interfaz\n*\n* */\n\ninterface NotifiableEmail  {\n    void sendEmail(String message);\n}\n\ninterface NotifiableSMS  {\n    void sendSMS(String message);\n}\n\n/*Ahora ya no estoy obligado a implementar todo*/\n\nclass EmailNotification implements NotifiableEmail{\n\n    @Override\n    public void sendEmail(String message) {\n        System.out.println(\"Notification sending email: \" + message);\n    }\n}\n\n\n/*EXTRA*/\ninterface Printable {\n    void print();\n}\n\ninterface ColorPrintable {\n    void colorPrint();\n}\n\ninterface Scannable {\n    void scan();\n}\n\ninterface Faxable {\n    void sendFax();\n}\n\nclass Printer implements Printable {\n\n    @Override\n    public void print() {\n        System.out.println(\"print monochromatic\");\n    }\n}\n\nclass ColorPrinter implements ColorPrintable {\n\n    @Override\n    public void colorPrint() {\n        System.out.println(\"print multi color\");\n    }\n}\n\nclass MultiFunctionalPrinter implements ColorPrintable, Scannable, Faxable {\n\n    @Override\n    public void colorPrint() {\n        System.out.println(\"print multi color\");\n    }\n\n    @Override\n    public void scan() {\n        System.out.println(\"use scan function\");\n    }\n\n    @Override\n    public void sendFax() {\n        System.out.println(\"sending fax\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/java/AnaLauDB.java",
    "content": "public class AnaLauDB {\n\n    // ==========================================================================\n    // IMPLEMENTACIÓN QUE CUMPLE EL PRINCIPIO DE SEGREGACIÓN DE INTERFACES (ISP)\n    // ==========================================================================\n\n    // 1. INTERFACES ESPECÍFICAS (SEGREGADAS)\n    // ==========================================================================\n\n    // Interfaz para funcionalidad de impresión básica\n    interface Imprimible {\n        void imprimir(String documento);\n    }\n\n    // Interfaz para funcionalidad de impresión en color\n    interface ImprimibleColor {\n        void imprimirColor(String documento);\n    }\n\n    // Interfaz para funcionalidad de escaneado\n    interface Escaneable {\n        String escanear();\n    }\n\n    // Interfaz para funcionalidad de fax\n    interface EnviadorFax {\n        void enviarFax(String numero, String documento);\n    }\n\n    // ==========================================================================\n    // 2. IMPLEMENTACIONES DE DIFERENTES TIPOS DE IMPRESORAS\n    // ==========================================================================\n\n    // Impresora que solo imprime en blanco y negro\n    static class ImpresoraBlancoNegro implements Imprimible {\n        private String modelo;\n\n        public ImpresoraBlancoNegro(String modelo) {\n            this.modelo = modelo;\n        }\n\n        @Override\n        public void imprimir(String documento) {\n            System.out.println(\"[\" + modelo + \"] Imprimiendo en blanco y negro: \" + documento);\n            // Simular tiempo de impresión\n            try {\n                Thread.sleep(500);\n            } catch (InterruptedException e) {\n                Thread.currentThread().interrupt();\n            }\n            System.out.println(\"[\" + modelo + \"] Documento impreso en B&N.\");\n        }\n\n        public String getModelo() {\n            return modelo;\n        }\n    }\n\n    // Impresora que solo imprime a color\n    static class ImpresoraColor implements ImprimibleColor {\n        private String modelo;\n\n        public ImpresoraColor(String modelo) {\n            this.modelo = modelo;\n        }\n\n        @Override\n        public void imprimirColor(String documento) {\n            System.out.println(\"[\" + modelo + \"] Imprimiendo a todo color: \" + documento);\n            // Simular tiempo de impresión (más lento por el color)\n            try {\n                Thread.sleep(1000);\n            } catch (InterruptedException e) {\n                Thread.currentThread().interrupt();\n            }\n            System.out.println(\"[\" + modelo + \"] Documento impreso a color.\");\n        }\n\n        public String getModelo() {\n            return modelo;\n        }\n    }\n\n    // Impresora multifunción completa\n    static class ImpresoraMultifuncion implements Imprimible, ImprimibleColor, Escaneable, EnviadorFax {\n        private String modelo;\n\n        public ImpresoraMultifuncion(String modelo) {\n            this.modelo = modelo;\n        }\n\n        @Override\n        public void imprimir(String documento) {\n            System.out.println(\"[\" + modelo + \"] Imprimiendo en blanco y negro: \" + documento);\n            try {\n                Thread.sleep(400);\n            } catch (InterruptedException e) {\n                Thread.currentThread().interrupt();\n            }\n            System.out.println(\"[\" + modelo + \"] Documento impreso en B&N.\");\n        }\n\n        @Override\n        public void imprimirColor(String documento) {\n            System.out.println(\"[\" + modelo + \"] Imprimiendo a todo color: \" + documento);\n            try {\n                Thread.sleep(800);\n            } catch (InterruptedException e) {\n                Thread.currentThread().interrupt();\n            }\n            System.out.println(\"[\" + modelo + \"] Documento impreso a color.\");\n        }\n\n        @Override\n        public String escanear() {\n            System.out.println(\"[\" + modelo + \"] Escaneando documento...\");\n            try {\n                Thread.sleep(600);\n            } catch (InterruptedException e) {\n                Thread.currentThread().interrupt();\n            }\n            String documentoEscaneado = \"documento_escaneado_\" + System.currentTimeMillis() + \".pdf\";\n            System.out.println(\"[\" + modelo + \"] Documento escaneado: \" + documentoEscaneado);\n            return documentoEscaneado;\n        }\n\n        @Override\n        public void enviarFax(String numero, String documento) {\n            System.out.println(\"[\" + modelo + \"] Enviando fax a \" + numero + \": \" + documento);\n            try {\n                Thread.sleep(2000);\n            } catch (InterruptedException e) {\n                Thread.currentThread().interrupt();\n            }\n            System.out.println(\"[\" + modelo + \"] Fax enviado exitosamente a \" + numero);\n        }\n\n        public String getModelo() {\n            return modelo;\n        }\n    }\n\n    // Impresora básica con escáner (sin fax ni color)\n    static class ImpresoraConEscaner implements Imprimible, Escaneable {\n        private String modelo;\n\n        public ImpresoraConEscaner(String modelo) {\n            this.modelo = modelo;\n        }\n\n        @Override\n        public void imprimir(String documento) {\n            System.out.println(\"[\" + modelo + \"] Imprimiendo en blanco y negro: \" + documento);\n            try {\n                Thread.sleep(450);\n            } catch (InterruptedException e) {\n                Thread.currentThread().interrupt();\n            }\n            System.out.println(\"[\" + modelo + \"] Documento impreso en B&N.\");\n        }\n\n        @Override\n        public String escanear() {\n            System.out.println(\"[\" + modelo + \"] Escaneando documento...\");\n            try {\n                Thread.sleep(550);\n            } catch (InterruptedException e) {\n                Thread.currentThread().interrupt();\n            }\n            String documentoEscaneado = \"scan_\" + System.currentTimeMillis() + \".pdf\";\n            System.out.println(\"[\" + modelo + \"] Documento escaneado: \" + documentoEscaneado);\n            return documentoEscaneado;\n        }\n\n        public String getModelo() {\n            return modelo;\n        }\n    }\n\n    // ==========================================================================\n    // 3. GESTOR DE IMPRESORAS\n    // ==========================================================================\n\n    static class GestorImpresoras {\n\n        // Método para manejar impresión básica\n        public static void realizarImpresion(Imprimible impresora, String documento) {\n            System.out.println(\"\\nIniciando impresión básica...\");\n            impresora.imprimir(documento);\n        }\n\n        // Método para manejar impresión a color\n        public static void realizarImpresionColor(ImprimibleColor impresora, String documento) {\n            System.out.println(\"\\nIniciando impresión a color...\");\n            impresora.imprimirColor(documento);\n        }\n\n        // Método para manejar escaneado\n        public static String realizarEscaneo(Escaneable escaner) {\n            System.out.println(\"\\nIniciando escaneado...\");\n            return escaner.escanear();\n        }\n\n        // Método para enviar fax\n        public static void enviarFax(EnviadorFax fax, String numero, String documento) {\n            System.out.println(\"\\nIniciando envío de fax...\");\n            fax.enviarFax(numero, documento);\n        }\n\n        // Método que demuestra el polimorfismo respetando ISP\n        public static void procesamientoAvanzado(Object impresora, String documento) {\n            System.out.println(\"\\nProcesamiento automático según capacidades...\");\n\n            // Solo usar las interfaces que la impresora implementa\n            if (impresora instanceof Imprimible) {\n                ((Imprimible) impresora).imprimir(documento);\n            }\n\n            if (impresora instanceof ImprimibleColor) {\n                ((ImprimibleColor) impresora).imprimirColor(documento + \"_color\");\n            }\n\n            if (impresora instanceof Escaneable) {\n                String archivoEscaneado = ((Escaneable) impresora).escanear();\n                System.out.println(\"Archivo generado: \" + archivoEscaneado);\n            }\n\n            if (impresora instanceof EnviadorFax) {\n                ((EnviadorFax) impresora).enviarFax(\"555-1234\", documento);\n            }\n        }\n    }\n\n    // ==========================================================================\n    // 4. CÓDIGO DE VERIFICACIÓN DEL ISP\n    // ==========================================================================\n\n    public static void main(String[] args) {\n        System.out.println(\"=== DEMOSTRACIÓN DEL PRINCIPIO DE SEGREGACIÓN DE INTERFACES (ISP) ===\");\n\n        // Crear diferentes tipos de impresoras\n        ImpresoraBlancoNegro impresoraBN = new ImpresoraBlancoNegro(\"HP LaserJet Pro\");\n        ImpresoraColor impresoraColor = new ImpresoraColor(\"Canon PIXMA\");\n        ImpresoraMultifuncion multifuncion = new ImpresoraMultifuncion(\"Epson WorkForce Pro\");\n        ImpresoraConEscaner impresoraEscaner = new ImpresoraConEscaner(\"Brother DCP-L2550\");\n\n        System.out.println(\"\\n1. VERIFICANDO CUMPLIMIENTO DEL ISP:\");\n        System.out.println(\"ImpresoraBlancoNegro solo implementa Imprimible\");\n        System.out.println(\"ImpresoraColor solo implementa ImprimibleColor\");\n        System.out.println(\"ImpresoraMultifuncion implementa todas las interfaces necesarias\");\n        System.out.println(\"ImpresoraConEscaner implementa Imprimible y Escaneable\");\n        System.out.println(\"Ninguna clase implementa métodos que no necesita\");\n\n        // 2. Probar funcionalidades específicas\n        System.out.println(\"\\n2. PROBANDO FUNCIONALIDADES ESPECÍFICAS:\");\n\n        // Impresora B&N - solo puede imprimir\n        GestorImpresoras.realizarImpresion(impresoraBN, \"Informe_Anual.pdf\");\n\n        // Impresora Color - solo puede imprimir a color\n        GestorImpresoras.realizarImpresionColor(impresoraColor, \"Presentacion_Marketing.pdf\");\n\n        // Multifunción - puede hacer todo\n        GestorImpresoras.realizarImpresion(multifuncion, \"Documento_Oficial.pdf\");\n        GestorImpresoras.realizarImpresionColor(multifuncion, \"Folleto_Promocional.pdf\");\n        String archivoEscaneado = GestorImpresoras.realizarEscaneo(multifuncion);\n        GestorImpresoras.enviarFax(multifuncion, \"555-9876\", \"Contrato.pdf\");\n\n        // Impresora con escáner - puede imprimir y escanear\n        GestorImpresoras.realizarImpresion(impresoraEscaner, \"Manual_Usuario.pdf\");\n        GestorImpresoras.realizarEscaneo(impresoraEscaner);\n\n        // 3. Demostrar procesamiento polimórfico respetando ISP\n        System.out.println(\"\\n3. PROCESAMIENTO POLIMÓRFICO CON ISP:\");\n\n        Object[] impresoras = { impresoraBN, impresoraColor, multifuncion, impresoraEscaner };\n\n        for (Object imp : impresoras) {\n            System.out.println(\"\\n--- Procesando: \" + imp.getClass().getSimpleName() + \" ---\");\n            GestorImpresoras.procesamientoAvanzado(imp, \"TestDocument\");\n        }\n\n        // 4. Verificar que ISP previene violaciones\n        System.out.println(\"\\n4. VERIFICACIÓN FINAL DEL ISP:\");\n\n        // Intentar usar solo las capacidades que cada impresora tiene\n        System.out.println(\"\\nVerificando que cada impresora solo expone métodos relevantes:\");\n\n        // Esta impresora NO puede hacer color, escanear o enviar fax\n        if (!(impresoraBN instanceof ImprimibleColor)) {\n            System.out.println(\"ImpresoraBN correctamente NO implementa ImprimibleColor\");\n        }\n\n        if (!(impresoraBN instanceof Escaneable)) {\n            System.out.println(\"ImpresoraBN correctamente NO implementa Escaneable\");\n        }\n\n        if (!(impresoraBN instanceof EnviadorFax)) {\n            System.out.println(\"ImpresoraBN correctamente NO implementa EnviadorFax\");\n        }\n\n        // Esta impresora NO puede hacer B&N, escanear o enviar fax\n        if (!(impresoraColor instanceof Imprimible)) {\n            System.out.println(\"ImpresoraColor correctamente NO implementa Imprimible básico\");\n        }\n\n        // Verificar que multifunción SÍ tiene todas las capacidades\n        if (multifuncion instanceof Imprimible &&\n                multifuncion instanceof ImprimibleColor &&\n                multifuncion instanceof Escaneable &&\n                multifuncion instanceof EnviadorFax) {\n            System.out.println(\"Multifunción correctamente implementa todas las interfaces\");\n        }\n\n        System.out.println(\"\\nCONCLUSIÓN ISP:\");\n        System.out.println(\"- Cada interfaz es pequeña y específica\");\n        System.out.println(\"- Las clases solo implementan las interfaces que necesitan\");\n        System.out.println(\"- No hay métodos forzados o innecesarios\");\n        System.out.println(\"- El sistema es flexible y extensible\");\n        System.out.println(\"- Los clientes no dependen de funcionalidades que no usan\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/java/JesusWay69.java",
    "content": "package ejercicio29;\n\n\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Segregación de Interfaces\n * (Interface Segregation Principle, ISP)\", y crea un ejemplo\n * simple donde se muestre su funcionamiento de forma correcta e incorrecta.\n */\npublic class JesusWay69 {\n\n    public static void main(String[] args) {\n        OstrichISP ostrich = new OstrichISP();\n        SwiftISP swift = new SwiftISP();\n        PenguinISP penguin = new PenguinISP();\n        testBirds(ostrich);\n        testBirds(swift);\n        testBirds(penguin);\n        BwPrinter hpBlackAndWhite = new BwPrinter();\n        ColorPrinter xeroxColor = new ColorPrinter();\n        MultiPrinter epsonMulti = new MultiPrinter();\n        Scanner canonScan = new Scanner();\n        testPrinter(hpBlackAndWhite);\n        testPrinter(epsonMulti);\n        testPrinter(canonScan);\n        testPrinter(xeroxColor);\n\n    }\n\n    public static void testBirds(Object object) {\n        String name = \"\";\n        boolean feathers = false;\n        boolean fly = false;\n        boolean swim = false;\n        boolean run = false;\n\n        if (object instanceof OstrichISP) {\n            feathers = ((OstrichISP) object).haveFeathersISP();\n            name = ((OstrichISP) object).birdName();\n            run = ((OstrichISP) object).run();\n        } else if (object instanceof SwiftISP) {\n            feathers = ((SwiftISP) object).haveFeathersISP();\n            name = ((SwiftISP) object).birdName();\n            fly = ((SwiftISP) object).fliesISP();\n        } else if (object instanceof PenguinISP) {\n            feathers = ((PenguinISP) object).haveFeathersISP();\n            name = ((PenguinISP) object).birdName();\n            swim = ((PenguinISP) object).swimsISP();\n        }\n        System.out.println(\"\\nEspecie de ave: \" + name\n                + \"\\n¿tiene plumas?: \" + feathers\n                + \"\\n¿Puede volar?: \" + fly\n                + \"\\n¿Puede correr?: \" + run\n                + \"\\n¿Puede nadar?: \" + swim);\n\n    }\n\n    public static void testPrinter(Object printer) {\n        boolean canPrint = false;\n        String device = \"\";\n        boolean bw = false;\n        boolean color = false;\n        boolean scan = false;\n        boolean fax = false;\n\n        if (printer instanceof BwPrinter) {\n            canPrint = ((BwPrinter) printer).printer();\n            device = ((BwPrinter) printer).printerModel();\n            bw = ((BwPrinter) printer).printBW();\n        } else if (printer instanceof ColorPrinter) {\n            canPrint = ((ColorPrinter) printer).printer();\n            device = ((ColorPrinter) printer).printerModel();\n            color = ((ColorPrinter) printer).printColor();\n        } else if (printer instanceof MultiPrinter) {\n            canPrint = ((MultiPrinter) printer).printer();\n            device = ((MultiPrinter) printer).printerModel();\n            bw = ((MultiPrinter) printer).printBW();\n            color = ((MultiPrinter) printer).printColor();\n            scan = ((MultiPrinter) printer).scanner();\n            fax = ((MultiPrinter) printer).fax();\n        } else if (printer instanceof Scanner) {\n            device = ((Scanner) printer).printerModel();\n            scan = ((Scanner) printer).scanner();\n        }\n        System.out.println(\"\\nTipo de dispositivo: \" + device\n                + \"\\n¿puede imprimir?: \" + canPrint\n                + \"\\n¿Imprime en blanco y negro?: \" + bw\n                + \"\\n¿Imprime en color?: \" + color\n                + \"\\n¿Escanea Documentos?: \" + scan\n                + \"\\n¿Puede enviar/recibir fax?: \" + fax);\n    }\n\n}\n\n/*\nEl siguiente código no cumple el principio de segregación de interfaces ya que sólo hay una interface que modela el contenido\nde las diferentes clases de aves con todas las características de las cuales solo la primera (tiene plumas)\nes común a todas las aves pero no las demás que aun así es obligatorio declarar sus métodos en todas las clases\nademás la constante que debemos devolver en cada método está seteada en true con lo cual en los métodos cuya\ncaracterística no cumpla el ave debemos forzar la salida retornando false.\n */\ninterface Bird {\n\n    boolean haveFeathers();\n\n    boolean flies();\n\n    boolean swims();\n\n    boolean run();\n\n    final boolean CHARACTERISTIC = true;\n}\n\nclass Ostrich implements Bird {\n\n    @Override\n    public boolean haveFeathers() {\n        return CHARACTERISTIC;\n    }\n\n    @Override\n    public boolean flies() {\n        return false;\n    }\n\n    @Override\n    public boolean swims() {\n        return false;\n    }\n\n    @Override\n    public boolean run() {\n        return CHARACTERISTIC;\n    }\n\n}\n\nclass swift implements Bird {\n\n    @Override\n    public boolean haveFeathers() {\n        return CHARACTERISTIC;\n    }\n\n    @Override\n    public boolean flies() {\n        return CHARACTERISTIC;\n    }\n\n    @Override\n    public boolean swims() {\n        return false;\n    }\n\n    @Override\n    public boolean run() {\n        return false;\n\n    }\n}\n\nclass Penguin implements Bird {\n\n    @Override\n    public boolean haveFeathers() {\n        return CHARACTERISTIC;\n    }\n\n    @Override\n    public boolean flies() {\n        return false;\n    }\n\n    @Override\n    public boolean swims() {\n        return CHARACTERISTIC;\n    }\n\n    @Override\n    public boolean run() {\n        return true;\n    }\n}\n\n/*\nEn el siguiente código aplicamos el principio de segregación de interfaces dividiendo en diferentes interfaces\nlos métodos que devuelven la característica verdadera, en el primero declaramos el método \"tiene plumas\" común\na todas las aves y el método que devuelve el nombre del ave así como la constante general de característica\nseteado en true, después creamos una interface por cada característica para declarar dentro su método de característica \nque no es común a todas las aves, volar, correr y nadar, luego creamos las clases que modelen cada especie de ave heredando\nen cada una de ellas las interfaces que se correspondan con sus características particulares (Java no permite la \nherencia múltiple de superclases ni clases abstractas pero sí permite heredar de varias interfaces), despues dentro\nde la clase principal del fichero creamos un método que reciba un objeto, seteamos todas las características en false\ny mediante condicionales aplicamos para cada tipo de objeto/ave sus correspondientes características que sean verdaderas,\ncreamos una salida que muestre todas las características y en cada ave mostrará true si esa característica está en el\nmodelado de su objeto o false, que es el valor por defecto que declaramos si no cumple dicha característica.\n */\ninterface BirdISP {\n\n    boolean haveFeathersISP();\n\n    String birdName();\n    final boolean CHARACTERISTICISP = true;\n\n}\n\ninterface FlyingBirdISP {\n\n    boolean fliesISP();\n}\n\ninterface SwimmingBirdISP {\n\n    boolean swimsISP();\n}\n\ninterface RunnerBirdISP {\n\n    boolean run();\n}\n\nclass OstrichISP implements BirdISP, RunnerBirdISP {\n\n    @Override\n    public boolean run() {\n        return CHARACTERISTICISP;\n    }\n\n    @Override\n    public boolean haveFeathersISP() {\n        return CHARACTERISTICISP;\n    }\n\n    @Override\n    public String birdName() {\n        return \"Avestruz\";\n    }\n\n}\n\nclass PenguinISP implements BirdISP, SwimmingBirdISP, RunnerBirdISP {\n\n    @Override\n    public boolean haveFeathersISP() {\n        return CHARACTERISTICISP;\n    }\n\n    @Override\n    public boolean swimsISP() {\n        return CHARACTERISTICISP;\n    }\n\n    @Override\n    public boolean run() {\n        return CHARACTERISTICISP;\n    }\n\n    @Override\n    public String birdName() {\n        return \"Pingüino\";\n    }\n\n}\n\nclass SwiftISP implements BirdISP, FlyingBirdISP {\n\n    @Override\n    public boolean haveFeathersISP() {\n        return CHARACTERISTICISP;\n    }\n\n    @Override\n    public boolean fliesISP() {\n        return CHARACTERISTICISP;\n    }\n\n    @Override\n    public String birdName() {\n        return \"Vencejo\";\n    }\n\n}\n\n/*\n * DIFICULTAD EXTRA (opcional):\n * Crea un gestor de impresoras.\n * Requisitos:\n * 1. Algunas impresoras sólo imprimen en blanco y negro.\n * 2. Otras sólo a color.\n * 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n *  Instrucciones:\n * 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n * 2. Aplica el ISP a la implementación.\n * 3. Desarrolla un código que compruebe que se cumple el principio.\n */\ninterface Printer {\n\n    boolean printer();\n\n    String printerModel();\n    final boolean FEATUREPRINTER = true;\n}\n\ninterface BlackAndWhite {\n\n    boolean printBW();\n}\n\ninterface Color {\n\n    boolean printColor();\n}\n\ninterface Scan {\n\n    boolean scanner();\n}\n\ninterface Fax {\n\n    boolean fax();\n}\n\nclass BwPrinter implements Printer, BlackAndWhite {\n\n    @Override\n    public boolean printer() {\n        return FEATUREPRINTER;\n    }\n\n    @Override\n    public String printerModel() {\n        return \"Impresora en blanco y negro\";\n    }\n\n    @Override\n    public boolean printBW() {\n        return FEATUREPRINTER;\n    }\n\n}\n\nclass ColorPrinter implements Printer, Color {\n\n    @Override\n    public boolean printer() {\n        return FEATUREPRINTER;\n    }\n\n    @Override\n    public String printerModel() {\n        return \"Impresora a color\";\n    }\n\n    @Override\n    public boolean printColor() {\n        return FEATUREPRINTER;\n    }\n\n}\n\nclass MultiPrinter implements Printer, Color, Scan, Fax, BlackAndWhite {\n\n    @Override\n    public boolean printer() {\n        return FEATUREPRINTER;\n    }\n\n    @Override\n    public String printerModel() {\n        return \"Dispositivo multifunción\";\n    }\n\n    @Override\n    public boolean printColor() {\n        return FEATUREPRINTER;\n    }\n\n    @Override\n    public boolean scanner() {\n        return FEATUREPRINTER;\n    }\n\n    @Override\n    public boolean fax() {\n        return FEATUREPRINTER;\n    }\n\n    @Override\n    public boolean printBW() {\n        return FEATUREPRINTER;\n    }\n\n}\n\nclass Scanner implements Printer, Scan {\n\n    @Override\n    public boolean printer() {\n        return FEATUREPRINTER;\n    }\n\n    @Override\n    public String printerModel() {\n        return \"Dispositivo exclusivo de escaneo\";\n    }\n\n    @Override\n    public boolean scanner() {\n        return FEATUREPRINTER;\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/java/Josegs95.java",
    "content": "public class Josegs95 {\n    public static void main(String[] args) {\n        //Ejercicio\n        //Forma incorrecta\n        WrongPigeon pidgeon1 = new WrongPigeon();\n        WrongHuman human1 = new WrongHuman();\n\n        pidgeon1.walk();\n        pidgeon1.fly();\n        human1.walk();\n        human1.fly();\n\n        //Forma correcta\n        Pigeon pigeon2 = new Pigeon();\n        Human human2 = new Human();\n\n        pigeon2.fly();\n        pigeon2.walk();\n        human2.walk();\n\n        //Reto\n        new Josegs95().retoFinal();\n    }\n\n    public void retoFinal(){\n        OldPrinter printer1 = new OldPrinter();\n        MediumPrinter printer2 = new MediumPrinter();\n        ModernPrinter printer3 = new ModernPrinter();\n\n        printer1.print(\"Texto ejemplo\");\n        printer2.print(\"Texto ejemplo\");\n        printer3.print(\"Texto ejemplo\");\n\n        System.out.println(printer3.scan());\n        printer3.fax(\"Texto por fax\");\n    }\n\n    //Forma incorrecta\n    public interface WrongAnimal{\n        public void walk();\n        public void fly();\n    }\n    public static class WrongPigeon implements WrongAnimal{\n\n        @Override\n        public void walk() {\n            System.out.println(\"La paloma camina...\");\n        }\n\n        @Override\n        public void fly() {\n            System.out.println(\"La paloma vuela...\");\n        }\n    }\n    public static class WrongHuman implements WrongAnimal{\n\n        @Override\n        public void walk() {\n            System.out.println(\"El humano camina...\");\n        }\n\n        @Override\n        public void fly() {} //Los humanos no vuelan\n    }\n    //Forma correcta\n    public interface WalkableAnimal{\n        public void walk();\n    }\n    public interface FlyingAnimal {\n        public void fly();\n    }\n    public static class Pigeon implements WalkableAnimal, FlyingAnimal {\n\n        @Override\n        public void walk() {\n            System.out.println(\"La paloma camina...\");\n        }\n\n        @Override\n        public void fly() {\n            System.out.println(\"La paloma vuela...\");\n        }\n    }\n    public static class Human implements WalkableAnimal{\n\n        @Override\n        public void walk() {\n            System.out.println(\"El humano camina...\");\n        }\n    }\n    //Reto\n    public abstract class Printer{\n        public void print(String text){\n            System.out.println(text);\n        }\n    }\n    public interface BWPrinter{\n        public void printBW(String text);\n    }\n    public interface ColorPrinter{\n        public void printColor(String text);\n    }\n    public interface MultiFunctionPrinter{\n        public String scan();\n        public void fax(String text);\n    }\n    public class OldPrinter extends Printer implements BWPrinter{\n\n        @Override\n        public void printBW(String text) {\n            super.print(\"\\\"\" + text + \"\\\" en blanco y negro\");\n        }\n\n        @Override\n        public void print(String text) {\n            printBW(text);\n        }\n    }\n    public class MediumPrinter extends Printer implements ColorPrinter{\n\n        @Override\n        public void printColor(String text) {\n            super.print(\"\\\"\" + text + \"\\\" a color\");\n        }\n\n        @Override\n        public void print(String text) {\n            printColor(text);\n        }\n    }\n    public class ModernPrinter extends Printer implements ColorPrinter, MultiFunctionPrinter{\n\n        @Override\n        public void printColor(String text) {\n            super.print(\"\\\"\" + text + \"\\\" a color\");\n        }\n\n        @Override\n        public String scan() {\n            return \"Texto escaneado\";\n        }\n\n        @Override\n        public void fax(String text) {\n            System.out.println(\"Texto enviado por fax con éxito\");\n        }\n\n        @Override\n        public void print(String text) {\n            printColor(text);\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/java/asjordi.java",
    "content": "/*\n    El Principio de Segregación de Interfaces (ISP) establece que las implementaciones de una interfaz\n    no deben depender de comportamientos que no usen. En otras palabras, una clase no debe implementar métodos que no necesita.\n    Por lo cual, es mejor tener muchas interfaces específicas que realicen 1 o 2 tareas que una interfaz general que realice muchas tareas.\n */\n\npublic class Main {\n\n    public static void main(String[] args) {\n        SimpleBlackAndWhitePrinter bwPrinter = new SimpleBlackAndWhitePrinter();\n        SimpleColorPrinter colorPrinter = new SimpleColorPrinter();\n        MultifunctionPrinter multifunctionPrinter = new MultifunctionPrinter();\n\n        bwPrinter.printBlackAndWhite();\n        colorPrinter.printColor();\n        multifunctionPrinter.printBlackAndWhite();\n        multifunctionPrinter.printColor();\n        multifunctionPrinter.scan();\n        multifunctionPrinter.fax();\n    }\n\n    /*\n        EJERCICIO:\n        Explora el \"Principio SOLID de Segregación de Interfaces (Interface Segregation Principle, ISP)\"\n        y crea un ejemplo simple donde se muestre su funcionamiento de forma correcta e incorrecta.\n     */\n\n    // Interfaz general que viola el ISP\n    public interface Worker {\n        void work();\n        void eat();\n    }\n\n    // Trabajador que solo trabaja\n    public static class RobotWorker implements Worker {\n        @Override\n        public void work() {\n            System.out.println(\"Trabajando...\");\n        }\n\n        @Override\n        public void eat() {\n            throw new UnsupportedOperationException(\"No puede comer\");\n        }\n    }\n\n    // Ejemplo Correcto (Aplicación del ISP)\n    // Interfaz específica para trabajar\n    public interface Workable {\n        void work();\n    }\n\n    // Interfaz específica para comer\n    public interface Eatable {\n        void eat();\n    }\n\n    // Trabajador que solo trabaja\n    public static class RobotWorker2 implements Workable {\n        @Override\n        public void work() {\n            System.out.println(\"Trabajando...\");\n        }\n    }\n\n    // Trabajador humano que trabaja y come\n    public static class HumanWorker implements Workable, Eatable {\n        @Override\n        public void work() {\n            System.out.println(\"Trabajando...\");\n        }\n\n        @Override\n        public void eat() {\n            System.out.println(\"Comiendo...\");\n        }\n    }\n\n    /*\n        DIFICULTAD EXTRA (opcional):\n        Crea un gestor de impresoras.\n        Requisitos:\n            1. Algunas impresoras sólo imprimen en blanco y negro.\n            2. Otras sólo a color.\n            3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n        Instrucciones:\n            1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n            2. Aplica el ISP a la implementación.\n            3. Desarrolla un código que compruebe que se cumple el principio.\n     */\n\n    interface BlackAndWhitePrinter {\n        void printBlackAndWhite();\n    }\n\n    interface ColorPrinter {\n        void printColor();\n    }\n\n    interface Scanner {\n        void scan();\n    }\n\n    interface Fax {\n        void fax();\n    }\n\n    static class SimpleBlackAndWhitePrinter implements BlackAndWhitePrinter {\n        @Override\n        public void printBlackAndWhite() {\n            System.out.println(\"Printing in black and white...\");\n        }\n    }\n\n    static class SimpleColorPrinter implements ColorPrinter {\n        @Override\n        public void printColor() {\n            System.out.println(\"Printing in color...\");\n        }\n    }\n\n    static class MultifunctionPrinter implements BlackAndWhitePrinter, ColorPrinter, Scanner, Fax {\n\n        @Override\n        public void printBlackAndWhite() {\n            System.out.println(\"Printing in black and white...\");\n        }\n\n        @Override\n        public void printColor() {\n            System.out.println(\"Printing in color...\");\n        }\n\n        @Override\n        public void fax() {\n            System.out.println(\"Sending fax...\");\n        }\n\n        @Override\n        public void scan() {\n            System.out.println(\"Scanning document...\");\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/java/danhingar.java",
    "content": "public class danhingar {\n\n    public static void main(String[] args) {\n        Machine machine = new Machine();\n        machine.eat();\n        Human human = new Human();\n        human.eat();\n\n        //CON ISP\n        Machine1 machine1 = new Machine1();\n        machine1.work();\n\n        Human1 human1 = new Human1();\n        human1.eat();\n        human1.work();\n\n        //Extra\n        Printer printer1 = new Printer();\n        printer1.print(\"doc.pdf\");\n\n        ColorPrinter printer2 = new ColorPrinter();\n        printer2.printColor(\"doc.pdf\");\n\n        MultifunctionPrinter printer3 = new MultifunctionPrinter();\n        printer3.print(\"doc.pdf\");\n        printer3.printColor(\"doc.pdf\");\n        printer3.scan(\"doc.pdf\");\n        printer3.sendFax(\"doc.pdf\");\n    }\n\n}\n\n// SIN ISP\ninterface WorkerInteface {\n\n    void work();\n\n    void eat();\n}\n\nclass Human implements WorkerInteface {\n\n    @Override\n    public void eat() {\n        System.out.println(\"Comiendo\");\n    }\n\n    @Override\n    public void work() {\n        System.out.println(\"Trabajando\");\n    }\n\n}\n\nclass Machine implements WorkerInteface {\n\n    @Override\n    public void eat() {\n    }\n\n    @Override\n    public void work() {\n        System.out.println(\"Trabajando\");\n    }\n\n}\n\n// CON ISP\n\ninterface WorkInterface {\n    void work();\n\n}\n\ninterface EatInterface {\n    void eat();\n\n}\n\n\nclass Human1 implements WorkInterface,EatInterface {\n\n    @Override\n    public void eat() {\n        System.out.println(\"Comiendo\");\n    }\n\n    @Override\n    public void work() {\n        System.out.println(\"Trabajando\");\n    }\n\n}\n\nclass Machine1 implements WorkInterface {\n\n    @Override\n    public void work() {\n        System.out.println(\"Trabajando\");\n    }\n\n}\n\n\n//EXTRA\ninterface PrinterInterface{\n    void print(String document);\n}\n\ninterface PrinterColorInterface {\n    void printColor(String document);\n}\n\ninterface ScannerInterface{\n    void scan(String document);\n}\n\ninterface FaxInterface{\n    void sendFax(String document);\n}\n\nclass Printer implements PrinterInterface{\n\n    @Override\n    public void print(String document) {\n        System.out.printf(\"Imprimiendo en blanco y negro el documento %s.\\n\",document);\n    }\n\n    \n}\n\nclass ColorPrinter implements PrinterColorInterface {\n\n    @Override\n    public void printColor(String document) {\n        System.out.printf(\"Imprimiendo a color el documento %s.\\n\",document);\n    }\n\n}\n\nclass MultifunctionPrinter implements PrinterInterface,PrinterColorInterface,ScannerInterface,FaxInterface {\n\n    @Override\n    public void sendFax(String document) {\n        System.out.printf(\"Enviado por fax el documento %s.\\n\",document);\n    }\n\n    @Override\n    public void scan(String document) {\n        System.out.printf(\"Escaneando el documento %s.\\n\",document);\n        System.out.printf(\"Documento %s escaneado.\\n\",document);\n    }\n\n    @Override\n    public void printColor(String document) {\n        System.out.printf(\"Imprimiendo a color el documento %s.\\n\",document);\n    }\n\n    @Override\n    public void print(String document) {\n        System.out.printf(\"Imprimiendo en blanco y negro el documento %s.\\n\",document);\n    }\n\n    \n}\n\n\n\n\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/java/martinbohorquez.java",
    "content": "/**\n * #29 SOLID: PRINCIPIO DE SEGREGACIÓN DE INTERFACES (ISP)\n *\n * @author martinbohorquez\n */\npublic class martinbohorquez {\n    public static void main(String[] args) {\n        incorrectISP();\n        correctISP();\n        /*\n         * DIFICULTAD EXTRA\n         */\n        testPrinter();\n\n    }\n\n    private static void incorrectISP() {\n        Worker humano = new Humano();\n        humano.work();\n        humano.eat();\n        Worker maquina = new Machine();\n        maquina.work();\n        maquina.eat();//incorrecto: no se implementa el método \"eat()\", pero se obliga a definir.\n    }\n\n    private static void correctISP() {\n        Human human = new Human();\n        human.work();\n        human.eat();\n        Robot robot = new Robot();\n        robot.work();\n//        robot.eat();//correcto: no se implementa ni existe el método \"eat()\" para Robot.\n    }\n\n    private static void testPrinter() {\n        Printer printer = new PrinterImpl();\n        String document = \"doc.pdf\";\n        printer.print(document);\n        ColorPrinter colorPrinter = new ColorPrinterImpl();\n        colorPrinter.printColor(document);\n        Multifunction multifunctionPrinter = new Multifunction();\n        multifunctionPrinter.print(document);\n        multifunctionPrinter.printColor(document);\n        multifunctionPrinter.scan(document);\n        multifunctionPrinter.sendFax(document);\n    }\n}\n\ninterface Worker {\n    void work();\n\n    void eat();\n}\n\nclass Humano implements Worker {\n    @Override\n    public void work() {\n        System.out.println(\"Trabajando!\");\n    }\n\n    @Override\n    public void eat() {\n        System.out.println(\"Comiendo!\");\n    }\n}\n\nclass Machine implements Worker {\n    @Override\n    public void work() {\n        System.out.println(\"Trabajando!\");\n    }\n\n    @Override\n    public void eat() {\n        // Robot no comen\n    }\n}\n\ninterface Work {\n    void work();\n}\n\ninterface Eat {\n    void eat();\n}\n\nclass Human implements Work, Eat {\n    @Override\n    public void work() {\n        System.out.println(\"Trabajando!\");\n    }\n\n    @Override\n    public void eat() {\n        System.out.println(\"Comiendo!\");\n    }\n}\n\nclass Robot implements Work {\n    @Override\n    public void work() {\n        System.out.println(\"Trabajando!\");\n    }\n}\n\ninterface Printer {\n    void print(String document);\n}\n\ninterface ColorPrinter {\n    void printColor(String document);\n}\n\ninterface Scanner {\n    String scan(String document);\n}\n\ninterface Fax {\n    void sendFax(String document);\n}\n\nclass PrinterImpl implements Printer {\n    @Override\n    public void print(String document) {\n        System.out.printf(\"Imprimiendo en blanco y negro el documento '%s'%n\", document);\n    }\n}\n\nclass ColorPrinterImpl implements ColorPrinter {\n    @Override\n    public void printColor(String document) {\n        System.out.printf(\"Imprimiendo a color el documento '%s'%n\", document);\n    }\n}\n\nclass Multifunction implements Printer, ColorPrinter, Scanner, Fax {\n\n    @Override\n    public void print(String document) {\n        System.out.printf(\"Imprimiendo en blanco y negro el documento '%s'%n\", document);\n    }\n\n    @Override\n    public void printColor(String document) {\n        System.out.printf(\"Imprimiendo a color el documento '%s'%n\", document);\n    }\n\n    @Override\n    public String scan(String document) {\n        System.out.printf(\"Escaneando el documento '%s'%n\", document);\n        return \"Documento \" + document + \" escaneado.\";\n    }\n\n    @Override\n    public void sendFax(String document) {\n        System.out.printf(\"Enviando por fax el documento '%s'%n\", document);\n    }\n}"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/java/simonguzman.java",
    "content": "public class simonguzman {\n    public static void main(String[] args) {\n        exampleNoIsp();\n        exampleIsp();\n        adittionalExerciseNoIsp();\n        adittionalExerciseIsp();\n    }\n\n    /******************************** Ejercicio adicional con isp ********************************/\n    static void adittionalExerciseIsp(){\n        Printer blackAndWhitePrinter = new BlackAndWhitePrinter();\n        blackAndWhitePrinter.print(\"Documento en blanco y negro\");\n\n        ColorPrinter colorPrinter = new ColorOnlyPrinter();\n        colorPrinter.printColor(\"Documento a color\");\n\n        MultiFunctionPrinter multiFunctionPrinter = new MultiFunctionPrinter();\n\n        multiFunctionPrinter.print(\"Documento multifunción en blanco y negro\");\n        multiFunctionPrinter.printColor(\"Documento multifunción a color\");\n        multiFunctionPrinter.scan(\"Escaneando un documento\");\n        multiFunctionPrinter.sendFax(\"Enviando fax del documento\");\n\n    }\n    static interface Printer {\n        void print(String content);\n    }\n    \n    static interface ColorPrinter {\n        void printColor(String content);\n    }\n    \n    static interface Scanner {\n        void scan(String content);\n    }\n    \n    static interface Fax {\n        void sendFax(String content);\n    }\n    \n    static class BlackAndWhitePrinter implements Printer {\n        @Override\n        public void print(String content) {\n            System.out.println(\"Imprimiendo en blanco y negro: \" + content);\n        }\n    }\n    \n    static class ColorOnlyPrinter implements ColorPrinter {\n        @Override\n        public void printColor(String content) {\n            System.out.println(\"Imprimiendo a color: \" + content);\n        }\n    }\n    \n    static class MultiFunctionPrinter implements Printer, ColorPrinter, Scanner, Fax {\n        @Override\n        public void print(String content) {\n            System.out.println(\"Imprimiendo en blanco y negro: \" + content);\n        }\n    \n        @Override\n        public void printColor(String content) {\n            System.out.println(\"Imprimiendo a color: \" + content);\n        }\n    \n        @Override\n        public void scan(String content) {\n            System.out.println(\"Escaneando: \" + content);\n        }\n    \n        @Override\n        public void sendFax(String content) {\n            System.out.println(\"Enviando fax: \" + content);\n        }\n    }\n    \n\n    /******************************** Ejercicio adicional sin isp ********************************/\n    static void adittionalExerciseNoIsp(){\n        UniversalPrinter basicPrinter = new BasicPrinter();\n\n        basicPrinter.print(\"Documento básico en blanco y negro\");\n        basicPrinter.printColor(\"Intentando imprimir a color (no soportado)\");\n        basicPrinter.scan(\"Intentando escanear (no soportado)\");\n        basicPrinter.sendFax(\"Intentando enviar fax (no soportado)\");\n    }\n\n    static interface UniversalPrinter {\n        void print(String content);\n        void printColor(String content);\n        void scan(String content);\n        void sendFax(String content);\n    }\n    \n    static class BasicPrinter implements UniversalPrinter {\n        @Override\n        public void print(String content) {\n            System.out.println(\"Imprimiendo en blanco y negro: \" + content);\n        }\n    \n        @Override\n        public void printColor(String content) {\n            // No soportado por esta impresora\n        }\n    \n        @Override\n        public void scan(String content) {\n            // No soportado por esta impresora\n        }\n    \n        @Override\n        public void sendFax(String content) {\n            // No soportado por esta impresora\n        }\n    }\n    \n\n    /******************************** Ejemplo con isp ********************************/\n    static void exampleIsp(){\n        Workable robotIsp = new RobotIsp();\n        robotIsp.work();\n\n        Employee employee = new Employee();\n        employee.work();\n        employee.eat();\n    }\n\n    static interface Workable {\n        void work();\n    }\n\n    static interface Eatable {\n        void eat();\n    }\n\n    static class RobotIsp implements Workable {\n        @Override\n        public void work() {\n            System.out.println(\"El robot está trabajando.\");\n        }\n    }\n\n    static class Employee implements Workable, Eatable {\n        @Override\n        public void work() {\n            System.out.println(\"El empleado está trabajando.\");\n        }\n\n        @Override\n        public void eat() {\n            System.out.println(\"El empleado está comiendo.\");\n        }\n    }\n    /******************************** Ejemplo sin isp ********************************/\n    static void exampleNoIsp(){\n        Worker robot = new Robot();\n        robot.work();  // Solo debería trabajar\n        robot.eat();\n    }\n\n    static interface Worker {\n        void work();\n        void eat();\n    }\n\n    static class Robot implements Worker {\n        @Override\n        public void work() {\n            System.out.println(\"El robot está trabajando.\");\n        }\n\n        @Override\n        public void eat() {\n            // No tiene sentido para un robot\n        }\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/javascript/Chrisdev00.js",
    "content": "/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Segregación de Interfaces (Interface Segregation Principle, ISP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un gestor de impresoras.\n * Requisitos:\n * 1. Algunas impresoras sólo imprimen en blanco y negro.\n * 2. Otras sólo a color.\n * 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n * Instrucciones:\n * 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n * 2. Aplica el ISP a la implementación.\n * 3. Desarrolla un código que compruebe que se cumple el principio.\n */\n\n// Forma incorrecta de aplicar el principio ISP\n\nclass Vehicle {\n    startEngine() {\n        throw new Error(\"Method 'startEngine()' must be implemented.\");\n    }  \n    stopEngine() {\n        throw new Error(\"Method 'stopEngine()' must be implemented.\");\n    }  \n    fly() {\n        throw new Error(\"Method 'fly()' must be implemented.\");\n    }  \n    drive() {\n        throw new Error(\"Method 'drive()' must be implemented.\");\n    }  \n    sail() {\n        throw new Error(\"Method 'sail()' must be implemented.\");\n    }\n}\n\nclass Car extends Vehicle{\n    startEngine() {\n        console.log('Car engine started');\n    }\n    \n    stopEngine() {\n        console.log('Car engine stopped');\n    }\n    \n    fly() {\n        throw new Error('Cars cannot fly');\n    }\n    \n    drive() {\n        console.log('Car is driving');\n    }\n    \n    sail() {\n        throw new Error('Cars cannot sail');\n    }\n}\n\nconst car1 = new Car();\ncar1.startEngine();\ncar1.fly();\n\n// Forma correcta de aplicar el principio ISP\n\nclass EnginePowered{\n    startEngine(){\n        throw new Error(\"Method 'startEngine()' must be implemented.\");\n    }\n    stopEngine(){\n        throw new Error(\"Method 'stopEngine()' must be implemented.\");\n    }\n}\nclass Drivable{\n    drive(){\n        throw new Error(\"Method 'drive()' must be implemented.\");\n    }\n}\nclass Flyable{\n    fly(){\n        throw new Error(\"Method 'fly()' must be implemented.\");\n    }\n}\nclass Sailable{\n    sail(){\n        throw new Error(\"Method 'sail()' must be implemented.\");\n    }\n}\n\n\nclass CarEngine extends EnginePowered{\n    startEngine() {\n        console.log('Car engine started');\n    }    \n    stopEngine() {\n        console.log('Car engine stopped');\n    }\n}\n\nclass CarDrive extends Drivable{\n    drive(){\n        console.log('Car is driving');\n    }\n}\n\nclass Car{\n    constructor(){\n        this.engine = new CarEngine();\n        this.driving = new CarDrive();\n    }\n    startEngine(){\n        this.engine.startEngine();\n    }\n    stopEngine(){\n        this.engine.stopEngine();\n    }\n    drive(){\n        this.driving.drive();\n    }\n}\n\nclass PlaneEngine extends EnginePowered{\n    startEngine(){\n        console.log('Plane engine started');\n    }\n    stopEngine(){\n        console.log('Plane engine stopped');\n    }\n}\n\nclass PlaneFly extends Flyable{\n    fly(){\n        console.log(\"Plane is flying\")\n    }\n}\n\nclass Plane{\n    constructor(){\n        this.engine = new PlaneEngine();\n        this.flying = new PlaneFly();\n    }\n    startEngine(){\n        this.engine.startEngine();\n    }\n    stopEngine(){\n        this.engine.stopEngine();\n    }\n    fly(){\n        this.flying.fly();\n    }\n}\n\n\nconst car = new Car();\n\ncar.startEngine();\ncar.drive();\ncar.stopEngine();\n\nconst plane = new Plane();\n\nplane.startEngine();\nplane.fly();\nplane.stopEngine();\n\n\n//////////////// --------------------------------------- EXTRA ------------------------------- //////////////////////\n\n\nclass BlackWhitePrint{\n    printBlWh(){\n        throw new Error(\"Method 'printBlWh()' must be implemented.\");\n    }\n}\nclass ColorPrint{\n    printColor(){\n        throw new Error(\"Method 'printColor()' must be implemented.\");\n    }\n}\nclass ScannerPrint{\n    scan(){\n        throw new Error(\"Method 'scan()' must be implemented.\");\n    }\n}\nclass FaxPrint{\n    sendFax(dest){\n        throw new Error(\"Method 'sendFax()' must be implemented.\");\n    }\n}\n\n// Implementaciones para una impresoar Epson\nclass EpsonBlackWhite extends BlackWhitePrint{\n    printBlWh(){\n        console.log(\"Impresion en blanco y negro\")\n    }\n}\nclass EpsonColor extends ColorPrint{\n    printColor(){\n        console.log(\"Impresion a colores\")\n    }\n}\nclass EpsonScanner extends ScannerPrint{\n    scan(){\n        console.log(\"Escaneo disponible\")\n    }\n}\n\nclass Epson{\n    constructor(){\n        this.blackWhite = new EpsonBlackWhite();\n        this.colores = new EpsonColor();\n        this.escaner = new EpsonScanner();\n    }\n    printBlWh(){\n        this.blackWhite.printBlWh();\n    }\n    printColor(){\n        this.colores.printColor();\n    }\n    scan(){\n        this.escaner.scan();\n    }\n}\n\n// Implementaciones para una impresora Cannon\nclass CannonBlackWhite extends BlackWhitePrint{\n    printBlWh(){\n        console.log(\"Impresion en blanco y negro\")\n    }\n}\nclass CannonFax extends FaxPrint{\n    sendFax(dest){\n        console.log(`Enviando documento a ${dest}`)\n    }\n}\n\nclass Cannon{\n    constructor(){\n        this.blackWhite = new CannonBlackWhite();\n        this.sendTo = new CannonFax();\n    }\n    printBlWh(){\n        this.blackWhite.printBlWh();\n    }\n    sendFax(dest){\n        this.sendTo.sendFax(dest);\n    }\n}\n\nconst epson = new Epson();\nepson.printBlWh();\nepson.printColor(),\nepson.scan();\n\nconst cannon = new Cannon();\ncannon.printBlWh();\ncannon.sendFax(\"juan4512\");\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/javascript/DavidMoralesDeveloper.js",
    "content": "// \"Los clientes no deben ser forzados a depender de interfaces que no utilizan.\"\n// En JavaScript, al no tener interfaces nativas, nos referimos a un contrato implícito o a una clase base abstracta}\n\n\nclass ControGeneral {\n    tvOn(){console.log(\"Encendiendo la TV\")}\n    tvOff(){console.log(\"Apagando la TV\")}\n    tvSubirVolume(){ console.log(\"Subiendo vol\")}\n    tvBajarVolume(){console.log(\"Bajando vol\") }\n    tvCanalMas(){console.log(\"Subiendo de Canal\")}\n    tvCanalMenos(){ console.log(\"Bajando de Canal\")}\n    airOn(){console.log(\"Prendiendo el Aire Acondicionado\")}\n    airOff(){console.log(\"Apagando el Aire Acondicionado\")}\n    airSubirTem(){console.log(\"Subiendo la temperatura\")}\n    airBajarTem(){console.log(\"Bajando la temperatura\") }\n    luzOn(){console.log(\"Luz Encendia\")}\n    luzOff(){console.log(\"Luz Apagada\")}\n    luzTenue(){console.log(\"Atenuar Luz\")}\n    \n}\n\nconst controlGeneral = new ControGeneral() \ncontrolGeneral.airOn()\ncontrolGeneral.tvBajarVolume()\n\nclass Tv extends ControGeneral{\n    prender(){console.log(\"encender la tele\")}\n    apagar(){console.log(\"apagar la tele\")}\n    volMas(){console.log(\"Subir Volimen\")}\n    volMenos(){console.log(\"Bajar Volumen\")}\n}\nclass Air extends ControGeneral{\n    prender(){console.log(\"prender Aire acondicionado\")}\n    apagar(){console.log(\"apagar Aire acondicionado\")}\n    subir(){console.log(\"subir temperatura\")}\n    bajar(){console.log(\"bajar temperatura\")}\n}\n\nclass Luz extends ControGeneral{\n    prender(){console.log(\"prender luz\")}\n    apagar(){console.log(\"apagar luz\")}\n}\n\nconst tv = new Tv()\ntv.prender()\nconst luz = new Luz()\nluz.apagar()\n\n/*\n\n * DIFICULTAD EXTRA (opcional):\n * Crea un gestor de impresoras.\n * Requisitos:\n * 1. Algunas impresoras sólo imprimen en blanco y negro.\n * 2. Otras sólo a color.\n * 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n * Instrucciones:\n * 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n * 2. Aplica el ISP a la implementación.\n * 3. Desarrolla un código que compruebe que se cumple el principio.\n */\n\nclass Impresora{\n   \n}\n\nclass BlackWhite extends Impresora{\n    imprimir(){console.log(\"Estoy imprimiendo en blanco y negro\")}\n}\n\nclass Color extends Impresora{\n    imprimir(){console.log(\"Estoy imprimiendo a color\")}\n}\n\nclass Multifuncion extends Impresora{\n    imprimirBlancoNegro(){console.log(\"imprimiendo en Blanco y Negro\")}\n    imprimirColor(){console.log(\"imprimiendo en Color\")}\n    escanear(){console.log(\"Escaneando documento\")}\n    faxSend(){console.log(\"Enviando Fax\")}\n}\n\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #29 - JavaScript -> Jesus Antonio Escamilla */\n\n/**\n * El ISP establece que una clase no debe estar obligada a implementar interfaces que no utiliza.\n * En otras palabras, es mejor tener interfaces más pequeñas y específicas que interfaces grandes y generales.\n */\n\n//---EJERCIÓ---\n// INCORRECTO\n// Interfaz general\nclass IWorker{\n   work(){\n      throw new Error(\"Method not implemented\");\n   }\n\n   attendMeeting(){\n      throw new Error(\"Method not implemented\");\n   }\n\n   writeCode(){\n      throw new Error(\"Method not implemented\");\n   }\n}\n\n// Clase que implementa interfaz general\nclass Manager__ extends IWorker{\n   work(){\n      console.log(\"Manager working on project management\");\n   }\n\n   attendMeeting(){\n      console.log(\"Manager attending a meeting\");\n   }\n\n   writeCode(){\n      throw new Error(\"Manager does not write code\");\n   }\n}\n\nclass Developer__ extends IWorker{\n   work(){\n      console.log(\"Developer working on coding\");\n   }\n\n   attendMeeting(){\n      throw new Error(\"Developer does not attend meetings\");\n   }\n\n   writeCode(){\n      console.log(\"Developer writing code\");\n   }\n}\n\n// Uso Incorrecto de ISP\nconst manager__ = new Manager__();\nmanager__.work();\nmanager__.attendMeeting();\n\nconst developer__ = new Developer__();\ndeveloper__.work();\ndeveloper__.writeCode();\n\n\n// CORRECTO\n// Interfaz general\nclass IWork{\n   work(){\n      throw new Error(\"Method not implemented\");\n   }\n}\n\nclass IAttendMeeting{\n   attendMeeting(){\n      throw new Error(\"Method not implemented\");\n   }\n}\n\nclass IWriteCode{\n   writeCode(){\n      throw new Error(\"Method not implemented\");\n   }\n}\n\n// Clase que implementa interfaz general\nclass Manager extends IWork{\n   work(){\n      console.log(\"Manager working on project management\");\n   }\n}\n\nclass ManagerMeeting extends IAttendMeeting{\n   attendMeeting(){\n      console.log(\"Manager attending a meeting\");\n   }\n}\n\nclass Developer extends IWriteCode{\n   work(){\n      console.log(\"Developer working on coding\");\n   }\n}\n\nclass DeveloperCoding extends IWriteCode{\n   writeCode(){\n      console.log(\"Developer writing code\")\n   }\n}\n\n// Uso Correcto de ISP\nconst manager = new Manager();\nmanager.work();\n\nconst managerMeeting = new ManagerMeeting();\nmanagerMeeting.attendMeeting();\n\nconst developer = new Developer();\ndeveloper.work();\n\nconst developerCoding = new DeveloperCoding();\ndeveloperCoding.writeCode();\n\n\n\n/**-----DIFICULTAD EXTRA-----*/\n\n// Interfaces\nclass IPrinterBlackAndWhite{\n   printBlackAndWhite(){\n      throw new Error('Method not implement');\n   }\n}\n\nclass IPrinterColor{\n   printColor(){\n      throw new Error('Method not implement');\n   }\n}\n\nclass IScan{\n   scan(){\n      throw new Error('Method not implement');\n   }\n}\n\nclass IFax{\n   sendFax(){\n      throw new Error('Method not implement');\n   }\n}\n\n// Implementado las Impresoras\nclass EpsonBlackAndWhiter extends IPrinterBlackAndWhite{\n   printBlackAndWhite(){\n      console.log('Epson => Imprimiendo documento a blanco y negro....');\n   }\n}\n\nclass CanonColor extends IPrinterBlackAndWhite{\n   printColor(){\n      console.log('Canon => Imprimiendo documento a color.....')\n   }\n}\n\nclass BrotherBlackAndWhiter extends IPrinterBlackAndWhite{\n   printBlackAndWhite(){\n      console.log('Brother => Imprimiendo documento a blanco y negro....');\n   }\n}\n\nclass BrotherColor extends IPrinterColor{\n   printColor(){\n      console.log('Brother => Imprimiendo documento a color....');\n   }\n}\n\nclass BrotherScan extends IScan{\n   scan(){\n      console.log('Brother => Escaneando el documento....');\n   }\n}\n\nclass BrotherFax extends IFax{\n   sendFax(){\n      console.log('Brother => Enviando el documento....');\n   }\n}\n\nclass MultiFunctionBrother{\n   constructor() {\n      this.black_white = new BrotherBlackAndWhiter();\n      this.color = new BrotherColor();\n      this.scan = new BrotherScan();\n      this.fax = new BrotherFax();\n   }\n\n   printBlack_White(){\n      this.black_white.printBlackAndWhite();\n   }\n   \n   printColor(){\n      this.color.printColor();\n   }\n\n   scanSend(){\n      this.scan.scan();\n   }\n\n   faxSend(){\n      this.fax.sendFax();\n   }\n}\n\n\n// Comprobando que se cumpla ISP y correctamente\nconst Epson = new EpsonBlackAndWhiter();\nconst Cannon = new CanonColor();\nconst Brother = new MultiFunctionBrother();\n\nEpson.printBlackAndWhite();\nCannon.printColor();\nBrother.printBlack_White();\nBrother.printColor();\nBrother.scanSend();\nBrother.faxSend();\n\n/**-----DIFICULTAD EXTRA-----*/"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/javascript/RaulDoezon.js",
    "content": "/*\n  EJERCICIO:\n  Explora el \"Principio SOLID de Segregación de Interfaces (Interface Segregation Principle, ISP)\" \n  y crea un ejemplo simple donde se muestre su funcionamiento de forma correcta e incorrecta.\n*/\n\nconsole.log(\"+++++++++ FORMA INCORRECTA +++++++++\");\n\nclass ProductProof {\n  getDetails() {\n    console.log(\"Obtener detalles del producto físico.\");\n  }\n\n  saveToDb() {\n    console.log(\"Guardar producto físico en la base de datos.\");\n  }\n}\n\nclass DigitalProductProof extends ProductProof {\n  getDetails() {\n    console.log(\"Obtener detalles del producto digital.\");\n  }\n\n  saveToDb() {\n    console.log(\"Guardar producto digital en la base de datos.\");\n  }\n}\n\nconst productProof = new ProductProof();\nconst digitalProductProof = new DigitalProductProof();\n\nproductProof.getDetails();\nproductProof.saveToDb();\ndigitalProductProof.getDetails();\ndigitalProductProof.saveToDb();\n\nconsole.log(\"\\n+++++++++ FORMA CORRECTA +++++++++\");\n\nclass Product {\n  getDetails() {\n    console.error(\"Primero se debe definir si los detalles a obtener son de un producto físico o dígital.\");\n  }\n}\n\nclass PhysicalProduct extends Product {\n  getDetails() {\n    console.log(\"Obtener detalles del producto físico.\");\n  }\n}\n\nclass DigitalProduct extends Product {\n  getDetails() {\n    console.log(\"Obtener detalles del producto digital.\");\n  }\n\n  saveToDb() {\n    console.log(\"Guardar producto digital en la base de datos.\");\n  }\n}\n\nconst product = new Product();\nconst physicalProduct = new PhysicalProduct();\nconst digitalProduct = new DigitalProduct();\n\nproduct.getDetails();\nphysicalProduct.getDetails();\ndigitalProduct.getDetails();\ndigitalProduct.saveToDb();\n\n/*\n  DIFICULTAD EXTRA (opcional):\n  Crea un gestor de impresoras.\n  Requisitos:\n  1. Algunas impresoras sólo imprimen en blanco y negro.\n  2. Otras sólo a color.\n  3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n  Instrucciones:\n  1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n  2. Aplica el ISP a la implementación.\n  3. Desarrolla un código que compruebe que se cumple el principio.\n*/\n\nconsole.log(\"\\n+++++++++ GESTOR DE IMPRESORAS +++++++++\");\n\nclass BlackAndWhiteInterface {\n  print(document) {\n    console.error(`El documento ${document} no se puede imprimir a blanco y negro desde la interfaz.`);\n  }\n}\n\nclass ColorInterface {\n  colorPrint(document) {\n    console.error(`El documento ${document} no se puede imprimir a color desde la interfaz.`);\n  }\n}\n\nclass ScannerInterface {\n  scan(document) {\n    console.error(`El documento ${document} no se puede escanear desde la interfaz.`);\n  }\n}\n\nclass FaxInterface {\n  fax(document) {\n    console.error(`El documento ${document} no se puede enviar por fax desde la interfaz.`);\n  }\n}\n\nclass BlackAndWhitePrinter extends BlackAndWhiteInterface {\n  print(document) {\n    console.log(`Imprimiendo el documento \"${document}\" a blanco y negro.`);\n  }\n}\n\nclass ColorPrinter extends ColorInterface {\n  colorPrint(document) {\n    console.log(`Imprimiendo el documento \"${document}\" a color.`);\n  }\n}\n\nclass MultifunctionPrinter extends (BlackAndWhiteInterface, ColorInterface, ScannerInterface, FaxInterface) {\n  print(document) {\n    console.log(`Imprimiendo el documento \"${document}\" a blanco y negro.`);\n  }\n\n  colorPrint(document) {\n    console.log(`Imprimiendo el documento \"${document}\" a color.`);\n  }\n\n  scan(document) {\n    console.log(`Escaneando el documento \"${document}\".`);\n  }\n\n  fax(document) {\n    console.log(`Enviando por el documento \"${document}\" por fax.`);\n  }\n}\n\nfunction testingPrinters() {\n  const doc = \"tenencia-2024.pdf\"\n\n  const blackAndWhiteInterface = new BlackAndWhiteInterface();\n  const colorInterface = new ColorInterface();\n  const scannerInterface = new ScannerInterface();\n  const faxInterface = new FaxInterface();\n\n  const blackAndWhitePrinter = new BlackAndWhitePrinter();\n  const colorPrinter = new ColorPrinter();\n  const multifunctionPrinter = new MultifunctionPrinter();\n\n  blackAndWhiteInterface.print(doc);\n  colorInterface.colorPrint(doc);\n  scannerInterface.scan(doc);\n  faxInterface.fax(doc);\n\n  blackAndWhitePrinter.print(doc);\n  colorPrinter.colorPrint(doc);\n  multifunctionPrinter.print(doc);\n  multifunctionPrinter.colorPrint(doc);\n  multifunctionPrinter.scan(doc);\n  multifunctionPrinter.fax(doc);\n}\n\ntestingPrinters();\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/javascript/RicJDev.js",
    "content": "//EJERCICIO\n//Incorrecto ❎\nclass BookNoISP {\n\tconstructor(title, author, price) {\n\t\tthis.title = title\n\t\tthis.author = author\n\t\tthis.price = price\n\t}\n\n\tgetPrice() {\n\t\t//Le muestra el precio del libro al cliente\n\t}\n\n\tgetReviews() {\n\t\t//Muestra los comentarios acerca del libro\n\t}\n}\n\nclass FreeBookNoISP extends BookNoISP {\n\tconstructor(title, author) {\n\t\tsuper(title, author)\n\t\tthis.price = 0\n\t}\n\n\t//Hereda el método para mostrar el precio, lo cual no tendría sentido para un libro gratuito\n}\n\n//Correcto ✅\nclass Book {\n\tconstructor(title, author) {\n\t\tthis.title = title\n\t\tthis.author = author\n\t}\n\n\tgetReviews() {\n\t\t//Muestra los comentarios acerca del libro\n\t}\n}\n\nclass PurchasableBook extends Book {\n\tconstructor(title, author, price) {\n\t\tsuper(author, title)\n\t\tthis.price = price\n\t}\n\n\tgetPrice() {\n\t\t//Le muestra el precio del libro al cliente\n\t}\n}\n\nclass FreeBook extends Book {\n\tconstructor(title, author) {\n\t\tsuper(title, author)\n\t}\n}\n\n//EXTRA\n//Interfaces\nclass PrinterInterface {\n\tprint(document) {\n\t\tconsole.log(`Imprimiendo ${document} en blanco y negro`)\n\t}\n}\n\nclass ColorPrinterInterface {\n\tprint(document) {\n\t\tconsole.log(`Imprimiendo ${document} a color`)\n\t}\n}\n\nclass ScanInterface {\n\tscan(document) {\n\t\tconsole.log(`Se ha escaneado el documento ${document}`)\n\t}\n}\nclass FaxInterface {\n\tsend(document) {\n\t\tconsole.log(`Se ha enviado el documento ${document} via fax`)\n\t}\n}\n\n//Implementacion\nclass Printer extends PrinterInterface {}\n\nclass ColorPrinter extends ColorPrinterInterface {}\n\nclass MultiFunction {\n\tconstructor() {\n\t\tthis.blackAndWhite = new Printer()\n\t\tthis.color = new ColorPrinter()\n\t\tthis.scanner = new ScanInterface()\n\t\tthis.fax = new FaxInterface()\n\t}\n\n\tprint(document) {\n\t\tthis.blackAndWhite.print(document)\n\t}\n\n\tprintColor(document) {\n\t\tthis.color.print(document)\n\t}\n\n\tscan(document) {\n\t\tthis.scanner.scan(document)\n\t}\n\n\tsendFax(document) {\n\t\tthis.fax.send(document)\n\t}\n}\n\n//Probando ISP\nlet doc = 'miDocumento.docx'\n\nconst printer = new Printer()\nconst colorPrinter = new ColorPrinter()\nconst multiFunction = new MultiFunction()\n\nprinter.print(doc)\ncolorPrinter.print(doc)\n\nmultiFunction.print(doc)\nmultiFunction.printColor(doc)\nmultiFunction.scan(doc)\nmultiFunction.sendFax(doc)\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/javascript/Sac-Corts.js",
    "content": "// Wrong way\nclass Device {\n    turnOn() {}\n    turnOff() {}\n    charge() {}\n    connectToInternet() {}\n}\n\nclass Laptop extends Device {\n    turnOn() {\n        console.log(\"Laptop turned on\");\n    }\n\n    turnOff() {\n        console.log(\"Laptop turned off\");\n    }\n\n    charge() {\n        console.log(\"Laptop charging\");\n    }\n\n    connectToInternet() {\n        console.log(\"Laptop connected to the internet\");\n    }\n}\n\nclass Microwave extends Device {\n    turnOn() {\n        console.log(\"Microwave turned on\");\n    }\n\n    turnOff() {\n        console.log(\"Microwave turned off\");\n    }\n\n    charge() {\n        throw new Error(\"A microwave doesn't need to be charged\");\n    }\n\n    connectToInternet() {\n        throw new Error(\"A microwave doesn't need to be connected to the internet\");\n    }\n}\n\nconst microwave = new Microwave();\n// microwave.charge();  // Error\n\n// Correct way\nclass Switchable {\n    turnOn() {}\n    turnOff() {}\n}\n\nclass Chargeable {\n    charge() {}\n}\n\nclass InternetConnectable {\n    connectToInternet() {}\n}\n\nclass Laptop2 extends Switchable {\n    turnOn() {\n        console.log(\"Laptop turned on\");\n    }\n\n    turnOff() {\n        console.log(\"Laptop turned off\");\n    }\n}\n\nclass AdvancedLaptop extends Laptop2 {\n    charge() {\n        console.log(\"Laptop charging.\");\n    }\n\n    connectToInternet() {\n        console.log(\"Laptop connected to the internet.\");\n    }\n}\n\nclass Microwave2 extends Switchable {\n    turnOn() {\n        console.log(\"Microwave turned on\");\n    }\n\n    turnOff() {\n        console.log(\"Microwave turned off\");\n    }\n}\n\nconst laptop2 = new AdvancedLaptop();\nlaptop2.charge();\nlaptop2.connectToInternet();\n\nconst microwave2 = new Microwave2();\nmicrowave2.turnOn();\nmicrowave2.turnOff();\n\n// Extra Exercise //\nclass BlackAndWhitePrintable  {\n    printBlackAndWhite() {}\n}\n\nclass ColorPrintable {\n    printColor() {}\n}\n\nclass Scannable {\n    scan() {}\n}\n\nclass Faxable {\n    sendFax() {}\n}\n\nclass BlackAndWhitePrinter extends BlackAndWhitePrintable {\n    printBlackAndWhite() {\n        console.log(\"Printing in black and white...\");\n    }\n}\n\nclass ColorPrinter extends ColorPrintable {\n    printColor() {\n        console.log(\"Printing in color...\");\n    }\n}\n\nclass MultiFunctionPrinter extends BlackAndWhitePrintable {\n    printBlackAndWhite() {\n        console.log(\"Printing in black and white...\");\n    }\n\n    printColor() {\n        console.log(\"Printing in color...\");\n    }\n\n    scan() {\n        console.log(\"Scanning...\");\n    }\n\n    sendFax() {\n        console.log(\"Sending fax...\");\n    }\n}\n\nconst blackAndWhitePrinter = new BlackAndWhitePrinter();\nblackAndWhitePrinter.printBlackAndWhite();\n\nconst colorPrinter = new ColorPrinter();\ncolorPrinter.printColor();\n\nconst multiFunctionPrinter = new MultiFunctionPrinter();\nmultiFunctionPrinter.printBlackAndWhite();\nmultiFunctionPrinter.printColor();\nmultiFunctionPrinter.scan();\nmultiFunctionPrinter.sendFax();"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/javascript/adrs1166ma.js",
    "content": "/* 🔥 EJERCICIO:\nExplora el \"Principio SOLID de Segregación de Interfaces (Interface Segregation Principle, ISP)\" \ny crea un ejemplo simple donde se muestre su funcionamiento de forma correcta e incorrecta.\n*/\n\nconsole.log(\"----- EJEMPLO SIMPLE -----\");\n\n//  * Ejemplo Incorrecto (viola ISP): Interfaz grande y forzada\n// --------------------------------------------------------------------------------------------------------------\nclass TrabajadorIncorrecto {\n    trabajar() {}\n    comer() {}\n    dormir() {}\n}\n\nclass Robot extends TrabajadorIncorrecto {\n    trabajar() {\n        console.log(\"🤖 Robot trabajando...\");\n    }\n\n    // Métodos no necesarios, pero obligados por la interfaz\n    comer() {\n        throw new Error(\"❌ Los robots no comen.\");\n    }\n\n    dormir() {\n        throw new Error(\"❌ Los robots no duermen.\");\n    }\n}\n\n// Función que usa la interfaz incorrecta\nfunction gestionarTrabajador(trabajador) {\n    trabajador.trabajar();\n    try {\n        trabajador.comer(); // ¡Falla con Robot!\n    } catch (error) {\n        console.error(error.message);\n    }\n}\n\n// Uso incorrecto\nconst robot = new Robot();\ngestionarTrabajador(robot); // Error: Los robots no comen.\n\n\n//  * Ejemplo Correcto (cumple ISP): Interfaces segregadas\n// --------------------------------------------------------------------------------------------------------------\nclass Trabajable {\n    trabajar() {\n        throw new Error(\"Implementa el método 'trabajar'\");\n    }\n}\n\nclass Comible {\n    comer() {\n        throw new Error(\"Implementa el método 'comer'\");\n    }\n}\n\nclass Dormible {\n    dormir() {\n        throw new Error(\"Implementa el método 'dormir'\");\n    }\n}\n\nclass RobotCorrecto extends Trabajable {\n    trabajar() {\n        console.log(\"🤖 Robot trabajando correctamente...\");\n    }\n}\n\nclass Humano extends Trabajable {\n    constructor() {\n        super();\n        this.comible = new Comible();\n        this.dormible = new Dormible();\n    }\n\n    trabajar() {\n        console.log(\"👤 Humano trabajando...\");\n    }\n\n    comer() {\n        this.comible.comer();\n    }\n\n    dormir() {\n        this.dormible.dormir();\n    }\n}\n\n// Función que cumple ISP\nfunction gestionarTrabajo(trabajable) {\n    trabajable.trabajar();\n}\n\n// Uso correcto\nconst robotCorrecto = new RobotCorrecto();\ngestionarTrabajo(robotCorrecto); // Correcto: solo usa 'trabajar'\n\n/* 🔥 DIFICULTAD EXTRA (opcional):\nCrea un gestor de impresoras.\nRequisitos:\n1. Algunas impresoras sólo imprimen en blanco y negro.\n2. Otras sólo a color.\n3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\nInstrucciones:\n1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n2. Aplica el ISP a la implementación.\n3. Desarrolla un código que compruebe que se cumple el principio.\n */\n// --------------------------------------------------------------------------------------------------------------\nconsole.log(\"\\n----- GESTOR DE IMPRESORAS (ISP) -----\");\n\n// Interfaz base para impresoras\nclass Impresora {\n    imprimir() {\n        throw new Error(\"Método 'imprimir' no implementado\");\n    }\n}\n\n// Interfaz para escáner\nclass Escaner {\n    escanear() {\n        throw new Error(\"Método 'escanear' no implementado\");\n    }\n}\n\n// Interfaz para fax\nclass Fax {\n    enviarFax() {\n        throw new Error(\"Método 'enviarFax' no implementado\");\n    }\n}\n\n// Impresora B/N (solo implementa impresión)\nclass ImpresoraBN extends Impresora {\n    imprimir() {\n        console.log(\"🖨️ Imprimiendo en blanco y negro.\");\n    }\n}\n\n// Impresora color (solo implementa impresión)\nclass ImpresoraColor extends Impresora {\n    imprimir() {\n        console.log(\"🌈 Imprimiendo a color.\");\n    }\n}\n\n// Multifunción (implementa todas las interfaces)\nclass Multifuncion extends Impresora {\n    constructor() {\n        super();\n        this.escaner = new Escaner();\n        this.fax = new Fax();\n    }\n\n    escanear() {\n        this.escaner.escanear();\n    }\n\n    enviarFax() {\n        this.fax.enviarFax();\n    }\n\n    imprimir() {\n        console.log(\"🖨️ 🌈 Imprimiendo en B/N o color (multifunción).\");\n    }\n}\n\n// Funciones del gestor que cumplen ISP\nfunction imprimirDocumento(impresora) {\n    if (impresora instanceof Impresora) {\n        impresora.imprimir();\n    } else {\n        console.log(\"⚠️ No es una impresora válida.\");\n    }\n}\n\nfunction escanearDocumento(escaner) {\n    if (escaner instanceof Escaner) {\n        escaner.escanear();\n    } else {\n        console.log(\"⚠️ No es un escáner válido.\");\n    }\n}\n\nfunction enviarFax(fax) {\n    if (fax instanceof Fax) {\n        fax.enviarFax();\n    } else {\n        console.log(\"⚠️ No es un fax válido.\");\n    }\n}\n\nconsole.log(\"\\n--- Pruebas de impresoras ---\");\nconst impresoraBN = new ImpresoraBN();\nconst impresoraColor = new ImpresoraColor();\nconst multifuncion = new Multifuncion();\n\nimprimirDocumento(impresoraBN); // Imprime B/N\nimprimirDocumento(impresoraColor); // Imprime color\nimprimirDocumento(multifuncion); // Imprime multifunción\n\nescanearDocumento(multifuncion); // Escanea (multifunción)\nescanearDocumento(impresoraBN); // Error: No es escáner\n\nenviarFax(multifuncion); // Envia fax (multifunción)\nenviarFax(impresoraColor); // Error: No es fax"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/javascript/caterinarodriguezdev.js",
    "content": "/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Segregación de Interfaces\n * (Interface Segregation Principle, ISP)\", y crea un ejemplo\n * simple donde se muestre su funcionamiento de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un gestor de impresoras.\n * Requisitos:\n * 1. Algunas impresoras sólo imprimen en blanco y negro.\n * 2. Otras sólo a color.\n * 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n * Instrucciones:\n * 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n * 2. Aplica el ISP a la implementación.\n * 3. Desarrolla un código que compruebe que se cumple el principio.\n */\n\n// INCORRECTA\n\nclass Empleado {\n    constructor() {\n        if (this.constructor === Empleado) {\n            throw new Error('No puedes instanciar una interfaz');\n        }\n    }\n    calcularSalario() {\n        throw new Error('Debe implementar el método calcular salario')\n    }\n\n    programarReunion() {\n        throw new Error('Debe implementar el método programar reunión')\n    }\n}\n\n\nclass Obrero extends Empleado {\n\n    calcularSalario() {\n        return 1000;\n    }\n}\n\nconst empleado = new Obrero();\nconsole.log(empleado.calcularSalario());\nconsole.log(empleado.programarReunion());\n\n// CORRECTA\nclass CalculadoraSalario {\n    calcularSalario() {}\n}\n\nclass ProgramadorReuniones {\n    programarReunion(){}\n}\n\nclass ObreroISP extends CalculadoraSalario {\n    calcularSalario() {}\n}\n\nconst empleadoISP = new ObreroISP();\nconsole.log(empleadoISP.calcularSalario());\n\n\nconsole.log('---------DIFICULTAD EXTRA-------------');\n\n// * DIFICULTAD EXTRA (opcional):\n// * Crea un gestor de impresoras.\n// * Requisitos:\n// * 1. Algunas impresoras sólo imprimen en blanco y negro.\n// * 2. Otras sólo a color.\n// * 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n// * Instrucciones:\n// * 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n// * 2. Aplica el ISP a la implementación.\n// * 3. Desarrolla un código que compruebe que se cumple el principio.\n// */\n\n\nclass GestorImpresorasBN {\n    constructor() {\n        if (this.constructor === GestorImpresorasBN) {\n            throw Error('No puede instanciar una interfaz');\n        }\n    }\n\n    imprimirBN() {\n        throw Error('Debe implementar imprimirBN')\n    }\n}\n\nclass GestorImpresorasColor {\n    constructor() {\n        if (this.constructor === GestorImpresorasColor) {\n            throw Error('No puede instanciar una interfaz');\n        }\n    }\n\n    imprimirColor() {\n        throw Error('Debe implementar imprimirColor')\n    }\n}\n\nclass GestorImpresorasMulti {\n    constructor() {\n        if (this.constructor === GestorImpresorasMulti) {\n            throw Error('No puede instanciar una interfaz');\n        }\n    }\n\n    imprimir() {\n        throw Error('Debe implementar imprimir')\n    }\n\n    escanear() {\n        throw Error('Debe implementar escanear')\n    }\n\n    enviarFax() {\n        throw Error('Debe implementar enviarFax')\n    }\n}\n\nclass ImpresoraBN extends GestorImpresorasBN {\n    imprimirBN() {\n        console.log('imprimiendo en bn');\n    }\n}\n\nclass ImpresoraColor extends GestorImpresorasColor {\n    imprimirColor() {\n        console.log('imprimiendo en color');\n    }\n}\n\nclass ImpresoraMulti extends GestorImpresorasMulti {\n    imprimir() {\n        console.log('imprimiendo');\n    }\n\n    escanear() {\n        console.log('escaneando');\n    }\n\n    enviarFax() {\n        console.log('enviando fax');\n    }\n}\n\nconst impresoraBN = new ImpresoraBN();\nimpresoraBN.imprimirBN();\n\nconst impresoraColor = new ImpresoraColor();\nimpresoraColor.imprimirColor();\n\nconst impresoraMulti = new ImpresoraMulti();\nimpresoraMulti.imprimir();\nimpresoraMulti.escanear();\nimpresoraMulti.enviarFax();"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/javascript/duendeintemporal.js",
    "content": "//#29 - Principio SOLID de Segregación de Interfaces (Interface Segregation Principle (ISP))\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Segregación de Interfaces (Interface Segregation Principle, ISP)\", y crea un ejemplo\n * simple donde se muestre su funcionamiento de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un gestor de impresoras.\n * Requisitos:\n * 1. Algunas impresoras sólo imprimen en blanco y negro.\n * 2. Otras sólo a color.\n * 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n * Instrucciones:\n * 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n * 2. Aplica el ISP a la implementación.\n * 3. Desarrolla un código que compruebe que se cumple el principio.\n */\n//Bibliografy: The Web Development Glossary (Jens Oliver Meiert) (Z-Library)\n//GPT\n\n/* Interface Segregation Principle\nThe principle that no client should be forced to depend on methods it does\nnot use. ISP splits interfaces that are very large into smaller and more\nspecific ones so that clients will only have to know about the methods that\nare of interest to them. Such shrunken interfaces are also called role\ninterfaces. ISP is intended to keep a system decoupled and thus easier to\nrefactor, change, and redeploy.  */\n\nlet log = console.log;\n\nwindow.addEventListener('load', ()=>{\n    const body = document.querySelector('body');\n    const title = document.createElement('h1');\n    \n    body.style.setProperty('background', '#000');\n    body.style.setProperty('text-align', 'center');\n    \n    title.textContent = 'Retosparaprogramadores #29.';\n    title.style.setProperty('font-size', '3.5vmax');\n    title.style.setProperty('color', '#fff');\n    title.style.setProperty('line-height', '100vh');\n    \n    body.appendChild(title);\n    \n    setTimeout(()=>{\n    alert('Retosparaprogramadores #29. Please open the Browser Developer Tools.');\n    }, 2000);\n    log( 'Retosparaprogramadores #29'); \n});\n\n// Incorrect Example\nclass PaymentService {\n    processCreditCardPayment(amount) {}\n    processPayPalPayment(amount) {}\n    processBitcoinPayment(amount) {}\n}\n\nclass CreditCardPayment extends PaymentService {\n    processCreditCardPayment(amount) {\n        log(`Processing credit card payment of ${amount}`);\n    }\n    \n    processPayPalPayment(amount) {\n        throw new Error(\"This payment method does not support PayPal payments\");\n    }\n    \n    processBitcoinPayment(amount) {\n        throw new Error(\"This payment method does not support Bitcoin payments\");\n    }\n}\n\nclass PayPalPayment extends PaymentService {\n    processCreditCardPayment(amount) {\n        throw new Error(\"This payment method does not support credit card payments\");\n    }\n    \n    processPayPalPayment(amount) {\n        log(`Processing PayPal payment of ${amount}`);\n    }\n    \n    processBitcoinPayment(amount) {\n        throw new Error(\"This payment method does not support Bitcoin payments\");\n    }\n}\n\nclass BitcoinPayment extends PaymentService {\n    processCreditCardPayment(amount) {\n        throw new Error(\"This payment method does not support credit card payments\");\n    }\n    \n    processPayPalPayment(amount) {\n        throw new Error(\"This payment method does not support PayPal payments\");\n    }\n    \n    processBitcoinPayment(amount) {\n        log(`Processing Bitcoin payment of ${amount}`);\n    }\n}\n\n\nconst creditCardPayment = new CreditCardPayment();\ncreditCardPayment.processCreditCardPayment(250); // Processing credit card payment of 250\n//creditCardPayment.processPayPalPayment(87); // This will throw an error\n//Error: This payment method does not support PayPal payments at CreditCardPayment.processPayPalPayment\n\n// Correct Example\nclass CreditCardPaymentService {\n    processCreditCardPayment(amount) {\n        log(`Processing credit card payment of ${amount}`);\n    }\n}\n\nclass PayPalPaymentService {\n    processPayPalPayment(amount) {\n        log(`Processing PayPal payment of ${amount}`);\n    }\n}\n\nclass BitcoinPaymentService {\n    processBitcoinPayment(amount) {\n        log(`Processing Bitcoin payment of ${amount}`);\n    }\n}\n\n\nconst creditCardPayment1 = new CreditCardPaymentService();\ncreditCardPayment1.processCreditCardPayment(400); // Processing credit card payment of 400\n\nconst payPalPayment = new PayPalPaymentService();\npayPalPayment.processPayPalPayment(130); // Processing PayPal payment of 130\n\nconst bitcoinPayment = new BitcoinPaymentService();\nbitcoinPayment.processBitcoinPayment(0.020); // Processing Bitcoin payment of 0.02\n\n\n//Extra Dificulty Exercise\n\nclass BlackAndWhitePrinter{\n    print(doc){\n        log(`Printing: ${doc} in Black & White`);\n    }\n}\n\nclass ColorPrinter{\n    print(doc){\n        log(`Printing: ${doc} in Color`);\n    }\n}\n\nclass MultiFunctionPrinter{\n\n    printInBlackAndWhite(doc){\n        log(`Printing: ${doc} in Black & White`);\n    }\n\n    print(doc){\n        log(`Printing: ${doc} in Color`);\n    }\n\n    fax(doc){\n        log(`Faxing: ${doc}`);\n    }\n\n    scan(doc){\n        log(`Scanning: ${doc}`);\n    }\n}\n\nlet book = 'vuelointemporal.odt';\n\nconst bw_printer = new BlackAndWhitePrinter();\nbw_printer.print(book); // Printing: vuelointemporal.odt in Black & White\n\nconst c_printer = new ColorPrinter();\nc_printer.print(book); // vuelointemporal.odt in Color\n\nconst m_printer = new MultiFunctionPrinter();\nm_printer.printInBlackAndWhite(book); // vuelointemporal.odt in Black & White\nm_printer.print(book); // Printing: vuelointemporal.odt in Color\nm_printer.fax(book); // Faxing: vuelointemporal.odt\nm_printer.scan(book); // Scanning: vuelointemporal.odt"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/javascript/hectorio23.js",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23 \n\n\"use strict\";\n\n// Define una clase abstracta para la funcionalidad de impresión\nclass Printer {\n    print() {\n        throw new Error(\"[+] - Este método debe ser implementado por una subclase.\");\n    }\n}\n\n// Define una clase abstracta para la funcionalidad de escaneo\nclass Scanner {\n    scan() {\n        throw new Error(\"[+] - Este método debe ser implementado por una subclase.\");\n    }\n}\n\n// Define una clase abstracta para la funcionalidad de fax\nclass Fax {\n    fax() {\n        throw new Error(\"[+] - Este método debe ser implementado por una subclase.\");\n    }\n}\n\n// Implementa una impresora en blanco y negro que solo necesita la interfaz de impresión\nclass BlackAndWhitePrinter extends Printer {\n    print() {\n        return \"[+] - Imprimiendo en blanco y negro\";\n    }\n}\n\n// Implementa una impresora a color que solo necesita la interfaz de impresión\nclass ColorPrinter extends Printer {\n    print() {\n        return \"[+] - Imprimiendo en color\";\n    }\n}\n\n// Implementa una impresora multifunción que necesita todas las interfaces: impresión, escaneo y fax\nclass MultiFunctionPrinter extends Printer {\n    print() {\n        return \"[+] - Imprimiendo en multifunción\";\n    }\n    scan() {\n        return \"[+] - Escaneando en multifunción\";\n    }\n    fax() {\n        return \"[+] - Enviando fax en multifunción\";\n    }\n}\n\n// Función que prueba la funcionalidad de impresión de una impresora\nfunction testPrinter(printer) {\n    console.log(printer.print());\n}\n\n// Función que prueba la funcionalidad de escaneo de un escáner\nfunction testScanner(scanner) {\n    console.log(scanner.scan());\n}\n\n// Función que prueba la funcionalidad de fax de un dispositivo de fax\nfunction testFax(fax) {\n    console.log(fax.fax());\n}\n\n// Crear instancias de las impresoras\nconst b_and_w_printer = new BlackAndWhitePrinter();\nconst color_printer = new ColorPrinter();\nconst multi_printer = new MultiFunctionPrinter();\n\n// Probar las impresoras\ntestPrinter(b_and_w_printer);\ntestPrinter(color_printer);\ntestPrinter(multi_printer);\ntestScanner(multi_printer);\ntestFax(multi_printer);\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n___________________________________________________\n#29 SOLID: PRINCIPIO DE SEGREGACIÓN DE INTERFACES (ISP)\n---------------------------------------------------\n * EJERCICIO:\n * Explora el \"Principio SOLID de Segregación de Interfaces (Interface Segregation Principle, ISP)\"\n * y crea un ejemplo simple donde se muestre su funcionamiento de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un gestor de impresoras.\n * Requisitos:\n * 1. Algunas impresoras sólo imprimen en blanco y negro.\n * 2. Otras sólo a color.\n * 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n * Instrucciones:\n * 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n * 2. Aplica el ISP a la implementación.\n * 3. Desarrolla un código que compruebe que se cumple el principio.\n*/\n// ________________________________________________________\n// Abstracciones\nclass AbsPlayable {\n    play() {\n        throw new Error(\"El método 'play' debe ser implementado.\");\n    }\n}\n\nclass AbsDisplayable {\n    display() {\n        throw new Error(\"El método 'display' debe ser implementado.\");\n    }\n}\n\n//__________________________\n// Implementar abstracciones\n\nclass Speaker extends AbsPlayable {\n    play() {\n        console.log(\"El altavoz está reproduciendo música.\");\n    }\n}\n\nclass Phone extends AbsPlayable {\n    play() {\n        console.log(\"El teléfono está reproduciendo música.\");\n    }\n}\n\nObject.assign(Phone.prototype, AbsDisplayable.prototype);\n\nPhone.prototype.display = function() {\n    console.log(\"El teléfono está mostrando la pantalla de reproducción.\");\n};\n\n//__________________________\n// Utilización\nconst speaker = new Speaker();\nspeaker.play();\n\nconst phone = new Phone();\nphone.play();\nphone.display();\n\n// ________________________________________________________\n// DIFICULTAD EXTRA\n// ----------------\n\n// Abstracciones\nclass AbsPrinter {\n    printFile(file) {\n        throw new Error(\"El método 'printFile' debe ser implementado.\");\n    }\n}\n\nclass AbsScanner {\n    toScan(pathSave) {\n        throw new Error(\"El método 'toScan' debe ser implementado.\");\n    }\n}\n\nclass AbsFax {\n    sendFile(file, phoneNumber) {\n        throw new Error(\"El método 'sendFile' debe ser implementado.\");\n    }\n}\n\n//__________________________\n// Implementar abstracciones\nclass MonoPrinter extends AbsPrinter {\n    printFile(file) {\n        console.log(\"\\nImpresora blanco y negro:\");\n        console.log(`${file} se imprimió.`);\n    }\n}\n\nclass ColorPrinter extends AbsPrinter {\n    printFile(file) {\n        console.log(\"\\nImpresora a color:\");\n        console.log(`${file} se imprimió.`);\n    }\n}\n\nclass Scanner extends AbsScanner {\n    toScan(pathSave) {\n        console.log(\"\\nEscaneo realizado, Guardado en:\", pathSave);\n    }\n}\n\nclass Fax extends AbsFax {\n    sendFile(file, phoneNumber) {\n        console.log(`\\n- ${file} fue enviado a: ${phoneNumber}`);\n    }\n}\n\nclass MultiFunctionPrinter {\n    constructor() {\n        this.monoPrinter = new MonoPrinter();\n        this.colorPrinter = new ColorPrinter();\n        this.scanner = new Scanner();\n        this.fax = new Fax();\n    }\n}\n\n//__________________________\n// Utilización\nconsole.log(\"\\nDIFICULTAD EXTRA\");\n\nconst monoPrinter = new MonoPrinter();\nmonoPrinter.printFile(\"filex.pdf\");\n\nconst colorPrinter = new ColorPrinter();\ncolorPrinter.printFile(\"filex.pdf\");\n\nconst scanner = new Scanner();\nscanner.toScan(\"c:\\\\docs\");\n\nconst fax = new Fax();\nfax.sendFile(\"filex.pdf\", 12345678);\n\nconsole.log(\"\\n___________\\nMultifunción:\");\nconst multifunction = new MultiFunctionPrinter();\n\nmultifunction.monoPrinter.printFile(\"filex.pdf\");\nmultifunction.colorPrinter.printFile(\"filex.pdf\");\nmultifunction.scanner.toScan(\"c:\\\\docs\");\nmultifunction.fax.sendFile(\"filex.pdf\", 12345678);\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/javascript/nlarrea.js",
    "content": "/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Segregación de Interfaces (Interface Segregation Principle, ISP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un gestor de impresoras.\n * Requisitos:\n * 1. Algunas impresoras sólo imprimen en blanco y negro.\n * 2. Otras sólo a color.\n * 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n * Instrucciones:\n * 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n * 2. Aplica el ISP a la implementación.\n * 3. Desarrolla un código que compruebe que se cumple el principio.\n */\n\n\n// Incorrect\n\nclass WorkerInterface {\n    work() {}\n    eat() {}\n}\n\n\nclass HumanWrong extends WorkerInterface {\n    work() {}\n    eat() {}\n}\n\n\nclass RobotWrong extends WorkerInterface {\n    work() {}\n    eat() {/* Robots don't eat */}\n}\n\n\n// Correct\n\nclass WorkInterface {\n    work() {\n        console.log('Working');\n    }\n}\n\nclass EatInterface {\n    eat() {\n        console.log('Eating');\n    }\n}\n\n\nclass Human {\n    constructor() {\n        // Extend from multiple classes\n        this.workSuper = new WorkInterface()\n        this.eatSuper = new EatInterface()\n    }\n\n    work() {\n        this.workSuper.work()\n    }\n\n    eat() {\n        this.eatSuper.eat()\n    }\n}\n\nclass Robot extends WorkInterface {\n    work() {\n        super.work()\n    }\n}\n\n\nconst human = new Human()\nhuman.work()\nhuman.eat()\n\nconst robot = new Robot()\nrobot.work()\n\n\n/**\n * DIFICULTAD EXTRA (opcional):\n * Crea un gestor de impresoras.\n * Requisitos:\n * 1. Algunas impresoras sólo imprimen en blanco y negro.\n * 2. Otras sólo a color.\n * 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n * Instrucciones:\n * 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n * 2. Aplica el ISP a la implementación.\n * 3. Desarrolla un código que compruebe que se cumple el principio.\n */\n\n\nclass PrinterInterface {\n    print(document) {\n        console.log(`Printing (black & white): ${document}`);\n    }\n}\n\n\nclass ColorPrinterInterface {\n    printColor(document) {\n        console.log(`Printing (color): ${document}`);\n    }\n}\n\n\nclass ScannerInterface {\n    scan(document) {\n        console.log(`Scanning document: ${document}`);\n        return 'scanned' + document\n    }\n}\n\n\nclass FaxInterface {\n    sendFax(document) {\n        console.log(`Sending through fax: ${document}`);\n    }\n}\n\n\nclass Printer extends PrinterInterface {\n    print(document) {\n        super.print(document);\n    }\n}\n\n\nclass ColorPrinter extends ColorPrinterInterface {\n    printColor(document) {\n        super.printColor(document)\n    }\n}\n\n\nclass MultifunctionPrinter {\n    // Private properties -> to use them only inside class\n    #printBW\n    #colorPrint\n    #scanner\n    #fax\n\n    constructor() {\n        this.#printBW = new PrinterInterface();\n        this.#colorPrint = new ColorPrinterInterface();\n        this.#scanner = new ScannerInterface();\n        this.#fax = new FaxInterface();\n    }\n\n    print(document) {\n        this.#printBW.print(document);\n    }\n\n    printColor(document) {\n        this.#colorPrint.printColor(document);\n    }\n\n    scan(document) {\n        return this.#scanner.scan(document);\n    }\n\n    sendFax(document) {\n        this.#fax.sendFax(document);\n    }\n}\n\n\nlet doc = 'my-document.txt';\n\nconst printer = new Printer();\nprinter.print(doc);\n\nconst colorPrinter = new ColorPrinter();\ncolorPrinter.printColor(doc);\n\n\ndoc = 'another-doc.txt';\n\nconst multifunctionPrinter = new MultifunctionPrinter();\nmultifunctionPrinter.print(doc);\nmultifunctionPrinter.printColor(doc);\nmultifunctionPrinter.scan(doc);\nmultifunctionPrinter.sendFax(doc);"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/javascript/parababire.js",
    "content": "// Incorrecto\n\n/* class Animal {\n  constructor(name) {\n    this.name = name\n    if (new.target === Animal) {\n      throw new Error('Animal es una interface y no puede ser instanciada')\n    }\n    if (!this.eat) {\n      throw new Error('Debe implimentar el método eat')\n    }\n    if (!this.fly) {\n      throw new Error('Debe implimentar el método fly')\n    }\n    if (!this.swim) {\n      throw new Error('Debe implimentar el método swim')\n    }\n  }\n}\n\nclass Fish extends Animal {\n  eat() {\n    console.log(`${this.name} is eating`)\n  }\n  swim() {\n    console.log(`${this.name} is swimming`)\n  }\n  fly() {\n    console.error(\"ERROR! Fishes can't fly\")\n  }\n}\n\nclass Bird extends Animal {\n  eat() {\n    console.log(`${this.name} is eating`)\n  }\n  swim() {\n    console.error(\"ERROR! Birds can't swim\");\n  }\n  fly() {\n    console.log(`${this.name} is flying`)\n  }\n}\n\nconst bird = new Bird('Titi the Parrot');\nbird.swim(); // ERROR! Birds can't swim\n\nconst fish = new Fish('Neo the Dolphin');\nfish.fly(); // ERROR! Fishes can't fly\n */\n// Correcto\n\nclass Swimmer {\n  constructor(name) {\n    this.name = name\n    if (new.target === Swimmer) {\n      throw new Error('Swimmer es una interface y no puede ser instanciada')\n    }\n    if (!this.swim) {\n      throw new Error('Debe implimentar el método swim')\n    }\n  }\n}\n\nclass Flyer {\n  constructor(name) {\n    this.name = name\n    if (new.target === Flyer) {\n      throw new Error('Flyer es una interface y no puede ser instanciada')\n    }\n    if (!this.fly) {\n      throw new Error('Debe implimentar el método eat')\n    }\n  }\n}\n\n// Implement interfaces for specific types of animals\n\nclass Bird extends Flyer {\n  constructor(name) {\n    super(name);\n  }\n  fly() {\n    console.log(`${this.name} is flying`);\n  }\n  eat() {\n    console.log(`${this.name} is eating`);\n  }\n}\n\nclass Fish extends Swimmer {\n  constructor(name) {\n    super(name);\n  }\n  swim() {\n    console.log(`${this.name} is swimming`);\n  }\n  eat() {\n    console.log(`${this.name} is eating`);\n  }\n}\n\n// Usage\n\nconst bird = new Bird('Titi the Parrot');\nbird.fly(); // Titi the Parrot is flying\nbird.eat(); // Titi the Parrot is eating\n\nconsole.log('\\n');\n\nconst fish = new Fish('Neo the Dolphin');\nfish.swim(); // Neo the Dolphin is swimming\nfish.eat(); // Neo the Dolphin is eating\n\n// Extra\n\nclass Printer {\n  constructor() {\n    if (new.target === Printer) {\n      throw new Error(\"Printer es una interface no puedes instanciarla.\")\n    }\n    if (!this.print) {\n      throw new Error(\"Debes implementar el método print\")\n    }\n  }\n}\n\nclass BlackAndWhitePrinter extends Printer {\n  print() {\n    console.log(\"Se imprime en blanco y negro.\")\n  }\n}\n\nclass ColorPrinter extends Printer {\n  print() {\n    console.log(\"Se imprime a color.\")\n  }\n}\n\nconst sendingFax = {\n  sendFax() {\n    console.log(\"Enviando fax.\")\n  }\n}\n\nconst scanner = {\n  scanning() {\n    console.log(\"Escaneando documento.\")\n  }\n}\n\nObject.assign(ColorPrinter.prototype, sendingFax)\nObject.assign(ColorPrinter.prototype, scanner)\n\nconst multifuncional = new ColorPrinter()\nmultifuncional.print()\nmultifuncional.sendFax()\nmultifuncional.scanning()\n\nfunction testInterface(object, interface) {\n  const prototypeProperties = Object.getOwnPropertyNames(interface.prototype)\n\n  for (const method of prototypeProperties) {\n    if (!object[method] || typeof object[method] !== 'function') {\n      throw new Error(`La clase no implementa el método ${method} de la interface.`)\n  }\n  }\n}\ntestInterface(multifuncional, Printer)"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/javascript/pedamoci.js",
    "content": "console.log('---------------------- ISP MAL HECHO ----------------------')\nclass WrongAnimal {\n  eat() {\n    console.log('Comiendo')\n  }\n  run() {\n    console.log('Corriendo')\n  }\n}\n\nclass WrongDog extends WrongAnimal {}\n\nclass WrongFish extends WrongAnimal {\n  run() {\n    try {\n      throw new Error(\"Un pez no puede correr\")\n    } catch (e) {\n      console.log(e.message)\n    }\n  }\n}\n\nconst wrongDog = new WrongDog\nconst wrongFish = new WrongFish\n\nwrongDog.eat()\nwrongDog.run()\n\nwrongFish.eat()\nwrongFish.run()\n\nconsole.log('\\n---------------------- ISP BIEN HECHO ----------------------')\nconst canEat = {\n  eat() { console.log('Comiendo') }\n}\n\nconst canRun = {\n  run() { console.log('Corriendo') }\n}\n\nclass Dog {\n  constructor() {\n    Object.assign(this, canEat, canRun)\n  }\n}\n\nclass Fish {\n  constructor() {\n    Object.assign(this, canEat)\n  }\n}\n\nconst dog = new Dog\nconst fish = new Fish\n\ndog.eat()\ndog.run()\n\nfish.eat()\n\n// ------------------------------------------ DIFICULTAD EXTRA ------------------------------------------\nconst colors = {\n  ROJO: \"\\x1b[31m\",\n  VERDE: \"\\x1b[32m\",\n  AMARILLO: \"\\x1b[33m\",\n  AZUL: \"\\x1b[34m\",\n  MAGENTA: \"\\x1b[35m\",\n  CIAN: \"\\x1b[36m\",\n  RESET: \"\\x1b[0m\"\n}\n\nconst printWhiteBlack = {\n  print(text) {\n    console.log('Imprimiendo...')\n    return new Promise(resolve => {\n      setTimeout(() => {\n        console.log(text)\n        resolve()\n      }, 1500);\n    })\n  }\n}\n\nconst printColor = {\n  print(text, color) {\n    console.log('Imprimiendo...')\n    return new Promise(resolve => {\n      setTimeout(() => {\n        switch (color) {\n          case 'rojo':\n            console.log(`${colors.ROJO}${text}${colors.RESET}`)\n            resolve()\n            break\n          case 'verde':\n            console.log(`${colors.VERDE}${text}${colors.RESET}`)\n            resolve()\n            break\n          case 'amarillo':\n            console.log(`${colors.AMARILLO}${text}${colors.RESET}`)\n            resolve()\n            break\n          case 'azul':\n            console.log(`${colors.AZUL}${text}${colors.RESET}`)\n            resolve()\n            break\n          case 'magenta':\n            console.log(`${colors.MAGENTA}${text}${colors.RESET}`)\n            resolve()\n            break\n          case 'cian':\n            console.log(`${colors.CIAN}${text}${colors.RESET}`)\n            resolve()\n            break\n          default: console.warn('Ese color no esta disponible')\n            resolve()\n            break\n        }\n      }, 1500);\n    })\n  }\n}\n\nconst hasScan = {\n  scan() {\n    console.log('Escaneando...')\n    return new Promise(resolve => {\n    setTimeout(() => {\n      this.text = 'EJERCICIO:\\n' +\n                  'Explora el \"Principio SOLID de Segregación de Interfaces\\n' +\n                  '(Interface Segregation Principle, ISP)\", y crea un ejemplo\\n' +\n                  'simple donde se muestre su funcionamiento de forma correcta e incorrecta.\\n' +\n\n                  '\\nDIFICULTAD EXTRA (opcional):\\n' +\n                  'Crea un gestor de impresoras.\\n' +\n                  'Requisitos:\\n' +\n                  '1. Algunas impresoras sólo imprimen en blanco y negro.\\n' +\n                  '2. Otras sólo a color.\\n' +\n                  '3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\\n' +\n                  'Instrucciones:\\n' +\n                  '1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\\n' +\n                  '2. Aplica el ISP a la implementación.\\n' +\n                  '3. Desarrolla un código que compruebe que se cumple el principio.'\n      console.log('El scaneo a terminado')\n      resolve()\n    }, 2500)\n    })\n  }\n}\n\nconst hasFax = {\n  sendFax() {\n    console.log('Enviando...')\n    return new Promise(resolve => {\n      setTimeout(() => {\n        console.log('Se ha emviado el fax')\n        resolve()\n      }, 4000);\n    })\n  } \n}\n\nclass PrinterWhiteBlack {\n  constructor() {\n    Object.assign(this, printWhiteBlack)\n  }\n}\n\nclass PrinterColor {\n  constructor() {\n    Object.assign(this, printColor)\n  }\n}\n\nclass PrinterWhiteBlackScanFax {\n  constructor() {\n    Object.assign(this, printWhiteBlack, hasScan, hasFax)\n    this.text = ''\n  }\n}\n\nclass PrinterColorScanFax {\n  constructor() {\n    Object.assign(this, printColor, hasScan, hasFax)\n    this.text = ''\n  }\n}\n\nconst printerWhiteBlack = new PrinterWhiteBlack\n\nconst printerColor = new PrinterColor\n\nconst printerWhiteBlackScanFax = new PrinterWhiteBlackScanFax\n\nconst printerColorScanFax = new PrinterColorScanFax\n\nasync function program() {\n  console.log('voy a escanear un texto con printerColorScanFax')\n  await printerColorScanFax.scan()\n\n  console.log('voy a enviar un fax con printerWhiteBlackScanFax')\n  await printerWhiteBlackScanFax.sendFax('Te mando este fax desde una impresora que solo imprime en blanco y negro')\n\n  console.log('voy a imprimir con printColor y printWhiteBlack')\n  await Promise.all([printColor.print('imprimiendo en color cian', 'cian'), printWhiteBlack.print('imprimiendo en blanco y negro')]) \n\n  console.log('voy a imprimir el texto escaneado con printerColorScanFax')\n  await printerColorScanFax.print(printerColorScanFax.text, 'magenta')\n}\nprogram()"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/javascript/victor-Casta.js",
    "content": "/*\n  * EJERCICIO:\n  * Explora el \"Principio SOLID de Segregación de Interfaces (Interface Segregation Principle, ISP)\"\n  * y crea un ejemplo simple donde se muestre su funcionamiento de forma correcta e incorrecta.\n*/\n\n// Forma incorrecta\n/*\n  class Animal {\n    fly() {\n      console.log(\"Volar\")\n    }\n\n    swim() {\n      console.log(\"Nadar\")\n    }\n\n    walk() {\n      console.log(\"Caminar\")\n    }\n  }\n\n  class Bird extends Animal {\n    fly() {\n      console.log(\"Volar\")\n    }\n  }\n\n  class Fish extends Animal {\n    swim() {\n      console.log(\"Nadar\")\n    }\n  }\n\n  class Dog extends Animal {\n    walk() {\n      console.log(\"Caminar\")\n    }\n    fly() {\n      throw new Error(\"No puede volar\")\n    }\n  }\n\n  const bird = new Bird()\n  bird.fly()\n\n  const fish = new Fish()\n  fish.swim()\n\n  const dog = new Dog()\n  dog.walk()\n\n  dog.fly()\n*/\n\n// Forma correcta\n\nclass AnimalCanFly {\n  fly() {\n    console.log(\"Volar\")\n  }\n}\n\nclass AnimalCanSwim {\n  swim() {\n    console.log(\"Nadar\")\n  }\n}\n\nclass AnimalCanWalk {\n  walk() {\n    console.log(\"Caminar\")\n  }\n}\n\nclass Bird extends AnimalCanFly {\n  fly() {\n    console.log(\"Volar\")\n  }\n}\n\nclass Fish extends AnimalCanSwim {\n  swim() {\n    console.log(\"Nadar\")\n  }\n}\n\nclass Dog extends AnimalCanWalk {\n  walk() {\n    console.log(\"Caminar\")\n  }\n}\n\nconst bird = new Bird()\nconst fish = new Fish()\nconst dog = new Dog()\n\nbird.fly()\nfish.swim()\ndog.walk()\n\n/*\n  * DIFICULTAD EXTRA (opcional):\n  * Crea un gestor de impresoras.\n  * Requisitos:\n  * 1. Algunas impresoras sólo imprimen en blanco y negro.\n  * 2. Otras sólo a color.\n  * 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n  * Instrucciones:\n  * 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n  * 2. Aplica el ISP a la implementación.\n  * 3. Desarrolla un código que compruebe que se cumple el principio.\n*/\n\nclass Printable {\n  print(document) {\n    console.log(`Printing ${document}`)\n  }\n}\n\nclass Scannable {\n  scan(document) {\n    console.log(`Scanning ${document}`)\n  }\n}\n\nclass Faxable {\n  sendFax(document) {\n    console.log(`Sending ${document}`)\n  }\n}\n\nclass BlackAndWhitePrinter extends Printable {}\nclass ColorPrinter extends Printable {}\nclass MultifunctionalPrinter extends Printable {\n  constructor() {\n    super()\n    this.scanner = new Scannable()\n    this.fax = new Faxable()\n  }\n\n  scan(document) {\n    this.scanner.scan(document)\n  }\n\n  sendFax(document) {\n    this.fax.sendFax(document)\n  }\n}\n\nconst bwPrinter = new BlackAndWhitePrinter()\nbwPrinter.print(\"Document1\")\n\nconst colorPrinter = new ColorPrinter()\ncolorPrinter.print(\"Document2\")\n\nconst multiPrinter = new MultifunctionalPrinter()\nmultiPrinter.print(\"Document3\")\nmultiPrinter.scan(\"Document3\")\nmultiPrinter.sendFax(\"Document3\")"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/kotlin/blackriper.kt",
    "content": "/*\r\nInterface Segregation Principle\r\n\r\nEste principio nos dice que una clase nunca debe extender de interfaces con métodos que no usa,\r\npor el principio de segregación de interfaces busca que las interfaces sean lo más pequeñas\r\ny específicas posible de modo que cada clase solo implemente los métodos que necesita.\r\n\r\nerrores comunes con este principio\r\n\r\n- Estaremos violando este principio si Tenemos clases que implementan métodos de interfaces que no se usan.\r\n\r\n- Definimos interfaces con parámetros que no se van a utilizar en todas las clases\r\n\r\n-cuando tenemos interfaces muy grandes y métodos que no son genéricos y que otras clases que implementen esta interfaz no puedan usar\r\n\r\n*/\r\n\r\n//ejemplo de lo que no debe de hacerce\r\n\r\n\r\ninterface Bank {\r\n    fun deposit(amount: Double)\r\n    fun withdraw(amount: Double)\r\n    fun getBalance()\r\n}\r\n\r\nclass AccountNormal(private var balance: Double):Bank{\r\n    override fun deposit(amount: Double) {\r\n        balance+=amount\r\n    }\r\n\r\n    override fun withdraw(amount: Double) {\r\n        balance-=amount\r\n    }\r\n\r\n    override fun getBalance() {\r\n        println(\"the balance is $balance\")\r\n    }\r\n\r\n}\r\n// esta cuenta solo es de imversion y esta no pueda hacer retiros por lo tanto rompe este principio\r\n// porque solo retornamos el error\r\nclass InterestAccount(private var balance: Double):Bank {\r\n    override fun deposit(amount: Double) {\r\n        balance += amount\r\n    }\r\n\r\n    override fun withdraw(amount: Double) {\r\n        throw Exception(\"not allowed this operation\")\r\n    }\r\n\r\n    override fun getBalance() {\r\n        println(\"the balance is $balance\")\r\n    }\r\n}\r\n\r\n// lo que debe de hacerce\r\n\r\n// quitamos el metodo que solo se permite  en las dos clases\r\ninterface LspBank{\r\n    fun deposit(amount: Double)\r\n    fun getBalance()\r\n}\r\n//las inferfaces pueden extender de otras interfaces ahora este inferfaz hija herera los metodos del padre\r\n// pero agrega la fucnionalidad de withdraw\r\ninterface LspNormalBank : LspBank{\r\n    fun withdraw(amount: Double)\r\n}\r\n\r\nclass NormalAccountLsp(private var balance: Double):LspNormalBank {\r\n    override fun withdraw(amount: Double) {\r\n        balance -= amount\r\n    }\r\n\r\n    override fun deposit(amount: Double) {\r\n        balance += amount\r\n    }\r\n\r\n    override fun getBalance() {\r\n        println(\"the balance is $balance\")\r\n    }\r\n}\r\n\r\nclass InterestAccountLsp(private var balance: Double):LspBank {\r\n    override fun deposit(amount: Double) {\r\n        balance += amount\r\n    }\r\n\r\n    override fun getBalance() {\r\n        println(\"the balance is $balance\")\r\n    }\r\n}\r\n\r\nfun exmapleLsp(){\r\n    val normal = NormalAccountLsp(100.0)\r\n    normal.deposit(100.0)\r\n    normal.getBalance()\r\n    normal.withdraw(50.0)\r\n    normal.getBalance()\r\n\r\n    val inv = InterestAccountLsp(100.0)\r\n    inv.deposit(100.0)\r\n    inv.getBalance()\r\n\r\n    println(\"violation this principle\")\r\n    // clase  que  viola esta principio\r\n    val interest = InterestAccount(100.0)\r\n    interest.deposit(100.0)\r\n    interest.getBalance()\r\n    // me veo forzado a chacar el error\r\n    runCatching { interest.withdraw(50.0)}.let { println(it.exceptionOrNull()?.message) }\r\n    interest.getBalance()\r\n}\r\n\r\n//ejercicio extra\r\n\r\nenum class ColorPrint{\r\n    BLACK_AND_WHITE,\r\n    COLOR\r\n}\r\n\r\ninterface Printer{\r\n    fun print(document:String)\r\n}\r\n\r\n// aplicando el principio de ISP para crear una nueva interfaz cuando esta tenga multiples funciones\r\ninterface MultiFunctionPrinter : Printer{\r\n    fun sendFax(document:String):Boolean\r\n    fun scan(document:String)\r\n}\r\n\r\nclass NormalPrinter(val color:ColorPrint):Printer{\r\n    override fun print(document: String) {\r\n        println(\"Printing $document in color: $color\")\r\n    }\r\n\r\n }\r\n\r\nclass MultiFuncPrinter(val color:ColorPrint):MultiFunctionPrinter {\r\n    override fun sendFax(document: String): Boolean {\r\n        if (document.isNotEmpty()){\r\n            println(\"Sending $document by fax\")\r\n            return true\r\n        }\r\n        return false\r\n    }\r\n\r\n    override fun scan(document: String) {\r\n        document.isNotEmpty().run {\r\n            println(\"Scanning $document\")\r\n        }\r\n    }\r\n\r\n    override fun print(document: String) {\r\n        println(\"Printing $document in color: $color\")\r\n    }\r\n}\r\n\r\nfun pritingDocument(printer:Printer, document:String){\r\n    printer.print(document)\r\n}\r\n\r\nfun examplePrinter(){\r\n    val normalPrinter = NormalPrinter(ColorPrint.BLACK_AND_WHITE)\r\n    pritingDocument(normalPrinter,\"Hello World\")\r\n    val multiFuncPrinter = MultiFuncPrinter(ColorPrint.COLOR)\r\n    pritingDocument(multiFuncPrinter,\"Kotlin is son of Java\")\r\n    multiFuncPrinter.sendFax(\"Hello Comunity\")\r\n    multiFuncPrinter.scan(\"Hello World\")\r\n}\r\n\r\n\r\nfun main() {\r\n    exmapleLsp()\r\n    examplePrinter()\r\n}"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/kotlin/eulogioep.kt",
    "content": "/*\n * Principio de Segregación de Interfaces (ISP)\n * \n * El ISP establece que ningún cliente debe ser forzado a depender de métodos\n * que no utiliza. Sugiere dividir interfaces grandes en otras más pequeñas\n * y específicas para que los clientes solo tengan que conocer los métodos\n * que realmente necesitan.\n */\n\n// Interfaces segregadas\ninterface Impresora {\n    fun imprimir(documento: String)\n}\n\ninterface ImpresoraColor : Impresora {\n    fun imprimirColor(documento: String)\n}\n\ninterface Escaner {\n    fun escanear(documento: String): String\n}\n\ninterface Fax {\n    fun enviarFax(documento: String)\n}\n\n// Implementaciones\nclass ImpresoraBasica : Impresora {\n    override fun imprimir(documento: String) {\n        println(\"Imprimiendo en blanco y negro: $documento\")\n    }\n}\n\nclass ImpresoraAColor : ImpresoraColor {\n    override fun imprimir(documento: String) {\n        println(\"Imprimiendo en blanco y negro: $documento\")\n    }\n\n    override fun imprimirColor(documento: String) {\n        println(\"Imprimiendo en color: $documento\")\n    }\n}\n\nclass ImpresoraMultifuncion : ImpresoraColor, Escaner, Fax {\n    override fun imprimir(documento: String) {\n        println(\"Imprimiendo en blanco y negro: $documento\")\n    }\n\n    override fun imprimirColor(documento: String) {\n        println(\"Imprimiendo en color: $documento\")\n    }\n\n    override fun escanear(documento: String): String {\n        println(\"Escaneando: $documento\")\n        return \"Documento escaneado: $documento\"\n    }\n\n    override fun enviarFax(documento: String) {\n        println(\"Enviando fax: $documento\")\n    }\n}\n\n// Gestor de impresoras\nclass GestorImpresoras {\n    fun imprimirDocumento(impresora: Impresora, documento: String) {\n        impresora.imprimir(documento)\n    }\n\n    fun imprimirDocumentoColor(impresora: ImpresoraColor, documento: String) {\n        impresora.imprimirColor(documento)\n    }\n\n    fun escanearDocumento(escaner: Escaner, documento: String): String {\n        return escaner.escanear(documento)\n    }\n\n    fun enviarFax(fax: Fax, documento: String) {\n        fax.enviarFax(documento)\n    }\n}\n\n// Función principal para probar el sistema\nfun main() {\n    val gestorImpresoras = GestorImpresoras()\n    val impresoraBasica = ImpresoraBasica()\n    val impresoraColor = ImpresoraAColor()\n    val multifuncion = ImpresoraMultifuncion()\n\n    println(\"Prueba de Impresora Básica:\")\n    gestorImpresoras.imprimirDocumento(impresoraBasica, \"Documento en blanco y negro\")\n\n    println(\"\\nPrueba de Impresora a Color:\")\n    gestorImpresoras.imprimirDocumento(impresoraColor, \"Documento en blanco y negro\")\n    gestorImpresoras.imprimirDocumentoColor(impresoraColor, \"Documento en color\")\n\n    println(\"\\nPrueba de Impresora Multifunción:\")\n    gestorImpresoras.imprimirDocumento(multifuncion, \"Documento en blanco y negro\")\n    gestorImpresoras.imprimirDocumentoColor(multifuncion, \"Documento en color\")\n    gestorImpresoras.escanearDocumento(multifuncion, \"Documento para escanear\")\n    gestorImpresoras.enviarFax(multifuncion, \"Documento para enviar por fax\")\n}"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/kotlin/rikmij.kt",
    "content": "fun main() {\n    //Uso Incorrecto\n    abstract class Aveh {\n        abstract fun walk(): String\n        abstract fun fly(): String\n    }\n    class Bird_: Aveh() {\n        override fun walk() = \"Estoy andando\"\n        override fun fly() = \"Estoy volando\"\n    }\n    class Penguin_: Aveh() {\n        override fun walk() = \"Estoy andando\"\n        override fun fly() = \"Estoy volando\"\n    }\n    val bird_ = Bird_()\n    println(bird_.walk())\n    val penguin_ = Penguin_()\n    println(penguin_.fly())\n    /*\n    Es incorrecto porque los pingünos no vuelan. Para que se de este principio tienen que venir de una clase\n    con métodos generales y cada subclase sus métodos específicos\n     */\n\n    //Uso correcto\n    abstract class Ave {\n        abstract fun walk(): String\n    }\n    class Bird: Ave() {\n        override fun walk() = \"Estoy andando\"\n        fun fly() = \"Estoy volando\"\n    }\n    class Penguin: Ave() {\n        override fun walk() = \"Estoy andando\"\n        fun swim() = \"Estoy nadando\"\n    }\n    val bird = Bird()\n    println(bird.fly())\n    val penguin = Penguin()\n    println(penguin.swim())\n    /*\n    Así es correcto porque la interfaz tiene los métodos generales y ya las subclases hacen lo que\n    sea específico de éstas más lo que herede.\n     */\n\n    println(\"\\n${\"*\".repeat(7)} EJERCICIO EXTRA ${\"*\".repeat(7)}\")\n    class PrinterByW: Printer {\n        override fun print(doc: String): String {\n            return \"Ha elegido impresión en blanco y negro. Imprimiendo '$doc'\"\n        }\n    }\n    class PrinterColor: Printer {\n        override fun print(doc: String): String {\n            return \"Ha elegido impresión a color. Imprimiendo '$doc'\"\n        }\n    }\n    class MultiPrinter: PrinterFunctions {\n        override fun print(doc: String): String {\n            return \"Imprimiendo $doc\"\n        }\n\n        //scan y sendFax están definidas en la interface y si no van a tener\n        //modificaciones, no es necesarios sobreescribirlas\n    }\n\n    val doc1 = PrinterByW()\n    println(doc1.print(\"El Quijote\"))\n    val doc2 = PrinterColor()\n    println(doc2.print(\"La Celestina\"))\n    val doc3 = MultiPrinter()\n    println(doc3.scan(\"Apuntes Matemáticas\"))\n    println(doc3.sendFax(\"Documento_Secreto\", 321456780))\n\n}\n\ninterface Printer {\n    fun print(doc: String): String\n}\n\ninterface PrinterFunctions: Printer {\n    fun scan(doc: String): String {\n        return \"Escaneando $doc\"\n    }\n    fun sendFax(doc: String, fax: Int): String {\n        return \"Enviando $doc al fax $fax\"\n    }\n}\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/ocaml/luishendrix92.ml",
    "content": "(******************************************************************************)\n(*                                                                            *)\n(*                      Interface Segregation Principle                       *)\n(*                                                                            *)\n(*  The core concept of this principle (the 'I' in {b SOLID}) is, a class     *)\n(*  should not be forced to implement methods that it doesn't need, caused    *)\n(*  by the implementation of a broad interface, or inheriting from a general  *)\n(*  abstract class that covers more ground than it should.                    *)\n(*                                                                            *)\n(*  The proposed solution is to create smaller interfaces that are only im-   *)\n(*  plemented if the class needs those methods and/or members and only        *)\n(*  inherit from a base class that won't force unwanted implementations. It   *)\n(*  goes hand in hand with the Liskov-Substitution Principle as it helps      *)\n(*  reduce the amount of exceptions thrown.                                   *)\n(*                                                                            *)\n(******************************************************************************)\n\nopen Printf\n\n(* This interface violates the ISP because if implemented by a specific type of\n   coffee machine, it will be forced to implement methods that it doesn't need\n   and thus it'll need to either throw an exception or provide a NoOP body. *)\nclass type coffee_machine_violating_isp = object\n  method drip_brew : unit\n  method replace_filter : unit\n  method steam_milk : unit\n  method pressure_brew : unit\n  method add_ground_coffee : unit\nend\n\nclass type coffee_machine = object\n  method brew : unit\n  method add_ground_coffee : unit\nend\n\nclass type drip = object\n  (* Inheriting a class type from another class type in OCaml is the same\n     as extending an interface in OOP languages. Though we can't implement\n     multiple interfaces, we can in fact inherit from multiple classes! *)\n  inherit coffee_machine\n  method drip_brew : unit\n  method replace_filter : unit\nend\n\nclass type espresso = object\n  inherit coffee_machine\n  method steam_milk : unit\n  method pressure_brew : unit\nend\n\nclass drip_machine : drip =\n  object (self)\n    method private drip_brew = print_endline \"Brewing through a paper filter...\"\n\n    method add_ground_coffee =\n      print_endline \"Adding ground coffee to drip coffee machine...\"\n\n    method replace_filter = print_endline \"Replacing paper filter...\"\n    method brew = self#drip_brew\n  end\n\nclass espresso_machine : espresso =\n  object (self)\n    method private pressure_brew =\n      print_endline \"Brewing through an espresso portafilter...\"\n\n    method add_ground_coffee =\n      print_endline\n        \"Adding and compressing ground coffee to espresso machine...\"\n\n    method steam_milk = print_endline \"Steaming milk for latte art...\"\n    method brew = self#pressure_brew\n  end\n\nlet _ =\n  let oster_drip : drip_machine = new drip_machine in\n  let barista : espresso_machine = new espresso_machine in\n  oster_drip#add_ground_coffee;\n  oster_drip#brew;\n  oster_drip#replace_filter;\n  barista#add_ground_coffee;\n  barista#brew;\n  barista#steam_milk\n;;\n\n(******************************************************************************)\n(*                                                                            *)\n(*                        Dificultad Extra (Opcional)                         *)\n(*                                                                            *)\n(*  Crea un gestor de impresoras.                                             *)\n(*  Requisitos:                                                               *)\n(*  1. Algunas impresoras solo imprimen en blanco y negro.                    *)\n(*  2. Otras solo a color.                                                    *)\n(*  3. Otras son multifunción, pueden imprimir, escanear y enviar fax.        *)\n(*  Instrucciones:                                                            *)\n(*  1. Implementan el sistema, con los diferentes tipos de impresoras y fun-  *)\n(*     ciones.                                                                *)\n(*  2. Aplica el ISP a la implementación.                                     *)\n(*  3. Desarrolla un código que compruebe que se cumple el principio.         *)\n(*                                                                            *)\n(******************************************************************************)\n\nclass virtual black_white_printing =\n  object\n    method virtual print_b_and_w : string -> unit\n  end\n\nclass virtual color_printing =\n  object\n    method virtual print_color : string -> unit\n  end\n\nclass virtual fax (number : string) =\n  object\n    val phone_number = number\n    method virtual send_document : string -> string -> unit\n  end\n\nclass virtual scanner =\n  object\n    method virtual scan_document : string -> unit\n  end\n\nclass bw_printer =\n  object\n    inherit black_white_printing\n\n    method print_b_and_w docfile =\n      printf \"Printing [%s] in black and white...\\n\" docfile\n  end\n\nclass color_printer =\n  object\n    inherit color_printing\n\n    method print_color docfile =\n      printf \"Printing [%s] in CYMK color...\\n\" docfile\n  end\n\nclass multifunctional_printer (number : string) =\n  object (self)\n    (* As I mentioned before, OCaml's class system offers multiple inheritance\n       but I could have also made them interfaces (class types) and in order to\n       create an interface that 'implements' all of them we could have done:\n\n       {[\n         class multifunctional_printer (number : string) : object\n           inherit color_printing\n           inherit black_white_printing\n           inherit scanner\n           inherit fax\n         end = object (self) end\n       ]}\n\n       This way we'd be forced to implement all of those methods but with one\n       catch: using class types 'seals' a class, meaning we can't expose more\n       public methods other than the ones in the interface.\n    *)\n    inherit color_printing\n    inherit black_white_printing\n    inherit scanner\n    inherit fax number\n\n    method scan_document docfile =\n      printf \"Scanning [%s] with a multifunctional\\n\" docfile\n\n    method send_document docfile destination_number =\n      printf\n        \"Sending [%s] from #%s to fax #%s through a multifunctional\\n\"\n        docfile\n        phone_number\n        destination_number\n\n    method private print_b_and_w docfile =\n      printf\n        \"Printing [%s] in black and white using a multifunctional\\n\"\n        docfile\n\n    method private print_color docfile =\n      printf \"Printing [%s] in CYMK color using a multifunctional\\n\" docfile\n\n    method print ?(use_color = true) docfile =\n      if use_color then self#print_color docfile else self#print_b_and_w docfile\n  end\n\nlet _ =\n  let compaq_bw = new bw_printer in\n  let epson_color = new color_printer in\n  let epson_mf = new multifunctional_printer \"664-934-1295\" in\n  compaq_bw#print_b_and_w \"2024report.xlsx\";\n  epson_color#print_color \"wedding_album.pdf\";\n  epson_mf#print ~use_color:false \"essat.docx\";\n  epson_mf#send_document \"private_letter.txt\" \"55-676-2424\";\n  epson_mf#scan_document \"ocr_test.jpg\"\n;;\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/php/miguelex.php",
    "content": "<?php\n\n// Ejemplo basico sin ISP\n\ninterface PaymentInterface {\n    public function payOnline($amount);\n    public function payInCash($amount);\n}\n\nclass OnlinePayment implements PaymentInterface {\n    public function payOnline($amount) {\n        echo \"Procesando el pago online de \" . $amount . \" €\\n\";\n    }\n\n    public function payInCash($amount) {\n        throw new Exception(\"El pago Online no admite el pago en efectivo\");\n    }\n}\n\nclass CashPayment implements PaymentInterface {\n    public function payOnline($amount) {\n        throw new Exception(\"El pago en efectivo no permite el pago por medios online\");\n    }\n\n    public function payInCash($amount) {\n        echo \"Procesando el pago en efectivo de \" . $amount. \" €\\n\";\n    }\n}\n\necho \"\\n Ejemplo basico sin ISP\\n\";\n$onlinePayment = new OnlinePayment();\n$cashPayment = new CashPayment();\n\n$onlinePayment->payOnline(100);\n//$onlinePayment->payInCash(100); \n\n//$cashPayment->payOnline(100); \n$cashPayment->payInCash(100);\n\n// Ejemplo basico aplicando ISP\n\ninterface OnlinePaymentInterface {\n    public function payOnline($amount);\n}\n\ninterface CashPaymentInterface {\n    public function payInCash($amount);\n}\n\nclass OnlinePayment2 implements OnlinePaymentInterface {\n    public function payOnline($amount) {\n        echo \"Procesando el pago online de \" . $amount. \" €\\n\";\n    }\n}\n\nclass CashPayment2 implements CashPaymentInterface {\n    public function payInCash($amount) {\n        echo \"Procesando el pago en efectivo de \" . $amount. \" €\\n\";\n    }\n}\n\necho \"\\n Ejemplo basico con ISP\\n\";\n$onlinePayment = new OnlinePayment2();\n$cashPayment = new CashPayment2();\n\n$onlinePayment->payOnline(100);\n\n$cashPayment->payInCash(100);\n\n// Extra\n\ninterface BlackAndWhitePrintInterface {\n    public function printBlackAndWhite($document);\n}\n\ninterface ColorPrintInterface {\n    public function printColor($document);\n}\n\ninterface ScanInterface {\n    public function scan($document);\n}\n\ninterface FaxInterface {\n    public function sendFax($document);\n}\n\nclass BlackAndWhitePrinter implements BlackAndWhitePrintInterface {\n    public function printBlackAndWhite($document) {\n        echo \"Imprimiendo el documento \" . $document . \" en ByN\\n\";\n    }\n}\n\nclass ColorPrinter implements ColorPrintInterface {\n    public function printColor($document) {\n        echo \"Imprimiendo el documento \" . $document . \" en color\\n\";\n    }\n}\n\nclass MultifunctionPrinter implements BlackAndWhitePrintInterface, ColorPrintInterface, ScanInterface, FaxInterface {\n    public function printBlackAndWhite($document) {\n        echo \"Imprimiendo el documento \" . $document . \" en ByN\\n\";\n    }\n\n    public function printColor($document) {\n        echo \"Imprimiendo el documento \" . $document . \" en color\\n\";\n    }\n\n    public function scan($document) {\n        echo \"Escaneando el documento \" . $document . \"\\n\";\n    }\n\n    public function sendFax($document) {\n        echo \"Mandando por fax el documento \". $document . \"\\n\";\n    }\n}\n\nfunction testPrinter(BlackAndWhitePrintInterface $bwPrinter = null, ColorPrintInterface $colorPrinter = null, ScanInterface $scanner = null, FaxInterface $faxMachine = null) {\n    $document = \"Test_Document.doc\";\n\n    if ($bwPrinter !== null) {\n        $bwPrinter->printBlackAndWhite($document);\n    }\n\n    if ($colorPrinter !== null) {\n        $colorPrinter->printColor($document);\n    }\n\n    if ($scanner !== null) {\n        $scanner->scan($document);\n    }\n\n    if ($faxMachine !== null) {\n        $faxMachine->sendFax($document);\n    }\n}\n\n$bwPrinter = new BlackAndWhitePrinter();\n$colorPrinter = new ColorPrinter();\n$multifunctionPrinter = new MultifunctionPrinter();\n\necho \"\\nExtra\\n\";\necho \"Probando impresora ByN:\\n\";\ntestPrinter($bwPrinter);\n\necho \"\\nProbanco impresora color:\\n\";\ntestPrinter(null, $colorPrinter);\n\necho \"\\nProbando impresora multifunción:\\n\";\ntestPrinter($multifunctionPrinter, $multifunctionPrinter, $multifunctionPrinter, $multifunctionPrinter);"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/Aldroide.py",
    "content": "\"\"\"\n    EJERCICIO:\n        Explora el \"Principio SOLID de Segregación de Interfaces (Interface Segregation Principle, ISP)\" \n        y crea un ejemplo simple donde se muestre su funcionamiento de forma correcta e incorrecta.\n\"\"\"\nfrom abc import ABC, abstractmethod\n\n# Ejemplo incorrecto\n\n\nclass Worker(ABC):\n    @abstractmethod\n    def work(self):\n        pass\n\n    @abstractmethod\n    def eat(self):\n        pass\n\n\nclass HumanWorker(Worker):\n    def work(self):\n        print(\"El trabajador esta realizando su labor\")\n\n    def eat(self):\n        print(\"El trabajador esta comiendo\")\n\n\nclass RobotWorker(Worker):\n    def work(self):\n        print(\"Robot is working\")\n\n    def eat(self):\n        raise NotImplementedError(\"Los Robots no comen\")\n\n\nhuman = HumanWorker()\nhuman.work()\nhuman.eat()\n\nrobot = RobotWorker()\nrobot.work()\ntry:\n    robot.eat()\nexcept NotImplementedError as e:\n    print(e)\n\n\n# uso correcto\nclass Worker(ABC):\n    @abstractmethod\n    def work(self):\n        pass\n\n\nclass Eater(ABC):\n    @abstractmethod\n    def eat(self):\n        pass\n\n\nclass HumanWorker(Worker, Eater):\n    def work(self):\n        print(\"El trabajador esta realizando su labor\")\n\n    def eat(self):\n        print(\"El trabajador esta comiendo\")\n\n\nclass RobotWorker(Worker):\n    def work(self):\n        print(\"Robot is working\")\n\n\nhuman = HumanWorker()\nhuman.work()\nhuman.eat()\n\nrobot = RobotWorker()\nrobot.work()\n\n\"\"\"\nDificultad Extra\nCrea un gestor de impresoras.\n * Requisitos:\n * 1. Algunas impresoras sólo imprimen en blanco y negro.\n * 2. Otras sólo a color.\n * 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n * Instrucciones:\n * 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n * 2. Aplica el ISP a la implementación.\n * 3. Desarrolla un código que compruebe que se cumple el principio.\n\"\"\"\n\n\nclass Printer(ABC):\n    def __init__(self, sheets=0):\n        self.sheets = sheets\n\n    # @abstractmethod\n    def printing(self, incrementSheet):\n        self.sheets += incrementSheet\n        print(f\"Se ha impreso {incrementSheet} hojas en blanco y negro\")\n\n\nclass ColorPrinter(ABC):\n    def printing_color(self, incrementSheet):\n        print(f\"imprimiendo {incrementSheet} hojas a color\")\n\n\nclass Scanner(ABC):\n    def __init__(self, sheet):\n        self.sheet = sheet\n\n    def scanning(self, incrementsheet):\n        # self.sheet += incrementsheet\n        print(f\"Se han escaneado {incrementsheet} hojas\")\n\n\nclass Fax(ABC):\n    def __init__(self, sheet):\n        self.sheet = sheet\n\n    def send_fax(self, incrementsheet):\n        # self.sheet += incrementsheet\n        print(f\"Se ha mandado {incrementsheet} en fax\")\n\n# Clases de Impresoras\n\n\nclass BlackAndWhite(Printer):\n    def printing(self, increment):\n        print(\"Imprimiendo en blanco y negro\")\n        super().printing(increment)\n\n\nclass ColorOnlyPrinter(ColorPrinter):\n    def printing_color(self, increment):\n        print(\"La impresora a color esta imprimiendo\")\n        super().printing(increment)\n\n\nclass MultifuncionPrinter(Printer, ColorPrinter, Scanner, Fax):\n\n    def printing(self, a):\n        print(\"Imprimiendo en blanco y negro.\")\n        super().printing(a)\n\n    def printing_color(self, b):\n        print(\"Imprimiendo a color\")\n        super().printing_color(b)\n\n    def scan(self, c):\n        print(\"Ecaneando un documento\")\n        super().scanning(c)\n\n    def send_fax(self, d):\n        print(\"Enviando fax.\")\n        super().send_fax(d)\n\n\ndef test_printer():\n    bw_printer = BlackAndWhite()\n    color_printer = ColorPrinter()\n    Multifuncion_Printer = MultifuncionPrinter()\n\n    print(\"Testing Black and White Printer:\")\n    bw_printer.printing(2)\n\n    print(\"\\nTesting Color Printer:\")\n    color_printer.printing_color(3)\n\n    print(\"\\nTesting Multifunction Printer:\")\n    Multifuncion_Printer.printing(3)\n    Multifuncion_Printer.printing_color(2)\n    Multifuncion_Printer.scan(4)\n    Multifuncion_Printer.send_fax(5)\n\n\ntest_printer()\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/BastianAlq.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Segregación de Interfaces (Interface Segregation Principle, ISP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento de forma correcta e incorrecta.\n *\n\n\"\"\"\n\n\"\"\"\n# ------------------------------------------\n# | INTERFACE SEGREGATION PRINCIPLE (ISP)  |  Información extraída de -> https://devexpert.io/principios-solid-guia-gratis/ \n# ------------------------------------------\n\n# El principio de segregación de interfaces plantea que ninguna clase debe depender de métodos que no usa.\n# por tanto, cuando creemos interfaces que definan comportamientos, hay que estar seguros que todas las clases\n# que implementan dichas interfaces puedan agregar comportamientos a todos los metodos, en caso contrario, es mejor\n# tener varias interfaces mas pequeñas\n#\n# ¿COMO DETECTAR QUE ESTAMOS VIOLANDO EL PRINCIPIO DE SEGREGACION DE INTERFACES?\n#  - Si al implementar una interfaz ves que uno o varios metodos no tienen sentido y te hace falta dejarlos vacios\n#  o lanzar excepciones, es muy probable que estes violando este principio\n\n\"\"\"\n\nfrom abc import ABC, abstractmethod\n\n\nprint(\"------------ FUNCIONAMIENTO INCORRECTO ISP ------------\")\n\n# Interfaz Vehicle que posee el metodo go y fly\nclass Vehicle(ABC):\n    \n    @abstractmethod\n    def go(self):\n        pass\n    \n    @abstractmethod\n    def fly(self):\n        pass\n\nclass Airplane(Vehicle):\n    def go(self):\n        print(\"el avion esta avanzando por tierra...\")\n    \n    def fly(self):\n        print(\"el avion está volando...\")\n\n# el objeto de la clase Car no puede implementar el metodo fly ya que los autos no vuelan, por ende es necesario separar\nclass Car(Vehicle):\n    \n    def go(self):\n        print(\"El auto está moviendose...\")\n    \n    def fly(self):\n        raise Exception('Los autos no vuelan...')\n\navion = Airplane()\navion.go()\navion.fly()\n\nauto = Car()\nauto.go()\n#auto.fly() lanza Exception\n\n\"\"\"\nLa solución es dividir la interfaz vehicle en dos interfaces mas pequeñas que sean especializadas.\nla clase Car implementa la interfaz Movable\nla clase Airplane implementa las interfaces Movable y Flyable\n\"\"\"\n\nprint(\"------------ FUNCIONAMIENTO CORRECTO ISP ------------\")\n\nclass Movable(ABC):\n    \n    @abstractmethod\n    def go(self):\n        pass\n\nclass Flyable(ABC):\n    \n    @abstractmethod\n    def fly(self):\n        pass\n\nclass Car(Movable):\n    def go(self):\n        print(\"El auto está avanzando...\")\n\nclass Airplane(Movable,Flyable):\n    def go(self):\n        print(\"El avion está avanzando por la pista...\")\n\n    def fly(self):\n        print(\"el avion esta volando...\")\n\ncar = Car()\nairplane = Airplane()\n\ncar.go()\n\nairplane.go()\nairplane.fly()\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un gestor de impresoras.\n * Requisitos:\n * 1. Algunas impresoras sólo imprimen en blanco y negro.\n * 2. Otras sólo a color.\n * 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n * Instrucciones:\n * 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n * 2. Aplica el ISP a la implementación.\n * 3. Desarrolla un código que compruebe que se cumple el principio.\n */\n\"\"\"\n\nprint(\"------------ FUNCIONAMIENTO CORRECTO ISP DIFICULTAD EXTRA ------------\")\n\nclass ScannerInterface(ABC):\n    @abstractmethod\n    def scan(self,document: str):\n        pass\n\nclass ColorPrintInterface(ABC):\n    @abstractmethod\n    def print_color(self, document: str):\n        pass\n\nclass PrintInterface(ABC):\n    @abstractmethod\n    def print(self, document: str):\n        pass\n\nclass FaxSenderInterface(ABC):\n    @abstractmethod\n    def send_fax(self, document: str):\n        pass\n\n# IMPRESORAS A COLOR\nclass ColorPrinter(ColorPrintInterface):\n    def print_color(self, document: str):\n        print(f\"imprimiendo documento {document} a color\")\n\n# IMPRESORAS EN BLANCO Y NEGRO\nclass Printer(PrintInterface):\n    def print(self, document: str):\n        print(f\"imprimiendo documento {document} en blanco y negro\")\n\n# IMPRESORAS MULTIFUNCIONALES\nclass MultifuncionalPrinter(PrintInterface, ColorPrintInterface,FaxSenderInterface,ScannerInterface):\n    \n    def print(self, document: str):\n        print(f\"imprimiendo documento {document} en blanco y negro\")\n    \n    def print_color(self, document: str):\n        print(f\"imprimiendo documento {document} a color\")\n    \n    def send_fax(self, document: str):\n        print(f\"enviando por fax el documento {document} \")\n    \n    def scan(self, document: str):\n        print(f\"escanenado el documento {document}\")\n\n\ndef test_printer():\n    multifuncional_printer = MultifuncionalPrinter()\n    color_printer = ColorPrinter()\n    basic_printer = Printer()\n\n    multifuncional_printer.print(\"documento.pdf\")\n    multifuncional_printer.print_color(\"documento.pdf\")\n    multifuncional_printer.send_fax(\"documento.pdf\")\n    multifuncional_printer.scan(\"documento.pdf\")\n    \n    color_printer.print_color(\"documento.pdf\")\n    \n    basic_printer.print(\"documento.pdf\")\n\ntest_printer()"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/CesarCarmona30.py",
    "content": "'''\n  EJERCICIO\n'''\n\nfrom abc import ABC, abstractmethod\n\n# Sin ISP\n\nclass WorkerInterface(ABC):\n\n  @abstractmethod\n  def work(self):\n    pass\n\n  @abstractmethod\n  def eat(self):\n    pass\n\nclass Human(WorkerInterface):\n  \n  def work(self):\n    print(\"Trabajando\")\n  \n  def work(self):\n    print(\"Comiendo\")\n\nclass Robot(WorkerInterface):\n  \n  def work(self):\n    print(\"Trabajando\")\n  \n  def work(self):\n    pass\n\nhuman = Human()\nhuman.work()\nhuman.eat()\n\nrobot = Robot()\nrobot.work()\nrobot.eat()\n\n# Con ISP\n\nclass WorkerInterface(ABC):\n\n  @abstractmethod\n  def work(self):\n    pass\n\nclass EatInterface(ABC):\n\n  @abstractmethod\n  def eat(self):\n    pass\n\nclass Human(WorkerInterface, EatInterface):\n\n  def work(self):\n    print(\"Trabajando\")\n\n  def eat(self):\n    print(\"Comiendo\")\n\nclass Robot(WorkerInterface):\n  def work(self):\n    print(\"Trabajando\")\n\nhuman = Human()\nhuman.work()\nhuman.eat()\n\nrobot = Robot()\nrobot.work()\n\n'''\n  EXTRA\n'''\n\nclass PrinterInterface(ABC):\n\n  @abstractmethod\n  def print(self, document):\n    pass\n\nclass ColorPrinterInterface(ABC):\n\n  @abstractmethod\n  def print_color(self, document):\n    pass\n\nclass ScannerInterface(ABC):\n\n  @abstractmethod\n  def scan(self, document):\n    pass\n\nclass FaxInterface(ABC):\n  \n  @abstractmethod\n  def send_fax(self, document):\n    pass\n\nclass Printer(PrinterInterface):\n  def print(self, document):\n    print(f'Imprimiendo en blanco y negro el documento. {document}')\n\nclass ColorPrinter(ColorPrinterInterface):\n  def print_color(self, document):\n    print(f'Imprimiendo a color el documento. {document}')\n\nclass MultifunctionPrinter(PrinterInterface, ColorPrinter):\n  def print(self, document):\n    print(f'Imprimiendo en blanco y negro el documento. {document}')\n  \n  def print_color(self, document):\n    print(f'Imprimiendo a color el documento. {document}')\n\n  def scan(self, document):\n    print(f'Escanenado el documento. {document}')\n    return f'Documento {document} escaneado.'\n\n  def send_fax(self, document):\n    print(f'Enviando por fax el documento. {document}')\n\ndef test_printers():\n\n  printer = Printer()\n  color_printer = ColorPrinter()\n  multifunction_printer = MultifunctionPrinter()\n\n  printer.print(\"doc.pdf\")\n  color_printer.print_color(\"doc.pdf\")\n  multifunction_printer.print(\"doc.pdf\")\n  multifunction_printer.print_color(\"doc.pdf\")\n  multifunction_printer.scan(\"doc.pdf\")\n  multifunction_printer.send_fax(\"doc.pdf\")\n\ntest_printers()"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/Chrisdev00.py",
    "content": "\"\"\"\n* EJERCICIO:\n* Explora el \"Principio SOLID de Segregación de Interfaces (Interface Segregation Principle, ISP)\" \n* y crea un ejemplo simple donde se muestre su funcionamiento de forma correcta e incorrecta.\n*\n* DIFICULTAD EXTRA (opcional):\n* Crea un gestor de impresoras.\n* Requisitos:\n* 1. Algunas impresoras sólo imprimen en blanco y negro.\n* 2. Otras sólo a color.\n* 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n* Instrucciones:\n* 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n* 2. Aplica el ISP a la implementación.\n* 3. Desarrolla un código que compruebe que se cumple el principio.\n\"\"\"\n\n# Forma Incorrecta sin aplicar el principio ISP\n\nfrom abc import ABC, abstractmethod\n\nclass Document(ABC):\n\n    @abstractmethod\n    def open (self):\n        pass\n    @abstractmethod\n    def save (self):\n        pass\n    @abstractmethod\n    def print (self):\n        pass\n    @abstractmethod\n    def convert_to (self, format):\n        pass\n\nclass PDFDocument(Document):\n\n    def open(self):\n        print(\"Opening PDF document\")\n\n    def save(self):\n        print(\"Saving PDF document\")\n\n    def print(self):\n        print(\"Printing PDF document\")\n\n    def convert_to(self, format):\n        print(f\"Converting PDF document to: {format}\")\n\nclass WordDocument(Document):\n\n    def open(self):\n        print(\"Opening Word document\")\n\n    def save(self):\n        print(\"Saving Word document\")\n\n    def print(self):\n        print(\"Printing Word document\")\n\n    def convert_to(self, format):\n        print(f\"Converting Word document to: {format}\")\n\nclass SpreadsheetDocument(Document):\n\n    def open(self):\n        print(\"Opening Spreadsheet document\")\n\n    def save(self):\n        print(\"Saving Spreadsheet document\")\n\n    def print(self):\n        # Hojas de calculo no necesitan imprimir\n        pass\n\n    def convert_to(self, format):\n        # Hojas de calculo no necesitan convertir\n        pass\n\npdf = PDFDocument()\npdf.open()\npdf.print()\npdf.convert_to('Word')\n\nspreadsheet = SpreadsheetDocument()\nspreadsheet.open()\nspreadsheet.print() # No hace nada\n\n# Forma Correcta de aplicar el principio ISP\n\nclass Document(ABC):\n    \n    @abstractmethod\n    def open (self):\n        pass\n    @abstractmethod\n    def save (self):\n        pass    \n\nclass PrintDocument(Document):\n    @abstractmethod\n    def print(self):\n        pass\n\nclass ConvertTo(Document):\n    @abstractmethod\n    def convert_to(self, format):\n        pass\n\nclass PDFDocument(PrintDocument, ConvertTo):\n\n    def open(self):\n        print(\"Opening PDF document\")\n\n    def save(self):\n        print(\"Saving PDF document\")\n\n    def print(self):\n        print(\"Printing PDF document\")\n\n    def convert_to(self, format):\n        print(f\"Converting PDF document to: {format}\")\n\nclass WordDocument(PrintDocument, ConvertTo):\n\n    def open(self):\n        print(\"Opening Word document\")\n\n    def save(self):\n        print(\"Saving Word document\")\n\n    def print(self):\n        print(\"Printing Word document\")\n\n    def convert_to(self, format):\n        print(f\"Converting Word document to: {format}\")\n\nclass SpreadsheetDocument(Document):\n\n    def open(self):\n        print(\"Opening Spreadsheet document\")\n\n    def save(self):\n        print(\"Saving Spreadsheet document\")\n\n\npdf = PDFDocument()\npdf.open()\npdf.print()\npdf.convert_to('Word')\n\nspreadsheet = SpreadsheetDocument()\nspreadsheet.open()\nspreadsheet.save()\n\n\n############### --------------------------------- EXTRA --------------------------------------- ###################\n\nclass Printer(ABC):\n    \n    @abstractmethod\n    def black_white_print(self):\n        pass\n\nclass ColorPrinter(ABC):\n    @abstractmethod\n    def color_print(self):\n        pass\n\nclass ScanerPrinter(ABC):\n    @abstractmethod\n    def scan(self):\n        pass\n\nclass FaxPrinter(ABC):\n    @abstractmethod\n    def send_fax(self, dest):\n        pass\n\nclass CannonPrinter(Printer, ColorPrinter, ScanerPrinter, FaxPrinter):\n\n    def black_white_print(self):\n        print(\"Impresion en blanco y negro\")\n\n    def color_print(self):\n        print(\"Impresion a colores\")\n\n    def scan(self):\n        print(\"Escaneo disponible\")\n\n    def send_fax(self, dest):\n        print(f\"Enviar documento a {dest}\")\n\nclass EpsonPrinter(Printer, ColorPrinter, ScanerPrinter):\n\n    def black_white_print(self):\n        print(\"Impresion en blanco y negro\")\n\n    def color_print(self):\n        print(\"Impresion a colores\")\n\n    def scan(self):\n        print(\"Escaneo disponible\")\n\nclass LGPrinter (Printer, FaxPrinter):\n\n    def black_white_print(self):\n        print(\"Impresion en blanco y negro\")\n\n    def send_fax(self, dest):\n        print(f\"Enviar documento a {dest}\")\n\nclass ColorOnlyPrinter(ColorPrinter):\n\n    def color_print(self):\n        print(\"Impresión a colores\")\n\n\ncannon = CannonPrinter()\ncannon.black_white_print()\ncannon.scan()\ncannon.send_fax(\"carlos@example.com\")\n\nepson = EpsonPrinter()\nepson.color_print()\nepson.scan()\n\nlg = LGPrinter()\nlg.send_fax(\"juan4562\")\n\ncolor_only = ColorOnlyPrinter()\ncolor_only.color_print()"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/EmmanuelMMontesinos.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Segregación de Interfaces (Interface Segregation Principle, ISP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento de forma correcta e incorrecta.\n */\n\"\"\"\n'Sin Aplicar'\nclass Caja:\n    def __init__(self,nombre) -> None:\n        self.estado = False\n        self.password = \"\"\n        self.alarma = False\n        self.intentos = 0\n        self.nombre = nombre\n    \n    def abrir(self):\n        if self.estado != True:\n            self.estado = True\n        else:\n            print(f\"{self.nombre} ya esta abierta\")\n        self.mostrar_estado()\n    \n    def cerrar(self):\n        if self.estado != False:\n            self.estado = False\n        else:\n            print(f\"{self.nombre} ya esta cerrada\")\n            return\n        self.mostrar_estado()\n\n    def cambiar_password(self,old,new):\n        if self.verificar(password=\"\"):\n            if old.lower() == self.password.lower():\n                self.password = new\n            else:\n                self.intentos += 1\n                print(f\"La contraseña de {self.nombre} no coincide con la proporcionada: nivel de alerta {self.intentos}/3\")\n            if self.intentos >= 3:\n                self.alarma = True\n        else:\n            print(f\"{self.nombre} esta bloqueado\")\n\n\n    def verificar(self,password):\n        if self.alarma == False:\n            if self.password.lower() == password.lower():\n                return True\n        else:\n            return False\n        \n    def mostrar_estado(self):\n        if self.estado:\n            print(f\"{self.nombre} esta abierta\")\n        else:\n            print(f\"{self.nombre} esta cerrada\")\n\nclass CajaCarton(Caja):\n    def __init__(self, nombre) -> None:\n        super().__init__(nombre)\n    \n    def abrir(self):\n        if self.verificar():\n            super().abrir()\n    \n    def cerrar(self):\n        super().cerrar()\n    \n    def cambiar_password(self, old, new):\n        pass\n\n    def mostrar_estado(self):\n        super().mostrar_estado()\n    \n    def verificar(self):\n        return True\n    \nclass CajaFuerte(Caja):\n    def __init__(self, nombre) -> None:\n        super().__init__(nombre)\n    \n    def abrir(self,password):\n        if self.verificar(password):\n            super().abrir()\n        else:\n            print(f\"{password} no es la contraseña correcta\")\n    \n    def cerrar(self):\n        super().cerrar()\n    \n    def cambiar_password(self, old, new):\n        super().cambiar_password(old, new)\n\n    def mostrar_estado(self):\n        super().mostrar_estado()\n    \n    def verificar(self,password):\n        return super().verificar(password)\n\nmi_caja_carton = CajaCarton(\"Caja de Carton\")\nmi_caja_fuerte = CajaFuerte(\"Caja Fuerte\")\n\nmi_caja_carton.abrir()\nmi_caja_fuerte.abrir(\"\")\nprint()\n\nmi_caja_carton.cerrar()\nmi_caja_fuerte.cerrar()\nprint()\n\nmi_caja_carton.cambiar_password(\"\",\"1234\")\nmi_caja_fuerte.cambiar_password(\"\",\"1234\")\n\nprint()\n\nmi_caja_carton.abrir()\nmi_caja_fuerte.abrir(\"4321\")\nprint()\n\nmi_caja_carton.cerrar()\nmi_caja_fuerte.cerrar()\n\n'Aplicado'\nclass CajaGenerica:\n    def __init__(self,nombre) -> None:\n        self.estado = False\n        self.nombre = nombre\n    \n    def abrir(self):\n        if self.estado != True:\n            self.estado = True\n        else:\n            print(f\"{self.nombre} ya esta abierta\")\n        self.mostrar_estado()\n    \n    def cerrar(self):\n        if self.estado != False:\n            self.estado = False\n        else:\n            print(f\"{self.nombre} ya esta cerrada\")\n            return\n        self.mostrar_estado()\n        \n    def mostrar_estado(self):\n        if self.estado:\n            print(f\"{self.nombre} esta abierta\")\n        else:\n            print(f\"{self.nombre} esta cerrada\")\n\nclass CajaCarton2(CajaGenerica):\n    def __init__(self, nombre) -> None:\n        super().__init__(nombre)\n\nclass CajaFuerte2(CajaGenerica):\n    def __init__(self, nombre) -> None:\n        super().__init__(nombre)\n        self.password = \"\"\n        self.alarma = False\n        self.intentos = 0\n    \n    def abrir(self,password):\n        if self.verificar(password):\n            super().abrir()\n        else:\n            print(f\"{password} no es la contraseña correcta\")\n    \n    def cambiar_password(self,old,new):\n        if self.verificar(password=\"\"):\n            if old.lower() == self.password.lower():\n                self.password = new\n            else:\n                self.intentos += 1\n                print(f\"La contraseña de {self.nombre} no coincide con la proporcionada: nivel de alerta {self.intentos}/3\")\n            if self.intentos >= 3:\n                self.alarma = True\n        else:\n            print(f\"{self.nombre} esta bloqueado\")\n\n    def verificar(self,password):\n        if self.alarma == False:\n            if self.password.lower() == password.lower():\n                return True\n        else:\n            return False\n        \n# Prueba\nmi_caja_carton2 = CajaCarton2(\"Caja de Carton 2\")\nmi_caja_fuerte2 = CajaFuerte2(\"Caja Fuerte 2\")\n\nmi_caja_carton2.abrir()\nmi_caja_fuerte2.abrir(\"\")\n\nmi_caja_carton2.cerrar()\nmi_caja_fuerte2.cerrar()\n\nmi_caja_carton2.abrir()\nmi_caja_fuerte2.abrir(\"\")\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un gestor de impresoras.\n * Requisitos:\n * 1. Algunas impresoras sólo imprimen en blanco y negro.\n * 2. Otras sólo a color.\n * 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n * Instrucciones:\n * 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n * 2. Aplica el ISP a la implementación.\n * 3. Desarrolla un código que compruebe que se cumple el principio.\n\"\"\"\nclass ImpresoraBase:\n    def __init__(self,nombre) -> None:\n        self.nombre = nombre\n    def imprimir_bn(self,documento):\n        print(f\"Imprimiendo desde {self.nombre} en blanco y negro: {documento}\\n\")\n\nclass ImpresoraColor(ImpresoraBase):\n    def imprimir_cl(self,documento):\n        print(f\"Imprimiendo desde {self.nombre} en color: {documento}\\n\")\n\nclass Multifuncion(ImpresoraColor):\n    def escanear(self,documento):\n        print(f\"Escaneando desde {self.nombre}: {documento}\\n\")\n\n    def enviar_fax(self,documento):\n        print(f\"Enviando Fax desde {self.nombre}: {documento}\\n\")\n\n# Prueba\ndef test_impresoras(documento):\n    base = ImpresoraBase(\"Base\")\n    color = ImpresoraColor(\"Color\")\n    multi = Multifuncion(\"Multi\")\n\n    base.imprimir_bn(documento)\n\n    color.imprimir_bn(documento)\n    color.imprimir_cl(documento)\n\n    multi.imprimir_bn(documento)\n    multi.imprimir_cl(documento)\n    multi.escanear(documento)\n    multi.enviar_fax(documento)\n\ntest_impresoras(\"Curriculum Vitae\")"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/Gordo-Master.py",
    "content": "# 29 - Solid ISP (Interface Segregation Principle)\n\n# Trata de que ninguna clase debe ser forzada a depender de métodos que no utiliza\n# Habla de que las interfases, o la clase base de la clase a utilizar no debe debe tener metodos que no utiliza.\n# Busca que las interfases (o clases base) sean pequeñas, especificas y bien enfocadas.\n\n\"\"\"\nIncorrecta##################################################################\n\"\"\"\n\nfrom abc import ABC, abstractmethod\n\n\"\"\"class WorkerInterface(ABC):\n\n    @abstractmethod\n    def work():\n        pass\n\n    @abstractmethod\n    def eat():\n        pass\n    \n\nclass Developer(WorkerInterface):\n    \n    def work(self):\n        print(\"Escribiendo codigo\")\n\n    def eat(self):\n        print(\"Comiendo el almuerzo\")\n\nclass Robot(WorkerInterface):\n\n    def work(self):\n        print(\"Realizando tareas automaticas\")\n\n    def eat(self):\n        raise NotImplementedError(\"Los robots no comen\")\n    \n\ncarlos = Developer()\ncarlosai = Robot()\n\ncarlos.work()\ncarlos.eat()\ncarlosai.work()\ncarlosai.eat()\n\"\"\"\n\n\"\"\"\nCorrecta##################################################################\n\"\"\"\n\nclass WorkerInterface(ABC):\n\n    @abstractmethod\n    def work():\n        pass\n\nclass CanEat(ABC):\n\n    @abstractmethod\n    def eat():\n        pass\n\n\nclass Developer(WorkerInterface, CanEat):\n    \n    def work(self):\n        print(\"Escribiendo codigo\")\n\n    def eat(self):\n        print(\"Comiendo el almuerzo\")\n\nclass Robot(WorkerInterface):\n\n    def work(self):\n        print(\"Realizando tareas automaticas\")\n\ncarlos = Developer()\ncarlosai = Robot()\n\n# carlos.work()\n# carlos.eat()\n# carlosai.work()\n\n\"\"\"\nEjercicio extra\n\"\"\"\n\nclass Printer(ABC):\n\n    @abstractmethod\n    def print_pages(self):\n        pass\n\n\nclass ColorPrinter(ABC):\n\n    @abstractmethod\n    def print_color_pages(self):\n        pass\n\nclass Fax(ABC):\n    \n    @abstractmethod\n    def send_fax(self):\n        pass\n\nclass Scanner(ABC):\n\n    @abstractmethod\n    def scan(self):\n        pass\n\nclass BlackAndWhitePrinter(Printer):\n\n    def print_pages(self):\n        print(\"Imprimiendo en blanco y negro\")\n\nclass ColorPrinter(ColorPrinter):\n\n    def print_color_pages(self):\n        print(\"Imprimiendo a color\")\n\nclass MultifunctionPrinter(Printer, ColorPrinter, Scanner, Fax):\n\n    def print_pages(self):\n        print(\"Imprimiendo en blanco y negro\")\n\n    def print_color_pages(self):\n        print(\"Imprimiendo a color\")\n\n    def send_fax(self):\n        print(\"Enviando el fax\")\n\n    def scan(self):\n        print(\"Escaneando documento\")\n\n\ndef test_printer():\n\n    printer_bandw = BlackAndWhitePrinter()\n    printer_color = ColorPrinter()\n    printer_multi = MultifunctionPrinter()\n\n    printer_bandw.print_pages()\n    printer_color.print_color_pages()\n    printer_multi.print_pages()\n    printer_multi.print_color_pages()\n    printer_multi.send_fax()\n    printer_multi.scan()\n\ntest_printer()"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/Jairo-Alejandro.py",
    "content": "\"\"\"\nEJERCICIO:\n * Explora el \"Principio SOLID de Segregación de Interfaces (Interface Segregation Principle, ISP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento de forma correcta e incorrecta.\n\"\"\"\n\"\"\"\nEl principio segmentacion de interfaces ISP indica que es mejor tener varias interfaces pequeñas pero especializadas a una unica interfaz gran y general\n\"\"\"\n\n# Ejemplo incorrecta\nclass HomeDevice():\n\n    def turn_on(self):\n        pass\n    def turn_off(self):\n        pass\n    def set_temperature(self, temperature):\n        pass\n\nclass light(HomeDevice):\n\n    def turn_on(self):\n        print(\"Light is turned on\")\n    def turn_off(self):\n        print(\"Light is turned off\")\n    def set_temperature(self, temperature):\n        raise NotImplementedError(\"Lights do not support temperature setting\")\n\nclass Heater(HomeDevice):\n\n    def turn_on(self):\n        print(\"Heater is turned on\")\n    \n    def turn_off(self):\n        print(\"Heater is turned off\")\n    def set_temperature(self, temperature):\n        print(f\"Setting heater to {temperature} degrees\")\n\nlight = light()\nlight.turn_on()\nlight.turn_off()\n#light.set_temperature(30) Esto lanzaría una excepción\n\nheater = Heater()\nheater.turn_on()\nheater.set_temperature(30)\nheater.turn_off()\n\n\n# Ejemplo correcto\n\nclass Switchable():\n\n    def turn_om(self):\n        pass\n    def turn_off(self):\n        pass\n\nclass Temperature_control():\n\n    def set_temperature(self,temperature):\n        pass\n\nclass Light(Switchable):\n\n    def turn_on(self):\n        print(\"Light is turned on\")\n    def turn_off(self):\n        print(\"Light is turned off\")\n\n\nclass Heater(Switchable,Temperature_control):\n\n    def turn_on(self):\n        print(\"Heater is turned on\")\n    \n    def turn_off(self):\n        print(\"Heater is turned off\")\n\n    def set_temperature(self, temperature):\n        print(f\"Setting heater to {temperature} degrees\")\n\nlight = Light()\nlight.turn_on()\nlight.turn_off()\n\nheater = Heater()\nheater.turn_on()\nheater.set_temperature(22)\nheater.turn_off()\n\n\n\"\"\"\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Segregación de Interfaces (Interface Segregation Principle, ISP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un gestor de impresoras.\n * Requisitos:\n * 1. Algunas impresoras sólo imprimen en blanco y negro.\n * 2. Otras sólo a color.\n * 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n * Instrucciones:\n * 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n * 2. Aplica el ISP a la implementación.\n * 3. Desarrolla un código que compruebe que se cumple el principio.\n */\n\"\"\"\n\nclass PrintDocuments():\n\n    def print_document(self, document):\n        pass\n\nclass Scannable():\n\n    def scan_document(self):\n        pass\n\nclass Fax():\n\n    def send_fax(self,document):\n        pass\n\nclass BlackAndWhite(PrintDocuments):\n\n    def print_document(self, document):\n        print(\"Printing in black and white:\", document)\n\nclass Color(PrintDocuments):\n\n    def print_document(self, document):\n        print(\"Printing in color:\", document)\n\nclass MultifunctionPrinter(PrintDocuments, Scannable, Fax):\n    def print_document(self, document):\n        print(\"Printing document:\", document)\n\n    def scan_document(self):\n        print(\"Scanning document\")\n\n    def send_fax(self, document):\n        print(\"Sending fax with document:\", document)\n\n\ndef test_printers():\n    # Imprimir\n    bw_printer = BlackAndWhite()\n    bw_printer.print_document(\"Report\")\n\n    color_printer = Color()\n    color_printer.print_document(\"Photo\")\n\n    # Multifunción\n    multi_printer = MultifunctionPrinter()\n    multi_printer.print_document(\"Manual\")\n    multi_printer.scan_document()\n    multi_printer.send_fax(\"Invoice\")\n\ntest_printers()\n\n\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/JesusWay69.py",
    "content": "import os, platform\r\nfrom abc import ABC, abstractmethod\r\n\r\n\r\nif (platform.platform().startswith(\"macOS\") or platform.platform().startswith(\"Linux\")):\r\n    os.system('clear')\r\nelse:\r\n    os.system('cls')\r\n\r\n\"\"\" \r\n * EJERCICIO:\r\n * Explora el \"Principio SOLID de Segregación de Interfaces\r\n * (Interface Segregation Principle, ISP)\", y crea un ejemplo\r\n * simple donde se muestre su funcionamiento de forma correcta e incorrecta.\"\"\"\r\n\r\n\"\"\"El siguiente código no cumple el principio de segregación de interfaces ya que sólo hay una \"interface\"\r\nque modela el contenido..\r\n(en python no existen las interfaces como tal, lo más parecido es crear una clase abstracta con el módulo abc y declarar\r\ntodos los métodos como abstractos y sin funcionalidad propia para que a efectos prácticos se comporte como una interface)\r\n..de las diferentes clases de aves con todas las características de las cuales solo la primera (tiene plumas)\r\nes común a todas las aves pero no las demás que aun así es obligatorio declarar sus métodos en todas las clases\r\nademás el método que debemos llamar para confirmar la característica del ave está seteada en true con lo cual en \r\nlos métodos cuya característica no cumpla dicho ave debemos forzar la salida retornando false.\"\"\"\r\n\r\n\r\nclass Bird (ABC):\r\n    \r\n    @abstractmethod\r\n    def have_feathers():\r\n        pass\r\n    @abstractmethod\r\n    def flies():\r\n        pass\r\n    @abstractmethod\r\n    def swims():\r\n        pass\r\n    @abstractmethod\r\n    def run():\r\n        pass\r\n    @abstractmethod\r\n    def feature():\r\n        return True\r\n    @abstractmethod\r\n    def bird_name():\r\n        pass\r\n    \r\nclass Ostrich(Bird):\r\n    def have_feathers():\r\n        return super().feature()\r\n    def flies():\r\n        return False\r\n    def swims():\r\n        return False\r\n    def run():\r\n        return super().feature()\r\n    def bird_name(self):\r\n        return \"Avestruz\"\r\n \r\nclass Swift (Bird):\r\n    def have_feathers():\r\n        return super().feature()\r\n    def flies():\r\n        return super().feature()\r\n    def swims():\r\n        return False\r\n    def run():\r\n        return False\r\n    def bird_name(self):\r\n        return \"Vencejo\"\r\n\r\nclass Penguin (Bird):\r\n    def have_feathers():\r\n        return super().feature()\r\n    def flies():\r\n        return False\r\n    def swims():\r\n        return super().feature()\r\n    def run():\r\n        return False\r\n    def bird_name(self):\r\n        return \"Pingüino\"\r\n    \r\n\"\"\"En el siguiente código aplicamos el principio de segregación de interfaces dividiendo en diferentes interfaces\r\nlos métodos que devuelven la característica verdadera, en el primero declaramos el método \"tiene plumas\" común\r\na todas las aves y el método que devuelve el nombre del ave así como la constante general de característica\r\nseteado en true, después creamos una interface por cada característica para declarar dentro su método de característica \r\nque no es común a todas las aves, volar, correr y nadar, luego creamos las clases que modelen cada especie de ave heredando\r\nen cada una de ellas las interfaces que se correspondan con sus características particulares\r\n(Python permite la herencia múltiple de clases abstractas y no abstractas),\r\ndespues dentro creamos un método que reciba un objeto, seteamos todas las características en false\r\ny mediante condicionales aplicamos para cada tipo de objeto/ave sus correspondientes características que sean verdaderas,\r\ncreamos una salida que muestre todas las características y en cada ave mostrará true si esa característica está en el\r\nmodelado de su objeto o false, que es el valor por defecto que declaramos si no cumple dicha característica.\"\"\"\r\n   \r\n\r\nclass BirdISP(ABC):\r\n    @abstractmethod\r\n    def have_feathersISP(self):\r\n        pass\r\n    @abstractmethod\r\n    def bird_name(self):\r\n        pass\r\n    def feature_ISP(self):\r\n        return True\r\nclass FlyingBirdISP(ABC):\r\n    @abstractmethod\r\n    def flies_ISP(self):\r\n        pass\r\nclass SwimmingBirdISP(ABC):\r\n    @abstractmethod\r\n    def swims_ISP(self):\r\n        pass\r\nclass RunnerBirdISP(ABC):\r\n    @abstractmethod\r\n    def run_ISP(self):\r\n        pass\r\n\r\nclass OstrichISP (BirdISP, RunnerBirdISP):\r\n    def have_feathersISP(self):\r\n        return super().feature_ISP()\r\n    def run_ISP(self):\r\n        return super().feature_ISP()\r\n    def bird_name(self):\r\n        return \"Avestruz\"\r\nclass SwiftISP(BirdISP, FlyingBirdISP):\r\n    def have_feathersISP(self):\r\n        return super().feature_ISP()\r\n    def flies_ISP(self):\r\n        return super().feature_ISP()\r\n    def bird_name(self):\r\n        return \"Vencejo\"\r\nclass PenguinISP(BirdISP, SwimmingBirdISP, RunnerBirdISP):\r\n    def have_feathersISP(self):\r\n        return super().feature_ISP()\r\n    def swims_ISP(self):\r\n        return super().feature_ISP()\r\n    def run_ISP(self):\r\n        return super().feature_ISP\r\n    def bird_name(self):\r\n        return \"Pingüino\"\r\n    \r\ndef test_birds(object):\r\n    name = None\r\n    feathers = False\r\n    fly = False\r\n    swim = False\r\n    run = False\r\n    if isinstance(object,OstrichISP):\r\n        name = object.bird_name()\r\n        feathers = object.have_feathersISP()\r\n        run = object.run_ISP()\r\n    elif isinstance(object, SwiftISP):\r\n        feathers = object.have_feathersISP()\r\n        name = object.bird_name()\r\n        fly = object.flies_ISP()\r\n    elif isinstance(object, PenguinISP):\r\n        feathers = object.have_feathersISP()\r\n        name = object.bird_name()\r\n        swim = object.swims_ISP()\r\n    print(\"\\nEspecie de ave: \" , name\r\n                , \"\\n¿tiene plumas?: \" , feathers\r\n                , \"\\n¿Puede volar?: \" , fly\r\n                , \"\\n¿Puede correr?: \" , run\r\n                , \"\\n¿Puede nadar?: \" , swim)\r\n\r\ntest_birds(OstrichISP())\r\ntest_birds(SwiftISP())\r\ntest_birds(PenguinISP())\r\n    \r\n\r\n\"\"\"\r\n * DIFICULTAD EXTRA (opcional):\r\n * Crea un gestor de impresoras.\r\n * Requisitos:\r\n * 1. Algunas impresoras sólo imprimen en blanco y negro.\r\n * 2. Otras sólo a color.\r\n * 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\r\n *  Instrucciones:\r\n * 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\r\n * 2. Aplica el ISP a la implementación.\r\n * 3. Desarrolla un código que compruebe que se cumple el principio.\"\"\"  \r\n\r\n\r\nclass Printer(ABC):\r\n    @abstractmethod\r\n    def printer(self):\r\n        pass\r\n    @abstractmethod\r\n    def printer_model(self):\r\n        pass\r\n    def feature_printer(self):\r\n        return True\r\n\r\nclass BlackAndWhite(ABC):\r\n    @abstractmethod\r\n    def print_BW(self):\r\n        pass\r\n\r\nclass Color(ABC):\r\n    @abstractmethod\r\n    def print_color(self):\r\n        pass\r\n\r\nclass Scan(ABC):\r\n    def scanner(self):\r\n        pass\r\n\r\nclass Fax(ABC):\r\n    def fax(self):\r\n        pass\r\n\r\nclass BwPrinter(Printer, BlackAndWhite):\r\n    def printer(self):\r\n        super().feature_printer()\r\n    \r\n    def printer_model(self):\r\n        return \"Impresora en blanco y negro\"\r\n    \r\n    def print_BW(self):\r\n        super().feature_printer()\r\n\r\nclass ColorPrinter(Printer, Color):\r\n    def printer(self):\r\n        super().feature_printer()\r\n\r\n    def printer_model(self):\r\n        return \"Impresora a color\"\r\n    \r\n    def print_color(self):\r\n        super().feature_printer()\r\n\r\n\r\nclass MultiPrinter(Printer, Color, Scan, Fax, BlackAndWhite):\r\n    def printer(self):\r\n        super().feature_printer()\r\n\r\n    def printer_model(self):\r\n        return \"Dispositivo multifunción\"\r\n    \r\n    def print_color(self):\r\n        super().feature_printer()\r\n\r\n    def scanner(self):\r\n        super().feature_printer()\r\n\r\n    def fax(self):\r\n        super().feature_printer()\r\n\r\n    def print_BW(self):\r\n        super().feature_printer()\r\n\r\nclass Scanner(Printer,Scan):\r\n    def printer(self):\r\n        pass  \r\n\r\n    def printer_model(self):\r\n        return \"Dispositivo exclusivo de escaneo\"\r\n    \r\n    def scanner(self):\r\n        super().feature_printer()\r\n\r\n\r\ndef test_printer(object):\r\n    can_print = False\r\n    device = \"\"\r\n    bw = False\r\n    color = False\r\n    scan = False\r\n    fax = False\r\n\r\n    if isinstance (object, BwPrinter):\r\n        bw = object.feature_printer()\r\n        can_print = object.feature_printer()\r\n        device = object.printer_model()\r\n\r\n    elif isinstance (object, ColorPrinter):\r\n        color = object.feature_printer()\r\n        can_print = object.feature_printer()\r\n        device = object.printer_model()\r\n\r\n    elif isinstance (object, MultiPrinter):\r\n        can_print = object.feature_printer()\r\n        color = object.feature_printer()\r\n        bw = object.feature_printer()\r\n        scan = object.feature_printer()\r\n        fax = object.feature_printer()\r\n        device = object.printer_model()\r\n\r\n    elif isinstance (object, Scanner):\r\n        scan = object.feature_printer()\r\n        device = object.printer_model()\r\n\r\n    print(\"\\nTipo de dispositivo: \" , device\r\n                , \"\\n¿puede imprimir?: \" , can_print\r\n                , \"\\n¿Imprime en blanco y negro?: \" , bw\r\n                , \"\\n¿Imprime en color?: \" , color\r\n                , \"\\n¿Escanea Documentos?: \" , scan\r\n                , \"\\n¿Puede enviar/recibir fax?: \" , fax)\r\n\r\ntest_printer(BwPrinter())\r\ntest_printer(MultiPrinter())\r\ntest_printer(Scanner())\r\ntest_printer(ColorPrinter())\r\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/JheisonQuiroga.py",
    "content": "# Author: Jheison Duban Quiroga Quintero\n# Github: https://github.com/JheisonQuiroga\n\n\"\"\"\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Segregación de Interfaces\n * (Interface Segregation Principle, ISP)\", y crea un ejemplo\n * simple donde se muestre su funcionamiento de forma correcta e incorrecta.\n *\"\"\"\n\n\"\"\" 4. Principio de Segregación de Interfaces (ISP)\nLos clientes no deben verse obligados a depender de interfaces que no necesitan.\nEvita crear interfaces grandes y complejas que obliguen a las clases a implementar métodos\nque no necesitan. En su lugar utiliza un interfaces más pequeñas y especificas. \n\"\"\"\n\n# Violación del ISP\nfrom abc import ABC, abstractmethod\n\nclass Bird(ABC):\n    @abstractmethod\n    def fly(self):\n        pass\n\n    @abstractmethod\n    def swim(self):\n        pass\n\nclass Pinguin(Bird):\n    def fly(self):\n        raise NotImplementedError(\"Error, los pinguinos no pueden volar\")\n    \n    def swim(self):\n        print(\"El pinguino está nadando\")\n\n# Siguiendo el Interface Segregation Principle\n\nclass BasicBird(ABC):\n    @abstractmethod\n    def eat(self):\n        pass\n\nclass FlyableBird(ABC):\n    @abstractmethod\n    def fly(self):\n        pass\n\nclass SwimmableBird(ABC):\n    @abstractmethod\n    def swim(self):\n        pass\n\n# Caso de uso\nclass Eagle(BasicBird, FlyableBird):\n    def eat(self):\n        print(\"El aguila está comiendo\")\n\n    def fly(self):\n        print(\"El aguila está volando\")\n\nclass Pinguin(BasicBird, SwimmableBird):\n    def eat(self):\n        print(\"El pinguino está comiendo\")\n\n    def swim(self):\n        print(\"El pinguino está nadando\")\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un gestor de impresoras.\n * Requisitos:\n * 1. Algunas impresoras sólo imprimen en blanco y negro.\n * 2. Otras sólo a color.\n * 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n * Instrucciones:\n * 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n * 2. Aplica el ISP a la implementación.\n * 3. Desarrolla un código que compruebe que se cumple el principio.\n */\n\"\"\"\n\n# Gestor de impresoras\n\nclass BWPrint(ABC):\n    @abstractmethod\n    def print_bw(self, document):\n        pass\n\nclass ColorPrint(ABC):\n    @abstractmethod\n    def print_to_color(self, document):\n        pass\n\nclass Scannable(ABC):\n    @abstractmethod\n    def scan(self, document):\n        pass\n\nclass Faxable(ABC):\n    @abstractmethod\n    def send_fax(self, document: str, number: str):\n        pass\n\n# Implementaciones especificas\nclass BasicPrinter(BWPrint):\n    def print_bw(self, document):\n        print(f\"Imprimiendo a blanco y negro {document}\")\n\n\nclass ModernPrinter(BWPrint, ColorPrint):\n    def print_bw(self, document):\n        print(f\"Imprimiendo a blanco y negro {document}\")\n\n    def print_to_color(self, document):\n        print(f\"Imprimiendo a color {document}\")\n\nclass MultiFunctionalPrinter(BWPrint, ColorPrint, Scannable, Faxable):\n    def print_bw(self, document):\n        print(f\"Imprimiendo a blanco y negro {document}\")\n\n    def print_to_color(self, document):\n        print(f\"Imprimiendo a color {document}\")\n\n    def scan(self, document):\n        print(f\"Escaneando {document}\")\n\n    def send_fax(self, document, number):\n        print(f\"Enviando Fax: {document} al número: {number}\")\n\n\n# Código de prueba\ndef test_printer(printer):\n    if isinstance(printer, BWPrint):\n        printer.print_bw(\"Documento de Prueba B/N\")\n    if isinstance(printer, ColorPrint):\n        printer.print_to_color(\"Documento de Prueba a color\")\n    if isinstance(printer, Scannable):\n        printer.scan(\"Documento de Prueba\")\n    if isinstance(printer, Faxable):\n        printer.send_fax(\"Documento de Prueba\", \"123456789\")\n\n\n# Caso de uso\nif __name__ == \"__main__\":\n    basic_printer = BasicPrinter()\n    modern_printer = ModernPrinter()\n    multi_printer = MultiFunctionalPrinter()\n\n    print(\"----- Impresora Básica -----\")\n    test_printer(basic_printer)\n\n    print(\"\\n----- Impresora Moderna -----\")\n    test_printer(modern_printer)\n\n    print(\"\\n----- Impresora Multifuncional -----\")\n    test_printer(multi_printer)"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/LucasRebuffo.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Segregación de Interfaces\n * (Interface Segregation Principle, ISP)\", y crea un ejemplo\n * simple donde se muestre su funcionamiento de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un gestor de impresoras.\n * Requisitos:\n * 1. Algunas impresoras sólo imprimen en blanco y negro.\n * 2. Otras sólo a color.\n * 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n * Instrucciones:\n * 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n * 2. Aplica el ISP a la implementación.\n * 3. Desarrolla un código que compruebe que se cumple el principio.\n */ \"\"\"\n\n\"\"\" El principio de ISP establece que las clases no deben esxponer metodos que no se utilizan,\n    por lo tanto se deben crear interfaces o clases especificas. \"\"\"\n\nfrom abc import ABC, abstractmethod\n\n\nclass Bird(ABC):\n\n    def __init__(self, name):\n        self.name = name\n\n    @abstractmethod\n    def do_sound(self) -> str:\n        pass\n\n\nclass FlyingBird(Bird):\n\n    @abstractmethod\n    def fly(self):\n        pass\n\n\nclass SwimmingBird(Bird):\n\n    @abstractmethod\n    def swim(self):\n        pass\n\n\nclass Crow(FlyingBird):\n\n    def fly(self):\n        print(f\"{self.name} is flying high and fast!\")\n\n    def do_sound(self) -> str:\n        return \"Caw\"\n\n\nclass Duck(SwimmingBird, FlyingBird):\n\n    def fly(self):\n        print(f\"{self.name} is flying not very high\")\n\n    def swim(self):\n        print(f\"{self.name} swims in the lake and quacks\")\n\n    def do_sound(self) -> str:\n        return \"Quack\"\n\n\n\"\"\" * DIFICULTAD EXTRA (opcional):\n * Crea un gestor de impresoras.\n * Requisitos:\n * 1. Algunas impresoras sólo imprimen en blanco y negro.\n * 2. Otras sólo a color.\n * 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n * Instrucciones:\n * 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n * 2. Aplica el ISP a la implementación.\n * 3. Desarrolla un código que compruebe que se cumple el principio. \"\"\"\n\n\nclass PrintInterface(ABC):\n    @abstractmethod\n    def print(self, document: str):\n        pass\n\n\nclass ColorPrintInterface(ABC):\n    @abstractmethod\n    def print_color(self, document: str):\n        pass\n\n\nclass ScanInterface(ABC):\n    @abstractmethod\n    def scan(self, document: str):\n        pass\n\n\nclass SendFaxInterface(ABC):\n    @abstractmethod\n    def send_fax(self, document: str):\n        pass\n\n\nclass Printer(PrintInterface):\n    def print(self, document: str):\n        print(f\"Imprimiendo en blanco y negro el documento {document}.\")\n\n\nclass ColorPrinter(ColorPrintInterface):\n    def print_color(self, document: str):\n        print(f\"Imprimiendo a color el documento {document}.\")\n\n\nclass MultiFunctionPrinter(\n    PrintInterface, ScanInterface, SendFaxInterface, ColorPrintInterface\n):\n    def print_color(self, document: str):\n        print(f\"Imprimiendo a color el documento {document}.\")\n\n    def print(self, document: str):\n        print(f\"Imprimiendo en blanco y negro el documento {document}.\")\n\n    def scan(self, document: str):\n        print(f\"Escaneando el documento {document}.\")\n        return f\"Documento {document} escaneado.\"\n\n    def send_fax(self, document: str):\n        print(f\"Enviando por fax el documento {document}.\")\n\n\nprinter = Printer()\ncolor_printer = ColorPrinter()\nmultifunction_printer = MultiFunctionPrinter()\n\nprinter.print(\"doc.pdf\")\ncolor_printer.print_color(\"doc.pdf\")\nmultifunction_printer.print(\"doc.pdf\")\nmultifunction_printer.print_color(\"doc.pdf\")\nmultifunction_printer.scan(\"doc.pdf\")\nmultifunction_printer.send_fax(\"doc.pdf\")\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/Nicojsuarez2.py",
    "content": "# #29 SOLID: PRINCIPIO DE SEGREGACIÓN DE INTERFACES (ISP)\n> #### Dificultad: Media | Publicación: 15/07/24 | Corrección: 22/07/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Segregación de Interfaces (Interface Segregation Principle, ISP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un gestor de impresoras.\n * Requisitos:\n * 1. Algunas impresoras sólo imprimen en blanco y negro.\n * 2. Otras sólo a color.\n * 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n * Instrucciones:\n * 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n * 2. Aplica el ISP a la implementación.\n * 3. Desarrolla un código que compruebe que se cumple el principio.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/Nikorasu-d.py",
    "content": "from abc import ABC, abstractmethod\n\n\n# El principio Solid de Segregacion de Interfaces comprende que una interfaz es un contrato que se debe cumplir por lo que una clase que herede de la interfaz no puede omitir sus metodos\n# o levantar excepciones/errores en su implementacion\n\n#Implementacion incorrecta\nclass AnimalesWrong (ABC):\n    \n    @abstractmethod\n    def caminar(self):\n        pass\n    @abstractmethod\n    def comer(self):\n        pass\n    \nclass PerroWrong (AnimalesWrong):\n    def __init__(self, name):\n      self.name = name\n    \n    def caminar(self):\n        print (f\"{self.name} esta Caminando\")\n    \n    def comer(self):\n        print (f\"{self.name} esta Comiendo\")\n\nclass PezWrong (AnimalesWrong):\n    \n    def __init__(self, especie):\n      self.especie = especie\n    \n    def caminar(self):\n        raise Exception('Los Peces no caminan')\n    \n    def comer(self):\n        print(f\"{self.especie} esta Comiendo\")\n    \n    def nadar(self):\n        print(f\"{self.especie} esta Nadando\")\n        \n        \n#Implementacion correcta\n\nclass funcionesGenerales(ABC):\n    \n    @abstractmethod\n    def alimentarse():\n        pass\n\nclass funcionesTerrestres(ABC):\n    \n    @abstractmethod\n    def caminar(self):\n        pass\n\nclass funcionesAcuaticas(ABC):\n    \n    @abstractmethod\n    def nadar(self):\n        pass\n\nclass Perro(funcionesGenerales,funcionesTerrestres):\n    def __init__(self, name):\n      self.name = name\n    \n    def caminar(self):\n        print (f\"{self.name} esta Caminando\")\n    \n    def alimentarse(self):\n        print (f\"{self.name} esta Comiendo\")\n\nclass Pez(funcionesGenerales,funcionesAcuaticas):\n    \n    def __init__(self, especie):\n      self.especie = especie\n    \n    def nadar(self):\n        print (f\"{self.especie} esta Nadando\")\n    \n    def alimentarse(self):\n        print(f\"{self.especie} esta Comiendo\")\n        \nclass Cocodrilo(funcionesGenerales,funcionesAcuaticas,funcionesTerrestres):\n    \n    def __init__(self, especie):\n      self.especie = especie\n    \n    def nadar(self):\n        print (f\"{self.especie} esta Nadando\")\n    \n    def alimentarse(self):\n        print(f\"{self.especie} esta Comiendo\")\n        \n    def caminar(self):\n        print (f\"{self.especie} esta Caminando\")\n        \n        \n# Ejercicio Extra Gestor de Impresoras\n\n\nclass funcionesBasicas(ABC):\n    \n    def imprimirBYN(self):\n        pass\n\nclass funcionesAvanzadas(ABC):\n    \n    def imprimirAColor(self):\n        pass\n    \n\nclass funcionesExtra(ABC):\n    \n    def enviarFax(self):\n        pass\n    \n    def escanearDocumento(self):\n        pass\n    \n\nclass impresoraBasica(funcionesBasicas):\n    \n    def __init__(self, marca, modelo):\n        self.marca = marca\n        self.modelo = modelo\n    \n    def imprimirBYN(self,documento):\n        print (f'Marca: {self.marca} Modelo: {self.modelo}')\n        print(f\"Imprimiendo {documento} a Blanco y Negro\")\n    \nclass impresoraModerna(funcionesAvanzadas):\n    \n    def __init__(self, marca, modelo):\n        self.marca = marca\n        self.modelo = modelo\n    \n    def imprimirAColor(self,documento):\n        print (f'Marca: {self.marca} Modelo: {self.modelo}')\n        print(f\"Imprimiendo {documento} a Color\")\n\nclass impresoraMultifuncional(funcionesBasicas,funcionesAvanzadas,funcionesExtra):\n    \n    def __init__(self, marca, modelo):\n        self.marca = marca\n        self.modelo = modelo\n        \n    def imprimirBYN(self,documento):\n        print (f'Marca: {self.marca} Modelo: {self.modelo}')\n        print(f\"Imprimiendo {documento} a Blanco y Negro\")\n        \n    def imprimirAColor(self,documento):\n        print (f'Marca: {self.marca} Modelo: {self.modelo}')\n        print(f\"Imprimiendo {documento} a Color\")\n        \n    def escanearDocumento(self, path):\n        print (f'Marca: {self.marca} Modelo: {self.modelo}')\n        print(f\"Escaneando documento hacia {path}\")\n    \n    def enviarFax(self, documento):\n        print (f'Marca: {self.marca} Modelo: {self.modelo}')\n        print(f\"Enviando {documento} en Fax\")\n\n\n\nprint('\\n')\nimpresora1 = impresoraBasica('Epson', 'Ecotank M1120')\nimpresora1.imprimirBYN('HOLA MUNDO.docx')\n\n\nprint('\\n')\nimpresora2 = impresoraModerna('Epson', 'Ecotank L121')\nimpresora2.imprimirAColor('HOLA MUNDO.docx')\n\n\nprint('\\n')\nimpresora3 = impresoraMultifuncional('Epson', 'Ecotank L3560')\nimpresora3.imprimirBYN('HOLA MUNDO.docx')   \nimpresora3.imprimirAColor('HOLA MUNDO.docx')   \nimpresora3.escanearDocumento('C:/users/usuario/documents/HOLA_MUNDO.txt')   \nimpresora3.enviarFax('HOLA MUNDO.docx')   "
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/Sac-Corts.py",
    "content": "from abc import ABC, abstractmethod\n\n# Incorrecto\nclass Vehicle:\n    def drive(self):\n        raise NotImplementedError\n\n    def play_music(self):\n        raise NotImplementedError\n\n    def open_trunk(self):\n        raise NotImplementedError\n\nclass Car(Vehicle):\n    def drive(self):\n        print(\"Driving a car\")\n\n    def play_music(self):\n        print(\"Playing music in the car\")\n\n    def open_trunk(self):\n        print(\"Opening the car trunk\")\n\nclass Bicycle(Vehicle):\n    def drive(self):\n        print(\"Riding a bicycle\")\n\n    def play_music(self):\n        pass\n\n    def open_trunk(self):\n        pass\n\n# Correcto\nclass Drivable(ABC):\n    @abstractmethod\n    def drive(self):\n        pass\n\nclass MusicPlayable(ABC):\n    @abstractmethod\n    def play_music(self):\n        pass\n\nclass TrunkOpenable(ABC):\n    @abstractmethod\n    def open_trunk(self):\n        pass\n\nclass Car(Drivable, MusicPlayable, TrunkOpenable):\n    def drive(self):\n        print(\"Driving a car\")\n\n    def play_music(self):\n        print(\"Playing music in the car\")\n\n    def open_trunk(self):\n        print(\"Opening the car trunk\")\n\nclass Bicycle(Drivable):\n    def drive(self):\n        print(\"Riding a bicycle\")\n\n\ncar = Car()\ncar.drive()\ncar.play_music()\ncar.open_trunk()\n\nbicycle = Bicycle()\nbicycle.drive()\n\n### Ejercicio Extra ###\nclass Printer(ABC):\n    @abstractmethod\n    def print(self, content: str):\n        pass\n\nclass ColorPrinter(ABC):\n    @abstractmethod\n    def print_color(self, content: str):\n        pass\n\nclass Scanner(ABC):\n    @abstractmethod\n    def scan(self, content: str):\n        pass\n\nclass Fax(ABC):\n    @abstractmethod\n    def send_fax(self, content: str):\n        pass\n\nclass BlackAndWhitePrinter(Printer):\n    def print(self, content: str):\n        print(f\"Printing in black and white: {content}\")\n\nclass ColorPrinterOnly(ColorPrinter):\n    def print_color(self, content: str):\n        print(f\"Printing in color: {content}\")\n\nclass MultifunctionPrinter(Printer, ColorPrinter, Scanner, Fax):\n    def print(self, content: str):\n        print(f\"Printing in black and white: {content}\")\n\n    def print_color(self, content: str):\n        print(f\"Printing in color: {content}\")\n\n    def scan(self, content: str):\n        print(f\"Scanning: {content}\")\n\n    def send_fax(self, content: str):\n        print(f\"Sending fax: {content}\")\n\n\nbw_printer = BlackAndWhitePrinter()\nbw_printer.print(\"Thesis\")\n\ncolor_printer = ColorPrinterOnly()\ncolor_printer.print_color(\"Images\")\n\nmultifunction_printer = MultifunctionPrinter()\nmultifunction_printer.print(\"Thesis\")\nmultifunction_printer.print_color(\"Images\")\nmultifunction_printer.scan(\"Credential\")\nmultifunction_printer.send_fax(\"Report\")\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/SooHav.py",
    "content": "# 29 SOLID: PRINCIPIO DE SEGREGACIÓN DE INTERFACES (ISP)\n# Ejercicio\n# Ejemplo Pato sin ISP\nfrom abc import ABC, abstractmethod\n\n\nclass Pato (ABC):\n    def __init__(self, tipo):\n        self.tipo = tipo\n\n    @abstractmethod\n    def vuela(self):\n        pass\n\n    @abstractmethod\n    def nada(self):\n        pass\n\n    @abstractmethod\n    def dice(self):\n        pass\n\n\nclass PatoSalvaje(Pato):\n    def __init__(self):\n        super().__init__(\"salvaje\")\n\n    def vuela(self):\n        print(\"El pato salvaje vuela.\")\n\n    def nada(self):\n        print(\"El pato salvaje nada.\")\n\n    def dice(self):\n        print(\"El pato salvaje dice Quack.\")\n\n\nclass PatoDomestico(Pato):\n    def __init__(self):\n        super().__init__(\"domestico\")\n\n    def vuela(self):\n        print(\"El pato doméstico vuela.\")\n\n    def nada(self):\n        print(\"El pato doméstico nada.\")\n\n    def dice(self):\n        print(\"El pato doméstico dice Quack.\")\n\n\nclass PatoPlastico(Pato):\n    def __init__(self):\n        super().__init__(\"plastico\")\n\n    def vuela(self):\n        print(\"El pato de plástico no puede volar.\")\n\n    def nada(self):\n        print(\"El pato de plástico no puede nadar.\")\n\n    def dice(self):\n        print(\"El pato de plástico dice Squeak.\")\n\n\n# Uso\nprint(\"Con LSP\")\npato1 = PatoSalvaje()\npato2 = PatoDomestico()\npato3 = PatoPlastico()\n\npato1.vuela()\npato1.nada()\npato1.dice()\n\npato2.vuela()\npato2.nada()\npato2.dice()\n\npato3.vuela()\npato3.nada()\npato3.dice()\n\n\n# Ejemplo Pato con ISP\nclass Volador (ABC):\n    @abstractmethod\n    def vuela(self):\n        pass\n\n\nclass Nadador (ABC):\n    @abstractmethod\n    def nada(self):\n        pass\n\n\nclass Hablador (ABC):\n    @abstractmethod\n    def dice(self):\n        pass\n\n\nclass Flotador (ABC):\n    @abstractmethod\n    def flota(self):\n        pass\n\n\nclass PatoSalvaje(Volador, Nadador, Hablador):\n    def __init__(self, tipo):\n        self.tipo = tipo\n\n    def vuela(self):\n        print(f\"El {self.tipo} vuela.\")\n\n    def nada(self):\n        print(f\"El {self.tipo} nada.\")\n\n    def dice(self):\n        print(f\"El {self.tipo} dice Quack.\")\n\n\nclass PatoDomestico(Nadador, Hablador):\n    def __init__(self, tipo):\n        self.tipo = tipo\n\n    def nada(self):\n        print(f\"El {self.tipo} nada.\")\n\n    def dice(self):\n        print(f\"El {self.tipo} dice Quack.\")\n\n\nclass PatoPlastico(Hablador, Flotador):\n    def __init__(self, tipo):\n        self.tipo = tipo\n\n    def dice(self):\n        print(f\"El {self.tipo} dice Quick.\")\n\n    def flota(self):\n        print(f\"El {self.tipo} flota en la bañera.\")\n\n\n# Uso\nprint(\"Con ISP\")\npato4 = PatoSalvaje(\"Pato Salvaje\")\npato5 = PatoDomestico(\"Pato Domestico\")\npato6 = PatoPlastico(\"Pato de plastico\")\n\npato4.vuela()\npato4.nada()\npato4.dice()\n\npato5.nada()\npato5.dice()\n\npato6.dice()\npato6.flota()\n\n# Extra\n\n\nclass Imprimir (ABC):\n    @abstractmethod\n    def imprime(self):\n        pass\n\n\nclass Escanear (ABC):\n    @abstractmethod\n    def escanea(self):\n        pass\n\n\nclass Enviar_Fax (ABC):\n    @abstractmethod\n    def envia(self):\n        pass\n\n\nclass Impresora_ByN(Imprimir):\n    def __init__(self, tipo):\n        self.tipo = tipo\n\n    def imprime(self):\n        print(f\"Se {self.imprime.__name__} documento en {self.tipo}.\")\n\n\nclass Impresora_Color(Imprimir):\n    def __init__(self, tipo):\n        self.tipo = tipo\n\n    def imprime(self):\n        print(f\"Se {self.imprime.__name__} documento en {self.tipo}.\")\n\n\nclass Impresora_Multifuncion(Imprimir, Escanear, Enviar_Fax):\n    def __init__(self, tipo):\n        self.tipo = tipo\n\n    def imprime(self):\n        print(f\"Se {self.imprime.__name__} documento en {self.tipo}.\")\n\n    def escanea(self):\n        print(f\"Se {self.escanea.__name__} documento en {self.tipo}.\")\n\n    def envia(self):\n        print(f\"Se {self.envia.__name__} fax en {self.tipo}.\")\n\n# Gestor de impresoras\n\n\nclass GestorImpresoras:\n    def __init__(self):\n        self.impresoras = []\n\n    def agregar_impresora(self, impresora):\n        self.impresoras.append(impresora)\n\n    def listar_impresoras(self):\n        print(\"\\nListado de impresoras disponibles:\")\n        for id, impresora in enumerate(self.impresoras, start=1):\n            print(f\"{id}. {type(impresora).__name__} - {impresora.tipo}\")\n\n    def seleccionar_impresora(self):\n        self.listar_impresoras()\n        seleccion = int(\n            input(\"Seleccione el número de la impresora que desea usar: \"))\n        if seleccion <= 0 or seleccion > len(self.impresoras):\n            print(\"Selección inválida.\")\n            return None\n        return self.impresoras[seleccion - 1]\n\n    def imprimir_documento(self, impresora):\n        if isinstance(impresora, Imprimir):\n            impresora.imprime()\n        else:\n            print(f\"La impresora {\n                  type(impresora).__name__} no puede imprimir.\")\n\n    def escanear_documento(self, impresora):\n        if isinstance(impresora, Escanear):\n            impresora.escanea()\n        else:\n            print(f\"La impresora {\n                  type(impresora).__name__} no puede escanear.\")\n\n    def enviar_documento(self, impresora):\n        if isinstance(impresora, Enviar_Fax):\n            impresora.envia()\n        else:\n            print(f\"La impresora {\n                  type(impresora).__name__} no puede enviar fax.\")\n\n\n# Uso del gestor de impresoras\nif __name__ == \"__main__\":\n    gestor = GestorImpresoras()\n\n    # Agregar impresoras\n    impresora1 = Impresora_ByN(\"Impresora B/N 1\")\n    impresora2 = Impresora_Color(\"Impresora Color 1\")\n    impresora3 = Impresora_Multifuncion(\"Impresora Multifunción 1\")\n    impresora4 = Impresora_ByN(\"Impresora B/N Secretaría\")\n\n    gestor.agregar_impresora(impresora1)\n    gestor.agregar_impresora(impresora2)\n    gestor.agregar_impresora(impresora3)\n    gestor.agregar_impresora(impresora4)\n\n    gestor.listar_impresoras()\n    gestor.seleccionar_impresora()\n\n    gestor.imprimir_documento(impresora4)\n    gestor.escanear_documento(impresora3)\n    gestor.enviar_documento(impresora3)\n\n\"\"\"\n#Interacción\n    while True:\n        print(\"\\n1. Agregar impresora\")\n        print(\"2. Visualizar listado de impresoras\")\n        print(\"3. Imprimir documento\")\n        print(\"4. Escanear documento\")\n        print(\"5. Enviar Fax\")\n        print(\"6. Salir\")\n        opcion = input(\"Seleccione una opción: \")\n\n        if opcion == \"1\":\n            tipo = input(\"Ingrese el tipo de impresora (ByN/Color/Multifuncion): \").lower()\n            nombre = input(\"Ingrese el nombre de la impresora: \")\n            if tipo == \"byn\":\n                gestor.agregar_impresora(Impresora_ByN(nombre))\n            elif tipo == \"color\":\n                gestor.agregar_impresora(Impresora_Color(nombre))\n            elif tipo == \"multifuncion\":\n                gestor.agregar_impresora(Impresora_Multifuncion(nombre))\n            else:\n                print(\"Tipo de impresora no reconocido.\")\n\n        elif opcion == \"2\":\n            gestor.listar_impresoras()\n\n        elif opcion == \"3\":\n            seleccionada = gestor.seleccionar_impresora()\n            if seleccionada:\n                gestor.imprimir_documento(seleccionada)\n\n        elif opcion == \"4\":\n            seleccionada = gestor.seleccionar_impresora()\n            if seleccionada:\n                gestor.escanear_documento(seleccionada)\n\n        elif opcion == \"5\":\n            seleccionada = gestor.seleccionar_impresora()\n            if seleccionada:\n                gestor.enviar_documento(seleccionada)\n\n        elif opcion == \"6\":\n            print(\"Saliendo del programa...\")\n            break\n\n        else:\n            print(\"Opción inválida. Intente nuevamente.\")\n\n \"\"\"\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/Trufoplus.py",
    "content": "###############################################################################\n### EJERCICIO: ISP\n###############################################################################\n\n### SIN APLICAR ISP ###\nclass Calculator:\n    \"\"\"\n    Una calculadora que suma, resta, multiplica y divide.\n    \"\"\"\n    def sum(self, a, b):\n        pass\n    \n    def subtract(self, a, b):\n        pass\n    \n    def multiply(self, a, b):\n        pass\n    \n    def divide(self, a, b):\n        pass\n\n# Si queremos crear una calculadora que solo sume y reste no podemos,\n# estamos obligados a implementar todos los métodos en nuestro objeto.\nmy_simple_calculator = Calculator()\n\n\n### APLICANDO ISP ###\n# Separamos los métodos en diferentes clases, para poder crear nuestra calculadora simple.\nclass Sum:\n    def sum(self, a, b):\n        return a + b\n\n\nclass Subtract: \n    def subtract(self, a, b):\n        return a - b\n\n\nclass Multiply:     \n    def multiply(self, a, b):\n        return a * b\n \n \nclass Divide:    \n    def divide(self, a, b):\n        return a / b\n\n\n# Ahora sí podemos crear una calculadora que solo sume y reste\nclass SimpleCalculator(Sum, Subtract):\n    pass\n\n\n# Ejemplo de uso\nmy_simple_calculator = SimpleCalculator()\nprint(my_simple_calculator.sum(2, 2))       \nprint(my_simple_calculator.subtract(2, 2))\n\n\n\n\n###############################################################################\n### DIFICULTAD EXTRA\n###############################################################################\n\n# Aplicamos una clase para cada funcion que puede realizar nuestra impresora \nclass Printer:\n    def print(self, file):\n        return f\"Printing {file}...\"\n\n\nclass Scanner:\n    def scan(self, file):\n        return f\"Scaning {file}...\"\n\n\nclass Fax:\n    def send_fax(self, file, address):\n        return f\"Sendinf {file} to {address}\"\n    \n\n# Creamos nuestras impresoras personalizadas \nclass BlanckWhitePrinter(Printer):\n    def print(self, file):\n        return f\"Printing {file} in black and white\"\n    def __str__(self) -> str:\n        return \"A black and White printer\"\n\n\nclass ColorPrinter(Printer):\n    def print(self, file):\n        return f\"Printinf {file} in color\"\n    \n    def __str__(self) -> str:\n        return \"A color printer\"\n\n\nclass MultifunctionDevice(Printer, Scanner, Fax):\n    def __str__(self) -> str:\n        return \"A Multifunction device\"\n\n\n\n# Creamos los objetos y empleamos los metodos.\nmy_printers = [BlanckWhitePrinter(), ColorPrinter(), MultifunctionDevice()]\n\nfor printer in my_printers:\n    print() # Un espacio en blanco para mejorar la visualizacion\n    print(printer)\n    print(printer.print(\"documento.txt\"))\n    \n    if isinstance(printer, Fax):\n        print(printer.send_fax(\"documento.txt\", \"moure@gmail.com\"))\n    else:\n        print(\"This print doesn't send fax\")\n    \n    if isinstance(printer, Scanner):\n        print(printer.scan(\"documento.txt\"))\n    else:\n        print(\"This printer doesn't scan\")\n    print() \n    \n\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/adra-dev.py",
    "content": "\"\"\"\nEJERCICIO:\nExplora el \"Principio SOLID de Segregación de Interfaces (Interface \nSegregation Principle, ISP)\" y crea un ejemplo simple donde se \nmuestre su funcionamiento de forma correcta e incorrecta.\n\nDIFICULTAD EXTRA(opcional):\nCrea un gestor de impresoras.\n\nRequisitos:\n1. Algunas impresoras sólo imprimen en blanco y negro.\n2. Otras sólo a color.\n3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\nInstrucciones:\n1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n2. Aplica el ISP a la implementación.\n3. Desarrolla un código que compruebe que se cumple el principio.\n\nby adra-dev\n\"\"\"\n\n\"\"\"\nInterface Segregation Principle (ISP):\nEl Principio de Segregación de Interfaces también fue propuesto por \nuncle bob. la idea central del principio es:\n\n    \"Los clientes no deberían ser forzados a depender de métodos que \n    ellos no usan. las interfaces pertenecen a los clientes no a sus \n    herencias.\"\n\ndocumentacion:\"https://realpython.com/solid-principles-python/\"\n    \nEn este caso, los clientes son las clases y las subclases y las \ninterfaces consisten en los métodos y atributos. En otras palabras, \nsi una clase utiliza métodos en particular o atributos entonces esos \nmétodos y atributos deberían ser segregados a clases más específicas.\n\nConsidera el siguiente ejemplo.\n\"\"\"\n\n# printers_isp.py\n\nfrom abc import ABC, abstractmethod\n\nclass Printer(ABC):\n    @abstractmethod\n    def print(self, document):\n        pass\n\n    @abstractmethod\n    def fax(self, document):\n        pass\n\n    @abstractmethod\n    def scan(self, document):\n        pass\n\nclass OldPrinter(Printer):\n    def print(self, document):\n        print(f\"Printing {document} in black and white...\")\n\n    def fax(self, document):\n        raise NotImplementedError(\"Fax functionality not supported\")\n\n    def scan(self, document):\n        raise NotImplementedError(\"Scan functionality not supported\")\n\nclass ModernPrinter(Printer):\n    def print(self, document):\n        print(f\"Printing {document} in color...\")\n\n    def fax(self, document):\n        print(f\"Faxing {document}...\")\n\n    def scan(self, document):\n        print(f\"Scanning {document}...\")\n\n\"\"\"\nEn este ejemplo, la clase base, impresora, provee las interfaces que \nsus subclases deben implementar. OldPrinter hereda de printer y debe \nimplementar la misma interfaz. Sin embargo, OldPrinter no utiliza los\n métodos .fax() y .scan() porque este tipo de impresora no soporta \n estas funcionalidades.\n\nEsta implementación viola el ISP porque obliga a OldPrinter a mostrar\nuna interfaz que la subclase no implementa o necesita. Para \nsolucionar este problema, deberías separar las interfaces en clases \nmás pequeñas y más específicas. Así después puedes crear subclases \nmás concretas por medio de la herencia de múltiples interfaces que \ndicha subclase necesite.\n\n\"\"\"\n\n# printers_isp.py\n\nfrom abc import ABC, abstractmethod\n\nclass Printer(ABC):\n    @abstractmethod\n    def print(self, document):\n        pass\n\nclass Fax(ABC):\n    @abstractmethod\n    def fax(self, document):\n        pass\n\nclass Scanner(ABC):\n    @abstractmethod\n    def scan(self, document):\n        pass\n\nclass OldPrinter(Printer):\n    def print(self, document):\n        print(f\"Printing {document} in black and white...\")\n\nclass NewPrinter(Printer, Fax, Scanner):\n    def print(self, document):\n        print(f\"Printing {document} in color...\")\n\n    def fax(self, document):\n        print(f\"Faxing {document}...\")\n\n    def scan(self, document):\n        print(f\"Scanning {document}...\")\n\n\"\"\"\n\nAhora Printer, Fax y Scanner son clases base  que proveen interfaces \nespecíficas con una única responsabilidad cada una. Para crear \nOldPrinter, ya solo necesitas heredar la interfaz de Printer. De este\nmodo, la clase no tendrá métodos que no se utilicen. Para crear la \nclase ModernPrinter, solo necesitas heredar de todas las interfaces \nen resumen haz segregado la interfaz de Printer. \n\n\"\"\"\n\n\"\"\"\nExtra\n\"\"\"\n\nfrom abc import ABC, abstractmethod\n\nclass Printer(ABC):\n    @abstractmethod\n    def print(self, document):\n        pass\n\nclass Fax(ABC):\n    @abstractmethod\n    def fax(self, document):\n        pass\n\nclass Scanner(ABC):\n    @abstractmethod\n    def scan(self, document):\n        pass\n\n\nclass BlackWhitePrinter(Printer):\n    def print(self, document):\n        print(f\"Printing {document} in black and white...\")\n\n\nclass ColorPrinter(Printer):\n    def print(self, document):\n        print(f\"Printing {document} in color...\")\n\n\nclass LastModelPrinter(Printer, Fax, Scanner):\n    def print(self, document):\n        print(f\"Printing {document} in black and white...\")\n\n    def print_color(self, document):\n        print(f\"Printing {document} in color...\")\n\n    def fax(self, document):\n        print(f\"Faxing {document}...\")\n\n    def scan(self, document):\n        print(f\"Scanning {document}...\")\n\n\ndef test_printers():\n\n    printer = BlackWhitePrinter()\n    color_printer = ColorPrinter()\n    multifunction_printer = LastModelPrinter()\n\n    printer.print(\"doc.pdf\")\n    color_printer.print(\"doc.pdf\")\n    multifunction_printer.print(\"doc.pdf\")\n    multifunction_printer.print_color(\"doc.pdf\")\n    multifunction_printer.scan(\"doc.pdf\")\n    multifunction_printer.fax(\"doc.pdf\")\n\n\ntest_printers()"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/agusrosero.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Segregación de Interfaces (Interface Segregation Principle, ISP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento de forma correcta e incorrecta.\n *\n\"\"\"\nfrom abc import ABC, abstractmethod\n\n# Forma incorrecta\n\n\nclass Bird(ABC):\n\n    def __init__(self, name):\n        self.name = name\n\n    @abstractmethod\n    def fly(self):\n        pass\n\n    @abstractmethod\n    def swim(self):\n        pass\n\n    @abstractmethod\n    def do_sound(self) -> str:\n        pass\n\n\nclass Crow(Bird):\n\n    def fly(self):\n        print(f\"{self.name} is flying high and fast!\")\n\n    def swim(self):\n        raise NotImplementedError(\"Crows don't swim!\")\n\n    def do_sound(self) -> str:\n        return \"Caw\"\n\n\nclass Duck(Bird):\n\n    def fly(self):\n        print(f\"{self.name} is flying not very high\")\n\n    def swim(self):\n        print(f\"{self.name} swims in the lake and quacks\")\n\n    def do_sound(self) -> str:\n        return \"Quack\"\n\n# Forma correcta\n\n\nclass Bird(ABC):\n\n    def __init__(self, name):\n        self.name = name\n\n    @abstractmethod\n    def do_sound(self) -> str:\n        pass\n\n\nclass FlyingBird(Bird):\n\n    @abstractmethod\n    def fly(self):\n        pass\n\n\nclass SwimmingBird(Bird):\n\n    @abstractmethod\n    def swim(self):\n        pass\n\n\nclass Crow(FlyingBird):\n\n    def fly(self):\n        print(f\"{self.name} is flying high and fast!\")\n\n    def do_sound(self) -> str:\n        return \"Caw\"\n\n\nclass Duck(SwimmingBird, FlyingBird):\n\n    def fly(self):\n        print(f\"{self.name} is flying not very high\")\n\n    def swim(self):\n        print(f\"{self.name} swims in the lake and quacks\")\n\n    def do_sound(self) -> str:\n        return \"Quack\"\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un gestor de impresoras.\n * Requisitos:\n * 1. Algunas impresoras sólo imprimen en blanco y negro.\n * 2. Otras sólo a color.\n * 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n * Instrucciones:\n * 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n * 2. Aplica el ISP a la implementación.\n * 3. Desarrolla un código que compruebe que se cumple el principio.\n */\n\"\"\"\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/alanshakir.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Segregación de Interfaces\n * (Interface Segregation Principle, ISP)\", y crea un ejemplo\n * simple donde se muestre su funcionamiento de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un gestor de impresoras.\n * Requisitos:\n * 1. Algunas impresoras sólo imprimen en blanco y negro.\n * 2. Otras sólo a color.\n * 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n * Instrucciones:\n * 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n * 2. Aplica el ISP a la implementación.\n * 3. Desarrolla un código que compruebe que se cumple el principio.\n */\n\"\"\"\n\nfrom abc import ABC, abstractmethod\n    #Incorrecto\nclass VehicleInterface(ABC):\n    @abstractmethod\n    def start_engine(self):\n        pass\n            \n    @abstractmethod   \n    def stop_engine(self):\n        pass\n        \n    @abstractmethod\n    def fly(self):\n        pass\n            \nclass Car(VehicleInterface):\n        \n    def start_engine(self):\n        print(\"Car engine started.\")\n        \n    def stop_engine(self):\n        print(\"Car engine stopped.\")\n        \n    def fly(self):\n        #los autos no vuelan\n        pass\n            \nclass airplanes(VehicleInterface):\n        \n    def start_engine(self):\n        print(\"airplanes engine started.\")\n        \n    def stop_engine(self):\n        print(\"airplanes engine stopped.\")\n        \n    def fly(self):\n        print(\"airplanes is flying\")\n    \n    #Correcto\nclass VehicleInterface(ABC):\n    @abstractmethod\n    def start_engine(self):\n        pass\n            \n    @abstractmethod   \n    def stop_engine(self):\n        pass\n            \nclass FlyInterface(VehicleInterface):        \n    @abstractmethod\n    def fly(self):\n        pass\n            \nclass Car(VehicleInterface):\n        \n    def start_engine(self):\n        print(\"Car engine started.\")\n        \n    def stop_engine(self):\n        print(\"Car engine stopped.\")\n        \n            \nclass airplanes(FlyInterface, VehicleInterface):\n        \n    def start_engine(self):\n        print(\"airplanes engine started.\")\n        \n    def stop_engine(self):\n        print(\"airplanes engine stopped.\")\n        \n    def fly(self):\n        print(\"airplanes is flying\")\n\n#Extra\nclass PrinterIsBlackInterface(ABC):\n    @abstractmethod\n    def printer_black(self, document):\n        pass\n\nclass PrinterIsColorInterface(ABC):\n    @abstractmethod\n    def printer_color(self, document):\n        pass\n\nclass PrinterScanInterface(ABC):\n    @abstractmethod\n    def printer_scan(self, document):\n        pass\n        \nclass PrinterFaxInterface(ABC):\n    @abstractmethod\n    def send_fax(self, document):\n        pass\n\nclass Printer(PrinterIsBlackInterface):\n    def printer_black(self, document):\n        print(f\"imprimiendo en blanco y negro {document}\")\n\nclass PrinterColor(PrinterIsColorInterface):\n    def printer_color(self, document):\n        print(f\"imprimiendo a color {document}\")\n\nclass PrinterMultiFunction(PrinterIsBlackInterface, PrinterIsColorInterface, PrinterScanInterface, PrinterFaxInterface):\n    def printer_black(self, document):\n        print(f\"imprimiendo en blanco y negro {document}\")\n    \n    def printer_color(self, document):\n        print(f\"imprimiendo a color {document}\")\n        \n    def printer_scan(self, document):\n        print(f\"escaneando documento {document}\")\n    \n    def send_fax(self, document):\n        print(f\"enviando {document} por fax\")\n\n\nprinted = Printer()\nprinted.printer_black(\"documento.ppt\")\n\nprinted_color = PrinterColor()\nprinted_color.printer_color(\"documento.ppt\")\n\nprinted_multifunction = PrinterMultiFunction()\nprinted_multifunction.printer_black(\"documento.ppt\")\nprinted_multifunction.printer_color(\"documento.ppt\")\nprinted_multifunction.printer_scan(\"documento.ppt\")\nprinted_multifunction.send_fax(\"documento.ppt\")\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/avcenal.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el \"Principio SOLID de Segregación de Interfaces\n * (Interface Segregation Principle, ISP)\", y crea un ejemplo\n * simple donde se muestre su funcionamiento de forma correcta e incorrecta.\n\"\"\"\n#INCORRECTO\nfrom abc import ABC, abstractmethod\n\nclass Worker():\n    def work(self):\n        print(\"Estoy trabajando\")\n    def eat(self):\n        print(\"Estoy comiendo\")\n\nclass Human_1(Worker):\n    def work(self):\n        print(\"Estoy trabajando\")\n    \n    def eat(self):\n        print(\"Estoy comiendo\")\n\nclass Robot_1(Worker):\n    def work(self):\n        print(\"Estoy trabajando\")\n\nmy_human_1 = Human_1()\nmy_robot_1 = Robot_1()\n\nmy_human_1.work()\nmy_human_1.eat()\n\n#my_robot_1.eat() Robot() no tiene definido una función eat() por tanto no debería poder implementarla. Los robots no comen.\n\nmy_robot_1.work() \n\n#CORRECTO\nclass Work(ABC):\n    @abstractmethod\n    def work(self):\n        print(\"Estoy trabajando\")\n\nclass Eat():\n    @abstractmethod\n    def eat(self):\n        print(\"Estoy comiendo\")\n\nclass Human(Work,Eat):\n    def work(self):\n        print(\"Estoy trabajando\")\n\n    def eat(self):\n        print(\"Estoy comiendo\")\n\nclass Robot(Work):\n    def work(self):\n        print(\"Estoy trabajando\")\n\nmy_human = Human()\nmy_robot = Robot()\n\nmy_human.work()\nmy_human.eat()\n\nmy_robot.work()\n#my_robot.eat() Ahora Robot() no tiene definida ninguna función eat() al solo heredar de Work(), ya que los robots no comen.\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un gestor de impresoras.\n * Requisitos:\n * 1. Algunas impresoras sólo imprimen en blanco y negro.\n * 2. Otras sólo a color.\n * 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n * Instrucciones:\n * 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n * 2. Aplica el ISP a la implementación.\n * 3. Desarrolla un código que compruebe que se cumple el principio.\n\"\"\"\nclass Printer(ABC):\n    @abstractmethod\n    def printer(self,document):\n        print(f\"Imprimiento en Blanco y Negro el documento:\\n{document}\")\n\nclass Color(ABC):\n    @abstractmethod\n    def print_color(self,document):\n        print(f\"Imprimiento en Color el documento:\\n{document}\")\n\nclass Scanner(ABC):\n    @abstractmethod\n    def scan(self,document):\n        print(f\"Escaneando el documento: {document}\")\n\nclass Fax(ABC):\n    @abstractmethod\n    def send_fax(self,document):\n        print(f\"Enviando por fax el documento: {document}\")\n        \nclass RegularPrinter(Printer):\n    def printer(self, document):\n        return super().printer(document)\n\nclass ColorPrinter(Color):\n    def print_color(self, document):\n        return super().print_color(document)\n\nclass MultifunctionPrinter(Printer,ColorPrinter,Scanner,Fax):\n\n    def printer(self,document):\n        return super().printer(document)\n\n    def print_color(self, document):\n        return super().print_color(document)\n\n    def scan(self, document):\n        return super().scan(document)\n\n    def send_fax(self, document):\n        return super().send_fax(document)\n\nmy_regular_printer = RegularPrinter()\nmy_color_printer = ColorPrinter()\nmy_multifunction_printer = MultifunctionPrinter()\n\nmy_regular_printer.printer(\"Me llamo Alex\")\nmy_color_printer.print_color(\"Me llamo Alex\")\nmy_multifunction_printer.printer(\"Me llamo Alex\")\nmy_multifunction_printer.print_color(\"Me llamo Alex\")\nmy_multifunction_printer.scan(\"DNI de Alex\")\nmy_multifunction_printer.send_fax(\"Nómina de Alex\")\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/barrancus.py",
    "content": "#29 - Python\n# EJERCICIO:\n# Explora el \"Principio SOLID de Segregación de Interfaces\n# (Interface Segregation Principle, ISP)\", y crea un ejemplo\n# simple donde se muestre su funcionamiento de forma correcta e incorrecta.\n# \n# DIFICULTAD EXTRA (opcional):\n# Crea un gestor de impresoras.\n# Requisitos:\n# 1. Algunas impresoras sólo imprimen en blanco y negro.\n# 2. Otras sólo a color.\n# 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n# Instrucciones:\n# 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n# 2. Aplica el ISP a la implementación.\n# 3. Desarrolla un código que compruebe que se cumple el principio.\n# \n\nclass Counter:\n    def __iter__(self):\n        self.a = 1\n        return self\n    \n    def __next__(self):\n        x = self.a\n        self.a += 1\n        return x\n\ncontador = iter(Counter())\n\ndef separacion(cadena) -> str:\n    global contador\n    print(f'\\nEjercicio {next(contador)}. {cadena} {'-.-' * 20}')\n\nfrom abc import ABC, abstractmethod\n\n#-----Incorrecto-----\nseparacion('Incorrecto fundamento')\n\nclass ArmyA(ABC):\n    \n    @abstractmethod\n    def attack(self):\n        pass\n\n    @abstractmethod\n    def deffense(self):\n        pass\n\n    @abstractmethod\n    def construct(self):\n        pass\n\n    @abstractmethod\n    def dissaster(self):\n        pass\n\nclass SpecialForce(ArmyA):\n\n    def attack(self):\n        print('Misión encubierta.')\n\n    def deffense(self):\n        pass\n\n    def construct(self):\n        pass\n\n    def dissaster(self):\n        pass    \nclass Marine(ArmyA):\n\n    def attack(self):\n        print('Desembarco en la playa.')\n    \n    def deffense(self):\n        print('Vigilancia de cuarteles.')\n    \n    def construct(self):\n        pass\n\n    def dissaster(self):\n        pass    \nclass Engineers(ArmyA):\n\n    def attack(self):\n        pass\n    \n    def deffense(self):\n        pass\n    \n    def dissaster(self):\n        pass    \n\n    def construct(self):\n        print('Recostruyendo puentes.')\n    \nclass Emrgency(ArmyA):\n\n    def attack(self):\n        pass\n    \n    def deffense(self):\n        pass\n    \n    def construct(self):\n        print('Limpiando escombros.')\n    \n    def dissaster(self):\n        print('Ayudando a la gente.')\n\nspecialforce = SpecialForce()\nmarine = Marine()\nengineers = Engineers()\nemrgency = Emrgency()\n\nspecialforce.attack()\nspecialforce.deffense()\nmarine.dissaster()\nmarine.construct()\nemrgency.attack()\n\n#-----Correcto-----\nseparacion('Correcto fundamento')\n\nclass ArmyB:\n\n    def __init__(self, name: str):\n        self.name = name\n\nclass InterfaceAta(ABC):\n    \n    @abstractmethod\n    def attack(self):\n        pass\n\nclass InterfaceDef(ABC):\n    \n    @abstractmethod\n    def deffense(self):\n        pass\n\nclass InterfaceCon(ABC):\n    \n    @abstractmethod\n    def construct(self):\n        pass\n\nclass InterfaceDis(ABC):\n    \n    @abstractmethod\n    def dissaster(self):\n        pass\n\nclass SpecialForce(ArmyB, InterfaceAta):\n\n    def attack(self):\n        return f'{self.name} en misión especial.'\n\nclass Marine(ArmyB, InterfaceAta, InterfaceDef):\n\n    def attack(self):\n        return f'{self.name} desembarcanado en la playa.'\n\n    def deffense(self):\n        return f'{self.name} vigilando el horizonte.'\n\nclass Engineers(ArmyB, InterfaceCon):\n\n    def construct(self):\n        return f'{self.name} reconstruyendo puentes.'\n\nclass Emrgency(ArmyB, InterfaceCon, InterfaceDis):\n\n    def construct(self):\n        return f'{self.name} desescombrando caminos.'\n\n    def dissaster(self):\n        return f'{self.name} ayudando al personal civil.'\n\nspecialforce = SpecialForce(\"Boina Verde\")\nmarine = Marine(\"Marines\")\nengineers = Engineers(\"Ingenieros\")\nemrgency = Emrgency(\"UME\")\n\nprint(specialforce.attack())\nprint(marine.attack())\nprint(marine.deffense())\nprint(engineers.construct())\nprint(emrgency.construct())\nprint(emrgency.dissaster())\n\n#-----EXTRA-----\nseparacion('EXTRA')\n\nclass InterfacePrintBW(ABC):\n    \n    @abstractmethod\n    def print_bw(self, document: str):\n        return f'Se está imprimiendo el documento \"{document}\" en blanco y negro.'\n\nclass InterfacePrintColor(ABC):\n    \n    @abstractmethod\n    def print_color(self, document: str):\n        return f'Se está imprimiendo el documento \"{document}\" en color.'\n\nclass InterfaceScan(ABC):\n    \n    @abstractmethod\n    def scan(self, document: str):\n        return f'Se está escaneando el documento y se guardará en el archivo \"{document}\".'\n\nclass InterfaceSendFax(ABC):\n    \n    @abstractmethod\n    def send_fax(self, document: str):\n        return f'Se está enviando por fax el archivo \"{document}\".'\n\nclass Printer:\n\n    def __init__(self, name: str):\n        self.name = name\n\nclass BWPrinter(Printer, InterfacePrintBW):\n\n    def print_bw(self, document):\n        print(f'Impresora {self.name}:')\n        print(super().print_bw(document))\n        print(f'Se terminó de imprimir el documento \"{document}\"')\n\nclass ColorPrinter(Printer, InterfacePrintColor):\n\n    def print_color(self, document):\n        print(f'Impresora {self.name}:')\n        print(super().print_color(document))\n        print(f'Se terminó de imprimir el documento \"{document}\"')\n\nclass MultiFunctionPrinter(Printer, InterfacePrintBW, InterfacePrintColor, InterfaceScan, InterfaceSendFax):\n\n    def print_bw(self, document):\n        print(f'Impresora {self.name}:')\n        print(super().print_bw(document))\n        print(f'Se terminó de imprimir el documento \"{document}\"')\n\n    def print_color(self, document):\n        print(f'Impresora {self.name}:')\n        print(super().print_color(document))\n        print(f'Se terminó de imprimir el documento \"{document}\"')\n\n    def send_fax(self, document):\n        print(f'Impresora {self.name}:')\n        print(super().send_fax(document))\n        print(f'Se terminó de enviar por fax el documento \"{document}\"')\n\n    def scan(self, document):\n        print(f'Impresora {self.name}:')\n        print(super().scan(document))\n        print(f'Se terminó de escanear \"{document}\" guardado en el PC.')\n\nbw_matricial = BWPrinter(\"Matricial\")\nmulti_equipment = MultiFunctionPrinter(\"RR4589\")\ncolor_printer = ColorPrinter(\"NZ5200\")\n\ndef test_printer(printer):\n    try:\n        printer.print_bw(\"elcamino.pdf\")\n    except AttributeError:\n        pass\n    \n    try:\n        printer.print_color(\"SupermanN342.pdf\")\n    except AttributeError:\n        pass\n    \n    try:\n        printer.scan(\"justificante.pdf\")\n    except AttributeError:\n        pass\n    \n    try:\n        printer.send_fax(\"justificante.pdf\")\n    except AttributeError:\n        pass\n\ntest_printer(bw_matricial)\ntest_printer(color_printer)\ntest_printer(multi_equipment)\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/bytecodesky.py",
    "content": "#  * EJERCICIO:\n#  * Explora el \"Principio SOLID de Segregación de Interfaces (Interface Segregation Principle, ISP)\" \n#  * y crea un ejemplo simple donde se muestre su funcionamiento de forma correcta e incorrecta.\n#  *\n\n#El principio de segregación de interfaces establece que un cliente no debe ser forzado a depender de interfaces que no utiliza.\n#En otras palabras, no se debe obligar a una clase a implementar interfaces que no necesita. \n# En lugar de eso, se deben dividir las interfaces en interfaces más pequeñas y específicas, de modo que las clases solo implementen las interfaces que son de su interés. \n#De esta forma, se evita que las clases tengan que implementar métodos que no necesitan, lo que puede llevar a una mayor complejidad y a un código más difícil de mantener.\n\n#ejemplo incorrecto donde se viola el principio de segregación de interfaces\nclass IShape:\n    def draw(self):\n        pass\n\n    def calculate_area(self):\n        pass\n\nclass Circle(IShape):\n    def draw(self):\n        print(\"Circle Drawn\")\n\n    def calculate_area(self):\n        print(\"Circle Area Calculated\")\n\nclass Square(IShape):\n    def draw(self):\n        print(\"Square Drawn\")\n\n    def calculate_area(self):\n        print(\"Square Area Calculated\")\n\n#En el ejemplo anterior, la interfaz IShape tiene dos métodos: draw() y calculate_area(). \n#Las clases Circle y Square implementan esta interfaz, pero no necesitan ambos métodos.\n#Circle solo necesita el método draw() y Square solo necesita el método calculate_area().\n#Esto viola el principio de segregación de interfaces, ya que las clases están obligadas a implementar métodos que no necesitan.\n\n#ejemplo correcto donde se cumple el principio de segregación de interfaces\nclass IDrawable:\n    def draw(self):\n        pass\n\nclass ICalculatable:\n    def calculate_area(self):\n        pass\n\nclass Circle(IDrawable):\n    def draw(self):\n        print(\"Circle Drawn\")\n\nclass Square(ICalculatable):\n    def calculate_area(self):\n        print(\"Square Area Calculated\")\n\n#En el ejemplo anterior, se han dividido las interfaces en IDrawable e ICalculatable, de modo que las clases solo implementan las interfaces que necesitan.\n#Circle implementa la interfaz IDrawable y Square implementa la interfaz ICalculatable,lo que evita que tengan que implementar métodos que no necesitan. Esto cumple con el principio de segregación de interfaces.\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea un gestor de impresoras.\n#  * Requisitos:\n#  * 1. Algunas impresoras sólo imprimen en blanco y negro.\n#  * 2. Otras sólo a color.\n#  * 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n#  * Instrucciones:\n#  * 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n#  * 2. Aplica el ISP a la implementación.\n#  * 3. Desarrolla un código que compruebe que se cumple el principio.\n\nfrom abc import ABC, abstractmethod\n\nclass Impresora(ABC):\n    @abstracmethod\n    def imprimir(self, documento):\n        pass\n\nclass ImpresoraBN(Impresora):\n    def imprimir(self, documento):\n        print(f\"Se ha impreso el {documento} a blanco y negro\")\n\nclass ImpresoraColor(Impresora):\n    def imprimir(self, documento):\n        print(f\"Se ha impreso el {documento} a color\")\n\nclass ImpresoraMul(Impresora):\n    def imprimir(self, documento):\n        print(f\"Se ha impreso {documento} en multifuncion\")\n    \n    def scanner(self, documento):\n        print(f\"Se escaneo el {documento}\")\n    \n    def fax(self, documento, nfax):\n        print(f\"Se envio el {documento} por fax con el numero {nfax}\")\n\n\nclass GesImpresoras:\n    def __init__(self):\n        self.impresoras = []\n    \n    def agg_impresoras(self, impresora):\n        self.impresoras.append(impresora)\n\n    def imp_doc(self, documento, tipo_impresora=None):\n        for impresora in self.impresoras:\n            if tipo_impresora is None or isinstance(impresora, tipo_impresora):\n                impresora.imprimir(documento)\n                break\n            else:\n                print('No se encontro la impresora')\n\ngestor = GesImpresoras()\ngestor.agg_impresoras(ImpresoraBN())\ngestor.agg_impresoras(ImpresoraColor())\ngestor.agg_impresoras(ImpresoraMul())\n\ngestor.imp_doc('documento', ImpresoraBN)\ngestor.imp_doc('documento', ImpresoraColor)\ngestor.imp_doc('documento', ImpresoraMul)\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/cristianfloyd.py",
    "content": "# EJERCICIO:\n# Explora el \"Principio SOLID de Segregación de Interfaces\n# (Interface Segregation Principle, ISP)\", y crea un ejemplo\n# simple donde se muestre su funcionamiento de forma correcta e incorrecta.\nfrom abc import ABC, abstractmethod\n\n\n# Ejemplo Incorrecto\nclass MetodoPagoInterface(ABC):\n    @abstractmethod\n    def procesar_pago(self, monto: float) -> str:\n        pass\n\n    @abstractmethod\n    def reembolsar_pago(self, monto: float) -> str:\n        pass\n\n    @abstractmethod\n    def dividir_en_cuotas(self, monto: float, cuotas: int) -> str:\n        pass\n\n\nclass PagoEfectivo(MetodoPagoInterface):\n    def procesar_pago(self, monto: float) -> str:\n        return f\"Pago procesado correctamente de ${monto}\"\n\n    def reembolsar_pago(self, monto: float) -> str:\n        return f\"Pago reembolsado correctamente de ${monto}\"\n\n    def dividir_en_cuotas(self, monto: float, cuotas: int) -> str:  # No se divide en cuotas\n        raise NotImplementedError(\"El efectivo no se divide en cuotas\")\n\n\nclass PagoTarjeta(MetodoPagoInterface):\n    def procesar_pago(self, monto: float) -> str:\n        return f\"Pago procesado correctamente de ${monto}\"\n\n    def reembolsar_pago(self, monto: float) -> str:\n        return f\"Pago reembolsado correctamente de ${monto}\"\n\n    def dividir_en_cuotas(self, monto: float, cuotas: int) -> str:\n        return f\"Pago dividido en {cuotas} cuotas de ${monto / cuotas}\"\n\n\n# Ejemplo Correcto\nclass Pagable(ABC):\n    @abstractmethod\n    def procesar_pago(self, monto: float) -> str:\n        pass\n\n\nclass Reembolsable(ABC):\n    @abstractmethod\n    def reembolsar_pago(self, monto: float) -> str:\n        pass\n\n\nclass Financiable(ABC):\n    @abstractmethod\n    def dividir_en_cuotas(self, monto: float, cuotas: int) -> str:\n        pass\n\n\nclass PagoEfectivoV2(Pagable, Reembolsable):\n    def procesar_pago(self, monto: float):\n        return f\"Pago procesado correctamente de ${monto}\"\n\n    def reembolsar_pago(self, monto: float):\n        return f\"Pago reembolsado correctamente de ${monto}\"\n\n\nclass PagoTarjetaV2(Pagable, Reembolsable, Financiable):\n    def procesar_pago(self, monto: float):\n        return f\"Pago procesado correctamente de ${monto}\"\n\n    def reembolsar_pago(self, monto: float):\n        return f\"Pago reembolsado correctamente de ${monto}\"\n\n    def dividir_en_cuotas(self, monto: float, cuotas: int):\n        return f\"Pago dividido en {cuotas} cuotas de ${monto / cuotas}\"\n\n\nclass PagoCriptomoneda(Pagable):\n    def procesar_pago(self, monto: float):\n        return f\"Pago procesado correctamente en criptomoneda de ${monto}\"\n\n\n# DIFICULTAD EXTRA (opcional):\n# Crea un gestor de impresoras.\n# Requisitos:\n# 1. Algunas impresoras sólo imprimen en blanco y negro.\n# 2. Otras sólo a color.\n# 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n# Instrucciones:\n# 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n# 2. Aplica el ISP a la implementación.\n# 3. Desarrolla un código que compruebe que se cumple el principio.\n\n\n# Interfaces segregadas\nclass DispositivoIdentificable(ABC):\n    @abstractmethod\n    def get_modelo(self) -> str:\n        pass\n\nclass ImprimibleBlancoNegro(DispositivoIdentificable):\n\n    @abstractmethod\n    def imprimir_blanco_negro(self, documento: str) -> str:\n        pass\n\n\nclass ImprimibleColor(DispositivoIdentificable):\n\n    @abstractmethod\n    def imprimir_color(self, documento: str) -> str:\n        pass\n\n\nclass Escaneable(DispositivoIdentificable):\n    \n    @abstractmethod\n    def escanear(self, documento: str) -> str:\n        pass\n\n\nclass EnviadorFax(DispositivoIdentificable):\n    \n    @abstractmethod\n    def enviar_fax(self, documento: str, destino: str) -> str:\n        pass\n\n\n\n# implementaciones concretas\n# ---------------------------------------------------------------------------\nclass ImpresoraBlancoNegro(ImprimibleBlancoNegro):\n    def __init__(self, modelo: str) -> None:\n        self.modelo = modelo\n        self.paginas_impresas = 0\n\n    def get_modelo(self) -> str:\n        return self.modelo\n\n    def imprimir_blanco_negro(self, documento: str) -> str:\n        self.paginas_impresas += 1\n        return f\"[{self.modelo}] Imprimiendo '{documento}' en blanco y negro (Página #{self.paginas_impresas})\"\n\n\nclass ImpresoraColor(ImprimibleColor):\n    def __init__(self, modelo: str) -> None:\n        self.modelo = modelo\n        self.paginas_impresas = 0\n\n    def get_modelo(self) -> str:\n        return self.modelo\n\n    def imprimir_color(self, documento: str) -> str:\n        self.paginas_impresas += 1\n        return f\"[{self.modelo}] Imprimiendo '{documento}' en color (Página #{self.paginas_impresas})\"\n\n\nclass ImpresoraMultifuncion(\n    ImprimibleBlancoNegro, ImprimibleColor, Escaneable, EnviadorFax\n):\n    def __init__(self, modelo: str) -> None:\n        self.modelo = modelo\n        self.paginas_impresas = 0\n        self.paginas_escaneadas = 0\n        self.paginas_enviadas_fax = 0\n\n    def get_modelo(self) -> str:\n        return self.modelo\n\n    def imprimir_blanco_negro(self, documento: str) -> str:\n        self.paginas_impresas += 1\n        return f\"[{self.modelo}] Imprimiendo '{documento}' en blanco y negro (Página #{self.paginas_impresas})\"\n\n    def imprimir_color(self, documento: str) -> str:\n        self.paginas_impresas += 1\n        return f\"[{self.modelo}] Imprimiendo '{documento}' en color (Página #{self.paginas_impresas})\"\n\n    def escanear(self, documento: str) -> str:\n        self.paginas_escaneadas += 1\n        return f\"[{self.modelo}] Escaneando '{documento}' (Página #{self.paginas_escaneadas})\"\n\n    def enviar_fax(self, documento: str, destino: str) -> str:\n        self.paginas_enviadas_fax += 1\n        return f\"[{self.modelo}] Enviando fax '{documento}' (Página #{self.paginas_enviadas_fax})\"\n\n\nclass ImpresoraAvanzadaColor(ImprimibleColor, Escaneable):\n    def __init__(self, modelo: str) -> None:\n        self.modelo = modelo\n        self.paginas_impresas = 0\n        self.paginas_escaneadas = 0\n\n    def get_modelo(self) -> str:\n        return self.modelo\n\n    def imprimir_color(self, documento: str) -> str:\n        self.paginas_impresas += 1\n        return f\"[{self.modelo}] Imprimiendo '{documento}' en color (Página #{self.paginas_impresas})\"\n\n    def escanear(self, documento: str) -> str:\n        self.paginas_escaneadas += 1\n        return f\"[{self.modelo}] Escaneando '{documento}' (Página #{self.paginas_escaneadas})\"\n\n\n### ================================================ ###\n### PRUEBAS\n### ================================================ ###\n\n\ndef probar_impresora_bn(impresora: ImprimibleBlancoNegro):\n    print(f\"\\n Probando impresora BN: {impresora.get_modelo()}\")\n    print(impresora.imprimir_blanco_negro(\"Documento.pdf\"))\n\n\ndef probar_impresora_color(impresora: ImprimibleColor):\n    print(f\"\\nProbando impresora a color: {impresora.get_modelo()}\")\n    print(impresora.imprimir_color('presentacion.pptx'))\n\n\ndef probar_escaner(dispositivo: Escaneable):\n    print(f\"\\nProbando escáner: {dispositivo.get_modelo()}\")\n    print(dispositivo.escanear('contrato.pdf'))\n\n\ndef probar_fax(dispositivo: EnviadorFax):\n    print(f\"\\nProbando fax: {dispositivo.get_modelo()}\")\n    print(dispositivo.enviar_fax('documento_urgente.pdf', '+34-123-456-789'))\n\n\ndef probar_multifuncion(impresora: ImpresoraMultifuncion):\n    print(f\"\\nProbando impresora multifunción: {impresora.get_modelo()}\")\n    print(f\"  {impresora.imprimir_blanco_negro('factura.pdf')}\")\n    print(impresora.imprimir_color('foto.jpg'))\n    print(impresora.escanear('recibo.pdf'))\n    print(impresora.enviar_fax('orden.pdf', '+34-987-654-321'))\n\n\nhp_laserjet = ImpresoraBlancoNegro(\"HP LaserJet Pro\")\nepson_colorjet = ImpresoraColor(\"Epson EcoTank Color\")\ncanon_multifuncion = ImpresoraMultifuncion(\"Canon PIXMA MX922\")\nbrother_avanzada = ImpresoraAvanzadaColor(\"Brother MFC-J995DW\")\n\nprint(\"\\nProbando impresora blanco y negro:\")\nprobar_impresora_bn(hp_laserjet)\nprobar_impresora_bn(canon_multifuncion) \n\nprint(\"\\nProbando impresora a color:\")\nprobar_impresora_color(epson_colorjet)\nprobar_impresora_color(canon_multifuncion)\nprobar_impresora_color(brother_avanzada)\n\nprint(\"\\nProbando escáner:\")\nprobar_escaner(canon_multifuncion)\nprobar_escaner(brother_avanzada)\n\nprint(\"\\nProbando fax:\")\nprobar_fax(canon_multifuncion)\n\nprint(\"\\nProbando multifunción:\")\nprobar_multifuncion(canon_multifuncion)\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/cyberdidac.py",
    "content": "from abc import ABC, abstractmethod\n\n\nclass BWPrinter(ABC):\n    @abstractmethod\n    def print_BW(self, file):\n        pass\n\n\nclass ColorPrinter(ABC):\n    @abstractmethod\n    def print_color(self, file):\n        pass\n\n\nclass Scanner(ABC):\n    @abstractmethod\n    def scann(self, file):\n        pass\n\n\nclass Fax(ABC):\n    @abstractmethod\n    def send(self, file):\n        pass\n\n\nclass PrinterBW(BWPrinter):\n    def print_BW(self, file):\n        print(f\"Imprimiendo {file} en blanco y negro\")\n\n\nclass PrinterColor(ColorPrinter):\n    def print_color(self, file):\n        print(f\"Imprimiendo {file} en color\")\n\n\nclass Multiprinter(BWPrinter, ColorPrinter, Scanner, Fax):\n    def print_BW(self, file):\n        print(f\"Imprimiendo {file} en blanco y negro\")\n\n    def print_color(self, file):\n        print(f\"Imprimiendo {file} en color\")\n\n    def scann(self, file):\n        print(f\"Escaneando {file}\")\n\n    def send(self, file):\n        print(f\"Enviando {file}\")\n\n\ndef main():\n    bw_printer = PrinterBW()\n    color_printer = PrinterColor()\n    multiprinter = Multiprinter()\n\n    bw_printer.print_BW(\"CV\")\n    color_printer.print_color(\"CV\")\n    multiprinter.print_BW(\"CV\")\n    multiprinter.print_color(\"CV\")\n    multiprinter.scann(\"CV\")\n    multiprinter.send(\"CV\")\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/davidrguez98.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Segregación de Interfaces (Interface Segregation Principle, ISP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un gestor de impresoras.\n * Requisitos:\n * 1. Algunas impresoras sólo imprimen en blanco y negro.\n * 2. Otras sólo a color.\n * 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n * Instrucciones:\n * 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n * 2. Aplica el ISP a la implementación.\n * 3. Desarrolla un código que compruebe que se cumple el principio.\n */ \"\"\"\n\nfrom abc import ABC, abstractmethod\n\n#EJERCICIO\n\n\"\"\" \nIncorrecto\n\"\"\"\n\nclass WorkerInterface(ABC):\n\n    @abstractmethod\n    def work(self):\n        pass\n\n    @abstractmethod\n    def eat(self):\n        pass\n\nclass Human(WorkerInterface):\n\n    def work(self):\n        print(\"Trabajando\")\n\n    def eat(self):\n        print(\"Comiendo\")\n\nclass Robot(WorkerInterface):\n\n    def work(self):\n        print(\"Trabajando\")\n\n    def eat(self):\n        pass\n\nhuman = Human()\nhuman.work()\nhuman.eat()\n\nrobot = Robot()\nrobot.work()\nrobot.eat()\n\n\"\"\" \nCorrecto\n\"\"\"\n\nclass WorkInterface(ABC):\n\n    @abstractmethod\n    def work(self):\n        pass\n\nclass EatInterface(ABC):\n\n    @abstractmethod\n    def eat(self):\n        pass\n\nclass Human(WorkInterface, EatInterface):\n\n    def work(self):\n        print(\"Trabajando\")\n\n    def eat(self):\n        print(\"Comiendo\")\n\nclass Robot(WorkInterface):\n\n    def work(self):\n        print(\"Trabajando\")\n\nhuman = Human()\nhuman.work()\nhuman.eat()\n\nrobot = Robot()\nrobot.work()\n\n#DIFICULTAD EXTRA\n\nclass BlackPrinter(ABC):\n\n    @abstractmethod\n    def print(self):\n        pass\n\nclass ColorPrinter(ABC):\n\n    @abstractmethod\n    def print_color(self):\n        pass\n\nclass ScanPrinter(ABC):\n\n    @abstractmethod\n    def scan(self):\n        pass\n\nclass FaxPrinter(ABC):\n\n    @abstractmethod\n    def send_fax(self):\n        pass\n\nclass Printer_one(BlackPrinter):\n\n    def print(self):\n        print(\"Imprimiendo en blanco y negro.\")\n\nclass Printer_two(BlackPrinter):\n\n    def print(self):\n        print(\"Imprimiendo en blanco y negro.\")\n\nclass Printer_three(ColorPrinter):\n\n    def print_color(self):\n        print(\"Imprimiendo en color.\")\n\nclass Printer_four(ColorPrinter):\n\n    def print_color(self):\n        print(\"Imprimiendo en color.\")\n\nclass Printer_Five(BlackPrinter, ColorPrinter, ScanPrinter, FaxPrinter):\n\n    def print(self):\n        print(\"Imprimiendo en blanco y negro.\")\n\n    def print_color(self):\n        print(\"Imprimiendo en color.\")\n\n    def scan(self):\n        print(\"Escaneando.\")\n\n    def send_fax(self):\n        print(\"Enviando fax.\")\n\nclass Printer_Six(BlackPrinter, ColorPrinter, ScanPrinter, FaxPrinter):\n\n    def print(self):\n        print(\"Imprimiendo en blanco y negro.\")\n\n    def print_color(self):\n        print(\"Imprimiendo en color.\")\n\n    def scan(self):\n        print(\"Escaneando.\")\n\n    def send_fax(self):\n        print(\"Enviando fax.\")\n\nprinter1 = Printer_one()\nprinter1.print()\n\nprinter2 = Printer_two()\nprinter2.print()\n\nprinter3 = Printer_three()\nprinter3.print_color()\n\nprinter4 = Printer_four()\nprinter4.print_color()\n\nprinter5 = Printer_Five()\nprinter5.print()\nprinter5.print_color()\nprinter5.scan()\nprinter5.send_fax()\n\nprinter6 = Printer_Six()\nprinter6.print()\nprinter6.print_color()\nprinter6.scan()\nprinter6.send_fax()"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/duendeintemporal.py",
    "content": "#29 { Retos para Programadores } Principio SOLID de Segregación de Interfaces (Interface Segregation Principle, ISP) \n\n# Bibliography reference:\n# The Web Development Glossary (Jens Oliver Meiert) (Z-Library)\n# I use GPT as a reference and sometimes to correct or generate proper comments.\n\n\"\"\"  \n* EJERCICIO:\n * Explora el \"Principio SOLID de Segregación de Interfaces\n * (Interface Segregation Principle, ISP)\", y crea un ejemplo\n * simple donde se muestre su funcionamiento de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un gestor de impresoras.\n * Requisitos:\n * 1. Algunas impresoras sólo imprimen en blanco y negro.\n * 2. Otras sólo a color.\n * 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n * Instrucciones:\n * 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n * 2. Aplica el ISP a la implementación.\n * 3. Desarrolla un código que compruebe que se cumple el principio.\n \"\"\"\n\n\"\"\" Interface Segregation Principle\nThe principle that no client should be forced to depend on methods it does\nnot use. ISP splits interfaces that are very large into smaller and more\nspecific ones so that clients will only have to know about the methods that\nare of interest to them. Such shrunken interfaces are also called role\ninterfaces. ISP is intended to keep a system decoupled and thus easier to\nrefactor, change, and redeploy.  \"\"\"\n\n\n# Shorthan for print\nlog = print\n\n# Incorrect Example\n\nclass PaymentService:\n    def process_credit_card_payment(self, amount):\n        pass\n\n    def process_paypal_payment(self, amount):\n        pass\n\n    def process_bitcoin_payment(self, amount):\n        pass\n\n\nclass CreditCardPayment(PaymentService):\n    def process_credit_card_payment(self, amount):\n        log(f\"Processing credit card payment of {amount}\")\n\n    def process_paypal_payment(self, amount):\n        raise Exception(\"This payment method does not support PayPal payments\")\n\n    def process_bitcoin_payment(self, amount):\n        raise Exception(\"This payment method does not support Bitcoin payments\")\n\n\nclass PayPalPayment(PaymentService):\n    def process_credit_card_payment(self, amount):\n        raise Exception(\"This payment method does not support credit card payments\")\n\n    def process_paypal_payment(self, amount):\n        log(f\"Processing PayPal payment of {amount}\")\n\n    def process_bitcoin_payment(self, amount):\n        raise Exception(\"This payment method does not support Bitcoin payments\")\n\n\nclass BitcoinPayment(PaymentService):\n    def process_credit_card_payment(self, amount):\n        raise Exception(\"This payment method does not support credit card payments\")\n\n    def process_paypal_payment(self, amount):\n        raise Exception(\"This payment method does not support PayPal payments\")\n\n    def process_bitcoin_payment(self, amount):\n        log(f\"Processing Bitcoin payment of {amount}\")\n\n\n# Example usage\ncredit_card_payment = CreditCardPayment()\ncredit_card_payment.process_credit_card_payment(250)  # Processing credit card payment of 250\n# credit_card_payment.process_paypal_payment(87)  # This will raise an exception\n# Exception: This payment method does not support PayPal payments\n\n# Correct Example\n\nclass CreditCardPaymentService:\n    def process_credit_card_payment(self, amount):\n        print(f\"Processing credit card payment of {amount}\")\n\n\nclass PayPalPaymentService:\n    def process_paypal_payment(self, amount):\n        print(f\"Processing PayPal payment of {amount}\")\n\n\nclass BitcoinPaymentService:\n    def process_bitcoin_payment(self, amount):\n        print(f\"Processing Bitcoin payment of {amount}\")\n\n\n# Example usage\ncredit_card_payment1 = CreditCardPaymentService()\ncredit_card_payment1.process_credit_card_payment(400)  # Processing credit card payment of 400\n\npay_pal_payment = PayPalPaymentService()\npay_pal_payment.process_paypal_payment(130)  # Processing PayPal payment of 130\n\nbitcoin_payment = BitcoinPaymentService()\nbitcoin_payment.process_bitcoin_payment(0.020)  # Processing Bitcoin payment of 0.02\n\n\n# Extra Difficulty Exercise\n\nclass BlackAndWhitePrinter:\n    def print(self, doc):\n        print(f\"Printing: {doc} in Black & White\")\n\n\nclass ColorPrinter:\n    def print(self, doc):\n        print(f\"Printing: {doc} in Color\")\n\n\nclass MultiFunctionPrinter:\n    def print_in_black_and_white(self, doc):\n        print(f\"Printing: {doc} in Black & White\")\n\n    def print(self, doc):\n        print(f\"Printing: {doc} in Color\")\n\n    def fax(self, doc):\n        print(f\"Faxing: {doc}\")\n\n    def scan(self, doc):\n        print(f\"Scanning: {doc}\")\n\n\n# Example usage for printers\nbook = 'vuelointemporal.odt'\n\nbw_printer = BlackAndWhitePrinter()\nbw_printer.print(book)  # Printing: vuelointemporal.odt in Black & White\n\nc_printer = ColorPrinter()\nc_printer.print(book)  # Printing: vuelointemporal.odt in Color\n\nm_printer = MultiFunctionPrinter()\nm_printer.print_in_black_and_white(book)  # Printing: vuelointemporal.odt in Black & White\nm_printer.print(book)  # Printing: vuelointemporal.odt in Color\nm_printer.fax(book)  # Faxing: vuelointemporal.odt\nm_printer.scan(book)  # Scanning: vuelointemporal.odt\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/fborjalv.py",
    "content": "\n\nfrom abc import ABC, abstractmethod\n\n\"\"\"\n * EJERCICIO:\n * Explora el \"Principio SOLID de Segregación de Interfaces\n * (Interface Segregation Principle, ISP)\", y crea un ejemplo\n * simple donde se muestre su funcionamiento de forma correcta e incorrecta.\n\"\"\"\nfrom abc import ABC, abstractmethod\n\n\n# FORMA INCORRECTA\n\nclass HumanResourcesManagement(ABC):\n\n    @abstractmethod\n    def make_annual_budget(self):\n        pass\n    \n    @abstractmethod\n    def project_managment(self):\n        pass\n\n    @abstractmethod\n    def work_on_a_project(self):\n        pass\n\n\nclass Executive(HumanResourcesManagement):\n\n    def make_annual_budget(self):\n        print(\"Ha comenzado la elaboración del presupuesto anual\")\n\n    def project_management(self):\n        print(\"Ha comenzado a gestionar en un nuevo proyecto\")\n    \n    def work_on_a_project(self):\n        # Los directivos no trabajan en proyectos\n        pass\n\nclass Worker(HumanResourcesManagement):\n\n    def make_annual_budget(self):\n        # Los trabajadores no participan en la elaboración de prespuestos\n        pass\n\n    def project_management(self):\n        # Los trabajadores no gestionan los proyectos\n        pass\n\n    def work_on_a_project(self):\n        print(\"Ha comenzado a trabajar en un nuevo proyecto\")\n\n\n# FORMA CORRECTA\n\nclass ManagementInterface(ABC):\n    @abstractmethod\n    def make_annual_budget(self):\n        pass\n    \n    @abstractmethod\n    def project_management(self):\n        pass\n\nclass WokerInterface(ABC):\n    @abstractmethod\n    def work_on_a_project(self):\n        pass\n\nclass Executive(ManagementInterface):\n\n    def make_annual_budget(self):\n        print(\"Ha comenzado la elaboración del presupuesto anual\")\n\n    def project_management(self):\n        print(\"Ha comenzado a gestionar en un nuevo proyecto\")\n    \n\nclass Worker(WokerInterface):\n\n    def work_on_a_project(self):\n        print(\"Ha comenzado a trabajar en un nuevo proyecto\")\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n * Crea un gestor de impresoras.\n * Requisitos:\n * 1. Algunas impresoras sólo imprimen en blanco y negro.\n * 2. Otras sólo a color.\n * 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n * Instrucciones:\n * 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n * 2. Aplica el ISP a la implementación.\n * 3. Desarrolla un código que compruebe que se cumple el principio.\n\n\n\"\"\"\n\n\nclass BWPrinterInterface(ABC):\n    @abstractmethod\n    def bw_print(self, document_name):\n        pass\n\nclass ColorPrinterInterface(ABC):\n    @abstractmethod\n    def color_print(self, document_name):\n        pass\nclass ScanInterface(ABC):\n    @abstractmethod\n    def scan(self, document_name):\n        pass\n\nclass FaxInterface(ABC):\n    @abstractmethod\n    def send_fax(self, document_name):\n        pass\n\n\n\nclass BWPrinter(BWPrinterInterface):\n    def bw_print(self, document_name):\n        print(f\"Está imprimiendo el documento {document_name} en blanco y negro\")\n\nclass ColorPrinter(ColorPrinterInterface):\n    def color_print(self, document_name):\n        print(f\"Está imprimiendo el documento {document_name} en color\")\n\nclass MultifunctionPrinter(ScanInterface, FaxInterface,  BWPrinterInterface, ColorPrinterInterface):\n    \n    def bw_print(self, document_name):\n        print(f\"Está imprimiendo el documento {document_name} en blanco y negro\")\n    def color_print(self, document_name):\n        print(f\"Está imprimiendo el documento {document_name} en color\")\n    def scan(self, document_name):\n        print(f\"Está escaneando el documento {document_name}\")\n    def send_fax(self, document_name):\n        print(f\"Está enviando  el documento {document_name} mediante fax\")\n\n\n\nmy_multifuction = MultifunctionPrinter()\n\nmy_multifuction.scan(\"my_document.word\")\nmy_multifuction.send_fax(\"my_document.word\")\nmy_multifuction.bw_print(\"my_document.word\")\nmy_multifuction.color_print(\"my_document.word\")\n\nmy_bwprinter = BWPrinter()\nmy_bwprinter.bw_print(\"my_document.word\")\n\nmy_color_printer = ColorPrinter()\nmy_color_printer.color_print(\"my_document.word\")"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/franxiscodev.py",
    "content": "'''\nSOLID\nISP: Interface Swgregation Principle\nprincipio de segregación de interfaces\n    # no se puede usar el método de la clase padre\n    # en la clase hija\n    # se debe crear una interfaz para cada clase hija\n    # y no una interfaz para todas las clases hijas\n    \n'''\nfrom abc import ABC, abstractmethod\n\n# Sin ISP\n\n\nclass WorkerInteface(ABC):\n    @abstractmethod\n    def work(self):\n        pass\n\n    @abstractmethod\n    def eat(self):\n        pass\n\n\nclass HumanWorker(WorkerInteface):\n    def work(self):\n        print(\"Trabajando\")\n\n    def eat(self):\n        print(\"Comiendo\")\n\n\nclass RobotWorker(WorkerInteface):\n    def work(self):\n        print(\"Trabajando\")\n\n    def eat(self):\n        # no se puede usar el método de la clase padre en la clase hija rompe el ISP\n        raise NotImplementedError(\"Los robots no comen\")\n\n# ISP\n\n\nclass WorkInteface(ABC):\n    @abstractmethod\n    def work(self):\n        pass\n\n\nclass EatInteface(ABC):\n    @abstractmethod\n    def eat(self):\n        pass\n\n\nclass HumanWorker(WorkInteface, EatInteface):\n    def work(self):\n        print(\"Trabajando\")\n\n    def eat(self):\n        print(\"Comiendo\")\n\n\nclass RobotWorker(WorkInteface):\n    def work(self):\n        print(\"Trabajando\")\n\n# Extra\n\n\nclass PrinterInteface(ABC):\n    @abstractmethod\n    def print(self, document: str):\n        pass\n\n\nclass ColorPrinterInteface(ABC):\n    @abstractmethod\n    def print_color(self, document: str):\n        pass\n\n\nclass ScannerInteface(ABC):\n    @abstractmethod\n    def scan(self, document: str) -> str:\n        pass\n\n\nclass FaxInteface(ABC):\n    @abstractmethod\n    def send_fax(self, document: str):\n        pass\n\n\nclass Printer(PrinterInteface):\n    def print(self, document: str):\n        print(f\"Imprimiendo {document} en blanco y negro\")\n\n\nclass ColorPrinter(ColorPrinterInteface):\n    def print_color(self, document: str):\n        print(f\"Imprimiendo {document} en color\")\n\n\nclass MultifunctionPrinter(PrinterInteface, ColorPrinterInteface, ScannerInteface, FaxInteface):\n    def print(self, document: str):\n        print(f\"Imprimiendo {document} en blanco y negro\")\n\n    def print_color(self, document: str):\n        print(f\"Imprimiendo {document} en color\")\n\n    def scan(self, document: str) -> str:\n        print(f\"Escaneando {document}\")\n        return document\n\n    def send_fax(self, document: str):\n        print(f\"Enviando fax de {document}\")\n\n\ndef test_printer():\n    printer = Printer()\n    color_printer = ColorPrinter()\n    mfp = MultifunctionPrinter()\n\n    printer.print(\"documento1.txt\")\n    color_printer.print_color(\"documento2.txt\")\n    print(\"\\tMultifunción\")\n    mfp.print(\"documento_byn.pdf\")\n    mfp.print_color(\"documento_color.pdf\")\n    mfp.scan(\"documento_scan.pdf\")\n    mfp.send_fax(\"documento_fax.pdf\")\n\n\ntest_printer()\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/hectorio23.py",
    "content": "# Autor: Héctor Adán\n# GitHub: https://github.com/hectorio23 \nfrom abc import ABC, abstractmethod\n\n# Define una interfaz abstracta para la funcionalidad de impresión\nclass Printer(ABC):\n    @abstractmethod\n    def print(self):\n        pass\n\n# Define una interfaz abstracta para la funcionalidad de escaneo\nclass Scanner(ABC):\n    @abstractmethod\n    def scan(self):\n        pass\n\n# Define una interfaz abstracta para la funcionalidad de fax\nclass Fax(ABC):\n    @abstractmethod\n    def fax(self):\n        pass\n\n# Implementa una impresora en blanco y negro que solo necesita la interfaz de impresión\nclass BlackAndWhitePrinter(Printer):\n    def print(self):\n        return \"[+] - Imprimiendo en blanco y negro\"\n\n# Implementa una impresora a color que solo necesita la interfaz de impresión\nclass ColorPrinter(Printer):\n    def print(self):\n        return \"[+] - Imprimiendo en color\"\n\n# Implementa una impresora multifunción que necesita todas las interfaces: impresión, escaneo y fax\nclass MultiFunctionPrinter(Printer, Scanner, Fax):\n    def print(self):\n        return \"[+] - Imprimiendo en multifunción\"\n\n    def scan(self):\n        return \"[+] - Escaneando en multifunción\"\n\n    def fax(self):\n        return \"[+] - Enviando fax en multifunción\"\n\n# Función que prueba la funcionalidad de impresión de una impresora\ndef test_printer(printer: Printer):\n    print(printer.print())\n\n# Función que prueba la funcionalidad de escaneo de un escáner\ndef test_scanner(scanner: Scanner):\n    print(scanner.scan())\n\n# Función que prueba la funcionalidad de fax de un dispositivo de fax\ndef test_fax(fax: Fax):\n    print(fax.fax())\n\n# Crear instancias de las impresoras\nb_and_w_printer = BlackAndWhitePrinter()\ncolor_printer = ColorPrinter()\nmulti_printer = MultiFunctionPrinter()\n\n# Probar las impresoras\ntest_printer(b_and_w_printer)\ntest_printer(color_printer)\ntest_printer(multi_printer)\ntest_scanner(multi_printer)\ntest_fax(multi_printer)\n\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/hozlucas28.py",
    "content": "# pylint: disable=missing-class-docstring,pointless-string-statement,missing-function-docstring,broad-exception-raised,too-few-public-methods,missing-module-docstring\n\nfrom abc import ABCMeta, abstractmethod\n\n\"\"\"\n    Interface Segregation Principle (ISP)...\n\"\"\"\n\nprint(\"Interface Segregation Principle (ISP)...\")\n\n\nclass AbcBadWorker(metaclass=ABCMeta):\n    @abstractmethod\n    def eat(self) -> None:\n        pass\n\n    @abstractmethod\n    def work(self) -> None:\n        pass\n\n\nclass BadProgrammer(AbcBadWorker):\n    def eat(self) -> None:\n        print(\"Eating!\")\n\n    def work(self) -> None:\n        print(\"Working!\")\n\n\nclass BadRobot(AbcBadWorker):\n    def eat(self) -> None:\n        raise Exception(\"A robot can not eat\")\n\n    def work(self) -> None:\n        print(\"Working!\")\n\n\nprint(\"\\nBad implementation of Interface Segregation Principle (ISP)...\")\n\nprint(\n    \"\\n```\",\n    \"\"\"class AbcBadWorker(metaclass=ABCMeta):\n  @abstractmethod\n  def eat(self) -> None:\n    pass\n\n  @abstractmethod\n  def work(self) -> None:\n    pass\n\n\nclass BadProgrammer(AbcBadWorker):\n  def eat(self) -> None:\n    print(\"Eating!\")\n\n  def work(self) -> None:\n    print(\"Working!\")\n\n\nclass BadRobot(AbcBadWorker):\n  def eat(self) -> None:\n    raise Exception(\"A robot can not eat\")\n\n  def work(self) -> None:\n    print(\"Working!\")\"\"\",\n    \"```\",\n    sep=\"\\n\",\n)\n\nprint(\n    \"\\nThis is a bad implementation of Interface Segregation Principle (ISP),\",\n    \"because the 'BadRobot' class should not implement an interface with methods\",\n    \"that it is going to never use. So, the implemented interface ('AbcBadWorker')\",\n    \"is to general for the 'BadRobot' class, but perfect for the 'BadProgrammer' class.\",\n    sep=\"\\n\",\n)\n\nprint(\"\\nGood implementation of Interface Segregation Principle (ISP)...\")\n\n\nclass AbcHumanWorker(metaclass=ABCMeta):\n    @abstractmethod\n    def eat(self) -> None:\n        pass\n\n    @abstractmethod\n    def work(self) -> None:\n        pass\n\n\nclass AbcNotHumanWorker(metaclass=ABCMeta):\n    @abstractmethod\n    def work(self) -> None:\n        pass\n\n\nclass GoodProgrammer(AbcHumanWorker):\n    def eat(self) -> None:\n        print(\"Eating!\")\n\n    def work(self) -> None:\n        print(\"Working!\")\n\n\nclass GoodRobot(AbcNotHumanWorker):\n    def work(self) -> None:\n        print(\"Working!\")\n\n\nprint(\n    \"\\n```\",\n    \"\"\"class AbcHumanWorker(metaclass=ABCMeta):\n  @abstractmethod\n  def eat(self) -> None:\n    pass\n\n  @abstractmethod\n  def work(self) -> None:\n    pass\n\n\nclass AbcNotHumanWorker(metaclass=ABCMeta):\n  @abstractmethod\n  def work(self) -> None:\n    pass\n\n\nclass GoodProgrammer(AbcHumanWorker):\n  def eat(self) -> None:\n    print(\"Eating!\")\n\n  def work(self) -> None:\n    print(\"Working!\")\n\n\nclass GoodRobot(AbcNotHumanWorker):\n  def work(self) -> None:\n    print(\"Working!\")\"\"\",\n    \"```\",\n    sep=\"\\n\",\n)\n\nprint(\n    \"\\nThis is a good implementation of Interface Segregation Principle (ISP),\",\n    \"because the 'GoodRobot' class only implements the necessary methods, without\",\n    \"any extras. Also, the 'GoodProgrammer' class utilizes an interface perfectly\",\n    \"suited to its needs, with no extra methods.\",\n    sep=\"\\n\",\n)\n\nprint(\n    \"\\n# ---------------------------------------------------------------------------------- #\\n\"\n)\n\n\"\"\"\n    Additional challenge...\n\"\"\"\n\nprint(\"Additional challenge...\")\n\n\nclass AbcBlackAndWhitePrinter(metaclass=ABCMeta):\n    @abstractmethod\n    def print_(self) -> None:\n        pass\n\n\nclass BlackAndWhitePrinter(AbcBlackAndWhitePrinter):\n    def print_(self) -> None:\n        print(\"Paper printed in black and white!\")\n\n\nclass AbcColorPrinter(metaclass=ABCMeta):\n    @abstractmethod\n    def print_(self) -> None:\n        pass\n\n\nclass ColorPrinter(AbcColorPrinter):\n    def print_(self) -> None:\n        print(\"Paper printed in color!\")\n\n\nclass AbcMultifunctionalPrinter(metaclass=ABCMeta):\n    @abstractmethod\n    def print_(self) -> None:\n        pass\n\n    @abstractmethod\n    def scan(self) -> None:\n        pass\n\n    @abstractmethod\n    def send_fax(self) -> None:\n        pass\n\n\nclass MultifunctionalPrinter(AbcMultifunctionalPrinter):\n    def print_(self) -> None:\n        print(\"Paper printed!\")\n\n    def scan(self) -> None:\n        print(\"Scan completed!\")\n\n    def send_fax(self) -> None:\n        print(\"Fax sent!\")\n\n\nblack_and_white_printer: BlackAndWhitePrinter = BlackAndWhitePrinter()\ncolor_printer: ColorPrinter = ColorPrinter()\nmultifunctional_printer: MultifunctionalPrinter = MultifunctionalPrinter()\n\nprint()\nblack_and_white_printer.print_()\n\nprint()\ncolor_printer.print_()\n\nprint()\nmultifunctional_printer.print_()\n\nprint()\nmultifunctional_printer.scan()\n\nprint()\nmultifunctional_printer.send_fax()\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/idiegorojas.py",
    "content": "\"\"\"\n#29 - Principio SOLID: Segregacion de interfaces en Python \n\"\"\"\n# \"Los clientes no deberian versen forzados a depender de interfaces que no utilizan.\"\n# Es mejor tener varias interfaces especificas y pequeñas\n# Esto evita que las clases dependan de metodos que no necesitan.\n\n\"\"\"\nBeneficios de aplicar el ISP\n\"\"\"\n# Código más mantenible: Las interfaces pequeñas y específicas son más fáciles de mantener y modificar.\n# Mayor cohesión: Cada interfaz tiene una responsabilidad clara y concreta.\n# Menor acoplamiento: Las clases solo dependen de las interfaces que realmente necesitan.\n# Mayor flexibilidad: Es más fácil combinar interfaces pequeñas para crear comportamientos complejos.\n# Testing más sencillo: Las interfaces pequeñas facilitan la creación de mocks y stubs para pruebas.\n\n\n\n\"\"\"\nViolacion del principio.\n\"\"\"\n# Creamos un programa para para dos impresoras, una nueva y una vieja\n# El problema aquí es que ImpresoraVieja está obligada a implementar métodos que no puede realizar.\n\n\nfrom abc import ABC, abstractmethod\n\nclass ImpresionDispositivo(ABC):\n    @abstractmethod\n    def imprimir(self, documento):\n        pass\n    \n    @abstractmethod\n    def escanear(self, documento):\n        pass\n    \n    @abstractmethod\n    def enviar_fax(self, documento):\n        pass\n    \n    @abstractmethod\n    def grapar(self, documento):\n        pass\n\n\nclass ImpresoraModerna(ImpresionDispositivo):\n    def imprimir(self, documento):\n        print(f\"Imprimiendo: {documento}\")\n    \n    def escanear(self, documento):\n        print(f\"Escaneando: {documento}\")\n    \n    def enviar_fax(self, documento):\n        print(f\"Enviando fax: {documento}\")\n    \n    def grapar(self, documento):\n        print(f\"Grapando: {documento}\")\n\n\nclass ImpresoraVieja(ImpresionDispositivo):\n    def imprimir(self, documento):\n        print(f\"Imprimiendo: {documento}\")\n    \n    def escanear(self, documento):\n        # Esta impresora no puede escanear\n        raise NotImplementedError(\"Esta impresora no puede escanear\")\n    \n    def enviar_fax(self, documento):\n        # Esta impresora no puede enviar fax\n        raise NotImplementedError(\"Esta impresora no puede enviar fax\")\n    \n    def grapar(self, documento):\n        # Esta impresora no puede grapar\n        raise NotImplementedError(\"Esta impresora no puede grapar\")\n    \n\n\n\"\"\"\nAplicar correctamente el principio y Ejercicio Extra\n\"\"\"\nfrom abc import ABC, abstractmethod\n\nclass Impresora(ABC):\n    @abstractmethod\n    def imprimir(self, documento):\n        pass\n\n\nclass Escaner(ABC):\n    @abstractmethod\n    def escanear(self, documento):\n        pass\n\n\nclass FaxDevice(ABC):\n    @abstractmethod\n    def enviar_fax(self, documento):\n        pass\n\n\nclass Grapadora(ABC):\n    @abstractmethod\n    def grapar(self, documento):\n        pass\n\n\nclass ImpresoraModerna(Impresora, Escaner, FaxDevice, Grapadora):\n    def imprimir(self, documento):\n        print(f\"Imprimiendo: {documento}\")\n    \n    def escanear(self, documento):\n        print(f\"Escaneando: {documento}\")\n    \n    def enviar_fax(self, documento):\n        print(f\"Enviando fax: {documento}\")\n    \n    def grapar(self, documento):\n        print(f\"Grapando: {documento}\")\n\n\nclass ImpresoraVieja(Impresora):\n    def imprimir(self, documento):\n        print(f\"Imprimiendo: {documento}\")\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/ignaciovihe.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el \"Principio SOLID de Segregación de Interfaces (Interface Segregation Principle, ISP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento de forma correcta e incorrecta.\n\"\"\"\n\nfrom abc import ABC, abstractmethod\n#ISP incorrecto\n\nclass Animal: # La superclase obliga a implementar todos los metodos, aunque alguno no tiene sentido para la subclase perro.\n    def fly(self):\n        pass\n\n    def run(self):\n        pass\n\n    def swim(self):\n        pass\n\n\nclass Dog(Animal):\n    def fly(self):\n        raise Exception(\"Los perros no vuelan.\")\n\n    def run(self):\n        print(\"El perro corre\")\n\n    def swimm(self):\n        print(\"El perro nada\")\n\n\"\"\"my_dog = Dog()\nmy_dog.run()\nmy_dog.swimm()\nmy_dog.fly()\"\"\" #Da error\n\n# ISP correcto\nclass RunInterface(ABC):\n    @abstractmethod\n    def run(self):\n        pass\n\nclass FLyInterface(ABC):\n    @abstractmethod\n    def fly(self):\n        pass\n\nclass SwimInterface(ABC):\n    @abstractmethod\n    def swim(self):\n        pass\n\nclass Dog(RunInterface,SwimInterface):\n    def run(self):\n        print(\"El perro corre\")\n\n    def swim(self):\n        print(\"El perro nada\")\n\nclass Bird(FLyInterface):\n    def fly(self):\n        print(\"El pajaro vuela\")\n\nmy_dog = Dog()\nmy_dog.run()\n\nmy_bird = Bird()\nmy_bird.fly()\n\n\"\"\"\n\n * DIFICULTAD EXTRA (opcional):\n * Crea un gestor de impresoras.\n * Requisitos:\n * 1. Algunas impresoras sólo imprimen en blanco y negro.\n * 2. Otras sólo a color.\n * 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n * Instrucciones:\n * 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n * 2. Aplica el ISP a la implementación.\n * 3. Desarrolla un código que compruebe que se cumple el principio.\"\"\"\n\nclass MonochromePrinterInterface(ABC):\n    @abstractmethod\n    def print_monochrome(self, document: str):\n        pass\n\n\nclass ColorPrinterInterface(ABC):\n    @abstractmethod\n    def print_color(self, document: str):\n        pass\n\n\nclass ScannInterface(ABC):\n    @abstractmethod\n    def scan(self, document) -> str:\n        pass\n\n\nclass FaxInterface(ABC):\n    @abstractmethod\n    def fax(self, document: str):\n        pass\n\n\nclass MonochromePrinter(MonochromePrinterInterface):\n    def print_monochrome(self, document):\n        print(f\"Imprimiendo {document} en blanco y negro\")\n\n\nclass ColorPrinter(ColorPrinterInterface):\n    def print_color(self, document):\n        print(f\"Imprimiendo {document} en color\")\n\n\nclass MultifunctionPrinter(MonochromePrinterInterface, ColorPrinterInterface, ScannInterface, FaxInterface):\n    def fax(self, document):\n        print(f\"Enviando {document} por fax\")\n\n    def scan(self, document):\n        print(f\"Escaneando documento {document}\")\n        return f\"Documento {document} escaneado\"\n\n    def print_color(self, document):\n        print(f\"Imprimiendo {document} en color\")\n\n    def print_monochrome(self, document):\n        print(f\"Imprimiendo {document} en blanco y negro\")\n\n\nmonochrome_printer = MonochromePrinter()\ncolor_printer = ColorPrinter()\nmultifunction = MultifunctionPrinter()\n\nmonochrome_printer.print_monochrome(\"doc1.pdf\")\ncolor_printer.print_color(\"doc1.pdf\")\nmultifunction.fax(\"doc1.pdf\")\nmultifunction.print_monochrome(\"doc1.pdf\")\nmultifunction.print_color(\"doc1.pdf\")\nmultifunction.scan(\"doc1.pdf\")"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/javi-kl.py",
    "content": "from abc import ABC, abstractmethod\n\n\n# Incorrecta\nclass Trabajador(ABC):\n    @abstractmethod\n    def trabajar(self):\n        pass\n\n    @abstractmethod\n    def dormir(self):\n        pass\n\n    @abstractmethod\n    def comer(self):\n        pass\n\n\nclass Humano(Trabajador):\n    def trabajar(self):\n        print(\"Trabajando...\")\n\n    def dormir(self):\n        print(\"Durmiendo..\")\n\n    def comer(self):\n        print(\"Comiendo\")\n\n\n# Aqui estamos violando el ISP, porque no debemos obligar a esta clase a usar metodos que no son acorde\nclass Robot(Trabajador):\n    def trabajar(self):\n        print(\"Trabajando...\")\n\n    def dormir(self):\n        print(\"Durmiendo..\")\n\n    def comer(self):\n        print(\"Comiendo\")\n\n\ntrabajador1 = Humano()\ntrabajador1.comer()\ntrabajador1.dormir()\ntrabajador1.comer()\n\n\n# correcto\nclass TrabajadorHumano(ABC):\n    @abstractmethod\n    def trabajar(self):\n        pass\n\n    @abstractmethod\n    def dormir(self):\n        pass\n\n    @abstractmethod\n    def comer(self):\n        pass\n\n\nclass TrabajadorMecanico(ABC):\n    @abstractmethod\n    def trabajar(self):\n        pass\n\n    @abstractmethod\n    def cargarse(self):\n        pass\n\n\nclass Peon(TrabajadorHumano):\n    def trabajar(self):\n        print(\"Humano Trabajando...\")\n\n    def dormir(self):\n        print(\"Humano Durmiendo..\")\n\n    def comer(self):\n        print(\"Humano Comiendo\")\n\n\nclass Robot(TrabajadorMecanico):\n    def trabajar(self):\n        print(\"Robot Trabajando...\")\n\n    def cargarse(self):\n        print(\"Robot Cargandose...\")\n\n\ntrabajador_humano1 = Peon()\ntrabajador_mecanico1 = Robot()\n\ntrabajador_humano1.comer()\ntrabajador_humano1.dormir()\ntrabajador_humano1.trabajar()\n\ntrabajador_mecanico1.trabajar()\ntrabajador_mecanico1.cargarse()\n\n\n\"\"\"\nextra\n\"\"\"\n\n\n# Interfaces pequeñas que abarquen todas las posibles funciones y que podemos expandir\nclass Imprimible(ABC):\n    \"\"\"Interfaz para capacidad de imprimir en blanco y negro\"\"\"\n\n    @abstractmethod\n    def imprimir(self):\n        pass\n\n\nclass ImprimibleColor(ABC):\n    \"\"\"Interfaz para capacidad de imprimir a color\"\"\"\n\n    @abstractmethod\n    def imprimir_color(self):\n        pass\n\n\nclass Escaneable(ABC):\n    \"\"\"Interfaz para capacidad de escanear documentos\"\"\"\n\n    @abstractmethod\n    def escanear(self):\n        pass\n\n\nclass EnviadorFax(ABC):\n    \"\"\"Interfaz para capacidad de enviar fax\"\"\"\n\n    @abstractmethod\n    def enviar_fax(self):\n        pass\n\n\n# Tipos posibles de impresoras, heredan de la interfaz segun el tipo de impresion\nclass Impresora(Imprimible):\n    def imprimir(self):\n        print(\"Imprimiendo en blanco y negro\")\n\n\n# Esta impresora puede utilizar los dos tipos de impresion\nclass ImpresoraColor(Imprimible, ImprimibleColor):\n    def imprimir(self):\n        print(\"Imprimiendo en blanco y negro\")\n\n    def imprimir_color(self):\n        print(\"Imprimiendo en color\")\n\n\n# Estas herendan de la interfaz segun el tipo de impresion y de metodos\nclass ImpresoraMulti(Imprimible, Escaneable, EnviadorFax):\n    def imprimir(self):\n        print(\"Imprimiendo en blanco y negro\")\n\n    def escanear(self):\n        print(\"Escaneando documento\")\n\n    def enviar_fax(self):\n        print(\"Enviando fax\")\n\n\nclass ImpresoraColorMulti(Imprimible, ImprimibleColor, Escaneable, EnviadorFax):\n    def imprimir(self):\n        print(\"Imprimiendo en blanco y negro\")\n\n    def imprimir_color(self):\n        print(\"Imprimiendo en color\")\n\n    def escanear(self):\n        print(\"Escaneando documento\")\n\n    def enviar_fax(self):\n        print(\"Enviando fax\")\n\n\nimpresora1 = Impresora()\nimpresora_color1 = ImpresoraColor()\nimpresora_multi1 = ImpresoraMulti()\nimpresora_color_multi1 = ImpresoraColorMulti()\n\n\nimpresora1.imprimir()\n\nimpresora_color1.imprimir_color()\n\nimpresora_multi1.imprimir()\nimpresora_multi1.escanear()\nimpresora_multi1.enviar_fax()\n\nimpresora_color_multi1.imprimir_color()\nimpresora_color_multi1.escanear()\nimpresora_color_multi1.enviar_fax()\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/juanmax2.py",
    "content": "\"\"\"\nEjercicio\n\"\"\"\n\nfrom abc import ABC, abstractmethod\n\n# Sin ISP\n\nclass InterfazTrabajador(ABC):\n    \n    @abstractmethod\n    def work(self):\n        pass\n    \n    @abstractmethod\n    def comer(self):\n        pass\n    \nclass Humano(InterfazTrabajador):\n    \n    def work(self):\n        print(\"Trabajando\")\n    \n    def comer(self):\n        print(\"Comiendo\")\n\nclass Robot(InterfazTrabajador):\n    \n    def work(self):\n        print(\"Trabajando\")\n        \n    def comer(self):\n        # Los robots no comen\n        raise ValueError(\"Los robots no comen\")\n\n# Con ISP\n\nclass WorkInterface(ABC):\n    \n    @abstractmethod\n    def work(self):\n        pass\n    \nclass EatInterface(ABC):\n    \n    @abstractmethod\n    def comer(self):\n        pass\n    \nclass Humano(WorkInterface, EatInterface):\n    \n    def work(self):\n        print(\"Trabajando\")\n    \n    def comer(self):\n        print(\"Comiendo\")\n\nclass Robot(WorkInterface):\n    \n    def work(self):\n        print(\"Trabajando\")\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un gestor de impresoras.\n * Requisitos:\n * 1. Algunas impresoras sólo imprimen en blanco y negro.\n * 2. Otras sólo a color.\n * 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n * Instrucciones:\n * 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n * 2. Aplica el ISP a la implementación.\n * 3. Desarrolla un código que compruebe que se cumple el principio.\n\"\"\"\n\nclass BlackAndWhite(ABC):\n    \n    @abstractmethod\n    def imprimir_blanco_negro(self,  document : str):\n        pass\n    \nclass Color(ABC):\n    \n    @abstractmethod\n    def imprimir_color(self,  document : str):\n        pass\n\nclass Scanner(ABC):\n    \n    @abstractmethod\n    def scanear(self,  document : str):\n        pass\n    \nclass EnviarFax(ABC):\n    \n    @abstractmethod\n    def enviar_fax(self,  document : str):\n        pass\n\nclass Printer(BlackAndWhite):\n    \n    def imprimir_blanco_negro(self, document):\n        print(f\"Imprimiendo en blanco y negro el documento {document}\")\n\nclass ColorPrinter(Color):\n    \n    def imprimir_color(self, document):\n        print(f\"Imprimiendo en color el documento {document}\")\n\nclass MultifuncionPrinter(BlackAndWhite, Color, Scanner, EnviarFax):\n    \n    def imprimir_blanco_negro(self, document):\n        print(f\"Imprimiendo en blanco y negro el documento {document}\")\n\n    def imprimir_color(self, document):\n        print(f\"Imprimiendo en color el documento {document}\")\n        \n    def scanear(self, document):\n        print(f\"Scaneando el documento {document}\")\n    \n    def enviar_fax(self, document):\n        print(f\"Enviando el documento {document} via fax\")\n\n# Caso de uso\n\ndef test_printers():\n    printer_1 = Printer()\n    printer_2 = ColorPrinter()\n    printer_3 = MultifuncionPrinter()   \n    \n    printer_1.imprimir_blanco_negro(\"documento 1\")\n    print(\"-------------------------------\")\n    printer_2.imprimir_color(\"documento 2\")\n    print(\"-------------------------------\")\n    printer_3.imprimir_blanco_negro(\"documento 3\")\n    printer_3.imprimir_color(\"documento 3\")\n    printer_3.scanear(\"documento 3\")\n    printer_3.enviar_fax(\"documento 3\")\n    \ntest_printers()\n\n\n\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/juanppdev.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el \"Principio SOLID de Segregación de Interfaces (Interface Segregation Principle, ISP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento de forma correcta e incorrecta.\n\"\"\"\n\n# Correcto\n\nfrom abc import ABC, abstractmethod\n\nclass Workable(ABC):\n    @abstractmethod\n    def work(self):\n        pass\n\nclass Eatable(ABC):\n    @abstractmethod\n    def eat(self):\n        pass\n\nclass HumanWorker(Workable, Eatable):\n    def work(self):\n        print(\"Human working\")\n\n    def eat(self):\n        print(\"Human eating\")\n\nclass RobotWorker(Workable):\n    def work(self):\n        print(\"Robot working\")\n\n\n# Incorrecto\n\nfrom abc import ABC, abstractmethod\n\nclass Worker(ABC):\n    @abstractmethod\n    def work(self):\n        pass\n\n    @abstractmethod\n    def eat(self):\n        pass\n\nclass HumanWorker(Worker):\n    def work(self):\n        print(\"Human working\")\n\n    def eat(self):\n        print(\"Human eating\")\n\nclass RobotWorker(Worker):\n    def work(self):\n        print(\"Robot working\")\n\n    def eat(self):\n        raise NotImplementedError(\"Robots don't eat\")\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un gestor de impresoras.\n * Requisitos:\n * 1. Algunas impresoras sólo imprimen en blanco y negro.\n * 2. Otras sólo a color.\n * 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n * Instrucciones:\n * 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n * 2. Aplica el ISP a la implementación.\n * 3. Desarrolla un código que compruebe que se cumple el principio.\n\"\"\"\n\nfrom abc import ABC, abstractmethod\n\nclass Printer(ABC):\n    @abstractmethod\n    def print(self):\n        pass\n\nclass Scanner(ABC):\n    @abstractmethod\n    def scan(self):\n        pass\n\nclass Fax(ABC):\n    @abstractmethod\n    def send_fax(self):\n        pass\n\nclass BlackAndWhitePrinter(Printer):\n    def print(self):\n        print(\"Printing in black and white\")\n\nclass ColorPrinter(Printer):\n    def print(self):\n        print(\"Printing in color\")\n\nclass MultiFunctionPrinter(Printer, Scanner, Fax):\n    def print(self):\n        print(\"Printing in color\")\n\n    def scan(self):\n        print(\"Scanning document\")\n\n    def send_fax(self):\n        print(\"Sending fax\")\n\n\nclass PrinterManager:\n    def __init__(self, printer: Printer):\n        self.printer = printer\n\n    def print_document(self):\n        self.printer.print()\n\nclass MultiFunctionPrinterManager:\n    def __init__(self, printer: MultiFunctionPrinter):\n        self.printer = printer\n\n    def print_document(self):\n        self.printer.print()\n\n    def scan_document(self):\n        self.printer.scan()\n\n    def send_fax(self):\n        self.printer.send_fax()\n\n\n# Usando una impresora en blanco y negro\nbw_printer = BlackAndWhitePrinter()\nprinter_manager = PrinterManager(bw_printer)\nprinter_manager.print_document()\n\n# Usando una impresora a color\ncolor_printer = ColorPrinter()\nprinter_manager = PrinterManager(color_printer)\nprinter_manager.print_document()\n\n# Usando una impresora multifunción\nmulti_printer = MultiFunctionPrinter()\nmulti_printer_manager = MultiFunctionPrinterManager(multi_printer)\nmulti_printer_manager.print_document()\nmulti_printer_manager.scan_document()\nmulti_printer_manager.send_fax()\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/kenysdev.py",
    "content": "# ╔═════════════════════════════════════╗\n# ║ Autor:  Kenys Alvarado              ║\n# ║ GitHub: https://github.com/Kenysdev ║\n# ║ 2024 -  Python                      ║\n# ╚═════════════════════════════════════╝\n\n# -----------------------------------------------------\n# * SOLID: PRINCIPIO DE SEGREGACIÓN DE INTERFACES (ISP)\n# -----------------------------------------------------\n# - Una clase no debería estar obligada a implementar interfaces que no utiliza.\n#   Evitando crear grandes clases monolíticas.\n\nfrom abc import ABC, abstractmethod\nfrom decimal import Decimal\n\n# NOTA: Este ejemplo muestra el uso CORRECTO. Para suponer un ejemplo que viole el principio, sería \n#       Imaginar todos los métodos siguientes, en una sola abstracción, entonces algunos dispositivos\n#       implementarían abstracciones que no necesitan.\n\n#______________________\n# Abstracciones\n\nclass AbsPlayable(ABC):\n    @abstractmethod\n    def play(self):\n        pass\n\nclass AbsDisplayable(ABC):\n    @abstractmethod\n    def display(self):\n        pass\n\n#______________________\n# Implementar abstracciones\n\nclass Speaker(AbsPlayable):\n    def play(self):\n        print(\"El altavoz está reproduciendo música.\")\n\nclass Phone(AbsPlayable, AbsDisplayable):\n    def play(self):\n        print(\"El teléfono está reproduciendo música.\")\n\n    def display(self):\n        print(\"El teléfono está mostrando la pantalla de reproducción.\")\n\n#______________________\n# Utilización\nprint(\"Ejercicio #1\")\n\nspeaker = Speaker()\nspeaker.play()\n\nphone = Phone()\nphone.play()\nphone.display()\n\n\"\"\"\n * EJERCICIO:\n * Crea un gestor de impresoras.\n * Requisitos:\n * 1. Algunas impresoras sólo imprimen en blanco y negro.\n * 2. Otras sólo a color.\n * 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n * Instrucciones:\n * 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n * 2. Aplica el ISP a la implementación.\n * 3. Desarrolla un código que compruebe que se cumple el principio.\n\"\"\"\n\n#______________________\n# Abstracciones\n\nclass AbsPrinter(ABC):    \n    @abstractmethod\n    def print_file(self, file: str) -> None:\n        pass\n\nclass AbsScanner(ABC):\n    @abstractmethod\n    def to_scan(self, path_save: str) -> None:\n        pass\n\nclass AbcFax(ABC):\n    @abstractmethod\n    def send_file(self, file: str,  phone_number: int) -> None:\n        pass\n\n#______________________\n# Implementar abstracciones\n\nclass MonoPrinter(AbsPrinter):\n    def print_file(self, file: str) -> None:\n        print(\"\\nImpresora blanco y negro:\")\n        print(file, \" se imprimió.\")\n\nclass ColorPrinter(AbsPrinter):\n    def print_file(self, file: str) -> None:\n        print(\"\\nImpresora a color:\")\n        print(file, \" se imprimió.\")\n\nclass Scanner(AbsScanner):\n    def to_scan(self, path_save: str) -> None:\n        print(\"\\nEscaneo realizado, Guardado en:\", path_save)\n\nclass Fax(AbcFax):\n    def send_file(self, file: str,  phone_number: int) -> None:\n        print(\"\\n-\", file, \"Fue enviado a:\", phone_number)\n\n\nclass MultiFunctionPrinter:\n    def __init__(self):\n        self.mono_printer: AbsPrinter = MonoPrinter()\n        self.color_printer: AbsPrinter = ColorPrinter()\n        self.scanner: AbsScanner = Scanner()\n        self.fax: AbcFax = Fax()\n\n#______________________\n# Utilización\nprint(\"\\nEjercicio #2\")\n\n#___________\n# blanco y negro.\nmono_printer = MonoPrinter()\nmono_printer.print_file(\"filex.pdf\")\n\n#___________\ncolor_printer = ColorPrinter()\ncolor_printer.print_file(\"filex.pdf\")\n\n#___________\nscaner = Scanner()\nscaner.to_scan(\"c:\\\\docs\")\n\n#___________\nfax = Fax()\nfax.send_file(\"filex.pdf\", 12345678)\n\n#___________\nprint(\"\\n___________\\nMultifunción:\")\nmultifunction = MultiFunctionPrinter()\n\nmultifunction.mono_printer.print_file(\"filex.pdf\")\nmultifunction.color_printer.print_file(\"filex.pdf\")\nmultifunction.scanner.to_scan(\"c:\\\\docs\")\nmultifunction.fax.send_file(\"filex.pdf\", 12345678)\n\n# end\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/mhayhem.py",
    "content": "# @Author Daniel Grande (Mhayhem)\n\nfrom abc import ABC, abstractmethod\n\n# EJERCICIO:\n# Explora el \"Principio SOLID de Segregación de Interfaces (Interface Segregation Principle, ISP)\" \n# y crea un ejemplo simple donde se muestre su funcionamiento de forma correcta e incorrecta.\n\nclass Worker:\n    def work(self):\n        pass\n    def eat(self):\n        pass\n    def sleep(self):\n        pass\n    def collect_salary(self):\n        pass\n\nclass Bot(Worker):\n    def work(self):\n        print(\"Robot trabajando.\")\n    def eat(self):\n        # los robots no comen\n        pass\n    def sleep(self):\n        # los robots no necesitan dormir\n        pass\n    def collect_salary(self):\n        # no cobra salario\n        pass\n\n# ISP\n\nclass Worker:\n    def work(self):\n        pass\n\nclass Feedable:\n    def eat(self):\n        pass\n\nclass Restable:\n    def sleep(self):\n        pass\n\nclass Payable:\n    def collect_salary(self):\n        pass\n\nclass Human(Worker, Feedable, Restable, Payable):\n    def work(self):\n        print(\"Humano trabajando.\")\n    def eat(self):\n        print(\"Humano comiendo.\")\n    def sleep(self):\n        print(\"Humano durmiendo.\")\n    def collect_salary(self):\n        print(\"Humano cobrando salario.\")\n\nclass Bot(Worker):\n    def work(self):\n        print(\"Robot trabajando.\")\n\n\n    # DIFICULTAD EXTRA (opcional):\n    # Crea un gestor de impresoras.\n    # Requisitos:\n    # 1. Algunas impresoras sólo imprimen en blanco y negro.\n    # 2. Otras sólo a color.\n    # 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n    # Instrucciones:\n    # 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n    # 2. Aplica el ISP a la implementación.\n    # 3. Desarrolla un código que compruebe que se cumple el principio.\n\nclass Printable(ABC):\n    @abstractmethod\n    def print_file(self):\n        pass\n\nclass Fax(ABC):\n    @abstractmethod\n    def recive_fax(self):\n        pass\n\n    @abstractmethod\n    def send_fax(self):\n        pass\n\nclass Scanner(ABC):\n    @abstractmethod\n    def scaning(self):\n        pass\n\nclass BlackAndWhitePrinter(Printable):\n    def print_file(self):\n        return \"Imprimiendo en blanco y negro.\"\n\nclass ColorPrinter(Printable):\n    def print_file(self):\n        return \"Imprimiendo a color.\"\n\nclass Multifunction(Printable, Fax, Scanner):\n    def print_file(self):\n        return \"Imprimiendo a color o en blanco y negro.\"\n    \n    def recive_fax(self):\n        return \"Reciviendo fax.\"\n    \n    def send_fax(self):\n        return \"Enviando fax.\"\n    \n    def scanning(self):\n        return \"Escaneando documento.\"\n\ndef test_printing(array: list):\n    for object in array:\n        object.printing_file()\n    \n    assert Exception\n\ndef test_multifunction_printer(printer: object):\n    printer.recive_fax()\n    printer.send_fax()\n    printer.scanning()\n    \n    assert Exception\n\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/mouredev.py",
    "content": "\"\"\"\nEjercicio\n\"\"\"\n\nfrom abc import ABC, abstractmethod\n\n# Sin ISP\n\n\nclass WorkerInterface(ABC):\n\n    @abstractmethod\n    def work(self):\n        pass\n\n    @abstractmethod\n    def eat(self):\n        pass\n\n\nclass Human(WorkerInterface):\n\n    def work(self):\n        print(\"Trabajando\")\n\n    def eat(self):\n        print(\"Comiendo\")\n\n\nclass Robot(WorkerInterface):\n\n    def work(self):\n        print(\"Trabajando\")\n\n    def eat(self):\n        # Los robots no comen\n        pass\n\n\nhuman = Human()\nhuman.work()\nhuman.eat()\n\nrobot = Robot()\nrobot.work()\nrobot.eat()  # error\n\n# Con ISP\n\n\nclass WorkInterface(ABC):\n\n    @abstractmethod\n    def work(self):\n        pass\n\n\nclass EatInterface(ABC):\n\n    @abstractmethod\n    def eat(self):\n        pass\n\n\nclass Human(WorkInterface, EatInterface):\n\n    def work(self):\n        print(\"Trabajando\")\n\n    def eat(self):\n        print(\"Comiendo\")\n\n\nclass Robot(WorkInterface):\n\n    def work(self):\n        print(\"Trabajando\")\n\n\nhuman = Human()\nhuman.work()\nhuman.eat()\n\nrobot = Robot()\nrobot.work()\n\n\"\"\"\nExtra\n\"\"\"\n\n\nclass PrinterInterface(ABC):\n\n    @abstractmethod\n    def print(self, document: str):\n        pass\n\n\nclass ColorPrinterInterface(ABC):\n\n    @abstractmethod\n    def print_color(self, document: str):\n        pass\n\n\nclass ScannerInterface(ABC):\n\n    @abstractmethod\n    def scan(self, document: str) -> str:\n        pass\n\n\nclass FaxInterface(ABC):\n\n    @abstractmethod\n    def send_fax(self, document: str):\n        pass\n\n\nclass Printer(PrinterInterface):\n    def print(self, document: str):\n        print(f\"Imprimiendo en blanco y negro el documento {document}.\")\n\n\nclass ColorPrinter(ColorPrinterInterface):\n    def print_color(self, document: str):\n        print(f\"Imprimiendo a color el documento {document}.\")\n\n\nclass MultifunctionPrinter(PrinterInterface, ColorPrinterInterface, ScannerInterface, FaxInterface):\n    def print(self, document: str):\n        print(f\"Imprimiendo en blanco y negro el documento {document}.\")\n\n    def print_color(self, document: str):\n        print(f\"Imprimiendo a color el documento {document}.\")\n\n    def scan(self, document: str) -> str:\n        print(f\"Escaneando el documento {document}.\")\n        return f\"Documento {document} escaneado.\"\n\n    def send_fax(self, document: str):\n        print(f\"Enviando por fax el documento {document}.\")\n\n\ndef test_printers():\n\n    printer = Printer()\n    color_printer = ColorPrinter()\n    multifunction_printer = MultifunctionPrinter()\n\n    printer.print(\"doc.pdf\")\n    color_printer.print_color(\"doc.pdf\")\n    multifunction_printer.print(\"doc.pdf\")\n    multifunction_printer.print_color(\"doc.pdf\")\n    multifunction_printer.scan(\"doc.pdf\")\n    multifunction_printer.send_fax(\"doc.pdf\")\n\n\ntest_printers()\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/mrodara.py",
    "content": "### Principio de Segregación de Interfaces (Interface Segregation Principle, ISP)\n\n'''\nEste principio establece que:\n\n\"Ningún cliente debería depender de métodos que no utiliza.\"\n\nEsto significa que las interfaces (o clases abstractas en Python) deben diseñarse de manera que los clientes que \nlas implementan no se vean forzados a definir métodos innecesarios o irrelevantes.\n\nVentajas:\n\n+ Reduce el acoplamiento\n+ Hace el código más modular\n+ Facilitan la implementación\n'''\n\n# Ejemplo que viola el principio\n\nfrom abc import ABC, abstractmethod\n\nclass Vehicle(ABC):\n    \n    @abstractmethod\n    def drive(self):\n        pass\n    \n    @abstractmethod\n    def pilot(self):\n        pass\n    \n    @abstractmethod\n    def navigate(self):\n        pass\n    \nclass Car(Vehicle):\n    \n    def drive():\n        print(\"El coche está en marcha\")\n    \n    def pilot(self):\n        raise NotImplementedError(\"Un coche no puede volar\")\n    \n    def navigate(self):\n        raise NotImplementedError(\"Un coche no puede navegar por el mar\")\n\n'''\nEn este ejemplo los principales problemas son:\n- El cliente (Car) debe implementar métodos que no utiliza (pilot y navigate)\n- El cliente debe manejar excepciones innecesarias\n'''\n\n# Fin Ejemplo que viola el principio\n\n# Rediseño para no violar el ISP\n\nclass Driveable(ABC):\n    \n    @abstractmethod\n    def drive(self):\n        pass\n\nclass Pilotable(ABC):\n    \n    @abstractmethod\n    def pilot(self):\n        pass\n\nclass Navigateable(ABC):\n    \n    @abstractmethod\n    def navigate(self):\n        pass\n\n\nclass Car(Driveable):\n    \n    def drive(self):\n        print(\"El cocche está en marcha\")\n\nclass Plane(Pilotable):\n    \n    def pilot(self):\n        print(\"El avión está volando\")\n\nclass Ship(Navigateable):\n    \n    def navigate(self):\n        print(\"El barco se encuentra navegando en alta mar\")\n    \n\n# Fin Rediseño para no violar el ISP\n\n## EJERCICIO EXTRA\n\nclass PrinterBW(ABC):\n    \n    @abstractmethod\n    def print_bn(self):\n        pass\n\nclass PrinterColor(ABC):\n    \n    @abstractmethod\n    def print_color(self):\n        pass\n\nclass Maileable(ABC):\n    \n    @abstractmethod\n    def send_mail(self):\n        pass\n\nclass Faxeable(ABC):\n    \n    @abstractmethod\n    def send_fax(self):\n        pass\n\nclass BwPrinter(PrinterBW):\n    \n    def print_bn(self):\n        print(\"Imprimiendo documento en Blanco/Negro\")\n\nclass ColorPrinter(PrinterColor):\n    \n    def print_color(self):\n        print(\"Imprimiendo documento en Color\")\n\nclass MultiFunction(PrinterBW, PrinterColor, Maileable, Faxeable):\n    \n    def print_bn(self):\n        print(\"Imprimiendo documento en Blanco/Negro\")\n    \n    def print_color(self):\n        print(\"Imprimiendo documento en Color\")\n    \n    def send_mail(self, to=\"correo@correo.es\", subject=\"Test\", body=\"This is a mail test\"):\n        print(f\"Enviando correo electrónico a {to} con asunto {subject} y mensaje {body}\")\n    \n    def send_fax(self, destination_number=\"+345557890\", content=\"This is a fax test\"):\n        print(f\"Enviando fax a {destination_number} con contenido {content}\")\n        \n\n# Batería de pruebas\n\ndef test_bw_printer():\n    printer = BwPrinter()\n    printer.print_bn()  # Debería imprimir en blanco y negro\n\ndef test_color_printer():\n    printer = ColorPrinter()\n    printer.print_color()  # Debería imprimir en color\n\ndef test_multi_function_print_bn():\n    printer = MultiFunction()\n    printer.print_bn()  # Debería imprimir en blanco y negro\n\ndef test_multi_function_print_color():\n    printer = MultiFunction()\n    printer.print_color()  # Debería imprimir en color\n\ndef test_multi_function_send_mail():\n    printer = MultiFunction()\n    printer.send_mail(to=\"example@mail.com\", subject=\"Prueba\", body=\"Esto es una prueba\")\n\ndef test_multi_function_send_fax():\n    printer = MultiFunction()\n    printer.send_fax(destination_number=\"+123456789\", content=\"Esto es una prueba de fax\")\n\ndef test_no_extra_methods_bw_printer():\n    printer = BwPrinter()\n    try:\n        printer.print_color()\n    except AttributeError:\n        print(\"Error esperado: 'BwPrinter' no tiene método 'print_color'\")\n\ndef test_no_extra_methods_color_printer():\n    printer = ColorPrinter()\n    try:\n        printer.print_bn()\n    except AttributeError:\n        print(\"Error esperado: 'ColorPrinter' no tiene método 'print_bn'\")\n        \n\nprint(\"Pruebas de BwPrinter:\")\ntest_bw_printer()\ntest_no_extra_methods_bw_printer()\n\nprint(\"\\nPruebas de ColorPrinter:\")\ntest_color_printer()\ntest_no_extra_methods_color_printer()\n\nprint(\"\\nPruebas de MultiFunction:\")\ntest_multi_function_print_bn()\ntest_multi_function_print_color()\ntest_multi_function_send_mail()\ntest_multi_function_send_fax()\n\n\n## FIN EJERCICIO EXTRA\n\n\n\n\n\n### FIN Principio de Segregación de Interfaces (Interface Segregation Principle, ISP)"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/neslarra.py",
    "content": "\"\"\"\n  EJERCICIO:\n Explora el \"Principio SOLID de Segregación de Interfaces (Interface Segregation Principle, ISP)\"\n y crea un ejemplo simple donde se muestre su funcionamiento de forma correcta e incorrecta.\n\n  DIFICULTAD EXTRA (opcional):\n Crea un gestor de impresoras.\n Requisitos:\n 1. Algunas impresoras sólo imprimen en blanco y negro.\n 2. Otras sólo a color.\n 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n Instrucciones:\n 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n 2. Aplica el ISP a la implementación.\n 3. Desarrolla un código que compruebe que se cumple el principio.\n\"\"\"\nfrom abc import ABC, abstractmethod\n\n\nprint(f\"{'#' * 47}\")\nprint(f\"##  Explicación  {'#' * 30}\")\nprint(f\"{'#' * 47}\")\n\nprint(r\"\"\"\nPara entender fácilmente los 5 ppios SOLID recomiendo leer:\n\n    https://blog.damavis.com/los-principios-solid-ilustrados-en-ejemplos-sencillos-de-python/\n\nen donde se explican de manera ordenada uno por uno, de manera sencilla y ejemplificada de manera progresiva (de hecho, de ahí\nvoy a tomar el ejemplo).\n\nEl cuarto ppio SOLID es el ppio de segregación de interfaz (Interface Segregation Principle) y establece que las clases \"hijas\" \nno deberían estar obligadas a implementar métodos que no han de usar.\n\nEn el ejemplo anterior vemos que la clase abstracta \"Bird\" tiene métodos \"fly\" y \"swim\", pero como el \"Cuervo\" no nada, no debería\nsu clase estar obligada a implementar dicho método (como así también una clase \"Pingüino\" no debiera implementar \"fly\".\n\nPara evitar este problema, separamos en distintas interfaces la implementación de aquellos métodos de la clase Bird que no son \nrealemente comunes a cualquier clase de pájaros.\n\n    from abc import ABC, abstractmethod\n    from typing import final\n    \n    class Bird(ABC):\n    \n        def __init__(self, name):\n            self.name = name\n    \n        @abstractmethod\n        def do_sound(self) -> str:\n            pass\n    \n    class FlyingBird(Bird):\n    \n        @abstractmethod\n        def fly(self):\n            pass\n    \n    class SwimmingBird(Bird):\n    \n        @abstractmethod\n        def swim(self):\n            pass\n    \n    class Crow(FlyingBird):\n       \n        def fly(self):\n            print(f\"{self.name} is flying high and fast!\")\n    \n        def do_sound(self) -> str:\n            return \"Caw\"\n    \n    class Duck(SwimmingBird, FlyingBird):\n       \n        def fly(self):\n            print(f\"{self.name} is flying not very high\")\n    \n        def swim(self):\n            print(f\"{self.name} swims in the lake and quacks\")\n    \n        def do_sound(self) -> str:\n            return \"Quack\"\n\n    lucas = Duck(\"Lucas\")\n    lucas.fly()\n    lucas.swim()\n    \n    dandy = Crow(\"Dandy\")\n    dandy.fly()\n    \n    Lucas is flying not very high\n    Lucas swims in the lake and quacks\n\n    Dandy is flying high and fast!\n\"\"\")\n\nprint(f\"{'#' * 52}\")\nprint(f\"##  Dificultad Extra  {'#' * 30}\")\nprint(f\"{'#' * 52}\\n\")\n\n\nclass Spooler(ABC):\n\n    @abstractmethod\n    def enqueue(self, docname: str):\n        pass\n\n    @abstractmethod\n    def dequeue(self):\n        pass\n\n\nclass Printer(Spooler):\n\n    def __init__(self):\n        self.queue = []\n\n    def enqueue(self, docname: str):\n        self.queue.append(docname)\n        print(f\"Document {docname} enqueued.\")\n\n    def dequeue(self):\n        return self.queue.pop(0)\n\n    @abstractmethod\n    def cartridge_level(self):\n        pass\n\n    @abstractmethod\n    def add_cartridge(self, color: str):\n        pass\n\n\nclass Fax(Spooler):\n    @abstractmethod\n    def send_document(self, target_number: str):\n        pass\n\n    @abstractmethod\n    def receive_document(self, docname: str, from_number: str):\n        pass\n\n\nclass Scanner(Spooler):\n    @abstractmethod\n    def save_document(self):\n        pass\n\n\nclass PrinterBN(Printer):\n\n    def __init__(self):\n        super().__init__()\n        self.black_cartridge_level = 100\n\n    def cartridge_level(self):\n        return self.black_cartridge_level\n\n    def print_document(self):\n        if self.queue.__len__() > 0:\n            if self.black_cartridge_level > 1:\n                print(f\"Printing {self.dequeue()}\")\n                self.black_cartridge_level -= 1\n            else:\n                print(\"RAISE Black Cartridge is EMPTY\")\n                return\n        else:\n            print(\"RAISE No documents enqueued\")\n\n    def add_cartridge(self, color: str=\"black\"):\n        if color == \"black\":\n            self.black_cartridge_level = 100\n            print(\"Cartridge black SET\")\n        else:\n            print(\"This printer accepts BLACK cartridge only\")\n\n\nclass PrinterColor(Printer):\n\n    def __init__(self):\n        super().__init__()\n        self.cartridges_status = {\"black\": 100, \"yellow\": 4, \"magenta\": 2, \"cyan\": 100}\n\n    def cartridge_level(self):\n        return self.cartridges_status\n\n    def print_document(self):\n\n        if self.queue.__len__() > 0:\n            for color, level in self.cartridges_status.items():\n                if level == 0:\n                    print(f\"RAISE {color.capitalize()} cartridge is EMPTY\")\n                    return\n            print(f\"Printing {self.dequeue()}\")\n            for color in self.cartridges_status.keys():\n                self.cartridges_status[color] -= 1\n        else:\n            print(\"RAISE No documents enqueued\")\n\n    def add_cartridge(self, color: str):\n        if color in self.cartridges_status.keys():\n            self.cartridges_status[color] = 100\n            print(f\"Cartridge {color} SET\")\n        else:\n            print(f\"RAISE {color.upper()} is not a valid cartridge\")\n\n\nclass Multifunction(PrinterColor, Scanner, Fax):\n\n    def save_document(self):\n        print(f\"Saving document {self.dequeue()} to Documents Folder\")\n\n    def send_document(self, target_number: str):\n        print(f\"Sending document {self.dequeue()} to {target_number}\")\n\n    def receive_document(self, docname: str, from_number: str):\n        self.enqueue(docname + \"_\" + from_number)\n\n\nprn_01 = PrinterBN()\nprn_02 = PrinterColor()\nprn_03 = Multifunction()\n\nprn_01.enqueue(\"Fichero_1.txt\")\nprn_01.print_document()\nprn_01.print_document()\n\nprn_02.enqueue(\"Album.pdf\")\nprn_02.enqueue(\"MapaGoogle.png\")\nprn_02.enqueue(\"DiplomaPython.pdf\")\nprn_02.print_document()\nprn_02.print_document()\nprn_02.print_document()\nprn_02.add_cartridge(\"Majenta\")\nprn_02.add_cartridge(\"magenta\")\nprn_02.print_document()\nprn_02.print_document()\n\nprn_03.receive_document(\"Notificacion.docx\", \"+5491112345678\")\nprn_03.save_document()\nprn_03.enqueue(\"Respuesta_Notificacion.docx\")\nprn_03.send_document(\"+5491112345678\")\nprn_03.enqueue(\"Git y GitHub desde cero.pdf\")\nprn_03.enqueue(\"Git y GitHub desde cero.pdf\")\nprn_03.enqueue(\"Git y GitHub desde cero.pdf\")\nprn_03.enqueue(\"Git y GitHub desde cero.pdf\")\nprn_03.enqueue(\"Git y GitHub desde cero.pdf\")\nprn_03.print_document()\nprn_03.print_document()\nprn_03.print_document()\nprn_03.add_cartridge(\"magenta\")\nprn_03.print_document()\nprn_03.print_document()\nprn_03.print_document()\nprn_03.add_cartridge(\"yellow\")\nprn_03.print_document()\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/nlarrea.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el \"Principio SOLID de Segregación de Interfaces (Interface Segregation Principle, ISP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un gestor de impresoras.\n * Requisitos:\n * 1. Algunas impresoras sólo imprimen en blanco y negro.\n * 2. Otras sólo a color.\n * 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n * Instrucciones:\n * 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n * 2. Aplica el ISP a la implementación.\n * 3. Desarrolla un código que compruebe que se cumple el principio.\n\"\"\"\n\n# To use interfaces\nfrom abc import ABC, abstractmethod\n\n\n# Incorrect\n\n\nclass WorkerInterface(ABC):\n\n    @abstractmethod\n    def work(self):\n        pass\n\n    @abstractmethod\n    def eat(self):\n        pass\n\n\nclass Human(WorkerInterface):\n    def work(self):\n        print(\"Working\")\n\n    def eat(self):\n        print(\"Eating\")\n\n\nclass Robot(WorkerInterface):\n    def work(self):\n        print(\"Working\")\n\n    def eat(self):\n        pass  # Robots don't eat\n\n\n\"\"\" What is wrong?\n- Interface has two methods, but one of its children classes doesn't use it.\n\"\"\"\n\n\n# Correct\n\n\nclass WorkInterface(ABC):\n\n    @abstractmethod\n    def work(self):\n        pass\n\n\nclass EatInterface(ABC):\n\n    @abstractmethod\n    def eat(self):\n        pass\n\n\nclass Human(WorkInterface, EatInterface):\n    def work(self):\n        print(\"Working\")\n\n    def eat(self):\n        print(\"Eating\")\n\n\nclass Robot(WorkInterface):\n    def work(self):\n        print(\"Working\")\n\n\nhuman = Human()\nhuman.work()\nhuman.eat()\n\nrobot = Robot()\nrobot.work()\n\n\"\"\"\nUse only interfaces that are always necessary for the children. If one of the\nchildren doesn't use one of the methods, it's better to split the interface and\nadd only the ones that are going to be implemented.\n\"\"\"\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un gestor de impresoras.\n * Requisitos:\n * 1. Algunas impresoras sólo imprimen en blanco y negro.\n * 2. Otras sólo a color.\n * 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n * Instrucciones:\n * 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n * 2. Aplica el ISP a la implementación.\n * 3. Desarrolla un código que compruebe que se cumple el principio.\n\"\"\"\n\n# Define interfaces\n\n\nclass PrinterInterface(ABC):\n\n    @abstractmethod\n    def print(self, document: str):\n        pass\n\n\nclass ColorPrinterInterface(ABC):\n\n    @abstractmethod\n    def print_color(self, document: str):\n        pass\n\n\nclass ScannerInterface(ABC):\n\n    @abstractmethod\n    def scan(self, document: str) -> str:\n        pass\n\n\nclass FaxInterface(ABC):\n\n    @abstractmethod\n    def send_fax(self, document):\n        pass\n\n\n# Create classes\n\n\nclass Printer(PrinterInterface):\n    def print(self, document: str):\n        print(f\"Printing (black & white): {document}\")\n\n\nclass ColorPrinter(ColorPrinterInterface):\n    def print_color(self, document: str):\n        print(f\"Printing (color): {document}\")\n\n\nclass MultifunctionPrinter(\n    PrinterInterface, ColorPrinterInterface, ScannerInterface, FaxInterface\n):\n    def print(self, document: str):\n        print(f\"Printing (black & white): {document}\")\n\n    def print_color(self, document: str):\n        print(f\"Printing (color): {document}\")\n\n    def scan(self, document: str) -> str:\n        print(f\"Scanning document: {document}\")\n        return \"scanned\" + document\n\n    def send_fax(self, document):\n        print(f\"Sending through fax: {document}\")\n\n\n# Testing the classes\n\nDOCUMENT = \"my-document.txt\"\n\nprinter = Printer()\nprinter.print(DOCUMENT)\n\ncolor_printer = ColorPrinter()\ncolor_printer.print_color(DOCUMENT)\n\nmultifunction_printer = MultifunctionPrinter()\nmultifunction_printer.print(DOCUMENT)\nmultifunction_printer.print_color(DOCUMENT)\nmultifunction_printer.scan(DOCUMENT)\nmultifunction_printer.send_fax(DOCUMENT)\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/oriaj3.py",
    "content": "\"\"\"\n29 - SOLID ISP - Interface Segregation Principle\nAutor de la solución: oriaj3    \n\nEl principio de segregación de interfaces (ISP) establece que una clase no debe ser forzada a implementar interfaces que no usará.\nEn otras palabras, una clase no debe depender de métodos que no necesita. En lugar de tener una interfaz grande que contenga\nmuchos métodos, es mejor tener varias interfaces más pequeñas que contengan solo los métodos necesarios. \n\nUn ejemplo sería una interfaz de impresión que contiene métodos para imprimir, escanear y enviar por fax. Si una clase solo necesita\nel método de impresión, no debería verse obligada a implementar los métodos de escaneo y fax.\n\nEn Python no hay una forma directa de implementar interfaces, pero se pueden usar clases abstractas para lograr un comportamiento similar.\nSe usa la librería abc (Abstract Base Classes) para definir clases abstractas.\n\"\"\"\n\n\"\"\"\n * EJERCICIO:\n * Explora el \"Principio SOLID de Segregación de Interfaces (Interface Segregation Principle, ISP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento de forma correcta e incorrecta.\n\"\"\"\n\n# Ejemplo incorrecto\nfrom abc import ABC, abstractmethod\n\nclass PrinterInterface(ABC):\n    @abstractmethod\n    def imprimir(self):\n        pass\n\n    @abstractmethod\n    def escanear(self):\n        pass\n\n    @abstractmethod\n    def fax(self):\n        pass\n\nclass PrinterBW(PrinterInterface):\n    def imprimir(self):\n        return \"Imprimiendo en blanco y negro\"\n    \n    def escanear(self):\n        raise Exception(\"Esta impresora no puede escanear\")\n    \n    def fax(self):\n        raise Exception(\"Esta impresora no puede enviar fax\")\n\nclass PrinterScanner(PrinterInterface):\n    def imprimir(self):\n        return \"Imprimiendo\"\n    \n    def escanear(self):\n        return \"Escaneando\"\n    \n    def fax(self):\n        raise Exception(\"No puedo enviar fax\")\n\n# Ejemplo correcto\n\nclass PrinterInterface(ABC):\n    \n    @abstractmethod\n    def print(self):\n        pass\n    \nclass ScannerInterface(ABC):\n    \n    @abstractmethod\n    def scan(self):\n        pass\n\nclass FaxInterfaceando(ABC):\n    \n    @abstractmethod\n    def fax(self):\n        pass\n    \n#Implemento clases para cada interfaz\nclass PrinterWithScanner(PrinterInterface, ScannerInterface):\n    def print(self):\n        print(\"Imprimiendo1\")\n        \n    def scan(self):\n        print(\"Scan1\")\n    \nclass PrinterScannerFax(PrinterInterface, ScannerInterface, FaxInterfaceando):\n    def print(self):\n        print(\"Imprimiendo2\")\n        \n    def scan(self):\n        print(\"Scan2\")\n    \n    def fax(self):\n        print(\"Fax2\")\n        \n#Creo objetos de las clases\nprinter1 = PrinterWithScanner()\nprinter1.print()\nprinter1.scan()\n\nprinter2 = PrinterScannerFax()\nprinter2.print()\nprinter2.scan()\nprinter2.fax()\n\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un gestor de impresoras.\n * Requisitos:\n * 1. Algunas impresoras sólo imprimen en blanco y negro.\n * 2. Otras sólo a color.\n * 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n * Instrucciones:\n * 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n * 2. Aplica el ISP a la implementación.\n * 3. Desarrolla un código que compruebe que se cumple el principio.\n */\n\"\"\"\n#Implemento las interfaces\nclass PrinterInterface(ABC):\n    \n    @abstractmethod\n    def print(self, document):\n        pass\n\nclass ColorPrinterInterface(ABC):\n\n    @abstractmethod\n    def print_color(self, document: str):\n        pass\n    \nclass ScanInterface(ABC):\n    \n    @abstractmethod\n    def scan(self, str) -> str:\n        pass\n    \nclass FaxInterface(ABC):\n    \n    @abstractmethod\n    def fax(self, document):\n        pass\n    \n#Implemento las clases\nclass Printer(PrinterInterface):\n    def print(self, document: str):\n        print(f\"Imprimiendo en blanco y negro el documento {document}.\")\n\nclass Scanner(ScannerInterface):\n    def scan(self, document: str)-> str:\n        print(f\"Escaneando el documento {document}.\")\n        return f\"Documento {document} escaneado.\"\n\nclass ColorPrinter(ColorPrinterInterface):\n    def print_color(self, document: str):\n        print(f\"Imprimiendo en color el documento {document}.\")\n        \nclass MultiPrinter(PrinterInterface, ColorPrinterInterface, ScanInterface, FaxInterface):\n    def print(self, document: str):\n        print(f\"Imprimiendo en blanco y negro el documento {document}.\")\n    \n    def print_color(self, document: str):\n        print(f\"Imprimiendo en color el documento {document}.\")\n    \n    def scan(self, document: str)-> str:\n        print(f\"Escaneando el documento {document}.\")\n        return f\"Documento {document} escaneado.\"\n    \n    def fax(self, document: str):\n        print(f\"Enviando por fax el documento {document}.\")\n\n#Función que crea los distintos objetos y prueba su función\ndef test_devices():\n    printer = Printer()\n    scanner = Scanner()\n    color_printer = ColorPrinter()\n    multiprinter = MultiPrinter()\n    \n    printer.print(\"Doc1.pdf\")\n    color_printer.print_color(\"DocColor2.pdf\")\n    scanner.scan(\"doc_scan.pdf\")\n    \n    multiprinter.print(\"Doc2.pdf\")\n    multiprinter.print_color(\"DocColor2.pdf\")\n    multiprinter.scan(\"Doc_Scan2.pdf\")\n    multiprinter.fax(\"DocFax.pdf\")\n    \ntest_devices()\n    "
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/pyramsd.py",
    "content": "## USO CORRECTO\nfrom abc import ABC, abstractmethod\n\nclass Printer(ABC):\n    @abstractmethod\n    def imprime(self, documento): print(f\"Documento {documento} impreso\")\n\nclass Escaner(ABC):\n    @abstractmethod\n    def escanear(self, documento): print(f\"Documento {documento} escaneado\")\n\nclass Fax(ABC):\n    @abstractmethod\n    def fax(self, documento): print(f\"Documento {documento} faxeado?\")\n\n\nclass BasicPrinter(Printer):\n    def imprime(self, document):\n        return super().imprime(document)\n\nclass BasicScanner(Escaner):\n    def escanear(self, document):\n        return super().escanear(document)\n    \nclass BasicFax(Fax):\n    def fax(self, document):\n        return super().fax(document)\n    \nclass MultiFunctionalMachine(Printer, Escaner, Fax):\n    def imprime(self, documento):\n        return super().imprime(documento)\n    \n    def escanear(self, documento):\n        return super().escanear(documento)\n    \n    def fax(self, documento):\n        return super().fax(documento)\n\nimpresora_basica = BasicPrinter()\nimpresora_basica.imprime(\"secret.txt\")\n\nescaner_basica = BasicScanner()\nescaner_basica.escanear(\"secret.txt\")\n\nfax_basica = BasicFax()\nfax_basica.fax(\"secret.txt\")\n\nmaquina_multifuncional = MultiFunctionalMachine()\nmaquina_multifuncional.imprime(\"response.txt\")\nmaquina_multifuncional.escanear(\"response.txt\")\nmaquina_multifuncional.fax(\"response.txt\")\n\n\n# USO INCORRECTO\nfrom abc import ABC, abstractmethod\n\nclass Machine(ABC):\n    @abstractmethod\n    def print(self, document):\n        pass\n\n    @abstractmethod\n    def scan(self, document):\n        pass\n\n    @abstractmethod\n    def fax(self, document):\n        pass\n\n# Implementación de una impresora básica que no necesita escanear ni enviar faxes\nclass ImpresoraBasica(Machine):\n    def print(self, document):\n        print(f\"Printing document: {document}\")\n\n    def scan(self, document):\n        print(\"Esta impresora no escanea\")\n\n    def fax(self, document):\n        print(\"Esta impresora no faxea?\")\n\nbasic_printer = ImpresoraBasica()\nbasic_printer.print(\"My report\")\nbasic_printer.scan(\"My report\")  # Esto lanzará una excepción\n\n\n\"\"\"\nEXTRA\n\"\"\"\nclass ImpresoraBW(ABC):\n    @abstractmethod\n    def imprimeBW(self, documento):\n        print(f\"Esta impresora imprime solo a blanco y negro el documento {documento}\")\n\nclass ImpresoraRGB(ABC):\n    @abstractmethod\n    def imprimeRGB(self, documento):\n        print(f\"Esta impresora imprime a color el documento {documento}\")\n\nclass Escaner(ABC):\n    @abstractmethod\n    def escanear(self, documento): print(f\"Documento {documento} escaneado\")\n\nclass Fax(ABC):\n    @abstractmethod\n    def fax(self, documento): print(f\"Documento {documento} faxeado?\")\n\nclass Impresora2Colors(ImpresoraBW):\n    def imprimeBW(self, documento):\n        return super().imprimeBW(documento)\n\nclass ImpresoraAllColors(ImpresoraRGB):\n    def imprimeRGB(self, documento):\n        return super().imprimeRGB(documento)\n\nclass AllInOneMachine(ImpresoraBW, ImpresoraRGB, Escaner, Fax):\n    def imprimeBW(self, documento):\n        return super().imprimeBW(documento)\n    \n    def imprimeRGB(self, documento):\n        return super().imprimeRGB(documento)\n    \n    def escanear(self, documento):\n        return super().escanear(documento)\n    \n    def fax(self, documento):\n        return super().fax(documento)\n    \n\nimpresoraBW = Impresora2Colors()\nimpresoraRGB = ImpresoraAllColors()\nmaquinaAllInOne = AllInOneMachine()\n\nimpresoraBW.imprimeBW(\"passwords.txt\")\nimpresoraRGB.imprimeRGB(\"images\")\nmaquinaAllInOne.imprimeBW(\"response.txt\")\nmaquinaAllInOne.imprimeRGB(\"response.txt\")\nmaquinaAllInOne.escanear(\"Images\")\nmaquinaAllInOne.fax(\"text.txt\")\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/rantamhack.py",
    "content": "\n\nprint(\"\\n\\n=======================================DIFICULTAD EXTRA=======================================\\n\\n\")\n\n\"\"\"\n * EJERCICIO:\n * Explora el \"Principio SOLID de Segregacion de Interfaces (Interface Segregation Principle, ISP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento de forma correcta e incorrecta.\n\"\"\"\n\n# SIN ISP\n# from abc import ABC, abstractmethod\n\n# class Car:\n#     @abstractmethod\n#     def go_to(self):\n#         pass\n        \n\n#     @abstractmethod\n#     def park(self):\n#         pass\n    \n#     @abstractmethod\n#     def refueling(self):\n#         pass\n        \n#     @abstractmethod\n#     def charging_batery(self):\n#         pass\n    \n    \n# class GasCar(Car):\n#     def go_to(self):\n#         return \"going to work\"\n\n#     def park(self):\n#         return \"car parking\"\n    \n#     def refueling(self):\n#         return \"The car is refueling\"\n    \n#     def charging_batery(self):   # ESTA CLASE NO NECESITA ESTE METODO\n#         return \"The car is charging the batteries\"\n    \n# class ElectricCar(Car):\n#     def go_to(self):\n#         return \"going to work\"\n\n#     def park(self):\n#         return \"car parking\"\n    \n#     def refueling(self):         # ESTA CLASE NO NECESITA ESTE METODO\n#         return \"The car is refueling\"\n    \n#     def charging_batery(self):\n#         return \"The car is charging the batteries\"\n    \n    \n    \nfrom abc import ABC, abstractmethod\n\n# CON ISP\n\nclass Car(ABC):\n    @abstractmethod\n    def go_to(self):\n        pass\n        \n\n    @abstractmethod\n    def park(self):\n        pass\n    \nclass GasCar:\n    @abstractmethod\n    def refueling(self):\n        pass\n        \nclass ElectricCar:\n    @abstractmethod\n    def charging_batery(self):\n        pass\n    \n    \nclass MyGasCar(Car, GasCar):\n    def go_to(self):\n        return \"going to work\"\n\n    def park(self):\n        return \"car parking\"\n    \n    def refueling(self):\n        return \"The car is refueling\"\n    \n    \nclass MyElectricCar(Car, ElectricCar):\n    def go_to(self):\n        return \"going to work\"\n\n    def park(self):\n        return \"car parking\"\n    \n    def charging_batery(self):\n        return \"The car is charging the batteries\"\n\nmy_car = MyGasCar()\n\nprint(my_car.go_to())\nprint(my_car.park())\nprint(my_car.refueling())\n\n\nmy_other_car = MyElectricCar()\n\nprint(my_other_car.go_to())\nprint(my_other_car.park())\nprint(my_other_car.charging_batery())    \n\n\n\n\n\nprint(\"\\n\\n=======================================DIFICULTAD EXTRA=======================================\\n\\n\")\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un gestor de impresoras.\n * Requisitos:\n * 1. Algunas impresoras solo imprimen en blanco y negro.\n * 2. Otras solo a color.\n * 3. Otras son multifuncion, pueden imprimir, escanear y enviar fax.\n * Instrucciones:\n * 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n * 2. Aplica el ISP a la implementacion.\n * 3. Desarrolla un codigo que compruebe que se cumple el principio.\n\"\"\"\nfrom abc import ABC, abstractmethod\n\nclass PrinterManager(ABC):\n    @abstractmethod\n    def standby(self):\n        pass\n\n    \nclass BlackAndWhitePrinter(ABC):\n    @abstractmethod\n    def print_bw(self):\n        self\n        \n        \nclass ColorPrinter(ABC):\n    @abstractmethod\n    def color_print(self):\n        pass\n        \nclass Scan(ABC):\n    @abstractmethod\n    def scan(self):\n        pass\n    \n    \nclass SendFax(ABC):\n    @abstractmethod   \n    def send_fax(self):\n        pass\n    \n    \nclass Printer(PrinterManager, BlackAndWhitePrinter):\n    def standby(self):\n        print(\"Printer is on standby\")\n        \n    def print_bw(self):\n        print(\"Printer is printing in black and white\")  \n        \n\nclass CPrinter(PrinterManager, ColorPrinter):\n    def standby(self):\n        print(\"Printer is on standby\")\n        \n    def color_print(self):\n        print(\"Printer is printing in color\")\n        \n     \nclass MultifunctionPrinter(PrinterManager, BlackAndWhitePrinter, ColorPrinter, Scan, SendFax):\n    def standby(self):\n        print(\"Printer is on standby\")\n        \n    def print_bw(self):\n        print(\"Printer is printing in black and white\") \n        \n    def color_print(self):\n        print(\"Printer is printing in color\") \n        \n    def scan(self):\n        print(\"Multifunction printer is scannig a document\")\n    \n    def send_fax(self):\n        print(\"Multifunction printer is faxing\")\n        \n        \nprinter1 = Printer()\nprinter2 = CPrinter()\nprinter3 = MultifunctionPrinter()\n\nprint(\"****************************************************\")\n\nprinter1.standby()\nprinter1.print_bw()\n\nprint(\"****************************************************\")\n\nprinter2.standby()\nprinter2.color_print()\n\nprint(\"****************************************************\")\n\nprinter3.standby()\nprinter3.print_bw()\nprinter3.color_print()\nprinter3.scan()\nprinter3.send_fax()\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/raulG91.py",
    "content": "from abc import ABC, abstractmethod\n\n#Incorrect example\nclass Phone(ABC):\n    @abstractmethod\n    def call(self):\n        pass\n    def play_game(self):\n        pass\n    def install_app(self):\n        pass\n    def gps_nav(self):\n        pass\n\nclass OldPhone(Phone):\n    def call(self):\n        print(\"Making a call\")\n    def play_game(self):\n        print(\"Playing snake game\")\n    def install_app(self):\n        raise NotImplementedError(\"You can not install applications\")\n    def gps_nav(self):\n        raise NotImplementedError(\"You can not use gps\")\n\nclass NewPhone(Phone):\n    def call(self):\n        print(\"Making a call\")\n    def play_game(self):\n        print(\"Playing a game\")\n    def install_app(self):\n        print(\"Intalling application\")\n    def gps_nav(self):\n        print(\"Using Maps navigation\")\n\nnokia = OldPhone()\nnokia.call()\ntry:\n    nokia.install_app()\nexcept  Exception as e:\n    print(e)    \nnokia.play_game()    \n\niphone5 = NewPhone()\niphone5.play_game()\niphone5.install_app()\niphone5.gps_nav()\n\n#Correct example\n\nclass PhoneV2(ABC):\n    def call(self):\n        pass\n    def play_game(self):\n        pass\n\nclass PhoneApp(ABC):\n    @abstractmethod\n    def install_app(self):\n        pass\n\nclass PhoneGPS(ABC):\n    def gps_nav(self):\n        pass\n\nclass OldPhone2(PhoneV2):\n    def call(self):\n        print(\"Making a call\")\n    def play_game(self):\n        print(\"Playing snake game\") \n\nclass NewPhone2(PhoneV2,PhoneApp,PhoneGPS):\n    def call(self):\n        print(\"Making a call\")\n    def play_game(self):\n        print(\"Playing a game\")\n    def install_app(self):\n        print(\"Intalling application\")\n    def gps_nav(self):\n        print(\"Using Maps navigation\")   \n\niphone15 = NewPhone2()\niphone15.gps_nav()\niphone15.call()\n\nalcatel = OldPhone2()\nalcatel.call()\n\n#Extra\nprint(\"--Extra--\")\n\nclass PrinterColor(ABC):\n    @abstractmethod\n    def printColor(self,text):\n        pass\nclass PrinterBlackWhite(ABC):\n    @abstractmethod\n    def printBlack(self,text):\n        pass    \n\nclass Scan(ABC):\n    @abstractmethod\n    def scan(self):\n        pass\nclass Fax(ABC):\n    @abstractmethod\n    def send_fax(self):\n        pass\n\n\nclass OldPrinter(PrinterBlackWhite):\n    def printBlack(self, text):\n        print(f'Printing {text} black and white')\n\nclass ModernPrinter(PrinterColor):\n    def printColor(self, text):\n        print(f'Printing {text} in color')\n\nclass MultifunctionPrinter(PrinterColor,PrinterBlackWhite,Scan,Fax):\n    def printBlack(self, text):\n        print(f'Printing {text} black and white from multifunction printer')\n    def printColor(self, text):\n        print(f'Printing {text} in color from multifunction printer') \n    def scan(self):\n        print(\"Scaning document\")\n    def send_fax(self):\n        print(\"Sending fax\")        \n\nprinter1 = OldPrinter()\nprinter1.printBlack(\"Some text \")\nprinter2 = ModernPrinter()\nprinter2.printColor(\"Text in color\")\nprinter3 = MultifunctionPrinter()\nprinter3.printColor(\"En un lugar de la mancha\")\nprinter3.printBlack(\"Hey!\")\nprinter3.scan()\nprinter3.send_fax()"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/raynerpv2022.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * Explora el \"Principio SOLID de Segregación de Interfaces (Interface Segregation Principle, ISP)\" \n#  * y crea un ejemplo simple donde se muestre su funcionamiento de forma correcta e incorrecta.\n#  *\n\n\n\n# Viola el principio de segregacion ..\nfrom abc import ABC,abstractmethod\n\nclass Worker(ABC):\n    @abstractmethod\n    def sleep(self):\n        pass\n\n    @abstractmethod\n    def work(self):\n        pass\n\n    @abstractmethod\n    def eat(self):\n        pass\n\nclass Robot(Worker):\n    def work(self):\n        print(\"Robot is working...\")\n\n    def sleep(self):\n         pass\n    \n    def eat(self):\n        pass\n\nclass Human (Worker):\n    def sleep(self):\n        print(\"Human is sleeping...\")\n    def work(self):\n        print(\"Human is working...\")\n    def eat(self):\n        print(\"Human is eating..\")\n\nprint(\"Whitout iSP\")\nR = Robot()\nR.work()\nH = Human()\nH.work()\nH.eat()\nH.sleep()\n\n#  aplicando principio de segregacion\n\nclass WorkInterface(ABC):\n    @abstractmethod\n    def work(self):\n        pass\n\nclass EatINterface(ABC):\n    @abstractmethod\n    def eat(self):\n        pass\n\nclass SleepInterface(ABC):\n    @abstractmethod\n    def sleep(self):\n        pass\n\nclass Human(WorkInterface,SleepInterface,EatINterface):\n     \n    def work(self):\n        print(\"HUman is working...\")\n    \n    def sleep(self):\n        print(\"HUman is sleeping\")\n\n    def eat(self):\n        print(\"Human is eating\")  \n\nclass Robot(WorkInterface):\n    def work(self):\n        print(\"Robot is workiing...\")\n\n\nprint(\"ISP\")\nRo = Robot()\nRo.work()\nHu = Human()\nHu.sleep()\nHu.work()\nHu.eat()\n\n\n# EXTRA\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea un gestor de impresoras.\n#  * Requisitos:\n#  * 1. Algunas impresoras sólo imprimen en blanco y negro.\n#  * 2. Otras sólo a color.\n#  * 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n#  * Instrucciones:\n#  * 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n#  * 2. Aplica el ISP a la implementación.\n#  * 3. Desarrolla un código que compruebe que se cumple el principio.\n#  */\n\n\nclass Scaninterface(ABC):\n    @abstractmethod\n    def Scan(self):\n        pass\n    \nclass FAXinterface(ABC):\n    @abstractmethod\n    def Fax(self):\n        pass\n\nclass PrintetInterface(ABC):\n    @abstractmethod\n    def Print(self):\n        pass\n\n\nclass ColorPrintInterface(ABC):\n    @abstractmethod\n    def Print_color(self):\n        pass\n\nclass Printer (PrintetInterface):\n    def Print(self):\n        print(\"IMpresora solo imprime white and black\")\n    \n\nclass PrinterColor(ColorPrintInterface):\n    def Print_color(self):\n        print(\"Impresora a Color...\")\n\nclass MultiFunction(PrintetInterface,ColorPrintInterface,Scaninterface,FAXinterface):\n    def Print(self):\n        print(\"Multifuncion Printing white and Black...\")\n        \n    def Print_color(self):\n        print(\"Multifuncion Printing in color...\")\n        \n\n    def Scan(self):\n        print(\"Mutifunction Scanning...\")\n\n    def Fax(self):\n        print(\"MultiFunction Faxing...\")\nprint(\"PRINTER\")\n\nprinter_wb = Printer()\nprinter_wb.Print()\nprinter_c = PrinterColor()\nprinter_c.Print_color()\n\nmulti = MultiFunction()\nmulti.Print()\nmulti.Print_color()\nmulti.Scan()\nmulti.Fax()"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/rigo93acosta.py",
    "content": "'''\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Segregación de Interfaces (Interface Segregation Principle, ISP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un gestor de impresoras.\n * Requisitos:\n * 1. Algunas impresoras sólo imprimen en blanco y negro.\n * 2. Otras sólo a color.\n * 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n * Instrucciones:\n * 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n * 2. Aplica el ISP a la implementación.\n * 3. Desarrolla un código que compruebe que se cumple el principio.\n */\n'''\n\n'''\nEjercicio\n\nTrabajo con interfaces en las\nclases\n'''\n\nfrom abc import ABC, abstractmethod\n\n# SIN ISP\n\nclass WorkerInterface(ABC):\n\n    @abstractmethod\n    def work(self):\n        ...\n\n    @abstractmethod\n    def eat(self):\n        ...\n\n\nclass Human(WorkerInterface):\n\n    def work(self):\n        print(\"Trabajando\")\n    \n    def eat(self):\n        print(\"Comiendo\")\n\n\nclass Robot(WorkerInterface):\n\n    def work(self):\n        print(\"Trabajando\")\n\n    def eat(self):\n        # Los robot no comen\n        pass\n\n\nhuman = Human()\nhuman.work()\nhuman.eat()\n\nrobot = Robot()\nrobot.work()\nrobot.eat() ## Error\n\n# CON ISP\n\nclass WorkInterface(ABC):\n\n    @abstractmethod\n    def work(self):\n        ...\n\nclass EatInterface(ABC):\n\n    @abstractmethod\n    def eat(self):\n        ...\n\nclass Human(WorkInterface, EatInterface):\n\n    def work(self):\n        print(\"Trabajando\")\n    \n    def eat(self):\n        print(\"Comiendo\")\n\nclass Robot(WorkInterface):\n\n    def work(self):\n        print(\"Trabajando\")\n\n'''\nExtra\n'''\n\n# Interfaces\nclass PrinterInterface(ABC):\n\n    @abstractmethod\n    def print(self, document: str):\n        ...\n\nclass ColorPrinterInterface(ABC):\n\n    @abstractmethod\n    def print_color(self, document: str):\n        ...\n\nclass ScannerInterface(ABC):\n    \n    @abstractmethod\n    def scan(self, document: str) -> str:\n        ...\n\nclass FaxInterface(ABC):\n    \n    @abstractmethod\n    def fax(self, document: str):\n        ...\n\n# Clases Especificas\n\nclass Printer(PrinterInterface):\n    def print(self, document: str):\n        print(\nf\"Imprimiendo en blanco y negro el docuemento {document}\"\n)\n        \nclass ColorPrinter(ColorPrinterInterface):\n\n    def print_color(self, document: str):\n        print(\nf\"Imprimiendo en color el docuemento {document}\"\n)\n\nclass MultiFunctionPrinter(PrinterInterface, ColorPrinterInterface,\n                           ScannerInterface, FaxInterface):\n\n    def print_color(self, document: str):\n        print(\nf\"Imprimiendo en color el docuemento {document}\"\n)\n\n    def print(self, document: str):\n        print(\nf\"Imprimiendo en blanco y negro el docuemento {document}\"\n)\n\n    def scan(self, document: str) -> str:\n        print(f\"Escaneando el documento {document}\")\n        return f\"Documento {document} escaneado\"     \n\n    def fax(self, document: str):\n        print(f\"Enviando por fax el documento {document}\")\n\ndef test_printers():\n    printer = Printer()\n    printer.print(\"Rigo.docx\")\n\n    printer_color = ColorPrinter()\n    printer_color.print_color(\"Rigo.docx\")\n\n    multi_printer = MultiFunctionPrinter()\n    multi_printer.print(\"Rigo.docx\")\n    multi_printer.print_color(\"Rigo.docx\")\n    print(multi_printer.scan((\"Rigo.docx\")))\n    multi_printer.fax((\"Rigo.docx\"))\n\ntest_printers()"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/rikmij.py",
    "content": "from abc import ABC, abstractmethod\n\n#Uso incorrecto\nclass Aveh(ABC):\n    @abstractmethod\n    def walk(self):\n        pass\n    \n    @abstractmethod\n    def fly(self):\n        pass\n\nclass Bird_(Aveh):\n    def walk(self):\n        return \"El pájaro está caminando\"\n    \n    def fly():\n        return \"El pájaro está volando\"\n\nclass Penguin_(Aveh):\n    def walk(self):\n        return \"El pingüino está caminando\"\n    \n    def fly(self):\n        return \"El pingüino está volando\"\n\nbird_ = Bird_()\nprint(bird_.walk())\n\n'''\nEs incorrecto porque los pingünos no vuelan. Para que se de este principio tienen que venir de una clase\ncon métodos generales y cada subclase sus métodos específicos\n'''\n\n#Uso correcto\nclass Ave(ABC):\n    @abstractmethod\n    def walk(self):\n        pass\n\nclass Bird(Ave):\n    def walk(self):\n        return \"El pájaro está caminando\"\n    \n    def fly(self):\n        return \"El pájaro está volando\"\n\nclass Penguin(Ave):\n    def walk(self):\n        return \"El pingüino está caminando\"\n    \n    def swim(self):\n        return \"El pingüino está nadando\"\n\nbird = Bird()\nprint(bird.fly())\npenguin = Penguin()\nprint(penguin.swim())\n\nprint(\"\\n\", \"*\"*7, \"EJERCICIO EXTRA\", \"*\"*7)\nclass Printer(ABC):\n    @abstractmethod\n    def printing(self, doc):\n        return f\"Imprimiendo {doc}\"\n\nclass Printer_Functions(Printer):\n    @abstractmethod\n    def scan(self, doc):\n        return f\"Escaneando \\\"{doc}\\\"\"\n    \n    @abstractmethod\n    def send_fax(self, doc, fax):\n        return f\"Enviando \\\"{doc}\\\" al {fax}\"\n    \n\nclass ByW_Printer(Printer):\n    def printing(self, doc):\n        return f\"Imprimiendo en blanco y negro: {doc}\"\n\nclass Color_Printer(Printer):\n    def printing(self, doc):\n        return f\"Imprimiendo a color: {doc}\"\n\nclass Multi_Printer(Printer_Functions):\n    def printing(self, doc):\n        return f\"Imprimiendo a color: {doc}\"\n    \n    def scan(self, doc):\n        return super().scan(doc)\n    \n    def send_fax(self, doc, fax):\n        return super().send_fax(doc, fax)\n\nbyn = ByW_Printer()\nprint(byn.printing(\"El Quijote\"))\n\ncolor = Color_Printer()\nprint(color.printing(\"Batman Begins\"))\n\nprinter = Multi_Printer()\nprint(printer.send_fax(\"Trabajo Final\", 254789630))\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/python/santyjL.py",
    "content": "#29 SOLID: PRINCIPIO DE SEGREGACIÓN DE INTERFACES (ISP)\n\n\"\"\"\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Segregación de Interfaces (Interface Segregation Principle, ISP)\"\n * y crea un ejemplo simple donde se muestre su funcionamiento de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un gestor de impresoras.\n * Requisitos:\n * 1. Algunas impresoras sólo imprimen en blanco y negro.\n * 2. Otras sólo a color.\n * 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n * Instrucciones:\n * 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n * 2. Aplica el ISP a la implementación.\n * 3. Desarrolla un código que compruebe que se cumple el principio.\n */\n\"\"\"\nfrom abc import ABC, abstractmethod\n\n\n# Interfaces pequeñas y específicas para cada tipo de vehículo\nclass VehiculoTerrestre(ABC):\n    @abstractmethod\n    def conducir(self):\n        pass\n\nclass VehiculoAereo(ABC):\n    @abstractmethod\n    def volar(self):\n        pass\n\nclass VehiculoAcuatico(ABC):\n    @abstractmethod\n    def navegar(self):\n        pass\n\n# Clase Coche que solo necesita implementar la interfaz de Vehículo Terrestre\nclass Coche(VehiculoTerrestre):\n    def conducir(self):\n        print(\"El coche está conduciendo.\")\n\n# Clase Avión que solo implementa la interfaz de Vehículo Aéreo\nclass Avion(VehiculoAereo):\n    def volar(self):\n        print(\"El avión está volando.\")\n\n# Clase Barco que solo implementa la interfaz de Vehículo Acuático\nclass Barco(VehiculoAcuatico):\n    def navegar(self):\n        print(\"El barco está navegando.\")\n\n# Crear instancias de los vehículos\ncoche = Coche()\navion = Avion()\nbarco = Barco()\n\n# Usar los métodos según las interfaces implementadas\ncoche.conducir()  # Salida: El coche está conduciendo.\navion.volar()     # Salida: El avión está volando.\nbarco.navegar()   # Salida: El barco está navegando.\n\n#mal uso\n# Interfaz general que agrupa todas las funcionalidades para vehículos\nclass Vehiculo(ABC):\n    @abstractmethod\n    def conducir(self):\n        pass\n\n    @abstractmethod\n    def volar(self):\n        pass\n\n    @abstractmethod\n    def navegar(self):\n        pass\n\n# Clase Coche que no necesita volar ni navegar, pero debe implementar los métodos\nclass Coche(Vehiculo):\n    def conducir(self):\n        print(\"El coche está conduciendo.\")\n\n    def volar(self):\n        raise NotImplementedError(\"El coche no puede volar.\")  # Error\n\n    def navegar(self):\n        raise NotImplementedError(\"El coche no puede navegar.\")  # Error\n\n# Clase Avión que no necesita conducir ni navegar, pero debe implementar los métodos\nclass Avion(Vehiculo):\n    def conducir(self):\n        raise NotImplementedError(\"El avión no puede conducir.\")  # Error\n\n    def volar(self):\n        print(\"El avión está volando.\")\n\n    def navegar(self):\n        raise NotImplementedError(\"El avión no puede navegar.\")  # Error\n\n# Clase Barco que no necesita conducir ni volar, pero debe implementar los métodos\nclass Barco(Vehiculo):\n    def conducir(self):\n        raise NotImplementedError(\"El barco no puede conducir.\")  # Error\n\n    def volar(self):\n        raise NotImplementedError(\"El barco no puede volar.\")  # Error\n\n    def navegar(self):\n        print(\"El barco está navegando.\")\n\ncoche = Coche()\navion = Avion()\nbarco = Barco()\n\n# Usar los métodos según la interfaz grande\ncoche.conducir()      # Funciona correctamente: \"El coche está conduciendo.\"\ncoche.volar()         # Error: El coche no puede volar.\ncoche.navegar()       # Error: El coche no puede navegar.\n\navion.volar()         # Funciona correctamente: \"El avión está volando.\"\navion.conducir()      # Error: El avión no puede conducir.\navion.navegar()       # Error: El avión no puede navegar.\n\nbarco.navegar()       # Funciona correctamente: \"El barco está navegando.\"\nbarco.volar()         # Error: El barco no puede volar.\nbarco.conducir()      # Error: El barco no puede conducir.\n\n\"\"\" !!!EXTRA¡¡¡ \"\"\"\n\n# Interfaces (Clases Abstractas)\nclass ImpresoraBlancoNegroInterfaz(ABC):\n    @abstractmethod\n    def impresion_en_blanco_y_negro(self):\n        pass\n\nclass ImpresoraColorInterfaz(ABC):\n    @abstractmethod\n    def impresion_a_color(self):\n        pass\n\nclass EscanerInterfaz(ABC):\n    @abstractmethod\n    def escanear(self):\n        pass\n\nclass EnviarFaxInterfaz(ABC):\n    @abstractmethod\n    def enviar_fax(self):\n        pass\n\n# Clases concretas\nclass ImpresoraBlancoNegro(ImpresoraBlancoNegroInterfaz):\n    def impresion_en_blanco_y_negro(self):\n        print(\"Se está imprimiendo el documento en blanco y negro\")\n\nclass ImpresoraColor(ImpresoraColorInterfaz):\n    def impresion_a_color(self):\n        print(\"Se está imprimiendo el documento a color\")\n\nclass ImpresoraMultifuncional(ImpresoraColorInterfaz, ImpresoraBlancoNegroInterfaz,\n                              EscanerInterfaz, EnviarFaxInterfaz):\n\n    def impresion_a_color(self):\n        print(\"Se está imprimiendo el documento a color\")\n\n    def impresion_en_blanco_y_negro(self):\n        print(\"Se está imprimiendo el documento en blanco y negro\")\n\n    def enviar_fax(self):\n        print(\"La impresora está enviando un Fax\")\n\n    def escanear(self):\n        print(\"La impresora está escaneando para sacarle copia al documento\")\n\n# Crear instancias de las clases\nimpresora_blanco_y_negro = ImpresoraBlancoNegro()\nimpresora_color = ImpresoraColor()\nimpresora_multifuncional = ImpresoraMultifuncional()\n\n# Ejecución del código\nprint(\"\\nImpresora a color e impresora en blanco y negro:\")\nimpresora_blanco_y_negro.impresion_en_blanco_y_negro()\nimpresora_color.impresion_a_color()\n\nprint(\"\\nImpresora Multifuncional:\")\nimpresora_multifuncional.impresion_a_color()\nimpresora_multifuncional.impresion_en_blanco_y_negro()\nimpresora_multifuncional.enviar_fax()\nimpresora_multifuncional.escanear()\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/rust/kenysdev.rs",
    "content": "/*\n╔═══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado                ║\n║ GitHub: https://github.com/Kenysdev   ║\n║ 2024 -  Rust                          ║\n╚═══════════════════════════════════════╝\n-----------------------------------------------------\n* SOLID: PRINCIPIO DE SEGREGACIÓN DE INTERFACES (ISP)\n-----------------------------------------------------\n- Una estructura no debería estar obligada a implementar interfaces que no utiliza.\n'   Evitando crear grandes clases monolíticas.\n\n_______________\n' NOTA: Este ejemplo muestra el uso CORRECTO. Para suponer un ejemplo que viole el principio, sería. \n'       Imaginar todos los métodos siguientes, en una sola interfaz, entonces algunos dispositivos\n'       implementarían una interfaz que no necesitan.\n*/\n\n//____________________________________\n// Interfaces\ntrait Playable {\n    fn play(&self);\n}\n\ntrait Displayable {\n    fn display(&self);\n}\n\n//____________________________________\n// Implementación\n\nstruct Speaker;\n\nimpl Playable for Speaker {\n    fn play(&self) {\n        println!(\"El altavoz está reproduciendo música.\");\n    }\n}\n\n//____________________________________\nstruct Phone;\n\nimpl Playable for Phone {\n    fn play(&self) {\n        println!(\"El teléfono está reproduciendo una canción.\");\n    }\n}\n\nimpl Displayable for Phone {\n    fn display(&self) {\n        println!(\"El teléfono está mostrando la pantalla de reproducción.\");\n    }\n}\n\n/*\n//____________________________________\n* EJERCICIO #2:\n'* Crea un gestor de impresoras.\n'* Requisitos:\n'* 1. Algunas impresoras sólo imprimen en blanco y negro.\n'* 2. Otras sólo a color.\n'* 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n'* Instrucciones:\n'* 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n'* 2. Aplica el ISP a la implementación.\n'* 3. Desarrolla un código que compruebe que se cumple el principio.\n*/\n\n//____________________________________\n// Interfaces\ntrait IPrinter {\n    fn print_file(&self, file: &str);\n}\n\ntrait IScanner {\n    fn to_scan(&self, path_save: &str);\n}\n\ntrait IFax {\n    fn send_file(&self, file: &str, phone_number: i32);\n}\n\n//____________________________________\n// Implementación\n\nstruct MonoPrinter;\n\nimpl IPrinter for MonoPrinter {\n    fn print_file(&self, file: &str) {\n        println!(\"\\nImpresora blanco y negro:\");\n        println!(\"{} se imprimió.\", file);\n    }\n}\n\n//____________________________________\nstruct ColorPrinter;\n\nimpl IPrinter for ColorPrinter {\n    fn print_file(&self, file: &str) {\n        println!(\"\\nImpresora a color:\");\n        println!(\"{} se imprimió.\", file);\n    }\n}\n\n//____________________________________\nstruct Scanner;\n\nimpl IScanner for Scanner {\n    fn to_scan(&self, path_save: &str) {\n        println!(\"\\nEscaneo realizado, guardado en: {}\", path_save);\n    }\n}\n\n//____________________________________\nstruct Fax;\n\nimpl IFax for Fax {\n    fn send_file(&self, file: &str, phone_number: i32) {\n        println!(\"\\n{} fue enviado a: {}\", file, phone_number);\n    }\n}\n\n//____________________________________\nstruct MultiFunctionPrinter {\n    mono_printer: MonoPrinter,\n    color_printer: ColorPrinter,\n    scanner: Scanner,\n    fax: Fax,\n}\n\nimpl MultiFunctionPrinter {\n    fn new() -> Self {\n        MultiFunctionPrinter {\n            mono_printer: MonoPrinter,\n            color_printer: ColorPrinter,\n            scanner: Scanner,\n            fax: Fax,\n        }\n    }\n}\n\n//____________________________________\nfn main() {\n    // exs 1\n    let speaker = Speaker;\n    speaker.play();\n\n    let phone = Phone;\n    phone.play();\n    phone.display();\n\n    //____________________________________\n    // exs 2\n    println!(\"\\nExs #2\");\n\n    // Individuales\n    let mono_printer = MonoPrinter;\n    mono_printer.print_file(\"filex.pdf\");\n\n    let color_printer = ColorPrinter;\n    color_printer.print_file(\"filex.pdf\");\n\n    let scanner = Scanner;\n    scanner.to_scan(\"c:\\\\docs\");\n\n    let fax = Fax;\n    fax.send_file(\"filex.pdf\", 12345678);\n\n    //____________________________________\n    println!(\"\\n__________\\nMultifunción\");\n    let mfp = MultiFunctionPrinter::new();\n\n    mfp.mono_printer.print_file(\"filex.pdf\");\n    mfp.color_printer.print_file(\"filex.pdf\");\n    mfp.scanner.to_scan(\"c:\\\\docs\");\n    mfp.fax.send_file(\"filex.pdF\", 123456789);\n\n}\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/sql/Nicojsuarez2.sql",
    "content": "# #29 SOLID: PRINCIPIO DE SEGREGACIÓN DE INTERFACES (ISP)\n> #### Dificultad: Media | Publicación: 15/07/24 | Corrección: 22/07/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Segregación de Interfaces (Interface Segregation Principle, ISP)\" \n * y crea un ejemplo simple donde se muestre su funcionamiento de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un gestor de impresoras.\n * Requisitos:\n * 1. Algunas impresoras sólo imprimen en blanco y negro.\n * 2. Otras sólo a color.\n * 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n * Instrucciones:\n * 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n * 2. Aplica el ISP a la implementación.\n * 3. Desarrolla un código que compruebe que se cumple el principio.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/swift/blackriper.swift",
    "content": "/*\nInterface Segregation Principle\n\nEste principio nos dice que una clase nunca debe extender de interfaces con métodos que no usa,\npor el principio de segregación de interfaces busca que las interfaces sean lo más pequeñas\ny específicas posible de modo que cada clase solo implemente los métodos que necesita.\n\nerrores comunes con este principio\n\n- Estaremos violando este principio si Tenemos clases que implementan métodos de interfaces que no se usan.\n\n- Definimos interfaces con parámetros que no se van a utilizar en todas las clases\n\n-cuando tenemos interfaces muy grandes y métodos que no son genéricos y que otras clases que implementen esta interfaz no puedan usar\n\n*/\n\n//ejemplo de lo que no debe de hacerce\n\nprotocol Animal{\n    func eat()\n    func sleep()\n    func run() throws->Void\n}\n\nenum ErrorAnimal:Error{\n    case IcannotRun(name:String)\n}\n\nclass Chicken:Animal{\n   let name:String\n   init(namePet:String){\n       name=namePet\n   }\n   \n   func eat(){\n       print(\"\\(name) is eating\")\n   }\n   \n   func sleep(){\n       print(\"the chicken \\(name) is sleeping\") \n   }\n   \n   func run() throws->Void{\n       print(\"the chicken \\(name) is running\")\n   }\n}\n\n// como el pez no puede correr mandamos un error por lo cual violamos este principio\n\n\nclass Fish:Animal{\n   let name:String\n   init(namePet:String){\n       name=namePet\n   }\n   \n   func eat(){\n       print(\"\\(name) is eating\")\n   }\n   \n   func sleep(){\n       print(\"the fish \\(name) is sleeping\") \n   }\n   \n   func run() throws->Void{\n      throw ErrorAnimal.IcannotRun(name: name)\n   }\n}\n\n\nlet chicken=Chicken(namePet:\"triki\")\nchicken.eat()\nchicken.sleep()\ntry chicken.run()\n\nlet fish=Fish(namePet:\"bandalo\")\nfish.eat()\nfish.sleep()\ndo{\n  try fish.run()\n}catch ErrorAnimal.IcannotRun(let name) {\n   print(\"the  fish \\(name) cannot run \")\n}\n\n// la forma  correcta de cumplir el principio\n\nprotocol Specie{\n  func eat()\n  func sleep()\n}\n\n// como la gallina si puede correr creamos una interfaz derivada de la original\n protocol EarthSpecie:Specie{\n     func run()\n }\n\n// ahora las clases quedan de la siguiente manera \n\nclass ChickenISP:EarthSpecie{\n   let name:String\n   init(namePet:String){\n       name=namePet\n   }\n   \n   func eat(){\n       print(\"\\(name) is eating\")\n   }\n   \n   func sleep(){\n       print(\"the chicken \\(name) is sleeping\") \n   }\n   \n   func run() {\n       print(\"the chicken \\(name) is running\")\n   }\n}\n\nclass FishISP:Specie{\n   let name:String\n   init(namePet:String){\n       name=namePet\n   }\n   \n   func eat(){\n       print(\"\\(name) is eating\")\n   }\n   \n   func sleep(){\n       print(\"the fish \\(name) is sleeping\") \n   }\n }\n\nlet chick=ChickenISP(namePet:\"blanquita\")\nchick.eat()\nchick.sleep()\nchick.run()\n\nlet fishing=FishISP(namePet:\"guason\")\nfishing.eat()\nfishing.sleep()\n\n// ejercicio extra\n\nenum Color{\n    case black_and_white\n    case color\n}\n\n// creamos una interfaz base de la cual haremos uns interface derivada \n\nprotocol Printer{\n    func print(_ document:String)->String\n}\n\n\nprotocol MultiFunctionPrinter:Printer{\n    func sendFax(_ fax:String)->String \n    func scanDocument(_ document:String)->String\n}\n\n\nstruct NormalPrinter:Printer{\n    let colorPrint:Color\n    \n    func print(_ document:String)->String{\n        return \"printing \\(document) in \\(colorPrint)\"\n    }\n}\n\n\nstruct MultifunPrinter:MultiFunctionPrinter{\n    let colorPrint:Color\n    \n    func sendFax(_ fax:String)->String{\n        return \"sending fax \\(fax)\"\n    }\n    \n    func scanDocument(_ document:String)->String{\n        return \"scan \\(document)\"\n    }\n    \n    func print(_ document:String)->String{\n        return \"printing \\(document) in \\(colorPrint)\"\n    }\n}\n\nfunc printingDocument(thermal:Printer,content:String){\n    print(thermal.print(content))\n}\n\n\n\nlet printer=NormalPrinter(colorPrint:.black_and_white)\nlet multi=MultifunPrinter(colorPrint:.color)\n\nprintingDocument(thermal:printer,content:\"Swift is great\")\nprintingDocument(thermal:multi,content:\"Swift is embebed\")\n\nprint(multi.sendFax(\"critical fail in system\"))\nprint(multi.scanDocument(\"WWDC2024 photos\"))\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/typescript/Sac-Corts.ts",
    "content": "// Wrong way\nclass Device {\n    turnOn(): void {}\n    turnOff(): void {}\n    charge(): void {}\n    connectToInternet(): void {}\n}\n\nclass Laptop extends Device {\n    turnOn(): void {\n        console.log(\"Laptop turned on\");\n    }\n\n    turnOff(): void {\n        console.log(\"Laptop turned off\");\n    }\n\n    charge(): void {\n        console.log(\"Laptop charging\");\n    }\n\n    connectToInternet(): void {\n        console.log(\"Laptop connected to the internet\");\n    }\n}\n\nclass Microwave extends Device {\n    turnOn(): void {\n        console.log(\"Microwave turned on\");\n    }\n\n    turnOff(): void {\n        console.log(\"Microwave turned off\");\n    }\n\n    charge(): void {\n        throw new Error(\"A microwave doesn't need to be charged\");\n    }\n\n    connectToInternet(): void {\n        throw new Error(\"A microwave doesn't need to be connected to the internet\");\n    }\n}\n\nconst microwave = new Microwave();\n// microwave.charge();  // Error\n\n// Correct way\nclass Switchable {\n    turnOn(): void {}\n    turnOff(): void {}\n}\n\nclass Chargeable {\n    charge(): void {}\n}\n\nclass InternetConnectable {\n    connectToInternet(): void {}\n}\n\nclass Laptop2 extends Switchable {\n    turnOn(): void {\n        console.log(\"Laptop turned on\");\n    }\n\n    turnOff(): void {\n        console.log(\"Laptop turned off\");\n    }\n}\n\nclass AdvancedLaptop extends Laptop2 implements Chargeable, InternetConnectable {\n    charge(): void {\n        console.log(\"Laptop charging.\");\n    }\n\n    connectToInternet(): void {\n        console.log(\"Laptop connected to the internet.\");\n    }\n}\n\nclass Microwave2 extends Switchable {\n    turnOn(): void {\n        console.log(\"Microwave turned on\");\n    }\n\n    turnOff(): void {\n        console.log(\"Microwave turned off\");\n    }\n}\n\nconst laptop2 = new AdvancedLaptop();\nlaptop2.charge();\nlaptop2.connectToInternet();\n\nconst microwave2 = new Microwave2();\nmicrowave2.turnOn();\nmicrowave2.turnOff();\n\n// Extra Exercise //\nclass BlackAndWhitePrintable {\n    printBlackAndWhite(): void {}\n}\n\nclass ColorPrintable {\n    printColor(): void {}\n}\n\nclass Scannable {\n    scan(): void {}\n}\n\nclass Faxable {\n    sendFax(): void {}\n}\n\nclass BlackAndWhitePrinter extends BlackAndWhitePrintable {\n    printBlackAndWhite(): void {\n        console.log(\"Printing in black and white...\");\n    }\n}\n\nclass ColorPrinter extends ColorPrintable {\n    printColor(): void {\n        console.log(\"Printing in color...\");\n    }\n}\n\nclass MultiFunctionPrinter extends BlackAndWhitePrintable implements ColorPrintable, Scannable, Faxable {\n    printBlackAndWhite(): void {\n        console.log(\"Printing in black and white...\");\n    }\n\n    printColor(): void {\n        console.log(\"Printing in color...\");\n    }\n\n    scan(): void {\n        console.log(\"Scanning...\");\n    }\n\n    sendFax(): void {\n        console.log(\"Sending fax...\");\n    }\n}\n\nconst blackAndWhitePrinter = new BlackAndWhitePrinter();\nblackAndWhitePrinter.printBlackAndWhite();\n\nconst colorPrinter = new ColorPrinter();\ncolorPrinter.printColor();\n\nconst multiFunctionPrinter = new MultiFunctionPrinter();\nmultiFunctionPrinter.printBlackAndWhite();\nmultiFunctionPrinter.printColor();\nmultiFunctionPrinter.scan();\nmultiFunctionPrinter.sendFax();\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/typescript/duendeintemporal.ts",
    "content": "//#29 { retosparaprogramadores } - Principio SOLID de Segregación de Interfaces (Interface Segregation Principle (ISP))\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Segregación de Interfaces (Interface Segregation Principle, ISP)\", y crea un ejemplo\n * simple donde se muestre su funcionamiento de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un gestor de impresoras.\n * Requisitos:\n * 1. Algunas impresoras sólo imprimen en blanco y negro.\n * 2. Otras sólo a color.\n * 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n * Instrucciones:\n * 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n * 2. Aplica el ISP a la implementación.\n * 3. Desarrolla un código que compruebe que se cumple el principio.\n */\n//Bibliografy: The Web Development Glossary (Jens Oliver Meiert) (Z-Library)\n//GPT\n\n/* Interface Segregation Principle\nThe principle that no client should be forced to depend on methods it does\nnot use. ISP splits interfaces that are very large into smaller and more\nspecific ones so that clients will only have to know about the methods that\nare of interest to them. Such shrunken interfaces are also called role\ninterfaces. ISP is intended to keep a system decoupled and thus easier to\nrefactor, change, and redeploy.  */\n\nlet log = console.log;\n\n// Check if running in a browser environment\nconst isBrowser = typeof window !== 'undefined';\n\n// Conditional check for browser environment\nif (isBrowser) {\n    window.addEventListener('load', () => {\n        const body: HTMLBodyElement | null = document.querySelector('body');\n        const title = document.createElement('h1');\n\n        body?.style.setProperty('background', '#000');\n        body?.style.setProperty('text-align', 'center');\n\n        title.textContent = 'Retosparaprogramadores #29.';\n        title.style.setProperty('font-size', '3.5vmax');\n        title.style.setProperty('color', '#fff');\n        title.style.setProperty('line-height', '100vh');\n\n        body?.appendChild(title);\n\n        setTimeout(() => {\n            alert('Retosparaprogramadores #29. Please open the Browser Developer Tools.');\n        }, 2000);\n        log('Retosparaprogramadores #29');\n    });\n} else {\n    log('This code is designed to run in a browser environment. Skipping window-related code.');\n    log('Retosparaprogramadores #29');\n}\n\n// Incorrect Example\nclass PaymentService {\n    processCreditCardPayment(amount: number): void {}\n    processPayPalPayment(amount: number): void {}\n    processBitcoinPayment(amount: number): void {}\n}\n\nclass CreditCardPayment extends PaymentService {\n    processCreditCardPayment(amount: number): void {\n        log(`Processing credit card payment of ${amount}`);\n    }\n    \n    processPayPalPayment(amount: number): void {\n        throw new Error(\"This payment method does not support PayPal payments\");\n    }\n    \n    processBitcoinPayment(amount: number): void {\n        throw new Error(\"This payment method does not support Bitcoin payments\");\n    }\n}\n\nclass PayPalPayment extends PaymentService {\n    processCreditCardPayment(amount: number): void {\n        throw new Error(\"This payment method does not support credit card payments\");\n    }\n    \n    processPayPalPayment(amount: number): void {\n        log(`Processing PayPal payment of ${amount}`);\n    }\n    \n    processBitcoinPayment(amount: number): void {\n        throw new Error(\"This payment method does not support Bitcoin payments\");\n    }\n}\n\nclass BitcoinPayment extends PaymentService {\n    processCreditCardPayment(amount: number): void {\n        throw new Error(\"This payment method does not support credit card payments\");\n    }\n    \n    processPayPalPayment(amount: number): void {\n        throw new Error(\"This payment method does not support PayPal payments\");\n    }\n    \n    processBitcoinPayment(amount: number): void {\n        log(`Processing Bitcoin payment of ${amount}`);\n    }\n}\n\n\nconst creditCardPayment = new CreditCardPayment();\ncreditCardPayment.processCreditCardPayment(250); // Processing credit card payment of 250\n//creditCardPayment.processPayPalPayment(87); // This will throw an error\n//Error: This payment method does not support PayPal payments at CreditCardPayment.processPayPalPayment\n\n// Correct Example\nclass CreditCardPaymentService {\n    processCreditCardPayment(amount: number): void {\n        log(`Processing credit card payment of ${amount}`);\n    }\n}\n\nclass PayPalPaymentService {\n    processPayPalPayment(amount: number): void {\n        log(`Processing PayPal payment of ${amount}`);\n    }\n}\n\nclass BitcoinPaymentService {\n    processBitcoinPayment(amount: number): void {\n        log(`Processing Bitcoin payment of ${amount}`);\n    }\n}\n\n\nconst creditCardPayment1 = new CreditCardPaymentService();\ncreditCardPayment1.processCreditCardPayment(400); // Processing credit card payment of 400\n\nconst payPalPayment = new PayPalPaymentService();\npayPalPayment.processPayPalPayment(130); // Processing PayPal payment of 130\n\nconst bitcoinPayment = new BitcoinPaymentService();\nbitcoinPayment.processBitcoinPayment(0.020); // Processing Bitcoin payment of 0.02\n\n\n//Extra Dificulty Exercise\n\nclass BlackAndWhitePrinter{\n    print(doc: string): void{\n        log(`Printing: ${doc} in Black & White`);\n    }\n}\n\nclass ColorPrinter{\n    print(doc: string): void{\n        log(`Printing: ${doc} in Color`);\n    }\n}\n\nclass MultiFunctionPrinter{\n\n    printInBlackAndWhite(doc: string): void{\n        log(`Printing: ${doc} in Black & White`);\n    }\n\n    print(doc: string): void{\n        log(`Printing: ${doc} in Color`);\n    }\n\n    fax(doc: string): void{\n        log(`Faxing: ${doc}`);\n    }\n\n    scan(doc: string): void{\n        log(`Scanning: ${doc}`);\n    }\n}\n\nlet book = 'vuelointemporal.odt';\n\nconst bw_printer = new BlackAndWhitePrinter();\nbw_printer.print(book); // Printing: vuelointemporal.odt in Black & White\n\nconst c_printer = new ColorPrinter();\nc_printer.print(book); // vuelointemporal.odt in Color\n\nconst m_printer = new MultiFunctionPrinter();\nm_printer.printInBlackAndWhite(book); // vuelointemporal.odt in Black & White\nm_printer.print(book); // Printing: vuelointemporal.odt in Color\nm_printer.fax(book); // Faxing: vuelointemporal.odt\nm_printer.scan(book); // Scanning: vuelointemporal.odt"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/typescript/hozlucas28.ts",
    "content": "/*\n    Interface Segregation Principle (ISP)...\n*/\n\nconsole.log('Interface Segregation Principle (ISP)...')\n\ninterface IBadAnimal {\n    fly: () => void\n    run: () => void\n    swim: () => void\n}\n\nclass BadDog implements IBadAnimal {\n    fly(): void {\n        throw new Error('A dog can not fly')\n    }\n\n    run(): void {\n        console.log('The dog is running!')\n    }\n\n    swim(): void {\n        console.log('The dog is swimming!')\n    }\n}\n\nclass BadDuck implements IBadAnimal {\n    fly(): void {\n        console.log('The duck is flying!')\n    }\n\n    run(): void {\n        console.log('The duck is running!')\n    }\n\n    swim(): void {\n        console.log('The duck is swimming!')\n    }\n}\n\nconsole.log('\\nBad implementation of Interface Segregation Principle (ISP)...')\n\nconsole.log(`\\n\\`\\`\\`\\ninterface IBadAnimal {\n    fly: () => void\n    run: () => void\n    swim: () => void\n}\n\nclass BadDog implements IBadAnimal {\n    fly(): void {\n        throw new Error('A dog can not fly')\n    }\n\n    run(): void {\n        console.log('The dog is running!')\n    }\n\n    swim(): void {\n        console.log('The dog is swimming!')\n    }\n}\n\nclass BadDuck implements IBadAnimal {\n    fly(): void {\n        console.log('The duck is flying!')\n    }\n\n    run(): void {\n        console.log('The duck is running!')\n    }\n\n    swim(): void {\n        console.log('The duck is swimming!')\n    }\n}\\n\\`\\`\\``)\n\nconsole.log(\n    '\\nThis is a bad implementation of Interface Segregation Principle (ISP),\\n' +\n        'because the \"BadDog\" class should not implement an interface with methods\\n' +\n        'that it is going to never use. So, the implemented interface (\"IBadAnimal\")\\n' +\n        'is to general for the \"BadDog\" class, but perfect for the \"BadDuck\" class.'\n)\n\nconsole.log('\\nGood implementation of Interface Segregation Principle (ISP)...')\n\ninterface IAerialAnimal {\n    fly: () => void\n}\n\ninterface IAquaticAnimal {\n    swim: () => void\n}\n\ninterface ITerrestrialAnimal {\n    run: () => void\n}\n\nclass GoodDog implements ITerrestrialAnimal, IAquaticAnimal {\n    run(): void {\n        console.log('The dog is running!')\n    }\n\n    swim(): void {\n        console.log('The dog is swimming!')\n    }\n}\n\nclass GoodDuck implements IAerialAnimal, IAquaticAnimal, ITerrestrialAnimal {\n    fly(): void {\n        console.log('The duck is flying!')\n    }\n\n    run(): void {\n        console.log('The duck is running!')\n    }\n\n    swim(): void {\n        console.log('The duck is swimming!')\n    }\n}\n\nconsole.log(`\\n\\`\\`\\`\\ninterface IAerialAnimal {\n    fly: () => void\n}\n\ninterface IAquaticAnimal {\n    swim: () => void\n}\n\ninterface ITerrestrialAnimal {\n    run: () => void\n}\n\nclass GoodDog implements ITerrestrialAnimal, IAquaticAnimal {\n    run(): void {\n        console.log('The dog is running!')\n    }\n\n    swim(): void {\n        console.log('The dog is swimming!')\n    }\n}\n\nclass GoodDuck implements IAerialAnimal, IAquaticAnimal, ITerrestrialAnimal {\n    fly(): void {\n        console.log('The duck is flying!')\n    }\n\n    run(): void {\n        console.log('The duck is running!')\n    }\n\n    swim(): void {\n        console.log('The duck is swimming!')\n    }\n}\\n\\`\\`\\``)\n\nconsole.log(\n    '\\nThis is a good implementation of Interface Segregation Principle (ISP),\\n' +\n        'because the \"GoodDog\" class only implements the necessary methods, without\\n' +\n        'any extras. Also, the \"GoodDuck\" class utilizes an interface perfectly suited\\n' +\n        'to its needs, with no extra methods.'\n)\n\nconsole.log(\n    '\\n# ---------------------------------------------------------------------------------- #\\n'\n)\n\n/*\n    Additional challenge...\n*/\n\nconsole.log('Additional challenge...')\n\ninterface IBlackAndWhitePrinter {\n    print: () => void\n}\n\nclass BlackAndWhitePrinter implements IBlackAndWhitePrinter {\n    constructor() {}\n\n    print(): void {\n        console.log('Paper printed in black and white!')\n    }\n}\n\ninterface IColorPrinter {\n    print: () => void\n}\n\nclass ColorPrinter implements IColorPrinter {\n    constructor() {}\n\n    print(): void {\n        console.log('Paper printed in color!')\n    }\n}\n\ninterface IMultifunctionalPrinter extends IBlackAndWhitePrinter, IColorPrinter {\n    scan: () => void\n    sendFax: () => void\n}\n\nclass MultifunctionalPrinter implements IMultifunctionalPrinter {\n    constructor() {}\n\n    print(): void {\n        console.log('Paper printed!')\n    }\n\n    scan(): void {\n        console.log('Scan completed!')\n    }\n\n    sendFax(): void {\n        console.log('Fax sent!')\n    }\n}\n\nconst blackAndWhitePrinter: BlackAndWhitePrinter = new BlackAndWhitePrinter()\nconst colorPrinter: ColorPrinter = new ColorPrinter()\nconst multifunctionalPrinter: MultifunctionalPrinter =\n    new MultifunctionalPrinter()\n\nconsole.log()\nblackAndWhitePrinter.print()\n\nconsole.log()\ncolorPrinter.print()\n\nconsole.log()\nmultifunctionalPrinter.print()\n\nconsole.log()\nmultifunctionalPrinter.scan()\n\nconsole.log()\nmultifunctionalPrinter.sendFax()\n"
  },
  {
    "path": "Roadmap/29 - SOLID ISP/vb.net/kenysdev.vb",
    "content": "' ╔══════════════════════════════════════╗\n' ║ Autor:  Kenys Alvarado               ║\n' ║ GitHub: https://github.com/Kenysdev  ║\n' ║ 2024 -  VB.NET                       ║\n' ╚══════════════════════════════════════╝\n'-----------------------------------------------------\n'* SOLID: PRINCIPIO DE SEGREGACIÓN DE INTERFACES (ISP)\n'-----------------------------------------------------\n' - Una clase no debería estar obligada a implementar interfaces que no utiliza.\n'   Evitando crear grandes clases monolíticas.\n\n'__________________________\n' NOTA: Este ejemplo muestra el uso CORRECTO. Para suponer un ejemplo que viole el principio, sería. \n'       Imaginar todos los métodos siguientes, en una sola interfaz, entonces algunos dispositivos\n'       implementarían una interfaz que no necesitan.\n\nPublic Interface IPlayable\n    Sub Play()\nEnd Interface\n\nPublic Interface IDisplayable\n    Sub Display()\nEnd Interface\n\n' ____________________________________________________\n' Implementar\nPublic Class Speaker\n    Implements IPlayable\n\n    Public Sub Play() Implements IPlayable.Play\n        Console.WriteLine(\"El altavoz está reproduciendo música.\")\n    End Sub\nEnd Class\n\nPublic Class Phone\n    Implements IPlayable, IDisplayable\n\n    Public Sub Play() Implements IPlayable.Play\n        Console.WriteLine(\"El teléfono está reproduciendo una canción.\")\n    End Sub\n\n    Public Sub Display() Implements IDisplayable.Display\n        Console.WriteLine(\"El teléfono está mostrando la pantalla de reproducción.\")\n    End Sub\nEnd Class\n\n'__________________________\n'* EJERCICIO\n'* Crea un gestor de impresoras.\n'* Requisitos:\n'* 1. Algunas impresoras sólo imprimen en blanco y negro.\n'* 2. Otras sólo a color.\n'* 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.\n'* Instrucciones:\n'* 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.\n'* 2. Aplica el ISP a la implementación.\n'* 3. Desarrolla un código que compruebe que se cumple el principio.\n\nPublic Interface IPrinter\n    Sub PrintFile(file As String)\nEnd Interface\n\nPublic Interface IScanner\n    Sub ToScan(pathSave As String)\nEnd Interface\n\nPublic Interface IFax\n    Sub SendFile(file As String, phoneNumber As Integer)\nEnd Interface\n\n' ____________________________________________________\n' Implementaciones\nPublic Class MonoPrinter\n    Implements IPrinter\n\n    Public Sub PrintFile(file As String) Implements IPrinter.PrintFile\n        Console.WriteLine(vbCrLf + \"Impresora blanco y negro:\")\n        Console.WriteLine(file + \" se imprimió.\")\n    End Sub\nEnd Class\n\nPublic Class ColorPrinter\n    Implements IPrinter\n\n    Public Sub PrintFile(file As String) Implements IPrinter.PrintFile\n        Console.WriteLine(vbCrLf + \"Impresora a color:\")\n        Console.WriteLine(file + \" se imprimió.\")\n    End Sub\nEnd Class\n\nPublic Class Scanner\n    Implements IScanner\n\n    Public Sub ToScan(pathSave As String) Implements IScanner.ToScan\n        Console.WriteLine(vbCrLf + \"Escaneo realizado, Guardado en: \" + pathSave)\n    End Sub\nEnd Class\n\nPublic Class Fax\n    Implements IFax\n\n    Public Sub SendFile(file As String, phoneNumber As Integer) Implements IFax.SendFile\n        Console.WriteLine(vbCrLf + $\"{file} Fue enviado a: {phoneNumber}\")\n    End Sub\nEnd Class\n\nPublic Class MultiFunctionPrinter\n    Public monoPrinter As New MonoPrinter\n    Public colorPrinter As New ColorPrinter\n    Public theScanner As New Scanner\n    Public fax As New Fax\nEnd Class\n\n' ____________________________________________________\nPublic Module Program\n    Public Sub Main()\n        ' Exs 1\n        Dim phone As New Phone()\n        phone.Play()\n        phone.Display()\n\n        Dim speaker As New Speaker()\n        speaker.Play()\n\n        '_____________________________________________\n        ' Exs 2\n        Console.WriteLine(vbCrLf + \"Exs #2\")\n\n        Dim MonoPrinter As New MonoPrinter\n        MonoPrinter.PrintFile(\"filex.pdf\")\n\n        Dim ColorPrinter As New ColorPrinter\n        ColorPrinter.PrintFile(\"filex.pdf\")\n\n        Dim theScanner As New Scanner\n        theScanner.ToScan(\"c:\\\\docs\")\n\n        Dim Fax As New Fax\n        Fax.SendFile(\"filex.pdf\", 12345678)\n\n        Console.WriteLine(vbCrLf + \"___________\" + vbCrLf + \"Multifunción\")\n\n        Dim MultiFunctionPrinter As New MultiFunctionPrinter\n        MultiFunctionPrinter.monoPrinter.PrintFile(\"filex.pdf\")\n        MultiFunctionPrinter.colorPrinter.PrintFile(\"filex.pdf\")\n        MultiFunctionPrinter.theScanner.ToScan(\"c:\\\\docs\")\n        MultiFunctionPrinter.fax.SendFile(\"filex.pdf\", 12345678)\n\n    End Sub\nEnd Module\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/bash/rantamhack.sh",
    "content": "#!/bin/bash\n\n# ESTE PRINCIPIO ESTABLECE DOS COSAS:\n# 1ª LOS MODULOS DE ALTO NIVEL NO PUEDEN DEPENDER DE LOS MODULOS DE BAJO NIVEL, LOS DOS DEBEN DEPENDER DE LAS ABSTRACCIONES\n# 2ª LAS ABSTRACCIONES NO PUEDEN DEPENDER DE LOS DETALLES SINO LOS DETALLES DE LAS ABSTRACCIONES\n\n\n\necho -e \"\\n\\n=======================================EJERCICIO=======================================\\n\\n\"\n\n\n#  * EJERCICIO:\n#  * Explora el \"Principio SOLID de Inversin de Dependencias (Dependency Inversion\n#  * Principle, DIP)\" y crea un ejemplo simple donde se muestre su funcionamiento \n#  * de forma correcta e incorrecta.\n\n# SIN DIP\n\n# function dictionary_chek_word(){\n#     local word=$1\n#     local dictionary=(\"hola\" \"mundo\" \"correcto\")\n#     for dict_word in \"${dictionary[@]}\"; do\n#         if [ \"$word\" == \"$dict_word\" ]; then\n#             echo \"La palabra $word está en el diccionario\"\n#             return\n#         fi\n#     done\n#     echo \"La palabra $word no está en el diccionario\"    \n# }\n            \n# function spell_correct(){\n#     local text=$1\n#     local words=\"($text)\"\n#     for word in \"${words[@]}\"; do\n#         dictionary_chek_word \"$word\"\n#     done        \n# }\n\n\n\n# CON DIP\n    \nfunction dictionary_check_word(){\n    local word=$1\n    local dictionary=(\"hola\" \"mundo\" \"correcto\")\n    for dict_word in \"${dictionary[@]}\"; do\n        if [ \"$word\" == \"$dict_word\" ];then\n            echo \"La palabra $word está en el diccionario\"\n            return\n        fi\n    done\n    echo \"La palabra $word no está en el diccionario\"\n}\n\nfunction online_service_check_word(){\n    local word=$1\n    local online_dictionary=(\"traductor\" \"online\" \"word\")\n    for dict_word in \"${online_dictionary[@]}\"; do\n        if [ \"$word\" == \"$dict_word\" ];then\n            echo \"La palabra está en el diccionario online\"\n            return\n        fi\n    done\n    echo \"Lapalabra no está en el diccionario online\"\n}\n\nfunction spell_correct(){\n    local checker_function=$1\n    local text=$2\n    local words=(\"$text\")\n    for word in \"${words[@]}\"; do\n        $checker_function \"$word\"\n    done\n}\n\n\n\necho -e \"\\n\\n=======================================DIFICULTAD EXTRA=======================================\\n\\n\"\n\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea un sistema de notificaciones.\n#  * Requisitos:\n#  * 1. El sistema puede enviar Email, PUSH y SMS (implementaciones especÃ­ficas).\n#  * 2. El sistema de notificaciones no puede depender de las implementaciones especÃ­ficas.\n#  * Instrucciones:\n#  * 1. Crea la interfaz o clase abstracta.\n#  * 2. Desarrolla las implementaciones especÃ­ficas.\n#  * 3. Crea el sistema de notificaciones usando el DIP.\n#  * 4. Desarrolla un cÃ³digo que compruebe que se cumple el principio.\n\n\nfunction send_email(){\n    local message=$1\n    echo \"Enviando por email el mensaje: $message\"\n}\n\nfunction send_PUSH(){\n    local message=$1\n    echo \"Enviando por PUSH el mensaje: $message\"\n}\n\nfunction send_SMS(){\n    local message=$1\n    echo -e \"Enviando por SMS el mensaje: $message\"\n}\n\nfunction send_notification(){\n    local send_method=$1\n    local message=$2\n    $send_method \"$message\"\n}\n        \nfunction notifier(){\n    local message=$1\n    echo \"1. Email\"\n    echo \"2. PUSH\"\n    echo \"3. SMS\"\n    read -p \"Elige una como quieres enviar el mensaje: \" option\n    \n    case $option in\n        1)\n            send_notification send_email \"$message\" \n            ;;\n        2)\n            send_notification send_PUSH \"$message\"\n            ;;\n        3)\n            send_notification send_SMS \"$message\"\n            ;;\n        *)\n            echo \"Opción no válida\"   \n            ;;\n    esac\n}\n    \n\n        \nnotifier \"Felices vacaciones!!\"\n\n    \n    \n    \n\n\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/c#/hequebo.cs",
    "content": "/*\n * El Principio de Inversión de Dependencia (DIP) nos dice\n * que la lógica debe de ser separada en módulos o servicios\n * que puedan ser reutilizados y si se deben de modificar\n * solo estos servicios se verán afectados. Los módulos de\n * alto nivel no deben depender de modulos de bajo nivel\n * si no de abstracciones\n */\n// Incorrecto \n/*\n * Creamos un servicio o módulo encargado de trar información\n * de un archivo en una ruta específica. Este servicio lo \n * usaremos dentro de otra clase\n */\nclass InfoFile\n{\n    private string _path;\n\n    public InfoFile(string path)\n    {\n        _path = path;\n    }\n    public void GetInfo() => Console.WriteLine($\"Se lee información de archivo en: {_path}...\");\n}\n/*\n * La clase Monitor Depende del servicio FileInfo \n * ya que utiliza la función GetInfo(), el principio\n * de Inversión de Dependencia se rompe ya que dentro\n * del módulo de nivel superior estamos creando una \n * instancia del módulo de nivel inferior, si este\n * módulo fuera a ser remplazado y ahora se leyera\n * la información de otra fuente se tendría que \n * buscar todas las partes del sistema donde se\n * tenga esta dependencia y modificarla\n */\nclass Monitor\n{\n    string _path;\n    public Monitor(string path) \n    {\n        _path = path;\n    }\n    public void GetInfo()\n    {\n        InfoFile infoFile = new InfoFile(_path);\n        infoFile.GetInfo();\n    }\n\n}\n// Correcto \n/*\n * Se crea una interfaz con el método que debe de ser\n * implementado por las clases\n */\ninterface IInfo\n{\n    public void GetInfo();\n}\n/*\n * Las siguientes clases implementan la interfaz\n * IInfo, una simula conectarse a una base de\n * datos mientras que la otra a un API\n */\nclass InfoDB : IInfo\n{\n    private string _connectionString;\n    public InfoDB(string connectionString)\n    {\n        _connectionString = connectionString;\n    }\n    public void GetInfo() => Console.WriteLine(\"Se realiza conexión a base de datos...\");\n}\nclass InfoHttp : IInfo\n{\n    private string _url;\n    public InfoHttp(string url)\n    {\n        _url = url;\n    }\n    public void GetInfo() => Console.WriteLine(\"Se realiza conexión a endpoint...\");\n}\nclass MonitorDIP\n{\n    private IInfo _info;\n\n    /*\n     * El servicio se obtiene ahora en el constructor ya creado\n     * en lugar de ser creado en la clase, El constructor espera\n     * recibir cualquier clase que implemente la interfaz IInfo\n     */\n    public MonitorDIP(IInfo info)\n    {\n        _info = info;\n    }\n    public void GetInfo() => _info.GetInfo();\n}\n\n// Ejercicio Extra\n\ninterface INotification\n{\n    public void Send();\n}\nclass EmailNotification : INotification\n{\n    private string _content;\n\n    public EmailNotification(string content)\n    {\n        _content = content;\n    }\n\n    public void Send() => Console.WriteLine(\"Se envía notificación a correo electrónico...\");\n}\nclass PushNotification : INotification\n{\n    private string _content;\n\n    public PushNotification(string content)\n    {\n        _content = content;\n    }\n\n    public void Send() => Console.WriteLine(\"Se envía notificación push...\");\n}\n\nclass SMSNotification : INotification\n{\n    private string _content;\n\n    public SMSNotification(string content)\n    {\n        _content = content;\n    }\n    public void Send() => Console.WriteLine(\"Se envía notificación por SMS...\");\n}\n\nclass NotificationSystem\n{\n    private INotification _notification;\n\n    public NotificationSystem(INotification notification)\n    {\n        _notification = notification;\n    }\n\n    public void Send() => _notification.Send();\n}\nclass Program\n{\n    static void Main(string[] args)\n    {\n        // Incorrecto\n        string path = \"info.txt\";\n        Monitor monitor = new Monitor(path);\n        monitor.GetInfo();\n\n        // Correcto\n        string connectionString = \"Data source=server; Initial Catalog=database;User=user; Password=password\";\n        InfoDB infoDB = new InfoDB(connectionString);\n        MonitorDIP monitorDB = new MonitorDIP(infoDB);\n        monitorDB.GetInfo();\n\n        string url = \"https://jsonplaceholder.typicode.com/posts\";\n        InfoHttp infoHttp = new InfoHttp(url);\n        MonitorDIP monitorHttp = new MonitorDIP(infoHttp);\n        monitorHttp.GetInfo();\n\n        // Ejercicio Extra\n        string content = \"Contenido de la notificación\";\n        EmailNotification emailNotification = new EmailNotification(content);\n        NotificationSystem notificationSystem = new NotificationSystem(emailNotification);\n        notificationSystem.Send();\n\n        PushNotification pushNotification = new PushNotification(content);\n        notificationSystem = new NotificationSystem(pushNotification);\n        notificationSystem.Send();\n\n        SMSNotification smsNotification = new SMSNotification(content);\n        notificationSystem = new NotificationSystem(smsNotification);\n        notificationSystem.Send();\n\n    }\n}"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/c#/kenysdev.cs",
    "content": "namespace exs30;\n/*\n╔══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado               ║\n║ GitHub: https://github.com/Kenysdev  ║\n║ 2024 -  C#                           ║\n╚══════════════════════════════════════╝\n-----------------------------------------------------\n* SOLID: PRINCIPIO DE INVERSIÓN DE DEPENDENCIAS (DIP)\n-----------------------------------------------------\n- Los módulos de alto nivel no deben depender de módulos de bajo nivel, sino de abstracciones. A su vez, las \n  abstracciones no deben depender de detalles concretos; los detalles deben depender de las abstracciones.\n\n___________________________________________________\n* EJERCICIO #1:\n* Explora el \"Principio SOLID de Inversión de Dependencias (Dependency Inversion\n* Principle, DIP)\" y crea un ejemplo simple donde se muestre su funcionamiento \n* de forma correcta e incorrecta.\n*/\n\n// ________________________________________________\n// De manera INCORRECTA:\n\npublic class Printer_\n{\n    public static void Print(string content)\n    {\n        Console.WriteLine(\"Impresión: \" + content);\n    }\n}\n\npublic class Report_\n{\n    public static void GenerateReport(string content)\n    {\n        Console.WriteLine(\"Generando informe, contenido: \" + content);\n\n        // Dependencia directa\n        Printer_.Print(content);\n    }\n}\n\n// ________________________________________________\n// De manera CORRECTA:\n\npublic interface IPrinter\n{\n     void Print(string content);\n}\n\npublic class Printer : IPrinter\n{\n    public void Print(string content)\n    {\n        Console.WriteLine(\"Impresión: \" + content);\n    }\n}\n\npublic class Report(IPrinter printer)\n{\n    // Ya no esta dependiendo de un modulo de bajo nivel.\n    private readonly IPrinter _printer = printer;\n\n    public void GenerateReport(string content)\n    {\n        Console.WriteLine(\"Generando informe, contenido: \" + content);\n        _printer.Print(content);\n    }\n}\n\n/*\n___________________________________________________\n* EJERCICIO #2:\n* Crea un sistema de notificaciones.\n* Requisitos:\n* 1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas).\n* 2. El sistema de notificaciones no puede depender de las implementaciones específicas.\n* Instrucciones:\n* 1. Crea la interfaz o clase abstracta.\n* 2. Desarrolla las implementaciones específicas.\n* 3. Crea el sistema de notificaciones usando el DIP.\n* 4. Desarrolla un código que compruebe que se cumple el principio.\n*/\n\npublic interface INotificationService\n{\n    void Send(object To, string Msg);\n}\n\n// Implementación\npublic class EmailService : INotificationService\n{\n    public void Send(object To, string Msg)\n    {\n        Console.WriteLine($\"Correo enviado a: {To}\");\n        Console.WriteLine($\"Mensaje: {Msg}\");\n    }\n}\n\n// Implementación\npublic class PUSHService : INotificationService\n{\n    public void Send(object To, string Msg)\n    {\n        Console.WriteLine($\"Notificación PUSH enviada a: {To}\");\n        Console.WriteLine($\"Mensaje: {Msg}\");\n    }\n}\n\n// Implementación\npublic class SMSService : INotificationService\n{\n    public void Send(object To, string Msg)\n    {\n        Console.WriteLine($\"Mensaje SMS enviado a: {To}\");\n        Console.WriteLine($\"Mensaje: {Msg}\");\n    }\n}\n\n// Clase de alto nivel\npublic class NotificationSystem(INotificationService Service)\n{\n    // Depende de la interfaz y no de implementaciones concretas.\n    private readonly INotificationService _Service = Service;\n\n    public void Notify(object To, string Msg)\n    {\n        _Service.Send(To, Msg);\n    }\n\n}\n\n// ________________________________________________\npublic class Program\n{\n    // Comprobación\n    public static void TestNotificationSystem(object To, string Msg, INotificationService Service)\n    {\n        // Inyeccion\n        NotificationSystem ServiceNotifer = new(Service);\n        ServiceNotifer.Notify(To, Msg);\n    }\n\n    public static void Main()\n    {\n        //________________________________\n        Console.WriteLine(\"EJERCICIO #1\");\n\n        // Imlementacion incorrecta\n        Report_.GenerateReport(\"Contenido x\");\n\n        // Imlementacion correcta\n        IPrinter printer = new Printer(); // Crear intancia\n        Report report = new(printer); // inyectar\n\n        report.GenerateReport(\"Contenido x\");\n\n        //________________________________\n        Console.WriteLine(\"\\nEJERCICIO #2\");\n\n        // Intancias de las implementaciones:\n        INotificationService emailService = new EmailService();\n        INotificationService pushService = new PUSHService();\n        INotificationService smsService = new SMSService();\n\n        // Pruebas\n        TestNotificationSystem(\"ejm@gg.com\", \"abcdsf\", emailService);\n        TestNotificationSystem(\"user01\", \"123456\", pushService);\n        TestNotificationSystem(123456789, \"aeiou\", smsService);\n    }\n}\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/c++/hectorio23.cpp",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n#include <iostream>\n#include <memory>\n#include <vector>\n\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Inversión de Dependencias (Dependency Inversion\n * Principle, DIP)\" y crea un ejemplo simple donde se muestre su funcionamiento \n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un sistema de notificaciones.\n * Requisitos:\n * 1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas).\n * 2. El sistema de notificaciones no puede depender de las implementaciones específicas.\n * Instrucciones:\n * 1. Crea la interfaz o clase abstracta.\n * 2. Desarrolla las implementaciones específicas.\n * 3. Crea el sistema de notificaciones usando el DIP.\n * 4. Desarrolla un código que compruebe que se cumple el principio.\n*/\n\n// Interfaz para el servicio de notificación\nclass NotificationService {\npublic:\n    virtual void sendNotification(const std::string& message) const = 0;\n    virtual ~NotificationService() = default;\n};\n\n// Implementación específica para Email\nclass EmailNotification : public NotificationService {\npublic:\n    void sendNotification(const std::string& message) const override {\n        std::cout << \"[+] - Enviando Email: \" << message << std::endl;\n    }\n};\n\n// Implementación específica para PUSH\nclass PushNotification : public NotificationService {\npublic:\n    void sendNotification(const std::string& message) const override {\n        std::cout << \"[+] - Enviando Push Notification: \" << message << std::endl;\n    }\n};\n\n// Implementación específica para SMS\nclass SMSNotification : public NotificationService {\npublic:\n    void sendNotification(const std::string& message) const override {\n        std::cout << \"[+] - Enviando SMS: \" << message << std::endl;\n    }\n};\n\n// Sistema de Notificaciones usando DIP\nclass NotificationSystem {\nprivate:\n    std::vector<std::shared_ptr<NotificationService>> services;\n\npublic:\n    void addService(const std::shared_ptr<NotificationService>& service) {\n        services.push_back(service);\n    }\n\n    void notifyAll(const std::string& message) const {\n        for (const auto& service : services) {\n            service->sendNotification(message);\n        }\n    }\n};\n\n// Función principal para demostrar el DIP\nint main() {\n    // Correcto: El sistema de notificaciones no depende directamente de las implementaciones concretas\n    std::shared_ptr<NotificationSystem> notificationSystem = std::make_shared<NotificationSystem>();\n\n    notificationSystem->addService(std::make_shared<EmailNotification>());\n    notificationSystem->addService(std::make_shared<PushNotification>());\n    notificationSystem->addService(std::make_shared<SMSNotification>());\n\n    notificationSystem->notifyAll(\"Mensaje de prueba.\");\n\n    // Incorrecto: Dependencia directa de las implementaciones concretas (violación del DIP)\n    EmailNotification emailNotification;\n    emailNotification.sendNotification(\"Mensaje directo sin sistema de notificaciones.\");\n\n    return 0;\n}\n\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/dart/EmilianoAngel.dart",
    "content": "// ignore_for_file: public_member_api_docs, sort_constructors_first\n// Incorrecto \n// class Button {\n//   void turnOn() {\n//     print('Enciende la lampara');\n//   }\n\n//   void turnOff() {\n//     print('Apaga la lampara');\n//   }\n// }\n\n// class Lamp {\n//   Button button = Button();\n\n//   void operate(String command) {\n//     if (command == 'on') {\n//       button.turnOn();\n//     } else if (command == 'off') {\n//       button.turnOff();\n//     }\n//   }\n// }\n\n// Correcto\n\nabstract class Switcher {\n  void turnOn();\n  void turnOff();\n}\n\nclass LampSwitch implements Switcher {\n  @override\n  void turnOn() {\n    print('Enciede la lampara');\n  }\n\n  @override\n  void turnOff() {\n    print('Apaga la lampara');\n  }\n}\n\nclass Lamp {\n  Switcher switcher;\n\n  Lamp(this.switcher);\n\n  void operate(String command) {\n    if (command == 'on') {\n      switcher.turnOn();\n    } else if (command == 'off') {\n      switcher.turnOff();\n    }\n  }\n}\n\n// Ejercicio sistema de notificaciones\n\nabstract class Notifier {\n  void send(String message);\n}\n\nclass EmailNotifier implements Notifier {\n  @override\n  void send(String message) {\n    print('Enviando email con text: $message');\n  }\n}\n\nclass PUSHNotifier implements Notifier {\n  @override\n  void send(String message) {\n    print('Enviando PUSH con text0: $message');\n  }\n}\n\nclass SMSNotifier implements Notifier {\n  @override\n  void send(String message) {\n    print('Enviando SMS con text0: $message');\n  }\n}\n\nclass NotificationService {\n  Notifier notifier;\n\n  NotificationService({\n    required this.notifier,\n  });\n\n  void notify(String message) {\n    notifier.send(message);\n  }\n}\n\nvoid main() {\n  // Lamp lamp = Lamp();\n  // lamp.operate('on');\n  // lamp.operate('off');\n\n  Lamp lamp = Lamp(LampSwitch());\n  lamp.operate('on');\n  lamp.operate('off');\n\n  // Ejercicio sistema de notificaciones\n  NotificationService service = NotificationService(notifier: SMSNotifier());\n\n  service.notify('Hola notificador');\n\n}"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/ejercicio.md",
    "content": "# #30 SOLID: PRINCIPIO DE INVERSIÓN DE DEPENDENCIAS (DIP)\n> #### Dificultad: Media | Publicación: 22/07/24 | Corrección: 29/07/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Inversión de Dependencias (Dependency Inversion\n * Principle, DIP)\" y crea un ejemplo simple donde se muestre su funcionamiento \n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un sistema de notificaciones.\n * Requisitos:\n * 1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas).\n * 2. El sistema de notificaciones no puede depender de las implementaciones específicas.\n * Instrucciones:\n * 1. Crea la interfaz o clase abstracta.\n * 2. Desarrolla las implementaciones específicas.\n * 3. Crea el sistema de notificaciones usando el DIP.\n * 4. Desarrolla un código que compruebe que se cumple el principio.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/30 - SOLID DIP/go/hozlucas28.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n)\n\n/* -------------------------------------------------------------------------- */\n/*                                 INTERFACES                                 */\n/* -------------------------------------------------------------------------- */\n\ntype CreditCardPayment interface {\n\tProcess()\n}\n\ntype BadPaymentProcessor interface {\n\tProcess()\n}\n\ntype PayPalPayment interface {\n\tProcess()\n}\n\ntype PaymentMethod interface {\n\tProcess()\n}\n\ntype GoodPaymentProcessor interface {\n\tProcess()\n}\n\ntype NotificationService interface {\n\tSend()\n}\n\ntype NotificationSystem interface {\n\tSendNotification()\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                   CLASSES                                  */\n/* -------------------------------------------------------------------------- */\n\n/* ---------------------------- CreditCardPayment --------------------------- */\n\ntype creditCardPayment struct{}\n\nfunc NewCreditCardPayment() CreditCardPayment {\n\tvar creditCardPayment creditCardPayment = creditCardPayment{}\n\treturn &creditCardPayment\n}\n\nfunc (creditCardPayment *creditCardPayment) Process() {\n\tfmt.Println(\"Credit card payment processed!\")\n}\n\n/* --------------------------- BadPaymentProcessor -------------------------- */\n\ntype badPaymentProcessor struct {\n\tmethod creditCardPayment\n\t_      struct{}\n}\n\nfunc NewBadPaymentProcessor() BadPaymentProcessor {\n\tvar paymentProcessor badPaymentProcessor = badPaymentProcessor{\n\t\tmethod: creditCardPayment{},\n\t}\n\n\treturn &paymentProcessor\n}\n\nfunc (paymentProcessor *badPaymentProcessor) Process() {\n\tpaymentProcessor.method.Process()\n}\n\n/* ------------------------------ PayPalPayment ----------------------------- */\n\ntype payPalPayment struct{}\n\nfunc NewPayPalPayment() PayPalPayment {\n\tvar payPalPayment payPalPayment = payPalPayment{}\n\treturn &payPalPayment\n}\n\nfunc (payPalPayment *payPalPayment) Process() {\n\tfmt.Println(\"PayPal payment processed!\")\n}\n\n/* -------------------------- GoodPaymentProcessor -------------------------- */\n\ntype goodPaymentProcessor struct {\n\tmethod PaymentMethod\n\t_      struct{}\n}\n\nfunc NewGoodPaymentProcessor(method PaymentMethod) GoodPaymentProcessor {\n\tvar paymentProcessor goodPaymentProcessor = goodPaymentProcessor{\n\t\tmethod: method,\n\t}\n\n\treturn &paymentProcessor\n}\n\nfunc (paymentProcessor *goodPaymentProcessor) Process() {\n\tpaymentProcessor.method.Process()\n}\n\n/* ------------------------------ EmailService ------------------------------ */\n\ntype emailService struct{}\n\nfunc NewEmailService() NotificationService {\n\tvar emailService emailService = emailService{}\n\treturn &emailService\n}\n\nfunc (emailService *emailService) Send() {\n\tfmt.Println(\"Email sent!\")\n}\n\n/* ------------------------------- PushService ------------------------------ */\n\ntype pushService struct{}\n\nfunc NewPushService() NotificationService {\n\tvar pushService pushService = pushService{}\n\treturn &pushService\n}\n\nfunc (pushService *pushService) Send() {\n\tfmt.Println(\"Push sent!\")\n}\n\n/* ------------------------------- SMSService ------------------------------- */\n\ntype smsService struct{}\n\nfunc NewSMSService() NotificationService {\n\tvar smsService smsService = smsService{}\n\treturn &smsService\n}\n\nfunc (smsService *smsService) Send() {\n\tfmt.Println(\"SMS sent!\")\n}\n\n/* --------------------------- NotificationService -------------------------- */\n\ntype notificationSystem struct {\n\tnotificationService NotificationService\n}\n\nfunc NewNotificationSystem(notificationService NotificationService) NotificationSystem {\n\tvar notificationSystem notificationSystem = notificationSystem{notificationService: notificationService}\n\treturn &notificationSystem\n}\n\nfunc (notificationSystem *notificationSystem) SendNotification() {\n\tnotificationSystem.notificationService.Send()\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\nfunc main() {\n\t/*\n\t\tDependency Inversion Principle (DIP)...\n\t*/\n\n\tfmt.Println(\"Dependency Inversion Principle (DIP)...\")\n\n\tfmt.Println(\"\\nBad implementation of Dependency Inversion Principle (DIP)...\")\n\n\tfmt.Println(\"\\n```\\n\" + `type CreditCardPayment interface {\n  Process()\n}\n\ntype BadPaymentProcessor interface {\n  Process()\n}\n\ntype creditCardPayment struct{}\n\nfunc NewCreditCardPayment() CreditCardPayment {\n  var creditCardPayment creditCardPayment = creditCardPayment{}\n  return &creditCardPayment\n}\n\nfunc (creditCardPayment *creditCardPayment) Process() {\n  fmt.Println(\"Credit card payment processed!\")\n}\n\ntype badPaymentProcessor struct {\n  method creditCardPayment\n  _      struct{}\n}\n\nfunc NewBadPaymentProcessor() BadPaymentProcessor {\n  var paymentProcessor badPaymentProcessor = badPaymentProcessor{\n    method: creditCardPayment{},\n  }\n\n  return &paymentProcessor\n}\n\nfunc (paymentProcessor *badPaymentProcessor) Process() {\n  paymentProcessor.method.Process()\n}` + \"\\n```\")\n\n\tfmt.Println(\n\t\t\"\\nThis is a bad implementation of Dependency Inversion Principle (DIP),\\n\" +\n\t\t\t\"'badPaymentProcessor' class depends directly on the 'creditCardPayment' class\\n\" +\n\t\t\t\"rather than on an interface. So, if the 'method' attribute in the 'badPaymentProcessor'\\n\" +\n\t\t\t\"class needs to be changed, the constructor ('NewBadPaymentProcessor') must also be modified.\",\n\t)\n\n\tfmt.Println(\"\\nGood implementation of Dependency Inversion Principle (DIP)...\")\n\n\tfmt.Println(\"\\n```\\n\" + `type CreditCardPayment interface {\n  Process()\n}\n\ntype PayPalPayment interface {\n  Process()\n}\n\ntype PaymentMethod interface {\n  Process()\n}\n\ntype GoodPaymentProcessor interface {\n  Process()\n}\n\ntype creditCardPayment struct{}\n\nfunc NewCreditCardPayment() CreditCardPayment {\n  var creditCardPayment creditCardPayment = creditCardPayment{}\n  return &creditCardPayment\n}\n\nfunc (creditCardPayment *creditCardPayment) Process() {\n  fmt.Println(\"Credit card payment processed!\")\n}\n\ntype payPalPayment struct{}\n\nfunc NewPayPalPayment() PayPalPayment {\n  var payPalPayment payPalPayment = payPalPayment{}\n  return &payPalPayment\n}\n\nfunc (payPalPayment *payPalPayment) Process() {\n  fmt.Println(\"PayPal payment processed!\")\n}\n\ntype goodPaymentProcessor struct {\n  method PaymentMethod\n  _      struct{}\n}\n\nfunc NewGoodPaymentProcessor(method PaymentMethod) GoodPaymentProcessor {\n  var paymentProcessor goodPaymentProcessor = goodPaymentProcessor{\n    method: method,\n  }\n\n  return &paymentProcessor\n}\n\nfunc (paymentProcessor *goodPaymentProcessor) Process() {\n  paymentProcessor.method.Process()\n}` + \"\\n```\")\n\n\tfmt.Println(\n\t\t\"\\nThis is a good implementation of Dependency Inversion Principle (DIP),\\n\" +\n\t\t\t\"because 'goodPaymentProcessor' class depends solely on injected dependencies\\n\" +\n\t\t\t\"that implement the 'PaymentMethod' interface. So, if the 'method' attribute in\\n\" +\n\t\t\t\"the 'goodPaymentProcessor' class needs to be changed, the constructor does not\\n\" +\n\t\t\t\"require modification (only the class call needs to be updated). For example, I\\n\" +\n\t\t\t\"could inject inside the 'method' attribute an instance of 'creditCardPayment'\\n\" +\n\t\t\t\"or 'payPalPayment' classes.\",\n\t)\n\n\tfmt.Println(\n\t\t\"\\n# ---------------------------------------------------------------------------------- #\",\n\t)\n\n\t/*\n\t   Additional challenge...\n\t*/\n\n\tfmt.Println(\"\\nAdditional challenge...\")\n\n\tvar emailService NotificationService = NewEmailService()\n\tvar pushService NotificationService = NewPushService()\n\tvar smsService NotificationService = NewSMSService()\n\n\tvar emailNotificationSystem NotificationSystem = NewNotificationSystem(emailService)\n\tvar pushNotificationSystem NotificationSystem = NewNotificationSystem(pushService)\n\tvar smsNotificationSystem NotificationSystem = NewNotificationSystem(smsService)\n\n\tfmt.Println()\n\temailNotificationSystem.SendNotification()\n\n\tfmt.Println()\n\tpushNotificationSystem.SendNotification()\n\n\tfmt.Println()\n\tsmsNotificationSystem.SendNotification()\n}\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/go/raynerpv2022.go",
    "content": "/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Inversión de Dependencias (Dependency Inversion\n * Principle, DIP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un sistema de notificaciones.\n * Requisitos:\n * 1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas).\n * 2. El sistema de notificaciones no puede depender de las implementaciones específicas.\n * Instrucciones:\n * 1. Crea la interfaz o clase abstracta.\n * 2. Desarrolla las implementaciones específicas.\n * 3. Crea el sistema de notificaciones usando el DIP.\n * 4. Desarrolla un código que compruebe que se cumple el principio.\n */\n\npackage main\n\nimport \"fmt\"\n\n// DIP incorrecto, Suma depende de Calcular, si queremos implementar otra operacion debemos modificar  Calcular\ntype Suma struct{}\n\nfunc (s Suma) Execute(n1 int, n2 int) int {\n\treturn n1 + n2\n}\n\ntype calculator struct{}\n\nfunc (c calculator) Calcular(op string, n1 int, n2 int) {\n\tif op == \"suma\" {\n\t\ts := Suma{}\n\t\tfmt.Println(s.Execute(n1, n2))\n\t} else {\n\t\tfmt.Println(\"Operacion aun no implementada\")\n\t}\n}\n\n//  DIP Correcto\n\ntype VirtualOperation interface {\n\tExecute(x, y int) int\n}\n\ntype SUMA struct{}\ntype RESTA struct{}\n\nfunc (s SUMA) Execute(x, y int) int {\n\treturn x + y\n}\n\nfunc (r RESTA) Execute(x, y int) int {\n\treturn x - y\n}\n\ntype Calculadora struct{}\n\nfunc (c Calculadora) CALCULAR(op VirtualOperation, x, y int) {\n\tfmt.Println(op.Execute(x, y))\n}\n\n// EXTRA\ntype Virtualnotification interface {\n\tPrint(message string)\n}\n\ntype ScreenNotification struct{}\n\ntype LogNotification struct{}\n\ntype MOngoDbNotification struct{}\n\nfunc (sn ScreenNotification) Print(message string) {\n\tfmt.Println(\"Enviando mensaje por pantalla\")\n\tfmt.Println(message)\n}\n\nfunc (lg LogNotification) Print(message string) {\n\tfmt.Println(\"Enviando mensaje por Archivo Log\")\n\tfmt.Println(message)\n}\n\nfunc (db MOngoDbNotification) Print(message string) {\n\tfmt.Println(\"Enviando mensaje por Base de DAto\")\n\tfmt.Println(message)\n}\n\ntype VirtualNotification interface {\n\tSendNotification(buzon string) string\n}\ntype Email struct{}\ntype Push struct{}\ntype Sms struct{}\n\nfunc (e Email) SendNotification(buzon string) string {\n\treturn fmt.Sprintf(\"Notificacion %s enviada por Email \\n\", buzon)\n\n}\n\nfunc (p Push) SendNotification(buzon string) string {\n\treturn fmt.Sprintf(\"Notificacion %s enviada por Push \\n\", buzon)\n}\nfunc (s Sms) SendNotification(buzon string) string {\n\treturn fmt.Sprintf(\"Notificacion %s enviada por Sms \\n\", buzon)\n}\n\ntype MDeamon struct{}\n\nfunc (md MDeamon) Notificador(notificador VirtualNotification, typeNotificator Virtualnotification, message string) {\n\ttypeNotificator.Print(notificador.SendNotification(message))\n\n}\n\nfunc main() {\n\tfmt.Println(\"Reto 30, SOLID, inversion de dependencias\")\n\n\tc := calculator{}\n\tc.Calcular(\"suma\", 12, 34)\n\tc.Calcular(\"sdssd\", 12, 34)\n\n\tC := Calculadora{}\n\tr := RESTA{}\n\ts := SUMA{}\n\tC.CALCULAR(r, 23, 10)\n\tC.CALCULAR(s, 23, 10)\n\n\t// Extra\n\tn := MDeamon{}\n\tn.Notificador(Email{}, LogNotification{}, \"Cita mana en el SEPE\")\n\tn.Notificador(Sms{}, MOngoDbNotification{}, \" Botar Basura en el Tonel correcto\")\n\tn.Notificador(Push{}, ScreenNotification{}, \"TUV presione enter para confirmar\")\n\n}\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/java/AmadorQuispe.java",
    "content": "package com.amsoft.roadmap.example30;\n\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\n//El principio de inversión de dependencias indica que las clases de un sistema deben depender\n//de las abstracciones/interfaces y no de las implementaciones concretas\npublic class Example30 {\n    public static void main(String[] args) {\n        /*Viola DIP*/\n        UserRepository repository = new UserRepository();\n        UserService service = new UserService(repository);\n        System.out.println(service.getUsers());\n        System.out.println(service.getUser(\"Amador\"));\n        /*Cumple DIP*/\n        UserRepositoryInterface userRepository = new UserRepositoryImpl();\n        UserServiceDIP userService = new UserServiceDIP(userRepository);\n        System.out.println(userService.getUsers());\n        System.out.println(userService.getUser(\"Alex\"));\n        /*EXTRA*/\n        NotificationService notificationEmailService = new NotificationService(message -> {\n            System.out.println(\"Enviando mensaje por email: \" + message);\n        });\n        notificationEmailService.sendNotification(\"Hola como estas\");\n\n        NotificationService notificationSMSService = new NotificationService(message -> {\n            System.out.println(\"Enviando mensaje por SMS: \" + message);\n        });\n        notificationSMSService.sendNotification(\"Hola como estas SMS\");\n\n        NotificationService notificationPUSHService = new NotificationService(message -> {\n            System.out.println(\"Enviando mensaje por PUSH: \" + message);\n        });\n        notificationPUSHService.sendNotification(\"Hola como estas PUSH\");\n    }\n}\n/*Viola DIP*/\n/*\n* En el caso se viola el DIP porque la clase UserService tiene dependencia directa con UserRepository\n*\n* */\nclass UserRepository {\n    private final ArrayList<String> users = new ArrayList<>(Arrays.asList(\"Amador\",\"Alex\"));\n    public ArrayList<String> findAll() {\n        return users;\n    }\n\n    public String findByName(String name){\n        var user = users.stream().filter(u->u.equals(name)).findFirst();\n        return user.orElse(null);\n    }\n\n}\nclass UserService {\n    UserRepository userRepository;\n    UserService(UserRepository userRepository){\n        this.userRepository = userRepository;\n    }\n\n    public ArrayList<String> getUsers() {\n        return userRepository.findAll();\n    }\n\n    public String getUser(String name){\n        return userRepository.findByName(name);\n    }\n}\n\n/*Con DIP*/\n/*\n* Ahora UserService depende de una abstracción, por lo tanto, facilmente podemos cambiar la implementación\n* del repositorio implementando la interfaz\n* */\ninterface UserRepositoryInterface {\n    ArrayList<String> findAll();\n    String findByName(String name);\n}\nclass UserRepositoryImpl implements UserRepositoryInterface {\n    private final ArrayList<String> users = new ArrayList<>(Arrays.asList(\"Amador\",\"Alex\"));\n    @Override\n    public ArrayList<String> findAll() {\n        return users;\n    }\n\n    @Override\n    public String findByName(String name) {\n        var user = users.stream().filter(u->u.equals(name)).findFirst();\n        return user.orElse(null);\n    }\n}\nclass UserServiceDIP {\n    UserRepositoryInterface userRepository;\n    UserServiceDIP(UserRepositoryInterface userRepository){\n        this.userRepository = userRepository;\n    }\n\n    public ArrayList<String> getUsers() {\n        return userRepository.findAll();\n    }\n\n    public String getUser(String name){\n        return userRepository.findByName(name);\n    }\n}\n\n/*  EXTRA  */\ninterface Notifiable {\n    void sendNotification(String message);\n}\n\nclass NotificationService {\n    private final Notifiable notifiable;\n\n    public NotificationService(Notifiable notifiable) {\n        this.notifiable = notifiable;\n    }\n    public void sendNotification(String message){\n        this.notifiable.sendNotification(message);\n    }\n}"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/java/AnaLauDB.java",
    "content": "public class AnaLauDB {\n\n    // ==========================================================================\n    // IMPLEMENTACIÓN QUE CUMPLE EL PRINCIPIO DE INVERSIÓN DE DEPENDENCIAS (DIP)\n    // ==========================================================================\n\n    // 1. ABSTRACCIÓN DE ALTO NIVEL (INTERFAZ)\n    // ==========================================================================\n\n    // Interfaz que define el contrato para cualquier servicio de notificación\n    interface ServicioNotificacion {\n        boolean enviarNotificacion(String destinatario, String mensaje);\n\n        String getTipoNotificacion();\n\n        boolean validarDestinatario(String destinatario);\n    }\n\n    // ==========================================================================\n    // 2. IMPLEMENTACIONES ESPECÍFICAS (MÓDULOS DE BAJO NIVEL)\n    // ==========================================================================\n\n    // Implementación específica para Email\n    static class ServicioEmail implements ServicioNotificacion {\n        private String servidorSMTP;\n\n        public ServicioEmail(String servidorSMTP) {\n            this.servidorSMTP = servidorSMTP;\n        }\n\n        @Override\n        public boolean enviarNotificacion(String destinatario, String mensaje) {\n            if (!validarDestinatario(destinatario)) {\n                System.out.println(\"Error: Email inválido - \" + destinatario);\n                return false;\n            }\n\n            System.out.println(\"ENVIANDO EMAIL...\");\n            System.out.println(\"Servidor SMTP: \" + servidorSMTP);\n            System.out.println(\"Para: \" + destinatario);\n            System.out.println(\"Mensaje: \" + mensaje);\n\n            // Simular envío\n            try {\n                Thread.sleep(1000);\n            } catch (InterruptedException e) {\n                Thread.currentThread().interrupt();\n            }\n\n            System.out.println(\"Email enviado exitosamente\");\n            return true;\n        }\n\n        @Override\n        public String getTipoNotificacion() {\n            return \"EMAIL\";\n        }\n\n        @Override\n        public boolean validarDestinatario(String destinatario) {\n            return destinatario != null && destinatario.contains(\"@\") && destinatario.contains(\".\");\n        }\n    }\n\n    // Implementación específica para notificaciones PUSH\n    static class ServicioPush implements ServicioNotificacion {\n        private String appId;\n\n        public ServicioPush(String appId) {\n            this.appId = appId;\n        }\n\n        @Override\n        public boolean enviarNotificacion(String destinatario, String mensaje) {\n            if (!validarDestinatario(destinatario)) {\n                System.out.println(\"Error: Token de dispositivo inválido\");\n                return false;\n            }\n\n            System.out.println(\"ENVIANDO NOTIFICACIÓN PUSH...\");\n            System.out.println(\"App ID: \" + appId);\n            System.out.println(\"Token del dispositivo: \" + destinatario);\n            System.out.println(\"Mensaje: \" + mensaje);\n\n            // Simular envío\n            try {\n                Thread.sleep(500);\n            } catch (InterruptedException e) {\n                Thread.currentThread().interrupt();\n            }\n\n            System.out.println(\"Notificación PUSH enviada exitosamente\");\n            return true;\n        }\n\n        @Override\n        public String getTipoNotificacion() {\n            return \"PUSH\";\n        }\n\n        @Override\n        public boolean validarDestinatario(String destinatario) {\n            return destinatario != null && destinatario.length() >= 10;\n        }\n    }\n\n    // Implementación específica para SMS\n    static class ServicioSMS implements ServicioNotificacion {\n        private String proveedorSMS;\n        private String apiKey;\n\n        public ServicioSMS(String proveedorSMS, String apiKey) {\n            this.proveedorSMS = proveedorSMS;\n            this.apiKey = apiKey;\n        }\n\n        @Override\n        public boolean enviarNotificacion(String destinatario, String mensaje) {\n            if (!validarDestinatario(destinatario)) {\n                System.out.println(\"Error: Número de teléfono inválido - \" + destinatario);\n                return false;\n            }\n\n            System.out.println(\"ENVIANDO SMS...\");\n            System.out.println(\"Proveedor: \" + proveedorSMS);\n            System.out.println(\"A: \" + destinatario);\n            System.out.println(\"Mensaje: \" + mensaje);\n\n            // Simular envío\n            try {\n                Thread.sleep(800);\n            } catch (InterruptedException e) {\n                Thread.currentThread().interrupt();\n            }\n\n            System.out.println(\"SMS enviado exitosamente\");\n            return true;\n        }\n\n        @Override\n        public String getTipoNotificacion() {\n            return \"SMS\";\n        }\n\n        @Override\n        public boolean validarDestinatario(String destinatario) {\n            return destinatario != null && destinatario.matches(\"\\\\+?[0-9]{10,15}\");\n        }\n    }\n\n    // ==========================================================================\n    // 3. SISTEMA DE NOTIFICACIONES (MÓDULO DE ALTO NIVEL)\n    // ==========================================================================\n\n    // El sistema depende de la abstracción, NO de implementaciones concretas\n    static class SistemaNotificaciones {\n        private ServicioNotificacion servicioNotificacion;\n\n        // Inyección de dependencia a través del constructor\n        public SistemaNotificaciones(ServicioNotificacion servicioNotificacion) {\n            this.servicioNotificacion = servicioNotificacion;\n        }\n\n        // Método para cambiar el servicio en tiempo de ejecución\n        public void setServicioNotificacion(ServicioNotificacion servicioNotificacion) {\n            this.servicioNotificacion = servicioNotificacion;\n        }\n\n        // Método principal para enviar notificaciones\n        public boolean enviarNotificacion(String destinatario, String mensaje) {\n            System.out.println(\"\\n=== SISTEMA DE NOTIFICACIONES ===\");\n            System.out.println(\"Tipo de servicio: \" + servicioNotificacion.getTipoNotificacion());\n\n            return servicioNotificacion.enviarNotificacion(destinatario, mensaje);\n        }\n\n        // Método para enviar notificaciones múltiples\n        public void enviarNotificacionMultiple(String[] destinatarios, String mensaje) {\n            System.out.println(\"\\n=== ENVÍO MÚLTIPLE ===\");\n            System.out.println(\"Servicio: \" + servicioNotificacion.getTipoNotificacion());\n\n            int exitosos = 0;\n            for (String destinatario : destinatarios) {\n                if (servicioNotificacion.enviarNotificacion(destinatario, mensaje)) {\n                    exitosos++;\n                }\n            }\n\n            System.out.println(\"Resumen: \" + exitosos + \"/\" + destinatarios.length +\n                    \" notificaciones enviadas exitosamente\");\n        }\n\n        // Método para obtener información del servicio actual\n        public String getInformacionServicio() {\n            return \"Servicio actual: \" + servicioNotificacion.getTipoNotificacion();\n        }\n    }\n\n    // ==========================================================================\n    // 4. FACTORY PARA CREAR SERVICIOS (OPCIONAL)\n    // ==========================================================================\n\n    static class FactoryNotificaciones {\n\n        public static ServicioNotificacion crearServicioEmail(String servidor) {\n            return new ServicioEmail(servidor);\n        }\n\n        public static ServicioNotificacion crearServicioPush(String appId) {\n            return new ServicioPush(appId);\n        }\n\n        public static ServicioNotificacion crearServicioSMS(String proveedor, String apiKey) {\n            return new ServicioSMS(proveedor, apiKey);\n        }\n    }\n\n    // ==========================================================================\n    // 5. CÓDIGO DE VERIFICACIÓN DEL DIP\n    // ==========================================================================\n\n    public static void main(String[] args) {\n        System.out.println(\"=== DEMOSTRACIÓN DEL PRINCIPIO DE INVERSIÓN DE DEPENDENCIAS (DIP) ===\");\n\n        // 1. Crear servicios específicos\n        ServicioNotificacion servicioEmail = new ServicioEmail(\"smtp.gmail.com\");\n        ServicioNotificacion servicioPush = new ServicioPush(\"com.miapp.notificaciones\");\n        ServicioNotificacion servicioSMS = new ServicioSMS(\"Twilio\", \"sk_test_123456\");\n\n        // 2. Crear sistema de notificaciones con inyección de dependencia\n        SistemaNotificaciones sistema = new SistemaNotificaciones(servicioEmail);\n\n        System.out.println(\"\\n1. VERIFICANDO CUMPLIMIENTO DEL DIP:\");\n        System.out.println(\"- El SistemaNotificaciones depende de la interfaz ServicioNotificacion\");\n        System.out.println(\"- NO depende de implementaciones concretas\");\n        System.out.println(\"- Las implementaciones dependen de la abstracción\");\n        System.out.println(\"- Se puede cambiar el comportamiento sin modificar el sistema\");\n\n        // 3. Probar con diferentes implementaciones\n        System.out.println(\"\\n2. PROBANDO CON SERVICIO EMAIL:\");\n        sistema.enviarNotificacion(\"usuario@ejemplo.com\", \"Bienvenido a nuestro sistema\");\n\n        System.out.println(\"\\n3. CAMBIANDO A SERVICIO PUSH (sin modificar el sistema):\");\n        sistema.setServicioNotificacion(servicioPush);\n        sistema.enviarNotificacion(\"token_dispositivo_123456789\", \"Nueva actualización disponible\");\n\n        System.out.println(\"\\n4. CAMBIANDO A SERVICIO SMS:\");\n        sistema.setServicioNotificacion(servicioSMS);\n        sistema.enviarNotificacion(\"+1234567890\", \"Código de verificación: 123456\");\n\n        // 4. Demonstrar envío múltiple con diferentes servicios\n        String[] emailsDestino = { \"ana@ejemplo.com\", \"carlos@ejemplo.com\", \"email_invalido\" };\n        String[] telefonos = { \"+1234567890\", \"+0987654321\", \"telefono_invalido\" };\n        String[] tokens = { \"token_123\", \"token_456\", \"tk_789\" };\n\n        System.out.println(\"\\n5. ENVÍO MÚLTIPLE CON EMAIL:\");\n        sistema.setServicioNotificacion(servicioEmail);\n        sistema.enviarNotificacionMultiple(emailsDestino, \"Notificación masiva por email\");\n\n        System.out.println(\"\\n6. ENVÍO MÚLTIPLE CON SMS:\");\n        sistema.setServicioNotificacion(servicioSMS);\n        sistema.enviarNotificacionMultiple(telefonos, \"Notificación masiva por SMS\");\n\n        System.out.println(\"\\n7. ENVÍO MÚLTIPLE CON PUSH:\");\n        sistema.setServicioNotificacion(servicioPush);\n        sistema.enviarNotificacionMultiple(tokens, \"Notificación masiva PUSH\");\n\n        // 5. Demostrar uso del Factory\n        System.out.println(\"\\n8. USANDO FACTORY PARA CREAR SERVICIOS:\");\n        ServicioNotificacion emailFactory = FactoryNotificaciones.crearServicioEmail(\"smtp.outlook.com\");\n        sistema.setServicioNotificacion(emailFactory);\n        sistema.enviarNotificacion(\"test@outlook.com\", \"Mensaje desde factory\");\n\n        // 6. Verificar manejo de errores\n        System.out.println(\"\\n9. PROBANDO MANEJO DE ERRORES:\");\n        sistema.setServicioNotificacion(servicioEmail);\n        sistema.enviarNotificacion(\"email_sin_arroba\", \"Este email debería fallar\");\n\n        sistema.setServicioNotificacion(servicioSMS);\n        sistema.enviarNotificacion(\"123\", \"Este SMS debería fallar\");\n\n        System.out.println(\"\\n=== VERIFICACIÓN FINAL DEL DIP ===\");\n        System.out.println(\"CUMPLIMIENTO EXITOSO:\");\n        System.out.println(\"- Módulos de alto nivel no dependen de módulos de bajo nivel\");\n        System.out.println(\"- Ambos dependen de abstracciones\");\n        System.out.println(\"- Las abstracciones no dependen de detalles\");\n        System.out.println(\"- Los detalles dependen de abstracciones\");\n        System.out.println(\"- El sistema es extensible sin modificar código existente\");\n        System.out.println(\"- Se puede inyectar cualquier implementación de ServicioNotificacion\");\n\n        // Ejemplo de extensibilidad - agregar nuevo servicio sin modificar código\n        // existente\n        System.out.println(\"\\n10. DEMOSTRANDO EXTENSIBILIDAD:\");\n        ServicioNotificacion nuevoServicio = new ServicioNotificacion() {\n            @Override\n            public boolean enviarNotificacion(String destinatario, String mensaje) {\n                System.out.println(\"SLACK: Enviando a canal \" + destinatario + \": \" + mensaje);\n                return true;\n            }\n\n            @Override\n            public String getTipoNotificacion() {\n                return \"SLACK\";\n            }\n\n            @Override\n            public boolean validarDestinatario(String destinatario) {\n                return destinatario != null && destinatario.startsWith(\"#\");\n            }\n        };\n\n        sistema.setServicioNotificacion(nuevoServicio);\n        sistema.enviarNotificacion(\"#general\", \"Nuevo servicio agregado sin modificar código existente\");\n\n        System.out.println(\"\\nSISTEMA COMPLETAMENTE COMPATIBLE CON DIP\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/java/Josegs95.java",
    "content": "public class Josegs95 {\n    public static void main(String[] args) {\n        //Ejericio\n        //Forma incorrecta\n        WrongLaptop laptop1 = new WrongLaptop(new ExternalBattery());\n        laptop1.charge();\n\n        //Forma correcta\n        Laptop laptop2 = new Laptop(new ExternalBattery());\n        laptop2.charge();\n\n        laptop2 = new Laptop(new InternalBattery());\n        laptop2.charge();\n\n        //Reto\n        new Josegs95().retoFinal();\n    }\n\n    public void retoFinal(){\n        Notification notification = new Notification();\n        notification.sendNotification(\"Jose\", \"Hola\", new Email());\n        notification.sendNotification(\"Laura\", \"Buenas tardes\", new PUSH());\n        notification.sendNotification(\"Yolanda\", \"Adios\", new SMS());\n    }\n\n    //Forma incorrecta\n    public static class WrongLaptop {\n        private ExternalBattery battery;\n        public WrongLaptop(ExternalBattery battery){\n            this.battery = battery;\n        }\n\n        public void charge(){\n            battery.charge();\n        }\n    }\n    //Forma correcta\n    public interface Battery{\n        public void charge();\n    }\n    public static class ExternalBattery implements Battery{\n        @Override\n        public void charge(){\n            System.out.println(\"La batería se carga mediante un transformador\");\n        }\n    }\n    public static class InternalBattery implements Battery{\n\n        @Override\n        public void charge() {\n            System.out.println(\"La batería se carga sin necesidad de un transformador\");\n        }\n    }\n    public static class Laptop{\n        private Battery battery;\n\n        public Laptop(Battery battery){\n            this.battery = battery;\n        }\n\n        public void charge(){\n            battery.charge();\n        }\n    }\n    //Reto\n    public interface MessageSender{\n        public void send(String recipient, String text);\n    }\n    public class Email implements MessageSender{\n        @Override\n        public void send(String recipient, String text) {\n            System.out.println(\"\\\"\" + text + \"\\\" enviado por email a \" + recipient);\n        }\n    }\n    public class PUSH implements MessageSender{\n        @Override\n        public void send(String recipient, String text) {\n            System.out.println(\"\\\"\" + text + \"\\\" enviado por push a \" + recipient);\n        }\n    }\n    public class SMS implements MessageSender{\n        @Override\n        public void send(String recipient, String text) {\n            System.out.println(\"\\\"\" + text + \"\\\" enviado por SMS a \" + recipient);\n        }\n    }\n    public class Notification{\n        public void sendNotification(String recipient, String text, MessageSender sender){\n            sender.send(recipient, text);\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/java/asjordi.java",
    "content": "/*\n    El Principio de Inversión de Dependencia (DIP) establece que las clases de alto nivel no deben depender de clases de bajo nivel.\n    Es decir, se deben fabricar abstracciones mediante interfaces y clases abstractas para asegurarse de que dos módulos\n    que deben interactuar entre sí solo se comuniquen a través de estas mismas, y de esta manera para esconder sus implementaciones concretas.\n */\n\npublic class Main {\n\n    public static void main(String[] args) {\n        Email email = new Email();\n        Push push = new Push();\n        SMS sms = new SMS();\n\n        SistemaNotificaciones snEmail = new SistemaNotificaciones(email);\n        SistemaNotificaciones snPush = new SistemaNotificaciones(push);\n        SistemaNotificaciones snSMS = new SistemaNotificaciones(sms);\n\n        snEmail.n.notificar();\n        snPush.n.notificar();\n        snSMS.n.notificar();\n    }\n\n    // Ejemplo Incorrecto (Violación del DIP)\n    /*\n        Se tiene una clase Impresora que recibe una Factura, lo cual hace que la clase Impresora dependa de la clase Factura.\n        Esto viola el DIP, ya que la clase de alto nivel (Impresora) depende de una clase de bajo nivel (Factura).\n        En caso de que se quiera para una clase Carta o cualquier otro tipo de documento, se tendría que modificar la clase Impresora.\n     */\n    static class Factura {\n        // Atributos\n        // Constructor\n        // Métodos\n    }\n\n    static class Impresora {\n        Factura f;\n\n        public Impresora(Factura f) {\n            this.f = f;\n        }\n    }\n\n    // Ejemplo Correcto (Aplicación del DIP)\n    /*\n        Se tiene una interfaz Imprimible que define un método imprimir(), y una clase Impresora que recibe un objeto que implemente la interfaz Imprimible.\n        De esta forma, la clase Impresora no depende de una clase concreta, sino de una interfaz, lo cual cumple con el DIP.\n     */\n\n    interface Imprimible {\n        void imprimir();\n    }\n\n    static class FacturaDIP implements Imprimible {\n        // Atributos\n        // Constructor\n        // Métodos\n\n        @Override\n        public void imprimir() {\n            // Imprimir la factura\n        }\n    }\n\n    static class CartaDIP implements Imprimible {\n        // Atributos\n        // Constructor\n        // Métodos\n\n        @Override\n        public void imprimir() {\n            // Imprimir la carta\n        }\n    }\n\n    static class ImpresoraDIP {\n        Imprimible i;\n\n        public ImpresoraDIP(Imprimible i) {\n            this.i = i;\n        }\n    }\n\n    /*\n        DIFICULTAD EXTRA (opcional):\n        Crea un sistema de notificaciones.\n        Requisitos:\n            1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas).\n            2. El sistema de notificaciones no puede depender de las implementaciones específicas.\n        Instrucciones:\n            1. Crea la interfaz o clase abstracta.\n            2. Desarrolla las implementaciones específicas.\n            3. Crea el sistema de notificaciones usando el DIP.\n            4. Desarrolla un código que compruebe que se cumple el principio.\n     */\n\n    interface Notificable {\n        void notificar();\n    }\n\n    static class Email implements Notificable {\n        @Override\n        public void notificar() {\n            System.out.println(\"Enviando notificación por email\");\n        }\n    }\n\n    static class Push implements Notificable {\n        @Override\n        public void notificar() {\n            System.out.println(\"Enviando notificación por push\");\n        }\n    }\n\n    static class SMS implements Notificable {\n        @Override\n        public void notificar() {\n            System.out.println(\"Enviando notificación por SMS\");\n        }\n    }\n\n    static class SistemaNotificaciones {\n        Notificable n;\n\n        public SistemaNotificaciones(Notificable n) {\n            this.n = n;\n        }\n    }\n\n\n}\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/java/danhingar.java",
    "content": "public class danhingar {\n\n    public static void main(String[] args) {\n        Lamp lamp1 = new Lamp();\n        lamp1.operate(\"on\");\n        lamp1.operate(\"off\");\n\n        //Con DIP\n        Lamp1 lamp2 = new Lamp1(new LampSwitchInterface());\n        lamp2.operate(\"on\");\n        lamp2.operate(\"off\");\n\n        //Extra\n        NotificationManager manager1 = new NotificationManager(new EmailNotifier());\n        manager1.notify(\"Hello\");\n\n        NotificationManager manager2 = new NotificationManager(new PushNotifier());\n        manager2.notify(\"Hello\");\n\n        NotificationManager manager3 = new NotificationManager(new SMSNotifier());\n        manager3.notify(\"Hello\");\n    }\n\n}\n\n// SIN DIP\nclass Switch {\n\n    public void turnOn() {\n        System.out.println(\"Enciende la lámpara\");\n    }\n\n    public void turnOff() {\n        System.out.println(\"Apaga la lámpara\");\n    }\n\n}\n\nclass Lamp {\n\n    private Switch switch1;\n\n    public Lamp() {\n        this.switch1 = new Switch();\n    }\n\n    public void operate(String command) {\n        if (command.equals(\"on\")) {\n            switch1.turnOn();\n        } else if (command.equals(\"off\")) {\n            switch1.turnOff();\n        }\n    }\n\n}\n\n// CON DIP\ninterface SwitchInterface {\n    void turnOn();\n\n    void turnOff();\n}\n\nclass LampSwitchInterface implements SwitchInterface {\n\n    @Override\n    public void turnOn() {\n        System.out.println(\"Enciende la lámpara\");\n    }\n\n    @Override\n    public void turnOff() {\n        System.out.println(\"Apaga la lámpara\");\n    }\n\n}\n\nclass Lamp1 {\n\n    private SwitchInterface switchInterface;\n\n    public Lamp1(SwitchInterface switchInterface) {\n        this.switchInterface = switchInterface;\n    }\n\n    public void operate(String command) {\n        if (command.equals(\"on\")) {\n            switchInterface.turnOn();\n        } else if (command.equals(\"off\")) {\n            switchInterface.turnOff();\n        }\n    }\n    \n}\n\n\n//EXTRA\ninterface NotifierInterface{\n    void sendNotification(String msg);\n}\n\nclass EmailNotifier implements NotifierInterface{\n\n    @Override\n    public void sendNotification(String msg) {\n        System.out.printf(\"Enviando email con texto %s.\\n\",msg);\n    }\n\n}\n\nclass PushNotifier implements NotifierInterface{\n\n    @Override\n    public void sendNotification(String msg) {\n        System.out.printf(\"Enviando PUSH con texto %s.\\n\",msg);\n    }\n\n}\n\nclass SMSNotifier implements NotifierInterface{\n\n    @Override\n    public void sendNotification(String msg) {\n        System.out.printf(\"Enviando SMS con texto %s.\\n\",msg);\n    }\n}\n\nclass NotificationManager {\n\n    private NotifierInterface notifierInterface;\n\n    public NotificationManager(NotifierInterface notifierInterface) {\n        this.notifierInterface = notifierInterface;\n    }\n\n    public void notify(String msg){\n        notifierInterface.sendNotification(msg);\n    }\n    \n}"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/java/martinbohorquez.java",
    "content": "/**\n * #30 SOLID: PRINCIPIO DE INVERSIÓN DE DEPENDENCIAS (DIP)\n *\n * @author martinbohorquez\n */\npublic class martinbohorquez {\n    public static void main(String[] args) {\n        incorrectDIP();\n        correctDIP();\n        /*\n         * DIFICULTAD EXTRA\n         */\n        notificationDIP();\n    }\n\n    private static void incorrectDIP() {\n        Lampara lampara = new Lampara();\n        lampara.operate(\"on\");\n        lampara.operate(\"off\");\n    }\n\n    private static void correctDIP() {\n        Lamp lamp = new Lamp(new LampSwitch());\n        lamp.operate(\"on\");\n        lamp.operate(\"off\");\n    }\n\n    private static void notificationDIP() {\n        var service = new NotificationService(new EmailNotifier());\n        service.notify(\"Mensaje 1\");\n        service = new NotificationService(new PushNotifier());\n        service.notify(\"Mensaje 2\");\n        service = new NotificationService(new SmsNotifier());\n        service.notify(\"Mensaje 3\");\n    }\n}\n\nclass Interruptor {\n    protected void turnOn() {\n        System.out.println(\"Enciende la lámpara!\");\n    }\n\n    protected void turnOff() {\n        System.out.println(\"Apaga la lámpara!\");\n    }\n}\n\nclass Lampara {\n    private final Interruptor aSwitch;\n\n    public Lampara() {\n        aSwitch = new Interruptor();\n    }\n\n    protected void operate(String command) {\n        if (\"on\".equals(command)) aSwitch.turnOn();\n        else if (\"off\".equals(command)) aSwitch.turnOff();\n    }\n}\n\ninterface Switch {\n    void turnOn();\n\n    void turnOff();\n}\n\nclass LampSwitch implements Switch {\n    @Override\n    public void turnOn() {\n        System.out.println(\"Enciende la lámpara!\");\n    }\n\n    @Override\n    public void turnOff() {\n        System.out.println(\"Apaga la lámpara!\");\n    }\n}\n\nclass Lamp {\n    private final Switch aSwitch;\n\n    public Lamp(Switch aSwitch) {\n        this.aSwitch = aSwitch;\n    } // Desacoplar la clase para poder usar cualquier clase implementa Switch (ejem. LampSwitch)\n\n    protected void operate(String command) {\n        if (\"on\".equals(command)) aSwitch.turnOn();\n        else if (\"off\".equals(command)) aSwitch.turnOff();\n    }\n}\n\ninterface Notifier {\n    void send(String message);\n}\n\nclass EmailNotifier implements Notifier {\n    @Override\n    public void send(String message) {\n        System.out.printf(\"Enviando email con texto: %s%n\", message);\n    }\n}\n\nclass PushNotifier implements Notifier {\n    @Override\n    public void send(String message) {\n        System.out.printf(\"Enviando PUSH con texto: %s%n\", message);\n    }\n}\n\nclass SmsNotifier implements Notifier {\n    @Override\n    public void send(String message) {\n        System.out.printf(\"Enviando SMS con texto: %s%n\", message);\n    }\n}\n\nclass NotificationService {\n    private final Notifier notifier;\n\n    public NotificationService(Notifier notifier) {\n        this.notifier = notifier;\n    }\n\n    void notify(String message) {\n        notifier.send(message);\n    }\n}"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/java/simonguzman.java",
    "content": "public class simonguzman {\n    public static void main(String[] args) {\n        exampleDIP();\n        exampleNoDIP();\n        adittionalExerciseNoDIP();\n        adittionalExerciseDIP();\n    }\n    /*********************************** Ejercicio adicional con DIP ***********************************/\n    static void adittionalExerciseDIP(){\n        Notification emailNotification = new EmailNotification();\n        NotificationService emailService = new NotificationService(emailNotification);\n        emailService.sendNotification(\"Este es un email\");\n\n        Notification smsNotification = new SMSNotification();\n        NotificationService smsService = new NotificationService(smsNotification);\n        smsService.sendNotification(\"Este es un SMS\");\n\n        Notification pushNotification = new PushNotification();\n        NotificationService pushService = new NotificationService(pushNotification);\n        pushService.sendNotification(\"Esta es una notificación PUSH\");\n    }\n    static interface Notification {\n        void send(String message);\n    }\n    static class EmailNotification implements Notification {\n        @Override\n        public void send(String message) {\n            System.out.println(\"Enviando email con mensaje: \" + message);\n        }\n    }\n\n    static class SMSNotification implements Notification {\n        @Override\n        public void send(String message) {\n            System.out.println(\"Enviando SMS con mensaje: \" + message);\n        }\n    }\n\n    static class PushNotification implements Notification {\n        @Override\n        public void send(String message) {\n            System.out.println(\"Enviando notificación PUSH con mensaje: \" + message);\n        }\n    }\n\n    static class NotificationService {\n        private Notification notification;\n\n        public NotificationService(Notification notification) {\n            this.notification = notification;\n        }\n\n        public void sendNotification(String message) {\n            notification.send(message);\n        }\n    }\n    /*********************************** Ejercicio adicional sin DIP ***********************************/\n    static void adittionalExerciseNoDIP(){\n        NotificationServiceNoDIP service = new NotificationServiceNoDIP();\n        service.sendEmailNotification(\"Este es un email\");\n        service.sendSMSNotification(\"Este es un SMS\");\n    }\n    static class EmailNotificationNoDIP {\n        public void sendEmail(String message) {\n            System.out.println(\"Enviando email con mensaje: \" + message);\n        }\n    }\n\n    static class SMSNotificationNoDIP {\n        public void sendSMS(String message) {\n            System.out.println(\"Enviando SMS con mensaje: \" + message);\n        }\n    }\n\n    static class NotificationServiceNoDIP {\n        private EmailNotificationNoDIP emailNotification = new EmailNotificationNoDIP();\n        private SMSNotificationNoDIP smsNotification = new SMSNotificationNoDIP();\n\n        public void sendEmailNotification(String message) {\n            emailNotification.sendEmail(message);\n        }\n\n        public void sendSMSNotification(String message) {\n            smsNotification.sendSMS(message);\n        }\n    }\n\n    /*********************************** Ejemplo con DIP ***********************************/\n    static void exampleDIP(){\n        MessageSender emailSender = new EmailSenderDIP();\n        NotificationServiceDIP notificationService = new NotificationServiceDIP(emailSender);\n        notificationService.notifyUser(\"Tu cuenta ha sido activada.\");\n\n        MessageSender smsSender = new SMSSenderDIP();\n        notificationService = new NotificationServiceDIP(smsSender);\n        notificationService.notifyUser(\"Tu código de verificación es 1234.\");\n    }\n    static interface MessageSender {\n        void sendMessage(String message);\n    }\n\n    static class EmailSenderDIP implements MessageSender {\n        @Override\n        public void sendMessage(String message) {\n            System.out.println(\"Enviando email: \" + message);\n        }\n    }\n\n    static class SMSSenderDIP implements MessageSender {\n        @Override\n        public void sendMessage(String message) {\n            System.out.println(\"Enviando SMS: \" + message);\n        }\n    }\n\n    static class NotificationServiceDIP {\n        private MessageSender messageSender;\n\n        public NotificationServiceDIP(MessageSender messageSender) {\n            this.messageSender = messageSender;\n        }\n\n        public void notifyUser(String message) {\n            messageSender.sendMessage(message);\n        }\n    }\n\n    /*********************************** Ejemplo sin DIP ***********************************/\n    static void exampleNoDIP(){\n        NotificationServiceNotDIP notificationService = new NotificationServiceNotDIP();\n        notificationService.notifyUser(\"Tu cuenta ha sido activada.\");\n    }\n    static class EmailSender {\n        public void sendEmail(String message) {\n            System.out.println(\"Enviando email: \" + message);\n        }\n    }\n\n    static class NotificationServiceNotDIP {\n        private EmailSender emailSender = new EmailSender();  // Dependencia concreta\n\n        public void notifyUser(String message) {\n            emailSender.sendEmail(message);\n        }\n    }\n\n\n}\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/javascript/Chrisdev00.js",
    "content": "/*\n* EJERCICIO:\n* Explora el \"Principio SOLID de Inversión de Dependencias (Dependency Inversion\n* Principle, DIP)\" y crea un ejemplo simple donde se muestre su funcionamiento \n* de forma correcta e incorrecta.\n*\n* DIFICULTAD EXTRA (opcional):\n* Crea un sistema de notificaciones.\n* Requisitos:\n* 1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas).\n* 2. El sistema de notificaciones no puede depender de las implementaciones específicas.\n* Instrucciones:\n* 1. Crea la interfaz o clase abstracta.\n* 2. Desarrolla las implementaciones específicas.\n* 3. Crea el sistema de notificaciones usando el DIP.\n* 4. Desarrolla un código que compruebe que se cumple el principio.\n*/\n\n// Forma Incorrecta de aplicar el principio DIP\n\nclass Backend {\n    getData() {\n      return \"Datos del backend\";\n    }\n}\n\nclass Frontend {\n    constructor() {\n      this.backend = new Backend();\n    }\n  \n    displayData() {\n      console.log(this.backend.getData());\n    }\n}\n\nconst frontend1 = new Frontend();\nfrontend1.displayData();\n\n\n// Forma Correcta de implementar el principio DIP\n\nclass DataService {\n    getData() {\n      throw new Error(\"Método no implementado\");\n    }\n}\n\nclass Backend extends DataService {\n    getData() {\n      return \"Datos del backend\";\n    }\n}\n\nclass Frontend {\n    constructor(dataService) {\n      this.dataService = dataService;\n    }\n  \n    displayData() {\n      console.log(this.dataService.getData());\n    }\n}\n\nconst backend = new Backend();\nconst frontend = new Frontend(backend);\nfrontend.displayData();\n  \n  \n//////////////////// ----------------------------- EXTRA ---------------------------------------- ///////////////\n\n\n// Clase abstracta NotificationService\nclass NotificationService {\n    sendNotification(message) {\n      throw new Error(\"Método no implementado\");\n    }\n}\n\nclass EmailNotification extends NotificationService {\n    sendNotification(message) {\n      console.log(`Enviando email con mensaje: ${message}`);\n    }\n}\n\nclass PushNotification extends NotificationService {\n    sendNotification(message) {\n      console.log(`Enviando notificación PUSH con mensaje: ${message}`);\n    }\n}\n\nclass SMSNotification extends NotificationService {\n    sendNotification(message) {\n      console.log(`Enviando SMS con mensaje: ${message}`);\n    }\n}\n\nclass NotificationSystem {\n    constructor(notificationService) {\n      this.notificationService = notificationService;\n    }\n  \n    notify(message) {\n      this.notificationService.sendNotification(message);\n    }\n}\n\nconst emailService = new EmailNotification();\nconst emailNotificationSystem = new NotificationSystem(emailService);\nemailNotificationSystem.notify(\"Este es un mensaje de prueba por Email.\");\n\nconst pushService = new PushNotification();\nconst pushNotificationSystem = new NotificationSystem(pushService);\npushNotificationSystem.notify(\"Este es un mensaje de prueba por PUSH.\");\n\nconst smsService = new SMSNotification();\nconst smsNotificationSystem = new NotificationSystem(smsService);\nsmsNotificationSystem.notify(\"Este es un mensaje de prueba por SMS.\");\n\n  \n  \n  "
  },
  {
    "path": "Roadmap/30 - SOLID DIP/javascript/DavidMoralesDeveloper.js",
    "content": "// El Principio de Inversión de Dependencias establece dos reglas clave:\n\n// Los módulos de alto nivel no deben depender de módulos de bajo nivel. Ambos deben depender de abstracciones.\n\n// Las abstracciones no deben depender de los detalles. Los detalles (implementaciones concretas) deben depender de las abstracciones.\n\n// El nivel alto y bajo dependen de la abstraccion comun\n\n\n\n\n//abstracción \nclass ServicioDeNotificacion {\n    enviar(){console.log(\"enviando mensaje Desde Servicio De Notificacion\" )}\n}\n\n// Tu módulo de alto nivel será un GestorDeNotificaciones. Su responsabilidad principal es enviar mensajes, sin importarle cómo se envían.\n//nivel alto\nclass GestorDeNotificaciones {\n    constructor(ServicioDeNotificacion){\n    this.servicio= ServicioDeNotificacion\n    }\n    enviarNotificacion(mensaje){\n        console.log(`Gestor: Intentando enviar notificación: \"${mensaje}\"`);\n        return this.servicio.enviar(mensaje)\n    }\n}\n\n\n//nivel bajo\nclass EmailService extends ServicioDeNotificacion{\n    enviar(mensaje) { // ¡Nombre del método CORRECTO: 'enviar'!\n        console.log(`[EmailService] Enviando correo electrónico: \"${mensaje}\"`);\n    }\n}\n\nclass SMSService extends ServicioDeNotificacion{\n    enviarmensaje(){console.log(\"enviando mensaje SMS\")}\n}\n\nconst emailservice = new EmailService()\n\nconst gestionar = new GestorDeNotificaciones(emailservice)\ngestionar.enviarNotificacion(\"Hola por email desde instancia\")\n\nconst smsservice = new SMSService()\nconst gestionarsms = new GestorDeNotificaciones(smsservice)\ngestionarsms.enviarNotificacion()\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #30 - JavaScript -> Jesus Antonio Escamilla */\n\n/**\n * Este principio establece dos reglas clave:\n * 1-. Los módulos de alto nivel no deben depender de módulos de bajo nivel. Ambos deben depender de abstracciones (interfaces).\n * 2-. Las abstracciones no deben depender de detalles. Los detalles deben depender de abstracciones.\n */\n\n//---EJERCIÓ---\n//INCORRECTO\n// Creamos un modelo para usarlo\nclass PdfReport__{\n   generate(content){\n      console.log(`Generating PDF report with content: ${content}`);\n   }\n}\n\n// Creamos un objeto\nclass ReportGenerator__{\n   constructor(pdfReport){\n      this.pdfReport = pdfReport;\n   }\n\n   generateReport(content){\n      this.pdfReport.generate(content);\n   }\n}\n\n// El uso Incorrecto de DIP\nconst pdfReport__ = new PdfReport__();\nconst reportGenerator__ = new ReportGenerator__(pdfReport__);\nreportGenerator__.generateReport(\"Annual Financial Report\");\n\n\n//CORRECTO\n// Interfaz del Report\nclass IReport{\n   generate(content){\n      throw new Error(\"Method 'generate()' must be implemented\");\n   }\n}\n\n// Implementación Correcta de DIP\nclass PdfReport extends IReport{\n   generate(content){\n      console.log(`Generating PDF report with content: ${content}`);\n   }\n}\n\nclass HtmlReport extends IReport{\n   generate(content){\n      console.log(`Generating HTML report with content: ${content}`);\n   }\n}\n\nclass ReportGenerator{\n   constructor(report){\n      // Dependencia de la abstraction\n      if (!(report instanceof IReport)) {\n         throw new Error(\"Invalid report service\");\n      }\n      this.report = report;\n   }\n\n   generateReport(content){\n      this.report.generate(content);\n   }\n}\n\n// El uso Correcto de DIP\nconst pdfReport = new PdfReport();\nconst htmlReport = new HtmlReport();\n\nconst reportGenerator = new ReportGenerator(pdfReport);\nreportGenerator.generateReport(\"Monthly Financial Report\");\n\nconst htmlReportGenerator = new ReportGenerator(htmlReport);\nhtmlReportGenerator.generateReport(\"Weekly Financial Report\")\n\n\n\n/**-----DIFICULTAD EXTRA-----*/\n\n// Interfaz\nclass INotificacionService{\n   sendNotificacion(user, message){\n      throw new Error(\"Method 'sendNotificacion()' must be implemented\");\n   }\n}\n\n// Implementación Especifica\nclass EmailService extends INotificacionService{\n   sendNotificacion(user, message){\n      console.log(`Sending Email to ${user.email}: ${message}`);\n   }\n}\n\nclass PushService extends INotificacionService{\n   sendNotificacion(user, message){\n      console.log(`Sending Email to ${user.deviceId}: ${message}`);\n   }\n}\n\nclass SmsService extends INotificacionService{\n   sendNotificacion(user, message){\n      console.log(`Sending Email to ${user.phoneNumber}: ${message}`);\n   }\n}\n\n// Sistema de Notificacion\nclass NotificationSystem{\n   constructor(notificationService){\n      if (!(notificationService instanceof INotificacionService)) {\n         throw new Error(\"Invalid notification service\");\n      }\n      this.notificationService = notificationService;\n   }\n\n   notify(user, message){\n      this.notificationService.sendNotificacion(user, message);\n   }\n}\n\n// Creando un usuario\nconst user = {\n   email: \"jesus@example.com\",\n   deviceId: \"antonio123\",\n   phoneNumber: \"1234567890\"\n}\n\n// Instanciando servicios\nconst emailService = new EmailService();\nconst pushService = new PushService();\nconst smsService = new SmsService();\n\n// Creando sistema de notificaciones\nconst emailNotificationSystem = new NotificationSystem(emailService);\nconst pushNotificationSystem = new NotificationSystem(pushService);\nconst smsNotificationSystem = new NotificationSystem(smsService);\n\n// Usando el sistema\nemailNotificationSystem.notify(user, \"Welcome via Email!\");\npushNotificationSystem.notify(user, \"Welcome via PUSH notificacion!\");\nsmsNotificationSystem.notify(user, \"Welcome via SMS!\");\n\n/**-----DIFICULTAD EXTRA-----*/"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/javascript/RaulDoezon.js",
    "content": "/*\n  EJERCICIO:\n  Explora el \"Principio SOLID de Inversión de Dependencias (Dependency Inversion\n  Principle, DIP)\" y crea un ejemplo simple donde se muestre su funcionamiento \n  de forma correcta e incorrecta.\n*/\n\nconsole.log(\"+++++++++ FORMA INCORRECTA +++++++++\");\n\nclass reminderServiceProof {\n  reminder(message) {\n    console.log(message);\n  }\n}\n\nclass AlarmServiceProof {\n  constructor() {\n    this.reminderService = new reminderServiceProof();\n  }\n\n  setAlarm(message) {\n    this.reminderService.reminder(message);\n  }\n}\n\nconst alarmServiceProof = new AlarmServiceProof();\nalarmServiceProof.setAlarm(\"Nueva alarma.\");\n\nconsole.log(\"\\n+++++++++ FORMA CORRECTA +++++++++\");\n\nclass ReminderService {\n  reminder(message) {\n    console.log(message);\n  }\n}\n\nclass AlarmService {\n  constructor(reminderService) {\n    this.reminderService = reminderService;\n  }\n\n  setAlarm(message) {\n    this.reminderService.reminder(message);\n  }\n}\n\nconst reminderService = new ReminderService();\nconst alarmService = new AlarmService(reminderService);\nalarmService.setAlarm(\"Nueva alarma.\");\n\n/*\n  DIFICULTAD EXTRA (opcional):\n  Crea un sistema de notificaciones.\n  Requisitos:\n  1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas).\n  2. El sistema de notificaciones no puede depender de las implementaciones específicas.\n  Instrucciones:\n  1. Crea la interfaz o clase abstracta.\n  2. Desarrolla las implementaciones específicas.\n  3. Crea el sistema de notificaciones usando el DIP.\n  4. Desarrolla un código que compruebe que se cumple el principio.\n*/\n\nconsole.log(\"\\n+++++++++ SISTEMA DE NOTIFICACIONES +++++++++\");\n\nclass Notifications {\n  email(emailNotification) {\n    console.log(emailNotification);\n  }\n\n  push(pushNotification) {\n    console.log(pushNotification);\n  }\n\n  sms(smsNotification) {\n    console.log(smsNotification);\n  }\n}\n\nclass EmailService {\n  constructor(notification) {\n    this.notification = notification;\n  }\n\n  sendNotification(message) {\n    this.notification.email(message);\n  }\n}\n\nclass PushService {\n  constructor(notification) {\n    this.notification = notification;\n  }\n\n  sendNotification(message) {\n    this.notification.email(message);\n  }\n}\n\nclass SmsService {\n  constructor(notification) {\n    this.notification = notification;\n  }\n\n  sendNotification(message) {\n    this.notification.email(message);\n  }\n}\n\nconst notification = new Notifications();\nconst email = new EmailService(notification);\nconst push = new PushService(notification);\nconst sms = new SmsService(notification);\n\nfunction testNotifications(notificationType) {\n  notificationType.sendNotification(`Notificación ${notificationType.constructor.name}`);\n}\n\ntestNotifications(sms);\ntestNotifications(push);\ntestNotifications(email);\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/javascript/RicJDev.js",
    "content": "//EJERCICIO\n//Incorrecto ❎\nclass ButtonNoDPI {\n\tturnOn() {\n\t\tconsole.log('Lamp is on!')\n\t}\n\n\tturnOff() {\n\t\tconsole.log('Lamp is off!')\n\t}\n}\n\nclass LampNoDPI {\n\tconstructor() {\n\t\tthis.button = new ButtonNoDPI()\n\t}\n\n\toperate(command) {\n\t\tif (command === 'on') {\n\t\t\tthis.button.turnOn()\n\t\t} else if (command === 'off') {\n\t\t\tthis.button.turnOff()\n\t\t}\n\t}\n}\n\nconst lamp1 = new LampNoDPI()\nlamp1.operate('on')\nlamp1.operate('off')\n\n//Correcto ✅\nclass ButtonInterface {\n\tconstructor() {\n\t\tif (new.target === ButtonInterface) {\n\t\t\tthrow new TypeError('Unable to instantiate interface \"ButtonInterface\"')\n\t\t}\n\t}\n\n\tturnOn() {\n\t\tthrow new Error('The method \"turnOn()\" must be implemented')\n\t}\n\n\tturnOff() {\n\t\tthrow new Error('The method \"turnOff()\" must be implemented')\n\t}\n}\n\nclass LampButton extends ButtonInterface {\n\tturnOn() {\n\t\tconsole.log('Lamp is on!')\n\t}\n\n\tturnOff() {\n\t\tconsole.log('Lamp is off!')\n\t}\n}\n\nclass Lamp {\n\tconstructor(button) {\n\t\tthis.button = button\n\t}\n\n\toperate(command) {\n\t\tif (command === 'on') {\n\t\t\tthis.button.turnOn()\n\t\t} else {\n\t\t\tthis.button.turnOff()\n\t\t}\n\t}\n}\n\n//EXTRA\nclass NotifierInterface {\n\tconstructor() {\n\t\tif (new.target === NotifierInterface) {\n\t\t\tthrow new TypeError('Unable to instantiate interface \"NotifierInterface\"')\n\t\t}\n\t}\n\n\tsend(message) {\n\t\tthrow new Error('The method \"send()\" must be implemented')\n\t}\n}\n\nclass EmailNotifier extends NotifierInterface {\n\tsend(message) {\n\t\tconsole.log(`Sending by email: ${message}`)\n\t}\n}\n\nclass PushNotifier extends NotifierInterface {\n\tsend(message) {\n\t\tconsole.log(`Sending by push: ${message}`)\n\t}\n}\n\nclass SMSNotifier extends NotifierInterface {\n\tsend(message) {\n\t\tconsole.log(`Sending by SMS: ${message}`)\n\t}\n}\n\nclass NotificationService {\n\tconstructor(notifier) {\n\t\tthis.notifier = notifier\n\t}\n\n\tnotify(message) {\n\t\tthis.notifier.send(message)\n\t}\n}\n\nconst pushService = new NotificationService(new PushNotifier())\nconst SMSService = new NotificationService(new SMSNotifier())\nconst emailService = new NotificationService(new EmailNotifier())\n\nlet message = 'Hello, notifier!'\n\npushService.notify(message)\nSMSService.notify(message)\nemailService.notify(message)\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/javascript/Sac-Corts.js",
    "content": "// Wrong way \nclass UserService {\n    constructor() {\n        this.database = new MySQLDatabase();\n    }\n\n    getUser(id) {\n        return this.database.findUserById(id);\n    }\n}\n\nclass MySQLDatabase {\n    findUserById(id) {\n        return { id, name: 'Isaac Cortés', db: 'MySQL' };\n    }\n}\n\nconst userService = new UserService();\nconsole.log(userService.getUser(1));\n\n// Correct way\nclass UserService2 {\n    constructor(database) {\n        this.database = database;\n    }\n\n    getUser(id) {\n        return this.database.findUserById(id);\n    }\n}\n\nclass Database {\n    findUserById(id) {\n        throw new Error(\"Method not implemented\");\n    }\n}\n\nclass MySQLDatabase2 extends Database {\n    findUserById(id) {\n        return { id, name: 'Isaac Cortés', db: 'MySQL' };\n    }\n}\n\nclass MongoDBDatabase extends Database {\n    findUserById(id) {\n        return { id, name: 'Isaac Cortés', db: 'MongoDB' };\n    }\n}\n\nconst mysqlService = new UserService2(new MySQLDatabase2());\nconsole.log(mysqlService.getUser(1));\n\nconst mongoService = new UserService2(new MongoDBDatabase());\nconsole.log(mongoService.getUser(2));\n\n// Extra Exercise //\nclass NotificationService {\n    sendNotification(message, recipient) {\n        throw new Error('Method not implemented');\n    }\n}\n\nclass EmailNotification extends NotificationService {\n    sendNotification(message, recipient) {\n        console.log(`Sending email to ${recipient}: ${message}`);\n    }\n}\n\nclass PushNotification extends NotificationService {\n    sendNotification(message, recipient) {\n        console.log(`Sending push to ${recipient}: ${message}`);\n    }\n}\n\nclass SMSNotification extends NotificationService {\n    sendNotification(message, recipient) {\n        console.log(`Sending SMS to ${recipient}: ${message}`)\n    }\n}\n\nclass NotificationManager {\n    constructor(notificationService) {\n        this.notificationService = notificationService;\n    }\n\n    send(message, recipient) {\n        this.notificationService.sendNotification(message, recipient);\n    }\n}\n\nconst emailService = new EmailNotification();\nconst pushService = new PushNotification();\nconst smsService = new SMSNotification();\n\nconst emailManager = new NotificationManager(emailService);\nconst pushManager = new NotificationManager(pushService);\nconst smsManager = new NotificationManager(smsService);\n\nemailManager.send('Hello, Isaac!', 'isaac@gmail.com');\npushManager.send('Hello, Isaac!', 'sac');\nsmsManager.send('Hello, Isaac!', '8992584897');"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/javascript/adrs1166ma.js",
    "content": "/* 🔥 EJERCICIO:\nExplora el \"Principio SOLID de Inversión de Dependencias (Dependency Inversion\nPrinciple, DIP)\" y crea un ejemplo simple donde se muestre su funcionamiento \nde forma correcta e incorrecta.\n*/\nconsole.log(\"----- EJEMPLO SIMPLE -----\");\n\n//  * Ejemplo Incorrecto (viola DIP): Dependencia directa\n// --------------------------------------------------------------------------------------------------------------\nclass Bombilla {\n    encender() {\n        console.log(\"💡 Bombilla encendida.\");\n    }\n\n    apagar() {\n        console.log(\"💡 Bombilla apagada.\");\n    }\n}\n\nclass InterruptorIncorrecto {\n    constructor(bombilla) {\n        this.bombilla = bombilla; // Dependencia directa a una implementación concreta\n    }\n\n    operar() {\n        this.bombilla.encender();\n    }\n}\n\n// Uso incorrecto\nconst bombilla = new Bombilla();\nconst interruptorIncorrecto = new InterruptorIncorrecto(bombilla);\ninterruptorIncorrecto.operar(); // Enciende la bombilla\n\n// Problema: Si queremos usar otra cosa (como un ventilador), debemos modificar InterruptorIncorrecto\n\n//  * Ejemplo Correcto (cumple DIP): Dependencia de abstracciones\n// --------------------------------------------------------------------------------------------------------------\nclass Dispositivo {\n    encender() {\n        throw new Error(\"Método 'encender' no implementado\");\n    }\n\n    apagar() {\n        throw new Error(\"Método 'apagar' no implementado\");\n    }\n}\n\nclass BombillaCorrecta extends Dispositivo {\n    encender() {\n        console.log(\"💡 Bombilla encendida correctamente.\");\n    }\n\n    apagar() {\n        console.log(\"💡 Bombilla apagada correctamente.\");\n    }\n}\n\nclass Ventilador extends Dispositivo {\n    encender() {\n        console.log(\"💨 Ventilador encendido.\");\n    }\n\n    apagar() {\n        console.log(\"💨 Ventilador apagado.\");\n    }\n}\n\nclass InterruptorCorrecto {\n    constructor(dispositivo) {\n        this.dispositivo = dispositivo; // Dependencia de una interfaz abstracta\n    }\n\n    operar() {\n        this.dispositivo.encender();\n    }\n}\n\n// Uso correcto\nconst bombillaCorrecta = new BombillaCorrecta();\nconst ventilador = new Ventilador();\n\nconst interruptorBombilla = new InterruptorCorrecto(bombillaCorrecta);\ninterruptorBombilla.operar(); // Enciende la bombilla\n\nconst interruptorVentilador = new InterruptorCorrecto(ventilador);\ninterruptorVentilador.operar(); // Enciende el ventilador\n\n// --------------------------------------------------------------------------------------------------------------\n/* 🔥 DIFICULTAD EXTRA (opcional):\nCrea un sistema de notificaciones.\nRequisitos:\n1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas).\n2. El sistema de notificaciones no puede depender de las implementaciones específicas.\nInstrucciones:\n1. Crea la interfaz o clase abstracta.\n2. Desarrolla las implementaciones específicas.\n3. Crea el sistema de notificaciones usando el DIP.\n4. Desarrolla un código que compruebe que se cumple el principio.\n*/\nconsole.log(\"\\n----- SISTEMA DE NOTIFICACIONES (DIP) -----\");\n\n// Interfaz abstracta\nclass ServicioNotificacion {\n    enviar(mensaje) {\n        throw new Error(\"Método 'enviar' no implementado\");\n    }\n}\n\n// Implementaciones específicas\nclass NotificacionEmail extends ServicioNotificacion {\n    enviar(mensaje) {\n        console.log(`📧 Enviando email: ${mensaje}`);\n    }\n}\n\nclass NotificacionPush extends ServicioNotificacion {\n    enviar(mensaje) {\n        console.log(`📱 Enviando notificación PUSH: ${mensaje}`);\n    }\n}\n\nclass NotificacionSMS extends ServicioNotificacion {\n    enviar(mensaje) {\n        console.log(`📲 Enviando SMS: ${mensaje}`);\n    }\n}\n\n// Sistema de notificaciones\nclass GestorNotificaciones {\n    constructor(servicios) {\n        this.servicios = servicios; // Dependencia de una lista de interfaces abstractas\n    }\n\n    notificar(mensaje) {\n        this.servicios.forEach(servicio => servicio.enviar(mensaje));\n    }\n}\n\n// Ejemplos de uso\nconst emailService = new NotificacionEmail();\nconst pushService = new NotificacionPush();\nconst smsService = new NotificacionSMS();\n\nconst gestor = new GestorNotificaciones([emailService, pushService, smsService]);\ngestor.notificar(\"¡Este es un mensaje importante!\");\n\n// Agregar un nuevo servicio sin modificar el gestor\nclass NotificacionWhatsApp extends ServicioNotificacion {\n    enviar(mensaje) {\n        console.log(`💬 Enviando WhatsApp: ${mensaje}`);\n    }\n}\n\nconst whatsappService = new NotificacionWhatsApp();\ngestor.servicios.push(whatsappService); // Añadir WhatsApp al sistema\ngestor.notificar(\"¡Nuevo mensaje añadido!\");"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/javascript/caterinarodriguezdev.js",
    "content": "/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Inversión de Dependencias (Dependency Inversion\n * Principle, DIP)\" y crea un ejemplo simple donde se muestre su funcionamiento \n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un sistema de notificaciones.\n * Requisitos:\n * 1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas).\n * 2. El sistema de notificaciones no puede depender de las implementaciones específicas.\n * Instrucciones:\n * 1. Crea la interfaz o clase abstracta.\n * 2. Desarrolla las implementaciones específicas.\n * 3. Crea el sistema de notificaciones usando el DIP.\n * 4. Desarrolla un código que compruebe que se cumple el principio.\n */\n\n// INCORRECTO\nclass Efectivo {\n    cobrar() {\n        console.log('Cobrando en efectivo');\n    }\n}\n\nclass Caja {\n    constructor() {\n        this.efectivo = new Efectivo();\n    }\n\n    cobrar() {\n        this.efectivo.cobrar();\n    }\n}\n\n// CORRECTO\nclass ICobro {\n    cobrar() {\n        throw Error('Debe implementar el método cobrar');\n    }\n}\n\nclass EfectivoDIP extends ICobro {\n    cobrar() {\n        console.log('Cobrando en efectivo');\n    }\n}\n\nclass TarjetaDIP extends ICobro {\n    cobrar() {\n        console.log('Cobrando con tarjeta');\n    }\n}\n\nclass CajaDIP {\n    constructor(service) {\n        this.service = service;\n    }\n\n    cobrar() {\n        this.service.cobrar();\n    }\n}\n\nconst efectivo = new EfectivoDIP();\nconst tarjeta = new TarjetaDIP();\nconst cajaE = new CajaDIP(efectivo);\nconst cajaT = new CajaDIP(tarjeta);\ncajaE.cobrar();\ncajaT.cobrar();\n\nconsole.log('-----------DIFICULTAD EXTREMA------');\n\nclass IMessage {\n    send() {\n        throw Error('Debe implementar el método send');\n    }\n}\n\nclass SMS extends IMessage {\n    send() {\n        console.log('Mandando SMS');\n    }\n}\n\nclass Push extends IMessage {\n    send() {\n        console.log('Mandando PUSH');\n    }\n}\n\nclass Email extends IMessage {\n    send() {\n        console.log('Mandando email');\n    }\n}\n\nclass Notification {\n    constructor(service) {\n        this.service = service;\n    }\n\n    send() {\n        this.service.send();\n    }\n}\n\nconst sms = new SMS();\nconst push = new Push();\nconst email = new Email();\n\nconst notificationSMS = new Notification(sms);\nnotificationSMS.send();\n\nconst notificationPush = new Notification(push);\nnotificationPush.send();\n\nconst notificationEmail = new Notification(email);\nnotificationEmail.send();"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/javascript/duendeintemporal.js",
    "content": "//#30 - Principio SOLID de Inversión de Dependencias (Dependency Inversion Principle (DIP))\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Inversión de Dependencias (Dependency Inversion\n * Principle, DIP)\" y crea un ejemplo simple donde se muestre su funcionamiento \n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un sistema de notificaciones.\n * Requisitos:\n * 1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas).\n * 2. El sistema de notificaciones no puede depender de las implementaciones específicas.\n * Instrucciones:\n * 1. Crea la interfaz o clase abstracta.\n * 2. Desarrolla las implementaciones específicas.\n * 3. Crea el sistema de notificaciones usando el DIP.\n * 4. Desarrolla un código que compruebe que se cumple el principio.\n */\n//Bibliografy: The Web Development Glossary (Jens Oliver Meiert) (Z-Library)\n//GPT\n\n/* Dependency Inversion Principle\nA specific form of decoupling software modules. When following this\nprinciple, the conventional dependency relationships established from\nhigh-level policy-setting modules to low-level dependency modules are\nreversed, thus rendering high-level modules independent of the low-level\nmodule implementation details. The principle states 1) that high-level\nmodules should not depend on low-level modules, but that both should\ndepend on abstractions (e.g., interfaces), and 2) that abstractions should\nnot depend on details, but that details (concrete implementations) should\ndepend on abstractions.\n\nA class that contains methods for use by other classes without having to be\nthe parent class of those other classes. How those other classes gain access\nto the mixin’s methods depends on the language. Mixins are sometimes\ndescribed as being “included” rather than “inherited.” Mixins encourage\ncode reuse and can be used to avoid the inheritance ambiguity that\nmultiple inheritance can cause, or to work around lack of support for\nmultiple inheritance in a language. A mixin can also be viewed as an\ninterface with implemented methods. This pattern is an example of\nenforcing the Dependency Inversion Principle */\n\nlet log = console.log;\n\nwindow.addEventListener('load', ()=>{\n    const body = document.querySelector('body');\n    const title = document.createElement('h1');\n    \n    body.style.setProperty('background', '#000');\n    body.style.setProperty('text-align', 'center');\n    \n    title.textContent = 'Retosparaprogramadores #30.';\n    title.style.setProperty('font-size', '3.5vmax');\n    title.style.setProperty('color', '#fff');\n    title.style.setProperty('line-height', '100vh');\n    \n    body.appendChild(title);\n    \n    setTimeout(()=>{\n    alert('Retosparaprogramadores #30. Please open the Browser Developer Tools.');\n    }, 2000);\n    log( 'Retosparaprogramadores #30'); \n});\n\n//Incorrect Example\n\nclass USABillingService1 {\n    calculateCharge(duration) {\n        return duration * 0.10; // $0.10 per minute\n    }\n}\n\nclass CallBillingService1 {\n    constructor() {\n        this.billingService = new USABillingService1(); // Direct dependency\n    }\n\n    billCall(duration) {\n        const charge = this.billingService.calculateCharge(duration);\n        log(`Total charge: ${charge.toFixed(2)}`);\n    }\n}\n\nconst callBillingService1 = new CallBillingService1();\ncallBillingService1.billCall(22); // Total charge: 2.20\n\n\n//Correct Example\n\nclass IBillingService {\n    calculateCharge(duration) {\n        throw new Error(\"Method 'calculateCharge()' must be implemented for this Billing Service.\");\n    }\n}\n\nclass USABillingService extends IBillingService {\n    constructor(){\n        super();\n        this.location = 'USA';\n    }\n\n    calculateCharge(duration) {\n        return duration * 0.10; \n    }\n}\n\nclass EuropeBillingService extends IBillingService {\n    constructor() {\n        super();\n        this.location = 'Europe';\n    }\n\n    calculateCharge(duration) {\n        return duration * 0.15; \n    }\n}\n\nclass AsiaBillingService extends IBillingService {\n    constructor() {\n        super();\n        this.location = 'Asia';\n    }\n\n    calculateCharge(duration) {\n        return duration * 0.05; \n    }\n}\n\nclass CallBillingService {\n    constructor(billingService) {\n        this.billingService = billingService; // Dependency injection\n    }\n\n    billCall(duration) {\n        const charge = this.billingService.calculateCharge(duration);\n        log(`Total charge for ${this.billingService.location}: ${charge.toFixed(2)}`);\n    }\n}\n\nconst usaBillingService = new USABillingService();\nconst europeBillingService = new EuropeBillingService();\nconst asiaBillingService = new AsiaBillingService();\n\nconst callBillingServiceUSA = new CallBillingService(usaBillingService);\nconst callBillingServiceEurope = new CallBillingService(europeBillingService);\nconst callBillingServiceAsia = new CallBillingService(asiaBillingService);\n\ncallBillingServiceUSA.billCall(127.22); // Total charge for USA: 12.72\ncallBillingServiceEurope.billCall(17.56); // Total charge for Europe: 2.63\ncallBillingServiceAsia.billCall(45.23); // Total charge for Asia: 2.26\n\n\n//Extra Dificulty Exercise\nclass INotificationService {\n    send(message) {\n        throw new Error(\"Method 'send()' must be implemented in this especific Notification Service.\");\n    }\n}\n\nclass EmailService extends INotificationService {\n    send(message) {\n        log(`Sending email: ${message}`);\n    }\n}\n\nclass SMSService extends INotificationService {\n    send(message) {\n        log(`Sending SMS: ${message}`);\n    }\n}\n\nclass PushService extends INotificationService {\n    send(message) {\n        log(`Sending PUSH notification: ${message}`);\n    }\n}\n\nclass NotificationSystem {\n    constructor(notificationService) {\n        this.notificationService = notificationService;\n    }\n\n    notify(message) {\n        this.notificationService.send(message);\n    }\n}\n\nconst emailService = new EmailService();\nconst smsService = new SMSService();\nconst pushService = new PushService();\n\nconst notificationSystemEmail = new NotificationSystem(emailService);\nconst notificationSystemSMS = new NotificationSystem(smsService);\nconst notificationSystemPush = new NotificationSystem(pushService);\n\nnotificationSystemEmail.notify(\"Testing sending a message via Email.\"); // Sending email: Testing sending a message via Email.\nnotificationSystemSMS.notify(\"Testing sending a message via SMS.\"); // Sending SMS: Testing sending a message via SMS.\nnotificationSystemPush.notify(\"Testing sending a message via PUSH.\"); // Sending PUSH notification: Testing sending a message via PUSH.\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/javascript/hectorio23.js",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\n\"use strict\";\n\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Inversión de Dependencias (Dependency Inversion\n * Principle, DIP)\" y crea un ejemplo simple donde se muestre su funcionamiento \n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA:\n * Crea un sistema de notificaciones.\n * Requisitos:\n * 1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas).\n * 2. El sistema de notificaciones no puede depender de las implementaciones específicas.\n * Instrucciones:\n * 1. Crea la interfaz o clase abstracta.\n * 2. Desarrolla las implementaciones específicas.\n * 3. Crea el sistema de notificaciones usando el DIP.\n * 4. Desarrolla un código que compruebe que se cumple el principio.\n*/\n\n// Interfaz para el servicio de notificación (usando clases abstractas en ES6)\nclass NotificationService {\n    sendNotification(message) {\n        throw new Error('Método no implementado');\n    }\n}\n\n// Implementación específica para Email\nclass EmailNotification extends NotificationService {\n    sendNotification(message) {\n        console.log(`[+] - Enviando Email: ${message}`);\n    }\n}\n\n// Implementación específica para PUSH\nclass PushNotification extends NotificationService {\n    sendNotification(message) {\n        console.log(`[+] - Enviando Push Notification: ${message}`);\n    }\n}\n\n// Implementación específica para SMS\nclass SMSNotification extends NotificationService {\n    sendNotification(message) {\n        console.log(`[+] - Enviando SMS: ${message}`);\n    }\n}\n\n// Sistema de Notificaciones usando DIP\nclass NotificationSystem {\n    constructor() {\n        this.services = [];\n    }\n\n    addService(service) {\n        this.services.push(service);\n    }\n\n    notifyAll(message) {\n        this.services.forEach(service => service.sendNotification(message));\n    }\n}\n\n// Función principal para demostrar el DIP\n(() => {\n    // Correcto: El sistema de notificaciones no depende directamente de las implementaciones concretas\n    const notificationSystem = new NotificationSystem();\n\n    notificationSystem.addService(new EmailNotification());\n    notificationSystem.addService(new PushNotification());\n    notificationSystem.addService(new SMSNotification());\n\n    notificationSystem.notifyAll('Mensaje de prueba.');\n\n    // Incorrecto: Dependencia directa de las implementaciones concretas (violación del DIP)\n    const emailNotification = new EmailNotification();\n    emailNotification.sendNotification('Mensaje directo sin sistema de notificaciones.');\n})();\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n_______________________________________________________\n#30 SOLID: PRINCIPIO DE INVERSIÓN DE DEPENDENCIAS (DIP)\n-------------------------------------------------------\n* EJERCICIO:\n * Explora el \"Principio SOLID de Inversión de Dependencias (Dependency Inversion\n * Principle, DIP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un sistema de notificaciones.\n * Requisitos:\n * 1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas).\n * 2. El sistema de notificaciones no puede depender de las implementaciones específicas.\n * Instrucciones:\n * 1. Crea la interfaz o clase abstracta.\n * 2. Desarrolla las implementaciones específicas.\n * 3. Crea el sistema de notificaciones usando el DIP.\n * 4. Desarrolla un código que compruebe que se cumple el principio.\n*/\n// ________________________________________________________\n// SIN APLICAR DIP\n// ---------------\n// Clase concreta\nclass FileStorage_ {\n    save(data) {\n        console.log(`Datos guardados en archivo: ${data}`);\n    }\n}\n\n// Clase de alto nivel \nclass DataManager_ {\n    constructor() {\n        // Dependencia directa de la clase concreta.\n        this.fileStorage = new FileStorage_();\n    }\n\n    storeData(data) {\n        this.fileStorage.save(data);\n    }\n}\n\n// ________________________________________________________\n// APLICANDO DIP\n// ---------------\n// Abstracción\nclass AbcStorage {\n    save(data) {\n        throw new Error(\"El método 'save' debe ser implementado.\");\n    }\n}\n\n// Implementación concreta\nclass FileStorage extends AbcStorage {\n    save(data) {\n        console.log(`Guardado en archivo: ${data}`);\n    }\n}\n\n// Implementación concreta\nclass DatabaseStorage extends AbcStorage {\n    save(data) {\n        console.log(`Guardado en base de datos: ${data}`);\n    }\n}\n\n// Clase de alto nivel\nclass DataManager {\n    constructor(storage) {\n        // Dependencia de la abstracción\n        if (!(storage instanceof AbcStorage)) {\n            throw new Error(\"La dependencia debe implementar AbcStorage\");\n        }\n        this.storage = storage;\n    }\n\n    storeData(data) {\n        this.storage.save(data);\n    }\n}\n\n// Uso\nconst dataToStore = \"Ejemplo de datos x\";\nconst fileStorage = new FileStorage();\nconst dataManagerFile = new DataManager(fileStorage);\ndataManagerFile.storeData(dataToStore);\nconst databaseStorage = new DatabaseStorage();\nconst dataManagerDatabase = new DataManager(databaseStorage);\ndataManagerDatabase.storeData(dataToStore);\n\n// ________________________________________________________\n// DIFICULTAD EXTRA\n// ----------------\n\n// Abstracción\nclass AbcMessageService {\n    send(to, message) {\n        throw new Error(\"El método 'send' debe ser implementado.\");\n    }\n}\n\n// Implementación: Email\nclass EmailService extends AbcMessageService {\n    send(to, message) {\n        console.log(\"Correo enviado a:\", to);\n        console.log(\"Mensaje:\", message);\n    }\n}\n\n// Implementación: PUSH\nclass PUSHService extends AbcMessageService {\n    send(to, message) {\n        console.log(\"Notificación PUSH enviada a:\", to);\n        console.log(\"Mensaje:\", message);\n    }\n}\n\n// Implementación: SMS\nclass SMSService extends AbcMessageService {\n    send(to, message) {\n        console.log(\"Mensaje SMS enviado a:\", to);\n        console.log(\"Mensaje:\", message);\n    }\n}\n\n// Módulo de alto nivel\nclass NotificationSystem {\n    constructor(service) {\n        if (!(service instanceof AbcMessageService)) {\n            throw new Error(\"La dependencia debe implementar AbcMessageService\");\n        }\n        this.service = service;\n    }\n\n    notify(to, message) {\n        this.service.send(to, message);\n    }\n}\n\n// Inyección de dependencias\nfunction testNotificationSystem(to, message, service) {\n    const serviceNotifier = new NotificationSystem(service);\n    serviceNotifier.notify(to, message);\n}\n\nconsole.log(\"\\nDIFICULTAD EXTRA\");\n\n// Asignación\nconst emailService = new EmailService();\nconst pushService = new PUSHService();\nconst smsService = new SMSService();\n\n// Comprobación:\ntestNotificationSystem(\"ejm@gg.com\", \"abcdsf\", emailService);\ntestNotificationSystem(\"user01\", \"123456\", pushService);\ntestNotificationSystem(123456789, \"aeiou\", smsService);\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/javascript/parababire.js",
    "content": "// Incorrecto\n\n// Modulo de alto nivel\n\n/* class Store {\n  constructor(user) {\n    this.stripe = new Stripe(user)\n  }\n  purchaseBike(quantity) {\n    this.stripe.makePayment(200 * quantity * 100)\n  }\n  purchaseHelment(quantity) {\n    this.stripe.makePayment(15 * quantity * 100)\n  }\n}\n\n// Modulo de bajo nivel\n\nclass Stripe {\n  constructor(user) {\n    this.user = user\n  }\n  makePayment(amountInCents) {\n    console.log(`${this.user} made payment of $${amountInCents / 100} with Stripe`)\n  }\n}\n\nconst store = new Store('John')\nstore.purchaseBike(2)\nstore.purchaseHelment(2) */\n\n// Correcto\n\nclass AbstracPayment {\n  constructor(user) {\n    this.user = user\n    if (new.target === AbstracPayment) {\n      throw new Error(\"AbstracPayment es una interface no se debe instanciar\")\n    }\n    if (!this.payment) {\n      throw new Error(\"Debes implementar el método payment\")\n    }\n  }\n}\n\nclass PaymentProcess extends AbstracPayment {\n  constructor(user) {\n    super(user)\n  }\n  payment(amountInDollars) {\n    console.log(`${this.user} made payment of $${amountInDollars}`)\n  }\n}\n\nclass Store {\n  constructor(paymentProcess) {\n    this.paymentProcess = paymentProcess\n  }\n  purchaseBike(quantity) {\n    this.paymentProcess.payment(200 * quantity)\n  }\n  purchaseHelment(quantity) {\n    this.paymentProcess.payment(15 * quantity)\n  }\n}\n\nconst store = new Store(new PaymentProcess('John'))\nstore.purchaseBike(2)\nstore.purchaseHelment(2)\n\n// Extra\n\nclass AbstractNotifier {\n  constructor(message) {\n    this.message = message\n    if (new.target === AbstractNotifier) {\n      throw new Error(\"AbstractNotifier es una interface no se debe instanciar\")\n    }\n    if (!this.send) {\n      throw new Error(\"Debes implementar el método send\")\n    }\n  }\n}\n\nclass EmailNotifier extends AbstractNotifier {\n  send() {\n    console.log(`Se ha enviado mail: ${this.message}`)\n  }\n}\nclass PUSHNotifier extends AbstractNotifier {\n  send() {\n    console.log(`Se ha enviado PUSH: ${this.message}`)\n  }\n}\nclass SMSNotifier extends AbstractNotifier {\n  send() {\n    console.log(`Se ha enviado SMS: ${this.message}`)\n  }\n}\n\nclass NotificationService {\n  constructor(notifier) {\n    this.notifier = notifier\n  }\n  notify() {\n    this.notifier.send()\n  }\n}\n\nconst notificationService = new NotificationService(new EmailNotifier('Hola Ángel'))\nnotificationService.notify()"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/javascript/pedamoci.js",
    "content": "// ----------------------- DIP MAL HECHO -----------------------\nclass MongoDB {\n  save(data) {\n    // Aca iria la logica para guardar los datos n la base de datos MongoDB\n  }\n}\n\nclass WrongPrograma {\n  constructor() {\n    this.database = new MongoDB()\n  }\n\n  saveUser(user) {\n    this.database.save(user)\n  }\n}\n\nconst wrongProgram = new WrongPrograma()\n\nclass MySQL {\n  save(data) {\n    // Aca iria la logica para guardar los datos n la base de datos MySQL\n  }\n}\n\n/* --> Si quisieras cambiar la base de datos necesitaias re escribir el programa principal <-- */\nclass NewWrongPrograma {\n  constructor() {\n    this.database = new MySQL()\n  }\n\n  saveUser(user) {\n    this.database.save(user)\n  }\n}\n\n\n// ----------------------- DIP BIEN HECHO -----------------------\nclass DataRepository {\n  save(data) {\n    throw new Error(\"Este metodo deberia estar sobreescrito por las subclases\");\n  }\n}\nclass PostgreeSQL extends DataRepository {\n  save(data) {\n    // Aca iria la logica para guardar los datos n la base de datos PostgreeSQL\n  }\n}\n\nclass Oracle extends DataRepository {\n  save(data) {\n    // Aca iria la logica para guardar los datos n la base de datos Oracle\n  }\n}\n\nclass Programa {\n  constructor(database) {\n    this.database = database\n  }\n\n  saveUser(user) {\n    this.database.save(user)\n  }\n}\n\nconst postgreeSQL = new PostgreeSQL\nconst programa = new Programa(postgreeSQL)\n/* --> Si quisieras cambiar la base de datos necesitaias pasarsela como parametro al programa principal <-- */\nconst oracle = new Oracle\nprograma.database = oracle\n\n// --------------------------------- DIFICULTAD EXTRA ---------------------------------\nclass ServiceMessage {\n  send(msg) {\n    throw new Error(\"Este metodo deberia estar sobreescrito por las subclases\");\n  }\n}\n\nclass Email extends ServiceMessage {\n  send(msg) {\n    console.log('Enviando el email...')\n    return new Promise(resolve => {\n      setTimeout(() => {\n        console.log(`Se ha enviado: ${msg}`)\n        resolve()\n      }, 500);\n    })\n  }\n}\n\nclass Push extends ServiceMessage {\n  send(msg) {\n    console.log('Enviando el push...')\n    return new Promise(resolve => {\n      setTimeout(() => {\n        console.log(`Se ha enviado: ${msg}`)\n        resolve()\n      }, 500);\n    })\n  }\n}\n\nclass Sms extends ServiceMessage {\n  send(msg) {\n    console.log('Enviando el sms...')\n    return new Promise(resolve => {\n      setTimeout(() => {\n        console.log(`Se ha enviado: ${msg}`)\n        resolve()\n      }, 500);\n    })\n  }\n}\n\nclass Program {\n  constructor(msgService) {\n    this.msgService = msgService\n  }\n\n  async notify(msg) {\n    await this.msgService.send(msg)\n  }\n}\n\nconst email = new Email()\nconst push = new Push()\nconst sms = new Sms()\nconst program = new Program(email)\n\nasync function tester() {\n  console.log('\\nEl testeo ha iniciado enviando el primer mensaje por email')\n  await program.notify('Enviando un mensaje por email')\n\n  console.log('\\nCambiando el servicio de mensajeria a sms')\n  program.msgService = sms\n  await program.notify('Enviando un mensaje por sms')\n\n  console.log('\\nCambiando el servicio de mensajeria a push')\n  program.msgService = push\n  await program.notify('Enviando un mensaje por push')\n}\ntester()"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/javascript/victor-Casta.js",
    "content": "/*\n  * EJERCICIO:\n  * Explora el \"Principio SOLID de Inversión de Dependencias (Dependency Inversion\n  * Principle, DIP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n  * de forma correcta e incorrecta.\n*/\n\n// Forma incorrecta\n\nclass Game {\n  start() {\n    return 'start'\n  }\n}\n\nclass getTypeOfGame {\n  constructor() {\n    this.game = new Game()\n  }\n}\n\n// Forma correcta\n\nclass Game {\n  start() {\n    return 'start'\n  }\n}\n\nclass GameType {\n  constructor(typeOfGame) {\n    this.typeOfGame = typeOfGame\n  }\n\n  displayGame() {\n    return this.typeOfGame.start()\n  }\n}\n\nconst gameInstance = new Game()\nconst gameType = new GameType(gameInstance)\nconsole.log(gameType.displayGame())\n\n/*\n  * DIFICULTAD EXTRA (opcional):\n  * Crea un sistema de notificaciones.\n  * Requisitos:\n  * 1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas).\n  * 2. El sistema de notificaciones no puede depender de las implementaciones específicas.\n  * Instrucciones:\n  * 1. Crea la interfaz o clase abstracta.\n  * 2. Desarrolla las implementaciones específicas.\n  * 3. Crea el sistema de notificaciones usando el DIP.\n  * 4. Desarrolla un código que compruebe que se cumple el principio.\n*/\n\nclass Notification {\n  send(message) {\n    throw new Error('Método send() debe ser implementado')\n  }\n}\n\nclass EmailNotification extends Notification {\n  send(email) {\n    console.log(`Sending Email: ${email}`)\n  }\n}\n\nclass PushNotification extends Notification {\n  send(push) {\n    console.log(`Sending Push: ${push}`)\n  }\n}\n\nclass SMSNotification extends Notification {\n  send(sms) {\n    console.log(`Sending SMS: ${sms}`)\n  }\n}\n\nclass NotificationSystem {\n  constructor(notificationService) {\n    this.notificationService = notificationService\n  }\n\n  sendNotification(message) {\n    this.notificationService.send(message)\n  }\n}\n\nconst emailService = new EmailNotification()\nconst pushService = new PushNotification()\nconst smsService = new SMSNotification()\n\nconst emailSystem = new NotificationSystem(emailService)\nemailSystem.sendNotification('Hello via Email')\n\nconst pushSystem = new NotificationSystem(pushService)\npushSystem.sendNotification('Hello via Push')\n\nconst smsSystem = new NotificationSystem(smsService)\nsmsSystem.sendNotification('Hello via SMS')\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/kotlin/blackriper.kt",
    "content": "import java.util.*\r\n\r\n/*\r\n   Inversion Dependency  Principle\r\n   Inversión de Dependencias, el cual nos dice que las clases de alto nivel no deben depender\r\n   de las clases de bajo nivel,sino que ambas deben depender de abstracciones.\r\n\r\n   El principio se establece en dos partes\r\n\r\n   1. La clase de alto nivel no debe de depender de la clase de bajo nivel\r\n   2.  Las abstracciones no deberían depender de los detalles, los detalles deben depender de las abstracciones.\r\n\r\n*/\r\n\r\n//ejemplo de lo que no debe de hacerce\r\n\r\ndata class ProductTick(val sku: UUID, var name: String, var cant: Int, var price: Double)\r\ndata class ServiceTick(val sku: UUID, var name: String, var price: Double)\r\n\r\n// la clase PrinterTicket solo depende de ProductTick y ServiceTick y al modificar o agregar mas tipos de tickets el codigo crece demasiado\r\nclass PrinterTicket{\r\n    fun printTicketProduct(product: ProductTick){\r\n        val ticket=\"\"\"\r\n            Ticket sold \r\n            sku: ${product.sku}\r\n            name: ${product.name}\r\n            cant: ${product.cant}\r\n            price: ${product.price}\r\n            _________________________\r\n            Total: ${product.price*product.cant}\r\n        \"\"\".trimIndent()\r\n        println(ticket)\r\n    }\r\n\r\n    fun printTicketService(service: ServiceTick){\r\n        val ticket=\"\"\"\r\n            Ticket sold \r\n            sku: ${service.sku}\r\n            name: ${service.name}\r\n            price: ${service.price}\r\n            _________________________\r\n            Total: ${service.price}\r\n        \"\"\".trimIndent()\r\n        println(ticket)\r\n    }\r\n}\r\n\r\n// abstrayendo la logica  de la clase PrinterTicket usando genericos experimiento\r\n\r\n//1.- extraemos la logica en una interfaz en este caso la T representa un tipo generico\r\ninterface Ticket<in T>{\r\n    fun printTicket(t: T)\r\n}\r\n\r\n//2.-implementamos la  interface  en la clase al requerir un solo tipo separamos la logica de los diferentes tickets\r\n\r\nclass PrinterProduct: Ticket<ProductTick>{\r\n    override fun printTicket(t: ProductTick) {\r\n        val ticket=\"\"\"\r\n            Ticket sold \r\n            sku: ${t.sku}\r\n            name: ${t.name}\r\n            cant: ${t.cant}\r\n            price: ${t.price}\r\n            _________________________\r\n            Total: ${t.price*t.cant}\r\n        \"\"\".trimIndent()\r\n        println(ticket)\r\n    }\r\n}\r\n\r\nclass PrinterService: Ticket<ServiceTick>{\r\n    override fun printTicket(t: ServiceTick) {\r\n        val ticket=\"\"\"\r\n            Ticket sold \r\n            sku: ${t.sku}\r\n            name: ${t.name}\r\n            price: ${t.price}\r\n            _________________________\r\n            Total: ${t.price}\r\n        \"\"\".trimIndent()\r\n        println(ticket)\r\n    }\r\n}\r\n\r\n//3.- ahora podemos crear una clase builder para la impresion de tickets\r\nclass ThermalPrinter<T>{\r\n   var dataTicket: T? = null\r\n\r\n    fun print(){\r\n        when(dataTicket){\r\n            is ProductTick -> PrinterProduct().printTicket(dataTicket as ProductTick)\r\n            is ServiceTick -> PrinterService().printTicket(dataTicket as ServiceTick)\r\n        }\r\n\r\n    }\r\n}\r\n//4.-kotlin builder opcional\r\nfun <T>printerBuilder(block: ThermalPrinter<T>.() -> Unit):ThermalPrinter<T>{\r\n   return ThermalPrinter<T>().apply(block)\r\n\r\n}\r\n\r\n\r\nfun exampleDip(){\r\n\r\n     printerBuilder<ProductTick> {\r\n        dataTicket = ProductTick(UUID.randomUUID(), \"Laptop\", 1, 2000.0)\r\n     }.run { this.print() }\r\n\r\n\r\n    printerBuilder<ServiceTick> {\r\n        dataTicket = ServiceTick(UUID.randomUUID(), \"Internet Isp\", 100.0)\r\n    }.run { this.print() }\r\n\r\n}\r\n\r\n// ejercicio opcional\r\ninterface ForNotification{\r\n    fun sendNotification():String\r\n}\r\n\r\n\r\nclass EmailNotification(private  val subject:String,\r\n                        private  val cc:String,\r\n                        private  val body:String):ForNotification{\r\n    override fun sendNotification(): String {\r\n        return \"\"\"\r\n            Subject: $subject\r\n            cc: $cc\r\n            body: $body\r\n        \"\"\".trimIndent()\r\n    }\r\n}\r\n\r\n\r\nclass SmsNotification(\r\n    private  val to:String,\r\n    private  val body:String\r\n):ForNotification{\r\n    override fun sendNotification(): String {\r\n        return \"\"\"\r\n            To: $to\r\n            body: $body\r\n        \"\"\".trimIndent()\r\n    }\r\n}\r\n\r\nclass PushNotification(\r\n    private  val title:String,\r\n    private  val appName:String,\r\n    private  val content:String\r\n):ForNotification{\r\n    override fun sendNotification(): String {\r\n        return \"\"\"\r\n            $appName\r\n          _____________________\r\n             $title\r\n             $content\r\n        \"\"\".trimIndent()\r\n    }\r\n}\r\n// creamos una factoria para construir notificaciones lo mejor seria que cada tipo de notificacion tuviera sus propios builders\r\nclass NotificationFactory{\r\n      var subject:String=\"\"\r\n      var cc:String=\"\"\r\n      var to:String=\"\"\r\n      var body:String=\"\"\r\n      var title:String=\"\"\r\n      var appName:String=\"\"\r\n      var content:String=\"\"\r\n\r\n      inline fun<reified T:ForNotification> buildNotification():T {\r\n          return when(T::class){\r\n              EmailNotification::class -> EmailNotification(subject,cc,body)\r\n              SmsNotification::class -> SmsNotification(to,body)\r\n              PushNotification::class -> PushNotification(title,appName,content)\r\n              else -> throw IllegalArgumentException(\"Not supported\")\r\n          } as T\r\n     }\r\n}\r\n// estas funciones se consideran avanzadas puedes ignorarlas y usar las otras clases en un manager comun\r\ninline fun <reified T:ForNotification>buildNotification(block: NotificationFactory.() -> Unit):String{\r\n    return NotificationFactory().apply(block).buildNotification<T>().sendNotification()\r\n}\r\n\r\nfun showNotification(){\r\n   buildNotification<EmailNotification> {\r\n       subject=\"correo@example.com\"\r\n       cc=\"microsoft@azure.com\"\r\n       body=\"Expiro licencia microsoft 365\"\r\n    }.let { it+\"\\n\" }.run { println(this) }\r\n\r\n    buildNotification<SmsNotification> {\r\n        to=\"4111145678\"\r\n        body=\"Tu saldo se ha expirado\"\r\n    }.let { it+\"\\n\" }.run { println(this) }\r\n\r\n    buildNotification<PushNotification> {\r\n        title=\"Brais moure curso javascript\"\r\n        appName=\"youtube\"\r\n        content=\"nuevo video del curso de javascript con ejercicios\"\r\n\r\n    }.let { it+\"\\n\" }.run { println(this) }\r\n}\r\n\r\n\r\n\r\nfun main(){\r\n    exampleDip()\r\n    showNotification()\r\n}"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/kotlin/eulogioep.kt",
    "content": "/*\n * Principio de Inversión de Dependencias (DIP)\n * \n * El Principio de Inversión de Dependencias es uno de los cinco principios SOLID\n * en programación orientada a objetos. Establece que:\n * \n * 1. Los módulos de alto nivel no deben depender de módulos de bajo nivel.\n *    Ambos deben depender de abstracciones.\n * 2. Las abstracciones no deben depender de los detalles. Los detalles deben\n *    depender de las abstracciones.\n * \n * En otras palabras, este principio nos ayuda a desacoplar los componentes de\n * software, haciendo que las clases de alto nivel dependan de interfaces o\n * clases abstractas en lugar de clases concretas. Esto mejora la flexibilidad,\n * la reutilización y la facilidad de prueba del código.\n */\n\n// Ejemplo incorrecto (violando DIP)\nclass IncorrectExample {\n    class LightBulb {\n        fun turnOn() {\n            println(\"LightBulb: Bulb turned on...\")\n        }\n        \n        fun turnOff() {\n            println(\"LightBulb: Bulb turned off...\")\n        }\n    }\n\n    class ElectricPowerSwitch(private val bulb: LightBulb) {\n        private var isOn = false\n        \n        fun press() {\n            isOn = if (isOn) {\n                bulb.turnOff()\n                false\n            } else {\n                bulb.turnOn()\n                true\n            }\n        }\n    }\n}\n\n// Ejemplo correcto (aplicando DIP)\nclass CorrectExample {\n    interface Switchable {\n        fun turnOn()\n        fun turnOff()\n    }\n    \n    class LightBulb : Switchable {\n        override fun turnOn() {\n            println(\"LightBulb: Bulb turned on...\")\n        }\n        \n        override fun turnOff() {\n            println(\"LightBulb: Bulb turned off...\")\n        }\n    }\n    \n    class Fan : Switchable {\n        override fun turnOn() {\n            println(\"Fan: Fan started...\")\n        }\n        \n        override fun turnOff() {\n            println(\"Fan: Fan stopped...\")\n        }\n    }\n\n    class ElectricPowerSwitch(private val device: Switchable) {\n        private var isOn = false\n        \n        fun press() {\n            isOn = if (isOn) {\n                device.turnOff()\n                false\n            } else {\n                device.turnOn()\n                true\n            }\n        }\n    }\n}\n\n// Sistema de notificaciones (Desafío extra)\ninterface NotificationService {\n    fun send(message: String)\n}\n\nclass EmailNotification : NotificationService {\n    override fun send(message: String) {\n        println(\"Sending Email: $message\")\n    }\n}\n\nclass PushNotification : NotificationService {\n    override fun send(message: String) {\n        println(\"Sending Push Notification: $message\")\n    }\n}\n\nclass SMSNotification : NotificationService {\n    override fun send(message: String) {\n        println(\"Sending SMS: $message\")\n    }\n}\n\nclass NotificationSystem(private val services: List<NotificationService>) {\n    fun notify(message: String) {\n        services.forEach { it.send(message) }\n    }\n}\n\nfun main() {\n    println(\"Incorrect Example (Violating DIP):\")\n    val incorrectBulb = IncorrectExample.LightBulb()\n    val incorrectSwitch = IncorrectExample.ElectricPowerSwitch(incorrectBulb)\n    incorrectSwitch.press()\n    incorrectSwitch.press()\n    \n    println(\"\\nCorrect Example (Following DIP):\")\n    val correctBulb = CorrectExample.LightBulb()\n    val correctSwitch1 = CorrectExample.ElectricPowerSwitch(correctBulb)\n    correctSwitch1.press()\n    correctSwitch1.press()\n    \n    val fan = CorrectExample.Fan()\n    val correctSwitch2 = CorrectExample.ElectricPowerSwitch(fan)\n    correctSwitch2.press()\n    correctSwitch2.press()\n    \n    println(\"\\nNotification System (Extra Challenge):\")\n    val notificationSystem = NotificationSystem(listOf(\n        EmailNotification(),\n        PushNotification(),\n        SMSNotification()\n    ))\n    notificationSystem.notify(\"Hello, this is a test notification!\")\n}"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/kotlin/rikmij.kt",
    "content": "fun main() {\n    //Uso incorrecto\n    class Worker(val name: String) {\n        fun toWork() = \"Soy $name y estoy trabajando\"\n    }\n\n    class Proyect(val nameProyect: String) {\n        fun workinProyect(): String {\n            val workerName = Worker(\"John\")\n            return \"${workerName.name} está trabajando en $nameProyect\"\n        }\n    }\n    val proy = Proyect(\"Google\")\n    println(proy.workinProyect())\n    /*\n    Aquí incumplimos el DIP porque vemos que el proyecto depende del trabajador, y si cambiara el trabajador\n    el proyecto se rompe, y eso no debe ocurrir\n     */\n\n    //Uso correcto\n    abstract class Department {\n        abstract fun work(): String\n    }\n\n    class Employee(val name: String): Department() {\n        override fun work() = \"Soy $name y estoy trabajando\"\n    }\n\n    class Project(val project: String): Department() {\n        override fun work() = \"El departamento está trabajando en $project\"\n    }\n    val emp = Employee(\"John\")\n    println(emp.work())\n    val proj = Project(\"BushiGPT\")\n    println(proj.work())\n    /*\n    Aquí sí se cumple porque depende de una interfaz, algo abstracto, y si cambia tendrá que\n    cambiar en todas sus implementaciones\n     */\n\n    println(\"\\n ${\"*\".repeat(7)} EJERCICIO EXTRA ${\"*\".repeat(7)}\")\n    class Email: SendNotif {\n        override fun sendNotification(user: String): String {\n            print(\"Para: \")\n            val dest = readln()\n            print(\"Asunto: \")\n            val subject = readln()\n            print(\"Mensaje: \")\n            val text = readln()\n\n            return \"from: $user \\nto: $dest\\nasunto: $subject\\n $text\"\n        }\n    }\n\n    class Push: SendNotif {\n        override fun sendNotification(user: String): String {\n            print(\"Mensaje: \")\n            val text = readln()\n\n            return \"@$user\\n $text\"\n        }\n    }\n\n    class SMS: SendNotif {\n        override fun sendNotification(user: String): String {\n            print(\"Mensaje: \")\n            val text = readln()\n\n            return \"to: $user\\n $text\"\n        }\n    }\n\n    fun sendMessage() {\n        println(\"¿Qué tipo de notificación quieres mandar?\\n\" +\n                \"1.- Correo\\n\" +\n                \"2.- Notificación Push\\n\" +\n                \"3.- SMS\")\n        val option = readln().toInt()\n\n        when (option) {\n            1 -> println(Email().sendNotification(\"ejemplo@prueba.com\"))\n            2 -> println(Push().sendNotification(\"TipodeIncognito\"))\n            3 -> println(SMS().sendNotification(\"123456789\"))\n        }\n    }\n    sendMessage()\n}\n\ninterface SendNotif {\n    fun sendNotification(user: String): String\n}\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/ocaml/luishendrix92.ml",
    "content": "open Printf\n\n(******************************************************************************)\n(*                                                                            *)\n(*                       Dependency Inversion Principle                       *)\n(*                                                                            *)\n(*  DIP is the strategy of depending upon interfaes or abstract functions     *)\n(*  and classes rather than upon concrete functions and classes. A good rule  *)\n(*  to apply is that higher-level components should not depend on a lower     *)\n(*  level component, and they should also work in isolation. DIP tells us     *)\n(*  that every dependency in the design should target an interface or an      *)\n(*  abstract class. Furthermore, a dependency should not target a concrete    *)\n(*  class. It's also worth noting that {e Dependency Injection} is just a     *)\n(*  vehicle to achieve the inversion of control.                              *)\n(*                                                                            *)\n(******************************************************************************)\n\nmodule LowLevelModule = struct\n  let do_something () = print_endline \"LLM Doing something...\"\nend\n\nmodule HighLevelModule = struct\n  (** [LowLevelSubModule] is tightly coupled with the high-level module.\n      This breaks the DIP and should be abstracted with a functor instead. *)\n  module LowLevelSubModule = LowLevelModule\n\n  let say_hello () =\n    print_endline \"Hello from HLM, submodule does something:\";\n    LowLevelModule.do_something ()\n  ;;\nend\n\nlet _ = HighLevelModule.say_hello ()\n\nmodule type AbstractModule = sig\n  val do_something : unit -> unit\nend\n\nmodule ConcreteModule : AbstractModule = struct\n  let do_something () = print_endline \"ConcreteModule does something...\"\nend\n\nmodule DIP_HLM_Functor (AM : AbstractModule) : sig\n  val say_hello : unit -> unit\nend = struct\n  (** [ASM] is an injected dependency module that implements the\n      [AbstractModule] pseudointerface.*)\n  module ASM = AM\n\n  let say_hello () =\n    print_endline \"Hello from a DIP-complied HLM!\";\n    print_endline \"The abstract submodule does something:\";\n    ASM.do_something ()\n  ;;\nend\n\nmodule DIP_Compliant = DIP_HLM_Functor (ConcreteModule)\n\nlet _ =\n  print_newline ();\n  (* Sealing [DIP_Compliant] with a module signature allows us to make the\n     abstract submodule (dependency) private, just like in OOP. *)\n  DIP_Compliant.say_hello ()\n;;\n\n(* Here's how it's done with classes in OCaml. *)\n\nclass type abstraction = object\n  method operation : unit\nend\n\nclass low_level_class : abstraction =\n  object\n    method operation = print_endline \"Low-level class operation/method\"\n  end\n\nclass high_level_class (dependency' : abstraction) =\n  object\n    val dependency = dependency'\n\n    method use_dependency =\n      print_endline \"High level class uses its injected dependency:\";\n      dependency#operation\n  end\n\nlet _ =\n  let hlo = new high_level_class (new low_level_class) in\n  print_newline ();\n  hlo#use_dependency\n;;\n\n(*\n   DIFICULTAD EXTRA (opcional):\n   Crea un sistema de notificaciones.\n   Requisitos:\n   1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas).\n   2. El sistema de notificaciones no puede depender de las implementaciones específicas.\n   Instrucciones:\n   1. Crea la interfaz o clase abstracta.\n   2. Desarrolla las implementaciones específicas.\n   3. Crea el sistema de notificaciones usando el DIP.\n   3. Desarrolla un código que compruebe que se cumple el principio.\n*)\n\nmodule type Notifier = sig\n  val id : string\n  val notify : string -> string -> unit\nend\n\nmodule EmailService : Notifier = struct\n  let address = \"luishendrix92@gmail.com\"\n  let id = \"EMAILER\"\n\n  let notify msg destination =\n    print_endline \"Email sent:\\n--------------------------\";\n    printf \"From: %s\\n\" address;\n    printf \"To: %s\\n\" destination;\n    print_endline msg\n  ;;\nend\n\nmodule NotificationManager (N : Notifier) : sig\n  val create_and_send : string -> string -> unit\nend = struct\n  module NotificationService = N\n\n  let create_and_send msg destination =\n    printf\n      \"Sending [%s] to [%s] via %s...\\n\"\n      msg\n      destination\n      NotificationService.id;\n    NotificationService.notify msg destination\n  ;;\nend\n\n(* We can inject an existing module that satisfies the interface: *)\nmodule EmailNotificationManager = NotificationManager (EmailService)\n\n(* OR... we can  also inject anonymous modules in-line: *)\nmodule SMSNotificationManager = NotificationManager (struct\n    let id = \"TelcelSMS\"\n    let phone_number = \"664-563-7778\"\n\n    let notify msg destination =\n      print_endline \"SMS sent:\\n--------------------------\";\n      printf \"To: [[ %s ]]\\n\" destination;\n      printf \"Text message: %s\\n\" msg;\n      printf \"From: [[ %s ]]\\n\" phone_number\n    ;;\n  end)\n\nmodule UbuntuNotificationCenter = NotificationManager (struct\n    let id = \"UbuntuNotifications\"\n\n    let notify msg destination =\n      printf \"Application: %s\\n\" destination;\n      print_endline msg\n    ;;\n  end)\n\nlet _ =\n  print_newline ();\n  EmailNotificationManager.create_and_send\n    \"Hello, how are you? Let's meet soon\"\n    \"friend@hotmail.com\";\n  print_newline ();\n  SMSNotificationManager.create_and_send \"Did you buy milk?\" \"664-121-4442\";\n  print_newline ();\n  UbuntuNotificationCenter.create_and_send\n    \"Currently playing: Los Lobos - La Bamba\"\n    \"Spotify\"\n;;\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/php/kerunaru.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Kerunaru\\Wrong;\n\nuse PDO;\n\nclass PdoMysqlUserRepository\n{\n\tprivate PDO $db = null;\n\n\tpublic function __construct()\n\t{\n\t\t// NOTE: Aquí pasan varias cosas: por un lado hay una dependencia funcional entre el PdoMysqlUserRepository y\n\t\t// la clase PDO de PHP pero ya que el PdoMysqlUserRepository es una envoltura de PDO es algo asumible dada la\n\t\t// naturaleza de la clase.\n\t\t//\n\t\t// Por otro lado, lo que no es asumible es que sea el repositorio el que instancie la clase PDO. Este diseño\n\t\t// presenta dos problemas: los parámetros de conexión estén escritos a fuego y hace que el código sea más\n\t\t// complicado de testear debido a la imposibilidad de falsear la conexión a la base de datos.\n\t\t$this->db = new PDO('mysql:host=localhost;dbname=kerunaru', 'root', 'password');\n\t}\n}\n\nclass GetUserUseCase\n{\n\tprivate PdoMysqlUserRepository $userRepository = null;\n\n\tpublic function __construct()\n\t{\n\t\t// NOTE: Aquí pasa algo similar a lo que ocurre en el repositorio. La clase GetUserUseCase tiene una\n\t\t// dependencia funcional con PdoMysqlUserRepository pero no debería ser la responsable de instanciarla.\n\t\t$this->userRepository = new PdoMysqlUserRepository();\n\t}\n}\n\nnamespace Kerunaru\\Right;\n\nuse PDO;\n\ninterface UserRepository\n{\n}\n\nclass PdoMysqlUserRepository implements UserRepository\n{\n\tpublic function __construct(\n\t\tprivate PDO $db\n\t) {\n\t}\n}\n\nclass GetUserUseCase\n{\n\tpublic function __construct(\n\t\tprivate UserRepository $userRepository\n\t) {\n\t}\n}\n\n// NOTE: Para instanciar el caso de uso, necesitamos pasarle una instancia de UserRepository la cual necesita de un Pdo.\n// Con esta solución, podemos falsear, no solo la conexión a la base de datos, sino también el propio caso de uso y hacer\n// que el código sea más testeable. Además de separar las responsabilidades de cada clase y hacer que el mantenimiento\n// del código sea más sostenible en el tiempo (si en el futuro cambiamos la base de datos, solo necesitamos cambiar la\n// el PdoMysqlUserRepository por otra implementación y no la instanciación dentro del propio caso de uso).\n$useCase = new GetUserUseCase(\n\tnew PdoMysqlUserRepository(\n\t\t// NOTE: Los parámetros de conexión a la base de datos se deberían cargar desde el entorno\n\t\tnew PDO('mysql:host=' . $_ENV['DB_HOST'] . ';dbname=' . $_ENV['DB_NAME'], $_ENV['DB_USER'], $_ENV['DB_PASS'])\n\t)\n);\n\nnamespace Kerunaru\\NotificationSystem;\n\ninterface Notification\n{\n\tpublic function send(string $message): void;\n}\n\nclass EmailNotification implements Notification\n{\n\tpublic function send(string $message): void\n\t{\n\t\techo 'Email sent: ' . $message . PHP_EOL;\n\t}\n}\n\nclass PushNotification implements Notification\n{\n\tpublic function send(string $message): void\n\t{\n\t\techo 'Push notification sent: ' . $message . PHP_EOL;\n\t}\n}\n\nclass SmsNotification implements Notification\n{\n\tpublic function send(string $message): void\n\t{\n\t\techo 'SMS sent: ' . $message . PHP_EOL;\n\t}\n}\n\nclass NotificationSystem\n{\n\tpublic function __construct(\n\t\tprivate Notification $notification\n\t) {\n\t}\n\n\tpublic function notify(string $message): void\n\t{\n\t\t$this->notification->send($message);\n\t}\n}\n\n$notificationSystem = new NotificationSystem(new EmailNotification());\n$notificationSystem->notify('Hello, world!');\n\n$notificationSystem = new NotificationSystem(new PushNotification());\n$notificationSystem->notify('Hello, world!');\n\n$notificationSystem = new NotificationSystem(new SmsNotification());\n$notificationSystem->notify('Hello, world!');\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/php/miguelex.php",
    "content": "<?php\n\n// Ejemplo de código que viola el principio de inversión de dependencias\n\nclass CreditCardPayment {\n    public function process($amount) {\n\n        echo \"Procesando pago de $amount con tarjeta de crédito\\n\";\n    }\n}\n\nclass PaymentProcessor {\n    private $paymentMethod;\n\n    public function __construct() {\n        $this->paymentMethod = new CreditCardPayment();\n    }\n\n    public function processPayment($amount) {\n        $this->paymentMethod->process($amount);\n    }\n}\n\n// Uso\necho \"\\n\\nEjemplo de mala implementacion\\n\\n\";\n$paymentProcessor = new PaymentProcessor();\n$paymentProcessor->processPayment(100);\n\n?>\n\n\n<?php\n\n// Ejemplo de codigo que cumple el principio de inversion de dependencias\ninterface PaymentMethodInterface {\n    public function process($amount);\n}\n\n// Implementación concreta de la interfaz\nclass CreditCardPayment2 implements PaymentMethodInterface {\n    public function process($amount) {\n\n        echo \"Procesando pago de $amount con tarjeta de crédito\\n\";\n    }\n}\n\nclass PayPalPayment implements PaymentMethodInterface {\n    public function process($amount) {\n        // Lógica para procesar el pago con PayPal\n        echo \"Procesando pago de $amount con PayPal\\n\";\n    }\n}\n\nclass PaymentProcessor2 {\n    private $paymentMethod;\n\n    public function __construct(PaymentMethodInterface $paymentMethod) {\n        $this->paymentMethod = $paymentMethod;\n    }\n\n    public function processPayment($amount) {\n        $this->paymentMethod->process($amount);\n    }\n}\n\necho \"\\n\\nEjemplo correcto\\n\\n\";\n$creditCardPayment = new CreditCardPayment2();\n$paymentProcessor = new PaymentProcessor2($creditCardPayment);\n$paymentProcessor->processPayment(100);\n\necho \"\\n\\nAhora probemos usando paypal\\n\\n\";\n$paypalPayment = new PayPalPayment();\n$paymentProcessor = new PaymentProcessor2($paypalPayment);\n$paymentProcessor->processPayment(200);\n\n// Ejercicio extra\n\ninterface NotificationInterface {\n    public function send($message, $recipient);\n}\n\nclass EmailNotification implements NotificationInterface {\n    public function send($message, $recipient) {\n        // Lógica para enviar un correo electrónico\n        echo \"Enviando email a $recipient: $message\\n\";\n    }\n}\n\nclass PushNotification implements NotificationInterface {\n    public function send($message, $recipient) {\n        // Lógica para enviar una notificación push\n        echo \"Enviando notificación push a $recipient: $message\\n\";\n    }\n}\n\nclass SMSNotification implements NotificationInterface {\n    public function send($message, $recipient) {\n        // Lógica para enviar un SMS\n        echo \"Enviando SMS a $recipient: $message\\n\";\n    }\n}\n\nclass NotificationService {\n    private $notificationMethod;\n\n    // Inyección de la dependencia a través del constructor\n    public function __construct(NotificationInterface $notificationMethod) {\n        $this->notificationMethod = $notificationMethod;\n    }\n\n    public function notify($message, $recipient) {\n        $this->notificationMethod->send($message, $recipient);\n    }\n}\n\necho \"\\n\\nEjercicio extra\\n\\n\";\n\n$emailNotification = new EmailNotification();\n$pushNotification = new PushNotification();\n$smsNotification = new SMSNotification();\n\n// Crear el servicio de notificaciones con diferentes métodos\n$emailService = new NotificationService($emailNotification);\n$pushService = new NotificationService($pushNotification);\n$smsService = new NotificationService($smsNotification);\n\n// Enviar notificaciones utilizando el servicio\n$emailService->notify(\"Hola, mundo!\", \"usuario@example.com\");\n$pushService->notify(\"Tienes una nueva actualización\", \"usuario123\");\n$smsService->notify(\"Tu código de verificación es 123456\", \"666666666\");\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/python/Aldroide.py",
    "content": "\"\"\"\n    Explora el principio SOLID fde Inversión de Dependencias(Dependency Inversion\n    Principle, DIP)\" y crea un ejemplo simple donde se muestre su funcionamiento \n    de forma correcta e incorrecta.\n\"\"\"\n\n# Forma Sin DIP\n\n\nfrom abc import ABC, abstractmethod\n\n\nclass Switch:\n    def turn_on(self):\n        print(\"Enciende la lampara\")\n\n    def turn_off(self):\n        print(\"Apaga la lampara\")\n\n\nclass Lamp:\n    def __init__(self) -> None:\n        self.switch = Switch()\n\n    def operate(self, command):\n        if command == \"on\":\n            self.switch.turn_on()\n        elif command == \"off\":\n            self.switch.turn_off()\n\n\nlamp = Lamp()\nlamp.operate(\"on\")\nlamp.operate(\"off\")\n\n# Con DIP\n\n\nclass AbstractSwitch:\n    def turn_on(self):\n        pass\n\n    def turn_off(self):\n        pass\n\n\nclass LampSwitch(AbstractSwitch):\n\n    def turn_on(self):\n        print(\"Enciende la lampara\")\n\n    def turn_off(self):\n        print(\"Apaga la lampara\")\n\n\nclass Lamp:\n\n    def __init__(self, switch: AbstractSwitch) -> None:\n        self.switch = switch\n\n    def operate(self, command):\n        if command == \"on\":\n            self.switch.turn_on()\n        elif command == \"off\":\n            self.switch.turn_off()\n\n\nlamp = Lamp(LampSwitch())\nlamp.operate(\"on\")\nlamp.operate(\"off\")\n\n\n\"\"\"\nExtra\n\"\"\"\n\n\nclass Notifier(ABC):\n\n    def send(self, message: str):\n        pass\n\n\nclass EmailNotifier(Notifier):\n    def send(self, message: str):\n        print(f\"Enviando email con texto: {message}\")\n\n\nclass PUSHNotifier(Notifier):\n    def send(self, message: str):\n        print(f\"Enviando Push con texto: {message}\")\n\n\nclass SMSNotifier(Notifier):\n    def send(self, message: str):\n        print(f\"Enviando SMS con texto: {message}\")\n\n\nclass NotificationService:\n\n    def __init__(self, notifier: Notifier) -> None:\n        self.notifier = notifier\n\n    def notify(self, message: str):\n        self.notifier.send(message)\n\n\nservice = NotificationService(EmailNotifier())\nservice.notify(\"hola notificador\")\nservice = NotificationService(PUSHNotifier())\nservice.notify(\"hola notificador\")\nservice = NotificationService(SMSNotifier())\nservice.notify(\"hola notificador\")\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/python/BastianAlq.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Inversión de Dependencias (Dependency Inversion\n * Principle, DIP)\" y crea un ejemplo simple donde se muestre su funcionamiento \n * de forma correcta e incorrecta.\n\n\"\"\"\n\n\n\"\"\"\n# ------------------------------------------\n# |   DEPENDENCY INVERSION PRINCIPLE (DIP)  |  Información extraída de -> https://devexpert.io/principios-solid-guia-gratis/ \n# ------------------------------------------\n# \n# Las clases de alto nivel no deberían depender de las clases de bajo\n# nivel. Ambas deberían depender de las abstracciones.\n# \n# Las abstracciones no deberían depender de los detalles. Los detalles\n# deberían depender de las abstracciones.\n# \n# \n# ¿CÓMO DETECTAR QUE ESTAMOS VIOLANDO EL PRINCIPIO DE INVERSION DE DEPENDENCIAS?\n# - cualquier instanciación de clases complejas o modulos es una violacion a este principio\n# - cuando no se pueda probar una clase con facilidad porque depende del codigo de otra clase\n#  \n#  SOLUCION: Utilizar alguna alternativa para suministrarle dependencias (constructor, setters, inyector de dependencias) \n\"\"\"\n\n\n# DEPENDENCY INVERSION PRINCIPLE FORMA INCORRECTA\n\nclass Shopping:\n    def __init__(self) -> None:\n        pass\n\n\"\"\"\nShoppingBasket incumple el principio ya que depende de clases de bajo nivel como CreditCard y SqlDatabase\n\n- ¿que pasa si queremos guardar la informacion en un servidor en vez de la base de datos?\n- ¿que pasa si queremos agregar otros medios de pago?\n\nRespuesta: se desmontaria toda la logica\n\"\"\"\nclass ShoppingBasket:\n    def buy(self, shopping: Shopping):\n        db = SqlDatabase()\n        db.save(shopping)\n        creditCard =  CreditCard()\n        creditCard.pay()\n\nclass SqlDatabase:\n    def save(self, shopping: Shopping):\n        print(\"Guardando en base de datos\")\n\nclass CreditCard:\n    def pay(self, shopping: Shopping):\n        print(\"Pago utilizando tarjeta de credito\")\n\n\n# DEPENDENCY INVERSION PRINCIPLE FORMA CORRECTA\n\"\"\"\nSolución: dejar de depender de concresiones.\nse crearán interfaces que definan el comportamiento que debe dar una clase\npara poder funcionar como mecanismo de persistencia o como metodo de pago.\n\"\"\"\n\nfrom abc import ABC, abstractmethod\n\n# Clase que actua como interface para definir metodo de persistencia\nclass Persistence(ABC):\n    @abstractmethod\n    def save(self, shopping: Shopping):\n        pass\n\nclass PaymentMethod(ABC):\n    @abstractmethod\n    def pay(self, shopping: Shopping):\n        pass\n\nclass SqlDatabase(Persistence):\n    def save(self, shopping: Shopping):\n        print(\"Guardando los datos en la Base de datos\")\n\nclass Server(Persistence):\n    def save(self, shopping: Shopping):\n        print(\"Guardando los datos en el servidor\")\n\nclass CreditCard(PaymentMethod):\n    def pay(self, shopping: Shopping):\n        print(\"Se ha hecho el pago con tarjeta de credito\")\n\nclass DebitCard(PaymentMethod):\n    def pay(self, shopping: Shopping):\n        print(\"Se ha hecho el pago con tarjeta de debito\")\n\nclass ShoppingBasket:\n    \n    def __init__(self, persistence: Persistence, paymentMethod: PaymentMethod) -> None:\n        self.persistence = persistence\n        self.paymentMethod = paymentMethod\n    \n    @property\n    def persistence(self):\n        return self._persistence\n    \n    @property\n    def paymentMethod(self):\n        return self._paymentMethod\n    \n    @persistence.setter\n    def persistence(self,persistence: Persistence):\n        self._persistence = persistence\n    \n    @paymentMethod.setter\n    def paymentMethod(self, paymentMethod: PaymentMethod):\n        self._paymentMethod = paymentMethod\n\n    def buy(self, shopping: Shopping):\n        self.persistence.save(shopping)\n        self.paymentMethod.pay(shopping)\n\ndef testDependencyInversion(shopping):\n    shoppingBasket = ShoppingBasket(SqlDatabase(), DebitCard())\n    shoppingBasket.buy(shopping)\n    \n    shoppingBasket.paymentMethod = CreditCard()\n    shoppingBasket.persistence = Server()\n    shoppingBasket.buy(shopping)\n    \n\ntestDependencyInversion(Shopping())\n\n\n\"\"\"\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un sistema de notificaciones.\n * Requisitos:\n * 1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas).\n * 2. El sistema de notificaciones no puede depender de las implementaciones específicas.\n * Instrucciones:\n * 1. Crea la interfaz o clase abstracta.\n * 2. Desarrolla las implementaciones específicas.\n * 3. Crea el sistema de notificaciones usando el DIP.\n * 4. Desarrolla un código que compruebe que se cumple el principio.\n */\n\"\"\"\n\nprint(\" ----------------- Dificultad Extra ------------------------\")\n\nfrom abc import ABC, abstractmethod\n\nclass Notifier(ABC):\n    @abstractmethod\n    def send(self, to: str, msg: str):\n        pass\n\nclass Email(Notifier):\n    def send(self, to: str, msg: str):\n        print(f\"se ha enviado un Email a {to}.\")\n        print(f\"Contenido: {msg}\")\n\nclass Sms(Notifier):\n    def send(self, to: str, msg: str):\n        print(f\"se ha enviado un SMS a {to}.\")\n        print(f\"Contenido: {msg}\")\n\nclass Push(Notifier):\n    def send(self, to: str, msg: str):\n        print(f\"se ha enviado una notificacion PUSH a {to}.\")\n        print(f\"Contenido: {msg}\")\n\n\nclass NotificationService():\n    def __init__(self,notifier: Notifier ) -> None:\n        self.notifier = notifier\n    \n    @property\n    def notifier(self):\n        return self._notifier\n    \n    @notifier.setter\n    def notifier(self, notifier):\n        self._notifier = notifier\n    \n    def sendMsg(self, to: str,msg: str):\n        self.notifier.send(to,msg)\n        \n\ndef comprobarDependencyInversion():\n    system = NotificationService(Sms())\n    system.sendMsg(\"Martin\", \"Hola martin, un gusto\")\n    \n    system.notifier = Email()\n    system.sendMsg(\"Martin\", \"Hola martin, un gusto\")\n    \n    system.notifier = Push()\n    system.sendMsg(\"Martin\", \"Hola martin, un gusto\")\n\n\ncomprobarDependencyInversion()"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/python/CesarCarmona30.py",
    "content": "'''\n  EJERCICIO\n'''\n\n# Sin DIP\n\nclass Keyboard:\n  def get_input(self):\n    return \"User input from keyboard\"\n  \nclass Computer:\n  def __init__(self) -> None:\n    self.keyboard = Keyboard()\n\n  def collect_input(self):\n    return self.keyboard.get_input()\n  \n# computer = Computer()\n# print(computer.collect_input())\n\n# Con DIP\n\nfrom abc import ABC, abstractmethod\n\nclass InputDevice(ABC):\n  @abstractmethod\n  def get_input(self):\n    pass\n\nclass Keyboard(InputDevice):\n  def get_input(self):\n    return \"User input from keyboard\"\n  \nclass Computer:\n  def __init__(self, input_device: InputDevice):\n    self.input_device = input_device\n\n  def collect_input(self):\n    return self.input_device.get_input()\n  \nkeyboard = Keyboard()\ncomputer = Computer(keyboard)\nprint(computer.collect_input())\n\nclass Mouse(InputDevice):\n  def get_input(self):\n    return \"User input from mouse\"\n\nmouse = Mouse()\ncomputer = Computer(mouse)\nprint(computer.collect_input())\n\n'''\n  EXTRA\n'''\n\nclass Notifier(ABC):\n  @abstractmethod\n  def notify(self, to, message):\n    pass\n\nclass EmailService(Notifier):\n  def notify(self, to, message):\n    print(\"Sending email to {to}: {message}\")\n  \nclass SMSService(Notifier):\n  def notify(self, to, message):\n    print(f\"Sending SMS to {to}: {message}\")\n  \nclass PUSHService(Notifier):\n  def notify(self, to, message):\n    print(f\"Sending PUSH to {to}: {message}\")\n\nclass Notification:\n  def __init__(self, notifier: Notifier):\n    self.notifier = notifier\n\n  def send_notification(self, user, message):\n    self.notifier.notify(user, message)\n\n\ndef test_services():\n  email_service = EmailService()\n  sms_service = SMSService()\n  push_service = PUSHService()\n\n  notification = Notification(email_service)\n  notification.send_notification(\"pedro@gmail.com\", \"Hola. ¿Cómo estás?\")\n  notification = Notification(sms_service)\n  notification.send_notification(\"5555555555\", \"Hola, espero te encuentres bien.\")\n  notification = Notification(push_service)\n  notification.send_notification(\"Leroy\", \"Hola amigo\")\n\ntest_services()"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/python/Chrisdev00.py",
    "content": "\"\"\"\n* EJERCICIO:\n* Explora el \"Principio SOLID de Inversión de Dependencias (Dependency Inversion\n* Principle, DIP)\" y crea un ejemplo simple donde se muestre su funcionamiento \n* de forma correcta e incorrecta.\n*\n* DIFICULTAD EXTRA (opcional):\n* Crea un sistema de notificaciones.\n* Requisitos:\n* 1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas).\n* 2. El sistema de notificaciones no puede depender de las implementaciones específicas.\n* Instrucciones:\n* 1. Crea la interfaz o clase abstracta.\n* 2. Desarrolla las implementaciones específicas.\n* 3. Crea el sistema de notificaciones usando el DIP.\n* 4. Desarrolla un código que compruebe que se cumple el principio.\n*/\n\"\"\"\n\n# Forma incorrecta de aplicar el principio DIP\n\nclass SQLStorage:\n    def save_user(self, user:dict):\n        print(f\"Guardando usuario en SQL: {user}\")\n\nclass UsersService:\n    def __init__(self):\n        self.storage = SQLStorage()   # dependencia directa\n\n    def user_register(self, name: str, email: str):\n        user = {\"nombre\": name, \"email\": email}\n        self.storage.save_user(user)\n\nservice = UsersService()\nservice.user_register(\"Juan\", \"juan@example.com\")\n\n\n# Forma Correcta de aplicar el principio DIP\n\nfrom abc import ABC, abstractmethod\n\nclass AlmacenamientoUsuarios(ABC):\n    @abstractmethod\n    def save_user(self, user: dict):\n        pass\n\nclass AlmacenamientoSQL(AlmacenamientoUsuarios):\n    def save_user(self, user: dict):\n        print(f\"Guardando usuario en SQL: {user}\")\n\nclass AlmacenamientoNoSQL(AlmacenamientoUsuarios):\n    def save_user(self, user: dict):\n        print(f\"Guardando usuario en NoSQL: {user}\")\n\nclass ServicioUsuarios:\n    def __init__(self, almacenamiento: AlmacenamientoUsuarios):\n        self.almacenamiento = almacenamiento\n\n    def user_register(self, name: str, email: str):\n        user = {\"nombre\": name, \"email\": email}\n        self.almacenamiento.save_user(user)\n\nalmacenamiento_sql = ServicioUsuarios(AlmacenamientoSQL())\nalmacenamiento_sql.user_register(\"Juan\", \"juan@example.com\")\n\nalmacenamiento_nosql = ServicioUsuarios(AlmacenamientoNoSQL())\nalmacenamiento_nosql.user_register(\"Pedro\", \"pedro@example.com\")\n\n\n##################### --------------------------- EXTRA --------------------------------- ########################\n\nfrom abc import ABC, abstractmethod\n\nclass Notifier(ABC):\n    @abstractmethod\n    def send_notify(self, recipient: str, message: str):\n        pass\n\nclass NotificacionByEmail(Notifier):\n    def send_notify(self, recipient: str, message: str):\n        print(f\"Enviando email a {recipient} con el mensaje: {message}\")\n\nclass NotificacionBySMS(Notifier):\n    def send_notify(self, recipient: str, message: str):\n        print(f\"Enviando sms a {recipient} con el mensaje: {message}\")\n\nclass NotificacionByPush(Notifier):\n    def send_notify(self, recipient: str, message: str):\n        print(f\"Enviando push a {recipient} con el mensaje: {message}\")\n\nclass NotificationService:\n    def __init__(self, notification: Notifier):\n        self.notification = notification\n\n    def send_notification(self, recipient: str, message: str):\n        self.notification.send_notify(recipient, message)\n\nnotification_email = NotificationService(NotificacionByEmail())\nnotification_email.send_notification(\"user@example.com\", \"Hola, este es un message por email\")\n\nnotification_sms = NotificationService(NotificacionBySMS())\nnotification_sms.send_notification(\"user@example.com\", \"Hola, esta es una notificaion por sms\")\n\nnotification_push = NotificationService(NotificacionByPush())\nnotification_push.send_notification(\"user@example.com\", \"Hola, esta es una notificacion via push\")"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/python/EmmanuelMMontesinos.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Inversión de Dependencias (Dependency Inversion\n * Principle, DIP)\" y crea un ejemplo simple donde se muestre su funcionamiento \n * de forma correcta e incorrecta.\n */\n\"\"\"\n'Sin Aplicar'\nclass Saludo:\n    def accion(self):\n        print(\"Buenos Dias\")\n\nclass Persona:\n    def __init__(self,saludo:Saludo) -> None:\n        self.saludo = saludo\n    \n# Prueba\nyo = Persona(Saludo())\nyo.saludo.accion()\n\n'Aplicado'\nclass Interacion:\n    def accion(self):\n        pass\n\nclass Saludo(Interacion):\n    def accion(self):\n        print(\"Buenos dias\")\n\nclass Insulto(Interacion):\n    def accion(self):\n        print(\"Eres un Pechso Lata\")\n\nclass Persona:\n    def __init__(self,interacion:Interacion) -> None:\n        self.interacion = interacion\n    \nyo = Persona(Saludo())\notro = Persona(Insulto())\n\nyo.interacion.accion()\notro.interacion.accion()\nprint()\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un sistema de notificaciones.\n * Requisitos:\n * 1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas).\n * 2. El sistema de notificaciones no puede depender de las implementaciones específicas.\n * Instrucciones:\n * 1. Crea la interfaz o clase abstracta.\n * 2. Desarrolla las implementaciones específicas.\n * 3. Crea el sistema de notificaciones usando el DIP.\n * 4. Desarrolla un código que compruebe que se cumple el principio.\n\"\"\"\nclass Notificacion:\n    def enviar(self):\n        pass\n\nclass Email(Notificacion):\n    def __init__(self,mail) -> None:\n        self.mail = mail\n    def enviar(self):\n        print(f\"Enviando un Email a {self.mail}\")\n\nclass Push(Notificacion):\n    def __init__(self,push) -> None:\n        self.push = push\n    \n    def enviar(self):\n        print(f\"Haciendo Push a {self.push}\")\n\nclass Sms(Notificacion):\n    def __init__(self,tlf) -> None:\n        self.tlf = tlf\n\n    def enviar(self):\n        print(f\"Enviando SMS al telefono {self.tlf}\")\n\nclass Aviso:\n    def __init__(self,notificacion) -> None:\n        self.notificacion = notificacion\n\n# Prueba\ndef test_notificacion():\n    email = Aviso(Email(\"emmanuelmmontesinos@gmail.com\"))\n    push = Aviso(Push(\"github@EmmanuelMMontesinos\"))\n    sms = Aviso(Sms(\"666555444\"))\n\n    email.notificacion.enviar()\n    push.notificacion.enviar()\n    sms.notificacion.enviar()\n\ntest_notificacion()"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/python/Gordo-Master.py",
    "content": "# 30 - Solid DIP (Dependency Inversion Principle), Principio de inversión de dependecia\n\n# Se basa en dos puntos:\n# 1- Las dependencias deben estar en abstracciones, no en detalles. (Las de alto nivel emplean abstracciones, y las de bajo nivel las implementan).\n# 2- Los modulos de alto nivel no deben depender de modulos de bajo nivel. Sino que ambos deben depender de abstracciones.\n\n\n\"\"\"\nForma incorrecta\n\"\"\"\n\n\"\"\"\nclass MailService:\n    def send_email(self, destination, subject, messenge):\n        print(f\"Enviando correo a {destination}: {subject}\\n{messenge}\")\n\nclass NotificationSystem:\n    def __init__(self):\n        self.mail_service = MailService()\n\n    def send_notification(self, destination, messenge): \n        self.mail_service.send_email(destination,\"Notificación\",messenge)\n\"\"\"\n\n\n\"\"\"\nForma correcta y ejercicio extra\n\"\"\"\n\nfrom abc import ABC, abstractmethod\n\nclass NotificationService(ABC):\n\n    @abstractmethod\n    def send(self, destination, messenge):\n        pass\n\nclass MailService(NotificationService):\n\n    def send(self, destination, messenge):\n        print(f\"Enviando correo a {destination}: \\n{messenge}\")\n\nclass SMSService(NotificationService):\n\n    def send(self, destination, messenge):\n        print(f\"Enviando SMS a {destination}: \\n{messenge}\")\n\nclass PushService(NotificationService):\n\n    def send(self, destination, messenge):\n        print(f\"Enviando PUSH a {destination}: \\n{messenge}\")\n\nclass NotificationSystem:\n    \n    def __init__(self, service: NotificationService):\n        self.service = service\n\n    def send_notification(self, destination, messenge):\n        self.service.send(destination, messenge)\n\nsystem_1 = NotificationSystem(MailService())\n\nsystem_2 = NotificationSystem(SMSService())\n\nsystem_3 = NotificationSystem(PushService())\n\ndef test():\n    system_1.send_notification(\"user_1@user.com\",\"Tienes una nueva notificación\")\n    system_2.send_notification(\"user_2@user.com\", \"Tienes un nuevo SMS\")\n    system_3.send_notification(\"user_1@user.com\", \"Tienes una nueva Push\")\n\ntest()\n\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/python/JesusWay69.py",
    "content": "import os, platform\nfrom abc import ABC, abstractmethod\n\nif (platform.platform().startswith(\"macOS\") or platform.platform().startswith(\"Linux\")):\n    os.system('clear')\nelse:\n    os.system('cls')\n\n\"\"\" \n * EJERCICIO:\n * Explora el \"Principio SOLID de Inversión de Dependencias (Dependency Inversion\n * Principle, DIP)\" y crea un ejemplo simple donde se muestre su funcionamiento \n * de forma correcta e incorrecta.\n *\n\"\"\"\n\n\n\"\"\"\nEl Principio de Inversión de Dependencia (DIP) establece que las clases de alto nivel\n no deben depender de clases de bajo nivel.\nEn el siguiente caso no se cumple el principio ya que hay una clase Fruta que establece la\nespecie de fruta y la impresión con la lógica para que el artículo en el mensaje se adapte a\nsi la especie de fruta se nombre con género masculino o femenino y a su vez las clases que crean\nobjetos de esos tipos de fruta sólo setean su nombre heradando de Fruta que crea todo el trabajo\"\"\"\n\nclass Fruit:\n    def __init__(self, object) -> None:\n        self.object = object\n        self.name = object.name\n\n    def print_fruit(self):\n        self.article = \"un\"\n        \n        if self.object.name.endswith('a'):\n            self.article = \"una\"\n        print (f\"La fruta es {self.article} {self.name} \")\n        \nclass Pear(Fruit):\n    def __init__(self) -> None:\n        self.name = \"pera\"\n\nclass Apple(Fruit):\n    def __init__(self) -> None:\n        self.name = \"manzana\"\n\nclass Melon(Fruit):\n    def __init__(self) -> None:\n        self.name = \"melón\"\n\n \npera = Fruit(Pear()).print_fruit()\nmelon = Fruit(Melon()).print_fruit()\nmanzana = Fruit(Apple()).print_fruit()\n\n\"\"\"En el siguiente caso creamos 2 clases abstractas, una que establece el seteo del nombre\ny otra que gestiona la impresión, las clases que generen objetos de tipos de fruta heredan\nde ambas clases abstractas , setean su nombre y sólo llaman a sus métodos que son comunes a todas la frutas.\"\"\"\n\nclass FruitDIP(ABC):\n    @abstractmethod\n    def set_name(self, name):\n        self.name = name\nclass PrintFruitDIP(ABC):\n    @abstractmethod\n    def print_fruit(self):\n        self.article = \"un\"\n        if self.name.endswith('a'):\n            self.article = \"una\"\n        print (f\"La fruta es {self.article} {self.name} \")\n\nclass Orange(FruitDIP, PrintFruitDIP):\n    name = \"naranja\"\n    def set_name(self, name):\n        return super().set_name(name)\n    def print_fruit(self):\n        return super().print_fruit()\n    \nclass WaterMelon(FruitDIP, PrintFruitDIP):\n    name = \"sandía\"\n    def set_name(self, name):\n        return super().set_name(name)\n    def print_fruit(self):\n        return super().print_fruit()\n    \nclass Lemon(FruitDIP, PrintFruitDIP):\n    name = \"limón\"\n    def set_name(self, name):\n        return super().set_name(name)\n    def print_fruit(self):\n        return super().print_fruit()\n    \nnaranja = Orange().print_fruit()\nsandia = WaterMelon().print_fruit()\nlimon = Lemon().print_fruit()\n\n\"\"\"En Python el concepto de clase abstracta o interface es algo ambiguo, en el caso mostrado las clases\nFruitDIP y PrintFruitDIP se pueden interpretar como clases abstractas ya que aunque todos sus métodos sean\nabstractos y por lo tanto es obligatorio implementarlos en las clases que hereden de esas clases ya tienen\nsu lógica y por lo tanto es más adecuado interpretarlas como clases abstractas, en otros lenguajes como Java\nla declaración de interface se hace tal cual y no permite crear lógica alguna en los métodos que se declaren dentro\nde la misma, además se pueden crear clases abstractas como tal y en este caso sí se pueden crear métodos con lógica\ny llamarlos desde las clases que hereden de la clase abstracta con la particularidad de que no permite la herencia\nmúltiple de varias clases abstractas pero sí de varias interfaces, por ello Python permite mayor flexibilidad pero \ntambien puede crear mayor confusión en estructuras de clases\"\"\"\n\n    \n\"\"\" \n * DIFICULTAD EXTRA (opcional):\n * Crea un sistema de notificaciones.\n * Requisitos:\n * 1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas).\n * 2. El sistema de notificaciones no puede depender de las implementaciones específicas.\n * Instrucciones:\n * 1. Crea la interfaz o clase abstracta.\n * 2. Desarrolla las implementaciones específicas.\n * 3. Crea el sistema de notificaciones usando el DIP.\n * 4. Desarrolla un código que compruebe que se cumple el principio.\"\"\"\n\n\nclass MessageInterface(ABC):\n    @abstractmethod\n    def email(self):\n        pass\n    @abstractmethod\n    def push(self):\n        pass\n    @abstractmethod\n    def sms(self):\n        pass\n\nclass SendNotification(MessageInterface):\n\n    def email(self, message):\n        self.message = message\n        print (self.message , \"--> Enviando email...\")\n    def push(self,message):\n        self.message = message\n        print (self.message, \"--> Enviando push...\")\n    def sms(self,message):\n        self.message = message\n        print (self.message,\"--> Enviando SMS...\")\n\nclass Confirmation(MessageInterface): \n    def email(self, message):\n        self.message = message\n        print (self.message,\"--> Email enviado\")\n    def push(self,message):\n        self.message = message\n        print (self.message,\"--> Mensaje PUSH enviado\")\n    def sms(self,message):\n        self.message = message\n        print (self.message,\"--> Mensaje SMS enviado\")\n    \nclass Email(SendNotification, Confirmation):\n    def __init__(self):\n        self.message = \"Esto es un mensaje de email...\"\n        super().email(self.message)\n    def confirmation(self):\n        super(SendNotification,self).email(self.message)\n\nclass Push(SendNotification, Confirmation):\n    def __init__(self):\n        self.message = \"Esto es un mensaje PUSH...\"\n        return super().push(self.message)\n    def confirmation(self):\n        super(SendNotification,self).push(self.message)\n    \nclass Sms(SendNotification, Confirmation):\n    def __init__(self):\n        self.message = \"Esto es un mensaje SMS...\"\n        return super().sms(self.message)\n    def confirmation(self):\n        super(SendNotification,self).sms(self.message)\n    \nemail = Email()\nemail.confirmation()\npush = Push()\npush.confirmation()\nsms = Sms()\nsms.confirmation()\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/python/JheisonQuiroga.py",
    "content": "# Author: Jheison Duban Quiroga Quintero\n# Github: https://github.com/JheisonQuiroga\n\n\"\"\"\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Inversión de Dependencias (Dependency Inversion\n * Principle, DIP)\" y crea un ejemplo simple donde se muestre su funcionamiento \n * de forma correcta e incorrecta.\"\"\"\n\n# Violación del DIP\n\nclass MySQLDatabase:\n    \"\"\"Simulación de una base de datos MySQL\"\"\"\n    def save(self, data):\n        print(f\"Guardando  {data} en la base de datos MySQL...\")\n\n# Módulo de alto nivel, depende de un módulo de bajo nivel.\nclass OrderProcessor:\n    def __init__(self) -> None:\n        self.db = MySQLDatabase() # Implementación o dependencia concreta\n    def process_order(self, order):\n        self.db.save(order)\n\n# OrderProcessor depende de MySQLDatabase el cual es un detalle técnico o implementación especifica\n# si cambiamos de base de datos, OrderProcessor no funcionará, por ende habrá que modificarlo.\n\n# Siguiendo el DIP\nfrom abc import ABC, abstractmethod\n\n# Definimos una abstracción (interfaz/clase abstracta)\nclass Database(ABC):\n    @abstractmethod\n    def save(self, data):\n        pass\n\n# Módulo de alto nivel depende de una abstracción\nclass OrderProcessor:\n    def __init__(self, db: Database) -> None:\n        self.db = db # Inyección de dependencia por constructor\n\n    def proccess_order(self, order):\n        self.db.save(order)\n\n# Implementación concreta de la abstracción en módulo de bajo nivel\nclass MySQLDatabase(Database):\n    def save(self, data):\n        print(f\"Guardando {data} en la base de datos MySQL...\")\n\nclass MongoDBDatabase(Database):\n    def save(self, data):\n        print(f\"Guardando {data} en la base de datos MongoDB...\")\n\nclass PostgreSQLDatabase(Database):\n    def save(self, data):\n        print(f\"Guardando {data} en la base de datos PostgreSQL...\")\n\n\"\"\"\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un sistema de notificaciones.\n * Requisitos:\n * 1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas).\n * 2. El sistema de notificaciones no puede depender de las implementaciones específicas.\n * Instrucciones:\n * 1. Crea la interfaz o clase abstracta.\n * 2. Desarrolla las implementaciones específicas.\n * 3. Crea el sistema de notificaciones usando el DIP.\n * 4. Desarrolla un código que compruebe que se cumple el principio.\n */\n\"\"\"\n\nfrom abc import ABC, abstractmethod\nfrom dataclasses import dataclass\nfrom datetime import datetime\n\n\n@dataclass\nclass Notification:\n    \"\"\"Clase que representa una notificación\"\"\"\n    message: str\n    recipient: str\n    timestamp: datetime = datetime.now()\n\n# Abstracción para el envio de las notificaciones\nclass NotificationSender(ABC):\n    \"\"\"Interfaz para el envio de las notificaciones\"\"\"\n    @abstractmethod\n    def send(self, notification: Notification) -> None:\n        \"\"\"Envia la notificación\"\"\"\n        pass\n\n# Implementaciones concretas o especificas\nclass EmailNotificationSender(NotificationSender):\n    def send(self, notification: Notification) -> None:\n        print(\n            f\"Enviando Email a {notification.recipient}: {notification.message} - {notification.timestamp}\"\n            )\n        \nclass PushNotificationSender(NotificationSender):\n    def send(self, notification: Notification) -> None:\n        print(f\"Enviando Push a {notification.recipient}:\" \n            f\"{notification.message} - {notification.timestamp}\"\n            )\n        \nclass SMSNotificationSender(NotificationSender):\n    def send(self, notification: Notification) -> None:\n        print(f\"Enviando SMS a {notification.recipient}:\" \n            f\"{notification.message} - {notification.timestamp}\"\n            )\n        \n# Sistema de notificaciones - Módulo de alto nivel(depende de la abstracción)\nclass NotificationSystem:\n    def __init__(self, notifier: NotificationSender):\n        self.notifier = notifier    # Inyección de dependencias por constructor\n    \n    def send(self, notification: Notification):\n        self.notifier.send(notification)\n\n# Test de la implementación\ndef test_notification_system(notification: Notification, notifier: NotificationSender):\n    notification_system = NotificationSystem(notifier)\n    notification_system.send(notification)\n\n# Caso de uso\n\nif __name__ == \"__main__\":\n    \n    # Creando una notificación\n    notification1 = Notification(\n        message=\"Hola, este es un mensaje de prueba.\",\n        recipient=\"Duban Quiroga\"\n    )\n    \n    # Creando los notificadores\n    email = EmailNotificationSender()\n    push = PushNotificationSender()\n    sms = SMSNotificationSender()\n\n    # Enviando la notificación\n    for notifier in [email, push, sms]:\n        test_notification_system(notification1, notifier)"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/python/LucasRebuffo.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Inversión de Dependencias (Dependency Inversion\n * Principle, DIP)\" y crea un ejemplo simple donde se muestre su funcionamiento \n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un sistema de notificaciones.\n * Requisitos:\n * 1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas).\n * 2. El sistema de notificaciones no puede depender de las implementaciones específicas.\n * Instrucciones:\n * 1. Crea la interfaz o clase abstracta.\n * 2. Desarrolla las implementaciones específicas.\n * 3. Crea el sistema de notificaciones usando el DIP.\n * 4. Desarrolla un código que compruebe que se cumple el principio.\n */ \"\"\"\n\n\"\"\" Paso directo al ejercicio\n    En sisntesis el principio plantea que las clases concretas no pueden depender de otras clases concretas\n    solo pueden depender de clases abstractas.\n    Otra manera de ppantearlo es que las clases de alto nivel no pueden depender de las clases de bajo nivel.\n \"\"\"\n\nfrom abc import ABC, abstractmethod\n\n\nclass AbstractChannel(ABC):\n\n    @abstractmethod\n    def get_channel_message(self) -> str:\n        pass\n\n\nclass SMSChannel(AbstractChannel):\n\n    def get_channel_message(self) -> str:\n        return \"(via SMS)\"\n\n\nclass PUSHChannel(AbstractChannel):\n\n    def get_channel_message(self) -> str:\n        return \"(via PUSH)\"\n\n\nclass EmailChannel(AbstractChannel):\n\n    def get_channel_message(self) -> str:\n        return \"(via Email)\"\n\n\nclass Notificator:\n\n    def __init__(self, channel: AbstractChannel):\n        self.channel = channel\n\n    def get_channel(self) -> str:\n        return self.channel\n\n    def notify(self, notification: str):\n        print(notification, self.get_channel().get_channel_message(), sep=\"\\n\")\n\nnotificator_sms = Notificator(SMSChannel())\nnotificator_push = Notificator(PUSHChannel())\nnotificator_email = Notificator(EmailChannel())\n\nnotificator_email.notify(\"This is a notification\")\nnotificator_push.notify(\"This is a notification\")\nnotificator_sms.notify(\"This is a notification\")"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/python/Nicojsuarez2.py",
    "content": "# #30 SOLID: PRINCIPIO DE INVERSIÓN DE DEPENDENCIAS (DIP)\n> #### Dificultad: Media | Publicación: 22/07/24 | Corrección: 29/07/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Inversión de Dependencias (Dependency Inversion\n * Principle, DIP)\" y crea un ejemplo simple donde se muestre su funcionamiento \n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un sistema de notificaciones.\n * Requisitos:\n * 1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas).\n * 2. El sistema de notificaciones no puede depender de las implementaciones específicas.\n * Instrucciones:\n * 1. Crea la interfaz o clase abstracta.\n * 2. Desarrolla las implementaciones específicas.\n * 3. Crea el sistema de notificaciones usando el DIP.\n * 4. Desarrolla un código que compruebe que se cumple el principio.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/python/SooHav.py",
    "content": "# 30 SOLID: PRINCIPIO DE INVERSIÓN DE DEPENDENCIAS (DIP)\n\n# siguiendo los principios SOLID con los patos .....\n\n# Ejemplo Pato\nfrom abc import ABC, abstractmethod\n\n\nclass Pato (ABC):\n    def __init__(self, tipo):\n        self.tipo = tipo\n\n    @abstractmethod\n    def vuela(self):\n        pass\n\n    @abstractmethod\n    def nada(self):\n        pass\n\n    @abstractmethod\n    def dice(self):\n        pass\n\n\nclass PatoSalvaje(Pato):\n    def __init__(self):\n        super().__init__(\"salvaje\")\n\n    def vuela(self):\n        print(\"El pato salvaje vuela.\")\n\n    def nada(self):\n        print(\"El pato salvaje nada.\")\n\n    def dice(self):\n        print(\"El pato salvaje dice Quack.\")\n\n\nclass PatoDomestico(Pato):\n    def __init__(self):\n        super().__init__(\"domestico\")\n\n    def vuela(self):\n        print(\"El pato doméstico vuela.\")\n\n    def nada(self):\n        print(\"El pato doméstico nada.\")\n\n    def dice(self):\n        print(\"El pato doméstico dice Quack.\")\n\n\nclass PatoPlastico(Pato):\n    def __init__(self):\n        super().__init__(\"plastico\")\n\n    def vuela(self):\n        print(\"El pato de plástico no puede volar.\")\n\n    def nada(self):\n        print(\"El pato de plástico no puede nadar.\")\n\n    def dice(self):\n        print(\"El pato de plástico dice Squeak.\")\n\n\n# Uso\nprint(\"Sin DIP:\\n\")\npato1 = PatoSalvaje()\npato2 = PatoDomestico()\npato3 = PatoPlastico()\n\npato1.vuela()\npato1.nada()\npato1.dice()\n\npato2.vuela()\npato2.nada()\npato2.dice()\n\npato3.vuela()\npato3.nada()\npato3.dice()\nprint(\"\\n\")\n# Ejemplo Pato con DIP\n# clases abstractas con acciones que puede hacer un pato\n\n\nclass Volador(ABC):\n    @abstractmethod\n    def vuela(self):\n        pass\n\n\nclass Nadador(ABC):\n    @abstractmethod\n    def nada(self):\n        pass\n\n\nclass Hablador(ABC):\n    @abstractmethod\n    def dice(self):\n        pass\n\n\nclass Flotador(ABC):\n    @abstractmethod\n    def flota(self):\n        pass\n\n\nclass Tipo(ABC):\n    @abstractmethod\n    def tipo(self):\n        pass\n\n# Implementaciones concretas de las acciones de los patos\n\n\nclass VuelaConAlas(Volador):\n    def vuela(self):\n        print(\"Vuela con alas.\")\n\n\nclass NadaEnLago(Nadador):\n    def nada(self):\n        print(\"Nada en el lago.\")\n\n\nclass DiceQuack(Hablador):\n    def dice(self):\n        print(\"Dice Quack.\")\n\n\nclass DiceQuick(Hablador):\n    def dice(self):\n        print(\"Dice Quick.\")\n\n\nclass FlotaEnBañadera(Flotador):\n    def flota(self):\n        print(\"Flota en la bañadera.\")\n\n\nclass TipoPato(Tipo):\n    def __init__(self, tipo):\n        self._tipo = tipo\n\n    def tipo(self):\n        print(f\"Es un {self._tipo}.\")\n\n# Implementación en las distintas clases de patos\n\n\nclass PatoSalvaje:\n    def __init__(self, tipo: Tipo, volador: Volador, nadador: Nadador, hablador: Hablador):\n        self._tipo = tipo\n        self.volador = volador\n        self.nadador = nadador\n        self.hablador = hablador\n\n    def tipo(self):\n        self._tipo.tipo()\n\n    def vuela(self):\n        self.volador.vuela()\n\n    def nada(self):\n        self.nadador.nada()\n\n    def dice(self):\n        self.hablador.dice()\n\n\nclass PatoDomestico:\n    def __init__(self, tipo: Tipo, nadador: Nadador, hablador: Hablador):\n        self._tipo = tipo\n        self.nadador = nadador\n        self.hablador = hablador\n\n    def tipo(self):\n        self._tipo.tipo()\n\n    def nada(self):\n        self.nadador.nada()\n\n    def dice(self):\n        self.hablador.dice()\n\n\nclass PatoPlastico:\n    def __init__(self, tipo: Tipo, hablador: Hablador, flotador: Flotador):\n        self._tipo = tipo\n        self.hablador = hablador\n        self.flotador = flotador\n\n    def tipo(self):\n        self._tipo.tipo()\n\n    def dice(self):\n        self.hablador.dice()\n\n    def flota(self):\n        self.flotador.flota()\n\n\n# Uso\nprint(\"Con DIP:\\n\")\nvuela_con_alas = VuelaConAlas()\nnada_en_lago = NadaEnLago()\ndice_quack = DiceQuack()\ndice_quick = DiceQuick()\nflota_en_bañadera = FlotaEnBañadera()\n\ntipo_salvaje = TipoPato(\"Pato Salvaje\")\ntipo_domestico = TipoPato(\"Pato Domestico\")\ntipo_plastico = TipoPato(\"Pato de Plastico\")\n\npato4 = PatoSalvaje(tipo_salvaje, vuela_con_alas, nada_en_lago, dice_quack)\npato5 = PatoDomestico(tipo_domestico, nada_en_lago, dice_quack)\npato6 = PatoPlastico(tipo_plastico, dice_quick, flota_en_bañadera)\n\npato4.tipo()\npato4.vuela()\npato4.nada()\npato4.dice()\n\npato5.tipo()\npato5.nada()\npato5.dice()\n\npato6.tipo()\npato6.dice()\npato6.flota()\nprint(\"\\n\")\n# Dificultad Extra\n# Clase notificación\n\n\nclass Notificacion(ABC):\n    @abstractmethod\n    def enviar(self, mensaje: str):\n        pass\n\n# Implementaciones concretas de tipos de notificaciones\n\n\nclass NotificacionEmail(Notificacion):\n    def enviar(self, mensaje: str):\n        print(f\"Enviando Email: {mensaje}\")\n\n\nclass NotificacionPush(Notificacion):\n    def enviar(self, mensaje: str):\n        print(f\"Enviando Notificación Push: {mensaje}\")\n\n\nclass NotificacionSMS(Notificacion):\n    def enviar(self, mensaje: str):\n        print(f\"Enviando SMS: {mensaje}\")\n\n# Sistema para las notificaciones\n\n\nclass Sistema_Notificacion:\n    def __init__(self, notificador: Notificacion):\n        self.notificador = notificador\n\n    def notificar(self, mensaje: str):\n        self.notificador.enviar(mensaje)\n\n\n# Uso\nprint(\"Dificultad Extra:\\n\")\nnotificacion_email = NotificacionEmail()\nnotificacion_push = NotificacionPush()\nnotificacion_sms = NotificacionSMS()\n\nenvio1 = Sistema_Notificacion(notificacion_email)\nenvio2 = Sistema_Notificacion(notificacion_push)\nenvio3 = Sistema_Notificacion(notificacion_sms)\n\nenvio1.notificar(\"Hola este es un correo electrónico\")\nenvio2.notificar(\"Hola este es un push\")\nenvio3.notificar(\"Hola este es un sms\")\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/python/Trufoplus.py",
    "content": "### EJERCICIO: PRINCIPIO DE INVERSIÓN DE DEPENDENCIAS (DIP)\n# Sin aplicar DIP\nclass Worker:\n    def broke_stone(self):\n        print('Broking Stone...')\n\nclass Job:\n    def __init__(self):\n        self.worker = Worker()\n    \n    def do_task(self):\n        self.worker.broke_stone()\n\n\n#USO\nprint('Sin Dip: ')\ndani = Job()\ndani.do_task()\nprint()\n\n\n\n#Aplicando DIP\nfrom abc import ABC, abstractmethod\n\n# Interfaz para los trabajadores\nclass Worker(ABC):\n    @abstractmethod\n    def do_task(self):\n        pass\n\n# Implementación concreta de Worker para romper piedras  \nclass Miner(Worker):\n    def do_task(self):\n        print('Broking Stone...')\n\n# Implementación concreta de Worker para recolectar plantas\nclass Gatherer(Worker):\n    def do_task(self):\n        print('Gathering plants...')\n\nclass Job:\n    def __init__(self, worker: Worker):\n        self.worker = worker\n    \n    def do_task(self):\n        self.worker.do_task()\n\n# USO\nminer = Miner()\nminer_work = Job(miner)\nminer_work.do_task()\n\n# Cambiando el tipo de tarea sin modificar Tasks\ngatherer = Gatherer()\ngatherer_work = Job(gatherer)\ngatherer_work.do_task()\n\n\n\n\n\n###############################################################################\n### DIFICUTAD EXTRA\n###############################################################################\n\n# Interfaz para los sistemas de notificación\nclass NotifySystem(ABC):\n    @abstractmethod\n    def send_notify(self):\n        pass\n\n# Implementación concreta de NotifySystem para enviar correos electrónicos\nclass Email(NotifySystem):\n    def send_notify(self):\n        print('Sending an email...')\n\n# Implementación concreta de NotifySystem para enviar notificaciones push\nclass Push(NotifySystem):\n    def send_notify(self):\n        print('Sending a push...')\n\n# Implementación concreta de NotifySystem para enviar mensajes SMS\nclass SMS(NotifySystem):\n    def send_notify(self):\n        print('Sending an SMS...')\n\n# Clase principal que usa la interfaz NotifySystem\nclass NotifySystemMain:\n    def __init__(self, notify_system: NotifySystem):\n        self.notify_system = notify_system\n    \n    def send_notify(self):\n        self.notify_system.send_notify()\n\n# USO\nemail = Email()\nnotify_email = NotifySystemMain(email)\nnotify_email.send_notify()\n\npush = Push()\nnotify_push = NotifySystemMain(push)\nnotify_push.send_notify()\n\nsms = SMS()\nnotify_sms = NotifySystemMain(sms)\nnotify_sms.send_notify()\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/python/adra-dev.py",
    "content": "\"\"\"\nEJERCICIO:\nExplora el \"Principio SOLID de Inversión de Dependencias (Dependency \nInversion Principle, DIP)\" y crea un ejemplo simple donde se muestre \nsu funcionamiento de forma correcta e incorrecta.\n\nDIFICULTAD EXTRA(opcional):\nCrea un sistema de notificaciones.\n\nRequisitos:\n1. El sistema puede enviar Email, PUSH y SMS (implementaciones \nespecíficas).\n2. El sistema de notificaciones no puede depender de las \nimplementaciones específicas.\nInstrucciones:\n1. Crea la interfaz o clase abstracta.\n2. Desarrolla las implementaciones específicas.\n3. Crea el sistema de notificaciones usando el DIP.\n4. Desarrolla un código que compruebe que se cumple el principio.\n\nby adra-dev\n\"\"\"\n\n\"\"\"\nDependency Inversion Principle (DIP):\nEl principio de inversión de dependencias (DIP) es el último \nprincipio del conjunto SOLID. Este principio establece que:\n\n    \"Las abstracciones no deben depender de detalles. Los detalles \n    deben depender de las abstracciones.\"\n\ndocumentacion:\"https://realpython.com/solid-principles-python/\"\n    \nConsidera el siguiente ejemplo: \nSupongamos que está creando una aplicación y tiene una clase FrontEnd\npara mostrar datos a los usuarios de una manera amigable. Actualmente, \nla aplicación obtiene sus datos de una base de datos, por lo que \ntermina con el siguiente código\n\"\"\"\n\n# app_dip.py\n\nclass FrontEnd:\n    def __init__(self, back_end):\n        self.back_end = back_end\n\n    def display_data(self):\n        data = self.back_end.get_data_from_database()\n        print(\"Display data:\", data)\n\nclass BackEnd:\n    def get_data_from_database(self):\n        return \"Data from the database\"\n    \n\"\"\"\nEn este ejemplo, la clase FrontEnd depende de la clase BackEnd y de \nsu implementación concreta. Se puede decir que ambas clases están \nestrechamente acopladas. \n\nEste acoplamiento puede dar lugar a problemas de escalabilidad. Por \nejemplo, supongamos que tu aplicación está creciendo rápidamente y \nquieres que pueda leer datos de una API de REST. ¿Cómo lo harías?\n\nPuede pensar en agregar un nuevo método al backend para recuperar los\ndatos de la API REST. Sin embargo, eso también requerirá que \nmodifique el FrontEnd, que debe estar cerrado a la modificación, de \nacuerdo con el principio de abierto-cerrado. \n\nPara solucionar el problema, puede aplicar el principio de inversión \nde dependencias y hacer que sus clases dependan de abstracciones en \nlugar de implementaciones concretas como BackEnd. En este ejemplo \nespecífico, puede introducir una clase DataSource que proporcione la \ninterfaz que se usará en sus clases concretas:\n\"\"\"\n\n# app_dip.py\n\nfrom abc import ABC, abstractmethod\n\nclass FrontEnd:\n    def __init__(self, data_source):\n        self.data_source = data_source\n\n    def display_data(self):\n        data = self.data_source.get_data()\n        print(\"Display data:\", data)\n\nclass DataSource(ABC):\n    @abstractmethod\n    def get_data(self):\n        pass\n\nclass Database(DataSource):\n    def get_data(self):\n        return \"Data from the database\"\n\nclass API(DataSource):\n    def get_data(self):\n        return \"Data from the API\"\n    \n\n\"\"\"\nEn este rediseño de las clases, se ha agregado una clase DataSource \ncomo una abstracción que proporciona la interfaz necesaria, o el \nmétodo .get_data(). Observe cómo FrontEnd ahora depende de la \ninterfaz proporcionada por DataSource, que es una abstracción.\n\"\"\"\n\ndb_front_end = FrontEnd(Database())\ndb_front_end.display_data()\n\napi_front_end = FrontEnd(API())\napi_front_end.display_data()\n\n\n\"\"\"\nExtra\n\"\"\"\nclass NotificationInterface(ABC):\n    @abstractmethod\n    def get_notification(self):\n        pass\n\nclass Email(NotificationInterface):\n    def get_notification(self):\n        return \"Email notification\"\n\nclass PUSH(NotificationInterface):\n    def get_notification(self):\n        return \"PUSH notification\"\n    \nclass SMS(NotificationInterface):\n    def get_notification(self):\n        return \"SMS notification\"\n\n    \nclass NotificationSystem(ABC):\n    def __init__(self, notification_type):\n        self.notification_type = notification_type\n\n    def display_notification(self):\n        notification = self.notification_type.get_notification()\n        print(\"Display data:\", notification)\n\nnotifiatcion_email = NotificationSystem(Email())\nnotifiatcion_email.display_notification()\nnotifiatcion_push = NotificationSystem(PUSH())\nnotifiatcion_push.display_notification()\nnotifiatcion_sms = NotificationSystem(SMS())\nnotifiatcion_sms.display_notification()"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/python/alanshakir.py",
    "content": "\"\"\"\"\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Inversión de Dependencias (Dependency Inversion\n * Principle, DIP)\" y crea un ejemplo simple donde se muestre su funcionamiento \n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un sistema de notificaciones.\n * Requisitos:\n * 1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas).\n * 2. El sistema de notificaciones no puede depender de las implementaciones específicas.\n * Instrucciones:\n * 1. Crea la interfaz o clase abstracta.\n * 2. Desarrolla las implementaciones específicas.\n * 3. Crea el sistema de notificaciones usando el DIP.\n * 4. Desarrolla un código que compruebe que se cumple el principio.\n */\n\"\"\"\n#SIN DIP\nclass EmailService():\n    def send_email(self, message):\n        print(f\"Enviando email: {message}\")    \n\nclass SMSService():\n    def send_sms(self, message):\n        print(f\"Enviando sms: {message}\")\n\nclass NotificationManager:\n    def __init__(self):\n        self.email_service = EmailService()\n        self.sms_service = SMSService()\n        \n    def notification_manager(self, message):\n        self.email_service = message\n        self.sms_service = message\n\n    def send_notification(self, message):\n        self.email_service.send_email(message)\n        self.sms_service.send_sms(message)\n\nmanager = NotificationManager()\nmanager.send_notification(\"Aprendiendo Python\")\n\n#CON DIP\nfrom abc import ABC, abstractmethod\n\nclass NotificationService(ABC):\n    @abstractmethod\n    def send(self, message):\n        pass\n\nclass EmailService(NotificationService):\n    def send(self, message):\n        print(f\"Enviando email: {message}\")    \n\nclass SMSService(NotificationService):\n    def send(self, message):\n        print(f\"Enviando sms: {message}\")\n\nclass NotificationManager:\n    def __init__(self, service : NotificationService):\n        self.notification_service = service\n        \n    def notification_manager(self, message):\n        self.notification_service = message\n\n    def send_notification(self, message):\n        self.notification_service.send(message)\n\nemail_service = EmailService()\nmanager = NotificationManager(email_service)\nmanager.send_notification(\"Aprendiendo Python\")\n\nsms_service = SMSService()\nmanager = NotificationManager(sms_service)\nmanager.send_notification(\"Aprendiendo Python\")\n\n#Extra\n\nfrom abc import ABC, abstractmethod\n\nclass NotificationService(ABC):\n    @abstractmethod\n    def send(self, message):\n        pass\n\nclass EmailService(NotificationService):\n    def send(self, message):\n        print(f\"Enviando email: {message}\")    \n\nclass PushService(NotificationService):\n    def send(self, message):\n        print(f\"Enviando push: {message}\")  \n\nclass SMSService(NotificationService):\n    def send(self, message):\n        print(f\"Enviando sms: {message}\")\n\nclass NotificationManager:\n    def __init__(self, service : NotificationService):\n        self.notification_service = service\n\n    def send_notification(self, message):\n        self.notification_service.send(message)\n\nmanager = NotificationManager(EmailService())\nmanager.send_notification(\"Aprendiendo Python, ruta de programacion\")\nmanager = NotificationManager(PushService())\nmanager.send_notification(\"Aprendiendo Python, ruta de programacion\")\nmanager = NotificationManager(SMSService())\nmanager.send_notification(\"Aprendiendo Python, ruta de programacion\")\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/python/avcenal.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el \"Principio SOLID de Inversión de Dependencias (Dependency Inversion\n * Principle, DIP)\" y crea un ejemplo simple donde se muestre su funcionamiento \n * de forma correcta e incorrecta.\n\"\"\"\n#INCORRECTO\nclass OtherPaymentService():\n    def paypal_payment(self,quantity:int|float):\n        print(f\"Estas pagando {quantity} EUR a través de Paypal\")\n\n    def stripe_payment(self,quantity:int|float):\n        print(f\"Estas pagando {quantity} EUR a través de Stripe\")\n\nother_payment_service = OtherPaymentService()\nother_payment_service.paypal_payment(255.30)\nother_payment_service.stripe_payment(125.50)\nprint(\"\\n\")\n\n#CORRECTO\nfrom abc import ABC, abstractmethod\n\nclass PaymentService(ABC):\n    @abstractmethod\n    def payment(self,quantity:int|float):\n        pass\n\nclass PayPalPaymentService(PaymentService):\n    def payment(self,quantity:int|float):\n        print(f\"Estas pagando {quantity} EUR a través de Paypal\")\n\nclass StripePaymentService(PaymentService):\n    def payment(self,quantity:int|float):\n        print(f\"Estas pagando {quantity} EUR a través de Stripe\")\n\nclass PaymentProcessor():\n    def process_payment(self,payment_service:PaymentService,quantity:int|float):\n        payment_service.payment(quantity)\n\npaypal_payment = PayPalPaymentService()\nstripe_payment = StripePaymentService()\npayment_processor = PaymentProcessor()\npayment_processor.process_payment(payment_service=paypal_payment,quantity=255.30)\npayment_processor.process_payment(payment_service=stripe_payment,quantity=125.50)\nprint(\"\\n\")\n\n\"\"\"\n* DIFICULTAD EXTRA (opcional):\n * Crea un sistema de notificaciones.\n * Requisitos:\n * 1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas).\n * 2. El sistema de notificaciones no puede depender de las implementaciones específicas.\n * Instrucciones:\n * 1. Crea la interfaz o clase abstracta.\n * 2. Desarrolla las implementaciones específicas.\n * 3. Crea el sistema de notificaciones usando el DIP.\n * 4. Desarrolla un código que compruebe que se cumple el principio.\n\"\"\"\nclass MessagingChannel(ABC):\n    @abstractmethod\n    def send_message(self,message:str):\n        pass\n\nclass SMSChannel(MessagingChannel):\n    def send_message(self,message:str):\n        print(f\"Estás enviando a través de SMS el siguiente mensaje:\\n\\\"{message}\\\"\\n\")\n\nclass PushChannel(MessagingChannel):\n    def send_message(self,message:str):\n        print(f\"Estás enviando a través de PUSH el siguiente mensaje:\\n\\\"{message}\\\"\\n\")\n\nclass EmailChannel(MessagingChannel):\n    def send_message(self,message:str):\n        print(f\"Estás enviando a través de PUSH el siguiente mensaje:\\n\\\"{message}\\\"\\n\")\n\nclass NotificationSystem():\n    def send_notification(self,message:str,channel:MessagingChannel):\n        channel.send_message(message)\n\nnotification_system = NotificationSystem()\n\nnotification_system.send_notification(message=\"Alex, ya tienes tu pedido preparado\",channel=SMSChannel())\nnotification_system.send_notification(message=\"Alex, tienes un nuevo mensaje en tu bandeja de entrada\",channel=PushChannel())\nnotification_system.send_notification(message=\"Alex, aquí tienes la newsletter quincenal de la comunidad\",channel=EmailChannel())\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/python/barrancus.py",
    "content": "#30 - Python\n# EJERCICIO:\n# Explora el \"Principio SOLID de Inversión de Dependencias (Dependency Inversion\n# Principle, DIP)\" y crea un ejemplo simple donde se muestre su funcionamiento \n# de forma correcta e incorrecta.\n# \n# DIFICULTAD EXTRA (opcional):\n# Crea un sistema de notificaciones.\n# Requisitos:\n# 1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas).\n# 2. El sistema de notificaciones no puede depender de las implementaciones específicas.\n# Instrucciones:\n# 1. Crea la interfaz o clase abstracta.\n# 2. Desarrolla las implementaciones específicas.\n# 3. Crea el sistema de notificaciones usando el DIP.\n# 4. Desarrolla un código que compruebe que se cumple el principio.\n# \n\nclass Counter:\n    def __iter__(self):\n        self.a = 1\n        return self\n    \n    def __next__(self):\n        x = self.a\n        self.a += 1\n        return x\n\ncontador = iter(Counter())\n\ndef separacion(cadena) -> str:\n    global contador\n    print(f'\\nEjercicio {next(contador)}. {cadena} {'-.-' * 20}')\n\nfrom abc import ABC, abstractmethod\n\n#-----Incorrecto-----\nseparacion('Incorrecto fundamento')\n\nclass SwitchA:\n\n    def turn_on(self)    :\n        print(\"Enciende la lámpara.\")\n\n    def turn_off(self):\n        print(\"Apaga la lámpara.\")\n\nclass LampA:\n\n    def __init__(self) -> None:\n        self.switchA = SwitchA()\n\n    def operate(self, command):\n        if command == \"on\":\n            self.switchA.turn_on()\n        elif command == \"off\":\n            self.switchA.turn_off()\n\nlamp = LampA()\nlamp.operate(\"on\")\nlamp.operate(\"off\")\nlamp.operate(\"True\")\n\n#-----Correcto-----\nseparacion('Correcto fundamento')\n\nclass AbstractSwtich:\n\n    def turn_on(self):\n        pass\n\n    def turn_off(self):\n        pass\n\nclass LampSwitch(AbstractSwtich):\n\n    def turn_on(self):\n        print(\"Enciende la lámpara.\")\n    \n    def turn_off(self):\n        print(\"Apaga la lámpara.\")\n\nclass TVSwitch(AbstractSwtich):\n\n    def turn_on(self):\n        print(\"Enciende la TV.\")\n    \n    def turn_off(self):\n        print(\"Apaga la TV.\")\n\nclass OnOff:\n\n    def __init__(self, switch: AbstractSwtich) -> None:\n        self.switch = switch\n\n    def operate(self, command):\n        if command == \"on\":\n            self.switch.turn_on()\n        elif command == \"off\":\n            self.switch.turn_off()\n\nlamp = OnOff(LampSwitch())\nlamp.operate(\"on\")\nlamp.operate(\"off\")\nlamp.operate(\"True\")\ntelevision = OnOff(TVSwitch())\ntelevision.operate(\"on\")\ntelevision.operate(\"off\")\n\n#-----EXTRA-----\nseparacion('EXTRA')\n\n# Crea un sistema de notificaciones.\n# Requisitos:\n# 1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas).\n# 2. El sistema de notificaciones no puede depender de las implementaciones específicas.\n# Instrucciones:\n# 1. Crea la interfaz o clase abstracta.\n# 2. Desarrolla las implementaciones específicas.\n# 3. Crea el sistema de notificaciones usando el DIP.\n# 4. Desarrolla un código que compruebe que se cumple el principio.\n\nclass AbstractNotification:\n    \n    def send_notification(self):\n        pass\n\nclass EmailNofified(AbstractNotification):\n    \n    def send_notification(self):\n        print('Notificación enviada al e-mail del usuario.')\n\nclass SmsNotified(AbstractNotification):\n\n    def send_notification(self):\n        print('Notificación enviada por SMS al usuario.')\n\nclass PushNotified(AbstractNotification):\n\n    def send_notification(self):\n        print('Notificado al usuario mediante el explorador.')\n\nclass Notified:\n\n    def __init__(self, notified_method: AbstractNotification) -> None:\n        self.notified_method = notified_method\n\n    def send_notification(self):\n        self.notified_method.send_notification()\n\nemail = Notified(EmailNofified())\nsms = Notified(SmsNotified())\npush = Notified(PushNotified())\n\ndef test_send_notified(notified_type):\n    notified_type.send_notification()\n\ntest_send_notified(email)\ntest_send_notified(sms)\ntest_send_notified(push)\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/python/bytecodesky.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * Explora el \"Principio SOLID de Inversión de Dependencias (Dependency Inversion\n#  * Principle, DIP)\" y crea un ejemplo simple donde se muestre su funcionamiento \n#  * de forma correcta e incorrecta.\n#  *\n\n# forma incorrecta de implementar el principio DIP\nclass LightBulb:\n    def turn_on(self):\n        print(\"LightBulb: turned on...\")\n\n    def turn_off(self):\n        print(\"LightBulb: turned off...\")\n\nclass Switch:\n    def __init__(self, bulb: LightBulb):\n        self.bulb = bulb\n\n    def operate(self):\n        self.bulb.turn_on()\n        self.bulb.turn_off()\n\nbulb = LightBulb()\nswitch = Switch(bulb)\nswitch.operate()\n\n# forma correcta de implementar el principio DIP\nclass Switchable:\n    def turn_on(self):\n        pass\n\n    def turn_off(self):\n        pass\n\nclass LightBulb(Switchable):\n    def turn_on(self):\n        print(\"LightBulb: turned on...\")\n\n    def turn_off(self):\n        print(\"LightBulb: turned off...\")\n\nclass Fan(Switchable):\n    def turn_on(self):\n        print(\"Fan: turned on...\")\n\n    def turn_off(self):\n        print(\"Fan: turned off...\")\n\nclass Switch:\n    def __init__(self, device: Switchable):\n        self.device = device\n\n    def operate(self):\n        self.device.turn_on()\n        self.device.turn_off()\n\nbulb = LightBulb()\nswitch = Switch(bulb)\nswitch.operate()\n\nfan = Fan()\nswitch = Switch(fan)\nswitch.operate()\n\n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea un sistema de notificaciones.\n#  * Requisitos:\n#  * 1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas).\n#  * 2. El sistema de notificaciones no puede depender de las implementaciones específicas.\n#  * Instrucciones:\n#  * 1. Crea la interfaz o clase abstracta.\n#  * 2. Desarrolla las implementaciones específicas.\n#  * 3. Crea el sistema de notificaciones usando el DIP.\n#  * 4. Desarrolla un código que compruebe que se cumple el principio.\n#  */\n\nfrom abc import ABC, abstractmethod\nclass Notification(ABC):\n    @abstractmethod\n    def send(self, message: str):\n        pass\n\nclass EmailNotification(Notification):\n    def send(self, message: str):\n        print(f\"EmailNotification: {message}\")\n\nclass PushNotification(Notification):\n    def send(self, message: str):\n        print(f\"PushNotification: {message}\")\n\nclass SMSNotification(Notification):\n    def send(self, message: str):\n        print(f\"SMSNotification: {message}\")\n\nclass NotificationService:\n    def __init__(self, notification: Notification):\n        self.notification = notification\n\n    def send(self, message: str):\n        self.notification.send(message)\n\nemail = EmailNotification()\npush = PushNotification()\nsms = SMSNotification()\n\nservice = NotificationService(email)\nservice.send(\"Hello, Email!\")\n\nservice = NotificationService(push)\nservice.send(\"Hello, Push!\")\n\nservice = NotificationService(sms)\nservice.send(\"Hello, SMS!\")\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/python/cristianfloyd.py",
    "content": "# EJERCICIO:\n# Explora el \"Principio SOLID de Inversión de Dependencias (Dependency Inversion\n# Principle, DIP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n# de forma correcta e incorrecta.\nfrom abc import ABC, abstractmethod\n\n\n# Implementacion incorrecta\nclass MySQLDatabase:\n    \"\"\"Implementacion concreta de una base de datos MySQL\"\"\"\n\n    def connect(self) -> str:\n        return \"Conectando a MySQL...\"\n\n    def save_order(self, order_data: dict) -> str:\n        return f\"Guardando orden: {order_data}\"\n\n\nclass EmailService:\n    \"\"\"Implementacion concreta de un servicio de email\"\"\"\n\n    def send_email(self, to: str, subject: str, body: str) -> str:\n        return f\"Enviando email a {to} con asunto {subject}\"\n\n\nclass GestorPedidos:\n    \"\"\"\n    Clase de alto nivel que depende de implementaciones concretas\n    \"\"\"\n\n    def __init__(self, database):\n        \"\"\"\n        Dependencia directa de implementaciones concretas\n        \"\"\"\n        self.database = MySQLDatabase()\n        self.email_service = EmailService()\n\n    def process_order(self, order_data: dict, customer_email: str) -> None:\n        \"\"\"\n        Logica de negocio mezclada con detalles de implementacion\n        \"\"\"\n        self.database.connect()\n        self.database.save_order(order_data)\n        self.email_service.send_email(\n            customer_email,\n            \"Orden procesada\",\n            \"La orden ha sido procesada correctamente\",\n        )\n\n\n# Implementacion correcta\n# =======================================================\n# Abstracciones\nclass DatabaseInterface(ABC):\n    @abstractmethod\n    def connect(self) -> str:\n        pass\n\n    @abstractmethod\n    def save_order(self, order_data: dict) -> str:\n        pass\n\n\nclass NotificacionInterface(ABC):\n    @abstractmethod\n    def send(self, recipient: str, subject: str, message: str) -> str:\n        pass\n\n\n# implementaciones concretas\nclass MySQLDatabaseV2(DatabaseInterface):\n    \"\"\"Implementacion concreta que depende de la abstraccion\"\"\"\n\n    def connect(self) -> str:\n        return \"Conectando a MySQL...\"\n\n    def save_order(self, order_data: dict) -> str:\n        return f\"Guardando orden: {order_data}\"\n\n\nclass PostgresDatabase(DatabaseInterface):\n    \"\"\"Implementacion concreta que depende de la abstraccion\"\"\"\n\n    def connect(self) -> str:\n        return \"Conectando a Postgres...\"\n\n    def save_order(self, order_data: dict) -> str:\n        return f\"Guardando orden: {order_data}\"\n\n\nclass EmailNotification(NotificacionInterface):\n    \"\"\"Implementacion concreta que depende de la abstraccion\"\"\"\n\n    def send(self, recipient: str, subject: str, message: str) -> str:\n        return f\"Enviando email a {recipient} con asunto {subject}\"\n\n\nclass SmsNotification(NotificacionInterface):\n    \"\"\"Implementacion concreta que depende de la abstraccion\"\"\"\n\n    def send(self, recipient: str, subject: str, message: str) -> str:\n        return f\"Enviando SMS a {recipient} con asunto {subject}\"\n\n\n# =======================================================\n# Modulo de alto nivel\n\n\nclass GestorPedidosV2:\n    \"\"\"\n    Clase de alto nivel que depende de abstracciones\n    Puede trabajar con cualquier implementacion que cumpla con el contrato de la interfaz\n    \"\"\"\n\n    def __init__(\n        self, database: DatabaseInterface, notification: NotificacionInterface\n    ):\n        \"\"\"\n        Dependencia de abstracciones\n        \"\"\"\n        self.database = database\n        self.notification = notification\n\n    def process_order(self, order_data: dict, customer_email: str) -> None:\n        \"\"\"\n        Logica de negocio\n        \"\"\"\n        self.database.connect()\n        self.database.save_order(order_data)\n        print(self.database.connect())\n        print(self.database.save_order(order_data))\n        print(\n            self.notification.send(\n                customer_email,\n                \"Orden procesada\",\n                \"La orden ha sido procesada correctamente\",\n            )\n        )\n        print(\"Orden procesada correctamente\")\n\n\n# Test\ndb_mysql = MySQLDatabaseV2()\nnotif_email = EmailNotification()\ngestor1 = GestorPedidosV2(db_mysql, notif_email)\n\npedido1 = {\"id\": 1234, \"producto\": \"Laptop\", \"cantidad\": 1}\ngestor1.process_order(pedido1, \"cliente@email.com\")\n\n\ndb_postgres = PostgresDatabase()\nnotif_sms = SmsNotification()\ngestor2 = GestorPedidosV2(db_postgres, notif_sms)\n\npedido2 = {\"id\": 5678, \"producto\": \"Mouse\", \"cantidad\": 2}\ngestor2.process_order(pedido2, \"+34612345678\")\n\n\n#\n# DIFICULTAD EXTRA (opcional):\n# Crea un sistema de notificaciones.\n# Requisitos:\n# 1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas).\n# 2. El sistema de notificaciones no puede depender de las implementaciones específicas.\n# Instrucciones:\n# 1. Crea la interfaz o clase abstracta.\n# 2. Desarrolla las implementaciones específicas.\n# 3. Crea el sistema de notificaciones usando el DIP.\n# 4. Desarrolla un código que compruebe que se cumple el principio.\n\n\n# Interfaz de notificacion\nclass NotificadorInterface(ABC):\n    @abstractmethod\n    def send(self, recipient: str, message: str) -> bool:\n        pass\n\n    @abstractmethod\n    def get_notification_type(self) -> str:\n        pass\n\n\n# Implementaciones concretas\nclass NotificadorEmail(NotificadorInterface):\n    def __init__(self, smtp_server: str = \"smtp.gmail.com\"):\n        self.smtp_server = smtp_server\n        self.send_count = 0\n\n    def send(self, recipient: str, message: str) -> bool:\n        try:\n            if \"@\" not in recipient:\n                raise ValueError(\"Email invalido\")\n\n            print(f\"Conectando a {self.smtp_server}\")\n            print(f\"Enviando email a {recipient}\")\n            print(f\"Mensaje: {message}\")\n            print(\"Email enviado exitosamente\")\n            self.send_count += 1\n            return True\n\n        except Exception as e:\n            print(f\"Error al enviar email: {e}\")\n            return False\n\n    def get_notification_type(self) -> str:\n        return \"EMAIL\"\n\n\nclass NotificadorSms(NotificadorInterface):\n    def __init__(self, provider: str = \"twilio\") -> None:\n        self.provider = provider\n        self.send_count = 0\n\n    def send(self, recipient: str, message: str) -> bool:\n        try:\n            if \"+\" not in recipient:\n                raise ValueError(\"Numero de telefono invalido\")\n\n            print(f\"Conectando a {self.provider}\")\n            print(f\"Enviando SMS a {recipient}\")\n            print(f\"Mensaje: {message}\")\n            print(\"SMS enviado exitosamente\")\n            self.send_count += 1\n            return True\n\n        except Exception as e:\n            print(f\"Error al enviar SMS: {e}\")\n            return False\n\n    def get_notification_type(self) -> str:\n        return \"SMS\"\n\n\nclass NotificadorPush(NotificadorInterface):\n    def __init__(self, service: str = \"firebase\") -> None:\n        self.service = service\n        self.send_count = 0\n\n    def send(self, recipient: str, message: str) -> bool:\n        try:\n            if \"app_id\" not in recipient:\n                raise ValueError(\"App ID invalido\")\n\n            print(f\"Conectando a {self.service}\")\n            print(f\"Token del dispositivo: {recipient[:5]}\")\n            print(f\"Enviando Push a {recipient}\")\n            print(f\"Mensaje: {message}\")\n            print(\"Push enviado exitosamente\")\n            self.send_count += 1\n            return True\n\n        except Exception as e:\n            print(f\"Error al enviar Push: {e}\")\n            return False\n\n    def get_notification_type(self) -> str:\n        return \"PUSH\"\n\n\n# =======================================================\n# Modulo de alto nivel\nclass NotificadorService:\n    \"\"\"\n    Clase de alto nivel que depende de abstracciones\n    Puede trabajar con cualquier implementacion que cumpla con el contrato de la interfaz\n    \"\"\"\n\n    def __init__(self) -> None:\n        \"\"\"\n        No rea Notificadores internamente\n        los recibe desde fuera (Inyeccion de dependencias)\n        \"\"\"\n        self._notificadores: list[NotificadorInterface] = []\n        self.count_send = 0\n\n    def registrar_notificador(self, notificador: NotificadorInterface) -> None:\n        \"\"\"\n        Registra un nuevo canal de notificacion\n        \"\"\"\n        self._notificadores.append(notificador)\n        print(f\"Canal de notificacion {notificador.get_notification_type()} registrado\")\n\n    def enviar_todo(self, recipient: str, message: str) -> dict:\n        \"\"\"Envia notificaciones a todos los canales registrados\"\"\"\n        if not self._notificadores:\n            print(\"No hay canales de notificacion registrados\")\n            return {}\n\n        resultados = {}\n        for notificador in self._notificadores:\n            try:\n                resultado = notificador.send(recipient, message)\n                resultados[notificador.get_notification_type()] = resultado\n                if resultado:\n                    self.count_send += 1\n\n            except Exception as e:\n                resultados[notificador.get_notification_type()] = f\"Error: {e}\"\n        return resultados\n\n    def enviar_por_canal(self, canal: str, recipient: str, message: str) -> bool:\n        \"\"\"Envia notificacion por un canal especifico\"\"\"\n        if not self._notificadores:\n            print(\"No hay canales de notificacion registrados\")\n            return False\n\n        for notificador in self._notificadores:\n            if notificador.get_notification_type() == canal.upper():\n                return notificador.send(recipient, message)\n        print(f\"Canal de notificacion {canal} no encontrado\")\n        return False\n\n    def get_registered_channels(self) -> list[str]:\n        \"\"\"Retorna lista de canales registrados\"\"\"\n        return [n.get_notification_type() for n in self._notificadores]\n\n    def get_stats(self) -> dict:\n        \"\"\"Retorna estadísticas del sistema\"\"\"\n        return {\n            \"total_channels\": len(self._notificadores),\n            \"channels\": self.get_registered_channels(),\n            \"total_sent\": self.count_send,\n        }\n\n\n# =======================================================\n# Pruebas\n\n\ndef demostrar_sistema_notificaciones():\n    \"\"\"Demuestra el funcionamiento del sistema de notificaciones\"\"\"\n    print(\"Iniciando sistema de notificaciones\")\n    notificador_service = NotificadorService()\n    print(\"Registrando canales de notificacion\")\n    notificador_service.registrar_notificador(NotificadorEmail())\n    notificador_service.registrar_notificador(NotificadorSms())\n    notificador_service.registrar_notificador(NotificadorPush())\n\n    print(\"Enviando notificaciones a todos los canales\")\n    notificador_service.enviar_todo(\n        \"cliente@email.com\", \"Hola, este es un mensaje de prueba\"\n    )\n    print(\"Enviando notificacion por canal email\")\n    notificador_service.enviar_por_canal(\n        \"email\", \"cliente@email.com\", \"Hola, este es un mensaje de prueba\"\n    )\n    print(\"Enviando notificacion por canal sms\")\n    notificador_service.enviar_por_canal(\n        \"sms\", \"+34612345678\", \"Hola, este es un mensaje de prueba\"\n    )\n    print(\"Enviando notificacion por canal push\")\n    notificador_service.enviar_por_canal(\n        \"push\", \"app_id_1234567890\", \"Hola, este es un mensaje de prueba\"\n    )\n\n    print(\"Mostrando estadisticas del sistema\")\n    print(notificador_service.get_stats())\n\n    print(\"Creando un nuevo notificador 'Telegram'\")\n\n    class NotificadorTelegram(NotificadorInterface):\n        def __init__(self, api_key: str = \"1234567890\") -> None:\n            self.api_key = api_key\n            self.send_count = 0\n\n        def send(self, recipient: str, message: str) -> bool:\n            try:\n                print(f\"Conectando a {self.api_key}\")\n                print(f\"Enviando notificacion a {recipient}\")\n                print(f\"Mensaje: {message}\")\n                print(\"Notificacion enviada exitosamente\")\n                self.send_count += 1\n                return True\n\n            except Exception as e:\n                print(f\"Error al enviar notificacion: {e}\")\n                return False\n\n        def get_notification_type(self) -> str:\n            return \"TELEGRAM\"\n\n    notificador_service.registrar_notificador(NotificadorTelegram())\n\n    print(\"Enviando notificacion por canal telegram\")\n    notificador_service.enviar_por_canal(\n        \"telegram\", \"cliente@telegram.com\", \"Hola, este es un mensaje de prueba\"\n    )\n\n    print(\"Mostrando estadisticas del sistema\")\n    print(notificador_service.get_stats())\n\n\nif __name__ == \"__main__\":\n    demostrar_sistema_notificaciones()\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/python/cyberdidac.py",
    "content": "from abc import ABC, abstractmethod\n\n\nclass MessageService(ABC):\n    @abstractmethod\n    def send_message(self, message: str):\n        pass\n\n\nclass EmailService(MessageService):\n    def send_message(self, message: str):\n        print(f\"Enviando email con mesnaje:\\n\"\n              f\"> {message}\")\n\n\nclass SMSService(MessageService):\n    def send_message(self, message: str):\n        print(f\"Enviando SMS con mensaje:\\n\"\n              f\"> {message}\")\n\n\nclass PUSHService(MessageService):\n    def send_message(self, message: str):\n        print(\"Enviando PUSH con mensaje:\\n\"\n              f\"> {message}\")\n\n\nclass Notification:\n    message_service: MessageService\n\n    def __init__(self, message_service: MessageService):\n        self.message_service = message_service\n\n    def send(self, message: str):\n        self.message_service.send_message(message)\n\n\ndef main():\n    email_service = EmailService()\n    sms_service = SMSService()\n    push_service = PUSHService()\n\n    notification_email = Notification(email_service)\n    notification_sms = Notification(sms_service)\n    notification_push = Notification(push_service)\n\n    notification_email.send(\"Hola desde el EmailService!\")\n    notification_sms.send(\"Hola desde el SMSService!\")\n    notification_push.send(\"Hola desde el PUSHService!\")\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/python/davidrguez98.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Inversión de Dependencias (Dependency Inversion\n * Principle, DIP)\" y crea un ejemplo simple donde se muestre su funcionamiento \n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un sistema de notificaciones.\n * Requisitos:\n * 1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas).\n * 2. El sistema de notificaciones no puede depender de las implementaciones específicas.\n * Instrucciones:\n * 1. Crea la interfaz o clase abstracta.\n * 2. Desarrolla las implementaciones específicas.\n * 3. Crea el sistema de notificaciones usando el DIP.\n * 4. Desarrolla un código que compruebe que se cumple el principio.\n */ \"\"\"\n\n#EJERCICIO\n\n\"\"\" \nIncorrecta\n\"\"\"\n\nclass Switch:\n\n    def turn_on(self):\n        print(\"Enciende la lámpara\")\n\n    def turn_off(self):\n        print(\"Apaga la lámpara\")\n\nclass Lamp:\n\n    def __init__(self):\n        self.switch = Switch()\n\n    def operate(self, command):\n        if command == \"on\":\n            self.switch.turn_on()\n        elif command == \"off\":\n            self.switch.turn_off()\n\nlamp = Lamp()\nlamp.operate(\"on\")\nlamp.operate(\"off\")\n\n\"\"\" \nCorrecta\n\"\"\"\n\nclass AbstractSwitch:\n\n    def turn_on(self):\n        pass\n\n    def turn_off(self):\n        pass\n\nclass LampSwitch(AbstractSwitch):\n\n    def turn_on(self):\n        print(\"Enciende la lámpara\")\n\n    def turn_off(self):\n        print(\"Apaga la lámpara\")\n\nclass Lamp:\n\n    def __init__(self, switch: AbstractSwitch):\n        self.switch = switch\n\n    def operate(self, command):\n        if command == \"on\":\n            self.switch.turn_on()\n        elif command == \"off\":\n            self.switch.turn_off()\n\nlamp  = Lamp(LampSwitch())\nlamp.operate(\"on\")\nlamp.operate(\"off\")\n\n#DIFICULTAD EXTRA\n\nfrom abc import ABC, abstractmethod\n\nclass Notifier(ABC):\n\n    def send(self, message: str):\n        pass\n\nclass EmailNotifier(Notifier):\n    def send(self, message):\n        print(f\"Enviando email con texto: {message}\")\n\nclass PushNotifier(Notifier):\n    def send(self, message):\n        print(f\"Enviando push con texto: {message}\")\n\nclass SMSNotifier(Notifier):\n    def send(self, message):\n        print(f\"Enviando SMS con texto: {message}\")\n\nclass NotificationService:\n\n    def __init__(self, notifier: Notifier):\n        self.notifier = notifier\n\n    def notify(self, message: str):\n        self.notifier.send(message)\n\nservice = NotificationService(EmailNotifier())\nservice.notify(\"Hola!\")\nservice = NotificationService(PushNotifier())\nservice.notify(\"Hola!\")\nservice = NotificationService(SMSNotifier())\nservice.notify(\"Hola!\")"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/python/duendeintemporal.py",
    "content": "#30 { Retos para Programadores } Principio SOLID de Inversión de Dependencias (Dependency Inversion Principle, DIP) \n\n# Bibliography reference:\n# The Web Development Glossary (Jens Oliver Meiert) (Z-Library)\n# I use GPT as a reference and sometimes to correct or generate proper comments.\n\n\"\"\"  \n * EJERCICIO:\n * Explora el \"Principio SOLID de Inversión de Dependencias (Dependency Inversion\n * Principle, DIP)\" y crea un ejemplo simple donde se muestre su funcionamiento \n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un sistema de notificaciones.\n * Requisitos:\n * 1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas).\n * 2. El sistema de notificaciones no puede depender de las implementaciones específicas.\n * Instrucciones:\n * 1. Crea la interfaz o clase abstracta.\n * 2. Desarrolla las implementaciones específicas.\n * 3. Crea el sistema de notificaciones usando el DIP.\n * 4. Desarrolla un código que compruebe que se cumple el principio.\n \n\"\"\"\n\n\"\"\" Dependency Inversion Principle\nA specific form of decoupling software modules. When following this\nprinciple, the conventional dependency relationships established from\nhigh-level policy-setting modules to low-level dependency modules are\nreversed, thus rendering high-level modules independent of the low-level\nmodule implementation details. The principle states 1) that high-level\nmodules should not depend on low-level modules, but that both should\ndepend on abstractions (e.g., interfaces), and 2) that abstractions should\nnot depend on details, but that details (concrete implementations) should\ndepend on abstractions.\n\nA class that contains methods for use by other classes without having to be\nthe parent class of those other classes. How those other classes gain access\nto the mixin’s methods depends on the language. Mixins are sometimes\ndescribed as being “included” rather than “inherited.” Mixins encourage\ncode reuse and can be used to avoid the inheritance ambiguity that\nmultiple inheritance can cause, or to work around lack of support for\nmultiple inheritance in a language. A mixin can also be viewed as an\ninterface with implemented methods. This pattern is an example of\nenforcing the Dependency Inversion Principle \"\"\"\n\n\nlog = print\nlog('Retos para Programadores #30')\n\n# Incorrect Example\n\nclass USABillingService1:\n    def calculate_charge(self, duration):\n        return duration * 0.10  # $0.10 per minute\n\n\nclass CallBillingService1:\n    def __init__(self):\n        self.billing_service = USABillingService1()  # Direct dependency\n\n    def bill_call(self, duration):\n        charge = self.billing_service.calculate_charge(duration)\n        log(f\"Total charge: {charge:.2f}\")\n\n\n# Example usage\ncall_billing_service1 = CallBillingService1()\ncall_billing_service1.bill_call(22)  # Total charge: 2.20\n\n# Correct Example\n\nclass IBillingService:\n    def calculate_charge(self, duration):\n        raise NotImplementedError(\"Method 'calculate_charge()' must be implemented for this Billing Service.\")\n\n\nclass USABillingService(IBillingService):\n    def __init__(self):\n        super().__init__()\n        self.location = 'USA'\n\n    def calculate_charge(self, duration):\n        return duration * 0.10\n\n\nclass EuropeBillingService(IBillingService):\n    def __init__(self):\n        super().__init__()\n        self.location = 'Europe'\n\n    def calculate_charge(self, duration):\n        return duration * 0.15\n\n\nclass AsiaBillingService(IBillingService):\n    def __init__(self):\n        super().__init__()\n        self.location = 'Asia'\n\n    def calculate_charge(self, duration):\n        return duration * 0.05\n\n\nclass CallBillingService:\n    def __init__(self, billing_service):\n        self.billing_service = billing_service  # Dependency injection\n\n    def bill_call(self, duration):\n        charge = self.billing_service.calculate_charge(duration)\n        log(f\"Total charge for {self.billing_service.location}: {charge:.2f}\")\n\n\n# Example usage for billing services\nusa_billing_service = USABillingService()\neurope_billing_service = EuropeBillingService()\nasia_billing_service = AsiaBillingService()\n\ncall_billing_service_usa = CallBillingService(usa_billing_service)\ncall_billing_service_europe = CallBillingService(europe_billing_service)\ncall_billing_service_asia = CallBillingService(asia_billing_service)\n\ncall_billing_service_usa.bill_call(127.22)  # Total charge for USA: 12.72\ncall_billing_service_europe.bill_call(17.56)  # Total charge for Europe: 2.63\ncall_billing_service_asia.bill_call(45.23)  # Total charge for Asia: 2.26\n\n\n# Extra Difficulty Exercise\nclass INotificationService:\n    def send(self, message):\n        raise NotImplementedError(\"Method 'send()' must be implemented in this specific Notification Service.\")\n\n\nclass EmailService(INotificationService):\n    def send(self, message):\n        log(f\"Sending email: {message}\")\n\n\nclass SMSService(INotificationService):\n    def send(self, message):\n        log(f\"Sending SMS: {message}\")\n\n\nclass PushService(INotificationService):\n    def send(self, message):\n        log(f\"Sending PUSH notification: {message}\")\n\n\nclass NotificationSystem:\n    def __init__(self, notification_service):\n        self.notification_service = notification_service\n\n    def notify(self, message):\n        self.notification_service.send(message)\n\n\n# Example usage for notification services\nemail_service = EmailService()\nsms_service = SMSService()\npush_service = PushService()\n\nnotification_system_email = NotificationSystem(email_service)\nnotification_system_sms = NotificationSystem(sms_service)\nnotification_system_push = NotificationSystem(push_service)\n\nnotification_system_email.notify(\"Testing sending a message via Email.\")  # Sending email: Testing sending a message via Email.\nnotification_system_sms.notify(\"Testing sending a message via SMS.\")  # Sending SMS: Testing sending a message via SMS.\nnotification_system_push.notify(\"Testing sending a message via PUSH.\")  # Sending PUSH notification: Testing sending a message via PUSH.\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/python/fborjalv.py",
    "content": "\"\"\"\n* DIFICULTAD EXTRA (opcional):\n * Crea un sistema de notificaciones.\n * Requisitos:\n * 1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas).\n * 2. El sistema de notificaciones no puede depender de las implementaciones específicas.\n * Instrucciones:\n * 1. Crea la interfaz o clase abstracta.\n * 2. Desarrolla las implementaciones específicas.\n * 3. Crea el sistema de notificaciones usando el DIP.\n * 4. Desarrolla un código que compruebe que se cumple el principio.\n\n\"\"\"\nfrom abc import ABC, abstractmethod\n\nclass Notification(ABC):\n    @abstractmethod\n    def enviar(self, emisor, receptor):\n        pass\n\n\nclass Email(Notification):\n    def enviar(self, emisor, receptor):\n        print(f\"Enviando email de {emisor} a {receptor}\")\n\nclass SMS(Notification):\n    def enviar(self, emisor, receptor):\n        print(f\"Enviando SMS de {emisor} a {receptor}\")\n\nclass Push(Notification):\n    def enviar(self, emisor, receptor):\n        print(f\"Enviando push de {emisor} a {receptor}\")\n\n\n\nclass NotificationService: \n    def __init__(self, notification: Notification):\n        self.notification = notification\n    \n    def notificar(self, emisor, receptor):\n        self.notification.enviar(emisor, receptor)\n\n\nservice = NotificationService(Email())\nservice.notificar(\"aaaaaa@gmail.com\", \"bbbbb@gmail.com\")"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/python/franxiscodev.py",
    "content": "'''\nSOLID - DIP\nPrincipio SOLID de Inversión de Dependencias (Dependency Inversion Principle, DIP)\n#\n# El principio de inversión de dependencias establece que las clases de alto nivel no deben depender de las clases de bajo nivel. \n# Ambas deben depender de abstracciones (interfaces o clases abstractas). \n# Además, las abstracciones no deben depender de los detalles, sino que los detalles deben depender de las abstracciones.\n \n'''\n# Sin DIP\n# el switch es una clase de bajo nivel y la bombilla es una clase de alto nivel\n# la bombilla depende del switch, lo que significa que la bombilla no puede funcionar sin el switch\n\n\nfrom abc import ABC, abstractmethod\n\n\nclass Switch:\n\n    def turn_on(self):\n        print(\"encender lámpara\")\n\n    def turn_off(self):\n        print(\"apagar lámpara\")\n\n\nclass Bulb:\n    def __init__(self) -> None:\n        self.switch = Switch()\n\n    def operate(self, command):\n        if command == \"on\":\n            self.switch.turn_on()\n        elif command == \"off\":\n            self.switch.turn_off()\n        else:\n            print(\"comando no válido\")\n\n\nbulb = Bulb()\nbulb.operate(\"on\")\nbulb.operate(\"off\")\nbulb.operate(\"office\")\n\n# con DIP\n\n\nclass AbstractSwitch:\n    def turn_on(self):\n        pass\n\n    def turn_off(self):\n        pass\n\n\nclass BulbSwitch(AbstractSwitch):\n    def turn_on(self):\n        print(\"encender lámpara dip\")\n\n    def turn_off(self):\n        print(\"apagar lámpara dip\")\n\n\nclass Bulb:\n    def __init__(self, switch: AbstractSwitch) -> None:\n        self.switch = switch\n\n    def operate(self, command):\n        if command == \"on\":\n            self.switch.turn_on()\n        elif command == \"off\":\n            self.switch.turn_off()\n        else:\n            print(\"comando no válido dip\")\n\n\n# la bombilla no depende del switch, sino de la abstracción AbstractSwitch\n# y el switch puede ser cualquier clase que implemente la interfaz AbstractSwitch\n# por lo que se puede cambiar el switch sin afectar a la bombilla\n# y la bombilla puede funcionar sin el switch\nbulb = Bulb(BulbSwitch())\nbulb.operate(\"on\")\nbulb.operate(\"off\")\nbulb.operate(\"office\")\n\n# Extra\n\n\nclass Notifier(ABC):\n    @abstractmethod\n    def send(self, message: str):\n        pass\n\n\nclass EmailNotifier(Notifier):\n    def send(self, message: str):\n        print(f\"Enviando correo: {message}\")\n\n\nclass PUSHNotifier(Notifier):\n    def send(self, message: str):\n        print(f\"Enviando PUSH: {message}\")\n\n\nclass SMSNotifier(Notifier):\n    def send(self, message: str):\n        print(f\"Enviando SMS: {message}\")\n\n\nclass NotificationService:\n    def __init__(self, notifier: Notifier) -> None:\n        self.notifier = notifier\n\n    def notify(self, message: str):\n        self.notifier.send(message)\n\n\nservice = NotificationService(EmailNotifier())\nservice.notify(\"Hola mundo x email\")\nservice = NotificationService(PUSHNotifier())\nservice.notify(\"Hola mundo x PUSH\")\nservice = NotificationService(SMSNotifier())\nservice.notify(\"Hola mundo x SMS\")\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/python/hectorio23.py",
    "content": "# Autor: Héctor Adán\n# GitHub: https://github.com/hectorio23\n\nfrom abc import ABC, abstractmethod\n\n# Interfaz para el servicio de notificación\nclass NotificationService(ABC):\n    @abstractmethod\n    def send_notification(self, message: str) -> None:\n        pass\n\n# Implementación específica para Email\nclass EmailNotification(NotificationService):\n    def send_notification(self, message: str) -> None:\n        print(f\"[+] - Enviando Email: {message}\")\n\n# Implementación específica para PUSH\nclass PushNotification(NotificationService):\n    def send_notification(self, message: str) -> None:\n        print(f\"[+] - Enviando Push Notification: {message}\")\n\n# Implementación específica para SMS\nclass SMSNotification(NotificationService):\n    def send_notification(self, message: str) -> None:\n        print(f\"[+] - Enviando SMS: {message}\")\n\n# Sistema de Notificaciones usando DIP\nclass NotificationSystem:\n    def __init__(self):\n        self.services = []\n\n    def add_service(self, service: NotificationService) -> None:\n        self.services.append(service)\n\n    def notify_all(self, message: str) -> None:\n        for service in self.services:\n            service.send_notification(message)\n\n# Función principal para demostrar el DIP\nif __name__ == \"__main__\":\n    # Correcto: El sistema de notificaciones no depende directamente de las implementaciones concretas\n    notification_system = NotificationSystem()\n    \n    notification_system.add_service(EmailNotification())\n    notification_system.add_service(PushNotification())\n    notification_system.add_service(SMSNotification())\n\n    notification_system.notify_all(\"Mensaje de prueba.\")\n\n    # Incorrecto: Dependencia directa de las implementaciones concretas (violación del DIP)\n    email_notification = EmailNotification()\n    email_notification.send_notification(\"Mensaje directo sin sistema de notificaciones.\")\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/python/hozlucas28.py",
    "content": "# pylint: disable=pointless-string-statement,missing-function-docstring,missing-class-docstring,too-few-public-methods,line-too-long\n\nfrom abc import ABCMeta, abstractmethod\nfrom multiprocessing.util import abstract_sockets_supported\n\n\"\"\"\n    Dependency Inversion Principle (DIP)...\n\"\"\"\n\nprint(\"Dependency Inversion Principle (DIP)...\")\n\nprint(\"\\nBad implementation of Dependency Inversion Principle (DIP)...\")\n\n\nclass AbcEmailService(metaclass=ABCMeta):\n    @abstractmethod\n    def send(self, content: str) -> None:\n        pass\n\n\nclass EmailService(AbcEmailService):\n    def send(self, content: str) -> None:\n        print(\"Email with {content=} sent!\")\n\n\nclass AbcBadNotificationService(metaclass=ABCMeta):\n    @abstractmethod\n    def send_email(self, content: str) -> None:\n        pass\n\n\nclass BadNotificationService(AbcBadNotificationService):\n    email_service: EmailService\n\n    def __init__(self) -> None:\n        self.email_service = EmailService()\n\n    def send_email(self, content: str) -> None:\n        self.email_service.send(content=content)\n\n\nprint(\n    \"\\n```\",\n    \"\"\"class AbcEmailService(metaclass=ABCMeta):\n    @abstractmethod\n    def send(self, content: str) -> None:\n        pass\n\n\nclass EmailService(AbcEmailService):\n    def send(self, content: str) -> None:\n        print(\"Email with {content=} sent!\")\n\n\nclass AbcBadNotificationService(metaclass=ABCMeta):\n    @abstractmethod\n    def send_email(self, content: str) -> None:\n        pass\n\n\nclass BadNotificationService(AbcBadNotificationService):\n    email_service: EmailService\n\n    def __init__(self) -> None:\n        self.email_service = EmailService()\n\n    def send_email(self, content: str) -> None:\n        self.email_service.send(content=content)\"\"\",\n    \"```\",\n    sep=\"\\n\",\n)\n\nprint(\n    \"\\nThis is a bad implementation of Dependency Inversion Principle (DIP),\",\n    \"'BadNotificationService' class depends directly on the 'EmailService' class \\n\",\n    \"rather than on an abstract class. So, if the 'email_service attribute in the'\\n\",\n    \"'BadNotificationService' class needs to be changed, the constructor must also be\\n\",\n    \"modified.\",\n    sep=\"\\n\",\n)\n\nprint(\"\\nGood implementation of Dependency Inversion Principle (DIP)...\")\n\n\nclass GmailService(AbcEmailService):\n    def send(self, content: str) -> None:\n        print(f\"Email with {content=} sent!\")\n\n\nclass YahooService(AbcEmailService):\n    def send(self, content: str) -> None:\n        print(f\"Email with {content=} sent!\")\n\n\nclass AbcGoodNotificationService(metaclass=ABCMeta):\n    @abstractmethod\n    def send_email(self, content: str) -> None:\n        pass\n\n\nclass GoodNotificationService(AbcGoodNotificationService):\n    email_service: AbcEmailService\n\n    def __init__(self, email_service: AbcEmailService) -> None:\n        self.email_service = email_service\n\n    def send_email(self, content: str) -> None:\n        self.email_service.send(content=content)\n\n\nprint(\n    \"\\n```\",\n    \"\"\"class GmailService(AbcEmailService):\n    def send(self, content: str) -> None:\n        print(f\"Email with {content=} sent!\")\n\n\nclass YahooService(AbcEmailService):\n    def send(self, content: str) -> None:\n        print(f\"Email with {content=} sent!\")\n\n\nclass AbcGoodNotificationService(metaclass=ABCMeta):\n    @abstractmethod\n    def send_email(self, content: str) -> None:\n        pass\n\n\nclass GoodNotificationService(AbcGoodNotificationService):\n    email_service: AbcEmailService\n\n    def __init__(self, email_service: AbcEmailService) -> None:\n        self.email_service = email_service\n\n    def send_email(self, content: str) -> None:\n        self.email_service.send(content=content)\"\"\",\n    \"```\",\n    sep=\"\\n\",\n)\n\nprint(\n    \"\\nThis is a good implementation of Dependency Inversion Principle (DIP),\",\n    \"because 'GoodNotificationService' class depends solely on injected dependencies\",\n    \"that implement the 'AbcEmailService' abstract class. So, if the 'email_service' attribute\",\n    \"in the 'GoodNotificationService' class needs to be changed, the constructor does not require\",\n    \"modification (only the class call needs to be updated). For example, I could inject inside the\",\n    \"'email_service' attribute an instance of 'GmailService' or 'YahooService' classes.\",\n    sep=\"\\n\",\n)\n\nprint(\n    \"\\n# ---------------------------------------------------------------------------------- #\\n\"\n)\n\n\"\"\"\n    Additional challenge...\n\"\"\"\n\nprint(\"Additional challenge...\")\n\n\nclass AbcNotificationService(metaclass=ABCMeta):\n    @abstractmethod\n    def send(self) -> None:\n        pass\n\n\nclass EmailService_(AbcNotificationService):\n    def __init__(self) -> None:\n        pass\n\n    def send(self) -> None:\n        print(\"Email sent!\")\n\n\nclass PushService(AbcNotificationService):\n    def __init__(self) -> None:\n        pass\n\n    def send(self) -> None:\n        print(\"Push sent!\")\n\n\nclass SMSService(AbcNotificationService):\n    def __init__(self) -> None:\n        pass\n\n    def send(self) -> None:\n        print(\"SMS sent!\")\n\n\nclass AbcNotificationSystem(metaclass=ABCMeta):\n    @abstractmethod\n    def send_notification(self) -> None:\n        pass\n\n\nclass NotificationSystem(AbcNotificationSystem):\n    notification_service: AbcNotificationService\n\n    def __init__(self, notification_service: AbcNotificationService) -> None:\n        self.notification_service = notification_service\n\n    def send_notification(self) -> None:\n        self.notification_service.send()\n\n\nemailService: EmailService_ = EmailService_()\npushService: PushService = PushService()\nsmsService: SMSService = SMSService()\n\nemailNotificationSystem: NotificationSystem = NotificationSystem(emailService)\npushNotificationSystem: NotificationSystem = NotificationSystem(pushService)\nsmsNotificationSystem: NotificationSystem = NotificationSystem(smsService)\n\nprint()\nemailNotificationSystem.send_notification()\n\nprint()\npushNotificationSystem.send_notification()\n\nprint()\nsmsNotificationSystem.send_notification()\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/python/idiegorojas.py",
    "content": "\"\"\"\n# 30 - Prinicipio SOLID: Inversion de dependencias.\n\"\"\"\n# Lo modulos de alto nivel no deben depender de los modulos de bajo nivel. Ambos deben depender de abstracciones\n# Las abstracciones no deben depender de los detalles. Los detalles deben depender de las abstracciones.\n# Debemos programar hacia interfaces o clases abstractas en lugar de implementaciones concretas. \n\n\"\"\"\nBeneficios\n\"\"\"\n# Desacoplamiento: Las clases de alto nivel no dependen de las implementaciones específicas.\n# Flexibilidad: Facilita cambiar implementaciones sin modificar código existente.\n# Facilita pruebas unitarias: Permite usar mocks o stubs para las dependencias.\n# Mejor diseño: Fomenta pensar en términos de interfaces y comportamientos, no implementaciones.\n\n\n\"\"\"\nEjemplo de violacion del principio\n\"\"\"\n# Interruptor depende directamente de LuzConcreta\n# Si queremos usar otro tipo de luz, tendríamos que modificar la clase Interruptor\n# Es difícil realizar pruebas unitarias\n\nclass LuzPasillo:\n    def encender(self):\n        print(\"Luz encendida\")\n\n    def apagar(self):\n        print('Luz apagada')\n\nclass Interruptor:\n    def __init__(self):\n        self.luz = LuzPasillo()\n\n    def operar(self):\n        self.luz.encender()\n\n\n\"\"\"\nEjemplo aplicando el principio\n\"\"\"\nfrom abc import ABC, abstractmethod\n\nclass DispositivoElectronico(ABC):\n    @abstractmethod\n    def encender(self):\n        pass\n\n    def apagar(self):\n        pass\n\n\nclass Luz(DispositivoElectronico):\n    def encender(self):\n        print('Luz encendida.')\n\n    def apagar(self):\n        print('Luz apagada')\n\n\nclass Ventilador(DispositivoElectronico):\n    def encender(self):\n        print('Ventilador encendido')\n\n    def apagar(self):\n        print('Ventilador apagado')\n\n\nclass Interruptor:\n    def __init__(self, dispositivo: DispositivoElectronico):\n        self.dispositivo = dispositivo\n\n    def operar(self, encender=True):\n        if encender:\n            self.dispositivo.encender()\n        else:\n            self.dispositivo.apagar()\n\nluz = Luz()\nventilador = Ventilador()\n\ninterruptor_luz = Interruptor(luz)\ninterruptor_ventilador = Interruptor(ventilador)\n\ninterruptor_luz.operar(encender=True)\ninterruptor_luz.operar(encender=False)\ninterruptor_ventilador.operar(encender=True)\n\n\n\"\"\"\nExtra\n\"\"\"\nfrom abc import ABC, abstractmethod\n\nclass Notificar(ABC):\n    @abstractmethod\n    def enviar_notificacion(self):\n        pass\n\n    @abstractmethod    \n    def cancelar_notificacion(self):\n        pass\n\n\nclass Email(Notificar):\n    def enviar_notificacion(self):\n        print('Se ha enviado el email.')\n\n    def cancelar_notificacion(self):\n        print('Se ha cancelado el email.')\n\nclass Push(Notificar):\n    def enviar_notificacion(self):\n        print('Se ha enviado el Push.')\n\n    def cancelar_notificacion(self):\n        print('Se ha cancelado el Push.')\n\nclass Sms(Notificar):\n    def enviar_notificacion(self):\n        print('Se ha enviado el SMS.')\n\n    def cancelar_notificacion(self):\n        print('Se ha cancelado el SMS.')\n\n\nclass SistemaNotificaciones:\n    def __init__(self, notificacion: Notificar):\n        self.notificacion = notificacion\n\n    def procesar_notificacion(self, enviar=True):\n        if enviar:\n            self.notificacion.enviar_notificacion()\n        else:\n            self.notificacion.cancelar_notificacion()\n\n\nemail = Email()\npush = Push()\nsms = Sms()\n\nenviar_email = SistemaNotificaciones(email)\nenviar_push = SistemaNotificaciones(push)\nenviar_sms = SistemaNotificaciones(sms)\n\nenviar_email.procesar_notificacion(enviar=True)\nenviar_email.procesar_notificacion(enviar=False)\nenviar_push.procesar_notificacion(enviar=True)\nenviar_push.procesar_notificacion(enviar=False)\nenviar_sms.procesar_notificacion(enviar=True)\nenviar_sms.procesar_notificacion(enviar=False)"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/python/ignaciovihe.py",
    "content": "\"\"\"\n * Explora el \"Principio SOLID de Inversión de Dependencias (Dependency Inversion\n * Principle, DIP)\" y crea un ejemplo simple donde se muestre su funcionamiento \n * de forma correcta e incorrecta.\n\"\"\"\nfrom abc import ABC, abstractmethod\n# Incorrecto DIP\n\nclass CardPayment:\n    def pay(self, quantity):\n        print(f\"Pagando {quantity} mediante tarjeta\")\n\n\nclass PayService:\n    def __init__(self, payer: CardPayment):\n        self.payer = payer  #Depende directamente de CardPayment, si quiero pagar por Paypal debería modificar PayService.\n\n    def process_payment(self, quantity):\n        self.payer.pay(quantity)\n\n\n# Correcto DIP\n\nclass PaymentStrategy(ABC): # Clase abstracta que sirve como interfaz. La clase de clato nivel PaymentService hace referencia a ella.\n    @abstractmethod\n    def pay(self, quantity):\n        pass\n\n\nclass CardPayment(PaymentStrategy):# Si hay que añadir otra metodo de pago sólo se añade una nueva clase.\n    def pay(self, quantity):\n        print(f\"Pagando {quantity} mediante tarjeta\")\n\n\nclass PayPalPayment(PaymentStrategy):\n    def pay(self, quantity):\n        print(f\"Pagando {quantity} mediante PayPal\")\n\nclass BizumPayment(PaymentStrategy):\n    def pay(self, quantity):\n        print(f\"Pagando {quantity} mediante Bizum\")\n\n\nclass PaymentService:\n    def __init__(self, payment_method: PaymentStrategy):\n        self.payment_method = payment_method\n\n    def process_payment(self, quantity):\n        self.payment_method.pay(quantity)\n\n\ncard_service = PaymentService(CardPayment())\ncard_service.process_payment(\"25€\")\npaypal_service = PaymentService(PayPalPayment())\npaypal_service.process_payment(\"30€\")\nbizum_service = PaymentService(BizumPayment())\nbizum_service.process_payment(\"15€\")\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un sistema de notificaciones.\n * Requisitos:\n * 1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas).\n * 2. El sistema de notificaciones no puede depender de las implementaciones específicas.\n * Instrucciones:\n * 1. Crea la interfaz o clase abstracta.\n * 2. Desarrolla las implementaciones específicas.\n * 3. Crea el sistema de notificaciones usando el DIP.\n * 4. Desarrolla un código que compruebe que se cumple el principio.\n\"\"\"\n\nclass Sender(ABC):\n    @abstractmethod\n    def send(self, message):\n        pass\n\n\nclass EmailSender(Sender):\n    def send(self, message):\n        print(f\"Enviando el mensaje '{message}' por email.\")\n\n\nclass PushSender(Sender):\n    def send(self, message):\n        print(f\"Enviando el mensaje '{message}' por push.\")\n\n\nclass SMSSender(Sender):\n    def send(self, message):\n        print(f\"Enviando el mensaje '{message}' por SMS.\")\n\n\nclass NotificationService:\n    def __init__(self, sender: Sender):\n        self.sender = sender\n\n    def notify(self, message):\n        self.sender.send(message)\n\n\nemail_service = NotificationService(EmailSender())\nemail_service.notify(\"Tu Pedido ha sido enviado\")\nsms_service = NotificationService(SMSSender())\nsms_service.notify(\"Tu Pedido ha sido enviado\")\npush_service = NotificationService(PushSender())\npush_service.notify(\"Tu Pedido ha sido enviado\")"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/python/javi-kl.py",
    "content": "from abc import ABC, abstractmethod\n\n\n# Incorrecto\n# Vehiculo esta dependiendo de otro modulo y no de una interfaz\nclass Surtidor:\n    def reponer_gasoleo(self):\n        pass\n\n    def reponer_gasolina(self):\n        pass\n\n    def reponer_queroseno(self):\n        pass\n\n\nclass Vehiculo1:\n    def __init__(self):\n        self.combustible = Surtidor\n\n    def mostrar_repostaje(self):\n        repostaje = self.combustible()\n        print(f\"Respostando {repostaje}\")\n\n\nvehiculo1 = Vehiculo1()\nvehiculo1.mostrar_repostaje()\n\n\n# Correcto\nclass Combustible(ABC):\n    @abstractmethod\n    def reponer(self) -> str:\n        pass\n\n\nclass SurtidorGasoleo(Combustible):\n    def reponer(self) -> str:\n        return \"Gasoleo\"\n\n\nclass SurtidorGasolina(Combustible):\n    def reponer(self) -> str:\n        return \"Gasolina\"\n\n\nclass SurtidorQueroseno(Combustible):\n    def reponer(self) -> str:\n        return \"Queroseno\"\n\n\nclass Vehiculo:\n    \"\"\"Clase de alto nivel - recibe cualquier combustible\"\"\"\n\n    def __init__(self, combustible: Combustible):\n        self.combustible = combustible\n\n    def mostrar_repostaje(self):\n        repostaje = self.combustible.reponer()\n        print(f\"Respostando {repostaje}\")\n\n\nvehiculo1 = Vehiculo(SurtidorGasoleo())\nvehiculo1.mostrar_repostaje()\n\nvehiculo2 = Vehiculo(SurtidorGasolina())\nvehiculo2.mostrar_repostaje()\n\nvehiculo3 = Vehiculo(SurtidorQueroseno())\nvehiculo3.mostrar_repostaje()\n\n\n\"\"\"\nextra\n\"\"\"\n\n\n# Interfaz\nclass InterfazNotificaciones(ABC):\n    \"\"\"Interfaz general de la que dependeran las clases de alto y bajo nivel\"\"\"\n\n    @abstractmethod\n    def notificar(self) -> str:\n        pass\n\n\n# Modulos de bajo nivel\nclass Email(InterfazNotificaciones):\n    \"\"\"Solo se usa para mandar emails\"\"\"\n\n    def notificar(self) -> str:\n        return \"Enviando Email\"\n\n\nclass Push(InterfazNotificaciones):\n    \"\"\"Solo se usa para mandar notificaciones push\"\"\"\n\n    def notificar(self) -> str:\n        return \"Enviando push\"\n\n\nclass Sms(InterfazNotificaciones):\n    \"\"\"Solo se usa para mandar Sms\"\"\"\n\n    def notificar(self) -> str:\n        return \"Enviando Sms\"\n\n\n# Modulo alto nivel\nclass Notificador:\n    \"\"\"Se encarga de mandar notificaciones, no de saber su tipo\"\"\"\n\n    def __init__(self, notificacion: InterfazNotificaciones):\n        self.notificacion = notificacion\n\n    def ejecutar_notificacion(self) -> None:\n        notificacion = self.notificacion.notificar()\n        print(notificacion)\n\n\nprint(\"=== Sistema de Notificaciones ===\\n\")\n\nnotificador_email = Notificador(Email())\nnotificador_email.ejecutar_notificacion()\nnotificador_push = Notificador(Push())\nnotificador_push.ejecutar_notificacion()\nnotificador_sms = Notificador(Sms())\nnotificador_sms.ejecutar_notificacion()\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/python/juanmax2.py",
    "content": "\"\"\"\nEjercicio\n\n\"\"\"\n\n\n# Incorrecto\n\nclass Switch:\n    \n    def encender(self):\n        print(\"Enciende la lámpara\")\n        \n    def apagar(self):\n        print(\"Apaga la lámpara\")\n\nclass Lampara:\n    \n    def __init__(self):\n        self.switch = Switch()\n        \n    def operate(self, command):\n        if command == \"on\":\n            self.switch.encender()\n        elif command == \"off\":\n            self.switch.apagar()\n\nlampara = Lampara()\n\nlampara.operate(\"on\")\nlampara.operate(\"off\")\n\n# Correcto\n\nclass AbstractSwitch:\n    \n    def encender(self):\n        pass\n        \n    def apagar(self):\n        pass\n\nclass LampSwitch(AbstractSwitch):\n    \n    def encender(self):\n        print(\"Enciende la lámpara\")\n        \n    def apagar(self):\n        print(\"Apaga la lámpara\")\n    \nclass Lampara:\n    \n    def __init__(self, switch : AbstractSwitch):\n        self.switch = switch\n        \n    def operate(self, command):\n        if command == \"on\":\n            self.switch.encender()\n        elif command == \"off\":\n            self.switch.apagar()\n\nlampara = Lampara(LampSwitch())\n\nlampara.operate(\"on\")\nlampara.operate(\"off\")\n\n\n\n\"\"\"\n\n * DIFICULTAD EXTRA (opcional):\n * Crea un sistema de notificaciones.\n * Requisitos:\n * 1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas).\n * 2. El sistema de notificaciones no puede depender de las implementaciones específicas.\n * Instrucciones:\n * 1. Crea la interfaz o clase abstracta.\n * 2. Desarrolla las implementaciones específicas.\n * 3. Crea el sistema de notificaciones usando el DIP.\n * 4. Desarrolla un código que compruebe que se cumple el principio.\n */\n\"\"\"\n\nfrom abc import ABC, abstractmethod\n\nclass Notificador(ABC):\n    \n    @abstractmethod\n    def send(self, mensaje : str):\n        pass\n\nclass Email(Notificador):\n    \n    def send(self, mensaje):\n        print(f\"Enviando email con mensaje {mensaje}\")\n\nclass Push(Notificador):\n    \n    def send(self, mensaje):\n        print(f\"Enviando push con mensaje {mensaje}\")\n        \nclass SMS(Notificador):\n    \n    def send(self, mensaje):\n        print(f\"Enviando SMS con mensaje {mensaje}\")\n        \n\nclass ServicioNotificacion:\n    \n    def __init__(self, notificador = Notificador):\n        self.notificador = notificador\n    \n    def notificar(self, mensaje : str):\n        self.notificador.send(mensaje)\n    \nservicio = ServicioNotificacion(Email())\nservicio.notificar(\"Juanma\")\nservicio_1 = ServicioNotificacion(Push())\nservicio_1.notificar(\"González\")\nservicio_2 = ServicioNotificacion(SMS())\nservicio_2.notificar(\"Espinosa\")"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/python/juanppdev.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Explora el \"Principio SOLID de Inversión de Dependencias (Dependency Inversion\n * Principle, DIP)\" y crea un ejemplo simple donde se muestre su funcionamiento \n * de forma correcta e incorrecta.\n\"\"\"\n\n# Correcto\n\nfrom abc import ABC, abstractmethod\n\nclass IMotor(ABC):\n    @abstractmethod\n    def encender(self):\n        pass\n\nclass Motor(IMotor):\n    def encender(self):\n        print(\"Motor encendido\")\n\nclass Coche:\n    def __init__(self, motor: IMotor):\n        self.motor = motor\n\n    def arrancar(self):\n        self.motor.encender()\n\nmotor = Motor()\ncoche = Coche(motor)\ncoche.arrancar()\n\n\n# Incorrecto\n\nclass Motor:\n    def encender(self):\n        print(\"Motor encendido\")\n\nclass Coche:\n    def __init__(self):\n        self.motor = Motor()\n\n    def arrancar(self):\n        self.motor.encender()\n\ncoche = Coche()\ncoche.arrancar()\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un sistema de notificaciones.\n * Requisitos:\n * 1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas).\n * 2. El sistema de notificaciones no puede depender de las implementaciones específicas.\n * Instrucciones:\n * 1. Crea la interfaz o clase abstracta.\n * 2. Desarrolla las implementaciones específicas.\n * 3. Crea el sistema de notificaciones usando el DIP.\n * 4. Desarrolla un código que compruebe que se cumple el principio.\n\"\"\"\n\nfrom abc import ABC, abstractmethod\n\nclass INotificacion(ABC):\n    @abstractmethod\n    def enviar(self, mensaje: str):\n        pass\n\n\nclass EmailNotificacion(INotificacion):\n    def enviar(self, mensaje: str):\n        print(f\"Enviando Email: {mensaje}\")\n\nclass PushNotificacion(INotificacion):\n    def enviar(self, mensaje: str):\n        print(f\"Enviando Notificación PUSH: {mensaje}\")\n\nclass SMSNotificacion(INotificacion):\n    def enviar(self, mensaje: str):\n        print(f\"Enviando SMS: {mensaje}\")\n\n\nclass SistemaNotificaciones:\n    def __init__(self, notificador: INotificacion):\n        self.notificador = notificador\n\n    def notificar(self, mensaje: str):\n        self.notificador.enviar(mensaje)\n\n# Crear instancias de las implementaciones específicas\nemail_notificacion = EmailNotificacion()\npush_notificacion = PushNotificacion()\nsms_notificacion = SMSNotificacion()\n\n# Crear el sistema de notificaciones con diferentes implementaciones\nsistema_email = SistemaNotificaciones(email_notificacion)\nsistema_push = SistemaNotificaciones(push_notificacion)\nsistema_sms = SistemaNotificaciones(sms_notificacion)\n\n# Enviar notificaciones\nsistema_email.notificar(\"Hola por Email\")\nsistema_push.notificar(\"Hola por PUSH\")\nsistema_sms.notificar(\"Hola por SMS\")\n\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/python/kenysdev.py",
    "content": "# ╔═════════════════════════════════════╗\n# ║ Autor:  Kenys Alvarado              ║\n# ║ GitHub: https://github.com/Kenysdev ║\n# ║ 2024 -  Python                      ║\n# ╚═════════════════════════════════════╝\n\n# -----------------------------------------------------\n# * SOLID: RINCIPIO DE INVERSIÓN DE DEPENDENCIAS (DIP)\n# -----------------------------------------------------\n# Los módulos de alto nivel no deben depender de módulos de bajo nivel, sino de abstracciones. A su vez, las \n# abstracciones no deben depender de detalles concretos; los detalles deben depender de las abstracciones.\n\nfrom abc import ABC, abstractmethod\n\n\"\"\"\n* EJERCICIO #1:\n * Explora el \"Principio SOLID de Inversión de Dependencias (Dependency Inversion\n * Principle, DIP)\" y crea un ejemplo simple donde se muestre su funcionamiento \n * de forma correcta e incorrecta.\n\"\"\"\n# __________________________________________________\n# De manera INCORRECTA:\n\nclass FileStorage_:\n    def save(self, data):\n        print(f\"Datos guardados en archivo: {data}\")\n\nclass DataManager_:\n    def __init__(self):\n        # Dependencia directa de una clase concreta\n        self.file_storage = FileStorage()\n    \n    def store_data(self, data):\n        self.file_storage.save(data)\n\n# __________________________________________________\n# De manera CORRECTA:\n\n# Abstracción\nclass AbcStorage(ABC):\n    @abstractmethod\n    def save(self, data):\n        pass\n\n# Implementación concreta\nclass FileStorage(AbcStorage):\n    def save(self, data):\n        print(f\"Guardado en archivo: {data}\")\n\n# Implementación concreta\nclass DatabaseStorage(AbcStorage):\n    def save(self, data):\n        print(f\"Guardado en base de datos: {data}\")\n\n# Módulo de alto nivel\nclass DataManager:\n    def __init__(self, storage: AbcStorage):\n        # Dependencia de la abstracción\n        self.storage: AbcStorage = storage\n    \n    def store_data(self, data):\n        self.storage.save(data)\n\n# Comprobación:\ndata_to_store = \"Ejemplo de datos x\"\n\n# Asignación\nfile_storage: AbcStorage = FileStorage()\ndatabase_storage: AbcStorage = DatabaseStorage()\n\n# Inyección de dependencia.\ndata_manager_file = DataManager(file_storage)\ndata_manager_database = DataManager(database_storage)\n\n# Utilizar el método implementado\ndata_manager_file.store_data(data_to_store)\ndata_manager_database.store_data(data_to_store)\n\n\"\"\"\n* EJERCICIO #2:\n* Crea un sistema de notificaciones.\n* Requisitos:\n* 1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas).\n* 2. El sistema de notificaciones no puede depender de las implementaciones específicas.\n* Instrucciones:\n* 1. Crea la interfaz o clase abstracta.\n* 2. Desarrolla las implementaciones específicas.\n* 3. Crea el sistema de notificaciones usando el DIP.\n* 4. Desarrolla un código que compruebe que se cumple el principio.\n\"\"\"\n\n# Abstracción\nclass AbcMessageService(ABC):\n    @abstractmethod\n    def send(self, to: int | str, message: str) -> None:\n        pass\n\n# Implementación\nclass EmailService(AbcMessageService):\n    def send(self, to: str, message: str) -> None:\n        print(\"Correo enviado a:\", to)\n        print(\"Mensaje:\", message)\n\n# Implementación\nclass PUSHService(AbcMessageService):\n    def send(self, to: str, message: str) -> None:\n        print(\"Notificación PUSH enviada a:\", to)\n        print(\"Mensaje:\", message)\n\n# Implementación\nclass SMSService(AbcMessageService):\n    def send(self, to: int, message: str) -> None:\n        print(\"Mensaje SMS enviado a:\", to)\n        print(\"Mensaje:\", message)\n\n# Módulo de alto nivel\nclass NotificationSystem:\n    def __init__(self, service: AbcMessageService) -> None:\n        # Dependencia de la abstracción\n        self.service: AbcMessageService = service\n    \n    def notify(self, to: int | str, message: str) -> None:\n        self.service.send(to, message)\n\n# Inyección de dependencia.\ndef test_notification_system(to: int | str, message: str, service: AbcMessageService):\n    service_notifier = NotificationSystem(service)\n    service_notifier.notify(to, message)\n\nprint(\"\\nEJERCICIO #2\")\n\n# Asignación\nemail_service: AbcMessageService = EmailService()\npush_service: AbcMessageService = PUSHService()\nsms_service: AbcMessageService = SMSService()\n\n# Comprobación:\ntest_notification_system(\"ejm@gg.com\", \"abcdsf\", email_service)\ntest_notification_system(\"user01\", \"123456\", push_service)\ntest_notification_system(123456789, \"aeiou\", sms_service)\n\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/python/mhayhem.py",
    "content": "# @Author Daniel Grande (Mhayhem)\n\nfrom abc import ABC, abstractmethod\n\n# EJERCICIO:\n# Explora el \"Principio SOLID de Inversión de Dependencias (Dependency Inversion\n# Principle, DIP)\" y crea un ejemplo simple donde se muestre su funcionamiento \n# de forma correcta e incorrecta.\n\n# incorrecta\n\nclass MySQLDatabase:\n    def save(self, data):\n        return \"Guardando en MySQL.\"\n\nclass UserRepository:\n    def __init__(self):\n        self.db = MySQLDatabase()\n    \n    def save_user(self, user):\n        self.db(user)\n\n# correcta\n\nclass DataBase(ABC):\n    @abstractmethod\n    def save(self, data):\n        pass\n\nclass MySQLDatabase:\n    def save(self, data):\n        return f\"Guardando {data} En MySQL.\"\n\nclass PostSQLDatabase:\n    def save(self, data):\n        return f\"Guardando {data} en PostSQL.\"\n\nclass MongoDBDatabase:\n    def save(self, data):\n        return f\"Guardando {data} en MongoDB.\"\n\nclass UserRepository:\n    def __init__(self):\n        self.db = DataBase()\n    \n    def save_user(self, user):\n        self.db.save(user)\n\n\n# DIFICULTAD EXTRA (opcional):\n# Crea un sistema de notificaciones.\n# Requisitos:\n# 1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas).\n# 2. El sistema de notificaciones no puede depender de las implementaciones específicas.\n# Instrucciones:\n# 1. Crea la interfaz o clase abstracta.\n# 2. Desarrolla las implementaciones específicas.\n# 3. Crea el sistema de notificaciones usando el DIP.\n# 4. Desarrolla un código que compruebe que se cumple el principio.\n\nclass NotificationService(ABC):\n    @abstractmethod\n    def send(self, message: str):\n        pass\n\nclass PushNotification(NotificationService):\n    def send(self, message: str) -> str:\n        return f\"Enviando notificación push : {message}\"\n\nclass EmailNotification(NotificationService):\n    def send(self, message: str) -> str:\n        return f\"EWnviando email: {message}\"\n\nclass SMSNotification(NotificationService):\n    def send(self, message: str) -> str:\n        return f\"Enviando SMS: {message}\"\n\nclass NotificationSystem:\n    def __init__(self, service=NotificationService):\n        self.service = service\n    \n    def notify(self, message: str):\n        self.service.send(message)\n\nsystem = NotificationSystem(NotificationService)\npush = PushNotification()\nemail = EmailNotification()\nsms = SMSNotification()\n\ndef test_notifications(array: list, message):\n    for notify in array:\n        print(notify.send(message))\n    \n    assert AttributeError\n\ndef test_system(element: NotificationSystem, message: str) -> str | None:\n    result = element.notify(message)\n\n    print(result)\n    assert result is not None\n    assert message in result"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/python/mouredev.py",
    "content": "\"\"\"\nEjercicio\n\"\"\"\n\n# Sin DIP\n\n\nfrom abc import ABC, abstractmethod\n\n\nclass Switch:\n\n    def turn_on(self):\n        print(\"Enciende la lámpara\")\n\n    def turn_off(self):\n        print(\"Apaga la lámpara\")\n\n\nclass Lamp:\n\n    def __init__(self) -> None:\n        self.switch = Switch()\n\n    def operate(self, command):\n        if command == \"on\":\n            self.switch.turn_on()\n        elif command == \"off\":\n            self.switch.turn_off()\n\n\nlamp = Lamp()\nlamp.operate(\"on\")\nlamp.operate(\"off\")\n\n# Con DIP\n\n\nclass AbstractSwitch:\n\n    def turn_on(self):\n        pass\n\n    def turn_off(self):\n        pass\n\n\nclass LampSwitch(AbstractSwitch):\n\n    def turn_on(self):\n        print(\"Enciende la lámpara\")\n\n    def turn_off(self):\n        print(\"Apaga la lámpara\")\n\n\nclass Lamp:\n\n    def __init__(self, switch: AbstractSwitch) -> None:\n        self.switch = switch\n\n    def operate(self, command):\n        if command == \"on\":\n            self.switch.turn_on()\n        elif command == \"off\":\n            self.switch.turn_off()\n\n\nlamp = Lamp(LampSwitch())\nlamp.operate(\"on\")\nlamp.operate(\"off\")\n\n\"\"\"\nExtra\n\"\"\"\n\n\nclass Notifier(ABC):\n\n    @abstractmethod\n    def send(self, message: str):\n        pass\n\n\nclass EmailNotifier(Notifier):\n    def send(self, message: str):\n        print(f\"Enviando email con texto: {message}\")\n\n\nclass PUSHNotifier(Notifier):\n    def send(self, message: str):\n        print(f\"Enviando PUSH con texto: {message}\")\n\n\nclass SMSNotifier(Notifier):\n    def send(self, message: str):\n        print(f\"Enviando SMS con texto: {message}\")\n\n\nclass NotificationService:\n\n    def __init__(self, notifier: Notifier) -> None:\n        self.notifier = notifier\n\n    def notify(self, message: str):\n        self.notifier.send(message)\n\n\n# service = NotificationService(EmailNotifier())\n# service = NotificationService(PUSHNotifier())\nservice = NotificationService(SMSNotifier())\nservice.notify(\"¡Hola, notificador!\")\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/python/mrodara.py",
    "content": "### Principio de Inversión de Dependencias (Dependency Inversion Principle, DIP)\n\n'''\nEste principio establece que:\n\nLos módulos de alto nivel NO deben depender de los módulos de bajo nivel. Ambos deben depender de abstracciones.\n\nLas abstracciones NO deben depender de los detalles. Los detalles DEBEN depender de las abstracciones.\n\nEn resumen, el DIP promueve que las clases principales (alto nivel) dependan de interfaces o abstracciones, \nen lugar de depender directamente de clases concretas (bajo nivel).\n'''\n\n'''\nVentajas:\n\n+ Reduce el acoplamiento:\n    Los módulos de alto nivel no dependen de los detalles específicos de implementación.\n+ Facilita el mantenimiento:\n    Los detalles de implementación pueden cambiar sin afectar a las clases principales.\n+ Aumenta la flexibilidad y la extensibilidad:\n    Es más sencillo sustituir o añadir implementaciones concretas al depender de abstracciones.\n\n'''\n\n# EJEMPLO QUE VIOLA EL PRINCIPIO\n\nclass CreditCardPayment():\n    \n    def proccess_payment(self, amount):\n        print(f\"Procesando pago con tarjeta de crédito: {amount} €\")\n\nclass OrderProccesor():\n    \n    def __init__(self):\n        self.payment_proccessor = CreditCardPayment()\n    \n    def proccess_order(self, amount):\n        self.payment_proccessor.proccess_payment(amount=amount)\n\n'''\nProblemas detectados:\n\n+ Dependencia directa:\n    OrderProcessor está acoplada directamente a CreditCardPayment. \n    No se puede usar otro método de pago sin modificar OrderProcessor.\n+ Falta de flexibilidad:\n    Si necesitas añadir PayPalPayment o CryptoPayment, tendrás que modificar el código de OrderProcessor.\n'''\n\n# FIN EJEMPLO QUE VIOLA EL PRINCIPIO\n\n# REDISEÑO PARA CUMPLIR CON EL PRINCIPIO\nfrom abc import ABC, abstractmethod\n\nclass PaymentProccessor(ABC):\n    \n    @abstractmethod\n    def proccess_payment(self, amount):\n        pass\n\nclass CreditCardPayment(PaymentProccessor):\n    \n    def proccess_payment(self, amount):\n        print(f\"Procesando pago con tarjeta de crédito: {amount} €\")\n\nclass PayPalPayment(PaymentProccessor):\n    \n    def proccess_payment(self, amount):\n        print(f\"Procesando el pago mediante Paypal: {amount} €\")\n\nclass BizumPayment(PaymentProccessor):\n    \n    def proccess_payment(self, amount):\n        print(f\"Procesando el pago mediante Bizum: {amount} €\")\n\n\n# Clase de Alto nivel\nclass OrderProccessor():\n    \n    def __init__(self, payment_proccessor):\n        self.payment_proccessor = payment_proccessor\n    \n    def proccess_order(self, amount):\n        self.payment_proccessor.proccess_payment(amount=amount)\n\norder = OrderProccessor(CreditCardPayment())\norder.proccess_order(amount=100)\n\norder = OrderProccessor(PayPalPayment())\norder.proccess_order(amount=200)\n\norder = OrderProccessor(BizumPayment())\norder.proccess_order(amount=300)\n\n# FIN REDISEÑO PARA CUMPLIR CON EL PRINCIPIO\n\n## EJERCICIO EXTRA\n\n# CLASE ABSTRACTA\nclass Notifier(ABC):\n    \n    @abstractmethod\n    def send_notification(self, message):\n        pass\n\n#Específicas\nclass EmailNotifier(Notifier):\n    \n    def send_notification(self, message):\n        print(f\"Enviando eamil con el mensaje {message}\")\n\nclass PushNotifier(Notifier):\n    \n    def send_notification(self, message):\n        print(f\"Enviando mensaje Push con texto: {message}\")\n\nclass SmsNotifier(Notifier):\n    def send_notification(self, message):\n        print(f\"Enviando mensaje SMS con texto: {message}\")\n\n# Alto nivel\nclass NotificationSender():\n    \n    def __init__(self, notifier: Notifier):\n        self.notifier = notifier\n    \n    def send_notification(self, message):\n        self.notifier.send_notification(message)\n        \n\n# Batería de pruebas\nemail_sender = NotificationSender(EmailNotifier())\nemail_sender.send_notification(\"Hola soy un Email\")\n\npush_sender = NotificationSender(PushNotifier())\npush_sender.send_notification(\"Hola soy un Push\")\n\nsms_sender = NotificationSender(SmsNotifier())\nsms_sender.send_notification(\"Hola soy un SMS\")\n\n\n## FIN EJERCICIO EXTRA\n\n### FIN Principio de Inversión de Dependencias (Dependency Inversion Principle, DIP)"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/python/neslarra.py",
    "content": "\"\"\"\n EJERCICIO:\n Explora el \"Principio SOLID de Inversión de Dependencias (Dependency Inversion\n Principle, DIP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n de forma correcta e incorrecta.\n\n DIFICULTAD EXTRA (opcional):\n Crea un sistema de notificaciones.\n Requisitos:\n 1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas).\n 2. El sistema de notificaciones no puede depender de las implementaciones específicas.\n Instrucciones:\n 1. Crea la interfaz o clase abstracta.\n 2. Desarrolla las implementaciones específicas.\n 3. Crea el sistema de notificaciones usando el DIP.\n 4. Desarrolla un código que compruebe que se cumple el principio.\n\"\"\"\nfrom abc import ABC, abstractmethod\n\nprint(f\"{'#' * 47}\")\nprint(f\"##  Explicación  {'#' * 30}\")\nprint(f\"{'#' * 47}\")\n\nprint(r\"\"\"\nPara entender fácilmente los 5 ppios SOLID recomiendo leer:\n\n    https://blog.damavis.com/los-principios-solid-ilustrados-en-ejemplos-sencillos-de-python/\n\nen donde se explican de manera ordenada uno por uno, de manera sencilla y ejemplificada de manera progresiva (de hecho, de ahí\nvoy a tomar el ejemplo).\n\nEl quinto ppio SOLID es el ppio de inverción de dependencia (Dependency Inversion Principle) y establece que las clases abstractas no\ndeben depender de los detalles de las clases que las implementan y, a su vez, las clases de alto nivel no deberían depender de las de \nbajo nivel, sino que ambas edben depender de abstracciones. \n\nRetomando el ejemplo, tenemos la clase Communicator definiendo un \"channel\". Pero este canal es un detalle de implementación, el cual,\nademás, si debiera modificarse, estaría incumpliendo los ppios de responsabilidad única y abierto-cerrado.\n\nPara corregir esta situación, separamos \"channel\" en su propia clase abstracta y, cuando Communicator la necesite, lo hará a través\nde otra clase abstracta que le inyecte la clase edl canal.\n\nDe esta menera, la clase Communicator ya no depende de los detalles del canal puesto que ahora va a recibir a su clase abstracta, cuyos \ndetalles solo se definiran cuando se implemente.\n\nIntegramos todo y resulta:\n\n    from abc import ABC, abstractmethod\n    from typing import final\n    \n    \n    class Bird(ABC):\n    \n        def __init__(self, name):\n            self.name = name\n    \n        @abstractmethod\n        def do_sound(self) -> str:\n            pass\n    \n    \n    class FlyingBird(Bird):\n    \n        @abstractmethod\n        def fly(self):\n            pass\n    \n    \n    class SwimmingBird(Bird):\n    \n        @abstractmethod\n        def swim(self):\n            pass\n    \n    \n    class AbstractConversation:\n    \n        def do_conversation(self) -> list:\n            pass\n    \n    \n    class Conversation(AbstractConversation):\n    \n        def __init__(self, bird1: Bird, bird2: Bird):\n            self.bird1 = bird1\n            self.bird2 = bird2\n    \n        def do_conversation(self) -> list:\n            sentence1 = f\"{self.bird1.name}: {self.bird1.do_sound()}, Hola {self.bird2.name}. ¿Cómo va?\"\n            sentence2 = f\"{self.bird2.name}: {self.bird2.do_sound()}, Todo bien {self.bird1.name} ¿Y tú?\"\n            return [sentence1, sentence2]\n    \n    \n    class AbstractChannel(ABC):\n    \n        def get_channel_message(self) -> str:\n            pass\n    \n    \n    class AbstractCommunicator(ABC):\n    \n        def get_channel(self) -> AbstractChannel:\n            pass\n    \n        @final\n        def communicate(self, conversation: AbstractConversation):\n            print(*conversation.do_conversation(), self.get_channel().get_channel_message(), sep='\\n')\n    \n    \n    class Communicator(AbstractCommunicator):\n    \n        def __init__(self, channel: AbstractChannel):\n            self._channel = channel\n    \n        def get_channel(self) -> AbstractChannel:\n            return self._channel\n    \n    \n    class Duck(SwimmingBird, FlyingBird):\n    \n        def fly(self):\n            print(f\"{self.name} is flying not very high\")\n    \n        def swim(self):\n            print(f\"{self.name} swims in the lake and quacks\")\n    \n        def do_sound(self) -> str:\n            return \"Quack\"\n    \n    \n    class SMSChannel(AbstractChannel):\n        def get_channel_message(self) -> str:\n            return \"Sending via SMS\"\n    \n    \n    class EMAILChannel(AbstractChannel):\n        def get_channel_message(self) -> str:\n            return \"Sending an email\"\n    \n    \n    lucas = Duck(\"Lucas\")\n    saturnino = Duck(\"Saturnino\")\n    \n    sms = SMSChannel()\n    email = EMAILChannel()\n    \n    comm1 = Communicator(sms)\n    comm2 = Communicator(email)\n    \n    print(comm1.communicate(Conversation(lucas, saturnino)))\n    print(comm2.communicate(Conversation(lucas, saturnino)))\n    \n    Lucas: Quack, Hola Saturnino. ¿Cómo va?\n    Saturnino: Quack, Todo bien Lucas ¿Y tú?\n    Sending via SMS\n    \n    Lucas: Quack, Hola Saturnino. ¿Cómo va?\n    Saturnino: Quack, Todo bien Lucas ¿Y tú?\n    Sending an email\n\"\"\")\n\nprint(f\"{'#' * 52}\")\nprint(f\"##  Dificultad Extra  {'#' * 30}\")\nprint(f\"{'#' * 52}\\n\")\n\n\nclass AbstractNotificationQueue(ABC):\n\n    @abstractmethod\n    def enqueue(self, message: str):\n        pass\n\n    @abstractmethod\n    def dequeue(self):\n        pass\n\n\nclass AbstracChannel(ABC):\n\n    @abstractmethod\n    def __init__(self, channel: str):\n        self.channel = channel\n\n    @abstractmethod\n    def send_method(self, target: str):\n        pass\n\n\nclass Notification(AbstractNotificationQueue):\n\n    def __init__(self):\n        self.queue = []\n\n    def enqueue(self, message: str):\n        self.queue.append(message)\n\n    def dequeue(self):\n        return self.queue.pop(0)\n\n    def queued_messages(self):\n        return self.queue.__len__()\n\n\nclass SMSChannel(AbstracChannel):\n\n    def __init__(self, channel: str):\n        super().__init__(channel)\n\n    def send_method(self, target: str):\n        return f\"Sending via {self.channel} to {target}\"\n\n\nclass EmailChannel(AbstracChannel):\n\n    def __init__(self, channel: str):\n        super().__init__(channel)\n\n    def send_method(self, target: str):\n        return f\"Sending via {self.channel} to {target}\"\n\n\nclass PushChannel(AbstracChannel):\n\n    def __init__(self, channel: str):\n        super().__init__(channel)\n\n    def send_method(self, target: str):\n        return f\"Sending via {self.channel} to {target}\"\n\n\nclass SendNotificacion:\n\n    def __init__(self, notification: Notification, channel: AbstracChannel, target: str):\n\n        self.notification = notification\n        self.channel = channel\n        self.target = target\n\n    def send_notification(self):\n        if self.notification.queued_messages():\n            print(f\"{self.channel.send_method(self.target)} => {self.notification.dequeue()}\")\n        else:\n            print(f\"{self.channel.__class__.__name__} NO encontró mensajes para enviar\")\n\n\nfacebook = PushChannel(\"FaceBook\")\nwhatsapp = PushChannel(\"WhatsApp\")\ncelu = SMSChannel(\"SMS\")\ncompu = EmailChannel(\"Gmail\")\n\nmis_mensajes = [\"Solicitud de amistad\", \"Avisale al jefe que llego tarde\", \"Mirá whatsapp por favor\",\n                \"Tenés una factura impaga\", \"Envió copia del documento solicitado\", \"No recibí la factura de este mes\"]\n\nnotificaciones = Notification()\nfor msg in mis_mensajes:\n    notificaciones.enqueue(msg)\n\nenvio_fcb = SendNotificacion(notificaciones, facebook, \"Kathy Perry\")\nenvio_fcb.send_notification()\n\nenvio_wsp = SendNotificacion(notificaciones, whatsapp, \"Mi Compa\")\nenvio_wsp.send_notification()\n\nenvio_celu = SendNotificacion(notificaciones, celu, \"1234-5678\")\nenvio_celu.send_notification()\n\nenvio_celu = SendNotificacion(notificaciones, celu, \"1122-3344\")\nenvio_celu.send_notification()\n\nenvio_compu = SendNotificacion(notificaciones, compu, \"nuevo_curro@slavers.com\")\nenvio_compu.send_notification()\n\nenvio_compu = SendNotificacion(notificaciones, compu, \"servicio@el_gas.com\")\nenvio_compu.send_notification()\n\nenvio_fcb.send_notification()\nenvio_wsp.send_notification()\nenvio_celu.send_notification()\nenvio_compu.send_notification()\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/python/oriaj3.py",
    "content": "\"\"\" \n30 - SOLID DIP - Principio de Inversión de Dependencias\nAutor de la solución: oriaj3\n\nTeoría: \nEl principio de inversión de dependencias (DIP) establece que las entidades de alto nivel no deben \ndepender de las entidades de bajo nivel. Ambas deben depender de abstracciones. Además, las abstracciones \nno deben depender de los detalles. Los detalles deben depender de las abstracciones.\n\nEn otras palabras, las clases de alto nivel no deben depender de las clases de bajo nivel. Ambas deben\ndepender de abstracciones. Las abstracciones no deben depender de los detalles. Los detalles deben depender\nde las abstracciones.\n\nPor ejemplo, si una clase A depende de una clase B, y la clase B depende de una clase C, entonces la clase A\ndepende de la clase C. Esto viola el principio de inversión de dependencias.\n\nclass C():\n\nclass B(C):\n\nclass A(B):\n\nEn este caso, la clase A depende de la clase C, lo que viola el principio de inversión de dependencias.\n\"\"\"\n\n\"\"\"\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Inversión de Dependencias (Dependency Inversion\n * Principle, DIP)\" y crea un ejemplo simple donde se muestre su funcionamiento \n * de forma correcta e incorrecta.\n\"\"\"\n\n### Ejemplo sin cumplir el DIP Un sistema de registro (logging) que puede escribir en diferentes destinos (consola, web, base de datos).\n\nclass LoginConsola:\n    def __init__(self, user, psswd):\n        self.user = user\n        self.psswd = psswd\n\n    def log(self, user, passwd):\n        if self.user == user and self.psswd == passwd:\n            print(f\"Usuario: {user} logueado en consola\")\n        else:\n            print(\"Usuario o contraseña incorrectos\")\n\nclass LoginWeb:\n    def __init__(self, user, psswd):\n        self.user = user\n        self.psswd = psswd\n\n    def log(self, user, psswd):\n        if self.user == user and self.psswd == psswd:\n            print(f\"Usuario: {user} logueado en web\")\n        else:\n            print(\"Usuario o contraseña incorrectos\")\n    \nclass LoginBD:\n    def __init__(self, user, psswd):\n        self.user = user\n        self.psswd = psswd\n\n    def log(self, user, psswd):\n        if self.user == user and self.psswd == psswd:\n            print(f\"Usuario: {user} logueado en base de datos\")\n        else:\n            print(\"Usuario o contraseña incorrectos\")\nclass GestorLogin:\n    def __init__(self):\n        self.login_consola = LoginConsola(\"admin\", \"admin\")\n        self.login_web = LoginWeb(\"admin\", \"admin\")\n        self.login_bd = LoginBD(\"admin\", \"admin\")\n\n    def login(self, user, psswd, destino):\n        if destino == \"consola\":\n            self.login_consola.log(user, psswd)\n        elif destino == \"web\":\n            self.login_web.log(user, psswd)\n        elif destino == \"bd\":\n            self.login_bd.log(user, psswd)\n        else:\n            print(\"Destino incorrecto\")\n\ngestor = GestorLogin()\n\ngestor.login(\"admin\", \"admin\", \"consola\")\ngestor.login(\"admin\", \"admin\", \"web\")\ngestor.login(\"admin\", \"admin\", \"bd\")\n\n### Ejemplo cumpliendo el DIP\nfrom abc import ABC, abstractmethod\n\nclass loginInterface(ABC):\n    @abstractmethod\n    def log(self, user, psswd):\n        pass\n    \nclass Login_Consola(loginInterface):\n    def __init__(self, user, psswd):\n        self.user = user\n        self.psswd = psswd\n\n    def log(self, user, passwd):\n        if self.user == user and self.psswd == passwd:\n            print(f\"**Usuario: {user} logueado en consola\")\n        else:\n            print(\"Usuario o contraseña incorrectos\")\n            \nclass Login_Web(loginInterface):\n    def __init__(self, user, psswd):\n        self.user = user\n        self.psswd = psswd\n\n    def log(self, user, psswd):\n        if self.user == user and self.psswd == psswd:\n            print(f\"**Usuario: {user} logueado en web\")\n        else:\n            print(\"Usuario o contraseña incorrectos\")\n\nclass Login_BD(loginInterface):\n    def __init__(self, user, psswd):\n        self.user = user\n        self.psswd = psswd\n\n    def log(self, user, psswd):\n        if self.user == user and self.psswd == psswd:\n            print(f\"**Usuario: {user} logueado en base de datos\")\n        else:\n            print(\"Usuario o contraseña incorrectos\")\n\nclass gestorLogin:\n    def __init__(self):\n        self.logins = [Login_Consola(\"admin\", \"admin\"), Login_Web(\"admin\", \"admin\"), Login_BD(\"admin\", \"admin\")]\n        \n    def login(self, user, psswd):\n        for login in self.logins:\n            login.log(user, psswd)\n\ngestor = gestorLogin()\ngestor.login(\"admin\", \"admin\")\n\n\n\"\"\"\n * DIFICULTAD EXTRA (opcional):\n * Crea un sistema de notificaciones.\n * Requisitos:\n * 1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas).\n * 2. El sistema de notificaciones no puede depender de las implementaciones específicas.\n * Instrucciones:\n * 1. Crea la interfaz o clase abstracta.\n * 2. Desarrolla las implementaciones específicas.\n * 3. Crea el sistema de notificaciones usando el DIP.\n * 4. Desarrolla un código que compruebe que se cumple el principio.\n */\n\"\"\" \n\n#Ejemplo sin cumplir el DIP\nclass NotificacionEmail1:\n    def enviar(self, mensaje):\n        print(f\"Enviando email: {mensaje}\")\n        \nclass NotificacionSMS1:\n    def enviar(self, mensaje):\n        print(f\"Enviando SMS: {mensaje}\")\n        \nclass NotificacionPush1:\n    def enviar(self, mensaje):\n        print(f\"Enviando PUSH: {mensaje}\")\n        \nclass GestorNotificaciones1:\n    def __init__(self):\n        self.email = NotificacionEmail1()\n        self.sms = NotificacionSMS1()\n        self.push = NotificacionPush1()\n        \n    def enviarNotificacion(self, mensaje):\n        self.email.enviar(mensaje)\n        self.sms.enviar(mensaje)\n        self.push.enviar(mensaje)\n\n\n\n#Ejemplo cumpliendo el DIP\nclass Notificacion(ABC):\n    @abstractmethod\n    def enviar(self, mensaje):\n        pass\n\nclass NotificacionEmail(Notificacion):\n    def enviar(self, mensaje):\n        print(f\"Enviando email: {mensaje}\")\n\nclass NotificacionSMS(Notificacion):\n    def enviar(self, mensaje):\n        print(f\"Enviando SMS: {mensaje}\")\n        \nclass NotificacionPush(Notificacion):\n    def enviar(self, mensaje):\n        print(f\"Enviando PUSH: {mensaje}\")\n        \nclass GestorNotificaciones:\n    def __init__(self):\n        self.notificaciones = []\n        \n    def agregarNotificacion(self, notificacion):\n        self.notificaciones.append(notificacion)\n        \n    def enviarNotificacion(self, mensaje):\n        for notificacion in self.notificaciones:\n            notificacion.enviar(mensaje)\n            \ngestor = GestorNotificaciones()\ngestor.agregarNotificacion(NotificacionEmail())\ngestor.agregarNotificacion(NotificacionSMS())\ngestor.agregarNotificacion(NotificacionPush())\n\ngestor.enviarNotificacion(\"Hola mundo\")\n\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/python/pyramsd.py",
    "content": "from abc import ABC, abstractmethod\n\n# USO INCORRECTO\nclass MySQLDatabase:\n    def connect(self):\n        print(\"Connecting to MySQL database...\")\n\n    def disconnect(self):\n        print(\"Disconnecting from MySQL database...\")\n\nclass Application:\n    def __init__(self):\n        self.database = MySQLDatabase()\n\n    def run(self):\n        self.database.connect()\n        print(\"Running the application...\")\n        self.database.disconnect()\n\napp = Application()\napp.run()\n\n\"\"\"\nLa clase Application depende directamente de la clase MySQLDatabase. Si se quiere cambiar a otra base de datos,\npor ejemplo, PostgreSQL, habrá que modificar la clase Application, lo que puede romper la aplicación o complicar\nel mantenimiento.\n\"\"\"\n\n\n# USO CORRECTO\nclass Database(ABC):\n    @abstractmethod\n    def connect(self):\n        pass\n\n    @abstractmethod\n    def disconnect(self):\n        pass\n\nclass MySQLDatabase(Database):\n    def connect(self):\n        print(\"Connecting to MySQL database...\")\n\n    def disconnect(self):\n        print(\"Disconnecting from MySQL database...\")\n\nclass PostgreSQLDatabase(Database):\n    def connect(self):\n        print(\"Connecting to PostgreSQL database...\")\n\n    def disconnect(self):\n        print(\"Disconnecting from PostgreSQL database...\")\n\nclass Application:\n    def __init__(self, database: Database):\n        self.database = database\n\n    def run(self):\n        self.database.connect()\n        print(\"Running the application...\")\n        self.database.disconnect()\n\n# Puedes cambiar la base de datos sin modificar la clase Application\nmysql_db = MySQLDatabase()\napp = Application(mysql_db)\napp.run()\n\npostgres_db = PostgreSQLDatabase()\napp = Application(postgres_db)\napp.run()\n\n\n\"\"\"\nEXTRA\n\"\"\"\nclass Notification(ABC):\n    @abstractmethod\n    def send(self, message: str, recipient: str):\n        pass\n\nclass EmailNotification(Notification):\n    def send(self, message: str, recipient: str):\n        print(f\"Sending Email to {recipient}: {message}\")\n\nclass PushNotification(Notification):\n    def send(self, message: str, recipient: str):\n        print(f\"Sending PUSH notification to {recipient}: {message}\")\n\nclass SMSNotification(Notification):\n    def send(self, message: str, recipient: str):\n        print(f\"Sending SMS to {recipient}: {message}\")\n\nclass NotificationService:\n    def __init__(self, notifier: Notification):\n        self.notifier = notifier\n\n    def notify(self, message: str, recipient: str):\n        self.notifier.send(message, recipient)\n\n\ndef main():\n    email_notifier = EmailNotification()\n    push_notifier = PushNotification()\n    sms_notifier = SMSNotification()\n\n    # Crear el servicio de notificaciones usando el notificador de Email\n    email_service = NotificationService(email_notifier)\n    email_service.notify(\"Hello via Email!\", \"email@example.com\")\n\n    # Crear el servicio de notificaciones usando el notificador de PUSH\n    push_service = NotificationService(push_notifier)\n    push_service.notify(\"Hello via PUSH!\", \"user_device_token\")\n\n    # Crear el servicio de notificaciones usando el notificador de SMS\n    sms_service = NotificationService(sms_notifier)\n    sms_service.notify(\"Hello via SMS!\", \"123-456-7890\")\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/python/rantamhack.py",
    "content": "\n# ESTE PRINCIPIO ESTABLECE DOS COSAS:\n# 1ª LOS MODULOS DE ALTO NIVEL NO PUEDEN DEPENDER DE LOS MODULOS DE BAJO NIVEL, LOS DOS DEBEN DEPENDER DE LAS ABSTRACCIONES\n# 2ª LAS ABSTRACCIONES NO PUEDEN DEPENDER DE LOS DETALLES SINO LOS DETALLES DE LAS ABSTRACCIONES\n\n\n\nprint(\"\\n\\n=======================================EJERCICIO=======================================\\n\\n\")\n\n'''\n * EJERCICIO:\n * Explora el \"Principio SOLID de Inversión de Dependencias (Dependency Inversion\n * Principle, DIP)\" y crea un ejemplo simple donde se muestre su funcionamiento \n * de forma correcta e incorrecta.\n'''\n\n# SIN DIP\n\n# class Dictionary():\n#     def chek_word(self, word, dictionary):\n#         if word in dictionary:\n#             return f\"La palabra {palabra} estÃ¡ en el diccionario\"\n            \n             \n# class SpellCorrect:\n#     def __init__(self, dictionary):\n#         self.dictionary = Dictionary()\n        \n#     def correct_text(self, text):\n#          #Tenemos que usar el diccionario para corregir el texto o cambiar toda la logica\n#          pass\n\n\n\n# CON DIP\n\nfrom abc import ABC, abstractmethod\n\nclass SpellChecker(ABC):\n    @abstractmethod\n    def check_word(self):\n        pass\n \n    \nclass Dictionary(SpellChecker):\n    def check_word(self, word, dictionary):\n        # Logica para verificar la palabra en el diccionario\n        pass\n \n    \nclass OnlineService(SpellChecker):\n    def check_word(self, word, url):\n        # Logica para verificar palabras desde el servicio web\n        pass\n    \nclass SpellCorrect:\n    def __init__(self, checker):\n        self.cheker = checker\n        \n    def correct_text(self, text):\n        # Usamos el verificador para corregir el texto da igual si usamos un servicio local o web, solo hay que indicar desde donde lo queremos hacer\n        pass\n\n\n\n\nprint(\"\\n\\n=======================================DIFICULTAD EXTRA=======================================\\n\\n\")\n\n'''\n * DIFICULTAD EXTRA (opcional):\n * Crea un sistema de notificaciones.\n * Requisitos:\n * 1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas).\n * 2. El sistema de notificaciones no puede depender de las implementaciones específicas.\n * Instrucciones:\n * 1. Crea la interfaz o clase abstracta.\n * 2. Desarrolla las implementaciones específicas.\n * 3. Crea el sistema de notificaciones usando el DIP.\n * 4. Desarrolla un código que compruebe que se cumple el principio.\n'''\n\nfrom abc import ABC, abstractmethod\n\nclass Notifier(ABC):\n    @abstractmethod\n    def send(self, message):\n        pass\n    \n    \nclass EmailNotification(Notifier):\n    def send(self, message):\n        print(f\"Enviando por email el mensaje: {message}\")\n        \n        \n        \nclass PUSHNotification(Notifier):\n    def send(self, message):\n        print(f\"Enviando por PUSH el mensaje: {message}\")\n        \n        \nclass SMSNotification(Notifier):\n    def send(self, message):\n        print(f\"Enviando por SMS el mensaje: {message}\")\n        \n        \nclass Notification:\n    def __init__(self, notifier: Notifier):\n        self.notifier = notifier\n        \n    def notify(self, message):\n        self.notifier.send(message)\n        \n        \n        \nnotice1 = Notification(EmailNotification())\nnotice1.notify(\"Felices vacaciones!!!\")\n\nnotice2 = Notification(PUSHNotification())\nnotice2.notify(\"Felices vacaciones!!!\")\n\nnotice3 = Notification(SMSNotification())\nnotice3.notify(\"Felices vacaciones!!!\")\n\n    \n    \n    \n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/python/raulG91.py",
    "content": "from abc import ABC,abstractmethod\n\n#Incorrect example\nclass FrontEnd:\n    def __init__(self,back_end):\n        self.back_end = back_end\n    def display_data(self):\n        data = self.back_end.get_data_from_database()\n        print(f'Data is: {data}')\n\nclass BackEnd:\n    def get_data_from_database(self):\n        return \"Data from databse\"\n    def gat_data_from_api(self):\n        return \"Data from API\"\n'''\nback = BackEnd()\nfront = FrontEnd(back)\nfront.display_data()\n'''\n\n#Correct example\n\nclass DataSource(ABC):\n    @abstractmethod\n    def get_data(self):\n        pass\nclass Database(DataSource):\n    def get_data(self):\n        return \"Data from database\"\n\nclass API(DataSource):\n    def get_data(self):\n        return \"Data from API\"\n\nclass FrontEndV2:\n    def __init__(self,datasource) -> None:\n        self.source = datasource\n    def  display_data(self):\n        data = self.source.get_data()\n        print(f'Data extracted: {data}')                  \n\ndatabsae_backend = Database()\nfront = FrontEndV2(databsae_backend) \nfront.display_data()       \napi_backend = API()\nfront = FrontEndV2(api_backend)\nfront.display_data()\n\n#Extra\n\nclass Notification(ABC):\n    @abstractmethod\n    def send_notfication(self):\n        pass\n\nclass EmailNotification(Notification):\n    def send_notfication(self):\n        print (\"Email Notification\")\n\nclass PushNotification(Notification):\n    def send_notfication(self):\n         print(\"Push Notification\")\n\nclass SMSNotification(Notification):\n    def send_notfication(self):\n        print(\"SMS Notification\")\n\nclass Service:\n    def __init__(self,notification) -> None:\n        self.notification = notification\n\n    def send(self):\n        self.notification.send_notfication()\n\nservice = Service(EmailNotification())\nservice.send()\n\nservice = Service(PushNotification())\nservice.send()\n\nservice = Service(SMSNotification())\nservice.send()"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/python/raynerpv2022.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * Explora el \"Principio SOLID de Inversión de Dependencias (Dependency Inversion\n#  * Principle, DIP)\" y crea un ejemplo simple donde se muestre su funcionamiento \n#  * de forma correcta e incorrecta.\nfrom abc import ABC, abstractmethod\n\n\n\n \n#  * DIFICULTAD EXTRA (opcional):\n#  * Crea un sistema de notificaciones.\n#  * Requisitos:\n#  * 1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas).\n#  * 2. El sistema de notificaciones no puede depender de las implementaciones específicas.\n#  * Instrucciones:\n#  * 1. Crea la interfaz o clase abstracta.\n#  * 2. Desarrolla las implementaciones específicas.\n#  * 3. Crea el sistema de notificaciones usando el DIP.\n#  * 4. Desarrolla un código que compruebe que se cumple el principio.\n#  */\n\n\n# Sistema de Notificaciones \n# DIP incorrecto\n\n\n\nclass PostNotification:\n    def SendMessage(self):\n        print(\"Sended Notificacion per Post\")\n\n# addicionando clase para enviar por email, necesitamos modificar la clase Notificacion\n\nclass EmailNotification:\n    def SendMessage(self):\n        print(\"Sended Notificacion per Email \") \n     \n\nclass Notification:\n    def __init__(self, m : PostNotification, e : EmailNotification):\n        self.Message = m\n        self.email = e\n\n    def PostMessage(self):\n        self.Message.SendMessage()\n\n    def EmailMessage(self):\n        self.email.SendMessage()\n\ne = EmailNotification()\np = PostNotification()\nMess1 = Notification(p,e)\nMess1.PostMessage()\nMess1.EmailMessage()\n\n# Correcto\n\n\nclass GenericNotification(ABC):\n    @abstractmethod\n    def SendMessage(self ): \n        pass\n\nclass PostNotification(GenericNotification):\n    def __init__(self, message):\n        self.message = message\n\n    def SendMessage(self):\n        print(f\"Message {self.message} was sent via POst\")\n\nclass EmailNotification(GenericNotification):\n    def __init__(self, message):\n        self.message = message\n\n    def SendMessage(self ):\n         print(f\"Message {self.message} was sent via Email\")\n        \nclass WhatsAPPNotification(GenericNotification):\n    def __init__(self, message):\n        self.message = message\n        \n    def SendMessage(self):\n         print(f\"Message {self.message} was sent via WhatsAPP\")\n\nclass TelegramNotification(GenericNotification):\n    def __init__(self, message):\n        self.message = message\n    \n    def SendMessage(self):\n         print(f\"Message {self.message} was sent via Telegram\")\n\n\nclass Notification:\n    def __init__(self, Noti: GenericNotification):\n        self.notification = Noti\n\n#  aqui almaceno el mensaje directo en la la instancia de la clase a enviar sea, sms, email, etc.\n    def Send(self):\n        self.notification.SendMessage()\n\n\n\nw = WhatsAPPNotification(\"Hallo\")\np = PostNotification(\"Hola\")\ne = EmailNotification(\"HI\")\nt = TelegramNotification(\"Telegram\")\n\nn = Notification(w)\nn.Send()\nn = Notification(p)\nn.Send()\nn = Notification(e)\nn.Send()\nn = Notification(t)\nn.Send()\n\n\n \n \n\n \n# Respuesta de CHatGPT\n# Has implementado correctamente el Principio de Inversión de Dependencias (DIP)! Ahora, si deseas seguir aplicando los demás principios SOLID a este ejemplo, podemos revisar cómo mejorar el diseño con cada uno de ellos. Vamos a hacer un breve repaso de cada uno:\n# 1. Single Responsibility Principle (SRP):\n\n# Cada clase tiene una única responsabilidad.\n\n#     PostNotification, EmailNotification, y WhatsAPPNotification son responsables de enviar un tipo específico de notificación.\n\n#     Notification es responsable de recibir una notificación y enviarla.\n#     Cumple con SRP.\n\n# 2. Open/Closed Principle (OCP):\n\n# El sistema está abierto para su extensión, pero cerrado para su modificación.\n\n#     Si quisieras agregar otro tipo de notificación (como SMS, Push, etc.), simplemente crearías una nueva clase que implemente GenericNotification, sin necesidad de modificar las clases existentes.\n#     Cumple con OCP.\n\n# 3. Liskov Substitution Principle (LSP):\n\n# Las subclases deben poder sustituir a sus clases base sin afectar la funcionalidad del sistema.\n\n#     PostNotification, EmailNotification, y WhatsAPPNotification son clases que implementan GenericNotification, lo que asegura que todas se comporten de manera esperada al ser usadas de forma intercambiable.\n#     Cumple con LSP.\n\n# 4. Interface Segregation Principle (ISP):\n\n# Las interfaces deben ser específicas y no imponer métodos innecesarios.\n\n#     La interfaz GenericNotification tiene solo el método necesario SendMessage. Si alguna notificación requiere más métodos (como establecer una prioridad, por ejemplo), puedes agregar una nueva interfaz sin hacer cambios innecesarios en las demás.\n#     Cumple con ISP.\n\n# 5. Dependency Inversion Principle (DIP):\n\n# Ya lo has implementado correctamente. La clase Notification depende de la interfaz GenericNotification, no de clases concretas, lo que permite que cualquier tipo de notificación sea inyectada sin modificar el comportamiento de Notification.\n# Cumple con DIP.\n# Resumen:\n\n# Tu diseño sigue correctamente los 5 principios SOLID. Las clases están bien estructuradas y mantienen una separación clara de responsabilidades, haciendo que el código sea extensible, mantenible y fácil de probar.\n\n# Si quieres explorar más sobre estos principios o tienes alguna duda en particular, no dudes en preguntar. ¡Buen trabajo!\n\n\n         \n# ¡Perfecto! Vamos a revisar tu código en Python paso a paso para ver cómo se alinean (o no) con los 5 principios SOLID. Aquí te dejo el análisis detallado:\n# ✅ 1. Single Responsibility Principle (SRP)\n\n#     Una clase debe tener una sola responsabilidad.\n\n# ✔️ Cumplido:\n\n# Cada clase tiene una única responsabilidad clara:\n\n#     PostNotification, EmailNotification y WhatsAPPNotification solo envían mensajes por un canal específico.\n\n#     Notification solo coordina el envío.\n\n#     No hay mezcla de lógicas adicionales.\n\n# ✅ 2. Open/Closed Principle (OCP)\n\n#     Abierto para extensión, cerrado para modificación.\n\n# ✔️ Cumplido:\n\n#     Si mañana agregas un nuevo canal (por ejemplo, TelegramNotification), puedes extender el sistema sin modificar las clases existentes.\n\n#     Solo necesitas crear una nueva subclase de GenericNotification.\n\n# class TelegramNotification(GenericNotification):\n#     def __init__(self, message):\n#         self.message = message\n\n#     def SendMessage(self):\n#         print(f\"Message {self.message} was sent via Telegram\")\n\n# ✅ 3. Liskov Substitution Principle (LSP)\n\n#     Las subclases deben poder sustituir a sus clases base sin problemas.\n\n# ✔️ Cumplido:\n\n#     Todas las clases (PostNotification, EmailNotification, WhatsAPPNotification) pueden reemplazar a GenericNotification en Notification sin romper nada.\n\n# n = Notification(EmailNotification(\"Hi\"))  # funciona igual con cualquier clase hija\n# n.Send()\n\n# ✅ 4. Interface Segregation Principle (ISP)\n\n#     Los clientes no deben depender de interfaces que no usan.\n\n# ✔️ Cumplido:\n\n#     GenericNotification tiene una única función abstracta, SendMessage(), y todas las subclases la implementan.\n\n#     No estás forzando a las subclases a implementar métodos que no necesitan.\n\n# ✅ 5. Dependency Inversion Principle (DIP)\n\n#     Depender de abstracciones, no de implementaciones concretas.\n\n# ✔️ Cumplido:\n\n#     La clase Notification depende de GenericNotification (una abstracción), no de clases concretas como EmailNotification.\n\n#     Esto permite intercambiar implementaciones sin tocar Notification.\n\n# class Notification:\n#     def __init__(self, Noti: GenericNotification):  # <- buena práctica\n#         self.notification = Noti\n\n    \n\n    # EXTRA EXTAR\n\n#     Crear un sistema que permita ejecutar comandos (Start, Shutdown, Login, Logout, Reset, etc.) \n# en distintos sistemas operativos (Windows, Ubuntu, etc.) siguiendo los 5 principios SOLID.\n\n# Requisitos:\n\n#     SRP – Principio de Responsabilidad Única:\n\n#         Cada clase debe encargarse de una sola cosa: enviar un comando, representar un sistema operativo, o coordinar la ejecución.\n\n#     OCP – Abierto para extensión, cerrado para modificación:\n\n#         Debes poder agregar nuevos comandos o nuevos sistemas operativos sin modificar las clases existentes.\n\n#     LSP – Sustitución de Liskov:\n\n#         Las clases hijas (Windows, Ubuntu, etc.) deben poder sustituir a la clase base del sistema operativo sin alterar el comportamiento del programa.\n\n#     ISP – Principio de Segregación de Interfaces:\n\n#         Divide los comandos en interfaces específicas (por ejemplo, ILogin, IShutdown) en lugar de una sola interfaz gigante.\n\n#     DIP – Principio de Inversión de Dependencias:\n\n#         Las clases de alto nivel (como CommandExecutor) deben depender de interfaces abstractas, no de implementaciones concretas.\n\n    \nclass VirtualCommand(ABC):\n    @abstractmethod\n    def Execute(self):\n        pass\n\n\n\nclass iStart(VirtualCommand):\n    def Execute(self):\n        return \"Start\"\n\nclass iShutDown(VirtualCommand):\n    def Execute(self):\n        return \" ShutDown\"\n\n\nclass VirtualSO(ABC):\n    @abstractmethod\n    def Command(self, command : VirtualCommand):\n        pass\n\nclass iWindows(VirtualSO):\n    def Command(self, command: VirtualCommand):\n        print(f\" Command {command.Execute()} in Windows\")\n\nclass iUbuntu(VirtualSO):\n    def Command(self, command : VirtualCommand):\n         print(f\" Command {command.Execute()} in Ubuntu\")\n\n\nclass ExecutTerminal:\n    def __init__(self,command: VirtualCommand, so: VirtualSO):\n        self.command = command\n        self.so = so\n\n    def Execute(self):\n        self.so.Command(self.command)\n\nstart = iStart()\nshutdown = iShutDown()\nso_w = iWindows()\nso_u = iUbuntu()\nex = ExecutTerminal(start,so_w)\nex.Execute()\nex = ExecutTerminal(shutdown, so_u)\nex.Execute()\n\n\n\n \n\n\n# ✅ 1. SRP – Principio de Responsabilidad Única\n\n# Cada clase tiene una responsabilidad única:\n\n#     VirtualCommand define una interfaz para comandos.\n\n#     iStart e iShutDown implementan comandos concretos.\n\n#     VirtualSO es la abstracción para los sistemas operativos.\n\n#     iWindows e iUbuntu ejecutan comandos específicos en su SO.\n\n#     ExecutTerminal orquesta la ejecución, pero no se encarga de los detalles internos de comandos ni SO.\n\n# ✅ Cumplido.\n# ✅ 2. OCP – Principio de Abierto/Cerrado\n\n# Tu código está abierto a extensión (puedes crear nuevos comandos o SOs), pero cerrado a modificación (no necesitas tocar las clases existentes para extender).\n\n# Por ejemplo:\n\n#     Puedes agregar iRestart() sin tocar ExecutTerminal.\n\n#     Puedes crear un nuevo SO como iMacOS.\n\n# ✅ Cumplido.\n# ✅ 3. LSP – Principio de Sustitución de Liskov\n\n# Las instancias de VirtualCommand (iStart, iShutDown) pueden reemplazar sin problema a su clase base VirtualCommand en cualquier parte del código sin romper nada.\n\n# ✅ Cumplido.\n# ✅ 4. ISP – Principio de Segregación de Interfaces\n\n# Estás usando interfaces (VirtualCommand, VirtualSO) con métodos mínimos y necesarios. No obligas a las clases a implementar métodos que no necesitan.\n\n# ✅ Cumplido.\n# ✅ 5. DIP – Principio de Inversión de Dependencias\n\n# ExecutTerminal depende de abstracciones, no de clases concretas:\n\n# def __init__(self, command: VirtualCommand, so: VirtualSO)\n\n# Eso te da flexibilidad total para cambiar implementaciones sin afectar la lógica de ExecutTerminal.\n\n# ✅ Cumplido.\n# 🔧 Sugerencias mínimas (opcional):\n\n#     Los nombres como iStart e iShutDown podrían cambiarse a StartCommand y ShutDownCommand para ser más claros (prefijo \"i\" se usa a veces para interfaces, lo cual puede llevar a confusión).\n\n#     Si más adelante quieres ejecutar múltiples comandos en fila, podrías añadir una lista de comandos o un patrón Command más completo (con undo, etc.).\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/python/raynerpv2022_1.py",
    "content": "from abc import ABC, abstractmethod\n\n# Ejercicio: Sistema de pedidos online con notificaciones\n\n# Crea una aplicación sencilla que haga lo siguiente:\n#     Se pueden crear distintos tipos de pedidos (por ejemplo, Electrónica, Ropa, Libros).\n#     El pedido puede ser procesado.\n#     El sistema puede notificar al cliente por distintos medios: Email, SMS o WhatsApp.\n#     Los mensajes deben cumplir con Open/Closed y Dependency Inversion.\n#     Añade una clase que simule una base de datos en memoria para almacenar los pedidos.\n\n# classe virtual para ordenes\nclass VirtualOrder(ABC):\n    @abstractmethod\n    def Process(self):\n        pass\n\n\n#  classes concretas para ordenes\n\nclass Internet(VirtualOrder):\n    def __init__(self, name: str):\n        self.name = name\n    \n    def Process(self):\n        return f\"Internet Order {self.name} Processed\"\n\nclass Electronic(VirtualOrder):\n    def __init__(self, name: str):\n        self.name = name\n         \n    def Process(self):\n        return f\"Electronic Order {self.name} Processed\"\n    \nclass Clothes( VirtualOrder):\n    def __init__(self, name: str):\n        self.name = name\n\n    def Process(self):\n        return f\"Clothes Order {self.name} Processed\"\n    \nclass Books (VirtualOrder):\n    def __init__(self, name: str):\n        self.name = name\n\n    def Process(self):\n        return  f\"Book Order {self.name} Processed\"\n    \n\n# classes virtual para notificaciones\nclass VirtualNotification(ABC):\n    @abstractmethod\n    def SendNotification(self):\n        pass\n\n# classes concretas para notificaciones\n\nclass Telegram(VirtualNotification):\n    def SendNotification(self):\n         return \" Telegram message sent\"\n\nclass Email(VirtualNotification):\n    def SendNotification(self):\n         return \" Email message sent\"\n\nclass Sms (VirtualNotification):\n    def SendNotification(self):\n        return \" SMS message sent\"\n\nclass Whatsapp(VirtualNotification):\n    def SendNotification(self):\n        return \" Whatsapp message sent\"\n    \n\n# classe virtual para repositorio\nclass VirtualDataBaseinMemory(ABC):\n    @abstractmethod\n    def AddOrder(self,order: VirtualOrder):\n        pass\n\n    @abstractmethod\n    def ListOrder(self):\n        pass\n\n# classe concreta para repositorio\nclass DataBAse(VirtualDataBaseinMemory):\n     def __init__(self):\n          self.orders = []\n\n     def AddOrder(self, order: VirtualOrder):\n        self.orders.append(order)\n\n     def ListOrder(self):\n         print(f\" Orders in DB\")\n         for o in self.orders:\n             print(f\"{type(o).__name__} : {o.name} \")\n             \n\n# classe para procesar ordenes\n\nclass OrderProcess():\n    def __init__(self, order: VirtualOrder):\n        self.order = order\n\n    def ProcessOrder(self ):\n        print(f\"{ self.order.Process()}\")\n\n\n# class para procesar notificaciones\n\nclass NotificationProcess:\n    def __init__(self, Notification: VirtualNotification):\n        self.notification = Notification\n\n    def ClientNotification(self):\n        print(f\"{ self.notification.SendNotification()}\")\n\n#  classe que administra repositorio con repositorio\n\nclass RepositoryProcess:\n    def __init__(self, data: VirtualDataBaseinMemory):\n        self.storage = data\n\n    def SaveOrder(self, order: VirtualOrder):\n        self.storage.AddOrder(order)\n\n    def PrintOrders(self ):\n        self.storage.ListOrder()\n\n         \n    \nclass OnlineOrder:\n    def __init__(self, Process: OrderProcess, Notification: NotificationProcess, Repository: RepositoryProcess):\n        self.process = Process\n        self.notification = Notification\n        self.repository = Repository\n    \n    def ExecuteProcess(self):\n        self.process.ProcessOrder()\n\n    def ExecuteNotification(self):\n        self.notification.ClientNotification()\n\n    def ExecuteSaveRepository(self, order: VirtualOrder):\n        self.repository.SaveOrder(order)\n\n    def ExecuteListRepository(self):\n        self.repository.PrintOrders()\n         \n        \n# ordenes\ne = Electronic(\"TV\")\nc = Clothes(\"Shoes\")\nb = Books(\"Odisea\")\ni = Internet(\"WIFI Net\")\n\n# notificaciones\nemail = Email()\nsms = Sms()\nwhatsapp = Whatsapp()\ntelegram = Telegram()\n\n# repositorio\nDB = DataBAse()  \n\n#  crear orden con nueva notificacion \nP = OrderProcess(e) # creando procesando la orden e\nN = NotificationProcess(email) # creando notificando por email\nR = RepositoryProcess(DB) # procesando repositorio la orden e\n\n\nOL = OnlineOrder(P,N,R) # orquestador necsita proceso, la notificacion y el repositorio\nOL.ExecuteProcess() # executando proceso  \nOL.ExecuteNotification() # executando notificacion\nOL.ExecuteSaveRepository(P.order) # executando salva en el repo \n\n#  crear orden con nueva notificacion \nP = OrderProcess(b) # creando procesando la orden e\nN = NotificationProcess(sms) # creando notificando por email\n \n\nOL = OnlineOrder(P,N,R) # orquestador necsita proceso, la notificacion y el repositorio\nOL.ExecuteProcess() # executando proceso  \nOL.ExecuteNotification() # executando notificacion\nOL.ExecuteSaveRepository(P.order) # executando salva en el repo\n\n#  crear orden con nueva notificacion \nP = OrderProcess(c) # creando procesando la orden e\nN = NotificationProcess(whatsapp) # creando notificando por email\n \n\nOL = OnlineOrder(P,N,R) # orquestador necsita proceso, la notificacion y el repositorio\nOL.ExecuteProcess() # executando proceso  \nOL.ExecuteNotification() # executando notificacion\nOL.ExecuteSaveRepository(P.order) # executando salva en el repo\n\n#  crear orden con nueva notificacion \nP = OrderProcess(i) # creando procesando la orden e\nN = NotificationProcess(telegram) # creando notificando por email\n \n\nOL = OnlineOrder(P,N,R) # orquestador necsita proceso, la notificacion y el repositorio\nOL.ExecuteProcess() # executando proceso  \nOL.ExecuteNotification() # executando notificacion\nOL.ExecuteSaveRepository(P.order) # executando salva en el repo\n\n\nOL.ExecuteListRepository() # executando Listado\n\n \n\n \n \n\n# ¡Ahora sí que sí! 🙌 Este código está muy bien estructurado y está aplicando principios de diseño muy sólidos. Vamos por partes para darte un análisis claro, directo y útil 👇\n# ✅ Puntos fuertes\n# 🧱 1. Principios SOLID\n# Principio\t¿Cumplido?\tComentario\n# SRP - Responsabilidad única\t✅\tCada clase hace una sola cosa (procesar orden, notificar, guardar).\n# OCP - Abierto/Cerrado\t✅\tPuedes agregar nuevos tipos de pedidos o notificaciones sin modificar nada existente.\n# LSP - Sustitución de Liskov\t✅\tTodas las clases hijas pueden reemplazar a las padres sin romper nada.\n# ISP - Segregación de interfaces\t✅\tInterfaces pequeñas y específicas (VirtualOrder, VirtualNotification, etc.).\n# DIP - Inversión de dependencias\t✅✔️\tTus clases dependen de abstracciones, no de implementaciones concretas. El cliente aún instancia objetos concretos, pero está bien para este nivel de aplicación. Si lo complementas con una factory externa, ya es perfecto.\n# 🔁 2. Extensible y mantenible\n\n#     Agregaste una nueva clase Internet sin modificar el código existente ✅\n\n#     Agregaste Telegram como nuevo tipo de notificación sin tocar clases previas ✅\n\n#     Solo cambias en el \"cliente\", no en la lógica base del sistema ✅\n\n# 💡 3. Claridad y separación de responsabilidades\n\n# Tu OnlineOrder actúa como un orquestador que agrupa el flujo de procesamiento, notificación y almacenamiento. Muy buena idea, fácil de testear y mantener. ✔️\n# 🧪 4. Perfecto para unit testing\n\n# Todas las clases están desacopladas y fácilmente testeables por separado. Por ejemplo:\n\n# def test_sms_notification():\n#     sms = Sms()\n#     assert sms.SendNotification() == \" SMS message sent\"\n\n# 🛠️ Recomendaciones menores\n\n# Aquí unas sugerencias que podrían darte un toque más profesional:\n# 1. Renombrar DataBAse → DataBase\n\n# Solo un pequeño error tipográfico.\n# 2. Fábrica para instanciar pedidos y notificaciones (si quieres llevarlo al siguiente nivel)\n\n# Esto haría que tu código cumpla DIP al 100% y facilitaría leer desde un archivo o formulario web:\n\n# def create_order(order_type: str, name: str) -> VirtualOrder:\n#     orders = {\n#         \"internet\": Internet,\n#         \"electronic\": Electronic,\n#         \"clothes\": Clothes,\n#         \"books\": Books,\n#     }\n#     return orders[order_type](name)\n\n# def create_notification(method: str) -> VirtualNotification:\n#     notifications = {\n#         \"email\": Email,\n#         \"sms\": Sms,\n#         \"whatsapp\": Whatsapp,\n#         \"telegram\": Telegram\n#     }\n#     return notifications[method]\n\n# 3. Renombrar algunas variables para más claridad\n\n# En vez de:\n\n# P = OrderProcess(e)\n# N = NotificationProcess(email)\n\n# Podrías usar:\n\n# order_process = OrderProcess(e)\n# notification_process = NotificationProcess(email)\n\n# Esto mejora la legibilidad, especialmente en proyectos grandes.\n# 4. Devolver en vez de imprimir\n\n# Para que el sistema sea más reutilizable y testable, mejor que las funciones como ProcessOrder() o ClientNotification() devuelvan en lugar de imprimir:\n\n# def ProcessOrder(self):\n#     return self.order.Process()\n\n# # y en el cliente:\n# print(OL.process.ProcessOrder())\n\n\n\n# Refactor Sugerido (Mini-ejemplo)\n# python\n\n# Podrías crear un builder/factory para simplificar\n# class OrderBuilder:\n#     def __init__(self, db):\n#         self.db = db\n        \n#     def create_order(self, order, notifier):\n#         processor = OrderProcess(order)\n#         notifier = NotificationProcess(notifier)\n#         repo = RepositoryProcess(self.db)\n#         return OnlineOrder(processor, notifier, repo)\n\n# # Uso:\n# builder = OrderBuilder(DB)\n# ol = builder.create_order(e, email)\n# ol.ExecuteProcess()\n# ol.ExecuteNotification()\n\n# 🏁 Conclusión final\n\n# 🎯 Tu diseño está excelente.\n\n# ✅ Aplica SOLID perfectamente.\n# ✅ Es fácil de extender.\n# ✅ Está muy limpio, sin acoplamiento innecesario.\n# ✅ Es perfecto como base para una app real (con GUI, API o CLI).\n# ✅ El cliente tiene control completo del flujo sin modificar la lógica de negocio.\n\n#     Si lo que querías era aplicar OOP, buenas prácticas y SOLID de verdad, lo has clavado.\n#     ¿Quieres que te prepare una versión con factories, entrada por input() o con interfaz básica por consola?"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/python/rigo93acosta.py",
    "content": "'''\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Inversión de Dependencias (Dependency Inversion\n * Principle, DIP)\" y crea un ejemplo simple donde se muestre su funcionamiento \n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un sistema de notificaciones.\n * Requisitos:\n * 1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas).\n * 2. El sistema de notificaciones no puede depender de las implementaciones específicas.\n * Instrucciones:\n * 1. Crea la interfaz o clase abstracta.\n * 2. Desarrolla las implementaciones específicas.\n * 3. Crea el sistema de notificaciones usando el DIP.\n * 4. Desarrolla un código que compruebe que se cumple el principio.\n */\n'''\n\n'''\nEJERCICIO\n'''\n\n## SIN DIP\n## Sistema muy acoplado\n\nclass Switch():\n\n    def turn_on(self):\n        print(\"Enciende la lámpara\")\n\n    def turn_off(self):\n        print(\"Apaga la lámpara\")\n\nclass Lamp():\n\n    def __init__(self) -> None:\n        self.switch = Switch()\n\n    def operate(self, command):\n        if command == \"on\":\n            self.switch.turn_on()\n        elif command == \"off\":\n            self.switch.turn_off()\n    \nlamp = Lamp()\nlamp.operate(\"on\")\nlamp.operate(\"off\")\n\n## CON DIP\n\nclass AbstractSwitch():\n    \n    def turn_on(self):\n        pass\n\n    def turn_off(self):\n        pass\n\nclass LampSwitch(AbstractSwitch):\n    \n    def turn_on(self):\n        print(\"Enciende la lámpara\")\n\n    def turn_off(self):\n        print(\"Apaga la lámpara\")\n\n\nclass Lamp():\n\n    def __init__(self, switch: AbstractSwitch) -> None:\n        self.switch = switch\n\n    def operate(self, command):\n        if command == \"on\":\n            self.switch.turn_on()\n        elif command == \"off\":\n            self.switch.turn_off()\n\nlamp = Lamp(LampSwitch())\nlamp.operate(\"on\")\nlamp.operate(\"off\")\n\n'''\nDIFICULTAD EXTRA\n'''\n\nfrom abc import ABC, abstractmethod\n\nclass Notifier(ABC):\n        \n    @abstractmethod\n    def send(self, message: str):\n        pass\n\nclass EmailNotifier(Notifier):\n    def send(self, message: str):\n        print(f\"Email: {message}\")\n\nclass PushNotifier(Notifier):\n    def send(self, message: str):\n        print(f\"Push: {message}\")\n\nclass SMSNotifier(Notifier):\n    def send(self, message: str):\n        print(f\"SMS: {message}\")\n\nclass NotificationService():\n        \n    def __init__(self, notifier: Notifier) -> None:\n        self.notifier = notifier\n\n    def notify(self, message):\n        self.notifier.send(message)\n\nnotification_system = NotificationService(EmailNotifier())\nnotification_system.notify(\"Hello, World!\")\n\nnotification_system = NotificationService(PushNotifier())\nnotification_system.notify(\"Hello, World!\")\n\nnotification_system = NotificationService(SMSNotifier())\nnotification_system.notify(\"Hello, World!\")\n\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/python/rikmij.py",
    "content": "from abc import ABC, abstractmethod\n\n#Uso incorrecto\nclass Worker:\n    def __init__(self, name):\n        self.name = name\n    \n    def to_work(self):\n        return f\"Soy {self.name} y estoy trabajando\"\n\nclass Proyect:\n    def __init__(self, project):\n        self.project = project\n    \n    def work_in_project(self):\n        worker_name = Worker(\"John\")\n        return f\"{worker_name.name} está trabajando en {self.project}\"\n\nproy = Proyect(\"Google\")\nprint(proy.work_in_project())\n\n'''\nAquí incumplimos el DIP porque vemos que el proyecto depende del trabajador, y si cambiara el trabajador\nel proyecto se rompe, y eso no debe ocurrir\n'''\n\n#Uso correcto\nclass Department(ABC):\n    @abstractmethod\n    def work(self):\n        pass\n\nclass Employee(Department):\n    def __init__(self, name):\n        self.name = name\n    \n    def work(self):\n        return f\"Soy {self.name} y estoy trabajando\"\n\nclass Project(Department):\n    def __init__(self, project_name):\n        self.project_name = project_name\n    \n    def work(self):\n        return f\"El equipo está trabajando en {self.project_name}\"\n\nproj = Project(\"BushiGPT\")\nprint(proj.work())\n\nprint(\"\\n\", \"*\"*7, \" EJERCICIO EXTRA \", \"*\"*7)\n\nclass Notification(ABC):\n    @abstractmethod\n    def send_notification(user):\n        pass\n\nclass Send_email(Notification):\n    def send_notification(user):\n        dest = input(\"Para: \")\n        subject = input(\"Asunto: \")\n        text = input(\"Mensaje: \")\n\n        return f\"De: {user}\\nPara: {dest}\\nAsunto: {subject}\\n {text}\"\n\nclass Send_push(Notification):\n    def send_notification(user):\n        text = input(\"Mensaje: \")\n\n        return f\"@{user}\\n {text}\"\n\nclass Send_sms(Notification):\n    def send_notification(user):\n        text = input(\"Mensaje: \")\n\n        return f\"De: {user}\\n {text}\"\n\ndef send_message():\n    print(\"¿Qué tipo de notificación quieres enviar?\\n\",\n                \"1.- Correo\\n\",\n                \"2.- Push\\n\",\n                \"3.- SMS\\n\")\n    option = int(input())\n\n    match option:\n        case 1:\n            print(Send_email.send_notification(\"ejemplo@prueba.com\"))\n        case 2:\n            print(Send_push.send_notification(\"TipodeIncognito\"))\n        case 3:\n            print(Send_sms.send_notification(123456789))\n\nsend_message()\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/python/santyjL.py",
    "content": "#30 SOLID: PRINCIPIO DE INVERSIÓN DE DEPENDENCIAS (DIP)\n\n\n\"\"\"\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Inversión de Dependencias (Dependency Inversion\n * Principle, DIP)\" y crea un ejemplo simple donde se muestre su funcionamiento\n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un sistema de notificaciones.\n * Requisitos:\n * 1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas).\n * 2. El sistema de notificaciones no puede depender de las implementaciones específicas.\n * Instrucciones:\n * 1. Crea la interfaz o clase abstracta.\n * 2. Desarrolla las implementaciones específicas.\n * 3. Crea el sistema de notificaciones usando el DIP.\n * 4. Desarrolla un código que compruebe que se cumple el principio.\n */\n\"\"\"\n\nfrom abc import ABC, abstractmethod\n\n\nclass SaludoIngles:\n    def generar_saludo(self):\n        return \"Hello!\"\n\nclass Saludador:\n    def __init__(self):\n        self.saludo = SaludoIngles()  # Dependencia concreta\n\n    def saludar(self):\n        print(self.saludo.generar_saludo())\n\n# Uso\nsaludador = Saludador()\nsaludador.saludar()\n\n# Definimos una interfaz o clase abstracta\nclass Saludo(ABC):\n    @abstractmethod\n    def generar_saludo(self):\n        pass\n\n# Implementación concreta en inglés\nclass SaludoIngles(Saludo):\n    def generar_saludo(self):\n        return \"Hello!\"\n\n# Implementación concreta en español\nclass SaludoEspanol(Saludo):\n    def generar_saludo(self):\n        return \"¡Hola!\"\n\n# Clase que sigue el IDP\nclass Saludador:\n    def __init__(self, saludo: Saludo):  # Dependencia abstracta\n        self.saludo = saludo\n\n    def saludar(self):\n        print(self.saludo.generar_saludo())\n\n# Uso con diferentes saludos\nsaludador_ingles = Saludador(SaludoIngles())\nsaludador_espanol = Saludador(SaludoEspanol())\n\nsaludador_ingles.saludar()  # \"Hello!\"\nsaludador_espanol.saludar()  # \"¡Hola!\"\n\n\n# Extra\nclass Notificador(ABC):\n    @abstractmethod\n    def enviar_notificacion(self, mensaje: str):\n        pass\n\nclass Email(Notificador):\n    def enviar_notificacion(self, mensaje: str):\n        print(\"Se envió el mensaje por Email: \", mensaje)\n\nclass Push(Notificador):\n    def enviar_notificacion(self, mensaje: str):\n        print(\"Se envió el mensaje por Push: \", mensaje)\n\nclass SMS(Notificador):\n    def enviar_notificacion(self, mensaje: str):\n        print(\"Se envió el mensaje por SMS: \", mensaje)\n\nclass SistemaNotificador:\n    def __init__(self, notificador: Notificador):\n        self.notificador = notificador\n\n    def enviar(self, mensaje: str):\n        self.notificador.enviar_notificacion(mensaje)\n\n# Ejemplo de uso\nnotificador_sms = SistemaNotificador(SMS())\nnotificador_push = SistemaNotificador(Push())\nnotificador_email = SistemaNotificador(Email())\n\nnotificador_sms.enviar(\"Hola mundo\")\nnotificador_push.enviar(\"Hola mundo\")\nnotificador_email.enviar(\"Hola mundo\")\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/rust/kenysdev.rs",
    "content": "/*\n╔═══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado                ║\n║ GitHub: https://github.com/Kenysdev   ║\n║ 2024 -  Rust                          ║\n╚═══════════════════════════════════════╝\n-----------------------------------------------------\n* SOLID: PRINCIPIO DE INVERSIÓN DE DEPENDENCIAS (DIP)\n-----------------------------------------------------\n- Los módulos de alto nivel no deben depender de módulos de bajo nivel, sino de abstracciones. A su vez, las \n  abstracciones no deben depender de detalles concretos; los detalles deben depender de las abstracciones.\n\n______________________________________\n* EJERCICIO #1:\n* Explora el \"Principio SOLID de Inversión de Dependencias (Dependency Inversion\n* Principle, DIP)\" y crea un ejemplo simple donde se muestre su funcionamiento \n* de forma correcta e incorrecta.\n*/\n\n// ___________________________________\n// De manera INCORRECTA:\n\n// Estructura de 'bajo nivel'\nstruct FileStorage_;\nimpl FileStorage_ {\n    fn save(&self, data: &str) {\n        println!(\"Datos guardados en archivo: {}\", data)\n    }\n}\n\n// Estructura de 'bajo nivel'\nstruct DatabaseStorage_;\nimpl DatabaseStorage_ {\n    fn save(&self, data: &str) {\n        println!(\"Guardado en base de datos: {}\", data)\n    }\n}\n\n// Estructura de 'alto nivel'\nstruct DataManager_ {\n    file_storage: FileStorage_,\n    database_storage: DatabaseStorage_,\n}\n\nimpl DataManager_ {\n\n    //# Dependencia directa de Estructuras concretas('de bajo nivel')\n    fn new() -> Self {\n        DataManager_ {\n            file_storage: FileStorage_,\n            database_storage: DatabaseStorage_,\n        }\n    }\n\n    fn file_storage(&self, data: &str) {\n        self.file_storage.save(data);\n    }\n\n    fn database_storage(&self, data: &str) {\n        self.database_storage.save(data);\n    }\n}\n\n// ___________________________________\n// De manera CORRECTA:\n\n// 'Interfaz'\ntrait IStorage {\n    fn save(&self, data: &str);\n}\n\n// Estructura concreta\nstruct FileStorage;\nimpl IStorage for FileStorage {\n    fn save(&self, data: &str) {\n        println!(\"Datos guardados en archivo: {}\", data)\n    }\n}\n\n// Estructura concreta\nstruct DatabaseStorage;\nimpl IStorage for DatabaseStorage {\n    fn save(&self, data: &str) {\n        println!(\"Guardado en base de datos: {}\", data)\n    }\n}\n\n// Estructura de 'alto nivel'\nstruct DataManager<T: IStorage> {\n  storage: T,\n}\nimpl <T: IStorage> DataManager<T> {\n\n  //# Depende de las instancias que recibe, las cuales implementan la interfaz.\n  fn new(storage: T) -> Self {\n      DataManager { storage }\n  }\n\n  fn store_data(&self, data: &str) {\n      self.storage.save(data);\n  }\n}\n\n/*\n//____________________________________\n* EJERCICIO #2:\n* Crea un sistema de notificaciones.\n* Requisitos:\n* 1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas).\n* 2. El sistema de notificaciones no puede depender de las implementaciones específicas.\n* Instrucciones:\n* 1. Crea la interfaz o clase abstracta.\n* 2. Desarrolla las implementaciones específicas.\n* 3. Crea el sistema de notificaciones usando el DIP.\n* 4. Desarrolla un código que compruebe que se cumple el principio.\n*/\n\ntrait INotificationService {\n  fn send(&self, to: &str, msg: &str);\n}\n\n// Implementación\nstruct EmailService;\n\nimpl INotificationService for EmailService {\n  fn send(&self, to: &str, msg: &str) {\n      println!(\"Correo enviado a: {}\", to);\n      println!(\"Mensaje: {}\", msg);\n  }\n}\n\n// Implementación\nstruct PushService;\n\nimpl INotificationService for PushService {\n  fn send(&self, to: &str, msg: &str) {\n      println!(\"Notificación PUSH enviada a: {}\", to);\n      println!(\"Mensaje: {}\", msg);\n  }\n}\n\n// Implementación\nstruct SmsService;\n\nimpl INotificationService for SmsService {\n  fn send(&self, to: &str, msg: &str) {\n      println!(\"Mensaje SMS enviado a: {}\", to);\n      println!(\"Mensaje: {}\", msg);\n  }\n}\n\n// Estructura 'de alto nivel'\nstruct NotificationSystem<T: INotificationService> {\n  service: T,\n}\n\nimpl<T: INotificationService> NotificationSystem<T> {\n  fn new(service: T) -> Self {\n      NotificationSystem { service }\n  }\n\n  fn notify(&self, to: &str, msg: &str) {\n      self.service.send(to, msg);\n  }\n}\n\n//____________________________________\nfn main() {\n    //________________________________\n    // exs 1\n    println!(\"Exs #1\");\n\n    // Usando ejemplo incorrecto:\n    println!(\"Uso incorrecto:\");\n\n    let data_manager_ = DataManager_::new();\n    data_manager_.file_storage(\"datos x\");\n    data_manager_.database_storage(\"datos x\");\n\n    // Usando ejemplo correcto:\n    println!(\"Uso correcto:\");\n\n    // Instancias:\n    let file_storage = FileStorage;\n    let database_storage = DatabaseStorage;\n\n    // Inyección\n    let data_manager_file = DataManager::new(file_storage);\n    let data_manager_database = DataManager::new(database_storage);\n    \n    // Uso del metodo implementado\n    data_manager_file.store_data(\"datos x\");\n    data_manager_database.store_data(\"datos x\");\n\n    //________________________________\n    // exs 2\n    println!(\"\\nExs #2\");\n\n    let email_service = EmailService;\n    let push_service = PushService;\n    let sms_service = SmsService;\n\n    let email_system = NotificationSystem::new(email_service);\n    email_system.notify(\"email@example.com\", \"Correo!\");\n\n    let push_system = NotificationSystem::new(push_service);\n    push_system.notify(\"usuario123\", \"Notificación PUSH\");\n\n    let sms_system = NotificationSystem::new(sms_service);\n    sms_system.notify(\"555-1234\", \"Mensaje SMS\")\n    \n}\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/sql/Nicojsuarez2.sql",
    "content": "# #30 SOLID: PRINCIPIO DE INVERSIÓN DE DEPENDENCIAS (DIP)\n> #### Dificultad: Media | Publicación: 22/07/24 | Corrección: 29/07/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Inversión de Dependencias (Dependency Inversion\n * Principle, DIP)\" y crea un ejemplo simple donde se muestre su funcionamiento \n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un sistema de notificaciones.\n * Requisitos:\n * 1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas).\n * 2. El sistema de notificaciones no puede depender de las implementaciones específicas.\n * Instrucciones:\n * 1. Crea la interfaz o clase abstracta.\n * 2. Desarrolla las implementaciones específicas.\n * 3. Crea el sistema de notificaciones usando el DIP.\n * 4. Desarrolla un código que compruebe que se cumple el principio.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/swift/blackriper.swift",
    "content": "/*\n inversion depedency principle \n el principio establece dos partes \n\n 1.-Los módulos de alto nivel no deberían depender de los módulos de bajo nivel, ambos deben depender de abstracciones\n 2.-Las abstracciones no deberían depender de los detalles, los detalles deben depender de las abstracciones\n\n */\n\n//ejemplo de lo que no debe de hacerce  al cambiar por otro driver hay que destruir la clase \nclass MySqlDatabase{\n    private var host:String\n    private var port:Int\n    private var database:String\n\n    init(server:String,port:Int,name:String){\n        self.host=server\n        self.port=port\n        self.database=name\n    }\n\n    func connect()->String{\n      return \"connect to \\(database) for \\(host) and \\(port)\"\n    }\n\n    func executeQuery(_ rawString:String)->String{\n        return \"execute query : \\(rawString)\"\n    }\n\n    func disconnect()->String{\n        return \"disconnect MySqlDatabase\"\n    }\n\n}\n\n// aplicando inversion de dependencias \n\n//1.- definimos un protocolo que va tener elas abstracciones del comportamiento\n\nprotocol Database {\n   func connect()->String\n   func executeQuery(_ rawString:String)->String \n   func disconnect()->String  \n}\n\n//2.-Definimos los diferentes drivers de conexion \n\nclass OracleDatabase:Database{\n    private var host:String\n    private var port:Int\n    private var database:String\n\n    init(_ server:String,_ port:Int,_ name:String){\n        self.host=server\n        self.port=port\n        self.database=name\n    }\n\n    func connect()->String{\n      return \"connect to \\(database) for \\(host) and \\(port)\"\n    }\n\n   func executeQuery(_ rawString: String) -> String {\n     return \"execute query: \\(rawString) \"\n   }\n    func disconnect()->String{\n        return \"disconnect OracleDatabase\"\n    }\n\n}\n\nclass PostgreSQLDatabase:Database{\n    private var host:String\n    private var port:Int\n    private var database:String\n\n    init(_ server:String,_ port:Int,_ name:String){\n        self.host=server\n        self.port=port\n        self.database=name\n    }\n\n    func connect()->String{\n      return \"connect to \\(database) for \\(host) and \\(port)\"\n    }\n\n    func executeQuery(_ rawString:String)->String{\n        return \"execute query : \\(rawString)\"\n    }\n\n    func disconnect()->String{\n        return \"disconnect PostgreSQL\"\n    }\n\n}\n\n// como las clases no tienen que deondender de las capas inferiores creamos una nueva clase  \n\nclass ModelRepository{\n    private var database:Database\n     \n     init(_ provider:Database){\n        self.database=provider\n    }\n\n\n    func connectDatabase()->String{\n       return database.connect()  \n    }\n\n    func executeSentence(sentence: String)->String{\n        return database.executeQuery(sentence)\n    }\n\n    func disconnectDatabase()->String{\n        return database.disconnect()\n    }\n}\n\n\nlet repo=ModelRepository(OracleDatabase(\"localhost\",1521,\"books\"))\nprint(repo.connectDatabase())\nprint(repo.executeSentence(sentence: \"SELECT id_book,title from books\"))\nprint(repo.disconnectDatabase())\n\nlet repo1=ModelRepository(PostgreSQLDatabase(\"localhost\",5432,\"products\"))\nprint(repo1.connectDatabase())\nprint(repo1.executeSentence(sentence: \"SELECT * FROM products\"))\nprint(repo1.disconnectDatabase())\n\n// ejercicio extra \n\nprotocol Notification{\n    func buildNotification()->String\n}\n\nstruct Email:Notification{\n     let subject:String\n     let to:String \n     let body:String\n\n    func buildNotification() -> String {\n    return \"\"\"\n       Subject: \\(self.subject)\n       To: \\(self.to)\n\n       \\(self.body) \n\n\n    \"\"\"\n    }\n}\n\nstruct SMS:Notification{\n     let to: String\n     let from:String\n     let message:String \n\n    func buildNotification() -> String {\n    return \"\"\"\n          To: \\(self.to)\n          From: \\(self.from)\n\n          \\(self.message)\n\n    \"\"\"\n    }\n}\n\n\nstruct Push: Notification{\n      let appName:String\n      let title:String\n      let content:String \n\n    func buildNotification() -> String {\n    return  \"\"\"\n        \\(self.appName)\n     ___________________________________\n     \\(title)\n\n     \\(content)\n    \"\"\"\n    }\n}\n\nstruct NotificationFactory<T:Notification>:Notification{\n    var notification: T \n    func buildNotification() -> String {\n        return notification.buildNotification()\n    }\n}\n\nlet emailpush=NotificationFactory(notification: Email(subject: \"dccomics@dccomics.com\", to: \"black@gmail.com\", body: \"your comics sold is processing\"))\nprint(emailpush.buildNotification())\n\nlet push=NotificationFactory(notification: Push(appName: \"youtube\", title: \"celebracion 6 años de freelance \", content: \"directo para celebrar los seis años de desarrollador de brais moure \"))\nprint(push.buildNotification())\n\nlet sms = NotificationFactory(notification: SMS(to: \"citiBanamex\", from: \"blackriper\", message: \"Deposito de  $500 \"))\nprint(sms.buildNotification())\n\n\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/typescript/Sac-Corts.ts",
    "content": "// Wrong way\nclass UserService {\n    private database: MySQLDatabase;\n\n    constructor() {\n        this.database = new MySQLDatabase();\n    }\n\n    getUser(id: number) {\n        return this.database.findUserById(id);\n    }\n}\n\nclass MySQLDatabase {\n    findUserById(id: number) {\n        return { id, name: 'Isaac Cortés', db: 'MySQL' };\n    }\n}\n\nconst userService = new UserService();\nconsole.log(userService.getUser(1));\n\n// Correct way\nclass UserService2 {\n    private database: Database;\n\n    constructor(database: Database) {\n        this.database = database;\n    }\n\n    getUser(id: number) {\n        return this.database.findUserById(id);\n    }\n}\n\nabstract class Database {\n    abstract findUserById(id: number): { id: number; name: string; db: string };\n}\n\nclass MySQLDatabase2 extends Database {\n    findUserById(id: number) {\n        return { id, name: 'Isaac Cortés', db: 'MySQL' };\n    }\n}\n\nclass MongoDBDatabase extends Database {\n    findUserById(id: number) {\n        return { id, name: 'Isaac Cortés', db: 'MongoDB' };\n    }\n}\n\nconst mysqlService = new UserService2(new MySQLDatabase2());\nconsole.log(mysqlService.getUser(1));\n\nconst mongoService = new UserService2(new MongoDBDatabase());\nconsole.log(mongoService.getUser(2));\n\n// ** Extra Exercise ** //\nabstract class NotificationService {\n    abstract sendNotification(message: string, recipient: string): void;\n}\n\nclass EmailNotification extends NotificationService {\n    sendNotification(message: string, recipient: string): void {\n        console.log(`Sending email to ${recipient}: ${message}`);\n    }\n}\n\nclass PushNotification extends NotificationService {\n    sendNotification(message: string, recipient: string): void {\n        console.log(`Sending push to ${recipient}: ${message}`);\n    }\n}\n\nclass SMSNotification extends NotificationService {\n    sendNotification(message: string, recipient: string): void {\n        console.log(`Sending SMS to ${recipient}: ${message}`);\n    }\n}\n\nclass NotificationManager {\n    private notificationService: NotificationService;\n\n    constructor(notificationService: NotificationService) {\n        this.notificationService = notificationService;\n    }\n\n    send(message: string, recipient: string): void {\n        this.notificationService.sendNotification(message, recipient);\n    }\n}\n\nconst emailService = new EmailNotification();\nconst pushService = new PushNotification();\nconst smsService = new SMSNotification();\n\nconst emailManager = new NotificationManager(emailService);\nconst pushManager = new NotificationManager(pushService);\nconst smsManager = new NotificationManager(smsService);\n\nemailManager.send('Hello, Isaac!', 'isaac@gmail.com');\npushManager.send('Hello, Isaac!', 'sac');\nsmsManager.send('Hello, Isaac!', '8992584897');\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/typescript/duendeintemporal.ts",
    "content": "//#30 - Principio SOLID de Inversión de Dependencias (Dependency Inversion Principle (DIP))\n/*\n * EJERCICIO:\n * Explora el \"Principio SOLID de Inversión de Dependencias (Dependency Inversion\n * Principle, DIP)\" y crea un ejemplo simple donde se muestre su funcionamiento \n * de forma correcta e incorrecta.\n *\n * DIFICULTAD EXTRA (opcional):\n * Crea un sistema de notificaciones.\n * Requisitos:\n * 1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas).\n * 2. El sistema de notificaciones no puede depender de las implementaciones específicas.\n * Instrucciones:\n * 1. Crea la interfaz o clase abstracta.\n * 2. Desarrolla las implementaciones específicas.\n * 3. Crea el sistema de notificaciones usando el DIP.\n * 4. Desarrolla un código que compruebe que se cumple el principio.\n */\n//Bibliografy: The Web Development Glossary (Jens Oliver Meiert) (Z-Library)\n//GPT\n\n/* Dependency Inversion Principle\nA specific form of decoupling software modules. When following this\nprinciple, the conventional dependency relationships established from\nhigh-level policy-setting modules to low-level dependency modules are\nreversed, thus rendering high-level modules independent of the low-level\nmodule implementation details. The principle states 1) that high-level\nmodules should not depend on low-level modules, but that both should\ndepend on abstractions (e.g., interfaces), and 2) that abstractions should\nnot depend on details, but that details (concrete implementations) should\ndepend on abstractions.\n\nA class that contains methods for use by other classes without having to be\nthe parent class of those other classes. How those other classes gain access\nto the mixin’s methods depends on the language. Mixins are sometimes\ndescribed as being “included” rather than “inherited.” Mixins encourage\ncode reuse and can be used to avoid the inheritance ambiguity that\nmultiple inheritance can cause, or to work around lack of support for\nmultiple inheritance in a language. A mixin can also be viewed as an\ninterface with implemented methods. This pattern is an example of\nenforcing the Dependency Inversion Principle */\n\nlet log = console.log;\n\n// Check if running in a browser environment\nconst isBrowser = typeof window !== 'undefined';\n\n// Conditional check for browser environment\nif (isBrowser) {\n    window.addEventListener('load', () => {\n        const body: HTMLBodyElement | null = document.querySelector('body');\n        const title = document.createElement('h1');\n\n        body?.style.setProperty('background', '#000');\n        body?.style.setProperty('text-align', 'center');\n\n        title.textContent = 'Retosparaprogramadores #30.';\n        title.style.setProperty('font-size', '3.5vmax');\n        title.style.setProperty('color', '#fff');\n        title.style.setProperty('line-height', '100vh');\n\n        body?.appendChild(title);\n\n        setTimeout(() => {\n            alert('Retosparaprogramadores #30. Please open the Browser Developer Tools.');\n        }, 2000);\n        log('Retosparaprogramadores #30');\n    });\n} else {\n    log('This code is designed to run in a browser environment. Skipping window-related code.');\n    log('Retosparaprogramadores #30');\n}\n\n// Incorrect Example\n\nclass USABillingService1 {\n    calculateCharge(duration: number): number {\n        return duration * 0.10; // $0.10 per minute\n    }\n}\n\nclass CallBillingService1 {\n    public billingService: USABillingService1;\n\n    constructor() {\n        this.billingService = new USABillingService1(); // Direct dependency\n    }\n\n    billCall(duration: number): void {\n        const charge = this.billingService.calculateCharge(duration);\n        log(`Total charge: ${charge.toFixed(2)}`);\n    }\n}\n\nconst callBillingService1 = new CallBillingService1();\ncallBillingService1.billCall(22); // Total charge: 2.20\n\n// Correct Example\n\ninterface IBillingService {\n    calculateCharge(duration: number): number;\n    location: string; // Add location property to the interface\n}\n\nclass USABillingService implements IBillingService {\n    public location: string;\n\n    constructor() {\n        this.location = 'USA';\n    }\n\n    calculateCharge(duration: number): number {\n        return duration * 0.10;\n    }\n}\n\nclass EuropeBillingService implements IBillingService {\n    public location: string;\n\n    constructor() {\n        this.location = 'Europe';\n    }\n\n    calculateCharge(duration: number): number {\n        return duration * 0.15;\n    }\n}\n\nclass AsiaBillingService implements IBillingService {\n    public location: string;\n\n    constructor() {\n        this.location = 'Asia';\n    }\n\n    calculateCharge(duration: number): number {\n        return duration * 0.05;\n    }\n}\n\nclass CallBillingService {\n    public billingService: IBillingService;\n\n    constructor(billingService: IBillingService) {\n        this.billingService = billingService; // Dependency injection\n    }\n\n    billCall(duration: number): void {\n        const charge = this.billingService.calculateCharge(duration);\n        log(`Total charge for ${this.billingService.location}: ${charge.toFixed(2)}`);\n    }\n}\n\nconst usaBillingService = new USABillingService();\nconst europeBillingService = new EuropeBillingService();\nconst asiaBillingService = new AsiaBillingService();\n\nconst callBillingServiceUSA = new CallBillingService(usaBillingService);\nconst callBillingServiceEurope = new CallBillingService(europeBillingService);\nconst callBillingServiceAsia = new CallBillingService(asiaBillingService);\n\ncallBillingServiceUSA.billCall(127.22); // USA call Total charge: 12.72\ncallBillingServiceEurope.billCall(17.56); // Europe call Total charge: 2.63\ncallBillingServiceAsia.billCall(45.23); // Asia call Total charge: 2.26"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/typescript/hozlucas28.ts",
    "content": "/*\n    Dependency Inversion Principle (DIP)...\n*/\n\nconsole.log('Dependency Inversion Principle (DIP)...')\n\nconsole.log('\\nBad implementation of Dependency Inversion Principle (DIP)...')\n\ninterface IUserRepository {\n    getUsers: () => string[]\n}\n\nclass UserRepository implements IUserRepository {\n    public getUsers(): string[] {\n        return ['User N°1', 'User N°2', 'User N°3']\n    }\n}\n\ninterface IBadUserService {\n    getUsers: () => string[]\n}\n\nclass BadUserService implements IUserRepository {\n    private userRepository: UserRepository\n\n    public constructor() {\n        this.userRepository = new UserRepository()\n    }\n\n    public getUsers(): string[] {\n        return this.userRepository.getUsers()\n    }\n}\n\nconsole.log(`\\n\\`\\`\\`\\ninterface IUserRepository {\n    getUsers: () => string[]\n}\n\nclass UserRepository implements IUserRepository {\n    public getUsers(): string[] {\n        return ['User N°1', 'User N°2', 'User N°3']\n    }\n}\n\ninterface IBadUserService {\n    getUsers: () => string[]\n}\n\nclass BadUserService implements IUserRepository {\n    private userRepository: UserRepository\n\n    public constructor() {\n        this.userRepository = new UserRepository()\n    }\n\n    public getUsers(): string[] {\n        return this.userRepository.getUsers()\n    }\n}\\n\\`\\`\\``)\n\nconsole.log(\n    '\\nThis is a bad implementation of Dependency Inversion Principle (DIP),\\n' +\n        '\"BadUserService\" class depends directly on the \"UserRepository\" class \\n' +\n        'rather than on an abstract class or an interface. So, if the \"userRepository\"\\n' +\n        'attribute in the \"BadUserService\" class needs to be changed, the constructor must\\n' +\n        'also be modified.'\n)\n\nconsole.log('\\nGood implementation of Dependency Inversion Principle (DIP)...')\n\nclass UserLocalRepository implements IUserRepository {\n    public getUsers(): string[] {\n        return ['Local user N°1', 'Local user N°2', 'Local user N°3']\n    }\n}\n\nclass UserRemoteRepository implements IUserRepository {\n    public getUsers(): string[] {\n        return ['Remote user N°1', 'Remote user N°2', 'Remote user N°3']\n    }\n}\n\ninterface IGoodUserService {\n    getUsers: () => string[]\n}\n\nclass GoodUserService implements IGoodUserService {\n    private userRepository: IUserRepository\n\n    public constructor(userRepository: IUserRepository) {\n        this.userRepository = userRepository\n    }\n\n    public getUsers(): string[] {\n        return this.userRepository.getUsers()\n    }\n}\n\nconsole.log(`\\n\\`\\`\\`\\ninterface IUserRepository {\n    getUsers: () => string[]\n}\n\nclass UserLocalRepository implements IUserRepository {\n    public getUsers(): string[] {\n        return ['Local user N°1', 'Local user N°2', 'Local user N°3']\n    }\n}\n\nclass UserRemoteRepository implements IUserRepository {\n    public getUsers(): string[] {\n        return ['Remote user N°1', 'Remote user N°2', 'Remote user N°3']\n    }\n}\n\ninterface IGoodUserService {\n    getUsers: () => string[]\n}\n\nclass GoodUserService implements IGoodUserService {\n    private userRepository: IUserRepository\n\n    public constructor(userRepository: IUserRepository) {\n        this.userRepository = userRepository\n    }\n\n    public getUsers(): string[] {\n        return this.userRepository.getUsers()\n    }\n}\\n\\`\\`\\``)\n\nconsole.log(\n    '\\nThis is a good implementation of Dependency Inversion Principle (DIP),\\n' +\n        'because \"GoodUserService\" class depends solely on injected dependencies\\n' +\n        'that implement the \"IUserRepository\" interface. So, if the \"userRepository\"\\n' +\n        'attribute in the \"GoodUserService\" class needs to be changed, the constructor\\n' +\n        'does not require modification (only the class call needs to be updated). For example,\\n' +\n        'I could inject inside the \"userRepository\" attribute an instance of \"UserLocalRepository\"\\n' +\n        'or \"UserRemoteRepository\" classes.'\n)\n\nconsole.log(\n    '\\n# ---------------------------------------------------------------------------------- #\\n'\n)\n\n/*\n    Additional challenge...\n*/\n\nconsole.log('Additional challenge...')\n\ninterface INotificationService {\n    send: () => void\n}\n\nclass EmailService implements INotificationService {\n    public constructor() {}\n\n    public send(): void {\n        console.log('Email sent!')\n    }\n}\n\nclass PushService implements INotificationService {\n    public constructor() {}\n\n    public send(): void {\n        console.log('Push sent!')\n    }\n}\n\nclass SMSService implements INotificationService {\n    public constructor() {}\n\n    public send(): void {\n        console.log('SMS sent!')\n    }\n}\n\ninterface INotificationSystem {\n    sendNotification: () => void\n}\n\nclass NotificationSystem implements INotificationSystem {\n    private notificationService: INotificationService\n\n    public constructor(notificationService: INotificationService) {\n        this.notificationService = notificationService\n    }\n\n    public sendNotification(): void {\n        this.notificationService.send()\n    }\n}\n\nconst emailService: EmailService = new EmailService()\nconst pushService: PushService = new PushService()\nconst smsService: SMSService = new SMSService()\n\nconst emailNotificationSystem: NotificationSystem = new NotificationSystem(\n    emailService\n)\n\nconst pushNotificationSystem: NotificationSystem = new NotificationSystem(\n    pushService\n)\n\nconst smsNotificationSystem: NotificationSystem = new NotificationSystem(\n    smsService\n)\n\nconsole.log()\nemailNotificationSystem.sendNotification()\n\nconsole.log()\npushNotificationSystem.sendNotification()\n\nconsole.log()\nsmsNotificationSystem.sendNotification()\n"
  },
  {
    "path": "Roadmap/30 - SOLID DIP/vb.net/kenysdev.vb",
    "content": "' ╔══════════════════════════════════════╗\n' ║ Autor:  Kenys Alvarado               ║\n' ║ GitHub: https://github.com/Kenysdev  ║\n' ║ 2024 -  VB.NET                       ║\n' ╚══════════════════════════════════════╝\n'-----------------------------------------------------\n'* SOLID: PRINCIPIO DE INVERSIÓN DE DEPENDENCIAS (DIP)\n'-----------------------------------------------------\n' - Los módulos de alto nivel no deben depender de módulos de bajo nivel, sino de abstracciones. A su vez, las \n'   abstracciones no deben depender de detalles concretos; los detalles deben depender de las abstracciones.\n\n' ____________________________________________________\n' * EJERCICIO #1:\n'* Explora el \"Principio SOLID de Inversión de Dependencias (Dependency Inversion\n'* Principle, DIP)\" y crea un ejemplo simple donde se muestre su funcionamiento \n'* de forma correcta e incorrecta.\n\n' ____________________________________________________\n' De manera INCORRECTA\n\n' Clase de bajo nivel\nPublic Class CsvExporter_\n    Public Sub Export(Data As String)\n        Console.WriteLine($\"Exportando datos a CSV: {Data}\")\n    End Sub\nEnd Class\n\n' Clase de bajo nivel\nPublic Class JsonExporter_\n    Public Sub Export(Data As String)\n        Console.WriteLine($\"Exportando datos a JSON: {Data}\")\n    End Sub\nEnd Class\n\n' Clase de alto nivel\nPublic Class ReportGenerator_\n    Private _csvExporter As CsvExporter_\n    Private _jsonExporter As JsonExporter_\n\n    Public Sub New()\n        ' Dependencia de clases especificas(módulos de bajo nivel)\n        _csvExporter = New CsvExporter_\n        _jsonExporter = New JsonExporter_\n    End Sub\n\n    Public Sub GenerateCsvReport(Data As String)\n        _csvExporter.Export(Data)\n    End Sub\n\n    Public Sub GenerateJsonReport(Data As String)\n        _jsonExporter.Export(Data)\n    End Sub\nEnd Class\n\n' ____________________________________________________\n' De manera CORRECTA\n\nPublic Interface IExporter\n    Sub Export(Data As String)\nEnd Interface\n\n' Implementación\nPublic Class CsvExporter\n    Implements IExporter\n\n    Public Sub Export(Data As String) Implements IExporter.Export\n        Console.WriteLine($\"Exportando datos a CSV: {Data}\")\n    End Sub\nEnd Class\n\n' Implementación\nPublic Class JsonExporter\n    Implements IExporter\n\n    Public Sub Export(Data As String) Implements IExporter.Export\n        Console.WriteLine($\"Exportando datos a JSON: {Data}\")\n    End Sub\nEnd Class\n\n' Clase de alto nivel\nPublic Class ReportGenerator\n    Private _Exporter As IExporter\n\n    Public Sub New(Exporter As IExporter)\n        ' Ya no está dependiendo de una clase específica(módulo de bajo nivel).\n        ' Depende de las instancias que recibe, las cuales implementan la interfaz.\n        _Exporter = Exporter\n    End Sub\n\n    Public Sub Generate(Data As String)\n        _Exporter.Export(Data)\n    End Sub\nEnd Class\n\n' ____________________________________________________\n' * EJERCICIO #2:\n'* Crea un sistema de notificaciones.\n'* Requisitos:\n'* 1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas).\n'* 2. El sistema de notificaciones no puede depender de las implementaciones específicas.\n'* Instrucciones:\n'* 1. Crea la interfaz o clase abstracta.\n'* 2. Desarrolla las implementaciones específicas.\n'* 3. Crea el sistema de notificaciones usando el DIP.\n'* 4. Desarrolla un código que compruebe que se cumple el principio.\n\nPublic Interface INotificationService\n    Sub Send(To_ As Object, Msg As String)\nEnd Interface\n\n' Implementación\nPublic Class EmailService\n    Implements INotificationService\n\n    Public Sub Send(To_ As Object, Msg As String) Implements INotificationService.Send\n        Console.WriteLine($\"Correo enviado a: {To_}\")\n        Console.WriteLine($\"Mensaje: {Msg}\")\n    End Sub\nEnd Class\n\n' Implementación\nPublic Class PUSHService\n    Implements INotificationService\n\n    Public Sub Send(To_ As Object, Msg As String) Implements INotificationService.Send\n        Console.WriteLine($\"Notificación PUSH enviado a: {To_}\")\n        Console.WriteLine($\"Mensaje: {Msg}\")\n    End Sub\nEnd Class\n\n' Implementación\nPublic Class SMSService\n    Implements INotificationService\n\n    Public Sub Send(To_ As Object, Msg As String) Implements INotificationService.Send\n        Console.WriteLine($\"Mensaje SMS enviado a: {To_}\")\n        Console.WriteLine($\"Mensaje: {Msg}\")\n    End Sub\nEnd Class\n\n' Clase de alto nivel\nPublic Class NotificationSystem\n    Private _Service As INotificationService\n\n    'Depende de las inatancias recibidas, las cuales implementan la interfaz.\n    Public Sub New(Service As INotificationService)\n        _Service = Service\n    End Sub\n\n    Public Sub Notify(To_ As Object, Msg As String)\n        _Service.Send(To_, Msg)\n    End Sub\nEnd Class\n\n' ____________________________________________________\nPublic Module Program\n\n    ' Comprobación de exs 2\n    Public Sub TestNotificationSystem(To_ As Object, Msg As String, Service As INotificationService)\n        ' Inyeccion\n        Dim ServiceNotifer As New NotificationSystem(Service)\n        ServiceNotifer.Notify(To_, Msg)\n    End Sub\n\n    Public Sub Main()\n        '________________________________________\n        ' Exs 1\n        Console.WriteLine(vbCrLf + \"Exs #1\")\n        '_________\n        Console.WriteLine(\"Implementación incorrecta:\")\n\n        Dim reportGenerator_ As New ReportGenerator_\n        reportGenerator_.GenerateCsvReport(\"Contenido x\")\n        reportGenerator_.GenerateJsonReport(\"Contenido x\")\n\n        '_________\n        Console.WriteLine(\"Implementación correcta:\")\n\n        ' Intancias de las implementaciones:\n        Dim csvExporter As New CsvExporter\n        Dim jsonExporter As New JsonExporter\n\n        ' Instancia de Clase 'alto nivel' con Inyeccion de dependencia:\n        Dim csvReport As New ReportGenerator(csvExporter)\n        Dim jsonReport As New ReportGenerator(jsonExporter)\n\n        ' Uso del metodo implementado:\n        csvReport.Generate(\"Contenido x\")\n        jsonReport.Generate(\"Contenido x\")\n\n        '________________________________________\n        ' Exs 2\n        Console.WriteLine(vbCrLf + \"Exs #2\")\n\n        ' Intancias de las implementaciones\n        Dim emailService As New EmailService()\n        Dim pUSHService As New PUSHService()\n        Dim sMSService As New SMSService()\n\n        ' Pruebas\n        TestNotificationSystem(\"ejm@gg.com\", \"abcdsf\", emailService)\n        TestNotificationSystem(\"user01\", \"123456\", pUSHService)\n        TestNotificationSystem(123456789, \"aeiou\", sMSService)\n\n    End Sub\nEnd Module\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/bash/rantamhack.sh",
    "content": "#!/bin/bash\n\n#  * EJERCICIO:\n#  * ¡Los JJOO de París 2024 han comenzado!\n#  * Crea un programa que simule la celebración de los juegos.\n#  * El programa debe permitir al usuario registrar eventos y participantes,\n#  * realizar la simulación de los eventos asignando posiciones de manera aleatoria\n#  * y generar un informe final. Todo ello por terminal.\n#  * Requisitos:\n#  * 1. Registrar eventos deportivos.\n#  * 2. Registrar participantes por nombre y paÃ­s.\n#  * 3. Simular eventos de manera aleatoria en base a los participantes (mÃ­nimo 3).\n#  * 4. Asignar medallas (oro, plata y bronce) basándose en el resultado del evento.\n#  * 5. Mostrar los ganadores por cada evento.\n#  * 6. Mostrar el ranking de países según el número de medallas.\n#  * Acciones:\n#  * 1. Registro de eventos.\n#  * 2. Registro de participantes.\n#  * 3. Simulación de eventos.\n#  * 4. Creación de informes.\n#  * 5. Salir del programa.\n\n\ndeclare -A events         \ndeclare -A participants   \ndeclare -A results        \n\nfunction register_event() {\n    local event_name=\"$1\"\n    if [[ -z \"${events[$event_name]}\" ]]; then\n        events[\"$event_name\"]=\"\"  \n        echo \"Evento '$event_name' registrado.\"\n    else\n        echo \"El evento '$event_name' ya está registrado.\"\n    fi\n}\n\nfunction register_participant() {\n    local name=\"$1\"\n    local country=\"$2\"\n    local event_name=\"$3\"\n\n    if [[ -n \"${events[$event_name]+exist}\" ]]; then\n        participants[\"$name\"]=\"$country\"\n        events[\"$event_name\"]+=\"$name,\"  \n        echo \"Participante '$name' de '$country' registrado en el evento '$event_name'.\"\n    else\n        echo \"El evento '$event_name' no está registrado.\"\n    fi\n}\n\nfunction simulate_events() {\n    for event_name in \"${!events[@]}\"; do\n        local participant_list=(${events[$event_name]//,/ })\n        local participant_count=${#participant_list[@]}\n\n        if (( participant_count >= 3 )); then\n            # Mezcla aleatoria de participantes\n            shuffled_participants=($(shuf -e \"${participant_list[@]}\"))\n\n            # Almacenar los tres primeros como ganadores\n            results[$event_name]=\"${shuffled_participants[0]},${shuffled_participants[1]},${shuffled_participants[2]}\"\n        else\n            echo \"No hay suficientes participantes en el evento '$event_name' para realizar una simulación.\"\n        fi\n    done\n}\n\nfunction generate_report() {\n    for event_name in \"${!results[@]}\"; do\n        echo \"Evento: $event_name\"\n        local winners=(${results[$event_name]//,/ })\n        local medals=(\"Gold\" \"Silver\" \"Bronze\")\n\n        for i in ${!winners[@]}; do\n            local participant=${winners[$i]}\n            local country=${participants[$participant]}\n            echo \"${medals[$i]}: $participant ($country)\"\n        done\n        echo \"\"\n    done\n}\n\nfunction show_menu() {\n    while true; do\n        echo -e \"\\nMenú:\"\n        echo -e \"\\t1. Registrar Evento\"\n        echo -e \"\\t2. Registrar Participante\"\n        echo -e \"\\t3. Simular Evento\"\n        echo -e \"\\t4. Generar Informe\"\n        echo -e \"\\t5. Salir\"\n        echo -e \"\\t6. Mostrar eventos y participantes guardados\"\n\n        read -p \"Seleccione una opción del menú: \" option\n\n        case $option in\n            1)\n                read -p \"Pon el nombre del nuevo evento: \" event_name\n                register_event \"$event_name\"\n                ;;\n            2)\n                read -p \"Escriba el nombre del participante: \" name\n                read -p \"Escriba el país al que pertenece el nuevo participante: \" country\n                read -p \"Escriba el nombre del evento en el que desea inscribirse: \" event_name\n                register_participant \"$name\" \"$country\" \"$event_name\"\n                ;;\n            3)\n                simulate_events\n                ;;\n            4)\n                generate_report\n                ;;\n            5)\n                echo -e \"\\nEventos guardados:\"\n                for event_name in \"${!events[@]}\"; do\n                    echo \"$event_name\"\n                done\n\n                echo -e \"\\nParticipantes guardados:\"\n                for name in \"${!participants[@]}\"; do\n                    echo \"$name (${participants[$name]})\"\n                done\n                ;;\n            6)\n                echo \"Saliendo del programa.\"\n                break\n                ;;\n            *)\n                echo \"Opción incorrecta, por favor elija una opción entre la 1 y la 6.\"\n                ;;\n        esac\n    done\n}\n\nshow_menu\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/bash/sisaroot.sh",
    "content": "#!/usr/bin/env bash\n# #31 SIMULADOR JUEGOS OLÍMPICOS - SisaRoot\n\ndeclare -A events\ndeclare -A participants\ndeclare -A medals_gold\ndeclare -A medals_silver\ndeclare -A medals_bronze\ndeclare -a event_list\n\nregister_event() {\n    read -r -p \"Nombre del evento: \" event_name\n    if [[ -v events[\"$event_name\"] ]]; then\n        echo \"El evento '$event_name' ya existe.\"\n    else\n        events[\"$event_name\"]=1\n        event_list+=(\"$event_name\")\n        echo \"Evento '$event_name' registrado.\"\n    fi\n}\n\nregister_participant() {\n    if [[ ${#event_list[@]} -eq 0 ]]; then\n        echo \"No hay eventos registrados. Registra un evento primero.\"\n        return\n    fi\n    echo \"Eventos disponibles:\"\n    for e in \"${event_list[@]}\"; do echo \"  - $e\"; done\n    read -r -p \"Evento para el participante: \" event_name\n    if [[ ! -v events[\"$event_name\"] ]]; then\n        echo \"Evento no encontrado.\"\n        return\n    fi\n    read -r -p \"Nombre del participante: \" pname\n    read -r -p \"País del participante: \" country\n    key=\"${event_name}|${pname}\"\n    participants[\"$key\"]=\"$country\"\n    echo \"Participante '$pname ($country)' registrado en '$event_name'.\"\n}\n\nsimulate_events() {\n    if [[ ${#event_list[@]} -eq 0 ]]; then\n        echo \"No hay eventos para simular.\"\n        return\n    fi\n    for event in \"${event_list[@]}\"; do\n        echo \"\"\n        echo \"=== Simulando: $event ===\"\n        local event_parts=()\n        for key in \"${!participants[@]}\"; do\n            if [[ \"$key\" == \"${event}|\"* ]]; then\n                event_parts+=(\"${key#*|}\")\n            fi\n        done\n        local count=${#event_parts[@]}\n        if [[ $count -lt 3 ]]; then\n            echo \"  El evento '$event' necesita al menos 3 participantes (tiene $count). Saltando.\"\n            continue\n        fi\n        for ((i=count-1; i>0; i--)); do\n            j=$((RANDOM % (i+1)))\n            tmp=\"${event_parts[$i]}\"\n            event_parts[$i]=\"${event_parts[$j]}\"\n            event_parts[$j]=\"$tmp\"\n        done\n        gold_name=\"${event_parts[0]}\"\n        silver_name=\"${event_parts[1]}\"\n        bronze_name=\"${event_parts[2]}\"\n        gold_country=\"${participants[${event}|${gold_name}]}\"\n        silver_country=\"${participants[${event}|${silver_name}]}\"\n        bronze_country=\"${participants[${event}|${bronze_name}]}\"\n        echo \"  🥇 Oro:    $gold_name ($gold_country)\"\n        echo \"  🥈 Plata:  $silver_name ($silver_country)\"\n        echo \"  🥉 Bronce: $bronze_name ($bronze_country)\"\n        medals_gold[\"$gold_country\"]=$(( ${medals_gold[\"$gold_country\"]:-0} + 1 ))\n        medals_silver[\"$silver_country\"]=$(( ${medals_silver[\"$silver_country\"]:-0} + 1 ))\n        medals_bronze[\"$bronze_country\"]=$(( ${medals_bronze[\"$bronze_country\"]:-0} + 1 ))\n    done\n}\n\nshow_report() {\n    echo \"\"\n    echo \"==============================\"\n    echo \"   INFORME FINAL - JJOO 2024  \"\n    echo \"==============================\"\n    declare -A all_countries\n    for c in \"${!medals_gold[@]}\"; do all_countries[\"$c\"]=1; done\n    for c in \"${!medals_silver[@]}\"; do all_countries[\"$c\"]=1; done\n    for c in \"${!medals_bronze[@]}\"; do all_countries[\"$c\"]=1; done\n    if [[ ${#all_countries[@]} -eq 0 ]]; then\n        echo \"No se han simulado eventos aún.\"\n        return\n    fi\n    declare -a sorted_countries\n    for c in \"${!all_countries[@]}\"; do\n        g=${medals_gold[\"$c\"]:-0}\n        s=${medals_silver[\"$c\"]:-0}\n        b=${medals_bronze[\"$c\"]:-0}\n        sorted_countries+=(\"$g $s $b $c\")\n    done\n    IFS=$'\\n' sorted=($(sort -rn <<<\"${sorted_countries[*]}\")); unset IFS\n    printf \"%-5s %-25s %-6s %-6s %-6s %-6s\\n\" \"Pos.\" \"País\" \"Oro\" \"Plata\" \"Bronce\" \"Total\"\n    echo \"------------------------------------------------------------\"\n    pos=1\n    for entry in \"${sorted[@]}\"; do\n        read -r g s b c <<< \"$entry\"\n        total=$((g + s + b))\n        printf \"%-5s %-25s %-6s %-6s %-6s %-6s\\n\" \"$pos.\" \"$c\" \"$g\" \"$s\" \"$b\" \"$total\"\n        ((pos++))\n    done\n}\n\nwhile true; do\n    echo \"\"\n    echo \"====== SIMULADOR JJOO PARÍS 2024 ======\"\n    echo \"1. Registrar evento\"\n    echo \"2. Registrar participante\"\n    echo \"3. Simular eventos\"\n    echo \"4. Ver informe\"\n    echo \"5. Salir\"\n    read -r -p \"Selecciona una opción: \" choice\n    case $choice in\n        1) register_event ;;\n        2) register_participant ;;\n        3) simulate_events ;;\n        4) show_report ;;\n        5) echo \"¡Hasta luego!\"; break ;;\n        *) echo \"Opción no válida.\" ;;\n    esac\ndone\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/c#/deathwing696.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Security.Cryptography;\nusing System.Text;\nusing System.Xml.Linq;\n\nnamespace reto31\n{\n    public class deathwing696\n    {\n        public class Participante\n        {\n            private string nombre;\n            private string pais;\n\n            public string Nombre { get { return nombre; } }\n            public string Pais { get { return pais; } }\n\n            public Participante(string nombre, string pais)\n            {\n                this.nombre = nombre;\n                this.pais = pais;\n            }\n\n            public override bool Equals(object obj)\n            {\n                if (obj == null || GetType() != obj.GetType()) \n                    return false;\n\n                Participante participante = obj as Participante;\n                return this.nombre.Equals(participante.nombre) && this.pais.Equals(participante.pais);\n            }\n\n            public override int GetHashCode()\n            {\n                // Combina los códigos hash de las propiedades para producir un único código hash\n                return (Nombre?.GetHashCode() ?? 0) ^ (Pais?.GetHashCode() ?? 0);\n            }\n        }\n\n        public class Evento\n        {\n            private string nombre;\n            private List<Participante> participantes;\n            private List<Participante> medallas;\n            public string Nombre { get { return nombre; } }\n\n            public Evento()\n            {\n                this.participantes = new List<Participante>();\n                this.medallas = new List<Participante>();\n            }\n\n            public Evento CreateEvent()\n            {\n                Console.Write(\"Introduce un nombre para el evento:\");\n                var name = Console.ReadLine();\n\n                this.nombre = name;\n\n                return this;\n            }\n\n            public void AddParticipant(Olimpiadas olimpic)\n            {\n                Console.Write(\"Escriba el nombre del participante:\");\n                var name = Console.ReadLine();\n                Console.Write(\"Escriba el pais del participante:\");\n                var country = Console.ReadLine();\n                Participante participante = new Participante(name, country);\n\n                if (participantes != null && !participantes.Contains(participante))\n                {\n                    this.participantes.Add(participante);\n                    Console.WriteLine(\"Participante registrado correctamente\");\n                    olimpic.AddCountry(country);\n                }\n                else\n                {\n                    Console.WriteLine($\"El participante {participante.Nombre} del pais {participante.Pais} ya está participando en el evento {this.nombre}\");\n                }\n            }\n\n            public void Simulate(Olimpiadas olimpic)\n            {\n                if (this.participantes != null && this.participantes.Count >= 3 && this.medallas.Count != 3)\n                {\n                    Random random = new Random();\n                    Participante participant;\n\n                    for (int i = 0; i < 3; i++)\n                    {\n                        do\n                        {\n                            var pos = random.Next(0, this.participantes.Count);\n                            participant = this.participantes[pos];\n                        } while (this.medallas.Contains(participant));\n\n                        this.medallas.Add(participant);\n                        olimpic.UpdateRanking(participant.Pais);\n                    }\n                }\n                else if (this.medallas.Count != 3)\n                {\n                    Console.WriteLine($\"El evento {this.nombre} no contiene un mínimo de 3 participantes, así que no se simulará\");\n                }\n            }\n\n            public void ShowMedalReport()\n            {\n                if (this.medallas.Count == 3)\n                {\n                    Console.WriteLine($\"EVENTO:{this.nombre}\");\n                    Console.WriteLine($\"ORO:{this.medallas[0].Nombre} del pais {this.medallas[0].Pais}\");\n                    Console.WriteLine($\"PLATA:{this.medallas[1].Nombre} del pais {this.medallas[1].Pais}\");\n                    Console.WriteLine($\"BRONCE:{this.medallas[2].Nombre} del pais {this.medallas[2].Pais}\");\n                }\n            }            \n        }\n\n        public class Olimpiadas\n        {\n            private static Olimpiadas instance;\n            private List<Evento> events;\n            private Dictionary<string, int> countryRanking;\n\n            public List<Evento> Events { get { return events; } }\n            public Dictionary<string, int> CountryRanking { get { return countryRanking; } }\n\n            private Olimpiadas()\n            {\n                events = new List<Evento>();\n                countryRanking = new Dictionary<string, int>();\n            }\n\n            public static Olimpiadas Instance\n            {\n                get\n                {\n                    if (instance == null)\n                        instance = new Olimpiadas();\n                    \n                    return instance;\n                }\n            }\n\n            public void AddCountry(string name)\n            {\n                var nameNormalized = NormalizeString(name);\n                \n                if (!this.countryRanking.ContainsKey(nameNormalized.ToString()))\n                    this.countryRanking.Add(nameNormalized.ToString(), 0);\n            }\n\n            private string NormalizeString(string input)\n            {\n                if (input == null)\n                {\n                    return String.Empty;\n                }\n                else\n                {\n                    var nameLower = input.ToLower().Trim();\n                    return Char.ToUpper(nameLower[0]) + nameLower.Substring(1);\n                }\n            }\n\n            public  Evento ShowEvents()\n            {\n                int i = 1;\n\n                foreach (Evento evento in this.Events)\n                    Console.WriteLine($\"{i}.{evento.Nombre}\");\n\n                Console.Write(\"Seleccione un evento:\");\n                var option = Int16.Parse(Console.ReadLine()) - 1;\n\n                if (option >= 0 && option <= this.Events.Count - 1)\n                    return this.Events[option];\n                else\n                    return null;\n            }\n\n            public void UpdateRanking(string country)\n            {\n                var countryNormalized = NormalizeString(country);\n\n                if (countryRanking.ContainsKey(countryNormalized))\n                    this.countryRanking[countryNormalized]++;\n            }\n\n            public void showMedals()\n            {\n                Console.WriteLine(\"Medallero por eventos\");\n                foreach (Evento evento in this.Events)\n                    evento.ShowMedalReport();\n            }\n\n            public void showCountryRanking()\n            {\n                var countryRankingOrdered = countryRanking.OrderByDescending(c => c.Value);\n\n                Console.WriteLine(\"Ranking de paises\");\n\n                var i = 1;\n\n                foreach (var country in countryRankingOrdered)\n                {\n                    Console.WriteLine($\"{i++}. {country.Key}: {country.Value} medallas\");\n                }\n            }\n        }\n        static void Main(string[] args)\n        {\n            Olimpiadas olimpic = Olimpiadas.Instance;            \n\n            while (true)\n            {\n                Console.WriteLine(\"1.Registro de eventos.\");\n                Console.WriteLine(\"2.Registro de participantes.\");\n                Console.WriteLine(\"3.Simulación de eventos.\");\n                Console.WriteLine(\"4.Creación de informes.\");\n                Console.WriteLine(\"5.Salir del programa.\");\n                Console.Write(\"Introduzca una opción:\");\n                var option = Int16.Parse(Console.ReadLine());\n\n                switch (option)\n                {\n                    case 1:\n                        Evento evento = new Evento();\n                        evento.CreateEvent();\n                        olimpic.Events.Add(evento);\n                        Console.WriteLine(\"Evento registrado correctamente\");\n                        break;\n                    case 2:\n                        if (olimpic.Events.Count > 0)\n                        { \n                            Evento selectedEvent = olimpic.ShowEvents();\n\n                            if (selectedEvent != null)\n                                selectedEvent.AddParticipant(olimpic);\n                            else\n                                Console.WriteLine(\"El evento seleccionado no es correcto\");\n                        }\n                        else\n                        {\n                            Console.WriteLine(\"No hay eventos registrados todavía, por favor, primero registre un evento\");\n                        }\n                        break;\n                    case 3:\n                        foreach (Evento e in olimpic.Events)\n                        {\n                            e.Simulate(olimpic);\n                        }\n                        break;\n                    case 4:\n                        olimpic.showMedals();\n                        olimpic.showCountryRanking();\n                        break;\n                    case 5:\n                        Console.WriteLine(\"Simulación terminada\");\n                        Console.ReadKey();\n                        return;\n                }\n            }\n        }                \n    }\n}\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/c#/hequebo.cs",
    "content": "class Program\n{\n    static void Main(string[] args)\n    {\n        EventService eventService = new EventService();\n        ParticipantService participantService = new ParticipantService();\n        ResultService resultService = new ResultService();\n        CountryResultService countryResultService = new CountryResultService();\n        Olympics olympics = new Olympics(eventService, participantService, resultService,countryResultService);\n\n        bool salir = false;\n\n        do\n        {\n            Menu();\n            int option = 0;\n            int.TryParse(Console.ReadLine(), out option);\n\n            switch (option)\n            {\n                case 1:\n                    olympics.AddEvent();\n                    break;\n                case 2:\n                    olympics.AddParticipant();\n                    break;\n                case 3:\n                    olympics.SimulateEvent();\n                    break;\n                case 4:\n                    olympics.ShowResults();\n                    break;\n                case 5:\n                    salir = true;\n                    Console.Clear();\n                    Console.WriteLine(\"Hasta la próxima...\");\n                    Thread.Sleep(1000);\n                    break;\n                default:\n                    Console.WriteLine(\"Opción no válida...\");\n                    break;\n            }\n        }\n        while (!salir);\n    }\n\n    static void Menu()\n    {\n        Console.WriteLine(\"---Simulador JJOO París 2024---\");\n        Console.WriteLine(\"1.- Registrar Evento.\");\n        Console.WriteLine(\"2.- Registrar Participante.\");\n        Console.WriteLine(\"3.- Simular Evento.\");\n        Console.WriteLine(\"4.- Consultar Ranking.\");\n        Console.WriteLine(\"5.- Salir.\");\n        Console.WriteLine(\"Seleccione una opción...\");\n    }\n}\nclass Event\n{\n    private int _id;\n    private string _name;\n\n    public string Name { get { return _name; } }\n    public int Id { get { return _id; } } \n\n    public Event(int id, string name)\n    {\n        _id = id;\n        _name = name;\n    }\n}\nclass EventService\n{\n    public int id = 1;\n    private List<Event> _events;\n\n    public EventService()\n    {\n        _events = new List<Event>();\n    }\n    public int SearchEvent(string name) => _events.Where(e => e.Name == name).Count();\n    public string Search(int id)\n    {\n        if (_events.Where(e => e.Id == id).Count() == 0)\n        {\n            Console.WriteLine($\"El evento con id {id} no existe...\");\n            return \"\";\n        }\n        var @event = _events.Where(e => e.Id == id).FirstOrDefault();\n        return @event.Name;\n    }\n    public void AddEvent(Event @event)\n    {\n        _events.Add(@event);\n        id++;\n    }\n\n    public bool GetEvents()\n    {\n        if (_events.Count == 0)\n        {\n            Console.WriteLine(\"No hay eventos registrados...\");\n            return false;\n        }\n        foreach (var @event in _events)\n            Console.WriteLine($\"{@event.Id}.- {@event.Name}\");\n        return true;\n    }\n}\nclass Participant\n{\n    private string _name;\n    private string _country;\n    private int _idEvent;\n\n    public string Name { get { return _name; } }\n    public string Country { get { return _country; } }\n    public int IdEvent { get { return _idEvent; } }\n\n    public Participant(string name, string country, int idEvent)\n    {\n        _name = name;\n        _country = country;\n        _idEvent = idEvent;\n    }\n}\nclass ParticipantService\n{\n    private List<Participant> _participants;\n\n    public ParticipantService()\n    {\n        _participants = new List<Participant>();\n    }\n    public int SearchParticipant(string name, string country) =>\n        _participants.Where(p => p.Name == name && p.Country == country).Count();\n    public List<Participant>? GetEventParticipants(int id)\n    {\n        var  participants = _participants.Where(p => p.IdEvent == id).ToList();\n\n        if (participants.Count() == 0)\n        {\n            Console.WriteLine(\"No hay participantes registrados en este evento...\");\n            return null;\n        }\n        if (participants.Count() < 3)\n        {\n            Console.WriteLine(\"Se necesitan al menos 3 participantes para simular el evento\" +\n                $\"actalmente solo hay {participants} participante(s) registrado(s)...\");\n            return null;\n        }\n        Console.Clear();\n        foreach (var participant in participants)\n            Console.WriteLine($\"Nombre: {participant.Name}, País: {participant.Country}\");\n        return participants;\n    }\n\n    public void AddParticipant(Participant participant) => _participants.Add(participant);\n}\nclass Result\n{\n    private string _event;\n    private string _gold;\n    private string _silver;\n    private string _bronze;\n\n    public string Event { get { return _event; } }\n    public string Gold { get { return _gold; } }\n    public string Silver { get { return _silver; } }\n    public string Bronze { get { return _bronze; } }\n\n    public Result(string @event, string gold, string silver, string bronze)\n    {\n        _event = @event;\n        _gold = gold;\n        _silver = silver;\n        _bronze = bronze;\n    }\n}\nclass ResultService\n{\n    private List<Result> _results;\n\n    public ResultService()\n    {\n        _results = new List<Result>();\n    }\n\n    public void AddResult(Result result) => _results.Add(result);\n    public void ShowResults()\n    {\n        foreach (var result in _results)\n            Console.WriteLine($\"Evento: {result.Event}, Oro: {result.Gold}, \" +\n                $\"Plata: {result.Silver}, Bronce: {result.Bronze}\");\n    }\n}\nclass CountryResult \n{\n    private string _country;\n    private int _gold;\n    private int _silver;\n    private int _bronze;\n\n    public string Country \n    {\n        get\n        {\n            return _country;\n        }\n        set\n        {\n            _country = value;\n        }\n    }\n    public int Gold\n    {\n        get\n        {\n            return _gold;\n        }\n        set\n        {\n            _gold = value;\n        }\n    }\n\n    public int Silver\n    {\n        get\n        {\n            return _silver;\n        }\n        set\n        {\n            _silver = value;\n        }\n    }\n    public int Bronze\n    {\n        get\n        {\n            return _bronze;\n        }\n        set\n        {\n            _bronze = value;\n        }\n    }\n\n    public CountryResult(string country, int gold, int silver, int bronze)\n    {\n        _country = country;\n        _gold = gold;\n        _silver = silver;\n        _bronze = bronze;\n    }\n}\nclass CountryResultService\n{\n    private List<CountryResult> _countryResults;\n\n    public CountryResultService()\n    {\n        _countryResults = new List<CountryResult>();\n    }\n\n    public void AddResult(CountryResult countryResult)\n    {\n        if (_countryResults.Where(c => c.Country == countryResult.Country).Count() > 0)\n        {\n            var country = _countryResults.Where(c => c.Country == countryResult.Country).FirstOrDefault();\n            country.Gold += countryResult.Gold;\n            country.Silver += countryResult.Silver;\n            country.Bronze += countryResult.Bronze;\n        }\n        else\n        {\n            _countryResults.Add(countryResult);\n        }\n    }\n    public void ShowResults()\n    {\n        var results = _countryResults.OrderByDescending(c => c.Gold).ThenByDescending(c => c.Silver)\n            .ThenByDescending(c => c.Bronze).ToList();\n\n        foreach(var result in results)\n            Console.WriteLine($\"País: {result.Country}, Oro: {result.Gold}, \" +\n                $\"Plata: {result.Silver}, Bronce: {result.Bronze}\");\n    }\n}\n\nclass Olympics\n{\n    private EventService _eventService;\n    private ParticipantService _participantService;\n    private ResultService _resultService;\n    private CountryResultService _countryResultService;\n\n    public Olympics(EventService eventService, ParticipantService participantService, \n        ResultService resultService, CountryResultService countrResultService)\n    {\n        _participantService = participantService;\n        _eventService = eventService;\n        _resultService = resultService;\n        _countryResultService = countrResultService;\n    }\n\n    public void AddEvent()\n    {\n        Console.Clear();\n        Console.WriteLine(\"Ingresa el nombre del evento:\");\n        string? name = Console.ReadLine();\n        if(string.IsNullOrEmpty(name))\n        {\n            Console.WriteLine(\"No se ha ingresado ningún nombre...\");\n            return;\n        }\n        if (_eventService.SearchEvent(name) > 0)\n        {\n            Console.WriteLine($\"El evento {name} ya ha sido registrado...\");\n            return;\n        }\n        Event @event = new Event(_eventService.id, name);\n        _eventService.AddEvent(@event);\n        Console.Clear();\n        Console.WriteLine($\"El evento {name} se ha registrado correctamente...\");\n    }\n    public void AddParticipant()\n    {\n        Console.Clear();\n        Console.WriteLine(\"Ingresa nombre del participante\");\n        string? name = Console.ReadLine();\n        Console.WriteLine(\"Ingresa país del participante\");\n        string? country = Console.ReadLine();\n        if(string.IsNullOrEmpty(name) || string.IsNullOrEmpty(country))\n        {\n            Console.WriteLine(\"No se ingresaron los datos correctamente...\");\n            return;\n        }\n        if (_participantService.SearchParticipant(name, country) > 0)\n        {\n            Console.WriteLine(\"Este participante ya se encuentra registrado\");\n            return;\n        }\n        if (!_eventService.GetEvents())\n            return;\n        Console.WriteLine(\"Selecciona evento en el cual se participará\");\n        int idEvento  = 0;\n        int.TryParse(Console.ReadLine(), out idEvento);\n        string eventName = _eventService.Search(idEvento);\n        if (eventName == \"\")\n            return;\n\n        Participant participant = new Participant(name, country, idEvento);\n        _participantService.AddParticipant(participant);\n        Console.Clear();\n        Console.WriteLine(\"El participante se ha registrado correctamente...\");\n        Console.WriteLine($\"Nombre: {participant.Name}, País: {participant.Country}, Evento: {eventName}\");\n    }\n    public void SimulateEvent()\n    {\n        Console.Clear();\n        if (!_eventService.GetEvents())\n            return;\n        Console.WriteLine(\"Seleccione evento a simular\");\n        int idEvent = 0;\n        int.TryParse(Console.ReadLine(), out idEvent);\n\n        string eventName = _eventService.Search(idEvent);\n        if (eventName == \"\")\n            return;\n\n        var participants = _participantService.GetEventParticipants(idEvent);\n        if (participants == null)\n            return;\n\n        List<Participant> winnersList = new List<Participant>();\n        Random random = new Random();\n        \n        // Medalla de Oro\n        int index = random.Next(0, participants.Count);\n        winnersList.Add(participants[index]);\n        participants.RemoveAt(index);\n\n        // Medalla de Plata\n        index = random.Next(0, participants.Count);\n        winnersList.Add(participants.ElementAt(index));\n        participants.RemoveAt(index);\n\n        // Medalla de Bronce\n        index = random.Next(0, participants.Count);\n        winnersList.Add(participants.ElementAt(index));\n\n\n        Console.WriteLine(\"---Resultados---\");\n        Console.WriteLine($\"Medalla de Oro: {winnersList[0].Name}, {winnersList[0].Country}\");\n        Console.WriteLine($\"Medalla de Plata: {winnersList[1].Name}, {winnersList[1].Country}\");\n        Console.WriteLine($\"Medalla de Bronce: {winnersList[2].Name}, {winnersList[2].Country}\");\n\n        Result result = new Result(eventName, winnersList[0].Country, winnersList[1].Country, winnersList[2].Country);\n        _resultService.AddResult(result);\n\n        var gold = new CountryResult(winnersList[0].Country, 1, 0, 0);\n        var silver = new CountryResult(winnersList[1].Country, 0, 1, 0);\n        var bronze = new CountryResult(winnersList[2].Country, 0, 0, 1);\n        _countryResultService.AddResult(gold);\n        _countryResultService.AddResult(silver);\n        _countryResultService.AddResult(bronze);\n        \n\n        Console.ReadLine();\n        Console.Clear();\n    }\n    public void ShowResults()\n    {\n        Console.Clear();\n        _resultService.ShowResults();\n        _countryResultService.ShowResults();\n        Console.ReadLine();\n    }\n}\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/c#/kenysdev.cs",
    "content": "namespace exs31;\n/*\n╔══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado               ║\n║ GitHub: https://github.com/Kenysdev  ║\n║ 2024 -  C#                           ║\n╚══════════════════════════════════════╝\n-----------------------------------------------------\n* SIMULADOR JUEGOS OLÍMPICOS\n-----------------------------------------------------\n\n* EJERCICIO:\n* ¡Los JJOO de París 2024 han comenzado!\n* Crea un programa que simule la celebración de los juegos.\n* El programa debe permitir al usuario registrar eventos y participantes,\n* realizar la simulación de los eventos asignando posiciones de manera aleatoria\n* y generar un informe final. Todo ello por terminal.\n * Requisitos:\n * 1. Registrar eventos deportivos.\n * 2. Registrar participantes por nombre y país.\n * 3. Simular eventos de manera aleatoria en base a los participantes (mínimo 3).\n * 4. Asignar medallas (oro, plata y bronce) basándose en el resultado del evento.\n * 5. Mostrar los ganadores por cada evento.\n * 6. Mostrar el ranking de países según el número de medallas.\n * Acciones:\n * 1. Registro de eventos.\n * 2. Registro de participantes.\n * 3. Simulación de eventos.\n * 4. Creación de informes.\n * 5. Salir del programa.\n*/\n\n// NOTA: Esto es un intento de aplicar los principios SOLID.\n\n// ________________________________________________\n// Interfaces\n/// <summary>Contrato sobre las constantes globales.</summary>\npublic interface IConstants\n{\n    string GetMenu();\n    string[] GetMedals();\n}\n\n/// <summary>\n/// Contrato sobre los métodos requeridos para cada tabla creada.\n/// </summary>\npublic interface IDataTable<T>\n{\n    void Add(T item);\n\n    /// <returns>El número de elementos.</returns>\n    int Count();\n\n    /// <returns>Una lista de los elementos.</returns>\n    List<T> GetList();\n}\n\n/// <summary>\n/// Contrato para implementar en diferentes formas de almacenamiento.\n/// </summary>\npublic interface IData\n{\n    IDataTable<string> EventsTable { get; }\n    IDataTable<(string Name, string Country, int EventId)> ParticipantsTable { get; }\n    IDataTable<List<(string EventName, List<(string Name, string Country, int EventId, int Score, string Medal)> Results)>> SimulationTable { get; }\n}\n\n/// <summary>\n/// Contrato sobre la entra de datos.\n/// </summary>\npublic interface IInput\n{\n    /// <returns>Una cadena no vacía</returns>\n    string GetStr(string msg);\n    /// <returns>Un entero</returns>\n    int GetInt(string msg);\n}\n\n// ________________________________________________\n/// CONTRATOS sobre la comunicación entre la interacción del usuario y la capa de datos.\npublic interface IEvents { void Add(); }\n\npublic interface IParticipants { void Add(); }\n\npublic interface ISimulations { void Start(); }\n\npublic interface IReports { void Generate(); }\n\n// ________________________________________________\n// IMPLEMENTAR CONTRATOS\n// ________________________________________________\npublic class Constants : IConstants\n{\n    private const string Menu = \"\"\"\n    \n    SIMULADOR JUEGOS OLÍMPICOS:\n    --------------------------------------------------\n    | 1. Registrar evento        | 4. Crear informes |  \n    | 2. Registrar participante  | 5. Salir          |\n    | 3. Simulación de eventos   |                   |\n    --------------------------------------------------\n    \"\"\";\n\n    private static readonly string[] Medals = [\"🥇 Oro\", \"🥈 Plata\", \"🥉 Bronce\"];\n    public string GetMenu() { return Menu; }\n    public string[] GetMedals() { return Medals; }\n}\n\npublic class EventsTable : IDataTable<string>\n{\n    private readonly List<string> dt = [];\n\n    public void Add(string sport)\n    {\n        dt.Add(sport);\n    }\n\n    public int Count()\n    {\n        return dt.Count;\n    }\n\n    public List<string> GetList()\n    {\n        return new List<string>(dt);\n    }\n}\n\npublic class ParticipantsTable : IDataTable<(string Name, string Country, int EventId)>\n{\n    private readonly List<(string Name, string Country, int EventId)> dt = [];\n\n    public void Add((string Name, string Country, int EventId) participant)\n    {\n        dt.Add(participant);\n    }\n\n    public int Count()\n    {\n        return dt.Count;\n    }\n\n    public List<(string Name, string Country, int EventId)> GetList()\n    {\n        return new List<(string Name, string Country, int EventId)>(dt);\n    }\n}\n\npublic class SimulationTable : IDataTable<List<(string EventName, List<(string Name, string Country, int EventId, int Score, string Medal)> Results)>>\n{\n    private readonly List<List<(string EventName, List<(string Name, string Country, int EventId, int Score, string Medal)> Results)>> dt = [];\n\n    public void Add(List<(string EventName, List<(string Name, string Country, int EventId, int Score, string Medal)> Results)> simulation)\n    {\n        dt.Add(simulation);\n    }\n\n    public int Count()\n    {\n        return dt.Count;\n    }\n\n    public List<List<(string EventName, List<(string Name, string Country, int EventId, int Score, string Medal)> Results)>> GetList()\n    {\n        return new List<List<(string EventName, List<(string Name, string Country, int EventId, int Score, string Medal)> Results)>>(dt);\n    }\n}\n\n/// <summary>\n/// Datos en memoria aplicando el patrón Singleton.\n/// </summary>\npublic class DataInMemory : IData\n{\n    private static DataInMemory? _instance;\n    public IDataTable<string> EventsTable { get; private set; }\n    public IDataTable<(string Name, string Country, int EventId)> ParticipantsTable { get; private set; }\n    public IDataTable<List<(string EventName, List<(string Name, string Country, int EventId, int Score, string Medal)> Results)>> SimulationTable { get; private set; }\n\n    private DataInMemory()\n    {\n        EventsTable = new EventsTable();\n        ParticipantsTable = new ParticipantsTable();\n        SimulationTable = new SimulationTable();\n    }\n\n    public static DataInMemory Instance\n    {\n        get\n        {\n            _instance ??= new DataInMemory();\n            return _instance;\n        }\n    }\n}\n\n// ________________________________________________\n/// <summary>\n/// Muestra un mensaje al usuario y devuelve su entrada.\n/// </summary>\npublic class Input : IInput\n{\n    public string GetStr(string msg)\n    {\n        while (true)\n        {\n            Console.Write(msg);\n            string? txt = Console.ReadLine();\n            if (!string.IsNullOrEmpty(txt))\n            {\n                return txt;\n            }\n        }\n    }\n\n    public int GetInt(string msg)\n    {\n        while (true)\n        {\n            Console.Write(msg);\n            string? txt = Console.ReadLine();\n            if (int.TryParse(txt, out int input))\n            {\n                return input;\n            }\n            else\n            {\n                Console.WriteLine(\"Ingresa un número entero.\");\n            }\n        }\n    }\n}\n\n// ________________________________________________\n/// <summary>\n/// 1. Registrar eventos deportivos.\n/// </summary>\npublic class Events(IData data, IInput input) : IEvents\n{\n    public void Add()\n    {\n        Console.WriteLine(\"AGREGAR EVENTO DEPORTIVO:\");\n        string sport = input.GetStr(\"Deporte: \");\n        data.EventsTable.Add(sport);\n        Console.WriteLine($\"{sport} fue agregado\");\n        //Console.WriteLine(constants.Menu);\n    }\n}\n\n// ________________________________________________\n/// <summary>\n/// 2. Registrar participantes por nombre y país.\n/// </summary>\npublic class Participants(IConstants constants, IData data, IInput input) : IParticipants\n{\n    private int GetEventId()\n    {\n        Console.WriteLine(\"Seleccionar el evento donde participará:\");\n        var events = data.EventsTable.GetList();\n        for (int i = 0; i < events.Count; i++)\n        {\n            Console.WriteLine($\"{i}. {events[i]}\");\n        }\n\n        while (true)\n        {\n            int index = input.GetInt(\"Id de evento: \");\n            if (index < 0 || index >= events.Count)\n            {\n                Console.WriteLine(\"\\nId no encontrada.\");\n            }\n            else\n            {\n                return index;\n            }\n        }\n    }\n\n    public void Add()\n    {\n        Console.WriteLine(\"AGREGAR PARTICIPANTE:\");\n        var events = data.EventsTable.GetList();\n        if (!(events.Count > 0))\n        {\n            Console.WriteLine(\"No existe evento en cuál participar.\");\n            return;\n        }\n\n        int eventId = GetEventId();\n        string name = input.GetStr(\"Nombre: \");\n        string country = input.GetStr(\"país: \");\n        data.ParticipantsTable.Add((name, country, eventId));\n        Console.WriteLine($\"{eventId} fue agregado\");\n        Console.WriteLine(constants.GetMenu());\n    }\n}\n\n// ________________________________________________\n/// <summary>\n/// 3. Simular eventos de manera aleatoria en base a los participantes (mínimo 3).\n/// 4. Asignar medallas (oro, plata y bronce) basándose en el resultado del evento.\n/// </summary>\npublic class Simulation(IConstants constants, IData data) : ISimulations\n{\n    private static readonly Random _random = new();\n\n    /// <returns>Una lista con los 3 ganadores del éxito, junto con su puntaje y su medalla. </returns>\n    private List<List<object>> QualifyParticipants(int eventId)\n    {\n        var participants = data.ParticipantsTable.GetList();\n        var ParticipantsOfEvent = participants.Where(p => p.EventId == eventId).ToList();\n\n        var qualifiedParticipants = ParticipantsOfEvent.Select(p =>\n        {\n            var list = new List<object>\n            {\n            p.Name,\n            p.Country,\n            p.EventId,\n            _random.Next(1, 101)\n            };\n            return list;\n        }).ToList();\n\n        qualifiedParticipants = [.. qualifiedParticipants.OrderByDescending(p => (int)p[3])];\n\n        var top3Participants = qualifiedParticipants.Take(3).ToList();\n\n        string[] medals = constants.GetMedals();\n        for (int i = 0; i < top3Participants.Count; i++)\n        {\n            top3Participants[i].Add(medals[i]);\n        }\n\n        return top3Participants;\n    }\n\n    private void AddResultEvents()\n    {\n        var events = data.EventsTable.GetList();\n        var simulation = new List<(\n            string EventName, List<(string Name, string Country, \n            int EventId, int Score, string Medal)> Results)>();\n\n        for (int id = 0; id < events.Count; id++)\n        {\n            var qualifiedParticipants = QualifyParticipants(id);\n            var eventResult = qualifiedParticipants.Select(p =>\n                (\n                    Name: p[0]?.ToString() ?? string.Empty,\n                    Country: p[1]?.ToString() ?? string.Empty,\n                    eventId: Convert.ToInt32(p[2]),\n                    Score: Convert.ToInt32(p[3]),\n                    Medal: p[4]?.ToString() ?? string.Empty\n                )\n            ).ToList();\n\n            simulation.Add((EventName: events[id], Results: eventResult));\n        }\n\n        data.SimulationTable.Add(simulation);\n    }\n\n    public void Start()\n    {\n        if (data.EventsTable.Count() >= 1 && data.ParticipantsTable.Count() >= 3)\n        {\n            AddResultEvents();\n            var totalSimulation = data.SimulationTable.Count();\n            Console.WriteLine($\"Simulación '#{totalSimulation}' creada.\");\n            Console.WriteLine(\"Puedes ver el resultado con opción: '4. Crear informes.'\");\n        }\n        else\n        {\n            Console.WriteLine(\"Debe haber al menos un evento y al menos 'tres' participantes.\");\n        }\n    }\n}\n\n// ________________________________________________\n/// <summary>\n/// 5. Mostrar los ganadores por cada evento.\n/// 6. Mostrar el ranking de países según el número de medallas.\n/// </summary>\npublic class Reports(IConstants constants, IData data) : IReports\n{\n    private readonly Dictionary<string, (int Medals, int CurrentScore)> rankingCountries = [];\n\n    private void GenerateTopCountries()\n    {\n        var sortedRank = rankingCountries.OrderByDescending(item => item.Value);\n\n        int i = 1;\n        foreach (var (name, total) in sortedRank)\n        {\n            Console.WriteLine($\"'{i}' - {name} -> Medallas: {total.Medals} | Puntaje: {total.CurrentScore}\");\n            i++;\n        }\n    }\n\n    private void IterateParticipants(IEnumerable<(\n        string Name, string Country, int EventId, int Score, string Medal)> participants)\n    {\n        int i = 1;\n        foreach (var (name, country, eventid, score, medal) in participants)\n        {\n            Console.WriteLine($\"'{i}' - {name} - {country} -> Score: {score}, Medal: {medal}\");\n\n            // Registrar para generar ranking de países por número de medallas\n            if (rankingCountries.TryGetValue(country, out var value))\n            {\n                int medals = value.Medals;\n                int currentScore = value.CurrentScore;\n                rankingCountries[country] = (medals + 1, currentScore + score);\n            }\n            else\n            {\n                rankingCountries[country] = (1, score);\n            }\n\n            i++;\n        }\n    }\n\n    private void IterateEvents(List<(\n        string EventName, List<(string Name, string Country, int EventId, int Score, string Medal)> Results)> simulation)\n    {\n        foreach (var (eventName, results) in simulation)\n        {\n            Console.WriteLine($\"\\nEvent: {eventName}:\");\n             if (results.Count < 3)\n             {\n                Console.WriteLine(\"Evento cancelado por falta de participantes.\");\n                continue;\n             }\n\n            IterateParticipants(results);\n        }\n    }\n\n    public void Generate()\n    {\n        var simulations = data.SimulationTable.GetList();\n        if (simulations.Count == 0)\n        {\n            Console.WriteLine(\"Aún no hay simulaciones creadas.\");\n            return;\n        }\n\n        int i = 1;\n        foreach (var simulation in simulations)\n        {\n            Console.WriteLine($\"\\n______________\\nSimulation {i}\");\n            IterateEvents(simulation);\n\n            Console.WriteLine(\"\\nRanking de países, según el número de medallas y puntaje:\");\n            GenerateTopCountries();\n            rankingCountries.Clear();\n\n            i++;\n        }\n\n        Console.WriteLine(constants.GetMenu());\n    }\n}\n\n// ________________________________________________\npublic class Features\n{\n    public required IConstants Constants { get; set; }\n    public required IData Data { get; set; }\n    public required IInput Input { get; set; }\n    public required IEvents Events { get; set; }\n    public required IParticipants Participants { get; set; }\n    public required ISimulations Simulation { get; set; }\n    public required IReports Reports { get; set; }\n}\n\n/// <summary>\n/// Recibimos instancias con las características del programa que dependen de las interfaces.\n/// </summary>\npublic class Program(Features Ft)\n{\n    public void Run()\n    {\n        Console.WriteLine(Ft.Constants.GetMenu());\n        while (true)\n        {\n            string option = Ft.Input.GetStr(\"\\nOpción: \");\n            switch (option)\n            {\n                case \"1\": Ft.Events.Add(); break;\n                case \"2\": Ft.Participants.Add(); break;\n                case \"3\": Ft.Simulation.Start(); break;\n                case \"4\": Ft.Reports.Generate(); break;\n                case \"5\": Console.WriteLine(\"Adios\"); return;\n                default: Console.WriteLine(\"Seleccionar de '1 a 5'\"); break;\n            }\n        }\n    }\n\n    public static void Main()\n    {\n        IConstants constants = new Constants();\n        IData data = DataInMemory.Instance;\n        IInput input = new Input();\n\n        Features Features_ = new()\n        {\n            Constants = constants,\n            Data = data,\n            Input = input,\n            Events = new Events(data, input),\n            Participants = new Participants(constants, data, input),\n            Simulation = new Simulation(constants, data),\n            Reports = new Reports(constants, data)\n        };\n\n        Program program = new(Features_);\n        program.Run();\n    }\n}\n\n// NOTA: Esto es un intento de aplicar los principios SOLID.\n\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/c#/sisaroot.cs",
    "content": "// #31 SIMULADOR JUEGOS OLÍMPICOS - SisaRoot\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nclass Participant\n{\n    public string Name { get; set; }\n    public string Country { get; set; }\n    public Participant(string name, string country) { Name = name; Country = country; }\n}\n\nclass OlympicEvent\n{\n    public string Name { get; set; }\n    public List<Participant> Participants { get; set; } = new();\n    public OlympicEvent(string name) => Name = name;\n}\n\nclass CountryMedals\n{\n    public string Country { get; set; }\n    public int Gold { get; set; }\n    public int Silver { get; set; }\n    public int Bronze { get; set; }\n    public int Total => Gold + Silver + Bronze;\n    public CountryMedals(string country) => Country = country;\n}\n\nclass SisaRoot\n{\n    static readonly List<OlympicEvent> events = new();\n    static readonly Dictionary<string, CountryMedals> medalTable = new();\n    static readonly Random rng = new();\n\n    static void RegisterEvent()\n    {\n        Console.Write(\"Nombre del evento: \");\n        string name = Console.ReadLine()?.Trim() ?? \"\";\n        if (string.IsNullOrEmpty(name)) { Console.WriteLine(\"Nombre inválido.\"); return; }\n        if (events.Any(e => e.Name.Equals(name, StringComparison.OrdinalIgnoreCase)))\n        { Console.WriteLine($\"El evento '{name}' ya existe.\"); return; }\n        events.Add(new OlympicEvent(name));\n        Console.WriteLine($\"Evento '{name}' registrado.\");\n    }\n\n    static void RegisterParticipant()\n    {\n        if (events.Count == 0) { Console.WriteLine(\"No hay eventos registrados.\"); return; }\n        Console.WriteLine(\"Eventos disponibles:\");\n        for (int i = 0; i < events.Count; i++)\n            Console.WriteLine($\"  {i + 1}. {events[i].Name}\");\n        Console.Write(\"Selecciona el número del evento: \");\n        if (!int.TryParse(Console.ReadLine(), out int idx) || idx < 1 || idx > events.Count)\n        { Console.WriteLine(\"Selección inválida.\"); return; }\n        var ev = events[idx - 1];\n        Console.Write(\"Nombre del participante: \");\n        string pname = Console.ReadLine()?.Trim() ?? \"\";\n        Console.Write(\"País del participante: \");\n        string country = Console.ReadLine()?.Trim() ?? \"\";\n        if (string.IsNullOrEmpty(pname) || string.IsNullOrEmpty(country))\n        { Console.WriteLine(\"Datos inválidos.\"); return; }\n        ev.Participants.Add(new Participant(pname, country));\n        Console.WriteLine($\"Participante '{pname} ({country})' añadido a '{ev.Name}'.\");\n    }\n\n    static void AddMedal(string country, string type)\n    {\n        if (!medalTable.TryGetValue(country, out var cm))\n        { cm = new CountryMedals(country); medalTable[country] = cm; }\n        if (type == \"gold\") cm.Gold++;\n        else if (type == \"silver\") cm.Silver++;\n        else cm.Bronze++;\n    }\n\n    static void SimulateEvents()\n    {\n        if (events.Count == 0) { Console.WriteLine(\"No hay eventos para simular.\"); return; }\n        foreach (var ev in events)\n        {\n            Console.WriteLine($\"\\n=== Simulando: {ev.Name} ===\");\n            if (ev.Participants.Count < 3)\n            { Console.WriteLine($\"  Necesita >=3 participantes (tiene {ev.Participants.Count}). Saltando.\"); continue; }\n            var shuffled = ev.Participants.OrderBy(_ => rng.Next()).ToList();\n            var gold = shuffled[0]; var silver = shuffled[1]; var bronze = shuffled[2];\n            Console.WriteLine($\"  🥇 Oro:    {gold.Name} ({gold.Country})\");\n            Console.WriteLine($\"  🥈 Plata:  {silver.Name} ({silver.Country})\");\n            Console.WriteLine($\"  🥉 Bronce: {bronze.Name} ({bronze.Country})\");\n            AddMedal(gold.Country, \"gold\"); AddMedal(silver.Country, \"silver\"); AddMedal(bronze.Country, \"bronze\");\n        }\n    }\n\n    static void ShowReport()\n    {\n        Console.WriteLine(\"\\n==============================\");\n        Console.WriteLine(\"   INFORME FINAL - JJOO 2024  \");\n        Console.WriteLine(\"==============================\");\n        if (medalTable.Count == 0) { Console.WriteLine(\"No se han simulado eventos aún.\"); return; }\n        var ranking = medalTable.Values\n            .OrderByDescending(c => c.Gold).ThenByDescending(c => c.Silver).ThenByDescending(c => c.Bronze).ToList();\n        Console.WriteLine($\"{\"Pos.\",-5} {\"País\",-25} {\"Oro\",-6} {\"Plata\",-6} {\"Bronce\",-6} {\"Total\",-6}\");\n        Console.WriteLine(new string('-', 60));\n        for (int i = 0; i < ranking.Count; i++)\n        {\n            var c = ranking[i];\n            Console.WriteLine($\"{i + 1 + \".\",-5} {c.Country,-25} {c.Gold,-6} {c.Silver,-6} {c.Bronze,-6} {c.Total,-6}\");\n        }\n    }\n\n    static void Main()\n    {\n        while (true)\n        {\n            Console.WriteLine(\"\\n====== SIMULADOR JJOO PARÍS 2024 ======\");\n            Console.WriteLine(\"1. Registrar evento\\n2. Registrar participante\\n3. Simular eventos\\n4. Ver informe\\n5. Salir\");\n            Console.Write(\"Selecciona una opción: \");\n            switch (Console.ReadLine()?.Trim())\n            {\n                case \"1\": RegisterEvent(); break;\n                case \"2\": RegisterParticipant(); break;\n                case \"3\": SimulateEvents(); break;\n                case \"4\": ShowReport(); break;\n                case \"5\": Console.WriteLine(\"¡Hasta luego!\"); return;\n                default: Console.WriteLine(\"Opción no válida.\"); break;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/c++/MikeFig99.cpp",
    "content": "#include <iostream>\n#include <vector>\n#include <random>\n#include <string>\n#include <algorithm>\n#include <set>\n#include <unordered_map>\n#include <ctime>\n\nclass Athlete{\n\n    private:\n        std::string name;\n        std::string country;\n    \n    public:\n                \n        Athlete(std::string athleteName, std::string athleteCountry){\n            name = athleteName;\n            country = athleteCountry;\n        }\n\n       bool operator <(const Athlete& other) const {\n            if (name == other.name) {\n                return country < other.country;\n            }\n            return name < other.name;\n       }\n        std::string getName() const {\n            return name;\n        }\n        std::string getCountry() const {\n            return country;\n        }\n};\n\nclass event\n{\n    private:\n        std::string name;\n        std::vector<Athlete> participants;\n\n    public:\n        event(std::string eventName) : name(eventName) {}\n\n        bool operator == (const event& other) const {\n            return name == other.name;\n        }\n\n        std::string getName() const {\n            return name;\n        }\n\n         std::vector<Athlete>& getParticipants() {\n            return participants;\n        }\n\n\n        void insert(const Athlete& athlete) {\n            participants.push_back(athlete);\n        }\n};\n\nclass OlympicsGames\n{\n    private:\n        std::vector<event> eventsList;\n        std::set<Athlete> athletesList;\n        std::unordered_map<std::string, std::unordered_map<std::string, int>> countryMedals;\n        bool Simulated = false;\n        \n    public:\n        void addEvent() {\n            std::string name;\n            std::cout << \"Ingrese el nombre del evento: \";\n            std::cin.ignore(); \n            std::getline(std::cin, name);\n            event newEvent(name);\n\n            if(std::find(eventsList.begin(), eventsList.end(), newEvent) == eventsList.end()){\n                eventsList.push_back(newEvent);\n                std::cout << std::endl << \"+ Evento '\" << newEvent.getName() << \"' agregado exitosamente.\" << std::endl;\n            }else{\n                std::cout << std::endl << \"> El evento ya existe!!!!!\" << std::endl;\n                return;\n            }\n            \n        }   \n\n        void registerAthlete() {\n            if (eventsList.size() == 0) {\n                std::cout << std::endl << \"> No hay eventos disponibles. Agregue un evento primero.\" << std::endl;\n                return;\n            }\n            \n            std::string name, country;\n            std::cout << \"Ingrese el nombre del atleta: \";\n            std::cin.ignore();\n            std::getline(std::cin, name);\n            std::cout << \"Ingrese el pais del atleta: \";\n            std::getline(std::cin, country);\n\n            auto registered = athletesList.insert(Athlete(name, country));\n\n            if(!registered.second){\n                std::cout << std::endl << \"> El atleta ya existe!!!!!\" << std::endl\n                            << \"Quieres registralo en un evento? (s/n): \";\n                char choice;\n                std::cin >> choice;\n                if (choice == 's' || choice == 'S') {\n                    OlympicsGames::registerInEvent(*registered.first);\n                }\n                return;\n            }\n            countryMedals[country] = {{\"Gold\", 0}, {\"Silver\", 0}, {\"Bronze\", 0}};\n\n            std::cout << std::endl << \"+ Atleta '\" << name << \"' de '\" << country << \"' Registrado exitosamente.\" << std::endl;\n            OlympicsGames::registerInEvent(*registered.first); \n\n        }\n\n        void registerInEvent(const Athlete& athlete) {\n            std::cout << std::endl << \"Eventos disponibles:\" << std::endl;\n            for (size_t i = 0; i < eventsList.size(); ++i) {\n                std::cout << i + 1 << \". \" << eventsList[i].getName() << std::endl;\n            }\n\n            std::cout << std::endl << \"Seleccione el # del evento al que desea inscribir al atleta: \";\n            size_t eventOption;\n            std::cin >> eventOption;\n            if (eventOption < 1 || eventOption > eventsList.size()) {\n                std::cout   << std::endl << \"> Opcion no valida\" << std::endl\n                            << \"> Atleta no registrado en el evento.\" << std::endl;\n                return;\n            }\n\n            for (const auto& participant : eventsList[eventOption - 1].getParticipants()) {\n                if (participant.getName() == athlete.getName())\n                {\n                    std::cout << std::endl << \"> El atleta ya esta registrado en este evento.\" << std::endl;\n                    return;\n                } \n            }    \n            eventsList[eventOption - 1].insert(athlete);\n            std::cout << std::endl << \"+ Atleta '\" << athlete.getName() << \"' registrado en el evento '\" << eventsList[eventOption - 1].getName() << \"' exitosamente.\" << std::endl;\n            \n        }\n\n        void SimulateEvents() {\n\n            if (eventsList.size() == 0) {\n                std::cout << std::endl << \"> No hay eventos disponibles. Agregue un evento primero.\" << std::endl;\n                return;\n            }\n\n            for (auto& currentEvent : eventsList) {\n                std::cout << std::endl << \"# Simulando evento: \" << currentEvent.getName() << std::endl;\n\n                std::cout << std::endl << \"Participantes:\" << std::endl;\n                for (const auto& participant : currentEvent.getParticipants()) {\n                    std::cout << \"- \" << participant.getName() << std::endl;\n                }\n                \n                if (currentEvent.getParticipants().size() < 3) {\n                    std::cout << \"> No hay suficientes participantes para este evento. Se necesitan al menos 3.\" << std::endl;\n                    continue;\n                }\n\n                std::shuffle(currentEvent.getParticipants().begin(), currentEvent.getParticipants().end(), std::default_random_engine(time(0)));\n\n                std::cout << std::endl << \"Resultados:\" << std::endl;\n                std::cout   << \"+ Oro: \" << currentEvent.getParticipants()[0].getName() \n                            << \" (\" << currentEvent.getParticipants()[0].getCountry() << \")\" << std::endl;\n\n                countryMedals[currentEvent.getParticipants()[0].getCountry()][\"Gold\"]++;\n\n                std::cout   << \"+ Plata: \" << currentEvent.getParticipants()[1].getName() \n                            << \" (\" << currentEvent.getParticipants()[1].getCountry() << \")\" << std::endl;\n\n                countryMedals[currentEvent.getParticipants()[1].getCountry()][\"Silver\"]++;\n\n                std::cout   << \"+ Bronce: \" << currentEvent.getParticipants()[2].getName() \n                            << \" (\" << currentEvent.getParticipants()[2].getCountry() << \")\" << std::endl;\n\n                countryMedals[currentEvent.getParticipants()[2].getCountry()][\"Bronze\"]++;\n\n            }\n            Simulated = true;\n            std::cout << std::endl << \"# Simulacion de eventos completada.\" << std::endl;\n        }\n        void generateReports() {\n\n            if (!Simulated) {\n                std::cout << std::endl << \"> No se han simulado eventos aun. Simule los eventos primero.\" << std::endl;\n                return;\n            }\n\n            std::cout << std::endl << \"Generando reportes...\" << std::endl;\n\n            std::cout << std::endl << \"Reportes de Eventos...\" << std::endl;\n            for ( auto& event : eventsList)\n            {\n                std::cout << std::endl << \"Evento: \" << event.getName() << std::endl;\n                if (event.getParticipants().size() < 3)\n                {\n                    std::cout << \"> No Simuladoi!!!!!!\" << std::endl;\n                    continue;\n                }\n                \n                std::cout << \"Oro: \" << event.getParticipants()[0].getName() << std::endl;\n                std::cout << \"Plata: \" << event.getParticipants()[1].getName() << std::endl;\n                std::cout << \"Bronce: \" << event.getParticipants()[2].getName() << std::endl;\n            }\n\n            std::cout << std::endl << \"Reporte por Pais...\" << std::endl;\n            for (const auto& country : countryMedals) {\n                std::cout << std::endl << \"Pais: \" << country.first << std::endl;\n                std::cout << \"Oro: \" << country.second.at(\"Gold\") << std::endl;\n                std::cout << \"Plata: \" << country.second.at(\"Silver\") << std::endl;\n                std::cout << \"Bronce: \" << country.second.at(\"Bronze\") << std::endl;\n            }\n\n        }   \n};\n\nint main(){\n    OlympicsGames olympics;\n    std::cout << std::endl << \"!!! Bienvenidos a los Juegos Olimpicos !!!\" << std::endl;\n    \n    char option;\n    \n    while (true)\n    {\n        std::cout << std::endl << \"Opciones: \" << std::endl;\n        std::cout << \"1. Agregar Evento\" << std::endl;\n        std::cout << \"2. Agregar Atleta\" << std::endl;\n        std::cout << \"3. Simular Eventos\" << std::endl;\n        std::cout << \"4. Crear Reporte\" << std::endl;\n        std::cout << \"5. Salir\" << std::endl;\n        std::cout << std::endl << \"Escoje el # de la opcion: \";\n        std::cin >> option; \n        \n        switch (option){\n        case '1':\n            olympics.addEvent();\n            break;\n        \n        case '2':\n            olympics.registerAthlete();\n            break;\n\n        case '3':\n            olympics.SimulateEvents();\n            break;\n\n        case '4':\n            olympics.generateReports();\n            break;\n        \n        case '5':\n            std::cout << std::endl << \"Saliendo del programa. Hasta luego!\" << std::endl;\n            return 0;\n\n        default:\n            std::cout << std::endl << \"Opcion no valida. Intente de nuevo.\" << std::endl;\n            break;\n        }\n    }\n    return 0;\n}   "
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/c++/hectorio23.cpp",
    "content": "// Autor:  Héctor Adán\n// GitHub: https://github.com/hectorio23\n\n#include <iostream>\n#include <vector>\n#include <map>\n#include <string>\n#include <algorithm>\n#include <random>\n#include <ctime>\n\n/*\n * EJERCICIO:\n * ¡Los JJOO de París 2024 han comenzado!\n * Crea un programa que simule la celebración de los juegos.\n * El programa debe permitir al usuario registrar eventos y participantes,\n * realizar la simulación de los eventos asignando posiciones de manera aleatoria\n * y generar un informe final. Todo ello por terminal.\n * Requisitos:\n * 1. Registrar eventos deportivos.\n * 2. Registrar participantes por nombre y país.\n * 3. Simular eventos de manera aleatoria en base a los participantes (mínimo 3).\n * 4. Asignar medallas (oro, plata y bronce) basándose en el resultado del evento.\n * 5. Mostrar los ganadores por cada evento.\n * 6. Mostrar el ranking de países según el número de medallas.\n * Acciones:\n * 1. Registro de eventos.\n * 2. Registro de participantes.\n * 3. Simulación de eventos.\n * 4. Creación de informes.\n * 5. Salir del programa.\n*/\n\n// Estructura para almacenar la información de un participante\nstruct Participant {\n    std::string name;\n    std::string country;\n};\n\n// Estructura para almacenar la información de un evento\nstruct Event {\n    std::string name;\n    std::vector<Participant> participants;\n};\n\n// Función para registrar un evento\nvoid registerEvent(std::vector<Event>& events) {\n    std::string eventName;\n    std::cout << \"Ingrese el nombre del evento: \";\n    std::cin >> eventName;\n    events.push_back({eventName, {}});\n}\n\n// Función para registrar un participante en un evento\nvoid registerParticipant(std::vector<Event>& events) {\n    std::string eventName;\n    std::string participantName;\n    std::string country;\n\n    std::cout << \"Ingrese el nombre del evento: \";\n    std::cin >> eventName;\n\n    auto it = std::find_if(events.begin(), events.end(), [&eventName](const Event& e) {\n        return e.name == eventName;\n    });\n\n    if (it != events.end()) {\n        std::cout << \"Ingrese el nombre del participante: \";\n        std::cin >> participantName;\n        std::cout << \"Ingrese el país del participante: \";\n        std::cin >> country;\n        it->participants.push_back({participantName, country});\n    } else {\n        std::cout << \"Evento no encontrado.\\n\";\n    }\n}\n\n// Función para simular un evento de manera aleatoria\nvoid simulateEvent(const Event& event, std::map<std::string, int>& medalTally) {\n    std::vector<Participant> shuffledParticipants = event.participants;\n    std::shuffle(shuffledParticipants.begin(), shuffledParticipants.end(), std::mt19937{std::random_device{}()});\n\n    std::cout << \"Resultados del evento \" << event.name << \":\\n\";\n    std::cout << \"Oro: \" << shuffledParticipants[0].name << \" (\" << shuffledParticipants[0].country << \")\\n\";\n    std::cout << \"Plata: \" << shuffledParticipants[1].name << \" (\" << shuffledParticipants[1].country << \")\\n\";\n    std::cout << \"Bronce: \" << shuffledParticipants[2].name << \" (\" << shuffledParticipants[2].country << \")\\n\";\n\n    medalTally[shuffledParticipants[0].country] += 3;\n    medalTally[shuffledParticipants[1].country] += 2;\n    medalTally[shuffledParticipants[2].country] += 1;\n}\n\n// Función para mostrar el ranking de medallas por país\nvoid displayMedalTally(const std::map<std::string, int>& medalTally) {\n    std::cout << \"\\nRanking de Medallas por País:\\n\";\n    for (const auto& entry : medalTally) {\n        std::cout << entry.first << \": \" << entry.second << \" puntos\\n\";\n    }\n}\n\n// Función principal para ejecutar el programa\nint main() {\n    std::vector<Event> events;\n    std::map<std::string, int> medalTally;\n    int option;\n\n    while (true) {\n        std::cout << \"\\n1. Registro de eventos\\n2. Registro de participantes\\n3. Simulación de eventos\\n4. Creación de informes\\n5. Salir\\nSeleccione una opción: \";\n        std::cin >> option;\n\n        switch (option) {\n            case 1:\n                registerEvent(events);\n                break;\n            case 2:\n                registerParticipant(events);\n                break;\n            case 3:\n                for (const auto& event : events) {\n                    if (event.participants.size() >= 3) {\n                        simulateEvent(event, medalTally);\n                    } else {\n                        std::cout << \"El evento \" << event.name << \" no tiene suficientes participantes.\\n\";\n                    }\n                }\n                break;\n            case 4:\n                displayMedalTally(medalTally);\n                break;\n            case 5:\n                return 0;\n            default:\n                std::cout << \"Opción inválida.\\n\";\n        }\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/c++/sisaroot.cpp",
    "content": "// #31 SIMULADOR JUEGOS OLÍMPICOS - SisaRoot\n\n#include <iostream>\n#include <vector>\n#include <map>\n#include <string>\n#include <algorithm>\n#include <random>\n#include <iomanip>\n\nstruct Participant { std::string name, country; };\nstruct Event { std::string name; std::vector<Participant> participants; };\nstruct CountryMedals { int gold=0, silver=0, bronze=0; int total() const { return gold+silver+bronze; } };\n\nstd::vector<Event> events;\nstd::map<std::string, CountryMedals> medalTable;\nstd::mt19937 rng(std::random_device{}());\n\nvoid registerEvent() {\n    std::cout << \"Nombre del evento: \";\n    std::string name; std::getline(std::cin, name);\n    for (auto& ev : events) if (ev.name == name) { std::cout << \"Ya existe.\\n\"; return; }\n    events.push_back({name, {}});\n    std::cout << \"Evento '\" << name << \"' registrado.\\n\";\n}\n\nvoid registerParticipant() {\n    if (events.empty()) { std::cout << \"No hay eventos.\\n\"; return; }\n    for (size_t i=0; i<events.size(); i++) std::cout << \"  \" << i+1 << \". \" << events[i].name << \"\\n\";\n    std::cout << \"Selecciona numero: \";\n    int idx; std::cin >> idx; std::cin.ignore();\n    if (idx<1 || idx>(int)events.size()) { std::cout << \"Invalido.\\n\"; return; }\n    auto& ev = events[idx-1];\n    std::cout << \"Nombre: \"; std::string n; std::getline(std::cin, n);\n    std::cout << \"Pais: \";   std::string c; std::getline(std::cin, c);\n    ev.participants.push_back({n, c});\n    std::cout << n << \" (\" << c << \") añadido a '\" << ev.name << \"'.\\n\";\n}\n\nvoid simulateEvents() {\n    if (events.empty()) { std::cout << \"No hay eventos.\\n\"; return; }\n    for (auto& ev : events) {\n        std::cout << \"\\n=== Simulando: \" << ev.name << \" ===\\n\";\n        if (ev.participants.size()<3) { std::cout << \"  Necesita >=3 participantes. Saltando.\\n\"; continue; }\n        auto s = ev.participants;\n        std::shuffle(s.begin(), s.end(), rng);\n        std::cout << \"  Oro:    \" << s[0].name << \" (\" << s[0].country << \")\\n\";\n        std::cout << \"  Plata:  \" << s[1].name << \" (\" << s[1].country << \")\\n\";\n        std::cout << \"  Bronce: \" << s[2].name << \" (\" << s[2].country << \")\\n\";\n        medalTable[s[0].country].gold++; medalTable[s[1].country].silver++; medalTable[s[2].country].bronze++;\n    }\n}\n\nvoid showReport() {\n    std::cout << \"\\n== INFORME FINAL ==\\n\";\n    if (medalTable.empty()) { std::cout << \"Sin resultados aun.\\n\"; return; }\n    std::vector<std::pair<std::string,CountryMedals>> v(medalTable.begin(), medalTable.end());\n    std::sort(v.begin(), v.end(), [](const auto& a, const auto& b){\n        if(a.second.gold!=b.second.gold) return a.second.gold>b.second.gold;\n        if(a.second.silver!=b.second.silver) return a.second.silver>b.second.silver;\n        return a.second.bronze>b.second.bronze;\n    });\n    int pos=1;\n    for (auto& [country, m] : v)\n        std::cout << pos++ << \". \" << std::setw(20) << std::left << country\n                  << \" Oro:\" << m.gold << \" Plata:\" << m.silver << \" Bronce:\" << m.bronze << \" Total:\" << m.total() << \"\\n\";\n}\n\nint main() {\n    while (true) {\n        std::cout << \"\\n====== SIMULADOR JJOO ======\\n1. Registrar evento\\n2. Registrar participante\\n3. Simular\\n4. Informe\\n5. Salir\\nOpcion: \";\n        std::string o; std::getline(std::cin, o);\n        if (o==\"1\") registerEvent();\n        else if (o==\"2\") registerParticipant();\n        else if (o==\"3\") simulateEvents();\n        else if (o==\"4\") showReport();\n        else if (o==\"5\") { std::cout << \"Hasta luego!\\n\"; break; }\n        else std::cout << \"Invalido.\\n\";\n    }\n}\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/ejercicio.md",
    "content": "# #31 SIMULADOR JUEGOS OLÍMPICOS\n> #### Dificultad: Difícil | Publicación: 29/07/24 | Corrección: 05/08/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * ¡Los JJOO de París 2024 han comenzado!\n * Crea un programa que simule la celebración de los juegos.\n * El programa debe permitir al usuario registrar eventos y participantes,\n * realizar la simulación de los eventos asignando posiciones de manera aleatoria\n * y generar un informe final. Todo ello por terminal.\n * Requisitos:\n * 1. Registrar eventos deportivos.\n * 2. Registrar participantes por nombre y país.\n * 3. Simular eventos de manera aleatoria en base a los participantes (mínimo 3).\n * 4. Asignar medallas (oro, plata y bronce) basándose en el resultado del evento.\n * 5. Mostrar los ganadores por cada evento.\n * 6. Mostrar el ranking de países según el número de medallas.\n * Acciones:\n * 1. Registro de eventos.\n * 2. Registro de participantes.\n * 3. Simulación de eventos.\n * 4. Creación de informes.\n * 5. Salir del programa.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/go/hozlucas28.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"math/rand\"\n\t\"slices\"\n\t\"sort\"\n\t\"strings\"\n\t\"time\"\n)\n\n/* -------------------------------------------------------------------------- */\n/*                                  UTILS.GO                                  */\n/* -------------------------------------------------------------------------- */\n\ntype CountryStats struct {\n\tName           CountryName\n\tNumberOfMedals int\n}\n\nfunc CountriesRankingByNumberOfMedals(sportEvents ...*SportEvent) []CountryStats {\n\tvar countriesStats []CountryStats\n\n\tvar winners []*Competitor\n\tfor _, sportEvent := range sportEvents {\n\t\tfor _, winner := range (*sportEvent).GetWinners() {\n\t\t\twinners = append(winners, winner)\n\t\t}\n\t}\n\n\tvar indexesToIgnore []int\n\n\tfor i, winner := range winners {\n\t\tif slices.Contains(indexesToIgnore, i) {\n\t\t\tcontinue\n\t\t}\n\n\t\tvar winnerCountry CountryName = (*winner).GetCountry()\n\t\tvar winnerNumberOfMedals int = len((*winner).GetMedals())\n\n\t\tvar countryStats CountryStats = CountryStats{\n\t\t\tName:           winnerCountry,\n\t\t\tNumberOfMedals: winnerNumberOfMedals,\n\t\t}\n\n\t\tfor j := i + 1; j < len(winners); j++ {\n\t\t\tif slices.Contains(indexesToIgnore, j) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tvar nextWinner *Competitor = winners[j]\n\t\t\tvar nextWinnerCountry CountryName = (*nextWinner).GetCountry()\n\t\t\tvar nextWinnerNumberOfMedals int = len((*nextWinner).GetMedals())\n\n\t\t\tvar areSameCountry bool = strings.ToUpper(string(winnerCountry)) == strings.ToUpper(string(nextWinnerCountry))\n\n\t\t\tif areSameCountry {\n\t\t\t\tcountryStats.NumberOfMedals += nextWinnerNumberOfMedals\n\t\t\t\tindexesToIgnore = append(indexesToIgnore, j)\n\t\t\t}\n\t\t}\n\n\t\tcountriesStats = append(countriesStats, countryStats)\n\t}\n\n\tsort.Slice(countriesStats, func(i, j int) bool {\n\t\treturn countriesStats[i].Name < countriesStats[j].Name\n\t})\n\n\tsort.Slice(countriesStats, func(i, j int) bool {\n\t\treturn countriesStats[i].NumberOfMedals > countriesStats[j].NumberOfMedals\n\t})\n\n\treturn countriesStats\n\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                  MEDAL.GO                                  */\n/* -------------------------------------------------------------------------- */\n\ntype MedalCategory string\n\nvar (\n\tBronze MedalCategory = \"bronze\"\n\tGold   MedalCategory = \"gold\"\n\tSilver MedalCategory = \"silver\"\n)\n\ntype Medal interface {\n\tGetCategory() MedalCategory\n\tGetDate() time.Time\n\tGetSportEvent() SportEvent\n}\n\ntype medal struct {\n\tdate       time.Time\n\tsportEvent SportEvent\n\tcategory   MedalCategory\n\t_          struct{}\n}\n\nfunc NewMedal(date time.Time, sportEvent SportEvent, medalCategory MedalCategory) Medal {\n\tvar medal medal = medal{date: date, sportEvent: sportEvent, category: medalCategory}\n\treturn &medal\n}\n\nfunc (medal *medal) GetCategory() MedalCategory {\n\treturn medal.category\n}\n\nfunc (medal *medal) GetDate() time.Time {\n\treturn medal.date\n}\n\nfunc (medal *medal) GetSportEvent() SportEvent {\n\treturn medal.sportEvent\n\n}\n\n/* -------------------------------------------------------------------------- */\n/*                             COMPETITOR/UTILS.GO                            */\n/* -------------------------------------------------------------------------- */\n\nfunc GetUniqueRandomsCompetitors(competitors []*Competitor, numberOfChoices int) ([]int, []*Competitor) {\n\tvar rtnI []int\n\tvar rtn []*Competitor\n\n\tvar sliceLength int = len(competitors)\n\tvar indexesToIgnore []int\n\n\tfor i := 0; i < numberOfChoices; i++ {\n\t\tvar randomChoiceI int = rand.Intn(sliceLength)\n\t\tif slices.Contains(indexesToIgnore, randomChoiceI) {\n\t\t\ti--\n\t\t\tcontinue\n\t\t}\n\n\t\trtnI = append(rtnI, randomChoiceI)\n\t\trtn = append(rtn, competitors[randomChoiceI])\n\t\tindexesToIgnore = append(indexesToIgnore, randomChoiceI)\n\t}\n\n\treturn rtnI, rtn\n}\n\n/* -------------------------------------------------------------------------- */\n/*                             COMPETITOR/MAIN.GO                             */\n/* -------------------------------------------------------------------------- */\n\ntype CountryName string\n\nvar (\n\tArgentina    CountryName = \"argentina\"\n\tSpain        CountryName = \"spain\"\n\tUnitedStates CountryName = \"united states\"\n\tMexico       CountryName = \"mexico\"\n\tCanada       CountryName = \"canada\"\n\tChile        CountryName = \"chile\"\n\tBrazil       CountryName = \"brazil\"\n\tGermany      CountryName = \"germany\"\n\tFrance       CountryName = \"france\"\n\tItaly        CountryName = \"italy\"\n\tAustralia    CountryName = \"australia\"\n\tJapan        CountryName = \"japan\"\n)\n\ntype Competitor interface {\n\tGetCountry() CountryName\n\tGetMedals() []Medal\n\tGetName() string\n\tAddMedals(newMedals ...Medal)\n}\n\ntype competitor struct {\n\tcountry CountryName\n\tmedals  []Medal\n\tname    string\n\t_       struct{}\n}\n\nfunc NewCompetitor(country CountryName, name string) Competitor {\n\tvar competitor competitor = competitor{country: country, name: name}\n\treturn &competitor\n}\n\nfunc (competitor *competitor) GetCountry() CountryName {\n\treturn competitor.country\n}\n\nfunc (competitor *competitor) GetMedals() []Medal {\n\treturn competitor.medals\n}\n\nfunc (competitor *competitor) GetName() string {\n\treturn competitor.name\n}\n\nfunc (competitor *competitor) AddMedals(newMedals ...Medal) {\n\tvar actualMedals []Medal = competitor.medals\n\tvar joinedMedals []Medal = slices.Concat(actualMedals, newMedals)\n\tcompetitor.medals = joinedMedals\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                SPORTEVENT.GO                               */\n/* -------------------------------------------------------------------------- */\n\nvar (\n\tMinimumNumberOfCompetitors int = 3\n)\n\ntype SportEvent interface {\n\tGetCompetitors() []*Competitor\n\tGetName() string\n\tGetWinners() [3]*Competitor\n\tAddCompetitors(newCompetitors ...*Competitor) error\n\tStart() error\n}\n\ntype sportEvent struct {\n\tcompetitors []*Competitor\n\tname        string\n\twinners     [3]*Competitor\n\n\t_ struct{}\n}\n\nfunc NewSportEvent(name string) SportEvent {\n\tvar sportEvent sportEvent = sportEvent{name: name}\n\treturn &sportEvent\n}\n\nfunc (sportEvent *sportEvent) GetCompetitors() []*Competitor {\n\treturn sportEvent.competitors\n}\n\nfunc (sportEvent *sportEvent) GetName() string {\n\treturn sportEvent.name\n}\n\nfunc (sportEvent *sportEvent) GetWinners() [3]*Competitor {\n\treturn sportEvent.winners\n}\n\nfunc (sportEvent *sportEvent) AddCompetitors(newCompetitors ...*Competitor) error {\n\tvar actualCompetitors []*Competitor = sportEvent.competitors\n\tvar joinedCompetitors []*Competitor = slices.Concat(actualCompetitors, newCompetitors)\n\tsportEvent.competitors = joinedCompetitors\n\treturn nil\n}\n\nfunc (sportEvent *sportEvent) Start() error {\n\tvar numberOfCompetitors int = len(sportEvent.competitors)\n\n\tif numberOfCompetitors < MinimumNumberOfCompetitors {\n\t\treturn fmt.Errorf(\"Sport event %s needs more competitors. It currently has %d competitor(s), but requires a minimum of %d.\", sportEvent.name, len(sportEvent.competitors), MinimumNumberOfCompetitors)\n\t}\n\n\t_, winners := GetUniqueRandomsCompetitors(sportEvent.competitors, 3)\n\n\tvar goldMedal Medal = NewMedal(time.Now(), sportEvent, Gold)\n\tvar silverMedal Medal = NewMedal(time.Now(), sportEvent, Silver)\n\tvar bronzeMedal Medal = NewMedal(time.Now(), sportEvent, Bronze)\n\n\t(*winners[0]).AddMedals(goldMedal)\n\t(*winners[1]).AddMedals(silverMedal)\n\t(*winners[2]).AddMedals(bronzeMedal)\n\n\tsportEvent.winners = [3]*Competitor{winners[0], winners[1], winners[2]}\n\n\treturn nil\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                   MAIN.GO                                  */\n/* -------------------------------------------------------------------------- */\n\nfunc main() {\n\tfmt.Println(\"> Paris 2024 olympic games.\")\n\n\tvar firstSportEvent SportEvent = NewSportEvent(\"football\")\n\tvar secondSportEvent SportEvent = NewSportEvent(\"handball\")\n\tvar thirdSportEvent SportEvent = NewSportEvent(\"table tennis\")\n\tvar fourthSportEvent SportEvent = NewSportEvent(\"swimming\")\n\n\tfmt.Println(\"\\n> First sport event...\")\n\tfmt.Printf(\"\\n%+v\\n\", firstSportEvent)\n\n\tfmt.Println(\"\\n> Second sport event...\")\n\tfmt.Printf(\"\\n%+v\\n\", secondSportEvent)\n\n\tfmt.Println(\"\\n> Third sport event...\")\n\tfmt.Printf(\"\\n%+v\\n\", thirdSportEvent)\n\n\tfmt.Println(\"\\n> Fourth sport event...\")\n\tfmt.Printf(\"\\n%+v\\n\", fourthSportEvent)\n\n\tvar competitorsOfFirstSportEvent [5]Competitor = [5]Competitor{\n\t\tNewCompetitor(Argentina, \"lionel messi\"),\n\t\tNewCompetitor(Spain, \"sergio ramos\"),\n\t\tNewCompetitor(UnitedStates, \"megan rapinoe\"),\n\t\tNewCompetitor(Mexico, \"hirving lozano\"),\n\t\tNewCompetitor(Canada, \"christine sinclair\"),\n\t}\n\n\tvar competitorsOfSecondSportEvent [5]Competitor = [5]Competitor{\n\t\tNewCompetitor(Brazil, \"neymar\"),\n\t\tNewCompetitor(Germany, \"manuel neuer\"),\n\t\tNewCompetitor(France, \"antoine griezmann\"),\n\t\tNewCompetitor(Italy, \"giorgio chiellini\"),\n\t\tNewCompetitor(Australia, \"sam kerr\"),\n\t}\n\n\tvar competitorsOfThirdSportEvent [5]Competitor = [5]Competitor{\n\t\tNewCompetitor(Japan, \"naomi osaka\"),\n\t\tNewCompetitor(Chile, \"liu shiwen\"),\n\t\tNewCompetitor(Spain, \"choi hyojoo\"),\n\t\tNewCompetitor(Italy, \"feng tianwei\"),\n\t\tNewCompetitor(Germany, \"han ying\"),\n\t}\n\n\tvar competitorsOfFourthSportEvent [5]Competitor = [5]Competitor{\n\t\tNewCompetitor(Brazil, \"sarah sjöström\"),\n\t\tNewCompetitor(UnitedStates, \"caleb dressel\"),\n\t\tNewCompetitor(Australia, \"emma mckeon\"),\n\t\tNewCompetitor(Canada, \"penny oleksiak\"),\n\t\tNewCompetitor(Japan, \"ranomi kromowidjojo\"),\n\t}\n\n\tfmt.Println(\"\\n> Competitors of first sport event...\")\n\tfmt.Println()\n\tfor _, competitor := range competitorsOfFirstSportEvent {\n\t\tfmt.Printf(\"%+v\\n\", competitor)\n\t}\n\n\tfmt.Println(\"\\n> Competitors of second sport event...\")\n\tfmt.Println()\n\tfor _, competitor := range competitorsOfSecondSportEvent {\n\t\tfmt.Printf(\"%+v\\n\", competitor)\n\t}\n\n\tfmt.Println(\"\\n> Competitors of third sport event...\")\n\tfmt.Println()\n\tfor _, competitor := range competitorsOfThirdSportEvent {\n\t\tfmt.Printf(\"%+v\\n\", competitor)\n\t}\n\n\tfmt.Println(\"\\n> Competitors of fourth sport event...\")\n\tfmt.Println()\n\tfor _, competitor := range competitorsOfFourthSportEvent {\n\t\tfmt.Printf(\"%+v\\n\", competitor)\n\t}\n\n\tfirstSportEvent.AddCompetitors(\n\t\t&competitorsOfFirstSportEvent[0],\n\t\t&competitorsOfFirstSportEvent[1],\n\t\t&competitorsOfFirstSportEvent[2],\n\t\t&competitorsOfFirstSportEvent[3],\n\t\t&competitorsOfFirstSportEvent[4],\n\t)\n\n\tsecondSportEvent.AddCompetitors(\n\t\t&competitorsOfSecondSportEvent[0],\n\t\t&competitorsOfSecondSportEvent[1],\n\t\t&competitorsOfSecondSportEvent[2],\n\t\t&competitorsOfSecondSportEvent[3],\n\t\t&competitorsOfSecondSportEvent[4],\n\t)\n\n\tthirdSportEvent.AddCompetitors(\n\t\t&competitorsOfThirdSportEvent[0],\n\t\t&competitorsOfThirdSportEvent[1],\n\t\t&competitorsOfThirdSportEvent[2],\n\t\t&competitorsOfThirdSportEvent[3],\n\t\t&competitorsOfThirdSportEvent[4],\n\t)\n\n\tfourthSportEvent.AddCompetitors(\n\t\t&competitorsOfFourthSportEvent[0],\n\t\t&competitorsOfFourthSportEvent[1],\n\t\t&competitorsOfFourthSportEvent[2],\n\t\t&competitorsOfFourthSportEvent[3],\n\t\t&competitorsOfFourthSportEvent[4],\n\t)\n\n\tfirstSportEvent.Start()\n\tsecondSportEvent.Start()\n\tthirdSportEvent.Start()\n\tfourthSportEvent.Start()\n\n\tvar winnersOfFirstSportEvent [3]*Competitor = firstSportEvent.GetWinners()\n\tvar winnersOfSecondSportEvent [3]*Competitor = secondSportEvent.GetWinners()\n\tvar winnersOfThirdSportEvent [3]*Competitor = thirdSportEvent.GetWinners()\n\tvar winnersOfFourthSportEvent [3]*Competitor = fourthSportEvent.GetWinners()\n\n\tfmt.Println(\"\\n> Winners of first sport event...\")\n\tfmt.Println()\n\tfor _, winner := range winnersOfFirstSportEvent {\n\t\tfmt.Printf(\"%+v\\n\", *winner)\n\t}\n\n\tfmt.Println(\"\\n> Winners of second sport event...\")\n\tfmt.Println()\n\tfor _, winner := range winnersOfSecondSportEvent {\n\t\tfmt.Printf(\"%+v\\n\", *winner)\n\t}\n\n\tfmt.Println(\"\\n> Winners of third sport event...\")\n\tfmt.Println()\n\tfor _, winner := range winnersOfThirdSportEvent {\n\t\tfmt.Printf(\"%+v\\n\", *winner)\n\t}\n\n\tfmt.Println(\"\\n> Winners of fourth sport event...\")\n\tfmt.Println()\n\tfor _, winner := range winnersOfFourthSportEvent {\n\t\tfmt.Printf(\"%+v\\n\", *winner)\n\t}\n\n\tvar medalRankingPerCountry = CountriesRankingByNumberOfMedals(\n\t\t&firstSportEvent,\n\t\t&secondSportEvent,\n\t\t&thirdSportEvent,\n\t\t&fourthSportEvent,\n\t)\n\n\tfmt.Println(\"\\n> Medal ranking per country...\")\n\tfor _, countryStats := range medalRankingPerCountry {\n\t\tfmt.Printf(\"\\n%+v\", countryStats)\n\t}\n}\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/go/sisaroot.go",
    "content": "// #31 SIMULADOR JUEGOS OLÍMPICOS - SisaRoot\n\npackage main\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"math/rand\"\n\t\"os\"\n\t\"sort\"\n\t\"strings\"\n\t\"time\"\n)\n\ntype Participant struct{ Name, Country string }\ntype Event struct {\n\tName         string\n\tParticipants []Participant\n}\ntype CountryMedals struct {\n\tCountry        string\n\tGold, Silver, Bronze int\n}\n\nfunc (c CountryMedals) Total() int { return c.Gold + c.Silver + c.Bronze }\n\nvar events []Event\nvar medalTable = map[string]*CountryMedals{}\nvar reader = bufio.NewReader(os.Stdin)\n\nfunc readLine(prompt string) string {\n\tfmt.Print(prompt)\n\tline, _ := reader.ReadString('\\n')\n\treturn strings.TrimSpace(line)\n}\n\nfunc registerEvent() {\n\tname := readLine(\"Nombre del evento: \")\n\tif name == \"\" { fmt.Println(\"Nombre invalido.\"); return }\n\tfor _, ev := range events {\n\t\tif strings.EqualFold(ev.Name, name) { fmt.Printf(\"'%s' ya existe.\\n\", name); return }\n\t}\n\tevents = append(events, Event{Name: name})\n\tfmt.Printf(\"Evento '%s' registrado.\\n\", name)\n}\n\nfunc registerParticipant() {\n\tif len(events) == 0 { fmt.Println(\"No hay eventos.\"); return }\n\tfor i, ev := range events { fmt.Printf(\"  %d. %s\\n\", i+1, ev.Name) }\n\tvar idx int\n\tfmt.Sscanf(readLine(\"Selecciona número: \"), \"%d\", &idx)\n\tif idx < 1 || idx > len(events) { fmt.Println(\"Invalido.\"); return }\n\tev := &events[idx-1]\n\tpname := readLine(\"Nombre: \")\n\tcountry := readLine(\"País: \")\n\tev.Participants = append(ev.Participants, Participant{pname, country})\n\tfmt.Printf(\"'%s (%s)' añadido a '%s'.\\n\", pname, country, ev.Name)\n}\n\nfunc simulateEvents() {\n\tif len(events) == 0 { fmt.Println(\"No hay eventos.\"); return }\n\trng := rand.New(rand.NewSource(time.Now().UnixNano()))\n\tfor _, ev := range events {\n\t\tfmt.Printf(\"\\n=== Simulando: %s ===\\n\", ev.Name)\n\t\tif len(ev.Participants) < 3 { fmt.Printf(\"  Necesita >=3 participantes. Saltando.\\n\"); continue }\n\t\ts := make([]Participant, len(ev.Participants))\n\t\tcopy(s, ev.Participants)\n\t\trng.Shuffle(len(s), func(i, j int) { s[i], s[j] = s[j], s[i] })\n\t\tfmt.Printf(\"  Oro:    %s (%s)\\n\", s[0].Name, s[0].Country)\n\t\tfmt.Printf(\"  Plata:  %s (%s)\\n\", s[1].Name, s[1].Country)\n\t\tfmt.Printf(\"  Bronce: %s (%s)\\n\", s[2].Name, s[2].Country)\n\t\taddMedal(s[0].Country, \"gold\"); addMedal(s[1].Country, \"silver\"); addMedal(s[2].Country, \"bronze\")\n\t}\n}\n\nfunc addMedal(country, t string) {\n\tif _, ok := medalTable[country]; !ok { medalTable[country] = &CountryMedals{Country: country} }\n\tswitch t {\n\tcase \"gold\": medalTable[country].Gold++\n\tcase \"silver\": medalTable[country].Silver++\n\tcase \"bronze\": medalTable[country].Bronze++\n\t}\n}\n\nfunc showReport() {\n\tfmt.Println(\"\\n== INFORME FINAL ==\")\n\tif len(medalTable) == 0 { fmt.Println(\"Sin resultados aun.\"); return }\n\tvar r []*CountryMedals\n\tfor _, cm := range medalTable { r = append(r, cm) }\n\tsort.Slice(r, func(i, j int) bool {\n\t\tif r[i].Gold != r[j].Gold { return r[i].Gold > r[j].Gold }\n\t\tif r[i].Silver != r[j].Silver { return r[i].Silver > r[j].Silver }\n\t\treturn r[i].Bronze > r[j].Bronze\n\t})\n\tfor i, c := range r {\n\t\tfmt.Printf(\"%d. %-20s Oro:%d Plata:%d Bronce:%d Total:%d\\n\", i+1, c.Country, c.Gold, c.Silver, c.Bronze, c.Total())\n\t}\n}\n\nfunc main() {\n\tfor {\n\t\tfmt.Println(\"\\n====== SIMULADOR JJOO ======\")\n\t\tfmt.Println(\"1. Registrar evento\\n2. Registrar participante\\n3. Simular\\n4. Informe\\n5. Salir\")\n\t\tswitch readLine(\"Opción: \") {\n\t\tcase \"1\": registerEvent()\n\t\tcase \"2\": registerParticipant()\n\t\tcase \"3\": simulateEvents()\n\t\tcase \"4\": showReport()\n\t\tcase \"5\": fmt.Println(\"Hasta luego!\"); return\n\t\tdefault: fmt.Println(\"Invalido.\")\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/java/AmadorQuispe.java",
    "content": "package com.amsoft.roadmap.example31;\n\nimport java.util.*;\n\npublic class Example31 {\n    public static void main(String[] args) {\n        System.out.println(\"\"\"\n                SIMULADOR JUEGOS OLÍMPICOS:\n                --------------------------------------------------\n                | 1. Registrar evento        | 4. Crear informes |\n                | 2. Registrar participante  | 5. Salir          |\n                | 3. Simulación de eventos   |                   |\n                --------------------------------------------------        \\s\n                \"\"\");\n        ManagerOlympic managerOlympic = new ManagerOlympic();\n        Scanner sc = new Scanner(System.in);\n        while (true) {\n            System.out.print(\"Ingresa el número de la opción:\");\n            String option = sc.nextLine();\n            switch (option) {\n                case \"1\":\n                    System.out.print(\"Ingresa el nombre del evento:\");\n                    String event = sc.nextLine();\n                    System.out.println(managerOlympic.addEvent(event));\n                    break;\n                case \"2\":\n                    System.out.println(\"Registrar participante\");\n                    System.out.print(\"Ingresa el nombre del evento:\");\n                    String eventParticipant = sc.nextLine();\n                    System.out.print(\"Ingresa el nombre del participante:\");\n                    String name = sc.nextLine();\n                    System.out.print(\"Ingresa el país del participante:\");\n                    String country = sc.nextLine();\n                    Participant participant = new Participant(name, country);\n                    System.out.println(managerOlympic.registerParticipant(eventParticipant, participant));\n                    break;\n                case \"3\":\n                    System.out.println(\"Simulación de eventos\");\n                    managerOlympic.simulateEvents();\n                    break;\n                case \"4\":\n                    managerOlympic.createReports();\n                    break;\n                case \"5\":\n                    System.out.println(\"Saliendo\");\n                    System.exit(0);\n                    break;\n                default:\n                    System.out.println(\"Saliendo\");\n                    break;\n            }\n        }\n    }\n}\n\nclass Participant {\n    private String name;\n    private String country;\n\n    public Participant(String name, String country) {\n        this.name = name;\n        this.country = country;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public String getCountry() {\n        return country;\n    }\n\n    public void setCountry(String country) {\n        this.country = country;\n    }\n\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) return true;\n        if (o == null || getClass() != o.getClass()) return false;\n        Participant that = (Participant) o;\n        return Objects.equals(name, that.name) && Objects.equals(country, that.country);\n    }\n\n    @Override\n    public int hashCode() {\n        return Objects.hash(name, country);\n    }\n}\n\nclass ManagerOlympic {\n    private final HashMap<String, List<Participant>> events;\n    private final HashMap<String, List<Participant>> eventResults;\n\n    ManagerOlympic() {\n        this.events = new HashMap<>();\n        this.eventResults = new HashMap<>();\n    }\n\n    public String addEvent(String eventName) {\n        if (this.events.containsKey(eventName)) {\n            return \"El evento \" + eventName + \" ya está registrado\";\n        }\n        List<Participant> participants = new ArrayList<>();\n        this.events.put(eventName, participants);\n        return \"El evento \" + eventName + \" fué registrado correctamente\";\n    }\n\n    public String registerParticipant(String eventName, Participant participant) {\n        if (!this.events.containsKey(eventName)) {\n            return \"El evento \" + eventName + \" no está registrado aún, registralo!!\";\n        }\n        List<Participant> participantsEvent = this.events.get(eventName);\n        if (participantsEvent.contains(participant)) {\n            return String.format(\n                    \"El participante %s de %s ya está registrado en el evento deportivo %s.\",\n                    participant.getName(),\n                    participant.getCountry(),\n                    eventName\n            );\n        }\n        participantsEvent.add(participant);\n        return String.format(\n                \"El participante %s de %s se ha registrado en el evento deportivo %s.\",\n                participant.getName(),\n                participant.getCountry(),\n                eventName\n        );\n    }\n\n    public void simulateEvents() {\n        if (this.events.isEmpty()) {\n            System.out.println(\"No hay eventos para iniciar simulación, registra una!!\");\n            return;\n        }\n        this.events.forEach((event, participants) -> {\n            if (participants.size() < 3) {\n                System.out.println(\"No hay participantes suficientes para simular el evento \" + event + \" (mínimo 3)\");\n                return;\n            }\n            Random r = new Random();\n            List<Participant> winners = new ArrayList<>();\n            while (winners.size() < 3) {\n                Participant winner = participants.get(r.nextInt(participants.size()));\n                if (winners.contains(winner)) {\n                    continue;\n                }\n                winners.add(winner);\n            }\n            this.eventResults.put(event, winners);\n        });\n        System.out.println(\"Simulación de eventos finalizada\");\n        System.out.println(\"Resultados:\");\n        this.eventResults.forEach((event, winners) -> {\n            System.out.println(\"Evento: \" + event);\n            System.out.println(\"Ganadores:\");\n            String gold = winners.get(0).getName() + \" de \" + winners.get(0).getCountry();\n            String silver = winners.get(1).getName() + \" de \" + winners.get(1).getCountry();\n            String bronze = winners.get(2).getName() + \" de \" + winners.get(2).getCountry();\n            System.out.println(\"Oro: \" + gold);\n            System.out.println(\"Plata: \" + silver);\n            System.out.println(\"Bronce: \" + bronze);\n        });\n\n    }\n\n    public void createReports() {\n        System.out.println(\"INFORME JUEGOS OLÍMPICOS\");\n        System.out.println(\"------------------------\");\n        if (this.eventResults.isEmpty()) {\n            System.out.println(\"No hay eventos para mostrar resultados\");\n            return;\n        }\n        System.out.println(\"Informe por eventos\");\n        System.out.println(\"-------------------\");\n        this.eventResults.forEach((event, winners) -> {\n            System.out.println(\"Evento: \" + event);\n            System.out.println(\"Ganadores:\");\n            String gold = winners.get(0).getName() + \" de \" + winners.get(0).getCountry();\n            String silver = winners.get(1).getName() + \" de \" + winners.get(1).getCountry();\n            String bronze = winners.get(2).getName() + \" de \" + winners.get(2).getCountry();\n            System.out.println(\"Oro: \" + gold);\n            System.out.println(\"Plata: \" + silver);\n            System.out.println(\"Bronce: \" + bronze);\n        });\n\n        System.out.println(\"Informe por países\");\n        System.out.println(\"-------------------\");\n        HashMap<String, List<Integer>> rankingMedals = new HashMap<>();\n        this.eventResults.forEach((event, winners) -> {\n            var gold = winners.get(0).getCountry();\n            var silver = winners.get(1).getCountry();\n            var bronze = winners.get(2).getCountry();\n            rankingMedals.putIfAbsent(gold, new ArrayList<>(Arrays.asList(0, 0, 0)));\n            rankingMedals.putIfAbsent(silver, new ArrayList<>(Arrays.asList(0, 0, 0)));\n            rankingMedals.putIfAbsent(bronze, new ArrayList<>(Arrays.asList(0, 0, 0)));\n            rankingMedals.get(gold).set(0, rankingMedals.get(gold).getFirst() + 1);\n            rankingMedals.get(silver).set(1, rankingMedals.get(silver).get(1) + 1);\n            rankingMedals.get(bronze).set(2, rankingMedals.get(bronze).get(2) + 1);\n\n        });\n        System.out.println(\"Ranking de medallas\");\n        rankingMedals.entrySet()\n                .stream()\n                .sorted((e1, e2) -> {\n                    int compareGold = e2.getValue().get(0) - e1.getValue().get(0); // Oro\n                    if (compareGold != 0) return compareGold;\n                    int compareSilver = e2.getValue().get(1) - e1.getValue().get(1); // Plata\n                    if (compareSilver != 0) return compareSilver;\n                    return e2.getValue().get(2) - e1.getValue().get(2); // Bronce\n                })\n                .forEach(entry -> {\n                    System.out.println(\"País: \" + entry.getKey());\n                    String result = String.format(\"Oro: %d, Plata: %d, Bronce: %d\",\n                            entry.getValue().get(0),\n                            entry.getValue().get(1),\n                            entry.getValue().get(2));\n                    System.out.println(result);\n                });\n\n\n    }\n\n\n}\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/java/JesusWay69.java",
    "content": "package ejercicio31;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Scanner;\nimport java.util.TreeMap;\n\n/*\n * EJERCICIO:\n * ¡Los JJOO de París 2024 han comenzado!\n * Crea un programa que simule la celebración de los juegos.\n * El programa debe permitir al usuario registrar eventos y participantes,\n * realizar la simulación de los eventos asignando posiciones de manera aleatoria\n * y generar un informe final. Todo ello por terminal.\n * Requisitos:\n * 1. Registrar eventos deportivos.\n * 2. Registrar participantes por nombre y país.\n * 3. Simular eventos de manera aleatoria en base a los participantes (mínimo 3).\n * 4. Asignar medallas (oro, plata y bronce) basándose en el resultado del evento.\n * 5. Mostrar los ganadores por cada evento.\n * 6. Mostrar el ranking de países según el número de medallas.\n * Acciones:\n * 1. Registro de eventos.\n * 2. Registro de participantes.\n * 3. Simulación de eventos.\n * 4. Creación de informes.\n * 5. Salir del programa.\n */\npublic class JesusWay69 {\n\n    public static void main(String[] args) {\n        Scanner sc = new Scanner(System.in);\n        String option;\n        OlympicGames olympicGames = new OlympicGames();\n\n        do {\n            System.out.print(\"\"\"\n                           Elija una opci\\u00f3n:\n                           1- Registrar evento\n                           2- Registrar participante\n                           3- Simular evento\n                           4- Crear informe\n                           5- Salir\n                           --->  \"\"\");\n            option = sc.next().strip();\n            sc.nextLine();\n            switch (option) {\n                case \"1\":\n                    System.out.print(\"Escriba el nombre de la competición a registrar: \");\n                    String sport = sc.nextLine().strip().toUpperCase();\n                    olympicGames.registerEvent(sport);\n                    break;\n                case \"2\":\n                    System.out.print(\"Escriba el nombre del participante a registrar: \");\n                    String name = sc.nextLine().strip().toUpperCase();\n                    System.out.print(\"Escriba el nombre del pais de \" + name + \" : \");\n                    String country = sc.nextLine().strip().toUpperCase();\n                    olympicGames.registerAthlete(name, country);\n                    break;\n                case \"3\":\n                    olympicGames.eventSimulator();\n                    break;\n                case \"4\":\n                    olympicGames.showEvents();\n                    olympicGames.showAthletes();\n                    break;\n                case \"5\":\n                    break;\n\n            }\n\n        } while (!\"5\".equals(option));\n\n    }\n\n}\n\nclass OlympicGames {\n\n    List<String> sportEvents = new ArrayList<>();\n    Map<String, String> competitors = new HashMap<>();\n\n    public OlympicGames() {\n    }\n\n    public void registerEvent(String event) {\n        sportEvents.add(event);\n        System.out.println(\"El evento deportivo \" + event + \" se ha registrado correctamente\\n\");\n\n    }\n\n    public void registerAthlete(String name, String country) {\n        competitors.put(name, country);\n        System.out.print(\"El participante \" + name + \" de \" + country + \" se ha registrado correctamente\\n\");\n        showEvents();\n\n    }\n\n    public void showEvents() {\n        System.out.println(\"Deportes disponibles:\");\n        int i = 0;\n        for (String sport : sportEvents) {\n            i++;\n            System.out.println(i + \"-\" + sport);\n        }\n\n    }\n\n    public void showAthletes() {\n        int i = 0;\n        System.out.println(\"Atletas disponibles: \");\n        for (String key : competitors.keySet()) {\n            String value = competitors.get(key);\n            i++;\n            System.out.println(i + \"-\" + key + \" --> \" + value);\n        }\n    }\n\n    public void eventSimulator() {\n        int athNum = 1, sportNum = 0;\n        Scanner sc = new Scanner(System.in);\n        System.out.println(\"Comienzan los eventos!!\");\n        System.out.println(\"-----------------------\");\n        //TreeMap<String, String> selectecCompetitors = new TreeMap<>();\n        List<String> competitorsNames = new ArrayList<>();\n        List<String> competitorsCountries = new ArrayList<>();\n\n        boolean flag = true;\n\n        while (flag) {\n            showEvents();\n            System.out.print(\"Elija el número del deporte para empezar la competición: \");\n            sportNum = sc.nextInt();\n            if (sportNum < 1 || sportNum > sportEvents.size()) {\n                System.out.println(\"El número \" + sportNum + \" no corresponde a ningún deporte\");\n            } else {\n                System.out.println(\"Empieza la competición de \" + sportEvents.get(sportNum - 1));\n                flag = false;\n            }\n        }\n        while (!competitors.isEmpty() || athNum != 0) {\n            showAthletes();\n            System.out.print(\"Elija el número de un deportista para empezar la competición de: \"\n                    + sportEvents.get(sportNum - 1)\n                    + \"\\n e introduce 0 cuando se hayan seleccionado al menos 3 participantes para terminar la selección: \");\n            athNum = sc.nextInt();\n            if (athNum < 0 || athNum > competitors.size()) {\n                System.out.println(\"El número \" + athNum + \" no corresponde a ningún deportista\");\n            } else {\n                int i = 0;\n                for (String key : competitors.keySet()) {\n                    String value = competitors.get(key);\n                    i++;\n                    if (athNum == i) {\n                        competitorsNames.add(key);\n                        competitorsCountries.add(value);\n                        //selectecCompetitors.put(key, value);\n                        System.out.println(\"Participante nº \" + athNum + \" añadido a la competición de \" + sportEvents.get(sportNum - 1));\n                    } else if (athNum == 0 && competitorsNames.size() < 3) {\n                        System.out.println(\"Debe elegir al menos 3 participantes\");\n                    } else if (athNum == 0 && competitorsNames.size() >= 3) {\n                        competitors.clear();\n                        randomCompetition(competitorsNames, competitorsCountries);\n                    }\n                }\n            }\n        }\n\n    }\n\n    public void randomCompetition(List competitorsNames, List competitorsCountries) {\n        String[] podium = {\"oro\", \"plata\", \"bronce\"};\n        int medal = 0;\n\n        while (!competitorsNames.isEmpty() && !competitorsCountries.isEmpty()) {\n\n            for (int i = 0; i < 3; i++) {\n                int winner = (int) (Math.random() * competitorsNames.size());\n                System.out.println(\"El atleta \" + competitorsNames.get(winner) + \" de \" + competitorsCountries.get(winner)\n                        + \" gana la medalla de \" + podium[medal]);\n                medal++;\n                competitorsNames.remove(winner);\n                competitorsCountries.remove(winner);\n                if (medal>=2){\n                    break;\n                }\n\n            }\n\n        }\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/java/Josegs95.java",
    "content": "import java.util.*;\n\npublic class Josegs95 {\n\n    final Scanner sc = new Scanner(System.in);\n\n    public static void main(String[] args) {\n        new Josegs95().olympics();\n    }\n\n    public void olympics(){\n        try(sc){\n            Olympics olympics = new Olympics();\n            app: while(true){\n                String option = askOption();\n                switch (option){\n                    case \"1\":\n                        olympics.registerEvent();\n                        break;\n                    case \"2\":\n                        olympics.registerParticipant();\n                       break;\n                    case \"3\":\n                        olympics.simulateEvent();\n                        break;\n                    case \"4\":\n                        olympics.logCreation();\n                        break;\n                    case \"5\":;\n                        break app;\n                    default:\n                        System.out.println(\"Opción incorrecta. Introduzca el número de la opción deseada\");\n                }\n            }\n            System.out.println(\"Terminando la aplicación. Gracias por usarla.\");\n        }\n    }\n\n    public enum Option{\n        REG_EVENT(\"Registro de eventos\"),\n        REG_PARTICIPANT(\"Registro de participantes\"),\n        SIM_EVENT(\"Simulación de eventos\"),\n        LOG_CREATION(\"Creación de informes\"),\n        EXIT(\"Salir del programa\");\n\n        private String name;\n\n        Option(String name){\n            this.name = name;\n        }\n\n        @Override\n        public String toString() {\n            return name;\n        }\n    }\n\n    private String askOption(){\n        showOptions();\n        System.out.print(\"Introduzca la opción deseada: \");\n        return sc.nextLine();\n    }\n\n    private void showOptions(){\n        System.out.println();\n        System.out.println(\"---Opciones---\");\n        for (int i = 0; i < Option.values().length; i++)\n            System.out.println((i + 1) + \". \" + Option.values()[i]);\n        System.out.println(\"--------------\");\n    }\n\n    public class Olympics{\n        private List<Event> eventList;\n        private List<Event> activeEventList;\n        private List<Nation> nationList;\n\n        Olympics(){\n            eventList = new ArrayList<>();\n            activeEventList = new ArrayList<>();\n            nationList = new ArrayList<>();\n        }\n\n        public void registerEvent(){\n            System.out.print(\"Introduzca el nombre del evento: \");\n            String name = sc.nextLine().strip();\n            Event event = new Event(name);\n\n            if (activeEventList.contains(event))\n                System.out.println(\"El evento \" + name + \" ya existe\");\n            else{\n                activeEventList.add(event);\n                eventList.add(event);\n                System.out.println(\"Evento \" + name + \" registrado correctamente\");\n            }\n\n        }\n\n        public void registerParticipant(){\n            if (activeEventList.isEmpty()){\n                System.out.println(\"No hay ningún evento activo para incribir a ningún participante\");\n                return;\n            }\n\n            System.out.print(\"Introduzca el nombre del participante: \");\n            String name = sc.nextLine().strip();\n            System.out.print(\"Introduzca la nacionalidad del participante: \");\n            String nationality = sc.nextLine().strip();\n            Nation nation = addNationtoList(nationality);\n            Participant participant = new Participant(name, nation);\n\n            Event event = askEvent();\n\n            if (event.addParticipant(participant))\n                System.out.println(name + \" registrado correctamente\");\n            else\n                System.out.println(name + \" ya estaba registrado\");\n        }\n\n        public void simulateEvent(){\n            if (activeEventList.isEmpty()){\n                System.out.println(\"No hay ningún evento activo para incribir a ningún participante\");\n                return;\n            }\n\n            Event event = askEvent();\n            if (event.countParticipants() < 3){\n                System.out.println(\"Solo se puede simular un evento si tiene mas de 3 participantes\");\n                return;\n            }\n\n            Random rnd = new Random();\n            List<Participant> aux = new ArrayList<>(event.getParticipantList());\n            Participant goldParticipant = aux.remove(rnd.nextInt(aux.size()));\n            Participant silverParticipant = aux.remove(rnd.nextInt(aux.size()));\n            Participant bronzeParticipant = aux.remove(rnd.nextInt(aux.size()));\n\n            event.setGold(goldParticipant);\n            event.setSilver(silverParticipant);\n            event.setBronze(bronzeParticipant);\n            goldParticipant.getNationality().addGoldMedal();\n            silverParticipant.getNationality().addSilverMedal();\n            bronzeParticipant.getNationality().addBronzeMedal();\n\n            System.out.println(\"Evento: \" + event);\n            System.out.println(\"Oro: \" + goldParticipant);\n            System.out.println(\"Plata: \" + silverParticipant);\n            System.out.println(\"Bronce: \" + bronzeParticipant);\n\n            activeEventList.remove(event);\n        }\n\n        public void logCreation(){\n            if (nationList.isEmpty()){\n                System.out.println(\"No hay naciones registradas aún\");\n                return;\n            }\n\n            System.out.println();\n            System.out.println(\"Ranking de naciones:\");\n            Collections.sort(nationList, Collections.reverseOrder());\n            for (Nation nation : nationList)\n                System.out.println(nation.getNationInfo());\n\n            System.out.println();\n            List<Event> aux = new ArrayList<>(eventList);\n            aux.removeAll(activeEventList);\n            for (Event event : aux){\n                System.out.println(event + \"-> Oro: \" + event.getGold() + \", Plata: \"\n                    + event.getSilver() + \", Bronce: \" + event.getBronze());\n            }\n\n        }\n\n        private void showEvents(){\n            System.out.println();\n            System.out.println(\"---Eventos---\");\n            for (int i = 0; i < activeEventList.size(); i++){\n                System.out.println((i + 1) + \". \" + activeEventList.get(i));\n            }\n            System.out.println(\"-------------\");\n        }\n\n        private Event askEvent(){\n            showEvents();\n            boolean validOption = false;\n            int option = -1;\n            do{\n                System.out.print(\"Seleccione a qué evento quiere registrarlo: \");\n                try{\n                    option = Integer.parseInt(sc.nextLine()) - 1;\n                    if (option < 0 || option >= activeEventList.size())\n                        System.out.println(\"Opción inválida. Hay \" + activeEventList.size() + \" eventos disponibles.\");\n                    else\n                        validOption = true;\n                } catch (NumberFormatException e){\n                    System.out.println(\"Opción inválida. Debe escribir un número\");\n                }\n            }while(!validOption);\n\n            return activeEventList.get(option);\n        }\n\n        private Nation addNationtoList(String name){\n            for(Nation nation : nationList){\n                if (nation.getName().toLowerCase().equals(name.toLowerCase()))\n                    return nation;\n            }\n\n            Nation nation = new Nation(name);\n            nationList.add(nation);\n            return nation;\n        }\n    }\n\n    public class Event{\n        private String name;\n        private List<Participant> participantList;\n        private Participant gold = null;\n        private Participant silver = null;\n        private Participant bronze = null;\n\n        Event(String name){\n            this.name = name;\n            participantList = new ArrayList<>();\n        }\n\n        public boolean addParticipant(Participant participant){\n            return participantList.add(participant);\n        }\n\n        public int countParticipants(){\n            return participantList.size();\n        }\n\n        public List<Participant> getParticipantList() {\n            return participantList;\n        }\n\n        public Participant getGold() {\n            return gold;\n        }\n\n        public Participant getSilver() {\n            return silver;\n        }\n\n        public Participant getBronze() {\n            return bronze;\n        }\n\n        public void setGold(Participant gold) {\n            this.gold = gold;\n        }\n\n        public void setSilver(Participant silver) {\n            this.silver = silver;\n        }\n\n        public void setBronze(Participant bronze) {\n            this.bronze = bronze;\n        }\n\n        @Override\n        public String toString() {\n            return name;\n        }\n\n        @Override\n        public boolean equals(Object o) {\n            if (this == o) return true;\n            if (!(o instanceof Event event)) return false;\n            return Objects.equals(name, event.name);\n        }\n\n        @Override\n        public int hashCode() {\n            return Objects.hash(name, participantList);\n        }\n    }\n\n    public class Participant{\n        private String name;\n        private Nation nationality;\n\n        public Participant(String name, Nation nationality) {\n            this.name = name;\n            this.nationality = nationality;\n        }\n\n        public String getName() {\n            return name;\n        }\n\n        public Nation getNationality() {\n            return nationality;\n        }\n\n        @Override\n        public String toString() {\n            return name + \"(\" + nationality + \")\";\n        }\n    }\n\n    public class Nation implements Comparable<Nation>{\n        private String name;\n        private int nGold = 0;\n        private int nSilver = 0;\n        private int nBronze = 0;\n\n        private int medalValue = 0;\n\n        Nation(String name){\n            this.name = name;\n        }\n\n        public void addGoldMedal(){\n            nGold++;\n            medalValue += 4;\n        }\n        public void addSilverMedal(){\n            nSilver++;\n            medalValue += 2;\n        }\n        public void addBronzeMedal(){\n            nBronze++;\n            medalValue += 1;\n        }\n\n        public int getMedalValue(){\n            return medalValue;\n        }\n\n        public String getName() {\n            return name;\n        }\n\n        public String getNationInfo(){\n            return name + \": \" + nGold + \" oros, \" + nSilver\n                    + \" platas, \" + nBronze + \" bronces\";\n        }\n\n        @Override\n        public String toString() {\n            return name;\n        }\n\n        @Override\n        public boolean equals(Object o) {\n            if (this == o) return true;\n            if (!(o instanceof Nation nation)) return false;\n            return Objects.equals(name, nation.name);\n        }\n\n        @Override\n        public int hashCode() {\n            return Objects.hashCode(name);\n        }\n\n        @Override\n        public int compareTo(Nation nation) {\n            return this.medalValue - nation.getMedalValue();\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/java/VolumiDev.java",
    "content": "import java.io.BufferedReader;\nimport java.io.File;\nimport java.io.FileWriter;\nimport java.io.IOException;\nimport java.io.InputStreamReader;\nimport java.io.PrintWriter;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Random;\n\n\npublic class VolumiDev {\n\t/**\n\t * Muestra el menu de la aplicacion.\n\t * @return\n\t * @throws IOException\n\t */\n\tpublic static int menu() throws IOException {\n\t\tLectura l = new Lectura();\n\t\tint op;\n\t\tSystem.out.println(\"1. Registrar eventos y participantes del evento\");\n\t\tSystem.out.println(\"2. Simular Eventos\");\n\t\tSystem.out.println(\"3. Creacion de informes\");\n\t\tSystem.out.println(\"4. Salir\");\n\t\top = l.pedir_entero(\"Introduce una de las opciones anteriores\", 1, 4);\n\t\treturn op;\n\t}\n\t\n\t/**\n\t * Crea y alamacena los enventos en una array list\n\t * @param events\n\t * @throws IOException\n\t */\n\tpublic static void registrar_evento(ArrayList<Evento> events) throws IOException {\n\t\tEvento event = new Evento();\n\t\tevent.registrar_evento(events);\n\t\tevents.add(event);\n\t}\n\t\n\t/**\n\t * mostramos los eventos reegistrado con el codigo del mismo para poder identificarlo.\n\t * @param events\n\t * @throws IOException \n\t */\n\tpublic static int mostramos_eventos(ArrayList<Evento> events) throws IOException {\n\t\tLectura l = new Lectura();\n\t\tint event_cod;\n\t\tfor (Evento event : events) {\n\t\t\tSystem.out.println(event.cod + \". \" + event.nombre);\n\t\t}\n\t\tevent_cod = l.pedir_entero(\"Elige el evento que deseas\", 1, events.size());\n\t\treturn event_cod-1;\n\t}\n\t\n\t/**\n\t * Metodo que llama a la función de simulación y a la de establecer el medallero\n\t * @param events\n\t * @throws IOException\n\t */\n\tpublic static void simular_event(ArrayList<Evento> events) throws IOException {\n\t\tEvento event = events.get(mostramos_eventos(events));\n\t\tevent.simulacion();\n\t\tevent.est_medallero();\n\t}\n\t\n\tpublic static boolean generar_informe(ArrayList<Evento> events, boolean flag_txt) throws IOException {\n\t\tEvento event = events.get(mostramos_eventos(events));\n\t\tif(event.informado) {\n\t\t\tFile txt = new File(\"Informe_medallas.txt\");\n\t\t\tif(flag_txt) {\n\t\t\t\tif(txt.exists()) {\n\t\t\t\t\ttxt.delete();\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(event.ejecucion == false) {\n\t\t\t\t\n\t\t\t\tFileWriter fw = new FileWriter(txt, true);\n\t\t\t\tPrintWriter pw = new PrintWriter(fw);\n\t\t\t\t\n\t\t\t\tpw.println(event.nombre.toUpperCase());\n\t\t\t\tfor(String medalla : event.medallero) {\n\t\t\t\t\tpw.println(\"\\t\" + medalla);;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tevent.informado = false;\n\t\t\t\tpw.close();\n\t\t\t\tfw.close();\t\t\t\n\t\t\t}else {\n\t\t\t\tSystem.out.println(\"El evento no se ha ejecutado aun\");\n\t\t\t}\n\t\t}else {\n\t\t\tSystem.out.println(\"El evento ya ha generado informes\");\n\t\t}\n\t\treturn false;\n\t}\n\tpublic static void main(String[] args) throws IOException {\t\n\t\tArrayList<Evento> events  = new ArrayList<Evento>();\n\t\tLectura l = new Lectura();\n\t\tboolean flag_txt = true;\n\t\tint op = menu();\n\t\twhile(op != 4) {\n\t\t\tswitch(op) {\n\t\t\tcase 1:\n\t\t\t\tchar terminar;\n\t\t\t\tdo {\n\t\t\t\t\tregistrar_evento(events);\n\t\t\t\t\tdo {\n\t\t\t\t\t\tterminar = l.pedir_cad(\"Quieres añadir mas eventos?? S/N\").toUpperCase().charAt(0);\t\n\t\t\t\t\t} while (terminar != 'S' && terminar != 'N' );\n\t\t\t\t} while (terminar != 'N');\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\tsimular_event(events);\n\t\t\t\tbreak;\n\t\t\tcase 3:\n\t\t\t\tflag_txt = generar_informe(events, flag_txt);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\top = menu();\n\t\t}\n\t\tSystem.out.println(\"Cerrando programa...\");\n\t}\n\t\n\t/**\n\t * Generamos la clase de los eventos con sus metodos\n\t * \n\t */\n\n\tstatic class Evento {\n\t\tprivate int cod;\n\t\tprivate String nombre;\n\t\tprivate int num_participantes; //minimo de 3 participantes\n\t\tprivate Atleta[] participantes;\n\t\tprivate String[] medallero;\n\t\tprivate String magnitud; //tiempo, metros, kg, puntos\n\t\tprivate int lim_sup;\n\t\tprivate int lim_inf;\n\t\tprivate boolean ejecucion;\n\t\tprivate boolean informado;\n\t\t\n\t\tEvento(){\n\t\t\tejecucion = true;\n\t\t\tinformado = true;\n\t\t}\n\t\t\n\t\t/**\n\t\t * Valida que la magnitud introducida este dentro de las permitidas, de esta forma nos permite \n\t\t * añadir nuevas magnitudes si metemos nuevos pruebas.\n\t\t * @param magnitudes\n\t\t * @param mag\n\t\t * @return boolean\n\t\t */\n\t\tprivate boolean validar_magnitud(String[] magnitudes, String mag) {\n\t\t\tboolean flag = true;\n\t\t\tfor (int i = 0; i < magnitudes.length && flag == true; i++) {\n\t\t\t\tif(magnitudes[i].equalsIgnoreCase(mag)) {\n\t\t\t\t\tflag = false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn flag;\n\t\t}\n\t\t\n\t\t/**\n\t\t * Registra los datos del evento\n\t\t * @throws IOException\n\t\t */\n\t\tpublic void registrar_evento(ArrayList<Evento> events) throws IOException {\n\t\t\tString[] magnitudes = {\"minutos\", \"segundos\", \"metros\", \"kilogramos\", \"puntos\"};\n\t\t\tLectura l = new Lectura();\n\t\t\tcod = events.size() + 1;\n\t\t\tnombre = l.pedir_cad(\"Introduce el nombre del evento\");\n\t\t\tnum_participantes = l.pedir_entero(\"Introduce la cantidad de participantes en la prueba\", 3, 30);\n\t\t\tparticipantes = new Atleta[num_participantes];\n\t\t\tfor (int i = 0; i < participantes.length; i++) {\n\t\t\t\tAtleta atl = new Atleta();\n\t\t\t\tatl.rellenar();\n\t\t\t\tparticipantes[i] = atl;\n\t\t\t\tSystem.out.println(\"Atleta registrado...\");\n\t\t\t}\n\t\t\tdo {\n\t\t\t\tmagnitud = l.pedir_cad(\"Introduce la magnitud del resultado (minutos, segundos, metros, kilogramos, puntos)\").toLowerCase();\t\t\t\t\n\t\t\t} while (validar_magnitud(magnitudes, magnitud));\n\t\t\tlim_inf = l.pedir_entero(\"Introduce el limite inferior de la magnitud\", 0, 9999999);\n\t\t\tlim_sup = l.pedir_entero(\"Introduce el limite superior de la magnitud\", lim_inf, 9999999);\n\t\t\t\n\t\t}\n\t\t\n\t\t/**\n\t\t * Hace la simulación de forma aleatoria y redondea el double genereado como resultado\n\t\t */\n\t\tpublic void simulacion() {\n\t\t\tif(ejecucion) {\n\t\t\t\tRandom random = new Random();\n\t\t\t\tfor (int i = 0; i < participantes.length; i++) {\n\t\t\t\t\tparticipantes[i].marca = Math.round(random.nextDouble(lim_inf, lim_sup) * 100.0)/100.0;\n\t\t\t\t}\t\n\t\t\t\tejecucion = false;\n\t\t\t}else {\n\t\t\t\tSystem.out.println(\"Este evento ya ha terminado\");\n\t\t\t}\n\t\t}\n\t\t\n\t\t/**\n\t\t * Establece el medallero e imprime por pantalla los resultados según el tipo de prueba que sea.\n\t\t */\n\t\tpublic void est_medallero() {\n\t\t\tArrays.sort(participantes);\n\t\t\tmedallero = new String[3];\n\t\t\tint medalla = 0;\n\t\t\tswitch(magnitud) {\n\t\t\tcase \"metros\", \"kilogramos\", \"puntos\":\n\t\t\t\tfor(int pos = participantes.length -1; pos >= participantes.length - 3; pos--) {\n\t\t\t\t\tif(medalla == 0) {\n\t\t\t\t\t\tmedallero[medalla] = participantes[pos].datos_txt() + \" ---> \" + \"ORO\";\n\t\t\t\t\t} else if(medalla == 1) {\n\t\t\t\t\t\tmedallero[medalla] = participantes[pos].datos_txt() + \" ---> \" + \"PLATA\";\n\t\t\t\t\t}else {\n\t\t\t\t\t\tmedallero[medalla] = participantes[pos].datos_txt() + \" ---> \" + \"BRONCE\";\n\t\t\t\t\t}\n\t\t\t\t\tmedalla++;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"minutos\", \"segundos\":\n\t\t\t\tfor(int pos = 0; pos < 3; pos++) {\n\t\t\t\t\tif(medalla == 0) {\n\t\t\t\t\t\tmedallero[medalla] = participantes[pos].datos_txt() + \" ---> \" + \"ORO\";\n\t\t\t\t\t} else if(medalla == 1) {\n\t\t\t\t\t\tmedallero[medalla] = participantes[pos].datos_txt() + \" ---> \" + \"PLATA\";\n\t\t\t\t\t}else {\n\t\t\t\t\t\tmedallero[medalla] = participantes[pos].datos_txt() + \" ---> \" + \"BRONCE\";\n\t\t\t\t\t}\n\t\t\t\t\tmedalla++;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tfor(String posicion : medallero) {\n\t\t\t\tSystem.out.println(posicion);\n\t\t\t}\n\t\t}\n\t}\n\t\n\t/**\n\t * Clase de atleta que almacena datos del atleta\n\t */\n\tstatic class Atleta implements Comparable<Atleta>{\n\t\tprivate String nombre;\n\t\tprivate String pais;\n\t\tprivate double marca;\n\t\t\n\t\t//metodos\n\t\t//rellena los datos del atleta\n\t\tpublic void rellenar() throws IOException {\n\t\t\tLectura l = new Lectura();\n\t\t\tnombre = l.pedir_cad(\"Introduce el nombre del atleta\");\n\t\t\tpais = l.pedir_cad(\"Introduce el pais del atleta\");\n\t\t}\n\t\t\n\t\t// transforma los datos en un String\n\t\tpublic String datos_txt() {\n\t\t\treturn \"\" + nombre + \" - \" + pais + \" - \" + marca;\n\t\t}\n\t\t\n\t\t/**\n\t\t * Compara un atleta con otro para poder usar el metodo sort de la calse Arrays\n\t\t */\n\t\tpublic int compareTo(Atleta otro) {\n\t\t\treturn Double.compare(marca, otro.marca);\n\t\t}\n\t}\n\t\n\t/**\n\t * Definimos una clase lectura con los metodos para los diferentes tipos de datos.\n\t */\n\tstatic class Lectura{\n\t\tpublic static BufferedReader leer = new BufferedReader(new InputStreamReader(System.in));\n\t\t\n\t\t/**\n\t\t * Metodo en el que pedimos una cadena de texto.\n\t\t * \n\t\t * @param cad\n\t\t * @return cadena introducida por teclado\n\t\t * @throws IOException\n\t\t */\n\t\tpublic String pedir_cad(String cad) throws IOException {\n\t\t\tString c;\n\t\t\tdo {\n\t\t\t\tSystem.out.println(cad);\n\t\t\t\tc = leer.readLine();\n\t\t\t} while (c.isEmpty());\n\t\t\treturn c;\n\t\t}\n\t\t\n\t\t/**\n\t\t * Método con el que pedimos un entero entre un rango concreto\n\t\t * @param cad\n\t\t * @param n1\n\t\t * @param n2\n\t\t * @return\n\t\t * @throws IOException\n\t\t */\n\t\tpublic int pedir_entero(String cad, int n1, int n2) throws IOException {\n\t\t\tint n = n1 - 1;\n\t\t\tdo {\n\t\t\t\ttry {\n\t\t\t\t\tSystem.out.println(cad);\n\t\t\t\t\tn=Integer.parseInt(leer.readLine());\n\t\t\t\t}catch (NumberFormatException e) {\n\t\t\t\t\tSystem.out.println(\"Solo valores numericos\");\n\t\t\t\t}\n\t\t\t} while (n < n1 || n > n2);\n\t\t\t\n\t\t\treturn n;\n\t\t}\n\t}\n\n}\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/java/alb-martinez.java",
    "content": "import java.util.*;\n\npublic class almartinez {\n\n    private static final List<Event> events = new ArrayList<>();\n    private static final Map<String, EnumMap<MedalType, Integer>> medalsByCountry = new HashMap<>();\n\n    public static void main(String[] args) {\n\n        Scanner scanner = new Scanner(System.in);\n        boolean exit = false;\n\n        while (!exit) {\n            displayMenu();\n            int option = getOption(scanner);\n\n            switch (option) {\n                case 1 -> registerEvent(scanner);\n                case 2 -> registerParticipant(scanner);\n                case 3 -> simulateEvents();\n                case 4 -> displayRanking();\n                case 5 -> exit = true;\n                default -> System.out.println(\"Invalid option.\");\n            }\n        }\n\n        scanner.close();\n    }\n\n    private static void displayMenu() {\n        System.out.println(\"\\nSelect an action:\");\n        System.out.println(\"1. Register event\");\n        System.out.println(\"2. Register participant\");\n        System.out.println(\"3. Simulate events\");\n        System.out.println(\"4. Create reports\");\n        System.out.println(\"5. exit\");\n    }\n\n    private static int getOption(Scanner scanner) {\n        while (!scanner.hasNextInt()) {\n            System.out.println(\"Please enter a valid number.\");\n            scanner.next();\n        }\n        int option = scanner.nextInt();\n        scanner.nextLine();\n        return option;\n    }\n\n    private static void registerEvent(Scanner scanner) {\n        System.out.println(\"Enter the event name: \");\n        String eventName = scanner.nextLine();\n        events.add(new Event(eventName));\n        System.out.println(\"Event registered: \" + eventName);\n    }\n\n    private static void registerParticipant(Scanner scanner) {\n        if (events.isEmpty()) {\n            System.out.println(\"No events registered. Plase register an event first\");\n            return;\n        }\n\n        System.out.println(\"Enter the participant's name: \");\n        String participantName = scanner.nextLine();\n\n        System.out.println(\"Enter the participant's country: \");\n        String participantCountry = scanner.nextLine();\n\n        Participant participan = new Participant(participantName, participantCountry);\n        displayEvents();\n        int eventIndex = getEventIndex(scanner);\n\n        if (eventIndex == -1) return;\n\n        events.get(eventIndex).addParticipant(participan);\n        medalsByCountry.putIfAbsent(participantCountry, new EnumMap<>(MedalType.class));\n        System.out.println(\"Participant registered: \" + participantName + \" from \" + participantCountry);\n    }\n\n    private static void simulateEvents() {\n        for (Event event : events) {\n            System.out.println(\"Simulating event: \" + event.name);\n\n            if (event.participants.size() < 3) {\n                System.out.println(\"Not enough participants to simulate this event.\");\n                continue;\n            }\n\n            List<Participant> winners = simulateEvent(event);\n            assignMedals(winners);\n            displayWinners(event, winners);\n        }\n    }\n\n    private static void displayEvents() {\n        System.out.println(\"Available events:\");\n        for (int i = 0; i < events.size(); i++) {\n            System.out.println(i + \": \" + events.get(i).name);\n        }\n    }\n\n    private static int getEventIndex(Scanner scanner) {\n        System.out.println(\"Select the event (0-\" + (events.size() -1) + \"): \");\n        while (!scanner.hasNextInt()) {\n            System.out.println(\"Please enter a valid number.\");\n            scanner.next();\n        }\n        int eventIndex = scanner.nextInt();\n\n        if (eventIndex < 0 || eventIndex >= events.size()) {\n            System.out.println(\"Invalid event.\");\n            return -1;\n        }\n        return eventIndex;\n    }\n    private static List<Participant> simulateEvent(Event event) {\n        Collections.shuffle(event.participants);\n        return event.participants.subList(0, 3);\n    }\n\n    private static void assignMedals(List<Participant> winners) {\n        awardMedal(winners.get(0), MedalType.GOLD);\n        awardMedal(winners.get(1), MedalType.SILVER);\n        awardMedal(winners.get(2), MedalType.BRONZE);\n    }\n\n    private static void awardMedal(Participant participant, MedalType medalType) {\n        EnumMap<MedalType, Integer> medals = medalsByCountry.get(participant.country);\n        medals.put(medalType, medals.getOrDefault(medalType, 0) + 1);\n    }\n\n    private static void displayWinners(Event event, List<Participant> winners) {\n        System.out.println(\"Winners of \" + event.name + \":\");\n        System.out.println(\"Gold: \" + winners.get(0).name + \" from \" + winners.get(0).country);\n        System.out.println(\"Silver: \" + winners.get(1).name + \" from \" + winners.get(1).country);\n        System.out.println(\"Bronze: \" + winners.get(2).name + \" from \" + winners.get(2).country);\n    }\n\n    private static void displayRanking() {\n        System.out.println(\"\\nRanking of countries by number of medals:\");\n        medalsByCountry.entrySet().stream()\n                .sorted((a, b) -> {\n                   int totalA = a.getValue().values().stream().mapToInt(Integer::intValue).sum();\n                   int totalB = b.getValue().values().stream().mapToInt(Integer::intValue).sum();\n                   return Integer.compare(totalB, totalA);\n                })\n                .forEach(entry -> {\n                    String country = entry.getKey();\n                    EnumMap<MedalType, Integer> medals = entry.getValue();\n                    System.out.printf(\"%s: Gold=%d, Silver=%d, Bronze=%d%n\",\n                            country,\n                            medals.getOrDefault(MedalType.GOLD, 0),\n                            medals.getOrDefault(MedalType.SILVER, 0),\n                            medals.getOrDefault(MedalType.BRONZE, 0));\n                });\n    }\n\n    enum MedalType {\n        GOLD, SILVER, BRONZE\n    }\n\n    static class Participant {\n        String name;\n        String country;\n\n        public Participant(String name, String country) {\n            this.name = name;\n            this.country = country;\n        }\n    }\n\n    static class Event {\n        String name;\n        List<Participant> participants = new ArrayList<>();\n\n        public Event(String name) {\n            this.name = name;\n        }\n\n        void addParticipant(Participant participant) {\n            participants.add(participant);\n        }\n    }\n\n\n}\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/java/asjordi.java",
    "content": "import net.datafaker.Faker;\nimport java.util.*;\n\npublic class Main {\n\n    public static void main(String[] args) {\n        Faker faker = new Faker(); // Generador de datos falsos\n\n        AdministradorEventos admin = new AdministradorEventos();\n        Evento atletismo100MM = new Evento(\"Atletismo 100 metros masculino\");\n        Evento atletismo100MF = new Evento(\"Atletismo 100 metros femenino\");\n\n        Participante p1 = new Participante(faker.name().fullName(), faker.address().country());\n        Participante p2 = new Participante(faker.name().fullName(), faker.address().country());\n        Participante p3 = new Participante(faker.name().fullName(), faker.address().country());\n        Participante p4 = new Participante(faker.name().fullName(), faker.address().country());\n        Participante p5 = new Participante(faker.name().fullName(), faker.address().country());\n        Participante p6 = new Participante(faker.name().fullName(), faker.address().country());\n        Participante p7 = new Participante(faker.name().fullName(), faker.address().country());\n        Participante p8 = new Participante(faker.name().fullName(), faker.address().country());\n        Participante p9 = new Participante(faker.name().fullName(), faker.address().country());\n        Participante p10 = new Participante(faker.name().fullName(), faker.address().country());\n\n        atletismo100MM.agregarParticipante(p1);\n        atletismo100MM.agregarParticipante(p2);\n        atletismo100MM.agregarParticipante(p3);\n        atletismo100MM.agregarParticipante(p4);\n        atletismo100MM.agregarParticipante(p5);\n        atletismo100MM.agregarParticipante(p6);\n        atletismo100MM.agregarParticipante(p7);\n\n        atletismo100MF.agregarParticipante(p8);\n        atletismo100MF.agregarParticipante(p9);\n        atletismo100MF.agregarParticipante(p10);\n        atletismo100MF.agregarParticipante(p1);\n        atletismo100MF.agregarParticipante(p2);\n        atletismo100MF.agregarParticipante(p3);\n        atletismo100MF.agregarParticipante(p4);\n\n        admin.agregarEvento(atletismo100MM);\n        admin.agregarEvento(atletismo100MF);\n\n        admin.iniciarEventos();\n        admin.mostrarRankingGeneralEventos();\n        admin.mostrarRankingPorPais();\n    }\n\n    static class AdministradorEventos {\n        private List<Evento> eventos;\n\n        public AdministradorEventos() {\n            this.eventos = new LinkedList<>();\n        }\n\n        public void iniciarEventos() {\n            this.eventos.forEach(Evento::iniciarEvento);\n        }\n\n        public void agregarEvento(Evento evento) {\n            this.eventos.add(evento);\n        }\n\n        public void mostrarRankingGeneralEventos() {\n            this.eventos.forEach(Evento::mostrarRanking);\n        }\n\n        public void mostrarRankingPorPais() {\n            Map<String, Integer> ranking = new HashMap<>();\n            this.eventos.forEach(e -> e.getRanking().forEach(p -> {\n                if (ranking.containsKey(p.getPais())) ranking.put(p.getPais(), ranking.get(p.getPais()) + 1);\n                else ranking.put(p.getPais(), 1);\n            }));\n\n            System.out.println(\"Ranking por país\");\n            ranking.forEach((k, v) -> System.out.println(\"Pais: \" + k + \" - Cantidad de medallas: \" + v));\n        }\n    }\n\n    static class Evento {\n        private String nombre;\n        private List<Participante> participantes;\n        private List<Participante> ranking;\n        private final Random r;\n\n        public Evento(String nombre) {\n            this.nombre = nombre;\n            this.participantes = new LinkedList<>();\n            this.ranking = new LinkedList<>();\n            this.r = new Random();\n        }\n\n        public void agregarParticipante(Participante participante) {\n            this.participantes.add(participante);\n        }\n\n        public void mostrarParticipantes() {\n            this.participantes.forEach(p -> System.out.println(\"Nombre: \" + p.getNombre() + \" - País: \" + p.getPais()));\n        }\n\n        public int cantidadParticipantes() {\n            return this.participantes.size();\n        }\n\n        public void iniciarEvento() {\n            System.out.println(\"Iniciando evento: \" + this.nombre);\n\n            while (this.ranking.size() != 3) {\n                int index = r.nextInt(this.participantes.size());\n                Participante p = this.participantes.get(index);\n                if (!this.ranking.contains(p)) this.ranking.add(p);\n            }\n\n            System.out.println(\"Evento finalizado\");\n        }\n\n        public void mostrarRanking() {\n            System.out.println(\"Ranking del evento: \" + this.nombre);\n            System.out.println(\"1er lugar: \" + this.ranking.get(0).getNombre() + \" - País: \" + this.ranking.get(0).getPais());\n            System.out.println(\"2do lugar: \" + this.ranking.get(1).getNombre() + \" - País: \" + this.ranking.get(1).getPais());\n            System.out.println(\"3er lugar: \" + this.ranking.get(2).getNombre() + \" - País: \" + this.ranking.get(2).getPais());\n        }\n\n        public String getNombre() {\n            return nombre;\n        }\n\n        public List<Participante> getRanking() {\n            return ranking;\n        }\n    }\n\n    static class Participante {\n        private String nombre;\n        private String pais;\n\n        public Participante(String nombre, String pais) {\n            this.nombre = nombre;\n            this.pais = pais;\n        }\n\n        public String getNombre() {\n            return nombre;\n        }\n\n        public String getPais() {\n            return pais;\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/java/danhingar.java",
    "content": "import java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.LinkedHashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Scanner;\nimport java.util.stream.Collectors;\n\npublic class danhingar {\n\n    public static void main(String[] args) {\n\n        simulateGame();\n\n    }\n\n    public static void simulateGame() {\n        System.out.println(\"Simulador de Juegos Olimpicos\");\n        Olympics olympics = new Olympics();\n\n        while (Boolean.TRUE) {\n            System.out.println();\n            String options = \"\"\"\n                    1. Registro de eventos.\n                    2. Registro de participantes.\n                    3. Simulación de eventos.\n                    4. Creación de informes.\n                    5. Salir.\"\"\";\n            System.out.println(options);\n            System.out.print(\"Selecciona una opción: \");\n            Scanner sc = new Scanner(System.in);\n            String option = sc.nextLine();\n            switch (option) {\n                case \"1\":\n                    olympics.registerEvent();\n                    break;\n                case \"2\":\n                    olympics.registerParticipant();\n                    break;\n                case \"3\":\n                    olympics.simulateEvents();\n                    break;\n                case \"4\":\n                    olympics.showReport();\n                    break;\n                case \"5\":\n                    System.out.println(\"Saliendo del simulador...\");\n                    sc.close();\n                    System.exit(0);\n                    break;\n\n                default:\n                    System.out.println(\"Opción no válida\");\n                    break;\n            }\n        }\n\n    }\n\n}\n\nclass Participant {\n    private String name;\n    private String country;\n\n    public Participant(String name, String country) {\n        this.name = name;\n        this.country = country;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public String getCountry() {\n        return country;\n    }\n\n    public void setCountry(String country) {\n        this.country = country;\n    }\n}\n\nclass Event {\n    private String category;\n    private List<Participant> participants;\n\n    public Event(String category) {\n        this.category = category;\n        this.participants = new ArrayList<>();\n    }\n\n    public String getCategory() {\n        return category;\n    }\n\n    public void setCategory(String category) {\n        this.category = category;\n    }\n\n    public List<Participant> getParticipants() {\n        return participants;\n    }\n\n    public void setParticipants(List<Participant> participants) {\n        this.participants = participants;\n    }\n}\n\ninterface EventInterface {\n\n    List<Participant> simulate(Event event);\n\n    Map<String, Participant> getPodium(Event event);\n\n    void registerParticipantInEvent(Event event, Participant participant);\n\n}\n\nclass EventService implements EventInterface {\n\n    @Override\n    public List<Participant> simulate(Event event) {\n        Collections.shuffle(event.getParticipants());\n        return event.getParticipants();\n\n    }\n\n    @Override\n    public Map<String, Participant> getPodium(Event event) {\n        return Map.of(\"gold\", event.getParticipants().get(0), \"silver\", event.getParticipants().get(1), \"bronze\",\n                event.getParticipants().get(2));\n    }\n\n    @Override\n    public void registerParticipantInEvent(Event event, Participant participant) {\n        event.getParticipants().add(participant);\n    }\n\n}\n\nclass Olympics {\n\n    private List<Event> events;\n    private EventService eventService;\n    private Map<String, Map<String, Integer>> countryResults;\n    private Map<Event, List<Participant>> eventResults;\n\n    public Olympics() {\n        this.events = new ArrayList<>();\n        this.countryResults = new HashMap<>();\n        this.eventResults = new HashMap<>();\n        this.eventService = new EventService();\n    }\n\n    public void registerEvent() {\n\n        System.out.print(\"Introduce la categoría del evento: \");\n        Scanner sc = new Scanner(System.in);\n        String category = sc.nextLine().trim();\n        Event event = new Event(category);\n        if (events.contains(event)) {\n            System.out.printf(String.format(\"El evento %s ya está registrado.\\n\", category));\n        } else {\n            events.add(event);\n        }\n        System.out.printf(String.format(\"Evento %s registrado correctamente.\\n\", category));\n    }\n\n    public void registerParticipant() {\n        if (events.isEmpty()) {\n            System.out.println(\"No hay eventos registrados. Registre uno primero.\");\n        } else {\n\n            System.out.print(\"Introduce el nombre del participante: \");\n            Scanner sc = new Scanner(System.in);\n            String name = sc.nextLine().trim();\n            System.out.print(\"Introduce el país del participante: \");\n            String country = sc.nextLine().trim();\n\n            Participant participant = new Participant(name, country);\n\n            System.out.println(\"Eventos disponibles:\");\n            for (int i = 0; i < events.size(); i++) {\n                System.out.println(i + 1 + \". \" + events.get(i).getCategory());\n            }\n\n            System.out.print(\"Selecciona el número del evento para asignar al participante: \");\n            Integer index = sc.nextInt() - 1;\n\n            if (index < 0 || index > events.size()) {\n                System.out.println(\"Selección del evento deportivo inválido. El participante no se ha registrado.\");\n            } else {\n\n                Event event = events.get(index);\n                if (event.getParticipants().contains(participant)) {\n                    System.out.printf(\"El participante %s de %s ya está registrado en el evento deportivo %s.\\n\",\n                            participant.getName(), participant.getCountry(), event.getCategory());\n                } else {\n                    eventService.registerParticipantInEvent(event, participant);\n                    System.out.printf(\"El participante %s de %s se ha registrado en el evento deportivo %s.\\n\",\n                            participant.getName(), participant.getCountry(), event.getCategory());\n                }\n            }\n        }\n    }\n\n    public void simulateEvents() {\n        if (events.isEmpty()) {\n            System.out.println(\"No hay eventos registrados.\");\n        } else {\n            for (Event event : events) {\n                if (event.getParticipants().size() < 3) {\n                    System.out.println(\n                            \"No hay participantes suficientes para simular el evento \" + event.getCategory()\n                                    + \" (mínimo 3).\");\n                    return;\n                }\n                eventService.simulate(event);\n                Map<String, Participant> result = eventService.getPodium(event);\n\n                eventResults.put(event, List.of(result.get(\"gold\"), result.get(\"silver\"), result.get(\"bronze\")));\n\n                updateCountryResult(\"gold\", result.get(\"gold\").getCountry());\n                updateCountryResult(\"silver\", result.get(\"silver\").getCountry());\n                updateCountryResult(\"bronze\", result.get(\"bronze\").getCountry());\n\n                System.out.printf(\"\"\"\n                        Resultados simulación del evento: %s\n                        Oro: %s (%s)\n                        Plata: %s (%s)\n                        Bronce: %s (%s)\\n\"\"\",\n                        event.getCategory(), result.get(\"gold\").getName(), result.get(\"gold\").getCountry(),\n                        result.get(\"silver\").getName(), result.get(\"silver\").getCountry(),\n                        result.get(\"bronze\").getName(), result.get(\"bronze\").getCountry());\n            }\n        }\n    }\n\n    public void showReport() {\n\n        System.out.println(\"Informe Juegos Olímpicos:\");\n\n        for (Event event : eventResults.keySet()) {\n            System.out.printf(\"\"\"\n                    Evento: %s\n                    Oro: %s (%s)\n                    Plata: %s (%s)\n                    Bronce: %s (%s)\\n\"\"\",\n                    event.getCategory(), eventResults.get(event).get(0).getName(),\n                    eventResults.get(event).get(0).getCountry(),\n                    eventResults.get(event).get(1).getName(), eventResults.get(event).get(1).getCountry(),\n                    eventResults.get(event).get(2).getName(), eventResults.get(event).get(2).getCountry());\n        }\n\n        if (!countryResults.isEmpty()) {\n            Map<String, Map<String, Integer>> sortedResults = countryResults.entrySet()\n                    .stream()\n                    .sorted((entry1, entry2) -> {\n                        Map<String, Integer> medals1 = entry1.getValue();\n                        Map<String, Integer> medals2 = entry2.getValue();\n\n                        int compareOro = Integer.compare(medals2.get(\"gold\"), medals1.get(\"gold\"));\n                        if (compareOro != 0)\n                            return compareOro;\n\n                        int comparePlata = Integer.compare(medals2.get(\"silver\"), medals1.get(\"silver\"));\n                        if (comparePlata != 0)\n                            return comparePlata;\n\n                        return Integer.compare(medals2.get(\"bronze\"), medals1.get(\"bronze\"));\n                    })\n                    .collect(Collectors.toMap(\n                            Map.Entry::getKey,\n                            Map.Entry::getValue,\n                            (e1, e2) -> e1,\n                            LinkedHashMap::new));\n            for (String country : sortedResults.keySet()) {\n                System.out.printf(\"\"\"\n                        País: %s Oro %s, Plata: %s, Bronce %s\\n\"\"\",\n                        country, countryResults.get(country).get(\"gold\"),\n                        countryResults.get(country).get(\"silver\"),\n                        countryResults.get(country).get(\"bronze\"));\n            }\n        } else {\n            System.out.println(\"No hay medallas por país registradas\");\n        }\n\n    }\n\n    public void updateCountryResult(String medal, String country) {\n        countryResults.putIfAbsent(country, new HashMap<>(Map.of(\"gold\", 0, \"silver\", 0, \"bronze\", 0)));\n\n        Map<String, Integer> countryMedals = countryResults.get(country);\n        countryMedals.put(medal, countryMedals.get(medal) + 1);\n    }\n\n}"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/java/martinbohorquez.java",
    "content": "import java.util.*;\nimport java.util.concurrent.atomic.AtomicInteger;\n\n/**\n * #31 SIMULADOR JUEGOS OLÍMPICOS\n *\n * @author martinbohorquez\n */\npublic class martinbohorquez {\n    private static final Scanner sc = new Scanner(System.in);\n    private static boolean flag = true;\n\n    public static void main(String[] args) {\n        String option;\n        while (flag) {\n            option = menuOptions();\n            switch (option) {\n                case \"1\" -> Olympic.registerEvent();\n                case \"2\" -> Olympic.registerCompetitor();\n                case \"3\" -> Olympic.simulateEvents();\n                case \"4\" -> {\n                    Olympic.displayWinners();\n                    Olympic.displayRankingByCountries();\n                }\n                case \"5\" -> {\n                    System.out.println(\"Saliendo del programa...!\");\n                    flag = false;\n                }\n                default -> System.out.printf(\"Opción '%s' no valida! Ingresar una opción del 1 al 5.%n\", option);\n            }\n        }\n    }\n\n    /*\n     *  Requisitos:\n     *  1. Registrar eventos deportivos.\n     *  2. Registrar participantes por nombre y país.\n     *  3. Simular eventos de manera aleatoria en base a los participantes (mínimo 3).\n     *  4. Asignar medallas (oro, plata y bronce) basándose en el resultado del evento.\n     *  5. Mostrar los ganadores por cada evento.\n     *  6. Mostrar el ranking de países según el número de medallas.\n     */\n    private static String menuOptions() {\n        System.out.printf(\"%n<--- BIENVENIDO AL MENU \\\"JJOO PARIS 2024\\\" --->%n\");\n        System.out.println(\"\"\"\n                ------------------------------------------------\n                Usted cuenta con las siguientes opciones:\n                1. Registro de eventos.\n                2. Registro de participantes.\n                3. Simulación de eventos.\n                4. Creación de informes.\n                5. Salir del programa.\n                \"\"\");\n        System.out.print(\"Ingresar su número opción del menú (1, 2, 3, 4, 5): \");\n        return sc.nextLine();\n    }\n\n    static class Competitor {\n        String name;\n        String country;\n\n        public Competitor(String name, String country) {\n            this.name = name;\n            this.country = country;\n        }\n\n        public String getName() {\n            return name;\n        }\n\n        public String getCountry() {\n            return country;\n        }\n\n        @Override\n        public boolean equals(Object object) {\n            if (this == object) return true;\n            if (object == null || getClass() != object.getClass()) return false;\n            Competitor that = (Competitor) object;\n            return Objects.equals(name, that.name) && Objects.equals(country, that.country);\n        }\n\n        @Override\n        public int hashCode() {\n            return Objects.hash(name, country);\n        }\n\n        @Override\n        public String toString() {\n            return \"{name= '\" + name + \"', country= '\" + country + \"'}\";\n        }\n    }\n\n    static class CountryRank {\n        private String country;\n        private Map<Medal, Integer> medals;\n\n        public CountryRank(String country) {\n            this.country = country;\n            medals = new LinkedHashMap<>();\n            medals.put(Medal.GOLD, 0);\n            medals.put(Medal.SILVER, 0);\n            medals.put(Medal.BRONZE, 0);\n        }\n\n        public String getCountry() {\n            return country;\n        }\n\n        public void setCountry(String country) {\n            this.country = country;\n        }\n\n        public Map<Medal, Integer> getMedals() {\n            return medals;\n        }\n\n        public void setMedals(Map<Medal, Integer> medals) {\n            this.medals = medals;\n        }\n\n        @Override\n        public String toString() {\n            return \"{country= '\" + country + \"', medals= '\" + medals + \"'}\";\n        }\n    }\n\n    enum Medal {\n        GOLD, SILVER, BRONZE\n    }\n\n    static class EventCompetitor {\n        private String event;\n        private List<Competitor> competitors;\n\n        public EventCompetitor(String event) {\n            this.event = event;\n            competitors = new LinkedList<>();\n        }\n\n        public String getEvent() {\n            return event;\n        }\n\n        public void setEvent(String event) {\n            this.event = event;\n        }\n\n        public List<Competitor> getCompetitors() {\n            return competitors;\n        }\n\n        public void setCompetitors(List<Competitor> competitors) {\n            this.competitors = competitors;\n        }\n\n        private void printWinner() {\n            System.out.printf(\"{event= '%s', competitor= '%s'}%n\", event, competitors.getFirst());\n        }\n\n        @Override\n        public String toString() {\n            return \"{event='\" + event + \"', competitors=\" + competitors + \"}\";\n        }\n    }\n\n    private static class Olympic {\n        static List<EventCompetitor> events = new LinkedList<>();\n        static List<CountryRank> countriesRank = new LinkedList<>();\n\n        private static void registerEvent() {\n            System.out.print(\"Indicar el evento a registrar: \");\n            String event = sc.nextLine().strip();\n\n            if (event.isBlank())\n                System.out.printf(\"El nombre del evento '%s' no debe estar en espacio en blanco!%n\", event);\n            else if (!events.isEmpty() && events.stream().anyMatch(e -> e.getEvent().equals(event)))\n                System.out.printf(\"El evento '%s' ya se encuentra registrado!%n\", event);\n            else {\n                EventCompetitor eventCompetitor = new EventCompetitor(event);\n                events.add(eventCompetitor);\n                System.out.printf(\"El evento '%s' registrado exitosamente!%n\", event);\n            }\n        }\n\n        private static void registerCompetitor() {\n            if (events.isEmpty()) {\n                System.out.println(\"No hay eventos registrados. Por favor, registra uno primero!\");\n                return;\n            }\n\n            System.out.println(\"Indicar los datos del competidor a registrar.\");\n            System.out.print(\"nombre: \");\n            String name = sc.nextLine().strip();\n            System.out.print(\"país: \");\n            String country = sc.nextLine().strip();\n            Competitor competitor = new Competitor(name, country);\n\n            System.out.println(\"Eventos deportivos disponibles:\");\n            AtomicInteger index = new AtomicInteger(0);\n            events.forEach(e -> System.out.printf(\"%d. %s%n\", index.incrementAndGet(), e.getEvent()));\n\n            System.out.println(\"Selecciona el número del evento para asignar al participante: \");\n            int eventIndex = Integer.parseInt(sc.nextLine()) - 1;\n\n            if (eventIndex >= 0 && eventIndex < events.size()) {\n                EventCompetitor eventCompetitor = events.get(eventIndex);\n                String event = eventCompetitor.getEvent();\n                List<Competitor> competitors = eventCompetitor.getCompetitors();\n\n                competitors.stream().filter(c -> c.equals(competitor))\n                        .findFirst()\n                        .ifPresentOrElse(c -> System.out.printf(\"El participante '%s' de '%s' ya está registrado en el evento deportivo '%s'.%n\",\n                                        c.getName(), c.getCountry(), event),\n                                () -> {\n                                    if (countriesRank.stream().noneMatch(cr -> cr.getCountry().equals(country))) {\n                                        countriesRank.add(new CountryRank(country));\n                                    }\n                                    competitors.add(competitor);\n                                    System.out.printf(\"El participante '%s' de '%s' se ha registrado en el evento deportivo '%s'.%n\",\n                                            name, country, event);\n                                });\n            } else System.out.println(\"Selección de evento deportivo inválido. El participante no se ha registrado!\");\n        }\n\n        private static void simulateEvents() {\n            if (events.isEmpty()) {\n                System.out.println(\"No hay eventos registrados. Por favor, registra uno primero!\");\n                return;\n            }\n            events.forEach(ec -> {\n                List<Competitor> competitors = ec.getCompetitors();\n                if (competitors.size() < 3)\n                    System.out.printf(\"%nNo hay participantes suficientes para simular el evento '%s' (mínimo 3).%n\", ec.getEvent());\n                else {\n                    Collections.shuffle(competitors);\n                    List<Competitor> rankCompetitor = competitors.subList(0, 3);\n\n                    updateRankingByCountries(competitors);\n\n                    System.out.printf(\"%nResultados de la simulación del evento '%s':%n\", ec.getEvent());\n\n                    System.out.printf(\"Oro: %s%n\", rankCompetitor.getFirst());\n                    System.out.printf(\"Plata: %s%n\", rankCompetitor.get(1));\n                    System.out.printf(\"Bronce: %s%n\", rankCompetitor.get(2));\n                }\n            });\n        }\n\n        private static void updateRankingByCountries(List<Competitor> competitors) {\n            for (Competitor c : competitors) {\n                String country = c.getCountry();\n                int index = competitors.indexOf(c);\n                switch (index) {\n                    case 0 -> assignMedal(country, Medal.GOLD);\n                    case 1 -> assignMedal(country, Medal.SILVER);\n                    case 2 -> assignMedal(country, Medal.BRONZE);\n                }\n            }\n        }\n\n        private static void assignMedal(String country, Medal medal) {\n            countriesRank.stream().filter(cr -> cr.getCountry().equals(country))\n                    .findFirst()\n                    .ifPresent(cr -> cr.getMedals().put(medal,\n                            cr.getMedals().get(medal) + 1));\n        }\n\n        private static void displayWinners() {\n            System.out.printf(\"%nReporte de ganadores por evento:%n\");\n            events.stream().filter(ec -> ec.getCompetitors().size() >= 3)\n                    .forEach(EventCompetitor::printWinner);\n            events.stream().filter(ec -> ec.getCompetitors().size() < 3)\n                    .forEach(ec -> System.out.printf(\"No hay resultado de simulación del evento '%s' \" +\n                            \"(mínimo 3 participantes).%n\", ec.getEvent()));\n        }\n\n        private static void displayRankingByCountries() {\n            System.out.printf(\"%nReporte de medallas (Oro, Plata, Bronce) obtenidas por país:%n\");\n            countriesRank.forEach(System.out::println);\n        }\n\n    }\n}\n\n/*\n * 1\n * Natacion\n * 1\n * Salto largo\n * 1\n * Salto alto\n * 1\n * 100 metros planos\n * 1\n * Lanzamiento de bala\n * 1\n * Lanzamiento de jabilina\n * 2\n * Martin\n * Peru\n * 1\n * 2\n * Martin\n * Peru\n * 2\n * 2\n * Martin\n * Peru\n * 3\n * 2\n * Martin\n * Peru\n * 4\n * 2\n * Martin\n * Peru\n * 5\n * 2\n * Kath\n * Colombia\n * 1\n * 2\n * Kath\n * Colombia\n * 2\n * 2\n * Kath\n * Colombia\n * 3\n * 2\n * Kath\n * Colombia\n * 4\n * 2\n * Kath\n * Colombia\n * 6\n * 2\n * Piero\n * Peru\n * 1\n * 2\n * Piero\n * Peru\n * 2\n * 2\n * Piero\n * Peru\n * 4\n * 2\n * Piero\n * Peru\n * 6\n * 2\n * Marshall\n * Canada\n * 1\n * 2\n * Marshall\n * Canada\n * 2\n * 2\n * Marshall\n * Canada\n * 3\n * 2\n * Marshall\n * Canada\n * 6\n * 2\n * Kendall\n * Chile\n * 2\n * 2\n * Kendall\n * Chile\n * 4\n * 2\n * Kendall\n * Chile\n * 5\n */"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/java/sisaroot.java",
    "content": "// #31 SIMULADOR JUEGOS OLÍMPICOS - SisaRoot\n\nimport java.util.*;\nimport java.util.stream.*;\n\npublic class SisaRoot {\n\n    record Participant(String name, String country) {}\n\n    static class Event {\n        String name;\n        List<Participant> participants = new ArrayList<>();\n        Event(String name) { this.name = name; }\n    }\n\n    static class CountryMedals {\n        String country; int gold, silver, bronze;\n        CountryMedals(String c) { country = c; }\n        int total() { return gold + silver + bronze; }\n    }\n\n    private final List<Event> events = new ArrayList<>();\n    private final Map<String, CountryMedals> medalTable = new LinkedHashMap<>();\n    private final Scanner scanner = new Scanner(System.in);\n    private final Random rng = new Random();\n\n    void registerEvent() {\n        System.out.print(\"Nombre del evento: \");\n        String name = scanner.nextLine().trim();\n        if (name.isEmpty()) { System.out.println(\"Invalido.\"); return; }\n        if (events.stream().anyMatch(e -> e.name.equalsIgnoreCase(name)))\n        { System.out.println(\"Ya existe.\"); return; }\n        events.add(new Event(name));\n        System.out.println(\"Evento '\" + name + \"' registrado.\");\n    }\n\n    void registerParticipant() {\n        if (events.isEmpty()) { System.out.println(\"No hay eventos.\"); return; }\n        for (int i=0; i<events.size(); i++) System.out.println(\"  \"+(i+1)+\". \"+events.get(i).name);\n        System.out.print(\"Selecciona numero: \");\n        int idx; try { idx = Integer.parseInt(scanner.nextLine().trim()); } catch (Exception e) { System.out.println(\"Invalido.\"); return; }\n        if (idx<1 || idx>events.size()) { System.out.println(\"Invalido.\"); return; }\n        var ev = events.get(idx-1);\n        System.out.print(\"Nombre: \"); String pname = scanner.nextLine().trim();\n        System.out.print(\"Pais: \");   String country = scanner.nextLine().trim();\n        ev.participants.add(new Participant(pname, country));\n        System.out.println(\"'\" + pname + \" (\" + country + \")' añadido a '\" + ev.name + \"'.\");\n    }\n\n    void simulateEvents() {\n        if (events.isEmpty()) { System.out.println(\"No hay eventos.\"); return; }\n        for (var ev : events) {\n            System.out.println(\"\\n=== Simulando: \" + ev.name + \" ===\");\n            if (ev.participants.size() < 3) { System.out.println(\"  Necesita >=3. Saltando.\"); continue; }\n            var s = new ArrayList<>(ev.participants);\n            Collections.shuffle(s, rng);\n            System.out.println(\"  🥇 Oro:    \" + s.get(0).name() + \" (\" + s.get(0).country() + \")\");\n            System.out.println(\"  🥈 Plata:  \" + s.get(1).name() + \" (\" + s.get(1).country() + \")\");\n            System.out.println(\"  🥉 Bronce: \" + s.get(2).name() + \" (\" + s.get(2).country() + \")\");\n            addMedal(s.get(0).country(), \"gold\"); addMedal(s.get(1).country(), \"silver\"); addMedal(s.get(2).country(), \"bronze\");\n        }\n    }\n\n    void addMedal(String country, String type) {\n        medalTable.putIfAbsent(country, new CountryMedals(country));\n        var cm = medalTable.get(country);\n        switch (type) { case \"gold\" -> cm.gold++; case \"silver\" -> cm.silver++; default -> cm.bronze++; }\n    }\n\n    void showReport() {\n        System.out.println(\"\\n== INFORME FINAL ==\");\n        if (medalTable.isEmpty()) { System.out.println(\"Sin resultados.\"); return; }\n        var ranking = new ArrayList<>(medalTable.values());\n        ranking.sort((a,b) -> b.gold!=a.gold ? b.gold-a.gold : b.silver!=a.silver ? b.silver-a.silver : b.bronze-a.bronze);\n        for (int i=0; i<ranking.size(); i++) {\n            var c = ranking.get(i);\n            System.out.printf(\"%d. %-20s Oro:%d Plata:%d Bronce:%d Total:%d%n\", i+1, c.country, c.gold, c.silver, c.bronze, c.total());\n        }\n    }\n\n    void run() {\n        while (true) {\n            System.out.println(\"\\n====== SIMULADOR JJOO ======\\n1. Registrar evento\\n2. Registrar participante\\n3. Simular\\n4. Informe\\n5. Salir\");\n            System.out.print(\"Opcion: \");\n            switch (scanner.nextLine().trim()) {\n                case \"1\" -> registerEvent(); case \"2\" -> registerParticipant();\n                case \"3\" -> simulateEvents(); case \"4\" -> showReport();\n                case \"5\" -> { System.out.println(\"Hasta luego!\"); return; }\n                default -> System.out.println(\"Invalido.\");\n            }\n        }\n    }\n\n    public static void main(String[] args) { new SisaRoot().run(); }\n}\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/javascript/DavidMoralesDeveloper.js",
    "content": "// EJERCICIO:\n//  * ¡Los JJOO de París 2024 han comenzado!\n//  * Crea un programa que simule la celebración de los juegos.\n//  * El programa debe permitir al usuario registrar eventos y participantes,\n//  * realizar la simulación de los eventos asignando posiciones de manera aleatoria\n//  * y generar un informe final. Todo ello por terminal.\n//  * Requisitos:\n//  * 1. Registrar eventos deportivos. listo\n//  * 2. Registrar participantes por nombre y país. Listo\n//  * 3. Simular eventos de manera aleatoria en base a los participantes (mínimo 3). listo \n//  * 4. Asignar medallas (oro, plata y bronce) basándose en el resultado del evento.listo + sin medalla\n//  * 5. Mostrar los ganadores por cada evento. listo\n//  * 6. Mostrar el ranking de países según el número de medallas.\n//  * Acciones:\n//  * 1. Registro de eventos.\n//  * 2. Registro de participantes.\n//  * 3. Simulación de eventos.\n//  * 4. Creación de informes.\n//  * 5. Salir del programa.\n\nconst readline = require('readline');\n const rl = readline.createInterface({\n        input: process.stdin, // For user input from the console\n        output: process.stdout // For displaying output to the console\n    });\n\n    \n\nfunction CelebracionDeLosJuegosOlimpicos () {\n\n    const participantes = [\n        {nombre: \"David\",pais: \"Mexico\"},\n        { nombre: 'Pepe', pais: 'Colombia'},\n        { nombre: 'Juan', pais: 'Chile'},\n        \n    ] //participante: nombre, pais\n    const eventos = [\"Acletismo\", \"Salto\",\"Natacion\",\"ciclismo\" ] //eventos: \n\n    let resultadoDeJuegos= []\n    let medallas = [\"Oro\", \"Plata\", \"Cobre\"]\n    let totaldeMedallas ={} // 6 Mostrar el ranking de países según el número de medallas.\n\n    //----------------------------------------------Paises y sus medallas----------------------------\n    function medallasDePaises(){\n        if(resultadoDeJuegos.length < 1){\n            console.log(\"Favor de simular un juegos\")\n        }else {\n            resultadoDeJuegos.forEach(participantes => {\n                participantes.equipos.forEach(info => {\n                    const pais = info.pais\n                    const medalla = info.medalla\n\n                    //si no esta el pais lo agregamos e inicializamos en 0\n                    if(!totaldeMedallas[pais]){\n                        totaldeMedallas[pais] = {Oro:0, Plata:0, Cobre:0}\n                    }\n                    if(totaldeMedallas[pais][medalla] !== undefined){\n                        totaldeMedallas[pais][medalla]++\n                       \n                    }\n                    console.log(totaldeMedallas)\n\n                })\n                \n            })\n            \n        }\n}\n\n\n    //--------------------------------------------informe de todos los juegos pasados-------------\n    function informe(){\n        if(resultadoDeJuegos.length == 0){\n            console.log(\"Aun no hay ningun juego favor de simular 1\")\n        }else {\n            console.log(\"-------------Lista de ganadores en los juegos----------\")\n            \n            resultadoDeJuegos.forEach(participantes => {\n                console.log(participantes.nombredeljuego)\n                participantes.equipos.forEach(info => {\n                    console.log(info)\n\n                })\n                \n                \n            })\n\n                \n            init()\n\n        }\n    }\n    //simulando eventos-------------------------------------------------------\n    function simular (){\n        \n        if(participantes.length < 3) {\n            console.log(`Tenemos ${participantes.length} y los participantes deben ser por lo menos 3, porfavor registra mas partcicpantes`)\n            registros(\"participante\")\n        }else{\n            console.log(\"-----------------------simulacion de juego-----------------\")\n            // sacarlo un numero del 1 al evento.leng despues mapear y selecionar ese evento en la posicion\n            let seleccionarJuego= eventos[Math.floor(Math.random()*eventos.length)]\n\n            let puntuajeDeParticipantes = participantes.map(participante => {\n                \n                return {\n                    ...participante,\n                    puntuaje:Math.floor(Math.random()*10)+1\n                }\n                \n            })         \n            \n\n            resultadoDeJuegos.push({nombredeljuego:seleccionarJuego, equipos:puntuajeDeParticipantes}) \n            \n            \n              resultadoDeJuegos.forEach(juego => {\n                \n\n                juego.equipos.sort((a, b) => {\n                    return b.puntuaje - a.puntuaje\n                });\n                \n                \n                let contadorMedallas = 0\n                juego.equipos.forEach(participante => {\n                    if(contadorMedallas <= 2){\n                        let guardarVueltas = contadorMedallas\n                    participante.medalla =medallas[guardarVueltas]\n                    contadorMedallas ++\n                    }else {\n                        let sinMedellas = \"sin medalla\"\n                        participante.medalla =sinMedellas\n                    }\n                 \n                });\n                                \n            });\n\n            let simulacionActual = resultadoDeJuegos.at(-1)\n            console.log(simulacionActual)\n            \n            \n            init()\n        }\n        \n    }\n    // funciones para simular los eventos-------------------------\n\n\n    //Registro de eventos y personas ---------------------------------------------------\n    function registros (respuesta){\n        if(respuesta === \"salir\"){\n            console.log(\"Saliendo de los juegos olimpicos\")\n            rl.close()\n            return\n        }else if (respuesta === \"participante\"){\n            rl.question(\"cual es tu nombre?\",(respuesta) => {\n                rl.question(\"Cual es tu pais?\", (respuesta2)=> {\n                    let savedb = {nombre: respuesta, pais: respuesta2}\n                    participantes.push(savedb) \n                    console.log(participantes)\n                    init()\n                })\n            })\n        }else if(respuesta === \"evento\"){\n            rl.question(\"que evento deportivo gustas registrar\", (respuesta) => {\n                eventos.push(respuesta)\n                console.log(eventos)\n                init()\n            })\n        }\n\n    }\n\n    function init (){\n\n        rl.question(\"Bienvenido a los juegos olimpicos acciones: 'registros', 'simular', 'ganadores', 'medallas' \", (respuesta)=>{\n            if(respuesta === \"registros\"){\n                rl.question(\"Puedes registrar a un participante o un evento: 'participante' o 'evento' \", (respuesta) => {\n                    registros(respuesta)\n                    respuesta !== \"salir\" ? init() : console.log(\"accion no permitida vuelve a intentar\", init()) \n                })\n                \n            } else if(respuesta === \"simular\"){\n            simular()\n             respuesta !== \"salir\" ? init() : console.log(\"accion no permitida vuelve a intentar\", init())\n        } else if(respuesta === \"medallas\"){\n            medallasDePaises()\n             respuesta !== \"salir\" ? init() : console.log(\"accion no permitida vuelve a intentar\", init())\n        } else if(respuesta === \"ganadores\"){\n            informe()\n             respuesta !== \"salir\" ? init() : console.log(\"accion no permitida vuelve a intentar\", init())\n        }else if(respuesta === \"salir\"){\n            console.log(\"Saliendo de los juegos olimpicos\")\n            rl.close()\n            return\n        } else {\n            console.log(\"accion no permitida vuelve a intentar\")\n            init()\n        }\n            })\n    }\n    init()\n\n}\nCelebracionDeLosJuegosOlimpicos()"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #31 - JavaScript -> Jesus Antonio Escamilla */\n\n/**\n * SIMULADOR JUEGOS OLÍMPICOS\n * Utilizando la Terminal para pedir datos y agregarlos.\n */\n\nconst readline = require('readline');\n\nconst rl = readline.createInterface({\n   input: process.stdin,\n   output: process.stdout\n});\n\nclass Participant{\n   constructor(nombre, pais) {\n      this.nombre = nombre;\n      this.pais = pais;\n   }\n\n   equals(other){\n      if (other instanceof Participant) {\n         return this.nombre === other.nombre && this.pais === other.pais;\n      }\n      return false;\n   }\n\n   hashCode(){\n      return `${this.nombre}-${this.pais}`.hashCode();\n   }\n}\n\nclass Olympics {\n   constructor() {\n      this.events = [];\n      this.participants = {};\n      this.eventResults = {};\n      this.paisResults = {};\n   }\n\n   registerEvent(callback) {\n      rl.question(\"Introduce el nombre del evento deportivo: \", (event) => {\n         event = event.trim();\n\n         if (this.events.includes(event)) {\n            console.log(`El evento ${event} ya está registrado.`);\n         } else {\n            this.events.push(event);\n            console.log(`Evento ${event} registrado correctamente.`);\n         }\n\n         callback();\n      });\n   }\n\n   registerParticipant(callback) {\n      if (this.events.length === 0) {\n         console.log(\"No hay eventos registrados. Por favor, registra uno primero.\");\n         callback();\n         return;\n      }\n\n      rl.question(\"Introduce el nombre del participante: \", (nombre) => {\n         rl.question(\"Introduce el país del participante: \", (pais) => {\n            const participant = new Participant(nombre.trim(), pais.trim());\n\n            console.log(\"Eventos deportivos disponibles:\");\n            this.events.forEach((event, index) => {\n               console.log(`${index + 1}. ${event}`);\n            })\n\n            rl.question(\"Selecciona el número del evento para asignar al participante: \", (eventChoice) => {\n               eventChoice = parseInt(eventChoice) - 1;\n\n                  if (eventChoice >= 0 && eventChoice < this.events.length) {\n                     const event = this.events[eventChoice];\n\n                     if (this.participants[event] && this.participants[event].some(p => p.equals(participant))) {\n                        console.log(`El participante ${nombre} de ${pais} ya está registrado en el evento deportivo ${event}.`);\n                     } else {\n                        if (!this.participants[event]) {\n                           this.participants[event] = [];\n                        }\n\n                        this.participants[event].push(participant);\n                        console.log(`El participante ${nombre} de ${pais} se ha registrado en el evento deportivo ${event}.`);\n                     }\n                  } else {\n                     console.log(\"Selección de evento deportivo inválido. El participante no se ha registrado.\");\n                  }\n               callback();\n            });\n         });\n      });\n   }\n\n   simulateEvents(callback) {\n      if (this.events.length === 0) {\n         console.log(\"No hay eventos registrados. Por favor, registra uno primero.\");\n         callback();\n         return;\n      }\n\n      this.events.forEach(event => {\n         if (!this.participants[event] || this.participants[event].length < 3) {\n            console.log(`No hay participantes suficientes para simular el evento ${event} (mínimo 3).`);\n            return;\n         }\n\n         const eventParticipants = [...this.participants[event]];\n         const shuffledParticipants = this.shuffleArray(eventParticipants).slice(0, 3);\n\n         const [gold, silver, bronze] = shuffledParticipants;\n         this.eventResults[event] = [gold, silver, bronze];\n\n         this.updateCountryResults(gold.pais, \"gold\");\n         this.updateCountryResults(silver.pais, \"silver\");\n         this.updateCountryResults(bronze.pais, \"bronze\");\n\n         console.log(`Resultados simulación del evento: ${event}`);\n         console.log(`Oro: ${gold.nombre} (${gold.pais})`);\n         console.log(`Plata: ${silver.nombre} (${silver.pais})`);\n         console.log(`Bronce: ${bronze.nombre} (${bronze.pais})`);\n      });\n\n      callback();\n   }\n\n   shuffleArray(array) {\n      for (let i = array.length - 1; i > 0; i--) {\n           const j = Math.floor(Math.random() * (i + 1));\n         [array[i], array[j]] = [array[j], array[i]];\n      }\n      return array;\n   }\n\n   updateCountryResults(pais, medal) {\n      if (!this.paisResults[pais]) {\n         this.paisResults[pais] = { gold: 0, silver: 0, bronze: 0 };\n      }\n      this.paisResults[pais][medal] += 1;\n   }\n\n   showReport(callback) {\n      console.log(\"Informe Juegos Olímpicos:\");\n\n      if (Object.keys(this.eventResults).length > 0) {\n         console.log(\"Informe por evento:\");\n\n         for (const [event, winners] of Object.entries(this.eventResults)) {\n            console.log(`Evento: ${event}`);\n            console.log(`Oro: ${winners[0].nombre} (${winners[0].pais})`);\n            console.log(`Plata: ${winners[1].nombre} (${winners[1].pais})`);\n            console.log(`Bronce: ${winners[2].nombre} (${winners[2].pais})`);\n         }\n      } else {\n         console.log(\"No hay resultados registrados.\");\n      }\n\n      console.log();\n\n      if (Object.keys(this.paisResults).length > 0) {\n         console.log(\"Informe por país:\");\n\n         const sortedCountries = Object.entries(this.paisResults).sort((a, b) => {\n            const [paisA, medalsA] = a;\n            const [paisB, medalsB] = b;\n            return medalsB.gold - medalsA.gold || medalsB.silver - medalsA.silver || medalsB.bronze - medalsA.bronze;\n         });\n\n         for (const [pais, medals] of sortedCountries) {\n            console.log(`${pais}: Oro ${medals.gold}, Plata ${medals.silver}, Bronce ${medals.bronze}`);\n         }\n      } else {\n         console.log(\"No hay medallas por país registradas.\");\n      }\n\n      callback();\n   }\n}\n\nolympic = new Olympics()\n\nfunction mostrarMenu(){\n   console.log(\"\\nSimulador de Juegos Olímpicos\\n\");\n   console.log(`\n      1. Registro de eventos.\n      2. Registro de participantes.\n      3. Simulación de eventos.\n      4. Creación de informes.\n      5. Salir.\n      `);\n      \n      rl.question('Selecciona una opción: ', (option) => {\n         switch (option) {\n            case \"1\":\n               olympic.registerEvent(mostrarMenu)\n               break;\n      \n            case \"2\":\n               olympic.registerParticipant(mostrarMenu)\n               break;\n      \n            case \"3\":\n               olympic.simulateEvents(mostrarMenu)\n               break;\n      \n            case \"4\":\n               olympic.showReport(mostrarMenu)\n               break;\n      \n            case \"5\":\n               console.log(\"Saliendo del programa.....\");\n               rl.close();\n               break;\n         \n            default:\n               console.log(\"Opción invalida. Por favor, seleccione una nueva\");\n               mostrarMenu();\n         }\n      });\n}\n\nmostrarMenu()"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/javascript/JesusEs1312.js",
    "content": "    const readline = require('readline');\n    const rl = readline.createInterface({\n        input: process.stdin,\n        output: process.stdout\n    });\n\n    class Participant {\n        constructor(nombre, pais, evento){\n            this.nombre = nombre;\n            this.pais   = pais;\n            this.evento = evento;\n            this.medal  = \"\";\n        }\n    }\n\n    class OlympicsGames {\n\n        constructor(){\n            this.participants = [];\n            this.events       = [];\n            this.countries    = [];\n        }\n\n        registrationEvents(){\n            rl.question(\"|* Nombre del evento: \", (newNameEvent) => {\n                let nameEvent = {nombre: newNameEvent, winners: []};\n                this.events.push(nameEvent);\n                console.log(`|== Se ha registrado el evento ${newNameEvent} correctamente`);\n                console.log(\"|== Estos son todos tus eventos actuales: \");\n                this.events.forEach((e, i) => console.log(`|${i + 1}.- ${e.nombre}`));\n                this.showMessage();\n            });\n        }\n\n        registrationParticipants(){\n            if(this.events.length >= 1){\n                let nombre = \"\";\n                let pais   = \"\";\n                let evento = \"\";\n                rl.question(\"|* Nombre del participante: \", (nombreParticipant) => {\n                    nombre = nombreParticipant;\n                    rl.question(\"|* País del participante: \", (paisParticipant) => {\n                        pais = paisParticipant;\n                        rl.question(\"|* Nombre del evento: \", (nombreEvento) => {\n                            this.events.forEach(e => evento = e.nombre === nombreEvento ? nombreEvento : \"\");\n                            if(evento !== \"\"){\n                                let participant = new Participant(nombre, pais, evento);\n                                this.participants.push(participant);\n                                this.countries.push(paisParticipant);\n                                console.log(`|== Se ha registrado al participante ${nombre} correctamente`);\n                                this.participants.forEach((p, i) => console.log(`|${i + 1}.- ${p.nombre}`));\n                                this.showMessage();\n                            } else {\n                                console.log(\"|== No se encontro el evento, intentalo de nuevo\");\n                                this.registrationParticipants();\n                            }\n                        });\n                    });\n                });\n    \n            } else {\n                console.log(\"=== No existe un evento para registrar al participante, intente de nuevo ===\");\n                this.showMessage();\n            }\n        }\n        \n        simulateEvents(){\n            if(this.events.length <= 0){\n                console.log(\"|== No existen eventos disponibles para simular\");\n            } else {\n                console.log(\"|== Eventos que puedes simular\");\n                this.events.forEach((e, i) => console.log(`|${i + 1}.- ${e.nombre}`));\n                rl.question(\"|* Selecciona una de las opciones: \", (accion) => {\n                    let count = 0;\n                    this.participants.forEach((participant) => {\n                        if(participant.evento == this.events[accion - 1].nombre){\n                            count++;\n                        }\n                    });\n                    if(count >= 3){\n                        console.log(\"|== Simulando...\");\n                        setTimeout(() => {\n                            let position1 = parseInt(Math.random() * this.participants.length);\n                            let position2 = parseInt(Math.random() * this.participants.length);\n                            let position3 = parseInt(Math.random() * this.participants.length);\n                            while(position1 === position2 || position1 == position3 || position2 == position3){\n                                position1 = parseInt(Math.random() * this.participants.length);\n                                position2 = parseInt(Math.random() * this.participants.length);\n                                position3 = parseInt(Math.random() * this.participants.length);\n                            }\n\n                            console.log(`----- Tabla de ganadores del evento ${this.events[accion - 1].nombre} -----`);\n                            console.log(`|1. ${this.participants[position1].nombre} (Oro)`);\n                            console.log(`|2. ${this.participants[position2].nombre} (Plata)`);\n                            console.log(`|3. ${this.participants[position3].nombre} (Bronce)`);\n                            this.participants[position1].medal = \"oro\";\n                            this.participants[position2].medal = \"plata\";\n                            this.participants[position3].medal = \"bronce\";\n                            this.events.find(index => index.nombre == this.events[accion - 1].nombre).winners.push(this.participants[position1]);\n                            this.events.find(index => index.nombre == this.events[accion - 1].nombre).winners.push(this.participants[position2]);\n                            this.events.find(index => index.nombre == this.events[accion - 1].nombre).winners.push(this.participants[position3]);\n                            this.showMessage();\n                        }, \"1000\");\n                        \n                    } else {\n                        console.log(\"|== ¡ERROR! El evento no tiene minimo 3 participantes o no existe\");\n                        this.showMessage();\n                    }\n                });\n            }\n        }\n\n        createData(){\n            console.log(\"|----- Creación de informes -----\");\n            console.log(\"|1. Ganadores por evento\");\n            console.log(\"|2. Ranking de paises\");\n            rl.question(\"|* Selecciona una opcion: \", (op) =>{\n                switch(op){\n                    case '1':\n                        this.rankingEvent();\n                        break;\n                    case '2':\n                        this.rankingCountry();\n                        break;\n                    default:\n                        console.log(\"|== Acción no permitida, intentelo de nuevo\");\n                        this.createData();\n                }\n            });\n        }\n\n        rankingCountry(){\n            let countriesAndMelds = [];\n            this.participants.forEach(participant => {\n                let medalla = participant.medal;\n                let score   = 0;\n                let oro     = 0;\n                let plata   = 0;\n                let bronce  = 0;\n                if(medalla == \"oro\"){\n                    score = 3;\n                    oro++;\n                } else if(medalla == \"plata\"){\n                    score = 2;\n                    plata++;\n                } else if(medalla == \"bronce\"){\n                    score = 1;\n                    bronce++;\n                } \n\n                if(countriesAndMelds.includes(countriesAndMelds.find(index => index.nombre == participant.pais))){\n                    countriesAndMelds.find(index => index.nombre == participant.pais).score += score;\n                    countriesAndMelds.find(index => index.nombre == participant.pais).oro += oro;\n                    countriesAndMelds.find(index => index.nombre == participant.pais).plata += plata;\n                    countriesAndMelds.find(index => index.nombre == participant.pais).bronce += bronce;\n                } else {\n                    countriesAndMelds.push({nombre: participant.pais, score: score, oro: oro, plata: plata, bronce: bronce});\n                }\n            });\n\n            countriesAndMelds.sort((a,b) => {\n                if(a.score > b.score){\n                    return -1;\n                } else if(a.score < b.score){\n                    return 1;\n                } else {\n                    return 0;\n                }\n            });\n\n            console.log(\"|----- Ranking por país -----\");\n            countriesAndMelds.forEach((countryAndMedal, index) => {\n                console.log(`|${index + 1}.  ${countryAndMedal.nombre}  Oro: ${countryAndMedal.oro}, Plata: ${countryAndMedal.plata}, Bronce: ${countryAndMedal.bronce}`);\n            });\n            this.showMessage();\n        }\n\n        rankingEvent(){\n            console.log(\"|----- Ranking por Evento -----\");\n            this.events.forEach(e => {\n                console.log(`|${e.nombre}`);\n                e.winners.forEach((winner, index) => console.log(`|${index + 1}. ${winner.nombre}`))\n            });\n            this.showMessage();\n        }\n\n        showMessage(){\n            let message = \"|Acciones que puedes realizar:\\n|1. Registro de eventos\\n|2. Registro de participantes\\n|3. Simulación de eventos\\n|4. Creación de informes\\n|5. Salir del programa\";\n            console.log(\"|-----------------------------------------------------\");\n            console.log(message.trim());\n            rl.question(\"|Selecciona una de las opciones: \", (accion) => {\n                switch(accion){\n                    case '1':\n                        this.registrationEvents();\n                        break;\n                    case '2':\n                        this.registrationParticipants();\n                        break;\n                    case '3':\n                        this.simulateEvents();\n                        break;\n                    case '4':\n                        this.createData();\n                        break;\n                    case '5':\n                        console.log(\"|Cerrando programa...\");\n                        rl.close();\n                        break;\n                    default:\n                        console.log(\"|Acción no permitida, intentelo de nuevo\");\n                        this.showMessage();\n                }\n            });\n        }\n    }\n\n    olympic = new OlympicsGames();\n    olympic.showMessage();\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/javascript/RaulDoezon.js",
    "content": "/*\n  EJERCICIO:\n  ¡Los JJOO de París 2024 han comenzado!\n  Crea un programa que simule la celebración de los juegos.\n  El programa debe permitir al usuario registrar eventos y participantes,\n  realizar la simulación de los eventos asignando posiciones de manera aleatoria\n  y generar un informe final. Todo ello por terminal.\n  Requisitos:\n  1. Registrar eventos deportivos.\n  2. Registrar participantes por nombre y país.\n  3. Simular eventos de manera aleatoria en base a los participantes (mínimo 3).\n  4. Asignar medallas (oro, plata y bronce) basándose en el resultado del evento.\n  5. Mostrar los ganadores por cada evento.\n  6. Mostrar el ranking de países según el número de medallas.\n  Acciones:\n  1. Registro de eventos.\n  2. Registro de participantes.\n  3. Simulación de eventos.\n  4. Creación de informes.\n  5. Salir del programa.\n*/\n\nlet selectedOption = 0;\nconst options = `Por favor, selecciona una opción:\n  1. Registrar eventos deportivos y participantes por nombre y país.\n  2. Mostrar el ranking de países.\n  3. Salir del programa.`;\nconst olympicGames = [];\n\nfunction showPositions() {\n  console.log(\"+++++++++ RESULTADOS POR EVENTO +++++++++\");\n\n  let sortByEvent = olympicGames.reduce((accumulator, currentValue) => {\n    accumulator[currentValue.event] = accumulator[currentValue.event] || [];\n    accumulator[currentValue.event].push(currentValue);\n\n    return accumulator;\n  }, []);\n\n  for (const key in sortByEvent) {\n    const eachEvent = sortByEvent[key];\n    let setNumbers = new Set();\n    let numberOfAthletes = eachEvent.length;\n\n    console.log(`\\n${eachEvent[0].event}`);\n\n    if (numberOfAthletes > 2) {\n      while(setNumbers.size !== numberOfAthletes) {\n        setNumbers.add(Math.floor(Math.random() * numberOfAthletes) + 1);\n      }\n\n      let aleatoryPositions = Array.from(setNumbers);\n\n      for (let index = 0; index < eachEvent.length; index++) {\n        const athletePerEvent = eachEvent[index];\n        athletePerEvent.position = aleatoryPositions[index];\n\n        if (athletePerEvent.position === 1) {\n          athletePerEvent.medal = \"Oro\";\n        } else if (athletePerEvent.position === 2) {\n          athletePerEvent.medal = \"Plata\";\n        } else if (athletePerEvent.position === 3) {\n          athletePerEvent.medal = \"Bronce\";\n        }\n      }\n\n      eachEvent.sort((a, b) => a.position - b.position);\n\n      for (const finalPosition of eachEvent) {\n        console.log(`Nombre: ${finalPosition.name} | País: ${finalPosition.country} | Posición: ${finalPosition.position} ${finalPosition.medal !== undefined ? '- ' + finalPosition.medal : ''}`);\n      }\n    } else {\n      console.log(`Mínimo, deben participar 3 atletas en ${eachEvent[0].event}`);\n    }\n  }\n}\n\nfunction medalTable() {\n  let medalTableByCountry = [];\n  let sortByCountry = olympicGames.reduce((accumulator, currentValue) => {\n    accumulator[currentValue.country] = accumulator[currentValue.country] || [];\n\n    if (currentValue.medal !== undefined) {\n      accumulator[currentValue.country].push(currentValue.medal);\n    }\n\n    return accumulator;\n  }, []);\n\n  for (const key in sortByCountry) {\n    const eachCountry = sortByCountry[key];\n    const eachCountryMedals = eachCountry.length;\n\n    medalTableByCountry.push({country: key, medals: eachCountryMedals});\n  }\n\n  console.log(\"\\n+++++++++ MEDALLERO OLÍMPICO +++++++++\");\n\n  medalTableByCountry.sort((a, b) => b.medals - a.medals);\n\n  for (let countryIndex = 0; countryIndex < medalTableByCountry.length; countryIndex++) {\n    const position = medalTableByCountry[countryIndex];\n\n    console.log(`${countryIndex + 1}. ${position.country} | Medallas: ${position.medals}`);\n  }\n}\n\ndo {\n  selectedOption = parseInt(prompt(options));\n\n  switch (selectedOption) {\n    case 1:\n      const event = prompt(\"Registra el evento deportivo:\");\n      const athleteName = prompt(\"Registra el nombre del atleta:\");\n      const athleteCountry = prompt(\"Registra el país del atleta:\");\n\n      olympicGames.push({event: event, name: athleteName, country: athleteCountry});\n      break;\n\n    case 2:\n      alert(\"Visualiza el medallero en la consola del navegador.\");\n\n      showPositions();\n      medalTable();\n      break;\n\n    case 3:\n      alert(\"Saliendo del programa...\");\n      break;\n\n    default:\n      alert(\"Debes seleccionar una de las opciones disponibles.\");\n      break;\n  }\n} while (selectedOption !== 3);\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/javascript/RicJDev.js",
    "content": "//@RicJDev\n\n//Se ha instalado Picocolors, un libreria para colorear texto en terminal (https://www.npmjs.com/package/picocolors)\nimport pc from 'picocolors'\n\n//EJERCICIO\nclass OlympicRegistry {\n  constructor() {\n    if (OlympicRegistry.instance) {\n      return OlympicRegistry.instance\n    }\n\n    this.events = []\n    this.participants = {}\n\n    OlympicRegistry.instance = this\n  }\n\n  addEvent(eventName) {\n    this.events.push(eventName)\n  }\n\n  registerParticipant(eventName, participant) {\n    if (this.events.includes(eventName)) {\n      if (!this.participants[eventName]) {\n        this.participants[eventName] = []\n      }\n\n      this.participants[eventName].push(participant)\n    } else {\n      console.log(pc.red('Evento no registrado'))\n    }\n  }\n\n  getParticipants(eventName) {\n    return this.participants[eventName] || []\n  }\n}\n\nclass Event {\n  constructor(name) {\n    this.name = name\n    this.medals = []\n  }\n\n  assignMedals() {\n    const participants = OlympicRegistry.instance.getParticipants(this.name)\n\n    if (participants.length < 3) {\n      console.log(pc.red('Se requieren al menos tres participantes'))\n\n      return\n    }\n\n    const medalTypes = ['Gold', 'Silver', 'Bronze']\n\n    for (let i = 0; i < 3; i++) {\n      const randomIndex = Math.floor(Math.random() * participants.length)\n\n      this.medals.push({\n        participant: participants[randomIndex],\n        medal: medalTypes[i],\n      })\n\n      participants.splice(randomIndex, 1)\n    }\n  }\n}\n\nclass MedalRanking {\n  constructor() {\n    this.rankings = {}\n  }\n\n  addMedal(country, medal) {\n    if (!this.rankings[country]) {\n      this.rankings[country] = {\n        Gold: 0,\n        Silver: 0,\n        Bronze: 0,\n      }\n\n      this.rankings[country][medal]++\n    }\n  }\n\n  displayRankings() {\n    if (Object.keys(this.rankings).length > 0) {\n      for (const country in this.rankings) {\n        console.log(' ')\n        console.log(country.toUpperCase())\n        console.log(`Gold: ${this.rankings[country].Gold}`)\n        console.log(`Silver: ${this.rankings[country].Silver}`)\n        console.log(`Bronze: ${this.rankings[country].Bronze}`)\n      }\n    } else {\n      console.log(pc.red('No se ha asignado medallas a ningún país'))\n    }\n  }\n}\n\nclass Participant {\n  constructor(name, country) {\n    this.name = name\n    this.country = country\n  }\n}\n\n/*\n\n  - Se ejecuta en Node.js, importando el modulo Readline (https://nodejs.org/api/readline.html)\n\n*/\n\nimport * as readline from 'node:readline'\n\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout,\n})\n\nconst registry = new OlympicRegistry()\nconst ranking = new MedalRanking()\n\n//1. Registrar evento\nfunction registerEvent() {\n  rl.question(pc.blue('\\nIndique el nombre del evento a registrar: '), (eventName) => {\n    registry.addEvent(eventName)\n\n    console.log(`${pc.green(eventName)} ha sido registrado!`)\n\n    main()\n  })\n}\n\n//2. Registrar participantes\nfunction registerParticipant() {\n  rl.question('\\nIndique el nombre del participante: ', (name) => {\n    rl.question('Indique el país del participante: ', (country) => {\n      if (registry.events.length > 0) {\n        console.log('\\nEstos son los eventos registrados: ')\n\n        for (let i = 0; i < registry.events.length; i++) {\n          console.log(`${i + 1}. ${registry.events[i]}`)\n        }\n\n        rl.question(pc.blue('\\nElija un evento para registrar al participante: '), (eventIndex) => {\n          const index = parseInt(eventIndex) - 1\n\n          if (registry.events[index]) {\n            registry.registerParticipant(registry.events[index], new Participant(name, country))\n\n            console.log(\n              `${pc.green(name)} ha sido registrado en ${pc.green(registry.events[index])}!`\n            )\n          } else {\n            console.log(pc.red('Elija una opción válida'))\n          }\n\n          main()\n        })\n      } else {\n        console.log(pc.red('Debe registrar al menos un evento'))\n        main()\n      }\n    })\n  })\n}\n\n//3. Simular evento\nfunction simulateEvent() {\n  if (registry.events.length > 0) {\n    console.log('\\nEstos son los eventos disponibles: ')\n\n    for (let i = 0; i < registry.events.length; i++) {\n      console.log(`${i + 1}. ${registry.events[i]}`)\n    }\n\n    rl.question(pc.blue('\\nIndique el evento a simular: '), (eventIndex) => {\n      const index = parseInt(eventIndex) - 1\n\n      if (registry.events[index]) {\n        const event = new Event(registry.events[index])\n\n        event.assignMedals()\n\n        for (const element of event.medals) {\n          ranking.addMedal(element.participant.country, element.medal)\n        }\n      } else {\n        console.log(pc.red('\\nEvento no registrado'))\n      }\n\n      main()\n    })\n  } else {\n    console.log(pc.red('Debe registrar al menos un evento'))\n    main()\n  }\n}\n\n//Mostrar medallas\nfunction generateInform() {\n  ranking.displayRankings()\n  main()\n}\n\n//5. Salir del programa\nfunction exit() {\n  console.log(pc.red('\\nSaliendo del programa...'))\n\n  setTimeout(() => {\n    console.clear()\n    rl.close()\n  }, 300)\n}\n\n//Menu principal\nfunction main() {\n  console.log(pc.underline('\\nSIMULADOR DE JUEGOS OLIMPICOS'))\n\n  console.log(\n    '\\n1. Registrar evento\\n2. Registrar participantes\\n3. Simular evento\\n4. Generar informes\\n5. Salir del programa'\n  )\n\n  const actions = new Map([\n    ['1', registerEvent],\n    ['2', registerParticipant],\n    ['3', simulateEvent],\n    ['4', generateInform],\n    ['5', exit],\n  ])\n\n  rl.question(pc.yellow('\\nSeleccione una opción (1 - 5) '), (option) => {\n    const action =\n      actions.get(option) ||\n      function () {\n        console.log(pc.red('Elija una opción válida'))\n        main()\n      }\n\n    action()\n  })\n}\n\nmain()\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/javascript/adrs1166ma.js",
    "content": "/* 🔥 EJERCICIO:\n¡Los JJOO de París 2024 han comenzado!\nCrea un programa que simule la celebración de los juegos.\nEl programa debe permitir al usuario registrar eventos y participantes,\nrealizar la simulación de los eventos asignando posiciones de manera aleatoria\ny generar un informe final. Todo ello por terminal.\nRequisitos:\n1. Registrar eventos deportivos.\n2. Registrar participantes por nombre y país.\n3. Simular eventos de manera aleatoria en base a los participantes (mínimo 3).\n4. Asignar medallas (oro, plata y bronce) basándose en el resultado del evento.\n5. Mostrar los ganadores por cada evento.\n6. Mostrar el ranking de países según el número de medallas.\nAcciones:\n1. Registro de eventos.\n2. Registro de participantes.\n3. Simulación de eventos.\n4. Creación de informes.\n5. Salir del programa.\n */\nconsole.log(\"🎉 ¡Bienvenido a los JJOO de París 2024! 🎉\");\n\n// Variables globales\nconst eventos = [];\nconst participantes = [];\nconst resultados = [];\n\n// Función principal del programa\nfunction iniciarPrograma() {\n    let continuar = true;\n\n    while (continuar) {\n        console.log(\"\\n--- MENÚ PRINCIPAL ---\");\n        console.log(\"1. Registrar evento.\");\n        console.log(\"2. Registrar participante.\");\n        console.log(\"3. Simular eventos.\");\n        console.log(\"4. Crear informe de resultados.\");\n        console.log(\"5. Salir del programa.\");\n\n        const opcion = prompt(\"Seleccione una opción (1-5): \");\n\n        switch (opcion) {\n            case \"1\":\n                registrarEvento();\n                break;\n            case \"2\":\n                registrarParticipante();\n                break;\n            case \"3\":\n                simularEventos();\n                break;\n            case \"4\":\n                crearInforme();\n                break;\n            case \"5\":\n                console.log(\"👋 ¡Gracias por usar el simulador de los JJOO de París 2024! 👋\");\n                continuar = false;\n                break;\n            default:\n                console.log(\"❌ Opción no válida. Intente de nuevo.\");\n        }\n    }\n}\n\n// 1. Registrar evento\nfunction registrarEvento() {\n    const nombre = prompt(\"Ingrese el nombre del evento: \");\n    if (!nombre) {\n        console.log(\"❌ El nombre del evento no puede estar vacío.\");\n        return;\n    }\n\n    eventos.push({ nombre, participantes: [] });\n    console.log(`✅ Evento \"${nombre}\" registrado.`);\n}\n\n// 2. Registrar participante\nfunction registrarParticipante() {\n    const nombre = prompt(\"Ingrese el nombre del participante: \");\n    const pais = prompt(\"Ingrese el país del participante: \");\n\n    if (!nombre || !pais) {\n        console.log(\"❌ El nombre y el país del participante son obligatorios.\");\n        return;\n    }\n\n    participantes.push({ nombre, pais });\n    console.log(`✅ Participante \"${nombre}\" (${pais}) registrado.`);\n}\n\n// 3. Simular eventos\nfunction simularEventos() {\n    if (eventos.length === 0) {\n        console.log(\"❌ No hay eventos registrados para simular.\");\n        return;\n    }\n\n    if (participantes.length < 3) {\n        console.log(\"❌ Se necesitan al menos 3 participantes para simular un evento.\");\n        return;\n    }\n\n    for (const evento of eventos) {\n        const participantesAleatorios = seleccionarParticipantesAleatorios(3);\n        const resultadosSimulados = simularResultados(participantesAleatorios);\n\n        // Asignar medallas\n        const medallas = [\"Oro\", \"Plata\", \"Bronce\"];\n        resultadosSimulados.forEach((resultado, index) => {\n            const medalla = medallas[index];\n            resultados.push({ evento: evento.nombre, participante: resultado, medalla });\n        });\n\n        console.log(`\\n🏆 Resultados del evento \"${evento.nombre}\":`);\n        resultadosSimulados.forEach((participante, index) => {\n            console.log(`${medallas[index]}: ${participante.nombre} (${participante.pais})`);\n        });\n    }\n}\n\n// Función auxiliar: Seleccionar participantes aleatorios\nfunction seleccionarParticipantesAleatorios(cantidad) {\n    const copiaParticipantes = [...participantes];\n    const seleccionados = [];\n\n    for (let i = 0; i < cantidad; i++) {\n        const indiceAleatorio = Math.floor(Math.random() * copiaParticipantes.length);\n        seleccionados.push(copiaParticipantes.splice(indiceAleatorio, 1)[0]);\n    }\n\n    return seleccionados;\n}\n\n// Función auxiliar: Simular resultados (orden aleatorio)\nfunction simularResultados(participantesAleatorios) {\n    return participantesAleatorios.sort(() => Math.random() - 0.5);\n}\n\n// 4. Crear informe de resultados\nfunction crearInforme() {\n    if (resultados.length === 0) {\n        console.log(\"❌ No hay resultados disponibles para generar el informe.\");\n        return;\n    }\n\n    // Contar medallas por país\n    const rankingPaises = {};\n    for (const resultado of resultados) {\n        const { pais } = resultado.participante;\n        if (!rankingPaises[pais]) {\n            rankingPaises[pais] = { Oro: 0, Plata: 0, Bronce: 0 };\n        }\n        rankingPaises[pais][resultado.medalla]++;\n    }\n\n    // Mostrar ganadores por evento\n    console.log(\"\\n--- GANADORES POR EVENTO ---\");\n    eventos.forEach(evento => {\n        console.log(`\\nEvento: ${evento.nombre}`);\n        const resultadosEvento = resultados.filter(r => r.evento === evento.nombre);\n        resultadosEvento.forEach(resultado => {\n            console.log(`${resultado.medalla}: ${resultado.participante.nombre} (${resultado.participante.pais})`);\n        });\n    });\n\n    // Mostrar ranking de países\n    console.log(\"\\n--- RANKING DE PAÍSES ---\");\n    const paisesOrdenados = Object.entries(rankingPaises).sort((a, b) => {\n        return (\n            b[1].Oro - a[1].Oro ||\n            b[1].Plata - a[1].Plata ||\n            b[1].Bronce - a[1].Bronce\n        );\n    });\n\n    paisesOrdenados.forEach(([pais, medallas], index) => {\n        console.log(\n            `${index + 1}. ${pais}: Oro=${medallas.Oro}, Plata=${medallas.Plata}, Bronce=${medallas.Bronce}`\n        );\n    });\n}\n\niniciarPrograma();"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/javascript/caterinarodriguezdev.js",
    "content": "const { stdin, stdout } = require(\"process\");\nconst readline = require(\"readline\");\nconst rl = readline.createInterface(stdin, stdout);\n\nconst events = [];\nconst participantes = [];\n\nconsole.log(\"¡Bienvenido a los JJOO!\");\n\nconst menu = () => {\n  console.log(`\n    1. Registrar evento\n    2. Registar participantes\n    3. Simular Evento\n    4. Creación de informe\n    5. Salir del programa\n    `);\n\n  rl.question(\"Elija una opción -> \", (resp) => {\n    switch (resp) {\n      case \"1\":\n        registerEvent();\n        break;\n      case \"2\":\n        registerPlayer();\n        break;\n      case \"3\":\n        startEvent();\n        break;\n      case \"4\":\n        createReport();\n        break;\n      case \"5\":\n        rl.close();\n        break;\n      default:\n        console.log(\"Opción no válida\");\n        menu();\n    }\n  });\n};\n\nconst registerEvent = () => {\n  rl.question(\"Nombre del evento -> \", (resp) => {\n    events.push(resp);\n    console.log(`Evento ${resp} registrado con éxito`);\n    menu();\n  });\n};\n\nconst registerPlayer = () => {\n  rl.question(\"Nombre del participante -> \", (nombre) => {\n    rl.question(\"País -> \", (pais) => {\n      const participante = {\n        nombre: nombre,\n        pais: pais,\n        eventos: {},\n      };\n      events.forEach((evento) => {\n        participante.eventos[evento] = { puntuacion: 0, medalla: null };\n      });\n      participantes.push(participante);\n      console.log(`Participante ${nombre} - ${pais} registrado con éxito`);\n      menu();\n    });\n  });\n};\n\nconst startEvent = () => {\n  if (events.length === 0) {\n    console.log(\"No hay eventos registrados\");\n    return menu();\n  }\n  console.log(\"Eventos disponibles:\");\n  events.forEach((e, index) => console.log(`${index + 1}. ${e}`));\n  rl.question(\"¿Qué evento deseas simular? (Ingrese el número) -> \", (resp) => {\n    const eventoIndex = parseInt(resp) - 1;\n    if (eventoIndex >= 0 && eventoIndex < events.length) {\n      const evento = events[eventoIndex];\n      if (participantes.length >= 3) {\n        console.log(`Simulando el evento: ${evento}`);\n        participantes.forEach((p) => {\n          p.eventos[evento].puntuacion = Math.floor(Math.random() * 10) + 1;\n        });\n        const participantesOrdenados = [...participantes].sort(\n          (a, b) => b.eventos[evento].puntuacion - a.eventos[evento].puntuacion\n        );\n\n        [\"Oro\", \"Plata\", \"Bronce\"].forEach((medalla, index) => {\n          if (participantesOrdenados[index]) {\n            participantesOrdenados[index].eventos[evento].medalla = medalla;\n            console.log(\n              `El participante ${\n                participantesOrdenados[index].nombre\n              } ha ganado la medalla de ${medalla.toLowerCase()}!`\n            );\n          }\n        });\n\n        console.log(\"¡El evento ha finalizado!\");\n      } else {\n        console.log(\"Debe haber mínimo 3 participantes\");\n      }\n    } else {\n      console.log(\"Evento no válido\");\n    }\n    menu();\n  });\n};\n\nconst createReport = () => {\n  events.forEach((event) => {\n    console.log(`EVENTO ${event}`);\n    participantes.forEach((p) => {\n      if (p.eventos[event].medalla) {\n        console.log(\n          `El participante ${p.nombre} ha ganado la medalla de ${p.eventos[\n            event\n          ].medalla.toLowerCase()}`\n        );\n      }\n    });\n    console.log(\"\\n\");\n  });\n\n  const medallasPorPais = {};\n\n  participantes.forEach((p) => {\n    if (!medallasPorPais[p.pais]) {\n      medallasPorPais[p.pais] = { oro: 0, plata: 0, bronce: 0, total: 0 };\n    }\n    Object.values(p.eventos).forEach((evento) => {\n      if (evento.medalla) {\n        medallasPorPais[p.pais][evento.medalla.toLowerCase()]++;\n        medallasPorPais[p.pais].total++;\n      }\n    });\n  });\n\n  const rankingPaises = Object.entries(medallasPorPais)\n    .map(([pais, medallas]) => ({ pais, ...medallas }))\n    .sort((a, b) => {\n      if (a.oro !== b.oro) return b.oro - a.oro;\n      if (a.plata !== b.plata) return b.plata - a.plata;\n      if (a.bronce !== b.bronce) return b.bronce - a.bronce;\n      return b.total - a.total;\n    });\n\n  console.log(\"RANKING DE PAÍSES\");\n  rankingPaises.forEach((elemento, index) => {\n    console.log(\n      `${index + 1}. ${elemento.pais} - Oro: ${elemento.oro}, Plata: ${\n        elemento.plata\n      }, Bronce: ${elemento.bronce}, Total: ${elemento.total}`\n    );\n  });\n\n  menu();\n};\n\nmenu();\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/javascript/duendeintemporal.js",
    "content": "//#31 - Simulador Juegos Olímpicos\n/*\n * EJERCICIO:\n * ¡Los JJOO de París 2024 han comenzado!\n * Crea un programa que simule la celebración de los juegos.\n * El programa debe permitir al usuario registrar eventos y participantes,\n * realizar la simulación de los eventos asignando posiciones de manera aleatoria\n * y generar un informe final. Todo ello por terminal.\n * Requisitos:\n * 1. Registrar eventos deportivos.\n * 2. Registrar participantes por nombre y país.\n * 3. Simular eventos de manera aleatoria en base a los participantes (mínimo 3).\n * 4. Asignar medallas (oro, plata y bronce) basándose en el resultado del evento.\n * 5. Mostrar los ganadores por cada evento.\n * 6. Mostrar el ranking de países según el número de medallas.\n * Acciones:\n * 1. Registro de eventos.\n * 2. Registro de participantes.\n * 3. Simulación de eventos.\n * 4. Creación de informes.\n * 5. Salir del programa.\n */\n\nlet log = console.log;\n\nwindow.addEventListener('load', ()=>{\n    const body = document.querySelector('body');\n    const title = document.createElement('h1');\n    \n    body.style.setProperty('background', '#000');\n    body.style.setProperty('text-align', 'center');\n    \n    title.textContent = 'Retosparaprogramadores #31.';\n    title.style.setProperty('font-size', '3.5vmax');\n    title.style.setProperty('color', '#fff');\n    title.style.setProperty('line-height', '100vh');\n    \n    body.appendChild(title);\n    \n    setTimeout(()=>{\n    alert('Retosparaprogramadores #31. Please open the Browser Developer Tools.');\n    }, 2000);\n    log( 'Retosparaprogramadores #31'); \n});\n\nfunction shuffleArray(array) {\n    for (let i = array.length - 1; i > 0; i--) {\n        const j = Math.floor(Math.random() * (i + 1));\n        [array[i], array[j]] = [array[j], array[i]];\n    }\n    return array;\n}\n\nclass Events {\n    constructor() {\n        this.events = {};\n        this.prizes = new Prizes();\n    }\n\n    addEvent(event) {\n        if (this.events[event]) {\n            log(`There's a ${event} event already registered.`);\n        } else {\n            this.events[event] = [];\n            log(`Event ${event} registered.`);\n        }\n    }\n\n    addPlayer(player) {\n        if (!this.events[player.event]) {\n            log(`Event ${player.event} is not registered.`);\n            return;\n        }\n\n        let isPlayer = this.events[player.event].find(p => p.name === player.name);\n        if (!isPlayer) {\n            this.events[player.event].push(player);\n            log(`Player ${player.name} added to ${player.event} event.`);\n        } else {\n            log(`The player ${player.name} is already registered to ${player.event} event.`);\n        }\n    }\n\n    randomEvents() {\n        let eventsList = Object.keys(this.events);\n        return shuffleArray(eventsList);\n    }\n\n    showParticipantsForEvent(event) {\n        if (this.events[event]) {\n            log(`Participants for ${event} event:`);\n            this.events[event].forEach(p => log(`${p.name} from ${p.country}`));\n        } else {\n            log(`There's no participant registered for the ${event} event.`);\n        }\n    }\n\n    showRegistryData() {\n        for (let key in this.events) {\n            log(`${key} event:`);\n            this.events[key].forEach(element => {\n                log(`${element.name} from ${element.country}`);\n            });\n        }\n    }\n}\n\nclass Player {\n    constructor(name, event, country) {\n        this.name = name;\n        this.country = country;\n        this.event = event;\n    }\n}\n\nclass Prizes {\n    constructor() {\n        this.gold = {};\n        this.silver = {};\n        this.bronze = {};\n        this.countryMedals = {};\n    }\n\n    addGold(player) {\n        this.addPrize(player, 'gold');\n    }\n\n    addSilver(player) {\n        this.addPrize(player, 'silver');\n    }\n\n    addBronze(player) {\n        this.addPrize(player, 'bronze');\n    }\n\n    addPrize(player, type) {\n        if (!this[type][player.event]) {\n            this[type][player.event] = [];\n        }\n        if (!this[type][player.event].find(p => p.name === player.name)) {\n            this[type][player.event].push(player);\n            this.countCountryMedal(player.country, type);\n        }\n    }\n\n    countCountryMedal(country, type) {\n        if (!this.countryMedals[country]) {\n            this.countryMedals[country] = { gold: 0, silver: 0, bronze: 0 };\n        }\n        this.countryMedals[country][type]++;\n    }\n\n    showWinners() {\n        log('Winners:');\n        for (let event in this.gold) {\n            log(`${event}: Gold - ${this.gold[event].map(p => p.name).join(', ')}`);\n            log(`       Silver - ${this.silver[event] ? this.silver[event].map(p => p.name).join(', ') : 'None'}`);\n            log(`       Bronze - ${this.bronze[event] ? this.bronze[event].map(p => p.name).join(', ') : 'None'}`);\n        }\n    }\n\n    showCountryMedals() {\n        log('Country Medal Count:');\n        for (let country in this.countryMedals) {\n            log(`${country}: Gold - ${this.countryMedals[country].gold}, Silver - ${this.countryMedals[country].silver}, Bronze - ${this.countryMedals[country].bronze}`);\n        }\n    }\n}\n\nconst eventSimulator = (events) => {\n    for (let key in events.events) {\n        if (events.events[key].length >= 3) {\n            let winners = shuffleArray(events.events[key]);\n            events.prizes.addGold(winners[0]);\n            events.prizes.addSilver(winners[1]);\n            events.prizes.addBronze(winners[2]);\n        } else {\n            log(`Not enough participants for ${key} event.`);\n        }\n    }\n    events.prizes.showWinners();\n}\n\nlet dummyData = [\n    ['Bob Marley', 'Archery', 'Jamaica'],\n    ['Lenny Kravitz', 'Swimming', 'USA'],\n    ['John Lennon', 'Weightlifting', 'England'],\n    ['Lorenna McKennit', '100m Sprint', 'Somewhere in Europe'],\n    ['Alice', '200m Freestyle', 'The Rabbit Hole'],\n    ['Che Guevara', '3000m Steeplechase', 'Argentina'],\n    ['Buda', 'Discus Throw', 'India'],\n    ['Bugs Bunny', 'Archery', 'Disney'],\n    ['Asterix', 'Swimming', 'Comics'],\n    ['Lucky Luke', 'Weightlifting', 'Comics'],\n    ['Jerry Maguire', '100m Sprint', 'Comics'],\n    ['Atreyo', '200m Freestyle', 'Book'],\n    ['Simón Bolívar', '3000m Steeplechase', 'Venezuela'],\n    ['Goku', 'Discus Throw', 'Anime'],\n    ['Shihiro', 'Archery', 'Anime'],\n    ['Ruby', 'Swimming', 'Book'],\n    ['Crows', 'Weightlifting', 'Book'],\n    ['Devian', '100m Sprint', 'Book'],\n    ['Peque', '200m Freestyle', 'My World'],\n    ['Sophy', '3000m Steeplechase', 'My World'],\n    ['Beth', 'Discus Throw', 'My World']\n];\n\n\nlet firstRound = new Events();\n\nconst olympicEvents = ['Archery', 'Swimming', 'Weightlifting', '100m Sprint', '200m Freestyle', '3000m Steeplechase', 'Discus Throw'].forEach(event => firstRound.addEvent(event));\n\ndummyData.forEach(d => firstRound.addPlayer(new Player(d[0], d[1], d[2])));\n\nfirstRound.showRegistryData();\n\neventSimulator(firstRound);\n\n/* Possible Output: \n\n                 Register events\n                 Updated list of events\n \n Event Archery registered.\n Event Swimming registered.\n Event Weightlifting registered.\n Event 100m Sprint registered.\n Event 200m Freestyle registered.\n Event 3000m Steeplechase registered.\n Event Discus Throw registered.\n\n                 Register players\n\nPlayer Bob Marley added to Archery event.\nPlayer Lenny Kravitz added to Swimming event.\nPlayer John Lennon added to Weightlifting event.\nPlayer Lorenna McKennit added to 100m Sprint event.\nPlayer Alice added to 200m Freestyle event.\nPlayer Che Guevara added to 3000m Steeplechase event.\nPlayer Buda added to Discus Throw event.\nPlayer Bugs Bunny added to Archery event.\nPlayer Asterix added to Swimming event.\nPlayer Lucky Luke added to Weightlifting event.\nPlayer Jerry Maguire added to 100m Sprint event.\nPlayer Atreyo added to 200m Freestyle event.\nPlayer Simón Bolívar added to 3000m Steeplechase event.\nPlayer Goku added to Discus Throw event.\nPlayer Shihiro added to Archery event.\nPlayer Ruby added to Swimming event.\nPlayer Crows added to Weightlifting event.\nPlayer Devian added to 100m Sprint event.\nPlayer Peque added to 200m Freestyle event.\nPlayer Sophy added to 3000m Steeplechase event.\nPlayer Beth added to Discus Throw event.     \n\n                    Show registered data\n\n                    Simulate events\nArchery event:\n Bob Marley from Jamaica\n Bugs Bunny from Disney\n Shihiro from Anime\n Swimming event:\n Lenny Kravitz from USA\n Asterix from Comics\n Ruby from Book\n Weightlifting event:\n John Lennon from England\n Lucky Luke from Comics\n Crows from Book\n 100m Sprint event:\n Lorenna McKennit from Somewhere in Europe\n Jerry Maguire from Comics\n Devian from Book\n 200m Freestyle event:\n Alice from The Rabbit Hole\n Atreyo from Book\n Peque from My World\n 3000m Steeplechase event:\n Che Guevara from Argentina\n Simón Bolívar from Venezuela\n Sophy from My World\n Discus Throw event:\n Buda from India\n Goku from Anime\n Beth from My World\nWinners:\n Archery: Gold - Shihiro\n          Silver - Bob Marley\n          Bronze - Bugs Bunny\n Swimming: Gold - Lenny Kravitz\n           Silver - Ruby\n           Bronze - Asterix\n Weightlifting: Gold - Crows\n                Silver - John Lennon\n                Bronze - Lucky Luke\n 100m Sprint: Gold - Jerry Maguire\n              Silver - Lorenna McKennit\n              Bronze - Devian\n 200m Freestyle: Gold - Peque\n                 Silver - Alice\n                 Bronze - Atreyo\n 3000m Steeplechase: Gold - Simón Bolívar\n                     Silver - Sophy\n                     Bronze - Che Guevara\n Discus Throw: Gold - Goku\n               Silver - Buda\n               Bronze - Beth                    \n*/\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/javascript/hectorio23.js",
    "content": "// Autor:  Héctor Adán\n// GitHub: https://github.com/hectorio23\n\n/*\n * EJERCICIO:\n * ¡Los JJOO de París 2024 han comenzado!\n * Crea un programa que simule la celebración de los juegos.\n * El programa debe permitir al usuario registrar eventos y participantes,\n * realizar la simulación de los eventos asignando posiciones de manera aleatoria\n * y generar un informe final. Todo ello por terminal.\n * Requisitos:\n * 1. Registrar eventos deportivos.\n * 2. Registrar participantes por nombre y país.\n * 3. Simular eventos de manera aleatoria en base a los participantes (mínimo 3).\n * 4. Asignar medallas (oro, plata y bronce) basándose en el resultado del evento.\n * 5. Mostrar los ganadores por cada evento.\n * 6. Mostrar el ranking de países según el número de medallas.\n * Acciones:\n * 1. Registro de eventos.\n * 2. Registro de participantes.\n * 3. Simulación de eventos.\n * 4. Creación de informes.\n * 5. Salir del programa.\n*/\nclass Participant {\n    constructor(name, country) {\n        this.name = name;\n        this.country = country;\n    }\n}\n\nclass Event {\n    constructor(name) {\n        this.name = name;\n        this.participants = [];\n    }\n}\n\nclass OlympicGames {\n    constructor() {\n        this.events = [];\n        this.medalTally = new Map();\n    }\n\n    registerEvent() {\n        const eventName = prompt(\"Ingrese el nombre del evento:\");\n        this.events.push(new Event(eventName));\n    }\n\n    registerParticipant() {\n        const eventName = prompt(\"Ingrese el nombre del evento:\");\n        const event = this.events.find(e => e.name === eventName);\n\n        if (event) {\n            const participantName = prompt(\"Ingrese el nombre del participante:\");\n            const country = prompt(\"Ingrese el país del participante:\");\n            event.participants.push(new Participant(participantName, country));\n        } else {\n            console.log(\"Evento no encontrado.\");\n        }\n    }\n\n    simulateEvent() {\n        for (const event of this.events) {\n            if (event.participants.length >= 3) {\n                const shuffledParticipants = event.participants.slice().sort(() => 0.5 - Math.random());\n\n                console.log(`Resultados del evento ${event.name}:`);\n                console.log(`Oro: ${shuffledParticipants[0].name} (${shuffledParticipants[0].country})`);\n                console.log(`Plata: ${shuffledParticipants[1].name} (${shuffledParticipants[1].country})`);\n                console.log(`Bronce: ${shuffledParticipants[2].name} (${shuffledParticipants[2].country})`);\n\n                this.medalTally.set(shuffledParticipants[0].country, (this.medalTally.get(shuffledParticipants[0].country) || 0) + 3);\n                this.medalTally.set(shuffledParticipants[1].country, (this.medalTally.get(shuffledParticipants[1].country) || 0) + 2);\n                this.medalTally.set(shuffledParticipants[2].country, (this.medalTally.get(shuffledParticipants[2].country) || 0) + 1);\n            } else {\n                console.log(`El evento ${event.name} no tiene suficientes participantes.`);\n            }\n        }\n    }\n\n    displayMedalTally() {\n        console.log(\"\\nRanking de Medallas por País:\");\n        const sortedTally = Array.from(this.medalTally.entries()).sort((a, b) => b[1] - a[1]);\n        for (const [country, points] of sortedTally) {\n            console.log(`${country}: ${points} puntos`);\n        }\n    }\n\n    run() {\n        while (true) {\n            console.log(\"\\n1. Registro de eventos\\n2. Registro de participantes\\n3. Simulación de eventos\\n4. Creación de informes\\n5. Salir\");\n            const option = parseInt(prompt(\"Seleccione una opción:\"), 10);\n\n            if (option === 1) {\n                this.registerEvent();\n            } else if (option === 2) {\n                this.registerParticipant();\n            } else if (option === 3) {\n                this.simulateEvent();\n            } else if (option === 4) {\n                this.displayMedalTally();\n            } else if (option === 5) {\n                break;\n            } else {\n                console.log(\"Opción inválida.\");\n            }\n        }\n    }\n}\n\n// Inicializa el programa\n(() => {\n    const games = new OlympicGames();\n    games.run();\n})();\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n_______________________________________________________\n#31 * SIMULADOR JUEGOS OLÍMPICOS\n-------------------------------------------------------\n* EJERCICIO:\n* ¡Los JJOO de París 2024 han comenzado!\n* Crea un programa que simule la celebración de los juegos.\n* El programa debe permitir al usuario registrar eventos y participantes,\n* realizar la simulación de los eventos asignando posiciones de manera aleatoria\n* y generar un informe final. Todo ello por terminal.\n * Requisitos:\n * 1. Registrar eventos deportivos.\n * 2. Registrar participantes por nombre y país.\n * 3. Simular eventos de manera aleatoria en base a los participantes (mínimo 3).\n * 4. Asignar medallas (oro, plata y bronce) basándose en el resultado del evento.\n * 5. Mostrar los ganadores por cada evento.\n * 6. Mostrar el ranking de países según el número de medallas.\n * Acciones:\n * 1. Registro de eventos.\n * 2. Registro de participantes.\n * 3. Simulación de eventos.\n * 4. Creación de informes.\n * 5. Salir del programa.\n*/\n// ________________________________________________________\n\nconst readline = require('readline');\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nconst GlobalConstants = {\n    MEDALS: ['🥇 Oro', '🥈 Plata', '🥉 Bronce'],\n    MENU: `\nSIMULADOR JUEGOS OLÍMPICOS:\n--------------------------------------------------\n| 1. Registrar evento        | 4. Crear informes |  \n| 2. Registrar participante  | 5. Salir          |\n| 3. Simulación de eventos   |                   |\n--------------------------------------------------`\n};\n\nconst data = {\n    events: [],\n    participants: [],\n    simulations: []\n};\n\nfunction getInput(promptText, callback, type = \"string\") {\n    rl.question(promptText, function processInput(input) {\n        if (!input || input.trim() === \"\") {\n            rl.question(\"La entrada no puede estar vacía. Intente de nuevo: \", processInput);\n            return;\n        }\n\n        if (type === \"number\") {\n            const numValue = Number(input.trim());\n            if (isNaN(numValue)) {\n                rl.question(\"Por favor ingresa un número válido: \", processInput);\n                return;\n            }\n            callback(numValue);\n            return;\n        }\n        \n        callback(input.trim());\n    });\n}\n\nfunction closeInput() {\n    rl.close();\n}\n\nconst Events = {\n    addEvent(onComplete) {\n        getInput(\"Deporte: \", (sport) => {\n            data.events.push(sport);\n            console.log(`${sport} fue agregado`);\n            onComplete();\n        });\n    }\n};\n\nconst Participants = {\n    addParticipant(onComplete) {\n        if (data.events.length === 0) {\n            console.log(\"No existe evento en cuál participar. Agrega un evento primero.\");\n            onComplete();\n            return;\n        }\n\n        console.log(\"Selecciona el evento donde participará:\");\n        data.events.forEach((event, i) => console.log(`${i}. ${event}`));\n\n        getInput(\"Id del evento: \", (eventId) => {\n            if (eventId < 0 || eventId >= data.events.length) {\n                console.log(\"Id no encontrado.\");\n                onComplete();\n                return;\n            }\n\n            getInput(\"Nombre del participante: \", (name) => {\n                getInput(\"País del participante: \", (country) => {\n                    data.participants.push({ name, country, eventId });\n                    console.log(`${name} fue agregado`);\n                    onComplete();\n                });\n            });\n        }, \"number\");\n    }\n};\n\nconst Simulation = {\n    startSimulation() {\n        if (data.events.length === 0) {\n            console.log(\"Debe haber al menos un evento.\");\n            return;\n        }\n\n        if (data.participants.length < 3) {\n            console.log(\"Debe haber al menos tres participantes.\");\n            return;\n        }\n\n        const results = data.events.map((event, eventId) => {\n            const participantsInEvent = data.participants.filter(p => p.eventId === eventId);\n            if (participantsInEvent.length < 3) {\n                return { event, winners: null };\n            }\n\n            participantsInEvent.forEach(p => (p.score = Math.floor(Math.random() * 100)));\n            participantsInEvent.sort((a, b) => b.score - a.score);\n            participantsInEvent.slice(0, 3).forEach((p, i) => (p.medal = GlobalConstants.MEDALS[i]));\n            return { event, winners: participantsInEvent.slice(0, 3) };\n        });\n\n        data.simulations.push(results);\n        console.log(`Simulación #${data.simulations.length} creada.`);\n    }\n};\n\nconst Reports = {\n    generateReport() {\n        if (data.simulations.length === 0) {\n            console.log(\"Aún no hay simulaciones creadas.\");\n            return;\n        }\n\n        data.simulations.forEach((simulation, index) => {\n            console.log(`\\nSimulación #${index + 1}`);\n            simulation.forEach(({ event, winners }) => {\n                console.log(`\\nEvento: ${event}`);\n                if (!winners) {\n                    console.log(\"Cancelado por falta de participantes.\");\n                    return;\n                }\n\n                winners.forEach(({ name, country, score, medal }, i) => {\n                    console.log(`${i + 1}. ${name} (${country}) -> Puntos: ${score}, Medalla: ${medal}`);\n                });\n            });\n        });\n    }\n};\n\nfunction showMenu() {\n    console.log(GlobalConstants.MENU);\n    getInput(\"Opción: \", (option) => {\n        switch (option) {\n            case \"1\":\n                Events.addEvent(() => showMenu());\n                break;\n            case \"2\":\n                Participants.addParticipant(() => showMenu());\n                break;\n            case \"3\":\n                Simulation.startSimulation();\n                showMenu();\n                break;\n            case \"4\":\n                Reports.generateReport();\n                showMenu();\n                break;\n            case \"5\":\n                console.log(\"Adiós.\");\n                closeInput();\n                break;\n            default:\n                console.log(\"Selecciona una opción válida (1-5).\");\n                showMenu();\n        }\n    });\n}\n\nshowMenu()\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/javascript/nlarrea.js",
    "content": "/*\n * EJERCICIO:\n * ¡Los JJOO de París 2024 han comenzado!\n * Crea un programa que simule la celebración de los juegos.\n * El programa debe permitir al usuario registrar eventos y participantes,\n * realizar la simulación de los eventos asignando posiciones de manera aleatoria\n * y generar un informe final. Todo ello por terminal.\n * Requisitos:\n * 1. Registrar eventos deportivos.\n * 2. Registrar participantes por nombre y país.\n * 3. Simular eventos de manera aleatoria en base a los participantes (mínimo 3).\n * 4. Asignar medallas (oro, plata y bronce) basándose en el resultado del evento.\n * 5. Mostrar los ganadores por cada evento.\n * 6. Mostrar el ranking de países según el número de medallas.\n * Acciones:\n * 1. Registro de eventos.\n * 2. Registro de participantes.\n * 3. Simulación de eventos.\n * 4. Creación de informes.\n * 5. Salir del programa.\n */\n\nconst readline = require('readline');\n\nconst rl = readline.createInterface({\n\tinput: process.stdin,\n\toutput: process.stdout,\n});\n\nclass Participant {\n\tconstructor(name, country) {\n\t\tthis.name = name;\n\t\tthis.country = country;\n\t}\n\n\tequals(other) {\n\t\tif (other instanceof Participant) {\n\t\t\treturn this.name === other.name && this.country === other.country;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\thashCode(other) {\n\t\treturn `${this.name} ${this.country}`.hashCode();\n\t}\n}\n\nclass Olympics {\n\tconstructor() {\n\t\tthis.events = [];\n\t\tthis.participants = {};\n\t\tthis.results = {};\n\t\tthis.countries = {};\n\t}\n\n\taddEvent() {\n\t\trl.question('Introducir el nombre del evento:\\n > ', (inputEvent) => {\n\t\t\tconst event = inputEvent.trim();\n\n\t\t\tif (this.events.includes(event)) {\n\t\t\t\tconsole.log(\n\t\t\t\t\t`El evento '${event}' ya ha sido añadido anteriormente.`\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tthis.events.push(event);\n\t\t\t\tconsole.log(`El evento '${event}' ha sido añadido.`);\n\t\t\t}\n\n\t\t\tmain();\n\t\t});\n\t}\n\n\taddParticipant() {\n\t\tif (this.events.length === 0) {\n\t\t\tconsole.log(\n\t\t\t\t'No existen eventos todavía. Espera a que haya alguno para inscribirte!'\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\t// Get participant's information\n\t\trl.question(\n\t\t\t'Introduce el nombre del participante:\\n > ',\n\t\t\t(inputName) => {\n\t\t\t\tconst name = inputName.trim();\n\n\t\t\t\trl.question(\n\t\t\t\t\t'Introduce el país del participante:\\n > ',\n\t\t\t\t\t(inputCountry) => {\n\t\t\t\t\t\tconst country = inputCountry.trim();\n\t\t\t\t\t\tconst participant = new Participant(name, country);\n\n\t\t\t\t\t\t// Register the participant in an event\n\t\t\t\t\t\tconsole.log('\\nMENÚ DE OPCIONES');\n\t\t\t\t\t\tconsole.log('----------------');\n\t\t\t\t\t\tfor (const index in this.events) {\n\t\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t\t`${parseInt(index) + 1}. ${\n\t\t\t\t\t\t\t\t\tthis.events[parseInt(index)]\n\t\t\t\t\t\t\t\t}`\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\trl.question(\n\t\t\t\t\t\t\t'Selecciona en qué evento deseas participar:\\n > ',\n\t\t\t\t\t\t\t(eventChoice) => {\n\t\t\t\t\t\t\t\tconst event =\n\t\t\t\t\t\t\t\t\tthis.events[parseInt(eventChoice) - 1];\n\n\t\t\t\t\t\t\t\tif (!event) {\n\t\t\t\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t\t\t\t`Debes introducir un número entre [1-${this.events.length}]!`\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\t\tObject.keys(\n\t\t\t\t\t\t\t\t\t\t\tthis.participants\n\t\t\t\t\t\t\t\t\t\t).includes(event) &&\n\t\t\t\t\t\t\t\t\t\tthis.participants[event].includes(\n\t\t\t\t\t\t\t\t\t\t\tparticipant\n\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t\t\t\t\t`El participante ${name} de ${country} ya está registrado en el evento deportivo ${event}`\n\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\t\t\t!Object.keys(\n\t\t\t\t\t\t\t\t\t\t\t\tthis.participants\n\t\t\t\t\t\t\t\t\t\t\t).includes(event)\n\t\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\t\tthis.participants[event] = [];\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tthis.participants[event].push(\n\t\t\t\t\t\t\t\t\t\t\tparticipant\n\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t\t\t\t\t`El participante ${name} de ${country} se ha registrado en ${event}`\n\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tmain();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\t\t);\n\t}\n\n\tsimulate() {\n\t\tconst randomSample = (list, quantity) => {\n\t\t\tconst selectedItems = [];\n\t\t\tlet listCopy = [...list];\n\t\t\twhile (selectedItems.length < quantity) {\n\t\t\t\t// Update maxValue to match the length of the list\n\t\t\t\tlet maxValue = listCopy.length;\n\t\t\t\t// Select a random index for the list -> [0, maxValue)\n\t\t\t\tconst index = Math.floor(Math.random() * (maxValue - 0) + 0);\n\t\t\t\t// Remove the selected index and append that item to the selectedItems\n\t\t\t\tselectedItems.push(...listCopy.splice(index, 1));\n\t\t\t}\n\t\t\treturn selectedItems;\n\t\t};\n\n\t\tif (this.events.length === 0) {\n\t\t\tconsole.log('Aún no hay eventos registrados');\n\t\t\treturn;\n\t\t}\n\n\t\tfor (const event of this.events) {\n\t\t\tif (\n\t\t\t\t!Object.keys(this.participants).includes(event) ||\n\t\t\t\tthis.participants[event].length < 3\n\t\t\t) {\n\t\t\t\tconsole.log(\n\t\t\t\t\t`\\nNo hay participantes suficientes para simular el evento '${event}'...`\n\t\t\t\t);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Get Gold, Silver and Bronze randomly\n\t\t\tconst eventParticipants = randomSample(\n\t\t\t\tthis.participants[event],\n\t\t\t\t3\n\t\t\t);\n\n\t\t\tconst [gold, silver, bronze] = eventParticipants;\n\t\t\tconst winners = { gold, silver, bronze };\n\t\t\tthis.results[event] = winners;\n\n\t\t\t// Update each country's medal counter\n\t\t\tthis.updateCountryResults(gold.country, 'gold');\n\t\t\tthis.updateCountryResults(silver.country, 'silver');\n\t\t\tthis.updateCountryResults(bronze.country, 'bronze');\n\n\t\t\tthis.printResults(event, winners);\n\t\t}\n\n\t\tmain();\n\t}\n\n\twriteSummary() {\n\t\tconsole.log('\\nINFORME DE LOS JJOO');\n\t\tconsole.log('-------------------\\n');\n\n\t\tif (!this.results) {\n\t\t\tconsole.log('No hay resultados registrados');\n\t\t} else {\n\t\t\tfor (const event in this.results) {\n\t\t\t\tthis.printResults(event, this.results[event]);\n\t\t\t}\n\t\t}\n\n\t\tif (!this.countries) {\n\t\t\tconsole.log('No hay medallas por país registradas');\n\t\t} else {\n\t\t\tconsole.log('RESULTADOS DEL EVENTO POR PAÍS:');\n\t\t\tfor (const country in this.countries) {\n\t\t\t\tconsole.log(`${country}:`);\n\t\t\t\tconsole.log(`  ${this.countries[country].gold} Oro`);\n\t\t\t\tconsole.log(`  ${this.countries[country].silver} Plata`);\n\t\t\t\tconsole.log(`  ${this.countries[country].bronze} Bronce`);\n\t\t\t}\n\t\t}\n\n\t\tmain();\n\t}\n\n\tupdateCountryResults(country, medal) {\n\t\tif (!Object.keys(this.countries).includes(country)) {\n\t\t\tthis.countries[country] = { gold: 0, silver: 0, bronze: 0 };\n\t\t}\n\n\t\tthis.countries[country][medal] += 1;\n\t}\n\n\tprintResults(event, winners) {\n\t\tconsole.log(`RESULTADOS DEL EVENTO:`, event);\n\t\tconsole.log(`Oro: ${winners.gold.name} (${winners.gold.country})`);\n\t\tconsole.log(\n\t\t\t`Plata: ${winners.silver.name} (${winners.silver.country})`\n\t\t);\n\t\tconsole.log(\n\t\t\t`Bronce: ${winners.bronze.name} (${winners.bronze.country})\\n`\n\t\t);\n\t}\n}\n\nconst jjoo = new Olympics();\nfunction main() {\n\tconst options = [\n\t\t'Registro de eventos',\n\t\t'Registro de participantes',\n\t\t'Simulación de eventos',\n\t\t'Creación de informes',\n\t\t'Salir del programa',\n\t];\n\n\tconsole.log('\\nMENÚ DE OPCIONES');\n\tconsole.log('----------------');\n\n\tfor (const index in options) {\n\t\tconsole.log(`${parseInt(index) + 1}. ${options[index]}`);\n\t}\n\n\trl.question('Selecciona una opción:\\n > ', (option) => {\n\t\tswitch (option) {\n\t\t\tcase '1':\n\t\t\t\tconsole.log();\n\t\t\t\tjjoo.addEvent();\n\t\t\t\tbreak;\n\t\t\tcase '2':\n\t\t\t\tconsole.log();\n\t\t\t\tjjoo.addParticipant();\n\t\t\t\tbreak;\n\t\t\tcase '3':\n\t\t\t\tconsole.log();\n\t\t\t\tjjoo.simulate();\n\t\t\t\tbreak;\n\t\t\tcase '4':\n\t\t\t\tconsole.log();\n\t\t\t\tjjoo.writeSummary();\n\t\t\t\tbreak;\n\t\t\tcase '5':\n\t\t\t\tconsole.log();\n\t\t\t\tconsole.log('Saliendo del programa...');\n\t\t\t\trl.close();\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tconsole.log(\n\t\t\t\t\t`Opción no válida. Introduce un valor entre [1-${options.length}]!`\n\t\t\t\t);\n\t\t\t\tmain();\n\t\t}\n\t});\n}\n\nmain();\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/javascript/pedamoci.js",
    "content": "import  readline  from \"readline\"\n\nfunction shuffled(array) {\n  const result = [...array];\n  for (let i = result.length - 1; i > 0; i--) {\n    const j = Math.floor(Math.random() * (i + 1));\n    [result[i], result[j]] = [result[j], result[i]];\n  }\n  return result;\n}\n\nfunction getMedalCounts(m) {\n  return {\n    Gold: Number(m.Gold ?? 0),\n    Silver: Number(m.Silver ?? 0),\n    Bronze: Number(m.Bronze ?? 0)\n  };\n}\n\nfunction sortRanking(rankingObj) {\n  return Object.entries(rankingObj)\n    .map(([Country, medals]) => {\n      const { Gold, Silver, Bronze } = getMedalCounts(medals);\n      return { Country, Gold, Silver, Bronze };\n    })\n    .sort((a, b) =>\n      (b.Gold - a.Gold) || (b.Silver - a.Silver) || (b.Bronze - a.Bronze)\n    );\n}\n\nclass Event {\n  constructor() {\n    this.events = []\n    this.participants = {}\n    this.results = {}\n  }\n\n  addEvent(nameEvent) {\n    if (!this.events.includes(nameEvent)) {\n      this.events.push(nameEvent)\n      this.participants[nameEvent] = []\n      console.log(\"The event has been created\")\n    } else console.warn(\"Event already exist\")\n  }\n\n  addParticipant(nameEvent, idParticipant) {\n    if (!this.participants[nameEvent].includes(idParticipant)) {\n      this.participants[nameEvent].push(idParticipant)\n    } else console.warn(\"Participant already added to the event\")\n  }\n\n  addResults(nameEvent, idParticipants) {\n    this.results[nameEvent] = idParticipants\n  }\n}\n\nclass Participant {\n  constructor() {\n    this.participants = {}\n  }\n\n  addParticipant(id, name, country) {\n    if (!this.participants[id]) {\n      this.participants[id] = {'name': name, 'country': country}\n      console.log(\"The participant has been added\")\n    } else console.warn(\"Participant already exist\")\n    \n  }\n}\n\nclass CountryMedals {\n  constructor() {\n    this.countryMedals = {}\n  }\n\n  addCountry(nameCountry) {\n    if (!this.countryMedals[nameCountry]) {\n      this.countryMedals[nameCountry] = {'Gold': 0, 'Silver': 0, 'Bronze': 0}\n    }\n  }\n\n  addMedal(nameCountry, typeMedal) {\n    if (!!this.countryMedals[nameCountry]) {\n      this.countryMedals[nameCountry][typeMedal] += 1\n    } else console.warn(\"The country has not been added\")\n  }\n}\n\nclass OlimpicsManager {\n  constructor() {\n    this.events = new Event()\n    this.participants = new Participant()\n    this.medals = new CountryMedals()\n  }\n\n  addEvent(nameEvent) {\n    this.events.addEvent(nameEvent)\n  }\n\n  addParticipant(idParticipant, name, country) {\n    this.participants.addParticipant(idParticipant, name, country)\n    this.medals.addCountry(country)\n  }\n\n  addParticipantToEvent(nameEvent, idParticipant) {\n    this.events.addParticipant(nameEvent, idParticipant)\n  }\n\n  simulateEvent(nameEvent) {\n    if (!this.events.events.includes(nameEvent)) {console.warn(\"The event has not been created\"); return}\n    if (!!this.events.results[nameEvent]) {console.warn(\"The event has already been simulated\"); return}\n\n    const participants = this.events.participants[nameEvent]\n\n    if (participants.length < 3) {console.warn(\"Three participants are needed to simulate this event\"); return}\n\n    let results = shuffled(participants)\n\n    this.events.addResults(nameEvent, results)\n\n    const podium = results.slice(0, 3)\n\n    this.medals.addMedal(this.participants.participants[podium[0]].country, 'Gold')\n    this.medals.addMedal(this.participants.participants[podium[1]].country, 'Silver')\n    this.medals.addMedal(this.participants.participants[podium[2]].country, 'Bronze')\n\n    console.log(\"The simulation of the event has ended\")\n  }\n\n  printResultsEvent(nameEvent) {\n    if (!this.events.results[nameEvent]) {console.warn(\"The event has not been simulated\"); return}\n\n    const participants = [...this.events.results[nameEvent]]\n\n    for (let i = 0; i < participants.length; i++) {\n      console.log(`${i + 1}° Puesto: ${this.participants.participants[participants[i]].name}`)\n    }\n  }\n\n  printRankig() {\n    console.table(sortRanking(this.medals.countryMedals))\n  }\n}\n\nclass Validation {\n  constructor() {\n    this.regexId = /^\\w+$/\n    this.regexEvent = /^\\w+(\\.?\\s?\\w+)+$/\n    this.regexNames = /^\\p{L}+(?:\\s\\p{L}+)*$/u\n  }\n\n  validateId(id) {\n    if (!this.regexId.test(id)) {\n      console.warn(\"The participant ID is incorrect\")\n    } return true\n  }\n\n  validateNameParticipant(nameParticipant) {\n    if (!this.regexNames.test(nameParticipant)) {\n      console.warn(\"The participant's name is incorrect\")\n    } return true\n  }\n\n  validateCountry(country) {\n    if (!this.regexNames.test(country)) {\n      console.warn(\"The name of the country is incorrect\")\n    } return true\n  }\n\n  validateEvent(event) {\n    if (!this.regexEvent.test(event)) {\n      console.warn(\"The name of the event is incorrect\")\n    } return true\n  }\n}\n\nclass Asks {\n  constructor() {\n    this.rl = readline.createInterface({\n      input: process.stdin,\n      output: process.stdout,\n    });\n  }\n\n  ask(question) {\n    return new Promise((resolve) => {\n      this.rl.question(question, (answer) => resolve(answer));\n    });\n  }\n\n  close() {\n    this.rl.close();\n  }\n}\n\nconst asks = new Asks()\n\nasync function startOlimpics() {\n  const olimpicsManager = new OlimpicsManager()\n  const validation = new Validation()\n\n  let operation = \"\"\n\n  while (operation.toUpperCase() !== 'E') {\n    operation = (await asks.ask(\n      'What operation would you like to perform?\\n' + \n      'AE --> Add event\\n' +\n      'SE --> Simulate event\\n' +\n      'AP --> Add participant\\n' +\n      'RE --> View event classification\\n' +\n      'VR --> See country rankings\\n' +\n      'E --> Exit\\n'\n    )).toUpperCase()\n\n    let event = \"\"; let id = \"\"; let participant = \"\"; let country = \"\"\n  \n    switch (operation) {\n      case 'AE':\n        event = await asks.ask(\"Enter the name of the event: \")\n        if (validation.validateEvent(event)) \n          olimpicsManager.addEvent(event)\n        break;\n  \n      case 'SE':\n        event = await asks.ask(\"Enter the name of the event: \")\n        if (validation.validateEvent(event)) \n          olimpicsManager.simulateEvent(event)\n        break;\n  \n      case 'AP':\n        participant = await asks.ask(\"Enter the participant's name: \")\n        id = await asks.ask(\"Enter the participant ID: \")\n        country = await asks.ask(\"Enter the name of the country: \")\n        event = await asks.ask(\"Enter the name of the event: \")\n  \n        if (\n          validation.validateNameParticipant(participant) &&\n          validation.validateId(id) &&\n          validation.validateCountry(country) &&\n          validation.validateEvent(event)\n        ) {\n          olimpicsManager.addParticipant(id, participant, country)\n          olimpicsManager.addParticipantToEvent(event, id)\n        }\n        break;\n  \n      case 'RE':\n        event = await asks.ask(\"Enter the name of the event: \")\n        if (validation.validateEvent(event)) \n          olimpicsManager.printResultsEvent(event)\n        break;\n  \n      case 'VR':\n        olimpicsManager.printRankig()\n        break;\n    \n      default:break;\n    }\n  }\n\n  asks.close()\n}\nstartOlimpics()"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/javascript/sisaroot.js",
    "content": "// #31 SIMULADOR JUEGOS OLÍMPICOS - SisaRoot\n// Run: node SisaRoot.js\n\nconst readline = require(\"readline\");\nconst rl = readline.createInterface({ input: process.stdin, output: process.stdout });\nconst ask = (q) => new Promise((res) => rl.question(q, res));\n\nconst events = [];\nconst medalTable = {};\n\nconst shuffle = (arr) => {\n    const a = [...arr];\n    for (let i = a.length - 1; i > 0; i--) {\n        const j = (Math.random() * (i + 1)) | 0;\n        [a[i], a[j]] = [a[j], a[i]];\n    }\n    return a;\n};\n\nconst addMedal = (country, type) => {\n    if (!medalTable[country]) medalTable[country] = { gold: 0, silver: 0, bronze: 0 };\n    medalTable[country][type]++;\n};\n\nasync function registerEvent() {\n    const name = (await ask(\"Nombre del evento: \")).trim();\n    if (!name) { console.log(\"Invalido.\"); return; }\n    if (events.some((e) => e.name.toLowerCase() === name.toLowerCase())) { console.log(`'${name}' ya existe.`); return; }\n    events.push({ name, participants: [] });\n    console.log(`Evento '${name}' registrado.`);\n}\n\nasync function registerParticipant() {\n    if (!events.length) { console.log(\"No hay eventos.\"); return; }\n    events.forEach((e, i) => console.log(`  ${i + 1}. ${e.name}`));\n    const idx = parseInt(await ask(\"Selecciona número: \"), 10);\n    if (isNaN(idx) || idx < 1 || idx > events.length) { console.log(\"Invalido.\"); return; }\n    const ev = events[idx - 1];\n    const name = (await ask(\"Nombre: \")).trim();\n    const country = (await ask(\"País: \")).trim();\n    ev.participants.push({ name, country });\n    console.log(`'${name} (${country})' añadido a '${ev.name}'.`);\n}\n\nfunction simulateEvents() {\n    if (!events.length) { console.log(\"No hay eventos.\"); return; }\n    for (const ev of events) {\n        console.log(`\\n=== Simulando: ${ev.name} ===`);\n        if (ev.participants.length < 3) { console.log(\"  Necesita >=3 participantes. Saltando.\"); continue; }\n        const [g, s, b] = shuffle(ev.participants);\n        console.log(`  🥇 ${g.name} (${g.country})\\n  🥈 ${s.name} (${s.country})\\n  🥉 ${b.name} (${b.country})`);\n        addMedal(g.country, \"gold\"); addMedal(s.country, \"silver\"); addMedal(b.country, \"bronze\");\n    }\n}\n\nfunction showReport() {\n    console.log(\"\\n== INFORME FINAL ==\");\n    if (!Object.keys(medalTable).length) { console.log(\"Sin resultados.\"); return; }\n    Object.entries(medalTable)\n        .map(([c, m]) => ({ c, ...m, t: m.gold + m.silver + m.bronze }))\n        .sort((a, b) => b.gold - a.gold || b.silver - a.silver || b.bronze - a.bronze)\n        .forEach((x, i) => console.log(`${i + 1}. ${x.c.padEnd(20)} Oro:${x.gold} Plata:${x.silver} Bronce:${x.bronze} Total:${x.t}`));\n}\n\nasync function main() {\n    while (true) {\n        console.log(\"\\n====== SIMULADOR JJOO ======\\n1. Registrar evento\\n2. Registrar participante\\n3. Simular\\n4. Informe\\n5. Salir\");\n        const opt = (await ask(\"Opción: \")).trim();\n        if (opt === \"1\") await registerEvent();\n        else if (opt === \"2\") await registerParticipant();\n        else if (opt === \"3\") simulateEvents();\n        else if (opt === \"4\") showReport();\n        else if (opt === \"5\") { console.log(\"Hasta luego!\"); rl.close(); break; }\n        else console.log(\"Invalido.\");\n    }\n}\n\nmain();\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/javascript/victor-Casta.js",
    "content": "const readline = require('node:readline')\nconst { stdin: input, stdout: output } = require('node:process')\nconst rl = readline.createInterface({ input, output })\n\nclass OlympicsGames {\n  constructor() {\n    this.events = []\n    this.participants = []\n    this.points = []\n    this.countriesRanking = {}\n  }\n\n  registerEvents() {\n    rl.question('Ingresa el nombre del evento: ', (nameOfEvent) => {\n      const eventName = nameOfEvent.trim().toLowerCase()\n      if (this.events.includes(eventName)) {\n        console.log('El evento ya está registrado')\n      } else {\n        this.events.push(eventName)\n        console.log('Evento registrado con éxito')\n      }\n      program()\n    })\n  }\n\n  registerParticipants() {\n    rl.question('Ingresa el nombre del participante: ', (nameOfParticipant) => {\n      rl.question('Ingresa el nombre del país: ', (countryOfParticipant) => {\n        if (this.events.length <= 0) {\n          console.log('No hay eventos disponibles')\n          program()\n        } else {\n          this.events.map((item, index) => {\n            console.log(`${index}.${item}`)\n          })\n          rl.question('Ingresa un el indice del evento a inscribir: ', (eventUserRegister) => {\n            const participantName = nameOfParticipant.trim().toLowerCase()\n            const participantCountry = countryOfParticipant.trim().toLowerCase()\n            const eventOfParticipant = parseInt(eventUserRegister)\n            const existingParticipant = this.participants.find((item) => item.name === participantName)\n            if (existingParticipant) {\n              console.log('El participante ya está registrado')\n            } else {\n              this.participants.push({\n                name: participantName,\n                country: participantCountry,\n                event: this.events[eventOfParticipant]\n              })\n              console.log('Participante registrado con éxito')\n            }\n            console.log(this.participants)\n            program()\n          })\n        }\n      })\n    })\n  }\n\n  updateCountryMedals(country, medalType) {\n    if (!this.countriesRanking[country]) {\n      this.countriesRanking[country] = { gold: 0, silver: 0, bronze: 0 }\n    }\n    this.countriesRanking[country][medalType]++\n  }\n\n  displayCountryRanking() {\n    const sortedCountries = Object.entries(this.countriesRanking)\n      .sort((a, b) => {\n        const [countryA, medalsA] = a\n        const [countryB, medalsB] = b\n        if (medalsB.gold !== medalsA.gold) return medalsB.gold - medalsA.gold\n        if (medalsB.silver !== medalsA.silver) return medalsB.silver - medalsA.silver\n        return medalsB.bronze - medalsA.bronze\n      })\n\n    console.log('Ranking de países:')\n    sortedCountries.forEach(([country, medals], index) => {\n      console.log(\n        `${index + 1}. ${country} - 🥇 ${medals.gold}, 🥈 ${medals.silver}, 🥉 ${medals.bronze}`\n      )\n    })\n  }\n\n  eventsSimulator() {\n    rl.question('Ingrese el nombre del evento a simular: ', (nameOfEvent) => {\n      const tableOfPoints = []\n      for (let participant of this.participants) {\n        if (\n          participant.event === nameOfEvent.trim().toLocaleLowerCase() &&\n          this.participants.length >= 3\n        ) {\n          const nameOfParticipant = participant.name\n          const country = participant.country\n          let points = Math.round(Math.random() * 11)\n          tableOfPoints.push({\n            participantName: nameOfParticipant,\n            country,\n            points,\n          })\n        } else {\n          console.log('No hay suficientes participantes para este evento')\n          program()\n        }\n      }\n\n      this.points = tableOfPoints.sort((a, b) => b.points - a.points)\n      if (this.points.length >= 3) {\n        console.log('Podio de ganadores')\n        console.log(`🥇 ${this.points[0].country} ${this.points[0].participantName} ${this.points[0].points} puntos`)\n        this.updateCountryMedals(this.points[0].country, 'gold')\n\n        console.log(`🥈 ${this.points[1].country} ${this.points[1].participantName} ${this.points[1].points} puntos`)\n        this.updateCountryMedals(this.points[1].country, 'silver')\n\n        console.log(`🥉 ${this.points[2].country} ${this.points[2].participantName} ${this.points[2].points} puntos`)\n        this.updateCountryMedals(this.points[2].country, 'bronze')\n      }\n      program()\n    })\n  }\n\n  finalReport() {\n    console.log('Reporte final de medallas:')\n    this.displayCountryRanking()\n    program()\n  }\n}\n\nconsole.log('¡JJOO de París 2024!')\nconst newOlympicsGames = new OlympicsGames()\n\nfunction program() {\n  console.log('1. Registrar eventos')\n  console.log('2. Registrar participantes')\n  console.log('3. Simular eventos')\n  console.log('4. Reporte final')\n  console.log('0. Salir')\n\n  rl.question('Ingresa una opción: ', (response) => {\n    switch (response) {\n      case '1':\n        newOlympicsGames.registerEvents()\n        break\n      case '2':\n        newOlympicsGames.registerParticipants()\n        break\n      case '3':\n        newOlympicsGames.eventsSimulator()\n        break\n      case '4':\n        newOlympicsGames.finalReport()\n        break\n      case '0':\n        rl.close()\n        break\n      default:\n        console.log('Opción inválida')\n        program()\n        break\n    }\n  })\n}\n\nprogram()"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/kotlin/blackriper.kt",
    "content": "import com.jakewharton.picnic.table\r\nimport kotlinx.coroutines.*\r\nimport kotlinx.coroutines.flow.*\r\nimport java.util.UUID\r\nimport java.time.Duration\r\n\r\n/*\r\nlibrerias extra\r\ncorutinas : https://github.com/Kotlin/kotlinx.coroutines\r\ntablas en consola : https://github.com/Jakewharton/picnic\r\n*/\r\n\r\n\r\n/* datos auxiliares y globales */\r\n\r\nval country= buildMap<Int,String> {\r\n   put(1,\"United States\")\r\n   put(2,\"France\")\r\n   put(3,\"Japan\")\r\n   put(4,\"China\")\r\n   put(5,\"Russia\")\r\n   put(6,\"Brazil\")\r\n   put(7,\"México\")\r\n   put(8,\"Uruguay\")\r\n   put(9,\"Argentina\")\r\n   put(10,\"Colombia\")\r\n   put(11,\"Spain\")\r\n   put(12,\"Germany\")\r\n   put(13,\"United Kingdom\")\r\n}\r\n\r\nval medalsList=country.values.toList().map { CountryMedals(it)}\r\nvar events: List<SportingEvent> =emptyList()\r\n\r\n/* defininicion de entidades y interfaces */\r\n\r\ndata class CountryMedals constructor(\r\n    val countryName:String,\r\n    var gold:Int=0,\r\n    var silver:Int=0,\r\n    var bronze:Int=0\r\n)\r\n\r\n\r\ndata class SportingEvent constructor(\r\n    val id:UUID=UUID.randomUUID(),\r\n    val title:String,\r\n    var players:MutableList<Player> = mutableListOf()\r\n    )\r\n\r\ndata class Player constructor(\r\n    val name:String,\r\n    val idEvent:UUID,\r\n    val country : String,\r\n    var score:Int=0\r\n)\r\n\r\ninterface ForEvents{\r\n  suspend fun registerEvent()\r\n  suspend fun simulateEvents()\r\n}\r\n\r\ninterface ForPlayers{\r\n    suspend fun registerPlayer()\r\n}\r\n\r\n\r\n/* implementacion de repositorios */\r\n\r\nclass RepositoryEvents:ForEvents {\r\n\r\n    override suspend fun registerEvent(): Unit = coroutineScope {\r\n        val eventsRegitered=async {\r\n            val eventsRegis = mutableListOf<SportingEvent>()\r\n            var option: String = \"\"\r\n            while (option != \"N\") {\r\n                println(\"Enter a event name\")\r\n                val title = readLine() ?: \"\"\r\n                SportingEvent(title = title)\r\n                eventsRegis.add(SportingEvent(title = title))\r\n                println(\"Do you want to continue? (Y/N)\")\r\n                option = readLine()?.let { it.uppercase() } ?: \"N\"\r\n            }\r\n            eventsRegis\r\n        }\r\n        events=eventsRegitered.await()\r\n    }\r\n\r\n\r\n    override suspend fun simulateEvents(): Unit = coroutineScope {\r\n           println(\"Starting events\")\r\n           events.filter { it.players.size >= 3 }.forEach {\r\n              launch {\r\n                  it.players.forEach {\r\n                      delay(1000L)\r\n                      it.score = (1..100).random()\r\n                  }\r\n                  val winners = it.players.sortedByDescending { it.score }.take(3)\r\n                  var i = 0\r\n                  var listmedals = listOf(\"Gold\", \"Silver\", \"Bronze\")\r\n\r\n                  println(\"\"\"Winners of ${it.title} are:\"\"\")\r\n                  val results = table {\r\n                      cellStyle {\r\n                          border = true\r\n                          paddingLeft = 1\r\n                          paddingRight = 1\r\n                      }\r\n                      row(\"Medal\", \"Name\", \"Country\", \"Score\")\r\n                      winners.forEach {\r\n                          updateMedalsList(listmedals[i], it.country)\r\n                          row(listmedals[i++], it.name, it.country, it.score)\r\n                      }\r\n                  }\r\n                  println(results)\r\n              }\r\n\r\n             }\r\n        }\r\n\r\n       private fun updateMedalsList(medal: String, country: String) {\r\n        medalsList.run {\r\n            when (medal) {\r\n                \"Gold\" -> this.first { it.countryName == country }.gold++\r\n                \"Silver\" -> this.first { it.countryName == country }.silver++\r\n                \"Bronze\" -> this.first { it.countryName == country }.bronze++\r\n                else -> {\r\n                    println(\"Invalid medal type\")\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n\r\n    class RepositoryPlayers : ForPlayers {\r\n     \r\n        override suspend fun registerPlayer(): Unit = coroutineScope {\r\n            if (events.isEmpty()){\r\n                println(\"no available events for registering players\")\r\n                return@coroutineScope\r\n            }\r\n            launch { getPlayers() }\r\n        }\r\n\r\n        private suspend fun getPlayers(){\r\n            var option: String = \"\"\r\n            while (option != \"N\") {\r\n                println(\"Enter a player name\")\r\n                val name = readLine() ?: \"\"\r\n                val country = getCountry()\r\n                val idEvent = getEventID()\r\n                events.first { it.id == idEvent }.players.add(Player(name, idEvent, country))\r\n                println(\"Do you want to continue? (Y/N)\")\r\n                option = readLine()?.let { it.uppercase() } ?: \"N\"\r\n             }\r\n        }\r\n\r\n\r\n        private fun getCountry(): String {\r\n            country.forEach { indx, cou ->\r\n                println(\"$indx - $cou\")\r\n            }\r\n            println(\"Choose a country: \")\r\n            val ind = readLine()!!.toInt()\r\n            return country[ind]?:\"United States\"\r\n        }\r\n\r\n        private fun getEventID(): UUID {\r\n            events.forEachIndexed { indx, event ->\r\n                println(\"${indx+1} - ${event.title} - ${event.players.size} players\")\r\n            }\r\n            println(\"Choose an event: \")\r\n            val idx = readLine()!!.toInt()\r\n            return events[idx-1].id\r\n        }\r\n\r\n    }\r\n\r\n\r\nclass JJOOController {\r\n    private val repositoryPlayers = RepositoryPlayers()\r\n    private val repositoryEvents = RepositoryEvents()\r\n\r\n    suspend fun showMenu() {\r\n        var option: Int = 0\r\n        while (option != 5) {\r\n            println(\"Welcome to JJOO 2024\")\r\n            println(\"1. Register event\")\r\n            println(\"2. Register player\")\r\n            println(\"3. Start events\")\r\n            println(\"4. Get list of countries with medals\")\r\n            println(\"5. Exit\")\r\n            println(\"Chosse a option\")\r\n            option = readLine()!!.toInt()\r\n            when (option) {\r\n                1 -> repositoryEvents.registerEvent()\r\n                2 -> repositoryPlayers.registerPlayer()\r\n                3 -> repositoryEvents.simulateEvents()\r\n                4 -> getMedalsList()\r\n                5 -> println(\"Good bye\")\r\n                else -> println(\"Invalid option\")\r\n            }\r\n        }\r\n\r\n    }\r\n\r\n   private fun getMedalsList() {\r\n       val results= table {\r\n            cellStyle {\r\n                border = true\r\n                paddingLeft = 1\r\n                paddingRight = 1\r\n            }\r\n            row(\"Country\", \"Gold\", \"Silver\", \"Bronze\")\r\n            medalsList.forEach {\r\n                row(it.countryName, it.gold, it.silver, it.bronze)\r\n            }\r\n        }\r\n       println(results)\r\n    }\r\n  }\r\n\r\n\r\n\r\n\r\n fun main()= runBlocking<Unit> {\r\n  val jjoApp=JJOOController()\r\n  jjoApp.showMenu()\r\n\r\n}"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/kotlin/eulogioep.kt",
    "content": "import kotlin.random.Random\n\n// Definición de las clases principales\ndata class Evento(val nombre: String, val participantes: MutableList<Participante> = mutableListOf())\ndata class Participante(val nombre: String, val pais: String, var medallas: MutableMap<String, Int> = mutableMapOf())\ndata class Resultado(val oro: Participante, val plata: Participante, val bronce: Participante)\n\n// Clase principal que maneja la simulación de los Juegos Olímpicos\nclass JuegosOlimpicos {\n    private val eventos = mutableListOf<Evento>()\n    private val participantes = mutableListOf<Participante>()\n\n    // Función para registrar un nuevo evento\n    fun registrarEvento(nombre: String) {\n        eventos.add(Evento(nombre))\n        println(\"Evento '$nombre' registrado correctamente.\")\n    }\n\n    // Función para registrar un nuevo participante\n    fun registrarParticipante(nombre: String, pais: String) {\n        participantes.add(Participante(nombre, pais))\n        println(\"Participante '$nombre' de '$pais' registrado correctamente.\")\n    }\n\n    // Función para simular todos los eventos\n    fun simularEventos() {\n        for (evento in eventos) {\n            // Seleccionar aleatoriamente al menos 3 participantes para el evento\n            val participantesEvento = participantes.shuffled().take(maxOf(3, Random.nextInt(participantes.size)))\n            evento.participantes.addAll(participantesEvento)\n\n            // Simular el evento y asignar medallas\n            val resultado = simularEvento(evento)\n            asignarMedallas(resultado)\n\n            // Mostrar los ganadores del evento\n            mostrarGanadoresEvento(evento, resultado)\n        }\n    }\n\n    // Función para simular un evento individual y determinar los ganadores\n    private fun simularEvento(evento: Evento): Resultado {\n        val ganadores = evento.participantes.shuffled().take(3)\n        return Resultado(ganadores[0], ganadores[1], ganadores[2])\n    }\n\n    // Función para asignar medallas a los ganadores\n    private fun asignarMedallas(resultado: Resultado) {\n        asignarMedalla(resultado.oro, \"oro\")\n        asignarMedalla(resultado.plata, \"plata\")\n        asignarMedalla(resultado.bronce, \"bronce\")\n    }\n\n    // Función auxiliar para asignar una medalla a un participante\n    private fun asignarMedalla(participante: Participante, tipoMedalla: String) {\n        participante.medallas[tipoMedalla] = participante.medallas.getOrDefault(tipoMedalla, 0) + 1\n    }\n\n    // Función para mostrar los ganadores de un evento\n    private fun mostrarGanadoresEvento(evento: Evento, resultado: Resultado) {\n        println(\"\\nResultados del evento: ${evento.nombre}\")\n        println(\"Oro: ${resultado.oro.nombre} (${resultado.oro.pais})\")\n        println(\"Plata: ${resultado.plata.nombre} (${resultado.plata.pais})\")\n        println(\"Bronce: ${resultado.bronce.nombre} (${resultado.bronce.pais})\")\n    }\n\n    // Función para generar y mostrar el ranking de países\n    fun mostrarRankingPaises() {\n        println(\"\\nRanking de países por medallas:\")\n        val rankingPaises = participantes.groupBy { it.pais }\n            .mapValues { (_, participantes) ->\n                participantes.sumOf { it.medallas.values.sum() }\n            }\n            .toList()\n            .sortedByDescending { it.second }\n\n        rankingPaises.forEachIndexed { index, (pais, medallas) ->\n            println(\"${index + 1}. $pais: $medallas medallas\")\n        }\n    }\n}\n\n// Función principal que maneja la interacción con el usuario\nfun main() {\n    val juegos = JuegosOlimpicos()\n    \n    while (true) {\n        println(\"\\n--- Juegos Olímpicos París 2024 ---\")\n        println(\"1. Registrar evento\")\n        println(\"2. Registrar participante\")\n        println(\"3. Simular eventos\")\n        println(\"4. Mostrar ranking de países\")\n        println(\"5. Salir\")\n        print(\"Seleccione una opción: \")\n        \n        when (readLine()) {\n            \"1\" -> {\n                print(\"Ingrese el nombre del evento: \")\n                val nombreEvento = readLine() ?: continue\n                juegos.registrarEvento(nombreEvento)\n            }\n            \"2\" -> {\n                print(\"Ingrese el nombre del participante: \")\n                val nombreParticipante = readLine() ?: continue\n                print(\"Ingrese el país del participante: \")\n                val paisParticipante = readLine() ?: continue\n                juegos.registrarParticipante(nombreParticipante, paisParticipante)\n            }\n            \"3\" -> juegos.simularEventos()\n            \"4\" -> juegos.mostrarRankingPaises()\n            \"5\" -> {\n                println(\"¡Gracias por usar el simulador de Juegos Olímpicos París 2024!\")\n                return\n            }\n            else -> println(\"Opción no válida. Por favor, intente de nuevo.\")\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/kotlin/sisaroot.kt",
    "content": "// #31 SIMULADOR JUEGOS OLÍMPICOS - SisaRoot\n\nimport kotlin.random.Random\n\ndata class Participant(val name: String, val country: String)\ndata class Event(val name: String, val participants: MutableList<Participant> = mutableListOf())\ndata class CountryMedals(val country: String, var gold: Int = 0, var silver: Int = 0, var bronze: Int = 0) {\n    fun total() = gold + silver + bronze\n}\n\nval events = mutableListOf<Event>()\nval medalTable = mutableMapOf<String, CountryMedals>()\n\nfun addMedal(country: String, type: String) {\n    val cm = medalTable.getOrPut(country) { CountryMedals(country) }\n    when (type) { \"gold\" -> cm.gold++; \"silver\" -> cm.silver++; else -> cm.bronze++ }\n}\n\nfun registerEvent() {\n    print(\"Nombre del evento: \")\n    val name = readLine()?.trim() ?: return\n    if (events.any { it.name.equals(name, true) }) { println(\"Ya existe.\"); return }\n    events.add(Event(name)); println(\"Evento '$name' registrado.\")\n}\n\nfun registerParticipant() {\n    if (events.isEmpty()) { println(\"No hay eventos.\"); return }\n    events.forEachIndexed { i, e -> println(\"  ${i+1}. ${e.name}\") }\n    val idx = readLine()?.trim()?.toIntOrNull() ?: 0\n    if (idx < 1 || idx > events.size) { println(\"Invalido.\"); return }\n    val ev = events[idx - 1]\n    print(\"Nombre: \"); val pname = readLine()?.trim() ?: \"\"\n    print(\"País: \"); val country = readLine()?.trim() ?: \"\"\n    ev.participants.add(Participant(pname, country))\n    println(\"'$pname ($country)' añadido a '${ev.name}'.\")\n}\n\nfun simulateEvents() {\n    if (events.isEmpty()) { println(\"No hay eventos.\"); return }\n    for (ev in events) {\n        println(\"\\n=== Simulando: ${ev.name} ===\")\n        if (ev.participants.size < 3) { println(\"  Necesita >=3. Saltando.\"); continue }\n        val s = ev.participants.shuffled(Random)\n        println(\"  🥇 ${s[0].name} (${s[0].country})\")\n        println(\"  🥈 ${s[1].name} (${s[1].country})\")\n        println(\"  🥉 ${s[2].name} (${s[2].country})\")\n        addMedal(s[0].country, \"gold\"); addMedal(s[1].country, \"silver\"); addMedal(s[2].country, \"bronze\")\n    }\n}\n\nfun showReport() {\n    println(\"\\n== INFORME FINAL ==\")\n    if (medalTable.isEmpty()) { println(\"Sin resultados.\"); return }\n    medalTable.values.sortedWith(compareByDescending<CountryMedals>{it.gold}.thenByDescending{it.silver}.thenByDescending{it.bronze})\n        .forEachIndexed { i, c -> println(\"${i+1}. ${c.country.padEnd(20)} Oro:${c.gold} Plata:${c.silver} Bronce:${c.bronze} Total:${c.total()}\") }\n}\n\nfun main() {\n    while (true) {\n        println(\"\\n====== SIMULADOR JJOO ======\\n1. Registrar evento\\n2. Registrar participante\\n3. Simular\\n4. Informe\\n5. Salir\")\n        when (readLine()?.trim()) {\n            \"1\" -> registerEvent(); \"2\" -> registerParticipant()\n            \"3\" -> simulateEvents(); \"4\" -> showReport()\n            \"5\" -> { println(\"Hasta luego!\"); return }\n            else -> println(\"Invalido.\")\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/ocaml/luishendrix92.ml",
    "content": "open Printf;;\n\nRandom.self_init ()\n\n(******************************************************************************)\n(*                                                                            *)\n(*                                 EJERCICIO                                  *)\n(*                                                                            *)\n(*  Los JJOO de París 2024 han comenzado! Crea un programa que simule la ce-  *)\n(*  lebración de los juegos. El programa debe permitir al usuario registrar   *)\n(*  eventos y participantes, realizar la simulación de los eventos asignando  *)\n(*  posiciones de manera aleatorio y generar un informe final. Por terminal.  *)\n(*                                                                            *)\n(*  Requisitos:                                                               *)\n(*  1. Registrar eventos deportivos.                                          *)\n(*  2. Registrar participantes por nombre y país.                             *)\n(*  3. Simular eventos de manera aleatoria en base a los participantes (>2).  *)\n(*  4. Asignar medallas (oro, plata, y bronce) según los resultados.          *)\n(*  5. Mostrar los ganadores por cada evento.                                 *)\n(*  6. Mostrar el ranking de paises segun el numero de medallas.              *)\n(*                                                                            *)\n(*  Acciones:                                                                 *)\n(*  1. Registro de eventos.                                                   *)\n(*  2. Registro de participantes.                                             *)\n(*  3. Simulación de eventos.                                                 *)\n(*  4. Creación de informes.                                                  *)\n(*  5. Salir del programa.                                                    *)\n(*                                                                            *)\n(******************************************************************************)\n\ntype sport =\n  | Swimming\n  | Judo\n  | Archery\n  | Gymnastics\n  | Cycling\n  | Boxing\n  | Track\n  | Diving\n  | Athletism\n\ntype medal =\n  | Bronze\n  | Silver\n  | Gold\n\nclass participant name' country' sport' =\n  object\n    val mutable medals : medal list = []\n    val name : string = name'\n    val country : string = country'\n    val sport : sport = sport'\n    method get_name = name\n    method get_sport = sport\n    method get_country = country\n    method award_medal medal = medals <- medal :: medals\n    method medal_count = List.length medals\n  end\n\nclass event sport' =\n  object\n    val mutable participants : participant list = []\n    val creation_timestamp = Core.Time_float.now ()\n    val mutable concluded = false\n    val sport : sport = sport'\n\n    method add_participant (p : participant) =\n      if List.find_opt (fun p' -> p'#get_name = p#get_name) participants\n         |> Option.is_some\n      then Result.Error (p#get_name ^ \" already participates in the event\")\n      else if p#get_sport <> sport\n      then Result.Error (p#get_name ^ \"'s sport doesn't match event's\")\n      else begin\n        participants <- p :: participants;\n        Result.Ok ()\n      end\n\n    method simulate =\n      if concluded\n      then Result.Error \"This event already concluded.\"\n      else if List.length participants < 3\n      then Result.Error \"Need 3 or more participants to simulate.\"\n      else begin\n        let shuffled = participants |> Array.of_list in\n        Array.shuffle ~rand:Random.int shuffled;\n        let shuffled = Array.to_list shuffled in\n        Core.List.take shuffled 3\n        |> List.iteri (fun i p ->\n          match i with\n          | 0 -> p#award_medal Gold\n          | 1 -> p#award_medal Silver\n          | 2 -> p#award_medal Bronze\n          | _ -> ());\n        concluded <- true;\n        Result.Ok shuffled\n      end\n\n    method get_participants = participants\n  end\n\nlet simulation_report =\n  Result.fold\n    ~error:print_endline\n    ~ok:\n      (List.iteri (fun i (p : participant) ->\n         match i with\n         | 0 -> printf \"%d. 🥇 %s (%s)\\n\" (i + 1) p#get_name p#get_country\n         | 1 -> printf \"%d. 🥈 %s (%s)\\n\" (i + 1) p#get_name p#get_country\n         | 2 -> printf \"%d. 🥉 %s (%s)\\n\" (i + 1) p#get_name p#get_country\n         | _ -> printf \"%d. %s (%s)\\n\" (i + 1) p#get_name p#get_country))\n;;\n\nmodule StringMap = Map.Make (String)\n\nlet _ =\n  (* 1. Registrar eventos y participantes*)\n  let archery = new event Archery in\n  let swimming = new event Swimming in\n  [ new participant \"Baptiste Addis\" \"France\" Archery |> archery#add_participant\n  ; new participant \"Kim Woo-jin\" \"South Korea\" Archery\n    |> archery#add_participant\n  ; new participant \"Florian Unruh\" \"Germany\" Archery |> archery#add_participant\n  ; new participant \"Li Jiaman\" \"China\" Archery |> archery#add_participant\n  ; new participant \"Brady Ellison\" \"USA\" Archery |> archery#add_participant\n  ; new participant \"Thomas ceccon\" \"Italy\" Swimming |> swimming#add_participant\n  ; new participant \"Daniel Wiffen\" \"Ireland\" Swimming\n    |> swimming#add_participant\n  ; new participant \"Leon Manchard\" \"France\" Swimming\n    |> swimming#add_participant\n  ; new participant \"Bobby Finke\" \"USA\" Swimming |> swimming#add_participant\n  ; new participant \"Pan Shanle\" \"China\" Swimming |> swimming#add_participant\n  ]\n  |> List.iter (Result.iter_error print_endline);\n  (* Simular eventos al azar e informe *)\n  print_endline \"Simulation of Archery event:\";\n  simulation_report archery#simulate;\n  print_newline ();\n  print_endline \"Simulation of Swimming event:\";\n  simulation_report swimming#simulate;\n  print_newline ();\n  (* Ranking de países según medallas ganadas *)\n  let roster = archery#get_participants @ swimming#get_participants in\n  roster\n  |> List.map (fun p -> p#get_country, p#medal_count)\n  |> List.fold_left\n       (fun ranking (country, medals) ->\n         StringMap.update\n           country\n           (function\n             | Some count -> Some (count + medals)\n             | None -> Some medals)\n           ranking)\n       StringMap.empty\n  |> StringMap.to_list\n  |> Core.List.stable_sort ~compare:(fun (_, medals_a) (_, medals_b) ->\n    Int.compare medals_b medals_a)\n  |> List.iteri (fun i (country, medals) ->\n    printf \"#%d - Country: %s | Medals: %d\\n\" (i + 1) country medals)\n;;\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/ocaml/sisaroot.ml",
    "content": "(* #31 SIMULADOR JUEGOS OLÍMPICOS - SisaRoot *)\n\nlet () = Random.self_init ()\n\ntype participant = { name: string; country: string }\ntype event = { name: string; mutable participants: participant list }\ntype country_medals = { country: string; mutable gold: int; mutable silver: int; mutable bronze: int }\n\nlet events : event list ref = ref []\nlet medal_table : (string, country_medals) Hashtbl.t = Hashtbl.create 16\n\nlet add_medal country t =\n  let cm = match Hashtbl.find_opt medal_table country with\n    | Some c -> c\n    | None -> let c={country;gold=0;silver=0;bronze=0} in Hashtbl.add medal_table country c; c in\n  (match t with \"gold\"->cm.gold<-cm.gold+1 | \"silver\"->cm.silver<-cm.silver+1 | _->cm.bronze<-cm.bronze+1)\n\nlet shuffle lst =\n  let a = Array.of_list lst in\n  for i = Array.length a - 1 downto 1 do\n    let j = Random.int (i+1) in let tmp=a.(i) in a.(i)<-a.(j); a.(j)<-tmp\n  done; Array.to_list a\n\nlet read_line_p p = print_string p; flush stdout; String.trim (input_line stdin)\n\nlet register_event () =\n  let name = read_line_p \"Nombre del evento: \" in\n  if List.exists (fun e -> String.lowercase_ascii e.name = String.lowercase_ascii name) !events\n  then Printf.printf \"Ya existe.\\n\"\n  else (events := !events @ [{name; participants=[]}]; Printf.printf \"Evento '%s' registrado.\\n\" name)\n\nlet register_participant () =\n  if !events = [] then print_endline \"No hay eventos.\"\n  else begin\n    List.iteri (fun i e -> Printf.printf \"  %d. %s\\n\" (i+1) e.name) !events;\n    match int_of_string_opt (read_line_p \"Numero: \") with\n    | None -> print_endline \"Invalido.\"\n    | Some idx when idx<1||idx>List.length !events -> print_endline \"Invalido.\"\n    | Some idx ->\n        let ev = List.nth !events (idx-1) in\n        let n = read_line_p \"Nombre: \" in let c = read_line_p \"Pais: \" in\n        ev.participants <- ev.participants @ [{name=n;country=c}];\n        Printf.printf \"'%s (%s)' añadido a '%s'.\\n\" n c ev.name\n  end\n\nlet simulate_events () =\n  if !events = [] then print_endline \"No hay eventos.\"\n  else List.iter (fun ev ->\n    Printf.printf \"\\n=== Simulando: %s ===\\n\" ev.name;\n    let n = List.length ev.participants in\n    if n < 3 then Printf.printf \"  Necesita >=3. Saltando.\\n\"\n    else let s = shuffle ev.participants in\n      let g=List.nth s 0 and sl=List.nth s 1 and b=List.nth s 2 in\n      Printf.printf \"  Oro:    %s (%s)\\n\" g.name g.country;\n      Printf.printf \"  Plata:  %s (%s)\\n\" sl.name sl.country;\n      Printf.printf \"  Bronce: %s (%s)\\n\" b.name b.country;\n      add_medal g.country \"gold\"; add_medal sl.country \"silver\"; add_medal b.country \"bronze\"\n  ) !events\n\nlet show_report () =\n  print_endline \"\\n== INFORME FINAL ==\";\n  if Hashtbl.length medal_table = 0 then print_endline \"Sin resultados.\"\n  else begin\n    let all = Hashtbl.fold (fun _ v acc -> v::acc) medal_table [] in\n    let r = List.sort (fun a b ->\n      let cg=compare b.gold a.gold in if cg<>0 then cg\n      else let cs=compare b.silver a.silver in if cs<>0 then cs else compare b.bronze a.bronze) all in\n    List.iteri (fun i c ->\n      Printf.printf \"%d. %-20s Oro:%d Plata:%d Bronce:%d Total:%d\\n\"\n        (i+1) c.country c.gold c.silver c.bronze (c.gold+c.silver+c.bronze)) r\n  end\n\nlet () =\n  let run = ref true in\n  while !run do\n    print_endline \"\\n====== SIMULADOR JJOO ======\";\n    print_endline \"1. Registrar evento\\n2. Registrar participante\\n3. Simular\\n4. Informe\\n5. Salir\";\n    (match read_line_p \"Opcion: \" with\n    | \"1\" -> register_event ()\n    | \"2\" -> register_participant ()\n    | \"3\" -> simulate_events ()\n    | \"4\" -> show_report ()\n    | \"5\" -> print_endline \"Hasta luego!\"; run := false\n    | _ -> print_endline \"Invalido.\")\n  done\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/php/miguelex.php",
    "content": "<?php\n\ninterface EventInterface {\n    public function registerEvent($eventName);\n    public function getEvents();\n}\n\ninterface ParticipantInterface {\n    public function registerParticipant($name, $country);\n    public function getParticipants();\n}\n\ninterface SimulationInterface {\n    public function simulateEvents();\n    public function getResults();\n    public function getMedalTable();\n}\n\ninterface ReportInterface {\n    public function generateReport();\n}\n\nclass EventManager implements EventInterface {\n    private $events = [];\n\n    public function registerEvent($eventName) {\n        $this->events[] = $eventName;\n        echo \"Evento '$eventName' registrado.\\n\";\n    }\n\n    public function getEvents() {\n        return $this->events;\n    }\n}\n\nclass ParticipantManager implements ParticipantInterface {\n    private $participants = [];\n\n    public function registerParticipant($name, $country) {\n        $this->participants[] = [\n            'name' => $name,\n            'country' => $country\n        ];\n        echo \"Participante '$name' de '$country' registrado.\\n\";\n    }\n\n    public function getParticipants() {\n        return $this->participants;\n    }\n}\n\nclass EventSimulator implements SimulationInterface {\n    private $eventManager;\n    private $participantManager;\n    private $results = [];\n    private $medalTable = [];\n\n    public function __construct(EventInterface $eventManager, ParticipantInterface $participantManager) {\n        $this->eventManager = $eventManager;\n        $this->participantManager = $participantManager;\n    }\n\n    public function simulateEvents() {\n        $events = $this->eventManager->getEvents();\n        $participants = $this->participantManager->getParticipants();\n\n        foreach ($events as $event) {\n            echo \"\\nSimulando evento '$event'...\\n\";\n            shuffle($participants);\n            $eventResults = array_slice($participants, 0, 3);\n\n            $this->results[$event] = $eventResults;\n\n            echo \"Resultados del evento '$event':\\n\";\n            echo \"Oro: \" . $eventResults[0]['name'] . \" de \" . $eventResults[0]['country'] . \"\\n\";\n            echo \"Plata: \" . $eventResults[1]['name'] . \" de \" . $eventResults[1]['country'] . \"\\n\";\n            echo \"Bronce: \" . $eventResults[2]['name'] . \" de \" . $eventResults[2]['country'] . \"\\n\";\n\n            $this->assignMedal($eventResults[0]['country'], 'gold');\n            $this->assignMedal($eventResults[1]['country'], 'silver');\n            $this->assignMedal($eventResults[2]['country'], 'bronze');\n        }\n    }\n\n    private function assignMedal($country, $medal) {\n        if (!isset($this->medalTable[$country])) {\n            $this->medalTable[$country] = ['gold' => 0, 'silver' => 0, 'bronze' => 0];\n        }\n        $this->medalTable[$country][$medal]++;\n    }\n\n    public function getResults() {\n        return $this->results;\n    }\n\n    public function getMedalTable() {\n        return $this->medalTable;\n    }\n}\n\nclass ReportGenerator implements ReportInterface {\n    private $simulation;\n\n    public function __construct(SimulationInterface $simulation) {\n        $this->simulation = $simulation;\n    }\n\n    public function generateReport() {\n        $results = $this->simulation->getResults();\n        $medalTable = $this->simulation->getMedalTable();\n\n        echo \"\\nInforme de resultados:\\n\\n\";\n        foreach ($results as $event => $result) {\n            echo \"Evento: $event\\n\";\n            echo \"Oro: \" . $result[0]['name'] . \" de \" . $result[0]['country'] . \"\\n\";\n            echo \"Plata: \" . $result[1]['name'] . \" de \" . $result[1]['country'] . \"\\n\";\n            echo \"Bronce: \" . $result[2]['name'] . \" de \" . $result[2]['country'] . \"\\n\";\n            echo \"\\n\";\n        }\n\n        echo \"\\nTabla de medallas:\\n\";\n        uasort($medalTable, function($a, $b) {\n            return $b['gold'] <=> $a['gold'] ?: $b['silver'] <=> $a['silver'] ?: $b['bronze'] <=> $a['bronze'];\n        });\n\n        foreach ($medalTable as $country => $medals) {\n            echo \"$country - Oro: {$medals['gold']}, Plata: {$medals['silver']}, Bronce: {$medals['bronze']}\\n\";\n        }\n    }\n}\n\nclass OlympicGames {\n    private $eventManager;\n    private $participantManager;\n    private $simulator;\n    private $reportGenerator;\n\n    public function __construct() {\n        $this->eventManager = new EventManager();\n        $this->participantManager = new ParticipantManager();\n        $this->simulator = new EventSimulator($this->eventManager, $this->participantManager);\n        $this->reportGenerator = new ReportGenerator($this->simulator);\n    }\n\n    public function run() {\n        echo \"\\n\\nCOMIENZAN LOS JJOO\\n\\n\";\n        while (true) {\n            echo \"\\nOpciones:\\n\";\n            echo \"1. Registro de eventos\\n\";\n            echo \"2. Registro de participantes\\n\";\n            echo \"3. Simulación de eventos\\n\";\n            echo \"4. Creación de informes\\n\";\n            echo \"5. Salir del programa\\n\";\n            echo \"\\nSelecciona una opción: \";\n\n            $option = trim(fgets(STDIN));\n\n            switch ($option) {\n                case '1':\n                    echo \"\\nIntroduce el nombre del evento: \";\n                    $eventName = trim(fgets(STDIN));\n                    $this->eventManager->registerEvent($eventName);\n                    echo \"\\n\";\n                    break;\n                case '2':\n                    echo \"\\nIntroduce el nombre del participante: \";\n                    $participantName = trim(fgets(STDIN));\n                    echo \"Introduce el país del participante: \";\n                    $participantCountry = trim(fgets(STDIN));\n                    $this->participantManager->registerParticipant($participantName, $participantCountry);\n                    echo \"\\n\";\n                    break;\n                case '3':\n                    $this->simulator->simulateEvents();\n                    break;\n                case '4':\n                    $this->reportGenerator->generateReport();\n                    break;\n                case '5':\n                    exit(\"Saliendo del programa.\\n\");\n                default:\n                    echo \"Opción no válida. Por favor, intenta de nuevo.\\n\";\n            }\n        }\n        \n    }\n}\n\n$olympicGames = new OlympicGames();\n$olympicGames->run();\necho \"\\n\\nFINALIZAN LOS JJOO\\n\\n\";\n\n\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/php/sisaroot.php",
    "content": "<?php\n// #31 SIMULADOR JUEGOS OLÍMPICOS - SisaRoot\n\n$events = [];\n$medalTable = [];\n\nfunction inp(string $p): string\n{\n    echo $p;\n    return trim(fgets(STDIN));\n}\n\nfunction addMedal(string $c, string $t): void\n{\n    global $medalTable;\n    if (!isset($medalTable[$c]))\n        $medalTable[$c] = ['gold' => 0, 'silver' => 0, 'bronze' => 0];\n    $medalTable[$c][$t]++;\n}\n\nfunction registerEvent(): void\n{\n    global $events;\n    $name = inp(\"Nombre del evento: \");\n    if (!$name) {\n        echo \"Invalido.\\n\";\n        return;\n    }\n    foreach ($events as $ev)\n        if (strtolower($ev['name']) === strtolower($name)) {\n            echo \"Ya existe.\\n\";\n            return;\n        }\n    $events[] = ['name' => $name, 'participants' => []];\n    echo \"Evento '$name' registrado.\\n\";\n}\n\nfunction registerParticipant(): void\n{\n    global $events;\n    if (!$events) {\n        echo \"No hay eventos.\\n\";\n        return;\n    }\n    foreach ($events as $i => $ev)\n        echo \"  \" . ($i + 1) . \". {$ev['name']}\\n\";\n    $idx = (int)inp(\"Selecciona número: \");\n    if ($idx < 1 || $idx > count($events)) {\n        echo \"Invalido.\\n\";\n        return;\n    }\n    $n = inp(\"Nombre: \");\n    $c = inp(\"País: \");\n    $events[$idx - 1]['participants'][] = ['name' => $n, 'country' => $c];\n    echo \"'$n ($c)' añadido a '{$events[$idx - 1]['name']}'.\\n\";\n}\n\nfunction simulateEvents(): void\n{\n    global $events;\n    if (!$events) {\n        echo \"No hay eventos.\\n\";\n        return;\n    }\n    foreach ($events as &$ev) {\n        echo \"\\n=== Simulando: {$ev['name']} ===\\n\";\n        $p = $ev['participants'];\n        if (count($p) < 3) {\n            echo \"  Necesita >=3. Saltando.\\n\";\n            continue;\n        }\n        shuffle($p);\n        echo \"  Oro:    {$p[0]['name']} ({$p[0]['country']})\\n\";\n        echo \"  Plata:  {$p[1]['name']} ({$p[1]['country']})\\n\";\n        echo \"  Bronce: {$p[2]['name']} ({$p[2]['country']})\\n\";\n        addMedal($p[0]['country'], 'gold');\n        addMedal($p[1]['country'], 'silver');\n        addMedal($p[2]['country'], 'bronze');\n    }\n}\n\nfunction showReport(): void\n{\n    global $medalTable;\n    echo \"\\n== INFORME FINAL ==\\n\";\n    if (!$medalTable) {\n        echo \"Sin resultados.\\n\";\n        return;\n    }\n    $r = array_map(fn($c, $m) => ['c' => $c, ...$m, 't' => $m['gold'] + $m['silver'] + $m['bronze']], array_keys($medalTable), $medalTable);\n    usort($r, fn($a, $b) => $b['gold'] - $a['gold'] ?: $b['silver'] - $a['silver'] ?: $b['bronze'] - $a['bronze']);\n    foreach ($r as $i => $x)\n        printf(\"%d. %-20s Oro:%d Plata:%d Bronce:%d Total:%d\\n\", $i + 1, $x['c'], $x['gold'], $x['silver'], $x['bronze'], $x['t']);\n}\n\nwhile (true) {\n    echo \"\\n====== SIMULADOR JJOO ======\\n1. Registrar evento\\n2. Registrar participante\\n3. Simular\\n4. Informe\\n5. Salir\\n\";\n    match (inp(\"Opción: \")) {\n            \"1\" => registerEvent(), \"2\" => registerParticipant(),\n            \"3\" => simulateEvents(), \"4\" => showReport(),\n            \"5\" => (function () {\n            echo \"Hasta luego!\\n\";\n            exit(0); })(),\n            default => print(\"Invalido.\\n\"),\n        };\n}\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/python/Aldroide.py",
    "content": "import random\n\n\nclass Participant:\n\n    def __init__(self, name, country):\n        self.name = name\n        self.country = country\n\n    def __eq__(self, other: object) -> bool:\n        if isinstance(other, Participant):\n            return self.name == other.name and self.country == other.country\n        return False\n\n    def __hash__(self) -> int:\n        return hash(self.name, self.country)\n\n\nclass Olympics():\n\n    def __init__(self):\n        self.events = []\n        self.participants = {}\n        self.event_results = {}\n        self.country_results = {}\n\n    def register_event(self):\n        event = input(\"Introduce nombre del evento: \").strip()\n\n        if (event in self.events):\n            print(f\"Evento {event} ha sido registrado anteriormente\")\n        else:\n            self.events.append(event)\n            print(f\"Evento {event} ha sido registado.\")\n\n    def register_participant(self):\n        if not self.events:\n            print(\"No existen eventos. Por favor, registra un evento deportivo.\")\n            return\n        name = input(\"Introduce el nombre del participante: \").strip()\n        country = input(\"País del participante: \").strip()\n        participant = Participant(name, country)\n\n        print(\"Eventos deportivvos disponibles: \")\n        for index, event in enumerate(self.events):\n            print(f\"{index+1}. {event}\")\n\n        event_choice = int(\n            input(\"Selecciona el número del evento para asignar al participante: \")) - 1\n\n        if event_choice >= 0 and event_choice < len(self.events):\n            event = self.events[event_choice]\n\n            if event in self.participants and participant in self.participants[event]:\n                print(\n                    f\"El participante {name} de {country} ya está registrado en el evento deportivo {event}\")\n            else:\n                if event not in self.participants:\n                    self.participants[event] = []\n                self.participants[event].append(participant)\n                print(\n                    f\"El participante {name} de {country} se ha registrado en el evento deportivo {event}\")\n        else:\n            print(\"El evento deporivo es inválido. El participante no se ha registrado\")\n\n    def simulate_event(self):\n        if not self.events:\n            print(\"No hay eventos. Por favor registra un evento.\")\n            return\n\n        for event in self.events:\n            if len(self.participants[event]) < 3:\n                print(\"Participantes insuficientes, se necesitan al menos 3\")\n                continue\n\n            event_participants = random.sample(self.participants[event], 3)\n            random.shuffle(event_participants)\n            gold, silver, bronze = event_participants\n            self.event_results[event] = [gold, silver, bronze]\n\n            self.update_country_results(gold.country, \"gold\")\n            self.update_country_results(silver.country, \"silver\")\n            self.update_country_results(bronze.country, \"bronze\")\n\n            print(f\"Resultados simulación del evento: {event}\")\n            print(f\"Oro: {gold.name} ({gold.country})\")\n            print(f\"Plata: {silver.name} ({silver.country})\")\n            print(f\"Bronce: {bronze.name} ({bronze.country})\")\n\n    def update_country_results(self, country, medal):\n        if country not in self.country_results:\n            self.country_results[country] = {\n                \"gold\": 0, \"silver\": 0, \"bronze\": 0}\n        self.country_results[country][medal] += 1\n\n    def report(self):\n        print(\"Informe JJOO Paris 2024\")\n        if self.event_results:\n            print(\"Informe por evento\")\n            for event, winners in self.event_results.items():\n                print(f\"Evento: {event}\")\n                print(f\"Oro: {winners[0].name} ({winners[0].country})\")\n                print(f\"Plata: {winners[1].name} ({winners[1].country})\")\n                print(f\"Bronce: {winners[2].name} ({winners[2].country})\")\n        else:\n            print(\"No hay resultados registrados.\")\n\n        if self.country_results:\n            print(\"\\nInforme por país:\")\n            for country, medals in sorted(self.country_results.items(), key=lambda x: (\n                    x[1][\"gold\"], x[1][\"silver\"], x[1][\"bronze\"]), reverse=True):\n                print(\n                    f\"{country}: Oro {medals['gold']}, Plata {medals['silver']}, Bronce {medals['bronze']}\")\n        else:\n            print(\"No hay medallas por país registradas.\")\n\n\nolympics = Olympics()\nwhile True:\n    print(\"\"\"\\n Simulador de Juegos Olimpicos\n    1. Registro de eventos.\n    2. Registro de participantes.\n    3. Simulación de eventos.\n    4. Creación de informes.\n    5. Salir\"\"\")\n\n    option = input(\"Selecciona una acción: \")\n\n    match option:\n        case \"1\":\n            olympics.register_event()\n        case \"2\":\n            olympics.register_participant()\n        case \"3\":\n            olympics.simulate_event()\n        case \"4\":\n            olympics.report()\n        case \"5\":\n            print(\"Gracias por simular...\")\n            break\n        case _:\n            print(\"opción no encontrada\")\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/python/CesarCarmona30.py",
    "content": "import random\n\nclass Participant:\n\n  def __init__(self, name, country):\n    self.name = name\n    self.country = country\n\n  def __eq__(self, other: object) -> bool:\n    if isinstance(other, Participant):\n      return self.name == other.name and self.country == other.country\n    return False\n  \n  def __hash__(self) -> int:\n    return hash(self.name, self.country)\n  \n\nclass Olympics:\n\n  def __init__(self):\n    self.events = []\n    self.participants = {}\n    self.event_results = {}\n    self.country_results = {}\n\n  def register_event(self):\n    \n    event = input(\"Introduce el nombre del evento deportivo: \").strip()\n\n    if event in self.events:\n      print(f\"El evento {event} ya está registrado.\")\n    else:\n      self.events.append(event)\n      print(f\"Evento {event} registrado correctamente.\")\n\n  def register_participant(self):\n\n    if not self.events:\n      print(\"No hay eventos registrados. Por favor, registra uno primero.\")\n      return\n\n    name = input(\"Introduce el nombre del participante: \").strip()\n    country = input(\"Introduce el país del participante: \").strip()\n    participant = Participant(name, country)\n\n    print(\"Eventos deportivos disponibles:\")\n    for index, event in enumerate(self.events):\n      print(f\"{index + 1}. {event}\")\n    event_choice = int(\n      input(\"Selecciona el número del evento para asignar al participante: \")) - 1\n    \n    if event_choice >= 0 and event_choice < len(self.events):\n      event = self.events[event_choice]\n\n      if event in self.participants and participant in self.participants[event]:\n        print(\n          f\"El participante {name} de {country} ya está registrado en el evento deportivo {event}.\"\n        )\n      else:\n        if event not in self.participants:\n          self.participants[event] = []\n        self.participants[event].append(participant)\n        print(\n          f\"El participante {name} de {country} se ha registrado en el evento deportivo {event}.\"\n        )\n    \n    else:\n      print(\n        \"Selección de evento deportivo inválido. El participante no se ha registrado\")\n\n\n  def simulate_events(self):\n\n    if not self.events:\n      print(\"No hay eventos registrados. Por favor, registra uno primero,\")\n      return\n    \n    for event in self.events:\n\n      if len(self.participants[event]) < 3 or not self.participants:\n        print(\n          f\"No hay participantes suficientes para simular el evento {event} (mínimo 3)\")\n        continue\n\n      event_participants = random.sample(self.participants[event], 3)\n      random.shuffle(event_participants)\n\n      gold, silver, bronze = event_participants\n      self.event_results[event] = [gold, silver, bronze]\n\n      self.update_country_results(gold.country, \"gold\")\n      self.update_country_results(silver.country, \"silver\")\n      self.update_country_results(bronze.country, \"bronze\")\n\n      print(f\"\"\"Resultados de la simulación del evento: {event}\n              Oro: {gold.name} - {gold.country}\n              Plata: {silver.name} - {silver.country}\n              Bronce: {bronze.name} - {bronze.country}\"\"\")\n      \n  def update_country_results(self, country, medal):\n    if country not in self.country_results:\n      self.country_results[country] = {\n        \"gold\": 0, \"silver\": 0, \"bronze\": 0 }\n    self.country_results[country][medal] += 1\n\n  def show_report(self):\n    print(\"Informe Juegos Olímpicos:\")\n\n    if self.event_results:\n      print(\"Informe por evento:\")\n\n      for event, winners in self.event_results.items():\n        print(f\"\"\"Evento: {event}\n          Oro: {winners[0].name} - {winners[0].country}\n          Plata: {winners[1].name} - {winners[1].country}\n          Bronce: {winners[2].name} - {winners[2].country}\"\"\")\n        \n    else:\n      print(\"No hay resultados registrados.\")\n\n    print()\n\n    if self.country_results:\n      print(\"Informe por país:\")  \n\n      for country, medals in sorted(self.country_results.items(), key=lambda x: (\n        x[1][\"gold\"], x[1][\"silver\"], x[1][\"bronze\"]), reverse=True):\n        print(\n          f\"{country}: Oro {medals[\"gold\"]}, Plata {medals[\"silver\"]}, Bronce {medals[\"bronze\"]}\")\n    \n    else:\n      print(\"No hay medallas por país registradas.\")\n\nolympics = Olympics()\n\nprint(\"Simulador de Juegos Olímpicos\")\n\nwhile True:\n  print()\n\n  print(\"1. Registro de eventos\")\n  print(\"2. Registro de participantes\")\n  print(\"3. Simulación de eventos\")\n  print(\"4. Creación de informes\")\n  print(\"5. Salir\")\n\n  option = input(\"Selecciona una acción: \")\n\n  match option:\n    case \"1\":\n      olympics.register_event()\n    case \"2\":\n      olympics.register_participant()\n    case \"3\":\n      olympics.simulate_events()\n    case \"4\":\n      olympics.show_report()\n    case \"5\":\n      print(\"Saliendo del simulador...\")\n      break\n    case _:\n      print(\"Opción inválida. Por favor seleccione una nueva.\")"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/python/EmmanuelMMontesinos.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * ¡Los JJOO de París 2024 han comenzado!\n * Crea un programa que simule la celebración de los juegos.\n * El programa debe permitir al usuario registrar eventos y participantes,\n * realizar la simulación de los eventos asignando posiciones de manera aleatoria\n * y generar un informe final. Todo ello por terminal.\n * Requisitos:\n * 1. Registrar eventos deportivos.\n * 2. Registrar participantes por nombre y país.\n * 3. Simular eventos de manera aleatoria en base a los participantes (mínimo 3).\n * 4. Asignar medallas (oro, plata y bronce) basándose en el resultado del evento.\n * 5. Mostrar los ganadores por cada evento.\n * 6. Mostrar el ranking de países según el número de medallas.\n * Acciones:\n * 1. Registro de eventos.\n * 2. Registro de participantes.\n * 3. Simulación de eventos.\n * 4. Creación de informes.\n * 5. Salir del programa.\n */\n\"\"\"\nfrom random import choice\n\nclass Participantes:\n    lista = []\n\n    def __init__(self, nombre:str, pais:str) -> None:\n        self.nombre = nombre\n        self.pais = pais\n\n        # Agrega el nuevo participante a lista\n        Participantes.lista.append(self)\n\n        # Si no esta el pais en top_paises lo crea\n        if pais not in Medallas.top_paises:\n            Medallas.top_paises[pais] = {\"oro\":0,\"plata\":0,\"bronce\":0}\n\nclass Medallas:\n    top_paises = {}\n\n    def __init__(\n            self,nombre:str, oro:Participantes, plata:Participantes, bronce:Participantes\n            ) -> None:\n        self.evento = nombre\n        self.oro = oro\n        self.plata = plata\n        self.bronce = bronce\n\nclass Eventos:\n    lista = []\n\n    def __init__(self, nombre:str) -> None:\n        self.nombre = nombre\n        self.finalizado = False\n        Eventos.lista.append(self)\n    \n    def decidir_ganador(self):\n        lista_participantes = Participantes.lista.copy()\n\n        if not self.finalizado:\n            try:\n                ganadores = []\n\n                for n in range(3):\n                    elegido = choice(lista_participantes)\n                    lista_participantes.remove(elegido)\n                    ganadores.append(elegido)\n\n                oro, plata, bronce = ganadores\n                registro = Medallas(self.nombre,oro,plata,bronce)\n                self.finalizado = True\n                return registro\n            \n            except Exception as e:\n                print(f\"Se necesitan al menos 3 participantes\\nNº de participantes actuales: {len(Participantes.lista)}\")\n                print(e)\n\nclass Juegos:\n    registro_finalizados = []\n    eventos_finalizados = []\n    def registrar_evento(self,nombre:str):\n        nuevo_evento = Eventos(nombre)\n        print(f\"Evento {nuevo_evento.nombre} se ha registrado\")\n\n    def registrar_participante(self,nombre:str,pais:str):\n        nuevo_participante = Participantes(nombre,pais)\n        print(f\"{nuevo_participante.nombre} de {pais} se ha registrado\")\n\n    def simular_evento(self,nombre_evento:str):\n        evento = None\n        for eventos in Eventos.lista:\n            if eventos.nombre == nombre_evento:\n                evento = eventos\n        if evento:\n            medallas = evento.decidir_ganador()\n            if medallas:\n                print(f\"Resultado del evento {medallas.evento}\")\n                print(f\"Oro - {medallas.oro.nombre.title()} de {medallas.oro.pais.upper()}\")\n                print(f\"Plata - {medallas.plata.nombre.title()} de {medallas.plata.pais.upper()}\")\n                print(f\"Bronce - {medallas.bronce.nombre.title()} de {medallas.bronce.pais.upper()}\\n\")\n                \n                Medallas.top_paises[medallas.oro.pais][\"oro\"] += 1\n                Medallas.top_paises[medallas.plata.pais][\"plata\"] += 1\n                Medallas.top_paises[medallas.bronce.pais][\"bronce\"] += 1\n\n                Juegos.registro_finalizados.append(medallas)\n                Juegos.eventos_finalizados.append(nombre_evento)\n        else:\n            print(f\"{nombre_evento} no esta registrado\")\n\n    def generar_informe(self):\n        for medalla in Juegos.registro_finalizados:\n            print(f\"Resultado del evento {medalla.evento}\")\n            print(f\"Oro - {medalla.oro.nombre} de {medalla.oro.pais}\")\n            print(f\"Plata - {medalla.plata.nombre} de {medalla.plata.pais}\")\n            print(f\"Bronce - {medalla.bronce.nombre} de {medalla.bronce.pais}\\n\")\n\n        print()\n        print(\"Lista de Paises\")\n        # Ranking de paises por medallas de oro\n        for pais,n_medallas in sorted(Medallas.top_paises.items(),key=lambda item: item[1][\"oro\"],reverse=True):\n            print(f\"{pais.title()} ---> Oro: {n_medallas[\"oro\"]}, Plata: {n_medallas[\"plata\"]}, Bronce: {n_medallas[\"bronce\"]}\")\n\ndef hacer_olimpiadas():\n    juego = Juegos()\n    salir = False\n    print(\"Bienvenido a las olimpiadas\")\n    while not salir:\n        print(\"\\nSelecciona una opcion:\")\n        print(\"1- Registrar Evento\")\n        print(\"2- Registrar Participante\")\n        print(\"3- Empezar Evento\")\n        print(\"4- Mostrar Informe\")\n        print(\"5- Salir\")\n        seleccion = input(\"\")\n\n        if seleccion == \"1\":\n            nombre_evento = input(\"Ponga el nombre del Evento:\\n\")\n            juego.registrar_evento(nombre_evento.lower())\n            print(f\"{nombre_evento} ha sido registrado\")\n            \n        elif seleccion == \"2\":\n            nombre_participante = input(\"Ponga el nombre del participante:\\n\")\n            pais_participante = input(\"Ponga el nombre del pais:\\n\")\n            juego.registrar_participante(nombre_participante.lower(),pais_participante.lower())\n            print(f\"{nombre_participante} de {pais_participante} ha sido registrado\")\n            \n        elif seleccion == \"3\":\n            for evento in Eventos.lista:\n                if evento.nombre not in Juegos.eventos_finalizados:\n                    print(f\"{evento.nombre.title()}\")\n                \n            seleccion_evento = input(\"Indique el nombre de un evento ya registrado:\\n\")\n            if seleccion_evento not in Juegos.eventos_finalizados:\n                juego.simular_evento(seleccion_evento.lower())\n\n            else:\n                print(f\"{seleccion_evento} ya se ha simulado\")\n        elif seleccion == \"4\":\n            juego.generar_informe()\n        elif seleccion == \"5\":\n            salir = True\n        else:\n            print(\"Seleccione una de las opciones anteriores\\n\")\n\nif __name__ == \"__main__\":\n    hacer_olimpiadas()"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/python/Gordo-Master.py",
    "content": "from abc import ABC, abstractmethod\nimport os, time\n\n\n# Definiendo las clases de competidor y evento\nclass Competitor():\n\n    def __init__(self, name, country):\n        self.name = name\n        self.country = country\n\n    def __eq__(self, other: object) -> bool:\n        if isinstance(other, Competitor):\n            return self.name == other.name and self.country == other.country\n        return False\n    \n    def __hash__(self):\n        return hash((self.name,self.country))\n\nclass Event():\n\n    def __init__(self, name):\n        self.name = name\n        self.competitors = set()\n        self.results = dict()\n\n    def __eq__(self, other: object) -> bool:\n        if isinstance(other, Event):\n            return self.name == other.name\n        return False\n    \n    def __hash__(self):\n        return hash(self.name)\n    \n    def add_competitor(self, competitor: Competitor):\n        self.competitors.add(competitor)\n    \n    def enough_competitors(self) -> bool:\n        if len(self.competitors) >= 3:\n            return True\n        else:\n            return False\n\n    def event_simulator(self):\n        for num, person in enumerate(self.competitors):\n            self.results[num+1] = person\n        \n        return [self.results[1],self.results[2],self.results[3]]\n    \n\n\n# Definiendo el metodo de registar\nclass Registration(ABC):\n\n    @abstractmethod\n    def register(self, data, recorder):\n        pass\n\n# Asignando metodos de mas bajo nivel de acuerdo a una abstracción\nclass CompetitorRegistration(Registration):\n\n    def register(self, data: Competitor, recorder: Event):\n        if data in recorder.competitors:\n            print(\"El participante ya existe en esta prueba\")\n        else:\n            recorder.add_competitor(data)\n            print(\"Competidor agregado exitosamente\")\n\nclass EventRegistration(Registration):\n\n    def register(self, data: Event, recorder: list):\n        if data in recorder:\n            print(\"El evento ya existe\")\n        else:\n            recorder.append(data)\n            print(\"Evento agregado exitosamente\")\n\n\n# Funcion que se repite\ndef error_return_init(text):\n    print(f\"{text}\\nRegresando al menu inicial\")\n    time.sleep(1.8)\n\n\n# Clase que va manejar toda la logica. De nivel superior\n\nclass Olimpycs():\n\n    def __init__(self):\n        self.events = []\n        self.country_results= {}\n\n    \n    def event_register(self):\n        EventRegistration().register(Event(input(\"Nombre del evento:\").strip()), self.events)\n        \n        input(\"[*] Presione enter para continuar...\")\n\n    def competitor_register(self):\n\n        if not self.events:\n            return error_return_init(\"No hay eventos registrados\")\n\n        self.events.sort(key= lambda x: x.name)\n\n        print(\"Eventos:\") \n        for num, i in enumerate(self.events):\n            print (f\"{num + 1 }.{i.name}\")\n\n        try:\n            number = int(input(\"Elige el numero del evento: \"))-1\n        except:\n            error_return_init(\"Valor invalido\")\n        else:\n            if number < 0 or number >= len(self.events) :\n                error_return_init(f\"Valor invalido. Debe ser un numero entre 1 y {len(self.events)}\")\n\n            else:        \n                name = input(\"Nombre del participante: \").strip()\n                country = input(\"Nacionalidad: \").strip()\n                CompetitorRegistration().register(Competitor(name, country),self.events[number])\n                input(\"[*] Presione enter para continuar...\")\n                \n\n\n    def country_count_medals(self, medals:list):\n        for num, med in enumerate(medals):\n            if med.country not in self.country_results:\n                self.country_results[med.country] = {\n                    \"gold\" : 0,\n                    \"silver\" : 0,\n                    \"bronze\" : 0\n                }\n            match num:\n                case 0:\n                    self.country_results[med.country][\"gold\"] += 1\n                case 1:\n                    self.country_results[med.country][\"silver\"] += 1\n                case 2:\n                    self.country_results[med.country][\"bronze\"] += 1\n\n    def event_simulator(self):\n\n        flag = False\n\n        if not self.events:\n            return error_return_init(\"No hay eventos registrados\")\n        \n\n        for event in self.events:\n            if not event.enough_competitors():\n                print(f\"No hay suficiente competidores para {event.name}! (3 participantes mínimos)\")\n                input(\"Presione enter para continuar...\")\n                continue\n\n            flag = True\n\n            list_medals = event.event_simulator()\n\n            self.country_count_medals(list_medals)\n        \n        if flag:\n            input(\"Simulación concluida con exito!\")\n\n\n    def show_report(self):\n        print(\"Informe de resultados:\")\n        if self.events:\n            for event in self.events:\n                \n                print(f\"\\nEvento: {event.name}\")\n                if not event.enough_competitors():\n                    print(f\"No hay suficiente competidores para {event.name}! (3 participantes mínimos)\")\n                    continue\n\n                for position, competitor in event.results.items():\n                    \n                    print(f\"Puesto {position}: {competitor.name}, {competitor.country}\")\n        else: \n            print(\"\\nNo hay resultados registrados.\")\n\n        input(\"Presione enter para continuar...\")\n\n        print(\"Informe de medallas por paises\")\n\n        if self.country_results:\n\n            for country, valor in sorted(self.country_results.items(), key = lambda x: (x[1][\"gold\"],x[1][\"silver\"],x[1][\"bronze\"]), reverse= True):\n                print(f\"{country}: \\nGold: {valor[\"gold\"]}{\" \"*4}Plate: {valor[\"silver\"]}{\" \"*4}Bronce: {valor[\"bronze\"]}\")\n\n        else:\n            input(\"\\nNo hay medallas por pais registrados.\")\n\n        input(\"Presione enter para continuar...\")\n\n\noojj = Olimpycs()\n\n# Función principal\ndef main():\n    text = \"\"\"Acciones:\n1. Registro de eventos.\n2. Registro de participantes.\n3. Simulación de eventos.\n4. Creación de informes.\n5. Salir del programa.\"\"\"\n\n    while True:\n        os.system(\"cls\")\n        print(text)\n        option = input(\"\\nElige un opción (número):\")\n        match option:\n\n            case \"1\":\n                oojj.event_register()\n\n            case \"2\":\n                oojj.competitor_register()\n\n            case \"3\":\n                oojj.event_simulator()\n\n            case \"4\":\n                oojj.show_report()\n\n            case \"5\":\n                print(\"[+] Saliendo del programa...\")\n                break\n            case _:\n                error_return_init(\"El valor es incorrecto. \\nDebe ser un valor entre 1 - 5.\")\n\n\nif __name__ == \"__main__\":\n    main()"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/python/Javi-kl.py",
    "content": "from abc import ABC, abstractmethod\nimport random\n\nprint(\"\"\"¡Los JJOO de París 2024 han comenzado!\"\"\")\n\n\nclass IRegistro(ABC):\n    \"\"\"Interfaz que define que hacer y NO como hacerlo\n    guardar y obtener datos en el registro\"\"\"\n\n    @abstractmethod\n    def registrar(self, datos: str) -> bool:\n        pass\n\n    @abstractmethod\n    def obtener_datos(self) -> list[str]:\n        pass\n\n\n# Modulos bajo nivel, solo guardan datos\nclass DatosEventos(IRegistro):\n    def __init__(self):\n        self.datos_eventos = []\n\n    def registrar(self, dato: str) -> bool:\n        self.datos_eventos.append(dato)\n        return True\n\n    def obtener_datos(self) -> list[str]:\n        return self.datos_eventos\n\n\nclass DatosUsuarios(IRegistro):\n    def __init__(self):\n        self.datos_usuarios = []\n\n    def registrar(self, dato: str) -> bool:\n        self.datos_usuarios.append(dato)\n        return True\n\n    def obtener_datos(self) -> list[str]:\n        return self.datos_usuarios\n\n\nclass ResultadosEventos(IRegistro):\n    def __init__(self) -> None:\n        self.resultados_list = []\n\n    def registrar(self, dato: str) -> bool:\n        self.resultados_list.append(dato)\n        return True\n\n    def obtener_datos(self) -> list[str]:\n        return self.resultados_list\n\n\nclass Evento:\n    def __init__(self, nombre) -> None:\n        self.nombre = nombre\n\n    def __str__(\n        self,\n    ) -> str:\n        return f\"Evento: {self.nombre}\"\n\n\nclass Participante:\n    def __init__(self, nombre, pais) -> None:\n        self.nombre = nombre\n        self.pais = pais\n\n    def __str__(\n        self,\n    ) -> str:\n        return f\"Participante: {self.nombre}, Pais: {self.pais}\"\n\n\nclass Resultado:\n    def __init__(self, dato) -> None:\n\n        self.evento = dato[\"evento\"]\n        self.oro = dato[\"medallas\"][0]\n        self.plata = dato[\"medallas\"][1]\n        self.bronce = dato[\"medallas\"][2]\n\n    def __str__(\n        self,\n    ) -> str:\n        return f\"{self.evento}\\nOro: {self.oro}\\nPlata: {self.plata}\\nBronce: {self.bronce}\"\n\n\nclass MedallaPais:\n    \"\"\"Representa UNA medalla ganada por UN país\"\"\"\n\n    def __init__(self, pais, medalla) -> None:\n\n        self.pais = pais\n        self.medalla = medalla\n\n    def __str__(\n        self,\n    ) -> str:\n        return f\"Pais: {self.pais}\\nMedalla: {self.medalla}\"\n\n\nclass SimuladorResultado:\n    @staticmethod\n    def simular(eventos, participantes):\n        datos_simulaciones = []\n        for evento in eventos:\n            datos_evento = {}\n            top3 = sorted(participantes, key=lambda x: random.random())\n            datos_evento[\"evento\"] = evento\n            datos_evento[\"medallas\"] = top3\n            datos_simulaciones.append(datos_evento)\n        return datos_simulaciones\n\n\nclass CalculadorMedallas:\n    @staticmethod\n    def calcular_medallas(todos_los_datos):\n        solo_medallas = [\n            dato for dato in todos_los_datos if isinstance(dato, MedallaPais)\n        ]\n        conteo_paises = {}\n        for medalla in solo_medallas:\n            pais = medalla.pais\n            tipo = medalla.medalla\n            if pais not in conteo_paises:\n                conteo_paises[pais] = {\"oro\": 0, \"plata\": 0, \"bronce\": 0, \"total\": 0}\n            conteo_paises[pais][tipo] += 1  # incrementa oro, plata o bronce\n            conteo_paises[pais][\"total\"] += 1\n\n        return sorted(\n            conteo_paises.items(), key=lambda item: item[1][\"total\"], reverse=True\n        )\n\n\n# Informador\nclass Informador:\n    \"\"\"Modulo de alto nivel - muestra cualquier dato de los registros\"\"\"\n\n    def __init__(self, registro: IRegistro):\n        self.registro = registro\n\n    def mostrar_datos(self):\n        datos = self.registro.obtener_datos()\n        for dato in datos:\n            print(f\"{dato}\")\n\n\n# Registrador\nclass Registrador:\n    \"\"\"Modulo de alto nivel -  registra cualquier cosa\"\"\"\n\n    def __init__(self, registro: IRegistro):\n        self.registro = registro\n\n    def registrar_datos(self, datos):\n        exito = self.registro.registrar(datos)\n        if exito:\n            print(f\"Registrado con exito {datos}\")\n        else:\n            print(\"Error al guardar\")\n\n\n# Eventos\ndatos_eventos = DatosEventos()\nregistrador_evento = Registrador(datos_eventos)\n\n# Participantes\ndatos_participantes = DatosUsuarios()\nregistrador_participante = Registrador(datos_participantes)\n\n# Simular resultados\nsimulador = SimuladorResultado()\ncalculador_medallas = CalculadorMedallas()\n# Resultados\nresultados = ResultadosEventos()\nregistrador_resultado = Registrador(resultados)\n\n# Informador\ninformador_resultados = Informador(resultados)\n\n\n# 6. Mostrar el ranking de países según el número de medallas.\ndef menu_principal():\n    while True:\n        print(\"Opciones:\\n1. Registro de eventos.\")\n        print(\"2. Registro de participantes.\")\n        print(\"3. Simulación de eventos.\")\n        print(\"4. Creación de informes.\")\n        print(\"5. Salir del programa.\")\n        opcion = input(\"-> \")\n        if opcion == \"5\":\n            break\n\n        elif opcion == \"4\":\n            print(f\"Informando de resultados\")\n            informador_resultados.mostrar_datos()\n            \"\"\"Ranking paises aqui\"\"\"\n            todos_los_datos = resultados.obtener_datos()\n            ranking = calculador_medallas.calcular_medallas(todos_los_datos)\n            for posicion, (pais, medallas) in enumerate(ranking, start=1):\n                print(f\"{posicion}. {pais.upper()}\")\n                print(\n                    f\"  Oro: {medallas['oro']}, Plata: {medallas['plata']}, Bronce: {medallas['bronce']}\"\n                )\n                print(f\" Total: {medallas['total']}\\n\")\n\n        elif opcion == \"3\":\n            print(\"\"\"\\n¡Que comiencen los juegos!\"\"\")\n            datos_simulacion = simulador.simular(\n                datos_eventos.datos_eventos, datos_participantes.datos_usuarios\n            )\n            for dato in datos_simulacion:\n                resultado = Resultado(dato)\n                print(\"\"\"\\n¡Registrando resultado de los eventos!\"\"\")\n                registrador_resultado.registrar_datos(resultado)\n                medalla_oro = MedallaPais(pais=dato[\"medallas\"][0].pais, medalla=\"oro\")\n                medalla_plata = MedallaPais(\n                    pais=dato[\"medallas\"][1].pais, medalla=\"plata\"\n                )\n                medalla_bronce = MedallaPais(\n                    pais=dato[\"medallas\"][2].pais, medalla=\"bronce\"\n                )\n                registrador_resultado.registrar_datos(medalla_oro)\n                registrador_resultado.registrar_datos(medalla_plata)\n                registrador_resultado.registrar_datos(medalla_bronce)\n\n        elif opcion == \"2\":\n            print(\"\"\"\\n¡Creando participante!\"\"\")\n            nombre = input(\"Nombre participante -> \")\n            pais = input(\"Pais ->\")\n            participante = Participante(nombre, pais)\n            registrador_participante.registrar_datos(participante)\n\n        elif opcion == \"1\":\n            print(\"\"\"\\n¡Creando evento!\"\"\")\n            nombre_evento = input(\"Nombre evento -> \")\n            evento = Evento(nombre_evento)\n            registrador_evento.registrar_datos(evento)\n\n        else:\n            print(\"Elije una opción valida...\")\n\n\nmenu_principal()\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/python/Jotarose.py",
    "content": "\"\"\"\r\nPrograma para simular los JJOO\r\n\r\nRequisitos\r\n- Registrar eventos deportivos\r\n- Registrar participantes\r\n- Simular eventos de manera aleatoria en base a los participantes (min 3)\r\n- Asignar medallas (oro, plata y bronce) basandose en el resultado del evento\r\n- Mostrar a los ganadores por cada eventos\r\n- Mostrar el ranking de paises segun el número de medallas\r\n\"\"\"\r\n\r\nimport random\r\nfrom dataclasses import dataclass, field\r\nfrom datetime import datetime\r\nfrom enum import StrEnum\r\n\r\n\r\n# --- Data Models ---\r\n@dataclass(unsafe_hash=True)\r\nclass Participant:\r\n    # --- 1. Atributos de Identidad (Se usan en __eq__ y __hash__) ---\r\n    name: str\r\n    country: str\r\n\r\n    # --- 2. Atributos de Estado (Mutables: NO se usan en __eq__ ni __hash__) ---\r\n    # registered_events: Es un set. Necesita su propia fábrica (set()) para no compartirse.\r\n    registered_events: set = field(\r\n        default_factory=set,\r\n        compare=False,\r\n        hash=False,\r\n        repr=False,  # No lo mostramos en el __repr__ por defecto para no ensuciar el log\r\n    )\r\n\r\n    # medals: Es un dict. Necesita su propia fábrica lambda.\r\n    medals: dict = field(\r\n        default_factory=lambda: {\"Gold\": 0, \"Silver\": 0, \"Bronze\": 0},\r\n        compare=False,\r\n        hash=False,\r\n        repr=False,\r\n    )\r\n\r\n    def add_medal(self, medal_type: str):\r\n        \"\"\"Método de negocio para añadir medallas.\"\"\"\r\n        if medal_type in self.medals:\r\n            self.medals[medal_type] += 1\r\n\r\n    def __str__(self) -> str:\r\n        \"\"\"\r\n        Las dataclasses crean un __repr__ automático, pero tú puedes\r\n        definir tu propio __str__ para que se vea bonito en la consola.\r\n        \"\"\"\r\n        events = \", \".join(e.sport for e in self.registered_events)\r\n        return f\"Deportista: {self.name} Pais: {self.country} Eventos registrados: {events}\"\r\n\r\n\r\n@dataclass(unsafe_hash=True)\r\nclass Event:\r\n    # --- Identidad ---\r\n    sport: str\r\n    date: datetime\r\n\r\n    # --- Estado Mutable (Colecciones) ---\r\n    participants: set = field(\r\n        default_factory=set,  # ¡Vital para que cada evento tenga su propia lista!\r\n        compare=False,\r\n        hash=False,\r\n        repr=False,\r\n    )\r\n\r\n    # --- Estado Mutable (Resultados / Nullables) ---\r\n    # Nota: Para valores simples como None, usamos default=None en vez de default_factory\r\n    results: list | None = field(default=None, compare=False, hash=False, repr=False)\r\n    gold: Participant | None = field(default=None, compare=False, hash=False, repr=False)\r\n    silver: Participant | None = field(default=None, compare=False, hash=False, repr=False)\r\n    bronze: Participant | None = field(default=None, compare=False, hash=False, repr=False)\r\n\r\n    def __str__(self) -> str:\r\n        date_str = self.date.strftime(\"%d/%m/%Y\")\r\n        return f\"Evento: {self.sport} Fecha: {date_str} Nº Participantes: {len(self.participants)}\"\r\n\r\n\r\n@dataclass(unsafe_hash=True)\r\nclass Country:\r\n    name: str\r\n\r\n    medals: dict = field(\r\n        default_factory=lambda: {\"Gold\": 0, \"Silver\": 0, \"Bronze\": 0},\r\n        compare=False,\r\n        hash=False,\r\n        repr=False,\r\n    )\r\n\r\n    def add_medal(self, medal_type: str):\r\n        if medal_type in self.medals:\r\n            self.medals[medal_type] += 1\r\n\r\n\r\nclass ProgramOptions(StrEnum):\r\n    ADD_EVENT = \"1\"\r\n    ADD_PARTICIPANT = \"2\"\r\n    SIMULATE_EVENT = \"3\"\r\n    GET_REPORT = \"4\"\r\n    EXIT = \"5\"\r\n\r\n\r\n# --- Repositories ---\r\nclass EventRepository:\r\n    def __init__(self):\r\n        self.event_repo = {}\r\n\r\n    def add_event(self, event_sport: str, event_date: datetime) -> Event:\r\n        if event_sport in self.event_repo:\r\n            raise ValueError(\"El evento ya existe.\")\r\n\r\n        new_event = Event(event_sport, event_date)\r\n        self.event_repo[event_sport] = new_event\r\n        return new_event\r\n\r\n    def get_event(self, name: str) -> Event | None:\r\n        return self.event_repo.get(name)\r\n\r\n    def list_events(self) -> list[Event]:\r\n        return list(self.event_repo.values())\r\n\r\n\r\nclass ParticipantRepository:\r\n    def __init__(self):\r\n        self.participant_repo = {}\r\n\r\n    def add_participant(self, name: str, country: str) -> Participant:\r\n\r\n        key = (name, country)\r\n        if key in self.participant_repo:\r\n            raise ValueError(\"El participante ya existe.\")\r\n\r\n        new_participant = Participant(name, country)\r\n        self.participant_repo[key] = new_participant\r\n        return new_participant\r\n\r\n    def get_participant(self, name: str, country: str) -> Participant | None:\r\n        return self.participant_repo.get((name, country))\r\n\r\n    def list_all_participants(self):\r\n        return self.participant_repo\r\n\r\n\r\nclass CountryRepository:\r\n    def __init__(self):\r\n        self.country_repo = {}\r\n\r\n    def add_country(self, name) -> None:\r\n        if name in self.country_repo:\r\n            return\r\n\r\n        new_country = Country(name)\r\n        self.country_repo[name] = new_country\r\n        return new_country\r\n\r\n    def get_country(self, name) -> Country | None:\r\n        return self.country_repo.get(name)\r\n\r\n    def get_ranking(self) -> list[Country]:\r\n        if not self.country_repo:\r\n            return []\r\n\r\n        countries = list(self.country_repo.values())\r\n        return sorted(\r\n            countries,\r\n            key=lambda c: (c.medals[\"Gold\"], c.medals[\"Silver\"], c.medals[\"Bronze\"]),\r\n            reverse=True,\r\n        )\r\n\r\n    def list_countries(self):\r\n        return self.country_repo\r\n\r\n\r\n# --- JJOO Manager ---\r\nclass JJOO:\r\n    def __init__(\r\n        self,\r\n        event_repo: EventRepository,\r\n        participants_repo: ParticipantRepository,\r\n        country_repo: CountryRepository,\r\n    ):\r\n        self.event_repo = event_repo\r\n        self.participants_repo = participants_repo\r\n        self.country_repo = country_repo\r\n\r\n    def register_participant(self, participant: Participant, event: Event) -> None:\r\n        if participant in event.participants:\r\n            raise ValueError(\"El participante ya está registrado en este evento.\")\r\n\r\n        event.participants.add(participant)\r\n        participant.registered_events.add(event)\r\n\r\n    def simulate_event(self, event: Event) -> list:\r\n        if len(event.participants) < 3:\r\n            raise ValueError(\r\n                \"El evento seleccionado no llega al minimo de participantes para simularse\"\r\n            )\r\n\r\n        participants = list(event.participants)\r\n        random.shuffle(participants)\r\n        event.results = participants\r\n\r\n        winner = participants[0]\r\n        winner_country = self.country_repo.get_country(winner.country)\r\n        second = participants[1]\r\n        second_country = self.country_repo.get_country(second.country)\r\n        third = participants[2]\r\n        third_country = self.country_repo.get_country(third.country)\r\n\r\n        event.gold = winner\r\n        winner.add_medal(\"Gold\")\r\n        winner_country.add_medal(\"Gold\")\r\n\r\n        event.silver = second\r\n        second.add_medal(\"Silver\")\r\n        second_country.add_medal(\"Silver\")\r\n\r\n        event.bronze = third\r\n        third.add_medal(\"Bronze\")\r\n        third_country.add_medal(\"Bronze\")\r\n\r\n        return participants\r\n\r\n\r\n# --- View ---\r\nclass View:\r\n    def show_menu(self):\r\n        print(\r\n            \"1. Registrar eventos deportivos\\n\"\r\n            \"2. Registrar participantes\\n\"\r\n            \"3. Simular eventos\\n\"\r\n            \"4. Crear informes\\n\"\r\n            \"5. Salir del programa\\n\"\r\n        )\r\n\r\n    def get_input(self, prompt: str) -> str:\r\n        return input(prompt)\r\n\r\n    def display_msg(self, msg: str) -> None:\r\n        print(f\"\\n{msg}\")\r\n\r\n    def display_err(self, err: str) -> None:\r\n        print(f\"\\nERROR: {err}.\")\r\n\r\n\r\n# --- Controllers ---\r\nclass Controller:\r\n    def __init__(\r\n        self,\r\n        view: View,\r\n        games: JJOO,\r\n        event_repo: EventRepository,\r\n        participant_repo: ParticipantRepository,\r\n        country_repo: CountryRepository,\r\n    ):\r\n        self.view = view\r\n        self.games = games\r\n        self.event_repo = event_repo\r\n        self.participant_repo = participant_repo\r\n        self.country_repo = country_repo\r\n\r\n    def add_event_handler(self):\r\n        event_name = self.view.get_input(\"Nombre del evento a registrar: \").strip().title()\r\n        date_str = self.view.get_input(\"Introduce una fecha para el evento (Ej: dd/mm/yyyy): \")\r\n\r\n        try:\r\n            event_date = datetime.strptime(date_str, \"%d/%m/%Y\")\r\n        except ValueError:\r\n            self.view.display_err(\"Formato de fecha incorrecto.\")\r\n            self.view.display_msg(\"No se pudo crear el evento\")\r\n            return\r\n\r\n        try:\r\n            new_event = self.event_repo.add_event(event_name, event_date)\r\n            self.view.display_msg(\"¡Evento creado con éxito!\")\r\n            self.view.display_msg(new_event)\r\n        except ValueError as verr:\r\n            self.view.display_err(verr)\r\n\r\n    def add_participant_handler(self) -> None:\r\n\r\n        if not self.event_repo.list_events():\r\n            self.view.display_err(\"No hay eventos deportivos registrados, registra uno primero.\")\r\n            return\r\n\r\n        participant_name = (\r\n            self.view.get_input(\"Nombre del participante a registrar: \").strip().title()\r\n        )\r\n        participant_country = self.view.get_input(\"Pais del participante: \").strip().title()\r\n\r\n        participant = self.participant_repo.get_participant(participant_name, participant_country)\r\n        if not participant:\r\n            participant = self.participant_repo.add_participant(\r\n                participant_name, participant_country\r\n            )\r\n            self.view.display_msg(\"¡Participante añadido con éxito!\")\r\n\r\n        country = self.country_repo.get_country(participant_country)\r\n        if not country:\r\n            country = self.country_repo.add_country(participant_country)\r\n\r\n        self.view.display_msg(\"Eventos deportivos disponibles\")\r\n        for event in self.event_repo.list_events():\r\n            print(event.sport)\r\n\r\n        participant_event = self.view.get_input(\"Evento del participante: \").strip().title()\r\n        event = self.event_repo.get_event(participant_event)\r\n\r\n        if not event:\r\n            self.view.display_err(\"El evento no existe.\")\r\n            return\r\n\r\n        try:\r\n            self.games.register_participant(participant, event)\r\n            self.view.display_msg(f\"¡Participante añadido al evento: {event.sport} con éxito!\")\r\n\r\n        except ValueError as verr:\r\n            self.view.display_err(\r\n                f\"Algo no salio bien al registrar el participante en el evento {event.sport}- {verr}\"\r\n            )\r\n\r\n    def simulate_event_handler(self) -> None:\r\n\r\n        if not self.event_repo.list_events():\r\n            self.view.display_err(\"No hay eventos deportivos registrados, registra uno primero.\")\r\n            return\r\n\r\n        self.view.display_msg(\"Eventos deportivos disponibles para simular\")\r\n        for index, event in enumerate(self.event_repo.list_events()):\r\n            print(f\"{index + 1}. {event.sport}: (Participantes: {len(event.participants)})\")\r\n\r\n        self.view.display_msg(\" \")\r\n\r\n        selected_event = (\r\n            self.view.get_input(\"Selecciona un evento de los disponibles: \").strip().title()\r\n        )\r\n        event = self.event_repo.get_event(selected_event)\r\n\r\n        if not event:\r\n            self.view.display_err(\"El evento no existe o no esta disponible para simular.\")\r\n            return\r\n\r\n        try:\r\n            results = self.games.simulate_event(event)\r\n\r\n            self.view.display_msg(f\"Resultados del evento: {event.sport}\\n\")\r\n            for index, participant in enumerate(results):\r\n                if index == 0:\r\n                    print(f\"{index + 1}. {participant.name} - GOLD\")\r\n                elif index == 1:\r\n                    print(f\"{index + 1}. {participant.name} - SILVER\")\r\n                elif index == 2:\r\n                    print(f\"{index + 1}. {participant.name} - BRONZE\")\r\n                else:\r\n                    print(f\"{index + 1}. {participant.name}\")\r\n\r\n            self.view.display_msg(\" \")\r\n\r\n        except ValueError as verr:\r\n            self.view.display_err(verr)\r\n        except Exception as e:\r\n            self.view.display_err(e)\r\n\r\n    def get_report_handler(self):\r\n\r\n        ranked_countries = self.country_repo.get_ranking()\r\n        if not ranked_countries:\r\n            self.view.display_err(\"No hay paises registrados en el sistema\")\r\n            return\r\n\r\n        for event in self.event_repo.list_events():\r\n            print(event)\r\n            if event.gold:\r\n                print(f\"\\t1. {event.gold.name}\")\r\n                print(f\"\\t2. {event.silver.name}\")\r\n                print(f\"\\t3. {event.bronze.name}\")\r\n                print(\"\\n*********************************************\\n\")\r\n            else:\r\n                print(\"\\t- El evento no se ha simulado por el momento.\\n\")\r\n                print(\"\\n*********************************************\\n\")\r\n\r\n        self.view.display_msg(\"RANKING DE PAISES\")\r\n        print(f\"{'PAÍS':<15} | {'ORO':<5} | {'PLATA':<5} | {'BRONCE':<5}\")\r\n        print(\"-\" * 45)\r\n        for index, country in enumerate(ranked_countries):\r\n            country_cell = f\"{index + 1}. {country.name}\"\r\n            print(\r\n                f\"{country_cell:<15} | \"\r\n                f\"{country.medals['Gold']:<5} | \"\r\n                f\"{country.medals['Silver']:<5} | \"\r\n                f\"{country.medals['Bronze']:<5}\"\r\n            )\r\n        print(\"-\" * 45)\r\n\r\n\r\n# --- Main Flow ---\r\ndef main():\r\n    try:\r\n        view = View()\r\n        event_repo = EventRepository()\r\n        participants_repo = ParticipantRepository()\r\n        country_repo = CountryRepository()\r\n        games = JJOO(event_repo, participants_repo, country_repo)\r\n\r\n        controller = Controller(view, games, event_repo, participants_repo, country_repo)\r\n        print(\"Simulador de Juegos Olimpicos.\\n\")\r\n\r\n    except Exception as e:\r\n        view.display_err(f\"Error al iniciar - {e}\")\r\n\r\n    while True:\r\n        try:\r\n            view.show_menu()\r\n            option = ProgramOptions(view.get_input(\"Elige una opcion de las anteriores: \"))\r\n\r\n            match option:\r\n                case ProgramOptions.ADD_EVENT:\r\n                    controller.add_event_handler()\r\n                case ProgramOptions.ADD_PARTICIPANT:\r\n                    controller.add_participant_handler()\r\n                case ProgramOptions.SIMULATE_EVENT:\r\n                    controller.simulate_event_handler()\r\n                case ProgramOptions.GET_REPORT:\r\n                    controller.get_report_handler()\r\n                case ProgramOptions.EXIT:\r\n                    view.display_msg(\"Saliendo del programa ...\\n\")\r\n                    break\r\n\r\n        except ValueError:\r\n            view.display_err(\"Opcion no válida, pruebe otra vez.\")\r\n        except Exception as e:\r\n            view.display_err(f\"Error en el flujo repetitivo - {e}\")\r\n\r\n\r\nif __name__ == \"__main__\":\r\n    try:\r\n        main()\r\n    except Exception as e:\r\n        print(f\"Error inesperado en el arranque - {e}.\")\r\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/python/LucasRebuffo.py",
    "content": "import random\nfrom typing import List\n\n\nclass Event:\n\n    def __init__(self, nombre) -> None:\n        self.nombre = nombre\n        self.participants: List[Participant] = []\n\n    def simular(self):\n        if len(self.participants) < 3:\n            print(f\"Falta {len(self.participants) - 3 } participante|s mas\")\n        else:\n            random.shuffle(self.participants)\n            self.participants[0].oro += 1\n            self.participants[1].plata += 1\n            self.participants[2].bronce += 1\n\n            print(f\"Evento {self.nombre} simulado\")\n            print(\"Podio: \")\n            print(f\"1 - {self.participants[0].nombre}\")\n            print(f\"2 - {self.participants[1].nombre}\")\n            print(f\"3 - {self.participants[2].nombre}\")\n            print(\"\\n\")\n\n    def agregarParticipante(self, *participantes):\n\n        for participant in participantes:\n            self.participants.append(participant)\n\n\nclass Participant:\n\n    def __init__(self, nombre, pais) -> None:\n        self.nombre = nombre\n        self.pais = pais\n        self.oro = 0\n        self.plata = 0\n        self.bronce = 0\n\n    def __str__(self) -> str:\n        print(f\"Nombre: {self.nombre} > Nacionalidad: {self.pais}\")\n\n\nparticipant1 = Participant(\"lucas\", \"Argentina\")\nparticipant2 = Participant(\"gaston\", \"España\")\nparticipant3 = Participant(\"jose\", \"España\")\nparticipant4 = Participant(\"marta\", \"Argentina\")\nparticipant5 = Participant(\"belen\", \"Uruguay\")\nparticipant6 = Participant(\"jhon\", \"EEUU\")\nparticipant7 = Participant(\"steven\", \"EEUU\")\nparticipant8 = Participant(\"ahmed\", \"Arabia\")\nparticipant8 = Participant(\"maria\", \"Arabia\")\nparticipant9 = Participant(\"sheila\", \"Uruguay\")\nparticipant10 = Participant(\"gertha\", \"Alemania\")\nparticipant11 = Participant(\"hunter\", \"Alemania\")\nparticipant12 = Participant(\"igor\", \"Rusia\")\nparticipant13 = Participant(\"katrina\", \"Rusia\")\n\n\nevento1 = Event(\"Evento1\")\nevento1.agregarParticipante(participant1, participant2, participant3, participant4)\nevento2 = Event(\"Evento2\")\nevento2.agregarParticipante(participant5, participant6, participant7, participant8)\nevento3 = Event(\"Evento3\")\nevento3.agregarParticipante(\n    participant9, participant10, participant11, participant12, participant13\n)\n\neventos = [evento1, evento2, evento3]\n\n\ndef info_evento(evento: Event):\n    print(f\"Nombre de evento: {evento.nombre}\")\n    for participante in evento.participants:\n        print(participante.nombre)\n    print(\"---------------------------------\\n\")\n\n\ndef mostrar_ganadores():\n    for evento in eventos:\n        print(f\"Evento: {evento.nombre} Ganador: {evento.participants[0].nombre}\")\n        print(f\"Evento: {evento.nombre} Segundo: {evento.participants[1].nombre}\")\n        print(f\"Evento: {evento.nombre} Tercero: {evento.participants[2].nombre}\")\n    print(\"\\n\")\n\n\ndef mostrar_ranking():\n    participantes = []\n    for evento in eventos:\n        participantes.extend(evento.participants)\n\n    paises = list(set(map(lambda x: x.pais, participantes)))\n    paises = list((map(lambda x: {\"pais\": x, \"contador\": 0}, paises)))\n\n    participantes = list(map(\n        lambda x: {\"pais\": x.pais, \"cant_medallas\": x.oro + x.plata + x.bronce},\n        participantes,\n    ))\n\n    ranking = []\n\n    for pais in paises:\n        for partcipante in participantes:\n            if pais[\"pais\"] == partcipante[\"pais\"]:\n                pais[\"contador\"] += partcipante[\"cant_medallas\"]\n        ranking.append(pais)\n\n    pos = 1\n\n    ranking = sorted(ranking,key=lambda x: x[\"contador\"],reverse=True)\n\n    for pais in ranking:\n        print(f\"{pos} - {pais[\"pais\"]}. Coantidad de medallas: {pais[\"contador\"]}\")\n        pos += 1\n\n    print(\"\\n\")\ndef celebrar_juegos():\n\n    while True:\n\n        print(\"1 - Registrar evento\")\n        print(\"2 - Registrar participante\")\n        print(\"3 - Simular eventos\")\n        print(\"4 - Crear informe\")\n        print(\"5 - Mostrar estado de eventos\")\n        print(\"6 - Salir\")\n        print(\"\\n\")\n\n        op = int(input(\"Ingresa un valor\\n\"))\n        print(\"\\n\")\n\n        match op:\n            case 1:\n                nombre = input(\"Ingrese nombre de evento: \\n\")\n                eventos.append(Event(nombre))\n\n            case 2:\n                nombre_evento = input(\"Ingrese nombre de evento: \\n\")\n                nombre_participante = input(\"Ingrese nombre de participante: \\n\")\n                pais_participante = input(\"Ingrese pais de participante: \\n\")\n\n                evento: Event = filter(lambda x: x.nombre == nombre_evento, eventos)\n                evento.agregarParticipante(\n                    Participant(nombre_participante, pais_participante)\n                )\n            case 3:\n                for evento in eventos:\n                    evento.simular()\n            case 4:\n                mostrar_ganadores()\n                mostrar_ranking()\n            case 5:\n                for evento in eventos:\n                    info_evento(evento)\n            case 6:\n                break\n            case _:\n                print(\"Operacion no valida\")\n\n\ncelebrar_juegos()\n\n\n\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/python/Nicojsuarez2.py",
    "content": "# #31 SIMULADOR JUEGOS OLÍMPICOS\n> #### Dificultad: Difícil | Publicación: 29/07/24 | Corrección: 05/08/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * ¡Los JJOO de París 2024 han comenzado!\n * Crea un programa que simule la celebración de los juegos.\n * El programa debe permitir al usuario registrar eventos y participantes,\n * realizar la simulación de los eventos asignando posiciones de manera aleatoria\n * y generar un informe final. Todo ello por terminal.\n * Requisitos:\n * 1. Registrar eventos deportivos.\n * 2. Registrar participantes por nombre y país.\n * 3. Simular eventos de manera aleatoria en base a los participantes (mínimo 3).\n * 4. Asignar medallas (oro, plata y bronce) basándose en el resultado del evento.\n * 5. Mostrar los ganadores por cada evento.\n * 6. Mostrar el ranking de países según el número de medallas.\n * Acciones:\n * 1. Registro de eventos.\n * 2. Registro de participantes.\n * 3. Simulación de eventos.\n * 4. Creación de informes.\n * 5. Salir del programa.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/python/SooHav.py",
    "content": "# 31 SIMULADOR JUEGOS OLÍMPICOS\n\nimport random\nimport pandas as pd\n\n# Registro de personas\n\n\nclass RegistroPersonas:\n    __instance = None\n\n    @staticmethod\n    def get_instance():\n        if RegistroPersonas.__instance is None:\n            RegistroPersonas.__instance = RegistroPersonas()\n        return RegistroPersonas.__instance\n\n    def __init__(self):\n        self.personas = []\n\n    def registrar_persona(self, nombre, pais, deporte):\n        self.personas.append((nombre, pais, deporte))\n\n    def obtener_personas(self):\n        return self.personas\n\n# Registro de eventos olímpicos\n\n\nclass RegistroEventos:\n    __instance = None\n\n    @staticmethod\n    def get_instance():\n        if RegistroEventos.__instance is None:\n            RegistroEventos.__instance = RegistroEventos()\n        return RegistroEventos.__instance\n\n    def __init__(self):\n        self.eventos = []\n\n    def registrar_evento(self, descripcion, fecha):\n        self.eventos.append((descripcion, fecha))\n\n    def obtener_eventos(self):\n        return [evento[0] for evento in self.eventos]\n\n# Simulador de eventos\n\n\ndef simular_podio(participantes, num_ganadores=3):\n    if len(participantes) < num_ganadores:\n        raise ValueError(\"No hay suficientes participantes para el podio.\")\n\n    random.shuffle(participantes)\n    podio = participantes[:num_ganadores]\n    categorias = [\"Oro\", \"Plata\", \"Bronce\"]\n    return [(participante, categorias[i]) for i, participante in enumerate(podio)]\n\n# Contador de medallas por país\n\n\ndef contar_medallas(resultados):\n    conteo_medallas = {}\n    for deporte, resultados_deporte in resultados.items():\n        for atleta, medalla in resultados_deporte:\n            pais = atleta[1]\n            if pais not in conteo_medallas:\n                conteo_medallas[pais] = {\n                    'Oro': 0, 'Plata': 0, 'Bronce': 0, 'Total': 0}\n            conteo_medallas[pais][medalla] += 1\n            conteo_medallas[pais]['Total'] += 1\n    return conteo_medallas\n\n# Función para mostrar el menú\n\n\ndef menu():\n    while True:\n        print(\"Menú:\")\n        print(\"1. Registrar evento\")\n        print(\"2. Registrar persona\")\n        print(\"3. Simular podios\")\n        print(\"4. Mostrar resultados\")\n        print(\"5. Salir\")\n        opcion = input(\"Ingrese una opción: \")\n        try:\n            return int(opcion)\n        except ValueError:\n            print(\"Opción inválida. Por favor, ingrese un número entero.\")\n\n\ndef menu_resultados():\n    while True:\n        print(\"Menú Resultados:\")\n        print(\"1. Ranking por países\")\n        print(\"2. Ganadores por deportes\")\n        print(\"3. Salir\")\n        opcion = input(\"Ingrese una opción: \")\n        try:\n            return int(opcion)\n        except ValueError:\n            print(\"Opción inválida. Por favor, ingrese un número entero.\")\n\n\n# Instanciar los registros de personas y eventos\nregistro_personas = RegistroPersonas.get_instance()\nregistro_eventos = RegistroEventos.get_instance()\n\nresultados = {}\n\nwhile True:\n    opcion = menu()\n\n    if opcion == 1:\n        evento = input(\"Ingrese el nombre del deporte: \").strip()\n        fecha = input(\"Ingrese la fecha de la final: \")\n        registro_eventos.registrar_evento(evento, fecha)\n\n    elif opcion == 2:\n        nombre = input(\"Ingrese el nombre del atleta: \").strip()\n        pais = input(\"Ingrese el país del atleta: \").strip()\n        listado_eventos = registro_eventos.obtener_eventos()\n        print(\"¿A que evento se registra?\")\n        print(f\"Deporte: \")\n        for deporte in listado_eventos:\n            print(f\"{deporte}\")\n        deporte = input(\"Ingrese el deporte: \").strip()\n        registro_personas.registrar_persona(nombre, pais, deporte)\n\n    elif opcion == 3:\n        listado_personas = registro_personas.obtener_personas()\n        listado_eventos = registro_eventos.obtener_eventos()\n\n        if len(listado_personas) < 3:\n            print(\"Error: Debes registrar al menos 3 atletas.\")\n        elif len(listado_eventos) < 1:\n            print(\"Error: Debes registrar al menos un evento.\")\n        else:\n            for evento in listado_eventos:\n                participantes_evento = random.sample(\n                    listado_personas, k=len(listado_personas))\n                podio = simular_podio(participantes_evento)\n                resultados[evento] = podio\n            print(\"Simulación de podios completada.\")\n\n    elif opcion == 4:\n        if not resultados:\n            print(\"No hay resultados para mostrar. Primero realiza una simulación.\")\n        else:\n            while True:\n                opcion_resultados = menu_resultados()\n\n                if opcion_resultados == 1:\n                    conteo = contar_medallas(resultados)\n                    data = [{'País': pais, **medallas}\n                            for pais, medallas in conteo.items()]\n                    df = pd.DataFrame(data)\n                    df = df.sort_values(by=['Oro', 'Total'], ascending=False)\n                    print(df)\n\n                elif opcion_resultados == 2:\n                    for evento, ganadores in resultados.items():\n                        print(f\"Deporte: {evento}\")\n                        for atleta, medalla in ganadores:\n                            print(f\"{medalla}: {atleta[0]} ({atleta[1]})\")\n                    print()\n\n                elif opcion_resultados == 3:\n                    break\n\n    elif opcion == 5:\n        print(\"¡Hasta luego!\")\n        break\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/python/Trufoplus.py",
    "content": "from random import randint, choice\n\nclass SignEvent:\n    \"\"\"\n    Registra un evento\n    \"\"\"\n    event_list = [] #Listado de eventos\n    \n    def __init__ (self, name: str):\n        self.name = name\n        SignEvent.event_list.append(self)       \n        \n\nclass SignParticipant:\n    \"\"\"\n    Registra un participante\n    \"\"\"   \n    def __init__(self, name: str, country: str):\n        self.name = name\n        self.country = country\n        self.wins = 0\n        \n        # Verifica si el país ya está en la lista de países, lo agrega si no esta\n        if country not in [c.country for c in CountryRanking.countries_list]:\n            CountryRanking(country)\n    \n    def __str__(self):\n        return f\"{self.name} de {self.country}\"\n        \n\nclass Event(SignEvent):\n    \"\"\"\n    Inicia el evento y agrega a los participantes\n    \"\"\"\n    def __init__(self, name: str):\n        super().__init__(name)\n        self.participants_list = []\n\n    def add_participant(self, participant: SignParticipant):\n        self.participants_list.append(participant)\n    \n    def get_participants(self):\n        return self.participants_list\n\n\nclass StartEvent:\n    \"\"\"\n    Da comienzo a un evento de manera aleatoria\n    \"\"\"\n    def start(self):\n        if SignEvent.event_list:\n            # Inicializamos un evento aleatorio y se elimina de la lista\n            random_index = randint(0, len(SignEvent.event_list)-1)\n            random_event = SignEvent.event_list.pop(random_index)\n            print(f'\\nComienza el evento {random_event.name}!!')\n            \n            return random_event\n        \n        else:\n            print('Se acabaron los eventos, gracias por asistir.')\n            \n            return None\n\n    \nclass SimulEvent():\n    \"\"\"\n    Simula el evento elegido\n    \"\"\"\n    @staticmethod\n    def start(event: Event):\n        #Simula los 'combate'\n        winner_1 = SimulEvent.fight(event, 0, 1)\n        winner_2 = SimulEvent.fight(event, 2, 3)\n        \n        # Combate entre los ganadores de los combates anteriores\n        SimulEvent.fight(event, winner_1, winner_2)\n        \n        # Muestra el ranking\n        EventRanking.ranking(event)\n\n    \n    @staticmethod\n    def fight(event: Event, index1: int, index2: int):\n        p_1 = event.participants_list[index1]    \n        p_2 = event.participants_list[index2] \n\n        print(f\"{p_1} VS {p_2}\")\n        \n        winner = choice([p_1, p_2])\n        print(f\"{winner.name} ha vencido!!\\n\")\n        winner.wins += 1\n        \n        # Retorna el índice del ganador en la lista de participantes\n        return event.participants_list.index(winner)\n        \n\nclass EventRanking():\n    @staticmethod\n    def ranking(event: Event):\n            ranking = sorted(event.participants_list, key = lambda x : x.wins, reverse=True) \n            medals = ['oro', 'plata', 'cobre']\n            \n            for index, participant in enumerate(ranking):\n                if index < 3:\n                    print(f\"Medalla de {medals[index]} para {participant} - {participant.wins} victorias\")\n                    index_country = next((i for i, c in enumerate(CountryRanking.countries_list) if c.country == participant.country), None)\n                    if index_country is not None:\n                        CountryRanking.countries_list[index_country].medals[index] += 1\n                        CountryRanking.countries_list[index_country].update_total_medals()\n                \n\nclass CountryRanking():\n    countries_list = []\n    \n    def __init__(self, country):\n        self.country = country\n        self.medals = [0, 0, 0]  # [oro, plata, cobre]\n        self.total = 0\n        CountryRanking.countries_list.append(self)\n    \n    def update_total_medals(self):\n        self.total = sum(self.medals)\n    \n    def __str__(self):\n        return self.country\n    \n    @staticmethod\n    def ranking():\n        ranking = sorted(CountryRanking.countries_list, key = lambda x : x.total, reverse=True) \n\n        print(\"\\nClasificación por países:\")\n        for index,country in enumerate(ranking):\n            print(f\"{index + 1} - {country.country} - Oro: {country.medals[0]}, Plata: {country.medals[1]}, Cobre: {country.medals[2]}, Total: {country.total}\")\n\n\n\n# Agregamos varios eventos y participantes\nevent_1 = Event('Atletismo')\nevent_1.add_participant(SignParticipant('Daniel Galvan', 'España'))\nevent_1.add_participant(SignParticipant('Mark Ruffalo', 'Usa'))\nevent_1.add_participant(SignParticipant('Tofu Minamato', 'Japon'))\nevent_1.add_participant(SignParticipant('Milano milanesa', 'Italia'))\n\n\nevent_2 = Event('Baloncesto')\nevent_2.add_participant(SignParticipant('Daniel Galvan', 'España'))\nevent_2.add_participant(SignParticipant('Mark Ruffalo', 'Usa'))\nevent_2.add_participant(SignParticipant('Tofu Minamato', 'Japon'))\nevent_2.add_participant(SignParticipant('Milano milanesa', 'Italia'))\n\nevent_3 = Event('Boxeo')\nevent_3.add_participant(SignParticipant('Daniel Galvan', 'España'))\nevent_3.add_participant(SignParticipant('Mark Ruffalo', 'Usa'))\nevent_3.add_participant(SignParticipant('Tofu Minamato', 'Japon'))\nevent_3.add_participant(SignParticipant('Milano milanesa', 'Italia'))\n\nevent_4 = Event('Tiro con arco')\nevent_4.add_participant(SignParticipant('Daniel Galvan', 'España'))\nevent_4.add_participant(SignParticipant('Mark Ruffalo', 'Usa'))\nevent_4.add_participant(SignParticipant('Tofu Minamato', 'Japon'))\nevent_4.add_participant(SignParticipant('Milano milanesa', 'Italia'))\n\nevent_5 = Event('Natación')\nevent_5.add_participant(SignParticipant('Daniel Galvan', 'España'))\nevent_5.add_participant(SignParticipant('Mark Ruffalo', 'Usa'))\nevent_5.add_participant(SignParticipant('Tofu Minamato', 'Japon'))\nevent_5.add_participant(SignParticipant('Milano milanesa', 'Italia'))\n\nevent_6 = Event('Esgrima')\nevent_6.add_participant(SignParticipant('Daniel Galvan', 'España'))\nevent_6.add_participant(SignParticipant('Mark Ruffalo', 'Usa'))\nevent_6.add_participant(SignParticipant('Tofu Minamato', 'Japon'))\nevent_6.add_participant(SignParticipant('Milano milanesa', 'Italia'))\n\n\n# Inicializa los eventos de manera aleatoria\nwhile SignEvent.event_list:\n    start_event = StartEvent().start()\n    if start_event:\n        SimulEvent.start(start_event)\n\n# Mostrar la clasificación final por países\nCountryRanking.ranking()\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/python/adra-dev.py",
    "content": "\"\"\"\nEJERCICIO:\n¡Los JJOO de París 2024 han comenzado!\nCrea un programa que simule la celebración de los juegos.\nEl programa debe permitir al usuario registrar eventos y participantes,\nrealizar la simulación de los eventos asignando posiciones de manera aleatoria\ny generar un informe final. Todo ello por terminal.\n \nRequisitos:\n1. Registrar eventos deportivos.\n2. Registrar participantes por nombre y país.\n3. Simular eventos de manera aleatoria en base a los participantes (mínimo 3).\n4. Asignar medallas (oro, plata y bronce) basándose en el resultado del evento.\n5. Mostrar los ganadores por cada evento.\n6. Mostrar el ranking de países según el número de medallas.\n\nAcciones:\n1. Registro de eventos.\n2. Registro de participantes.\n3. Simulación de eventos.\n4. Creación de informes.\n5. Salir del programa.\n\nby adra-dev\n\"\"\"\n\n\nimport random\n\nclass Participant:\n\n    def __init__(self, name, country):\n        self.name = name\n        self.country = country\n\n    def __eq__(self, other: object) -> bool:\n        if isinstance(other, Participant):\n            return self.name == other.name and self.country == other.country\n        return False\n    \n    def __hash__(self) -> int:\n        return hash(self.name, self.country)\n\n\nclass Olympics:\n    def __init__(self):\n        self.events = []\n        self.participants = {}\n        self.event_results = {}\n        self.country_results = {}\n\n    def register_event(self):\n        \n        event = input(\"Ingresa el nombre del evento deportivo: \").strip()\n\n        if event in self.events:\n            print(f\"El evento {event} ya se encuentra registrado.\")\n        else:\n            self.events.append(event)\n            print(f\"El evento {event} se ha registrado correctamente.\")\n\n    def register_participant(self):\n\n        if not self.events:\n            print(\"No hay eventos regsitrados, porfavor registra uno primero.\")\n            return\n        \n        name = input(\"Ingresa el nombre del participante: \").strip()\n        country = input(\"Ingresa el pais del participante: \").strip()\n        participant = Participant(name, country)\n\n        print(\"Eventos deportivos disponibles: \")\n        for index, event in enumerate(self.events):\n            print(f\"{index + 1}. {event}\")\n\n        event_choice = int(input(\n            \"Selecciona el numero del evento para asignar al participante: \")) -1\n\n        if event_choice >= 0 and event_choice < len(self.events):\n\n            event = self.events[event_choice]\n            \n\n            if event in self.participants and participant in self.participants[event]:\n                print(\n                    f\"El participante {name} del pais {country} ya se encuentra registrado en el evento dportivo {event}.\")\n            else:\n\n                if event not in self.participants:\n                    self.participants[event] = []\n\n                self.participants[event].append(participant)\n                print(\n                    f\"El participante {name} del pais {country} se ha registrado correctamente en el evento dportivo {event}.\")\n        else:\n            print(\n                \"Seleccion de vento deportivo invalido. El participante no se ha registrado.\")\n            \n    def simulate_events(self):\n\n        if not self.events:\n            print(\"No hay eventos registrados. Por favor, registra uno primero.\")\n            return\n        \n        for event in self.events:\n\n             if len(self.participants[event]) < 3:\n                print(\n                    f\"No ay participantes suficientes para simular el evento {event} (mininmo 3).\") \n                continue\n             \n             event_participants = random.sample(self.participants[event], 3)\n             random.shuffle(event_participants)\n\n             gold, silver, bronze = event_participants\n             self.event_results[event] = [gold, silver, bronze]\n\n             self.update_country_results(gold.country, \"gold\")\n             self.update_country_results(silver.country, \"silver\")\n             self.update_country_results(bronze.country, \"bronze\")\n\n             print(f\"Resultados simulacion del evento {event}\")\n             print(f\"Oro: {gold.name} ({gold.country})\")\n             print(f\"Plata: {silver.name} ({silver.country})\")\n             print(f\"Bronce: {bronze.name} ({bronze.country})\")\n\n    def update_country_results(self, country, medal):\n        if country not in self.country_results:\n            self.country_results[country] = {\n                \"gold\": 0, \"silver\": 0, \"bronze\": 0}\n\n        self.country_results[country][medal] += 1\n\n    def show_report(self):\n\n        print(\"Informe Juegos Olimpicos: \")\n\n        if self.event_results:\n\n            print(\"Informe por evento:\")\n\n            for event, winners in self.event_results.items():\n                print(f\"Evento: {event}\")\n                print(f\"Oro: {winners[0].name} ({winners[0].country})\")\n                print(f\"Plata: {winners[1].name} ({winners[1].country})\")\n                print(f\"Bronce: {winners[2].name} ({winners[2].country})\")\n        else:\n            print(\"No hay resultados de registrados.\")\n        \n        print()\n\n        if self.country_results:\n\n            print(\"Informe por país:\")\n\n            for country, medals in  sorted(self.country_results.items(), key=lambda x: (\n                x[1][\"gold\"], x[1][\"silver\"], x[1][\"bronze\"]), reverse=True):\n\n                print(f\"{country}: Oro {medals['gold']}, Plata {medals['silver']}, Bronce {medals['bronze']}\")\n            \n            \n\n        else:\n            print(\"No hay medallas por pais registradas.\")\n\n\nolympics =  Olympics()\n\n\nprint(\"Simulador de Juegos Olimpicos\")\n\nwhile True:\n\n    print()\n\n    print(\"1. Registro de eventos.\")\n    print(\"2. Registro de participantes.\")\n    print(\"3. Simulación de eventos.\")\n    print(\"4. Creación de informes.\")\n    print(\"5. Salir del programa.\")\n\n    option = input(\"Selecciona una accion: \")\n\n    match option:\n        case \"1\":\n            olympics.register_event()\n        case \"2\":\n            olympics.register_participant()\n        case \"3\":\n            olympics.simulate_events()\n        case \"4\":\n            olympics.show_report()\n        case \"5\":\n            print(\"Saliendo del simuador de . . .\")\n            break\n        case _:\n            print(\"Opcion invalida. Por favor, selecciona una nueva.\")\n    \n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/python/alanshakir.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * ¡Los JJOO de París 2024 han comenzado!\n * Crea un programa que simule la celebración de los juegos.\n * El programa debe permitir al usuario registrar eventos y participantes,\n * realizar la simulación de los eventos asignando posiciones de manera aleatoria\n * y generar un informe final. Todo ello por terminal.\n * Requisitos:\n * 1. Registrar eventos deportivos.\n * 2. Registrar participantes por nombre y país.\n * 3. Simular eventos de manera aleatoria en base a los participantes (mínimo 3).\n * 4. Asignar medallas (oro, plata y bronce) basándose en el resultado del evento.\n * 5. Mostrar los ganadores por cada evento.\n * 6. Mostrar el ranking de países según el número de medallas.\n * Acciones:\n * 1. Registro de eventos.\n * 2. Registro de participantes.\n * 3. Simulación de eventos.\n * 4. Creación de informes.\n * 5. Salir del programa.\n */\n\"\"\"\nimport random\nclass Participant:\n    def __init__(self, name, country):\n        self.name = name\n        self.country = country\n        \n    def __eq__(self, value: object) -> bool:\n        if isinstance(value, Participant):\n            return self.name == value.name and self.country == value.country\n        return False\n    \n    def __hash__(self) -> int:\n        return hash(self.name, self.country)\n\nclass OlimpicsGames:\n    def __init__(self):\n        self.events = []\n        self.participants = {}\n        self.results = {}\n        self.country_results = {}\n\n    \n    def register_event(self):\n        event = input(\"Introduce el nombre del evento deportivo: \").strip()\n        if event in self.events:\n            print(f\"{event} ya esta registrado\")\n        else:\n\n            self.events.append(event)\n            print(f\"{event} registrado exitosamente\")\n    \n    def register_participant(self):\n        if not self.events:\n            print(\"No hay eventos registrados\")\n            return\n        else: \n            name = input(\"Introduce el nombre del participante: \").strip()\n            country = input(\"Introduce el pais del participante: \").strip()\n            participant = Participant(name, country)\n\n            print(\"Eventos disponible\")\n            for index, event in enumerate(self.events):\n                print(f\"{index +1}. {event}\")\n\n            event_choice = int(input(\"Selecciona un indice para asignar evento al participante: \")) - 1\n\n            if event_choice >= 0 and event_choice <= len(self.events):\n                event = self.events[event_choice]\n                if event in self.participants and participant in self.participants[event]:\n                    print(f\"{participant} ya esta registrado en el evento\")\n                else:\n                    if event not in self.participants:\n                        self.participants[event] = []\n                    self.participants[event].append(participant)\n                    print(f\"participante {name} se ha registrado en el evento {event}\")\n            else:\n                print(\"Evento invalido\")\n\n    def simulator_events(self):\n        if not self.events:\n            print(\"No hay eventos registrados\")\n            return\n        for event in self.events:\n            if len(self.participants[event]) < 3:\n                print(f\"no hay participantes suficientes para el {event}\")\n                continue\n            event_participants = random.sample(self.participants[event], 3)\n            random.shuffle(event_participants)\n\n            gold, silver, bronze = event_participants\n            self.results[event] = [gold, silver, bronze]\n\n            self.update_country_results(gold.country, \"gold\")\n            self.update_country_results(silver.country, \"silver\")\n            self.update_country_results(bronze.country, \"bronze\")\n\n            print(f\"resultados de la simulacion: {event}\")\n            print(f\"Oro: {gold.name} ({gold.country})\")\n            print(f\"Silver: {silver.name} ({silver.country})\")\n            print(f\"Bronze: {bronze.name} ({bronze.country})\")\n    \n    def update_country_results(self, country, medal):\n        if country not in self.country_results:\n            self.country_results[country] = {\n                \"gold\" : 0,\n                \"silver\" : 0,\n                \"bronze\": 0\n            }\n        self.country_results[country][medal] += 1\n\n    def create_report(self):\n        print(\"Informe juegos\")\n        if self.results:\n            for event, winners in self.results.items():\n                print(f\"resultados: {event}\")\n                print(f\"Oro: {winners[0].name} ({winners[0].country})\")\n                print(f\"Silver: {winners[1].name} ({winners[1].country})\")\n                print(f\"Bronze: {winners[2].name} ({winners[2].country})\")\n        else:\n            print(\"No hay eventos registrados\")\n        \n        if self.country_results:\n            for country, medals in sorted(self.country_results.items(), key=lambda x: (x[1][\"gold\"], x[1][\"silver\"], x[1][\"bronze\"]), reverse=True):\n                print(f\"{country}: Oro {medals['gold']}, Silver {medals['silver']}, Bronze {medals['bronze']}\")\n        else:\n            print(\"No hay medallas por pais\")   \n\n\n\n\nolimpics = OlimpicsGames()\nprint(\"Simulador de juegos olimpicos\")\nwhile True:\n    print()\n    print(\"1. Registro de eventos.\") \n    print(\"2. Registro de participantes.\")\n    print(\"3. Simulación de eventos.\")\n    print(\"4. Creación de informes.\")\n    print(\"5. Salir del programa.\")\n    print()\n\n    option = input(\"Elige una accion: \")\n    print()\n    match option:\n        case \"1\":\n            olimpics.register_event()\n        case \"2\":\n            olimpics.register_participant()\n        case \"3\":\n            olimpics.simulator_events()\n        case \"4\":\n            olimpics.create_report()\n        case \"5\":\n            print(\"Fin de la simulacion.\")\n            break\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/python/avcenal.py",
    "content": "#El enfoque para implementar este programa ha sido tratando de seguir los principios SOLID\n#MEJORAS POSIBLES A IMPLEMENTAR:\n# - Regex en todos los inputs\n# - Uso de archivos externos para guardar información y generar informes\n# - Logging para el debug e información de sistema\n# - Manejo de excepciones: sería necesario probablemente implementarlo en alguno de los métodos sobre todo si se incluyera el control de los input por Regex.\n\nfrom abc import ABC,abstractmethod\nfrom random import randint\n\n#INTERFACES ABSTRACTAS\nclass AbstractEvent(ABC):\n    @abstractmethod\n    def __init__(self,discipline:str):\n        pass\n\nclass AbstractParticipant(ABC):\n    @abstractmethod\n    def __init__(self,name:str,country:str):\n        pass\n\nclass AbstractListOfEvents(ABC):\n    @abstractmethod\n    def __init__(self) -> None:\n        pass\n\nclass AbstractCountry(ABC):\n    @abstractmethod\n    def __init__(self,name:str,medals_quantity:int=0, gold: int=0,silver:int=0,bronze:int=0):\n        pass\n\nclass AbstractOlympicWinner(ABC):\n    @abstractmethod\n    def __init__(self,name:str,country:str,medals_quantity:int=0,gold:int=0,silver:int=0,bronze:int=0):\n        pass\n\nclass AbstractInformsGenerator(ABC):\n    @abstractmethod\n    def generate_country_informs(self):\n        pass\n\n    @abstractmethod\n    def generate_winner_informs(self):\n        pass\n\nclass AbstractInformsPrinter(ABC):\n    @abstractmethod\n    def show_country_ranking(self):\n        pass\n\n    abstractmethod\n    def show_winners_ranking(self):\n        pass\n\nclass AbstractEventRegister(ABC):\n    @abstractmethod\n    def event_register(self,event:AbstractEvent,event_list:AbstractListOfEvents):\n        pass\n\nclass AbstractParticipantRegister(ABC):\n    @abstractmethod\n    def participant_register(self,event:AbstractEvent,participant:AbstractParticipant):\n        pass\n\nclass AbstractEventSimulator(ABC):\n    @abstractmethod\n    def simulate_event(self,event:AbstractEvent):\n        pass\n\n    @abstractmethod\n    def show_event_winners(self,event:AbstractEvent):\n        pass\n\n#CLASES QUE HEREDAN DE LAS INTERFACES ABSTRACTAS\n\nclass Participant(AbstractParticipant):\n    def __init__(self,name:str,country:str):\n        self.data = {\"name\":name,\"country\":country}\n        self.medals = {\"quantity\":0,\"gold\":0,\"silver\":0,\"bronze\":0}\n\n    def print_participant(self):\n        return f\"- Nombre: {self.data[\"name\"]}\\n- País: {self.data[\"country\"]}\\n\"\n\nclass Event(AbstractEvent):\n    def __init__(self,discipline:str):\n        self.discipline = discipline.upper()\n        self.participant_list = []\n        self.event_winners = []\n\n    def add_participant(self,participant:AbstractParticipant):\n        return self.participant_list.append(participant)\n    \n    def show_details(self): #imprime por pantalla la disciplina del evento y el número de participantes\n        print(f\"Disciplina: {self.discipline}\")\n        print(f\"Número de participantes:{len(self.participant_list)}\")\n        print(\"\\n\")\n\n    def event_completed(self): #devuelve un true si el evento está completado y un false si no lo está\n        if len(self.event_winners) == 0:\n            return False\n        else:\n            return True\n\nclass Events(AbstractListOfEvents):\n    def __init__(self):\n        self.events = list()\n\n    def add_event(self,event:AbstractEvent):\n        return self.events.append(event)\n    \n    def get_event(self,position:int): #devuelve el evento dada una posición en la lista\n        try:\n            return self.events[position]\n        except:\n            print(\"Esa disciplina no está presente en estos Juegos Olímpicos\")\n    \n    def show_events(self): #muestra todos los eventos que hay almacenados\n        for event in self.events:\n            event.show_details()\n\n    def find_event(self,event:str): #busca un evento y devuelve el índice que tiene dentro de la lista\n        found = False\n        event_index = None\n        for index,listed_event in enumerate(self.events):\n            if listed_event.discipline == event:\n                found = True\n                event_index = index\n                break\n        if found:\n            return event_index\n        else:\n            print(\"Esta disciplina no se encuentra en la lista\\n\") #podría preguntar si se quiere añadir...            \n\nclass EventRegister(AbstractEventRegister):\n    def event_register(self,event:AbstractEvent,event_list:AbstractListOfEvents): #registra una disciplina y no deja registrar disciplinas con el mismo nombre\n        event_found = False\n        for element in event_list.events:\n            if element.discipline == event.discipline:\n                event_found = True\n        if not event_found:\n            event_list.add_event(event)\n            print(\"Disciplina registrada\\n\")\n        else:\n            print(\"Disciplina anteriormente registrada, prueba de nuevo\\n\")\n\nclass ParticipantRegister(AbstractParticipantRegister):\n    def participant_register(self,event:AbstractEvent,participant:AbstractParticipant): #registra un participante y no deja registrar un participante con el mismo nombre\n        participant_found = False                                                       # -- se podría controlar comparando nombre y país\n        for element in event.participant_list:\n            if element.data[\"name\"] == participant.data[\"name\"]:\n                participant_found = True\n        if not participant_found:\n            event.add_participant(participant)\n        else:\n            print(\"Participante anteriormente registrado.\\n\")\n\nclass EventSimulator(AbstractEventSimulator):\n    def simulate_event(self,event:AbstractEvent): #simula un evento cogiendo un número aleatorio entre 0 y el número de participantes -1\n        if len(event.participant_list) < 3:       # y guarda los ganadores en una lista siendo el 0 - ORO, 1 - PLATA, 2 - BRONCE\n            print(\"No se puede simular el evento, no hay participantes suficientes\")\n        else: \n            win_count = 0\n            index = 0\n            while win_count < 3:\n                index = randint(0,len(event.participant_list)-1)\n                if event.participant_list[index] not in event.event_winners:\n                    event.participant_list[index].medals[\"quantity\"] = 1\n                    #si win_count = 0 -- ORO || win_count = 1 -- PLATA || win_count = 2 -- BRONCE\n                    if win_count == 0:\n                        event.participant_list[index].medals[\"gold\"] += 1\n                    elif win_count == 1:\n                        event.participant_list[index].medals[\"silver\"] += 1\n                    elif win_count == 2:\n                        event.participant_list[index].medals[\"bronze\"] += 1\n                    event.event_winners.append(event.participant_list[index])\n                    win_count += 1\n    \n    def show_event_winners(self,event:AbstractEvent): #muestra el detalle de los ganadores y qué medalla han ganado. Si no hay ganadores, muestra un mensaje de que el evento no se ha celebrado\n        if len(event.event_winners) != 0:\n            print(f\"Disciplina: {event.discipline}\\nNúmero de participantes: {len(event.participant_list)}\\nORO\\n{event.event_winners[0].print_participant()}\\nPLATA\\n{event.event_winners[1].print_participant()}\\nBRONCE\\n{event.event_winners[2].print_participant()}\\n\")\n        else:\n            print(f\"Disciplina: {event.discipline}\\n-- No se ha celebrado el evento --\\n\")\n\nclass OlympicWinner(AbstractOlympicWinner): #clase para almacenar el ranking de los deportistas que han participado, con su cantidad de medallas y tipo\n    def __init__(self,name:str,country:str,medals_quantity:int=0,gold:int=0,silver:int=0,bronze:int=0):\n        self.data ={\"name\":name,\"country\":country}\n        self.medals = {\"quantity\":medals_quantity,\"gold\":gold,\"silver\":silver,\"bronze\":bronze}\n\nclass Country(AbstractCountry): #clase para almacenar los países que han participado con su nombre, cantidad de medallas y tipo\n    def __init__(self, name:str,medals_quantity:int=0, gold: int=0,silver:int=0,bronze:int=0):\n        self.name = name\n        self.medals = {\"quantity\":medals_quantity,\"gold\":gold,\"silver\":silver,\"bronze\":bronze}\n\nclass InformsGenerator(AbstractInformsGenerator): #clase para generar los informes por país y por deportistas\n    def __init__(self):\n        self.country_ranking = []\n        self.winner_ranking = []\n\n    def generate_country_informs(self,list_of_events:AbstractListOfEvents):\n        for event in list_of_events.events:\n            for winner in event.event_winners:\n                country = next((c for c in self.country_ranking if c.name == winner.data[\"country\"]), None)\n                if country is None:\n                    country = Country(name=winner.data[\"country\"], medals_quantity=1, gold=winner.medals[\"gold\"], silver=winner.medals[\"silver\"], bronze=winner.medals[\"bronze\"])\n                    self.country_ranking.append(country) #si el país no está en la lista, lo crea con el constructor de Country\n                else:\n                    country.medals[\"quantity\"] += 1\n                    country.medals[\"gold\"] += winner.medals[\"gold\"]\n                    country.medals[\"silver\"] += winner.medals[\"silver\"]\n                    country.medals[\"bronze\"] += winner.medals[\"bronze\"] #si está, actualiza la cantidad de medallas\n\n    def generate_winner_informs(self,list_of_events:AbstractListOfEvents):\n        for event in list_of_events.events:\n            for winner in event.event_winners:\n                olympic_winner = next((ow for ow in self.winner_ranking if ow.data[\"name\"]== winner.data[\"name\"]),None)\n                if olympic_winner == None: #si el deportista no está en la lista, lo crea con el constructor de OlympicWinner\n                    self.winner_ranking.append(OlympicWinner(name=winner.data[\"name\"],country=winner.data[\"country\"],medals_quantity=1,gold=winner.medals[\"gold\"],silver=winner.medals[\"silver\"],bronze=winner.medals[\"bronze\"]))\n                else: #si el deportista está, actualiza su cantidad de medallas\n                    olympic_winner.medals[\"quantity\"] +=1\n                    olympic_winner.medals[\"gold\"] += winner.medals[\"gold\"]\n                    olympic_winner.medals[\"silver\"] += winner.medals[\"silver\"]\n                    olympic_winner.medals[\"bronze\"] += winner.medals[\"bronze\"]\n\nclass InformsPrinter(AbstractInformsPrinter):\n    def show_all_events(self,list_of_events:AbstractListOfEvents): #muestra el resultado de todos los eventos, con los ganadores de oro, plata y bronce\n        print(\"CLASIFICACIONES POR DISCIPLINA OLÍMPICA:\\n\")\n        for event in list_of_events.events:\n            EventSimulator().show_event_winners(event)\n\n    def show_country_ranking(self,inform:AbstractInformsGenerator): #ordena la lista de los países en base a medallas>oro>plata>bronce y la muestra\n        if len(inform.country_ranking) !=0:\n            print(\"RANKING DE PAÍSES (según cantidad de medallas y tipo)\")\n            sorted_countries = sorted(inform.country_ranking,key = lambda x : (x.medals[\"quantity\"],x.medals[\"gold\"],x.medals[\"silver\"],x.medals[\"bronze\"]),reverse=True)\n            for country in sorted_countries:\n                print(f\"País: {country.name}\\nMedallas: {country.medals[\"quantity\"]}\\n--Oro:{country.medals[\"gold\"]}\\n--Plata:{country.medals[\"silver\"]}\\n--Bronce:{country.medals[\"bronze\"]}\\n\")\n            inform.country_ranking = []\n\n    def show_winners_ranking(self,inform:AbstractInformsGenerator): #ordena la lista de los deportistas en base a medallas>oro>plata>bronce y la muestra\n        if len(inform.winner_ranking) != 0:\n            print(\"RANKING DE DEPORTISTAS DE LOS JUEGOS OLÍMPICOS (según cantidad de medallas y tipo)\")\n            sorted_olympic_winners = sorted(inform.winner_ranking,key = lambda x : (x.medals[\"quantity\"],x.medals[\"gold\"],x.medals[\"silver\"],x.medals[\"bronze\"]),reverse=True)\n            for olympic_winner in sorted_olympic_winners:\n                print(f\"Nombre:{olympic_winner.data[\"name\"]}\\nPaís: {olympic_winner.data[\"country\"]}\\nMedallas: {olympic_winner.medals[\"quantity\"]}\\n--Oro:{olympic_winner.medals[\"gold\"]}\\n--Plata:{olympic_winner.medals[\"silver\"]}\\n--Bronce:{olympic_winner.medals[\"bronze\"]}\\n\")\n        inform.winner_ranking = []\n\n# CLASE QUE AGRUPA LAS FUNCIONES PRINCIPALES DEL PROGRAMA\nclass MainFunctions():\n    def __init__(self,event_register:AbstractEventRegister,participant_register:AbstractParticipantRegister,event_simulator:AbstractEventSimulator,generate_informs:AbstractInformsGenerator,print_informs:AbstractInformsPrinter) -> None:\n        self.event_register = event_register\n        self.particiant_register = participant_register\n        self.event_simulator = event_simulator\n        self.generate_informs = generate_informs\n        self.print_informs = print_informs\n\n    def event_registration(self,list_of_events:AbstractListOfEvents):\n        event = Event(input(\"Dime por favor el nombre de la disciplina olímpica: \").upper())\n        self.event_register.event_register(event,list_of_events)\n        return list_of_events\n    \n    def participant_registration(self,list_of_events:AbstractListOfEvents):\n        index = None\n        event = input(\"Dime el evento en al que quieres añadir participantes: \").upper()\n        index = list_of_events.find_event(event)\n        if index != None:\n            name = input(\"Dime el nombre completo del participante: \").title()\n            country = input(\"Y por último el país que representa: \").title()\n            self.particiant_register.participant_register(list_of_events.get_event(index),Participant(name,country))\n            print(\"\\n\")\n            return list_of_events\n\n    def simulate_event(self,list_of_events:AbstractListOfEvents):\n        index = None\n        event = input(\"¿Qué evento quieres simular?: \").upper()\n        index = list_of_events.find_event(event)\n        if index != None:\n            if not list_of_events.get_event(index).event_completed():\n                self.event_simulator.simulate_event(list_of_events.get_event(index))\n                self.event_simulator.show_event_winners(list_of_events.get_event(index))\n                print(\"\\n\")\n            else:\n                print(\"El evento ya se ha terminado con el siguiente resultado\")\n                self.event_simulator.show_event_winners(list_of_events.get_event(index))\n                print(\"\\n\")\n\n    def inform_generator(self,list_of_events:AbstractListOfEvents):\n        self.generate_informs.generate_country_informs(list_of_events)\n        self.generate_informs.generate_winner_informs(list_of_events)\n        self.print_informs.show_all_events(list_of_events)\n        self.print_informs.show_country_ranking(self.generate_informs)\n        self.print_informs.show_winners_ranking(self.generate_informs)\n\n#PROGRAMA PRINCIPAL\nlist_of_events = Events()\nmain_functions = MainFunctions(EventRegister(),ParticipantRegister(),EventSimulator(),InformsGenerator(),InformsPrinter())\nprint(\"\\n\")\nprint(\"--- TE DOY LA BIENVENIDA A LA APLICACIÓN DE LAS OLIMPIADAS DE 2024 ---\")\nwhile True:\n    option = input(\"Por favor elige una opción:\\n- Registrar un Evento(E)\\n- Registrar un Participante(P)\\n- Simulación de Eventos(S)\\n- Generación de informes(G)\\n- Salir(O)\\n----> \").upper()\n    print(\"\\n\")\n    if option == \"E\":\n        main_functions.event_registration(list_of_events)\n    elif option == \"P\":\n        main_functions.participant_registration(list_of_events)\n    elif option == \"S\":\n        main_functions.simulate_event(list_of_events)\n    elif option == \"G\":\n        main_functions.inform_generator(list_of_events)\n    elif option == \"O\":\n        print(\"Gracias por usar la app de los Juegos Olímpicos 2024. Hasta pronto\")\n        break\n    else:\n        option = input(\"Tu opción no es válida, prueba de nuevo\\n\")\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/python/cristianfloyd.py",
    "content": "# EJERCICIO:\n# ¡Los JJOO de París 2024 han comenzado!\n# Crea un programa que simule la celebración de los juegos.\n# El programa debe permitir al usuario registrar eventos y participantes,\n# realizar la simulación de los eventos asignando posiciones de manera aleatoria\n# y generar un informe final. Todo ello por terminal.\n# Requisitos:\n# 1. Registrar eventos deportivos.\n# 2. Registrar participantes por nombre y país.\n# 3. Simular eventos de manera aleatoria en base a los participantes (mínimo 3).\n# 4. Asignar medallas (oro, plata y bronce) basándose en el resultado del evento.\n# 5. Mostrar los ganadores por cada evento.\n# 6. Mostrar el ranking de países según el número de medallas.\n# Acciones:\n# 1. Registro de eventos.\n# 2. Registro de participantes.\n# 3. Simulación de eventos.\n# 4. Creación de informes.\n# 5. Salir del programa.\n\n# =======================================================\n# Estructuras de datos\nimport random\n\n\nclass Medalla:\n    \"\"\"\n    Clase que representa a una medalla de los juegos olímpicos\n    \"\"\"\n\n    def __init__(self, tipo: str):\n        self.tipo = tipo\n\n    def get_tipo(self) -> str:\n        return self.tipo\n\n    def __eq__(self, other) -> bool:\n        \"\"\"\n        Funcion que compara si dos medallas son iguales\n        Parametros:\n        - other: Medalla - Medalla a comparar\n        Retorna:\n        - bool - True si las medallas son iguales, False en caso contrario\n        \"\"\"\n        if isinstance(other, Medalla):\n            return self.tipo == other.tipo\n        return False\n\n\nclass Event:\n    \"\"\"\n    Clase que representa a un evento de los juegos olímpicos\n    \"\"\"\n\n    def __init__(self, nombre):\n        self.nombre = nombre\n\n    def get_nombre(self) -> str:\n        return self.nombre\n\n\nclass Eventos:\n    \"\"\"\n    Clase que representa la lista de eventos de los juegos olímpicos\n    \"\"\"\n\n    def __init__(self):\n        self.eventos: list[Event] = []\n\n    def add_event(self, evento: Event):\n        if evento not in self.eventos:\n            self.eventos.append(evento)\n\n    def get_events(self) -> list[Event] | None:\n        if len(self.eventos) == 0:\n            return None\n        return self.eventos\n\n    def __len__(self) -> int:\n        return len(self.eventos)\n\n\nclass Participante:\n    \"\"\"\n    Clase que representa a un participante de los juegos olímpicos\n    \"\"\"\n\n    def __init__(self, nombre: str, pais: str, deporte: str):\n        self.nombre = nombre\n        self.pais = pais\n        self.deporte = deporte\n        self.eventos: list[Event] = []\n        self.medallas: list[Medalla] = []\n\n    def add_evento(self, evento: Event):\n        if evento not in self.eventos:\n            self.eventos.append(evento)\n\n    def add_medalla(self, medalla: Medalla):\n        if medalla not in self.medallas:\n            self.medallas.append(medalla)\n        else:\n            print(f\"La medalla {medalla.get_tipo()} ya está asignada\")\n\n    def get_nombre(self) -> str:\n        return self.nombre\n\n    def get_eventos(self) -> list[Event]:\n        return self.eventos\n\n    def get_medallas(self) -> list[Medalla]:\n        return self.medallas[:]\n\n    def get_medallas_tipo(self, tipo: Medalla) -> int:\n        \"\"\"funcion que devuelve el numero de medallas de un tipo\n        Parametros:\n        - tipo: Medalla - Tipo de medalla\n        Retorna:\n        - int - Numero de medallas de un tipo\n        \"\"\"\n        return len([medalla for medalla in self.medallas if medalla.get_tipo() == tipo])\n\n\nclass Participantes:\n    \"\"\"\n    Clase que representa la lista de participantes de los juegos olímpicos\n    \"\"\"\n\n    def __init__(self):\n        self.participantes: list[Participante] = []\n        self.medallas: list[Medalla] = []\n\n    def add_participante(self, Participante: Participante):\n        self.participantes.append(Participante)\n\n    def get_participantes(self) -> list[Participante]:\n        return self.participantes[:]\n\n    def hay_participantes(self) -> bool:\n        return len(self.participantes) > 0\n\n    def add_medalla(self, medalla: Medalla):\n        if medalla not in self.medallas:\n            self.medallas.append(medalla)\n        else:\n            print(f\"La medalla {medalla.get_tipo()} ya está asignada\")\n\n    def get_medallas(self) -> list[Medalla]:\n        return self.medallas[:]\n\n\nclass Resultados:\n    \"\"\"\n    Clase que representa la lista de resultados de los eventos\n    \"\"\"\n\n    def __init__(self):\n        self.resultados = []\n\n    def add_resultado(self, resultado):\n        self.resultados.append(resultado)\n\n    def get_resultados(self):\n        return self.resultados\n\n\nclass Medallero:\n    \"\"\"\n    Clase que representa al medallero de los juegos olímpicos\n    diccionario {país: {oro: numero, plata: numero, bronce: numero}}\n    \"\"\"\n\n    def __init__(self):\n        self.countries = {}\n\n    def add_medalla(self, pais: str, tipo_medalla: str):\n        if pais not in self.countries:\n            self.countries[pais] = {\"oro\": 0, \"plata\": 0, \"bronce\": 0}\n        self.countries[pais][tipo_medalla] += 1\n\n    def get_ranking(self):\n        return sorted(\n            self.countries.items(),\n            key=lambda x: x[1][\"oro\"] + x[1][\"plata\"] + x[1][\"bronce\"],\n            reverse=True,\n        )\n\n\n# =======================================================\n# funciones principales\n\n\ndef mostrar_menu() -> None:\n    print(\"\\n\" + \"=\" * 50)\n    print(\"SIMULADOR DE JUEGOS OLÍMPICOS - PARÍS 2024\")\n    print(\"=\" * 50)\n    print(\"1. Registro de eventos\")\n    print(\"2. Registro de participantes\")\n    print(\"3. Simulación de eventos\")\n    print(\"4. Creación de informes\")\n    print(\"5. Salir del programa\")\n    print(\"=\" * 50)\n\n\ndef registrar_evento(eventos: Eventos) -> None:\n    nombre_evento = input(\"Ingrese el nombre del evento: \").strip().lower()\n    if not nombre_evento:\n        print(\"El nombre del evento no puede estar vacío\")\n        return\n    eventos_actuales = eventos.get_events()\n    if eventos_actuales and nombre_evento in [\n        event.get_nombre() for event in eventos_actuales\n    ]:\n        print(f\"El evento {nombre_evento} ya está registrado\")\n        return\n    eventos.add_event(Event(nombre_evento))\n    print(f\"Evento {nombre_evento} registrado correctamente\")\n\n\ndef registrar_participante(participantes: Participantes, eventos: Eventos) -> None:\n    nombre_participante = input(\"Ingrese el nombre del participante: \").lower().strip()\n    pais_participante = input(\"Ingrese el país del participante: \").lower().strip()\n    deporte_participante = (\n        input(\"Ingrese el deporte del participante: \").lower().strip()\n    )\n    if not nombre_participante or not pais_participante or not deporte_participante:\n        print(\"Los datos del participante no pueden estar vacíos\")\n        return\n\n    eventos_actuales = eventos.get_events()\n    if not eventos_actuales:\n        print(\"No hay eventos registrados\")\n        return\n\n    if nombre_participante in [\n        participante.get_nombre() for participante in participantes.get_participantes()\n    ]:\n        print(f\"El participante {nombre_participante} ya está registrado\")\n        return\n\n    # mostrar los eventos disponibles\n    for i, evento in enumerate(eventos_actuales, 1):\n        print(f\"{i}. {evento.get_nombre()}\")\n\n    print(\"\\n Ingrese los numeros de eventos separados por comas, ej: 1,2,3,6\")\n    seleccion = input(\"Eventos: \").strip()\n\n    if not seleccion:\n        print(\"No se seleccionaron eventos\")\n        return\n\n    eventos_seleccionados = []\n\n    try:\n        indices = [int(x.strip()) for x in seleccion.split(\",\")]\n        for idx in indices:\n            if 1 <= idx <= len(eventos_actuales):\n                eventos_seleccionados.append(eventos_actuales[idx - 1])\n            else:\n                print(f\"El evento {idx} no es válido\")\n        if not eventos_seleccionados:\n            print(\"No se seleccionaron eventos válidos\")\n            return\n    except ValueError:\n        print(\"Los eventos seleccionados no son válidos\")\n        return\n\n    nuevo_participante = Participante(\n        nombre_participante, pais_participante, deporte_participante\n    )\n\n    for evento in eventos_seleccionados:\n        nuevo_participante.add_evento(evento)\n\n    participantes.add_participante(nuevo_participante)\n\n    print(f\"Participante {nombre_participante} registrado correctamente\")\n\n\ndef simular_eventos(\n    participantes: Participantes, eventos: Eventos, medallero: Medallero\n) -> None:\n    \"\"\"\n    Funcion que simula todos los eventos registrados\n    Parametros:\n    - participantes: Participantes - Lista de participantes registrados\n    - eventos: Eventos - Lista de eventos registrados\n    \"\"\"\n    lista_eventos = eventos.get_events()\n    if not lista_eventos:\n        print(\"No hay eventos registrados\")\n        return\n\n    if not participantes.hay_participantes():\n        print(\"No hay participantes registrados\")\n        return\n\n    eventos_simulados = 0\n\n    for evento in lista_eventos:\n        # filtrar participantes inscriptos en este evento\n        participantes_evento: list[Participante] = [\n            participante\n            for participante in participantes.get_participantes()\n            if evento in participante.get_eventos()\n        ]\n        if len(participantes_evento) < 3:\n            print(f\"El evento {evento.get_nombre()} necesita al menos 3 participantes\")\n            continue\n\n        # simular el evento(orden aleatorio de los participantes)\n        random.shuffle(participantes_evento)\n        oro, plata, bronce = participantes_evento[:3]\n\n        # asignar las medallas a los participantes\n        oro.add_medalla(Medalla(\"oro\"))\n        plata.add_medalla(Medalla(\"plata\"))\n        bronce.add_medalla(Medalla(\"bronce\"))\n\n        # actualizar medallero\n        medallero.add_medalla(pais=oro.pais, tipo_medalla=\"oro\")\n        medallero.add_medalla(pais=plata.pais, tipo_medalla=\"plata\")\n        medallero.add_medalla(pais=bronce.pais, tipo_medalla=\"bronce\")\n\n        # mostrar resultados\n        print(f\"Evento {evento.get_nombre()} simulado\")\n        print(f\"Oro: {oro.nombre} ({oro.pais})\")\n        print(f\"Plata: {plata.nombre} ({plata.pais})\")\n        print(f\"Bronce: {bronce.nombre} ({bronce.pais})\")\n\n        eventos_simulados += 1\n\n    if eventos_simulados > 0:\n        print(f\"Se simularon {eventos_simulados} eventos\")\n    else:\n        print(\"No se pudo simular ningun evento\")\n\n\ndef generar_informe(\n    participantes: Participantes, eventos: Eventos, medallero: Medallero\n) -> None:\n    lista_eventos = eventos.get_events()\n    if not lista_eventos:\n        print(\"No hay eventos registrados\")\n        return\n\n    print(\"\\n\" + \"=\" * 60)\n    print(\"INFORME FINAL - JUEGOS OLÍMPICOS PARÍS 2024\")\n    print(\"=\" * 60)\n\n    # Resumen general\n    print(\"\\nRESUMEN GENERAL:\")\n    print(f\"Eventos registrados: {len(lista_eventos)}\")\n    print(f\"Participantes registrados: {len(participantes.get_participantes())}\")\n\n    # Medallero\n    if medallero.countries:\n        print(\"\\nMEDALLERO POR PAÍSES:\")\n        print(f\"   {'País':<20} {'Oro':<10} {'Plata':<10} {'Bronce':<10} {'Total':<10}\")\n        print(\"   \" + \"-\" * 60)\n\n        ranking = sorted(\n            medallero.countries.items(),\n            key=lambda x: (x[1][\"oro\"], x[1][\"plata\"], x[1][\"bronce\"]),\n            reverse=True,\n        )\n\n        for pais, medallas in ranking:\n            total = medallas[\"oro\"] + medallas[\"plata\"] + medallas[\"bronce\"]\n            print(\n                f\"   {pais.capitalize():<20} {medallas['oro']:<10} {medallas['plata']:<10} {medallas['bronce']:<10} {total:<10}\"\n            )\n\n    print(\"\\n\" + \"=\" * 60)\n\n\ndef cargar_datos_prueba(eventos: Eventos, participantes: Participantes) -> None:\n    \"\"\"\n    Función que precarga datos de prueba para el simulador\n    - 3 eventos deportivos\n    - 10 participantes de diversos países\n    \"\"\"\n    print(\"\\nCargando datos de prueba...\")\n\n    # ========== EVENTOS ==========\n    evento1 = Event(\"100m lisos\")\n    evento2 = Event(\"natación 200m\")\n    evento3 = Event(\"salto en largo\")\n\n    eventos.add_event(evento1)\n    eventos.add_event(evento2)\n    eventos.add_event(evento3)\n\n    # ========== PARTICIPANTES ==========\n    # Participante 1\n    p1 = Participante(\"usain bolt\", \"jamaica\", \"atletismo\")\n    p1.add_evento(evento1)\n    participantes.add_participante(p1)\n\n    # Participante 2\n    p2 = Participante(\"tyson gay\", \"estados unidos\", \"atletismo\")\n    p2.add_evento(evento1)\n    participantes.add_participante(p2)\n\n    # Participante 3\n    p3 = Participante(\"yohan blake\", \"jamaica\", \"atletismo\")\n    p3.add_evento(evento1)\n    participantes.add_participante(p3)\n\n    # Participante 4\n    p4 = Participante(\"justin gatlin\", \"estados unidos\", \"atletismo\")\n    p4.add_evento(evento1)\n    participantes.add_participante(p4)\n\n    # Participante 5\n    p5 = Participante(\"michael phelps\", \"estados unidos\", \"natación\")\n    p5.add_evento(evento2)\n    participantes.add_participante(p5)\n\n    # Participante 6\n    p6 = Participante(\"ryan lochte\", \"estados unidos\", \"natación\")\n    p6.add_evento(evento2)\n    participantes.add_participante(p6)\n\n    # Participante 7\n    p7 = Participante(\"sun yang\", \"china\", \"natación\")\n    p7.add_evento(evento2)\n    participantes.add_participante(p7)\n\n    # Participante 8\n    p8 = Participante(\"chad le clos\", \"sudáfrica\", \"natación\")\n    p8.add_evento(evento2)\n    participantes.add_participante(p8)\n\n    # Participante 9\n    p9 = Participante(\"carl lewis\", \"estados unidos\", \"atletismo\")\n    p9.add_evento(evento1)  # También participa en 100m\n    p9.add_evento(evento3)  # Salto en largo\n    participantes.add_participante(p9)\n\n    # Participante 10\n    p10 = Participante(\"mike powell\", \"estados unidos\", \"atletismo\")\n    p10.add_evento(evento3)\n    participantes.add_participante(p10)\n\n    # Participantes adicionales para salto en largo (para completar mínimo 3)\n    p11 = Participante(\"bob beamon\", \"estados unidos\", \"atletismo\")\n    p11.add_evento(evento3)\n    participantes.add_participante(p11)\n\n    p12 = Participante(\"ivan pedroso\", \"cuba\", \"atletismo\")\n    p12.add_evento(evento3)\n    participantes.add_participante(p12)\n\n    print(\"Datos de prueba cargados correctamente\")\n    print(f\" Eventos: {len(eventos)}\")\n    print(f\" Participantes: {len(participantes.get_participantes())}\")\n    print(\"\\n Ahora puedes ir directamente a la opción 3 para simular eventos\")\n\n\ndef main() -> None:\n    \"\"\"Función principal que ejecuta el simulador.\"\"\"\n    print(\"¡Bienvenido al Simulador de Juegos Olímpicos!\")\n\n    # Inicializar estructuras de datos\n    eventos = Eventos()\n    participantes = Participantes()\n    medallero = Medallero()\n\n    # cargar datos de prueba\n    print(\"\\n¿Desea cargar datos de prueba?\")\n    print(\"1. Sí - Cargar datos precargados (3 eventos, 12 participantes)\")\n    print(\"2. No - Comenzar con datos vacíos\")\n\n    opcion_inicial = input(\"\\nSeleccione una opción (1 o 2): \").strip()\n\n    if opcion_inicial == \"1\":\n        cargar_datos_prueba(eventos, participantes)\n    else:\n        print(\n            \"\\nIniciando con datos vacíos. Use el menú para registrar eventos y participantes.\"\n        )\n\n    while True:\n        mostrar_menu()\n        opcion = input(\"\\nSeleccione una opción (1-5): \").strip()\n\n        if opcion == \"1\":\n            registrar_evento(eventos)\n        elif opcion == \"2\":\n            registrar_participante(participantes, eventos)\n        elif opcion == \"3\":\n            simular_eventos(participantes, eventos, medallero)\n        elif opcion == \"4\":\n            generar_informe(participantes, eventos, medallero)\n        elif opcion == \"5\":\n            print(\"\\n¡Gracias por usar el simulador! Hasta pronto.\")\n            break\n        else:\n            print(\"Opción inválida. Por favor, seleccione una opción del 1 al 5.\")\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/python/d1d4cum.py",
    "content": "import random\nfrom enum import Enum\n\nevents = []\n\n\nclass Country(Enum):\n    SPAIN = \"SP\"\n    FRANCE = \"FR\"\n    GERMANY = \"GER\"\n    ENGLAND = \"EN\"\n    ITALY = \"IT\"\n\n\nclass Participant:\n    name: str\n    country: Country\n\n    def __init__(self, name, country):\n        self.name = name\n        self.country = country\n\n\nclass Event:\n    name: str\n    participants: list\n    gold: Participant\n    silver: Participant\n    bronze: Participant\n\n    def __init__(self, name):\n        self.name = name\n        self.participants = []\n        self.gold = None\n        self.silver = None\n        self.bronze = None\n\n    def simulate(self):\n        random.shuffle(self.participants)\n        if len(self.participants) >= 3:\n            self.gold = self.participants[0]\n            self.silver = self.participants[1]\n            self.bronze = self.participants[2]\n        else:\n            print(\"El número de participantes no es suficiente\")\n\n\ndef print_winners(event: Event):\n    print(f\"\\n| {event.name} |\")\n    try:\n        print(f\"*** Gold: {event.gold.name} - {event.gold.country}\")\n        print(f\"** Silver: {event.silver.name} - {event.silver.country}\")\n        print(f\"* Bronze: {event.bronze.name} - {event.bronze.country}\")\n    except Exception as e:\n        print(e)\n        print(\"No hay resultados\")\n\n\ndef country_ranking():\n    countries = {}\n\n    for country in Country:\n        countries[country.name] = 0\n\n    for event in events:\n        try:\n            for medal in [event.gold, event.silver, event.bronze]:\n                if medal:\n                    match medal.country:\n                        case 'IT':\n                            countries['ITALY'] += 1\n                        case 'SP':\n                            countries['SPAIN'] += 1\n                        case 'FR':\n                            countries['FRANCE'] += 1\n                        case 'EN':\n                            countries['ENGLAND'] += 1\n                        case 'GER':\n                            countries['GERMANY'] += 1\n        except Exception as e:\n            print(\"⚠️ No se han realizado pruebas aún\\n\")\n\n    for country, points in countries.items():\n        print(f\"{country}: {points} points\")\n\n\ndef event_registration():\n    name = input(\"\\nNombre del evento: \")\n    new_event = Event(name=name)\n    events.append(new_event)\n\n\ndef paticipant_registration():\n    name = input(\"\\nNombre del participante: \")\n    country = input(\"País del participante (SP, FR, GER, EN, IT): \")\n    print(\"Prueba en la que participa: \")\n\n    for event in events:\n        print(f\"- {event.name}\")\n\n    selected_event = input(\"> \")\n\n    new_participant = Participant(name, country)\n\n    if country == \"SP\" or country == \"FR\" or country == \"GER\" or country == \"EN\" or country == \"IT\":\n\n        found = False\n\n        for event in events:\n            if event.name == selected_event:\n                event.participants.append(new_participant)\n                found = True\n                break\n\n        if not found:\n            print(\"Prueba no encontrada\")\n        else:\n            print(\"Participante añadido correctamente\")\n    else:\n        print(\"País erróneo\")\n\n\ndef make_report():\n    print(\"\\n---------------\")\n    print(\"|   Winners   |\")\n    print(\"---------------\")\n\n    for event in events:\n        print_winners(event)\n\n    print(\"\\n---------------------\")\n    print(\"|   Country ranking   |\")\n    print(\" ---------------------\")\n\n    country_ranking()\n\n\ndef main():\n    quit = False\n\n    while not quit:\n        print(\"\\nSelecciona una opción:\")\n        print(\"1. Registro de eventos\\n\"\n              \"2. Registro de participantes\\n\"\n              \"3. Simulación de eventos\\n\"\n              \"4. Creación de informes\\n\"\n              \"5. Salir del programa\")\n\n        option = input(\"> \")\n\n        match option:\n            case \"1\":\n                event_registration()\n            case \"2\":\n                paticipant_registration()\n            case \"3\":\n                for event in events:\n                    event.simulate()\n                print(\"Simulación completada\")\n            case \"4\":\n                make_report()\n            case \"5\":\n                quit = True\n            case _:\n                print(\"Opción no válida\")\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/python/davidrguez98.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * ¡Los JJOO de París 2024 han comenzado!\n * Crea un programa que simule la celebración de los juegos.\n * El programa debe permitir al usuario registrar eventos y participantes,\n * realizar la simulación de los eventos asignando posiciones de manera aleatoria\n * y generar un informe final. Todo ello por terminal.\n * Requisitos:\n * 1. Registrar eventos deportivos.\n * 2. Registrar participantes por nombre y país.\n * 3. Simular eventos de manera aleatoria en base a los participantes (mínimo 3).\n * 4. Asignar medallas (oro, plata y bronce) basándose en el resultado del evento.\n * 5. Mostrar los ganadores por cada evento.\n * 6. Mostrar el ranking de países según el número de medallas.\n * Acciones:\n * 1. Registro de eventos.\n * 2. Registro de participantes.\n * 3. Simulación de eventos.\n * 4. Creación de informes.\n * 5. Salir del programa.\n */ \"\"\"\n\n#EJERCICIO\n\nimport random\n\n\nclass Participant:\n\n    def __init__(self, name, country):\n        self.name = name\n        self.country = country\n\n    def __eq__(self, other):\n        if isinstance(other, Participant):\n            return self.name == other.name and self.country == other.country\n        return False\n    \n    def __hash__(self):\n        return hash(self.name, self.country)\n\nclass Olympics:\n\n    def __init__(self):\n        self.events = []\n        self.participants = {}\n        self.results = {}\n        self.country_results = {}\n\n    def register_event(self):\n        \n        event = input(\"Introduce el nombre del evento deportivo: \").strip()\n\n        if event in self.events:\n            print(f\"El evento {event} ya está registrado.\")\n        else:\n            self.events.append(event)\n            print(f\"El evento {event} registrado correctamente.\")\n\n    def register_participants(self):\n\n        if not self.events:\n            print(\"No hay eventos registrados. Por favor, registra uno primero.\")\n            return\n\n        name = input(\"Introduce el nombre del participante: \").strip()\n        country = input(\"Introduce el país del participante: \").strip()\n        participant = Participant(name, country)\n\n        print(\"Eventos deportivos disponibles:\")\n        for index, event in enumerate(self.events):\n            print(f\"{index + 1}. {event}\")\n\n        event_choice = int(input(\"Selecciona el número del evento para asignar al participante: \")) - 1\n\n        if event_choice >= 0 and event_choice < len(self.events):\n            event = self.events[event_choice]\n\n            if event in self.participants and participant in self.participants[event]:\n                print(f\"El participante {name} del país {country} ya está registrado en el evento deportivo {event}\")\n            else:\n\n                if event not in self.participants:\n                    self.participants[event] = []\n\n                self.participants[event].append(participant)\n                print(f\"El participante {name} del país {country} se ha registrado en el evento deportivo {event}\")\n        else:\n            print(\"Selección de evento deportivo inválido. El participante no se ha registrado.\")\n\n    def simulate_event(self):\n\n        if not self.events:\n            print(\"No hay eventos registrados. Por favor, registra uno primero.\")\n            return\n        \n        for event in self.events:\n\n            if len(self.participants[event]) < 3:\n                print(f\"No hay participantes suficientes para simular el evento {event} (mínimo 3).\")\n                continue\n\n            event_participants = random.sample(self.participants[event], 3)\n            random.shuffle(event_participants)\n\n            gold, silver, bronze = event_participants\n            self.results[event] = [gold, silver, bronze]\n\n            self.update_country_results(gold.country, \"gold\")\n            self.update_country_results(silver.country, \"silver\")\n            self.update_country_results(bronze.country, \"bronze\")\n\n            print(f\"Resultados simulación del evento: {event}\")\n            print(f\"Oro: {gold.name} ({gold.country})\")\n            print(f\"Plata: {silver.name} ({silver.country})\")\n            print(f\"Bronce: {bronze.name} ({bronze.country})\")\n\n    def update_country_results(self, country, medal):\n\n        if country not in self.country_results:\n            self.country_results[country] = {\"gold\": 0, \"silver\": 0, \"bronze\": 0}\n        self.country_results[country][medal] += 1\n\n    def show_report(self):\n\n        print(\"Informe Juegos Olímpicos:\")\n\n        if self.results:\n\n            print(\"Informe por evento:\")\n\n            for event, winners in self.results.items():\n                print(f\"Evento: {event}\")\n                print(f\"Oro: {winners[0].name} ({winners[0].country})\")\n                print(f\"Plata: {winners[1].name} ({winners[1].country})\")\n                print(f\"Bronce: {winners[2].name} ({winners[2].country})\")\n        else:\n            print(\"No hay resultados registrados.\")\n        \n        if self.country_results:\n\n            print(\"Informe por país:\")\n\n            for country, medals, in sorted(self.country_results.items(), key=lambda x: (\n                x[1][\"gold\"], x[1][\"silver\"], x[1][\"bronze\"]), reverse=True):\n\n                print(f\"{country}: Oro {medals[\"gold\"]}, Plata {medals[\"silver\"]}, Bronce {medals[\"bronze\"]}\")\n        else:\n            print(\"No hay medallas por país registradas.\")\n\nolympics = Olympics()\n\nprint(\"Simulador de Juegos Olímpicos\")\n\nwhile True:\n\n    print()\n\n    print(\"1. Registro de eventos.\")\n    print(\"2. Registro de participantes.\")\n    print(\"3. Simulación de eventos.\")\n    print(\"4. Creación de informes.\")\n    print(\"5. Salir del programa.\")\n\n    option = input(\"Selecciona una acción: \")\n\n    match option:\n\n        case \"1\":\n            olympics.register_event()\n        case \"2\":\n            olympics.register_participants()\n        case \"3\":\n            olympics.simulate_event()\n        case \"4\":\n            olympics.show_report()\n        case \"5\":\n            print(\"Saliendo del simulador.\")\n            break\n        case _:\n            print(\"Opción inválida.\")"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/python/duendeintemporal.py",
    "content": "#31 { Retos para Programadores } SIMULADOR JUEGOS OLÍMPICOS\n\n# Bibliography reference:\n# I use GPT as a reference and sometimes to correct or generate proper comments.\n\n\"\"\"  \n  * EJERCICIO:\n * ¡Los JJOO de París 2024 han comenzado!\n * Crea un programa que simule la celebración de los juegos.\n * El programa debe permitir al usuario registrar eventos y participantes,\n * realizar la simulación de los eventos asignando posiciones de manera aleatoria\n * y generar un informe final. Todo ello por terminal.\n * Requisitos:\n * 1. Registrar eventos deportivos.\n * 2. Registrar participantes por nombre y país.\n * 3. Simular eventos de manera aleatoria en base a los participantes (mínimo 3).\n * 4. Asignar medallas (oro, plata y bronce) basándose en el resultado del evento.\n * 5. Mostrar los ganadores por cada evento.\n * 6. Mostrar el ranking de países según el número de medallas.\n * Acciones:\n * 1. Registro de eventos.\n * 2. Registro de participantes.\n * 3. Simulación de eventos.\n * 4. Creación de informes.\n * 5. Salir del programa.\n\n\"\"\"\n\nimport random\nimport logging\n\n# Set up logging\nlogging.basicConfig(level=logging.INFO)\nlog = logging.info\n\ndef shuffle_array(array):\n    for i in range(len(array) - 1, 0, -1):\n        j = random.randint(0, i)\n        array[i], array[j] = array[j], array[i]\n    return array\n\nclass Events:\n    def __init__(self):\n        self.events = {}\n        self.prizes = Prizes()\n\n    def add_event(self, event):\n        if event in self.events:\n            log(f\"There's a {event} event already registered.\")\n        else:\n            self.events[event] = []\n            log(f\"Event {event} registered.\")\n\n    def add_player(self, player):\n        if player.event not in self.events:\n            log(f\"Event {player.event} is not registered.\")\n            return\n\n        is_player = next((p for p in self.events[player.event] if p.name == player.name), None)\n        if not is_player:\n            self.events[player.event].append(player)\n            log(f\"Player {player.name} added to {player.event} event.\")\n        else:\n            log(f\"The player {player.name} is already registered to {player.event} event.\")\n\n    def random_events(self):\n        events_list = list(self.events.keys())\n        return shuffle_array(events_list)\n\n    def show_participants_for_event(self, event):\n        if event in self.events:\n            log(f\"Participants for {event} event:\")\n            for p in self.events[event]:\n                log(f\"{p.name} from {p.country}\")\n        else:\n            log(f\"There's no participant registered for the {event} event.\")\n\n    def show_registry_data(self):\n        for key in self.events:\n            log(f\"{key} event:\")\n            for element in self.events[key]:\n                log(f\"{element.name} from {element.country}\")\n\nclass Player:\n    def __init__(self, name, event, country):\n        self.name = name\n        self.country = country\n        self.event = event\n\nclass Prizes:\n    def __init__(self):\n        self.gold = {}\n        self.silver = {}\n        self.bronze = {}\n        self.country_medals = {}\n\n    def add_gold(self, player):\n        self.add_prize(player, 'gold')\n\n    def add_silver(self, player):\n        self.add_prize(player, 'silver')\n\n    def add_bronze(self, player):\n        self.add_prize(player, 'bronze')\n\n    def add_prize(self, player, prize_type):\n        if player.event not in self.__getattribute__(prize_type):\n            self.__getattribute__(prize_type)[player.event] = []\n        if not any(p.name == player.name for p in self.__getattribute__(prize_type)[player.event]):\n            self.__getattribute__(prize_type)[player.event].append(player)\n            self.count_country_medal(player.country, prize_type)\n\n    def count_country_medal(self, country, prize_type):\n        if country not in self.country_medals:\n            self.country_medals[country] = {'gold': 0, 'silver': 0, 'bronze': 0}\n        self.country_medals[country][prize_type] += 1\n\n    def show_winners(self):\n        log('Winners:')\n        for event in self.gold:\n            log(f\"{event}: Gold - {', '.join(p.name for p in self.gold[event])}\")\n            log(f\"       Silver - {', '.join(p.name for p in self.silver.get(event, [])) if event in self.silver else 'None'}\")\n            log(f\"       Bronze - {', '.join(p.name for p in self.bronze.get(event, [])) if event in self.bronze else 'None'}\")\n\n    def show_country_medals(self):\n        log('Country Medal Count:')\n        for country in self.country_medals:\n            log(f\"{country}: Gold - {self.country_medals[country]['gold']}, Silver - {self.country_medals[country]['silver']}, Bronze - {self.country_medals[country]['bronze']}\")\n\ndef event_simulator(events):\n    for key in events.events:\n        if len(events.events[key]) >= 3:\n            winners = shuffle_array(events.events[key])\n            events.prizes.add_gold(winners[0])\n            events.prizes.add_silver(winners[1])\n            events.prizes.add_bronze(winners[2])\n        else:\n            log(f\"Not enough participants for {key} event.\")\n    events.prizes.show_winners()\n\ndummy_data = [\n    ['Bob Marley', 'Archery', 'Jamaica'],\n    ['Lenny Kravitz', 'Swimming', 'USA'],\n    ['John Lennon', 'Weightlifting', 'England'],\n    ['Lorenna McKennit', '100m Sprint', 'Somewhere in Europe'],\n    ['Alice', '200m Freestyle', 'The Rabbit Hole'],\n    ['Che Guevara', '3000m Steeplechase', 'Argentina'],\n    ['Buda', 'Discus Throw', 'India'],\n    ['Bugs Bunny', 'Archery', 'Disney'],\n    ['Asterix', 'Swimming', 'Comics'],\n    ['Lucky Luke', 'Weightlifting', 'Comics'],\n    ['Jerry Maguire', '100m Sprint', 'Comics'],\n    ['Atreyo', '200m Freestyle', 'Book'],\n    ['Simón Bolívar', '3000m Steeplechase', 'Venezuela'],\n    ['Goku', 'Discus Throw', 'Anime'],\n    ['Shihiro', 'Archery', 'Anime'],\n    ['Ruby', 'Swimming', 'Book'],\n    ['Crows', 'Weightlifting', 'Book'],\n    ['Devian', '100m Sprint', 'Book'],\n    ['Peque', '200m Freestyle', 'My World'],\n    ['Sophy', '3000m Steeplechase', 'My World'],\n    ['Beth', 'Discus Throw', 'My World']\n]\n\nfirst_round = Events()\n\nolympic_events = ['Archery', 'Swimming', 'Weightlifting', '100m Sprint', '200m Freestyle', '3000m Steeplechase', 'Discus Throw']\nfor event in olympic_events:\n    first_round.add_event(event)\n\nfor d in dummy_data:\n    first_round.add_player(Player(d[0], d[1], d[2]))\n\nfirst_round.show_registry_data()\n\nevent_simulator(first_round)\n\n# Output:\n\"\"\"    \nINFO:root:Event Archery registered.\nINFO:root:Event Swimming registered.\nINFO:root:Event Weightlifting registered.\nINFO:root:Event 100m Sprint registered.\nINFO:root:Event 200m Freestyle registered.\nINFO:root:Event 3000m Steeplechase registered.\nINFO:root:Event Discus Throw registered.\nINFO:root:Player Bob Marley added to Archery event.\nINFO:root:Player Lenny Kravitz added to Swimming event.\nINFO:root:Player John Lennon added to Weightlifting event.\nINFO:root:Player Lorenna McKennit added to 100m Sprint event.\nINFO:root:Player Alice added to 200m Freestyle event.\nINFO:root:Player Che Guevara added to 3000m Steeplechase event.\nINFO:root:Player Buda added to Discus Throw event.\nINFO:root:Player Bugs Bunny added to Archery event.\nINFO:root:Player Asterix added to Swimming event.\nINFO:root:Player Lucky Luke added to Weightlifting event.\nINFO:root:Player Jerry Maguire added to 100m Sprint event.\nINFO:root:Player Atreyo added to 200m Freestyle event.\nINFO:root:Player Simón Bolívar added to 3000m Steeplechase event.\nINFO:root:Player Goku added to Discus Throw event.\nINFO:root:Player Shihiro added to Archery event.\nINFO:root:Player Ruby added to Swimming event.\nINFO:root:Player Crows added to Weightlifting event.\nINFO:root:Player Devian added to 100m Sprint event.\nINFO:root:Player Peque added to 200m Freestyle event.\nINFO:root:Player Sophy added to 3000m Steeplechase event.\nINFO:root:Player Beth added to Discus Throw event.\nINFO:root:Archery event:\nINFO:root:Bob Marley from Jamaica\nINFO:root:Bugs Bunny from Disney\nINFO:root:Shihiro from Anime\nINFO:root:Swimming event:\nINFO:root:Lenny Kravitz from USA\nINFO:root:Asterix from Comics\nINFO:root:Ruby from Book\nINFO:root:Weightlifting event:\nINFO:root:John Lennon from England\nINFO:root:Lucky Luke from Comics\nINFO:root:Crows from Book\nINFO:root:100m Sprint event:\nINFO:root:Lorenna McKennit from Somewhere in Europe\nINFO:root:Jerry Maguire from Comics\nINFO:root:Devian from Book\nINFO:root:200m Freestyle event:\nINFO:root:Alice from The Rabbit Hole\nINFO:root:Atreyo from Book\nINFO:root:Peque from My World\nINFO:root:3000m Steeplechase event:\nINFO:root:Che Guevara from Argentina\nINFO:root:Simón Bolívar from Venezuela\nINFO:root:Sophy from My World\nINFO:root:Discus Throw event:\nINFO:root:Buda from India\nINFO:root:Goku from Anime\nINFO:root:Beth from My World\nINFO:root:Winners:\nINFO:root:Archery: Gold - Bob Marley\nINFO:root:       Silver - Shihiro\nINFO:root:       Bronze - Bugs Bunny\nINFO:root:Swimming: Gold - Lenny Kravitz\nINFO:root:       Silver - Ruby\nINFO:root:       Bronze - Asterix\nINFO:root:Weightlifting: Gold - Crows\nINFO:root:       Silver - John Lennon\nINFO:root:       Bronze - Lucky Luke\nINFO:root:100m Sprint: Gold - Devian\nINFO:root:       Silver - Jerry Maguire\nINFO:root:       Bronze - Lorenna McKennit\nINFO:root:200m Freestyle: Gold - Atreyo\nINFO:root:       Silver - Peque\nINFO:root:       Bronze - Alice\nINFO:root:3000m Steeplechase: Gold - Sophy\nINFO:root:       Silver - Che Guevara\nINFO:root:       Bronze - Simón Bolívar\nINFO:root:Discus Throw: Gold - Buda\nINFO:root:       Silver - Goku\nINFO:root:       Bronze - Beth\n\n\"\"\""
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/python/fborjalv.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * ¡Los JJOO de París 2024 han comenzado!\n * Crea un programa que simule la celebración de los juegos.\n * El programa debe permitir al usuario registrar eventos y participantes,\n * realizar la simulación de los eventos asignando posiciones de manera aleatoria\n * y generar un informe final. Todo ello por terminal.\n * Requisitos:\n * 1. Registrar eventos deportivos. ✅\n * 2. Registrar participantes por nombre y país. ✅\n * 3. Simular eventos de manera aleatoria en base a los participantes (mínimo 3). ✅\n * 4. Asignar medallas (oro, plata y bronce) basándose en el resultado del evento.\n * 5. Mostrar los ganadores por cada evento.\n * 6. Mostrar el ranking de países según el número de medallas.\n * Acciones:\n * 1. Registro de eventos.\n * 2. Registro de participantes.\n * 3. Simulación de eventos.\n * 4. Creación de informes.\n * 5. Salir del programa.\n */\n\n\"\"\"\n\n\"\"\"\n-- registrar eventos deportivos\n-- registrar participante por nombre y pais \n-- simular eventos\n-- asignar medallas \n\n\"\"\"\n\nfrom abc import ABC, abstractmethod\n\n\n\nimport random\n\n\nclass OlympicsGames():\n\n    def __init__(self) -> None:\n        self.participant_registry = ParticipantRegistry()\n        self.event_registry = EventRegistry()\n        self.my_report = Report()\n\n    def show_menu(self):\n        while True:\n            print(\"-- Menú principal --\")\n            print(\"1. Registro de eventos\")\n            print(\"2. Registro de participantes.\")\n            print(\"3. Simulación de eventos.\")\n            print(\"4. Creación de informes.\")\n            print(\"5. Salir del programa.\")\n            option = input(\"Introduce una opción: \")\n\n            match option:\n                case \"1\":\n                    print(\"Registro de eventos\")\n                    name = input(\"Introduce el nombre del evento: \")\n                    event = Event(name)\n                    self.event_registry.add_event(event)\n\n                case \"2\":\n                    print(\"Registro de participantes\")\n                    name = input(\"Introduce el nombre del deporista: \")\n                    country = input(\"Introduce el país al que representa: \")\n                    deportist = Participant(name, country)\n                    self.participant_registry.add_participant(deportist)\n\n                case \"3\":\n                    print(\"Simulación de eventos\")\n                    self.participant_registry.show_participant()\n                    self.event_registry.show_events()\n                    event.simulation(self.participant_registry.list_participant)\n                    print(event.result)\n                    event.award_medals(self.participant_registry.list_participant)\n                    self.participant_registry.show_participant()\n                case \"4\":\n                    print(\"Creación de informes\")\n                    self.my_report.show_winners_by_event(self.event_registry)\n                    self.my_report.show_ranking_by_country(self.participant_registry)\n                case \"5\":\n                    print(\"Saliendo del programa\")\n                    break\n\nclass Participant():\n    \n    def __init__(self, name, country) -> None:\n        self.name = name\n        self.country = country\n        self.medals = {\"GOLD\": 0, \"SILVER\": 0, \"BRONZE\": 0}\n\nclass ParticipantRegistry(OlympicsGames):\n    def __init__(self) -> None:\n        self.list_participant = []\n    def add_participant(self, Participant):\n        self.list_participant.append(Participant)\n    def show_participant(self):\n        for participant in self.list_participant:\n            print(f\"Nombre: {participant.name},  Pais: {participant.country}, Medallas: {participant.medals}\")\n\nclass Event():\n\n    result = {}\n    def __init__(self, sport_name) -> None:\n        self.sport_name = sport_name\n\n    def simulation(self, participant_list: list):\n        if len(participant_list) < 3:\n            print(\"El Evento no se puede realizar por falta de participantes\")\n        else: \n            self.result[\"sport\"] = self.sport_name\n            winners = random.sample(participant_list, k=3)\n            self.result[\"winners\"] = {\"GOLD\": winners[0].name, \"SILVER\": winners[1].name, \"BRONZE\":winners[2].name}\n\n    def award_medals(self, participant_list):\n        for medal, name in self.result[\"winners\"].items():\n            for participant in participant_list:\n                if participant.name == name:\n                    participant.medals[medal] += 1\n                    break\n\nclass EventRegistry(OlympicsGames):\n\n    def __init__(self) -> None:\n        self.event_list = []\n    def add_event(self, event):\n        self.event_list.append(event)\n    def show_events(self):\n        for event in self.event_list:\n            print(f\"Nombre del evento: {event.sport_name}\")\n\n\nclass Report():\n\n    def __init__(self) -> None:\n        pass\n\n    def show_winners_by_event(self, event_registry):\n        for event in event_registry.event_list:\n            print(f\"Deporte: {event.result['sport']}\")\n            print(\"; \".join([str(f\"{medal, winner}\") for medal, winner in event.result['winners'].items()]))\n\n    def show_ranking_by_country(self, participant_registry):\n        country_medals = {}\n        for participant in participant_registry.list_participant:\n            if participant.country not in country_medals:\n                country_medals[participant.country] = 0\n            country_medals[participant.country] += sum(participant.medals.values())\n        print(country_medals)\n\nsistem = OlympicsGames()\nsistem.show_menu()"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/python/franxiscodev.py",
    "content": "import random\n\n\nclass Participant:\n    def __init__(self, name, country):\n        self.name = name\n        self.country = country\n\n    def __eq__(self, other: object) -> bool:\n        if not isinstance(other, Participant):\n            return False\n        return self.name == other.name and self.country == other.country\n\n    def __hash__(self) -> int:\n        return hash(self.name, self.country)\n\n\nclass Olympics:\n    def __init__(self):\n        self.events = []\n        self.participants = {}\n        self.event_results = {}\n        self.country_results = {}\n\n    def register_event(self):\n        event = input(\n            \"Introducir nombre del evento deportivo: \").strip().lower()\n        if event not in self.events:\n            self.events.append(event)\n            self.participants[event] = []  # crear la clave del evento vacía\n            # Inicializar la lista de participantes\n            # self.participants[event] = []\n            print(f\"✅ El evento --{event}-- registrado OK\")\n        else:\n            print(f\"❌ El evento --{event}-- ya existe\")\n\n    def register_participant(self):\n        if not self.events:\n            print(\"❌No hay eventos registrados. Por favor, registra uno\")\n            return\n\n        name = input(\"Introducir nombre participante: \").strip().capitalize()\n        country = input(\n            \"Introducir país del participante: \").strip().capitalize()\n        participant = Participant(name, country)\n\n        print(\"🔹Eventos disponibles para registrar el participante: \")\n        for index, event in enumerate(self.events):\n            print(f\"{index + 1}.-  {event}\")\n        event_choice = int(\n            input(f\"Selecciona el nro del evento para {name}: \")) - 1\n        if event_choice >= 0 and event_choice < len(self.events):\n            event = self.events[event_choice]\n            '''if event not in self.participants:\n                self.participants[event] = []'''\n            if participant in self.participants[event]:\n                print(\n                    f\"❌El participante {name} de {country} ya está registrado en el evento deportivo {event}\")\n            else:\n                self.participants[event].append(participant)\n                print(\n                    f\"✅El participante {name} de {country} se ha registrado en el evento deportivo {event}\")\n        else:\n            print(f\"❌ Evento deportivo inválido\")\n\n    def simulate_events(self):\n        if not self.events:\n            print(\"❌ No hay eventos registrados.\")\n            return\n        for event in self.events:\n\n            count_participants = len(self.participants[event])\n            if count_participants < 3:\n                print(\n                    f\"💥 Solo hay {count_participants} para el evento {event}, debe haber al menos 3 \")\n                continue\n            # me quedo al azar con sólo 3 participantes para el oro plata cobre\n            event_winner_particpants = random.sample(\n                self.participants[event], 3)\n            # ordenarlo de manera aleatoria\n            random.shuffle(event_winner_particpants)\n            # asigno a cada medalla los participantes\n            gold, silver, bronze = event_winner_particpants\n            self.event_results[event] = [gold, silver, bronze]\n\n            # medallero por país\n            self.update_country_results(gold.country, \"gold\")\n            self.update_country_results(silver.country, \"silver\")\n            self.update_country_results(bronze.country, \"bronze\")\n\n            print(f\"🥇🥈🥉 Resultados Simulación del evento: {event}\")\n            print(f\"🥇 ORO: {gold.name} ({gold.country})\")\n            print(f\"🥈 PLATA: {silver.name} ({silver.country})\")\n            print(f\"🥉 BRONCE: {bronze.name} ({bronze.country})\")\n\n    def update_country_results(self, country, medal):\n        if country not in self.country_results:\n            self.country_results[country] = {\n                \"gold\": 0, \"silver\": 0, \"bronze\": 0}\n        self.country_results[country][medal] += 1\n\n    def show_report(self):\n        print(\"Informe JJOO\")\n        if self.event_results:\n\n            for event, winners in self.event_results.items():\n                print(f\"🏁 Evento: {event}\")\n                print(f\"🥇 ORO: {winners[0].name} ({winners[0].country})\")\n                print(f\"🥈 PLATA: {winners[1].name} ({winners[1].country})\")\n                print(f\"🥉 BRONCE: {winners[2].name} ({winners[2].country})\")\n        else:\n            print(\"Sin resultados de eventos\")\n\n        if self.country_results:\n            sorted_countries = sorted(self.country_results.items(), key=lambda x: (\n                x[1][\"gold\"], x[1][\"silver\"], x[1][\"bronze\"]), reverse=True)\n\n            for country, medals in sorted_countries:\n                print(\n                    f\"🏁 País: {country} - 🥇 ORO: {medals[\"gold\"]} - 🥈 PLATA: {medals[\"silver\"]} - 🥉 BRONCE: {medals[\"bronze\"]}\")\n        else:\n            print(\"Sin resultados por país\")\n\n\nolympics = Olympics()\n\nprint(\"Simulador de JJOO\")\n\nwhile True:\n    print()\n    print(\" * 1. Registro de eventos.\")\n    print(\" * 2. Registro de participantes.\")\n    print(\" * 3. Simulación de eventos.\")\n    print(\" * 4. Creación de informes.\")\n    print(\" * 5. Salir del programa.\")\n\n    option = input(\"Seleccione una opción: \")\n    match option:\n        case \"1\":\n            olympics.register_event()\n        case \"2\":\n            olympics.register_participant()\n        case \"3\":\n            olympics.simulate_events()\n        case \"4\":\n            olympics.show_report()\n        case \"5\":\n            print(\"Saliendo del programa.\")\n            break\n        case _:\n            print(\"Opción no válida. Intente nuevamente.\")\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/python/hectorio23.py",
    "content": "# Autor:  Héctor Adán\n# GitHub: https://github.com/hectorio23\n\nfrom collections import defaultdict\nimport random\n\n'''\n * EJERCICIO:\n * ¡Los JJOO de París 2024 han comenzado!\n * Crea un programa que simule la celebración de los juegos.\n * El programa debe permitir al usuario registrar eventos y participantes,\n * realizar la simulación de los eventos asignando posiciones de manera aleatoria\n * y generar un informe final. Todo ello por terminal.\n * Requisitos:\n * 1. Registrar eventos deportivos.\n * 2. Registrar participantes por nombre y país.\n * 3. Simular eventos de manera aleatoria en base a los participantes (mínimo 3).\n * 4. Asignar medallas (oro, plata y bronce) basándose en el resultado del evento.\n * 5. Mostrar los ganadores por cada evento.\n * 6. Mostrar el ranking de países según el número de medallas.\n * Acciones:\n * 1. Registro de eventos.\n * 2. Registro de participantes.\n * 3. Simulación de eventos.\n * 4. Creación de informes.\n * 5. Salir del programa.\n'''\n\nclass Participant:\n    def __init__(self, name, country):\n        self.name = name\n        self.country = country\n\nclass Event:\n    def __init__(self, name):\n        self.name = name\n        self.participants = []\n\nclass OlympicGames:\n    def __init__(self):\n        self.events = []\n        self.medal_tally = defaultdict(int)\n\n    def register_event(self):\n        event_name = input(\"Ingrese el nombre del evento: \")\n        self.events.append(Event(event_name))\n\n    def register_participant(self):\n        event_name = input(\"Ingrese el nombre del evento: \")\n        event = next((e for e in self.events if e.name == event_name), None)\n\n        if event:\n            participant_name = input(\"Ingrese el nombre del participante: \")\n            country = input(\"Ingrese el país del participante: \")\n            event.participants.append(Participant(participant_name, country))\n        else:\n            print(\"Evento no encontrado.\")\n\n    def simulate_event(self):\n        for event in self.events:\n            if len(event.participants) >= 3:\n                participants = event.participants[:]\n                random.shuffle(participants)\n\n                print(f\"Resultados del evento {event.name}:\")\n                print(f\"Oro: {participants[0].name} ({participants[0].country})\")\n                print(f\"Plata: {participants[1].name} ({participants[1].country})\")\n                print(f\"Bronce: {participants[2].name} ({participants[2].country})\")\n\n                self.medal_tally[participants[0].country] += 3\n                self.medal_tally[participants[1].country] += 2\n                self.medal_tally[participants[2].country] += 1\n            else:\n                print(f\"El evento {event.name} no tiene suficientes participantes.\")\n\n    def display_medal_tally(self):\n        print(\"\\nRanking de Medallas por País:\")\n        for country, points in sorted(self.medal_tally.items(), key=lambda x: x[1], reverse=True):\n            print(f\"{country}: {points} puntos\")\n\n    def run(self):\n        while True:\n            print(\"\\n1. Registro de eventos\\n2. Registro de participantes\\n3. Simulación de eventos\\n4. Creación de informes\\n5. Salir\")\n            option = int(input(\"Seleccione una opción: \"))\n\n            if option == 1:\n                self.register_event()\n            elif option == 2:\n                self.register_participant()\n            elif option == 3:\n                self.simulate_event()\n            elif option == 4:\n                self.display_medal_tally()\n            elif option == 5:\n                break\n            else:\n                print(\"Opción inválida.\")\n\nif __name__ == \"__main__\":\n    OlympicGames().run()\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/python/hozlucas28.py",
    "content": "# pylint: disable=missing-module-docstring,missing-class-docstring,missing-function-docstring,too-few-public-methods,broad-exception-raised\n\nfrom abc import ABCMeta, abstractmethod\nfrom datetime import datetime\nfrom typing import Literal, Self, LiteralString, TypedDict\nfrom random import sample\n\n# ---------------------------------------------------------------------------- #\n#                                SHARED_TYPES.PY                               #\n# ---------------------------------------------------------------------------- #\n\ntype TName = str\n\n\n# ---------------------------------------------------------------------------- #\n#                                   UTILS.PY                                   #\n# ---------------------------------------------------------------------------- #\n\nTCountryWithNumberOfMedals = TypedDict(\n    \"TCountryWithNumberOfMedals\", {\"name\": str, \"number_of_medals\": int}\n)\n\n\ndef countries_ranking_by_number_of_medals(\n    *sport_events: \"TSportEvent\",\n) -> list[TCountryWithNumberOfMedals]:\n    ranking_per_country: list[TCountryWithNumberOfMedals] = []\n\n    winners: list[TCompetitor] = []\n    for sport_event in sport_events:\n        for winner_ in sport_event.winners:\n            winners.append(winner_)\n\n    indexes_to_ignore: list[int] = []\n\n    for i, anchor_winner in enumerate(winners):\n        if i in indexes_to_ignore:\n            continue\n\n        country_stats: TCountryWithNumberOfMedals = {\n            \"name\": anchor_winner.country,\n            \"number_of_medals\": len(anchor_winner.medals),\n        }\n\n        for j in range(i + 1, len(winners)):\n            if j in indexes_to_ignore:\n                continue\n\n            next_winner = winners[j]\n\n            if anchor_winner.country.upper() == next_winner.country.upper():\n                country_stats[\"number_of_medals\"] += len(next_winner.medals)\n                indexes_to_ignore.append(j)\n\n        ranking_per_country.append(country_stats)\n\n    ranking_per_country.sort(\n        key=lambda stats: stats[\"name\"],\n        reverse=False,\n    )\n\n    ranking_per_country.sort(\n        key=lambda stats: stats[\"number_of_medals\"],\n        reverse=True,\n    )\n\n    return ranking_per_country\n\n\n# ---------------------------------------------------------------------------- #\n#                                   MEDAL.PY                                   #\n# ---------------------------------------------------------------------------- #\n\ntype TCategory = \"MedalCategory\"\ntype TDate = datetime\ntype TSportEvent = \"AbcSportEvent\"\n\nMedalCategory = Literal[\"silver\", \"gold\", \"bronze\"]\n\n\nclass AbcMedal(metaclass=ABCMeta):\n    @property\n    @abstractmethod\n    def category(self) -> TCategory:\n        pass\n\n    @property\n    @abstractmethod\n    def date(self) -> TDate:\n        pass\n\n    @property\n    @abstractmethod\n    def sport_event(self) -> TSportEvent:\n        pass\n\n\nclass Medal(AbcMedal):\n    __category: TCategory\n    __date: TDate\n    __sport_event: TSportEvent\n\n    def __init__(\n        self, *, category_: TCategory, date_: TDate, sport_event_: TSportEvent\n    ) -> None:\n        self.__category = category_\n        self.__date = date_\n        self.__sport_event = sport_event_\n\n    @property\n    def category(self) -> str:\n        return self.__category\n\n    @property\n    def date(self) -> TDate:\n        return self.__date\n\n    @property\n    def sport_event(self) -> TSportEvent:\n        return self.__sport_event\n\n\n# ---------------------------------------------------------------------------- #\n#                                 COMPETITOR.PY                                #\n# ---------------------------------------------------------------------------- #\n\n\nTCountry = (\n    Literal[\n        \"argentina\",\n        \"españa\",\n        \"estados unidos\",\n        \"méxico\",\n        \"canada\",\n        \"chile\",\n        \"brazil\",\n        \"germany\",\n        \"france\",\n        \"italy\",\n        \"australia\",\n        \"japan\",\n    ]\n    | LiteralString\n)\n\n\nclass AbcCompetitor(metaclass=ABCMeta):\n    @property\n    @abstractmethod\n    def country(self) -> TCountry:\n        pass\n\n    @property\n    @abstractmethod\n    def medals(self) -> list[\"AbcMedal\"]:\n        pass\n\n    @property\n    @abstractmethod\n    def name(self) -> TName:\n        pass\n\n    @abstractmethod\n    def add_medals(self, *new_medals: AbcMedal) -> Self:\n        pass\n\n\nclass Competitor(AbcCompetitor):\n    __country: TCountry\n    __medals: list[AbcMedal]\n    __name: TName\n\n    def __init__(\n        self, *, country_: TCountry, medals_: list[AbcMedal] | None = None, name_: TName\n    ) -> None:\n        if medals_ is None:\n            medals_ = []\n\n        self.__country = country_\n        self.__medals = medals_\n        self.__name = name_\n\n    @property\n    def country(self) -> TCountry:\n        return self.__country\n\n    @property\n    def medals(self) -> list[AbcMedal]:\n        return self.__medals\n\n    @property\n    def name(self) -> TName:\n        return self.__name\n\n    def add_medals(self, *new_medals: AbcMedal) -> Self:\n        current_medals: list[AbcMedal] = self.__medals\n        joined_medals: list[AbcMedal] = [*current_medals, *new_medals]\n        self.__medals = joined_medals\n        return self\n\n\n# ---------------------------------------------------------------------------- #\n#                                 SPORTEVENT.PY                                #\n# ---------------------------------------------------------------------------- #\n\ntype TCompetitor = AbcCompetitor\ntype TWinner = TCompetitor\n\n\nclass AbcSportEvent(metaclass=ABCMeta):\n    @property\n    @abstractmethod\n    def competitors(self) -> list[TCompetitor]:\n        pass\n\n    @property\n    @abstractmethod\n    def name(self) -> TName:\n        pass\n\n    @property\n    @abstractmethod\n    def winners(self) -> list[TCompetitor]:\n        pass\n\n    @abstractmethod\n    def add_competitors(self, *new_competitors: TCompetitor) -> Self:\n        pass\n\n    @abstractmethod\n    def start(self) -> Self:\n        pass\n\n\nclass SportEvent(AbcSportEvent):\n    __competitors: list[TCompetitor]\n    __name: str\n    __winners: list[TCompetitor]\n\n    def __init__(\n        self,\n        *,\n        competitors_: list[TCompetitor] | None = None,\n        name_: str,\n    ) -> None:\n        if competitors_ is None:\n            competitors_ = []\n\n        self.__competitors = competitors_\n        self.__name = name_\n\n    @property\n    def competitors(self) -> list[TCompetitor]:\n        return self.__competitors\n\n    @property\n    def name(self) -> str:\n        return self.__name\n\n    @property\n    def winners(self) -> list[TCompetitor]:\n        return self.__winners\n\n    @staticmethod\n    def minimum_number_of_competitors() -> int:\n        return 3\n\n    def __has_enough_competitors(self) -> bool:\n        return len(self.__competitors) >= SportEvent.minimum_number_of_competitors()\n\n    def add_competitors(self, *new_competitors: AbcCompetitor) -> Self:\n        current_competitors: list[TCompetitor] = self.__competitors\n        joined_competitors: list[TCompetitor] = [*current_competitors, *new_competitors]\n        self.__competitors = joined_competitors\n        return self\n\n    def start(self) -> Self:\n        if not self.__has_enough_competitors():\n            raise Exception(\n                f\"`Sport event '${self.__name}' needs more competitors. It currently has {len(self.__competitors)} competitor(s), but requires a minimum of {SportEvent.minimum_number_of_competitors()}.\"\n            )\n\n        [first_place_index, second_place_index, third_place_index] = sample(\n            population=range(0, len(self.__competitors)), k=3\n        )\n\n        first_place_medal: AbcMedal = Medal(\n            category_=\"gold\", date_=datetime.today(), sport_event_=self\n        )\n\n        second_place_medal: AbcMedal = Medal(\n            category_=\"silver\", date_=datetime.today(), sport_event_=self\n        )\n\n        third_place_medal: AbcMedal = Medal(\n            category_=\"bronze\", date_=datetime.today(), sport_event_=self\n        )\n\n        self.__competitors[first_place_index].add_medals(first_place_medal)\n        self.__competitors[second_place_index].add_medals(second_place_medal)\n        self.__competitors[third_place_index].add_medals(third_place_medal)\n\n        self.__winners = [\n            self.competitors[first_place_index],\n            self.competitors[second_place_index],\n            self.competitors[third_place_index],\n        ]\n        return self\n\n\nmedal = Medal(\n    category_=\"bronze\", date_=datetime.today(), sport_event_=SportEvent(name_=\"Juan\")\n)\n\n\n# ---------------------------------------------------------------------------- #\n#                                   EXERCISE                                   #\n# ---------------------------------------------------------------------------- #\n\nprint(\"> Paris 2024 olympic games...\")\n\nfirst_sport_event: TSportEvent = SportEvent(name_=\"football\")\nsecond_sport_event: TSportEvent = SportEvent(name_=\"handball\")\nthird_sport_event: TSportEvent = SportEvent(name_=\"table tennis\")\nfourth_sport_event: TSportEvent = SportEvent(name_=\"swimming\")\n\nprint(\"\\n> First sport event...\\n\")\nprint(first_sport_event.__dict__)\n\nprint(\"\\n> Second sport event...\\n\")\nprint(second_sport_event.__dict__)\n\nprint(\"\\n> Third sport event...\\n\")\nprint(third_sport_event.__dict__)\n\nprint(\"\\n> Fourth sport event...\\n\")\nprint(fourth_sport_event.__dict__)\n\n\ncompetitors_of_first_sport_event: list[TCompetitor] = [\n    Competitor(country_=\"argentina\", name_=\"lionel messi\"),\n    Competitor(country_=\"españa\", name_=\"sergio ramos\"),\n    Competitor(country_=\"estados unidos\", name_=\"megan rapinoe\"),\n    Competitor(country_=\"méxico\", name_=\"hirving lozano\"),\n    Competitor(country_=\"canada\", name_=\"christine sinclair\"),\n]\n\ncompetitors_of_second_sport_event: list[TCompetitor] = [\n    Competitor(country_=\"brazil\", name_=\"neymar\"),\n    Competitor(country_=\"germany\", name_=\"manuel neuer\"),\n    Competitor(country_=\"france\", name_=\"antoine griezmann\"),\n    Competitor(country_=\"italy\", name_=\"giorgio chiellini\"),\n    Competitor(country_=\"australia\", name_=\"sam kerr\"),\n]\n\ncompetitors_of_third_sport_event: list[TCompetitor] = [\n    Competitor(country_=\"japan\", name_=\"naomi osaka\"),\n    Competitor(country_=\"china\", name_=\"liu shiwen\"),\n    Competitor(country_=\"south korea\", name_=\"choi hyojoo\"),\n    Competitor(country_=\"singapore\", name_=\"feng tianwei\"),\n    Competitor(country_=\"germany\", name_=\"han ying\"),\n]\n\ncompetitors_of_fourth_sport_event: list[TCompetitor] = [\n    Competitor(country_=\"sweden\", name_=\"sarah sjöström\"),\n    Competitor(country_=\"united states\", name_=\"caleb dressel\"),\n    Competitor(country_=\"australia\", name_=\"emma mckeon\"),\n    Competitor(country_=\"canada\", name_=\"penny oleksiak\"),\n    Competitor(country_=\"netherlands\", name_=\"ranomi kromowidjojo\"),\n]\n\nprint(\"\\n> Competitors of first sport event...\\n\")\nfor competitor in competitors_of_first_sport_event:\n    print(competitor.__dict__)\n\nprint(\"\\n> Competitors of second sport event...\\n\")\nfor competitor in competitors_of_second_sport_event:\n    print(competitor.__dict__)\n\nprint(\"\\n> Competitors of third sport event...\\n\")\nfor competitor in competitors_of_third_sport_event:\n    print(competitor.__dict__)\n\nprint(\"\\n> Competitors of fourth sport event...\\n\")\nfor competitor in competitors_of_fourth_sport_event:\n    print(competitor.__dict__)\n\nfirst_sport_event.add_competitors(*competitors_of_first_sport_event).start()\nsecond_sport_event.add_competitors(*competitors_of_second_sport_event).start()\nthird_sport_event.add_competitors(*competitors_of_third_sport_event).start()\nfourth_sport_event.add_competitors(*competitors_of_fourth_sport_event).start()\n\nwinners_of_first_sport_event: list[AbcCompetitor] = first_sport_event.winners\nwinners_of_second_sport_event: list[AbcCompetitor] = second_sport_event.winners\nwinners_of_third_sport_event: list[AbcCompetitor] = third_sport_event.winners\nwinners_of_fourth_sport_event: list[AbcCompetitor] = fourth_sport_event.winners\n\nprint(\"\\n> Winners of first sport event...\\n\")\nfor winner in winners_of_first_sport_event:\n    print(winner.__dict__)\n\nprint(\"\\n> Winners of second sport event...\\n\")\nfor winner in winners_of_second_sport_event:\n    print(winner.__dict__)\n\nprint(\"\\n> Winners of third sport event...\\n\")\nfor winner in winners_of_third_sport_event:\n    print(winner.__dict__)\n\nprint(\"\\n> Winners of fourth sport event...\\n\")\nfor winner in winners_of_fourth_sport_event:\n    print(winner.__dict__)\n\nmedal_ranking_per_country: list[TCountryWithNumberOfMedals] = (\n    countries_ranking_by_number_of_medals(\n        first_sport_event, second_sport_event, third_sport_event, fourth_sport_event\n    )\n)\n\nprint(\"\\n> Medal ranking per country...\\n\")\nfor stats in medal_ranking_per_country:\n    print(stats)\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/python/idiegorojas.py",
    "content": "\"\"\"\n#31 - Simulador juegos olimpicos\n\"\"\"\n\n\"\"\"\nEJERCICIO:\n\"\"\"\n\n# Crea un programa que simule la celebración de los juegos.\n# El programa debe permitir al usuario registrar eventos y participantes,\n# realizar la simulación de los eventos asignando posiciones de manera aleatoria\n# y generar un informe final. Todo ello por terminal.\n\n\"\"\"\nRequesitos:\n\"\"\"\n# 1. Registrar eventos deportivos.\n# 2. Registrar participantes por nombre y país.\n# 3. Simular eventos de manera aleatoria en base a los participantes (mínimo 3).\n# 4. Asignar medallas (oro, plata y bronce) basándose en el resultado del evento.\n# 5. Mostrar los ganadores por cada evento.\n# 6. Mostrar el ranking de países según el número de medallas.\n\n\"\"\"\nAcciones\n\"\"\"\n# 1. Registro de eventos.\n# 2. Registro de participantes.\n# 3. Simulación de eventos.\n# 4. Creación de informes.\n# 5. Salir del programa.\n\n\nfrom abc import ABC, abstractmethod\nimport random\n\nclass JuegosOlimpicos(ABC):\n    @abstractmethod\n    def registro_evento(self):\n        pass\n\n    @abstractmethod\n    def registro_participante(self):\n        pass\n\n    @abstractmethod\n    def simulacion_evento(self):\n        pass\n\n    @abstractmethod\n    def creacion_informe(self):\n        pass\n\n\nclass SimuladorOlimpico(JuegosOlimpicos):\n    def __init__(self):\n        self.eventos = {}  # {nombre_evento: [lista_participantes]}\n        self.participantes = {}  # {nombre: pais}\n        self.resultados = {}  # {nombre_evento: [(oro, plata, bronce)]}\n        self.medallero = {}  # {pais: {oro: 0, plata: 0, bronce: 0}}\n\n    def registro_evento(self):\n        evento = input(\"Ingrese el nombre del evento: \")\n        if evento in self.eventos:\n            print(f\"El evento '{evento}' ya está registrado.\")\n        else:\n            self.eventos[evento] = []\n            print(f\"Evento '{evento}' registrado correctamente.\")\n\n    def registro_participante(self):\n        if not self.eventos:\n            print(\"Primero debe registrar al menos un evento.\")\n            return\n\n        nombre = input(\"Ingrese el nombre del participante: \")\n        pais = input(\"Ingrese el país del participante: \")\n        \n        if nombre in self.participantes:\n            print(f\"El participante '{nombre}' ya está registrado.\")\n            return\n            \n        self.participantes[nombre] = pais\n        \n        print(\"Eventos disponibles:\")\n        for i, evento in enumerate(self.eventos.keys(), 1):\n            print(f\"{i}. {evento}\")\n            \n        seleccion = input(\"Seleccione el número del evento en el que participará (o 'todos'): \")\n        \n        if seleccion.lower() == 'todos':\n            for evento in self.eventos:\n                self.eventos[evento].append(nombre)\n            print(f\"{nombre} registrado en todos los eventos.\")\n        else:\n            try:\n                indice = int(seleccion) - 1\n                evento = list(self.eventos.keys())[indice]\n                self.eventos[evento].append(nombre)\n                print(f\"{nombre} registrado en {evento}.\")\n            except (ValueError, IndexError):\n                print(\"Selección inválida.\")\n\n    def simulacion_evento(self):\n        if not self.eventos:\n            print(\"No hay eventos registrados.\")\n            return\n            \n        print(\"Eventos disponibles para simular:\")\n        for i, evento in enumerate(self.eventos.keys(), 1):\n            print(f\"{i}. {evento}\")\n            \n        seleccion = input(\"Seleccione el número del evento a simular: \")\n        \n        try:\n            indice = int(seleccion) - 1\n            evento = list(self.eventos.keys())[indice]\n            \n            participantes = self.eventos[evento]\n            if len(participantes) < 3:\n                print(f\"El evento {evento} necesita al menos 3 participantes.\")\n                return\n                \n            # Simular el evento (aleatoriamente)\n            podio = random.sample(participantes, 3)\n            oro, plata, bronce = podio\n            \n            print(\"\\n=== RESULTADOS ===\")\n            print(f\"ORO: {oro} ({self.participantes[oro]})\")\n            print(f\"PLATA: {plata} ({self.participantes[plata]})\")\n            print(f\"BRONCE: {bronce} ({self.participantes[bronce]})\")\n            \n            # Guardar resultados\n            self.resultados[evento] = (oro, plata, bronce)\n            \n            # Actualizar medallero\n            for medalla, participante in zip(['oro', 'plata', 'bronce'], podio):\n                pais = self.participantes[participante]\n                if pais not in self.medallero:\n                    self.medallero[pais] = {'oro': 0, 'plata': 0, 'bronce': 0}\n                self.medallero[pais][medalla] += 1\n                \n        except (ValueError, IndexError):\n            print(\"Selección inválida.\")\n\n    def creacion_informe(self):\n        if not self.resultados:\n            print(\"No se ha simulado ningún evento todavía.\")\n            return\n            \n        print(\"\\n===== INFORME DE RESULTADOS =====\")\n        \n        # Mostrar ganadores por evento\n        print(\"\\n--- Ganadores por Evento ---\")\n        for evento, podio in self.resultados.items():\n            print(f\"\\nEvento: {evento}\")\n            oro, plata, bronce = podio\n            print(f\"ORO: {oro} ({self.participantes[oro]})\")\n            print(f\"PLATA: {plata} ({self.participantes[plata]})\")\n            print(f\"BRONCE: {bronce} ({self.participantes[bronce]})\")\n        \n        # Mostrar ranking de países\n        print(\"\\n--- Ranking de Países ---\")\n        paises_ranking = sorted(\n            self.medallero.items(), \n            key=lambda x: (x[1]['oro'], x[1]['plata'], x[1]['bronce']),\n            reverse=True\n        )\n        \n        for i, (pais, medallas) in enumerate(paises_ranking, 1):\n            print(f\"{i}. {pais}: {medallas['oro']} oro, {medallas['plata']} plata, {medallas['bronce']} bronce\")\n\n\ndef main():\n    simulador = SimuladorOlimpico()\n    \n    while True:\n        print(\"\\n===== SIMULADOR DE JUEGOS OLÍMPICOS =====\")\n        print(\"1. Registro de eventos\")\n        print(\"2. Registro de participantes\")\n        print(\"3. Simulación de eventos\")\n        print(\"4. Creación de informes\")\n        print(\"5. Salir del programa\")\n        \n        opcion = input(\"\\nSeleccione una opción: \")\n        \n        if opcion == \"1\":\n            simulador.registro_evento()\n        elif opcion == \"2\":\n            simulador.registro_participante()\n        elif opcion == \"3\":\n            simulador.simulacion_evento()\n        elif opcion == \"4\":\n            simulador.creacion_informe()\n        elif opcion == \"5\":\n            print(\"Gracias por usar el simulador. ¡Hasta pronto!\")\n            break\n        else:\n            print(\"Opción inválida. Intente de nuevo.\")\n\nif __name__ == \"__main__\":\n    main()"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/python/ignaciovihe.py",
    "content": "\"\"\"\n * EJERCICIO:\n * ¡Los JJOO de París 2024 han comenzado!\n * Crea un programa que simule la celebración de los juegos.\n * El programa debe permitir al usuario registrar eventos y participantes,\n * realizar la simulación de los eventos asignando posiciones de manera aleatoria\n * y generar un informe final. Todo ello por terminal.\n * Requisitos:\n * 1. Registrar eventos deportivos.\n * 2. Registrar participantes por nombre y país.\n * 3. Simular eventos de manera aleatoria en base a los participantes (mínimo 3).\n * 4. Asignar medallas (oro, plata y bronce) basándose en el resultado del evento.\n * 5. Mostrar los ganadores por cada evento.\n * 6. Mostrar el ranking de países según el número de medallas.\n * Acciones:\n * 1. Registro de eventos.\n * 2. Registro de participantes.\n * 3. Simulación de eventos.\n * 4. Creación de informes.\n * 5. Salir del programa.\n\"\"\"\nfrom enum import Enum\nfrom abc import ABC, abstractmethod\nimport random\n#from uuid import uuid4 Se utiliza para obtener calves unitarias. Al final no lo use.\n\n# Enumeración que representa los países posibles en los eventos.\nclass Country(Enum):\n    SPAIN = 1\n    GERMANY = 2\n    EEUU = 3\n    RUSSLAND = 4\n    CHINA = 5\n    FRANCE = 6\n    ITALY = 7\n    UK = 8\n    CANADA = 9\n    PORTUGAL = 10\n    CHILE = 11\n    ARGENTINA = 12\n\n# Enumeración que representa las medallas posibles en los eventos.\nclass Medals(Enum):\n    GOLD = 0\n    SILVER = 1\n    BRONZE = 2\n\n# Clase que representa un evento en los Juegos Olímpicos.\nclass Event:\n    def __init__(self, name: str):\n        self.name = name\n        self.participants = [] # Lista de participantes en el evento.\n        self.finished = False # Estado del evento: si ya se ha finalizado o no.\n        self.standings = [] # Los puestos (ganadores) del evento.\n\n    # Comparación de eventos por nombre (para evitar duplicados).\n    def __eq__(self, other):\n        return self.name == other.name\n    \n    # Se sobrecarga el hash para que los eventos puedan ser usados en conjuntos o diccionarios.\n    def __hash__(self):\n        return hash((self.name))\n\n\n# Clase que gestiona los eventos (registro de eventos).\nclass EventsManager:\n    def __init__(self):\n        self.events = [] # Lista de todos los eventos registrados.\n\n    def register_event(self, event: Event):\n        if event not in self.events:\n            self.events.append(event)\n        else:\n            print(\"El evento ya esta registrado.\")\n\n# Clase que representa a un participante en un evento.\nclass Participant:\n    def __init__(self, name: str, country: Country):\n        self.name = name\n        self.country = country\n\n    def __eq__(self, other):\n        return (self.name == other.name and self.country == other.country)\n    \n    def __hash__(self):\n        return hash((self.name, self.country))\n    \n\n\n# Clase encargada de generar los informes de los eventos y países.\nclass ReportManager:\n    def __init__(self):\n        self.event_winners = {} # Almacena los ganadores de cada evento.\n        self.country_winners ={} # Almacena las victorias por país.\n\n    def add_event_winners(self, event: Event):\n        self.event_winners[event] = event.standings[0:3]\n\n    def add_country_winners(self):\n        for event, winners in self.event_winners.items():\n            for index, participant in enumerate(winners):\n                if participant.country not in self.country_winners:\n                    self.country_winners[participant.country] = [0,0,0]\n                self.country_winners[participant.country][index] += 1\n\n\n# Interfaz abstracta para las opciones del menú (patrón de diseño Command).\nclass OptionInterface(ABC):\n    @abstractmethod\n    def execute(self):\n        pass\n\n# Clase que implementa la opción de registrar un evento.\nclass EventRegistry(OptionInterface):\n    def execute(self, events_manager):\n        event_name = input(\"Introduce el nombre del evento: \").lower()\n        event = Event(event_name)\n        if event not in events_manager.events:\n            events_manager.register_event(event)\n        else:\n            print(\"El evento ya esta registrado.\")\n\n# Clase que implementa la opción de registrar un participante en un evento.\nclass ParticipantRegistry(OptionInterface):\n\n    #Comprueba si hay al menos un evento diponible.\n    def available_events(self, events_manager: EventsManager) -> bool:\n        for event in events_manager.events:\n            if not event.finished:\n                return True\n        return False\n    \n    def execute(self, events_manager):\n        if len(events_manager.events) > 0 and self.available_events(events_manager):\n            while True:\n                print(\"Eventos diponibles:\")\n                for index, event in enumerate(events_manager.events):\n                    if not event.finished:\n                        print(f\"\\t {index + 1}.- {event.name}\")\n                try:\n                    event_option = int(input(\"Introduce el número del evento donde quieres registrar al participante: \"))\n                    if event_option <=0 or event_option > len(events_manager.events) or events_manager.events[event_option -1].finished:\n                        raise ValueError\n                    break\n                except ValueError:\n                    print(\"Introduce una opcion correcta.\")\n                    continue\n            event = events_manager.events[event_option - 1]\n            while True:\n                participant_name = input(\"Introduce el nombre del participante: \").lower()\n                if participant_name:\n                    break\n                else:\n                    print(\"Debes introducir un nombre. No dejes el campo vacío.\")\n            print(\"Países disponibles:\")\n            for country in Country:\n                print(f\"- {country.name.capitalize()}\")\n            while True:\n                participant_country = input(\"Introduce el pais del participante: \").upper()\n                try:\n                    country_enum = Country[participant_country]\n                    break\n                except KeyError:\n                    print(\"País incorrecto, inténtalo de nuevo.\")\n            participant = Participant(participant_name, country_enum)\n            if participant not in event.participants:\n                event.participants.append(participant)\n            else:\n                print(f\"El participante {participant.name.capitalize()} de {participant.country.name} ya esta registrado en el evento '{event.name}'\")\n        else:\n            print(\"No hay eventos disponibles. Registra primero un evento para poder registrar participantes.\")\n\n\n# Clase que simula la realización de los eventos.\nclass SimulateEvents(OptionInterface):\n    def execute(self, events_manager):\n        for event in events_manager.events:\n            if not event.finished:\n                if  len(event.participants) >= 3:\n                    shuffled = event.participants[:] # Crea una coipa de la lista para trabajar con ella.\n                    random.shuffle(shuffled) # Baraja los participantes aleatoriamente para determinar los resultados.\n                    event.standings = shuffled\n                    event.finished = True\n                    print(f\"El evento {event.name} ha tenido lugar.\")\n                else:\n                    print(f\" El evento {event.name} sólo tiene {len(event.participants)} participantes. Necesita 3.\")\n            else:\n                print(f\"El evento {event.name} ya ha terminado.\")\n\n\n# Clase que crea los informes de los eventos y países.\nclass CreateInforms(OptionInterface):\n    def execute(self, events_manager: EventsManager):\n        informs_manager = ReportManager()\n        for event in events_manager.events:\n            if event.finished:\n                informs_manager.add_event_winners(event)\n        informs_manager.add_country_winners()\n\n        print(\"WINNERS FOR EVENT:\")\n        for event, winners in informs_manager.event_winners.items():\n            print(f\"{event.name.capitalize()} Standings:\")\n            for index, winner in enumerate(winners):\n                tabs = \"\\t\" * (index + 1)\n                print(f\"{tabs}{Medals(index).name}: {winner.name} - {winner.country.name}\")\n\n        print(\"\\nCOUNTRY STANDINGS:\")\n        country_standigs = sorted(informs_manager.country_winners.items(), key=lambda item: (-item[1][0], -item[1][1], -item[1][2]))\n        print(\"COUNTRY  -  GOLD  -  SILVER  -  BRONZE\")\n        for country, medals in country_standigs:\n            print(f\"{country.name}     -     {medals[0]}     -     {medals[1]}     -     {medals[2]}\")\n\n\n# Clase que maneja la interfaz de las opciones del menú (Command pattern).\nclass OptionMenuService:\n    def __init__(self, option_interface: OptionInterface, events) -> None:\n        self.option_interface = option_interface\n        self.events = events\n\n    def execute_option(self):\n        self.option_interface.execute(self.events)\n\n\n\ndef main():\n    print(\"JJOO Paris 2024\")\n    events_manager = EventsManager()\n\n    # Diccionario de opciones con objetos Command\n    options = {\n        1: OptionMenuService(EventRegistry(), events_manager),\n        2: OptionMenuService(ParticipantRegistry(), events_manager),\n        3: OptionMenuService(SimulateEvents(), events_manager),\n        4: OptionMenuService(CreateInforms(), events_manager),\n    }\n\n    while True:\n        print(\"1. Register event\")\n        print(\"2. Register participant\")\n        print(\"3. Simulate events\")\n        print(\"4. Create informs\")\n        print(\"5. Exit\")\n        try:\n            option = int(input(\"Introduce una opción: \"))\n            if option == 5:\n                print(\"Saliendo del sistema. ¡Hasta luego!\")\n                break\n            elif option in options:\n                options[option].execute_option()\n            else:\n                print(\"La opción elegida no existe. Elige una opción válida.\")\n        except ValueError:\n            print(\"Entrada no válida. Por favor, introduce un número del 1 al 5.\")\n\n\nmain()\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/python/juanmax2.py",
    "content": "\"\"\"\n* EJERCICIO:\n * ¡Los JJOO de París 2024 han comenzado!\n * Crea un programa que simule la celebración de los juegos.\n * El programa debe permitir al usuario registrar eventos y participantes,\n * realizar la simulación de los eventos asignando posiciones de manera aleatoria\n * y generar un informe final. Todo ello por terminal.\n * Requisitos:\n * 1. Registrar eventos deportivos.\n * 2. Registrar participantes por nombre y país.\n * 3. Simular eventos de manera aleatoria en base a los participantes (mínimo 3).\n * 4. Asignar medallas (oro, plata y bronce) basándose en el resultado del evento.\n * 5. Mostrar los ganadores por cada evento.\n * 6. Mostrar el ranking de países según el número de medallas.\n * Acciones:\n * 1. Registro de eventos.\n * 2. Registro de participantes.\n * 3. Simulación de eventos.\n * 4. Creación de informes.\n * 5. Salir del programa.\n\"\"\"\n\nimport random\n\n# Clase eventos\nclass Participante:\n    \n    def __init__(self, nombre, pais):\n        self.nombre = nombre\n        self.pais = pais\n        self.participantes = {}\n    \n    def __eq__(self, otro : object) -> bool:\n        \n        if isinstance(otro, Participante):\n            return self.nombre == otro.nombre and self.pais == otro.pais\n        return False\n    \n    def __hash__(self) -> int:\n        return  hash(self.nombre, self.pais)\n    \nclass Evento:\n    \n    def __init__(self):\n        \n        self.eventos = []\n        self.participantes = {}\n        self.resultados = {}\n        self.medallas_pais = {}\n    \n    def registrar_evento(self):\n        evento = input(\"Introduce el nombre del evento deportivo: \")\n        \n        if evento not in self.eventos:\n            self.eventos.append(evento)\n            print(f\"El evento {evento} registrado.\")\n        else:\n            print(\"Evento ya existente\")\n    \n    def registrar_participantes(self):\n        \n        if not self.eventos:\n            print(\"No hay eventos para participar\")\n            return\n        \n        nombre = input(\"Introduce el nombre del participante: \")\n        pais = input(\"Introduce el pais del participante: \")\n        participante = Participante(nombre, pais)\n        \n        \n        print(\"Eventos disponibles\")\n        for index, evento in enumerate(self.eventos):\n            print(f\"{index + 1} - {evento}\")\n        \n        eleccion_evento = int(input(\n            \"Selecciona el número del evento para asignar al participante: \"\n        )) - 1\n        \n        if eleccion_evento >= 0 and eleccion_evento < len(self.eventos):\n            evento = self.eventos[eleccion_evento]\n            \n            if evento in self.participantes and participante in self.participantes[evento]:\n                print(f\"El participante {nombre}, {pais} ya esta registrado\")\n            \n            else:\n                if evento not in self.participantes:\n                    self.participantes[evento] = []\n                    \n                self.participantes[evento].append(participante)\n                print(f\"El participante {participante.nombre} registrado correctamente en evento {evento}\")\n\n        else:\n            print(\n                \"Selección del evento erronea\"\n            )\n        \n    def simular_eventos(self):\n        \n        if not self.eventos:\n            print(\"No hay eventos registrados. Por favor, registra uno primero\")\n            return\n        \n        for evento in self.eventos:\n            if len(self.participantes[evento]) < 3:\n                print(\"No hay suficientes participantes para simular el evento\")\n                continue\n            \n            participantes_evento = random.sample(self.participantes[evento], 3)\n            random.shuffle(participantes_evento)\n            \n            oro, plata, bronce = participantes_evento\n            self.resultados[evento] = [oro, plata, bronce]\n            \n            self.actualizar_resultados_pais(oro.pais, \"oro\")\n            self.actualizar_resultados_pais(plata.pais, \"plata\")\n            self.actualizar_resultados_pais(bronce.pais, \"bronce\")\n            \n            print(f\"Simulación del evento: {evento}\")\n            print(f\"Oro: {oro.nombre} ({oro.pais})\")\n            print(f\"Plata: {plata.nombre} ({plata.pais})\")\n            print(f\"Bronce: {bronce.nombre} ({bronce.pais})\")\n            \n    def actualizar_resultados_pais(self, pais, medalla):\n        if pais not in self.medallas_pais:\n            self.medallas_pais[pais] = {\n                \"oro\" : 0, \"plata\" : 0, \"bronce\" : 0\n            }\n        self.medallas_pais[pais][medalla] += 1\n    \n    def mostrar_informe(self):\n        \n        print(\"Informe por evento\")\n        \n        if self.resultados:\n            for evento, ganador in self.resultados.items():\n                print(f\"Evento: {evento}\")\n                print(f\"Oro: {ganador[0].nombre} ({ganador[0].pais})\")\n                print(f\"Plata: {ganador[1].nombre} ({ganador[1].pais})\")\n                print(f\"Bronce: {ganador[2].nombre} ({ganador[2].pais})\")   \n        \n        else:\n            print(f\"No hay resultados que mostrar\") \n        \n        if self.medallas_pais:\n            print(\"Informe por pais\")\n            \n            for pais, medalla in sorted(self.medallas_pais.items(), key=lambda x: (\n                x[1][\"oro\"], x[1][\"plata\"], x[1][\"bronce\"]), reverse=True):\n                \n                print(f\"{pais}: Oro {medalla[\"oro\"]}, Plata: {medalla[\"plata\"]}, Bronce: {medalla[\"bronce\"]}\")\n            \n            \n                \n \n         \n# Menu de opciones\n\ndef mostrar_menu():\n    print(\n        \"\"\"\n        1. Registro de eventos.\n        2. Registro de participantes.\n        3. Simulación de eventos.\n        4. Creación de informes.\n        5. Salir del programa.\n        \"\"\"\n        )\n\n# Seleccionar opción\n\ndef seleccionar_opcion():\n    \n    opcion = int(input(\"Selecciona la opción que quieres ejecutar: \"))\n    return opcion\n\n\nevento = Evento()\ncontinuar = True\nwhile continuar == True:\n    mostrar_menu()\n    opcion = seleccionar_opcion()\n    \n    match opcion:\n        case 1:\n            evento.registrar_evento()\n        case 2:\n            evento.registrar_participantes()\n        case 3:\n            evento.simular_eventos()\n        case 4:\n            evento.mostrar_informe()\n        case 5:\n            print(\"Cerrando programa...\")\n            continuar = False\n        case _:\n            print(\"Opción invalida por favor selecciona una nueva\")"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/python/juanppdev.py",
    "content": "\"\"\"\n * EJERCICIO:\n * ¡Los JJOO de París 2024 han comenzado!\n * Crea un programa que simule la celebración de los juegos.\n * El programa debe permitir al usuario registrar eventos y participantes,\n * realizar la simulación de los eventos asignando posiciones de manera aleatoria\n * y generar un informe final. Todo ello por terminal.\n * Requisitos:\n * 1. Registrar eventos deportivos.\n * 2. Registrar participantes por nombre y país.\n * 3. Simular eventos de manera aleatoria en base a los participantes (mínimo 3).\n * 4. Asignar medallas (oro, plata y bronce) basándose en el resultado del evento.\n * 5. Mostrar los ganadores por cada evento.\n * 6. Mostrar el ranking de países según el número de medallas.\n * Acciones:\n * 1. Registro de eventos.\n * 2. Registro de participantes.\n * 3. Simulación de eventos.\n * 4. Creación de informes.\n * 5. Salir del programa.\n\"\"\"\n\nimport json\nimport random\n\n# Inicializar datos\ndata = {\n    \"eventos\": [],\n    \"participantes\": [],\n    \"resultados\": []\n}\n\n# Función para guardar datos en un archivo JSON\ndef guardar_datos():\n    with open('juegos_olimpicos.json', 'w') as archivo:\n        json.dump(data, archivo, indent=4)\n\n# Función para registrar eventos\ndef registrar_evento():\n    evento = input(\"Nombre del evento: \")\n    data[\"eventos\"].append(evento)\n    guardar_datos()\n    print(f\"Evento '{evento}' registrado con éxito.\")\n\n# Función para registrar participantes\ndef registrar_participante():\n    nombre = input(\"Nombre del participante: \")\n    pais = input(\"País del participante: \")\n    data[\"participantes\"].append({\"nombre\": nombre, \"pais\": pais})\n    guardar_datos()\n    print(f\"Participante '{nombre}' de '{pais}' registrado con éxito.\")\n\n# Función para simular eventos\ndef simular_evento():\n    if len(data[\"participantes\"]) < 3:\n        print(\"Se necesitan al menos 3 participantes para simular un evento.\")\n        return\n\n    evento = input(\"Nombre del evento a simular: \")\n    if evento not in data[\"eventos\"]:\n        print(f\"El evento '{evento}' no está registrado.\")\n        return\n\n    participantes = random.sample(data[\"participantes\"], 3)\n    random.shuffle(participantes)\n    medallas = [\"oro\", \"plata\", \"bronce\"]\n\n    resultado = {\n        \"evento\": evento,\n        \"ganadores\": []\n    }\n\n    for i in range(3):\n        resultado[\"ganadores\"].append({\n            \"nombre\": participantes[i][\"nombre\"],\n            \"pais\": participantes[i][\"pais\"],\n            \"medalla\": medallas[i]\n        })\n\n    data[\"resultados\"].append(resultado)\n    guardar_datos()\n    print(f\"Evento '{evento}' simulado con éxito.\")\n    for ganador in resultado[\"ganadores\"]:\n        print(f\"{ganador['nombre']} de {ganador['pais']} ganó la medalla de {ganador['medalla']}.\")\n\n# Función para crear informes\ndef crear_informe():\n    paises = {}\n    for resultado in data[\"resultados\"]:\n        for ganador in resultado[\"ganadores\"]:\n            pais = ganador[\"pais\"]\n            medalla = ganador[\"medalla\"]\n            if pais not in paises:\n                paises[pais] = {\"oro\": 0, \"plata\": 0, \"bronce\": 0}\n            paises[pais][medalla] += 1\n\n    print(\"\\nRanking de países según el número de medallas:\")\n    for pais, medallas in sorted(paises.items(), key=lambda item: (item[1][\"oro\"], item[1][\"plata\"], item[1][\"bronce\"]), reverse=True):\n        print(f\"{pais}: Oro: {medallas['oro']}, Plata: {medallas['plata']}, Bronce: {medallas['bronce']}\")\n\n# Menú interactivo\ndef menu():\n    while True:\n        print(\"\\nMenú:\")\n        print(\"1. Registro de eventos\")\n        print(\"2. Registro de participantes\")\n        print(\"3. Simulación de eventos\")\n        print(\"4. Creación de informes\")\n        print(\"5. Salir del programa\")\n        opcion = input(\"Selecciona una opción: \")\n\n        if opcion == \"1\":\n            registrar_evento()\n        elif opcion == \"2\":\n            registrar_participante()\n        elif opcion == \"3\":\n            simular_evento()\n        elif opcion == \"4\":\n            crear_informe()\n        elif opcion == \"5\":\n            print(\"Saliendo del programa.\")\n            break\n        else:\n            print(\"Opción no válida. Inténtalo de nuevo.\")\n\n# Ejecutar el menú\nmenu()\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/python/kenysdev.py",
    "content": "# ╔═════════════════════════════════════╗\n# ║ Autor:  Kenys Alvarado              ║\n# ║ GitHub: https://github.com/Kenysdev ║\n# ║ 2024 -  Python                      ║\n# ╚═════════════════════════════════════╝\n\n# ---------------------------------\n# 31 * SIMULADOR JUEGOS OLÍMPICOS\n# ---------------------------------\n\n\"\"\"\n* EJERCICIO:\n* ¡Los JJOO de París 2024 han comenzado!\n* Crea un programa que simule la celebración de los juegos.\n* El programa debe permitir al usuario registrar eventos y participantes,\n* realizar la simulación de los eventos asignando posiciones de manera aleatoria\n* y generar un informe final. Todo ello por terminal.\n * Requisitos:\n * 1. Registrar eventos deportivos.\n * 2. Registrar participantes por nombre y país.\n * 3. Simular eventos de manera aleatoria en base a los participantes (mínimo 3).\n * 4. Asignar medallas (oro, plata y bronce) basándose en el resultado del evento.\n * 5. Mostrar los ganadores por cada evento.\n * 6. Mostrar el ranking de países según el número de medallas.\n * Acciones:\n * 1. Registro de eventos.\n * 2. Registro de participantes.\n * 3. Simulación de eventos.\n * 4. Creación de informes.\n * 5. Salir del programa.\n\"\"\"\n\nfrom abc import ABC, abstractmethod\nfrom random import randint\nimport copy\n\n# _______________\nclass GlobalConstants:\n    MEDALS = ['🥇 Oro', '🥈 Plata', '🥉 Bronce']\n\n    MENU = \"\"\"\nSIMULADOR JUEGOS OLÍMPICOS:\n--------------------------------------------------\n| 1. Registrar evento        | 4. Crear informes |  \n| 2. Registrar participante  | 5. Salir          |\n| 3. Simulación de eventos   |                   |\n--------------------------------------------------\n\"\"\"\n\nclass AbstractDataTable(ABC):\n    \"\"\"Contrato sobre los métodos requeridos para cada tabla creada.\"\"\"\n    @abstractmethod\n    def add(self) -> None:\n        pass\n\n    @abstractmethod\n    def count(self) -> int:\n        pass\n\n    @abstractmethod\n    def get_list(self) -> list:\n        pass\n\n#__________________________\nclass DataInMemory:\n    __instance = None\n\n    class EventsTable(AbstractDataTable):\n        def __init__(self) -> None:\n            self._dt: list = []\n        \n        def add(self, sport: str) -> None: \n            self._dt.append([sport])\n        \n        def count(self) -> int:\n            return len(self._dt)\n\n        def get_list(self) -> list:\n            return copy.deepcopy(self._dt)\n\n\n    class ParticipantsTable(AbstractDataTable):\n        def __init__(self) -> None:\n            self._dt: list = []\n\n        def add(self, name: str, country: str, event_id: int) -> None: \n            self._dt.append([name, country, event_id])\n        \n        def count(self) -> int:\n            return len(self._dt)\n\n        def get_list(self) -> list:\n            return copy.deepcopy(self._dt)\n\n    class SimulationTable(AbstractDataTable):\n        def __init__(self) -> None:\n            self._dt: list = []\n\n        def add(self, result_event: list) -> None:\n            self._dt.append(result_event)\n        \n        def count(self) -> int:\n            return len(self._dt)\n        \n        def get_list(self) -> list:\n            return self._dt\n\n    def _init_tables(self):\n        self.events_table = self.EventsTable()\n        self.participants_table = self.ParticipantsTable()\n        self.simulation_table = self.SimulationTable()\n\n    def __new__(cls):\n        if cls.__instance is None:\n            cls.__instance = super().__new__(cls)\n            cls.__instance._init_tables()\n        return cls.__instance\n\n#__________________________\nclass Input:\n    def get(self, msg: str, type_= \"str\") -> str:\n        \"\"\"Retorna por defecto un tipo 'str' no vacío, si se especifica 'int' retornará un entero. \"\"\"\n        while True:\n            txt: str = input(msg)\n            if type_ == 'str' and len(txt) > 0:\n                return txt\n            if type_ == 'int' and txt.isdigit():\n                return int(txt)\n            else:\n                print(\"\\nIngresa un número entero.\")\n\n#__________________________\n# -> Requisitos:\n# 1. Registrar eventos deportivos.\nclass Events:\n    def __init__(self, data, input_, global_constants):\n        self.dt = data()\n        self.input_ = input_()\n        self.gc = global_constants\n\n    def add(self) -> None:\n        print(\"AGREGAR EVENTO DEPORTIVO:\")\n        sport: str = self.input_.get(\"Deporte: \")\n        self.dt.events_table.add(sport)\n        print(f\"{sport} fue agregado\")\n        #print(self.gc.MENU)\n        \n#__________________________\n# 2. Registrar participantes por nombre y país.\nclass Participants:\n    def __init__(self, data, input_, global_constants):\n        self.dt = data()\n        self.input_ = input_()\n        self.gc = global_constants()\n\n    def get_event_id(self, events: list) -> int:\n        print(\"Seleccionar el evento donde participará:\")\n        for i, e in enumerate(events):\n            print(f\"{i}. {e[0]}\")\n\n        while True:\n            index = self.input_.get(\"Id de evento: \", \"int\")\n            if not 0 <= int(index) < len(events):\n                print(\"\\nId no encontrada.\")\n            else:\n                break              \n        \n        return int(index)\n\n    def add(self) -> None:\n        print(\"AGREGAR PARTICIPANTE:\")\n        events = self.dt.events_table.get_list()\n        if not len(events) > 0:\n            print(\"No existe evento en cuál participar, agrega un evento primero.\")\n            return\n        \n        event_id: int = self.get_event_id(events)\n        name: str = self.input_.get(\"Nombre: \")\n        country: str = self.input_.get(\"país: \")\n        self.dt.participants_table.add(name, country, event_id)\n        print(f\"{name} fue agregado\")\n        print(self.gc.MENU)\n        \n#__________________________\n# 3. Simular eventos de manera aleatoria en base a los participantes (mínimo 3).\n# 4. Asignar medallas (oro, plata y bronce) basándose en el resultado del evento.\n \nclass Simulation:\n    def __init__(self, data, global_constants):\n        self.dt = data()\n        self.gc = global_constants()\n\n    def _qualify_participants(self, event_id) -> list:\n        participants: list = self.dt.participants_table.get_list()\n        participants = list(filter(lambda x: x[2] == event_id, participants))\n        for p in participants:\n            p.append(randint(1, 100))\n        \n        participants.sort(key=lambda x: x[3], reverse=True)\n        top_3_participants = participants[:3]\n\n        medals = self.gc.MEDALS\n        for i, p in enumerate(top_3_participants):\n            p.append(medals[i])\n        \n        return top_3_participants\n\n    def _add_result_events(self):\n        events = self.dt.events_table.get_list()\n        simulation: list = []\n        for event_id, event in enumerate(events):\n            event.append(self._qualify_participants(event_id))\n            simulation.append(event)\n\n        self.dt.simulation_table.add(simulation)\n\n    def start(self) -> None:\n        if self.dt.events_table.count() >= 1:\n            if self.dt.participants_table.count() >= 3:\n                self._add_result_events()\n                total_simulation = self.dt.simulation_table.count()\n                print(f\"Simulación '#{total_simulation}' creada.\")\n                print(\"Puedes ver el resultadoc con opcion: '4. Crear informes.'\")\n            else:\n                print(\"Debe haber al menos 'tres' participantes.\")\n        else:\n            print(\"Debe haber al menos un evento.\")\n\n#__________________________\n# 5. Mostrar los ganadores por cada evento.\n# 6. Mostrar el ranking de países según el número de medallas.\nclass Reports:\n    def __init__(self, data, global_constants):\n        self.dt = data()\n        self.gc = global_constants()\n        self.ranking_countries: dict = {}\n\n    def _generate_top_countries(self):\n        countries = self.ranking_countries.items()\n        sorted_rank = sorted(countries, key=lambda item: item[1], reverse=True)\n\n        for i, (name, total) in enumerate(sorted_rank):\n            print(f\"'{i + 1}' - {name} -> Medallas: {total[0]} | Puntaje: {total[1]}\")\n\n    def _iterate_participants(self, participants):\n        for i, participant in enumerate(participants):\n            name, country, event_id, score, medal = participant\n            \n            print(f\"'{i + 1}' - {name} - {country} -> Score: {score}, Medal: {medal}\")\n\n            # Registrar para generar ranking de países por numero de medallas.\n            if country in self.ranking_countries:\n                medals, current_score = self.ranking_countries[country]\n                self.ranking_countries[country] = [medals + 1, current_score + score]\n            else:\n                self.ranking_countries[country] = [1, score]\n\n    def _iterate_events(self, simulation):\n        for event in simulation:\n            event_name = event[0]\n            participants = event[1]\n\n            print(f\"\\nEvent: {event_name}:\")\n            if len(participants) < 3:\n                print(\"Cancelado por falta de participantes.\")\n                continue\n\n            self._iterate_participants(participants)\n\n    def generate(self) -> None:\n        simulations = self.dt.simulation_table.get_list()\n        if simulations == []:\n            print(\"Aún no hay simulaciones creadas.\")\n\n        for i, simulation in enumerate(simulations):\n            simulation_id = i + 1\n            \n            print(f\"\\n______________\\nSimulation {simulation_id}\")\n            self._iterate_events(simulation)\n\n            print(\"\\nRanking de países, según el número de medallas:\") \n            self._generate_top_countries()\n            self.ranking_countries.clear()\n\n        print(self.gc.MENU)\n\n#__________________________\nclass Program:\n    def __init__(self, global_constants, data, input_):\n        self._gc = global_constants()\n        self.input_ = input_()\n        self._events = Events(data, input_, global_constants)\n        self._participants = Participants(data, input_, global_constants)\n        self._simulation = Simulation(data, global_constants)\n        self._reports = Reports(data, global_constants)\n\n    def run(self):\n        print(self._gc.MENU)\n        while True:\n            option = self.input_.get(\"\\nOpción: \")\n            match option:\n                case \"1\": self._events.add()\n                case \"2\": self._participants.add()\n                case \"3\": self._simulation.start()\n                case \"4\": self._reports.generate()\n                case '5': print(\"Adios\"); break\n                case _: print(\"Seleccionar de '1 a 5'\")\n\n#__________________________\nif __name__ == \"__main__\":\n    program = Program(GlobalConstants, DataInMemory, Input)\n    program.run()\n\n# end\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/python/mhayhem.py",
    "content": "# @Author Daniel Grande (Mhayhem)\n\nimport random\nfrom abc import ABC, abstractmethod\n\n# EJERCICIO:\n# ¡Los JJOO de París 2024 han comenzado!\n# Crea un programa que simule la celebración de los juegos.\n# El programa debe permitir al usuario registrar eventos y participantes,\n# realizar la simulación de los eventos asignando posiciones de manera aleatoria\n# y generar un informe final. Todo ello por terminal.\n# Requisitos:\n# 1. Registrar eventos deportivos.\n# 2. Registrar participantes por nombre y país.\n# 3. Simular eventos de manera aleatoria en base a los participantes (mínimo 3).\n# 4. Asignar medallas (oro, plata y bronce) basándose en el resultado del evento.\n# 5. Mostrar los ganadores por cada evento.\n# 6. Mostrar el ranking de países según el número de medallas.\n# Acciones:\n# 1. Registro de eventos.\n# 2. Registro de participantes.\n# 3. Simulación de eventos.\n# 4. Creación de informes.\n# 5. Salir del programa.\n\n# // class //\n\n# athlete instance\nclass Athlete:\n    # athelte init\n    def __init__(self, name : str, surname: str, country: str):\n        self.name = name.capitalize()\n        self.surname = surname.capitalize()\n        self.country = country.capitalize()\n    # display athlete info\n    def __str__(self):\n        return f\"Nombre: {self.name} {self.surname}; Pais {self.country}\"\n\n\nclass OlimpicEvents:\n    def __init__(self):\n        self.participants = []\n        self.event = []\n        self.medals = {}\n        \n    def register_participants(self):\n        print(\"Registro de participantes.\")\n        while len(self.participants) < 5:\n            name = input(\"Nombre:\\n\")\n            surname = input(\"Apellido:\\n\")\n            country = input(\"País:\\n\")\n            \n            if name and surname and country:\n                athlete = Athlete(name, surname, country)\n                self.participants.append(athlete)\n            else:\n                print(\"Ninguna entrada puede estar vacía.\")\n        \n        self.medals = {person.country : 0 for person in self.participants}\n            \n    def register_event(self):\n        print(\"Registro de eventos.\")\n        while len(self.event) < 3:\n            event = input(\"Evento:\\n\")\n            if event and event not in self.event:\n                self.event.append(event)\n            else:\n                print(\"Evento ya registrado o no has escrito nada.\")\n    \n    def events_simulator(self):\n        events_copy = self.event\n        for event in events_copy:\n            print(f\"El evento {event} va ha comenzar.\")\n            print(\"*\" * 40)\n            events_copy.remove(event)\n            gold, silver, bronze = random.sample(self.participants, 3)\n            print(f\"Oro: {gold.name}, plata: {silver.name} y bronce: {bronze.name}\")\n            print(\"*\" * 40)\n            \n            self.medals[gold.country] += 1\n            self.medals[silver.country] += 1\n            self.medals[bronze.country] += 1\n    \n    def display_report(self):\n        print(\"Tabla de medallas por pais\")\n        print(f\"{\"=\" * 10} MEDALS {\"=\" * 10}\")\n        for k, v in self.medals.items():\n            print(f\"{k}: {v}\")\n\n\ndef main():\n    print(\"1. Registrar eventos(3 por registro).\\n\"\n        \"2. Registrar participantes(5 por registro).\\n\"\n        \"3. Simular los eventos.\\n\"\n        \"4. Mostrar informes.\\n\"\n        \"5. Cerrar programa.\")\n    \n    olimpics = OlimpicEvents()\n    \n    while True:\n        try:\n            option = int(input())\n        except ValueError:\n            print(\"Debes introducir solo números (del 1 al 5)\")\n            continue\n        \n        match option:\n            case 1:\n                olimpics.register_event()\n            case 2:\n                olimpics.register_participants()\n            case 3:\n                olimpics.events_simulator()\n            case 4:\n                olimpics.display_report()\n            case 5:\n                print(\"Cerrando programa.\")\n                break"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/python/mouredev.py",
    "content": "import random\n\n\nclass Participant:\n\n    def __init__(self, name, country):\n        self.name = name\n        self.country = country\n\n    def __eq__(self, other: object) -> bool:\n        if isinstance(other, Participant):\n            return self.name == other.name and self.country == other.country\n        return False\n\n    def __hash__(self) -> int:\n        return hash(self.name, self.country)\n\n\nclass Olympics:\n\n    def __init__(self):\n        self.events = []\n        self.participants = {}\n        self.event_results = {}\n        self.country_results = {}\n\n    def register_event(self):\n\n        event = input(\"Introduce el nombre del evento deportivo: \").strip()\n\n        if event in self.events:\n            print(f\"El evento {event} ya está registrado.\")\n        else:\n            self.events.append(event)\n            print(f\"Evento {event} registrado correctamente.\")\n\n    def register_participant(self):\n\n        if not self.events:\n            print(\"No hay eventos registrados. Por favor, registra uno primero.\")\n            return\n\n        name = input(\"Introduce el nombre del participante: \").strip()\n        country = input(\"Introduce el país del participante: \").strip()\n        participant = Participant(name, country)\n\n        print(\"Eventos deportivos disponibles:\")\n        for index, event in enumerate(self.events):\n            print(f\"{index + 1}. {event}\")\n\n        event_choice = int(\n            input(\"Selecciona el número del evento para asignar al participante: \")) - 1\n\n        if event_choice >= 0 and event_choice < len(self.events):\n\n            event = self.events[event_choice]\n\n            if event in self.participants and participant in self.participants[event]:\n                print(\n                    f\"El participante {name} de {country} ya está registrado en el evento deportivo {event}.\")\n            else:\n\n                if event not in self.participants:\n                    self.participants[event] = []\n\n                self.participants[event].append(participant)\n                print(\n                    f\"El participante {name} de {country} se ha registrado en el evento deportivo {event}.\")\n        else:\n            print(\n                \"Selección de evento deportivo inválido. El participante no se ha registrado.\")\n\n    def simulate_events(self):\n\n        if not self.events:\n            print(\"No hay eventos registrados. Por favor, registra uno primero.\")\n            return\n\n        for event in self.events:\n\n            if len(self.participants[event]) < 3:\n                print(\n                    f\"No hay participantes suficientes para simular el evento {event} (mínimo 3).\")\n                continue\n\n            event_participants = random.sample(self.participants[event], 3)\n            random.shuffle(event_participants)\n\n            gold, silver, bronze = event_participants\n            self.event_results[event] = [gold, silver, bronze]\n\n            self.update_country_results(gold.country, \"gold\")\n            self.update_country_results(silver.country, \"silver\")\n            self.update_country_results(bronze.country, \"bronze\")\n\n            print(f\"Resultados simulación del evento: {event}\")\n            print(f\"Oro: {gold.name} ({gold.country})\")\n            print(f\"Plata: {silver.name} ({silver.country})\")\n            print(f\"Bronce: {bronze.name} ({bronze.country})\")\n\n    def update_country_results(self, country, medal):\n        if country not in self.country_results:\n            self.country_results[country] = {\n                \"gold\": 0, \"silver\": 0, \"bronze\": 0}\n        self.country_results[country][medal] += 1\n\n    def show_report(self):\n\n        print(\"Informe Juegos Olímpicos:\")\n\n        if self.event_results:\n\n            print(\"Informe por evento:\")\n\n            for event, winners in self.event_results.items():\n                print(f\"Evento: {event}\")\n                print(f\"Oro: {winners[0].name} ({winners[0].country})\")\n                print(f\"Plata: {winners[1].name} ({winners[1].country})\")\n                print(f\"Bronce: {winners[2].name} ({winners[2].country})\")\n        else:\n            print(\"No hay resultados registrados.\")\n\n        print()\n\n        if self.country_results:\n\n            print(\"Informe por país:\")\n\n            for country, medals in sorted(self.country_results.items(), key=lambda x: (\n                    x[1][\"gold\"], x[1][\"silver\"], x[1][\"bronze\"]), reverse=True):\n\n                print(\n                    f\"{country}: Oro {medals['gold']}, Plata {medals['silver']}, Bronce {medals['bronze']}\")\n\n        else:\n            print(\"No hay medallas por país registradas.\")\n\n\nolympics = Olympics()\n\nprint(\"Simulador de Juegos Olímpicos\")\n\nwhile True:\n\n    print()\n\n    print(\"1. Registro de eventos\")\n    print(\"2. Registro de participantes\")\n    print(\"3. Simulación de eventos\")\n    print(\"4. Creación de informes\")\n    print(\"5. Salir\")\n\n    option = input(\"Selecciona una acción: \")\n\n    match option:\n        case \"1\":\n            olympics.register_event()\n        case \"2\":\n            olympics.register_participant()\n        case \"3\":\n            olympics.simulate_events()\n        case \"4\":\n            olympics.show_report()\n        case \"5\":\n            print(\"Saliendo del simulador...\")\n            break\n        case _:\n            print(\"Opción inválida. Por favor, selecciona una nueva.\")\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/python/mrodara.py",
    "content": "### Simulador Juegos Olímpicos\nimport random\n\nclass Athlete():\n    \n    def __init__(self, name: str, country: str):\n        self.name = name\n        self.country = country\n        \n    # Comprobación de si estamos trabajando con un mismo atleta\n    def __eq__(self, athlete: object)->bool:\n        if isinstance(athlete, Athlete):\n            return self.name == athlete.name and self.country == athlete.country\n        return False\n    \nclass OlimpicGames():\n    \n    def __init__(self):\n        self.events = []\n        self.participants = {}\n        self.event_results = {}\n        self.country_results = {}\n    \n    #Registro de evento\n    def register_event(self):\n        \n        event_name = input(\"Introduce el nombre del evento: \")\n        \n        if event_name.lower() in self.events:\n            print(f\"El evento {event_name.capitalize()} ya está registrado.\")\n        else:\n            self.events.append(event_name.lower())\n            print(f\"El evento {event_name.capitalize()} se ha registrado correctamente\")\n    \n    # Listar eventos disponibles\n    def list_events(self):\n        \n        if not self.events:\n            print(\"No hay eventos registrados. Por favor, regístra un evento primero.\")\n        else:\n            print(\"Eventos disponibles:\")\n            for i, event in enumerate(self.events):\n                print(f\"{i+1}. {event.capitalize()}\")\n    \n    #Registro de participante\n    def register_participant(self):\n        \n        if not self.events:\n            print(\"No hay eventos registrados. Por favor, regístra un evento primero.\")\n        else:\n            name = input(\"Introduce el nombre del atleta: \")\n            country = input(\"Introduce el país del atleta: \")\n            #athlete = Athlete(name, country)\n            \n            # Tenemos que mostrar la lista de eventos disponibles para inscribir al atleta.\n            self.list_events()\n            option = int(input(\"Indica el evento en el quieres inscribir al participante: \"))\n            \n            #Comprobación de opción correcta:\n            while (option < 1 or option > len(self.events)) or not isinstance(option, int):\n                print(\"Error, debes indicar una de las opciones de eventos que te listamos: \")\n                option = int(input(\"Indica el evento en el quieres inscribir al participante: \"))\n            \n            # Añadimos al diccionario de participantes el evento y la lista de participantes.\n            if not self.events[option-1] in self.participants:\n                self.participants[self.events[option-1]] = []\n                \n            # Tenemos que comprobar que el participante no esté ya inscrito\n            if Athlete(name, country) in self.participants[self.events[option-1]]:\n                print(f\"El atleta {name} ya está inscrito en el evento {self.events[option-1].capitalize()}\")\n            else:\n                self.participants[self.events[option-1]].append(Athlete(name, country))\n                print(f\"El atleta {name} se ha inscrito correctamente en el evento {self.events[option-1].capitalize()}\")\n            \n    # Listar participantes inscritos por evento    \n    def list_participants(self):\n        \n        if not self.participants:\n            print(\"No hay participantes inscritos. Por favor, inscribe un participante primero.\")\n        else:\n            print(\"Participantes inscritos:\")\n            for event, participants in self.participants.items():\n                print(f\"Evento: {event.capitalize()}\")\n                for i, participant in enumerate(participants):\n                    print(f\"{i+1}. {participant.name} - {participant.country}\")\n    \n    #Asignar medallas tras evento\n    def assign_medal(self, country: str, position: int):\n        if not country in self.country_results:\n            self.country_results[country] = [0,0,0] #Orden Oro, Plata, Bronce\n        self.country_results[country][position] +=1\n    \n    '''\n    Para el ranking y simulando a como ocurre en realidad vamos a darle\n    mas valor a las medallas de oro que de plata y a las de plata sobre \n    las de bronce:\n    oro x 5\n    plata x 2\n    bronce x 1\n    '''\n    #Ranking según Paises\n    def show_ranking(self):\n        \n        ranking = []\n        \n        if not self.country_results:\n            print(\"No hay resultados de eventos. Registra eventos, participantes y simulalos\")\n        else:\n            for country, results in self.country_results.items():\n                score = results[0]*5 + results[1]*2 + results[2]\n                ranking.append((country, score, results[0], results[1], results[2]))\n            \n            # Ordenar el ranking por el puntaje de mayor a menor\n            ranking.sort(key=lambda x: x[1], reverse=True)\n            \n            print(\"Ranking de países:\")\n            for country, score, gold, silver, bronze in ranking:\n                print(f\"{country}: Oro: {gold} Plata: {silver} Bronce: {bronze} - Puntuación: {score}\")\n\n    #Mostrar resultados de un evento\n    def show_event_results(self):\n        #Mostramos los eventos disponibles\n        self.list_events()\n        \n        option = int(input(\"Indica el evento sobre el que consultar el resultado: \"))\n            \n        #Comprobación de opción correcta:\n        while (option < 1 or option > len(self.events)) or not isinstance(option, int):\n            print(\"Error, debes indicar una de las opciones de eventos que te listamos: \")\n            option = int(input(\"Indica el evento sobre el que consultar el resultado: \"))\n        print(f\"Posicion  Participante  País\")\n        print(f\"=============================\")\n        for i, participant in enumerate(self.event_results[self.events[option-1]]):\n            if i+1 == 1:\n                print(f\"{i+1}. {participant.name} - {participant.country} - Medalla de Oro\")\n            elif i+1 == 2:\n                print(f\"{i+1}. {participant.name} - {participant.country} - Medalla de Plata\")\n            elif i+1 == 3:\n                print(f\"{i+1}. {participant.name} - {participant.country} - Medalla de Bronce\")\n            else:\n                print(f\"{i+1}. {participant.name} - {participant.country}\")\n    #Simular un evento\n    def simulate_event(self):\n        self.list_events()\n        \n        option = int(input(\"Indica el evento que quieres simular: \"))\n        #Comprobación de opción correcta:\n        while (option < 1 or option > len(self.events)) or not isinstance(option, int):\n            print(\"Error, debes indicar una de las opciones de eventos que te listamos: \")\n            option = int(input(\"Indica el evento que quieres simular: \"))\n        \n        #Minimo de participantes\n        if not len(self.events[option-1]) >= 3:\n            print(f\"El evento {self.events[option-1].capitalize()} no tiene el mínimo de participantes\")\n        else:\n            #Simulación del evento\n            if not self.events[option-1] in self.event_results:\n                self.event_results[self.events[option-1]] = []\n            \n                print(f\"Simulando el evento {self.events[option-1].capitalize()}...\")\n                positions = random.sample(self.participants[self.events[option-1]], len(self.participants[self.events[option-1]]))\n                self.event_results[self.events[option-1]] = positions\n                \n                #Mostramos el resultado de la simulación del evento y guardamos las medallas en el medallero de cada País.\n                print(f\"El resultado del evento {self.events[option-1].capitalize()} es: \")\n                for i, participant in enumerate(self.event_results[self.events[option-1]]):\n                    if i+1 == 1:\n                        print(f\"{i+1}. {participant.name} - {participant.country} - Medalla de Oro\")\n                        self.assign_medal(country=participant.country, position=i)\n                    elif i+1 == 2:\n                        print(f\"{i+1}. {participant.name} - {participant.country} - Medalla de Plata\")\n                        self.assign_medal(country=participant.country, position=i)\n                    elif i+1 == 3:\n                        print(f\"{i+1}. {participant.name} - {participant.country} - Medalla de Bronce\")\n                        self.assign_medal(country=participant.country, position=i)\n                    else:\n                        print(f\"{i+1}. {participant.name} - {participant.country}\")\n                print(f\"Fin de la simulación del evento {self.events[option-1].capitalize()}...\")\n                \nparis2024 = OlimpicGames()\n\nparis2024.register_event()\nparis2024.register_event()\nparis2024.register_participant()\nparis2024.register_participant()\nparis2024.register_participant()\nparis2024.register_participant()\nparis2024.register_participant()\nparis2024.register_participant()\nparis2024.register_participant()\nparis2024.register_participant()\nparis2024.list_participants()\nparis2024.simulate_event()\nparis2024.simulate_event()\nparis2024.show_event_results()\nparis2024.show_ranking()"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/python/neslarra.py",
    "content": "\"\"\"\n EJERCICIO:\n ¡Los JJOO de París 2024 han comenzado!\n Crea un programa que simule la celebración de los juegos.\n El programa debe permitir al usuario registrar eventos y participantes,\n realizar la simulación de los eventos asignando posiciones de manera aleatoria\n y generar un informe final <=>> por terminal.\n Requisitos:\n 1. Registrar eventos deportivos.\n 2. Registrar participantes por nombre y país.\n 3. Simular eventos de manera aleatoria en base a los participantes (mínimo 3).\n 4. Asignar medallas (oro, plata y bronce) basándose en el resultado del evento.\n 5. Mostrar los ganadores por cada evento.\n 6. Mostrar el ranking de países según el número de medallas.\n Acciones:\n 1. Registro de eventos.\n 2. Registro de participantes.\n 3. Simulación de eventos.\n 4. Creación de informes.\n 5. Salir del programa.\n\"\"\"\n\n\nclass Athlete:\n\n    def __init__(self, name: str, country: str, game: str, participation: str):\n        self.name = name\n        self.country = country\n        self.game = game\n        self.participation = participation\n\n    def get_name(self):\n        return self.name\n\n    def get_country(self):\n        return self.country\n\n\nclass Game:\n\n    def __init__(self, game: dict):\n        self.name = game[\"name\"]\n        self.members = game[\"members\"]\n        self.competitors_team = dict()\n        self.medals_team = {\"gold\": \"\", \"silver\": \"\", \"bronze\": \"\"}\n        self.scores_team = dict()\n        self.competitors_individual = dict()\n        self.medals_individual = {\"gold\": \"\", \"silver\": \"\", \"bronze\": \"\"}\n        self.scores_individual = dict()\n\n    def add_competitor(self, athlete: Athlete):\n        if athlete.participation == \"Team\":\n            self.add_competitors_team(athlete)\n        else:\n            self.add_competitors_individual(athlete)\n\n    def add_competitors_team(self, athlete: Athlete):\n        if athlete.country in self.competitors_team.keys():\n            self.competitors_team[athlete.country].append(athlete)\n        else:\n            self.competitors_team[athlete.country] = [athlete]\n\n    def set_scores_team(self, country: str, score: float):\n        self.scores_team[country] = score\n\n    def set_medals_team(self):\n        positions = list(sorted(self.scores_team.items(), key=lambda x: x[1], reverse=True))\n        self.medals_team[\"gold\"] = positions[0][0]\n        self.medals_team[\"silver\"] = positions[1][0]\n        self.medals_team[\"bronze\"] = positions[2][0]\n\n    def add_competitors_individual(self, athlete: Athlete):\n        if athlete.country in self.competitors_individual.keys():\n            self.competitors_individual[athlete.country].append(athlete)\n        else:\n            self.competitors_individual[athlete.country] = [athlete]\n\n    def set_scores_individual(self, athlete: str, score: float):\n        self.scores_individual[athlete] = score\n\n    def set_medals_individual(self):\n        positions = list(sorted(self.scores_individual.items(), key=lambda x: x[1], reverse=True))\n        self.medals_individual[\"gold\"] = positions[0][0]\n        self.medals_individual[\"silver\"] = positions[1][0]\n        self.medals_individual[\"bronze\"] = positions[2][0]\n\n\ndef get_valid_name() -> str:\n    import requests\n    api_names_url = \"https://randomuser.me/api/\"\n    lower_letters = list(map(chr, range(ord(\"a\"), ord(\"z\") + 1)))\n\n    while True:\n        req = requests.get(api_names_url)\n        data = req.json()\n        firstname = data[\"results\"][0][\"name\"][\"first\"]\n        lastname = data[\"results\"][0][\"name\"][\"last\"]\n        if all([c.lower() in lower_letters for c in firstname + lastname]):  # evitar otros alfabetos\n            break\n    return firstname + \" \" + lastname\n\n\ndef load_games(games: list, countries: list):\n    x = 0\n    print(\"Cargando 504 atletas...\")\n    for game in games:\n        for country in countries:\n            for participation_type in (\"Individual\", \"Team\"):\n                if participation_type == \"Individual\":\n                    members = 1\n                else:\n                    members = game.members\n                for i in range(0, members):\n                    x += 1\n                    if x % 3 == 0:\n                        print(f\"\\b\\b\\b\\b---{x}>\", end=\"\")\n                    if x % 60 == 0:\n                        print(\"\")\n                    name = get_valid_name()\n                    athlete = Athlete(name, country, game.name, participation_type)\n                    game.add_competitor(athlete)\n    print(f\"\\b\\b\\b\\b---{x}>\")\n\n\ndef competition(game: Game):\n    from random import uniform\n    get_scores = lambda x: list(map(lambda a: uniform(13, 16).__round__(3), range(0, x)))\n    get_media = lambda x: sum(x) / x.__len__()\n\n    for country in game.competitors_team.keys():\n        scores = get_scores(game.members)\n        media = get_media(scores)\n        game.set_scores_team(country, media)\n\n    for athlete in game.competitors_individual.values():\n        scores = get_scores(1)\n        media = get_media(scores)\n        game.set_scores_individual(athlete[0], media)\n\n\ndef game_report(game: Game):\n    print(f\"\\n{game.name}\")\n    print(\"\\tIndividual\")\n    for medal, athlete in game.medals_individual.items():\n        print(f\"\\t\\t{medal} {athlete.get_name()} / {athlete.get_country()}\")\n    print(\"\\tTeams\")\n    for medal, country in game.medals_team.items():\n        print(f\"\\t\\t{medal} {country}\")\n\n\ndef final_report(games: list):\n    countries_score = {}\n    t = 0\n    g = 0\n    s = 0\n    b = 0\n    for game in games:\n        for medal, athlete in game.medals_individual.items():\n            if athlete.get_country() not in countries_score.keys():\n                countries_score[athlete.get_country()] = {\"total\": 0, \"gold\": 0, \"silver\": 0, \"bronze\": 0}\n            countries_score[athlete.get_country()][\"total\"] += 1\n            if medal == \"gold\":\n                countries_score[athlete.get_country()][\"gold\"] += 1\n            elif medal == \"silver\":\n                countries_score[athlete.get_country()][\"silver\"] += 1\n            else:\n                countries_score[athlete.get_country()][\"bronze\"] += 1\n        for medal, country in game.medals_team.items():\n            if country not in countries_score.keys():\n                countries_score[country] = {\"total\": 0, \"gold\": 0, \"silver\": 0, \"bronze\": 0}\n            countries_score[country][\"total\"] += 1\n            if medal == \"gold\":\n                countries_score[country][\"gold\"] += 1\n            elif medal == \"silver\":\n                countries_score[country][\"silver\"] += 1\n            else:\n                countries_score[country][\"bronze\"] += 1\n    lista_paises = []\n    for y in countries_score.items():\n        lista_paises.append({\"country\": y[0], \"gold\": y[1][\"gold\"], \"silver\": y[1][\"silver\"], \"bronze\": y[1][\"bronze\"], \"total\": y[1][\"total\"]})\n    lista_paises = sorted(lista_paises, key=lambda k: (-k[\"gold\"], -k[\"silver\"], -k[\"bronze\"], -k[\"total\"], k[\"country\"]))\n\n    for c in lista_paises:\n        print(f\"{c['country']}: Gold {c['gold']} / Plata {c['silver']} / Bronze {c['bronze']} <=> TOTAL {c['total']}\")\n\n\ngames = []\nfor game in [{\"name\": \"Shoot\", \"members\": 2}, {\"name\": \"Archery\", \"members\":  4}, {\"name\": \"Swim\", \"members\":  4}, {\"name\": \"Gymnastic\", \"members\":  6},\n             {\"name\": \"Tennis\", \"members\":  2}, {\"name\": \"Judo\", \"members\":  4}, {\"name\": \"Fencing\", \"members\":  4}, {\"name\": \"Table Tennis\", \"members\":  2}]:\n    games.append(Game(game))\n\ncountries = ['AIM', 'Argelia', 'Argentina', 'Brasil', 'Canada', 'China', 'Corea', 'EEUU', 'Egipto', 'España', 'Jamaica', 'Japón', 'México', 'Sudáfrica']\n\nload_games(games, countries)\n\nfor game in games:\n    competition(game)\n    game.set_medals_individual()\n    game.set_medals_team()\n    game_report(game)\nprint(\"\\n Ranking Final\\n\")\nfinal_report(games)\n\nr\"\"\"\nLa salida es algo así:\n\nCargando 504 atletas...\n--------------------------------------60>\n-----------------------------------------------120>\n------------------------------------------------------------180>\n------------------------------------------------------------240>\n------------------------------------------------------------300>\n------------------------------------------------------------360>\n------------------------------------------------------------420>\n------------------------------------------------------------480>\n---------------------------504>\n\nShoot\n\tIndividual\n\t\tgold Farah Fossmo / España\n\t\tsilver Stefania Nikolaus / Argelia\n\t\tbronze Joachim Hubert / Japón\n\tTeams\n\t\tgold EEUU\n\t\tsilver España\n\t\tbronze Canada\n\nArchery\n\tIndividual\n\t\tgold Flurin Chevalier / Japón\n\t\tsilver Waldtraut Wedekind / México\n\t\tbronze Amelia Matthews / Argelia\n\tTeams\n\t\tgold Argentina\n\t\tsilver Egipto\n\t\tbronze EEUU\n\nSwim\n\tIndividual\n\t\tgold Sabrin Paulsrud / Egipto\n\t\tsilver Archie Thomas / Jamaica\n\t\tbronze Franco Broeren / Argentina\n\tTeams\n\t\tgold Argelia\n\t\tsilver Jamaica\n\t\tbronze Sudáfrica\n\nGymnastic\n\tIndividual\n\t\tgold Patsy Fisher / China\n\t\tsilver Calvin Peters / AIM\n\t\tbronze Freya Molnes / España\n\tTeams\n\t\tgold México\n\t\tsilver AIM\n\t\tbronze Jamaica\n\nTennis\n\tIndividual\n\t\tgold Signe Hansen / AIM\n\t\tsilver Taliana Castro / Brasil\n\t\tbronze Aaron Blanc / Jamaica\n\tTeams\n\t\tgold EEUU\n\t\tsilver Jamaica\n\t\tbronze Egipto\n\nJudo\n\tIndividual\n\t\tgold Storm Johansen / AIM\n\t\tsilver Maelya Colin / China\n\t\tbronze Valerij Hartwich / Argentina\n\tTeams\n\t\tgold Japón\n\t\tsilver Argelia\n\t\tbronze Sudáfrica\n\nFencing\n\tIndividual\n\t\tgold Clayton Nelson / Brasil\n\t\tsilver Prathiksha Manjunath / Egipto\n\t\tbronze Juho Halko / Argelia\n\tTeams\n\t\tgold Canada\n\t\tsilver Egipto\n\t\tbronze Argentina\n\nTable Tennis\n\tIndividual\n\t\tgold Ajinkya Manjunath / Argentina\n\t\tsilver Jagat Adiga / AIM\n\t\tbronze Aapo Kuusisto / Brasil\n\tTeams\n\t\tgold Japón\n\t\tsilver España\n\t\tbronze Argelia\n\nRanking Final:\n\nJapón: Gold 3 / Plata 0 / Bronze 1 <=> TOTAL 4\nAIM: Gold 2 / Plata 3 / Bronze 0 <=> TOTAL 5\nArgentina: Gold 2 / Plata 0 / Bronze 3 <=> TOTAL 5\nEEUU: Gold 2 / Plata 0 / Bronze 1 <=> TOTAL 3\nEgipto: Gold 1 / Plata 3 / Bronze 1 <=> TOTAL 5\nArgelia: Gold 1 / Plata 2 / Bronze 3 <=> TOTAL 6\nEspaña: Gold 1 / Plata 2 / Bronze 1 <=> TOTAL 4\nBrasil: Gold 1 / Plata 1 / Bronze 1 <=> TOTAL 3\nChina: Gold 1 / Plata 1 / Bronze 0 <=> TOTAL 2\nMéxico: Gold 1 / Plata 1 / Bronze 0 <=> TOTAL 2\nCanada: Gold 1 / Plata 0 / Bronze 1 <=> TOTAL 2\nJamaica: Gold 0 / Plata 3 / Bronze 2 <=> TOTAL 5\nSudáfrica: Gold 0 / Plata 0 / Bronze 2 <=> TOTAL 2\n\"\"\"\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/python/nlarrea.py",
    "content": "\"\"\"\n * EJERCICIO:\n * ¡Los JJOO de París 2024 han comenzado!\n * Crea un programa que simule la celebración de los juegos.\n * El programa debe permitir al usuario registrar eventos y participantes,\n * realizar la simulación de los eventos asignando posiciones de manera aleatoria\n * y generar un informe final. Todo ello por terminal.\n * Requisitos:\n * 1. Registrar eventos deportivos.\n * 2. Registrar participantes por nombre y país.\n * 3. Simular eventos de manera aleatoria en base a los participantes (mínimo 3).\n * 4. Asignar medallas (oro, plata y bronce) basándose en el resultado del evento.\n * 5. Mostrar los ganadores por cada evento.\n * 6. Mostrar el ranking de países según el número de medallas.\n * Acciones:\n * 1. Registro de eventos.\n * 2. Registro de participantes.\n * 3. Simulación de eventos.\n * 4. Creación de informes.\n * 5. Salir del programa.\n\"\"\"\n\nimport random\nfrom typing import Literal\n\n\nclass Participant:\n    def __init__(self, name: str, country: str):\n        self.name = name\n        self.country = country\n\n    def __eq__(self, other: object) -> bool:\n        \"\"\"Indicates to the Participant class when two instances are equals.\n\n        Parameters\n        ----------\n        other : object\n            The second object with which the current instance must be compared.\n\n        Returns\n        -------\n        bool\n            Whether the both objects are equals.\n        \"\"\"\n\n        if isinstance(other, Participant):\n            return self.name == other.name and self.country == other.country\n\n        return False\n\n    def __hash__(self) -> int:\n        return hash(self.name, self.country)\n\n\nclass Olympics:\n    def __init__(self):\n        self.events: list[str] = []\n        self.participants: dict[str, list[Participant]] = dict()\n        self.results: dict[\n            str, dict[Literal[\"gold\", \"silver\", \"bronze\"], Participant]\n        ] = dict()\n        self.countries: dict[\n            str, dict[Literal[\"gold\", \"silver\", \"bronze\"], int]\n        ] = dict()\n\n    def add_event(self):\n        \"\"\"Asks the user for an event name and adds it to the events list if it\n        didn't exist already.\"\"\"\n\n        event: str = input(\"Introducer el nombre del evento:\\n > \").strip()\n\n        if event in self.events:\n            print(f\"El evento '{event}' ya ha sido añadido anteriormente.\")\n        else:\n            self.events.append(event)\n            print(f\"El evento '{event}' ha sido añadido.\")\n\n    def add_participant(self):\n        \"\"\"Asks the user for the name and the country of a participant. If\n        there are not events yet, it won't be possible to add a participant. A\n        participant can't be added to the same event twice.\"\"\"\n\n        if not self.events:\n            print(\n                \"No existen eventos todavía. Espera a que haya alguno para inscribirte!\"\n            )\n            return\n\n        # Get participant's information\n        name: str = input(\"Introduce el nombre del participante:\\n > \").strip()\n        country: str = input(\n            \"Introduce el país del participante:\\n > \"\n        ).strip()\n        participant: Participant = Participant(name, country)\n\n        # Register the participant in an event\n        event_choice: int = menu(\n            options=self.events,\n            prompt=\"Selecciona en qué evento deseas participar: \",\n        )\n        event: str = self.events[event_choice]\n\n        if (\n            event in self.participants\n            and participant in self.participants[event]\n        ):\n            print(\n                f\"El participante {name} de {country} ya está registrado en el evento deportivo {event}.\"\n            )\n        else:\n            if event not in self.participants:\n                self.participants[event] = []\n\n            self.participants[event].append(participant)\n            print(\n                f\"El participante {name} de {country} se ha registrado en {event}.\"\n            )\n\n    def simulate(self):\n        \"\"\"Simulates the games by picking the gold, silver and bronze\n        participants and updates the results.\"\"\"\n\n        if not self.events:\n            print(\"Aún no hay eventos registrados.\")\n\n        for event in self.events:\n            if (\n                event not in self.participants\n                or len(self.participants[event]) < 3\n            ):\n                print(\n                    f\"No hay participantes suficientes para simular el evento {event}.\"\n                )\n                continue\n\n            # Get Golden, Silver and Bronze randomly\n            event_participants: list[Participant] = random.sample(\n                self.participants[event], 3\n            )\n            random.shuffle(event_participants)\n\n            gold, silver, bronze = event_participants\n            winners = {\n                \"gold\": gold,\n                \"silver\": silver,\n                \"bronze\": bronze,\n            }\n            self.results[event] = winners\n\n            # Update each country's medal counter\n            self._update_country_results(gold.country, \"gold\")\n            self._update_country_results(silver.country, \"silver\")\n            self._update_country_results(bronze.country, \"bronze\")\n\n            self._print_results(event, winners)\n\n    def write_summary(self):\n        \"\"\"Prints a summary of the results into the console.\"\"\"\n\n        print(\"\\nINFORME DE LOS JJOO\")\n        print(\"-------------------\\n\")\n\n        if not self.results:\n            print(\"No hay resultados registrados.\")\n        else:\n            for event, winners in self.results.items():\n                self._print_results(event, winners)\n\n        if not self.countries:\n            print(\"No hay medallas por país registradas.\")\n        else:\n            for country, medals in self.countries.items():\n                print(f\"{country}:\")\n                print(f\"  {medals['gold']} Oro\")\n                print(f\"  {medals['silver']} Plata\")\n                print(f\"  {medals['bronze']} Bronce\")\n\n    def _update_country_results(\n        self, country: str, medal: Literal[\"gold\", \"silver\", \"bronze\"]\n    ):\n        \"\"\"Updates the countries' medal quantities.\n\n        Parameters\n        ----------\n        country : str\n            The name of the country.\n        medal : Literal[\"gold\", \"silver\", \"bronze\"]\n            The type of medal the country has won.\n        \"\"\"\n\n        if not country in self.countries:\n            self.countries[country] = {\"gold\": 0, \"silver\": 0, \"bronze\": 0}\n\n        self.countries[country][medal] += 1\n\n    def _print_results(\n        self,\n        event: str,\n        winners: dict[Literal[\"gold\", \"silver\", \"bronze\"], Participant],\n    ):\n        \"\"\"Prints the received results, showing the event name and who are the\n        winners of it.\n\n        Parameters\n        ----------\n        event : str\n            The event name.\n        winners : dict[Literal[\"gold\", \"silver\", \"bronze\"], Participant]\n            The winners' names and countries.\n        \"\"\"\n\n        print(f\"RESULTADOS DEL EVENTO:\", event)\n        print(f\"Oro: {winners['gold'].name} ({winners['gold'].country})\")\n        print(f\"Plata: {winners['silver'].name} ({winners['silver'].country})\")\n        print(\n            f\"Bronce: {winners['bronze'].name} ({winners['bronze'].country})\"\n        )\n\n\ndef menu(\n    options: list[str], prompt: str = \"Selecciona qué quieres hacer: \"\n) -> int:\n    \"\"\"Prints a sequence of options and asks the user to choose one of them.\n\n    Parameters\n    ----------\n    options : list[str]\n        A list that contains the available options.\n\n    Returns\n    -------\n    int\n        The index of the selected option.\n    \"\"\"\n\n    while True:\n        print(\"\\nMENÚ DE OPCIONES\")\n        print(\"----------------\")\n        for index, option in enumerate(options):\n            print(f\"{index + 1}. {option}\")\n\n        try:\n            chosen: str = input(prompt)\n            assert chosen.isnumeric()\n        except:\n            print(f\"Debes introducir un número entre [1-{len(options)}]!\")\n        else:\n            chosen: int = int(chosen)\n            if chosen >= 1 and chosen <= len(options):\n                print()\n                return chosen - 1  # chosen option's index\n\n\nif __name__ == \"__main__\":\n    OPTIONS: list[str] = [\n        \"Registro de eventos\",\n        \"Registro de participantes\",\n        \"Simulación de eventos\",\n        \"Creación de informes\",\n        \"Salir del programa\",\n    ]\n    jjoo = Olympics()\n\n    while True:\n        chosen_option: int = menu(OPTIONS)\n\n        if chosen_option == 0:\n            jjoo.add_event()\n        elif chosen_option == 1:\n            jjoo.add_participant()\n        elif chosen_option == 2:\n            jjoo.simulate()\n        elif chosen_option == 3:\n            jjoo.write_summary()\n        elif chosen_option == 4:\n            print(\"Saliendo del programa...\")\n            break\n        else:\n            print(\"Opción no válida.\")\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/python/oriaj3.py",
    "content": "\"\"\"\n30 - SIMULADOR JUEGOS OLÍMPICOS\nAutor de la solución: oriaj3\n \n EJERCICIO:\n ¡Los JJOO de París 2024 han comenzado!\n Crea un programa que simule la celebración de los juegos.\n El programa debe permitir al usuario registrar eventos y participantes,\n realizar la simulación de los eventos asignando posiciones de manera aleatoria\n y generar un informe final. Todo ello por terminal.\n Requisitos:\n 1. Registrar eventos deportivos.\n 2. Registrar participantes por nombre y país.\n 3. Simular eventos de manera aleatoria en base a los participantes (mínimo 3).\n 4. Asignar medallas (oro, plata y bronce) basándose en el resultado del evento.\n 5. Mostrar los ganadores por cada evento.\n 6. Mostrar el ranking de países según el número de medallas.\n Acciones:\n 1. Registro de eventos.\n 2. Registro de participantes.\n 3. Simulación de eventos.\n 4. Creación de informes.\n 5. Salir del programa.\n */\n\"\"\"\nimport random\n\nclass Pais:\n    name: str\n    medallas: dict[str, int]\n\n    def __init__(self, name: str)-> None:\n        self.name = name\n        self.medallas = {\"Oro\": 0, \"Plata\": 0, \"Bronce\": 0}\n    \n    def __hash__(self)-> int:\n        return hash(self.name)\n    \n    def __eq__(self, other: \"Pais\"):\n        return self.name == other.name\n    \n    def get_total_medallas(self)-> int:\n        total = self.medallas[\"Oro\"] + self.medallas[\"Plata\"] + self.medallas[\"Bronce\"]\n        return total\n    \n    def __str__(self)-> str:\n        return f\"{self.name} - O: {self.medallas['Oro']} P: {self.medallas['Plata']} B: {self.medallas['Bronce']}\"\n    \nclass Participante:\n    name: str\n    country: Pais\n\n    def __init__(self, name: str, country: Pais)-> None:\n        self.name = name\n        self.country = country\n    \n    def __hash__(self)-> int:\n        # Genera un valor hash basado en el nombre del participante + el country\n        return hash(self.name + self.country.name)\n    \n    def __eq__(self, other)-> bool:\n        # Compara dos participantes basándose en su nombre y país\n        return self.name == other.name and self.country == other.country\n    \nclass Evento: \n    name: str\n    resultados: dict[Participante, int]\n    \n    def __init__(self, name: str, participantes: list[Participante]):\n        self.name=name\n        self.resultados = {}\n        if(len(participantes)>= 3):\n            self.participantes = participantes\n            for participante in participantes:\n                self.resultados[participante] = 0 #self.resultados = {participante: 0 for participante in participantes}\n        else:\n            raise (\"Los eventos deben tener mínimo 3 participantes\")\n    \n    def simular(self)-> None:\n        set_resultados = set()\n        for participante in self.participantes:\n            resultado = random.randint(0, 100)\n            # Generar un nuevo resultado si ya está en el conjunto\n            while resultado in set_resultados:\n                resultado = random.randint(0, 100)\n            # Agregar el resultado al conjunto y al diccionario\n            set_resultados.add(resultado)\n            self.resultados[participante] = resultado\n            \n        #Ordena los resultados\n        self.resultados = sorted(self.resultados.items(), key=lambda x: x[1], reverse=True)\n        \n        medallas = [\"Oro\", \"Plata\", \"Bronce\"]\n        for i in range(3):\n            self.resultados[i][0].country.medallas[medallas[i]] += 1\n            \n                        \n\n    def ranking(self)-> None:\n        posicion=0\n        for resultado in self.resultados:\n            print(f\"{posicion+1} - {resultado[0].name} ({resultado[0].country.name}): {resultado[1]}\")\n            posicion+=1\n        \n    def get_ganadores(self)-> list[tuple[Participante, int]]:\n        return self.resultados[:3]\n\nclass Olimpiadas:\n    eventos: list[Evento]\n    paises: list[Pais]\n    participantes: list[Participante]\n\n    def __init__(self)-> None:\n        self.eventos = []\n        self.paises = []\n        self.participantes = []\n    \n    def registrar_pais(self, name: str)-> None:\n        if name not in [pais.name for pais in self.paises]:\n            self.paises.append(Pais(name))\n    \n    def registrar_participante(self, name: str, country: Pais)-> None:\n        if country not in self.paises:\n            raise ValueError(\"El país no está registrado\")\n        elif name not in [participante.name for participante in self.participantes]:\n            for pais in self.paises:\n                if pais.name == country.name:\n                    self.participantes.append(Participante(name, pais))\n        else:\n            raise ValueError(\"El participante ya está registrado\")\n        \n    def registrar_evento(self, name: str, participantes: list[Participante])-> None:\n        if len(participantes) < 3:\n            raise ValueError(\"Los eventos deben tener mínimo 3 participantes\")\n        elif name not in [evento.name for evento in self.eventos]:\n            self.eventos.append(Evento(name, participantes))\n        else:\n            raise ValueError(\"El evento ya está registrado\")   \n        \n    def ordenar_paises_por_medallas(self)-> list[Pais]:\n        # Ordena los países utilizando una clave que considera primero el oro, luego la plata, y finalmente el bronce\n        paises_ordenados = sorted(self.paises, key=lambda pais: (pais.medallas[\"Oro\"], pais.medallas[\"Plata\"], pais.medallas[\"Bronce\"]), reverse=True)\n        return paises_ordenados\n    \n    def iniciar_olimpiadas(self)-> None:\n        self.paises.append(Pais(\"Jamaica\")) #0\n        self.paises.append(Pais(\"USA\"))     #1\n        self.paises.append(Pais(\"España\"))  #2\n        self.paises.append(Pais(\"Francia\")) #3\n        self.paises.append(Pais(\"Alemania\"))#4    \n        self.paises.append(Pais(\"China\"))   #5\n                \n        # 100 metros planos\n        self.participantes.append(Participante(\"Usain Bolt\", self.paises[0]))  # Jamaica\n        self.participantes.append(Participante(\"Carl Lewis\", self.paises[1]))  # USA\n        self.participantes.append(Participante(\"Bruno Hortelano\", self.paises[2]))  # España\n        self.participantes.append(Participante(\"Christophe Lemaitre\", self.paises[3]))  # Francia\n        self.participantes.append(Participante(\"Julian Reus\", self.paises[4]))  # Alemania\n        self.participantes.append(Participante(\"Su Bingtian\", self.paises[5]))  # China\n        #Registrar evento\n        self.eventos.append(Evento(\"100m\", self.participantes[-6:])) # Selecciona los últimos 6 participantes\n\n        # Tiro con arco\n        self.participantes.append(Participante(\"Dwayne McKenzie\", self.paises[0]))  # Jamaica (Nombre ficticio)\n        self.participantes.append(Participante(\"Brady Ellison\", self.paises[1]))  # USA\n        self.participantes.append(Participante(\"Miguel Alvariño\", self.paises[2]))  # España\n        self.participantes.append(Participante(\"Jean-Charles Valladont\", self.paises[3]))  # Francia\n        self.participantes.append(Participante(\"Florian Unruh\", self.paises[4]))  # Alemania\n        self.participantes.append(Participante(\"Xing Yu\", self.paises[5]))  # China\n        # Registrar evento\n        self.eventos.append(Evento(\"Tiro con arco\", self.participantes[-6:]))  # Selecciona los últimos 6 participantes\n\n        # Natación - 200 metros estilo libre\n        self.participantes.append(Participante(\"Michael Phelps\", self.paises[1]))  # USA\n        self.participantes.append(Participante(\"Ryan Lochte\", self.paises[1]))  # USA\n        self.participantes.append(Participante(\"Mireia Belmonte\", self.paises[2]))  # España\n        self.participantes.append(Participante(\"Yannick Agnel\", self.paises[3]))  # Francia\n        self.participantes.append(Participante(\"Paul Biedermann\", self.paises[4]))  # Alemania\n        self.participantes.append(Participante(\"Sun Yang\", self.paises[5]))  # China\n        # Registrar evento\n        self.eventos.append(Evento(\"Natacion\", self.participantes[-6:]))  # Selecciona los últimos 6 participantes\n\n        # Esgrima - Florete individual\n        self.participantes.append(Participante(\"Aliona Edwards\", self.paises[0]))  # Jamaica (Nombre ficticio)\n        self.participantes.append(Participante(\"Mariel Zagunis\", self.paises[1]))  # USA\n        self.participantes.append(Participante(\"Carlos Llavador\", self.paises[2]))  # España\n        self.participantes.append(Participante(\"Ysaora Thibus\", self.paises[3]))  # Francia\n        self.participantes.append(Participante(\"Peter Joppich\", self.paises[4]))  # Alemania\n        self.participantes.append(Participante(\"Lei Sheng\", self.paises[5]))  # China\n        # Registrar evento\n        self.eventos.append(Evento(\"Esgrima\", self.participantes[-6:]))  # Selecciona los últimos 6 participantes\n\n        # Gimnasia artística - Final de suelo\n        self.participantes.append(Participante(\"Simone Biles\", self.paises[1]))  # USA\n        self.participantes.append(Participante(\"Nadia Comăneci\", self.paises[1]))  # USA (originalmente de Rumanía, pero dejémoslo para ejemplo)\n        self.participantes.append(Participante(\"Rayderley Zapata\", self.paises[2]))  # España\n        self.participantes.append(Participante(\"Samir Aït Saïd\", self.paises[3]))  # Francia\n        self.participantes.append(Participante(\"Fabian Hambüchen\", self.paises[4]))  # Alemania\n        self.participantes.append(Participante(\"Liu Yang\", self.paises[5]))  # China\n        # Registrar evento\n        self.eventos.append(Evento(\"Gimnasia\", self.participantes[-6:]))\n        \n        #Lista los eventos\n        print(\"Eventos registrados:\")\n        for evento in self.eventos:\n            print(evento.name)\n            \n        #Simula los eventos\n        print(\"\\nSimulación de eventos:\")\n        for evento in self.eventos:\n            print(f\"\\n{evento.name}\")\n            evento.simular()\n            evento.ranking()\n        \n        #Muestra el ranking de países\n        print(\"\\nRanking de países:\")\n        self.paises = self.ordenar_paises_por_medallas()\n        for pais in self.paises:\n            print(f\"{pais.name}: Oro {pais.medallas['Oro']}, Plata {pais.medallas['Plata']}, Bronce {pais.medallas['Bronce']}\")\n\n#Creo una instancia de las olimpiadas y las inicio\nolimpiadas = Olimpiadas()\nolimpiadas.iniciar_olimpiadas()\n\ninput(\"Presiona una tecla para iniciar el menú...\")\n\n#Función para limpiar la pantalla\nimport os\ndef clear_screen():\n    os.system('cls' if os.name == 'nt' else 'clear')\n\n#Funciones auxiliares para mostrar el menú y sus opciones\nfrom enum import Enum\n\nclass MenuOpciones(Enum):\n    REGISTRAR_PAIS = 1\n    REGISTRAR_PARTICIPANTE = 2\n    REGISTRAR_EVENTO = 3\n    SIMULAR_EVENTOS = 4\n    MOSTRAR_RANKING_PAISES = 5\n    MOSTRAR_RESULTADO_EVENTO = 7\n    SALIR = 9\n\ndef mostrar_menu()-> None:\n    for opcion in MenuOpciones:\n        print(f\"{opcion.value}. {opcion.name.replace('_', ' ').capitalize()}\")\n    print(\"\")\n\ndef mostrar_participantes(participantes: list[Participante])-> None:\n    clear_screen()\n    print(\"Participantes disponibles:\")\n    for i, participante in enumerate(participantes, 1):\n        print(f\"{i}. {participante.name} ({participante.country.name})\")\n\ndef seleccionar_participantes(olimpiadas: Olimpiadas, num_participantes:int =3) -> list[Participante]:\n    participantes_seleccionados = []\n    while len(participantes_seleccionados) < num_participantes:\n        mostrar_participantes(olimpiadas.participantes)\n        try:\n            indice = int(input(f\"Seleccione el participante {len(participantes_seleccionados) + 1} (número): \")) - 1\n            if 0 <= indice < len(olimpiadas.participantes):\n                participante = olimpiadas.participantes[indice]\n                if participante not in participantes_seleccionados:\n                    participantes_seleccionados.append(participante)\n                    print(f\"Seleccionado: {participante.name}\")\n                else:\n                    print(\"Este participante ya ha sido seleccionado. Por favor, elija otro.\")\n            else:\n                print(\"Número de participante no válido. Intente de nuevo.\")\n        except ValueError:\n            print(\"Por favor, ingrese un número válido.\")\n    \n    return participantes_seleccionados\n\n\nwhile(True):\n    #Borro la pantalla\n    clear_screen()\n    mostrar_menu()\n    \n    #Pido la opción\n    try:\n        opcion = MenuOpciones(int(input(\"Seleccione una opción: \")))\n    except ValueError:\n        print(\"Opción no válida. Por favor, intente de nuevo.\")\n        input(\"Presione Enter para continuar...\")\n        continue\n    \n    match opcion:\n        case MenuOpciones.REGISTRAR_PAIS:\n            try:\n                nombre_pais = input(\"Ingrese el nombre del país: \")\n                olimpiadas.registrar_pais(nombre_pais)\n            except ValueError as e:\n                print(e)\n        case MenuOpciones.REGISTRAR_PARTICIPANTE:\n            try:\n                nombre_participante = input(\"Ingrese el nombre del participante: \")\n                nombre_pais = input(\"Ingrese el nombre del país: \")\n                pais = Pais(nombre_pais)\n                olimpiadas.registrar_participante(nombre_participante, pais)\n            except ValueError as e:\n                print(e)\n        case MenuOpciones.REGISTRAR_EVENTO:\n            try:\n                nombre_evento = input(\"Ingrese el nombre del evento: \")\n                participantes = seleccionar_participantes(olimpiadas)\n                olimpiadas.registrar_evento(nombre_evento, participantes)\n                print(f\"Evento '{nombre_evento}' registrado con éxito con los siguientes participantes:\")\n                for p in participantes:\n                    print(f\"- {p.name} ({p.country.name})\")\n            except ValueError as e:\n                print(f\"Error al registrar el evento: {e}\")\n            input(\"Presione Enter para continuar...\")\n        case MenuOpciones.SIMULAR_EVENTOS:\n            print(\"\\nSimulación de eventos:\")\n            for evento in olimpiadas.eventos:\n                print(f\"\\n{evento.name}\")\n            evento_sel = input(\"Seleccione el evento a simular: \")\n            for evento in olimpiadas.eventos:\n                if evento.name == evento_sel:\n                    print(f\"\\n{evento.name}\")\n                    evento.simular()\n                    evento.ranking()\n                    input(\"Presiona una tecla para continuar...\")\n        case MenuOpciones.MOSTRAR_RANKING_PAISES:\n            print(\"\\nRanking de países:\")\n            olimpiadas.paises = olimpiadas.ordenar_paises_por_medallas()\n            for pais in olimpiadas.paises:\n                print(f\"{pais.name}: Oro {pais.medallas['Oro']}, Plata {pais.medallas['Plata']}, Bronce {pais.medallas['Bronce']}\")\n            input(\"Presiona una tecla para continuar...\")\n        case MenuOpciones.MOSTRAR_RESULTADO_EVENTO:\n            print(\"\\nResultados de eventos:\")\n            for evento in olimpiadas.eventos:\n                print(f\"\\n{evento.name}\")\n            \n            evento_sel = input(\"Seleccione el evento a mostrar:\")   \n            for evento in olimpiadas.eventos:\n                if evento.name == evento_sel:\n                    print(f\"\\n{evento.name}\")\n                    evento.ranking()\n            input(\"Presiona una tecla para continuar...\")\n        \n        case MenuOpciones.SALIR:\n            break"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/python/pyramsd.py",
    "content": "from enum import Enum\nimport random\n\neventos = []\n\nclass Pais(Enum):\n    ESPANA = \"SP\"\n    FRANCIA = \"FR\"\n    ELEMANIA = \"GR\"\n    ITALIA = \"IT\"\n    PERU = \"PE\"\n    INGLATERRA = \"EN\"\n\nclass Participante:\n    def __init__(self, nombre: str, pais: Pais) -> None:\n        self.nombre = nombre\n        self.pais = pais\n\nclass Evento:\n    oro: Participante\n    plata: Participante\n    bronce: Participante\n\n    def __init__(self, nombre: str):\n        self.nombre = nombre\n        self.participantes = []\n        self.oro = None\n        self.plata = None\n        self.bronce = None\n\n    def simulacion(self):\n        random.shuffle(self.participantes)\n        if len(self.participantes) >= 3:\n            self.oro = self.participantes[0]\n            self.plata = self.participantes[1]\n            self.bronce = self.participantes[2]\n        else:\n            print(\"El número de participantes insuficiente\")\n\n\ndef ganadores(evento: Evento):\n    print(f\"\\n| {evento.nombre} |\")\n    try:\n        print(f\"*** Gold: {evento.oro.nombre} - {evento.oro.pais}\")\n        print(f\"** Silver: {evento.plata.nombre} - {evento.plata.pais}\")\n        print(f\"* Bronze: {evento.bronce.nombre} - {evento.bronce.pais}\")\n    except Exception as e:\n        print(e)\n        print(\"No hay resultados\")\n\n\ndef ranking_paises():\n    paises = {}\n\n    for pais in Pais:\n        paises[pais.name] = 0\n\n    for evento in eventos:\n        try:\n            for medalla in [evento.oro, evento.plata, evento.bronce]:\n                if medalla:\n                    match medalla.pais:\n                        case 'IT':\n                            paises['ITALIA'] += 1\n                        case 'SP':\n                            paises['ESPANA'] += 1\n                        case 'FR':\n                            paises['FRANCIA'] += 1\n                        case 'EN':\n                            paises['INGLATERRA'] += 1\n                        case 'GER':\n                            paises['ALEMANIA'] += 1\n                        case 'PE':\n                            paises['PERU'] += 1\n        except Exception as e:\n            print(\"No hay pruebas aún\\n\")\n\n    for pais, points in paises.items():\n        print(f\"{pais}: {points} puntos\")\n\n\ndef registro_evento():\n    nombre = input(\"\\nNombre del evento: \")\n    nuevo_evento = Evento(nombre=nombre)\n    eventos.append(nuevo_evento)\n\n\ndef registro_participante():\n    nombre = input(\"\\nNombre del participante: \")\n    pais = input(\"País del participante (SP, FR, GER, EN, IT, PE): \")\n    print(\"Prueba en la que participa: \")\n\n    for evento in eventos:\n        print(f\"- {evento.nombre}\")\n\n    selected_event = input(\"> \")\n\n    new_participant = Participante(nombre, pais)\n\n    if pais == \"SP\" or pais == \"FR\" or pais == \"GER\" or pais == \"EN\" or pais == \"IT\" or pais == \"PE\":\n\n        found = False\n\n        for evento in eventos:\n            if evento.nombre == selected_event:\n                evento.participantes.append(new_participant)\n                found = True\n                break\n\n        if not found:\n            print(\"Prueba no encontrada\")\n        else:\n            print(\"Participante añadido correctamente\")\n    else:\n        print(\"País erróneo\")\n\n\ndef reporte():\n    print(\"\\n---------------\")\n    print(\"|   Winners   |\")\n    print(\"---------------\")\n\n    for evento in eventos:\n        ganadores(evento)\n\n    print(\"\\n---------------------\")\n    print(\"|   Country ranking   |\")\n    print(\" ---------------------\")\n\n    ranking_paises()\n\n\ndef main():\n    quit = False\n\n    while not quit:\n        print(\"\\nSelecciona una opción:\")\n        print(\"1. Registro de eventos\\n\"\n              \"2. Registro de participantes\\n\"\n              \"3. Simulación de eventos\\n\"\n              \"4. Creación de informes\\n\"\n              \"5. Salir del programa\")\n\n        option = input(\"> \")\n\n        match option:\n            case \"1\":\n                registro_evento()\n            case \"2\":\n                registro_participante()\n            case \"3\":\n                for evento in eventos:\n                    evento.simulacion()\n                print(\"Simulación completada\")\n            case \"4\":\n                reporte()\n            case \"5\":\n                quit = True\n            case _:\n                print(\"Opción no válida\")\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/python/rantamhack.py",
    "content": "\n\n'''\n * EJERCICIO:\n * ¡Los JJOO de Pari­s 2024 han comenzado!\n * Crea un programa que simule la celebración de los juegos.\n * El programa debe permitir al usuario registrar eventos y participantes,\n * realizar la simulación de los eventos asignando posiciones de manera aleatoria\n * y generar un informe final. Todo ello por terminal.\n * Requisitos:\n * 1. Registrar eventos deportivos.\n * 2. Registrar participantes por nombre y paí­s.\n * 3. Simular eventos de manera aleatoria en base a los participantes (má­nimo 3).\n * 4. Asignar medallas (oro, plata y bronce) basándose en el resultado del evento.\n * 5. Mostrar los ganadores por cada evento.\n * 6. Mostrar el ranking de países según el número de medallas.\n * Acciones:\n * 1. Registro de eventos.\n * 2. Registro de participantes.\n * 3. Simulación de eventos.\n * 4. Creación de informes.\n * 5. Salir del programa.\n'''\n\nimport random\n\n\nclass Event:\n    def __init__(self, name):\n        self.name = name\n        self.participants = []\n        \n    def add_participant(self, participant):\n        self.participants.append(participant)\n        \n        \nclass Participants:\n    def __init__(self, name, country):\n        self.name = name\n        self.country = country\n        \n        \n        \nclass SimulateEvent:\n    def __init__(self, events, results):\n        self.events = events\n        self.results = results\n    \n    def simulate(self):\n        for event in self.events:\n            random.shuffle(event.participants)\n            self.results[event.name] = event.participants[:3]  \n            \n            \nclass Report:\n    def __init__(self, results):\n        self.results = results\n    \n    def create_report(self):\n        for event, winners in self.results.items():\n            print(f\"Evento:  {event}\")\n            medals = [\"Gold\", \"Silver\", \"Bronze\"]\n            for i, winner in enumerate(winners):\n                print(f\"{medals[i]}: {winner.name} ({winner.country})\")\n\n\nclass OlympiceGames:\n    def __init__(self):      \n        self.events = []\n        self.participants = []\n        self.results = {}\n        \n    def register_event(self, event_name):\n        event = Event(event_name)\n        if event_name not in [e.name for e in self.events]:\n            self.events.append(event)\n        else:\n            print(\"El evento ya está registrado\")\n            \n    def register_participant(self, name, country, event_name):\n        participant = Participants(name, country)\n        self.participants.append(participant)\n        for event in self.events:\n            if event.name ==  event_name:\n                event.add_participant(participant)\n            break  \n        else:\n            print(\"El evento no está registrado\")\n\n    def simulate_events(self):  \n        simulator = SimulateEvent(self.events, self.results)\n        simulator.simulate()  \n        \n    def generate_report(self):\n        report = Report(self.results)\n        report.create_report()                       \n    \n    def show_menu(self):\n        while True:\n            print(\"\\nMenu: \")\n            print(\"\\n\\t1. Registrar Evento\")\n            print(\"\\n\\t2. Registrar Participante\")\n            print(\"\\n\\t3. Simular Evento\")\n            print(\"\\n\\t4. Generar informe\")\n            print(\"\\n\\t5. Salir\")\n            print(\"\\n\\t6. Mostrar eventos y participantes guardados\")\n             \n            option = input(\"\\n\\tSeleccione una opción del menú: \") \n            \n            if option == \"1\":\n                event_name = input(\"Pon el nombre del nuevo evento: \")\n                self.register_event(event_name)\n                \n            elif option == \"2\":\n                name = input(\"Escriba el nombre del participante: \")\n                country = input(\"Escriba el pais al que pertenece el nuevo participante: \")\n                event_name = input(\"Escriba el nombre del evento en el que desea inscribirse: \")\n                self.register_participant(name, country, event_name)\n                    \n            elif option == \"3\":\n                self.simulate_events()\n                \n            elif option == \"4\":\n                self.generate_report()\n                \n            elif option == \"5\":\n                break\n            \n            elif option == \"6\":\n                print(\"\\nEventos guardados:\")\n                for event in self.events:\n                    print(f\"{event.name}\")\n\n                print(\"\\nParticipantes guardados: \")\n                for participant in self.participants:\n                    print(f\" {participant.name} ({participant.country})\")\n\n            else:\n                print(\"Opcion incorrecta, por favor elige una opcion entre la 1 y la 6\")   \n            \n            \nparis2024 = OlympiceGames()\nparis2024.show_menu()          \n            \n    \n        \n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/python/raulG91.py",
    "content": "from random import sample\nclass Participant:\n    def __init__(self,name:str,country:str):\n        self.name = name.lower()\n        self.country = country.lower()\n    def getName(self):\n        return self.name\n    def getCountry(self):\n        return self.country    \nclass Event:\n    def __init__(self,name:str):\n        self.name = name.lower()\n        self.participants = []\n        self.winners = []\n        \n    def getName(self):\n        return self.name\n    def getParticipants(self):\n        return self.participants    \n    def addParticipant(self,participant:Participant):\n        self.participants.append(participant)\n    def simulateWinners(self):\n        if len(self.participants) < 3:\n            print(\"We need at least 3 participant\")    \n        else:\n            #Get 3 random participants, Gold, silver and bronze\n            self.winners = sample(self.participants,k=3)\n    def getWinners(self):\n        return self.winners        \n    def printWinners(self):\n        if len(self.winners) > 0:\n            print(f'Gold medal: {self.winners[0].getName()} nationality: {self.winners[0].getCountry()}')\n            print(f'Silver medal: {self.winners[1].getName()} nationality: {self.winners[1].getCountry()}')\n            print(f'Bronze medal: {self.winners[2].getName()} nationality: {self.winners[2].getCountry()}')\n        else:\n            print(\"Event not simulated yet\")\n\n\nclass JJOO: \n    def __init__(self):\n        self.competitions = []\n    def addCompetition(self,competition:Event):\n        self.competitions.append(competition)\n    def getCompetitionByName(self,name)->Event:\n        found = False\n        for element in self.competitions:\n            if element.getName() == name:\n                found = True\n                return element\n        if not(found):\n            return None\n    def getStats(self):\n        countryMedals = {}\n\n        for competition in self.competitions:\n            winners = competition.getWinners()\n            for winner in winners:\n                if countryMedals.__contains__(winner.getCountry()):\n                    countryMedals[winner.getCountry()] += 1\n                else:\n                    countryMedals[winner.getCountry()]  =  1    \n        return countryMedals \nparis = JJOO()\n\nwhile(True):\n    print(\" Press 1 to add an event\")\n    print(\" Press 2 to add participant to event\")\n    print(\" Press 3 to simulate an event\")\n    print(\" Press 4 to create reports\")\n    print(\" Press 5 to exit the program\")\n\n    option = int(input())\n\n    if option == 1:\n        print(\"Enter event game\")\n        name = str(input())\n        if not(paris.getCompetitionByName(name)):\n            event = Event(name)\n            paris.addCompetition(event)\n        else: \n            print(\"Event already exist\")    \n    elif option == 2:\n        print(\"Enter event name to add participant \")\n        name = str(input())\n        event = paris.getCompetitionByName(name)\n        if event:\n            print(\"Enter participant name \")\n            participant_name = str(input())\n            print(\"Enter participant country \")\n            particpant_nationality = str(input())\n            participant = Participant(participant_name,particpant_nationality)\n            event.addParticipant(participant)\n        else:\n            print(\"Event doesn't exist\")\n    elif option == 3:\n        print(\"Enter event name to simulate \")\n        name = str(input())\n        event = paris.getCompetitionByName(name)\n        if event:\n            event.simulateWinners()\n            winners = event.printWinners()\n\n        else:\n            print(\"Event doesn' exist\")\n    elif option == 4:\n        print(paris.getStats())\n    elif option == 5: \n        break"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/python/raynerpv2022.py",
    "content": "# # # /*\n# # #  * EJERCICIO:\n# # #  * ¡Los JJOO de París 2024 han comenzado!\n# # #  * Crea un programa que simule la celebración de los juegos.\n# # #  * El programa debe permitir al usuario registrar eventos y participantes,\n# # #  * realizar la simulación de los eventos asignando posiciones de manera aleatoria\n# # #  * y generar un informe final. Todo ello por terminal.\n# # #  * Requisitos:\n# # #  * 1. Registrar eventos deportivos.\n# # #  * 2. Registrar participantes por nombre y país.\n# # #  * 3. Simular eventos de manera aleatoria en base a los participantes (mínimo 3).\n# # #  * 4. Asignar medallas (oro, plata y bronce) basándose en el resultado del evento.\n# # #  * 5. Mostrar los ganadores por cada evento.\n# # #  * 6. Mostrar el ranking de países según el número de medallas.\n# # #  * Acciones:\n# # #  * 1. Registro de eventos.\n# # #  * 2. Registro de participantes.\n# # #  * 3. Simulación de eventos.\n# # #  * 4. Creación de informes.\n# # #  * 5. Salir del programa.\n# # #  */\n\n\n# Importación de módulos necesarios\nfrom abc import ABC, abstractmethod  # Para clases abstractas\nfrom types import SimpleNamespace    # Para crear objetos dinámicos\nimport random                       # Para simulación aleatoria\n\n# Clase que contiene datos iniciales de atletas y eventos\nclass VirtualDatos(ABC):\n    pass\n\nclass Datos(VirtualDatos):\n    # Lista de atletas predefinidos (nombre, país)\n    def __init__(self, atleta, evento):\n        self._atleta = atleta\n        self._event = evento\n\n# Clase fábrica para creación de objetos\nclass VirtualFabrica(ABC):\n    @classmethod\n    @abstractmethod\n    def crear_evento(cls, *nombres):\n        pass\n    \n    @classmethod\n    @abstractmethod\n    def crear_atleta(cls, *datos):\n        pass\n    \nclass Fabrica(VirtualFabrica):\n    @classmethod\n    def crear_evento(cls, *nombres):\n        \"\"\"\n        Crea eventos deportivos a partir de nombres\n        Args:\n            *nombres: Nombres de los eventos a crear\n        Returns:\n            Lista de objetos CEventoDeportivo\n        \"\"\"\n        instancia = SimpleNamespace()  # Objeto dinámico para almacenar eventos\n        result = []                   # Lista de resultados\n        \n        for n in nombres:\n            inst = CEventoDeportivo(n)  # Crea instancia de evento\n            setattr(instancia, n, inst) # Asigna al namespace\n            result.append(inst)         # Agrega a la lista\n        return result\n\n    @classmethod\n    def crear_atleta(cls, *datos):\n        \"\"\"\n        Crea participantes (atletas) a partir de datos\n        Args:\n            *datos: Tuplas con (nombre, país)\n        Returns:\n            Lista de objetos CParticipante\n        \"\"\"\n        instancia = SimpleNamespace()  # Objeto dinámico para almacenar atletas\n        result = []                   # Lista de resultados\n        \n        for d in datos:\n            inst = CParticipante(*d)  # Crea instancia de participante\n            nombre = d[0]             # Obtiene nombre\n            setattr(instancia, nombre, inst)  # Asigna al namespace\n            result.append(inst)        # Agrega a la lista\n        return result\n\n# INTERFACES ABSTRACTAS ------------------------------------------------------\n\n# Interfaz para atletas\nclass VirtualAtleth(ABC):\n    @abstractmethod\n    def __init__(self, name: str, country: str):\n        \"\"\"Inicializa un atleta con nombre y país\"\"\"\n        pass\n\n# Interfaz para medallero\nclass VirtualMedallero(ABC):\n    @abstractmethod\n    def __init__(self):\n        \"\"\"Inicializa el medallero\"\"\"\n        pass\n       \n    @abstractmethod\n    def asignar_medallas(self, resultado: list[VirtualAtleth]):\n        \"\"\"Asigna medallas basado en resultados\"\"\"\n        pass\n        \n    @abstractmethod\n    def mostrar_medallero(self):\n        \"\"\"Muestra el medallero por países\"\"\"\n        pass\n\n# Interfaz para eventos deportivos\nclass VirtualEventoDeportivo(ABC): \n    @abstractmethod\n    def __init__(self, name: str):\n        \"\"\"Inicializa evento con nombre\"\"\"\n        pass\n        \n    @abstractmethod\n    def agregar_participante(self, participante: VirtualAtleth):\n        \"\"\"Agrega participante al evento\"\"\"\n        pass\n        \n    @abstractmethod\n    def simular(self):\n        \"\"\"Simula la celebración del evento\"\"\"\n        pass\n\n# Interfaz para registro de eventos\nclass VirtualRegistroEventos(ABC):\n    @abstractmethod\n    def __init__(self):\n        \"\"\"Inicializa el registro\"\"\"\n        pass\n        \n    @abstractmethod\n    def get_eventos_registrados(self):\n        \"\"\"Obtiene lista de eventos registrados\"\"\"\n        pass\n        \n    @abstractmethod\n    def registrar_evento(self, evento: VirtualEventoDeportivo):\n        \"\"\"Registra un nuevo evento\"\"\"\n        pass\n        \n    @abstractmethod\n    def registrar_participante(self, evento: VirtualEventoDeportivo, \n                           atleta: VirtualAtleth, medallero: VirtualMedallero):\n        \"\"\"Registra participante en evento\"\"\"\n        pass\n\n# Interfaz para generación de informes\nclass VirtualInforme(ABC):\n    @abstractmethod\n    def mostrar_eventos_participantes(self, eventos_registrados: VirtualRegistroEventos):\n        \"\"\"Muestra eventos con sus participantes\"\"\"\n        pass\n        \n    @abstractmethod\n    def mostrar_ganadores(self, eventos_registrados: VirtualRegistroEventos):\n        \"\"\"Muestra ganadores por evento\"\"\"\n        pass\n\n# Interfaz para el gestor principal\nclass VirtualManagerOlimpicGames(ABC):\n    @abstractmethod \n    def __init__(self, fabrica: VirtualFabrica, datos:VirtualDatos,eventos_registrados: VirtualRegistroEventos,\n                medallero: VirtualMedallero, informe: VirtualInforme):\n        \"\"\"Inicializa el gestor con sus dependencias\"\"\"\n        pass\n    \n    # Métodos abstractos del gestor\n    @abstractmethod   \n    def crear_eventos(self):\n        \"\"\"Crea eventos iniciales\"\"\"\n        pass\n        \n    @abstractmethod \n    def crear_participantes(self):\n        \"\"\"Crea participantes iniciales\"\"\"\n        pass\n        \n    @abstractmethod \n    def caso_registro_eventos(self):\n        \"\"\"Caso de uso 1: registro de eventos\"\"\"\n        pass\n        \n    @abstractmethod \n    def caso_registro_participantes(self):\n        \"\"\"Caso de uso 2: registro de participantes\"\"\"\n        pass\n    \n    @abstractmethod   \n    def registrar_participante(self, evento: VirtualEventoDeportivo, \n                                atleta: VirtualAtleth):\n        \"\"\"Registra participante en evento\"\"\"\n        pass\n         \n    @abstractmethod\n    def registrar_evento(self, *evento):\n        \"\"\"Registra uno o más eventos\"\"\"\n        pass\n\n    @abstractmethod       \n    def mostrar_eventos_participantes(self):\n        \"\"\"Muestra eventos con participantes\"\"\"\n        pass\n          \n    @abstractmethod\n    def simular_eventos(self):\n        \"\"\"Simula todos los eventos registrados\"\"\"\n        pass\n        \n    @abstractmethod     \n    def mostrar_ganadores(self):\n        \"\"\"Muestra ganadores\"\"\"\n        pass\n        \n    @abstractmethod \n    def mostrar_medallero(self):\n        \"\"\"Muestra medallero\"\"\"\n        pass\n\n# IMPLEMENTACIONES CONCRETAS -------------------------------------------------\n\n# Implementación concreta de participante\nclass CParticipante(VirtualAtleth):\n    def __init__(self, name: str, country: str):\n        \"\"\"Inicializa participante con nombre y país\"\"\"\n        self.name = name      # Nombre del atleta\n        self.country = country  # País del atleta\n\n# Implementación concreta de medallero\nclass CMedallero(VirtualMedallero):\n    def __init__(self):\n        \"\"\"Inicializa medallero vacío\"\"\"\n        self.country = {}  # Diccionario {país: [oro, plata, bronce]}\n\n    def asignar_medallas(self, resultado: list[VirtualAtleth]):\n        \"\"\"\n        Asigna medallas basado en resultados\n        Args:\n            resultado: Lista ordenada de participantes (1° oro, 2° plata, 3° bronce)\n        \"\"\"\n        # Asigna medallas a los 3 primeros\n        self.country[resultado[0].country][0] += 1  # Oro\n        self.country[resultado[1].country][1] += 1  # Plata\n        self.country[resultado[2].country][2] += 1  # Bronce\n\n    def mostrar_medallero(self):\n        \"\"\"Muestra medallero ordenado por cantidad de medallas\"\"\"\n        print(\"Medallero Por Paises\\n\\n\")\n        # Ordena por total de medallas (descendente)\n        self.country = dict(sorted(self.country.items(), \n                                 key=lambda item: item[1], reverse=True))\n        # Imprime cada país con sus medallas\n        for c, m in self.country.items():\n            print(f\"{c}   Oro {m[0]} Plata {m[1]} Bronce {m[2]}\") \n\n# Implementación concreta de evento deportivo\nclass CEventoDeportivo(VirtualEventoDeportivo):  \n    def __init__(self, name: str):\n        \"\"\"Inicializa evento con nombre\"\"\"\n        self.name = name            # Nombre del evento\n        self.participantes = []     # Lista de participantes\n        self.result = []            # Resultados (no usado actualmente)\n        self.celebrado = False      # Estado del evento\n\n    def agregar_participante(self, participante: VirtualAtleth):\n        \"\"\"Agrega participante al evento\"\"\"\n        self.participantes.append(participante)\n          \n    def simular(self):\n        \"\"\"Simula el evento: mezcla participantes aleatoriamente\"\"\"\n        random.shuffle(self.participantes)  # Resultado aleatorio\n        print(f\"Evento {self.name} celebrado correctamente\")\n        self.celebrado = True  # Marca como celebrado\n\n# Implementación concreta de registro de eventos\nclass CRegistroEventos(VirtualRegistroEventos):\n    def __init__(self):\n        \"\"\"Inicializa registro vacío\"\"\"\n        self.eventos_deportivos_registrados = []  # Lista de eventos\n      \n    def get_eventos_registrados(self):\n        \"\"\"Obtiene lista de eventos registrados\"\"\"\n        return self.eventos_deportivos_registrados\n\n    def registrar_evento(self, evento: VirtualEventoDeportivo):\n        \"\"\"\n        Registra un nuevo evento\n        Args:\n            evento: Evento a registrar\n        \"\"\"\n        if evento.celebrado:\n            print(f\"Evento {evento.name} ya se ha celebrado, imposible agregarlo\")\n            return\n         \n        if evento in self.eventos_deportivos_registrados:\n            print(f\"Evento {evento.name} ya esta Registrado\")\n        else:\n            self.eventos_deportivos_registrados.append(evento)\n            print(f\"Evento {evento.name} registrado correctamente\")\n\n    def registrar_participante(self, evento: VirtualEventoDeportivo, \n                           atleta: VirtualAtleth, medallero: VirtualMedallero):\n        \"\"\"\n        Registra participante en evento\n        Args:\n            evento: Evento deportivo\n            atleta: Participante a registrar\n            medallero: Medallero para actualizar países\n        \"\"\"\n        if evento.celebrado:\n            print(f\"Evento {evento.name} ya se ha celebrado, imposible agregar participantes\")\n            return\n            \n        # Si el país no está en medallero, lo inicializa\n        if atleta.country not in medallero.country:\n            medallero.country[atleta.country] = [0, 0, 0]  # [Oro, Plata, Bronce]\n\n        if atleta in evento.participantes:\n            print(f\"Atleta {atleta.name} ya esta Registrado en evento {evento.name}\")\n        else:\n            evento.agregar_participante(atleta)\n            print(f\"Participante {atleta.name} Agregado al evento {evento.name} correctamente\")\n\n# Implementación concreta de informe\nclass CInforme(VirtualInforme):\n    def mostrar_eventos_participantes(self, eventos_registrados: VirtualRegistroEventos):\n        \"\"\"\n        Muestra eventos con sus participantes\n        Args:\n            eventos_registrados: Gestor de eventos registrados\n        \"\"\"\n        print(\"Eventos Registrados\\n\")\n        for evento in eventos_registrados.get_eventos_registrados():\n            print(f\"{evento.name} \", end=\"\")\n            for p in evento.participantes:\n                print(f\"{p.name} \", end=\"\")\n            print()  # Nueva línea\n\n    def mostrar_ganadores(self, eventos_registrados: VirtualRegistroEventos):\n        \"\"\"\n        Muestra ganadores por evento\n        Args:\n            eventos_registrados: Gestor de eventos registrados\n        \"\"\"\n        print(\"Ganadores por eventos\\n\")\n        for evento in eventos_registrados.get_eventos_registrados():\n            print(f\"{evento.name}  1 {evento.participantes[0].name}\")\n\n# Implementación concreta del gestor principal\nclass ManagerOlimpicGames(VirtualManagerOlimpicGames):\n    def __init__(self, fabrica: VirtualFabrica, datos: VirtualDatos, eventos_registrados: VirtualRegistroEventos,\n                medallero: VirtualMedallero, informe: VirtualInforme):\n        \"\"\"\n        Inicializa el gestor con sus dependencias\n        Args:\n            fabrica: Fábrica para crear objetos\n            eventos_registrados: Gestor de eventos\n            medallero: Medallero olímpico\n            informe: Generador de informes\n        \"\"\"\n        self.eventos_registrados = eventos_registrados\n        self.medallero = medallero\n        self.informe = informe\n        self.fabrica = fabrica\n        self.Datos = datos\n         \n    def crear_eventos(self):\n        \"\"\"Crea eventos usando datos predefinidos\"\"\"\n        return self.fabrica.crear_evento(*self.Datos._event)\n    \n    def registrar_evento(self, *eventos):\n        \"\"\"Registra uno o más eventos\"\"\"\n        for evento in eventos:\n            self.eventos_registrados.registrar_evento(evento)\n\n    def caso_registro_eventos(self):\n        \"\"\"Caso de uso 1: crea y registra eventos\"\"\"\n        eventos = self.crear_eventos()\n        self.registrar_evento(*eventos)\n        self.mostrar_eventos_participantes()\n\n    def caso_registro_participantes(self):\n        \"\"\"Caso de uso 2: registra participantes en todos los eventos\"\"\"\n        atletas = self.crear_participantes()\n                        \n        for evento in self.eventos_registrados.get_eventos_registrados():\n            for atleta in atletas:\n                self.registrar_participante(evento, atleta)\n        self.mostrar_eventos_participantes()\n\n    def crear_participantes(self):\n        \"\"\"Crea participantes usando datos predefinidos\"\"\"\n        return self.fabrica.crear_atleta(*self.Datos._atleta)\n          \n        \n    def registrar_participante(self, evento: VirtualEventoDeportivo, atleta: VirtualAtleth):\n        \"\"\"Registra participante en evento\"\"\"\n        self.eventos_registrados.registrar_participante(evento, atleta, self.medallero)\n\n    def mostrar_eventos_participantes(self):\n        \"\"\"Muestra eventos con participantes\"\"\"\n        self.informe.mostrar_eventos_participantes(self.eventos_registrados)\n          \n    def simular_eventos(self):\n        \"\"\"Simula todos los eventos registrados\"\"\"\n        for evento in self.eventos_registrados.eventos_deportivos_registrados:\n            if len(evento.participantes) < 3:\n                print(f\"Se necesitan minimo 3 participantes para celebrar el evento {evento.name}\")\n            else:\n                evento.simular()\n                self.medallero.asignar_medallas(evento.participantes)\n         \n    def mostrar_ganadores(self):\n        \"\"\"Muestra ganadores por evento\"\"\"\n        self.informe.mostrar_ganadores(self.eventos_registrados)\n        \n    def mostrar_medallero(self):\n        \"\"\"Muestra medallero por países\"\"\"\n        self.medallero.mostrar_medallero()\n\n# Clase para menú de usuario\nclass MenuUsuario:\n    def __init__(self):\n        \"\"\"Inicializa menú con opción por defecto 0\"\"\"\n        self.option = 0\n      \n    def validar_entrada(self) -> bool:\n        \"\"\"\n        Valida entrada numérica del usuario\n        Returns:\n            True si es válida, False si no\n        \"\"\"\n        try:\n            self.option = int(input())\n        except ValueError:\n            print(\"Debe teclear un numero\\n\")\n            return False\n        else:\n            return True\n                    \n    def menu_principal(self, MOG: VirtualManagerOlimpicGames):\n        \"\"\"\n        Muestra y gestiona menú principal\n        Args:\n            MOG: Gestor olímpico principal\n        \"\"\"\n        print(\"Olimpic Simulator\\n\")\n\n        while True:\n            print(\"1. Registrar eventos deportivos.\")\n            print(\"2. Registrar participantes por nombre y país.\")\n            print(\"3. Simular eventos deportivos.\")\n            print(\"4. Creacion de Informe.\")\n            print(\"5. Salir del simulador\")\n\n            if not self.validar_entrada():\n                continue\n            else:\n                match self.option:\n                    case 1:  # Registrar eventos\n                        MOG.caso_registro_eventos()\n                    case 2:  # Registrar participantes\n                        MOG.caso_registro_participantes()\n                    case 3:  # Simular eventos\n                        MOG.simular_eventos()\n                        MOG.mostrar_eventos_participantes()\n                    case 4:  # Generar informe\n                        MOG.mostrar_ganadores()\n                        MOG.mostrar_medallero()\n                    case 5:  # Salir\n                        break\n                    case _:  # Opción inválida\n                        print(\"Debe teclear un numero entre 1 y 7\\n\")\n\n# INICIALIZACIÓN Y EJECUCIÓN -------------------------------------------------\n\n# Creación de instancias principales\nmedallero = CMedallero()                     # Medallero olímpico\nregistro_eventos = CRegistroEventos()        # Registro de eventos\ninforme = CInforme()                         # Generador de informes\nfabrica = Fabrica()                          # Fábrica de objetos\n\natleta = [(\"pepe\", \"Cuba\"), (\"ricardo\",\"Spain\"), (\"federico\", \"France\"), \n              (\"vanessa\", \"Japon\"), (\"mijain\",\"Rusia\")]\n   \nevento = [\"Atletismo\", \"Boxeo\", \"Natacion\", \"Ciclismo\"]\ndatos = Datos(atleta, evento)\n# Creación del gestor principal con sus dependencias\nMOG = ManagerOlimpicGames(fabrica, datos, registro_eventos, medallero, informe)\n\n# Creación y ejecución del menú principal\nmenu_usuario = MenuUsuario()\nmenu_usuario.menu_principal(MOG)\n\n\n# Análisis SOLID Detallado (con foco en escalabilidad)\n# 1. ✅ Single Responsibility Principle (SRP) - 9.5/10\n\n# Puntos fuertes:\n\n#     Cada clase tiene una única razón para cambiar:\n\n#         CEventoDeportivo: Solo simula eventos.\n\n#         CMedallero: Solo gestiona medallas.\n\n#         ManagerOlimpicGames: Orquesta sin implementar lógica (👍 Correcto como coordinador).\n\n# Mejora posible:\n\n#     CRegistroEventos podría dividirse en:\n\n#         RegistroEventos (guardar eventos).\n\n#         RegistroParticipantes (añadir atletas).\n\n# Ejemplo de escalabilidad:\n# python\n\n# class RegistroParticipantes:\n#     def __init__(self, medallero: VirtualMedallero):\n#         self._medallero = medallero\n    \n#     def agregar(self, evento: VirtualEventoDeportivo, atleta: VirtualAtleth):\n#         if atleta.country not in self._medallero.country:\n#             self._medallero.country[atleta.country] = [0, 0, 0]\n#         evento.agregar_participante(atleta)\n\n# 2. ✅ Open/Closed Principle (OCP) - 8/10\n\n# Puntos fuertes:\n\n#     Interfaces como VirtualEventoDeportivo permiten añadir nuevos tipos de eventos sin modificar código existente.\n\n# Mejora posible:\n\n#     Usar Strategy Pattern para simulación:\n\n# python\n\n# class EstrategiaSimulacion(ABC):\n#     @abstractmethod\n#     def simular(self, participantes: list): pass\n\n# class SimulacionAleatoria(EstrategiaSimulacion):\n#     def simular(self, participantes): \n#         random.shuffle(participantes)\n\n# class SimulacionPorHabilidad(EstrategiaSimulacion):\n#     def simular(self, participantes):\n#         participantes.sort(key=lambda x: x.habilidad, reverse=True)\n\n# # En CEventoDeportivo:\n# def __init__(self, name: str, estrategia: EstrategiaSimulacion):\n#     self._estrategia = estrategia\n# def simular(self):\n#     self._estrategia.simular(self.participantes)\n\n# 3. ✅ Liskov Substitution (LSP) - 10/10\n\n# Puntos fuertes:\n\n#     Todas las subclases (CParticipante, CEventoDeportivo) pueden sustituir a sus padres sin romper el sistema.\n\n#     Ejemplo:\n#     python\n\n#     def prueba_lsp(atleta: VirtualAtleth):\n#         print(atleta.name)  # Funciona con cualquier implementación\n\n# 4. ✅ Interface Segregation (ISP) - 9/10\n\n# Puntos fuertes:\n\n#     Interfaces pequeñas (VirtualInforme solo tiene 2 métodos).\n\n#     Ejemplo de ISP bien aplicado:\n#     python\n\n#     class IReporteMedallas(ABC):\n#         @abstractmethod\n#         def generar_reporte_medallas(self): pass\n\n#     # Clases que no usen medallas no están obligadas a implementarlo.\n\n# Mejora:\n\n#     VirtualRegistroEventos podría dividirse en:\n\n#         IRegistroEventos (solo eventos).\n\n#         IRegistroParticipantes (solo atletas).\n\n# 5. ✅ Dependency Inversion (DIP) - 9/10\n\n# Puntos fuertes:\n\n#     ManagerOlimpicGames depende de abstracciones (VirtualFabrica, VirtualMedallero).\n\n#     Inyección de dependencias:\n#     python\n\n#     def __init__(self, fabrica: VirtualFabrica, medallero: VirtualMedallero, ...):\n#         self._fabrica = fabrica  # 👍 No depende de implementaciones concretas\n\n# Mejora:\n\n#     Usar inyección por constructor en todas las clases (evitar instanciar Fabrica() dentro de Manager).\n\n# 📊 Puntuación Final SOLID\n# Principio\tPuntuación (10)\tComentario\n# SRP\t9.5\tManager como orquestador es correcto. Algunas clases podrían dividirse.\n# OCP\t8.0\tStrategy Pattern mejoraría extensibilidad en simulación.\n# LSP\t10\tPerfecto: subtipos sustituibles.\n# ISP\t9.0\tInterfaces pequeñas, pero alguna podría dividirse.\n# DIP\t9.0\tAlto nivel de abstracción, pero hay oportunidades para más inyección.\n# Total\t9.1\tExcelente base, con espacio para patrones avanzados.\n# 🚀 Ejemplo de Escalabilidad\n\n# Contexto: Queremos añadir deportes con reglas de simulación diferentes (ej: Atletismo vs. Natación).\n# Solución con Patrones:\n# python\n\n# # 1. Strategy Pattern para simulación\n# class EstrategiaSimulacion(ABC):\n#     @abstractmethod\n#     def simular(self, participantes: list): pass\n\n# class SimulacionCarrera(EstrategiaSimulacion):\n#     def simular(self, participantes):\n#         # Lógica específica para carreras (ej: tiempo + habilidad)\n#         participantes.sort(key=lambda x: x.tiempo)\n\n# # 2. Factory Method para eventos\n# class FabricaEventosEspecificos(VirtualFabrica):\n#     def crear_evento(self, nombre: str) -> VirtualEventoDeportivo:\n#         if nombre == \"Natacion\":\n#             return CNatacion(nombre, SimulacionCarrera())\n#         elif nombre == \"Boxeo\":\n#             return CBoxeo(nombre, SimulacionPorGolpes())\n\n# # 3. Uso en el sistema\n# natacion = FabricaEventosEspecificos().crear_evento(\"Natacion\")\n# natacion.simular()  # Usa SimulacionCarrera\n\n# Beneficios:\n\n#     OCP: Añadir nuevos deportes no requiere modificar CEventoDeportivo.\n\n#     SRP: Cada estrategia maneja una única lógica.\n\n#     DIP: El alto nivel (Manager) no depende de detalles de simulación.\n\n# 🔧 Áreas Clave de Mejora\n\n#     Inyección de Dependencias:\n\n#         Mover la creación de Fabrica y otros componentes al main (fuera de Manager).\n\n#     Manejo de Errores:\n\n#         Usar excepciones personalizadas (EventoNoValidoError, ParticipanteDuplicadoError).\n\n#     Patrón Observer:\n\n#         Notificar cambios (ej: cuando un evento termina, actualizar UI o bases de datos).\n\n# python\n\n# # Ejemplo Observer\n# class Observador(ABC):\n#     @abstractmethod\n#     def actualizar(self, evento): pass\n\n# class LogObservador(Observador):\n#     def actualizar(self, evento):\n#         print(f\"Evento {evento.name} completado!\")\n\n# # En CEventoDeportivo:\n# def simular(self):\n#     random.shuffle(self.participantes)\n#     for observador in self._observadores:\n#         observador.actualizar(self)\n\n# 🎯 Conclusión Final\n\n# Tu diseño es robusto y bien estructurado, con un claro enfoque en SOLID. Para escalar:\n\n#     Patrones recomendados: Strategy, Factory Method, Observer.\n\n#     Inyección explícita: Delegar la creación de objetos al nivel más alto.\n\n#     Documentar extensiones: Usar type hints y docstrings para nuevas funcionalidades.\n\n# Puntuación final: 9.1/10 — ¡Excelente trabajo! 👏\n\n\n\n# *******************************\n\n# Análisis de POO del Simulador de JJOO\n\n# (Abstracción, Encapsulación, Herencia, Polimorfismo y Asociación)\n# 1. ✅ Abstracción (9/10)\n\n# Puntos fuertes:\n\n#     Interfaces claras (VirtualEventoDeportivo, VirtualAtleth) definen contratos bien estructurados.\n\n#     Clases abstractas (VirtualDatos, VirtualFabrica) establecen una base sólida para extensiones.\n\n#     Ejemplo destacado:\n#     python\n\n#     class VirtualEventoDeportivo(ABC):\n#         @abstractmethod\n#         def simular(self): pass  # Obliga a implementar lógica específica en subclases\n\n# Mejora:\n\n#     Añadir más métodos abstractos para comportamientos comunes (ej: validar_participantes() en VirtualEventoDeportivo).\n\n# 2. ✅ Encapsulación (8.5/10)\n\n# Puntos fuertes:\n\n#     Atributos como _atleta y _evento en Datos están protegidos.\n\n#     Métodos públicos bien definidos (ej: agregar_participante(), simular()).\n\n# Mejoras:\n\n#     Usar propiedades (@property) para atributos como participantes en CEventoDeportivo:\n#     python\n\n#     @property\n#     def participantes(self) -> list:\n#         return self._participantes  # Atributo privado _participantes\n\n#     Ejemplo de error: En CMedallero, self.country es un diccionario público (debería ser privado _country).\n\n# 3. ✅ Herencia (9/10)\n\n# Puntos fuertes:\n\n#     Jerarquía clara:\n\n#     VirtualAtleth (Padre)  \n#     └── CParticipante (Hijo)  \n\n#     Uso correcto de herencia para especialización (ej: VirtualFabrica → Fabrica).\n\n# Mejora:\n\n#     Evitar herencia múltiple si se escala (preferir composición).\n\n# 4. ⚠️ Polimorfismo (7.5/10)\n\n# Puntos fuertes:\n\n#     Métodos como simular() se implementan de forma distinta en cada evento (aunque actualmente todos usan random.shuffle).\n\n#     Ejemplo básico:\n#     python\n\n#     # Todos los eventos implementan simular()\n#     atletismo = CEventoDeportivo(\"Atletismo\")\n#     natacion = CEventoDeportivo(\"Natación\")\n#     atletismo.simular()  # Polimorfismo en acción\n#     natacion.simular()\n\n# Mejoras:\n\n#     Polimorfismo avanzado: Usar estrategias de simulación diferentes por deporte (como en el análisis SOLID con EstrategiaSimulacion).\n\n#     Ejemplo de mejora:\n#     python\n\n#     class CEventoNatacion(CEventoDeportivo):\n#         def simular(self):\n#             # Lógica específica para natación (ej: ordenar por tiempo)\n#             self.participantes.sort(key=lambda x: x.tiempo)\n\n# 5. ✅ Asociación/Composición (9/10)\n\n# Puntos fuertes:\n\n#     Composición fuerte: ManagerOlimpicGames usa CRegistroEventos, CMedallero, etc., sin heredar de ellos.\n\n#     Ejemplo clave:\n#     python\n\n#     class ManagerOlimpicGames:\n#         def __init__(self, registro: VirtualRegistroEventos, medallero: VirtualMedallero):\n#             self._registro = registro  # Composicion (Manager \"tiene un\" Registro)\n#             self._medallero = medallero\n\n# Mejora:\n\n#     Documentar relaciones claramente (ej: \"Un Manager tiene un Medallero\").\n\n# 📊 Puntuación Final POO\n# Concepto\tPuntuación (10)\tComentario\n# Abstracción\t9.0\tInterfaces sólidas, pero podrían ser más descriptivas.\n# Encapsulación\t8.5\tMayor uso de propiedades y atributos privados mejoraría.\n# Herencia\t9.0\tBien aplicada, sin abuso.\n# Polimorfismo\t7.5\tFuncional pero básico. Estrategias lo elevarían.\n# Asociación\t9.0\tComposiciones bien diseñadas.\n# Total\t8.6\tExcelente base con oportunidades para profundizar.\n# 🚀 Ejemplo de Escalabilidad con POO\n\n# Objetivo: Añadir deportes de equipo (ej: Fútbol) con comportamientos únicos.\n# Implementación con Polimorfismo y Composicón:\n# python\n\n# # 1. Nueva clase para equipos (Composición)\n# class CEquipo(VirtualAtleth):\n#     def __init__(self, nombre: str, pais: str, integrantes: list):\n#         super().__init__(nombre, pais)\n#         self._integrantes = integrantes  # Lista de CParticipante\n\n# # 2. Evento de equipo (Polimorfismo)\n# class CEventoEquipo(CEventoDeportivo):\n#     def simular(self):\n#         # Lógica específica para equipos (ej: suma de habilidades)\n#         self.participantes.sort(key=lambda equipo: sum(p.habilidad for p in equipo._integrantes))\n\n# # 3. Uso en el sistema\n# equipo1 = CEquipo(\"Argentina\", \"ARG\", [CParticipante(\"Messi\", \"ARG\"), ...])\n# futbol = CEventoEquipo(\"Fútbol\")\n# futbol.agregar_participante(equipo1)\n# futbol.simular()  # ¡Polimorfismo en acción!\n\n# Beneficios POO:\n\n#     Extensibilidad: Añadir nuevos tipos de eventos no rompe el código existente.\n\n#     Reutilización: CEquipo reutiliza VirtualAtleth pero con nueva funcionalidad.\n\n#     Mantenibilidad: Cada clase maneja su propia lógica.\n\n# 🔍 Recomendaciones Clave\n\n#     Patrón Strategy: Para variar algoritmos de simulación sin modificar clases.\n\n#     Properties: Proteger atributos críticos (ej: _participantes, _country).\n\n#     Type Hints: Mejorar documentación y autocompletado.\n#     python\n\n#     def agregar_participante(self, participante: VirtualAtleth) -> None: ...\n\n#     Exceptions: Personalizar errores (ej: EventoNoValidoError).\n\n# Puntuación final POO: 8.6/10 — ¡Buen diseño, listo para escalar! 🏆"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/python/rigo93acosta.py",
    "content": "'''\n/*\n * EJERCICIO:\n * ¡Los JJOO de París 2024 han comenzado!\n * Crea un programa que simule la celebración de los juegos.\n * El programa debe permitir al usuario registrar eventos y participantes,\n * realizar la simulación de los eventos asignando posiciones de manera aleatoria\n * y generar un informe final. Todo ello por terminal.\n * Requisitos:\n * 1. Registrar eventos deportivos.\n * 2. Registrar participantes por nombre y país.\n * 3. Simular eventos de manera aleatoria en base a los participantes (mínimo 3).\n * 4. Asignar medallas (oro, plata y bronce) basándose en el resultado del evento.\n * 5. Mostrar los ganadores por cada evento.\n * 6. Mostrar el ranking de países según el número de medallas.\n * Acciones:\n * 1. Registro de eventos.\n * 2. Registro de participantes.\n * 3. Simulación de eventos.\n * 4. Creación de informes.\n * 5. Salir del programa.\n */\n'''\nimport random\n\nclass Olympics:\n\n    def __init__(self) -> None:\n        \n        self.events: list = []\n        self.participants: dict = {}\n        self.results: dict = {}\n        self.country_medals: dict = {}\n\n    def register_event(self):\n        \n        event = input(\"Ingrese el nombre del evento: \").strip()\n\n        if event in self.events:\n            print(\"El evento ya se encuentra registrado.\")\n        else:\n            self.events.append(event)\n            print(f\"Evento {event} registrado con éxito.\")\n        \n\n    def register_participant(self):\n        \n        if not self.events:\n            print(\"No se han registrado eventos.\")\n            return\n        \n        name = input(\"Ingrese el nombre del participante: \").strip()\n        country = input(\"Ingrese el país del participante: \").strip()\n        participant = Participant(name, country)\n\n        print(\"Eventos registrados:\")\n        for index, event in enumerate(self.events):\n            print(f\"{index + 1}. {event}\")\n\n        event_choice = int(\n            input(\n                \"Seleccione el evento en el que participará: \"\n                )\n            )-1\n        \n        if event_choice >= 0 and event_choice < len(self.events):\n            event = self.events[event_choice]\n            if event in self.participants and participant in self.participants[event]:\n                print(f\"El participante {name} ya se encuentra registrado en el evento {event}.\")\n            else:\n                if event not in self.participants:\n                    self.participants[event] = []\n                self.participants[event].append(participant)\n                print(f\"Participante {name} de {country} registrado en el evento {event}.\")      \n        else:\n            print(\"Evento no válido.\")\n    \n    def simulate_event(self):\n        \n        if not self.events:\n            print(\"No se han registrado eventos.\")\n            return\n        \n        for event in self.events:\n            \n            if len(self.participants[event]) < 3:\n                print(f\"El evento {event} no cuenta con suficientes participantes (mínimo 3).\")\n                continue\n                        \n            if event in self.results: # Si el evento ya ha sido simulado no se vuelve a simular\n                print(f\"El evento {event} ya ha sido simulado.\")\n                continue\n\n            event_participant = random.sample(self.participants[event], 3)\n            random.shuffle(event_participant)\n            gold, silver, bronze = event_participant\n            self.results[event] = [gold, silver, bronze]\n                       \n            self.update_country_results(gold.country, \"gold\")\n            self.update_country_results(silver.country, \"silver\")\n            self.update_country_results(bronze.country, \"bronze\")\n\n            print(f\"Resultado simulación del evento: {event}.\")\n            print(f\"Oro: {gold.name} - {gold.country}\")\n            print(f\"Plata: {silver.name} - {silver.country}\")\n            print(f\"Bronce: {bronze.name} - {bronze.country}\")\n    \n    def update_country_results(self, country, medal):\n        if country not in self.country_medals:\n            self.country_medals[country] = {\"gold\": 0, \"silver\": 0, \"bronze\": 0}\n        self.country_medals[country][medal] += 1\n\n    def show_report(self):\n\n        print(\"Informe Juegos Olimpicos: \")\n        if self.results:\n            for event, winners in self.results.items():\n                print(f\"Evento: {event}.\")\n                print(f\"Oro: {winners[0].name} - {winners[0].country}\")\n                print(f\"Plata: {winners[1].name} - {winners[1].country}\")\n                print(f\"Bronce: {winners[2].name} - {winners[2].country}\")\n        else:\n            print(\"No hay resultados para mostrar.\")\n        \n        if self.country_medals:\n            print(\"Ranking de países:\")\n            sorted_countries = sorted(self.country_medals.items(), key=lambda x: (x[1][\"gold\"], x[1][\"silver\"], x[1][\"bronze\"]), reverse=True)\n            for country, medals in sorted_countries:\n                print(f\"{country}: {medals['gold']} oro, {medals['silver']} plata, {medals['bronze']} bronce.\")\n        else:\n            print(\"No hay países con medallas.\")\n\nclass Participant():\n\n    def __init__(self, name: str, country: str) -> None:\n        self.name = name\n        self.country = country\n\n    def __eq__(self, other: object) -> bool:\n        \n        if isinstance(other, Participant):\n            return self.name == other.name and self.country == other.country \n        return False\n\n    def __hash__(self) -> int:\n        return hash((self.name, self.country))\n    \nif __name__ == '__main__':\n\n    olympics = Olympics()\n\n    print(\"Simulación de Juegos Olímpicos\")\n    while True:\n\n        print(\"\"\"\n        1. Registro de eventos.\n        2. Registro de participantes.\n        3. Simulación de eventos.\n        4. Creación de informes.\n        5. Salir del programa.\n        \"\"\")\n\n        option = input(\"Seleccione una opción: \")\n\n        match option:\n            case \"1\":\n                olympics.register_event()\n            case \"2\":\n                olympics.register_participant()\n            case \"3\":\n                olympics.simulate_event()\n            case \"4\":\n                olympics.show_report()\n            case \"5\":\n                print(\"Saliendo del simulador...\")\n                break\n            case _:\n                print(\"Opción no válida, seleccione una opción del menú\")"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/python/santyjl.py",
    "content": "# #31 SIMULADOR JUEGOS OLÍMPICOS\n## Ejercicio\n\n\"\"\"\n/*\n * EJERCICIO:\n * ¡Los JJOO de París 2024 han comenzado!\n * Crea un programa que simule la celebración de los juegos.\n * El programa debe permitir al usuario registrar eventos y participantes,\n * realizar la simulación de los eventos asignando posiciones de manera aleatoria\n * y generar un informe final. Todo ello por terminal.\n * Requisitos:\n * 1. Registrar eventos deportivos.\n * 2. Registrar participantes por nombre y país.\n * 3. Simular eventos de manera aleatoria en base a los participantes (mínimo 3).\n * 4. Asignar medallas (oro, plata y bronce) basándose en el resultado del evento.\n * 5. Mostrar los ganadores por cada evento.\n * 6. Mostrar el ranking de países según el número de medallas.\n * Acciones:\n * 1. Registro de eventos.\n * 2. Registro de participantes.\n * 3. Simulación de eventos.\n * 4. Creación de informes.\n * 5. Salir del programa.\n */\n\"\"\"\n\nimport random\nimport time\n\n\n# Clase Registro\nclass Registro:\n    participantes: dict = {}\n\n    def __init__(self, nombre: str, pais: str):\n        self.nombre: str = nombre\n        self.pais: str = pais\n\n    def agregar_participantes(self):\n        self.participantes[self.nombre] = self.pais\n\n# Clase Evento\nclass Evento:\n    juegos: list = []\n\n    def __init__(self, nombre_evento: str):\n        self.nombre_evento = nombre_evento\n\n    def agregar_evento(self):\n        self.juegos.append(self.nombre_evento)\n\n# Clase Simulador\nclass Simulador:\n    def resultados(self, participantes: Registro) -> list:\n        # Obtenemos los participantes (nombres y países)\n        resultado: dict = participantes.participantes\n\n        # Mezclamos a los participantes para simular resultados\n        participantes_list = list(resultado.keys())  # Lista de nombres de personas\n        random.shuffle(participantes_list)  # Mezcla aleatoria de los participantes\n\n        # Mostramos los ganadores por persona (simulación)\n        print(f\"Ganadores del evento (persona): {participantes_list[:3]}\\n\")\n\n        # Retornamos los países de los ganadores\n        return [resultado[participante] for participante in participantes_list[:3]]\n\n# Clase Informes\nclass Informes:\n    medalla_oro: dict = {}\n    medalla_plata: dict = {}\n    medalla_bronce: dict = {}\n\n    def informe(self, pais: list):\n        # Asignamos medallas dependiendo de la cantidad de ganadores\n        if len(pais) >= 1:\n            if pais[0] in self.medalla_oro:\n                self.medalla_oro[pais[0]] += 1\n            else:\n                self.medalla_oro[pais[0]] = 1\n\n        if len(pais) >= 2:\n            if pais[1] in self.medalla_plata:\n                self.medalla_plata[pais[1]] += 1\n            else:\n                self.medalla_plata[pais[1]] = 1\n\n        if len(pais) >= 3:\n            if pais[2] in self.medalla_bronce:\n                self.medalla_bronce[pais[2]] += 1\n            else:\n                self.medalla_bronce[pais[2]] = 1\n\n    def mostrar_informe(self):\n        # Imprimir informe de medallas por país\n        print(\"*ORO*\")\n        for pais, cantidad in self.medalla_oro.items():\n            print(f\"{pais}: {cantidad} medallas de oro\")\n            time.sleep(0.2)\n\n        print(\"\\n*PLATA*\")\n        for pais, cantidad in self.medalla_plata.items():\n            print(f\"{pais}: {cantidad} medallas de plata\")\n            time.sleep(0.2)\n\n        print(\"\\n*BRONCE*\")\n        for pais, cantidad in self.medalla_bronce.items():\n            print(f\"{pais}: {cantidad} medallas de bronce\")\n            time.sleep(0.2)\n\n        print(\"\")\n\n\n# Simulación del proceso\nif __name__ == \"__main__\":\n    # Crear registro de participantes\n    registro1 = Registro(\"Juan\", \"Argentina\")\n    registro1.agregar_participantes()\n\n    registro2 = Registro(\"Pedro\", \"Brasil\")\n    registro2.agregar_participantes()\n\n    registro3 = Registro(\"Maria\", \"Colombia\")\n    registro3.agregar_participantes()\n\n    registro4 = Registro(\"Ana\", \"Chile\")\n    registro4.agregar_participantes()\n\n    registro5 = Registro(\"Luis\", \"Perú\")\n    registro5.agregar_participantes()\n\n    # Crear el informe para almacenar los resultados generales\n    informes = Informes()\n\n    # Lista de eventos con el número de ganadores en cada uno\n    eventos = [\"Natación\", \"Atletismo\", \"Gimnasia\",\"Velocidad\",\"Salto\"]\n\n    # Crear simulador de eventos\n    simulador = Simulador()\n\n    # Simular los resultados de cada evento\n    for nombre_evento in eventos:\n        evento = Evento(nombre_evento)\n        evento.agregar_evento()\n\n        print(f\"Simulando evento: {nombre_evento}\")\n        paises_ganadores = simulador.resultados(Registro)  # Obtiene los países ganadores\n\n        # Pasar los resultados de este evento al informe\n        informes.informe(paises_ganadores)\n        time.sleep(0.4)\n\n    # Mostrar informe final de medallas por país\n    informes.mostrar_informe()\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/python/sisaroot.py",
    "content": "# #31 SIMULADOR JUEGOS OLÍMPICOS - SisaRoot\n\nimport random\nfrom collections import defaultdict\n\n\ndef shuffle_participants(participants: list) -> list:\n    shuffled = participants[:]\n    random.shuffle(shuffled)\n    return shuffled\n\n\nclass OlympicSimulator:\n    def __init__(self):\n        self.events: dict[str, list[dict]] = {}\n        self.medal_table: dict[str, dict] = defaultdict(lambda: {\"gold\": 0, \"silver\": 0, \"bronze\": 0})\n        self.results: list[dict] = []\n\n    def register_event(self):\n        name = input(\"Nombre del evento: \").strip()\n        if not name:\n            print(\"Nombre inválido.\")\n            return\n        if name.lower() in (k.lower() for k in self.events):\n            print(f\"El evento '{name}' ya existe.\")\n            return\n        self.events[name] = []\n        print(f\"Evento '{name}' registrado.\")\n\n    def register_participant(self):\n        if not self.events:\n            print(\"No hay eventos registrados. Registra un evento primero.\")\n            return\n        print(\"Eventos disponibles:\")\n        event_names = list(self.events.keys())\n        for i, ev in enumerate(event_names, 1):\n            print(f\"  {i}. {ev}\")\n        try:\n            idx = int(input(\"Selecciona el número del evento: \").strip())\n            if not (1 <= idx <= len(event_names)):\n                raise ValueError\n        except ValueError:\n            print(\"Selección inválida.\")\n            return\n        event_name = event_names[idx - 1]\n        participant_name = input(\"Nombre del participante: \").strip()\n        country = input(\"País del participante: \").strip()\n        if not participant_name or not country:\n            print(\"Datos inválidos.\")\n            return\n        self.events[event_name].append({\"name\": participant_name, \"country\": country})\n        print(f\"Participante '{participant_name} ({country})' registrado en '{event_name}'.\")\n\n    def simulate_events(self):\n        if not self.events:\n            print(\"No hay eventos para simular.\")\n            return\n        self.results.clear()\n        for event_name, participants in self.events.items():\n            print(f\"\\n=== Simulando: {event_name} ===\")\n            if len(participants) < 3:\n                print(f\"  Necesita al menos 3 participantes (tiene {len(participants)}). Saltando.\")\n                continue\n            shuffled = shuffle_participants(participants)\n            gold   = shuffled[0]\n            silver = shuffled[1]\n            bronze = shuffled[2]\n            print(f\"  🥇 Oro:    {gold['name']} ({gold['country']})\")\n            print(f\"  🥈 Plata:  {silver['name']} ({silver['country']})\")\n            print(f\"  🥉 Bronce: {bronze['name']} ({bronze['country']})\")\n            self.medal_table[gold[\"country\"]][\"gold\"] += 1\n            self.medal_table[silver[\"country\"]][\"silver\"] += 1\n            self.medal_table[bronze[\"country\"]][\"bronze\"] += 1\n            self.results.append({\n                \"event\": event_name,\n                \"gold\": gold, \"silver\": silver, \"bronze\": bronze,\n            })\n\n    def show_report(self):\n        print(\"\\n\" + \"=\" * 50)\n        print(\"        INFORME FINAL — JJOO PARÍS 2024\")\n        print(\"=\" * 50)\n        if not self.results:\n            print(\"No se han simulado eventos aún.\")\n            return\n        print(\"\\n📋 GANADORES POR EVENTO:\")\n        for result in self.results:\n            print(f\"\\n  Evento: {result['event']}\")\n            print(f\"    🥇 {result['gold']['name']} ({result['gold']['country']})\")\n            print(f\"    🥈 {result['silver']['name']} ({result['silver']['country']})\")\n            print(f\"    🥉 {result['bronze']['name']} ({result['bronze']['country']})\")\n        print(\"\\n🏆 RANKING DE PAÍSES:\")\n        ranking = sorted(\n            self.medal_table.items(),\n            key=lambda x: (-x[1][\"gold\"], -x[1][\"silver\"], -x[1][\"bronze\"])\n        )\n        print(f\"{'Pos.':<5} {'País':<25} {'🥇':<6} {'🥈':<6} {'🥉':<6} {'Total':<6}\")\n        print(\"-\" * 58)\n        for pos, (country, medals) in enumerate(ranking, 1):\n            total = medals[\"gold\"] + medals[\"silver\"] + medals[\"bronze\"]\n            print(f\"{pos:<5} {country:<25} {medals['gold']:<6} {medals['silver']:<6} {medals['bronze']:<6} {total:<6}\")\n\n    def run(self):\n        menu = {\n            \"1\": (\"Registrar evento\",       self.register_event),\n            \"2\": (\"Registrar participante\", self.register_participant),\n            \"3\": (\"Simular eventos\",        self.simulate_events),\n            \"4\": (\"Ver informe final\",      self.show_report),\n            \"5\": (\"Salir\",                  None),\n        }\n        while True:\n            print(\"\\n====== SIMULADOR JJOO PARÍS 2024 ======\")\n            for key, (label, _) in menu.items():\n                print(f\"{key}. {label}\")\n            option = input(\"Selecciona una opción: \").strip()\n            if option == \"5\":\n                print(\"¡Hasta luego!\")\n                break\n            elif option in menu:\n                menu[option][1]()\n            else:\n                print(\"Opción no válida.\")\n\n\nif __name__ == \"__main__\":\n    OlympicSimulator().run()\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/rust/kenysdev.rs",
    "content": "/*\n╔═══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado                ║\n║ GitHub: https://github.com/Kenysdev   ║\n║ 2024 -  Rust                          ║\n╚═══════════════════════════════════════╝\n-----------------------------------------------------\n* SIMULADOR JUEGOS OLÍMPICOS\n-----------------------------------------------------\n\n* EJERCICIO:\n* ¡Los JJOO de París 2024 han comenzado!\n* Crea un programa que simule la celebración de los juegos.\n* El programa debe permitir al usuario registrar eventos y participantes,\n* realizar la simulación de los eventos asignando posiciones de manera aleatoria\n* y generar un informe final. Todo ello por terminal.\n * Requisitos:\n * 1. Registrar eventos deportivos.\n * 2. Registrar participantes por nombre y país.\n * 3. Simular eventos de manera aleatoria en base a los participantes (mínimo 3).\n * 4. Asignar medallas (oro, plata y bronce) basándose en el resultado del evento.\n * 5. Mostrar los ganadores por cada evento.\n * 6. Mostrar el ranking de países según el número de medallas.\n * Acciones:\n * 1. Registro de eventos.\n * 2. Registro de participantes.\n * 3. Simulación de eventos.\n * 4. Creación de informes.\n * 5. Salir del programa.\n*/\n\n// NOTA: Solo es un intento de practicar los principios SOLID. XD\n\n// ________________________________________________\nuse std::io::{self, Write};\nuse std::sync::{Arc, Mutex};\nuse std::collections::HashMap;\n\n// [dependencies]\n// rand = \"0.8.5\"\n// https://crates.io/crates/rand\nuse rand::prelude::*;\n\n// ________________________________________________\n// INTERFACES\n/// Contrato para acceder a constantes globales.\ntrait IGlobalConfig {\n    fn medals(&self) -> [&'static str; 3];\n    fn menu(&self) -> &'static str;\n}\n\n/// Contrato de métodos requeridos para una tabla de datos.\ntrait IDataTable<T> {\n    fn add(&mut self, item: T);\n    fn count(&self) -> usize;\n    fn get_list(&self) -> Vec<T>;\n}\n\n/// Contrato para implementar diferentes formas de almacenamiento de datos.\ntrait IData {\n    fn events_table(&mut self) -> &mut dyn IDataTable<String>;\n    fn participants_table(&mut self) -> &mut dyn IDataTable<(String, String, i32)>; // name, country, event_id \n    fn simulation_table( &mut self, //event_name, name, country, event_id, score, medal\n    ) -> &mut dyn IDataTable<Vec<(String, Vec<(String, String, i32, i32, String)>)>>; \n}\n\n/// Contrato sobre la entra de datos.\ntrait IInput {\n    fn get(&self, msg: &str) -> String;\n    fn get_int(&self, msg: &str) -> i32;\n}\n\n// ________________________________________________\n// CONTRATOS sobre la comunicación entre la interacción del usuario y la capa de datos.\ntrait IEvents { fn add(&self); }\n\ntrait IParticipants {\n    fn get_event_id(&self) -> i32;\n    fn add(&self);\n}\n\ntrait ISimulations { fn start(&self); }\n\ntrait IReports { fn generate(&self); }\n\n// ________________________________________________\n// IMPLEMENTAR CONTRATOS\nstruct GlobalConfig;\n\nimpl IGlobalConfig for GlobalConfig {\n    fn medals(&self) -> [&'static str; 3] {\n        static MEDALS: [&'static str; 3] = [\"🥇 Oro\", \"🥈 Plata\", \"🥉 Bronce\"];\n        MEDALS\n    }\n\n    fn menu(&self) -> &'static str {\n        r#\"\nSIMULADOR JUEGOS OLÍMPICOS:\n--------------------------------------------------\n| 1. Registrar evento        | 4. Crear informes |  \n| 2. Registrar participante  | 5. Salir          |\n| 3. Simulación de eventos   |                   |\n--------------------------------------------------\n\"#\n    }\n}\n\nstruct EventsTable {\n    dt: Vec<String>,\n}\n\nimpl EventsTable {\n    fn new() -> Self {\n        EventsTable { dt: Vec::new() }\n    }\n}\n\nimpl IDataTable<String> for EventsTable {\n    fn add(&mut self, sport: String) {\n        self.dt.push(sport);\n    }\n\n    fn count(&self) -> usize {\n        self.dt.len()\n    }\n\n    fn get_list(&self) -> Vec<String> {\n        self.dt.clone()\n    }\n}\n\n// _____________________\nstruct ParticipantsTable {\n    dt: Vec<(String, String, i32)>,\n}\n\nimpl ParticipantsTable {\n    fn new() -> Self {\n        ParticipantsTable { dt: Vec::new() }\n    }\n}\n\nimpl IDataTable<(String, String, i32)> for ParticipantsTable {\n    fn add(&mut self, participant: (String, String, i32)) {\n        self.dt.push(participant);\n    }\n\n    fn count(&self) -> usize {\n        self.dt.len()\n    }\n\n    fn get_list(&self) -> Vec<(String, String, i32)> {\n        self.dt.clone()\n    }\n}\n\n// _____________________\nstruct SimulationTable { // event_name, name, country, event_id, score, medal\n    dt: Vec<Vec<(String, Vec<(String, String, i32, i32, String)>)>>,\n}\n\nimpl SimulationTable {\n    fn new() -> Self {\n        SimulationTable { dt: Vec::new() }\n    }\n}\n\nimpl IDataTable<Vec<(String, Vec<(String, String, i32, i32, String)>)>> for SimulationTable {\n    fn add(&mut self, simulation: Vec<(String, Vec<(String, String, i32, i32, String)>)>) {\n        self.dt.push(simulation);\n    }\n\n    fn count(&self) -> usize {\n        self.dt.len()\n    }\n\n    fn get_list(&self) -> Vec<Vec<(String, Vec<(String, String, i32, i32, String)>)>> {\n        self.dt.clone()\n    }\n}\n\n// _____________________\n/// Aplicando interfaz para Datos en memoria.\nstruct DataInMemory {\n    events_table: Box<dyn IDataTable<String>>,\n    participants_table: Box<dyn IDataTable<(String, String, i32)>>,\n    simulation_table: Box<dyn IDataTable<Vec<(String, Vec<(String, String, i32, i32, String)>)>>>,\n}\n\nimpl DataInMemory {\n    fn new() -> Self {\n        DataInMemory {\n            events_table: Box::new(EventsTable::new()),\n            participants_table: Box::new(ParticipantsTable::new()),\n            simulation_table: Box::new(SimulationTable::new()),\n        }\n    }\n}\n\nimpl IData for DataInMemory {\n    fn events_table(&mut self) -> &mut dyn IDataTable<String> {\n        &mut *self.events_table\n    }\n\n    fn participants_table(&mut self) -> &mut dyn IDataTable<(String, String, i32)> {\n        &mut *self.participants_table\n    }\n\n    fn simulation_table(\n        &mut self,\n    ) -> &mut dyn IDataTable<Vec<(String, Vec<(String, String, i32, i32, String)>)>> {\n        &mut *self.simulation_table\n    }\n}\n\n// ________________________________________________\n\n/// Muestra un mensaje al usuario y devuelve su entrada.\nstruct ConsoleInput;\n\nimpl IInput for ConsoleInput {\n    fn get(&self, msg: &str) -> String {\n        loop {\n            print!(\"{}\", msg);\n            io::stdout().flush().expect(\"Error: limpiar búfer\");\n\n            let mut input = String::new();\n            io::stdin()\n                .read_line(&mut input)\n                .expect(\"Error al leer la entrada\");\n\n            let trimmed_input = input.trim().to_string();\n            if !trimmed_input.is_empty() {\n                return trimmed_input;\n            }\n\n            println!(\"La entrada no puede estar vacía.\");\n        }\n    }\n    \n    fn get_int(&self, msg: &str) -> i32 {\n        loop {\n            let input: String = self.get(msg);\n            \n            match input.trim().parse::<i32>() {\n                Ok(number) => {\n                    return number\n                },\n                Err(_) => {\n                    println!(\"Se requiere un número entero.\");\n                }\n            }\n        }\n    }\n}\n\n// ________________________________________________\n/// 1. Registrar eventos deportivos.\nstruct Events {\n    data: Arc<Mutex<Box<dyn IData>>>,\n    input: Arc<dyn IInput>,\n    constants: Arc<dyn IGlobalConfig>,\n}\n\nimpl Events {\n    fn new(\n        data: Arc<Mutex<Box<dyn IData>>>,\n        input: Arc<dyn IInput>,\n        constants: Arc<dyn IGlobalConfig>,\n    ) -> Self { Events { data, input, constants, } }\n}\n\nimpl IEvents for Events {\n    fn add(&self) {\n        println!(\"AGREGAR EVENTO DEPORTIVO:\");\n        let sport = self.input.get(\"Deporte: \");\n        let mut data = self.data.lock().unwrap();\n        data.events_table().add(sport.clone());\n        println!(\"\\n{} fue agregado\", sport);\n        println!(\"{}\", self.constants.menu());\n    }\n}\n\n// ________________________________________________\n/// 2. Registrar participantes por nombre y país.\nstruct Participants {\n    data: Arc<Mutex<Box<dyn IData>>>,\n    input: Arc<dyn IInput>,\n    constants: Arc<dyn IGlobalConfig>,\n}\n\nimpl Participants {\n    fn new(\n        data: Arc<Mutex<Box<dyn IData>>>,\n        input: Arc<dyn IInput>,\n        constants: Arc<dyn IGlobalConfig>,\n    ) -> Self { Participants { data, input, constants, } }\n}\n\nimpl IParticipants for Participants {\n    fn get_event_id(&self) -> i32 {\n        println!(\"Seleccionar el evento donde participará:\");\n        let mut data = self.data.lock().unwrap();\n        let events = data.events_table().get_list();\n        \n        for i in 0..events.len() {\n            println!(\"{}: {}\", i, events[i]);\n        }\n\n        loop {\n            let index: i32 = self.input.get_int(\"d de evento: \");\n            if index < 0 || index >= events.len().try_into().unwrap() {\n                println!(\"Id no encontrada.\");\n            } else {\n                return index;\n            }\n        }\n    }\n\n    fn add(&self) {\n        println!(\"AGREGAR PARTICIPANTE:\");\n        let mut data = self.data.lock().unwrap();\n        let events = data.events_table().get_list();\n                \n        if !(events.len() > 0) {\n            println!(\"No existe evento en cuál participar.\");\n            return;\n        }\n\n        drop(data);\n        let event_id: i32 = self.get_event_id();\n        let name = self.input.get(\"Nombre: \");\n        let country = self.input.get(\"País: \");\n\n        let mut data = self.data.lock().unwrap();\n        data.participants_table()\n            .add((name.clone(), country.clone(), event_id));\n        println!(\"\\n{} fue agregado\", name);\n\n        println!(\"{}\", self.constants.menu());\n    }\n}\n// ________________________________________________\n/// 3. Simular eventos de manera aleatoria en base a los participantes (mínimo 3).\n/// 4. Asignar medallas (oro, plata y bronce) basándose en el resultado del evento.\nstruct Simulation {\n    data: Arc<Mutex<Box<dyn IData>>>,\n    constants: Arc<dyn IGlobalConfig>,\n}\n\nimpl Simulation {\n    fn new(data: Arc<Mutex<Box<dyn IData>>>, constants: Arc<dyn IGlobalConfig>) -> Self {\n        Simulation { data, constants }\n    }\n\n    fn qualify_participants(&self, event_id: i32) -> Vec<(String, String, i32, i32, String)> {\n        let mut rng = rand::thread_rng();\n        let medals = self.constants.medals();\n\n        let participants_list = {\n            let mut data = self.data.lock().unwrap();\n            data.participants_table().get_list()\n        };\n\n        // Seleccionar solo los participantes que tienen el ID del evento.\n        let participants_of_event: Vec<_> = participants_list\n        .iter()\n        .filter(|p| p.2 == event_id)\n        .collect();\n\n        let mut participants: Vec<_> = participants_of_event\n            .iter()\n            .map(|(name, country, event_id)| (\n                name.clone(), country.clone(), event_id.clone(), rng.gen_range(1..=100)))\n            .collect();\n\n        participants.sort_by(|a, b| b.3.cmp(&a.3));\n\n        participants\n            .into_iter()\n            .take(3)\n            .enumerate()\n            .map(|(i, (name, country, event_id, score))| (\n                name, country, event_id, score, medals[i].to_string()))\n            .collect()\n    }\n\n    fn add_result_events(&self) {\n        let mut data = self.data.lock().unwrap();\n        let events = data.events_table().get_list();\n        drop(data);\n         \n        let simulation: Vec<_> = events\n            .into_iter()\n            .enumerate()\n            .map(|(index, event)| (event, self.qualify_participants(index\n                .try_into()\n                .unwrap())))\n            .collect();\n\n        let mut data2 = self.data.lock().unwrap();\n        data2.simulation_table().add(simulation);\n    }\n}\n\nimpl ISimulations for Simulation {\n    fn start(&self) {\n        let mut data = self.data.lock().unwrap();\n        if data.events_table().count() >= 1 && data.participants_table().count() >= 3 {\n            drop(data);\n            self.add_result_events();\n            let total_simulation = self.data.lock().unwrap().simulation_table().count();\n            println!(\"\\nSimulación '#{:?}' creada.\", total_simulation);\n            println!(\"Puedes ver el resultado con opción: '4. Crear informes.'\");\n            println!(\"{}\", self.constants.menu());\n        } else {\n            println!(\"\\nDebe haber al menos un evento y al menos 'tres' participantes.\");\n        }\n    }\n}\n\n// ________________________________________________\n/// 5. Mostrar los ganadores por cada evento.\n/// 6. Mostrar el ranking de países según el número de medallas.\n\nstruct Reports {\n    data: Arc<Mutex<Box<dyn IData>>>,\n    constants: Arc<dyn IGlobalConfig>,\n}\n\nimpl Reports {\n    fn new(data: Arc<Mutex<Box<dyn IData>>>, constants: Arc<dyn IGlobalConfig>) -> Self {\n        Reports { data, constants }\n    }\n\n    fn generate_top_countries(&self, ranking_countries: &mut HashMap<String, (i32, i32)>) {\n        let mut vec: Vec<_> = ranking_countries.iter().collect();\n        vec.sort_by(|a, b| b.1.0.cmp(&a.1.0).then(b.1.1.cmp(&a.1.1)));\n\n        for (i, (country, (medals, score))) in vec.iter().take(10).enumerate() {\n            println!(\"🔵 {:<2} | {:<12} | 🏅 {:<3} | 🧮 {:>4}\", i + 1, country, medals, score);\n        }\n    }\n\n    fn update_country_ranking(\n        ranking_countries: &mut HashMap<String, (i32, i32)>,\n        country: String,\n        score: i32\n    ) {\n        match ranking_countries.get_mut(&country) {\n            Some((medals, current_score)) => {\n                *medals += 1;\n                *current_score += score;\n            },\n            None => {\n                ranking_countries.insert(country, (1, score));\n            }\n        }\n    }\n\n    fn iterate_participants(\n        &self,\n        participants: &[(String, String, i32, i32, String)],\n        ranking_countries: &mut HashMap<String, (i32, i32)>,\n    ) {\n        for (i, (name, country, _event_id, score, medal)) in participants.iter().enumerate() {\n            println!(\"🟢 '{:<1}' | {:<7} | {:<12} -> 🔢 {:<3}, | {:<3}\", i + 1, name, country, score, medal\n            );\n            Self::update_country_ranking(ranking_countries, country.clone(), score.clone());\n        }\n    }\n\n    fn iterate_events(\n        &self,\n        simulation: &Vec<(String, Vec<(String, String, i32, i32, String)>)>,\n        ranking_countries: &mut HashMap<String, (i32, i32)>,\n    ) {\n        for (event_name, results) in simulation {\n            println!(\"\\nEvent: {}:\", event_name);\n            if results.len() < 3 {\n                println!(\"Evento cancelado por falta de participantes.\");\n                continue;\n            }\n\n            self.iterate_participants(results, ranking_countries);\n        }\n    }\n}\n\nimpl IReports for Reports {\n    fn generate(&self) {\n        let simulations = self.data.lock().unwrap().simulation_table().get_list();\n        if simulations.is_empty() {\n            println!(\"Aún no hay simulaciones creadas.\");\n            return;\n        }\n\n        for (i, simulation) in simulations.iter().enumerate() {\n            println!(\"\\n______________\\nSimulation {}\", i + 1);\n            let mut ranking_countries: HashMap<String, (i32, i32)> = HashMap::new();\n            self.iterate_events(simulation, &mut ranking_countries);\n\n            println!(\"\\nRanking de países, según el número de medallas:\");\n            self.generate_top_countries(&mut ranking_countries);\n        }\n\n        println!(\"{}\", self.constants.menu());\n    }\n}\n\n// ________________________________________________\nstruct Program {\n    events: Box<dyn IEvents>,\n    participants: Box<dyn IParticipants>,\n    simulation: Box<dyn ISimulations>,\n    reports: Box<dyn IReports>,\n    input: Arc<dyn IInput>,\n    constants: Arc<dyn IGlobalConfig>,\n}\n\nimpl Program {\n    fn new() -> Self {\n        let data: Arc<Mutex<Box<dyn IData>>> = Arc::new(Mutex::new(Box::new(DataInMemory::new())));\n        let input: Arc<dyn IInput> = Arc::new(ConsoleInput);\n        let constants: Arc<dyn IGlobalConfig> = Arc::new(GlobalConfig);\n\n        Program {\n            events: Box::new(Events::new(data.clone(), input.clone(), constants.clone())),\n            participants: Box::new(Participants::new(data.clone(), input.clone(), constants.clone(),)),\n            simulation: Box::new(Simulation::new(data.clone(), constants.clone())),\n            reports: Box::new(Reports::new(data, constants.clone())),\n            input,\n            constants,\n        }\n    }\n\n    fn run(&self) {\n        println!(\"{}\", self.constants.menu());\n\n        loop {\n            let option = self.input.get(\"\\nOpción: \");\n\n            match option.as_str() {\n                \"1\" => self.events.add(),\n                \"2\" => self.participants.add(),\n                \"3\" => self.simulation.start(),\n                \"4\" => self.reports.generate(),\n                \"5\" => {\n                    println!(\"Adios\");\n                    break;\n                }\n                _ => println!(\"Seleccionar de '1 a 5'\"),\n            }\n        }\n    }\n}\n\n//____________________________________\nfn main() {\n    let program = Program::new();\n    program.run();\n}\n\n// NOTA: Solo es un intento de practicar los principios SOLID. XD\n\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/rust/sisaroot.rs",
    "content": "// #31 SIMULADOR JUEGOS OLÍMPICOS - SisaRoot\n\nuse std::collections::HashMap;\nuse std::io::{self, BufRead, Write};\n\n#[derive(Clone)]\nstruct Participant { name: String, country: String }\nstruct Event { name: String, participants: Vec<Participant> }\n#[derive(Default)]\nstruct Medals { gold: u32, silver: u32, bronze: u32 }\nimpl Medals { fn total(&self) -> u32 { self.gold + self.silver + self.bronze } }\n\nfn readline(prompt: &str) -> String {\n    print!(\"{}\", prompt); io::stdout().flush().unwrap();\n    let mut l = String::new();\n    io::stdin().lock().read_line(&mut l).unwrap();\n    l.trim().to_string()\n}\n\nfn xorshift(state: &mut u64) -> u64 {\n    *state ^= *state << 13; *state ^= *state >> 7; *state ^= *state << 17; *state\n}\n\nfn register_event(events: &mut Vec<Event>) {\n    let name = readline(\"Nombre del evento: \");\n    if events.iter().any(|e| e.name.to_lowercase() == name.to_lowercase())\n    { println!(\"Ya existe.\"); return; }\n    events.push(Event { name: name.clone(), participants: vec![] });\n    println!(\"Evento '{}' registrado.\", name);\n}\n\nfn register_participant(events: &mut Vec<Event>) {\n    if events.is_empty() { println!(\"No hay eventos.\"); return; }\n    for (i,ev) in events.iter().enumerate() { println!(\"  {}. {}\", i+1, ev.name); }\n    let idx: usize = match readline(\"Numero: \").parse::<usize>() {\n        Ok(n) if n>=1 && n<=events.len() => n, _ => { println!(\"Invalido.\"); return; }\n    };\n    let n = readline(\"Nombre: \"); let c = readline(\"País: \");\n    let ev_name = events[idx-1].name.clone();\n    events[idx-1].participants.push(Participant { name: n.clone(), country: c.clone() });\n    println!(\"'{} ({})' añadido a '{}'.\", n, c, ev_name);\n}\n\nfn simulate_events(events: &Vec<Event>, medals: &mut HashMap<String, Medals>) {\n    use std::time::{SystemTime, UNIX_EPOCH};\n    let mut rng = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().subsec_nanos() as u64;\n    for ev in events {\n        println!(\"\\n=== Simulando: {} ===\", ev.name);\n        if ev.participants.len() < 3 { println!(\"  Necesita >=3. Saltando.\"); continue; }\n        let mut s: Vec<Participant> = ev.participants.clone();\n        for i in (1..s.len()).rev() { let j = (xorshift(&mut rng) as usize) % (i+1); s.swap(i,j); }\n        println!(\"  🥇 {} ({})\", s[0].name, s[0].country);\n        println!(\"  🥈 {} ({})\", s[1].name, s[1].country);\n        println!(\"  🥉 {} ({})\", s[2].name, s[2].country);\n        medals.entry(s[0].country.clone()).or_default().gold += 1;\n        medals.entry(s[1].country.clone()).or_default().silver += 1;\n        medals.entry(s[2].country.clone()).or_default().bronze += 1;\n    }\n}\n\nfn show_report(medals: &HashMap<String, Medals>) {\n    println!(\"\\n== INFORME FINAL ==\");\n    if medals.is_empty() { println!(\"Sin resultados.\"); return; }\n    let mut r: Vec<(&String, &Medals)> = medals.iter().collect();\n    r.sort_by(|a,b| b.1.gold.cmp(&a.1.gold).then(b.1.silver.cmp(&a.1.silver)).then(b.1.bronze.cmp(&a.1.bronze)));\n    for (i,(c,m)) in r.iter().enumerate() {\n        println!(\"{:<3} {:<20} Oro:{} Plata:{} Bronce:{} Total:{}\", i+1, c, m.gold, m.silver, m.bronze, m.total());\n    }\n}\n\nfn main() {\n    let mut events: Vec<Event> = vec![];\n    let mut medals: HashMap<String, Medals> = HashMap::new();\n    loop {\n        println!(\"\\n====== SIMULADOR JJOO ======\\n1. Registrar evento\\n2. Registrar participante\\n3. Simular\\n4. Informe\\n5. Salir\");\n        match readline(\"Opción: \").as_str() {\n            \"1\" => register_event(&mut events),\n            \"2\" => register_participant(&mut events),\n            \"3\" => simulate_events(&events, &mut medals),\n            \"4\" => show_report(&medals),\n            \"5\" => { println!(\"Hasta luego!\"); break; }\n            _ => println!(\"Invalido.\"),\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/sql/Nicojsuarez2.sql",
    "content": "# #31 SIMULADOR JUEGOS OLÍMPICOS\n> #### Dificultad: Difícil | Publicación: 29/07/24 | Corrección: 05/08/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * ¡Los JJOO de París 2024 han comenzado!\n * Crea un programa que simule la celebración de los juegos.\n * El programa debe permitir al usuario registrar eventos y participantes,\n * realizar la simulación de los eventos asignando posiciones de manera aleatoria\n * y generar un informe final. Todo ello por terminal.\n * Requisitos:\n * 1. Registrar eventos deportivos.\n * 2. Registrar participantes por nombre y país.\n * 3. Simular eventos de manera aleatoria en base a los participantes (mínimo 3).\n * 4. Asignar medallas (oro, plata y bronce) basándose en el resultado del evento.\n * 5. Mostrar los ganadores por cada evento.\n * 6. Mostrar el ranking de países según el número de medallas.\n * Acciones:\n * 1. Registro de eventos.\n * 2. Registro de participantes.\n * 3. Simulación de eventos.\n * 4. Creación de informes.\n * 5. Salir del programa.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/sql/sisaroot.sql",
    "content": "-- #31 SIMULADOR JUEGOS OLÍMPICOS - SisaRoot (SQLite)\n\nCREATE TABLE IF NOT EXISTS events (\n    id   INTEGER PRIMARY KEY AUTOINCREMENT,\n    name TEXT NOT NULL UNIQUE\n);\n\nCREATE TABLE IF NOT EXISTS participants (\n    id       INTEGER PRIMARY KEY AUTOINCREMENT,\n    event_id INTEGER NOT NULL REFERENCES events(id),\n    name     TEXT NOT NULL,\n    country  TEXT NOT NULL\n);\n\nCREATE TABLE IF NOT EXISTS results (\n    id             INTEGER PRIMARY KEY AUTOINCREMENT,\n    event_id       INTEGER NOT NULL REFERENCES events(id),\n    gold_name      TEXT NOT NULL, gold_country    TEXT NOT NULL,\n    silver_name    TEXT NOT NULL, silver_country  TEXT NOT NULL,\n    bronze_name    TEXT NOT NULL, bronze_country  TEXT NOT NULL\n);\n\n-- == REGISTRAR EVENTOS ==\nINSERT INTO events (name) VALUES\n    ('100m Atletismo'), ('Natacion 200m'), ('Ciclismo de Pista');\n\n-- == REGISTRAR PARTICIPANTES ==\nINSERT INTO participants (event_id, name, country) VALUES\n    (1,'Marcell Jacobs','Italia'),\n    (1,'Fred Kerley','Estados Unidos'),\n    (1,'Trayvon Bromell','Estados Unidos'),\n    (1,'Adam Gemili','Reino Unido'),\n    (2,'Caeleb Dressel','Estados Unidos'),\n    (2,'Kristof Milak','Hungria'),\n    (2,'Tom Dean','Reino Unido'),\n    (2,'Kyle Chalmers','Australia'),\n    (3,'Harrie Lavreysen','Paises Bajos'),\n    (3,'Jeffrey Hoogland','Paises Bajos'),\n    (3,'Jack Carlin','Reino Unido'),\n    (3,'Nicholas Paul','Trinidad y Tobago');\n\n-- == SIMULAR EVENTOS (aleatorio) ==\nINSERT INTO results (event_id, gold_name, gold_country, silver_name, silver_country, bronze_name, bronze_country)\nSELECT p1.event_id, p1.name, p1.country, p2.name, p2.country, p3.name, p3.country\nFROM\n    (SELECT *, ROW_NUMBER() OVER (PARTITION BY event_id ORDER BY RANDOM()) rn FROM participants) p1\n    JOIN (SELECT *, ROW_NUMBER() OVER (PARTITION BY event_id ORDER BY RANDOM()) rn FROM participants) p2\n      ON p1.event_id=p2.event_id AND p2.rn=2 AND p1.name<>p2.name\n    JOIN (SELECT *, ROW_NUMBER() OVER (PARTITION BY event_id ORDER BY RANDOM()) rn FROM participants) p3\n      ON p1.event_id=p3.event_id AND p3.rn=3 AND p1.name<>p3.name AND p2.name<>p3.name\nWHERE p1.rn=1;\n\n-- == GANADORES POR EVENTO ==\nSELECT e.name AS Evento,\n    r.gold_name   ||' ('||r.gold_country  ||')' AS Oro,\n    r.silver_name ||' ('||r.silver_country||')' AS Plata,\n    r.bronze_name ||' ('||r.bronze_country||')' AS Bronce\nFROM results r JOIN events e ON e.id=r.event_id;\n\n-- == RANKING POR PAÍS ==\nWITH m AS (\n    SELECT gold_country   country, 1 g, 0 s, 0 b FROM results\n    UNION ALL SELECT silver_country, 0,1,0 FROM results\n    UNION ALL SELECT bronze_country, 0,0,1 FROM results\n)\nSELECT ROW_NUMBER() OVER (ORDER BY SUM(g) DESC,SUM(s) DESC,SUM(b) DESC) Pos,\n    country Pais, SUM(g) Oro, SUM(s) Plata, SUM(b) Bronce, SUM(g+s+b) Total\nFROM m GROUP BY country ORDER BY SUM(g) DESC,SUM(s) DESC,SUM(b) DESC;\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/typescript/duendeintemporal.ts",
    "content": "/**\n * Retosdeprogramacion #31 { retosparaprogramadores } - Simulador Juegos Olímpicos\n * \n * EJERCICIO:\n * ¡Los JJOO de París 2024 han comenzado!\n * Crea un programa que simule la celebración de los juegos.\n * El programa debe permitir al usuario registrar eventos y participantes,\n * realizar la simulación de los eventos asignando posiciones de manera aleatoria\n * y generar un informe final. Todo ello por terminal.\n * Requisitos:\n * 1. Registrar eventos deportivos.\n * 2. Registrar participantes por nombre y país.\n * 3. Simular eventos de manera aleatoria en base a los participantes (mínimo 3).\n * 4. Asignar medallas (oro, plata y bronce) basándose en el resultado del evento.\n * 5. Mostrar los ganadores por cada evento.\n * 6. Mostrar el ranking de países según el número de medallas.\n * Acciones:\n * 1. Registro de eventos.\n * 2. Registro de participantes.\n * 3. Simulación de eventos.\n * 4. Creación de informes.\n * 5. Salir del programa.\n *  */\n\nconst log = console.log;\n\n// Check if running in a browser environment\nconst isBrowser = typeof window !== 'undefined';\n\n// Conditional check for browser environment\nif (isBrowser) {\n    window.addEventListener('load', () => {\n        const body: HTMLBodyElement | null = document.querySelector('body');\n        const title = document.createElement('h1');\n\n        body?.style.setProperty('background', '#000');\n        body?.style.setProperty('text-align', 'center');\n\n        title.textContent = 'Retosparaprogramadores #31.';\n        title.style.setProperty('font-size', '3.5vmax');\n        title.style.setProperty('color', '#fff');\n        title.style.setProperty('line-height', '100vh');\n\n        body?.appendChild(title);\n\n        setTimeout(() => {\n            alert('Retosparaprogramadores #31. Please open the Browser Developer Tools.');\n        }, 2000);\n        log('Retosparaprogramadores #31');\n    });\n} else {\n    log('This code is designed to run in a browser environment. Skipping window-related code.');\n    log('Retosparaprogramadores #31');\n}\n\n/**\n * Shuffles an array in place using the Fisher-Yates algorithm.\n * @param array - The array to shuffle.\n * @returns The shuffled array.\n */\nfunction shuffleArray<T>(array: T[]): T[] {\n    for (let i = array.length - 1; i > 0; i--) {\n        const j = Math.floor(Math.random() * (i + 1));\n        [array[i], array[j]] = [array[j], array[i]];\n    }\n    return array;\n}\n\n/**\n * Represents an Olympic event.\n */\nclass Events {\n    public events: { [key: string]: Player[] };\n    public prizes: Prizes;\n\n    constructor() {\n        this.events = {};\n        this.prizes = new Prizes();\n    }\n\n    /**\n     * Adds a new event to the registry.\n     * @param event - The name of the event.\n     */\n    addEvent(event: string): void {\n        if (this.events[event]) {\n            log(`There's a ${event} event already registered.`);\n        } else {\n            this.events[event] = [];\n            log(`Event ${event} registered.`);\n        }\n    }\n\n    /**\n     * Adds a player to a specific event.\n     * @param player - The player to add.\n     */\n    addPlayer(player: Player): void {\n        if (!this.events[player.event]) {\n            log(`Event ${player.event} is not registered.`);\n            return;\n        }\n\n        const isPlayer = this.events[player.event].find(p => p.name === player.name);\n        if (!isPlayer) {\n            this.events[player.event].push(player);\n            log(`Player ${player.name} added to ${player.event} event.`);\n        } else {\n            log(`The player ${player.name} is already registered to ${player.event} event.`);\n        }\n    }\n\n    /**\n     * Randomizes the order of events.\n     * @returns A shuffled list of events.\n     */\n    randomEvents(): string[] {\n        const eventsList = Object.keys(this.events);\n        return shuffleArray(eventsList);\n    }\n\n    /**\n     * Displays participants for a specific event.\n     * @param event - The event to display participants for.\n     */\n    showParticipantsForEvent(event: string): void {\n        if (this.events[event]) {\n            log(`Participants for ${event} event:`);\n            this.events[event].forEach(p => log(`${p.name} from ${p.country}`));\n        } else {\n            log(`There's no participant registered for the ${event} event.`);\n        }\n    }\n\n    /**\n     * Displays all registered events and their participants.\n     */\n    showRegistryData(): void {\n        for (const key in this.events) {\n            log(`${key} event:`);\n            this.events[key].forEach(element => {\n                log(`${element.name} from ${element.country}`);\n            });\n        }\n    }\n}\n\n/**\n * Represents a participant in an Olympic event.\n */\nclass Player {\n    constructor(public name: string, public event: string, public country: string) {}\n}\n\n/**\n * Manages the awarding of medals and tracking of country medal counts.\n */\nclass Prizes {\n    public gold: { [key: string]: Player[] };\n    public silver: { [key: string]: Player[] };\n    public bronze: { [key: string]: Player[] };\n    public countryMedals: { [key: string]: { gold: number, silver: number, bronze: number } };\n\n    constructor() {\n        this.gold = {};\n        this.silver = {};\n        this.bronze = {};\n        this.countryMedals = {};\n    }\n\n    /**\n     * Awards a gold medal to a player.\n     * @param player - The player to award the gold medal to.\n     */\n    addGold(player: Player): void {\n        this.addPrize(player, 'gold');\n    }\n\n    /**\n     * Awards a silver medal to a player.\n     * @param player - The player to award the silver medal to.\n     */\n    addSilver(player: Player): void {\n        this.addPrize(player, 'silver');\n    }\n\n    /**\n     * Awards a bronze medal to a player.\n     * @param player - The player to award the bronze medal to.\n     */\n    addBronze(player: Player): void {\n        this.addPrize(player, 'bronze');\n    }\n\n    /**\n     * Adds a prize to a player and updates the country's medal count.\n     * @param player - The player to award the prize to.\n     * @param type - The type of prize (gold, silver, bronze).\n     */\n    private addPrize(player: Player, type: 'gold' | 'silver' | 'bronze'): void {\n        if (!this[type][player.event]) {\n            this[type][player.event] = [];\n        }\n        if (!this[type][player.event].find(p => p.name === player.name)) {\n            this[type][player.event].push(player);\n            this.countCountryMedal(player.country, type);\n        }\n    }\n\n    /**\n     * Updates the medal count for a country.\n     * @param country - The country to update.\n     * @param type - The type of medal (gold, silver, bronze).\n     */\n    private countCountryMedal(country: string, type: 'gold' | 'silver' | 'bronze'): void {\n        if (!this.countryMedals[country]) {\n            this.countryMedals[country] = { gold: 0, silver: 0, bronze: 0 };\n        }\n        this.countryMedals[country][type]++;\n    }\n\n    /**\n     * Displays the winners for each event.\n     */\n    showWinners(): void {\n        log('Winners:');\n        for (const event in this.gold) {\n            log(`${event}: Gold - ${this.gold[event].map(p => p.name).join(', ')}`);\n            log(`       Silver - ${this.silver[event] ? this.silver[event].map(p => p.name).join(', ') : 'None'}`);\n            log(`       Bronze - ${this.bronze[event] ? this.bronze[event].map(p => p.name).join(', ') : 'None'}`);\n        }\n    }\n\n    /**\n     * Displays the medal count for each country.\n     */\n    showCountryMedals(): void {\n        log('Country Medal Count:');\n        for (const country in this.countryMedals) {\n            log(`${country}: Gold - ${this.countryMedals[country].gold}, Silver - ${this.countryMedals[country].silver}, Bronze - ${this.countryMedals[country].bronze}`);\n        }\n    }\n}\n\n/**\n * Simulates the events and assigns medals to the winners.\n * @param events - The events to simulate.\n */\nconst eventSimulator = (events: Events): void => {\n    for (const key in events.events) {\n        if (events.events[key].length >= 3) {\n            const winners = shuffleArray(events.events[key]);\n            events.prizes.addGold(winners[0]);\n            events.prizes.addSilver(winners[1]);\n            events.prizes.addBronze(winners[2]);\n        } else {\n            log(`Not enough participants for ${key} event.`);\n        }\n    }\n    events.prizes.showWinners();\n}\n\n// Dummy data for testing\nconst dummyData: [string, string, string][] = [\n    ['Bob Marley', 'Archery', 'Jamaica'],\n    ['Lenny Kravitz', 'Swimming', 'USA'],\n    ['John Lennon', 'Weightlifting', 'England'],\n    ['Lorenna McKennit', '100m Sprint', 'Somewhere in Europe'],\n    ['Alice', '200m Freestyle', 'The Rabbit Hole'],\n    ['Che Guevara', '3000m Steeplechase', 'Argentina'],\n    ['Buda', 'Discus Throw', 'India'],\n    ['Bugs Bunny', 'Archery', 'Disney'],\n    ['Asterix', 'Swimming', 'Comics'],\n    ['Lucky Luke', 'Weightlifting', 'Comics'],\n    ['Jerry Maguire', '100m Sprint', 'Comics'],\n    ['Atreyo', '200m Freestyle', 'Book'],\n    ['Simón Bolívar', '3000m Steeplechase', 'Venezuela'],\n    ['Goku', 'Discus Throw', 'Anime'],\n    ['Shihiro', 'Archery', 'Anime'],\n    ['Ruby', 'Swimming', 'Book'],\n    ['Crows', 'Weightlifting', 'Book'],\n    ['Devian', '100m Sprint', 'Book'],\n    ['Peque', '200m Freestyle', 'My World'],\n    ['Sophy', '3000m Steeplechase', 'My World'],\n    ['Beth', 'Discus Throw', 'My World']\n];\n\n// Create a new instance of Events\nconst firstRound = new Events();\n\n// Register Olympic events\nconst olympicEvents = ['Archery', 'Swimming', 'Weightlifting', '100m Sprint', '200m Freestyle', '3000m Steeplechase', 'Discus Throw'];\nolympicEvents.forEach(event => firstRound.addEvent(event));\n\n// Register participants from dummy data\ndummyData.forEach(d => firstRound.addPlayer(new Player(d[0], d[1], d[2])));\n\n// Display registered data\nfirstRound.showRegistryData();\n\n// Simulate events and display winners\neventSimulator(firstRound);\n\n/* Output: \nRetosparaprogramadores #31\nEvent Archery registered.\nEvent Swimming registered.\nEvent Weightlifting registered.\nEvent 100m Sprint registered.\nEvent 200m Freestyle registered.\nEvent 3000m Steeplechase registered.\nEvent Discus Throw registered.\nPlayer Bob Marley added to Archery event.\nPlayer Lenny Kravitz added to Swimming event.\nPlayer John Lennon added to Weightlifting event.\nPlayer Lorenna McKennit added to 100m Sprint event.\nPlayer Alice added to 200m Freestyle event.\nPlayer Che Guevara added to 3000m Steeplechase event.\nPlayer Buda added to Discus Throw event.\nPlayer Bugs Bunny added to Archery event.\nPlayer Asterix added to Swimming event.\nPlayer Lucky Luke added to Weightlifting event.\nPlayer Jerry Maguire added to 100m Sprint event.\nPlayer Atreyo added to 200m Freestyle event.\nPlayer Simón Bolívar added to 3000m Steeplechase event.\nPlayer Goku added to Discus Throw event.\nPlayer Shihiro added to Archery event.\nPlayer Ruby added to Swimming event.\nPlayer Crows added to Weightlifting event.\nPlayer Devian added to 100m Sprint event.\nPlayer Peque added to 200m Freestyle event.\nPlayer Sophy added to 3000m Steeplechase event.\nPlayer Beth added to Discus Throw event.\nArchery event:\nBob Marley from Jamaica\nBugs Bunny from Disney\nShihiro from Anime\nSwimming event:\nLenny Kravitz from USA\nAsterix from Comics\nRuby from Book\nWeightlifting event:\nJohn Lennon from England\nLucky Luke from Comics\nCrows from Book\n100m Sprint event:\nLorenna McKennit from Somewhere in Europe\nJerry Maguire from Comics\nDevian from Book\n200m Freestyle event:\nAlice from The Rabbit Hole\nAtreyo from Book\nPeque from My World\n3000m Steeplechase event:\nChe Guevara from Argentina\nSimón Bolívar from Venezuela\nSophy from My World\nDiscus Throw event:\nBuda from India\nGoku from Anime\nBeth from My World\nWinners:\nArchery: Gold - Bob Marley\n       Silver - Shihiro\n       Bronze - Bugs Bunny\nSwimming: Gold - Lenny Kravitz\n       Silver - Ruby\n       Bronze - Asterix\nWeightlifting: Gold - Crows\n       Silver - Lucky Luke\n       Bronze - John Lennon\n100m Sprint: Gold - Devian\n       Silver - Jerry Maguire\n       Bronze - Lorenna McKennit\n200m Freestyle: Gold - Peque\n       Silver - Alice\n       Bronze - Atreyo\n3000m Steeplechase: Gold - Che Guevara\n       Silver - Sophy\n       Bronze - Simón Bolívar\nDiscus Throw: Gold - Goku\n       Silver - Buda\n       Bronze - Beth\n*/"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/typescript/hozlucas28.ts",
    "content": "/* -------------------------------------------------------------------------- */\n/*                                  ERRORS.TS                                 */\n/* -------------------------------------------------------------------------- */\n\ninterface SportEventErrorsRtn {\n    notEnoughCompetitors: string\n}\n\nfunction sportEventErrors<T>(sportEvent: ISportEvent): SportEventErrorsRtn {\n    const name: Lowercase<string> = sportEvent.getName()\n    const competitors: ICompetitor[] = sportEvent.getCompetitors()\n\n    return {\n        notEnoughCompetitors: `Sport event '${name}' needs more competitors. It currently has ${competitors.length} competitor(s), but requires a minimum of ${SportEvent.minimumNumberOfCompetitors}.`,\n    }\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                  UTILS.TS                                  */\n/* -------------------------------------------------------------------------- */\n\ninterface CountriesRankingByNumberOfMedalsRtn {\n    name: Country\n    numberOfMedals: number\n}\n\nfunction countriesRankingByNumberOfMedals(\n    ...sportEvents: ISportEvent[]\n): CountriesRankingByNumberOfMedalsRtn[] {\n    const medalRankingPerCountry: CountriesRankingByNumberOfMedalsRtn[] = []\n\n    const winners: ICompetitor[] = []\n    for (let i = 0; i < sportEvents.length; i++) {\n        const sportEventWinners = sportEvents[i].getWinners()\n        winners.push(...sportEventWinners)\n    }\n\n    const indexesToIgnore: number[] = []\n\n    for (let i = 0; i < winners.length; i++) {\n        if (indexesToIgnore.includes(i)) continue\n\n        const anchorWinner = winners[i]\n        const anchorWinnerCountry: Country = anchorWinner.getCountry()\n        const anchorWinnerMedals: IMedal[] = anchorWinner.getMedals()\n\n        const countryStats: CountriesRankingByNumberOfMedalsRtn = {\n            name: anchorWinnerCountry,\n            numberOfMedals: anchorWinnerMedals.length,\n        }\n\n        for (let j = i + 1; j < winners.length; j++) {\n            if (indexesToIgnore.includes(j)) continue\n\n            const nextWinner = winners[j]\n            const nextWinnerCountry: Country = nextWinner.getCountry()\n            const nextWinnerMedals: IMedal[] = nextWinner.getMedals()\n\n            const areSameCountry: boolean =\n                anchorWinnerCountry.toUpperCase() ===\n                nextWinnerCountry.toUpperCase()\n\n            if (areSameCountry) {\n                countryStats.numberOfMedals += nextWinnerMedals.length\n                indexesToIgnore.push(j)\n            }\n        }\n\n        medalRankingPerCountry.push(countryStats)\n    }\n\n    medalRankingPerCountry.sort((a, b) => {\n        const comparison: number = b.numberOfMedals - a.numberOfMedals\n        return comparison === 0 ? a.name.localeCompare(b.name) : comparison\n    })\n\n    return medalRankingPerCountry\n}\n\nfunction thereAreDuplicatedElements<T extends object>(array: T[]): boolean {\n    if (array.length < 2) return false\n\n    const arrayStr: string[] = array.map((element) => JSON.stringify(element))\n    const uniqueElements: Set<string> = new Set(arrayStr)\n    return array.length !== uniqueElements.size\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                  MEDAL.TS                                  */\n/* -------------------------------------------------------------------------- */\n\ntype MedalCategory = Lowercase<'gold' | 'silver' | 'bronze'>\n\ninterface IMedal {\n    getDate: () => Date\n    getEvent: () => ISportEvent\n    getMedalCategory: () => MedalCategory\n}\n\ninterface MedalConstructor {\n    date: Date\n    event: ISportEvent\n    medalCategory: 'gold' | 'silver' | 'bronze'\n}\n\nclass Medal implements IMedal {\n    private readonly date: Date\n    private readonly event: ISportEvent\n    private readonly medalCategory: MedalCategory\n\n    public constructor({date, event, medalCategory}: MedalConstructor) {\n        this.date = date\n        this.event = event\n        this.medalCategory = medalCategory\n    }\n\n    public getDate(): Date {\n        return this.date\n    }\n\n    public getEvent(): ISportEvent {\n        return this.event\n    }\n\n    public getMedalCategory(): MedalCategory {\n        return this.medalCategory\n    }\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                COMPETITOR.TS                               */\n/* -------------------------------------------------------------------------- */\n\ntype Country =\n    | Lowercase<\n          | 'argentina'\n          | 'españa'\n          | 'estados unidos'\n          | 'méxico'\n          | 'canada'\n          | 'chile'\n          | 'brazil'\n          | 'germany'\n          | 'france'\n          | 'italy'\n          | 'australia'\n          | 'japan'\n      >\n    | (string & {})\n\ninterface ICompetitor {\n    getName: () => Lowercase<string>\n    getMedals: () => IMedal[]\n    getCountry: () => Country\n    addMedals: (...newMedals: IMedal[]) => this\n}\n\ninterface CompetitorConstructor {\n    country: Country\n    name: Lowercase<string>\n    medals?: IMedal[]\n}\n\nclass Competitor implements ICompetitor {\n    private country: Country\n    private medals: IMedal[]\n    private name: Lowercase<string>\n\n    public constructor({country, medals, name}: CompetitorConstructor) {\n        if (medals && thereAreDuplicatedElements(medals)) {\n            throw new Error(\n                'Duplicate medals detected. Each medal must be unique.'\n            )\n        }\n\n        this.country = country\n        this.medals = medals ?? []\n        this.name = name\n    }\n\n    public getCountry(): Country {\n        return this.country\n    }\n\n    public getMedals(): IMedal[] {\n        return this.medals\n    }\n\n    public getName(): Lowercase<string> {\n        return this.name\n    }\n\n    public addMedals(...newMedals: IMedal[]): this {\n        const existingMedals: IMedal[] = this.medals\n        const joinedMedals: IMedal[] = [...existingMedals, ...newMedals]\n\n        if (thereAreDuplicatedElements(joinedMedals)) {\n            throw new Error(\n                'Duplicate medals detected. Each medal must be unique.'\n            )\n        }\n\n        this.medals = joinedMedals\n        return this\n    }\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                SPORTEVENT.TS                               */\n/* -------------------------------------------------------------------------- */\n\ninterface ISportEvent {\n    getCompetitors: () => ICompetitor[]\n    getName: () => Lowercase<string>\n    getWinners: () => [ICompetitor, ICompetitor, ICompetitor]\n    addCompetitors: (...newCompetitors: ICompetitor[]) => this\n    start: () => this\n}\n\nclass SportEvent implements ISportEvent {\n    public static readonly minimumNumberOfCompetitors = 3\n\n    private competitors: ICompetitor[]\n    private name: Lowercase<string>\n    private winners: [ICompetitor, ICompetitor, ICompetitor]\n\n    public constructor(\n        name: Lowercase<string>,\n        competitors: ICompetitor[] = []\n    ) {\n        if (competitors && thereAreDuplicatedElements(competitors)) {\n            throw new Error(\n                'Duplicate competitors detected. Each competitor must be unique.'\n            )\n        }\n\n        this.name = name\n        this.competitors = competitors\n    }\n\n    public getCompetitors(): ICompetitor[] {\n        return this.competitors\n    }\n\n    public getName(): Lowercase<string> {\n        return this.name\n    }\n\n    public getWinners(): [ICompetitor, ICompetitor, ICompetitor] {\n        return this.winners\n    }\n\n    private hasEnoughCompetitors(): boolean {\n        return this.competitors.length >= SportEvent.minimumNumberOfCompetitors\n    }\n\n    public addCompetitors(...newCompetitors: ICompetitor[]): this {\n        const existingCompetitors: ICompetitor[] = this.competitors\n        const joinedCompetitors: ICompetitor[] = [\n            ...existingCompetitors,\n            ...newCompetitors,\n        ]\n\n        if (thereAreDuplicatedElements(joinedCompetitors)) {\n            throw new Error(\n                'Duplicate competitors detected. Each competitor must be unique.'\n            )\n        }\n\n        this.competitors = joinedCompetitors\n        return this\n    }\n\n    public start(): this {\n        if (!this.hasEnoughCompetitors()) {\n            const errorMessage: string =\n                sportEventErrors(this).notEnoughCompetitors\n            throw new Error(errorMessage)\n        }\n\n        const indexOfRndCompetitor = (\n            indexesToIgnore: number[] = []\n        ): number => {\n            const competitorI: number = Math.min(\n                Math.floor(\n                    Math.random() * Math.max(10, this.competitors.length)\n                ),\n                this.competitors.length - 1\n            )\n\n            if (indexesToIgnore.includes(competitorI))\n                return indexOfRndCompetitor(indexesToIgnore)\n            return competitorI\n        }\n\n        const firstPlaceI: number = indexOfRndCompetitor()\n        const secondPlaceI: number = indexOfRndCompetitor([firstPlaceI])\n        const thirdPlaceI: number = indexOfRndCompetitor([\n            firstPlaceI,\n            secondPlaceI,\n        ])\n\n        const goldMedal: IMedal = new Medal({\n            date: new Date(),\n            event: this,\n            medalCategory: 'gold',\n        })\n\n        const silverMedal: IMedal = new Medal({\n            date: new Date(),\n            event: this,\n            medalCategory: 'silver',\n        })\n\n        const bronzeMedal: IMedal = new Medal({\n            date: new Date(),\n            event: this,\n            medalCategory: 'bronze',\n        })\n\n        this.competitors[firstPlaceI].addMedals(goldMedal)\n        this.competitors[secondPlaceI].addMedals(silverMedal)\n        this.competitors[thirdPlaceI].addMedals(bronzeMedal)\n\n        this.winners = [\n            this.competitors[firstPlaceI],\n            this.competitors[secondPlaceI],\n            this.competitors[thirdPlaceI],\n        ]\n\n        return this\n    }\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                  EXERCISE                                  */\n/* -------------------------------------------------------------------------- */\n\nconsole.log('> Paris 2024 olympic games...')\n\nconst firstSportEvent: ISportEvent = new SportEvent('football')\nconst secondSportEvent: ISportEvent = new SportEvent('handball')\nconst thirdSportEvent: ISportEvent = new SportEvent('table tennis')\nconst fourthSportEvent: ISportEvent = new SportEvent('swimming')\n\nconsole.log('\\n> First sport event...\\n')\nconsole.dir(firstSportEvent)\n\nconsole.log('\\n> Second sport event...\\n')\nconsole.dir(secondSportEvent)\n\nconsole.log('\\n> Third sport event...\\n')\nconsole.dir(thirdSportEvent)\n\nconsole.log('\\n> Fourth sport event...\\n')\nconsole.dir(fourthSportEvent)\n\nconst competitorsOfFirstSportEvent: ICompetitor[] = [\n    new Competitor({country: 'argentina', name: 'lionel messi'}),\n    new Competitor({country: 'españa', name: 'sergio ramos'}),\n    new Competitor({country: 'estados unidos', name: 'megan rapinoe'}),\n    new Competitor({country: 'méxico', name: 'hirving lozano'}),\n    new Competitor({country: 'canada', name: 'christine sinclair'}),\n]\n\nconst competitorsOfSecondSportEvent: ICompetitor[] = [\n    new Competitor({country: 'brazil', name: 'neymar'}),\n    new Competitor({country: 'germany', name: 'manuel neuer'}),\n    new Competitor({country: 'france', name: 'antoine griezmann'}),\n    new Competitor({country: 'italy', name: 'giorgio chiellini'}),\n    new Competitor({country: 'australia', name: 'sam kerr'}),\n]\n\nconst competitorsOfThirdSportEvent: ICompetitor[] = [\n    new Competitor({country: 'japan', name: 'naomi osaka'}),\n    new Competitor({country: 'china', name: 'liu shiwen'}),\n    new Competitor({country: 'south korea', name: 'choi hyojoo'}),\n    new Competitor({country: 'singapore', name: 'feng tianwei'}),\n    new Competitor({country: 'germany', name: 'han ying'}),\n]\n\nconst competitorsOfFourthSportEvent: ICompetitor[] = [\n    new Competitor({country: 'sweden', name: 'sarah sjöström'}),\n    new Competitor({country: 'united states', name: 'caleb dressel'}),\n    new Competitor({country: 'australia', name: 'emma mckeon'}),\n    new Competitor({country: 'canada', name: 'penny oleksiak'}),\n    new Competitor({country: 'netherlands', name: 'ranomi kromowidjojo'}),\n]\n\nconsole.log('\\n> Competitors of first sport event...\\n')\nconsole.dir(competitorsOfFirstSportEvent)\n\nconsole.log('\\n> Competitors of second sport event...\\n')\nconsole.dir(competitorsOfSecondSportEvent)\n\nconsole.log('\\n> Competitors of third sport event...\\n')\nconsole.dir(competitorsOfThirdSportEvent)\n\nconsole.log('\\n> Competitors of fourth sport event...\\n')\nconsole.dir(competitorsOfFourthSportEvent)\n\nfirstSportEvent.addCompetitors(...competitorsOfFirstSportEvent).start()\nsecondSportEvent.addCompetitors(...competitorsOfSecondSportEvent).start()\nthirdSportEvent.addCompetitors(...competitorsOfThirdSportEvent).start()\nfourthSportEvent.addCompetitors(...competitorsOfFourthSportEvent).start()\n\nconst winnersOfFirstSportEvent = firstSportEvent.getWinners()\nconst winnersOfSecondSportEvent = secondSportEvent.getWinners()\nconst winnersOfThirdSportEvent = thirdSportEvent.getWinners()\nconst winnersOfFourthSportEvent = fourthSportEvent.getWinners()\n\nconsole.log('\\n> Winners of first sport event...\\n')\nconsole.dir(winnersOfFirstSportEvent)\n\nconsole.log('\\n> Winners of second sport event...\\n')\nconsole.dir(winnersOfSecondSportEvent)\n\nconsole.log('\\n> Winners of third sport event...\\n')\nconsole.dir(winnersOfThirdSportEvent)\n\nconsole.log('\\n> Winners of fourth sport event...\\n')\nconsole.dir(winnersOfFourthSportEvent)\n\nconst medalRankingPerCountry = countriesRankingByNumberOfMedals(\n    firstSportEvent,\n    secondSportEvent,\n    thirdSportEvent,\n    fourthSportEvent\n)\n\nconsole.log('\\n> Medal ranking per country...\\n')\nconsole.dir(medalRankingPerCountry)\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/typescript/sisaroot.ts",
    "content": "// #31 SIMULADOR JUEGOS OLÍMPICOS - SisaRoot\n// Run: npx ts-node SisaRoot.ts\n\nimport * as readline from \"readline\";\n\ninterface Participant { name: string; country: string; }\ninterface OlympicEvent { name: string; participants: Participant[]; }\ninterface Medals { gold: number; silver: number; bronze: number; }\n\nconst events: OlympicEvent[] = [];\nconst medalTable = new Map<string, Medals>();\nconst rl = readline.createInterface({ input: process.stdin, output: process.stdout });\nconst ask = (q: string): Promise<string> => new Promise((res) => rl.question(q, res));\n\nconst shuffle = <T>(arr: T[]): T[] => {\n    const a = [...arr];\n    for (let i = a.length - 1; i > 0; i--) {\n        const j = (Math.random() * (i + 1)) | 0;\n        [a[i], a[j]] = [a[j], a[i]];\n    }\n    return a;\n};\n\nfunction addMedal(country: string, type: keyof Medals): void {\n    if (!medalTable.has(country)) medalTable.set(country, { gold: 0, silver: 0, bronze: 0 });\n    medalTable.get(country)![type]++;\n}\n\nasync function registerEvent(): Promise<void> {\n    const name = (await ask(\"Nombre del evento: \")).trim();\n    if (!name) { console.log(\"Invalido.\"); return; }\n    if (events.some((e) => e.name.toLowerCase() === name.toLowerCase())) { console.log(`'${name}' ya existe.`); return; }\n    events.push({ name, participants: [] });\n    console.log(`Evento '${name}' registrado.`);\n}\n\nasync function registerParticipant(): Promise<void> {\n    if (!events.length) { console.log(\"No hay eventos.\"); return; }\n    events.forEach((e, i) => console.log(`  ${i + 1}. ${e.name}`));\n    const idx = parseInt(await ask(\"Número: \"), 10);\n    if (isNaN(idx) || idx < 1 || idx > events.length) { console.log(\"Invalido.\"); return; }\n    const ev = events[idx - 1];\n    const name = (await ask(\"Nombre: \")).trim();\n    const country = (await ask(\"País: \")).trim();\n    ev.participants.push({ name, country });\n    console.log(`'${name} (${country})' añadido a '${ev.name}'.`);\n}\n\nfunction simulateEvents(): void {\n    if (!events.length) { console.log(\"No hay eventos.\"); return; }\n    for (const ev of events) {\n        console.log(`\\n=== Simulando: ${ev.name} ===`);\n        if (ev.participants.length < 3) { console.log(\"  Necesita >=3. Saltando.\"); continue; }\n        const [g, s, b] = shuffle(ev.participants);\n        console.log(`  🥇 ${g.name} (${g.country})\\n  🥈 ${s.name} (${s.country})\\n  🥉 ${b.name} (${b.country})`);\n        addMedal(g.country, \"gold\"); addMedal(s.country, \"silver\"); addMedal(b.country, \"bronze\");\n    }\n}\n\nfunction showReport(): void {\n    console.log(\"\\n== INFORME FINAL ==\");\n    if (!medalTable.size) { console.log(\"Sin resultados.\"); return; }\n    [...medalTable.entries()]\n        .map(([c, m]) => ({ c, ...m, t: m.gold + m.silver + m.bronze }))\n        .sort((a, b) => b.gold - a.gold || b.silver - a.silver || b.bronze - a.bronze)\n        .forEach((x, i) => console.log(`${i + 1}. ${x.c.padEnd(20)} Oro:${x.gold} Plata:${x.silver} Bronce:${x.bronze} Total:${x.t}`));\n}\n\nasync function main(): Promise<void> {\n    while (true) {\n        console.log(\"\\n====== SIMULADOR JJOO ======\\n1. Registrar evento\\n2. Registrar participante\\n3. Simular\\n4. Informe\\n5. Salir\");\n        const opt = (await ask(\"Opción: \")).trim();\n        if (opt === \"1\") await registerEvent();\n        else if (opt === \"2\") await registerParticipant();\n        else if (opt === \"3\") simulateEvents();\n        else if (opt === \"4\") showReport();\n        else if (opt === \"5\") { console.log(\"Hasta luego!\"); rl.close(); break; }\n        else console.log(\"Invalido.\");\n    }\n}\n\nmain();\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/vb.net/kenysdev.vb",
    "content": "' ╔══════════════════════════════════════╗\n' ║ Autor:  Kenys Alvarado               ║\n' ║ GitHub: https://github.com/Kenysdev  ║\n' ║ 2024 -  VB.NET                       ║\n' ╚══════════════════════════════════════╝\n'-----------------------------------------------------\n'* SIMULADOR JUEGOS OLÍMPICOS\n'-----------------------------------------------------\n\n'* EJERCICIO\n'* ¡Los JJOO de París 2024 han comenzado!\n'* Crea un programa que simule la celebración de los juegos.\n'* El programa debe permitir al usuario registrar eventos y participantes,\n'* realizar la simulación de los eventos asignando posiciones de manera aleatoria\n'* y generar un informe final. Todo ello por terminal.\n' * Requisitos:\n' * 1. Registrar eventos deportivos.\n' * 2. Registrar participantes por nombre y país.\n' * 3. Simular eventos de manera aleatoria en base a los participantes (mínimo 3).\n' * 4. Asignar medallas (oro, plata y bronce) basándose en el resultado del evento.\n' * 5. Mostrar los ganadores por cada evento.\n' * 6. Mostrar el ranking de países según el número de medallas.\n' * Acciones:\n' * 1. Registro de eventos.\n' * 2. Registro de participantes.\n' * 3. Simulación de eventos.\n' * 4. Creación de informes.\n' * 5. Salir del programa.\n\n' _________________\n'' NOTA: Esto es un intento de aplicar los principios SOLID.\n\nImports System.Text\n\n'''<summary>Contrato sobre las constantes globales.</summary>\nPublic Interface IConstants\n    Function GetMenu() As String\n    Function GetMedals() As String()\nEnd Interface\n\n' ____________________________________________________\n'' CONTRATOS para la capa de datos.\n''' <summary>\n''' Contrato sobre los métodos requeridos para cada tabla creada.\n''' </summary>\nPublic Interface IDataTable(Of T)\n    Sub Add(item As T)\n\n    ''' <returns>El número de elementos.</returns>\n    Function Count() As Integer\n\n    ''' <returns>Una lista de elementos.</returns>\n    Function GetList() As List(Of T)\nEnd Interface\n\n''' <summary>\n''' Define un contrato para implementar diferentes formas de almacenamiento de datos.\n''' </summary>\nPublic Interface IData\n    ReadOnly Property EventsTable As IDataTable(Of String)\n    ReadOnly Property ParticipantsTable As IDataTable(Of (Name As String, Country As String, EventId As Integer))\n    ReadOnly Property SimulationTable As IDataTable(Of SimulationType)\nEnd Interface\n\n''' <summary>\n''' Define una estructura para representar los datos en una simulación.\n''' </summary>\nPublic Structure SimulationType\n    Public Property Events As List(Of (EventName As String, Results As List(Of (Name As String, Country As String, EventId As Integer, Score As Integer, Medal As String))))\n\n    Public Sub New(events As List(Of (EventName As String, Results As List(Of (Name As String, Country As String, EventId As Integer, Score As Integer, Medal As String)))))\n        Me.Events = events\n    End Sub\nEnd Structure\n\n''' <summary>\n''' Define el contrato para la entrada de datos del usuario.\n''' </summary>\nPublic Interface IInput\n    ''' <returns>Una cadena no vacía.</returns>\n    Function GetStr(msg As String) As String\n    ''' <returns>Un número entero.</returns>\n    Function GetInt(msg As String) As Integer\nEnd Interface\n\n' ____________________________________________________\n' CONTRATOS sobre la comunicación entre la interacción del usuario y la capa de datos.\nPublic Interface IEvents\n    Sub Add()\nEnd Interface\n\nPublic Interface IParticipants\n    Sub Add()\nEnd Interface\n\nPublic Interface ISimulations\n    Sub Start()\nEnd Interface\n\nPublic Interface IReports\n    Sub Generate()\nEnd Interface\n\n' ____________________________________________________\n' IMPLEMENTAR CONTRATOS\n\n' ____________________________________________________\nPublic Class DefaultConstants\n    Implements IConstants\n\n    Private Const Menu As String = \"\nSIMULADOR JUEGOS OLÍMPICOS:\n--------------------------------------------------\n| 1. Registrar evento        | 4. Crear informes |  \n| 2. Registrar participante  | 5. Salir          |\n| 3. Simulación de eventos   |                   |\n--------------------------------------------------\n\"\n\n    Private Shared ReadOnly Medals As String() = {\"🥇 Oro\", \"🥈 Plata\", \"🥉 Bronce\"}\n\n    Public Function GetMenu() As String Implements IConstants.GetMenu\n        Return Menu\n    End Function\n\n    Public Function GetMedals() As String() Implements IConstants.GetMedals\n        Return Medals\n    End Function\nEnd Class\n\n''' <summary>\n''' Implementación de <see cref=\"IDataTable(Of String)\"/> para la tabla de eventos.\n''' </summary>\nPublic Class EventsTable\n    Implements IDataTable(Of String)\n\n    Private ReadOnly dt As New List(Of String)()\n\n    Public Sub Add(sport As String) Implements IDataTable(Of String).Add\n        dt.Add(sport)\n    End Sub\n\n    Public Function Count() As Integer Implements IDataTable(Of String).Count\n        Return dt.Count\n    End Function\n\n    Public Function GetList() As List(Of String) Implements IDataTable(Of String).GetList\n        Return New List(Of String)(dt)\n    End Function\nEnd Class\n\n''' <summary>\n''' Implementación de <see cref=\"IDataTable(Of (String, String))\"/> para la tabla de participantes.\n''' </summary>\nPublic Class ParticipantsTable\n    Implements IDataTable(Of (String, String, Integer))\n\n    Private ReadOnly dt As New List(Of (String, String, Integer))()\n\n    Public Sub Add(participant As (String, String, Integer)) Implements IDataTable(Of (String, String, Integer)).Add\n        dt.Add(participant)\n    End Sub\n\n    Public Function Count() As Integer Implements IDataTable(Of (String, String, Integer)).Count\n        Return dt.Count\n    End Function\n\n    Public Function GetList() As List(Of (String, String, Integer)) Implements IDataTable(Of (String, String, Integer)).GetList\n        Return New List(Of (String, String, Integer))(dt)\n    End Function\nEnd Class\n\n''' <summary>\n''' Implementación de <see cref=\"IDataTable(Of Types.SimulationResult)\"/> para la tabla de simulaciones.\n''' </summary>\nPublic Class SimulationTable\n    Implements IDataTable(Of SimulationType)\n\n    Private ReadOnly dt As New List(Of SimulationType)()\n\n    Public Sub Add(item As SimulationType) Implements IDataTable(Of SimulationType).Add\n        dt.Add(item)\n    End Sub\n\n    Public Function Count() As Integer Implements IDataTable(Of SimulationType).Count\n        Return dt.Count\n    End Function\n\n    Public Function GetList() As List(Of SimulationType) Implements IDataTable(Of SimulationType).GetList\n        Return dt\n    End Function\nEnd Class\n\n\n' ____________________________________________________\n''' <summary>\n''' Datos en memoria aplicando el patrón Singleton.\n''' </summary>\nPublic Class DataInMemory\n    Implements IData\n    Private Shared _instance As DataInMemory\n\n    ''' <summary>\n    ''' Obtiene la instancia única de <see cref=\"DataInMemory\"/>.\n    ''' </summary>\n    Public Shared ReadOnly Property Instance As DataInMemory\n        Get\n            If _instance Is Nothing Then\n                _instance = New DataInMemory()\n            End If\n            Return _instance\n        End Get\n    End Property\n\n    Public ReadOnly Property EventsTable As IDataTable(Of String) Implements IData.EventsTable\n    Public ReadOnly Property ParticipantsTable As IDataTable(Of (String, String, Integer)) Implements IData.ParticipantsTable\n    Public ReadOnly Property SimulationTable As IDataTable(Of SimulationType) Implements IData.SimulationTable\n\n    Private Sub New()\n        EventsTable = New EventsTable()\n        ParticipantsTable = New ParticipantsTable()\n        SimulationTable = New SimulationTable()\n    End Sub\nEnd Class\n\n' ____________________________________________________\n''' <summary>\n''' Muestra un mensaje al usuario y devuelve su entrada.\n''' </summary>\nPublic Class Input\n    Implements IInput\n\n    Public Function GetStr(msg As String) As String Implements IInput.GetStr\n        While True\n            Console.Write(msg)\n            Dim txt As String = Console.ReadLine()\n            If Not String.IsNullOrEmpty(txt) Then\n                Return txt\n            End If\n        End While\n        Return Nothing\n    End Function\n\n    Public Function GetInt(msg As String) As Integer Implements IInput.GetInt\n        While True\n            Console.Write(msg)\n            Dim txt As String = Console.ReadLine()\n            Dim input As Integer\n            If Integer.TryParse(txt, input) Then\n                Return input\n            Else\n                Console.WriteLine(\"Ingresa un número entero.\")\n            End If\n        End While\n        Return Nothing\n    End Function\nEnd Class\n\n' ____________________________________________________\n''' <summary>\n''' 1. Registrar eventos deportivos.\n''' </summary>\nPublic Class Events\n    Implements IEvents\n\n    Private ReadOnly _data As IData\n    Private ReadOnly _input As IInput\n\n    Public Sub New(data As IData, input As IInput)\n        _data = data\n        _input = input\n    End Sub\n\n    Public Sub Add() Implements IEvents.Add\n        Console.WriteLine(\"AGREGAR EVENTO DEPORTIVO:\")\n        Dim sport As String = _input.GetStr(\"Deporte: \")\n        _data.EventsTable.Add(sport)\n        Console.WriteLine($\"{sport} fue agregado\")\n        'Console.WriteLine(_constants.GetMenu())\n    End Sub\nEnd Class\n\n' ____________________________________________________\n''' <summary>\n''' 2. Registrar participantes por nombre y país.\n''' </summary>\nPublic Class Participants\n    Implements IParticipants\n\n    Private ReadOnly _constants As IConstants\n    Private ReadOnly _data As IData\n    Private ReadOnly _input As IInput\n\n    Public Sub New(constants As IConstants, data As IData, input As IInput)\n        _constants = constants\n        _data = data\n        _input = input\n    End Sub\n\n    Private Function GetEventId() As Integer\n        Console.WriteLine(\"Seleccionar el evento donde participará:\")\n        Dim events = _data.EventsTable.GetList()\n\n        For i As Integer = 0 To events.Count - 1\n            Console.WriteLine($\"{i}. {events(i)}\")\n        Next\n\n        While True\n            Dim index As Integer = _input.GetInt(\"Id de evento: \")\n            If index < 0 OrElse index >= events.Count Then\n                Console.WriteLine(vbCrLf & \"Id no encontrada.\")\n            Else\n                Return index\n            End If\n        End While\n        Return 0\n    End Function\n\n    Public Sub Add() Implements IParticipants.Add\n        Console.WriteLine(\"AGREGAR PARTICIPANTE:\")\n        Dim events = _data.EventsTable.GetList()\n        If Not events.Count > 0 Then\n            Console.WriteLine(\"No existe evento en cuál participar.\")\n            Return\n        End If\n\n        Dim eventId As Integer = GetEventId()\n        Dim name As String = _input.GetStr(\"Nombre: \")\n        Dim country As String = _input.GetStr(\"país: \")\n        _data.ParticipantsTable.Add((name, country, eventId))\n        Console.WriteLine($\"{name} fue agregado\")\n        Console.WriteLine(_constants.GetMenu())\n    End Sub\nEnd Class\n\n' ____________________________________________________\n''' <summary>\n''' 3. Simular eventos de manera aleatoria en base a los participantes (mínimo 3).\n''' 4. Asignar medallas (oro, plata y bronce) basándose en el resultado del evento.\n''' </summary>\nPublic Class Simulation\n    Implements ISimulations\n\n    Private ReadOnly constants As IConstants\n    Private Shared ReadOnly _random As New Random()\n    Private ReadOnly data As IData\n\n    Public Sub New(constants As IConstants, data As IData)\n        Me.constants = constants\n        Me.data = data\n    End Sub\n\n    Private Function QualifyParticipants(eventId As Integer) As List(Of List(Of Object))\n        Dim participants = data.ParticipantsTable.GetList()\n\n        ' Seleccionar solo los participantes que tienen el ID del evento.\n        Dim ParticipantsOfEvent = participants.Where(Function(p) p.EventId = eventId).ToList()\n        Dim qualifiedParticipants = ParticipantsOfEvent.Select(Function(p)\n                                                                   Dim list As New List(Of Object) From {\n                                                                p.Name,\n                                                                p.Country,\n                                                                p.EventId,\n                                                                _random.Next(1, 101)\n                                                            }\n                                                                   Return list\n                                                               End Function).ToList()\n\n        qualifiedParticipants = qualifiedParticipants.OrderByDescending(Function(p) CInt(p(3))).ToList()\n\n        Dim top3Participants = qualifiedParticipants.Take(3).ToList()\n\n        Dim medals = constants.GetMedals()\n        For i As Integer = 0 To top3Participants.Count - 1\n            top3Participants(i).Add(medals(i))\n        Next\n\n        Return top3Participants\n    End Function\n\n    Private Sub AddResultEvents()\n        Dim events = data.EventsTable.GetList()\n        Dim allEvents As New List(Of (EventName As String, Results As List(Of (Name As String, Country As String, EventId As Integer, Score As Integer, Medal As String))))\n\n        For id As Integer = 0 To events.Count - 1\n            Dim qualifiedParticipants = QualifyParticipants(id)\n            Dim eventResult = qualifiedParticipants.Select(Function(p)\n                                                               Return (\n                                                          Name:=If(p(0)?.ToString(), String.Empty),\n                                                          Country:=If(p(1)?.ToString(), String.Empty),\n                                                          EventId:=CInt(p(2)),\n                                                          Score:=CInt(p(3)),\n                                                          Medal:=If(p(4)?.ToString(), String.Empty)\n                                                      )\n                                                           End Function).ToList()\n\n            allEvents.Add((EventName:=events(id), Results:=eventResult))\n        Next\n\n        ' Agregar una nueva simulación con todos los eventos\n        Dim simulation As New SimulationType(allEvents)\n        data.SimulationTable.Add(simulation)\n    End Sub\n\n    Public Sub Start() Implements ISimulations.Start\n        If data.EventsTable.Count() >= 1 AndAlso data.ParticipantsTable.Count() >= 3 Then\n            AddResultEvents()\n            Dim totalSimulation = data.SimulationTable.Count()\n            Console.WriteLine($\"Simulación '#{totalSimulation}' creada.\")\n            Console.WriteLine(\"Puedes ver el resultado con opción: '4. Crear informes.'\")\n            'Console.WriteLine(GlobalConstants.Menu)\n        Else\n            Console.WriteLine(\"Debe haber al menos un evento y al menos 'tres' participantes.\")\n        End If\n    End Sub\n\nEnd Class\n\n' ____________________________________________________\n''' <summary>\n''' 5. Mostrar los ganadores por cada evento.\n''' 6. Mostrar el ranking de países según el número de medallas.\n''' </summary>\nPublic Class Reports\n    Implements IReports\n\n    Private ReadOnly constants As IConstants\n    Private ReadOnly rankingCountries As New Dictionary(Of String, (Medals As Integer, CurrentScore As Integer))()\n    Private ReadOnly data As IData\n    Public Sub New(constants As IConstants, data As IData)\n        Me.constants = constants\n        Me.data = data\n    End Sub\n\n    Private Sub GenerateTopCountries()\n        Dim sortedRank = rankingCountries.OrderByDescending(Function(item) item.Value)\n\n        Dim i As Integer = 1\n        For Each entry In sortedRank\n            Dim name As String = entry.Key\n            Dim total As (Medals As Integer, CurrentScore As Integer) = entry.Value\n            Console.WriteLine($\"'{i}' - {name} -> Medallas: 🏅 {total.Medals} | Puntaje: 📊 {total.CurrentScore}\")\n            i += 1\n        Next\n    End Sub\n\n    Private Sub IterateParticipants(participants As List(Of (Name As String, Country As String, EventId As Integer, Score As Integer, Medal As String)))\n        For Each entry In participants.Select(Function(p, index) New With {\n            Key .Index = index + 1,\n            p.Name,\n            p.Country,\n            p.EventId,\n            p.Score,\n            p.Medal\n    })\n            Console.WriteLine($\"'{entry.Index}' - {entry.Name} - {entry.Country} -> Score: {entry.Score}, Medal: {entry.Medal}\")\n\n            ' Registrar para generar ranking de países por número de medallas\n            Dim value As (Medals As Integer, CurrentScore As Integer)\n            If rankingCountries.TryGetValue(entry.Country, value) Then\n                Dim medals As Integer = value.Medals\n                Dim currentScore As Integer = value.CurrentScore\n                rankingCountries(entry.Country) = (medals + 1, currentScore + entry.Score)\n            Else\n                rankingCountries(entry.Country) = (1, entry.Score)\n            End If\n        Next\n    End Sub\n\n    Private Sub IterateEvents(simulation As SimulationType)\n        For Each eventResult In simulation.Events\n            Console.WriteLine(vbCrLf + $\"Event: {eventResult.EventName}:\")\n            If eventResult.Results.Count < 3 Then\n                Console.WriteLine(\"Evento cancelado por falta de participantes.\")\n                Continue For\n            End If\n\n            IterateParticipants(eventResult.Results)\n        Next\n    End Sub\n\n    Public Sub Generate() Implements IReports.Generate\n        Dim simulations = data.SimulationTable.GetList()\n\n        If simulations.Count = 0 Then\n            Console.WriteLine(\"Aún no hay simulaciones creadas.\")\n            Return\n        End If\n\n        Dim i As Integer = 1\n        For Each Simulation In simulations\n            Console.WriteLine(vbCrLf + \"_______________\")\n            Console.WriteLine($\"Simulation {i}\")\n\n            ' Iterar sobre los eventos en cada simulación\n            IterateEvents(Simulation)\n\n            Console.WriteLine(vbCrLf + \"Ranking de países, según el número de medallas y puntaje:\")\n            GenerateTopCountries()\n            rankingCountries.Clear()\n\n            i += 1\n        Next\n\n        Console.WriteLine(constants.GetMenu())\n    End Sub\nEnd Class\n\n' ____________________________________________________\nPublic Class Features\n    Public Property Constants As IConstants\n    Public Property Data As IData\n    Public Property Input As IInput\n    Public Property Events As IEvents\n    Public Property Participants As IParticipants\n    Public Property Simulation As ISimulations\n    Public Property Reports As IReports\nEnd Class\n\n' ____________________________________________________\n''' <summary>\n''' Recibimos instancias con las características del programa que dependen de las interfaces.\n''' </summary>\nPublic Class Program\n    Private ReadOnly Ft As Features\n    Public Sub New(ft As Features)\n        Me.Ft = ft\n    End Sub\n\n    Public Sub Run()\n        Console.WriteLine(Ft.Constants.GetMenu())\n        While True\n            Dim option_ As String = Ft.Input.GetStr(vbCrLf & \"Opción: \")\n            Select Case option_\n                Case \"1\"\n                    Ft.Events.Add()\n                Case \"2\"\n                    Ft.Participants.Add()\n                Case \"3\"\n                    Ft.Simulation.Start()\n                Case \"4\"\n                    Ft.Reports.Generate()\n                Case \"5\"\n                    Console.WriteLine(\"Adios\")\n                    Return\n                Case Else\n                    Console.WriteLine(\"Seleccionar de '1 a 5'\")\n            End Select\n        End While\n    End Sub\n\n    Public Shared Sub Main()\n        Console.OutputEncoding = Encoding.UTF8\n        Dim constants As IConstants = New DefaultConstants()\n        Dim data As IData = DataInMemory.Instance\n        Dim input As IInput = New Input()\n\n        Dim features As New Features With {\n            .Constants = constants,\n            .Data = data,\n            .Input = input,\n            .Events = New Events(data, input),\n            .Participants = New Participants(constants, data, input),\n            .Simulation = New Simulation(constants, data),\n            .Reports = New Reports(constants, data)\n        }\n\n        Dim program As New Program(features)\n        program.Run()\n    End Sub\nEnd Class\n\n' _________________\n'' NOTA: Esto es un intento de aplicar los principios SOLID.\n\n"
  },
  {
    "path": "Roadmap/31 - SIMULADOR JUEGOS OLÍMPICOS/vb.net/sisaroot.vb",
    "content": "' #31 SIMULADOR JUEGOS OLÍMPICOS - SisaRoot\n\nImports System\nImports System.Collections.Generic\nImports System.Linq\n\nModule SisaRoot\n\n    Class Participant\n        Property Name As String\n        Property Country As String\n        Sub New(n As String, c As String) : Name=n : Country=c : End Sub\n    End Class\n\n    Class OlympicEvent\n        Property Name As String\n        Property Participants As New List(Of Participant)\n        Sub New(n As String) : Name=n : End Sub\n    End Class\n\n    Class Medals\n        Property Country As String\n        Property Gold As Integer = 0\n        Property Silver As Integer = 0\n        Property Bronze As Integer = 0\n        ReadOnly Property Total As Integer\n            Get : Return Gold+Silver+Bronze : End Get\n        End Property\n        Sub New(c As String) : Country=c : End Sub\n    End Class\n\n    Dim events As New List(Of OlympicEvent)\n    Dim medalTable As New Dictionary(Of String, Medals)\n    Dim rng As New Random()\n\n    Sub AddMedal(c As String, t As String)\n        If Not medalTable.ContainsKey(c) Then medalTable(c) = New Medals(c)\n        Select Case t\n            Case \"gold\"   : medalTable(c).Gold   += 1\n            Case \"silver\" : medalTable(c).Silver += 1\n            Case Else     : medalTable(c).Bronze += 1\n        End Select\n    End Sub\n\n    Sub RegisterEvent()\n        Console.Write(\"Nombre del evento: \")\n        Dim name As String = Console.ReadLine()?.Trim()\n        If String.IsNullOrEmpty(name) Then Console.WriteLine(\"Invalido.\") : Return\n        If events.Any(Function(e) String.Equals(e.Name,name,StringComparison.OrdinalIgnoreCase)) Then Console.WriteLine(\"Ya existe.\") : Return\n        events.Add(New OlympicEvent(name))\n        Console.WriteLine($\"Evento '{name}' registrado.\")\n    End Sub\n\n    Sub RegisterParticipant()\n        If events.Count=0 Then Console.WriteLine(\"No hay eventos.\") : Return\n        For i=0 To events.Count-1 : Console.WriteLine($\"  {i+1}. {events(i).Name}\") : Next\n        Console.Write(\"Número: \")\n        Dim idx As Integer\n        If Not Integer.TryParse(Console.ReadLine()?.Trim(),idx) OrElse idx<1 OrElse idx>events.Count Then Console.WriteLine(\"Invalido.\") : Return\n        Dim ev = events(idx-1)\n        Console.Write(\"Nombre: \") : Dim pname = Console.ReadLine()?.Trim()\n        Console.Write(\"País: \")   : Dim country = Console.ReadLine()?.Trim()\n        ev.Participants.Add(New Participant(pname,country))\n        Console.WriteLine($\"'{pname} ({country})' añadido a '{ev.Name}'.\")\n    End Sub\n\n    Sub SimulateEvents()\n        If events.Count=0 Then Console.WriteLine(\"No hay eventos.\") : Return\n        For Each ev In events\n            Console.WriteLine($\"{Environment.NewLine}=== Simulando: {ev.Name} ===\")\n            If ev.Participants.Count<3 Then Console.WriteLine(\"  Necesita >=3. Saltando.\") : Continue For\n            Dim s = ev.Participants.OrderBy(Function(_) rng.Next()).ToList()\n            Console.WriteLine($\"  Oro:    {s(0).Name} ({s(0).Country})\")\n            Console.WriteLine($\"  Plata:  {s(1).Name} ({s(1).Country})\")\n            Console.WriteLine($\"  Bronce: {s(2).Name} ({s(2).Country})\")\n            AddMedal(s(0).Country,\"gold\") : AddMedal(s(1).Country,\"silver\") : AddMedal(s(2).Country,\"bronze\")\n        Next\n    End Sub\n\n    Sub ShowReport()\n        Console.WriteLine(Environment.NewLine & \"== INFORME FINAL ==\")\n        If medalTable.Count=0 Then Console.WriteLine(\"Sin resultados.\") : Return\n        Dim ranking = medalTable.Values.OrderByDescending(Function(c) c.Gold).ThenByDescending(Function(c) c.Silver).ThenByDescending(Function(c) c.Bronze).ToList()\n        For i=0 To ranking.Count-1\n            Dim c = ranking(i)\n            Console.WriteLine($\"{i+1}. {c.Country.PadRight(20)} Oro:{c.Gold} Plata:{c.Silver} Bronce:{c.Bronze} Total:{c.Total}\")\n        Next\n    End Sub\n\n    Sub Main()\n        While True\n            Console.WriteLine(Environment.NewLine & \"====== SIMULADOR JJOO ======\")\n            Console.WriteLine(\"1. Registrar evento\" & Environment.NewLine & \"2. Registrar participante\" & Environment.NewLine & \"3. Simular\" & Environment.NewLine & \"4. Informe\" & Environment.NewLine & \"5. Salir\")\n            Console.Write(\"Opción: \")\n            Select Case Console.ReadLine()?.Trim()\n                Case \"1\" : RegisterEvent()\n                Case \"2\" : RegisterParticipant()\n                Case \"3\" : SimulateEvents()\n                Case \"4\" : ShowReport()\n                Case \"5\" : Console.WriteLine(\"Hasta luego!\") : Return\n                Case Else : Console.WriteLine(\"Invalido.\")\n            End Select\n        End While\n    End Sub\n\nEnd Module\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/Jotarose.py",
    "content": "\"\"\"\r\nPrograma que simula una pelea y determina un ganador\r\n- Simula un combate por turnos\r\n\r\nPersonaje (2)\r\n- Puntos de vida iniciales (1000 puntos)\r\n\r\n- Daño de ataque variable\r\n    - Deadpool: entre 10 y 100 puntos\r\n    - Wolverine: entre 10 y 120 puntos\r\n    - Si el daño que ejecuta el atacante es maximo, le vuelve a tocar en el turno siguiente atacar.\r\n        - El oponente se tiene que regenerar, pero sin aumentar vida\r\n\r\n- Regeneracion\r\n- Evasión de ataques\r\n    - Deadpool: 25% de posibilidades\r\n    - Wolverine: 20% de posibilidades\r\n\r\n- Un personaje pierde si sus puntos de vida llegan a cero o menos.\r\n\r\nAcciones:\r\n1. Simula una batalla\r\n2. Muestra el numero del turno (pausa de 1 segundo entre turnos)\r\n3. Muestra que pasa en cada turno\r\n4. Muestra la vida en cada turno\r\n5. Muestra el resultado final\r\n\"\"\"\r\n\r\nimport random\r\nfrom abc import ABC, abstractmethod\r\nfrom time import sleep\r\n\r\n\r\nclass Hero(ABC):\r\n    @abstractmethod\r\n    def __init__(self):\r\n        pass\r\n\r\n    @abstractmethod\r\n    def attack(self, turn_counter: int) -> int:\r\n        pass\r\n\r\n    @abstractmethod\r\n    def evade(self) -> bool:\r\n        pass\r\n\r\n\r\nclass Deadpool(Hero):\r\n    def __init__(self):\r\n        self.name = \"Deadpool\"\r\n        self.health = 1000\r\n        self.min_damage = 10\r\n        self.max_damage = 100\r\n        self.prob_evade = 25\r\n        self.special_attack_turn = 3\r\n\r\n    def attack(self, turn_counter: int) -> int:\r\n        \"\"\"\r\n        Calcula el daño de un ataque generando un número aleatorio.\r\n        - Si el turno es multiplo de 3, ejecuta un ataque especial con el máximo de daño.\r\n\r\n        Returns:\r\n            int: Puntos de daño infligidos (entre 10 y 100).\r\n        \"\"\"\r\n\r\n        if turn_counter % self.special_attack_turn == 0:\r\n            return self.max_damage\r\n        else:\r\n            return random.randint(self.min_damage, self.max_damage)\r\n\r\n    def evade(self) -> bool:\r\n        \"\"\"\r\n        Decide si el personaje evade el ataque del oponente en función de su porcentaje de evasión.\r\n\r\n        Returns:\r\n            bool: True si evade el ataque, False si no lo hace.\r\n        \"\"\"\r\n        prob_evasion = random.randint(1, 100)\r\n\r\n        if prob_evasion <= self.prob_evade:\r\n            return True\r\n        else:\r\n            return False\r\n\r\n    def __str__(self) -> str:\r\n        \"\"\"\r\n        Retorna el estado del personaje\r\n\r\n        Returns:\r\n            str: Estado del personaje\r\n        \"\"\"\r\n        return f\"{self.name} tiene una vida de {self.health} puntos.\"\r\n\r\n\r\nclass Wolverine(Hero):\r\n    def __init__(self):\r\n        self.name = \"Wolverine\"\r\n        self.health = 1000\r\n        self.min_damage = 10\r\n        self.max_damage = 120\r\n        self.prob_evade = 20\r\n        self.special_attack_turn = 4\r\n\r\n    def attack(self, turn_counter: int) -> int:\r\n        if turn_counter % self.special_attack_turn == 0:\r\n            return self.max_damage\r\n        else:\r\n            return random.randint(self.min_damage, self.max_damage)\r\n\r\n    def evade(self) -> bool:\r\n        prob_evasion = random.randint(1, 100)\r\n\r\n        if prob_evasion <= self.prob_evade:\r\n            return True\r\n        else:\r\n            return False\r\n\r\n    def __str__(self) -> str:\r\n        return f\"{self.name} tiene una vida de {self.health} puntos.\"\r\n\r\n\r\nclass View:\r\n    def display_msg(self, msg: str):\r\n        print(msg)\r\n\r\n    def display_err(self, err: str):\r\n        print(f\"\\nERROR: {err}\")\r\n\r\n\r\nclass Fight:\r\n    def __init__(self, deadpool: Hero, wolverine: Hero, view: View):\r\n        self.deadpool = deadpool\r\n        self.wolverine = wolverine\r\n        self.view = view\r\n        self.turn_counter = 0\r\n\r\n    def who_starts(self) -> Hero:\r\n        \"\"\"\r\n        Sirve para elegir que personaje comienza atacando en la batalla.\r\n\r\n        Returns:\r\n            Hero,Hero: Retorna el primero el que empieza atacando y seguido el que empieza defendiendo.\r\n        \"\"\"\r\n        result = random.randint(1, 2)\r\n        if result == 1:\r\n            first = self.deadpool\r\n            second = self.wolverine\r\n            return first, second\r\n\r\n        else:\r\n            first = self.wolverine\r\n            second = self.deadpool\r\n            return first, second\r\n\r\n    def _execute_attack(self, first_opp: Hero, second_opp: Hero, first_opp_damage: int) -> bool:\r\n        \"\"\"\r\n        Ejecuta un ataque de un heroe.\r\n\r\n        Returns:\r\n            bool: retorna True si el ataque fue máximo, False si no lo fue\r\n        \"\"\"\r\n        self.view.display_msg(\r\n            f\"- {first_opp.name} lanzo un ataque de {first_opp_damage} puntos de daño\"\r\n        )\r\n\r\n        if first_opp_damage == first_opp.max_damage:\r\n            second_opp.health -= first_opp_damage\r\n\r\n            self.view.display_msg(f\"\\t- {first_opp.name} uso su ataque con el máximo daño posible.\")\r\n            self.view.display_msg(\r\n                f\"\\t- {second_opp.name} no puede atacar, se esta recuperando del daño sufrido.\"\r\n            )\r\n            self.view.display_msg(f\"\\t- {second_opp}\\n\")\r\n\r\n            return True\r\n\r\n        else:\r\n            if second_opp.evade():\r\n                self.view.display_msg(f\"\\t- {second_opp.name} esquivo el ataque.\")\r\n                self.view.display_msg(f\"\\t- {second_opp}\\n\")\r\n\r\n            else:\r\n                second_opp.health -= first_opp_damage\r\n\r\n                self.view.display_msg(f\"\\t- {second_opp}\\n\")\r\n\r\n            return False\r\n\r\n    def turn(self, first_opponent: Hero, second_opponent: Hero) -> Hero:\r\n        \"\"\"\r\n        Desarrolla un turno de la batalla.\r\n        - Calcula los daños de los heroes\r\n        - Ejecuta la funcion de ataque\r\n\r\n        Returns:\r\n            Hero: retorna el siguiente orden de los oponentes.\r\n        \"\"\"\r\n        sleep(1)\r\n\r\n        self.turn_counter += 1\r\n        self.view.display_msg(f\"\\nComienza el turno: {self.turn_counter}.\")\r\n\r\n        # Calculo los daños de los ataques en funcion de los turnos\r\n        first_opponent_damage = first_opponent.attack(self.turn_counter)\r\n        second_opponent_damage = second_opponent.attack(self.turn_counter)\r\n\r\n        # Ataca el primer oponente\r\n        max_attack_result = self._execute_attack(\r\n            first_opponent, second_opponent, first_opponent_damage\r\n        )\r\n        if max_attack_result:\r\n            return first_opponent, second_opponent\r\n\r\n        if second_opponent.health <= 0:\r\n            return first_opponent, second_opponent\r\n\r\n        # Ataca el segundo oponente\r\n        max_attack_result = self._execute_attack(\r\n            second_opponent, first_opponent, second_opponent_damage\r\n        )\r\n        if max_attack_result:\r\n            return second_opponent, first_opponent\r\n\r\n        return first_opponent, second_opponent\r\n\r\n\r\ndef main():\r\n    deadpool = Deadpool()\r\n    wolverine = Wolverine()\r\n    view = View()\r\n    fight = Fight(deadpool, wolverine, view)\r\n\r\n    view.display_msg(\"\\nBATALLA ENTRE DEADPOOL Y WOLVERINE\")\r\n\r\n    first_opponent, second_opponent = fight.who_starts()\r\n\r\n    while first_opponent.health > 0 and second_opponent.health > 0:\r\n        first_opponent, second_opponent = fight.turn(first_opponent, second_opponent)\r\n\r\n    if first_opponent.health <= 0 and second_opponent.health > 0:\r\n        view.display_msg(f\"\\n{second_opponent.name} ha ganado la batalla.\")\r\n\r\n    elif second_opponent.health <= 0 and first_opponent.health > 0:\r\n        view.display_msg(f\"\\n{first_opponent.name} ha ganado la batalla.\")\r\n\r\n\r\nif __name__ == \"__main__\":\r\n    main()\r\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/c#/deathwing696.cs",
    "content": "/*\n * EJERCICIO:\n * ¡Deadpool y Wolverine se enfrentan en una batalla épica!\n * Crea un programa que simule la pelea y determine un ganador.\n * El programa simula un combate por turnos, donde cada protagonista posee unos\n * puntos de vida iniciales, un daño de ataque variable y diferentes cualidades\n * de regeneración y evasión de ataques.\n * Requisitos:\n * 1. El usuario debe determinar la vida inicial de cada protagonista.\n * 2. Cada personaje puede impartir un daño aleatorio:\n *    - Deadpool: Entre 10 y 100.\n *    - Wolverine: Entre 10 y 120.\n * 3. Si el daño es el máximo, el personaje que lo recibe no ataca en el\n * siguiente turno, ya que tiene que regenerarse (pero no aumenta vida).\n * 4. Cada personaje puede evitar el ataque contrario:\n *    - Deadpool: 25% de posibilidades.\n *    - Wolverine: 20% de posibilidades.\n * 5. Un personaje pierde si sus puntos de vida llegan a cero o menos.\n * Acciones:\n * 1. Simula una batalla.\n * 2. Muestra el número del turno (pausa de 1 segundo entre turnos).\n * 3. Muestra qué pasa en cada turno.\n * 4. Muestra la vida en cada turno.\n * 5. Muestra el resultado final.\n */\n\nusing System;\nusing System.CodeDom;\nusing System.Collections.Generic;\nusing System.Security.Cryptography;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nnamespace deathwing696\n{\n    public class deathwing696\n    {\n        public class Wolverine\n        {\n            private int hp;\n            private readonly int attack_min;\n            private readonly int attack_max;\n            private bool isMaxAttack;\n\n            public int HP { get { return hp; } }\n            public bool IsMaxAttack { get { return isMaxAttack; } }\n\n            public Wolverine(int hp)\n            {\n                this.hp = hp;\n                this.attack_min = 10;\n                this.attack_max = 120;\n            }\n\n            public int Attack()\n            {                \n                Random random = new Random();\n                int attack = random.Next(attack_min, attack_max);\n\n                if (attack == this.attack_max)\n                    this.isMaxAttack = true;\n                else\n                    this.isMaxAttack = false;\n\n                return attack;\n            }\n\n            public bool Dodge()\n            {\n                Random random = new Random();\n                int prob = random.Next(1, 5);\n\n                return prob == 1;\n            }\n\n            public bool RecievesDamage(int damage)\n            {\n                this.hp -= damage;\n\n                return this.hp <= 0;\n            }\n        }\n        public class Deadpool\n        {\n            private int hp;\n            private readonly int attack_min = 10;\n            private readonly int attack_max = 100;\n            private bool isMaxAttack = false;\n\n            public int HP { get { return hp; } }\n\n            public bool IsMaxAttack { get { return isMaxAttack; } }\n\n            public Deadpool(int hp) \n            {\n                this.hp = hp;\n            }\n\n            public int Attack()\n            {\n                Random random = new Random();\n                int attack = random.Next(attack_min, attack_max);\n\n                if (attack == this.attack_max)\n                    this.isMaxAttack = true;\n                else\n                    this.isMaxAttack = false;\n\n                return attack;\n            }\n\n            public bool Dodge()\n            {\n                Random random = new Random();\n                int prob = random.Next(1, 4);\n\n                return prob == 1;\n            }\n\n            public bool RecievesDamage(int damage)\n            {\n                this.hp -= damage;\n\n                return this.hp <= 0;\n            }\n\n        }\n        \n        static void Main(string[] args)\n        {\n            Console.Write(\"Introduce la vida de Wolverine:\");\n            int wolverineHP = Int16.Parse(Console.ReadLine());\n            Console.Write(\"Introduce la vida de Deadpool:\");\n            int deadPoolHP = Int16.Parse(Console.ReadLine());\n            Wolverine wolverine = new Wolverine(wolverineHP);\n            Deadpool deadpool = new Deadpool(deadPoolHP);\n            var turno = 0;\n            var esCritico = false;\n\n            while (wolverine.HP > 0 && deadpool.HP > 0)\n            {\n                Console.WriteLine($\"\\nTurno {++turno}\");\n\n                if (!esCritico && deadpool.HP > 0) // Turno de Deadpool si el ataque de Wolverine no ha sido crítico\n                {\n                    var deadpoolDamage = deadpool.Attack();\n                    esCritico = deadpool.IsMaxAttack;\n\n                    if (!wolverine.Dodge())\n                    {\n                        wolverine.RecievesDamage(deadpoolDamage);\n                        Console.WriteLine($\"Deadpool ataca a Wolverine y le hace {deadpoolDamage} puntos de vida\");\n                    }\n                    else\n                    {\n                        Console.WriteLine(\"Wolverine esquiva el ataque de Deadpool\");\n                    }\n                }\n                else if (esCritico)\n                {\n                    Console.WriteLine(\"Deadpool no atacará este turno porque se tiene que regenerar\");\n                    esCritico = false;\n                }\n\n                if (!esCritico && wolverine.HP > 0) //Turno de Wolverine si el ataque de Deadpool no ha sido crítico\n                {\n                    var wolverineDamage = wolverine.Attack();\n                    esCritico = wolverine.IsMaxAttack;\n\n                    if (!deadpool.Dodge())\n                    {\n                        deadpool.RecievesDamage(wolverineDamage);\n                        Console.WriteLine($\"Wolverine ataca a Deadpool y le hace {wolverineDamage} puntos de vida\");\n                    }\n                    else\n                    {\n                        Console.WriteLine(\"Deadpool esquiva el ataque de Wolverine\");\n                    }\n                }\n                else if (esCritico)\n                {\n                    Console.WriteLine(\"Wolverine no atacará este turno porque se tiene que regenerar\");\n                    esCritico = false;\n                }\n\n                Console.WriteLine($\"A Deadpool le quedan {deadpool.HP} puntos de vida\");\n                Console.WriteLine($\"A Wolverine le quedan {wolverine.HP} puntos de vida\");\n\n                Thread.Sleep(1000);\n            }\n\n            if (deadpool.HP <= 0)\n                Console.WriteLine(\"El ganador es WOLVERINE\");\n            else\n                Console.WriteLine(\"El ganador es DEADPOOL\");\n\n            Console.ReadKey();\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/c#/hequebo.cs",
    "content": "class DeadpoolVsWolverine\n{\n    static void Main(string[] args)\n    {\n        Hero hero1;\n        Hero hero2;\n        Random random = new Random();\n        Console.WriteLine(\"---SIMULADOR DE PELEA DEADPOOL VS WOLVERINE---\");\n        if (random.NextDouble() > 0.5)\n        {\n            Console.WriteLine(\"Establece la vida inicial de Deadpool\");\n            int hp = int.Parse(Console.ReadLine());\n            hero1 = new Hero(\"Deadpool\", hp, 10, 100, 0.25);\n            Console.WriteLine(\"Establece la vida inicial de Wolverine\");\n            hp = int.Parse(Console.ReadLine());\n            hero2 = new Hero(\"Wolverine\", hp, 10, 120, 0.20);\n\n        }\n        else\n        {\n            Console.WriteLine(\"Establece la vida inicial de Wolverine\");\n            int hp = int.Parse(Console.ReadLine());\n            hero1 = new Hero(\"Wolverine\", hp, 10, 120, 0.20);\n            Console.WriteLine(\"Establece la vida inicial de Deadpool\");\n            hp = int.Parse(Console.ReadLine());\n            hero2 = new Hero(\"Deadpool\", hp, 10, 100, 0.25);\n        }  \n        int turn = 0;   \n        \n        while(hero1.Hp > 0 && hero2.Hp > 0)\n        {\n            turn++;\n            Console.WriteLine($\"Turno {turn}\");\n            SimulateTurn(ref hero1 , ref hero2);\n            if (hero2.Hp > 0)\n                SimulateTurn(ref hero2 , ref hero1);\n            Thread.Sleep(1000);\n        }\n        Console.ReadLine();\n\n    }\n    static void SimulateTurn(ref Hero hero1, ref Hero hero2)\n    {\n        if (hero1.Regenarate)\n        {\n            Console.WriteLine($\"{hero1.Name} se está regenerando, no puede atacar este turno...\");\n        }\n        else\n        {\n            int attack = hero1.Attack();\n            Console.WriteLine($\"{hero1.Name} Ataca con {attack} puntos de daño\");\n            bool dogde = hero2.Dodge();\n            if (dogde)\n            {\n                Console.WriteLine($\"{hero2.Name} esquivó el ataque y no recibió daño...\");\n            }\n            else\n            {\n                hero2.TakeDamage(attack);\n                Console.WriteLine($\"{hero2.Name} recibe {attack} puntos de daño...\");\n                if (attack == hero1.MaxDamage)\n                {\n                    Console.WriteLine($\"Golpe crítico de {hero1.Name}, {hero2.Name} \" +\n                        $\"no podrá atacar el siguiente turno...\");\n                    hero2.Regenarate = true;\n                }\n                if (hero2.Hp <= 0)\n                {\n                    Console.WriteLine($\"La vida de {hero2.Name} ha llegado a 0...\");\n                    Console.WriteLine($\"{hero1.Name} ha ganado la pelea..\");\n                } \n                else\n                    Console.WriteLine($\"La salud de {hero2.Name} está en {hero2.Hp}hp...\");\n            }\n        }\n        hero1.Regenarate = false;\n    }\n}\n\nclass Hero\n{\n    private string _name;\n    private int _hp;\n    private int _minDamage;\n    private int _maxDamage;\n    private bool _regenarate;\n    private double _dodgeChances;\n\n    public string Name { get { return _name; } }\n    public int Hp { get { return _hp; } }\n    public int MaxDamage{  get { return _maxDamage; } }\n    public bool Regenarate\n    {\n        get => _regenarate;\n        set => _regenarate = value;\n    }\n\n    public Hero(string name, int hp, int minDamage, int maxDamage, double dodgeChances)\n    {\n        _name = name;\n        _hp = hp;\n        _minDamage = minDamage;\n        _maxDamage = maxDamage;\n        _regenarate = false;\n        _dodgeChances = dodgeChances;\n    }\n\n    public int Attack()\n    {\n        Random random = new Random();\n        return random.Next(_minDamage, _maxDamage + 1);\n    }\n    public void TakeDamage(int damage)\n    {\n        _hp -= damage;\n    }\n    public bool Dodge()\n    {\n        Random random = new Random();\n        if (random.NextDouble() > _dodgeChances)\n        {\n            return false;\n        }\n        return true;\n    }\n}\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/c#/kenysdev.cs",
    "content": "namespace exs32;\n/*\n╔══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado               ║\n║ GitHub: https://github.com/Kenysdev  ║\n║ 2024 -  C#                           ║\n╚══════════════════════════════════════╝\n-----------------------------------------------------\n* BATALLA DEADPOOL Y WOLVERINE\n-----------------------------------------------------\n\n * EJERCICIO:\n * ¡Deadpool y Wolverine se enfrentan en una batalla épica!\n * Crea un programa que simule la pelea y determine un ganador.\n * El programa simula un combate por turnos, donde cada protagonista posee unos\n * puntos de vida iniciales, un daño de ataque variable y diferentes cualidades\n * de regeneración y evasión de ataques.\n * Requisitos:\n * 1. El usuario debe determinar la vida inicial de cada protagonista.\n * 2. Cada personaje puede impartir un daño aleatorio:\n *    - Deadpool: Entre 10 y 100.\n *    - Wolverine: Entre 10 y 120.\n * 3. Si el daño es el máximo, el personaje que lo recibe no ataca en el\n * siguiente turno, ya que tiene que regenerarse (pero no aumenta vida).\n * 4. Cada personaje puede evitar el ataque contrario:\n *    - Deadpool: 25% de posibilidades.\n *    - Wolverine: 20% de posibilidades.\n * 5. Un personaje pierde si sus puntos de vida llegan a cero o menos.\n * Acciones:\n * 1. Simula una batalla.\n * 2. Muestra el número del turno (pausa de 1 segundo entre turnos).\n * 3. Muestra qué pasa en cada turno.\n * 4. Muestra la vida en cada turno.\n * 5. Muestra el resultado final.\n*/\nusing System.Text;\n\n// _____\n// NOTA: Estoy intentando practicar los principios SOLID. XD 😂\n\n// ---------------------------------------\n// INYECCIÓN DE DEPENDENCIAS\n// ---------------------------------------\n// _______________________________________\n/// <summary>Definirá las interfaces que requieren ser configuradas</summary>\npublic class Factory\n{\n    public required IGlobalConfig GlobalConfig { get; set; }\n    public required IInput Input { get; set; }\n    public required IBattleStrategy Strategy { get; set; }\n    public required ICharacter Character1 { get; set; }\n    public required ICharacter Character2 { get; set; }\n}\n\n// _______________________________________\n/// <summary>Recibe la inyección de dependencias</summary>\npublic class Program(Factory _factory, Simulation simulation)\n{\n    public static void Main()\n    {\n        Console.OutputEncoding = Encoding.UTF8;\n        Factory factory = ConfigureFactory();\n        Simulation simulation = new(factory);\n        Program program = new(factory, simulation);\n        program.Run();\n    }\n    public void Run()\n    {\n        Console.WriteLine(_factory.GlobalConfig.Menu);\n        while (true)\n        {\n            int option = _factory.Input.Get(\"\\nOpción: \");\n            switch (option)\n            {\n                case 1: simulation.Start(); break;\n                case 2: Console.WriteLine(\"Adios\"); return;\n                default: Console.WriteLine(\"Seleccionar de '1 a 5'\"); break;\n            }\n        }\n    }\n\n    /// <summary>Asignará y retornará las instancias de clases que dependen de las interfaces.</summary>\n    private static Factory ConfigureFactory()\n    {\n        return new Factory\n        {\n            GlobalConfig = new DefaultConfig(),\n            Input = new ConsoleInput(),\n            Strategy = new DefaultBattleStrategy(),\n            Character1 = new DefaultCharacter(),\n            Character2 = new DefaultCharacter()\n        };\n    }\n}\n\n// _______________________________________\n/// <summary>Realizar simulación de la batalla</summary>\npublic class Simulation(Factory factory)\n{\n    /// <summary>Agrega datos de los personajes</summary>\n    public void AddCharacter(string msg, ICharacter character)\n    {\n        while (true)\n        {\n            int index = factory.Input.Get(msg);\n            var keys = factory.GlobalConfig.Characters.Keys.ToList();\n\n            if (index < 0 || index >= keys.Count)\n            {\n                Console.WriteLine(\"Número de personaje incorrecto.\");\n                continue; // Volver a solicitar\n            }\n\n            if (keys[index] == factory.Character1.Name)\n            {\n                Console.WriteLine(\"El personaje ya fue utilizado.\");\n                continue;\n            }\n\n            int hp = factory.Input.Get($\"Establecer una vida >= que '{factory.GlobalConfig.MinimumHp}': \");\n            if (hp < factory.GlobalConfig.MinimumHp)\n            {\n                Console.WriteLine($\"La vida debe ser mayor o igual que '{factory.GlobalConfig.MinimumHp}'.\");\n                continue;\n            }\n\n            string name = keys[index];\n            TCharacterConfig attributes = factory.GlobalConfig.Characters[name];\n            character.Add(name, hp, attributes);\n            break;\n        }\n    }\n\n    public void ShowHp()\n    {\n        Console.WriteLine(\"____________________________\");\n        Console.WriteLine($\"|{factory.Character1.Name}: ❤️ {factory.Character1.Hp}| |{factory.Character2.Name}: ❤️ {factory.Character2.Hp}|\");\n    }\n\n    /// <summary>Llevará a cabo el turno de la batalla.</summary>\n    public void Battle()\n    {\n        int turn = 1;\n        while (true)\n        {\n            Console.WriteLine($\"\\n----------------------------\\nTurno #{turn}\\n----------------------------\");\n\n            // Ataque de personaje #1 hacia #2\n            ShowHp();\n            if (!factory.Strategy.Execute(factory.Character1, factory.Character2))\n            {\n                break;\n            }\n\n            // Ataque de personaje #2 hacia #1\n            ShowHp();\n            if (!factory.Strategy.Execute(factory.Character2, factory.Character1))\n            {\n                break;\n            }\n\n            turn++;\n            Thread.Sleep(factory.GlobalConfig.TurnInterval * 1000);\n        }\n\n        ShowHp();\n    }\n\n    public void Start()\n    {\n        Console.WriteLine(\"Personajes disponibles:\");\n        var characters = factory.GlobalConfig.Characters.Keys.ToList();\n        for (int i = 0; i < characters.Count; i++)\n        {\n            Console.WriteLine($\"{i}. {characters[i]}\");\n        }\n\n        AddCharacter(\"\\n'Primer' personaje: \", factory.Character1);\n\n        AddCharacter(\"'Segundo' personaje: \", factory.Character2);\n\n        Battle();\n\n        factory.Character1.Name = \"\";\n        Console.WriteLine(factory.GlobalConfig.Menu);\n    }\n}\n\n// ---------------------------------------\n// INTERFACES\n// ---------------------------------------\n// _______________________________________\n/// <summary>Contrato para la configuración global.</summary>\npublic interface IGlobalConfig\n{\n    /// <summary>Tiempo de espera en segundos entre cada turno.</summary>\n    int TurnInterval { get; }\n\n    /// <summary>Mínima cantidad de vida inicial permitida.</summary>\n    int MinimumHp { get; }\n\n    /// <summary>\n    /// Diccionario de personajes, con sus habilidades, Daño posible, Probabilidad de defensa.\n    /// {\"Character\": {\"attacks\": [\"Attack1\", \"Attack2\"], \"damage_range\": (10, 100), \"defense_chance\": 0.25}}\n    /// </summary>\n    IDictionary<string, TCharacterConfig> Characters { get; }\n\n    /// <summary>Acciones del menú principal.</summary>\n    string Menu { get; }\n}\n\n\n/// <summary>Tipos requeridos en el diccionario./// </summary>\npublic class TCharacterConfig\n{\n    public required List<string> Attacks { get; set; }\n    public (int Min, int Max) DamageRange { get; set; }\n    public double DefenseChance { get; set; }\n}\n\n// _______________________________________\n/// <summary> Contrato sobre la entra de datos.</summary>\npublic interface IInput\n{\n    /// <param name=\"msg\">Mensaje a mostrar al usuario.</param>\n    /// <returns>un dato entero que no debe ser vacio.</returns>\n    int Get(string msg);\n}\n\n// _______________________________________\n/// <summary> Contrato sobre los datos y metodos de un personaje que participara en la batalla.</summary>\npublic interface ICharacter\n{\n    // Propiedades\n    string Name { get; set; }\n    int Hp { get; set; }\n    bool CanAttack { get; set; }\n    List<string> Attacks { get; set; }\n    (int MinDamage, int MaxDamage) DamageRange { get; set; }\n    double DefenseChance { get; set; }\n\n    void Add(string name, int hp, TCharacterConfig attributes);\n\n    // Métodos\n    /// <summary> Verifica si puede atacar, realiza un ataque y devuelve el daño infligido.</summary>\n    int Attack();\n\n    /// <summary> Determina si el personaje puede defenderse.</summary>\n    bool Defend();\n}\n\n// _______________________________________\n/// <summary>Lógica para la batalla.</summary>\npublic interface IBattleStrategy\n{\n    /// <summary>Ejecuta la estrategia de batalla entre el atacante y el defensor.</summary>\n    /// <returns>Retorna verdadero si el defensor sigue en pie, falso si el atacante gana la batalla.</returns>\n    bool Execute(ICharacter attacker, ICharacter defender);\n}\n\n// ---------------------------------------\n// IMPLEMENTACIÓN DE INTERFACES\n// ---------------------------------------\n// _______________________________________\n/// <summary>Constantes globales.</summary>\npublic class DefaultConfig : IGlobalConfig\n{\n    private const int TIME = 1; // segundos\n    private readonly int MINIMUM_HP = 200;\n\n    private static readonly IDictionary<string, TCharacterConfig> CHARACTERS =\n        new Dictionary<string, TCharacterConfig>\n        {\n            {\n                \"Deadpool\",\n                new TCharacterConfig\n                {\n                    Attacks = [\"Con arma.\", \"Cuerpo a cuerpo.\", \"Con ataque imprudente.\"],\n                    DamageRange = (10, 100),\n                    DefenseChance = 0.25\n                }\n            },\n            {\n                \"Wolverine\",\n                new TCharacterConfig\n                {\n                    Attacks = [\"Con garras de adamantium.\", \"Con arma.\", \"Cuerpo a cuerpo.\"],\n                    DamageRange = (10, 120),\n                    DefenseChance = 0.20\n                }\n            }\n            // Puedes añadir más personajes aquí.\n        };\n\n    private const string MENU = @\"\nSIMULADOR DE BATALLAS:\n------------------------------------------\n| 1. Simular una batalla | 2. Salir      |  \n------------------------------------------\";\n\n    public int TurnInterval => TIME;\n    public int MinimumHp => MINIMUM_HP;\n    public IDictionary<string, TCharacterConfig> Characters => CHARACTERS;\n    public string Menu => MENU;\n}\n\n// _______________________________________\n/// <summary>Solicitud de entrada.</summary>\npublic class ConsoleInput : IInput\n{\n    public int Get(string msg)\n    {\n        while (true)\n        {\n            Console.Write(msg);\n            string? input = Console.ReadLine();\n\n            if (string.IsNullOrWhiteSpace(input))\n            {\n                Console.WriteLine(\"La entrada no puede estar vacía.\");\n                continue;\n            }\n\n            if (int.TryParse(input, out int intValue))\n            {\n                return intValue;\n            }\n            else\n            {\n                Console.WriteLine(\"Por favor, ingresa un número entero válido.\");\n            }\n        }\n    }\n}\n\n// _______________________________________\n/// <summary>Datos y metodos de un personaje que participara en la batalla.</summary>\npublic class DefaultCharacter : ICharacter\n{\n    public string Name { get; set; } = \"\";\n    public int Hp { get; set; } = 0;\n    public bool CanAttack { get; set; } = true;\n    public List<string> Attacks { get; set; } = [];\n    public (int MinDamage, int MaxDamage) DamageRange { get; set; } = (0, 0);\n    public double DefenseChance { get; set; } = 0.0;\n\n    public void Add(string name, int hp, TCharacterConfig attributes)\n    {\n        Name = name;\n        Hp = hp;\n        Attacks = attributes.Attacks;\n        DamageRange = attributes.DamageRange;\n        DefenseChance = attributes.DefenseChance;\n    }\n\n    public int Attack()\n    {\n        if (CanAttack)\n        {\n            Random random = new();\n            int damage = random.Next(DamageRange.MinDamage, DamageRange.MaxDamage + 1);\n            string selectedAttack = Attacks[random.Next(Attacks.Count)];\n            Console.WriteLine($\"|'{Name}' ataca '{selectedAttack}' causando un: '-{damage}' 👊|\");\n            return damage;\n        }\n        else\n        {\n            Console.WriteLine($\"|'{Name}' se está regenerando y no puede atacar. 😴|\");\n            return 0;\n        }\n    }\n\n    public bool Defend()\n    {\n        Random random = new();\n        bool defended = random.NextDouble() < DefenseChance;\n        Console.WriteLine(defended\n            ? $\"|'{Name}' logró defenderse. 🛡️|\"\n            : $\"|'{Name}' no pudo bloquear el ataque. 🤕|\");\n        return defended;\n    }\n}\n\n// _______________________________________\n/// <summary>Estrategia estabglecida.</summary>\npublic class DefaultBattleStrategy : IBattleStrategy\n{\n    public bool Execute(ICharacter attacker, ICharacter defender)\n    {\n        int damage = attacker.Attack();\n\n        if (damage == attacker.DamageRange.MaxDamage)\n        {\n            Console.WriteLine($\"|'{defender.Name}' 🚨recibió un ataque crítico y no podrá atacar.🚨|\");\n            defender.CanAttack = false;\n        }\n\n        if (attacker.CanAttack)\n        {\n            if (!defender.Defend())\n            {\n                defender.Hp -= damage;\n            }\n        }\n        else\n        {\n            attacker.CanAttack = true;\n        }\n\n        if (defender.Hp <= 0)\n        {\n            Console.WriteLine(\"\\n____________________________\");\n            Console.WriteLine($\"|'{attacker.Name}' 🏆 gana la batalla. 🏆|\");\n            return false;\n        }\n\n        return true;\n    }\n}\n\n// _____\n// NOTA: Estoy intentando practicar los principios SOLID. XD 😂\n\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/c#/lurtur.cs",
    "content": "/******************************************************************************/\n// Author: Luis Rodriguez\n// github: https//github.com/lurtur\n// Date: 15 August 2024\n/******************************************************************************/\n\nnamespace _32_WolverineVsDeadpool;\n\n/// <summary>\n/// Defines the state contract\n/// </summary>\npublic interface IState\n{\n    public void RunAction(Character context, Character oponent, Battle battle);\n}\n\n/// <summary>\n/// Defines the action when the character is in Attacking state.\n/// </summary>\npublic class Attacking() : IState\n{\n    public void RunAction(Character context, Character oponent, Battle battle)\n    {\n        if (context.Regenerate == true)\n        {\n            context.Regenerate = false;\n            Console.WriteLine($\"{context.Name} is regenerating...skip attack this turn.\");\n        }\n        else\n        {\n            int damage = context.Attack(oponent);\n\n            oponent.Defend();\n\n            battle.UpdateHealth(oponent, damage);\n        }\n\n        context.SetState(new Defending());\n    }\n}\n\n/// <summary>\n/// Defines the action when the character is in Defending state\n/// </summary>\npublic class Defending() : IState\n{\n    public void RunAction(Character context, Character oponent, Battle battle)\n    {\n        context.SetState(new Attacking());\n    }\n}\n\n/// <summary>\n/// Defines the character class.\n/// It is the context on the State design pattern.\n/// </summary>\n/// <param name=\"name\">The name of the character</param>\n/// <param name=\"health\">The health level of the character</param>\n/// <param name=\"minDamage\">The minimum damage the character can inflict</param>\n/// <param name=\"maxDamage\">The maximum damage the character can inflict</param>\n/// <param name=\"elusionThreshold\">Threshold to elude attacks</param>\n/// <param name=\"initialState\">Initial state of the character</param>\npublic class Character(string name, int health, int minDamage, int maxDamage, int elusionThreshold, IState initialState)\n{\n    public string Name { get; set; } = name;\n    public int Health { get; set; } = health;\n    public int MinDamage { get; set; } = minDamage;\n    public int MaxDamage { get; set; } = maxDamage;\n    public bool Elude { get; set; }\n    public int ElusionThreshold { get; set; } = elusionThreshold;\n    public bool Regenerate { get; set; }\n\n    private IState _state = initialState;\n\n    public void SetState(IState state)\n    {\n        _state = state;\n    }\n\n    public void RunAction(Character oponent, Battle battle)\n    {\n        _state.RunAction(this, oponent, battle);\n    }\n\n    public int Attack(Character oponent)\n    {\n        // Generate a random damage value\n        Random rnd = new();\n        int damage = rnd.Next(MinDamage, MaxDamage + 1);\n\n        // Determine if it is a critical damage\n        if (damage == MaxDamage)\n        {\n            // The oponent will regenerate next turn, hence skip the attack\n            // This just set the Regenerate property based on the potential damage\n            // but the final value is determined by defending which can set it to \n            // false upon eluding the attack.\n            oponent.Regenerate = true;\n\n            Console.WriteLine($\"AMAZING CRITICAL!!! {Name} attacks with {damage} units of damage.\");\n        }\n        else\n        {\n            Console.WriteLine($\"{Name} attacks with {damage} units of damage.\");\n        }\n\n        return damage;\n    }\n\n    public void Defend()\n    {\n        // Get a random value as the probability of eluding the attack\n        Random rnd = new();\n        int elusionChance = rnd.Next(1, 100);\n\n        // Determine if the attack is eluded\n        if (elusionChance < ElusionThreshold)\n        {\n            Elude = true;\n\n            // In case the attack is eluded the character will not regenerate\n            // since the damaged was not inflicted\n            Regenerate = false;\n\n            Console.WriteLine($\"UNBELIEVABLE!!! {Name} eludes the attack.\");\n        }\n        else\n        {\n            Console.WriteLine($\"TOO LATE!!! {Name} received the attack.\");\n        }\n    }\n}\n\n/// <summary>\n/// Defines the battle class.\n/// It handles the battle by:\n/// - Updating the health of the oponents.\n/// - Displaying the health on the console.\n/// - Running the actions of the characters.\n/// </summary>\n/// <param name=\"character1\">The first character in the battle</param>\n/// <param name=\"character2\">The second character in the battle</param>\npublic class Battle(Character character1, Character character2)\n{\n    private Character _character1 = character1;\n    private Character _character2 = character2;\n\n    private int _turn;\n\n    public void Start()\n    {\n        int counter = 0;\n        Console.WriteLine(\"The battle begins!\\n\");\n        while (_character1.Health > 0 && _character2.Health > 0)\n        {\n            // Each turn implies the counter increment two numbers.\n            // e.g. counter = 1 means the first character attacking and\n            // counter = 2 means the second character attacking. Therefore,\n            // every two iterations _turn is incremented.\n            if ((counter % 2) == 0)\n            {\n                ++_turn;\n                counter = 0;\n                Console.WriteLine($\"\\nTurn {_turn}\");\n            }\n            ++counter;\n\n            _character1.RunAction(_character2, this);\n            if (_character2.Health > 0)\n            {\n                _character2.RunAction(_character1, this);\n            }\n\n            DisplayHealth();\n\n            if (counter ==  2)\n            {\n                Console.WriteLine(\"Waiting 1 second...\");\n                Thread.Sleep(1000);\n            }\n        }\n\n        // Determine which character wins\n        if (_character1.Health > 0)\n        {\n            Console.WriteLine(\"-------------------------------------------\");\n            Console.WriteLine($\"{_character1.Name} wins the battle.\");\n            Console.WriteLine(\"-------------------------------------------\");\n        }\n        else\n        {\n            Console.WriteLine(\"-------------------------------------------\");\n            Console.WriteLine($\"{_character2.Name} wins the battle.\");\n            Console.WriteLine(\"-------------------------------------------\");\n        }\n    }\n\n    public void UpdateHealth(Character oponent, int damage)\n    {\n        if (oponent.Elude == false)\n        {\n            oponent.Health -= damage;\n            if (oponent.Health < 0)\n            {\n                oponent.Health = 0;\n            }\n        }\n        else\n        {\n            oponent.Elude = false;\n        }\n    }\n\n    private void DisplayHealth()\n    {\n        Console.WriteLine($\"{_character1.Name} health {_character1.Health}\");\n        Console.WriteLine($\"{_character2.Name} health {_character2.Health}\");\n    }\n}\n\n\nclass Program\n{\n    static void Main(string[] args)\n    {\n        // Console.WriteLine(\"Enter the health for Wolverine\");\n        // int deadpoolHealth = int.Parse(Console.ReadLine()!);\n        int deadpoolHealth = 1000;\n\n        //Console.WriteLine(\"Enter the health for Deadpool\");\n        //int wolwerineHealth = int.Parse(Console.ReadLine()!);\n        int wolwerineHealth = 1000;\n\n        Character deadpool = new(\"Deadpool\", deadpoolHealth, 10, 100, 25, new Attacking());\n        Character wolwerine = new(\"Wolverine\", wolwerineHealth, 10, 120, 20, new Defending());\n\n        Battle battle = new(deadpool, wolwerine);\n        battle.Start();\n    }\n}"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/c++/AngelRamirez02.cpp",
    "content": "//Angel Ramirez Castro\r\n#include <iostream>\r\n#include <stdlib.h>\r\n#include <thread>  \r\n#include <chrono>  \r\n\r\nusing namespace std;\r\n\r\n//clase para personajes\r\nclass personaje{\r\n\tpublic:\r\n\t\tint vida; //valor de vida\r\n\t\tint ataque, prob_evadir; //valor de ataque y prob de evadir el siguiente ataque\r\n};\r\n\r\nint main(){\r\n\t//creacion de personajes\r\n\tpersonaje DeadPool, Wolwerine;\r\n\tcout<<\"\\tSimulador de batalla\\n\\n\";\r\n\t//Ingreso de la vida de los usuarios\r\n\tcout<<\"Ingrese la vida de Deadpool: \";\r\n\tcin>>DeadPool.vida;\r\n\tcout<<\"Ingrese la vida de Wolwerine: \";\r\n\tcin>>Wolwerine.vida;\r\n\t//Inicio de turnos, true para deadpol, false para wolwerine\r\n\tbool DeadPoolTurno=true;\r\n\tint turno=1;\r\n\r\n\twhile( Wolwerine.vida>0 && DeadPool.vida>0){\r\n\t\tsystem(\"cls\");\r\n\t\tcout<<\"\\n\\tSimulador de batalla\\n\";\r\n\t\tif(DeadPoolTurno){\r\n\t\t\t//Genera el valor del ataque de deadpool y la prob de evadir de wolwerine\r\n\t\t\tDeadPool.ataque=rand()%91+10;\r\n\t\t\tWolwerine.prob_evadir=rand()%101;\r\n\t\t\t\r\n\t\t\tif(Wolwerine.prob_evadir<20){ //si la probabilidad es 20%\r\n\t\t\t\tcout<<\"Wolwerine logra evadir el ataque!\\n\";\r\n\t\t\t}\r\n\t\t\telse if(DeadPool.ataque==110){//ssuper ataque\r\n\t\t\t\tcout<<\"Deadpool conecta un super ataque de \"<<DeadPool.ataque<<endl;\r\n\t\t\t\tcout<<\"Wolwerine no puede atacar en el siguiente turno\\n\";\r\n\t\t\t\tWolwerine.vida-=DeadPool.ataque;//wolwerine pierde vida\r\n\t\t\t\tDeadPoolTurno=true;\r\n\t\t\t}\r\n\t\t\telse{ //ataque normal\r\n\t\t\t\tcout<<\"Deadpool logra un ataque de \"<<DeadPool.ataque<<endl;\r\n\t\t\t\tWolwerine.vida-=DeadPool.ataque;//wolwerine pierde vida\r\n\t\t\t\tDeadPoolTurno=false;\r\n\t\t\t}\r\n\t\t\t//Imprime resultados\r\n\t\t\tcout<<\"\\n\\t\\tTurno: \"<<turno<<endl;\r\n\t\t\tcout<<\"\\t\\tD   VS   W\\n\";\r\n\t\t\tcout<<\"\\t       \"<<DeadPool.vida<<\"       \"<<Wolwerine.vida<<endl;\r\n\t\t\tthis_thread::sleep_for(chrono::seconds(1));\r\n\t\t}\r\n\t\telse{\r\n\t\t\t//Genera el valor del ataque de wolwerine y la prob de evadir de deadpool\r\n\t\t\tWolwerine.ataque=rand()%111+10;\r\n\t\t\tDeadPool.prob_evadir=rand()%101;\r\n\t\t\t\r\n\t\t\tif(DeadPool.prob_evadir<25){//probabilidad de 25%\r\n\t\t\t\tcout<<\"Deadpool logra evadir el ataque!\\n\";\t\r\n\t\t\t}\r\n\t\t\telse if(Wolwerine.ataque==120){//super ataque\r\n\t\t\t\tcout<<\"Wolwerine conecta un super ataque de \"<<Wolwerine.ataque<<endl;\r\n\t\t\t\tcout<<\"Deadpool no puede atacar en el siguiente turno\\n\";\r\n\t\t\t\tDeadPool.vida-=Wolwerine.ataque;//Deadpool pierde vida\r\n\t\t\t\tDeadPoolTurno=false;\t\r\n\t\t\t}\r\n\t\t\telse{//ataque normal\r\n\t\t\t\tcout<<\"Wolwerine logra un ataque de \"<<Wolwerine.ataque<<endl;\r\n\t\t\t\tDeadPool.vida-=Wolwerine.ataque;//Deadpool pierde vida\r\n\t\t\t\tDeadPoolTurno=true;\t\r\n\t\t\t}\r\n\t\t\t//Imprime resultados\r\n\t\t\tcout<<\"\\n\\t\\tTurno: \"<<turno<<endl;\r\n\t\t\tcout<<\"\\t\\tD   VS   W\\n\";\r\n\t\t\tcout<<\"\\t       \"<<DeadPool.vida<<\"       \"<<Wolwerine.vida<<endl;\r\n\t\t\tthis_thread::sleep_for(chrono::seconds(1));\r\n\t\t}\r\n\t\tturno++;//aumenta el numero de turno\t\r\n\t}\r\n\t//muestra ganador\r\n\tif(DeadPool.vida>Wolwerine.vida){\r\n\t\tcout<<\"\\n\\tDeadpool es el ganador!\\n\";\r\n\t}else{\r\n\t\tcout<<\"\\n\\tWolwerine es el ganador!\\n\";\t\r\n\t}\r\n\t\t\r\n\treturn 0;\r\n}\r\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/c++/hectorio23.cpp",
    "content": "// Autor:  Héctor Adán\n// GitHub: https://github.com/hectorio23\n\n#include <iostream>\n#include <cstdlib>\n#include <ctime>\n#include <thread>\n\n/*\n * EJERCICIO:\n * ¡Deadpool y Wolverine se enfrentan en una batalla épica!\n * Crea un programa que simule la pelea y determine un ganador.\n * El programa simula un combate por turnos, donde cada protagonista posee unos\n * puntos de vida iniciales, un daño de ataque variable y diferentes cualidades\n * de regeneración y evasión de ataques.\n * Requisitos:\n * 1. El usuario debe determinar la vida inicial de cada protagonista.\n * 2. Cada personaje puede impartir un daño aleatorio:\n *    - Deadpool: Entre 10 y 100.\n *    - Wolverine: Entre 10 y 120.\n * 3. Si el daño es el máximo, el personaje que lo recibe no ataca en el\n * siguiente turno, ya que tiene que regenerarse (pero no aumenta vida).\n * 4. Cada personaje puede evitar el ataque contrario:\n *    - Deadpool: 25% de posibilidades.\n *    - Wolverine: 20% de posibilidades.\n * 5. Un personaje pierde si sus puntos de vida llegan a cero o menos.\n * Acciones:\n * 1. Simula una batalla.\n * 2. Muestra el número del turno (pausa de 1 segundo entre turnos).\n * 3. Muestra qué pasa en cada turno.\n * 4. Muestra la vida en cada turno.\n * 5. Muestra el resultado final.\n*/\n\n// Clase base para los personajes\nclass Character {\npublic:\n    std::string name;\n    int health;\n    int minDamage;\n    int maxDamage;\n    double dodgeChance;\n\n    Character(std::string name, int minDamage, int maxDamage, double dodgeChance)\n        : name(name), health(0), minDamage(minDamage), maxDamage(maxDamage), dodgeChance(dodgeChance) {}\n\n    virtual int attack() = 0;\n\n    virtual bool evade() {\n        return (static_cast<double>(rand()) / RAND_MAX) < dodgeChance;\n    }\n\n    bool isAlive() const {\n        return health > 0;\n    }\n};\n\n// Clase para Deadpool\nclass Deadpool : public Character {\npublic:\n    Deadpool() : Character(\"Deadpool\", 10, 100, 0.25) {}\n\n    int attack() override {\n        return rand() % (maxDamage - minDamage + 1) + minDamage;\n    }\n};\n\n// Clase para Wolverine\nclass Wolverine : public Character {\npublic:\n    Wolverine() : Character(\"Wolverine\", 10, 120, 0.20) {}\n\n    int attack() override {\n        return rand() % (maxDamage - minDamage + 1) + minDamage;\n    }\n};\n\n// Función para simular la batalla\nvoid simulateBattle(Character& char1, Character& char2) {\n    int turn = 1;\n    bool skipChar1 = false;\n    bool skipChar2 = false;\n\n    while (char1.isAlive() && char2.isAlive()) {\n        std::cout << \"\\n**** Turno \" << turn << \" ****:\\n\";\n        if (!skipChar1) {\n            if (!char2.evade()) {\n                int damage = char1.attack();\n                char2.health -= damage;\n                std::cout << \"[+] - \" << char1.name << \" ataca a \" << char2.name << \" causando \" << damage << \" de daño.\\n\";\n                if (damage == char1.maxDamage) {\n                    std::cout << \"[+] - \" << char2.name << \" debe regenerarse y pierde el siguiente turno.\\n\";\n                    skipChar2 = true;\n                }\n            } else {\n                std::cout << \"[+] -\" << char2.name << \" evade el ataque de \" << char1.name << \".\\n\";\n            }\n        } else {\n            skipChar1 = false;\n        }\n\n        if (!skipChar2 && char2.isAlive()) {\n            if (!char1.evade()) {\n                int damage = char2.attack();\n                char1.health -= damage;\n                std::cout << \"[+] -\" << char2.name << \" ataca a \" << char1.name << \" causando \" << damage << \" de daño.\\n\";\n                if (damage == char2.maxDamage) {\n                    std::cout << \"[+] -\" << char1.name << \" debe regenerarse y pierde el siguiente turno.\\n\";\n                    skipChar1 = true;\n                }\n            } else {\n                std::cout << \"[+] -\" << char1.name << \" evade el ataque de \" << char2.name << \".\\n\";\n            }\n        } else {\n            skipChar2 = false;\n        }\n\n        std::cout << char1.name << \" Vida: \" << char1.health << \", \" << char2.name << \" Vida: \" << char2.health << \"\\n\";\n        std::this_thread::sleep_for(std::chrono::seconds(1));\n        turn++;\n    }\n\n    if (char1.isAlive()) {\n        std::cout << char1.name << \" gana la batalla!\\n\";\n    } else {\n        std::cout << char2.name << \" gana la batalla!\\n\";\n    }\n}\n\n// Función principal para ejecutar el programa\nint main() {\n    srand(static_cast<unsigned>(time(0)));\n\n    int deadpoolHealth, wolverineHealth;\n\n    std::cout << \"Ingrese la vida inicial de Deadpool: \";\n    std::cin >> deadpoolHealth;\n\n    std::cout << \"Ingrese la vida inicial de Wolverine: \";\n    std::cin >> wolverineHealth;\n\n    Deadpool deadpool;\n    Wolverine wolverine;\n\n    deadpool.health = deadpoolHealth;\n    wolverine.health = wolverineHealth;\n\n    simulateBattle(deadpool, wolverine);\n\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/ejercicio.md",
    "content": "# #32 BATALLA DEADPOOL Y WOLVERINE\n> #### Dificultad: Media | Publicación: 05/08/24 | Corrección: 12/08/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * ¡Deadpool y Wolverine se enfrentan en una batalla épica!\n * Crea un programa que simule la pelea y determine un ganador.\n * El programa simula un combate por turnos, donde cada protagonista posee unos\n * puntos de vida iniciales, un daño de ataque variable y diferentes cualidades\n * de regeneración y evasión de ataques.\n * Requisitos:\n * 1. El usuario debe determinar la vida inicial de cada protagonista.\n * 2. Cada personaje puede impartir un daño aleatorio:\n *    - Deadpool: Entre 10 y 100.\n *    - Wolverine: Entre 10 y 120.\n * 3. Si el daño es el máximo, el personaje que lo recibe no ataca en el\n * siguiente turno, ya que tiene que regenerarse (pero no aumenta vida).\n * 4. Cada personaje puede evitar el ataque contrario:\n *    - Deadpool: 25% de posibilidades.\n *    - Wolverine: 20% de posibilidades.\n * 5. Un personaje pierde si sus puntos de vida llegan a cero o menos.\n * Acciones:\n * 1. Simula una batalla.\n * 2. Muestra el número del turno (pausa de 1 segundo entre turnos).\n * 3. Muestra qué pasa en cada turno.\n * 4. Muestra la vida en cada turno.\n * 5. Muestra el resultado final.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/go/hozlucas28.go",
    "content": "package main\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"math/rand/v2\"\n\t\"time\"\n)\n\n/* -------------------------------------------------------------------------- */\n/*                                    TYPES                                   */\n/* -------------------------------------------------------------------------- */\n\ntype Turn struct {\n\tAttacker ISuperhero\n\tNumber   int\n\tVictim   ISuperhero\n\t_        struct{}\n}\n\ntype ExecutedTurn struct {\n\tTurn\n\tDamageProducedByAttacker int\n\tDamageReceivedByVictim   int\n\tVictimAvoidAttack        bool\n\t_                        struct{}\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                   ERRORS                                   */\n/* -------------------------------------------------------------------------- */\n\n/* ----------------------- SuperheroRegeneratingError ----------------------- */\n\ntype SuperheroRegeneratingError struct {\n\tSuperhero ISuperhero\n\t_         struct{}\n}\n\nfunc (err *SuperheroRegeneratingError) Error() string {\n\treturn fmt.Sprintf(\"%s is regenerating\", err.Superhero.GetName())\n}\n\n/* -------------------------- ThereIsNoWinnerError -------------------------- */\n\ntype ThereIsNoWinnerError struct{}\n\nfunc (err *ThereIsNoWinnerError) Error() string {\n\treturn \"There is no winner\"\n}\n\n/* --------------------------- ThereIsAWinnerError -------------------------- */\n\ntype ThereIsAWinnerError struct{}\n\nfunc (err *ThereIsAWinnerError) Error() string {\n\treturn \"There is a winner\"\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                   CLASSES                                  */\n/* -------------------------------------------------------------------------- */\n\n/* -------------------------------- Superhero ------------------------------- */\n\ntype ISuperhero interface {\n\tGetAttackDamage() [2]int\n\tGetLifePoints() int\n\tGetName() string\n\tIsRegenerating() bool\n\tSetRegenerating(regenerating bool) ISuperhero\n\tEvadeAttack() bool\n\tProduceDamage() (int, error)\n\tReceiveDamage(damage int) ISuperhero\n}\n\ntype superhero struct {\n\tattackDamage    [2]int\n\tevadePercentage float32\n\tlifePoints      int\n\tname            string\n\tregenerating    bool\n\t_               struct{}\n}\n\nfunc NewSuperhero(\n\tattackDamage [2]int,\n\tevadePercentage float32,\n\tlifePoints int,\n\tname string,\n) ISuperhero {\n\tvar superhero superhero = superhero{\n\t\tlifePoints:      lifePoints,\n\t\tregenerating:    false,\n\t\tattackDamage:    attackDamage,\n\t\tevadePercentage: evadePercentage,\n\t\tname:            name,\n\t}\n\n\treturn &superhero\n}\n\nfunc (superhero *superhero) GetAttackDamage() [2]int {\n\treturn superhero.attackDamage\n}\n\nfunc (superhero *superhero) GetLifePoints() int {\n\treturn superhero.lifePoints\n}\n\nfunc (superhero *superhero) GetName() string {\n\treturn superhero.name\n}\n\nfunc (superhero *superhero) IsRegenerating() bool {\n\treturn superhero.regenerating\n}\n\nfunc (superhero *superhero) SetRegenerating(regenerating bool) ISuperhero {\n\tsuperhero.regenerating = regenerating\n\treturn superhero\n}\n\nfunc (superhero *superhero) EvadeAttack() bool {\n\tvar rndNumber float32 = rand.Float32()\n\treturn rndNumber <= superhero.evadePercentage\n}\n\nfunc (superhero *superhero) ProduceDamage() (int, error) {\n\tif superhero.IsRegenerating() {\n\t\treturn 0, &SuperheroRegeneratingError{\n\t\t\tSuperhero: superhero,\n\t\t}\n\t}\n\n\tminAttackDamage, maxAttackDamage := superhero.attackDamage[0], superhero.attackDamage[1]\n\tvar rndDamage int = rand.N(maxAttackDamage-minAttackDamage+1) + minAttackDamage\n\n\treturn rndDamage, nil\n}\n\nfunc (superhero *superhero) ReceiveDamage(damage int) ISuperhero {\n\tsuperhero.lifePoints -= damage\n\treturn superhero\n}\n\n/* ---------------------------- SuperheroesFight ---------------------------- */\n\ntype ISuperheroesFight interface {\n\tGetTurn() Turn\n\tGetWinner() (ISuperhero, error)\n\tExecuteTurn() (ExecutedTurn, error)\n}\n\ntype superheroesFight struct {\n\tTurn   Turn\n\tWinner ISuperhero\n\t_      struct{}\n}\n\nfunc NewSuperheroesFight(superheroOne ISuperhero, superheroTwo ISuperhero) ISuperheroesFight {\n\tvar superheroesFight superheroesFight = superheroesFight{\n\t\tTurn: Turn{\n\t\t\tAttacker: superheroOne,\n\t\t\tNumber:   1,\n\t\t\tVictim:   superheroTwo,\n\t\t},\n\t}\n\n\treturn &superheroesFight\n}\n\nfunc (fight *superheroesFight) GetTurn() Turn {\n\treturn fight.Turn\n}\n\nfunc (fight *superheroesFight) GetWinner() (ISuperhero, error) {\n\tif fight.Winner == nil {\n\t\treturn nil, &ThereIsNoWinnerError{}\n\t}\n\n\treturn fight.Winner, nil\n}\n\nfunc (fight *superheroesFight) ExecuteTurn() (ExecutedTurn, error) {\n\tif fight.Winner != nil {\n\t\treturn ExecutedTurn{}, &ThereIsAWinnerError{}\n\t}\n\n\tvar attacker ISuperhero = fight.Turn.Attacker\n\tvar number int = fight.Turn.Number\n\tvar victim ISuperhero = fight.Turn.Victim\n\n\tvictim.SetRegenerating(false)\n\n\tfight.Turn = Turn{\n\t\tAttacker: victim,\n\t\tNumber:   number + 1,\n\t\tVictim:   attacker,\n\t}\n\n\tdamageProducedByAttacker, err := attacker.ProduceDamage()\n\tif err != nil {\n\t\treturn ExecutedTurn{}, err\n\t}\n\n\tattackerAttackDamage := attacker.GetAttackDamage()\n\tvar victimAvoidAttack bool = victim.EvadeAttack()\n\n\tvar damageReceivedByVictim int\n\tif !victimAvoidAttack {\n\t\tdamageReceivedByVictim = damageProducedByAttacker\n\t\tvictim.ReceiveDamage(damageProducedByAttacker)\n\t\tvictim.SetRegenerating(damageProducedByAttacker == attackerAttackDamage[1])\n\n\t\tif victim.GetLifePoints() <= 0 {\n\t\t\tfight.Winner = attacker\n\t\t}\n\t}\n\n\treturn ExecutedTurn{\n\t\tTurn: Turn{\n\t\t\tAttacker: attacker,\n\t\t\tVictim:   victim,\n\t\t\tNumber:   number,\n\t\t},\n\n\t\tDamageProducedByAttacker: damageProducedByAttacker,\n\t\tDamageReceivedByVictim:   damageReceivedByVictim,\n\t\tVictimAvoidAttack:        victimAvoidAttack,\n\t}, nil\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\nfunc main() {\n\tvar deadpool ISuperhero = NewSuperhero(\n\t\t[2]int{10, 100},\n\t\t0.25,\n\t\t500,\n\t\t\"Deadpool\",\n\t)\n\n\tvar wolverine ISuperhero = NewSuperhero(\n\t\t[2]int{10, 120},\n\t\t0.20,\n\t\t500,\n\t\t\"Wolverine\",\n\t)\n\n\tvar superheroesFight ISuperheroesFight = NewSuperheroesFight(deadpool, wolverine)\n\n\tfor _, err := superheroesFight.GetWinner(); err != nil; _, err = superheroesFight.GetWinner() {\n\t\ttime.Sleep(time.Second)\n\t\tvar currentTurn Turn = superheroesFight.GetTurn()\n\n\t\texecutedTurn, err := superheroesFight.ExecuteTurn()\n\t\tif err != nil {\n\t\t\tvar regeneratingErr *SuperheroRegeneratingError\n\t\t\tif errors.As(err, &regeneratingErr) {\n\t\t\t\tfmt.Printf(\"\\n> Turn N°%d: %s\\n\", currentTurn.Number, err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\n\t\tif executedTurn.VictimAvoidAttack {\n\t\t\tfmt.Printf(\n\t\t\t\t\"\\n> Turn N°%d: %s avoided %s attack\\n\",\n\t\t\t\texecutedTurn.Turn.Number,\n\t\t\t\texecutedTurn.Turn.Victim.GetName(),\n\t\t\t\texecutedTurn.Turn.Attacker.GetName(),\n\t\t\t)\n\t\t\tcontinue\n\t\t}\n\n\t\tfmt.Printf(\n\t\t\t\"\\n> Turn N°%d: %s attacked %s with %d points of damage\",\n\t\t\texecutedTurn.Turn.Number,\n\t\t\texecutedTurn.Turn.Attacker.GetName(),\n\t\t\texecutedTurn.Turn.Victim.GetName(),\n\t\t\texecutedTurn.DamageProducedByAttacker,\n\t\t)\n\n\t\tfmt.Printf(\n\t\t\t\"\\n[ Life points of %s: %d ]\",\n\t\t\tdeadpool.GetName(),\n\t\t\tdeadpool.GetLifePoints(),\n\t\t)\n\n\t\tfmt.Printf(\"\\n[ Life points of %s: %d ]\\n\",\n\t\t\twolverine.GetName(),\n\t\t\twolverine.GetLifePoints(),\n\t\t)\n\t}\n\n\twinner, _ := superheroesFight.GetWinner()\n\tfmt.Printf(\"\\nThe winner is %s!\", winner.GetName())\n}\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/java/AmadorQuispe.java",
    "content": "package com.amsoft.roadmap.example32;\n\nimport java.util.Random;\nimport java.util.concurrent.TimeUnit;\n\npublic class Example32 {\n    public static void main(String[] args) {\n        Character deadpool = new Character.Builder()\n                .name(\"Deadpool\")\n                .health(1000)\n                .minDamage(10)\n                .maxDamage(100)\n                .probabilityDefend(25)\n                .build();\n        Character wolverine = new Character.Builder()\n                .name(\"Wolverine\")\n                .health(1000)\n                .minDamage(10)\n                .maxDamage(120)\n                .probabilityDefend(20)\n                .build();\n        simulateBattle simulateBattle = new simulateBattle();\n        simulateBattle.battle(deadpool, wolverine);\n    }\n}\n\nclass simulateBattle {\n    public void battle(Character hero1, Character hero2) {\n        int turn = 0; //Turnos pares ataca el hero1, turnos impares ataca el hero2\n        boolean loseTurn;\n        while (hero1.getHealth() > 0 && hero2.getHealth() > 0) {\n            System.out.println(\"-----------------\" + \"Turno \" + turn + \"-----------------\");\n            if (turn % 2 == 0) {\n                loseTurn = turnAttack(hero1, hero2);\n            } else {\n                loseTurn = turnAttack(hero2, hero1);\n            }\n            if (!loseTurn){\n                turn++;\n            }\n            try {\n                TimeUnit.SECONDS.sleep(1);\n            } catch (InterruptedException e) {\n                throw new RuntimeException(e);\n            }\n        }\n        System.out.println(\"Batalla finalizada\");\n        System.out.println(\"-----------------\");\n        if (hero1.getHealth() <= 0) {\n            System.out.println(hero2.getName() + \" gana la batalla\");\n        } else {\n            System.out.println(hero1.getName() + \" gana la batalla\");\n        }\n    }\n\n    public boolean turnAttack(Character attacker, Character defender){\n        int damage = attacker.attack();\n        int defend = defender.defend();\n        if(damage == attacker.getMaxDamage()){\n            String message = String.format(\n                    \"%s ataca con %d de daño crítico, %s pierde el turno\",\n                    attacker.getName(), damage, defender.getName()\n            );\n            System.out.println(message);\n            return true;\n        }\n        if (defend == 0) {\n            String message = String.format(\n                    \"%s ataca con %d de daño, y %s evade el ataque, queda con %d de vida\",\n                    attacker.getName(), damage, defender.getName(), defender.getHealth()\n            );\n            System.out.println(message);\n        } else {\n            defender.decreaseHealth(damage);\n            String message = String.format(\n                    \"%s ataca con %d de daño, deja a %s con %d de vida\",\n                    attacker.getName(), damage,\n                    defender.getName(), defender.getHealth()\n            );\n            System.out.println(message);\n        }\n        return false;\n    }\n}\n\n\n\n\n\nclass Character {\n    private final String name;\n    private Integer health;\n    private final Integer minDamage;\n    private final Integer maxDamage;\n    private final Integer probabilityDefend;\n\n    private Character(Builder builder) {\n        this.name = builder.name;\n        this.health = builder.health;\n        this.minDamage = builder.minDamage;\n        this.maxDamage = builder.maxDamage;\n        this.probabilityDefend = builder.probabilityDefend;\n    }\n\n\n    public Integer attack() {\n        return new Random().nextInt(maxDamage - minDamage + 1) + minDamage;\n    }\n\n    public Integer defend() {\n        int defend = new Random().nextInt(100);\n        return defend <= probabilityDefend ? 0 : 1;\n    }\n\n    public void decreaseHealth(Integer damage) {\n        health -= damage;\n    }\n\n    static class Builder {\n        private String name;\n        private Integer health;\n        private Integer minDamage;\n        private Integer maxDamage;\n        private Integer probabilityDefend;\n\n        public Builder name(String name) {\n            this.name = name;\n            return this;\n        }\n\n        public Builder health(Integer health) {\n            this.health = health;\n            return this;\n        }\n\n        public Builder minDamage(Integer minDamage) {\n            this.minDamage = minDamage;\n            return this;\n        }\n\n        public Builder maxDamage(Integer maxDamage) {\n            this.maxDamage = maxDamage;\n            return this;\n        }\n\n        public Builder probabilityDefend(Integer probabilityDefend) {\n            this.probabilityDefend = probabilityDefend;\n            return this;\n        }\n\n        public Character build() {\n            return new Character(this);\n        }\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public Integer getHealth() {\n        return health;\n    }\n\n    public Integer getMinDamage() {\n        return minDamage;\n    }\n\n    public Integer getMaxDamage() {\n        return maxDamage;\n    }\n\n    public Integer getProbabilityDefend() {\n        return probabilityDefend;\n    }\n}\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/java/ArmentaAngel.java",
    "content": "import java.util.Random;\nimport java.util.Scanner;\n\nimport static java.lang.Thread.sleep;\n\npublic class ArmentaAngel {\n\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);  // Create a Scanner object\n\n        System.out.println(\"Enter Deadpool's life points:\");\n        Fighter deadpool = new Fighter(Hero.DEADPOOL, scanner.nextInt()) ;\n\n        System.out.println(\"Enter Wolverine's life points:\");\n        Fighter wolverine = new Fighter(Hero.WOLVERINE, scanner.nextInt()) ;\n\n        Game game = new Game(deadpool, wolverine);\n        game.start();\n    }\n}\n\nenum Hero {\n\n    DEADPOOL(\"Deadpool\", 10, 100, 25),\n    WOLVERINE(\"Wolverine\", 10, 120, 20);\n\n    final String name;\n    final int minDamage;\n    final int maxDamage;\n    final int defendAttackPercentage;\n\n    Hero(String name, int minDamage, int maxDamage, int defendAttackPercentage) {\n        this.name = name;\n        this.minDamage = minDamage;\n        this.maxDamage = maxDamage;\n        this.defendAttackPercentage = defendAttackPercentage;\n    }\n}\n\nclass Fighter {\n\n    public Hero hero;\n    public int life;\n    public String[] randomDefense = new String[100];\n\n    private final String SUPER_DEFENSE = \"SUPER_DEFENSE\";\n    private final String USED = \"USED\";\n    private final String NOT_USED = \"NOT_USED\";\n\n    private final Random rand = new Random();\n\n    public Fighter(Hero hero, int life) {\n        this.hero = hero;\n        this.life = life;\n\n        buildRandomDefense();\n    }\n\n    public int attack() {\n        return randomBetween(hero.minDamage, hero.maxDamage);\n    }\n\n    public boolean defense() {\n        int index;\n        Boolean noDamage;\n\n        do {\n            index = rand.nextInt(100);\n            if (randomDefense[index].equals(SUPER_DEFENSE)) {\n                noDamage = true;\n            } else if (randomDefense[index].equals(NOT_USED)) {\n                noDamage = false;\n            } else {\n                // Only can be USED\n                noDamage = null;\n            }\n        } while (noDamage == null);\n        randomDefense[index] = USED;\n\n        return noDamage;\n    }\n\n    protected int randomBetween(int minInclusive, int maxInclusive) {\n        return rand.nextInt(maxInclusive - minInclusive + 1) + minInclusive;\n    }\n\n    private void buildRandomDefense() {\n        // Place SUPER_DEFENSE positions\n        int avoidAttackCount = hero.defendAttackPercentage;\n        while (avoidAttackCount > 0) {\n            int index = rand.nextInt(100);\n            if (randomDefense[index] == null) {\n                randomDefense[index] = SUPER_DEFENSE;\n                avoidAttackCount--;\n            }\n        }\n\n        fillNullIndexes(randomDefense, NOT_USED);\n    }\n\n    private void fillNullIndexes(String[] array, String filler) {\n        for (int i = 0; i < array.length; i++) {\n            if(array[i] == null) {\n                array[i] = filler;\n            }\n        }\n    }\n}\n\nclass Game {\n    private final Fighter[] fighters = new Fighter[2];\n    private int turnCount;\n    protected int turnOf;\n    private boolean fightEnds = false;\n\n    private final int TURN_TIME_IN_SECONDS = 1;\n\n    public Game(Fighter fighter1, Fighter fighter2) {\n        fighters[0] = fighter1;\n        fighters[1] = fighter2;\n    }\n\n    public void start() {\n        turnCount = 1;\n        turnOf = chooseFirstFighterRandomly();\n\n        while (!fightEnds) {\n            playTurn();\n        }\n\n        fightBroadcastFightEnds();\n    }\n\n    protected int chooseFirstFighterRandomly() {\n        Random rand = new Random();\n        return rand.nextInt(2); // Only can return 0 or 1\n    }\n\n    protected void changeTurn() {\n        turnOf = turnOf == 1 ? 0 : 1;\n    }\n\n    protected int fighterOnDefenseIndex() {\n        return turnOf == 1 ? 0 : 1;\n    }\n\n    protected boolean fightEnds() {\n        return fighters[0].life <= 0 || fighters[1].life <= 0;\n    }\n\n    protected int getWinnerIndex() {\n        return fighters[0].life > fighters[1].life ? 0 : 1;\n    }\n\n    private void playTurn() {\n        Fighter fighterOnAttack = fighters[turnOf];\n        Fighter fighterOnDefense = fighters[fighterOnDefenseIndex()];\n\n        fightBroadcastTurnBegins();\n\n        dramaticPause();\n\n        int attackPower = fighterOnAttack.attack();\n        boolean defended = fighterOnDefense.defense();\n        boolean maximumPower = attackPower == fighterOnAttack.hero.maxDamage;\n\n        fightBroadcastTurnEnds(attackPower, maximumPower, defended);\n\n        if (!defended) {\n            fighterOnDefense.life -= attackPower;\n        }\n\n        if (!fightEnds()) {\n            if (!maximumPower) {\n                changeTurn();\n            }\n            turnCount++;\n        } else {\n            fightEnds = true;\n        }\n    }\n\n    private void dramaticPause() {\n        try {\n            sleep(TURN_TIME_IN_SECONDS * 1000);\n        } catch (Exception e) {\n            throw new RuntimeException(e);\n        }\n    }\n\n    private void fightBroadcastTurnBegins() {\n        System.out.printf(\"# This is turn %d ##############################################################%n\", turnCount);\n        System.out.printf(\"# %s life is %d%n\", fighters[0].hero.name, fighters[0].life);\n        System.out.printf(\"# %s life is %d%n\", fighters[1].hero.name, fighters[1].life);\n        System.out.printf(\"# %s's turn to attack, %s's turn to defend%n\", fighters[turnOf].hero.name, fighters[fighterOnDefenseIndex()].hero.name);\n        System.out.printf(\"%n\");\n    }\n\n    private void fightBroadcastTurnEnds(int power, boolean maximumPower, boolean defended) {\n        // Turn results\n        System.out.printf(\"@ After turn %d%n\", turnCount);\n        if(maximumPower) {\n            System.out.printf(\"@ %s attack is %d. It is a $$$ MAXIMUM POWER ATTACK $$$%n\", fighters[turnOf].hero.name, power);\n            System.out.printf(\"@ With this MAXIMUM POWER ATTACK, %s will strike again in the next turn%n\", fighters[turnOf].hero.name);\n        } else {\n            System.out.printf(\"@ %s attack power is %d%n\", fighters[turnOf].hero.name, power);\n        }\n        if(defended) {\n            System.out.printf(\"@ %s dodges the attack with a --- SUPER DEFENSE ---%n\", fighters[fighterOnDefenseIndex()].hero.name);\n        } else {\n            System.out.printf(\"@ %s receives an accurate hit and loses %d life points%n\", fighters[fighterOnDefenseIndex()].hero.name, power);\n        }\n        System.out.printf(\"%n\");\n    }\n\n    private void fightBroadcastFightEnds() {\n        // Fight results\n        System.out.printf(\"################################################################################%n\");\n        System.out.printf(\"#                                                                              #%n\");\n        System.out.printf(\"# %s is the WINNER after %d turns%n\", fighters[getWinnerIndex()].hero.name, turnCount);\n        System.out.printf(\"#                                                                              #%n\");\n        System.out.printf(\"# %s loses with %d life points%n\", fighters[fighterOnDefenseIndex()].hero.name, fighters[fighterOnDefenseIndex()].life);\n        System.out.printf(\"# %s wins with %d life points%n\", fighters[turnOf].hero.name, fighters[turnOf].life);\n        System.out.printf(\"#                                                                              #%n\");\n        System.out.printf(\"################################################################################%n\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/java/Jesus2421.java",
    "content": "package Principal;\r\nimport java.util.Random;\r\n\r\nimport Clases.*;\r\n/*\r\n * EJERCICIO:\r\n * ¡Deadpool y Wolverine se enfrentan en una batalla épica!\r\n * Crea un programa que simule la pelea y determine un ganador.\r\n * El programa simula un combate por turnos, donde cada protagonista posee unos\r\n * puntos de vida iniciales, un daño de ataque variable y diferentes cualidades\r\n * de regeneración y evasión de ataques.\r\n * Requisitos:\r\n * 1. El usuario debe determinar la vida inicial de cada protagonista.\r\n * 2. Cada personaje puede impartir un daño aleatorio:\r\n *    - Deadpool: Entre 10 y 100.\r\n *    - Wolverine: Entre 10 y 120.\r\n * 3. Si el daño es el máximo, el personaje que lo recibe no ataca en el\r\n * siguiente turno, ya que tiene que regenerarse (pero no aumenta vida).\r\n * 4. Cada personaje puede evitar el ataque contrario:\r\n *    - Deadpool: 25% de posibilidades.\r\n *    - Wolverine: 20% de posibilidades.\r\n * 5. Un personaje pierde si sus puntos de vida llegan a cero o menos.\r\n * Acciones:\r\n * 1. Simula una batalla.\r\n * 2. Muestra el número del turno (pausa de 1 segundo entre turnos).\r\n * 3. Muestra qué pasa en cada turno.\r\n * 4. Muestra la vida en cada turno.\r\n * 5. Muestra el resultado final.\r\n */\r\npublic abstract class Personajes {\r\n\tprotected int vida;\r\n\r\n    public Personajes() {\r\n        this.setVida(100); \r\n    }\r\n\r\n    public abstract int atacar();\r\n\r\n    public abstract int defenderse();\r\n    \r\n    public abstract int regenerarse();\r\n\r\n\tpublic int getVida() {\r\n\t\treturn vida;\r\n\t}\r\n\r\n\tpublic void setVida(int vida) {\r\n\t\tthis.vida = vida;\r\n\t}\r\n}\r\npublic class Wolverine extends Personajes {\r\n\tprivate boolean estaRegenerandose;\r\n\tpublic Wolverine() {\r\n\t\t super();\r\n\t\t this.estaRegenerandose = false;\r\n\t}\r\n\r\n\t@Override\r\n\t public int atacar() {\r\n        Random rand = new Random();\r\n        return rand.nextInt((120 - 10) + 1) + 10;\r\n    }\r\n\r\n\t@Override\r\n\tpublic int defenderse() {\r\n\t\tRandom rand = new Random();\r\n        int probabilidad = rand.nextInt(100);\r\n        if (probabilidad < 20) {\r\n            return 1; // Defensa exitosa\r\n        } else {\r\n            return 0; // Defensa fallida\r\n        }\r\n\t}\r\n\r\n\t@Override\r\n\tpublic int regenerarse() {\r\n        // Se regenera si recibe daño crítico, lo que le impide atacar\r\n        if (this.vida <= 20) {\r\n            this.estaRegenerandose = true;\r\n            this.vida += 20; // Aumenta la vida en 20 puntos\r\n        }\r\n        return this.vida;\r\n    }\r\n\t\r\n\t public boolean estaRegenerandose() {\r\n\t        return this.estaRegenerandose;\r\n\t }\r\n\r\n}\r\npublic class Deadpool extends Personajes {\r\n    private boolean estaRegenerandose;\r\n\r\n    public Deadpool() {\r\n        super(); // Llama al constructor de la clase padre para inicializar la vida\r\n        this.estaRegenerandose = false; // Inicializa la variable de regeneración\r\n    }\r\n\r\n    @Override\r\n    public int atacar() {\r\n        Random rand = new Random();\r\n        return rand.nextInt((100 - 10) + 1) + 10;\r\n    }\r\n\r\n    @Override\r\n    public int defenderse() {\r\n        // Tiene una probabilidad de defenderse del 25%\r\n        Random rand = new Random();\r\n        int probabilidad = rand.nextInt(100);\r\n        if (probabilidad < 25) {\r\n            return 1; // Defensa exitosa\r\n        } else {\r\n            return 0; // Defensa fallida\r\n        }\r\n    }\r\n    @Override\r\n    public int regenerarse() {\r\n        // Se regenera si recibe daño crítico, lo que le impide atacar\r\n        if (this.vida <= 20) {\r\n            this.estaRegenerandose = true;\r\n            this.vida += 20; // Aumenta la vida en 20 puntos\r\n        }\r\n        return this.vida;\r\n    }\r\n\r\n    public boolean estaRegenerandose() {\r\n        return this.estaRegenerandose;\r\n    }\r\n}\r\n\r\n\r\npublic class Principal {\r\n\r\n\tpublic static void main(String[] args) throws InterruptedException{\r\n\t\tPersonajes P1 = new Deadpool();\r\n\t\tPersonajes P2 = new Wolverine();\r\n\t\tint turno = 1;\r\n\t\tRandom rand = new Random();\r\n\t\twhile (P1.getVida() > 0 && P2.getVida() > 0) {\r\n\t\t\tSystem.out.println(\"Turno: \" + turno);\r\n            System.out.println(\"Vida de Deadpool: \" + P1.getVida());\r\n            System.out.println(\"Vida del Wolverine: \" + P2.getVida());\r\n            boolean PrimerAtaqque = rand.nextBoolean();\r\n            if (PrimerAtaqque) {\r\n                // Deadpool ataca\r\n                int ataque = P1.atacar();\r\n                System.out.println(\"Deadpool ataca con un daño de \" + ataque);\r\n                if(P2.defenderse() == 0) {\r\n                \tint reducirvida = P2.getVida()-ataque;\r\n                \tSystem.out.println(\"Wolverine recibe daño\");\r\n                \tP2.setVida(reducirvida);\r\n                }else {\r\n                \tSystem.out.println(\"Wolverine Se defienden\");\r\n                } \r\n            } else {\r\n                // Wolverine ataca\r\n                int ataque = P2.atacar();\r\n                System.out.println(\"Wolverine ataca con un daño de \" + ataque);\r\n                if(P2.defenderse() == 0) {\r\n                \tint reducirvida = P1.getVida()-ataque;\r\n                \tSystem.out.println(\"Deadpool recibe daño\");\r\n                \tP1.setVida(reducirvida);\r\n                }else {\r\n                \tSystem.out.println(\"Deadpool Se defienden\");\r\n                }                 \r\n            }    \r\n            // Cambiamos el turno\r\n            \r\n            PrimerAtaqque = !PrimerAtaqque;\r\n\r\n            // Pausa de 1 segundo\r\n            Thread.sleep(1000);\r\n            turno++;\r\n\t\t}\r\n\t\t if (P1.getVida() <= 0) {\r\n\t            System.out.println(\"Wolverine ha ganado la batalla.\");\r\n\t        } else {\r\n\t            System.out.println(\"Deadpool ha ganado la batalla.\");\r\n\t        }\r\n\t}\r\n\r\n}\r\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/java/JesusWay69.java",
    "content": "package ejercicio32;\n\nimport java.util.Scanner;\n\n/*\n * EJERCICIO:\n * ¡Deadpool y Wolverine se enfrentan en una batalla épica!\n * Crea un programa que simule la pelea y determine un ganador.\n * El programa simula un combate por turnos, donde cada protagonista posee unos\n * puntos de vida iniciales, un daño de ataque variable y diferentes cualidades\n * de regeneración y evasión de ataques.\n * Requisitos:\n * 1. El usuario debe determinar la vida inicial de cada protagonista.\n * 2. Cada personaje puede impartir un daño aleatorio:\n *    - Deadpool: Entre 10 y 100.\n *    - Wolverine: Entre 10 y 120.\n * 3. Si el daño es el máximo, el personaje que lo recibe no ataca en el\n * siguiente turno, ya que tiene que regenerarse (pero no aumenta vida).\n * 4. Cada personaje puede evitar el ataque contrario:\n *    - Deadpool: 25% de posibilidades.\n *    - Wolverine: 20% de posibilidades.\n * 5. Un personaje pierde si sus puntos de vida llegan a cero o menos.\n * Acciones:\n * 1. Simula una batalla.\n * 2. Muestra el número del turno (pausa de 1 segundo entre turnos).\n * 3. Muestra qué pasa en cada turno.\n * 4. Muestra la vida en cada turno.\n * 5. Muestra el resultado final.\n */\npublic class JesusWay69 {\n\n    public static void main(String[] args) throws InterruptedException {\n        boolean regenerateState = false;\n        Deadpool deadpool = new Deadpool();\n        Wolverine wolverine = new Wolverine();\n        Scanner sc = new Scanner(System.in);\n        System.out.print(\"Introduzca los puntos de inicio de Deadpool: \");\n        deadpool.lifePoints = sc.nextInt();\n        System.out.print(\"Introduzca los puntos de inicio de Wolverine: \");\n        wolverine.lifePoints = sc.nextInt();\n        battle(wolverine.lifePoints, deadpool.lifePoints, regenerateState,\n                wolverine.maxDamage, deadpool.maxDamage, wolverine.shield, deadpool.shield);\n\n    }\n\n    public static void battle(int wPoints, int dPoints, boolean regenerateState,\n            int vMaxDamage, int dMaxDamage, int vShield, int dShield) throws InterruptedException {\n        String name = \"\";\n        int round = 1;\n        while (wPoints > 0 && dPoints > 0) {\n            System.out.println(\"\\nRonda: \" + round);\n            \n            /////////////////////////////////////ATACA DEADPOOL////////////////////////////////////////////////////////\n            if (regenerateState) { //Comprobamos si en el turno del oponente ha generado ataque máximo y ha cambado el estado a true (empieza en false por defecto)\n                System.out.println(name + \" pierde su turno por haber recibido daño máximo y tiene que regenerarse \");\n                regenerateState = false;//Tras perder el turno se vuelve a poner el estado en false\n            } else if (Math.random() > (double) (vShield / 100)) {//En caso contrario generamos un número aleatorio entre 0 y 1 que sea mayor al porcentaje de la capacidad del escudo\n                int dDamage = (int) (Math.random() * dMaxDamage + 10);//Y otro número random entre 10 y el máximo daño del atacante en caso de que la condición anterior se cumpla\n                System.out.println(\" El ataque de Deadpool le ha restado \" + dDamage + \" puntos de vida a Wolverine\");\n                if (dDamage == 100) { //Dentro del if del ataque comprobamos si el daño coincide con el ataque mçaximo\n                    System.out.println(\"Ataque máximo de Deadpool\");\n                    regenerateState = true;//Cambiamos el estado a true para que en el turno del oponente salte el primer if y ceda turno\n                    name = \"Wolverine\";\n                }\n                wPoints = wPoints - dDamage;// Le restamos los puntos generados en el ataque al saldo del oponente\n                if (wPoints <= 0) {//Comprobamos si el oponente se ha quedado sin puntos de vida\n                    System.out.println(\"Wolverine se ha quedado sin puntos de vida\");\n                } else {// Si no es así imprimimos el saldo de puntos del oponente\n                    System.out.println(\"A Wolverine le quedan \" + wPoints + \" puntos\");\n                }\n            } else {//En caso de que el número generado sea menor a la probabilidad de escudo del oponente no se genera ataque y se informa sobre la defensa del oponente\n                System.out.println(\"Wolverine repele el ataque y no pierde puntos\");\n            }\n            //Todas las anotaciones anteriores sirven para el siguiente bloque de código que sigue dentro del while\n\n            /////////////////////////////////////ATACA WOLVERINE////////////////////////////////////////////////////////\n            if (regenerateState) {\n                System.out.println(name + \" pierde su turno por haber recibido daño máximo y tiene que regenerarse \");\n                regenerateState = false;\n            } else if (Math.random() > (double) (dShield / 100)) {\n                int vDamage = (int) (Math.random() * vMaxDamage + 10);\n                System.out.println(\" \\nEl ataque de Wolverine le ha restado \" + vDamage + \" puntos de vida a Deadpool\");\n                if (vDamage == 120) {\n                    System.out.println(\"Ataque máximo de Wolverine\");\n                    regenerateState = true;\n                    name = \"Deadpool\";\n                }\n                dPoints = dPoints - vDamage;\n                if (dPoints <= 0) {\n                    System.out.println(\"Deadpoool se ha quedado sin puntos de vida\");\n                } else {\n                    System.out.println(\"A Deadpool le quedan \" + dPoints + \" puntos\");\n                }\n            } else {\n                System.out.println(\"Deadpool repele el ataque y no pierde puntos\");\n            }\n            Thread.sleep(1000);\n            round++;\n        }\n\n        if (dPoints > 0) {//Una vez se quede uno de los contendientes a 0 o menos y se salga del while se comprueba cual de los 2 ha sido y se anuncia el ganador\n            System.out.println(\"Deadpool gana con \" + dPoints + \" puntos de vida restantes\");\n        } else {\n            System.out.println(\"Wolverine gana con \" + wPoints + \" puntos de vida restantes\");\n        }\n    }\n\n}\n\nclass Deadpool {\n\n    int maxDamage = 100;\n    int shield = 25;\n    int lifePoints;\n}\n\nclass Wolverine {\n\n    int maxDamage = 120;\n    int shield = 20;\n    int lifePoints;\n\n}\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/java/Josegs95.java",
    "content": "import java.util.Random;\nimport java.util.Scanner;\n\npublic class Josegs95 {\n    public static void main(String[] args) {\n        new Josegs95().battleSim();\n    }\n\n    private Superhero deadpool;\n    private Superhero wolverine;\n    final Scanner sc = new Scanner(System.in);\n    private Random rnd = new Random();\n\n    public void battleSim(){\n//        System.out.println(\"---Opciones---\");\n//        System.out.println(\"1. Empezar la batalla\");\n//        System.out.println(\"2. Salir del programa\");\n\n        try(sc){\n//            app: while(true){\n//                System.out.print(\"Introduzca la opción que desee: \");\n//                String option = sc.nextLine().strip();\n//                switch (option){\n//                    case \"1\":\n//                        initSuperheros();\n//                        battle();\n//                        break;\n//                    case \"2\":\n//                        System.out.println(\"Saliendo de la aplicación...\");\n//                        break;\n//                    default:\n//                        System.out.println(\"Opción inválida.\");\n//                }\n//            }\n\n            initSuperheros();\n            battle();\n        }\n    }\n\n    private void initSuperheros(){\n        deadpool = new Superhero(\"Deadpool\", askSuperheroHp(\"Deadpool\"),\n            10, 100, 25);\n        wolverine = new Superhero(\"Wolverine\", askSuperheroHp(\"Wolverine\"),\n                10, 120, 20);\n    }\n\n    private void battle(){\n        Random rnd = new Random();\n        Superhero first;\n        Superhero last;\n        int turn = 1;\n        while(true){\n            System.out.println();\n            System.out.println(\"Turno: \" + turn++);\n            System.out.println(deadpool);\n            System.out.println(wolverine);\n\n            if (rnd.nextBoolean()){\n                first = deadpool;\n                last = wolverine;\n            } else{\n                first = wolverine;\n                last = deadpool;\n            }\n\n            if (attack(first, last) || attack(last, first))\n                break;\n\n            try{\n                Thread.sleep(1000);\n            } catch (InterruptedException e) {\n                throw new RuntimeException(e);\n            }\n        }\n    }\n\n    private boolean attack(Superhero attacker, Superhero defender){\n        if (attacker.isStunned()){\n            System.out.println(attacker.getName() + \" está regenerandose y no puede atacar\");\n            attacker.setStunned(false);\n            return false;\n        }\n\n        Integer damage = rnd.nextInt(attacker.getATK_MIN(), attacker.getATK_MAX() + 1);\n\n        if (rnd.nextInt(100) <= defender.getEvasion()){\n            System.out.println(defender.getName() + \" esquivó el ataque de \" + attacker.getName());\n            return false;\n        }\n\n        System.out.println(attacker.getName() + \" hizo \" + damage + \" puntos de \" +\n                \"daño a \" + defender.getName());\n        defender.takeDamage(damage);\n\n        if (!defender.isAlive()){\n            System.out.println(\"\\n\" + attacker);\n            System.out.println(defender);\n            System.out.println(\"¡\" + attacker.getName() + \" es el ganador!\");\n            return true;\n        }\n\n        if (damage == attacker.getATK_MAX()){\n            defender.setStunned(true);\n        }\n\n        return false;\n    }\n\n    private Integer askSuperheroHp(String name){\n        boolean validOption = false;\n        Integer value = -1;\n        while (!validOption){\n            System.out.print(\"Introduzca la vida inicial de \" + name + \": \");\n            String input = sc.nextLine();\n            try{\n                value = Integer.parseInt(input);\n                validOption = true;\n            } catch (NumberFormatException e){\n                System.out.println(\"Error. Introduzca un número entero por favor\");\n            }\n        }\n        return value;\n    }\n\n    public class Superhero{\n        final private Integer HP_MAX;\n        final private Integer ATK_MIN;\n        final private Integer ATK_MAX;\n        final private Integer EVASION;\n\n        private String name;\n        private Integer hp;\n        private boolean stunned;\n\n        public Superhero(String name, Integer hp, Integer atkMin, Integer atkMax, Integer evasion){\n            HP_MAX = hp;\n            ATK_MIN = atkMin;\n            ATK_MAX = atkMax;\n            EVASION = evasion;\n\n            this.name = name;\n            this.hp = HP_MAX;\n            stunned = false;\n        }\n\n        public void takeDamage(Integer damage){\n            if (damage > hp)\n                hp = 0;\n            else\n                hp -= damage;\n        }\n\n        public String getName() {\n            return name;\n        }\n\n        public Integer getHp() {\n            return hp;\n        }\n\n        public Integer getEvasion() {\n            return EVASION;\n        }\n\n        public Integer getATK_MIN() {\n            return ATK_MIN;\n        }\n\n        public Integer getATK_MAX() {\n            return ATK_MAX;\n        }\n\n        public boolean isStunned() {\n            return stunned;\n        }\n\n        public void setStunned(boolean stunned) {\n            this.stunned = stunned;\n        }\n\n        public boolean isAlive(){\n            return hp > 0;\n        }\n\n        @Override\n        public String toString() {\n            return name + \"(\" + hp + \"/\" + HP_MAX + \")\";\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/java/adriDiazz.java",
    "content": "package Principal;\n\nimport java.util.Random;\nimport java.util.Scanner;\n\n// INTERFACE PARA ESTRATEGIAS DE ATAQUE Y DEFENSA\ninterface AttackStrategy {\n    int attack();\n}\n\ninterface DefenseStrategy {\n    boolean defend();\n}\n\n// CLASE ABSTRACTA PARA PERSONAJES\nabstract class Character {\n    protected int life;\n    protected AttackStrategy attackStrategy;\n    protected DefenseStrategy defenseStrategy;\n\n    public Character(int life, AttackStrategy attackStrategy, DefenseStrategy defenseStrategy) {\n        this.life = life;\n        this.attackStrategy = attackStrategy;\n        this.defenseStrategy = defenseStrategy;\n    }\n\n    public int getLife() {\n        return life;\n    }\n\n    public void setLife(int life) {\n        this.life = life;\n    }\n\n    public int attack() {\n        return attackStrategy.attack();\n    }\n\n    public boolean defend() {\n        return defenseStrategy.defend();\n    }\n}\n\n// IMPLEMENTACIONES DE ESTRATEGIAS DE ATAQUE Y DEFENSA\nclass RandomAttackStrategy implements AttackStrategy {\n    private final int minAttack;\n    private final int maxAttack;\n    private final Random random;\n\n    public RandomAttackStrategy(int minAttack, int maxAttack) {\n        this.minAttack = minAttack;\n        this.maxAttack = maxAttack;\n        this.random = new Random();\n    }\n\n    @Override\n    public int attack() {\n        return random.nextInt((maxAttack - minAttack) + 1) + minAttack;\n    }\n}\n\nclass RandomDefenseStrategy implements DefenseStrategy {\n    private final int evadeChance; // porcentaje de evasión\n    private final Random random;\n\n    public RandomDefenseStrategy(int evadeChance) {\n        this.evadeChance = evadeChance;\n        this.random = new Random();\n    }\n\n    @Override\n    public boolean defend() {\n        return random.nextInt(100) < evadeChance;\n    }\n}\n\n// CLASES DE PERSONAJES\nclass DeadPool extends Character {\n    public DeadPool(int life) {\n        super(life, new RandomAttackStrategy(10, 100), new RandomDefenseStrategy(25));\n    }\n}\n\nclass Wolverine extends Character {\n    public Wolverine(int life) {\n        super(life, new RandomAttackStrategy(10, 120), new RandomDefenseStrategy(20));\n    }\n}\n\n// CONTROLADOR DE LA BATALLA\nclass BattleController {\n    private final Character character1;\n    private final Character character2;\n\n    public BattleController(Character character1, Character character2) {\n        this.character1 = character1;\n        this.character2 = character2;\n    }\n\n    public void startBattle() {\n        int turn = 0;\n        while (character1.getLife() > 0 && character2.getLife() > 0) {\n            turn++;\n            System.out.println(\"Turno número \" + turn);\n            System.out.println(\"Vida \" + character1.getClass().getSimpleName() + \": \" + character1.getLife());\n            System.out.println(\"Vida \" + character2.getClass().getSimpleName() + \": \" + character2.getLife());\n\n            executeTurn(character1, character2);\n            if (character2.getLife() <= 0) break;\n\n            executeTurn(character2, character1);\n        }\n\n        declareWinner();\n    }\n\n    private void executeTurn(Character attacker, Character defender) {\n        int attackValue = attacker.attack();\n        if (!defender.defend()) {\n            System.out.println(attacker.getClass().getSimpleName() + \" ataca con \" + attackValue);\n            defender.setLife(defender.getLife() - attackValue);\n        } else {\n            System.out.println(defender.getClass().getSimpleName() + \" esquiva el ataque\");\n        }\n    }\n\n    private void declareWinner() {\n        if (character1.getLife() <= 0) {\n            System.out.println(character2.getClass().getSimpleName() + \" ha ganado!\");\n        } else if (character2.getLife() <= 0) {\n            System.out.println(character1.getClass().getSimpleName() + \" ha ganado!\");\n        }\n    }\n}\n\n// CLASE PRINCIPAL\npublic class adriDiazz {\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n\n        System.out.println(\"Vida DeadPool:\");\n        int vidaDeadpool = scanner.nextInt();\n\n        System.out.println(\"Vida Wolverine:\");\n        int vidaWolverine = scanner.nextInt();\n\n        Character deadPool = new DeadPool(vidaDeadpool);\n        Character wolverine = new Wolverine(vidaWolverine);\n\n        BattleController battle = new BattleController(deadPool, wolverine);\n        battle.startBattle();\n    }\n}\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/java/asjordi.java",
    "content": "import java.util.Random;\nimport java.util.Scanner;\n\npublic class asjordi {\n\n    public static void main(String[] args) {\n        Scanner sc = new Scanner(System.in);\n        int numTurno = 0;\n\n        System.out.println(\"Bienvenido a Deadpool vs Wolverine\");\n        System.out.println(\"Ingresa la vida de Deadpool: \");\n        int vidaDeadpool = sc.nextInt();\n        System.out.println(\"Ingresa la vida de Wolverine: \");\n        int vidaWolverine = sc.nextInt();\n\n        Personaje deadpool = new Personaje(TipoPersonaje.DEADPOOL, vidaDeadpool);\n        Personaje wolverine = new Personaje(TipoPersonaje.WOLVERINE, vidaWolverine);\n\n        while (deadpool.getVida() > 0 || wolverine.getVida() > 0) {\n            numTurno++;\n            System.out.println(\"Turno \" + numTurno);\n            System.out.println(\"Deadpool: \" + deadpool.getVida() + \" vida\");\n            System.out.println(\"Wolverine: \" + wolverine.getVida() + \" vida\");\n\n            System.out.println(\"Deadpool ataca a Wolverine\");\n            deadpool.atacar(wolverine);\n            System.out.println(\"Wolverine ataca a Deadpool\");\n            wolverine.atacar(deadpool);\n\n            if (deadpool.getVida() <= 0) {\n                System.out.println(\"Wolverine ha ganado\");\n                break;\n            } else if (wolverine.getVida() <= 0) {\n                System.out.println(\"Deadpool ha ganado\");\n                break;\n            }\n        }\n    }\n\n    static class Personaje {\n        private TipoPersonaje personaje;\n        private double vida;\n        private double ataque;\n        private final Random r;\n        private double ultimoAtaque;\n\n        public Personaje(TipoPersonaje personaje, double vida) {\n            this.personaje = personaje;\n            this.vida = vida;\n            this.r = new Random();\n            definirPoderAtaque();\n        }\n\n        private void definirPoderAtaque() {\n            this.ataque = r.nextInt(personaje.getMinAtaque(), personaje.getMaxAtaque() + 1);\n        }\n\n        public void recibirAtaque(double ataque) {\n            if (r.nextInt(1, 101) > personaje.getPosEvitarAtaque()) {\n                this.vida -= ataque;\n            }\n        }\n\n        public void atacar(Personaje personaje) {\n            personaje.recibirAtaque(this.ataque);\n            System.out.println(\"Ataque de \" + this.personaje + \" a \" + personaje.personaje + \" con \" + this.ataque + \" de daño\");\n        }\n\n        public double getVida() {\n            return vida;\n        }\n\n        public void setVida(double vida) {\n            this.vida = vida;\n        }\n\n        public double getAtaque() {\n            return ataque;\n        }\n\n        public void setAtaque(double ataque) {\n            this.ataque = ataque;\n        }\n    }\n\n    enum TipoPersonaje {\n        DEADPOOL(10, 100, 25),\n        WOLVERINE(10, 120, 20);\n        private final int minAtaque;\n        private final int maxAtaque;\n        private int posEvitarAtaque;\n\n        TipoPersonaje(int minDamage, int maxAtaque, int posEvitarAtaque) {\n            this.minAtaque = minDamage;\n            this.maxAtaque = maxAtaque;\n            this.posEvitarAtaque = posEvitarAtaque;\n        }\n\n        public int getMinAtaque() {\n            return minAtaque;\n        }\n\n        public int getMaxAtaque() {\n            return maxAtaque;\n        }\n\n        public int getPosEvitarAtaque() {\n            return posEvitarAtaque;\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/java/danhingar.java",
    "content": "import java.util.Random;\n\npublic class danhingar {\n\n    public static void main(String[] args) throws InterruptedException {\n        Player deepool = new Player(1000, 100, \"Deadpool\");\n        Player wolverine = new Player(1000, 120, \"Wolverine\");\n        Battle battle = new Battle(deepool, wolverine);\n        battle.init();\n    }\n\n}\n\nclass Player {\n    private String name;\n    private Integer health;\n    private Integer maxDamage;\n\n    public Player(Integer health, Integer maxDamage, String name) {\n        this.health = health;\n        this.maxDamage = maxDamage;\n        this.name = name;\n    }\n\n    public Integer getHealth() {\n        return health;\n    }\n\n    public void setHealth(Integer health) {\n        this.health = health;\n    }\n\n    public Integer getMaxDamage() {\n        return maxDamage;\n    }\n\n    public void setMaxDamage(Integer maxDamage) {\n        this.maxDamage = maxDamage;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public Integer damage() {\n        Random random = new Random();\n\n        int min = 10;\n        int max = this.maxDamage;\n\n        return random.nextInt(max - min + 1) + min;\n    }\n\n}\n\nclass Battle {\n\n    private Player player1;\n    private Player player2;\n\n    public Battle(Player player1, Player player2) {\n        this.player1 = player1;\n        this.player2 = player2;\n    }\n\n    public void init() throws InterruptedException {\n        int shiftNumber = 1;\n        Integer attackDeepool = 0;\n        Integer attackWolverine = 0;\n        Boolean regenerate = Boolean.FALSE;\n        while (player1.getHealth() > 0 && player2.getHealth() > 0) {\n            System.out.println(\"\\nTurno \" + shiftNumber);\n            Double preventAttackWolverine = Math.random();\n            if (regenerate) {\n                System.out.println(\"Deadpool se está regenerando y no ataca.\");\n                regenerate = Boolean.FALSE;\n            } else if (preventAttackWolverine > 0.2) {\n                attackDeepool = attack(player1, player2);\n                System.out.printf(\"%s ataca a %s con %d puntos de daño.\\n\", player1.getName(), player2.getName(),\n                        attackDeepool);\n                if (attackDeepool == 100) {\n                    System.out.printf(\n                            \"¡Golpe crítico de %s! %s no atacará en el siguiente turno ya que tiene que regenerarse.\\n\",\n                            player1.getName(), player2.getName());\n                    regenerate = Boolean.TRUE;\n                }\n\n                if (player2.getHealth() <= 0) {\n                    System.out.printf(\"La vida de %s ha llegado a cero.\\n\", player2.getName());\n                    break;\n                }\n                System.out.printf(\"Vida restante de %s: %d\\n\", player2.getName(), player2.getHealth());\n\n            } else {\n                System.out.printf(\"¡%s esquiva el ataque de %s!\\n\", player2.getName(), player1.getName());\n            }\n\n            Double preventAttackDeepool = Math.random();\n            if (regenerate) {\n                System.out.println(\"Wolverine se está regenerando y no ataca.\");\n                regenerate = Boolean.FALSE;\n            } else if (preventAttackDeepool > 0.25) {\n                attackWolverine = attack(player2, player1);\n                if (attackDeepool == 120) {\n                    System.out.printf(\n                            \"¡Golpe crítico %s! %s no atacará en el siguiente turno ya que tiene que regenerarse.\\n\",\n                            player2.getName(), player1.getName());\n                    regenerate = Boolean.TRUE;\n                }\n                System.out.printf(\"%s ataca a %s con %d puntos de daño.\\n\", player2.getName(), player1.getName(),\n                        attackWolverine);\n                if (player1.getHealth() <= 0) {\n                    System.out.printf(\"La vida de %s ha llegado a cero.\\n\", player1.getName());\n                    break;\n                }\n                System.out.printf(\"Vida restante de %s: %d\\n\", player1.getName(), player1.getHealth());\n\n            } else {\n                System.out.printf(\"¡%s esquiva el ataque de %s!\\n\", player1.getName(), player2.getName());\n            }\n            shiftNumber++;\n            Thread.sleep(1000);\n        }\n        finish(player1, player2);\n    }\n\n    public void turn(Player player1, Player Player2, Boolean regenerate) {\n\n    }\n\n    public Integer attack(Player attacker, Player defender) {\n        Integer damage = attacker.damage();\n        Integer newHealth = defender.getHealth() - damage;\n        defender.setHealth(newHealth);\n        return damage;\n    }\n\n    public void finish(Player player1, Player player2) {\n        if (player1.getHealth() < 0) {\n            System.out.printf(\"%s ha ganado la batalla!!!.\\n\", player2.getName());\n        } else {\n            System.out.printf(\"%s ha ganado la batalla!!!.\\n\", player1.getName());\n        }\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/java/euu92.java",
    "content": "import java.util.Random;\nimport java.util.Scanner;\n\npublic class euudev {\n\n    static Deadpool deadpool = new Deadpool();\n    static Wolverine wolverine = new Wolverine();\n    static Scanner scanner = new Scanner(System.in);\n    static Random random = new Random();\n\n    public static void main(String[] args) {\n\n        AdministradorBatalla administradorBatalla = new AdministradorBatalla();\n\n        administradorBatalla.setInitialHp();\n        administradorBatalla.simBattle();\n\n    }\n\n    static class AdministradorBatalla {\n\n        public void setInitialHp() {\n            boolean deadpoolHpSet = false;\n            boolean wolverineHpSet = false;\n\n            while (!deadpoolHpSet || !wolverineHpSet) {\n                if (!deadpoolHpSet) {\n                    System.out.println(\"Selecciona un personaje:\");\n                    System.out.println(\"1. Deadpool\");\n                    System.out.println(\"2. Wolverine\");\n\n                    int action = scanner.nextInt();\n                    scanner.nextLine();\n\n                    switch (action) {\n                        case 1:\n                            setDeadpoolHp();\n                            deadpoolHpSet = true;\n                            break;\n                        case 2:\n                            setWolverineHp();\n                            wolverineHpSet = true;\n                            break;\n                        default:\n                            System.out.println(\"Acción no válida. Inténtalo de nuevo.\");\n                    }\n                } else if (!wolverineHpSet) {\n                    setWolverineHp();\n                    wolverineHpSet = true;\n                } else if (!deadpoolHpSet) {\n                    setDeadpoolHp();\n                    deadpoolHpSet = true;\n                }\n            }\n        }\n\n        public void simBattle () {\n            int turn = 1;\n            boolean deadpoolSkipTurn = false;\n            boolean wolverineSkipTurn = false;\n\n            while (deadpool.getHp() > 0 && wolverine.getHp() > 0) {\n                System.out.println(\"Turno \" + turn);\n                if (!deadpoolSkipTurn) {\n                    if (!evadeAttack(wolverine)) {\n                        int damage = random.nextInt(91) + 10;\n                        if (damage == 100) {\n                            wolverineSkipTurn = true;\n                        }\n                        wolverine.setHp(wolverine.getHp() - damage);\n                        System.out.println(\"Deadpool ataca a Wolverine con \" + damage + \" de daño.\");\n                    } else {\n                        System.out.println(\"Wolverine evade el ataque de Deadpool.\");\n                    } \n                } else {\n                    deadpoolSkipTurn = false;\n                    System.out.println(\"Deadpool se está recuperando y no puede atacar.\");\n                }\n\n                if (wolverine.getHp() <= 0) break;\n\n                if (!wolverineSkipTurn) {\n                    if(!evadeAttack(deadpool)) {\n                        int damage = random.nextInt(111) + 10;\n                        if (damage == 120) {\n                            deadpoolSkipTurn = true;\n                        }\n                        deadpool.setHp(deadpool.getHp() - damage);\n                        System.out.println(\"Wolverine ataca a Deadpool con \" + damage + \" de daño.\");\n                    } else {\n                        System.out.println(\"Deadpool evade el ataque de Wolverine.\");\n                    }\n                } else {\n                    wolverineSkipTurn = false;\n                    System.out.println(\"Wolverine se está recuperando y no puede atacar.\");\n                }\n\n                System.out.println(\"Vida de Deadpool: \" + deadpool.getHp());\n                System.out.println(\"Vida de Wolverine: \" + wolverine.getHp());\n\n                turn++;\n                try {\n                    Thread.sleep(1000);\n                } catch (InterruptedException e) {\n                    e.printStackTrace();\n                }\n            } \n\n            if (deadpool.getHp() <= 0) {\n                System.out.println(\"Wolverine gana la batalla!\");\n            } else {\n                System.out.println(\"Deadpool gana la batalla!\");\n            }\n        }\n\n        public static boolean evadeAttack(Character character) {\n            int chance = random.nextInt(100);\n            if(character instanceof Deadpool) {\n                return chance < 25;\n            } else if (character instanceof Wolverine) {\n                return chance < 20;\n            }\n            return false;\n        }\n\n        public void setDeadpoolHp() {\n            System.out.println(\"Establece HP para Deadpool: \");\n            int hp = scanner.nextInt();\n            scanner.nextLine();\n            deadpool.setHp(hp);\n            System.out.println(\"HP de Deadpool establecida\");\n        }\n\n        public void setWolverineHp() {\n            System.out.println(\"Establece HP para Wolverine: \");\n            int hp = scanner.nextInt();\n            scanner.nextLine();\n            wolverine.setHp(hp);\n            System.out.println(\"HP de Wolverine establecida\");\n        }\n    }\n}\n\nclass Deadpool extends Character {\n    public Deadpool() {\n        super();\n    }\n}\n\nclass Wolverine extends Character {\n    public Wolverine() {\n        super();\n    }\n}\n\nclass Character {\n    private int hp;\n\n    public int getHp() {\n        return hp;\n    }\n\n    public void setHp(int hp) {\n        this.hp = hp;\n    }\n}\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/java/martinbohorquez.java",
    "content": "import java.util.Random;\nimport java.util.Scanner;\nimport java.util.concurrent.TimeUnit;\n\npublic class martinbohorquez {\n    static Random random = new Random();\n\n    public static void main(String[] args) throws InterruptedException {\n        Hero deadpool = new Hero(\"Deadpool\");\n        Hero wolverine = new Hero(\"Wolverine\");\n        Scanner sc = new Scanner(System.in);\n        System.out.println(\"Ingresar la vida de Deadpool (número de 1 a 1000):\");\n        deadpool.setHealth(Integer.parseInt(sc.nextLine()));\n        deadpool.setMinDamage(10);\n        deadpool.setMaxDamage(100);\n        deadpool.setEvasionRate(0.25f);\n\n        System.out.println(\"Ingresar la vida de Wolverine (número de 1 a 1000):\");\n        wolverine.setHealth(Integer.parseInt(sc.nextLine()));\n        wolverine.setMinDamage(10);\n        wolverine.setMaxDamage(120);\n        wolverine.setEvasionRate(0.2f);\n\n        int turn = 0;\n\n        while (deadpool.getHealth() > 0 && wolverine.getHealth() > 0) {\n            System.out.printf(\"%nTurno %s:%n\", ++turn);\n            if (deadpool.attack(wolverine)) break;\n            if (wolverine.attack(deadpool)) break;\n            TimeUnit.SECONDS.sleep(1);\n        }\n\n        if (deadpool.getHealth() > 0)\n            System.out.printf(\"Deadpool gana la batalla con %s de vida restante!%n\", deadpool.getHealth());\n        else System.out.printf(\"Wolverine gana la batalla con %s de vida restante!%n\", wolverine.getHealth());\n    }\n\n    static class Hero {\n        private String name;\n        private int health;\n        private int minDamage;\n        private int maxDamage;\n        private float evasionRate;\n        private boolean regenerate;\n\n        public Hero(String name) {\n            this.name = name;\n            regenerate = false;\n        }\n\n        public String getName() {\n            return name;\n        }\n\n        public boolean isRegenerate() {\n            return regenerate;\n        }\n\n        public void setRegenerate(boolean regenerate) {\n            this.regenerate = regenerate;\n        }\n\n        public int getHealth() {\n            return health;\n        }\n\n        public void setHealth(int health) {\n            this.health = health;\n        }\n\n        public int getMinDamage() {\n            return minDamage;\n        }\n\n        public void setMinDamage(int minDamage) {\n            this.minDamage = minDamage;\n        }\n\n        public int getMaxDamage() {\n            return maxDamage;\n        }\n\n        public void setMaxDamage(int maxDamage) {\n            this.maxDamage = maxDamage;\n        }\n\n        public float getEvasionRate() {\n            return evasionRate;\n        }\n\n        public void setEvasionRate(float evasionRate) {\n            this.evasionRate = evasionRate;\n        }\n\n        private int getDamage() {\n            return random.nextInt(this.getMinDamage(), this.getMaxDamage() + 1);\n        }\n\n        public void decreaseHealth(int damage) {\n            this.health -= damage;\n        }\n\n        private boolean attack(Hero hero) {\n            if (isRegenerate()) {\n                System.out.printf(\"%s se está regenerando y no ataca!%n\", getName());\n                setRegenerate(false);\n            } else if (random.nextFloat() > getEvasionRate()) {\n                int damage = getDamage();\n                System.out.printf(\"%s ataca a %s con %d de daño!%n\"\n                        , getName(), hero.getName(), damage);\n                if (damage == getMaxDamage()) {\n                    System.out.printf(\"%s da un golpe crítico! %s no atacará en el siguiente turno.%n\"\n                            , getName(), hero.getName());\n                    hero.setRegenerate(true);\n                }\n\n                hero.decreaseHealth(damage);\n\n                if (hero.getHealth() <= 0) {\n                    System.out.printf(\"La vida de %s ha llegado a 0!%n\", hero.getName());\n                    return true;\n                } else {\n                    System.out.printf(\"Vida restante de %s: %d%n\", hero.getName(), hero.getHealth());\n                }\n            } else System.out.printf(\"¡%s esquiva el ataque!%n\", hero.getName());\n            return false;\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/java/whiterbb.java",
    "content": "import java.util.Random;\nimport java.util.Scanner;\n\n//GlobalConstants\ninterface GlobalConstants{\n    static final int DEADPOOL_MIN_DAMAGE = 10;\n    static final int DEADPOOL_MAX_DAMAGE = 100;\n    static final int WOLVERINE_MIN_DAMAGE = 10;\n    static final int WOLVERINE_MAX_DAMAGE = 120;\n    static final double DEADPOOL_DODGE_PROBABILITY = 0.25;\n    static final double WOLVERINE_DODGE_PROBABILITY = 0.20;\n}\n\npublic class whiterbb implements GlobalConstants{\n\n    /* Global Variables (I know that we shouldn't do it. But in this case it doesn't matter.)\n    *  We can create a helper class to return object with values like isRegenerating boolean.\n    */\n    static Random random = new Random();\n    static boolean isDeadpoolRegenerating = false;\n    static boolean isWolverineRegenerating = false;\n\n    public static void main(String[] args) {\n\n        Scanner scanner = new Scanner(System.in);\n\n        System.out.println(\"Welcome to this Epic Battle\");\n\n        System.out.println(\"Deadpool's life points (LP): \");\n        int deadpoolLP = scanner.nextInt();\n        System.out.println(\"Wolverine's life Points (LP): \");\n        int wolverineLP = scanner.nextInt();\n\n        simulateCombat(deadpoolLP, wolverineLP);\n    }\n\n    public static void simulateCombat(int deadpoolLP, int wolverineLP) {\n        int turn = 1;\n\n        //Loop until anyone's lifepoints is 0\n        while (deadpoolLP > 0 && wolverineLP > 0) {\n            System.out.println(\"Turn: \" + turn);\n\n            // Deadpool attacks if he is not regenerating\n            \n            //Parameters: attack(Enemy's name, Enemy's LP, AttackerMinDamage, AttackerMaxDamage, Enemy's DodgeProbability)\n            if (!isDeadpoolRegenerating) {\n                wolverineLP = attack(\"Wolverine\", wolverineLP, DEADPOOL_MIN_DAMAGE, DEADPOOL_MAX_DAMAGE,\n                        WOLVERINE_DODGE_PROBABILITY);\n            } else {\n                System.out.println(\"Deadpool is regenerating, cannot attack!\");\n            }\n            //Reset Regenerating Status\n            isDeadpoolRegenerating = false;\n\n            if (wolverineLP > 0 && !isWolverineRegenerating) {\n                deadpoolLP = attack(\"Deadpool\", deadpoolLP, WOLVERINE_MIN_DAMAGE, WOLVERINE_MAX_DAMAGE,\n                        DEADPOOL_DODGE_PROBABILITY);\n            } else {\n                System.out.println(\"Wolverine is regenerating, cannot attack!\");\n            }\n            \n            //Reset Regenerating Status\n            isWolverineRegenerating = false;\n\n            System.out.println(\"Remaining Deadpool's Life Points: \" + deadpoolLP);\n            System.out.println(\"Remaining Wolverine's Life Points: \" + wolverineLP);\n\n            turn++;\n            waitOneSecond();\n        }\n\n        displayWinner(deadpoolLP);\n    }\n\n    public static int attack(String enemyname, int enemyLP, int minDamage, int maxDamage, double dodgeProbability) {\n        \n        if (random.nextDouble() <= dodgeProbability) {\n            System.out.println(enemyname + \" dodge the attack!\");\n            return enemyLP;\n        } else {\n            int damage = generateRandomDamage(minDamage, maxDamage);\n\n            //Attacker\n            String attacker = (enemyname.equals(\"Deadpool\")) ? \"Wolverine\" : \"Deadpool\";\n            \n            if (damage == maxDamage) {\n                if (enemyname.equals(\"Deadpool\")) {\n                    System.out.println(\"Wolverine does an amazing attack!\");\n                    enemyLP -= damage;\n                    isDeadpoolRegenerating = true;\n                } else {\n                    System.out.println(\"Deadpool does an amazing attack!\");\n                    enemyLP -= damage;\n                    isWolverineRegenerating = true;\n                }\n\n                return enemyLP;\n            }\n\n            System.out.println(attacker + \" attacks with \" + damage + \" damage!\");\n            enemyLP -= damage;\n\n            return enemyLP;\n        }\n\n    }\n\n    public static int generateRandomDamage(int minDamage, int maxDamage){\n        return random.nextInt(maxDamage - minDamage + 1) + minDamage;\n    }\n\n    public static void displayWinner(int deadpoolLP){\n        if(deadpoolLP <= 0){\n            System.out.println(\"Wolverine wins!\");\n        }else{\n            System.out.println(\"Deadpool wins!\");\n        }\n    }\n\n    static void waitOneSecond() {\n        try {\n            Thread.sleep(1000);\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/javascript/DavidMoralesDeveloper.js",
    "content": "const readline = require(\"readline\");\nconst rl = readline.createInterface({\n  input: process.stdin, // For user input from the console\n  output: process.stdout, // For displaying output to the console\n});\n\n\nlet deadPool = [\n  {\n    nombre: \"DeadPool\",\n    vida: 1000,\n    ataque() {\n      return Math.floor(Math.random() * 100) + 1;\n    },\n    regeneracion() {\n      const vidaRecuperada = Math.round(this.ataque() * 0.1);\n      this.vida += vidaRecuperada;\n      // console.log(`¡${this.nombre} se regenera ${vidaRecuperada} de vida! Vida actual: ${this.vida}`);\n      return vidaRecuperada;\n    }, //10 porciento del ataque,\n    evasion() {\n      return Math.floor(Math.random() * 100) + 1 < 25 ? 1 : 0;\n    }, //25% de evasion 1 acerti la evasion 0 recive el ataque\n  },\n];\nlet wolverin = [\n  {\n    nombre: \"Wolverin\",\n    vida: 1000,\n    ataque() {\n      return Math.floor(Math.random() * 120) + 1;\n    },\n    regeneracion() {\n      const vidaRecuperada = Math.round(this.ataque() * 0.1);\n      this.vida += vidaRecuperada;\n      // console.log(`¡${this.nombre} se regenera ${vidaRecuperada} de vida! Vida actual: ${this.vida}`);\n      return vidaRecuperada;\n    }, //10 porciento del ataque,\n    evasion() {\n      return Math.floor(Math.random() * 100) + 1 < 20 ? 1 : 0;\n    }, //25% de evasion\n  },\n];\nlet pierdeturnoDeadPool = false;\n  let pierdeturnoWolverin = false;\n\nfunction batallaDvsW() {\n  console.log(\"--------------------------comienza ataque-------------\");\n\n  let turno = 1;\n\n  while (wolverin[0].vida > 0 && deadPool[0].vida > 0) {\n    console.log(`Turno ${turno}`);\n\n    //turno de deadpool\n    if (deadPool[0].vida > 0 ) {\n        if (pierdeturnoDeadPool) {\n      console.log(\" Dead poolRegenerandome\");\n      pierdeturnoDeadPool = false;\n    }else{\n      let dañoDeadpool = deadPool[0].ataque();\n      console.log(`DeadPool ataca con ${dañoDeadpool}`);\n      if (dañoDeadpool === 100) {\n        console.log(\n          `¡ATAQUE CRÍTICO DE ${deadPool[0].nombre}! ${wolverin[0].nombre} pierde su próximo turno.`\n        );\n        pierdeturnoWolverin = true;\n\n        let vidaRegeneradaDeadPool = deadPool[0].regeneracion(); // Deadpool se regenera\n        console.log(\n          `${deadPool[0].nombre} gana ${vidaRegeneradaDeadPool} de recuperación. Vida de ${deadPool[0].nombre}: ${deadPool[0].vida}`\n        );\n      } else {\n        if (wolverin[0].evasion()) {\n          console.log(\"Wolverin a evadido el daño\");\n        } else {\n          wolverin[0].vida -= dañoDeadpool;\n          console.log(\n            `Wolverin recibe ${dañoDeadpool} daño. Vide de Wolverin ${wolverin[0].vida}`\n          );\n        }\n      }\n    }\n    }\n\n    //vemos si wolverin sigue vivo\n    if (wolverin.vida <= 0) {\n      console.log(`¡Wolverin ha sido derrotado!`);\n      break; // Salimos del bucle si Wolverin muere\n    }\n\n    //tueno de wolverin\n    if (wolverin[0].vida > 0 ) {\n        if (pierdeturnoWolverin) {\n      console.log(\"Wolverin regenerandome\");\n      pierdeturnoWolverin = false;\n    }else {\n      let dañoWolverin = wolverin[0].ataque();\n      console.log(`Wolverin ataca con ${dañoWolverin}`);\n      if (dañoWolverin === 120) {\n        console.log(\n          `¡ATAQUE CRÍTICO DE ${wolverin[0].nombre}! ${deadPool[0].nombre} pierde su próximo turno.`\n        );\n        pierdeturnoDeadPool = true; // Deadpool pierde el siguiente turno\n        let vidaRegeneradaWolverin = wolverin[0].regeneracion(); // Wolverine se regenera\n        console.log(\n          `${wolverin[0].nombre} gana ${vidaRegeneradaWolverin} de recuperación. Vida de ${wolverin[0].nombre}: ${wolverin[0].vida}`\n        );\n      } else {\n        if (deadPool[0].evasion()) {\n          console.log(\"Deadpool a evadido el ataque\");\n        } else {\n          deadPool[0].vida -= dañoWolverin;\n          console.log(\n            `DeadPool recibe ${dañoWolverin} daño. Vide de DeadPool ${deadPool[0].vida}`\n          );\n        }\n      }\n    }\n    }\n\n    if (deadPool[0].vida < 0) {\n      console.log(`DeadPool ha sido derrotado!`);\n      break; // Salimos del bucle si Wolverin muere\n    }\n\n    turno++;\n}\ninit()\n  //-------------------------preguntas de vida-------------inicia funcion \n  \n}\n\nfunction init() {\n    rl.question(\n      \"para comenzar La batalla asigna la vida de los  dead pool \",\n      (respuesta1) => {\n        deadPool[0].vida = respuesta1;\n        rl.question(\"Asignar vida a Wolverin \", (respuesta) => {\n          wolverin[0].vida = respuesta;\n          batallaDvsW()\n          respuesta !== \"salir\" ? batallaDvsW() : console.log(\"accion no permitida vuelve a intentar\", init())\n        });\n      }\n    );\n  }\n\ninit();\n\n\n\n\n\n\n  \n \n\n\n\n//--------------------------------------------------------------wile metodo------------------------------------\n\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #32 - JavaScript -> Jesus Antonio Escamilla */\n\n/**\n * BATALLA DEADPOOL Y WOLVERINE\n * Utilizando la Terminal para pedir datos y agregarlos.\n */\n\nconst readline = require('readline');\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nclass Character{\n    constructor(name, maxDamage, evadeChance) {\n        this.name = name;\n        this.maxDamage = maxDamage;\n        this.evadeChance = evadeChance;\n        this.health = 0;\n    }\n\n    setHealth(health){\n        this.health = health;\n    }\n\n    attack(){\n        return Math.floor(Math.random() * (this.maxDamage - 10 * 1)) + 10;\n    }\n\n    evade(){\n        return Math.random() < this.evadeChance;\n    }\n}\n\nfunction simulateBattle(deadpoolHealth, wolverineHealth){\n    const deadpool = new Character(\"DeadPool\", 100, 0.25);\n    const wolverine = new Character(\"Wolverine\", 120, 0.20);\n\n    deadpool.setHealth(deadpoolHealth);\n    wolverine.setHealth(wolverineHealth);\n\n    let turn = 1;\n    let deadpoolSkip = false;\n    let wolverineSkip = false;\n\n    function battleTurn() {\n        console.log(`\\nTurno ${turn}`);\n\n        if (!deadpoolSkip) {\n            if (!wolverine.evade()) {\n                const damage = deadpool.attack();\n                if (damage == 100) wolverineSkip = true;\n                wolverine.health -= damage;\n                console.log(`DeadPool ataca a Wolverine  y causa ${damage} de daño.`);\n            } else {\n                console.log(\"Wolverine evade el ataque de DeadPool.\");\n            }\n        } else {\n            console.log(\"DeadPool está recreándose y no puede atacar.\");\n            deadpoolSkip = false;\n        }\n    \n        if (wolverine.health <= 0) {\n            console.log(`Wolverine ha sido derrotado. DeadPool gana la batalla, con ${deadpool.health} de vida`);\n            rl.close();\n            return;\n        }\n    \n        if (!wolverineSkip) {\n            if (!deadpool.evade()) {\n                const damage = wolverine.attack();\n                if (damage == 120) deadpoolSkip = true;\n                deadpool.health -= damage;\n                console.log(`Wolverine ataca a DeadPool y causa ${damage} de daño.`);\n            } else {\n                console.log(\"DeadPool evade el ataque de Wolverine.\");\n            }\n        } else {\n            console.log(\"Wolverine está recreándose y no puede atacar.\");\n            wolverineSkip = false;\n        }\n    \n        if (deadpool.health <= 0) {\n            console.log(`DeadPool ha sido derrotado. Wolverine gana la batalla, con ${wolverine.health} de vida`);\n            rl.close();\n            return;\n        }\n    \n        console.log(`Vida restante - DeadPool: ${deadpool.health}, Wolverine: ${wolverine.health}`);\n        turn++;\n    \n        setTimeout(battleTurn, 1000);\n    }\n\n    battleTurn();\n}\n\n// Determina la vida inicial de cada protagonista\nrl.question(\"Ingresa la vida inicial de Deadpool: \", (deadpoolInitialHealth) => {\n    rl.question(\"Ingresa la vida inicial de Wolverine: \", (wolverineInitialHealth) => {\n        simulateBattle(parseInt(deadpoolInitialHealth), parseInt(wolverineInitialHealth));\n    });\n});"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/javascript/JesusEs1312.js",
    "content": "class Character {\n    constructor(name, hp, regeneration, evasion){\n        this.name         = name;\n        this.hp           = hp;\n        this.regeneration = regeneration;\n        this.evasion      = evasion;\n        this.damage       = 0;\n    }\n}\n\nclass Battle {\n\n    constructor(){}\n    \n    regenaration(character){\n        let probability = Math.random() * 100 + 1; \n        if(probability <= character.regenaration){\n            console.log(`${character.name} esquivo el golpe xD`);\n            console.log(`${character.name} se esta regenerando...`);\n            character.hp =+ character.regenaration;\n            console.log(`${character.name} se regeneró ${character.regenaration}%, su nueva vida: ${character.hp}`);\n            return true;\n        }\n        \n        return false;\n    }\n\n    fight(){\n        console.log(\"Entreeeee a la batalla\");\n        let deadpool = new Character(\"Deadpool\", 1000, 25, 25);\n        let wolverine = new Character(\"Wolverine\", 1200, 15, 20);\n        while(deadpool.hp > 0 && wolverine.hp > 0){\n            let random1 = Math.random() * (100 - 10) + 10;\n            let random2 = Math.random() * (120 - 10) + 10;\n            deadpool.damage = parseInt(random1); \n            wolverine.damage = parseInt(random2);\n            let min = 0;\n            let max = 2;\n            let turn = parseInt(Math.random() * (max - min) + min);\n            let regenaration = false;\n            if(turn == 0){\n                console.log(`Golpea Deadpool con ${deadpool.damage} de daño`);\n                regenaration = this.regenaration(deadpool);  \n                if(regenaration){\n                    min = 1;\n                    max = 2;\n                } else {\n                    wolverine.hp -= deadpool.damage;\n                    console.log(`Vida restante de ${wolverine.name}: ${wolverine.hp}`);\n                    if(deadpool.damage == 100){       \n                        console.log(`${deadpool.name} dio un critico`);\n                        min = 0;\n                        max = 1;\n                    } else {\n                        min = 1;\n                        max = 2;\n                    }\n                }\n            } else {\n                console.log(`Golpea Wolverine con ${deadpool.damage} de daño`);\n                regenaration = this.regenaration(wolverine);  \n                if(regenaration){\n                    min = 0;\n                    max = 1;\n                } else {\n                    deadpool.hp -= wolverine.damage;\n                    console.log(`Vida restante de ${deadpool.name}: ${deadpool.hp}`);\n                    if(wolverine.damage == 120){       \n                        console.log(`${wolverine.name} dio un critico`);\n                        min = 1;\n                        max = 2;\n                    } else {\n                        min = 0;\n                        max = 1;\n                    }\n                }\n            }\n        }\n\n        if(deadpool.hp > 0){\n            console.log(\"----- Deadpool gana -----\");\n        } else {\n            console.log(\"----- Wolverine gana -----\");\n        }\n    }\n\n}\n\nlet battle = new Battle();\nbattle.fight();\n    \n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/javascript/Rafacv23.js",
    "content": "/* \n    Creado por Rafa Canosa\n    Github: https://github.com/Rafacv23\n    Website: https://www.rafacanosa.dev\n*/\n\n// Definimos las constantes de la vida de ambos personajes\nlet DEADPOOL_HEALTH = 1000\nlet WOLVERINE_HEALTH = 1000\nlet turn = 0\n\n// Definimos los objetos con los datos de cada personaje\nconst characters = [\n  {\n    name: \"Deadpool\",\n    health: DEADPOOL_HEALTH,\n    critic: false,\n    minDamage: 10,\n    maxDamage: 100,\n    dodge: 0.25,\n  },\n  {\n    name: \"Wolverine\",\n    health: WOLVERINE_HEALTH,\n    critic: false,\n    minDamage: 10,\n    maxDamage: 120,\n    dodge: 0.2,\n  },\n]\n\n//Funcion para generar el valor del ataque de cada personaje\nfunction getAttackValue(min, max) {\n  min = Math.ceil(min)\n  max = Math.floor(max)\n  return Math.floor(Math.random() * (max - min) + min)\n}\n\n// Función para hacer que el bucle se espere un segundo entre cada iteracion (turno del combate)\nfunction sleep(ms) {\n  return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\n// función que ejecuta el turno de cada personaje\nfunction attack(atack, defend) {\n  // Buscamos dentro del array characters el personaje que es atacante y el defensor\n  const attacker = characters.find((character) => character.name === atack)\n  const defender = characters.find((character) => character.name === defend)\n\n  // Comprobamos que el personaje que tiene que defender no haya hecho crítico en el turno anterior\n  if (defender.critic === true) {\n    console.log(\n      `${attacker.name} no puede atacar en este turno, tiene que regenerarse.`\n    )\n  } else {\n    // asignamos valor al ataque del personaje\n    let attackerDamage = getAttackValue(attacker.minDamage, attacker.maxDamage)\n\n    // comprobamos si el ataque ha sido crítico\n    if (attackerDamage === attacker.maxDamage) {\n      console.log(\n        `${attacker.name} ha hecho un golpe crítico: ${attackerDamage}`\n      )\n      attacker.critic = true\n    } else {\n      console.log(\n        `El ataque de ${attacker.name} tiene un valor de ${attackerDamage}`\n      )\n      attacker.critic = false\n    }\n\n    //comprobamos si el defensor evade el ataque\n    if (Math.random() <= defender.dodge) {\n      console.log(`${defender.name} ha esquivado el ataque de ${attacker.name}`)\n      attackerDamage = 0\n    }\n\n    // Restamos la vida del defensor\n\n    defender.health -= attackerDamage\n\n    console.log(`Vida restante de ${defender.name}: ${defender.health}`)\n\n    // Comprobamos que siga vivo\n\n    if (defender.health <= 0) {\n      console.log(`${defender.name} ha muerto.`)\n    }\n\n    // retornamos el valor para comprobar la siguiente iteración del bucle\n    return defender.health\n  }\n}\n\n// funcion autoejecutada\n;(async () => {\n  // Mientras la vida de los dos personajes sea superior a cero ejecutamos el bucle\n  while (DEADPOOL_HEALTH > 0 || WOLVERINE_HEALTH > 0) {\n    await sleep(1000) // esperamos un segundo entre cada turno\n\n    //Incrementamos el turno al inicio de cada iteración del bucle\n    turn = turn + 1\n\n    console.log(`Turno: ${turn}`)\n\n    DEADPOOL_HEALTH = attack(\"Deadpool\", \"Wolverine\")\n\n    if (DEADPOOL_HEALTH <= 0) {\n      break\n    }\n\n    WOLVERINE_HEALTH = attack(\"Wolverine\", \"Deadpool\")\n\n    if (WOLVERINE_HEALTH <= 0) {\n      break\n    }\n  }\n})()\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/javascript/RaulDoezon.js",
    "content": "/*\n  EJERCICIO:\n  ¡Deadpool y Wolverine se enfrentan en una batalla épica!\n  Crea un programa que simule la pelea y determine un ganador.\n  El programa simula un combate por turnos, donde cada protagonista posee unos\n  puntos de vida iniciales, un daño de ataque variable y diferentes cualidades\n  de regeneración y evasión de ataques.\n  Requisitos:\n  1. El usuario debe determinar la vida inicial de cada protagonista.\n  2. Cada personaje puede impartir un daño aleatorio:\n     - Deadpool: Entre 10 y 100.\n     - Wolverine: Entre 10 y 120.\n  3. Si el daño es el máximo, el personaje que lo recibe no ataca en el\n  siguiente turno, ya que tiene que regenerarse (pero no aumenta vida).\n  4. Cada personaje puede evitar el ataque contrario:\n     - Deadpool: 25% de posibilidades.\n     - Wolverine: 20% de posibilidades.\n  5. Un personaje pierde si sus puntos de vida llegan a cero o menos.\n  Acciones:\n  1. Simula una batalla.\n  2. Muestra el número del turno (pausa de 1 segundo entre turnos).\n  3. Muestra qué pasa en cada turno.\n  4. Muestra la vida en cada turno.\n  5. Muestra el resultado final.\n*/\n\nlet deadPoolcounter = 1;\nlet wolverineCounter = 1;\nlet allWolverineDamage = [0];\nlet allDeadpoolDamage = [0];\nlet deadpoolIndexCounter = 0;\nlet wolverineIndexCounter = 0;\n\nfunction epicBattle(wolverineInitialLife, deadpoolInitialLife) {\n  const deadpoolAtack = Math.random() <= 0.25 ? 0 : Math.floor(Math.random() * (101 - 10) + 10);\n  const wolverineAtack = Math.random() <= 0.20 ? 0 : Math.floor(Math.random() * (121 - 10) + 10);\n  let deadpoolPreviousDamage = allDeadpoolDamage[deadpoolIndexCounter++];\n  let wolverinePreviousDamage = allWolverineDamage[wolverineIndexCounter++];\n  let wolverineLife = wolverineInitialLife;\n  let deadpoolLife = deadpoolInitialLife;\n\n  if (wolverineLife <= 0) {\n    console.log(\"\\n+++++++++ ⚔️ Deadpool derrotó a Wolverine +++++++++\");\n\n    return;\n  } else if (deadpoolLife <= 0) {\n    console.log(\"\\n+++++++++ 🐺 Wolverine derrotó a Deadpool +++++++++\");\n\n    return;\n  }\n\n  if (deadPoolcounter === 1 && wolverineCounter === 1) {\n    console.log(`Vida inicial de Wolverine: ${wolverineInitialLife} ||| Vida inicial de Deadpool: ${deadpoolInitialLife}`);\n  }\n\n  console.log(`\\nTurno ${deadPoolcounter++} de Deadpool ----------`);\n\n  if (wolverinePreviousDamage === 120) {\n    allDeadpoolDamage.push(0);\n\n    console.log(\"🚫 Deadpool se encuentra regenerándose.\");\n  } else {\n    allDeadpoolDamage.push(deadpoolAtack);\n\n    if (deadpoolAtack === 0) {\n      console.log(\"🛡️ Wolverine evadió el ataque.\");\n    }\n\n    console.log(`💥 Ataque de Deadpool: ${deadpoolAtack}`);\n    console.log(\"🩸 Vida de Wolverine: \", wolverineLife - deadpoolAtack);\n  }\n\n  console.log(`\\nTurno ${wolverineCounter++} de Wolverine ---------`);\n\n  if (deadpoolPreviousDamage === 100) {\n    allWolverineDamage.push(0);\n\n    console.log(\"🚫 Wolverine se encuentra regenerándose.\");\n  } else {\n    allWolverineDamage.push(wolverineAtack);\n\n    if (wolverineAtack === 0) {\n      console.log(\"🛡️ Deadpool evadió el ataqué.\");\n    }\n\n    console.log(`💥 Ataque de Wolverine: ${wolverineAtack}`);\n    console.log(\"🩸 Vida de Deadpool: \", deadpoolLife - wolverineAtack);\n  }\n\n  setTimeout(() => {\n    return epicBattle(wolverinePreviousDamage === 120 ? wolverineInitialLife : wolverineInitialLife - deadpoolAtack, deadpoolPreviousDamage === 100 ? deadpoolInitialLife : deadpoolInitialLife - wolverineAtack);\n  }, 1000);\n}\n\nepicBattle(300, 300);\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/javascript/RicJDev.js",
    "content": "/*\n  EJERCICIO:\n\n- Se ejecuta en Node.js, importando el modulo Readline/promises (https://nodejs.org/api/readline.html)\n- Se ha instalado Picocolors, un libreria para colorear texto en terminal (https://www.npmjs.com/package/picocolors)\n\n  @RicJDev\n*/\n\nimport * as readline from 'node:readline/promises'\nimport pc from 'picocolors'\n\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout,\n})\n\n//Modelado de personajes\nclass Character {\n  /**\n   * @param {string} name\n   * @param {number} hp\n   * @param {number} defenseRate\n   * @param {{ min: number, max: number, }} attackRange\n   */\n\n  constructor(name, hp, defenseRate, attackRange) {\n    this.name = name\n    this.hp = this.validateHp(hp)\n\n    this.defenseRate = defenseRate\n    this.attackRange = attackRange\n\n    this.canAttack = true\n  }\n\n  validateHp(hp) {\n    if (hp > 2000) {\n      console.log(pc.gray('Se ha establecido en el máximo de 2000 hp.'))\n      return 2000\n    } else if (hp < 500 || isNaN(hp)) {\n      console.log(pc.gray('Se ha establecido en el mínimo de 500 hp.'))\n      return 500\n    }\n\n    return hp\n  }\n\n  attack() {\n    if (!this.canAttack) return 0\n\n    return Math.floor(\n      Math.random() * (this.attackRange.max - this.attackRange.min + 1) + this.attackRange.min\n    )\n  }\n\n  defense(damage) {\n    if (Math.floor(Math.random() * 100 + 1) > 100 - this.defenseRate) return 0\n\n    this.hp = Math.max(this.hp - damage, 0)\n\n    return damage\n  }\n\n  get lifeBar() {\n    if (this.hp === 0) {\n      return '💀'\n    }\n\n    return pc.green('|'.repeat(Math.floor(this.hp / 25)))\n  }\n}\n\n//Funciones del simulador\nfunction display(playerA, playerB) {\n  console.log(`\\n${playerA.name} (${playerA.hp}):\\n${playerA.lifeBar} `)\n  console.log(`\\n${playerB.name} (${playerB.hp}):\\n${playerB.lifeBar} `)\n}\n\nfunction simulateAttack(attacker, defender) {\n  let message\n\n  if (attacker.canAttack) {\n    let damage = defender.defense(attacker.attack())\n\n    if (damage > 0) {\n      message = `${attacker.name} ha golpeado a ${defender.name}! ${pc.magenta(`-${damage} hp`)}`\n\n      if (damage === attacker.attackRange.max) {\n        message = `Golpe crítico de ${attacker.name}! ${pc.magenta(`-${damage} hp`)}\\n${\n          defender.name\n        } no atacará en el siguiente turno`\n\n        defender.canAttack = false\n      }\n    } else {\n      message = `${defender.name} ha esquivado el ataque de ${attacker.name}!`\n    }\n  } else {\n    message = `${attacker.name} recibió un golpe crítico. No puede atacar`\n\n    attacker.canAttack = true\n  }\n\n  console.log(' ')\n  console.log(message)\n  console.log(' ')\n}\n\nfunction simulateBattle(playerA, playerB) {\n  let alternate = true\n  let turn = 1\n\n  const battle = setInterval(() => {\n    console.clear()\n\n    console.log('\\nBATALLA EN CURSO!')\n    console.log('Turno:', turn)\n    turn++\n\n    display(playerA, playerB)\n\n    if (alternate) {\n      simulateAttack(playerA, playerB)\n    } else {\n      simulateAttack(playerB, playerA)\n    }\n\n    alternate = !alternate\n\n    if (playerA.hp === 0 || playerB.hp === 0) {\n      clearInterval(battle)\n\n      console.clear()\n\n      console.log('BATALLA FINALIZADA!')\n      display(playerA, playerB)\n      console.log(`\\n${playerA.hp === 0 ? playerB.name : playerA.name} ha ganado!\\n`)\n    }\n  }, 1100)\n}\n\n//Implementacion en terminal\nasync function main() {\n  console.clear()\n  console.log('\\nBIENVENIDO AL SIMULADOR!\\n')\n\n  //Deadpool\n  let deadpoolHP = parseInt(await rl.question('Indique la cantidad de vida para Deadpool. '))\n  const Deadpool = new Character(pc.red('Deadpool'), deadpoolHP, 25, { min: 10, max: 100 })\n\n  //Wolverine\n  let wolverineHP = parseInt(await rl.question('Indique la cantidad de vida para Wolverine. '))\n  const Wolverine = new Character(pc.yellow('Wolverine'), wolverineHP, 20, { min: 10, max: 120 })\n\n  console.log(pc.gray('Cargando...'))\n  simulateBattle(Deadpool, Wolverine)\n\n  rl.close()\n}\n\nmain()\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/javascript/adrs1166ma.js",
    "content": "/*\nEJERCICIO:\n¡Deadpool y Wolverine se enfrentan en una batalla épica!\nCrea un programa que simule la pelea y determine un ganador.\nEl programa simula un combate por turnos, donde cada protagonista posee unos\npuntos de vida iniciales, un daño de ataque variable y diferentes cualidades\nde regeneración y evasión de ataques.\nRequisitos:\n1. El usuario debe determinar la vida inicial de cada protagonista.\n2. Cada personaje puede impartir un daño aleatorio:\n   - Deadpool: Entre 10 y 100.\n   - Wolverine: Entre 10 y 120.\n3. Si el daño es el máximo, el personaje que lo recibe no ataca en el\nsiguiente turno, ya que tiene que regenerarse (pero no aumenta vida).\n4. Cada personaje puede evitar el ataque contrario:\n   - Deadpool: 25% de posibilidades.\n   - Wolverine: 20% de posibilidades.\n5. Un personaje pierde si sus puntos de vida llegan a cero o menos.\nAcciones:\n1. Simula una batalla.\n2. Muestra el número del turno (pausa de 1 segundo entre turnos).\n3. Muestra qué pasa en cada turno.\n4. Muestra la vida en cada turno.\n5. Muestra el resultado final.\n */\n// 🔥 SIMULADOR DE LA BATALLA ENTRE DEADPOOL Y WOLVERINE 🔥\n\nconsole.log(\"⚔️ ¡Deadpool vs Wolverine: Batalla Épica! ⚔️\")\n\n// Función principal del programa\nfunction iniciarBatalla() {\n    console.log(\"\\n--- CONFIGURACIÓN INICIAL ---\");\n\n    // 1. Configurar vida inicial\n    const vidaDeadpool = parseInt(prompt(\"Ingrese la vida inicial de Deadpool (ej. 200): \"));\n    const vidaWolverine = parseInt(prompt(\"Ingrese la vida inicial de Wolverine (ej. 200): \"));\n\n    if (isNaN(vidaDeadpool) || isNaN(vidaWolverine) || vidaDeadpool <= 0 || vidaWolverine <= 0) {\n        console.log(\"❌ La vida inicial debe ser un número positivo.\");\n        return;\n    }\n\n    // Estado inicial de los personajes\n    let deadpool = { nombre: \"Deadpool\", vida: vidaDeadpool, maximoDanio: 100 };\n    let wolverine = { nombre: \"Wolverine\", vida: vidaWolverine, maximoDanio: 120 };\n    let turno = 1;\n\n    // Variable para controlar si un personaje está en regeneración\n    let deadpoolRegenerando = false;\n    let wolverineRegenerando = false;\n\n    console.log(\"\\n--- COMIENZA LA BATALLA ---\");\n\n    while (deadpool.vida > 0 && wolverine.vida > 0) {\n        console.log(`\\n--- TURNO ${turno} ---`);\n\n        // Deadpool ataca\n        if (!deadpoolRegenerando) {\n            const resultado = atacar(deadpool, wolverine);\n            console.log(resultado);\n            if (resultado.includes(\"máximo daño\")) {\n                wolverineRegenerando = true; // Wolverine no ataca en el siguiente turno\n            }\n        } else {\n            console.log(`${deadpool.nombre} está regenerándose y no puede atacar.`);\n            deadpoolRegenerando = false; // Regeneración completa\n        }\n\n        // Verificar si Wolverine ha perdido\n        if (wolverine.vida <= 0) {\n            console.log(`💀 ${wolverine.nombre} ha sido derrotado.`);\n            break;\n        }\n\n        // Wolverine ataca\n        if (!wolverineRegenerando) {\n            const resultado = atacar(wolverine, deadpool);\n            console.log(resultado);\n            if (resultado.includes(\"máximo daño\")) {\n                deadpoolRegenerando = true; // Deadpool no ataca en el siguiente turno\n            }\n        } else {\n            console.log(`${wolverine.nombre} está regenerándose y no puede atacar.`);\n            wolverineRegenerando = false; // Regeneración completa\n        }\n\n        // Mostrar vida actual\n        console.log(`❤️ Vida de ${deadpool.nombre}: ${deadpool.vida}`);\n        console.log(`❤️ Vida de ${wolverine.nombre}: ${wolverine.vida}`);\n\n        // Incrementar turno y pausa de 1 segundo\n        turno++;\n        pausa(1000);\n    }\n\n    // Resultado final\n    console.log(\"\\n--- RESULTADO FINAL ---\");\n    if (deadpool.vida > 0) {\n        console.log(`🎉 ¡${deadpool.nombre} es el ganador! 🎉`);\n    } else {\n        console.log(`🎉 ¡${wolverine.nombre} es el ganador! 🎉`);\n    }\n}\n\n// Función para simular un ataque\nfunction atacar(atacante, defensor) {\n    // Determinar si el ataque es evadido\n    const evade = Math.random();\n    if ((atacante.nombre === \"Deadpool\" && evade < 0.25) || (atacante.nombre === \"Wolverine\" && evade < 0.2)) {\n        return `💨 ${defensor.nombre} ha evadido el ataque de ${atacante.nombre}.`;\n    }\n\n    // Calcular daño\n    const danio = Math.floor(Math.random() * atacante.maximoDanio) + 10;\n    defensor.vida -= danio;\n\n    // Mensaje según el daño\n    if (danio === atacante.maximoDanio) {\n        return `💥 ${atacante.nombre} ha infligido el máximo daño (${danio}). ${defensor.nombre} debe regenerarse.`;\n    } else {\n        return `⚔️ ${atacante.nombre} ha atacado a ${defensor.nombre} causando ${danio} puntos de daño.`;\n    }\n}\n\n// Función para pausa (simulación de tiempo)\nfunction pausa(ms) {\n    const inicio = Date.now();\n    while (Date.now() - inicio < ms) {}\n}\n\niniciarBatalla()"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/javascript/caterinarodriguezdev.js",
    "content": "/*\n * EJERCICIO:\n * ¡Deadpool y Wolverine se enfrentan en una batalla épica!\n * Crea un programa que simule la pelea y determine un ganador.\n * El programa simula un combate por turnos, donde cada protagonista posee unos\n * puntos de vida iniciales, un daño de ataque variable y diferentes cualidades\n * de regeneración y evasión de ataques.\n * Requisitos:\n * 1. El usuario debe determinar la vida inicial de cada protagonista.\n * 2. Cada personaje puede impartir un daño aleatorio:\n *    - Deadpool: Entre 10 y 100.\n *    - Wolverine: Entre 10 y 120.\n * 3. Si el daño es el máximo, el personaje que lo recibe no ataca en el\n * siguiente turno, ya que tiene que regenerarse (pero no aumenta vida).\n * 4. Cada personaje puede evitar el ataque contrario:\n *    - Deadpool: 25% de posibilidades.\n *    - Wolverine: 20% de posibilidades.\n * 5. Un personaje pierde si sus puntos de vida llegan a cero o menos.\n * Acciones:\n * 1. Simula una batalla.\n * 2. Muestra el número del turno (pausa de 1 segundo entre turnos).\n * 3. Muestra qué pasa en cada turno.\n * 4. Muestra la vida en cada turno.\n * 5. Muestra el resultado final.\n */\n\nconst readline = require('readline');\nconst rl = readline.createInterface(process.stdin, process.stdout);\n\nconsole.log('BATALLA DEADPOOL VS WOLVERINE');\n\nconst menu = () => {\n    rl.question(\"Vida inicial Deadpool ❤️❤️❤️ -> \", (resp) => {\n        let vidaDeadpool = resp;\n        rl.question(\"Vida inicial Wolverine ❤️❤️❤️ -> \", (resp) => {\n            let vidaWolverine = resp;\n            console.log(\"\\n\");\n            let turno = 0;\n            let regenerate = false;\n            while (vidaDeadpool > 0 && vidaWolverine > 0) {\n                turno += 1;\n                console.log(`\\nTurno ${turno}`);\n\n                // deadpool ataca a wolverine\n                if (regenerate) {\n                    console.log('Deadpool se está regenerando, no puede atacar');\n                    regenerate = false;\n                }\n                else if (Math.random() > 0.2) {\n                    let ataqueDeadpool = Math.floor(Math.random() * (100 - 10 + 1)) + 10;\n\n                    console.log(`Deadpool ataca a Wolverine con ${ataqueDeadpool} de daño ⚔️`);\n\n                    if (ataqueDeadpool === 100) {\n                        console.log('Deadpool ataca con DAÑO MÁXIMO a Wolverine!! Wolverine no atacará en el siguiente turno ya que tiene que regenerarse ⚔️⚔️⚔️');\n                        regenerate = true;\n                    }\n\n                    vidaWolverine -= ataqueDeadpool;\n\n                    if (vidaWolverine <= 0) {\n                        console.log('\\nKO - Wolverine ha sido derrotado :O');\n                        console.log('\\nBATALLA FINALIZADA!!!');\n                        rl.close();\n                        continue;\n                    } else {\n                        console.log('Vida Wolverine -> ', vidaWolverine);\n                    }\n                } else {\n                    console.log('¡Deadpool intenta atacar a Wolverine pero este esquiva el ataque! 🥷');\n                }\n\n                // wolverine ataca a deadpool\n                if (regenerate) {\n                    console.log('Wolverine se está regenerando, no puede atacar');\n                    regenerate = false;\n                }\n                if (Math.random() > 0.25) {\n                    let ataqueWolverine = Math.floor(Math.random() * (120 - 10 + 1)) + 10;\n\n                    console.log(`Wolverine ataca a Deadpool con ${ataqueWolverine} de daño ⚔️`);\n\n                    if (ataqueWolverine === 120) {\n                        console.log('Wolverine ataca con el DAÑO MÁXIMO a Deadpool! Deadpool no atacará en el siguiente turno ya que tiene que regenerarse ⚔️⚔️⚔️');\n                        regenerate = true;\n                    }\n\n                    vidaDeadpool -= ataqueWolverine;\n\n                    if (vidaDeadpool <= 0) {\n                        console.log('\\nKO - Deadpool ha sido derrotado :O');\n                        console.log('\\nBATALLA FINALIZADA!!!');\n                        rl.close();\n                        continue;\n                    } else {\n                        console.log('Vida Deadpool -> ', vidaDeadpool);\n                    }\n                } else {\n                    console.log('¡Wolverine intenta atacar a Deadpool pero este esquiva el ataque! 🥷');\n                }\n            }\n        })\n    });\n}\n\nmenu();"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/javascript/dfc201692.js",
    "content": "\n/* https://github.com/dfc201692\n  EJERCICIO:\n  ¡Deadpool y Wolverine se enfrentan en una batalla épica!\n  Crea un programa que simule la pelea y determine un ganador.\n  El programa simula un combate por turnos, donde cada protagonista posee unos\n  puntos de vida iniciales, un daño de ataque variable y diferentes cualidades\n  de regeneración y evasión de ataques.\n  Requisitos:\n  1. El usuario debe determinar la vida inicial de cada protagonista.\n  2. Cada personaje puede impartir un daño aleatorio:\n     - Deadpool: Entre 10 y 100.\n     - Wolverine: Entre 10 y 120.\n  3. Si el daño es el máximo, el personaje que lo recibe no ataca en el\n  siguiente turno, ya que tiene que regenerarse (pero no aumenta vida).\n  4. Cada personaje puede evitar el ataque contrario:\n     - Deadpool: 25% de posibilidades.\n     - Wolverine: 20% de posibilidades.\n  5. Un personaje pierde si sus puntos de vida llegan a cero o menos.\n  Acciones:\n  1. Simula una batalla.\n  2. Muestra el número del turno (pausa de 1 segundo entre turnos).\n  3. Muestra qué pasa en cada turno.\n  4. Muestra la vida en cada turno.\n  5. Muestra el resultado final.\n*/\n\nfunction getRandomInt(min, max) {\n    return Math.floor(Math.random() * (max - min + 1)) + min;\n}\n\nfunction battle(deadpoolLife, wolverineLife) {\n    let turn = 1;\n\n    while (deadpoolLife > 0 && wolverineLife > 0) {\n        console.log(`Turno ${turn}:`);\n        \n        // Deadpool ataca a Wolverine\n        if (Math.random() > 0.25) { // Deadpool no evade\n            let deadpoolDamage = getRandomInt(10, 100);\n            console.log(`Deadpool ataca a Wolverine y causa ${deadpoolDamage} de daño.`);\n            wolverineLife -= deadpoolDamage;\n            if (deadpoolDamage === 100) {\n                console.log(\"¡Wolverine recibe un ataque máximo y no puede atacar en el próximo turno!\");\n                turn++;\n                continue; // Saltamos el turno de Wolverine\n            }\n        } else {\n            console.log(\"¡Deadpool evade el ataque de Wolverine!\");\n        }\n\n        // Wolverine ataca a Deadpool\n        if (Math.random() > 0.2) { // Wolverine no evade\n            let wolverineDamage = getRandomInt(10, 120);\n            console.log(`Wolverine ataca a Deadpool y causa ${wolverineDamage} de daño.`);\n            deadpoolLife -= wolverineDamage;\n            if (wolverineDamage === 120) {\n                console.log(\"¡Deadpool recibe un ataque máximo y no puede atacar en el próximo turno!\");\n                turn++;\n                continue; // Saltamos el turno de Deadpool\n            }\n        } else {\n            console.log(\"¡Wolverine evade el ataque de Deadpool!\");\n        }\n\n        // Mostrar la vida restante\n        console.log(`Vida de Deadpool: ${deadpoolLife > 0 ? deadpoolLife : 0}`);\n        console.log(`Vida de Wolverine: ${wolverineLife > 0 ? wolverineLife : 0}`);\n        console.log('----------------------------------------');\n\n        turn++;\n    }\n\n    // Determinar el ganador\n    if (deadpoolLife <= 0 && wolverineLife <= 0) {\n        console.log(\"¡Es un empate! Ambos han caído en combate.\");\n    } else if (deadpoolLife <= 0) {\n        console.log(\"¡Wolverine gana!\");\n    } else {\n        console.log(\"¡Deadpool gana!\");\n    }\n}\n\n// Aquí es donde debes definir la vida inicial y ejecutar la batalla\nlet deadpoolLife = 300;  // Vida inicial de Deadpool\nlet wolverineLife = 300; // Vida inicial de Wolverine\n\nbattle(deadpoolLife, wolverineLife);\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/javascript/duendeintemporal.js",
    "content": "//#32 - BATALLA ENTRE DEADPOOL Y WOLVERINE\n/*\n * EJERCICIO:\n * ¡Deadpool y Wolverine se enfrentan en una batalla épica!\n * Crea un programa que simule la pelea y determine un ganador.\n * El programa simula un combate por turnos, donde cada protagonista posee unos\n * puntos de vida iniciales, un daño de ataque variable y diferentes cualidades\n * de regeneración y evasión de ataques.\n * Requisitos:\n * 1. El usuario debe determinar la vida inicial de cada protagonista.\n * 2. Cada personaje puede impartir un daño aleatorio:\n *    - Deadpool: Entre 10 y 100.\n *    - Wolverine: Entre 10 y 120.\n * 3. Si el daño es el máximo, el personaje que lo recibe no ataca en el\n * siguiente turno, ya que tiene que regenerarse (pero no aumenta vida).\n * 4. Cada personaje puede evitar el ataque contrario:\n *    - Deadpool: 25% de posibilidades.\n *    - Wolverine: 20% de posibilidades.\n * 5. Un personaje pierde si sus puntos de vida llegan a cero o menos.\n * Acciones:\n * 1. Simula una batalla.\n * 2. Muestra el número del turno (pausa de 1 segundo entre turnos).\n * 3. Muestra qué pasa en cada turno.\n * 4. Muestra la vida en cada turno.\n * 5. Muestra el resultado final.\n */\n\nlet log = console.log;\n\nclass Combatant {\n    constructor(name, avatar, life, atkMax, atkMin, def) {\n        this.name = name;\n        this.avatar = avatar;\n        this.life = life;\n        this.attackDamageMax = atkMax;\n        this.attackDamageMin = atkMin;\n        this.defense = def;\n        this.attackPotence = atkMax;\n    }\n}\n\nconst WOLVERINE = new Combatant('Wolverine', 'avatar', 100, 120, 10, 20);\nconst DEADPOOL = new Combatant('Deadpool', 'avatar', 100, 100, 10, 25);\n\nclass Battle {\n    constructor(c1 = new Combatant(), c2 = new Combatant()) {\n        this.combatant1 = c1;\n        this.combatant2 = c2;\n        this.result = '';\n        this.battleInterval = null; \n    }\n\n    startBattle() {\n        let isAttacking = false; \n\n        this.battleInterval = setInterval(() => {\n            if (this.combatant1.life <= 0 || this.combatant2.life <= 0) {\n                clearInterval(this.battleInterval); \n                return; \n            }\n\n            if (!isAttacking) {\n                isAttacking = true; \n                this.round(); \n\n                setTimeout(() => {\n                    isAttacking = false;\n                }, 4500); \n            }\n        }, 1500);\n    }\n\n    attack(attacker, defender) {\n        const body = document.body;\n        const attackStyle = (attacker === this.combatant1) ? 'wolv_attack' : 'dead_attack';\n        let avoidAttack = Math.floor(Math.random() * 101);\n\n        log(`Attacker: ${attacker.name}, Defender: ${defender.name}, Attack Style: ${attackStyle}`);\n\n        \n        if (avoidAttack < 101 - defender.defense) {\n            // Calculate damage based on attackPotence but within the defined range\n            const maxDamage = Math.min(attacker.attackDamageMax, attacker.attackPotence);\n            const minDamage = attacker.attackDamageMin; // Keep the minimum damage as defined\n\n            // Calculate the actual damage within the range\n            const damage = Math.floor(Math.random() * (maxDamage - minDamage + 1)) + minDamage;\n\n            defender.life -= damage;\n            attacker.attackPotence -= 10; // Decrease attackPotence after the attack\n\n            // Update the log container\n            logContainer.innerHTML += `<p>${attacker.name} dealt ${damage} damage to ${defender.name}. ${defender.name} has ${defender.life} life left.</p>`;\n            \n            // Check if the defender's life is less than or equal to zero\n            if (defender.life <= 0) {\n                this.declareWinner(attacker, defender);\n                return; // Exit the attack method\n            }\n\n            body.classList.toggle(attackStyle);\n            \n            // Change background every 1500 milliseconds during the attack\n            const changeBackground = () => {\n                body.classList.toggle(attackStyle);\n                setTimeout(() => {\n                    body.classList.toggle(attackStyle);\n                }, 500); // Toggle back after 500ms\n            };\n\n            // Call changeBackground every 1500ms for a total of 3 times (4.5 seconds)\n            const intervalId = setInterval(() => {\n                changeBackground();\n            }, 1500);\n\n            // Stop changing the background after 4.5 seconds\n            setTimeout(() => {\n                clearInterval(intervalId);\n                body.classList.remove(attackStyle); \n            }, 4500);\n            \n        } else {\n            logContainer.innerHTML += `<p>${defender.name} blocked ${attacker.name}'s attack.</p>`;\n        }\n\n        // Ensure attackPotence does not go below a certain threshold\n        if (attacker.attackPotence < attacker.attackDamageMin) {\n            attacker.attackPotence = attacker.attackDamageMin; // Reset to minimum attack damage if it goes below\n        }\n    }\n\n    declareWinner(winner, loser) {\n        log(`${winner.name} is the winner!`);\n        logContainer.innerHTML += `<p>${winner.name} is the winner!</p>`;\n        clearInterval(this.battleInterval); \n    }\n\n    round() {\n        if (this.combatant1.life > 0 && this.combatant2.life > 0) {\n            // Both combatants are alive, proceed with the attack\n            let position = Math.floor(Math.random() * 2);\n            (position === 1) ? this.attack(this.combatant1, this.combatant2) : this.attack(this.combatant2, this.combatant1);\n        } else {\n            // One or both combatants are dead, declare the winner\n            if (this.combatant1.life <= 0 && this.combatant2.life <= 0) {\n                log(\"It's a draw!\");\n                logContainer.innerHTML += `<p>It's a draw!</p>`;\n            } else if (this.combatant1.life <= 0) {\n                this.declareWinner(this.combatant2, this.combatant1);\n            } else {\n                this.declareWinner(this.combatant1, this.combatant2);\n            }\n        }\n    }\n    \n    }\n\n\nconst battle1 = new Battle(WOLVERINE, DEADPOOL);\n\nwindow.addEventListener('load', () => {\n    battle1.startBattle();\n});\n\n/*\n    One Possible Output: \nWolverine dealt 37 damage to Deadpool. Deadpool has 63 life left.\n\nDeadpool blocked Wolverine's attack.\n\nDeadpool dealt 99 damage to Wolverine. Wolverine has 1 life left.\n\nDeadpool dealt 28 damage to Wolverine. Wolverine has -27 life left.\n\nDeadpool is the winner!\n\n    Another possible Output:\nDeadpool blocked Wolverine's attack.\n\nWolverine blocked Deadpool's attack.\n\nWolverine dealt 88 damage to Deadpool. Deadpool has 12 life left.\n\nWolverine dealt 62 damage to Deadpool. Deadpool has -50 life left.\n\nWolverine is the winner!    \n\n*/\n\n\nconst styles = `\n    body {\n        background: #000;\n        display: flex;\n        justify-content: center;\n        align-items: center;\n        transition: background .5s ease; \n    }\n\n    .contrincants_wrapper {\n        display: flex;\n        justify-content\n        justify-content: center;\n        align-items: center;\n    }\n\n    .contrincant {\n        width: 200px;\n        height: 200px;\n        border: 1px solid #fff outset;\n        object-fit: cover;\n        object-position: center center;\n    }\n\n    .wolv_attack{\n        background: linear-gradient(to top, blue, red);\n        background: -webkit-linear-gradient(to top, blue, red); /* For Safari */\n        background: -moz-linear-gradient(to top, blue, red); /* For Firefox */\n        background: -o-linear-gradient(to top, blue, red); /* For Opera */\n        background: -ms-linear-gradient(to top, blue, red);\n        background: #0000ff;\n    }\n\n    .dead_attack{\n        background: linear-gradient(to bottom, green, yellow);\n        background: -webkit-linear-gradient(to bottom, green, yellow); /* For Safari */\n        background: -moz-linear-gradient(to bottom, green, yellow); /* For Firefox */\n        background: -o-linear-gradient(to bottom, green, yellow); /* For Opera */\n        background: -ms-linear-gradient(to bottom, green, yellow); /*\n        background: #00ff00;\n    }\n\n    .log_container {\n        background: rgba(0, 0, 0, 0.7); \n        padding: 10px; \n        border-radius: 5px; \n        max-height: 200px; \n        overflow-y: auto; \n        z-index: 1;\n        border: 1px solid #fff;\n    }\n\n`;\n\n//we use DataURI converted to work with image without files loading.\n\nconst deadpool_avatar = `url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAkGBwgHBgkIBwgKCgkLDRYPDQwMDRsUFRAWIB0iIiAdHx8kKDQsJCYxJx8fLT0tMTU3Ojo6Iys/RD84QzQ5OjcBCgoKDQwNGg8PGjclHyU3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3N//AABEIALgAwgMBIgACEQEDEQH/xAAcAAABBAMBAAAAAAAAAAAAAAAABAUGBwIDCAH/xABJEAABAgQBBgsFBAkEAQUBAAACAQMABBESBQYhIjEyQQcTQlFSYXGBkaHwFCNiscEVM3LRJENjgpKisuHxFlNzwvI0RISj0gj/xAAaAQEAAwEBAQAAAAAAAAAAAAAAAQIDBAUG/8QAKhEAAgIBAwMDAwUBAAAAAAAAAAECAxEEEiExQVEFIjITYXEUQoGRoSP/2gAMAwEAAhEDEQA/ALxggggAggggAggggAggggAggjxVgAj2GfEMosMw9bZiZHjE/VhpL4Jq74YJnhBlwP3Mo4Q9IiRPJKxVySNoUWT6ImyR4vbEDHhFC6hSP/2/2h2w3LbCZ7RNwpcv2mrxT60hvj5Jlpbo/tJRBGpt0HQEgISEtRCqKkbYsYBBBBABBBBABBBBABBBBABBBBABBBBABBBBABBBBABBBGiYfblmHH3zFtpsbiIsyIia1WAMZuaZkpc35lwW2gSpEUVnlFlhM4kRNSRlLyngR9aqmpOpIR5X5RO43MWtXDKMroNlrVedU9UhhQo5p2Z4R7uk0Cgt1i93jwba/FGDiaEYEXr1rjU85GZ2uvJqfds6MIXJog2I9mHNrShumDi6RzyzEfcJyoncKeulZlxvpCOyvai5li08kcvJTGHgkZq1mcVNEh2HFrSib0Wu7/EUKhacLJCaKXnBdaLSbsISHWi3hnTyiybi+DC6uF0eVz5OpKVj2GjJnFRxjCGJzlElDHmJNf59ipDtvWOhPJ4souLcX2MoIIIEBBBBABBBBABBBBABBBBABBBBAGl95qXaJ2YdFtsdojJERO1ViC4lws5PSs/7HKjMTpjtPNCgtD3kqKvcip1xo4asIensBYxBkytkHbjbuWlCzXU1KqLROxVilTEdEg/FbvXuSLJZB1Yw4DrQOAVwGKEK86KlUiL8JE6kpk043y5lwWkTn3r5CsIuCXGftDJsZR0rn5LQ2kVbF2Vzd6d0IeFqazyEp+J0vJEX5xlY8RZ2+nVfV1MIvzn+ivpV0jDpfnv86woQShuFz2R4huERLS0qJzrRKrnzqsL23RPR/lz/ACVEXyjncX1PofrQ+La3I9NP3YTvrCtUvDQu/OEjyRGMFk8jY+WmW1DY8cLZtdOGw/XPn1U51XckXRw3yMSL4vxf35o8YesnGrxLbC7dmRa6tdKomumqMCOwLv3h396bu/w548wZRmMVaYd2XBMfEV8V641UPJ5c9S8+0ungtxhGpwsPMvdP6QfjRPqlfBItOOcsl335SfaIStcZPR7UVP8AHdHQ0o+MxLNPhsuAhJ3pEw8FNXH3Ka7iiCCCLnIEEEEAEEEEAEEEEAEEEEAEeVj2KX4TsoMXkco3yw+cebGSJqxsXFQaqKEiqKLpItVRa81N6QBbuJSTWISEzJzH3cwCgXYqUjmOdk38JxKZw6YH3su4okI9W+vNzLzR0ZkjjzOUuT8pisuNvHD7wK1sNFoQ9yovdFbcNuCezzknj0uOi77h/wDEiKoqvaiKnckWi8MDDwbYt9iZSNk677qY904I6s6pnquui03JEi4SXidymMUL7lpsfGq/WK1uFr3t2zskWZE7t/fWJPOz7mJve2TH3rjQXXa6oKD9K98Z6hcHr+ipfXb8JiFob8Vt/ZfktPCsLzkmzC223pb0XOutF1Z6Z0ovWkN+GlfjGnyXLe7V9YfpwCaDZ/Fpes8Wj8UcWoebpP7jRMOOSlpGVzXKuqtiVRLq5lVEVUqi1VK1qtFpseW8Ltn6bl8FRU7o9fc49olQRc1+7LUuZUVF6lRVRc2pVhHLulpNEd3RcLlpRFFe1R18yoqJGVsO6O/Q6mWdsmIJwfi2oQC3fcPJKul2kIeOkS90Ok4On68/CG40H2Pa0m6Fb12rXwV1PKK19TTXvEBnmHCdud6RKXjqjLADsx6RL9rb4oqQPBZGiRWzEpYui6HzjoPHLAnW/YceKzZcFHW+3Mi+dVi5shJn2jJ9r9mSh9aecVJlGF7MjOAP3ZWOdi6v6fOLC4K5i+Rm2eiaF41T6RkuJHRJ7qPwT2CCCNDiCCCE07NsyUm7NTRI2w0Cm4RbkRIAUVj2OZsW4QMdncqX8SwmeelAvtbbEqiQJmRCFcy6ubfFwZDZfymUhhh8w2TGKi1eQiK2OU1qK7uei+dIYBOYIIIAIIIxIrYA9VY5+4TJxqdx3F3WnGyG9GhJKKioIoK6t6EngvVSJ/lzl0xKSbspg7wuOuNr+ktklobrRXeXySKRxSY/Q+KARtIreMGlFJKoufXqVM1E1ItIlAtf/wDnmYI8AxVi73Tc4hB1VBEVP5YsPKjB2sewGcw12nvm1sXommcV7lpEQ4DMGcwzIz2x0bXcRdV8R+BEQR8aKvfFiqkQDlARJrjWnRIZlklAhKtyKmZURNy9kPGEqRyA/DUfr9Uh84XMFLB8qfb5cC9mxEb9HVelEJO/MvesR3BiL37Vw7SFo9eZc/hEWrMMnpekzUdQk+6aMJR79Mf+Jz+/1icuGMwzp8oUPZTeiLXr5oriWUmpkr9ErlEu2qpD6GVjbTLUscqXuRs4xtxKr3Kndri66HLZLdNsUzTRS721DQD1j3FfFo3ZkopVReuhr4OLrpmcSygw+eC07m/+T80hqxXiAtdArmrrSIS5K1Rc6cyKq9yLENZRWMtslJCrEF41kiD9YOj35qL35u6EEyghLXAP3hr4XKi+PFCvdC1HeNlmnT2iMCK2uiqkiF/Mh+MMs/NXSzTAFs2EXe0BVr1kZrGVaO/WT3KIimjv2ISAdhiXRJC8FRYdMJwybxicGVwyWcmXy6OynWq6kTPvh+ynyCdycw0ZnE8QlxfIfuRFda8lFVaqvdGp55JXVaxDJi5orrmrh7USqLm66ZokfBDM3zMw2Ra2LvBUr84q/IXEXDKawh3SYcacMdLUqIiKnYta90WHwPoX2v8A/GO7+IYzl1RtDmE19i4YIIIucgRTnDhlWTINYBJH95pTJDRU6gX50/KLLypxtjJ/B3p6YLZGgD0i3RzNPzT+J4k/OTBcYTxXERfJUXV8uuJQEkq0MuyRfy/RP7xe/BBkuWF4R9rzofp06NRu1g3rRO/MvZSK14OsmP8AU2Ugi6JfZ8rR2Z5l5g718kXVmjo0RQRRB1QYMoIIIgGKxU3CPleD84/g8o45xDOi/wAXShnmzKtFzJqpvz8yRZOOYk3hOETc+7pCw0R26rlRMyd60TvjnCU9rnpl92bdbIrr7WRzVVVWqKvfz9sE+S6hJx3Y4NhyrcwH6Rs8lvOqLvpXNXXXwXmoSOASUxOMDNTLnsPGpx4iK3ENUqKEtKKqJSirvrWsSGSl2wltCTZcfKo8c5Ul1qmZFWibt0Y4a3xsg06Y23NoVw9ef6xYqWvIZYZOm022zONsNoKIAuDxaIm5Ermpm3Q8yOJyOIKvsU2y9btC2aKqdqa0jnYjc9m0C0m3DDwon5wzP43N4ZMi7KPuNvtuIQkJUWioqLq7EiMA6A4TsC+3sk5kWgumZX9IY56ii1RO1FVKc9IobCHrJwSMvvBs6krq80TxixOD/hZcxCflsMyg4v3ugM2VBoVMyEiZqLqrmz0iGZa4P/p/KqekRG1gi42WL4VzpTsVVTuicZTRemz6VkZ+GJ5+Q42cIQ0ScJCHv/vWHPJTJzDXcVtyjIm5MhtEhctRCrqJdyruz0WEzq+0SzUyAlcI+W9PGvfDtKKOJsi7KTTbE82NrglQeM3VruWnjFIPKOnV1qFrx0fK/klWOcHOSASBPys4UtbyvaUJPOKxLAB9sIZSeEmBK3jLVoe9aLqVESHebYcD/wBW6zo9Eq/LXC9psZGQJ02rrhUrbaqooiqqU5lRFROtUTfFjlQxnhtkm60G03pXdaEtfOvhELm1K/levy1dyRZUs0XsbomVxEKkRc67y71qvfFf4szxUyXxRhCXuZ6urocaYPuhwwjKnG8Pk/ZsMmRlB6TLQ3F2qqL5UhFOOvz0yUziEy9Mul+seNSXzXMkI2HSCN77onsRueWPORSCGJTMzbosyx+cWfwNDdiMyfRlqJ3kn5RVmEPeyYO+IbU05Z3JrX11xcHAqz7nEH/+MPmsZv5I2jxXJloxiS2pGUQThSyqbwPByk2nbZyaFRG3kDqqvbnTuWLnKVzwtZUljGN/Z0uV0pL6I7qrmqSKmtPFNUQsG372paUEnJmYJAbEdaqq0RKas+r8oxRdp2b5VSu5+tFizOBTJY5qcLKbEB903VqSEt5aiPuzonWq80WILIyFyZayXyfYkQtKYLTmXOm4uvuTUnUkSOCCKkhBBBAFE5XZUTuUbxN3cTh4lcDA00qaiJd69SZu3exYRLEeJOtdJvvXOiV/m8oUEnTjZhqiE5xtvJcG7nooLm84wpk3LLPoPU6a6KIxh5JNh7FgfCJ/MRNKfxQkw+T4rCpYbv1aD4IiQ91EGfxA3/QiL/TDMsyISAjyhcdC7scL6UjpPAIviwjKSz5Xf+8MdrnU1/6xDJ+aF17TG4bYkWOOuOhif7OZaIe8Vr5ksQ9bTe09EeUWvygDYjPKlyu/Z76dXPFhm1P5QcGktjk1c4/hU0UrxpazlqCqKq77SVUrzVivm2WweaJ10vZuMTjCb2rKpVU66V8o62YwXC/9P/ZErLNt4abKti22ma0k19uetVz1zwzgg58wZ+8CautHatEs9FzL5/OE020UpM6BaPJ9evJYHJRzAcbmZGb+8lnVBzclOl2KlFhzdG8CaMeTbpeuxe6MpPZP7M92mj9ZpPb84cflCKUMXT410tES0v8AMO81MlMcU0GjquG3OCZlQVTdVUQ1TmEK7SxH2WZkJwhAdnZIh0fxU1KvVqrtLmor3LhxX4uUREqrnWqqq71Vc6rviLLElhHPo9FKye6SwkOLVtlvJEfDm+XnEByiCyc2Ylr8zYHxRGMUHjTuOMYPk9PX1/8APgYFQoE0/XqnyjY4FkYIN8dKZ8+4C+UO+0eSOz9fOOh+CWT9nyZJzlPPEvgiJ80WOfMHG94Y6Z4P2uJyTkesSLxJViieZm9kNumz5aHrEJtrD5N6cf8Au2QUy5825O3VHMmVGPOZTYw/OTGiRF7vXRBTMg06u5YsvhnymEJX7FlHBR0tJ7S8v80inRIRZJx3aHlFrTqWu7t8o1R5464Bg0zlNjctgspcJPFc+4OdGm01l3VomrOqJvjpzDZGXw2QYkZRsW2JdtAbEdyIlIhHBDkquCYJ9pTzduI4jQyEtbTfJHqVda9a03RYUGSEEEEQAggggDnU1HllCVmZEJl8ejpDzrVEVeqlR80jX7R8Vvn65oZ35gpfG9PRFxpbfOMaup7fqT3Vr8liPYgXs3J2A/7+WaIymJF+nCZaLc2tv7wivzrCGdxsQ0eKeJohT7txB1VpyFzZ15ueGMsUAPafdOe9dQxuJCzINM60TP3R0HiinEJy/wC0B6TTZeBokR4WydPQhe06xMPP+0OkwLjVvGC0p50JFSqIvVrhM/xUu8Ps75ODbpEQKGeuqirzQIH/AIP8lSytxv7KWbGVaFvjXVKtxAioioCalXPvzJrz0pHVLLYtNA22KCICgiPMiao5x4MX/szKBjHJ1qYbkmWjFsm2l94RIiINVoipRVWtdyJ1Jar3CTKkBeyyDxlu4w0FPFKxnKcU+TerS3Wr2RyRbhuwUZeflMcaHRf9w/o8pEVUVe1EVP3Yh0o+Tss0R7X1TNWJjlPlVM41hzsliEtL+zEqKQiK1zLXMte3VEKxRfZNJoR4pvkjuTq9Z4xnbGaSR73p2mu0cpTsaxjlG9wrHmi6RW/l5VhakNCv8bLXBpW6Q/Kvgqw6iYmAkHKG6M5I9BSW+WO/JqeGGufHpw9U0IbJ5BMIR6nPe8xZFpnbjSi2aUKJpNOEbix0roeBJ4HjAbQMnT2R9Ui98n8pgw3g1bxOZtEmBMBz5loSoir4pFASrlksLX+4Wl2Ivrwh6nsdm3cNawwLhlpclK4ecs6+HqkVgve2aaiS/Txj4Ykn51/GMSfnHS964V2kWbuVdXy7IlnBZk3/AKjyjGZmG7sNwyhncOZxytRDsTOqp1JzxD2WnXTak8PaIpyZcQG2x3qq0SnNnp1U3b46WyKydYyXyelsNaUScFLn3P8AccXOS/ROpEjdnmD8kewQRUkIIIIAIIIIA5NYnR6Uap8m5sxI9odkvW6MsPwcnQF2YK27kiXfRV7FrG93DGAC4HXB0rd3N2RRQfVHoy1cZx2yGyZmdAWgtuzXF2CtfNfJISqjnSuH8SQ7y0tLXulxHGcW0ZldVb9yJ4ki5uaHB6XlmgEQYZ0aaXFpnolKxqcDx2IxW/b9dkYq2J6Oj654fJo2Ji0ZhoSt2d1O9N0JrJSX0gaH8JES9+dYkglWT+KFI4JItOlouCoaWfRqqoip2KmaMnH2wnCEC0XBQh3665q9SivlviFzU2VjAgXQ/pT61hyGbI59oulUebNWvzp4xnZHcjr0dzrtXhkomDhmnDs2+Tol9M3h5w4q5eH9MIMSG8C+H1mT1v545lE96y+T5Q1NXNPE1tMOaIiOdUqiqtOqlVr+cPeGzF7I3lpev7eEMsql4FePwiXz883dGLD5SJ2mVw9L+8XayYUzcGm/i/8ACVD68YRTYbXryjSziQmEaJ6eGwrIoka2TWM5GLEF04QJCqZK8yhCR9DZjdHhWy5yL5K514eUWyIw4SbW1pXFtEQlmqq1zfn1Q3SMzocRLtaT2i44WtU6PUnPz+UOntjeHmIutC+08CFxg5lSiqi2rvTr1L5xdLBjOzdwWdwNZL8fOO5QzzWiyShKaKUuVKESdiKqV51Xmi5Yh2QmUmATuDyUnhjoy9jaC2y4qIp86puVVWq89a5omMDIIIIIAIIIIAIIIIA5XamCAB2dH80zeMJHJkr7fWbfCVJwtLimhEY1I+R6NpfD2rFiR0kFIAET/WErrn/G3nTxOiRofnb7ul8u2PXXxD2nitoqMN/hFKrTtWngsNjjtn4uj61QBm48R+qIPau6NDjg2Wh7wtm4swp2JvWPFQj29no7k/ONgt2cmANSXOzI/DDsy3YcsXR//SQgAbIUI84AbN1paPauf6fLniH0LV/JEjOZbANN31WERkUwdxlxbXJ3Ev5fPs1QgYmRvudtIh2d1PGFntA/+Ucx7cZbkYuILWiFojyerq7Pl2ak7q8kxjJ5fijXW8Lf4f7RJO7C2oTE3Z90VvyhK6sz/u/ypClzQ9fSNCnFkcNmOnKERo7y/wCqMLYVHCcljRM45wSMmE07f8d8O+UD7RycpbtNkvgqZ/NEhlQrI9dMnbRPkw7kbkotEiwSaIMNaEC2SXldaqnzixsmOEXEsPQWJsvbWB/3CW5E6i1+NYqrDnRsJrlX6PZRETf1LDyxaYXRcodH4JlNheMgPs74i6X6lzMXdz90PccxS06/LvCQOkPxXRYOAcIMzLnKt4g/xjHGWO8ZSoivKrrzfKIwMFuQRracF0BICEhLeK1Re+NkQQEEEEAcZ1GMU2xICK6MFWMUWLEitHi2brfw6S66qic3asYC3+Efh1+K71jBstONqLAHopGxU0Izl2SONjjUAaBX339MLlbslrf3iLf6/sm6PZWV2nz2eT69a+pYwm3tARAbnSK0R54ym8vCO2iG2O9mljTMtm0R5XOupPnHqp+IY2tsi0Fu0W0Rc69XVHipGeToUW1yalu6UeiZBHpDGKiUTkYaeUZkYmFp3fw1+UJHQH1+SxtIrOSX7ueNVbw6X0gis3nqaLSP+G714xpcCFRoOj+H6pGDoDf8NqfKL5OWUciRRgFI3qIxrNNn1qi6MJxwbmXNDk3Z9nfX/Hzh3kZiz/rDK0kL5YrP/L6RYqPGkEYGdh7XJu+calmXADQG4ujdTzpGQTAus3GPF3EgaVF170XqoufNrgSSWRyrxvBQ4yVnnBab94TJUUVRM6oqLWlUSleuLkyfyuksVd9mdMWJz/bIsx/hX6a+2KGVRdBoQG7jD8kSqp4JTvj2ZnbHrgfK4dES1as1a1zaq+EMDB09WCKAay/x0GwD293RRE0iqvfBDaRgqtY8rBBAg2JCuVETgggSODehpW/wx4o8aYjo6Rd2/N5KvdTekEERLoXrinIXzNrQfCOj664a2UJ17j/3W+pP7wQRznqNZaFCpGCpoQQRBcwVIxFIIIkqYkkJnrbC0f3oIIsjKxcAqbPrdHrjY2CXYP8AKiwQRJj5E5aEayUbLeVdteu6CCLIxs6GTacmFaFZsQQRoYCllywLujGozLjmhu2Suct51TMvy8YIIBD4itgZFoiLeiPfnXv2fFYaQmRv0xuG6CCBJt9qY6Tnruj2CCBB/9k=)`;\n\nconst wolverine_avatar = `url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAkGBwgHBgkIBwgKCgkLDRYPDQwMDRsUFRAWIB0iIiAdHx8kKDQsJCYxJx8fLT0tMTU3Ojo6Iys/RD84QzQ5OjcBCgoKDQwNGg8PGjclHyU3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3N//AABEIAJQA/gMBIgACEQEDEQH/xAAcAAACAgMBAQAAAAAAAAAAAAAFBgQHAAIDAQj/xABFEAABAwMCAwUGBAQEBAQHAAABAgMEAAUREiEGMUETIlFhcQcUMoGRoSNCscEVUtHwJGKS4TNDgsJTcrLxFhc0RGOiw//EABoBAAIDAQEAAAAAAAAAAAAAAAQFAgMGAQD/xAAxEQACAgEEAQMBBwMFAQAAAAABAgADEQQSITFBEyJRBRQyYXGBobFCkfAjUsHR4ST/2gAMAwEAAhEDEQA/AKhbjrdUlDaSXFKCUjGxJ2H61dnDnAXDzkVa5ttbf7JAClqUrvEDc86ReELR7zemNae4zlwjHUcvvV1LAg8O61JwVAqOPrV617Rg+YK1mX48SvJHDPDcdmfNetrSY0ZKlBOVY7o36+O1JtpYsz9xtJet6ewfQWJHeJQHfyqznY9MGnXjlRicIiJqIdlrAVg8xkKV+w+dV5BaNrR79MGWHAQ1HJ3k+Z8EDx68hUNQmfaOJPT2EDd3LKRwbw52faOWxrB+HdW/3rm5wfw8Bk2tgZ5AFX9aFWfiNxGFynwHnEAtxHvyjpuPhGOQOaKpv8N9Wl51TDyuQe7uo+SuSvkaQXafV1ngkj845pv09nBAB/GArxw5aO3hwocJDb0l3mknutp3WefhgfOm9jgfhlm0mVLtLRUo9wlStk+POoPCcP8AjN6euAAKVK7Bk+DaT3iPVX6U0cZSg2huG1y06ceQ5/tT3R1FKVD8seYp1du60lOAOIkMcN8OsxJ1xmW1oRo6SrSSrHiBz/vNVM4QpalJQG0kkhA5JHhVr+0KQYdii2do4ckjt3/JA/qSB8jVUqGDgjfwqVpG7AnKQduTJVtchNOn3+P2zauWD8NMUD/4YkvCOY2CrZJOpOT5b0r9gvB0oUogZVpGdIrQZzsSPMULYm7yRCUs2+MiWzbuEuH3WxmC05j+YqB/Wip4H4bU0dNrbBxzSpWR96WuHLz7rHP8ScQ2ezzqCshzHUeNOsK9QnoxfD2EIR2qsg/D5ePypBqDqEf2scRqi1MuSBE9nhuySGYsFNua9+bWRLWknICDg9fznHyNNMngXhiFA1SbSyt7H8yuf1qZwjbdbz1zkshp19faLT/LthIPTupAHrXa5PJnTShSgmOykrXqOAEjc/30rU6an06gH77Mz11pewlOvETJfC1lSuJGRbW+3fParwpWUo30pAz+Y/YGiaOBuH2IqQ9bWnVgbuFR5n510sUxp69O3GSnQqS2Vs6xhSUA40jPIgAZHnTRJCXbd7w0nCSkKAI6VmPqmts9fahwI70tCog3DJMq/jPh+0Q7XBTboCESpcoISpJOdIyT18qjxuF4T7awiGlZR8eCTgeNEr1JD0mKpY7kGKvSnwcWogH/AEhX1FR2JS4kdw9sUdqNLigcAJ5nJ+laT6Wm2gGzkxN9Sc+qVTgD4gmVaLTGQVraQlCPiVqO2aDTG7a+UqhMBtpnd1xWcHyqdxHGmvwW5i2+xgBwNspXsXVEE6seGB1oJHYfcDKXArsCsqA5ZwNzj6VfY4LYA4lVSMFyxh632uG4louwh38aSScn/agN6iph3R9hCdKQoYT4DFO8IpchvOKaUVYAScHCQDsBSxxckqnNScZ1t6VHxUDv+tetTFYnKrN1h5gNDZcOlIAA3z4Dxo1brKiYn3h9fu0JI+M/E55gVLtXDEx6yN3xbaVwFOEKCVd/Y4yR4Z8PKol7updUY8fCW0gAn+lD1vWcnOcQmwOOJ5dn7MB2VugjCNi6pZKlHxNBSAd8AelZWGvMS3idUATEd1WdKVeShkUYkSYMplli32lJmu4GASrCv8ozvQb7VZXsy91ehKTDjBVwQT2iiMYBOxKvDyoXU2ipPUPiEULvbaTibweErRa7S2u9RxIlqxlJPU/lGPpXJjhiM9rdNtjNtqOUF1agn5b7+tNU9q2W5Zm3OS2+8znvOKwyzn/1HypRn8bPzpamrHb1TVp7ynVg7p8k9BSyq2+0Eqf1PX6Q0itcAgRx4LsjkYulxACnFhKFJOQpPiD4U7X9vWlqKPh2yPL+xWcLwDEhR23UnW2nOD0J3olKijtC8sZI+EVp3cepxM9VUfS57Mq/jtpkSmXJQC22m/wowO7iidyrwSPvypJuA92e96uIDs1wAoaI7rI/KSPLon5nnT7xKhLMx2Y4kLlLOW0q3DQHIkePgKQLilSyta1FS1HKlHmT1oi2rKboLRf/AKhQxWnIeRKU444pa1HX2hPx/wCap1tnT5MhqE3hwvnQMjx8vrXZtlD4MZ3ugnLbh/Io/sev19W32a8MOu3hbzzOlTR7JGf5jzP0/WgVQk/hGTOMZ8y0eC7Q3arR2gThDbYQ2PIc/qaDrSbletat0JPXwB/qab76REtiIzG2RpGOmBSRfZSrDwvOnISfeXQGmABkqUrYAD1q4NwWlJXGElX8eqkXa9y7g2SqOF9g0hPPQjIzjzJJ+dLrn+ECUuYMoDGOfZD91fpy57BzhuMsxgySlUvSEujIPY7cvNXj0HnS9erC9HHvUYKdjr5gc0H+lVNX/UvMtS0D2niB48h2M6HmHFJcHXPP1pms7Fmvr5TKbUxJV8XZHGT/ADAdfSlTlzG9dIxUmQ0UPFpYUNLn8nnQli5HBwYUj7Tz1LZtHD8i0KaVpbuFvKgQ4npv1FGbhAjTL5FjwG0owQ64lIwnf4R9d/lQezXKbboOu46VpQjPvDGSlfkU9FfUU7cHwFIjruUwYfeUVqH8pxyHkBhI9KA0VD2aj1LOl/eEatxXUEXsyXcHEWq2oYaxqxjGPiNJd1lJjtxIy9OZ74DpVy7IHKgf/MRj0zRy4vquNx0BQSgHBUTgDHM58qr7iqcpxLdxUlbKFzWQyhXRhO6FEdM7nx3pzqn217fJ4i7TIGfPgRkuiFx3FIlslmGmSUrcWR3tS9vTpv503PXBEmxIUhITqOE48P7FV/cuIEXNm2WM6lrkuCS6TnCW85A/SiXFV2Fq4efdaxqCeyZSORcVsD8tz8qyVunawopHJP7R8CpG49CJtzfS37w52hKXJOrxykKAAHj1pz4Q4PkXRAm3FBbjp+BCv36Up2NVuhx27hdJbCG2SG4za91KWB3l6ee3IfOiF49qrotyoNjbWkY09u6nAGfBPP61rlIRQvxM+VLsSRI3tPnMOX2DZ4qgWoZ1vBH8x6fIZ+tDbY+Jl0kPpQlLaO42MbDlSkXFvP6tSu0UclSlcz1JNM1ncYixUtocSVHfnXa2y2TOXJhMCN1zmJMSLFbShKQjLgTtqWetI/F4KO6UnSoBxB88YP8AflRxpxLq8heo56VE4oQDCakEZ93cSsjHTIyP0+lE2+6skQOn2WqDH+xobbsEViOtpyOGgAEKBAqruN7ImzXf8BBEV9Opo5zpP5h9d/nVjRkwoDaX0R3kMr7xWyfw/mKh8QSOFrrDMW43cx0jCk91JWg+W/7VkNNY1V5IBKnuazUIr1AHuVGa3baceWEMtqcWeSEJyT8qZ51r4ZiupMG6+/NEb6hpWk+B6H1FcF8QMQmy1Z46Ws7FzG5880/qCuocnAiR2ZTtAnJnh1yOA5dliOBv2QUNfz8KkwuIFWt1TVjSdb47PCDjUo7D1NAZEqXPeJWXHVk8gCam2+13FiUxKCOwLK0uJLu24OalYAylQvE9XlWDM3MY4/CN2vK0PX2YplsfCwjBKflyH3qwODOFIdojuloLWXDutfxK/wBvKgfCcq73+epUhtDENGUJSg7uK8c+A3/sVaEaOEthI2SBttWc1H2iyz0M4H4dCM2NSJuXknzCVtTiOCQdhgZr24vFqG4UjC9J0+tclvqh29rVutQHPzoHxPcz7jhB/F+LSDvgbk/KtTWhZ4ntsFdZzEy/OZQvUcnfOfGk2YAcij9zmC4IUpBAeRkqQPzp/mHn4j50tOuhS8femVzAJtiXSqWtLzSPF7RWMZJ2FXtwNaRCgM6wO0bbAKupJ51VnBsMS7qzqTlDf4is/arxtqA1BQeWregrgFUARlpyXck9CR7gz7w7uOWw9arP2qz/AHdyNboqQHmUFxTp37PVsMDocZ38DVsuONpaUrblVE8ZSRNusmQrfUo4Pl0rlKbwc9CS1NgqZQOzEKNINvlhZ+BWQv8ArT1Y5Ud1RiyyQy9yXj4D0PpSDcsa6n2m+RIkVpmRqQpAxr086hS+xsSd9e9QQIbu/CzMmWtCMMu5+NONJ8zS5P4XuMJZStKVJ/mHhTNHu0aWhOJIVtjBQdxWzvbsqIQJD8YjU2sJKgnyqyxK2GRKq7LUODCXBjU24Bq3PIStppaXFOdVH8o+2fkKtG9vJttuEdojONIIod7PbB/DYJkSUgPK77m2wWRyHoMCuV6Ls+4hsbJ1aR/WqaalTKj8/wBYTbYW9x88RfuS2mbWpl9ZHvuUK08+yG7mPUd35mo3GzEGXEYeDiUx3WTGLvxBCighClfMiljiO9ok8SOutBCIsApaZklWwAJCyfNRyMDngVvAmJmW2RDWotxH+1EZBOVIRpJ1nw3Bx4ZpZrVZ7lcHgQ7ShVr2+TIMqWxF4gg3FIUlkRg05q/5biTuk/SoXF1/N9W23GSv3dglRx1Vjn9K8ukdmXHiyVLhqf0aZLnbaSFA4yQOZI/SosaBJgrjrUjS3JcGhKtlrRkblPTPPHhU66kLBj2OJKyx1UicYrTM5BHZrW8OehQBx5eIrwxrYwvRLemtg8x2YpitdltyHgue0olZOCdt/Khl6gMLX+A6ltQPwuNHP+oUwNZC7jFq2qzbRN2JHCsZGzD7ywNlOlf6YArvCuEWQsiJBfWfHswEgeZzSyy6qO6SENqUOqk5qU7eZi29CnEoQOiE6a4LQJJqcxkXMDKd20JOeQVk58MCuzyFPw1oe3U40fkahxbcYUWGxLCjcpoEhaVf/bx/yDH8yzlR8EpHiaMOI0hAPLNXVEuCYPaBWwHmAeGeI71Y20FtlcmCcgtqTqG22Aflyp5gJ4H4waPbW9MWYdlFs9k4k0O9nLyW4s6JpyuNLUO9tqSd8fY/WmW93e12SbEcm25r3d7uh8oBLS+eFf30rLax8XFEUhvkGaCtAalLHIMDSfY5D7XXGvUhDBGyVtJUry3GNqSLraYHDsxUS6IXIfAyAjZK09CP72q5lXtmQ0golNdmod3QcUge0Wyv3hMedbGFvOMgocCRjUk9R47/AK1H6brdQLNt54/KRv0ea8iJx4mkstlq2R2YKPFtA1/WhT0yXJcBckOuLJ/MrrWsuLIhPdjLYWw7jOlwY2qdZLa5KkocWnDaDn/zVolLOcAxYQqAx34GuTtgltOLC3YjgCZCBupP+dI8RzI6jPlVzOup7NsIVqSoagpPIg1UkVCbdbXp6sdpgtxweiiN1fIE/PFH/Z9fDKgOW59RU5Dx2ZVk5bOcfTl9KXfWqWopNlI9x7ndHcbW2nrxHe/Pj3llkHkc/QZ/pVbceXZTV0jNtrUlTKAoEHko06XR8uXtQz8CCT8zj9BQK3W2JxAid79GLjL0hYC88tHdGCNxyJphqdWujqFjSlKPtFjL4lfzJiXUmdE7i0Y7ZCfyH+YDwP2oc4+l/wDHbwlWcuoB5HxHkf76UzTPZ3eod+jot0hDsRw7ynB/w0dQ4nrtttz8qI3PgO02mC/KYcmuyAPwwXQBqOwTgDlkgb5/eqD9VodlCnJPxL00RVTxwJO9nMQqjpewdchYCc/yg4qzrlLEUMsIAACcn0pf4Gt6IxabbCdEdoA7cjywPLnWtzmGTenEJOUhWj5CmDe58fEDTKV5+TJHE11MCxvOpXpdVhCMeKqp+8yA+hT7aQFDZ1sHOk+I8j9j92v2i3dtuVBt5UBsXF+p2T+9IN4U+ysSY/e0jvDHP18RVm8JXgSr0zZeGaLs5zWvFS+Hbz/CJZfMOPLQpOl1p1I3/wAyT0NQZWlz8ZkYaVzSOaFeB8vA1FFAnuM5cXDPFXDMpYMtBjkfkfTp+42P98qc2ptr4hlsQ7Uw0qKwQ48tCcDI+EZxvv8ApVA2tIynKk8/A19Ceze1iDakFxADih2ru3JR5D5Cr1IK5MGcEPtEZ3GhHiBlPPG+BSbxViBZZj4dDLridCHOqc8yB1OM07hxt5SgpWBVX+06Uh+UiM2vKWcjT5nrU6ELnEr1VgqXdKmlNlxKmmYzSYjOMJcOSnzJyMqPj9Nq7xHESGkwWXvdgO6EvtFSHOhSVpJx866NIacuAjvt9qh8dkEjY6j8O/riodkdftt0U62C4yw6Q+0djpHXT5eNAXcEiMqGyBHm22FyXJYjyWmtSSgMpabSlvKuayATqKRkjJxmpvG1ptsBoJtzYRJ1ICNRypwgjJ+YyCac+FolvXGQ8wnvpRkeAqJIhaX5cmTpSkt6ELV+RO5UfTYfSs39sf1wSevHzGPpKwKyq47gVIJddQVKOUpUrfH0otc4EJ8JCVqUCkZyPLxoTDMU3aS92SX2t0o1pOFDJ3xXeY/GhtlzWptBOEIB1HPgkftW2qYGvLTMXIVt2oYGncOpB1xnN87gjauvCvDi5VyS9PS4i3tKwp9CdSdYxhP9a43afLivoYkRZEfXhRDqdKlI/wAvr49Kufhe625+wxkWpLaIWkBLPMJPnnfNLdVYqj2CNNHS7Nh+4lcRsra4rtz8qQh9D8QtpcScghCtvMY19c1l4jll7TjCdIKf61L9o9vZaVarjEGlXvCm1JGdPeSTy9UAVz94TcLWlt0Dtm091R548KO+nPvogH1RNl+Ys2S5sWbieaia8lpl8JKSrlnbn9TVg3GDGv8AaghxoSmF4OG1gFXUd7PPz86rmPeoll4kkuz4632nGmwUoCSQfHemmN7TbDGbShqBNSnHIBAx9KQfUaLWv31LzHWiuUUBXML2Oxv22MWbHw2p8oWSTMnJGhX3xsfAVBurfGUyUI7qrdaIhJ1PIdDqkD7ZP0oFM9q0lTr3ultAaWQcuPaSdgNwB+9Ls/jS7XEpQ2GmlK2HZJKlKNQTTXk5YDPyeZI3J1u4+BGriFixxIXYFaZ00kFTzqgpaiNyc9BtyoPw0p+aO3eSEtrIDbYHIVpZOCbxMbcuMlspWkFSWlnC3D1B88Z28aKRXUsNAtp0lIwARjB8KcfSwgJUNkjuKvqZsKg7cZm3EcnLqYrZBaYGnbqep+tKjl/kW2VqtSwl0JKVOeRxt9hXt/uC0EtNqwpW6vKl1Qq7UOHJU9SGmr2KCJ9ByZaW5FymLIw0Duf8qSf1pB9m/EM+A8r3pTi4by9bgG5QSckgHp6b0x3h5Q4UnEq70r8MHr3yB+5oJZmUsyEoQkBI2A8anbpU1K+m/Up+0NQCy9y2mpbb7KXGihbagMLSdsY6f70t8QPreuECA0rSlSlPv7fElIwkeXeIP/TUCXPVapRRE0lHNxonZR8vA1pZHjdp8icArStYZbSeYSn/AHKqRaP6G2l1oPajqMG19dumYDhusSwLPot1ikTVDGUlWT5cqVLK4t6W4+sg47xJ8Sf/AHpg43f/AIbw8xDbOC6oJI8gMmlWK97nY5UofEUKKfXGB960CHOXMBcdIIhXVa+JuK7w00f+DHcLJ8NBSB+9Q7C//EI6mHhl5B0qBprYsaLNeZ8xteyYSI+w+JxRyfn3QfnS5dbI7wy1DuatWZMpaHQrokgFH0IV9aV6fWo12CeDGN+lIpyOxAV5tK7e4p5lOWV/Gg0HYbbW+lC1lCDzUBmrEnrQuIl/s+2iuDCwPynrSXe7aiN/iYp1RVdRvp/2o+6vByIHTZkbWjTwhw6HL2grc7VhpIcUNON+g+ufpV8HTarQhKwQpW68c8+FI3sosa0QWHZbeHVAPO5zkfyp+Qx880e4pnqkXH3ZpWyNj5mpgDIWV5Iy00m3n3K3PTFkd0YQD+ZR5VV9yuZuAIeVl7mhRPxeR/ap3tMvHuz0O1NL2bR2rgHnsM/eq+kTdQ5n5VM3hAQJUNMXIZvE8nyFayQShQVnOe8Ff1olcXveY7PEsZRTO7cNygnGjX4kdNQ6UEfd9576hl0DBP8AP5+oqVYZrMeSY1wBXbpQDUpAPIflWPNJ3+tAWc8xlWce2W7wHxI3KjtkNhlwJwWvAeXiKY78nt0xghRLbru+PAAkj0OMfOq4slrcscv3WQ4X44OqPJSd0hXL1B5Y86siC+2uEWlkKVjIV+9ZXWoqW716jqsMVDHuVxIiFi5S0r+FLmR02O9OPBHCMMvNXq7I7WUpOqOyvGlhOeeOqj1PnQ2Zb2rneUlLuIraQiTp/OQThIP6nyxTQ864GtadWAO6lAGemw/X5U/Ot36dEHfmLU0LC57D56nPjW1Wi/xVR5Ucr07trQQkoOOaT+3XwqrbEqXwdxAiHKc7S2TiEhxXRXT0NGOIuMZFrWWTamSkHV+JMCnPpg4+RqILlbOLYEhlKVNyw2DoWd0qG4Uk+teQMB7ujLfb/SfcIe44WV8NrI7xjyGlj01YP2JoBAQ62h5w4U0TqGDunPr51OQ65ceDpSXQO193UFjwUj/2ofCfCrco5+JKcfWmH08gAiLvqo3MrDzBloYs1zvVyg3klLjugMrSd0EJ3waPQPZvGjKcXPb/AIjGKgpmQ24oEJ8FJB50mXG3LNiavKAQpUtwLVj8qlEJP1T96mcPcfXezLGt1UhoDGlRGceHnS3VJfYWehv0/wCoZSUrCq45EsGFwjYQpY/hMRRSditGQR471NFqsdsc96aYt0R5A2dQ2lJHzpcd9o9imalSrZpcVzUnWCfXSRQWTxJwk6oq/gTa1E/nSs5+ppatGoY/6gb/AD9YZ61ePaBDs/iyG3NNvtijLluuBLZSSUpyBuceHUCjfF/C2ix/xmGlQktJ1ykfzt8yceKfuM+VQfZpJtt1mKcgcOR4jaB/9UltIJPgDjP3qx7nK92ZKNidJGMZrwuTS25UYx+8ou3XAI3OZ8sXBztpzqknu6ilO/QVGo3xna0WjiGTHYTojq/EZT0Sk9B6Gghp8rixQw6MAZNvtMt3iNfZ2i3sj87usjyAJqFa3gzIQpe4SrO9bcYOrTPgsMt6+zZUTlWANwN/lmhjbctTPaaWlA9Erwr5A86Zq3ui2xcrzJl2uB0SJLnxYKtqe/Z7bwlUFo5PZt61+Zxn9TVYqKJk6HC7wU6+nWlSSCEpyo8/THzq7uB2ghiRKWMHYA+Q3Ned+CZ6qoBgIA9o0wv3hqKk5THb3HmaG3MoZjWuEvAS9ISpzJwNCAVn7pSPnUZ93+J8QOvHJDr2R6D/AGoB7Q/eLnfrfaYSyHSjmDjTqOT+iaHuAXTnJxxCKffeIxRpSbvc3nWwDb4S0qfI5KVyA8zjJPgB50J9qUr33hSC8RpDqy6lPgMgJx8s114hda4e4cas9u5tJy4oc3FnmSfEn9Kh+07Sf4LZknOexaJHTx/UVlqEBuRl6yf7CPbmJUg94i5wrcu1ZXCkHOBt5jof2qZbrO47xCzHbJ9xd/Efb6YHh4ZOKVZDT9jvbsZWoORnihW2Mjp9RVu+zaCq5vomKTlLxARn/wANJyT8zk+mK1Vbh15iKxGR8jzLFtyU2fh9Uhey1IKzn7CkmK+CqTcJSjpQC4s/ej/HlwH4UBs8zkgeA/v7GlG6XCJbVWi3TFhPvr4177YG+/lq0j517OFLmd27mCCVNxNImSb/AD3rghTclTx1Nq5pHJI/04oZk1ZXtViNtNNSUtI1rcBKykahtyzSbcLCqHZIFyQtTiJKQpadP/Dzyx40CtocZh9lJrO0QOMg5B36VmM8/pXtZU5VGeFxpLjQ2I7sNp8so0JWpwgkYxvtRyycXXC66oERlLCtOVP69XZp5befhVeDJISkEqPJI5n0FN3DXDnFDrLjtutf4ThBLjqsbDoE6gfHnQ76aph1CE1Dg98RzbkRbH2pW+lqA2kEuLVuHDzA8T1rk9drzf2349iYVGaDeVPvbOrHLuDPdJ6US4X4MTciJt8SZamVFtphxrQ2349zGPHc5pvas8OzQXFFaW2irYLIGOQSkfYCvCkA58yb6kkbR1Kgf4DYagx57r76m1PIL/bDCuzUcE56HNLfD0lFv4pZU2Sprt1Mgk80kkA/pVn8WXZmd7MZMxLamirtYq21EZStLoTVW3NmBCZthhP9tL7y5C0kaRuNI+yjRBGRBVOGBljW+Mptu8RSpRSl1YQkgAd5AO31pUivFFsyT8LWT8hTnbndct/tc6n2W1BI8BlJP3FI0hPu0OYyf+UpxHyBIqOkbDGWa1QyqY2Q7UZfCRtYHecjAAn+bGR96qyVEkw5BjTI7jEgf8paSFH0HUelNnDXHc23Ftia2qU1kJSUDDnljxp8ie0DhqUpCJxLLyNkqeZIWkn150tLajTMx2bgfiEuKrlBU4IlWWzhG/XRaRHtj6UE/wDEfT2afvvT3w57NITTiXr5JEnBz2LZ0I28T1/SmW/RuIJsMOWq8MNtrTqQFxsEjp6fSk1jhriedckIvtyWYOfxEsSCNQHTAAwKpbVveh94T8u/3nVo29KT/EuC1sQokRLcBptthOwDYAG23+1QLw8V5wrfGPKuMV0RYqGUEhCRhKc7AeAqHJd1k+FZ5FbfycjMLrow2TKp9pFuuLc1udJUl2Kr8NtSU40dcHx9aSzVy8Zw1XLh2c0hOSy32ySBzUnfA+4+dU1sd61+gt9SkDyIu1deyyNntDmuniRSG3VJDcdAIBxvuf3FRYfEIZYCXWypzOCrbFR+Mlhzie5EKyA4lGfRI/eg1MjYQ5xAPTVlAMsXhx83C5CTpIS0zgDzUf6D71brrv8ACuB33M6XFN6R5lRAH61VHs1hKVb2z+aQ99s4FWJx/J7K3wYCTgKVrPoNh+tEZLIM+YOMIxMXeHWsvlWN0j9aBmShniW531aEuJjZaQkqwfAlPiRp5Uz21AiwXH1EJBBXk9AKrCa7KnWoIbjuN9ortCpQzkHc8t/tXL0V1KN8TtDsjArMRLd4n4rhMKUvsFyEnRy2BySfpUri+V73xxEGvUll1vSc9NQP6AVrwGkRru/OlDSpiOsJ1D4lHqPQZ+tDLY7/ABDi5l4jIVIKvpmk7JtsPHCrGwYuuT2TLT9pMRNxtEZhpLfaSJLaVOADUoevkBTlwbDbt1qcfQgIShIbbHTAH9/Sk9Kl3G9tR2jqZhJGO7sHVjlt4JI/1048TyU2mxIhtnvlOnHmev61f9LpNelAPZ/iCaywNefhf5io44bne3HicoSru58B/U7/ADqsOM5arzxA+SSGk/hRFHYKCeePU5P0qwJ8pNn4dekuKSh10dmjJxgq2H9aU5cJqdDDY7pSkaFp8ByIpm6bhtHiBCzYdx8yf2z3FPAuXCFzIiS28OupPI/MCly7Sy7wjalsqAT2SWT3uqdjt/fOpvD1yXZZzkiQnDSwGZyAnkOjo8vGhvEENVplzLa6QYsgiTFdG6c+A/T6Ur2bH2+OxG/qb03DvowFEivzJCI0Rpbry8hCE8zgEn7A02cL8EI4gtbjiZa2JneCG1JGMjof3pThyH4spqREdU282oFtaTuDTnaOKLzZJyZl5grTDdUFOFtATg89Y3Iz4jrVpgwlk2DhG3O26JDkwWGZTKRh1oYWhYG5Ch15+tN9qhs2xCYodCihO+tQCiPGq54w4jktP2y9WKW0AFdnIb20KUoZRrHNIPLPQkc6r3i5q63e5ru8rtVplN9xRGNKBnuHHUHbzr2J2XRxh7R+HuH3OwDqZsnSSWoqkrKD4KI5Heqv9ol7m3kJntvEMobjSozI/wCWnBO+PNWf+iq/KOzyjGCOmKboL8OVw7bm3dfbsurhualfEhYUpH/9Ejw2ronpG4ovD7sc29lX+DlyE3Eb8ypAGPTOT6mmC98L2+x8Iq96dQZMlKHWQlRUtSx8RIHIYwPD60lzo60WhtLmA9b5K4ru3NKsrQfqlwfSrq/gsBnhBhpMtMiMqAhCQpZJCu8Svwxy28q4Z6DS3GTb7TPtzodadGlw9QrG4I9RSfdY6F3yXEeB7J6Un/SsJJ/U0YhJbHD9vcaGShhGpYGSdjuDjGNvuKDcQuOO3pgNuNtOOtsrC14IScrAPP8Ay/eqEPubELtGUGfkQ1buHoFtmB+BAW64nqqSnH3FE0oubcszYvDERUo40vPSEqV9TnFJdxgcXx5KWkQnZBcGpt2DqWhwDfbCuflQiWeJkqKJLV4ZztoU06Mn6eNBije2S4P+fnLTegGAuP7SzJ0vjuSApLFtZUrfvySo/pRmIhUWK0ibJQ5I05ccyACrrjypC4b9m17uqRJusqREQrcI7QqXjz329KfbZ7M+HoidT8QSlZ3W+ckn50u1Z049oPI/2j/nMnXcy8n+f/Jo7cre1sqfFT5F5P8AWp0JtqSyX0KS430KTkUbi2e3QkgRIUdkDl2bYFey0gJIwKVWOvSgy0andxAj7SAnSEgCvn3iCH/DLxNiaNKW3lBA/wAp3T9q+hZB51UXtQiBm+MSkoz27OD6pP8AvTf6Nbi0p8ynWJuQGK14c7a7z3P55Lp//Y1EPlW+7z3d5uLJ+ppqatDLUWMgoSXHXUN6hzwVDUfpmtOqFySIoawIBLF9n8EMMxEadmmQT6kf71K43d7e9Ntf+C0E/WiPCbelCl+JH2oLdMyb2+odXAn6UbjkCBDomacRLLHDMltJwpxtLKT4FZCf3oTabM27r7V4IQ23lTiwQnPgKI8WOfg29jbvyNZB8EpJ/UpoUtwlO/TlV9ag5JgeodgQo6g24Wxl7X2aiD+ZQOx+vOl+3xv4RfmVOg6EpURjfptj9KZnnemknzGK4xY6bldobWnUlpReWSOQGwHzJH0oe+lH4helusTkywvZ/blAtvSB+IMvOq8Vq6f34V5xTKNyvQZT8DXM+Z/oMUeh6bXYVvrHeWNR/Yf340qQxpL8x8jmVKV0HUn7VxVGePEsJOPz5iN7VLhrkQ7W2ruMp7V4D+YjCR9Mn5ila0Xh23kIVlbOeWd0+lEOMEy3Vpmzoqozr0hfxc1pISps/wCjA+VLe/Tn6UH6u5iywv0gFCtHhRZmoEphSFahjPQjwNSWYLd5ta7M8T2zCSq3ur6D+Q+n6UkW+c7Bd1NnKD8aDyNNMSch8tyIq8LQoKG+ClX9/WpPi0fjI1k0N+ET32HI7y2JCNDiFYUk9KbeHeHU8QW0PuXN4OJdDagtZKWhnnv5UV4ltTd+gpuMNGJqdloSPiIG4z+lQ7sjhuy2mzO25+Y4+8tL8hkk6VBJAUFJO2RuB54odXzx5hT17eR1I3ENrctSH4Wt5S4ONDpbKRJj5HyOhRHpmmyyXuFdrAbY4lsyT329XNSgN0/Mb+oo005ZuJ4Vthx5jIZjv9oHkrC17ghSFA7jUDjHnVW8Y2KVwdxGuF2hS2D2kVwHcp6fMVOVQXeQ2JjhR8Oa2siDIVLhD45DJ7HHMuoOtOPXCk/9Vb3lovttXZpI7GUrS7/+N7GVJ8sjvDxFQIklcKUzKbJC2VhYx1wc4rs9GKW2qd2ymQSbnbw+nAzqeZIOw8SAcD/NVmNNW4+z+3M2xfaR1wFKeUk5KlAcj4EHIoNw/wAMSXb3Gke6k2ZqT72zICk6SFpJU3zz1A2H5RTRd4q3kNsx+zZDzv4qUJAHZ4JXy67DfzFRZgBJKpY4EWbagN8OsRiCOxYQgnG+dIOfvSZxqUrbiqAH4iSCEnYaVZx8tdWNck/4d1fRStQSkEbYA/akO829y4uW1hH4YWpwKUpJxnu9PlQdLDO6MNQh2hYK4ZvV9iy2I1pfcVk40cwPHV5Cr9skqW5HAmYUrSNZA21dceVI/B3DzFuTpjpKlk991QGVHz8KfYqNKUoR86QfVtQljYQfrLa6jXX7uz+0NxglQBwAPSvX1pJ7nw1yQVBsDNcHngPWoLrUq0+wDmBlCW4nrjgSD40NlPqXnbat3VlWT4VBkL0jJPypcGaw5MLqrkZ886r/ANqEQvwIjzZ76HtO3gQT/wBtOkl9SshP+kUNlwhMQEvpJAOdh1plo81WB5fam6siVRw3CDiw+vGEjbxpigupl8QRWNWQ0C5geQ0j/wBX2ocXBb7aA2O9p2xzJohwVBU1dHXXiFPFsFR8Mnl9q3K+FEy785cy2rAjs4ZPmTQVlAXNLn8zhV96OxCGrYtXgkmhsJsahnGQPvV57laD2xZ4vUXLpFY2wiOtSuvxKA/7aELShI2HqRU3iF0K4hlnOyG22wPA4JP61AAJ7yth51JDxB7F92ZotelslSu7+vlR/wBnluMtbkotlBlO4APRtOQPvqPzFLryVrACE5cUQhsY5FRwP78qtnhG3Nw4acDAbQEJ+m9RY4OZYgyMTOKXzoZgtcjuoDy2/v0pT4pfMKze7so1rfUGgjVgqTzV9gaYJyzJujjvLoPQUq3q4NquzrBbS4I7ASkn8q17/ZIT/qqIXIx8yxzt90Bccvf/ABI/Zo9uB1vr0hOMdngYIPmKERuBbg9fJMF1JZiRjl2SrGMeA8zj9+tMNhYbVxPFdXjdK+fLIwc48dsfIVM9od7ujSREt0dXZLwVupGwzWdsNmnuGlr6x3HVRW+oXNK1vseJEuj7EBxS2EHAKvGosWS5FdDjR3HMdD61qtGXlpDgcwT3x1865+lMVyAPmCtgk/EsDhq9Np1acll0aVpP5FVw45tvvEWPLhx1a2dfbpAwQCRj1O1JsWS7FdDjKsEcweRHnVqcPTIc7h7t2VFx8EofbX+QAZHL16c6jbx7xLaPcPTbrxK/4U4kk8N3ESo47RtXdWjOD6g9DVwWG9Wfi+yqXdoCHC6lbSycKW18+nrVVcWWAQlqlQsFnOVgH4T0PpXCx3aK1JCpC3oTxGn3iMvH1HI9OYrwYMMyLIVODLDt/s/hxYEmMb0zKYkIUlcdxBSDhWW1BYzhSfHB5mvf/lXw63AWr324S5GnZWpKUBXkB09a34cuCUwwn+J+8NrcKx2oQo7nkMAdaNpmhkvdpKeeDnwo7qQ2D0GBn71W1yr3LF0zt1Ozl3aRZmWLI21LdCAzHixlhSUqGxCiOSR1Pl41IWHmmQ04WnJryQHFN5DaAOYHlud+tQbZAaiNYjMx7ZEUe+pCPxF58f8Ac/KjUhNttbC1ofLjqgSVFWcacZH36UPba1gwo4hFVS0t7uTFTiZ4R0OJUBpSNjzH08aS47naybcEBOpc1SkkklRGkjfPIUx8SLVc31pYWkJx8ZGOWfrzI22/YNw25bpd2BLyGvcm9Lba1ZLiid1g45dB8/GuAbKSZY5L2ASxLa0mOyEJ3J5misdwJI3oPHcBGQoEeIqWhZrKWKS2TDWXMMe9AI2O9RlOZHPPnUTtDXKRI0DGf96r9PJlIq54nR+TpSdJ+dDVuqcJwcDqTXN15JOpxYSkeJ2rRtUiUsNwGSc/8xQ2+Q6+pwPWjKqQJbxWJ7JdjwWC9JcS2gfmUefp4n0pem3O9TVFVrYahxwrCXZKdS3PRPQeu/lTUuzIaw/MUXX+mT8Pp4fKoMggKwkDbzomvUIpwgyfxlePU8yrB+I8nXvoRqA89hTNwoM3CZ5KbA9MV7WVta/vTMWdSw3SRaFY/wAv61GidflWVlXt2ZWnUr2eSu/XXVv/AIj/ALU1xbKnHw2pR0eAwKysrydSqzuEbS0l3iGA2sqKEhxwDP5gAAfuattgBu0Eo2OgGsrKjZJ0dReAH4h67VWzjy1y5Tijlbkl0qPorSPskVlZXR2JK7qbxnVt3iDoOMFZ+xpYuvEt0elSmFPJCO0UjZAzjlzr2spVqAPtRP4CMdKf/mH5wIlwtoW0kDCyMnG/LxrXoPMA1lZUxOGZRrg+dIh3+GlleESHgy6g8lJO313rKyuP90ydX3xGyYP8Q4jP4a3OzLfQDf8ApSJI0w7irsm0KSFgaFjIINe1lV1S7UdiP8S129tSFIhMpKgFHSCnfB8D5U1W2KyyAppASSOfP9aysoO6H09Ty4ynUoYCVY7RSkkjwxQeVJdU/oz3NIUU+Jr2srtf3ZGz70jXUh1VrhlKQ1JaU84QO9lJT3QeicnOKP2/h22XBoqlRkKKN07AY2z4VlZQutdlxtOJ5OiYQbhMQQEMJOP8xzUkHasrKSuYaOpsCajyzlQFZWVFO5EdzpAhMPuBTqdWPGjraUsNFTSUp8gK8rK6pO4/lA9QfdAlzkOaM55nFDSgE71lZUqOUBhFX3J//9k=)`\n\n// Create a <style> element and append the styles\nlet styleSheet = document.createElement(\"style\");\nstyleSheet.type = \"text/css\";\nstyleSheet.innerText = styles;\ndocument.head.appendChild(styleSheet);\n\n// Create the combatants' wrapper\nlet div_wrapper = document.createElement('div');\ndiv_wrapper.classList.add('contrincants_wrapper');\n\n// Create the first combatant (Wolverine)\nlet div1 = document.createElement('div');\ndiv1.classList.add('contrincant');\ndiv1.style.setProperty('background', wolverine_avatar);\ndiv1.style.backgroundSize = 'cover'; // Ensure the background covers the div\ndiv_wrapper.appendChild(div1);\n\n// Create the second combatant (Deadpool)\nlet div2 = document.createElement('div');\ndiv2.classList.add('contrincant');\ndiv2.style.setProperty('background', deadpool_avatar);\ndiv2.style.backgroundSize = 'cover'; \ndiv_wrapper.appendChild(div2);\n\n// Create the log container\nlet logContainer = document.createElement('div');\nlogContainer.classList.add('log_container');\nlogContainer.style.color = '#fff';\nlogContainer.style.marginTop = '20px'; \nlogContainer.style.width = '100%'; \nlogContainer.style.textAlign = 'center'; \ndiv_wrapper.appendChild(logContainer);\n\n\n// Append the wrapper to the body\ndocument.body.appendChild(div_wrapper);\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/javascript/hectorio23.js",
    "content": "// Autor:  Héctor Adán\n// GitHub: https://github.com/hectorio23\n\n/*\n * EJERCICIO:\n * ¡Deadpool y Wolverine se enfrentan en una batalla épica!\n * Crea un programa que simule la pelea y determine un ganador.\n * El programa simula un combate por turnos, donde cada protagonista posee unos\n * puntos de vida iniciales, un daño de ataque variable y diferentes cualidades\n * de regeneración y evasión de ataques.\n * Requisitos:\n * 1. El usuario debe determinar la vida inicial de cada protagonista.\n * 2. Cada personaje puede impartir un daño aleatorio:\n *    - Deadpool: Entre 10 y 100.\n *    - Wolverine: Entre 10 y 120.\n * 3. Si el daño es el máximo, el personaje que lo recibe no ataca en el\n * siguiente turno, ya que tiene que regenerarse (pero no aumenta vida).\n * 4. Cada personaje puede evitar el ataque contrario:\n *    - Deadpool: 25% de posibilidades.\n *    - Wolverine: 20% de posibilidades.\n * 5. Un personaje pierde si sus puntos de vida llegan a cero o menos.\n * Acciones:\n * 1. Simula una batalla.\n * 2. Muestra el número del turno (pausa de 1 segundo entre turnos).\n * 3. Muestra qué pasa en cada turno.\n * 4. Muestra la vida en cada turno.\n * 5. Muestra el resultado final.\n*/\n\nclass Character {\n    constructor(name, minDamage, maxDamage, dodgeChance) {\n        this.name = name;\n        this.health = 0;\n        this.minDamage = minDamage;\n        this.maxDamage = maxDamage;\n        this.dodgeChance = dodgeChance;\n    }\n\n    attack() {\n        return Math.floor(Math.random() * (this.maxDamage - this.minDamage + 1)) + this.minDamage;\n    }\n\n    evade() {\n        return Math.random() < this.dodgeChance;\n    }\n\n    isAlive() {\n        return this.health > 0;\n    }\n}\n\nclass Deadpool extends Character {\n    constructor() {\n        super(\"Deadpool\", 10, 100, 0.25);\n    }\n}\n\nclass Wolverine extends Character {\n    constructor() {\n        super(\"Wolverine\", 10, 120, 0.20);\n    }\n}\n\nfunction simulateBattle(char1, char2) {\n    let turn = 1;\n    let skipChar1 = false;\n    let skipChar2 = false;\n\n    while (char1.isAlive() && char2.isAlive()) {\n        console.log(`\\n**** Turno ${turn} ****:`);\n        if (!skipChar1) {\n            if (!char2.evade()) {\n                let damage = char1.attack();\n                char2.health -= damage;\n                console.log(`[+] - ${char1.name} ataca a ${char2.name} causando ${damage} de daño.`);\n                if (damage === char1.maxDamage) {\n                    console.log(`[+] - ${char2.name} debe regenerarse y pierde el siguiente turno.`);\n                    skipChar2 = true;\n                }\n            } else {\n                console.log(`[+] - ${char2.name} evade el ataque de ${char1.name}.`);\n            }\n        } else {\n            skipChar1 = false;\n        }\n\n        if (!skipChar2 && char2.isAlive()) {\n            if (!char1.evade()) {\n                let damage = char2.attack();\n                char1.health -= damage;\n                console.log(`[+] - ${char2.name} ataca a ${char1.name} causando ${damage} de daño.`);\n                if (damage === char2.maxDamage) {\n                    console.log(`[+] - ${char1.name} debe regenerarse y pierde el siguiente turno.`);\n                    skipChar1 = true;\n                }\n            } else {\n                console.log(`[+] - ${char1.name} evade el ataque de ${char2.name}.`);\n            }\n        } else {\n            skipChar2 = false;\n        }\n\n        console.log(`${char1.name} Vida: ${char1.health}, ${char2.name} Vida: ${char2.health}\\n`);\n        turn++;\n        require('child_process').execSync('sleep 1');  // Pausa de 1 segundo\n    }\n\n    if (char1.isAlive()) {\n        console.log(`${char1.name} gana la batalla!`);\n    } else {\n        console.log(`${char2.name} gana la batalla!`);\n    }\n}\n\n// Solicitar al usuario la vida inicial de los personajes y ejecutar la simulación\n(async function () {\n    const readline = require('readline').createInterface({\n        input: process.stdin,\n        output: process.stdout\n    });\n\n    const ask = (question) => new Promise(resolve => readline.question(question, resolve));\n\n    let deadpoolHealth = await ask(\"Ingrese la vida inicial de Deadpool: \");\n    let wolverineHealth = await ask(\"Ingrese la vida inicial de Wolverine: \");\n\n    deadpoolHealth = Number(deadpoolHealth);\n    wolverineHealth = Number(wolverineHealth);\n\n    let deadpool = new Deadpool();\n    let wolverine = new Wolverine();\n\n    deadpool.health = deadpoolHealth;\n    wolverine.health = wolverineHealth;\n\n    simulateBattle(deadpool, wolverine);\n\n    readline.close();\n})();\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/javascript/isaacus98.js",
    "content": "/*\n * EJERCICIO:\n * ¡Deadpool y Wolverine se enfrentan en una batalla épica!\n * Crea un programa que simule la pelea y determine un ganador.\n * El programa simula un combate por turnos, donde cada protagonista posee unos\n * puntos de vida iniciales, un daño de ataque variable y diferentes cualidades\n * de regeneración y evasión de ataques.\n * Requisitos:\n * 1. El usuario debe determinar la vida inicial de cada protagonista.\n * 2. Cada personaje puede impartir un daño aleatorio:\n *    - Deadpool: Entre 10 y 100.\n *    - Wolverine: Entre 10 y 120.\n * 3. Si el daño es el máximo, el personaje que lo recibe no ataca en el\n * siguiente turno, ya que tiene que regenerarse (pero no aumenta vida).\n * 4. Cada personaje puede evitar el ataque contrario:\n *    - Deadpool: 25% de posibilidades.\n *    - Wolverine: 20% de posibilidades.\n * 5. Un personaje pierde si sus puntos de vida llegan a cero o menos.\n * Acciones:\n * 1. Simula una batalla.\n * 2. Muestra el número del turno (pausa de 1 segundo entre turnos).\n * 3. Muestra qué pasa en cada turno.\n * 4. Muestra la vida en cada turno.\n * 5. Muestra el resultado final.\n */\n\nclass Character {\n    constructor(name, health, minDamage, maxDamage, evasion) {\n        this.name = name\n        this.health = health\n        this.minDamage = minDamage\n        this.maxDamage = maxDamage\n        this.evasion = evasion\n    }\n\n    // Devuelve el numero de daño generado\n    attack() {\n        return Math.floor(Math.random() * this.maxDamage) + this.minDamage\n    }\n\n    // Devuelve true si esquiva el ataque, false si no lo esquiva y le resta puntos de vida\n    dodge(damage) {\n        let isEvasion = Math.floor(Math.random() * 100) + 1\n\n        // Ha evadido el ataque\n        if (isEvasion <= this.evasion) {\n            return true\n        } else {\n            if ((this.health - damage) < 0) {\n                this.health = 0\n            } else {\n                this.health -= damage\n            }\n\n            return false\n        }\n    }\n}\n\nconst rl = require('readline-sync');\n\n// Pide los puntos de vida que tendra Deadpool\nlet health = rl.question(\"Inserte la cantidad de vida que tendra Deadpool? \")\nlet deadpool = new Character(\"Deadpool\", parseInt(health), 10, 100, 25)\n\n// Pide los puntos de vida que tendra Wolverine\nhealth = rl.question(\"Inserte la cantidad de vida que tendra Wolverine? \")\nlet wolverine = new Character(\"Wolverine\", parseInt(health), 10, 120, 20)\n\nconsole.log(\"Estadisticas Deadpool\")\nconsole.table(deadpool)\n\nconsole.log(\"Estadisticas Wolverine\")\nconsole.table(wolverine)\n\nbattle()\n\nasync function battle() {\n    let alternate = true\n    let evasion = false\n    let damage = 0\n    let wolverineInitialHealth = wolverine.health\n    let deadpoolInitialHealth = deadpool.health\n\n    do {\n\n        // Deadpool\n        if (alternate) {\n            console.log(\"Turno de Deadpool\")\n        \n            // Realizar ataque\n            damage = deadpool.attack()\n            console.log(`Deadpool hace un ataque de ${damage} puntos de daño`)\n        \n            // Evasión\n            evasion = wolverine.dodge(damage)\n            if (evasion) {\n                console.log(\"Wolverine ha esquivado el ataque\")\n            } else {\n                console.log(`Wolverine a recibido un ataque de ${damage} puntos de daño`)\n            }\n\n            // Comprovar si el turno canvia\n            if (damage == deadpool.maxDamage & !evasion) {\n                console.log(\"Wolverine entra en modo de regeneración\")\n                alternate = true\n            } else {\n                alternate = false\n            }\n        } else { // Wolverine\n            console.log(\"Turno de Wolverine\")\n        \n            // Realizar ataque\n            damage = wolverine.attack()\n            console.log(`Wolverine hace un ataque de ${damage} puntos de daño`)\n        \n            // Evasión\n            evasion = deadpool.dodge(damage)\n            if (evasion) {\n                console.log(\"Deadpool ha esquivado el ataque\")\n            } else {\n                console.log(`Deadpool a recibido un ataque de ${damage} puntos de daño`)\n            }\n\n            // Comprovar si el turno canvia\n            if (damage == wolverine.maxDamage & !evasion) {\n                console.log(\"Deadpool entra en modo de regeneración\")\n                alternate = false\n            } else {\n                alternate = true\n            }\n        }\n\n        // Mostrar vida de los personajes a final de turno\n        console.log(`Deadpool: ${deadpool.health}/${deadpoolInitialHealth}`)\n        console.log(`Wolverine: ${wolverine.health}/${wolverineInitialHealth}`)\n\n        // Pausa de 1 segundo\n        await new Promise(r => setTimeout(r, 1000));\n    } while(deadpool.health > 0 & wolverine.health > 0)\n\n    if (deadpool.health == 0) {\n        console.log(\"Wolverine ha ganado la pelea\")\n    } else {\n        console.log(\"Deadpool ha ganado la pelea\")\n    }\n}"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n_______________________________________________________\n#32 * BATALLA DEADPOOL Y WOLVERINE\n-------------------------------------------------------\n * EJERCICIO:\n * ¡Deadpool y Wolverine se enfrentan en una batalla épica!\n * Crea un programa que simule la pelea y determine un ganador.\n * El programa simula un combate por turnos, donde cada protagonista posee unos\n * puntos de vida iniciales, un daño de ataque variable y diferentes cualidades\n * de regeneración y evasión de ataques.\n * Requisitos:\n * 1. El usuario debe determinar la vida inicial de cada protagonista.\n * 2. Cada personaje puede impartir un daño aleatorio:\n *    - Deadpool: Entre 10 y 100.\n *    - Wolverine: Entre 10 y 120.\n * 3. Si el daño es el máximo, el personaje que lo recibe no ataca en el\n * siguiente turno, ya que tiene que regenerarse (pero no aumenta vida).\n * 4. Cada personaje puede evitar el ataque contrario:\n *    - Deadpool: 25% de posibilidades.\n *    - Wolverine: 20% de posibilidades.\n * 5. Un personaje pierde si sus puntos de vida llegan a cero o menos.\n * Acciones:\n * 1. Simula una batalla.\n * 2. Muestra el número del turno (pausa de 1 segundo entre turnos).\n * 3. Muestra qué pasa en cada turno.\n * 4. Muestra la vida en cada turno.\n * 5. Muestra el resultado final.\n*/\n// ________________________________________________________\nconst readline = require('readline');\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nfunction getInput(promptText, callback, type = \"string\") {\n    rl.question(promptText, function processInput(input) {\n        if (!input || input.trim() === \"\") {\n            rl.question(\"The input cannot be empty. Please try again: \", processInput);\n            return;\n        }\n\n        if (type === \"number\") {\n            const numValue = Number(input.trim());\n            if (isNaN(numValue)) {\n                rl.question(\"Please enter a valid number: \", processInput);\n                return;\n            }\n            callback(numValue);\n            return;\n        }\n        \n        callback(input.trim());\n    });\n}\n\nfunction getInputAsync(promptText, type = \"string\") {\n    return new Promise((resolve) => {\n        getInput(promptText, resolve, type);\n    });\n}\n\nclass GlobalConfig {\n    static TIME = 2;\n    static MINIMUM_HP = 200;\n    static CHARACTERS = {\n        \"Deadpool\": {\n            attacks: [\"With weapon\", \"Hand to hand\", \"With reckless attack\"],\n            damageRange: [10, 100],\n            defenseChance: 0.25\n        },\n        \"Wolverine\": {\n            attacks: [\"With adamantium claws\", \"With weapon\", \"Hand to hand\"],\n            damageRange: [10, 120],\n            defenseChance: 0.20\n        }\n    };\n    \n    static MENU = `\nBATTLE SIMULATOR:\n------------------------------------------\n| 1. Simulate a battle | 2. Exit         |\n------------------------------------------`;\n}\n\nclass Character {\n    constructor(name, hp, attributes) {\n        this.name = name;\n        this.hp = hp;\n        this.attacks = attributes.attacks;\n        this.damageRange = attributes.damageRange;\n        this.defenseChance = attributes.defenseChance;\n        this.canAttack = true;\n    }\n\n    attack() {\n        if (this.canAttack) {\n            const selectedAttack = this.attacks[Math.floor(Math.random() * this.attacks.length)];\n            const damage = Math.floor(Math.random() * (this.damageRange[1] - this.damageRange[0] + 1)) + this.damageRange[0];\n            console.log(`|'${this.name}' attacks '${selectedAttack}' Causing: '-${damage}' 👊|`);\n            return damage;\n        } else {\n            console.log(`|'${this.name}' is regenerating and cannot attack. 😴|`);\n            return 0;\n        }\n    }\n\n    defend() {\n        if (Math.random() < this.defenseChance) {\n            console.log(`|'${this.name}' managed to defend. 🛡️|`);\n            return true;\n        } else {\n            console.log(`|'${this.name}' couldn't block the attack. 🤕|`);\n            return false;\n        }\n    }\n}\n\nclass BattleStrategy {\n    execute(attacker, defender) {\n        const damage = attacker.attack();\n        \n        if (damage === attacker.damageRange[1]) {\n            console.log(`|'${defender.name}' 🚨received a critical hit and won't be able to attack.🚨|`);\n            defender.canAttack = false;\n        }\n        \n        if (attacker.canAttack) {\n            if (!defender.defend()) {\n                defender.hp -= damage;\n            }\n        } else {\n            attacker.canAttack = true;\n        }\n        \n        if (defender.hp <= 0) {\n            console.log(\"\\n____________________________\");\n            console.log(`|'${attacker.name}' 🏆 wins the battle. 🏆|`);\n            return false;\n        }\n        \n        return true;\n    }\n}\n\nclass BattleFeatures {\n    constructor() {\n        this.battleStrategy = new BattleStrategy();\n        this.character1 = null;\n        this.character2 = null;\n    }\n\n    async getCharacter(msg) {\n        while (true) {\n            console.log(\"\\nAvailable characters:\");\n            Object.keys(GlobalConfig.CHARACTERS).forEach((name, i) => {\n                console.log(`${i}. ${name}`);\n            });\n\n            const index = await getInputAsync(msg, \"number\");\n            const keys = Object.keys(GlobalConfig.CHARACTERS);\n\n            if (!(index >= 0 && index < keys.length)) {\n                console.log(\"Incorrect character number.\");\n                continue;\n            }\n\n            if (this.character1 && keys[index] === this.character1.name) {\n                console.log(\"Character already used.\");\n                continue;\n            }\n\n            const hp = await getInputAsync(`Set HP >= than '${GlobalConfig.MINIMUM_HP}': `, \"number\");\n            if (hp < GlobalConfig.MINIMUM_HP) {\n                console.log(`HP must be greater than '${GlobalConfig.MINIMUM_HP}'.`);\n                continue;\n            }\n\n            const name = keys[index];\n            const attributes = GlobalConfig.CHARACTERS[name];\n            return { name, hp, attributes };\n        }\n    }\n\n    showHP() {\n        console.log(\"____________________________\");\n        console.log(`|${this.character1.name}: ❤️ ${this.character1.hp}| |${this.character2.name}: ❤️ ${this.character2.hp}|`);\n    }\n\n    async battle() {\n        let turn = 1;\n        while (true) {\n            console.log(`\\n----------------------------\\nTurn #${turn}\\n----------------------------`);\n\n            this.showHP();\n            if (!this.battleStrategy.execute(this.character1, this.character2)) break;\n            \n            this.showHP();\n            if (!this.battleStrategy.execute(this.character2, this.character1)) break;\n\n            turn++;\n            await new Promise(resolve => setTimeout(resolve, GlobalConfig.TIME * 1000));\n        }\n        \n        this.showHP();\n    }\n\n    async startSimulation() {\n        const char1Data = await this.getCharacter(\"'First' character: \");\n        this.character1 = new Character(char1Data.name, char1Data.hp, char1Data.attributes);\n\n        const char2Data = await this.getCharacter(\"'Second' character: \");\n        this.character2 = new Character(char2Data.name, char2Data.hp, char2Data.attributes);\n\n        await this.battle();\n\n        this.character1 = null;\n        this.character2 = null;\n        console.log(GlobalConfig.MENU);\n    }\n}\n\nclass Program {\n    constructor() {\n        this.features = new BattleFeatures();\n    }\n\n    async run() {\n        console.log(GlobalConfig.MENU);\n        while (true) {\n            const option = await getInputAsync(\"\\nOption: \", \"number\");\n            switch (option) {\n                case 1:\n                    await this.features.startSimulation();\n                    break;\n                case 2:\n                    console.log(\"Goodbye\");\n                    rl.close();\n                    return;\n                default:\n                    console.log(\"Select from '1 to 2'\");\n            }\n        }\n    }\n}\n\nconst program = new Program();\nprogram.run().catch(console.error);\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/javascript/nlarrea.js",
    "content": "/*\n * EJERCICIO:\n * ¡Deadpool y Wolverine se enfrentan en una batalla épica!\n * Crea un programa que simule la pelea y determine un ganador.\n * El programa simula un combate por turnos, donde cada protagonista posee unos\n * puntos de vida iniciales, un daño de ataque variable y diferentes cualidades\n * de regeneración y evasión de ataques.\n * Requisitos:\n * 1. El usuario debe determinar la vida inicial de cada protagonista.\n * 2. Cada personaje puede impartir un daño aleatorio:\n *    - Deadpool: Entre 10 y 100.\n *    - Wolverine: Entre 10 y 120.\n * 3. Si el daño es el máximo, el personaje que lo recibe no ataca en el\n * siguiente turno, ya que tiene que regenerarse (pero no aumenta vida).\n * 4. Cada personaje puede evitar el ataque contrario:\n *    - Deadpool: 25% de posibilidades.\n *    - Wolverine: 20% de posibilidades.\n * 5. Un personaje pierde si sus puntos de vida llegan a cero o menos.\n * Acciones:\n * 1. Simula una batalla.\n * 2. Muestra el número del turno (pausa de 1 segundo entre turnos).\n * 3. Muestra qué pasa en cada turno.\n * 4. Muestra la vida en cada turno.\n * 5. Muestra el resultado final.\n */\n\nconst readline = require('readline');\n\nconst rl = readline.createInterface({\n\tinput: process.stdin,\n\toutput: process.stdout,\n});\n\nconst random = (min, max) => {\n\tmax = max | 0;\n\t[min, max] = [Math.min(min, max), Math.max(min, max)];\n\treturn Math.floor(Math.random() * (max - min) + min);\n};\n\nclass Damage {\n\t#min;\n\t#max;\n\n\tconstructor(min, max) {\n\t\tthis.#min = min;\n\t\tthis.#max = max;\n\t}\n\n\tcalculate() {\n\t\treturn random(this.min, this.max);\n\t}\n\n\tget min() {\n\t\treturn this.#min;\n\t}\n\n\tget max() {\n\t\treturn this.#max;\n\t}\n}\n\nclass Fighter {\n\t#name;\n\t#damage;\n\t#evade;\n\t#life;\n\t#rests;\n\n\tconstructor(name, damage, evade, life, rests) {\n\t\tthis.#name = name;\n\t\tthis.#damage = damage;\n\t\tthis.#evade = evade;\n\t\tthis.#life = life;\n\t\tthis.#rests = rests;\n\t}\n\n\tattack() {\n\t\tif (this.#rests) {\n\t\t\tconsole.log(`${this.#name} se está recuperando...`);\n\t\t\tthis.#rests = false;\n\t\t\treturn 0;\n\t\t}\n\n\t\t// Calculate the damage value\n\t\tconst damage = this.#damage.calculate();\n\t\t// Check if fighter will need to rest in his next turn\n\t\tthis.#rests = damage === this.#damage.max;\n\t\tif (this.#rests) {\n\t\t\tconsole.log(\n\t\t\t\t`Golpe crítico! ${\n\t\t\t\t\tthis.#name\n\t\t\t\t} deberá descansar en el siguiente turno...`\n\t\t\t);\n\t\t}\n\n\t\treturn damage;\n\t}\n\n\tevade() {\n\t\treturn Math.random() < this.#evade;\n\t}\n\n\tget name() {\n\t\treturn this.#name;\n\t}\n\n\tget life() {\n\t\treturn this.#life;\n\t}\n\n\tset life(life) {\n\t\tthis.#life = life;\n\t}\n}\n\nconst D = 'Deadpool';\nconst W = 'Wolverine';\n\nfunction isWinner(fighters) {\n\treturn fighters.some((fighter) => fighter.life <= 0);\n}\n\nfunction showLife(fighters) {\n\tfor (const fighter of fighters) {\n\t\tconsole.log(` - Vida de ${fighter.name}:`, fighter.life);\n\t}\n}\n\nfunction simulate(dLife, wLife) {\n\tconst fighters = [\n\t\tnew Fighter(D, new Damage(10, 100), 0.25, dLife),\n\t\tnew Fighter(W, new Damage(10, 120), 0.2, wLife),\n\t];\n\n\tconsole.log('\\nVidas iniciales:');\n\tshowLife(fighters);\n\n\t// Select who starts the fight\n\tconst firstFighter = Math.random() < 0.5 ? fighters[0] : fighters[1];\n\tconst secondFighter =\n\t\tfighters[(fighters.indexOf(firstFighter) + 1) % fighters.length];\n\n\tconsole.log(`\\n¡${firstFighter.name.toUpperCase()} COMIENZA EL COMBATE!`);\n\n\tlet turnCounter = 1;\n\tfunction battle(currentFighter, otherFighter) {\n\t\tfunction fight(currentFighter, otherFighter) {\n\t\t\tconst damage = currentFighter.attack();\n\t\t\tif (damage > 0) {\n\t\t\t\tif (otherFighter.evade()) {\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t`${otherFighter.name} ha esquivado el ataque!`\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t`${otherFighter.name} ha recibido ${damage} puntos de año!`\n\t\t\t\t\t);\n\t\t\t\t\totherFighter.life -= damage;\n\t\t\t\t\tif (otherFighter.life < 0) {\n\t\t\t\t\t\totherFighter.life = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tshowLife(fighters);\n\n\t\t\tif (isWinner(fighters)) {\n\t\t\t\tconsole.log(\n\t\t\t\t\t`\\n${currentFighter.name.toUpperCase()} HA GANADO EL COMBATE!`\n\t\t\t\t);\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\n\t\tconsole.log(`\\nTURNO ${turnCounter}:`);\n\n\t\t// Set the otherFighter\n\t\totherFighter =\n\t\t\tfighters[(fighters.indexOf(currentFighter) + 1) % fighters.length];\n\n\t\t// Fight\n\t\tlet winner = fight(firstFighter, secondFighter);\n\t\tif (winner) {\n\t\t\trl.close();\n\t\t\treturn;\n\t\t}\n\t\twinner = fight(secondFighter, firstFighter);\n\t\tif (winner) {\n\t\t\trl.close();\n\t\t\treturn;\n\t\t}\n\n\t\tturnCounter++;\n\t\tsetTimeout(() => battle(firstFighter, secondFighter), 1000);\n\t}\n\n\tbattle(firstFighter, secondFighter);\n}\n\nrl.question(`Ingresa la vida inicial de ${D}: `, (dLife) => {\n\trl.question(`Ingresa la vida inicial de ${W}: `, (wLife) => {\n\t\tsimulate(parseInt(dLife), parseInt(wLife));\n\t});\n});\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/javascript/pedamoci.js",
    "content": "import readline from \"readline\";\n\nconst colors = {\n  red: \"\\x1b[31m\",\n  green: \"\\x1b[32m\",\n  yellow: \"\\x1b[33m\",\n  reset: \"\\x1b[0m\",\n}\n\nclass Asks {\n  constructor() {\n    this.rl = readline.createInterface({\n      input: process.stdin,\n      output: process.stdout,\n    });\n  }\n\n  ask(question) {\n    return new Promise((resolve) => {\n      this.rl.question(question, (answer) => resolve(answer));\n    });\n  }\n\n  close() {\n    this.rl.close();\n  }\n}\n\nclass Character {\n  constructor(name, health, maxDamage, probabilityOfEvasion) {\n    this.name = name\n    this.health = health\n    this.minDamage = 10\n    this.maxDamage = maxDamage\n    this.probabilityOfEvasion = probabilityOfEvasion\n  }\n\n  attack() {\n    return (Math.round(this.minDamage + (Math.random() * (this.maxDamage - this.minDamage))))\n  }\n\n  evade() {\n    if ((Math.random() * 100) < this.probabilityOfEvasion) {\n      return true\n    } \n\n    return false\n  }\n}\n\nconst asks = new Asks()\n\nfunction await1Second() {\n  return new Promise(resolve => {\n    setTimeout(() => {\n      resolve()\n    }, 1000);\n  })\n}\n\nclass FightManager {\n  constructor(characterOne, characterTwo) {\n    this.characterOne = characterOne\n    this.characterTwo = characterTwo\n    this.damage = 0\n    this.didEvade = false\n    this.round = 0\n  }\n\n  logRound() {\n    this.round += 1\n    console.log(`\\n${colors.yellow}------- Round: ${this.round} -------${colors.reset}`)\n  }\n\n  processAttack(whoAttack) {\n    let defender, attacker\n    if ((whoAttack % 2) === 0) {\n      attacker = this.characterTwo\n      defender = this.characterOne\n    } else {\n      attacker = this.characterOne\n      defender = this.characterTwo\n    }\n\n    this.damage = attacker.attack()\n\n    this.didEvade = defender.evade()\n\n    if (this.didEvade) {\n      console.log(`${colors.green}${defender.name} evaded the attack${colors.reset}`)\n    } else {\n      defender.health = Math.max(0, defender.health - this.damage)\n\n      console.log(`🗡️   ${attacker.name} inflicted ${this.damage} points of damage`)\n    }\n  }\n\n  async shouldSkipTurn(whoAttack) {\n    if ((whoAttack % 2) === 0 && this.damage === this.characterTwo.maxDamage) {\n      this.logRound()\n\n      console.log(`\\n💥   ${this.characterTwo.name} has done MAX DAMAGE   💥\\n${this.characterOne.name} nedds to regenerate`)\n\n      await await1Second()\n\n      return true\n    } else if ((whoAttack % 2) === 1 && this.damage === this.characterOne.maxDamage) {\n      this.logRound()\n\n      console.log(`\\n💥   ${this.characterOne.name} has done MAX DAMAGE   💥\\n${this.characterTwo.name} nedds to regenerate`)\n\n      await await1Second()\n\n      return true\n    } else return false\n  }\n\n  printStatus() {\n    console.log(`❤️   ${colors.red}${this.characterOne.name} health: ${this.characterOne.health}` + '\\n' +\n                `❤️   ${this.characterTwo.name} health: ${this.characterTwo.health}${colors.reset}`\n    )\n  }\n\n  checkWinner() {\n    if (this.characterOne.health === 0) {\n      console.log(`\\nWINNER: ${this.characterTwo.name}`)\n      return true\n    }\n\n    if (this.characterTwo.health === 0) {\n      console.log(`\\nWINNER: ${this.characterOne.name}`)\n      return true\n    }\n  }\n}\n\nasync function fight() {\n  const healthCharacterOne = parseInt(await asks.ask(\"Insert Wolverine's health: \"))\n  const healthCharacterTwo = parseInt(await asks.ask(\"Insert Deadpool's health: \"))\n\n  if (isNaN(healthCharacterOne) || isNaN(healthCharacterTwo)) {\n    console.warn('The health of the characters must be a number')\n    fight()\n  }\n\n  const fightManager = new FightManager(new Character('Wolverine', healthCharacterOne, 120, 20), new Character('Deadpool' , healthCharacterTwo, 100, 25))\n\n  const firstAttack = (await asks.ask('who will launch the first attack?' + '\\n' +\n                                      'W ---> Wolverine'  + '\\n' +\n                                      'D ---> Deadpool\\n')).toUpperCase()\n\n  if (firstAttack !== 'W' && firstAttack !== 'D') {\n    console.warn('Invalid option')\n    return fight()\n  }\n\n  let whoAttack = (firstAttack === 'W') ? 1 \n                                    : 2 \n\n  let finished = false\n\n  while (!finished) {\n    fightManager.logRound()\n    fightManager.processAttack(whoAttack)\n    fightManager.printStatus()\n    if (fightManager.checkWinner()) finished = true\n\n    await await1Second()\n\n    if (await fightManager.shouldSkipTurn()) { whoAttack++ }\n\n    whoAttack++\n  }\n\n  asks.close()\n}\n\nfight()"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/javascript/raulG91.js",
    "content": "\nconst prompt = require('prompt-sync')();\n\nfunction getRandomNumber(min,max){\n\n    const minCeiled = Math.ceil(min);\n    const maxFloored = Math.floor(max);\n    return Math.floor(Math.random() * (maxFloored - minCeiled + 1) + minCeiled);\n}\n\nlet deadpool_life = prompt('Introduce vida maxima para Deadpool ')\nif(deadpool_life < 0) {\n\n}\nlet wolverine_life = prompt('Introduce vida maxima para wolverine ')\n\nif(deadpool_life > 0 && wolverine_life > 0){\n    let turn = 1;\n    let skip_turn = false;\n    while (deadpool_life > 0  && wolverine_life > 0) {\n        console.log(`Turno: ${turn}`)\n        //Determine who is attacking this turn\n\n        if (turn % 2 != 0){\n            //Attack Deadpool\n            if(skip_turn){\n                console.log(\"Deadpool no atacara en este turno\")\n                skip_turn = false\n            }\n            else{\n                let deadpool_attack = getRandomNumber(10,100);\n                //Let's see if Wolverine avoid attack\n                console.log(\"Deadpool atacara con: \" + String(deadpool_attack))\n                let skip = getRandomNumber(0,100);\n                if(skip <= 20){\n                    console.log(\"Wolverine esquiva el ataque de Deadpool\")\n                }\n                else{\n                    // Check if the damage is the max attack\n                    if(deadpool_attack == 100){\n                        skip_turn = true\n                        console.log(\"Ataque maximo de Deadpool!\")\n                    }\n                    wolverine_life -= deadpool_attack;\n                    \n                }\n            }\n        \n        }\n        else{\n            if(skip_turn){\n                console.log(\"Wolverine no atacara en este turno\")\n                skip_turn = false;\n            }\n            else{\n                let wolverine_attack = getRandomNumber(10,120)\n                console.log(`Wolverine atacara con ${wolverine_attack}`)\n                let skip = getRandomNumber(0,100);\n                if(skip <= 25){\n                    console.log(\"Deadpool esquiva el ataque de Wolverine\")\n                }\n                else{\n                    if(wolverine_attack == 120){\n                        skip_turn = true;\n                        console.log(\"Ataque maximo de Wolverine\")\n                    }\n                    deadpool_life -= wolverine_attack;\n                }\n            }\n        }\n        if(deadpool_life> 0 && wolverine_life > 0){\n            console.log(`Vida de Deadpool tras turno ${turn} es ${deadpool_life}`)\n            console.log(`Vida de Wolverine tras turno ${turn} es ${wolverine_life}`)\n            turn ++;\n        }\n        else{\n            // One character has died\n            if(turn % 2 == 0){\n                console.log(\"Wolverine ha ganado el combate\")\n            }\n            else{\n                console.log(\"Deadpool ha ganado el combate\")\n            }\n        }\n    }\n} \nelse{\n    console.log(\"Vida maxima debe ser mayor que 0\")\n}"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/javascript/victor-Casta.js",
    "content": "const readline = require('node:readline')\nconst { stdin: input, stdout: output } = require('node:process')\nconst rl = readline.createInterface({ input, output })\n\nclass Battle {\n  constructor() {\n    this.player_1 = { name: 'Deadpool', life: 1000, canAttack: true }\n    this.player_2 = { name: 'Wolverine', life: 1000, canAttack: true }\n  }\n\n  assignamentPlayerLife() {\n    rl.question(`Ingresa la vida inicial de Deadpool: `, (lifeFirstPlayer) => {\n      rl.question(`Ingresa la vida inicial de Wolverine: `, (lifeSecondPlayer) => {\n        let formatLifeFirstPlayer = parseInt(lifeFirstPlayer)\n        let formatLifeSecondPlayer = parseInt(lifeSecondPlayer)\n\n        if (formatLifeFirstPlayer > 0 && formatLifeSecondPlayer > 0) {\n          this.player_1.life = formatLifeFirstPlayer\n          this.player_2.life = formatLifeSecondPlayer\n          console.log(this.player_1)\n          console.log(this.player_2)\n\n          this.fight()\n        } else {\n          console.log('La vida del personaje no puede ser menor que 0')\n        }\n        rl.close()\n      })\n    })\n  }\n\n  fight() {\n    console.log('\\n¡Comienza la batalla!\\n')\n    while (this.player_1.life > 0 && this.player_2.life > 0) {\n      if (this.player_1.canAttack) {\n        const damageToPlayer2 = Math.round(Math.random() * (100 - 10) + 10)\n        const dodgeChancePlayer2 = Math.random() * 100\n\n        if (damageToPlayer2 === 100) {\n          console.log(`${this.player_2.name} recibe el daño máximo y no puede atacar la próxima ronda.`)\n          this.player_2.canAttack = false\n        } else if (dodgeChancePlayer2 <= 25) {\n          console.log(`${this.player_2.name} esquivó el ataque de ${this.player_1.name}`)\n        } else {\n          this.player_2.life -= damageToPlayer2\n          console.log(\n            `${this.player_1.name} ataca a ${this.player_2.name} y le hace ${damageToPlayer2} de daño. Vida restante de ${this.player_2.name}: ${this.player_2.life}`\n          )\n        }\n      } else {\n        console.log(`${this.player_2.name} está recuperándose y no puede atacar esta ronda.`)\n        this.player_2.canAttack = true\n      }\n\n      if (this.player_2.life <= 0) {\n        console.log('\\n¡Gana Deadpool!')\n        return\n      }\n\n      if (this.player_2.canAttack) {\n        const damageToPlayer1 = Math.round(Math.random() * (100 - 10) + 10)\n        const dodgeChancePlayer1 = Math.random() * 100\n\n        if (damageToPlayer1 === 100) {\n          console.log(`${this.player_1.name} recibe el daño máximo y no puede atacar la próxima ronda.`)\n          this.player_1.canAttack = false\n        } else if (dodgeChancePlayer1 <= 20) {\n          console.log(`${this.player_1.name} esquivó el ataque de ${this.player_2.name}`)\n        } else {\n          this.player_1.life -= damageToPlayer1\n          console.log(\n            `${this.player_2.name} ataca a ${this.player_1.name} y le hace ${damageToPlayer1} de daño. Vida restante de ${this.player_1.name}: ${this.player_1.life}`\n          )\n        }\n      } else {\n        console.log(`${this.player_1.name} está recuperándose y no puede atacar esta ronda.`)\n        this.player_1.canAttack = true\n      }\n\n      if (this.player_1.life <= 0) {\n        console.log('\\n¡Gana Wolverine!')\n        return\n      }\n    }\n  }\n}\n\nconst legendBattle = new Battle()\nlegendBattle.assignamentPlayerLife()\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/kotlin/blackriper.kt",
    "content": "import kotlinx.coroutines.*\r\nimport kotlinx.coroutines.flow.*\r\nimport java.time.Duration\r\n\r\n\r\n//1.-Definir entidades\r\n\r\ndata class Friend constructor(\r\n    val name:String,\r\n    val skill:String,\r\n    val damage:Int=(10..120).random()\r\n)\r\n\r\ndata class Warrior constructor(\r\n    val name:String=\"Deadpool\",\r\n    var life:Int=0,\r\n  )\r\n\r\n\r\nenum class Fighter{\r\n    DEADPOOL,\r\n    WOLVERINE\r\n}\r\n\r\n//2.-Definir datos auxiliares\r\n\r\nval deadpoolFriens= listOf(\r\n    Friend(\"Cable\",\"Telequinesis Shooter\"),\r\n    Friend(\"Yukio\",\"Energy Attack\"),\r\n    Friend(\"Domino\",\"Lucky Evasion\",0),\r\n    Friend(\"Colosus\",\"Steal Punch\")\r\n)\r\nval wolverineFriends= listOf(\r\n    Friend(\"Cyclops\",\"Slash\"),\r\n    Friend(\"Jean Gray\",\"Fenix force\",120),\r\n    Friend(\"Rougue\",\"Drain Attack\"),\r\n    Friend(\"Storm\",\"Hurancane\")\r\n)\r\n\r\nval deadpoolSkills= listOf(\r\n    \"Shooter Attack\",\r\n    \"Katana Slash\",\r\n    \"Granate Attack\",\r\n   )\r\n\r\nval wolverineSkills= listOf(\r\n    \"Drill Claw\",\r\n    \"Tornado Claw\",\r\n    \"Berserker Slash\",\r\n  )\r\n\r\n//3.-Definir comportamiento de la aplicación\r\n\r\ninterface Fighting {\r\n   suspend fun asssigmentLife()\r\n   suspend fun simulateFight()\r\n   suspend fun ShowResult()\r\n}\r\n\r\ninterface StateFighting{\r\n    suspend fun criticalAttack(fighter: Fighter,damageFigther:Int): Boolean\r\n    suspend fun infoTurn(warrior1:Warrior,warrior2:Warrior,turn:Int)\r\n    suspend fun friendAttack(fighter: Fighter): Int\r\n    fun getSkill(fighter: Fighter): String\r\n    fun genererateRandomDamage(limit:Int):Int\r\n    fun getEvasion(probability: Double): Boolean\r\n}\r\n\r\n//4.- Implementar comportamiento\r\n\r\n\r\nclass FigthingState:StateFighting{\r\n\r\n    override suspend fun criticalAttack(fighter: Fighter, damageFigther: Int): Boolean=when(fighter) {\r\n        Fighter.DEADPOOL -> if (damageFigther == 100) true else false\r\n        else -> if (damageFigther == 120) true else false\r\n    }\r\n\r\n    override suspend fun infoTurn(warrior1: Warrior, warrior2: Warrior, turn: Int) {\r\n        val info=\"\"\"\r\n        :::::::::::Turn: $turn:::::::::::::\r\n        ${warrior1.name} Life: ${if(warrior1.life<0) 0 else warrior1.life}\r\n        ${warrior2.name} Life: ${if(warrior2.life<0) 0 else warrior2.life}\r\n    \"\"\".trimIndent()\r\n\r\n      println(info)\r\n\r\n    }\r\n\r\n    override fun getSkill(fighter: Fighter): String = when (fighter) {\r\n        Fighter.DEADPOOL -> (0..<deadpoolSkills.size).random().let { deadpoolSkills[it] }\r\n        Fighter.WOLVERINE -> (0..<wolverineSkills.size).random().let { wolverineSkills[it] }\r\n    }\r\n\r\n    override fun getEvasion(probability: Double): Boolean = (0..5).random() <= probability\r\n\r\n\r\n    override  suspend fun friendAttack(fighter: Fighter): Int= coroutineScope {\r\n      val damage= async {\r\n          if (fighter == Fighter.DEADPOOL) {\r\n              val friend = (0..<deadpoolFriens.size).random().let { deadpoolFriens[it] }\r\n              if (friend.skill == \"Lucky Evasion\") println(\"Deadpool use Lucky Evasion thanks to ${friend.name} an evade damage\")\r\n              else println(\"Deadpool call friend ${friend.name} and use ${friend.skill}  cause damage ${friend.damage}\")\r\n              friend.damage\r\n          }\r\n          if (fighter == Fighter.WOLVERINE) {\r\n               (0..<wolverineFriends.size).random().let { wolverineFriends[it] }.let {\r\n                  println(\"Wolverine call friend ${it.name} and use ${it.skill}  cause damage ${it.damage}\")\r\n                  it.damage\r\n              }\r\n          }\r\n          0//encaso de no entrar a ninguna condicion\r\n      }.await()\r\n        return@coroutineScope damage\r\n    }\r\n\r\n    override fun genererateRandomDamage(limit:Int):Int=(10..limit).random()\r\n\r\n}\r\n\r\n\r\n\r\ncontext(StateFighting)\r\nclass FightMarvel:Fighting{\r\n    private val deadPool=Warrior()\r\n    private val wolverine=Warrior(\"Wolverine\")\r\n\r\n    override suspend fun asssigmentLife():Unit= coroutineScope {\r\n      launch {\r\n          println(\"Enter deadpool life: \")\r\n          val lifeD = readLine()!!.toInt()\r\n          println(\"Enter wolverine life: \")\r\n          val lifeW = readLine()!!.toInt()\r\n          deadPool.life = lifeD\r\n          wolverine.life = lifeW\r\n      }\r\n    }\r\n\r\n    override suspend fun simulateFight(): Unit = coroutineScope {\r\n        var turn = 1\r\n        while (deadPool.life >= 0 && wolverine.life >= 0) {\r\n            val skillDeadpool = getSkill(Fighter.DEADPOOL)\r\n            val skillWolverine = getSkill(Fighter.WOLVERINE)\r\n            var damageD = 0\r\n            var damageW = 0\r\n\r\n            var criticalD = criticalAttack(Fighter.DEADPOOL, damageD)\r\n            var criticalW = criticalAttack(Fighter.WOLVERINE, damageW)\r\n\r\n            if (getEvasion(0.25)) {\r\n                println(\"Deadpool evades attack\")\r\n                continue\r\n            }\r\n            if (getEvasion(0.20)) {\r\n                println(\"Wolverine evades attack\")\r\n                continue\r\n            }\r\n\r\n            attackCritical(criticals = Pair(criticalD, criticalW), skills = Pair(skillDeadpool, skillWolverine))\r\n\r\n\r\n            val friendAttack = (0..5).random()\r\n            if (friendAttack == 0) damageD = friendAttack(Fighter.DEADPOOL)\r\n            if (friendAttack == 1) damageW = friendAttack(Fighter.WOLVERINE)\r\n\r\n            if (damageD > 0) {\r\n                damageW = genererateRandomDamage(120)\r\n                deadPool.life -= damageW\r\n                wolverine.life -= damageD\r\n                println(\"Wolverine use $skillWolverine and cause damage $damageW\")\r\n                continue\r\n            }\r\n\r\n            if (damageW > 0) {\r\n                damageD = genererateRandomDamage(100)\r\n                deadPool.life -= damageW\r\n                wolverine.life -= damageD\r\n                println(\"Deadpool use $skillDeadpool and cause damage $damageD\")\r\n                continue\r\n            }\r\n\r\n            if (criticalW.not() && criticalD.not()) {\r\n                damageD = genererateRandomDamage(100)\r\n                damageW = genererateRandomDamage(120)\r\n                deadPool.life -= damageW\r\n                wolverine.life -= damageD\r\n                println(\"Deadpool use $skillDeadpool and cause damage $damageD\")\r\n                println(\"Wolverine use $skillWolverine and cause damage $damageW\")\r\n            }\r\n\r\n            infoTurn(deadPool, wolverine, turn)\r\n            delay(Duration.ofSeconds(1).toMillis())\r\n            turn++\r\n\r\n        }\r\n    }\r\n\r\n    override suspend fun ShowResult() {\r\n        if (deadPool.life <= 0) println(\"Wolverine win\")\r\n        if (wolverine.life <= 0) println(\"Deadpool win\")\r\n    }\r\n\r\n    private fun attackCritical(criticals:Pair<Boolean,Boolean>,skills:Pair<String,String>){\r\n        if (criticals.first){\r\n            println(\"Wolverine receives critical attack need regenerate in this turn\")\r\n            val damageD =genererateRandomDamage(100)\r\n            wolverine.life -= damageD\r\n            println(\"Deadpool use ${skills.first} and cause damage $damageD\")\r\n        }\r\n\r\n        if (criticals.second){\r\n            println(\"Deadpool receives critical attack need regenerate in this turn\")\r\n            val damageW =genererateRandomDamage(120)\r\n            deadPool.life -= damageW\r\n            println(\"Wolverine use ${skills.second} and cause damage $damageW\")\r\n        }\r\n    }\r\n }\r\n\r\n\r\n\r\nfun main()= runBlocking {\r\n  with(FigthingState()) {\r\n      val fight = FightMarvel()\r\n      fight.asssigmentLife()\r\n      fight.simulateFight()\r\n      fight.ShowResult()\r\n  }\r\n}\r\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/kotlin/eulogioep.kt",
    "content": "import kotlin.random.Random\nimport kotlinx.coroutines.*\n\n// Clase para representar a un personaje\ndata class Character(\n    val name: String,\n    var health: Int,\n    val minDamage: Int,\n    val maxDamage: Int,\n    val evasionChance: Double,\n    var canAttack: Boolean = true\n)\n\n// Función principal\nsuspend fun main() = coroutineScope {\n    // Solicitar la vida inicial de los personajes\n    println(\"Ingrese la vida inicial de Deadpool:\")\n    val deadpoolHealth = readLine()?.toIntOrNull() ?: 1000\n    println(\"Ingrese la vida inicial de Wolverine:\")\n    val wolverineHealth = readLine()?.toIntOrNull() ?: 1000\n\n    // Crear los personajes\n    val deadpool = Character(\"Deadpool\", deadpoolHealth, 10, 100, 0.25)\n    val wolverine = Character(\"Wolverine\", wolverineHealth, 10, 120, 0.20)\n\n    var turn = 1\n\n    // Bucle principal de la batalla\n    while (deadpool.health > 0 && wolverine.health > 0) {\n        println(\"\\nTurno $turn\")\n        \n        // Simular el ataque de Deadpool\n        if (deadpool.canAttack) {\n            attack(deadpool, wolverine)\n        } else {\n            println(\"${deadpool.name} se está regenerando y no puede atacar este turno.\")\n            deadpool.canAttack = true\n        }\n\n        // Verificar si Wolverine ha sido derrotado\n        if (wolverine.health <= 0) break\n\n        // Simular el ataque de Wolverine\n        if (wolverine.canAttack) {\n            attack(wolverine, deadpool)\n        } else {\n            println(\"${wolverine.name} se está regenerando y no puede atacar este turno.\")\n            wolverine.canAttack = true\n        }\n\n        // Mostrar la vida restante de ambos personajes\n        println(\"Vida de ${deadpool.name}: ${deadpool.health}\")\n        println(\"Vida de ${wolverine.name}: ${wolverine.health}\")\n\n        turn++\n        delay(1000) // Pausa de 1 segundo entre turnos\n    }\n\n    // Mostrar el resultado final\n    val winner = if (deadpool.health > 0) deadpool.name else wolverine.name\n    println(\"\\n¡$winner ha ganado la batalla!\")\n}\n\n// Función para simular un ataque\nfun attack(attacker: Character, defender: Character) {\n    // Determinar si el defensor evade el ataque\n    if (Random.nextDouble() < defender.evasionChance) {\n        println(\"${defender.name} ha evadido el ataque de ${attacker.name}!\")\n        return\n    }\n\n    // Calcular el daño\n    val damage = Random.nextInt(attacker.minDamage, attacker.maxDamage + 1)\n    \n    // Aplicar el daño\n    defender.health -= damage\n    println(\"${attacker.name} ha causado $damage de daño a ${defender.name}!\")\n\n    // Verificar si el daño es máximo\n    if (damage == attacker.maxDamage) {\n        println(\"¡Golpe crítico! ${defender.name} no podrá atacar en el próximo turno.\")\n        defender.canAttack = false\n    }\n}"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/ocaml/luishendrix92.ml",
    "content": "open Printf\nopen Moure;;\n\nRandom.self_init ()\n\nclass fighter name' attack' evasion' =\n  object (self)\n    val mutable recharging = false\n    val mutable hp = 1000\n    val name : string = name'\n\n    val attack : int * int =\n      let min_attack, max_attack = attack' in\n      let min_attack, max_attack =\n        min min_attack max_attack, max min_attack max_attack\n      in\n      max 0 min_attack, min 9999 max_attack\n\n    val evasion : int = Math.clamp ~a:0 ~b:100 evasion'\n    method set_recharging recharging' = recharging <- recharging'\n    method is_alive = hp > 0\n    method get_name = name\n    method set_hp hp' = hp <- Math.clamp ~a:0 ~b:9999 hp'\n    method get_hp = hp\n\n    method show =\n      printf \"%s | HP: %d\" name hp;\n      if recharging then printf \" | Recharging!\";\n      print_newline ()\n\n    method fight (enemy : fighter) =\n      if recharging\n      then begin\n        self#set_recharging false;\n        printf \"%s is recharging...\\n\" name\n      end\n      else if Random.int 100 < 100 - evasion\n      then begin\n        let min_attack, max_attack = attack in\n        let turn_attack = Random.int_in_range ~min:min_attack ~max:max_attack in\n        enemy#set_hp (enemy#get_hp - turn_attack);\n        printf \"%s dealt %d damage to %s...\" name turn_attack enemy#get_name;\n        if turn_attack = max_attack\n        then begin\n          enemy#set_recharging true;\n          print_string \" CRITICAL HIT!!\"\n        end;\n        print_newline ()\n      end\n      else printf \"%s missed the attack!\\n\" name\n  end\n\nmodule Battle = struct\n  let wolverine = new fighter \"Wolverine\" (10, 120) 20\n  let deadpool = new fighter \"Deadpool\" (10, 100) 25\n  let print_divider () = print_endline \"---------------------------------\"\n\n  let show_winner () =\n    let winner =\n      if wolverine#get_hp <= 0 then deadpool#get_name else wolverine#get_name\n    in\n    printf \"Battle is over. %s is the winner!\\n\" winner;\n    print_endline \"Final stats:\";\n    deadpool#show;\n    wolverine#show\n  ;;\n\n  let start () =\n    let rec loop turn =\n      Unix.sleep 1;\n      printf \"Turn #%d:\\n\" turn;\n      deadpool#show;\n      wolverine#show;\n      if turn mod 2 = 0\n      then wolverine#fight deadpool\n      else deadpool#fight wolverine;\n      print_divider ();\n      if wolverine#is_alive && deadpool#is_alive\n      then loop (turn + 1)\n      else show_winner ()\n    in\n    print_endline \"Wolverine vs Deadpool! Who will win?\";\n    print_divider ();\n    loop 1\n  ;;\nend\n;;\n\nBattle.start ()\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/php/miguelex.php",
    "content": "<?php\n\nfunction simulateBattle($initialLifeDeadpool, $initialLifeWolverine) {\n    $lifeDeadpool = $initialLifeDeadpool;\n    $lifeWolverine = $initialLifeWolverine;\n    \n    $turn = 1;\n    $skipTurnDeadpool = false;\n    $skipTurnWolverine = false;\n\n    echo \"\\n---------------\\n\";\n    while ($lifeDeadpool > 0 && $lifeWolverine > 0) {\n        echo \"Turno: $turn\\n\";\n        \n        if (!$skipTurnDeadpool) {\n            \n            if (rand(1, 100) > 25) { \n                $damageDeadpool = rand(10, 100);\n                $lifeWolverine -= $damageDeadpool;\n                echo \"Deadpool ataca y causa $damageDeadpool de daño a Wolverine.\\n\";\n                if ($damageDeadpool == 100) {\n                    echo \"¡Deadpool causa daño máximo! Wolverine pierde su siguiente turno.\\n\";\n                    $skipTurnWolverine = true;\n                } else {\n                    $skipTurnWolverine = false;\n                }\n            } else {\n                echo \"Deadpool intenta atacar, pero Wolverine esquiva el ataque.\\n\";\n            }\n        } else {\n            echo \"Deadpool pierde su turno para regenerarse.\\n\";\n            $skipTurnDeadpool = false;\n        }\n\n        if ($lifeWolverine <= 0) {\n            echo \"Wolverine ha caído. ¡Deadpool gana!\\n\";\n            break;\n        }\n\n        if (!$skipTurnWolverine) {\n            \n            if (rand(1, 100) > 20) { \n                $damageWolverine = rand(10, 120);\n                $lifeDeadpool -= $damageWolverine;\n                echo \"Wolverine ataca y causa $damageWolverine de daño a Deadpool.\\n\";\n                if ($damageWolverine == 120) {\n                    echo \"¡Wolverine causa daño máximo! Deadpool pierde su siguiente turno.\\n\";\n                    $skipTurnDeadpool = true;\n                } else {\n                    $skipTurnDeadpool = false;\n                }\n            } else {\n                echo \"Wolverine intenta atacar, pero Deadpool esquiva el ataque.\\n\";\n            }\n        } else {\n            echo \"Wolverine pierde su turno para regenerarse.\\n\";\n            $skipTurnWolverine = false;\n        }\n\n        if ($lifeDeadpool <= 0) {\n            echo \"Deadpool ha caído. ¡Wolverine gana!\\n\";\n            break;\n        }\n\n        echo \"Vida de Deadpool: $lifeDeadpool\\n\";\n        echo \"Vida de Wolverine: $lifeWolverine\\n\";\n        echo \"---------------\\n\";\n        $turn++;\n        sleep(1); \n    }\n\n    echo \"\\nResultado final:\\n\";\n    echo \"Vida de Deadpool: $lifeDeadpool\\n\";\n    echo \"Vida de Wolverine: $lifeWolverine\\n\";\n}\n\necho \"\\n¡Bienvenido a la batalla entre Deadpool y Wolverine!\\n\";\n\n$initialLifeDeadpool = (int)readline(\"Introduce la vida inicial de Deadpool: \");\n$initialLifeWolverine = (int)readline(\"Introduce la vida inicial de Wolverine: \");\n\nsimulateBattle($initialLifeDeadpool, $initialLifeWolverine);\n\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/python/Aldroide.py",
    "content": "import time\nimport random\n\n\nclass Character:\n    def __init__(self, name, max_damage, evasion):\n        self.name = name\n        self.max_damage = max_damage\n        self.evasion = evasion\n        self.healt = 0\n\n    def set_healt(self, healt):\n        self.healt = healt\n\n    def attack(self):\n        return random.randint(0, self.max_damage)\n\n    def evade(self):\n        return random.random() < self.evasion\n\n\ndef simulate_battle(deadpool_healt, wolverine_healt):\n    deadpool = Character(\"Deadpool\", 100, 0.25)\n    wolverine = Character(\"Wolverine\", 120, 0.20)\n\n    deadpool.set_healt(deadpool_healt)\n    wolverine.set_healt(wolverine_healt)\n\n    turn = 1\n    skip_next = {\"Deadpool\": False, \"Wolverine\": False}\n    while deadpool.healt > 0 and wolverine_healt > 0:\n        print(f\"Turno {turn}\")\n        if not skip_next[\"Deadpool\"]:\n            if not wolverine.evade():\n                damage = deadpool.attack()\n                if damage == deadpool.max_damage:\n                    skip_next[\"Wolverine\"] = True\n                wolverine.healt -= damage\n                print(f\"Deadpool ataca y causa {damage} de daño a Wolverine.\")\n            else:\n                print(\"Wolverine evade el ataque de Deadpool\")\n        else:\n            print(\"Deadpool se recupera y no puede atacar este turno\")\n            skip_next[\"Deadpool\"] = False\n\n        if wolverine.healt <= 0:\n            print(\"Wolverine ha sido derrotado, Deadpool gana!\")\n            break\n\n        if not skip_next[\"Wolverine\"]:\n            if not deadpool.evade():\n                damage = wolverine.attack()\n                if damage == wolverine.max_damage:\n                    skip_next[\"Deadpool\"] = True\n                deadpool.healt -= damage\n                print(f\"Wolverine ataca y causa {damage} de daño a Deadpool.\")\n            else:\n                print(\"Deadpool evade el ataque de Wolverine.\")\n        else:\n            print(\"Wolverine se recupera y no puede atacar este turno\")\n            skip_next[\"Wolverine\"] = False\n\n        if deadpool.healt <= 0:\n            print(\"Deadpool ha sido derrotado, Wolverine gana!\")\n\n        print(f\"Vida de Deadpool: {deadpool.healt}\")\n        print(f\"Vida de Wolverine: {wolverine.healt}\")\n        print()\n        turn += 1\n        time.sleep(1)\n\n    if deadpool.healt > 0:\n        print(f\"Deadpool gana la batalla con {deadpool.healt} puntos de vida\")\n    elif wolverine.healt > 0:\n        print(\n            f\"Wolverine gana la batalla con {wolverine.healt} puntos de vida\")\n\n\nsimulate_battle(250, 250)\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/python/CesarCarmona30.py",
    "content": "import random, time\n\ndeadpool_health = int(input(\"Introduce la vida de Deadpool: \"))\nwolverine_health = int(input(\"Introduce la vida de Wolverine: \"))\n\nturn = 0\nregenerate = False\n\nwhile deadpool_health > 0 and wolverine_health > 0:\n\n  turn += 1\n  print(f\"\\nTurno {turn}\")\n\n  if regenerate:\n    print(\"Deadpool se está regenerando y no ataca.\")\n    regenerate = False\n\n  elif random.random() > 0.2:\n    deadpool_damage = random.randint(10, 100)\n    print(f\"Deadpool ataca a Wolverine con {deadpool_damage} de daño.\")\n    if deadpool_damage == 100:\n      regenerate = True\n      print(\n        \"¡Golpe crítico de Deadpool! Wolverine no atacará en el siguiente turno ya que tiene que regenerarse.\"\n      )\n\n    wolverine_health  -= deadpool_damage\n\n    if wolverine_health <= 0:\n      print(f\"La vida de Wolverine ha llegado a cero.\")\n      break\n    else:\n      print(f\"Vida restante de Wolverine: {wolverine_health}\")\n  else:\n    print(\"¡Wolverine esquiva el ataque de Deadpool!\")\n\n  if regenerate:\n    print(\"Wolverine se está regenerando y no ataca.\")\n    regenerate = False\n\n  elif random.random() > 0.25:\n    wolverine_damage = random.randint(10, 120)\n    print(f\"Wolverine ataca a Deadpool con {wolverine_damage} de daño.\")\n    if wolverine_damage == 120:\n      regenerate = True\n      print(\n        \"¡Golpe crítico de Wolverine! Deadpool no atacará en el siguiente turno ya que tiene que regenerarse.\"\n      )\n\n    deadpool_health -= wolverine_damage\n    if deadpool_health <= 0:\n      print(f\"La vida de Deadpool ha llegado a cero.\")\n      break\n    else:\n      print(f\"Vida restante de Deadpool: {deadpool_health}\")\n  else:\n    print(\"¡Deadpool esquiva el ataque de Wolverine!\")\n\n  time.sleep(1)\n\nif deadpool_health > 0:\n  print(f\"Deadpool gana la batalla con {deadpool_health} de vida restante.\")\nelse:\n  print(f\"Wolverine gana la batalla con {wolverine_health} de vida restante.\")"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/python/EmmanuelMMontesinos.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * ¡Deadpool y Wolverine se enfrentan en una batalla épica!\n * Crea un programa que simule la pelea y determine un ganador.\n * El programa simula un combate por turnos, donde cada protagonista posee unos\n * puntos de vida iniciales, un daño de ataque variable y diferentes cualidades\n * de regeneración y evasión de ataques.\n * Requisitos:\n * 1. El usuario debe determinar la vida inicial de cada protagonista.\n * 2. Cada personaje puede impartir un daño aleatorio:\n *    - Deadpool: Entre 10 y 100.\n *    - Wolverine: Entre 10 y 120.\n * 3. Si el daño es el máximo, el personaje que lo recibe no ataca en el\n * siguiente turno, ya que tiene que regenerarse (pero no aumenta vida).\n * 4. Cada personaje puede evitar el ataque contrario:\n *    - Deadpool: 25% de posibilidades.\n *    - Wolverine: 20% de posibilidades.\n * 5. Un personaje pierde si sus puntos de vida llegan a cero o menos.\n * Acciones:\n * 1. Simula una batalla.\n * 2. Muestra el número del turno (pausa de 1 segundo entre turnos).\n * 3. Muestra qué pasa en cada turno.\n * 4. Muestra la vida en cada turno.\n * 5. Muestra el resultado final.\n */\n\"\"\"\nfrom random import randint,choice\nimport time\n\n# Descripciones de los ataques\nDESCRIPTION_DAMAGE_DEADPOOL = [\"Puñetazo en la cara\",\n                            \"Patada en la entrepierna\",\n                            \"Nalgada Cariñosa\",\n                            \"Katanazo en el pecho\",\n                            \"Salto con doble tirabuzon en la rodilla\"\n                            ]\nDESCRIPTION_DAMAGE_WOLVERINE = [\"Cabezazo\",\n                                \"Ataque de garras de Adamantium\",\n                                \"Lanzamiento de Puro a los ojos\",\n                                \"Puñetazo al higado\"]\n\n# Clase para los Deadpoll y Wolverine\nclass SuperHero:\n    def __init__(self,nombre,vida,damage_max,agilidad,descriptions) -> None:\n        self.nombre = nombre\n        self.vida = vida\n        self.damage_max = damage_max\n        self.agilidad = agilidad\n        self.is_shock = False\n        self.descriptions = descriptions\n\n    def ataque(self,enemigo):\n\n        if not self.is_shock:\n            damage_turn = randint(10,self.damage_max+1)\n            turno = f\"Turno de {self.nombre}:\"\n            \n            if not enemigo.esquivar():\n                enemigo.vida -= damage_turn\n                \n                if enemigo.vida < 0:\n                    enemigo.vida = 0\n                turno += f\"{choice(self.descriptions)} y le hace {damage_turn} puntos de daño\\n\"\n\n                if damage_turn == self.damage_max:\n                    enemigo.shock = True\n                    turno += f\"{enemigo.nombre} esta en shock por ataque CRITICO!!!\"\n\n            else:\n                turno += f\"{enemigo.nombre} ha esquivado el ataque\"\n\n            print(turno)\n            print(f\"Vida de {enemigo.nombre}: {enemigo.vida}\")\n\n        else:\n            self.is_shock = False\n            print(f\"{self.nombre} se esta regenerando\")\n        print()\n\n\n    def esquivar(self):\n        if randint(1,101) <= self.agilidad:\n            return True\n        else:\n            return False \n\n# Clase para simular los turnos\nclass Combate:\n    def __init__(self,vida_dead, vida_wolve) -> None:\n        self.deadpool = SuperHero(\"Deadpool\",vida_dead,100,25,DESCRIPTION_DAMAGE_DEADPOOL)\n        self.wolverine = SuperHero(\"Wolverine\", vida_wolve,120,20,DESCRIPTION_DAMAGE_WOLVERINE)\n        self.n_turno = 1\n\n\n    def combate(self):\n        print(f\"Inicio del Turno nº {self.n_turno}\")\n        self.deadpool.ataque(self.wolverine)\n        if self.wolverine.vida > 0:\n            self.wolverine.ataque(self.deadpool)\n        print(f\"Fin del Turno nº {self.n_turno}\\n\")\n        time.sleep(1)\n        if self.deadpool.vida <= 0 or self.wolverine.vida <= 0:\n            if self.deadpool.vida == 0:\n                self.ganador = self.wolverine.nombre.title()\n            else:\n                self.ganador = self.deadpool.nombre.title()\n            return False\n        else:\n            self.n_turno += 1\n            return True\n        \n    def bucle(self):\n        check = True\n        while check:\n            check = self.combate()\n        print(\"Combate Terminado:\")\n        print(f\"Vida de Deadpool: {self.deadpool.vida}\")\n        print(f\"Vida de Wolverine: {self.wolverine.vida}\")\n        print(f\"El ganador del Combate Moure en el turno nº {self.n_turno} es: {self.ganador}\")\n\n# Prueba\nvida_dead = int(input(\"Indique la vida de Deadpool: \"))\nvida_wolve = int(input(\"Indique la vida de Wolverine: \"))\n\nsimulacion = Combate(vida_dead,vida_wolve)\nsimulacion.bucle()"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/python/GiovanniPeirone.py",
    "content": "'''\n * EJERCICIO:\n * ¡Deadpool y Wolverine se enfrentan en una batalla épica!\n * Crea un programa que simule la pelea y determine un ganador.\n * El programa simula un combate por turnos, donde cada protagonista posee unos\n * puntos de vida iniciales, un daño de ataque variable y diferentes cualidades\n * de regeneración y evasión de ataques.\n * Requisitos:\n * 1. El usuario debe determinar la vida inicial de cada protagonista.\n * 2. Cada personaje puede impartir un daño aleatorio:\n *    - Deadpool: Entre 10 y 100.\n *    - Wolverine: Entre 10 y 120.\n * 3. Si el daño es el máximo, el personaje que lo recibe no ataca en el\n * siguiente turno, ya que tiene que regenerarse (pero no aumenta vida).\n * 4. Cada personaje puede evitar el ataque contrario:\n *    - Deadpool: 25% de posibilidades.\n *    - Wolverine: 20% de posibilidades.\n * 5. Un personaje pierde si sus puntos de vida llegan a cero o menos.\n * Acciones:\n * 1. Simula una batalla.\n * 2. Muestra el número del turno (pausa de 1 segundo entre turnos).\n * 3. Muestra qué pasa en cada turno.\n * 4. Muestra la vida en cada turno.\n * 5. Muestra el resultado final.\n'''\nimport random\nimport os\n\n\nLimpiarPantalla = \"cls\" # si usas Linux o mac coloca \"clear\"\n\nclass Personaje:\n    def __init__(self, Vida, Ataque, Defensa,Nombre , AtaqueMax):\n        self.vida = Vida\n        self.ataque = Ataque\n        self.defensa = Defensa\n        self.nombre = Nombre\n        self.ataquemax = AtaqueMax\n    \n    def Atacar(self, Enemigo ):\n        self.vida -= self.ataque\n        print(f\"{self.nombre} a recibido {self.ataque} de daño\" )\n\nclass main():\n\n    Turno = 0\n\n    def MAIN(self):\n\n        vidaDeadpool = int(input(\"Vida de Deadpool:\"))\n        vidaWolverine = int(input(\"Vida de Wolverine:\"))\n        Deadpool = Personaje(vidaDeadpool, random.randrange(10, 100), random.randrange(25, 100) ,\"Deadpool\",100)\n        Wolverine = Personaje(vidaWolverine, random.randrange(10, 120), random.randrange(20, 100) ,\"Wolverine\",120)\n\n        while True:\n            Deadpool.ataque = random.randrange(10,100)\n            Wolverine.ataque = random.randrange(10,120)\n            Deadpool.defensa = random.randrange(0,100)\n            Wolverine.defensa = random.randrange(0,100)\n            print(f\"---------------------- Turno {main.Turno} ----------------------\")\n            print(f'''\n            {Deadpool.nombre}       | {Wolverine.nombre}\n            Vida = {Deadpool.vida}       | Vida = {Wolverine.vida}\n            ''')\n            if self.Turno % 2 == 0: \n                #Ataca Wolverine\n                if Deadpool.defensa < 20:\n                    print(\"Deadpool se a defendido\")\n                if Wolverine.ataque == 120:\n                    Deadpool.Atacar(Wolverine)\n                    print(\"Wolverine a echo el maximo de daño, Deadpool debe utilizar su turno para recuperarse\")\n                    main.Turno += 1\n                else:\n                    Wolverine.Atacar(Deadpool)\n\n            if self.Turno % 2 != 0:\n                #Ataca Deadpool\n                if Wolverine.defensa < 25:\n                    print(\"Wolverine se a defendido\")\n                if Deadpool.ataque == 100:\n                    Deadpool.Atacar(Wolverine)\n                    print(\"Deadpool a echo el maximo de daño Wolverine debe utilizar el turno para recuperarse\")\n                    main.Turno +1\n                else:\n                    Deadpool.Atacar(Wolverine)\n            \n            if Deadpool.vida <= 0:\n                print(f\"Deadpool a muerto vida = {Deadpool.vida}\")\n                break\n            if Wolverine.vida <= 0:\n                print(f\"Wolverine a muerto vida = {Wolverine.vida}\")\n                break\n            os.system(\"pause\")\n            main.Turno += 1\n            os.system(LimpiarPantalla)\naplicacion = main()\naplicacion.MAIN()\nexit()"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/python/Gordo-Master.py",
    "content": "# 32 - Batalla de Deadpool y Wolverine\nimport random\nimport time\n\n\nclass Fighter():\n\n    def __init__(self, name: str, health: int, damage: tuple, regeneration: bool, evasion: int):\n        self.name = name\n        self.health = health\n        self.damage = damage\n        self.regeneration = regeneration\n        self.evasion = evasion\n\n    def take_damage(self, damage, critic):\n        self.health -= damage\n        self.regeneration = critic\n\nwolverine_hp = int(input(\"Ingrese la vida de Wolverine: \"))\ndeadpool_hp = int(input(\"Ingrese la vida de Deadpool: \"))\n\nwolverine =Fighter(\"Wolverine\", wolverine_hp, (10, 120),False,20)\ndeadpool = Fighter(\"Deadpool\", deadpool_hp, (10, 100),False,25)\n\n\ndef damage_dealt(attacker: Fighter, defender: Fighter) -> tuple :\n\n    if not random.random() < (defender.evasion/100):\n        damage = random.randint(attacker.damage[0],attacker.damage[1])\n        if damage == attacker.damage[1]:\n            return damage, True\n        return damage, False\n    return 0, False\n\ndef turn_to_attack(attacker: Fighter, defender: Fighter):\n    \n    if not attacker.regeneration:\n\n        attacker_dam, attacker_crit = damage_dealt(attacker, defender)\n\n        if attacker_crit == False:\n            if attacker_dam == 0:\n                print(f\"{attacker.name} ataca a {defender.name}, pero este logra esquivarlo!\")\n            else:\n                print(f\"{attacker.name} ataca a {defender.name}, y le baja {attacker_dam} HP\")\n        else:\n            print(f\"{attacker.name} hace un golpe critico a {defender.name} y le baja {attacker_dam} HP, dejandolo incapacitado para el siguiente turno!\")\n        \n        return attacker_dam, attacker_crit\n    \n    else:\n        print(f\"{attacker.name} se esta regenerando y no puede atacar!\")\n        attacker.regeneration = False\n        return 0, False    \n    \n\ndef fight():\n\n    round = 0\n\n    print(\"Comienza la pelea!!!\")\n    print(f\"Wolverine HP: {wolverine.health}{\" \"*5}Deadpoll HP: {deadpool.health}\")\n    while True:\n        round += 1\n        print(f\"\\nRonda {round}:\")\n        wolv_dam, wolv_crit = turn_to_attack(wolverine, deadpool)\n        dead_dam, dead_crit = turn_to_attack(deadpool, wolverine)\n        deadpool.take_damage(wolv_dam, wolv_crit)\n        wolverine.take_damage(dead_dam, dead_crit)\n\n\n        print(f\"Wolverine HP: {wolverine.health}{\" \"*5}Deadpoll HP: {deadpool.health}\")\n        if wolverine.health <= 0 or deadpool.health <= 0:\n            if wolverine.health > 0 and deadpool.health <= 0:\n                print(\"Wolverine gana\")\n            elif deadpool.health > 0 and wolverine.health <= 0:\n                print(\"Deadpool gana\")\n            else:\n                print(\"Ambos han perdido xd!\")\n            break\n        time.sleep(2)\n\nfight()\n\n\n    "
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/python/JesusWay69.py",
    "content": "import os, platform, random, time\n\nif (platform.platform().startswith(\"macOS\") or platform.platform().startswith(\"Linux\")):\n    os.system('clear')\nelse:\n    os.system('cls')\n\n    \"\"\"* EJERCICIO:\n * ¡Deadpool y Wolverine se enfrentan en una batalla épica!\n * Crea un programa que simule la pelea y determine un ganador.\n * El programa simula un combate por turnos, donde cada protagonista posee unos\n * puntos de vida iniciales, un daño de ataque variable y diferentes cualidades\n * de regeneración y evasión de ataques.\n * Requisitos:\n * 1. El usuario debe determinar la vida inicial de cada protagonista.\n * 2. Cada personaje puede impartir un daño aleatorio:\n *    - Deadpool: Entre 10 y 100.\n *    - Wolverine: Entre 10 y 120.\n * 3. Si el daño es el máximo, el personaje que lo recibe no ataca en el\n * siguiente turno, ya que tiene que regenerarse (pero no aumenta vida).\n * 4. Cada personaje puede evitar el ataque contrario:\n *    - Deadpool: 25% de posibilidades.\n *    - Wolverine: 20% de posibilidades.\n * 5. Un personaje pierde si sus puntos de vida llegan a cero o menos.\n * Acciones:\n * 1. Simula una batalla.\n * 2. Muestra el número del turno (pausa de 1 segundo entre turnos).\n * 3. Muestra qué pasa en cada turno.\n * 4. Muestra la vida en cada turno.\n * 5. Muestra el resultado final.\"\"\"\n    \nclass Deadpool:\n    name = \"Deadpool\"\n    max_damage = 100\n    shield = 25\n\nclass Wolverine:\n    name = \"Wolverine\"\n    max_damage = 120\n    shield = 20\n\ndef battle(local_name, foreign_name, shield, max_damage, local_points, enemy_points, regenerate_state ):\n    if regenerate_state:\n        print(f\" {local_name} pierde su turno por haber recibido daño máximo y tener que regenerarse \")\n        regenerate_state = False\n        \n    elif random.random() > shield/100:\n        damage = random.randint(10, max_damage)\n        print (f\" El ataque de {local_name} le ha restado {damage} puntos de vida a {foreign_name}\")\n        if damage == 100:\n            print(f\" ¡¡Ataque máximo de {local_name}!!\")\n            regenerate_state = True\n        enemy_points -= damage\n        if enemy_points <= 0:\n            print(f\" {foreign_name} se ha quedado sin puntos de vida\")\n            print(f\"\\n----- {local_name} gana el torneo con {local_points} puntos de vida restantes -----\")\n        else:\n            print(f\" A {foreign_name} le quedan {enemy_points} puntos\")\n    else:\n        print(f\" {foreign_name} repele el ataque de {local_name} y no pierde puntos, conserva sus {enemy_points} puntos\")\n    return  tuple((enemy_points, regenerate_state))\n\ndeadpool = Deadpool()\nwolverine = Wolverine()\n\nd_points = int(input(\"Introduzca los puntos de inicio de Deadpool: \"))\nw_points = int(input(\"Introduzca los puntos de inicio de Wolverine: \"))\nregenerate_state = False\nround = 1\nwhile d_points>0 and w_points>0:\n    print(\"Ronda: \",round)\n    ####################Ataca Deadpool####################\n    w_points, regenerate_state = battle(deadpool.name, wolverine.name, wolverine.shield, deadpool.max_damage, d_points, w_points, regenerate_state)\n    print()\n    if w_points <=0:\n        break\n    ####################Ataca Wolverine####################\n    d_points, regenerate_state = battle(wolverine.name, deadpool.name, deadpool.shield, wolverine.max_damage, w_points, d_points, regenerate_state)\n    round+=1\n    print()\n    time.sleep(1)\n    \n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/python/Nicojsuarez2.py",
    "content": "# #32 BATALLA DEADPOOL Y WOLVERINE\n> #### Dificultad: Media | Publicación: 05/08/24 | Corrección: 12/08/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * ¡Deadpool y Wolverine se enfrentan en una batalla épica!\n * Crea un programa que simule la pelea y determine un ganador.\n * El programa simula un combate por turnos, donde cada protagonista posee unos\n * puntos de vida iniciales, un daño de ataque variable y diferentes cualidades\n * de regeneración y evasión de ataques.\n * Requisitos:\n * 1. El usuario debe determinar la vida inicial de cada protagonista.\n * 2. Cada personaje puede impartir un daño aleatorio:\n *    - Deadpool: Entre 10 y 100.\n *    - Wolverine: Entre 10 y 120.\n * 3. Si el daño es el máximo, el personaje que lo recibe no ataca en el\n * siguiente turno, ya que tiene que regenerarse (pero no aumenta vida).\n * 4. Cada personaje puede evitar el ataque contrario:\n *    - Deadpool: 25% de posibilidades.\n *    - Wolverine: 20% de posibilidades.\n * 5. Un personaje pierde si sus puntos de vida llegan a cero o menos.\n * Acciones:\n * 1. Simula una batalla.\n * 2. Muestra el número del turno (pausa de 1 segundo entre turnos).\n * 3. Muestra qué pasa en cada turno.\n * 4. Muestra la vida en cada turno.\n * 5. Muestra el resultado final.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/python/SooHav.py",
    "content": "# 32 BATALLA DEADPOOL Y WOLVERINE\n\nimport time\nimport random\nimport pandas as pd\n\n\nclass Batalla:\n    \"\"\"\n    Clase que registra ataques.\n    \"\"\"\n\n    def __init__(self):\n        self.registro = {}\n\n    def registro_ataque(self, personaje, vida, evita_ataque, numero_ataque=0, dano_max=1, dano_var=0):\n        \"\"\"\n        Función que registra un ataque.\n        \"\"\"\n        nuevo_registro = {\n            \"Puntos de vida\": vida,\n            \"Evasión de ataque\": evita_ataque,\n            \"Numero de ataque\": numero_ataque,\n            \"Daño máximo\": dano_max,\n            \"Daño\": dano_var\n        }\n        self.registro[personaje] = nuevo_registro\n        print(f\"Resultado del ataque de '{personaje}' registrado con éxito.\\n\")\n\n    def calcular_dano(self, atacante):\n        \"\"\"\n        Función que calcula el daño.\n        \"\"\"\n        dano_var = round(random.uniform(0.4, atacante[\"Daño máximo\"]), 2)\n        return dano_var\n\n\nsimulador_batalla = Batalla()\n\n# Función para mostrar el menú\n\n\ndef menu():\n    while True:\n        print(\"Menú:\")\n        print(\"1. Asignar puntos de vida\")\n        print(\"2. Simular batalla\")\n        print(\"3. Resultado final\")\n        print(\"4. Salir\")\n        opcion = input(\"Ingrese una opción: \")\n        try:\n            return int(opcion)\n        except ValueError:\n            print(\"Opción inválida. Por favor, ingrese un número entero.\")\n\n\nwhile True:\n    opcion = menu()\n\n    if opcion == 1:\n        vida_deadpool = int(input(\"Ingrese puntos de vida de DEADPOOL: \"))\n        evita_ataque_deadpool = 0.25\n        numero_ataque = 0\n        dano_max_d = 0.8\n        simulador_batalla.registro_ataque(\n            \"Deadpool\", vida_deadpool, evita_ataque_deadpool, numero_ataque, dano_max_d)\n\n        vida_wolverine = int(input(\"Ingrese puntos de vida de WOLVERINE: \"))\n        evita_ataque_wolverine = 0.2\n        dano_max_w = 0.7\n        simulador_batalla.registro_ataque(\n            \"Wolverine\", vida_wolverine, evita_ataque_wolverine, numero_ataque, dano_max_w)\n\n    elif opcion == 2:\n        while simulador_batalla.registro[\"Deadpool\"][\"Puntos de vida\"] > 0 and simulador_batalla.registro[\"Wolverine\"][\"Puntos de vida\"] > 0:\n            for personaje in list(simulador_batalla.registro.keys()):\n                atacante = simulador_batalla.registro[personaje]\n                defensor = simulador_batalla.registro[\"Wolverine\" if personaje ==\n                                                      \"Deadpool\" else \"Deadpool\"]\n\n                if random.random() > defensor['Evasión de ataque']:\n                    dano = simulador_batalla.calcular_dano(atacante)\n\n                    if dano < atacante[\"Daño máximo\"]:\n                        dano_realizado = round(\n                            dano * defensor[\"Puntos de vida\"])\n                        defensor[\"Puntos de vida\"] -= dano_realizado\n                        atacante[\"Numero de ataque\"] += 1\n                        print(f\"Turno {atacante['Numero de ataque']}: {\n                              personaje} ataca y causa {dano_realizado} de daño.\")\n                        print(f\"A {list(simulador_batalla.registro.keys())[1 if personaje == 'Deadpool' else 0]} le quedan {\n                              round(defensor['Puntos de vida'], 2)} puntos de vida.\")\n\n                        simulador_batalla.registro_ataque(list(simulador_batalla.registro.keys())[\n                                                          1 if personaje == 'Deadpool' else 0], defensor[\"Puntos de vida\"], defensor[\"Evasión de ataque\"], defensor[\"Numero de ataque\"], defensor[\"Daño máximo\"], dano)\n                    else:\n                        atacante[\"Numero de ataque\"] += 1\n                        print(f\"Turno {atacante['Numero de ataque']}: {\n                              personaje} realiza un ataque máximo.\")\n                        print(f\"{list(simulador_batalla.registro.keys())[\n                              1 if personaje == 'Deadpool' else 0]} se regenera.\")\n                        defensor[\"Puntos de vida\"] += random.randint(1, 3)\n                        simulador_batalla.registro_ataque(list(simulador_batalla.registro.keys())[\n                                                          1 if personaje == 'Deadpool' else 0], defensor[\"Puntos de vida\"], defensor[\"Evasión de ataque\"], defensor[\"Numero de ataque\"], defensor[\"Daño máximo\"], dano)\n                else:\n                    atacante[\"Numero de ataque\"] += 1\n                    print(f\"Turno {atacante['Numero de ataque']}.\")\n                    print(f\"{personaje} esquiva el ataque en el turno {\n                          atacante['Numero de ataque']}.\\n\")\n\n                time.sleep(1)\n\n            if simulador_batalla.registro[\"Deadpool\"][\"Puntos de vida\"] <= 0 or simulador_batalla.registro[\"Wolverine\"][\"Puntos de vida\"] <= 0:\n                break\n\n        if simulador_batalla.registro[\"Deadpool\"][\"Puntos de vida\"] <= 0:\n            print(\"¡Wolverine gana!\")\n        else:\n            print(\"¡Deadpool gana!\")\n\n    elif opcion == 3:\n        resultados = simulador_batalla.registro\n        if not resultados:\n            print(\"No hay resultados para mostrar. Primero simula la batalla.\")\n        else:\n            df = pd.DataFrame(resultados).T\n            print(df)\n\n    elif opcion == 4:\n        print(\"¡El juego ha finalizado!\")\n        break\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/python/Trufoplus.py",
    "content": "from random import randint\nimport time\n\n\nclass BattleSystem:\n    def damage(self):\n        return randint(self.damage_range[0], self.damage_range[1])\n    \n    def critical_hit(self, damage):\n        return damage == self.damage_range[1]\n              \n    def evasion_chance(self):\n        return randint(0, 100) < self.evasion\n    \n    def dead(self):\n        return self.health <= 0\n\n    def __str__(self):\n        return (\n            f'Vida {self.name}: {self.health}'\n            )\n   \n    \nclass Deadpool(BattleSystem):\n    def __init__(self, health: int):\n        self.name = 'Deadpool'\n        self.health = health\n        self.damage_range = [10, 100]\n        self.regeneration = 1\n        self.evasion = 25\n        \n\nclass Wolverine(BattleSystem):\n    def __init__(self, health: int):\n        self.name = 'Wolverine'\n        self.health = health\n        self.damage_range = [10, 120]\n        self.regeneration = 1\n        self.evasion = 20\n\n\nclass BattleSimulation:\n    @staticmethod\n    def battle(deadpool: Deadpool, wolverine: Wolverine):\n        turn = 1\n        \n        while True:\n            #Comprueba si deadpool esta vivo   \n            if deadpool.dead():\n                print(\"\\nDeadpool ha sido derrotado. ¡Wolverine gana!\\n\")\n                break\n            \n            print(f'\\nEstamos en el turno {turn}')\n            \n            #Si estamos empezando aun no se han realizado ataques\n            if turn == 1:\n                damage = 0\n            #Ataca Deapool si no le han hecho un daño critico\n            if not wolverine.critical_hit(damage):\n                damage = deadpool.damage()\n                \n                if wolverine.evasion_chance():\n                    print('Wolverine esquiva el ataque!!')\n                else:\n                    wolverine.health -= damage\n                    print(f'+ Deadpool hace {damage} puntos de daño.')                    \n                print(wolverine)\n            \n            #Comprueba si wolverine esta vivo\n            if wolverine.dead():\n                print(\"\\nWolverine ha sido derrotado. ¡Deadpool gana!\\n\")\n                break\n            \n            # Ataca wolverine si no le han hecho un daño critico\n            if not deadpool.critical_hit(damage):\n                \n                damage = wolverine.damage()\n                if deadpool.evasion_chance():\n                    print('Deadpool esquiva el ataque!!')\n                else:\n                    deadpool.health -= damage\n                    print(f'+ Wolverine hace {damage} puntos de daño.')\n                print(deadpool)\n            \n            time.sleep(5)    \n            turn += 1\n            \n        \n        \n        \n        \n\n\n\n\n\n\n\n\n# Pruebas\ndeadpool_char = Deadpool(int(input('Introduce la vida inicial de Deadpool: ')))\nprint(deadpool_char)\nwolverine_char = Wolverine(int(input('Introduce la vida inicial de Wolverine: ')))\nprint(wolverine_char)\n\nBattleSimulation.battle(deadpool_char, wolverine_char)"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/python/adra-dev.py",
    "content": "\"\"\"\nEJERCICIO:\n¡Deadpool y Wolverine se enfrentan en una batalla épica!\nCrea un programa que simule la pelea y determine un ganador.\nEl programa simula un combate por turnos, donde cada protagonista posee unos\npuntos de vida iniciales, un daño de ataque variable y diferentes cualidades\nde regeneración y evasión de ataques.\n\nRequisitos:\n1. El usuario debe determinar la vida inicial de cada protagonista.\n2. Cada personaje puede impartir un daño aleatorio:\n    - Deadpool: Entre 10 y 100.\n    - Wolverine: Entre 10 y 120.\n3. Si el daño es el máximo, el personaje que lo recibe no ataca en el\nsiguiente turno, ya que tiene que regenerarse (pero no aumenta vida).\n4. Cada personaje puede evitar el ataque contrario:\n    - Deadpool: 25% de posibilidades.\n    - Wolverine: 20% de posibilidades.\n5. Un personaje pierde si sus puntos de vida llegan a cero o menos.\n\nAcciones:\n1. Simula una batalla.\n2. Muestra el número del turno (pausa de 1 segundo entre turnos).\n3. Muestra qué pasa en cada turno.\n4. Muestra la vida en cada turno.\n5. Muestra el resultado final.\n\nby adra-dev\n\"\"\"\nimport random\nimport time\n\ndeadpool_health = int(input(\"Introduce la vida de Deadpool: \"))\nwolverine_health = int(input(\"Introduce la vida de Wolverine: \"))\n\nturn = 0\nregenerate = False\n\nwhile deadpool_health > 0 and wolverine_health > 0:\n\n    turn +=1\n    print(f\"\\nTurno {turn}\")\n\n    # Wolverine ataca a Deadpool\n    if regenerate:\n        print(\"Wolverine se esta regenerado y no ataca.\")\n        regenerate = False\n    elif random.random() > 0.25:\n        wolverine_damage = random.randint(10,120)\n        print(f\"Wolverine ataca a Deadpool con {wolverine_damage}.\")\n        if wolverine_damage == 120:\n            regenerate = True\n            print(\"Wolverine critico! Deadpool no atacara en el siguiente turno.\")\n        \n        deadpool_health -= wolverine_damage\n\n        if deadpool_health <= 0:\n            print(f\"La vida de Deadpool ha llegado a 0.\")\n            break\n        else:\n            print(f\"Vida restante de Deadpool: {deadpool_health}\")\n    else: \n        print(\"Deadpool esquiva el ataque de Wolverine!\")\n\n    # Deadpool ataca a Wolverinel\n    if regenerate:\n        print(\"Deadpool se esta regenerado y no ataca.\")\n        regenerate = False\n    elif random.random() > 0.2:\n        deadpool_damage = random.randint(10,100)\n        print(f\"Deadpool ataca a Wolverine con {deadpool_damage}.\")\n        if deadpool_damage == 80:\n            regenerate = True\n            print(\"Deadpool critico! Wolverine no atacara en el siguiente turno.\")\n        \n        wolverine_health -= deadpool_damage\n\n        if wolverine_health <= 0:\n            print(f\"La vida de Wolverine ha llegado a 0.\")\n            break\n        else:\n            print(f\"Vida restante de Wolverine: {wolverine_health}\")\n    else: \n        print(\"Wolverine esquiva el ataque de Deadpool!\")\n\n    time.sleep(1)\n\n\nif deadpool_health > 0:\n    print(\"Deadpool gana la batalla.\")\nelse:\n    print(\"Wolverine gana la batalla.\")"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/python/alanshakir.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * ¡Deadpool y Wolverine se enfrentan en una batalla épica!\n * Crea un programa que simule la pelea y determine un ganador.\n * El programa simula un combate por turnos, donde cada protagonista posee unos\n * puntos de vida iniciales, un daño de ataque variable y diferentes cualidades\n * de regeneración y evasión de ataques.\n * Requisitos:\n * 1. El usuario debe determinar la vida inicial de cada protagonista.\n * 2. Cada personaje puede impartir un daño aleatorio:\n *    - Deadpool: Entre 10 y 100.\n *    - Wolverine: Entre 10 y 120.\n * 3. Si el daño es el máximo, el personaje que lo recibe no ataca en el\n * siguiente turno, ya que tiene que regenerarse (pero no aumenta vida).\n * 4. Cada personaje puede evitar el ataque contrario:\n *    - Deadpool: 25% de posibilidades.\n *    - Wolverine: 20% de posibilidades.\n * 5. Un personaje pierde si sus puntos de vida llegan a cero o menos.\n * Acciones:\n * 1. Simula una batalla.\n * 2. Muestra el número del turno (pausa de 1 segundo entre turnos).\n * 3. Muestra qué pasa en cada turno.\n * 4. Muestra la vida en cada turno.\n * 5. Muestra el resultado final.\n */\n\"\"\"\nimport random, time\n\nclass Simulator():\n\n    deadpool_life = int(input(\"Introduce la vida inicial para deadpool: \"))\n    wolverine_life = int(input(\"Introduce la vida inicial para wolverine: \"))\n\n    \n    wolverine_attack = random.randint(10, 120)\n\n    deadpool_defense = 0.25\n    wolverine_defense = 0.20\n\n    turn = 0\n    deadpool_regenerate = False\n    wolverine_regenerate = False\n\n    while deadpool_life > 0 and wolverine_life > 0:\n        turn += 1\n        print(f\"Turno: {turn}\")\n\n        if deadpool_regenerate:\n            print(\"Deadpool se esta regenerando\")\n            deadpool_regenerate = False\n        elif random.random() > 0.2:\n            deadpool_attack = random.randint(10, 100)\n            print(f\"Deadpool ataca con {deadpool_attack} de daño.\")\n            if deadpool_attack == 100:\n                deadpool_regenerate = True\n                print(\"¡Golpe Critico! Wolverine no ataca en el siguiente turno\")\n            wolverine_life -= deadpool_attack\n            if wolverine_life <= 0:\n                print(\"Wolverine ha sido eliminado.\")\n                break\n            else:\n                print(f\"Vida restante de Wolverine: {wolverine_life}\")\n        else:\n            print(\"Wolverine esquiva el ataque de Deadpool\")\n        \n        if wolverine_regenerate:\n            print(\"Wolverine se esta regerenando\")\n            wolverine_regenerate = False\n        elif random.random() > 0.25:\n            wolverine_attack = random.randint(10, 120)\n            print(f\"Wolverine ataca con {wolverine_attack} de daño.\")\n            if wolverine_attack == 120:\n                wolverine_regenerate = True\n                print(\"¡Golpe Critico! Deadpool no ataca en el siguiente turno\")\n            deadpool_life -= wolverine_attack\n            if deadpool_life <= 0:\n                print(\"Deadpool ha sido eliminado.\")\n                break\n            else:\n                print(f\"Vida restante de Wolverine: {deadpool_life}\")\n        else:\n            print(\"Deadpool esquiva el ataque de Wolverine\")\n    time.sleep(1)\n\n    if deadpool_life > 0:\n        print(\"Deadpool ha ganado\")\n    else:\n        print(\"Wolverine ha ganado\")\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/python/avcenal.py",
    "content": "\"\"\"\n* EJERCICIO:\n * ¡Deadpool y Wolverine se enfrentan en una batalla épica!\n * Crea un programa que simule la pelea y determine un ganador.\n * El programa simula un combate por turnos, donde cada protagonista posee unos\n * puntos de vida iniciales, un daño de ataque variable y diferentes cualidades\n * de regeneración y evasión de ataques.\n * Requisitos:\n * 1. El usuario debe determinar la vida inicial de cada protagonista.\n * 2. Cada personaje puede impartir un daño aleatorio:\n *    - Deadpool: Entre 10 y 100.\n *    - Wolverine: Entre 10 y 120.\n * 3. Si el daño es el máximo, el personaje que lo recibe no ataca en el\n * siguiente turno, ya que tiene que regenerarse (pero no aumenta vida).\n * 4. Cada personaje puede evitar el ataque contrario:\n *    - Deadpool: 25% de posibilidades.\n *    - Wolverine: 20% de posibilidades.\n * 5. Un personaje pierde si sus puntos de vida llegan a cero o menos.\n * Acciones:\n * 1. Simula una batalla.\n * 2. Muestra el número del turno (pausa de 1 segundo entre turnos).\n * 3. Muestra qué pasa en cada turno.\n * 4. Muestra la vida en cada turno.\n * 5. Muestra el resultado final.\n\"\"\"\nfrom abc import ABC,abstractmethod\nfrom random import randint\nfrom time import sleep,time\nimport logging\n\n#Congiguración del nivel del log a mostrar\nlogging.basicConfig(level=logging.DEBUG,\n                    format=\"%(asctime)s -- %(levelname)s: %(message)s\",\n                    datefmt=\"%d/%m/%Y - %H:%M:%S\")\n\n#decorador para mostrar que función se ha ejecutado y cuando\ndef time_decorator(function):\n    def original_function(*args):\n        result = function(*args)\n        logging.debug(f\"Se ha ejecutado la función \\\"{function.__name__}\\\"\")\n        return result\n    return original_function\n\n#CLASES ABSTRACTAS\nclass AbstractCharacter(ABC):\n    @abstractmethod\n    def __init__(self):\n        pass\n\n    @abstractmethod\n    def attack(self):\n        pass\n\n#Clases de los personajes que heredan de la abstracta\nclass DeadPool(AbstractCharacter):\n    def __init__(self,life:int = 0):\n        self.name:str = \"Deadpool\"\n        self.life:int = life\n        self.strength:int = 100\n        self.agility:int = 25\n\n    @time_decorator\n    def attack(self):\n        return randint(10,self.strength) #random entre 10 y 100 para determinar el ataque de Deadpool\n    \nclass Wolverine(AbstractCharacter):\n    def __init__(self,life:int = 0 ):\n        self.name:str = \"Wolverine\"\n        self.life:int = life\n        self.strength:int = 120\n        self.agility:int = 20\n    \n    @time_decorator\n    def attack(self):\n        return randint(10,self.strength) #random entre 10 y 100 para determinar el ataque de Wolverine\n    \n#clase que engloba los métodos necesarios para ejecutar la batalla\nclass Battle():\n\n    def set_life(self,fighter:AbstractCharacter): #para determinar la vida en la batalla de un personaje\n        while True:\n            try:\n                life = int(input (f\"Dime los puntos de vida de {fighter.name} por favor: \"))\n            except:\n                logging.warning(\"El dato introducido no es un número\") #se controla que se introduzca un número válido\n                print(\"Parece que has introducido algo que no es un número...\")\n            else:\n                if life <= 0:\n                    logging.warning(\"El número es cero o menor que cero\")\n                    print(\"Por favor introduce un número positivo mayor que cero...\")\n                else:\n                    fighter.life = life\n                    break\n\n    def __life_to_zero(self,fighter:AbstractCharacter): #Función privada que se encarga de cambiar la vida del personaje a 0 (solo en caso de que su vida baje de 0)\n        fighter.life = 0\n\n    def __hit(self,attacker:AbstractCharacter,defender:AbstractCharacter): #Función privada que ejecuta el golpe del atacante al defensor\n        hit = attacker.attack()                                            # devuelve el entero del golpe para calcular después si es crítico o no\n        print(f\"{attacker.name.upper()} golpea a {defender.name}\")                 # en la función principal\n        dodge_chance = randint(0,100)\n        if dodge_chance <= defender.agility:\n            logging.info(f\"** {defender.name.upper()} ESQUIVA **\")\n            print(f\"{defender.name} esquiva el ataque\")\n            hit = 0 # al esquivar, el gole del atacante ha de ser 0 porque no ha impactado\n        else:\n            print(f\"Y hace {hit} puntos de daño\")\n            defender.life -= hit\n        return hit\n\n    def battle(self,fighter_1:AbstractCharacter,fighter_2:AbstractCharacter,turn:int = 1): #función recursiva que recibe los dos atacantes y el turno (si no se recibe turno, se entiende que es el turno número 1)\n        if fighter_1.life == 0:                             # caso base 1: el combatiente 1 no tiene vida\n            logging.info(f\"Gana el combate {fighter_2.name}\")\n            print(f\"¡¡FIN DE LA PELEA!! El ganador es {fighter_2.name}\\n\".upper())\n        elif fighter_2.life == 0:                           #caso base 2: el combatiente 2 no tiene vida\n            logging.info(f\"Gana el combate {fighter_1.name}\")\n            print(f\"¡¡FIN DE LA PELEA!! El ganador es {fighter_1.name}\\n\".upper())\n        else:                                               #si no es ningún caso base, se simula el turno\n            print(f\"--- TURNO {turn} ---\")\n            hit = self.__hit(fighter_1,fighter_2)\n            if fighter_1.life <0: #con estos dos IF se controla que no aparezca ningún número negativo en el resultado de la vida de cada personaje\n                self.__life_to_zero(fighter=fighter_1)\n            if fighter_2.life <0:\n                self.__life_to_zero(fighter=fighter_2)\n            print(f\"-- Vida restante de {fighter_1.name} {fighter_1.life}\\n-- Vida restante de {fighter_2.name} {fighter_2.life}\\n\")\n            turn += 1\n            sleep(1)\n            if hit == fighter_1.strength and fighter_2.life > 0:\n                logging.info(\"** GOLPE CRÍTICO **\")\n                print(f\"** Como ha sido un golpe crítico, {fighter_2.name} tiene que regenerarse y no puede atacar en el siguiente turno **\\n\")\n                self.battle(fighter_1,fighter_2,turn)       #si es crítico se llama a la misma función respetando el mismo orden de los combatiente y no \"pasa el turno\"\n            else:\n                self.battle(fighter_2,fighter_1,turn)       #si no es crítico, se invierte el orden de los combatientes para que \"pase el turno\"\n\nprint(\"\\nTe doy la bienvenida a la mas que esperada y ansiada pelea en la Tierra 10005 entre.... ¡¡¡¡DEADPOOL y WOLVERINE!!!\\n\")\nwade_wilson = DeadPool()\nlogan = Wolverine()\nbattle = Battle()\nbattle.set_life(wade_wilson)\nbattle.set_life(logan)\nlogging.info(\"Comienza la pelea\")\nprint(\"Todo listo... LFG!!\\n\")\nsleep(1)\nstart_time = time()\nbattle.battle(wade_wilson,logan)\nend_time = time()\nlogging.info(f\"El combate ha durado {end_time-start_time:.4} segundos\") # se muestra en el log cuántos segundos ha tardado en acabar la pelea\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/python/cristianfloyd.py",
    "content": "# EJERCICIO:\n# ¡Deadpool y Wolverine se enfrentan en una batalla épica!\n# Crea un programa que simule la pelea y determine un ganador.\n# El programa simula un combate por turnos, donde cada protagonista posee unos\n# puntos de vida iniciales, un daño de ataque variable y diferentes cualidades\n# de regeneración y evasión de ataques.\n# Requisitos:\n# 1. El usuario debe determinar la vida inicial de cada protagonista.\n# 2. Cada personaje puede impartir un daño aleatorio:\n#    - Deadpool: Entre 10 y 100.\n#    - Wolverine: Entre 10 y 120.\n# 3. Si el daño es el máximo, el personaje que lo recibe no ataca en el\n# siguiente turno, ya que tiene que regenerarse (pero no aumenta vida).\n# 4. Cada personaje puede evitar el ataque contrario:\n#    - Deadpool: 25% de posibilidades.\n#    - Wolverine: 20% de posibilidades.\n# 5. Un personaje pierde si sus puntos de vida llegan a cero o menos.\n# Acciones:\n# 1. Simula una batalla.\n# 2. Muestra el número del turno (pausa de 1 segundo entre turnos).\n# 3. Muestra qué pasa en cada turno.\n# 4. Muestra la vida en cada turno.\n# 5. Muestra el resultado final.\n\nimport os\nimport random\nimport time\nfrom typing import Tuple\n\n\nclass Personaje:\n    def __init__(self, nombre: str, vida: int, ataque: int, evasion: int):\n        self.nombre: str = nombre\n        self.vida: int = vida\n        self.vida_maxima: int = vida\n        self.ataque_maximo: int = ataque\n        self.evasion: int = evasion\n        self.esta_aturdido: bool = False\n        self.regeneracion: int = 10\n        self.color: str = \"\\033[94m\"\n\n    def atacar(self, objetivo: \"Personaje\") -> None:\n        \"\"\"\n        Ataca al objetivo con un numero aleatorio de ataque entre 0 y el ataque maximo.\n        \"\"\"\n        # tirada de dados entre 0 y 100\n        ataque: int = random.randint(10, self.ataque_maximo)\n\n        damage = objetivo.recibir_ataque(ataque, ataque == self.ataque_maximo)\n        \n        print(f\"{self.nombre} ataca a {objetivo.nombre} y le hace {damage} de daño.\")\n\n    def recibir_ataque(self, cantidad_ataque: int, es_maximo: bool) -> int:\n        \"\"\"\n        Recibe un ataque y reduce la vida del personaje.\n        \"\"\"\n        # tirada de dados entre 0 y 100\n        tirada_dados: int = random.randint(0, 100)\n        porcentaje_evasion: int = self.porcentaje_evasion(tirada_dados)\n        ataque_recibido: int = 0\n        if porcentaje_evasion == 100:\n            print(f\"{self.nombre} evita el ataque.\")\n            ataque_recibido = 0\n        elif porcentaje_evasion == 50:\n            print(f\"{self.nombre} evita el ataque.\")\n            ataque_recibido = int(cantidad_ataque / 2)\n        else:\n            ataque_recibido = cantidad_ataque\n        self.vida -= ataque_recibido\n\n        if es_maximo:\n            self.esta_aturdido = True\n            print(f\"{self.nombre} se aturde.\")\n            time.sleep(1)\n\n        print(f\"{self.nombre} recibe {ataque_recibido} de daño.\")\n        return ataque_recibido\n\n    def porcentaje_evasion(self, tirada_dados: int) -> int:\n        \"\"\"\n        Retorna el porcentaje de evasion del personaje.\n        que puede ser 100% o 50% o 0%.\n        100 cuando supera el umbral de evasion.\n        50 cuando esta cerca del umbral de evasion.\n        0 cuando no supera el umbral de evasion.\n        \"\"\"\n        umbral = 10\n\n        if tirada_dados <= self.evasion:\n            return 100\n        elif tirada_dados > self.evasion and tirada_dados <= self.evasion + umbral:\n            return 50\n        else:\n            return 0\n\n    def defender(self) -> None:\n        if self.vida > 0:\n            self.vida -= int(self.ataque_maximo * self.evasion)\n        else:\n            print(f\"{self.nombre} ya no tiene vida.\")\n        print(f\"{self.nombre} defiende y le hace {self.evasion} de daño.\")\n\n    def regenerar(self) -> None:\n        if self.esta_aturdido:\n            print(f\"{self.nombre} esta aturdido.\")\n            time.sleep(2)\n            return\n        if self.vida > 0 and not self.esta_aturdido:\n            self.vida = min(self.vida + self.regeneracion, self.vida_maxima)\n            print(f\"{self.nombre} se regenera y recupera {self.regeneracion} de vida.\")\n        else:\n            print(f\"{self.nombre} ya no tiene vida.\")\n\n    def limpiar_aturdido(self) -> None:\n        self.esta_aturdido = False\n\nclass Deadpool(Personaje):\n    def __init__(self, vida_inicial: int):\n        self.ataque_maximo: int = 100\n        self.color = \"\\033[91m\"\n        super().__init__(\n            nombre=\"Deadpool\",\n            vida=vida_inicial,\n            ataque=self.ataque_maximo,\n            evasion=25\n            )\n        \n\nclass Wolverine(Personaje):\n    def __init__(self, vida_inicial: int):\n        self.ataque_maximo: int = 120\n        self.color = \"\\033[93m\"\n        super().__init__(\n            nombre=\"Wolverine\",\n            vida=vida_inicial,\n            ataque=self.ataque_maximo,\n            evasion=20\n            )\n\n# motor de combate\nclass batalla:\n    def __init__(self, personaje1: Personaje, personaje2: Personaje):\n        self.personaje1: Personaje = personaje1\n        self.personaje2: Personaje = personaje2\n        self.turno: int = 1\n\n    def iniciar(self) -> None:\n        atacante, defensor = self.atacante_inicial()\n        while atacante.vida > 0 and defensor.vida > 0:\n            os.system(\"cls\" if os.name == 'nt' else \"clear\")\n            self.mostrar_stats()\n            print(f\"Ataque de {atacante.nombre}\")\n            self.turno += 1\n            if atacante.esta_aturdido:\n                atacante.limpiar_aturdido()\n            else:\n                atacante.atacar(defensor)\n            defensor.regenerar()\n            atacante, defensor = defensor, atacante\n            time.sleep(1)\n        if atacante.vida <= 0:\n            print(f\"{defensor.nombre} gana la batalla.\")\n        elif defensor.vida <= 0:\n            print(f\"{atacante.nombre} gana la batalla.\")\n\n    def atacante_inicial(self) -> Tuple[Personaje, Personaje]:\n        return (self.personaje1, self.personaje2) if random.randint(0, 1) == 0 else (self.personaje2, self.personaje1)\n\n    def barra_vida(self, personaje: Personaje) -> int:\n        progreso = max(0, personaje.vida / personaje.vida_maxima) * 20\n        return int(progreso)\n\n    def armar_bloque(self, bloques: int) -> str:\n        return \"█\" * bloques + \"░\" * (20 - bloques)\n\n    def mostrar_stats(self):\n        print(\"\\n\")\n        print(f\"{'':^15} TURNO {self.turno} {'':^15}\")\n        for p in [self.personaje1, self.personaje2]:\n            # calcular cuantos bloques pintar (20 maximo)\n            num_bloques = min(20, self.barra_vida(p))\n            bloque = self.armar_bloque(num_bloques)\n            estado = \" 💫\" if p.esta_aturdido else \"\"\n            \n            print(f\"{p.color}{p.nombre:<10}\\033[0m [{bloque}] {p.vida}/{p.vida_maxima} HP{estado}\")\n        print(\"=\"*45 + \"\\n\")\n\n\nif __name__ == \"__main__\":\n    vida_inicial_deadpool: int = int(input(\"Ingrese la vida inicial de Deadpool: \"))\n    vida_inicial_wolverine: int = int(input(\"Ingrese la vida inicial de Wolverine: \"))\n    personaje1: Deadpool = Deadpool(vida_inicial_deadpool)\n    personaje2: Wolverine = Wolverine(vida_inicial_wolverine)\n    pelea: batalla = batalla(personaje1, personaje2)\n    pelea.iniciar()\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/python/d1d4cum.py",
    "content": "import random\nimport time\n\n\nclass Character:\n    name: str\n    life: int\n    min_atack: int\n    max_atack: int\n    evasion: int\n\n    def __init__(self, name, life, min_atack, max_atack, evasion):\n        self.name = name\n        self.life = life\n        self.min_atack = min_atack\n        self.max_atack = max_atack\n        self.evasion = evasion\n\n    def atack(self):\n        return random.randint(self.min_atack, self.max_atack)\n\n    def avoid(self):\n        result = True if random.random() < (self.evasion / 100) else False\n        return result\n\n\ndef main():\n    wolverine = Character(name=\"Wolverine\", life=300, min_atack=10, max_atack=120, evasion=20)\n    deadpool = Character(name=\"Deadpool\", life=200, min_atack=10, max_atack=100, evasion=25)\n    turn = 1\n    atack_turn = wolverine\n    defense_turn = deadpool\n\n    finish = False\n\n    def change_turn():\n        nonlocal atack_turn, defense_turn\n\n        if atack_turn == wolverine:\n            atack_turn = deadpool\n            defense_turn = wolverine\n        else:\n            atack_turn = wolverine\n            defense_turn = deadpool\n\n    def points_resume():\n        nonlocal atack_turn, defense_turn, finish\n\n        if defense_turn.life <= 0:\n            print(f\"{atack_turn.name}: {atack_turn.life} puntos\")\n            print(f\"{defense_turn.name}: 0 puntos\")\n            print(f\"{atack_turn.name} gana!!\")\n            finish = True\n        else:\n            print(f\"{atack_turn.name}: {atack_turn.life} puntos\")\n            print(f\"{defense_turn.name}: {defense_turn.life} puntos\")\n\n    while not finish:\n\n        print(f\"\\nTurno {turn}\")\n        atack = atack_turn.atack()\n        print(f\"{atack_turn.name} ataca\")\n\n        if not defense_turn.avoid():\n            defense_turn.life -= atack\n\n            if atack != atack_turn.max_atack:\n                print(f\"{defense_turn.name} intenta evadir el ataque, pero recibe {atack} puntos de daño\")\n                points_resume()\n                change_turn()\n            else:\n                print(f\"{defense_turn.name} intenta evadir el ataque, pero recibe un ataque crítico\")\n                print(f\"{defense_turn.name} pierde el turno\")\n                points_resume()\n\n        else:\n            print(f\"{defense_turn.name} evade el ataque\")\n            points_resume()\n            change_turn()\n\n        time.sleep(1)\n        turn += 1\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/python/davidrguez98.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * ¡Deadpool y Wolverine se enfrentan en una batalla épica!\n * Crea un programa que simule la pelea y determine un ganador.\n * El programa simula un combate por turnos, donde cada protagonista posee unos\n * puntos de vida iniciales, un daño de ataque variable y diferentes cualidades\n * de regeneración y evasión de ataques.\n * Requisitos:\n * 1. El usuario debe determinar la vida inicial de cada protagonista.\n * 2. Cada personaje puede impartir un daño aleatorio:\n *    - Deadpool: Entre 10 y 100.\n *    - Wolverine: Entre 10 y 120.\n * 3. Si el daño es el máximo, el personaje que lo recibe no ataca en el\n * siguiente turno, ya que tiene que regenerarse (pero no aumenta vida).\n * 4. Cada personaje puede evitar el ataque contrario:\n *    - Deadpool: 25% de posibilidades.\n *    - Wolverine: 20% de posibilidades.\n * 5. Un personaje pierde si sus puntos de vida llegan a cero o menos.\n * Acciones:\n * 1. Simula una batalla.\n * 2. Muestra el número del turno (pausa de 1 segundo entre turnos).\n * 3. Muestra qué pasa en cada turno.\n * 4. Muestra la vida en cada turno.\n * 5. Muestra el resultado final.\n */ \"\"\"\n\n#EJERCICIO\n\nimport random\nimport time\n\ndeadpool_healt = 1000\nwolverine_healt = 1000\n\nturn = 0\n\nregenerate = False\n\nwhile deadpool_healt > 0 and wolverine_healt > 0:\n\n    turn += 1\n    print(f\"\\nTurno {turn}\")\n\n    \"\"\" Deadpool ataca a Wolverine \"\"\"\n\n    if regenerate:\n        print(\"Deadpool se está regenerando y no ataca.\")\n        regenerate = False\n    elif random.random() > 0.2:\n        deadpool_damage = random.randint(10, 100)\n        print(f\"Deadpool ataca a Wolverine con {deadpool_damage} de daño.\")\n        if deadpool_damage == 100:\n            regenerate = True\n            print(\"¡Deadpool ataca con daño máximo a Wolverine! Wolverine no atacará en el siguiente turno.\")\n        \n        wolverine_healt -= deadpool_damage\n        \n        if wolverine_healt <= 0:\n            print(\"La vida de Wolverine ha llegado a 0.\")\n            break\n        else:\n            print(f\"Vida restante de Wolverine es: {wolverine_healt}\")\n    else:\n        print(\"Wolverine esquiva el ataque de Deadpool.\")\n\n\n    \"\"\" Wolverine ataca a Deathpool \"\"\"\n\n    if regenerate:\n        print(\"Wolverine se está regenerando y no ataca.\")\n        regenerate = False\n    elif random.random() > 0.25:\n        wolverine_damage = random.randint(10, 120)\n        print(f\"Wolverine ataca a Deadpool con {wolverine_damage} de daño.\")\n\n        if wolverine_damage == 120:\n            regenerate = True\n            print(\"¡Wolverine ataca con daño máximo a Deadpool! Deadpool no atacará en el siguiente turno.\")\n        \n        deadpool_healt -= wolverine_damage\n        \n        if deadpool_healt <= 0:\n            print(\"La vida de Deadpool ha llegado a 0.\")\n            break\n        else:\n            print(f\"Vida restante de Deadpool es: {deadpool_healt}\")\n    else:\n        print(\"Deadpool esquiva el ataque de Wolverine.\")\n\n    time.sleep(1)\n\nif deadpool_healt > 0:\n    print(\"Deadpool gana la batalla.\")\nelse:\n    print(\"Wolverine gana la batalla.\")\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/python/duendeintemporal.py",
    "content": "#32 { Retos para Programadores } BATALLA DEADPOOL Y WOLVERINE\n\n# Bibliography reference:\n# I use GPT as a reference and sometimes to correct or generate proper comments.\n\n\"\"\"  \n* EJERCICIO:\n * ¡Deadpool y Wolverine se enfrentan en una batalla épica!\n * Crea un programa que simule la pelea y determine un ganador.\n * El programa simula un combate por turnos, donde cada protagonista posee unos\n * puntos de vida iniciales, un daño de ataque variable y diferentes cualidades\n * de regeneración y evasión de ataques.\n * Requisitos:\n * 1. El usuario debe determinar la vida inicial de cada protagonista.\n * 2. Cada personaje puede impartir un daño aleatorio:\n *    - Deadpool: Entre 10 y 100.\n *    - Wolverine: Entre 10 y 120.\n * 3. Si el daño es el máximo, el personaje que lo recibe no ataca en el\n * siguiente turno, ya que tiene que regenerarse (pero no aumenta vida).\n * 4. Cada personaje puede evitar el ataque contrario:\n *    - Deadpool: 25% de posibilidades.\n *    - Wolverine: 20% de posibilidades.\n * 5. Un personaje pierde si sus puntos de vida llegan a cero o menos.\n * Acciones:\n * 1. Simula una batalla.\n * 2. Muestra el número del turno (pausa de 1 segundo entre turnos).\n * 3. Muestra qué pasa en cada turno.\n * 4. Muestra la vida en cada turno.\n * 5. Muestra el resultado final.\n\n\"\"\"\n\n\"\"\" The original code version was created in JavaScript, which allows the use of CSS styles for effects and Data URI images to visualize the opponents. Since Python does not have a built-in way to handle CSS styles or HTML directly, we will focus on the logic of the combat system and simulate the battle in a console-based format. \"\"\"\n\nlog = print\n\nimport random\nimport time\n\nclass Combatant:\n    def __init__(self, name, avatar, life, atk_max, atk_min, defense):\n        self.name = name\n        self.avatar = avatar\n        self.life = life\n        self.attack_damage_max = atk_max\n        self.attack_damage_min = atk_min\n        self.defense = defense\n        self.attack_potence = atk_max\n\nclass Battle:\n    def __init__(self, c1, c2):\n        self.combatant1 = c1\n        self.combatant2 = c2\n        self.result = ''\n        self.battle_interval = None\n\n    def start_battle(self):\n        is_attacking = False\n\n        while self.combatant1.life > 0 and self.combatant2.life > 0:\n            if not is_attacking:\n                is_attacking = True\n                self.round()\n                time.sleep(4.5)  # Simulate the time between attacks\n                is_attacking = False\n            time.sleep(1.5)  # Wait before the next round\n\n    def attack(self, attacker, defender):\n        log(f\"Attacker: {attacker.name}, Defender: {defender.name}\")\n\n        avoid_attack = random.randint(0, 100)\n\n        if avoid_attack < 101 - defender.defense:\n            max_damage = min(attacker.attack_damage_max, attacker.attack_potence)\n            min_damage = attacker.attack_damage_min\n            damage = random.randint(min_damage, max_damage)\n\n            defender.life -= damage\n            attacker.attack_potence -= 10  # Decrease attack potency\n\n            log(f\"{attacker.name} dealt {damage} damage to {defender.name}. {defender.name} has {defender.life} life left.\")\n\n            if defender.life <= 0:\n                self.declare_winner(attacker, defender)\n                return\n\n        else:\n            log(f\"{defender.name} blocked {attacker.name}'s attack.\")\n\n        if attacker.attack_potence < attacker.attack_damage_min:\n            attacker.attack_potence = attacker.attack_damage_min\n\n    def declare_winner(self, winner, loser):\n        log(f\"{winner.name} is the winner!\")\n        self.result = f\"{winner.name} is the winner!\"\n\n    def round(self):\n        if self.combatant1.life > 0 and self.combatant2.life > 0:\n            position = random.randint(0, 1)\n            if position == 1:\n                self.attack(self.combatant1, self.combatant2)\n            else:\n                self.attack(self.combatant2, self.combatant1)\n        else:\n            if self.combatant1.life <= 0 and self.combatant2.life <= 0:\n                log(\"It's a draw!\")\n            elif self.combatant1.life <= 0:\n                self.declare_winner(self.combatant2, self.combatant1)\n            else:\n                self.declare_winner(self.combatant1, self.combatant2)\n\n# Create combatants\nWOLVERINE = Combatant('Wolverine', 'avatar', 100, 120, 10, 20)\nDEADPOOL = Combatant('Deadpool', 'avatar', 100, 100, 10, 25)\n\n# Start the battle\nbattle1 = Battle(WOLVERINE, DEADPOOL)\n\nif __name__ == \"__main__\":\n    battle1.start_battle()\n\n\"\"\"  \nAttacker: Wolverine, Defender: Deadpool\nWolverine dealt 38 damage to Deadpool. Deadpool has 62 life left.\nAttacker: Wolverine, Defender: Deadpool\nWolverine dealt 57 damage to Deadpool. Deadpool has 5 life left.\nAttacker: Wolverine, Defender: Deadpool\nDeadpool blocked Wolverine's attack.\nAttacker: Deadpool, Defender: Wolverine\nDeadpool dealt 27 damage to Wolverine. Wolverine has 73 life left.\nAttacker: Deadpool, Defender: Wolverine\nDeadpool dealt 66 damage to Wolverine. Wolverine has 7 life left.\nAttacker: Deadpool, Defender: Wolverine\nDeadpool dealt 23 damage to Wolverine. Wolverine has -16 life left.\nDeadpool is the winner!\n\n\"\"\""
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/python/fborjalv.py",
    "content": "\"\"\"\n\n/*\n * EJERCICIO:\n * ¡Deadpool y Wolverine se enfrentan en una batalla épica!\n * Crea un programa que simule la pelea y determine un ganador.\n * El programa simula un combate por turnos, donde cada protagonista posee unos\n * puntos de vida iniciales, un daño de ataque variable y diferentes cualidades\n * de regeneración y evasión de ataques.\n * Requisitos:\n * 1. El usuario debe determinar la vida inicial de cada protagonista. ✅\n * 2. Cada personaje puede impartir un daño aleatorio: ✅\n *    - Deadpool: Entre 10 y 100.\n *    - Wolverine: Entre 10 y 120.\n * 3. Si el daño es el máximo, el personaje que lo recibe no ataca en el ✅\n * siguiente turno, ya que tiene que regenerarse (pero no aumenta vida).\n * 4. Cada personaje puede evitar el ataque contrario: ✅\n *    - Deadpool: 25% de posibilidades.\n *    - Wolverine: 20% de posibilidades.\n * 5. Un personaje pierde si sus puntos de vida llegan a cero o menos. ✅\n * Acciones:\n * 1. Simula una batalla. ✅\n * 2. Muestra el número del turno (pausa de 1 segundo entre turnos). ✅\n * 3. Muestra qué pasa en cada turno. ✅\n * 4. Muestra la vida en cada turno. ✅\n * 5. Muestra el resultado final. ✅\n */\n\n\n\"\"\"\n\nimport random\nfrom time import sleep\nclass Character:\n    def __init__(self, health) -> None:\n        self.name = \"\"\n        self.health = health\n        self.min_damage = 0\n        self.max_damage = 0\n        self.damage = 0\n        self.evassion = 0\n    def evade_attack(self):\n        return random.random() < self.evassion\n\n    def attack(self, enemy):\n        self.damage = random.randint(self.min_damage, self.max_damage)\n        if not enemy.evade_attack():\n            enemy.health -= self.damage\n            print(f\"{self.name} ha golpeado a {enemy.name}. Ha realizado un ataque de {self.damage} puntos\")\n            print(f\"Ahora la salud de {enemy.name} es de {enemy.health}\")\n        else:\n            print(f\"{enemy.name} ha evitado el ataque de {self.name}\")\n\n    def is_critical(self, enemy):\n        if self.damage == self.max_damage:\n            print(f\"{self.name} le ha dado golpe críticoa {enemy.name}, que pierde un turno de ataque para regenerarse\")\n            return True\n        else: \n            return False\n\nclass Deadpool(Character):\n    def __init__(self, health) -> None:\n        super().__init__(health)\n        self.name = \"Deadpool\"\n        self.min_damage = 10\n        self.max_damage = 100\n        self.evassion = 0.25\n\n\nclass Wolverine(Character):\n    def __init__(self, health) -> None:\n        super().__init__(health)\n        self.name = \"Wolverine\"\n        self.min_damage = 10\n        self.max_damage = 120\n        self.evassion = 0.2\n\nclass Game:\n\n    def __init__(self) -> None:\n        dp_health = int(input(\"Introduce puntos de salud para Deadpool: \"))\n        wv_health = int(input(\"Introduce puntos de salud para Wolverine: \"))\n        self.player1, self.player2  = random.sample([Deadpool(dp_health), Wolverine(wv_health)], 2)\n        self.turn = 0\n\n    def is_character_alive(self):\n        if self.player1.health <= 0 or self.player2.health <=0:\n            winner = max(self.player1, self.player2, key= lambda x: x.health)\n            loser = min(self.player1, self.player2, key= lambda x: x.health)\n            print(f\"{winner.name} ha ganado el combate a {loser.name}\")\n            return False\n        else: \n            return True\n\n\n    def init_game(self):\n        \n        print(f\"{self.player1.name} comienza atacando a {self.player2.name}\")\n        turn_off_player1 = False\n        turn_off_player2 = False\n        while self.player1.health > 0 and self.player2.health > 0:\n            \n            sleep(3)\n            print(f\"Turno: {self.turn} ----------\")\n            self.turn +=1\n            if not turn_off_player1: \n                self.player1.attack(self.player2)\n                if not self.is_character_alive(): break\n                turn_off_player2 = False\n                if self.player1.is_critical(self.player2):\n                    turn_off_player2 = True\n\n            if not turn_off_player2:    \n                self.player2.attack(self.player1)\n                if not self.is_character_alive(): break\n                turn_off_player1 = False\n                if self.player2.is_critical(self.player1):\n                    turn_off_player1 = True\n            \n\nsystem = Game()\nsystem.init_game()\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/python/franxiscodev.py",
    "content": "'''\nBatalla deadpool vs wolverine\n'''\nimport random\nimport time\n\n# DEADPOOL_HEALTH = 1000\n# WOLVERINE_HEALTH = 1200\n\ndeadpool_health = 1000\nwolverine_health = 1200\n\nturn = 0\nregenerate = False\n\nwhile deadpool_health > 0 and wolverine_health > 0:\n\n    turn += 1\n    print(f\"\\n⌛ Turno {turn}\")\n\n    # Deadpooll ataca\n    if regenerate:\n        print(\"❌ Deadpool se está regenerando y no ataca\")\n        regenerate = False\n    elif random.random() > 0.2:\n        deadpool_damage = random.randint(10, 100)\n        print(f\"Deadpool ataca con daño {deadpool_damage}\")\n        if deadpool_damage > 80:\n            regenerate = True\n            print(\n                f\"🤜🤜🤜 Deadpool crítico! {deadpool_damage}: Wolverine no atacará en el siguiente turno\")\n        wolverine_health -= deadpool_damage\n\n        if wolverine_health <= 0:\n            print(f\"Vida de Wolverine a CERO fin: {wolverine_health}\")\n            break\n        else:\n            print(f\"Vida restante de Wolverine {wolverine_health}\")\n    else:\n        print(\"🛡️  Wolverine esquiva el ataque de Deadpool\")\n\n    # Wolverine ataca\n    if regenerate:\n        print(\"❌ Wolverine se está regenerando y no ataca\")\n        regenerate = False\n    elif random.random() > 0.25:\n        wolverine_damage = random.randint(10, 120)\n        print(f\"Wolverine ataca con daño {wolverine_damage}\")\n        if wolverine_damage > 100:\n            regenerate = True\n            print(\n                f\"🤜🤜🤜 Wolverine crítico! {wolverine_damage}: Deadpool no atacará en el siguiente turno\")\n        deadpool_health -= wolverine_damage\n\n        if deadpool_health <= 0:\n            print(f\"Vida de Deadpool a CERO fin: {deadpool_health}\")\n            break\n        else:\n            print(f\"Vida restante de Deadpool {deadpool_health}\")\n    else:\n        print(\"🛡️  Deadpool esquiva el ataque de Wolverine\")\n    time.sleep(1)\n\nif deadpool_health > 0:\n    print(f\"💯 Deadpool gana la batalla {deadpool_health}\")\nelse:\n    print(f\"💪 Wolverine gana la batalla {wolverine_health}\")\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/python/hectorio23.py",
    "content": "# Autor:  Héctor Adán\n# GitHub: https://github.com/hectorio23\n\n'''\n * EJERCICIO:\n * ¡Deadpool y Wolverine se enfrentan en una batalla épica!\n * Crea un programa que simule la pelea y determine un ganador.\n * El programa simula un combate por turnos, donde cada protagonista posee unos\n * puntos de vida iniciales, un daño de ataque variable y diferentes cualidades\n * de regeneración y evasión de ataques.\n * Requisitos:\n * 1. El usuario debe determinar la vida inicial de cada protagonista.\n * 2. Cada personaje puede impartir un daño aleatorio:\n *    - Deadpool: Entre 10 y 100.\n *    - Wolverine: Entre 10 y 120.\n * 3. Si el daño es el máximo, el personaje que lo recibe no ataca en el\n * siguiente turno, ya que tiene que regenerarse (pero no aumenta vida).\n * 4. Cada personaje puede evitar el ataque contrario:\n *    - Deadpool: 25% de posibilidades.\n *    - Wolverine: 20% de posibilidades.\n * 5. Un personaje pierde si sus puntos de vida llegan a cero o menos.\n * Acciones:\n * 1. Simula una batalla.\n * 2. Muestra el número del turno (pausa de 1 segundo entre turnos).\n * 3. Muestra qué pasa en cada turno.\n * 4. Muestra la vida en cada turno.\n * 5. Muestra el resultado final.\n'''\n\n\nimport random\nimport time\n\nclass Character:\n    def __init__(self, name, min_damage, max_damage, dodge_chance):\n        self.name = name\n        self.health = 0\n        self.min_damage = min_damage\n        self.max_damage = max_damage\n        self.dodge_chance = dodge_chance\n\n    def attack(self):\n        return random.randint(self.min_damage, self.max_damage)\n\n    def evade(self):\n        return random.random() < self.dodge_chance\n\n    def is_alive(self):\n        return self.health > 0\n\nclass Deadpool(Character):\n    def __init__(self):\n        super().__init__(\"Deadpool\", 10, 100, 0.25)\n\nclass Wolverine(Character):\n    def __init__(self):\n        super().__init__(\"Wolverine\", 10, 120, 0.20)\n\ndef simulate_battle(char1, char2):\n    turn = 1\n    skip_char1 = False\n    skip_char2 = False\n\n    while char1.is_alive() and char2.is_alive():\n        print(f\"\\n**** Turno {turn} ****:\")\n        if not skip_char1:\n            if not char2.evade():\n                damage = char1.attack()\n                char2.health -= damage\n                print(f\"[+] - {char1.name} ataca a {char2.name} causando {damage} de daño.\")\n                if damage == char1.max_damage:\n                    print(f\"[+] - {char2.name} debe regenerarse y pierde el siguiente turno.\")\n                    skip_char2 = True\n            else:\n                print(f\"[+] - {char2.name} evade el ataque de {char1.name}.\")\n        else:\n            skip_char1 = False\n\n        if not skip_char2 and char2.is_alive():\n            if not char1.evade():\n                damage = char2.attack()\n                char1.health -= damage\n                print(f\"[+] - {char2.name} ataca a {char1.name} causando {damage} de daño.\")\n                if damage == char2.max_damage:\n                    print(f\"[+] - {char1.name} debe regenerarse y pierde el siguiente turno.\")\n                    skip_char1 = True\n            else:\n                print(f\"[+] - {char1.name} evade el ataque de {char2.name}.\")\n        else:\n            skip_char2 = False\n\n        print(f\"{char1.name} Vida: {char1.health}, {char2.name} Vida: {char2.health}\\n\")\n        time.sleep(1)\n        turn += 1\n\n    if char1.is_alive():\n        print(f\"{char1.name} gana la batalla!\")\n    else:\n        print(f\"{char2.name} gana la batalla!\")\n\nif __name__ == \"__main__\":\n    deadpool_health = int(input(\"Ingrese la vida inicial de Deadpool: \"))\n    wolverine_health = int(input(\"Ingrese la vida inicial de Wolverine: \"))\n\n    deadpool = Deadpool()\n    wolverine = Wolverine()\n\n    deadpool.health = deadpool_health\n    wolverine.health = wolverine_health\n\n    simulate_battle(deadpool, wolverine)\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/python/hozlucas28.py",
    "content": "# pylint: disable=missing-module-docstring,missing-class-docstring,missing-function-docstring\n\n\nfrom abc import ABCMeta, abstractmethod\nfrom random import randint\nfrom typing import Self, TypedDict\n\nimport asyncio\n\n# ---------------------------------------------------------------------------- #\n#                      SUPERHEROREGENERATINGERROR (ERROR)                      #\n# ---------------------------------------------------------------------------- #\n\n\nclass SuperheroRegeneratingException(Exception):\n    def __init__(self, *, superhero: \"AbcSuperhero\") -> None:\n        super().__init__(f\"{superhero.name} is regenerating\")\n\n\n# ---------------------------------------------------------------------------- #\n#                               SUPERHERO (CLASS)                              #\n# ---------------------------------------------------------------------------- #\n\ntype AttackDamage = tuple[int, int]\n\n\nclass AbcSuperhero(metaclass=ABCMeta):\n    @property\n    @abstractmethod\n    def life_points(self) -> int:\n        pass\n\n    @property\n    @abstractmethod\n    def regenerating(self) -> bool:\n        pass\n\n    @property\n    @abstractmethod\n    def attack_damage(self) -> AttackDamage:\n        pass\n\n    @property\n    @abstractmethod\n    def evade_percentage(self) -> int:\n        pass\n\n    @property\n    @abstractmethod\n    def name(self) -> str:\n        pass\n\n    @abstractmethod\n    def set_regenerating(self, regenerating: bool) -> Self:\n        pass\n\n    @abstractmethod\n    def evade_attack(self) -> bool:\n        pass\n\n    @abstractmethod\n    def produce_damage(self) -> int:\n        pass\n\n    @abstractmethod\n    def receive_damage(self, damage: int) -> Self:\n        pass\n\n\nclass Superhero(AbcSuperhero):\n    __life_points: int\n    __regenerating: bool\n    __attack_damage: AttackDamage\n    __evade_percentage: int\n    __name: str\n\n    def __init__(\n        self,\n        *,\n        life_points: int,\n        attack_damage: AttackDamage,\n        evade_percentage: int,\n        name: str,\n    ) -> None:\n        self.__life_points = life_points\n        self.__regenerating = False\n        self.__attack_damage = attack_damage\n        self.__evade_percentage = evade_percentage\n        self.__name = name\n\n    @property\n    def life_points(self) -> int:\n        return self.__life_points\n\n    @property\n    def regenerating(self) -> bool:\n        return self.__regenerating\n\n    @property\n    def attack_damage(self) -> AttackDamage:\n        return self.__attack_damage\n\n    @property\n    def evade_percentage(self) -> int:\n        return self.__evade_percentage\n\n    @property\n    def name(self) -> str:\n        return self.__name\n\n    def set_regenerating(self, regenerating: bool) -> Self:\n        self.__regenerating = regenerating\n        return self\n\n    def evade_attack(self) -> bool:\n        rnd_int: int = randint(a=0, b=100)\n        return rnd_int <= self.__evade_percentage\n\n    def produce_damage(self) -> int:\n        if self.__regenerating:\n            raise SuperheroRegeneratingException(superhero=self)\n\n        [min_attack_damage, max_attack_damage] = self.attack_damage\n        rnd_damage: int = randint(a=min_attack_damage, b=max_attack_damage)\n        return rnd_damage\n\n    def receive_damage(self, damage: int) -> Self:\n        self.__life_points -= damage\n        return self\n\n\n# ---------------------------------------------------------------------------- #\n#                               WOLVERINE (CLASS)                              #\n# ---------------------------------------------------------------------------- #\n\n\nclass Wolverine(Superhero):\n    def __init__(self, *, life_points: int) -> None:\n        super().__init__(\n            life_points=life_points,\n            attack_damage=(10, 120),\n            evade_percentage=20,\n            name=\"Wolverine\",\n        )\n\n\n# ---------------------------------------------------------------------------- #\n#                               DEADPOOL (CLASS)                               #\n# ---------------------------------------------------------------------------- #\n\n\nclass Deadpool(Superhero):\n    def __init__(self, *, life_points: int) -> None:\n        super().__init__(\n            life_points=life_points,\n            attack_damage=(10, 100),\n            evade_percentage=25,\n            name=\"Deadpool\",\n        )\n\n\n# ---------------------------------------------------------------------------- #\n#                           SUPERHEROESFIGHT (CLASS)                           #\n# ---------------------------------------------------------------------------- #\n\n\nclass Turn(TypedDict):\n    attacker: AbcSuperhero\n    number: int\n    victim: AbcSuperhero\n\n\nclass ExecutedTurn(Turn):\n    damage_produced_by_attacker: int\n    damage_received_by_victim: int\n    victim_avoid_attack: bool\n\n\nclass AbcSuperheroesFight(metaclass=ABCMeta):\n    @property\n    @abstractmethod\n    def turn(self) -> Turn:\n        pass\n\n    @property\n    @abstractmethod\n    def winner(self) -> None | AbcSuperhero:\n        pass\n\n    @abstractmethod\n    def execute_turn(self) -> ExecutedTurn:\n        pass\n\n\nclass SuperheroesFight(AbcSuperheroesFight):\n    __turn: Turn\n    __winner: None | AbcSuperhero\n\n    def __init__(\n        self, *, superhero_one: AbcSuperhero, superhero_two: AbcSuperhero\n    ) -> None:\n        self.__turn = {\n            \"attacker\": superhero_one,\n            \"number\": 1,\n            \"victim\": superhero_two,\n        }\n\n        self.__winner = None\n\n    @property\n    def turn(self) -> Turn:\n        return self.__turn\n\n    @property\n    def winner(self) -> None | AbcSuperhero:\n        return self.__winner\n\n    def execute_turn(self) -> ExecutedTurn:\n        turn: Turn = self.turn\n        attacker: AbcSuperhero = turn[\"attacker\"]\n        number: int = turn[\"number\"]\n        victim: AbcSuperhero = turn[\"victim\"]\n\n        victim.set_regenerating(regenerating=False)\n\n        self.__turn = {\n            \"attacker\": victim,\n            \"number\": number + 1,\n            \"victim\": attacker,\n        }\n\n        try:\n            damage_produced_by_attacker: int = attacker.produce_damage()\n            attacker_attack_damage: AttackDamage = attacker.attack_damage\n\n            victim_avoid_attack: bool = victim.evade_attack()\n\n            if victim_avoid_attack:\n                return {\n                    \"attacker\": attacker,\n                    \"damage_produced_by_attacker\": damage_produced_by_attacker,\n                    \"damage_received_by_victim\": 0,\n                    \"number\": number,\n                    \"victim\": victim,\n                    \"victim_avoid_attack\": victim_avoid_attack,\n                }\n\n            victim.receive_damage(damage_produced_by_attacker)\n            victim.set_regenerating(\n                regenerating=damage_produced_by_attacker == attacker_attack_damage[1]\n            )\n\n            if victim.life_points <= 0:\n                self.__winner = attacker\n\n            return {\n                \"attacker\": attacker,\n                \"damage_produced_by_attacker\": damage_produced_by_attacker,\n                \"damage_received_by_victim\": damage_produced_by_attacker,\n                \"number\": number,\n                \"victim\": victim,\n                \"victim_avoid_attack\": victim_avoid_attack,\n            }\n\n        except SuperheroRegeneratingException as error:\n            raise error\n\n\n# ---------------------------------------------------------------------------- #\n#                                     MAIN                                     #\n# ---------------------------------------------------------------------------- #\n\n\nasync def main() -> None:\n    deadpool: Deadpool = Deadpool(life_points=500)\n    wolverine: Wolverine = Wolverine(life_points=500)\n\n    superheroes_fight: SuperheroesFight = SuperheroesFight(\n        superhero_one=deadpool, superhero_two=wolverine\n    )\n\n    while superheroes_fight.winner is None:\n        await asyncio.sleep(delay=1)\n        current_turn: Turn = superheroes_fight.turn\n\n        try:\n            executed_turn: ExecutedTurn = superheroes_fight.execute_turn()\n\n            if executed_turn[\"victim_avoid_attack\"]:\n                print(\n                    f\"\\n> Turn N°{executed_turn['number']}: {executed_turn['victim'].name}\",\n                    f\" avoided {executed_turn['attacker'].name} attack.\",\n                )\n                continue\n\n            print(\n                f\"\\n> Turn N°{executed_turn['number']}: {executed_turn['attacker'].name} attacked\"\n                + f\" {executed_turn['victim'].name} with\"\n                + f\" {executed_turn['damage_produced_by_attacker']} points of damage.\",\n                f\"[ Life points of Deadpool: {deadpool.life_points} ]\",\n                f\"[ Life points of Wolverine: {wolverine.life_points} ]\",\n                sep=\"\\n\",\n            )\n        except SuperheroRegeneratingException:\n            print(\n                f\"\\n> Turn N°{current_turn['number']}: {current_turn['attacker'].name} is\"\n                + \" regenerating\"\n            )\n\n    print(f\"\\nThe winner is {superheroes_fight.winner.name}!\")\n\n\nasyncio.run(main=main())\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/python/idiegorojas.py",
    "content": "\"\"\"\n#32 - Batalla Deadpool y Wolverine\n\"\"\"\n# ¡Deadpool y Wolverine se enfrentan en una batalla épica!\n# Crea un programa que simule la pelea y determine un ganador.\n# El programa simula un combate por turnos, donde cada protagonista posee unos\n# puntos de vida iniciales, un daño de ataque variable y diferentes cualidades de regeneración y evasión de ataques.\n\n\"\"\"\nRequisitos:\n\"\"\"\n# 1. El usuario debe determinar la vida inicial de cada protagonista.\n# 2. Cada personaje puede impartir un daño aleatorio:\n    # Deadpool: Entre 10 y 100.\n    # Wolverine: Entre 10 y 120.\n# 3. Si el daño es el máximo, el personaje que lo recibe no ataca en el\n# siguiente turno, ya que tiene que regenerarse (pero no aumenta vida).\n# 4. Cada personaje puede evitar el ataque contrario:\n    # Deadpool: 25% de posibilidades.\n    # Wolverine: 20% de posibilidades.\n# 5. Un personaje pierde si sus puntos de vida llegan a cero o menos.\n\n\"\"\"\nAcciones:\n\"\"\"\n# 1. Simula una batalla.\n# 2. Muestra el número del turno (pausa de 1 segundo entre turnos).\n# 3. Muestra qué pasa en cada turno.\n# 4. Muestra la vida en cada turno.\n# 5. Muestra el resultado final.\n\nimport random\nimport time\n\nclass SimulacionBatalla:\n    def __init__(self, vida_deadpool, vida_wolverine):\n        self.vida_deadpool = vida_deadpool\n        self.vida_wolverine = vida_wolverine\n        self.turno = 0\n        self.deadpool_puede_atacar = True\n        self.wolverine_puede_atacar = True\n    \n    def batalla(self):\n        while self.vida_deadpool > 0 and self.vida_wolverine > 0:\n            self.turno += 1\n            print(f\"\\n--- TURNO {self.turno} ---\")\n            time.sleep(1)\n            \n            # Ataque de Deadpool\n            if self.deadpool_puede_atacar:\n                self.ataque_deadpool()\n            else:\n                print(\"¡Deadpool está regenerándose y no puede atacar!\")\n                self.deadpool_puede_atacar = True\n            \n            # Verificar si Wolverine aún tiene vida\n            if self.vida_wolverine <= 0:\n                break\n                \n            # Ataque de Wolverine\n            if self.wolverine_puede_atacar:\n                self.ataque_wolverine()\n            else:\n                print(\"¡Wolverine está regenerándose y no puede atacar!\")\n                self.wolverine_puede_atacar = True\n                \n            # Mostrar vida actual\n            print(f\"Vida Deadpool: {self.vida_deadpool}\")\n            print(f\"Vida Wolverine: {self.vida_wolverine}\")\n        \n        # Mostrar resultado final\n        self.mostrar_resultado()\n    \n    def ataque_deadpool(self):\n        # Deadpool ataca (10-100 daño)\n        daño = random.randint(10, 100)\n        \n        # Comprobar evasión de Wolverine (20%)\n        if random.random() < 0.20:\n            print(f\"¡Wolverine ha evitado el ataque de Deadpool!\")\n            return\n        \n        # Aplicar daño\n        self.vida_wolverine -= daño\n        print(f\"¡Deadpool ataca y causa {daño} de daño a Wolverine!\")\n        \n        # Comprobar si es un golpe crítico\n        if daño == 100:\n            print(\"¡GOLPE CRÍTICO! Wolverine necesita regenerarse\")\n            self.wolverine_puede_atacar = False\n    \n    def ataque_wolverine(self):\n        # Wolverine ataca (10-120 daño)\n        daño = random.randint(10, 120)\n        \n        # Comprobar evasión de Deadpool (25%)\n        if random.random() < 0.25:\n            print(f\"¡Deadpool ha evitado el ataque de Wolverine!\")\n            return\n        \n        # Aplicar daño\n        self.vida_deadpool -= daño\n        print(f\"¡Wolverine ataca y causa {daño} de daño a Deadpool!\")\n        \n        # Comprobar si es un golpe crítico\n        if daño == 120:\n            print(\"¡GOLPE CRÍTICO! Deadpool necesita regenerarse\")\n            self.deadpool_puede_atacar = False\n    \n    def mostrar_resultado(self):\n        print(\"\\n--- FIN DE LA BATALLA ---\")\n        if self.vida_deadpool <= 0 and self.vida_wolverine <= 0:\n            print(\"¡EMPATE! Ambos cayeron al mismo tiempo\")\n        elif self.vida_deadpool <= 0:\n            print(\"¡WOLVERINE GANA!\")\n        else:\n            print(\"¡DEADPOOL GANA!\")\n\n# Código principal\nif __name__ == \"__main__\":\n    print(\"--- BATALLA ÉPICA: DEADPOOL VS WOLVERINE ---\")\n    vida_deadpool = int(input(\"Vida inicial de Deadpool: \"))\n    vida_wolverine = int(input(\"Vida inicial de Wolverine: \"))\n    \n    batalla = SimulacionBatalla(vida_deadpool, vida_wolverine)\n    batalla.batalla()"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/python/ignaciovihe.py",
    "content": "\"\"\"\n * EJERCICIO:\n * ¡Deadpool y Wolverine se enfrentan en una batalla épica!\n * Crea un programa que simule la pelea y determine un ganador.\n * El programa simula un combate por turnos, donde cada protagonista posee unos\n * puntos de vida iniciales, un daño de ataque variable y diferentes cualidades\n * de regeneración y evasión de ataques.\n * Requisitos:\n * 1. El usuario debe determinar la vida inicial de cada protagonista.\n * 2. Cada personaje puede impartir un daño aleatorio:\n *    - Deadpool: Entre 10 y 100.\n *    - Wolverine: Entre 10 y 120.\n * 3. Si el daño es el máximo, el personaje que lo recibe no ataca en el\n * siguiente turno, ya que tiene que regenerarse (pero no aumenta vida).\n * 4. Cada personaje puede evitar el ataque contrario:\n *    - Deadpool: 25% de posibilidades.\n *    - Wolverine: 20% de posibilidades.\n * 5. Un personaje pierde si sus puntos de vida llegan a cero o menos.\n * Acciones:\n * 1. Simula una batalla.\n * 2. Muestra el número del turno (pausa de 1 segundo entre turnos).\n * 3. Muestra qué pasa en cada turno.\n * 4. Muestra la vida en cada turno.\n * 5. Muestra el resultado final.\n\"\"\"\n\nfrom abc import ABC, abstractmethod\nimport random\nimport time\n\nPAUSE_DURATION = 3\n\nclass SuperHero(ABC): # La clase abstracta superhero, sirve de intarfaz y centraliza metodos comunes.\n    def __init__(self, life_points):\n        self.life_points = life_points\n        self.regenerating = False\n\n    @abstractmethod\n    def calculate_attack_damage(self) -> int:\n        pass\n\n    @abstractmethod\n    def is_max_damage(self, damage: int) -> bool:\n        pass\n\n    def reduce_health(self, attack_points):\n        self.life_points = max(0, self.life_points - attack_points)\n\n    @abstractmethod\n    def dodge_attack(self) -> bool:\n        pass\n\n    @abstractmethod\n    def must_skip_turn_due_to_regeneration(self) ->bool:\n        pass\n\n    def attack(self, damage: int, critic_damage: bool):\n        name = self.__class__.__name__\n        if not self.dodge_attack():\n            self.reduce_health(damage)\n            print(f\"{name} recibe el ataque de fuerza {damage}. Vida restante: {self.life_points}\")\n            time.sleep(PAUSE_DURATION)\n            if critic_damage:\n                print(f\"El ataque es crítico. {name} debe regenerarse.\")\n                time.sleep(PAUSE_DURATION)\n                self.regenerating = True\n        else:\n            print(f\"{name} [VIDA:{self.life_points}] consigue evitar el ataque.\")\n            time.sleep(PAUSE_DURATION)\n\n\nclass Wolverine(SuperHero):# Define sus propias habilidades\n    def calculate_attack_damage(self):\n        return random.randint(1,12) * 10\n    \n    def is_max_damage(self, damage):\n        return damage == 120\n\n    def dodge_attack(self):\n        return random.randint(1, 5) == 1\n\n    def must_skip_turn_due_to_regeneration(self):\n        if self.regenerating == True:\n            print(f\"Wolverine [VIDA:{self.life_points}] tiene que regenerarse. No ataca en este turno\")\n            time.sleep(PAUSE_DURATION)\n            self.regenerating = False\n            return True\n        return False\n    \n\nclass Deadpool(SuperHero):\n    def calculate_attack_damage(self):\n        return random.randint(1,10) * 10\n    \n    def is_max_damage(self, damage):\n        return damage == 100\n\n    def dodge_attack(self):\n        return random.randint(1, 4) == 1\n\n    def must_skip_turn_due_to_regeneration(self):\n        if self.regenerating == True:\n            print(f\"Deadpool [VIDA:{self.life_points}] tiene que regenerarse. No ataca en este turno\")\n            time.sleep(PAUSE_DURATION)\n            self.regenerating = False\n            return True\n        return False\n    \n\nclass Battle:# Gestiona los turnos y la batalla en si.\n    def __init__(self, hero1: SuperHero, hero2: SuperHero):\n        self.heroes = [hero1, hero2]\n        random.shuffle(self.heroes)# Para que empiece una de forma aleatoria.\n\n    def check_active_battle(self):\n        for heroe in self.heroes:\n            if heroe.life_points == 0:\n                return False\n        return True\n\n    def start_battle(self):\n        turn = 1\n        aux_count = 1\n        while self.check_active_battle():\n            if aux_count % 2 != 0:\n                print(f\"TURNO {turn}:\")\n                turn += 1\n            active_heroe: SuperHero = self.heroes.pop(0)\n            print(f\"Turno de {active_heroe.__class__.__name__} [VIDA:{active_heroe.life_points}]\")\n            time.sleep(PAUSE_DURATION)\n            if active_heroe.must_skip_turn_due_to_regeneration():\n                self.heroes.append(active_heroe)\n            else:\n                attack_damage = active_heroe.calculate_attack_damage()\n                print(f\"{active_heroe.__class__.__name__} [VIDA:{active_heroe.life_points}] ataca con fuerza {attack_damage}\")\n                time.sleep(PAUSE_DURATION)\n                self.heroes[0].attack(attack_damage, active_heroe.is_max_damage(attack_damage))\n                self.heroes.append(active_heroe)\n            aux_count += 1\n        winner = [h for h in self.heroes if h.life_points > 0][0]\n        print(f\"\\n{winner.__class__.__name__} ha ganado la batalla con {winner.life_points} puntos de vida.\")\n\n\ndef main():\n    wolverine_life = int(input(\"Vida de Wolverine: \"))\n    deadpool_life = int(input(\"Vida de Deadpool: \"))\n    wolverine = Wolverine(wolverine_life)\n    deadpool = Deadpool(deadpool_life)\n    Battle(wolverine, deadpool).start_battle()\n\nmain()   "
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/python/javi-kl.py",
    "content": "from abc import ABC, abstractmethod\nimport random\nimport time\n\n\nclass Interfaz(ABC):\n    @abstractmethod\n    def __init__(self, vida) -> None:\n        self.vida = vida\n\n    @abstractmethod\n    def atacar(self) -> int:\n        pass\n\n    @abstractmethod\n    def evadir(self) -> bool:\n        pass\n\n    @abstractmethod\n    def devolver_vida(self) -> int:\n        pass\n\n    @abstractmethod\n    def recibir_daño(self, daño) -> None:\n        pass\n\n\nclass Wolverine(Interfaz):\n    def __init__(self, vida) -> None:\n        self.vida = vida\n\n    def atacar(self) -> int:\n        daño_aleatorio = random.randint(10, 120)\n        return daño_aleatorio\n\n    def evadir(self) -> bool:\n        num_evasion = random.randint(0, 100)\n        return num_evasion < 20\n\n    def devolver_vida(self) -> int:\n        return self.vida\n\n    def recibir_daño(self, daño) -> None:\n        self.vida -= daño\n\n\nclass Deadpool(Interfaz):\n    def __init__(self, vida) -> None:\n        self.vida = vida\n\n    def atacar(self) -> int:\n        daño_aleatorio = random.randint(10, 100)\n        return daño_aleatorio\n\n    def evadir(self) -> bool:\n        num_evasion = random.randint(0, 100)\n        return num_evasion < 25\n\n    def devolver_vida(self) -> int:\n        return self.vida\n\n    def recibir_daño(self, daño) -> None:\n        self.vida -= daño\n\n\nwolverine = Wolverine(500)\ndeadpool = Deadpool(500)\n\n\nclass Simulador:\n    def __init__(self) -> None:\n        self.turno = 0\n\n    def siguiente_turno(self):\n        print(\"Cambio de turno\")\n        time.sleep(1)\n        self.turno += 1\n\n    def omitir_turno(self):\n        print(\"Turno omitido por golpe critico\")\n        time.sleep(1)\n        self.turno += 2\n\n    def simular(self):\n        \"\"\"Si la vida de uno es menor a 0 finaliza el combate,\n        si el turno es par ataca Wolverino, si no Deadpool\"\"\"\n\n        while True:\n            vida_wolverine = wolverine.devolver_vida()\n            vida_deadpool = deadpool.devolver_vida()\n            if vida_deadpool <= 0:\n                print(\"Wolverine derroto a su oponente\")\n                break\n            elif vida_wolverine <= 0:\n                print(\"Deadpool derroto a su oponente\")\n                break\n            else:\n                print(\n                    f\"Puntos de vida\\nWolverine: {vida_wolverine}\\nDeadpool: {vida_deadpool}\"\n                )\n                print(f\"\\nTurno {self.turno}\")\n\n                if self.turno % 2 == 0:\n                    daño = wolverine.atacar()\n                    exito_evadir = deadpool.evadir()\n                    if exito_evadir:\n                        print(\"Deadpool ha evadido con exito\")\n                        Simulador.siguiente_turno(self)\n\n                    else:\n                        deadpool.recibir_daño(daño)\n\n                        if daño == 120:\n                            print(\"Wolverine inflinge golpe critico\")\n                            print(\"Volverá a atacar en el siguiente turno\")\n                            Simulador.omitir_turno(self)\n\n                        print(f\"Wolverine inflinge {daño} puntos de daño.\")\n                        Simulador.siguiente_turno(self)\n\n                else:\n                    daño = deadpool.atacar()\n                    exito_evadir = wolverine.evadir()\n                    if exito_evadir:\n                        print(\"Wolverine ha evadido con exito\")\n                        Simulador.siguiente_turno(self)\n\n                    else:\n                        wolverine.recibir_daño(daño)\n                        if daño == 100:\n                            print(\"Deadpool inflinge golpe critico\")\n                            print(\"Volverá a atacar en el siguiente turno\")\n                            Simulador.omitir_turno(self)\n\n                        print(f\"Deadpool inflinge {daño} puntos de daño.\")\n                        Simulador.siguiente_turno(self)\n\n\nsimulador = Simulador()\nsimulador.simular()\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/python/javierfiestasbotella.py",
    "content": "'''\n```\n/*\n * EJERCICIO:\n * ¡Deadpool y Wolverine se enfrentan en una batalla épica!\n * Crea un programa que simule la pelea y determine un ganador.\n * El programa simula un combate por turnos, donde cada protagonista posee unos\n * puntos de vida iniciales, un daño de ataque variable y diferentes cualidades\n * de regeneración y evasión de ataques.\n * Requisitos:\n * 1. El usuario debe determinar la vida inicial de cada protagonista.\n * 2. Cada personaje puede impartir un daño aleatorio:\n *    - Deadpool: Entre 10 y 100.\n *    - Wolverine: Entre 10 y 120.\n * 3. Si el daño es el máximo, el personaje que lo recibe no ataca en el\n * siguiente turno, ya que tiene que regenerarse (pero no aumenta vida).\n * 4. Cada personaje puede evitar el ataque contrario:\n *    - Deadpool: 25% de posibilidades.\n *    - Wolverine: 20% de posibilidades.\n * 5. Un personaje pierde si sus puntos de vida llegan a cero o menos.\n * Acciones:\n * 1. Simula una batalla.\n * 2. Muestra el número del turno (pausa de 1 segundo entre turnos).\n * 3. Muestra qué pasa en cada turno.\n * 4. Muestra la vida en cada turno.\n * 5. Muestra el resultado final.\n */'''\nimport random\nimport time\n\nclass Heroe:\n    def __init__(self,nombre,daño,defensa,puntos_vida=300):\n        self.nombre=nombre\n        self.daño=daño\n        self.defensa=defensa\n        self.puntos_vida=puntos_vida\n\n    def __str__(self):\n        return f'''\n        {self.nombre}\n        Daño: {self.daño}\n        Defensa: {self.defensa}%'''\n    \n    def ataque(self):\n        return random.randint(10, self.daño)\n    \n    def defensa(self):\n        return random.randint(1, int(10*(self.defensa/100)))\n    \n    def resta_vida(self,n):\n        self.puntos_vida-=n\n\n\n\n\nif __name__ == \"__main__\":\n    turno=1\n    final=False\n    vida_1=int(input('Introduce vida inicial de Deadpool: '))\n    vida_2=int(input('Introduce vida inicial de Wolverine: '))\n\n    Deadpool=Heroe('Deadpool',100,25,vida_1)\n    Wolverine=Heroe('Wolverine',120,20,vida_2)\n\n    print(f'''\n        Comienza La Batalla Wolverine VS Deadpool\n          \n    Deadpool comienza con {vida_1} puntos de vida\n    Wolverine comienza con {vida_2} puntos de vida   ''')\n\n    def lucha(heroe):\n        if heroe.ataque()==heroe.daño:\n            return True\n        else:\n            return heroe.ataque()\n    \n    def golpe_defensa(h1,h2): \n        l=lucha(h1)\n        if l==True:\n            golpe_defensa(h1,h2)\n            h2.resta_vida(l)\n            time.sleep(1) \n            print(f'''{h1.nombre} Golpéa con el máximo de fuerza \n                  dejando a {h2.nombre} con {h2.puntos_vida} puntos de vida.\n                  Repite el turno mientras {h2.nombre} se regenera.''')\n            time.sleep(1)\n            \n                \n            print()\n        else:\n            d=l-h2.defensa\n            h2.resta_vida(d)\n            time.sleep(1)\n            print(f'''{h1.nombre} Golpéa con {l} de fuerza \n                  dejando a {h2.nombre} con {h2.puntos_vida} puntos de vida.\n                  Ahora el turno es para {h2.nombre}.''') \n            time.sleep(1) \n            \n                \n            print()\n\n    while final==False:\n        golpe_defensa(Deadpool,Wolverine)\n        if Wolverine.puntos_vida<=0:\n            print(f'{Deadpool.nombre} GANADOR!!!!')\n            final=True\n            break\n\n        golpe_defensa(Wolverine,Deadpool)\n        if Deadpool.puntos_vida<=0:\n            print(f'{Wolverine.nombre} GANADOR!!!!')\n            final=True \n            break\n    print('FINAL DEL JUEGO')\n    print(f'''\n{Deadpool.nombre} --> {Deadpool.puntos_vida}\n{Wolverine.nombre} --> {Wolverine.puntos_vida}''')\n\n\n\n    "
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/python/juanmax2.py",
    "content": "\"\"\"\n * EJERCICIO:\n * ¡Deadpool y Wolverine se enfrentan en una batalla épica!\n * Crea un programa que simule la pelea y determine un ganador.\n * El programa simula un combate por turnos, donde cada protagonista posee unos\n * puntos de vida iniciales, un daño de ataque variable y diferentes cualidades\n * de regeneración y evasión de ataques.\n * Requisitos:\n * 1. El usuario debe determinar la vida inicial de cada protagonista.\n * 2. Cada personaje puede impartir un daño aleatorio:\n *    - Deadpool: Entre 10 y 100.\n *    - Wolverine: Entre 10 y 120.\n * 3. Si el daño es el máximo, el personaje que lo recibe no ataca en el\n * siguiente turno, ya que tiene que regenerarse (pero no aumenta vida).\n * 4. Cada personaje puede evitar el ataque contrario:\n *    - Deadpool: 25% de posibilidades.\n *    - Wolverine: 20% de posibilidades.\n * 5. Un personaje pierde si sus puntos de vida llegan a cero o menos.\n * Acciones:\n * 1. Simula una batalla.\n * 2. Muestra el número del turno (pausa de 1 segundo entre turnos).\n * 3. Muestra qué pasa en cada turno.\n * 4. Muestra la vida en cada turno.\n * 5. Muestra el resultado final.\n\"\"\"\nimport random\nimport time\n\ndeadpool_health = 1000\nwolwerine_health = 1000\n\nturn = 0\nregenerate = False\ncontinuar = True\nwhile continuar == True:\n    \n    turn += 1\n    print(f\"Turno: {turn}\")\n    # Deadpool ataca\n    if regenerate:\n        print(\"Deadpool se esta regenerando y no ataca\")\n        regenerate = False\n    elif random.random() > 0.2:\n        deadpool_damage = random.randint(10, 100)\n        print(f\"Deadpool inflinge {deadpool_damage} puntos de daño\")\n    \n        if deadpool_damage == 100:\n            regenerate = True\n            print(\"Golpe crítico de Deadpool, wolwerine no atacara en el siguiente turno\")\n        wolwerine_health -= deadpool_damage\n    \n        if wolwerine_health <= 0:\n            continuar = False\n        else:\n            print(f\"Vida actual de Wolwerine {wolwerine_health}\")\n    else:\n        print(\"Wolwerine ha esquivado el ataque!\")\n     \n        \n    # Wolwerine ataca\n    if regenerate:\n        print(\"Wolverine se esta regenerando y no ataca\")\n        regenerate = False\n        \n    elif random.random() > 0.25:\n        wolwerine_damage = random.randint(10, 120)\n        print(f\"Wolverine inflinge {wolwerine_damage} puntos de daño\")\n    \n        if wolwerine_damage == 120:\n            regenerate = True\n            print(\"Golpe crítico de Wolwerine, Deadpool no atacara en el siguiente turno\")\n        deadpool_health -= wolwerine_damage\n    \n        if deadpool_health <= 0:\n             continuar = False\n        else:\n            print(f\"Vida actual de Deadpool {deadpool_health}\")\n    else:\n        print(\"Deadpool ha esquivado el ataque!\")\n    \n    time.sleep(2)\n    \nif deadpool_health > 0:\n    print(\"Deadpool gana la batalla\")\nelse:\n    print(\"Wolwerine gana la batalla\")"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/python/juanmjimenezs.py",
    "content": "\"\"\"\n * EJERCICIO:\n * ¡Deadpool y Wolverine se enfrentan en una batalla épica!\n * Crea un programa que simule la pelea y determine un ganador.\n * El programa simula un combate por turnos, donde cada protagonista posee unos\n * puntos de vida iniciales, un daño de ataque variable y diferentes cualidades\n * de regeneración y evasión de ataques.\n * Requisitos:\n * 1. El usuario debe determinar la vida inicial de cada protagonista.\n * 2. Cada personaje puede impartir un daño aleatorio:\n *    - Deadpool: Entre 10 y 100.\n *    - Wolverine: Entre 10 y 120.\n * 3. Si el daño es el máximo, el personaje que lo recibe no ataca en el\n * siguiente turno, ya que tiene que regenerarse (pero no aumenta vida).\n * 4. Cada personaje puede evitar el ataque contrario:\n *    - Deadpool: 25% de posibilidades.\n *    - Wolverine: 20% de posibilidades.\n * 5. Un personaje pierde si sus puntos de vida llegan a cero o menos.\n * Acciones:\n * 1. Simula una batalla.\n * 2. Muestra el número del turno (pausa de 1 segundo entre turnos).\n * 3. Muestra qué pasa en cada turno.\n * 4. Muestra la vida en cada turno.\n * 5. Muestra el resultado final.\n\"\"\"\n\nfrom random import randint\nimport time\n\nclass Character:\n    def __init__(self, name, live_points, max_damage, evasion):\n        self.name = name\n        self.live_points = live_points\n        self.max_damage = max_damage\n        self.evasion = evasion\n\n    def attack(self, target):\n        time.sleep(1)\n        damage = randint(10, self.max_damage)\n        print(f\"{self.name} ataca a {target.name} con un daño potencial de {damage} puntos.\")\n        target.take_damage(damage)\n    \n    def take_damage(self, damage):\n        if randint(0, 100) > self.evasion * 100:\n            self.live_points -= damage\n            print(f\"{self.name} recibe {damage} puntos de daño.\")\n        else:\n            print(f\"{self.name} esquiva el ataque.\")\n\nclass Game:\n    def __init__(self, player1, player2):\n        self.player1 = player1\n        self.player2 = player2\n        self.turn = 1\n\n    def play(self):\n        while self.player1.live_points > 0 and self.player2.live_points > 0:\n            print(f\"Turno {self.turn}\")\n            self.player1.attack(self.player2)\n            if self.player2.live_points > 0:\n                self.player2.attack(self.player1)\n            self.display_status()\n            self.turn += 1\n\n    def display_status(self):\n        print(f\"{self.player1.name}: {self.player1.live_points} puntos de vida\")\n        print(f\"{self.player2.name}: {self.player2.live_points} puntos de vida\")\n\n        if self.player1.live_points <= 0 or self.player2.live_points <= 0:\n            if self.player1.live_points <= 0 and self.player2.live_points <= 0:\n                print(\"Ambos jugadores han muerto.\")\n            elif self.player1.live_points <= 0:\n                print(f\"{self.player1.name} ha muerto.\")\n            elif self.player2.live_points <= 0:\n                print(f\"{self.player2.name} ha muerto.\")\n\n\nprint(\"Esta es la épica batalla entre Deadpool y Wolverine!\")\n# Asking for Deadpool life score\ndeadpool_live_points = int(input(\"Por favor, ingresa los puntos de vida para Deadpool: \"))\n# Asking for Wolverine life score\nwolverine_live_points = int(input(\"Por favor, ingresa los puntos de vida para Wolverine: \"))\n\n# Creating characters\ndeadpool = Character(\"Deadpool\", deadpool_live_points, 100, 0.25)\nwolverine = Character(\"Wolverine\", wolverine_live_points, 120, 0.20)\ngame = Game(deadpool, wolverine)\ngame.play()\nprint(\"¡El combate ha terminado!\")\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/python/juanppdev.py",
    "content": "\"\"\"\n * EJERCICIO:\n * ¡Deadpool y Wolverine se enfrentan en una batalla épica!\n * Crea un programa que simule la pelea y determine un ganador.\n * El programa simula un combate por turnos, donde cada protagonista posee unos\n * puntos de vida iniciales, un daño de ataque variable y diferentes cualidades\n * de regeneración y evasión de ataques.\n * Requisitos:\n * 1. El usuario debe determinar la vida inicial de cada protagonista.\n * 2. Cada personaje puede impartir un daño aleatorio:\n *    - Deadpool: Entre 10 y 100.\n *    - Wolverine: Entre 10 y 120.\n * 3. Si el daño es el máximo, el personaje que lo recibe no ataca en el\n * siguiente turno, ya que tiene que regenerarse (pero no aumenta vida).\n * 4. Cada personaje puede evitar el ataque contrario:\n *    - Deadpool: 25% de posibilidades.\n *    - Wolverine: 20% de posibilidades.\n * 5. Un personaje pierde si sus puntos de vida llegan a cero o menos.\n * Acciones:\n * 1. Simula una batalla.\n * 2. Muestra el número del turno (pausa de 1 segundo entre turnos).\n * 3. Muestra qué pasa en cada turno.\n * 4. Muestra la vida en cada turno.\n * 5. Muestra el resultado final.\n\"\"\"\n\nimport random\nimport time\nimport json\n\nclass Character:\n    def __init__(self, name, min_damage, max_damage, evade_chance):\n        self.name = name\n        self.min_damage = min_damage\n        self.max_damage = max_damage\n        self.evade_chance = evade_chance\n        self.health = 0\n\n    def set_health(self, health):\n        self.health = health\n\n    def attack(self):\n        return random.randint(self.min_damage, self.max_damage)\n\n    def evade(self):\n        return random.random() < self.evade_chance\n\ndef simulate_battle(deadpool, wolverine):\n    turn = 1\n    while deadpool.health > 0 and wolverine.health > 0:\n        print(f\"Turno {turn}\")\n        if turn % 2 != 0:\n            attacker, defender = deadpool, wolverine\n        else:\n            attacker, defender = wolverine, deadpool\n\n        if defender.evade():\n            print(f\"{defender.name} evade el ataque de {attacker.name}!\")\n        else:\n            damage = attacker.attack()\n            defender.health -= damage\n            print(f\"{attacker.name} ataca a {defender.name} y causa {damage} puntos de daño.\")\n            if damage == attacker.max_damage:\n                print(f\"{defender.name} está aturdido y no puede atacar en el siguiente turno.\")\n                turn += 1\n\n        print(f\"Vida de {deadpool.name}: {deadpool.health}\")\n        print(f\"Vida de {wolverine.name}: {wolverine.health}\")\n        time.sleep(1)\n        turn += 1\n\n    if deadpool.health <= 0:\n        print(\"¡Wolverine gana la batalla!\")\n    elif wolverine.health <= 0:\n        print(\"¡Deadpool gana la batalla!\")\n\ndef main():\n    deadpool = Character(\"Deadpool\", 10, 100, 0.25)\n    wolverine = Character(\"Wolverine\", 10, 120, 0.20)\n\n    deadpool_health = int(input(\"Introduce la vida inicial de Deadpool: \"))\n    wolverine_health = int(input(\"Introduce la vida inicial de Wolverine: \"))\n\n    deadpool.set_health(deadpool_health)\n    wolverine.set_health(wolverine_health)\n\n    simulate_battle(deadpool, wolverine)\n\n    data = {\n        \"Deadpool\": deadpool.health,\n        \"Wolverine\": wolverine.health\n    }\n\n    with open(\"battle_results.json\", \"w\") as file:\n        json.dump(data, file)\n\n    print(\"Los resultados de la batalla se han guardado en 'battle_results.json'.\")\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/python/kenysdev.py",
    "content": "# ╔═════════════════════════════════════╗\n# ║ Autor:  Kenys Alvarado              ║\n# ║ GitHub: https://github.com/Kenysdev ║\n# ║ 2024 -  Python                      ║\n# ╚═════════════════════════════════════╝\n\n# ---------------------------------------\n# 32 * BATALLA DEADPOOL Y WOLVERINE\n# ---------------------------------------\n\"\"\"\n * EJERCICIO:\n * ¡Deadpool y Wolverine se enfrentan en una batalla épica!\n * Crea un programa que simule la pelea y determine un ganador.\n * El programa simula un combate por turnos, donde cada protagonista posee unos\n * puntos de vida iniciales, un daño de ataque variable y diferentes cualidades\n * de regeneración y evasión de ataques.\n * Requisitos:\n * 1. El usuario debe determinar la vida inicial de cada protagonista.\n * 2. Cada personaje puede impartir un daño aleatorio:\n *    - Deadpool: Entre 10 y 100.\n *    - Wolverine: Entre 10 y 120.\n * 3. Si el daño es el máximo, el personaje que lo recibe no ataca en el\n * siguiente turno, ya que tiene que regenerarse (pero no aumenta vida).\n * 4. Cada personaje puede evitar el ataque contrario:\n *    - Deadpool: 25% de posibilidades.\n *    - Wolverine: 20% de posibilidades.\n * 5. Un personaje pierde si sus puntos de vida llegan a cero o menos.\n * Acciones:\n * 1. Simula una batalla.\n * 2. Muestra el número del turno (pausa de 1 segundo entre turnos).\n * 3. Muestra qué pasa en cada turno.\n * 4. Muestra la vida en cada turno.\n * 5. Muestra el resultado final.\n\"\"\"\n\n# NOTA: Estoy intentando practicar los principios SOLID. XD 😂\n\n#__________________________\nfrom abc import ABC, abstractmethod\nfrom typing import Type\nfrom typing import Dict, List, Tuple, Any\nimport random\nimport time\n\n# ---------------------------------------\n# ABSTRACIONES\n# ---------------------------------------\n#__________________________\nclass AbcGlobalConfig(ABC):\n    \"\"\"Contrato sobre las constantes globales\"\"\"\n    @property\n    @abstractmethod\n    def turn_interval(self) -> int:\n        \"\"\"Tiempo de espera en segundos entre cada turno.\"\"\"\n        pass\n\n    @property\n    @abstractmethod\n    def minimun_hp(self) -> str:\n        \"\"\"Mínima cantidad de vida inicial permitida.\"\"\"\n        pass\n\n    @property\n    @abstractmethod\n    def characters(self) -> Dict[str, Dict]:\n        \"\"\"\n        Diccionario de personajes, con sus habilidades, Daño posible, Probabilidad de defensa.\n        {\"Character\": {\"attacks\": [\"Attack1\", \"Attack2\"], \"damage_range\": (10, 100), \"defense_chance\": 0.25}}\n        \"\"\"\n        pass\n\n    @property\n    @abstractmethod\n    def menu(self) -> str:\n        \"\"\"Acciones del menú principal.\"\"\"\n        pass\n\n#__________________________\nclass AbcInput(ABC):\n    \"\"\"Contrato sobre la entra de datos.\"\"\"\n    def get(self, msg: str, type_: str) -> str | int:\n        \"\"\"Retornará un dato que no debe ser None y garantizará el tipo de dato solicitado.\"\"\"\n        pass\n\n#__________________________\nclass AbcCharacter(ABC):\n    \"\"\"Contrato sobre los datos y metodos de un personaje que participara en la batalla.\"\"\"\n    def __init__(self, name: str, hp:int, attributes: Dict[str, Any]) -> None:\n        pass\n\n    @property\n    @abstractmethod\n    def name(self) -> str:\n        \"\"\"Nombre del personaje.\"\"\"\n        pass\n\n    @property\n    @abstractmethod\n    def attacks(self) -> List[str]:\n        \"\"\"Lista de ataques disponibles para el personaje.\"\"\"\n        pass\n\n    @property\n    @abstractmethod\n    def damage_range(self) -> Tuple[int, int]:\n        \"\"\"Rango de daño que el personaje puede infligir.\"\"\"\n        pass\n\n    @property\n    @abstractmethod\n    def defense_chance(self) -> float:\n        \"\"\"Probabilidad de que el personaje se defienda de un ataque.\"\"\"\n        pass\n    \n    @property\n    @abstractmethod\n    def hp(self) -> int:\n        \"\"\"Puntos de vida del personaje.\"\"\"\n        pass\n\n    @property\n    @abstractmethod\n    def can_attack(self) -> bool:\n        \"\"\"Indica si el personaje puede atacar en el turno actual.\"\"\"\n        pass\n\n    @hp.setter\n    @abstractmethod\n    def hp(self, value: int) -> None:\n        \"\"\"Modifica los puntos de vida del personaje.\"\"\"\n        pass\n\n    @can_attack.setter\n    @abstractmethod\n    def can_attack(self, value: bool) -> None:\n        \"\"\"Modifica la capacidad del personaje para atacar.\"\"\"\n        pass\n\n    @abstractmethod\n    def attack(self) -> int:\n        \"\"\"\n        Verifica si puede atacar usando '@can_attack.setter'.\n        Imprime el ataque realizado y cantidad de daño.\n        Realiza un ataque y devuelve el daño infligido.\n        \"\"\"\n        pass\n\n    @abstractmethod\n    def defend(self) -> bool:\n        \"\"\"Determina si el personaje puede defenderse.\"\"\"\n        pass\n\n#__________________________\nclass AbsBattleStrategy(ABC):\n    \"\"\"Lógica para la batalla.\"\"\"\n    @abstractmethod\n    def execute(self, attacker: 'AbcCharacter', defender: 'AbcCharacter') -> bool:\n        \"\"\"Ejecutará la estrategia \"\"\"\n        pass\n\n#__________________________\nclass AbcFeatures(ABC):\n    \"\"\"Contrato sobre las caracteristicas del programa las cuales usaran(AbcGlobalConfig, AbcInput, AbcCharacter y AbsBattleStrategy).\"\"\"\n    def __init__(self, gc: Type[AbcGlobalConfig], input_: Type[AbcInput], \n    character: Type[AbcCharacter], battle_strategy: Type[AbsBattleStrategy]) -> None:\n        pass\n\n    @abstractmethod\n    def get_character(self, msg: str) -> Tuple[str, int, Dict[str, Any]]:\n        \"\"\"\n        Retorna los personajes y su vida.\n        \"\"\"\n        pass\n    \n    @abstractmethod\n    def show_hp(self) -> None:\n        \"\"\"Mostrara la vida de ambos personajes.\"\"\"\n        pass\n\n    @abstractmethod\n    def battle(self) -> None:\n        \"\"\"\n        Llevará a cabo el turno de la batalla. Utilizando actions() y show_hp()\n        También será donde se establezca el tiempo de espera de cada turno.\n        \"\"\"\n        pass\n\n    @abstractmethod\n    def start_simulation(self) -> None:\n        \"\"\"Creará la simulación, utilizando get_character() y battle().\"\"\"\n        pass\n\n# ---------------------------------------\n# IMPLEMENTACIÓN DE ABSTRACCIONES\n# ---------------------------------------\n#__________________________\nclass DefaultConfig(AbcGlobalConfig):\n    \"\"\"Constantes globales\"\"\"\n    TIME: int = 2 # segundos\n\n    MINIMUM_HP = 200\n\n    CHARACTERS: Dict[str, Dict] = {\n        \"Deadpool\": {\n            \"attacks\": [\"Con arma.\", \"Cuerpo a cuerpo.\", \"Con ataque imprudente.\"],\n            \"damage_range\": (10, 100),\n            \"defense_chance\": 0.25\n        },\n        \"Wolverine\": {\n            \"attacks\": [\"Con garras de adamantium.\", \"Con arma.\", \"Cuerpo a cuerpo.\"],\n            \"damage_range\": (10, 120),\n            \"defense_chance\": 0.20\n        }\n\n        # Sí, se desea incorporar más personajes, disponibles.\n    }\n\n    MENU: str = \"\"\"\nSIMULADOR DE BATALLAS:\n------------------------------------------\n| 1. Simular una batalla | 2. Salir      |  \n------------------------------------------\"\"\"\n\n    @property\n    def turn_interval(self) -> int:\n        return self.TIME\n\n    @property\n    def minimun_hp(self) -> str:\n        return self.MINIMUM_HP\n\n    @property\n    def characters(self) -> dict:\n        return self.CHARACTERS\n\n    @property\n    def menu(self) -> str:\n        return self.MENU\n\n#__________________________\nclass DefaultInput(AbcInput):\n    \"\"\"Solicitud de entrada.\"\"\"\n    def get(self, msg: str, type_: str) -> str | int:\n        while True:\n            txt = input(msg)\n            \n            if type_ == 'str':\n                if isinstance(txt, str) and len(txt) > 0:\n                    return txt\n                else:\n                    print(\"La entrada no puede estar vacía.\")\n            \n            elif type_ == 'int':\n                if txt.isdigit():\n                    return int(txt)\n                else:\n                    print(\"Por favor, ingresa un número entero válido.\")\n            \n            else:\n                print(\"Tipo de dato no soportado.\")\n\n#__________________________\nclass DefaultCharacter(AbcCharacter):\n    \"\"\"Datos y metodos de un personaje que participara en la batalla.\"\"\"\n    def __init__(self, name: str, hp:int, attributes: Dict[str, Any]) -> None:\n        self._name: str = name\n        self._hp: int = hp\n        self._attacks: List[str] = attributes.get('attacks', [])\n        self._damage_range: Tuple[int, int] = attributes.get('damage_range', (0, 0))\n        self._defense_chance: float = attributes.get('defense_chance', 0.0)\n        self._can_attack: bool = True\n    \n    @property\n    def name(self) -> str:\n        return self._name\n\n    @property\n    def attacks(self) -> List[str]:\n        return self._attacks\n\n    @property\n    def damage_range(self) -> Tuple[int, int]:\n        return self._damage_range\n\n    @property\n    def defense_chance(self) -> float:\n        return self._defense_chance\n\n    @property\n    def hp(self) -> int:\n        return self._hp\n\n    @hp.setter\n    def hp(self, value: int) -> None:\n        self._hp = value\n\n    @property\n    def can_attack(self) -> bool:\n        return self._can_attack\n\n    @can_attack.setter\n    def can_attack(self, value: bool) -> None:\n        self._can_attack = value\n    \n    def attack(self) -> int:\n        if self.can_attack:\n            selected_attack = random.choice(self.attacks)\n            damage: int = random.randint(self.damage_range[0], self.damage_range[1])\n            print(f\"|'{self._name}' ataca '{selected_attack}' Produciendo un: '-{damage}' 👊|\")\n            return damage\n        else:\n            print(f\"|'{self._name}' se está regenerando y no ataca. 😴|\")\n            return 0\n\n    def defend(self) -> bool:\n        # random.random() genera un número decimal entre 0.0 y 1.0\n        # tendra un self._defense_chance % de poder defenderse.\n        if random.random() < self.defense_chance:\n            print(f\"|'{self.name}' logró defenderse. 🛡️|\")\n            return True\n        else:\n            print(f\"|'{self.name}' no pudo bloquear el ataque. 🤕|\")\n            return False\n\n#__________________________\nclass DefaultBattleStrategy(AbsBattleStrategy):\n    def execute(self, attacker: 'AbcCharacter', defender: 'AbcCharacter') -> bool:\n        damage = attacker.attack()\n        \n        if damage == attacker.damage_range[1]:\n            print(f\"|'{defender.name}' 🚨recibió un ataque crítico y no podrá atacar.🚨|\")\n            defender.can_attack = False\n        \n        if attacker.can_attack:\n            if not defender.defend():\n                defender.hp -= damage\n        else:\n            attacker.can_attack = True\n        \n        if defender.hp <= 0:\n            print(\"\\n____________________________\")\n            print(f\"|'{attacker.name}' 🏆 gana la batalla. 🏆|\")\n            return False\n        \n        return True\n\n#__________________________\nclass DefaultFeatures(AbcFeatures):\n    \"\"\"Caracteristicas del programa.\"\"\"\n    def __init__(self, gc: Type[AbcGlobalConfig], input_: Type[AbcInput], \n    character: Type[AbcCharacter], battle_strategy: Type[AbsBattleStrategy]) -> None:\n        super().__init__(gc, input_, character, battle_strategy)\n        self._gc: AbcGlobalConfig = gc()\n        self._input: AbcInput = input_()\n        self._new_character: AbcCharacter = character\n        self._battle_strategy = battle_strategy()\n        self.character1: AbcCharacter = character\n        self.character2: AbcCharacter = character\n\n    def get_character(self, msg: str) -> Tuple[str, int, Dict[str, Any]]:\n        while True:\n            #________\n            index: int = self._input.get(msg, type_=\"int\")\n            keys: list = list(self._gc.characters.keys())\n\n            #________\n            if not (0 <= index < len(keys)):\n                print(\"Número de personaje incorrecto.\")\n                continue  # Volver a solicitar\n            \n            #________\n            if keys[index] == self.character1.name:\n                print(\"El personaje ya fue utilizado.\")\n                continue\n            \n            #________\n            hp: int = self._input.get(f\"Establecer una vida >= que '{self._gc.minimun_hp}' : \", \"int\")\n            if hp < self._gc.minimun_hp:\n                print(f\"La vida debe ser mayor a '{self._gc.minimun_hp}'.\")\n                continue\n            \n            #________\n            name: str = keys[index]\n            attributes: Dict[str, Any] = self._gc.characters[name]\n            return name, hp, attributes\n\n    def show_hp(self) -> None:\n        print(\"____________________________\")\n        print(f\"|{self.character1.name}: ❤️ {self.character1.hp}| |{self.character2.name}: ❤️ {self.character2.hp}|\")\n\n    def battle(self):\n        turn: int = 1\n        while True:\n            print(f\"\\n----------------------------\\nTurno #{turn}\\n----------------------------\")\n\n            # Ataque de personaje #1 hacia #2\n            self.show_hp()\n            if not self._battle_strategy.execute(attacker=self.character1, defender=self.character2):\n                break\n            \n            # Ataque de personaje #2 hacia #1\n            self.show_hp()\n            if not self._battle_strategy.execute(attacker=self.character2, defender=self.character1):\n                break\n\n            turn += 1\n            time.sleep(self._gc.turn_interval)\n        \n        self.show_hp()\n\n    def start_simulation(self) -> None:\n        #________\n        print(\"Personajes disponibles:\")\n        for i, name in enumerate(self._gc.characters):\n            print(f\"{i}. {name}\")\n\n        #________\n        dt = self.get_character(\"'Primer' personaje: \")\n        name, hp, attributes = dt\n        self.character1 = self._new_character(name, hp, attributes)\n\n        #________\n        dt = self.get_character(\"'Segundo' personaje: \")\n        name, hp, attributes = dt\n        self.character2 = self._new_character(name, hp, attributes)\n\n        #________\n        # Iniciar batalla\n        self.battle()\n\n        #________\n        self.character1 = self._new_character # Sin instancia\n        self.character2 = self._new_character\n        print(self._gc.menu)\n\n# ---------------------------------------\n# INYECCIÓN DE DEPENDENCIAS Y UTILIZACIÓN\n# ---------------------------------------\n#__________________________\nclass Program():\n    def __init__(self) -> None:\n\n        self.__gc: AbcGlobalConfig = DefaultConfig\n        self.__input: AbcInput = DefaultInput\n        self.__Character: AbcCharacter = DefaultCharacter\n        self.__battle_strategy: AbsBattleStrategy = DefaultBattleStrategy\n        self._ft: AbcFeatures = DefaultFeatures(self.__gc, self.__input, self.__Character, self.__battle_strategy)\n        \n    def run(self) -> None:\n\n        print(self._ft._gc.menu)\n        while True:\n            option: int = self._ft._input.get(msg=\"\\nOpción: \", type_=\"int\")\n            match option:\n                case 1: self._ft.start_simulation()\n                case 2: print(\"Adios\"); break\n                case _: print(\"Seleccionar de '1 a 2'\")\n\n#__________________________\nif __name__ == \"__main__\":\n    program = Program()\n    program.run()\n\n# NOTA: Solo estoy intentando practicar los principios SOLID. XD 😂\n\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/python/lesclaz.py",
    "content": "# EJERCICIO:\n# ¡Deadpool y Wolverine se enfrentan en una batalla épica!\n# Crea un programa que simule la pelea y determine un ganador.\n# El programa simula un combate por turnos, donde cada protagonista posee unos\n# puntos de vida iniciales, un daño de ataque variable y diferentes cualidades\n# de regeneración y evasión de ataques.\n# Requisitos:\n# 1. El usuario debe determinar la vida inicial de cada protagonista.\n# 2. Cada personaje puede impartir un daño aleatorio:\n#    - Deadpool: Entre 10 y 100.\n#    - Wolverine: Entre 10 y 120.\n# 3. Si el daño es el máximo, el personaje que lo recibe no ataca en el\n# siguiente turno, ya que tiene que regenerarse (pero no aumenta vida).\n# 4. Cada personaje puede evitar el ataque contrario:\n#    - Deadpool: 25% de posibilidades.\n#    - Wolverine: 20% de posibilidades.\n# 5. Un personaje pierde si sus puntos de vida llegan a cero o menos.\n# Acciones:\n# 1. Simula una batalla.\n# 2. Muestra el número del turno (pausa de 1 segundo entre turnos).\n# 3. Muestra qué pasa en cada turno.\n# 4. Muestra la vida en cada turno.\n# 5. Muestra el resultado final.\n\nimport dataclasses\nfrom random import choice, randint\nimport time\n\n\n# Representa un peleador.\n@dataclasses.dataclass\nclass Fighter:\n\n    name: str\n    min_damage: int\n    max_damage: int\n    evasion_possibilities: int\n    health_regeneration: int\n    life_points: int\n    turns: int = 0\n    attacks: int = 0\n    max_damage_inflicted: int = 0\n    min_damage_inflicted: int = 0\n    damage_inflicted: int = 0\n\n\n# Representa un turno en la pelea.\n@dataclasses.dataclass\nclass Turn:\n\n    number: int\n    attacker: Fighter\n    damage: int\n\n# Representa la pelea\nclass Fight:\n\n    def __init__(self, fighter_one: Fighter, fighter_two: Fighter) -> None:\n        self.fighter_one = fighter_one\n        self.fighter_two = fighter_two\n        self.current_turn = Turn(1, choice([fighter_one, fighter_two]), 0)\n        self.previous_turn = Turn(\n            0,\n            fighter_one if self.current_turn.attacker == fighter_two else fighter_two,\n            0\n        )\n\n    @property\n    def fighter_attacker(self) -> Fighter:\n        return self.fighter_one if self.current_turn.attacker == self.fighter_one else self.fighter_two\n\n    def __attempt_health_regeneration(self) -> None:\n        health_generated = randint(0, self.fighter_attacker.health_regeneration + 1)\n        if health_generated > 0:\n            self.fighter_attacker.life_points += health_generated\n            print(f\"Se regenera y recupera {health_generated} puntos de vida.\")\n\n    def __to_attack(self) -> int:\n        damage_receiver = self.fighter_one if self.previous_turn.attacker == self.fighter_one else self.fighter_two\n        self.current_turn.damage = randint(10, self.current_turn.attacker.max_damage + 1)\n        if randint(1, self.previous_turn.attacker.evasion_possibilities) == 1:\n            return 0\n        else:\n            damage_receiver.life_points -= self.current_turn.damage\n            return self.current_turn.damage\n\n    def __switch_turn(self):\n        proximo = self.previous_turn.attacker\n        self.previous_turn = self.current_turn\n        self.current_turn = Turn(self.previous_turn.number + 1, proximo, 0)\n\n    def comment_turn(self) -> None:\n        if self.previous_turn.number == 0:\n            print(\"Comienza la pelea!\")\n\n        self.fighter_attacker.turns += 1\n\n        print(f\"El atacante del turno {self.current_turn.number} es {self.fighter_attacker.name}.\")\n\n        if self.previous_turn.damage == self.previous_turn.attacker.max_damage:\n            print(f\"Pero no ataca por recibir el daño máximo en el turno anterior.\\n\\n\")\n            self.__switch_turn()\n            return\n        else:\n            self.__attempt_health_regeneration()\n            damage_inflicted = self.__to_attack()\n            if damage_inflicted == 0:\n                print(f\"{self.current_turn.attacker.name} ataca pero {self.previous_turn.attacker.name} logra esquivarlo.\\n\\n\")\n            else:\n                print(f\"{self.current_turn.attacker.name} ataca y provoca un daño de {self.current_turn.damage}.\")\n                self.fighter_attacker.damage_inflicted += damage_inflicted\n                if damage_inflicted > self.fighter_attacker.max_damage_inflicted:\n                    self.fighter_attacker.max_damage_inflicted = damage_inflicted\n                if damage_inflicted < self.fighter_attacker.min_damage_inflicted or self.fighter_attacker.min_damage_inflicted == 0:\n                    self.fighter_attacker.min_damage_inflicted = damage_inflicted\n                print(\n                    f\"Los puntos de vida actual de {self.previous_turn.attacker.name} son \"\n                    f\"{self.previous_turn.attacker.life_points if self.previous_turn.attacker.life_points > 0 else 0}.\\n\\n\"\n                )\n\n            self.fighter_attacker.attacks += 1\n            if self.fighter_one.life_points > 0 and self.fighter_two.life_points > 0:\n                self.__switch_turn()\n\n\nif __name__ == '__main__':\n\n    def print_fighter_statistics(fighter: Fighter) -> None:\n        print(f\"Estadisticas de {fighter.name}:\")\n        print(f\"Total de daño infringido al rival :: {fighter.damage_inflicted} en {fighter.turns} turnos.\")\n        print(f\"Ataque más poderoso :: {fighter.max_damage_inflicted} puntos.\")\n        print(f\"Ataque más debil :: {fighter.min_damage_inflicted} puntos.\")\n\n    deadpool_life_points = int(input(\"Introduzca los puntos de vida inicial para Deadpool: \"))\n    wolverine_life_points = int(input(\"Introduzca los puntos de vida inicial para Wolverine: \"))\n\n    # Peleadores\n    deadpool = Fighter(\"Deadpool\", 10, 100, 5, 70, deadpool_life_points)\n    wolverine = Fighter(\"Wolverine\", 10, 120, 6, 70, wolverine_life_points)\n\n    # La pelea\n    fight = Fight(deadpool, wolverine)\n\n    while fight.fighter_one.life_points > 0 and fight.fighter_two.life_points > 0:\n        fight.comment_turn()\n        time.sleep(1)\n\n    print(\n        f\"{fight.current_turn.attacker.name} es el ganador de la pelea! \"\n        f\"Con {fight.current_turn.attacker.life_points} puntos de vida restantes.\\n\\n\"\n    )\n    print_fighter_statistics(fight.current_turn.attacker)\n    print()\n    print_fighter_statistics(fight.previous_turn.attacker)\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/python/mhayhem.py",
    "content": "# @Author Daniel Grande (Mhayhem)\n\nimport random\nimport os\nfrom time import sleep\n\n# EJERCICIO:\n# ¡Deadpool y Wolverine se enfrentan en una batalla épica!\n# Crea un programa que simule la pelea y determine un ganador.\n# El programa simula un combate por turnos, donde cada protagonista posee unos\n# puntos de vida iniciales, un daño de ataque variable y diferentes cualidades\n# de regeneración y evasión de ataques.\n# Requisitos:\n# 1. El usuario debe determinar la vida inicial de cada protagonista.\n# 2. Cada personaje puede impartir un daño aleatorio:\n#    - Deadpool: Entre 10 y 100.\n#    - Wolverine: Entre 10 y 120.\n# 3. Si el daño es el máximo, el personaje que lo recibe no ataca en el\n# siguiente turno, ya que tiene que regenerarse (pero no aumenta vida).\n# 4. Cada personaje puede evitar el ataque contrario:\n#    - Deadpool: 25% de posibilidades.\n#    - Wolverine: 20% de posibilidades.\n# 5. Un personaje pierde si sus puntos de vida llegan a cero o menos.\n# Acciones:\n# 1. Simula una batalla.\n# 2. Muestra el número del turno (pausa de 1 segundo entre turnos).\n# 3. Muestra qué pasa en cada turno.\n# 4. Muestra la vida en cada turno.\n# 5. Muestra el resultado final.\n\nclass Fighter:\n    def __init__(self, name: str, life: int, damage: int, evasion_value: float):\n        self.name = name.capitalize()\n        self.life = life\n        self.damage = damage\n        self.evasion_value = evasion_value\n\n    def attack(self, stunned: bool):\n        stunt = False\n        damage = random.randint(10, self.damage)\n        if stunned:\n            print(f\"{self.name} esta regenerandose, no puede atacar.\")\n            damage = 0\n        if damage == self.damage:\n            stunt = True\n        return damage, stunt\n\n    def evasion(self):\n        return random.random() < self.evasion_value\n\n    def be_damaged(self, damage: int, evasion: bool, stunt: bool):\n        stunned = False\n        if evasion:\n            print(f\"{self.name} evade el ataque.\")\n        else:\n            if stunt:\n                stunned = True\n            self.life -= damage\n        if self.life < 0:\n            self.life = 0\n        return stunned\n\n\nclass SimFight:\n    def turn_based_combat(self, fighter1: Fighter, fighter2: Fighter):\n        turn = 1\n        stunned1 = False\n        stunned2 = False\n        print(f\"### {fighter1.name}: {fighter1.life} hp //  {fighter2.name}: {fighter2.life} hp ###\")\n        print(\"\\n\")\n        while fighter1.life > 0 and fighter2.life > 0:\n            print(f\"### {fighter1.name}: {fighter1.life} hp //  {fighter2.name}: {fighter2.life} hp ###\")\n            print(\"\\n\")\n            print(f\"Turno {turn}\")\n            print(\"\\n\")\n\n            if not stunned1:\n                print(f\"{fighter1.name} Ataca.\")\n                print(\"\\n\")\n                damage, stunt = fighter1.attack(False)\n                evaded = fighter2.evasion()\n                stunned2 = fighter2.be_damaged(damage, evaded, stunt)\n                if evaded:\n                    print(f\"{fighter2.name} no recibe daño.\")\n                else:\n                    print(f\"{fighter2.name} ha recivido {damage} puntos de daño.\")\n                print(\"\\n\")\n            else:\n                print(f\"{fighter1.name} esta aturdido y se regenera.\")\n                stunned1 = False\n\n            if not stunned2:\n                print(f\"{fighter2.name} Ataca.\")\n                print(\"\\n\")\n                damage, stunt = fighter2.attack(False)\n                evaded = fighter1.evasion()\n                stunned2 = fighter1.be_damaged(damage, evaded, stunt)\n                if evaded:\n                    print(f\"{fighter1.name} no recibe daño.\")\n                else:\n                    print(f\"{fighter1.name} ha recibido {damage} puntos de daño.\")\n            else:\n                print(f\"{fighter2.name} esta aturdido y se regenera.\")\n                print(\"\\n\")\n                stunned2 = False\n\n            print(\"\\n\")\n            turn += 1\n            sleep(1)\n            os.system(\"clear\")\n\n        if fighter1.life < 0:\n            print(f\"### {fighter1.name}: {fighter1.life} hp //  {fighter2.name}: {fighter2.life} hp ###\")\n            print(f\"{fighter2.name} WINNER!!!!!!\")\n        else:\n            print(f\"### {fighter1.name}: {fighter1.life} hp //  {fighter2.name}: {fighter2.life} hp ###\")\n            print(f\"{fighter1.name} WINNER!!!!!!\")\n\ndead = Fighter(\"deadpool\", 1200, 100, 0.25)\nwolf = Fighter(\"wolverine\", 1200, 120, 0.2)\n\ncombat = SimFight()\ncombat.turn_based_combat(dead, wolf)\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/python/mouredev.py",
    "content": "import random\nimport time\n\ndeadpool_health = int(input(\"Introduce la vida de Deadpool: \"))\nwolverine_health = int(input(\"Introduce la vida de Wolverine: \"))\n\nturn = 0\nregenerate = False\n\nwhile deadpool_health > 0 and wolverine_health > 0:\n\n    turn += 1\n    print(f\"\\nTurno {turn}\")\n\n    # Deadpool ataca a Wolverine\n\n    if regenerate:\n        print(\"Deadpool se está regenerando y no ataca.\")\n        regenerate = False\n    elif random.random() > 0.2:\n        deadpool_damage = random.randint(10, 100)\n        print(f\"Deadpool ataca a Wolverine con {deadpool_damage} de daño.\")\n        if deadpool_damage == 100:\n            regenerate = True\n            print(\n                \"¡Golpe crítico de Deadpool! Wolverine no atacará en el siguiente turno ya que tiene que regenerarse.\")\n\n        wolverine_health -= deadpool_damage\n\n        if wolverine_health <= 0:\n            print(f\"La vida de Wolverine ha llegado a cero.\")\n            break\n        else:\n            print(f\"Vida restante de Wolverine: {wolverine_health}\")\n    else:\n        print(\"¡Wolverine esquiva el ataque de Deadpool!\")\n\n    # Wolverine ataca a Deadpool\n\n    if regenerate:\n        print(\"Wolverine se está regenerando y no ataca.\")\n        regenerate = False\n    elif random.random() > 0.25:\n        wolverine_damage = random.randint(10, 120)\n        print(f\"Wolverine ataca a Deadpool con {wolverine_damage} de daño.\")\n        if wolverine_damage == 120:\n            regenerate = True\n            print(\n                \"¡Golpe crítico de Wolverine! Deadpool no atacará en el siguiente turno ya que tiene que regenerarse.\")\n\n        deadpool_health -= wolverine_damage\n\n        if deadpool_health <= 0:\n            print(f\"La vida de Deadpool ha llegado a cero.\")\n            break\n        else:\n            print(f\"Vida restante de Deadpool: {deadpool_health}\")\n    else:\n        print(\"¡Deadpool esquiva el ataque de Wolverine!\")\n\n    time.sleep(1)\n\nif deadpool_health > 0:\n    print(f\"Deadpool gana la batalla con {deadpool_health} de vida restante.\")\nelse:\n    print(\n        f\"Wolverine gana la batalla con {wolverine_health} de vida restante.\")\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/python/mrodara.py",
    "content": "### BATALLA DEADPOOL VS WOLVERINE\nfrom abc import ABC, abstractmethod\nfrom random import randint\nfrom time import sleep\n\nclass Character(ABC):\n    \n    @abstractmethod\n    def attack(self):\n        pass\n    \n    @abstractmethod\n    def dodge(self):\n        pass\n    \n    @abstractmethod\n    def regenerate(self):\n        pass\n\nclass Deadpool(Character):\n    def __init__(self, health: int = 250):\n        self.name = \"Deadpool\"\n        self.health = health\n        self.max_health = health\n        self.min_damage = 10\n        self.max_damage = 100\n        self.dodge_habilities = ['baile sexy', 'moonwalker', 'voltereta hacia atrás', 'chiste malo']\n    \n    def attack(self, opponent: object) -> int:\n        damage = randint(self.min_damage, self.max_damage)\n        opponent.health -= damage\n        \n        return damage\n    \n    def dodge(self):\n        return randint(1,4) == 1 #25% de posibilidades de sacar el valor\n    \n    def regenerate(self):\n        self.health += 15 if self.health < self.max_health else self.max_health\n        print(f\"{self.name} ha regenerado su salud, ahora tiene {self.health} puntos\")\n\nclass Wolverine(Character):\n    def __init__(self, health: int = 350):\n        self.name = \"Wolverine\"\n        self.health = health\n        self.max_health = health\n        self.min_damage = 10\n        self.max_damage = 120\n        self.dodge_habilities = ['agacharse', 'barrido lateral', 'doble tirabuzón', 'mortal invertido']\n\n    def attack(self, opponent: object) -> int:\n        damage = randint(self.min_damage, self.max_damage)\n        opponent.health -= damage\n        \n        return damage\n    \n    def dodge(self):\n        return randint(1,5) == 1 #20% de posibilidades de sacar el valor\n    \n    def regenerate(self):\n        self.health += 25 if self.health < self.max_health else self.max_health\n        print(f\"{self.name} ha regenerado su salud, ahora tiene {self.health}/{self.max_health} puntos\")\n\n\n\ndef simulate_battle():\n    \n    #Instanciamos los personajes\n    deadpool = Deadpool()   \n    wolverine = Wolverine()\n\n    turn = 0\n        \n    #Decidimos quien ataca y quien defiende en primera instancia\n    attacker = deadpool if turn % 2 == 0 else wolverine\n    defender = wolverine if turn % 2 == 0 else deadpool\n    \n    print(\"#### Inicio de la Pelea ####\")\n    print(\"-\" * 30)\n    \n    while deadpool.health>0 or wolverine.health>0:\n        print(f\"Turno {turn + 1}\")\n        print(f\"Turno de {attacker.name}\")\n        if defender.dodge():\n            print(f\"{defender.name} ha conseguido esquivar el Ataque con {defender.dodge_habilities[randint(0, len(defender.dodge_habilities)-1)]}\")\n        else:\n            damage = attacker.attack(opponent=defender)\n            print(f\"{attacker.name} ha lanzando una ataque de fuerza {damage} ahora {defender.name} tiene una salud de {defender.health}/{defender.max_health}\")\n            defender.regenerate() if damage != attacker.max_damage and defender.health>0 else None\n        print(\"-\" * 50)\n        #Comprobamos la salud del defensor por si ha acabado la batalla\n        if defender.health <= 0:\n            print(f\"{defender.name} ha sido derrotado\")\n            break\n        \n        #Cambiamos de turno si no se ha dado un ataque con el máximo de daño\n        if damage != attacker.max_damage:\n            attacker, defender = defender, attacker #Intercambiamos los papeles\n        \n        turn += 1\n        sleep(1)\n        \n    print(\"#### Fin de la Pelea ####\")\n    print(\"-\" * 30)\n\nsimulate_battle()\n### FIN BATALLA DEADPOOL VS WOLVERINE"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/python/neslarra.py",
    "content": "\"\"\"\n EJERCICIO:\n ¡Deadpool y Wolverine se enfrentan en una batalla épica!\n Crea un programa que simule la pelea y determine un ganador.\n El programa simula un combate por turnos, donde cada protagonista posee unos\n puntos de vida iniciales, un daño de ataque variable y diferentes cualidades\n de regeneración y evasión de ataques.\n Requisitos:\n 1. El usuario debe determinar la vida inicial de cada protagonista.\n 2. Cada personaje puede impartir un daño aleatorio:\n    - Deadpool: Entre 10 y 100.\n    - Wolverine: Entre 10 y 120.\n 3. Si el daño es el máximo, el personaje que lo recibe no ataca en el\n siguiente turno, ya que tiene que regenerarse (pero no aumenta vida).\n 4. Cada personaje puede evitar el ataque contrario:\n    - Deadpool: 25% de posibilidades.\n    - Wolverine: 20% de posibilidades.\n 5. Un personaje pierde si sus puntos de vida llegan a cero o menos.\n Acciones:\n 1. Simula una batalla.\n 2. Muestra el número del turno (pausa de 1 segundo entre turnos).\n 3. Muestra qué pasa en cada turno.\n 4. Muestra la vida en cada turno.\n 5. Muestra el resultado final.\n\"\"\"\nfrom abc import ABC, abstractmethod\nfrom random import choice\nfrom time import sleep\n\n\nclass AbstractHero(ABC):\n\n    @abstractmethod\n    def attack(self):\n        pass\n\n    @abstractmethod\n    def defense(self, hit_power: float):\n        pass\n\n    @abstractmethod\n    def get_lives_level(self):\n        pass\n\n    @abstractmethod\n    def get_name(self):\n        pass\n\n    @abstractmethod\n    def get_max_hit_power(self):\n        pass\n\n\nclass AbstractFight(ABC):\n\n    @abstractmethod\n    def turn(self):\n        pass\n\n    @abstractmethod\n    def get_turn(self):\n        pass\n\n    @abstractmethod\n    def combat(self):\n        pass\n\n\nclass Hero(AbstractHero):\n\n    def __init__(self, name: str, lives: int, attack_power: dict, defense_pct: float):\n\n        self.name = name\n        self.lives = lives\n        self.attack_power = attack_power\n        self.defense_pct = defense_pct\n\n    def attack(self):\n        hit = choice([x for x in self.attack_power.keys()])\n        return hit, self.attack_power[hit]\n\n    def defense(self, hit_power: float):\n        damage = hit_power * (1 - self.defense_pct / 100)\n        self.lives -= damage / 10                           # la potencia del golpe es mucho mayor que las vidas => lo bajo para que dure la pelea\n\n    def get_lives_level(self):\n        return self.lives.__round__(2)\n\n    def get_name(self):\n        return self.name\n\n    def get_max_hit_power(self):\n        return max([x for x in self.attack_power.values()])\n\n\nclass Fight(AbstractFight):\n\n    def __init__(self, hero1: AbstractHero, hero2: AbstractHero):\n\n        self.hero1 = hero1\n        self.hero2 = hero2\n        self.turn_number = 0\n        self.lost_turn = False\n\n    def turn(self):\n        self.turn_number += 1\n\n    def get_turn(self):\n        return self.turn_number\n\n    def combat(self):\n        self.turn()\n        if self.get_turn() % 2 == 0:\n            if self.lost_turn:\n                print(f\"\\t{self.hero1.get_name()} lost its turn.\")\n                self.lost_turn = False\n            else:\n                punch, power = self.hero1.attack()\n                self.hero2.defense(power)\n                print(f\"\\t{self.hero1.get_name()} hits with {punch}\")\n                if power == self.hero1.get_max_hit_power():\n                    self.lost_turn = True\n        else:\n            if self.lost_turn:\n                print(f\"\\t{self.hero2.get_name()} lost its turn.\")\n                self.lost_turn = False\n            else:\n                punch, power = self.hero2.attack()\n                self.hero1.defense(power)\n                print(f\"\\t{self.hero2.get_name()} hits with {punch}\")\n                if power == self.hero2.get_max_hit_power():\n                    self.lost_turn = True\n        print(f\"\\t{self.hero1.get_name()}'s lives {self.hero1.get_lives_level()}  /  {self.hero2.get_name()}'s lives {self.hero2.get_lives_level()}\")\n\n\ndeadpool = Hero(\"Deadpool\", 20, {\"left_punch\": 10, \"right_punch\": 20, \"left_kick\": 30, \"right_kick\": 40, \"up_flying_kick\": 50,\n                                 \"down_flying_kick\": 60, \"single_pistol\": 70, \"double_pistol\": 80, \"single_sword\": 100, \"double_sword\": 100},\n                25)\nwolverine = Hero(\"Wolverine\", 20, {\"left_punch\": 10, \"right_punch\": 20, \"left_kick\": 30, \"right_kick\": 40, \"up_flying_kick\": 50,\n                                   \"down_flying_kick\": 60, \"left_knives_up\": 90, \"right_knives_up\": 90, \"left_knives_down\": 120, \"right_knives_down\": 120},\n                 20)\n\nfight = Fight(deadpool, wolverine)\n\nwhile deadpool.get_lives_level() > 0 and wolverine.get_lives_level() > 0:\n    print(f\"Turn# {fight.get_turn() + 1}\")\n    fight.combat()\n    sleep(1)\n    if deadpool.get_lives_level() <= 0:\n        print(f\"{wolverine.get_name()} WON!!!\")\n    if wolverine.get_lives_level() <= 0:\n        print(f\"{deadpool.get_name()} WON!!!\")\n\nr\"\"\"\nLa salida es algo como ésto:\n\nTurn# 1\n    Wolverine hits with left_knives_down\n    Deadpool's lives 11.0  /  Wolverine's lives 20\nTurn# 2\n    Deadpool lost its turn.\n    Deadpool's lives 11.0  /  Wolverine's lives 20\nTurn# 3\n    Wolverine hits with right_knives_up\n    Deadpool's lives 4.25  /  Wolverine's lives 20\nTurn# 4\n    Deadpool hits with right_kick\n    Deadpool's lives 4.25  /  Wolverine's lives 16.8\nTurn# 5\n    Wolverine hits with down_flying_kick\n    Deadpool's lives -0.25  /  Wolverine's lives 16.8\nWolverine WON!!!\n\"\"\"\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/python/nlarrea.py",
    "content": "\"\"\"\n * EJERCICIO:\n * ¡Deadpool y Wolverine se enfrentan en una batalla épica!\n * Crea un programa que simule la pelea y determine un ganador.\n * El programa simula un combate por turnos, donde cada protagonista posee unos\n * puntos de vida iniciales, un daño de ataque variable y diferentes cualidades\n * de regeneración y evasión de ataques.\n * Requisitos:\n * 1. El usuario debe determinar la vida inicial de cada protagonista.\n * 2. Cada personaje puede impartir un daño aleatorio:\n *    - Deadpool: Entre 10 y 100.\n *    - Wolverine: Entre 10 y 120.\n * 3. Si el daño es el máximo, el personaje que lo recibe no ataca en el\n * siguiente turno, ya que tiene que regenerarse (pero no aumenta vida).\n * 4. Cada personaje puede evitar el ataque contrario:\n *    - Deadpool: 25% de posibilidades.\n *    - Wolverine: 20% de posibilidades.\n * 5. Un personaje pierde si sus puntos de vida llegan a cero o menos.\n * Acciones:\n * 1. Simula una batalla.\n * 2. Muestra el número del turno (pausa de 1 segundo entre turnos).\n * 3. Muestra qué pasa en cada turno.\n * 4. Muestra la vida en cada turno.\n * 5. Muestra el resultado final.\n\"\"\"\n\nfrom random import randint, random\nfrom time import sleep\nfrom typing import Self\n\n\nclass Damage:\n    def __init__(self, min_: int = 10, max_: int = 100):\n        self._min = min_\n        self._max = max_\n\n    def calculate(self):\n        return randint(self.min, self.max)\n\n    @property\n    def min(self):\n        return self._min\n\n    @property\n    def max(self):\n        return self._max\n\n\nclass Fighter:\n    def __init__(\n        self,\n        name: str,\n        damage: Damage,\n        evade: float,\n        life: int,\n        rests: bool = False,\n    ):\n        self._name = name\n        self._damage = damage\n        self._evade = evade\n        self._life = life\n        self._rests = rests\n\n    def attack(self) -> int:\n        # Check if current fighter has to rest\n        if self._rests:\n            print(f\"{self.name} se está recuperando...\")\n            self._rests = False\n            return 0\n\n        # Calculate the damage value\n        damage = self._damage.calculate()\n        # Check if fighter will need to rest in his next turn\n        self._rests = damage == self._damage.max\n        if self._rests:\n            print(\n                f\"Golpe crítico! {self.name} deberá descansar en el siguiente turno...\"\n            )\n\n        return damage\n\n    def evade(self, damage: int):\n        if random() < self._evade:\n            print(f\"{self.name} ha esquivado el ataque!\")\n        else:\n            print(f\"{self.name} ha recibido {damage} puntos de daño!\")\n            self._update_life(damage)\n\n    def _update_life(self, damage: int):\n        self._life -= damage\n        if self._life < 0:\n            self._life = 0\n\n    @property\n    def name(self):\n        return self._name\n\n    @property\n    def life(self):\n        return self._life\n\n\nD = \"Deadpool\"\nW = \"Wolverine\"\n\n\ndef ask_life(fighter: str) -> int | None:\n    while True:\n        try:\n            print(\"\\nPuedes pulsar Q para salir.\")\n            message = f\"Introduce la vida de {fighter}:\\n > \"\n\n            num = input(message)\n            if num.lower() == \"q\":\n                return\n\n            assert (\n                num.replace(\".\", \"\", 1).isnumeric() and int(num) >= 1\n            ), f\"Debes introducir un número positivo.\"\n\n        except AssertionError as error:\n            print(error)\n\n        else:\n            return int(num)\n\n\ndef create_fighters() -> tuple[Fighter, Fighter] | None:\n    # Definir Deadpool\n    life = ask_life(fighter=D)\n    if life is None:\n        return\n\n    deadpool = Fighter(\n        name=D, damage=Damage(min_=10, max_=100), evade=0.25, life=life\n    )\n\n    # Definir Wolverine\n    life = ask_life(fighter=W)\n    if life is None:\n        return\n\n    wolverine = Fighter(\n        name=W, damage=Damage(min_=10, max_=120), evade=0.2, life=life\n    )\n\n    return deadpool, wolverine\n\n\ndef is_winner(fighters: tuple[Fighter]):\n    return any([fighter.life <= 0 for fighter in fighters])\n\n\ndef show_life(fighters: list[Fighter]):\n    for fighter in fighters:\n        print(f\" - Vida de {fighter.name}:\", fighter.life)\n\n\ndef simulate():\n    # Create fighters and their data\n    fighters: tuple[Fighter] = create_fighters()\n    if fighters is None:\n        return\n\n    print(\"\\nVidas iniciales:\")\n    show_life(fighters)\n\n    print(\"\\n¡COMIENZA EL COMBATE!\")\n\n    # Select who starts the fight\n    current_fighter = fighters[0] if random() < 0.5 else fighters[1]\n\n    turn_counter = 1\n    while not is_winner(fighters):\n        print(f\"\\nTURNO {turn_counter}: {current_fighter.name} ataca!\")\n\n        other_fighter = fighters[\n            (fighters.index(current_fighter) + 1) % len(fighters)\n        ]\n\n        damage = current_fighter.attack()\n        if damage:\n            other_fighter.evade(damage)\n\n        show_life(fighters)\n\n        if is_winner(fighters):\n            print(f\"\\n{current_fighter.name.upper()} HA GANADO EL COMBATE!\")\n            return\n\n        current_fighter = other_fighter\n        turn_counter += 1\n\n        sleep(1)\n\n\nif __name__ == \"__main__\":\n    simulate()\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/python/oriaj3.py",
    "content": "\"\"\"\n32 - BATALLA DEADPOOL Y WOLVERINE\nAutor de la solución: Oriaj3\n\n/*\n * EJERCICIO:\n * ¡Deadpool y Wolverine se enfrentan en una batalla épica!\n * Crea un programa que simule la pelea y determine un ganador.\n * El programa simula un combate por turnos, donde cada protagonista posee unos\n * puntos de vida iniciales, un daño de ataque variable y diferentes cualidades\n * de regeneración y evasión de ataques.\n * Requisitos:\n * 1. El usuario debe determinar la vida inicial de cada protagonista.\n * 2. Cada personaje puede impartir un daño aleatorio:\n *    - Deadpool: Entre 10 y 100.\n *    - Wolverine: Entre 10 y 120.\n * 3. Si el daño es el máximo, el personaje que lo recibe no ataca en el\n * siguiente turno, ya que tiene que regenerarse (pero no aumenta vida).\n * 4. Cada personaje puede evitar el ataque contrario:\n *    - Deadpool: 25% de posibilidades.\n *    - Wolverine: 20% de posibilidades.\n * 5. Un personaje pierde si sus puntos de vida llegan a cero o menos.\n * Acciones:\n * 1. Simula una batalla.\n * 2. Muestra el número del turno (pausa de 1 segundo entre turnos).\n * 3. Muestra qué pasa en cada turno.\n * 4. Muestra la vida en cada turno.\n * 5. Muestra el resultado final.\n */\n\"\"\"\n\nimport random\nimport time\n\nclass simulador():\n    deadpool_health: int\n    wolverine_health: int\n    turn: int = 0\n\n    #Porcentaje de esquiva \n    deeadpool_evade = 0.25\n    wolverine_evade = 0.20\n\n    #Flag para saber si el personaje se está regenerando\n    deadpool_regenerate = False\n    wolverine_regenerate = False\n\n    def __init__(self):\n        deadpool_hp = int(input(\"Introduce la vida inicial de Deadpool: \"))\n        wolverine_hp = int(input(\"Introduce la vida inicial de Wolverine: \"))\n        \n        self.deadpool_health = deadpool_hp\n        self.wolverine_health = wolverine_hp\n\n    def iniciar(self):\n        while(self.deadpool_health > 0 and self.wolverine_health > 0):\n            self.turno()\n            time.sleep(1)\n        self.resultado()\n\n    def turno(self):\n        print(f\"\\nTurno {self.turn}\")\n        self.turn += 1\n\n        # Calcula los daños \n        deadpool_damage = random.randint(10, 100)\n        wolverine_damage = random.randint(10, 120)\n\n        if self.deadpool_regenerate:\n            print(\"Deadpool se está regenerando y no ataca.\")\n            self.deadpool_regenerate = False\n            deadpool_damage = 0\n    \n        if self.wolverine_regenerate:\n            self.wolverine_regenerate = False\n            wolverine_damage = 0\n        \n\n        # Daños máximos\n        if deadpool_damage == 100:\n            print(\"¡Golpe crítico de Deadpool! Wolverine no atacará en el siguiente turno ya que tiene que regenerarse.\")\n            self.wolverine_regenerate = True\n        elif wolverine_damage == 120:\n            print(\"¡Golpe crítico de Wolverine! Deadpool no atacará en el siguiente turno ya que tiene que regenerarse.\")\n            self.deadpool_regenerate = True\n        else:\n            if deadpool_damage != 0:\n                print(f\"Deadpool ataca a Wolverine con {deadpool_damage} de daño.\")\n            else:\n                print(\"Wolverine se está regenerando y no ataca.\")\n            if wolverine_damage != 0:\n                print(f\"Wolverine ataca a Deadpool con {wolverine_damage} de daño.\")\n            else:\n                print(\"Deadpool se está regenerando y no ataca.\")\n\n        #Calculo si esquiva el ataque, random.random() devuelve un número entre 0 y 1 por tanto si es menor al porcentaje de esquiva, esquiva el ataque\n        if random.random() < self.deeadpool_evade:\n            print(\"¡Deadpool esquiva el ataque de Wolverine!\")\n        else:\n            self.deadpool_health -= wolverine_damage\n            print(f\"Vida restante de Deadpool: {self.deadpool_health}\")\n        \n        if random.random() < self.wolverine_evade:\n            print(\"¡Wolverine esquiva el ataque de Deadpool!\")\n        else:\n            self.wolverine_health -= deadpool_damage\n            print(f\"Vida restante de Wolverine: {self.wolverine_health}\")\n        \n    def resultado(self):\n        if self.deadpool_health <= 0 and self.wolverine_health <= 0:\n            print(\"Ambos personajes han muerto.\")\n        elif self.deadpool_health <= 0:\n            print(\"Wolverine ha ganado la batalla!\")\n        else:\n            print(\"Deadpool ha ganado la batalla!\")\n\n\nsimulador = simulador()\nsimulador.iniciar()\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/python/pyramsd.py",
    "content": "import time\nimport random\n\nclass Personaje:\n    def __init__(self, personaje, vida, evasion, damage):\n        self.personaje = personaje\n        self.vida = vida\n        self.evasion = evasion\n        self.damage = damage\n\n    def set_vida(self, vida):\n        self.vida = vida\n\n    def atacar(self):\n        return random.randint(10, self.damage)\n    \n    def evadir(self):\n        return random.random() < self.evasion\n    \n\ndef batalla(psj1, psj2):\n    turno = 1\n    print(f\"Vidas iniciales:\\nDeadpool: {psj1.vida} - Wolverine: {psj2.vida}\")\n    while psj1.vida > 0 and psj2.vida > 0:\n        print(\"------------------------------\")\n        print(f\"Turno: {turno}\")\n\n        if not psj2.evadir():\n            damage = psj1.atacar()\n            psj2.vida -= damage\n            print(f\"\\033[38;5;214m[!!] {psj1.personaje} ataca a {psj2.personaje} y causa {damage} de daño.\\033[0m\")\n        else:\n            print(f\"\\033[34m[!] {psj2.personaje} esquiva el ataque de {psj1.personaje}!\\033[0m\")\n        \n\n        if psj2.vida <= 0:\n            print(f\"\\033[31m[-] {psj2.personaje} ha sido derrotado!\\033[0m\")\n            print(f\"\\033[32m[+] {psj1.personaje} es el ganador!\\033[0m\")\n            break\n\n\n        if not psj1.evadir():\n            damage = psj2.atacar()\n            psj1.vida -= damage\n            print(f\"\\033[38;5;214m[!!] {psj2.personaje} ataca a {psj1.personaje} y causa {damage} de daño.\\033[0m\")\n        else:\n            print(f\"\\033[34m[!] {psj1.personaje} esquiva el ataque de {psj2.personaje}!\\033[0m\")\n\n        \n        if psj1.vida <= 0:\n            print(f\"\\033[31m[-] {psj1.personaje} ha sido derrotado!\\033[0m\")\n            print(f\"\\033[32m[+] {psj2.personaje} es el ganador!\\033[0m\")\n            break\n\n        print(f\"Vida de {psj1.personaje}: {psj1.vida}\")\n        print(f\"Vida de {psj2.personaje}: {psj2.vida}\")\n\n        turno += 1\n        time.sleep(1)\n\ndeadpool = Personaje(\"Deadpool\", 100, 0.25, 100)\nwolverine = Personaje(\"Wolverine\", 100, 0.20, 120)\n\nbatalla(deadpool, wolverine)\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/python/raulG91.py",
    "content": "from abc import ABC,abstractmethod\nfrom random import randint\nimport  time\n\nclass Hero(ABC):\n    def __init__(self,max_life):\n        self.life = max_life\n    @abstractmethod\n    def attack(self)->int:\n        pass\n    @abstractmethod\n    def defende(self)->bool:\n        pass\n    @abstractmethod\n    def getMaxAttack(self)->int:\n        pass\n    def getLife(self)->int:\n        return self.life\n    def reduceLife(self,number):\n        self.life -= number    \n\nclass Deadpool(Hero):\n    def attack(self) -> int:\n        #Generate a random number between 10 and 100\n        number = randint(10,100)\n        return number         \n    def defende(self) -> bool:\n        number = randint(0,100)\n        if number <=25:\n            return True\n        else:\n            return False\n    def getMaxAttack(self) -> int:\n        return 100\n\nclass Wolverine(Hero):\n    def attack(self) -> int:\n        #Generate a random number between 10 and 100\n        number = randint(10,120)\n        return number         \n    def defende(self) -> bool:\n        number = randint(0,100)\n        if number <=20:\n            return True\n        else:\n            return False\n    def getMaxAttack(self) -> int:\n        return 120       \n\n\nprint(\"Enter max life for Deadpool\")\nmax_life = int(input())\n\ndeadpool = Deadpool(max_life)\n\nprint(\"Enter max life for Wolverine\")\nmax_life = int(input())\nwolverine = Wolverine(max_life)\n\nturn = 1\nskip_turn = False\n\nwhile(True):\n    \n    if deadpool.getLife()<=0 or wolverine.getLife() <= 0:\n        #One of the heroes doesn't have life\n        print(\"Ending battle\")\n        break\n    else:\n        print(f'Starting turn {turn}')\n        if skip_turn:\n            if turn % 2 != 0:\n                print(\"Skipping this turn for Deadpool\")\n            else:\n                print(\"Skipping turn for Wolverine\")\n            skip_turn = False    \n            turn += 1\n        else:  \n            if turn % 2 != 0:\n                #Deadpool attack\n                attack = deadpool.attack()\n                defense = wolverine.defende()\n                print(f'Deadpool attack {attack} ')\n                if not(defense):\n                    wolverine.reduceLife(attack) \n                else:\n                    print(\"Wolverine will defend Deadpool's attack\")    \n                if attack == deadpool.getMaxAttack():\n                    skip_turn = True    \n            else:\n                #Wolverine attack\n                attack = wolverine.attack()\n                defense = deadpool.defende()\n                print(f'Wolverine attack {attack} ')\n                if not(defense):\n                    deadpool.reduceLife(attack)    \n                else:\n                    print(\"Deadpool will defend Wolverine's attack\")   \n                if attack == wolverine.getMaxAttack():\n                    skip_turn = True    \n            print(f'Deadpol remains life is {deadpool.getLife()}')\n            print(f'Wolverine remains life is {wolverine.getLife()}')   \n            turn += 1     \n            time.sleep(1)\n\n\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/python/raynerpv2022.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * ¡Deadpool y Wolverine se enfrentan en una batalla épica!\n#  * Crea un programa que simule la pelea y determine un ganador.\n#  * El programa simula un combate por turnos, donde cada protagonista posee unos\n#  * puntos de vida iniciales, un daño de ataque variable y diferentes cualidades\n#  * de regeneración y evasión de ataques.\n#  * Requisitos:\n#  * 1. El usuario debe determinar la vida inicial de cada protagonista.\n#  * 2. Cada personaje puede impartir un daño aleatorio:\n#  *    - Deadpool: Entre 10 y 100.\n#  *    - Wolverine: Entre 10 y 120.\n#  * 3. Si el daño es el máximo, el personaje que lo recibe no ataca en el\n#  * siguiente turno, ya que tiene que regenerarse (pero no aumenta vida).\n#  * 4. Cada personaje puede evitar el ataque contrario:\n#  *    - Deadpool: 25% de posibilidades.\n#  *    - Wolverine: 20% de posibilidades.\n#  * 5. Un personaje pierde si sus puntos de vida llegan a cero o menos.\n#  * Acciones:\n#  * 1. Simula una batalla.\n#  * 2. Muestra el número del turno (pausa de 1 segundo entre turnos).\n#  * 3. Muestra qué pasa en cada turno.\n#  * 4. Muestra la vida en cada turno.\n#  * 5. Muestra el resultado final.\n#  */\nfrom abc import ABC, abstractmethod\n\nimport random, time\n\nclass VirtualWarrior(ABC):\n    @abstractmethod\n    def __init__(self, initial_life: int, maximo: int,ae: int):\n        self._initial_life = initial_life\n        self._life = initial_life\n        self._atack_damage = 0\n        self._regeneration  = False\n        self._atack_evation = ae\n        self._winner = False\n        self._maximo =  maximo\n    \n    \n    def reset_warrior(self):\n          self._life = self._initial_life\n          self._atack_damage = 0\n          self._regeneration  = False\n          self._winner = False\n          \n                   \n    def  evation(self):\n            \n           return  random.random() < self._atack_evation/100\n            \n    \n     \n    def attack(self):\n         self._atack_damage = random.randint(10,self._maximo)\n          \n         \n          \n\n\nclass DeadPool(VirtualWarrior):\n    def __init__(self, initial_life: int, maximo: int,ae: int):\n        super().__init__(initial_life,maximo, ae)\n         \n         \n         \n\n     \n          \n\nclass Wolwerine(VirtualWarrior):\n    def __init__(self, initial_life: int, maximo: int,ae: int):\n        super().__init__(initial_life,maximo, ae)\n         \n         \n         \n\n    \nclass VirtualReport(ABC):\n     @abstractmethod\n     def __init__(self):\n          pass\n     @abstractmethod\n     def reset(self):\n          pass\n     @abstractmethod\n     def turn_report(self):\n          pass\n     @abstractmethod\n     def show_winner(self):\n          pass\n\n\n\n    \n\n\nclass Report(VirtualReport):\n     def __init__(self):\n          self._message = {\"attacker\":None,\n                          \"defenser\": None,\n                          \"winner\": None,\n                          \"regeneration\": None,\n                          \"evation\": None,\n                          \"attackpower\": None,\n                          \"maximalhit\": None,\n                          \"turn\": None,\n                          \"defenserlife\":None,\n\n                          }\n           \n     \n     def reset(self):\n           for  clave in self._message:\n            self._message[clave] = None\n\n    \n     def turn_report(self):\n          \n\n          print(f\"  Turno :{self._message[\"turn\"]} -  Atacante : {self._message[\"attacker\"]} Defensor :{self._message[\"defenser\"]} Fuerza de Ataque: {self._message[\"attackpower\"]}\")\n          \n          if self._message[\"evation\"] :\n               print(f\"    :{self._message[\"evation\"]}\")\n\n          if self._message[\"maximalhit\"] :\n               print(f\"    :{self._message[\"maximalhit\"]}\")\n\n          if self._message[\"regeneration\"] :\n               print(f\"    :{self._message[\"regeneration\"]}\")\n\n          \n            \n               \n          print(f\"  Vide de  {self._message[\"defenser\"]}  : {self._message[\"defenserlife\"]}\")\n           \n\n     def show_winner(self):\n          \n          print(f\"  {self._message[\"attacker\"]} is the WINNER\")\n\n     \nclass VirtualTurn(ABC):\n     @abstractmethod\n     def __init__(self, warriors: list[VirtualWarrior] ):\n          pass\n          \n     @abstractmethod      \n     def  choose_current_attacker(self, report: Report)    :\n            pass\n\n     @abstractmethod     \n     def choose_current_defenser(self, report: Report) :\n          pass\n     \n     @abstractmethod\n     def turn_change(self, attacker: VirtualWarrior, defenser: VirtualWarrior,report: Report):\n          pass\n\n     @abstractmethod\n     def turn_winner(self, attacker: VirtualWarrior, defenser: VirtualWarrior, report: Report): \n          pass\n     \n     \nclass Turn(VirtualTurn):\n     def __init__(self, warriors: list[VirtualWarrior] ):\n          self._warriors = warriors\n          self._number_turn = 0\n          self._current_attacker : VirtualWarrior\n          self._current_defenser : VirtualWarrior\n          self._message : VirtualWarrior\n          \n           \n         \n           \n     def  choose_current_attacker(self, report: Report)    :\n            self._current_attacker = random.choice(self._warriors)\n            report._message[\"attacker\"] = self._current_attacker.__class__.__name__\n             \n         \n     \n     def choose_current_defenser(self, report: Report) :\n          self._current_defenser = (next(w for w in self._warriors if w is not self._current_attacker))\n          report._message[\"defenser\"] = self._current_defenser.__class__.__name__\n     \n     def turn_change(self, attacker: VirtualWarrior, defenser: VirtualWarrior,report: Report):\n          \n          if defenser._regeneration :\n               defenser._regeneration = False\n               report._message[\"attacker\"], report._message[\"defenser\"] = self._current_attacker.__class__.__name__, self._current_defenser.__class__.__name__\n                 \n\n               return\n          else:\n               self._current_attacker, self._current_defenser = defenser, attacker\n               report._message[\"attacker\"], report._message[\"defenser\"] = self._current_attacker.__class__.__name__, self._current_defenser.__class__.__name__\n                 \n               \n\n        \n                \n          \n\n     def turn_winner(self, attacker: VirtualWarrior, defenser: VirtualWarrior, report: Report):\n            \n            if defenser._life <= 0:\n                     attacker._winner = True\n                     report._message[\"winner\"] = f\"{attacker.__class__.__name__} is the WINNER\"\n            \n     \n          \nclass VirtualAttackManager(ABC):\n     @abstractmethod\n     def turn_attack(self, attacker: VirtualWarrior, defenser: VirtualWarrior, report: Report):\n               pass\n               \n\n\nclass AttackManager(VirtualAttackManager):\n               \n     def turn_attack(self, attacker: VirtualWarrior, defenser: VirtualWarrior, report: Report):\n     \n         attacker.attack()\n         report._message[\"attackpower\"] = attacker._atack_damage\n         report._message[\"defenserlife\"] = defenser._life\n         if defenser.evation():\n            \n            report._message[\"evation\"] = f\"{defenser.__class__.__name__} ha evadido el ataque\"\n            return\n         \n         defenser._life -= attacker._atack_damage\n         report._message[\"defenserlife\"] = defenser._life\n         if attacker._atack_damage >= attacker._maximo   :\n                defenser._regeneration = True\n                report._message[\"maximalhit\"] = f\"   {attacker.__class__.__name__}  GOLPE MAXIMO !!!\"\n                report._message[\"regeneration\"] =  f\"   {defenser.__class__.__name__} Debe Regenerarse\"\n               \n          \n             \n            \n             \n\n      \n                 \n            \n\nclass Battle:\n     def __init__(self,warriors: list[VirtualWarrior], report: VirtualReport, attack: VirtualAttackManager):\n          \n          self._warriors = warriors\n          self._report = report\n          self._attack_manager = attack\n\n     def reset(self):\n            for i in self._warriors:   \n                i.reset_warrior()\n     \n\n    \n     def battle_simulator(self):\n            self._turn = Turn(self._warriors)\n            self._turn.choose_current_attacker(report)\n            self._turn.choose_current_defenser(report)\n            \n            \n            \n            while True:\n                           self._turn._number_turn +=1\n                           self._report._message[\"turn\"] = self._turn._number_turn\n                             \n                           self._attack_manager.turn_attack(self._turn._current_attacker, self._turn._current_defenser, report)\n                           self._report.turn_report()\n\n                           self._turn.turn_winner(self._turn._current_attacker, self._turn._current_defenser,report)\n                           \n                           \n                           if self._turn._current_attacker._winner:\n                                break\n                           time.sleep(1)\n                           self._report.reset()\n                           self._turn.turn_change(self._turn._current_attacker, self._turn._current_defenser, report)\n                 \n            self._report.show_winner()\n            self.reset()\n   \n\nclass MenuUser:\n    def __init__(self):\n         self._option = 0\n\n    def show_menu(self):\n            \n            print(\"Batalla Epica\")\n            print()\n            print(\"1. Simula una batalla.\") \n            print(\"2. Terminar.\")\n\n    def option_select(self, battle: Battle):\n         while True:\n            self._option = int(input(\"Option between 1 and 2 : \"))\n            print()\n            1\n\n            match self._option:\n                        case 1:\n                            battle.battle_simulator()\n                        case 2:\n                            break\n                        case _:\n                            print(\"Option not available, try again...\")\n                     \n               \n\n\n     \n\n\nmenu = MenuUser()\nreport = Report()\nattack_manager = AttackManager()\n \nwarrior = [DeadPool(300,120, 20),Wolwerine(300, 100, 25)]\nbattle = Battle( warrior, report, attack_manager)\nmenu.show_menu()\nmenu.option_select(battle)\n \n\n\n\n\n# ****************************************************************\n\n\n# 🔍 Análisis revisado punto por punto con SOLID + OOP\n# ✅ 1. S - Single Responsibility Principle (SRP)\n\n# ✔ Bien aplicado, aunque con matices.\n# Clase\tResponsabilidad principal\t¿Cumple SRP?\n# Battle\tOrquestar la batalla (simulación de alto nivel)\t✅ Sí\n# Report\tMostrar y gestionar los reportes de combate\t✅ Sí\n# AttackManager\tLógica del ataque: daño, evasión, efectos\t✅ Sí\n# Turn\tManejo de turnos, cambio de roles, orden\t⚠ Parcial\n\n# 🔧 Mejora sugerida para Turn:\n# Actualmente mezcla:\n\n#     Elección inicial de atacante/defensor\n\n#     Cambio de turno\n\n#     Determinar ganador\n\n# 👉 Podrías separar la lógica de elección y la verificación del fin de combate en servicios distintos, si quieres escalar o testear.\n# ✅ 2. O - Open/Closed Principle (OCP)\n\n# ✔ Excelente cumplimiento.\n\n#     Puedes agregar nuevos tipos de guerreros (como Hulk o Thanos) simplemente heredando de VirtualWarrior.\n\n#     Nuevas reglas de batalla pueden ser incorporadas creando nuevos AttackManager o Turn.\n\n# ✅ Todas las clases dependen de interfaces/abstracciones (VirtualAttackManager, VirtualReport, VirtualTurn), por lo que están cerradas para modificación, pero abiertas para extensión.\n# ✅ 3. L - Liskov Substitution Principle (LSP)\n\n# ✔ Muy bien.\n\n#     Cualquier objeto DeadPool, Wolverine funciona correctamente donde se espera un VirtualWarrior.\n\n#     Igual con Report, AttackManager, etc.\n\n#     No se rompe el comportamiento esperado al sustituir instancias concretas por abstractas.\n\n# ✅ 4. I - Interface Segregation Principle (ISP)\n\n# ✔ Bien aplicado.\n\n#     Las clases abstractas (VirtualTurn, VirtualWarrior, etc.) definen solo lo esencial.\n\n#     No hay métodos innecesarios forzados a las clases hijas.\n\n#     Muy adecuado para Python, aunque Python no requiere interfaces explícitas, tu diseño lo simula muy bien con ABC.\n\n# ✅ 5. D - Dependency Inversion Principle (DIP)\n\n# ✔ CUMPLIDO gracias a tu aclaración.\n\n#     Battle no instancia directamente Report o AttackManager.\n\n#     Los recibe como dependencias inyectadas a través de sus interfaces abstractas:\n\n# battle = Battle(warrior, report, attack_manager)\n\n#     Esto hace que Battle dependa de abstracciones, no de implementaciones concretas.\n\n# ⚙️ Diseño General POO\n# ✔️ Fortalezas\n\n#     Modularidad: Cada componente está separado con una responsabilidad clara.\n\n#     Extensibilidad: Fácil agregar personajes, reglas, tipos de ataque, nuevos reportes.\n\n#     Reusabilidad: Puedes usar los mismos VirtualWarrior con otro AttackManager, etc.\n\n#     Testabilidad: Gracias al uso de abstracciones, puedes mockear objetos para testing.\n\n# 🔧 Mejoras posibles\n# 1. Encapsulamiento real\n\n#     Actualmente accedes directamente a atributos como report._message[...] desde otras clases.\n\n#         🔧 Mejor usar set_data() y get_data() para no violar el encapsulamiento.\n\n# 2. Separar responsabilidades del Turn\n\n#     Como mencionamos, tiene múltiples roles.\n\n# 3. Mejorar el input del usuario\n\n#     Validaciones con try/except para evitar errores en consola.\n\n# 4. Uso de propiedades (@property)\n\n#     En vez de exponer _life, podrías tener @property def life() y @life.setter.\n\n# 5. Añadir pruebas unitarias\n\n#     La estructura está lista para testeo automático si desacoplas el input() / print().\n\n# 📊 Conclusión en Puntos\n# Criterio\tEvaluación\tComentario breve\n# SRP (Responsabilidad única)\t✅ 80% cumplido\tTurn tiene demasiadas tareas\n# OCP (Abierto/cerrado)\t✅ Excelente\tFácil de extender\n# LSP (Sustitución)\t✅ Sin problemas\tTodo sustituible sin romper\n# ISP (Interfaces claras)\t✅ Bien aplicado\tSin métodos forzados\n# DIP (Inversión de dependencias)\t✅ ✔ Cumplido con abstracciones\tMuy bien hecho"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/python/rigo93acosta.py",
    "content": "'''\n * EJERCICIO:\n * ¡Deadpool y Wolverine se enfrentan en una batalla épica!\n * Crea un programa que simule la pelea y determine un ganador.\n * El programa simula un combate por turnos, donde cada protagonista posee unos\n * puntos de vida iniciales, un daño de ataque variable y diferentes cualidades\n * de regeneración y evasión de ataques.\n * Requisitos:\n * 1. El usuario debe determinar la vida inicial de cada protagonista.\n * 2. Cada personaje puede impartir un daño aleatorio:\n *    - Deadpool: Entre 10 y 100.\n *    - Wolverine: Entre 10 y 120.\n * 3. Si el daño es el máximo, el personaje que lo recibe no ataca en el\n * siguiente turno, ya que tiene que regenerarse (pero no aumenta vida).\n * 4. Cada personaje puede evitar el ataque contrario:\n *    - Deadpool: 25% de posibilidades.\n *    - Wolverine: 20% de posibilidades.\n * 5. Un personaje pierde si sus puntos de vida llegan a cero o menos.\n * Acciones:\n * 1. Simula una batalla.\n * 2. Muestra el número del turno (pausa de 1 segundo entre turnos).\n * 3. Muestra qué pasa en cada turno.\n * 4. Muestra la vida en cada turno.\n * 5. Muestra el resultado final.\n'''\n### Libraries\nimport random\nimport time\n\n### Classes\n\nclass Character():\n    \n    def __init__(self, name, health, attack, evade):\n        self.name = name\n        self.health = health\n        self.attack = attack\n        self.evade = evade\n\n    def action_attack(self):\n        return random.randint(self.attack[0], self.attack[1])\n\n    def action_evade(self):\n        return random.randint(1, 100) <= self.evade\n    \n    def get_health(self):\n        return self.health\n\n    def get_critical(self):\n        return self.attack[1]\n\nif __name__ == \"__main__\":\n    \n    deadpool_health = int(input(\"Ingrese la vida de Deadpool: \"))\n    wolverine_health = int(input(\"Ingrese la vida de Wolverine: \"))\n    deadpool = Character(\"Deadpool\", deadpool_health, [10, 100], 25)\n    wolverine = Character(\"Wolverine\", wolverine_health, [10, 120], 20)\n\n    ## Eleccion de quien inicia\n    flag_init = random.randint(0, 1) ## 0 Deadpool, 1 Wolverine\n    flag_deadpool_recovery = False ## Deadpool se está regenerando\n    flag_wolverine_recovery = False ## Wolverine se está regenerando\n    print(\"================== Batalla Wolwerine vs Deadpool ==================\")\n\n    turn = 1\n    while True:\n        \n        print(f\"\\n================== Turno {turn} ==================\\n\")\n\n        if flag_deadpool_recovery:\n            print(\"==== Deadpool se está regenerando ==== \")\n            flag_deadpool_recovery = False\n        else:\n            deadpool_damage = deadpool.action_attack()\n            print(f\"Deadpool ataca a Wolverine con un daño de {deadpool_damage}\")\n            if deadpool_damage == deadpool.get_critical():\n                print(\"Wolverine no podrá atacar en el siguiente turno\")\n                flag_wolverine_recovery = True\n                wolverine.health -= deadpool_damage\n            else:\n                if wolverine.action_evade():\n                    print(\"Wolverine ha evadido el ataque\")\n                else:\n                    wolverine.health -= deadpool_damage\n\n        if flag_wolverine_recovery:\n            print(\"Wolverine se está regenerando\")\n            flag_wolverine_recovery = False\n        else:\n            wolverine_damage = wolverine.action_attack()\n            print(f\"Wolverine ataca a Deadpool con un daño de {wolverine_damage}\")\n            if wolverine_damage == wolverine.get_critical():\n                print(\"Deadpool no podrá atacar en el siguiente turno\")\n                flag_deadpool_recovery = True\n                deadpool.health -= wolverine_damage\n            else:\n                if deadpool.action_evade():\n                    print(\"Deadpool ha evadido el ataque\")\n                else:\n                    deadpool.health -= wolverine_damage\n\n        if deadpool.get_health() <= 0:\n            print(\"\\n===============================\")\n            print(\"!!!!! Wolverine ha ganado !!!!!\")\n            print(\"===============================\\n\")\n            break\n        if wolverine.get_health() <= 0:\n            print(\"\\n===============================\")\n            print(\"!!!!! Deadpool ha ganado !!!!!!\")\n            print(\"===============================\\n\")\n            break\n        \n        print(f\"====== Deadpool tiene {deadpool.get_health()} puntos de vida ======\")\n\n        print(f\"====== Wolverine tiene {wolverine.get_health()} puntos de vida ======\")\n\n        turn += 1\n        time.sleep(1) ## Espera\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/python/santyjl.py",
    "content": "# #32 BATALLA DEADPOOL Y WOLVERINE\n#### Dificultad: Media | Publicación: 05/08/24 | Corrección: 12/08/24\n\n\"\"\"\n/*\n * EJERCICIO:\n * ¡Deadpool y Wolverine se enfrentan en una batalla épica!\n * Crea un programa que simule la pelea y determine un ganador.\n * El programa simula un combate por turnos, donde cada protagonista posee unos\n * puntos de vida iniciales, un daño de ataque variable y diferentes cualidades\n * de regeneración y evasión de ataques.\n * Requisitos:\n * 1. El usuario debe determinar la vida inicial de cada protagonista.\n * 2. Cada personaje puede impartir un daño aleatorio:\n *    - Deadpool: Entre 10 y 100.\n *    - Wolverine: Entre 10 y 120.\n * 3. Si el daño es el máximo, el personaje que lo recibe no ataca en el\n * siguiente turno, ya que tiene que regenerarse (pero no aumenta vida).\n * 4. Cada personaje puede evitar el ataque contrario:\n *    - Deadpool: 25% de posibilidades.\n *    - Wolverine: 20% de posibilidades.\n * 5. Un personaje pierde si sus puntos de vida llegan a cero o menos.\n * Acciones:\n * 1. Simula una batalla.\n * 2. Muestra el número del turno (pausa de 1 segundo entre turnos).\n * 3. Muestra qué pasa en cada turno.\n * 4. Muestra la vida en cada turno.\n * 5. Muestra el resultado final.\n */\n\"\"\"\n\nimport os\nimport random\nimport time\n\n\ndef barra_de_vida(vida : float):\n    for i in range(int(vida//10)):\n        print(\"💗=\" , end=\"\")\n\n    print(\"\")\n\ndef daño(peleador: int) -> int:\n    valor_daño = 0\n\n    if peleador == 1 :\n        valor_daño = random.randint(10 , 120)\n        if valor_daño > 30:\n            valor_daño //= 3\n\n    else:\n        valor_daño = random.randint(10 , 100)\n        if valor_daño > 30:\n            valor_daño //= 3\n\n    return valor_daño\n\nvida_Wolverine = float(input(\"Ingresa la vida de Wolverine: \"))\nvida_Deadpool = float(input(\" Ingresa la vida de DeadPool: \"))\n\nturno = 0\n\nprint(\" ¡Deadpool y Wolverine se enfrentan en una batalla épica!, algo indescriptible pero no imposible de crer.\\n\")\ntime.sleep(1)\nprint(\"Wolverine toma siempre la iniciativa y va con todo contra Deadpool\")\n\nwhile True:\n    os.system(\"cls\")\n    turno += 1\n\n    if vida_Deadpool <= 0 or vida_Wolverine <= 0:\n        print(\"final de la batalla, El ganador a sido ......\")\n        time.sleep(2)\n\n        print(f\" :========== {\" Deadpool🦴\" if vida_Deadpool > vida_Wolverine else \"Wolverine🐆\"} ==========: \")\n        break\n\n    print(f\"====== Ronda {turno} ======\")\n    evitar_golpe = random.randint(1 , 100)\n\n    print(\"Vida de Wolverine : \" , end=\"\")\n    barra_de_vida(vida_Wolverine)\n    print(\"Vida Deadpool : \", end=\"\")\n    barra_de_vida(vida_Deadpool)\n\n\n\n\n    if turno % 2 == 0 and evitar_golpe > 25:\n        daño_infligido = daño(2)\n        print(f\"Deadpool le ha dado efectivamente a Wolverine un golpe con un daño de {daño_infligido}\")\n\n        vida_Wolverine -= daño_infligido\n\n    elif turno % 2 == 0 :\n        print(f\"Deadpool fue con todo para darle a Wolverine pero fue equivado.\")\n\n\n    if turno % 2 != 0 and evitar_golpe > 20:\n        daño_infligido = daño(1)\n        print(f\"Wolverine le ha dado efectivamente a Deadpool un golpe con un daño de {daño_infligido}\")\n\n        vida_Deadpool -= daño_infligido\n\n    elif turno % 2 != 0 :\n        print(f\"Wolverine fue tan rapido como una pantera pero fue equivado por Deadpool en el último segundo. \")\n\n    time.sleep(4.5)\n\n\n\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/rust/kenysdev.rs",
    "content": "/*\n╔═══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado                ║\n║ GitHub: https://github.com/Kenysdev   ║\n║ 2024 -  Rust                          ║\n╚═══════════════════════════════════════╝\n-----------------------------------------------------\n* BATALLA DEADPOOL Y WOLVERINE\n-----------------------------------------------------\n\n* EJERCICIO:\n * ¡Deadpool y Wolverine se enfrentan en una batalla épica!\n * Crea un programa que simule la pelea y determine un ganador.\n * El programa simula un combate por turnos, donde cada protagonista posee unos\n * puntos de vida iniciales, un daño de ataque variable y diferentes cualidades\n * de regeneración y evasión de ataques.\n * Requisitos:\n * 1. El usuario debe determinar la vida inicial de cada protagonista.\n * 2. Cada personaje puede impartir un daño aleatorio:\n *    - Deadpool: Entre 10 y 100.\n *    - Wolverine: Entre 10 y 120.\n * 3. Si el daño es el máximo, el personaje que lo recibe no ataca en el\n * siguiente turno, ya que tiene que regenerarse (pero no aumenta vida).\n * 4. Cada personaje puede evitar el ataque contrario:\n *    - Deadpool: 25% de posibilidades.\n *    - Wolverine: 20% de posibilidades.\n * 5. Un personaje pierde si sus puntos de vida llegan a cero o menos.\n * Acciones:\n * 1. Simula una batalla.\n * 2. Muestra el número del turno (pausa de 1 segundo entre turnos).\n * 3. Muestra qué pasa en cada turno.\n * 4. Muestra la vida en cada turno.\n * 5. Muestra el resultado final.\n*/\n\n// _____\n// NOTA: Estoy intentando practicar los principios SOLID. XD 😂\n\n// ________________________________________________\n\n// [dependencies]\n// rand = \"0.8.5\"\n// https://crates.io/crates/rand\nuse rand::prelude::*;\n\nuse std::io::{self, Write};\nuse std::collections::HashMap;\nuse std::thread::sleep;\nuse std::time::Duration;\n\n// ---------------------------------------\n// INTERFACES\n// ---------------------------------------\n\n/// Contrato sobre la configuración global del juego.\npub trait IGlobalConfig {\n    fn turn_interval(&self) -> i32;\n    fn minimum_hp(&self) -> i32;\n    /// Diccionario de personajes, con sus habilidades, Daño posible, Probabilidad de defensa.\n    /// Fácil de adaptar a un Json de personajes.\n    /// {\"Character\": {\"attacks\": [\"Attack1\", \"Attack2\"], \"damage_range\": (10, 100), \"defense_chance\": 0.25}}\n    fn characters(&self) -> &HashMap<String, TCharacterConfig>;\n    fn menu(&self) -> &str;\n}\n\n/// Clase que define la configuración del personaje\n#[derive(Clone)]\npub struct TCharacterConfig {\n    pub attacks: Vec<String>,\n    pub damage_range: (i32, i32),\n    pub defense_chance: f64,\n}\n\npub trait IInput {\n    /// # Returns\n    /// Retorna un dato `entero` que no debe ser vacío.\n    fn get_int(&self, msg: &str) -> i32;\n}\n\n/// Contrato para los datos y métodos de un personaje instanciado.\npub trait ICharacter {\n    fn name(&self) -> &str;\n    fn set_name(&mut self, name: String);\n    fn hp(&self) -> i32;\n    fn set_hp(&mut self, hp: i32);\n    fn can_attack(&self) -> bool;\n    fn set_can_attack(&mut self, can_attack: bool);\n    fn attacks(&self) -> &Vec<String>;\n    fn damage_range(&self) -> (i32, i32);\n    fn defense_chance(&self) -> f64;\n    fn add(&mut self, name: String, hp: i32, attributes: TCharacterConfig);\n    /// Verifica si puede atacar, realiza un ataque y devuelve el daño infligido.\n    fn attack(&self) -> i32;\n    /// Determina si el personaje puede defenderse y lo retorna.\n    fn defend(&self) -> bool;\n}\n\n/// Contrato para lógica de batalla.\npub trait IBattleStrategy {\n    /// Ejecuta la estrategia de batalla entre el atacante y el defensor.\n    /// # Returns\n    /// Retorna verdadero si el defensor sigue en pie, falso si el atacante gana la batalla.\n    fn execute(&self, attacker: &mut dyn ICharacter, defender: &mut dyn ICharacter) -> bool;\n}\n\n// ---------------------------------------\n// IMPLEMENTACIÓN DE INTERFACES\n// ---------------------------------------\npub struct DefaultConfig {\n    characters: HashMap<String, TCharacterConfig>,\n}\n\nimpl IGlobalConfig for DefaultConfig {\n    fn turn_interval(&self) -> i32 { 1 }\n    fn minimum_hp(&self) -> i32 { 200 }\n    fn characters(&self) -> &HashMap<String, TCharacterConfig> { &self.characters }\n    fn menu(&self) -> &str {\n        \"\\nSIMULADOR DE BATALLAS:\\n\\\n        -------------------------------------------\\n\\\n        | 1. Simular una batalla |    2. Salir    |\\n\\\n        -------------------------------------------\"\n    }\n}\n\nimpl DefaultConfig {\n    pub fn new() -> Self {\n        let mut characters = HashMap::new();\n        characters.insert(\"Deadpool\".to_string(), TCharacterConfig {\n            attacks: vec![\"Con arma\".to_string(), \"Cuerpo a cuerpo\".to_string(), \"Ataque imprudente\".to_string()],\n            damage_range: (10, 100),\n            defense_chance: 0.25,\n        });\n        characters.insert(\"Wolverine\".to_string(), TCharacterConfig {\n            attacks: vec![\"Con garras de adamantium\".to_string(), \"Con arma\".to_string(), \"Cuerpo a cuerpo\".to_string()],\n            damage_range: (10, 120),\n            defense_chance: 0.2,\n        });\n        DefaultConfig { characters }\n    }\n}\n\npub struct ConsoleInput;\n\nimpl IInput for ConsoleInput {\n    fn get_int(&self, msg: &str) -> i32 {\n        loop {\n            print!(\"{}\", msg);\n            io::stdout().flush().expect(\"Error: limpiar búfer\");\n\n            let mut input = String::new();\n            io::stdin()\n                .read_line(&mut input)\n                .expect(\"Error al leer la entrada\");\n\n            match input.trim().parse() {\n                Ok(num) => return num,\n                Err(_) => println!(\"Ingresa un número entero.\"),\n            }\n        }\n    }\n}\n\npub struct DefaultCharacter {\n    name: String,\n    hp: i32,\n    can_attack: bool,\n    attacks: Vec<String>,\n    damage_range: (i32, i32),\n    defense_chance: f64,\n}\n\nimpl Default for DefaultCharacter {\n    fn default() -> Self {\n        DefaultCharacter {\n            name: \"Unknown\".to_string(),\n            hp: 200,\n            can_attack: true,\n            attacks: vec![\"Basic Attack\".to_string()],\n            damage_range: (5, 90),\n            defense_chance: 0.25,\n        }\n    }\n}\n\nimpl ICharacter for DefaultCharacter {\n    fn name(&self) -> &str { &self.name }\n    fn set_name(&mut self, name: String) { self.name = name; }\n    fn hp(&self) -> i32 { self.hp }\n    fn set_hp(&mut self, hp: i32) { self.hp = hp; }\n    fn can_attack(&self) -> bool { self.can_attack }\n    fn set_can_attack(&mut self, can_attack: bool) { self.can_attack = can_attack; }\n    fn attacks(&self) -> &Vec<String> { &self.attacks }\n    fn damage_range(&self) -> (i32, i32) { self.damage_range }\n    fn defense_chance(&self) -> f64 { self.defense_chance }\n\n    fn add(&mut self, name: String, hp: i32, attributes: TCharacterConfig) {\n        self.name = name;\n        self.hp = hp;\n        self.attacks = attributes.attacks;\n        self.damage_range = attributes.damage_range;\n        self.defense_chance = attributes.defense_chance;\n        self.can_attack = true;\n    }\n\n    fn attack(&self) -> i32 {\n        if self.can_attack {\n            let mut rng = rand::thread_rng();\n            let damage = rng.gen_range(self.damage_range.0..=self.damage_range.1);\n            let selected_attack = &self.attacks[rng.gen_range(0..self.attacks.len())];\n            println!(\"|'{}'ataca '{}' causando un: '-{}' 👊|\", self.name, selected_attack, damage);\n            damage\n        } else {\n            println!(\"|'{}' se está regenerando y no puede atacar. 😴|\", self.name);\n            0\n        }\n    }\n\n    fn defend(&self) -> bool {\n        let defended = rand::thread_rng().gen_bool(self.defense_chance);\n        if defended {\n            println!(\"|'{}' logró defenderse. 🛡️|\", self.name);\n        } else {\n            println!(\"|'{}' no pudo bloquear el ataque. 🤕|\", self.name);\n        }\n        defended\n    }\n}\n\npub struct DefaultBattleStrategy;\n\nimpl IBattleStrategy for DefaultBattleStrategy {\n    fn execute(&self, attacker: &mut dyn ICharacter, defender: &mut dyn ICharacter) -> bool {\n        let damage = attacker.attack();\n        if damage == attacker.damage_range().1 {\n            println!(\"|'{}' 🚨Recibió un ataque crítico y no podrá atacar.🚨|\", defender.name());\n            defender.set_can_attack(false);\n        }\n        if attacker.can_attack() {\n            if !defender.defend() {\n                defender.set_hp(defender.hp() - damage);\n            }\n        } else {\n            attacker.set_can_attack(true);\n        }\n        if defender.hp() <= 0 {\n            println!(\"\\n____________________________\");\n            println!(\"|'{}' 🏆Gana la batalla. 🏆|\", attacker.name());\n            return false;\n        }\n        true\n    }\n}\n\n\n// ---------------------------------------\n// INYECCIÓN DE DEPENDENCIAS\n// ---------------------------------------\n\npub struct Features {\n    global_config: Box<dyn IGlobalConfig>,\n    input: Box<dyn IInput>,\n    strategy: Box<dyn IBattleStrategy>,\n    player1: Box<dyn ICharacter>,\n    player2: Box<dyn ICharacter>,\n}\n\nimpl Features {\n    fn new() -> Self {\n        Features {\n            global_config: Box::new(DefaultConfig::new()),\n            input: Box::new(ConsoleInput),\n            strategy: Box::new(DefaultBattleStrategy),\n            player1: Box::new(DefaultCharacter::default()),\n            player2: Box::new(DefaultCharacter::default()),\n        }\n    }\n}\n\npub struct Simulation {\n    features: Features,\n}\n\nimpl Simulation {\n    pub fn new(features: Features) -> Self {\n        Simulation { features }\n    }\n\n    pub fn show_hp(&self) {\n        println!(\"____________________________\");\n        println!(\n            \"|{}: ❤️ {}| |{}: ❤️ {}|\",\n            self.features.player1.name(),\n            self.features.player1.hp(),\n            self.features.player2.name(),\n            self.features.player2.hp()\n        );\n    }\n\n    fn init_battle(&mut self) {\n        let mut turn = 1;\n        loop {\n            println!(\"\\n----------------------------\");\n            println!(\"Turno #{}\", turn);\n            println!(\"----------------------------\");\n\n            self.show_hp();\n            // Ataque de personaje #1 hacia #2\n            if !self.features.strategy.execute(&mut *self.features.player1, &mut *self.features.player2) {\n                break;\n            }\n\n            self.show_hp();\n            // Ataque de personaje #2 hacia #1\n            if !self.features.strategy.execute(&mut *self.features.player2, &mut *self.features.player1) {\n                break;\n            }\n\n            turn += 1;\n            sleep(Duration::from_secs(self.features.global_config.turn_interval() as u64));\n        }\n\n        self.show_hp();\n    }\n\n    fn add(&mut self, msg: &str, player: &str) {\n        loop {\n            let index = self.features.input.get_int(msg);\n            let keys: Vec<String> = self.features.global_config.characters().keys().cloned().collect();\n            if index < 0 || index >= keys.len() as i32 {\n                println!(\"Número de personaje incorrecto.\");\n                continue;\n            }\n            let name = &keys[index as usize];\n            if name == self.features.player1.name() {\n                println!(\"El personaje ya fue utilizado.\");\n                continue;\n            }\n            let attributes: TCharacterConfig =self.features.global_config.characters().get(name).unwrap().clone();\n            let hp = loop {\n                let hp = self.features.input.get_int(&format!(\"Establecer una vida >= que '{}': \",self.features.global_config.minimum_hp()));\n                if hp >= self.features.global_config.minimum_hp() {\n                    break hp;\n                }\n                println!(\"La vida debe ser mayor o igual que '{}'.\", self.features.global_config.minimum_hp());\n            };\n\n            if player == \"player1\" {\n                self.features.player1.add(name.clone(), hp, attributes);\n            } else if player == \"player2\" {\n                self.features.player2.add(name.clone(), hp, attributes); \n            }\n            \n            break;\n        }\n    }\n\n    pub fn start(&mut self) {\n        println!(\"Personajes disponibles:\");\n        let characters: Vec<String> = self.features.global_config.characters().keys().cloned().collect();\n        for (i, character) in characters.iter().enumerate() {\n            println!(\"{}: {}\", i, character);\n        }\n\n        self.add(\"'Primer' personaje: \", \"player1\");\n        self.add(\"'Segundo' personaje: \", \"player2\");\n\n        self.init_battle();\n\n        // Restablecer para iniciar nueva simulación\n        self.features.player1.set_name(\"Unknown\".to_string());\n        self.features.player2.set_name(\"Unknown\".to_string());\n        println!(\"{}\", self.features.global_config.menu());\n    }\n}\n\npub struct Program {\n    features: Features,\n}\n\nimpl Program {\n    pub fn new(features: Features) -> Self {\n        Program { features }\n    }\n\n    fn run(&mut self) {\n        println!(\"{}\", self.features.global_config.menu());\n        let mut simulation = Simulation::new(Features::new());\n\n        loop {\n            let option = self.features.input.get_int(\"\\nOpción: \");\n            match option {\n                1 => {\n                    simulation.start();\n                },\n                2 => {\n                    println!(\"Adiós\");\n                    return;\n                }\n                _ => println!(\"Seleccionar de '1 o 2'\"),\n            }\n        }\n    }\n}\n\nfn main() {\n    let mut program = Program::new(Features::new());\n    program.run();\n}\n\n// _____\n// NOTA: Estoy intentando practicar los principios SOLID. XD 😂\n\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/sql/Nicojsuarez2.sql",
    "content": "# #32 BATALLA DEADPOOL Y WOLVERINE\n> #### Dificultad: Media | Publicación: 05/08/24 | Corrección: 12/08/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * ¡Deadpool y Wolverine se enfrentan en una batalla épica!\n * Crea un programa que simule la pelea y determine un ganador.\n * El programa simula un combate por turnos, donde cada protagonista posee unos\n * puntos de vida iniciales, un daño de ataque variable y diferentes cualidades\n * de regeneración y evasión de ataques.\n * Requisitos:\n * 1. El usuario debe determinar la vida inicial de cada protagonista.\n * 2. Cada personaje puede impartir un daño aleatorio:\n *    - Deadpool: Entre 10 y 100.\n *    - Wolverine: Entre 10 y 120.\n * 3. Si el daño es el máximo, el personaje que lo recibe no ataca en el\n * siguiente turno, ya que tiene que regenerarse (pero no aumenta vida).\n * 4. Cada personaje puede evitar el ataque contrario:\n *    - Deadpool: 25% de posibilidades.\n *    - Wolverine: 20% de posibilidades.\n * 5. Un personaje pierde si sus puntos de vida llegan a cero o menos.\n * Acciones:\n * 1. Simula una batalla.\n * 2. Muestra el número del turno (pausa de 1 segundo entre turnos).\n * 3. Muestra qué pasa en cada turno.\n * 4. Muestra la vida en cada turno.\n * 5. Muestra el resultado final.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/typescript/AaronLopezBarros.ts",
    "content": "import * as readline from \"readline\";\nimport { setTimeout } from \"timers/promises\";\n\n//--------------------------------//\n//             CONSTS             //\n//--------------------------------//\n\nconst TURN_DELAY = 1000;\n\n//--------------------------------//\n//           INTERFACES           //\n//--------------------------------//\ninterface SuperHero {\n  name: string;\n  health: number;\n  attackRange: Array<number>;\n  evadePercentage: number;\n  isRegenerating: boolean;\n  isWinner: boolean;\n}\n\n//--------------------------------//\n//         UTILS FUNCTIONS        //\n//--------------------------------//\n\nconst askQuestion = (query: string): Promise<string> => {\n  const rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout,\n  });\n\n  return new Promise((resolve) => {\n    rl.question(query, (answer) => {\n      resolve(answer);\n      rl.close();\n    });\n  });\n};\n\n//--------------------------------//\n//       SUPERHERO CONFIG         //\n//--------------------------------//\n\nconst createSuperHero = (\n  name: string,\n  attackRange: [number, number],\n  evadePercentage: number\n): SuperHero => ({\n  name,\n  health: 0,\n  attackRange,\n  evadePercentage,\n  isRegenerating: false,\n  isWinner: false,\n});\n\n//--------------------------------//\n//       BATTLE MECHANICS         //\n//--------------------------------//\n\nconst calculateAttack = (superHero: SuperHero): number => {\n  const [min, max] = superHero.attackRange;\n  return Math.floor(Math.random() * (max - min)) + min;\n};\n\nconst attemptEvade = (superHero: SuperHero): boolean => {\n  return Math.random() * 100 < superHero.evadePercentage;\n};\n\nconst applyDamage = (damage: number, superHero: SuperHero): void => {\n  superHero.health -= damage;\n};\n\nconst executeTurn = async (\n  attacker: SuperHero,\n  victim: SuperHero,\n  turnNumber: number\n): Promise<void> => {\n  console.log(`--- Turn ${turnNumber}: ${attacker.name} atack ---\\n`);\n\n  if (!attacker.isRegenerating) {\n    const damage = calculateAttack(attacker);\n    if (attemptEvade(victim)) {\n      console.log(`${victim.name} avoided ${attacker.name} atack!`);\n    } else {\n      applyDamage(damage, victim);\n      console.log(\n        `${attacker.name} hits ${victim.name} with ${damage} points of damage!`\n      );\n      if (damage === attacker.attackRange[1]) {\n        victim.isRegenerating = true;\n        console.log(`Maximum damage! ${victim.name} will miss his next turn.`);\n      }\n    }\n  } else {\n    console.log(`${attacker.name} recovers and loses his turn.`);\n    attacker.isRegenerating = false;\n  }\n\n  console.log(`\\n[__${attacker.name} tiene ${attacker.health} de vida__]`);\n  console.log(`[__${victim.name} tiene ${victim.health} de vida__]\\n`);\n\n  if (victim.health <= 0) {\n    attacker.isWinner = true;\n  }\n\n  await setTimeout(TURN_DELAY);\n};\n\nconst superHeroesFight = async (\n  superHeroOne: SuperHero,\n  superHeroTwo: SuperHero,\n  turnCount: number\n): Promise<void> => {\n  await executeTurn(superHeroOne, superHeroTwo, turnCount);\n  if (!superHeroOne.isWinner) {\n    await executeTurn(superHeroTwo, superHeroOne, turnCount + 1);\n  }\n};\n\nconst initializeHeroes = async (\n  heroOne: SuperHero,\n  heroTwo: SuperHero\n): Promise<void> => {\n  heroOne.health = parseInt(\n    await askQuestion(`Ingrese la vida de ${heroOne.name}: `)\n  );\n  heroTwo.health = parseInt(\n    await askQuestion(`Ingrese la vida de ${heroTwo.name}: `)\n  );\n};\n\nconst startBattle = async (\n  superHeroOne: SuperHero,\n  superHeroTwo: SuperHero\n): Promise<SuperHero> => {\n  await initializeHeroes(superHeroOne, superHeroTwo);\n\n  console.log(\n    `\\nComienza la batalla entre ${superHeroOne.name} y ${superHeroTwo.name}\\n`\n  );\n\n  let turnCount = 1;\n  while (!superHeroOne.isWinner && !superHeroTwo.isWinner) {\n    await superHeroesFight(superHeroOne, superHeroTwo, turnCount);\n    turnCount += 2;\n  }\n\n  const winner = superHeroOne.isWinner ? superHeroOne : superHeroTwo;\n  console.log(`The winner is ${winner.name}!`);\n\n  return winner;\n};\n\n//--------------------------------//\n//              MAIN              //\n//--------------------------------//\n\nconst wolverine = createSuperHero(\"Wolverine\", [10, 100], 0.2);\nconst deadpool = createSuperHero(\"Deadpool\", [10, 120], 0.25);\n\nconst main = async (): Promise<void> => {\n  await startBattle(wolverine, deadpool);\n};\n\nmain();\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/typescript/hozlucas28.ts",
    "content": "import {setTimeout} from 'timers/promises'\n\n/* -------------------------------------------------------------------------- */\n/*                     SUPERHEROREGENERATINGERROR (ERROR)                     */\n/* -------------------------------------------------------------------------- */\n\nclass SuperheroRegeneratingError extends Error {\n    public constructor(superhero: ISuperhero) {\n        super(`${superhero.getName()} is regenerating`)\n        this.name = 'SuperheroRegeneratingError'\n    }\n}\n\n/* -------------------------------------------------------------------------- */\n/*                              SUPERHERO (CLASS)                             */\n/* -------------------------------------------------------------------------- */\n\ninterface ISuperhero {\n    getAttackDamage: () => Readonly<[number, number]>\n    getLifePoints: () => number\n    getName: () => Capitalize<string>\n    isRegenerating: () => boolean\n    setRegenerating: (regenerating: boolean) => this\n    evadeAttack: () => boolean\n    produceDamage: () => number | never\n    receiveDamage: (damage: number) => this\n}\n\ninterface SuperheroConstructor {\n    lifePoints: number\n    attackDamage: [number, number]\n    evadePercentage: number\n    name: Capitalize<string>\n}\n\nclass Superhero implements ISuperhero {\n    private lifePoints: number\n    private regenerating: boolean\n    private readonly attackDamage: Readonly<[number, number]>\n    private readonly evadePercentage: number\n    private readonly name: Capitalize<string>\n\n    protected constructor({\n        attackDamage,\n        evadePercentage,\n        lifePoints,\n        name,\n    }: SuperheroConstructor) {\n        this.lifePoints = lifePoints\n        this.regenerating = false\n        this.attackDamage = attackDamage\n        this.evadePercentage = evadePercentage\n        this.name = name\n    }\n\n    public getAttackDamage(): Readonly<[number, number]> {\n        return this.attackDamage\n    }\n\n    public getLifePoints(): number {\n        return this.lifePoints\n    }\n\n    public getName(): Capitalize<string> {\n        return this.name\n    }\n\n    public isRegenerating(): boolean {\n        return this.regenerating\n    }\n\n    public setRegenerating(regenerating: boolean): this {\n        this.regenerating = regenerating\n        return this\n    }\n\n    public evadeAttack(): boolean {\n        const rndNumber: number = Math.random()\n        return rndNumber <= this.evadePercentage\n    }\n\n    public produceDamage(): number | never {\n        if (this.isRegenerating()) throw new SuperheroRegeneratingError(this)\n\n        const [minAttackDamage, maxAttackDamage]: readonly [number, number] =\n            this.getAttackDamage()\n\n        const rndDamage: number = Math.max(\n            minAttackDamage,\n            Math.round(Math.random() * maxAttackDamage)\n        )\n\n        return rndDamage\n    }\n\n    public receiveDamage(damage: number): this {\n        this.lifePoints -= damage\n        return this\n    }\n}\n\n/* -------------------------------------------------------------------------- */\n/*                              WOLVERINE (CLASS)                             */\n/* -------------------------------------------------------------------------- */\n\ninterface IWolverine {}\n\ninterface WolverineConstructor\n    extends Omit<\n        SuperheroConstructor,\n        'attackDamage' | 'evadePercentage' | 'name'\n    > {}\n\nclass Wolverine extends Superhero implements IWolverine {\n    public constructor({lifePoints}: WolverineConstructor) {\n        super({\n            attackDamage: [10, 120],\n            evadePercentage: 0.2,\n            lifePoints,\n            name: 'Wolverine',\n        })\n    }\n}\n\n/* -------------------------------------------------------------------------- */\n/*                              DEADPOOL (CLASS)                              */\n/* -------------------------------------------------------------------------- */\n\ninterface IDeadpool {}\n\ninterface DeadpoolConstructor\n    extends Omit<\n        SuperheroConstructor,\n        'attackDamage' | 'evadePercentage' | 'name'\n    > {}\n\nclass Deadpool extends Superhero implements IDeadpool {\n    public constructor({lifePoints}: DeadpoolConstructor) {\n        super({\n            attackDamage: [10, 100],\n            evadePercentage: 0.25,\n            lifePoints,\n            name: 'Deadpool',\n        })\n    }\n}\n\n/* -------------------------------------------------------------------------- */\n/*                          SUPERHEROESFIGHT (CLASS)                          */\n/* -------------------------------------------------------------------------- */\n\ninterface Turn {\n    attacker: ISuperhero\n    number: number\n    victim: ISuperhero\n}\n\ninterface ExecutedTurn extends Turn {\n    damageProducedByAttacker: number\n    damageReceivedByVictim: number\n    victimAvoidAttack: boolean\n}\n\ninterface ISuperheroFight {\n    getTurn: () => Readonly<Turn>\n    getWinner: () => ISuperhero | undefined\n    executeTurn: () => Readonly<ExecutedTurn> | never\n}\n\ninterface SuperheroFightConstructor {\n    superHeroOne: ISuperhero\n    superHeroTwo: ISuperhero\n}\n\nclass SuperheroFight implements ISuperheroFight {\n    private turn: Readonly<Turn>\n    private winner: undefined | ISuperhero\n\n    public constructor({\n        superHeroOne,\n        superHeroTwo,\n    }: SuperheroFightConstructor) {\n        this.turn = {\n            attacker: superHeroOne,\n            number: 1,\n            victim: superHeroTwo,\n        }\n\n        this.winner = undefined\n    }\n\n    public getTurn(): Readonly<Turn> {\n        return this.turn\n    }\n\n    public getWinner(): undefined | ISuperhero {\n        return this.winner\n    }\n\n    public executeTurn(): Readonly<ExecutedTurn> | never {\n        const {attacker, number, victim} = this.getTurn()\n        victim.setRegenerating(false)\n\n        this.turn = {\n            attacker: victim,\n            number: number + 1,\n            victim: attacker,\n        }\n\n        try {\n            const damageProducedByAttacker = attacker.produceDamage()\n            const attackerAttackDamage: Readonly<[number, number]> =\n                attacker.getAttackDamage()\n\n            const victimAvoidAttack = victim.evadeAttack()\n\n            if (!victimAvoidAttack) {\n                victim.receiveDamage(damageProducedByAttacker)\n                victim.setRegenerating(\n                    damageProducedByAttacker === attackerAttackDamage[1]\n                )\n\n                if (victim.getLifePoints() <= 0) this.winner = attacker\n            }\n\n            return {\n                attacker,\n                victim,\n                number,\n                damageProducedByAttacker,\n                victimAvoidAttack,\n                damageReceivedByVictim: victimAvoidAttack\n                    ? 0\n                    : damageProducedByAttacker,\n            }\n        } catch (error) {\n            throw error\n        }\n    }\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\n;(async () => {\n    const deadpool: Deadpool = new Deadpool({lifePoints: 500})\n    const wolverine: Wolverine = new Wolverine({lifePoints: 500})\n\n    const superheroFight: SuperheroFight = new SuperheroFight({\n        superHeroOne: deadpool,\n        superHeroTwo: wolverine,\n    })\n\n    while (!superheroFight.getWinner()) {\n        await setTimeout(1000)\n        const currentTurn: Readonly<Turn> = superheroFight.getTurn()\n\n        try {\n            const executedTurn: Readonly<ExecutedTurn> =\n                superheroFight.executeTurn()\n\n            if (executedTurn.victimAvoidAttack) {\n                console.log(\n                    `\\n> Turn N°${\n                        currentTurn.number\n                    }: ${currentTurn.victim.getName()} avoided ${currentTurn.attacker.getName()} attack.`\n                )\n\n                continue\n            }\n\n            console.log(\n                `\\n> Turn N°${\n                    currentTurn.number\n                }: ${currentTurn.attacker.getName()} attacked ${currentTurn.victim.getName()} with ${\n                    executedTurn.damageProducedByAttacker\n                } points of damage.`\n            )\n\n            console.log(\n                `[ Life points of Deadpool: ${deadpool.getLifePoints()} ]\\n` +\n                    `[ Life points of Wolverine: ${wolverine.getLifePoints()} ]`\n            )\n        } catch (error) {\n            if (error instanceof SuperheroRegeneratingError) {\n                console.log(\n                    `\\n> Turn N°${currentTurn.number}: ${error.message}.`\n                )\n            }\n        }\n    }\n\n    console.log(`\\n¡The winner is ${superheroFight.getWinner()?.getName()}!`)\n})()\n"
  },
  {
    "path": "Roadmap/32 - BATALLA DEADPOOL Y WOLVERINE/vb.net/kenysdev.vb",
    "content": "' ╔══════════════════════════════════════╗\n' ║ Autor:  Kenys Alvarado               ║\n' ║ GitHub: https://github.com/Kenysdev  ║\n' ║ 2024 -  VB.NET                       ║\n' ╚══════════════════════════════════════╝\n'-----------------------------------------------------\n'* BATALLA DEADPOOL Y WOLVERINE\n'-----------------------------------------------------\n'* EJERCICIO\n' * ¡Deadpool y Wolverine se enfrentan en una batalla épica!\n' * Crea un programa que simule la pelea y determine un ganador.\n' * El programa simula un combate por turnos, donde cada protagonista posee unos\n' * puntos de vida iniciales, un daño de ataque variable y diferentes cualidades\n' * de regeneración y evasión de ataques.\n' * Requisitos:\n' * 1. El usuario debe determinar la vida inicial de cada protagonista.\n' * 2. Cada personaje puede impartir un daño aleatorio:\n' *    - Deadpool Entre 10 y 100.\n' *    - Wolverine: Entre 10 y 120.\n' * 3. Si el daño es el máximo, el personaje que lo recibe no ataca en el\n' * siguiente turno, ya que tiene que regenerarse (pero no aumenta vida).\n' * 4. Cada personaje puede evitar el ataque contrario:\n' *    - Deadpool 25% de posibilidades.\n' *    - Wolverine: 20% de posibilidades.\n' * 5. Un personaje pierde si sus puntos de vida llegan a cero o menos.\n' * Acciones:\n' * 1. Simula una batalla.\n' * 2. Muestra el número del turno (pausa de 1 segundo entre turnos).\n' * 3. Muestra qué pasa en cada turno.\n' * 4. Muestra la vida en cada turno.\n' * 5. Muestra el resultado final.\n' ____________________________________________________\n'' NOTA: Estoy intentando practicar los principios SOLID. XD 😂 \n\nImports System.Text\n\n' ---------------------------------------\n' INYECCIÓN DE DEPENDENCIAS\n' ---------------------------------------\n''' <summary>Definirá las interfaces con valores predeterminados.</summary>\nPublic Class Features\n    Implements IFeatures\n\n    Public Property GlobalConfig As IGlobalConfig = New DefaultConfig() Implements IFeatures.GlobalConfig\n    Public Property Input As IInput = New ConsoleInput() Implements IFeatures.Input\n    Public Property CharacterSetup As ICharacterSetup = New CharacterSetup() Implements IFeatures.CharacterSetup\n    Public Property Strategy As IBattleStrategy = New DefaultBattleStrategy() Implements IFeatures.Strategy\n    Public Property Player1 As ICharacter = New DefaultCharacter() Implements IFeatures.Player1\n    Public Property Player2 As ICharacter = New DefaultCharacter() Implements IFeatures.Player2\nEnd Class\n\n''' <summary>\n''' Recibimos instancias de 'Features' con las características del programa que dependen de las interfaces.\n''' </summary>\nPublic Class Program\n    Private ReadOnly _Ft As IFeatures\n    Private ReadOnly _Simulation As Simulation\n\n    Public Sub New(features As IFeatures, simulation As Simulation)\n        Me._Ft = features\n        Me._Simulation = simulation\n    End Sub\n\n    Public Shared Sub Main()\n        Console.OutputEncoding = Encoding.UTF8\n\n        Dim features As IFeatures = New Features()\n        Dim simulation As New Simulation(features)\n        Dim program As New Program(features, simulation)\n        program.Run()\n    End Sub\n\n    Public Sub Run()\n        Console.WriteLine(_Ft.GlobalConfig.Menu)\n        While True\n            Dim option_ As Integer = _Ft.Input.GetInt(vbCrLf & \"Opción: \")\n            Select Case option_\n                Case 1\n                    _Simulation.Start()\n\n                Case 2\n                    Console.WriteLine(\"Adios\")\n                    Return\n                Case Else\n                    Console.WriteLine(\"Seleccionar de '1 o 2'\")\n            End Select\n        End While\n    End Sub\nEnd Class\n\nPublic Class Simulation\n    Private ReadOnly Ft As IFeatures\n\n    Public Sub New(features As IFeatures)\n        Me.Ft = features\n    End Sub\n\n    Public Sub ShowHp()\n        Console.WriteLine(\"____________________________\")\n        Console.WriteLine($\"|{Ft.Player1.Name}: ❤️ {Ft.Player1.Hp}| |{Ft.Player2.Name}: ❤️ {Ft.Player2.Hp}|\")\n    End Sub\n\n    ''' <summary>Llevará a cabo el turno de la batalla.</summary>\n    Private Sub InitBattle()\n        Dim turn As Integer = 1\n        While True\n            Console.WriteLine(vbCrLf & \"----------------------------\" & vbCrLf & $\"Turno #{turn}\" & vbCrLf & \"----------------------------\")\n\n            ' Ataque de personaje #1 hacia #2\n            ShowHp()\n            If Not Ft.Strategy.Execute(Ft.Player1, Ft.Player2) Then\n                Exit While\n            End If\n\n            ' Ataque de personaje #2 hacia #1\n            ShowHp()\n            If Not Ft.Strategy.Execute(Ft.Player2, Ft.Player1) Then\n                Exit While\n            End If\n\n            turn += 1\n            Threading.Thread.Sleep(Ft.GlobalConfig.TurnInterval * 1000)\n        End While\n\n        ShowHp()\n    End Sub\n\n    Public Sub Start()\n        Console.WriteLine(\"Personajes disponibles:\")\n        Dim characters As List(Of String) = Ft.GlobalConfig.Characters.Keys.ToList()\n        For i As Integer = 0 To characters.Count - 1\n            Console.WriteLine($\"{i}. {characters(i)}\")\n        Next\n\n        ' Configurar Personajes\n        Ft.CharacterSetup.Add(Ft, vbCrLf & \"'Primer' personaje: \", Ft.Player1)\n        Ft.CharacterSetup.Add(Ft, \"'Segundo' personaje: \", Ft.Player2)\n\n        InitBattle()\n\n        Ft.Player1.Name = String.Empty ' Restablecer para iniciar nueva simulación.\n        Console.WriteLine(Ft.GlobalConfig.Menu)\n    End Sub\nEnd Class\n\n'' ---------------------------------------\n'' INTERFACES\n'' ---------------------------------------\nPublic Interface IFeatures\n    ''' <summary>Configuración global del juego.</summary>\n    Property GlobalConfig As IGlobalConfig\n    ''' <summary>Interfaz para la entrada del usuario.</summary>\n    Property Input As IInput\n    ''' <summary>Interfaz para la configuración de los personajes.</summary>\n    Property CharacterSetup As ICharacterSetup\n    ''' <summary>Estrategia de batalla.</summary>\n    Property Strategy As IBattleStrategy\n    Property Player1 As ICharacter\n    Property Player2 As ICharacter\nEnd Interface\n\n''' <summary>Contrato para la configuración global.</summary>\nPublic Interface IGlobalConfig\n    ReadOnly Property TurnInterval As Integer\n    ReadOnly Property MinimumHp As Integer\n    ''' <summary>\n    ''' Diccionario de personajes, con sus habilidades, Daño posible, Probabilidad de defensa.\n    ''' Fácil de adaptar a un Json de personajes.\n    ''' {\"Character\": {\"attacks\": [\"Attack1\", \"Attack2\"], \"damage_range\": (10, 100), \"defense_chance\": 0.25}}\n    ''' </summary>\n    ReadOnly Property Characters As IDictionary(Of String, TCharacterConfig)\n    ReadOnly Property Menu As String\nEnd Interface\n\n''' <summary>Clase que define la configuración del personaje</summary>\nPublic Class TCharacterConfig\n    Public Property Attacks As List(Of String)\n    Public Property DamageRange As (Min As Integer, Max As Integer)\n    Public Property DefenseChance As Double\nEnd Class\n\nPublic Interface IInput\n    ''' <returns>Un dato entero que no debe ser vacío.</returns>\n    Function GetInt(msg As String) As Integer\nEnd Interface\n\n''' <summary>Contrato para los datos y métodos de un personaje.</summary>\nPublic Interface ICharacter\n    Property Name As String\n    Property Hp As Integer\n    Property CanAttack As Boolean\n    Property Attacks As List(Of String)\n    Property DamageRange As (MinDamage As Integer, MaxDamage As Integer)\n    Property DefenseChance As Double\n\n    Sub Add(name As String, hp As Integer, attributes As TCharacterConfig)\n\n    ''' <summary>Verifica si puede atacar, realiza un ataque y devuelve el daño infligido.</summary>\n    Function Attack() As Integer\n\n    ''' <summary>Determina si el personaje puede defenderse y lo retorna.</summary>\n    Function Defend() As Boolean\nEnd Interface\n\n''' <summary>Contrato para agrega datos de los personajes.</summary>\nPublic Interface ICharacterSetup\n    '''<summary>Agrega datos de los personajes.</summary>\n    ''' <param name=\"msg\">Mensaje a mostrar al usuario.</param>\n    ''' <param name=\"player\">La instancia del personaje a configurar.</param>\n    Sub Add(Ft As IFeatures, msg As String, player As ICharacter)\nEnd Interface\n\nPublic Interface IBattleStrategy\n    ''' <summary>Ejecuta la estrategia de batalla entre el atacante y el defensor.</summary>\n    ''' <returns>Retorna verdadero si el defensor sigue en pie, falso si el atacante gana la batalla.</returns>\n    Function Execute(attacker As ICharacter, defender As ICharacter) As Boolean\nEnd Interface\n\n'' ---------------------------------------\n'' IMPLEMENTACIÓN DE INTERFACES\n'' ---------------------------------------\n''' <summary>Constantes globales.</summary>\nPublic Class DefaultConfig\n    Implements IGlobalConfig\n\n    Public ReadOnly Property TurnInterval As Integer Implements IGlobalConfig.TurnInterval\n        Get\n            Return 1\n        End Get\n    End Property\n\n    Public ReadOnly Property MinimumHp As Integer Implements IGlobalConfig.MinimumHp\n        Get\n            Return 200\n        End Get\n    End Property\n\n    ' Fácil de adaptar a un Json de personajes.\n    Public ReadOnly Property Characters As IDictionary(Of String, TCharacterConfig) Implements IGlobalConfig.Characters\n        Get\n            Return New Dictionary(Of String, TCharacterConfig) From {\n                {\"Deadpool\", New TCharacterConfig With {\n                    .Attacks = New List(Of String) From {\"Con arma\", \"Cuerpo a cuerpo\", \"Ataque imprudente\"},\n                    .DamageRange = (10, 100),\n                    .DefenseChance = 0.25\n                }},\n                {\"Wolverine\", New TCharacterConfig With {\n                    .Attacks = New List(Of String) From {\"Con garras de adamantium\", \"Con arma\", \"Cuerpo a cuerpo\"},\n                    .DamageRange = (10, 120),\n                    .DefenseChance = 0.2\n                }}\n            }   'Puedes añadir más personajes\n        End Get\n    End Property\n\n    Public ReadOnly Property Menu As String Implements IGlobalConfig.Menu\n        Get\n            Return vbCrLf & \"SIMULADOR DE BATALLAS:\" & vbCrLf &\n                   \"------------------------------------------\" & vbCrLf &\n                   \"| 1. Simular una batalla |    2. Salir    |\" & vbCrLf &\n                   \"------------------------------------------\"\n        End Get\n    End Property\nEnd Class\n\n' ____________________________________________________\n'''<summary>Solicitud de entrada.</summary>\nPublic Class ConsoleInput\n    Implements IInput\n\n    Public Function GetInt(msg As String) As Integer Implements IInput.GetInt\n        While True\n            Console.Write(msg)\n            Dim input As String = Console.ReadLine()\n\n            If String.IsNullOrWhiteSpace(input) Then\n                Console.WriteLine(\"La entrada no puede estar vacía.\")\n                Continue While\n            End If\n\n            Dim intValue As Integer\n            If Integer.TryParse(input, intValue) Then\n                Return intValue\n            Else\n                Console.WriteLine(\"Por favor, ingresa un número entero válido.\")\n            End If\n        End While\n        Return 0\n    End Function\nEnd Class\n\n' ____________________________________________________\n'''<summary>Datos y metodos de un personaje que participara en la batalla.</summary>\nPublic Class DefaultCharacter\n    Implements ICharacter\n\n    Public Property Name As String = \"\" Implements ICharacter.Name\n    Public Property Hp As Integer = 0 Implements ICharacter.Hp\n    Public Property CanAttack As Boolean = True Implements ICharacter.CanAttack\n    Public Property Attacks As List(Of String) = New List(Of String)() Implements ICharacter.Attacks\n    Public Property DamageRange As (MinDamage As Integer, MaxDamage As Integer) = (0, 0) Implements ICharacter.DamageRange\n    Public Property DefenseChance As Double = 0.0 Implements ICharacter.DefenseChance\n\n    Public Sub Add(name As String, hp As Integer, attributes As TCharacterConfig) Implements ICharacter.Add\n        Me.Name = name\n        Me.Hp = hp\n        Me.Attacks = attributes.Attacks\n        Me.DamageRange = attributes.DamageRange\n        Me.DefenseChance = attributes.DefenseChance\n    End Sub\n\n    Public Function Attack() As Integer Implements ICharacter.Attack\n        If CanAttack Then\n            Dim random As New Random()\n            Dim damage As Integer = random.Next(DamageRange.MinDamage, DamageRange.MaxDamage + 1)\n            Dim selectedAttack As String = Attacks(random.Next(Attacks.Count))\n            Console.WriteLine($\"|'{Name}' ataca '{selectedAttack}' causando un: '-{damage}' 👊|\")\n            Return damage\n        Else\n            Console.WriteLine($\"|'{Name}' se está regenerando y no puede atacar. 😴|\")\n            Return 0\n        End If\n    End Function\n\n    Public Function Defend() As Boolean Implements ICharacter.Defend\n        Dim random As New Random()\n        Dim defended As Boolean = random.NextDouble() < DefenseChance\n        Console.WriteLine(If(defended,\n                            $\"|'{Name}' logró defenderse. 🛡️|\",\n                            $\"|'{Name}' no pudo bloquear el ataque. 🤕|\"))\n        Return defended\n    End Function\nEnd Class\n\n' ____________________________________________________\n'''<summary>Agrega datos de los personajes.</summary>\nPublic Class CharacterSetup\n    Implements ICharacterSetup\n\n    Public Sub Add(Ft As IFeatures, msg As String, player As ICharacter) Implements ICharacterSetup.Add\n        While True\n            Dim index As Integer = Ft.Input.GetInt(msg)\n            Dim keys As List(Of String) = Ft.GlobalConfig.Characters.Keys.ToList()\n            Dim name As String = keys(index)\n            Dim hp As Integer\n            Dim attributes As TCharacterConfig = Ft.GlobalConfig.Characters(name)\n\n            If index < 0 OrElse index >= keys.Count Then\n                Console.WriteLine(\"Número de personaje incorrecto.\")\n                Continue While ' Volver a solicitar\n            End If\n\n            If name = Ft.Player1.Name Then\n                Console.WriteLine(\"El personaje ya fue utilizado.\")\n                Continue While\n            End If\n\n            While True\n                hp = Ft.Input.GetInt($\"Establecer una vida >= que '{Ft.GlobalConfig.MinimumHp}': \")\n                If hp < Ft.GlobalConfig.MinimumHp Then\n                    Console.WriteLine($\"La vida debe ser mayor o igual que '{Ft.GlobalConfig.MinimumHp}'.\")\n                Else\n                    Exit While\n                End If\n            End While\n\n            player.Add(name, hp, attributes)\n            Exit While\n        End While\n    End Sub\nEnd Class\n\n' ____________________________________________________\n'''<summary>Estrategia 'standard'.</summary>\nPublic Class DefaultBattleStrategy\n    Implements IBattleStrategy\n\n    Public Function Execute(attacker As ICharacter, defender As ICharacter) As Boolean Implements IBattleStrategy.Execute\n        Dim damage As Integer = attacker.Attack()\n\n        If damage = attacker.DamageRange.MaxDamage Then\n            Console.WriteLine($\"|'{defender.Name}' 🚨Recibió un ataque crítico y no podrá atacar.🚨|\")\n            defender.CanAttack = False\n        End If\n\n        If attacker.CanAttack Then\n            If Not defender.Defend() Then\n                defender.Hp -= damage\n            End If\n        Else\n            attacker.CanAttack = True\n        End If\n\n        If defender.Hp <= 0 Then\n            Console.WriteLine(vbCrLf & \"____________________________\")\n            Console.WriteLine($\"|'{attacker.Name}' 🏆Gana la batalla. 🏆|\")\n            Return False\n        End If\n\n        Return True\n    End Function\nEnd Class\n\n' _________________\n'' NOTA: Estoy intentando practicar los principios SOLID. XD 😂\n\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/c#/deathwing696.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Security.Policy;\nusing System.Text;\n\nnamespace reto33\n{\n    public class deathwing696\n    {\n        const string kMENSAJE = \"Movimiento no permitido\";\n        public class Posicion\n        {\n            private int x, y;\n\n            public int X { get { return x; } }\n            public int Y { get { return y; } }\n\n            public Posicion(int x, int y)\n            {\n                this.x = x;\n                this.y = y;\n            }\n\n            public void MoverDerecha()\n            {\n                this.y += 1;\n            }\n\n            public void MoverIzquierda()\n            {\n                this.y -= 1;\n            }\n\n            public void MoverArriba()\n            {\n                this.x -= 1;\n            }\n\n            public void MoverAbajo()\n            {\n                this.x += 1;\n            }\n\n        }\n        public class Tablero\n        {\n            private string[,] tablero;\n            private Posicion posicion;\n            private bool llegada = false;\n\n            public bool Llegada { get { return llegada; } }\n\n            public Tablero() \n            {\n                tablero = new string[6, 6];\n\n                for (int i = 0; i  < tablero.GetLength(0); i++)\n                {\n                    for (int j = 0; j < tablero.GetLength(1); j++)\n                    {\n                        tablero[i,j] = \"_\";\n                    }\n                }\n\n                GeneraObstaculos();\n                GeneraSalida();\n                GeneraInicioMickey();\n            }\n\n            private void GeneraInicioMickey()\n            {\n                Random random = new Random();\n                int fila, columna;\n\n                do\n                {\n                    fila = random.Next(0, 5);\n                    columna = random.Next(0, 5);\n                } while (tablero[fila, columna] != \"_\");\n\n                tablero[fila, columna] = \"M\";\n                posicion = new Posicion(fila, columna);\n            }\n\n            private void GeneraSalida()\n            {\n                Random random = new Random();\n                int fila, columna;\n\n                do\n                {\n                    fila = random.Next(0, 5);\n                    columna = random.Next(0, 5);\n                } while (tablero[fila, columna] != \"_\");\n\n                tablero[fila, columna] = \"S\";\n            }\n\n            private void GeneraObstaculos()\n            {\n                Random random = new Random();\n                var numObstaculos = random.Next(6, 12);\n\n                for (int i = 0; i < numObstaculos; i++)\n                {\n                    int fila, columna;\n\n                    do\n                    {\n                        fila = random.Next(0, 5);\n                        columna = random.Next(0, 5);\n                    } while (tablero[fila, columna] != \"_\");\n\n                    tablero[fila, columna] = \"X\";\n                }\n            }\n\n            public void MuestraTablero()\n            {\n                Console.WriteLine(\"Leyenda:\");\n                Console.WriteLine(\"_ -> Hueco\");\n                Console.WriteLine(\"X -> Obstaculo\");\n                Console.WriteLine(\"M -> Mickey\");\n                Console.WriteLine(\"S -> Salida\");\n                Console.WriteLine(\"Tablero:\");\n\n                for (int i = 0; i < tablero.GetLength(0); i++)\n                {\n                    for (int j = 0; j < tablero.GetLength(1); j++)\n                    {\n                        Console.Write(tablero[i,j] + \" \");\n                    }\n\n                    Console.WriteLine();\n                }                \n            }\n\n            public bool MueveDerecha()\n            {\n                if (posicion.Y + 1 < tablero.GetLength(0))\n                {\n                    if (tablero[posicion.X, posicion.Y + 1] != \"X\")\n                    {\n                        if (tablero[posicion.X, posicion.Y + 1] == \"S\")\n                        {\n                            llegada = true;\n                        }\n\n                        tablero[posicion.X, posicion.Y] = \"_\";\n                        tablero[posicion.X, posicion.Y + 1] = \"M\";\n                        posicion.MoverDerecha();\n\n                        return true;\n                    }\n                }\n\n                return false;\n            }\n\n            public bool MueveIzquierda()\n            {\n                if (posicion.Y - 1 >= 0)\n                {\n                    if (tablero[posicion.X, posicion.Y - 1] != \"X\")\n                    {\n                        if (tablero[posicion.X, posicion.Y - 1] == \"S\")\n                        {\n                            llegada = true;\n                        }\n\n                        tablero[posicion.X, posicion.Y] = \"_\";\n                        tablero[posicion.X, posicion.Y - 1] = \"M\";\n                        posicion.MoverIzquierda();\n\n                        return true;\n                    }\n                }\n\n                return false;\n            }\n\n            public bool MueveArriba()\n            {\n                if (posicion.X - 1 >= 0)\n                {\n                    if (tablero[posicion.X - 1, posicion.Y] != \"X\")\n                    {\n                        if (tablero[posicion.X - 1, posicion.Y] == \"S\")\n                        {\n                            llegada = true;\n                        }\n\n                        tablero[posicion.X, posicion.Y] = \"_\";\n                        tablero[posicion.X - 1, posicion.Y] = \"M\";\n                        posicion.MoverArriba();\n\n                        return true;\n                    }\n                }\n\n                return false;\n            }\n\n            public bool MueveAbajo()\n            {\n                if (posicion.X + 1 < tablero.GetLength(1))\n                {\n                    if (tablero[posicion.X + 1, posicion.Y] != \"X\")\n                    {\n                        if (tablero[posicion.X + 1, posicion.Y] == \"S\")\n                        {\n                            llegada = true;\n                        }\n\n                        tablero[posicion.X, posicion.Y] = \"_\";\n                        tablero[posicion.X + 1, posicion.Y] = \"M\";\n                        posicion.MoverAbajo();\n\n                        return true;\n                    }\n                }\n\n                return false;\n            }\n        }\n        static void Main(string[] args)\n        {\n            Tablero tablero = new Tablero();\n\n            while (!tablero.Llegada)\n            {\n                tablero.MuestraTablero();\n                Console.WriteLine(\"¿Hacia dónde quieres moverte?\");\n                Console.WriteLine(\"1. Derecha\");\n                Console.WriteLine(\"2. Izquierda\");\n                Console.WriteLine(\"3. Arriba\");\n                Console.WriteLine(\"4. Abajo\");\n                Console.Write(\"Opcion: \");\n                var opcion = Int16.Parse(Console.ReadLine());\n\n                switch (opcion)\n                {\n                    case 1:\n                        if (!tablero.MueveDerecha())\n                            Console.WriteLine(kMENSAJE);\n                        break;\n                    case 2:\n                        if (!tablero.MueveIzquierda())\n                            Console.WriteLine(kMENSAJE);\n                        break;\n                    case 3:\n                        if (!tablero.MueveArriba())\n                            Console.WriteLine(kMENSAJE);\n                        break;\n                    case 4:\n                        if (!tablero.MueveAbajo())\n                            Console.WriteLine(kMENSAJE);\n                        break;\n                    default:\n                        Console.WriteLine(\"Opción incorrecta\");\n                        break;\n                }\n            }\n            Console.WriteLine(\"¡Enhorabuena! Has ayudado a Mickey a escapar del laberinto\");\n\n            Console.ReadKey();\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/c#/hequebo.cs",
    "content": "class Program\n{\n    static string[,] maze =\n    {\n        {\"🐭\", \"⬛️\", \"⬛️\", \"⬛️\", \"⬛️\", \"⬛️\"},\n        {\"⬜️\", \"⬛️\", \"⬛️\", \"⬛️\", \"⬜️\", \"⬛️\"},\n        {\"⬜️\", \"⬛️\", \"⬛️\", \"⬛️\", \"⬜️\", \"⬛️\"},\n        {\"⬜️\", \"⬜️\", \"⬜️\", \"⬜️\", \"⬜️\", \"⬜️\"},\n        {\"⬛️\", \"⬜️\", \"⬛️\", \"⬜️\", \"⬛️\", \"⬛️\"},\n        {\"⬛️\", \"⬜️\", \"⬛️\", \"⬜️\", \"⬜️\", \"🚪\"}\n    };\n    static void Main(string[] args)\n    {\n        Console.WriteLine(\"---El laberinto de Mickey Mouse----\");\n        Random random = new Random();\n        ShowMaze(maze);\n        Console.WriteLine(\"¡Ayuda a Mickey a encontrar la salida!\");\n        Console.WriteLine(\"Utiliza las teclas W,A,S y D para moverte.\");\n        bool cleared = false;\n        Mickey mickey = new Mickey();\n        do\n        {\n            string? direction = Console.ReadLine();\n            mickey.Move(direction, ref maze, ref cleared);\n            ShowMaze(maze);\n\n        } while (!cleared);\n\n    }\n\n    static void ShowMaze(string[,] maze) \n    {\n        for (int i = 0; i < 6; i++)\n        {\n            for (int j = 0; j < 6; j++)\n                Console.Write(maze[i, j]);\n            Console.WriteLine();\n        }\n    }\n}\nclass Mickey\n{\n    private int[] _position;\n\n    public Mickey()\n    {\n        _position = new int[] {0, 0};\n    }\n\n    public void Move(string? direction, ref string[,] maze, ref bool cleared)\n    {\n        string current = \"\";\n        switch (direction?.ToLower())\n        {\n            case \"w\":\n                if (_position[0] == 0)\n                {\n                    Console.WriteLine(\"No es posible moverse hacia arriba...\");\n                    break;\n                }\n                if (maze[_position[0] - 1, _position[1]] == \"⬛️\")\n                {\n                    Console.WriteLine(\"Un obstaculo impide moverse hacia arriba\");\n                    break;\n                }\n                _position[0] -= 1;\n\n                Console.WriteLine(\"Se mueve hacia arriba\");\n                current = maze[_position[0], _position[1]];\n                maze[_position[0], _position[1]] = \"🐭\";\n                maze[_position[0] + 1, _position[1]] = \"⬜️\";\n                break;\n            case \"a\":\n                if (_position[1] == 0)\n                {\n                    Console.WriteLine(\"No es posible moverse hacia la izquierda...\");\n                    break;\n                }\n                if (maze[_position[0], _position[1] - 1] == \"⬛️\")\n                {\n                    Console.WriteLine(\"Un obstaculo impide moverse hacia la izquierda\");\n                    break;\n                }\n                _position[1] -= 1;\n\n                Console.WriteLine(\"Se mueve hacia la izquierda\");\n                current = maze[_position[0], _position[1]];\n                maze[_position[0], _position[1]] = \"🐭\";\n                maze[_position[0], _position[1] + 1] = \"⬜️\";\n                break;\n            case \"s\":\n                if (_position[0] == 5)\n                {\n                    Console.WriteLine(\"No es posible moverse hacia abajo...\");\n                    break;\n                }\n                if (maze[_position[0] + 1, _position[1]] == \"⬛️\")\n                {\n                    Console.WriteLine(\"Un obstaculo impide moverse hacia abajo\");\n                    break;\n                }\n                _position[0] += 1;\n\n                Console.WriteLine(\"Se mueve hacia abajo\");\n                current = maze[_position[0], _position[1]];\n                maze[_position[0], _position[1]] = \"🐭\";\n                maze[_position[0] - 1, _position[1]] = \"⬜️\";\n                break;\n            case \"d\":\n                if (_position[1] == 5)\n                {\n                    Console.WriteLine(\"No es posible moverse hacia la derecha...\");\n                    break;\n                }\n                if (maze[_position[0], _position[1] + 1] == \"⬛️\")\n                {\n                    Console.WriteLine(\"Un obstaculo impide moverse hacia la derecha\");\n                    break;\n                }\n                _position[1] += 1;\n\n                Console.WriteLine(\"Se mueve hacia la derecha\");\n                current = maze[_position[0], _position[1]];\n                maze[_position[0], _position[1]] = \"🐭\";\n                maze[_position[0], _position[1] - 1] = \"⬜️\";\n                break;\n            default:\n                Console.WriteLine(\"Dirección no válida...\");\n                break;\n        }\n        if (current == \"🚪\")\n        {\n            Console.WriteLine(\"¡Mickey ha salido del laberinto!\");\n            cleared = true;\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/c#/kenysdev.cs",
    "content": "namespace exs33;\n/*\n╔══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado               ║\n║ GitHub: https://github.com/Kenysdev  ║\n║ 2024 -  C#                           ║\n╚══════════════════════════════════════╝\n-----------------------------------------------------\n* RESCATANDO A MICKEY\n-----------------------------------------------------\n * EJERCICIO:\n * ¡Disney ha presentado un montón de novedades en su D23! \n * Pero... ¿Dónde está Mickey?\n * Mickey Mouse ha quedado atrapado en un laberinto mágico \n * creado por Maléfica.\n * Desarrolla un programa para ayudarlo a escapar.\n * Requisitos:\n * 1. El laberinto está formado por un cuadrado de 6x6 celdas.\n * 2. Los valores de las celdas serán:\n *    - ⬜️ Vacío\n *    - ⬛️ Obstáculo\n *    - 🐭 Mickey\n *    - 🚪 Salida\n * Acciones:\n * 1. Crea una matriz que represente el laberinto (no hace falta\n * que se genere de manera automática).\n * 2. Interactúa con el usuario por consola para preguntarle hacia\n * donde se tiene que desplazar (arriba, abajo, izquierda o derecha).\n * 3. Muestra la actualización del laberinto tras cada desplazamiento.\n * 4. Valida todos los movimientos, teniendo en cuenta los límites\n * del laberinto y los obtáculos. Notifica al usuario.\n * 5. Finaliza el programa cuando Mickey llegue a la salida.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection;\n\nclass Program\n{\n    static void Main()\n    {\n        // These are the default values. You can change them here.\n        var config = new Dictionary<string, string>\n        {\n            { \"title\", \"RESCUING MICKEY\" },\n            { \"size\", \"7, 7\" },\n            { \"empty\", \"⬜️\" },\n            { \"obstacle\", \"⬛️\" },\n            { \"mouse\", \"🐭\" },\n            { \"exit\", \"🚪\" }\n        };\n\n        var maze = new Maze(config);\n        var game = new Game(config, maze);\n        game.Play();\n    }\n}\n\nclass Game(Dictionary<string, string> config, Maze maze)\n{\n    private readonly Dictionary<string, string> _config = config;\n    private readonly Maze _maze = maze;\n\n    private static bool RestartOrExit()\n    {\n        while (true)\n        {\n            Console.Write(\"Y/N: \");\n            var option = Console.ReadLine()!.ToLower();\n            switch (option)\n            {\n                case \"y\": return true;\n                case \"n\": return false;\n                default: Console.WriteLine(\"❌Invalid key.❌\");\n                    break;\n            }\n        }\n    }\n\n    public void Play()\n    {\n        foreach (var (key, value) in _config)\n        {\n            Console.WriteLine($\"{key}: {value}\");\n        }\n\n        _maze.Create();\n        while (true)\n        {\n            _maze.PrintMaze();\n            Console.WriteLine(\"Use the keys: (W, S, A, D).\\nTo restart: R. To exit: 9.\");\n            Console.Write(\"Key: \");\n            var option = Console.ReadLine()!.ToLower();\n            switch (option)\n            {\n                case \"w\": _maze.Up(); break;\n                case \"s\": _maze.Down(); break;\n                case \"d\": _maze.Right(); break;\n                case \"a\": _maze.Left(); break;\n                case \"r\":\n                    Console.WriteLine(\"😮Do you want to restart?😮\");\n                    if (RestartOrExit())\n                    {\n                        _maze.Create();\n                    }\n                    break;\n                case \"9\":\n                    Console.WriteLine(\"😮Do you want to exit?😮\");\n                    if (RestartOrExit())\n                    {\n                        return;\n                    }\n                    break;\n                default:\n                    Console.WriteLine(\"❌Invalid key.❌\");\n                    break;\n            }\n\n            if (_maze.VerifyWin())\n            {\n                Console.WriteLine(\"🏆Congratulations, you managed to get me out.🏆\");\n                Console.WriteLine(\"🤔Do you want to play again?🤔\");\n                if (RestartOrExit())\n                {\n                    _maze.Create();\n                }\n                else\n                {\n                    Console.WriteLine(\"Bye\");\n                    return;\n                }\n            }\n        }\n    }\n}\n\nclass Data\n{\n    protected Dictionary<string, string> _config;\n    protected List<List<string>> _maze;\n    protected Tuple<int, int> _positionMouse;\n    protected Tuple<int, int> _exitLocation;\n    protected int _width;\n    protected int _height;\n    protected string _obstacleChar;\n    protected string _emptyChar;\n    protected string _mouseChar;\n    protected string _exitChar;\n\n    public Data(Dictionary<string, string> config)\n    {\n        _config = config;\n        _maze = [];\n        _positionMouse = new Tuple<int, int>(0, 0);\n        _exitLocation = new Tuple<int, int>(0, 0);\n\n        var size = config[\"size\"].Split(',');\n        _width = int.Parse(size[0]);\n        _height = int.Parse(size[1]);\n        _obstacleChar = _config[\"obstacle\"];\n        _emptyChar = _config[\"empty\"];\n        _mouseChar = _config[\"mouse\"];\n        _exitChar = _config[\"exit\"];\n    }\n\n    public void PrintMaze()\n    {\n        Console.WriteLine(\"--------------------------------------\");\n        foreach (var row in _maze)\n        {\n            Console.WriteLine(string.Join(\"\", row));\n        }\n        Console.WriteLine(\"--------------------------------------\");\n    }\n}\n\nclass Moves(Dictionary<string, string> config) : Data(config)\n{\n    private void CanMove(int y, int x, int oldY, int oldX)\n    {\n        int rows = _maze.Count;\n        int cols = _maze[0].Count;\n        if (y < 0 || x < 0 || y >= rows || x >= cols)\n        {\n            Console.WriteLine(\"🚨I can't jump over the edges.🚨\");\n            return;\n        }\n\n        if (_maze[y][x] == _obstacleChar)\n        {\n            Console.WriteLine(\"🚨You pushed me against the wall.🚨\");\n            return;\n        }\n\n        _positionMouse = new Tuple<int, int>(y, x);\n        Console.WriteLine(\"✅Correct move.✅\");\n        _maze[oldY][oldX] = _emptyChar;\n        _maze[y][x] = _mouseChar;\n    }\n\n    public void Up()\n    {\n        var (y, x) = _positionMouse;\n        CanMove(y - 1, x, oldY: y, oldX: x);\n    }\n\n    public void Down()\n    {\n        var (y, x) = _positionMouse;\n        CanMove(y + 1, x, oldY: y, oldX: x);\n    }\n\n    public void Right()\n    {\n        var (y, x) = _positionMouse;\n        CanMove(y, x + 1, oldY: y, oldX: x);\n    }\n\n    public void Left()\n    {\n        var (y, x) = _positionMouse;\n        CanMove(y, x - 1, oldY: y, oldX: x);\n    }\n}\n\nclass Maze(Dictionary<string, string> config) : Moves(config)\n{\n    private void CreatePaths(int x, int y)\n    {\n        _maze[y][x] = _emptyChar;\n        var directions = new List<(int, int)> { (0, 1), (1, 0), (0, -1), (-1, 0) };\n        foreach (var (dx, dy) in directions.OrderBy(x => Guid.NewGuid()))\n        {\n            int nx = x + dx * 2, ny = y + dy * 2;\n            if (0 < nx && nx < _width - 1 && 0 < ny && ny < _height - 1 && _maze[ny][nx] == _obstacleChar)\n            {\n                _maze[y + dy][x + dx] = _emptyChar;\n                CreatePaths(nx, ny);\n            }\n        }\n    }\n\n    public void Create()\n    {\n        if (_width % 2 == 0) _width++;\n        if (_height % 2 == 0) _height++;\n\n        _maze = [];\n        for (int i = 0; i < _height; i++)\n        {\n            _maze.Add(Enumerable.Repeat(_obstacleChar, _width).ToList());\n        }\n\n        int initialX = new Random().Next(1, _width - 1) | 1;\n        int initialY = new Random().Next(1, _height - 1) | 1;\n        CreatePaths(initialX, initialY);\n\n        _maze[0][1] = _mouseChar;\n        _maze[_height - 1][_width - 2] = _exitChar;\n        _positionMouse = new Tuple<int, int>(0, 1);\n        _exitLocation = new Tuple<int, int>(_height - 1, _width - 2);\n    }\n\n    public bool VerifyWin()\n    {\n        var (y, x) = _exitLocation;\n        return _maze[y][x] == _mouseChar;\n    }\n}\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/c++/hectorio23.cpp",
    "content": "// Autor: Héctor Adán\n// Github: https://github.com/hectorio23\n\n#include <cstdlib>\n#include <iostream>\n#include <vector>\n#include <string>\n\n// Imprime el laberinto en su estado actual\nvoid printLabyrinth(const std::vector<std::vector<std::string>>& labyrinth) {\n    for (const auto& row : labyrinth) {\n        for (const auto& cell : row) {\n            std::cout << cell << \" \";\n        }\n        std::cout << std::endl;\n    }\n}\n\n// Intenta mover a Mickey a una nueva posición y valida el movimiento\nbool moveMickey(std::vector<std::vector<std::string>>& labyrinth, int& mickeyX, int& mickeyY, int newX, int newY) {\n    // Validación de límites del laberinto\n    if (newX < 0 || newX >= 6 || newY < 0 || newY >= 6) {\n        std::cout << \"Movimiento inválido, fuera de los límites del laberinto.\" << std::endl;\n        return false;\n    }\n    // Validación de obstáculos\n    if (labyrinth[newX][newY] == \"⬛️\") {\n        std::cout << \"Movimiento inválido, obstáculo en el camino.\" << std::endl;\n        return false;\n    }\n    // Actualización de la posición de Mickey\n    labyrinth[mickeyX][mickeyY] = \"⬜️\"; // Limpia la posición anterior\n    mickeyX = newX;\n    mickeyY = newY;\n\n    // Verificación si Mickey ha llegado a la salida\n    if (labyrinth[mickeyX][mickeyY] == \"🚪\") {\n        std::cout << \"¡Mickey ha escapado!\" << std::endl;\n        return true;\n    }\n\n    labyrinth[mickeyX][mickeyY] = \"🐭\"; // Actualiza la posición de Mickey\n    return false;\n}\n\nint main() {\n    // Definición inicial del laberinto\n    std::vector<std::vector<std::string>> labyrinth = {\n        {\"⬜️\", \"⬜️\", \"⬜️\", \"⬛️\", \"⬛️\", \"⬛️\"},\n        {\"⬛️\", \"⬛️\", \"⬜️\", \"⬛️\", \"🚪\", \"⬛️\"},\n        {\"⬛️\", \"⬛️\", \"⬜️\", \"⬛️\", \"⬜️\", \"⬛️\"},\n        {\"⬛️\", \"⬛️\", \"⬜️\", \"⬜️\", \"⬜️\", \"⬛️\"},\n        {\"⬛️\", \"⬛️\", \"⬜️\", \"⬛️\", \"⬛️\", \"⬛️\"},\n        {\"🐭\", \"⬜️\", \"⬜️\", \"⬛️\", \"⬛️\", \"⬛️\"}\n    };\n\n    // Posición inicial de Mickey\n    int mickeyX = 5, mickeyY = 0;\n    std::string direction;\n    bool escaped = false;\n\n    // Ciclo principal de interacción con el usuario\n    while (!escaped) {\n        std::system(\"clear\");\n        printLabyrinth(labyrinth); // Muestra el estado actual del laberinto\n        std::cout << \"Introduce dirección (arriba, abajo, izquierda, derecha): \";\n        std::cin >> direction;\n\n        // Procesa la dirección ingresada y mueve a Mickey si es válido\n        if (direction == \"arriba\") escaped = moveMickey(labyrinth, mickeyX, mickeyY, mickeyX - 1, mickeyY);\n        else if (direction == \"abajo\") escaped = moveMickey(labyrinth, mickeyX, mickeyY, mickeyX + 1, mickeyY);\n        else if (direction == \"izquierda\") escaped = moveMickey(labyrinth, mickeyX, mickeyY, mickeyX, mickeyY - 1);\n        else if (direction == \"derecha\") escaped = moveMickey(labyrinth, mickeyX, mickeyY, mickeyX, mickeyY + 1);\n        else std::cout << \"Dirección inválida. Intenta nuevamente.\" << std::endl;\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/ejercicio.md",
    "content": "# #33 RESCATANDO A MICKEY\n> #### Dificultad: Fácil | Publicación: 12/08/24 | Corrección: 19/08/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * ¡Disney ha presentado un montón de novedades en su D23! \n * Pero... ¿Dónde está Mickey?\n * Mickey Mouse ha quedado atrapado en un laberinto mágico \n * creado por Maléfica.\n * Desarrolla un programa para ayudarlo a escapar.\n * Requisitos:\n * 1. El laberinto está formado por un cuadrado de 6x6 celdas.\n * 2. Los valores de las celdas serán:\n *    - ⬜️ Vacío\n *    - ⬛️ Obstáculo\n *    - 🐭 Mickey\n *    - 🚪 Salida\n * Acciones:\n * 1. Crea una matriz que represente el laberinto (no hace falta\n * que se genere de manera automática).\n * 2. Interactúa con el usuario por consola para preguntarle hacia\n * donde se tiene que desplazar (arriba, abajo, izquierda o derecha).\n * 3. Muestra la actualización del laberinto tras cada desplazamiento.\n * 4. Valida todos los movimientos, teniendo en cuenta los límites\n * del laberinto y los obstáculos. Notifica al usuario.\n * 5. Finaliza el programa cuando Mickey llegue a la salida.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/go/hozlucas28.go",
    "content": "package main\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"strings\"\n)\n\n/* -------------------------------------------------------------------------- */\n/*                                    TYPES                                   */\n/* -------------------------------------------------------------------------- */\n\n/* ---------------------------------- Cell ---------------------------------- */\n\ntype TCell string\n\nconst (\n\tobstacle TCell = \"⬛️\"\n\tfree     TCell = \"⬜️\"\n\tplayer   TCell = \"🐭\"\n\texit     TCell = \"🚪\"\n)\n\ntype cells struct {\n\tObstacle TCell\n\tFree     TCell\n\tPlayer   TCell\n\tExit     TCell\n}\n\nvar Cell cells = cells{\n\tObstacle: obstacle,\n\tFree:     free,\n\tPlayer:   player,\n\tExit:     exit,\n}\n\n/* -------------------------------- Dashboard ------------------------------- */\n\ntype Dashboard [6][6]TCell\n\n/* -------------------------------- Position -------------------------------- */\n\ntype Position struct {\n\tx int\n\ty int\n\t_ struct{}\n}\n\n/* ---------------------------------- Move ---------------------------------- */\n\ntype TMove string\n\nconst (\n\tdown  TMove = \"down\"\n\tleft  TMove = \"left\"\n\tright TMove = \"right\"\n\tup    TMove = \"up\"\n)\n\ntype moves struct {\n\tDown  TMove\n\tLeft  TMove\n\tRight TMove\n\tUp    TMove\n}\n\nvar Move moves = moves{\n\tDown:  down,\n\tLeft:  left,\n\tRight: right,\n\tUp:    up,\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                   ERRORS                                   */\n/* -------------------------------------------------------------------------- */\n\n/* ---------------------------- ExitNotFoundError --------------------------- */\n\ntype ExitNotFoundError struct{}\n\nfunc (err *ExitNotFoundError) Error() string {\n\treturn \"Exit not found\"\n}\n\n/* -------------------------------- GameOver -------------------------------- */\n\ntype GameOverError struct{}\n\nfunc (err *GameOverError) Error() string {\n\treturn \"Game over\"\n}\n\n/* ----------------------- InvalidPlayerPositionError ----------------------- */\n\ntype InvalidPlayerPositionError struct {\n\tposition *Position\n\t_        struct{}\n}\n\nfunc (err *InvalidPlayerPositionError) Error() string {\n\treturn fmt.Sprintf(\"Position (%d, %d) is invalid for a player\", err.position.x+1, err.position.y+1)\n}\n\n/* --------------------------- PlayerNotFoundError -------------------------- */\n\ntype PlayerNotFoundError struct{}\n\nfunc (err *PlayerNotFoundError) Error() string {\n\treturn \"Player not found\"\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                   CLASSES                                  */\n/* -------------------------------------------------------------------------- */\n\ntype initialPositions struct {\n\texit   Position\n\tplayer Position\n\t_      struct{}\n}\n\n/* ---------------------------------- Maze ---------------------------------- */\n\ntype Maze interface {\n\tGetDashboard() *Dashboard\n\tGetExitPos() *Position\n\tGetPlayerPos() *Position\n\tSetPlayerPos(newPos *Position) error\n}\n\ntype maze struct {\n\tdashboard               *Dashboard\n\texitPos                 *Position\n\tplayerPos               *Position\n\toriginalCellAtPlayerPos TCell\n\t_                       struct{}\n}\n\nfunc NewMaze(dashboard *Dashboard) (Maze, error) {\n\tvar maze maze\n\n\tvar initialPositions initialPositions = initialPositions{\n\t\texit:   Position{x: -1, y: -1},\n\t\tplayer: Position{x: -1, y: -1},\n\t}\n\n\tfor y, row := range dashboard {\n\t\tfor x, col := range row {\n\t\t\tif col == Cell.Exit {\n\t\t\t\tinitialPositions.exit.x = x\n\t\t\t\tinitialPositions.exit.y = y\n\t\t\t} else if col == Cell.Player {\n\t\t\t\tinitialPositions.player.x = x\n\t\t\t\tinitialPositions.player.y = y\n\t\t\t}\n\t\t}\n\t}\n\n\tif initialPositions.exit.x < 0 {\n\t\treturn &maze, &ExitNotFoundError{}\n\t}\n\n\tif initialPositions.player.x < 0 {\n\t\treturn &maze, &PlayerNotFoundError{}\n\t}\n\n\tmaze.dashboard = dashboard\n\tmaze.originalCellAtPlayerPos = Cell.Free\n\tmaze.exitPos = &initialPositions.exit\n\tmaze.playerPos = &initialPositions.player\n\n\treturn &maze, nil\n}\n\nfunc (maze *maze) GetDashboard() *Dashboard {\n\treturn maze.dashboard\n}\n\nfunc (maze *maze) GetExitPos() *Position {\n\treturn maze.exitPos\n}\n\nfunc (maze *maze) GetPlayerPos() *Position {\n\treturn maze.playerPos\n}\n\nfunc (maze *maze) SetPlayerPos(pos *Position) error {\n\tif !maze.isValidPlayerPos(pos) {\n\t\treturn &InvalidPlayerPositionError{position: pos}\n\t}\n\n\tx, y := pos.x, pos.y\n\n\tvar prevPlayerPos *Position = maze.playerPos\n\tvar prevOriginalCellAtPlayerPos TCell = maze.originalCellAtPlayerPos\n\n\tmaze.originalCellAtPlayerPos = maze.dashboard[y][x]\n\tmaze.dashboard[y][x] = Cell.Player\n\tmaze.dashboard[prevPlayerPos.y][prevPlayerPos.x] = prevOriginalCellAtPlayerPos\n\tmaze.playerPos = pos\n\n\treturn nil\n}\n\nfunc (maze *maze) isValidPos(pos *Position) bool {\n\tx, y := pos.x, pos.y\n\n\tvar dashboard *Dashboard = maze.dashboard\n\n\tvar dashboardMaxY int = len(dashboard) - 1\n\tvar outOfYRange bool = y < 0 || y > dashboardMaxY\n\tif outOfYRange {\n\t\treturn false\n\t}\n\n\tvar dashboardMaxX int = len(dashboard[0]) - 1\n\tvar outOfXRange bool = x < 0 || x > dashboardMaxX\n\tif outOfXRange {\n\t\treturn false\n\t}\n\n\treturn true\n}\n\nfunc (maze *maze) isValidPlayerPos(pos *Position) bool {\n\tif !maze.isValidPos(pos) {\n\t\treturn false\n\t}\n\n\tvar cellAtPos TCell = maze.dashboard[pos.y][pos.x]\n\n\tvar obstacleAtPos bool = cellAtPos == Cell.Obstacle\n\treturn !obstacleAtPos\n}\n\n/* ---------------------------------- Game ---------------------------------- */\n\ntype Game interface {\n\tGetMaze() *Maze\n\tMovePlayer(move TMove) error\n\tIsGameOver() bool\n}\n\ntype game struct {\n\tmaze *Maze\n\t_    struct{}\n}\n\nfunc NewGame(maze *Maze) Game {\n\tvar game game = game{maze: maze}\n\treturn &game\n}\n\nfunc (game *game) GetMaze() *Maze {\n\treturn game.maze\n}\n\nfunc (game *game) MovePlayer(move TMove) error {\n\tif game.IsGameOver() {\n\t\treturn &GameOverError{}\n\t}\n\n\tvar maze *Maze = game.maze\n\tvar playerPos *Position = (*maze).GetPlayerPos()\n\n\tx, y := playerPos.x, playerPos.y\n\n\tvar err error\n\n\tswitch move {\n\tcase Move.Down:\n\t\terr = (*maze).SetPlayerPos(&Position{\n\t\t\tx: x,\n\t\t\ty: y + 1,\n\t\t})\n\n\tcase Move.Left:\n\t\terr = (*maze).SetPlayerPos(&Position{\n\t\t\tx: x - 1,\n\t\t\ty: y,\n\t\t})\n\n\tcase Move.Right:\n\t\terr = (*maze).SetPlayerPos(&Position{\n\t\t\tx: x + 1,\n\t\t\ty: y,\n\t\t})\n\n\tcase Move.Up:\n\t\terr = (*maze).SetPlayerPos(&Position{\n\t\t\tx: x,\n\t\t\ty: y - 1,\n\t\t})\n\t}\n\n\treturn err\n}\n\nfunc (game *game) IsGameOver() bool {\n\tvar maze *Maze = game.maze\n\tvar exitPos *Position = (*maze).GetExitPos()\n\tvar playerPos *Position = (*maze).GetPlayerPos()\n\n\tvar playerAtExitPos bool = playerPos.x == exitPos.x && playerPos.y == exitPos.y\n\n\treturn playerAtExitPos\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    UTILS                                   */\n/* -------------------------------------------------------------------------- */\n\nfunc printDashboard(dashboard *Dashboard) {\n\tfmt.Println(\"[\")\n\n\tfor _, row := range dashboard {\n\t\tfmt.Printf(\" %v\\n\", row)\n\t}\n\n\tfmt.Println(\"]\")\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\nfunc main() {\n\tvar dashboard Dashboard = Dashboard{\n\t\t[6]TCell{Cell.Exit, Cell.Obstacle, Cell.Obstacle, Cell.Obstacle, Cell.Obstacle, Cell.Obstacle},\n\t\t[6]TCell{Cell.Free, Cell.Obstacle, Cell.Free, Cell.Free, Cell.Free, Cell.Obstacle},\n\t\t[6]TCell{Cell.Free, Cell.Obstacle, Cell.Free, Cell.Obstacle, Cell.Free, Cell.Free},\n\t\t[6]TCell{Cell.Free, Cell.Free, Cell.Free, Cell.Obstacle, Cell.Free, Cell.Player},\n\t\t[6]TCell{Cell.Obstacle, Cell.Obstacle, Cell.Free, Cell.Obstacle, Cell.Free, Cell.Obstacle},\n\t\t[6]TCell{Cell.Obstacle, Cell.Obstacle, Cell.Free, Cell.Free, Cell.Free, Cell.Obstacle},\n\t}\n\n\tmaze, err := NewMaze(&dashboard)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\n\tvar game Game = NewGame(&maze)\n\tprintDashboard((*game.GetMaze()).GetDashboard())\n\n\tfor !game.IsGameOver() {\n\t\tvar move string\n\t\tfmt.Print(\"\\n> Enter a move ('up', 'right', 'left', or 'down'): \")\n\t\tfmt.Scanf(\"%s\\n\", &move)\n\n\t\tfmt.Println()\n\n\t\tswitch strings.TrimSpace(move) {\n\t\tcase string(Move.Down):\n\t\t\terr = game.MovePlayer(Move.Down)\n\n\t\tcase string(Move.Left):\n\t\t\terr = game.MovePlayer(Move.Left)\n\n\t\tcase string(Move.Right):\n\t\t\terr = game.MovePlayer(Move.Right)\n\n\t\tcase string(Move.Up):\n\t\t\terr = game.MovePlayer(Move.Up)\n\n\t\tdefault:\n\t\t\tfmt.Printf(\"> Invalid move! Try again...\\n\\n\")\n\t\t}\n\n\t\tif err == nil {\n\t\t\tprintDashboard((*game.GetMaze()).GetDashboard())\n\t\t} else {\n\t\t\tvar invalidPlayerPositionError *InvalidPlayerPositionError\n\n\t\t\tif errors.As(err, &invalidPlayerPositionError) {\n\t\t\t\tfmt.Printf(\"> %s.\\n\", err.Error())\n\t\t\t\terr = nil\n\t\t\t} else {\n\t\t\t\tpanic(err)\n\t\t\t}\n\t\t}\n\t}\n\n\tfmt.Print(\"\\n> Game over!\")\n}\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/java/AmadorQuispe.java",
    "content": "package com.amsoft.roadmap.example33;\n\npublic class Example33 {\n    private static final String EMPTY = \"⬜\";\n    private static final String BARRIER = \"⬛\";\n    private static final String EXIT = \"🚪\";\n    private static final String PLAYER = \"🐭\";\n    private static final int ROWS = 6;\n    private static final int COLUMNS = 6;\n    private static String[][] map = new String[ROWS][COLUMNS];\n\n\n    public static void main(String[] args) {\n        initializeMap();\n        int[] playerPosition = {0, 0};\n        movePlayer(playerPosition, playerPosition);\n        while (true) {\n            var scanner = new java.util.Scanner(System.in);\n            System.out.println(\"Enter the direction: \");\n            System.out.println(\"[w]: up, [s]: down, [a]: left, [d]: right or [q]: quit\");\n            System.out.print(\"Press a key: \");\n            String direction = scanner.nextLine();\n            int[] newPosition;\n            switch (direction) {\n                case \"w\":\n                    newPosition = new int[]{playerPosition[0] - 1, playerPosition[1]};\n                    if (movePlayer(playerPosition, newPosition)) {\n                        playerPosition = newPosition;\n                    }\n                    break;\n                case \"s\":\n                    newPosition = new int[]{playerPosition[0] + 1, playerPosition[1]};\n                    if (movePlayer(playerPosition, newPosition)) {\n                        playerPosition = newPosition;\n                    }\n                    break;\n                case \"a\":\n                    newPosition = new int[]{playerPosition[0], playerPosition[1] - 1};\n                    if (movePlayer(playerPosition, newPosition)) {\n                        playerPosition = newPosition;\n                    }\n                    break;\n                case \"d\":\n                    newPosition = new int[]{playerPosition[0], playerPosition[1] + 1};\n                    if (movePlayer(playerPosition, newPosition)) {\n                        playerPosition = newPosition;\n                    }\n                    break;\n                case \"q\":\n                    System.out.println(\"Bye!\");\n                    System.exit(0);\n                default:\n                    System.out.println(\"Invalid direction\");\n                    break;\n            }\n        }\n    }\n\n    private static boolean movePlayer(int[] currentPosition, int[] newPosition) {\n        if (newPosition[0] < 0 || newPosition[0] >= ROWS || newPosition[1] < 0 || newPosition[1] >= COLUMNS) {\n            throw new IllegalArgumentException(\"Invalid player position\");\n        }\n\n        if (map[newPosition[0]][newPosition[1]].equals(EXIT)) {\n            System.out.println(\"You won!\");\n            System.exit(0);\n        }\n\n        if (map[newPosition[0]][newPosition[1]].equals(BARRIER)) {\n            System.out.println(\"You can't move there\");\n            return false;\n        }\n\n        map[currentPosition[0]][currentPosition[1]] = EMPTY;\n        map[newPosition[0]][newPosition[1]] = PLAYER;\n\n\n        for (int i = 0; i < ROWS; i++) {\n            var row = map[i];\n            for (int j = 0; j < COLUMNS; j++) {\n                System.out.print(row[j] + \" \");\n            }\n            System.out.println();\n        }\n        return true;\n    }\n\n    public static void initializeMap() {\n        map = new String[][]{\n                {PLAYER, BARRIER, EMPTY, EMPTY, BARRIER, BARRIER},\n                {EMPTY, EMPTY, EMPTY, BARRIER, EMPTY, BARRIER},\n                {BARRIER, EMPTY, EMPTY, BARRIER, EMPTY, BARRIER},\n                {BARRIER, BARRIER, EMPTY, BARRIER, EMPTY, BARRIER},\n                {BARRIER, EMPTY, EMPTY, EMPTY, EMPTY, BARRIER},\n                {BARRIER, BARRIER, BARRIER, BARRIER, EXIT, BARRIER}\n        };\n    }\n}\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/java/ArmentaAngel.java",
    "content": "import java.util.Scanner;\n\npublic class ArmentaAngel {\n\n    public static void main(String[] args) {\n        Juego juego = new Juego();\n        juego.jugar();\n    }\n}\n\nenum TipoCelda {\n    VACIO(\"Vacio\", \" \"),\n    OBSTACULO(\"Obstaculo\", \"#\"),\n    MICKEY(\"Mickey\", \"M\"),\n    SALIDA(\"Salida\", \"S\");\n\n    final String tipo;\n    final String simbolo;\n\n    TipoCelda(String contenido, String simbolo) {\n        this.tipo = contenido;\n        this.simbolo = simbolo;\n    }\n}\n\nclass Celda {\n    TipoCelda tipo;\n    boolean oculta;\n\n    public Celda(TipoCelda tipo, boolean oculta) {\n        this.tipo = tipo;\n        this.oculta = oculta;\n    }\n}\n\nclass Posicion {\n    int x;\n    int y;\n\n    public Posicion(int x, int y) {\n        this.x = x;\n        this.y = y;\n    }\n}\n\nclass Juego {\n    private static final Celda[][] laberinto = new Celda[6][6];\n    private int numMovimientos = 0;\n    private final Posicion posMickey = new Posicion(0, 0);\n    private boolean salidaEncontrada = false;\n\n    public Juego() {\n        creaLaberinto();\n    }\n\n    private void creaLaberinto() {\n        // 0 [#M #S#]\n        laberinto[0][0] = new Celda(TipoCelda.OBSTACULO, true);\n        laberinto[0][1] = new Celda(TipoCelda.MICKEY, false);\n        posMickey.x = 0;\n        posMickey.y = 1;\n        laberinto[0][2] = new Celda(TipoCelda.VACIO, false);\n        laberinto[0][3] = new Celda(TipoCelda.OBSTACULO, true);\n        laberinto[0][4] = new Celda(TipoCelda.SALIDA, false);\n        laberinto[0][5] = new Celda(TipoCelda.OBSTACULO, true);\n\n        // 1 [  #   ]\n        laberinto[1][0] = new Celda(TipoCelda.VACIO, false);\n        laberinto[1][1] = new Celda(TipoCelda.VACIO, false);\n        laberinto[1][2] = new Celda(TipoCelda.OBSTACULO, true);\n        laberinto[1][3] = new Celda(TipoCelda.VACIO, false);\n        laberinto[1][4] = new Celda(TipoCelda.VACIO, false);\n        laberinto[1][5] = new Celda(TipoCelda.VACIO, false);\n\n        // 2 [# ##  ]\n        laberinto[2][0] = new Celda(TipoCelda.OBSTACULO, true);\n        laberinto[2][1] = new Celda(TipoCelda.VACIO, false);\n        laberinto[2][2] = new Celda(TipoCelda.VACIO, false);\n        laberinto[2][3] = new Celda(TipoCelda.OBSTACULO, true);\n        laberinto[2][4] = new Celda(TipoCelda.OBSTACULO, true);\n        laberinto[2][5] = new Celda(TipoCelda.VACIO, false);\n\n        // 3 [#  #  ]\n        laberinto[3][0] = new Celda(TipoCelda.OBSTACULO, true);\n        laberinto[3][1] = new Celda(TipoCelda.VACIO, false);\n        laberinto[3][2] = new Celda(TipoCelda.VACIO, false);\n        laberinto[3][3] = new Celda(TipoCelda.OBSTACULO, true);\n        laberinto[3][4] = new Celda(TipoCelda.VACIO, false);\n        laberinto[3][5] = new Celda(TipoCelda.VACIO, false);\n\n        // 4 [ #   #]\n        laberinto[4][0] = new Celda(TipoCelda.VACIO, false);\n        laberinto[4][1] = new Celda(TipoCelda.OBSTACULO, true);\n        laberinto[4][2] = new Celda(TipoCelda.VACIO, false);\n        laberinto[4][3] = new Celda(TipoCelda.VACIO, false);\n        laberinto[4][4] = new Celda(TipoCelda.VACIO, false);\n        laberinto[4][5] = new Celda(TipoCelda.OBSTACULO, true);\n\n        // 5 [      ]\n        laberinto[5][0] = new Celda(TipoCelda.VACIO, false);\n        laberinto[5][1] = new Celda(TipoCelda.VACIO, false);\n        laberinto[5][2] = new Celda(TipoCelda.VACIO, false);\n        laberinto[5][3] = new Celda(TipoCelda.VACIO, false);\n        laberinto[5][4] = new Celda(TipoCelda.VACIO, false);\n        laberinto[5][5] = new Celda(TipoCelda.VACIO, false);\n    }\n\n    public void jugar() {\n        bienvenida();\n\n        Scanner scanner = new Scanner(System.in);\n        do {\n            System.out.print(\"Introduce tu movimiento: \");\n            ejecutaMovimiento(scanner.nextLine());\n        } while (!salidaEncontrada);\n    }\n\n    private void ejecutaMovimiento(String movimiento) {\n        boolean movimientoValido = true;\n        switch (movimiento.toLowerCase()) {\n            case \"q\":\n                arriba();\n                break;\n            case \"a\":\n                abajo();\n                break;\n            case \"o\":\n                izquierda();\n                break;\n            case \"p\":\n                derecha();\n                break;\n            default:\n                movimientoNoValido(movimiento);\n                movimientoValido = false;\n        }\n        if (movimientoValido) {\n            numMovimientos++;\n        }\n    }\n\n    private void arriba() {\n        Posicion posicionDeseada = new Posicion(posMickey.x - 1, posMickey.y);\n        evaluaMovimiento(posicionDeseada, \"arriba\");\n    }\n\n    private void abajo() {\n        Posicion posicionDeseada = new Posicion(posMickey.x + 1, posMickey.y);\n        evaluaMovimiento(posicionDeseada, \"abajo\");\n    }\n\n    private void izquierda() {\n        Posicion posicionDeseada = new Posicion(posMickey.x, posMickey.y - 1);\n        evaluaMovimiento(posicionDeseada, \"izquierda\");\n    }\n\n    private void derecha() {\n        Posicion posicionDeseada = new Posicion(posMickey.x, posMickey.y + 1);\n        evaluaMovimiento(posicionDeseada, \"derecha\");\n    }\n\n    private void evaluaMovimiento(Posicion posicionDesada, String direccion) {\n        if (posicionDesada.x < 0 || posicionDesada.x > 5 || posicionDesada.y < 0 || posicionDesada.y > 5) {\n            movimientoContraPared(direccion);\n        } else if (laberinto[posicionDesada.x][posicionDesada.y].tipo.tipo.equals(TipoCelda.OBSTACULO.tipo)) {\n            movimientoContraObstaculo(posicionDesada);\n        } else if (laberinto[posicionDesada.x][posicionDesada.y].tipo.tipo.equals(TipoCelda.SALIDA.tipo)) {\n            movimientoGanador();\n        } else {\n            // Solo puede ser VACIO\n            movimientoCorrecto(posicionDesada);\n        }\n    }\n\n    private void movimientoCorrecto(Posicion posicionDesada) {\n        System.out.printf(\"¡Muy bien! has alcanzado una nueva posición%n\");\n        cambiaPosicionMickey(posicionDesada);\n        pintaLaberinto(false);\n    }\n\n    private void movimientoNoValido(String movimiento) {\n        System.out.printf(\"'%s' no es un movimiento válido %n\", movimiento);\n        System.out.printf(\"Recuerda las teclas:%n -> q=arriba%n -> a=abajo%n -> o=izquierda%n -> p=derecha%n\");\n    }\n\n    private void movimientoContraObstaculo(Posicion posicionDeseada) {\n        System.out.printf(\"¡Vaya!, en esa dirección hay un obstáculo. ¡Prueba con otro movimiento!%n\");\n        laberinto[posicionDeseada.x][posicionDeseada.y].oculta = false;\n        pintaLaberinto(false);\n    }\n\n    private void movimientoContraPared(String direccion) {\n        System.out.printf(\"No puedes moverte dirección %s, es una pared del laberinto. ¡Prueba con otro movimiento!%n\", direccion);\n        laberinto[0][0].oculta = false;\n    }\n\n    private void movimientoGanador() {\n        System.out.printf(\"¡Lo conseguiste! ¡Alcanzaste la SALIDA en %d movimientos!%n\", numMovimientos);\n        salidaEncontrada = true;\n    }\n\n    private void cambiaPosicionMickey(Posicion nuevaPosicion) {\n        laberinto[posMickey.x][posMickey.y].tipo = TipoCelda.VACIO;\n        laberinto[nuevaPosicion.x][nuevaPosicion.y].tipo = TipoCelda.MICKEY;\n\n        posMickey.x = nuevaPosicion.x;\n        posMickey.y = nuevaPosicion.y;\n    }\n\n    private void bienvenida() {\n        System.out.printf(\"%n¡Bienvenido al laberinto!. ¿Serás capaz de conducir a Mickey hasta la salida?%n\");\n        System.out.printf(\"A continuación, se te revelará tu posición y la de la salida en el laberinto. ¡Pero no es tan fácil!, hay obstaculos ocultos%n\");\n        pintaLaberinto(false);\n        System.out.printf(\"Usa las siguientes teclas para moverte cuando se te solicite:%n -> q=arriba%n -> a=abajo%n -> o=izquierda%n -> p=derecha%n\");\n        System.out.printf(\"¡En marcha!%n%n\");\n    }\n\n    private void pintaLaberinto(boolean muestraOcultos) {\n        for (int i = 0; i < laberinto.length + 2 ; i++) {\n            System.out.print(\"-\");\n        }\n        System.out.printf(\"%n\");\n\n        for (Celda[] celdas : laberinto) {\n            System.out.print(\"|\");\n            for (Celda celda : celdas) {\n                if (muestraOcultos || !celda.oculta) {\n                    System.out.print(celda.tipo.simbolo);\n                } else {\n                    System.out.print(TipoCelda.VACIO.simbolo);\n                }\n            }\n            System.out.printf(\"|%n\");\n        }\n\n        for (int i = 0; i < laberinto.length + 2 ; i++) {\n            System.out.print(\"-\");\n        }\n        System.out.printf(\"%n\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/java/Josegs95.java",
    "content": "import java.util.Scanner;\n\npublic class Josegs95 {\n    public static void main(String[] args) {\n        new Josegs95().rescueMickey();\n    }\n\n    private String[][] maze;\n    private int mickeyYCoord = 4;\n    private int mickeyXCoord = 0;\n\n    final private Scanner sc = new Scanner(System.in);\n\n    public void rescueMickey(){\n        maze = initMaze();\n\n        try(sc){\n            boolean exit = false;\n            while(!exit){\n                printMaze();\n                String direction = askDirection();\n                switch (direction){\n                    case \"arriba\":\n                        exit = moveMickey(-1, 0);\n                        break;\n                    case \"abajo\":\n                        exit = moveMickey(1, 0);\n                        break;\n                    case \"derecha\":\n                        exit = moveMickey(0, 1);\n                        break;\n                    case \"izquierda\":\n                        exit = moveMickey(0, -1);\n                        break;\n                }\n                System.out.println();\n            }\n            printMaze();\n        }\n    }\n\n    private String[][] initMaze(){\n        String[][] maze = {\n                {\" \", \" \", \" \", \" \", \" \", \" \"},\n                {\" \", \"X\", \" \", \" \", \"X\", \" \"},\n                {\" \", \" \", \"X\", \" \", \"X\", \" \"},\n                {\"X\", \" \", \"X\", \" \", \"X\", \" \"},\n                {\"M\", \" \", \"X\", \"X\", \"X\", \" \"},\n                {\"X\", \"X\", \"S\", \" \", \" \", \" \"}\n        };\n\n        return maze;\n    }\n\n    private String askDirection(){\n        while (true){\n            System.out.print(\"¿A dónde se quiere desplazar (arriba/abajo/izquierda/derecha)?: \");\n            String input = sc.nextLine().strip().toLowerCase();\n            switch (input){\n                case \"arriba\":\n                case \"abajo\":\n                case \"derecha\":\n                case \"izquierda\":\n                    return input;\n                default:\n                    System.out.println(\"Opción no válida\");\n            }\n        }\n    }\n\n    public boolean moveMickey(int iChange, int jChange){\n        if (iChange != 0){\n            if (iChange > 0){\n                if (mickeyYCoord == maze.length - 1){\n                    System.out.println(\"No se puede bajar más\");\n                    return false;\n                }\n            }else{\n                if (mickeyYCoord == 0){\n                    System.out.println(\"No se puede subir más\");\n                    return false;\n                }\n            }\n        } else{\n            if (jChange > 0){\n                if (mickeyXCoord == maze[0].length - 1){\n                    System.out.println(\"No se puede ir más a la derecha\");\n                    return false;\n                }\n            }else{\n                if (mickeyXCoord == 0){\n                    System.out.println(\"No se puede ir más a la izquierda\");\n                    return false;\n                }\n            }\n        }\n\n        if(maze[mickeyYCoord + iChange][mickeyXCoord + jChange].equals(\"X\")){\n            System.out.println(\"Camino bloqueado, no se puede pasar.\");\n            return false;\n        }\n        if (maze[mickeyYCoord + iChange][mickeyXCoord + jChange].equals(\"S\")) {\n            maze[mickeyYCoord][mickeyXCoord] = \" \";\n            maze[mickeyYCoord + iChange][mickeyXCoord + jChange] = \"M\";\n            System.out.println(\"¡Felicidades, has llegado a la salida!\");\n            return true;\n        }\n\n        maze[mickeyYCoord][mickeyXCoord] = \" \";\n        maze[mickeyYCoord + iChange][mickeyXCoord + jChange] = \"M\";\n        mickeyYCoord += iChange;\n        mickeyXCoord += jChange;\n\n        return false;\n    }\n\n    private void printMaze(){\n        for (int i = 0; i < maze.length; i++){\n            for (int j = 0; j < maze[0].length; j++)\n                System.out.print(\"[\" + maze[i][j] + \"]\");\n            System.out.println();\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/java/MohamedElderkaoui.java",
    "content": "import java.util.*;\n\npublic class MohamedElderkaoui{\n\n    public static void main(String[] args) {\n        Laberinto.main(args);\n    }\n}\n class Laberinto {\n\n    public static void main(String[] args) {\n        final int SIZE = 6;\n        char[][] laberinto = generarLaberinto(SIZE);\n        int mickeyRow = 0;\n        int mickeyCol = 0;\n        int salidaRow = 0;\n        int salidaCol = 0;\n\n        // Encuentra la posición inicial de Mickey y la salida\n        for (int i = 0; i < SIZE; i++) {\n            for (int j = 0; j < SIZE; j++) {\n                if (laberinto[i][j] == 'M') {\n                    mickeyRow = i;\n                    mickeyCol = j;\n                }\n                if (laberinto[i][j] == 'S') {\n                    salidaRow = i;\n                    salidaCol = j;\n                }\n            }\n        }\n\n        Scanner scanner = new Scanner(System.in);\n        int maxMoves = 50;  // Límite de movimientos\n        int moves = 0;\n\n        while (moves < maxMoves) {\n            mostrarLaberinto(laberinto, mickeyRow, mickeyCol);\n\n            if (mickeyRow == salidaRow && mickeyCol == salidaCol) {\n                System.out.println(\"¡Felicidades! Mickey ha encontrado la salida.\");\n                break;\n            }\n\n            System.out.print(\"¿Hacia dónde quieres moverte? (arriba/abajo/izquierda/derecha): \");\n            String movimiento = scanner.nextLine().toLowerCase();\n\n            int nuevaFila = mickeyRow;\n            int nuevaColumna = mickeyCol;\n\n            switch (movimiento) {\n                case \"arriba\":\n                    nuevaFila--;\n                    break;\n                case \"abajo\":\n                    nuevaFila++;\n                    break;\n                case \"izquierda\":\n                    nuevaColumna--;\n                    break;\n                case \"derecha\":\n                    nuevaColumna++;\n                    break;\n                default:\n                    System.out.println(\"Movimiento no válido. Intenta de nuevo.\");\n                    continue;\n            }\n\n            if (esMovimientoValido(nuevaFila, nuevaColumna, laberinto)) {\n                laberinto[mickeyRow][mickeyCol] = ' ';\n                mickeyRow = nuevaFila;\n                mickeyCol = nuevaColumna;\n                laberinto[mickeyRow][mickeyCol] = 'M';\n                moves++;\n            } else {\n                System.out.println(\"Movimiento no válido. Hay un obstáculo o estás fuera del laberinto.\");\n            }\n\n            System.out.println(\"Movimientos restantes: \" + (maxMoves - moves));\n        }\n\n        if (moves >= maxMoves) {\n            System.out.println(\"¡Se acabaron los movimientos! Mickey no ha encontrado la salida.\");\n        }\n\n        scanner.close();\n    }\n\n    private static char[][] generarLaberinto(int size) {\n        char[][] laberinto = new char[size][size];\n        Random rand = new Random();\n\n        // Inicializa el laberinto con celdas vacías\n        for (int i = 0; i < size; i++) {\n            for (int j = 0; j < size; j++) {\n                laberinto[i][j] = ' ';\n            }\n        }\n\n        // Coloca los obstáculos y la salida de manera aleatoria\n        int numObstaculos = size;  // Número de obstáculos\n        for (int i = 0; i < numObstaculos; i++) {\n            int fila = rand.nextInt(size);\n            int columna = rand.nextInt(size);\n            if (laberinto[fila][columna] == ' ' && !(fila == 0 && columna == 0) && !(fila == size - 1 && columna == size - 1)) {\n                laberinto[fila][columna] = 'O';  // Obstáculo representado por 'O'\n            }\n        }\n\n        // Coloca la salida en una posición fija\n        int salidaFila = size - 1;\n        int salidaColumna = size - 1;\n        laberinto[salidaFila][salidaColumna] = 'S';  // Salida representada por 'S'\n\n        // Coloca a Mickey en una posición fija\n        int mickeyFila, mickeyColumna;\n        do {\n            mickeyFila = rand.nextInt(size);\n            mickeyColumna = rand.nextInt(size);\n        } while (laberinto[mickeyFila][mickeyColumna] != ' ');\n\n        laberinto[mickeyFila][mickeyColumna] = 'M';  // Mickey representado por 'M'\n\n        return laberinto;\n    }\n\n    private static void mostrarLaberinto(char[][] laberinto, int mickeyRow, int mickeyCol) {\n        System.out.println(\"Laberinto:\");\n        for (int i = 0; i < laberinto.length; i++) {\n            for (int j = 0; j < laberinto[i].length; j++) {\n                if (i == mickeyRow && j == mickeyCol) {\n                    System.out.print('M' + \" \");\n                } else {\n                    System.out.print(laberinto[i][j] + \" \");\n                }\n            }\n            System.out.println();\n        }\n    }\n\n    private static boolean esMovimientoValido(int fila, int columna, char[][] laberinto) {\n        return fila >= 0 && fila < laberinto.length && columna >= 0 && columna < laberinto[0].length && laberinto[fila][columna] != 'O';\n    }\n}\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/java/VolumiDev.java",
    "content": "import java.io.BufferedReader;\nimport java.io.IOException;\nimport java.io.InputStreamReader;\nimport java.util.ArrayList;\nimport java.util.Iterator;\nimport java.util.Stack;\n\nimport javax.print.attribute.SetOfIntegerSyntax;\n\npublic class Rescatar_Mickey {\n\t\n\tpublic static void generar_elementos(int row, int col, ArrayList<Elemento> elements) throws NumberFormatException, IOException {\n\t\tBufferedReader leer = new  BufferedReader(new InputStreamReader(System.in));\n\t\tRescatar_Mickey rescatarMickey = new Rescatar_Mickey();\n\t\tSystem.out.println(\"¿Cuantos obstaculos quieres crear?\");\n\t\tint num_obstaculos = Integer.parseInt(leer.readLine());\n\t\t// posicion de Mikey\n\t\tRescatar_Mickey.Mickey mickey = rescatarMickey.new Mickey();\n\t\t\n\t\tdo {\n\t\t\tmickey.colocar_elemento(row, 0);\n\t\t} while (esta_ocupado(elements, mickey));\n\t\telements.add(mickey);\n\t\t// Posicion de la salida\n\t\tRescatar_Mickey.Salida salida = rescatarMickey.new Salida(col - 1);\n\t\tdo {\n\t\t\tsalida.colocar_elemento(row, 0);\n\t\t} while (esta_ocupado(elements, salida));\n\t\telements.add(salida);\n\t\t// posicion de los obstaculos\n\t\tfor (int i = 0; i < num_obstaculos; i++) {\n\t\t\tRescatar_Mickey.Obstaculo obs = rescatarMickey.new Obstaculo();\n\t\t\tdo {\n\t\t\t\tobs.colocar_elemento(row, col);\n\t\t\t} while (esta_ocupado(elements, obs));\n\t\t\telements.add(obs);\n\t\t}\n\t}\n\t\n\t//Dibujamos el laberinto\n\tpublic static void lab_draw(ArrayList<Elemento> elements, int row, int col) {\n\t\tString[][] lab = new String[row][col];\n\n\t\tfor(Elemento element : elements) {\n\t\t\tlab[element.get_row()][element.get_col()] = element.vista;\n\t\t}\n\t\t\n\t\tSystem.out.println(\"------------ LABERINTO ------------\");\n\t\tfor (int i = 0; i < lab.length; i++) {\n\t\t\tfor (int j = 0; j < lab[i].length; j++) {\n\t\t\t\tif(lab[i][j] == null) {\n\t\t\t\t\tlab[i][j] = \"⬜\";\n\t\t\t\t}\n\t\t\t\tSystem.out.print(lab[i][j] + \"\\t\");\n\t\t\t}\n\t\t\tSystem.out.println();\n\t\t}\n\t\tvalidacion(lab, elements);\n\t}\n\t\n\t// Validamos si la posicion esta ocupada por alguno de lo elementos del arraylist\n\tpublic static boolean esta_ocupado(ArrayList<Elemento> elements, Elemento obs) {\n\t\tboolean flag = false;\n\t\tfor (int i = 0; i < elements.size() && flag == false; i++) {\n\t\t\tif (obs.row == elements.get(i).row && obs.col == elements.get(i).col) {\n\t\t\t\tflag = true;\n\t\t\t}\n\t\t}\n\t\treturn flag;\n\t}\n\t\n\t\n\t// Solicitamos movimiento de mickey\n\tpublic static void movimiento(Elemento mickey, int matrix_length) throws IOException {\n\t\tBufferedReader leer = new  BufferedReader(new InputStreamReader(System.in));\n\t\tchar mov;\n\t\tdo {\n\t\t\tSystem.out.println(\"Mueve a Mickey\");\n\t\t\tmov = leer.readLine().toUpperCase().charAt(0);\n\t\t} while (mov != 'W' && mov != 'A' && mov != 'S' && mov != 'D');\n\t\tmickey.mov(mov, matrix_length);\n\t}\n\t\n\t// Comparamos la posicion de mickey con la matriz\n\tpublic static void validacion(String[][] lab, ArrayList<Elemento>elements) {\n\t\tElemento mickey = elements.get(0);\n\t\tfor (int i = 0; i < lab.length; i++) {\n\t\t\tfor (int j = 0; j < lab.length; j++) {\n\t\t\t\tif(!lab[i][j].equalsIgnoreCase(\"⬜\")) {\n\t\t\t\t\tif(lab[i][j].equalsIgnoreCase(\"🚪\")  && mickey.get_col() == j && mickey.get_row() == i) {\n\t\t\t\t\t\tmickey.set_Exit(true);\n\t\t\t\t\t\tSystem.out.println(\"LO LOGRASTE. MICKEY ESCAPO\");\n\t\t\t\t\t}else if(lab[i][j].equalsIgnoreCase(\"💣\")  && mickey.get_col() == j && mickey.get_row() == i) {\n\t\t\t\t\t\tmickey.set_Life(false);\n\t\t\t\t\t\tSystem.out.println(\"MICKEY HA MUERTO\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t\n\t\n\tpublic static void main(String[] args) throws IOException {\n\t\t// TODO Auto-generated method stub\n\t\tBufferedReader leer = new  BufferedReader(new InputStreamReader(System.in));\n\t\tint row = 0, col = 0;\n\t\tString[][] lab;\n\t\tdo {\n\t\t\ttry {\n\t\t\t\tSystem.out.println(\"Introduce el numero de filas y columnas\");\n\t\t\t\trow = Integer.parseInt(leer.readLine());\n\t\t\t\tcol = row;\n\t\t\t} catch (NumberFormatException e) {\n\t\t\t\t// TODO: handle exception\n\t\t\t\tSystem.out.println(\"Solo valores numericos\");\n\t\t\t}\n\t\t} while (row < 2);\n\t\tArrayList<Elemento> elements = new ArrayList<Elemento>();\n\t\tgenerar_elementos(row, col, elements);\n\t\tlab_draw(elements, row, col);\n\t\twhile(elements.get(0).isLife() && elements.get(0).isexit() == false) {\n\t\t\tmovimiento(elements.get(0), row);\n\t\t\tlab_draw(elements, row, col);\n\t\t}\n\t\tSystem.out.println(\"PARTIDA TERMINADA\");\n\t}\n\t\n\t\n\tpublic class Elemento{\n\t\tprivate String vista;\n\t\tprivate int row;\n\t\tprivate int col;\n\t\t\n\t\t// Metodo que coloca un elemento en la matriz del laberinto\n\t\tprotected void colocar_elemento(int row, int col) {\n\n\t\t}\n\t\t\n\t\tprotected int get_row() {\n\t\t\treturn row;\n\t\t}\n\t\t\n\t\tprotected int get_col() {\n\t\t\treturn col;\n\t\t}\n\t\tprotected boolean isLife() {\n\t\t\treturn false;\n\t\t}\n\t\t\n\t\tprotected boolean isexit() {\n\t\t\treturn false;\n\t\t}\n\t\t\n\t\tpublic void mov(char key, int matrix_lentgh) {\n\t\t\t\n\t\t}\n\t\tpublic void set_Exit(boolean exit) {\n\t\t}\n\t\tpublic void set_Life(boolean life) {\n\t\t}\n\t}\n\n\t// Clase que representa a Mickey Mouse\n\tpublic class Mickey extends Elemento{\n\t\t\n\t\tprivate boolean life;\n\t\tprivate boolean exit;\n\t\t\n\t\tpublic Mickey() {\n\t\t\t// TODO Auto-generated constructor stub\n\t\t\tsuper();\n\t\t\tsuper.vista = \"🐭\";\n\t\t\tsuper.col = 0;\n\t\t\tlife = true;\n\t\t\texit = false;\n\t\t}\n\t\t\n\t\t\n\t\t// Metodo que coloca un elemento en la matriz del laberinto\n\t\tpublic void colocar_elemento(int row, int col) {\n\t\t\tsuper.row = (int) (Math.random()*row);\n\t\t}\n\t\t\n\t\tpublic void mov(char key, int matrix_lentgh) {\n\t\t\tswitch (key) {\n\t\t\tcase 'W':\n\t\t\t\tif(super.row > 0) {\n\t\t\t\tsuper.row--;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'A':\n\t\t\t\tif(super.col > 0) {\n\t\t\t\t\tsuper.col--;\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'S':\n\t\t\t\tif(super.row < matrix_lentgh - 1) {\n\t\t\t\t\tsuper.row++;\t\t\t\t\t\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'D':\n\t\t\t\tif(super.col < matrix_lentgh - 1) {\n\t\t\t\t\tsuper.col++;\t\t\t\t\t\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tSystem.out.println(\"Tecla incorrecta\");\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\t\n\t\tpublic void set_Exit(boolean e) {\n\t\t\tthis.exit = true;\n\t\t}\n\t\tpublic void set_Life(boolean l) {\n\t\t\tthis.life = false;\n\t\t}\n\t\t\n\t\tpublic boolean isLife() {\n\t\t\treturn life;\n\t\t}\n\t\t\n\t\tpublic boolean isexit() {\n\t\t\treturn exit;\n\t\t}\n\t\t\n\t}\n\t\n\t// Clase que representa obstaculos\n\tpublic class Obstaculo extends Elemento{\n\t\t\n\t\tObstaculo(){\n\t\t\tsuper();\n\t\t\tsuper.vista = \"💣\";\n\t\t}\n\t\t\n\t\tpublic void get_pos() {\n\t\t\tSystem.out.println(\"ROW = \" + super.row + \"COL = \" + super.col);\n\t\t}\n\t\t\n\t\t// Metodo que coloca un elemento en la matriz del laberinto\n\t\t\t\tpublic void colocar_elemento(int row, int col) {\n\t\t\t\t\tsuper.row = (int) (Math.random()*row);\n\t\t\t\t\tsuper.col = (int) (Math.random()*((col-2) -1 + 1) + 1);\n\t\t\t\t}\n\t}\n\t\n\t//Clase que representa la salida\n\tpublic class Salida extends Elemento{\n\t\t\n\t\tSalida(int col){\n\t\t\tsuper();\n\t\t\tsuper.vista = \"🚪\";\n\t\t\tsuper.col = col;\n\t\t}\n\t\t\n\t\tpublic void get_pos() {\n\t\t\tSystem.out.println(\"X = \" + super.row + \"Y = \" + super.col);\n\t\t}\n\t\t\n\t\t// Metodo que coloca un elemento en la matriz del laberinto\n\t\tpublic void colocar_elemento(int row, int col) {\n\t\t\tsuper.row = (int) (Math.random()*row);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/java/asjordi.java",
    "content": "import java.util.Arrays;\nimport java.util.Scanner;\n\npublic class Main {\n\n    private static final String EMPTY = \"⬜\";\n    private static final String BARRIER = \"⬛\";\n    private static final String MICKEY = \"\\uD83D\\uDC2D\";\n    private static final String EXIT = \"\\uD83D\\uDEAA\";\n    private static String[][] board = {\n            {MICKEY, EMPTY, EMPTY, EMPTY, EMPTY, BARRIER},\n            {EMPTY, BARRIER, EMPTY, EMPTY, BARRIER, EMPTY},\n            {EMPTY, BARRIER, EMPTY, BARRIER, EMPTY, EMPTY},\n            {EMPTY, EMPTY, EMPTY, EMPTY, BARRIER, EMPTY},\n            {BARRIER, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY},\n            {EMPTY, BARRIER, EMPTY, EMPTY, EMPTY, EXIT}\n    };\n\n    public static void main(String[] args) {\n        Scanner sc = new Scanner(System.in);\n        System.out.println(\"Welcome to the maze game! Find the exit to help Mickey Mouse escape!\");\n        System.out.println(\"Movements available: W (up), A (left), S (down), D (right)\");\n        System.out.println(\"Write 'exit' to quit the game\");\n        System.out.println(\"Good luck!\");\n        System.out.println(\"Where do you want to move?\");\n\n        String input = \"\";\n\n        while (!input.equalsIgnoreCase(\"exit\")) {\n            printBoard();\n            input = sc.nextLine();\n            if (move(input)) break;\n        }\n    }\n\n    private static boolean move(String direction) {\n        int[] mickeyPosition = findMickey();\n        int x = mickeyPosition[0];\n        int y = mickeyPosition[1];\n\n        if (x == board.length - 1 && y == board[0].length - 1) {\n            System.out.println(\"Congratulations! You helped Mickey Mouse escape!\");\n            return true;\n        }\n\n        switch (direction) {\n            case \"W\":\n                if (x > 0 && !board[x - 1][y].equals(BARRIER)) {\n                    board[x][y] = EMPTY;\n                    board[x - 1][y] = MICKEY;\n                }\n                break;\n            case \"A\":\n                if (y > 0 && !board[x][y - 1].equals(BARRIER)) {\n                    board[x][y] = EMPTY;\n                    board[x][y - 1] = MICKEY;\n                }\n                break;\n            case \"S\":\n                if (x < board.length - 1 && !board[x + 1][y].equals(BARRIER)) {\n                    board[x][y] = EMPTY;\n                    board[x + 1][y] = MICKEY;\n                }\n                break;\n            case \"D\":\n                if (y < board[0].length - 1 && !board[x][y + 1].equals(BARRIER)) {\n                    board[x][y] = EMPTY;\n                    board[x][y + 1] = MICKEY;\n                }\n                break;\n            case \"EXIT\":\n                System.out.println(\"Thanks for playing!\");\n                break;\n            default:\n                System.out.println(\"Invalid input. Please try again.\");\n        }\n\n        return false;\n    }\n\n    private static int[] findMickey() {\n        int[] mickeyPosition = new int[2];\n\n        for (int i = 0; i < board.length; i++) {\n            for (int j = 0; j < board[0].length; j++) {\n                if (board[i][j].equals(MICKEY)) {\n                    mickeyPosition[0] = i;\n                    mickeyPosition[1] = j;\n                    break;\n                }\n            }\n        }\n\n        return mickeyPosition;\n    }\n\n    static void printBoard() {\n        for (String[] strings : board) {\n            System.out.println(Arrays.toString(strings));\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/java/danhingar.java",
    "content": "import java.util.Objects;\nimport java.util.Scanner;\n\npublic class danhingar {\n\n    public static void main(String[] args) {\n\n        String[][] maze = { { \"🐭\", \"⬛\", \"⬛\", \"⬛\", \"⬛\", \"⬜\" },\n                { \"⬜\", \"⬛\", \"⬜\", \"⬛\", \"⬜\", \"⬜\" },\n                { \"⬜\", \"⬜\", \"⬜\", \"⬛\", \"⬜\", \"⬛\" },\n                { \"⬜\", \"⬛\", \"⬜\", \"⬜\", \"⬜\", \"⬛\" },\n                { \"⬜\", \"⬜\", \"⬛\", \"⬜\", \"⬜\", \"⬜\" },\n                { \"⬜\", \"⬛\", \"⬛\", \"⬛\", \"⬛\", \"🚪\" } };\n\n        print(maze);\n\n        int[] mickey = { 0, 0 };\n        Scanner sc = new Scanner(System.in);\n        while (Boolean.TRUE) {\n            System.out.println(\"¿Hacia dónde se mueve Mickey?\");\n            System.out.println(\"[u] Arriba\");\n            System.out.println(\"[d] Abajo\");\n            System.out.println(\"[l] Izquierda\");\n            System.out.println(\"[r] Derecha\");\n            System.out.print(\"Dirección: \");\n\n            String direction = sc.nextLine();\n\n            int currentRow = mickey[0], currentColumn = mickey[1];\n            int newRow = currentRow, newColumn = currentColumn;\n\n            switch (direction) {\n                case \"u\":\n                    newRow = currentRow - 1;\n                    break;\n                case \"d\":\n                    newRow = currentRow + 1;\n                    break;\n                case \"r\":\n                    newColumn = currentColumn + 1;\n                    break;\n                case \"l\":\n                    newColumn = currentColumn - 1;\n                    break;\n                default:\n                    System.out.println(\"Dirección no válida.\\n\");\n                    break;\n            }\n\n            if ((newRow < 0 || newRow > 5) || (newColumn < 0 || newColumn > 5)) {\n                System.out.println(\"No puedes desplazarte fuera del Laberinto.\\n\");\n            } else if (Objects.equals(maze[newRow][newColumn], \"⬛\")) {\n                System.out.println(\"!En esa dirección hay un obstáculo!\\n\");\n                continue;\n            } else if (Objects.equals(maze[newRow][newColumn], \"🚪\")) {\n                System.out.println(\"!Has encontrado la salida!\");\n                break;\n            } else {\n                maze[currentRow][currentColumn] = \"⬜\";\n                maze[newRow][newColumn] = \"🐭\";\n                mickey[0] = newRow;\n                mickey[1] = newColumn;\n                print(maze);\n            }\n\n        }\n        sc.close();\n    }\n\n    public static void print(String[][] maze) {\n        for (int i = 0; i < 6; i++) {\n            for (int j = 0; j < 6; j++) {\n                System.out.print(\"\".concat(maze[i][j]));\n\n            }\n            System.out.println();\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/java/martinbohorquez.java",
    "content": "import java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\nimport java.util.Scanner;\n\n/**\n * #33 RESCATANDO A MICKEY\n *\n * @author martinbohorquez\n */\npublic class martinbohorquez {\n\n    static Scanner sc = new Scanner(System.in);\n\n    static List<List<String>> maze = new ArrayList<>(\n            Arrays.asList(\n                    Arrays.asList(\"🐭\", \"⬛️\", \"⬛️\", \"⬛️\", \"⬛️\", \"⬛️\"),\n                    Arrays.asList(\"⬜️\", \"⬛️\", \"⬛️\", \"⬛️\", \"⬜️\", \"⬛️\"),\n                    Arrays.asList(\"⬜️\", \"⬛️\", \"⬛️\", \"⬛️\", \"⬜️\", \"⬛️\"),\n                    Arrays.asList(\"⬜️\", \"⬜️\", \"⬜️\", \"⬜️\", \"⬜️\", \"⬜️\"),\n                    Arrays.asList(\"⬛️\", \"⬜️\", \"⬛️\", \"⬜️\", \"⬛️\", \"⬛️\"),\n                    Arrays.asList(\"⬛️\", \"⬜️\", \"⬛️\", \"⬜️\", \"⬜️\", \"🚪\")\n            )\n    );\n\n    static Position mickey = new Position(\"Mickey\");\n    static boolean flag = false;\n\n    public static void main(String[] args) {\n\n        while (!flag) {\n            System.out.println(\"<-------------- JUEGO DE MICKY ------------------>\");\n            printMaze(maze);\n            System.out.println(\"\"\"\n                    ¿Hacia dónde se mueve Mickey?\n                    [w] arriba\n                    [s] abajo\n                    [a] izquierda\n                    [d] derecha\n                    \"\"\");\n            System.out.print(\"Dirección: \");\n            String direction = sc.nextLine().toLowerCase();\n\n            mickey.move(direction);\n        }\n    }\n\n    private static void printMaze(List<List<String>> maze) {\n        maze.forEach(row -> {\n            row.forEach(cell -> System.out.print(cell + \" \"));\n            System.out.println();\n        });\n    }\n\n    static class Position {\n        private String name;\n        private Integer row;\n        private Integer column;\n\n        public Position(String name) {\n            this.name = name;\n            this.row = 0;\n            this.column = 0;\n        }\n\n        private String getName() {\n            return name;\n        }\n\n        private Integer getRow() {\n            return row;\n        }\n\n        private void setRow(Integer row) {\n            this.row = row;\n        }\n\n        private Integer getColumn() {\n            return column;\n        }\n\n        private void setColumn(Integer column) {\n            this.column = column;\n        }\n\n        private void move(String direction) {\n            switch (direction) {\n                case \"w\" -> update(-1, 0);\n                case \"s\" -> update(1, 0);\n                case \"a\" -> update(0, -1);\n                case \"d\" -> update(0, 1);\n                default -> System.out.printf(\"Dirección '%s' es incorrecta!%n\", direction);\n            }\n        }\n\n        private void update(int i, int j) {\n            if (getRow() + i < 0 || getRow() + i > maze.size() || getColumn() + j < 0 || getColumn() + j > maze.getFirst().size())\n                System.out.println(\"¡No puedes desplazarte fuera del laberinto!\");\n            else if (maze.get(getRow() + i).get(getColumn() + j).equals(\"⬛️\"))\n                System.out.println(\"¡En esa dirección hay un obstáculo!\");\n            else {\n                maze.get(getRow()).set(getColumn(), \"⬜️\");\n                setRow(getRow() + i);\n                setColumn(getColumn() + j);\n                if (maze.get(getRow()).get(getColumn()).equals(\"🚪\")) {\n                    System.out.printf(\"¡%s ha encontrado la salida!%n\", mickey.getName());\n                    flag = true;\n                }\n                maze.get(getRow()).set(getColumn(), \"🐭\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/javascript/Eduardo282.js",
    "content": "// Representación del laberinto\nlet laberinto = [\n  [\"⬜️\", \"⬜️\", \"⬛️\", \"⬜️\", \"⬛️\", \"⬜️\"],\n  [\"⬛️\", \"⬛️\", \"⬛️\", \"⬜️\", \"⬛️\", \"⬜️\"],\n  [\"⬜️\", \"⬜️\", \"⬜️\", \"⬜️\", \"⬛️\", \"⬜️\"],\n  [\"⬛️\", \"⬛️\", \"⬛️\", \"⬛️\", \"⬛️\", \"⬜️\"],\n  [\"⬜️\", \"🐭\", \"⬜️\", \"⬛️\", \"⬜️\", \"⬜️\"],\n  [\"⬜️\", \"⬛️\", \"⬜️\", \"⬛️\", \"⬜️\", \"🚪\"],\n];\n\n// Posición inicial de Mickey\nlet posicionMickey = { x: 4, y: 1 };\n\n// Función para mostrar el laberinto\nfunction mostrarLaberinto() {\n  laberinto.forEach((fila) => console.log(fila.join(\" \")));\n  console.log();\n}\n\n// Función para mover a Mickey\nfunction moverMickey(direccion) {\n  let { x, y } = posicionMickey;\n  let nuevaPosicion;\n\n  switch (direccion) {\n    case \"arriba\":\n      nuevaPosicion = { x: x - 1, y: y };\n      break;\n    case \"abajo\":\n      nuevaPosicion = { x: x + 1, y: y };\n      break;\n    case \"izquierda\":\n      nuevaPosicion = { x: x, y: y - 1 };\n      break;\n    case \"derecha\":\n      nuevaPosicion = { x: x, y: y + 1 };\n      break;\n    default:\n      console.log(\n        \"Dirección no válida. Usa 'arriba', 'abajo', 'izquierda' o 'derecha'.\"\n      );\n      return false;\n  }\n\n  let { x: nx, y: ny } = nuevaPosicion;\n\n  // Validar límites y obstáculos\n  if (nx < 0 || nx >= 6 || ny < 0 || ny >= 6) {\n    console.log(\"¡No puedes salir del laberinto!\");\n    return false;\n  } else if (laberinto[nx][ny] === \"⬛️\") {\n    console.log(\"¡Cuidado! Hay un obstáculo.\");\n    return false;\n  } else if (laberinto[nx][ny] === \"🚪\") {\n    console.log(\"¡Felicidades! ¡Mickey ha encontrado la salida!\");\n    return true;\n  } else {\n    // Actualizar la posición de Mickey en el laberinto\n    laberinto[x][y] = \"⬜️\";\n    laberinto[nx][ny] = \"🐭\";\n    posicionMickey = { x: nx, y: ny };\n    return false;\n  }\n}\n\n// Ciclo principal del juego\nfunction jugar() {\n  while (true) {\n    mostrarLaberinto();\n    let direccion = prompt(\n      \"¿Hacia dónde debería ir Mickey? (arriba, abajo, izquierda, derecha):\"\n    ).toLowerCase();\n    if (moverMickey(direccion)) {\n      break;\n    }\n  }\n  console.log(\"¡Juego terminado!\");\n}\n\n// Ejecutar el juego\njugar();\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #33 - JavaScript -> Jesus Antonio Escamilla */\n\n/**\n * RESCATANDO A MICKEY\n * Utilizando la Terminal para pedir datos y agregarlos.\n */\n\nconst readline = require('readline');\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nconst laberinto = [\n    ['⬛️', '⬛️', '⬜️', '⬛️', '⬛️', '⬛️'],\n    ['⬛️', '⬜️', '⬜️', '⬜️', '⬛️', '⬛️'],\n    ['⬜️', '⬜️', '⬛️', '⬜️', '⬛️', '⬛️'],\n    ['🐭', '⬜️', '⬛️', '⬜️', '⬜️', '⬛️'],\n    ['⬛️', '⬛️', '⬛️', '⬛️', '⬜️', '⬜️'],\n    ['🚪', '⬜️', '⬜️', '⬜️', '⬜️', '⬛️'],\n];\n\n\nlet mickeyPosition = { x: 3, y: 0 }; // Posición inicial de Mickey\nlet exitPosition = { x: 5, y: 0 }; // Posición de la salida\n\n// Mostrar laberinto\nfunction mostrarLaberinto() {\n    laberinto.forEach((fila) => {\n        console.log(fila.join(' '))\n    });\n    console.log('\\n')\n}\n\n// Función para que se mueva Mickey\nfunction moverMickey(direction) {\n    const { x, y } = mickeyPosition;\n    let newX = x;\n    let newY = y;\n\n    switch (direction.toLowerCase()) {\n        case 'w':\n            newX = x - 1\n            break;\n\n        case 's':\n            newX = x + 1\n            break;\n\n        case 'a':\n            newY = y - 1\n            break;\n\n        case 'd':\n            newY = y + 1\n            break;\n\n        default:\n            console.log('Dirección no valida')\n            return;\n    }\n\n    // Validar limites y obstáculos\n    if (newX >= 0 && newX < 6 && newY >= 0 && newY < 6) {\n        if (laberinto[newX][newY] === '⬛️') {\n            console.log('Hay un obstáculo');\n            return;\n        } else if (laberinto[newX][newY] === '🚪') {\n            laberinto[x][y] = '⬜️';\n            laberinto[newX][newY] = '🐭';\n            console.log('¡Mickey ha encontrado la salida! 🎉');\n            mostrarLaberinto();\n        } else {\n            laberinto[x][y] = '⬜️';\n            laberinto[newX][newY] = '🐭';\n            mickeyPosition = { x: newX, y: newY };\n        }\n    } else {\n        console.log('No puedes desplazarte fuera del laberinto');\n        return;\n    }\n}\n\nfunction iniciarJuego() {\n    mostrarLaberinto()\n    rl.question(`Donde quieres mover a Mickey? ([w] arriba, [s] abajo,[a] izquierda, [d] derecha) salir: `, (resp) => {\n        moverMickey(resp)\n        if (mickeyPosition.x !== exitPosition.x || mickeyPosition.y !== exitPosition.y) {\n            iniciarJuego();\n            return\n        } else {\n            rl.close();\n            return;\n        }\n    });\n}\n\niniciarJuego();"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/javascript/JesusEs1312.js",
    "content": "const readline = require('readline');\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nclass RescatandoMickey {\n    constructor(){\n        this.matrix = [\n            [\"🚪\", \"⬜️\", \"⬜️\", \"⬛️\", \"⬜️\", \"⬜️\"],\n            [\"⬜️\", \"⬛️\", \"⬜️\", \"⬜️\", \"⬛️\", \"⬜️\"],\n            [\"⬜️\", \"⬜️\", \"⬛️\", \"⬜️\", \"⬜️\", \"⬜️\"],\n            [\"⬜️\", \"⬛️\", \"⬜️\", \"⬜️\", \"⬜️\", \"⬛️\"],\n            [\"⬜️\", \"⬛️\", \"⬜️\", \"⬛️\", \"⬜️\", \"⬜️\"],\n            [\"⬜️\", \"⬜️\", \"⬜️\", \"⬛️\", \"⬜️\", \"🐭\"]\n        ];\n        this.positions = {\n            actual: {x: 5, y: 5},\n            new: {x: 0, y: 0}\n        }\n        this.move = '';\n    }\n\n    showMaze(){\n        let matrix = this.matrix;\n        for(let i = 0; i < matrix.length; i++){\n            for(let j = 0; j < matrix.length; j++){\n                process.stdout.write(matrix[i][j]);\n            }\n            console.log(\"\");\n        }\n    }\n\n    changePositions() {\n        let actualPositionX      = this.positions.actual.x;\n        let actualPositionY      = this.positions.actual.y;\n        let newPositionX         = this.positions.new.x;\n        let newPositionY         = this.positions.new.y;\n        let matrix               = this.matrix;\n        let temporalActual       = matrix[actualPositionX][actualPositionY];//🐭\n        matrix[actualPositionX][actualPositionY] = matrix[newPositionX][newPositionY];//🐭 = ⬜️  \n        matrix[newPositionX][newPositionY] = temporalActual;//⬜️ = 🐭 \n        this.matrix = matrix;\n        this.positions.actual.x = newPositionX;\n        this.positions.actual.y = newPositionY;\n        this.start();\n    }\n\n    validationMove() {\n        let mickeyX = this.positions.new.x;\n        let mickeyY = this.positions.new.y;\n        let move    = this.move;\n        let matrix  = this.matrix;\n\n        if(mickeyX == 6 && move == 's'){\n            console.log(\"===== No puedes ir abajo =====\");\n            this.start();\n        } else if(mickeyY == 6 && move == 'd'){\n            console.log(\"===== No puedes ir a la derecha =====\");\n            this.start();\n        } else if(mickeyY < 0  && move == 'a') {\n            console.log(\"===== No puedes ir a la izquierda =====\");\n            this.start();\n        } else if(mickeyX < 0 && move == 'w') {\n            console.log(\"===== No puedes ir arriba =====\");\n            this.start();\n        } else if(matrix[mickeyX][mickeyY] == \"⬛️\"){\n            console.log(\"===== No puedes moverte a esa dirección porque hay un obstaculo =====\");\n            this.start();\n        } else if(matrix[mickeyX][mickeyY] == \"🚪\"){\n            console.log(\"====== Felicidades has rescatado a Mickey :D =====\");\n            rl.close();\n        } else if (matrix[mickeyX][mickeyY] == \"⬜️\"){\n            this.changePositions();\n        }\n    }\n\n    start(){\n        console.log(\"----------------------------------------\");\n        console.log(\"¡Ayuda a Mickey a salir del laberinto!\");\n        this.showMaze();\n        rl.question(\"Selecciona una de las siguientes opciones: [w] Arriba, [s] Abajo, [a] Izquierda, [d] Derecha, [f] Salir: \", (resp) =>{\n            this.move = resp;\n            switch(resp){\n                case 'w':\n                    this.positions.new.x = this.positions.actual.x-1;\n                    this.positions.new.y = this.positions.actual.y;\n                    this.validationMove();\n                    break;\n                case 's':\n                    this.positions.new.x = this.positions.actual.x+1;\n                    this.positions.new.y = this.positions.actual.y;\n                    this.validationMove();\n                    break;\n                case 'a':\n                    this.positions.new.x = this.positions.actual.x;\n                    this.positions.new.y = this.positions.actual.y-1;\n                    this.validationMove();\n                    break;\n                case 'd':\n                    this.positions.new.x = this.positions.actual.x;\n                    this.positions.new.y = this.positions.actual.y+1;\n                    this.validationMove();\n                    break;\n                case 'f':\n                    rl.close();\n                    break;\n                default:\n                    process.stdout.write(\"Opción no valida, intenta de nuevo\");\n                    this.start();\n            }\n        });\n    }\n}\n\nlet rescatandoMickey = new RescatandoMickey();\nrescatandoMickey.start();\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/javascript/Rafacv23.js",
    "content": "const readline = require(\"readline\") // importamos para poder pedir al usuario inputs a través de la terminal.\n\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout,\n})\n\n/* \n    Creado por Rafa Canosa\n    Github: https://github.com/Rafacv23\n    Website: https://www.rafacanosa.dev\n*/\n\n// Creamos el tabler de juego de 6x6\n\nconst board = [\n  [\"⬜\", \"⬜\", \"⬛\", \"⬜\", \"⬜\", \"⬜\"],\n  [\"⬛\", \"⬜\", \"⬜\", \"⬜\", \"⬛\", \"⬜\"],\n  [\"⬛\", \"⬛\", \"⬛\", \"⬛\", \"⬛\", \"⬜\"],\n  [\"⬜\", \"⬜\", \"🚪\", \"⬛\", \"⬛\", \"⬜\"],\n  [\"⬜\", \"⬛\", \"⬛\", \"⬛\", \"⬜\", \"⬜\"],\n  [\"⬜\", \"⬜\", \"⬜\", \"⬜\", \"⬜\", \"⬛\"],\n]\n\nlet position = { x: 0, y: 0 } // posicion del jugador, la posicion inicial siempre es 0,0\n\n// funcion encargada de pintar el tablero\nfunction showLabyrinth() {\n  console.clear() // limpiamos la consola antes de pintar el tablero\n\n  console.log(\n    `Utiliza las teclas WASD para elegir la dirección a la que quieres moverte y después pulsa ENTER para confirmar. Presiona Crtl+C para salir del juego.`\n  )\n\n  for (let y = 0; y < board.length; y++) {\n    let row = \"\"\n    for (let x = 0; x < board[y].length; x++) {\n      if (x === position.x && y === position.y) {\n        row += \"🐭\" // representa al jugador\n      } else {\n        row += board[y][x]\n      }\n    }\n    console.log(row)\n  }\n}\n\n// función encargada de mover al jugador a través del tablero y de verificar si se ha ganado.\nfunction movePlayer(dir) {\n  const newPosition = { ...position }\n\n  if (dir === \"w\") newPosition.y -= 1 // arriba\n  if (dir === \"s\") newPosition.y += 1 // abajo\n  if (dir === \"a\") newPosition.x -= 1 // izquierda\n  if (dir === \"d\") newPosition.x += 1 // derecha\n\n  // Verificar que la nueva posición esté dentro de los límites del tablero\n  if (\n    newPosition.x >= 0 &&\n    newPosition.x < board[0].length &&\n    newPosition.y >= 0 &&\n    newPosition.y < board.length\n  ) {\n    // Verificar si la nueva posición es un muro\n    if (board[newPosition.y][newPosition.x] === \"⬛\") {\n      console.log(\n        `Mickey 🐭 se ha chocado contra un muro ⬛, prueba a moverte en otra dirección.`\n      )\n    } else {\n      // Solo si la nueva posición no es un muro, actualiza la posición del jugador\n      position = newPosition\n    }\n  } else {\n    console.log(\n      `Mickey 🐭 no puede salir del tablero, prueba a moverte en otra dirección.`\n    )\n  }\n\n  if (board[position.y][position.x] === \"🚪\") {\n    console.log(\"Has ganado, Mickey 🐭 ha salido del laberinto.\")\n    rl.close()\n    process.exit(0)\n  }\n\n  showLabyrinth()\n}\n\nshowLabyrinth()\n\nrl.on(\"line\", (input) => {\n  movePlayer(input)\n})\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/javascript/RaulDoezon.js",
    "content": "/*\n  EJERCICIO:\n  ¡Disney ha presentado un montón de novedades en su D23! \n  Pero... ¿Dónde está Mickey?\n  Mickey Mouse ha quedado atrapado en un laberinto mágico \n  creado por Maléfica.\n  Desarrolla un programa para ayudarlo a escapar.\n  Requisitos:\n  1. El laberinto está formado por un cuadrado de 6x6 celdas.\n  2. Los valores de las celdas serán:\n     - ⬜️ Vacío\n     - ⬛️ Obstáculo\n     - 🐭 Mickey\n     - 🚪 Salida\n  Acciones:\n  1. Crea una matriz que represente el laberinto (no hace falta\n  que se genere de manera automática).\n  2. Interactúa con el usuario por consola para preguntarle hacia\n  donde se tiene que desplazar (arriba, abajo, izquierda o derecha).\n  3. Muestra la actualización del laberinto tras cada desplazamiento.\n  4. Valida todos los movimientos, teniendo en cuenta los límites\n  del laberinto y los obtáculos. Notifica al usuario.\n  5. Finaliza el programa cuando Mickey llegue a la salida.\n*/\n\nconst maze = [\n  [\"🐭\", \"⬛️\", \"⬛️\", \"⬛️\", \"⬜️\", \"⬜️\"],\n  [\"⬜️\", \"⬛️\", \"⬜️\", \"⬜️\", \"⬜️\", \"⬛️\"],\n  [\"⬜️\", \"⬛️\", \"⬜️\", \"⬛️\", \"⬜️\", \"⬛️\"],\n  [\"⬜️\", \"⬜️\", \"⬜️\", \"⬛️\", \"⬜️\", \"⬜️\"],\n  [\"⬜️\", \"⬛️\", \"⬜️\", \"⬜️\", \"⬛️\", \"⬜️\"],\n  [\"⬜️\", \"⬜️\", \"⬛️\", \"⬜️\", \"⬛️\", \"🚪\"],\n];\n\nconst moves = \"Arriba, Abajo, Izquierda, Derecha\";\nlet columnPosition = \"\";\nlet rowPosition = \"\";\n\nfunction mickeyPosition() {\n  for (let column = 0; column < maze.length; column++) {\n    for (let row = 0; row < maze[column].length; row++) {\n      if (maze[column][row] == \"🐭\") {\n        columnPosition = column;\n        rowPosition = row;\n      }\n    }\n  }\n}\n\nfunction moveTop() {\n  mickeyPosition();\n\n  if (columnPosition - 1 < 0 || maze[columnPosition - 1][rowPosition].includes(\"⬛️\")) {\n    alert(\"No puedes ir hacia arriba. Hay un obstáculo.\");\n  } else {\n    maze[columnPosition][rowPosition] = \"⬜️\";\n\n    if (maze[columnPosition - 1][rowPosition].includes(\"🚪\")) {\n      alert(\"¡Mickey encontró la salida!\");\n    } else {\n      maze[columnPosition - 1][rowPosition] = \"🐭\";\n    }\n  }\n\n  console.table(maze);\n}\n\nfunction moveDown() {\n  mickeyPosition();\n\n  if (columnPosition + 1 === maze.length || maze[columnPosition + 1][rowPosition].includes(\"⬛️\")) {\n    alert(\"No puedes ir hacia abajo. Hay un obstáculo.\");\n  } else {\n    maze[columnPosition][rowPosition] = \"⬜️\";\n\n    if (maze[columnPosition + 1][rowPosition].includes(\"🚪\")) {\n      alert(\"¡Mickey encontró la salida!\");\n    } else {\n      maze[columnPosition + 1][rowPosition] = \"🐭\";\n    }\n  }\n\n  console.table(maze);\n}\n\nfunction moveLeft() {\n  mickeyPosition();\n\n  if (maze[columnPosition][rowPosition - 1] === undefined || maze[columnPosition][rowPosition - 1].includes(\"⬛️\")) {\n    alert(\"No puedes ir a la izquierda. Hay un obstáculo.\");\n  } else {\n    maze[columnPosition][rowPosition] = \"⬜️\";\n\n    if (maze[columnPosition][rowPosition - 1].includes(\"🚪\")) {\n      alert(\"¡Mickey encontró la salida!\");\n    } else {\n      maze[columnPosition][rowPosition - 1] = \"🐭\";\n    }\n  }\n\n  console.table(maze);\n}\n\nfunction moveRight() {\n  mickeyPosition();\n\n  if (maze[columnPosition][rowPosition + 1] === undefined ||  maze[columnPosition][rowPosition + 1].includes(\"⬛️\")) {\n    alert(\"No puedes ir a la derecha. Hay un obstáculo.\");\n  } else {\n    maze[columnPosition][rowPosition] = \"⬜️\";\n\n    if (maze[columnPosition][rowPosition + 1].includes(\"🚪\")) {\n      alert(\"¡Mickey encontró la salida!\");\n    } else {\n      maze[columnPosition][rowPosition + 1] = \"🐭\";\n    }\n  }\n\n  console.table(maze);\n}\n\ndo {\n  const userInteraction = prompt(moves);\n\n  switch (userInteraction) {\n    case \"Arriba\":\n      moveTop();\n      break;\n\n    case \"Abajo\":\n      moveDown();\n      break;\n\n    case \"Izquierda\":\n      moveLeft();\n      break;\n\n    case \"Derecha\":\n      moveRight();\n      break;\n\n    default:\n      alert(\"Por favor, ingresa una opción válida.\");\n      break;\n  }\n} while (maze.find((mickey) => mickey.includes(\"🐭\")) !== undefined);\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/javascript/RicJDev.js",
    "content": "/*\n  EJERCICIO:\n\n- Se ejecuta en Node.js, importando el módulo 'Readline/promises' (https://nodejs.org/api/readline.html)\n\n  @RicJDev\n*/\n\n//PARTE I: modelado del laberinto (estático) y las funciones para dibujar y mover al personaje.\n\nconst maze = [\n  [0, 0, 0, 1, 0, 1],\n  [0, 1, 1, 1, 0, 1],\n  [0, 0, 0, 1, 0, 0],\n  [1, 0, 1, 1, 1, 0],\n  [0, 0, 0, 0, 1, 0],\n  [0, 0, 1, 0, 0, 0],\n]\n\nconst character = { y: 5, x: 0 }\n\nconst door = { y: 0, x: 4 }\n\nfunction drawMaze() {\n  maze[door.y][door.x] = 5\n  maze[character.y][character.x] = 6\n\n  const items = {\n    0: '⬜️',\n    1: '⬛️',\n    5: '🚪',\n    6: '🐭',\n  }\n\n  maze.forEach((row) => {\n    let rowString = ''\n\n    row.forEach((cell) => {\n      rowString += items[cell] || items[0]\n    })\n\n    console.log(rowString)\n  })\n}\n\nfunction moveCharacter(dy, dx) {\n  let newY = character.y + dy\n  let newX = character.x + dx\n\n  if (maze[newY] && maze[newY][newX] !== 1 && maze[newY][newX] !== undefined) {\n    maze[character.y][character.x] = 0\n\n    character.x = newX\n    character.y = newY\n  }\n}\n\nconst move = {\n  up: () => moveCharacter(-1, 0),\n  down: () => moveCharacter(1, 0),\n  left: () => moveCharacter(0, -1),\n  right: () => moveCharacter(0, 1),\n}\n\nfunction isGoal() {\n  return character.y === door.y && character.x === door.x\n}\n\n//PARTE II: Implementación en terminal con manejo básico de entradas erróneas\n\nimport * as readline from 'readline/promises'\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout,\n})\n\nlet invalid = false\nlet [message1, message2] = ['\\nMueve a Mickey! ', '\\nOpcion no valida. A dónde se mueve Mickey? ']\n\nwhile (true) {\n  console.clear()\n  console.log('\\nAYUDA A MICKEY A ESCAPAR!\\n')\n\n  drawMaze()\n\n  if (isGoal()) {\n    console.log('\\nHas liberado a Mickey. ¡Prepárate para una demanda por copyright!\\n')\n\n    rl.close()\n    break\n  }\n\n  let message\n\n  if (invalid) {\n    message = message2\n    invalid = false\n  } else {\n    message = message1\n  }\n\n  console.log('\\n(w) Arriba. (s) Abajo. (a) Izquierda. (d) Derecha.\\n(x) Salir')\n  let answer = await rl.question(message)\n\n  if (answer === 'x') {\n    console.log('\\nSaliendo del programa...')\n\n    rl.close()\n    break\n  }\n\n  const movements = {\n    w: move.up,\n    s: move.down,\n    a: move.left,\n    d: move.right,\n  }\n\n  const action =\n    movements[answer.toLowerCase()] ||\n    function () {\n      invalid = true\n    }\n\n  action()\n}\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/javascript/adrs1166ma.js",
    "content": "/*\nEJERCICIO:\n¡Disney ha presentado un montón de novedades en su D23! \nPero... ¿Dónde está Mickey?\nMickey Mouse ha quedado atrapado en un laberinto mágico \ncreado por Maléfica.\nDesarrolla un programa para ayudarlo a escapar.\nRequisitos:\n1. El laberinto está formado por un cuadrado de 6x6 celdas.\n2. Los valores de las celdas serán:\n   - ⬜️ Vacío\n   - ⬛️ Obstáculo\n   - 🐭 Mickey\n   - 🚪 Salida\nAcciones:\n1. Crea una matriz que represente el laberinto (no hace falta\nque se genere de manera automática).\n2. Interactúa con el usuario por consola para preguntarle hacia\ndonde se tiene que desplazar (arriba, abajo, izquierda o derecha).\n3. Muestra la actualización del laberinto tras cada desplazamiento.\n4. Valida todos los movimientos, teniendo en cuenta los límites\ndel laberinto y los obstáculos. Notifica al usuario.\n5. Finaliza el programa cuando Mickey llegue a la salida.\n */\n// 🔥 SIMULADOR: ¡Ayuda a Mickey a escapar del laberinto mágico! 🔥\n\nconsole.log(\"🎩 ¡Bienvenido al laberinto mágico de Maléfica! 🎩\")\nconsole.log(\"🐭 Mickey necesita tu ayuda para encontrar la salida (🚪).\")\n\n// 1. Crear el laberinto\nconst laberinto = [\n    [\"⬜️\", \"⬛️\", \"⬜️\", \"⬜️\", \"⬛️\", \"⬜️\"],\n    [\"⬜️\", \"⬛️\", \"⬜️\", \"⬛️\", \"⬛️\", \"⬜️\"],\n    [\"🐭\", \"⬜️\", \"⬜️\", \"⬛️\", \"⬜️\", \"⬜️\"],\n    [\"⬛️\", \"⬛️\", \"⬜️\", \"⬛️\", \"⬜️\", \"⬛️\"],\n    [\"⬜️\", \"⬜️\", \"⬜️\", \"⬛️\", \"🚪\", \"⬛️\"],\n    [\"⬛️\", \"⬜️\", \"⬛️\", \"⬜️\", \"⬛️\", \"⬜️\"]\n];\n\n// Posición inicial de Mickey\nlet posicionMickey = { fila: 2, columna: 0 };\n\n// Función principal del programa\nfunction iniciarLaberinto() {\n    console.log(\"\\n--- LABERINTO INICIAL ---\");\n    mostrarLaberinto();\n\n    while (true) {\n        const direccion = prompt(\"¿Hacia dónde quieres mover a Mickey? (arriba/abajo/izquierda/derecha): \").toLowerCase();\n\n        // Validar dirección\n        if (![\"arriba\", \"abajo\", \"izquierda\", \"derecha\"].includes(direccion)) {\n            console.log(\"❌ Dirección no válida. Inténtalo de nuevo.\");\n            continue;\n        }\n\n        // Intentar mover a Mickey\n        const nuevaPosicion = calcularNuevaPosicion(posicionMickey, direccion);\n        if (!esMovimientoValido(nuevaPosicion)) {\n            console.log(\"❌ Movimiento inválido. Hay un obstáculo o estás fuera del laberinto.\");\n            continue;\n        }\n\n        // Actualizar posición de Mickey\n        laberinto[posicionMickey.fila][posicionMickey.columna] = \"⬜️\"; // Limpiar la posición anterior\n        posicionMickey = nuevaPosicion; // Actualizar posición\n        laberinto[posicionMickey.fila][posicionMickey.columna] = \"🐭\"; // Colocar a Mickey en la nueva posición\n\n        // Mostrar el laberinto actualizado\n        console.log(`\\n--- MOVIMIENTO HACIA ${direccion.toUpperCase()} ---`);\n        mostrarLaberinto();\n\n        // Verificar si Mickey llegó a la salida\n        if (laberinto[posicionMickey.fila][posicionMickey.columna] === \"🚪\") {\n            console.log(\"🎉 ¡Felicidades! Mickey ha encontrado la salida. 🚪🐭\");\n            break;\n        }\n    }\n}\n\n// Función para mostrar el laberinto\nfunction mostrarLaberinto() {\n    laberinto.forEach(fila => console.log(fila.join(\" \")));\n}\n\n// Función para calcular la nueva posición\nfunction calcularNuevaPosicion(posicionActual, direccion) {\n    const nuevaPosicion = { ...posicionActual };\n    switch (direccion) {\n        case \"arriba\":\n            nuevaPosicion.fila -= 1;\n            break;\n        case \"abajo\":\n            nuevaPosicion.fila += 1;\n            break;\n        case \"izquierda\":\n            nuevaPosicion.columna -= 1;\n            break;\n        case \"derecha\":\n            nuevaPosicion.columna += 1;\n            break;\n    }\n    return nuevaPosicion;\n}\n\n// Función para validar el movimiento\nfunction esMovimientoValido(posicion) {\n    const { fila, columna } = posicion;\n\n    // Verificar límites del laberinto\n    if (fila < 0 || fila >= laberinto.length || columna < 0 || columna >= laberinto[0].length) {\n        return false;\n    }\n\n    // Verificar obstáculos\n    if (laberinto[fila][columna] === \"⬛️\") {\n        return false;\n    }\n\n    return true;\n}\n\niniciarLaberinto()"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/javascript/duendeintemporal.js",
    "content": "#!/usr/bin/env node --encoding=utf8\n\n//#33 - RESCATANDO A MICKEY\n/*\n * EJERCICIO:\n * ¡Disney ha presentado un montón de novedades en su D23!\n * Pero... ¿Dónde está Mickey?\n * Mickey Mouse ha quedado atrapado en un laberinto mágico\n * creado por Maléfica.\n * Desarrolla un programa para ayudarlo a escapar.\n * Requisitos:\n * 1. El laberinto está formado por un cuadrado de 6x6 celdas.\n * 2. Los valores de las celdas serán:\n *    - ⬜️ Vacío\n *    - ⬛️ Obstáculo\n *    - 🐭 Mickey\n *    - 🚪 Salida\n * Acciones:\n * 1. Crea una matriz que represente el laberinto (no hace falta\n * que se genere de manera automática).\n * 2. Interactúa con el usuario por consola para preguntarle hacia\n * donde se tiene que desplazar (arriba, abajo, izquierda o derecha).\n * 3. Muestra la actualización del laberinto tras cada desplazamiento.\n * 4. Valida todos los movimientos, teniendo en cuenta los límites\n * del laberinto y los obtáculos. Notifica al usuario.\n * 5. Finaliza el programa cuando Mickey llegue a la salida.\n */\n\n/* \n⬜️ Empty: \\u{2B1C}\n⬛️ Obstacle: \\u{2B1B}\n🐭 Mickey: \\u{1F42D}\n🚪 Exit: \\u{1F6AA} */\n\n\n/*  \nNote: If you are using Command Prompt(cmd or Shell in Windows), you may need to change the code page to UTF-8 to properly display emojis. You can do this by running the following command before executing your script:\n\nchcp 65001\n\nAlso set the font type to: Segoe UI Emoji or Noto Color Emoji is available. (if this doesn't work you will need to install Windows Terminal to to properly display emojis)\n*/\n\nlet log = console.log;\n\nconst obstacle = '\\u2B1B'; // ⬛️ Obstacle\nconst emptySpace = '\\u2B1C'; // ⬜️ Empty space\nconst mickey = '\\u1F42D'; // 🐭 Mickey\nconst exit = '\\u1F6AA'; // 🚪 Exit\nconst path = '\\u1F40E'; // 🐊 Path\n\nconst readline = require('readline');\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nlet position = { x: 0, y: 0 }; // Start position for Mickey\n\n// Function to generate a random maze with obstacles\nfunction generateRandomMaze(size) {\n    const maze = Array.from({ length: size }, () => Array(size).fill(obstacle)); // ⬛️ Obstacle\n\n    for (let y = 0; y < size; y++) {\n        for (let x = 0; x < size; x++) {\n            // Randomly decide to place an obstacle or leave it empty\n            maze[y][x] = Math.random() < 0.4 ? obstacle : emptySpace; // 40% chance to be an obstacle\n        }\n    }\n\n    // Ensure the start and exit positions are setted correctly\n    maze[0][0] = mickey; // Start position\n    maze[size - 1][size - 1] = exit; // Exit position\n\n    return maze;\n}\n\n// Function to carve a path in the maze using Dijkstra's algorithm\nfunction dijkstra(maze, recursive = false) {\n    const size = maze.length;\n    const directions = [\n        { x: -1, y: 0 }, // up\n        { x: 1, y: 0 },  // down\n        { x: 0, y: -1 }, // left\n        { x: 0, y: 1 }   // right\n    ];\n\n    const distances = Array.from({ length: size }, () => Array(size).fill(Infinity));\n    const previous = Array.from({ length: size }, () => Array(size).fill(null));\n\n    distances[0][0] = 0; // Distance from the entrance is 0\n\n    const queue = [{ x: 0, y: 0, distance: 0 }];\n\n    while (queue.length > 0) {\n        const { x, y, distance } = queue.shift();\n\n        if (distance > distances[y][x]) {\n            continue; // If the distance is greater than the current distance, do nothing\n        }\n\n        for (const { x: dx, y: dy } of directions) {\n            const newX = x + dx;\n            const newY = y + dy;\n\n            if (newX >= 0 && newX < size && newY >= 0 && newY < size) {\n                const newDistance = distance + (maze[newY][newX] === obstacle ? 10 : 1); // If it's an obstacle, add 10 to the distance\n\n                if (newDistance < distances[newY][newX]) {\n                    distances[newY][newX] = newDistance;\n                    previous[newY][newX] = { x, y };\n                    queue.push({ x: newX, y: newY, distance: newDistance });\n                }\n            }\n        }\n    }\n\n    // Reconstruct the shortest path\n    const path = [];\n    let x = size - 1;\n    let y = size - 1;\n\n    while (x !== 0 || y !== 0) {\n        if (previous[y][x] === null) {\n            break; // No valid path found\n        }\n        path.push({ x, y });\n        const prev = previous[y][x];\n        x = prev.x;\n        y = prev.y;\n    }\n    path.reverse(); // Reverse the path to get it from start to exit\n\n    // If a path is found, mark it\n    if (path.length > 0) {\n        for (const { x, y } of path) {\n            maze[y][x] = emptySpace; // Mark the path with an empty space\n        }\n    }\n\n    maze[size - 1][size - 1] = exit; // ensure exit is not over writing\n    return path;\n}\n\n// Function to display the maze\nfunction displayMaze(maze) {\n    console.log('\\nMaze:\\n');\n    maze.forEach(row => {\n        console.log(row.join(' '));\n    });\n    console.log('\\n');\n}\n\n// Function to move Mickey\nfunction moveMickey(dir, maze) {\n    const newPosition = { ...position };\n    \n    // Update new position based on the direction\n    if (dir === \"w\") newPosition.y -= 1; // up\n    if (dir === \"s\") newPosition.y += 1; // down\n    if (dir === \"a\") newPosition.x -= 1; // left\n    if (dir === \"d\") newPosition.x += 1; // right\n    \n    // Check if the new position is within the bounds of the board\n    if (\n        newPosition.x >= 0 &&\n        newPosition.x < maze[0].length &&\n        newPosition.y >= 0 &&\n        newPosition.y < maze.length\n    ) {\n        // Check if the new position is a wall or path\n        if (maze[newPosition.y][newPosition.x] === obstacle) {\n            console.log(`Mickey 🐭 has hit a wall ⬛️, try moving in another direction.`);\n            return false; // Movement failed due to wall\n        } else {\n            // Check if the new position is the exit\n            if (maze[newPosition.y][newPosition.x] === exit) {\n                log('\\n');\n                console.log(\"Congratulations! You won! Mickey 🐭 has escaped the maze.\");\n                maze[position.y][position.x] = emptySpace; // empty the cell\n                position = newPosition;\n                maze[position.y][position.x] = mickey; // move 🐭 Mickey \n                rl.close(); // Close the readline interface\n                return true; // Movement successful and game won\n            }\n            // Update the position of the player\n            maze[position.y][position.x] = emptySpace; // empty the cell\n            position = newPosition;\n            maze[position.y][position.x] = mickey; // move 🐭 Mickey \n            \n            return true; // Movement successful\n        }\n    } else {\n        console.log(`Mickey 🐭 cannot move outside the maze, try moving in another direction.`);\n        return false; // Movement failed due to out of bounds\n    }\n}\n\n// Prompt user for maze size\nrl.question('Enter the size of the maze (between 7 and 15): ', (input) => {\n    const mazeSize = parseInt(input);\n    \n    // Validate the maze size input\n    if (isNaN(mazeSize) || mazeSize < 7 || mazeSize > 15) {\n        console.log('Please enter a valid number between 7 and 15.');\n        rl.close();\n        return;\n    }\n    \n    // Generate the random maze\n    const maze = generateRandomMaze(mazeSize);\n    \n    // Carve a path in the maze using Dijkstra's algorithm\n    const path = dijkstra(maze);\n    \n    // Display the generated maze\n     displayMaze(maze);\n\n    // Start the game loop\n    function startGame() {\n        rl.question(\"Choose a direction to move (up - w, down - s, left - a, right - d): \", (answer) => {\n            const moveSuccessful = moveMickey(answer.toLowerCase(), maze);\n            displayMaze(maze); // Display the maze after the move\n        \n            // If the move was successful and Mickey has not reached the exit\n            if (moveSuccessful) {\n                // No need to call startGame() again if Mickey has reached the exit\n                if (maze[position.y][position.x] !== maze[maze.length -1][maze.length -1]) {\n                    startGame(); // Continue the game\n                }\n                // If Mickey has reached the exit, the message will be displayed in moveMickey\n            } else {\n                startGame(); // Retry if the move was not successful\n            }\n        });\n    }\n        startGame(); // Start the game\n});\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/javascript/hectorio23.js",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\nconst readline = require('readline');\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\n// Definición inicial del laberinto\nconst labyrinth = [\n    ['⬜️', '⬜️', '⬜️', '⬛️', '⬛️', '⬛️'],\n    ['⬛️', '⬛️', '⬜️', '⬛️', '🚪', '⬛️'],\n    ['⬛️', '⬛️', '⬜️', '⬛️', '⬜️', '⬛️'],\n    ['⬛️', '⬛️', '⬜️', '⬜️', '⬜️', '⬛️'],\n    ['⬛️', '⬛️', '⬜️', '⬛️', '⬛️', '⬛️'],\n    ['🐭', '⬜️', '⬜️', '⬛️', '⬛️', '⬛️']\n];\n\nlet mickeyX = 5, mickeyY = 0; // Posición inicial de Mickey\nlet escaped = false;\n\n// Imprime el estado actual del laberinto\nfunction printLabyrinth() {\n    labyrinth.forEach(row => {\n        console.log(row.join(' '));\n    });\n    console.log();\n}\n\n// Mueve a Mickey a una nueva posición y valida el movimiento\nfunction moveMickey(newX, newY) {\n    // Validación de límites del laberinto\n    if (newX < 0 || newX >= 6 || newY < 0 || newY >= 6) {\n        console.log(\"Movimiento inválido, fuera de los límites del laberinto.\");\n        return false;\n    }\n    // Validación de obstáculos\n    if (labyrinth[newX][newY] === '⬛️') {\n        console.log(\"Movimiento inválido, obstáculo en el camino.\");\n        return false;\n    }\n\n    // Actualiza la posición de Mickey\n    labyrinth[mickeyX][mickeyY] = '⬜️'; // Limpia la posición anterior\n    mickeyX = newX;\n    mickeyY = newY;\n\n    // Verificación si Mickey ha llegado a la salida\n    if (labyrinth[mickeyX][mickeyY] === '🚪') {\n        console.log(\"¡Mickey ha escapado!\");\n        return true;\n    }\n\n    labyrinth[mickeyX][mickeyY] = '🐭'; // Actualiza la posición de Mickey\n    return false;\n}\n\n// Solicita al usuario que introduzca una dirección y procesa el movimiento\nfunction askDirection() {\n    \n    console.clear();\n\n    printLabyrinth(); // Muestra el estado actual del laberinto\n    rl.question('Introduce dirección (arriba, abajo, izquierda, derecha): ', (direction) => {\n        let newX = mickeyX, newY = mickeyY;\n\n        // Determina la nueva posición basada en la dirección ingresada\n        if (direction === \"arriba\") newX--;\n        else if (direction === \"abajo\") newX++;\n        else if (direction === \"izquierda\") newY--;\n        else if (direction === \"derecha\") newY++;\n        else console.log(\"Dirección inválida. Intenta nuevamente.\");\n\n        // Intenta mover a Mickey si no ha escapado todavía\n        if (!escaped) escaped = moveMickey(newX, newY);\n\n        // Si Mickey no ha escapado, pide otra dirección\n        if (!escaped) askDirection();\n        else rl.close(); // Cierra la interfaz si Mickey ha escapado\n    });\n}\n\naskDirection(); // Inicia el ciclo de interacción con el usuario\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n_______________________________________________________\n#33 * RESCATANDO A MICKEY\n-------------------------------------------------------\n* EJERCICIO:\n * ¡Disney ha presentado un montón de novedades en su D23! \n * Pero... ¿Dónde está Mickey?\n * Mickey Mouse ha quedado atrapado en un laberinto mágico \n * creado por Maléfica.\n * Desarrolla un programa para ayudarlo a escapar.\n * Requisitos:\n * 1. El laberinto está formado por un cuadrado de 6x6 celdas.\n * 2. Los valores de las celdas serán:\n *    - ⬜️ Vacío\n *    - ⬛️ Obstáculo\n *    - 🐭 Mickey\n *    - 🚪 Salida\n * Acciones:\n * 1. Crea una matriz que represente el laberinto (no hace falta\n * que se genere de manera automática).\n * 2. Interactúa con el usuario por consola para preguntarle hacia\n * donde se tiene que desplazar (arriba, abajo, izquierda o derecha).\n * 3. Muestra la actualización del laberinto tras cada desplazamiento.\n * 4. Valida todos los movimientos, teniendo en cuenta los límites\n * del laberinto y los obtáculos. Notifica al usuario.\n * 5. Finaliza el programa cuando Mickey llegue a la salida.\n*/\n// ________________________________________________________\n\nconst readline = require('readline');\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nconst getInput = async (prompt) => {\n    return new Promise((resolve) => {\n        rl.question(prompt, (input) => {\n            resolve(input.toLowerCase());\n        });\n    });\n};\n\nclass Data {\n    constructor(config) {\n        this._config = config;\n        this._maze = [];\n        this._position = [0, 0];\n        this._exit = [0, 0];\n    }\n\n    printMaze() {\n        console.log(\"--------------------------------------\");\n        this._maze.forEach(row => {\n            console.log(row.join(''));\n        });\n        console.log(\"--------------------------------------\");\n    }\n}\n\nclass Moves extends Data {\n    constructor(config) {\n        super(config);\n    }\n\n    _canMove(y, x) {\n        const size = this._maze.length;\n        if (y < 0 || x < 0 || y >= size || x >= size) {\n            console.log(\"🚨I can't jump over the edges.🚨\");\n            return false;\n        }\n\n        if (this._maze[y][x] === this._config.obstacle) {\n            console.log(\"🚨You pushed me against the wall.🚨\");\n            return false;\n        }\n\n        this._position = [y, x];\n        console.log(\"✅Correct move.✅\");\n        this._maze[y][x] = this._config.mouse;\n        return true;\n    }\n\n    up() {\n        const [y, x] = this._position;\n        if (!this._canMove(y - 1, x)) return;\n        this._maze[y][x] = this._config.empty;\n    }\n\n    down() {\n        const [y, x] = this._position;\n        if (!this._canMove(y + 1, x)) return;\n        this._maze[y][x] = this._config.empty;\n    }\n\n    right() {\n        const [y, x] = this._position;\n        if (!this._canMove(y, x + 1)) return;\n        this._maze[y][x] = this._config.empty;\n    }\n\n    left() {\n        const [y, x] = this._position;\n        if (!this._canMove(y, x - 1)) return;\n        this._maze[y][x] = this._config.empty;\n    }\n}\n\nclass Maze extends Moves {\n    constructor(config) {\n        super(config);\n    }\n\n    _createPaths(x, y, width, height) {\n        const maze = this._maze;\n        const { obstacle, empty } = this._config;\n\n        maze[y][x] = empty;\n        const directions = [[0, 1], [1, 0], [0, -1], [-1, 0]];\n        this._shuffleArray(directions);\n\n        directions.forEach(([dx, dy]) => {\n            const nx = x + dx * 2;\n            const ny = y + dy * 2;\n            if (0 < nx && nx < width - 1 && 0 < ny && ny < height - 1 && maze[ny][nx] === obstacle) {\n                maze[y + dy][x + dx] = empty;\n                this._createPaths(nx, ny, width, height);\n            }\n        });\n    }\n\n    _shuffleArray(array) {\n        for (let i = array.length - 1; i > 0; i--) {\n            const j = Math.floor(Math.random() * (i + 1));\n            [array[i], array[j]] = [array[j], array[i]];\n        }\n    }\n\n    create() {\n        let [width, height] = this._config.size;\n        const { obstacle, mouse, exit } = this._config;\n\n        if (width % 2 === 0) width += 1;\n        if (height % 2 === 0) height += 1;\n\n        this._maze = Array(height).fill().map(() => Array(width).fill(obstacle));\n\n        const initialX = 1 + 2 * Math.floor(Math.random() * ((width - 1) / 2));\n        const initialY = 1 + 2 * Math.floor(Math.random() * ((height - 1) / 2));\n        this._createPaths(initialX, initialY, width, height);\n\n        this._maze[0][1] = mouse;\n        this._maze[height - 1][width - 2] = exit;\n        this._position = [0, 1];\n        this._exit = [height - 1, width - 2];\n    }\n\n    verifyWin() {\n        const [y, x] = this._exit;\n        return this._maze[y][x] === this._config.mouse;\n    }\n}\n\nclass Game {\n    constructor(config, instanceMaze) {\n        this._config = config;\n        this._maze = instanceMaze;\n    }\n\n    async _restartOrExit() {\n        while (true) {\n            const option = await getInput(\"Y/N: \");\n            switch (option) {\n                case 'y': return true;\n                case 'n': return false;\n                default: console.log(\"❌Invalid key.❌\");\n            }\n        }\n    }\n\n    async play() {\n        Object.entries(this._config).forEach(([k, v]) => {\n            console.log(`${k}: ${v}`);\n        });\n\n        this._maze.create();\n        while (true) {\n            this._maze.printMaze();\n            console.log(\"Use the keys: (W, S, A, D).\\nTo restart: R. To exit: 9.\");\n            const option = await getInput(\"\\nKey: \");\n\n            switch (option) {\n                case 'w': this._maze.up(); break;\n                case 's': this._maze.down(); break;\n                case 'd': this._maze.right(); break;\n                case 'a': this._maze.left(); break;\n                case 'r':\n                    console.log(\"😮Do you want to restart?😮\");\n                    if (await this._restartOrExit()) {\n                        this._maze.create();\n                    }\n                    break;\n                case '9':\n                    console.log(\"😮Do you want to exit?😮\");\n                    if (await this._restartOrExit()) {\n                        rl.close();\n                        return;\n                    }\n                    break;\n                default: console.log(\"❌Invalid key.❌\");\n            }\n\n            if (this._maze.verifyWin()) {\n                console.log(\"🏆Congratulations, you managed to get me out.🏆\");\n                console.log(\"🤔Do you want to play again?🤔\");\n                if (await this._restartOrExit()) {\n                    this._maze.create();\n                } else {\n                    console.log(\"Bye\");\n                    rl.close();\n                    return;\n                }\n            }\n        }\n    }\n}\n\nconst config = {\n    title: \"RESCUING MICKEY\",\n    size: [6, 6],\n    empty: \"⬜️\",\n    obstacle: \"⬛️\",\n    mouse: \"🐭\",\n    exit: \"🚪\"\n};\n\nconst maze = new Maze(config);\nconst game = new Game(config, maze);\ngame.play().catch(console.error);\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/javascript/nlarrea.js",
    "content": "/*\n * EJERCICIO:\n * ¡Disney ha presentado un montón de novedades en su D23!\n * Pero... ¿Dónde está Mickey?\n * Mickey Mouse ha quedado atrapado en un laberinto mágico\n * creado por Maléfica.\n * Desarrolla un programa para ayudarlo a escapar.\n * Requisitos:\n * 1. El laberinto está formado por un cuadrado de 6x6 celdas.\n * 2. Los valores de las celdas serán:\n *    - ⬜️ Vacío\n *    - ⬛️ Obstáculo\n *    - 🐭 Mickey\n *    - 🚪 Salida\n * Acciones:\n * 1. Crea una matriz que represente el laberinto (no hace falta\n * que se genere de manera automática).\n * 2. Interactúa con el usuario por consola para preguntarle hacia\n * donde se tiene que desplazar (arriba, abajo, izquierda o derecha).\n * 3. Muestra la actualización del laberinto tras cada desplazamiento.\n * 4. Valida todos los movimientos, teniendo en cuenta los límites\n * del laberinto y los obstáculos. Notifica al usuario.\n * 5. Finaliza el programa cuando Mickey llegue a la salida.\n */\n\nconst readline = require('readline');\n\nconst rl = readline.createInterface({\n\tinput: process.stdin,\n\toutput: process.stdout,\n});\n\nconst EMPTY = '⬜️';\nconst PLAYER = '🐭';\nconst EXIT = '🚪';\nconst OBSTACLE = '⬛️';\n\nconst maze = [\n\t[PLAYER, OBSTACLE, OBSTACLE, OBSTACLE, OBSTACLE, OBSTACLE],\n\t[EMPTY, OBSTACLE, OBSTACLE, OBSTACLE, EMPTY, OBSTACLE],\n\t[EMPTY, OBSTACLE, OBSTACLE, OBSTACLE, EMPTY, OBSTACLE],\n\t[EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY],\n\t[OBSTACLE, EMPTY, OBSTACLE, EMPTY, OBSTACLE, OBSTACLE],\n\t[OBSTACLE, EMPTY, OBSTACLE, EMPTY, EMPTY, EXIT],\n];\n\nconst actions = {\n\tup: 'w',\n\tdown: 's',\n\tleft: 'a',\n\tright: 'd',\n\texit: 'q',\n};\n\nclass Position {\n\t#maxRow;\n\t#maxCol;\n\n\tconstructor(row, col, maxRow, maxCol) {\n\t\tthis.row = row;\n\t\tthis.col = col;\n\t\tthis.#maxRow = maxRow;\n\t\tthis.#maxCol = maxCol;\n\t}\n\n\tequals(other) {\n\t\tif (other instanceof Position) {\n\t\t\treturn this.row === other.row && this.col === other.col;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\thashCode(other) {\n\t\treturn `${this.row} ${this.col}`.hashCode();\n\t}\n\n\tmove(direction) {\n\t\tif (direction === actions.up) {\n\t\t\tif (this.row > 0) {\n\t\t\t\tthis.row--;\n\t\t\t}\n\t\t} else if (direction === actions.down) {\n\t\t\tif (this.row < this.#maxRow) {\n\t\t\t\tthis.row++;\n\t\t\t}\n\t\t} else if (direction === actions.left) {\n\t\t\tif (this.col > 0) {\n\t\t\t\tthis.col--;\n\t\t\t}\n\t\t} else if (direction === actions.right) {\n\t\t\tif (this.col < this.#maxCol) {\n\t\t\t\tthis.col++;\n\t\t\t}\n\t\t} else {\n\t\t\tconsole.log(`La dirección '${direction}' no es posible.`);\n\t\t}\n\t}\n}\n\nfunction getPosition(maze, item) {\n\tfor (const row in maze) {\n\t\tfor (const col in maze[row]) {\n\t\t\tif (maze[row][col] === item) {\n\t\t\t\treturn new Position(\n\t\t\t\t\tparseInt(row),\n\t\t\t\t\tparseInt(col),\n\t\t\t\t\tmaze.length,\n\t\t\t\t\tmaze[parseInt(row)].length\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction printOptions() {\n\tconsole.log('Movimientos posibles:');\n\tfor (const action in actions) {\n\t\tconsole.log(` [${actions[action]}]: ${action}`);\n\t}\n}\n\nfunction printMaze(maze) {\n\tconsole.log();\n\tfor (const row of maze) {\n\t\tconsole.log(row.join(''));\n\t}\n\tconsole.log();\n}\n\nfunction updateMaze(maze, newPosition) {\n\tconst oldPlayerPos = getPosition(maze, PLAYER);\n\n\tmaze[oldPlayerPos.row][oldPlayerPos.col] = EMPTY;\n\tmaze[newPosition.row][newPosition.col] = PLAYER;\n\n\treturn maze;\n}\n\nfunction getAvailableActions(maze, position) {\n\tconst available = [EMPTY, EXIT];\n\tconst acts = [];\n\n\t// Up\n\tif (\n\t\tposition.row > 0 &&\n\t\tavailable.includes(maze[position.row - 1][position.col])\n\t) {\n\t\tacts.push(actions.up);\n\t}\n\n\t// Down\n\tif (\n\t\tposition.row < maze.length - 1 &&\n\t\tavailable.includes(maze[position.row + 1][position.col])\n\t) {\n\t\tacts.push(actions.down);\n\t}\n\n\t// Left\n\tif (\n\t\tposition.col > 0 &&\n\t\tavailable.includes(maze[position.row][position.col - 1])\n\t) {\n\t\tacts.push(actions.left);\n\t}\n\n\t// Right\n\tif (\n\t\tposition.col < maze.length - 1 &&\n\t\tavailable.includes(maze[position.row][position.col + 1])\n\t) {\n\t\tacts.push(actions.right);\n\t}\n\n\treturn acts;\n}\n\nfunction run(maze) {\n\tconst exitPosition = getPosition(maze, EXIT);\n\tconst playerPos = getPosition(maze, PLAYER);\n\n\tprintMaze(maze);\n\tprintOptions();\n\trl.question('Selecciona qué hacer:\\n > ', (selected) => {\n\t\tif (selected.toLowerCase() === actions.exit) {\n\t\t\trl.close();\n\t\t\treturn;\n\t\t} else if (!Object.values(actions).includes(selected.toLowerCase())) {\n\t\t\tconsole.log(\n\t\t\t\t'\\nDebes introducir una de las siguientes letras:',\n\t\t\t\tObject.values(actions).join(', ')\n\t\t\t);\n\t\t} else if (\n\t\t\t!getAvailableActions(maze, playerPos).includes(\n\t\t\t\tselected.toLowerCase()\n\t\t\t)\n\t\t) {\n\t\t\tconsole.log('\\nLa acción introducida no es posible.');\n\t\t} else {\n\t\t\tplayerPos.move(selected);\n\t\t\tmaze = updateMaze(maze, playerPos);\n\n\t\t\tif (\n\t\t\t\tplayerPos.row === exitPosition.row &&\n\t\t\t\tplayerPos.col === exitPosition.col\n\t\t\t) {\n\t\t\t\tprintMaze(maze);\n\t\t\t\tconsole.log('\\n\\n¡HAS ENCONTRADO LA SALIDA!');\n\t\t\t\trl.close();\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\trun(maze);\n\t\treturn;\n\t});\n}\n\nrun(maze);\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/javascript/pedamoci.js",
    "content": "import readline from \"readline\";\n\nconst colors = {\n  red: \"\\x1b[31m\",\n  green: \"\\x1b[32m\",\n  yellow: \"\\x1b[33m\",\n  cyan: \"\\x1b[34m\",\n  reset: \"\\x1b[0m\",\n}\n\nclass Asks {\n  constructor() {\n    this.rl = readline.createInterface({\n      input: process.stdin,\n      output: process.stdout,\n    });\n  }\n\n  ask(question) {\n    return new Promise((resolve) => {\n      this.rl.question(question, (answer) => resolve(answer));\n    });\n  }\n\n  close() {\n    this.rl.close();\n  }\n}\n\nconst asks = new Asks()\n\nfunction createPath() {\n  let start = [Math.round(Math.random() * 5), 0]\n  let visited = [start]\n  const path = new Set([`${start[0]},${start[1]}`])\n  let resetLimit = 40\n\n  while (visited[visited.length - 1][1] !== 5 && resetLimit > 0) {\n    const MOVES = [\n      [1, 0],\n      [-1, 0],\n      [0, 1],\n      [0, -1]\n    ]\n\n    const [y, x] = visited[visited.length - 1]\n\n    const move = MOVES[Math.floor(Math.random() * 4)]\n\n    const nx = x + move[1]\n    const ny = y + move[0]\n\n    const newMove = `${ny},${nx}`;\n\n    const isInside = ny >= 0 && ny < 6 && nx >= 0 && nx < 6;\n\n    if (isInside && !path.has(newMove)) {\n      visited.push([ny, nx])\n      path.add(newMove)\n    }\n\n    resetLimit--\n  }\n\n  if (resetLimit === 0) {\n    console.log(colors.yellow + 'Resetting path creation...' + colors.reset)\n    return createPath()\n  }\n  return path\n}\n\nfunction createMaze(path) {\n  const maze = []\n  let row = []\n\n  for (let i = 0, j = 0; i < 6; j++) {\n    if (path.has(`${i},${j}`)) {\n      row.push(0)\n    }\n    else row.push(1)\n\n    if (j === 5) {\n      maze.push(row)\n      i++\n      j = -1\n      row = []\n    }\n  }\n\n  return maze\n}\n\nfunction prettyMaze(maze, mickey) {\n  return new Promise((resolve) => {\n    const viewMaze = maze.map((column, indexRow) => {\n      return column.map((cell, indexColumn) => {\n        if (indexRow === mickey[0] && indexColumn === mickey[1]) {\n          return '🐭'\n        }\n        else if (cell === 0) {\n          if (indexColumn === 5) return '🚪'\n          else return '⬜️'\n        }\n        else if (cell === 1) {\n          return '⬛️'\n        }\n      })\n    })\n\n    console.log(viewMaze.join('\\n').replaceAll(',', ' '))\n  resolve()\n  })\n}\n\nfunction checkMove({ move, mickey, maze }) {\n  let [y, x] = mickey\n\n  if (move === 'w' && y > 0 && maze[y-1][x] === 0) return [y-1, x]\n  if (move === 's' && y < 5 && maze[y+1][x] === 0) return [y+1, x]\n  if (move === 'a' && x > 0 && maze[y][x-1] === 0) return [y, x-1]\n  if (move === 'd' && x < 5 && maze[y][x+1] === 0) return [y, x+1]\n\n  console.log(colors.red + \"Invalid move!\" + colors.reset)\n  return mickey\n}\n\nfunction checkWin(mickey) {\n  if (mickey[1] === 5) {\n    console.log(colors.green + '\\n🎉🎊 YOU WIN! Mickey has been rescued! 🎊🎉' + colors.reset)\n  }\n}\n\nasync function start() {\n  const maze = createMaze(createPath())\n\n  const startPosition = [maze.findIndex(row => row[0] === 0), 0]\n  let mickey = startPosition\n\n  while (mickey[1] !== 5) {\n    console.log(colors.cyan + '\\nCurrent Maze:' + colors.reset)\n\n    await prettyMaze(maze, mickey)\n\n    const move = (await asks.ask(colors.cyan + '\\nEnter your move (w/a/s/d): ' + colors.reset)).toLowerCase()\n\n    mickey = checkMove({ move, mickey, maze })\n\n    checkWin(mickey)\n  }\n\n  asks.close()\n}\n\nstart()\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/javascript/redom69.js",
    "content": "/*\n * EJERCICIO:\n * ¡Disney ha presentado un montón de novedades en su D23! \n * Pero... ¿Dónde está Mickey?\n * Mickey Mouse ha quedado atrapado en un laberinto mágico \n * creado por Maléfica.\n * Desarrolla un programa para ayudarlo a escapar.\n * Requisitos:\n * 1. El laberinto está formado por un cuadrado de 6x6 celdas.\n * 2. Los valores de las celdas serán:\n *    - ⬜️ Vacío\n *    - ⬛️ Obstáculo\n *    - 🐭 Mickey\n *    - 🚪 Salida\n * Acciones:\n * 1. Crea una matriz que represente el laberinto (no hace falta\n * que se genere de manera automática).\n * 2. Interactúa con el usuario por consola para preguntarle hacia\n * donde se tiene que desplazar (arriba, abajo, izquierda o derecha).\n * 3. Muestra la actualización del laberinto tras cada desplazamiento.\n * 4. Valida todos los movimientos, teniendo en cuenta los límites\n * del laberinto y los obtáculos. Notifica al usuario.\n * 5. Finaliza el programa cuando Mickey llegue a la salida.\n */\n\nconst readline = require('readline');\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\n// Constantes\nconst VACIO = \"⬜️\";\nconst OBSTACULO = \"⬛️\";\nconst MICKEY = \"🐭\";\nconst SALIDA = \"🚪\";\n\nfunction generateMaze(width, height, total = 10) {\n    let maze = Array.from({ length: height }, () =>\n        Array.from({ length: width }, () => VACIO)\n    );\n\n    let mickeyPos = [\n        Math.floor(Math.random() * height),\n        Math.floor(Math.random() * width)\n    ];\n    maze[mickeyPos[0]][mickeyPos[1]] = MICKEY;\n\n    let end;\n    while (true) {\n        end = [\n            Math.floor(Math.random() * height),\n            Math.floor(Math.random() * width)\n        ];\n        if (end[0] !== mickeyPos[0] || end[1] !== mickeyPos[1]) {\n            maze[end[0]][end[1]] = SALIDA;\n            break;\n        }\n    }\n\n    let obstacles = 0;\n    while (obstacles < total) {\n        let obstaclesPos = [\n            Math.floor(Math.random() * height),\n            Math.floor(Math.random() * width)\n        ];\n        if (maze[obstaclesPos[0]][obstaclesPos[1]] === VACIO) {\n            maze[obstaclesPos[0]][obstaclesPos[1]] = OBSTACULO;\n            obstacles++;\n        }\n    }\n\n    return { maze, mickeyPos, end };\n}\n\nfunction showMaze(maze) {\n    return maze.map(row => row.join(' ')).join('\\n');\n}\n\nfunction isValid(newMove, maze) {\n    const [x, y] = newMove;\n    const withinBounds = x >= 0 && x < maze.length && y >= 0 && y < maze[0].length;\n    const notAnObstacle = withinBounds && maze[x][y] !== OBSTACULO;\n    return withinBounds && notAnObstacle;\n}\n\nfunction moveMickey(maze, mickeyPos, move) {\n    const [x, y] = mickeyPos;\n    let newMove = [];\n\n    switch (move) {\n        case 'w':\n            newMove = [x - 1, y];\n            break;\n        case 's':\n            newMove = [x + 1, y];\n            break;\n        case 'a':\n            newMove = [x, y - 1];\n            break;\n        case 'd':\n            newMove = [x, y + 1];\n            break;\n        default:\n            return mickeyPos;\n    }\n\n    if (isValid(newMove, maze)) {\n        maze[x][y] = VACIO;\n        mickeyPos = newMove;\n        maze[newMove[0]][newMove[1]] = MICKEY;\n    } \n\n    return mickeyPos;\n}\n\nlet { maze, mickeyPos, end } = generateMaze(6, 6, 10);\n\n\nfunction gameLoop() {\n    console.log(showMaze(maze));\n\n    rl.question(\"Mueve a Mickey (w/a/s/d): \", (move) => {\n        mickeyPos = moveMickey(maze, mickeyPos, move.toLowerCase());\n\n        if (mickeyPos[0] === end[0] && mickeyPos[1] === end[1]) {\n            console.log(showMaze(maze));\n            console.log(\"¡Mickey ha llegado a la salida!\", MICKEY);\n            rl.close();\n        } else {\n            gameLoop();\n        }\n    });\n}\n\ngameLoop(); \n\n\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/javascript/victor-Casta.js",
    "content": "const readline = require('node:readline')\nconst { stdin: input, stdout: output } = require('node:process')\nconst rl = readline.createInterface({ input, output })\n\nconst WALL = '⬛️'\nconst PATH = '⬜️'\nconst MOUSE = '🐭'\nconst END = '🚪'\n\nconst maze = [\n  [MOUSE, WALL, WALL, WALL, PATH, WALL],\n  [PATH, PATH, PATH, PATH, PATH, WALL],\n  [WALL, PATH, PATH, WALL, PATH, WALL],\n  [PATH, WALL, PATH, WALL, WALL, WALL],\n  [PATH, PATH, PATH, PATH, PATH, PATH],\n  [PATH, WALL, WALL, PATH, WALL, END],\n]\n\nfunction printMaze(maze) {\n  maze.forEach(row => {\n    console.log(row.join(' '))\n  })\n}\n\nfunction findMouse() {\n  let position = undefined\n  for (let row = 0; row < maze.length; row++) {\n    const col = maze[row].findIndex(value => value === MOUSE)\n    if (col !== -1) {\n      position = { row, col }\n      break\n    }\n  }\n  return position\n}\n\nfunction moveToRight(mousePosition) {\n  const row = mousePosition.row\n  const col = mousePosition.col\n\n  if (col + 1 >= maze[row].length || maze[row][col + 1] === WALL) {\n    console.log('No se puede mover a la derecha: fuera de los límites o hay un muro')\n    return false\n  }\n\n  if (maze[row][col + 1] === END) {\n    console.log('¡Has llegado al final!')\n    return true\n  }\n\n  maze[row][col] = PATH\n  maze[row][col + 1] = MOUSE\n  mousePosition.col++\n  console.log('Ratón movido a la derecha')\n  return false\n}\n\nfunction moveToLeft(mousePosition) {\n  const row = mousePosition.row\n  const col = mousePosition.col\n\n  if (col - 1 < 0 || maze[row][col - 1] === WALL) {\n    console.log('No se puede mover a la izquierda: fuera de los límites o hay un muro')\n    return false\n  }\n\n  maze[row][col] = PATH\n  maze[row][col - 1] = MOUSE\n  mousePosition.col--\n  console.log('Ratón movido a la izquierda')\n  return false\n}\n\nfunction moveToDown(mousePosition) {\n  const row = mousePosition.row\n  const col = mousePosition.col\n\n  if (row + 1 >= maze.length || maze[row + 1][col] === WALL) {\n    console.log('No se puede mover hacia abajo: fuera de los límites o hay un muro')\n    return false\n  }\n\n  if (maze[row + 1][col] === END) {\n    console.log('¡Has llegado al final!')\n    return true\n  }\n\n  maze[row][col] = PATH\n  maze[row + 1][col] = MOUSE\n  mousePosition.row++\n  console.log('Ratón movido hacia abajo')\n  return false\n}\n\nfunction moveToUp(mousePosition) {\n  const row = mousePosition.row\n  const col = mousePosition.col\n\n  if (row - 1 < 0 || maze[row - 1][col] === WALL) {\n    console.log('No se puede mover hacia arriba: fuera de los límites o hay un muro')\n    return false\n  }\n\n  maze[row][col] = PATH\n  maze[row - 1][col] = MOUSE\n  mousePosition.row--\n  console.log('Ratón movido hacia arriba')\n  return false\n}\n\nlet mousePosition = findMouse()\n\nfunction program() {\n  printMaze(maze)\n  console.log('1. mover arriba')\n  console.log('2. mover abajo')\n  console.log('3. mover izquierda')\n  console.log('4. mover derecha')\n  console.log('0. salir')\n\n  rl.question('Ingresa una opción: ', (answer) => {\n    let isEnd = false\n    switch (answer) {\n      case '1':\n        isEnd = moveToUp(mousePosition)\n        break\n      case '2':\n        isEnd = moveToDown(mousePosition)\n        break\n      case '3':\n        isEnd = moveToLeft(mousePosition)\n        break\n      case '4':\n        isEnd = moveToRight(mousePosition)\n        break\n      case '0':\n        rl.close()\n        return\n      default:\n        console.log('Opción inválida')\n        program()\n        return\n    }\n\n    if (isEnd) {\n      rl.close()\n    } else {\n      program()\n    }\n  })\n}\n\nprogram()"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/kotlin/blackriper.kt",
    "content": "\r\n//1.-Declaracion de varibles auxiliares e interfaces\r\ntypealias ObstacleList=MutableList<Pair<Int,Int>>\r\n\r\ninterface Drawable{\r\n    fun drawLaberit(mickeyLoc:Pair<Int,Int>)\r\n    fun searchObstacle(location:Pair<Int,Int>):Boolean\r\n}\r\n\r\ninterface Move{\r\n    fun moveMickey(y: Int,x: Int):Pair<Int,Int>\r\n    fun mickeyIsFree(mickeyPosition: Pair<Int, Int>):Boolean\r\n}\r\n\r\n//2.-implementar clases y interfaces\r\n\r\nclass DrawableLaberit:Drawable{\r\n    private  var laberit: String=\"\"\r\n    private var listObstacle:ObstacleList = mutableListOf()\r\n    private var completed=false\r\n\r\n    override fun drawLaberit(mickeyLoc: Pair<Int, Int>) {\r\n        for (x in 1..6){\r\n            for (y in 1..6) {\r\n                laberit += if (x==mickeyLoc.first && y==mickeyLoc.second) \"🐭\"\r\n                else if (y==6 && x==6) \"🚪\"  else drawObstacle(x,y)\r\n                if (y%6==0) laberit+=\"\\n\"\r\n\r\n            }\r\n         }\r\n        completed=true\r\n        println(laberit)\r\n        laberit=\"\"\r\n\r\n    }\r\n\r\n    override fun searchObstacle(location: Pair<Int, Int>): Boolean {\r\n       if(listObstacle.count { it.first == location.first && it.second == location.second } == 1){\r\n           println(\"Mickey found obstacle he need move to another way\")\r\n           return true\r\n       }\r\n       return false\r\n    }\r\n\r\n   private fun drawObstacle(x:Int,y:Int):String=\r\n       if (completed) generateExistObstacle(x,y)\r\n       else generateNewObstacles(x,y)\r\n\r\n\r\n   private fun  generateNewObstacles(x: Int,y: Int):String{\r\n       val generator=(1..10).random()\r\n       if (x==generator || y==generator) {\r\n           listObstacle.add(Pair(x,y))\r\n           return \"⬛️\"\r\n       }\r\n       return \"⬜️\"\r\n   }\r\n\r\n  private fun  generateExistObstacle(x: Int,y: Int):String{\r\n      if (listObstacle.count { x==it.first && y==it.second }==1) return \"⬛️\"\r\n      return \"⬜️\"\r\n  }\r\n\r\n}\r\n\r\nclass Mickey(\r\n   val blockObs:(Pair<Int,Int>)->Boolean\r\n  ):Move{\r\n\r\n    override fun moveMickey(y: Int,x: Int):Pair<Int,Int> {\r\n       println(\"Select direction to move Mickey 1 [Up], 2 [Down] , 3 [Left], 4 [Right] \")\r\n       val position= readlnOrNull()?.toInt()?:0\r\n       val oldPosition=Pair(y,x)\r\n\r\n        return when(position){\r\n           1->if(isLimit(Pair(y-1,x))) oldPosition else isObstacle(Pair(y-1,x),oldPosition)\r\n           2->if(isLimit(Pair(y+1,x))) oldPosition else isObstacle(Pair(y+1,x),oldPosition)\r\n           3->if(isLimit(Pair(y,x+1))) oldPosition else isObstacle(Pair(y,x+1),oldPosition)\r\n           4->if(isLimit(Pair(y,x-1))) oldPosition else isObstacle(Pair(y,x-1),oldPosition)\r\n           else -> oldPosition\r\n       }\r\n    }\r\n\r\n    override fun mickeyIsFree(mickeyPosition:Pair<Int,Int>): Boolean {\r\n       if (mickeyPosition.first == 6 && mickeyPosition.second == 6){\r\n           println(\"Mickey found exit of laberit\")\r\n           return true\r\n       }\r\n      return false\r\n    }\r\n\r\n private fun isLimit(newPosition: Pair<Int, Int>):Boolean {\r\n    if(newPosition.first == 0 || newPosition.first>=7|| newPosition.second>6){\r\n        println(\"Mickey can't go any further, he has reached a wall in the maze \")\r\n        return true\r\n    }\r\n    return false\r\n }\r\n\r\n   private fun isObstacle(newPosition:Pair<Int,Int>,position:Pair<Int,Int>):Pair<Int,Int> =\r\n       if (blockObs(newPosition)) position else newPosition\r\n\r\n}\r\n\r\nfun laberitD23(){\r\n    val laberit= DrawableLaberit()\r\n    val mickey= Mickey(laberit::searchObstacle)\r\n    var mickeyPosition=Pair(1,1)\r\n\r\n\r\n    while (!mickey.mickeyIsFree(mickeyPosition)){\r\n        laberit.drawLaberit(mickeyPosition)\r\n        mickeyPosition=mickeyPosition.let { mickey.moveMickey(it.first,it.second) }\r\n    }\r\n\r\n}\r\n\r\n\r\n\r\nfun main() {\r\n  laberitD23()\r\n}"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/ocaml/luishendrix92.ml",
    "content": "module Maze = struct\n  type t =\n    { mutable mouse_pos : int * int\n    ; exit_pos : int * int\n    ; walls : int array array\n    ; width : int\n    ; height : int\n    }\n\n  let create mouse_pos exit_pos str =\n    let walls =\n      Core.String.split_lines str\n      |> List.map (fun line ->\n        Core.String.to_array line\n        |> Array.map (function\n          | ' ' -> 0\n          | _ -> 1))\n      |> Array.of_list\n    in\n    let rows, cols = Array.length walls, Array.length walls.(0) in\n    { mouse_pos; exit_pos; walls; width = cols; height = rows }\n  ;;\nend\n\nmodule App = struct\n  open Curses\n\n  type dir =\n    | Up\n    | Right\n    | Down\n    | Left\n\n  let ui_str = Stdio.In_channel.read_all \"./resources/mickey-ui.txt\"\n  let maze_str = Stdio.In_channel.read_all \"./resources/mickey-maze.txt\"\n  let maze = Maze.create (1, 1) (90, 18) maze_str\n\n  let init_curses () =\n    initscr () |> ignore;\n    cbreak () |> ignore;\n    start_color () |> ignore;\n    noecho () |> ignore;\n    keypad (stdscr ()) true |> ignore;\n    curs_set 0 |> ignore;\n    init_pair 1 Color.white Color.blue |> ignore;\n    init_pair 2 Color.white Color.red |> ignore\n  ;;\n\n  let draw_entities () =\n    mvaddstr 0 0 ui_str |> ignore;\n    mvaddstr 5 0 maze_str |> ignore;\n    let mouse_x, mouse_y = maze.mouse_pos in\n    let exit_x, exit_y = maze.exit_pos in\n    attron A.bold |> ignore;\n    attron (A.color_pair 1) |> ignore;\n    mvaddch (mouse_y + 5) mouse_x (int_of_char 'M') |> ignore;\n    attroff (A.color_pair 1) |> ignore;\n    attron (A.color_pair 2) |> ignore;\n    mvaddch (exit_y + 5) exit_x (int_of_char 'E') |> ignore;\n    attroff (A.color_pair 2) |> ignore;\n    attroff A.bold |> ignore;\n    refresh () |> ignore\n  ;;\n\n  let stop () =\n    clear ();\n    addstr \"Goodbye\" |> ignore;\n    refresh () |> ignore;\n    Thread.delay 1.0;\n    endwin ();\n    exit 0\n  ;;\n\n  let move_mouse dir =\n    let new_x, new_y =\n      let x, y = maze.mouse_pos in\n      match dir with\n      | Up -> x, y - 1\n      | Right -> x + 1, y\n      | Down -> x, y + 1\n      | Left -> x - 1, y\n    in\n    if (new_x, new_y) = maze.exit_pos\n    then stop ()\n    else if (new_x >= 0 && new_x < maze.width)\n            && new_y >= 0\n            && new_y < maze.height\n            && maze.walls.(new_y).(new_x) <> 1\n    then maze.mouse_pos <- new_x, new_y\n    else ()\n  ;;\n\n  let rec loop () =\n    clear ();\n    draw_entities ();\n    begin\n      match getch () with\n      | 27 -> stop ()\n      | 0o402 -> move_mouse Down\n      | 0o403 -> move_mouse Up\n      | 0o404 -> move_mouse Left\n      | 0o405 -> move_mouse Right\n      | _ -> ()\n    end;\n    loop ()\n  ;;\n\n  let start () =\n    init_curses ();\n    loop ()\n  ;;\nend\n;;\n\nApp.start ()\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/php/miguelex.php",
    "content": "<?php\ndefine('SIZE', 6);\n\nfunction generarLaberinto() {\n    $laberinto = [];\n\n    // Laberinto vacio\n    for ($i = 0; $i < SIZE; $i++) {\n        for ($j = 0; $j < SIZE; $j++) {\n            $laberinto[$i][$j] = '⬜️'; \n        }\n    }\n\n    // obstáculos\n    $numObstaculos = rand(5, 10); \n\n    for ($i = 0; $i < $numObstaculos; $i++) {\n        do {\n            $x = rand(0, SIZE - 1);\n            $y = rand(0, SIZE - 1);\n        } while ($laberinto[$x][$y] !== '⬜️'); \n\n        $laberinto[$x][$y] = '⬛️';\n    }\n\n    // Mickey\n    do {\n        $mickeyX = rand(0, SIZE - 1);\n        $mickeyY = rand(0, SIZE - 1);\n    } while ($laberinto[$mickeyX][$mickeyY] !== '⬜️');\n\n    $laberinto[$mickeyX][$mickeyY] = '🐭';\n\n    // salida\n    do {\n        $salidaX = rand(0, SIZE - 1);\n        $salidaY = rand(0, SIZE - 1);\n    } while ($laberinto[$salidaX][$salidaY] !== '⬜️');\n\n    $laberinto[$salidaX][$salidaY] = '🚪';\n\n    return [$laberinto, $mickeyX, $mickeyY, $salidaX, $salidaY];\n}\n\nfunction mostrarLaberintoCiego($laberinto, $mickeyX, $mickeyY) {\n    for ($i = 0; $i < SIZE; $i++) {\n        for ($j = 0; $j < SIZE; $j++) {\n            if ($i === $mickeyX && $j === $mickeyY) {\n                echo '🐭 ';\n            } elseif (abs($i - $mickeyX) <= 1 && abs($j - $mickeyY) <= 1) {\n                echo $laberinto[$i][$j] . ' ';\n            } else {\n                echo '❓ '; // Celda desconocida\n            }\n        }\n        echo PHP_EOL;\n    }\n}\n\n\nfunction mostrarLaberinto($laberinto) {\n    foreach ($laberinto as $fila) {\n        echo implode(' ', $fila) . PHP_EOL;\n    }\n}\n\nfunction moverMickey($direccion, &$mickeyX, &$mickeyY, &$laberinto, $salidaX, $salidaY) {\n    $nuevaX = $mickeyX;\n    $nuevaY = $mickeyY;\n\n    switch ($direccion) {\n        case 'a': \n            $nuevaX--;\n            break;\n        case 'b': \n            $nuevaX++;\n            break;\n        case 'i': \n            $nuevaY--;\n            break;\n        case 'd': \n            $nuevaY++;\n            break;\n        default:\n            echo \"Dirección no válida. Intenta de nuevo.\\n\";\n            return false;\n    }\n\n\n    if ($nuevaX < 0 || $nuevaX >= SIZE || $nuevaY < 0 || $nuevaY >= SIZE) {\n        echo \"¡No puedes salirte del laberinto!\\n\";\n        return false;\n    }\n\n    if ($laberinto[$nuevaX][$nuevaY] === '⬛️') {\n        echo \"¡Hay un obstáculo en esa dirección!\\n\";\n        return false;\n    }\n\n    $laberinto[$mickeyX][$mickeyY] = ($mickeyX === $salidaX && $mickeyY === $salidaY) ? '🚪' : '⬜️'; // Mantener la puerta si estaba ahí\n    $mickeyX = $nuevaX;\n    $mickeyY = $nuevaY;\n    $laberinto[$mickeyX][$mickeyY] = '🐭';\n\n    if ($mickeyX === $salidaX && $mickeyY === $salidaY) {\n        return true;\n    }\n\n    return false;\n}\n\nfunction jugar() {\n    list($laberinto, $mickeyX, $mickeyY, $salidaX, $salidaY) = generarLaberinto();\n\n    while (true) {\n        mostrarLaberintoCiego($laberinto, $mickeyX, $mickeyY);\n\n        echo \"¿Hacia dónde te gustaría mover a Mickey? (a=arriba, b=abajo, i=izquierda, d=derecha): \";\n        $direccion = trim(fgets(STDIN));\n\n        if (moverMickey($direccion, $mickeyX, $mickeyY, $laberinto, $salidaX, $salidaY)) {\n            echo \"¡Felicidades! Mickey ha llegado a la salida.\\n\";\n            mostrarLaberinto($laberinto); \n            break;\n        }\n    }\n}\n\njugar();\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/python/CesarCarmona30.py",
    "content": "from os import system\nfrom pynput.keyboard import Key, Listener\n\nmaze = [\n  [\"⬜️\", \"⬜️\", \"⬜️\", \"⬜️\", \"⬜️\", \"⬛️\"],\n  [\"⬜️\", \"⬛️\", \"⬜️\", \"⬛️\", \"⬛️\", \"⬛️\"],\n  [\"⬜️\", \"⬛️\", \"⬜️\", \"⬛️\", \"⬛️\", \"⬛️\"],\n  [\"⬜️\", \"⬛️\", \"⬜️\", \"⬜️\", \"⬜️\", \"⬜️\"],\n  [\"🐭\", \"⬜️\", \"⬛️\", \"⬜️\", \"⬛️\", \"⬛️\"],\n  [\"⬜️\", \"⬛️\", \"⬛️\", \"⬜️\", \"⬜️\", \"🚪\"]\n]\n\nmickey_pos = [4, 0]\nexit_door = [5, 5]\n\ndef draw_maze(maze: list):\n    system(\"cls\")\n    for row in maze:\n        print(\"\".join(row))\n\ndef on_press(key: Key):\n    global mickey_pos\n    try:\n        mickey_prev = mickey_pos.copy()\n        mickey_pos = movements(key, mickey_pos)\n\n        if not mickey_pos:\n            return False\n\n        maze[mickey_prev[0]][mickey_prev[1]] = \"⬜️\"\n        maze[mickey_pos[0]][mickey_pos[1]] = \"🐭\"\n        draw_maze(maze)\n\n        if mickey_pos == exit_door:\n            print(\"You Won!!\")\n            return False\n\n    except AttributeError:\n        print(f\"special key pressed: {key}\")\n\ndef on_release(key: Key):\n    if key == Key.esc:\n        return False\n\ndef move_up(current_pos: list) -> list:\n    y_pos, x_pos = current_pos\n    if y_pos > 0 and maze[y_pos - 1][x_pos] in (\"⬜️\", \"🚪\"):\n        return [y_pos - 1, x_pos]\n    return current_pos\n\ndef move_down(current_pos: list) -> list:\n    y_pos, x_pos = current_pos\n    if y_pos < len(maze) - 1 and maze[y_pos + 1][x_pos] in (\"⬜️\", \"🚪\"):\n        return [y_pos + 1, x_pos]\n    return current_pos\n\ndef move_left(current_pos: list) -> list:\n    y_pos, x_pos = current_pos\n    if x_pos > 0 and maze[y_pos][x_pos - 1] in (\"⬜️\", \"🚪\"):\n        return [y_pos, x_pos - 1]\n    return current_pos\n\ndef move_right(current_pos: list) -> list:\n    y_pos, x_pos = current_pos\n    if x_pos < len(maze[0]) - 1 and maze[y_pos][x_pos + 1] in (\"⬜️\", \"🚪\"):\n        return [y_pos, x_pos + 1]\n    return current_pos\n\ndef movements(pressed_key: Key, position: list) -> list:\n    match pressed_key:\n        case Key.up:\n            return move_up(position)\n        case Key.down:\n            return move_down(position)\n        case Key.left:\n            return move_left(position)\n        case Key.right:\n            return move_right(position)\n        case Key.esc:\n            position.clear()\n    return position\n\nwith Listener(on_press=on_press, on_release=on_release) as listener:\n    draw_maze(maze)\n    listener.join()\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/python/EmmanuelMMontesinos.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * ¡Disney ha presentado un montón de novedades en su D23! \n * Pero... ¿Dónde está Mickey?\n * Mickey Mouse ha quedado atrapado en un laberinto mágico \n * creado por Maléfica.\n * Desarrolla un programa para ayudarlo a escapar.\n * Requisitos:\n * 1. El laberinto está formado por un cuadrado de 6x6 celdas.\n * 2. Los valores de las celdas serán:\n *    - ⬜️ Vacío\n *    - ⬛️ Obstáculo\n *    - 🐭 Mickey\n *    - 🚪 Salida\n * Acciones:\n * 1. Crea una matriz que represente el laberinto (no hace falta\n * que se genere de manera automática).\n * 2. Interactúa con el usuario por consola para preguntarle hacia\n * donde se tiene que desplazar (arriba, abajo, izquierda o derecha).\n * 3. Muestra la actualización del laberinto tras cada desplazamiento.\n * 4. Valida todos los movimientos, teniendo en cuenta los límites\n * del laberinto y los obtáculos. Notifica al usuario.\n * 5. Finaliza el programa cuando Mickey llegue a la salida.\n */\n\"\"\"\n\nclass Laberinto:\n    def __init__(self) -> None:\n        self.camino = \"⬜️\"\n        self.obstaculo = \"⬛️\"\n        self.salida = \"🚪\"\n        self.pos_inicio = [0,0]\n        self.pos_final = [5,5]\n        self.jugador = Mickey()\n        self.pos_mickey = self.jugador.posicion\n        # Crea una matriz que represente el laberinto\n        self.nivel = {\n            0: [self.jugador.mickey, self.camino, self.obstaculo, self.camino, self.camino, self.camino],\n            1: [self.obstaculo, self.camino, self.camino, self.camino, self.obstaculo, self.camino],\n            2: [self.obstaculo, self.obstaculo, self.obstaculo, self.obstaculo, self.obstaculo, self.camino],\n            3: [self.camino, self.camino, self.camino, self.camino, self.camino, self.camino],\n            4: [self.camino, self.obstaculo, self.obstaculo, self.obstaculo, self.obstaculo, self.obstaculo],\n            5: [self.camino, self.camino, self.camino, self.camino, self.camino, self.salida],\n        }\n\n\n    # Muestra la actualización del laberinto tras cada desplazamiento\n    def mostrar_mapa(self):\n        print(f\"Golpes: {self.jugador.golpes}\")\n        for row in self.nivel.keys():\n            for column in range(6):\n                print(self.nivel[row][column],end=\" \")\n            print()\n\n    # Finaliza el programa cuando Mickey llegue a la salida\n    def is_end(self):\n        if self.nivel[5][5] == \"🐭\":\n            return True\n        else:\n            return False\n        \n    def bucle(self):\n        print(\"El Laberinto del Moure\")\n        check = False\n        while not check:\n            self.mostrar_mapa()\n            self.jugador.movimiento(self)\n            check = self.is_end()\n        self.mostrar_mapa()\n        print(f\"Has Llegado a la salida con {self.jugador.golpes} golpes!!!\")\n    \nclass Mickey:\n    def __init__(self) -> None:\n        self.mickey = \"🐭\"\n        self.posicion = [0,0]\n        # Sistema para contar los golpes, no esta en el ejercicio pero me parecia ineresante meterlo\n        self.golpes = 0\n\n    # Valida todos los movimientos, teniendo en cuenta los límites\n    # del laberinto y los obtáculos. Notifica al usuario.\n    def comprobar_mov(self,siguiente,laberinto):\n        if siguiente != self.posicion:\n            if siguiente[0] >= 0 and siguiente[0] <= 5:\n                if siguiente[1] >= 0 and siguiente[1] <= 5:\n                    if laberinto.nivel[siguiente[0]][siguiente[1]] != laberinto.obstaculo:\n\n                        laberinto.nivel[siguiente[0]][siguiente[1]] = self.mickey\n                        laberinto.nivel[self.posicion[0]][self.posicion[1]] = laberinto.camino\n                        self.posicion = siguiente\n\n                    else:\n\n                        print(\"Te has dado un tortazo contra la pared!!!\")\n                        self.golpes += 1\n                else:\n\n                    print(\"Te has dado un tortazo contra la pared!!!\")\n                    self.golpes += 1\n            else:\n\n                print(\"Te has dado un tortazo contra la pared!!!\")\n                self.golpes += 1\n\n    # Interactúa con el usuario por consola para preguntarle hacia donde se tiene que desplazar\n    def movimiento(self,laberinto:Laberinto):\n        mov = input(\"1: Izquierda, 2: Arriba, 3: Abajao, 4: Derecha\\n\")\n        match mov:\n            case \"1\":\n                siguiente = [self.posicion[0], self.posicion[1]-1]\n                \n            case \"2\":\n                siguiente = [self.posicion[0]-1, self.posicion[1]]\n                \n            case \"3\":\n                siguiente = [self.posicion[0]+1, self.posicion[1]]\n                \n            case \"4\":\n                siguiente = [self.posicion[0], self.posicion[1]+1]\n            case _:\n                print(f\"{mov} No es un movimiento permitido Mickey!!!\")\n                siguiente = self.posicion\n\n        self.comprobar_mov(siguiente,laberinto)\n\n# Prueba\n\ndisney_maze = Laberinto()\ndisney_maze.bucle()\n\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/python/Gordo-Master.py",
    "content": "# 33 - Rescatando a Mickey\n\nimport time\nimport os\n\nmov_up = [-1, 0]\nmov_down = [1, 0]\nmov_left = [0, -1]\nmov_right = [0, 1]\n\nmaze = [\n    [\"🚪\",\"⬛️\",\"⬜️\",\"⬜️\",\"⬜️\",\"⬜️\"],\n    [\"⬜️\",\"⬛️\",\"⬛️\",\"⬜️\",\"⬛️\",\"⬜️\"],\n    [\"⬜️\",\"⬛️\",\"⬛️\",\"⬜️\",\"⬛️\",\"⬜️\"],\n    [\"⬜️\",\"⬜️\",\"⬜️\",\"⬜️\",\"⬛️\",\"⬜️\"],\n    [\"⬛️\",\"⬛️\",\"⬛️\",\"⬜️\",\"⬛️\",\"⬜️\"],\n    [\"🐭\",\"⬜️\",\"⬜️\",\"⬜️\",\"⬜️\",\"⬛️\"] \n]\n\nmickey = [5,0]\n\ndef mickey_move(mickey, move_to):\n    to_go = [a + b for a,b in zip(mickey,move_to)]\n    if to_go[0] < 0 or to_go[0] > 5 or to_go[1] < 0 or to_go[1] > 5:\n        print(\"Por ese lado se encuentra una pared!\")\n        return mickey, False\n    elif maze[to_go[0]][to_go[1]] == \"⬛️\":\n        print(\"Por ese lado se encuentra una obstaculo!\")\n        return mickey, False\n    elif maze[to_go[0]][to_go[1]] == \"⬜️\":\n        print(\"Mickey se movio!\")\n        return to_go, False\n    else:\n        print(\"Mickey ha encontrado la salida!\")\n        return to_go, True\n\ndef print_maze():\n    for row in maze:\n        print(\"\".join(row))\n\nwhile True:\n    os.system(\"cls\")  \n    print(\"El laberinto de Mickey\")  \n    print_maze()\n    print(\"Elige el movimiento: \")\n    print(\"W: arriba\")\n    print(\"S: abajo\")\n    print(\"A: izquierda\")\n    print(\"D: derecha\")  \n    move = input(\"Opción: \").upper()\n    opcion = [\"W\",\"S\",\"A\",\"D\"]\n    if move not in opcion:\n        print(\"Valor invalido\")\n        time.sleep(1)\n        continue      \n\n    match move:\n        case \"W\":\n            maze[mickey[0]][mickey[1]] = \"⬜️\"\n            mickey, escape = mickey_move(mickey, mov_up)\n            maze[mickey[0]][mickey[1]] = \"🐭\"\n\n        case \"S\":\n            maze[mickey[0]][mickey[1]] = \"⬜️\"\n            mickey, escape = mickey_move(mickey, mov_down)\n            maze[mickey[0]][mickey[1]] = \"🐭\"\n\n        case \"A\":\n            maze[mickey[0]][mickey[1]] = \"⬜️\"\n            mickey, escape = mickey_move(mickey, mov_left)\n            maze[mickey[0]][mickey[1]] = \"🐭\"\n        case \"D\":\n            maze[mickey[0]][mickey[1]] = \"⬜️\"\n            mickey, escape = mickey_move(mickey, mov_right)\n            maze[mickey[0]][mickey[1]] = \"🐭\"\n\n    time.sleep(1)\n\n    if escape:\n        os.system(\"cls\")\n        print(\"Felicidades Mickey ha logrado escapar de Malefica!\")\n        print_maze()\n        break"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/python/JesusWay69.py",
    "content": "import os, platform\n\nif (platform.platform().startswith(\"macOS\") or platform.platform().startswith(\"Linux\")):\n    os.system('clear')\nelse:\n    os.system('cls')\n\n\"\"\" * EJERCICIO:\n * ¡Disney ha presentado un montón de novedades en su D23!\n * Pero... ¿Dónde está Mickey?\n * Mickey Mouse ha quedado atrapado en un laberinto mágico\n * creado por Maléfica.\n * Desarrolla un programa para ayudarlo a escapar.\n * Requisitos:\n * 1. El laberinto está formado por un cuadrado de 6x6 celdas.\n * 2. Los valores de las celdas serán:\n *    - ⬜️ Vacío\n *    - ⬛️ Obstáculo\n *    - 🐭 Mickey\n *    - 🚪 Salida\n * Acciones:\n * 1. Crea una matriz que represente el laberinto (no hace falta\n * que se genere de manera automática).\n * 2. Interactúa con el usuario por consola para preguntarle hacia\n * donde se tiene que desplazar (arriba, abajo, izquierda o derecha).\n * 3. Muestra la actualización del laberinto tras cada desplazamiento.\n * 4. Valida todos los movimientos, teniendo en cuenta los límites\n * del laberinto y los obstáculos. Notifica al usuario.\n * 5. Finaliza el programa cuando Mickey llegue a la salida.\"\"\"\n\n\nlabyrinth =[[\"🐭\",\"⬛️\",\"⬛️\",\"⬜️\",\"⬜️\",\"⬜️\"],\n            [\"⬜️\",\"⬜️\",\"⬛️\",\"⬜️\",\"⬛️\",\"⬜️\"],\n            [\"⬛️\",\"⬜️\",\"⬛️\",\"⬜️\",\"⬜️\",\"⬜️\"],\n            [\"⬛️\",\"⬜️\",\"⬛️\",\"⬜️\",\"⬜️\",\"⬛️\"],\n            [\"⬜️\",\"⬜️\",\"⬛️\",\"⬜️\",\"⬜️\",\"🚪\"],\n            [\"⬜️\",\"⬜️\",\"⬜️\",\"⬜️\",\"⬛️\",\"⬜️\"]]\n\ndef show_labyrinth(labyrinth):\n    for rows in labyrinth:\n        print()\n        for columns in rows:\n            print(columns, end='') \n    print()\n\ndef movements(next_row, next_column, mickey_position):\n    if next_column > 5 or next_column < 0 or next_row < 0 or next_row > 5 or labyrinth[next_row][next_column] == '⬛️':\n        print(\"No se puede seguir en esa dirección, pruebe de nuevo\")\n        next_row, next_column = row, column\n        show_labyrinth(labyrinth)\n\n    elif labyrinth[next_row][next_column] == '🚪':\n        print(\"¡¡Has encontrado la salida del laberinto!!\")\n        labyrinth[row][column] = '⬜️'\n        labyrinth[next_row][next_column] = '🐭'\n        mickey_position = [-1, -1]\n        show_labyrinth(labyrinth)\n        \n    else:\n        labyrinth[row][column] = '⬜️'\n        labyrinth[next_row][next_column] = '🐭'\n        mickey_position = [next_row, next_column]\n        show_labyrinth(labyrinth)\n    return mickey_position \n\nmickey_position = [0,0]\n\nshow_labyrinth(labyrinth)\n\nwhile mickey_position != [-1, -1]:\n    row, column = mickey_position\n\n    next_row, next_column = row, column\n\n    movement = input(\"\"\"\\n\\nElija un movimiento para guiar a Mickey por el laberinto:\n              n - Subir\n              s - Bajar\n              w - Izquierda\n              e - Derecha\n              ---> \"\"\").lower()    \n              \n    if movement != \"n\" and movement != \"s\" and movement != \"w\" and movement != \"e\":\n        print(\"comando no válido, pruebe de nuevo\")\n        show_labyrinth(labyrinth)\n        continue\n\n    else:\n        if movement == \"n\":\n            next_row = row - 1\n            \n        elif movement == \"s\":\n            next_row = row + 1\n           \n        elif movement == \"w\":\n            next_column = column - 1\n            \n        elif movement == \"e\":\n            next_column = column + 1\n           \n    mickey_position = movements(next_row, next_column, mickey_position)\n    \n    \n\n\n\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/python/Jotarose.py",
    "content": "\"\"\"\r\nAyudar a escapar a Mickey.\r\n- Laberinto formado por un CUADRADO de 6x6 CELDAS\r\n    - Valores de las celdas:\r\n        - Celda vacia\r\n        - Celda con obstaculo\r\n        - Mickey\r\n        - Salida\r\n\r\n- Acciones:\r\n    1. Crear la matriz que represente el laberinto\r\n    2. Interactuar con el usuario por consola para preguntarle desplazamientos\r\n        - arriba, izquierda, derecha y abajo\r\n    3. Mostrar actualización del laberinto tras cada desplazamiento\r\n    4. Validar los movimientos teniendo en cuenta los limites del laberinto y los obstaculos\r\n        - Avisar al usuario\r\n    5. Finalizar el programa cuando Mickey llega a la salida\r\n\"\"\"\r\n\r\nfrom dataclasses import dataclass, field\r\nfrom enum import StrEnum\r\nfrom random import randint\r\n\r\n\r\n@dataclass\r\nclass Maze:\r\n    \"\"\"\r\n    Representa la estructura de datos del laberinto.\r\n\r\n    Attributes:\r\n        rows (int): Número de filas del laberinto. Por defecto 6.\r\n        cols (int): Número de columnas. Se iguala a rows en __post_init__ si no se especifica.\r\n        pos_min (int): Índice mínimo válido (0).\r\n        pos_max (int): Índice máximo válido (calculado dinámicamente).\r\n        maze (list): La matriz que representa el tablero de juego.\r\n    \"\"\"\r\n\r\n    rows: int = 6\r\n    cols: int = rows\r\n    pos_min: int = 0\r\n    pos_max: int = 0\r\n    maze: list = field(default_factory=list)\r\n\r\n    def __post_init__(self):\r\n        \"\"\"Calcula los límites dinámicos después de la inicialización.\"\"\"\r\n        self.pos_max = self.rows - 1\r\n\r\n    def get_limits(self) -> int:\r\n        \"\"\"\r\n        Devuelve los límites inferior y superior del laberinto.\r\n\r\n        Returns:\r\n            tuple[int, int]: Una tupla con (pos_min, pos_max).\r\n        \"\"\"\r\n        return self.pos_min, self.pos_max\r\n\r\n\r\nclass MoveOption(StrEnum):\r\n    UP = \"1\"\r\n    DOWN = \"2\"\r\n    RIGHT = \"3\"\r\n    LEFT = \"4\"\r\n    EXIT = \"5\"\r\n\r\n\r\nclass View:\r\n    \"\"\"Maneja toda la interacción con el usuario (entradas y salidas por consola).\"\"\"\r\n\r\n    def display_msg(self, msg: str):\r\n        \"\"\"\r\n        Muestra un mensaje estándar en la consola.\r\n\r\n        Args:\r\n            msg (str): El mensaje a mostrar.\r\n        \"\"\"\r\n        print(msg)\r\n\r\n    def display_err(self, err):\r\n        \"\"\"\r\n        Muestra un mensaje de error formateado.\r\n\r\n        Args:\r\n            err (str): El texto del error.\r\n        \"\"\"\r\n        print(f\"\\nERROR: {err}\")\r\n\r\n    def get_user_input(self, prompt: str) -> str:\r\n        \"\"\"\r\n        Solicita información al usuario.\r\n\r\n        Args:\r\n            prompt (str): El texto que se mostrará para pedir el dato.\r\n\r\n        Returns:\r\n            str: Lo que el usuario escribe en la consola.\r\n        \"\"\"\r\n        return input(prompt)\r\n\r\n\r\nclass Game:\r\n    \"\"\"Controla la lógica principal del juego, el estado y las reglas.\"\"\"\r\n\r\n    def __init__(self, maze: Maze, view: View):\r\n        \"\"\"\r\n        Inicializa el juego.\r\n\r\n        Args:\r\n            maze (Maze): Objeto con la configuración del tablero.\r\n            view (View): Objeto para manejar la interfaz de usuario.\r\n        \"\"\"\r\n\r\n        self.maze = maze\r\n        self.maze_pos_min, self.maze_pos_max = self.maze.get_limits()\r\n        self.view = view\r\n\r\n        self.mickey = \"🐭\"\r\n        self.empty = \"⬜️\"\r\n        self.obstacle = \"⬛️\"\r\n        self.exit = \"🚪\"\r\n\r\n        self.obstacle_counter = 9\r\n        self.move_counter = 0\r\n        self.mickey_pos = None\r\n        self.exit_pos = None\r\n\r\n    def generate_maze(self):\r\n        \"\"\"\r\n        Genera el laberinto inicial colocando a Mickey, la salida y los obstáculos.\r\n\r\n        Asegura que la salida no se superpone con Mickey y que los obstáculos\r\n        no se superponen con nada existente.\r\n        \"\"\"\r\n\r\n        self.view.display_msg(\"\\nComienza el juego:\")\r\n        self.view.display_msg(\"- Generando un nuevo mapa aleatorio ...\\n\")\r\n\r\n        self.maze.maze = [[\"⬜️\"] * self.maze.cols for _ in range(self.maze.rows)]\r\n\r\n        mickey_row = randint(self.maze_pos_min, self.maze_pos_max)\r\n        mickey_col = randint(self.maze_pos_min, self.maze_pos_max)\r\n        self.maze.maze[mickey_row][mickey_col] = self.mickey\r\n        self.mickey_pos = [mickey_row, mickey_col]\r\n\r\n        while True:\r\n            exit_row = randint(self.maze_pos_min, self.maze_pos_max)\r\n            exit_col = randint(self.maze_pos_min, self.maze_pos_max)\r\n            if self.maze.maze[exit_row][exit_col] == self.mickey:\r\n                continue\r\n            else:\r\n                self.maze.maze[exit_row][exit_col] = self.exit\r\n                self.exit_pos = [exit_row, exit_col]\r\n                break\r\n\r\n        counter = 0\r\n        while counter < self.obstacle_counter:\r\n            row = randint(self.maze_pos_min, self.maze_pos_max)\r\n            col = randint(self.maze_pos_min, self.maze_pos_max)\r\n\r\n            if (\r\n                self.maze.maze[row][col] == self.obstacle\r\n                or self.maze.maze[row][col] == self.exit\r\n                or self.maze.maze[row][col] == self.mickey\r\n            ):\r\n                continue\r\n            else:\r\n                self.maze.maze[row][col] = self.obstacle\r\n                counter += 1\r\n\r\n        self._print_maze()\r\n\r\n    def get_next_move(self) -> MoveOption:\r\n        \"\"\"\r\n        Solicita al usuario el siguiente movimiento y lo valida.\r\n\r\n        Maneja errores de entrada si el usuario introduce una opción que no existe.\r\n\r\n        Returns:\r\n            MoveOption: La opción seleccionada por el usuario (UP, DOWN, etc.).\r\n        \"\"\"\r\n\r\n        while True:\r\n            try:\r\n                move = MoveOption(\r\n                    self.view.get_user_input(\r\n                        \"\\nSelecciona el siguiente movimiento de Mickey:\\n\"\r\n                        \"1. Arriba\\n\"\r\n                        \"2. Abajo\\n\"\r\n                        \"3. Derecha\\n\"\r\n                        \"4. Izquierda\\n\"\r\n                        \"5. Finalizar el juego.\\n\"\r\n                        \"\\n-> Escribe tu opcion: \"\r\n                    )\r\n                )\r\n\r\n                match move:\r\n                    case MoveOption.UP:\r\n                        return MoveOption.UP\r\n                    case MoveOption.DOWN:\r\n                        return MoveOption.DOWN\r\n                    case MoveOption.RIGHT:\r\n                        return MoveOption.RIGHT\r\n                    case MoveOption.LEFT:\r\n                        return MoveOption.LEFT\r\n                    case MoveOption.EXIT:\r\n                        return MoveOption.EXIT\r\n\r\n            except ValueError:\r\n                self.view.display_err(\"\\nMovimiento no válido\")\r\n\r\n    def update_maze(self, next_move: MoveOption):\r\n        \"\"\"\r\n        Coordina la ejecución del movimiento seleccionado.\r\n\r\n        Args:\r\n            next_move (MoveOption): La dirección hacia la que mover a Mickey.\r\n        \"\"\"\r\n\r\n        match next_move:\r\n            case MoveOption.UP:\r\n                self._make_move(move_row=-1)\r\n                self._print_maze()\r\n                return\r\n\r\n            case MoveOption.DOWN:\r\n                self._make_move(move_row=1)\r\n                self._print_maze()\r\n                return\r\n\r\n            case MoveOption.RIGHT:\r\n                self._make_move(move_col=1)\r\n                self._print_maze()\r\n                return\r\n\r\n            case MoveOption.LEFT:\r\n                self._make_move(move_col=-1)\r\n                self._print_maze()\r\n                return\r\n\r\n    def finish_game(self) -> bool:\r\n        \"\"\"\r\n        Comprueba si Mickey ha llegado a la salida.\r\n\r\n        Returns:\r\n            bool: True si la posición de Mickey coincide con la salida, False en caso contrario.\r\n        \"\"\"\r\n\r\n        if self.exit_pos[0] == self.mickey_pos[0] and self.exit_pos[1] == self.mickey_pos[1]:\r\n            self.view.display_msg(\"\\nENHORABUENA, MICKEY ENCONTRO LA SALIDA.\")\r\n            self.view.display_msg(f\"- Tardaste {self.move_counter} movimientos en resolverlo.\\n\")\r\n            return True\r\n        else:\r\n            return False\r\n\r\n    def _make_move(self, move_row=0, move_col=0):\r\n        \"\"\"\r\n        Realiza el cálculo interno del movimiento y actualiza la matriz.\r\n\r\n        Verifica si el movimiento es válido (dentro de límites y sin obstáculos).\r\n        Si es válido, actualiza la posición de Mickey y la matriz visual.\r\n\r\n        Args:\r\n            move_row (int): Desplazamiento en filas (-1, 0, 1).\r\n            move_col (int): Desplazamiento en columnas (-1, 0, 1).\r\n        \"\"\"\r\n\r\n        if (\r\n            (self.mickey_pos[0] == self.maze_pos_min and move_row == -1)\r\n            or (self.mickey_pos[0] == self.maze_pos_max and move_row == 1)\r\n            or (self.mickey_pos[1] == self.maze_pos_min and move_col == -1)\r\n            or (self.mickey_pos[1] == self.maze_pos_max and move_col == 1)\r\n        ):\r\n            self.view.display_err(\"Movimiento fuera de limites.\\n\")\r\n            return\r\n\r\n        elif (\r\n            self.maze.maze[self.mickey_pos[0] + move_row][self.mickey_pos[1] + move_col]\r\n            == self.obstacle\r\n        ):\r\n            self.view.display_err(\"Hay un obstaculo.\\n\")\r\n            return\r\n\r\n        else:\r\n            self.maze.maze[self.mickey_pos[0]][self.mickey_pos[1]] = self.empty\r\n            self.maze.maze[self.mickey_pos[0] + move_row][self.mickey_pos[1] + move_col] = (\r\n                self.mickey\r\n            )\r\n            self.mickey_pos[0] = self.mickey_pos[0] + move_row\r\n            self.mickey_pos[1] = self.mickey_pos[1] + move_col\r\n\r\n            self.move_counter += 1\r\n            return\r\n\r\n    def _print_maze(self):\r\n        \"\"\"Imprime el estado actual del laberinto en la consola.\"\"\"\r\n\r\n        for i in range(len(self.maze.maze)):\r\n            print(self.maze.maze[i])\r\n\r\n\r\ndef main():\r\n    view = View()\r\n    maze = Maze()\r\n    game = Game(maze, view)\r\n\r\n    view.display_msg(\"\\nBIENVENIDO A EL JUEGO DEL LABERINTO.\")\r\n\r\n    game.generate_maze()\r\n    print(f\"\\nMickey POS: {game.mickey_pos}\")\r\n    print(f\"EXIT POS: {game.exit_pos}\")\r\n\r\n    finish = False\r\n    while not finish:\r\n        next_move = game.get_next_move()\r\n        view.display_msg(f\"\\nElegiste: {next_move.name}\\n\")\r\n\r\n        if next_move == MoveOption.EXIT:\r\n            view.display_msg(\"\\nSaliendo del juego ...\\n\")\r\n            break\r\n\r\n        game.update_maze(next_move)\r\n        finish = game.finish_game()\r\n\r\n\r\nif __name__ == \"__main__\":\r\n    main()\r\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/python/Mauricio-Leyva.py",
    "content": "import os\n\nlaberinto = [\n    ['⬜️', '⬜️', '⬜️', '⬜️', '⬜️', '⬜️'],\n    ['⬜️', '⬛️', '⬛️', '⬜️', '⬛️', '⬜️'],\n    ['⬜️', '⬜️', '⬜️', '⬜️', '⬛️', '⬜️'],\n    ['⬜️', '⬛️', '⬛️', '⬛️', '⬛️', '⬜️'],\n    ['⬜️', '⬜️', '⬜️', '⬜️', '⬛️', '⬜️'],\n    ['🐭', '⬛️', '⬛️', '⬜️', '⬜️', '🚪']\n]\n\n# Posición inicial de Mickey\nmickey_pos = [5, 0]\n\ndef imprimir_laberinto():\n    os.system('cls' if os.name == 'nt' else 'clear')  # Limpiar la consola\n    for fila in laberinto:\n        print(''.join(fila))\n    print(\"\\nUsa 'w' (arriba), 's' (abajo), 'a' (izquierda), 'd' (derecha) para mover a Mickey.\")\n\ndef mover_mickey(direccion):\n    nueva_pos = mickey_pos.copy()\n    if direccion == 'w':\n        nueva_pos[0] -= 1\n    elif direccion == 's':\n        nueva_pos[0] += 1\n    elif direccion == 'a':\n        nueva_pos[1] -= 1\n    elif direccion == 'd':\n        nueva_pos[1] += 1\n    \n    if 0 <= nueva_pos[0] < 6 and 0 <= nueva_pos[1] < 6 and laberinto[nueva_pos[0]][nueva_pos[1]] != '⬛️':\n        laberinto[mickey_pos[0]][mickey_pos[1]] = '⬜️'\n        mickey_pos[0], mickey_pos[1] = nueva_pos\n        laberinto[mickey_pos[0]][mickey_pos[1]] = '🐭'\n        return True\n    else:\n        print(\"¡Movimiento no válido! Mickey no puede ir por ahí.\")\n        return False\n\ndef main():\n    while True:\n        imprimir_laberinto()\n        if laberinto[5][5] == '🐭':\n            print(\"¡Felicidades! Mickey ha escapado del laberinto.\")\n            break\n        \n        movimiento = input(\"¿Hacia dónde debe moverse Mickey? \").lower()\n        if movimiento in ['w', 'a', 's', 'd']:\n            mover_mickey(movimiento)\n        else:\n            print(\"Entrada no válida. Usa 'w', 'a', 's', o 'd'.\")\n\nif __name__ == \"__main__\":\n    main()"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/python/Nicojsuarez2.py",
    "content": "# #33 RESCATANDO A MICKEY\n> #### Dificultad: Fácil | Publicación: 12/08/24 | Corrección: 19/08/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * ¡Disney ha presentado un montón de novedades en su D23! \n * Pero... ¿Dónde está Mickey?\n * Mickey Mouse ha quedado atrapado en un laberinto mágico \n * creado por Maléfica.\n * Desarrolla un programa para ayudarlo a escapar.\n * Requisitos:\n * 1. El laberinto está formado por un cuadrado de 6x6 celdas.\n * 2. Los valores de las celdas serán:\n *    - ⬜️ Vacío\n *    - ⬛️ Obstáculo\n *    - 🐭 Mickey\n *    - 🚪 Salida\n * Acciones:\n * 1. Crea una matriz que represente el laberinto (no hace falta\n * que se genere de manera automática).\n * 2. Interactúa con el usuario por consola para preguntarle hacia\n * donde se tiene que desplazar (arriba, abajo, izquierda o derecha).\n * 3. Muestra la actualización del laberinto tras cada desplazamiento.\n * 4. Valida todos los movimientos, teniendo en cuenta los límites\n * del laberinto y los obstáculos. Notifica al usuario.\n * 5. Finaliza el programa cuando Mickey llegue a la salida.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/python/SooHav.py",
    "content": "# 33 RESCATANDO A MICKEY\nimport numpy as np\n\n\ndef crear_laberinto(filas, columnas, obstaculos=0.3):\n    if filas < 3 or columnas < 3:\n        raise ValueError(\n            \"El laberinto debe tener al menos 3 filas y 3 columnas\")\n\n    laberinto = np.empty((filas, columnas), dtype=object)\n\n    fila_entrada = np.random.randint(0, filas-2)\n    fila_salida = np.random.randint(fila_entrada + 2, filas)\n    columna_entrada = np.random.randint(0, columnas-2)\n    columna_salida = np.random.randint(columna_entrada, columnas)\n    laberinto[fila_entrada, columna_entrada] = \"🐭\"\n    laberinto[fila_salida, columna_salida] = \"🚪\"\n\n    for i in range(filas):\n        for j in range(columnas):\n            if laberinto[i, j] is None:\n                if np.random.random() > obstaculos:\n                    laberinto[i, j] = \"⬜\"\n                else:\n                    laberinto[i, j] = \"⬛\"\n\n    return laberinto\n\n\ndef encontrar_coordenadas(matriz, dato):\n    filas, columnas = matriz.shape\n    for i in range(filas):\n        for j in range(columnas):\n            if matriz[i, j] == dato:\n                return (i, j)\n    return None\n\n\ndef movimiento(coordenadas1, coordenadas2):\n    fila, columna = coordenadas1[0] + \\\n        coordenadas2[0], coordenadas1[1] + coordenadas2[1]\n    return (fila, columna)\n\n# Función para mostrar el menú\n\n\ndef menu():\n    while True:\n        print(\"Menú:\")\n        print(\"1. Generar Laberinto\")\n        print(\"2. Mover a Mikey\")\n        print(\"3. Salir\")\n        opcion = input(\"Ingrese una opción: \")\n        try:\n            return int(opcion)\n        except ValueError:\n            print(\"Opción inválida. Por favor, ingrese un número entero.\")\n\n\nwhile True:\n    opcion = menu()\n\n    if opcion == 1:\n        try:\n            filas = int(input(\"Ingrese el número de filas: \"))\n            columnas = int(input(\"Ingrese el número de columnas: \"))\n            obstaculos = float(\n                input(\"Ingrese el porcentaje de obstáculos (entre 0.2 y 0.7): \"))\n            laberinto = crear_laberinto(filas, columnas, obstaculos)\n            for celda in laberinto:\n                print(\"\".join(celda))\n        except ValueError:\n            print(\"Intente nuevamente\")\n\n    elif opcion == 2:\n\n        while True:\n            coordenadas_mikey = encontrar_coordenadas(laberinto, \"🐭\")\n            coordenadas_salida = encontrar_coordenadas(laberinto, \"🚪\")\n\n            if coordenadas_mikey == coordenadas_salida:\n                print(\"¡Mikey encontró la salida!\")\n                break\n\n            elif coordenadas_mikey is None:\n                print(\"Primero debe generar un laberinto.\")\n                break\n\n            else:\n                print(f\"Mikey se encuentra en {coordenadas_mikey}\")\n                opcion_movimiento = int(\n                    input(\"1. sur, 2. oeste, 3. este, 4. norte Ingrese una opción: \"))\n                coordenadas_movimiento = [(1, 0), (0, -1), (0, 1), (-1, 0)]\n\n                if 1 <= opcion_movimiento <= 4:\n                    nueva_coordenada = movimiento(\n                        coordenadas_mikey, coordenadas_movimiento[opcion_movimiento - 1])\n                    fila, columna = nueva_coordenada\n\n                    if 0 <= fila < laberinto.shape[0] and 0 <= columna < laberinto.shape[1]:\n\n                        if laberinto[fila, columna] == \"⬜\":\n                            laberinto[coordenadas_mikey[0],\n                                      coordenadas_mikey[1]] = \"⬜\"\n                            laberinto[fila, columna] = \"🐭\"\n                            for celda in laberinto:\n                                print(\"\".join(celda))\n                            print(f\"Mikey se mueve a {nueva_coordenada}\")\n                        elif laberinto[fila, columna] == \"🚪\":\n                            print(\"¡Mikey encontró la salida!\")\n                            laberinto[coordenadas_mikey[0],\n                                      coordenadas_mikey[1]] = \"⬜\"\n                            for celda in laberinto:\n                                print(\"\".join(celda))\n                            break\n                        else:\n                            print(\n                                \"¡Movimiento inválido! Mikey no puede moverse allí.\")\n\n                            opcion = int(\n                                input(\"Debes elegir una opcion: 1 (continua) 2 (finaliza): \"))\n\n                            match opcion:\n                                case 1:\n                                    continue\n                                case 2:\n                                    print(\"Mikey no pudo salir!!\")\n                                    break\n\n                    else:\n                        print(\"¡Movimiento inválido! Mikey está fuera del laberinto.\")\n                else:\n                    print(\"Opción inválida. Por favor, ingrese una opción válida.\")\n\n    elif opcion == 3:\n        print(\"¡Hasta la próxima!\")\n        break\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/python/Trufoplus.py",
    "content": "class Board():\n    def __init__(self):\n        # Valores de las celdas:\n        self.emp = '⬜️'   # Celda vacía\n        self.obs = '⬛️'   # Obstáculo\n        self.mickey = '🐭' # Personaje\n        self.exit = '🚪'  # Salida\n        self.lifes = 3 # Vidas del mickey\n        self.make_board() #crea el tablero\n        self.mickey_pos = [0, 0] #Posicion inicial de mickey\n    \n    def make_board(self):\n        # Crear un tablero 6x6 con celdas vacías\n        self.board = []\n        self.board.append([self.mickey, self.emp, self.emp, self.emp, self.obs, self.obs])\n        self.board.append([self.obs, self.obs, self.obs, self.emp, self.emp, self.emp])\n        self.board.append([self.emp, self.emp, self.emp, self.emp, self.obs, self.obs])\n        self.board.append([self.emp, self.obs, self.obs, self.obs, self.emp, self.obs])\n        self.board.append([self.emp, self.emp, self.emp, self.emp, self.obs, self.obs])\n        self.board.append([self.obs, self.obs, self.obs, self.emp, self.emp, self.exit])  \n    \n    def print_board(self):        \n        # Imprimir el tablero\n        print('\\nRESCATANDO A MICKEY')\n        for fila in self.board:\n            print(\" \".join(fila))\n        print()\n    \n    def move_mickey(self, direction):\n        x, y = self.mickey_pos\n        \n        if direction == 'a': # izquierda\n            new_x, new_y = x, y - 1\n        \n        elif direction == 'd': #derecha\n            new_x, new_y = x, y + 1\n        \n        elif direction == 's': #abajo\n            new_x, new_y = x + 1, y\n        \n        elif direction == 'w': #arriba\n            new_x, new_y = x - 1, y\n        \n        elif direction == 'e': # salir\n            print('Saliendo del juego...')\n            return\n                          \n        else:\n            print('\\nError: Opcion incorrecta, porfavor seleccione una opción valida.\\n')\n        \n        # verificar si la nueva posicion es correcta\n        if 0 <= new_x < 6 and 0 <= new_y < 6 and self.board[new_x][new_y] != self.obs:\n            # Sustituimos la casella de mickey por una vacia\n            self.board[self.mickey_pos[0]][self.mickey_pos[1]] = self.emp\n            # Cambiamos la posicion de mickey actual\n            self.mickey_pos = [new_x, new_y]\n            # Colocamos a mickey en la nueva posicion en el tablero\n            self.board[new_x][new_y] = self.mickey\n            # Dibujamos el tablero con la nueva posicion\n            self.print_board()\n        else:\n            print('\\nouch! Mickey se ha golpeado contra una pared!')\n            self.lifes -= 1\n            print(f'Pierdes una vida, vida actual: {self.lifes}\\n')\n                          \n\n\ndef play():\n    # creamos el tablero\n    board = Board()\n    \n    # Dibuja el tablero\n    board.print_board()\n    \n    # Menu de movimientos permitidos \n    print('MOVIMIENTOS:\\na = izquierda\\nd = Derecha\\ns = Abajo\\nw = Arriba\\ne = Salir\\n')\n    \n    while True:                \n        # Movemos a mickey\n        move = input('Selecciona un movimiento: ')\n        board.move_mickey(move)\n        \n        # Condiciones para terminar el juego.\n        if board.mickey_pos == [5, 5]:\n            print('\\n¡FELICIDADES! ¡Has rescatado a Mickey!\\n')\n            break\n        if board.lifes <= 0:\n            print('¡Oh no! Mickey ha fallecido por tantos cabezazos contra la pared, lo siento.')\n            break\n        if move == 'e':\n            break\n        \n\nif __name__ == '__main__':\n    play()"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/python/adra-dev.py",
    "content": "\"\"\"\nEJERCICIO:\n¡Disney ha presentado un montón de novedades en su D23! \nPero... ¿Dónde está Mickey?\nMickey Mouse ha quedado atrapado en un laberinto mágico \ncreado por Maléfica.\nDesarrolla un programa para ayudarlo a escapar.\nRequisitos:\n1. El laberinto está formado por un cuadrado de 6x6 celdas.\n2. Los valores de las celdas serán:\n    - ⬜️ Vacío\n    - ⬛️ Obstáculo\n    - 🐭 Mickey\n    - 🚪 Salida\nAcciones:\n1. Crea una matriz que represente el laberinto (no hace falta\nque se genere de manera automática).\n2. Interactúa con el usuario por consola para preguntarle hacia\ndonde se tiene que desplazar (arriba, abajo, izquierda o derecha).\n3. Muestra la actualización del laberinto tras cada desplazamiento.\n4. Valida todos los movimientos, teniendo en cuenta los límites\ndel laberinto y los obtáculos. Notifica al usuario.\n5. Finaliza el programa cuando Mickey llegue a la salida.\n\nby adra-dev\n\"\"\"\n\n\nlabyrinth = [\n    [ \"⬜️\", \"⬜️\", \"⬛️\", \"⬛️\", \"⬛️\", \"⬛️\"], \n    [ \"⬜️\", \"⬜️\", \"⬜️\", \"⬛️\", \"⬛️\", \"⬛️\"],\n    [ \"🐭\", \"⬜️\", \"⬜️\", \"⬜️\", \"⬜️\", \"⬜️\"], \n    [ \"⬛️\", \"⬛️\", \"⬛️\", \"⬛️\", \"⬛️\", \"⬜️\"],\n    [ \"⬛️\", \"⬛️\", \"⬛️\", \"⬛️\", \"⬛️\", \"⬜️\"],\n    [ \"⬛️\", \"⬛️\", \"⬛️\", \"⬛️\", \"⬛️\", \"🚪\" ]\n]\n\n\ndef print_labyrinth():\n    for row in labyrinth:\n        print(\"\".join(row))\n    print()\n\nmickey = [2, 0]\n\n\n\nwhile True:\n\n    print_labyrinth()\n\n    print(\"Hacia donde se mueve mickey?\")\n    print(\"[w] arriba\")\n    print(\"[s] abajo\")\n    print(\"[a] izquierda\")\n    print(\"[d] dereca\")\n    direction = input(\"Direccion: \")\n\n    current_row, current_column = mickey\n    new_row, new_column = current_row, current_column\n\n    match direction:\n        case \"w\":\n            new_row = current_row - 1\n        case \"s\":\n            new_row = current_row + 1\n        case \"a\":\n            new_column = current_column - 1\n        case \"d\":\n            new_column = current_column + 1\n        case _:\n            print(\"Direccion no valida.\\n\")\n            continue\n    \n    if new_row < 0 or new_row > 5 or new_column < 0 or new_row > 5:\n        print(\"No puedes desplazarte fuera del laberinto.\\n\")\n        continue\n    else:\n        if labyrinth[new_row][new_column] == \"⬛️\":\n            print(\"En esa direccion hay un obstaculo.\\n\")\n            continue\n        elif labyrinth[new_row][new_column] == \"🚪\":\n            print(\"Has encontrado la salida!\")\n            labyrinth[current_row][current_column] = \"⬜️\"\n            labyrinth[new_row][new_column] = \"🐭\"\n            print_labyrinth()\n            break\n        else:\n            labyrinth[current_row][current_column] = \"⬜️\"\n            labyrinth[new_row][new_column] = \"🐭\"\n            mickey = [new_row, new_column]"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/python/alanshakir.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * ¡Disney ha presentado un montón de novedades en su D23! \n * Pero... ¿Dónde está Mickey?\n * Mickey Mouse ha quedado atrapado en un laberinto mágico \n * creado por Maléfica.\n * Desarrolla un programa para ayudarlo a escapar.\n * Requisitos:\n * 1. El laberinto está formado por un cuadrado de 6x6 celdas.\n * 2. Los valores de las celdas serán:\n *    - ⬜️ Vacío\n *    - ⬛️ Obstáculo\n *    - 🐭 Mickey\n *    - 🚪 Salida\n * Acciones:\n * 1. Crea una matriz que represente el laberinto (no hace falta\n * que se genere de manera automática).\n * 2. Interactúa con el usuario por consola para preguntarle hacia\n * donde se tiene que desplazar (arriba, abajo, izquierda o derecha).\n * 3. Muestra la actualización del laberinto tras cada desplazamiento.\n * 4. Valida todos los movimientos, teniendo en cuenta los límites\n * del laberinto y los obtáculos. Notifica al usuario.\n * 5. Finaliza el programa cuando Mickey llegue a la salida.\n */\n\"\"\"\ntablero = [[\"🐭\",\"⬛️\",\"⬛️\",\"⬛️\",\"⬛️\",\"⬛️\" ],\n           [\"⬜️\",\"⬜️\",\"⬜️\",\"⬛️\",\"⬛️\",\"⬛️\" ],\n           [\"⬛️\",\"⬛️\",\"⬜️\",\"⬜️\",\"⬛️\",\"⬛️\" ],\n           [\"⬛️\",\"⬛️\",\"⬛️\",\"⬜️\",\"⬜️\",\"⬜️\" ],\n           [\"⬜️\",\"⬜️\",\"⬜️\",\"⬛️\",\"⬜️\",\"⬜️\" ],\n           [\"⬜️\",\"⬛️\",\"⬛️\",\"⬜️\",\"⬜️\",\"🚪\" ]\n           ]\n\ndef draw_tablero():\n    for row in tablero:\n        print(\"\".join(row))\n\ndraw_tablero()\n\nmickey_pos = [0,0]\n\n\nwhile True:\n    draw_tablero()\n    print(\"¿Dónde está Mickey?\")\n    print(\"1. Arriba\")\n    print(\"2. Abajo\")\n    print(\"3. Izquierda\")\n    print(\"4. Derecha\")\n    print(\"5. Salir\")\n    direction = input(\"Elige una opcion: \")\n\n    prev_row, prev_col = mickey_pos\n    next_row, next_col = prev_row, prev_col\n\n    match direction:\n        case \"1\":\n            next_row = prev_row - 1\n        case \"2\":\n            next_row = prev_row + 1\n        case \"3\":\n            next_col = prev_col - 1\n        case \"4\":\n            next_col = prev_col + 1\n        case \"5\":\n            print(\"Has decidido salir del juego, hasta luego.!\")\n            break\n    if next_row < 0 or next_row > 5 or next_col < 0 or next_col > 5:\n        print(\"Te has salido del laberinto\")\n        continue\n    else:\n        if tablero[next_row][next_col] == \"⬛️\":\n            print(\"En esa direccion hay un obstaculo\")\n            continue\n        elif tablero[next_row][next_col] == \"🚪\":\n            print(\"Has encontrado la salida\")\n            tablero[prev_row][prev_col] == \"⬜️\"\n            tablero[next_row][next_col] = \"🐭\"\n            break\n            \n        else:\n            tablero[prev_row][prev_col] == \"⬜️\"\n            tablero[next_row][next_col] = \"🐭\"\n            mickey_pos = [next_row, next_col]\n            print(f\"posicion mickey {mickey_pos}\")\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/python/avcenal.py",
    "content": "\"\"\"\n* EJERCICIO:\n * ¡Disney ha presentado un montón de novedades en su D23!\n * Pero... ¿Dónde está Mickey?\n * Mickey Mouse ha quedado atrapado en un laberinto mágico\n * creado por Maléfica.\n * Desarrolla un programa para ayudarlo a escapar.\n * Requisitos:\n * 1. El laberinto está formado por un cuadrado de 6x6 celdas.\n * 2. Los valores de las celdas serán:\n *    - ⬜️ Vacío\n *    - ⬛️ Obstáculo\n *    - 🐭 Mickey\n *    - 🚪 Salida\n * Acciones:\n * 1. Crea una matriz que represente el laberinto (no hace falta\n * que se genere de manera automática).\n * 2. Interactúa con el usuario por consola para preguntarle hacia\n * donde se tiene que desplazar (arriba, abajo, izquierda o derecha).\n * 3. Muestra la actualización del laberinto tras cada desplazamiento.\n * 4. Valida todos los movimientos, teniendo en cuenta los límites\n * del laberinto y los obtáculos. Notifica al usuario.\n * 5. Finaliza el programa cuando Mickey llegue a la salida.\n\"\"\"\n#A pesar de que en el ejercicio no se pide, el programa genera el laberinto de manera automática\n#Esto tiene varias limitaciones a nivel de cuántos obstáculos se pueden colocar para que el juego tenga solución\n\nfrom abc import ABC,abstractmethod\nfrom random import randint,shuffle\nfrom math import ceil\n\n#Clases Abstractas\nclass AbstractBoardGenerator(ABC):\n    @abstractmethod\n    def create_board(self):\n        pass\n\nclass AbstractPlaceMickeyAndExit(ABC):\n    @abstractmethod\n    def place_mickey_and_exit(self,board:AbstractBoardGenerator):\n        pass\n\nclass AbstractObstaclesGenerator(ABC):\n    @abstractmethod\n    def place_obstacles(self,board:AbstractBoardGenerator):\n        pass\n\nclass AbstractBoardChecker(ABC):\n    @abstractmethod\n    def confirm_board(self,board:AbstractBoardGenerator):\n        pass\n\nclass AbstractBoardPrinter(ABC):\n    @abstractmethod\n    def print_board(self,board:AbstractBoardGenerator):\n        pass\n\nclass AbstractMickeyMove(ABC):\n    @abstractmethod\n    def __init__(self):\n        pass\n\n    @abstractmethod\n    def move_up(self):\n        pass\n\n    @abstractmethod\n    def move_down(self):\n        pass\n\n    @abstractmethod\n    def move_left(self):\n        pass\n\n    @abstractmethod\n    def move_right(self):\n        pass\n\nclass AbstractMoveChecker(ABC):\n    @abstractmethod\n    def check_move(self,board:AbstractBoardGenerator):\n        pass\n\n#Clases del programa que implementan las abstractas\n\n#Clase que se ocupa de colocar a Mickey y la Salida\nclass PlaceMickeyAndExit(AbstractPlaceMickeyAndExit):\n    def place_mickey_and_exit(self,board:AbstractBoardGenerator):\n        while True:\n            mickey_row = randint(0,board.number_of_rows-1)\n            mickey_column = randint(0,board.number_of_columns-1)\n            if mickey_row == 0:\n                out_row = 5\n                out_column = randint(0,board.number_of_columns-1)\n                break\n            elif mickey_row == 5:\n                out_row = 0\n                out_column = randint(0,board.number_of_columns-1)\n                break\n            else:\n                if mickey_column == 0:\n                    out_column = board.number_of_columns-1\n                    out_row = randint(0,board.number_of_rows-1)\n                    break\n                elif mickey_column == board.number_of_columns-1:\n                    out_column = 0\n                    out_row = randint(0,board.number_of_rows-1)\n                    break\n\n        board.board[mickey_row][mickey_column] = \"🐭\"\n        board.board[out_row][out_column] = \"🚪\"\n        return mickey_row,mickey_column,out_row,out_column\n\nclass ObstaclesGenerator(AbstractObstaclesGenerator):\n    #Método privado que genera 2 obstáculos por cuadrante de manera aleatoria\n    def __set_obstacles_in_cuadrant(self,board:AbstractBoardGenerator,rows_start:int,rows_limit:int,columns_start:int,columns_limit:int,number_of_obstacles:int):\n        index = 0\n        positions = [(row, col) for row in range(rows_start, rows_limit + 1) for col in range(columns_start, columns_limit + 1)]\n        shuffle(positions)  # Mezclar posiciones para seleccionar aleatoriamente\n        while index < number_of_obstacles:\n            row, column = positions.pop()\n            if board.board[row][column] == \"⬜️\":\n                board.board[row][column] = \"⬛️\"\n            index +=1\n    #método que calcula cuántos obstáculos se han de colocar por cuadrante según el tamaño del tablero (2 en este ejercicio) y usa __set_obstacles_in_cuadrant para generarlos\n    def place_obstacles(self,board:AbstractBoardGenerator):\n        NUMBER_OF_OBSTACLES = ceil((board.number_of_rows*board.number_of_columns)*2/9/4) #la proporcion es 9/2, por cada 9 casillas se ponen un máximo de 2 obstáculos para que el laberinto tenga solución. El resultado se divide entre 4 cuadrantes\n        #primer cuadrante\n        rows_start = 0\n        rows_limit = int(board.number_of_rows/2-1)\n        colunms_start = 0\n        columns_limit = int(board.number_of_columns/2-1)\n        self.__set_obstacles_in_cuadrant(board,rows_start,rows_limit,colunms_start,columns_limit,NUMBER_OF_OBSTACLES)\n        #segundo cuadrante\n        rows_start = int(board.number_of_rows/2)\n        rows_limit = board.number_of_rows-1\n        colunms_start = 0\n        columns_limit = int(board.number_of_columns/2-1)\n        self.__set_obstacles_in_cuadrant(board,rows_start,rows_limit,colunms_start,columns_limit,NUMBER_OF_OBSTACLES)\n        #tercer cuadrante\n        rows_start = 0\n        rows_limit = int(board.number_of_rows/2-1)\n        colunms_start = int(board.number_of_columns/2)\n        columns_limit = board.number_of_columns-1\n        self.__set_obstacles_in_cuadrant(board,rows_start,rows_limit,colunms_start,columns_limit,NUMBER_OF_OBSTACLES)\n        #cuarto cuadrante\n        rows_start = int(board.number_of_rows/2)\n        rows_limit = board.number_of_rows-1\n        colunms_start = int(board.number_of_columns/2)\n        columns_limit = board.number_of_columns-1\n        self.__set_obstacles_in_cuadrant(board,rows_start,rows_limit,colunms_start,columns_limit,NUMBER_OF_OBSTACLES)\n\nclass BoardChecker(AbstractBoardChecker): #comprueba que ni Mickey ni la salida están bloqueados por obstáculos\n    def __check_position(self,board:AbstractBoardGenerator,row:int,column:int): #este método privado revisa que Mickey o la Salida no estén rodeados por obstáculos devolviendo un boolean\n        valid_position = True\n        if row == 5:\n            if board.board[row-1][column] == \"⬛️\" and board.board[row][column-1] == \"⬛️\" and board.board[row][column+1] == \"⬛️\":\n                valid_position = False\n        elif column == 5:\n            if board.board[row-1][column] == \"⬛️\" and board.board[row+1][column] == \"⬛️\" and board.board[row][column-1] == \"⬛️\":\n                valid_position = False\n        elif row == 0:\n            if board.board[row][column+1] == \"⬛️\" and board.board[row+1][column] == \"⬛️\" and board.board[row][column-1] == \"⬛️\":\n                valid_position = False\n        elif column == 0:\n            if board.board[row-1][column] == \"⬛️\" and board.board[row+1][column] == \"⬛️\" and board.board[row][column+1] == \"⬛️\":\n                valid_position = False\n        elif row == 0 and column == 0:\n            if board.board[row+1][column] == \"⬛️\" and board.board[row][column+1] == \"⬛️\":\n                valid_position = False\n        elif row == 5 and column == 5:\n            if board.board[row-1][column] == \"⬛️\" and board.board[row][column-1] == \"⬛️\":\n                valid_position = False\n        elif row == 0 and column == 5:\n            if board.board[row+1][column] == \"⬛️\" and board.board[row][column-1] == \"⬛️\":\n                valid_position = False\n        elif row == 5 and column == 0:\n            if board.board[row-1][column] == \"⬛️\" and board.board[row][column+1] == \"⬛️\":\n                valid_position = False\n        else:\n            if board.board[row-1][column] == \"⬛️\" and board.board[row+1][column] == \"⬛️\" and board.board[row][column-1] == \"⬛️\" and board.board[row][column+1] == \"⬛️\":\n                valid_position = False\n\n        return valid_position\n\n    #Este método confirma el tablero apoyándose en __check_position. Si Mickey o la salida están rodeados, genera un nuevo tablero y lo comprueba de manera recursiva\n    def confirm_board(self, board: AbstractBoardGenerator,place_mickey_and_exit:AbstractPlaceMickeyAndExit,obstacle_generator:AbstractObstaclesGenerator):\n        if not self.__check_position(board,board.mickey_row,board.mickey_column) or not self.__check_position(board,board.out_row,board.out_column):\n            board.create_blank_board()\n            board.mickey_row,board.mickey_column,board.out_row,board.out_column = place_mickey_and_exit.place_mickey_and_exit(board)\n            obstacle_generator.place_obstacles(board)\n            self.confirm_board(board,place_mickey_and_exit,obstacle_generator)\n        else:\n            pass\n\nclass BoardPrinter(AbstractBoardPrinter): #imprime el tablero por consola\n    def print_board(self,board:AbstractBoardGenerator):\n        row_printed = \"\"\n        index = 0\n        for row in board.board:\n            for index,column in enumerate(row):\n                if index == len(row)-1:\n                    row_printed += f\"{row[index]}\\n\"\n                else:\n                    row_printed += f\"{row[index]}  \"\n            print (row_printed)\n            row_printed = \"\"\n\nclass BoardGenerator(AbstractBoardGenerator): #genera el tablero en blanco y usa el resto de métodos para generar los obstáculos y colocar a Mickey y la salida\n    def create_blank_board(self):\n        for i in range (0,self.number_of_rows):\n            row = []\n            for index in range(0,self.number_of_columns):\n                row.append(\"⬜️\")\n            self.board.append(row)\n\n    def create_board(self,number_of_rows:int,number_of_columns:int,place_mickey_and_exit:AbstractPlaceMickeyAndExit,place_obstacles:AbstractObstaclesGenerator,confirm_board:AbstractBoardChecker):\n        self.number_of_rows:int = number_of_rows\n        self.number_of_columns:int = number_of_columns\n        self.board:list = []\n        self.create_blank_board()\n        self.mickey_row,self.mickey_column,self.out_row,self.out_column = place_mickey_and_exit.place_mickey_and_exit(self)\n        place_obstacles.place_obstacles(self)\n        confirm_board.confirm_board(self,place_mickey_and_exit,place_obstacles)\n        return self.mickey_row,self.mickey_column,self.out_row,self.out_column\n\nclass MoveChecker(AbstractMoveChecker): #con este método comprueba que el movimiento es válido y si ha llegado a la salida o no.\n    def check_move(self,board:AbstractBoardGenerator,move:AbstractMickeyMove):\n        exit = False\n        if move.up:\n            if board.mickey_row == 0:\n                print(\"Mickey no puede avanzar en esa dirección, se chocaría con la pared del laberinto\\n\")\n                move.up = False\n            else:\n                row = board.mickey_row\n                board.mickey_row -= 1\n                if board.board[board.mickey_row][board.mickey_column] == \"🚪\":\n                    board.board[row][board.mickey_column] =\"⬜️\"\n                    print(\"¡Mickey ha conseguido salir del laberinto!\\n\")\n                    exit = True\n                elif board.board[board.mickey_row][board.mickey_column] != \"⬛️\":\n                        board.board[board.mickey_row][board.mickey_column] = \"🐭\"\n                        board.board[row][board.mickey_column] =\"⬜️\"\n                        move.up = False\n                else:\n                    print(\"Mickey no se puede mover ahi, hay un obstáculo en el camino\\n\")\n                    board.mickey_row = row\n                    move.up = False\n        elif move.down:\n            row = board.mickey_row\n            try:\n                board.mickey_row +=1\n                if board.board[board.mickey_row][board.mickey_column] == \"🚪\":\n                    board.board[row][board.mickey_column] =\"⬜️\"\n                    print(\"¡Mickey ha conseguido salir del laberinto!\\n\")\n                    exit = True\n                elif board.board[board.mickey_row][board.mickey_column] != \"⬛️\":\n                        board.board[board.mickey_row][board.mickey_column] = \"🐭\"\n                        board.board[row][board.mickey_column] =\"⬜️\"\n                        move.down = False\n                else:\n                    print(\"Mickey no se puede mover ahi, hay un obstáculo en el camino\\n\")\n                    board.mickey_row = row\n                    move.down = False\n            except IndexError:\n                print(\"Mickey no puede avanzar en esa dirección, se chocaría con la pared del laberinto\\n\")\n                move.down = False\n        elif move.left:\n            if board.mickey_column == 0:\n                print(\"Mickey no puede avanzar en esa dirección, se chocaría con la pared del laberinto\\n\")\n                move.left = False\n            else:\n                column = board.mickey_column\n                board.mickey_column -= 1\n                if board.board[board.mickey_row][board.mickey_column] == \"🚪\":\n                    board.board[board.mickey_row][column] =\"⬜️\"\n                    print(\"¡Mickey ha conseguido salir del laberinto!\\n\")\n                    exit = True\n                elif board.board[board.mickey_row][board.mickey_column] != \"⬛️\":\n                    board.board[board.mickey_row][board.mickey_column] = \"🐭\"\n                    board.board[board.mickey_row][column] =\"⬜️\"\n                    move.left = False\n                else:\n                    print(\"Mickey no se puede mover ahi, hay un obstáculo en el camino\\n\")\n                    board.mickey_column = column\n                    move.left = False\n        elif move.right:\n            column = board.mickey_column\n            try:\n                board.mickey_column += 1\n                if board.board[board.mickey_row][board.mickey_column] == \"🚪\":\n                    board.board[board.mickey_row][column] =\"⬜️\"\n                    print(\"¡Mickey ha conseguido salir del laberinto!\\n\")\n                    exit = True\n                elif board.board[board.mickey_row][board.mickey_column] != \"⬛️\":\n                    board.board[board.mickey_row][board.mickey_column] = \"🐭\"\n                    board.board[board.mickey_row][column] =\"⬜️\"\n                    move.right = False\n                else:\n                    print(\"Mickey no se puede mover ahi, hay un obstáculo en el camino\\n\")\n                    board.mickey_column = column\n                    move.right = False\n            except IndexError:\n                print(\"Mickey no puede avanzar en esa dirección, se chocaría con la pared del laberinto\\n\")\n                move.right = False\n        return exit\n\nclass MickeyMove(AbstractMickeyMove): #clase para el movimiento de Mickey\n    def __init__(self):\n        self.up:bool = False\n        self.down:bool = False\n        self.right:bool = False\n        self.left:bool = False\n\n    def move_up(self):\n        self.up = True\n        return self\n\n    def move_down(self):\n        self.down = True\n        return self\n\n    def move_left(self):\n        self.left = True\n        return self\n\n    def move_right(self):\n        self.right = True\n        return self\n\nexit = False\nNUMBER_OF_ROWS = 6 #se podría solicitar el tamaño del tablero por consola.\nNUMBER_OF_COLUMNS = 6\nboard = BoardGenerator()\nmickey_row,mickey_column,out_row,out_column = board.create_board(NUMBER_OF_ROWS,NUMBER_OF_COLUMNS,PlaceMickeyAndExit(),ObstaclesGenerator(),BoardChecker())\nboard_printer = BoardPrinter()\nprint(\"Te doy la bienvenida al Laberinto del D23 en el que tendrás que ayudar a Mickey a escapar\\n\")\nboard_printer.print_board(board)\nprint(\"\\n\")\nmickey_move = MickeyMove()\nmove_checker = MoveChecker()\nwhile not exit:\n    input_move = input(\"¿Hacia donde quieres mover a Mickey?\\n- Arriba (U)\\n- Abajo (D)\\n- Izquierda (L)\\n- Derecha (R)\\n Introduce el movimiento por favor: \").upper()\n    if input_move == \"U\":\n        move = mickey_move.move_up()\n    elif input_move == \"D\":\n        move = mickey_move.move_down()\n    elif input_move == \"L\":\n        move = mickey_move.move_left()\n    elif input_move == \"R\":\n        move = mickey_move.move_right()\n    else:\n        print(\"Vaya, parece que Mickey no puede hacer ese movimiento, probemos de nuevo...\")\n    exit = move_checker.check_move(board,move)\n    board_printer.print_board(board)\n    print(\"\\n\")\n\nprint(\"Enhorabuena y gracias por ayudar a Mickey a salir del laberinto. Hasta pronto.\")\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/python/cristianfloyd.py",
    "content": "# EJERCICIO:\n# ¡Disney ha presentado un montón de novedades en su D23!\n# Pero... ¿Dónde está Mickey?\n# Mickey Mouse ha quedado atrapado en un laberinto mágico\n# creado por Maléfica.\n# Desarrolla un programa para ayudarlo a escapar.\n# Requisitos:\n# 1. El laberinto está formado por un cuadrado de 6x6 celdas.\n# 2. Los valores de las celdas serán:\n#    - ⬜️ Vacío\n#    - ⬛️ Obstáculo\n#    - 🐭 Mickey\n#    - 🚪 Salida\n# Acciones:\n# 1. Crea una matriz que represente el laberinto (no hace falta\n# que se genere de manera automática).\n# 2. Interactúa con el usuario por consola para preguntarle hacia\n# donde se tiene que desplazar (arriba, abajo, izquierda o derecha).\n# 3. Muestra la actualización del laberinto tras cada desplazamiento.\n# 4. Valida todos los movimientos, teniendo en cuenta los límites\n# del laberinto y los obstáculos. Notifica al usuario.\n# 5. Finaliza el programa cuando Mickey llegue a la salida.\n\nimport os\nfrom dataclasses import dataclass\nfrom enum import Enum\nfrom typing import Dict\n\n\n@dataclass(frozen=True)\nclass Coordenada:\n    # constantes\n    LIMITES_X = (0, 5)\n    LIMITES_Y = (0, 5)\n\n    x: int\n    y: int\n\n    @classmethod\n    def esta_dentro(cls, coordenada: \"Coordenada\") -> bool:\n        return (\n            cls.LIMITES_X[0] <= coordenada.x <= cls.LIMITES_X[1]\n            and cls.LIMITES_Y[0] <= coordenada.y <= cls.LIMITES_Y[1]\n        )\n\n    def __add__(self, other: \"Coordenada\") -> \"Coordenada\":\n        return Coordenada(self.x + other.x, self.y + other.y)\n\n    def __repr__(self) -> str:\n        return f\"({self.x}, {self.y})\"\n\n    def __eq__(self, other: object) -> bool:\n        if not isinstance(other, Coordenada):\n            return NotImplemented\n        return self.x == other.x and self.y == other.y\n\n    def __hash__(self) -> int:\n        return hash((self.x, self.y))\n\n    def distancia(self, other: \"Coordenada\") -> int:\n        return abs(self.x - other.x) + abs(self.y - other.y)\n\n\nclass Movimiento(Enum):\n    UP = Coordenada(0, -1)\n    DOWN = Coordenada(0, 1)\n    LEFT = Coordenada(-1, 0)\n    RIGHT = Coordenada(1, 0)\n\n    @classmethod\n    def up(cls) -> \"Movimiento\":\n        return cls.UP\n\n    @classmethod\n    def down(cls) -> \"Movimiento\":\n        return cls.DOWN\n\n    @classmethod\n    def left(cls) -> \"Movimiento\":\n        return cls.LEFT\n\n    @classmethod\n    def right(cls) -> \"Movimiento\":\n        return cls.RIGHT\n\n    @classmethod\n    def get(cls, movimiento: str) -> \"Movimiento | None\":\n        match movimiento.lower().strip():\n            case \"arriba\":\n                return cls.UP\n            case \"abajo\":\n                return cls.DOWN\n            case \"izquierda\":\n                return cls.LEFT\n            case \"derecha\":\n                return cls.RIGHT\n            case _:\n                return None\n\n\nclass Celda(Enum):\n    VACIO = \"0\"\n    OBSTACULO = \"1\"\n    MICKEY = \"2\"\n    SALIDA = \"3\"\n\n    @classmethod\n    def get(cls, valor: str) -> \"Celda | None\":\n        match valor:\n            case \"0\":\n                return cls.VACIO\n            case \"1\":\n                return cls.OBSTACULO\n            case \"2\":\n                return cls.MICKEY\n            case \"3\":\n                return cls.SALIDA\n            case _:\n                return None\n\n    def emoji(self) -> str:\n        mapa_emojis = {\n            Celda.VACIO: \"⬜️\",\n            Celda.OBSTACULO: \"⬛️\",\n            Celda.MICKEY: \"🐭\",\n            Celda.SALIDA: \"🚪\",\n        }\n        return mapa_emojis.get(self, \"\")\n\n\nclass Laberinto:\n    def __init__(self, laberinto: Dict[Coordenada, Celda]):\n        self.laberinto = laberinto\n        self.posicion_mickey = self.find_mickey()\n        self.posicion_salida = self.find_salida()\n\n    def get_cell(self, coordenada: Coordenada) -> Celda:\n        return self.laberinto.get(coordenada, Celda.VACIO)\n\n    def es_transitable(self, coordenada: Coordenada) -> bool:\n        if coordenada.esta_dentro(coordenada):\n            return self.get_cell(coordenada) != Celda.OBSTACULO\n        return False\n\n    def move_mickey(self, movimiento: Movimiento) -> bool:\n        if self.posicion_mickey is None:\n            return False\n        vector = movimiento.value\n        to_coord = self.posicion_mickey + vector\n        if to_coord.esta_dentro(to_coord):\n            if self.es_transitable(to_coord):\n                # donde estaba mickey ahora esta vacio\n                self.laberinto[self.posicion_mickey] = Celda.VACIO\n                # actualizo la posicion de mickey\n                self.posicion_mickey = to_coord\n                # solo dibujo si no esta en la salida\n                if to_coord != self.posicion_salida:\n                    self.laberinto[self.posicion_mickey] = Celda.MICKEY\n                return True\n        return False\n\n    def find_mickey(self) -> Coordenada | None:\n        for coordenada, valor in self.laberinto.items():\n            if valor == Celda.MICKEY:\n                return coordenada\n        return None\n\n    def find_salida(self) -> Coordenada | None:\n        for coordenada, valor in self.laberinto.items():\n            if valor == Celda.SALIDA:\n                return coordenada\n        return None\n\n    def mostrar(self) -> None:\n        \"\"\"\n        Muestra el laberinto en la consola.\n        \"\"\"\n        for y in range(6):\n            fila = \"\"\n            for x in range(6):\n                coordenada = Coordenada(x, y)\n                fila += self.get_cell(coordenada).emoji()\n            print(fila)\n\n    @classmethod\n    def crear_desde_mapa(cls, mapa: list[str]) -> \"Laberinto\":\n        laberinto: Dict[Coordenada, Celda] = {}\n        mensaje = cls.verificar_mapa(mapa)\n        if mensaje:\n            raise ValueError(mensaje)\n        for y, fila in enumerate(mapa):\n            celdas: list[str] = list(fila)\n            for x, valor in enumerate(celdas):\n                laberinto[Coordenada(x, y)] = Celda(valor)\n\n        return cls(laberinto)\n\n    def esta_en_salida(self) -> bool:\n        return self.posicion_mickey == self.posicion_salida\n\n    @classmethod\n    def verificar_mapa(cls, mapa: list[str]) -> str:\n        errores: list[str] = []\n        if len(mapa) != 6:\n            errores.append(\"\\nEl mapa debe tener 6 filas\")\n        for fila in mapa:\n            if len(fila) != 6:\n                errores.append(\"\\nEl mapa debe tener 6 columnas\")\n        # verifico valores enteros en el rango 0-3\n        for fila in mapa:\n            for valor in fila:\n                if not valor.isdigit():\n                    errores.append(\"\\nEl mapa debe tener valores enteros\")\n                elif int(valor) not in range(4):\n                    errores.append(\"\\nEl mapa debe tener valores enteros en el rango 0-3\")\n        # verifico que haya una salida y que sea solo una\n        contador_salida: int = 0\n        for fila in mapa:\n            if \"3\" in fila:\n                contador_salida += 1\n        if contador_salida == 0:\n            errores.append(\"\\nEl mapa debe tener una salida\")\n        elif contador_salida > 1:\n            errores.append(\"\\nEl mapa debe tener una sola salida\")\n        # verifico que haya un mickey\n        contador_mickey: int = 0\n        for fila in mapa:\n            if \"2\" in fila:\n                contador_mickey += 1\n        if contador_mickey != 1:\n            errores.append(\"\\nEl mapa debe tener un mickey\")\n        return \"\\n\".join(errores)\n\n\nclass MotorJuego:\n    def __init__(self, laberinto: Laberinto):\n        self.laberinto = laberinto\n        self.movimiento = Movimiento\n        self.mensaje = \"\"\n\n    def jugar(self):\n        while True:\n            # limpiar la consola\n            os.system(\"cls\" if os.name == \"nt\" else \"clear\")\n            # mostrar el laberinto\n            self.laberinto.mostrar()\n            # mostrar mensaje\n            print(\"\\n\")\n            print(self.mensaje)\n            print(\"-\" * 20)\n            # pedir movimiento\n            movimiento = (\n                input(\"Movimiento (arriba, abajo, izquierda, derecha, salir): \")\n                .lower()\n                .strip()\n            )\n            if movimiento == \"salir\":\n                break\n            movimiento = self.movimiento.get(movimiento)\n            if movimiento is None:\n                self.mensaje = \"Movimiento no válido\"\n                continue\n            if self.laberinto.move_mickey(movimiento):\n                if self.laberinto.esta_en_salida():\n                    self.mensaje = \"¡Mickey ha escapado!\"\n                    os.system(\"cls\" if os.name == \"nt\" else \"clear\")\n                    self.laberinto.mostrar()\n                    print(f\"\\n{self.mensaje}\")\n                    break\n                else:\n                    self.mensaje = \"\"\n            else:\n                self.mensaje = \"¡Cuidado! Hay un obstáculo o intentas salir del laberinto.\"\n\n\ndef main():\n    mapa = [\"201000\", \"011010\", \"000010\", \"111110\", \"000000\", \"011113\"]\n    try:\n        laberinto = Laberinto.crear_desde_mapa(mapa)\n    except ValueError as e:\n        print(f\"Error: {e}\")\n        return\n    motor_juego = MotorJuego(laberinto)\n    motor_juego.jugar()\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/python/d1d4cum.py",
    "content": "from abc import ABC, abstractmethod\nfrom typing import Tuple\n\n\nclass MazeInterface(ABC):\n    @abstractmethod\n    def get_cell(self, position: Tuple[int, int]) -> str:\n        pass\n\n    @abstractmethod\n    def update_maze(self, character_position: Tuple[int, int], last_position: Tuple[int, int]):\n        pass\n\n    @abstractmethod\n    def print_maze(self):\n        pass\n\n\nclass Character:\n    finish: bool\n    up: str\n    right: str\n    left: str\n    down: str\n    last_position: Tuple[int, int]\n    position: Tuple[int, int]\n    maze: MazeInterface\n\n    def __init__(self, maze: MazeInterface):\n        self.finish = False\n        self.up = '⬜'\n        self.right = '⬛'\n        self.left = '⬛'\n        self.down = ''\n        self.last_position = (0, 0)\n        self.position = (5, 2)\n        self.maze = maze\n        self.update_character_elements()\n\n    def move_up(self):\n        match self.up:\n            case '⬜':\n                print(\"Avanza hacia arriba\")\n                self.last_position = self.position\n                self.position = (self.position[0] - 1, self.position[1])\n                self.update_character_elements()\n            case '⬛':\n                print(\"Hay un obstáculo\")\n            case '':\n                print(\"Estás en el límite del mapa\")\n            case '🚪':\n                print(\"Llegaste a la salida\")\n                self.finish = True\n\n    def move_right(self):\n        match self.right:\n            case '⬜':\n                print(\"Avanza hacia la derecha\")\n                self.last_position = self.position\n                self.position = (self.position[0], self.position[1] + 1)\n                self.update_character_elements()\n            case '⬛':\n                print(\"Hay un obstáculo\")\n            case '':\n                print(\"Estás en el límite del mapa\")\n            case '🚪':\n                print(\"Llegaste a la salida\")\n                self.finish = True\n\n    def move_left(self):\n        match self.left:\n            case '⬜':\n                print(\"Avanza hacia la izquierda\")\n                self.last_position = self.position\n                self.position = (self.position[0], self.position[1] - 1)\n                self.update_character_elements()\n            case '⬛':\n                print(\"Hay un obstáculo\")\n            case '':\n                print(\"Estás en el límite del mapa\")\n            case '🚪':\n                print(\"Llegaste a la salida\")\n                self.finish = True\n\n    def move_down(self):\n        match self.down:\n            case '⬜':\n                print(\"Avanza hacia abajo\")\n                self.last_position = self.position\n                self.position = (self.position[0] + 1, self.position[1])\n                self.update_character_elements()\n            case '⬛':\n                print(\"Hay un obstáculo\")\n            case '':\n                print(\"Estás en el límite del mapa\")\n            case '🚪':\n                print(\"Llegaste a la salida\")\n                self.finish = True\n\n    def update_character_elements(self):\n        # Positions around the character\n        up = (self.position[0] - 1, self.position[1])\n        down = (self.position[0] + 1, self.position[1])\n        right = (self.position[0], self.position[1] + 1)\n        left = (self.position[0], self.position[1] - 1)\n\n        self.up = self.maze.get_cell(up)\n        self.down = self.maze.get_cell(down)\n        self.right = self.maze.get_cell(right)\n        self.left = self.maze.get_cell(left)\n\n\nclass Maze(MazeInterface):\n    maze = [['🚪', '⬜', '⬛', '⬛', '⬛', '⬛'],\n            ['⬛', '⬜', '⬛', '⬛', '⬛', '⬛'],\n            ['⬛', '⬜', '⬜', '⬜', '⬛', '⬛'],\n            ['⬛', '⬛', '⬛', '⬜', '⬛', '⬛'],\n            ['⬛', '⬛', '⬜', '⬜', '⬛', '⬛'],\n            ['⬛', '⬛', '🐭', '⬛', '⬛', '⬛']]\n\n    def get_cell(self, position: Tuple[int, int]) -> str:\n        if 0 <= position[0] < len(self.maze) and 0 <= position[1] < len(self.maze[0]):\n            return self.maze[position[0]][position[1]]\n        return ''\n\n    def update_maze(self, character_position: Tuple[int, int], last_position: Tuple[int, int]):\n        self.maze[character_position[0]][character_position[1]] = '🐭'\n        self.maze[last_position[0]][last_position[1]] = '⬜'\n\n    def print_maze(self):\n        for row in self.maze:\n            actual_row = \"\"\n            for element in row:\n                actual_row += element\n            print(actual_row)\n\n\ndef main():\n    maze = Maze()\n    character = Character(maze)\n\n    while not character.finish:\n        maze.print_maze()\n        print(\"\\nMovimiento de Mickey:\"\n              \"\\n- Arriba\"\n              \"\\n- Abajo\"\n              \"\\n- Derecha\"\n              \"\\n- Izquierda\")\n        option = input(\"> \").lower()\n        print(\"\")\n\n        match option:\n            case \"arriba\":\n                character.move_up()\n            case \"abajo\":\n                character.move_down()\n            case \"derecha\":\n                character.move_right()\n            case \"izquierda\":\n                character.move_left()\n            case _:\n                print(\"⚠️Opción incorrecta\")\n\n        maze.update_maze(character.position, character.last_position)\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/python/davidrguez98.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * ¡Disney ha presentado un montón de novedades en su D23! \n * Pero... ¿Dónde está Mickey?\n * Mickey Mouse ha quedado atrapado en un laberinto mágico \n * creado por Maléfica.\n * Desarrolla un programa para ayudarlo a escapar.\n * Requisitos:\n * 1. El laberinto está formado por un cuadrado de 6x6 celdas.\n * 2. Los valores de las celdas serán:\n *    - ⬜️ Vacío\n *    - ⬛️ Obstáculo\n *    - 🐭 Mickey\n *    - 🚪 Salida\n * Acciones:\n * 1. Crea una matriz que represente el laberinto (no hace falta\n * que se genere de manera automática).\n * 2. Interactúa con el usuario por consola para preguntarle hacia\n * donde se tiene que desplazar (arriba, abajo, izquierda o derecha).\n * 3. Muestra la actualización del laberinto tras cada desplazamiento.\n * 4. Valida todos los movimientos, teniendo en cuenta los límites\n * del laberinto y los obtáculos. Notifica al usuario.\n * 5. Finaliza el programa cuando Mickey llegue a la salida.\n */ \"\"\"\n\n#EJERCICIO\n\nmaze = [\n    [\"🐭\", \"⬛️\", \"⬛️\", \"⬛️\", \"⬛️\", \"⬛️\",],\n    [\"⬜️\", \"⬛️\", \"⬛️\", \"⬛️\", \"⬜️\", \"⬛️\",],\n    [\"⬜️\", \"⬛️\", \"⬛️\", \"⬛️\", \"⬜️\", \"⬛️\",],\n    [\"⬜️\", \"⬜️\", \"⬜️\", \"⬜️\", \"⬜️\", \"⬜️\",],\n    [\"⬛️\", \"⬜️\", \"⬛️\", \"⬜️\", \"⬛️\", \"⬛️\",],\n    [\"⬛️\", \"⬛️\", \"⬛️\", \"⬜️\", \"⬜️\", \"🚪\",]\n]\n\ndef print_maze():\n    for row in maze:\n        print(\"\".join(row))\n    print()\n\nmickey = [0, 0]\n\nwhile True:\n\n    print_maze()\n\n    print(\"¿Hacia donde se mueve Mickey?\")\n    print(\"[w] Arriba\")\n    print(\"[s] Abajo\")\n    print(\"[a] Izquierda\")\n    print(\"[d] Derecha\")\n    direction = input(\"Dirección: \")\n\n    current_row, current_column = mickey\n    new_row, new_column = current_row, current_column\n\n    match direction:\n        case \"w\":\n            new_row = current_row - 1\n        case \"s\":\n            new_row = current_row + 1\n        case \"a\":\n            new_column = current_column - 1\n        case \"d\":\n            new_column = current_column + 1\n        case _:\n            print(\"Dirección no valida.\\n\")\n            continue\n\n    if new_row < 0 or new_row > 5 or new_column < 0 or new_column > 5:\n        print(\"No puedes desplazarte fuera del laberinto.\\n\")\n        continue\n    else:\n        if maze[new_row][new_column] == \"⬛️\":\n            print(\"En esa dirección hay un obstáculo.\\n\")\n            continue\n        elif maze[new_row][new_column] == \"🚪\":\n            print(\"¡Has econtrado la salida!.\")\n            print_maze()\n            break\n        else:\n            maze[current_row][current_column] = \"⬜️\"\n            maze[new_row][new_column] = \"🐭\"\n            mickey = new_row, new_column"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/python/duendeintemporal.py",
    "content": "#33 { Retos para Programadores } RESCATANDO A MICKEY \n\n# Bibliography reference:\n# I use GPT as a reference and sometimes to correct or generate proper comments.\n\n\"\"\"  \n* EJERCICIO:\n * ¡Disney ha presentado un montón de novedades en su D23!\n * Pero... ¿Dónde está Mickey?\n * Mickey Mouse ha quedado atrapado en un laberinto mágico\n * creado por Maléfica.\n * Desarrolla un programa para ayudarlo a escapar.\n * Requisitos:\n * 1. El laberinto está formado por un cuadrado de 6x6 celdas.\n * 2. Los valores de las celdas serán:\n *    - ⬜️ Vacío\n *    - ⬛️ Obstáculo\n *    - 🐭 Mickey\n *    - 🚪 Salida\n * Acciones:\n * 1. Crea una matriz que represente el laberinto (no hace falta\n * que se genere de manera automática).\n * 2. Interactúa con el usuario por consola para preguntarle hacia\n * donde se tiene que desplazar (arriba, abajo, izquierda o derecha).\n * 3. Muestra la actualización del laberinto tras cada desplazamiento.\n * 4. Valida todos los movimientos, teniendo en cuenta los límites\n * del laberinto y los obtáculos. Notifica al usuario.\n * 5. Finaliza el programa cuando Mickey llegue a la salida.\n\n\"\"\"\n\n\"\"\" \nNote: If you are using Command Prompt(cmd or Shell in Windows), you may need to change the code page to UTF-8 to properly display emojis. You can do this by running the following command before executing your script:\n\nchcp 65001\n\nAlso set the font type to: Segoe UI Emoji or Noto Color Emoji is available. (if this doesn't work you will need to install Windows Terminal to to properly display emojis)\n\n\"\"\"\n\nlog = print\n\nimport random\n\n# Constants for the maze\nobstacle = '\\u2B1B'  # ⬛️ Obstacle\nempty_space = '\\u2B1C'  # ⬜️ Empty space\nmickey = '\\U0001F42D'  # 🐭 Mickey\nexit = '\\U0001F6AA'  # 🚪 Exit\n\n# Start position for Mickey\nposition = {'x': 0, 'y': 0}\n\n# Function to generate a random maze with obstacles\ndef generate_random_maze(size):\n    maze = [[obstacle if random.random() < 0.4 else empty_space for _ in range(size)] for _ in range(size)]\n    maze[0][0] = mickey  # Start position\n    maze[size - 1][size - 1] = exit  # Exit position\n    return maze\n\n# Function to carve a path in the maze using Dijkstra's algorithm\ndef dijkstra(maze):\n    size = len(maze)\n    directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]\n    distances = [[float('inf')] * size for _ in range(size)]\n    previous = [[None] * size for _ in range(size)]\n    distances[0][0] = 0  # Distance from the entrance is 0\n    queue = [(0, 0, 0)]  # (x, y, distance)\n\n    while queue:\n        x, y, distance = queue.pop(0)\n\n        if distance > distances[y][x]:\n            continue  # If the distance is greater than the current distance, do nothing\n\n        for dx, dy in directions:\n            new_x, new_y = x + dx, y + dy\n\n            if 0 <= new_x < size and 0 <= new_y < size:\n                new_distance = distance + (10 if maze[new_y][new_x] == obstacle else 1)\n\n                if new_distance < distances[new_y][new_x]:\n                    distances[new_y][new_x] = new_distance\n                    previous[new_y][new_x] = (x, y)\n                    queue.append((new_x, new_y, new_distance))\n\n    # Reconstruct the shortest path\n    path = []\n    x, y = size - 1, size - 1\n\n    while (x, y) != (0, 0):\n        if previous[y][x] is None:\n            break  # No valid path found\n        path.append((x, y))\n        x, y = previous[y][x]\n    path.reverse()  # Reverse the path to get it from start to exit\n\n    # If a path is found, mark it\n    if path:\n        for x, y in path:\n            maze[y][x] = empty_space  # Mark the path with an empty space\n\n    maze[size - 1][size - 1] = exit  # Ensure exit is not overwritten\n    return path\n\n# Function to display the maze\ndef display_maze(maze):\n    print('\\nMaze:\\n')\n    for row in maze:\n        print(' '.join(row))\n    print('\\n')\n\n# Function to move Mickey\ndef move_mickey(direction, maze):\n    global position\n    new_position = position.copy()\n\n    # Update new position based on the direction\n    if direction == \"w\":\n        new_position['y'] -= 1  # up\n    elif direction == \"s\":\n        new_position['y'] += 1  # down\n    elif direction == \"a\":\n        new_position['x'] -= 1  # left\n    elif direction == \"d\":\n        new_position['x'] += 1  # right\n\n    # Check if the new position is within the bounds of the board\n    if (0 <= new_position['x'] < len(maze[0]) and\n            0 <= new_position['y'] < len(maze)):\n        # Check if the new position is a wall or path\n        if maze[new_position['y']][new_position['x']] == obstacle:\n            print(\"Mickey 🐭 has hit a wall ⬛️, try moving in another direction.\")\n            return False  # Movement failed due to wall\n        elif maze[new_position['y']][new_position['x']] == exit:\n            print(\"\\nCongratulations! You won! Mickey 🐭 has escaped the maze.\")\n            maze[position['y']][position['x']] = empty_space  # Empty the cell\n            position = new_position\n            maze[position['y']][position['x']] = mickey  # Move\n            maze[position['y']][position['x']] = mickey  # Move 🐭 Mickey \n            return True  # Movement successful and game won\n        else:\n            # Update the position of the player\n            maze[position['y']][position['x']] = empty_space  # Empty the cell\n            position = new_position\n            maze[position['y']][position['x']] = mickey  # Move 🐭 Mickey \n            return True  # Movement successful\n    else:\n        print(\"Mickey 🐭 cannot move outside the maze, try moving in another direction.\")\n        return False  # Movement failed due to out of bounds\n\n# Main function to start the game\ndef main():\n    maze_size = int(input('Enter the size of the maze (between 7 and 15): '))\n    \n    # Validate the maze size input\n    if maze_size < 7 or maze_size > 15:\n        print('Please enter a valid number between 7 and 15.')\n        return\n    \n    # Generate the random maze\n    maze = generate_random_maze(maze_size)\n    \n    # Carve a path in the maze using Dijkstra's algorithm\n    dijkstra(maze)\n    \n    # Display the generated maze\n    display_maze(maze)\n\n    # Start the game loop\n    while True:\n        direction = input(\"Choose a direction to move (up - w, down - s, left - a, right - d): \").lower()\n        if move_mickey(direction, maze):\n            display_maze(maze)  # Display the maze after the move\n            if maze[position['y']][position['x']] == exit:\n                break  # Exit the loop if Mickey has reached the exit\n        else:\n            display_maze(maze)  # Display the maze after an unsuccessful move\n\nif __name__ == \"__main__\":\n    main()  # Start the game\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/python/fborjalv.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * ¡Disney ha presentado un montón de novedades en su D23!\n * Pero... ¿Dónde está Mickey?\n * Mickey Mouse ha quedado atrapado en un laberinto mágico\n * creado por Maléfica.\n * Desarrolla un programa para ayudarlo a escapar.\n * Requisitos:\n * 1. El laberinto está formado por un cuadrado de 6x6 celdas.\n * 2. Los valores de las celdas serán:\n *    - ⬜️ Vacío\n *    - ⬛️ Obstáculo\n *    - 🐭 Mickey\n *    - 🚪 Salida\n * Acciones:\n * 1. Crea una matriz que represente el laberinto (no hace falta\n * que se genere de manera automática).\n * 2. Interactúa con el usuario por consola para preguntarle hacia\n * donde se tiene que desplazar (arriba, abajo, izquierda o derecha).\n * 3. Muestra la actualización del laberinto tras cada desplazamiento.\n * 4. Valida todos los movimientos, teniendo en cuenta los límites\n * del laberinto y los obtáculos. Notifica al usuario.\n * 5. Finaliza el programa cuando Mickey llegue a la salida.\n */\n\n\"\"\"\nMICKEY = \"🐭\"\nEXIT = \"🚪\"\nVACIO = \"⬜️\"\nOBSTACULO = \"⬛️\"\n\nclass Mickey:\n    def __init__(self) -> None:\n        self.position_x = 0\n        self.position_y = 0\n    def move_down(self):\n        self.position_y += 1\n        print(\"Movimiento: hacia abajo\")\n    def move_up(self):\n        self.position_y -= 1\n        print(\"Movimiento: hacia arriba\")\n    def move_right(self):\n        self.position_x += 1\n        print(\"Movimiento: hacia la derecha\")\n    def move_left(self):\n        self.position_x -= 1\n        print(\"Movimiento: hacia la izquierda\")\n\n\nclass Game:\n    def __init__(self) -> None:\n        self.maze = [\n            [MICKEY, VACIO, VACIO, VACIO, OBSTACULO, VACIO],\n            [OBSTACULO, VACIO, OBSTACULO, VACIO, VACIO, VACIO],\n            [OBSTACULO, VACIO, OBSTACULO, OBSTACULO, OBSTACULO, VACIO],\n            [OBSTACULO, VACIO, VACIO, VACIO, OBSTACULO, OBSTACULO], \n            [VACIO, VACIO, OBSTACULO, VACIO, OBSTACULO, OBSTACULO],\n            [VACIO, OBSTACULO, OBSTACULO, VACIO, VACIO, EXIT]]\n        self.player = Mickey()\n        self.print_maze()\n        self.exit_x = 5\n        self.exit_y = 5\n\n    def print_maze(self):\n        print(f\"Player position: {self.player.position_x + 1}, {self.player.position_y + 1}\")\n        for fila in self.maze:\n            print(' '.join(map(str, fila)))\n\n\n    def move_player(self):\n        move = input(\"Introduce la dirección hacia la que se mueve Mickey: \")\n        match move:\n                case \"a\":\n                    if self.player.position_x > 0 and self.maze[self.player.position_y][self.player.position_x - 1] != OBSTACULO:\n                        self.maze[self.player.position_y][self.player.position_x] = VACIO\n                        self.player.move_left()\n                        self.maze[self.player.position_y][self.player.position_x] = MICKEY\n                    else:\n                        print(\"No puede seguir avanzado por la izquierda\")\n                case \"d\":\n                    if self.player.position_x < len(self.maze[0])-1 and self.maze[self.player.position_y][self.player.position_x + 1] != OBSTACULO:\n                        self.maze[self.player.position_y][self.player.position_x] = VACIO\n                        self.player.move_right()\n                        self.maze[self.player.position_y][self.player.position_x] = MICKEY\n                    else:\n                        print(\"No puede seguir avanzado por la derecha\")\n                case \"s\":\n                    if self.player.position_y < len(self.maze) -1 and self.maze[self.player.position_y + 1][self.player.position_x] != OBSTACULO:\n                        self.maze[self.player.position_y][self.player.position_x] = VACIO\n                        self.player.move_down()\n                        self.maze[self.player.position_y][self.player.position_x] = MICKEY\n                    else:\n                        print(\"No puede seguir avanzado hacia abajo\")\n                case \"w\":\n                    if self.player.position_y > 0 and self.maze[self.player.position_y - 1][self.player.position_x] != OBSTACULO:\n                        self.maze[self.player.position_y][self.player.position_x] = VACIO\n                        self.player.move_up()\n                        self.maze[self.player.position_y][self.player.position_x] = MICKEY\n                    else: \n                        print(\"No puede seguir avazando hacia arriba\")\n                case _:\n                    print(\"Introduce un valor correcto\") \n\n    def game_on(self):\n        while True:\n            if self.player.position_y == self.exit_x and self.player.position_x == self.exit_y:\n                print(\"HAS GANADO!!\")\n                break\n            else: \n                self.move_player()\n                self.print_maze()\n            \n\nsystem = Game()\nsystem.game_on()\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/python/franxiscodev.py",
    "content": "maze = [\n    [\"🐭\", \"◼️\", \"◼️\", \"◼️\", \"◼️\", \"◼️\"],\n    [\"◽\", \"◼️\", \"◼️\", \"◼️\", \"◼️\", \"◼️\"],\n    [\"◽\", \"◼️\", \"◼️\", \"◼️\", \"◽\", \"◼️\"],\n    [\"◽\", \"◽\", \"◽\", \"◽\", \"◽\", \"◽\"],\n    [\"◼️\", \"◽\", \"◼️\", \"◽\", \"◼️\", \"◼️\"],\n    [\"◼️\", \"◽\", \"◼️\", \"◽\", \"◽\", \"◽\"],\n    [\"◽\", \"◽\", \"◼️\", \"◼️\", \"◼️\", \"📤\"]\n]\n\n\ndef print_maze():\n    for row in maze:\n        print(\"\".join(row))\n\n\nmicky_position = [0, 0]  # Posición inicial de Mickey Mouse\nprint(\"Bienvenido a la aventura de Mickey Mouse!\")\nprint(\"Mickey Mouse se encuentra atrapado en un laberinto y necesita tu ayuda para escapar.\")\nprint(\"El laberinto es el siguiente:\")\nprint_maze()\n\n# Preguntar al usuario si quiere jugar\nplay = input(\n    \"¿Quieres ayudar a Mickey Mouse a escapar del laberinto? (s/n): \").lower()\nif play != \"s\":\n    print(\"¡Hasta luego!\")\n    exit()\n\nwhile True:\n    # Preguntar al usuario por la dirección\n    direction = input(\n        \"¿En qué dirección quieres mover a Mickey Mouse? \\n[u] arriba \\n[d] abajo \\n[l] izquierda \\n[r] derecha \\n: \").lower()\n\n    current_row, current_col = micky_position\n    new_row, new_col = current_row, current_col\n    # Mover a Mickey Mouse en la dirección elegida\n\n    match direction:\n        case \"u\":\n            # Código para mover hacia arriba\n            new_row = current_row - 1\n        case \"d\":\n            # Código para mover hacia abajo\n            new_row = current_row + 1\n        case \"l\":\n            # Código para mover hacia la izquierda\n            new_col = current_col - 1\n        case \"r\":\n            # Código para mover hacia la derecha\n            new_col = current_col + 1\n        case _:\n            print(\"Dirección no válida. Intenta de nuevo.\")\n            continue\n    # Verificar límites del laberinto\n    if not (0 <= new_row < len(maze) and 0 <= new_col < len(maze[0])):\n        print(\"¡No puedes salir del laberinto! Intenta de nuevo.\")\n        continue\n    # Verificar si la nueva posición es un muro\n    else:\n        if maze[new_row][new_col] == \"◼️\":\n            print(\"¡Has chocado con un muro! Intenta de nuevo.\")\n            continue\n        # Verificar si la nueva posición es la salida\n        elif maze[new_row][new_col] == \"📤\":\n            print(\"¡Felicidades! Mickey Mouse ha encontrado la salida del laberinto.\")\n            break\n        # Actualizar la posición de Mickey Mouse en el laberinto\n        else:\n            maze[current_row][current_col] = \"◽\"\n            maze[new_row][new_col] = \"🐭\"\n            micky_position = [new_row, new_col]\n            print(\n                f\"Mickey Mouse se ha movido a la posición ({new_row}, {new_col})\")\n            print(\"El laberinto actualizado es el siguiente:\")\n            print_maze()\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/python/hectorio23.py",
    "content": "# Autor: Héctor Adán\n# GitHub: https://github.com/hectorio23\nimport subprocess\n\n# Imprime el estado actual del laberinto\ndef print_labyrinth(labyrinth):\n    for row in labyrinth:\n        print(\" \".join(row))\n    print()\n\n# Mueve a Mickey a una nueva posición y valida el movimiento\ndef move_mickey(labyrinth, mickey_x, mickey_y, new_x, new_y):\n    # Validación de límites del laberinto\n    if new_x < 0 or new_x >= 6 or new_y < 0 or new_y >= 6:\n        print(\"Movimiento inválido, fuera de los límites del laberinto.\")\n        return mickey_x, mickey_y, False\n    # Validación de obstáculos\n    if labyrinth[new_x][new_y] == '⬛️':\n        print(\"Movimiento inválido, obstáculo en el camino.\")\n        return mickey_x, mickey_y, False\n\n    # Actualiza la posición de Mickey\n    labyrinth[mickey_x][mickey_y] = '⬜️' # Limpia la posición anterior\n    mickey_x, mickey_y = new_x, new_y\n\n    # Verificación si Mickey ha llegado a la salida\n    if labyrinth[mickey_x][mickey_y] == '🚪':\n        print(\"¡Mickey ha escapado!\")\n        return mickey_x, mickey_y, True\n\n    labyrinth[mickey_x][mickey_y] = '🐭' # Actualiza la posición de Mickey\n    return mickey_x, mickey_y, False\n\n# Definición inicial del laberinto\nlabyrinth = [\n    ['⬜️', '⬜️', '⬜️', '⬛️', '⬛️', '⬛️'],\n    ['⬛️', '⬛️', '⬜️', '⬛️', '🚪', '⬛️'],\n    ['⬛️', '⬛️', '⬜️', '⬛️', '⬜️', '⬛️'],\n    ['⬛️', '⬛️', '⬜️', '⬜️', '⬜️', '⬛️'],\n    ['⬛️', '⬛️', '⬜️', '⬛️', '⬛️', '⬛️'],\n    ['🐭', '⬜️', '⬜️', '⬛️', '⬛️', '⬛️']\n]\n\n# Posición inicial de Mickey\nmickey_x, mickey_y = 5, 0\nescaped = False\n\n# Ciclo principal de interacción con el usuario\nwhile not escaped:\n    subprocess.call(['clear'])\n\n    print_labyrinth(labyrinth)  # Muestra el estado actual del laberinto\n    direction = input(\"Introduce dirección (arriba, abajo, izquierda, derecha): \")\n\n    # Procesa la dirección ingresada y mueve a Mickey si es válido\n    if direction == \"arriba\":\n        mickey_x, mickey_y, escaped = move_mickey(labyrinth, mickey_x, mickey_y, mickey_x - 1, mickey_y)\n    elif direction == \"abajo\":\n        mickey_x, mickey_y, escaped = move_mickey(labyrinth, mickey_x, mickey_y, mickey_x + 1, mickey_y)\n    elif direction == \"izquierda\":\n        mickey_x, mickey_y, escaped = move_mickey(labyrinth, mickey_x, mickey_y, mickey_x, mickey_y - 1)\n    elif direction == \"derecha\":\n        mickey_x, mickey_y, escaped = move_mickey(labyrinth, mickey_x, mickey_y, mickey_x, mickey_y + 1)\n    else:\n        print(\"Dirección inválida. Intenta nuevamente.\")\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/python/hozlucas28.py",
    "content": "# pylint: disable=missing-module-docstring,missing-class-docstring,missing-function-docstring,too-few-public-methods,expression-not-assigned\n\nfrom abc import ABCMeta, abstractmethod\nfrom typing import TypedDict, Literal, Self, cast\n\n# ---------------------------------------------------------------------------- #\n#                                     TYPES                                    #\n# ---------------------------------------------------------------------------- #\n\n\nCell = Literal[\"⬜️\", \"⬛️\", \"🐭\", \"🚪\"]\n\nDashboard = list[list[Cell]]\n\nPosition = TypedDict(\"Position\", {\"x\": int, \"y\": int})\n\n\n# ---------------------------------------------------------------------------- #\n#                                  EXCEPTIONS                                  #\n# ---------------------------------------------------------------------------- #\n\n\nclass ExitNotFoundException(Exception):\n    def __init__(self) -> None:\n        super().__init__(\"exit not found\")\n\n\nclass GameOverException(Exception):\n    def __init__(self) -> None:\n        super().__init__(\"game over\")\n\n\nclass InvalidPlayerPositionException(Exception):\n    def __init__(self, *, invalidPos: \"Position\") -> None:\n        super().__init__(\n            f\"position ({invalidPos['x']}, {invalidPos['y']}) is invalid for a player\"\n        )\n\n\nclass PlayerNotFoundException(Exception):\n    def __init__(self) -> None:\n        super().__init__(\"player not found\")\n\n\n# ---------------------------------------------------------------------------- #\n#                                    CLASSES                                   #\n# ---------------------------------------------------------------------------- #\n\n\n# ----------------------------------- Maze ----------------------------------- #\n\nInitialPositions = TypedDict(\"InitialPositions\", {\"exit\": Position, \"player\": Position})\n\n\nclass AbcMaze(metaclass=ABCMeta):\n    @property\n    @abstractmethod\n    def dashboard(self) -> Dashboard:\n        pass\n\n    @property\n    @abstractmethod\n    def exit_pos(self) -> Position:\n        pass\n\n    @property\n    @abstractmethod\n    def player_pos(self) -> Position:\n        pass\n\n    @player_pos.setter\n    def player_pos(self, pos: Position) -> None:\n        pass\n\n\nclass Maze(AbcMaze):\n    __dashboard: Dashboard\n    __exit_pos: Position\n    __player_pos: Position\n    __original_cell_at_player_pos: Cell\n\n    def __init__(self, *, dashboard: Dashboard) -> None:\n        initial_positions: InitialPositions = self.__get_initial_positions(\n            dashboard=dashboard\n        )\n        self.__dashboard = dashboard\n        self.__exit_pos = initial_positions[\"exit\"]\n        self.__player_pos = initial_positions[\"player\"]\n        self.__original_cell_at_player_pos = \"⬜️\"\n\n    def __get_initial_positions(self, *, dashboard: Dashboard) -> InitialPositions:\n        exit_pos: Position = {\"x\": -1, \"y\": -1}\n        player_pos: Position = {\"x\": -1, \"y\": -1}\n\n        for y, row in enumerate(iterable=dashboard):\n            for x, col in enumerate(iterable=row):\n                if col == \"🐭\":\n                    player_pos[\"x\"] = x\n                    player_pos[\"y\"] = y\n                elif col == \"🚪\":\n                    exit_pos[\"x\"] = x\n                    exit_pos[\"y\"] = y\n\n        if exit_pos[\"x\"] < 0:\n            raise ExitNotFoundException()\n\n        if player_pos[\"x\"] < 0:\n            raise PlayerNotFoundException()\n\n        return {\"exit\": exit_pos, \"player\": player_pos}\n\n    @property\n    def dashboard(self) -> Dashboard:\n        return self.__dashboard\n\n    @property\n    def exit_pos(self) -> Position:\n        return self.__exit_pos\n\n    @property\n    def player_pos(self) -> Position:\n        return self.__player_pos\n\n    @player_pos.setter\n    def player_pos(self, pos: Position) -> None:\n        if not self.__is_valid_pos_for_player(pos=pos):\n            raise InvalidPlayerPositionException(invalidPos=pos)\n\n        x, y = pos[\"x\"], pos[\"y\"]\n        px, py = self.__player_pos[\"x\"], self.__player_pos[\"y\"]\n        pre_original_cell_at_player_pos = self.__original_cell_at_player_pos\n\n        self.__original_cell_at_player_pos = self.__dashboard[y][x]\n        self.__dashboard[y][x] = \"🐭\"\n        self.__dashboard[py][px] = pre_original_cell_at_player_pos\n        self.__player_pos = pos\n\n    def __is_valid_pos(self, *, pos: Position) -> bool:\n        x, y = pos[\"x\"], pos[\"y\"]\n        dashboard = self.__dashboard\n\n        dashboard_max_y: int = len(dashboard) - 1\n        out_of_y_range: bool = y < 0 or y > dashboard_max_y\n        if out_of_y_range:\n            return False\n\n        dashboard_max_x: int = len(dashboard[0]) - 1\n        out_of_x_range: bool = x < 0 or x > dashboard_max_x\n        if out_of_x_range:\n            return False\n\n        return True\n\n    def __is_valid_pos_for_player(self, *, pos: Position) -> bool:\n        if not self.__is_valid_pos(pos=pos):\n            return False\n\n        x, y = pos[\"x\"], pos[\"y\"]\n        cell_at_pos: Cell = self.__dashboard[y][x]\n\n        obstacle_at_pos: bool = cell_at_pos == \"⬛️\"\n        return not obstacle_at_pos\n\n\n# ----------------------------------- Game ----------------------------------- #\n\ntype Move = Literal[\"down\", \"left\", \"right\", \"up\"]\n\n\nclass AbcGame(metaclass=ABCMeta):\n    @property\n    @abstractmethod\n    def game_over(self) -> bool:\n        pass\n\n    @property\n    @abstractmethod\n    def maze(self) -> AbcMaze:\n        pass\n\n    @abstractmethod\n    def move_player(self, *, _move: Move) -> Self:\n        pass\n\n\nclass Game(AbcGame):\n    __game_over: bool\n    __maze: AbcMaze\n\n    def __init__(self, *, _maze: AbcMaze) -> None:\n        self.__maze = _maze\n        self.__game_over = self.__is_game_over()\n\n    @property\n    def game_over(self) -> bool:\n        return self.__game_over\n\n    @property\n    def maze(self) -> AbcMaze:\n        return self.__maze\n\n    def move_player(self, *, _move: Move) -> Self:\n        if self.__game_over:\n            raise GameOverException()\n\n        _maze: AbcMaze = self.__maze\n\n        curren_player_pos = _maze.player_pos\n        x, y = curren_player_pos[\"x\"], curren_player_pos[\"y\"]\n\n        match _move:\n            case \"down\":\n                _maze.player_pos = {\"x\": x, \"y\": y + 1}\n            case \"left\":\n                _maze.player_pos = {\"x\": x - 1, \"y\": y}\n            case \"right\":\n                _maze.player_pos = {\"x\": x + 1, \"y\": y}\n            case \"up\":\n                _maze.player_pos = {\"x\": x, \"y\": y - 1}\n\n        self.__game_over = self.__is_game_over()\n        return self\n\n    def __is_game_over(self) -> bool:\n        _maze: AbcMaze = self.__maze\n        player_pos = _maze.player_pos\n        exit_pos = _maze.exit_pos\n\n        px, py = player_pos[\"x\"], player_pos[\"y\"]\n        ex, ey = exit_pos[\"x\"], exit_pos[\"y\"]\n\n        player_at_exit_pos: bool = px == ex and py == ey\n\n        return player_at_exit_pos\n\n\n# ---------------------------------------------------------------------------- #\n#                                     UTILS                                    #\n# ---------------------------------------------------------------------------- #\n\n\ndef print_dashboard(*, _dashboard: Dashboard) -> None:\n    print(\"[\")\n\n    for row in _dashboard:\n        print(f\" {row}\")\n\n    print(\"]\")\n\n\n# ---------------------------------------------------------------------------- #\n#                                     MAIN                                     #\n# ---------------------------------------------------------------------------- #\n\n\nmaze: Maze = Maze(\n    dashboard=[\n        [\"🚪\", \"⬛️\", \"⬛️\", \"⬛️\", \"⬛️\", \"⬛️\"],\n        [\"⬜️\", \"⬛️\", \"⬜️\", \"⬜️\", \"⬜️\", \"⬛️\"],\n        [\"⬜️\", \"⬛️\", \"⬜️\", \"⬛️\", \"⬜️\", \"⬜️\"],\n        [\"⬜️\", \"⬜️\", \"⬜️\", \"⬛️\", \"⬜️\", \"🐭\"],\n        [\"⬛️\", \"⬛️\", \"⬜️\", \"⬛️\", \"⬜️\", \"⬛️\"],\n        [\"⬛️\", \"⬛️\", \"⬜️\", \"⬜️\", \"⬜️\", \"⬛️\"],\n    ]\n)\n\ngame: Game = Game(_maze=maze)\nprint_dashboard(_dashboard=game.maze.dashboard)\n\nwhile not game.game_over:\n    move: str = input(\"\\n> Enter a move ('up', 'right', 'left', or 'down'): \")\n\n    try:\n        print()\n\n        match cast(Move, move.strip().lower()):\n            case \"down\":\n                game.move_player(_move=\"down\")\n                print_dashboard(_dashboard=game.maze.dashboard)\n\n            case \"left\":\n                game.move_player(_move=\"left\")\n                print_dashboard(_dashboard=game.maze.dashboard)\n\n            case \"right\":\n                game.move_player(_move=\"right\")\n                print_dashboard(_dashboard=game.maze.dashboard)\n\n            case \"up\":\n                game.move_player(_move=\"up\")\n                print_dashboard(_dashboard=game.maze.dashboard)\n\n            case _:\n                print(\"> Invalid move! Try again...\")\n\n    except InvalidPlayerPositionException:\n        print(\"> Player can not move down!\")\n\nprint(\"\\n> Game over!\")\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/python/idiegorojas.py",
    "content": "\"\"\"\n# 33 - Rescatando a Mickey\n\"\"\"\n# ¡Disney ha presentado un montón de novedades en su D23!\n# Pero... ¿Dónde está Mickey?\n# Mickey Mouse ha quedado atrapado en un laberinto mágico creado por Maléfica.\n# Desarrolla un programa para ayudarlo a escapar.\n\n\"\"\"\nRequisitos:\n\"\"\"\n# 1. El laberinto está formado por un cuadrado de 6x6 celdas.\n# 2. Los valores de las celdas serán:\n    # ⬜️ Vacío\n    # ⬛️ Obstáculo\n    # 🐭 Mickey\n    # 🚪 Salida\n\n\"\"\"\nAcciones:\n\"\"\"\n# 1. Crea una matriz que represente el laberinto (no hace falta que se genere de manera automática).\n# 2. Interactúa con el usuario por consola para preguntarle hacia donde se tiene que desplazar (arriba, abajo, izquierda o derecha).\n# 3. Muestra la actualización del laberinto tras cada desplazamiento.\n# 4. Valida todos los movimientos, teniendo en cuenta los límites del laberinto y los obstáculos. Notifica al usuario.\n# 5. Finaliza el programa cuando Mickey llegue a la salida.\n\n\ndef imprimir_laberinto(lab):\n    \"\"\"Imprime el laberinto en un formato legible\"\"\"\n    for fila in lab:\n        print(\"\".join(fila))\n    print()\n\ndef encontrar_mickey(lab):\n    \"\"\"Encuentra la posición actual de Mickey en el laberinto\"\"\"\n    for i in range(len(lab)):\n        for j in range(len(lab[i])):\n            if lab[i][j] == \"🐭\":\n                return i, j\n    return -1, -1  # En caso de que Mickey no esté en el laberinto\n\ndef mover_mickey(lab, direccion):\n    \"\"\"Intenta mover a Mickey en la dirección indicada\"\"\"\n    fila_mickey, col_mickey = encontrar_mickey(lab)\n    nueva_fila, nueva_col = fila_mickey, col_mickey\n    \n    if direccion == \"arriba\":\n        nueva_fila -= 1\n    elif direccion == \"abajo\":\n        nueva_fila += 1\n    elif direccion == \"izquierda\":\n        nueva_col -= 1\n    elif direccion == \"derecha\":\n        nueva_col += 1\n        \n    # Validar límites del laberinto\n    if nueva_fila < 0 or nueva_fila >= len(lab) or nueva_col < 0 or nueva_col >= len(lab[0]):\n        print(\"¡No puedes salir de los límites del laberinto!\")\n        return False\n        \n    # Validar obstáculos\n    if lab[nueva_fila][nueva_col] == \"⬛️\":\n        print(\"¡Hay un obstáculo en esa dirección!\")\n        return False\n        \n    # Verificar si es la salida\n    if lab[nueva_fila][nueva_col] == \"🚪\":\n        lab[fila_mickey][col_mickey] = \"⬜️\"\n        lab[nueva_fila][nueva_col] = \"🐭\"\n        return \"victoria\"\n        \n    # Mover a Mickey\n    lab[fila_mickey][col_mickey] = \"⬜️\"\n    lab[nueva_fila][nueva_col] = \"🐭\"\n    return True\n\n# Laberinto\nlaberinto = [\n    [\"🐭\", \"⬜️\", \"⬛️\", \"⬛️\", \"⬛️\", \"⬛️\"],\n    [\"⬛️\", \"⬜️\", \"⬛️\", \"⬛️\", \"⬛️\", \"⬛️\"],\n    [\"⬛️\", \"⬜️\", \"⬜️\", \"⬜️\", \"⬛️\", \"⬛️\"],\n    [\"⬛️\", \"⬛️\", \"⬛️\", \"⬜️\", \"⬛️\", \"⬛️\"],\n    [\"⬛️\", \"⬛️\", \"⬛️\", \"⬜️\", \"⬛️\", \"⬛️\"],\n    [\"⬛️\", \"⬛️\", \"⬛️\", \"⬜️\", \"⬜️\", \"🚪\"]\n]\n\n# Juego principal\ndef main():\n    print(\"¡Ayuda a Mickey a escapar del laberinto de Maléfica!\")\n    print(\"Usa 'arriba', 'abajo', 'izquierda', 'derecha' para moverte.\")\n    print(\"Escribe 'salir' para terminar el juego.\")\n    imprimir_laberinto(laberinto)\n    \n    while True:\n        direccion = input(\"¿Hacia dónde quieres mover a Mickey? \").lower()\n        \n        if direccion == \"salir\":\n            print(\"¡Juego terminado!\")\n            break\n            \n        if direccion not in [\"arriba\", \"abajo\", \"izquierda\", \"derecha\"]:\n            print(\"Dirección inválida. Usa 'arriba', 'abajo', 'izquierda' o 'derecha'.\")\n            continue\n            \n        resultado = mover_mickey(laberinto, direccion)\n        imprimir_laberinto(laberinto)\n        \n        if resultado == \"victoria\":\n            print(\"¡Felicidades! ¡Mickey ha escapado del laberinto!\")\n            break\n\nif __name__ == \"__main__\":\n    main()"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/python/ignaciovihe.py",
    "content": "\"\"\"\n * EJERCICIO:\n * ¡Disney ha presentado un montón de novedades en su D23! \n * Pero... ¿Dónde está Mickey?\n * Mickey Mouse ha quedado atrapado en un laberinto mágico \n * creado por Maléfica.\n * Desarrolla un programa para ayudarlo a escapar.\n * Requisitos:\n * 1. El laberinto está formado por un cuadrado de 6x6 celdas.\n * 2. Los valores de las celdas serán:\n *    - ⬜️ Vacío\n *    - ⬛️ Obstáculo\n *    - 🐭 Mickey\n *    - 🚪 Salida\n * Acciones:\n * 1. Crea una matriz que represente el laberinto (no hace falta\n * que se genere de manera automática).\n * 2. Interactúa con el usuario por consola para preguntarle hacia\n * donde se tiene que desplazar (arriba, abajo, izquierda o derecha).\n * 3. Muestra la actualización del laberinto tras cada desplazamiento.\n * 4. Valida todos los movimientos, teniendo en cuenta los límites\n * del laberinto y los obstáculos. Notifica al usuario.\n * 5. Finaliza el programa cuando Mickey llegue a la salida.\n\"\"\"\n\n\n\"\"\"\nHe querido realizar el ejercicio con clases para practicar SOLID. Se podía haber resuelto de forma mucho mas sencilla.\n\"\"\"\n\nimport os\nfrom abc import ABC, abstractmethod\n\ndef clear_console():# Sierve para borrar la consola y que el tablero quede siempre en el mismo sitio\n    os.system('cls' if os.name == 'nt' else 'clear')\n\n\nmaze = [[\"⬜️\",\"⬛️\",\"🚪\",\"⬜️\",\"⬜️\",\"⬜️\",\"⬛️\",\"⬜️\",\"⬜️\",\"⬜️\",\"⬜️\",\"⬛️\"],\n        [\"⬜️\",\"⬛️\",\"⬛️\",\"⬛️\",\"⬛️\",\"⬜️\",\"⬜️\",\"⬜️\",\"⬜️\",\"⬜️\",\"⬜️\",\"⬜️\"],\n        [\"⬛️\",\"⬜️\",\"⬜️\",\"⬜️\",\"⬜️\",\"⬜️\",\"⬛️\",\"⬜️\",\"⬛️\",\"⬜️\",\"⬜️\",\"⬛️\"],\n        [\"⬜️\",\"⬜️\",\"⬛️\",\"⬜️\",\"⬛️\",\"⬛️\",\"⬜️\",\"⬛️\",\"⬜️\",\"⬛️\",\"⬛️\",\"⬜️\"],\n        [\"⬜️\",\"⬛️\",\"⬜️\",\"⬜️\",\"⬛️\",\"⬛️\",\"⬜️\",\"⬛️\",\"⬜️\",\"⬜️\",\"⬜️\",\"⬜️\"],\n        [\"⬜️\",\"⬛️\",\"⬛️\",\"⬛️\",\"⬛️\",\"⬜️\",\"⬜️\",\"⬜️\",\"⬛️\",\"⬜️\",\"⬜️\",\"⬜️\"],\n        [\"⬜️\",\"⬛️\",\"⬜️\",\"⬛️\",\"⬜️\",\"⬛️\",\"⬛️\",\"⬛️\",\"⬜️\",\"⬛️\",\"⬛️\",\"⬜️\"],\n        [\"⬜️\",\"⬛️\",\"⬜️\",\"⬛️\",\"⬛️\",\"⬜️\",\"⬜️\",\"⬜️\",\"⬜️\",\"⬜️\",\"⬜️\",\"⬛️\"],\n        [\"⬜️\",\"⬛️\",\"⬛️\",\"⬛️\",\"⬛️\",\"⬜️\",\"⬛️\",\"⬜️\",\"⬛️\",\"⬛️\",\"⬜️\",\"⬜️\"],\n        [\"⬜️\",\"⬛️\",\"⬛️\",\"⬜️\",\"⬛️\",\"⬛️\",\"⬛️\",\"⬜️\",\"⬜️\",\"⬜️\",\"⬛️\",\"⬜️\"],\n        [\"⬜️\",\"⬛️\",\"⬜️\",\"⬛️\",\"⬜️\",\"⬜️\",\"⬜️\",\"⬛️\",\"⬜️\",\"⬜️\",\"⬜️\",\"⬜️\"],\n        [\"⬛️\",\"🐭\",\"⬜️\",\"⬛️\",\"⬛️\",\"⬛️\",\"⬜️\",\"⬜️\",\"⬜️\",\"⬜️\",\"⬛️\",\"⬜️\"],\n        [\"⬜️\",\"⬛️\",\"⬜️\",\"⬛️\",\"⬜️\",\"⬜️\",\"⬛️\",\"⬛️\",\"⬛️\",\"⬛️\",\"⬜️\",\"⬜️\"],\n        [\"⬜️\",\"⬛️\",\"⬜️\",\"⬛️\",\"⬛️\",\"⬜️\",\"⬜️\",\"⬜️\",\"⬜️\",\"⬜️\",\"⬜️\",\"⬜️\"]]\n\nclass Maze:#Clase que contiene el laberinto y sus proiedades.\n    def __init__(self, grid):\n        self.grid = grid\n        self.obstacles, self.mickey, self.exit = self.update_maze_properties()\n\n    def __getitem__(self, index):# Este metodo hace que cuando accedo a la instacia de Maze con indices no tengo que acceder a maze.grid\n        return self.grid[index]\n    \n    def __len__(self):\n        return len(self.grid)# Igualmente dice que cuando acceda a len de la instancia de Maze este accediendo directamente a len de maze.grid\n\n    def update_maze_properties(self):\n        current_obstacles = []\n        mickey = exit = None #Mejora la seguridad\n        for i, line in enumerate(self.grid):\n            for j, column in enumerate(line):\n                if column != \"⬜️\":\n                    if column == \"⬛️\":\n                        current_obstacles.append((i, j))\n                    elif column == \"🐭\":\n                        mickey = (i, j)\n                    elif column == \"🚪\":\n                        exit = (i, j)\n        return current_obstacles, mickey, exit\n\n\nclass MazePrinter:#Esta clase sieve para pintar el laberinto\n    def __init__(self, maze: Maze):\n        self.maze = maze\n\n    def print_maze(self):\n        for line in self.maze:\n            for cell in line:\n                print(cell, end=\"\")\n            print()\n\n\nclass CellChecker:# Esta clase se encarga de comprobar las situaciones en el tablero\n    def __init__(self, maze: Maze):\n        self.maze = maze\n\n    def is_inside_maze(self, i:int, j:int):\n        return 0<= i < len(self.maze)  and   0<= j < len(self.maze[0]) # Puedo acceder directamente a self.maze como si fuera grid por la funcion __getitem__\n\n    def is_obstacle(self, i:int, j:int):\n        return (i, j) in self.maze.obstacles\n\n    def is_exit(self, i:int, j: int):\n        return (i, j) in self.maze.exit\n\n    def is_mickey(self, i:int, j: int):\n        return (i, j) in self.maze.mickey\n    \n\nclass GameMessenger:# Esta clase se encarga de imprimir los mensajes de feedback\n    def invalid_direction(self):\n        print(\"Elige una opción válida\")\n\n    def mickey_blocked(self):\n        print(\"Mickey no puede continuar por ahí\")\n\n    def mickey_wins(self):\n        print(\"FELICIDADES! - HAS LIBERADO A MICKEY\")\n    \n\nclass MoveStrategy(ABC):# Interfaz/Clase abstracta de los posibles movimientos.\n    @abstractmethod\n    def matches(self, direction: str) -> bool:\n        pass\n    @abstractmethod\n    def get_movement(self) -> tuple[int, int]:\n        pass\n\nclass MoveLeft(MoveStrategy):#Implementaciones concretas de los posibles movimientos\n    def matches(self, direction): return direction == \"a\"\n    def get_movement(self): return (0, -1)\n\nclass MoveUpLeft(MoveStrategy):\n    def matches(self, direction): return direction == \"q\"\n    def get_movement(self): return (-1, -1)\n\nclass MoveUp(MoveStrategy):\n    def matches(self, direction): return direction == \"w\"\n    def get_movement(self): return (-1, 0)\n\nclass MoveUpRight(MoveStrategy):\n    def matches(self, direction): return direction == \"e\"\n    def get_movement(self): return (-1, 1)\n\nclass MoveRight(MoveStrategy):\n    def matches(self, direction): return direction == \"d\"\n    def get_movement(self): return (0, 1)\n\nclass MoveDownRight(MoveStrategy):\n    def matches(self, direction): return direction == \"c\"\n    def get_movement(self): return (1, 1)\n\nclass MoveDown(MoveStrategy):\n    def matches(self, direction): return direction == \"s\"\n    def get_movement(self): return (1, 0)\n\nclass MoveDownLeft(MoveStrategy):\n    def matches(self, direction): return direction == \"z\"\n    def get_movement(self): return (1, -1)\n\nclass MovementManager:# Esta clase se encarga de manejar los posibles movimientos\n    def __init__(self, maze: Maze, cell_checker: CellChecker, strategies):\n        self.maze = maze\n        self.cell_checker = cell_checker\n        self.strategies = strategies\n        \n    def calculate_movement(self, direction: str):# Obtiene el movimiento segun la opcion elegida\n        for strategie in self.strategies:\n            if strategie.matches(direction):\n                return strategie.get_movement()\n        return None    \n            \n    def move(self, direction: str):# Realiza el movimiento y devuelve el estado de lo que ha ocurrido. Movimiento normal, bloqueado, final.\n        movement = self.calculate_movement(direction)\n        if movement is None:\n            return \"invalid\"\n                \n        new_i = self.maze.mickey[0] + movement[0]\n        new_j = self.maze.mickey[1] + movement[1]\n\n        if self.cell_checker.is_inside_maze(new_i, new_j) and not self.cell_checker.is_obstacle(new_i, new_j):\n            old_i, old_j = self.maze.mickey\n            self.maze[old_i][old_j]= \"⬜️\"\n            self.maze[new_i][new_j] = \"🐭\"\n            self.maze.mickey = (new_i, new_j)\n            \n            if self.maze.mickey == self.maze.exit:\n                return \"win\"\n            return \"moved\"\n        else:\n            return \"blocked\"\n\n\ndef main():# Se encarga del flujo del programa\n    my_maze = Maze(maze)\n    printer = MazePrinter(my_maze)\n    cell_checker = CellChecker(my_maze)\n    movement_strategies = [\n            MoveLeft(), MoveUpLeft(), MoveUp(), MoveUpRight(), MoveRight(), MoveDownRight(), MoveDown(), MoveDownLeft()\n        ]\n    movement_manager = MovementManager(my_maze, cell_checker, movement_strategies)\n    messenger = GameMessenger()\n\n    finish = False\n    print(\"--Welcome to Mickey Maze--\")\n    printer.print_maze()\n\n    while not finish:\n        print(\"Movimientos:\")\n        print(\"a. Izquierda\")\n        print(\"q. Arriba izquierda\")\n        print(\"w. Arriba\")\n        print(\"e. Arriba derecha\")\n        print(\"d. Derecha\")\n        print(\"c. Abajo derecha\")\n        print(\"s. Abajo\")\n        print(\"z. Abajo izquierda\")\n\n        option = input(\"Introduce a donde quieres moverte:\")\n        clear_console()\n        result = movement_manager.move(option)\n\n        printer.print_maze()\n\n        match result:\n            case \"invalid\":\n                messenger.invalid_direction()\n            case \"blocked\":\n                messenger.mickey_blocked()\n            case \"win\":\n                messenger.mickey_wins()\n                finish = True\n\nmain()"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/python/javi-kl.py",
    "content": "import numpy as np\n\narr = np.array(\n    [\n        [0, 0, 0, 5, 0, 0],\n        [2, 2, 0, 2, 0, 2],\n        [0, 2, 0, 0, 0, 0],\n        [0, 0, 0, 0, 0, 0],\n        [0, 0, 2, 0, 2, 0],\n        [0, 0, 0, 0, 0, 3],\n    ]\n)\nprint(\"\"\" ---- RESCATANDO A MICKEY ----\"\"\")\nprint(\n    \"\"\"\nLeyenda\nlibre = 0\nMickey = 5\nobstaculos = 2\nsalida = 3\"\"\"\n)\n\n\nclass Mickey:\n    def __init__(self, fila, columna) -> None:\n\n        self.fila = fila\n        self.columna = columna\n\n    # movimientos\n    def moverse(self, delta_fila, delta_columna):\n\n        self.fila += delta_fila\n        self.columna += delta_columna\n\n\nclass Comprobador:\n    def comprobar_obstaculo(self, fila, columna):\n        return arr[fila, columna] == 2\n\n    def comprobar_salida(self, fila, columna):\n        return arr[fila, columna] == 3\n\n\ndef intentar_movimiento(direccion, mickey, comprobador):\n    nueva_fila = mickey.fila + direccion[\"delta_fila\"]\n    nueva_columna = mickey.columna + direccion[\"delta_columna\"]\n    if nueva_fila < 0 or nueva_fila > 5 or nueva_columna < 0 or nueva_columna > 5:\n        print(\"Encontró el límite\")\n        return False\n\n    if comprobador.comprobar_obstaculo(nueva_fila, nueva_columna):\n        print(\"Obstáculo encontrado\")\n        return False\n\n    else:\n        arr[mickey.fila, mickey.columna] = 0  # Limpiar posición anterior\n    mickey.moverse(direccion[\"delta_fila\"], direccion[\"delta_columna\"])  # Mover Mickey\n    return True\n\n\nmickey = Mickey(0, 3)  # Pasamos posición de inicio\ncomprobador = Comprobador()\n\n\ndef menu_principal():\n    direcciones = {\n        \"1\": {\n            \"delta_fila\": 1,\n            \"delta_columna\": 0,\n            \"nombre\": \"abajo\",\n        },\n        \"2\": {\n            \"delta_fila\": -1,\n            \"delta_columna\": 0,\n            \"nombre\": \"arriba\",\n        },\n        \"3\": {\n            \"delta_fila\": 0,\n            \"delta_columna\": -1,\n            \"nombre\": \"izquierda\",\n        },\n        \"4\": {\n            \"delta_fila\": 0,\n            \"delta_columna\": 1,\n            \"nombre\": \"derecha\",\n        },\n    }\n    print(\"\\nMickey esta en el inicio del laberinto\")\n    while True:\n        arr[mickey.fila, mickey.columna] = 5  # Nueva posición de Mickey\n        print(f\"\\n{arr}\\n\")\n\n        print(\"1 = abajo\")\n        print(\"2 = Arriba\")\n        print(\"3 = izquierda\")\n        print(\"4 = derecha\")\n        print(\"5 = Terminar programa\")\n\n        opcion = input(\"Elige siguiente movimiento\\n->\")\n        if opcion == \"5\":\n            print(\"¡Hasta luego!\")\n            break\n        elif opcion in direcciones:\n            if intentar_movimiento(direcciones[opcion], mickey, comprobador):\n                if comprobador.comprobar_salida(mickey.fila, mickey.columna):\n                    arr[mickey.fila, mickey.columna] = 5  # Mostrar Mickey en la salida\n                    print(f\"\\n{arr}\\n\")\n                    print(\"¡Enhorabuena! Mickey encontró la salida\")\n                    break\n            else:\n                print(\"No puede moverse aquí\")\n        else:\n            print(\"Opción no válida\")\n\n\nmenu_principal()\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/python/juanmax2.py",
    "content": "\n\nlaberinto = [\n    [\"🐭\",\"⬛️\",\"⬛️\",\"⬛️\",\"⬛️\",\"⬛️\"],\n    [\"⬜️\",\"⬛️\",\"⬜️\",\"⬜️\",\"⬜️\",\"⬛️\"],\n    [\"⬜️\",\"⬛️\",\"⬜️\",\"⬛️\",\"⬜️\",\"⬛️\"],\n    [\"⬜️\",\"⬛️\",\"⬜️\",\"⬜️\",\"⬜️\",\"⬜️\"],\n    [\"⬜️\",\"⬜️\",\"⬜️\",\"⬛️\",\"⬜️\",\"⬛️\"],\n    [\"⬛️\",\"⬛️\",\"⬛️\",\"⬛️\",\"🚪\",\"⬛️\"],\n]\n\ncontinuar = True\nmickey = [0, 0]\ndef print_laberinto(laberinto):\n        for camino in laberinto:\n            print(\" \".join(camino))\n        \n        print()\n\nwhile continuar == True:\n    print(\"Ayuda a Mickey a salir del laberinto\")\n    print(\"[w] Arriba\")\n    print(\"[s] Abajo\")\n    print(\"[a] Izquierda\")\n    print(\"[d] Derecha\")\n    direccion = input(\"Hacia donde debe moverse Mickey? \")\n    \n    fila_actual, columna_actual = mickey\n    nueva_fila, nueva_columna = fila_actual, columna_actual\n    \n    match direccion:\n        case \"w\":\n            nueva_fila = fila_actual - 1\n        case \"s\":\n            nueva_fila = fila_actual + 1\n        case \"a\":\n            nueva_columna = columna_actual - 1\n        case \"d\":\n            nueva_columna = columna_actual + 1\n        case _:\n            print(\"Dirección no válida, prueba con otra.\\n\")\n            continue\n        \n    if nueva_fila < 0 or nueva_fila > 5 or nueva_columna < 0 or nueva_columna > 5:\n        print(\"No puedes desplazarte fuera del laberinto\\n\")\n        continue\n    else:\n        if laberinto[nueva_fila][nueva_columna] == \"⬛️\":\n            print(\"En esa dirección hay un obstaculo\\n\")\n            continue\n        elif laberinto[nueva_fila][nueva_columna] == \"🚪\":\n            print(\"Has encontrado la salida!! Enhorabuena\\n\")\n            continuar = False\n        else:\n            laberinto[fila_actual][columna_actual] = \"⬜️\"\n            laberinto[nueva_fila][nueva_columna] = \"🐭\"\n            mickey = nueva_fila, nueva_columna\n    print_laberinto(laberinto)\n            \n\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/python/juanmjimenezs.py",
    "content": "\"\"\"\n * EJERCICIO:\n * ¡Disney ha presentado un montón de novedades en su D23!\n * Pero... ¿Dónde está Mickey?\n * Mickey Mouse ha quedado atrapado en un laberinto mágico\n * creado por Maléfica.\n * Desarrolla un programa para ayudarlo a escapar.\n * Requisitos:\n * 1. El laberinto está formado por un cuadrado de 6x6 celdas.\n * 2. Los valores de las celdas serán:\n *    - ⬜️ Vacío\n *    - ⬛️ Obstáculo\n *    - 🐭 Mickey\n *    - 🚪 Salida\n * Acciones:\n * 1. Crea una matriz que represente el laberinto (no hace falta\n * que se genere de manera automática).\n * 2. Interactúa con el usuario por consola para preguntarle hacia\n * donde se tiene que desplazar (arriba, abajo, izquierda o derecha).\n * 3. Muestra la actualización del laberinto tras cada desplazamiento.\n * 4. Valida todos los movimientos, teniendo en cuenta los límites\n * del laberinto y los obtáculos. Notifica al usuario.\n * 5. Finaliza el programa cuando Mickey llegue a la salida.\n\"\"\"\n\ngrid = [\n    ['🐭', '⬛️', '⬜️', '⬜️', '⬜️', '⬛️'],\n    ['⬜️', '⬜️', '⬜️', '⬛️', '⬜️', '⬜️'],\n    ['⬛️', '⬜️', '⬛️', '⬛️', '⬛️', '⬜️'],\n    ['⬜️', '⬜️', '⬛️', '⬜️', '⬜️', '⬜️'],\n    ['⬜️', '⬛️', '⬜️', '⬜️', '⬛️', '⬛️'],\n    ['⬜️', '⬜️', '⬜️', '⬜️', '⬜️', '🚪']\n]\n\nrow, col = 0, 0\ninvalid_move = False\nwon_game = False\n\ndef print_grid():\n    \"\"\"Printing updated\"\"\"\n    print(\"\\n\")\n    for row in grid:\n        print(' '.join(row))\n\ndef win_check():\n    \"\"\"Checking if the player has won\"\"\"\n    if grid[row][col] == '🚪':\n        return True\n    else:\n        return False\n\nprint(\"Bienvenido a la aventura de Mickey Mouse\")\nprint(\"Mickey Mouse ha quedado atrapado en un laberinto mágico creado por Maléfica\")\nprint_grid()\n\nprint(\"Dale indicaciones a Mickey para salir de aquí y escribe SALIR en cualquier momento para salir del juego.\")\nprint(\"Presiona arriba (E), abajo (X), izquierda (S) y derecha (D) y luego <ENTER>.\")\n\nwhile True:\n    if won_game:\n        print(\"Mickey Mouse ah encontrado la salida!\")\n        break\n\n    if invalid_move:\n        print(\"Movimiento inválido. Inténtalo de nuevo.\")\n\n    direction = input(\"a donde quieres que vaya?: \")\n\n    # Keyword to exit the game\n    if direction.lower() == 'salir':\n        print(\"Lamento que tengas que irte, vuelve pronto!\")\n        break\n\n    if direction.lower() == 'e':\n        if row > 0 and grid[row - 1][col] != '⬛️':\n            grid[row][col] = '⬜️'\n            row -= 1\n            won_game = win_check()\n            grid[row][col] = '🐭'\n        else:\n            invalid_move = True\n    elif direction.lower() == 'x':\n        if row < 5 and grid[row + 1][col] != '⬛️':\n            grid[row][col] = '⬜️'\n            row += 1\n            won_game = win_check()\n            grid[row][col] = '🐭'\n        else:\n            invalid_move = True\n    elif direction.lower() == 's':\n        if col > 0 and grid[row][col - 1] != '⬛️':\n            grid[row][col] = '⬜️'\n            col -= 1\n            won_game = win_check()\n            grid[row][col] = '🐭'\n        else:\n            invalid_move = True\n    elif direction.lower() == 'd':\n        if col < 5 and grid[row][col + 1] != '⬛️':\n            grid[row][col] = '⬜️'\n            col += 1\n            won_game = win_check()\n            grid[row][col] = '🐭'\n        else:\n            invalid_move = True\n\n    print_grid()\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/python/juanppdev.py",
    "content": "\"\"\"\nEJERCICIO:\n * ¡Disney ha presentado un montón de novedades en su D23!\n * Pero... ¿Dónde está Mickey?\n * Mickey Mouse ha quedado atrapado en un laberinto mágico\n * creado por Maléfica.\n * Desarrolla un programa para ayudarlo a escapar.\n * Requisitos:\n * 1. El laberinto está formado por un cuadrado de 6x6 celdas.\n * 2. Los valores de las celdas serán:\n *    - ⬜️ Vacío\n *    - ⬛️ Obstáculo\n *    - 🐭 Mickey\n *    - 🚪 Salida\n * Acciones:\n * 1. Crea una matriz que represente el laberinto (no hace falta\n * que se genere de manera automática).\n * 2. Interactúa con el usuario por consola para preguntarle hacia\n * donde se tiene que desplazar (arriba, abajo, izquierda o derecha).\n * 3. Muestra la actualización del laberinto tras cada desplazamiento.\n * 4. Valida todos los movimientos, teniendo en cuenta los límites\n * del laberinto y los obtáculos. Notifica al usuario.\n * 5. Finaliza el programa cuando Mickey llegue a la salida.\n\"\"\"\n\nimport random\n\n# Definimos los símbolos del laberinto\nVACIO = '⬜️'\nOBSTACULO = '⬛️'\nMICKEY = '🐭'\nSALIDA = '🚪'\n\n# Generamos el laberinto de forma automática\ndef generar_laberinto():\n    laberinto = [[VACIO for _ in range(6)] for _ in range(6)]\n    # Colocamos obstáculos aleatorios\n    for _ in range(8):\n        x, y = random.randint(0, 5), random.randint(0, 5)\n        laberinto[x][y] = OBSTACULO\n    # Colocamos a Mickey y la salida\n    laberinto[0][0] = MICKEY\n    laberinto[5][5] = SALIDA\n    return laberinto\n\n# Imprimimos el laberinto\ndef imprimir_laberinto(laberinto):\n    for fila in laberinto:\n        print(' '.join(fila))\n    print()\n\n# Movemos a Mickey en el laberinto\ndef mover_mickey(laberinto, direccion):\n    # Encontramos la posición actual de Mickey\n    for i in range(6):\n        for j in range(6):\n            if laberinto[i][j] == MICKEY:\n                x, y = i, j\n                break\n\n    # Calculamos la nueva posición\n    if direccion == 'arriba':\n        nuevo_x, nuevo_y = x - 1, y\n    elif direccion == 'abajo':\n        nuevo_x, nuevo_y = x + 1, y\n    elif direccion == 'izquierda':\n        nuevo_x, nuevo_y = x, y - 1\n    elif direccion == 'derecha':\n        nuevo_x, nuevo_y = x, y + 1\n    else:\n        print(\"Dirección no válida\")\n        return False\n\n    # Validamos el movimiento\n    if 0 <= nuevo_x < 6 and 0 <= nuevo_y < 6:\n        if laberinto[nuevo_x][nuevo_y] == VACIO or laberinto[nuevo_x][nuevo_y] == SALIDA:\n            laberinto[x][y] = VACIO\n            laberinto[nuevo_x][nuevo_y] = MICKEY\n            return True\n        elif laberinto[nuevo_x][nuevo_y] == OBSTACULO:\n            print(\"¡Hay un obstáculo en esa dirección!\")\n            return False\n    else:\n        print(\"¡Movimiento fuera de los límites del laberinto!\")\n        return False\n\n# Programa principal\ndef main():\n    laberinto = generar_laberinto()\n    imprimir_laberinto(laberinto)\n\n    while True:\n        direccion = input(\"¿Hacia dónde quieres mover a Mickey? (arriba, abajo, izquierda, derecha): \").strip().lower()\n        if mover_mickey(laberinto, direccion):\n            imprimir_laberinto(laberinto)\n            # Verificamos si Mickey ha llegado a la salida\n            if laberinto[5][5] == MICKEY:\n                print(\"¡Mickey ha escapado del laberinto!\")\n                break\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/python/kenysdev.py",
    "content": "# ╔═════════════════════════════════════╗\n# ║ Autor:  Kenys Alvarado              ║\n# ║ GitHub: https://github.com/Kenysdev ║\n# ║ 2024 -  Python                      ║\n# ╚═════════════════════════════════════╝\n\n# ---------------------------------------\n# 32 * RESCATANDO A MICKEY\n# ---------------------------------------\n\"\"\"\n * EJERCICIO:\n * ¡Disney ha presentado un montón de novedades en su D23! \n * Pero... ¿Dónde está Mickey?\n * Mickey Mouse ha quedado atrapado en un laberinto mágico \n * creado por Maléfica.\n * Desarrolla un programa para ayudarlo a escapar.\n * Requisitos:\n * 1. El laberinto está formado por un cuadrado de 6x6 celdas.\n * 2. Los valores de las celdas serán:\n *    - ⬜️ Vacío\n *    - ⬛️ Obstáculo\n *    - 🐭 Mickey\n *    - 🚪 Salida\n * Acciones:\n * 1. Crea una matriz que represente el laberinto (no hace falta\n * que se genere de manera automática).\n * 2. Interactúa con el usuario por consola para preguntarle hacia\n * donde se tiene que desplazar (arriba, abajo, izquierda o derecha).\n * 3. Muestra la actualización del laberinto tras cada desplazamiento.\n * 4. Valida todos los movimientos, teniendo en cuenta los límites\n * del laberinto y los obtáculos. Notifica al usuario.\n * 5. Finaliza el programa cuando Mickey llegue a la salida.\n\"\"\"\n\nfrom typing import List, Dict, Tuple\nimport random\n\n# ________________________\nclass Data:\n    def __init__(self, config: Dict[str, str]) -> None:\n        self._config = config\n        self._maze: List[List[int]] = []\n        self._position: Tuple[int, int] = (0, 0)\n        self._exit: Tuple[int, int] = (0, 0)\n\n    def print_maze(self) -> None:\n        print(\"--------------------------------------\")\n        for row in self._maze:\n            print(\"\".join(row))\n        print(\"--------------------------------------\")\n\nclass Moves(Data):\n    def __init__(self, config: Dict[str, str]) -> None:\n        super().__init__(config)\n\n    def _can_move(self, y: int, x: int) -> bool:\n        size: int = len(self._maze)\n        if y < 0 or x < 0 or y >= size or x >= size:\n            print(\"🚨I can't jump over the edges.🚨\")\n            return False\n\n        if self._maze[y][x] == self._config[\"obstacle\"]:\n            print(\"🚨You pushed me against the wall.🚨\")\n            return False\n        \n        self._position = (y, x)\n        print(\"✅Correct move.✅\")\n        self._maze[y][x] = config[\"mouse\"]\n        return True\n\n    def up(self) -> None:\n        y, x = self._position\n        if not self._can_move(y - 1, x): \n            return None\n        self._maze[y][x] = self._config[\"empty\"]\n                \n    def down(self) -> None:\n        y, x = self._position       \n        if not self._can_move(y + 1, x): \n            return None\n        self._maze[y][x] = self._config[\"empty\"]\n    \n    def right(self) -> None:\n        y, x = self._position       \n        if not self._can_move(y, x + 1): \n            return None\n        self._maze[y][x] = self._config[\"empty\"]\n\n    def left(self) -> None:\n        y, x = self._position       \n        if not self._can_move(y, x - 1): \n            return None\n        self._maze[y][x] = self._config[\"empty\"]\n\n# ________________________\nclass Maze(Moves):\n    def __init__(self, config: Dict[str, str]) -> None:\n        super().__init__(config)\n\n    def _create_paths(self, x, y, width, height):\n        maze: List[List[int]] = self._maze\n        obstacle = self._config[\"obstacle\"]\n        empyte = self._config[\"empty\"]\n\n        maze[y][x] = empyte\n        for dx, dy in random.sample([(0, 1), (1, 0), (0, -1), (-1, 0)], 4):\n            nx, ny = x + dx * 2, y + dy * 2\n            if 0 < nx < width - 1 and 0 < ny < height - 1 and maze[ny][nx] == obstacle:\n                maze[y + dy][x + dx] = empyte\n                self._create_paths(nx, ny, width, height)\n\n    def create(self) -> None:\n        width = self._config[\"size\"][0]\n        height = self._config[\"size\"][1]\n        obstacle = self._config[\"obstacle\"]\n        \n        if not width % 2: width += 1\n        if not height % 2: height += 1\n        self._maze = [[obstacle] * width for _ in range(height)]\n\n        initial_x = random.randrange(1, width - 1, 2)\n        initial_y = random.randrange(1, height - 1, 2)\n        self._create_paths(initial_x, initial_y, width, height)\n\n        self._maze[0][1] = self._config[\"mouse\"]\n        self._maze[height - 1][width - 2] = self._config[\"exit\"]\n        self._position = (0, 1)\n        self._exit = (height - 1, width - 2)\n\n    def veify_win(self) -> bool:\n        y, x = self._exit\n        if self._maze[y][x] == self._config[\"mouse\"]:\n            return True\n        return False\n\n# ________________________\nclass Game:\n    def __init__(self, config: Dict[str, str], instance_Maze) -> None:\n        self._config: dict = config\n        self._maze = instance_Maze\n\n    def _restart_or_exit(self) -> bool:\n        while True:\n            option: str = (input(\"Y/N: \")).lower()\n            match option:\n                case 'y': return True\n                case 'n': return False\n                case _ : print(\"❌Invalid key.❌\")\n\n    def play(self):\n        for k, v in self._config.items():\n            print(f\"{k}: {v}\")\n        \n        self._maze.create()\n        while True:\n            self._maze.print_maze()\n            print(\"Use the keys: (W, S, A, D).\\nTo restart: R. To exit: 9.\")\n            option: str = (input(\"\\nTecla: \")).lower()\n            match option:\n                case 'w': self._maze.up()\n                case 's': self._maze.down()\n                case 'd': self._maze.right()\n                case 'a': self._maze.left()\n                case 'r': \n                    print(\"😮Do you want to restart?😮\")\n                    if self._restart_or_exit():\n                        self._maze.create()\n\n                case '9': \n                    print(\"😮Do you want to exit?😮\")\n                    if self._restart_or_exit():\n                        break\n\n                case _ : print(\"❌Invalid key.❌\")\n\n            if self._maze.veify_win():\n                print(\"🏆Congratulations, you managed to get me out.🏆\")\n                print(\"🤔Do you want to play again?🤔\")\n                if self._restart_or_exit():\n                    self._maze.create()\n                else:\n                    print(\"Bye\")\n                    break\n\n# ________________________\nif __name__ == \"__main__\":\n    # These are the default values. You can change them here.\n    config: Dict[str, str] = {\n        \"title\": \"RESCUING MICKEY\",\n        \"size\": (6, 6),\n        \"empty\": \"⬜️\",\n        \"obstacle\": \"⬛️\",\n        \"mouse\": \"🐭\",\n        \"exit\": \"🚪\"\n    }\n\n    _maze = Maze(config)\n    _game = Game(config, _maze)\n    _game.play()\n\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/python/lurtur.py",
    "content": "####################################\n# Author: Luis Rodriguez\n# GitHub: https://github/lurtur\n# Date: 15 August 2024\n####################################\n\nfrom abc import ABC, abstractmethod\nimport sys\n\nclass Direction: \n    UP = 0\n    RIGHT = 1\n    DOWN = 2\n    LEFT = 3\n\n\nclass Position:\n    \n    def __init__(self, x: int = 0, y: int = 0):\n        self.x = x\n        self.y = y\n\n\nclass PositionChangeEvent:\n\n    def __init__(self, direction: Direction = None):\n        self.direction: Direction = direction\n\n\nclass Observer(ABC):\n    \n    @abstractmethod\n    def update(self, event: PositionChangeEvent):\n        pass\n\n\nclass Observable(ABC):\n    \n    @abstractmethod\n    def subscribe(self, observer: Observer):\n        pass\n\n    @abstractmethod\n    def unsubscribe(self, observer: Observer):\n        pass\n\n    @abstractmethod\n    def notify(self):\n        pass\n\n\nclass Character(Observable):\n    \n    def __init__(self):\n        self.observers = []\n\n    def subscribe(self, observer: Observer):\n        self.observers.append(observer)\n    \n    def unsubscribe(self, observer: Observer):\n        self.observers.remove(observer)\n\n    def notify(self, event: PositionChangeEvent):\n        for observer in self.observers:\n            observer.update(event)\n\n    def move_up(self):\n        event = PositionChangeEvent()\n        event.direction = Direction.UP\n        \n        self.notify(event)\n\n    def move_down(self):\n        event = PositionChangeEvent()\n        event.direction = Direction.DOWN \n        \n        self.notify(event)\n            \n    def move_right(self):\n        event = PositionChangeEvent()\n        event.direction = Direction.RIGHT\n        \n        self.notify(event)\n        \n    def move_left(self):\n        event = PositionChangeEvent()\n        event.direction = Direction.LEFT\n\n        self.notify(event)\n    \n\nclass Board(Observer):\n    \n    def __init__(self):\n        self.board = [ \n            ['Mickey', 'Vacio', 'Vacio', 'Obstaculo', 'Obstaculo', 'Obstaculo'], \n            ['Obstaculo', 'Obstaculo', 'Vacio', 'Vacio', 'Vacio', 'Vacio'], \n            ['Obstaculo', 'Obstaculo', 'Obstaculo', 'Obstaculo', 'Obstaculo', 'Vacio'], \n            ['Vacio', 'Vacio', 'Vacio', 'Vacio', 'Vacio', 'Vacio'], \n            ['Vacio', 'Obstaculo', 'Obstaculo', 'Obstaculo', 'Obstaculo', 'Obstaculo'], \n            ['Vacio', 'Vacio', 'Vacio', 'Vacio', 'Vacio', 'Salida'], \n            ]\n        self.rows = 6\n        self.cols = 6\n        self.character_pos = Position(0, 0)\n        self.character_escaped = False\n        \n    def update(self, event: PositionChangeEvent):\n        new_pos = Position(self.character_pos.x, self.character_pos.y)\n\n        if event.direction == Direction.UP:\n            new_pos.y -= 1\n        elif event.direction == Direction.RIGHT:\n            new_pos.x += 1\n        elif event.direction == Direction.DOWN:\n            new_pos.y += 1\n        elif event.direction == Direction.LEFT:\n            new_pos.x -= 1\n\n        if self.validate_position(new_pos):\n            if self.is_exit(new_pos):\n                self.board[new_pos.y][new_pos.x] = 'Mickey'\n                self.board[self.character_pos.y][self.character_pos.x] = 'Vacio'\n\n                self.character_pos = new_pos\n\n                self.character_escaped = True\n\n            else:\n                # Swap the content between the current position of the character and the new position.\n                self.board[self.character_pos.y][self.character_pos.x], self.board[new_pos.y][new_pos.x] = \\\n                    self.board[new_pos.y][new_pos.x], self.board[self.character_pos.y][self.character_pos.x]\n                \n                # Update the character position\n                self.character_pos = new_pos\n\n    def is_exit(self, position: Position) -> bool:\n        return (self.board[position.y][position.x] == 'Salida')\n\n    def show(self):\n        print()\n\n        # Determine the width of the columns since the content size varies\n        col_widths = [max(len(str(item)) for item in col) for col in zip(*self.board)]\n        for row in self.board:\n            print(\" \".join(str(item).ljust(width) for item, width in zip(row, col_widths)))\n        print()\n\n    def validate_position(self, position: Position) -> False:\n        result = True\n        \n        # Check if the position is between the limits of the board\n        if position.x < 0:\n            position.x = 0\n            result = False\n        elif position.x >= self.cols:\n            position.x = self.cols\n            result = False\n        \n        if position.y < 0:\n            position.y = 0\n            result = False\n        elif position.y >= self.rows:\n            position.y = self.rows\n            result = False\n\n        # Check if the position has an obstacle\n        if (self.board[position.y][position.x] == 'Obstaculo'):\n            print(\"|*** [ Invalid request: There is an obstacle ] ***|\")\n            result = False\n\n        return result\n\nclass Commands:\n    UP = '1'\n    RIGHT = '2'\n    DOWN = '3'\n    LEFT = '4'\n    QUIT = '5'\n\ndef commands_menu() -> str:\n    print(\"+++ { Commands menu } +++\")\n    print(\"[ UP   : 1 ]\")\n    print(\"[ RIGHT: 2 ]\")\n    print(\"[ DOWN : 3 ]\")\n    print(\"[ LEFT : 4 ]\")\n    print(\"[ QUIT : 5 ]\")\n    option = input(\"Select the direction you want Mickey to move: \")\n    options = f\"{Commands.UP}{Commands.RIGHT}{Commands.DOWN}{Commands.LEFT}{Commands.QUIT}\"\n\n    if option in options:\n        return option\n        \n    return -1\n\ndef main():\n    board = Board()\n    mickey = Character()\n    mickey.subscribe(board)\n\n    while True:\n        board.show()\n\n        if board.character_escaped:\n            print(\"!!! -o-{ Mickey has found the exit }-o- !!!\")\n            sys.exit(0)\n\n        option = commands_menu()\n        if option == -1:\n            print()\n            print(\"|*** [ Invalid option ] ***|\")\n            print()\n            continue\n\n        if option == Commands.UP:\n            mickey.move_up()\n        elif option == Commands.RIGHT:\n            mickey.move_right()\n        elif option == Commands.DOWN:\n            mickey.move_down()\n        elif option == Commands.LEFT:\n            mickey.move_left()\n        elif option == Commands.QUIT:\n            sys.exit(0)\n            \n\nmain()"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/python/mhayhem.py",
    "content": "# @Author Daniel Grande (Mhayhem)\nimport random\nimport readchar as rc\nimport os\n\n# EJERCICIO:\n# ¡Disney ha presentado un montón de novedades en su D23! \n# Pero... ¿Dónde está Mickey?\n# Mickey Mouse ha quedado atrapado en un laberinto mágico \n# creado por Maléfica.\n# Desarrolla un programa para ayudarlo a escapar.\n# Requisitos:\n# 1. El laberinto está formado por un cuadrado de 6x6 celdas.\n# 2. Los valores de las celdas serán:\n#    - ⬜️ Vacío\n#    - ⬛️ Obstáculo\n#    - 🐭 Mickey\n#    - 🚪 Salida\n# Acciones:\n# 1. Crea una matriz que represente el laberinto (no hace falta\n# que se genere de manera automática).\n# 2. Interactúa con el usuario por consola para preguntarle hacia\n# donde se tiene que desplazar (arriba, abajo, izquierda o derecha).\n# 3. Muestra la actualización del laberinto tras cada desplazamiento.\n# 4. Valida todos los movimientos, teniendo en cuenta los límites\n# del laberinto y los obstáculos. Notifica al usuario.\n# 5. Finaliza el programa cuando Mickey llegue a la salida.\n\nclass Maze:\n    \n    def __init__(self):\n        # init maze 6x6\n        self.size = 6\n        self.maze = [[\"⬜️\" for _ in range(self.size)] for _ in range(self.size)]\n\n        #  place output\n        self.door_i = random.randint(0, self.size -1)\n        self.door_j = random.randint(0, self.size -1)\n        \n        self.maze[self.door_i][self.door_j] = \"🚪\"\n\n        # find adjacent positions\n        adjacent = []\n        for di, dj in [(-1,0),(1,0),(0,-1),(0,1)]:\n            ni, nj = self.door_i +di, self.door_j + dj\n            if 0 <= ni < self.size and 0 <= nj < self.size:\n                adjacent.append((ni,nj))\n\n        # place player\n        self.player_i = random.randint(0, self.size -1)\n        self.player_j = random.randint(0, self.size -1)\n        while (self.player_i, self.player_j) == (self.door_i, self.door_j):\n            self.player_i = random.randint(0, self.size -1)\n            self.player_j = random.randint(0, self.size -1)\n        self.maze[self.player_i][self.player_j] = \"🐭\"\n\n\n        # generate free way between user and door\n        path = self.generate_path(self.player_i, self.player_j, self.door_i, self.door_j)\n\n        # num aleatory obstacles\n        num_obstacles = 10\n        # check that obstacles do not overlap\n        obstacles_position = set()\n        while len(obstacles_position) < num_obstacles:\n            i, j = random.randint(0, self.size -1), random.randint(0, self.size -1)\n            # Do not place any obstacles in the doorway or in the free space.\n            if (i, j) not in obstacles_position and (i, j) != (self.door_i, self.door_j) and (i, j) != (self.player_i, self.player_j):\n                obstacles_position.add((i, j))\n                self.maze[i][j] = \"⬛️\"\n\n    def generate_path(self, ui, uj, di, dj):\n        path = set()\n        i, j = ui, uj\n        path.add((i, j))\n        while (i,j) != (di, dj):\n            if i != di:\n                if random.choice([True,False]):\n                    i += 1 if di > i else -1\n                else:\n                    j += 1 if dj > i else -1\n            elif i != di:\n                i += 1 if di > i else -1\n            elif j != dj:\n                j += 1 if dj > i else -1\n        \n            path.add((i, j))\n        \n        return path\n\n    def draw_maze(self):\n        # clean display\n        os.system(\"cls\" if os.name == \"nt\" else \"clear\")\n        for row in self.maze:\n            print(\"\".join(row))\n    \n    def mickey_move(self, direction):\n        di, dj = 0, 0\n        if direction == \"w\" or direction == rc.key.UP: di = -1\n        elif direction == \"s\" or direction == rc.key.DOWN: di = 1\n        elif direction == \"a\" or direction == rc.key.LEFT: dj = -1\n        elif direction == \"d\" or direction == rc.key.RIGHT: dj = 1\n        else: return # invalid key\n        \n        new_i = self.player_i + di\n        new_j = self.player_j + dj\n        \n        # check limits\n        if 0 <= new_i < self.size and 0 <= new_j < self.size:\n            # check obstacle\n            if self.maze[new_i][new_j] != \"⬛️\":\n                # player move\n                self.maze[self.player_i][self.player_j] = \"⬜️\"\n                self.player_i, self.player_j = new_i, new_j\n                self.maze[self.player_i][self.player_j] = \"🐭\"\n\n    def play_game(self):\n        self.draw_maze()\n        while True:\n            key = rc.readkey()\n            if key == \"q\":\n                print(\"saliendo del juego.\")\n                break\n            self.mickey_move(key)\n            self.draw_maze()\n            # win by reaching the door\n            if (self.player_i, self.player_j) == (self.door_i, self.door_j):\n                print(\"Has salvado a Mickey Mouse!!!!\")\n                break\n\ngame = Maze()\ngame.play_game()"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/python/mouredev.py",
    "content": "maze = [\n    [\"🐭\", \"⬛️\", \"⬛️\", \"⬛️\", \"⬛️\", \"⬛️\"],\n    [\"⬜️\", \"⬛️\", \"⬛️\", \"⬛️\", \"⬜️\", \"⬛️\"],\n    [\"⬜️\", \"⬛️\", \"⬛️\", \"⬛️\", \"⬜️\", \"⬛️\"],\n    [\"⬜️\", \"⬜️\", \"⬜️\", \"⬜️\", \"⬜️\", \"⬜️\"],\n    [\"⬛️\", \"⬜️\", \"⬛️\", \"⬜️\", \"⬛️\", \"⬛️\"],\n    [\"⬛️\", \"⬜️\", \"⬛️\", \"⬜️\", \"⬜️\", \"🚪\"]\n]\n\n\ndef print_maze():\n    for row in maze:\n        print(\"\".join(row))\n    print()\n\n\nmickey = [0, 0]\n\n\nwhile True:\n\n    print_maze()\n\n    print(\"¿Hacia dónde se mueve Mickey?\")\n    print(\"[w] arriba\")\n    print(\"[s] abajo\")\n    print(\"[a] izquierda\")\n    print(\"[d] derecha\")\n    direction = input(\"Dirección: \")\n\n    current_row, current_column = mickey\n    new_row, new_column = current_row, current_column\n\n    match direction:\n        case \"w\":\n            new_row = current_row - 1\n        case \"s\":\n            new_row = current_row + 1\n        case \"a\":\n            new_column = current_column - 1\n        case \"d\":\n            new_column = current_column + 1\n        case _:\n            print(\"Dirección no válida.\\n\")\n            continue\n\n    if new_row < 0 or new_row > 5 or new_column < 0 or new_column > 5:\n        print(\"No puedes desplazarte fuera del laberinto.\\n\")\n        continue\n    else:\n        if maze[new_row][new_column] == \"⬛️\":\n            print(\"¡En esa dirección hay un obstáculo!\\n\")\n            continue\n        elif maze[new_row][new_column] == \"🚪\":\n            print(\"¡Has encontrado la salida!\")\n            maze[current_row][current_column] = \"⬜️\"\n            maze[new_row][new_column] = \"🐭\"\n            print_maze()\n            break\n        else:\n            maze[current_row][current_column] = \"⬜️\"\n            maze[new_row][new_column] = \"🐭\"\n            mickey = [new_row, new_column]\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/python/mrodara.py",
    "content": "### RESCATANDO A MICKEY\nimport random as rnd\n\ndef generate_maze() -> list :\n    \n    maze = []\n    empty_row = ['obstaculo', 'vacio', 'vacio', 'vacio', 'vacio', 'obstaculo']\n    border_sup_inf = ['obstaculo','obstaculo','obstaculo','obstaculo','obstaculo','obstaculo']\n\n    # Generamos el maze vacío y con los obstáculos en los extremos.\n    maze.append(border_sup_inf.copy())\n    for i in range(1, 5):\n        maze.append(empty_row.copy())\n    maze.append(border_sup_inf.copy())\n    \n    #Dejamos también vacías las posiciones (1,0) y (0,1) para poder movernos\n    maze[1][0] = 'vacio'\n    maze[0][1] = 'vacio'\n\n    # Elegimos de manera aleatoria donde vamos a colocar la salida\n    row_out = 5 # Siempre tomaremos la última fila de momento.\n    col_out = rnd.randint(1, 5)\n    maze[row_out][col_out] = 'salida'\n\n    # Colocamos de manera aleatoria a Mickey dentro del tablero\n    row_mickey = rnd.randint(1, 4)\n    col_mickey = rnd.randint(1, 4)\n    maze[row_mickey][col_mickey] = 'mickey'\n    \n    # La posición 0,0 serla el punto de entrada\n    maze[0][0] = 'vacio'\n    \n    return maze\n\ndef check_obstacle(x: int, y: int, matrix: list) -> bool:\n    if matrix[x][y] == 'obstaculo':\n        return True\n    return False\n\ndef check_mickey(x: int, y: int, matrix: list) -> bool:\n    if matrix[x][y] == 'mickey':\n        return True\n    return False\n\nmaze = generate_maze()\n\nfor row in maze:\n    print(row)\n\nexit = False\nposition = [0,0]\nfounded = False\n\nwhile not exit:\n    # Preguntamos al usuario qué acción quiere realizar.\n    print(f\"Tu posición actual es [{position[0]}, {position[1]}]\")\n    action = input(\"Indica la acción a realizar (u - arriba, d - abajo, l - izquierda, r - derecha, e - exit): \")\n    while action[0].lower() not in ['u', 'd', 'l', 'r', 'e']:\n        print(\"Error: Introduce un valor correcto para el movimiento\")\n        action = input(\"Indica la acción a realizar (u - arriba, d - abajo, l - izquierda, r - derecha): \")\n    \n    if action[0].lower() == 'e':\n        exit = True\n        break\n    \n    match action[0].lower():\n        case 'u':\n            if check_mickey(x=position[0] - 1, y=position[1], matrix=maze):\n                founded = True\n                print('¡Mickey está aquí!')\n                position[0] -= 1\n            else:\n                if not check_obstacle(x=position[0] - 1, y=position[1], matrix=maze):\n                    position[0] -= 1\n                else:\n                    print('Hay un obstáculo, no te puedes mover ahí')\n        case 'd':\n            if check_mickey(x=position[0] + 1, y=position[1], matrix=maze):\n                founded = True\n                print('¡Mickey está aquí!')\n                position[0] += 1\n            else:\n                if not check_obstacle(x=position[0] + 1, y=position[1], matrix=maze):\n                    position[0] += 1\n                else:\n                    print('Hay un obstáculo, no te puedes mover ahí')\n        case 'l':\n            if check_mickey(x=position[0], y=position[1] - 1, matrix=maze):\n                founded = True\n                print('¡Mickey está aquí!')\n                position[1] -= 1\n            else:\n                if not check_obstacle(x=position[0], y=position[1] - 1, matrix=maze):\n                    position[1] -= 1\n                else:\n                    print('Hay un obstáculo, no te puedes mover ahí')\n        case 'r':\n            if check_mickey(x=position[0], y=position[1] + 1, matrix=maze):\n                founded = True\n                print('¡Mickey está aquí!')\n                position[1] += 1\n            else:\n                if not check_obstacle(x=position[0], y=position[1] + 1, matrix=maze):\n                    position[1] += 1\n                else:\n                    print('Hay un obstáculo, no te puedes mover ahí')\n\nif founded:\n    print(f'Enhorabuena, pudiste rescatar a Mickey!!!')\nprint('Fin del juego')\n### FIN RESCATANDO A MICKEY"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/python/neslarra.py",
    "content": "r\"\"\"\n EJERCICIO:\n ¡Disney ha presentado un montón de novedades en su D23!\n Pero... ¿Dónde está Mickey?\n Mickey Mouse ha quedado atrapado en un laberinto mágico\n creado por Maléfica.\n Desarrolla un programa para ayudarlo a escapar.\n Requisitos:\n 1. El laberinto está formado por un cuadrado de 6x6 celdas.\n 2. Los valores de las celdas serán:\n    - ⬜️ Vacío\n    - ⬛️ Obstáculo\n    - 🐭 Mickey\n    - 🚪 Salida\n Acciones:\n 1. Crea una matriz que represente el laberinto (no hace falta\n que se genere de manera automática).\n 2. Interactúa con el usuario por consola para preguntarle hacia\n donde se tiene que desplazar (arriba, abajo, izquierda o derecha).\n 3. Muestra la actualización del laberinto tras cada desplazamiento.\n 4. Valida todos los movimientos, teniendo en cuenta los límites\n del laberinto y los obtáculos. Notifica al usuario.\n 5. Finaliza el programa cuando Mickey llegue a la salida.\n \"\"\"\nfrom os import system\nimport keyboard as kb\n\nmaze = [['⬜', '🐭', '⬜', '⬜', '⬜', '⬜'],\n        ['⬜', '⬛', '⬛', '⬛', '⬜', '⬛'],\n        ['⬜', '⬜', '⬜', '⬜', '⬛', '⬜'],\n        ['⬜', '⬜', '⬛', '⬜', '⬜', '⬛'],\n        ['⬛', '⬜', '⬜', '⬛', '⬜', '🚪'],\n        ['⬜', '⬜', '⬜', '⬛', '⬜', '⬜']]\nmickey_pos = [0, 1]\nexit_door = [4, 5]\n\n\ndef draw_maze(maze: list):\n    system(\"cls\")\n    print(\"Press key arrow to move or Escape to quit. \\n\")\n    for r in range(0, 6):\n        for c in range(0, 6):\n            print(maze[r][c], end=\"\")\n        print()\n\n\ndef move_up(mickey_pos: list) -> list:\n    if mickey_pos[0] > 0:\n        if maze[mickey_pos[0] - 1][mickey_pos[1]] in (\"⬜\", \"🚪\"):\n            mickey_pos = [mickey_pos[0] - 1, mickey_pos[1]]\n    return mickey_pos\n\n\ndef move_down(mickey_pos: list) -> list:\n    if mickey_pos[0] < 5:\n        if maze[mickey_pos[0] + 1][mickey_pos[1]] in (\"⬜\", \"🚪\"):\n            mickey_pos = [mickey_pos[0] + 1, mickey_pos[1]]\n    return mickey_pos\n\n\ndef move_left(mickey_pos: list) -> list:\n    if mickey_pos[1] > 0:\n        if maze[mickey_pos[0]][mickey_pos[1] - 1] in (\"⬜\", \"🚪\"):\n            mickey_pos = [mickey_pos[0], mickey_pos[1] - 1]\n    return mickey_pos\n\n\ndef move_right(mickey_pos: list) -> list:\n    if mickey_pos[1] < 5:\n        if maze[mickey_pos[0]][mickey_pos[1] + 1] in (\"⬜\", \"🚪\"):\n            mickey_pos = [mickey_pos[0], mickey_pos[1] + 1]\n    return mickey_pos\n\n\ndef move(pressed_key: str, mickey_pos: list) -> list:\n\n    match pressed_key:\n        case 'flecha abajo':\n            mickey_pos = move_down(mickey_pos)\n        case 'flecha izquierda':\n            mickey_pos = move_left(mickey_pos)\n        case 'flecha derecha':\n            mickey_pos = move_right(mickey_pos)\n        case 'flecha arriba':\n            mickey_pos = move_up(mickey_pos)\n        case 'esc':\n            mickey_pos =  []\n    return mickey_pos\n\n\nwhile True:\n    draw_maze(maze)\n    pressed_key = kb.read_event()\n\n    if pressed_key.event_type == \"down\":\n        mickey_prev = mickey_pos.copy()\n        mickey_pos = move(pressed_key.name, mickey_pos)\n        if not mickey_pos:\n            break\n        maze[mickey_prev[0]][mickey_prev[1]] = \"⬜\"\n        maze[mickey_pos[0]][mickey_pos[1]] = \"🐭\"\n        if mickey_pos == exit_door:\n            print(\"Mickey found the door!!! You Won!!!\")\n            break\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/python/nlarrea.py",
    "content": "\"\"\"\n * EJERCICIO:\n * ¡Disney ha presentado un montón de novedades en su D23! \n * Pero... ¿Dónde está Mickey?\n * Mickey Mouse ha quedado atrapado en un laberinto mágico \n * creado por Maléfica.\n * Desarrolla un programa para ayudarlo a escapar.\n * Requisitos:\n * 1. El laberinto está formado por un cuadrado de 6x6 celdas.\n * 2. Los valores de las celdas serán:\n *    - \"⬜️\" Vacío\n *    - ⬛️ Obstáculo\n *    - 🐭 Mickey\n *    - 🚪 Salida\n * Acciones:\n * 1. Crea una matriz que represente el laberinto (no hace falta\n * que se genere de manera automática).\n * 2. Interactúa con el usuario por consola para preguntarle hacia\n * donde se tiene que desplazar (arriba, abajo, izquierda o derecha).\n * 3. Muestra la actualización del laberinto tras cada desplazamiento.\n * 4. Valida todos los movimientos, teniendo en cuenta los límites\n * del laberinto y los obstáculos. Notifica al usuario.\n * 5. Finaliza el programa cuando Mickey llegue a la salida.\n\"\"\"\n\nfrom enum import Enum\nfrom typing import Literal\n\n\nEMPTY = \"⬜️\"\nPLAYER = \"🐭\"\nEXIT = \"🚪\"\nOBSTACLE = \"⬛️\"\n\nMAZE = [\n    [PLAYER, OBSTACLE, OBSTACLE, OBSTACLE, OBSTACLE, OBSTACLE],\n    [EMPTY, OBSTACLE, OBSTACLE, OBSTACLE, EMPTY, OBSTACLE],\n    [EMPTY, OBSTACLE, OBSTACLE, OBSTACLE, EMPTY, OBSTACLE],\n    [EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY],\n    [OBSTACLE, EMPTY, OBSTACLE, EMPTY, OBSTACLE, OBSTACLE],\n    [OBSTACLE, EMPTY, OBSTACLE, EMPTY, EMPTY, EXIT],\n]\n\n\nclass Action(Enum):\n    UP = \"w\"\n    DOWN = \"s\"\n    RIGHT = \"d\"\n    LEFT = \"a\"\n    EXIT = \"q\"\n\n\nclass Position:\n    def __init__(self, row: int, col: int, max_row: int, max_col: int):\n        self.row = row\n        self.col = col\n        self._max_row = max_row\n        self._max_col = max_col\n\n    def __eq__(self, value: object):\n        if isinstance(value, Position):\n            return value.row == self.row and value.col == self.col\n\n        return False\n\n    def __hash__(self) -> int:\n        return hash(self.row, self.col)\n\n    def move(self, direction: str):\n        if direction == Action.UP.value:\n            self._up()\n        elif direction == Action.DOWN.value:\n            self._down()\n        elif direction == Action.RIGHT.value:\n            self._right()\n        elif direction == Action.LEFT.value:\n            self._left()\n        else:\n            print(f\"La dirección '{direction}' no es posible.\")\n\n    def _up(self) -> tuple[int, int]:\n        if self.row > 0:\n            self.row -= 1\n        return (self.row, self.col)\n\n    def _down(self) -> tuple[int, int]:\n        if self.row < self._max_row:\n            self.row += 1\n        return (self.row, self.col)\n\n    def _left(self) -> tuple[int, int]:\n        if self.col > 0:\n            self.col -= 1\n        return (self.row, self.col)\n\n    def _right(self) -> tuple[int, int]:\n        if self.col < self._max_col:\n            self.col += 1\n        return (self.row, self.col)\n\n\ndef select_movement() -> str:\n    keys = [action.value for action in Action]\n    while True:\n        print(\"Movimientos posibles:\")\n        for action in Action:\n            print(f\" [{action.value.upper()}]: {action.name.capitalize()}\")\n\n        try:\n            selection = input(\"Selecciona qué hacer:\\n > \")\n            assert (\n                selection.isalpha() and selection.lower() in keys\n            ), f\"\\nDebes introducir una de las siguientes letras: {', '.join(keys)}\"\n\n        except AssertionError as error:\n            print(error)\n\n        else:\n            return selection.lower()\n\n\ndef print_maze(maze: list[list[str]]):\n    print()\n    for row in maze:\n        print(\"\".join(row))\n    print()\n\n\ndef update_maze(\n    maze: list[list[str]], new_position: Position\n) -> list[list[str]]:\n    # Get current player's position\n    old_player_pos = get_position(maze, PLAYER)\n\n    # Update player position to be empty from now on\n    maze[old_player_pos.row][old_player_pos.col] = EMPTY\n    # Update maze to show player in new position\n    maze[new_position.row][new_position.col] = PLAYER\n\n    return maze\n\n\ndef get_position(maze: list[list[str]], item: Literal[\"🐭\", \"🚪\"]) -> Position:\n    for nrow, row in enumerate(maze):\n        for ncol, col in enumerate(row):\n            if col == item:\n                return Position(\n                    row=nrow, col=ncol, max_row=len(maze), max_col=len(row)\n                )\n\n\ndef actions(maze: list[list[str]], position: Position) -> list[str]:\n    actions_ = []\n\n    # Up\n    if position.row > 0 and maze[position.row - 1][position.col] in [\n        EMPTY,\n        EXIT,\n    ]:\n        actions_.append(Action.UP.value)\n\n    # Down\n    if position.row < len(maze) - 1 and maze[position.row + 1][\n        position.col\n    ] in [EMPTY, EXIT]:\n        actions_.append(Action.DOWN.value)\n\n    # Left\n    if position.col > 0 and maze[position.row][position.col - 1] in [\n        EMPTY,\n        EXIT,\n    ]:\n        actions_.append(Action.LEFT.value)\n\n    # Right\n    if position.col < len(maze) - 1 and maze[position.row][\n        position.col + 1\n    ] in [EMPTY, EXIT]:\n        actions_.append(Action.RIGHT.value)\n\n    return actions_\n\n\ndef run(maze: list[list[str]]):\n    EXIT_POS = get_position(maze, EXIT)\n    player_pos = get_position(maze, PLAYER)\n\n    while True:\n        print_maze(maze)\n\n        selected = select_movement()\n        available_actions = actions(maze, player_pos)\n\n        if selected == Action.EXIT.value:\n            print(\"\\nSaliendo del juego.\")\n            break\n\n        elif selected not in available_actions:\n            print(\"\\nLa opción que has escogido no es posible.\")\n            continue\n\n        player_pos.move(selected)\n        maze = update_maze(maze, player_pos)\n\n        if player_pos == EXIT_POS:\n            print_maze(maze)\n            print(\"\\n\\n¡HAS ENCONTRADO LA SALIDA!\")\n            break\n\n\nif __name__ == \"__main__\":\n    run(MAZE)\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/python/oriaj3.py",
    "content": "\"\"\" \n33 - RESCATANDO A MICKEY\n\n/*\n * EJERCICIO:\n * ¡Disney ha presentado un montón de novedades en su D23! \n * Pero... ¿Dónde está Mickey?\n * Mickey Mouse ha quedado atrapado en un laberinto mágico \n * creado por Maléfica.\n * Desarrolla un programa para ayudarlo a escapar.\n * Requisitos:\n * 1. El laberinto está formado por un cuadrado de 6x6 celdas.\n * 2. Los valores de las celdas serán:\n *    - ⬜️ Vacío\n *    - ⬛️ Obstáculo\n *    - 🐭 Mickey\n *    - 🚪 Salida\n * Acciones:\n * 2. Interactúa con el usuario por consola para preguntarle hacia\n * donde se tiene que desplazar (arriba, abajo, izquierda o derecha).\n * 3. Muestra la actualización del laberinto tras cada desplazamiento.\n * 4. Valida todos los movimientos, teniendo en cuenta los límites\n * del laberinto y los obtáculos. Notifica al usuario.\n * 5. Finaliza el programa cuando Mickey llegue a la salida.\n */\n\"\"\"\n\nfrom enum import Enum\nimport random\nimport time\nimport os\nimport keyboard\n\nclass Valores_celdas(enumerate):\n    VACIO = \"⬜️\"\n    OBSTACULO = \"⬛️\"\n    MICKEY = \"🐭\"\n    SALIDA = \"🚪\"\n\nclass Movimientos(enumerate):\n    ARRIBA = \"w\"\n    ABAJO = \"s\"\n    IZQUIERDA = \"a\"\n    DERECHA = \"d\"\n\nclass Dificultades(Enum):\n    FACIL = 1\n    NORMAL = 2\n    DIFICIL = 3\n    \nclass Laberinto():\n    # Tamaño del laberinto\n    tamano :int  = 6\n    num_obstaculos :int = 0\n    posicion_micky  = [0, 0] \n    posicion_salida = [0, 0] \n\n    #Flag para saber si ha llegado a la salida\n    ha_llegado_a_salida : bool = False\n\n    # Tablero array bidemensional\n    tablero : list = []\n\n    def __init__ (self):\n        self.tablero = []\n\n        # Bienvenida al usuario\n        print(\"¡Bienvenido a RESCATANDO A MICKEY!\")\n        print(\"Mickey Mouse ha quedado atrapado en un laberinto mágico creado por Maléfica.\")\n        time.sleep(1)\n        print(\"Usa las teclas 'w', 's', 'a' y 'd' para mover a Mickey. Pulsa control + c para salir.\")\n        time.sleep(1)\n        tamano = int(input(\"Introduce el tamaño del laberinto (n): \"))\n\n        print(\"¡Buena suerte y recuerda que algunos laberintos son tan díficiles que no se pueden hacer!\")\n        time.sleep(1)\n\n        # Inicializar tablero\n        for i in range(tamano):\n            self.tablero.append([])\n            for j in range(self.tamano):\n                self.tablero[i].append(Valores_celdas.VACIO)\n        \n        # Coloco a Micky en una posición aleatoria de la primera columna\n        fila_mickey = random.randint(0, self.tamano - 1)\n        self.tablero[fila_mickey][0] = Valores_celdas.MICKEY\n        self.posicion_micky = [fila_mickey, 0]\n\n        # Coloco la salida en una posición aleatoria de la última columna\n        fila_salida = random.randint(0, self.tamano - 1)\n        self.tablero[fila_salida][self.tamano - 1] = Valores_celdas.SALIDA\n        self.posicion_salida = [fila_salida, self.tamano - 1]\n\n        self.num_obstaculos = self.calcula_dificultad()\n        while(self.num_obstaculos > 0):\n            fila_obstaculo = random.randint(0, self.tamano - 1)\n            columna_obstaculo = random.randint(0, self.tamano - 1)\n            if self.tablero[fila_obstaculo][columna_obstaculo] == Valores_celdas.VACIO:\n                self.tablero[fila_obstaculo][columna_obstaculo] = Valores_celdas.OBSTACULO\n                self.num_obstaculos -= 1 \n    def calcula_dificultad(self) -> int:\n        print(\"Selecciona la dificultad:\")\n        #1. Fácil\n        #2. Normal\n        #3. Difícil\n\n        # Muestro las dificultades (enumerate)\n        for nombre, miembro in Dificultades. __members__.items():\n            print(f\"{miembro.value}. {nombre}\")\n        \n        opcion = int(input(\"Introduce el índice: \"))\n\n        #Fórmula para calcular el número de obstáculos\n        \"\"\"    \n                        Díficultad\n        obstáculos    Facil Normal  Difícil\n        2x2 = 4         1    1      2\n        3x3 = 9         2    3      4\n        4x4 = 16        3    5      6\n        5x5 = 25        4    7      8\n        6x6 = 36        5    9      12\n        7x7 = 49        6    11     14\n        \"\"\"\n        match opcion:\n            case Dificultades.FACIL.value:\n                return self.tamano - 1\n            case Dificultades.NORMAL.value:\n                return (self.tamano - 1) + 2\n            case Dificultades.DIFICIL.value:\n                return (self.tamano - 1) * 2\n\n    def borra_pantalla(self):\n        os.system('cls' if os.name == 'nt' else 'clear')\n\n    def mostrar_tablero(self):\n        for i in range(self.tamano):\n            for j in range(self.tamano):\n                print(self.tablero[i][j], end=\" \")\n            print()\n    def comprobar_movimiento(self, posicion):\n        #Compruebo que esta dentro del tablero\n        if posicion[0] < 0 or posicion[0] >= self.tamano or posicion[1] < 0 or posicion[1] >= self.tamano:\n            return False\n        \n        #Compruebo que no hay obstáculo\n        if self.tablero[posicion[0]][posicion[1]] == Valores_celdas.OBSTACULO:\n            print(\"¡Has chocado con un obstáculo!\")\n            time.sleep(1)\n            return False\n        \n        #Compruebo que no hay salida\n        if self.tablero[posicion[0]][posicion[1]] == Valores_celdas.SALIDA:\n            print(\"¡Enhorabuena! Has rescatado a Mickey.\")\n            self.ha_llegado_a_salida = True\n            return False\n        \n        #Compruebo que hay vacío (no necesario)\n        if self.tablero[posicion[0]][posicion[1]] == Valores_celdas.VACIO:\n            return True\n\n    def mover_micky(self):\n        # Compruebo que el movimiento es válido\n        while True:\n            evento = keyboard.read_event(suppress=True)\n            if evento.event_type == keyboard.KEY_DOWN:\n                direccion = evento.name\n                if direccion in [Movimientos.ARRIBA, Movimientos.ABAJO, Movimientos.IZQUIERDA, Movimientos.DERECHA]:\n                    break\n        \n        futuro_movimiento = [0, 0]\n\n        match direccion:\n            case Movimientos.ARRIBA:\n                futuro_movimiento = [self.posicion_micky[0] - 1, self.posicion_micky[1]]\n\n            case Movimientos.ABAJO:\n                futuro_movimiento = [self.posicion_micky[0] + 1, self.posicion_micky[1]]\n\n            case Movimientos.IZQUIERDA:\n                futuro_movimiento = [self.posicion_micky[0], self.posicion_micky[1] - 1]\n\n            case Movimientos.DERECHA:\n                futuro_movimiento = [self.posicion_micky[0], self.posicion_micky[1] + 1]\n\n        if self.ha_llegado_a_salida:\n            return True\n\n        if self.comprobar_movimiento(futuro_movimiento):\n            self.tablero[self.posicion_micky[0]][self.posicion_micky[1]] = Valores_celdas.VACIO\n            self.tablero[futuro_movimiento[0]][futuro_movimiento[1]] = Valores_celdas.MICKEY\n            self.posicion_micky = futuro_movimiento\n        else:\n            print(\"Movimiento no válido.\")\n\n    def jugar(self):\n        while not self.ha_llegado_a_salida:\n            self.borra_pantalla()\n            self.mostrar_tablero()\n            self.mover_micky()\n\n    def __del__(self):\n        self.tablero = None\n\ndef main():\n    lab = Laberinto()\n    lab.jugar()\n    while(True):\n        if input(\"¡Has rescatado a Mickey!¿Quieres jugar de nuevo? (s/n) \") == \"n\":\n            lab.borra_pantalla()\n            break\n        lab = None\n        lab = Laberinto()\n        lab.jugar()\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/python/pyramsd.py",
    "content": "def crear_laberinto():\n    laberinto = [\n        ['⬛️', '⬛️', '⬜️', '⬛️', '⬛️', '🚪'],\n        ['⬛️', '⬛️', '⬜️', '⬛️', '⬛️', '⬜️'],\n        ['⬜️', '⬜️', '⬜️', '⬛️', '⬛️', '⬜️'],\n        ['⬜️', '⬛️', '⬜️', '⬜️', '⬜️', '⬜️'],\n        ['⬜️', '⬜️', '⬜️', '⬛️', '⬜️', '⬛️'],\n        ['⬛️', '⬛️', '⬛️', '🐭', '⬜️', '⬛️']\n    ]\n    return laberinto\n\ndef mover_raton(laberinto):\n    # Encontrar la posición actual del ratón (🐭)\n    for i in range(len(laberinto)):\n        for j in range(len(laberinto[i])):\n            if laberinto[i][j] == '🐭':\n                raton_pos = (i, j)\n                break\n    \n    # Opciones\n    print(\"Opciones de movimiento:\")\n    print(\"1. Arriba\")\n    print(\"2. Abajo\")\n    print(\"3. Izquierda\")\n    print(\"4. Derecha\")\n    \n    movimiento = input(\"¿Hacia dónde deseas mover al ratón? (1: Arriba, 2: Abajo, 3: Izquierda, 4: Derecha): \")\n\n    if movimiento == \"1\":\n        dx, dy = -1, 0\n    elif movimiento == \"2\":\n        dx, dy = 1, 0\n    elif movimiento == \"3\":\n        dx, dy = 0, -1\n    elif movimiento == \"4\":\n        dx, dy = 0, 1\n    else:\n        print(\"\\033[31mMovimiento inválido.\\33[0m\")\n        \n\n    # Nueva posicion\n    nx, ny = raton_pos[0] + dx, raton_pos[1] + dy\n\n    # Ratón llaga a la puerta\n    if 0 <= nx < len(laberinto) and 0 <= ny < len(laberinto[0]) and laberinto[nx][ny] == '🚪':\n        laberinto[raton_pos[0]][raton_pos[1]] = '⬜️'\n        laberinto[nx][ny] = '🐭'\n        print(\"\\n\\033[32mGanaste!!!\\033[0m\")\n        return True\n\n    # Si la posición es válida\n    if 0 <= nx < len(laberinto) and 0 <= ny < len(laberinto[0]) and laberinto[nx][ny] == '⬜️':\n        laberinto[raton_pos[0]][raton_pos[1]] = '⬜️'\n        laberinto[nx][ny] = '🐭'\n    else:\n        print(\"\\033[31mMovimiento no válido. El ratón no puede moverse en esa dirección.\\33[0m\")\n\n\nlaberinto = crear_laberinto()\n\nprint(\"Labertinto inicial:\")\nfor fila in laberinto:\n    print(''.join(fila))\n\nwhile True:\n    if mover_raton(laberinto):\n        print(\"\\n\\033[38;5;214mLabertinto después de mover al ratón:\\033[0m\")\n        for fila in laberinto:\n            print(''.join(fila))\n        break\n\n    print(\"\\n\\033[38;5;214mLabertinto después de mover al ratón:\\033[0m\")\n    for fila in laberinto:\n        print(''.join(fila))\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/python/raulG91.py",
    "content": "#Define matrix\n\nmatrix = [[\"🐭\",\"⬜️\",\"⬜️\",\"⬜️\",\"⬜️\",\"⬛️\"],\n          [\"⬛️\",\"⬜️\",\"⬛️\",\"⬜️\",\"⬜️\",\"⬜️\"],\n          [\"⬜️\",\"⬜️\",\"⬛️\",\"⬜️\",\"⬜️\",\"⬜️\"],\n          [\"⬜️\",\"⬜️\",\"⬜️\",\"⬜️\",\"⬛️\",\"⬛️\"],\n          [\"⬜️\",\"⬛️\",\"⬜️\",\"⬜️\",\"⬜️\",\"⬜️\"],\n          [\"⬛️\",\"⬜️\",\"⬛️\",\"⬜️\",\"⬜️\",\"🚪\"]]\n\n\ndef print_matrix():\n    for row in matrix:\n        row_string = \"\"\n        for column in row:\n            row_string+=column\n\n        print(row_string)\n\n#Mickey's initial position\nmickey_pos = [0,0]\nprev_value=\"⬜️\"\nprint_matrix()\nwhile True:\n    print(\"Enter left to move to the left\")\n    print(\"Enter right to move to the right\")\n    print(\"Enter up to move up\")\n    print(\"Enter down to move down\")\n    print(\"Enter exit to termiante the program\")\n    option = str(input(\"Enter option \")).lower()\n\n    if option == \"left\":\n        if mickey_pos[1] - 1 < 0:\n            print(\"Imposible to move outsite the limits\")\n        else:\n            if matrix[mickey_pos[0]][mickey_pos[1]-1] == \"⬛️\":\n                print(\"Imposible to move there is an obstacle\")\n            else:    \n                matrix[mickey_pos[0]][mickey_pos[1]] = prev_value\n                prev_value = matrix[mickey_pos[0]][mickey_pos[1]-1]\n                mickey_pos[1]-=1\n                matrix[mickey_pos[0]][mickey_pos[1]]=\"🐭\"\n              \n    elif option == \"right\":\n        if mickey_pos[1] + 1 > 5:\n            print(\"Imposible to move outsite the limits\")\n        else:\n            if matrix[mickey_pos[0]][mickey_pos[1]+1] == \"⬛️\":\n                print(\"Imposible to move there is an obstacle\")\n            else:    \n                matrix[mickey_pos[0]][mickey_pos[1]] = prev_value\n                prev_value = matrix[mickey_pos[0]][mickey_pos[1]+1]\n                mickey_pos[1]+=1\n                matrix[mickey_pos[0]][mickey_pos[1]]=\"🐭\"\n    elif option == \"up\":\n        if mickey_pos[0] - 1 < 0:\n            print(\"Imposible to move outsite the limits\")\n        else:\n            if matrix[mickey_pos[0]-1][mickey_pos[1]] == \"⬛️\":\n                print(\"Imposible to move there is an obstacle\")\n            else:    \n                matrix[mickey_pos[0]][mickey_pos[1]] = prev_value\n                prev_value = matrix[mickey_pos[0]-1][mickey_pos[1]]\n                mickey_pos[0]-=1\n                matrix[mickey_pos[0]][mickey_pos[1]]=\"🐭\" \n    elif option == \"down\":\n        if mickey_pos[0] +1 > 5:\n            print(\"Imposible to move outsite the limits\")\n        else:\n            if matrix[mickey_pos[0]+1][mickey_pos[1]] == \"⬛️\":\n                print(\"Imposible to move there is an obstacle\")\n            else:    \n                matrix[mickey_pos[0]][mickey_pos[1]] = prev_value\n                prev_value = matrix[mickey_pos[0]+1][mickey_pos[1]]\n                mickey_pos[0]+=1\n                matrix[mickey_pos[0]][mickey_pos[1]]=\"🐭\"\n    elif option == \"exit\":\n        break\n    else:\n        print(\"Incorrect option, please try again\")\n\n    #Check if it is the end\n    if prev_value == \"🚪\":\n        print(\"Exit has been found...\") \n        break   \n    print_matrix()      "
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/python/raynerpv2022.py",
    "content": "\n# /*\n#  * EJERCICIO:\n#  * ¡Disney ha presentado un montón de novedades en su D23! \n#  * Pero... ¿Dónde está Mickey?\n#  * Mickey Mouse ha quedado atrapado en un laberinto mágico \n#  * creado por Maléfica.\n#  * Desarrolla un programa para ayudarlo a escapar.\n#  * Requisitos:\n#  * 1. El laberinto está formado por un cuadrado de 6x6 celdas.\n#  * 2. Los valores de las celdas serán:\n#  *    - ⬜️ Vacío\n#  *    - ⬛️ Obstáculo\n#  *    - 🐭 Mickey\n#  *    - 🚪 Salida\n#  * Acciones:\n#  * 1. Crea una matriz que represente el laberinto (no hace falta\n#  * que se genere de manera automática).\n#  * 2. Interactúa con el usuario por consola para preguntarle hacia\n#  * donde se tiene que desplazar (arriba, abajo, izquierda o derecha).\n#  * 3. Muestra la actualización del laberinto tras cada desplazamiento.\n#  * 4. Valida todos los movimientos, teniendo en cuenta los límites\n#  * del laberinto y los obstáculos. Notifica al usuario.\n#  * 5. Finaliza el programa cuando Mickey llegue a la salida.\n#  */\n\nfrom abc import ABC, abstractmethod\nfrom random import randint, choice \n\n\nclass VirtualBoardGenerator(ABC):\n#  clase virtual para generar tablero, puede ser generado manual,  automatico o de alguna forma diferente\n    @abstractmethod\n    def generator(self):\n        pass\n    \n\n     \n\nclass VirtualShowBoard(ABC):\n    # clase virtual para mostrar el tablero, puede ser mostrado en consola, en interfaz grafica, en archivo, impreso en db\n    @abstractmethod\n    def ShowBoard(self):\n        pass\n\nclass VirtualValidator(ABC):\n#  clase virtual para validar, pueden existir diferentes tipos de validaciones\n    # @abstractmethod\n    # def validator(self, XYuserMove : list, XYcurrent: list):\n    #     pass\n    @abstractmethod\n    def validator(self, data):\n         pass\n    \n         \nclass VirtualMenu(ABC):\n\n    @abstractmethod\n    def boardType(self):\n        pass\n\n    @abstractmethod\n    def movement(self ):\n        pass\n\n    @abstractmethod\n    def userMenu(self, op: list):\n        pass\n\nclass CBoard:\n    def __init__(self, board: VirtualBoardGenerator):\n        self._board =  board.generator()\n        \n        self.mikyPosition = []\n        self.exitPosition = []\n         \n        \n        \n\n\n    def getBoard(self):\n        return self._board\n    \n    def isWinner(self, pos):\n         if pos == self.exitPosition:\n              return True\n         return False\n    \n    def updatePos(self, new_pos: list):\n            self._board[self.mikyPosition[0]][self.mikyPosition[1]] = '⬜️'\n            self._board[new_pos[0]][new_pos[1]] = '🐭'\n            self.mikyPosition = new_pos\n            if self.isWinner(new_pos):\n                 return True\n            return False\n\n    \n    def getEmpty(self):\n         listEmpty = []\n         for i,vi in enumerate(self._board):\n              for j, vj in enumerate(vi):\n                   if self._board[i][j] == '⬜️':\n                        listEmpty.append([i,j])\n         self.emptyPos = listEmpty\n    \n    def newBoard(self, board: VirtualBoardGenerator):\n        self._board =  board.generator()\n\n    def getNextPosition(self, op: str):\n         newPosition = None\n          \n         if self.mikyPosition != None :\n            if op == 'w' :\n                 newPosition = [self.mikyPosition[0]-1,self.mikyPosition[1]]\n            elif op == 'a':\n                 newPosition = [self.mikyPosition[0],self.mikyPosition[1]-1]\n            elif op == 'd':\n                 newPosition = [self.mikyPosition[0],self.mikyPosition[1]+1]\n            elif op == 'x':\n                 newPosition = [self.mikyPosition[0]+1,self.mikyPosition[1]]\n         return newPosition\n                 \n\nclass CValidatorBoard(VirtualValidator):\n     \n     def __init__(self):\n          self.input = [\"q\",\"a\",\"m\" ]\n     \n     def validator(self, data):\n           \n          return data in self.input\n     \nclass CValidatorMovement(VirtualValidator):\n     \n     def __init__(self):\n          self.input = [\"q\",\"a\",\"w\",\"d\",\"x\"]\n     \n     def validator(self, data):\n           \n          return data in self.input\n     \n     def _isPositionValid(self, empty:list, newPosition : list ):\n          \n         if newPosition in empty :\n              return True\n         return False\n               \n                   \n\nclass CShowTerminalBoard(VirtualShowBoard):\n#  clase para mostrar tablero por consola, la unica por el momento\n# recibe una matriz, no le interesa que es solo la muestra en consola\n\n    def ShowBoard(self, matriz: list):\n        for i in matriz:\n             print(i)\n\nclass ManualBoardGeneration(VirtualBoardGenerator ):\n    #  clase para generar manualmente el tablerio con posiciones fijas\n     \n     \n    def generator(self):\n        \n        return  [   ['🐭','⬜️','⬜️','⬜️','⬜️','⬜️'],\n                    ['⬜️','⬛️','⬛️','⬜️','⬛️','⬜️'],\n                    ['⬜️','⬛️','⬜️','⬜️','⬛️','⬜️'],\n                    ['⬜️','⬛️','⬜️','⬛️','⬛️','⬛️'],\n                    ['⬜️','⬜️','⬜️','⬛️','⬛️','⬛️'],\n                    ['⬛️','⬜️','⬜️','⬜️','⬜️','🚪']]\n         \n          \n\nclass RandomBoardGenerator(VirtualBoardGenerator):\n#  clase para generar el tablero aleatorio\n#   recibe tamano\n#  devuelve tamanno, posiciones d miky, obstaculos, de salida y de espacios en blanco\n\n    def __init__(self, col, row : int):\n        self.col, self.row = col,row\n         \n    def _mikeyPosition(self):\n        self.mikyX = randint(0,self.col)\n        self.mikyY = randint(0,self.row)\n         \n\n    \n    def _getMikyPosition(self):\n        return [self.mikyX, self.mikyY]\n    \n    def _exitPosition(self):\n         \n        self.exitX = randint(0,self.col)\n         \n\n        match self.exitX:\n            case 0 | (self.col):\n                    self.exitY = randint(0,self.row)\n            case _:\n                 self.exitY = choice([0,self.row])\n         \n\n    def _getExitPosition(self):\n         return [self.exitX, self.exitY]\n\n    def _obstaclePosition(self):\n        self.obstacleX = []\n        self.obstacleY = []\n\n        for i in range(self.col*self.row//2):\n            self.obstacleX.append(randint(0,6))\n            self.obstacleY.append(randint(0,6))\n\n    def _getObstaclePosition(self):\n        return self.obstacleX, self.obstacleY\n    \n    def generator(self):\n        mikyChar,exitChar, obstChar, emptyChar = '🐭','🚪','⬛️','⬜️'\n\n        self._mikeyPosition()\n        self._exitPosition()\n        self._obstaclePosition()\n\n        self.matriz = [[emptyChar]*(self.col+1)  for _ in range(self.row+1)] \n         \n        for i, vi in enumerate(self.matriz):\n             print(i, vi)\n\n        self.matriz[self.mikyX][self.mikyY] = mikyChar\n        self.matriz[self.exitX][self.exitY] = exitChar\n\n        obstPosX, obstPosY = self._getObstaclePosition() \n\n        for i in range(len(obstPosX)-1):\n                if self.matriz[obstPosX[i]][obstPosY[i]] == emptyChar:\n                    self.matriz[obstPosX[i]][obstPosY[i]] = obstChar\n        \n    \n        return self.matriz\n\n\nclass CMenu(VirtualMenu):\n\n    def __init__(self):\n        self.op = 0\n\n    def boardType(self, validator: VirtualValidator):\n        \n        print(\"Seleccione tipo de Laberinto (Aleatorio / Manual) (A/M) and Q to exit\")\n        return self.userMenu(validator)\n        \n    def movement(self, validator: VirtualValidator):\n        \n        print(\"Seleciona un movimiento valido: \")\n        print(\" (A Left) (W Up) (D Right) (X Down) and Q to exit\")\n        return self.userMenu(validator)\n         \n\n    def userMenu(self, validator: VirtualValidator):\n         \n        while True: \n             \n            self.op = input()\n            if not validator.validator(self.op):\n                    print(\"seleccione opcion valida\")\n                    continue\n            return self.op    \n\n\n\nclass BoardFactory:\n    \n    def createBoard(self,op: str):\n\n         \n            if op == \"a\":\n                gen  = RandomBoardGenerator(6,6)\n                a = CBoard(gen)\n                 \n\n                return a,{'miky':gen._getMikyPosition(), 'exit':gen._getExitPosition()}\n                 \n            elif op ==  \"m\":\n                gen  = ManualBoardGeneration()\n                return CBoard(gen), {'miky':[0,0], 'exit':[5,5]}\n            \n            elif op == \"q\":\n                return None\n                 \n\n\nclass Game:\n#  clase orquestadora\n#  recibe un tablero, y las accions a implementar\n#  no le interesa mas nada, solo recibe oredenes y decide cuando y sobre que ejecutarla\n\n    def __init__(self,):\n        self.state = \"INICIAL\"\n        self.board = None\n            \n    def setState(self, op: str):\n        if  op == \"q\" or op == \"WINN\":\n             self.state = \"FIN\"\n         \n            \n    def start(self, Menu: VirtualMenu, boardfactory: BoardFactory, validator: VirtualValidator) :\n                \n                op = Menu.boardType(validator)\n                \n                self.board, itemPosition = boardfactory.createBoard(op)\n                self.board.mikyPosition = itemPosition.get('miky')\n                self.board.exitPosition = itemPosition.get('exit')\n                self.setState(op)\n\n\n    def execute(self,ShowBoard: VirtualShowBoard, menu: VirtualMenu, validator: VirtualValidator):\n            \n            while self.state != \"FIN\":\n                print(\" Donde esta Mikey? \")\n                print()\n                print(\"Mapa Actual\")\n                ShowBoard.ShowBoard(self.board.getBoard())\n                op = menu.movement(validator)\n                #recibo la opcion validada\n                # alguien debe de recibir esa opcion y analizar si el movimiento es posible\n                new_position = self.board.getNextPosition(op)\n                self.board.getEmpty()\n                self.board.emptyPos.append(self.board.exitPosition)\n                if validator._isPositionValid(self.board.emptyPos,new_position):\n                     \n                     if self.board.updatePos(new_position):\n                          ShowBoard.ShowBoard(self.board.getBoard())\n                          self.setState(\"WINN\")\n                          print(\" You are te Winner\")\n                          continue\n                          \n                else :\n                     print(\"Movimiento imposible\")\n\n                 \n                self.setState(op)\n\n        \n\n\nshowBoard = CShowTerminalBoard() # lo muestro por terminal\nmenu = CMenu()\nbf = BoardFactory()\nvalidator_board = CValidatorBoard()\nvalidator_mov = CValidatorMovement()\ng = Game()\n \n\ng.start(menu, bf, validator_board)\ng.execute(showBoard, menu, validator_mov)  \n\n\n \n \n \n\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/python/redom69.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * ¡Disney ha presentado un montón de novedades en su D23! \n * Pero... ¿Dónde está Mickey?\n * Mickey Mouse ha quedado atrapado en un laberinto mágico \n * creado por Maléfica.\n * Desarrolla un programa para ayudarlo a escapar.\n * Requisitos:\n * 1. El laberinto está formado por un cuadrado de 6x6 celdas.\n * 2. Los valores de las celdas serán:\n *    - ⬜️ Vacío\n *    - ⬛️ Obstáculo\n *    - 🐭 Mickey\n *    - 🚪 Salida\n * Acciones:\n * 1. Crea una matriz que represente el laberinto (no hace falta\n * que se genere de manera automática).\n * 2. Interactúa con el usuario por consola para preguntarle hacia\n * donde se tiene que desplazar (arriba, abajo, izquierda o derecha).\n * 3. Muestra la actualización del laberinto tras cada desplazamiento.\n * 4. Valida todos los movimientos, teniendo en cuenta los límites\n * del laberinto y los obtáculos. Notifica al usuario.\n * 5. Finaliza el programa cuando Mickey llegue a la salida.\n */\n\"\"\"\n\nimport random\n\n\n# Constantes\nVACIO = \"⬜️\"\nOBSTACULO = \"⬛️\"\nMICKEY = \"🐭\"\nSALIDA = \"🚪\"\n\ndef generateMaze(width, height, total=10):\n\n    maze = [[VACIO for _ in range(width)] for _ in range(height)]\n\n    \n    mickeyPos = (random.randint(0, height - 1), random.randint(0, width - 1))\n    maze[mickeyPos[0]][mickeyPos[1]] = MICKEY\n\n    while True:\n        end = (random.randint(0, height - 1), random.randint(0, width - 1))\n        if end != mickeyPos:\n            maze[end[0]][end[1]] = SALIDA\n            break\n    \n    obstacles = 0\n    while obstacles < total:\n        obstacles_pos = (random.randint(0, height - 1), random.randint(0, width - 1))\n        if maze[obstacles_pos[0]][obstacles_pos[1]] == VACIO:\n            maze[obstacles_pos[0]][obstacles_pos[1]] = OBSTACULO\n            obstacles += 1\n    \n    return maze, mickeyPos, end\n\ndef showMaze(maze):\n    for row in maze:\n        print(\"\".join(row))\n\ndef isValid(newMove,maze):\n    x,y = newMove\n    if -7 <= x <= 7 and -7 <= y <= 7:\n        if maze[x][y] != OBSTACULO:\n            return True\n    return False \n\ndef moveMickey(maze,mickeyPos,move):\n    x,y = mickeyPos\n\n    if move == 'w' :\n        newMove= (x-1,y)\n    elif  move == 's':\n        newMove = (x+1,y)\n    elif move == 'a':\n        newMove = (x,y-1)\n    elif  move == 'd':\n        newMove = (x,y+1)\n    else:\n        newMove = mickeyPos\n\n    if isValid(newMove,maze):\n        maze[x][y] = VACIO\n        mickeyPos = newMove\n        maze[newMove[0]][newMove[1]]= MICKEY\n\n    return  mickeyPos\n\n\n\ndef main():\n    width = 6\n    height = 6\n    maze, mickeyPos, end = generateMaze(width, height)\n\n    while True:\n        showMaze(maze)\n        move = input(\"Mueve a Mickey (w/a/s/d): \")\n        mickeyPos = moveMickey(maze,mickeyPos,move)    \n\n        if mickeyPos == end :\n            print(\"¡Mickey ha llegado a la salida!\",MICKEY)\n            break\n\n\n\nif __name__ == \"__main__\":\n    main()"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/python/rigo93acosta.py",
    "content": "'''\n/*\n * EJERCICIO:\n * ¡Disney ha presentado un montón de novedades en su D23! \n * Pero... ¿Dónde está Mickey?\n * Mickey Mouse ha quedado atrapado en un laberinto mágico \n * creado por Maléfica.\n * Desarrolla un programa para ayudarlo a escapar.\n * Requisitos:\n * 1. El laberinto está formado por un cuadrado de 6x6 celdas.\n * 2. Los valores de las celdas serán:\n *    - ⬜️ Vacío\n *    - ⬛️ Obstáculo\n *    - 🐭 Mickey\n *    - 🚪 Salida\n * Acciones:\n * 1. Crea una matriz que represente el laberinto (no hace falta\n * que se genere de manera automática).\n * 2. Interactúa con el usuario por consola para preguntarle hacia\n * donde se tiene que desplazar (arriba, abajo, izquierda o derecha).\n * 3. Muestra la actualización del laberinto tras cada desplazamiento.\n * 4. Valida todos los movimientos, teniendo en cuenta los límites\n * del laberinto y los obtáculos. Notifica al usuario.\n * 5. Finaliza el programa cuando Mickey llegue a la salida.\n */\n'''\n\nmaze = [\n    ['🐭', '⬛️', '⬜️', '⬜️', '⬜️', '⬜️'],\n    ['⬜️', '⬜️', '⬜️', '⬛️', '⬜️', '⬛️'],\n    ['⬜️', '⬜️', '⬜️', '⬜️', '⬛️', '⬜️'],\n    ['⬛️', '⬜️', '⬛️', '⬜️', '⬛️', '⬜️'],\n    ['⬛️', '⬜️', '⬛️', '⬜️', '⬜️', '⬜️'],\n    ['⬛️', '⬜️', '⬜️', '⬛️', '⬛️', '🚪']\n]\n\n\nmickey = [0, 0]\ndoor_out = lambda x, y: maze[x][y] == '🚪'\n\ndef chart_end():\n    print(f\"{45*'*'}\")\n    print(\"¡Felicidades! Mickey ha salido del laberinto\")\n    print(f\"{45*'*'}\")\n\ndef maze_print(maze):\n    for row in maze:\n        for cell in row:\n            print(str(cell).ljust(1), end=\"\")\n        print()\n\nmaze_print(maze)\n\nwhile True:\n    print(\"\\nHacia donde se tiene que desplazar Mickey?\")\n    print(\"[w] Arriba\")\n    print(\"[s] Abajo\")\n    print(\"[a] Izquierda\")\n    print(\"[d] Derecha\")\n    direction = input(\"Dirección: \")\n    \n    current_row, current_col = mickey\n    new_row, new_col = current_row, current_col\n\n    match direction:\n        \n        case \"w\":\n            new_row -= 1\n\n        case \"s\":\n            new_row += 1\n        case \"a\":\n            new_col -= 1\n        case \"d\":\n            new_col += 1\n        case _:\n            print(\"Dirección no válida\")\n            continue\n    \n    if new_row < 0 or new_row >= len(maze) or new_col < 0 or new_col >= len(maze):\n        print(\"Desplezamiento fuera del laberinto.\")\n        print(\"Movimiento no válido.\")\n        continue\n    else:\n        if maze[new_row][new_col] == '⬛️':\n            print(\"Hay un obstáculo.\")\n            print(\"Movimiento no válido.\")\n            continue\n        elif door_out(new_row, new_col):\n            maze[current_row][current_col] = '⬜️'\n            maze[new_row][new_col] = '🐭'\n            mickey = [new_row, new_col]\n            maze_print(maze)\n            chart_end()\n            break\n        else:\n            maze[current_row][current_col] = '⬜️'\n            maze[new_row][new_col] = '🐭'\n            mickey = [new_row, new_col]\n            maze_print(maze)\n    \n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/python/santyjl.py",
    "content": "# #33 RESCATANDO A MICKEY\n#### Dificultad: Fácil | Publicación: 12/08/24 | Corrección: 19/08/24\n\n\"\"\"\n/*\n * EJERCICIO:\n * ¡Disney ha presentado un montón de novedades en su D23!\n * Pero... ¿Dónde está Mickey?\n * Mickey Mouse ha quedado atrapado en un laberinto mágico\n * creado por Maléfica.\n * Desarrolla un programa para ayudarlo a escapar.\n * Requisitos:\n * 1. El laberinto está formado por un cuadrado de 6x6 celdas.\n * 2. Los valores de las celdas serán:\n *    - ⬜️ Vacío\n *    - ⬛️ Obstáculo\n *    - 🐭 Mickey\n *    - 🚪 Salida\n * Acciones:\n * 1. Crea una matriz que represente el laberinto (no hace falta\n * que se genere de manera automática).\n * 2. Interactúa con el usuario por consola para preguntarle hacia\n * donde se tiene que desplazar (arriba, abajo, izquierda o derecha).\n * 3. Muestra la actualización del laberinto tras cada desplazamiento.\n * 4. Valida todos los movimientos, teniendo en cuenta los límites\n * del laberinto y los obtáculos. Notifica al usuario.\n * 5. Finaliza el programa cuando Mickey llegue a la salida.\n */\n\"\"\"\n\nimport os\nimport time\n\nlaberinto= [\n    [\"🐭\",\"⬜️\",\"⬜️\",\"⬛️\",\"⬜️\",\"⬛️\"],\n    [\"⬜️\",\"⬛️\",\"⬛️\",\"⬜️\",\"⬜️\",\"⬛️\"],\n    [\"⬜️\",\"⬜️\",\"⬛️\",\"⬛️\",\"⬛️\",\"⬜️\"],\n    [\"⬛️\",\"⬜️\",\"⬜️\",\"⬛️\",\"⬜️\",\"⬜️\"],\n    [\"⬜️\",\"⬜️\",\"⬜️\",\"⬜️\",\"⬜️\",\"⬜️\"],\n    [\"⬛️\",\"⬜️\",\"⬛️\",\"⬜️\",\"⬜️\",\"🚪\"]\n]\n\ndef formatear_laberinto():\n    for linea in laberinto:\n        print(\"\".join(linea))\n\n    print()\n\nprint( \"Mickey Mouse ha quedado atrapado en un laberinto mágico creado por Maléfica.\")\n\ncoordenadas_mickey:list = [0,0]\n\nwhile True:\n    formatear_laberinto()\n\n    print(\"\"\"\n          (W)- Arriba,\n          (S)- Abajo,\n          (A)- Izquierda,\n          (D)- Derecha\n          \"\"\")\n    accion:str = input(\"Elige el movimiento que hara Mickey Mouse para salir del laberinto: \")\n\n    linea_actual, columna_actual = coordenadas_mickey\n    linea_nueva, columna_nueva = linea_actual, columna_actual\n\n    match accion.lower():\n        case \"w\":\n            linea_nueva = linea_actual - 1\n        case \"s\":\n            linea_nueva = linea_actual + 1\n\n        case \"a\":\n            columna_nueva = columna_actual - 1\n\n        case \"d\":\n            columna_nueva = columna_actual + 1\n        case _:\n            print(\"Dirección no válida.\\n\")\n            continue\n\n    if linea_nueva < 0 or columna_nueva < 0 or linea_nueva > 5 or columna_nueva > 5:\n        print(\"este movimiento no es posible\")\n        time.sleep(1)\n        os.system(\"cls\")\n        continue\n\n    elif \"⬛️\" == laberinto[linea_nueva][columna_nueva]:\n        print(\"En este camino hay un obstaculo, no puedes pasar, busca otro camino.\")\n        print(\"\")\n        time.sleep(1)\n        os.system(\"cls\")\n        continue\n\n    else:\n        if \"🚪\" == laberinto[linea_nueva] [columna_nueva]:\n            print(\"Felicidades, has logrado escapar del laberinto\")\n            break\n\n        else:\n            laberinto[linea_actual] [columna_actual] = \"⬜\"\n            laberinto[linea_nueva] [columna_nueva] = \"🐭\"\n            coordenadas_mickey = [linea_nueva , columna_nueva]\n            time.sleep(1.5)\n            os.system(\"cls\")\n            continue\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/rust/kenysdev.rs",
    "content": "/*\n╔═══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado                ║\n║ GitHub: https://github.com/Kenysdev   ║\n║ 2024 -  Rust                          ║\n╚═══════════════════════════════════════╝\n-----------------------------------------------------\n* RESCATANDO A MICKEY\n-----------------------------------------------------\n * ¡Disney ha presentado un montón de novedades en su D23!\n * Pero... ¿Dónde está Mickey?\n * Mickey Mouse ha quedado atrapado en un laberinto mágico\n * creado por Maléfica.\n * Desarrolla un programa para ayudarlo a escapar.\n * Requisitos:\n * 1. El laberinto está formado por un cuadrado de 6x6 celdas.\n * 2. Los valores de las celdas serán:\n *    - ⬜️ Vacío\n *    - ⬛️ Obstáculo\n *    - 🐭 Mickey\n *    - 🚪 Salida\n * Acciones:\n * 1. Crea una matriz que represente el laberinto (no hace falta\n * que se genere de manera automática).\n * 2. Interactúa con el usuario por consola para preguntarle hacia\n * donde se tiene que desplazar (arriba, abajo, izquierda o derecha).\n * 3. Muestra la actualización del laberinto tras cada desplazamiento.\n * 4. Valida todos los movimientos, teniendo en cuenta los límites\n * del laberinto y los obtáculos. Notifica al usuario.\n * 5. Finaliza el programa cuando Mickey llegue a la salida.\n*/\n\nuse std::cell::RefCell;\nuse std::collections::HashMap;\nuse std::io::{self, Write};\nuse std::rc::Rc;\n\n// [dependencies]\n// rand = \"0.8.5\"\n// https://crates.io/crates/rand\nuse rand::prelude::*;\n\n//____________________________________________________________\nstruct Input;\n\nimpl Input {\n    fn get(&self, msg: &str) -> String {\n        print!(\"{}\", msg);\n        io::stdout().flush().expect(\"Error flushing output buffer.\");\n        let mut input = String::new();\n        io::stdin()\n            .read_line(&mut input)\n            .expect(\"Error reading input.\");\n        return input.trim().to_string();\n    }\n}\n\n//____________________________________________________________\nstruct Data {\n    maze: Vec<Vec<String>>,\n    position_mouse: (usize, usize),\n    exit_location: (usize, usize),\n    width: usize,\n    height: usize,\n    title: String,\n    obstacle_char: String,\n    empty_char: String,\n    mouse_char: String,\n    exit_char: String,\n}\n\nimpl Data {\n    fn new(config: HashMap<&str, &str>) -> Rc<RefCell<Self>> {\n        let size: Vec<&str> = config[\"size\"].split(',').collect();\n        let width = size[0].trim().parse().expect(\"Invalid width value\");\n        let height = size[1].trim().parse().expect(\"Invalid height value\");\n\n        Rc::new(RefCell::new(Data {\n            maze: Vec::new(),\n            position_mouse: (0, 0),\n            exit_location: (0, 0),\n            width,\n            height,\n            title: config[\"title\"].to_string(),\n            obstacle_char: config[\"obstacle\"].to_string(),\n            empty_char: config[\"empty\"].to_string(),\n            mouse_char: config[\"mouse\"].to_string(),\n            exit_char: config[\"exit\"].to_string(),\n        }))\n    }\n\n    fn print_maze(&self) {\n        println!(\"--------------------------------------\");\n        for row in &self.maze {\n            println!(\"{}\", row.join(\"\"));\n        }\n        println!(\"--------------------------------------\");\n    }\n\n    fn print_config(&self) {\n        println!(\n            \"{}\\nSize: {}*{}\\nObstacle: {}\\nEmpty: {}\\nMouse: {}\\nExit: {}\",\n            self.title,\n            self.width,\n            self.height,\n            self.obstacle_char,\n            self.empty_char,\n            self.mouse_char,\n            self.exit_char\n        )\n    }\n}\n\n//____________________________________________________________\nstruct Moves {\n    data: Rc<RefCell<Data>>,\n}\n\nimpl Moves {\n    fn new(data: Rc<RefCell<Data>>) -> Self {\n        Moves { data }\n    }\n\n    fn can_move(&self, y: isize, x: isize, old_y: usize, old_x: usize) {\n        let mut data_ref = self.data.borrow_mut();\n        let rows = data_ref.maze.len();\n        let cols = data_ref.maze[0].len();\n        if y < 0 || x < 0 || y >= rows as isize || x >= cols as isize {\n            println!(\"🚨I can't jump over the edges.🚨\");\n            return;\n        }\n\n        let y = y as usize;\n        let x = x as usize;\n\n        if data_ref.maze[y][x] == data_ref.obstacle_char {\n            println!(\"🚨You pushed me against the wall.🚨\");\n            return;\n        }\n\n        data_ref.position_mouse = (y, x);\n        println!(\"✅Correct move.✅\");\n        data_ref.maze[old_y][old_x] = data_ref.empty_char.clone();\n        data_ref.maze[y][x] = data_ref.mouse_char.clone();\n    }\n\n    fn up(&self) {\n        let (y, x) = self.data.borrow().position_mouse;\n        self.can_move(y as isize - 1, x as isize, y, x);\n    }\n\n    fn down(&self) {\n        let (y, x) = self.data.borrow().position_mouse;\n        self.can_move(y as isize + 1, x as isize, y, x);\n    }\n\n    fn right(&self) {\n        let (y, x) = self.data.borrow().position_mouse;\n        self.can_move(y as isize, x as isize + 1, y, x);\n    }\n\n    fn left(&self) {\n        let (y, x) = self.data.borrow().position_mouse;\n        self.can_move(y as isize, x as isize - 1, y, x);\n    }\n}\n\n//____________________________________________________________\nstruct Maze {\n    data: Rc<RefCell<Data>>,\n    moves: Moves,\n}\n\nimpl Maze {\n    fn new(data: Rc<RefCell<Data>>, moves: Moves) -> Self {\n        Maze { data, moves }\n    }\n\n    fn create_paths(&self, x: usize, y: usize) {\n        let mut data_ref = self.data.borrow_mut();\n        data_ref.maze[y][x] = data_ref.empty_char.clone();\n\n        let directions = [(0, 1), (1, 0), (0, -1), (-1, 0)];\n        let mut rng = rand::thread_rng();\n        let mut directions: Vec<_> = directions.iter().copied().collect();\n        directions.shuffle(&mut rng);\n\n        let width = data_ref.width;\n        let height = data_ref.height;\n\n        for (dx, dy) in directions {\n            let nx = x as isize + dx * 2;\n            let ny = y as isize + dy * 2;\n            if 0 < nx && nx < width as isize - 1 && 0 < ny && ny < height as isize - 1 {\n                let nx = nx as usize;\n                let ny = ny as usize;\n\n                if data_ref.maze[ny][nx] == data_ref.obstacle_char.clone() {\n                    let mid_x = (x as isize + dx) as usize;\n                    let mid_y = (y as isize + dy) as usize;\n\n                    if mid_x < width && mid_y < height {\n                        data_ref.maze[mid_y][mid_x] = data_ref.empty_char.clone();\n                        drop(data_ref);\n                        self.create_paths(nx, ny);\n                        data_ref = self.data.borrow_mut();\n                    }\n                }\n            }\n        }\n    }\n\n    fn create(&self) {\n        let mut data_ref = self.data.borrow_mut();\n\n        if data_ref.width % 2 == 0 {\n            data_ref.width += 1;\n        }\n        if data_ref.height % 2 == 0 {\n            data_ref.height += 1;\n        }\n\n        data_ref.maze = vec![vec![data_ref.obstacle_char.clone(); data_ref.width]; data_ref.height];\n\n        let height = data_ref.height;\n        let width = data_ref.width;\n        data_ref.maze[0][1] = data_ref.mouse_char.clone();\n        data_ref.maze[height - 1][width - 2] = data_ref.exit_char.clone();\n        data_ref.position_mouse = (0, 1);\n        data_ref.exit_location = (height - 1, width - 2);\n\n        let mut rng = rand::thread_rng();\n        let initial_x = rng.gen_range(1..width - 1) | 1;\n        let initial_y = rng.gen_range(1..height - 1) | 1;\n\n        drop(data_ref);\n        self.create_paths(initial_x, initial_y);\n    }\n\n    fn verify_win(&self) -> bool {\n        let data = self.data.borrow();\n        let (y, x) = data.exit_location;\n        return data.maze[y][x] == data.mouse_char;\n    }\n}\n\n//____________________________________________________________\nstruct Game {\n    input: Input,\n    maze: Maze,\n}\n\nimpl Game {\n    fn new(input: Input, maze: Maze) -> Self {\n        Game { input, maze }\n    }\n\n    fn restart_or_exit(&self) -> bool {\n        loop {\n            match self.input.get(\"Y/N: \").as_str() {\n                \"y\" => return true,\n                \"n\" => return false,\n                _ => println!(\"❌Invalid key.❌\"),\n            }\n        }\n    }\n\n    fn play(&self) {\n        self.maze.data.borrow().print_config();\n\n        self.maze.create();\n        loop {\n            self.maze.data.borrow().print_maze();\n            println!(\"Use the keys: (W, S, A, D).\\nTo restart: R. To exit: 9.\");\n\n            match self.input.get(\"Key: \").as_str() {\n                \"w\" => self.maze.moves.up(),\n                \"s\" => self.maze.moves.down(),\n                \"d\" => self.maze.moves.right(),\n                \"a\" => self.maze.moves.left(),\n                \"r\" => {\n                    println!(\"😮Do you want to restart?😮\");\n                    if self.restart_or_exit() {\n                        self.maze.create();\n                    }\n                }\n                \"9\" => {\n                    println!(\"😮Do you want to exit?😮\");\n                    if self.restart_or_exit() {\n                        return;\n                    }\n                }\n                \n                _ => println!(\"❌Invalid key.❌\"),\n            }\n\n            if self.maze.verify_win() {\n                println!(\"🏆Congratulations, you managed to get me out.🏆\");\n                println!(\"🤔Do you want to play again?🤔\");\n                if self.restart_or_exit() {\n                    self.maze.create();\n                } else {\n                    println!(\"Bye\");\n                    return;\n                }\n            }\n        }\n    }\n}\n\n//____________________________________________________________\nfn main() {\n    // These are the default values. You can change them here.\n    let config: HashMap<&str, &str> = [\n        (\"title\", \"RESCUING MICKEY\"),\n        (\"size\", \"7, 7\"),\n        (\"empty\", \"⬜️\"),\n        (\"obstacle\", \"⬛️\"),\n        (\"mouse\", \"🐭\"),\n        (\"exit\", \"🚪\"),\n    ]\n    .iter()\n    .cloned()\n    .collect();\n\n    let input = Input;\n    let data = Data::new(config);\n    let moves = Moves::new(data.clone());\n    let maze = Maze::new(data.clone(), moves);\n    let game = Game::new(input, maze);\n    game.play();\n}\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/sql/Nicojsuarez2.sql",
    "content": "# #33 RESCATANDO A MICKEY\n> #### Dificultad: Fácil | Publicación: 12/08/24 | Corrección: 19/08/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * ¡Disney ha presentado un montón de novedades en su D23! \n * Pero... ¿Dónde está Mickey?\n * Mickey Mouse ha quedado atrapado en un laberinto mágico \n * creado por Maléfica.\n * Desarrolla un programa para ayudarlo a escapar.\n * Requisitos:\n * 1. El laberinto está formado por un cuadrado de 6x6 celdas.\n * 2. Los valores de las celdas serán:\n *    - ⬜️ Vacío\n *    - ⬛️ Obstáculo\n *    - 🐭 Mickey\n *    - 🚪 Salida\n * Acciones:\n * 1. Crea una matriz que represente el laberinto (no hace falta\n * que se genere de manera automática).\n * 2. Interactúa con el usuario por consola para preguntarle hacia\n * donde se tiene que desplazar (arriba, abajo, izquierda o derecha).\n * 3. Muestra la actualización del laberinto tras cada desplazamiento.\n * 4. Valida todos los movimientos, teniendo en cuenta los límites\n * del laberinto y los obstáculos. Notifica al usuario.\n * 5. Finaliza el programa cuando Mickey llegue a la salida.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/typescript/hozlucas28.ts",
    "content": "import readline from 'node:readline/promises'\n\n/* -------------------------------------------------------------------------- */\n/*                                UTILITY TYPES                               */\n/* -------------------------------------------------------------------------- */\n\ntype ArrayOfN<\n    T extends any,\n    N extends number,\n    Acc extends T[] = []\n> = Acc['length'] extends N ? Acc : ArrayOfN<T, N, [T, ...Acc]>\n\ntype NumberBetween<\n    Min extends number,\n    Max extends number,\n    Counter extends 0[] = ArrayOfN<0, Min>,\n    Acc extends number[] = []\n> = Counter['length'] extends Max\n    ? Acc[number]\n    : NumberBetween<Min, Max, [0, ...Counter], [Counter['length'], ...Acc]>\n\n/* -------------------------------------------------------------------------- */\n/*                                    TYPES                                   */\n/* -------------------------------------------------------------------------- */\n\ntype Cell = '⬜️' | '⬛️' | '🐭' | '🚪'\n\ntype Dashboard = ArrayOfN<ArrayOfN<Cell, 6>, 6>\n\ninterface Position {\n    x: NumberBetween<0, 6> | (number & {})\n    y: NumberBetween<0, 6> | (number & {})\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                   ERRORS                                   */\n/* -------------------------------------------------------------------------- */\n\nclass ExitNotFoundError extends Error {\n    public constructor() {\n        super('Exit not found')\n        this.name = 'ExitNotFoundError'\n    }\n}\n\nclass GameOverError extends Error {\n    public constructor() {\n        super('Game over')\n        this.name = 'GameOverError'\n    }\n}\n\nclass InvalidPlayerPositionError extends Error {\n    public constructor(invalidPos: Position) {\n        super(\n            `Position (${invalidPos.x}, ${invalidPos.y}) is invalid for a player`\n        )\n        this.name = 'InvalidPlayerPositionError'\n    }\n}\n\nclass PlayerNotFoundError extends Error {\n    public constructor() {\n        super('Player not found')\n        this.name = 'PlayerNotFoundError'\n    }\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                   CLASSES                                  */\n/* -------------------------------------------------------------------------- */\n\n/* ---------------------------------- Maze ---------------------------------- */\n\ninterface InitialPositions {\n    exitPos: Position\n    playerPos: Position\n}\n\ninterface IMaze {\n    getDashboard: () => Dashboard\n    getExitPos: () => Position\n    getPlayerPos: () => Position\n    setPlayerPos: (newPos: Position) => this | never\n}\n\ninterface MazeConstructor {\n    dashboard: Dashboard\n}\n\nclass Maze implements IMaze {\n    private dashboard: Dashboard\n    private exitPos: Position\n    private playerPos: Position\n    private originalCellAtPlayerPos: Cell\n\n    public constructor({dashboard}: MazeConstructor) {\n        const {exitPos, playerPos} = this.getInitialPositions(dashboard)\n        this.dashboard = dashboard\n        this.exitPos = exitPos\n        this.playerPos = playerPos\n        this.originalCellAtPlayerPos = '⬜️'\n    }\n\n    private getInitialPositions(\n        dashboard: Dashboard\n    ): InitialPositions | never {\n        let exitPos: Position = {x: -1, y: -1}\n        let playerPos: Position = {x: -1, y: -1}\n\n        for (let y = 0; y < dashboard.length; y++) {\n            const row = dashboard[y]\n            for (let x = 0; x < row.length; x++) {\n                const col = row[x]\n                if (col === '🚪') exitPos = {x, y}\n                else if (col === '🐭') playerPos = {x, y}\n            }\n        }\n\n        if (exitPos.x < 0) throw new ExitNotFoundError()\n        if (playerPos.x < 0) throw new PlayerNotFoundError()\n\n        return {exitPos, playerPos}\n    }\n\n    public getDashboard(): Dashboard {\n        return this.dashboard\n    }\n\n    public getExitPos(): Position {\n        return this.exitPos\n    }\n\n    public getPlayerPos(): Position {\n        return this.playerPos\n    }\n\n    public setPlayerPos(pos: Position): this | never {\n        if (!this.isValidPosForPlayer(pos))\n            throw new InvalidPlayerPositionError(pos)\n\n        const prevPlayerPos = this.playerPos\n        const prevOriginalCellAtPlayerPos = this.originalCellAtPlayerPos\n\n        this.originalCellAtPlayerPos = this.dashboard[pos.y][pos.x]\n        this.dashboard[pos.y][pos.x] = '🐭'\n        this.dashboard[prevPlayerPos.y][prevPlayerPos.x] =\n            prevOriginalCellAtPlayerPos\n        this.playerPos = pos\n        return this\n    }\n\n    private isValidPos(pos: Position): boolean {\n        const {x, y}: Position = pos\n        const dashboard: Dashboard = this.dashboard\n\n        const dashboardMaxY: number = dashboard.length - 1\n        const outOfYRange: boolean = y < 0 || y > dashboardMaxY\n        if (outOfYRange) return false\n\n        const dashboardMaxX: number = dashboard[0].length - 1\n        const outOfXRange: boolean = x < 0 || x > dashboardMaxX\n        if (outOfXRange) return false\n\n        return true\n    }\n\n    private isValidPosForPlayer(pos: Position): boolean {\n        if (!this.isValidPos(pos)) return false\n\n        const {x, y}: Position = pos\n        const posAtDashboard: Cell = this.dashboard[y][x]\n\n        const obstacleAtPos: boolean = posAtDashboard === '⬛️'\n        if (obstacleAtPos) return false\n\n        return true\n    }\n}\n\n/* ---------------------------------- Game ---------------------------------- */\n\ntype Move = 'down' | 'left' | 'right' | 'up'\n\ninterface IGame {\n    getMaze: () => IMaze\n    movePlayer: (move: Move) => this | never\n    isGameOver: () => boolean\n}\n\ninterface GameConstructor {\n    maze: IMaze\n}\n\nclass Game implements IGame {\n    private maze: IMaze\n\n    public constructor({maze}: GameConstructor) {\n        this.maze = maze\n    }\n\n    public getMaze(): IMaze {\n        return this.maze\n    }\n\n    public movePlayer(move: Move): this | never {\n        if (this.isGameOver()) throw new GameOverError()\n\n        const maze: IMaze = this.getMaze()\n        const {x, y}: Position = maze.getPlayerPos()\n\n        const moveActions: Record<Move, () => void> = {\n            down: () => maze.setPlayerPos({x, y: y + 1}),\n            left: () => maze.setPlayerPos({x: x - 1, y}),\n            right: () => maze.setPlayerPos({x: x + 1, y}),\n            up: () => maze.setPlayerPos({x, y: y - 1}),\n        }\n\n        moveActions[move]()\n\n        return this\n    }\n\n    public isGameOver(): boolean {\n        const maze: IMaze = this.getMaze()\n        const exitPos = maze.getExitPos()\n        const playerPos = maze.getPlayerPos()\n\n        const playerAtExitPos: boolean =\n            playerPos.x === exitPos.x && playerPos.y === exitPos.y\n\n        return playerAtExitPos\n    }\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\n;(async () => {\n    const maze: Maze = new Maze({\n        dashboard: [\n            ['🚪', '⬛️', '⬛️', '⬛️', '⬛️', '⬛️'],\n            ['⬜️', '⬛️', '⬜️', '⬜️', '⬜️', '⬛️'],\n            ['⬜️', '⬛️', '⬜️', '⬛️', '⬜️', '⬜️'],\n            ['⬜️', '⬜️', '⬜️', '⬛️', '⬜️', '🐭'],\n            ['⬛️', '⬛️', '⬜️', '⬛️', '⬜️', '⬛️'],\n            ['⬛️', '⬛️', '⬜️', '⬜️', '⬜️', '⬛️'],\n        ],\n    })\n\n    const game: Game = new Game({maze})\n    console.dir(game.getMaze().getDashboard())\n\n    const rl = readline.createInterface({\n        input: process.stdin,\n        output: process.stdout,\n    })\n\n    while (!game.isGameOver()) {\n        const move = await rl.question(\n            \"\\n> Enter a move ('up', 'right', 'left', or 'down'): \"\n        )\n\n        try {\n            console.log()\n\n            switch (move.trim().toUpperCase() as Uppercase<Move>) {\n                case 'DOWN':\n                    game.movePlayer('down')\n                    console.dir(game.getMaze().getDashboard())\n                    break\n\n                case 'LEFT':\n                    game.movePlayer('left')\n                    console.dir(game.getMaze().getDashboard())\n                    break\n\n                case 'RIGHT':\n                    game.movePlayer('right')\n                    console.dir(game.getMaze().getDashboard())\n                    break\n\n                case 'UP':\n                    game.movePlayer('up')\n                    console.dir(game.getMaze().getDashboard())\n                    break\n\n                default:\n                    console.log('> Invalid move! Try again...')\n            }\n        } catch (error) {\n            if (error instanceof InvalidPlayerPositionError)\n                console.log('> Player can not move down!')\n        }\n    }\n    rl.close()\n\n    console.log('\\n> Game over!')\n})()\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/typescript/redom69.ts",
    "content": "import * as readline from 'readline';\n\n// Constantes\nconst VACIO = \"⬜️\";\nconst OBSTACULO = \"⬛️\";\nconst MICKEY = \"🐭\";\nconst SALIDA = \"🚪\";\n\ntype Position = [number, number];\n\ninterface Maze {\n    maze: string[][];\n    mickeyPos: Position;\n    end: Position;\n}\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nfunction generateMaze(width: number, height: number, total: number = 10): Maze {\n    let maze: string[][] = Array.from({ length: height }, () =>\n        Array.from({ length: width }, () => VACIO)\n    );\n\n    let mickeyPos: Position = [\n        Math.floor(Math.random() * height),\n        Math.floor(Math.random() * width)\n    ];\n    maze[mickeyPos[0]][mickeyPos[1]] = MICKEY;\n\n    let end: Position;\n    while (true) {\n        end = [\n            Math.floor(Math.random() * height),\n            Math.floor(Math.random() * width)\n        ];\n        if (end[0] !== mickeyPos[0] || end[1] !== mickeyPos[1]) {\n            maze[end[0]][end[1]] = SALIDA;\n            break;\n        }\n    }\n\n    let obstacles = 0;\n    while (obstacles < total) {\n        let obstaclesPos: Position = [\n            Math.floor(Math.random() * height),\n            Math.floor(Math.random() * width)\n        ];\n        if (maze[obstaclesPos[0]][obstaclesPos[1]] === VACIO) {\n            maze[obstaclesPos[0]][obstaclesPos[1]] = OBSTACULO;\n            obstacles++;\n        }\n    }\n\n    return { maze, mickeyPos, end };\n}\n\nfunction showMaze(maze: string[][]): string {\n    return maze.map(row => row.join(' ')).join('\\n');\n}\n\nfunction isValid(newMove: Position, maze: string[][]): boolean {\n    const [x, y] = newMove;\n    const withinBounds = x >= 0 && x < maze.length && y >= 0 && y < maze[0].length;\n    const notAnObstacle = withinBounds && maze[x][y] !== OBSTACULO;\n    return withinBounds && notAnObstacle;\n}\n\nfunction moveMickey(maze: string[][], mickeyPos: Position, move: string): Position {\n    const [x, y] = mickeyPos;\n    let newMove: Position = [x, y];\n\n    switch (move) {\n        case 'w':\n            newMove = [x - 1, y];\n            break;\n        case 's':\n            newMove = [x + 1, y];\n            break;\n        case 'a':\n            newMove = [x, y - 1];\n            break;\n        case 'd':\n            newMove = [x, y + 1];\n            break;\n        default:\n            return mickeyPos;\n    }\n\n    if (isValid(newMove, maze)) {\n        maze[x][y] = VACIO;\n        mickeyPos = newMove;\n        maze[newMove[0]][newMove[1]] = MICKEY;\n    }\n\n    return mickeyPos;\n}\n\nlet { maze, mickeyPos, end } = generateMaze(6, 6, 10);\n\nfunction gameLoop() {\n    console.log(showMaze(maze));\n\n    rl.question(\"Mueve a Mickey (w/a/s/d): \", (move) => {\n        mickeyPos = moveMickey(maze, mickeyPos, move.toLowerCase());\n\n        if (mickeyPos[0] === end[0] && mickeyPos[1] === end[1]) {\n            console.log(showMaze(maze));\n            console.log(\"¡Mickey ha llegado a la salida!\", MICKEY);\n            rl.close();\n        } else {\n            gameLoop();\n        }\n    });\n}\n\ngameLoop();\n"
  },
  {
    "path": "Roadmap/33 - RESCATANDO A MICKEY/vb.net/kenysdev.vb",
    "content": "' ╔══════════════════════════════════════╗\n' ║ Autor:  Kenys Alvarado               ║\n' ║ GitHub: https://github.com/Kenysdev  ║\n' ║ 2024 -  VB.NET                       ║\n' ╚══════════════════════════════════════╝\n'-----------------------------------------------------\n'* RESCATANDO A MICKEY\n'-----------------------------------------------------\n' * ¡Disney ha presentado un montón de novedades en su D23! \n' * Pero... ¿Dónde está Mickey?\n' * Mickey Mouse ha quedado atrapado en un laberinto mágico \n' * creado por Maléfica.\n' * Desarrolla un programa para ayudarlo a escapar.\n' * Requisitos:\n' * 1. El laberinto está formado por un cuadrado de 6x6 celdas.\n' * 2. Los valores de las celdas serán:\n' *    - ⬜️ Vacío\n' *    - ⬛️ Obstáculo\n' *    - 🐭 Mickey\n' *    - 🚪 Salida\n' * Acciones:\n' * 1. Crea una matriz que represente el laberinto (no hace falta\n' * que se genere de manera automática).\n' * 2. Interactúa con el usuario por consola para preguntarle hacia\n' * donde se tiene que desplazar (arriba, abajo, izquierda o derecha).\n' * 3. Muestra la actualización del laberinto tras cada desplazamiento.\n' * 4. Valida todos los movimientos, teniendo en cuenta los límites\n' * del laberinto y los obtáculos. Notifica al usuario.\n' * 5. Finaliza el programa cuando Mickey llegue a la salida.\n\nImports System.Text\n\nModule Program\n    Sub Main()\n        Console.OutputEncoding = Encoding.UTF8\n        ' These are the default values. You can change them here.\n        Dim config As New Dictionary(Of String, String) From {\n            {\"title\", \"RESCUING MICKEY\"},\n            {\"size\", \"7, 7\"},\n            {\"empty\", \"⬜️\"},\n            {\"obstacle\", \"⬛️\"},\n            {\"mouse\", \"🐭\"},\n            {\"exit\", \"🚪\"}\n        }\n\n        Dim maze As New Maze(config)\n        Dim game As New Game(config, maze)\n        game.Play()\n    End Sub\nEnd Module\n\nClass Game\n    Private ReadOnly _config As Dictionary(Of String, String)\n    Private ReadOnly _maze As Maze\n\n    Public Sub New(config As Dictionary(Of String, String), maze As Maze)\n        _config = config\n        _maze = maze\n    End Sub\n\n    Private Shared Function RestartOrExit(msg As String) As Boolean\n        While True\n            Console.WriteLine(msg)\n            Console.Write(\"Y/N: \")\n            Dim option_ = Console.ReadLine().ToLower()\n            Select Case option_\n                Case \"y\"\n                    Return True\n                Case \"n\"\n                    Return False\n                Case Else\n                    Console.WriteLine(\"❌Invalid key.❌\")\n            End Select\n        End While\n        Return False\n    End Function\n\n    Public Sub Play()\n        For Each kvp In _config\n            Console.WriteLine($\"{kvp.Key}: {kvp.Value}\")\n        Next\n\n        _maze.Create()\n        While True\n            _maze.PrintMaze()\n            Console.WriteLine(\"Use the keys: (W, S, A, D).\" & vbCrLf & \"To restart: R. To exit: 9.\")\n            Console.Write(\"Key: \")\n            Dim option_ = Console.ReadLine().ToLower()\n            Select Case option_\n                Case \"w\"\n                    _maze.Up()\n                Case \"s\"\n                    _maze.Down()\n                Case \"d\"\n                    _maze.Right()\n                Case \"a\"\n                    _maze.Left()\n                Case \"r\"\n                    If RestartOrExit(\"😮Do you want to restart?😮\") Then\n                        _maze.Create()\n                    End If\n                Case \"9\"\n                    If RestartOrExit(\"😮Do you want to exit?😮\") Then\n                        Return\n                    End If\n                Case Else\n                    Console.WriteLine(\"❌Invalid key.❌\")\n            End Select\n\n            If _maze.VerifyWin() Then\n                Console.WriteLine(\"🏆Congratulations, you managed to get me out.🏆\")\n                If RestartOrExit(\"🤔Do you want to play again?🤔\") Then\n                    _maze.Create()\n                Else\n                    Console.WriteLine(\"Bye\")\n                    Return\n                End If\n            End If\n        End While\n    End Sub\nEnd Class\n\nClass Data\n    Protected _config As Dictionary(Of String, String)\n    Protected _maze As List(Of List(Of String))\n    Protected _positionMouse As Tuple(Of Integer, Integer)\n    Protected _exitLocation As Tuple(Of Integer, Integer)\n    Protected _width As Integer\n    Protected _height As Integer\n    Protected _obstacleChar As String\n    Protected _emptyChar As String\n    Protected _mouseChar As String\n    Protected _exitChar As String\n\n    Public Sub New(config As Dictionary(Of String, String))\n        _config = config\n        _maze = New List(Of List(Of String))\n        _positionMouse = New Tuple(Of Integer, Integer)(0, 0)\n        _exitLocation = New Tuple(Of Integer, Integer)(0, 0)\n\n        Dim size = config(\"size\").Split(\",\"c)\n        _width = Integer.Parse(size(0))\n        _height = Integer.Parse(size(1))\n        _obstacleChar = _config(\"obstacle\")\n        _emptyChar = _config(\"empty\")\n        _mouseChar = _config(\"mouse\")\n        _exitChar = _config(\"exit\")\n    End Sub\n\n    Public Sub PrintMaze()\n        Console.WriteLine(\"--------------------------------------\")\n        For Each row In _maze\n            Console.WriteLine(String.Join(\"\", row))\n        Next\n        Console.WriteLine(\"--------------------------------------\")\n    End Sub\nEnd Class\n\nClass Moves\n    Inherits Data\n\n    Public Sub New(config As Dictionary(Of String, String))\n        MyBase.New(config)\n    End Sub\n\n    Private Sub CanMove(y As Integer, x As Integer, oldY As Integer, oldX As Integer)\n        Dim rows = _maze.Count\n        Dim cols = _maze(0).Count\n        If y < 0 OrElse x < 0 OrElse y >= rows OrElse x >= cols Then\n            Console.WriteLine(\"🚨I can't jump over the edges.🚨\")\n            Return\n        End If\n\n        If _maze(y)(x) = _obstacleChar Then\n            Console.WriteLine(\"🚨You pushed me against the wall.🚨\")\n            Return\n        End If\n\n        _positionMouse = New Tuple(Of Integer, Integer)(y, x)\n        Console.WriteLine(\"✅Correct move.✅\")\n        _maze(oldY)(oldX) = _emptyChar\n        _maze(y)(x) = _mouseChar\n    End Sub\n\n    Public Sub Up()\n        Dim y = _positionMouse.Item1\n        Dim x = _positionMouse.Item2\n        CanMove(y - 1, x, oldY:=y, oldX:=x)\n    End Sub\n\n    Public Sub Down()\n        Dim y = _positionMouse.Item1\n        Dim x = _positionMouse.Item2\n        CanMove(y + 1, x, oldY:=y, oldX:=x)\n    End Sub\n\n    Public Sub Right()\n        Dim y = _positionMouse.Item1\n        Dim x = _positionMouse.Item2\n        CanMove(y, x + 1, oldY:=y, oldX:=x)\n    End Sub\n\n    Public Sub Left()\n        Dim y = _positionMouse.Item1\n        Dim x = _positionMouse.Item2\n        CanMove(y, x - 1, oldY:=y, oldX:=x)\n    End Sub\nEnd Class\n\nClass Maze\n    Inherits Moves\n\n    Public Sub New(config As Dictionary(Of String, String))\n        MyBase.New(config)\n    End Sub\n\n    Private Sub CreatePaths(x As Integer, y As Integer)\n        _maze(y)(x) = _emptyChar\n        Dim directions = New List(Of (Integer, Integer)) From {(0, 1), (1, 0), (0, -1), (-1, 0)}\n        For Each direction In directions.OrderBy(Function(unused) Guid.NewGuid())\n            Dim dx = direction.Item1\n            Dim dy = direction.Item2\n            Dim nx = x + dx * 2\n            Dim ny = y + dy * 2\n            If 0 < nx AndAlso nx < _width - 1 AndAlso 0 < ny AndAlso ny < _height - 1 AndAlso _maze(ny)(nx) = _obstacleChar Then\n                _maze(y + dy)(x + dx) = _emptyChar\n                CreatePaths(nx, ny)\n            End If\n        Next\n    End Sub\n\n    Public Sub Create()\n        If _width Mod 2 = 0 Then _width += 1\n        If _height Mod 2 = 0 Then _height += 1\n\n        _maze.Clear()\n        For i = 0 To _height - 1\n            _maze.Add(Enumerable.Repeat(_obstacleChar, _width).ToList())\n        Next\n\n        Dim rnd As New Random()\n        Dim initialX = rnd.Next(1, _width - 1) Or 1\n        Dim initialY = rnd.Next(1, _height - 1) Or 1\n        CreatePaths(initialX, initialY)\n\n        _maze(0)(1) = _mouseChar\n        _maze(_height - 1)(_width - 2) = _exitChar\n        _positionMouse = New Tuple(Of Integer, Integer)(0, 1)\n        _exitLocation = New Tuple(Of Integer, Integer)(_height - 1, _width - 2)\n    End Sub\n\n    Public Function VerifyWin() As Boolean\n        Dim y = _exitLocation.Item1\n        Dim x = _exitLocation.Item2\n        Return _maze(y)(x) = _mouseChar\n    End Function\nEnd Class\n"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/c#/deathwing696.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace reto_34\n{\n    public class Deathwing696\n    {\n        public class Arbol\n        {\n            private List<Personaje> personajes;\n\n            public List<Personaje> Personajes { get { return personajes; } }\n\n            public Arbol()\n            {\n                personajes = new List<Personaje>();\n            }\n\n            public bool AddPersonaje(Personaje personaje)\n            {\n                if (!personajes.Contains(personaje))\n                {\n                    personajes.Add(personaje);\n                    Console.WriteLine(\"Personaje introducido correctamente\\n\");\n                    return true;\n                }\n\n                Console.WriteLine(\"El personaje introducido ya existe\");\n                return false;\n            }\n\n            public bool DeletePersonaje(int pos)\n            {\n                if (personajes.Count > 0 && pos >= 0 && pos < personajes.Count)\n                {\n                    personajes.RemoveAt(pos);\n                    Console.WriteLine(\"Personaje borrado correctamente\\n\");\n                    return true;\n                }\n\n                Console.WriteLine(\"No se ha encontrado al personaje\");\n                return false;\n            }\n\n            internal void ShowSelect()\n            {\n                Console.WriteLine(\"Selecciones un personaje:\");\n                var i = 1;\n\n                foreach (var personaje in personajes)\n                    Console.WriteLine($\"{i++}. {personaje.Name}\"); \n            }\n\n            internal bool ModificaPareja(int index, int id, string name)\n            {\n                if (personajes.Count == 0 || index < 0 || index >= personajes.Count)\n                {\n                    Console.WriteLine(\"Selección de personaje inválida\\n\");\n                    return false;\n                }\n\n                Personaje parejaExistente = personajes.Where(p => p.ID == id).FirstOrDefault();\n\n                if (parejaExistente != null)\n                {\n                    Console.WriteLine(\"El personaje pareja ya existe y no se podrá crear para crear la relación\\n\");\n                    return false;\n                }\n\n                Personaje personajeSelected = personajes[index];\n                Personaje pareja = new Personaje(id, name);\n\n                if (!personajeSelected.AddPareja(pareja))\n                    return false;                    \n\n                Console.WriteLine(\"Pareja asignada correctamente\");\n                return true;\n            }\n\n            internal bool ModificarHijo(int index, int id, string name)\n            {\n                if (personajes.Count == 0 || index < 0 || index >= personajes.Count)\n                {\n                    Console.WriteLine(\"Selección de personaje inválida\\n\");\n                    return false;\n                }\n\n                Personaje hijoExistente = personajes.Where(p => p.ID == id).FirstOrDefault();\n\n                if (hijoExistente != null)\n                {\n                    Console.WriteLine(\"El personaje pareja ya existe y no se podrá crear para crear la relación\\n\");\n                    return false;\n                }\n\n                Personaje personajeSelected = personajes[index];\n                Personaje hijo = new Personaje(id, name);\n\n                if (!personajeSelected.AddHijo(hijo))\n                    return false;\n\n                Console.WriteLine(\"Hijo asignado correctamente\");\n                return true;\n            }\n\n            internal void Show()\n            {\n                foreach (Personaje personaje in personajes)\n                {\n                    var pareja = personaje.Pareja?.Name;\n                    Console.WriteLine($\"- {personaje.Name}\\t - \\t {pareja}\");\n                    ShowSons(personaje.Hijos);\n                }\n            }\n\n            private void ShowSons(List<Personaje> hijos)\n            {\n                foreach (Personaje hijo in hijos)\n                {\n                    Console.WriteLine($\"\\t\\t - {hijo.Name}\");\n                }\n            }\n        }\n        public class Personaje\n        {\n            private int id;\n            private string name;\n            private Personaje pareja = null;\n            private List<Personaje> hijos;\n            private int? parentId = null;\n\n            public int ID { get { return id; } }\n            public string Name { get { return name; } }\n\n            public Personaje Pareja { get { return pareja; } }\n\n            public List<Personaje> Hijos { get { return hijos; } }\n\n            public int? ParentId { get { return parentId; } }\n\n            public override bool Equals(object obj)\n            {\n                Personaje personaje2 = obj as Personaje;\n\n                return this.id == personaje2.id;\n            }\n\n            public override int GetHashCode()\n            {\n                int hashCode = -48284730;\n                hashCode = hashCode * -1521134295 + id.GetHashCode();\n                hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(name);\n                return hashCode;\n            }\n\n            public Personaje(int id, string name)\n            {\n                this.id = id;\n                this.name = name;\n                hijos = new List<Personaje>();\n            }\n\n            public bool AddPareja(Personaje pareja)\n            {\n                if (this.pareja != null)\n                {\n                    Console.WriteLine(\"El personaje ya tiene una pareja\\n\");\n                    return false;\n                }\n\n                if (pareja.pareja != null)\n                {\n                    Console.WriteLine(\"Esta pareja ya está casada con otro personaje\\n\");\n                    return false;\n                }\n\n                this.pareja = pareja;\n                pareja.pareja = this;\n                return true;\n            }\n\n            public bool AddHijo(Personaje hijo)\n            {\n                if (hijo.parentId != null)\n                {\n                    Console.WriteLine(\"Un hijo no puede tener más de un padre\\n\");\n                    return false;\n                }\n\n                this.Hijos.Add(hijo);\n                hijo.parentId = this.id;\n                return true;\n            }\n        }\n\n        static void Main(string[] args)\n        {\n            Console.WriteLine(\"Bienvenido a la simulación del árbol genealógico de la casa de dragones\");\n\n            Arbol arbol = new Arbol();\n\n            while (true)\n            {\n                Console.WriteLine(\"¿Qué desea hacer?\");\n                Console.WriteLine(\"1. Añadir personaje\");\n                Console.WriteLine(\"2. Eliminar personaje\");\n                Console.WriteLine(\"3. Modificar pareja\");\n                Console.WriteLine(\"4. Modificar hijos\");\n                Console.WriteLine(\"5. Mostrar árbol\");\n                Console.WriteLine(\"0. Salir\");\n                Console.Write(\"Introduce la opción: \");\n                var opcion = Int16.Parse(Console.ReadLine());\n\n                switch (opcion)\n                {\n                    case 1:\n                        Console.Write(\"Introduce el id del personaje:\");\n                        var id = Int16.Parse(Console.ReadLine());\n                        Console.Write(\"Introduce el nombre del personaje:\");\n                        var name = Console.ReadLine();\n                        Personaje personaje = new Personaje(id, name);\n\n                        arbol.AddPersonaje(personaje);\n                        break;\n                    case 2:\n                        arbol.ShowSelect();\n                        Console.Write(\"Seleccione una opción: \");\n                        var sel = Int16.Parse(Console.ReadLine());\n                        arbol.DeletePersonaje(sel - 1);\n                        break;\n                    case 3:\n                        arbol.ShowSelect();\n                        Console.Write(\"Seleccione una opción: \");\n                        sel = Int16.Parse(Console.ReadLine());\n                        Console.Write(\"Introduce el id de la pareja: \");\n                        id = Int16.Parse(Console.ReadLine());\n                        Console.Write(\"Introduce el nombre de la pareja: \");\n                        name = Console.ReadLine();\n                        arbol.ModificaPareja(sel - 1, id, name);\n                        break;\n                    case 4:\n                        arbol.ShowSelect();\n                        Console.Write(\"Seleccione una opción: \");\n                        sel = Int16.Parse(Console.ReadLine());\n                        Console.Write(\"Introduce el id del hijo: \");\n                        id = Int16.Parse(Console.ReadLine());\n                        Console.Write(\"Introduce el nombre del hijo: \");\n                        name = Console.ReadLine();\n                        arbol.ModificarHijo(sel - 1, id, name);\n                        break;\n                    case 5:\n                        arbol.Show();\n                        break;\n                    case 0:\n                        Console.WriteLine(\"Adios!\");\n                        Console.ReadKey();\n                        return;\n                    default:\n                        Console.WriteLine(\"Opción incorrecta\\n\");\n                        break;\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/c#/hequebo.cs",
    "content": "using System;\n\nclass Person\n{\n    private int _id;\n    private string _name;\n    private Person? _partner = null;\n    private List<Person>? _children;\n    private bool _hasParents;\n\n    public int Id { get { return _id; } }\n    public string Name { get { return _name; } }\n    public Person Partner { get { return _partner; } }\n    public List<Person> Children { get { return _children; } }\n    public bool HasParents { get { return _hasParents; } set { _hasParents = value; } }\n\n    public Person(int id, string name)\n    {\n        _id = id;\n        _name = name;\n        _hasParents = false;\n        _children = new List<Person>();\n    }\n\n    public void AddPartner(Person partner) \n    {\n        if (_partner != null)\n        {\n            Console.WriteLine($\"{_name} ya tiene una pareja ({_partner._name})\");\n            return;\n        }\n        if (partner.Partner != null)\n        {\n            Console.WriteLine($\"{partner.Name} ya tiene una pareja ({partner.Partner.Name})\");\n            return;\n        }\n        if (partner == this)\n        {\n            Console.WriteLine($\"{_name} no puede estar emparejado consigo mismo...\");\n            return;\n        }\n        _partner = partner;\n        _partner._partner = this;\n        Console.Clear();\n        Console.WriteLine($\"{_partner._name} ahora es pareja de {_name}\");\n    }\n\n    public void AddChild(Person child)\n    {\n        if (_children.Where(c => c._id == child._id).Count() > 0)\n        {\n            Console.WriteLine($\"{child._name} ya es hijo de {_name}\");\n            return;\n        }\n        if (child == this)\n        {\n            Console.WriteLine($\"{_name} no puede ser su mismo hijo\");\n        }\n        _children.Add(child);\n        Console.Clear();\n    }\n}\n\nclass FamiliyTree\n{\n    private List<Person> _people;\n    public int Id = 1;\n    public FamiliyTree()\n    {\n        _people = new List<Person>();\n    }\n\n    public void AddPerson(Person person)\n    {\n        if (_people.Exists(p => p.Id == person.Id))\n        {\n            Console.WriteLine($\"Una persona con el Id {person.Id} ya ha sido registrada...\");\n            return;\n        }\n        _people.Add(person);\n        Console.WriteLine($\"{person.Name} ha sido agregado a la lista correctamente...\");\n        Id++;\n    }\n    public void RemovePerson(int id)\n    {\n        var person = _people.Where(p => p.Id == id).FirstOrDefault();\n        if (person == null)\n        {\n            Console.WriteLine($\"La persona con el id {id} no existe...\");\n            return;\n        }\n        _people.Remove(person);\n        Console.Clear();\n        Console.WriteLine($\"{person.Name} ha sido eliminado...\");\n    }\n\n    public bool PrintList()\n    {\n        if (_people.Count == 0)\n        {\n            Console.WriteLine(\"No hay personas registradas...\");\n            return false;\n        }\n        foreach (Person person in _people)\n            Console.WriteLine($\"{person.Id}.- {person.Name}\");\n        return true;\n    }\n    public Person? Get(int id)\n    {\n        var person = _people.FirstOrDefault(p => p.Id == id);\n\n        return person;\n    }\n    public void SetPartner(int id, int idPartner)\n    {\n        var person = Get(id);\n        var partner = Get(idPartner);\n\n        if (person == null || partner == null)\n        {\n            Console.WriteLine(\"Un Id o más no pudieron ser encontrados\");\n            return;\n        }\n        person.AddPartner(partner);\n    }\n    public void SetChild(int idParent, int idChild)\n    {\n        var parent = Get(idParent);\n        var child = Get(idChild);\n\n        if (parent == null || child == null)\n        {\n            Console.WriteLine(\"Un Id o más no pudieron ser encontrados\");\n            return;\n        }\n        if (parent.Partner == null)\n        {\n            Console.WriteLine($\"{parent.Name} no tiene una pareja con la que tener hijos...\");\n            return;\n        }\n        if (child.HasParents)\n        {\n            Console.WriteLine($\"{child.Name} ya cuenta con padres...\");\n            var parents = GetParents(idChild);\n            foreach (var person in GetParents(idChild))\n                Console.WriteLine($\"{person.Id}.- {person.Name}\");\n            return;\n        }\n        parent.AddChild(child);\n        parent.Partner.AddChild(child);\n        child.HasParents = true;\n        Console.WriteLine($\"{child.Name} es hijo de {parent.Name} y {parent.Partner.Name}\");\n    }\n    public List<Person> GetParents(int idChild)\n    {\n        var parents = new List<Person>();\n        foreach (Person person in _people)\n        {\n            if (person.Children.Exists(p => p.Id == idChild))\n                parents.Add(person);\n        }\n        return parents;\n    }\n    public void PrintTree()\n    {\n        if (_people.Count == 0)\n        {\n            Console.WriteLine(\"No hay personas registradas...\");\n            return;\n        }\n        List<Person> visited = new List<Person>();\n        void PrintPerson(Person person)\n        {\n            if (visited.Contains(person))\n                return;\n            visited.Add(person);\n\n            Console.Write($\"{person.Id}.- {person.Name}\");\n\n            if (person.Partner != null)\n            {\n                visited.Add(person.Partner);\n                Console.Write($\"\\tPareja: {person.Partner.Id}.- {person.Partner.Name}\");\n            }\n            Console.WriteLine();\n            if (person.Children.Count > 0)\n            {\n                Console.WriteLine(\"Hijos\");\n                foreach (Person child in person.Children)\n                    PrintPerson(child);\n                Console.WriteLine();\n            }\n        }\n        \n        foreach(Person person in _people) \n            PrintPerson(person);\n    }\n    \n}\nclass Program\n{\n    static void Main(string[] args)\n    {\n        var tree = new FamiliyTree();\n        bool exit = false;\n\n        do\n        {\n            Menu();\n            int option = 0;\n            int.TryParse(Console.ReadLine(), out option);\n\n            switch (option)\n            {\n                case 1:\n                    AddPerson(ref tree);\n                    break;\n                case 2:\n                    RemovePerson(ref tree);\n                    break;\n                case 3:\n                    SetPartner(ref tree);\n                    break;\n                case 4:\n                    SetChild(ref tree);\n                    break;\n                case 5:\n                    PrintTree(ref tree);\n                    break;\n                case 6:\n                    exit = true;\n                    Console.Clear();\n                    Console.WriteLine(\"Hasta la próxima...\");\n                    Thread.Sleep(1000);\n                    break;\n                default:\n                    Console.Clear();\n                    Console.WriteLine(\"Opción no válida...\");\n                    break;\n            }\n        } while (!exit);\n\n\n    }\n\n    static void Menu()\n    {\n        Console.WriteLine(\"---ÁRBOL GENEALÓGICO---\");\n        Console.WriteLine(\"1.- Agregar una persona.\");\n        Console.WriteLine(\"2.- Eliminar a una persona.\");\n        Console.WriteLine(\"3.- Agregar una pareja.\");\n        Console.WriteLine(\"4.- Agregar un hijo.\");\n        Console.WriteLine(\"5.- Imprimir árbol.\");\n        Console.WriteLine(\"6.- Salir.\");\n        Console.WriteLine(\"Selecciona una opción...\");\n    }\n    static void AddPerson(ref FamiliyTree tree)\n    {\n        Console.Clear();\n        Console.WriteLine(\"Ingresa el nombre de la persona\");\n        string? name = Console.ReadLine();\n        if (string.IsNullOrEmpty(name))\n        {\n            Console.WriteLine(\"El nombre no es válido...\");\n            return;\n        }\n        var person = new Person(tree.Id, name);\n        tree.AddPerson(person);\n    }\n    static void RemovePerson(ref  FamiliyTree tree)\n    {\n        Console.Clear();\n        if (!tree.PrintList())\n            return;\n        Console.WriteLine(\"Ingresa el Id de la persona a eliminar\");\n        int id = 0;\n        int.TryParse(Console.ReadLine(), out id);\n        tree.RemovePerson(id);\n    }\n    static void SetPartner(ref FamiliyTree tree)\n    {\n        Console.Clear();\n        if (!tree.PrintList())\n            return;\n        Console.WriteLine(\"Ingresa el Id de la primera persona\");\n        int id = 0;\n        int.TryParse(Console.ReadLine(), out id);\n        Console.WriteLine(\"Ingresa el Id de su pareja\");\n        int idPartner = 0;\n        int.TryParse(Console.ReadLine(), out idPartner);\n        tree.SetPartner(id, idPartner);\n    }\n    static void SetChild(ref  FamiliyTree tree)\n    {\n        Console.Clear();\n        if (!tree.PrintList()) \n            return;\n        Console.WriteLine(\"Ingresa el Id del padre\");\n        int idParent = 0;\n        int.TryParse(Console.ReadLine(), out idParent);\n        Console.WriteLine(\"Ingresa el Id del hijo\");\n        int idChild = 0;\n        int.TryParse(Console.ReadLine(), out idChild);\n        tree.SetChild(idParent, idChild);\n    }\n    static void PrintTree(ref FamiliyTree tree)\n    {\n        Console.Clear();\n        tree.PrintTree();\n        Console.ReadLine();\n    }\n}"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/c#/kenysdev.cs",
    "content": "namespace exs34;\n/*\n╔══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado               ║\n║ GitHub: https://github.com/Kenysdev  ║\n║ 2024 -  C#                           ║\n╚══════════════════════════════════════╝\n-----------------------------------------------------\n #34 ÁRBOL GENEALÓGICO DE LA CASA DEL DRAGÓN\n-----------------------------------------------------\n * ¡La Casa del Dragón ha finalizado y no volverá hasta 2026! \n * ¿Alguien se entera de todas las relaciones de parentesco\n * entre personajes que aparecen en la saga?\n * Desarrolla un árbol genealógico para relacionarlos (o invéntalo).\n * Requisitos:\n * 1. Estará formado por personas con las siguientes propiedades:\n *    - Identificador único (obligatorio)\n *    - Nombre (obligatorio)\n *    - Pareja (opcional)\n *    - Hijos (opcional)\n * 2. Una persona sólo puede tener una pareja (para simplificarlo).\n * 3. Las relaciones deben validarse dentro de lo posible.\n *    Ejemplo: Un hijo no puede tener tres padres.\n * Acciones:\n * 1. Crea un programa que permita crear y modificar el árbol.\n *    - Añadir y eliminar personas\n *    - Modificar pareja e hijos\n * 2. Podrás imprimir el árbol (de la manera que consideres).\n * \n * NOTA: Ten en cuenta que la complejidad puede ser alta si\n * se implementan todas las posibles relaciones. Intenta marcar\n * tus propias reglas y límites para que te resulte asumible.\n*/\n\n// NOTE: Here is the 'people.json' file with the data if you want to test it:\n//       https://pastebin.com/29kWWgPU\n//       Just paste it into the base folder.\n\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text.Json;\n\n//______________________________\n\npublic class Person(int id, string name)\n{\n    public int Id { get; set; } = id;\n    public string Name { get; set; } = name;\n    public List<int> Parents { get; set; } = [];\n    public List<int> Partners { get; set; } = [];\n    public Dictionary<int, List<int>> Children { get; set; } = [];\n    public bool Deleted { get; set; }\n\n    public Dictionary<string, object> ToDict()\n    {\n        return new Dictionary<string, object>\n        {\n            [\"id\"] = Id,\n            [\"name\"] = Name,\n            [\"parents\"] = Parents,\n            [\"partners\"] = Partners,\n            [\"children\"] = Children,\n            [\"deleted\"] = Deleted\n        };\n    }\n\n    public static Person FromDict(Dictionary<string, object> data)\n    {\n        var person = new Person((int)data[\"id\"], (string)data[\"name\"]);\n        \n        if (data.TryGetValue(\"parents\", out var parents))\n            person.Parents = (List<int>)parents;\n        \n        if (data.TryGetValue(\"partners\", out var partners))\n            person.Partners = (List<int>)partners;\n        \n        if (data.TryGetValue(\"children\", out var children))\n            person.Children = ((JsonElement)children).Deserialize<Dictionary<int, List<int>>>()!;\n        \n        if (data.TryGetValue(\"deleted\", out var deleted))\n            person.Deleted = (bool)deleted;\n        \n        return person;\n    }\n\n    public override string ToString() => $\"Person(id={Id}, name='{Name}')\";\n}\n\n//______________________________\npublic static class Input\n{\n    public static string GetStr(string msg)\n    {\n        while (true)\n        {\n            Console.Write(msg);\n            string txt = Console.ReadLine()!;\n            if (!string.IsNullOrEmpty(txt))\n            {\n                return txt;\n            }\n\n            Console.WriteLine(\"\\n❌ This field cannot be empty.\");\n        }\n    }\n\n    public static int GetInt(string msg)\n    {\n        while (true)\n        {\n            string txt = GetStr(msg);\n            if (int.TryParse(txt, out int result))\n            {\n                return result;\n            }\n\n            Console.WriteLine(\"\\n❌ Enter an integer.\");\n        }\n    }\n}\n\n//______________________________\npublic class People\n{\n    private List<Person> _people = [];\n    private readonly string _filename;\n    private static readonly JsonSerializerOptions _jsonOptions = new(JsonSerializerDefaults.Web) { WriteIndented = true };\n\n    public People(string filename = \"people.json\")\n    {\n        _filename = filename;\n        LoadFromJson();\n    }\n\n    public IReadOnlyList<Person> GetPeople() => _people.AsReadOnly();\n\n    public void LoadFromJson()\n    {\n        try\n        {\n             string jsonString = File.ReadAllText(_filename);\n            _people = JsonSerializer.Deserialize<List<Person>>(jsonString, _jsonOptions) ?? [];\n            Console.WriteLine($\"✅ The file '{_filename}' has been successfully loaded.\");\n        }\n        catch (Exception)\n        {\n            Console.WriteLine($\"⚠️ The file '{_filename}' not found. Starting with an empty list.\");\n            _people = [new(0, \"unknown\")];\n        }\n    }\n\n    public void SaveToJson()\n    {\n        try\n        {\n            string jsonString = JsonSerializer.Serialize(_people, _jsonOptions);\n            File.WriteAllText(_filename, jsonString);\n            Console.WriteLine($\"✅ Data saved successfully to {_filename}\");\n        }\n        catch (Exception e)\n        {\n            Console.WriteLine($\"❌ An error occurred while saving to '{_filename}': {e.Message}. Data may not have been saved.\");\n        }\n    }\n\n    public void PrintPeople()\n    {\n        Console.WriteLine(new string('_', 32));\n        Console.WriteLine($\"|{\"id\",4}|{\"Name\",-25}|\");\n        Console.WriteLine(new string('_', 32));\n        foreach (var person in _people.Where(p => !p.Deleted))\n        {\n            Console.WriteLine($\"|{person.Id,4}|{person.Name,-25}|\");\n        }\n        Console.WriteLine(new string('_', 32));\n    }\n\n    public Person? GetPersonById(int id)\n    {\n        var person = _people.FirstOrDefault(p => p.Id == id);\n        if (person == null)\n        {\n            Console.WriteLine(\"❌ id not found.\");\n        }\n        return person;\n    }\n\n    public void AddPerson()\n    {\n        Console.WriteLine(\"Add Person or 'x' to Exit\");\n        string name = Input.GetStr(\"Name: \");\n        if (name.Equals(\"x\", StringComparison.CurrentCultureIgnoreCase))\n        {\n            Console.WriteLine(\"Exit\");\n            return;\n        }\n\n        int newId = _people.Count > 0 ? _people.Max(p => p.Id) + 1 : 0;\n        var newPerson = new Person(newId, name);\n        _people.Add(newPerson);\n        Console.WriteLine($\"✅ Added: {newPerson}\");\n        SaveToJson();\n    }\n\n    public void RemovePerson()\n    {\n        PrintPeople();\n        Console.WriteLine(\"\\nPerson ID to mark as deleted or a letter to exit.\");\n        string idStr = Input.GetStr(\"ID: \");\n        if (!int.TryParse(idStr, out int id))\n        {\n            Console.WriteLine(\"Exit\");\n            return;\n        }\n\n        var person = GetPersonById(id);\n        if (person == null) return;\n\n        if (person.Partners.Count != 0 || person.Parents.Count != 0)\n        {\n            Console.WriteLine(\"❌ You cannot delete a person who is linked to parents or partners.\");\n            return;\n        }\n\n        person.Deleted = true;\n        Console.WriteLine($\"✅ '{person.Name}' is marked as deleted.\");\n        SaveToJson();\n    }\n\n    public int Count => _people.Count;\n\n}\n\n//______________________________\npublic class Partners : People\n{\n    private void Add(List<int> partners, int idPerson)\n    {\n        Console.WriteLine(\"Select Partner ID\");\n        int idPartner = Input.GetInt(\"ID: \");\n        var partner = GetPersonById(idPartner);\n        if (partner == null || partner.Deleted)\n        {\n            Console.WriteLine(\"❌ ID not found or the person is deleted.\");\n            return;\n        }\n\n        if (partners.Contains(idPartner))\n        {\n            Console.WriteLine(\"❌ This partner is already added.\");\n            return;\n        }\n\n        partners.Add(idPartner);\n        partner.Partners.Add(idPerson);\n\n        Console.WriteLine(\"✅ Partner successfully added.\");\n        SaveToJson();\n    }\n\n    private void Remove(List<int> partners, int idPerson)\n    {\n        Console.WriteLine(\"Select Partner ID to Delete\");\n        int id = Input.GetInt(\"ID: \");\n        if (!partners.Contains(id))\n        {\n            Console.WriteLine(\"❌ ID not found.\");\n            return;\n        }\n\n        var partner = GetPersonById(id);\n        if (partner == null)\n        {\n            Console.WriteLine(\"❌ Partner not found.\");\n            return;\n        }\n\n        if (partner.Children.Count != 0)\n        {\n            Console.WriteLine(\"❌ Cannot delete a partner who has children.\");\n            return;\n        }\n\n        partners.Remove(id);\n        partner.Partners.Remove(idPerson);\n\n        Console.WriteLine(\"✅ Partner deleted\");\n        SaveToJson();\n    }\n\n    private void Options(List<int> partners, int idPerson)\n    {\n        Console.WriteLine(\"\\n1. Add partner | 2. Remove partner | 3. Exit\");\n        int option = Input.GetInt(\"\\nOption: \");\n\n        switch (option)\n        {\n            case 1:\n                Add(partners, idPerson);\n                break;\n            case 2:\n                Remove(partners, idPerson);\n                break;\n            case 3:\n                return;\n            default:\n                Console.WriteLine(\"❌ Invalid option.\");\n                break;\n        }\n    }\n\n    public void EditPartners()\n    {\n        PrintPeople();\n        Console.WriteLine(\"\\nPerson ID to edit partners or a letter to exit.\");\n        string idStr = Input.GetStr(\"ID: \");\n        if (!int.TryParse(idStr, out int id))\n        {\n            Console.WriteLine(\"Exit\");\n            return;\n        }\n\n        var person = GetPersonById(id);\n        if (person == null || person.Deleted)\n        {\n            Console.WriteLine(\"❌ ID not found or the person is deleted.\");\n            return;\n        }\n\n        Console.WriteLine($\"You selected '{person.Name}'\");\n        var partners = person.Partners;\n\n        if (partners.Count != 0)\n        {\n            Console.WriteLine(\"Partners:\");\n            foreach (var idP in partners)\n            {\n                var partner = GetPersonById(idP);\n                if (partner != null)\n                {\n                    Console.WriteLine($\"ID: {partner.Id} -> {partner.Name}\");\n                }\n            }\n        }\n        else\n        {\n            Console.WriteLine(\"🚫 This person has no partners.\");\n        }\n\n        Options(partners, id);\n    }\n}\n\n//______________________________\npublic class Children : Partners\n{\n    private int _idParent;\n    private Dictionary<int, List<int>>? _children;\n    private int _idChild;\n    private int _idPartner;\n\n    private int? SelectPartner(List<int> partners)\n    {\n        Console.WriteLine(\"Partners:\");\n        foreach (var idP in partners)\n        {\n            var partnerPerson = GetPersonById(idP);\n            if (partnerPerson != null)\n            {\n                Console.WriteLine($\"ID: {partnerPerson.Id} -> {partnerPerson.Name}\");\n            }\n        }\n\n        Console.WriteLine(\"Select the ID of the partner with whom you have the child.\");\n        int idPartner = Input.GetInt(\"ID: \");\n        var partner = GetPersonById(idPartner);\n        if (!partners.Contains(idPartner) || partner == null || partner.Deleted)\n        {\n            Console.WriteLine(\"❌ ID not found or the person is deleted.\");\n            return null;\n        }\n\n        return idPartner;\n    }\n\n    private int? UpdateChildParent()\n    {\n        int idPartner = _idPartner;\n        Console.WriteLine(\"Select Child ID\");\n        int idChild = Input.GetInt(\"ID: \");\n        var child = GetPersonById(idChild);\n        if (child == null)\n        {\n            Console.WriteLine(\"❌ ID not found.\");\n            return null;\n        }\n\n        if (child.Parents.Count != 0)\n        {\n            Console.WriteLine(\"❌ This person already has parents.\");\n            return null;\n        }\n\n        _children ??= [];\n\n        if (_children.TryGetValue(idPartner, out var childrenList))\n        {\n            if (!childrenList.Contains(idChild))\n            {\n                childrenList.Add(idChild);\n            }\n        }\n        else\n        {\n            _children[idPartner] = [idChild];\n        }\n\n        var parent = GetPersonById(_idParent);\n        if (parent != null)\n        {\n            parent.Children = _children;\n        }\n\n        child.Parents = [_idParent, idPartner];\n\n        return idChild;\n    }\n\n    private void UpdateChildPartner(Person partner)\n    {\n        if (partner.Children.TryGetValue(_idParent, out var childrenList))\n        {\n            if (!childrenList.Contains(_idChild))\n            {\n                childrenList.Add(_idChild);\n            }\n        }\n        else\n        {\n            partner.Children[_idParent] = [_idChild];\n        }\n    }\n\n    private void Add()\n    {\n        var parent = GetPersonById(_idParent);\n        if (parent == null)\n        {\n            Console.WriteLine(\"❌ Parent not found.\");\n            return;\n        }\n\n        var partners = parent.Partners;\n        if (partners.Count == 0)\n        {\n            Console.WriteLine(\"❌ This person does not have a partner with whom to have children.\");\n            return;\n        }\n\n        var idPartner = SelectPartner(partners);\n        if (!idPartner.HasValue)\n        {\n            return;\n        }\n\n        var partner = GetPersonById(idPartner.Value);\n        if (partner == null)\n        {\n            Console.WriteLine(\"❌ Partner not found.\");\n            return;\n        }\n\n        _idPartner = idPartner.Value;\n        var idChild = UpdateChildParent();\n        if (!idChild.HasValue)\n        {\n            return;\n        }\n\n        _idChild = idChild.Value;\n        UpdateChildPartner(partner);\n\n        Console.WriteLine(\"✅ Child successfully added.\");\n        SaveToJson();\n    }\n\n    private void RemoveAndUpdate(int idParent, int idPartner)\n    {\n        var parent = GetPersonById(idParent);\n        if (parent == null)\n        {\n            Console.WriteLine(\"❌ Parent not found.\");\n            return;\n        }\n\n        if (parent.Children.TryGetValue(idPartner, out var childrenWithPartner))\n        {\n            childrenWithPartner.Remove(_idChild);\n            if (childrenWithPartner.Count == 0)\n            {\n                parent.Children.Remove(idPartner);\n            }\n            else\n            {\n                parent.Children[idPartner] = childrenWithPartner;\n            }\n        }\n\n        var child = GetPersonById(_idChild);\n        child?.Parents.Remove(idParent);\n\n        Console.WriteLine($\"✅ Child deleted in parent: (ID: {idParent})\");\n        SaveToJson();\n    }\n\n    private void Remove()\n    {\n        Console.WriteLine(\"Select Child ID to Delete\");\n        _idChild = Input.GetInt(\"ID: \");\n        var child = GetPersonById(_idChild);\n        if (child == null)\n        {\n            Console.WriteLine(\"❌ Child not found.\");\n            return;\n        }\n\n        var parents = child.Parents;\n        if (parents.Count != 2)\n        {\n            Console.WriteLine(\"❌ Child does not have two parents.\");\n            return;\n        }\n\n        int idP1 = parents[0], idP2 = parents[1];\n        RemoveAndUpdate(idP1, idP2);\n        RemoveAndUpdate(idP2, idP1);\n    }\n\n    private void Options()\n    {\n        Console.WriteLine(\"\\n1. Add child | 2. Remove child | 3. Exit\");\n        int option = Input.GetInt(\"\\nOption: \");\n\n        switch (option)\n        {\n            case 1:\n                Add();\n                break;\n            case 2:\n                Remove();\n                break;\n            case 3:\n                return;\n            default:\n                Console.WriteLine(\"❌ Invalid option.\");\n                break;\n        }\n    }\n\n    public void EditChildren()\n    {\n        PrintPeople();\n        Console.WriteLine(\"\\nPerson ID to edit Children or a letter to exit.\");\n        string idStr = Input.GetStr(\"ID: \");\n        if (!int.TryParse(idStr, out int id))\n        {\n            Console.WriteLine(\"Exit\");\n            return;\n        }\n\n        var parent = GetPersonById(id);\n        if (parent == null || parent.Deleted)\n        {\n            Console.WriteLine(\"❌ ID not found or the person is deleted.\");\n            return;\n        }\n\n        Console.WriteLine($\"You selected '{parent.Name}'\");\n        var children = parent.Children;\n        if (children.Count != 0)\n        {\n            Console.WriteLine(\"Children:\");\n            foreach (var (partnerId, childIds) in children)\n            {\n                var partner = GetPersonById(partnerId);\n                string partnerName = partner?.Name ?? \"Unknown\";\n                Console.WriteLine($\"With ID: {partnerId} -> '{partnerName}':\");\n                foreach (var childId in childIds)\n                {\n                    var child = GetPersonById(childId);\n                    string childName = child?.Name ?? \"Unknown\";\n                    Console.WriteLine($\"    ID: {childId} -> '{childName}'\");\n                }\n            }\n        }\n        else\n        {\n            Console.WriteLine(\"🚫 This person has no children.\");\n        }\n\n        _idParent = id;\n        _children = children;\n        Options();\n    }\n}\n\n//______________________________\npublic class Tree : Children\n{\n    private (List<Person> Grandparents, List<Person> NoPartner) FilteredGrandparents()\n    {\n        var grandparents = new List<Person>();\n        var noPartner = new List<Person>();\n\n        foreach (var person in GetPeople())\n        {\n            if (person.Parents.Count == 0 && !person.Deleted && person.Name != \"unknown\")\n            {\n                if (person.Partners.Count == 0)\n                {\n                    noPartner.Add(person);\n                    continue;\n                }\n\n                bool hasGrandparentPartner = person.Partners.Any(partnerId =>\n                {\n                    var partner = GetPersonById(partnerId);\n                    return partner != null && grandparents.Contains(partner);\n                });\n\n                if (!hasGrandparentPartner)\n                {\n                    grandparents.Add(person);\n                }\n            }\n        }\n\n        return (grandparents, noPartner);\n    }\n\n    private void PrintChild(List<int> children, string prefix, bool isLast, bool isRoot)\n    {\n        for (int j = 0; j < children.Count; j++)\n        {\n            bool isLastChild = j == children.Count - 1;\n            string newPrefix = prefix;\n            if (!isRoot)\n            {\n                newPrefix = prefix[..^4] + (isLast ? \"    \" : \"│   \");\n            }\n\n            PrintFamily(\n                children[j],\n                newPrefix + (isLastChild ? \"└── \" : \"├── \"),\n                isLastChild,\n                false\n            );\n        }\n    }\n\n    private void PrintParents(int id, List<int> partners, string prefix, bool isLast, bool isRoot)\n    {\n        foreach (var partnerId in partners)\n        {\n            var partner = GetPersonById(partnerId);\n            if (partner != null)\n            {\n                Console.WriteLine($\"{prefix}💑 With: {partner.Name} (ID: {partner.Id})\");\n                if (partner.Children.TryGetValue(id, out var children) && children.Count > 0)\n                {\n                    PrintChild(children, prefix, isLast, isRoot);\n                }\n                else\n                {\n                    Console.WriteLine($\"{prefix}└── 🚫 Without children\");\n                }\n            }\n        }\n    }\n\n    private void PrintFamily(int id, string prefix = \"\", bool isLast = false, bool isRoot = true)\n    {\n        var person = GetPersonById(id);\n        if (person == null) return;\n\n        Console.WriteLine($\"{prefix}🙂 {person.Name} (ID: {person.Id})\");\n\n        if (person.Partners.Count > 0)\n        {\n            if (!isRoot)\n            {\n                prefix = prefix[..^4] + (isLast ? \"    \" : \"│   \");\n            }\n\n            PrintParents(id, person.Partners, prefix, isLast, isRoot);\n            if (!isLast)\n            {\n                Console.WriteLine(prefix);\n            }\n        }\n    }\n\n    public void PrintTree()\n    {\n        var (grandparents, noPartner) = FilteredGrandparents();\n\n        if (grandparents.Count == 0 && noPartner.Count == 0)\n        {\n            Console.WriteLine(\"⚠️ No users are registered.\");\n            return;\n        }\n\n        if (noPartner.Count > 0)\n        {\n            Console.WriteLine(\"__________\\nParents unknown, without descendants and without a partner:\");\n            foreach (var p in noPartner)\n            {\n                Console.WriteLine($\"😐 {p.Name} (ID: {p.Id})\");\n            }\n        }\n\n        Console.WriteLine();\n        for (int i = 0; i < grandparents.Count; i++)\n        {\n            Console.WriteLine($\"__________\\nFamily #{i + 1}\");\n            PrintFamily(grandparents[i].Id);\n        }\n    }\n}\n\n//______________________________\npublic class Program: Tree\n{\n    private const string MENU = @\"\n---------------------------------------------\n| 1. Add person     | 4. Edit children      |  \n| 2. Remove person  | 5. Print tree         |\n| 3. Edit partners  | 6. Exit               |\n---------------------------------------------\";\n\n    public void Run()\n    {\n        while (true)\n        {\n            Console.WriteLine(MENU);\n            int option = Input.GetInt(\"\\nOption: \");\n            switch (option)\n            {\n                case 1:\n                    AddPerson();\n                    break;\n                case 2:\n                    RemovePerson();\n                    break;\n                case 3:\n                    EditPartners();\n                    break;\n                case 4:\n                    EditChildren();\n                    break;\n                case 5:\n                    PrintTree();\n                    break;\n                case 6:\n                    Console.WriteLine(\"Bye\");\n                    return;\n                default:\n                    Console.WriteLine(\"❌ Invalid option.\");\n                    break;\n            }\n        }\n    }\n\n    public static void Main()\n    {\n        Program program = new();\n        program.Run();\n    }\n}\n"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/c++/hectorio23.cpp",
    "content": "// Autor: Héctor Adán \n// GitHub: https://github.com/hectorio23\n\n#include <cstdlib>\n#include <iostream>\n#include <vector>\n#include <string>\n#include <stdexcept>\n#include <algorithm>\n\nusing namespace std;\n\nclass Person {\npublic:\n    int id;\n    string name;\n    Person* partner;\n    vector<Person*> children;\n\n    Person(int id, string name) : id(id), name(name), partner(nullptr) {}\n\n    void setPartner(Person* p) {\n        if (partner == nullptr) {\n            partner = p;\n            p->partner = this;  // Ensure both partners are connected\n        } else {\n            throw runtime_error(name + \" already has a partner.\");\n        }\n    }\n\n    void addChild(Person* child) {\n        if (child->parents().size() < 2) {\n            children.push_back(child);\n        } else {\n            throw runtime_error(child->name + \" already has two parents.\");\n        }\n    }\n\n    vector<Person*> parents() {\n        // Find parents by searching who has this person as a child\n        vector<Person*> parents;\n        for (Person* p : allPersons) {\n            if (find(p->children.begin(), p->children.end(), this) != p->children.end()) {\n                parents.push_back(p);\n            }\n        }\n        return parents;\n    }\n\n    static void displayTree(Person* p, int level = 0) {\n        if (p->partner) {\n            cout << string(level * 2, ' ') << p->partner->name << endl;\n        }\n        cout << string(level * 2, ' ') << p->name << endl;\n        for (Person* child : p->children) {\n            displayTree(child, level + 1);\n        }\n    }\n\n    static vector<Person*> allPersons;\n};\n\nvector<Person*> Person::allPersons;\n\n// Sample usage\nint main() {\n    Person* alice = new Person(1, \"Andrea\");\n    Person::allPersons.push_back(alice);\n    Person* bob = new Person(2, \"Adán\");\n    Person::allPersons.push_back(bob);\n    alice->setPartner(bob);\n    Person* alejandro = new Person(3, \"Alejandro\");\n    Person::allPersons.push_back(alejandro);\n    alice->addChild(alejandro);\n    Person::displayTree(alice);\n         \n    return EXIT_SUCCESS;\n}\n"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/dart/redom69.dart",
    "content": "class Person {\n  int id;\n  String name;\n  Person? couple;\n  List<Person> children;\n\n  Person({\n    required this.id,\n    required this.name,\n    this.couple,\n    List<Person>? children,\n  }) : children = children ?? [];\n\n  void addChild(Person child) {\n    children.add(child);\n  }\n\n  void modifyCouple(Person newCouple) {\n    couple = newCouple;\n  }\n\n  @override\n  String toString() {\n    String coupleName = couple != null ? couple!.name : \"None\";\n    return 'Person(id=$id, name=$name, couple=$coupleName, children=${children.length})';\n  }\n}\n\nclass FamilyTree {\n  Person root;\n  Map<int, Person> people;\n\n  FamilyTree(this.root) : people = {root.id: root};\n\n  void addPerson(Person person) {\n    if (!people.containsKey(person.id)) {\n      people[person.id] = person;\n    } else {\n      print('Ya existe');\n    }\n  }\n\n  void deletePerson(int personId) {\n    if (people.containsKey(personId)) {\n      people.remove(personId);\n    } else {\n      print('No existe');\n    }\n  }\n\n  void editPerson(int id,\n      {String? name, Person? couple, List<Person>? children}) {\n    if (people.containsKey(id)) {\n      Person person = people[id]!;\n      if (name != null) person.name = name;\n      if (couple != null) person.modifyCouple(couple);\n      if (children != null && children.isNotEmpty) person.children = children;\n    } else {\n      print('No existe');\n    }\n  }\n\n  void displayTree([Person? person, int level = 0]) {\n    person ??= root;\n\n    String indent = ' ' * (level * 4);\n    String coupleName =\n        person.couple != null ? ' & ${person.couple!.name}' : '';\n    print('$indent${person.name}$coupleName');\n\n    for (var child in person.children) {\n      displayTree(child, level + 1);\n    }\n  }\n}\n\nvoid main() {\n  Person jaehaerys = Person(id: 1, name: \"Jaehaerys I Targaryen\");\n  Person alysanne = Person(id: 2, name: \"Alysanne Targaryen\");\n\n  Person baelon = Person(id: 3, name: \"Baelon Targaryen\");\n  Person alyssa = Person(id: 4, name: \"Alyssa Targaryen\");\n\n  Person viserys = Person(id: 5, name: \"Viserys I Targaryen\");\n  Person aemma = Person(id: 6, name: \"Aemma Arryn\");\n\n  Person daemon = Person(id: 7, name: \"Daemon Targaryen\");\n  Person rhea = Person(id: 8, name: \"Rhea Royce\");\n  Person laena = Person(id: 9, name: \"Laena Velaryon\");\n  Person rhaenyra = Person(id: 10, name: \"Rhaenyra Targaryen\");\n\n  Person alicent = Person(id: 11, name: \"Alicent Hightower\");\n  Person aegonII = Person(id: 12, name: \"Aegon II Targaryen\");\n  Person helaena = Person(id: 13, name: \"Helaena Targaryen\");\n  Person aemond = Person(id: 14, name: \"Aemond Targaryen\");\n  Person daeron = Person(id: 15, name: \"Daeron Targaryen\");\n\n  jaehaerys.modifyCouple(alysanne);\n  baelon.modifyCouple(alyssa);\n  baelon.children = [viserys, daemon];\n  viserys.modifyCouple(aemma);\n  viserys.children = [rhaenyra];\n  daemon.modifyCouple(rhea);\n  daemon.children = [];\n\n  daemon.modifyCouple(laena);\n  Person baela = Person(id: 16, name: \"Baela Targaryen\");\n  Person rhaena = Person(id: 17, name: \"Rhaena Targaryen\");\n  daemon.children = [baela, rhaena];\n\n  rhaenyra.modifyCouple(daemon);\n\n  viserys.modifyCouple(alicent);\n  viserys.children.addAll([aegonII, helaena, aemond, daeron]);\n\n  FamilyTree familyTree = FamilyTree(viserys);\n  familyTree.addPerson(jaehaerys);\n  familyTree.addPerson(alysanne);\n  familyTree.addPerson(baelon);\n  familyTree.addPerson(alyssa);\n  familyTree.addPerson(daemon);\n  familyTree.addPerson(rhea);\n  familyTree.addPerson(laena);\n  familyTree.addPerson(rhaenyra);\n  familyTree.addPerson(alicent);\n  familyTree.addPerson(aegonII);\n  familyTree.addPerson(helaena);\n  familyTree.addPerson(aemond);\n  familyTree.addPerson(daeron);\n  familyTree.addPerson(baela);\n  familyTree.addPerson(rhaena);\n\n  familyTree.displayTree();\n}\n"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/ejercicio.md",
    "content": "# #34 ÁRBOL GENEALÓGICO DE LA CASA DEL DRAGÓN\n> #### Dificultad: Difícil | Publicación: 19/08/24 | Corrección: 26/08/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * ¡La Casa del Dragón ha finalizado y no volverá hasta 2026! \n * ¿Alguien se entera de todas las relaciones de parentesco\n * entre personajes que aparecen en la saga?\n * Desarrolla un árbol genealógico para relacionarlos (o invéntalo).\n * Requisitos:\n * 1. Estará formado por personas con las siguientes propiedades:\n *    - Identificador único (obligatorio)\n *    - Nombre (obligatorio)\n *    - Pareja (opcional)\n *    - Hijos (opcional)\n * 2. Una persona sólo puede tener una pareja (para simplificarlo).\n * 3. Las relaciones deben validarse dentro de lo posible.\n *    Ejemplo: Un hijo no puede tener tres padres.\n * Acciones:\n * 1. Crea un programa que permita crear y modificar el árbol.\n *    - Añadir y eliminar personas\n *    - Modificar pareja e hijos\n * 2. Podrás imprimir el árbol (de la manera que consideres).\n * \n * NOTA: Ten en cuenta que la complejidad puede ser alta si\n * se implementan todas las posibles relaciones. Intenta marcar\n * tus propias reglas y límites para que te resulte asumible.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/go/hozlucas28.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"slices\"\n\t\"strings\"\n)\n\n/* -------------------------------------------------------------------------- */\n/*                                    TYPES                                   */\n/* -------------------------------------------------------------------------- */\n\n/* ------------------------------ FamilyStatus ------------------------------ */\n\ntype TFamilyStatus string\n\nconst (\n\tfather TFamilyStatus = \"father\"\n\tmother TFamilyStatus = \"mother\"\n)\n\ntype familyStatus struct {\n\tFather TFamilyStatus\n\tMother TFamilyStatus\n}\n\nvar FamilyStatus familyStatus = familyStatus{\n\tFather: father,\n\tMother: mother,\n}\n\n/* ---------------------------------- UUID ---------------------------------- */\n\ntype UUID string\n\n/* -------------------------------------------------------------------------- */\n/*                                   ERRORS                                   */\n/* -------------------------------------------------------------------------- */\n\n/* --------------------------- PersonNotFoundError -------------------------- */\n\ntype PersonNotFoundError struct {\n\tuuid UUID\n\t_    struct{}\n}\n\nfunc (err *PersonNotFoundError) Error() string {\n\treturn fmt.Sprintf(\"Person with %s UUID not found\", err.uuid)\n}\n\n/* --------------------- PersonDoesNotHaveChildrenError --------------------- */\n\ntype PersonDoesNotHaveChildrenError struct {\n\tuuid UUID\n\t_    struct{}\n}\n\nfunc (err *PersonDoesNotHaveChildrenError) Error() string {\n\treturn fmt.Sprintf(\"Person with %s UUID does not have a children\", err.uuid)\n}\n\n/* ---------------------- PersonDoesNotHavePartnerError --------------------- */\n\ntype PersonDoesNotHavePartnerError struct {\n\tuuid UUID\n\t_    struct{}\n}\n\nfunc (err *PersonDoesNotHavePartnerError) Error() string {\n\treturn fmt.Sprintf(\"Person with %s UUID does not have a partner\", err.uuid)\n}\n\n/* ------------------- PersonDoesNotHaveFamilyStatusError ------------------- */\n\ntype PersonDoesNotHaveFamilyStatusError struct {\n\tuuid UUID\n\t_    struct{}\n}\n\nfunc (err *PersonDoesNotHaveFamilyStatusError) Error() string {\n\treturn fmt.Sprintf(\"Person with %s UUID does not have a family status\", err.uuid)\n}\n\n/* ---------------------- PersonDoesNotHaveAFatherError --------------------- */\n\ntype PersonDoesNotHaveAFatherError struct {\n\tuuid UUID\n\t_    struct{}\n}\n\nfunc (err *PersonDoesNotHaveAFatherError) Error() string {\n\treturn fmt.Sprintf(\"Person with %s UUID does not have a father\", err.uuid)\n}\n\n/* ---------------------- PersonDoesNotHaveAMotherError --------------------- */\n\ntype PersonDoesNotHaveAMotherError struct {\n\tuuid UUID\n\t_    struct{}\n}\n\nfunc (err *PersonDoesNotHaveAMotherError) Error() string {\n\treturn fmt.Sprintf(\"Person with %s UUID does not have a mother\", err.uuid)\n}\n\n/* -------------------- FamilyTreeDoesNotHavePeopleError -------------------- */\n\ntype FamilyTreeDoesNotHavePeopleError struct{}\n\nfunc (err *FamilyTreeDoesNotHavePeopleError) Error() string {\n\treturn fmt.Sprintf(\"Family tree does not have people\")\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                   CLASSES                                  */\n/* -------------------------------------------------------------------------- */\n\n/* --------------------------------- Person --------------------------------- */\n\ntype IPerson interface {\n\tGetName() string\n\tGetUUID() UUID\n\tGetChildren() ([]IPerson, error)\n\tGetPartner() (IPerson, error)\n\tGetFamilyStatus() (TFamilyStatus, error)\n\tGetFather() (IPerson, error)\n\tGetMother() (IPerson, error)\n\tSetFamilyStatus(familyStatus TFamilyStatus)\n\tSetFather(father IPerson)\n\tSetMother(mother IPerson)\n\tSetPartner(partner IPerson)\n\tAddChildren(children ...IPerson)\n\tRemoveChildren(children ...UUID)\n}\n\ntype person struct {\n\tname         string\n\tuuid         UUID\n\tchildren     []IPerson\n\tpartner      IPerson\n\tfamilyStatus TFamilyStatus\n\tfather       IPerson\n\tmother       IPerson\n\t_            struct{}\n}\n\nfunc NewPerson(name string, uuid UUID) IPerson {\n\tvar sanitizedName string = strings.TrimSpace(name)\n\tvar sanitizedUUID UUID = UUID(strings.TrimSpace(string(uuid)))\n\n\tif sanitizedName == \"\" {\n\t\tpanic(\n\t\t\tfmt.Sprintf(\n\t\t\t\t\"`name` parameter of `NewPerson` function must not be empty, received '%s' as `name`\",\n\t\t\t\tname,\n\t\t\t),\n\t\t)\n\t} else if sanitizedUUID == \"\" {\n\t\tpanic(\n\t\t\tfmt.Sprintf(\n\t\t\t\t\"`uuid` parameter of `NewPerson` function must not be empty, received '%s' as `uuid`\",\n\t\t\t\tuuid,\n\t\t\t))\n\t}\n\n\tvar person person = person{name: sanitizedName, uuid: sanitizedUUID}\n\treturn &person\n}\n\nfunc (p *person) GetName() string {\n\treturn p.name\n}\n\nfunc (p *person) GetUUID() UUID {\n\treturn p.uuid\n}\n\nfunc (p *person) GetChildren() ([]IPerson, error) {\n\tvar children []IPerson = p.children\n\tif len(children) < 1 {\n\t\treturn children, &PersonDoesNotHaveChildrenError{uuid: p.uuid}\n\t}\n\n\treturn children, nil\n}\n\nfunc (p *person) GetPartner() (IPerson, error) {\n\tvar partner IPerson = p.partner\n\tif partner == nil {\n\t\treturn partner, &PersonDoesNotHavePartnerError{uuid: p.uuid}\n\t}\n\n\treturn p.partner, nil\n}\n\nfunc (p *person) GetFamilyStatus() (TFamilyStatus, error) {\n\tvar familyStatus TFamilyStatus = p.familyStatus\n\tif familyStatus == \"\" {\n\t\treturn familyStatus, &PersonDoesNotHaveFamilyStatusError{uuid: p.uuid}\n\t}\n\n\treturn familyStatus, nil\n}\n\nfunc (p *person) GetFather() (IPerson, error) {\n\tvar father IPerson = p.father\n\tif father == nil {\n\t\treturn father, &PersonDoesNotHaveAFatherError{uuid: p.uuid}\n\t}\n\n\treturn father, nil\n}\n\nfunc (p *person) GetMother() (IPerson, error) {\n\tvar mother IPerson = p.mother\n\tif mother == nil {\n\t\treturn mother, &PersonDoesNotHaveAMotherError{uuid: p.uuid}\n\t}\n\n\treturn mother, nil\n}\n\nfunc (p *person) SetFamilyStatus(familyStatus TFamilyStatus) {\n\tp.familyStatus = familyStatus\n}\n\nfunc (p *person) SetFather(father IPerson) {\n\tp.father = father\n\tfather.AddChildren(p)\n}\n\nfunc (p *person) SetMother(mother IPerson) {\n\tp.mother = mother\n\tmother.AddChildren(p)\n}\n\nfunc (p *person) SetPartner(partner IPerson) {\n\tif p.partner == partner {\n\t\treturn\n\t}\n\n\tp.partner = partner\n\tpartner.SetPartner(p)\n}\n\nfunc (p *person) AddChildren(children ...IPerson) {\n\tp.children = append(p.children, children...)\n}\n\nfunc (p *person) RemoveChildren(children ...UUID) {\n\tfor _, uuid := range children {\n\t\tp.children = slices.DeleteFunc(p.children, func(c IPerson) bool {\n\t\t\tvar cUUID UUID = c.GetUUID()\n\t\t\treturn uuid == cUUID\n\t\t})\n\t}\n}\n\n/* ------------------------------- FamilyTree ------------------------------- */\n\ntype IFamilyTree interface {\n\tGetPerson(uuid UUID) (IPerson, error)\n\tGetPeople() ([]IPerson, error)\n\tAddPeople(people ...IPerson)\n\tRemovePeople(people ...UUID)\n\tPeopleToString() string\n}\n\ntype familyTree struct {\n\tpeople []IPerson\n\t_      struct{}\n}\n\nfunc NewFamilyTree() IFamilyTree {\n\tvar familyTree familyTree = familyTree{}\n\treturn &familyTree\n}\n\nfunc (ft *familyTree) GetPerson(uuid UUID) (IPerson, error) {\n\tpeople, err := ft.GetPeople()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tfor _, person := range people {\n\t\tvar pUUID UUID = person.GetUUID()\n\n\t\tif pUUID == uuid {\n\t\t\treturn person, nil\n\t\t}\n\t}\n\n\treturn nil, &PersonNotFoundError{uuid: uuid}\n}\n\nfunc (ft *familyTree) GetPeople() ([]IPerson, error) {\n\tvar people []IPerson = ft.people\n\tif len(people) < 1 {\n\t\treturn people, &FamilyTreeDoesNotHavePeopleError{}\n\t}\n\n\treturn people, nil\n}\n\nfunc (ft *familyTree) AddPeople(people ...IPerson) {\n\tft.people = append(ft.people, people...)\n}\n\nfunc (ft *familyTree) RemovePeople(people ...UUID) {\n\tfor _, uuid := range people {\n\t\tft.people = slices.DeleteFunc(ft.people, func(p IPerson) bool {\n\t\t\tvar pUUID UUID = p.GetUUID()\n\t\t\treturn uuid == pUUID\n\t\t})\n\t}\n}\n\nfunc (ft *familyTree) PeopleToString() string {\n\tvar peopleStr string\n\n\tpeopleStr += fmt.Sprintf(\"+%s+\\n\", strings.Repeat(\"-\", 177))\n\n\tpeopleStr += fmt.Sprintf(\"| %-20s \", \"name\")\n\tpeopleStr += fmt.Sprintf(\"| %-64s \", \"children\")\n\tpeopleStr += fmt.Sprintf(\"| %-16s \", \"familyStatus\")\n\tpeopleStr += fmt.Sprintf(\"| %-20s \", \"father\")\n\tpeopleStr += fmt.Sprintf(\"| %-20s \", \"mother\")\n\tpeopleStr += fmt.Sprintf(\"| %-20s |\\n\", \"partner\")\n\n\tfor _, p := range ft.people {\n\t\tpeopleStr += fmt.Sprintf(\"-%s-\\n\", strings.Repeat(\"-\", 177))\n\n\t\tvar name string = p.GetName()\n\t\tpeopleStr += fmt.Sprintf(\"| %-20s \", name)\n\n\t\tchildren, err := p.GetChildren()\n\t\tif err == nil {\n\t\t\tif len(children) > 1 {\n\t\t\t\tvar aux []string\n\t\t\t\tfor _, child := range children {\n\t\t\t\t\taux = append(aux, child.GetName())\n\t\t\t\t}\n\n\t\t\t\tvar childrenStr string\n\t\t\t\tchildrenStr = strings.Join(aux[:len(aux)-1], \", \")\n\t\t\t\tchildrenStr += fmt.Sprintf(\", and %s.\", aux[len(aux)-1])\n\t\t\t\tpeopleStr += fmt.Sprintf(\"| %-64s \", childrenStr)\n\t\t\t} else {\n\t\t\t\tpeopleStr += fmt.Sprintf(\"| %-64s \", children[0].GetName() + \".\")\n\t\t\t}\n\t\t} else {\n\t\t\tpeopleStr += fmt.Sprintf(\"| %-64s \", \"nil\")\n\t\t}\n\n\t\tfamilyStatus, err := p.GetFamilyStatus()\n\t\tif err == nil {\n\t\t\tpeopleStr += fmt.Sprintf(\"| %-16s \", familyStatus)\n\t\t} else {\n\t\t\tpeopleStr += fmt.Sprintf(\"| %-16s \", \"nil\")\n\t\t}\n\n\t\tfather, err := p.GetFather()\n\t\tif err == nil {\n\t\t\tpeopleStr += fmt.Sprintf(\"| %-20s \", father.GetName())\n\t\t} else {\n\t\t\tpeopleStr += fmt.Sprintf(\"| %-20s \", \"nil\")\n\t\t}\n\n\t\tmother, err := p.GetMother()\n\t\tif err == nil {\n\t\t\tpeopleStr += fmt.Sprintf(\"| %-20s \", mother.GetName())\n\t\t} else {\n\t\t\tpeopleStr += fmt.Sprintf(\"| %-20s \", \"nil\")\n\t\t}\n\n\t\tpartner, err := p.GetPartner()\n\t\tif err == nil {\n\t\t\tpeopleStr += fmt.Sprintf(\"| %-20s |\\n\", partner.GetName())\n\t\t} else {\n\t\t\tpeopleStr += fmt.Sprintf(\"| %-20s |\\n\", \"nil\")\n\t\t}\n\n\t}\n\n\tpeopleStr += fmt.Sprintf(\"+%s+\\n\", strings.Repeat(\"-\", 177))\n\n\treturn peopleStr\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\nfunc main() {\n\tvar jaehaerysTargaryen IPerson = NewPerson(\"Jaehaerys Targaryen\", \"1\")\n\tjaehaerysTargaryen.SetFamilyStatus(FamilyStatus.Father)\n\n\tvar alysanneTargaryen IPerson = NewPerson(\"Alysanne Targaryen\", \"2\")\n\talysanneTargaryen.SetPartner(jaehaerysTargaryen)\n\talysanneTargaryen.SetFamilyStatus(FamilyStatus.Mother)\n\n\tvar jocelynBaratheon IPerson = NewPerson(\"Jocelyn Baratheon\", \"3\")\n\tjocelynBaratheon.SetFamilyStatus(FamilyStatus.Mother)\n\n\tvar aemonTargaryen IPerson = NewPerson(\"Aemon Targaryen\", \"4\")\n\taemonTargaryen.SetPartner(jocelynBaratheon)\n\taemonTargaryen.SetFamilyStatus(FamilyStatus.Father)\n\taemonTargaryen.SetFather(jaehaerysTargaryen)\n\taemonTargaryen.SetMother(alysanneTargaryen)\n\n\tvar baelonTargaryen IPerson = NewPerson(\"Baelon Targaryen\", \"5\")\n\tbaelonTargaryen.SetFamilyStatus(FamilyStatus.Mother)\n\tbaelonTargaryen.SetFather(jaehaerysTargaryen)\n\tbaelonTargaryen.SetMother(alysanneTargaryen)\n\n\tvar alyssaTargaryen IPerson = NewPerson(\"Alyssa Targaryen\", \"6\")\n\talyssaTargaryen.SetPartner(baelonTargaryen)\n\talyssaTargaryen.SetFamilyStatus(FamilyStatus.Mother)\n\talyssaTargaryen.SetFather(jaehaerysTargaryen)\n\talyssaTargaryen.SetMother(alysanneTargaryen)\n\n\tvar lyonelStrong IPerson = NewPerson(\"Lyonel Strong\", \"7\")\n\tlyonelStrong.SetFamilyStatus(FamilyStatus.Father)\n\n\tvar vaemondValaryon IPerson = NewPerson(\"Vaemond Valaryon\", \"8\")\n\n\tvar corlysVelaryon IPerson = NewPerson(\"Corlys Velaryon\", \"9\")\n\tcorlysVelaryon.SetFamilyStatus(FamilyStatus.Father)\n\n\tvar rhaenysTargaryen IPerson = NewPerson(\"Rhaenys Targaryen\", \"10\")\n\trhaenysTargaryen.SetFamilyStatus(FamilyStatus.Mother)\n\trhaenysTargaryen.SetPartner(corlysVelaryon)\n\trhaenysTargaryen.SetFather(aemonTargaryen)\n\trhaenysTargaryen.SetMother(jocelynBaratheon)\n\n\tvar rheaRoyce IPerson = NewPerson(\"Rhea Royce\", \"11\")\n\trheaRoyce.SetFamilyStatus(FamilyStatus.Mother)\n\n\tvar daemonTargaryen IPerson = NewPerson(\"Daemon Targaryen\", \"12\")\n\tdaemonTargaryen.SetFamilyStatus(FamilyStatus.Father)\n\tdaemonTargaryen.SetPartner(rheaRoyce)\n\tdaemonTargaryen.SetFather(baelonTargaryen)\n\tdaemonTargaryen.SetMother(alyssaTargaryen)\n\n\tvar aemmaArryn IPerson = NewPerson(\"Aemma Arryn\", \"13\")\n\taemmaArryn.SetFamilyStatus(FamilyStatus.Mother)\n\n\tvar viserysTargaryen IPerson = NewPerson(\"Viserys Targaryen\", \"14\")\n\tviserysTargaryen.SetFamilyStatus(FamilyStatus.Father)\n\tviserysTargaryen.SetPartner(aemmaArryn)\n\tviserysTargaryen.SetFather(baelonTargaryen)\n\tviserysTargaryen.SetMother(alyssaTargaryen)\n\n\tvar ottoHightower IPerson = NewPerson(\"Otto Hightower\", \"15\")\n\tottoHightower.SetFamilyStatus(FamilyStatus.Father)\n\n\tvar hobertHightower IPerson = NewPerson(\"Hobert Hightower\", \"16\")\n\n\tvar familyTree IFamilyTree = NewFamilyTree()\n\n\tfamilyTree.AddPeople(\n\t\tjaehaerysTargaryen,\n\t\talysanneTargaryen,\n\t\tjocelynBaratheon,\n\t\taemonTargaryen,\n\t\tbaelonTargaryen,\n\t\talyssaTargaryen,\n\t\tlyonelStrong,\n\t\tvaemondValaryon,\n\t\tcorlysVelaryon,\n\t\trhaenysTargaryen,\n\t\trheaRoyce,\n\t\tdaemonTargaryen,\n\t\taemmaArryn,\n\t\tviserysTargaryen,\n\t\tottoHightower,\n\t\thobertHightower,\n\t)\n\n\tfmt.Printf(\"House of Dragon family tree from the first row to the third one...\\n\\n\")\n\n\tfmt.Print(familyTree.PeopleToString())\n\n\tfmt.Println(\"\\n> House of Dragon official family tree: https://www.hbo.com/house-of-the-dragon/character-guide\")\n}\n"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/java/AmadorQuispe.java",
    "content": "package com.amsoft.roadmap.example34;\n\nimport java.util.*;\nimport java.util.stream.Collectors;\nimport java.util.stream.Stream;\n\npublic class Example34 {\n    public static void main(String[] args) {\n        FamilyTree tree = new FamilyTree();\n\n        Person p1 = new Person(\"Persona 01\");\n        Person p2 = new Person(\"Persona 02\");\n        Person p3 = new Person(\"Persona 03\");\n        Person p4 = new Person(\"Persona 04\");\n        Person p5 = new Person(\"Persona 05\");\n\n        p1.setPartner(p2);\n        p2.setPartner(p1);\n\n        p1.addChildren(p3, p4);\n        p2.addChildren(p3, p4);\n\n        p3.addChild(p5);\n\n        tree.addPeople(p1, p2, p3, p4, p5);\n\n        tree.printTree();\n    }\n\n    static class Person {\n        private final UUID id = UUID.randomUUID();\n        private final String name;\n        private Person partner;\n        private List<Person> children;\n\n        public Person(String name) {\n            this.name = name;\n            this.children = new ArrayList<>();\n        }\n\n        public UUID getId() {\n            return id;\n        }\n\n        public String getName() {\n            return name;\n        }\n\n        public Person getPartner() {\n            return partner;\n        }\n\n        public void setPartner(Person partner) {\n            Optional.ofNullable(this.partner)\n                    .ifPresentOrElse(p -> System.out.println(\"Error: \" + this.name + \" ya tiene pareja.\"),\n                            () -> this.partner = partner);\n        }\n\n        public List<Person> getChildren() {\n            return children;\n        }\n\n        public void addChild(Person child) {\n            if (children.stream().noneMatch(c -> c.equals(child))) {\n                children = Stream.concat(children.stream(), Stream.of(child))\n                        .collect(Collectors.toList());\n            } else {\n                System.out.println(\"Error: El hijo \" + child.getName() + \" ya existe.\");\n            }\n        }\n\n\n        public void addChildren(Person... children) {\n            Arrays.stream(children)\n                    .forEach(this::addChild);\n        }\n    }\n\n    static class FamilyTree {\n        private List<Person> people;\n\n        public FamilyTree() {\n            this.people = new ArrayList<>();\n        }\n\n        public void addPeople(Person... persons) {\n            people = Stream.concat(people.stream(), Arrays.stream(persons))\n                    .distinct()\n                    .collect(Collectors.toList());\n        }\n\n        public void removePerson(Person person) {\n            Optional.of(people.remove(person))\n                    .ifPresentOrElse(p -> System.out.println(person.getName() + \" eliminado.\"),\n                            () -> System.out.println(\"Error: Persona no encontrada.\"));\n        }\n\n        public void printTree() {\n            people.forEach(person -> {\n                System.out.println(\"ID: \" + person.getId() + \", Name: \" + person.getName());\n                Optional.ofNullable(person.getPartner())\n                        .ifPresent(p -> System.out.println(\"  Pareja: \" + p.getName()));\n                if (!person.getChildren().isEmpty()) {\n                    System.out.println(\"  Hijos: \" + person.getChildren()\n                            .stream()\n                            .map(Person::getName)\n                            .collect(Collectors.joining(\", \")));\n                }\n            });\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/java/Josegs95.java",
    "content": "import java.util.ArrayList;\nimport java.util.List;\nimport java.util.Scanner;\n\npublic class Josegs95 {\n    public static void main(String[] args) {\n        new Josegs95().houseOfDragons();\n    }\n\n    private int idCounter = 1;\n\n    private List<Person> personList;\n\n    final private Scanner sc = new Scanner(System.in);\n\n    public void houseOfDragons(){\n        personList = new ArrayList<>();\n\n        try(sc){\n            app: while(true){\n                printOptions();\n                String option = askOptionToUser();\n                switch (option){\n                    case \"1\":\n                        addPerson();\n                        break;\n                    case \"2\":\n                        deletePerson();\n                        break;\n                    case \"3\":\n                        addPartner();\n                        break;\n                    case \"4\":\n                        addChild();\n                        break;\n                    case \"5\":\n                        printFamilyTree();\n                        break;\n                    case \"6\":\n                        break app;\n                }\n                System.out.println();\n            }\n        }\n\n        System.out.println(\"Saliendo de la aplicación\");\n    }\n\n    private String askOptionToUser(){\n        boolean validOption = false;\n        String option = null;\n        while(!validOption){\n            System.out.print(\"Seleccione la opción que desee (1-6): \");\n            option = sc.nextLine();\n            switch (option){\n                case \"1\": case \"2\": case \"3\": case \"4\": case \"5\": case \"6\":\n                    validOption = true;\n                    break;\n                default:\n                    System.out.println(\"Opción no válida.\");\n            }\n        }\n        System.out.println();\n\n        return option;\n    }\n\n    private void addPerson(){\n        System.out.print(\"Introduzca el nombre de la persona: \");\n        String name = sc.nextLine();\n\n        personList.add(new Person(idCounter++, name));\n        System.out.println(name + \" añadido/a correctamente.\");\n    }\n\n    private void deletePerson(){\n        printPeople();\n        try{\n            Person person = getPersonByIDFromUser(\"Introduzca el 'id' de la persona que quiere borrar o '0' para cancelar: \");\n\n            Person partner = person.getPartner();\n            if(partner != null)\n                partner.setPartner(null);\n            Person father = person.getFather();\n            if(father != null)\n                father.getChildren().remove(person);\n            Person mother = person.getMother();\n            if(mother != null)\n                mother.getChildren().remove(person);\n\n            personList.remove(person);\n            System.out.println(person.getName() + \" borrada correctamente.\");\n        } catch (SafeCancelException e) {\n            System.out.println(\"Abortando operación...\");\n        }\n    }\n\n    private void addPartner(){\n        printPeople();\n\n        try {\n            Person person1 = getPersonByIDFromUser(\"Introduzca el 'id' de la persona que a la que quiere \" +\n                    \"añadir una pareja o '0' para cancelar: \");\n            if (person1.getPartner() != null){\n                System.out.println(person1.getName() + \" ya tiene pareja\");\n                return;\n            }\n\n            Person person2 = getPersonByIDFromUser(\"Introduzca el 'id' de la persona que quiere \" +\n                    \"añadir como pareja de \" + person1 + \" o '0' para cancelar: \");\n            if (person2.getPartner() != null){\n                System.out.println(person2.getName() + \" ya tiene pareja\");\n                return;\n            }\n            if (person1 == person2){\n                System.out.println(\"No puede seleccionar a la misma persona como pareja\");\n                return;\n            }\n\n            person1.setPartner(person2);\n            person2.setPartner(person1);\n        } catch (SafeCancelException e) {\n            System.out.println(\"Abortando operación...\");\n        }\n    }\n\n    private void addChild(){\n        printPeople();\n\n        try{\n            Person child = getPersonByIDFromUser(\"Introduzca el 'id' del hijo/a; o '0' para cancelar: \");\n\n            if (child.getFather() != null)\n                System.out.println(\"Esta persona ya tiene un padre\");\n            else {\n                Person father = getPersonByIDFromUser(\"Introduzca el 'id' del padre; o '0' para cancelar: \");\n                if (child == father){\n                    System.out.println(\"No puede elegir a la misma persona como padre\");\n                }\n                father.addChild(child);\n                child.setFather(father);\n            }\n            if (child.getMother() != null)\n                System.out.println(\"Esta persona ya tiene una madre\");\n            else{\n                Person mother = getPersonByIDFromUser(\"Introduzca el 'id' de la madre; o '0' para cancelar: \");\n                if (child == mother){\n                    System.out.println(\"No puede elegir a la misma persona como madre\");\n                }\n                mother.addChild(child);\n                child.setMother(mother);\n            }\n        } catch (SafeCancelException e) {\n            System.out.println(\"Abortando operación...\");\n        }\n    }\n\n    private void printFamilyTree(){\n        List<Person> printedPeople = new ArrayList<>();\n        for(Person person : personList){\n            if (printedPeople.contains(person))\n                continue; //Ya está pintado\n            if (person.hasParents())\n                continue; //Tiene personas por encima en el árbol\n\n            if (person.getPartner() != null){\n                if (person.getPartner().hasParents())\n                    continue;\n            }\n\n            printPersonTree(printedPeople, person, \"\");\n            System.out.println();\n        }\n    }\n\n    private void printPersonTree(List<Person> printedPeople, Person person, String indent){\n        System.out.print(person.getName());\n        printedPeople.add(person);\n\n        if (person.getPartner() != null){\n            System.out.println(\"/\" + person.getPartner().getName());\n            printedPeople.add(person.getPartner());\n        } else\n            System.out.println();\n\n        for (Person child : person.getChildren()){\n            System.out.print(indent + \"|_> \");\n            printPersonTree(printedPeople, child, indent.concat(\"\\t\\t\"));\n        }\n    }\n\n    private Person getPersonByIDFromUser(String message) throws SafeCancelException {\n        Integer idPerson = askIDToUser(message);\n        if (idPerson == 0)\n            throw new SafeCancelException();\n\n        Person person = searchPersonByID(idPerson);\n        if (person == null){\n            System.out.println(\"No hay nadie registrado con ese 'id'\");\n            throw new SafeCancelException();\n        }\n\n        return person;\n    }\n\n    private Integer askIDToUser(String message){\n        Integer id = null;\n        while(id == null){\n            System.out.print(message);\n            try{\n                id = Integer.parseInt(sc.nextLine());\n            } catch (NumberFormatException e) {\n                System.out.println(\"Error. Debe introducir un número\");\n            }\n        }\n\n        return id;\n    }\n\n    private Person searchPersonByID(int idPerson){\n        for (Person person : personList){\n            if (person.getID() == idPerson)\n                return person;\n        }\n\n        return null;\n    }\n\n    private void printOptions(){\n        System.out.println(\"---Opciones---\");\n        System.out.println(\"1. Añadir persona\");\n        System.out.println(\"2. Borrar persona\");\n        System.out.println(\"3. Añadir pareja de persona\");\n        System.out.println(\"4. Añadir hijo/s de persona\");\n        System.out.println(\"5. Imprimir árbol genealógico\");\n        System.out.println(\"6. Salir del programa\");\n        System.out.println(\"----------------------\");\n    }\n\n    private void printPeople(){\n        for (Person p : personList)\n            System.out.println(p);\n    }\n\n    public class Person {\n        final private Integer ID;\n        final private String NAME;\n        private Person partner;\n        private Person mother;\n        private Person father;\n        private List<Person> children;\n\n        public Person(Integer ID, String name) {\n            this.ID = ID;\n            this.NAME = name;\n            children = new ArrayList<>();\n        }\n\n        public Integer getID() {\n            return ID;\n        }\n\n        public String getName() {\n            return NAME;\n        }\n\n        public Person getPartner() {\n            return partner;\n        }\n\n        public void setPartner(Person partner) {\n            this.partner = partner;\n        }\n\n        public List<Person> getChildren() {\n            return children;\n        }\n\n        public boolean addChild(Person child){\n            if (!children.contains(child))\n                return children.add(child);\n            else\n                return false;\n        }\n\n        public Person getMother() {\n            return mother;\n        }\n\n        public void setMother(Person mother) {\n            this.mother = mother;\n        }\n\n        public Person getFather() {\n            return father;\n        }\n\n        public void setFather(Person father) {\n            this.father = father;\n        }\n\n        public boolean hasParents(){\n            return father != null || mother != null;\n        }\n\n        @Override\n        public String toString() {\n            return NAME + \"[id:\" + ID + \"]\";\n        }\n    }\n\n    public class SafeCancelException extends Exception{}\n}\n"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/java/Mantaras96.java",
    "content": "package org.example;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.UUID;\n\npublic class Mantaras96 {\n\n    public static void main(String[] args) {\n\n        // Crear personas\n        Person person1 = new Person(\"Meri\");\n        Person person2 = new Person(\"John\");\n        Person child1 = new Person(\"Tom\");\n        Person child2 = new Person(\"Anna\");\n\n        // Establecer relaciones\n        person1.setPartner(person2);\n\n        // Añadir hijos\n        person1.addChild(child1);\n        person1.addChild(child2);\n\n        // Imprimir la familia de person1\n        printFamily(person1);\n        System.out.println(\"####################### Persona2 #######################\");\n        printFamily(person2);\n\n    }\n\n    public static class Person {\n\n        private final String identifier;\n        private Person partner;\n        private final String name;\n        private List<Person> children;\n\n        public Person(String name) {\n            this.identifier = UUID.randomUUID().toString();\n            this.name = name;\n            this.children = new ArrayList<Person>(); // Initialize the list\n        }\n\n        public String getIdentifier() {\n            return identifier;\n        }\n\n        public Person getPartner() {\n            return partner;\n        }\n\n        public void setPartner(Person partner) {\n            if (this.partner != partner) {\n                this.partner = partner;\n                if (partner != null && partner.getPartner() != this) {\n                    partner.setPartner(this);\n                }\n            }\n        }\n\n        public String getName() {\n            return name;\n        }\n\n        public List<Person> getChildren() {\n            return children;\n        }\n\n        public void setChildren(List<Person> children) {\n            this.children = children;\n        }\n\n        public void addChild(Person child) {\n            if (!this.children.contains(child)) {\n                this.children.add(child);\n                if (this.partner != null && !this.partner.getChildren().contains(child)) {\n                    this.partner.getChildren().add(child);\n                }\n            }\n        }\n\n        @Override\n        public String toString() {\n            return \"My name is \" + this.name;\n        }\n\n    }\n\n    private static void printFamily(Person persona) {\n        String info = persona.toString();\n        if (persona.getPartner() != null) {\n            info += \" y mi pareja es \" + persona.getPartner().getName();\n        } else {\n            info += \" y no tengo pareja\";\n        }\n        System.out.println(info);\n    \n        if (persona.getChildren().size() > 0) {\n            System.out.println(\"----------- Hijos ----------\");\n            for (Person child : persona.getChildren()) {\n                System.out.println(\"Soy el hijo de \" + persona.getName() + \" y mi nombre es \" + child.getName());\n                printFamily(child);\n            }\n        } else {\n            System.out.println(\" No tengo hijos \");\n        }\n    }\n    \n\n}\n"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/java/MohamedElderkaoui.java",
    "content": "import java.util.*;\n\npublic class MohamedElderkaoui{\n\n    public static void main(String[] args) {\n        ArbolGenealogico arbol = new ArbolGenealogico();\n\n        // Añadimos personas\n        arbol.añadirPersona(\"Alicia\");\n        arbol.añadirPersona(\"Roberto\");\n        arbol.añadirPersona(\"Carlos\");\n\n        // Obtenemos los IDs de las personas\n        String idAlicia = arbol.getPersonas().values().stream()\n                .filter(p -> p.getNombre().equals(\"Alicia\")).findFirst().get().getId();\n        String idRoberto = arbol.getPersonas().values().stream()\n                .filter(p -> p.getNombre().equals(\"Roberto\")).findFirst().get().getId();\n        String idCarlos = arbol.getPersonas().values().stream()\n                .filter(p -> p.getNombre().equals(\"Carlos\")).findFirst().get().getId();\n\n        // Modificamos relaciones\n        arbol.modificarPareja(idAlicia, idRoberto);\n        arbol.añadirHijo(idAlicia, idCarlos);\n\n        // Imprimimos el árbol\n        arbol.imprimirArbol();\n    }\n}\n\n\nclass Persona {\n    private final String id;\n    private String nombre;\n    private Persona pareja;\n    private final List<Persona> hijos;\n\n    public Persona(String nombre) {\n        this.id = UUID.randomUUID().toString(); // Genera un identificador único\n        this.nombre = nombre;\n        this.hijos = new ArrayList<>();\n    }\n\n    public String getId() {\n        return id;\n    }\n\n    public String getNombre() {\n        return nombre;\n    }\n\n    public void setNombre(String nombre) {\n        this.nombre = nombre;\n    }\n\n    public Optional<Persona> getPareja() {\n        return Optional.ofNullable(pareja);\n    }\n\n    public void setPareja(Persona pareja) {\n        this.pareja = pareja;\n    }\n\n    public List<Persona> getHijos() {\n        return hijos;\n    }\n\n    public void añadirHijo(Persona hijo) {\n        if (!hijos.contains(hijo)) {\n            hijos.add(hijo);\n        }\n    }\n\n    public void eliminarHijo(Persona hijo) {\n        hijos.remove(hijo);\n    }\n\n    @Override\n    public String toString() {\n        return \"Persona{id='\" + id + \"', nombre='\" + nombre + \"'}\";\n    }\n}\n\nclass ArbolGenealogico {\n    private final Map<String, Persona> personas;\n\n    public ArbolGenealogico() {\n        this.personas = new HashMap<>();\n    }\n\n    public void añadirPersona(String nombre) {\n        Persona nuevaPersona = new Persona(nombre);\n        personas.put(nuevaPersona.getId(), nuevaPersona);\n        System.out.println(\"Persona añadida: \" + nuevaPersona);\n    }\n\n    public void eliminarPersona(String id) {\n        Persona persona = personas.remove(id);\n        if (persona != null) {\n            System.out.println(\"Persona eliminada: \" + persona);\n        } else {\n            System.out.println(\"Persona no encontrada.\");\n        }\n    }\n\n    public void modificarPareja(String idPersona, String idPareja) {\n        Persona persona = personas.get(idPersona);\n        Persona pareja = personas.get(idPareja);\n\n        if (persona != null && pareja != null) {\n            persona.setPareja(pareja);\n            pareja.setPareja(persona); // Hacemos la relación bidireccional\n            System.out.println(persona.getNombre() + \" ahora está emparejado con \" + pareja.getNombre());\n        } else {\n            System.out.println(\"Una o ambas personas no fueron encontradas.\");\n        }\n    }\n\n    public void añadirHijo(String idPadre, String idHijo) {\n        Persona padre = personas.get(idPadre);\n        Persona hijo = personas.get(idHijo);\n\n        if (padre != null && hijo != null) {\n            padre.añadirHijo(hijo);\n            System.out.println(hijo.getNombre() + \" ahora es hijo de \" + padre.getNombre());\n        } else {\n            System.out.println(\"Padre o hijo no fueron encontrados.\");\n        }\n    }\n\n    public void imprimirArbol() {\n        for (Persona persona : personas.values()) {\n            System.out.println(persona.getNombre() + \" (ID: \" + persona.getId() + \")\");\n            persona.getPareja().ifPresent(p -> System.out.println(\"  Pareja: \" + p.getNombre()));\n            if (!persona.getHijos().isEmpty()) {\n                System.out.println(\"  Hijos:\");\n                for (Persona hijo : persona.getHijos()) {\n                    System.out.println(\"    - \" + hijo.getNombre());\n                }\n            }\n        }\n    }\n\n    public Map<String, Persona> getPersonas() {\n        return personas;\n    }\n}\n\n"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/java/asjordi.java",
    "content": "import java.util.LinkedList;\nimport java.util.List;\nimport java.util.UUID;\n\npublic class asjordi {\n\n    public static void main(String[] args) {\n        FamilyTree tree = new FamilyTree();\n\n        Person john = new Person(\"John\");\n        Person jane = new Person(\"Jane\");\n        Person jack = new Person(\"Jack\");\n        Person jill = new Person(\"Jill\");\n        Person jenny = new Person(\"Jenny\");\n\n        john.setPartner(jane);\n        jane.setPartner(john);\n\n        john.addChild(jack);\n        john.addChild(jill);\n        jane.addChild(jack);\n        jane.addChild(jill);\n\n        jack.addChild(jenny);\n\n        tree.addPerson(john);\n        tree.addPerson(jane);\n\n        tree.printTree();\n\n    }\n\n    static class Person {\n        private final UUID id = UUID.randomUUID();\n        private String name;\n        private Person partner;\n        private List<Person> children;\n\n        public Person(String name) {\n            this.name = name;\n            this.children = new LinkedList<>();\n        }\n\n        public UUID getId() {\n            return id;\n        }\n\n        public String getName() {\n            return name;\n        }\n\n        public Person getPartner() {\n            return partner;\n        }\n\n        public void setPartner(Person partner) {\n            this.partner = partner;\n        }\n\n        public List<Person> getChildren() {\n            return children;\n        }\n\n        public void addChild(Person child) {\n            this.children.add(child);\n        }\n\n        public void removeChild(Person child) {\n            this.children.remove(child);\n        }\n    }\n\n    static class FamilyTree {\n        private List<Person> people;\n\n        public FamilyTree() {\n            this.people = new LinkedList<>();\n        }\n\n        public void addPerson(Person person) {\n            this.people.add(person);\n        }\n\n        public void removePerson(Person person) {\n            this.people.remove(person);\n        }\n\n        public void printTree() {\n            for (Person person : people) {\n                System.out.println(\"ID: \" + person.getId() + \", Name: \" + person.getName());\n                if (person.getPartner() != null) System.out.println(\"  Partner: \" + person.getPartner().getName());\n                if (!person.getChildren().isEmpty()) {\n                    System.out.println(\"  Children: \");\n                    for (Person child : person.getChildren()) {\n                        System.out.println(\"    - \" + child.getName());\n                    }\n                }\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/java/martinbohorquez.java",
    "content": "import java.util.*;\n\n/**\n * #34 ÁRBOL GENEALÓGICO DE LA CASA DEL DRAGÓN\n *\n * @author martinbohorquez\n */\npublic class martinbohorquez {\n    public static void main(String[] args) {\n        FamilyTree tree = new FamilyTree();\n\n        tree.addPerson(1, \"Jocelyn\", Gender.FEMALE);\n        tree.addPerson(2, \"Aemon\", Gender.MALE);\n\n        tree.setPartner(1, 2);\n\n        tree.addPerson(3, \"Rhaenys\", Gender.FEMALE);\n\n        tree.addChild(1, 3);\n\n        tree.addPerson(4, \"Corlys\", Gender.MALE);\n\n        tree.setPartner(3, 4);\n\n        tree.addPerson(5, \"Laena\", Gender.FEMALE);\n        tree.addPerson(6, \"Laenor\", Gender.MALE);\n\n        tree.addChild(3, 5);\n        tree.addChild(3, 6);\n\n        tree.addPerson(7, \"Baelon\", Gender.MALE);\n        tree.addPerson(8, \"Alyssa\", Gender.FEMALE);\n\n        tree.setPartner(7, 8);\n\n        tree.addPerson(9, \"Viserys I\", Gender.MALE);\n        tree.addPerson(10, \"Daemon\", Gender.MALE);\n\n        tree.addChild(7, 9);\n        tree.addChild(8, 10);\n\n        tree.addPerson(11, \"Aemma\", Gender.FEMALE);\n\n        tree.setPartner(9, 11);\n\n        tree.addPerson(12, \"Rhaenyra\", Gender.FEMALE);\n\n        tree.addChild(9, 12);\n\n        tree.setPartner(10, 12);\n\n        tree.addPerson(13, \"Aegon\", Gender.MALE);\n        tree.addPerson(14, \"Viserys\", Gender.MALE);\n\n        tree.addChild(12, 13);\n        tree.addChild(12, 14);\n\n        tree.displayTree();\n    }\n\n    static class Person implements Comparable<Person> {\n        private Integer id;\n        private String name;\n        private Integer level;\n        private Gender gender;\n        private Person partner;\n        private Person father;\n        private Person mother;\n        private Set<Person> children;\n\n        public Person(Integer id, String name, Gender gender) {\n            this.id = id;\n            this.name = name;\n            this.level = 0;\n            this.gender = gender;\n            this.partner = null;\n            this.father = null;\n            this.mother = null;\n            children = new TreeSet<>();\n        }\n\n        public Integer getId() {\n            return id;\n        }\n\n        public void setId(Integer id) {\n            this.id = id;\n        }\n\n        public String getName() {\n            return name;\n        }\n\n        public void setName(String name) {\n            this.name = name;\n        }\n\n        public Integer getLevel() {\n            return level;\n        }\n\n        public void setLevel(Integer level) {\n            this.level = level;\n        }\n\n        public Gender getGender() {\n            return gender;\n        }\n\n        public void setGender(Gender gender) {\n            this.gender = gender;\n        }\n\n        public Person getPartner() {\n            return partner;\n        }\n\n        public void setPartner(Person partner) {\n            this.partner = partner;\n        }\n\n        public Person getFather() {\n            return father;\n        }\n\n        public void setFather(Person father) {\n            if (getFather() == null) {\n                if (father != null) {\n                    father.addChild(this);\n                    this.father = father;\n                    System.out.printf(\"A %s se le ha asignado un padre: %s.%n\", getName(), father.getName());\n                } else System.out.printf(\"%s aún no tiene asignado un padre.%n\", getName());\n            } else System.out.printf(\"%s ya tiene un padre con nombre %s.%n\", getName(), getFather().getName());\n        }\n\n        public Person getMother() {\n            return mother;\n        }\n\n        public void setMother(Person mother) {\n            if (getMother() == null) {\n                if (mother != null) {\n                    mother.addChild(this);\n                    this.mother = mother;\n                    System.out.printf(\"A %s se le ha asignado una madre: %s.%n\", getName(), mother.getName());\n                } else System.out.printf(\"%s aún no tiene asignado un padre.%n\", getName());\n            } else System.out.printf(\"%s ya tiene una madre con nombre %s.%n\", getName(), getMother().getName());\n        }\n\n        public Set<Person> getChildren() {\n            return children;\n        }\n\n        public void setChildren(Set<Person> children) {\n            this.children = children;\n        }\n\n        private void addPartner(Person partner) {\n            if (getPartner() != null) System.out.printf(\"%s ya está emparejado con %s.%n\", getName(), getPartner());\n            else if (partner.getPartner() != null) System.out.printf(\"%s ya está emparejado con %s.%n\",\n                    partner.getName(), partner.getPartner());\n            else {\n                setPartner(partner);\n                partner.setPartner(this);\n                System.out.printf(\"%s es pareja de %s.%n\", getName(), partner.getName());\n            }\n        }\n\n        private Person addChild(Person child) {\n            if (getChildren().contains(child)) {\n                if (child.getGender() == Gender.MALE)\n                    System.out.printf(\"%s ya es hijo de %s.%n\", child.getName(), getName());\n                if (child.getGender() == Gender.FEMALE)\n                    System.out.printf(\"%s ya es hija de %s.%n\", child.getName(), getName());\n            } else if (child.getFather() != null && child.getMother() != null)\n                System.out.printf(\"%s tiene como padres a: %s y %s.%n\",\n                        child.getName(), child.getFather().getName(), child.getMother().getName());\n            else {\n                getChildren().add(child);\n                if (child.getGender() == Gender.MALE)\n                    System.out.printf(\"A %s se le ha asignado un hijo: %s.%n\", getName(), child.getName());\n                if (child.getGender() == Gender.FEMALE)\n                    System.out.printf(\"A %s se le ha asignado una hija: %s.%n\", getName(), child.getName());\n                if (getGender() == Gender.MALE) {\n                    child.setFather(this);\n                    if (child.getMother() == null) child.setMother(getPartner());\n                    else System.out.printf(\"%s tiene como padres a: %s y %s.%n\",\n                            child.getName(), child.getFather().getName(), child.getMother().getName());\n                }\n                if (getGender() == Gender.FEMALE) {\n                    child.setMother(this);\n                    if (child.getFather() == null) child.setFather(getPartner());\n                    else System.out.printf(\"%s tiene como padres a: %s y %s.%n\",\n                            child.getName(), child.getFather().getName(), child.getMother().getName());\n                }\n            }\n            return this;\n        }\n\n        @Override\n        public int compareTo(Person other) {\n            return this.id.compareTo(other.id);\n        }\n    }\n\n    public enum Gender {\n        MALE(\"Hombre\"),\n        FEMALE(\"Mujer\");\n\n        private final String displayName;\n\n        // Constructor to initialize the display name\n        Gender(String displayName) {\n            this.displayName = displayName;\n        }\n\n        @Override\n        public String toString() {\n            return displayName;\n        }\n    }\n\n    static class FamilyTree {\n        private Map<Integer, Person> people;\n        private int nivel;\n\n        public FamilyTree() {\n            people = new LinkedHashMap<>();\n        }\n\n        private void addPerson(Integer id, String name, Gender gender) {\n            if (people.containsKey(id)) System.out.printf(\"La persona con ID: %d ya existe!%n\", id);\n            else {\n                Person person = new Person(id, name, gender);\n                people.put(id, person);\n                System.out.printf(\"La persona con nombre %s [ID: %d] ha sido añadida al árbol.%n\", name, id);\n            }\n        }\n\n        private void removePerson(Integer id) {\n            if (people.containsKey(id)) {\n                Person person = people.get(id);\n                people.remove(id);\n                System.out.printf(\"La persona con nombre %s [ID: %d] ha sido removida del árbol.%n\",\n                        person.getName(), id);\n            }\n        }\n\n        private void setPartner(Integer id1, Integer id2) {\n            if (people.containsKey(id1)) {\n                if (people.containsKey(id2)) people.get(id1).addPartner(people.get(id2));\n                else System.out.printf(\"El ID: %d no existe en el árbol!%n\", id2);\n            } else System.out.printf(\"El ID: %d no existe en el árbol!%n\", id1);\n        }\n\n        private void addChild(Integer parentId, Integer childId) {\n            if (parentId.equals(childId)) System.out.printf(\"Los IDs: %d y %d no pueden ser iguales!%n\",\n                    parentId, childId);\n            if (people.containsKey(parentId)) {\n                Person parent = people.get(parentId);\n                if (parent.getPartner() == null)\n                    System.out.printf(\"%s no tiene pareja. Se necesita una pareja para poder tener un hijo.%n\",\n                            parent.getName());\n                else if (people.containsKey(childId)) {\n                    parent.addChild(people.get(childId));\n                } else System.out.printf(\"El ID: %d del niño no existe en el árbol!%n\", childId);\n            } else System.out.printf(\"El ID: %d del padre/madre no existe en el árbol!%n\", parentId);\n        }\n\n        private void displayTree() {\n            Set<Integer> visited = new LinkedHashSet<>();\n            int level = 0;\n            nivel = 0;\n            people.values().forEach(person -> {\n                if (person.getFather() == null && person.getMother() == null) {\n                    displayPerson(person, level, visited);\n                }\n            });\n        }\n\n        private void displayPerson(Person person, int level, Set<Integer> visited) {\n            if (visited.contains(person.getId()) && level == person.getLevel()) return;\n            if (level == 0) {\n                System.out.println(\"-\".repeat(60));\n                System.out.printf(\"Árbol #%d:%n\", ++nivel);\n            }\n            visited.add(person.getId());\n            person.setLevel(level);\n            String indent1 = \"\\t\".repeat(level) + \"└> \";\n            String indent2 = \"\\t\".repeat(level) + \"   \";\n            System.out.printf(\"%s%s [ID: %d]%n\", indent1, person.getName(), person.getId());\n            Person partner = person.getPartner();\n            Set<Person> children = person.getChildren();\n            if (partner != null) {\n                visited.add(person.getPartner().getId());\n                System.out.printf(\"%sPareja: %s [ID: %d]%n\", indent2, partner.getName(), partner.getId());\n            }\n            if (!person.getChildren().isEmpty()) {\n                System.out.printf(\"%sHijos:%n\", indent2);\n                children.forEach(child -> {\n                    child.setLevel(level);\n                    displayPerson(child, level + 1, visited);\n                });\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #34 - JavaScript -> Jesus Antonio Escamilla */\n\n/**\n * ÁRBOL GENEALÓGICO DE LA CASA DEL DRAGÓN.\n * Utilizando la Terminal para pedir datos y agregarlos.\n */\n\nclass Persona {\n    constructor(id, name) {\n        this.id = id;\n        this.name = name;\n        this.partner = null;\n        this.children = [];\n        this.parents = [];\n    }\n}\n\nclass ArbolGenealogico {\n    constructor() {\n        this.people = new Map(); // Almacenamos personas usando un Map para un acceso rápido\n    }\n    \n    addPersona(id, name) {\n        if (this.people.has(id)) {\n            console.log(`La persona con id ${id} ya existe.`);\n            return;\n        }\n        const person = new Persona(id, name);\n        this.people.set(id, person);\n        console.log(`Persona ${name} añadida con id ${id}.`);\n    }\n    \n    removePersona(id) {\n        if (!this.people.has(id)) {\n            console.log(`La persona con id ${id} no existe.`);\n            return;\n        }\n        const person = this.people.get(id);\n        \n        // Quitar la relación de pareja\n        if (person.partner) {\n            const partner = this.people.get(person.partner);\n            partner.partner = null;\n        }\n        \n        // Quitar la relación de hijos\n        person.children.forEach(childId => {\n            const child = this.people.get(childId);\n            child.parents = child.parents.filter(parentId => parentId !== id);\n        });\n        \n        this.people.delete(id);\n        console.log(`Persona con id ${id} eliminada.`);\n    }\n    \n    assignPareja(id1, id2) {\n        if (!this.people.has(id1) || !this.people.has(id2)) {\n            console.log('Una o ambas personas no existen.');\n            return;\n        }\n        \n        const person1 = this.people.get(id1);\n        const person2 = this.people.get(id2);\n    \n        if (person1.partner || person2.partner) {\n            console.log('Una de las personas ya tiene pareja.');\n            return;\n        }\n    \n        person1.partner = id2;\n        person2.partner = id1;\n        console.log(`${person1.name} y ${person2.name} ahora son pareja.`);\n    }\n    \n    addHijo(parentId, childId) {\n        if (!this.people.has(parentId) || !this.people.has(childId)) {\n            console.log('El padre o el hijo no existen.');\n            return;\n        }\n    \n        const parent = this.people.get(parentId);\n        const child = this.people.get(childId);\n    \n        if (child.parents && child.parents.length >= 2) {\n            console.log(`${child.name} ya tiene dos padres.`);\n            return;\n        }\n    \n        parent.children.push(childId);\n        if (!child.parents) {\n            child.parents = [];\n        }\n        child.parents.push(parentId);\n        console.log(`${child.name} añadido como hijo de ${parent.name}.`);\n    }\n    \n    removeHijo(parentId, childId) {\n        if (!this.people.has(parentId) || !this.people.has(childId)) {\n            console.log('El padre o el hijo no existen.');\n            return;\n        }\n    \n        const parent = this.people.get(parentId);\n        parent.children = parent.children.filter(id => id !== childId);\n        const child = this.people.get(childId);\n        child.parents = child.parents.filter(id => id !== parentId);\n    \n        console.log(`${child.name} eliminado como hijo de ${parent.name}.`);\n    }\n\n    imprimirArbol() {\n        const visited = new Set();\n    \n        const printPerson = (person, level = 0) => {\n            if (visited.has(person.id)) {\n                return; // Evita ciclos\n            }\n\n            visited.add(person.id);\n            \n            const indent = '\\t'.repeat(level);\n            console.log(`${indent}- ${person.name} [ID: ${person.id}]`);\n            \n            if (person.partner) {\n                const partner = this.people.get(person.partner);\n                if (partner) {\n                    visited.add(partner.id);\n                    console.log(`${indent}  Pareja: ${partner.name} [ID: ${partner.id}]`);\n                }\n            }\n            \n            if (person.children.length > 0) {\n                console.log(`${indent}  Hijos:`);\n                person.children.forEach(childId => {\n                const child = this.people.get(childId);\n                if (child) {\n                    printPerson(child, level + 1);\n                }\n                });\n            }\n        };\n        \n        // Iniciar impresión para cada persona que no sea hijo (raíz)\n        this.people.forEach(person => {\n        const isChild = person.parents.length > 0;\n        if (!isChild) {\n            printPerson(person);\n        }\n        });\n    }\n\n}\n\n// Ejemplo de uso\nconst arbol = new ArbolGenealogico();\n\narbol.addPersona(1, \"Jocelyn\");\narbol.addPersona(2, \"Aemon\");\n\narbol.assignPareja(1, 2);\n\narbol.addPersona(3, \"Rhaenys\");\n\narbol.addHijo(1, 3);\n\narbol.addPersona(4, \"Corlys\");\n\narbol.assignPareja(3, 4);\n\narbol.addPersona(5, \"Laena\");\narbol.addPersona(6, \"Laenor\");\n\narbol.addHijo(3, 5);\narbol.addHijo(3, 6);\n\narbol.addPersona(7, \"Baelon\");\narbol.addPersona(8, \"Alyssa\");\n\narbol.assignPareja(7, 8);\n\narbol.addPersona(9, \"Viserys I\");\narbol.addPersona(10, \"Daemon\");\n\narbol.addHijo(7, 9);\narbol.addHijo(8, 10);\n\narbol.addPersona(11, \"Aemma\");\n\narbol.assignPareja(9, 11);\n\narbol.addPersona(12, \"Rhaenyra\");\n\narbol.addHijo(9, 12);\n\narbol.assignPareja(10, 12);\n\narbol.addPersona(13, \"Aegon\");\narbol.addPersona(14, \"Viserys\");\n\narbol.addHijo(12, 13);\narbol.addHijo(12, 14);\n\narbol.imprimirArbol();"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/javascript/Rafacv23.js",
    "content": "/* \n    Creado por Rafa Canosa\n    Github: https://github.com/Rafacv23\n    Website: https://www.rafacanosa.dev\n*/\n\nlet characters = [] // array donde vamos a ir guardando todos los personajes\n\nfunction printCharacters() {\n  if (characters.length === 0) {\n    console.log(\"No hay personajes para mostrar.\")\n    return\n  }\n\n  console.log(\"Lista de Personajes:\")\n  characters.forEach((character, index) => {\n    console.log(`\\nPersonaje ${index + 1}:`)\n    character.displayInfo()\n  })\n}\n\nclass Character {\n  constructor(name, partner = null, children = [], parents = []) {\n    this.name = name\n    this.partner = partner // Solo un partner permitido\n    this.children = children\n    this.parents = parents // Lista de padres del personaje\n    characters.push(this)\n  }\n\n  // Método para establecer un partner\n  setPartner(partner) {\n    if (partner instanceof Character) {\n      if (this.partner === null) {\n        //si es null significa que no tiene una pareja y le podemos asignar una\n        this.partner = partner\n        partner.partner = this // asignamos la pareja a ambos personajes a la vez, para no tener que llamar al método dos veces\n        console.log(`Ahora ${partner.name} y ${this.name} son pareja`)\n      } else {\n        console.error(\n          `${this.name} ya tiene una pareja, por lo tanto no le podemos asignar otra.`\n        )\n      }\n    } else {\n      console.error(\"Partner debe ser una instancia de Character.\")\n    }\n  }\n\n  // Método para agregar un child\n  addChild(child) {\n    if (child instanceof Character) {\n      if (this.children.includes(child)) {\n        console.error(`${child.name} ya es hijo de ${this.name}`)\n      } else if (child.parents.length >= 2) {\n        console.error(`${child.name} ya tiene el máximo de 2 padres`)\n      } else {\n        this.children.push(child)\n        if (!child.parents.includes(this)) {\n          child.parents.push(this)\n        }\n        console.log(`${this.name} ha añadido a ${child.name} como hijo`)\n      }\n    } else {\n      console.error(\"Child debe ser una instancia de Character.\")\n    }\n  }\n\n  // Método para mostrar la información del personaje\n  displayInfo() {\n    console.log(`Name: ${this.name}`)\n    console.log(`Partner: ${this.partner ? this.partner.name : \"Ninguno\"}`)\n    console.log(\n      `Children: ${\n        this.children.length >= 1\n          ? this.children.map((c) => c.name).join(\", \")\n          : \"Ninguno\"\n      }`\n    )\n    console.log(\n      `Parents: ${\n        this.parents.length >= 1\n          ? this.parents.map((p) => p.name).join(\", \")\n          : \"Ninguno\"\n      }`\n    )\n  }\n}\n\nconst daemon = new Character(\"Daemon Targaryen\")\nconst laena = new Character(\"Laena Velaryion\")\nconst baela = new Character(\"Baela Targaryen\")\nconst rhaena = new Character(\"Rhaena Targaryen\")\n\ndaemon.setPartner(laena)\ndaemon.addChild(baela)\ndaemon.addChild(rhaena)\nlaena.addChild(baela)\nlaena.addChild(rhaena)\n\nprintCharacters()\n"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/javascript/RaulDoezon.js",
    "content": "/*\n * EJERCICIO:\n * ¡La Casa del Dragón ha finalizado y no volverá hasta 2026! \n * ¿Alguien se entera de todas las relaciones de parentesco\n * entre personajes que aparecen en la saga?\n * Desarrolla un árbol genealógico para relacionarlos (o invéntalo).\n * Requisitos:\n * 1. Estará formado por personas con las siguientes propiedades:\n *    - Identificador único (obligatorio)\n *    - Nombre (obligatorio)\n *    - Pareja (opcional)\n *    - Hijos (opcional)\n * 2. Una persona sólo puede tener una pareja (para simplificarlo).\n * 3. Las relaciones deben validarse dentro de lo posible.\n *    Ejemplo: Un hijo no puede tener tres padres.\n * Acciones:\n * 1. Crea un programa que permita crear y modificar el árbol.\n *    - Añadir y eliminar personas\n *    - Modificar pareja e hijos\n * 2. Podrás imprimir el árbol (de la manera que consideres).\n * \n * NOTA: Ten en cuenta que la complejidad puede ser alta si\n * se implementan todas las posibles relaciones. Intenta marcar\n * tus propias reglas y límites para que te resulte asumible.\n*/\n\nclass Person {\n  constructor(id, name) {\n    this.id = id;\n    this.name = name;\n    this.partner = null;\n    this.children = [];\n    this.has_parents = false;\n  }\n\n  addPartner(partner) {\n    if (this.partner !== null) {\n      console.log(`${this.name} ya tiene pareja: ${this.partner.name}.`);\n    } else {\n      this.partner = partner;\n      partner.partner = this;\n\n      console.log(`${this.name} es pareja de ${partner.name}.`);\n    }\n  }\n\n  addChild(child) {\n    if (!this.children.includes(child)) {\n      this.children.push(child);\n\n      console.log(`${child.name} es hijo/a de ${this.name}`);\n    } else {\n      console.log(`${child.name} es hijo/a de ${this.name}.`);\n    }\n  }\n}\n\nclass FamilyTree {\n  constructor() {\n    this.people = {};\n  }\n\n  addPerson(id, name) {\n    if (id in this.people) {\n      console.log(`La persona con ID: ${id} ya existe.`);\n    } else {\n      const person = new Person(id, name);\n\n      this.people[id] = person;\n\n      console.log(`${name} (ID: ${id}) se agregó al árbol.`);\n    }\n  }\n\n  removePerson(id) {\n    if (id in this.people) {\n      const person = this.people[id];\n\n      delete this.people[id];\n\n      console.log(`${person.name} (ID: ${id}) se eliminó del árbol.`);\n    } else {\n      console.log(`La persona con ID: ${id} no existe en el árbol.`);\n    }\n  }\n\n  setPartner(id1, id2) {\n    if (id1 in this.people && id2 in this.people) {\n      const person1 = this.people[id1];\n      const person2 = this.people[id2];\n\n      person1.addPartner(person2);\n    } else {\n      console.log(\"Algún ID no existe en el árbol.\");\n    }\n  }\n\n  addChild(parent_id, child_id) {\n    if (parent_id in this.people && child_id in this.people) {\n      if (parent_id === child_id) {\n        console.log(\"Los ID no pueden ser iguales a la hora de asignar un hijo.\");\n      } else {\n        const parent = this.people[parent_id];\n\n        if (parent.partner === null) {\n          console.log(\"Se necesita una pareja para poder tener un hijo.\");\n        } else {\n          const child = this.people[child_id];\n\n          if (child.has_parents) {\n            console.log(`${child.name} (ID: ${child.id}) ya tiene padres.`);\n          } else {\n            child.has_parents = true;\n            parent.addChild(child);\n            parent.partner.addChild(child);\n          }\n        }\n      }\n    } else {\n      console.log(\"Algún ID no existe en el árbol.\");\n    }\n  }\n\n  printTree() {\n    const visited = new Set();\n    const printPerson = (person, level = 0) => {\n      if (visited.has(person.id)) {\n        return;\n      }\n\n      visited.add(person.id);\n\n      const indent = \"\\t\".repeat(level);\n\n      console.log(`${indent} - ${person.name} (ID: ${person.id})`);\n\n      if (person.partner) {\n        visited.add(person.partner.id);\n\n        console.log(`${indent}   Pareja: ${person.partner.name} (ID: ${person.partner.id})`);\n      }\n\n      if (person.children.length > 0) {\n        console.log(`${indent}   Hijos:`);\n\n        for (const child of person.children) {\n          printPerson(child, level + 1);\n        }\n      }\n    };\n\n    for (const person of Object.values(this.people)) {\n      const is_child = person.has_parents;\n\n      if (!is_child) {\n        printPerson(person);\n      }\n    }\n  }\n}\n\nlet tree = new FamilyTree();\n\ntree.addPerson(0, \"Raditz\");\ntree.addPerson(1, \"Goku\");\ntree.addPerson(2, \"Milk\");\ntree.addPerson(3, \"Gohan\");\ntree.addPerson(4, \"Goten\");\ntree.addPerson(5, \"Videl\");\ntree.addPerson(6, \"Pan\");\n\ntree.removePerson(0);\n\ntree.setPartner(1, 2);\ntree.setPartner(3, 5);\n\ntree.addChild(1, 3);\ntree.addChild(1, 4);\ntree.addChild(3, 6);\n\ntree.printTree();\n"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/javascript/RicJDev.js",
    "content": "/*\n  EJERCICIO\n  @RicJDev\n*/\n\nclass Person {\n  constructor(id, name) {\n    this.name = name\n    this.id = id\n\n    this.parents = []\n    this.children = []\n\n    this.partner = null\n  }\n\n  addChild(child) {\n    if (!this.children.includes(child)) {\n      if (child.hasParents()) {\n        console.log(\n          `${child.name} ya tiene padres: ${child.parents[0].name}, ${child.parents[1].name}.`\n        )\n      } else {\n        child.parents.push(this)\n        this.children.push(child)\n\n        console.log(`${this.name} ha tenido un hijo: ${child.name}.`)\n      }\n    } else {\n      console.log(`${child.name} ya es hijo de ${this.name}.`)\n    }\n  }\n\n  setPartner(partner) {\n    if (partner.hasPartner() || this.hasPartner()) {\n      this.hasPartner()\n        ? console.log(`${this.name} ya tiene pareja: ${this.partner.name}.`)\n        : console.log(`${partner.name} ya tiene pareja: ${partner.partner.name}.`)\n    } else {\n      this.partner = partner\n      partner.partner = this\n\n      console.log(`${this.name} ahora es pareja de ${partner.name}.`)\n    }\n  }\n\n  hasPartner() {\n    return !(this.partner === null)\n  }\n\n  hasParents() {\n    return this.parents.length === 2\n  }\n}\n\nclass FamilyTree {\n  constructor() {\n    this.people = {}\n  }\n\n  addPerson(id, name) {\n    if (this.people[id]) {\n      console.log(`El ID ${id} ya ha sido registrado.`)\n    } else {\n      this.people[id] = new Person(id, name)\n\n      console.log(`Se ha registrado a ${name} [ID: ${id}].`)\n    }\n  }\n\n  deletePerson(id) {\n    this.people[id]\n      ? delete this.people[id]\n      : console.log(`No se ha encontrado a ninguna persona con la ID: ${id || 0}.`)\n  }\n\n  setPartner(id1, id2) {\n    const person1 = this.people[id1]\n    const person2 = this.people[id2]\n\n    person1 && person2\n      ? person1.setPartner(person2)\n      : console.log(`Una de las ID's no coincide con ningún registro: ${id1 || 0}, ${id2 || 0}`)\n  }\n\n  addChild(id, childId) {\n    const parent = this.people[id]\n    const child = this.people[childId]\n\n    if (parent && child) {\n      parent.addChild(child)\n\n      if (parent.hasPartner()) {\n        parent.partner.addChild(child)\n      }\n    } else {\n      console.log(`Una de las ID's no coincide con ningún registro: ${id || 0}, ${childId || 0}`)\n    }\n  }\n\n  displayTree() {\n    const visited = new Set()\n\n    function printPerson(person, level) {\n      if (visited.has(person.id)) return\n      visited.add(person.id)\n\n      let ident = ' '.repeat(level * 4)\n\n      console.log(`${ident} - ${person.name} [ID: ${person.id}]`)\n\n      if (person.partner) {\n        visited.add(person.partner.id)\n\n        console.log(`${ident}   Pareja: ${person.partner.name} [ID: ${person.id}]`)\n      }\n\n      if (person.children.length > 0) {\n        console.log(`${ident}   Hijos:`)\n        person.children.forEach((child) => {\n          printPerson(child, level + 1)\n        })\n      }\n    }\n\n    const rootPersons = Object.values(this.people).filter((person) => {\n      return person.parents.length === 0\n    })\n\n    rootPersons.forEach((root) => printPerson(root, 0))\n  }\n}\n\nconst tree = new FamilyTree()\n\ntree.addPerson(1, 'Aegon I Targaryen')\ntree.addPerson(2, 'Rhaenys Targaryen')\ntree.addPerson(3, 'Visenya Targaryen')\n\ntree.addPerson(4, 'Aenys I Targaryen')\ntree.addPerson(5, 'Maegor I Targaryen')\n\ntree.addPerson(6, 'Jaehaerys I Targaryen')\ntree.addPerson(7, 'Alysanne Targaryen')\n\ntree.addPerson(8, 'Aegon II Targaryen')\ntree.addPerson(9, 'Helaena Targaryen')\n\ntree.addPerson(10, 'Viserys II Targaryen')\n\ntree.addPerson(11, 'Rhaenyra Targaryen')\ntree.addPerson(12, 'Daemon Targaryen')\n\ntree.setPartner(1, 2)\ntree.setPartner(1, 3)\ntree.setPartner(4, 7)\ntree.setPartner(8, 9)\ntree.setPartner(11, 12)\n\ntree.addChild(1, 4)\ntree.addChild(1, 5)\n\ntree.addChild(4, 6)\ntree.addChild(4, 11)\n\ntree.addChild(6, 8)\ntree.addChild(6, 10)\n\nconsole.log(' ')\ntree.displayTree()\n"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/javascript/adrs1166ma.js",
    "content": "/*\nEJERCICIO:\n¡La Casa del Dragón ha finalizado y no volverá hasta 2026!\n¿Alguien se entera de todas las relaciones de parentesco\nentre personajes que aparecen en la saga?\nDesarrolla un árbol genealógico para relacionarlos (o invéntalo).\nRequisitos:\n1. Estará formado por personas con las siguientes propiedades:\n- Identificador único (obligatorio)\n- Nombre (obligatorio)\n- Pareja (opcional)\n- Hijos (opcional)\n2. Una persona sólo puede tener una pareja (para simplificarlo).\n3. Las relaciones deben validarse dentro de lo posible.\nEjemplo: Un hijo no puede tener tres padres.\nAcciones:\n1. Crea un programa que permita crear y modificar el árbol.\n- Añadir y eliminar personas\n- Modificar pareja e hijos\n2. Podrás imprimir el árbol (de la manera que consideres).\n\nNOTA: Ten en cuenta que la complejidad puede ser alta si\nse implementan todas las posibles relaciones. Intenta marcar\ntus propias reglas y límites para que te resulte asumible.\n*/\n// 🔥 SIMULADOR: ÁRBOL GENEALÓGICO DE LA CASA DEL DRAGÓN 🔥\nconsole.log(\"🐉 ¡Bienvenido al árbol genealógico de La Casa del Dragón! 🐉\");\n// Base de datos para almacenar personas\nconst personas = {};\n\n// Función principal del programa\nfunction iniciarPrograma() {\n    let continuar = true;\n\n    while (continuar) {\n        console.log(\"\\n--- MENÚ PRINCIPAL ---\");\n        console.log(\"1. Añadir persona.\");\n        console.log(\"2. Modificar pareja.\");\n        console.log(\"3. Modificar hijos.\");\n        console.log(\"4. Eliminar persona.\");\n        console.log(\"5. Mostrar árbol genealógico.\");\n        console.log(\"6. Salir del programa.\");\n\n        const opcion = prompt(\"Seleccione una opción (1-6): \");\n\n        switch (opcion) {\n            case \"1\":\n                añadirPersona();\n                break;\n            case \"2\":\n                modificarPareja();\n                break;\n            case \"3\":\n                modificarHijos();\n                break;\n            case \"4\":\n                eliminarPersona();\n                break;\n            case \"5\":\n                mostrarArbolGenealogico();\n                break;\n            case \"6\":\n                console.log(\"👋 ¡Gracias por usar el simulador del árbol genealógico! 👋\");\n                continuar = false;\n                break;\n            default:\n                console.log(\"❌ Opción no válida. Intente de nuevo.\");\n        }\n    }\n}\n\n// 1. Añadir persona\nfunction añadirPersona() {\n    const id = prompt(\"Ingrese un identificador único para la persona: \");\n    if (personas[id]) {\n        console.log(\"❌ Ya existe una persona con ese identificador.\");\n        return;\n    }\n\n    const nombre = prompt(\"Ingrese el nombre de la persona: \");\n    if (!nombre) {\n        console.log(\"❌ El nombre es obligatorio.\");\n        return;\n    }\n\n    personas[id] = { id, nombre, pareja: null, hijos: [] };\n    console.log(`✅ Persona \"${nombre}\" añadida con ID ${id}.`);\n}\n\n// 2. Modificar pareja\nfunction modificarPareja() {\n    const id = prompt(\"Ingrese el ID de la persona cuya pareja desea modificar: \");\n    const persona = personas[id];\n    if (!persona) {\n        console.log(\"❌ No se encontró ninguna persona con ese ID.\");\n        return;\n    }\n\n    const idPareja = prompt(\"Ingrese el ID de la nueva pareja (o 'null' para eliminar pareja): \");\n    if (idPareja === \"null\") {\n        // Eliminar pareja actual\n        if (persona.pareja) {\n            const parejaActual = personas[persona.pareja];\n            if (parejaActual) parejaActual.pareja = null; // Actualizar pareja de la otra persona\n        }\n        persona.pareja = null;\n        console.log(`✅ Pareja eliminada para \"${persona.nombre}\".`);\n        return;\n    }\n\n    const pareja = personas[idPareja];\n    if (!pareja) {\n        console.log(\"❌ No se encontró ninguna persona con ese ID de pareja.\");\n        return;\n    }\n\n    // Validar que la pareja no tenga ya otra pareja\n    if (pareja.pareja && pareja.pareja !== id) {\n        console.log(`❌ ${pareja.nombre} ya tiene una pareja asignada.`);\n        return;\n    }\n\n    // Actualizar relaciones\n    if (persona.pareja) {\n        const parejaAnterior = personas[persona.pareja];\n        if (parejaAnterior) parejaAnterior.pareja = null; // Desvincular pareja anterior\n    }\n    persona.pareja = idPareja;\n    pareja.pareja = id;\n\n    console.log(`✅ ${persona.nombre} ahora está vinculado/a con ${pareja.nombre}.`);\n}\n\n// 3. Modificar hijos\nfunction modificarHijos() {\n    const idPadre = prompt(\"Ingrese el ID del padre/madre: \");\n    const padre = personas[idPadre];\n    if (!padre) {\n        console.log(\"❌ No se encontró ninguna persona con ese ID.\");\n        return;\n    }\n\n    const accion = prompt(\"¿Desea añadir o eliminar un hijo? (añadir/eliminar): \").toLowerCase();\n    if (![\"añadir\", \"eliminar\"].includes(accion)) {\n        console.log(\"❌ Acción no válida.\");\n        return;\n    }\n\n    const idHijo = prompt(\"Ingrese el ID del hijo: \");\n    const hijo = personas[idHijo];\n    if (!hijo) {\n        console.log(\"❌ No se encontró ninguna persona con ese ID de hijo.\");\n        return;\n    }\n\n    if (accion === \"añadir\") {\n        // Validar que el hijo no tenga más de dos padres\n        const padresActuales = Object.values(personas).filter(p => p.hijos.includes(idHijo));\n        if (padresActuales.length >= 2) {\n            console.log(\"❌ Este hijo ya tiene dos padres asignados.\");\n            return;\n        }\n\n        padre.hijos.push(idHijo);\n        console.log(`✅ ${hijo.nombre} añadido como hijo de ${padre.nombre}.`);\n    } else if (accion === \"eliminar\") {\n        const index = padre.hijos.indexOf(idHijo);\n        if (index === -1) {\n            console.log(\"❌ Este hijo no está registrado como hijo de esta persona.\");\n            return;\n        }\n\n        padre.hijos.splice(index, 1);\n        console.log(`✅ ${hijo.nombre} eliminado como hijo de ${padre.nombre}.`);\n    }\n}\n\n// 4. Eliminar persona\nfunction eliminarPersona() {\n    const id = prompt(\"Ingrese el ID de la persona que desea eliminar: \");\n    const persona = personas[id];\n    if (!persona) {\n        console.log(\"❌ No se encontró ninguna persona con ese ID.\");\n        return;\n    }\n\n    // Eliminar referencias de pareja e hijos\n    if (persona.pareja) {\n        const pareja = personas[persona.pareja];\n        if (pareja) pareja.pareja = null;\n    }\n\n    for (const p of Object.values(personas)) {\n        const index = p.hijos.indexOf(id);\n        if (index !== -1) p.hijos.splice(index, 1);\n    }\n\n    delete personas[id];\n    console.log(`✅ Persona \"${persona.nombre}\" eliminada.`);\n}\n\n// 5. Mostrar árbol genealógico\nfunction mostrarArbolGenealogico() {\n    console.log(\"\\n--- ÁRBOL GENEALÓGICO ---\");\n    for (const persona of Object.values(personas)) {\n        console.log(`ID: ${persona.id}, Nombre: ${persona.nombre}`);\n        if (persona.pareja) {\n            const pareja = personas[persona.pareja];\n            console.log(`   Pareja: ${pareja ? pareja.nombre : \"Sin pareja\"}`);\n        } else {\n            console.log(\"   Pareja: Sin pareja\");\n        }\n\n        if (persona.hijos.length > 0) {\n            const nombresHijos = persona.hijos.map(idHijo => personas[idHijo]?.nombre || \"Desconocido\");\n            console.log(`   Hijos: ${nombresHijos.join(\", \")}`);\n        } else {\n            console.log(\"   Hijos: Ninguno\");\n        }\n    }\n}\n\niniciarPrograma();"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/javascript/duendeintemporal.js",
    "content": "//#34 - ARBOL GENEALÓGICO DE LA CASA DEL DRAGÓN:\n/*\n * EJERCICIO:\n * ¡La Casa del Dragón ha finalizado y no volverá hasta 2026!\n * ¿Alguien se entera de todas las relaciones de parentesco\n * entre personajes que aparecen en la saga?\n * Desarrolla un árbol genealógico para relacionarlos (o invéntalo).\n * Requisitos:\n * 1. Estará formado por personas con las siguientes propiedades:\n *    - Identificador único (obligatorio)\n *    - Nombre (obligatorio)\n *    - Pareja (opcional)\n *    - Hijos (opcional)\n * 2. Una persona sólo puede tener una pareja (para simplificarlo).\n * 3. Las relaciones deben validarse dentro de lo posible.\n *    Ejemplo: Un hijo no puede tener tres padres.\n * Acciones:\n * 1. Crea un programa que permita crear y modificar el árbol.\n *    - Añadir y eliminar personas\n *    - Modificar pareja e hijo\n * 2. Podrás imprimir el árbol (de la manera que consideres).\n * \n * NOTA: Ten en cuenta que la complejidad puede ser alta si\n * se implementan todas las posibles relaciones. Intenta marcar\n * tus propias reglas y límites para que te resulte asumible.\n */\n\n/*          Arbol Genealógico\n\nRey Viserys I Targaryen:\n    Título: Rey de los Siete Reinos.\n    Esposas:\n        Aemma Arryn (madre de Rhaenyra y Aegon II).\n        Alicent Hightower (madre de Aegon III, Aemond y otros).\n    Hijos:\n        Con Aemma Arryn:\n            Rhaenyra Targaryen (heredera al trono).\n            Aegon II Targaryen (rival de Rhaenyra).\n        Con Alicent Hightower:\n            Aegon III Targaryen.\n            Aemond Targaryen.\n        Otros hijos (como Daeron Targaryen).\nRhaenyra Targaryen:\n    Título: Princesa de Dragonstone, heredera al trono.\n    Esposo: Laenor Velaryon (hijo de Corlys Velaryon y Rhaenys Targaryen).\n    Hijos: Joffrey Velaryon. Lucerys Velaryon. Jorah Velaryon.\nAegon II Targaryen:\n    Título: Rey de los Siete Reinos (rival de Rhaenyra).\n    Hijos: No se menciona que Aegon II tenga hijos legítimos en la serie.\nAlicent Hightower:\n    Título: Reina consorte.\n    Hijos: Aegon III Targaryen. Aemond Targaryen. Daeron Targaryen (en algunas versiones de la historia).\n    Familia: Proviene de la influyente Casa Hightower, que juega un papel importante en la política de Westeros.\nAemond Targaryen:\n    Título: Príncipe de la Casa Targaryen.\n    Hermanos: Aegon III y Daeron Targaryen.\nLaenor Velaryon:\n    Título: Príncipe de la Casa Velaryon.\n    Esposa: Rhaenyra Targaryen.\n    Hijos: Joffrey, Lucerys y Jorah Velaryon (aunque su paternidad es cuestionada). */\n\n    let log = console.log;\n\n    window.addEventListener('load', ()=>{\n        const body = document.querySelector('body');\n        const title = document.createElement('h1');\n        \n        body.style.setProperty('background', '#000');\n        body.style.setProperty('text-align', 'center');\n        \n        title.textContent = 'Retosparaprogramadores #34.';\n        title.style.setProperty('font-size', '3.5vmax');\n        title.style.setProperty('color', '#fff');\n        title.style.setProperty('line-height', '100vh');\n        \n        body.appendChild(title);\n        \n        setTimeout(()=>{\n        alert('Retosparaprogramadores #34. Please open the Browser Developer Tools.');\n        }, 2000);\n        log( 'Retosparaprogramadores #34'); \n    });\n    \n\n    class Person {\n        constructor(id, name, mother = '', father = '', partners = [], childrens = []) {\n            this.id = id;\n            this.name = name;\n            this.mother = mother;\n            this.father = father;\n            this.partners = this.setPartners(partners);\n            this.childrens = this.setChildrens(childrens);\n        }\n    \n        setPartners(partners) {\n            if (!partners) {\n                log('You have to give a valid name string or array');\n                return [];\n            }\n            if (Array.isArray(partners)) {\n                return [...partners];\n            } else {\n                return [partners];\n            }\n        }\n    \n        setChildrens(childrens) {\n            if (!childrens) {\n                log('You have to give a valid name string or array');\n                return [];\n            }\n            if (Array.isArray(childrens)) {\n                return [...childrens];\n            } else {\n                return [childrens];\n            }\n        }\n    \n        getPartners() {\n            return this.partners.length > 0 ? this.partners : `there's no partners for ${this.name}`;\n        }\n    \n        getChildrens() {\n            return this.childrens.length > 0 ? this.childrens : `there's no childrens for ${this.name}`;\n        }\n    }\n    \n    class GenealogyTree {\n        constructor(persons = []) {\n            this.persons = persons;\n        }\n    \n        addPerson(person) {\n            if (this.persons.some(p => p.id === person.id)) {\n                log(`The ${person.name} is already added`);\n                return;\n            }\n            this.persons.push(person);\n        }\n    \n        deletePerson(personId) {\n            const index = this.persons.findIndex(p => p.id === personId);\n            if (index === -1) {\n                log(`The person with id ${personId} isn't already added`);\n                return;\n            }\n            this.persons.splice(index, 1);\n        }\n    \n        showTree() {\n            this.persons.forEach(p => {\n                log(`ID: ${p.id}, Name: ${p.name}, Mother: ${p.mother}, Father: ${p.father}, Partners: ${p.getPartners()}, Childrens: ${p.getChildrens()}`);\n            });\n        }\n    }\n    \n    const king = new Person(1, 'Rey Viserys I Targaryen', '', '', ['Aemma Arryn', 'Alicent Hightower'], ['Rhaenyra Targaryen', 'Aegon II Targaryen', 'Aegon III Targaryen', 'Aemond Targaryen', 'Daeron Targaryen']);\n    const princess = new Person(2, 'Rhaenyra Targaryen', 'Aemma Arryn', 'Rey Viserys I Targaryen', ['Laenor Velaryon'], ['Joffrey Velaryon', 'Lucerys Velaryon', 'Jorah Velaryon']);\n    const kingAegonII = new Person(3, 'Aegon II Targaryen', 'Aemma Arryn', 'Rey Viserys I Targaryen');\n    const queen = new Person(4, 'Alicent Hightower', '', '', ['Rey Viserys I Targaryen'], ['Aegon III Targaryen', 'Aemond Targaryen', 'Daeron Targaryen']);\n    const princeAemond = new Person(5, 'Aemond Targaryen', '', '', [], []);\n    const princeLaenor = new Person(6, 'Laenor Velaryon', '', '', ['Rhaenyra Targaryen'], ['Joffrey Velaryon', 'Lucerys Velaryon', 'Jorah Velaryon']);\n    \n    const dragonHouseTree = new GenealogyTree([king, princess, kingAegonII, queen, princeAemond, princeLaenor]);\n    \n    dragonHouseTree.showTree();\n    "
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/javascript/hectorio23.js",
    "content": "// Autor: Héctor Adán \n// GitHub: https://github.com/hectorio23\n\nclass Person {\n    constructor(id, name, partner = null) {\n        this.id = id;  // Unique identifier\n        this.name = name;  // Person's name\n        this.partner = partner;  // Optional partner\n        this.children = [];  // List of children\n    }\n\n    addChild(child) {\n        if (this.getParents(child).length < 2) {\n            this.children.push(child);\n        } else {\n            throw new Error(`${child.name} already has two parents.`);\n        }\n    }\n\n    setPartner(partner) {\n        if (!this.partner) {\n            this.partner = partner;\n            partner.partner = this;  // Mutual partnership\n        } else {\n            throw new Error(`${this.name} already has a partner.`);\n        }\n    }\n\n    getParents(person) {\n        // Find parents by checking who has this person as a child\n        return Person.allInstances.filter(p => p.children.includes(person));\n    }\n\n    static displayTree(person, level = 0) {\n        if (person.partner ) {\n            console.log(\"  \".repeat(level) + person.partner.name);\n        }\n        console.log(\"  \".repeat(level) + person.name);\n        person.children.forEach(child => {\n            Person.displayTree(child, level + 1);\n        });\n    }\n}\n\n// Keep track of all instances\nPerson.allInstances = [];\n\n// Sample usage\nconst alice = new Person(1, \"Andrea\");\nPerson.allInstances.push(alice);\nconst bob = new Person(2, \"Adan\");\nPerson.allInstances.push(bob);\nalice.setPartner(bob);\nconst charlie = new Person(3, \"Alejandro\");\nPerson.allInstances.push(charlie);\nalice.addChild(charlie);\nPerson.displayTree(alice);\n\n"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n_______________________________________________________\n#34 ÁRBOL GENEALÓGICO DE LA CASA DEL DRAGÓN\n-------------------------------------------------------\n#  * ¡La Casa del Dragón ha finalizado y no volverá hasta 2026!\n#  * ¿Alguien se entera de todas las relaciones de parentesco\n#  * entre personajes que aparecen en la saga?\n#  * Desarrolla un árbol genealógico para relacionarlos (o invéntalo).\n#  * Requisitos:\n#  * 1. Estará formado por personas con las siguientes propiedades:\n#  *    - id_entificador único (obligatorio)\n#  *    - Nombre (obligatorio)\n#  *    - Pareja (opcional)\n#  *    - Hijos (opcional)\n#  * 2. Una persona sólo puede tener una pareja (para simplificarlo).\n#  * 3. Las relaciones deben valid_arse dentro de lo posible.\n#  *    Ejemplo: Un hijo no puede tener tres padres.\n#  * Acciones:\n#  * 1. Crea un programa que permita crear y modificar el árbol.\n#  *    - Añadir y eliminar personas\n#  *    - Modificar pareja e hijos\n#  * 2. Podrás imprimir el árbol (de la manera que consid_eres).\n#  *\n#  * NOTA: Ten en cuenta que la complejidad puede ser alta si\n#  * se implementan todas las posibles relaciones. Intenta marcar\n#  * tus propias reglas y límites para que te resulte asumible.\n\n*/\n// ________________________________________________________\n// NOTE: Here is the 'people.json' file with the data if you want to test it:\n//       https://pastebin.com/29kWWgPU\n//       Just paste it into the base folder where file.py is located.\n\nconst readline = require('readline');\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nclass Input {\n    async inputStr(msg) {\n        while (true) {\n            const txt = await new Promise((resolve) => {\n                rl.question(msg, (answer) => {\n                    resolve(answer.trim());\n                });\n            });\n\n            if (txt.length > 0) {\n                return txt;\n            }\n            console.log(\"\\n❌ This field cannot be empty.\");\n        }\n    }\n\n    async inputInt(msg) {\n        while (true) {\n            const txt = await this.inputStr(msg);\n            if (/^\\d+$/.test(txt)) {\n                return parseInt(txt);\n            }\n            console.log(\"\\n❌ Enter an integer.\");\n        }\n    }\n}\n\nclass Person {\n    constructor(id, name) {\n        this.id = id;\n        this.name = name;\n        this.parents = [];\n        this.partners = [];\n        this.children = {};\n        this.deleted = false;\n    }\n\n    toJSON() {\n        return {\n            id: this.id,\n            name: this.name,\n            parents: this.parents,\n            partners: this.partners,\n            children: this.children,\n            deleted: this.deleted\n        };\n    }\n\n    static fromJSON(data) {\n        const person = new Person(data.id, data.name);\n        person.parents = data.parents || [];\n        person.partners = data.partners || [];\n        person.children = Object.fromEntries(\n            Object.entries(data.children || {}).map(([k, v]) => [parseInt(k), v])\n        );\n        person.deleted = data.deleted || false;\n        return person;\n    }\n\n    toString() {\n        return `Person(id=${this.id}, name='${this.name}')`;\n    }\n}\n\nclass People extends Input {\n    constructor(filename = \"people.json\") {\n        super();\n        this._people = [];\n        this._filename = filename;\n        this.loadFromJSON();\n    }\n\n    getPeople() {\n        return this._people;\n    }\n\n    async loadFromJSON() {\n        try {\n            const fs = require('fs');\n            const data = JSON.parse(fs.readFileSync(this._filename, 'utf8'));\n            this._people = data.map(personData => Person.fromJSON(personData));\n            console.log(`✅ The file '${this._filename}' has been successfully loaded.`);\n        } catch (error) {\n            console.log(`⚠️ The file '${this._filename}' not found. Starting with an empty list.`);\n            this._people = [new Person(0, \"unknown\")];\n        }\n    }\n\n    async saveToJSON() {\n        try {\n            const fs = require('fs');\n            const data = this._people.map(person => person.toJSON());\n            fs.writeFileSync(this._filename, JSON.stringify(data, null, 2));\n            console.log(`✅ Data saved successfully to ${this._filename}`);\n        } catch (error) {\n            console.log(`❌ An error occurred while saving to '${this._filename}': ${error}. Data may not have been saved.`);\n        }\n    }\n\n    printPeople() {\n        console.log(\"_\".repeat(32));\n        console.log(`|${this.centerText(\"id\", 4)}|${this.centerText(\"Name\", 25)}|`);\n        console.log(\"_\".repeat(32));\n\n        this._people.forEach(person => {\n            if (!person.deleted) {\n                console.log(`|${this.centerText(String(person.id), 4)}|${this.centerText(person.name, 25)}|`);\n            }\n        });\n\n        console.log(\"_\".repeat(32));\n    }\n\n    centerText(text, width) {\n        const padding = width - text.length;\n        const leftPad = Math.floor(padding / 2);\n        const rightPad = padding - leftPad;\n        return \" \".repeat(leftPad) + text + \" \".repeat(rightPad);\n    }\n\n    getPersonById(id) {\n        if (id >= 0 && id < this._people.length) {\n            return this._people[id];\n        }\n        console.log(\"❌ id not found.\");\n        return null;\n    }\n\n    async addPerson() {\n        console.log(\"Add Person or 'x' to Exit\");\n        const name = await this.inputStr(\"Name: \");\n        if (name.toLowerCase() === \"x\") {\n            console.log(\"Exit\");\n            return;\n        }\n\n        const newId = Math.max(-1, ...this._people.map(p => p.id)) + 1;\n        const newPerson = new Person(newId, name);\n        this._people.push(newPerson);\n        console.log(`✅ Added: ${newPerson}`);\n        await this.saveToJSON();\n    }\n\n    async removePerson() {\n        this.printPeople();\n        console.log(\"\\nPerson ID to mark as deleted or a letter to exit.\");\n        const idStr = await this.inputStr(\"ID: \");\n        if (!/^\\d+$/.test(idStr)) {\n            console.log(\"Exit\");\n            return;\n        }\n\n        const person = this.getPersonById(parseInt(idStr));\n        if (!person) return;\n\n        if (person.partners.length || person.parents.length) {\n            console.log(\"❌ You cannot delete a person who is linked to parents or partners.\");\n            return;\n        }\n\n        person.deleted = true;\n        console.log(`✅ '${person.name}' is marked as deleted.`);\n        await this.saveToJSON();\n    }\n\n    get length() {\n        return this._people.length;\n    }\n}\n\nclass Partners extends People {\n    async #add(partners, idPerson) {\n        console.log(\"Select Partner ID\");\n        const idPartner = await this.inputInt(\"ID: \");\n        const partner = this.getPersonById(idPartner);\n        if (!partner || partner.deleted) {\n            console.log(\"❌ ID not found or the person is deleted.\");\n            return;\n        }\n\n        if (partners.includes(idPartner)) {\n            console.log(\"❌ This partner is already added.\");\n            return;\n        }\n\n        partners.push(idPartner);\n        partner.partners.push(idPerson);\n\n        console.log(\"✅ Partner successfully added.\");\n        await this.saveToJSON();\n    }\n\n    async #remove(partners, idPerson) {\n        console.log(\"Select Partner ID to Delete\");\n        const id = await this.inputInt(\"ID: \");\n        if (!partners.includes(id)) {\n            console.log(\"❌ ID not found.\");\n            return;\n        }\n\n        const partner = this.getPersonById(id);\n        if (!partner) {\n            console.log(\"❌ Partner not found.\");\n            return;\n        }\n\n        if (Object.keys(partner.children).length > 0) {\n            console.log(\"❌ Cannot delete a partner who has children.\");\n            return;\n        }\n\n        partners.splice(partners.indexOf(id), 1);\n        partner.partners.splice(partner.partners.indexOf(idPerson), 1);\n\n        console.log(\"✅ Partner deleted\");\n        await this.saveToJSON();\n    }\n\n    async #options(partners, idPerson) {\n        console.log(\"\\n1. Add partner | 2. Remove partner | 3. Exit\");\n        const option = await this.inputInt(\"\\nOption: \");\n\n        switch (option) {\n            case 1:\n                await this.#add(partners, idPerson);\n                break;\n            case 2:\n                await this.#remove(partners, idPerson);\n                break;\n            case 3:\n                return;\n            default:\n                console.log(\"❌ Invalid option.\");\n        }\n    }\n\n    async editPartners() {\n        this.printPeople();\n        console.log(\"\\nPerson ID to edit partners or a letter to exit.\");\n        const idStr = await this.inputStr(\"ID: \");\n        if (!/^\\d+$/.test(idStr)) {\n            console.log(\"Exit\");\n            return;\n        }\n\n        const id = parseInt(idStr);\n        const person = this.getPersonById(id);\n        if (!person || person.deleted) {\n            console.log(\"❌ ID not found or the person is deleted.\");\n            return;\n        }\n\n        console.log(`You selected '${person.name}'`);\n        const partners = person.partners;\n\n        if (partners.length > 0) {\n            console.log(\"Partners:\");\n            partners.forEach(idP => {\n                const partner = this.getPersonById(idP);\n                if (partner) {\n                    console.log(`ID: ${partner.id} -> ${partner.name}`);\n                }\n            });\n        } else {\n            console.log(\"🚫 This person has no partners.\");\n        }\n\n        await this.#options(partners, id);\n    }\n}\n\nclass Children extends Partners {\n    constructor(filename = \"people.json\") {\n        super(filename);\n        this._idParent = null;\n        this._children = {};\n        this._idChild = null;\n        this._parents = null;\n        this._idPartner = null;\n    }\n\n    async #selectPartner(partners) {\n        console.log(\"Partners:\");\n        partners.forEach(idP => {\n            const partner = this.getPersonById(idP);\n            if (partner) {\n                console.log(`ID: ${partner.id} -> ${partner.name}`);\n            }\n        });\n\n        console.log(\"Select the ID of the partner with whom you have the child.\");\n        const idPartner = await this.inputInt(\"ID: \");\n        const partner = this.getPersonById(idPartner);\n        if (!partners.includes(idPartner) || !partner || partner.deleted) {\n            console.log(\"❌ ID not found or the person is deleted.\");\n            return null;\n        }\n\n        return idPartner;\n    }\n\n    async #updateChildParent() {\n        console.log(\"Select Child ID\");\n        const idChild = await this.inputInt(\"ID: \");\n        const child = this.getPersonById(idChild);\n        if (!child) {\n            console.log(\"❌ ID not found.\");\n            return null;\n        }\n\n        if (child.parents.length) {\n            console.log(\"❌ This person already has parents.\");\n            return null;\n        }\n\n        const idPartner = this._idPartner;\n        if (this._children[idPartner]) {\n            if (!this._children[idPartner].includes(idChild)) {\n                this._children[idPartner].push(idChild);\n            }\n        } else {\n            this._children[idPartner] = [idChild];\n        }\n\n        const parent = this.getPersonById(this._idParent);\n        if (parent) {\n            parent.children = this._children;\n        }\n\n        child.parents = [this._idParent, idPartner];\n\n        return idChild;\n    }\n\n    #updateChildPartner(partner) {\n        if (this._idParent in partner.children) {\n            if (!partner.children[this._idParent].includes(this._idChild)) {\n                partner.children[this._idParent].push(this._idChild);\n            }\n        } else {\n            partner.children[this._idParent] = [this._idChild];\n        }\n    }\n\n    async #add() {\n        const parent = this.getPersonById(this._idParent);\n        if (!parent) {\n            console.log(\"❌ Parent not found.\");\n            return;\n        }\n\n        const partners = parent.partners;\n        if (!partners.length) {\n            console.log(\"❌ This person does not have a partner with whom to have children.\");\n            return;\n        }\n\n        const idPartner = await this.#selectPartner(partners);\n        if (!idPartner) return;\n\n        const partner = this.getPersonById(idPartner);\n        if (!partner) {\n            console.log(\"❌ Partner not found.\");\n            return;\n        }\n\n        this._idPartner = idPartner;\n        const idChild = await this.#updateChildParent();\n        if (idChild === null) return;\n\n        this._idChild = idChild;\n        this.#updateChildPartner(partner);\n\n        console.log(\"✅ Child successfully added.\");\n        await this.saveToJSON();\n    }\n\n    async #removeAndUpdate(idParent, idPartner) {\n        const parent = this.getPersonById(idParent);\n        if (!parent) {\n            console.log(\"❌ Parent not found.\");\n            return;\n        }\n\n        const childrenWithPartner = parent.children[idPartner] || [];\n        if (childrenWithPartner.includes(this._idChild)) {\n            const index = childrenWithPartner.indexOf(this._idChild);\n            childrenWithPartner.splice(index, 1);\n            if (childrenWithPartner.length === 0) {\n                delete parent.children[idPartner];\n            } else {\n                parent.children[idPartner] = childrenWithPartner;\n            }\n        }\n\n        const child = this.getPersonById(this._idChild);\n        if (child) {\n            const index = child.parents.indexOf(idParent);\n            if (index !== -1) {\n                child.parents.splice(index, 1);\n            }\n        }\n    }\n\n    async #remove() {\n        console.log(\"Select Child ID to Delete\");\n        const idChild = await this.inputInt(\"ID: \");\n        const child = this.getPersonById(idChild);\n        if (!child) {\n            console.log(\"❌ Child not found.\");\n            return;\n        }\n\n        const parents = child.parents;\n        if (parents.length !== 2) {\n            console.log(\"❌ Child does not have two parents.\");\n            return;\n        }\n\n        this._idChild = idChild;\n        this._parents = parents;\n        const [idP1, idP2] = parents;\n        await this.#removeAndUpdate(idP1, idP2);\n        await this.#removeAndUpdate(idP2, idP1);\n\n        console.log(\"✅ Child deleted\");\n        await this.saveToJSON();\n    }\n\n    async #options() {\n        console.log(\"\\n1. Add child | 2. Remove child | 3. Exit\");\n        const option = await this.inputInt(\"\\nOption: \");\n\n        switch (option) {\n            case 1:\n                await this.#add();\n                break;\n            case 2:\n                await this.#remove();\n                break;\n            case 3:\n                return;\n            default:\n                console.log(\"❌ Invalid option.\");\n        }\n    }\n\n    async editChildren() {\n        this.printPeople();\n        console.log(\"\\nPerson ID to edit Children or a letter to exit.\");\n        const idStr = await this.inputStr(\"ID: \");\n        if (!/^\\d+$/.test(idStr)) {\n            console.log(\"Exit\");\n            return;\n        }\n\n        const id = parseInt(idStr);\n        const parent = this.getPersonById(id);\n        if (!parent || parent.deleted) {\n            console.log(\"❌ ID not found or the person is deleted.\");\n            return;\n        }\n\n        console.log(`You selected '${parent.name}'`);\n        const children = parent.children;\n        if (Object.keys(children).length > 0) {\n            console.log(\"Children:\");\n            for (const [partnerId, childIds] of Object.entries(children)) {\n                const partner = this.getPersonById(parseInt(partnerId));\n                const partnerName = partner ? partner.name : \"Unknown\";\n                console.log(`With ID: ${partnerId} -> '${partnerName}':`);\n                childIds.forEach(childId => {\n                    const child = this.getPersonById(childId);\n                    const childName = child ? child.name : \"Unknown\";\n                    console.log(`    ID: ${childId} -> '${childName}'`);\n                });\n            }\n        } else {\n            console.log(\"🚫 This person has no children.\");\n        }\n\n        this._idParent = id;\n        this._children = children;\n        await this.#options();\n    }\n}\n\nclass Tree extends Children {\n    #filteredGrandparents() {\n        const grandparents = [];\n        const noPartner = [];\n\n        for (const person of this.getPeople()) {\n            if (\n                !person.parents.length &&\n                !person.deleted &&\n                person.name !== \"unknown\"\n            ) {\n                const partners = person.partners;\n                if (!partners.length) {\n                    noPartner.push(person);\n                    continue;\n                }\n\n                let hasGrandparentPartner = false;\n                for (const partnerId of partners) {\n                    const partner = this.getPersonById(partnerId);\n                    if (partner && grandparents.includes(partner)) {\n                        hasGrandparentPartner = true;\n                        break;\n                    }\n                }\n\n                if (!hasGrandparentPartner) {\n                    grandparents.push(person);\n                }\n            }\n        }\n\n        return [grandparents, noPartner];\n    }\n\n    #printChild(children, px, isLast, isRoot) {\n        children.forEach((childId, j) => {\n            const isLastChild = j === children.length - 1;\n            let newPrefix = px;\n            if (!isRoot) {\n                newPrefix = px.slice(0, -4) + (isLast ? \"    \" : \"│   \");\n            }\n\n            this.#printFamily(\n                childId,\n                newPrefix + (isLastChild ? \"└── \" : \"├── \"),\n                isLastChild,\n                false\n            );\n        });\n    }\n\n    #printParents(id, partners, px, isLast, isRoot) {\n        partners.forEach(partnerId => {\n            const partner = this.getPersonById(partnerId);\n            if (partner) {\n                console.log(`${px}💑 With: ${partner.name} (ID: ${partner.id})`);\n                const children = partner.children[id] || [];\n                if (children.length) {\n                    this.#printChild(children, px, isLast, isRoot);\n                } else {\n                    console.log(`${px}└── 🚫 Without children`);\n                }\n            }\n        });\n    }\n\n    #printFamily(id, px = \"\", isLast = false, isRoot = true) {\n        const person = this.getPersonById(id);\n        if (!person) return;\n\n        console.log(`${px}🙂 ${person.name} (ID: ${person.id})`);\n\n        const partners = person.partners;\n        if (Array.isArray(partners) && partners.length) {\n            if (!isRoot) {\n                px = px.slice(0, -4) + (isLast ? \"    \" : \"│   \");\n            }\n\n            this.#printParents(id, partners, px, isLast, isRoot);\n            if (!isLast) {\n                console.log(px);\n            }\n        }\n    }\n\n    printTree() {\n        const [grandparents, noPartner] = this.#filteredGrandparents();\n\n        if (!grandparents.length && !noPartner.length) {\n            console.log(\"⚠️ No users are registered.\");\n            return;\n        }\n\n        if (noPartner.length) {\n            console.log(\"__________\\nParents unknown, without descendants and without a partner:\");\n            noPartner.forEach(p => {\n                console.log(`😐 ${p.name}`);\n            });\n        }\n\n        console.log();\n        grandparents.forEach((person, i) => {\n            console.log(`__________\\nFamily #${i + 1}`);\n            this.#printFamily(person.id);\n        });\n    }\n}\n\nclass Program extends Tree {\n    static MENU = `\n  ---------------------------------------------\n  | 1. Add person     | 4. Edit children      |  \n  | 2. Remove person  | 5. Print tree         |\n  | 3. Edit partners  | 6. Exit               |\n  ---------------------------------------------`;\n\n    async run() {\n        while (true) {\n            console.log(Program.MENU);\n            const option = await this.inputInt(\"\\nOption: \");\n\n            switch (option) {\n                case 1:\n                    await this.addPerson();\n                    break;\n                case 2:\n                    await this.removePerson();\n                    break;\n                case 3:\n                    await this.editPartners();\n                    break;\n                case 4:\n                    await this.editChildren();\n                    break;\n                case 5:\n                    this.printTree();\n                    break;\n                case 6:\n                    console.log(\"Bye\");\n                    rl.close();\n                    return;\n                default:\n                    console.log(\"❌ Invalid option.\");\n            }\n        }\n    }\n}\n\nconst program = new Program();\nprogram.run().catch(console.error);\n"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/javascript/miguelex.js",
    "content": "class Person {\n    constructor(id, name) {\n        this.id = id;\n        this.name = name;\n        this.partner = null;\n        this.children = [];\n    }\n\n    setPartner(partner) {\n        this.partner = partner;\n    }\n\n    addChild(child) {\n        this.children.push(child);\n    }\n}\n\nclass FamilyTree {\n    constructor() {\n        this.people = {};\n    }\n\n    addPerson(id, name) {\n        this.people[id] = new Person(id, name);\n    }\n\n    removePerson(id) {\n        delete this.people[id];\n    }\n\n    setPartner(id1, id2) {\n        if (this.people[id1] && this.people[id2]) {\n            this.people[id1].setPartner(this.people[id2]);\n            this.people[id2].setPartner(this.people[id1]);\n        }\n    }\n\n    addChild(parentId, childId) {\n        if (this.people[parentId] && this.people[childId]) {\n            this.people[parentId].addChild(this.people[childId]);\n        }\n    }\n\n    printTree() {\n        Object.values(this.people).forEach(person => {\n            if (!this.hasParents(person)) {\n                this.printSubTree(person);\n                console.log(\"\");\n            }\n        });\n    }\n\n    printSubTree(person, indent = 0) {\n        console.log(\" \".repeat(indent) + person.name + (person.partner ? \" ⟷ \" + person.partner.name : \"\"));\n        person.children.forEach(child => {\n            this.printSubTree(child, indent + 4);\n        });\n    }\n\n    hasParents(person) {\n        return Object.values(this.people).some(other => other.children.includes(person));\n    }\n}\n\nlet tree = new FamilyTree();\ntree.addPerson(1, \"Aegon I Targaryen\");\ntree.addPerson(2, \"Rhaenys Targaryen\");\ntree.addPerson(3, \"Visenya Targaryen\");\n\ntree.addPerson(4, \"Aenys I Targaryen\");\ntree.addPerson(5, \"Maegor I Targaryen\");\n\ntree.addPerson(6, \"Jaehaerys I Targaryen\");\ntree.addPerson(7, \"Alysanne Targaryen\");\n\ntree.addPerson(8, \"Aegon II Targaryen\");\ntree.addPerson(9, \"Helaena Targaryen\");\n\ntree.addPerson(10, \"Viserys II Targaryen\");\n\ntree.addPerson(11, \"Rhaenyra Targaryen\");\ntree.addPerson(12, \"Daemon Targaryen\");\n\ntree.setPartner(1, 2); // Aegon I y Rhaenys\ntree.setPartner(1, 3); // Aegon I y Visenya\ntree.setPartner(4, 7); // Jaehaerys I y Alysanne\ntree.setPartner(8, 9); // Aegon II y Helaena\ntree.setPartner(11, 12); // Rhaenyra y Daemon\n\ntree.addChild(1, 4); // Aenys I hijo de Aegon I y Rhaenys\ntree.addChild(1, 5); // Maegor I hijo de Aegon I y Visenya\n\ntree.addChild(4, 6); // Jaehaerys I hijo de Aenys I\ntree.addChild(4, 11); // Rhaenyra hija de Aenys I\n\ntree.addChild(6, 8); // Aegon II hijo de Jaehaerys I\ntree.addChild(6, 10); // Viserys II hijo de Jaehaerys I\n\ntree.printTree();\n"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/javascript/pedamoci.js",
    "content": "import readline from \"readline\"\n\nconst colors = {\n  red: \"\\x1b[31m\",\n  green: \"\\x1b[32m\",\n  yellow: \"\\x1b[33m\",\n  cyan: \"\\x1b[34m\",\n  reset: \"\\x1b[0m\",\n}\n\nclass Asks {\n  constructor() {\n    this.readline = readline.createInterface({\n      input: process.stdin,\n      output: process.stdout\n    })\n  }\n\n  #ask(question) {\n    return new Promise(resolve => {\n      this.readline.question(question, (answer) => resolve(answer))\n    })\n  }\n\n  close() {\n    this.readline.close()\n  }\n\n  async askLabel(label) {\n    const response = await this.#ask(colors.cyan + `Enter the ${label}: ` + colors.reset)\n    return response\n  }\n\n  async askForOperation() {\n    const operation = (await this.#ask(colors.cyan + \"Choose an action: \" +\n                                      \"\\nAP  --> For add Person             RP  --> For remove Person\" + \n                                      \"\\nAF  --> For add Father             RF  --> For remove Father\" + \n                                      \"\\nAM  --> For add Mother             RM  --> For remove Mother\" + \n                                      \"\\nAPT --> For add Partner            RPT --> For remove Partner\" + \n                                      \"\\nAC  --> For add child              RC  --> For remove child\" +  \n                                      \"\\nVT  --> View Tree                  GI  --> get person ID\" + \n                                      \"\\nE   --> Exit\" +\n                                      \"\\nYour choice: \" + colors.reset)).toUpperCase()\n    return operation\n  }\n}\n\nconst asks = new Asks()\n\nclass Validator {\n  static alreadyHasFather(childID, childParents) {\n    return !!childParents[childID]?.father\n  }\n\n  static alreadyHasMother(childID, childParents) {\n    return !!childParents[childID]?.mother\n  }\n\n  static isExistingChild(childID, childParents) {\n    return !!childParents[childID]\n  }\n\n  static isExistingFather(fatherID, childParents) {\n    for (const childID in childParents) {\n      if (childParents[childID].father === fatherID) {\n        return true\n      }\n    }\n    return false\n  }\n\n  static isExistingMother(motherID, childParents) {\n    for (const childID in childParents) {\n      if (childParents[childID].mother === motherID) {\n        return true\n      }\n    }\n    return false\n  }\n\n  static isExistingPartner(personID, partners) {\n    for (const parentID in partners) {\n      if (parentID === personID) return true\n    }\n    return false\n  }\n\n  static isExistingPerson(id, people) {\n    for (const personID in people) {\n      if (personID === id) return true\n    }\n    return false\n  }\n\n  static isHisFather(childID, fatherID, childParents) {\n    return (childParents[childID].father === fatherID)\n  }\n\n  static isHisMother(childID, motherID, childParents) {\n    return (childParents[childID].mother === motherID)\n  }\n\n  static isTryingToSetSameParent(childID, newParentID, childParents){\n    const { mother, father } = childParents[childID] || {}\n\n    return (newParentID === mother || newParentID === father)\n  }\n\n  static isValidID(id) {\n    return /^\\d+$/.test(id)\n  }\n\n  static isValidName(name) {\n    return (typeof name === \"string\" && name.trim().length > 0)\n  }\n\n  static treeIsEmpty(people) {\n    return !!(people == {})\n  }\n}\n\nclass ValidatorHelper {\n  static validatePersonID(id, people) {\n    if (!Validator.isValidID(id)){\n      Renderer.error(`ID ${id} is invalid`)\n      return false\n    }\n\n    if (!Validator.isExistingPerson(id, people)){\n      Renderer.error(`Person with ID ${id} does not exist`)\n      return false\n    }\n\n    return true\n  }\n}\n\nclass PersonManager {\n  constructor() {\n    this.people = {}\n  }\n\n  addPerson(id, name) {\n    this.people[id] = { name }\n  }\n\n  removePerson(id) {\n    delete this.people[id]\n  }\n\n  getID(name) {\n    for (const id in this.people) {\n      if (this.people[id].name === name) {\n        return id\n      }\n    }\n    return false\n  }\n}\n\nclass RelationManager {\n  constructor() {\n    this.childParents = {}\n    this.partners = {}\n  }\n\n  addChild(childID, motherID, fatherID) {\n    if (!this.childParents[childID]) this.childParents[childID] = {}\n    this.childParents[childID].mother = motherID\n    this.childParents[childID].father = fatherID\n  }\n\n  addFather(childID, fatherID) {\n    if (!this.childParents[childID]) this.childParents[childID] = {}\n    this.childParents[childID].father = fatherID\n  }\n\n  addMother(childID, motherID) {\n    if (!this.childParents[childID]) this.childParents[childID] = {}\n    this.childParents[childID].mother = motherID\n  }\n\n  addPartner(personID, partnerID) {\n    this.partners[personID] = partnerID\n    this.partners[partnerID] = personID\n  }\n\n  removeChild(childID) {\n    delete this.childParents[childID]\n  }\n\n  removeFather(childID) {\n    delete this.childParents[childID].father\n  }\n\n  removeMother(childID) {\n    delete this.childParents[childID].mother\n  }\n\n  removePartner(personID) {\n    const partnerID = this.partners[personID]\n\n    delete this.partners[personID]\n    delete this.partners[partnerID]\n  }\n\n  removePersonFather(fatherID){\n    for (const childID in this.childParents) {\n      if (this.childParents[childID].father === fatherID) {\n        delete this.childParents[childID].father\n      }\n    }\n  }\n\n  removePersonMother(motherID){\n    for (const childID in this.childParents) {\n      if (this.childParents[childID].mother === motherID) {\n        delete this.childParents[childID].mother\n      }\n    }\n  }\n}\n\nclass Renderer {\n  static error(message) {\n    console.log(colors.red + \"Error: \" + message + colors.reset)\n  }\n\n  static success(message) {\n    console.log(colors.green + \"Success: \" + message + colors.reset)\n  }\n\n  static info(info) {\n    console.log(info)\n  }\n}\n\nclass TreePrinter {\n  static buildChildrenMap(people, childParents) {\n    const childrenMap = {}\n    \n    Object.keys(people).forEach(id => childrenMap[id] = [])\n\n    for (const [childID, parents] of Object.entries(childParents)) {\n      if (parents.father && childrenMap[parents.father]) {\n        childrenMap[parents.father].push(childID)\n      }\n      if (parents.mother && childrenMap[parents.mother]) {\n        childrenMap[parents.mother].push(childID)\n      }\n    }\n    return childrenMap\n  }\n\n  static print(personManager, relationManager) {\n    const people = personManager.people\n    const childParents = relationManager.childParents\n    const partners = relationManager.partners\n\n    const childrenMap = this.buildChildrenMap(people, childParents)\n    const visited = new Set()\n\n    const roots = Object.keys(people).filter(id => !childParents[id])\n\n    const allIds = roots.length > 0 ? roots : Object.keys(people)\n\n    allIds.forEach(rootId => {\n      if (!visited.has(rootId)) {\n        this.printNode(rootId, 0, people, childrenMap, partners, visited, childParents)\n        Renderer.info(\"\")\n      }\n    })\n  }\n\n  static printNode(id, level, people, childrenMap, partners, visited, childParents) {\n    if (visited.has(id)) return\n    visited.add(id)\n\n    const personName = people[id].name\n    const indent = \"    \".repeat(level)\n\n    let partnerInfo = \"\";\n    if (partners[id]) {\n      const partnerId = partners[id]\n      const partnerName = people[partnerId].name\n\n      if (!Validator.isExistingChild(partnerId, childParents)) visited.add(partnerId)\n\n      partnerInfo = `${colors.red}❤${colors.reset}  ${partnerName}`\n    }\n\n    (level === 0) ? Renderer.info(`${indent}${personName} ${partnerInfo}`)\n                  : Renderer.info(`${indent}${colors.green}└─ ${colors.reset}${personName} ${partnerInfo}`)\n\n    const children = childrenMap[id] || []\n    if (children.length > 0) {\n        children.forEach(childId => {\n            this.printNode(childId, level + 1, people, childrenMap, partners, visited, childParents)\n        })\n    }\n  }\n}\n\nclass MenuController {\n  constructor(personManager, relationManager) {\n    this.personManager = personManager\n    this.relationManager = relationManager\n    this.init = true\n  }\n\n  async start() {\n    while (this.init) {\n      const option = (await asks.askForOperation()).toUpperCase()\n      await this.processOption(option)\n    }\n  }\n\n  async processOption(option) {\n    switch (option) {\n      case \"AP\":\n        {\n          const id = await asks.askLabel(\"person ID\")\n          const name = await asks.askLabel(\"person NAME\")\n\n          if (!Validator.isValidID(id)){\n            Renderer.error(\"Invalid ID\")\n            break\n          }\n\n          if (!Validator.isValidName(name)){\n            Renderer.error(\"Invalid NAME\")\n            break\n          }\n\n          if (Validator.isExistingPerson(id, this.personManager.people)){\n            Renderer.error(\"Person already exists\")\n            break\n          }\n\n          this.personManager.addPerson(id, name)\n          Renderer.success(\"The person has been added\")\n        }\n        break;\n\n      case \"AF\":\n        {\n          const fatherID = await asks.askLabel(\"father ID\")\n          const childID = await asks.askLabel(\"child ID\")\n\n          if (!ValidatorHelper.validatePersonID(fatherID, this.personManager.people)) break\n\n          if (!ValidatorHelper.validatePersonID(childID, this.personManager.people)) break\n\n          if (Validator.alreadyHasFather(childID, this.relationManager.childParents)){\n            Renderer.error(\"The child already has a father\")\n            break\n          }\n\n          if (Validator.isTryingToSetSameParent(childID, fatherID, this.relationManager.childParents)){\n            Renderer.error(\"Mother and father cannot be the same person\")\n            break\n          }\n\n          this.relationManager.addFather(childID, fatherID)\n          Renderer.success(\"The father has been added\")\n        }\n        break;\n\n      case \"AM\":\n        {\n          const motherID = await asks.askLabel(\"mother ID\")\n          const childID = await asks.askLabel(\"child ID\")\n\n          if (!ValidatorHelper.validatePersonID(motherID, this.personManager.people)) break\n\n          if (!ValidatorHelper.validatePersonID(childID, this.personManager.people)) break\n\n          if (Validator.isTryingToSetSameParent(childID, this.relationManager.childParents)){\n            Renderer.error(\"The child already has a mother\")\n            break\n          }\n\n          if (Validator.isHisFather(childID, motherID, this.relationManager.childParents)){\n            Renderer.error(\"Mother and father cannot be the same person\")\n            break\n          }\n\n          this.relationManager.addMother(childID, motherID)\n          Renderer.success(\"The mother has been added\")\n        }\n        break;\n\n      case \"APT\":\n        {\n          const personID = await asks.askLabel(\"person ID\")\n          const partnerID = await asks.askLabel(\"partner ID\")\n\n          if (!ValidatorHelper.validatePersonID(personID, this.personManager.people)) break\n\n          if (!ValidatorHelper.validatePersonID(partnerID, this.personManager.people)) break\n\n          if (Validator.isExistingPartner(personID, this.personManager.partners)){\n            Renderer.error(`the person with ID ${personID} already has partner`)\n            break\n          }\n\n          if (Validator.isExistingPartner(partnerID, this.personManager.partners)){\n            Renderer.error(`the person with ID ${partnerID} already has partner`)\n            break\n          }\n\n          this.relationManager.addPartner(personID, partnerID)\n          Renderer.success(\"The partner has been added\")\n        }\n        break;\n\n      case \"AC\":\n        {\n          const childID = await asks.askLabel(\"child ID\")\n          const motherID = await asks.askLabel(\"mother ID\")\n          const fatherID = await asks.askLabel(\"father ID\")\n\n          if (!ValidatorHelper.validatePersonID(childID, this.personManager.people)) break\n\n          if (!ValidatorHelper.validatePersonID(motherID, this.personManager.people)) break\n\n          if (!ValidatorHelper.validatePersonID(fatherID, this.personManager.people)) break\n\n          if (motherID === fatherID) {\n            Renderer.error(\"Mother and father cannot be the same person\")\n            break\n          }\n\n          this.relationManager.addChild(childID, motherID, fatherID)\n          Renderer.success(\"The child has been added\")\n        }\n        break;\n\n      case \"RP\":\n        {\n          const id = await asks.askLabel(\"person ID\")\n\n          if (!ValidatorHelper.validatePersonID(id, this.personManager.people)) break\n\n          if (Validator.isExistingChild(id, this.relationManager.childParents))\n            this.relationManager.removeChild(id)\n\n          if (Validator.isExistingFather(id, this.relationManager.childParents))\n            this.relationManager.removePersonFather(id)\n\n          if (Validator.isExistingMother(id, this.relationManager.childParents))\n            this.relationManager.removePersonMother(id)\n\n          if (Validator.isExistingPartner(id, this.relationManager.partners))\n            this.relationManager.removePartner(id)\n\n          this.personManager.removePerson(id)\n          Renderer.success(\"The person has been eliminated\")\n        }\n        break;\n\n      case \"RF\":\n        {\n          const fatherID = await asks.askLabel(\"father ID\")\n          const childID = await asks.askLabel(\"child ID\")\n\n          if (!ValidatorHelper.validatePersonID(fatherID, this.personManager.people)) break\n\n          if (!ValidatorHelper.validatePersonID(childID, this.personManager.people)) break\n\n          if (!Validator.isExistingChild(childID, this.relationManager.childParents)){\n            Renderer.error(`This ID ${childID} does not correspond to a child`)\n            break\n          }\n\n          if (!Validator.isHisFather(childID, fatherID, this.relationManager.childParents)){\n            Renderer.error(\"This ID does not correspond to the father\")\n            break\n          }\n\n          this.relationManager.removeFather(childID)\n          Renderer.success(\"The father has been eliminated\")\n        }\n        break;\n\n      case \"RM\":\n        {\n          const motherID = await asks.askLabel(\"mother ID\")\n          const childID = await asks.askLabel(\"child ID\")\n\n          if (!ValidatorHelper.validatePersonID(motherID, this.personManager.people)) break\n\n          if (!ValidatorHelper.validatePersonID(childID, this.personManager.people)) break\n\n          if (!Validator.isExistingChild(childID, this.relationManager.childParents)){\n            Renderer.error(`This ID ${childID} does not correspond to a child`)\n            break\n          }\n\n          if (!Validator.isHisMother(childID, motherID, this.relationManager.childParents)){\n            Renderer.error(\"This ID does not correspond to the mother\")\n            break\n          }\n\n          this.relationManager.removeMother(childID)\n          Renderer.success(\"The mother has been eliminated\")\n        }\n        break;\n\n      case \"RPT\":\n        {\n          const id = await asks.askLabel(\"partner ID\")\n\n          if (!ValidatorHelper.validatePersonID(id, this.personManager.people)) break\n\n          if (!Validator.isExistingPartner(id, this.relationManager.partners)){\n            Renderer.error(\"This ID has not partner\")\n            break\n          }\n\n          this.relationManager.removePartner(id)\n          Renderer.success(\"The partner has been eliminated\")\n        }\n        break;\n\n      case \"RC\":\n        {\n          const id = await asks.askLabel(\"child ID\")\n\n          if (!ValidatorHelper.validatePersonID(id, this.personManager.people)) break\n\n          if (!Validator.isExistingChild(id, this.relationManager.childParents)){\n            Renderer.error(\"This ID does not belong to any child\")\n            break\n          }\n\n          this.relationManager.removeChild(id)\n          Renderer.success(\"The child has been eliminated\")\n        }\n        break;\n\n      case \"GI\":\n        {\n          const name = await asks.askLabel(\"person NAME\")\n\n          const response = this.personManager.getID(name)\n\n          if (!response) \n            Renderer.error(\"This name does not correspond to a person\")\n\n          Renderer.success(`The person ID is ${response}`)\n        }\n        break;\n\n        case \"VT\":\n          {\n            if (Validator.treeIsEmpty()){\n              Renderer.error(\"The family tree is empty\")\n            }\n\n            Renderer.info(colors.yellow + \"\\n--- FAMILY TREE ---\\n\" + colors.reset)\n            TreePrinter.print(this.personManager, this.relationManager)\n          }\n          break;\n\n      case \"E\":\n        this.init = false\n        asks.close()\n        break;\n      default:\n        break;\n    }\n  }\n}\n\nconst menuController = new MenuController(new PersonManager, new RelationManager)\nmenuController.start()"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/javascript/redom69.js",
    "content": "class Person {\n    constructor(id, name, couple = null, children = []) {\n        this.id = id\n        this.name=name\n        this.couple = couple\n        this.children= children\n    }\n\n    addChild(child){\n        this.children.push(child)\n    }\n\n    modifyCouple(couple){\n        this.couple = couple\n    }\n\n    toString(){\n        const coupleName = this.couple ? this.couple.name : \"None\";\n        return `Person(id=${this.id}, name=${this.name}, couple=${coupleName}, children=${this.children.length})`;\n    }\n}\n\nclass FamilyTree{\n\n    constructor(person){\n        this.root = person\n        this.people = {};\n        this.people[person.id] = person;\n    }\n\n    addPerson(person){\n        if (!(person.id in this.people)) {\n            this.people[person.id] = person\n        }else{\n            console.log('Ya existe')\n        }\n    }\n\n    deletePerson(person_id){\n        if (id in this.people) {\n            delete this.people[person_id];\n        }else{\n            console.log('No existe')\n        }\n    }\n\n    editPerson(id, name, couple = null, children = []){\n        if (id){\n            const person =  this.people[id]\n            if (name) person.name = name\n            if (couple) person.modifyCouple(couple)\n            if (children.length()>0) person.children = children\n        }else{\n            console.log('No existe')\n        }\n    }\n\n    displayTree(person = null, level = 0) {\n        if (person === null) {\n            person = this.root;\n        }\n\n        const indent = \" \".repeat(level * 4);\n        const coupleName = person.couple ? ` & ${person.couple.name}` : \"\";\n        console.log(`${indent}${person.name}${coupleName}`);\n\n        for (const child of person.children) {\n            this.displayTree(child, level + 1);\n        }\n    }\n}\n\n\nfunction main() {\n    const jaehaerys = new Person(1, \"Jaehaerys I Targaryen\");\n    const alysanne = new Person(2, \"Alysanne Targaryen\");\n\n    const baelon = new Person(3, \"Baelon Targaryen\");\n    const alyssa = new Person(4, \"Alyssa Targaryen\");\n\n    const viserys = new Person(5, \"Viserys I Targaryen\");\n    const aemma = new Person(6, \"Aemma Arryn\");\n\n    const daemon = new Person(7, \"Daemon Targaryen\");\n    const rhea = new Person(8, \"Rhea Royce\");\n    const laena = new Person(9, \"Laena Velaryon\");\n    const rhaenyra = new Person(10, \"Rhaenyra Targaryen\");\n\n    const alicent = new Person(11, \"Alicent Hightower\");\n    const aegonII = new Person(12, \"Aegon II Targaryen\");\n    const helaena = new Person(13, \"Helaena Targaryen\");\n    const aemond = new Person(14, \"Aemond Targaryen\");\n    const daeron = new Person(15, \"Daeron Targaryen\");\n\n    jaehaerys.modifyCouple(alysanne);\n    baelon.modifyCouple(alyssa);\n    baelon.children = [viserys, daemon];\n    viserys.modifyCouple(aemma);\n    viserys.children = [rhaenyra];\n    daemon.modifyCouple(rhea);\n    daemon.children = [];\n\n    daemon.modifyCouple(laena);\n    const baela = new Person(16, \"Baela Targaryen\");\n    const rhaena = new Person(17, \"Rhaena Targaryen\");\n    daemon.children = [baela, rhaena];\n\n    rhaenyra.modifyCouple(daemon);\n\n    viserys.modifyCouple(alicent);\n    viserys.children.push(aegonII, helaena, aemond, daeron);\n\n    const familyTree = new FamilyTree(viserys);\n    familyTree.addPerson(jaehaerys);\n    familyTree.addPerson(alysanne);\n    familyTree.addPerson(baelon);\n    familyTree.addPerson(alyssa);\n    familyTree.addPerson(daemon);\n    familyTree.addPerson(rhea);\n    familyTree.addPerson(laena);\n    familyTree.addPerson(rhaenyra);\n    familyTree.addPerson(alicent);\n    familyTree.addPerson(aegonII);\n    familyTree.addPerson(helaena);\n    familyTree.addPerson(aemond);\n    familyTree.addPerson(daeron);\n    familyTree.addPerson(baela);\n    familyTree.addPerson(rhaena);\n\n    familyTree.displayTree();\n}\n\nmain();"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/javascript/victor-Casta.js",
    "content": "class Person {\n  constructor(id, name) {\n    this.id = id\n    this.name = name\n    this.partner = null\n    this.children = []\n  }\n}\n\nclass FamilyTree {\n  constructor() {\n    this.people = new Map()\n  }\n\n  addPerson(id, name) {\n    if (this.people.has(id)) {\n      console.log(`La persona con ID ${id} ya existe.`)\n      return\n    }\n    const newPerson = new Person(id, name)\n    this.people.set(id, newPerson)\n    console.log(`Persona ${name} añadida al árbol.`)\n  }\n\n  removePerson(id) {\n    if (!this.people.has(id)) {\n      console.log(`La persona con ID ${id} no existe.`)\n      return\n    }\n\n    const person = this.people.get(id)\n    if (person.partner) {\n      person.partner.partner = null\n    }\n\n    this.people.forEach((p) => {\n      p.children = p.children.filter((child) => child.id !== id)\n    })\n\n    this.people.delete(id)\n    console.log(`Persona con ID ${id} eliminada del árbol.`)\n  }\n\n  setPartner(id1, id2) {\n    if (!this.people.has(id1) || !this.people.has(id2)) {\n      console.log(`Una o ambas personas no existen.`)\n      return\n    }\n\n    const person1 = this.people.get(id1)\n    const person2 = this.people.get(id2)\n\n    if (person1.partner || person2.partner) {\n      console.log(`Una de las personas ya tiene pareja.`)\n      return\n    }\n\n    person1.partner = person2\n    person2.partner = person1\n    console.log(`${person1.name} y ${person2.name} ahora son pareja.`)\n  }\n\n  addChild(parentId, childId) {\n    if (!this.people.has(parentId) || !this.people.has(childId)) {\n      console.log(`Una o ambas personas no existen.`)\n      return\n    }\n\n    const parent = this.people.get(parentId)\n    const child = this.people.get(childId)\n\n    if (!parent.children.includes(child)) {\n      parent.children.push(child)\n      console.log(`${child.name} añadido como hijo/a de ${parent.name}.`)\n    } else {\n      console.log(`${child.name} ya es hijo/a de ${parent.name}.`)\n    }\n  }\n\n  printTree() {\n    this.people.forEach((person) => {\n      console.log(`ID: ${person.id}, Nombre: ${person.name}`)\n      if (person.partner) {\n        console.log(`  Pareja: ${person.partner.name}`)\n      }\n      if (person.children.length > 0) {\n        const childNames = person.children.map((child) => child.name).join(\", \")\n        console.log(`  Hijos: ${childNames}`)\n      }\n    })\n  }\n}\n\nconst tree = new FamilyTree()\ntree.addPerson(1, \"Alicent\")\ntree.addPerson(2, \"Viserys\")\ntree.addPerson(3, \"Rhaenyra\")\ntree.addPerson(4, \"Daemon\")\n\ntree.setPartner(1, 2)\ntree.addChild(1, 3)\ntree.setPartner(3, 4)\n\ntree.printTree()\ntree.removePerson(3)\ntree.printTree()"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/kotlin/blackriper.kt",
    "content": "import kotlinx.coroutines.async\r\nimport kotlinx.coroutines.coroutineScope\r\nimport kotlinx.coroutines.launch\r\nimport kotlinx.coroutines.runBlocking\r\nimport java.util.UUID\r\n\r\n//1.-Definir entidades y comportamiento\r\n\r\ndata class Partner constructor(\r\n    val uuid:UUID=UUID.randomUUID(),\r\n    var name:String=\"\",\r\n    var sons : MutableList<UUID> = mutableListOf(),\r\n )\r\n\r\ndata class Person constructor(\r\n    val uuid:UUID=UUID.randomUUID(),\r\n    var name:String=\"\",\r\n    var partner: MutableList<Partner> = mutableListOf(),\r\n    var sons : MutableList<Person> = mutableListOf(),\r\n)\r\n\r\n\r\ninterface FamilyRecord{\r\n suspend fun registerPerson(person: Person)\r\n suspend fun deletePerson(uuid: UUID)\r\n suspend fun findMember(name: String):UUID?\r\n suspend fun updateOrDeletePartner(uuid: UUID,confirm:String)\r\n}\r\n\r\ninterface PersonValidators{\r\n  suspend fun maxNumofPartners(numWife: Int):Boolean\r\n  suspend fun maxNumofSons(numSons: Int):Boolean\r\n  suspend fun moreThanOneFather(son:Person):Boolean\r\n}\r\n\r\n//2.-Definir  un estado reactivo\r\ntypealias ListPerson=MutableList<Person>\r\nval persons:ListPerson=mutableListOf()\r\n\r\nclass DragonRecord:FamilyRecord {\r\n\r\n    override suspend fun registerPerson(person: Person) {\r\n        persons.add(person)\r\n\r\n    }\r\n\r\n\r\n    override suspend fun deletePerson(uuid: UUID) {\r\n        persons.removeIf { it.uuid == uuid }.run {\r\n            if (this) println(\"The person was deleted\")\r\n            else println(\"The person was not found\")\r\n        }\r\n    }\r\n\r\n\r\n    override suspend fun findMember(name: String): UUID? =\r\n        persons.firstOrNull { it.name.lowercase() == name }?.uuid\r\n\r\n\r\n    override suspend fun updateOrDeletePartner(uuid: UUID, confirm: String) {\r\n        val partner = persons.first { it.uuid == uuid }.partner\r\n        when (confirm) {\r\n            \"D\" -> {\r\n                println(\"Name of the partner you want to delete\")\r\n                val partnerName = readLine()?.let { it.lowercase() } ?: \"\"\r\n\r\n                partner.removeIf { it.name.lowercase() == partnerName }.run {\r\n                    if (this) println(\"The partner $partnerName was deleted\")\r\n                    else println(\"The partner $partnerName was not found\")\r\n                }\r\n            }\r\n\r\n            \"U\" -> {\r\n                println(\"Enter a partner name to update\")\r\n                val partnerName = readLine()?.let { it.lowercase() } ?: \"\"\r\n\r\n                partner.firstOrNull { it.name.lowercase() == partnerName }.run {\r\n                    if (this == null) println(\"partner name incorrect try again\")\r\n                    if (this != null) {\r\n                        println(\"Enter new name (${this.name})\")\r\n                        this.name = readLine() ?: this.name\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n    }\r\n}\r\n\r\nclass Validator:PersonValidators{\r\n    override suspend fun maxNumofPartners(numWife: Int): Boolean =numWife>2\r\n\r\n    override suspend fun maxNumofSons(numSons: Int): Boolean =numSons>2\r\n\r\n    override suspend fun moreThanOneFather(son :Person): Boolean =\r\n        persons.contains(son)\r\n}\r\n\r\ncontext(PersonValidators,FamilyRecord)\r\nclass FamilyTree{\r\n\r\n   suspend fun registerPerson():Unit= coroutineScope{\r\n       val person= async {\r\n           val father=Person()\r\n           println(\"Enter a person name: \")\r\n           father.name = readLine() ?: \"\"\r\n           val patList= async { personPartners() }.await()\r\n           val sonList = async {\r\n               val sons:MutableList<Person> = mutableListOf()\r\n               patList.forEach {\r\n                   val patherSons=personSons(it.name)\r\n                   it.sons.addAll(patherSons.map { it.uuid })\r\n                   sons.addAll(patherSons)\r\n               }\r\n               sons\r\n           }.await()\r\n           father.apply {\r\n               partner=patList\r\n               sons=sonList\r\n           }\r\n       }\r\n        registerPerson(person.await())\r\n     }\r\n\r\n    suspend  fun deletePerson():Unit= coroutineScope{\r\n        println(\"Name of the person you want to delete\")\r\n        val name=readLine() ?: \"\"\r\n        val uuid = findMember(name.lowercase())\r\n        if (uuid==null) println(\"Person not found\")\r\n        if (uuid!=null) launch { deletePerson(uuid) }\r\n    }\r\n\r\n\r\n    suspend fun updateSonsOrWifes()= coroutineScope{\r\n       println(\"Name of the person you want to update\")\r\n       val name=readLine() ?: \"\"\r\n       val uuidFather = findMember(name.lowercase())\r\n       if (uuidFather==null) println(\"Person not found\")\r\n       if (uuidFather!=null) launch { updateMenu(uuidFather) }\r\n    }\r\n\r\n  private suspend fun updateMenu(uuidFather:UUID){\r\n      var operation = 0\r\n      while (operation != 4) {\r\n          println(\"1. Update/Delete wifes\")\r\n          println(\"2. Update/Delete sons\")\r\n          println(\"3. Add sons or wifes \")\r\n          println(\"4. Exit\")\r\n          operation = readLine()!!.toInt()\r\n          when (operation) {\r\n              1-> deleteOrUpdatePartner(uuidFather)\r\n              2-> deleteOrUpdateSon(uuidFather)\r\n              3 -> with(Validator()){ addFamilyMember(uuidFather) }\r\n\r\n          }\r\n      }\r\n  }\r\n\r\n\r\n    private suspend fun deleteOrUpdateSon(uuid: UUID):Unit= coroutineScope{\r\n        val sonList=persons.first { it.uuid == uuid }.sons\r\n        println(\"Do you want to delete or update? (D/U)\")\r\n        val confirm = readLine()?.let { it.uppercase() } ?: \"D\"\r\n        when(confirm){\r\n            \"D\"->{\r\n                println(\"Name of son you want to delete\")\r\n                val sonName = readLine()?.let { it.lowercase() } ?: \"\"\r\n                sonList.removeIf { it.name.lowercase() == sonName }.run {\r\n                    if (this) println(\"The son $sonName was deleted\")\r\n                    else println(\"The son $sonName was not found\")\r\n                }\r\n            }\r\n            \"U\"->{\r\n                println(\"Name of son you want to update\")\r\n                val sonName = readLine()?.let { it.lowercase() } ?: \"\"\r\n                sonList.firstOrNull { it.name.lowercase() == sonName }.run {\r\n                    if (this == null) println(\"son name incorrect try again\")\r\n                    if (this != null) {\r\n                        println(\"Enter new name (${this.name})\")\r\n                        val newName = readLine() ?: this.name\r\n                        this.name= if (newName.isNotEmpty()) newName else this.name\r\n                        val partnerList= async { personPartners() }.await()\r\n                        val sonColl = async {\r\n                            val sons:MutableList<Person> = mutableListOf()\r\n                            partnerList.forEach {\r\n                                val patherSons=personSons(it.name)\r\n                                it.sons.addAll(patherSons.map { it.uuid })\r\n                                sons.addAll(patherSons)\r\n                            }\r\n                            sons\r\n                        }.await()\r\n                        this.apply {\r\n                            partner=partnerList\r\n                            sons=sonColl\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    private suspend fun deleteOrUpdatePartner(uuid: UUID) {\r\n        println(\"Do you want to delete or update? (D/U)\")\r\n        val confirm = readLine()?.let { it.uppercase() } ?: \"D\"\r\n        updateOrDeletePartner(uuid,confirm)\r\n    }\r\n\r\n\r\n    private suspend  fun personSons(partnerName:String):MutableList<Person> {\r\n        println(\"The person have sons with $partnerName ? (Y/N)\")\r\n        val confirmSons = readLine()?.let { it.uppercase() } ?: \"N\"\r\n        if (confirmSons == \"Y\") return registerSons(::maxNumofSons, ::moreThanOneFather)\r\n        else return mutableListOf()\r\n    }\r\n\r\n    private suspend fun personPartners(): MutableList<Partner>  {\r\n        println(\"The person have a partner? (Y/N)\")\r\n        val confirm = readLine()?.let { it.uppercase() } ?: \"N\"\r\n        if (confirm == \"Y\")  return registerPartner(::maxNumofPartners)\r\n        else return mutableListOf()\r\n    }\r\n\r\n\r\n}\r\n\r\nclass RecordTree(private val record: FamilyTree){\r\n\r\n  suspend fun showMenu()= coroutineScope{\r\n      var option=0\r\n      while (option!=5){\r\n          println(\"1. Add person\")\r\n          println(\"2. Delete person\")\r\n          println(\"3. Update sons or partners\")\r\n          println(\"4.-Print family tree\")\r\n          println(\"5. Exit\")\r\n          option=readLine()!!.toInt()\r\n          when(option){\r\n              1->record.registerPerson()\r\n              2->record.deletePerson()\r\n              3->record.updateSonsOrWifes()\r\n              4->printTree()\r\n          }\r\n      }\r\n  }\r\n\r\n  private suspend fun printTree(){\r\n      println(\"Name of the person you want to print the family tree\")\r\n      val name=readLine()?.let { it.lowercase() } ?: \"\"\r\n      val person=persons.first { it.name.lowercase() == name }\r\n      val familyTree=\"\"\"\r\n          \r\n               ${person.name}\r\n      __________________________________\r\n            ${person.name}  Partners    \r\n      __________________________________                 \r\n      ${person.partner.forEach { \"${it.name}\\n\" }}\r\n      ___________________________________\r\n      ${printSons(person.uuid,person.partner)}\r\n      \r\n      \r\n      \"\"\".trimIndent()\r\n\r\n      println(familyTree)\r\n  }\r\n\r\n  private fun printSons(uuidFather: UUID,parthers:MutableList<Partner>):String{\r\n      var result=\"\"\r\n      if (parthers.isEmpty()) return result\r\n       parthers.forEach {\r\n          it.sons.forEach {uuid->\r\n              val person = persons.first { it.uuid == uuidFather }.sons.first {it.uuid == uuid }\r\n              result += \"\"\"\r\n                       ${it.name} sons\r\n              __________________________________    \r\n                       ${person.name}\r\n              __________________________________\r\n                    ${person.name}  Partners    \r\n              __________________________________                 \r\n             ${person.partner}\r\n              ___________________________________\r\n                      \r\n              \"\"\".trimIndent()\r\n            }\r\n\r\n      }\r\n      return result\r\n  }\r\n\r\n\r\n}\r\n\r\n\r\n\r\n\r\n\r\n//4.-Vamos a usar programacion funcional para modularizar algunas acciones de la clase FamilyTree\r\ncontext(PersonValidators)\r\nsuspend fun addFamilyMember(uuid: UUID)= coroutineScope{\r\n    val person = persons.first { it.uuid == uuid }\r\n    println(\"Who do you want to add? (P or S)\")\r\n    val confirm = readLine()?.let { it.uppercase() } ?: \"P\"\r\n    if (confirm == \"P\") {\r\n        launch {\r\n            val newPartners = registerPartner(::maxNumofPartners, person.partner.size)\r\n            person.partner.addAll(newPartners)\r\n        }\r\n    }\r\n\r\n    if (confirm == \"S\") {\r\n        launch {\r\n            val newSons = registerSons(::maxNumofSons, ::moreThanOneFather, person.sons.size)\r\n            person.sons.addAll(newSons)\r\n        }\r\n    }\r\n}\r\n\r\n\r\nsuspend fun registerPartner(maxPartner: suspend (Int)->Boolean, partnersSize:Int=0): MutableList<Partner>{\r\n    val partnerList = mutableListOf<Partner>()\r\n    var option = \"\"\r\n    while (option != \"N\") {\r\n        println(\"Enter partner name: \")\r\n        val wifeName = readLine() ?: \"\"\r\n        val partner = Partner(name = wifeName)\r\n        val numPartner=if (partnersSize>0) partnerList.size+partnersSize else partnerList.size\r\n        if (maxPartner(numPartner)) {\r\n            println(\"The person not have more than 3 partner\")\r\n            break\r\n        }\r\n        partnerList.add(partner)\r\n        println(\"The person have another partner ? (Y/N)\")\r\n        option = readLine()?.let { it.uppercase() } ?: \"N\"\r\n\r\n    }\r\n    return partnerList\r\n}\r\n\r\nsuspend fun registerSons(\r\n    \r\n    maxNumofSons: suspend (Int) -> Boolean,\r\n    moreThanOneFather: suspend (Person) -> Boolean,\r\n    oldSon:Int=0\r\n\r\n):MutableList<Person>{\r\n    val sonList = mutableListOf<Person>()\r\n    var option = \"\"\r\n    while (option != \"N\") {\r\n        println(\"Enter son name: \")\r\n        val sonName = readLine() ?: \"\"\r\n        val son=Person(name = sonName)\r\n        if (moreThanOneFather(son)) {\r\n            println(\"Your son have more than one father. please try again\")\r\n            continue\r\n        }\r\n        val numSons=if (oldSon>0) sonList.size+oldSon else sonList.size\r\n        if (maxNumofSons(numSons)){\r\n            println(\"The person not have more than 3 sons\")\r\n            break\r\n        }\r\n        sonList.add(son)\r\n        println(\"The person have another son? (Y/N)\")\r\n        option = readLine()?.let { it.uppercase() } ?: \"N\"\r\n\r\n    }\r\n    return sonList\r\n    \r\n}\r\n\r\n\r\nfun main() = runBlocking {\r\n    with(Validator()) {\r\n        with(DragonRecord()) {\r\n            val recordTree = RecordTree(FamilyTree())\r\n            recordTree.showMenu()\r\n       }\r\n\r\n    }\r\n}\r\n\r\n"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/php/miguelex.php",
    "content": "<?php\n\nclass Person {\n    private $id;\n    private $name;\n    private $partner;\n    private $children = [];\n\n    public function __construct($id, $name) {\n        $this->id = $id;\n        $this->name = $name;\n    }\n\n    public function getId() {\n        return $this->id;\n    }\n\n    public function getName() {\n        return $this->name;\n    }\n\n    public function setPartner($partner) {\n        $this->partner = $partner;\n    }\n\n    public function getPartner() {\n        return $this->partner;\n    }\n\n    public function addChild($child) {\n        $this->children[] = $child;\n    }\n\n    public function getChildren() {\n        return $this->children;\n    }\n}\n\nclass FamilyTree {\n    private $people = [];\n\n    public function addPerson($id, $name) {\n        $this->people[$id] = new Person($id, $name);\n    }\n\n    public function removePerson($id) {\n        unset($this->people[$id]);\n    }\n\n    public function setPartner($id1, $id2) {\n        if (isset($this->people[$id1]) && isset($this->people[$id2])) {\n            $this->people[$id1]->setPartner($this->people[$id2]);\n            $this->people[$id2]->setPartner($this->people[$id1]);\n        }\n    }\n\n    public function addChild($parentId, $childId) {\n        if (isset($this->people[$parentId]) && isset($this->people[$childId])) {\n            $this->people[$parentId]->addChild($this->people[$childId]);\n        }\n    }\n\n    public function printTree() {\n        foreach ($this->people as $person) {\n            if (!$this->hasParents($person)) {\n                $this->printSubTree($person);\n                echo \"\\n\";\n            }\n        }\n    }\n\n    private function printSubTree($person, $indent = 0) {\n        echo str_repeat(\" \", $indent) . $person->getName();\n        if ($person->getPartner()) {\n            echo \" ⟷ \" . $person->getPartner()->getName();\n        }\n        echo \"\\n\";\n\n        foreach ($person->getChildren() as $child) {\n            $this->printSubTree($child, $indent + 4);\n        }\n    }\n\n    private function hasParents($person) {\n        foreach ($this->people as $other) {\n            if (in_array($person, $other->getChildren())) {\n                return true;\n            }\n        }\n        return false;\n    }\n}\n\n$tree = new FamilyTree();\n$tree->addPerson(1, \"Aegon I Targaryen\");\n$tree->addPerson(2, \"Rhaenys Targaryen\");\n$tree->addPerson(3, \"Visenya Targaryen\");\n\n$tree->addPerson(4, \"Aenys I Targaryen\");\n$tree->addPerson(5, \"Maegor I Targaryen\");\n\n$tree->addPerson(6, \"Jaehaerys I Targaryen\");\n$tree->addPerson(7, \"Alysanne Targaryen\");\n\n$tree->addPerson(8, \"Aegon II Targaryen\");\n$tree->addPerson(9, \"Helaena Targaryen\");\n\n$tree->addPerson(10, \"Viserys II Targaryen\");\n\n$tree->addPerson(11, \"Rhaenyra Targaryen\");\n$tree->addPerson(12, \"Daemon Targaryen\");\n\n$tree->setPartner(1, 2); // Aegon I y Rhaenys\n$tree->setPartner(1, 3); // Aegon I y Visenya\n$tree->setPartner(4, 7); // Jaehaerys I y Alysanne\n$tree->setPartner(8, 9); // Aegon II y Helaena\n$tree->setPartner(11, 12); // Rhaenyra y Daemon\n\n$tree->addChild(1, 4); // Aenys I hijo de Aegon I y Rhaenys\n$tree->addChild(1, 5); // Maegor I hijo de Aegon I y Visenya\n\n$tree->addChild(4, 6); // Jaehaerys I hijo de Aenys I\n$tree->addChild(4, 11); // Rhaenyra hija de Aenys I\n\n$tree->addChild(6, 8); // Aegon II hijo de Jaehaerys I\n$tree->addChild(6, 10); // Viserys II hijo de Jaehaerys I\n\n$tree->printTree();\n"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/python/CesarCarmona30.py",
    "content": "'''\n  EJERCICIO\n'''\n\nclass Person:\n  \n  def __init__(self, id: int, name: str) -> None:\n    self.id = id\n    self.name = name\n    self.partner = None\n    self.children = []\n    self.has_parents = False\n\n  def add_partner(self, partner):\n    if self.partner is not None:\n      print(f'{self.name} ya tiene una pareja: {self.partner.name}.')\n    else:\n      self.partner = partner\n      partner.partner = self\n      print(f'{self.name} es pareja de: {partner.name}.')\n\n  def add_child(self, child):\n    if child not in self.children:\n      self.children.append(child)\n      print(f'{self.name} ha tenido un hijo: {child.name}.')\n    else:\n      print(f'{child.name} ya es hijo de {self.name}.')\n\nclass FamilyTree:\n\n  def __init__(self):\n    self.people = {}\n\n  def add_person(self, id, name):\n    if id in self.people:\n      print(f\"La persona con ID: {id} ya existe.\")\n    else:\n      person = Person(id, name)\n      self.people[id] = person\n      print(\n            f\"La persona con nombre {name} [ID: {id}] ha sido añadida al árbol.\")\n\n  def remove_person(self, id):\n    if id in self.people:\n      person = self.people[id]\n      del self.people[id]\n      print(\n            f\"La persona con nombre {person.name} [ID: {id}] ha sido eliminada del árbol.\")\n    else:\n      print(f\"La persona con ID: {id} no existe en el árbol.\")\n\n  def set_partner(self, id1, id2):\n    if id1 in self.people and id2 in self.people:\n      person1 = self.people[id1]\n      person2 = self.people[id2]\n      person1.add_partner(person2)\n    else:\n      print(\"Algún ID no existe en el árbol.\")\n\n  def add_child(self, parent_id, child_id):\n    if parent_id in self.people and child_id in self.people:\n      if parent_id == child_id:\n        print(\"Los ID no pueden ser iguales a la hora de asignar un hijo.\")\n      else:\n        parent = self.people[parent_id]\n        if parent.partner is None:\n          print(f\"Se necesita una pareja para poder tener un hijo.\")\n        else:\n          child = self.people[child_id]\n          if child.has_parents:\n            print(\n                  f\"{child.name} [ID: {child.id}] ya tiene padres.\")\n          else:\n            child.has_parents = True\n            parent.add_child(child)\n            parent.partner.add_child(child)\n    else:\n      print(\"Algún ID no existe en el árbol.\")\n\n  def print_tree(self):\n    visited = set()\n\n    def print_person(person, level=0):\n\n      if person.id in visited:\n        return\n\n      visited.add(person.id)\n      indent = \"\\t\" * level\n\n      print(f\"{indent} ├── {person.name} [ID: {person.id}]\")\n\n      if person.partner:\n        visited.add(person.partner.id)\n        print(\n              f\"{indent} \\t└──  Pareja: {person.partner.name} [ID: {person.partner.id}]\")\n\n      if person.children:\n        print(f\"{indent} \\t└──  Hijos:\")\n        for child in person.children:\n          print_person(child, level + 1)\n\n    for person in self.people.values():\n      is_child = person.has_parents\n      if not is_child:\n        print_person(person)\n\ntree = FamilyTree()\n\ntree.add_person(1, \"Jocelyn\")\ntree.add_person(2, \"Aemon\")\n\ntree.set_partner(1, 2)\n\ntree.add_person(3, \"Rhaenys\")\n\ntree.add_child(1, 3)\n\ntree.add_person(4, \"Corlys\")\n\ntree.set_partner(3, 4)\n\ntree.add_person(5, \"Laena\")\ntree.add_person(6, \"Laenor\")\n\ntree.add_child(3, 5)\ntree.add_child(3, 6)\n\ntree.add_person(7, \"Baelon\")\ntree.add_person(8, \"Alyssa\")\n\ntree.set_partner(7, 8)\n\ntree.add_person(9, \"Viserys I\")\ntree.add_person(10, \"Daemon\")\n\ntree.add_child(7, 9)\ntree.add_child(8, 10)\n\ntree.add_person(11, \"Aemma\")\n\ntree.set_partner(9, 11)\n\ntree.add_person(12, \"Rhaenyra\")\n\ntree.add_child(9, 12)\n\ntree.set_partner(10, 12)\n\ntree.add_person(13, \"Aegon\")\ntree.add_person(14, \"Viserys\")\n\ntree.add_child(12, 13)\ntree.add_child(12, 14)\n\ntree.print_tree()\n"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/python/EmmanuelMMontesinos.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * ¡La Casa del Dragón ha finalizado y no volverá hasta 2026! \n * ¿Alguien se entera de todas las relaciones de parentesco\n * entre personajes que aparecen en la saga?\n * Desarrolla un árbol genealógico para relacionarlos (o invéntalo).\n * Requisitos:\n * 1. Estará formado por personas con las siguientes propiedades:\n *    - Identificador único (obligatorio)\n *    - Nombre (obligatorio)\n *    - Pareja (opcional)\n *    - Hijos (opcional)\n * 2. Una persona sólo puede tener una pareja (para simplificarlo).\n * 3. Las relaciones deben validarse dentro de lo posible.\n *    Ejemplo: Un hijo no puede tener tres padres.\n * Acciones:\n * 1. Crea un programa que permita crear y modificar el árbol.\n *    - Añadir y eliminar personas\n *    - Modificar pareja e hijos\n * 2. Podrás imprimir el árbol (de la manera que consideres).\n * \n * NOTA: Ten en cuenta que la complejidad puede ser alta si\n * se implementan todas las posibles relaciones. Intenta marcar\n * tus propias reglas y límites para que te resulte asumible.\n */\n\"\"\"\n\nclass Personas:\n    numero_personas = 0\n    arbol = {}\n    \n    def __init__(self,nombre) -> None:\n        Personas.numero_personas += 1\n        self.id = Personas.numero_personas\n        self.nombre = nombre.lower()\n        self.pareja = None\n        self.padres = [None,None]\n        self.hijos = []\n        self.estado = True\n        self.asesino = None\n        Personas.arbol[self.nombre] = self\n\n    def mostrar_arbol(self):\n        print(\"---Arbol Moure---\")\n        for num, personas in enumerate(Personas.arbol.values()):\n            print(f\"{num} - {personas.nombre}\")\n\n    def matar_persona(self,asesino=None):\n        if asesino:\n            self.asesino = asesino.nombre\n        else:\n            self.asesino = \"forma natural\"\n\n        del Personas.arbol[self.nombre]\n        self.estado = False\n        print(f\"{self.nombre} ha muerto por {self.asesino}\")\n\n    def mostrar_datos(self):\n        if self.estado:\n            print(\"Vivo/a\")\n        else:\n            print(f\"Muerto/a por {self.asesino}\")\n        print(f\"ID: {self.id}\")\n        print(f\"Nombre: {self.nombre}\")\n        if self.pareja:\n            print(f\"Pareja: {self.pareja.nombre}\")\n        for padre in self.padres:\n            if padre != None:\n                print(f\"Progenitor: {padre.nombre}\")\n        if self.hijos:\n            print(\"Hijos:\")\n            for hijo in self.hijos:\n                print(f\"{hijo.nombre}\")\n        print()\n    def mostrar_pareja(self):\n        print(f\"{self.nombre} esta actualmente casado/a con {self.pareja.nombre}\")\n    \n    def tener_hijos(self,hijo):\n        if hijo.padres[0] == None:\n            hijo.padres[0] = self\n            self.hijos.append(hijo)\n        elif hijo.padres[1] == None:\n            hijo.padres[1] = self\n            self.hijos.append(hijo)\n\n\n    def cambiar_pareja(self,pareja,ambos=False):\n        self.pareja = None\n        self.pareja = pareja\n        if ambos:\n            pareja.cambiar_pareja(self)\n\n        print(f\"Cambio realizado: {self.nombre} casado/a con {self.pareja.nombre}\")\n\n    def casamiento(self,pareja):\n        if self.pareja and pareja.pareja:\n            self.mostrar_pareja()\n            pareja.mostrar_pareja()\n            cambio = input(f\"Quiere cambiar la pareja a {pareja.nombre}\\n1-Si 2-No: \")\n            match cambio:\n                case \"1\":\n                    self.cambiar_pareja(pareja,ambos=True)\n\n                case \"2\":\n                    print(\"Cambio cancelado\")\n        elif self.pareja or pareja.pareja:\n            if self.pareja:\n                self.mostrar_pareja()\n                cambio = input(f\"Quiere cambiar la pareja a {pareja.nombre}\\n1-Si 2-No: \")\n                match cambio:\n                    case \"1\":\n                        self.cambiar_pareja(pareja)\n\n                    case \"2\":\n                        print(\"Cambio cancelado\")\n            else:\n                pareja.mostrar_pareja()\n                cambio = input(f\"Quiere cambiar la pareja a {self.nombre}\\n1-Si 2-No: \")\n                match cambio:\n                    case \"1\":\n                        self.cambiar_pareja(pareja,ambos=True)\n\n                    case \"2\":\n                        print(\"Cambio cancelado\")\n        else:\n            self.cambiar_pareja(pareja,ambos=True)\n\nclass Consola:\n    def bucle(self):\n        salir = False\n        while not salir:\n            print(\"1-Añadir pj 2-Añadir pareja a pj 3-Añadir hijo a pj 4- Matar pj 5-Mostrar_datos 6-Salir:\")\n            seleccion = input(\"\")\n            match seleccion:\n                case \"1\":\n                    self.add_pj()\n                    \n                case \"2\":\n                    self.add_pareja()\n                    \n                case \"3\":\n                    self.add_hijo()\n                    \n                case \"4\":\n                    self.matar()\n\n                case \"5\":\n                    self.mostrar_datos()\n                    \n                case \"6\":\n                    salir = True\n\n    def mostrar_datos(self):\n        self.mostrar_arbol()\n        try:\n            seleccion = input(\"Nombre: \")\n            nombre = Personas.arbol[seleccion.lower()]\n            nombre.mostrar_datos()\n        except Exception as e:\n            print(f\"Error: {e}\")\n                \n    def add_pj(self):\n        nombre = input(\"Nombre: \")\n        pj = Personas(nombre.lower())\n        print(f\"{pj.nombre} añadido al arbol\")\n    \n    def add_pareja(self):\n        self.mostrar_arbol()\n        try:\n            seleccion_1 = input(\"Nombre del primer pj: \")\n            pj_1 = Personas.arbol[seleccion_1.lower()]\n\n            seleccion_2 = input(\"Nombre del segundo pj: \")\n            pj_2 = Personas.arbol[seleccion_2.lower()]\n\n            pj_1.casamiento(pj_2)\n        except Exception as e:\n            print(f\"Error: {e}\")\n\n    def add_hijo(self):\n        self.mostrar_arbol()\n        try:\n            padre = input(\"Nombre del padre: \")\n            padre = Personas.arbol[padre.lower()]\n\n            hijo = input(\"Nombre del hijo: \")\n            hijo = Personas.arbol[hijo.lower()]\n        except Exception as e:\n            print(f\"Error: {e}\")\n    def matar(self):\n        self.mostrar_arbol()\n        try:\n            victima = input(\"Nombre víctima\")\n            victima = Personas.arbol[victima.lower()]\n            asesino = input(\"Nombre asesino(enter si es por forma natural)\")\n            if asesino:\n                victima.matar_persona(asesino=asesino)\n            else:\n                victima.matar_persona()\n        except Exception as e:\n            print(f\"Error: {e}\")\n\n    def mostrar_arbol(self):\n        Personas.mostrar_arbol(Personas)\n\n# Pruebas\n\n# Creación de personajes\nned = Personas(\"Ned Stark\")\ncatelyn = Personas(\"Catelyn Stark\")\njon = Personas(\"Jon Snow\")\narya = Personas(\"Arya Stark\")\nsansa = Personas(\"Sansa Stark\")\nbran = Personas(\"Bran Stark\")\nrobb = Personas(\"Robb Stark\")\nrickon = Personas(\"Rickon Stark\")\ntyrion = Personas(\"Tyrion Lannister\")\ndaenerys = Personas(\"Daenerys Targaryen\")\n\n# Matrimonios\ndaenerys.casamiento(tyrion)\nned.casamiento(catelyn)\n\n# Hijos\ncatelyn.tener_hijos(arya)\ncatelyn.tener_hijos(sansa)\nned.tener_hijos(robb)\nned.tener_hijos(bran)\nned.tener_hijos(rickon)\n\n# Eliminar personajes\nned.matar_persona(tyrion)\ncatelyn.matar_persona(daenerys)\n\n# Mostrar datos\nned.mostrar_datos()\ncatelyn.mostrar_datos()\narya.mostrar_datos()\njon.mostrar_datos()\nsansa.mostrar_datos()\nbran.mostrar_datos()\nrobb.mostrar_datos()\nrickon.mostrar_datos()\ntyrion.mostrar_datos()\ndaenerys.mostrar_datos()\n\n# Mostrar Arbol actual\nPersonas.mostrar_arbol(Personas)\n\nconsola = Consola()\nconsola.bucle()"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/python/Gordo-Master.py",
    "content": "# 34 - Arbol Genealogico de la casa del dragon\n\nclass Person():\n\n    def __init__(self, id: int, name: str):\n        self.id = id\n        self.name = name\n        self.partner = None\n        self.children = []\n        self.has_parents = False\n        self.father = None\n        self.mother = None\n\n    def add_partner(self, partner):\n        if self.partner is not None:\n            print(f\"{self.name} ya tiene pareja ({self.partner.name})\")\n        elif partner.partner is not None:\n            print(f\"{partner.name} ya tiene pareja ({partner.partner.name})\")\n        else:\n            self.partner = partner\n            partner.partner = self\n            print(f\"{self.name} es pareja de {self.partner.name}\")\n\n    def add_child(self, child):\n        if child not in self.children:\n            self.children.append(child)\n            print(f\"{self.name} ha tenido un hijo: {child.name}\")\n        else:    \n            print(f\"{child.name} ya esta registrado como hijo de {self.name}\")\n\n    def add_parent(self, father, mother):\n        if father is None and mother is None:\n            self.father = father\n            self.mother = mother\n            self.has_parents = True\n        # else:\n        #     print(f\"{self.name} ya tiene padres añadidos: {self.father}, {self.mother}\")\n\nclass FamilyTree():\n\n    def __init__(self):\n        self.people = {}\n\n    def add_person(self,id, name):\n        if id in self.people:\n            print(f\"Ya se encuentra una persona con ID:{id}\")\n        elif name in self.people.values():\n            print(f\"Ya se encuentra una persona con el nombre: {name}\")\n        else:\n            person = Person(id, name)\n            self.people[id] = person\n            print(f\"La persona de nombre: {name} con ID: {id} ha sido añadida a la lista\")\n        \n    def remove_person(self, id):\n        if id in self.people:\n            person = self.people[id]\n            del self.people[id]\n            print(f\"La persona: {person.name} con ID:{id} ha sido removido del arbol familiar\")\n        else:\n            print(f\"No existe una persona con ID:{id}\")\n\n    def set_partner(self, id_1, id_2):\n        if id_1 in self.people and id_2 in self.people:\n            person_1 = self.people[id_1]\n            person_2 = self.people[id_2]\n            person_1.add_partner(person_2)\n        else:\n            print(\"Alguno de los ID no se encuentran en la lista\")\n        \n\n    def add_child(self, id_parent, id_child):\n        if id_parent in self.people and id_child in self.people:\n            if id_parent == id_child:\n                print(\"No pueden tener el mismo ID\")\n            else:\n                parent = self.people[id_parent]\n                if parent.partner is None:\n                    print(f\"{parent.name} debe tener pareja para tener un hijo\")\n                else:\n                    child = self.people[id_child]\n                    if child.has_parents:\n                        print(\n                            f\"ID: {child.id} ya tiene padres!\")\n                    else:\n                        parent.add_child(child)\n                        parent.partner.add_child(child)\n                        child.add_parent(parent, parent.partner)\n        else:\n            print(\"Alguno de los ID no se encuentran en la lista\")\n\n    def print_tree(self):\n\n        visited = set()\n\n        def print_person(person: Person, level =0):\n\n            if person.id in visited:\n                return\n            \n            visited.add(person.id)\n\n            indent = \" \"*4*level\n\n            print(f\"{indent}-{person.name} [ID]: {person.id}\")\n\n            if person.partner:\n                visited.add(person.partner.id)\n                print(\n                    f\"{indent} Pareja: {person.partner.name} [ID]: {person.partner.id}\"\n                )\n            \n            if person.children:\n                print(f\"{indent} Hijos:\")\n                for child in person.children:\n                    print_person(child, level+1)\n        \n        for person in self.people.values():\n            is_child = person.has_parents\n            if not is_child:\n                print_person(person)\n\ntree = FamilyTree()\n\n\ntree.add_person(1, \"Jocelyn\")\ntree.add_person(2, \"Aemon\")\n\ntree.set_partner(1, 2)\n\ntree.add_person(3, \"Rhaenys\")\n\ntree.add_child(1, 3)\n\ntree.add_person(4, \"Corlys\")\n\ntree.set_partner(3, 4)\n\ntree.add_person(5, \"Laena\")\ntree.add_person(6, \"Laenor\")\n\ntree.add_child(3, 5)\ntree.add_child(3, 6)\n\ntree.add_person(7, \"Baelon\")\ntree.add_person(8, \"Alyssa\")\n\ntree.set_partner(7, 8)\n\ntree.add_person(9, \"Viserys I\")\ntree.add_person(10, \"Daemon\")\n\ntree.add_child(7, 9)\ntree.add_child(8, 10)\n\ntree.add_person(11, \"Aemma\")\n\ntree.set_partner(9, 11)\n\ntree.add_person(12, \"Rhaenyra\")\n\ntree.add_child(9, 12)\n\ntree.set_partner(10, 12)\n\ntree.add_person(13, \"Aegon\")\ntree.add_person(14, \"Viserys\")\n\ntree.add_child(12, 13)\ntree.add_child(12, 14)\n\ntree.print_tree()\n"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/python/JesusWay69.py",
    "content": "import os, platform, json\n\nif (platform.platform().startswith(\"macOS\") or platform.platform().startswith(\"Linux\")):\n    os.system('clear')\nelse:\n    os.system('cls')\n\n    \"\"\" * EJERCICIO:\n    * ¡La Casa del Dragón ha finalizado y no volverá hasta 2026!\n    * ¿Alguien se entera de todas las relaciones de parentesco\n    * entre personajes que aparecen en la saga?\n    * Desarrolla un árbol genealógico para relacionarlos (o invéntalo).\n    * Requisitos:\n    * 1. Estará formado por personas con las siguientes propiedades:\n    *    - Identificador único (obligatorio)\n    *    - Nombre (obligatorio)\n    *    - Pareja (opcional)\n    *    - Hijos (opcional)\n    * 2. Una persona sólo puede tener una pareja (para simplificarlo).\n    * 3. Las relaciones deben validarse dentro de lo posible.\n    *    Ejemplo: Un hijo no puede tener tres padres.\n    * Acciones:\n    * 1. Crea un programa que permita crear y modificar el árbol.\n    *    - Añadir y eliminar personas\n    *    - Modificar pareja e hijo\n    * 2. Podrás imprimir el árbol (de la manera que consideres).\n    * \n    * NOTA: Ten en cuenta que la complejidad puede ser alta si\n    * se implementan todas las posibles relaciones. Intenta marcar\n    * tus propias reglas y límites para que te resulte asumible.\"\"\"\n\n\n    \ndef create_dict(id:int, name:str, spouse:str=\"\", children:list=[])->dict:\n    character:dict = {}\n    character_value:dict = {}\n    character[id] = character_value\n    character_value[\"Nombre\"] = name\n    character_value[\"Pareja\"] = spouse\n    character_value[\"Hijos\"] = children\n    return character\n\ndef print_json_contain(file:str):\n        with open(file) as contains:\n            json_load:list = json.load(contains)\n        for element in  json_load:\n            print(element)\n\ndef get_json_contain(file:str)->list:\n    with open(file, 'r') as contains:\n            json_load = json.load(contains)\n    return json_load\n\ndef create_file_json(file:str, json_root:list):\n        with open(file, 'w') as create_json:\n           json.dump(json_root,create_json, indent=4, sort_keys=False)\n\ndef print_family_tree(file:str):\n    with open(file, 'r') as contains:\n        json_load:list = json.load(contains)\n\n    for i in range(len(json_load)):\n        name = list(json_load[i].values())[0][\"Nombre\"]\n        spouse = list(json_load[i].values())[0][\"Pareja\"]\n        children = list(json_load[i].values())[0][\"Hijos\"]\n        print(f\"\\n----- Nombre: {name} ---------------------- Pareja: {spouse} -----\")\n        print(\"------- Hijos: \", end = '------  ')\n        for j in range(len(children)):\n            child = children[j]\n            if j < len(children) - 1:\n                print(f\"\\b{child}\", end=',  ')\n            else:\n                print(f\"\\b\\b {child} ------\")\n        \n\n########      FICHERO ORIGINAL     ########\nmy_path:str = r\"C:\\Users\\jesus\\Documents\\Python3project\\roadmap_python\\#34 - HOUSE OF THE DRAGON\\\\\"\nfile:str = my_path + \"family_tree.json\"\n\nwhile True:\n    print(\"\"\"\\nElija una opción:\n          0 - Crear nuevo fichero o borrar contenido de fichero ya existente\n          1 - Añadir personaje\n          2 - Eliminar personaje\n          3 - Modificar pareja\n          4 - Añadir hijo\n          5 - Imprimir árbol genealógico y salir\n\"\"\")\n    \n    option = input(\"Introduzca un número del 1 al 5: \")\n    if not option.isdigit():\n        print(\"Sólo se pueden introducir números del 1 al 5, intente de nuevo\")\n        continue\n    else:\n        option = int(option)\n    match option: \n        case 0:\n            new_file = input(\"Introduzca el nombre del nuevo fichero json sin extensión, si el fichero ya existe se borrará todo su contenido: \")\n            my_path:str = r\"C:\\Users\\jesus\\Documents\\Python3project\\roadmap_python\\#34 - HOUSE OF THE DRAGON\\\\\"\n            file:str = my_path + new_file + \".json\"\n            json_root:list = []\n            create_file_json(file, json_root)\n        \n        case 1: \n            json_root:list = get_json_contain(file)\n            if len(json_root)>0: \n                last_dict:dict = json_root[len(json_root)-1] \n                print(last_dict)\n                list_key = list(last_dict.keys())\n                id = int(list_key[0])\n            else:\n                id=0\n\n            children =[]\n            id +=1\n            name:str = input(\"Escriba el nombre del personaje: \").title()\n            spouse:str = input(\"Escriba el nombre de la pareja del personaje si tiene, si no pulse enter: \").title()\n            if spouse == \"\" :\n                spouse = None\n            son:str = None\n            while son != \"\":\n                son = input(\"Escriba el nombre de un hijo del personaje, si no tiene o ya ha escrito todos pulse enter: \").title()\n                children.append(son)\n            del children[len(children)-1] \n            json_root.append(create_dict(id, name, spouse, children))\n            if spouse != None:\n                json_root.append(create_dict(id+1, spouse, name, children))                     \n            create_file_json(file, json_root)\n            \n        case 2:\n            id_del:str = input(\"escriba el id del personaje a eliminar: \")\n            json_data:list = get_json_contain(file)                                                              \n            for row in json_data:              \n                if id_del in row:\n                    json_data.remove(row)\n                    print(f\"El personaje {row[id_del][\"Nombre\"]} se ha eliminado correctamnete\")\n                    create_file_json(file, json_data)\n                    continue\n            print(f\"El id {id_del} no corresponde a ningún personaje, pruebe de nuevo.\")\n            \n        case 3:\n            id_mod:str = input(\"Escriba el id del personaje cuya pareja se va a editar: \")\n            json_data:list = get_json_contain(file)                               \n            for row in json_data:              \n                if id_mod in row:\n                    print(f\"La pareja actual de {row[id_mod][\"Nombre\"]} es {row[id_mod][\"Pareja\"]}\")\n                    new_spouse:str = input(f\"Escriba el nombre de la nueva pareja de {row[id_mod][\"Nombre\"]}: \").capitalize()\n                    row[id_mod][\"Pareja\"] = new_spouse\n            create_file_json(file, json_data)      \n                    \n        case 4:\n            id_add_child:str = input(\"Escriba el id del personaje cuyo hijo se va a añadir: \")\n            json_data:list = get_json_contain(file)                              \n            for row in json_data:              \n                if id_add_child in row:\n                    print(f\"Los hijos de {row[id_add_child][\"Nombre\"]} y {row[id_add_child][\"Pareja\"]} son {row[id_add_child][\"Hijos\"]}\")\n                    new_child = input(f\"Escriba el nombre del nuevo/a hijo/a de {row[id_add_child][\"Nombre\"]} y {row[id_add_child][\"Pareja\"]}: \").capitalize()\n                    row[id_add_child][\"Hijos\"].append(new_child)\n            create_file_json(file, json_data)\n\n        case 5:\n            print_family_tree(file)\n            break\n\n        case _:\n            print(\"Sólo se pueden introducir números del 1 al 5, intente de nuevo\")\n\n\n\n#Salida de print_family_tree() tras incorporar los datos de los personajes de la serie y recuperarlos desde un fichero json \n\n\"\"\"\n----- Nombre: Jocelyn Baratheon ---------------------- Pareja: Aemon Targaryen -----\n------- Hijos: ------ Rhaenys Targaryen ------\n\n----- Nombre: Aemon Targaryen ---------------------- Pareja: Jocelyn Baratheon -----\n------- Hijos: ------ Rhaenys Targaryen ------\n\n----- Nombre: Daella Targaryen ---------------------- Pareja: Rodrik Arryn -----\n------- Hijos: ------ Aemma Arryn ------\n\n----- Nombre: Rodrik Arryn ---------------------- Pareja: Daella Targaryen -----\n------- Hijos: ------ Aemma Arryn ------\n\n----- Nombre: Baelon I Targaryen ---------------------- Pareja: Alissa Targaryen -----\n------- Hijos: ------ Viserys I Targaryen, Daemon Targaryen ------\n\n----- Nombre: Alissa Targaryen ---------------------- Pareja: Baelon I Targaryen -----\n------- Hijos: ------ Viserys I Targaryen, Daemon Targaryen ------\n\n----- Nombre: Otto Hightower ---------------------- Pareja: None -----\n------- Hijos: ------ Alicent Hightower, Gwayne Higthtower ------\n\n----- Nombre: Alicent Hightower ---------------------- Pareja: Viserys I Targaryen -----\n------- Hijos: ------ Aegon II Targaryen, Helaena Targaryen, Aemond Targaryen, Daeron targaryen ------\n\n----- Nombre: Viserys I Targaryen ---------------------- Pareja: Alicent Hightower -----\n------- Hijos: ------ Aegon II Targaryen, Helaena Targaryen, Aemond Targaryen, Daeron targaryen ------      \n\n----- Nombre: Aemma Arryn ---------------------- Pareja: Viserys I Targaryen -----\n------- Hijos: ------ Rhaenyra Targaryen ------\n\n----- Nombre: Corlys Velaryon ---------------------- Pareja: Rhaenys Targaryen -----\n------- Hijos: ------ Laena Velaryon, Laenor Velaryon ------\n\n----- Nombre: Rhaenys Targaryen ---------------------- Pareja: Corlys Velarion -----\n------- Hijos: ------ Laena Velaryon, Laenor Velaryon ------\n\n----- Nombre: Rhaenyra Targaryen ---------------------- Pareja: Laenor Velaryon -----\n------- Hijos: ------ Jacaerys Velaryon, Lucerys Velaryon, Joffrey Velaryon ------\n\n----- Nombre: Laenor Velaryon ---------------------- Pareja: Rhaenyra Targaryen -----\n------- Hijos: ------ Jacaerys Velaryon, Lucerys Velaryon, Joffrey Velaryon ------\n\n----- Nombre: Laena Velaryon ---------------------- Pareja: Daemon Targaryen -----\n------- Hijos: ------ Baela Targaryen, Rhaena Targaryen ------\n\n----- Nombre: Daemon Targaryen ---------------------- Pareja: Laena Velaryon -----\n------- Hijos: ------ Baela Targaryen, Rhaena Targaryen ------\n\"\"\"\n\n\n\n\n\n\n\n\n\n\n    \n\n"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/python/JohnAlexGuerrero.py",
    "content": "'''\nOriginal file is located at\n    https://colab.research.google.com/drive/1WALB50MrWbmuH-8tQuNXw4bC2UJEqNha\n\n/*\n * EJERCICIO:\n * ¡La Casa del Dragón ha finalizado y no volverá hasta 2026!\n * ¿Alguien se entera de todas las relaciones de parentesco\n * entre personajes que aparecen en la saga?\n * Desarrolla un árbol genealógico para relacionarlos (o invéntalo).\n * Requisitos:\n * 1. Estará formado por personas con las siguientes propiedades:\n *    - Identificador único (obligatorio)\n *    - Nombre (obligatorio)\n *    - Pareja (opcional)\n *    - Hijos (opcional)\n * 2. Una persona sólo puede tener una pareja (para simplificarlo).\n * 3. Las relaciones deben validarse dentro de lo posible.\n *    Ejemplo: Un hijo no puede tener tres padres.\n * Acciones:\n * 1. Crea un programa que permita crear y modificar el árbol.\n *    - Añadir y eliminar personas\n *    - Modificar pareja e hijo\n * 2. Podrás imprimir el árbol (de la manera que consideres).\n *\n * NOTA: Ten en cuenta que la complejidad puede ser alta si\n * se implementan todas las posibles relaciones. Intenta marcar\n * tus propias reglas y límites para que te resulte asumible.\n */\n'''\n\nimport uuid\n\n#clase familia\nclass Familia:\n  def __init__(self, apellido):\n    self.apellido = apellido\n    self.miembros = []\n    self.id = str(uuid.uuid4())\n\n  def agregar_miembro(self, miembro):\n    self.miembros.append(miembro)\n\n  def total_miembros(self):\n    return len(self.miembros)\n\n  def parentesco(self, afinidad, person):\n    self.relaciones[afinidad].append(person)\n\n#clase person\nclass Person(Familia):\n  def __init__(self, nombre, apellido_paterno, apellido_materno, edad, sexo, vivo):\n    super().__init__(apellido_paterno)\n    self.nombre = nombre\n    self.apellido_paterno = apellido_paterno\n    self.apellido_materno = apellido_materno\n    self.edad = edad\n    self.sexo = sexo\n    self.vivo = vivo\n    self.relaciones = {\n        \"padre\":[],\n        \"madre\":[],\n        \"hijos\":[],\n        \"esposas\":[],\n        \"hijas\":[],\n        \"hermanos\":[]\n    }\n    self.id = str(uuid.uuid4())\n\n  def vive(self, estado):\n    self.vivo = estado\n\n  def informacion_personal(self):\n    data = {\n        \"nombres\":self.nombre,\n        \"primer apellido\":self.apellido_paterno,\n        \"segundo apellido\":self.apellido_materno,\n        \"edad\":self.edad,\n        \"sexo\":self.sexo,\n        \"vive\": \"vive\" if self.vivo == 1 else \"muerto\",\n        \"hijos\": [f'{h.nombre} {h.apellido_paterno}' for h in self.relaciones['hijos']],\n        \"esposas\": [f'{e.nombre} {e.apellido_paterno}' for e in self.relaciones['esposas']],\n        \"hermanos\": [f'{her.nombre} {her.apellido_paterno}' for her in self.relaciones['hermanos']],\n\n    }\n    return data\n\ntitle_header = '''\n    HOUSE OF THE DRAGON\n  =======================\n    Familia TARGARYEN\n  =======================\n'''\n\n#primer rey the conquest\np1 = Person('aergon','targaryen','',23,'hombre',1)\np1.agregar_miembro(p1)\n#hermanas\np2 = Person('rhaenys','targaryen','',19,'mujer',1)\np3 = Person('visenya','targaryen','',19,'mujer',1)\np1.parentesco('hermanos',p2)\np1.parentesco('hermanos',p3)\np1.agregar_miembro(p2)\np1.agregar_miembro(p3)\n#esposas\np1.parentesco('esposas',p2)\np1.parentesco('esposas',p3)\n\n#hijos con rhaenys targaryen\np4 = Person('aenys I','targaryen','',19,'hombre',1)\np1.parentesco('hijos', p4)\np4.parentesco('madre',p2)\np1.agregar_miembro(p4)\n#esposa de aenys I targaryen\np6 = Person('alyssa','velaryon','',16,'mujer',1)\np4.parentesco('esposas',p6)\np1.agregar_miembro(p6)\n#hijos de aenys I targaryen y alyssa velaryon\np7 = Person('rhaena','targaryen','velaryon',18,'mujer',1)\np8 = Person('aegon','targaryen','velaryon',16,'hombre',0)\np9 = Person('viserys','targaryen','velaryon',14,'hombre',0)\np10 = Person('jaehaerys I','targaryen','velaryon',14,'hombre',1)\np11 = Person('alysanne','targaryen','velaryon',15,'mujer',1)\nfor hijo in [p7,p8,p9,p10,p10]:\n  p4.parentesco('hijos', hijo)\n  p6.parentesco('hijos', hijo)\n  hijo.parentesco('padre', p4)\n  hijo.parentesco('madre', p6)\n  p1.agregar_miembro(hijo)\n\n#hermanos\nhijos = [p7,p8,p9,p10,p10]\nfor person in hijos:\n  for hermano in hijos:\n    if person != hermano:\n      person.parentesco('hermanos',hermano)\n    else:\n      continue\n\n#esposa de jaehaerys I targaryen\np10.parentesco('esposas',p11)\np1.agregar_miembro(p10)\n#hijos d ejaehaerys I targaryen y alysanne targaryen velaryon\n\n#hijos con visenya targaryen\np5 = Person('maegob I','targaryen','',19,'hombre',1)\np1.parentesco('hijos',p5)\np5.parentesco('madre',p3)\np1.agregar_miembro(p5)\n\nprint(title_header)\np1.informacion_personal()\n\np1.total_miembros()\n"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/python/Juanppdev.py",
    "content": "\"\"\"\n * EJERCICIO:\n * ¡La Casa del Dragón ha finalizado y no volverá hasta 2026! \n * ¿Alguien se entera de todas las relaciones de parentesco\n * entre personajes que aparecen en la saga?\n * Desarrolla un árbol genealógico para relacionarlos (o invéntalo).\n * Requisitos:\n * 1. Estará formado por personas con las siguientes propiedades:\n *    - Identificador único (obligatorio)\n *    - Nombre (obligatorio)\n *    - Pareja (opcional)\n *    - Hijos (opcional)\n * 2. Una persona sólo puede tener una pareja (para simplificarlo).\n * 3. Las relaciones deben validarse dentro de lo posible.\n *    Ejemplo: Un hijo no puede tener tres padres.\n * Acciones:\n * 1. Crea un programa que permita crear y modificar el árbol.\n *    - Añadir y eliminar personas\n *    - Modificar pareja e hijos\n * 2. Podrás imprimir el árbol (de la manera que consideres).\n * \n * NOTA: Ten en cuenta que la complejidad puede ser alta si\n * se implementan todas las posibles relaciones. Intenta marcar\n * tus propias reglas y límites para que te resulte asumible.\n\"\"\"\n\nclass Persona:\n    def __init__(self, id, nombre, pareja=None):\n        self.id = id\n        self.nombre = nombre\n        self.pareja = pareja\n        self.hijos = []\n\n    def añadir_hijo(self, hijo):\n        self.hijos.append(hijo)\n\n    def __str__(self):\n        pareja_nombre = self.pareja.nombre if self.pareja else \"Ninguna\"\n        hijos_nombres = \", \".join([hijo.nombre for hijo in self.hijos]) if self.hijos else \"Ninguno\"\n        return f\"ID: {self.id}, Nombre: {self.nombre}, Pareja: {pareja_nombre}, Hijos: {hijos_nombres}\"\n\nclass ArbolGenealogico:\n    def __init__(self):\n        self.personas = {}\n\n    def añadir_persona(self, id, nombre):\n        if id in self.personas:\n            print(\"ID ya existe.\")\n        else:\n            self.personas[id] = Persona(id, nombre)\n\n    def eliminar_persona(self, id):\n        if id in self.personas:\n            del self.personas[id]\n        else:\n            print(\"ID no encontrado.\")\n\n    def modificar_pareja(self, id, pareja_id):\n        if id in self.personas and pareja_id in self.personas:\n            self.personas[id].pareja = self.personas[pareja_id]\n        else:\n            print(\"ID no encontrado.\")\n\n    def añadir_hijo(self, id, hijo_id):\n        if id in self.personas and hijo_id in self.personas:\n            self.personas[id].añadir_hijo(self.personas[hijo_id])\n        else:\n            print(\"ID no encontrado.\")\n\n    def imprimir_arbol(self):\n        for persona in self.personas.values():\n            print(persona)\n\ndef menu():\n    arbol = ArbolGenealogico()\n    while True:\n        print(\"\\nMenú:\")\n        print(\"1. Añadir persona\")\n        print(\"2. Eliminar persona\")\n        print(\"3. Modificar pareja\")\n        print(\"4. Añadir hijo\")\n        print(\"5. Imprimir árbol\")\n        print(\"6. Salir\")\n        opcion = input(\"Selecciona una opción: \")\n\n        if opcion == \"1\":\n            id = input(\"ID: \")\n            nombre = input(\"Nombre: \")\n            arbol.añadir_persona(id, nombre)\n        elif opcion == \"2\":\n            id = input(\"ID: \")\n            arbol.eliminar_persona(id)\n        elif opcion == \"3\":\n            id = input(\"ID: \")\n            pareja_id = input(\"ID de la pareja: \")\n            arbol.modificar_pareja(id, pareja_id)\n        elif opcion == \"4\":\n            id = input(\"ID: \")\n            hijo_id = input(\"ID del hijo: \")\n            arbol.añadir_hijo(id, hijo_id)\n        elif opcion == \"5\":\n            arbol.imprimir_arbol()\n        elif opcion == \"6\":\n            break\n        else:\n            print(\"Opción no válida.\")\n\n# if __name__ == \"__main__\":\n#     menu()\n\nif __name__ == \"__main__\":\n    arbol = ArbolGenealogico()\n    arbol.añadir_persona(\"1\", \"Rhaenyra Targaryen\")\n    arbol.añadir_persona(\"2\", \"Daemon Targaryen\")\n    arbol.añadir_persona(\"3\", \"Alicent Hightower\")\n    arbol.modificar_pareja(\"1\", \"2\")  # Rhaenyra y Daemon son pareja\n    arbol.añadir_persona(\"4\", \"Jacaerys Velaryon\")\n    arbol.añadir_hijo(\"1\", \"4\")  # Jacaerys es hijo de Rhaenyra\n    arbol.imprimir_arbol()\n\n"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/python/MelonConYogurt.py",
    "content": "class Arbol:\r\n    def __init__(self)-> list:\r\n        self.data = []\r\n\r\n    def nueva_persona(self, nombre: str, pareja: str = None, hijos: list[str] = None) -> bool:\r\n        try:\r\n            if self.verificar_existencia(nombre):\r\n                print(f\"Error: La persona con el nombre '{nombre}' ya existe.\")\r\n                return False\r\n            \r\n            if pareja == nombre:\r\n                print(\"La pareja debe ser diferente a tu mismo nombre\")\r\n                return False\r\n            elif self.verificar_pareja(pareja) >= 1:\r\n                print(f\"Error: La pareja '{pareja}' ya está asociada a más de una persona.\")\r\n                return False\r\n            \r\n            if hijos:\r\n                for hijo in hijos:\r\n                    if hijo == nombre or hijo == pareja:\r\n                        print(\"Tu mismo o tu pareja no puede ser tu hijo\")\r\n                        return False\r\n                if self.verificar_hijos(hijos):\r\n                    print(f\"Error: Uno o más hijos ya existen en el sistema.\")\r\n                    return False\r\n\r\n            persona = {\r\n                \"id\": len(self.data),\r\n                \"nombre\": nombre,\r\n                \"pareja\": pareja if pareja else \"\",\r\n                \"hijos\": hijos if hijos else [] \r\n            }\r\n            \r\n            self.data.append(persona)\r\n    \r\n            print(f\"Persona agregada al árbol familiar:\\n\\n\"\r\n                  f\"ID: {persona['id']}\\n\"\r\n                  f\"Nombre: {nombre}\\n\"\r\n                  f\"Pareja: {pareja if pareja else 'N/A'}\\n\"\r\n                  f\"Hijos: {', '.join(hijos) if hijos else 'Ninguno'}\\n\")\r\n        \r\n            return True\r\n        except Exception as e:\r\n            print(f\"Error al agregar la persona: {e}\")\r\n            return False\r\n\r\n    def verificar_existencia(self, nombre: str) -> bool:\r\n        for person in self.data:\r\n            if person[\"nombre\"] == nombre:\r\n                return True\r\n        return False\r\n\r\n    def verificar_pareja(self, nombre: str) -> int:\r\n        numero_coincidencias = 0\r\n        for person in self.data:\r\n            if person[\"pareja\"] == nombre:\r\n                numero_coincidencias += 1\r\n        return numero_coincidencias\r\n\r\n    def verificar_hijos(self, hijos: list[str]) -> bool:\r\n        numero_coincidencias = 0\r\n        for hijo in hijos:\r\n            for person in self.data:\r\n                if hijo in person[\"hijos\"]:\r\n                    numero_coincidencias += 1\r\n            if numero_coincidencias >= 2:\r\n                print(f\"El hijo '{hijo}' ya tiene sus dos padres\")\r\n                return True\r\n            \r\n            numero_coincidencias = 0\r\n        return False\r\n\r\n    def eliminar_persona(self, nombre: str) -> bool:\r\n        try:\r\n            persona_a_eliminar = next((person for person in self.data if person[\"nombre\"] == nombre), None)\r\n            if persona_a_eliminar:\r\n                self.data.remove(persona_a_eliminar)\r\n                print()\r\n                print(f\"Persona '{nombre}' eliminada del árbol familiar.\")\r\n                print()\r\n                return True\r\n            else:\r\n                print(f\"Error: La persona con el nombre '{nombre}' no se encuentra en el árbol.\")\r\n                return False\r\n        except Exception as e:\r\n            print(f\"Error al eliminar la persona: {e}\")\r\n            return False\r\n\r\n    def editar_persona(self, nombre: str, pareja: str = None, hijos: list[str] = None) -> bool:\r\n        try:\r\n            persona_para_actualizar = next((person for person in self.data if person[\"nombre\"] == nombre), None)\r\n            \r\n            if not persona_para_actualizar:\r\n                print(f\"Error: La persona con el nombre '{nombre}' no se encuentra en el árbol.\")\r\n                return False\r\n            \r\n            if pareja:\r\n                if pareja == nombre:\r\n                    print(\"La pareja debe ser diferente a tu mismo nombre.\")\r\n                    return False\r\n                elif self.verificar_pareja(pareja) >= 1:\r\n                    print(f\"Error: La pareja '{pareja}' ya está asociada a más de una persona.\")\r\n                    return False\r\n\r\n            if hijos:\r\n                persona_para_actualizar['hijos'] = []\r\n                for hijo in hijos:\r\n                    if hijo == nombre or hijo == pareja:\r\n                        print(\"Tu mismo o tu pareja no puede ser tu hijo.\")\r\n                        return False\r\n                if self.verificar_hijos(hijos):\r\n                    print(f\"Error: Uno o más hijos ya existen en el sistema.\")\r\n                    return False\r\n                \r\n            persona_para_actualizar['pareja'] = pareja if pareja else persona_para_actualizar['pareja']\r\n            persona_para_actualizar['hijos'] = hijos if hijos else persona_para_actualizar['hijos']\r\n\r\n            print(f\"Datos de la persona '{nombre}' actualizados exitosamente:\")\r\n            print()\r\n            print(f\"Pareja: {persona_para_actualizar['pareja'] if persona_para_actualizar['pareja'] else 'N/A'}\")\r\n            print(f\"Hijos: {', '.join(persona_para_actualizar['hijos']) if persona_para_actualizar['hijos'] else 'Ninguno'}\")\r\n            print()\r\n\r\n            return True\r\n        except Exception as e:\r\n                    print(f\"Error al eliminar la persona: {e}\")\r\n                    return False\r\n\r\n    def imprimir_arbol(self):\r\n        print(\"Arbol familiar:\")\r\n        def buscar_padre_madre(nombre:str, hijos: list[str]):\r\n            for hijo in hijos:\r\n                for person in self.data:\r\n                    if hijo in person[\"hijos\"] and (person[\"nombre\"] != nombre):\r\n                        return person[\"nombre\"]\r\n                    else:\r\n                        return False\r\n                \r\n        for person in range (len(self.data)):\r\n            persona = self.data[person]\r\n            padres = [persona[\"nombre\"]]\r\n            pareja = persona[\"pareja\"]\r\n            hijos = persona[\"hijos\"]\r\n            encontrar_padre_madre = buscar_padre_madre(nombre=persona[\"nombre\"], hijos = hijos ) \r\n            if encontrar_padre_madre:\r\n                padres.append(encontrar_padre_madre)\r\n            print(\"---\"*20)\r\n            print(f\"Padres: {padres}\\nPareja actual: {pareja}\\nHijos: {hijos}\")\r\n            print(\"---\"*20)\r\n            \r\nif __name__ == '__main__':\r\n    try:\r\n        ab = Arbol()\r\n        ab.nueva_persona(nombre=\"Juan Carlos Lopera\", pareja=\"Maria del Rosario\", hijos=[\"Juan Carlos\", \"Juan Miguel\"])\r\n        ab.nueva_persona(nombre=\"Maria Camila Gonzales\", pareja=\"Juan Fernando\", hijos=[\"Juan Carlos\", \"Juan Miguel\"])\r\n        ab.nueva_persona(nombre=\"Alejandro\")\r\n\r\n        ab.eliminar_persona(\"Alejandro\")\r\n        \r\n        ab.editar_persona(nombre=\"Juan Carlos Lopera\", pareja=\"Ana Maria\", hijos=[\"Juan Carlos\", \"Juan Miguel\", \"Sofia\"])\r\n        ab.imprimir_arbol()\r\n    except Exception as e:\r\n        print(f\"Error: {e}\")\r\n"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/python/Nicojsuarez2.py",
    "content": "# #34 ÁRBOL GENEALÓGICO DE LA CASA DEL DRAGÓN\n> #### Dificultad: Difícil | Publicación: 19/08/24 | Corrección: 26/08/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * ¡La Casa del Dragón ha finalizado y no volverá hasta 2026! \n * ¿Alguien se entera de todas las relaciones de parentesco\n * entre personajes que aparecen en la saga?\n * Desarrolla un árbol genealógico para relacionarlos (o invéntalo).\n * Requisitos:\n * 1. Estará formado por personas con las siguientes propiedades:\n *    - Identificador único (obligatorio)\n *    - Nombre (obligatorio)\n *    - Pareja (opcional)\n *    - Hijos (opcional)\n * 2. Una persona sólo puede tener una pareja (para simplificarlo).\n * 3. Las relaciones deben validarse dentro de lo posible.\n *    Ejemplo: Un hijo no puede tener tres padres.\n * Acciones:\n * 1. Crea un programa que permita crear y modificar el árbol.\n *    - Añadir y eliminar personas\n *    - Modificar pareja e hijos\n * 2. Podrás imprimir el árbol (de la manera que consideres).\n * \n * NOTA: Ten en cuenta que la complejidad puede ser alta si\n * se implementan todas las posibles relaciones. Intenta marcar\n * tus propias reglas y límites para que te resulte asumible.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/python/SooHav.py",
    "content": "# 34 ÁRBOL GENEALÓGICO DE LA CASA DEL DRAGÓN\n\nfrom abc import ABC, abstractmethod\nimport uuid\nimport json\nimport networkx as nx\nimport matplotlib.pyplot as plt\nfrom matplotlib.offsetbox import OffsetImage, AnnotationBbox\nimport requests\nfrom PIL import Image\nfrom io import BytesIO\n\n\nclass IRegistroPersonas(ABC):\n    @abstractmethod\n    def registrar_persona(self, nombre, genero, id_padre=None, id_madre=None, conyugue=None, hijos=None, imagen=None):\n        pass\n\n    @abstractmethod\n    def buscar_persona(self, nombre):\n        pass\n\n    @abstractmethod\n    def actualizar_relacion_hijo(self, hijo, padre_o_madre):\n        pass\n\n    @abstractmethod\n    def validar_numero_padres(self, persona):\n        pass\n\n    @abstractmethod\n    def actualizar_persona(self,  id_persona, padre=None, madre=None, conyugue=None):\n        pass\n\n    @abstractmethod\n    def eliminar_persona(self, id):\n        pass\n\n\nclass IMostrarArbol(ABC):\n    @abstractmethod\n    def construir_arbol(self, id_raiz):\n        pass\n\n    @abstractmethod\n    def mostrar_arbol(self, arbol):\n        pass\n\n\nclass RegistroPersonas(IRegistroPersonas):\n    def __init__(self):\n        self.personas = {}\n\n    def registrar_persona(self, nombre, genero, padre=None, madre=None, conyugue=None, hijos=None, imagen_url=''):\n        if nombre is None or genero is None:\n            raise ValueError(\"Nombre y género son requeridos.\")\n\n        id_unico = str(uuid.uuid4())\n\n        if padre == id_unico or madre == id_unico or conyugue == id_unico:\n            raise ValueError(\n                \"Una persona no puede ser su propio padre, madre o cónyuge.\")\n\n        if conyugue:\n            conyugue_persona = self.personas.get(conyugue)\n            if conyugue_persona:\n                if conyugue_persona.get(\"conyugue\"):\n                    raise ValueError(\n                        f\"{conyugue_persona['nombre']} ya está casada con otra persona.\")\n                conyugue_persona[\"conyugue\"] = id_unico\n\n        persona = {\n            'id_unico': id_unico,\n            'nombre': nombre.lower(),\n            'genero': genero.lower(),\n            'padre': padre,\n            'madre': madre,\n            'conyugue': conyugue,\n            'hijos': [],\n            'imagen': imagen_url\n        }\n        self.personas[id_unico] = persona\n        return persona\n\n    def buscar_persona(self, nombre):\n        for clave, valor in self.personas.items():\n            if valor[\"nombre\"].lower() == nombre.lower():\n                return clave, valor[\"nombre\"], valor[\"id_unico\"]\n        return None, None\n\n    def actualizar_relacion_hijo(self, hijo, padre_o_madre):\n        if hijo not in self.personas[padre_o_madre][\"hijos\"]:\n            self.personas[padre_o_madre][\"hijos\"].append(hijo)\n\n    def validar_numero_padres(self, persona):\n        padres = 0\n        if persona.get(\"padre\"):\n            padres += 1\n        if persona.get(\"madre\"):\n            padres += 1\n        if padres > 2:\n            raise ValueError(\"La persona tiene más de dos padres.\")\n\n    def actualizar_persona(self, id_persona, padre=None, madre=None, conyugue=None, hijo=None):\n        persona = self.personas.get(id_persona)\n        if not persona:\n            raise ValueError(\"La persona con este ID no existe.\")\n\n        if padre == id_persona or madre == id_persona or conyugue == id_persona:\n            raise ValueError(\n                \"Una persona no puede ser su propio padre, madre o cónyuge.\")\n\n        self.validar_numero_padres(persona)\n\n        if conyugue:\n            conyugue_persona = self.personas.get(conyugue)\n            if conyugue_persona:\n                if conyugue_persona.get(\"conyugue\") and conyugue_persona[\"conyugue\"] != id_persona:\n                    raise ValueError(\n                        f\"{conyugue_persona['nombre']} ya está casada con otra persona.\")\n                # Actualiza el cónyuge en ambas personas\n                conyugue_persona[\"conyugue\"] = id_persona\n            persona[\"conyugue\"] = conyugue\n\n        persona.update({'padre': padre, 'madre': madre})\n\n        if hijo:\n            self.actualizar_relacion_hijo(hijo, id_persona)\n        if padre:\n            self.actualizar_relacion_hijo(id_persona, padre)\n        if madre:\n            self.actualizar_relacion_hijo(id_persona, madre)\n\n    def eliminar_persona(self, nombre):\n        for clave, valor in list(self.personas.items()):\n            if valor[\"nombre\"].lower() == nombre.lower():\n                del self.personas[clave]\n                print(f\"Persona con nombre {nombre} eliminada.\")\n                return\n        print(\"Nombre no encontrado.\")\n\n\nclass MostrarArbol(IMostrarArbol):\n    def __init__(self, registro_personas):\n        self.registro_personas = registro_personas\n        self.arbol = {}\n\n    def construir_arbol(self, id_raiz):\n        def construir_diccionario(id_persona):\n            persona = self.registro_personas.personas.get(id_persona)\n            if not persona:\n                return None\n\n            padre = self.registro_personas.personas.get(persona.get(\"padre\"))\n            madre = self.registro_personas.personas.get(persona.get(\"madre\"))\n            conyugue = self.registro_personas.personas.get(\n                persona.get(\"conyugue\"))\n\n            diccionario = {\n                \"id\": id_persona,\n                \"nombre\": persona.get(\"nombre\"),\n                \"imagen\": persona.get(\"imagen\"),\n                \"padre\": {\n                    \"nombre\": padre.get(\"nombre\") if padre else None,\n                    \"imagen\": padre.get(\"imagen\") if padre else None\n                } if padre else None,\n                \"madre\": {\n                    \"nombre\": madre.get(\"nombre\") if madre else None,\n                    \"imagen\": madre.get(\"imagen\") if madre else None\n                } if madre else None,\n                \"conyugue\": {\n                    \"nombre\": conyugue.get(\"nombre\") if conyugue else None,\n                    \"imagen\": conyugue.get(\"imagen\") if conyugue else None\n                } if conyugue else None,\n                \"hijos\": [\n                    {\n                        \"nombre\": hijo.get(\"nombre\"),\n                        \"imagen\": hijo.get(\"imagen\")\n                    }\n                    for hijo in (self.registro_personas.personas.get(hijo_id) for hijo_id in persona.get(\"hijos\") if hijo_id in self.registro_personas.personas)\n                ]\n            }\n            return diccionario\n\n        self.arbol = construir_diccionario(id_raiz)\n        return self.arbol\n\n    def mostrar_arbol(self, arbol):\n        print(json.dumps(arbol, indent=4))\n\n\n# Uso del código\nregistro = RegistroPersonas()\nid_jaehaerysI = registro.registrar_persona(\n    \"Jaehaerys I Targaryen\", \"Masculino\", imagen_url=\"https://es.digitaltrends.com/wp-content/uploads/2024/07/1-Jaehaerys-I-Targaryen.jpg?fit=720%2C480&p=1\")\nid_alysanne = registro.registrar_persona(\n    \"Alysanne Targaryen\", \"Femenino\", imagen_url=\"https://static.wikia.nocookie.net/hieloyfuego/images/5/55/Alysanne.jpg/revision/latest?cb=20171022174856\")\nid_aemon = registro.registrar_persona(\n    \"Aemon Targaryen\", \"Masculino\", padre=id_jaehaerysI[\"id_unico\"], madre=id_alysanne['id_unico'], imagen_url=\"\")\nid_baelon = registro.registrar_persona(\n    \"Baelon Targaryen\", \"Masculino\", padre=id_jaehaerysI[\"id_unico\"], madre=id_alysanne['id_unico'], imagen_url=\"\")\nid_alysa = registro.registrar_persona(\n    \"Alysa Targaryen\", \"Femenino\", padre=id_jaehaerysI[\"id_unico\"], madre=id_alysanne['id_unico'], conyugue=id_baelon[\"id_unico\"], imagen_url=\"\")\nid_joselyne = registro.registrar_persona(\n    \"Jocelyne Baratheon\", \"Femenino\", conyugue=id_aemon[\"id_unico\"], imagen_url=\"\")\nid_daemon = registro.registrar_persona(\"Daemon Targaryen\", \"Masculino\", padre=id_baelon[\"id_unico\"], madre=id_alysa[\n                                       'id_unico'], imagen_url=\"https://i2-prod.mirror.co.uk/news/uk-news/article33141854.ece/ALTERNATES/s1200b/0_daemon-targaryen.jpg\")\nid_viserysI = registro.registrar_persona(\"Viserys I Targaryen\", \"Masculino\", padre=id_baelon[\"id_unico\"], madre=id_alysa['id_unico'],\n                                         imagen_url=\"https://static.wikia.nocookie.net/hieloyfuego/images/f/fa/Paddy_Considine_como_Viserys_I_HBO.jpg/revision/latest?cb=20231201142723\")\nid_aemma = registro.registrar_persona(\n    \"Aemma Arryn\", \"Femenino\", imagen_url=\"https://static.wikia.nocookie.net/hieloyfuego/images/1/1d/Aemma_Arryn_HBO.png/revision/latest?cb=20220818134257\")\nid_rhea = registro.registrar_persona(\n    \"Rhea Royce\", \"Femenino\", imagen_url=\"https://static.wikia.nocookie.net/hieloyfuego/images/7/7e/Rhea_Royce_HBO.jpeg/revision/latest?cb=20220915180910\")\n\nregistro.actualizar_persona(\n    id_viserysI[\"id_unico\"], conyugue=id_aemma[\"id_unico\"])\nregistro.actualizar_persona(\n    id_daemon[\"id_unico\"], conyugue=id_rhea[\"id_unico\"])\nregistro.actualizar_persona(\n    id_jaehaerysI[\"id_unico\"], conyugue=id_alysanne[\"id_unico\"])\nregistro.actualizar_persona(\n    id_jaehaerysI[\"id_unico\"], hijo=id_alysa[\"id_unico\"])\nregistro.actualizar_persona(\n    id_jaehaerysI[\"id_unico\"], hijo=id_aemon[\"id_unico\"])\nregistro.actualizar_persona(\n    id_jaehaerysI[\"id_unico\"], hijo=id_baelon[\"id_unico\"])\nregistro.actualizar_persona(\n    id_alysanne[\"id_unico\"], conyugue=id_jaehaerysI[\"id_unico\"])\nregistro.actualizar_persona(id_alysanne[\"id_unico\"], hijo=id_alysa[\"id_unico\"])\nregistro.actualizar_persona(id_alysanne[\"id_unico\"], hijo=id_aemon[\"id_unico\"])\nregistro.actualizar_persona(\n    id_alysanne[\"id_unico\"], hijo=id_baelon[\"id_unico\"])\nregistro.actualizar_persona(id_baelon[\"id_unico\"], hijo=id_daemon[\"id_unico\"])\nregistro.actualizar_persona(\n    id_baelon[\"id_unico\"], hijo=id_viserysI[\"id_unico\"])\nregistro.actualizar_persona(\n    id_baelon[\"id_unico\"], padre=id_jaehaerysI[\"id_unico\"], madre=id_alysanne[\"id_unico\"])\n\npersonaje_buscado = registro.buscar_persona(\"Rhea Royce\")\nprint(personaje_buscado)\nregistro.eliminar_persona(\"Rhea Royce\")\n\n# Mostrar árbol genealógico como diccionario\nmostrar = MostrarArbol(registro)\narbol = mostrar.construir_arbol(id_baelon[\"id_unico\"])\nmostrar.mostrar_arbol(arbol)\n\n# Extra: Mostrar árbol genealógico como un grafo\n# Función para cargar imágenes desde un enlace\n\n\ndef obtener_imagen(url):\n    if not url or not url.startswith(('http://', 'https://')):\n        print(f\"URL no válida: {url}. Se usará la imagen por defecto.\")\n        url = default_image_url\n    try:\n        response = requests.get(url)\n        img = Image.open(BytesIO(response.content))\n        return OffsetImage(img, zoom=0.03)\n    except Exception as e:\n        print(f\"Error al cargar la imagen desde {url}: {e}\")\n        return OffsetImage(Image.open(BytesIO(requests.get(default_image_url).content)), zoom=0.08)\n\n\n# Configuración de imágenes por defecto\ndefault_image_url = \"https://mundo-ghibli.com/wp-content/uploads/2023/10/sin-rostro-chihiro.jpg.webp\"\n\n# Crear el grafo dirigido\nG = nx.DiGraph()\n\n# Agregar nodos y aristas usando nombres como identificadores\n# Verificar si el padre existe y agregar nodo y arista si es así\nif arbol.get(\"padre\") and arbol[\"padre\"].get(\"nombre\"):\n    G.add_node(arbol[\"padre\"][\"nombre\"],\n               imagen=arbol[\"padre\"].get(\"imagen\", default_image_url))\n    G.add_node(arbol[\"nombre\"], imagen=arbol.get(\"imagen\", default_image_url))\n    G.add_edge(arbol[\"padre\"][\"nombre\"], arbol[\"nombre\"])\n\n# Verificar si la madre existe y agregar nodo y arista\nif arbol.get(\"madre\") and arbol[\"madre\"].get(\"nombre\"):\n    G.add_node(arbol[\"madre\"][\"nombre\"],\n               imagen=arbol[\"madre\"].get(\"imagen\", default_image_url))\n    G.add_edge(arbol[\"madre\"][\"nombre\"], arbol[\"nombre\"])\n\n# Verificar si el cónyuge existe y agregar nodo y arista\nif arbol.get(\"conyugue\") and arbol[\"conyugue\"].get(\"nombre\"):\n    G.add_node(arbol[\"conyugue\"][\"nombre\"],\n               imagen=arbol[\"conyugue\"].get(\"imagen\", default_image_url))\n    G.add_edge(arbol[\"nombre\"], arbol[\"conyugue\"][\"nombre\"])\n\n# Verificar si hay hijos y agregar nodos y aristas\nfor hijo in arbol.get(\"hijos\", []):\n    if hijo.get(\"nombre\"):  # Evitar nodos sin nombre\n        # Usar imagen del hijo o predeterminada\n        G.add_node(hijo[\"nombre\"], imagen=hijo.get(\n            \"imagen\", default_image_url))\n        G.add_edge(arbol[\"nombre\"], hijo[\"nombre\"])\n\n# Posiciones para una mejor visualización\npos = {\n    arbol[\"nombre\"]: (0, 0),  # El nodo principal en el centro\n}\n\n# Posición del padre si existe\nif arbol.get(\"padre\") and arbol[\"padre\"].get(\"nombre\"):\n    # Posicionamos al padre a la izquierda arriba\n    pos[arbol[\"padre\"][\"nombre\"]] = (-1, 1)\n\n# Posición de la madre si existe\nif arbol.get(\"madre\") and arbol[\"madre\"].get(\"nombre\"):\n    # Posicionamos a la madre a la derecha arriba\n    pos[arbol[\"madre\"][\"nombre\"]] = (1, 1)\n\n# Posición del cónyuge si existe\nif arbol.get(\"conyugue\") and arbol[\"conyugue\"].get(\"nombre\"):\n    # Posicionamos al cónyuge a la derecha del nodo principal\n    pos[arbol[\"conyugue\"][\"nombre\"]] = (1, 0)\n\n# Distribuir la posición de los hijos\nfor idx, hijo in enumerate(arbol.get(\"hijos\", [])):\n    if hijo.get(\"nombre\"):\n        # Calculamos la posición horizontal de cada hijo\n        # Los hijos se posicionan debajo del nodo principal\n        pos[hijo[\"nombre\"]] = (idx - len(arbol[\"hijos\"]) / 2, -1)\n\n# Dibujar el grafo\nfig, ax = plt.subplots()\n\n# Verifica si el nodo existe y no es None\ntry:\n    padre_nombre = arbol.get(\"padre\", {}).get(\"nombre\", None)\nexcept AttributeError:\n    padre_nombre = None\ntry:\n    madre_nombre = arbol.get(\"madre\", {}).get(\"nombre\", None)\nexcept AttributeError:\n    madre_nombre = None\ntry:\n    conyugue_nombre = arbol.get(\"conyugue\", {}).get(\"nombre\", None)\nexcept AttributeError:\n    conyugue_nombre = None\n\n# Definir tamaños de los nodos\nnode_sizes = {\n    padre_nombre: 1200 if padre_nombre else 0,\n    madre_nombre: 1200 if madre_nombre else 0,\n    arbol[\"nombre\"]: 2000,\n    conyugue_nombre: 2000 if conyugue_nombre else 0,\n    **{hijo[\"nombre\"]: 1000 for hijo in arbol.get(\"hijos\", []) if hijo.get(\"nombre\")}\n}\n\n# Definir colores de los nodos\nnode_colors = {\n    padre_nombre: \"grey\" if padre_nombre else 'white',\n    madre_nombre: \"grey\" if madre_nombre else 'white',\n    arbol[\"nombre\"]: \"blue\",\n    conyugue_nombre: \"purple\" if conyugue_nombre else 'white',\n    **{hijo[\"nombre\"]: \"lightblue\" for hijo in arbol.get(\"hijos\", []) if hijo.get(\"nombre\")}\n}\n\n# Dibuja el grafo con aristas\nnx.draw(\n    G, pos, with_labels=False, arrows=True,\n    node_size=[node_sizes.get(node, 500) for node in G.nodes()],\n    node_color=[node_colors.get(node, 'white') for node in G.nodes()],\n    font_size=10, font_weight='bold', ax=ax\n)\n\n# Añadir los nombres por encima de los nodos\nfor nodo, (x, y) in pos.items():\n    ax.text(x + 0.1, y + 0.15, nodo, fontsize=10, ha='center',\n            color='black')  # Ajustar posición del texto\n\n# Añadir las imágenes a los nodos\nfor nodo, (x, y) in pos.items():\n    if nodo in G.nodes():\n        imagen_url = G.nodes[nodo].get('imagen', default_image_url)\n        try:\n            # Obtener la imagen del diccionario\n            img = obtener_imagen(imagen_url)\n            ab = AnnotationBbox(img, (x, y), frameon=False)\n            ax.add_artist(ab)\n        except Exception as e:\n            print(f\"No se pudo cargar la imagen para {nodo}: {e}\")\n\nplt.title(\"Árbol Genealógico de la Casa del Dragón\",\n          fontsize=14, fontweight='bold', y=1.05)\nplt.axis('off')\nplt.show()\n"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/python/Trufoplus.py",
    "content": "class Person:\n    def __init__(self, id, name):\n        self.id = id\n        self.name = name \n        self.couple = None\n        self.childs = []\n\n    def relationships(self, couple):\n        if self.couple:\n            print(f'{self.name} ya tiene una pareja: {self.couple.name}.')\n        else:\n            self.couple = couple\n            couple.couple = self  # Asegura que la relación sea mutua\n\n    def add_child(self, child):\n        if child in self.childs:\n            print(f'{self.name} ya tiene a {child.name} como hijo.')\n        else:\n            self.childs.append(child)\n            \n    def delete_child(self, child):\n        if child in self.childs:\n            self.childs.remove(child)\n        else:\n            print(f'{child.name} no es hijo de {self.name}.')\n\n    def delete_couple(self):\n        if self.couple:\n            print(f'{self.name} se ha separado de {self.couple.name}.')\n            self.couple.couple = None  # Rompe la relación mutua\n            self.couple = None\n        else:\n            print(f'{self.name} no tiene ninguna pareja.')\n    \n    def print_tree(self, level=0):\n        print(' ' * level * 4 + f\"{self.name}\")\n        if self.couple:\n            print(' ' * level * 4 + f\"  Pareja: {self.couple.name}\")\n        if self.childs:\n            print(' ' * level * 4 + f\"  Hijos: \")\n            for child in self.childs:\n                child.print_tree(level + 1)   \n            \ndef create_person(id, name):\n    return Person(id, name)        \n\ndef establish_childs(father, mother, child):\n    father.add_child(child)\n    mother.add_child(child)\n\n\n\n# Personas de la casa del dragon\naemon = create_person(2, 'Aemon Targaryen')\njocelyn = create_person(1, 'Jocelyn Baratheon')\nrhaenys = create_person(3, 'Rhaenys Targaryen')\ncorlys = create_person(4, 'Corlys Velaryon')\nloena = create_person(5, 'Loena Velaryon')\nlaenor = create_person(6, 'Laenor Velaryon')\ndaemon = create_person(7, 'Daemon Targaryen')\nbaela = create_person(8, 'Baela Targaryen')\nrhaena = create_person(9, 'Rhaena Targaryen')\nrhaenyra = create_person(10, 'Rhaenyra Targaryen')\njacaerys = create_person(11, 'jacaerys Velarion')\nlucerys = create_person(12, 'Lucerys Velarion')\njoffrey = create_person(13, 'Joffrey Velarion')\n\n\n# Establecionda las relaciones\naemon.relationships(jocelyn)\nestablish_childs(aemon, jocelyn, rhaenys)\n\nrhaenys.relationships(corlys)\nestablish_childs(corlys, rhaenys, loena)\nestablish_childs(corlys, rhaenys, laenor)\n\ndaemon.relationships(loena)\nestablish_childs(daemon, loena, baela)\nestablish_childs(daemon, loena, rhaena)\n\nrhaenyra.relationships(laenor)\nestablish_childs(laenor, rhaenyra, jacaerys)\nestablish_childs(laenor, rhaenyra, lucerys)\nestablish_childs(laenor, rhaenyra, joffrey)\n\n\n# Imprimir el árbol genealógico\naemon.print_tree()\n\n\n"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/python/adra-dev.py",
    "content": "\"\"\"\nEJERCICIO:\n¡La Casa del Dragón ha finalizado y no volverá hasta 2026! \n¿Alguien se entera de todas las relaciones de parentesco\nentre personajes que aparecen en la saga?\nDesarrolla un árbol genealógico para relacionarlos (o invéntalo).\nRequisitos:\n1. Estará formado por personas con las siguientes propiedades:\n    - Identificador único (obligatorio)\n    - Nombre (obligatorio)\n    - Pareja (opcional)\n    - Hijos (opcional)\n2. Una persona sólo puede tener una pareja (para simplificarlo).\n3. Las relaciones deben validarse dentro de lo posible.\n    Ejemplo: Un hijo no puede tener tres padres.\nAcciones:\n1. Crea un programa que permita crear y modificar el árbol.\n    - Añadir y eliminar personas\n    - Modificar pareja e hijos\n2. Podrás imprimir el árbol (de la manera que consideres).\n \nNOTA: Ten en cuenta que la complejidad puede ser alta si\nse implementan todas las posibles relaciones. Intenta marcar\ntus propias reglas y límites para que te resulte asumible.\n\nby adra-dev\n\"\"\"\n\nclass Person:\n    \n    def __init__(self, id: int, name: str):\n        self.id = id\n        self.name = name \n        self.partner = None\n        self.children = []\n        self.has_parents = False\n\n\n    def add_partner(self, partner):\n        if self.partner is not None:\n            print(f\"{self.name} ya tiene una pareja: {self.partner.name}.\")\n        else:\n            self.partner = partner\n            partner.partner = self\n            print(f\"{self.name} es pareja de {partner.name}\")\n\n    def add_child(self, child):\n        if child not in self.children:\n            self.children.append(child)\n            print(f\"{self.name} ha tenido un hijo: {child.name}\")\n        else:\n            print(f\"{child.name} ya es hijo de {self.name}\")\n\n\nclass FamilyTree:\n\n    def __init__(self):\n        self.people = {}\n\n    def add_person(self, id, name):\n        if id in self.people:\n            print(f\"La persona con ID:{id} ya existe.\")\n        else:\n            person = Person(id, name)\n            self.people[id] = person\n            print(f\"La perosna con nombre {name} [ID: {id}] ha sido agregada al arbol.\")\n\n    def remove_person(self, id):\n        if id in self.people:\n            person = self.people[id]\n            del self.people[id]\n            print(f\"La persona con nombre {person.name} [ID: {id}] ha sido eliminada del arbol.\")\n        else:\n            print(f\"La persona con [ID: {id}] no existe en el arbol.\")\n        \n    def set_partner(self, id1, id2):\n        if id1 in self.people and id2 in self.people:\n            person1 = self.people[id1]\n            person2 = self.people[id2]\n            person1.add_partner(person2)\n        else:\n            print(\"Algun ID no existe en el arbol.\")\n\n    def add_child(self, parent_id, child_id):\n        if parent_id in self.people and child_id in self.people:\n            if parent_id == child_id:\n                print(\"Los ID no pueden ser iguales a la hora de asignar un hijo.\")\n            else:\n                parent = self.people[parent_id]\n                if parent.partner is None:\n                    print(f\"Se necesita una pareja para poder tener un hijo.\")\n                else:\n                    child = self.people[child_id]\n                    if child.has_parents:\n                        print(f\"{child.name} [ID: {id}] ya tiene padres\")\n                    else:\n                        child.has_parents = True\n                        parent.add_child(child)\n                        parent.partner.add_child(child)\n        else:\n            print(\"Algun ID no existe en el arbol.\")\n\n    def pint_tree(self):\n\n        visited = set()\n\n        def print_person(person, level = 0):\n            \n            if person.id in visited:\n                return\n            \n            visited.add(person.id)\n\n            indent = \"\\t\" * level\n\n            print(f\"{indent} - {person.name} [ID: {person.id}]\")\n\n            if person.partner:\n                visited.add(person.partner.id)\n                print(\n                    f\"{indent}   Pareja: {person.partner.name} [ID: {person.partner.id}]\")\n\n            if person.children:\n                print(f\"{indent}  Hijos:\")\n                for child in person.children:\n                    print_person(child, level + 1)\n        \n\n        for person in self.people.values():\n            is_child = person.has_parents\n            if not is_child:\n                print_person(person)\n\n\ntree = FamilyTree()\n\ntree.add_person(1, \"Jocelyn\")\ntree.add_person(2, \"Aemon\")\n\ntree.set_partner(1, 2)\n\ntree.add_person(3, \"Rhaenys\")\n\ntree.add_child(1, 3)\n\ntree.add_person(4, \"Corlys\")\n\ntree.set_partner(3, 4)\n\ntree.add_person(5, \"Laena\")\ntree.add_person(6, \"Laenor\")\n\ntree.add_child(3, 5)\ntree.add_child(3, 6)\n\ntree.add_person(7, \"Baelon\")\ntree.add_person(8, \"Alyssa\")\n\ntree.set_partner(7,8)\n\n\ntree.add_person(9, \"Viserys I\")\ntree.add_person(10, \"Daemon\")\n\ntree.add_child(7, 9)\ntree.add_child(8, 10)\n\ntree.add_person(11, \"Aemma\")\n\ntree.set_partner(9, 11)\n\ntree.add_person(12, \"Rhaenyra\")\n\ntree.add_child(9, 12)\n\ntree.set_partner(10, 12)\n\ntree.add_person(13, \"Aegon\")\ntree.add_person(14, \"Viserys\")\n\ntree.add_child(12, 13)\ntree.add_child(12, 14)\n\ntree.pint_tree()"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/python/avcenal.py",
    "content": "\"\"\"\n * EJERCICIO:\n * ¡La Casa del Dragón ha finalizado y no volverá hasta 2026!\n * ¿Alguien se entera de todas las relaciones de parentesco\n * entre personajes que aparecen en la saga?\n * Desarrolla un árbol genealógico para relacionarlos (o invéntalo).\n * Requisitos:\n * 1. Estará formado por personas con las siguientes propiedades:\n *    - Identificador único (obligatorio)\n *    - Nombre (obligatorio)\n *    - Pareja (opcional)\n *    - Hijos (opcional)\n * 2. Una persona sólo puede tener una pareja (para simplificarlo).\n * 3. Las relaciones deben validarse dentro de lo posible.\n *    Ejemplo: Un hijo no puede tener tres padres.\n * Acciones:\n * 1. Crea un programa que permita crear y modificar el árbol.\n *    - Añadir y eliminar personas\n *    - Modificar pareja e hijo\n * 2. Podrás imprimir el árbol (de la manera que consideres).\n * \n * NOTA: Ten en cuenta que la complejidad puede ser alta si\n * se implementan todas las posibles relaciones. Intenta marcar\n * tus propias reglas y límites para que te resulte asumible.\n\"\"\"\n#Para poder llevar a cabo este programa se han construido dos estructuras\n#Lista de Personajes: personajes que se \"dan de alta\" para después linkarlos a alguna parte del árbol\n#Árbol Genealógico: los personajes que una vez dados de alta, pasan a estar en el árbol, siempre con algún tipo de relación.\n#Nota: el único personaje que se puede crear sin relación es el personaje origen o root\n\nfrom abc import ABC, abstractmethod\n\nclass AbstractIdFinder(ABC):\n    @abstractmethod\n    def find_id(self):\n        pass\n\nclass AbstractCharacterFinder(ABC):\n    @abstractmethod\n    def find_character(self):\n        pass\n\nclass AbstractCharacter(ABC):\n    @abstractmethod\n    def __init__(self):\n        pass\n\nclass AbstractMarriage(ABC):\n    @abstractmethod\n    def marriage(self):\n        pass\n\nclass AsbtractSetChildren(ABC):\n    @abstractmethod\n    def set_children(self):\n        pass\n\nclass AsbtractSetParents(ABC):\n    @abstractmethod\n    def set_parents(self):\n        pass\n\nclass AbstractCharacterPrinter(ABC):\n    @abstractmethod\n    def print_character(self):\n        pass\n\nclass AbstractFullTreePrinter(ABC):\n    @abstractmethod\n    def print_tree(self):\n        pass\n\nclass IdFinder(AbstractIdFinder):\n    def find_id(self,character:AbstractCharacter,id:int): #método para comprobar si un id está o no en el árbol familiar. Devuelve un boolean\n        if character.id == id:\n            return True\n        elif character.couple != None:\n            if character.couple.id == id:\n                return True\n            elif character.children != None :\n                for child in character.children:\n                    if self.find_id(child,id):\n                        return True\n        return False\n    \nclass CharacterFinder(AbstractCharacterFinder):\n    def __check_fathers(self,character:AbstractCharacter,id:int):\n        if character.father.id == id: #si es el padre\n            return character.father\n        elif character.mother.id == id: #si es la madre\n            return character.mother\n        else:\n            return None\n\n    def find_character(self,root:AbstractCharacter,id:int):\n        stack = [root]\n        ids = set()\n        while stack:\n            current_character = stack.pop()\n            ids.add(current_character.id)\n            if current_character.id == id:\n                return current_character\n\n            if current_character.couple and current_character.couple.id not in ids:\n                ids.add(current_character.couple.id)\n                stack.append(current_character.couple)\n\n            if current_character.children:\n                for child in current_character.children:\n                    if child.id not in ids:\n                        ids.add(child.id)\n                        stack.append(child)\n\n            if current_character.father and current_character.father.id not in ids:\n                stack.append(current_character.father)\n\n            if current_character.mother and current_character.mother.id not in ids:\n                stack.append(current_character.mother)\n        return None\n\nclass Character(AbstractCharacter):\n    def __init__(self,id:int,name:str,sex:str):\n        self.id:int = id\n        self.name:str = name\n        self.sex:str = sex\n        self.father:AbstractCharacter | None = None\n        self.mother:AbstractCharacter | None = None\n        self.couple:AbstractCharacter | None = None\n        self.children: list[AbstractCharacter] | None = None\n\nclass Marriage(AbstractMarriage):\n    def marriage(self,character_1:AbstractCharacter,character_2:AbstractCharacter): #creación del matrimonio de dos personajes\n        if (character_1.couple == None and character_2.couple == None) and ((character_1.sex == \"hombre\" and character_2.sex == \"mujer\")or (character_2.sex == \"hombre\" and character_1.sex == \"mujer\")):\n            character_1.couple = character_2 #en Westeros solo se pueden casar hombre y mujer, se controla en este punto junto con que ninguno de los dos esté casado ya\n            character_2.couple = character_1\n            print(f\"{character_1.name} y {character_2.name} se han casado y son pareja\")\n        else:\n            if character_1.couple != None: #si el character_1 está casado, no se le permite desposarse de nuevo\n                print(f\"No es posible este matrimonio, {character_1.name} ya tiene pareja\\n\")\n            elif character_2.couple != None: #lo mismo con el character_2\n                print(f\"No es posible este matrimonio, {character_2.name} ya tiene pareja\\n\")\n            else: #en caso de que los dos sean hombres o mujeres, no se les permite casarse\n                print(\"El matrimonio no es posible según las leyes de Westeros, solamente se podrán casar hombre y mujer\")\n        \n\nclass SetChildren(AsbtractSetChildren):\n    def set_children(self,character_1:AbstractCharacter,character_2:AbstractCharacter,child:AbstractCharacter):\n        if character_1.couple == character_2 and character_2.couple == character_1: #se comprueba que los dos personajes son pareja\n            if character_1.children == None: #si no tienen hijos aún, se crea la lista con el primer hijo\n                character_1.children = [child]\n            else:\n                character_1.children.append(child) #si tienen hijos, se añade a la lista el nuevo hijo/a\n            child.father = character_1 #se marca como padre al character_1\n            character_2.children = character_1.children #los hijos del character_1 son los mismos para character_2 por ser matrimonio\n            child.mother = character_2 #se marca como madre a character_2\n        else:\n            print(f\"{character_1.name} y {character_2.name} no pueden tener hijos porque no son pareja\") #en caso de que no sean pareja, entonces no pueden tener hijos\n\nclass SetParents(AsbtractSetParents):\n    def set_parents(self,character:AbstractCharacter,father:AbstractCharacter,mother:AbstractCharacter): #con  este método se pueden definir padres y madres para un personaje recien creado\n        if character.father == None and character.mother == None:                                                                     #IGUALMENTE SE PODRÍA CONTROLAR POR EL SEXO DEL PADRE Y LA MADRE, TESTEAR\n                if (father.couple == None or father.couple == mother) and (mother.couple == None or mother.couple == father):\n                    father.couple = mother\n                    mother.couple = father\n                    character.father = father\n                    character.mother = mother\n                    if father.children:\n                        father.children.append(character)\n                    else:\n                        father.children = [character]\n                    if mother.children:\n                        mother.children.append(character)\n                    else:\n                        mother.children = [character]\n                else:\n                    if father.couple != None and father.couple != father:\n                        print(f\"{father.name} no puede ser el padre de {character.name} porque {father.name} ya tiene una pareja que no es {mother.name}, es {father.couple.name}\\n\")\n                    elif mother.couple != None and mother.couple != mother:\n                        print(f\"{mother.name} no puede ser la madre de {character.name} porque {mother.name} ya tiene una pareja que no es {father.name}, es {mother.couple.name}\\n\")\n        else:\n            if character.father != None:\n                print(f\"{father.name} no puede ser el padre de {character.name} porque ya tiene un padre que es {character.father}\\n\")\n            elif character.mother != None:\n                print(f\"{mother.name} no puede ser la madre de {character.name} porque ya tiene un padre que es {character.mother}\\n\")\n\nclass CharacterPrinter(AbstractCharacterPrinter):\n    def print_character(self,character:AbstractCharacter):\n        if character:\n            print(f\"Id: {character.id}\\nNombre: {character.name}\\nSexo: {character.sex}\")\n            if character.couple:\n                print(f\"Su pareja es {character.couple.name}\")\n            if character.children:\n                print(f\"Tiene {len(character.children)} hijo(s):\")\n                for child in character.children:\n                    print(f\"- {child.name}\")\n            if character.father and character.mother:\n                print(\"Y sus padres son:\")\n                print(f\"- {character.father.name}\")\n                print(f\"- {character.mother.name}\")\n            print(\"\\n\")\n        else:\n            print(f\"Ese personaje no está en el árbol\")\n\n    def print_character_by_id(self,id:int,origin_character:AbstractCharacter,character_finder:AbstractCharacterFinder):\n        character = character_finder.find_character(origin_character,id)\n        self.print_character(character)\n\nclass FullTreePrinter(AbstractFullTreePrinter):\n    def __is_printed(self,id:int,characters_printed:set[int]):\n        if id in characters_printed:\n            return True\n        else:\n            return False\n    \n    def print_tree(self,root:AbstractCharacter,character_printer:AbstractCharacterPrinter):\n        stack = [root]\n        characters_printed = set()\n\n        while stack:\n            current_character = stack.pop()\n            #print(current_character.id)\n            if not self.__is_printed (current_character.id,characters_printed):\n                character_printer.print_character(current_character)\n                characters_printed.add(current_character.id)\n\n            if current_character.couple and not self.__is_printed(current_character.couple.id,characters_printed):\n                stack.append(current_character.couple)\n\n            if current_character.children:\n                for child in current_character.children:\n                    if not self.__is_printed(child.id,characters_printed):\n                        stack.append(child)\n\n            if current_character.father and not self.__is_printed(current_character.father.id,characters_printed):\n                stack.append(current_character.father)\n\n            if current_character.mother and not self.__is_printed(current_character.mother.id,characters_printed):\n                stack.append(current_character.mother)\n\n            stack = sorted(stack,key=lambda x : x.id,reverse=True)\n\n#Los dos métodos de a continuación podrían ir en una clase para tratar de respetar aún más los principios SOLID\n#Sin ella, el programa no los cumple al 100%\n\ndef __find_id_in_list_of_characters(id:int, list:list): #nueva clase que incluya este y la siguiente función???\n    for character in list:\n        if character.id == id:\n            return True\n    return False      \n    \ndef __find_character_in_list(id:int,list:list):\n    for character in list:\n        if character.id == id:\n            return character\n\nprint(\"Te doy la bienvenida a la aplicación de creación del Árbol Genealógico de los Targaryen\")\nid_finder = IdFinder()\nroot = None\nlist_of_characters = []\ncharacter_finder = CharacterFinder()\ncharacter_printer = CharacterPrinter()\ntree_printer = FullTreePrinter()\nwhile True:\n    option = input(\"\\n¿Qué deseas hacer?:\\n- Crear un personaje(C)\\n- Casar a un personaje(M)\\n- Definir los padres de un personaje(P)\\n- Definir los hijos de un personaje(S)\\n- Imprimir el árbol completo(F)\\n- Salir(O)\\nIntroduce tu opción ----> \").upper()\n    if option == \"C\":\n        if not root:\n            print(\"Como el árbol genealógico está vacío, vamos a crear el primer personaje que tendrá el id 1\")\n            name = input(\"Dime su nombre: \")\n            while True:\n                sex_option = input (\"Dime si es hombre (H) o mujer (M): \").upper()\n                if sex_option == \"H\":\n                    sex = \"hombre\"\n                    break\n                elif sex_option == \"M\":\n                    sex = \"mujer\"\n                    break\n                else:\n                    print(\"Parece que has introducido una opción errónea...\")\n            root = Character(1,name,sex)\n            list_of_characters.append(root)\n        else:\n            try:\n                id = int(input(\"Dime su id: \"))\n            except ValueError:\n                print(\"Introduce un número por favor\")\n            else:\n                if not id_finder.find_id(root,id) and not __find_id_in_list_of_characters(id,list_of_characters): #busca el id en el ábrol y en la lista\n                    name = input(\"Dime su nombre: \")\n                    while True:\n                        sex_option = input (\"Dime si es hombre (H) o mujer (M): \").upper()\n                        if sex_option == \"H\":\n                            sex = \"hombre\"\n                            break\n                        elif sex_option == \"M\":\n                            sex = \"mujer\"\n                            break\n                        else:\n                            print(\"Parece que has introducido una opción errónea...\")\n                    new_character = Character(id,name,sex)\n                    list_of_characters.append(new_character)\n                else:\n                    print(\"Ups... ese ID existe, empecemos de nuevo...\")\n\n    elif option == \"M\":\n        if len(list_of_characters) == 1:\n            print(\"No es posible celebrar ningún matrimonio porque solo has dado de alta 1 personaje\")\n        if len(list_of_characters) == 2:\n            print(f\"Como solo hay dos personajes dados de alta, se celebrará el matrimonio entre {root.name} y {list_of_characters[1].name}\")\n            Marriage().marriage(root,list_of_characters[1])\n        else:\n            id_1 = int(input(\"Dime el id del primer personaje (perteneciente al árbol) que quieres casar: \")) #ha de pertenecer al árbol porque en caso contrario crearíamos un árbol diferente.\n            print(f\"Has elegido a {character_finder.find_character(root,id_1).name}\")\n            if id_finder.find_id(root,id_1):                                                                  #Se podría llegar a enlazar pero el nivel de complejidad sería muy alto para este ejercicio\n                id_2 = int(input(\"Ahora dime el id del segundo personaje (perteneciente al árbol o solo dado de alta) que quieres casar: \"))\n                if id_finder.find_id(root,id_2):\n                    print(f\"Has elegido a {character_finder.find_character(root,id_2).name}\")\n                    Marriage().marriage(character_finder.find_character(root,id_1),character_finder.find_character(root,id_2))\n                elif __find_id_in_list_of_characters(id_2,list_of_characters):\n                    print(f\"Has elegido a {__find_character_in_list(id_2,list_of_characters).name}\")\n                    Marriage().marriage(character_finder.find_character(root,id_1),__find_character_in_list(id_2,list_of_characters))\n                else:\n                    print(f\"No existe ningún personaje con el id {id_2}\")\n            else:\n                print(f\"No existe ningún personaje con el id {id_1}\")\n\n    elif option == \"P\":\n        character_id = int(input(\"Dime el id del personaje del árbol que quieres declarar sus padres: \"))\n        if id_finder.find_id(root,character_id):\n            print(f\"Has elegido a {character_finder.find_character(root,character_id)}\")\n            father_id = int(input(\"Dime el id de su padre (El personaje debe estar dado de alta): \"))\n            if __find_id_in_list_of_characters(father_id,list_of_characters):\n                print(f\"Has elegido como padre a {__find_character_in_list(father_id,list_of_characters)}\")\n                mother_id = int(input(\"Ahora dime el id de la madre (Igualmente el personaje debe estár dado de alta): \"))\n                if __find_id_in_list_of_characters(mother_id,list_of_characters):\n                    print(f\"Has elegido como madre a {__find_character_in_list(mother_id,list_of_characters)}\")\n                    SetParents().set_parents(character_finder.find_character(root,character_id),__find_character_in_list(father_id,list_of_characters),__find_character_in_list(mother_id,list_of_characters))\n                else:\n                    print(f\"No existe ningún personaje en el árbol con el id {mother_id}\")\n            else:\n                    print(f\"No existe ningún personaje en el árbol con el id {father_id}\")\n        else:\n                    print(f\"No existe ningún personaje en el árbol con el id {character_id}\")\n    elif option == \"S\":\n        father_id = int(input(\"Dime el id del padre (solamente serán válidos los ids de personajes registrados en el árbol): \"))\n        if id_finder.find_id(root,father_id):\n            print(f\"Has elegido como padre a {character_finder.find_character(root,father_id)}\")\n            mother_id = int(input(\"Ahora el id de la madre: \"))\n            if id_finder.find_id(root,mother_id):\n                print(f\"Has elegido como madre a {character_finder.find_character(root,mother_id)}\")\n                son_id = int(input(\"Y para finalizar el del hijo (en este caso solo hace falta que esté dado de alta o creado): \"))\n                if __find_id_in_list_of_characters(son_id,list_of_characters):\n                    print(f\"Has elegido como hijo a {__find_character_in_list(son_id,list_of_characters)}\")\n                    SetChildren().set_children(character_finder.find_character(root,father_id),character_finder.find_character(root,mother_id),__find_character_in_list(son_id,list_of_characters))\n                else:\n                    print(\"El hijo/a no está creado o dado de alta\")\n            else:\n                print(\"No hay ningún personaje con ese id en el árbol, por tanto, no se puede declarar como madre\")\n        else:\n            print(\"No hay ningún personaje con ese id en el árbol, por tanto, no se puede declarar como padre\")\n    elif option == \"F\":\n        print(\" --- ÁBROL GENEALOGICO ---\")\n        tree_printer.print_tree(root,character_printer)\n    elif option == \"O\":\n        print(\"Gracias por usar el sistema del Árbol Genealógico de los Targaryen. Hasta pronto.\")\n        break\n    else:\n        print(\"Tu opción no es válida...\\n\")\n"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/python/cristianfloyd.py",
    "content": "# EJERCICIO:\n# ¡La Casa del Dragón ha finalizado y no volverá hasta 2026!\n# ¿Alguien se entera de todas las relaciones de parentesco\n# entre personajes que aparecen en la saga?\n# Desarrolla un árbol genealógico para relacionarlos (o invéntalo).\n# Requisitos:\n# 1. Estará formado por personas con las siguientes propiedades:\n#    - Identificador único (obligatorio)\n#    - Nombre (obligatorio)\n#    - Pareja (opcional)\n#    - Hijos (opcional)\n# 2. Una persona solo puede tener una pareja (para simplificarlo).\n# 3. Las relaciones deben validarse dentro de lo posible.\n#    Ejemplo: Un hijo no puede tener tres padres.\n# Acciones:\n# 1. Crea un programa que permita crear y modificar el árbol.\n#    - Añadir y eliminar personas\n#    - Modificar pareja e hijo\n# 2. Podrás imprimir el árbol (de la manera que consideres).\n#\n# NOTA: Ten en cuenta que la complejidad puede ser alta si\n# se implementan todas las posibles relaciones. Intenta marcar\n# tus propias reglas y límites para que te resulte asumible.\n\n\n# ╔══════════════════════════════════════════════════╗\n# ║ Autor:  Cristian Arenas                          ║\n# ║ GitHub: https: https://github.com/cristianfloyd  ║\n# ║ 2025 -  Python                                   ║\n# ╚══════════════════════════════════════════════════╝\n\nfrom abc import ABC\nfrom typing import Literal, Optional, overload\n\n\nclass Persona:\n    def __init__(\n        self,\n        person_id: int,\n        nombre: str,\n        pareja: Optional[\"Persona\"] = None,\n        hijos: Optional[list[\"Persona\"]] = None,\n    ):\n        self.id = person_id\n        self.nombre: str = nombre\n        self.pareja: Optional[\"Persona\"] = pareja or None\n        self.hijos: list[\"Persona\"] = hijos or []\n        self.padres: tuple[Optional[\"Persona\"], Optional[\"Persona\"]] = (None, None)\n\n    def accept_visitor(self, visitor: \"ArbolVisitorInterface\") -> None:\n        visitor.visitar(self)\n\n    def __str__(self):\n        return f\"{self.nombre} ({self.id})\"\n\n    def __repr__(self):\n        return self.__str__()\n\n\nclass ArbolGenealogico:  # funcionará como repositorio de personas\n    \"\"\"Clase que representa el árbol genealógico\"\"\"\n\n    def __init__(self):\n        self.personas: dict[int, Persona] = {}\n        self._proximo_id: int = 1\n\n    def registrar_persona(self, nombre: str):\n        \"\"\"\n        Registra una nueva persona en el arbol.\n\n        Genera un identificador unico para la persona, valida el identificador y crea un nuevo objeto persona\n        Args:\n            nombre (str): El nombre a registrar.\n\n        Raises:\n            ValueError: Si el ID generado no es válido o se viola alguna restricción de validación.\n\n        Returns:\n            Persona: El objeto persona recién registrado.\n        \"\"\"\n        nuevo_id = self._proximo_id\n        try:\n            validador = FamilyValidator(self.personas)\n            validador.validar_id(nuevo_id)\n            nueva_persona = Persona(nuevo_id, nombre)\n            self.personas[nuevo_id] = nueva_persona\n            self._proximo_id += 1\n            return nueva_persona\n        except ValueError as e:\n            raise ValueError(f\"Error al registrar persona: {e}\")\n\n    def init_get_root(self) -> list[\"Persona\"]:\n        \"\"\"Buscamos en nuestro diccionario de personas aquellas que no tienen padres asignados.\"\"\"\n        return [\n            p\n            for p in self.personas.values()\n            if p.padres[0] is None and p.padres[1] is None\n        ]\n\n    def get_persona(self, persona_id: int) -> \"Persona\":\n        \"\"\"Devuelve la persona con el ID especificado.\n        Lanza ValueError si no existe.\n        \"\"\"\n        if persona_id not in self.personas:\n            raise ValueError(f\"Persona con ID {persona_id} no encontrada\")\n        return self.personas[persona_id]\n\n    def recorrer_arbol_completo(self, visitor: \"ArbolVisitorInterface\") -> None:\n        \"\"\"Refinamiento: El árbol sabe cómo ser recorrido íntegramente\"\"\"\n        raices = self.init_get_root()\n        for raiz in raices:\n            raiz.accept_visitor(visitor)\n\n    def add_hijo(self, padre: \"Persona\", hijo: \"Persona\") -> None:\n        \"\"\"Añade un hijo a una persona.\n        \n        Args:\n            padre: La persona que será padre\n            hijo: La persona que será hijo\n            \n        Raises:\n            ValueError: Si la relación es inválida (ciclos, límite de padres, etc.)\n            \n        Example:\n            >>> arbol = ArbolGenealogico()\n            >>> padre = arbol.registrar_persona(\"Aenar\")\n            >>> hijo = arbol.registrar_persona(\"Gaemon\")\n            >>> arbol.add_hijo(padre, hijo)\n        \"\"\"\n        try:\n            validator = FamilyValidator(self.personas)\n            validator.validar(padre, hijo, \"hijo\")\n            padre.hijos.append(hijo)\n\n            if hijo.padres[0] is None:\n                hijo.padres = (padre, hijo.padres[1])\n            elif hijo.padres[1] is None:\n                hijo.padres = (hijo.padres[0], padre)\n\n        except ValueError as e:\n            raise ValueError(f\"Error al añadir hijo: {e}\")\n\n    def add_pareja(self, persona1: \"Persona\", persona2: \"Persona\") -> None:\n        \"\"\"Añade una pareja a dos personas.\n        Lanza ValueError si no es válido.\n        \"\"\"\n        try:\n            validator = FamilyValidator(self.personas)\n            validator.validar(persona1, persona2, \"pareja\")\n            persona1.pareja = persona2\n            persona2.pareja = persona1\n        except ValueError as e:\n            raise ValueError(f\"Error al añadir pareja: {e}\")\n\n    def remove_pareja(self, persona1: \"Persona\", persona2: \"Persona\") -> None:\n        \"\"\"Remueve una pareja de dos personas.\n        Lanza ValueError si no es válido.\n        \"\"\"\n        try:\n            validator = FamilyValidator(self.personas)\n            validator.validar(persona1, persona2, \"remover_pareja\")\n            persona1.pareja = None\n            persona2.pareja = None\n        except ValueError as e:\n            raise ValueError(f\"Error al remover pareja: {e}\")\n\n    def eliminar_persona(self, persona_id: int, confirmar_rotura: bool = False) -> None:\n        \"\"\"Elimina una persona.\n        Lanza ValueError si no es válido.\n        \"\"\"\n        if persona_id not in self.personas:\n            raise ValueError(f\"Persona con ID {persona_id} no encontrada\")\n\n        persona = self.personas[persona_id]\n\n        # chequear impacto eliminacion\n        if persona.hijos and not confirmar_rotura:\n            validador = FamilyValidator(self.personas)\n            validador.validar_impacto_eliminacion(persona)\n\n        # 1 desvincular la pareja\n        if persona.pareja:\n            persona.pareja.pareja = None\n            persona.pareja = None\n        # 2 desvincular los padres\n        for p in persona.padres:\n            if p:\n                p.hijos.remove(persona)\n\n        # 3 desvincular los hijos\n        for h in persona.hijos:\n            p_lista: list[Persona | None] = list(h.padres)\n            if p_lista[0] and p_lista[0].id == persona.id:\n                p_lista[0] = None\n            if p_lista[1] and p_lista[1].id == persona.id:\n                p_lista[1] = None\n            h.padres = (p_lista[0], p_lista[1])\n\n        # 4 eliminar la persona\n        del self.personas[persona_id]\n\n\n\nclass FamilyValidator:  # funcionará como validador de relaciones\n    \"\"\"Clase que valida las relaciones entre personas\"\"\"\n\n    def __init__(self, personas_existentes: dict[int, \"Persona\"]):\n        self.personas_existentes: dict[int, \"Persona\"] = personas_existentes\n\n    def validar(self, persona1: \"Persona\", persona2: \"Persona\", relacion: str):\n        match relacion:\n            case \"nuevo_registro\":\n                pass\n            case \"eliminar_persona\":\n                self.validar_impacto_eliminacion(persona1)\n            case \"pareja\":\n                self._validar_pareja(persona1, persona2)\n            case \"remover_pareja\":\n                self._validar_remover_pareja(persona1, persona2)\n            case \"hijo\":\n                self._validar_hijo(persona1, persona2)\n            case _:\n                raise ValueError(\"Relacion no valida\")\n\n    def _validar_hijo(self, padre: \"Persona\", hijo: \"Persona\"):\n        # regla 1: no puede ser su propio padre\n        if padre.id == hijo.id:\n            raise ValueError(f\"{padre.nombre} no puede ser su propio padre\")\n        # regla 2: maximo 2 padres\n        self._limite_padres(hijo)\n\n        # regla 3: no puede ser pareja de su propio padre\n        self._no_pareja_descendiente(hijo, padre)\n\n        # regla 4: deteccion de ciclos, ej.:\n        # A es hijo de B, B es hijo de C, C es hijo de A.\n        # No crear bucles infinitos\n        self._deteccion_ciclos(hijo, padre)\n\n    def _limite_padres(self, persona: \"Persona\") -> None:\n        \"\"\"\n        Valida que la persona no tenga más de 2 padres.\n        Args:\n            persona: La persona a validar\n        Raises:\n            ValueError: Si la persona ya tiene 2 padres\n        \"\"\"\n        if persona.padres[0] is not None and persona.padres[1] is not None:\n            raise ValueError(\"La persona ya tiene 2 padres\")\n\n    def _no_pareja_descendiente(self, hijo: \"Persona\", padre: \"Persona\") -> None:\n        \"\"\"\n        Valida que el hijo no sea pareja de su propio padre.\n        Args:\n            hijo: La persona que será hijo\n            padre: La persona que será padre\n        Raises:\n            ValueError: Si la relación es inválida (ciclos, límite de padres, etc.)\n        \"\"\"\n        if hijo.pareja is not None and hijo.pareja.id == padre.id:\n            raise ValueError(f\"{hijo.nombre} no puede ser pareja de su propio padre\")\n        if padre.pareja is not None and padre.pareja.id == hijo.id:\n            raise ValueError(f\"{padre.nombre} no puede ser pareja de su propio hijo\")\n\n    def _deteccion_ciclos(self, hijo: \"Persona\", padre: \"Persona\"):\n        \"\"\"\n        Funcion recursiva que detecta ciclos en el arbol genealógico\n        \"\"\"\n        if self._es_ancestro_de(hijo, padre):\n            raise ValueError(\n                f\"¡Paradoja temporal! {hijo.nombre} es ancestro de {padre.nombre}.\"\n            )\n\n    def _es_ancestro_de(self, buscar: \"Persona\", inicio: \"Persona\") -> bool:\n        \"\"\"\n        sube por el arbol desde 'inicio' buscando a 'buscar'\n        \"\"\"\n        # Si no, busca recursivamente en los padres de los padres.\n        for p in inicio.padres:\n            if p is not None:\n                if p.id == buscar.id or self._es_ancestro_de(buscar, p):\n                    return True\n        return False\n\n    def validar_id(self, id_nuevo: Optional[int]):\n        if id_nuevo is None:\n            raise ValueError(\"El id no puede ser nulo\")\n\n        if id_nuevo <= 0:\n            raise ValueError(f\"El id {id_nuevo} debe ser un entero positivo\")\n\n        if id_nuevo in self.personas_existentes:\n            raise ValueError(f\"El id {id_nuevo} ya pertenece a otra persona\")\n\n    def _validar_pareja(self, persona1: \"Persona\", persona2: \"Persona\") -> None:\n        \"\"\"Valida que persona1 y persona2 sean parejas\n        Args: persona1, persona2 (Persona)\n        \"\"\"\n        if persona1.id == persona2.id:\n            raise ValueError(f\"{persona1.nombre} no puede ser su propia pareja\")\n\n        if persona1.pareja is not None:\n            raise ValueError(\n                f\"{persona1.nombre} ya tiene una pareja: {persona1.pareja.nombre}.\"\n            )\n        if persona2.pareja is not None:\n            raise ValueError(\n                f\"{persona2.nombre} ya tiene una pareja: {persona2.pareja.nombre}.\"\n            )\n\n    def _validar_remover_pareja(self, persona1: \"Persona\", persona2: \"Persona\") -> None:\n        try:\n            if persona1.pareja is None or persona2.pareja is None:\n                raise ValueError(\n                    f\"{persona1.nombre} o {persona2.nombre} no tiene pareja\"\n                )\n            if persona1.pareja.id != persona2.id:\n                raise ValueError(\n                    f\"{persona1.nombre} y {persona2.nombre} no son parejas\"\n                )\n            if persona2.pareja.id != persona1.id:\n                raise ValueError(\n                    f\"{persona1.nombre} y {persona2.nombre} no son parejas\"\n                )\n        except ValueError as e:\n            raise ValueError(f\"Error al validar remover pareja: {e}\")\n\n    @staticmethod\n    def validar_impacto_eliminacion(persona: \"Persona\") -> None:\n        if persona.hijos:\n            raise ValueError(\n                f\"ADVERTENCIA: {persona.nombre} tiene descendientes. \"\n                \"Eliminar este nodo dividirá el árbol en dos y romperá el linaje. \"\n                \"¿Desea continuar?\"\n            )\n\n\nclass ArbolVisitorInterface(ABC):  # patron visitor\n    \"\"\"Clase que representa un visitante del árbol genealógico\n    - Interfaz\n    \"\"\"\n\n    def visitar(self, persona: \"Persona\"):\n        pass\n\n\nclass PrintArbolVisitor(ArbolVisitorInterface):  # patron visitor concreto\n    \"\"\"Clase que representa un visitante del árbol genealógico que imprimira el árbol\n    - Su estado interno es el string que está construyendo\n    - Utiliza recursividad para añadir └— y ├—.\n    \"\"\"\n\n    def __init__(self):\n        self.resultado: list[str] = []\n        self.visitados: set[int] = set()\n\n    def visitar(self, persona: \"Persona\"):\n        \"\"\"\n        Visita una persona y sus hijos de manera recursiva.\n        Args:\n            persona (Persona): La persona a visitar.\n        \"\"\"\n        if persona.id not in self.visitados:\n            # inicia el recorrido desde esta persona como raiz.\n            self._visitar_recursivo(persona, es_ultimo=True, prefijos=[])\n\n    def _visitar_recursivo(self, persona: \"Persona\", es_ultimo: bool, prefijos: list[str]):\n        \"\"\"\n        Metodo auxiliar recursivo que realiza la impresion real.\n        Args:\n            persona (Persona): La persona a visitar.\n            es_ultimo (bool): Indica si es el ultimo hijo de su padre.\n            prefijos (list[str]): Prefijos para la impresion.\n        \"\"\"\n        if persona.id in self.visitados:\n            return\n        \n        # construir el prefijo concatenando los prefijos\n        prefijo_completo = \"\".join(prefijos)\n\n        # Elegir símbolo: └─ para último hijo, ├─ para hijos intermedios\n        simbolo = \"└─\" if es_ultimo else \"├─\"\n    \n        # Construir la línea con información de la persona\n        persona_id = f\" (id: {persona.id})\" if persona.id else \"\"\n        pareja_str = f\"-> {persona.pareja.id}\" if persona.pareja else \"\"\n\n        self.resultado.append(f\"{prefijo_completo}{simbolo} {persona.nombre}{persona_id}{pareja_str}\")\n        self.visitados.add(persona.id)\n\n        # hijos que aun no han sido visitados\n        hijos_no_visitados = [h for h in persona.hijos if h.id not in self.visitados]\n\n        # recorrer hijos no visitados\n        for i, hijo in enumerate(hijos_no_visitados):\n            es_ultimo_hijo = i == len(hijos_no_visitados) - 1\n\n            # crear prefijos para el siguiente nivel\n            nuevos_prefijos = prefijos.copy()\n            nuevo_prefijo =  \"│  \" if not es_ultimo else \"   \"\n\n            nuevos_prefijos.append(nuevo_prefijo)\n\n            # llamada recursiva\n            self._visitar_recursivo(hijo, es_ultimo_hijo, nuevos_prefijos)\n    \n\n    def ejecutar(self, persona: \"Persona\"):\n        self.visitar(persona)\n        return \"\\n\".join(self.resultado)\n\n    def get_resultado(self):\n        if not self.resultado:\n            return \"No hay personajes registrados.\"\n        return \"\\n\".join(self.resultado)\n\n\nclass SearchArbolVisitor(ArbolVisitorInterface):  # patron visitor concreto\n    \"\"\"Clase que representa un visitante del árbol genealógico que buscara una persona\n    - Su estado es el resultado de la búsqueda.\n    - No imprime nada, solo acumula nodos que cumplan un criterio.\n    \"\"\"\n\n    def __init__(self, nombre_a_buscar: str):\n        self.resultado: list[\"Persona\"] = []\n        self.nombre_a_buscar: str = nombre_a_buscar.strip().lower()\n        self.visitados: set[int] = set()\n\n    def visitar(self, persona: \"Persona\"):\n        if persona.id in self.visitados:\n            return\n        \n        self.visitados.add(persona.id)\n\n        if persona.nombre.strip().lower() == self.nombre_a_buscar:\n            self.resultado.append(persona)\n\n        for hijo in persona.hijos:\n            hijo.accept_visitor(self)\n\n    def obtener_resultado(self):\n        \"\"\"\n        Returns the result stored in the object.\n        Retorna el resultado almacenado en el objeto.\n\n        Este método recupera el valor del resultado almacenado internamente en el\n        objeto. No modifica ni altera el valor almacenado y sirve como un simple\n        accessor.\n\n        Returns:\n            list[Persona]: Lista de personas que cumplen con el criterio de búsqueda.\n        \"\"\"\n        return self.resultado\n\n\nclass DinastiaUI:\n    def __init__(self, arbol_gen: \"ArbolGenealogico\") -> None:\n        self.arbol = arbol_gen\n\n    def mostrar_menu_principal(self):\n        while True:\n            print(\"\\nMenu Principal\")\n            print(\"1. Agregar persona\")\n            print(\"2. Eliminar persona\")\n            print(\"3. Buscar persona\")\n            print(\"4. Mostrar arbol\")\n            print(\"5. Agregar hijo\")\n            print(\"6. Agregar pareja\")\n            print(\"7. Eliminar pareja\")\n            print(\"8. Salir\")\n            opcion = input(\"Ingrese una opción: \").strip().lower()\n\n            match opcion:\n                case \"1\":\n                    self.agregar_persona()\n                case \"2\":\n                    self.eliminar_persona()\n                case \"3\":\n                    self.buscar_persona()\n                case \"4\":\n                    self.mostrar_arbol()\n                case \"5\":\n                    self.agregar_hijo()\n                case \"6\":\n                    self.agregar_pareja()\n                case \"7\":\n                    self.eliminar_pareja()\n                case \"8\":\n                    break\n                case _:\n                    print(\"Opción invalida. Intente de nuevo.\")\n\n    def agregar_persona(self):\n        try:\n            nombre = self.pedir_dato(\n                mensaje=\"Ingrese el nombre de la persona: \", es_entero=False\n            )\n            nuevo_registro = self.arbol.registrar_persona(nombre)\n            print(f\"Persona {nuevo_registro.nombre} registrada exitosamente.\")\n            print(f\"\\nID: {nuevo_registro.id}\")\n        except ValueError as e:\n            print(e)\n\n    def buscar_persona(self):\n        try:\n            print(\"Ingrese el nombre de la persona a buscar:\")\n            nombre = self.pedir_dato(mensaje=\"Nombre: \", es_entero=False)\n            visitor = SearchArbolVisitor(nombre)\n            self.arbol.recorrer_arbol_completo(visitor)\n            resultados = visitor.obtener_resultado()\n            if not resultados:\n                print(\"No se encontraron resultados.\")\n            else:\n                print(\"Resultados:\")\n                for r in resultados:\n                    print(f\"- {r.nombre} ({r.id})\")\n        except ValueError as e:\n            print(e)\n\n    def mostrar_arbol(self):\n        \"\"\"Muestra el arbol genealógico via visitor; maneja arbol vacío\"\"\"\n        try:\n            visitor = PrintArbolVisitor()\n            self.arbol.recorrer_arbol_completo(visitor)\n            resultado = visitor.get_resultado()\n            print(resultado)\n        except ValueError as e:\n            print(e)\n\n    def agregar_hijo(self):\n        try:\n            padre_id = self.pedir_dato(\"Ingrese el ID del padre: \", True)\n            hijo_id = self.pedir_dato(\"Ingrese el ID del hijo: \", True)\n\n            padre = self.arbol.get_persona(padre_id)\n            hijo = self.arbol.get_persona(hijo_id)\n\n            self.arbol.add_hijo(padre, hijo)\n            print(f\"Ahora {padre.nombre} es padre de {hijo.nombre}\")\n        except ValueError as e:\n            print(f\"Error: {e}\")\n\n    def agregar_pareja(self):\n        try:\n            persona1_id = self.pedir_dato(\n                mensaje=\"Ingrese el ID de la primera persona: \", es_entero=True\n            )\n            persona2_id = self.pedir_dato(\n                mensaje=\"Ingrese el ID de la segunda persona: \", es_entero=True\n            )\n\n            persona1 = self.arbol.get_persona(persona1_id)\n            persona2 = self.arbol.get_persona(persona2_id)\n            self.arbol.add_pareja(persona1, persona2)\n            print(f\"Ahora {persona1.nombre} es pareja de {persona2.nombre}\")\n        except ValueError as e:\n            print(f\"Error: {e}\")\n\n    @overload\n    @staticmethod\n    def pedir_dato(mensaje: str, es_entero: Literal[True]) -> int: ...\n\n    @overload\n    @staticmethod\n    def pedir_dato(mensaje: str, es_entero: Literal[False]) -> str: ...\n\n    @staticmethod\n    def pedir_dato(mensaje: str, es_entero: bool = False) -> None | str | int:\n        \"\"\"\n        Pide un dato al usuario.\n        Args:\n            mensaje (str): El mensaje a mostrar al usuario.\n            es_entero (bool): Indica si el dato debe ser un entero.\n        Returns:\n            None | str | int: El dato ingresado por el usuario.\n        \"\"\"\n        while True:\n            dato = input(mensaje).strip()\n            if not dato:\n                print(\"El valor no puede estar vacío. Intente de nuevo.\")\n                continue\n            if es_entero:\n                try:\n                    return int(dato)\n                except ValueError:\n                    print(\"El valor debe ser un entero. Intente de nuevo.\")\n                    continue\n            return dato\n\n    def eliminar_pareja(self):\n        try:\n            persona1_id = self.pedir_dato(\"Ingrese el ID de la primera persona: \", True)\n            persona2_id = self.pedir_dato(\"Ingrese el ID de la segunda persona: \", True)\n            persona1 = self.arbol.get_persona(persona1_id)\n            persona2 = self.arbol.get_persona(persona2_id)\n            self.arbol.remove_pareja(persona1, persona2)\n            print(f\"Ahora {persona1.nombre} no es pareja de {persona2.nombre}\")\n        except ValueError as e:\n            print(f\"Error: {e}\")\n\n    def eliminar_persona(self):\n        try:\n            id_persona = self.pedir_dato(\n                \"Ingrese el ID de la persona a eliminar: \", True\n            )\n            persona = self.arbol.get_persona(id_persona)\n            try:\n                self.arbol.eliminar_persona(id_persona)\n                print(f\"Persona {persona.nombre} eliminada exitosamente.\")\n            except ValueError as e:\n                mensaje_error = str(e)\n                if \"ADVERTENCIA\" in mensaje_error:\n                    print(f\"\\n{mensaje_error}\")\n                    confirma = input(\"Desea continuar? (s/n): \").strip().lower()\n                    if confirma == \"s\":\n                        confirma = True\n                        self.arbol.eliminar_persona(id_persona, confirma)\n                        print(f\"Persona {persona.nombre} eliminada exitosamente.\")\n                    else:\n                        print(\"Operación cancelada.\")\n                else:\n                    print(f\"Error: {e}\")\n\n        except ValueError as e:\n            print(f\"Error: {e}\")\n\n\nif __name__ == \"__main__\":\n    arbol = ArbolGenealogico()\n    aenar = arbol.registrar_persona(\"Aenar\")\n\n    gaemon = arbol.registrar_persona(\"Gaemon\")\n    daenys = arbol.registrar_persona(\"Daenys\")\n    arbol.add_hijo(aenar, gaemon)\n    arbol.add_hijo(aenar, daenys)\n    arbol.add_pareja(gaemon, daenys)\n\n    aegon = arbol.registrar_persona(\"Aegon\")\n    eleana = arbol.registrar_persona(\"Elaena\")\n    arbol.add_pareja(aegon, eleana)\n\n    arbol.add_hijo(gaemon, aegon)\n    arbol.add_hijo(daenys, aegon)\n\n    arbol.add_hijo(gaemon, eleana)\n    arbol.add_hijo(daenys, eleana)\n\n    maegon = arbol.registrar_persona(\"Maegon\")\n    aerys = arbol.registrar_persona(\"Aerys\")\n\n    arbol.add_hijo(eleana, maegon)\n    arbol.add_hijo(aegon, maegon)\n    arbol.add_hijo(eleana, aerys)\n    arbol.add_hijo(aegon, aerys)\n\n    ui = DinastiaUI(arbol)\n    ui.mostrar_menu_principal()\n"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/python/davidrguez98.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * ¡La Casa del Dragón ha finalizado y no volverá hasta 2026! \n * ¿Alguien se entera de todas las relaciones de parentesco\n * entre personajes que aparecen en la saga?\n * Desarrolla un árbol genealógico para relacionarlos (o invéntalo).\n * Requisitos:\n * 1. Estará formado por personas con las siguientes propiedades:\n *    - Identificador único (obligatorio)\n *    - Nombre (obligatorio)\n *    - Pareja (opcional)\n *    - Hijos (opcional)\n * 2. Una persona sólo puede tener una pareja (para simplificarlo).\n * 3. Las relaciones deben validarse dentro de lo posible.\n *    Ejemplo: Un hijo no puede tener tres padres.\n * Acciones:\n * 1. Crea un programa que permita crear y modificar el árbol.\n *    - Añadir y eliminar personas\n *    - Modificar pareja e hijos\n * 2. Podrás imprimir el árbol (de la manera que consideres).\n * \n * NOTA: Ten en cuenta que la complejidad puede ser alta si\n * se implementan todas las posibles relaciones. Intenta marcar\n * tus propias reglas y límites para que te resulte asumible.\n */ \"\"\"\n\n#EJERCICIO\n\nclass Person:\n\n    def __init__(self, id: int, name: str):\n        self.id = id\n        self.name = name\n        self.partner = None\n        self.children = []\n        self.has_parents = False\n\n    def add_partner(self, partner):\n        if self.partner is not None:\n            print(f\"{self.name} ya tiene pareja: {self.partner.name}\")\n        else:\n            self.partner = partner\n            partner.partner = self\n            print(f\"{self.name} es pareja de {partner.name}\")\n\n    def add_child(self, child):\n        if child not in self.children:\n            self.children.append(child)\n            print(f\"{self.name} ha tenido un hijo: {child.name}\")\n        else:\n            print(f\"{child.name} ya es hijo de {self.name}.\")\n\nclass FamilyTree:\n\n    def __init__(self):\n        self.people = {}\n\n    def add_person(self, id, name):\n        if id in self.people:\n            print(f\"La persona con ID: {id} ya existe.\")\n        else:\n            person = Person(id, name)\n            self.people[id] = person\n            print(f\"La persona con nombre {name} [ID: {id}] ha sido añadida al árbol.\")\n\n    def remove_persona(self, id):\n        if id in self.people:\n            person = self.people[id]\n            del self.people[id]\n            print(F\"La persona con nombre {person.name} [ID: {id}] ha sido eliminada del árbol.\")\n        else:\n            print(f\"La persona con ID: {id} no existe en el árbol.\")\n\n    def set_partner(self, id1, id2):\n        if id1 in self.people and id2 in self.people:\n            person1 = self.people[id1]\n            person2 = self.people[id2]\n            person1.add_partner(person2)\n        else:\n            print(\"Algún ID no existe en el árbol.\")\n\n    def add_child(self, parent_id, child_id):\n        if parent_id in self.people and child_id in self.people:\n            if parent_id == child_id:\n                print(\"Los ID no pueden ser iguales.\")\n            else:\n                parent = self.people[parent_id]\n                if parent.partner is None:\n                    print(f\"Se necesita una pareja para poder tener un hijo.\")\n                child = self.people[child_id]\n                if child.has_parents:\n                    print(f\"{child.name} [ID: {child.id} ya tiene padres.]\")\n                else:\n                    child.has_parents = True\n                    parent.add_child(child)\n                    parent.partner.add_child(child)\n        else:\n            print(\"Algún ID no existe en el árbol.\")\n\n    def print_tree(self):\n\n        visited = set()\n\n        def print_person(person, level = 0):\n            if person.id in visited:\n                return\n            \n            visited.add(person.id)\n\n            indent = \"\\t\" * level\n\n            print(f\"{indent} - {person.name} [ID: {person.id}]\")\n\n            if person.partner:\n                visited.add(person.partner.id)\n                print(f\"{indent}   Pareja: {person.partner.name} [ID: {person.id}]\")\n\n            if person.children:\n                print(f\"{indent}   Hijos:\")\n                for child in person.children:\n                    print_person(child, level + 1)\n\n\n        for person in self.people.values():\n            is_child = person.has_parents\n            if not is_child:\n                print_person(person)\n\ntree = FamilyTree()\n\ntree.add_person(1, \"Jocelyn\")\ntree.add_person(2, \"Aemon\")\n\ntree.set_partner(1, 2)\n\ntree.add_person(3, \"Rhaenys\")\n\ntree.add_child(1, 3)\n\ntree.add_person(4, \"Corlys\")\n\ntree.set_partner(3, 4)\n\ntree.add_person(5, \"Laena\")\ntree.add_person(6, \"Laenor\")\n\ntree.add_child(3, 5)\ntree.add_child(3, 6)\n\ntree.add_person(7, \"Baelon\")\ntree.add_person(8, \"Alyssa\")\n\ntree.set_partner(7, 8)\n\ntree.add_person(9, \"Viserys I\")\ntree.add_person(10, \"Daemon\")\n\ntree.add_child(7, 9)\ntree.add_child(8, 10)\n\ntree.add_person(11, \"Aemma\")\n\ntree.set_partner(9, 11)\n\ntree.add_person(12, \"Rhaenyra\")\n\ntree.add_child(9, 12)\n\ntree.set_partner(10, 12)\n\ntree.add_person(13, \"Aegon\")\ntree.add_person(14, \"Viserys\")\n\ntree.add_child(12, 13)\ntree.add_child(12, 14)\n\ntree.print_tree()"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/python/duendeintemporal.py",
    "content": "#34 { Retos para Programadores } ÁRBOL GENEALÓGICO DE LA CASA DEL DRAGÓN \n\n# Bibliography reference:\n# I use GPT as a reference and sometimes to correct or generate proper comments.\n\n\"\"\"  \n * EJERCICIO:\n * ¡La Casa del Dragón ha finalizado y no volverá hasta 2026!\n * ¿Alguien se entera de todas las relaciones de parentesco\n * entre personajes que aparecen en la saga?\n * Desarrolla un árbol genealógico para relacionarlos (o invéntalo).\n * Requisitos:\n * 1. Estará formado por personas con las siguientes propiedades:\n *    - Identificador único (obligatorio)\n *    - Nombre (obligatorio)\n *    - Pareja (opcional)\n *    - Hijos (opcional)\n * 2. Una persona sólo puede tener una pareja (para simplificarlo).\n * 3. Las relaciones deben validarse dentro de lo posible.\n *    Ejemplo: Un hijo no puede tener tres padres.\n * Acciones:\n * 1. Crea un programa que permita crear y modificar el árbol.\n *    - Añadir y eliminar personas\n *    - Modificar pareja e hijo\n * 2. Podrás imprimir el árbol (de la manera que consideres).\n * \n * NOTA: Ten en cuenta que la complejidad puede ser alta si\n * se implementan todas las posibles relaciones. Intenta marcar\n * tus propias reglas y límites para que te resulte asumible.\n\n\"\"\"\n\n\n\"\"\"   Arbol Genealógico\n\nRey Viserys I Targaryen:\n    Título: Rey de los Siete Reinos.\n    Esposas:\n        Aemma Arryn (madre de Rhaenyra y Aegon II).\n        Alicent Hightower (madre de Aegon III, Aemond y otros).\n    Hijos:\n        Con Aemma Arryn:\n            Rhaenyra Targaryen (heredera al trono).\n            Aegon II Targaryen (rival de Rhaenyra).\n        Con Alicent Hightower:\n            Aegon III Targaryen.\n            Aemond Targaryen.\n        Otros hijos (como Daeron Targaryen).\nRhaenyra Targaryen:\n    Título: Princesa de Dragonstone, heredera al trono.\n    Esposo: Laenor Velaryon (hijo de Corlys Velaryon y Rhaenys Targaryen).\n    Hijos: Joffrey Velaryon. Lucerys Velaryon. Jorah Velaryon.\nAegon II Targaryen:\n    Título: Rey de los Siete Reinos (rival de Rhaenyra).\n    Hijos: No se menciona que Aegon II tenga hijos legítimos en la serie.\nAlicent Hightower:\n    Título: Reina consorte.\n    Hijos: Aegon III Targaryen. Aemond Targaryen. Daeron Targaryen (en algunas versiones de la historia).\n    Familia: Proviene de la influyente Casa Hightower, que juega un papel importante en la política de Westeros.\nAemond Targaryen:\n    Título: Príncipe de la Casa Targaryen.\n    Hermanos: Aegon III y Daeron Targaryen.\nLaenor Velaryon:\n    Título: Príncipe de la Casa Velaryon.\n    Esposa: Rhaenyra Targaryen.\n    Hijos: Joffrey, Lucerys y Jorah Velaryon (aunque su paternidad es cuestionada). \"\"\"\n\nlog = print\n\nclass Person:\n    def __init__(self, id, name, mother='', father='', partners=None, childrens=None):\n        self.id = id\n        self.name = name\n        self.mother = mother\n        self.father = father\n        self.partners = self.set_partners(partners)\n        self.childrens = self.set_childrens(childrens)\n\n    def set_partners(self, partners):\n        if partners is None:\n            return []  # Return an empty list if no partners are provided\n        if isinstance(partners, list):\n            return partners.copy()\n        else:\n            return [partners]\n\n    def set_childrens(self, childrens):\n        if childrens is None:\n            return []  # Return an empty list if no children are provided\n        if isinstance(childrens, list):\n            return childrens.copy()\n        else:\n            return [childrens]\n\n    def get_partners(self):\n        return self.partners if self.partners else f\"there's no partners for {self.name}\"\n\n    def get_childrens(self):\n        return self.childrens if self.childrens else f\"there's no childrens for {self.name}\"\n\n\nclass GenealogyTree:\n    def __init__(self, persons=None):\n        if persons is None:\n            persons = []\n        self.persons = persons\n\n    def add_person(self, person):\n        if any(p.id == person.id for p in self.persons):\n            print(f\"The {person.name} is already added\")\n            return\n        self.persons.append(person)\n\n    def delete_person(self, person_id):\n        index = next((i for i, p in enumerate(self.persons) if p.id == person_id), -1)\n        if index == -1:\n            print(f\"The person with id {person_id} isn't already added\")\n            return\n        self.persons.pop(index)\n\n    def show_tree(self):\n        for p in self.persons:\n            print(f\"ID: {p.id}, Name: {p.name}, Mother: {p.mother}, Father: {p.father}, \"\n                  f\"Partners: {p.get_partners()}, Childrens: {p.get_childrens()}\")\n\n\n# Creating instances of Person\nking = Person(1, 'Rey Viserys I Targaryen', '', '', ['Aemma Arryn', 'Alicent Hightower'],\n              ['Rhaenyra Targaryen', 'Aegon II Targaryen', 'Aegon III Targaryen', 'Aemond Targaryen', 'Daeron Targaryen'])\nprincess = Person(2, 'Rhaenyra Targaryen', 'Aemma Arryn', 'Rey Viserys I Targaryen', ['Laenor Velaryon'],\n                  ['Joffrey Velaryon', 'Lucerys Velaryon', 'Jorah Velaryon'])\nking_aegon_ii = Person(3, 'Aegon II Targaryen', 'Aemma Arryn', 'Rey Viserys I Targaryen')\nqueen = Person(4, 'Alicent Hightower', '', '', ['Rey Viserys I Targaryen'],\n               ['Aegon III Targaryen', 'Aemond Targaryen', 'Daeron Targaryen'])\nprince_aemond = Person(5, 'Aemond Targaryen', '', '', [], [])\nprince_laenor = Person(6, 'Laenor Velaryon', '', '', ['Rhaenyra Targaryen'],\n                       ['Joffrey Velaryon', 'Lucerys Velaryon', 'Jorah Velaryon'])\n\n# Creating the genealogy tree\ndragon_house_tree = GenealogyTree([king, princess, king_aegon_ii, queen, prince_aemond, prince_laenor])\n\n# Displaying the genealogy\n\n# Displaying the genealogy tree\ndragon_house_tree.show_tree()\n\n# output:\n\"\"\"   \nID: 1, Name: Rey Viserys I Targaryen, Mother: , Father: , Partners: ['Aemma Arryn', 'Alicent Hightower'], Childrens: ['Rhaenyra Targaryen', 'Aegon II Targaryen', 'Aegon III Targaryen', 'Aemond Targaryen', 'Daeron Targaryen']\nID: 2, Name: Rhaenyra Targaryen, Mother: Aemma Arryn, Father: Rey Viserys I Targaryen, Partners: ['Laenor Velaryon'], Childrens: ['Joffrey Velaryon', 'Lucerys Velaryon', 'Jorah Velaryon']\nID: 3, Name: Aegon II Targaryen, Mother: Aemma Arryn, Father: Rey Viserys I Targaryen, Partners: there's no partners for Aegon II Targaryen, Childrens: there's no childrens for Aegon II Targaryen\nID: 4, Name: Alicent Hightower, Mother: , Father: , Partners: ['Rey Viserys I Targaryen'], Childrens: ['Aegon III Targaryen', 'Aemond Targaryen', 'Daeron Targaryen']\nID: 5, Name: Aemond Targaryen, Mother: , Father: , Partners: there's no partners for Aemond Targaryen, Childrens: there's no childrens for Aemond Targaryen\nID: 6, Name: Laenor Velaryon, Mother: , Father: , Partners: ['Rhaenyra Targaryen'], Childrens: ['Joffrey Velaryon', 'Lucerys Velaryon', 'Jorah Velaryon']\n\n\"\"\""
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/python/fborjalv.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * ¡La Casa del Dragón ha finalizado y no volverá hasta 2026!\n * ¿Alguien se entera de todas las relaciones de parentesco\n * entre personajes que aparecen en la saga?\n * Desarrolla un árbol genealógico para relacionarlos (o invéntalo).\n * Requisitos:\n * 1. Estará formado por personas con las siguientes propiedades: ✅\n *    - Identificador único (obligatorio)\n *    - Nombre (obligatorio)\n *    - Pareja (opcional)\n *    - Hijos (opcional)\n * 2. Una persona sólo puede tener una pareja (para simplificarlo). ✅\n * 3. Las relaciones deben validarse dentro de lo posible.\n *    Ejemplo: Un hijo no puede tener tres padres.\n * Acciones:\n * 1. Crea un programa que permita crear y modificar el árbol.\n *    - Añadir y eliminar personas\n *    - Modificar pareja e hijo\n * 2. Podrás imprimir el árbol (de la manera que consideres).\n * \n * NOTA: Ten en cuenta que la complejidad puede ser alta si\n * se implementan todas las posibles relaciones. Intenta marcar\n * tus propias reglas y límites para que te resulte asumible.\n */\n\n\"\"\"\n\n\nclass Person:\n\n    def __init__(self, id: int, name) -> None:\n        self.id = id\n        self.name = name\n        self.partner = None\n        self.children = []\n        self.father = None\n    \n    def add_partner(self, partner):\n        if self.partner is None:\n            self.partner = partner\n            partner.partner =self.partner\n        else:\n            print(\"Esta persona ya tiene pareja\")\n\n    def add_child(self, child):\n        self.children.append(child)\n\nclass PersonManagment:\n    def __init__(self) -> None:\n        self.person_list = {}\n    \n    def new_person(self):\n        name = input(\"Introduce el nombre de la persona: \")\n        id = input(\"Asigna un identificador: \")\n        new_person = Person(id, name)\n        self.person_list[f\"{new_person.id}\"] = new_person\n    \n    def show_all_person(self):\n            for id, person in self.person_list.items():\n                print(f\"{id}: {person.name}\")\n                if person.partner != None:\n                    print(f\"Esta casado con {person.partner.name}\")\n                else:\n                    print(\"No tiene pareja\")\n                if person.children:\n                    print(f\"Tiene hijos: {', '.join(child.name for child in person.children)}\")\n                else:\n                    print(\"No tiene hijos\")\n\n    def delete_person(self):\n        id = input(\"Introduce el identificador de la persona que quieres eliminar: \")\n        if id in self.person_list:\n            del self.person_list[id]\n            print(\"Persona eliminada correctamente\")\n        else:\n            print(\"El identificador proporcionado no se corresponde con ninguna persona\")\n\n    def edit_person(self):\n        id = input(\"Introduce el identificador de la persona que quieres modificar: \")\n        if id in self.person_list:\n            name = input(\"Introduce el nuevo nombre: \")\n            self.person_list[id].name =  name\n        else:\n            print(\"El identificador proporcionado no se corresponde con ninguna persona\")\n\n    def change_partner(self):\n        id = input(\"Introduce el Id de la persona que quieres modificar su pareja\")\n        if id in self.person_list and self.person_list[id].partner != None:\n            id_partner = input(\"Introduce el id de su nueva pareja\")\n            if id_partner in self.person_list:\n                self.person_list[id].partner = self.person_list[id_partner]\n                self.person_list[id_partner].partner = self.person_list[id]\n                print(\"Pareja añadida correctamente\")\n            else:\n                print(\"El id introducido no se corresponde con ninguna persona\")\n        else: \n            print(\"El id introducido no se corresponde con ninguna persona\")\n    \n    def add_partner(self):\n        id = input(\"Introduce el Id de la persona a la que quieres añadir una pareja: \")\n        if id in self.person_list and self.person_list[id].partner is None:\n            id_partner = input(\"Introduce el Id de la pareja: \")\n            if id_partner in self.person_list and self.person_list[id_partner].partner is None:\n                self.person_list[id].partner = self.person_list[id_partner]\n                self.person_list[id_partner].partner = self.person_list[id]\n            else:\n                print(\"El id de la pareja no existe o ya tiene pareja\")\n        else: \n            print(\"No se puede añadir una pareja. El Id no existe o ya tiene pareja\")\n\n    def add_child(self):\n        id = input(\"Introduce el id del padre: \")\n        id_child = input(\"Introduce le id del hijo: \")\n        if id in self.person_list and id_child in self.person_list: \n            self.person_list[id].children.append(self.person_list[id_child])\n        else:\n            print(\"Los ids introducidos no son correctos\")\n                \ndef main_menu():\n\n    person_managment = PersonManagment()\n\n    while True:\n        print(\"\\n--- Menú Principal ---\")\n        print(\"1. Añadir persona✅\")\n        print(\"2. Mostrar todas las personas✅\")\n        print(\"3. Eliminar persona✅\")\n        print(\"4. Editar persona\")\n        print(\"5. Añadir pareja✅\")\n        print(\"6. Cambiar pareja\")\n        print(\"7. Añadir hij@✅\")\n        print(\"8. Dibujar árbol genealógico\")\n        print(\"9. Salir\")\n\n        option = input(\"Introduce una opción: \")\n\n        match option:\n            case \"1\":\n                person_managment.new_person()\n            case \"2\":\n                person_managment.show_all_person()\n            case \"3\":\n                person_managment.delete_person()\n            case \"4\":\n                person_managment.edit_person()\n            case \"5\":\n                person_managment.add_partner()\n            case \"6\":\n                person_managment.change_partner()\n            case \"7\":\n                person_managment.add_child()\n            case \"8\":\n                break\n\n\n\nmain_menu()"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/python/franxiscodev.py",
    "content": "'''\nArbol genealógico de la casa del dragón\n'''\n\n\nclass Person:\n    def __init__(self, id: int, name: str):\n        self.id = id\n        self.name = name\n        self.partner = None\n        self.children = []\n\n    def add_partner(self, partner):\n        if self.partner is not None:\n            print(f\"Esta persona ya tiene pareja: {self.partner.name}\")\n        else:\n            self.partner = partner\n            partner.partner = self  # no es una relación unilateral\n            print(f\"{self.name} es pareja de {partner.name} y viceversa\")\n\n    def add_child(self, child):\n        if self.partner == None:\n            print(\"No puedes tener hijos sin pareja.\")\n        elif child not in self.children:\n            self.children.append(child)\n            self.partner.children.append(child)  # hijo de ambos\n            print(\n                f\"{self.name} ha tenido un hijo: {child.name} junto a su pareja {self.partner.name}\")\n        else:\n            print(f\"{self.name} ya tiene un hijo: {child.name}\")\n\n\nclass FamilyTree:\n    def __init__(self):\n        self.people = {}\n\n    def add_person(self, id: int, name: str):\n        if id not in self.people:\n            person = Person(id, name)\n            self.people[id] = person\n            print(f\"La persona {name} con ID:{id} se agregó al árbol.\")\n        else:\n            print(f\"El ID: {id} ya existe.\")\n\n    def remove_person(self, id: int):\n        if id in self.people:\n            person = self.people[id]\n            del self.people[id]\n            print(f\"Se eliminó el ID: {id} de la persona {person.name}.\")\n        else:\n            print(f\"Persona con ID: {id} no existe.\")\n\n    def set_partner(self, id: int, partner_id: int):\n        if id in self.people and partner_id in self.people:\n            person = self.people[id]\n            partner = self.people[partner_id]\n            person.add_partner(partner)\n        else:\n            print(\n                f\"Una de las personas no existe. ID: {id} o ID: {partner_id}\")\n\n    def set_child(self, parent_id: int, child_id: int):\n        if parent_id == child_id:\n            print(\"No puedes ser padre de ti mismo.\")\n        elif parent_id in self.people and child_id in self.people:\n            parent = self.people[parent_id]\n            child = self.people[child_id]\n            parent.add_child(child)\n        else:\n            print(\n                f\"Una de las personas no existe. ID: {parent_id} o ID: {child_id}\")\n\n    def print_tree(self):\n        for person in self.people.values():\n            print(\n                f\"ID: {person.id}, Name: {person.name}, Partner: {person.partner.name if person.partner else 'None'}, Children: {[child.name for child in person.children]}\")\n\n\ntree = FamilyTree()\ntree.add_person(1, \"Alicia\")\ntree.add_person(2, \"Bob\")\ntree.add_person(3, \"Charlie\")\n\ntree.set_partner(1, 3)  # Alicia es pareja de Charlie\ntree.set_child(1, 2)    # Alicia es madre de Bob\n# tree.set_child(3, 2)    # Charlie es padre de Bob, no es necesario lo fuerzo por ser pareja de ... que ya tiene un hijo\ntree.set_child(3, 3)    # No puedes ser padre de ti mismo.\n\ntree.print_tree()\n"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/python/hectorio23.py",
    "content": "#! /bin/python3.12\n\n# Autor: Héctor Adán\n# GitHub: https://github.com/hectorio23\n\nclass Person:\n    def __init__(self, id, name, partner=None):\n        self.id = id  \n        self.name = name \n        self.partner = partner  \n        self.children = []  \n\n    def add_child(self, child):\n        if len(child.parents()) < 2:\n            self.children.append(child)\n        else:\n            raise ValueError(f\"{child.name} already has two parents.\")\n\n    def set_partner(self, partner):\n        if self.partner is None:\n            self.partner = partner\n            partner.partner = self\n        else:\n            raise ValueError(f\"{self.name} is already partnered with {self.partner.name}.\")\n\n    def parents(self):\n        # Get the parents by finding people who have this person as a child\n        return [p for p in Person.instances if self in p.children]\n\n    @staticmethod\n    def display_tree(person, level=0):\n        if person.partner:\n            print(\"  \" * level + person.partner.name)\n\n        print(\"  \" * level + person.name)\n        for child in person.children:\n            Person.display_tree(child, level + 1)\n\n\n# Sample usage examples\nPerson.instances = []\nalice = Person(1, \"Andrea\")\nbob = Person(2, \"Adán\")\nalice.set_partner(bob)\nchild = Person(3, \"Alejandro\")\nalice.add_child(child)\nchild.add_child(Person(4, \"María\"))\nPerson.display_tree(alice)\n\n"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/python/hozlucas28.py",
    "content": "# pylint: disable=missing-module-docstring,missing-class-docstring,missing-function-docstring,too-many-arguments\n\nfrom abc import ABCMeta, abstractmethod\nfrom typing import Literal\nfrom uuid import UUID, uuid4\n\n\n# ---------------------------------------------------------------------------- #\n#                                     TYPES                                    #\n# ---------------------------------------------------------------------------- #\n\ntype FamilyStatus = Literal[\"father\", \"mother\"]\n\n\n# ---------------------------------------------------------------------------- #\n#                                  EXCEPTIONS                                  #\n# ---------------------------------------------------------------------------- #\n\n\nclass FamilyTreeHasNotPeopleException(Exception):\n    def __init__(self) -> None:\n        super().__init__(\"Family tree does not have people\")\n\n\nclass PersonNotFoundException(Exception):\n    def __init__(self, *, uuid: UUID) -> None:\n        super().__init__(f\"Person with {uuid} UUID not found\")\n\n\n# ---------------------------------------------------------------------------- #\n#                                    CLASSES                                   #\n# ---------------------------------------------------------------------------- #\n\n\nclass AbcPerson(metaclass=ABCMeta):\n    @property\n    @abstractmethod\n    def name(self) -> str:\n        pass\n\n    @property\n    @abstractmethod\n    def uuid(self) -> UUID:\n        pass\n\n    @property\n    @abstractmethod\n    def children(self) -> \"list[AbcPerson] | None\":\n        pass\n\n    @property\n    @abstractmethod\n    def partner(self) -> \"AbcPerson | None\":\n        pass\n\n    @property\n    @abstractmethod\n    def family_status(self) -> FamilyStatus | None:\n        pass\n\n    @property\n    @abstractmethod\n    def father(self) -> \"AbcPerson | None\":\n        pass\n\n    @property\n    @abstractmethod\n    def mother(self) -> \"AbcPerson | None\":\n        pass\n\n    @partner.setter\n    def partner(self, partner: \"AbcPerson\") -> None:\n        pass\n\n    @abstractmethod\n    def add_children(self, *children: \"AbcPerson\") -> None:\n        pass\n\n    @abstractmethod\n    def remove_children(self, *children: UUID) -> None:\n        pass\n\n\nclass Person(AbcPerson):\n    __name: str\n    __uuid: UUID\n    __children: list[AbcPerson] | None\n    __partner: AbcPerson | None\n    __family_status: FamilyStatus | None\n    __father: AbcPerson | None\n    __mother: AbcPerson | None\n\n    def __init__(\n        self,\n        *,\n        name: str,\n        uuid: UUID,\n        children: list[AbcPerson] | None = None,\n        partner: AbcPerson | None = None,\n        familyStatus: FamilyStatus | None = None,\n        father: AbcPerson | None = None,\n        mother: AbcPerson | None = None,\n    ) -> None:\n        if partner is not None:\n            partner.partner = self\n\n        if father is not None:\n            father.add_children(self)\n\n        if mother is not None:\n            mother.add_children(self)\n\n        self.__name = name\n        self.__uuid = uuid\n        self.__children = children\n        self.__partner = partner\n        self.__family_status = familyStatus\n        self.__father = father\n        self.__mother = mother\n\n    @property\n    def name(self) -> str:\n        return self.__name\n\n    @property\n    def uuid(self) -> UUID:\n        return self.__uuid\n\n    @property\n    def children(self) -> \"list[AbcPerson] | None\":\n        return self.__children\n\n    @property\n    def partner(self) -> \"AbcPerson | None\":\n        return self.__partner\n\n    @property\n    def family_status(self) -> FamilyStatus | None:\n        return self.__family_status\n\n    @property\n    def father(self) -> \"AbcPerson | None\":\n        return self.__father\n\n    @property\n    def mother(self) -> \"AbcPerson | None\":\n        return self.__mother\n\n    @partner.setter\n    def partner(self, partner: \"AbcPerson\") -> None:\n        self.__partner = partner\n\n    def add_children(self, *children: \"AbcPerson\") -> None:\n        if self.__children is None:\n            self.__children = [*children]\n        else:\n            self.__children.append(*children)\n\n    def remove_children(self, *children: UUID) -> None:\n        if self.__children is None:\n            return\n\n        self.__children = list(\n            filter(\n                lambda person: person.uuid not in children,\n                self.__children,\n            )\n        )\n\n\n# -------------------------------- FamilyTree -------------------------------- #\n\n\nclass AbcFamilyTree(metaclass=ABCMeta):\n    @property\n    @abstractmethod\n    def people(self) -> list[AbcPerson] | None:\n        pass\n\n    @abstractmethod\n    def get_person(self, *, uuid: UUID) -> AbcPerson:\n        pass\n\n    @abstractmethod\n    def add_people(self, *people: AbcPerson) -> None:\n        pass\n\n    @abstractmethod\n    def remove_people(self, *people: UUID) -> None:\n        pass\n\n    @abstractmethod\n    def __repr__(self) -> str:\n        pass\n\n\nclass FamilyTree(AbcFamilyTree):\n    __people: list[AbcPerson] | None\n\n    def __init__(self, *, people: list[AbcPerson] | None = None) -> None:\n        self.__people = people\n\n    @property\n    def people(self) -> list[AbcPerson] | None:\n        return self.__people\n\n    def get_person(self, *, uuid: UUID) -> AbcPerson:\n        if self.__people is None:\n            raise FamilyTreeHasNotPeopleException()\n\n        for _person in self.__people:\n            if _person.uuid == uuid:\n                return _person\n\n        raise PersonNotFoundException(uuid=uuid)\n\n    def add_people(self, *people: AbcPerson) -> None:\n        if self.__people is None:\n            self.__people = [*people]\n        else:\n            self.__people.append(*people)\n\n    def remove_people(self, *people_uuids: UUID) -> None:\n        if self.__people is None:\n            raise FamilyTreeHasNotPeopleException()\n\n        self.__people = list(\n            filter(\n                lambda person: person.uuid not in people_uuids,\n                self.__people,\n            )\n        )\n\n    def __repr__(self) -> str:\n        if self.__people is None:\n            raise FamilyTreeHasNotPeopleException()\n\n        _repr: list[str] = [\n            f\"|-{''.center(20, '-')}-|-\"\n            f\"{'-'.center(64, '-')}-|-\"\n            f\"{'-'.center(16, '-')}-|-\"\n            f\"{'-'.center(20, '-')}-|-\"\n            f\"{'-'.center(20, '-')}-|-\"\n            f\"{'-'.center(20, '-')}-|\",\n            f\"| {'name'.center(20)} | \"\n            f\"{'children'.center(64)} | \"\n            f\"{'family_status'.center(16)} | \"\n            f\"{'father'.center(20)} | \"\n            f\"{'mother'.center(20)} | \"\n            f\"{'partner'.center(20)} |\",\n            f\"|-{''.center(20, '-')}-|-\"\n            f\"{'-'.center(64, '-')}-|-\"\n            f\"{'-'.center(16, '-')}-|-\"\n            f\"{'-'.center(20, '-')}-|-\"\n            f\"{'-'.center(20, '-')}-|-\"\n            f\"{'-'.center(20, '-')}-|\",\n        ]\n\n        for person in self.__people:\n            name: str = person.name\n            family_status: str = (\n                person.family_status if person.family_status is not None else \"None\"\n            )\n            father: str = person.father.name if person.father is not None else \"None\"\n            mother: str = person.mother.name if person.mother is not None else \"None\"\n            partner: str = person.partner.name if person.partner is not None else \"None\"\n\n            children: str = \"None\"\n            if person.children is not None:\n                children = \"\"\n                for j, child in enumerate(iterable=person.children):\n                    if j == 0:\n                        children = (\n                            f\"{child.name}.\" if len(person.children) < 2 else child.name\n                        )\n                    elif j == len(person.children) - 1:\n                        children += f\", and {child.name}.\"\n                    else:\n                        children += f\", {child.name}\"\n\n            _repr.append(\n                f\"| {name.ljust(20)} | \"\n                f\"{children.ljust(64)} | \"\n                f\"{family_status.ljust(16)} | \"\n                f\"{father.ljust(20)} | \"\n                f\"{mother.ljust(20)} | \"\n                f\"{partner.ljust(20)} |\"\n                f\"\\n|-{''.center(20, '-')}-|-\"\n                f\"{'-'.center(64, '-')}-|-\"\n                f\"{'-'.center(16, '-')}-|-\"\n                f\"{'-'.center(20, '-')}-|-\"\n                f\"{'-'.center(20, '-')}-|-\"\n                f\"{'-'.center(20, '-')}-|\",\n            )\n\n        return \"\\n\".join(_repr)\n\n\n# ---------------------------------------------------------------------------- #\n#                                     MAIN                                     #\n# ---------------------------------------------------------------------------- #\n\n\njaehaerysTargaryen: Person = Person(\n    name=\"Jaehaerys Targaryen\",\n    uuid=uuid4(),\n    familyStatus=\"father\",\n)\n\nalysanneTargaryen: Person = Person(\n    name=\"Alysanne Targaryen\",\n    uuid=uuid4(),\n    partner=jaehaerysTargaryen,\n    familyStatus=\"mother\",\n)\n\njocelynBaratheon: Person = Person(\n    name=\"Jocelyn Baratheon\",\n    uuid=uuid4(),\n    familyStatus=\"mother\",\n)\n\naemonTargaryen: Person = Person(\n    name=\"Aemon Targaryen\",\n    uuid=uuid4(),\n    partner=jocelynBaratheon,\n    familyStatus=\"father\",\n    father=jaehaerysTargaryen,\n    mother=alysanneTargaryen,\n)\n\nbaelonTargaryen: Person = Person(\n    name=\"Baelon Targaryen\",\n    uuid=uuid4(),\n    familyStatus=\"mother\",\n    father=jaehaerysTargaryen,\n    mother=alysanneTargaryen,\n)\n\nalyssaTargaryen: Person = Person(\n    name=\"Alyssa Targaryen\",\n    uuid=uuid4(),\n    partner=baelonTargaryen,\n    familyStatus=\"mother\",\n    father=jaehaerysTargaryen,\n    mother=alysanneTargaryen,\n)\n\nlyonelStrong: Person = Person(\n    name=\"Lyonel Strong\",\n    uuid=uuid4(),\n    familyStatus=\"father\",\n)\n\nvaemondValaryon: Person = Person(\n    name=\"Vaemond Valaryon\",\n    uuid=uuid4(),\n)\n\ncorlysVelaryon: Person = Person(\n    name=\"Corlys Velaryon\",\n    uuid=uuid4(),\n    familyStatus=\"father\",\n)\n\nrhaenysTargaryen: Person = Person(\n    name=\"Rhaenys Targaryen\",\n    uuid=uuid4(),\n    familyStatus=\"mother\",\n    partner=corlysVelaryon,\n    father=aemonTargaryen,\n    mother=jocelynBaratheon,\n)\n\nrheaRoyce: Person = Person(\n    name=\"Rhea Royce\",\n    uuid=uuid4(),\n    familyStatus=\"mother\",\n)\n\ndaemonTargaryen: Person = Person(\n    name=\"Daemon Targaryen\",\n    uuid=uuid4(),\n    familyStatus=\"father\",\n    partner=rheaRoyce,\n    father=baelonTargaryen,\n    mother=alyssaTargaryen,\n)\n\naemmaArryn: Person = Person(\n    name=\"Aemma Arryn\",\n    uuid=uuid4(),\n    familyStatus=\"mother\",\n)\n\nviserysTargaryen: Person = Person(\n    name=\"Viserys Targaryen\",\n    uuid=uuid4(),\n    familyStatus=\"father\",\n    partner=aemmaArryn,\n    father=baelonTargaryen,\n    mother=alyssaTargaryen,\n)\n\nottoHightower: Person = Person(\n    name=\"Otto Hightower\",\n    uuid=uuid4(),\n    familyStatus=\"father\",\n)\n\nhobertHightower: Person = Person(\n    name=\"Hobert Hightower\",\n    uuid=uuid4(),\n)\n\nfamilyTree: FamilyTree = FamilyTree()\n\nfamilyTree.add_people(\n    jaehaerysTargaryen,\n    alysanneTargaryen,\n    jocelynBaratheon,\n    aemonTargaryen,\n    baelonTargaryen,\n    alyssaTargaryen,\n    lyonelStrong,\n    vaemondValaryon,\n    corlysVelaryon,\n    rhaenysTargaryen,\n    rheaRoyce,\n    daemonTargaryen,\n    aemmaArryn,\n    viserysTargaryen,\n    ottoHightower,\n    hobertHightower,\n)\n\nprint(\"House of Dragon family tree from the first row to the third one...\\n\")\n\nprint(familyTree)\n\nprint(\n    \"\\n> House of Dragon official family tree: \"\n    + \"https://www.hbo.com/house-of-the-dragon/character-guide\"\n)\n"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/python/idiegorojas.py",
    "content": "\"\"\"\n# 34 - Arbol Genealogico Casa del Dragon\n\"\"\"\n# Desarrolla un árbol genealógico para relacionarlos (o invéntalo).\n\n\n\"\"\"\nRequisitos:\n\"\"\"\n# 1. Estará formado por personas con las siguientes propiedades:\n    # Identificador único (obligatorio)\n    # Nombre (obligatorio)\n    # Pareja (opcional)\n    # Hijos (opcional)\n# 2. Una persona sólo puede tener una pareja (para simplificarlo).\n# 3. Las relaciones deben validarse dentro de lo posible.\n    # Ejemplo: Un hijo no puede tener tres padres. \n\n\n\"\"\"\nAcciones:\n\"\"\" \n\n# 1. Crea un programa que permita crear y modificar el árbol.\n    # Añadir y eliminar personas\n    # Modificar pareja e hijo\n# 2. Podrás imprimir el árbol (de la manera que consideres).\n\n# NOTA: Ten en cuenta que la complejidad puede ser alta si se implementan todas las posibles relaciones. Intenta marcar tus propias reglas y límites para que te resulte asumible.\n\n\nclass Persona:\n    def __init__(self, id, nombre):\n        self.id = id\n        self.nombre = nombre\n        self.pareja = None\n        self.hijos = []\n    \n    def anadir_hijo(self, persona):\n        if persona not in self.hijos:\n            self.hijos.append(persona)\n            return True\n        return False\n    \n    def establecer_pareja(self, persona):\n        self.pareja = persona\n        return True\n    \n    def eliminar_hijo(self, persona):\n        if persona in self.hijos:\n            self.hijos.remove(persona)\n            return True\n        return False\n    \n    def eliminar_pareja(self):\n        self.pareja = None\n        return True\n    \n    def __str__(self):\n        return f\"{self.nombre} (ID: {self.id})\"\n\n\nclass ArbolGenealogico:\n    def __init__(self):\n        self.personas = {}\n        self.ultimo_id = 0\n    \n    def anadir_persona(self, nombre):\n        self.ultimo_id += 1\n        persona = Persona(self.ultimo_id, nombre)\n        self.personas[self.ultimo_id] = persona\n        return persona\n    \n    def eliminar_persona(self, id):\n        if id in self.personas:\n            persona_eliminar = self.personas[id]\n            \n            # Eliminar relaciones de pareja\n            for persona in self.personas.values():\n                if persona.pareja == persona_eliminar:\n                    persona.eliminar_pareja()\n            \n            # Eliminar relaciones de hijos\n            for persona in self.personas.values():\n                if persona_eliminar in persona.hijos:\n                    persona.eliminar_hijo(persona_eliminar)\n            \n            # Eliminar la persona del diccionario\n            del self.personas[id]\n            return True\n        return False\n    \n    def establecer_pareja(self, id1, id2):\n        if id1 in self.personas and id2 in self.personas:\n            persona1 = self.personas[id1]\n            persona2 = self.personas[id2]\n            \n            # Validar que ninguno tenga pareja ya\n            if persona1.pareja is not None or persona2.pareja is not None:\n                return False\n            \n            persona1.establecer_pareja(persona2)\n            persona2.establecer_pareja(persona1)\n            return True\n        return False\n    \n    def es_ancestro(self, posible_ancestro, persona):\n        \"\"\"Verifica si posible_ancestro es ancestro de persona\"\"\"\n        if posible_ancestro == persona:\n            return True\n        \n        for p in self.personas.values():\n            if persona in p.hijos and self.es_ancestro(posible_ancestro, p):\n                return True\n        \n        return False\n    \n    def anadir_hijo(self, id_padre, id_hijo):\n        if id_padre in self.personas and id_hijo in self.personas:\n            padre = self.personas[id_padre]\n            hijo = self.personas[id_hijo]\n            \n            # Validar que no se creen ciclos\n            if self.es_ancestro(hijo, padre):\n                return False\n            \n            # Contar padres actuales\n            contador_padres = sum(1 for p in self.personas.values() if hijo in p.hijos)\n            \n            # Validar que no tenga más de 2 padres\n            if contador_padres >= 2:\n                return False\n            \n            return padre.anadir_hijo(hijo)\n        return False\n    \n    def eliminar_relacion_hijo(self, id_padre, id_hijo):\n        if id_padre in self.personas and id_hijo in self.personas:\n            padre = self.personas[id_padre]\n            hijo = self.personas[id_hijo]\n            return padre.eliminar_hijo(hijo)\n        return False\n    \n    def eliminar_pareja(self, id):\n        if id in self.personas:\n            persona = self.personas[id]\n            if persona.pareja:\n                pareja = persona.pareja\n                persona.eliminar_pareja()\n                pareja.eliminar_pareja()\n                return True\n        return False\n    \n    def imprimir_arbol(self):\n        # Encontrar raíces (personas sin padres)\n        raices = []\n        for persona in self.personas.values():\n            es_hijo = False\n            for otra in self.personas.values():\n                if persona in otra.hijos:\n                    es_hijo = True\n                    break\n            if not es_hijo:\n                raices.append(persona)\n        \n        if not raices:\n            print(\"El árbol está vacío o no hay personas sin padres.\")\n            return\n        \n        # Imprimir árbol\n        print(\"\\n=== ÁRBOL GENEALÓGICO ===\")\n        for raiz in raices:\n            self._imprimir_subarbol(raiz, 0)\n    \n    def _imprimir_subarbol(self, persona, nivel):\n        espacios = \"  \" * nivel\n        info_pareja = f\" - Pareja: {persona.pareja.nombre}\" if persona.pareja else \"\"\n        print(f\"{espacios}{persona.nombre} (ID: {persona.id}){info_pareja}\")\n        \n        for hijo in persona.hijos:\n            self._imprimir_subarbol(hijo, nivel + 1)\n\n\ndef main():\n    arbol = ArbolGenealogico()\n    \n    # Ejemplo: Creando algunos personajes de La Casa del Dragón\n    viserys = arbol.anadir_persona(\"Viserys Targaryen\")\n    aemma = arbol.anadir_persona(\"Aemma Arryn\")\n    alicent = arbol.anadir_persona(\"Alicent Hightower\")\n    rhaenyra = arbol.anadir_persona(\"Rhaenyra Targaryen\")\n    daemon = arbol.anadir_persona(\"Daemon Targaryen\")\n    aegon = arbol.anadir_persona(\"Aegon II Targaryen\")\n    \n    # Estableciendo algunas relaciones iniciales\n    arbol.establecer_pareja(viserys.id, aemma.id)\n    arbol.anadir_hijo(viserys.id, rhaenyra.id)\n    arbol.anadir_hijo(aemma.id, rhaenyra.id)\n    \n    # Después de la muerte de Aemma\n    arbol.eliminar_pareja(viserys.id)\n    arbol.establecer_pareja(viserys.id, alicent.id)\n    arbol.anadir_hijo(viserys.id, aegon.id)\n    arbol.anadir_hijo(alicent.id, aegon.id)\n    \n    arbol.establecer_pareja(rhaenyra.id, daemon.id)\n    \n    while True:\n        print(\"\\n=== MENÚ ÁRBOL GENEALÓGICO ===\")\n        print(\"1. Añadir persona\")\n        print(\"2. Eliminar persona\")\n        print(\"3. Establecer pareja\")\n        print(\"4. Eliminar pareja\")\n        print(\"5. Añadir hijo\")\n        print(\"6. Eliminar relación padre-hijo\")\n        print(\"7. Imprimir árbol genealógico\")\n        print(\"8. Salir\")\n        \n        opcion = input(\"\\nSeleccione una opción: \")\n        \n        if opcion == \"1\":\n            nombre = input(\"Nombre de la persona: \")\n            persona = arbol.anadir_persona(nombre)\n            print(f\"Persona añadida con ID: {persona.id}\")\n        \n        elif opcion == \"2\":\n            try:\n                id = int(input(\"ID de la persona a eliminar: \"))\n                if arbol.eliminar_persona(id):\n                    print(\"Persona eliminada correctamente\")\n                else:\n                    print(\"No se encontró la persona con ese ID\")\n            except ValueError:\n                print(\"Por favor, introduzca un número válido\")\n        \n        elif opcion == \"3\":\n            try:\n                id1 = int(input(\"ID de la primera persona: \"))\n                id2 = int(input(\"ID de la segunda persona: \"))\n                if arbol.establecer_pareja(id1, id2):\n                    print(\"Pareja establecida correctamente\")\n                else:\n                    print(\"No se pudo establecer la pareja (IDs no válidos o alguno ya tiene pareja)\")\n            except ValueError:\n                print(\"Por favor, introduzca números válidos\")\n        \n        elif opcion == \"4\":\n            try:\n                id = int(input(\"ID de una de las personas de la pareja: \"))\n                if arbol.eliminar_pareja(id):\n                    print(\"Pareja eliminada correctamente\")\n                else:\n                    print(\"No se pudo eliminar la pareja (ID no válido o no tiene pareja)\")\n            except ValueError:\n                print(\"Por favor, introduzca un número válido\")\n        \n        elif opcion == \"5\":\n            try:\n                id_padre = int(input(\"ID del padre/madre: \"))\n                id_hijo = int(input(\"ID del hijo: \"))\n                if arbol.anadir_hijo(id_padre, id_hijo):\n                    print(\"Relación padre-hijo establecida correctamente\")\n                else:\n                    print(\"No se pudo establecer la relación (IDs no válidos, ya existe relación, o se crearía ciclo)\")\n            except ValueError:\n                print(\"Por favor, introduzca números válidos\")\n        \n        elif opcion == \"6\":\n            try:\n                id_padre = int(input(\"ID del padre/madre: \"))\n                id_hijo = int(input(\"ID del hijo: \"))\n                if arbol.eliminar_relacion_hijo(id_padre, id_hijo):\n                    print(\"Relación padre-hijo eliminada correctamente\")\n                else:\n                    print(\"No se pudo eliminar la relación (IDs no válidos o no existe la relación)\")\n            except ValueError:\n                print(\"Por favor, introduzca números válidos\")\n        \n        elif opcion == \"7\":\n            arbol.imprimir_arbol()\n        \n        elif opcion == \"8\":\n            print(\"¡Hasta pronto!\")\n            break\n        \n        else:\n            print(\"Opción no válida. Intente de nuevo.\")\n\n\nif __name__ == \"__main__\":\n    main()"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/python/ignaciovihe.py",
    "content": "\"\"\"\n* EJERCICIO:\n * ¡La Casa del Dragón ha finalizado y no volverá hasta 2026! \n * ¿Alguien se entera de todas las relaciones de parentesco\n * entre personajes que aparecen en la saga?\n * Desarrolla un árbol genealógico para relacionarlos (o invéntalo).\n * Requisitos:\n * 1. Estará formado por personas con las siguientes propiedades:\n *    - Identificador único (obligatorio)\n *    - Nombre (obligatorio)\n *    - Pareja (opcional)\n *    - Hijos (opcional)\n * 2. Una persona sólo puede tener una pareja (para simplificarlo).\n * 3. Las relaciones deben validarse dentro de lo posible.\n *    Ejemplo: Un hijo no puede tener tres padres.\n * Acciones:\n * 1. Crea un programa que permita crear y modificar el árbol.\n *    - Añadir y eliminar personas\n *    - Modificar pareja e hijos\n * 2. Podrás imprimir el árbol (de la manera que consideres).\n * \n * NOTA: Ten en cuenta que la complejidad puede ser alta si\n * se implementan todas las posibles relaciones. Intenta marcar\n * tus propias reglas y límites para que te resulte asumible.\n\"\"\"\n\nfrom uuid import uuid4\n\n# Contiene la informacion de cada mienbro.\nclass Person:\n\n    _id_counter = 1 # Se utiliza para crear el id. Se podria usar uuid4 pero serian ids mas complejos.\n    \n    def __init__(self, name: str):\n        self.id = Person._id_counter\n        Person._id_counter += 1\n        self.name = name\n        self.parents = []\n        self.partners = {} # Para implementar varias parejas he diseñado un dicccionario con {id_pareja:[hijos]}\n\n\nclass Family: # Esta clase es como un diccionario que une cada id de persona con su objeto Persona. Para poder hacer busquedas rapidas.\n    def __init__(self):\n        self.members = {}\n\n    def __getitem__(self, index):# permite obtener un item sin tener que acceder a family.members[i]-> simplemente family[i]\n        return self.members[index]\n    \n    def __setitem__(self, key, value):# lo mismo para setear un valor\n        self.members[key] = value\n\n    def __contains__(self, key):# para poder usar in family directamente (no in family.members)\n        return key in self.members\n    \n    def __len__(self):\n        return len(self.members)# para obtener len fa family directamente.\n\n\n# Esta clase se encarga de gestionar las personas y añadir relaciones en family.\nclass FamilyManager:\n    def __init__(self, family: Family):\n        self.family = family\n\n    def add_person(self, person: Person):\n        self.family[person.id] = person\n\n    def add_partner(self, person: Person, partner: Person):\n        if person.id in self.family and partner.id in self.family:\n            if partner.id not in person.partners:\n                person.partners[partner.id] = []\n                partner.partners[person.id] =[]\n            else:\n                print(\"Ya esta registrada la pareja.\")\n        else:\n            print(\"Una de las personas no esta añadida a la familia.\")\n\n    def add_child(self, parent: Person, partner: Person, child: Person):\n        if parent.id in self.family and partner.id in self.family and child.id in self.family:\n            if partner.id in parent.partners and not child.parents:\n                parent.partners[partner.id].append(child)\n                partner.partners[parent.id].append(child)\n                child.parents.append(parent)\n                child.parents.append(partner)\n            else:\n                print(\"Las personas pasadas no son pareja, o el hijo ya tiene padres.\")\n        else:\n            print(\"El padre, madre o el hijo no estan añadidas a la familia\")\n\n\n# Se encarga de imprimir el arbol familiar a partir de una raiz de forma recursiva.\n# Lo he diseñado para que imprime todas las parejas de cada miembro y sus hijos.\n#Aunque se repita alguna persona. Con el id se puede ver si se refiere a la misma.\nclass FamilyPrinter:\n    def __init__(self, family: Family):\n        self.family = family\n\n    def print_family_tree(self, root: Person, prefix: str = \"\", is_last: bool = True):\n\n        branch = \"└─ \" if is_last else \"├─ \"\n        print(f\"{prefix}{branch}{root.name}[id={root.id}]\")\n\n        if is_last:\n            prefix_partner = prefix + \"   \"\n        else:\n            prefix_partner = prefix + \"│  \"\n\n        partners = root.partners.keys()\n        for i , id_partner in enumerate(partners):\n            is_last_partner = i == len(partners) - 1\n            branch_partner = \"└─ \" if is_last_partner else \"├─ \"\n            print(f\"{prefix_partner}{branch_partner}💍- {self.family[id_partner].name}[id={self.family[id_partner].id}]\")\n\n            if is_last_partner:\n                prefix_child = prefix_partner + \"   \"\n            else:\n                prefix_child = prefix_partner + \"│  \"\n\n            children = root.partners[id_partner]\n            for i, child in enumerate(children):\n                is_last_child = i == len(children) - 1\n                self.print_family_tree(child, prefix_child, is_last_child)\n\n\ndef main():\n    print()\n    print()\n    family = Family()\n    family_manager = FamilyManager(family)\n    family_printer = FamilyPrinter(family)\n\n    p1 = Person(\"Jocelyn\")\n    p2 = Person(\"Aemon\")\n    family_manager.add_person(p1)\n    family_manager.add_person(p2)\n    family_manager.add_partner(p1, p2)\n\n    p3 = Person(\"Rhaenys\")\n    family_manager.add_person(p3)\n    family_manager.add_child(p1, p2, p3)\n\n    p4 = Person(\"Corlys\")\n    family_manager.add_person(p4)\n    family_manager.add_partner(p3, p4)\n\n    p5 = Person(\"Laena Velaryon\")\n    p6 = Person(\"Laenor Velaryon\")\n    family_manager.add_person(p5)\n    family_manager.add_person(p6)\n    family_manager.add_child(p3, p4, p5)\n    family_manager.add_child(p3, p4, p6)\n\n\n    p7 = Person(\"Baelon\")\n    p8 = Person(\"Alyssa\")\n    family_manager.add_person(p7)\n    family_manager.add_person(p8)\n    family_manager.add_partner(p7, p8)\n\n    p9 = Person(\"Viserys I\")\n    p10 = Person(\"Daemon\")\n    family_manager.add_person(p9)\n    family_manager.add_person(p10)\n    family_manager.add_child(p7, p8, p9)\n    family_manager.add_child(p8, p7, p10)\n\n    family_manager.add_partner(p10, p5)\n\n    p11 = Person(\"Aemma Arryn\")\n    family_manager.add_person(p11)\n    family_manager.add_partner(p9, p11)\n\n    p12 = Person(\"Alicent Hightower\")\n    family_manager.add_person(p12)\n    family_manager.add_partner(p9, p12)\n    p20 = Person(\"Aegon II\")\n    p21 = Person(\"Helaena\")\n    p22 = Person(\"Aemond\")\n    family_manager.add_person(p20)\n    family_manager.add_person(p21)\n    family_manager.add_person(p22)\n    family_manager.add_child(p9, p12, p20)\n    family_manager.add_child(p9, p12, p21)\n    family_manager.add_child(p9, p12, p22)\n\n\n    p13 = Person(\"Rhaenyra\")\n    family_manager.add_person(p13)\n    family_manager.add_child(p9, p11, p13)\n    family_manager.add_partner(p13, p6)\n\n    p15 = Person(\"Jacaerys\")\n    p16 = Person(\"Lucerys\")\n    p17 = Person(\"Joffrey\")\n    family_manager.add_person(p15)\n    family_manager.add_person(p16)\n    family_manager.add_person(p17)\n    family_manager.add_child(p13, p6, p15)\n    family_manager.add_child(p13, p6, p16)\n    family_manager.add_child(p13, p6, p17)\n\n    family_manager.add_partner(p10, p13)\n    p18 = Person(\"Aegon III\")\n    p19 = Person(\"Viserys II\")\n    family_manager.add_person(p18)\n    family_manager.add_person(p19)\n    family_manager.add_child(p10, p13, p18)\n    family_manager.add_child(p10, p13, p19)\n    \n    \n    p24 = Person(\"Aegon\")\n    p25 = Person(\"Viserys\")\n    family_manager.add_person(p24)\n    family_manager.add_person(p25)\n    \n    family_manager.add_child(p10 ,p5, p24)\n    family_manager.add_child(p10 ,p5, p25)\n\n    family_printer.print_family_tree(p1)\n    family_printer.print_family_tree(p7)\n\nmain()   \n"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/python/javi-kl.py",
    "content": "class Persona:\n    def __init__(self, id_unico, nombre):\n        self.id_unico = str(id_unico)\n        self.nombre = nombre\n        self.hijos: list[\"Persona\"] = []\n        self.pareja: \"Persona | None\" = None\n\n    def agregar_hijo(self, hijo, arbol):  # TODO\n        contador = 0\n        # Comprobamos si hijo no tiene ya 2 padres y si no es ya hijo de esa persona\n        for persona in arbol.personas.values():\n            if hijo in persona.hijos:\n                contador += 1\n        if contador < 2 and hijo not in self.hijos:\n            self.hijos.append(hijo)\n\n    def cambiar_pareja(self, nueva_pareja):\n        if nueva_pareja != self.pareja:\n            self.pareja = nueva_pareja\n            nueva_pareja.pareja = self\n\n    def eliminar_referencias(self):\n        if self.pareja:\n            self.pareja.pareja = None\n\n    def __str__(self) -> str:\n        hijos_nombre = (\n            [h.nombre for h in self.hijos] if len(self.hijos) > 0 else \"Sin hijos\"\n        )\n        pareja = \"Sin pareja\" if self.pareja == None else self.pareja.nombre\n        return f\"{self.nombre}\\nHijos: {hijos_nombre}\\nPareja: {pareja}\"\n\n\nclass ArbolGenealogico:\n    \"\"\"Guarda o retorna personas\"\"\"\n\n    def __init__(self) -> None:\n        self.personas: dict[str, Persona] = {}\n\n    def agregar_persona(self, persona):\n\n        self.personas[persona.id_unico] = persona\n\n    def eliminar_persona(self, id_unico: str) -> bool:\n        persona = self.personas.get(id_unico)\n        if persona:\n            persona.eliminar_referencias()\n            for p in self.personas.values():\n                p.hijos = [h for h in p.hijos if h.id_unico != id_unico]\n            del self.personas[id_unico]\n            return True\n        return False\n\n    def buscar_persona(self, id_unico: str):\n        return self.personas.get(id_unico)\n\n    def mostrar_arbol(self):\n        if not self.personas:\n            print(\"Arbol vacio\")\n        else:\n            print(\"--- Arbol genealogico ---\")\n            for persona in self.personas.values():\n                print(f\"{persona}\")\n\n\narbol = ArbolGenealogico()\n\n\ndef menu_principal():\n    print(\"Bienvenido!\")\n    counter_ids = 0\n    while True:\n\n        print(\"\\n --- Menu principal ---\")\n        print(\"1. Modificar arbol\")\n        print(\"2. Mostrar arbol\")\n        print(\"3. Salir\")\n        opcion_principal = input(\"-> \")\n\n        if opcion_principal == \"3\":\n            print(\"Hasta luego\")\n            break\n\n        elif opcion_principal == \"1\":\n            print(\"\\n --- Menu modificación ---\")\n            print(\"1. Agregar personaje\")\n            print(\"2. Eliminar personaje\")\n            print(\"3. Añadir hijo\")\n            print(\"4. Cambiar pareja\")\n            print(\"5. Volver atras\")\n            opcion_modificar = input(\"-> \")\n            if opcion_modificar == \"5\":\n                continue\n\n            elif opcion_modificar == \"1\":\n                counter_ids += 1\n                nombre_persona = input(\"Nombre -> \")\n                nueva_persona = Persona(counter_ids, nombre_persona)\n                arbol.agregar_persona(nueva_persona)\n                print(f\"Agregada persona '{nombre_persona}' con ID {counter_ids}\")\n\n            elif opcion_modificar == \"2\":\n                id_eliminar = input(\"Introduce id unico\\n -> \")\n                eliminado = arbol.eliminar_persona(id_eliminar)\n                print(\"Eliminado\" if eliminado else \"No encontrado\")\n\n            elif opcion_modificar == \"3\":\n                padre_id = input(\"Introduce id unico del padre\\n ->\")\n                hijo_nombre = input(\"Introduce nombre\\n -> \")\n                padre = arbol.buscar_persona(padre_id)\n                if padre:\n                    counter_ids += 1\n                    nuevo_hijo = Persona(counter_ids, hijo_nombre)\n                    arbol.agregar_persona(nuevo_hijo)\n                    padre.agregar_hijo(nuevo_hijo, arbol)\n                    print(\n                        f\"Hijo '{hijo_nombre}' agregado al personaje '{padre.nombre}'\"\n                    )\n                else:\n                    print(\"Padre/madre no encontrado.\")\n\n            elif opcion_modificar == \"4\":\n                id_persona = input(\"ID de la persona que quiere cambiar pareja\\n -> \")\n                id_pareja = input(\"ID de la nueva pareja\\n -> \")\n                persona = arbol.buscar_persona(id_persona)\n                pareja = arbol.buscar_persona(id_pareja)\n                if persona and pareja:\n                    persona.cambiar_pareja(pareja)\n                    print(f\"Pareja de {persona.nombre} cambiada a {pareja.nombre}\")\n                else:\n                    print(\"Persona o pareja no encontrada.\")\n\n        elif opcion_principal == \"2\":\n            print(\"\\n --- Menu mostrar arbol ---\")\n            print(\"1. Mostrar arbol\")\n            print(\"2. Buscar persona\")\n            print(\"3. Volver atras\")\n            opcion_mostrar = input(\"-> \")\n            if opcion_mostrar == \"3\":\n                continue\n\n            elif opcion_mostrar == \"2\":\n                opcion = input(\"Introduce id unico\\n -> \")\n                persona = arbol.buscar_persona(opcion)\n                if persona:\n                    print(persona)\n                else:\n                    print(\"Persona no encontrada.\")\n\n            elif opcion_mostrar == \"1\":\n                arbol.mostrar_arbol()\n\n\nmenu_principal()\n"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/python/javierfiestasbotella.py",
    "content": "'''/*\n * EJERCICIO:\n * ¡La Casa del Dragón ha finalizado y no volverá hasta 2026! \n * ¿Alguien se entera de todas las relaciones de parentesco\n * entre personajes que aparecen en la saga?\n * Desarrolla un árbol genealógico para relacionarlos (o invéntalo).\n * Requisitos:\n * 1. Estará formado por personas con las siguientes propiedades:\n *    - Identificador único (obligatorio)\n *    - Nombre (obligatorio)\n *    - Pareja (opcional)\n *    - Hijos (opcional)\n * 2. Una persona sólo puede tener una pareja (para simplificarlo).\n * 3. Las relaciones deben validarse dentro de lo posible.\n *    Ejemplo: Un hijo no puede tener tres padres.\n * Acciones:\n * 1. Crea un programa que permita crear y modificar el árbol.\n *    - Añadir y eliminar personas\n *    - Modificar pareja e hijos\n * 2. Podrás imprimir el árbol (de la manera que consideres).\n * \n * NOTA: Ten en cuenta que la complejidad puede ser alta si\n * se implementan todas las posibles relaciones. Intenta marcar\n * tus propias reglas y límites para que te resulte asumible.\n */\n```'''\n\nclass Persona:\n    _id_counter = 1  # Contador estático que se incrementa con cada nueva instancia\n\n    def __init__(self, nombre):\n        self.id = Persona._id_counter\n        Persona._id_counter += 1\n        self.nombre = nombre\n\n    def __str__(self):\n        return self.nombre\n\nclass CreaParejas:\n    def __init__(self, pareja_1, pareja_2):\n        self.pareja_1 = pareja_1\n        self.pareja_2 = pareja_2\n        self.hijos = []\n\n    def __str__(self):\n        if self.hijos:\n            hijos_str = ', '.join([hijo.nombre for hijo in self.hijos])\n            return f\"{self.pareja_1.nombre} y {self.pareja_2.nombre} tienen como hijos: {hijos_str}\"\n        else:\n            return f\"{self.pareja_1.nombre} y {self.pareja_2.nombre} no tienen hijos.\"\n\n    def agregar_hijo(self, hijo):\n        if not self.hijos:\n            self.hijos.append(hijo)\n            print(f\"Hijo {hijo.nombre} agregado a la pareja {self.pareja_1.nombre} y {self.pareja_2.nombre}\")\n        else:\n            print(f\"La pareja {self.pareja_1.nombre} y {self.pareja_2.nombre} ya tiene un hijo: {self.hijos[0].nombre}\")\n\n    def eliminar_hijo(self):\n        if self.hijos:\n            hijo = self.hijos.pop(0)\n            print(f\"Hijo {hijo.nombre} eliminado de la pareja {self.pareja_1.nombre} y {self.pareja_2.nombre}\")\n        else:\n            print(f\"La pareja {self.pareja_1.nombre} y {self.pareja_2.nombre} no tiene hijos para eliminar.\")\n\nclass ArbolGenealogico:\n    def __init__(self):\n        self.parejas = []\n\n    def agregar_pareja(self, pareja):\n        self.parejas.append(pareja)\n\n    def buscar_pareja(self, nombre1, nombre2):\n        for pareja in self.parejas:\n            if (pareja.pareja_1.nombre == nombre1 and pareja.pareja_2.nombre == nombre2) or \\\n               (pareja.pareja_1.nombre == nombre2 and pareja.pareja_2.nombre == nombre1):\n                return pareja\n        return None\n\n    def eliminar_pareja(self, nombre1, nombre2):\n        pareja = self.buscar_pareja(nombre1, nombre2)\n        if pareja:\n            self.parejas.remove(pareja)\n            print(f\"Pareja entre {nombre1} y {nombre2} eliminada del árbol genealógico.\")\n        else:\n            print(\"La pareja no existe en el árbol genealógico.\")\n\n    def imprimir_arbol(self):\n        print(\"Árbol Genealógico:\")\n        for pareja in self.parejas:\n            print(f\"{pareja.pareja_1.nombre} y {pareja.pareja_2.nombre}\")\n            if pareja.hijos:\n                for hijo in pareja.hijos:\n                    print(f\"    └── {hijo.nombre}\")\n            else:\n                print(f\"    └── Sin hijos\")\n\n# MENÚ Y FUNCIONES NECESARIAS\nmenu = '''\n 1- Añadir y eliminar personas\n 2- Crear Parejas\n 3- Crear hijos\n 4- Modificar parejas e hijos\n 5- Imprimir árbol genealógico\n 6- Salir\n'''\n\narbol_genealogico = ArbolGenealogico()\npersonas = []  \n\ndef buscar_persona(nombre):\n    for persona in personas:\n        if persona.nombre == nombre:\n            return persona\n    return None\n\nif __name__ == \"__main__\":\n    while True:\n        print(menu)\n        opc = int(input('Introduce una opción: '))\n        if opc == 1:\n            sub_opc = input(\"¿Quieres (a)ñadir o (e)liminar una persona? \")\n            if sub_opc.lower() == 'a':\n                name = input('Introduce el nombre de la persona: ')\n                persona = Persona(nombre=name)\n                personas.append(persona)\n                print(f'Se creó la Persona {persona.nombre} con ID {persona.id}')\n            elif sub_opc.lower() == 'e':\n                name = input('Introduce el nombre de la persona que deseas eliminar: ')\n                persona = buscar_persona(name)\n                if persona:\n                    personas.remove(persona)\n                    print(f'Se eliminó la Persona {persona.nombre}')\n                else:\n                    print(\"La persona no existe en la lista.\")\n\n        elif opc == 2:\n            pareja1_nombre = input('Introduce el nombre de la primera pareja: ')\n            pareja2_nombre = input('Introduce el nombre de la segunda pareja: ')\n\n            pareja1 = buscar_persona(pareja1_nombre)\n            pareja2 = buscar_persona(pareja2_nombre)\n\n            if pareja1 and pareja2:\n                pareja = CreaParejas(pareja1, pareja2)\n                arbol_genealogico.agregar_pareja(pareja)\n                print(f\"Pareja creada: {pareja}\")\n            else:\n                print(\"Una o ambas personas no existen. Asegúrate de crear las personas primero.\")\n\n        elif opc == 3:\n            hijo = input('Introduce el nombre del hijo: ')\n            hijo1 = buscar_persona(hijo)\n\n            if hijo1:\n                print('Este hijo ya existe. Si quieres modificar la pareja, elige la opción 4.')\n            else:\n                hijo1 = Persona(nombre=hijo)\n                pareja1_nombre = input('Introduce el nombre de la primera pareja: ')\n                pareja2_nombre = input('Introduce el nombre de la segunda pareja: ')\n\n                pareja = arbol_genealogico.buscar_pareja(pareja1_nombre, pareja2_nombre)\n\n                if pareja:\n                    pareja.agregar_hijo(hijo1)\n                    personas.append(hijo1)\n                else:\n                    print(\"La pareja no existe. Asegúrate de crear la pareja primero.\")\n\n        elif opc == 4:\n            sub_opc = input(\"¿Quieres (m)odificar una pareja o (e)liminar un hijo? \")\n            if sub_opc.lower() == 'm':\n                pareja1_nombre = input('Introduce el nombre de la primera pareja: ')\n                pareja2_nombre = input('Introduce el nombre de la segunda pareja: ')\n                pareja = arbol_genealogico.buscar_pareja(pareja1_nombre, pareja2_nombre)\n                if pareja:\n                    nuevo_hijo = input(\"Introduce el nombre del nuevo hijo para agregar: \")\n                    hijo1 = Persona(nombre=nuevo_hijo)\n                    pareja.agregar_hijo(hijo1)\n                    personas.append(hijo1)\n                else:\n                    print(\"La pareja no existe.\")\n            elif sub_opc.lower() == 'e':\n                pareja1_nombre = input('Introduce el nombre de la primera pareja: ')\n                pareja2_nombre = input('Introduce el nombre de la segunda pareja: ')\n                pareja = arbol_genealogico.buscar_pareja(pareja1_nombre, pareja2_nombre)\n                if pareja:\n                    pareja.eliminar_hijo()\n                else:\n                    print(\"La pareja no existe.\")\n\n        elif opc == 5:\n            arbol_genealogico.imprimir_arbol()\n\n        elif opc == 6:\n            break\n\n    \n    print(\"\\nÁrbol Genealógico:\")\n    arbol_genealogico.imprimir_arbol()\n"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/python/juanmax2.py",
    "content": "class Persona:\n    \n    def __init__(self, id : int, nombre : str):\n        self.id = id\n        self.nombre = nombre\n        self.pareja = None\n        self.hijos = []\n        self.tiene_padres = False\n        \n    def add_pareja(self, pareja):\n        if self.pareja is not None:\n            print(f\"La persona {self.nombre} ya tiene pareja {self.pareja.nombre}\")\n        \n        else:\n            self.pareja = pareja\n            pareja.pareja = self\n            print(f\"{self.nombre} es pareja de {pareja.nombre}\")\n    \n    def add_hijo(self, hijo):\n        if hijo not in self.hijos:\n            self.hijos.append(hijo)\n            print(f\"{self.nombre} ha tenido un hijo {hijo.nombre}\")\n        else:\n            print(f\"{hijo.nombre} ya es hijo de {self.nombre}\")\n\nclass ArbolGenealogico:\n    \n    def __init__(self):\n        self.personas = {}\n        \n    def add_persona(self, id, nombre):\n        if id in self.personas:\n            print(f\"El identificador {id} ya existe en la lista\")\n        persona = Persona(id, nombre)\n        self.personas[id] = persona\n        print(f\"La persona con nombre {nombre} [ID: {id}] ha sido añadida\")\n    \n    def eliminar_persona(self, id):\n        if id in self.personas:\n            person = self.personas[id]\n            del self.personas[id]\n            print(f\"La persona con nombre {person.nombre} [ID: {id}] ha sido añadida\")\n        else:\n            print(f\"La persona con ID: {id} no existe en el árbol.\")\n            \n    def set_pareja(self, id, id_pareja):\n        if id in self.personas and id_pareja in self.personas:\n            persona_1 = self.personas[id]\n            persona_2 = self.personas[id_pareja]\n            persona_1.add_pareja(persona_2)\n        else:\n            print(\"Algun ID no existe en el árbol.\")\n            \n    def add_hijo(self, pariente_id, hijo_id):\n        if pariente_id in self.personas and hijo_id in self.personas:\n            if pariente_id == hijo_id:\n                print(\"Los ID no pueden ser iguales a la hora de asignar un hijo\")\n            else:\n                pariente = self.personas[pariente_id]\n                if pariente.pareja == None:\n                    print(f\"Se necesita una pareja para poder tener un hijo.\")\n                else:\n                    hijo = self.personas[hijo_id]\n                    if hijo.tiene_padres:\n                        print(f\"{hijo.nombre} con id {hijo.id} ya tiene padres.\")\n                    else:\n                        hijo.tiene_padres = True\n                        pariente.add_hijo(hijo)\n                        pariente.pareja.add_hijo(hijo)\n                    \n        else:\n            print(\"Algun ID no existe en el árbol.\")\n            \n    def print_arbol(self):\n        \n        visitados = set()\n        \n        def print_persona(persona, level = 0):\n            if persona.id in visitados:\n                return\n            \n            visitados.add(persona.id)\n            \n            indent = \"\\t\" * level\n            \n            print(f\"{indent} - {persona.nombre} [ID: {persona.id}]\")\n            \n            if persona.pareja:\n                visitados.add(persona.pareja.id)\n                print(f\"{indent} Pareja: {persona.pareja.nombre} [ID: {persona.pareja.id}]\")\n                \n            if persona.hijos:\n                print(f\"{indent} Hijos:\")\n                for hijo in persona.hijos:\n                    print_persona(hijo, level + 1)\n        for persona in self.personas.values():\n            es_hijo = persona.tiene_padres\n            if not es_hijo:\n                print_persona(persona)\n\n\narbol = ArbolGenealogico()\n\narbol.add_persona(1, \"Persona 1\")\narbol.add_persona(2, \"Persona 2\")\narbol.add_persona(3, \"Persona 3\")\narbol.add_persona(4, \"Persona 4\")\narbol.add_persona(5, \"Persona 5\")\narbol.add_persona(6, \"Persona 6\")\n\narbol.set_pareja(1, 2)\narbol.set_pareja(3, 5)\n\narbol.add_hijo(1, 3)\narbol.add_hijo(3, 6)\n\narbol.print_arbol()"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/python/kenysdev.py",
    "content": "# ╔═════════════════════════════════════╗\n# ║ Autor:  Kenys Alvarado              ║\n# ║ GitHub: https: github.com/Kenysdev  ║\n# ║ 2024 -  Python                      ║\n# ╚═════════════════════════════════════╝\n\n# -------------------------------------------\n# #34 ÁRBOL GENEALÓGICO DE LA CASA DEL DRAGÓN\n# -------------------------------------------\n#  * ¡La Casa del Dragón ha finalizado y no volverá hasta 2026!\n#  * ¿Alguien se entera de todas las relaciones de parentesco\n#  * entre personajes que aparecen en la saga?\n#  * Desarrolla un árbol genealógico para relacionarlos (o invéntalo).\n#  * Requisitos:\n#  * 1. Estará formado por personas con las siguientes propiedades:\n#  *    - id_entificador único (obligatorio)\n#  *    - Nombre (obligatorio)\n#  *    - Pareja (opcional)\n#  *    - Hijos (opcional)\n#  * 2. Una persona sólo puede tener una pareja (para simplificarlo).\n#  * 3. Las relaciones deben valid_arse dentro de lo posible.\n#  *    Ejemplo: Un hijo no puede tener tres padres.\n#  * Acciones:\n#  * 1. Crea un programa que permita crear y modificar el árbol.\n#  *    - Añadir y eliminar personas\n#  *    - Modificar pareja e hijos\n#  * 2. Podrás imprimir el árbol (de la manera que consid_eres).\n#  *\n#  * NOTA: Ten en cuenta que la complejid_ad puede ser alta si\n#  * se implementan todas las posibles relaciones. Intenta marcar\n#  * tus propias reglas y límites para que te resulte asumible.\n\n# NOTE: Here is the 'people.json' file with the data if you want to test it:\n#       https://pastebin.com/29kWWgPU\n#       Just paste it into the base folder where file.py is located.\n\nimport json\nfrom typing import List, Optional, Dict, Tuple\n\n# ________________________\nclass Input:\n    def input_str(self, msg: str) -> str:\n        while True:\n            txt: str = input(msg)\n            if len(txt) > 0:\n                return txt\n            \n            print(\"\\n❌ This field cannot be empty.\")\n\n    def input_int(self, msg: str) -> int:\n        while True:\n            txt: str = self.input_str(msg)\n            if txt.isdigit():\n                return int(txt)\n            print(\"\\n❌ Enter an integer.\")\n\n# ________________________\nclass Person:\n    def __init__(self, id: int, name: str):\n        self.id = id\n        self.name = name\n        self.parents: List[int] = []\n        self.partners: List[int] = []\n        self.children: Dict[int, List[int]] = {}\n        self.deleted: bool = False\n\n    def to_dict(self):\n        return {\n            \"id\": self.id,\n            \"name\": self.name,\n            \"parents\": self.parents,\n            \"partners\": self.partners,\n            \"children\": self.children,\n            \"deleted\": self.deleted\n        }\n\n    @classmethod\n    def from_dict(cls, data: dict):\n        person = cls(data['id'], data['name'])\n        person.parents = data.get('parents', [])\n        person.partners = data.get('partners', [])\n        person.children = {int(k): v for k, v in data.get('children', {}).items()}\n        person.deleted = data.get('deleted', False)\n        return person\n\n    def __repr__(self) -> str:\n        return f\"Person(id={self.id}, name='{self.name}')\"\n\n# ________________________\nclass People(Input):\n    def __init__(self, filename: str = \"people.json\") -> None:\n        self._people: List[Person] = []\n        self._filename = filename\n        self.load_from_json()\n\n    def get_people(self) -> List[Person]:\n        return self._people\n\n    def load_from_json(self) -> None:\n        try:\n            with open(self._filename, \"r\") as f:\n                data = json.load(f)\n                self._people = []\n                for person_data in data:\n                    person = Person.from_dict(person_data)\n                    self._people.append(person)\n                    \n                print(f\"✅ The file '{self._filename}' has been successfully loaded.\")\n        except Exception:\n            print(\n                f\"⚠️ The file '{self._filename}' not found. Starting with an empty list.\"\n            )\n            self._people = []\n            self._people.append(Person(id=0, name=\"unknown\"))\n\n    def save_to_json(self) -> None:\n        try:\n            data = [person.to_dict() for person in self._people]\n            with open(self._filename, \"w\") as f:\n                json.dump(data, f, indent=2)\n            print(f\"✅ Data saved successfully to {self._filename}\")\n        except Exception as e:\n            print(\n                f\"❌ An error occurred while saving to '{self._filename}': {e}. Data may not have been saved.\"\n            )\n\n    def print_people(self) -> None:\n        print(f\"{'_' * 32}\\n|{'id'.center(4)}|{'Name'.center(25)}|\\n{'_' * 32}\")\n        for person in self._people:\n            if not person.deleted:\n                print(\n                    f\"|{str(person.id).center(4)}|{str(person.name).center(25):<25}|\"\n                )\n            # optional:\n            # else:\n            #    print(f\"id: {person.id:<4}, This person was deleted.\")\n        print(\"_\" * 32)\n\n    def get_person_by_id_(self, id_: int) -> Optional[Person]:\n        if 0 <= id_ < len(self._people):\n            return self._people[id_]\n        else:\n            print(\"❌ id not found.\")\n            return None\n\n    def add_person(self) -> None:\n        print(\"Add Person or 'x' to Exit\")\n        name = self.input_str(\"Name: \")\n        if name.lower() == \"x\":\n            print(\"Exit\")\n            return\n\n        new_id = max([person.id for person in self._people], default=-1) + 1\n        new_person = Person(id=new_id, name=name)\n        self._people.append(new_person)\n        print(f\"✅ Added: {new_person}\")\n        self.save_to_json()\n\n    def remove_person(self) -> None:\n        self.print_people()\n        print(\"\\nPerson ID to mark as deleted or a letter to exit.\")\n        id_: str = self.input_str(\"ID: \")\n        if not id_.isdigit():\n            print(\"Exit\")\n            return\n\n        person = self.get_person_by_id_(int(id_))\n        if not person:\n            return\n\n        if person.partners or person.parents:\n            print(\"❌ You cannot delete a person who is linked to parents or partners.\")\n            return\n\n        person.deleted = True\n        print(f\"✅ '{person.name}' is marked as deleted.\")\n        self.save_to_json()\n\n    def __len__(self) -> int:\n        return len(self._people)\n\n# ________________________\nclass Partners(People):\n    def __add(self, partners: list, id_person: int):\n        print(\"Select Partner ID\")\n        id_partner: int = self.input_int(\"ID: \")\n        partner = self.get_person_by_id_(id_partner)\n        if not partner or partner.deleted:\n            print(\"❌ ID not found or the person is deleted.\")\n            return\n\n        if id_partner in partners:\n            print(\"❌ This partner is already added.\")\n            return\n\n        partners.append(id_partner)\n        partner.partners.append(id_person)\n\n        print(\"✅ Partner successfully added.\")\n        self.save_to_json()\n\n    def __remove(self, partners: list, id_person: int):\n        print(\"Select Partner ID to Delete\")\n        id_: int = self.input_int(\"ID: \")\n        if id_ not in partners:\n            print(\"❌ ID not found.\")\n            return\n\n        partner = self.get_person_by_id_(id_)\n        if not partner:\n            print(\"❌ Partner not found.\")\n            return\n\n        if partner.children:\n            print(\"❌ Cannot delete a partner who has children.\")\n            return\n\n        partners.remove(id_)\n        partner.partners.remove(id_person)\n\n        print(\"✅ Partner deleted\")\n        self.save_to_json()\n\n    def __options(self, partners: list, id_person: int):\n        print(\"\\n1. Add partner | 2. Remove partner | 3. Exit\")\n        option: int = self.input_int(\"\\nOption: \")\n\n        if option == 1:\n            self.__add(partners, id_person)\n\n        elif option == 2:\n            self.__remove(partners, id_person)\n\n        elif option == 3:\n            return\n\n        else:\n            print(\"❌ Invalid option.\")\n\n    def edit_partners(self):\n        self.print_people()\n        print(\"\\nPerson ID to edit partners or a letter to exit.\")\n        id_s: str = self.input_str(\"ID: \")\n        if not id_s.isdigit():\n            print(\"Exit\")\n            return\n\n        id_: int = int(id_s)\n        person = self.get_person_by_id_(id_)\n        if not person or person.deleted:\n            print(\"❌ ID not found or the person is deleted.\")\n            return\n\n        print(f\"You selected '{person.name}'\")\n        partners = person.partners\n\n        if partners:\n            print(\"Partners:\")\n            for id_p in partners:\n                partner = self.get_person_by_id_(id_p)\n                if partner:\n                    print(f\"ID: {partner.id} -> {partner.name}\")\n        else:\n            print(\"🚫 This person has no partners.\")\n\n        self.__options(partners, id_)\n\n# ________________________\nclass Children(People):\n    def __init__(self, filename: str = \"people.json\") -> None:\n        super().__init__(filename)\n        self.__id_parent: int\n        self.__children: dict\n        self.__id_child: int\n        self.__parents: list\n        self.__id_partner: int\n\n    def __select_partner(self, partners: list) -> Optional[int]:\n        print(\"Partners:\")\n        for id_p in partners:\n            partner = self.get_person_by_id_(id_p)\n            if partner:\n                print(f\"ID: {partner.id} -> {partner.name}\")\n\n        print(\"Select the ID of the partner with whom you have the child.\")\n        id_partner: int = self.input_int(\"ID: \")\n        partner = self.get_person_by_id_(id_partner)\n        if id_partner not in partners or not partner or partner.deleted:\n            print(\"❌ ID not found or the person is deleted.\")\n            return\n\n        return id_partner\n\n    def __update_child_parent(self) -> Optional[int]:\n        id_partner: int = self.__id_partner\n        print(\"Select Child ID\")\n        id_child: int = self.input_int(\"ID: \")\n        child = self.get_person_by_id_(id_child)\n        if not child:\n            print(\"❌ ID not found.\")\n            return\n\n        if child.parents:\n            print(\"❌ This person already has parents.\")\n            return\n\n        if id_partner in self.__children:\n            if id_child not in self.__children[id_partner]:\n                self.__children[id_partner].append(id_child)\n        else:\n            self.__children[id_partner] = [id_child]\n\n        parent = self.get_person_by_id_(self.__id_parent)\n        if parent:\n            parent.children = self.__children\n\n        child.parents = [self.__id_parent, id_partner]\n\n        return id_child\n\n    def __update_child_partner(self, partner: Person) -> None:\n        if self.__id_parent in partner.children:\n            if self.__id_child not in partner.children[self.__id_parent]:\n                partner.children[self.__id_parent].append(self.__id_child)\n        else:\n            partner.children[self.__id_parent] = [self.__id_child]\n\n    def __add(self) -> None:\n        id_parent: int = self.__id_parent\n        parent = self.get_person_by_id_(id_parent)\n        if not parent:\n            print(\"❌ Parent not found.\")\n            return\n\n        partners = parent.partners\n        if not partners:\n            print(\"❌ This person does not have a partner with whom to have children.\")\n            return\n\n        id_partner = self.__select_partner(partners)\n        if not id_partner:\n            return\n\n        partner = self.get_person_by_id_(id_partner)\n        if not partner:\n            print(\"❌ Partner not found.\")\n            return\n\n        self.__id_partner = id_partner\n        id_child = self.__update_child_parent()\n        if id_child is None:\n            return\n\n        self.__id_child = id_child\n        self.__update_child_partner(partner)\n\n        print(\"✅ Child successfully added.\")\n        self.save_to_json()\n\n    def __remove_and_update(self, id_parent: int, id_partner: int) -> None:\n        parent = self.get_person_by_id_(id_parent)\n        if not parent:\n            print(\"❌ Parent not found.\")\n            return\n\n        children_with_partner = parent.children.get(id_partner, [])\n        if self.__id_child in children_with_partner:\n            children_with_partner.remove(self.__id_child)\n            if not children_with_partner:\n                del parent.children[id_partner]\n            else:\n                parent.children[id_partner] = children_with_partner\n\n        child = self.get_person_by_id_(self.__id_child)\n        if child:\n            child.parents.remove(id_parent)\n\n        print(\"✅ Child deleted\")\n        self.save_to_json()\n\n    def __remove(self) -> None:\n        print(\"Select Child ID to Delete\")\n        self.__id_child = self.input_int(\"ID: \")\n        child = self.get_person_by_id_(self.__id_child)\n        if not child:\n            print(\"❌ Child not found.\")\n            return\n\n        parents = child.parents\n        if len(parents) != 2:\n            print(\"❌ Child does not have two parents.\")\n            return\n\n        self.__parents = parents\n        id_p1, id_p2 = parents\n        self.__remove_and_update(id_p1, id_p2)\n        self.__remove_and_update(id_p2, id_p1)\n\n    def __options(self) -> None:\n        print(\"\\n1. Add child | 2. Remove child | 3. Exit\")\n        option: int = self.input_int(\"\\nOption: \")\n\n        if option == 1:\n            self.__add()\n\n        elif option == 2:\n            self.__remove()\n\n        elif option == 3:\n            return\n\n        else:\n            print(\"❌ Invalid option.\")\n\n    def edit_children(self) -> None:\n        self.print_people()\n        print(\"\\nPerson ID to edit Children or a letter to exit.\")\n        id_s: str = self.input_str(\"ID: \")\n        if not id_s.isdigit():\n            print(\"Exit\")\n            return\n\n        id_: int = int(id_s)\n        parent = self.get_person_by_id_(id_)\n        if not parent or parent.deleted:\n            print(\"❌ ID not found or the person is deleted.\")\n            return\n\n        print(f\"You selected '{parent.name}'\")\n        children = parent.children\n        if children:\n            print(\"Children:\")\n            for partner_id, child_ids in children.items():\n                partner = self.get_person_by_id_(partner_id)\n                partner_name = partner.name if partner else \"Unknown\"\n                print(f\"With ID: {partner_id} -> '{partner_name}':\")\n                for child_id in child_ids:\n                    child = self.get_person_by_id_(child_id)\n                    child_name = child.name if child else \"Unknown\"\n                    print(f\"    ID: {child_id} -> '{child_name}'\")\n        else:\n            print(\"🚫 This person has no children.\")\n\n        self.__id_parent = id_\n        self.__children = children\n        self.__options()\n\n# ________________________\nclass Tree(People):\n    def __filtered_grandparents(self) -> Tuple[List[Person], List[Person]]:\n        grandparents = []\n        no_partner = []\n\n        for person in self.get_people():\n            if (\n                not person.parents\n                and not person.deleted\n                and person.name != \"unknown\"\n            ):\n                partners = person.partners\n                if not partners:\n                    no_partner.append(person)\n                    continue\n\n                has_grandparent_partner = False\n                for partner_id in partners:\n                    partner = self.get_person_by_id_(partner_id)\n                    if partner and partner in grandparents:\n                        has_grandparent_partner = True\n                        break\n\n                if not has_grandparent_partner:\n                    grandparents.append(person)\n\n        return grandparents, no_partner\n\n    def __print_child(self, children: list, px: str, is_last: bool, is_root: bool) -> None:\n        for j, child_id in enumerate(children):\n            is_last_child = j == len(children) - 1\n            new_prefix = px\n            if not is_root:\n                new_prefix = px[:-4] + (\"    \" if is_last else \"│   \")\n\n            self.__print_family(\n                child_id,\n                new_prefix + (\"└── \" if is_last_child else \"├── \"),\n                is_last_child,\n                False,\n            )\n\n    def __print_parents(self, id_: int, partners: list, px: str, is_last: bool, is_root: bool) -> None:\n        for partner_id in partners:\n            partner = self.get_person_by_id_(partner_id)\n            if partner:\n                print(f\"{px}💑 With: {partner.name} (ID: {partner.id})\")\n                children = partner.children.get(id_, [])\n                if children:\n                    self.__print_child(children, px, is_last, is_root)\n                else:\n                    print(f\"{px}└── 🚫 Without children\")\n\n    def __print_family(self, id_: int, px=\"\", is_last=False, is_root=True) -> None:\n        person = self.get_person_by_id_(id_)\n        if not person:\n            return\n\n        print(f\"{px}🙂 {person.name} (ID: {person.id})\")\n\n        partners = person.partners\n        if isinstance(partners, list) and partners:\n            if not is_root:\n                px = px[:-4] + (\"    \" if is_last else \"│   \")\n\n            self.__print_parents(id_, partners, px, is_last, is_root)\n            if not is_last:\n                print(px)\n\n    def print_tree(self): \n        grandparents, no_partner = self.__filtered_grandparents()\n\n        if not grandparents and not no_partner:\n            print(\"⚠️ No users are registered.\")\n            return\n\n        if no_partner:\n            print(\"__________\\nParents unknown, without descendants and without a partner:\")\n            for p in no_partner:\n                print(f\"😐 {p.name}\")\n\n        print()      \n        for i, person in enumerate(grandparents):\n            print(f\"__________\\nFamily #{i+1}\")\n            self.__print_family(person.id)\n\n# ________________________\nclass Program(Tree, Partners, Children):\n    MENU = \"\"\"\n---------------------------------------------\n| 1. Add person     | 4. Edit children      |  \n| 2. Remove person  | 5. Print tree         |\n| 3. edit partners  | 6. Salir              |\n---------------------------------------------\"\"\"\n\n    def run(self):\n        # self.test()\n        while True:\n            print(Program.MENU)\n            option: int = self.input_int(\"\\nOption: \")\n            match option:\n                case 1:\n                    self.add_person()\n                case 2:\n                    self.remove_person()\n                case 3:\n                    self.edit_partners()\n                case 4:\n                    self.edit_children()\n                case 5:\n                    self.print_tree()\n                case 6:\n                    print(\"Bye\")\n                    break\n                case _:\n                    print(\"❌ Invalid option.\")\n\n# ________________________\nif __name__ == \"__main__\":\n    _program = Program()\n    _program.run()\n\n"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/python/mhayhem.py",
    "content": "# @Author Daniel Grande (Mhayhem)\n\n# EJERCICIO:\n# ¡La Casa del Dragón ha finalizado y no volverá hasta 2026! \n# ¿Alguien se entera de todas las relaciones de parentesco\n# entre personajes que aparecen en la saga?\n# Desarrolla un árbol genealógico para relacionarlos (o invéntalo).\n# Requisitos:\n# 1. Estará formado por personas con las siguientes propiedades:\n#    - Identificador único (obligatorio)\n#    - Nombre (obligatorio)\n#    - Pareja (opcional)\n#    - Hijos (opcional)\n# 2. Una persona sólo puede tener una pareja (para simplificarlo).\n# 3. Las relaciones deben validarse dentro de lo posible.\n#    Ejemplo: Un hijo no puede tener tres padres.\n# Acciones:\n# 1. Crea un programa que permita crear y modificar el árbol.\n#    - Añadir y eliminar personas\n#    - Modificar pareja e hijos\n# 2. Podrás imprimir el árbol (de la manera que consideres).\n# \n# NOTA: Ten en cuenta que la complejidad puede ser alta si\n# se implementan todas las posibles relaciones. Intenta marcar\n# tus propias reglas y límites para que te resulte asumible.\n\nclass Person:\n    def __init__(self, id: int, name: str, partner=None, children=None):\n        self.id = id\n        self.name = name.capitalize()\n        self.partner = partner\n        self.children = children if children is not None else []\n\n    def set_partner(self, person):\n        if self.partner:\n            self.partner.partner = None\n        self.partner = person\n        if person:\n            person.partner = self\n        print(\"Registro de pareja completado.\")\n\n    def add_child(self, child):\n        if child not in self.children:\n            self.children.append(child)\n\n    def delete_relantioship(self, person):\n        if self.partner and person.id == self.partner.id:\n            self.partner = None\n\n        self.children = [child for child in self.children if child.id != person.id]\n\nclass FamilyTre:\n    def __init__(self):\n        self.people = {}\n        self.next_id = 1\n\n    def add_person(self):\n        name = input(\"Introducir nombre:\\n\")\n        person = Person(self.next_id, name)\n        self.people[self.next_id] = person\n        self.next_id += 1\n        print(f\"{person.name} ha sido registrado con ID: {person.id}.\")\n        \n        return person\n\n    def delete_person(self, id: int):\n        if id in self.people:\n            person = self.people[id]\n            print(f\"Eliminando a {person.name}\")\n            for per in self.people.values():\n                if person in per.children:\n                    per.children.remove(person)\n            if person.partner:\n                person.partner.partner = None\n            del self.people[id]\n        else:\n            print(\"ID no encontrado.\")\n\n    def get_id(self):\n        if self.people:\n            id = int(input(\"Indique el ID de la persona.\"))\n            return id\n        else:\n            print(\"No hay personas registradas.\")\n            return\n\n    def get_person(self, id: int):\n        if id in self.people:\n            return self.people[id]\n        else:\n            print(f\"ID: {id}: No encontrado.\")\n            return None\n\n    def display_people(self):\n        for index, value in self.people.items():\n            print(f\"{index}: {value.name}\")\n\n    def print_tree(self, person: object):\n        partner_name = person.partner.name if person.partner else \"Sin Pareja\"\n        \n        if person.children:\n            children_names = ', '.join([child.name for  child in person.children])\n            child_name = f\"Hijo(s): {children_names}\"\n            \n        else:\n            child_name = f\"Hijo(s): Sin hijos.\"\n\n        print(f\"Nombre: {person.name} - Pareja: {partner_name}\\n\"\n            f\"{child_name}\")\n\n    def verify_not_partner(self, person: object):\n        for per in self.people.values():\n            if person == per.partner:\n                return False\n            return True\n\n    def verify_partner_not_sibilis(self, person: object, person2: object):\n        for per in self.people.values():\n            if person in per.children:\n                if person2 in per.children:\n                    return False\n        return True\n\n    def verify_not_parents(self, person: object, person2: object):\n        if person in person2.children or person2 in person.children:\n            return False\n        return True\n\n    def verify_not_has_parents(self, person: object):\n        parents = 0\n        for per in self.people.values():\n            if person in per.children:\n                parents += 1\n        if parents > 2:\n            return False\n        return True\n\ndef main():\n    \n    tree = FamilyTre()\n    \n    print(\"\\n ######### ÁRBOL GENEALÓGICO #########\\n\")\n    while True:\n        print(\"\\n1. Añadir persona.\\n\"\n            \"2. Eliminar persona\\n\"\n            \"3. Establecer pareja.\\n\"\n            \"4. Añadir hijo.\\n\"\n            \"5. Mostrar árbol.\\n\"\n            \"6. Salir.\")\n        \n        option = int(input(\"Elegir una opción.\\n\"))\n        try:\n            match option:\n                case 1:\n                    person = tree.add_person()\n                case 2:\n                    tree.display_people()\n                    index = int(input(\"Indique indice de la persona a elegir.\\n\"))\n                    person = tree.get_person(index)\n                    tree.delete_person(person.id)\n                case 3:\n                    tree.display_people()\n                    index = int(input(\"Indique indice de la persona a elegir.\\n\"))\n                    person = tree.get_person(index)\n                    if person is None:\n                        print(\"ERROR: ID no valido.\")\n                        continue\n                    index2 = int(input(\"Indique indice de la persona que sera su compañera.\\n\"))\n                    person2 = tree.get_person(index2)\n                    if person2 is None:\n                        print(\"ERROR: ID no valido.\")\n                        continue\n                    elif person.id == person2.id:\n                        print(\"ERROR: Son la misma persona.\")\n                        continue\n                    single = tree.verify_not_partner(person2)\n                    not_sibilis = tree.verify_partner_not_child(person, person2)\n                    not_child = tree.verify_not_parents(person, person2)\n                    if single:\n                        if not_sibilis:\n                            if not_child:\n                                person.set_partner(person2)\n                            else:\n                                print(f\"{person.name} y {person2.name} tienen relación padre e hijo.\")\n                        else:\n                            print(f\"{person2.name} y {person.name} son hermanos.\")\n                            continue\n                    else:\n                        print(f\"{person2.name} ya tiene otra pareja.\")\n                        continue\n                    \n                case 4:\n                    tree.display_people()\n                    index = int(input(\"Indique indice de la persona a elegir.\\n\"))\n                    person = tree.get_person(index)\n                    while True:\n                        index2 = int(input(\"Indique indice de la persona del hijo.\\n\"))\n                        if person.id == index2:\n                            print(\"ERROR: Son la misma persona.\")\n                            continue\n                        person2 = tree.get_person(index2)\n                        has_parents = tree.verify_not_has_parents(person2)\n                        if has_parents:\n                            person.add_child(person2)\n                        else:\n                            print(\"No puede tener mas de dos padres.\")\n                        again = input(\"¿Añadir otro hijo?\\n\").lower()\n                        if again != \"si\":\n                            break\n                case 5:\n                    tree.display_people()\n                    index = int(input(\"Indique indice de la persona.\\n\"))\n                    person = tree.get_person(index)\n                    tree.print_tree(person)\n                case 6:\n                    print(\"Cerrando el programa.\")\n                    break\n        except ValueError as e:\n            print(f\"ERROR: {e}; Solo se admiten números.\")\n        print(\"\\n\")\n\nmain()"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/python/mouredev.py",
    "content": "class Person:\n\n    def __init__(self, id: int, name: str):\n        self.id = id\n        self.name = name\n        self.partner = None\n        self.children = []\n        self.has_parents = False\n\n    def add_partner(self, partner):\n        if self.partner is not None:\n            print(f\"{self.name} ya tiene una pareja: {self.partner.name}.\")\n        else:\n            self.partner = partner\n            partner.partner = self\n            print(f\"{self.name} es pareja de {partner.name}.\")\n\n    def add_child(self, child):\n        if child not in self.children:\n            self.children.append(child)\n            print(f\"{self.name} ha tenido un hijo: {child.name}\")\n        else:\n            print(f\"{child.name} ya es hijo de {self.name}.\")\n\n\nclass FamilyTree:\n\n    def __init__(self):\n        self.people = {}\n\n    def add_person(self, id, name):\n        if id in self.people:\n            print(f\"La persona con ID: {id} ya existe.\")\n        else:\n            person = Person(id, name)\n            self.people[id] = person\n            print(\n                f\"La persona con nombre {name} [ID: {id}] ha sido añadida al árbol.\")\n\n    def remove_person(self, id):\n        if id in self.people:\n            person = self.people[id]\n            del self.people[id]\n            print(\n                f\"La persona con nombre {person.name} [ID: {id}] ha sido eliminada del árbol.\")\n        else:\n            print(f\"La persona con ID: {id} no existe en el árbol.\")\n\n    def set_partner(self, id1, id2):\n        if id1 in self.people and id2 in self.people:\n            person1 = self.people[id1]\n            person2 = self.people[id2]\n            person1.add_partner(person2)\n        else:\n            print(\"Algún ID no existe en el árbol.\")\n\n    def add_child(self, parent_id, child_id):\n        if parent_id in self.people and child_id in self.people:\n            if parent_id == child_id:\n                print(\"Los ID no pueden ser iguales a la hora de asignar un hijo.\")\n            else:\n                parent = self.people[parent_id]\n                if parent.partner is None:\n                    print(f\"Se necesita una pareja para poder tener un hijo.\")\n                else:\n                    child = self.people[child_id]\n                    if child.has_parents:\n                        print(\n                            f\"{child.name} [ID: {child.id}] ya tiene padres.\")\n                    else:\n                        child.has_parents = True\n                        parent.add_child(child)\n                        parent.partner.add_child(child)\n        else:\n            print(\"Algún ID no existe en el árbol.\")\n\n    def print_tree(self):\n\n        visited = set()\n\n        def print_person(person, level=0):\n\n            if person.id in visited:\n                return\n\n            visited.add(person.id)\n\n            indent = \"\\t\" * level\n\n            print(f\"{indent} - {person.name} [ID: {person.id}]\")\n\n            if person.partner:\n                visited.add(person.partner.id)\n                print(\n                    f\"{indent}   Pareja: {person.partner.name} [ID: {person.partner.id}]\")\n\n            if person.children:\n                print(f\"{indent}   Hijos:\")\n                for child in person.children:\n                    print_person(child, level + 1)\n\n        for person in self.people.values():\n            is_child = person.has_parents\n            if not is_child:\n                print_person(person)\n\n\ntree = FamilyTree()\n\ntree.add_person(1, \"Jocelyn\")\ntree.add_person(2, \"Aemon\")\n\ntree.set_partner(1, 2)\n\ntree.add_person(3, \"Rhaenys\")\n\ntree.add_child(1, 3)\n\ntree.add_person(4, \"Corlys\")\n\ntree.set_partner(3, 4)\n\ntree.add_person(5, \"Laena\")\ntree.add_person(6, \"Laenor\")\n\ntree.add_child(3, 5)\ntree.add_child(3, 6)\n\ntree.add_person(7, \"Baelon\")\ntree.add_person(8, \"Alyssa\")\n\ntree.set_partner(7, 8)\n\ntree.add_person(9, \"Viserys I\")\ntree.add_person(10, \"Daemon\")\n\ntree.add_child(7, 9)\ntree.add_child(8, 10)\n\ntree.add_person(11, \"Aemma\")\n\ntree.set_partner(9, 11)\n\ntree.add_person(12, \"Rhaenyra\")\n\ntree.add_child(9, 12)\n\ntree.set_partner(10, 12)\n\ntree.add_person(13, \"Aegon\")\ntree.add_person(14, \"Viserys\")\n\ntree.add_child(12, 13)\ntree.add_child(12, 14)\n\ntree.print_tree()\n"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/python/neslarra.py",
    "content": "\"\"\"\n EJERCICIO:\n ¡La Casa del Dragón ha finalizado y no volverá hasta 2026! \n ¿Alguien se entera de todas las relaciones de parentesco\n entre personajes que aparecen en la saga?\n Desarrolla un árbol genealógico para relacionarlos (o invéntalo).\n Requisitos:\n 1. Estará formado por personas con las siguientes propiedades:\n    - Identificador único (obligatorio)\n    - Nombre (obligatorio)\n    - Pareja (opcional)\n    - Hijos (opcional)\n 2. Una persona sólo puede tener una pareja (para simplificarlo).\n 3. Las relaciones deben validarse dentro de lo posible.\n    Ejemplo: Un hijo no puede tener tres padres.\n Acciones:\n 1. Crea un programa que permita crear y modificar el árbol.\n    - Añadir y eliminar personas\n    - Modificar pareja e hijos\n 2. Podrás imprimir el árbol (de la manera que consideres).\n \n NOTA: Ten en cuenta que la complejidad puede ser alta si\n se implementan todas las posibles relaciones. Intenta marcar\n tus propias reglas y límites para que te resulte asumible.\n\"\"\"\nfrom typing import Literal\n\n\nclass Relationship:\n\n    def __init__(self, relation: Literal[\"single\", \"spouse\", \"parent\", \"child\"]):\n        self.relation = []\n        self.add_relation(relation)\n\n    def add_relation(self, relation: Literal[\"single\", \"spouse\", \"parent\", \"child\"]):\n        self.relation.append(relation)\n\n    def drop_relation(self, relation: Literal[\"single\", \"spouse\", \"parent\", \"child\"]):\n        self.relation.remove(relation)\n\n\nclass Person(Relationship):\n\n    id = 0\n    people = []\n\n    def __init__(self, name: str, gender: Literal[\"F\", \"M\"]):\n        super().__init__(\"single\")\n        self.name = name.title()\n        self.gender = gender\n        self.spouse = None\n        self.parents = []\n        self.children = []\n        self.id = self.set_id()\n        Person.people.append(self)\n\n    @classmethod\n    def set_id(cls):\n        cls.id += 1\n        return cls.id\n\n    @classmethod\n    def get_people(cls):\n        def sort_people(p):\n            return p.get_name()\n\n        cls.people.sort(key=sort_people)\n        return cls.people\n\n    def get_id(self):\n        return self.id\n\n    def get_name(self):\n        return self.name\n\n    def get_parent(self):\n        return self.parents\n\n    def get_children(self):\n        return self.children\n\n    def is_maried(self):\n        return self.spouse\n\n    def get_relations(self):\n        return self.relation\n\n    def set_spouse(self, spouse):\n        if \"spouse\" in self.get_relations():\n            return False\n        self.spouse = spouse\n        self.drop_relation(\"single\")\n        self.add_relation(\"spouse\")\n        return True\n\n    def set_parents(self, parents):\n\n        def restrictions():\n            if self in parents:\n                print(f\"No se puede ser padre de uno mismo\")\n                return True\n            if self.parents:\n                print(f\"Ya tiene padres\")\n                return True\n            if parents.__len__() > 1:\n                if parents[0] == parents[1]:\n                    print(f\"Ambos padres NO pueden ser la misma persona.\")\n                    return True\n                if parents[0] != parents[1].is_maried():\n                    print(f\"Los padres NO estan casados.\")\n                    return True\n            return False\n\n        if restrictions():\n            return False\n\n        self.parents.append(parents[0])\n        if self not in parents[0].get_children():\n            parents[0].set_children([self])\n        if parents.__len__() > 1:\n            self.parents.append(parents[1])\n            if self not in parents[1].get_children():\n                parents[1].set_children([self])\n        if \"child\" not in self.get_relations():\n            self.add_relation(\"child\")\n        return True\n\n    def set_children(self, children):\n        for child in children:\n            if child not in self.get_children():\n                self.children.append(child)\n                if \"child\" not in child.get_relations():\n                    child.add_relation(\"child\")\n        if \"parent\" not in self.get_relations():\n            self.add_relation(\"parent\")\n\n\ndef are_siblings(person1: Person, person2: Person):\n\n    for parent in person1.get_parent():\n        if person2 in parent.get_children():\n            return True\n\n    for parent in person2.get_parent():\n        if person1 in parent.get_children():\n            return True\n\n    return False\n\n\ndef get_married(person1: Person, person2: Person):\n\n    if person1 == person2:\n        print(f\"No se puede casar consigo mismo\")\n    else:\n        p1_married = person1.is_maried()\n        p2_married = person2.is_maried()\n        siblings = are_siblings(person1, person2)\n        p1_son = person1 in person2.get_children()\n        p2_son = person1 in person1.get_children()\n        p1_parent = person1 in person2.get_parent()\n        p2_parent = person1 in person1.get_parent()\n        if any([p1_married, p2_married]):\n            print(f\"No se pueden casar: bigamia\")\n        elif any([siblings, p1_son, p2_son, p1_parent, p2_parent]):\n            print(f\"No se pueden casar: consanguinidad\")\n        else:\n            person1.set_spouse(person2)\n            person2.set_spouse(person1)\n\n\ndef menu():\n    option = -1\n\n    print(\"\\n\\tElegir una persona para mostrar el árbol genealógico\\n\")\n    for index, person in enumerate(Person.get_people()):\n        print(f\"\\t{index + 1} - {person.get_name()}\")\n    print(f\"\\t0 - Salir\")\n    while option < 0 or option > Person.get_people().__len__():\n        option = input(f\"\\n\\tIngrese una opción [1 - {Person.get_people().__len__()} | 0 para salir]: \")\n        if not option.isnumeric():\n            option = -1\n        else:\n            option = int(option)\n    return Person.get_people()[option - 1] if option > 0 else None\n\n\ndef load_generations():\n    # Primera generación\n    tito = Person(\"Tito\", \"M\")\n    livia = Person(\"Livia\", \"F\")\n    chacho = Person(\"Chacho\", \"M\")\n    tina = Person(\"Tina\", \"F\")\n    romula = Person(\"Romula\", \"F\")\n\n    get_married(tito, livia)\n    get_married(chacho, tina)\n\n    # Segunda generación\n    turula = Person(\"Turula\", \"F\")\n    pepe = Person(\"Pepe\", \"M\")\n    papo = Person(\"Papo\", \"M\")\n    pipa = Person(\"Pipa\", \"F\")\n    soto = Person(\"Soto\", \"M\")\n    rema = Person(\"Rema\", \"F\")\n    roma = Person(\"Roma\", \"F\")\n\n    for child in [turula, pepe, papo]:\n        child.set_parents([tito, livia])\n\n    for child in [pipa, soto]:\n        child.set_parents([chacho, tina])\n\n    for child in [rema, roma]:\n        child.set_parents([romula])\n\n    get_married(turula, soto)\n    get_married(pepe, pipa)\n    get_married(papo, roma)\n\n    # Tercera generación\n    tita = Person(\"Tita\", \"F\")\n    sita = Person(\"Sita\", \"F\")\n    pipo = Person(\"Pipo\", \"M\")\n    pepa = Person(\"Pepa\", \"F\")\n    chino = Person(\"Chino\", \"M\")\n    ramo = Person(\"Ramo\", \"M\")\n    rima = Person(\"Rima\", \"F\")\n\n    for child in [tita, sita]:\n        child.set_parents([turula, soto])\n\n    for child in [pipo, pepa, chino]:\n        child.set_parents([pepe, pipa])\n\n    for child in [ramo, rima]:\n        child.set_parents([rema])\n\n    get_married(tita, ramo)\n    get_married(pipo, rima)\n\n    # Cuarta generación\n    paco = Person(\"Paco\", \"M\")\n    chicho = Person(\"Chicho\", \"M\")\n    chona = Person(\"Chona\", \"F\")\n    chano = Person(\"Chano\", \"M\")\n    rama = Person(\"Rama\", \"F\")\n\n    paco.set_parents([tita, ramo])\n\n    for child in [chicho, chona, chano]:\n        child.set_parents([pipo, rima])\n\n    rama.set_parents([sita])\n\n    # Quinta generación\n    pico = Person(\"Pico\", \"M\")\n\n    pico.set_parents([paco])\n\n\ndef show_tree(person: Person, level: int = 0, iteration: int = 0, tree=None):\n    if tree is None:\n        tree = {0: [], 1: [], 2: []}\n    message = \"\"\n    for relationship in person.get_relations():\n        match relationship, level:\n            case \"child\", 0:\n                parents = []\n                siblings = []\n                for parent in person.get_parent():\n                    parents.append(parent.get_name())\n                    show_tree(parent, 1, iteration + 1, tree)\n                for sibling in person.get_parent()[0].get_children():\n                    if person != sibling:\n                        siblings.append(sibling.get_name())\n                message = f\"\\t{person.get_name()} es {'hijo' if person.gender == 'M' else 'hija'} de \" + f\"{', '.join(parents)}\"\n                if siblings:\n                    message += f\"\\n\\t{person.get_name()} es {'hermano' if person.gender == 'M' else 'hermana'} de \" + f\"{', '.join(siblings)}\"\n                if message not in tree[level]:\n                    tree[level].append(message)\n            case \"spouse\", 0:\n                message = f\"\\t{person.get_name()} está {'casado' if person.gender == 'M' else 'casada'} con {person.spouse.get_name()}\"\n                if message not in tree[level]:\n                    tree[level].append(message)\n            case \"parent\", 0:\n                children = []\n                for child in person.get_children():\n                    children.append(child.get_name())\n                    show_tree(child, 2, iteration + 1, tree)\n                message = f\"\\t{person.get_name()} es {'padre' if person.gender == 'M' else 'madre'} de \" + f\"{', '.join(children)}\"\n                if message not in tree[level]:\n                    tree[level].append(message)\n            case \"single\", 0:\n                message = f\"\\t{person.get_name()} es {'soltero' if person.gender == 'M' else 'soltera'}\"\n                if message not in tree[level]:\n                    tree[level].append(message)\n            case \"child\", 1:\n                parents = []\n                for parent in person.get_parent():\n                    parents.append(parent.get_name())\n                    show_tree(parent, 1, iteration + 1, tree)\n                message = f\"\\t{'-' * 5 * iteration + '> '}{person.get_name()} es {'hijo' if person.gender == 'M' else 'hija'} de \" + f\"{', '.join(parents)}\"\n                if message not in tree[level]:\n                    tree[level].append(message)\n            case \"parent\", 2:\n                children = []\n                for child in person.get_children():\n                    children.append(child.get_name())\n                    show_tree(child, 2, iteration + 1, tree)\n                message = f\"\\t{'-' * 5 * iteration + '> '}{person.get_name()} es {'padre' if person.gender == 'M' else 'madre'} de \" + f\"{', '.join(children)}\"\n                if message not in tree[level]:\n                    tree[level].append(message)\n        # tree[level].append(message)\n    return tree\n\n\nload_generations()\nwhile True:\n    person = menu()\n    if not person:\n        break\n    tree = show_tree(person)\n    tree[2].sort(reverse=True)\n    print(f\"\\n\\t## Árbol  {'#' * 30}\\n\")\n    for level in (1, 0, 2):\n        for msg in tree[level]:\n            print(msg)\n    print(f\"\\n\\t{'#' * 40}\")\n"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/python/oriaj3.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * ¡La Casa del Dragón ha finalizado y no volverá hasta 2026! \n * ¿Alguien se entera de todas las relaciones de parentesco\n * entre personajes que aparecen en la saga?\n * Desarrolla un árbol genealógico para relacionarlos (o invéntalo).\n * Requisitos:\n * 1. Estará formado por personas con las siguientes propiedades:\n *    - Identificador único (obligatorio)\n *    - Nombre (obligatorio)\n *    - Pareja (opcional)\n *    - Hijos (opcional)\n * 2. Una persona sólo puede tener una pareja (para simplificarlo).\n * 3. Las relaciones deben validarse dentro de lo posible.\n *    Ejemplo: Un hijo no puede tener tres padres.\n * Acciones:\n * 1. Crea un programa que permita crear y modificar el árbol.\n *    - Añadir y eliminar personas\n *    - Modificar pareja e hijos\n * 2. Podrás imprimir el árbol (de la manera que consideres).\n * \n * NOTA: Ten en cuenta que la complejidad puede ser alta si\n * se implementan todas las posibles relaciones. Intenta marcar\n * tus propias reglas y límites para que te resulte asumible.\n */\n \"\"\"\nimport uuid\n\n#from graphviz import Digraph\n\n\nclass Persona:\n    def __init__(self, nombre, apellido):\n        self.id = str(uuid.uuid4())  # Generación automática de ID único\n        self.nombre = nombre\n        self.apellido = apellido\n        self.parejas = [] # Lista de parejas\n        self.hijos = {}    # Diccionario de listas de hijos por pareja\n    \n    def __str__(self):\n        # Devuelve el nombre de la persona, su id, el nombre de sus parejas y sus hijos, sólo si tiene pareja o hijos\n        nombre_parejas = \", \".join([persona.nombre for persona in self.parejas])\n        hijos_str = {pareja.nombre: \", \".join([hijo.nombre for hijo in hijos]) for pareja, hijos in self.hijos.items()}\n        nombre_hijos = \"\\n\".join([f\"{pareja}: {hijos}\" for pareja, hijos in hijos_str.items()]) if hijos_str else \"Ninguno\"\n        if self.parejas and self.hijos:\n            return f\"{self.nombre} {self.apellido}\\n [Hijos=> {nombre_hijos}]\\n\"\n        else:\n            return \" \"\n        \n                \nclass ArbolGenealogico:\n    def __init__(self):\n        self.personas = {}\n    \n    def crear_persona(self, nombre, apellido):\n        persona = Persona(nombre, apellido)\n        self.personas[persona.id] = persona\n        return persona.id\n        \n    def buscar_persona(self, id):\n            return self.personas.get(id, None)\n    \n    def agregar_pareja(self, id_persona, id_pareja):\n        if id_persona == id_pareja:\n            print(\"Una persona no puede ser su propia pareja.\")\n            return\n        \n        persona = self.buscar_persona(id_persona)\n        pareja = self.buscar_persona(id_pareja)\n\n        if persona and pareja:\n            if id_pareja in persona.parejas or id_persona in pareja.parejas:\n                print(\"Estas personas ya están vinculadas como pareja.\")\n                return\n            \n            persona.parejas.append(pareja)\n            pareja.parejas.append(persona)\n            # Inicializa la lista de hijos para esta pareja\n            persona.hijos[pareja] = []\n            pareja.hijos[persona] = []\n        else:\n            print(\"Persona no encontrada\")\n    \n    def agregar_hijo(self, id_padre, id_madre, id_hijo):\n        padre = self.buscar_persona(id_padre)\n        madre = self.buscar_persona(id_madre)\n        hijo = self.buscar_persona(id_hijo)\n        \n        if padre and madre and hijo:\n            if madre in padre.hijos:\n                padre.hijos[madre].append(hijo)\n            if padre in madre.hijos:\n                madre.hijos[padre].append(hijo)\n        else:\n            print(\"Padre, madre o hijo no encontrado\")\n    #Formato de impresión de árbol con /tab para tabular los niveles/generaciones        \n    def imprimir_arbol(self):\n        set_visitados = set()\n\n        def mostrar_persona(persona: Persona, nivel=0):\n            identacion = \"\\t\" * nivel\n            if persona.id in set_visitados:\n                return\n            else:                              \n                print(f\"{identacion} - {persona.nombre} {persona.apellido}\")\n                set_visitados.add(persona.id)\n                if persona.parejas:\n                    for pareja in persona.parejas:\n                        print(f\"{identacion} Pareja: {pareja.nombre} {pareja.apellido}\")\n                        for hijo in persona.hijos.get(pareja, []):\n                            mostrar_persona(hijo, nivel + 1)\n\n        for persona in self.personas.values():\n            mostrar_persona(persona)\n            \n    def buscar_por_nombre(self, nombre):\n        return [persona for persona in self.personas.values() if persona.nombre.lower() == nombre.lower()]\n\n    \n    def eliminar_persona(self, id):\n        persona = self.buscar_persona(id)\n        if persona:\n            # Desvincula las parejas\n            for pareja in persona.parejas:\n                pareja.parejas.remove(persona)\n                if persona in pareja.hijos:\n                    del pareja.hijos[persona]\n            \n            # Elimina a la persona de los hijos de cualquier padre\n            for padre in self.personas.values():\n                for pareja, hijos in padre.hijos.items():\n                    if persona in hijos:\n                        hijos.remove(persona)\n            \n            # Elimina a la persona\n            del self.personas[id]\n            print(f\"Persona {id} eliminada.\")\n        else:\n            print(\"Persona no encontrada\")\n    \n    def generar_arbol_grafico(self):\n        dot = Digraph(comment='Árbol Genealógico')\n        \n        # Añadir nodos\n        for persona in self.personas.values():\n            dot.node(persona.id, f'{persona.nombre} {persona.apellido}')\n        \n        # Añadir conexiones (flechas) entre padres e hijos\n        for persona in self.personas.values():\n            for pareja, hijos in persona.hijos.items():\n                for hijo in hijos:\n                    dot.edge(persona.id, hijo.id, color='blue')  # Conectar padre con hijo\n        \n        dot.render('arbol_genealogico_hijos', format='png', cleanup=True)\n        print(\"Árbol genealógico generado como 'arbol_genealogico_hijos.png'.\")\n\n        # Añadir flecha para cada pareja\n        ya_conectado = set()\n        for persona in self.personas.values():\n            for pareja in persona.parejas:\n                if (persona.id, pareja.id) not in ya_conectado and (pareja.id, persona.id) not in ya_conectado:\n                    dot.edge(persona.id, pareja.id, color='red', style='dashed')  # Conectar parejas\n                    ya_conectado.add((persona.id, pareja.id))                    \n        \n        dot.render('arbol_genealogico_relaciones', format='png', cleanup=True)\n        print(\"Árbol genealógico generado como 'arbol_genealogico_relaciones.png'.\")\n#Crear arbol genealogico\narbol = ArbolGenealogico()\n\n\n# Crear personas\n\n#Baratheon - Targaryan\njocelyn = arbol.crear_persona(\"Jocelyn\", \"Baratheon\")\naemon = arbol.crear_persona(\"Aemon\", \"Targaryan\")\n\n#Targaryaen - Velaryon\ncorlys = arbol.crear_persona(\"Corlys\", \"Velaryon\")\nrhaenys = arbol.crear_persona(\"Rhaenys\", \"Targaryen\")\n\narbol.agregar_pareja(jocelyn, aemon)\narbol.agregar_hijo(jocelyn, aemon, rhaenys)\narbol.agregar_pareja(corlys, rhaenys)\n\nlaena = arbol.crear_persona(\"Laena\", \"Velaryon\")\nlaenor = arbol.crear_persona(\"Laenor\", \"Velaryon\")\n\narbol.agregar_hijo(corlys, rhaenys, laena)\narbol.agregar_hijo(corlys, rhaenys, laenor)\n\n#Targaryen - Arryn\ndaella = arbol.crear_persona(\"Daella\", \"Targaryen\")\nrodrik = arbol.crear_persona(\"Rodrik\", \"Arryn\")\n\n#Targaryen - Targaryen\nbaelon = arbol.crear_persona(\"Baelon I\", \"Targaryen\")\nalyssa = arbol.crear_persona(\"Alyssa\", \"Targaryen\")\n\n#Targaryen - Hihgtower\naemma = arbol.crear_persona(\"Aemma\", \"Arryn\")\nviserys_i = arbol.crear_persona(\"Viserys I\", \"Targaryen\")\nalicent = arbol.crear_persona(\"Alicent\", \"Hightower\")\n\narbol.agregar_pareja(daella, rodrik)\narbol.agregar_hijo(daella, rodrik, aemma)\narbol.agregar_pareja(baelon, alyssa)\narbol.agregar_hijo(baelon, alyssa, viserys_i)\n\narbol.agregar_pareja(viserys_i, aemma)\nrhaenyra = arbol.crear_persona(\"Rhaenyra\", \"Targaryen\")\n\narbol.agregar_hijo(viserys_i, aemma, rhaenyra)\n\n\narbol.agregar_pareja(viserys_i, alicent)\naegon_ii = arbol.crear_persona(\"Aegon II\", \"Targaryen\")\nhelaena = arbol.crear_persona(\"Helaena\", \"Targaryen\")\naemond = arbol.crear_persona(\"Aemond\", \"Targaryen\")\ndaeron = arbol.crear_persona(\"Daeron\", \"Targaryen\")\n\narbol.agregar_hijo(viserys_i, alicent, aegon_ii)\narbol.agregar_hijo(viserys_i, alicent, helaena)\narbol.agregar_hijo(viserys_i, alicent, aemond)\narbol.agregar_hijo(viserys_i, alicent, daeron)\n\n#Daemon\ndaemon = arbol.crear_persona(\"Daemon\", \"Targaryen\")\narbol.agregar_pareja(daemon, laena)\n\nbaela = arbol.crear_persona(\"Baela\", \"Targaryen\")\nrhaena = arbol.crear_persona(\"Rhaena\", \"Targaryen\")\n\narbol.agregar_hijo(daemon, laena, baela)\narbol.agregar_hijo(daemon, laena, rhaena)\n\n#Rhaenyra\narbol.agregar_pareja(rhaenyra, laenor)\n\njacaerys = arbol.crear_persona(\"Jacaerys\", \"Velaryon\")\nlucerys = arbol.crear_persona(\"Lucerys\", \"Velaryon\")\njoffrey = arbol.crear_persona(\"Joffrey\", \"Velaryon\")\n\narbol.agregar_hijo(rhaenyra, laenor, jacaerys)\narbol.agregar_hijo(rhaenyra, laenor, lucerys)\narbol.agregar_hijo(rhaenyra, laenor, joffrey)\n\n#Rhaenyra - Daemon\narbol.agregar_pareja(rhaenyra, daemon)\n\nviserys_ii = arbol.crear_persona(\"Viserys II\", \"Targaryen\")\nvisenya = arbol.crear_persona(\"Visenya\", \"Targaryen\")\naegon_iii = arbol.crear_persona(\"Aegon III\", \"Targaryen\")\n\narbol.agregar_hijo(rhaenyra, daemon, viserys_ii)\narbol.agregar_hijo(rhaenyra, daemon, visenya)\narbol.agregar_hijo(rhaenyra, daemon, aegon_iii)\n\n#Aegon II - Helaena\narbol.agregar_pareja(aegon_ii, helaena)\n\njaehaera = arbol.crear_persona(\"Jaehaera\", \"Targaryen\")\njaehaerys = arbol.crear_persona(\"Jaehaerys\", \"Targaryen\")\nmaelor = arbol.crear_persona(\"Maelor\", \"Targaryen\")\n\narbol.agregar_hijo(aegon_ii, helaena, jaehaera)\narbol.agregar_hijo(aegon_ii, helaena, jaehaerys)\narbol.agregar_hijo(aegon_ii, helaena, maelor)\n\n#Muestra el arbol\narbol.imprimir_arbol()\n\n#Imprime el arbol en png\n#arbol.generar_arbol_grafico()\n"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/python/pyramsd.py",
    "content": "class Persona:\n\n    def __init__(self, id: int, nombre) -> None:\n        self.id = id\n        self.nombre = nombre\n        self.pareja = None\n        self.hijos = []\n        self.padre = None\n    \n    def add_pareja(self, pareja):\n        if self.pareja is None:\n            self.pareja = pareja\n            pareja.pareja =self.pareja\n        else:\n            print(\"[!] Esta persona ya tiene pareja\")\n\n    def add_hijo(self, child):\n        self.hijos.append(child)\n\nclass AdministrarPeronas:\n    def __init__(self) -> None:\n        self.person_list = {}\n    \n    def nueva_persona(self):\n        nombre = input(\"Introduce el nombre de la persona: \")\n        id = input(\"Asigna un identificador: \")\n        nueva_persona = Persona(id, nombre)\n        self.person_list[f\"{nueva_persona.id}\"] = nueva_persona\n    \n    def mostrar_personas(self):\n            for id, person in self.person_list.items():\n                print(f\"{id}: {person.nombre}\")\n                if person.pareja != None:\n                    print(f\"\\033[38;5;214m[!!] Esta casad@ con {person.pareja.nombre}\\033[0m\")\n                else:\n                    print(\"\\033[34m[!] No tiene pareja\\033[0m\")\n                if person.hijos:\n                    print(f\"\\033[32m[+] Tiene hijos: {', '.join(child.nombre for child in person.hijos)}\\033[0m\")\n                else:\n                    print(\"\\033[34m[!] No tiene hijos\\033[0m\")\n\n    def elimina_persona(self):\n        id = input(\"Introduce el identificador de la persona que quieres eliminar: \")\n        if id in self.person_list:\n            del self.person_list[id]\n            print(\"\\033[32m[+] Persona eliminada correctamente\\033[0m\")\n        else:\n            print(\"\\033[31m[-] El identificador proporcionado no se corresponde con ninguna persona\\033[0m\")\n\n    def editar_persona(self):\n        id = input(\"Introduce el identificador de la persona que quieres modificar: \")\n        if id in self.person_list:\n            nombre = input(\"Introduce el nuevo nombre: \")\n            self.person_list[id].nombre =  nombre\n        else:\n            print(\"\\033[31m[-] El identificador proporcionado no se corresponde con ninguna persona\\033[0m\")\n\n    def cambiar_pareja(self):\n        id = input(\"Introduce el Id de la persona que quieres modificar su pareja\")\n        if id in self.person_list and self.person_list[id].pareja != None:\n            id_partner = input(\"Introduce el id de su nueva pareja\")\n            if id_partner in self.person_list:\n                self.person_list[id].pareja = self.person_list[id_partner]\n                self.person_list[id_partner].pareja = self.person_list[id]\n                print(\"Pareja añadida correctamente\")\n            else:\n                print(\"\\033[31m[-] El id introducido no se corresponde con ninguna persona\\033[0m\")\n        else: \n            print(\"\\033[31m[-] El id introducido no se corresponde con ninguna persona\\033[0m\")\n    \n    def add_pareja(self):\n        id = input(\"Introduce el Id de la persona a la que quieres añadir una pareja: \")\n        if id in self.person_list and self.person_list[id].pareja is None:\n            id_partner = input(\"Introduce el Id de la pareja: \")\n            if id_partner in self.person_list and self.person_list[id_partner].pareja is None:\n                persona = self.person_list[id]\n                pareja = self.person_list[id_partner]\n\n                # Establecer relación de pareja\n                persona.pareja = pareja\n                pareja.pareja = persona\n\n                # Transferir hijos\n                for hijo in persona.hijos:\n                    if hijo not in pareja.hijos:\n                        pareja.hijos.append(hijo)\n                for hijo in pareja.hijos:\n                    if hijo not in persona.hijos:\n                        persona.hijos.append(hijo)\n\n                print(\"\\033[32m[+] Pareja añadida correctamente y se compartieron los hijos\\033[0m\")\n            else:\n                print(\"\\033[31m[-] El id de la pareja no existe o ya tiene pareja\\033[0m\")\n        else: \n            print(\"\\033[31m[-] No se puede añadir una pareja. El Id no existe o ya tiene pareja\\033[0m\")\n    \n    def add_hijo(self):\n        id = input(\"Introduce el id del padre: \")\n        id_child = input(\"Introduce le id del hijo: \")\n        if id in self.person_list and id_child in self.person_list: \n            self.person_list[id].hijos.append(self.person_list[id_child])\n        else:\n            print(\"\\033[31m[-] Los ids introducidos no son correctos\\033[0m\")\n                \ndef main_menu():\n\n    person_managment = AdministrarPeronas()\n\n    while True:\n        print(\"\\n--- Menú Principal ---\")\n        print(\"1. Añadir persona\")\n        print(\"2. Mostrar todas las personas\")\n        print(\"3. Eliminar persona\")\n        print(\"4. Editar persona\")\n        print(\"5. Añadir pareja\")\n        print(\"6. Cambiar pareja\")\n        print(\"7. Añadir hij@\")\n        print(\"8. Dibujar árbol genealógico\")\n        print(\"9. Salir\")\n\n        option = input(\"Introduce una opción: \")\n\n        match option:\n            case \"1\":\n                person_managment.nueva_persona()\n            case \"2\":\n                person_managment.mostrar_personas()\n            case \"3\":\n                person_managment.elimina_persona()\n            case \"4\":\n                person_managment.editar_persona()\n            case \"5\":\n                person_managment.add_pareja()\n            case \"6\":\n                person_managment.cambiar_pareja()\n            case \"7\":\n                person_managment.add_hijo()\n            case \"8\":\n                break\n\n\n\nmain_menu()"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/python/raulG91.py",
    "content": "class Person:\n\n    def __init__(self,id:int,name:str):\n        self.id = id\n        self.name = name\n        self.patner = None\n        self.childs = []\n    def getId(self):\n        return self.id\n    def getName(self):\n        return self.name\n    def getPatner(self):\n        return self.patner\n    def getChilds(self):\n        return self.childs\n    def addPatner(self,person):\n        if self.patner:\n            print(f'{self.name} already has a patner')\n        else:\n            self.patner = person    \n    def addChild(self,person):\n        self.childs.append(person)\n\ndef exist(iterator:list[Person],id)->int:\n    for index,element in enumerate(iterator):\n        if element.getId()==id:\n            return index\n    return -1 \ndef check_child_has_parents(child_id:int,iterator:list[Person]):\n    #Check if the child has parents \n   for element in iterator:\n       child_list = element.getChilds()\n       if child_id in child_list:\n           return True\n\n   return False    \n\n    \ndef print_tree(iterator:list[Person]):\n   for element in iterator:\n       patner_name = \"\"\n       if element.getPatner():\n        patner_name = iterator[exist(iterator,element.getPatner())].getName()\n       childs = element.getChilds()\n       childs_names = list(map(lambda x: iterator[exist(iterator,x)].getName(),childs))\n       print(f'Person {element.getId()}, name: {element.getName()} patner: {patner_name}, childs: {childs_names}')\n       \n       \ndef main():\n    people:list[Person] = []\n    while True:\n        print(\"What do you want to do?\")\n        print(\"Press 1 to add a person\")\n        print(\"Press 2 to delete a person\")\n        print(\"Press 3 to add a patner\")\n        print(\"Press 4 to add a child to one person\")\n        print(\"Press 5 to print tree \")\n        print(\"Press 6 to exit the program\")\n        option = int(input(\"Which option do you choose? \"))\n\n        match option:\n            case 1: \n                id = int(input(\"Enter person id \"))\n                if exist(people,id) == -1:\n                    #If person doesn't exist\n                    name = input(\"Enter person name \")\n                    new_person = Person(id,name)\n                    people.append(new_person)\n                else:\n                    print(f'Person {id} already exist')    \n            case 2:\n                id = int(input(\"Enter the person id to be deleted \"))\n                index = exist(people,id)\n                if index >= 0:\n                    people.pop(index)\n                else:\n                    print(f'Person {id} doesn\\'t exist')    \n            case 3:\n                patner1_id = int(input(\"Enter the id for patner 1 \"))\n                patner1_index = exist(people,patner1_id)\n                if patner1_index >= 0:\n                    if not people[patner1_index].getPatner():\n                        patner2_id = int(input(\"Enter the id for patner 2 \"))\n                        patner2_index = exist(people,patner2_id)\n                        if patner2_index >=0:\n                            #Check if patner doesn't have a patner\n                            if not people[patner2_index].getPatner():\n                                if patner1_id != patner2_id:\n                                    people[patner1_index].addPatner(people[patner2_index].getId())\n                                    people[patner2_index].addPatner(people[patner1_index].getId())\n                                else:\n                                    print(\"A patner could not be the same person\")    \n                            else:\n                                print(f'Person {patner2_id} has already a patner {people[patner2_index].getPatner()}')    \n                        else:\n                            print(f'Person {patner2_id} doesn\\'t exist ')\n                    else:\n                        print(f'Person {patner1_id} has already a patner {people[patner1_index].getPatner()}')\n                else:\n                    print(f'Person {patner1_id} doesn\\'t exist')    \n\n            case 4:\n                child_id = int(input(\"Enter the id for the person to be added as child \"))\n                child_index = exist(people,child_id)\n                if child_index >= 0:\n                    #If the person exist, let user to \n                    if not check_child_has_parents(child_id,people):\n                        mother_id = int(input(\"Enter id of the mother \"))\n                        mother_index = exist(people,mother_id)\n                        if mother_index >= 0:\n                            #Find father \n                            father_id = int(input(\"Enter id of the father \"))\n                            father_index = exist(people,father_id)\n\n                            if father_index >= 0:\n                                if father_id != mother_id:\n                                    people[mother_index].addChild(people[child_index].getId())\n                                    people[father_index].addChild(people[child_index].getId())\n                                else:\n                                    print(\"Father and mother could not be the same person \")    \n                            else:\n                                print(f'Person {father_id} doesn\\'t exist')     \n                        else:\n                            print(f'Person {mother_id} does not exit')\n                    else:\n                        print(\"Person already has parents\")\n                else:\n                    print(f'Person {child_id} doesn\\'t exist')\n            case 5:\n                print_tree(people)          \n            case 6: \n                break\n\nmain()\n"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/python/redom69.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * ¡La Casa del Dragón ha finalizado y no volverá hasta 2026! \n * ¿Alguien se entera de todas las relaciones de parentesco\n * entre personajes que aparecen en la saga?\n * Desarrolla un árbol genealógico para relacionarlos (o invéntalo).\n * Requisitos:\n * 1. Estará formado por personas con las siguientes propiedades:\n *    - Identificador único (obligatorio)\n *    - Nombre (obligatorio)\n *    - Pareja (opcional)\n *    - Hijos (opcional)\n * 2. Una persona sólo puede tener una pareja (para simplificarlo).\n * 3. Las relaciones deben validarse dentro de lo posible.\n *    Ejemplo: Un hijo no puede tener tres padres.\n * Acciones:\n * 1. Crea un programa que permita crear y modificar el árbol.\n *    - Añadir y eliminar personas\n *    - Modificar pareja e hijos\n * 2. Podrás imprimir el árbol (de la manera que consideres).\n * \n * NOTA: Ten en cuenta que la complejidad puede ser alta si\n * se implementan todas las posibles relaciones. Intenta marcar\n * tus propias reglas y límites para que te resulte asumible.\n */\n \"\"\"\n\nclass Person:\n    def __init__(self, id, name, couple=None, children=None):\n        self.id = id\n        self.name = name\n        self.couple = couple\n        self.children = children if children is not None else []\n\n    def add_child(self, child):\n        self.children.append(child)\n\n    def modify_couple(self, couple):\n        self.couple = couple\n\n    def __repr__(self):\n        couple_name = self.couple.name if self.couple else \"None\"\n        return f\"Person(id={self.id}, name={self.name}, couple={couple_name}, children={len(self.children)})\"\n\nclass FamilyTree:\n    def __init__(self, person):\n        self.root = person\n        self.people = {person.id: person}\n\n    def add_person(self, person):\n        if person.id not in self.people:\n            self.people[person.id] = person\n        else:\n            print(f\"La persona con ID {person.id} ya existe en el árbol genealógico.\")\n\n    def delete_person(self, person_id):\n        if person_id in self.people:\n            del self.people[person_id]\n        else:\n            print(f\"No se encontró ninguna persona con ID {person_id}.\")\n\n    def edit_person(self, id, name=None, couple=None, children=None):\n        if id in self.people:\n            person = self.people[id]\n            if name:\n                person.name = name\n            if couple:\n                person.modify_couple(couple)\n            if children is not None:\n                person.children = children if isinstance(children, list) else []\n        else:\n            print(f\"No se encontró ninguna persona con ID {id}.\")\n\n    def display_tree(self, person=None, level=0):\n        if person is None:\n            person = self.root\n\n        indent = \" \" * (level * 4)\n        couple_name = f\" & {person.couple.name}\" if person.couple else \"\"\n        print(f\"{indent}{person.name}{couple_name}\")\n\n        if person.children:\n            for child in person.children:\n                self.display_tree(child, level + 1)\n\n    def __repr__(self):\n        return f\"FamilyTree(root={self.root.name}, total_people={len(self.people)})\"\n\ndef main():\n\n    jaehaerys = Person(id=1, name=\"Jaehaerys I Targaryen\")\n    alysanne = Person(id=2, name=\"Alysanne Targaryen\")\n\n    baelon = Person(id=3, name=\"Baelon Targaryen\")\n    alyssa = Person(id=4, name=\"Alyssa Targaryen\")\n\n    viserys = Person(id=5, name=\"Viserys I Targaryen\")\n    aemma = Person(id=6, name=\"Aemma Arryn\")\n\n    daemon = Person(id=7, name=\"Daemon Targaryen\")\n    rhea = Person(id=8, name=\"Rhea Royce\")\n    laena = Person(id=9, name=\"Laena Velaryon\")\n    rhaenyra = Person(id=10, name=\"Rhaenyra Targaryen\")\n\n    alicent = Person(id=11, name=\"Alicent Hightower\")\n    aegon_ii = Person(id=12, name=\"Aegon II Targaryen\")\n    helaena = Person(id=13, name=\"Helaena Targaryen\")\n    aemond = Person(id=14, name=\"Aemond Targaryen\")\n    daeron = Person(id=15, name=\"Daeron Targaryen\")\n\n    jaehaerys.couple = alysanne\n    baelon.couple = alyssa\n    baelon.children = [viserys, daemon]\n    viserys.couple = aemma\n    viserys.children = [rhaenyra]\n    daemon.couple = rhea  \n    daemon.children = []  \n\n    daemon.couple = laena\n    baela = Person(id=16, name=\"Baela Targaryen\")\n    rhaena = Person(id=17, name=\"Rhaena Targaryen\")\n    daemon.children = [baela, rhaena]\n\n    rhaenyra.couple = daemon\n\n    viserys.couple = alicent\n    viserys.children += [aegon_ii, helaena, aemond, daeron] \n\n    family_tree = FamilyTree(viserys)\n    family_tree.add_person(jaehaerys)\n    family_tree.add_person(alysanne)\n    family_tree.add_person(baelon)\n    family_tree.add_person(alyssa)\n    family_tree.add_person(daemon)\n    family_tree.add_person(rhea)\n    family_tree.add_person(laena)\n    family_tree.add_person(rhaenyra)\n    family_tree.add_person(alicent)\n    family_tree.add_person(aegon_ii)\n    family_tree.add_person(helaena)\n    family_tree.add_person(aemond)\n    family_tree.add_person(daeron)\n    family_tree.add_person(baela)\n    family_tree.add_person(rhaena)\n\n    family_tree.display_tree()\n\n\n\nif __name__ == \"__main__\":\n    main()"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/python/rigo93acosta.py",
    "content": "'''\n/*\n * EJERCICIO:\n * ¡La Casa del Dragón ha finalizado y no volverá hasta 2026! \n * ¿Alguien se entera de todas las relaciones de parentesco\n * entre personajes que aparecen en la saga?\n * Desarrolla un árbol genealógico para relacionarlos (o invéntalo).\n * Requisitos:\n * 1. Estará formado por personas con las siguientes propiedades:\n *    - Identificador único (obligatorio)\n *    - Nombre (obligatorio)\n *    - Pareja (opcional)\n *    - Hijos (opcional)\n * 2. Una persona sólo puede tener una pareja (para simplificarlo).\n * 3. Las relaciones deben validarse dentro de lo posible.\n *    Ejemplo: Un hijo no puede tener tres padres.\n * Acciones:\n * 1. Crea un programa que permita crear y modificar el árbol.\n *    - Añadir y eliminar personas\n *    - Modificar pareja e hijos\n * 2. Podrás imprimir el árbol (de la manera que consideres).\n * \n * NOTA: Ten en cuenta que la complejidad puede ser alta si\n * se implementan todas las posibles relaciones. Intenta marcar\n * tus propias reglas y límites para que te resulte asumible.\n */\n'''\n\nclass Person:\n\n    def __init__(self, id: int, name: str) -> None:\n        \n        self.id = id\n        self.name = name\n        self.partner = None\n        self.children: list = []\n        self.has_parents = False\n\n    def add_partner(self, partner):\n        if self.partner is not None:\n            print(f\"{self.name} ya tiene una pareja: {self.partner.name}\")\n        else:\n            self.partner = partner\n            partner.partner = self\n            print(f\"{self.name} y {partner.name} son pareja.\")\n\n    def add_child(self, child): \n        if child not in self.children:\n            self.children.append(child)\n            print(f\"{child.name} es hijo de {self.name}\")\n        else:\n            print(f\"{child.name} ya es hijo de {self.name}\")\n\n\nclass FamilyTree:\n\n    def __init__(self) -> None:\n        self.people: dict = {}\n\n    def add_person(self, id, name):\n        if id in self.people:\n            print(f\"Ya existe una persona con el ID: {id}.\")\n        else:\n            person = Person(id, name)\n            self.people[id] = person\n            print(f\"{person.name} ha sido añadido al árbol.\")\n\n    def remove_person(self, id):\n\n        if id in self.people:\n            person = self.people[id]\n            del self.people[id]\n            print(f\"{person.name} ha sido eliminado del árbol.\")\n        else:\n            print(f\"{person.name} no está en el árbol.\")\n\n    def set_partner(self, id1, id2):\n        if id1 not in self.people and id2 not in self.people:\n            print(\"Alguna de las personas no está en el árbol.\")\n        else:\n            person1 = self.people[id1]\n            person2 = self.people[id2]\n            person1.add_partner(person2)\n\n    def add_child(self, parent_id, child_id):\n        if parent_id == child_id:\n            print(\"Una persona no puede ser su propio hijo.\")\n        elif parent_id not in self.people and child_id not in self.people:\n            print(\"Alguna de las personas no está en el árbol.\")\n        else:\n            parent = self.people[parent_id]\n            if parent.partner is None:\n                print(\"Se necesita una pareja para tener hijos.\")\n            else:\n                child = self.people[child_id]\n                child.has_parents = True\n                parent.add_child(child)\n                parent.partner.add_child(child)\n        \n\n    def print_tree(self):\n        \n        print(\"=\"*63)\n        print(\"Árbol genealógico\")\n        print(\"=\"*63)\n        visited = set()\n\n        def print_person(person, level = 0):\n\n            if person.id in visited:\n                return\n            \n            visited.add(person.id)\n\n            indent = \"\\t\" * level\n            \n            print(f\"{indent} - {person.name} [ID: {person.id}]\")\n            \n            if person.partner:\n                visited.add(person.partner.id)\n                print(f\"{indent}   Pareja: {person.partner.name} [ID: {person.partner.id}]\")\n\n            if person.children:\n                print(f\"{indent}   Hijos:\")\n                for child in person.children:\n                    print_person(child, level + 1)\n\n\n        for person in self.people.values():\n            is_child = person.has_parents\n            if not is_child:\n                print_person(person)\n\nif __name__ == \"__main__\":\n\n    print(\"=\"*63)\n    print(\"Árbol genealógico\")\n    print(\"=\"*63)\n    tree = FamilyTree()\n    \n    tree.add_person(1, \"Jocelyn\")\n    tree.add_person(2, \"Aemon\")\n\n    tree.set_partner(1, 2)\n\n    tree.add_person(3, \"Rhaenys\")\n\n    tree.add_child(1, 3)\n\n    tree.add_person(4, \"Corlys\")\n\n    tree.set_partner(3, 4)\n\n    tree.add_person(5, \"Laena\")\n    tree.add_person(6, \"Laenor\")\n\n    tree.add_child(3, 5)\n    tree.add_child(3, 6)\n\n    tree.add_person(7, \"Baelon\")\n    tree.add_person(8, \"Alyssa\")\n\n    tree.set_partner(7, 8)\n\n    tree.add_person(9, \"Viserys I\")\n    tree.add_person(10, \"Daemon\")\n\n    tree.add_child(7, 9)\n    tree.add_child(8, 10)\n\n    tree.add_person(11, \"Aemma\")\n\n    tree.set_partner(9, 11)\n\n    tree.add_person(12, \"Rhaenyra\")\n\n    tree.add_child(9, 12)\n\n    tree.set_partner(10, 12)\n\n    tree.add_person(13, \"Aegon\")\n    tree.add_person(14, \"Viserys\")\n\n    tree.add_child(12, 13)\n    tree.add_child(12, 14)\n\n    tree.print_tree()\n\n"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/rust/kenysdev.rs",
    "content": "/*\n╔═══════════════════════════════════════╗\n║ Autor:  Kenys Alvarado                ║\n║ GitHub: https://github.com/Kenysdev   ║\n║ 2024 -  Rust                          ║\n╚═══════════════════════════════════════╝\n-----------------------------------------------------\n* 34 ÁRBOL GENEALÓGICO DE LA CASA DEL DRAGÓN\n-----------------------------------------------------\n * ¡La Casa del Dragón ha finalizado y no volverá hasta 2026!\n * ¿Alguien se entera de todas las relaciones de parentesco\n * entre personajes que aparecen en la saga?\n * Desarrolla un árbol genealógico para relacionarlos (o invéntalo).\n * Requisitos:\n * 1. Estará formado por personas con las siguientes propiedades:\n *    - Identificador único (obligatorio)\n *    - Nombre (obligatorio)\n *    - Pareja (opcional)\n *    - Hijos (opcional)\n * 2. Una persona sólo puede tener una pareja (para simplificarlo).\n * 3. Las relaciones deben validarse dentro de lo posible.\n *    Ejemplo: Un hijo no puede tener tres padres.\n * Acciones:\n * 1. Crea un programa que permita crear y modificar el árbol.\n *    - Añadir y eliminar personas\n *    - Modificar pareja e hijos\n * 2. Podrás imprimir el árbol (de la manera que consideres).\n *\n * NOTA: Ten en cuenta que la complejidad puede ser alta si\n * se implementan todas las posibles relaciones. Intenta marcar\n * tus propias reglas y límites para que te resulte asumible.\n\n'_______\n' NOTE Here Is the 'people.json' file with the data if you want to test it:\n'      https://pastebin.com/29kWWgPU\n'      Just paste it into the base folder.\n*/\n\nuse std::fs;\nuse std::collections::{HashMap, HashSet};\nuse std::io::{self, Write};\n\n/*\nhttps://crates.io/crates/serde_json\n[dependencies]\nserde = { version = \"1.0.197\", features = [\"derive\"] }\nserde_json = \"1.0.115\"\n*/\nuse serde::{Serialize, Deserialize};\n\n//_______________________________________\n#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]\npub struct Person {\n    id: i32,\n    name: String,\n    parents: HashSet<i32>,\n    partners: HashSet<i32>,\n    children: HashMap<i32, Vec<i32>>,\n    deleted: bool,\n}\n\nimpl Person {\n    pub fn new(id: i32, name: String) -> Self {\n        Self {\n            id,\n            name,\n            parents: HashSet::new(),\n            partners: HashSet::new(),\n            children: HashMap::new(),\n            deleted: false,\n        }\n    }\n\n    pub fn id(&self) -> i32 { self.id }\n    pub fn name(&self) -> &str { &self.name }\n    pub fn parents(&self) -> &HashSet<i32> { &self.parents }\n    pub fn parents_mut(&mut self) -> &mut HashSet<i32> { &mut self.parents }\n    pub fn partners(&self) -> &HashSet<i32> { &self.partners }\n    pub fn partners_mut(&mut self) -> &mut HashSet<i32> { &mut self.partners }\n    pub fn children(&self) -> &HashMap<i32, Vec<i32>> { &self.children }\n    pub fn children_mut(&mut self) -> &mut HashMap<i32, Vec<i32>> { &mut self.children }\n    pub fn is_deleted(&self) -> bool { self.deleted }\n    pub fn mark_as_deleted(&mut self) { self.deleted = true; }\n}\n\nimpl std::fmt::Display for Person {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"Person(id={}, name='{}')\", self.id, self.name)\n    }\n}\n\n//_______________________________________\npub mod input {\n    use super::*;\n    pub fn get_str(msg: &str) -> String {\n        loop {\n            print!(\"{}\", msg);\n            io::stdout().flush().unwrap();\n\n            let mut input = String::new();\n            io::stdin().read_line(&mut input).unwrap();\n            let input = input.trim();\n\n            if !input.is_empty() {\n                return input.to_string();\n            }\n\n            println!(\"\\n❌ This field cannot be empty.\");\n        }\n    }\n\n    pub fn get_int(msg: &str) -> i32 {\n        loop {\n            let input = get_str(msg);\n            match input.parse() {\n                Ok(num) => return num,\n                Err(_) => println!(\"\\n❌ Enter an integer.\"),\n            }\n        }\n    }\n}\n\n//_______________________________________\npub struct People {\n    people: Vec<Person>,\n    filename: String,\n}\n\nimpl People {\n    pub fn new(filename: Option<&str>) -> Self {\n        let filename = filename.unwrap_or(\"people.json\").to_string();\n        let mut people = Self { people: Vec::new(), filename };\n        people.load_from_json();\n        people\n    }\n\n    pub fn get_people(&self) -> &[Person] {\n        &self.people\n    }\n\n    pub fn load_from_json(&mut self) {\n        match fs::read_to_string(&self.filename) {\n            Ok(json_string) => {\n                match serde_json::from_str(&json_string) {\n                    Ok(loaded_people) => {\n                        self.people = loaded_people;\n                        println!(\"✅ The file '{}' has been successfully loaded.\", self.filename);\n                    },\n                    Err(e) => println!(\"⚠️ Error parsing JSON from '{}': {}\", self.filename, e),\n                }\n            },\n            Err(_) => {\n                println!(\"⚠️ The file '{}' not found. Starting with an empty list.\", self.filename);\n                self.people = vec![Person::new(0, \"unknown\".to_string())];\n            }\n        }\n    }\n\n    pub fn save_to_json(&self) {\n        match serde_json::to_string_pretty(&self.people) {\n            Ok(json_string) => {\n                match fs::write(&self.filename, json_string) {\n                    Ok(_) => println!(\"✅ Data saved successfully to {}\", self.filename),\n                    Err(e) => println!(\"❌ An error occurred while saving to '{}': {}.\", self.filename, e),\n                }\n            },\n            Err(e) => println!(\"❌ Error serializing data: {}\", e),\n        }\n    }\n\n    pub fn print_people(&self) {\n        println!(\"{}\", \"_\".repeat(32));\n        println!(\"|{:4}|{:-25}|\", \"id\", \"Name\");\n        println!(\"{}\", \"_\".repeat(32));\n        for person in self.people.iter().filter(|p| !p.is_deleted()) {\n            println!(\"|{:4}|{:-25}|\", person.id(), person.name());\n        }\n        println!(\"{}\", \"*\".repeat(32));\n    }\n\n    pub fn get_person_by_id(&self, id: i32) -> Option<&Person> {\n        self.people.iter().find(|p| p.id() == id)\n    }\n    \n    pub fn get_person_by_id_mut(&mut self, id: i32) -> Option<&mut Person> {\n        self.people.iter_mut().find(|p| p.id() == id)\n    }\n\n    pub fn add_person(&mut self) {\n        println!(\"Add Person or 'x' to Exit\");\n        let name = input::get_str(\"Name: \");\n        if name.eq_ignore_ascii_case(\"x\") {\n            println!(\"Exit\");\n            return;\n        }\n        let new_id = self.people.iter().map(|p| p.id()).max().unwrap_or(-1) + 1;\n        let new_person = Person::new(new_id, name);\n        println!(\"✅ Added: {}\", new_person);\n        self.people.push(new_person);\n        self.save_to_json();\n    }\n\n    pub fn remove_person(&mut self) {\n        self.print_people();\n        println!(\"\\nPerson ID to mark as deleted or a letter to exit.\");\n        let id_str = input::get_str(\"ID: \");\n        match id_str.parse::<i32>() {\n            Ok(id) => {\n                if let Some(person) = self.people.iter_mut().find(|p| p.id() == id) {\n                    if !person.partners().is_empty() || !person.parents().is_empty() {\n                        println!(\"❌ You cannot delete a person who is linked to parents or partners.\");\n                        return;\n                    }\n                    person.mark_as_deleted();\n                    println!(\"✅ '{}' is marked as deleted.\", person.name());\n                    self.save_to_json();\n                } else {\n                    println!(\"❌ ID not found.\");\n                }\n            },\n            Err(_) => println!(\"Exit\"),\n        }\n    }\n\n    pub fn count(&self) -> usize {\n        self.people.len()\n    }\n}\n\n//_______________________________________\npub mod partners {\n    use super::*;\n\n    fn add(people: &mut People, partners: &mut HashSet<i32>, id_person: i32) {\n        println!(\"Select Partner ID\");\n        let id_partner = input::get_int(\"ID: \");\n        if let Some(partner) = people.get_person_by_id_mut(id_partner) {\n            if partner.is_deleted() {\n                println!(\"❌ ID not found or the person is deleted.\");\n                return;\n            }\n            if partners.contains(&id_partner) {\n                println!(\"❌ This partner is already added.\");\n                return;\n            }\n\n            partners.insert(id_partner);\n            partner.partners_mut().insert(id_person);\n            if let Some(person) = people.get_person_by_id_mut(id_person) {\n                person.partners_mut().insert(id_partner);\n            }\n\n            println!(\"✅ Partner successfully added.\");\n            people.save_to_json();\n        } else {\n            println!(\"❌ ID not found or the person is deleted.\");\n        }\n    }\n\n    fn remove(people: &mut People, partners: &mut HashSet<i32>, id_person: i32) {\n        println!(\"Select Partner ID to Delete\");\n        let id = input::get_int(\"ID: \");\n        if !partners.contains(&id) {\n            println!(\"❌ ID not found.\");\n            return;\n        }\n        if let Some(partner) = people.get_person_by_id_mut(id) {\n            if !partner.children().is_empty() {\n                println!(\"❌ Cannot delete a partner who has children.\");\n                return;\n            }\n            partners.remove(&id);\n            partner.partners_mut().remove(&id_person);\n            \n            if let Some(person) = people.get_person_by_id_mut(id_person) {\n                person.partners_mut().remove(&id);\n            }\n            \n            println!(\"✅ Partner deleted\");\n            people.save_to_json();\n        } else {\n            println!(\"❌ Partner not found.\");\n        }\n    }\n\n    fn options(people: &mut People, partners: &mut HashSet<i32>, id_person: i32) {\n        println!(\"\\n1. Add partner | 2. Remove partner | 3. Exit\");\n        let option = input::get_int(\"\\nOption: \");\n        match option {\n            1 => add(people, partners, id_person),\n            2 => remove(people, partners, id_person),\n            3 => return,\n            _ => println!(\"❌ Invalid option.\"),\n        }\n    }\n\n    pub fn edit_partners(people: &mut People) {\n        people.print_people();\n        println!(\"\\nPerson ID to edit partners or a letter to exit.\");\n        let id_str = input::get_str(\"ID: \");\n        let id = match id_str.parse::<i32>() {\n            Ok(id) => id,\n            Err(_) => {\n                println!(\"Exit\");\n                return;\n            }\n        };\n\n        if let Some(person) = people.get_person_by_id(id) {\n            if person.is_deleted() {\n                println!(\"❌ ID not found or the person is deleted.\");\n                return;\n            }\n            println!(\"You selected '{}'\", person.name());\n            let partners = person.partners().clone();\n            if !partners.is_empty() {\n                println!(\"Partners:\");\n                for &id_p in partners.iter() {\n                    if let Some(partner) = people.get_person_by_id(id_p) {\n                        println!(\"ID: {} -> {}\", partner.id(), partner.name());\n                    }\n                }\n            } else {\n                println!(\"🚫 This person has no partners.\");\n            }\n            \n            let mut partners = partners;\n            options(people, &mut partners, id);\n            \n            if let Some(person) = people.get_person_by_id_mut(id) {\n                *person.partners_mut() = partners;\n            }\n        } else {\n            println!(\"❌ ID not found or the person is deleted.\");\n        }\n    }\n}\n\n//_______________________________________\npub struct Children {\n    id_parent: i32,\n    id_partner: i32,\n    id_child: i32,\n    children: HashMap<i32, Vec<i32>>,\n}\n\nimpl Children {\n    pub fn new() -> Self {\n        Self {\n            id_parent: 0,\n            id_partner: 0,\n            id_child: 0,\n            children: HashMap::new(),\n        }\n    }\n\n    fn select_partner(&self, people: &People, partners: &HashSet<i32>) -> Option<i32> {\n        println!(\"Partners:\");\n        for &id_p in partners {\n            if let Some(partner) = people.get_person_by_id(id_p) {\n                println!(\"ID: {} -> {}\", partner.id(), partner.name());\n            }\n        }\n\n        println!(\"Select the ID of the partner with whom you have the child.\");\n        let id_partner = input::get_int(\"Id: \");\n        if partners.contains(&id_partner) {\n            return Some(id_partner);\n        }\n\n        println!(\"❌ ID not found or the person is deleted.\");\n        None\n    }\n\n    fn update_child_parent(&mut self, people: &mut People) -> Option<i32> {\n        let id_child = input::get_int(\"Select Child ID: \");\n        if let Some(child) = people.get_person_by_id(id_child) {\n            if !child.parents().is_empty() {\n                println!(\"❌ This person already has parents.\");\n                return None;\n            }\n\n            if self.children.is_empty() {\n                self.children = HashMap::new();\n            }\n\n            let children_list = self.children.entry(self.id_partner).or_insert_with(Vec::new);\n            if !children_list.contains(&id_child) {\n                children_list.push(id_child);\n            }\n\n            if let Some(parent) = people.get_person_by_id_mut(self.id_parent) {\n                parent.children_mut().clear();\n                parent.children_mut().extend(self.children.clone());\n            }\n\n            if let Some(child) = people.get_person_by_id_mut(id_child) {\n                child.parents_mut().clear();\n                child.parents_mut().extend([self.id_parent, self.id_partner].iter().copied());\n            }\n\n            Some(id_child)\n        } else {\n            None\n        }\n    }\n\n    fn update_child_partner(&self, partner: &mut Person) {\n        let children_list = partner.children_mut().entry(self.id_parent).or_insert_with(Vec::new);\n        if !children_list.contains(&self.id_child) {\n            children_list.push(self.id_child);\n        }\n    }\n\n    fn add(&mut self, people: &mut People) {\n        let parent = match people.get_person_by_id(self.id_parent) {\n            Some(p) => p,\n            None => {\n                println!(\"❌ Parent not found.\");\n                return;\n            }\n        };\n    \n        let partners = parent.partners();\n        if partners.is_empty() {\n            println!(\"❌ This person does not have a partner with whom to have children.\");\n            return;\n        }\n    \n        let id_partner = match self.select_partner(people, &partners) {\n            Some(id) => id,\n            None => return,\n        };\n        \n        self.id_partner = id_partner;\n        let id_child = match self.update_child_parent(people) {\n            Some(id) => id,\n            None => {\n                println!(\"❌ Failed to update child.\");\n                return;\n            }\n        };\n    \n        let partner = match people.get_person_by_id_mut(id_partner) {\n            Some(p) => p,\n            None => {\n                println!(\"❌ Partner not found.\");\n                return;\n            }\n        };\n    \n        self.id_child = id_child;\n        self.update_child_partner(partner);\n    \n        println!(\"✅ Child successfully added.\");\n        people.save_to_json();\n    }\n\n    fn remove_and_update(&mut self, people: &mut People, id_parent: i32, id_partner: i32) {\n        if let Some(parent) = people.get_person_by_id_mut(id_parent) {\n            if let Some(children_with_partner) = parent.children_mut().get_mut(&id_partner) {\n                children_with_partner.retain(|&child| child != self.id_child);\n                if children_with_partner.is_empty() {\n                    parent.children_mut().remove(&id_partner);\n                }\n            }\n        }\n\n        if let Some(child) = people.get_person_by_id_mut(self.id_child) {\n            child.parents_mut().retain(|&parent_id| parent_id != id_parent);\n        }\n\n        println!(\"✅ Child deleted in parent: (ID: {})\", id_parent);\n        people.save_to_json();\n    }\n\n    fn remove(&mut self, people: &mut People) {\n        self.id_child = input::get_int(\"Select Child ID to Delete: \");\n        if let Some(child) = people.get_person_by_id(self.id_child) {\n            if child.parents().len() != 2 {\n                println!(\"❌ Child does not have two parents.\");\n                return;\n            }\n\n            let parent_ids: Vec<i32> = child.parents().iter().cloned().collect();\n            let (id_p1, id_p2) = (parent_ids[0], parent_ids[1]);\n            self.remove_and_update(people, id_p1, id_p2);\n            self.remove_and_update(people, id_p2, id_p1);\n        }\n    }\n\n    fn options(&mut self, people: &mut People) {\n        println!(\"\\n1. Add child | 2. Remove child | 3. Exit\");\n        let option = input::get_int(\"Option: \");\n\n        match option {\n            1 => self.add(people),\n            2 => self.remove(people),\n            3 => return,\n            _ => println!(\"❌ Invalid option.\"),\n        }\n    }\n\n    pub fn edit_children(&mut self, people: &mut People) {\n        people.print_people();\n        println!(\"\\nPerson ID to edit Children or a letter to exit.\");\n        let id_str = input::get_str(\"id: \");\n        if let Ok(id) = id_str.parse::<i32>() {\n            if let Some(parent) = people.get_person_by_id(id) {\n                if parent.is_deleted() {\n                    println!(\"❌ ID not found or the person is deleted.\");\n                    return;\n                }\n    \n                println!(\"You selected '{}'\", parent.name());\n                let children = parent.children().clone();\n                if !children.is_empty() {\n                    println!(\"Children:\");\n                    for (partner_id, child_ids) in children.iter() {\n                        if let Some(partner) = people.get_person_by_id(*partner_id) {\n                            let partner_name = partner.name();\n                            println!(\"With ID: {} -> '{}':\", partner_id, partner_name);\n                            for &child_id in child_ids.iter() {\n                                if let Some(child) = people.get_person_by_id(child_id) {\n                                    println!(\"    ID: {} -> '{}'\", child_id, child.name());\n                                }\n                            }\n                        }\n                    }\n                } else {\n                    println!(\"🚫 This person has no children.\");\n                }\n    \n                self.id_parent = id;\n                self.children = children;\n                self.options(people);\n            } else {\n                println!(\"❌ ID not found or the person is deleted.\");\n            }\n        } else {\n            println!(\"Exit\");\n        }\n    }\n}\n\n//_______________________________________\npub mod tree {\n    use super::*;\n    use std::collections::HashSet;\n\n    struct FilteredGrandparents<'a> {\n        grandparents: Vec<&'a Person>,\n        no_partner: Vec<&'a Person>,\n    }\n\n    fn filtered_grandparents(people: &People) -> FilteredGrandparents {\n        let mut grandparents = Vec::new();\n        let mut no_partner = Vec::new();\n\n        for person in people.get_people().iter().filter(|p| !p.is_deleted() && p.name() != \"unknown\") {\n            if person.parents().is_empty() {\n                if person.partners().is_empty() {\n                    no_partner.push(person);\n                } else {\n                    let has_grandparent_partner = person.partners().iter().any(|&partner_id| {\n                        people.get_person_by_id(partner_id)\n                        .map_or(false, |partner| grandparents.iter().any(|gp: &&Person| gp.id() == partner.id()))\n                    });\n\n                    if !has_grandparent_partner {\n                        grandparents.push(person);\n                    }\n                }\n            }\n        }\n\n        FilteredGrandparents { grandparents, no_partner }\n    }\n\n    fn print_child(people: &People, children: &[i32], prefix: &str, is_last: bool, is_root: bool) {\n        for (i, &child_id) in children.iter().enumerate() {\n            let is_last_child = i == children.len() - 1;\n            let new_prefix = if is_root {\n                prefix.to_string()\n            } else {\n                let prefix_chars: Vec<char> = prefix.chars().collect();\n                let new_prefix_chars = if prefix_chars.len() > 4 {\n                    prefix_chars[0..prefix_chars.len() - 4].to_vec()\n                } else {\n                    Vec::new()\n                };\n                format!(\"{}{}\", new_prefix_chars.into_iter().collect::<String>(), if is_last { \"    \" } else { \"│   \" })\n            };\n\n            print_family(\n                people,\n                child_id,\n                &format!(\"{}{}\", new_prefix, if is_last_child { \"└── \" } else { \"├── \" }),\n                is_last_child,\n                false,\n            );\n        }\n    }\n\n    fn print_parents(people: &People, id: i32, partners: &HashSet<i32>, prefix: &str, is_last: bool, is_root: bool) {\n        for &partner_id in partners {\n            if let Some(partner) = people.get_person_by_id(partner_id) {\n                println!(\"{}💑 With: {} (ID: {})\", prefix, partner.name(), partner.id());\n                if let Some(children) = partner.children().get(&id) {\n                    if !children.is_empty() {\n                        print_child(people, children, prefix, is_last, is_root);\n                    } else {\n                        println!(\"{}└── 🚫 Without children\", prefix);\n                    }\n                }\n            }\n        }\n    }\n\n    fn print_family(people: &People, id: i32, prefix: &str, is_last: bool, is_root: bool) {\n        if let Some(person) = people.get_person_by_id(id) {\n            println!(\"{}🙂 {} (ID: {})\", prefix, person.name(), person.id());\n    \n            if !person.partners().is_empty() {\n                let new_prefix = if !is_root {\n                    let prefix_chars: Vec<char> = prefix.chars().collect();\n                    let new_prefix_chars = if prefix_chars.len() > 4 {\n                        prefix_chars[0..prefix_chars.len() - 4].to_vec()\n                    } else {\n                        Vec::new()\n                    };\n                    let new_prefix = new_prefix_chars.into_iter().collect::<String>();\n                    format!(\"{}{}\", new_prefix, if is_last { \"    \" } else { \"│   \" })\n                } else {\n                    prefix.to_string()\n                };\n    \n                print_parents(people, id, person.partners(), &new_prefix, is_last, is_root);\n                if !is_last {\n                    println!(\"{}\", new_prefix);\n                }\n            }\n        }\n    }\n\n    pub fn print_tree(people: &People) {\n        let FilteredGrandparents { grandparents, no_partner } = filtered_grandparents(people);\n\n        if grandparents.is_empty() && no_partner.is_empty() {\n            println!(\"⚠️ No users are registered.\");\n            return;\n        }\n\n        if !no_partner.is_empty() {\n            println!(\"__________\");\n            println!(\"Parents unknown, without descendants and without a partner:\");\n            for p in &no_partner {\n                println!(\"😐 {} (ID: {})\", p.name(), p.id());\n            }\n        }\n\n        println!();\n        for (i, grandparent) in grandparents.iter().enumerate() {\n            println!(\"__________\");\n            println!(\"Family #{}\", i + 1);\n            print_family(people, grandparent.id(), \"\", false, true);\n        }\n    }\n}\n\n//_______________________________________\nconst MENU: &str = r\"\n---------------------------------------------\n| 1. Add person    | 4. Edit children       |\n| 2. Remove person | 5. Print tree          |\n| 3. Edit partners | 6. Exit                |\n---------------------------------------------\";\n\nstruct Program {\n    people: People,\n}\n\nimpl Program {\n    fn new() -> Self {\n        Program {\n            people: People::new(None),\n        }\n    }\n\n    fn run(&mut self) {\n        loop {\n            println!(\"{}\", MENU);\n            let option = input::get_int(\"\\nOption: \");\n            match option {\n                1 => self.people.add_person(),\n                2 => self.people.remove_person(),\n                3 => partners::edit_partners(&mut self.people),\n                4 => Children::new().edit_children(&mut self.people),\n                5 => tree::print_tree(&self.people),\n                6 => {\n                    println!(\"Bye\");\n                    return;\n                },\n                _ => println!(\"❌ Invalid option.\"),\n            }\n        }\n    }\n}\n\nfn main() {\n    let mut program = Program::new();\n    program.run();\n}\n"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/sql/Nicojsuarez2.sql",
    "content": "# #34 ÁRBOL GENEALÓGICO DE LA CASA DEL DRAGÓN\n> #### Dificultad: Difícil | Publicación: 19/08/24 | Corrección: 26/08/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * ¡La Casa del Dragón ha finalizado y no volverá hasta 2026! \n * ¿Alguien se entera de todas las relaciones de parentesco\n * entre personajes que aparecen en la saga?\n * Desarrolla un árbol genealógico para relacionarlos (o invéntalo).\n * Requisitos:\n * 1. Estará formado por personas con las siguientes propiedades:\n *    - Identificador único (obligatorio)\n *    - Nombre (obligatorio)\n *    - Pareja (opcional)\n *    - Hijos (opcional)\n * 2. Una persona sólo puede tener una pareja (para simplificarlo).\n * 3. Las relaciones deben validarse dentro de lo posible.\n *    Ejemplo: Un hijo no puede tener tres padres.\n * Acciones:\n * 1. Crea un programa que permita crear y modificar el árbol.\n *    - Añadir y eliminar personas\n *    - Modificar pareja e hijos\n * 2. Podrás imprimir el árbol (de la manera que consideres).\n * \n * NOTA: Ten en cuenta que la complejidad puede ser alta si\n * se implementan todas las posibles relaciones. Intenta marcar\n * tus propias reglas y límites para que te resulte asumible.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/typescript/hozlucas28.ts",
    "content": "import type {UUID} from 'crypto'\nimport {randomUUID} from 'crypto'\n\n/* -------------------------------------------------------------------------- */\n/*                                    TYPES                                   */\n/* -------------------------------------------------------------------------- */\n\ntype Name = `${Capitalize<string>} ${Capitalize<string>}`\n\ntype FamilyStatus = Lowercase<'father' | 'mother'>\n\ninterface PrettifiedPerson {\n    name: string\n    children?: string\n    familyStatus?: FamilyStatus\n    father?: Name\n    mother?: Name\n    partner?: Name\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                   ERRORS                                   */\n/* -------------------------------------------------------------------------- */\n\nclass PersonNotFound extends Error {\n    public constructor(UUID: UUID) {\n        super(`Person with ${UUID} UUID not found`)\n        this.name = 'PersonNotFound'\n    }\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                   CLASSES                                  */\n/* -------------------------------------------------------------------------- */\n\n/* --------------------------------- Person --------------------------------- */\n\ninterface IPerson {\n    getName: () => Name\n    getUUID: () => UUID\n    getChildren: () => IPerson[] | undefined\n    getPartner: () => IPerson | undefined\n    getFamilyStatus: () => FamilyStatus | undefined\n    getFather: () => IPerson | undefined\n    getMother: () => IPerson | undefined\n    setPartner: (partner: IPerson) => void\n    addChildren: (...children: IPerson[]) => void\n    removeChildren: (...children: UUID[]) => void\n}\n\ninterface PersonConstructor {\n    readonly name: Name\n    readonly uuid: UUID\n    children?: IPerson[]\n    partner?: IPerson\n    readonly familyStatus?: FamilyStatus\n    readonly father?: IPerson\n    readonly mother?: IPerson\n}\n\nclass Person implements IPerson {\n    private readonly name: Name\n    private readonly uuid: UUID\n    private children?: IPerson[]\n    private partner?: IPerson\n    private readonly familyStatus?: FamilyStatus\n    private readonly father?: IPerson\n    private readonly mother?: IPerson\n\n    public constructor({\n        name,\n        uuid,\n        children,\n        partner,\n        familyStatus,\n        father,\n        mother,\n    }: PersonConstructor) {\n        partner && partner.setPartner(this)\n        father && father.addChildren(this)\n        mother && mother.addChildren(this)\n\n        this.name = name\n        this.uuid = uuid\n        this.children = children\n        this.partner = partner\n        this.familyStatus = familyStatus\n        this.father = father\n        this.mother = mother\n    }\n\n    public getName(): Name {\n        return this.name\n    }\n\n    public getUUID(): UUID {\n        return this.uuid\n    }\n\n    public getChildren(): IPerson[] | undefined {\n        return this.children\n    }\n\n    public getPartner(): IPerson | undefined {\n        return this.partner\n    }\n\n    public getFamilyStatus(): FamilyStatus | undefined {\n        return this.familyStatus\n    }\n\n    public getFather(): IPerson | undefined {\n        return this.father\n    }\n\n    public getMother(): IPerson | undefined {\n        return this.mother\n    }\n\n    public setPartner(partner: IPerson): void {\n        this.partner = partner\n    }\n\n    public addChildren(...children: IPerson[]): void {\n        this.children?.push(...children) ?? (this.children = [...children])\n    }\n\n    public removeChildren(...children: UUID[]): void {\n        if (!this.children) return\n\n        for (let i = 0; i < children.length; i++) {\n            const uuid: UUID = children[i]\n            const sonIndex: number = this.children.findIndex(\n                (son) => uuid === son.getUUID()\n            )\n\n            if (sonIndex < 0) throw new PersonNotFound(uuid)\n            this.children.splice(sonIndex, 1)\n        }\n    }\n}\n\n/* ------------------------------- FamilyTree ------------------------------- */\n\ninterface IFamilyTree {\n    getPerson: (uuid: UUID) => IPerson\n    getPeople: () => IPerson[] | undefined\n    addPeople: (...people: IPerson[]) => void\n    removePeople: (...people: UUID[]) => void\n    toPrettifiedPeople: () => PrettifiedPerson[]\n}\n\ninterface FamilyTreeConstructor {\n    readonly people?: IPerson[]\n}\n\nclass FamilyTree implements IFamilyTree {\n    private people?: IPerson[]\n\n    public constructor({people}: FamilyTreeConstructor = {}) {\n        this.people = people\n    }\n\n    public getPerson(uuid: UUID): IPerson {\n        const people: IPerson[] | undefined = this.people\n        const person: IPerson | undefined = people?.find(\n            (person) => person.getUUID() === uuid\n        )\n\n        if (!person) throw new PersonNotFound(uuid)\n\n        return person\n    }\n\n    public getPeople(): IPerson[] | undefined {\n        return this.people\n    }\n\n    public addPeople(...people: IPerson[]): void {\n        this.people?.push(...people) ?? (this.people = [...people])\n    }\n\n    public removePeople(...people: UUID[]): void {\n        if (!this.people) return\n\n        for (let i = 0; i < people.length; i++) {\n            const uuid: UUID = people[i]\n            const personIndex: number = this.people.findIndex(\n                (person) => uuid === person.getUUID()\n            )\n\n            if (personIndex < 0) throw new PersonNotFound(uuid)\n            this.people.splice(personIndex, 1)\n        }\n    }\n\n    public toPrettifiedPeople(): PrettifiedPerson[] {\n        const people: IPerson[] | undefined = this.people\n\n        let prettifiedPeople: PrettifiedPerson[] = []\n        if (!people) return prettifiedPeople\n\n        for (const person of people) {\n            const name: Name = person.getName()\n            const familyStatus: FamilyStatus | undefined =\n                person.getFamilyStatus()\n            const father: IPerson | undefined = person.getFather()\n            const mother: IPerson | undefined = person.getMother()\n            const partner: IPerson | undefined = person.getPartner()\n\n            const prettifiedPerson: PrettifiedPerson = {\n                name,\n                children: undefined,\n                familyStatus,\n                father: father ? father.getName() : undefined,\n                mother: mother ? mother.getName() : undefined,\n                partner: partner ? partner.getName() : undefined,\n            } satisfies PrettifiedPerson\n\n            const children: IPerson[] | undefined = person.getChildren()\n            if (children) {\n                const sons: string[] = []\n                for (const son of children) {\n                    sons.push(son.getName())\n                }\n\n                const formatter: Intl.ListFormat = new Intl.ListFormat('en', {\n                    style: 'long',\n                    type: 'conjunction',\n                })\n\n                prettifiedPerson.children = formatter.format(sons)\n            }\n\n            prettifiedPeople.push(prettifiedPerson)\n        }\n\n        return prettifiedPeople\n    }\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\n/**\n * House of Dragon family tree from the first row to the third one.\n *\n * > House of Dragon official family tree: https://www.hbo.com/house-of-the-dragon/character-guide\n */\n\nconsole.log(\n    'House of Dragon family tree from the first row to the third one...\\n'\n)\n\nconst jaehaerysTargaryen: Person = new Person({\n    name: 'Jaehaerys Targaryen',\n    uuid: randomUUID(),\n    familyStatus: 'father',\n})\n\nconst alysanneTargaryen: Person = new Person({\n    name: 'Alysanne Targaryen',\n    uuid: randomUUID(),\n    partner: jaehaerysTargaryen,\n    familyStatus: 'mother',\n})\n\nconst jocelynBaratheon: Person = new Person({\n    name: 'Jocelyn Baratheon',\n    uuid: randomUUID(),\n    familyStatus: 'mother',\n})\n\nconst aemonTargaryen: Person = new Person({\n    name: 'Aemon Targaryen',\n    uuid: randomUUID(),\n    partner: jocelynBaratheon,\n    familyStatus: 'father',\n    father: jaehaerysTargaryen,\n    mother: alysanneTargaryen,\n})\n\nconst baelonTargaryen: Person = new Person({\n    name: 'Baelon Targaryen',\n    uuid: randomUUID(),\n    familyStatus: 'mother',\n    father: jaehaerysTargaryen,\n    mother: alysanneTargaryen,\n})\n\nconst alyssaTargaryen: Person = new Person({\n    name: 'Alyssa Targaryen',\n    uuid: randomUUID(),\n    partner: baelonTargaryen,\n    familyStatus: 'mother',\n    father: jaehaerysTargaryen,\n    mother: alysanneTargaryen,\n})\n\nconst lyonelStrong: Person = new Person({\n    name: 'Lyonel Strong',\n    uuid: randomUUID(),\n    familyStatus: 'father',\n})\n\nconst vaemondValaryon: Person = new Person({\n    name: 'Vaemond Valaryon',\n    uuid: randomUUID(),\n})\n\nconst corlysVelaryon: Person = new Person({\n    name: 'Corlys Velaryon',\n    uuid: randomUUID(),\n    familyStatus: 'father',\n})\n\nconst rhaenysTargaryen: Person = new Person({\n    name: 'Rhaenys Targaryen',\n    uuid: randomUUID(),\n    familyStatus: 'mother',\n    partner: corlysVelaryon,\n    father: aemonTargaryen,\n    mother: jocelynBaratheon,\n})\n\nconst rheaRoyce: Person = new Person({\n    name: 'Rhea Royce',\n    uuid: randomUUID(),\n    familyStatus: 'mother',\n})\n\nconst daemonTargaryen: Person = new Person({\n    name: 'Daemon Targaryen',\n    uuid: randomUUID(),\n    familyStatus: 'father',\n    partner: rheaRoyce,\n    father: baelonTargaryen,\n    mother: alyssaTargaryen,\n})\n\nconst aemmaArryn: Person = new Person({\n    name: 'Aemma Arryn',\n    uuid: randomUUID(),\n    familyStatus: 'mother',\n})\n\nconst viserysTargaryen: Person = new Person({\n    name: 'Viserys Targaryen',\n    uuid: randomUUID(),\n    familyStatus: 'father',\n    partner: aemmaArryn,\n    father: baelonTargaryen,\n    mother: alyssaTargaryen,\n})\n\nconst ottoHightower: Person = new Person({\n    name: 'Otto Hightower',\n    uuid: randomUUID(),\n    familyStatus: 'father',\n})\n\nconst hobertHightower: Person = new Person({\n    name: 'Hobert Hightower',\n    uuid: randomUUID(),\n})\n\nconst familyTree: FamilyTree = new FamilyTree()\n\nfamilyTree.addPeople(\n    jaehaerysTargaryen,\n    alysanneTargaryen,\n    jocelynBaratheon,\n    aemonTargaryen,\n    baelonTargaryen,\n    alyssaTargaryen,\n    lyonelStrong,\n    vaemondValaryon,\n    corlysVelaryon,\n    rhaenysTargaryen,\n    rheaRoyce,\n    daemonTargaryen,\n    aemmaArryn,\n    viserysTargaryen,\n    ottoHightower,\n    hobertHightower\n)\n\nconsole.table(familyTree.toPrettifiedPeople())\n\nconsole.log(\n    '\\n> House of Dragon official family tree: https://www.hbo.com/house-of-the-dragon/character-guide'\n)\n"
  },
  {
    "path": "Roadmap/34 - ÁRBOL GENEALÓGICO LA CASA DEL DRAGÓN/vb.net/kenysdev.vb",
    "content": "' ╔══════════════════════════════════════╗\n' ║ Autor:  Kenys Alvarado               ║\n' ║ GitHub: https://github.com/Kenysdev  ║\n' ║ 2024 -  VB.NET                       ║\n' ╚══════════════════════════════════════╝\n'-----------------------------------------------------\n'* 34 ÁRBOL GENEALÓGICO DE LA CASA DEL DRAGÓN\n'-----------------------------------------------------\n'* ¡La Casa del Dragón ha finalizado y no volverá hasta 2026! \n' * ¿Alguien se entera de todas las relaciones de parentesco\n' * entre personajes que aparecen en la saga?\n' * Desarrolla un árbol genealógico para relacionarlos (o invéntalo).\n' * Requisitos:\n' * 1. Estará formado por personas con las siguientes propiedades\n' *    - Identificador único (obligatorio)\n' *    - Nombre (obligatorio)\n' *    - Pareja (opcional)\n' *    - Hijos (opcional)\n' * 2. Una persona sólo puede tener una pareja (para simplificarlo).\n' * 3. Las relaciones deben validarse dentro de lo posible.\n' *    Ejemplo: Un hijo no puede tener tres padres.\n' * Acciones:\n' * 1. Crea un programa que permita crear y modificar el árbol.\n' *    - Añadir y eliminar personas\n' *    - Modificar pareja e hijos\n' * 2. Podrás imprimir el árbol (de la manera que consideres).\n' * \n' * NOTA: Ten en cuenta que la complejidad puede ser alta si\n' * se implementan todas las posibles relaciones. Intenta marcar\n' * tus propias reglas y límites para que te resulte asumible.\n\n'_______\n' NOTE Here Is the 'people.json' file with the data if you want to test it:\n'      https://pastebin.com/29kWWgPU\n'      Just paste it into the base folder.\n\nImports System.IO\nImports System.Text\nImports System.Text.Json\n\n'___________________________________________________\nPublic Class Person\n    Public Property Id As Integer\n    Public Property Name As String\n    Public Property Parents As New List(Of Integer)\n    Public Property Partners As New List(Of Integer)\n    Public Property Children As New Dictionary(Of Integer, List(Of Integer))\n    Public Property Deleted As Boolean\n\n    Public Sub New(id As Integer, name As String)\n        Me.Id = id\n        Me.Name = name\n    End Sub\n\n    Public Function ToDict() As Dictionary(Of String, Object)\n        Return New Dictionary(Of String, Object) From {\n            {\"id\", Id},\n            {\"name\", Name},\n            {\"parents\", Parents},\n            {\"partners\", Partners},\n            {\"children\", Children},\n            {\"deleted\", Deleted}\n        }\n    End Function\n\n    Public Shared Function FromDict(data As Dictionary(Of String, Object)) As Person\n        Dim person As New Person(CInt(data(\"id\")), CStr(data(\"name\")))\n\n        If data.ContainsKey(\"parents\") Then\n            person.Parents = DirectCast(data(\"parents\"), List(Of Integer))\n        End If\n\n        If data.ContainsKey(\"partners\") Then\n            person.Partners = DirectCast(data(\"partners\"), List(Of Integer))\n        End If\n\n        If data.ContainsKey(\"children\") Then\n            person.Children = JsonSerializer.Deserialize(Of Dictionary(Of Integer, List(Of Integer)))(\n                DirectCast(data(\"children\"), JsonElement).GetRawText()\n            )\n        End If\n\n        If data.ContainsKey(\"deleted\") Then\n            person.Deleted = CBool(data(\"deleted\"))\n        End If\n\n        Return person\n    End Function\n\n    Public Overrides Function ToString() As String\n        Return $\"Person(id={Id}, name='{Name}')\"\n    End Function\nEnd Class\n\n'___________________________________________________\nPublic Module Input\n    Public Function GetStr(msg As String) As String\n        Do\n            Console.Write(msg)\n            Dim txt As String = Console.ReadLine()\n            If Not String.IsNullOrEmpty(txt) Then\n                Return txt\n            End If\n\n            Console.WriteLine(vbCrLf & \"❌ This field cannot be empty.\")\n        Loop\n    End Function\n\n    Public Function GetInt(msg As String) As Integer\n        Do\n            Dim txt As String = GetStr(msg)\n            Dim result As Integer\n            If Integer.TryParse(txt, result) Then\n                Return result\n            End If\n\n            Console.WriteLine(vbCrLf & \"❌ Enter an integer.\")\n        Loop\n    End Function\nEnd Module\n\n'___________________________________________________\nPublic Class People\n    Private _people As New List(Of Person)()\n    Private ReadOnly _filename As String\n    Private Shared ReadOnly _jsonOptions As New JsonSerializerOptions(JsonSerializerDefaults.Web) With {.WriteIndented = True}\n\n    Public Sub New(Optional filename As String = \"people.json\")\n        _filename = filename\n        LoadFromJson()\n    End Sub\n\n    Public Function GetPeople() As IReadOnlyList(Of Person)\n        Return _people.AsReadOnly()\n    End Function\n\n    Public Sub LoadFromJson()\n        Try\n            Dim jsonString As String = File.ReadAllText(_filename)\n            _people = JsonSerializer.Deserialize(Of List(Of Person))(jsonString, _jsonOptions)\n            If _people Is Nothing Then _people = New List(Of Person)()\n            Console.WriteLine($\"✅ The file '{_filename}' has been successfully loaded.\")\n        Catch ex As Exception\n            Console.WriteLine($\"⚠️ The file '{_filename}' not found. Starting with an empty list.\")\n            _people = New List(Of Person) From {New Person(0, \"unknown\")}\n        End Try\n    End Sub\n\n    Public Sub SaveToJson()\n        Try\n            Dim jsonString As String = JsonSerializer.Serialize(_people, _jsonOptions)\n            File.WriteAllText(_filename, jsonString)\n            Console.WriteLine($\"✅ Data saved successfully to {_filename}\")\n        Catch e As Exception\n            Console.WriteLine($\"❌ An error occurred while saving to '{_filename}': {e.Message}. Data may not have been saved.\")\n        End Try\n    End Sub\n\n    Public Sub PrintPeople()\n        Console.WriteLine(New String(\"_\"c, 32))\n        Console.WriteLine($\"|{\"id\",4}|{\"Name\",-25}|\")\n        Console.WriteLine(New String(\"_\"c, 32))\n        For Each person In _people.Where(Function(p) Not p.Deleted)\n            Console.WriteLine($\"|{person.Id,4}|{person.Name,-25}|\")\n        Next\n        Console.WriteLine(New String(\"_\"c, 32))\n    End Sub\n\n    Public Function GetPersonById(id As Integer) As Person\n        Dim person = _people.FirstOrDefault(Function(p) p.Id = id)\n        If person Is Nothing Then\n            Console.WriteLine(\"❌ ID not found.\")\n        End If\n        Return person\n    End Function\n\n    Public Sub AddPerson()\n        Console.WriteLine(\"Add Person or 'x' to Exit\")\n        Dim name As String = Input.GetStr(\"Name: \")\n        If name.Equals(\"x\", StringComparison.CurrentCultureIgnoreCase) Then\n            Console.WriteLine(\"Exit\")\n            Return\n        End If\n\n        Dim newId As Integer = If(_people.Count > 0, _people.Max(Function(p) p.Id) + 1, 0)\n        Dim newPerson As New Person(newId, name)\n        _people.Add(newPerson)\n        Console.WriteLine($\"✅ Added: {newPerson}\")\n        SaveToJson()\n    End Sub\n\n    Public Sub RemovePerson()\n        PrintPeople()\n        Console.WriteLine(vbCrLf & \"Person ID to mark as deleted or a letter to exit.\")\n        Dim idStr As String = Input.GetStr(\"ID: \")\n        Dim id As Integer\n        If Not Integer.TryParse(idStr, id) Then\n            Console.WriteLine(\"Exit\")\n            Return\n        End If\n\n        Dim person = GetPersonById(id)\n        If person Is Nothing Then Return\n\n        If person.Partners.Count <> 0 OrElse person.Parents.Count <> 0 Then\n            Console.WriteLine(\"❌ You cannot delete a person who is linked to parents or partners.\")\n            Return\n        End If\n\n        person.Deleted = True\n        Console.WriteLine($\"✅ '{person.Name}' is marked as deleted.\")\n        SaveToJson()\n    End Sub\n\n    Public ReadOnly Property Count As Integer\n        Get\n            Return _people.Count\n        End Get\n    End Property\nEnd Class\n\n'___________________________________________________\nPublic Class Partners\n    Inherits People\n\n    Private Sub Add(partners As List(Of Integer), idPerson As Integer)\n        Console.WriteLine(\"Select Partner ID\")\n        Dim idPartner As Integer = Input.GetInt(\"ID: \")\n        Dim partner = GetPersonById(idPartner)\n        If partner Is Nothing OrElse partner.Deleted Then\n            Console.WriteLine(\"❌ ID not found or the person is deleted.\")\n            Return\n        End If\n\n        If partners.Contains(idPartner) Then\n            Console.WriteLine(\"❌ This partner is already added.\")\n            Return\n        End If\n\n        partners.Add(idPartner)\n        partner.Partners.Add(idPerson)\n\n        Console.WriteLine(\"✅ Partner successfully added.\")\n        SaveToJson()\n    End Sub\n\n    Private Sub Remove(partners As List(Of Integer), idPerson As Integer)\n        Console.WriteLine(\"Select Partner ID to Delete\")\n        Dim id As Integer = Input.GetInt(\"ID: \")\n        If Not partners.Contains(id) Then\n            Console.WriteLine(\"❌ ID not found.\")\n            Return\n        End If\n\n        Dim partner = GetPersonById(id)\n        If partner Is Nothing Then\n            Console.WriteLine(\"❌ Partner not found.\")\n            Return\n        End If\n\n        If partner.Children.Count <> 0 Then\n            Console.WriteLine(\"❌ Cannot delete a partner who has children.\")\n            Return\n        End If\n\n        partners.Remove(id)\n        partner.Partners.Remove(idPerson)\n\n        Console.WriteLine(\"✅ Partner deleted\")\n        SaveToJson()\n    End Sub\n\n    Private Sub Options(partners As List(Of Integer), idPerson As Integer)\n        Console.WriteLine(vbCrLf & \"1. Add partner | 2. Remove partner | 3. Exit\")\n        Dim option_ As Integer = Input.GetInt(vbCrLf & \"Option: \")\n\n        Select Case option_\n            Case 1\n                Add(partners, idPerson)\n            Case 2\n                Remove(partners, idPerson)\n            Case 3\n                Return\n            Case Else\n                Console.WriteLine(\"❌ Invalid option.\")\n        End Select\n    End Sub\n\n    Public Sub EditPartners()\n        PrintPeople()\n        Console.WriteLine(vbCrLf & \"Person ID to edit partners or a letter to exit.\")\n        Dim idStr As String = Input.GetStr(\"ID: \")\n        Dim id As Integer\n        If Not Integer.TryParse(idStr, id) Then\n            Console.WriteLine(\"Exit\")\n            Return\n        End If\n\n        Dim person = GetPersonById(id)\n        If person Is Nothing OrElse person.Deleted Then\n            Console.WriteLine(\"❌ ID not found or the person is deleted.\")\n            Return\n        End If\n\n        Console.WriteLine($\"You selected '{person.Name}'\")\n        Dim partners = person.Partners\n\n        If partners.Count <> 0 Then\n            Console.WriteLine(\"Partners:\")\n            For Each idP In partners\n                Dim partner = GetPersonById(idP)\n                If partner IsNot Nothing Then\n                    Console.WriteLine($\"ID: {partner.Id} -> {partner.Name}\")\n                End If\n            Next\n        Else\n            Console.WriteLine(\"🚫 This person has no partners.\")\n        End If\n\n        Options(partners, id)\n    End Sub\nEnd Class\n\n'___________________________________________________\nPublic Class Children\n    Inherits Partners\n\n    Private _idParent As Integer\n    Private _children As Dictionary(Of Integer, List(Of Integer))\n    Private _idChild As Integer\n    Private _idPartner As Integer\n\n    Private Function SelectPartner(partners As List(Of Integer)) As Integer?\n        Console.WriteLine(\"Partners:\")\n        For Each idP In partners\n            Dim partnerPerson = GetPersonById(idP)\n            If partnerPerson IsNot Nothing Then\n                Console.WriteLine($\"ID: {partnerPerson.Id} -> {partnerPerson.Name}\")\n            End If\n        Next\n\n        Console.WriteLine(\"Select the ID of the partner with whom you have the child.\")\n        Dim idPartner As Integer = Input.GetInt(\"ID: \")\n        Dim partner = GetPersonById(idPartner)\n        If Not partners.Contains(idPartner) OrElse partner Is Nothing OrElse partner.Deleted Then\n            Console.WriteLine(\"❌ ID not found or the person is deleted.\")\n            Return Nothing\n        End If\n\n        Return idPartner\n    End Function\n\n    Private Function UpdateChildParent() As Integer?\n        Dim idPartner As Integer = _idPartner\n        Console.WriteLine(\"Select Child ID\")\n        Dim idChild As Integer = Input.GetInt(\"ID: \")\n        Dim child = GetPersonById(idChild)\n        If child Is Nothing Then\n            Return Nothing\n        End If\n\n        If child.Parents.Count <> 0 Then\n            Console.WriteLine(\"❌ This person already has parents.\")\n            Return Nothing\n        End If\n\n        If _children Is Nothing Then\n            _children = New Dictionary(Of Integer, List(Of Integer))()\n        End If\n\n        Dim childrenList As List(Of Integer) = Nothing\n        If _children.TryGetValue(idPartner, childrenList) Then\n            If childrenList IsNot Nothing AndAlso Not childrenList.Contains(idChild) Then\n                childrenList.Add(idChild)\n            End If\n        Else\n            _children(idPartner) = New List(Of Integer) From {idChild}\n        End If\n\n        Dim parent = GetPersonById(_idParent)\n        If parent IsNot Nothing Then\n            parent.Children = _children\n        End If\n\n        child.Parents = New List(Of Integer) From {_idParent, idPartner}\n\n        Return idChild\n    End Function\n\n    Private Sub UpdateChildPartner(partner As Person)\n        Dim childrenList As List(Of Integer) = Nothing\n        If partner.Children.TryGetValue(_idParent, childrenList) Then\n            If childrenList IsNot Nothing AndAlso Not childrenList.Contains(_idChild) Then\n                childrenList.Add(_idChild)\n            End If\n        Else\n            partner.Children(_idParent) = New List(Of Integer) From {_idChild}\n        End If\n    End Sub\n\n    Private Sub Add()\n        Dim parent = GetPersonById(_idParent)\n        If parent Is Nothing Then\n            Console.WriteLine(\"❌ Parent not found.\")\n            Return\n        End If\n\n        Dim partners = parent.Partners\n        If partners.Count = 0 Then\n            Console.WriteLine(\"❌ This person does not have a partner with whom to have children.\")\n            Return\n        End If\n\n        Dim idPartner = SelectPartner(partners)\n        If Not idPartner.HasValue Then\n            Return\n        End If\n\n        Dim partner = GetPersonById(idPartner.Value)\n        If partner Is Nothing Then\n            Console.WriteLine(\"❌ Partner not found.\")\n            Return\n        End If\n\n        _idPartner = idPartner.Value\n        Dim idChild = UpdateChildParent()\n        If Not idChild.HasValue Then\n            Return\n        End If\n\n        _idChild = idChild.Value\n        UpdateChildPartner(partner)\n\n        Console.WriteLine(\"✅ Child successfully added.\")\n        SaveToJson()\n    End Sub\n\n    Private Sub RemoveAndUpdate(idParent As Integer, idPartner As Integer)\n        Dim parent = GetPersonById(idParent)\n        If parent Is Nothing Then\n            Console.WriteLine(\"❌ Parent not found.\")\n            Return\n        End If\n\n        Dim childrenWithPartner As List(Of Integer) = Nothing\n        If parent.Children.TryGetValue(idPartner, childrenWithPartner) Then\n            If childrenWithPartner IsNot Nothing Then\n                childrenWithPartner.Remove(_idChild)\n                If childrenWithPartner.Count = 0 Then\n                    parent.Children.Remove(idPartner)\n                Else\n                    parent.Children(idPartner) = childrenWithPartner\n                End If\n            End If\n        End If\n\n        Dim child = GetPersonById(_idChild)\n        If child IsNot Nothing Then\n            child.Parents.Remove(idParent)\n        End If\n\n        Console.WriteLine($\"✅ Child deleted in parent: (ID: {idParent})\")\n        SaveToJson()\n    End Sub\n\n    Private Sub Remove()\n        Console.WriteLine(\"Select Child ID to Delete\")\n        _idChild = Input.GetInt(\"ID: \")\n        Dim child = GetPersonById(_idChild)\n        If child Is Nothing Then\n            Return\n        End If\n\n        Dim parents = child.Parents\n        If parents.Count <> 2 Then\n            Console.WriteLine(\"❌ Child does not have two parents.\")\n            Return\n        End If\n\n        Dim idP1 As Integer = parents(0), idP2 As Integer = parents(1)\n        RemoveAndUpdate(idP1, idP2)\n        RemoveAndUpdate(idP2, idP1)\n    End Sub\n\n    Private Sub Options()\n        Console.WriteLine(vbCrLf & \"1. Add child | 2. Remove child | 3. Exit\")\n        Dim option_ As Integer = Input.GetInt(vbCrLf & \"Option: \")\n\n        Select Case option_\n            Case 1\n                Add()\n            Case 2\n                Remove()\n            Case 3\n                Return\n            Case Else\n                Console.WriteLine(\"❌ Invalid option.\")\n        End Select\n    End Sub\n\n    Public Sub EditChildren()\n        PrintPeople()\n        Console.WriteLine(vbCrLf & \"Person ID to edit Children or a letter to exit.\")\n        Dim idStr As String = Input.GetStr(\"ID: \")\n        Dim id As Integer\n        If Not Integer.TryParse(idStr, id) Then\n            Console.WriteLine(\"Exit\")\n            Return\n        End If\n\n        Dim parent = GetPersonById(id)\n        If parent Is Nothing OrElse parent.Deleted Then\n            Console.WriteLine(\"❌ ID not found or the person is deleted.\")\n            Return\n        End If\n\n        Console.WriteLine($\"You selected '{parent.Name}'\")\n        Dim children = parent.Children\n        If children.Count <> 0 Then\n            Console.WriteLine(\"Children:\")\n            For Each kvp In children\n                Dim partner = GetPersonById(kvp.Key)\n                Dim partnerName As String = If(partner IsNot Nothing, partner.Name, \"Unknown\")\n                Console.WriteLine($\"With ID: {kvp.Key} -> '{partnerName}':\")\n                For Each childId In kvp.Value\n                    Dim child = GetPersonById(childId)\n                    Dim childName As String = If(child IsNot Nothing, child.Name, \"Unknown\")\n                    Console.WriteLine($\"    ID: {childId} -> '{childName}'\")\n                Next\n            Next\n        Else\n            Console.WriteLine(\"🚫 This person has no children.\")\n        End If\n\n        _idParent = id\n        _children = children\n        Options()\n    End Sub\nEnd Class\n\n'___________________________________________________\nPublic Class Tree\n    Inherits Children\n\n    Private Function FilteredGrandparents() As (Grandparents As List(Of Person), NoPartner As List(Of Person))\n        Dim grandparents As New List(Of Person)()\n        Dim noPartner As New List(Of Person)()\n\n        For Each person In GetPeople()\n            If person.Parents.Count = 0 AndAlso Not person.Deleted AndAlso person.Name <> \"unknown\" Then\n                If person.Partners.Count = 0 Then\n                    noPartner.Add(person)\n                Else\n                    Dim hasGrandparentPartner As Boolean = person.Partners.Any(\n                        Function(partnerId)\n                            Dim partner = GetPersonById(partnerId)\n                            Return partner IsNot Nothing AndAlso grandparents.Contains(partner)\n                        End Function\n                    )\n\n                    If Not hasGrandparentPartner Then\n                        grandparents.Add(person)\n                    End If\n                End If\n            End If\n        Next\n\n        Return (grandparents, noPartner)\n    End Function\n\n    Private Sub PrintChild(children As List(Of Integer), prefix As String, isLast As Boolean, isRoot As Boolean)\n        For i As Integer = 0 To children.Count - 1\n            Dim isLastChild As Boolean = i = children.Count - 1\n            Dim newPrefix As String = If(isRoot, prefix, prefix.Substring(0, Math.Max(0, prefix.Length - 4)) & If(isLast, \"    \", \"│   \"))\n\n            PrintFamily(\n                children(i),\n                newPrefix & If(isLastChild, \"└── \", \"├── \"),\n                isLastChild,\n                False\n            )\n        Next\n    End Sub\n\n    Private Sub PrintParents(id As Integer, partners As List(Of Integer), prefix As String, isLast As Boolean, isRoot As Boolean)\n        For Each partnerId In partners\n            Dim partner = GetPersonById(partnerId)\n            If partner IsNot Nothing Then\n                Console.WriteLine($\"{prefix}💑 With: {partner.Name} (ID: {partner.Id})\")\n                Dim children As List(Of Integer) = Nothing\n                If partner.Children.TryGetValue(id, children) AndAlso children.Count > 0 Then\n                    PrintChild(children, prefix, isLast, isRoot)\n                Else\n                    Console.WriteLine($\"{prefix}└── 🚫 Without children\")\n                End If\n            End If\n        Next\n    End Sub\n\n    Private Sub PrintFamily(id As Integer, Optional prefix As String = \"\", Optional isLast As Boolean = False, Optional isRoot As Boolean = True)\n        Dim person = GetPersonById(id)\n        If person Is Nothing Then Return\n\n        Console.WriteLine($\"{prefix}🙂 {person.Name} (ID: {person.Id})\")\n\n        If person.Partners.Count > 0 Then\n            If Not isRoot Then\n                prefix = prefix.Substring(0, Math.Max(0, prefix.Length - 4)) & If(isLast, \"    \", \"│   \")\n            End If\n\n            PrintParents(id, person.Partners, prefix, isLast, isRoot)\n            If Not isLast Then\n                Console.WriteLine(prefix)\n            End If\n        End If\n    End Sub\n\n    Public Sub PrintTree()\n        Dim result = FilteredGrandparents()\n        Dim grandparents = result.Grandparents\n        Dim noPartner = result.NoPartner\n\n        If grandparents.Count = 0 AndAlso noPartner.Count = 0 Then\n            Console.WriteLine(\"⚠️ No users are registered.\")\n            Return\n        End If\n\n        If noPartner.Count > 0 Then\n            Console.WriteLine(\"__________\")\n            Console.WriteLine(\"Parents unknown, without descendants and without a partner:\")\n            For Each p In noPartner\n                Console.WriteLine($\"😐 {p.Name} (ID: {p.Id})\")\n            Next\n        End If\n\n        Console.WriteLine()\n        For i As Integer = 0 To grandparents.Count - 1\n            Console.WriteLine(\"__________\")\n            Console.WriteLine($\"Family #{i + 1}\")\n            PrintFamily(grandparents(i).Id)\n        Next\n    End Sub\nEnd Class\n\n'___________________________________________________\nPublic Class Program\n    Inherits Tree\n\n    Private Const MENU As String = \"\n---------------------------------------------\n| 1. Add person     | 4. Edit children      |  \n| 2. Remove person  | 5. Print tree         |\n| 3. Edit partners  | 6. Exit               |\n---------------------------------------------\"\n\n    Public Sub Run()\n        While True\n            Console.WriteLine(MENU)\n            Dim option_ As Integer = Input.GetInt(vbLf & \"Option: \")\n            Select Case option_\n                Case 1\n                    AddPerson()\n                Case 2\n                    RemovePerson()\n                Case 3\n                    EditPartners()\n                Case 4\n                    EditChildren()\n                Case 5\n                    PrintTree()\n                Case 6\n                    Console.WriteLine(\"Bye\")\n                    Return\n                Case Else\n                    Console.WriteLine(\"❌ Invalid option.\")\n            End Select\n        End While\n    End Sub\n\n    Public Shared Sub Main()\n        Console.OutputEncoding = Encoding.UTF8\n        Dim program As New Program()\n        program.Run()\n    End Sub\nEnd Class\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/c#/deathwing696.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\n/*\n * EJERCICIO:\n * ¡La temporada 2 de \"Los Anillos de Poder\" está a punto de estrenarse! \n * ¿Qué pasaría si tuvieras que encargarte de repartir los anillos\n * entre las razas de la Tierra Media?\n * Desarrolla un programa que se encargue de distribuirlos.\n * Requisitos:\n * 1. Los Elfos recibirán un número impar.\n * 2. Los Enanos un número primo.\n * 3. Los Hombres un número par.\n * 4. Sauron siempre uno.\n * Acciones:\n * 1. Crea un programa que reciba el número total de anillos\n *    y busque una posible combinación para repartirlos.\n * 2. Muestra el reparto final o el error al realizarlo.\n */\n\nnamespace Reto_35\n{\n    internal class deathwing696\n    {\n        public class ManageRings\n        {\n            public ManageRings()\n            {\n            }\n\n            public List<int> RingSharing(int totalRings)\n            {\n                for (int elves = 1;  elves < totalRings; elves += 2) //Sólo números impares\n                {\n                    for (int dwarfs = 2; dwarfs < totalRings; dwarfs++) //Los primos empiezan a partir de 2\n                    {\n                        for (int humans = 2; humans < totalRings; humans += 2) // Sólo números pares\n                        {\n                            int sauron = 1;\n                            int sum = elves + dwarfs + humans + sauron;\n\n                            if (sum == totalRings)\n                            {\n                                Console.WriteLine(\"Reparto encontrado:\");\n                                Console.WriteLine($\"Elfos: {elves}\");\n                                Console.WriteLine($\"Enanos: {dwarfs}\");\n                                Console.WriteLine($\"Hombres: {humans}\");\n                                Console.WriteLine($\"Sauron: {sauron}\");\n\n                                var solution = new List<int>();\n                                solution.Add(elves);\n                                solution.Add(dwarfs);\n                                solution.Add(humans);\n                                solution.Add(sauron);\n\n                                return solution;\n                            }\n                        }\n                    }\n                }\n\n                Console.WriteLine(\"No se encontró un reparto válido para el número total de anillos proporcionado.\");\n\n                return null;\n            }\n\n            public bool IsPrime(int number)\n            {\n                if (number < 2)\n                    return false;\n\n                for (int i = 2; i < Math.Sqrt(number); i++)\n                {\n                    if (number % i == 0)\n                        return false;\n                }\n\n                return true;\n            }\n        }\n\n        static void Main(string[] args)\n        {\n            Console.WriteLine(\"Bienvenido al programa de gestión para el reparto de los anillos de poder.\");\n            Console.WriteLine(\"El reparto se hará según los siguientes criterios.\");\n            Console.WriteLine(\"1. Los Elfos recibirán un número impar.\");\n            Console.WriteLine(\"2. Los Enanos un número primo.\");\n            Console.WriteLine(\"3. Los Hombres un número par.\");\n            Console.WriteLine(\"4. Sauron siempre uno.\");\n            Console.Write(\"Introduce el númeor de anillos que desea repartir: \");\n            var totalRings = Int16.Parse(Console.ReadLine());\n\n            ManageRings rings = new ManageRings();\n            rings.RingSharing(totalRings);\n            Console.WriteLine(\"Adiós!\");\n\n            Console.ReadKey();\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/c#/hequebo.cs",
    "content": "class Distribution\n{\n    private int _sauron;\n    private int _elves;\n    private int _dwarves;\n    private int _men;\n\n    public int Sauron { get { return _sauron; } }\n    public int Elves { get { return _elves; } }\n    public int Dwarves {  get { return _dwarves; } }\n    public int Men { get { return _men; } }\n\n    public Distribution(int sauron, int elves, int dwarves, int men)\n    {\n        _sauron = sauron;\n        _elves = elves;\n        _dwarves = dwarves;\n        _men = men;\n    }\n}\nclass Program\n{\n    static void Main(string[] args)\n    {\n        Console.WriteLine(\"---DISTRIBUCIÓN DE ANILLOS---\");\n        Console.WriteLine(\"Ingresa un número entero de anillos a distribuir\");\n        int rings = 0;\n        int.TryParse(Console.ReadLine(), out rings);\n        if (rings == 0)\n        {\n            Console.WriteLine(\"El número de anillos no es válido...\");\n            return;\n        }\n        var distributions = DistributeRings(rings);\n        if (distributions.Count() == 0)\n        {\n            Console.WriteLine(\"No se pudo distribuir los anillos correctamente...\");\n            return;\n        }\n        Console.WriteLine(\"---Posibles Distribuciones de los anillos---\");\n        foreach (var distribution in distributions)\n        {\n            Console.WriteLine($\"Elfos: {distribution.Elves}, Enanos: {distribution.Dwarves} \" +\n                $\"Hombres: {distribution.Men}, Sauron: {distribution.Sauron}\");\n        }\n        Console.WriteLine(\"Distribucion media:\");\n        var mean = distributions[(int) distributions.Count() / 2];\n        Console.WriteLine($\"Elfos: {mean.Elves}, Enanos: {mean.Dwarves} \" +\n                $\"Hombres: {mean.Men}, Sauron: {mean.Sauron}\");\n    }\n    /*\n     * 1. Los Elfos recibirán un número impar.\n     * 2. Los Enanos un número primo.\n     * 3. Los Hombres un número par.\n     * 4. Sauron siempre uno.\n     */\n    static List<Distribution> DistributeRings(int rings)\n    {\n        var distributions = new List<Distribution>();\n        int sauron = 1;\n        rings -= sauron;\n\n        for (int elves = 1; elves < rings; elves += 2) \n        {\n            for (int men = 2; men < rings; men += 2) \n            {\n                int dwarves = rings - elves - men;\n                if (dwarves > 0 && IsPrime(dwarves)) \n                {\n                    var distribution = new Distribution(sauron, elves, dwarves, men);\n                    distributions.Add(distribution);\n                }\n            }\n        }\n        return distributions;\n    }\n    static bool IsPrime(int number)\n    {\n        if (number <= 1)\n            return false;\n        if (number == 2)\n            return true;\n        if (number % 2 == 0)\n            return false;\n        int limit = (int)Math.Sqrt(number);\n        for (int i = 3; i < limit; i += 2)\n        {\n            if (number % i == 0)\n                return false;\n\n        }\n        return true;\n    }\n\n}"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/c#/kenysdev.cs",
    "content": "namespace exs35;\n/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - C#\n_____________________________________\n35 REPARTIENDO LOS ANILLOS DE PODER\n------------------------------------\n¡La temporada 2 de \"Los Anillos de Poder\" está a punto de estrenarse!\n¿Qué pasaría si tuvieras que encargarte de repartir los anillos\nentre las razas de la Tierra Media?\nDesarrolla un programa que se encargue de distribuirlos.\nRequisitos:\n1. Los Elfos recibirán un número impar.\n2. Los Enanos un número primo.\n3. Los Hombres un número par.\n4. Sauron siempre uno.\nAcciones:\n1. Crea un programa que reciba el número total de anillos\n   y busque una posible combinación para repartirlos.\n2. Muestra el reparto final o el error al realizarlo.\n*/\n\nclass Program\n{\n    static int GetTotalRings()\n    {\n        while (true)\n        {\n            Console.Write(\"Cantidad de anillos: \");\n            if (int.TryParse(Console.ReadLine(), out int result) && result >= 1)\n            {\n                return result;\n            }\n            Console.WriteLine(\"Debe ser un valor entero '>= 1'.\");\n        }\n    }\n\n    static bool IsPrime(int n)\n    {\n        if (n < 2) return false;\n        for (int i = 2; i <= Math.Sqrt(n); i++)\n        {\n            if (n % i == 0) return false;\n        }\n        return true;\n    }\n\n    static List<(int, int, int)> Distribute(int total)\n    {\n        var combinations = new List<(int, int, int)>();\n        for (int elves = 1; elves < total; elves += 2)\n        {\n            for (int men = 2; men < total; men += 2)\n            {\n                int dwarves = total - (men + elves);\n                if (dwarves > 0 && IsPrime(dwarves))\n                {\n                    combinations.Add((elves, men, dwarves));\n                }\n            }\n        }\n        return combinations;\n    }\n\n    static double StandardDeviation(Tuple<int, int, int> tup)\n    {\n        double[] values = [tup.Item1, tup.Item2, tup.Item3];\n        double avg = values.Average();\n        double sum = values.Sum(d => Math.Pow(d - avg, 2));\n        return Math.Sqrt(sum / (values.Length - 1));\n    }\n\n    static (int, int, int) TheMostBalanced(List<(int, int, int)> combinations)\n    {\n        return combinations.OrderBy(c => StandardDeviation(Tuple.Create(c.Item1, c.Item2, c.Item3))).First();\n    }\n\n    static void PrintResult((int elves, int men, int dwarves) distribution, int sauron)\n    {\n        if (distribution == default)\n        {\n            Console.WriteLine(\"Error en la selección equitativa.\");\n            return;\n        }\n\n        Console.WriteLine(\"_________________________\");\n        Console.WriteLine($\"Elfos   -> {distribution.elves} : # Impar\");\n        Console.WriteLine($\"Enanos  -> {distribution.dwarves} : # Primo\");\n        Console.WriteLine($\"Hombres -> {distribution.men} : # Par\");\n        Console.WriteLine($\"Sauron  -> {sauron} : # Fijo\");\n        Console.WriteLine(\"-------------------------\");\n    }\n\n    static void Main()\n    {\n        Console.WriteLine(\"REPARTIENDO LOS ANILLOS DE PODER\");\n        int total = GetTotalRings();\n        int sauron = 1;\n        total -= sauron;\n\n        var combinations = Distribute(total);\n        if (combinations.Count == 0)\n        {\n            Console.WriteLine(\"No existe una combinación posible.\");\n            return;\n        }\n\n        var distribution = TheMostBalanced(combinations);\n        PrintResult(distribution, sauron);\n    }\n}\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/c#/miguelex.cs",
    "content": "using System;\n\nclass miguelex\n{\n    static bool EsPrimo(int num)\n    {\n        if (num <= 1) return false;\n        if (num == 2) return true;\n        if (num % 2 == 0) return false;\n\n        for (int i = 3; i <= Math.Sqrt(num); i += 2)\n        {\n            if (num % i == 0) return false;\n        }\n        return true;\n    }\n\n    static string RepartirAnillos(int totalAnillos)\n    {\n        if (totalAnillos < 4)\n        {\n            return \"Error: No hay suficientes anillos para cumplir con los requisitos.\";\n        }\n\n        int anillosSauron = 1;\n        totalAnillos -= 1;\n\n        int mejorDiferencia = int.MaxValue;\n        int[] mejorReparto = null;\n\n        for (int anillosElfos = 1; anillosElfos <= totalAnillos; anillosElfos += 2)\n        {\n            for (int anillosEnanos = 2; anillosEnanos <= totalAnillos; anillosEnanos++)\n            {\n                if (EsPrimo(anillosEnanos))\n                {\n                    int anillosHombres = totalAnillos - anillosElfos - anillosEnanos;\n\n                    if (anillosHombres > 0 && anillosHombres % 2 == 0)\n                    {\n                        int diferencia = Math.Max(anillosElfos, Math.Max(anillosEnanos, anillosHombres)) -\n                                         Math.Min(anillosElfos, Math.Min(anillosEnanos, anillosHombres));\n\n                        if (diferencia < mejorDiferencia)\n                        {\n                            mejorDiferencia = diferencia;\n                            mejorReparto = new int[] { anillosElfos, anillosEnanos, anillosHombres, anillosSauron };\n                        }\n                    }\n                }\n            }\n        }\n\n        if (mejorReparto != null)\n        {\n            return $\"Reparto exitoso: Elfos = {mejorReparto[0]}, Enanos = {mejorReparto[1]}, Hombres = {mejorReparto[2]}, Sauron = {mejorReparto[3]}\";\n        }\n        else\n        {\n            return \"Error: No se encontró una combinación válida para repartir los anillos.\";\n        }\n    }\n\n    static void Main(string[] args)\n    {\n        Console.Write(\"Ingresa el número total de anillos: \");\n        int totalAnillos = int.Parse(Console.ReadLine());\n\n        string resultado = RepartirAnillos(totalAnillos);\n        Console.WriteLine(resultado);\n    }\n}\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/c++/hectorio23.cpp",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\n#include <iostream>\n#include <cmath>\nusing namespace std;\n\nbool isPrime(int n) {\n    if (n <= 1) return false;\n    for (int i = 2; i <= sqrt(n); i++) {\n        if (n % i == 0) return false;\n    }\n    return true;\n}\n\nvoid distributeRings(int totalRings) {\n    int sauronRings = 1;\n    int remainingRings = totalRings - sauronRings;\n    \n    // Try different combinations for elves and dwarves\n    for (int elvesRings = 1; elvesRings < remainingRings; elvesRings += 2) {  // Elves get odd numbers\n        for (int dwarvesRings = 2; dwarvesRings < remainingRings; dwarvesRings++) {\n            if (isPrime(dwarvesRings)) {  // Dwarves get prime numbers\n                int humansRings = remainingRings - elvesRings - dwarvesRings;\n                if (humansRings > 0 && humansRings % 2 == 0) {  // Humans get even numbers\n                    cout << \"Elves: \" << elvesRings << \", Dwarves: \" << dwarvesRings \n                         << \", Humans: \" << humansRings << \", Sauron: \" << sauronRings << endl;\n                    return;\n                }\n            }\n        }\n    }\n    cout << \"Error: No valid distribution found.\" << endl;\n}\n\nint main() {\n    int totalRings = 20;\n    distributeRings(totalRings);\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/dart/redom69.dart",
    "content": "import 'dart:io';\n\nbool isPrime(int n) {\n  if (n <= 1) return false;\n  if (n <= 3) return true;\n  if (n % 2 == 0 || n % 3 == 0) return false;\n  int i = 5;\n  while (i * i <= n) {\n    if (n % i == 0 || n % (i + 2) == 0) return false;\n    i += 6;\n  }\n  return true;\n}\n\nList<int> findAllPrimes(int max_n) {\n  List<int> primes = [];\n  for (int i = 2; i <= max_n; i++) {\n    if (isPrime(i)) {\n      primes.add(i);\n    }\n  }\n  return primes;\n}\n\nList<int> findAllPars(int max_n) {\n  List<int> pars = [];\n  for (int i = 2; i <= max_n; i += 2) {\n    pars.add(i);\n  }\n  return pars;\n}\n\nList<int> findAllOdds(int max_n) {\n  List<int> odds = [];\n  for (int i = 1; i <= max_n; i += 2) {\n    odds.add(i);\n  }\n  return odds;\n}\n\nMap<String, int>? distributeRings(int rings) {\n  rings = rings - 1; // Uno es siempre para Sauron\n  if (rings < 3) {\n    print(\n        \"El número de anillos es insuficiente para cumplir con los requisitos.\");\n    return null;\n  }\n\n  List<int> primes = findAllPrimes(rings);\n  List<int> odds = findAllOdds(rings);\n  List<int> pars = findAllPars(rings);\n\n  Map<String, int>? bestDistribution;\n\n  for (int dwarf_rings in primes) {\n    for (int elf_rings in odds) {\n      for (int human_rings in pars) {\n        if (dwarf_rings + elf_rings + human_rings == rings) {\n          Map<String, int> currentDistribution = {\n            \"Enanos\": dwarf_rings,\n            \"Elfos\": elf_rings,\n            \"Humanos\": human_rings,\n            \"Sauron\": 1\n          };\n          if (bestDistribution == null ||\n              (currentDistribution[\"Enanos\"]! +\n                      currentDistribution[\"Elfos\"]! +\n                      currentDistribution[\"Humanos\"]! >\n                  bestDistribution[\"Enanos\"]! +\n                      bestDistribution[\"Elfos\"]! +\n                      bestDistribution[\"Humanos\"]!)) {\n            bestDistribution = currentDistribution;\n          }\n        }\n      }\n    }\n  }\n\n  if (bestDistribution != null) {\n    return bestDistribution;\n  } else {\n    print(\"No se pudo encontrar una distribución válida.\");\n    return null;\n  }\n}\n\nvoid printDistribution(Map<String, int> distribution) {\n  distribution.forEach((race, count) {\n    print(\"$race: $count anillos\");\n  });\n}\n\nvoid main() {\n  stdout.write('Introduce el número de anillos de poder: ');\n  String? input = stdin.readLineSync();\n  if (input != null) {\n    int rings = int.parse(input);\n    Map<String, int>? distribution = distributeRings(rings);\n    if (distribution != null) {\n      printDistribution(distribution);\n    } else {\n      print('No se han podido repartir los anillos correctamente.');\n    }\n  }\n}\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/ejercicio.md",
    "content": "# #35 REPARTIENDO LOS ANILLOS DE PODER\n> #### Dificultad: Media | Publicación: 26/08/24 | Corrección: 02/09/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * ¡La temporada 2 de \"Los Anillos de Poder\" está a punto de estrenarse! \n * ¿Qué pasaría si tuvieras que encargarte de repartir los anillos\n * entre las razas de la Tierra Media?\n * Desarrolla un programa que se encargue de distribuirlos.\n * Requisitos:\n * 1. Los Elfos recibirán un número impar.\n * 2. Los Enanos un número primo.\n * 3. Los Hombres un número par.\n * 4. Sauron siempre uno.\n * Acciones:\n * 1. Crea un programa que reciba el número total de anillos\n *    y busque una posible combinación para repartirlos.\n * 2. Muestra el reparto final o el error al realizarlo.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/go/miguelex.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"math\"\n)\n\nfunc esPrimo(num int) bool {\n\tif num <= 1 {\n\t\treturn false\n\t}\n\tif num == 2 {\n\t\treturn true\n\t}\n\tif num%2 == 0 {\n\t\treturn false\n\t}\n\tfor i := 3; i <= int(math.Sqrt(float64(num))); i += 2 {\n\t\tif num%i == 0 {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc repartirAnillos(totalAnillos int) string {\n\tif totalAnillos < 4 {\n\t\treturn \"Error: No hay suficientes anillos para cumplir con los requisitos.\"\n\t}\n\n\tanillosSauron := 1\n\ttotalAnillos -= 1\n\n\tmejorDiferencia := int(^uint(0) >> 1) // Máximo entero\n\tvar mejorReparto []int\n\n\tfor anillosElfos := 1; anillosElfos <= totalAnillos; anillosElfos += 2 {\n\t\tfor anillosEnanos := 2; anillosEnanos <= totalAnillos; anillosEnanos++ {\n\t\t\tif esPrimo(anillosEnanos) {\n\t\t\t\tanillosHombres := totalAnillos - anillosElfos - anillosEnanos\n\t\t\t\tif anillosHombres > 0 && anillosHombres%2 == 0 {\n\t\t\t\t\tdiferencia := max(anillosElfos, anillosEnanos, anillosHombres) - min(anillosElfos, anillosEnanos, anillosHombres)\n\t\t\t\t\tif diferencia < mejorDiferencia {\n\t\t\t\t\t\tmejorDiferencia = diferencia\n\t\t\t\t\t\tmejorReparto = []int{anillosElfos, anillosEnanos, anillosHombres, anillosSauron}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif mejorReparto != nil {\n\t\treturn fmt.Sprintf(\"Reparto exitoso: Elfos = %d, Enanos = %d, Hombres = %d, Sauron = %d\", mejorReparto[0], mejorReparto[1], mejorReparto[2], mejorReparto[3])\n\t} else {\n\t\treturn \"Error: No se encontró una combinación válida para repartir los anillos.\"\n\t}\n}\n\nfunc max(nums ...int) int {\n\tmaxNum := nums[0]\n\tfor _, num := range nums {\n\t\tif num > maxNum {\n\t\t\tmaxNum = num\n\t\t}\n\t}\n\treturn maxNum\n}\n\nfunc min(nums ...int) int {\n\tminNum := nums[0]\n\tfor _, num := range nums {\n\t\tif num < minNum {\n\t\t\tminNum = num\n\t\t}\n\t}\n\treturn minNum\n}\n\nfunc main() {\n\tvar totalAnillos int\n\tfmt.Print(\"Ingresa el número total de anillos: \")\n\tfmt.Scanf(\"%d\", &totalAnillos)\n\n\tresultado := repartirAnillos(totalAnillos)\n\tfmt.Println(resultado)\n}\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/java/AmadorQuispe.java",
    "content": "package com.amsoft.roadmap.example35;\n\nimport java.util.Objects;\nimport java.util.Optional;\nimport java.util.Scanner;\nimport java.util.stream.IntStream;\n\npublic class Example35 {\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n        System.out.print(\"Enter the total number of rings: \");\n        int totalRings = scanner.nextInt();\n\n        if (totalRings <= 1) {\n            System.out.println(\"Error: Not enough rings to distribute.\");\n            return;\n        }\n\n        int remainingRings = totalRings - 1;\n\n        Optional<Distribution> result = findValidDistribution(remainingRings);\n\n        result.ifPresentOrElse(\n                Example35::printDistribution,\n                () -> System.out.println(\"No valid distribution found for the given number of rings.\")\n        );\n\n        scanner.close();\n    }\n\n    private static Optional<Distribution> findValidDistribution(int remainingRings) {\n        return IntStream.iterate(1, i -> i + 2)\n                .limit(remainingRings / 2)\n                .boxed()\n                .flatMap(elves -> IntStream.range(2, remainingRings)\n                        .filter(Example35::isPrime)\n                        .boxed()\n                        .map(dwarves -> {\n                            int men = remainingRings - elves - dwarves;\n                            if (men > 0 && men % 2 == 0) {\n                                return new Distribution(elves, dwarves, men);\n                            }\n                            return null;\n                        })\n                        .filter(Objects::nonNull))\n                .findFirst();\n    }\n\n    private static boolean isPrime(int number) {\n        return number > 1 && IntStream.rangeClosed(2, (int) Math.sqrt(number))\n                .allMatch(i -> number % i != 0);\n    }\n\n    private static void printDistribution(Distribution distribution) {\n        System.out.println(\"Valid distribution found:\");\n        System.out.println(\"Elves: \" + distribution.elves());\n        System.out.println(\"Dwarves: \" + distribution.dwarves());\n        System.out.println(\"Men: \" + distribution.men());\n        System.out.println(\"Sauron: 1\");\n    }\n\n    record Distribution(int elves, int dwarves, int men) {\n    }\n}\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/java/Josegs95.java",
    "content": "import java.util.ArrayList;\nimport java.util.List;\n\npublic class Josegs95 {\n    public static void main(String[] args) {\n        new Josegs95().ringOfPower();\n    }\n\n    private int ringToSauron;\n    private int ringToMen;\n    private int ringToElves;\n    private int ringToDwarves;\n\n    public void ringOfPower(){\n        shareRings(20);\n        shareRings(51);\n        shareRings(101);\n        shareRings(117);\n    }\n\n    private void shareRings(int ringAmount){\n        List<Integer[]> combinations = calculateSharing(ringAmount);\n        if (combinations.isEmpty()){\n            System.out.println(\"Error. No ha sido posible hacer la distribución de los \" + ringAmount + \" anillos\");\n            return;\n        }\n\n        //Ver todas las combinaciones\n        int counter = 1;\n        for (Integer[] combination : combinations){\n            System.out.println(counter + \". Hombres: \" + combination[0] + \", Elfos: \" +\n                    combination[1] + \", Enanos: \" + combination[2] + \", Sauron: 1\");\n            counter++;\n        }\n\n        Integer[] combination = combinations.get((combinations.size() / 2) - (combinations.size() % 2 == 0 ? 1 : 0));\n\n        System.out.println(\"¡Se repartieron los \" + ringAmount + \" anillos con éxito!\");\n        System.out.println(\"Los hombres reciben \" + combination[0] + \" anillo/s.\");\n        System.out.println(\"Los elfos reciben \" + combination[1] + \" anillo/s.\");\n        System.out.println(\"Los enanos reciben \" + combination[2] + \" anillo/s.\");\n        System.out.println(\"Y Sauron recibe 1 anillo.\");\n    }\n\n    private List<Integer[]> calculateSharing(int ringAmount){\n        ringToSauron = 1;\n        ringToElves = 0;\n        ringToMen = 0;\n        ringToDwarves = 0;\n\n        List<Integer[]> possibleSharing = new ArrayList<>();\n\n        for (int a = 0; ringToElves < ringAmount; a++){\n            ringToElves = 1 + 2 * a;\n\n            for (int b = 0; ringToMen < ringAmount; b++){\n                ringToMen = 2 + 2 * b;\n\n                for (int c = 0; ringToDwarves < ringAmount; c++){\n                    ringToDwarves = primeNumber(c);\n                    if (checkRingSum() == ringAmount)\n                        possibleSharing.add(new Integer[] {ringToMen, ringToElves, ringToDwarves});\n                }\n\n                ringToDwarves = 2;\n                if (checkRingSum() == ringAmount)\n                    possibleSharing.add(new Integer[] {ringToMen, ringToElves, ringToDwarves});\n            }\n\n            ringToMen = 2;\n            if (checkRingSum() == ringAmount)\n                possibleSharing.add(new Integer[] {ringToMen, ringToElves, ringToDwarves});\n        }\n\n\n\n        return possibleSharing;\n    }\n\n    private int primeNumber(int n){\n        if (n == 0)\n            return 2;\n\n        List<Integer> primeNumberList = new ArrayList<>();\n        primeNumberList.add(2);\n\n        numbers:\n        for (int i = 3; i < Integer.MAX_VALUE; i+= 2){\n            for (int primeNumber : primeNumberList){\n                if (i % primeNumber == 0){\n                    continue numbers;\n                }\n            }\n            if (--n == 0)\n                return i;\n            primeNumberList.add(i);\n        }\n\n        return -1;\n    }\n\n    private int checkRingSum(){\n        return ringToSauron + ringToDwarves + ringToElves + ringToMen;\n    }\n}\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/java/MohamedElderkaoui.java",
    "content": "import java.util.Scanner;\n\npublic class MohamedElderkaoui{\n        public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n        System.out.print(\"Ingresa el número total de anillos: \");\n        int totalAnillos = scanner.nextInt();\n\n        // Sauron siempre recibe 1 anillo, descontamos eso.\n        int anillosRestantes = totalAnillos - 1;\n\n        if (anillosRestantes <= 0) {\n            System.out.println(\"Error: No hay suficientes anillos para repartir.\");\n            return;\n        }\n\n        boolean encontrado = false;\n\n        // Iteramos para encontrar los valores correctos.\n        for (int elfos = 1; elfos < anillosRestantes; elfos += 2) {  // Impar\n            for (int enanos = 2; enanos < anillosRestantes; enanos++) {  // Primos\n                if (esPrimo(enanos)) {\n                    int hombres = anillosRestantes - elfos - enanos;\n                    if (hombres > 0 && hombres % 2 == 0) {  // Par\n                        System.out.println(\"Reparto encontrado:\");\n                        System.out.println(\"Elfos: \" + elfos);\n                        System.out.println(\"Enanos: \" + enanos);\n                        System.out.println(\"Hombres: \" + hombres);\n                        System.out.println(\"Sauron: 1\");\n                        encontrado = true;\n                        break;\n                    }\n                }\n            }\n            if (encontrado) break;\n        }\n\n        if (!encontrado) {\n            System.out.println(\"No   encontró un reparto válido para el número de anillos dado.\");\n        }\n\n        scanner.close();\n    }\n\n    // Método para verificar si un número es primo\n    private static boolean esPrimo(int numero) {\n        if (numero < 2) return false;\n        for (int i = 2; i <= Math.sqrt(numero); i++) {\n            if (numero % i != 0) return false;\n        }\n        return true;\n    }\n}"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/java/asjordi.java",
    "content": "public class Main {\n\n    public static void main(String[] args) {\n        int totalRings = 10;\n        distribuirAnillos(totalRings);\n    }\n\n    public static void distribuirAnillos(int totalAnillos) {\n        if (totalAnillos < 4) {\n            System.out.println(\"Error: Se necesitan al menos 4 anillos para distribuir.\");\n            return;\n        }\n\n        int anillosSauron = 1;\n        int anillosRestantes = totalAnillos - anillosSauron;\n\n        for (int anillosElfos = 1; anillosElfos < anillosRestantes; anillosElfos += 2) {\n            for (int anillosEnanos = 2; anillosEnanos < anillosRestantes - anillosElfos; anillosEnanos++) {\n                if (esPrimo(anillosEnanos)) {\n                    int anillosHombres = anillosRestantes - anillosElfos - anillosEnanos;\n                    if (anillosHombres % 2 == 0) {\n                        System.out.println(\"Reparto exitoso:\");\n                        System.out.println(\"Elfos: \" + anillosElfos);\n                        System.out.println(\"Enanos: \" + anillosEnanos);\n                        System.out.println(\"Hombres: \" + anillosHombres);\n                        System.out.println(\"Sauron: \" + anillosSauron);\n                        return;\n                    }\n                }\n            }\n        }\n\n        System.out.println(\"Error: No se pudo encontrar una distribución válida para \" + totalAnillos + \" anillos.\");\n    }\n\n    private static boolean esPrimo(int number) {\n        if (number <= 1) return false;\n        if (number <= 3) return true;\n        if (number % 2 == 0 || number % 3 == 0) return false;\n        for (int i = 5; i * i <= number; i += 6) {\n            if (number % i == 0 || number % (i + 2) == 0) return false;\n        }\n        return true;\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/java/martinbohorquez.java",
    "content": "import java.util.*;\nimport java.util.function.Consumer;\n\n/**\n * #35 REPARTIENDO LOS ANILLOS DE PODER\n *\n * @author martinbohorquez\n */\npublic class martinbohorquez {\n    static List<Map<String, Race>> racesList = new LinkedList<>();\n\n    public static void main(String[] args) {\n        Scanner sc = new Scanner(System.in);\n        System.out.println(\"Introduce el número de anillos que deseas repartir:\");\n\n        try {\n            Integer totalRings = Integer.valueOf(sc.nextLine());\n            long duration1 = getDuration(martinbohorquez::distributeRings, totalRings);\n            if (racesList.isEmpty()) System.out.println(\"No es posible distribuir los anillos de poder.\");\n            else {\n                long duration2 = getDuration(martinbohorquez::displayDistributeRings, racesList);\n                System.out.printf(\"La cantidad de posibles distribuciones es: %s%n\", racesList.size());\n                long duration3 = getDuration(martinbohorquez::bestDistributeRings, racesList);\n                double duration = (double) (duration1 + duration2 + duration3) / 1000;\n                System.out.printf(\"Execution time in seconds: %d (ms) + %d (ms) + %d (ms) = %.2f seconds.%n\", duration1, duration2, duration3, duration);\n            }\n        } catch (NumberFormatException e) {\n            System.out.println(\"Debe ingresar un número entero de anillos!\");\n        }\n    }\n\n    private static <T> long getDuration(Consumer<T> method, T parameter) {\n        long startTime = System.currentTimeMillis();\n        method.accept(parameter); // Run the passed method\n        long endTime = System.currentTimeMillis();\n        return endTime - startTime;\n    }\n\n    private static Map<String, Race> getRaceMap() {\n        Map<String, Race> races = new LinkedHashMap<>();\n        races.put(\"elves\", new Race(\"Elfos\"));\n        races.put(\"dwarves\", new Race(\"Enanos\"));\n        races.put(\"men\", new Race(\"Hombres\"));\n        races.put(\"sauron\", new Race(\"Sauron\"));\n        return races;\n    }\n\n    private static void distributeRings(Integer totalRings) {\n        totalRings -= 1;\n        for (int men = 2; men <= totalRings; men += 2)\n            for (int elves = 1; elves <= (totalRings - men); elves += 2) {\n                int dwarves = totalRings - men - elves;\n                if (esPrimo(dwarves)) {\n                    Map<String, Race> raceMap = getRaceMap();\n                    raceMap.get(\"elves\").setRings(elves);\n                    raceMap.get(\"dwarves\").setRings(dwarves);\n                    raceMap.get(\"men\").setRings(men);\n                    raceMap.get(\"sauron\").setRings(1);\n                    racesList.add(raceMap);\n                }\n            }\n    }\n\n    private static void displayDistributeRings(List<Map<String, Race>> racesList) {\n        racesList.stream()\n                .map(Map::values)\n                .forEach(System.out::println);\n    }\n\n    private static void bestDistributeRings(List<Map<String, Race>> racesList) {\n        System.out.println(\"El conjunto de repartición mas equitativo es:\");\n        racesList.stream().map(Map::values)\n                .min(Comparator.comparingDouble(martinbohorquez::calcularDesviacionEstandar))\n                .ifPresent(System.out::println);\n    }\n\n    private static boolean esPrimo(Integer numero) {\n        if (numero <= 1) return false;\n        if (numero <= 3) return true;\n        if (numero % 2 == 0) return false;\n        for (int i = 3; i <= Math.sqrt(numero); i += 2) {\n            if (numero % i == 0) return false;\n        }\n        return true;\n    }\n\n    private static double calcularDesviacionEstandar(Collection<Race> races) {\n        if (races.isEmpty()) return 0.0;\n\n        double media = races.stream()\n                .mapToInt(Race::getRings)\n                .average()\n                .orElse(0.0);\n\n        double sumaCuadrados = races.stream()\n                .mapToDouble(race -> Math.pow(race.getRings() - media, 2))\n                .sum();\n\n        return Math.sqrt(sumaCuadrados / races.size());\n    }\n\n    private static class Race {\n        private final String name;\n        private Integer rings;\n\n        public Race(String name) {\n            this.name = name;\n        }\n\n        public Integer getRings() {\n            return rings;\n        }\n\n        public void setRings(Integer rings) {\n            this.rings = rings;\n        }\n\n        @Override\n        public String toString() {\n            return \"'\" + name + \"': '\" + rings + \"'\";\n        }\n    }\n}\n\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/java/miguelex.java",
    "content": "import java.util.Scanner;\n\npublic class miguelex {\n    \n    public static boolean esPrimo(int num) {\n        if (num <= 1) return false;\n        if (num == 2) return true;\n        if (num % 2 == 0) return false;\n        \n        for (int i = 3; i <= Math.sqrt(num); i += 2) {\n            if (num % i == 0) return false;\n        }\n        return true;\n    }\n\n    public static String repartirAnillos(int totalAnillos) {\n        if (totalAnillos < 4) {\n            return \"Error: No hay suficientes anillos para cumplir con los requisitos.\";\n        }\n\n        int anillosSauron = 1;\n        totalAnillos -= 1;\n        \n        int mejorDiferencia = Integer.MAX_VALUE;\n        int[] mejorReparto = null;\n        \n        for (int anillosElfos = 1; anillosElfos <= totalAnillos; anillosElfos += 2) {\n            for (int anillosEnanos = 2; anillosEnanos <= totalAnillos; anillosEnanos++) {\n                if (esPrimo(anillosEnanos)) {\n                    int anillosHombres = totalAnillos - anillosElfos - anillosEnanos;\n                    \n                    if (anillosHombres > 0 && anillosHombres % 2 == 0) {\n                        int diferencia = Math.max(anillosElfos, Math.max(anillosEnanos, anillosHombres)) - Math.min(anillosElfos, Math.min(anillosEnanos, anillosHombres));\n                        \n                        if (diferencia < mejorDiferencia) {\n                            mejorDiferencia = diferencia;\n                            mejorReparto = new int[]{ anillosElfos, anillosEnanos, anillosHombres, anillosSauron };\n                        }\n                    }\n                }\n            }\n        }\n        \n        if (mejorReparto != null) {\n            return String.format(\"Reparto exitoso: Elfos = %d, Enanos = %d, Hombres = %d, Sauron = %d\", mejorReparto[0], mejorReparto[1], mejorReparto[2], mejorReparto[3]);\n        } else {\n            return \"Error: No se encontró una combinación válida para repartir los anillos.\";\n        }\n    }\n\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n        System.out.print(\"Ingresa el número total de anillos: \");\n        int totalAnillos = scanner.nextInt();\n        \n        String resultado = repartirAnillos(totalAnillos);\n        System.out.println(resultado);\n    }\n}\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #35 - JavaScript -> Jesus Antonio Escamilla */\n\n/**\n * REPARTIENDO LOS ANILLOS DE PODER.\n * Utilizando la Terminal para pedir datos y agregarlos.\n */\n\nconst readline = require('readline');\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\n\nfunction esPrimo(numero){\n    if (numero <= 1) return false;\n    if (numero <= 3) return true;\n    if (numero % 2 === 0 || numero % 3 === 0) return false;\n    for (let i = 5; i * i <= numero; i += 6) {\n        if (numero % i === 0 || numero % (i + 2) === 0) return false;\n    }\n    return true;\n}\n\nfunction repetirAnillos(totalAnillos){\n    let sauron = 1;\n    totalAnillos -= sauron;\n    let distribuciones = [];\n\n    for (let elAnillos = 1; elAnillos < totalAnillos; elAnillos += 2) {\n        for (let enAnillos = 2; enAnillos < totalAnillos; enAnillos++) {\n            if (esPrimo(enAnillos)) {\n                let homAnillos = totalAnillos - elAnillos - enAnillos;\n                if (homAnillos % 2 === 0 && homAnillos > 0) {\n                    distribuciones.push({\n                        Hombres: homAnillos,\n                        Elfos: elAnillos,\n                        Enanos: enAnillos,\n                        Sauron: sauron\n                    });\n                }\n            }\n        }\n    }\n\n    return distribuciones.length > 0 ? distribuciones : ['Error: No se puede repartir los anillos de acuerdo a las reglas.']\n}\n\n// Ejemplo de uso:\nrl.question('Introduce el numero total de anillos: ', (input) => {\n    const totalAnillos = parseInt(input, 10);\n\n    if (isNaN(totalAnillos) || totalAnillos <= 0) {\n        console.log(\"Por favor, introduce un número válido.\");\n    } else {\n        let distribuciones = repetirAnillos(totalAnillos);\n        if (Array.isArray(distribuciones)) {\n            distribuciones.forEach((reparto, index) => {\n                console.log(`Distribución ${index + 1}:`);\n                console.log(`  Hombres: ${reparto.Hombres}`);\n                console.log(`  Elfos: ${reparto.Elfos}`);\n                console.log(`  Enanos: ${reparto.Enanos}`);\n                console.log(`  Sauron: ${reparto.Sauron}`);\n                console.log();\n            });\n        } else {\n            console.log(distribuciones);\n        }\n    }\n\n    rl.close();\n})"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/javascript/Rafacv23.js",
    "content": "/*\n    Creado por Rafa Canosa\n    Github: https://github.com/Rafacv23\n    Website: https://www.rafacanosa.dev\n*/\n\nlet rings = 8 // número inicial de anillos\n\nlet elfos = 0 // reciben números impares, como mínimo reciben 1\nlet enanos = 0 // reciben números primos, como mínimo reciben 2\nlet hombres = 0 // reciben números pares, como mínimo reciben 0\nlet sauron = 0 // siempre recibe uno\n\nif (rings >= 4) {\n  // Otorgamos siempre 1 anillo a Sauron\n  sauron = 1\n  rings -= 1\n\n  // Mientras haya anillos para repartir\n  while (rings > 0) {\n    // Seleccionamos un número aleatorio de anillos a repartir (de 1 a rings)\n    let asignar = Math.floor(Math.random() * rings) + 1\n\n    // Si el número aleatorio es impar, asignamos a los Elfos\n    if (asignar % 2 !== 0 && rings > 0) {\n      elfos += asignar\n      rings -= asignar\n    }\n\n    // Si el número aleatorio es primo, asignamos a los Enanos\n    if (esPrimo(asignar) && rings > 0) {\n      enanos += asignar\n      rings -= asignar\n    }\n\n    // Si el número aleatorio es par, asignamos a los Hombres\n    if (asignar % 2 === 0 && rings > 0) {\n      hombres += asignar\n      rings -= asignar\n    }\n  }\n\n  console.log(`Sauron: ${sauron}`)\n  console.log(`Elfos: ${elfos}`)\n  console.log(`Enanos: ${enanos}`)\n  console.log(`Hombres: ${hombres}`)\n} else {\n  console.error(\n    \"El número de anillos que has introducido es menor de 4, por lo tanto no podemos realizar un reparto equitativo de los mismos\"\n  )\n}\n\n// Función para verificar si un número es primo\nfunction esPrimo(num) {\n  if (num < 2) return false\n  for (let i = 2; i <= Math.sqrt(num); i++) {\n    if (num % i === 0) return false\n  }\n  return true\n}\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/javascript/RaulDoezon.js",
    "content": "/*\n  EJERCICIO:\n  ¡La temporada 2 de \"Los Anillos de Poder\" está a punto de estrenarse! \n  ¿Qué pasaría si tuvieras que encargarte de repartir los anillos\n  entre las razas de la Tierra Media?\n  Desarrolla un programa que se encargue de distribuirlos.\n  Requisitos:\n  1. Los Elfos recibirán un número impar.\n  2. Los Enanos un número primo.\n  3. Los Hombres un número par.\n  4. Sauron siempre uno.\n  Acciones:\n  1. Crea un programa que reciba el número total de anillos\n     y busque una posible combinación para repartirlos.\n  2. Muestra el reparto final o el error al realizarlo.\n*/\n\nconst ringDistribution = (totalRings) => {\n  const sauronRing = 1;\n  let allPrimeNumbers = [],\n    primeNumber,\n    indexNumber,\n    isPrime;\n\n  console.log(`Anillos totales: ${totalRings}`);\n  console.log(`Anillos para Sauron: ${sauronRing}`);\n\n  totalRings = totalRings - sauronRing;\n\n  do {\n    elvesRings = Math.floor(Math.random() * totalRings);\n  } while(elvesRings % 2 === 0);\n\n  totalRings = totalRings - elvesRings;\n\n  console.log(`Anillos para los Elfos: ${elvesRings}`);\n\n  for (primeNumber = 2; primeNumber <= totalRings; primeNumber++) {\n    if (primeNumber == 1 || primeNumber == 0) {\n      continue;\n    }\n\n    isPrime = true;\n\n    for (indexNumber = 2; indexNumber <= primeNumber / 2; indexNumber++) {\n      if (primeNumber % indexNumber == 0) {\n        isPrime = false;\n\n        break;\n      }\n    }\n\n    if (isPrime) {\n      allPrimeNumbers.push(primeNumber);\n    }\n  }\n\n  let selectPrimeNumber = Math.floor(Math.random() * allPrimeNumbers.length);\n  let dwarvesRings = allPrimeNumbers[selectPrimeNumber];\n  totalRings = totalRings - dwarvesRings;\n\n  console.log(`Anillos para los Enanos: ${dwarvesRings}`);\n\n  do {\n    menRings = Math.floor((Math.random() * totalRings) + 1);\n  } while(menRings % 2 !== 0);\n\n  totalRings = totalRings - menRings;\n\n  if (totalRings > 0 && totalRings % 2 === 0) {\n    menRings = menRings + totalRings;\n    totalRings = totalRings - totalRings;\n  }\n\n  console.log(`Anillos para los Hombres: ${menRings}`);\n\n  if (totalRings > 0 && totalRings % 2 !== 0) {\n    console.error(`Los anillos no se distribuyeron correctamente. El restante fue de: ${totalRings}`);\n  }\n}\n\nringDistribution(100);\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/javascript/RicJDev.js",
    "content": "/*\n  EJERCICIO:\n\n- Se ejecuta en Node.js, importando el módulo 'Readline/promises' (https://nodejs.org/api/readline.html)\n\n  @RicJDev\n*/\n\nfunction isPrime(num) {\n  if (num <= 1) return false\n  if (num <= 3) return true\n  if (num % 2 === 0 || num % 3 === 0) return false\n\n  for (let i = 5; i * i <= num; i += 6) {\n    if (num % i === 0 || num % (i + 2) === 0) {\n      return false\n    }\n  }\n\n  return true\n}\n\nconst isEven = (num) => num % 2 === 0\n\nfunction distributeRings(totalRings) {\n  let rings = null\n\n  if (totalRings < 6) {\n    console.warn('No hay suficientes anillos para repartir')\n    return rings\n  }\n\n  totalRings -= 1\n\n  let bestDiference = Number.MAX_SAFE_INTEGER\n\n  for (let elvesRings = 1; elvesRings <= totalRings; elvesRings += 2) {\n    for (let dwarvesRings = 2; dwarvesRings <= totalRings; dwarvesRings++) {\n      if (isPrime(dwarvesRings)) {\n        let humansRings = totalRings - elvesRings - dwarvesRings\n\n        if (isEven(humansRings) && humansRings > 0) {\n          const diference =\n            Math.max(elvesRings, dwarvesRings, humansRings) -\n            Math.min(elvesRings, dwarvesRings, humansRings)\n\n          if (diference < bestDiference) {\n            bestDiference = diference\n\n            rings = {\n              elves: elvesRings,\n              dwarves: dwarvesRings,\n              humans: humansRings,\n              sauron: 1,\n            }\n          }\n        }\n      }\n    }\n  }\n\n  if (rings === null) {\n    console.warn('No se ha encontrado una combinación para repartir los anillos')\n  }\n\n  return rings\n}\n\n//Implementación en terminal\n\nimport * as readline from 'readline/promises'\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout,\n})\n\nconsole.clear()\n\nwhile (true) {\n  let answer = await rl.question('Indique la cantidad de anillos a repartir. ')\n\n  let totalRings = parseInt(answer.match(/\\d+/g))\n\n  if (isNaN(totalRings)) {\n    console.log('Por favor igresar numeros enteros')\n  } else {\n    const rings = distributeRings(totalRings)\n\n    if (rings !== null) {\n      console.log(`\\nSe han distribuido los ${totalRings} anillos de la siguiente manera: `)\n      console.log('Elfos:', rings.elves)\n      console.log('Enanos:', rings.dwarves)\n      console.log('Hombres:', rings.humans)\n      console.log('Sauron:', rings.sauron)\n\n      rl.close()\n      break\n    }\n  }\n}\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/javascript/adrs1166ma.js",
    "content": "/*\nEJERCICIO:\n¡La temporada 2 de \"Los Anillos de Poder\" está a punto de estrenarse! \n¿Qué pasaría si tuvieras que encargarte de repartir los anillos\nentre las razas de la Tierra Media?\nDesarrolla un programa que se encargue de distribuirlos.\nRequisitos:\n1. Los Elfos recibirán un número impar.\n2. Los Enanos un número primo.\n3. Los Hombres un número par.\n4. Sauron siempre uno.\nAcciones:\n1. Crea un programa que reciba el número total de anillos\n   y busque una posible combinación para repartirlos.\n2. Muestra el reparto final o el error al realizarlo.\n */\n// 🔥 SIMULADOR: Reparto de los Anillos de Poder 🔥\nconsole.log(\"💍 ¡Bienvenido al repartidor de los Anillos de Poder! 💍\");\n\n// Función principal del programa\nfunction repartirAnillos() {\n    const totalAnillos = parseInt(prompt(\"Ingrese el número total de anillos: \"));\n\n    if (isNaN(totalAnillos) || totalAnillos <= 0) {\n        console.log(\"❌ El número de anillos debe ser un entero positivo.\");\n        return;\n    }\n\n    // Sauron siempre recibe 1 anillo\n    const sauron = 1;\n    const anillosRestantes = totalAnillos - sauron;\n\n    // Buscar combinaciones válidas\n    for (let elfos = 1; elfos < anillosRestantes; elfos += 2) { // Número impar para Elfos\n        for (let enanos = 2; enanos < anillosRestantes; enanos++) { // Número primo para Enanos\n            if (!esPrimo(enanos)) continue;\n\n            const hombres = anillosRestantes - (elfos + enanos); // Número par para Hombres\n            if (hombres > 0 && hombres % 2 === 0) {\n                console.log(\"\\n--- REPARTO FINAL ---\");\n                console.log(`Elfos: ${elfos} (número impar)`);\n                console.log(`Enanos: ${enanos} (número primo)`);\n                console.log(`Hombres: ${hombres} (número par)`);\n                console.log(`Sauron: ${sauron}`);\n                return;\n            }\n        }\n    }\n\n    // Si no se encuentra una combinación válida\n    console.log(\"❌ No es posible repartir los anillos con las reglas dadas.\");\n}\n\n// Función para verificar si un número es primo\nfunction esPrimo(numero) {\n    if (numero < 2) return false;\n    for (let i = 2; i <= Math.sqrt(numero); i++) {\n        if (numero % i === 0) return false;\n    }\n    return true;\n}\n\nrepartirAnillos();"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/javascript/duendeintemporal.js",
    "content": "\n//#35 - REPARTIENDO LOS ANILLOS DEL PODER\n/*\n * EJERCICIO:\n * ¡La temporada 2 de \"Los Anillos de Poder\" está a punto de estrenarse!\n * ¿Qué pasaría si tuvieras que encargarte de repartir los anillos\n * entre las razas de la Tierra Media?\n * Desarrolla un programa que se encargue de distribuirlos.\n * Requisitos:\n * 1. Los Elfos recibirán un número impar.\n * 2. Los Enanos un número primo.\n * 3. Los Hombres un número par.\n * 4. Sauron siempre uno.\n * Acciones:\n * 1. Crea un programa que reciba el número total de anillos\n *    y busque una posible combinación para repartirlos.\n * 2. Muestra el reparto final o el error al realizarlo.\n */\n\nconst log = console.log;\n\n// Function to check if a number is prime\nconst isPrime = (num) => {\n    if (num <= 1) return false; // Numbers less than or equal to 1 are not prime\n    if (num <= 3) return true; // 2 and 3 are prime numbers\n    if (num % 2 === 0 || num % 3 === 0) return false; // Eliminate even numbers and multiples of 3\n\n    // Check for factors from 5 to the square root of num\n    for (let i = 5; i * i <= num; i += 6) {\n        if (num % i === 0 || num % (i + 2) === 0) return false; // Check i and i + 2\n    }\n    return true; // If no factors were found, num is prime\n};\n\n// Function to find the largest prime number less than a given number\nconst firstPrime = (num) => {\n    for (let i = num - 1; i >= 2; i--) {\n        if (isPrime(i)) return i; // Return the first prime found\n    }\n    return 2; // Return 2 if no prime found (should not happen for valid input)\n};\n\nconst isOdd = (num) => {\n    return num % 2 !== 0; // Return true if the number is odd\n};\n\n// Function to assign rings based on the rules\nfunction assignRings(num) {\n    // Check if the number of rings is odd and greater than or equal to 7\n    if (!isOdd(num) || num < 7) {\n        log('The number of rings must be an odd number and greater than or equal to 7');\n        start(); // Prompt for input again\n        return;\n    }\n\n    let arr_of_rings = [0, 0, 0, 1]; // Sauron always gets 1 ring\n    let fPrime = firstPrime(num); // Find the largest prime less than num\n    let r = num - fPrime; // Remaining rings after giving to Dwarves\n\n    // Adjust remaining rings if less than 4\n    if (r < 4) {\n        fPrime = firstPrime(num - 3)\n        r = num - fPrime; \n    }\n\n    // Distribute rings based on the remaining count\n    if (r === 4) {\n        arr_of_rings[0] = (r / 2) - 1; // Elves\n        arr_of_rings[1] = fPrime;      // Dwarves\n        arr_of_rings[2] = r / 2;        // Men\n    } else if (r === 6) {\n        arr_of_rings[0] = Math.round(((r - 1) / 2)); // Elves\n        arr_of_rings[1] = fPrime;      // Dwarves\n        arr_of_rings[2] = Math.floor((r - 1) / 2); // Men\n    } else if (r === 8) {\n        arr_of_rings[0] = Math.floor((r - 1) / 2); // Elves\n        arr_of_rings[1] = fPrime;      // Dwarves\n        arr_of_rings[2] = Math.round(((r - 1) / 2)); // Men\n    } else {\n        // Alternative distribution logic for other values of r\n        alternativeDistribution(arr_of_rings, fPrime, r);\n    }\n\n    // Output the distribution of rings\n    log('\\n');\n    log(`${arr_of_rings[0]} rings to: Elves, ${arr_of_rings[1]} rings to: Dwarves, ${arr_of_rings[2]} rings to: Men, and ${arr_of_rings[3]} ring to: Sauron`);\n    rl.close(); // Close the readline interface after showing the result\n}\n\nfunction alternativeDistribution(arr_of_rings, fPrime, r) {\n    // Dwarves get the prime\n    arr_of_rings[1] = fPrime; // Dwarves\n    arr_of_rings[3] = 1; // Sauron gets 1 ring\n\n    // Calculate remaining rings after assigning to Dwarves and Sauron\n    let remainingForElvesAndMen = r - arr_of_rings[3]; // Only subtract Sauron's ring\n\n    // Ensure Elves get an odd number and Men get an even number\n    \n    if(isOdd(remainingForElvesAndMen)){\n        arr_of_rings[0] = Math.max(1, Math.round(remainingForElvesAndMen / 2)); // Ensure Elves get an odd number\n        arr_of_rings[2] = remainingForElvesAndMen - arr_of_rings[0]; // Calculate remaining rings for Men\n    }else{\n        log(\"It's not possible to do the distribution accordly with the getRandomValues.\");\n    }\n        \n\n}\n\n// Set up readline interface for user input\nconst readline = require(\"readline\");\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout,\n});\n\n// Function to start the input process\nconst start = () => {\n    rl.question('Indicate the number of rings to distribute: ', (answer) => {\n        let totalRings = parseInt(answer); \n        if (!isNaN(totalRings)) {\n            assignRings(totalRings); \n        } else {\n            log('Please enter a valid number.'); // Prompt for valid input\n            start(); // Prompt again for valid input\n        }\n    });\n};\n\nconsole.clear(); \nstart(); \n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/javascript/hectorio23.js",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\nfunction isPrime(n) {\n    if (n <= 1) return false;\n    for (let i = 2; i <= Math.sqrt(n); i++) {\n        if (n % i === 0) return false;\n    }\n    return true;\n}\n\nfunction distributeRings(totalRings) {\n    const sauronRings = 1;\n    let remainingRings = totalRings - sauronRings;\n\n    // Try different combinations for elves and dwarves\n    for (let elvesRings = 1; elvesRings < remainingRings; elvesRings += 2) {  // Elves get odd numbers\n        for (let dwarvesRings = 2; dwarvesRings < remainingRings; dwarvesRings++) {\n            if (isPrime(dwarvesRings)) {  // Dwarves get prime numbers\n                const humansRings = remainingRings - elvesRings - dwarvesRings;\n                if (humansRings > 0 && humansRings % 2 === 0) {  // Humans get even numbers\n                    return {\n                        Elves: elvesRings,\n                        Dwarves: dwarvesRings,\n                        Humans: humansRings,\n                        Sauron: sauronRings\n                    };\n                }\n            }\n        }\n    }\n    return \"Error: No valid distribution found.\";\n}\n\n// Example usage\nconst totalRings = 20;\nconsole.log(distributeRings(totalRings));\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n_______________________________________________________\n#35 REPARTIENDO LOS ANILLOS DE PODER\n-------------------------------------------------------\n * EJERCICIO:\n * ¡La temporada 2 de \"Los Anillos de Poder\" está a punto de estrenarse! \n * ¿Qué pasaría si tuvieras que encargarte de repartir los anillos\n * entre las razas de la Tierra Media?\n * Desarrolla un programa que se encargue de distribuirlos.\n * Requisitos:\n * 1. Los Elfos recibirán un número impar.\n * 2. Los Enanos un número primo.\n * 3. Los Hombres un número par.\n * 4. Sauron siempre uno.\n * Acciones:\n * 1. Crea un programa que reciba el número total de anillos\n *    y busque una posible combinación para repartirlos.\n * 2. Muestra el reparto final o el error al realizarlo.\n*/\n// ________________________________________________________\n\nconst readline = require(\"readline\");\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout,\n});\n\nconst getInput = async (prompt) => {\n  return new Promise((resolve) => {\n    rl.question(prompt, (input) => {\n      resolve(input.trim());\n    });\n  });\n};\n\nconst getTotalRings = async () => {\n  while (true) {\n    const input_ = await getInput(\"Cantidad de anillos: \");\n    const total = parseInt(input_, 10);\n    if (!isNaN(total) && total >= 1) {\n      return total;\n    }\n    console.log(\"Debe ser un valor entero '>= 1'.\");\n  }\n};\n\nconst isPrime = (n) => {\n  if (n < 2) return false;\n  for (let i = 2; i <= Math.sqrt(n); i++) {\n    if (n % i === 0) return false;\n  }\n  return true;\n};\n\nconst distribute = (total) => {\n  const combinations = [];\n  for (let elves = 1; elves < total; elves += 2) {\n    for (let men = 2; men < total; men += 2) {\n      const dwarves = total - (men + elves);\n      if (dwarves > 0 && isPrime(dwarves)) {\n        combinations.push([elves, men, dwarves]);\n      }\n    }\n  }\n  return combinations;\n};\n\nconst standardDeviation = (tuple) => {\n  const mean = tuple.reduce((sum, val) => sum + val, 0) / tuple.length;\n  const variance =\n    tuple.reduce((sum, val) => sum + Math.pow(val - mean, 2), 0) /\n    tuple.length;\n  return Math.sqrt(variance);\n};\n\nconst theMostBalanced = (combinations) => {\n  const deviations = combinations.map(standardDeviation);\n  const indexOfLeastDeviation = deviations.indexOf(Math.min(...deviations));\n  return combinations[indexOfLeastDeviation];\n};\n\nconst printResult = (distribution, sauron) => {\n  if (!distribution) {\n    console.log(\"Error en la selección equitativa.\");\n    return;\n  }\n\n  const [elves, men, dwarves] = distribution;\n  console.log(\"_________________________\");\n  console.log(`Elfos   -> ${elves} : # Impar`);\n  console.log(`Enanos  -> ${dwarves} : # Primo`);\n  console.log(`Hombres -> ${men} : # Par`);\n  console.log(`Sauron  -> ${sauron} : # Fijo`);\n  console.log(\"-------------------------\");\n};\n\nconst main = async () => {\n  console.log(\"REPARTIENDO LOS ANILLOS DE PODER\");\n  let total = await getTotalRings();\n  const sauron = 1;\n  total -= sauron;\n\n  const combinations = distribute(total);\n\n  if (combinations.length === 0) {\n    console.log(\"No existe una combinación posible.\");\n    rl.close();\n    return;\n  }\n\n  const distribution = theMostBalanced(combinations);\n  printResult(distribution, sauron);\n\n  rl.close();\n};\n\nmain();\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/javascript/miguelex.js",
    "content": "function esPrimo(num) {\n    if (num <= 1) return false;\n    if (num === 2) return true;\n    if (num % 2 === 0) return false;\n    \n    for (let i = 3; i <= Math.sqrt(num); i += 2) {\n        if (num % i === 0) return false;\n    }\n    return true;\n}\n\nfunction repartirAnillos(totalAnillos) {\n    if (totalAnillos < 4) {\n        return \"Error: No hay suficientes anillos para cumplir con los requisitos.\";\n    }\n\n    let anillosSauron = 1;\n    totalAnillos -= 1;\n    \n    let mejorDiferencia = Number.MAX_SAFE_INTEGER;\n    let mejorReparto = null;\n    \n    for (let anillosElfos = 1; anillosElfos <= totalAnillos; anillosElfos += 2) {\n        for (let anillosEnanos = 2; anillosEnanos <= totalAnillos; anillosEnanos++) {\n            if (esPrimo(anillosEnanos)) {\n                let anillosHombres = totalAnillos - anillosElfos - anillosEnanos;\n                \n                if (anillosHombres > 0 && anillosHombres % 2 === 0) {\n                    let diferencia = Math.max(anillosElfos, anillosEnanos, anillosHombres) - Math.min(anillosElfos, anillosEnanos, anillosHombres);\n                    \n                    if (diferencia < mejorDiferencia) {\n                        mejorDiferencia = diferencia;\n                        mejorReparto = {\n                            Elfos: anillosElfos,\n                            Enanos: anillosEnanos,\n                            Hombres: anillosHombres,\n                            Sauron: anillosSauron\n                        };\n                    }\n                }\n            }\n        }\n    }\n    \n    if (mejorReparto) {\n        return `Reparto exitoso: Elfos = ${mejorReparto.Elfos}, Enanos = ${mejorReparto.Enanos}, Hombres = ${mejorReparto.Hombres}, Sauron = ${mejorReparto.Sauron}`;\n    } else {\n        return \"Error: No se encontró una combinación válida para repartir los anillos.\";\n    }\n}\n\nconst totalAnillos = 25;\nconst resultado = repartirAnillos(totalAnillos);\nconsole.log(resultado);\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/javascript/nlarrea.js",
    "content": "/**\n * EJERCICIO:\n * ¡La temporada 2 de \"Los Anillos de Poder\" está a punto de estrenarse!\n * ¿Qué pasaría si tuvieras que encargarte de repartir los anillos\n * entre las razas de la Tierra Media?\n * Desarrolla un programa que se encargue de distribuirlos.\n * Requisitos:\n * 1. Los Elfos recibirán un número impar.\n * 2. Los Enanos un número primo.\n * 3. Los Hombres un número par.\n * 4. Sauron siempre uno.\n * Acciones:\n * 1. Crea un programa que reciba el número total de anillos\n *    y busque una posible combinación para repartirlos.\n * 2. Muestra el reparto final o el error al realizarlo.\n */\n\nconst readline = require('readline');\n\nconst rl = readline.createInterface({\n\tinput: process.stdin,\n\toutput: process.stdout,\n});\n\nfunction isEven(number) {\n\treturn number % 2 === 0;\n}\n\nfunction isPrime(number) {\n\tif (number < 2) {\n\t\treturn false;\n\t}\n\n\tconst range = Array.from('x'.repeat(number - 2), (_, i) => 2 + i);\n\tfor (const n of range) {\n\t\tif (number % parseInt(n) === 0) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n\nfunction oddNumbers(number) {\n\tconst range = Array.from('x'.repeat(number - 1), (_, i) => 1 + i);\n\treturn range.filter((n) => !isEven(n));\n}\n\nfunction evenNumbers(number) {\n\tconst range = Array.from('x'.repeat(number - 1), (_, i) => 1 + i);\n\treturn range.filter((n) => isEven(n));\n}\n\nfunction combineOptions(totalRings) {\n\tconst solution = [];\n\n\t// Give one ring to Sauron\n\ttotalRings--;\n\n\t// Get possible values for the rest of the races\n\tfor (const man of evenNumbers(totalRings)) {\n\t\tfor (const elf of oddNumbers(totalRings)) {\n\t\t\tconst dwarf = totalRings - elf - man;\n\t\t\tif (dwarf > 0 && isPrime(dwarf)) {\n\t\t\t\tsolution.push({\n\t\t\t\t\telfos: elf,\n\t\t\t\t\tenanos: dwarf,\n\t\t\t\t\thombres: man,\n\t\t\t\t\tsauron: 1,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\treturn solution;\n}\n\nfunction printResult(results) {\n\tif (results.length === 0) {\n\t\tconsole.log('No se ha encontrado ninguna solución.');\n\t\treturn;\n\t}\n\n\tlet counter = 1;\n\twhile (results.length > 0) {\n\t\tconst result = results.shift();\n\n\t\tconsole.log(`\\nSOLUCIÓN ${counter}:`);\n\t\tfor (const race in result) {\n\t\t\tconsole.log(\n\t\t\t\t`${race[0].toUpperCase() + race.slice(1)}: ${result[race]}`\n\t\t\t);\n\t\t}\n\t\tcounter++;\n\t}\n}\n\nfunction run() {\n\trl.question(\n\t\t'Introduce la cantidad de anillos a repartir:\\n > ',\n\t\t(rings) => {\n\t\t\tconst totalRings = parseInt(rings, 10);\n\n\t\t\tconst results = combineOptions(totalRings);\n\t\t\tprintResult(results);\n\n\t\t\trl.close();\n\t\t}\n\t);\n}\n\nrun();\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/javascript/pedamoci.js",
    "content": "import readline from \"readline\"\n\nconst colors = {\n  red: \"\\x1b[31m\",\n  green: \"\\x1b[32m\",\n  yellow: \"\\x1b[33m\",\n  cyan: \"\\x1b[34m\",\n  reset: \"\\x1b[0m\",\n}\n\nclass Asks {\n  constructor() {\n    this.readline = readline.createInterface({\n      input: process.stdin,\n      output: process.stdout\n    })\n  }\n\n  #ask(question) {\n    return new Promise(resolve => {\n      this.readline.question(question, (answer) => resolve(answer))\n    })\n  }\n\n  close() {\n    this.readline.close()\n  }\n\n  async askLabel(label) {\n    const response = await this.#ask(colors.cyan + `Enter the ${label}: ` + colors.reset)\n    return response\n  }\n}\n\nclass Renderer {\n  static error(message) {\n    console.log(colors.red + \"Error: \" + message + colors.reset)\n  }\n\n  static success(message) {\n    console.log(colors.green + \"Success: \" + message + colors.reset)\n  }\n\n  static info(ringSauron, ringsElfs, ringsDwarf, ringsHumans) {\n    console.log(colors.yellow + \n                `\\nSauron: ${ringSauron}`+ \n                `\\nElfs: ${ringsElfs}`+ \n                `\\nDwarfs: ${ringsDwarf}`+ \n                `\\nHumans: ${ringsHumans}` + colors.reset)\n  }\n}\n\nconst asks = new Asks()\n\nclass DistributionRings {\n  constructor() {\n    this.ringsElfs\n    this.ringsHumans\n    this.ringsDwarf\n    this.ringSauron\n    this.rings\n  }\n\n  assingRings(num) {\n    this.rings = num\n  }\n\n  assingOneSauron(){\n    this.rings--\n    this.ringSauron = 1\n  }\n\n  assingPrimeNumberDwarf(){\n    let dividing = Math.floor(Math.sqrt(this.rings))\n\n    while (dividing > 1) {\n      if (this.rings % dividing === 0) return false\n      dividing--\n    }\n\n    this.ringsDwarf = this.rings\n    this.rings -= this.ringsDwarf\n    return true\n  }\n\n  assingOddNumberElfs(){\n    let num = Math.floor(Math.random() * (this.rings - 4) + 1)\n\n    if (num % 2 === 0) num--\n\n    this.ringsElfs = num\n    this.rings -= this.ringsElfs\n  }\n\n  assingEvenNumberHumans() {\n    let num = Math.floor(Math.random() * (this.rings - 4) + 2)\n\n    if (num % 2 !== 0) num--\n\n    this.ringsHumans = num\n    this.rings -= this.ringsHumans\n  }\n\n  startDistribution() {\n    if (Math.random() > 0.5) {\n      this.assingEvenNumberHumans()\n      this.assingOddNumberElfs()\n    } else {\n      this.assingOddNumberElfs()\n      this.assingEvenNumberHumans()\n    }\n    this.checkDistribution()\n  }\n\n  checkDistribution() {\n    while (this.rings !== 0) {\n      if (this.rings % 2 === 0){\n        this.ringsDwarf = 2\n\n        if (Math.random() > 0.5) {\n          this.ringsElfs += (this.rings - 2)\n          this.rings = 0\n        } else {\n          this.ringsHumans += (this.rings - 2)\n          this.rings = 0\n        }\n      } else if (!this.assingPrimeNumberDwarf()){\n        if (Math.random() > 0.5) {\n          this.ringsElfs += 2\n          this.rings -= 2\n        } else {\n          this.ringsHumans += 2\n          this.rings -= 2\n        }\n      }\n    }\n  }\n}\n\nclass ControllerDistribution {\n  constructor(distributionRings) {\n    this.distributionRings = distributionRings\n  }\n\n  async start(){\n    const rings = Number.parseInt(await asks.askLabel(\"number of rings\"))\n\n    if (!(rings >= 6)) {\n      Renderer.error(\"The number of rings must be greater than or equal to 6\")\n      return this.start()\n    }\n\n    this.distributionRings.rings = rings\n\n    this.distributionRings.assingOneSauron()\n\n    this.distributionRings.startDistribution()\n\n    Renderer.success(\"The rings have been distributed correctly\")\n    Renderer.info(this.distributionRings.ringSauron, this.distributionRings.ringsElfs, this.distributionRings.ringsDwarf, this.distributionRings.ringsHumans)\n    asks.close()\n  }\n}\n\nconst controllerDistribution = new ControllerDistribution(new DistributionRings)\ncontrollerDistribution.start()"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/javascript/redom69.js",
    "content": "\n/*\n * EJERCICIO:\n * ¡La temporada 2 de \"Los Anillos de Poder\" está a punto de estrenarse! \n * ¿Qué pasaría si tuvieras que encargarte de repartir los anillos\n * entre las razas de la Tierra Media?\n * Desarrolla un programa que se encargue de distribuirlos.\n * Requisitos:\n * 1. Los Elfos recibirán un número impar.\n * 2. Los Enanos un número primo.\n * 3. Los Hombres un número par.\n * 4. Sauron siempre uno.\n * Acciones:\n * 1. Crea un programa que reciba el número total de anillos\n *    y busque una posible combinación para repartirlos.\n * 2. Muestra el reparto final o el error al realizarlo.\n */\n\n\nconst readline = require('readline');\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nfunction isPrime(n){\n    if (n<=1) return false\n    if (n<=3) return true\n    if (n % 2 == 0 || n % 3 == 0) return false\n    let i=5;\n    while (i*i<=n){\n        if (n % i == 0 || n % (i + 2) == 0) return false\n        i += 6\n    }\n    return true\n}\n\nfunction findAllPrimes(max_n){\n    let primes = [];\n    for (let i = 2; i <= max_n; i++) {\n        if (isPrime(i)) {\n            primes.push(i);\n        }\n    }\n    return primes;\n}\n\nfunction findAllEvens(max_n){\n    let pars = [];\n    for (let i = 2; i <= max_n; i += 2) {\n        pars.push(i);\n    }\n    return pars;\n}\n\nfunction findAllOdds(max_n){\n    let odds = [];\n    for (let i = 1; i <= max_n; i += 2) {\n        odds.push(i);\n    }\n    return odds;\n}\n\nfunction distributeRings(rings) {\n    rings = parseInt(rings) - 1; // Uno es siempre para Sauron\n    if (rings < 3) {\n        console.log(\"El número de anillos es insuficiente para cumplir con los requisitos.\");\n        return null;\n    }\n\n    const primes = findAllPrimes(rings);\n    const odds = findAllOdds(rings);\n    const pars = findAllEvens(rings);\n\n    let bestDistribution = null;\n\n    for (let dwarf_rings of primes) {\n        for (let elf_rings of odds) {\n            for (let human_rings of pars) {\n                if (dwarf_rings + elf_rings + human_rings === rings) {\n                    let currentDistribution = {\n                        \"Enanos\": dwarf_rings,\n                        \"Elfos\": elf_rings,\n                        \"Humanos\": human_rings,\n                        \"Sauron\": 1\n                    };\n                    if (!bestDistribution || (\n                        currentDistribution[\"Enanos\"] + currentDistribution[\"Elfos\"] + currentDistribution[\"Humanos\"] >\n                        bestDistribution[\"Enanos\"] + bestDistribution[\"Elfos\"] + bestDistribution[\"Humanos\"]\n                    )) {\n                        bestDistribution = currentDistribution;\n                    }\n                }\n            }\n        }\n    }\n\n    if (bestDistribution) {\n        return bestDistribution;\n    } else {\n        console.log(\"No se pudo encontrar una distribución válida.\");\n        return null;\n    }\n}\n\n\nfunction printDistribution(distribution) {\n    for (let race in distribution) {\n        console.log(`${race}: ${distribution[race]} anillos`);\n    }\n}\n\nrl.question('Introduce el número de anillos de poder: ', (rings) => {\n    console.log(`Has introducido: ${rings}`);\n    const distribution =  distributeRings(rings)\n    if (distribution){\n        printDistribution(distribution)\n    }else{\n        print('No se han podido repartir los anillos correctamente.')\n    }\n    rl.close();\n});\n\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/kotlin/blackriper.kt",
    "content": "\r\n//1.-Definir estructura de datos para guardar valores\r\nval ringList= mutableMapOf(\r\n    \"elves\" to 0,\r\n    \"dwarves\" to 0,\r\n    \"humans\" to 0,\r\n    \"sauron\" to 1\r\n)\r\n\r\n\r\n//2.- Definir funcion auxilares\r\n\r\nfun String.capitalizeWord():String {\r\n    return replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() }\r\n}\r\n\r\nfun isPrime(num: Int): Boolean {\r\n    if (num<=1) return false\r\n    for (i in 2..num / 2) {\r\n        if (num % i == 0) {\r\n            return false\r\n        }\r\n    }\r\n    return true\r\n}\r\n\r\nfun numberRings():Int{\r\n    var numRings=0\r\n    while (numRings<=0) {\r\n        println(\"Enter number of rings: \")\r\n        numRings= readLine()?.let { it.toInt() - 1 } ?: 0\r\n        if (numRings<0) println(\"Number of rings must be greater than 0\")\r\n     }\r\n    return numRings\r\n}\r\n\r\nfun repartitionRings(numRings:Int) {\r\n    var elves=0\r\n    var dwarves=0\r\n    var humans=0\r\n\r\n   for (i in 1.. numRings){\r\n       if (i%2==0) elves++\r\n       else if(isPrime(i)) dwarves++\r\n       else humans++\r\n   }\r\n   ringList[\"elves\"]=elves\r\n   ringList[\"dwarves\"]=dwarves\r\n   ringList[\"humans\"]=humans\r\n\r\n}\r\n\r\nfun printResults(){\r\n    ringList.forEach { specie, numRings ->\r\n        println(\"${specie.capitalizeWord()} has $numRings rings\")\r\n    }\r\n}\r\n\r\n\r\n\r\nfun main() {\r\n    val numRings=numberRings()\r\n    repartitionRings(numRings)\r\n    printResults()\r\n}"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/kotlin/miguelex.kt",
    "content": "fun esPrimo(num: Int): Boolean {\n    if (num <= 1) return false\n    if (num == 2) return true\n    if (num % 2 == 0) return false\n\n    for (i in 3..Math.sqrt(num.toDouble()).toInt() step 2) {\n        if (num % i == 0) return false\n    }\n    return true\n}\n\nfun repartirAnillos(totalAnillos: Int): String {\n    if (totalAnillos < 4) {\n        return \"Error: No hay suficientes anillos para cumplir con los requisitos.\"\n    }\n\n    val anillosSauron = 1\n    var totalAnillosRestantes = totalAnillos - 1\n\n    var mejorDiferencia = Int.MAX_VALUE\n    var mejorReparto: IntArray? = null\n\n    for (anillosElfos in 1..totalAnillosRestantes step 2) {\n        for (anillosEnanos in 2..totalAnillosRestantes) {\n            if (esPrimo(anillosEnanos)) {\n                val anillosHombres = totalAnillosRestantes - anillosElfos - anillosEnanos\n\n                if (anillosHombres > 0 && anillosHombres % 2 == 0) {\n                    val diferencia = maxOf(anillosElfos, anillosEnanos, anillosHombres) -\n                                     minOf(anillosElfos, anillosEnanos, anillosHombres)\n\n                    if (diferencia < mejorDiferencia) {\n                        mejorDiferencia = diferencia\n                        mejorReparto = intArrayOf(anillosElfos, anillosEnanos, anillosHombres, anillosSauron)\n                    }\n                }\n            }\n        }\n    }\n\n    return if (mejorReparto != null) {\n        \"Reparto exitoso: Elfos = ${mejorReparto[0]}, Enanos = ${mejorReparto[1]}, Hombres = ${mejorReparto[2]}, Sauron = ${mejorReparto[3]}\"\n    } else {\n        \"Error: No se encontró una combinación válida para repartir los anillos.\"\n    }\n}\n\nfun main() {\n    print(\"Ingresa el número total de anillos: \")\n    val totalAnillos = readLine()?.toIntOrNull() ?: 0\n\n    val resultado = repartirAnillos(totalAnillos)\n    println(resultado)\n}\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/php/miguelex.php",
    "content": "<?php\n\nfunction esPrimo($num) {\n    if ($num <= 1) return false;\n    if ($num == 2) return true;\n    if ($num % 2 == 0) return false;\n    \n    for ($i = 3; $i <= sqrt($num); $i += 2) {\n        if ($num % $i == 0) return false;\n    }\n    return true;\n}\n\nfunction repartirAnillos($totalAnillos) {\n    if ($totalAnillos < 4) {\n        return \"Error: No hay suficientes anillos para cumplir con los requisitos.\";\n    }\n\n    $anillosSauron = 1;\n    $totalAnillos -= 1;\n    \n    $mejorDiferencia = PHP_INT_MAX;\n    $mejorReparto = null;\n    \n    for ($anillosElfos = 1; $anillosElfos <= $totalAnillos; $anillosElfos += 2) {\n        for ($anillosEnanos = 2; $anillosEnanos <= $totalAnillos; $anillosEnanos++) {\n            if (esPrimo($anillosEnanos)) {\n                $anillosHombres = $totalAnillos - $anillosElfos - $anillosEnanos;\n                \n                if ($anillosHombres > 0 && $anillosHombres % 2 == 0) {\n                    $diferencia = max($anillosElfos, $anillosEnanos, $anillosHombres) - min($anillosElfos, $anillosEnanos, $anillosHombres);\n                    \n                    if ($diferencia < $mejorDiferencia) {\n                        $mejorDiferencia = $diferencia;\n                        $mejorReparto = [\n                            'Elfos' => $anillosElfos,\n                            'Enanos' => $anillosEnanos,\n                            'Hombres' => $anillosHombres,\n                            'Sauron' => $anillosSauron\n                        ];\n                    }\n                }\n            }\n        }\n    }\n    \n    if ($mejorReparto) {\n        return \"Reparto exitoso: Elfos = {$mejorReparto['Elfos']}, Enanos = {$mejorReparto['Enanos']}, Hombres = {$mejorReparto['Hombres']}, Sauron = {$mejorReparto['Sauron']}\";\n    } else {\n        return \"Error: No se encontró una combinación válida para repartir los anillos.\";\n    }\n}\n\necho \"Ingresa el número total de anillos: \";\n$totalAnillos = intval(readline());\n\n$resultado = repartirAnillos($totalAnillos);\necho $resultado;\n\n\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/python/CesarCarmona30.py",
    "content": "import math\n\ndef is_prime(num):\n    if num <= 1 or (num % 2 == 0 and num > 2):\n        return False\n    return all(num % i for i in range(3, int(math.sqrt(num)) + 1, 2))\n\ndef prime_below_half(n):\n    for i in range(n-1, 1, -1):\n        if is_prime(i):\n            return i\n    return 2 \n\ndef distribute_rings(rings):\n    if rings < 6:\n        return \"No hay suficientes anillos para repartir, deben ser por lo menos 6.\"\n    \n    half = rings // 2\n    dwarves = prime_below_half(half)\n    sauron = 1\n    remaining = rings - dwarves - sauron  \n    \n    elves = (remaining // 2) | 1  \n    men = remaining - elves \n    \n    return f'''Anillos totales: {rings}\n    Cantidad por grupo:\n      Elfos   - {elves}\n      Enanos  - {dwarves}\n      Hombres - {men}\n      Sauron  - {sauron}\n    '''\n\n# Usage examples\nprint(distribute_rings(4))\nprint(distribute_rings(5))\nprint(distribute_rings(6))\nprint(distribute_rings(10))\nprint(distribute_rings(20))\nprint(distribute_rings(30))\nprint(distribute_rings(40))\nprint(distribute_rings(97))\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/python/DavidVilem.py",
    "content": "import math\r\n\r\ndef es_primo(n):\r\n    if n <= 1:\r\n        return False\r\n    if n <= 3:\r\n        return True\r\n    if n % 2 == 0 or n % 3 == 0:\r\n        return False\r\n    i = 5\r\n    while i * i <= n:\r\n        if n % i == 0 or n % (i + 2) == 0:\r\n            return False\r\n        i += 6\r\n    return True\r\n\r\ndef distribuir_anillos(total_anillos):\r\n    if total_anillos < 4:\r\n        return \"Error: No es posible repartir los anillos con las reglas dadas.\"\r\n    \r\n    anillos_distribuidos = {\r\n        \"Elfos\": [],\r\n        \"Enanos\": [],\r\n        \"Hombres\": [],\r\n        \"Sauron\": [total_anillos]\r\n    }\r\n\r\n    total_anillos -= 1\r\n    numero_actual = 0\r\n    numeros_asignados = set()\r\n\r\n    # Asignar los anillos en ciclos hasta que se acaben\r\n    while total_anillos > 0:\r\n        cambios_realizados = False\r\n\r\n        # Asignar a los Elfos (impar)\r\n        if total_anillos > 0 and numero_actual % 2 != 0:\r\n            anillos_distribuidos[\"Elfos\"].append(numero_actual)\r\n            numeros_asignados.add(numero_actual)\r\n            total_anillos -= 1\r\n            cambios_realizados = True\r\n\r\n        # Incrementar al siguiente número\r\n        numero_actual += 1\r\n\r\n        # Asignar a los Enanos (primo)\r\n        if total_anillos > 0 and es_primo(numero_actual):\r\n            anillos_distribuidos[\"Enanos\"].append(numero_actual)\r\n            numeros_asignados.add(numero_actual)\r\n            total_anillos -= 1\r\n            cambios_realizados = True\r\n\r\n        # Incrementar al siguiente número\r\n        numero_actual += 1\r\n\r\n        # Asignar a los Hombres (par)\r\n        if total_anillos > 0 and numero_actual % 2 == 0:\r\n            anillos_distribuidos[\"Hombres\"].append(numero_actual)\r\n            numeros_asignados.add(numero_actual)\r\n            total_anillos -= 1\r\n            cambios_realizados = True\r\n\r\n        # Incrementar al siguiente número\r\n        numero_actual += 1\r\n\r\n        # Si no se realizaron cambios en un ciclo, detener el proceso\r\n        if not cambios_realizados:\r\n            break\r\n\r\n    return anillos_distribuidos\r\n\r\ndef formatear_salida(anillos_distribuidos):\r\n    for raza, numeros in anillos_distribuidos.items():\r\n        cantidad = len(numeros)\r\n        numeros_asignados = ', '.join(map(str, numeros))\r\n        print(f\"Raza: {raza}, Cantidad: {cantidad}, Números: {numeros_asignados}\")\r\n\r\nif __name__ == \"__main__\":\r\n    total_anillos = int(input(\"Introduce el número total de anillos a distribuir: \"))\r\n    resultado = distribuir_anillos(total_anillos)\r\n    formatear_salida(resultado)\r\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/python/EmmanuelMMontesinos.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * ¡La temporada 2 de \"Los Anillos de Poder\" está a punto de estrenarse! \n * ¿Qué pasaría si tuvieras que encargarte de repartir los anillos\n * entre las razas de la Tierra Media?\n * Desarrolla un programa que se encargue de distribuirlos.\n * Requisitos:\n * 1. Los Elfos recibirán un número impar.\n * 2. Los Enanos un número primo.\n * 3. Los Hombres un número par.\n * 4. Sauron siempre uno.\n * Acciones:\n * 1. Crea un programa que reciba el número total de anillos\n *    y busque una posible combinación para repartirlos.\n * 2. Muestra el reparto final o el error al realizarlo.\n */\n\"\"\"\nclass Anillos:\n\n    def __init__(self,total) -> None:\n        self.total = int(total)\n        self.dar_anillos()\n    \n    def dar_anillos(self):\n        restantes = self.total\n        contador = 1\n        sauron = 1\n        restantes -= sauron\n        primos = self.generar_primos(restantes)\n        if primos:\n            for num in primos:\n                posible = restantes - num\n                if posible % 2 != 0:\n                    enanos = num\n                    humanos = posible // 2\n                    elfos = posible - humanos\n                    if enanos + humanos + elfos + sauron == self.total and humanos % 2 == 0 and humanos > 0:\n                        print(f\"Posible reparto de {self.total} anillos de poder Nº {contador}:\")\n                        print(f\"Elfos: {elfos}, Enanos: {enanos}, Humanos: {humanos}, Sauron: {sauron}\")\n                        print()\n                        contador += 1\n        if contador == 1:\n            print(f\"{self.total} no pueden repartirse\")\n\n    def generar_primos(self,restante):\n        es_primo = [True] * (restante + 1)\n        p = 2\n        while p ** 2 <= restante:\n            if es_primo[p]:\n                for i in range(p * p, restante + 1, p):\n                    es_primo[i] = False\n            p += 1\n        primos = [p for p in range(2, restante + 1) if es_primo[p]]\n        return primos\n\n# Pruebas\nAnillos(12)\nAnillos(20)\nAnillos(150)\nAnillos(251)\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/python/Gordo-Master.py",
    "content": "# 35 - Repartiendo los anillos del poder\n\ndef is_prime(number) -> bool:\n    for i in range(2, int(number ** 0.5)+1):\n        if number % i == 0:\n            return False\n    else:\n        return True\n\ndef distr_rings(rings):\n\n    sauron = 1\n    rings -= sauron\n\n    distributed_rings = []\n\n    for humans in range(2, rings, 2):\n        for elves in range(1, rings, 2):\n            dwarfs = rings - humans - elves\n            if dwarfs > 0 and is_prime(dwarfs):\n                distributed_rings.append({\n                    \"Sauron\" : sauron,\n                    \"Elfs\" : elves,\n                    \"Dwarfs\" : dwarfs,\n                    \"Humans\" : humans\n                    }\n                )\n    \n    if distributed_rings:\n        return distributed_rings\n    else:\n        print(\"No se puede distribuir los anillos de poder\")\n\ntry:\n    rings = int(input(\"Elige la cantidad de anillos: \"))\n    if rings < 0:\n        raise ValueError\n\nexcept ValueError:\n    print(\"Ingresa un numero entero, mayor que 0\")\n\nelse:\n    distributed_rings = distr_rings(rings)\n\n    if isinstance(distributed_rings, list):\n        print(\"Posibles combinaciones de distribución\")\n\n        for index, i in enumerate(distributed_rings):\n            print(f\"{index}. {i}\")\n\n        print(f\"Distribución media: {distributed_rings[int(len(distributed_rings)/2)]}\")\n\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/python/GreenAlpak.py",
    "content": "import math \n\n\ndef dame_los_anillos():\n    try:\n        anillos=int(input(\"Cuantos anillos vamos a repartir?\"))\n    except Exception as e:\n        print(f\"Introduzca un elemento valido: {e}\")\n        dame_los_anillos()\n    return anillos\n\ndef impares(num_anillos):\n    return [anillo for anillo in range(1,num_anillos+1) if anillo%2==1]\n\ndef pares(num_anillos):\n    return [anillo for anillo in range(1,num_anillos+1) if anillo%2==0]\n\ndef primos(num_anillos):\n    result=[]\n    enc=False\n    j=2\n    for i in range(2,num_anillos+1):\n        primo=True\n        for j in range(2,math.ceil(math.sqrt(i))+1):\n            if i%j==0:\n                primo=False\n                break\n        if primo:\n            result.append(i)\n\n    return result\n\ndef backtrack(lists,target,current_sum=0,index=0,current_combination=[]):\n    if index==len(lists):\n        if current_sum==target:\n            return current_combination\n        else:\n            return None\n    for num in lists[index]:\n        result=backtrack(lists,target,current_sum+num,index+1,current_combination+[num])\n        if result is not None:\n            return result\n    return None\n\n        \n\ndef evalua_opciones(num_anillos,l_pares,l_impares,l_primos,sauron):\n    print(f\"\"\"{num_anillos = }\\n \n          {l_pares = }\\n \n          {l_impares = }\\n \n          {l_primos = }\\n \"\"\")\n    result=backtrack([l_pares,l_impares,l_primos,sauron],num_anillos)\n    \n    if result is None:\n        print(\"No hay combinacion posible con esos anillos\")\n    else:\n        print(f\"Los anillos se han repartido con esta combinacion: {result}\")\n\n       \nif __name__==\"__main__\":\n    num_anillos=dame_los_anillos()\n    l_impares=impares(num_anillos)\n    l_primos=primos(num_anillos)\n    l_pares=pares(num_anillos)\n    sauron=[1]\n    evalua_opciones(num_anillos,l_pares,l_impares,l_primos,sauron)\n\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/python/JesusWay69.py",
    "content": "import os, platform\n\nif (platform.platform().startswith(\"macOS\") or platform.platform().startswith(\"Linux\")):\n    os.system('clear')\nelse:\n    os.system('cls')\n\n\"\"\" * EJERCICIO:\n * ¡La temporada 2 de \"Los Anillos de Poder\" está a punto de estrenarse!\n * ¿Qué pasaría si tuvieras que encargarte de repartir los anillos\n * entre las razas de la Tierra Media?\n * Desarrolla un programa que se encargue de distribuirlos.\n * Requisitos:\n * 1. Los Elfos recibirán un número impar.\n * 2. Los Enanos un número primo.\n * 3. Los Hombres un número par.\n * 4. Sauron siempre uno.\n * Acciones:\n * 1. Crea un programa que reciba el número total de anillos\n *    y busque una posible combinación para repartirlos.\n * 2. Muestra el reparto final o el error al realizarlo.\"\"\"\n\ndef prime_generator(num)->list:# Creamos una función que nos devuelva una lista de números primos  \n    prime_list = []       #  hasta el número de anillos introducido\n    for i in range(2, num + 1):\n        prime = True\n        for j in range(2, i):\n            if i % j == 0:\n                prime = False\n                break\n        if prime:\n            prime_list.append(i)                   \n    return prime_list\n\nwhile True:\n    rings = input(\"\\nEscriba el número de anillos a repartir: \")\n    if not rings.isdigit() or int(rings) < 6: # Condicional para evitar que se introduzcan caracteres no numéricos o menores a 6\n            print(\"Sólo se pueden introducir números a partir de 6, intente de nuevo\")\n            continue\n    else:\n            rings = int(rings) # Casteamos la cifra introducida a int \n            start_rings = rings # Guardamos un backup de esa cifra para imprimir al final\n\n    adjust = rings//70 # Creamos una variable para dar más precisión a la cifra del número primo\n    div = len(prime_generator(rings))//2 #Dividimos entre 2 redondeando a int para seleccionar un nº primo a la mitad del total\n    if adjust == 0:\n         adjust = 1\n    if div == 1:\n         div = 2\n    dwarves = prime_generator(rings)[div-adjust-1] # Asignamos el nº primo restando la variable de ajuste según los anillos \n    sauron = 1                                   #  disponibles , 1 unidad por cada 50 anillos para hacer el reparto equitativo\n    rings = rings - dwarves - sauron # Restamos la cantidad de anillos en nº primo de los enanos y el anillo fijo de Saurom\n\n    if rings % 2 == 0: # Si lo que queda es par asignamos justo la mitad a los hombres y la otra mitad menos 1 a los elfos\n        men = rings / 2\n        elves = men - 1\n        if men % 2 != 0: # Comprobamos de nuevo por si tras la división anterior hubiera resultado impar\n            elves = men  # y le hubiéramos asignado una cifra impar a los hombres, se la asignamos a los elfos\n            men += 1 # y le asignamos ese valor mas 1 a los hombres\n        \n    else:\n        men = (rings-1) / 2 # Si es impar le quitamos 1 al total y dividimos entre 2 para los hombres \n        elves = men + 1 #  y el resto mas el que hemos restado antes se lo asignamos a los elfos\n        if men % 2 != 0: # Comprobamos de nuevo por si tras la división anterior hubiera vuelto a dar impar\n            elves = men   # y le hubiéramos asignado una cifra impar a los hombres, se la asignamos a los elfos\n            men += 1 # y le asignamos ese valor mas 1 a los hombres \n        \n    rings = rings - men - elves\n    if rings < 0:#Condicionamos para que no se asignen más anillos de los disponibles\n        men -= 2\n        rings += 2\n    elif rings == 2:# ni sobren 2 en cuyo caso se los asignamos a los elfos\n        elves += 2\n        rings -=2 \n\n    print (f\"\"\"De los {start_rings} anillos se han repartido {sauron} para Sauron, {int(elves)} para los elfos, {int(dwarves)} para los enanos y {int(men)} para los hombres\"\"\")\n    print (\"Anillos sobrantes: \",int(rings))\n    print()\n    break\n\n\n\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/python/JohnAlexGuerrero.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"#35-repartiendo-anillos-de-poder.ipynb\n\nAutomatically generated by Colab.\n\nOriginal file is located at\n    https://colab.research.google.com/drive/1EwPbfqxJ_S_A7BUW43-BVJJ0fJWFzddt\n\"\"\"\n\n'''\n/*\n * EJERCICIO:\n * ¡La temporada 2 de \"Los Anillos de Poder\" está a punto de estrenarse!\n * ¿Qué pasaría si tuvieras que encargarte de repartir los anillos\n * entre las razas de la Tierra Media?\n * Desarrolla un programa que se encargue de distribuirlos.\n * Requisitos:\n * 1. Los Elfos recibirán un número impar.\n * 2. Los Enanos un número primo.\n * 3. Los Hombres un número par.\n * 4. Sauron siempre uno.\n * Acciones:\n * 1. Crea un programa que reciba el número total de anillos\n *    y busque una posible combinación para repartirlos.\n * 2. Muestra el reparto final o el error al realizarlo.\n */\n '''\n\nheader_str = '''\n    Los Anillos de Poder\n  =======================\n '''\n\nimport pandas as pd\n\ndef repartir_anillos(num):\n  anillos_restantes = num_anillos - 1\n  total_anillos_enanos = []\n  total_anillos_hombres = []\n  total_anillos_elfos = []\n  total_anillos_sauron = []\n\n  for x in numeros_primos(anillos_restantes):\n    for y in numeros_pares(anillos_restantes):\n      for z in numeros_impares(anillos_restantes):\n        if x + y + z + 1 == num:\n          total_anillos_enanos.append(x)\n          total_anillos_hombres.append(y)\n          total_anillos_elfos.append(z)\n          total_anillos_sauron.append(1)\n          break\n        continue\n      break\n    continue\n\n\n  data = {\n      \"Elfos\": total_anillos_elfos,\n      \"Enanos\":total_anillos_enanos,\n      \"Hombres\":total_anillos_hombres,\n      \"Sauron\": total_anillos_sauron\n  }\n\n  if len(total_anillos_elfos) != 0:\n    df = pd.DataFrame(data=data, index=[x for x in range(1, len(total_anillos_hombres) + 1)])\n    return df\n  return 'No hay anillos suficientes'\n\n\n#numeros primos menores de num_anillos\ndef numeros_primos(num):\n  primos = []\n  for i in range(2, num):\n    es_primo = True\n    for j in range(2, int(i ** 0.5) + 1):\n      if i % j == 0:\n        es_primo = False\n        break\n    if es_primo:\n      primos.append(i)\n  return primos\n\n#numeros pares menores de num_anillos\ndef numeros_pares(num):\n  pares = [i for i in range(1, num) if i % 2 == 0]\n  return pares\n\n#numeros impares menores de num_anillos\ndef numeros_impares(num):\n  impares = [i for i in range(1, num + 1) if i % 2 != 0]\n  return impares\n\nprint(header_str)\nnum_anillos = int(input('¿Cuantos anillos tienes para repartir? '))\nprint(f'Tienes {num_anillos} de poder')\n\nrepartir_anillos(num_anillos)\n\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/python/Mauricio-Leyva.py",
    "content": "from sympy import isprime\n\ndef distribuir_anillos(total_anillos):\n    if total_anillos < 4:  # Mínimo 1 para Sauron, 1 impar para Elfos, 1 primo para Enanos, y 1 par para Hombres\n        print(\"No es posible repartir los anillos con las reglas dadas.\")\n        return\n    \n    anillos_restantes = total_anillos - 1\n    \n    for elfos in range(1, anillos_restantes, 2):  \n        for enanos in range(2, anillos_restantes):\n            if isprime(enanos):  \n                hombres = anillos_restantes - elfos - enanos\n                if hombres > 0 and hombres % 2 == 0:  \n                    if elfos + enanos + hombres == anillos_restantes:\n                        print(f\"Reparto de anillos: Elfos = {elfos}, Enanos = {enanos}, Hombres = {hombres}, Sauron = 1\")\n                        return\n    \n    print(\"No se encontró una combinación válida para repartir los anillos.\")\n\n# Ejemplo de uso\ntotal_anillos = 20\ndistribuir_anillos(total_anillos)\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/python/Nicojsuarez2.py",
    "content": "# #35 REPARTIENDO LOS ANILLOS DE PODER\n> #### Dificultad: Media | Publicación: 26/08/24 | Corrección: 02/09/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * ¡La temporada 2 de \"Los Anillos de Poder\" está a punto de estrenarse! \n * ¿Qué pasaría si tuvieras que encargarte de repartir los anillos\n * entre las razas de la Tierra Media?\n * Desarrolla un programa que se encargue de distribuirlos.\n * Requisitos:\n * 1. Los Elfos recibirán un número impar.\n * 2. Los Enanos un número primo.\n * 3. Los Hombres un número par.\n * 4. Sauron siempre uno.\n * Acciones:\n * 1. Crea un programa que reciba el número total de anillos\n *    y busque una posible combinación para repartirlos.\n * 2. Muestra el reparto final o el error al realizarlo.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/python/SooHav.py",
    "content": "# 35 REPARTIENDO LOS ANILLOS DE PODER\nimport random\nfrom sympy import isprime\nfrom abc import ABC, abstractmethod\n\n\nclass Anillos(ABC):\n    @abstractmethod\n    def calcular(self, numero_anillos):\n        pass\n\n\nclass AnillosElfos(Anillos):\n    def calcular(self, cantidad_anillos):\n        # Los elfos reciben un número impar de anillos\n        if cantidad_anillos < 1:\n            raise ValueError(\n                \"No hay suficientes anillos para asignar a los Elfos.\")\n        while True:\n            elfos = random.randint(1, cantidad_anillos-2)\n            if elfos % 2 == 1:\n                return elfos\n\n\nclass AnillosEnanos(Anillos):\n    def calcular(self, cantidad_anillos):\n        # Los enanos reciben un número primo de anillos\n        while True:\n            primo = random.randint(2, cantidad_anillos-3)\n            if isprime(primo):\n                return primo\n\n\nclass AnillosHombres(Anillos):\n    def calcular(self, cantidad_anillos):\n        # Los hombres reciben un número par de anillos\n        if cantidad_anillos < 2:\n            raise ValueError(\n                \"No hay suficientes anillos para asignar a los hombres.\")\n        while True:\n            hombres = random.randint(2, cantidad_anillos)\n            if hombres % 2 == 0:\n                return hombres\n\n\nclass RepartoAnillos:\n    def __init__(self, numero_anillos):\n        self.sauron = 1\n        self.elfos = None\n        self.enanos = None\n        self.hombres = None\n        self.numero_anillos = numero_anillos\n        self.intentos = 0\n\n    def repartir_anillos(self):\n        while True:\n            self.intentos += 1\n            calculador_elfos = AnillosElfos()\n            calculador_enanos = AnillosEnanos()\n            calculador_hombres = AnillosHombres()\n\n            self.enanos = calculador_enanos.calcular(\n                self.numero_anillos - self.sauron)\n            self.elfos = calculador_elfos.calcular(\n                self.numero_anillos - self.sauron - self.enanos)\n            self.hombres = calculador_hombres.calcular(\n                self.numero_anillos - self.sauron - self.enanos - self.elfos)\n\n            if self.calcular_suma_total() == self.numero_anillos:\n                print(f\"Solución encontrada en {self.intentos} intentos\")\n                break\n\n            if self.intentos > 2000:\n                print(\"No se encontró solución después de 2000 intentos\")\n                break\n\n    def calcular_suma_total(self):\n        return self.sauron + self.elfos + self.enanos + self.hombres\n\n    def __str__(self):\n        if self.intentos > 2000:\n            return (f\"\\nReparto de anillos:\\nSauron: \\nElfos: \\n\"\n                    f\"Enanos: \\nHombres: \")\n        else:\n            return (f\"\\nReparto de anillos:\\nSauron: {self.sauron}\\nElfos: {self.elfos}\\n\"\n                    f\"Enanos: {self.enanos}\\nHombres: {self.hombres}\")\n\n\n# Ejecutar el reparto de anillos\nnumero_anillos = int(input(\"Ingrese el número total de anillos: \"))\nanillos_del_poder = RepartoAnillos(numero_anillos)\nanillos_del_poder.repartir_anillos()\nprint(anillos_del_poder)\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/python/adra-dev.py",
    "content": "\"\"\"\nEJERCICIO:\n¡La temporada 2 de \"Los Anillos de Poder\" está a punto de estrenarse! \n¿Qué pasaría si tuvieras que encargarte de repartir los anillos\nentre las razas de la Tierra Media?\nDesarrolla un programa que se encargue de distribuirlos.\nRequisitos:\n1. Los Elfos recibirán un número impar.\n2. Los Enanos un número primo.\n3. Los Hombres un número par.\n4. Sauron siempre uno.\nAcciones:\n1. Crea un programa que reciba el número total de anillos\n    y busque una posible combinación para repartirlos.\n2. Muestra el reparto final o el error al realizarlo.\n\nby adra-dev\n\"\"\"\n\ndef is_prime(number:int) -> bool:\n    if number < 2:\n        return False\n    for i in range(2, int(number ** 0.5) + 1):\n        if (number % i) == 0:\n            return False\n    return True\n\ndef distribute_rings(total_rings: int):\n    \n    sauron = 1\n    total_rings -= sauron\n\n    distributed_rings = []\n    \n    for men in range(2, total_rings, 2):\n        for elves in range(1, total_rings, 2):\n            dwarves = total_rings - men - elves\n            if dwarves > 0 and is_prime(dwarves):\n                distributed_rings.append({\n                    \"Hombres\": men,\n                    \"Elfos\": elves,\n                    \"Enanos\": dwarves,\n                    \"Sauron\": sauron\n                })\n\n    if distributed_rings:\n        return distributed_rings\n\n    return \"No es posible distribuir los anillos de poder.\"\n\n\ntry:\n    total_rings = int(\n        input(\"Introduce el numero de anillos que quieres repartir: \")\n    )\n    distributed_rings = distribute_rings(total_rings)\n\n    if isinstance(distributed_rings, list):\n        print(\"Posibles distribuciones de los anillos de poder:\\n\")\n\n        for index, distribution in enumerate(distributed_rings):\n            print(f\"{index + 1}. {distribution}\")\n\n        print(f\"\\nDistribucion media { distributed_rings[int(len(distributed_rings) / 2)]}\")\n\n    else:\n        print(distributed_rings)\nexcept ValueError:\n    print(\"Por favor, introduce un numero entero de anillos.\")"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/python/avcenal.py",
    "content": "\"\"\" * EJERCICIO:\n * ¡La temporada 2 de \"Los Anillos de Poder\" está a punto de estrenarse!\n * ¿Qué pasaría si tuvieras que encargarte de repartir los anillos\n * entre las razas de la Tierra Media?\n * Desarrolla un programa que se encargue de distribuirlos.\n * Requisitos:\n * 1. Los Elfos recibirán un número impar.\n * 2. Los Enanos un número primo.\n * 3. Los Hombres un número par.\n * 4. Sauron siempre uno.\n * Acciones:\n * 1. Crea un programa que reciba el número total de anillos\n *    y busque una posible combinación para repartirlos.\n * 2. Muestra el reparto final o el error al realizarlo.\n\"\"\"\n\nfrom random import randint\n\ndef is_prime(number:int):\n    if number ==1: #en el caso de este programa, el número nunca podrá ser 0. En otro caso habría que evaluar number < 2\n        return False\n    else:\n        for index in range(2,int(number**0.5)+1): #se evalúan valores desde 2 hasta la raíz cuadrada del número\n            if number % index == 0: # y si la división entre el número y alguno de esos valorers tien resto 0\n                return False #entonces no es un número primo.\n    return True\n    \ndef is_odd(number:int):\n    return number % 2 != 0\n\ndef is_even(number:int):\n    return number %2 == 0\n\nTHE_ONE_RING = 1\nprint(\"Te doy la bienvenida al programa de reparto de LOS ANILLOS DE PODER\")\nrings = int(input(\"Dime el número de Anillos de Poder a Repartir: \"))\n#rings = 9\nif rings <= 5:\n    print(\"No hay suficientes anillos para repartir\")\nelse:\n    sauron = THE_ONE_RING\n    while True:\n        rings_aux = rings-sauron\n        men = randint(1,rings_aux)\n        if is_even(men):\n            rings_aux -= men\n            if rings_aux >= 3:\n                dwarven = randint(1,rings_aux)\n                if is_prime(dwarven):\n                    rings_aux -= dwarven\n                    \n                    if rings_aux > 0:\n                        elven = rings_aux\n                        if is_odd(elven):\n                            if sauron+men+dwarven+elven == rings:\n                                print(\"LOS ANILLOS SE HAN REPARTIDO CORRECTAMENTE\")\n                                print(f\"TOTAL DE ANILLOS: {rings}\\n- SAURON: {sauron}\\n- HOMBRES: {men}\\n- ENANOS: {dwarven}\\n- ELFOS: {elven}\")\n                                break\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/python/d1d4cum.py",
    "content": "import math\n\n\ndef is_prime(n: int) -> bool:\n    if n <= 1:\n        return False\n    for i in range(2, int(n ** 0.5) + 1):\n        if n % i == 0:\n            return False\n    return True\n\n\ndef first_prime_in_range(end: int) -> int:\n    for num in range(0, end + 1):\n        if is_prime(num):\n            return num\n    return -1  # Return -1 if no prime number is found\n\n\ndef main():\n    sauron = 1\n    dwarves = 0\n    elfs = 0\n    men = 0\n\n    try:\n        rings = int(input(\"> \"))\n        rings -= 1\n\n        dwarves = first_prime_in_range(rings) if first_prime_in_range(rings) != -1 else 0\n        rings -= dwarves\n\n        if dwarves != 0 and rings % 2 != 0:\n            elfs = math.ceil(rings / 2)\n            men = rings - elfs\n\n            print(f\"Sauron - {sauron}\")\n            print(f\"Enanos - {dwarves}\")\n            print(f\"Elfos - {elfs}\")\n            print(f\"Hombres - {men}\")\n        else:\n            print(\"No se ha podido hacer el reparto\")\n\n    except Exception as e:\n        print(\"Número incorrecto\")\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/python/davidrguez98.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * ¡La temporada 2 de \"Los Anillos de Poder\" está a punto de estrenarse! \n * ¿Qué pasaría si tuvieras que encargarte de repartir los anillos\n * entre las razas de la Tierra Media?\n * Desarrolla un programa que se encargue de distribuirlos.\n * Requisitos:\n * 1. Los Elfos recibirán un número impar.\n * 2. Los Enanos un número primo.\n * 3. Los Hombres un número par.\n * 4. Sauron siempre uno.\n * Acciones:\n * 1. Crea un programa que reciba el número total de anillos\n *    y busque una posible combinación para repartirlos.\n * 2. Muestra el reparto final o el error al realizarlo.\n */ \"\"\"\n\n#EJERCICIO\n\ndef is_prime(number: int) -> bool:\n\n    if number < 2:\n        return False\n    for i in range(2, number):\n        if (number % i) == 0:\n            return False\n    return True\n\ndef distribute_ring(total_rings: int):\n    \n    Sauron = 1\n    total_rings -= Sauron\n\n    distributed_rings = []\n    \n    for men in range(2, total_rings, 2):\n        for elves in range(1, total_rings, 2):\n            dwarves = total_rings - men - elves\n\n            if dwarves > 0 and is_prime(dwarves):\n                distributed_rings.append({\n                    \"Hombres\": men,\n                    \"Elfos\": elves,\n                    \"Enanos\": dwarves,\n                    \"Sauron\": Sauron\n                })\n\n    if distributed_rings:\n        return distributed_rings\n    \n    return \"No es posible distribuir los anillos de poder.\"\n\ntry:\n    total_rings = int(input(\"Número de anillos a repartir: \"))\n    distributed_rings = distribute_ring(total_rings)\n\n    if isinstance(distributed_rings, list):\n        print(\"Distribución de los anillos de poder:\\n\")\n\n        for index, distribution in enumerate(distributed_rings):\n            print(f\"{index + 1}. {distribution}\")\n\n    else:\n        print(distributed_rings)\n\nexcept ValueError:\n    print(\"Introduce un número entero.\")\n\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/python/duendeintemporal.py",
    "content": "#35 { Retos para Programadores } REPARTIENDO LOS ANILLOS DEL PODER \n\n# Bibliography reference:\n# I use GPT as a reference and sometimes to correct or generate proper comments.\n\n\"\"\"  \n * EJERCICIO:\n * ¡La temporada 2 de \"Los Anillos de Poder\" está a punto de estrenarse!\n * ¿Qué pasaría si tuvieras que encargarte de repartir los anillos\n * entre las razas de la Tierra Media?\n * Desarrolla un programa que se encargue de distribuirlos.\n * Requisitos:\n * 1. Los Elfos recibirán un número impar.\n * 2. Los Enanos un número primo.\n * 3. Los Hombres un número par.\n * 4. Sauron siempre uno.\n * Acciones:\n * 1. Crea un programa que reciba el número total de anillos\n *    y busque una posible combinación para repartirlos.\n * 2. Muestra el reparto final o el error al realizarlo.\n\n\"\"\"\n\nlog = print\n\nimport math\n\n# Function to check if a number is prime\ndef is_prime(num):\n    if num <= 1:\n        return False  # Numbers less than or equal to 1 are not prime\n    if num <= 3:\n        return True  # 2 and 3 are prime numbers\n    if num % 2 == 0 or num % 3 == 0:\n        return False  # Eliminate even numbers and multiples of 3\n\n    # Check for factors from 5 to the square root of num\n    for i in range(5, int(math.sqrt(num)) + 1, 6):\n        if num % i == 0 or num % (i + 2) == 0:\n            return False  # Check i and i + 2\n    return True  # If no factors were found, num is prime\n\n# Function to find the largest prime number less than a given number\ndef first_prime(num):\n    for i in range(num - 1, 1, -1):\n        if is_prime(i):\n            return i  # Return the first prime found\n    return 2  # Return 2 if no prime found (should not happen for valid input)\n\ndef is_odd(num):\n    return num % 2 != 0  # Return true if the number is odd\n\n# Function to assign rings based on the rules\ndef assign_rings(num):\n    # Check if the number of rings is odd and greater than or equal to 7\n    if not is_odd(num) or num < 7:\n        log('The number of rings must be an odd number and greater than or equal to 7')\n        start()  # Prompt for input again\n        return\n\n    arr_of_rings = [0, 0, 0, 1]  # Sauron always gets 1 ring\n    f_prime = first_prime(num)  # Find the largest prime less than num\n    r = num - f_prime  # Remaining rings after giving to Dwarves\n\n    # Adjust remaining rings if less than 4\n    if r < 4:\n        f_prime = first_prime(num - 3)\n        r = num - f_prime \n\n    # Distribute rings based on the remaining count\n    if r == 4:\n        arr_of_rings[0] = (r // 2) - 1  # Elves\n        arr_of_rings[1] = f_prime        # Dwarves\n        arr_of_rings[2] = r // 2          # Men\n    elif r == 6:\n        arr_of_rings[0] = (r - 1) // 2  # Elves\n        arr_of_rings[1] = f_prime        # Dwarves\n        arr_of_rings[2] = (r - 1) // 2  # Men\n    elif r == 8:\n        arr_of_rings[0] = (r - 1) // 2  # Elves\n        arr_of_rings[1] = f_prime        # Dwarves\n        arr_of_rings[2] = (r - 1) // 2  # Men\n    else:\n        # Alternative distribution logic for other values of r\n        alternative_distribution(arr_of_rings, f_prime, r)\n\n    # Output the distribution of rings\n    log(f'\\n{arr_of_rings[0]} rings to: Elves, {arr_of_rings[1]} rings to: Dwarves, '\n          f'{arr_of_rings[2]} rings to: Men, and {arr_of_rings[3]} ring to: Sauron')\n\n# Function for alternative distribution logic\ndef alternative_distribution(arr_of_rings, f_prime, r):\n    # Dwarves get the prime\n    arr_of_rings[1] = f_prime  # Dwarves\n    arr_of_rings[3] = 1  # Sauron gets 1 ring\n\n    # Calculate remaining rings after assigning to Dwarves and Sauron\n    remaining_for_elves_and_men = r - arr_of_rings[3]  # Only subtract Sauron's ring\n\n    # Ensure Elves get an odd number and Men get an even number\n    if is_odd(remaining_for_elves_and_men):\n        arr_of_rings[0] = max(1, (remaining_for_elves_and_men + 1) // 2)  # Ensure Elves get an odd number\n        arr_of_rings[2] = remaining_for_elves_and_men - arr_of_rings[0]  # Calculate remaining rings for Men\n    else:\n        log(\"It's not possible to do the distribution according to the rules.\")\n\n# Function to start the input process\ndef start():\n    total_rings = input('Indicate the number of rings to distribute: ')\n    try:\n        total_rings = int(total_rings)\n        assign_rings(total_rings)\n    except ValueError:\n        log('Please enter a valid number.')  # Prompt for valid input\n        start()  # Prompt again for valid input\n\n# Start the program\nif __name__ == \"__main__\":\n    start()\n\n# Output Example:\n\"\"\"   \nIndicate the number of rings to distribute: 102\nThe number of rings must be an odd number and greater than or equal to 7\nIndicate the number of rings to distribute: 103\n\n2 rings to: Elves, 97 rings to: Dwarves, 2 rings to: Men, and 1 ring to: Sauron\n\n\"\"\""
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/python/fborjalv.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * ¡La temporada 2 de \"Los Anillos de Poder\" está a punto de estrenarse!\n * ¿Qué pasaría si tuvieras que encargarte de repartir los anillos\n * entre las razas de la Tierra Media?\n * Desarrolla un programa que se encargue de distribuirlos.\n * Requisitos:\n * 1. Los Elfos recibirán un número impar.\n * 2. Los Enanos un número primo.\n * 3. Los Hombres un número par.\n * 4. Sauron siempre uno.\n * Acciones:\n * 1. Crea un programa que reciba el número total de anillos\n *    y busque una posible combinación para repartirlos.\n * 2. Muestra el reparto final o el error al realizarlo.\n */\n\n\"\"\"\n\n\nn_rings = int(input(\"Introduce el número de anillos a repartirse: \"))\ntotal_rings = {\"Sauron\": 0, \"Elfos\": 0, \"Hombres\": 0, \"Enanos\": 0}\n\ndef es_primo(number):\n    if number <= 1:\n        return False\n    for element in range(2, number):\n        if number % element == 0:\n            return False\n    return True\n\nif n_rings > 0:\n    n_rings -= 1\n    total_rings[\"Sauron\"] += 1\n\nwhile n_rings > 0: \n    distributed = False\n    if (total_rings[\"Hombres\"] + 1) % 2 == 0:\n        n_rings -= 1\n        total_rings[\"Hombres\"] += 1\n        distributed = True\n\n    if (total_rings[\"Elfos\"] + 1) % 3 == 0:\n        n_rings -= 1\n        total_rings[\"Elfos\"] += 1\n        distributed = True\n\n    if es_primo(total_rings[\"Enanos\"]+1):\n        n_rings -= 1\n        total_rings[\"Enanos\"] +=1\n        distributed = True\n\n    if not distributed and n_rings > 0: \n        min_group = min(total_rings, key = lambda x: total_rings[x] if x != \"Sauron\" else float(\"inf\"))\n        total_rings[min_group] += 1\n        n_rings -= 1  \n\nfor key, value in total_rings.items():\n    print(f\"{key} recibe {value}\")\n\nprint(f\"Quedan {n_rings}\")\n\n\n\n    "
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/python/hectorio23.py",
    "content": "# Autor: Héctor Adán\n# GitHub: https://github.com/hectorio23\n\nimport math\n\ndef is_prime(n):\n    \"\"\"Check if a number is prime.\"\"\"\n    if n <= 1:\n        return False\n    for i in range(2, int(math.sqrt(n)) + 1):\n        if n % i == 0:\n            return False\n    return True\n\ndef distribute_rings(total_rings):\n    # Sauron always gets one ring\n    sauron_rings = 1\n    remaining_rings = total_rings - sauron_rings\n    \n    # We need at least 1 ring for each race\n    for elves_rings in range(1, remaining_rings, 2):  # Elves get an odd number\n        for dwarves_rings in range(2, remaining_rings):\n            if is_prime(dwarves_rings):  # Dwarves get a prime number\n                humans_rings = remaining_rings - elves_rings - dwarves_rings\n                if humans_rings > 0 and humans_rings % 2 == 0:  # Humans get an even number\n                    return {\n                        \"Elves\": elves_rings,\n                        \"Dwarves\": dwarves_rings,\n                        \"Humans\": humans_rings,\n                        \"Sauron\": sauron_rings\n                    }\n\n    return \"Error: No valid distribution found.\"\n\n# Example usage\ntotal_rings = 20\nresult = distribute_rings(total_rings)\nprint(result)\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/python/idiegorojas.py",
    "content": "\"\"\"\n35 - Los Anillos de Poder\n\"\"\"\n# Desarrolla un programa que se encargue de distribuirlos.\n\n# Requisitos:\n# 1. Los Elfos recibirán un número impar.\n# 2. Los Enanos un número primo.\n# 3. Los Hombres un número par.\n# 4. Sauron siempre uno.\n\n# Acciones:\n# 1. Crea un programa que reciba el número total de anillos y busque una posible combinación para repartirlos.\n# 2. Muestra el reparto final o el error al realizarlo.\n\n\nimport math\nimport random\nfrom abc import ABC, abstractmethod\n\ndef es_primo(num):\n    \"\"\"Verifica si un número es primo\"\"\"\n    if num < 2:\n        return False\n    for i in range(2, int(math.sqrt(num)) + 1):\n        if num % i == 0:\n            return False\n    return True\n\nclass Distribuidor:\n    def __init__(self, total_anillos):\n        try:\n            self.total = int(total_anillos)\n            self.anillos_disponibles = list(range(1, self.total + 1))\n            self.anillos_asignados = []\n        except ValueError:\n            print(\"Por favor ingrese un número válido\")\n            self.total = 0\n            self.anillos_disponibles = []\n            self.anillos_asignados = []\n\n    def distribuir_anillos(self):\n        if self.total < 20:  # 3 + 7 + 9 + 1 = 20 anillos mínimo\n            print(f\"No hay suficientes anillos ({self.total}) para la distribución. Se necesitan al menos 20.\")\n            return False\n            \n        # Obtener anillos para elfos (3 impares)\n        anillos_impares = [a for a in self.anillos_disponibles if a % 2 == 1]\n        if len(anillos_impares) < 3:\n            print(\"No hay suficientes anillos impares para los elfos\")\n            return False\n        anillos_elfos = random.sample(anillos_impares, 3)\n        self.anillos_asignados.extend(anillos_elfos)\n        \n        # Obtener anillos para enanos (7 primos)\n        anillos_primos = [a for a in self.anillos_disponibles \n                        if es_primo(a) and a not in self.anillos_asignados]\n        if len(anillos_primos) < 7:\n            print(\"No hay suficientes anillos primos para los enanos\")\n            return False\n        anillos_enanos = random.sample(anillos_primos, 7)\n        self.anillos_asignados.extend(anillos_enanos)\n        \n        # Obtener anillos para hombres (9 pares)\n        anillos_pares = [a for a in self.anillos_disponibles \n                       if a % 2 == 0 and a not in self.anillos_asignados]\n        if len(anillos_pares) < 9:\n            print(\"No hay suficientes anillos pares para los hombres\")\n            return False\n        anillos_hombres = random.sample(anillos_pares, 9)\n        self.anillos_asignados.extend(anillos_hombres)\n        \n        # Obtener anillo para Sauron (cualquiera que quede)\n        anillos_restantes = [a for a in self.anillos_disponibles \n                           if a not in self.anillos_asignados]\n        if not anillos_restantes:\n            print(\"No queda ningún anillo para Sauron\")\n            return False\n        anillo_sauron = random.choice(anillos_restantes)\n        self.anillos_asignados.append(anillo_sauron)\n        \n        # Mostrar resultados\n        print(f\"Los elfos recibieron anillos: {anillos_elfos}\")\n        print(f\"Los enanos recibieron anillos: {anillos_enanos}\")\n        print(f\"Los hombres recibieron anillos: {anillos_hombres}\")\n        print(f\"Sauron recibió el anillo: {anillo_sauron}\")\n        \n        return True\n\n# Programa principal\nif __name__ == \"__main__\":\n    anillos = input(\"Ingrese el número total de anillos a repartir: \")\n    distribuidor = Distribuidor(anillos)\n    distribuidor.distribuir_anillos()"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/python/ignaciovihe.py",
    "content": "\"\"\"\n * EJERCICIO:\n * ¡La temporada 2 de \"Los Anillos de Poder\" está a punto de estrenarse! \n * ¿Qué pasaría si tuvieras que encargarte de repartir los anillos\n * entre las razas de la Tierra Media?\n * Desarrolla un programa que se encargue de distribuirlos.\n * Requisitos:\n * 1. Los Elfos recibirán un número impar.\n * 2. Los Enanos un número primo.\n * 3. Los Hombres un número par.\n * 4. Sauron siempre uno.\n * Acciones:\n * 1. Crea un programa que reciba el número total de anillos\n *    y busque una posible combinación para repartirlos.\n * 2. Muestra el reparto final o el error al realizarlo.\n\"\"\"\n\ndef prime_generator():\n    \"\"\"Generador infinito de números primos (modo eficiente).\"\"\"\n\n    n = 2\n    while True:\n        for i in range (2, int(n ** 0.5) +1):#solo hace falta llegar hasta la raiz cuadrada del numero mas alla no habra divisores.\n            if n % i == 0:\n                break\n        else:# el bloque else de un for se ejecuta si no se usa un break.\n            yield n\n        n += 1\n\n\ndef distribute_rings(total_rings: int):\n    \"\"\"Genera posibles distribuciones de anillos entre razas, dejando 1 para Sauron\n    y asegurando que los Enanos reciban un número primo de anillos.\"\"\"\n\n    possibilities= []\n    prime = prime_generator()\n    rings_for_dwarfs = next(prime)\n\n    while total_rings - rings_for_dwarfs >= 4:\n        resting_rings = total_rings\n        rings_for_sauron = 1\n        resting_rings -=  rings_for_sauron # One ring for Sauron.\n        \n        if (resting_rings - rings_for_dwarfs) % 2 != 0:\n            resting_rings -=  rings_for_dwarfs\n            for rings_for_elfs in range(1, resting_rings, 2):\n                rings_for_men = resting_rings - rings_for_elfs\n                possibilities.append({\n                    \"Sauron\": rings_for_sauron,\n                    \"Elves\": rings_for_elfs,\n                    \"Dwarfs\": rings_for_dwarfs,\n                    \"Men\": rings_for_men\n                })\n\n        rings_for_dwarfs = next(prime)\n    \n    return possibilities\n        \ndef print_distribution(distributed_rings):\n    if distributed_rings:\n        print(\"Posibles distribuciones encontradas:\")\n        for index, distribution in enumerate(distributed_rings):\n            print(f\"{index + 1}._ {distribution}\")\n        print(f\"\\nTotal de posibilidades encontradas: {len(distributed_rings)}\")\n\n        print(\"Distribucion equitativa:\")\n        print(distributed_rings[int(len(distributed_rings) / 2) - 1])\n    else:\n        print(\"No hay suficientes anillos para todos.\")  \n\n\ndef main():\n    while True:\n        try:\n            total_rings = int(input(\"Introduce el numero total de anillos a repartir: \"))\n            distributed_rings = distribute_rings(total_rings)\n            print_distribution(distributed_rings)\n            break\n        except ValueError as e:\n            print(f\"Introduce un número entero.\")\n            continue\n\nmain()"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/python/javi-kl.py",
    "content": "class Distribuidor:\n    def __init__(self, n) -> None:\n        self.total_anillos = n\n        self.sauron = 1\n        self.hombres = 0\n        self.elfos = 0\n        self.enanos = 0\n\n    def __str__(self) -> str:\n        return f\"Sauron {self.sauron}\\nHombres {self.hombres}\\nEnanos: {self.enanos}\\nElfos {self.elfos}\"\n\n    def comprobacion(self):\n        return (\n            sum(([self.sauron, self.hombres, self.enanos, self.elfos]))\n            == self.total_anillos\n        )\n\n    def distribuir(self):\n        for i in range(2, self.total_anillos + 1, 2):  # hombres\n            for j in range(1, self.total_anillos + 1, 2):  # elfos\n                for k in range(2, self.total_anillos + 1):  # enanos\n                    if es_primo(k):\n                        self.hombres = i\n                        self.elfos = j\n                        self.enanos = k\n                        if self.comprobacion():\n                            return True\n        return False\n\n\ndef es_primo(num):\n    if num < 2:\n        return False\n    for i in range(2, num):\n        if num % i == 0:\n            return False\n    return True\n\n\ndistribuidor = Distribuidor(7)\nif distribuidor.distribuir():\n    print(\"Distribución con exito: \")\n    print(distribuidor)\nelse:\n    print(\"No se encuentra una solución\")\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/python/javierfiestasbotella.py",
    "content": "'''\n * EJERCICIO:\n * ¡La temporada 2 de \"Los Anillos de Poder\" está a punto de estrenarse! \n * ¿Qué pasaría si tuvieras que encargarte de repartir los anillos\n * entre las razas de la Tierra Media?\n * Desarrolla un programa que se encargue de distribuirlos.\n * Requisitos:\n * 1. Los Elfos recibirán un número impar.\n * 2. Los Enanos un número primo.\n * 3. Los Hombres un número par.\n * 4. Sauron siempre uno.\n * Acciones:\n * 1. Crea un programa que reciba el número total de anillos\n *    y busque una posible combinación para repartirlos.\n * 2. Muestra el reparto final o el error al realizarlo.\n */\n'''\nimport random\n\ndef primo(n):\n    if n < 2:\n        return False\n    for i in range(2, int(n**0.5) + 1):\n        if n % i == 0:\n            return False\n    return True\n\nfor _ in range(100):  \n    enanos = random.choice([i for i in range(1, 20) if primo(i)])\n    elfos = random.choice([i for i in range(1, 20, 2)])\n    humanos = random.choice([i for i in range(2, 21, 2)])\n    sauron = 1\n\n    if enanos + elfos + humanos + sauron == 20:\n        print(f'''\n    Enanos -> {enanos}\n    Elfos -> {elfos}\n    Sauron -> {sauron}\n    Humanos -> {humanos}''')\n        break\nelse:\n    print(\"No se encontró una combinación válida.\")\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/python/juanmax2.py",
    "content": "\"\"\"\n * EJERCICIO:\n * ¡La temporada 2 de \"Los Anillos de Poder\" está a punto de estrenarse! \n * ¿Qué pasaría si tuvieras que encargarte de repartir los anillos\n * entre las razas de la Tierra Media?\n * Desarrolla un programa que se encargue de distribuirlos.\n * Requisitos:\n * 1. Los Elfos recibirán un número impar.\n * 2. Los Enanos un número primo.\n * 3. Los Hombres un número par.\n * 4. Sauron siempre uno.\n * Acciones:\n * 1. Crea un programa que reciba el número total de anillos\n *    y busque una posible combinación para repartirlos.\n * 2. Muestra el reparto final o el error al realizarlo.\n\"\"\"\nimport random\n\n# Función para comprobar el total\ndef comprobar_total(num_anillos: int, total_anillos: int, anillos_enanos : int) -> bool:\n    if num_anillos == total_anillos and anillos_enanos >= 2:\n        return True\n    else:\n        return False\n\n# Función para número par\ndef numero_par(numero: int) -> list:\n    lista_pares = []\n    for num in range(2, numero + 1, 2):\n        lista_pares.append(num)\n    return lista_pares\n        \n    \n# Funcion para numero impar\ndef numero_impar(numero: int) -> list:\n    lista_impares = []\n    for num in range(1, numero + 1, 2):\n        lista_impares.append(num)\n    return lista_impares\n        \n# Función para comprobar si un número es primo\ndef es_primo(num: int):\n    lista_primos = []\n    count = 0\n    for i in range(2, num + 1):\n        for j in range(2, int(i/2 + 1)):\n            if i % j == 0:\n                count += 1\n        if count == 0:\n            lista_primos.append(i)\n        count = 0\n    return lista_primos\n    \n    \n# Función para distribuir los anillos\n\ndef distribucion_anillos(num_anillos : int):\n           \n    if num_anillos < 6:\n        print(\"No es posible hacer una repartición de los anillos\")\n    else:\n        continuar = True\n        numero_anillos = num_anillos\n        total_anillos = 0\n        anillos_hombres = 0\n        anillos_elfos = 0\n        anillos_enanos = 0\n        while continuar == True:    \n            sauron_anillos = 1\n            numero_anillos -= sauron_anillos\n            \n            lista_hombres = numero_par(numero_anillos)\n            anillos_hombres = random.choice(lista_hombres)\n            numero_anillos -= anillos_hombres\n            lista_elfos = numero_impar(numero_anillos)\n            anillos_elfos = random.choice(lista_elfos)\n            numero_anillos -= anillos_elfos\n            if sauron_anillos + anillos_elfos + anillos_hombres <= num_anillos-2:\n                lista_enanos = es_primo(numero_anillos)\n                anillos_enanos = random.choice(lista_enanos)\n                total_anillos = sauron_anillos + anillos_elfos + anillos_enanos + anillos_hombres\n            \n                condicion = comprobar_total(num_anillos, total_anillos, anillos_enanos)\n                if condicion == True:\n                    print(\n                        f\"\"\"Sauron : {sauron_anillos}\\nHombres : {anillos_hombres}\\nElfos : {anillos_elfos}\\nEnanos : {anillos_enanos}\"\"\"\n                        )\n                    continuar = False\n                else:\n                    numero_anillos = num_anillos\n                    total_anillos = 0\n                    anillos_hombres = 0\n                    anillos_elfos = 0\n                    anillos_enanos = 0\n                    continue\n            \n            else:\n                numero_anillos = num_anillos\n                total_anillos = 0\n                anillos_hombres = 0\n                anillos_elfos = 0\n                anillos_enanos = 0\n                continue\n            \n                \n                          \n\n# Pedir los anillos por consola\ntry:\n    num_anillos = int(input(\"Introduce el número de anillos para repartir: \"))\n    distribucion_anillos(num_anillos)\n\nexcept ValueError:\n    print(\"No has introducido un número entero\")\n\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/python/juanppdev.py",
    "content": "\"\"\"\n * EJERCICIO:\n * ¡La temporada 2 de \"Los Anillos de Poder\" está a punto de estrenarse! \n * ¿Qué pasaría si tuvieras que encargarte de repartir los anillos\n * entre las razas de la Tierra Media?\n * Desarrolla un programa que se encargue de distribuirlos.\n * Requisitos:\n * 1. Los Elfos recibirán un número impar.\n * 2. Los Enanos un número primo.\n * 3. Los Hombres un número par.\n * 4. Sauron siempre uno.\n * Acciones:\n * 1. Crea un programa que reciba el número total de anillos\n *    y busque una posible combinación para repartirlos.\n * 2. Muestra el reparto final o el error al realizarlo.\n\"\"\"\n\ndef es_primo(num):\n    if num < 2:\n        return False\n    for i in range(2, int(num**0.5) + 1):\n        if num % i == 0:\n            return False\n    return True\n\ndef distribuir_anillos(total_anillos):\n    if total_anillos < 4:\n        return \"No es posible distribuir los anillos con los requisitos dados.\"\n\n    # Sauron siempre recibe uno\n    sauron = 1\n    total_anillos -= sauron\n\n    # Distribuir los anillos restantes\n    elfos = 0\n    enanos = 0\n    hombres = 0\n\n    for i in range(1, total_anillos + 1):\n        if i % 2 != 0:  # Número impar para los Elfos\n            elfos += 1\n        elif es_primo(i):  # Número primo para los Enanos\n            enanos += 1\n        else:  # Número par para los Hombres\n            hombres += 1\n\n    if elfos + enanos + hombres == total_anillos:\n        return f\"Reparto final: Elfos: {elfos}, Enanos: {enanos}, Hombres: {hombres}, Sauron: {sauron}\"\n    else:\n        return \"No es posible distribuir los anillos con los requisitos dados.\"\n\n# Ejemplo de uso\ntotal_anillos = 20\nprint(distribuir_anillos(total_anillos))\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/python/kenysdev.py",
    "content": "# _____________________________________\n# https://github.com/kenysdev\n# 2024 - Python\n# _____________________________________\n# 35 REPARTIENDO LOS ANILLOS DE PODER\n# ------------------------------------\n# ¡La temporada 2 de \"Los Anillos de Poder\" está a punto de estrenarse!\n# ¿Qué pasaría si tuvieras que encargarte de repartir los anillos\n# entre las razas de la Tierra Media?\n# Desarrolla un programa que se encargue de distribuirlos.\n# Requisitos:\n# 1. Los Elfos recibirán un número impar.\n# 2. Los Enanos un número primo.\n# 3. Los Hombres un número par.\n# 4. Sauron siempre uno.\n# Acciones:\n# 1. Crea un programa que reciba el número total de anillos\n#    y busque una posible combinación para repartirlos.\n# 2. Muestra el reparto final o el error al realizarlo.\n\nimport statistics\n\ndef get_total_rings() -> int:\n    while True:\n        input_ = input(\"Cantidad de anillos: \")\n        if input_.isdigit() and int(input_) >= 1:\n            return int(input_)\n        print(\"Debe ser un valor entero '>= 1'.\")\n\ndef is_prime(n):\n    if n < 2:\n        return False\n    for i in range(2, int(n**0.5) + 1):\n        if n % i == 0:\n            return False\n    return True\n\ndef distribute(total: int) -> list:\n    combinations = []\n    for elves in range(1, total, 2):\n        for men in range(2, total, 2):\n            dwarves = total - (men + elves)\n            if dwarves > 0 and is_prime(dwarves):\n                combinations.append((elves, men, dwarves))\n\n    return combinations\n\ndef standard_deviation(tup: tuple) -> float:\n    return statistics.stdev(tup)\n\ndef the_most_balanced(combinations: list) -> tuple:\n    deviations: list = [standard_deviation(tup) for tup in combinations]\n    index_of_least_deviation = deviations.index(min(deviations))\n    return combinations[index_of_least_deviation]\n\ndef print_result(distribution: tuple, sauron: int):\n    if not distribution:\n        print(\"Error en la selección equitativa.\")\n        return\n\n    elves, men, dwarves = distribution\n    print(\"_________________________\")\n    print(f\"Elfos   -> {elves} : # Impar\\nEnanos  -> {dwarves} : # Primo\")\n    print(f\"Hombres -> {men} : # Par\\nSauron  -> {sauron} : # Fijo\")\n    print(\"-------------------------\")\n\ndef main(total: int):\n    sauron = 1\n    total -= sauron\n    combinations: list = distribute(total)\n\n    if not combinations:\n        print(\"No existe una combinación posible.\")\n        return\n\n    distribution: tuple = the_most_balanced(combinations)\n    print_result(distribution, sauron)\n    \nif __name__ == \"__main__\":\n    print(\"REPARTIENDO LOS ANILLOS DE PODER\")\n    total: int = get_total_rings()\n    main(total)\n\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/python/mhayhem.py",
    "content": "# @Author Daniel Grande (Mhayhem)\n\nimport random\n\n# EJERCICIO:\n# ¡La temporada 2 de \"Los Anillos de Poder\" está a punto de estrenarse! \n# ¿Qué pasaría si tuvieras que encargarte de repartir los anillos\n# entre las razas de la Tierra Media?\n# Desarrolla un programa que se encargue de distribuirlos.\n# Requisitos:\n# 1. Los Elfos recibirán un número impar.\n# 2. Los Enanos un número primo.\n# 3. Los Hombres un número par.\n# 4. Sauron siempre uno.\n# Acciones:\n# 1. Crea un programa que reciba el número total de anillos\n#    y busque una posible combinación para repartirlos.\n# 2. Muestra el reparto final o el error al realizarlo.\ndef prime_number(num):\n    if num < 2:\n        return False\n    if num == 2:\n        return True\n    if num % 2 == 0:\n        return False\n    for i in range(3, int(num**0.5) + 1, 2):\n        if num % i == 0:\n            return False\n    return True\n\ndef distribution_of_the_rings(num_rings):\n    dwarfs = [num for num in range(2, num_rings) if prime_number(num)]\n    elfs = [num for num in range(1, num_rings) if num % 2 != 0]\n    sauron = 1\n\n    result = []\n\n    for numd in dwarfs:\n        for nume in elfs:\n            numh = num_rings - nume - numd - sauron\n            if numh > 0 and numh % 2 == 0:\n                rings_delivery = numh + nume + numd + sauron\n                result.append(f\"Sauron: {sauron}; Elfos: {nume}; Enanos: {numd}; Humanos: {numh}. Resultado: {rings_delivery}\")\n\n    if not result:\n        print(\"No existe combinación.\")\n    else:\n        print(random.choice(result))\n\ndistribution_of_the_rings(200)"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/python/miguelex.py",
    "content": "import math\n\ndef es_primo(num):\n    if num <= 1:\n        return False\n    if num == 2:\n        return True\n    if num % 2 == 0:\n        return False\n    \n    for i in range(3, int(math.sqrt(num)) + 1, 2):\n        if num % i == 0:\n            return False\n    return True\n\ndef repartir_anillos(total_anillos):\n    if total_anillos < 4:\n        return \"Error: No hay suficientes anillos para cumplir con los requisitos.\"\n    \n    anillos_sauron = 1\n    total_anillos -= 1\n    \n    mejor_diferencia = float('inf')\n    mejor_reparto = None\n    \n    for anillos_elfos in range(1, total_anillos + 1, 2):\n        for anillos_enanos in range(2, total_anillos + 1):\n            if es_primo(anillos_enanos):\n                anillos_hombres = total_anillos - anillos_elfos - anillos_enanos\n                \n                if anillos_hombres > 0 and anillos_hombres % 2 == 0:\n                    diferencia = max(anillos_elfos, anillos_enanos, anillos_hombres) - min(anillos_elfos, anillos_enanos, anillos_hombres)\n                    \n                    if diferencia < mejor_diferencia:\n                        mejor_diferencia = diferencia\n                        mejor_reparto = (anillos_elfos, anillos_enanos, anillos_hombres, anillos_sauron)\n    \n    if mejor_reparto:\n        return f\"Reparto exitoso: Elfos = {mejor_reparto[0]}, Enanos = {mejor_reparto[1]}, Hombres = {mejor_reparto[2]}, Sauron = {mejor_reparto[3]}\"\n    else:\n        return \"Error: No se encontró una combinación válida para repartir los anillos.\"\n\n# Solicitar el número total de anillos por teclado\ntotal_anillos = int(input(\"Ingresa el número total de anillos: \"))\nresultado = repartir_anillos(total_anillos)\nprint(resultado)\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/python/mouredev.py",
    "content": "def is_prime(number: int) -> bool:\n    if number < 2:\n        return False\n    for i in range(2, int(number ** 0.5) + 1):\n        if (number % i) == 0:\n            return False\n    return True\n\n\ndef distribute_rings(total_rings: int):\n\n    sauron = 1\n    total_rings -= sauron\n\n    distributed_rings = []\n\n    for men in range(2, total_rings, 2):\n        for elves in range(1, total_rings, 2):\n            dwarves = total_rings - men - elves\n            if dwarves > 0 and is_prime(dwarves):\n                distributed_rings.append({\n                    \"Hombres\": men,\n                    \"Elfos\": elves,\n                    \"Enanos\": dwarves,\n                    \"Sauron\": sauron\n                })\n\n    if distributed_rings:\n        return distributed_rings\n\n    return \"No es posible distribuir los anillos de poder.\"\n\n\ntry:\n    total_rings = int(\n        input(\"Introduce el número de anillos de poder que quieres repartir: \")\n    )\n    distributed_rings = distribute_rings(total_rings)\n\n    if isinstance(distributed_rings, list):\n        print(\"Posibles distribuciones de los anillos de poder:\\n\")\n\n        for index, distribution in enumerate(distributed_rings):\n            print(f\"{index + 1}. {distribution}\")\n\n        print(\n            f\"\\nDistribución media {\n                distributed_rings[int(len(distributed_rings) / 2)]}\"\n        )\n\n    else:\n        print(distributed_rings)\nexcept ValueError:\n    print(\"Por favor, introduce un número entero de anillos.\")\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/python/neslarra.py",
    "content": "\"\"\"\n EJERCICIO:\n ¡La temporada 2 de \"Los Anillos de Poder\" está a punto de estrenarse! \n ¿Qué pasaría si tuvieras que encargarte de repartir los anillos\n entre las razas de la Tierra Media?\n Desarrolla un programa que se encargue de distribuirlos.\n Requisitos:\n 1. Los Elfos recibirán un número impar.\n 2. Los Enanos un número primo.\n 3. Los Hombres un número par.\n 4. Sauron siempre uno.\n Acciones:\n 1. Crea un programa que reciba el número total de anillos\n    y busque una posible combinación para repartirlos.\n 2. Muestra el reparto final o el error al realizarlo.\n\"\"\"\nimport math\n\n\ndef is_prime(num: int):\n    if num == 1 or (num % 2 == 0 and num > 2):\n        return False\n    return all(num % i for i in range(3, int(math.sqrt(num)) + 1, 2))\n\n\ndef odd_even(num: int):\n    return False if num % 2 else True\n\n\ndef group_of_three(num: int):\n    elfos = [x for x in range(1, num) if not odd_even(x)]\n    hombres = [x for x in range(1, num) if odd_even(x)]       # OJO el 0 es par PERO si lo considero los hombres NO estarían recibiendo anillos\n    enanos = [x for x in range(1, num) if is_prime(x)]\n\n    combinacion = []\n\n    for elfo in elfos:\n        anillos = elfo\n        for enano in enanos:\n            anillos += enano\n            for hombre in hombres:\n                anillos += hombre\n                if anillos == num - 1:\n                    combinacion.append({\"elfos\": elfo, \"enanos\": enano, \"hombres\": hombre, \"sauron\": 1})\n                anillos -= hombre\n            anillos -= enano\n\n    return combinacion\n\n\nanillos = int(input(\"Ingresa la cantidad de anillos de poder: \"))\ncombinacion = group_of_three(anillos)\nif not combinacion:\n    print(f\"No hay posible combinación de {anillos} anillos\")\nelse:\n    for combineta in combinacion:\n        print(combineta)\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/python/nlarrea.py",
    "content": "\"\"\"\n * EJERCICIO:\n * ¡La temporada 2 de \"Los Anillos de Poder\" está a punto de estrenarse! \n * ¿Qué pasaría si tuvieras que encargarte de repartir los anillos\n * entre las razas de la Tierra Media?\n * Desarrolla un programa que se encargue de distribuirlos.\n * Requisitos:\n * 1. Los Elfos recibirán un número impar.\n * 2. Los Enanos un número primo.\n * 3. Los Hombres un número par.\n * 4. Sauron siempre uno.\n * Acciones:\n * 1. Crea un programa que reciba el número total de anillos\n *    y busque una posible combinación para repartirlos.\n * 2. Muestra el reparto final o el error al realizarlo.\n\"\"\"\n\n\ndef is_even(number: int) -> bool:\n    return number % 2 == 0\n\n\ndef is_prime(number: int) -> bool:\n    if number < 2:\n        return False\n\n    for n in range(2, number):\n        if number % n == 0:\n            return False\n\n    return True\n\n\ndef odd_numbers(number: int) -> list[int]:\n    return list(filter(lambda n: not is_even(n), range(1, number)))\n\n\ndef even_numbers(number: int) -> list[int]:\n    return list(filter(lambda n: is_even(n), range(1, number)))\n\n\ndef ask_rings() -> int:\n    while True:\n        try:\n            rings = input(\"Introduce la cantidad de anillos a repartir:\\n > \")\n            assert (\n                rings.isnumeric() and int(rings) > 0\n            ), \"\\nDebes introducir un número entero positivo (>0).\"\n        except AssertionError as error:\n            print(error)\n        else:\n            return int(rings)\n\n\ndef combine_options(total_rings: int) -> list[dict[str, int]]:\n    solution = []\n\n    # Give one ring to Sauron\n    total_rings -= 1\n\n    # Get possible values for the rest races\n    for man in even_numbers(total_rings):\n        for elf in odd_numbers(total_rings):\n            dwarf = total_rings - elf - man\n            if dwarf > 0 and is_prime(dwarf):\n                solution.append(\n                    {\n                        \"Elfos\": elf,\n                        \"Enanos\": dwarf,\n                        \"Hombres\": man,\n                        \"Sauron\": 1,\n                    }\n                )\n\n    return solution\n\n\ndef print_result(results: list[dict[str, int]]):\n    if not results:\n        print(\"No se ha encontrado ninguna solución.\")\n        return\n\n    for i, result in enumerate(results):\n        print(f\"\\nSOLUCIÓN {i + 1}:\")\n        for race, ring_qty in result.items():\n            print(f\"{race}: {ring_qty}\")\n\n\ndef repartition():\n    total_rings = ask_rings()\n\n    results = combine_options(total_rings)\n    print_result(results)\n\n\nif __name__ == \"__main__\":\n    repartition()\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/python/oriaj3.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * ¡La temporada 2 de \"Los Anillos de Poder\" está a punto de estrenarse! \n * ¿Qué pasaría si tuvieras que encargarte de repartir los anillos\n * entre las razas de la Tierra Media?\n * Desarrolla un programa que se encargue de distribuirlos.\n * Requisitos:\n * 1. Los Elfos recibirán un número impar.\n * 2. Los Enanos un número primo.\n * 3. Los Hombres un número par.\n * 4. Sauron siempre uno.\n * Acciones:\n * 1. Crea un programa que reciba el número total de anillos\n *    y busque una posible combinación para repartirlos.\n * 2. Muestra el reparto final o el error al realizarlo.\n */\n\"\"\"\ndef es_par(numero):\n    if numero%2 == 0:\n        return True\n    else:\n        return False\n\ndef es_primo(numero):\n    es_primo = True\n    if numero<2:\n        return False\n    for i in range(2, int(numero/2 + 1 )):\n        if numero % i == 0:\n            es_primo = False\n    if es_primo:\n        return True\n    else:\n        return False\n    \ndef distribucion_anillos(anillos):\n    sauron = 1\n    anillos -= sauron\n    distribuciones = []\n    for hombres in range (2, anillos, 2):\n        for elfos in range (1, anillos, 2):\n            enanos = anillos - hombres - elfos\n            if enanos > 0 and es_primo(enanos):\n                distribuciones.append(\n                    {\n                        \"Hombres\": hombres, \n                        \"Elfos\": elfos,\n                        \"Enanos\": enanos,\n                        \"Saruon\": sauron\n                    }\n                )\n    if distribuciones:\n        return distribuciones\n    else:\n        return \"No es posible repartir los anillos según las normas. \"\ntry:    \n    anillos_user = int(input(\"Introduce el número de anillos de poder a repartir: \"))\n    distribucion_user = distribucion_anillos(anillos_user)\n    if isinstance(distribucion_user, list):\n        for index, item in enumerate(distribucion_user):\n            print(f\"{index}. {item}\")\n\n        print(f\"La distribución elegida/media es: \\n {distribucion_user[int(len(distribucion_user)/2)]}\")\n    else:\n        print(distribucion_user)\nexcept ValueError:\n    print(\"Introduce un número válido. \")"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/python/pyramsd.py",
    "content": "from random import randint\n\ndef is_prime(number:int):\n    if number ==1:\n        return False\n    else:\n        for index in range(2,int(number**0.5)+1):\n            if number % index == 0:\n                return False\n    return True\n    \ndef is_odd(number:int):\n    return number % 2 != 0\n\nTHE_ONE_RING = 1\n\ndef repartir_anillos(rings: int):\n        \n    if rings <= 5:\n        return \"No hay suficientes anillos para repartir\"\n    \n    sauron = THE_ONE_RING\n    while True:\n            rings_aux = rings-sauron\n            men = randint(1, rings_aux//2) *2\n            rings_aux -= men\n            if rings_aux >= 3:\n                    dwarven = randint(1,rings_aux)\n                    if is_prime(dwarven):\n                        rings_aux -= dwarven\n                        if rings_aux > 0:\n                            elven = rings_aux\n                            if is_odd(elven):\n                                if sauron+men+dwarven+elven == rings:\n                                    print(\"LOS ANILLOS SE HAN REPARTIDO CORRECTAMENTE\")\n                                    return f\"TOTAL DE ANILLOS: {rings}\\n- SAURON: {sauron}\\n- HOMBRES: {men}\\n- ENANOS: {dwarven}\\n- ELFOS: {elven}\"\n\n\nif __name__ == \"__main__\":\n    rings = int(input(\"Dime el número de Anillos de Poder a Repartir: \"))\n    resultado = repartir_anillos(rings)\n    print(resultado)\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/python/raulG91.py",
    "content": "import random\ndef is_prime(number:int)->bool:\n    for i in range(2,int(number ** 0.5) +1):\n       if number % i == 0:\n           return False\n    return True          \n\ndef distribute_rings(number_rings:int)->list:\n    sauron = 1\n    pending_rings = number_rings -1\n    division = []\n    for human in range(2,pending_rings,2):\n        for elf in range(1,pending_rings,2):\n            dwarves = pending_rings -  human - elf\n\n            if dwarves > 0 and is_prime(dwarves):\n                division.append({\n\n                    'sauron':sauron,\n                    'human': human,\n                    'elf':elf,\n                    'dwarves': dwarves\n                }\n                )\n    return division            \n\nnumber_rings = int(input(\"Enter number of rings \"))\nif number_rings >=5:\n    result = distribute_rings(number_rings)\n    if result:\n        print(random.choices(result))\n\nelse:\n    print(\"At least 5 rings are needed \")    "
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/python/redom69.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * ¡La temporada 2 de \"Los Anillos de Poder\" está a punto de estrenarse! \n * ¿Qué pasaría si tuvieras que encargarte de repartir los anillos\n * entre las razas de la Tierra Media?\n * Desarrolla un programa que se encargue de distribuirlos.\n * Requisitos:\n * 1. Los Elfos recibirán un número impar.\n * 2. Los Enanos un número primo.\n * 3. Los Hombres un número par.\n * 4. Sauron siempre uno.\n * Acciones:\n * 1. Crea un programa que reciba el número total de anillos\n *    y busque una posible combinación para repartirlos.\n * 2. Muestra el reparto final o el error al realizarlo.\n */\n\"\"\"\ndef is_prime(n):\n    if n <= 1:\n        return False\n    if n <= 3:\n        return True\n    if n % 2 == 0 or n % 3 == 0:\n        return False\n    i = 5\n    while i * i <= n:\n        if n % i == 0 or n % (i + 2) == 0:\n            return False\n        i += 6\n    return True\n\ndef find_all_primes(max_n):\n    return [i for i in range(2, max_n + 1) if is_prime(i)]\n\ndef find_all_pars(max_n):\n    return [i for i in range(2, max_n + 1, 2)]\n\ndef find_all_odds(max_n):\n    return [i for i in range(1, max_n + 1, 2)]\n\ndef distribute_rings(rings):\n    rings = int(rings) - 1  # Uno es siempre para Sauron\n    if rings < 3:\n        print(\"El número de anillos es insuficiente para cumplir con los requisitos.\")\n        return None\n\n    primes = find_all_primes(rings)\n    odds = find_all_odds(rings)\n    pars = find_all_pars(rings)\n\n    best_distribution = None\n\n    for dwarf_rings in primes:\n        for elf_rings in odds:\n            for human_rings in pars:\n                if dwarf_rings + elf_rings + human_rings == rings:\n                    current_distribution = {\n                        \"Enanos\": dwarf_rings,\n                        \"Elfos\": elf_rings,\n                        \"Humanos\": human_rings,\n                        \"Sauron\": 1\n                    }\n                    if best_distribution is None or (\n                        current_distribution[\"Enanos\"] + current_distribution[\"Elfos\"] + current_distribution[\"Humanos\"] >\n                        best_distribution[\"Enanos\"] + best_distribution[\"Elfos\"] + best_distribution[\"Humanos\"]\n                    ):\n                        best_distribution = current_distribution\n\n    if best_distribution:\n        return best_distribution\n    else:\n        print(\"No se pudo encontrar una distribución válida.\")\n        return None\n\ndef print_distribution(distribution):\n    for race, count in distribution.items():\n        print(f\"{race}: {count} anillos\")\n\ndef main():\n    rings = input(\"Introduce el número de anillos de poder: \")\n    distribution = distribute_rings(rings)\n    if distribution:\n        print_distribution(distribution)\n    else:\n        print('No se han podido repartir los anillos correctamente.')\n\nif __name__ == \"__main__\":\n    main()\n\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/python/rigo93acosta.py",
    "content": "'''\n/*\n * EJERCICIO:\n * ¡La temporada 2 de \"Los Anillos de Poder\" está a punto de estrenarse! \n * ¿Qué pasaría si tuvieras que encargarte de repartir los anillos\n * entre las razas de la Tierra Media?\n * Desarrolla un programa que se encargue de distribuirlos.\n * Requisitos:\n * 1. Los Elfos recibirán un número impar.\n * 2. Los Enanos un número primo.\n * 3. Los Hombres un número par.\n * 4. Sauron siempre uno.\n * Acciones:\n * 1. Crea un programa que reciba el número total de anillos\n *    y busque una posible combinación para repartirlos.\n * 2. Muestra el reparto final o el error al realizarlo.\n */\n'''\n\ndef is_prime(number: int) -> bool:\n    if number < 2:\n        return False\n    for i in range(2, int((number ** 0.5)+1)):\n        if number % i == 0:\n            return False\n    return True\n\n\n\ndef distribute_rings(total_rings: int):\n\n    distributed_rings = []\n\n    sauron = 1\n    total_rings -= sauron\n\n    for men in range(2, total_rings, 2):\n        for elves in range(1, total_rings, 2):\n\n            dwarves = total_rings - elves - men\n\n            if dwarves > 0 and is_prime(dwarves):\n                \n                distributed_rings.append({\n                    \"Hombres\": men,\n                    \"Elfos\": elves,\n                    \"Enanos\": dwarves,\n                    \"Sauron\": sauron\n                })\n\n    if distributed_rings:\n        return distributed_rings\n    return \"Error: No es posible repartir los anillos.\"\n    \nif __name__ == '__main__':\n    \n    try:\n        total_rings = int(\n            input('Introduce el número de anillos a repartir: ')\n        )\n        \n        distributed_rings = distribute_rings(total_rings)\n\n        if isinstance(distributed_rings, list):\n            print(\"Posibles distribuciones de los anillos de poder:\\n\")\n            for distribution in enumerate(distributed_rings):\n                print(f\"{distribution[0] + 1}. {distribution[1]}\")\n\n            print(f\"\\nDistribución media: {distributed_rings[int(len(distributed_rings) / 2)]}\")\n        else:\n            print(distributed_rings)\n    except ValueError:\n        print('Error, el número debe ser un entero.')\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/python/santyjl.py",
    "content": "# #35 REPARTIENDO LOS ANILLOS DE PODER\n#### Dificultad: Media | Publicación: 26/08/24 | Corrección: 02/09/24\n\n\"\"\"\n/*\n * EJERCICIO:\n * ¡La temporada 2 de \"Los Anillos de Poder\" está a punto de estrenarse!\n * ¿Qué pasaría si tuvieras que encargarte de repartir los anillos\n * entre las razas de la Tierra Media?\n * Desarrolla un programa que se encargue de distribuirlos.\n * Requisitos:\n * 1. Los Elfos recibirán un número impar.\n * 2. Los Enanos un número primo.\n * 3. Los Hombres un número par.\n * 4. Sauron siempre uno.\n * Acciones:\n * 1. Crea un programa que reciba el número total de anillos\n *    y busque una posible combinación para repartirlos.\n * 2. Muestra el reparto final o el error al realizarlo.\n */\n\"\"\"\n\nimport random\n\n\ndef pares (num):\n    lista = []\n    for i in range(num):\n        if i % 2 == 0 and i != 0:\n            lista.append(i)\n\n    return random.choice(lista)\n\ndef impar(num):\n    lista= []\n    for i in range(num):\n        if i % 2 != 0 and i != 0:\n            lista.append(i)\n\n    return random.choice(lista)\n\ndef es_primo(num:int):\n    if num == 1:\n        return False\n\n    for i in range(2 , int(num ** 0.5) + 1):\n        if num % i == 0:\n            return False\n\n    return True\n\ndef repartir_anillos(num:int):\n    num_total = num - 1\n\n    anillos_elfos = 0\n    anillos_enanos = 0\n    anillos_humanos = 0\n    SAURON = 1\n\n\n    while num_total > 0 :\n        anillos_elfos = impar(num_total)\n        num_total -= anillos_elfos\n\n        anillos_humanos = pares(num_total)\n        num_total -= anillos_humanos\n\n        if es_primo(num_total):\n            anillos_enanos = num_total\n            num_total = 0\n\n            return anillos_elfos , anillos_humanos , anillos_enanos , SAURON\n\n        num_total = num - 1\n\n\ntry:\n    anillos_elfos , anillos_humanos , anillos_enanos , SAURON = repartir_anillos(10)\n\n    print(\"los elfos tienen un total de : \" , anillos_elfos , \"anillos del poder\")\n    print(\"los humanos tienen un total de : \" , anillos_humanos , \"anillos del poder\")\n    print(\"los enanos tienen un total de : \" , anillos_enanos , \"anillos del poder\")\n    print(\"los Sauron tienen un total de : \" , SAURON , \"anillos del poder\")\nexcept Exception:\n        print(\"ha habido un error al momento de repartir los anillos\")"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/rust/kenysdev.rs",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - Rust\n_____________________________________\n35 REPARTIENDO LOS ANILLOS DE PODER\n------------------------------------\n¡La temporada 2 de \"Los Anillos de Poder\" está a punto de estrenarse!\n¿Qué pasaría si tuvieras que encargarte de repartir los anillos\nentre las razas de la Tierra Media?\nDesarrolla un programa que se encargue de distribuirlos.\nRequisitos:\n1. Los Elfos recibirán un número impar.\n2. Los Enanos un número primo.\n3. Los Hombres un número par.\n4. Sauron siempre uno.\nAcciones:\n1. Crea un programa que reciba el número total de anillos\n   y busque una posible combinación para repartirlos.\n2. Muestra el reparto final o el error al realizarlo.\n*/\n\nuse std::io::{self, Write};\n\nfn get_total_rings() -> u32 {\n    loop {\n        print!(\"Cantidad de anillos: \");\n        io::stdout().flush().unwrap();\n        let mut input = String::new();\n        io::stdin().read_line(&mut input).unwrap();\n        match input.trim().parse() {\n            Ok(n) if n >= 1 => return n,\n            _ => println!(\"Debe ser un valor entero '>= 1'.\"),\n        }\n    }\n}\n\nfn is_prime(n: u32) -> bool {\n    if n < 2 {\n        return false;\n    }\n    (2..=(n as f64).sqrt() as u32).all(|i| n % i != 0)\n}\n\nfn standard_deviation(tup: &(u32, u32, u32)) -> f64 {\n    let values = [tup.0 as f64, tup.1 as f64, tup.2 as f64];\n    let avg = values.iter().sum::<f64>() / values.len() as f64;\n    let variance = values.iter().map(|&x| (x - avg).powi(2)).sum::<f64>() / (values.len() - 1) as f64;\n    variance.sqrt()\n}\n\nfn the_most_balanced(combinations: &[(u32, u32, u32)]) -> Option<(u32, u32, u32)> {\n    combinations.iter()\n        .min_by(|&a, &b| standard_deviation(a).partial_cmp(&standard_deviation(b)).unwrap())\n        .cloned()\n}\n\nfn recording_more_accurate_results(mut combinations:Vec<(u32, u32, u32)>) -> Vec<(u32, u32, u32)> {\n    if combinations.len() > 2{\n        let distribution = the_most_balanced(&combinations);\n        combinations.clear();\n        combinations.extend(distribution);\n    }\n    combinations\n }\n\nfn distribute(total: u32) -> Vec<(u32, u32, u32)> {\n    let mut combinations = Vec::new();\n    for elves in (1..total).step_by(2) {\n        for men in (2..total).step_by(2) {\n            let dwarves = total.saturating_sub(men + elves);\n            if dwarves > 0 && is_prime(dwarves) {\n                combinations.push((elves, men, dwarves));\n                combinations = recording_more_accurate_results(combinations.clone())\n            }\n        }\n    }\n    combinations\n}\n\nfn print_result(distribution: Option<(u32, u32, u32)>, sauron: u32) {\n    match distribution {\n        Some((elves, men, dwarves)) => {\n            println!(\"_________________________\");\n            println!(\"🧝 Elfos   -> {} : # Impar\", elves);\n            println!(\"🧔 Enanos  -> {} : # Primo\", dwarves);\n            println!(\"👨 Hombres -> {} : # Par\", men);\n            println!(\"👁️  Sauron  -> {} : # Fijo\", sauron);\n            println!(\"-------------------------\");\n        }\n        None => println!(\"Error en la selección equitativa.\"),\n    }\n}\n\nfn main() {\n    println!(\"REPARTIENDO LOS ANILLOS DE PODER\");\n    let mut total = get_total_rings();\n    let sauron = 1;\n    total -= sauron;\n\n    let combinations = distribute(total);\n    if combinations.is_empty() {\n        println!(\"No existe una combinación posible.\");\n        return;\n    }\n\n    let distribution = the_most_balanced(&combinations);\n    print_result(distribution, sauron);\n}\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/sql/Nicojsuarez2.sql",
    "content": "# #35 REPARTIENDO LOS ANILLOS DE PODER\n> #### Dificultad: Media | Publicación: 26/08/24 | Corrección: 02/09/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * ¡La temporada 2 de \"Los Anillos de Poder\" está a punto de estrenarse! \n * ¿Qué pasaría si tuvieras que encargarte de repartir los anillos\n * entre las razas de la Tierra Media?\n * Desarrolla un programa que se encargue de distribuirlos.\n * Requisitos:\n * 1. Los Elfos recibirán un número impar.\n * 2. Los Enanos un número primo.\n * 3. Los Hombres un número par.\n * 4. Sauron siempre uno.\n * Acciones:\n * 1. Crea un programa que reciba el número total de anillos\n *    y busque una posible combinación para repartirlos.\n * 2. Muestra el reparto final o el error al realizarlo.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/typescript/miguelex.ts",
    "content": "function esPrimo(num: number): boolean {\n    if (num <= 1) return false;\n    if (num === 2) return true;\n    if (num % 2 === 0) return false;\n    \n    for (let i = 3; i <= Math.sqrt(num); i += 2) {\n        if (num % i === 0) return false;\n    }\n    return true;\n}\n\nfunction repartirAnillos(totalAnillos: number): string {\n    if (totalAnillos < 4) {\n        return \"Error: No hay suficientes anillos para cumplir con los requisitos.\";\n    }\n\n    const anillosSauron = 1;\n    totalAnillos -= 1;\n    \n    let mejorDiferencia = Number.MAX_SAFE_INTEGER;\n    let mejorReparto: { Elfos: number, Enanos: number, Hombres: number, Sauron: number } | null = null;\n    \n    for (let anillosElfos = 1; anillosElfos <= totalAnillos; anillosElfos += 2) {\n        for (let anillosEnanos = 2; anillosEnanos <= totalAnillos; anillosEnanos++) {\n            if (esPrimo(anillosEnanos)) {\n                const anillosHombres = totalAnillos - anillosElfos - anillosEnanos;\n                \n                if (anillosHombres > 0 && anillosHombres % 2 === 0) {\n                    const diferencia = Math.max(anillosElfos, anillosEnanos, anillosHombres) - Math.min(anillosElfos, anillosEnanos, anillosHombres);\n                    \n                    if (diferencia < mejorDiferencia) {\n                        mejorDiferencia = diferencia;\n                        mejorReparto = {\n                            Elfos: anillosElfos,\n                            Enanos: anillosEnanos,\n                            Hombres: anillosHombres,\n                            Sauron: anillosSauron\n                        };\n                    }\n                }\n            }\n        }\n    }\n    \n    if (mejorReparto) {\n        return `Reparto exitoso: Elfos = ${mejorReparto.Elfos}, Enanos = ${mejorReparto.Enanos}, Hombres = ${mejorReparto.Hombres}, Sauron = ${mejorReparto.Sauron}`;\n    } else {\n        return \"Error: No se encontró una combinación válida para repartir los anillos.\";\n    }\n}\n\nconst totalAnillos: number = parseInt(prompt(\"Ingresa el número total de anillos: \") || \"0\", 10);\nconst resultado: string = repartirAnillos(totalAnillos);\nconsole.log(resultado);\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/typescript/redom69.ts",
    "content": "import * as readline from 'readline';\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nfunction isPrime(n: number): boolean {\n    if (n <= 1) return false;\n    if (n <= 3) return true;\n    if (n % 2 === 0 || n % 3 === 0) return false;\n    let i = 5;\n    while (i * i <= n) {\n        if (n % i === 0 || n % (i + 2) === 0) return false;\n        i += 6;\n    }\n    return true;\n}\n\nfunction findAllPrimes(max_n: number): number[] {\n    let primes: number[] = [];\n    for (let i = 2; i <= max_n; i++) {\n        if (isPrime(i)) {\n            primes.push(i);\n        }\n    }\n    return primes;\n}\n\nfunction findAllEvens(max_n: number): number[] {\n    let evens: number[] = [];\n    for (let i = 2; i <= max_n; i += 2) {\n        evens.push(i);\n    }\n    return evens;\n}\n\nfunction findAllOdds(max_n: number): number[] {\n    let odds: number[] = [];\n    for (let i = 1; i <= max_n; i += 2) {\n        odds.push(i);\n    }\n    return odds;\n}\n\nfunction distributeRings(rings: number): Record<string, number> | null {\n    rings = rings - 1; // Uno es siempre para Sauron\n    if (rings < 3) {\n        console.log(\"El número de anillos es insuficiente para cumplir con los requisitos.\");\n        return null;\n    }\n\n    const primes = findAllPrimes(rings);\n    const odds = findAllOdds(rings);\n    const evens = findAllEvens(rings);\n\n    let bestDistribution: Record<string, number> | null = null;\n\n    for (let dwarf_rings of primes) {\n        for (let elf_rings of odds) {\n            for (let human_rings of evens) {\n                if (dwarf_rings + elf_rings + human_rings === rings) {\n                    let currentDistribution: Record<string, number> = {\n                        \"Enanos\": dwarf_rings,\n                        \"Elfos\": elf_rings,\n                        \"Humanos\": human_rings,\n                        \"Sauron\": 1\n                    };\n                    if (!bestDistribution || (\n                        currentDistribution[\"Enanos\"] + currentDistribution[\"Elfos\"] + currentDistribution[\"Humanos\"] >\n                        bestDistribution[\"Enanos\"] + bestDistribution[\"Elfos\"] + bestDistribution[\"Humanos\"]\n                    )) {\n                        bestDistribution = currentDistribution;\n                    }\n                }\n            }\n        }\n    }\n\n    if (bestDistribution) {\n        return bestDistribution;\n    } else {\n        console.log(\"No se pudo encontrar una distribución válida.\");\n        return null;\n    }\n}\n\nfunction printDistribution(distribution: Record<string, number>): void {\n    for (let race in distribution) {\n        console.log(`${race}: ${distribution[race]} anillos`);\n    }\n}\n\nrl.question('Introduce el número de anillos de poder: ', (rings) => {\n    console.log(`Has introducido: ${rings}`);\n    const ringCount = parseInt(rings);\n    const distribution = distributeRings(ringCount);\n    if (distribution) {\n        printDistribution(distribution);\n    } else {\n        console.log('No se han podido repartir los anillos correctamente.');\n    }\n    rl.close();\n});\n"
  },
  {
    "path": "Roadmap/35 - REPARTIENDO LOS ANILLOS DE PODER/vb.net/kenysdev.vb",
    "content": "' _____________________________________\n' https://github.com/kenysdev\n' 2024 - vb.net\n' _____________________________________\n' 35 REPARTIENDO LOS ANILLOS DE PODER\n' ------------------------------------\n' ¡La temporada 2 de \"Los Anillos de Poder\" está a punto de estrenarse!\n' ¿Qué pasaría si tuvieras que encargarte de repartir los anillos\n' entre las razas de la Tierra Media?\n' Desarrolla un programa que se encargue de distribuirlos.\n' Requisitos:\n' 1. Los Elfos recibirán un número impar.\n' 2. Los Enanos un número primo.\n' 3. Los Hombres un número par.\n' 4. Sauron siempre uno.\n' Acciones:\n' 1. Crea un programa que reciba el número total de anillos\n'   y busque una posible combinación para repartirlos.\n' 2. Muestra el reparto final o el error al realizarlo.\n\nModule Program\n    Function GetTotalRings() As Integer\n        Do\n            Console.Write(\"Cantidad de anillos: \")\n            Dim input = Console.ReadLine()\n            Dim result As Integer\n            If Integer.TryParse(input, result) AndAlso result >= 1 Then\n                Return result\n            End If\n            Console.WriteLine(\"Debe ser un valor entero '>= 1'.\")\n        Loop\n    End Function\n\n    Function IsPrime(n As Integer) As Boolean\n        If n < 2 Then Return False\n        For i As Integer = 2 To Math.Sqrt(n)\n            If n Mod i = 0 Then Return False\n        Next\n        Return True\n    End Function\n\n    Function Distribute(total As Integer) As List(Of (Integer, Integer, Integer))\n        Dim combinations As New List(Of (Integer, Integer, Integer))\n        Dim range As Integer\n        Dim start As Integer\n        Dim [end] As Integer\n\n        If total > 1000 Then\n            ' For large numbers.\n            range = Math.Min(1000, total \\ 3)\n            start = (total - range) \\ 2\n            [end] = start + range\n        Else\n            ' For smaller numbers.\n            start = 1\n            [end] = total - 1\n        End If\n\n        For elves As Integer = start To [end] Step 2\n            For men As Integer = start + 1 To [end] Step 2\n                Dim dwarves As Integer = total - (men + elves)\n                If dwarves > 0 AndAlso IsPrime(dwarves) Then\n                    combinations.Add((elves, men, dwarves))\n                End If\n            Next\n        Next\n\n        Return combinations\n    End Function\n\n    Function StandardDeviation(tup As (Integer, Integer, Integer)) As Double\n        Dim values() As Double = {tup.Item1, tup.Item2, tup.Item3}\n        Dim avg As Double = values.Average()\n        Dim sum As Double = values.Sum(Function(d) Math.Pow(d - avg, 2))\n        Return Math.Sqrt(sum / (values.Length - 1))\n    End Function\n\n    Function TheMostBalanced(combinations As List(Of (Integer, Integer, Integer))) As (Integer, Integer, Integer)\n        Return combinations.OrderBy(Function(c) StandardDeviation(c)).First()\n    End Function\n\n    Sub PrintResult(distribution As (Integer, Integer, Integer), sauron As Integer)\n        If distribution.Equals(Nothing) Then\n            Console.WriteLine(\"Error en la selección equitativa.\")\n            Return\n        End If\n\n        Console.WriteLine(\"_________________________\")\n        Console.WriteLine($\"Elfos   -> {distribution.Item1} : # Impar\")\n        Console.WriteLine($\"Enanos  -> {distribution.Item3} : # Primo\")\n        Console.WriteLine($\"Hombres -> {distribution.Item2} : # Par\")\n        Console.WriteLine($\"Sauron  -> {sauron} : # Fijo\")\n        Console.WriteLine(\"-------------------------\")\n    End Sub\n\n    Sub Main()\n        Console.WriteLine(\"REPARTIENDO LOS ANILLOS DE PODER\")\n        Dim total As Integer = GetTotalRings()\n        Dim sauron As Integer = 1\n        total -= sauron\n\n        Dim combinations = Distribute(total)\n        If combinations.Count = 0 Then\n            Console.WriteLine(\"No existe una combinación posible.\")\n            Return\n        End If\n\n        Dim distribution = TheMostBalanced(combinations)\n        PrintResult(distribution, sauron)\n    End Sub\nEnd Module\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/c#/deathwing696.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Linq;\nusing System.Runtime.Remoting.Messaging;\nusing System.Text;\nusing System.Threading;\n\n/*\n * EJERCICIO:\n * Cada 1 de septiembre, el Hogwarts Express parte hacia la escuela\n * de programación de Hogwarts para magos y brujas del código.\n * En ella, su famoso sombrero seleccionador ayuda a los programadores\n * a encontrar su camino...\n * Desarrolla un programa que simule el comportamiento del sombrero.\n * Requisitos:\n * 1. El sombrero realizará 10 preguntas para determinar la casa del alumno.\n * 2. Deben existir 4 casas. Por ejemplo: Frontend, Backend, Mobile y Data.\n *    (Puedes elegir las que quieras)\n * Acciones:\n * 1. Crea un programa que solicite el nombre del alumno y realice 10\n *    preguntas, con cuatro posibles respuestas cada una.\n * 2. Cada respuesta asigna puntos a cada una de las casas (a tu elección).\n * 3. Una vez finalizado, el sombrero indica el nombre del alumno \n *    y a qué casa pertenecerá (resuelve el posible empate de manera aleatoria,\n *    pero indicándole al alumno que la decisión ha sido complicada).\n */\n\nnamespace Reto_36\n{\n    public class sortingHat\n    {\n        private int frontendPoints, backendPoints, mobilePoints, dataPoints;\n\n        public int FrontendPoints { get { return frontendPoints; } }\n        public int BackendPoints { get { return backendPoints; } }\n        public int MobilePoints { get { return mobilePoints; } }\n        public int DataPoints { get { return dataPoints; } }\n\n        public string Name { get; set; }\n\n        public sortingHat()\n        {\n            frontendPoints = 0;\n            backendPoints = 0;\n            mobilePoints = 0;\n            dataPoints = 0;\n        }\n\n        public void AskQuestion(int number)\n        {\n            switch (number)\n            {\n                case 1:\n                    AskQuestion1();\n                    break;\n                case 2:\n                    AskQuestion2();\n                    break;\n                case 3:\n                    AskQuestion3();\n                    break;\n                case 4:\n                    AskQuestion4();\n                    break;\n                case 5:\n                    AskQuestion5();\n                    break;\n                case 6:\n                    AskQuestion6();\n                    break;\n                case 7:\n                    AskQuestion7();\n                    break;\n                case 8:\n                    AskQuestion8();\n                    break;\n                case 9:\n                    AskQuestion9();\n                    break;\n                case 10:\n                    AskQuestion10();\n                    break;\n                default:\n                    break;\n            }\n        }\n\n        private void AskQuestion1()\n        {\n            int response;\n            Console.WriteLine(\"Pregunta 1: ¿Qué tecnología elegirías para desarrollar una interfaz de usuario interactiva?\\r\\n\\r    1.React\\r\\n    2.Vue\\r\\n    3.Angular.js\\r\\n    4.Ni pajolera idea de lo que me hablas\");\n            Console.Write(\"Respuesta: \");\n            try\n            {\n                response = Int16.Parse(Console.ReadLine());\n            }\n            catch\n            {\n                response = 0;\n            }\n\n            switch (response)\n            {\n                case 1:\n                    frontendPoints += 5;\n                    backendPoints += 1;\n                    mobilePoints += 2;\n                    dataPoints += 1;\n                    break;\n                case 2:\n                    frontendPoints += 5;\n                    backendPoints += 1;\n                    mobilePoints += 1;\n                    dataPoints += 2;\n                    break;\n                case 3:\n                    frontendPoints += 4;\n                    backendPoints += 2;\n                    mobilePoints += 1;\n                    dataPoints += 2;\n                    break;\n                case 4:\n                    Console.WriteLine(\"No te preocupes, pasamos a la siguiente pregunta, verás como se te da mejor\");\n                    break;\n                default:\n                    Console.WriteLine(\"Respuesta incorrecta, pasamos a la siguiente pregunta\");\n                    break;\n            }\n        }\n\n        private void AskQuestion2()\n        {\n            int response;\n            Console.WriteLine(\"Pregunta 2: ¿Qué base de datos usarías para una aplicación con alta disponibilidad y escalabilidad?\\r\\n\\r    1.MongoDB\\r\\n    2.PostgreSQL\\r\\n    3.Firebase Realtime Database\\r\\n    4.Ni pajolera idea de lo que me hablas\");\n            Console.Write(\"Respuesta: \");\n            try\n            {\n                response = Int16.Parse(Console.ReadLine());\n            }\n            catch\n            {\n                response = 0;\n            }\n\n\n            switch (response)\n            {\n                case 1:\n                    frontendPoints += 1;\n                    backendPoints += 4;\n                    mobilePoints += 2;\n                    dataPoints += 3;\n                    break;\n                case 2:\n                    frontendPoints += 1;\n                    backendPoints += 4;\n                    mobilePoints += 1;\n                    dataPoints += 4;\n                    break;\n                case 3:\n                    frontendPoints += 2;\n                    backendPoints += 3;\n                    mobilePoints += 3;\n                    dataPoints += 2;\n                    break;\n                case 4:\n                    Console.WriteLine(\"No te preocupes, pasamos a la siguiente pregunta, verás como se te da mejor\");\n                    break;\n                default:\n                    Console.WriteLine(\"Respuesta incorrecta, pasamos a la siguiente pregunta\");\n                    break;\n            }\n        }\n\n        private void AskQuestion3()\n        {\n            int response;\n            Console.WriteLine(\"Pregunta 3: ¿Qué herramienta utilizarías para control de versiones en un proyecto de desarrollo?\\r\\n\\r    1.Git\\r\\n    2.Mercurial\\r\\n    3.Subversion\\r\\n    4.Ni pajolera idea de lo que me hablas\");\n            Console.Write(\"Respuesta: \");\n            try\n            {\n                response = Int16.Parse(Console.ReadLine());\n            }\n            catch\n            {\n                response = 0;\n            }\n\n            switch (response)\n            {\n                case 1:\n                    frontendPoints += 3;\n                    backendPoints += 3;\n                    mobilePoints += 2;\n                    dataPoints += 2;\n                    break;\n                case 2:\n                    frontendPoints += 2;\n                    backendPoints += 2;\n                    mobilePoints += 2;\n                    dataPoints += 2;\n                    break;\n                case 3:\n                    frontendPoints += 2;\n                    backendPoints += 2;\n                    mobilePoints += 2;\n                    dataPoints += 2;\n                    break;\n                case 4:\n                    Console.WriteLine(\"No te preocupes, pasamos a la siguiente pregunta, verás como se te da mejor\");\n                    break;\n                default:\n                    Console.WriteLine(\"Respuesta incorrecta, pasamos a la siguiente pregunta\");\n                    break;\n            }\n        }\n\n        private void AskQuestion4()\n        {\n            int response;\n            Console.WriteLine(\"Pregunta 4: ¿Cuál es tu framework preferido para desarrollo backend?\\r\\n\\r    1.Express.js\\r\\n    2.Django\\r\\n    3.Spring Boot\\r\\n    4.Ni pajolera idea de lo que me hablas\");\n            Console.Write(\"Respuesta: \");\n            try\n            {\n                response = Int16.Parse(Console.ReadLine());\n            }\n            catch\n            {\n                response = 0;\n            }\n\n            switch (response)\n            {\n                case 1:\n                    frontendPoints += 2;\n                    backendPoints += 5;\n                    mobilePoints += 2;\n                    dataPoints += 1;\n                    break;\n                case 2:\n                    frontendPoints += 2;\n                    backendPoints += 5;\n                    mobilePoints += 1;\n                    dataPoints += 2;\n                    break;\n                case 3:\n                    frontendPoints += 1;\n                    backendPoints += 5;\n                    mobilePoints += 2;\n                    dataPoints += 2;\n                    break;\n                case 4:\n                    Console.WriteLine(\"No te preocupes, pasamos a la siguiente pregunta, verás como se te da mejor\");\n                    break;\n                default:\n                    Console.WriteLine(\"Respuesta incorrecta, pasamos a la siguiente pregunta\");\n                    break;\n            }\n        }\n\n        private void AskQuestion5()\n        {\n            int response;\n            Console.WriteLine(\"Pregunta 5: ¿Qué lenguaje de programación prefieres para desarrollar aplicaciones móviles?\\r\\n\\r    1.Swift\\r\\n    2.Kotlin\\r\\n    3.JavaScript\\r\\n    4.Ni pajolera idea de lo que me hablas\");\n            Console.Write(\"Respuesta: \");\n            try\n            {\n                response = Int16.Parse(Console.ReadLine());\n            }\n            catch\n            {\n                response = 0;\n            }\n\n            switch (response)\n            {\n                case 1:\n                    frontendPoints += 2;\n                    backendPoints += 1;\n                    mobilePoints += 5;\n                    dataPoints += 1;\n                    break;\n                case 2:\n                    frontendPoints += 2;\n                    backendPoints += 2;\n                    mobilePoints += 5;\n                    dataPoints += 1;\n                    break;\n                case 3:\n                    frontendPoints += 3;\n                    backendPoints += 2;\n                    mobilePoints += 4;\n                    dataPoints += 1;\n                    break;\n                case 4:\n                    Console.WriteLine(\"No te preocupes, pasamos a la siguiente pregunta, verás como se te da mejor\");\n                    break;\n                default:\n                    Console.WriteLine(\"Respuesta incorrecta, pasamos a la siguiente pregunta\");\n                    break;\n            }\n        }\n\n        private void AskQuestion6()\n        {\n            int response;\n            Console.WriteLine(\"Pregunta 6: ¿Qué metodología ágil prefieres para gestionar tus proyectos de desarrollo?\\r\\n\\r    1.Scrum\\r\\n    2.Kanban\\r\\n    3.XP (Extreme Programming)\\r\\n    4.Ni pajolera idea de lo que me hablas\");\n            Console.Write(\"Respuesta: \");\n            try\n            {\n                response = Int16.Parse(Console.ReadLine());\n            }\n            catch\n            {\n                response = 0;\n            }\n\n            switch (response)\n            {\n                case 1:\n                    frontendPoints += 3;\n                    backendPoints += 3;\n                    mobilePoints += 3;\n                    dataPoints += 3;\n                    break;\n                case 2:\n                    frontendPoints += 3;\n                    backendPoints += 3;\n                    mobilePoints += 3;\n                    dataPoints += 3;\n                    break;\n                case 3:\n                    frontendPoints += 3;\n                    backendPoints += 3;\n                    mobilePoints += 3;\n                    dataPoints += 1;\n                    break;\n                case 4:\n                    Console.WriteLine(\"No te preocupes, pasamos a la siguiente pregunta, verás como se te da mejor\");\n                    break;\n                default:\n                    Console.WriteLine(\"Respuesta incorrecta, pasamos a la siguiente pregunta\");\n                    break;\n            }\n        }\n\n        private void AskQuestion7()\n        {\n            int response;\n            Console.WriteLine(\"Pregunta 7: ¿Qué herramienta prefieres para pruebas automáticas en frontend?\\r\\n\\r    1.Jest\\r\\n    2.Cypress\\r\\n    3.Mocha\\r\\n    4.Ni pajolera idea de lo que me hablas\");\n            Console.Write(\"Respuesta: \");\n            try\n            {\n                response = Int16.Parse(Console.ReadLine());\n            }\n            catch\n            {\n                response = 0;\n            }\n\n            switch (response)\n            {\n                case 1:\n                    frontendPoints += 4;\n                    backendPoints += 2;\n                    mobilePoints += 2;\n                    dataPoints += 2;\n                    break;\n                case 2:\n                    frontendPoints += 4;\n                    backendPoints += 2;\n                    mobilePoints += 2;\n                    dataPoints += 2;\n                    break;\n                case 3:\n                    frontendPoints += 4;\n                    backendPoints += 2;\n                    mobilePoints += 2;\n                    dataPoints += 2;\n                    break;\n                case 4:\n                    Console.WriteLine(\"No te preocupes, pasamos a la siguiente pregunta, verás como se te da mejor\");\n                    break;\n                default:\n                    Console.WriteLine(\"Respuesta incorrecta, pasamos a la siguiente pregunta\");\n                    break;\n            }\n        }\n\n        private void AskQuestion8()\n        {\n            int response;\n            Console.WriteLine(\"Pregunta 8: ¿Cuál es tu enfoque preferido para manejar la autenticación en una aplicación web?\\r\\n\\r    1.OAuth\\r\\n    2.JWT (JSON Web Token)\\r\\n    3.Session-based\\r\\n    4.Ni pajolera idea de lo que me hablas\");\n            Console.Write(\"Respuesta: \");\n            try\n            {\n                response = Int16.Parse(Console.ReadLine());\n            }\n            catch\n            {\n                response = 0;\n            }\n\n            switch (response)\n            {\n                case 1:\n                    frontendPoints += 2;\n                    backendPoints += 4;\n                    mobilePoints += 2;\n                    dataPoints += 2;\n                    break;\n                case 2:\n                    frontendPoints += 2;\n                    backendPoints += 4;\n                    mobilePoints += 3;\n                    dataPoints += 1;\n                    break;\n                case 3:\n                    frontendPoints += 2;\n                    backendPoints += 4;\n                    mobilePoints += 2;\n                    dataPoints += 2;\n                    break;\n                case 4:\n                    Console.WriteLine(\"No te preocupes, pasamos a la siguiente pregunta, verás como se te da mejor\");\n                    break;\n                default:\n                    Console.WriteLine(\"Respuesta incorrecta, pasamos a la siguiente pregunta\");\n                    break;\n            }\n        }\n\n        private void AskQuestion9()\n        {\n            int response;\n            Console.WriteLine(\"Pregunta 9: ¿Qué estrategia de despliegue prefieres para tus aplicaciones?\\r\\n\\r    1.CI/CD con Jenkins\\r\\n    2.GitHub Actions\\r\\n    3.CircleCI\\r\\n    4.Ni pajolera idea de lo que me hablas\");\n            Console.Write(\"Respuesta: \");\n            try\n            {\n                response = Int16.Parse(Console.ReadLine());\n            }\n            catch\n            {\n                response = 0;\n            }\n\n            switch (response)\n            {\n                case 1:\n                    frontendPoints += 2;\n                    backendPoints += 5;\n                    mobilePoints += 3;\n                    dataPoints += 2;\n                    break;\n                case 2:\n                    frontendPoints += 3;\n                    backendPoints += 4;\n                    mobilePoints += 3;\n                    dataPoints += 2;\n                    break;\n                case 3:\n                    frontendPoints += 3;\n                    backendPoints += 4;\n                    mobilePoints += 3;\n                    dataPoints += 2;\n                    break;\n                case 4:\n                    Console.WriteLine(\"No te preocupes, pasamos a la siguiente pregunta, verás como se te da mejor\");\n                    break;\n                default:\n                    Console.WriteLine(\"Respuesta incorrecta, pasamos a la siguiente pregunta\");\n                    break;\n            }\n        }\n\n        private void AskQuestion10()\n        {\n            int response;\n            Console.WriteLine(\"Pregunta 10: ¿Qué enfoque prefieres para el análisis de datos en tus aplicaciones?\\r\\n\\r    1.Python con Pandas\\r\\n    2.R\\r\\n    3.SQL\\r\\n    4.Ni pajolera idea de lo que me hablas\");\n            Console.Write(\"Respuesta: \");\n            try\n            {\n                response = Int16.Parse(Console.ReadLine());\n            }\n            catch\n            {\n                response = 0;\n            }\n\n            switch (response)\n            {\n                case 1:\n                    frontendPoints += 1;\n                    backendPoints += 2;\n                    mobilePoints += 1;\n                    dataPoints += 5;\n                    break;\n                case 2:\n                    frontendPoints += 1;\n                    backendPoints += 2;\n                    mobilePoints += 1;\n                    dataPoints += 5;\n                    break;\n                case 3:\n                    frontendPoints += 1;\n                    backendPoints += 3;\n                    mobilePoints += 1;\n                    dataPoints += 4;\n                    break;\n                case 4:\n                    Console.WriteLine(\"No te preocupes, pasamos a la siguiente pregunta, verás como se te da mejor\");\n                    break;\n                default:\n                    Console.WriteLine(\"Respuesta incorrecta, pasamos a la siguiente pregunta\");\n                    break;\n            }\n        }\n\n        internal void AsignHouse()\n        {\n            List<Tuple<string, int>> puntuation = new List<Tuple<string, int>>();\n            puntuation.Add(new Tuple<string, int>(\"frontend\", frontendPoints));\n            puntuation.Add(new Tuple<string, int>(\"backend\", backendPoints));\n            puntuation.Add(new Tuple<string, int>(\"mobile\", mobilePoints));\n            puntuation.Add(new Tuple<string, int>(\"data\", dataPoints));\n\n            puntuation.Sort((x,y) =>\n            {\n                var result = y.Item2.CompareTo(x.Item2);\n\n                if (result == 0)\n                    result = x.Item1.CompareTo(y.Item1);\n\n                return result;\n            });\n\n            if (puntuation.First().Item2 == puntuation.ElementAt(1).Item2)\n            {\n                Console.WriteLine(\"Ha sido una difícil elección...mmmmmm....pero creo que lo tengo...\");\n                Thread.Sleep(2000);\n            }\n\n            string houseName = puntuation.First().Item1;\n\n            switch (houseName)\n            {\n                case \"frontend\":\n                    Console.WriteLine($\"¡Enhorabuena {Name}! Has sido asignado a la casa Frontend\");\n                    break;\n                case \"backend\":\n                    Console.WriteLine($\"¡Enhorabuena {Name}! Has sido asignado a la casa Backend\");\n                    break;\n                case \"mobile\":\n                    Console.WriteLine($\"¡Enhorabuena {Name}! Has sido asignado a la casa Mobile\");\n                    break;\n                case \"data\":\n                    Console.WriteLine($\"¡Enhorabuena {Name}! Has sido asignado a la casa Data\");\n                    break;\n            }\n        }\n    }\n    internal class deathwing696\n    {        \n        static void Main(string[] args)\n        {            \n            sortingHat sortingHat = new sortingHat();\n\n            Console.WriteLine(\"Bienvenido a Hogwarts, soy el sombrero seleccionador y voy a intentar asignarte una de las cuatro casas posibles: Frontend, Backend, Mobile o Data\");\n            Console.WriteLine(\"Te haré diez preguntas, según tus respuestas te asignaré a una de las casas anteriores, ¿Estás preparado?\");\n            Console.Write(\"Primero de nada, dime cómo te llamas:\");\n            sortingHat.Name = Console.ReadLine();\n            Console.WriteLine($\"Perfecto {sortingHat.Name}, ¡Comenzamos!\");\n\n            for (int i = 1; i < 11; i++)\n            {\n                sortingHat.AskQuestion(i);\n            }\n\n            sortingHat.AsignHouse();\n\n            Console.ReadKey();\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/c#/hequebo.cs",
    "content": "class Question\n{\n    public string _Question { get; set; }\n    public Dictionary<int, string> Options { get; set; }\n\n    public Question(string question, Dictionary<int, string> options)\n    {\n        _Question = question;\n        Options = options;\n    }\n}\nclass QuestionService\n{\n    private List<Question> _questions;\n    private Dictionary<string, int> _houses = new Dictionary<string, int>\n        {\n            {\"Frontend\", 0 },\n            {\"Backend\", 0 },\n            {\"Mobile\", 0 },\n            {\"Data\", 0 }\n        };\n\n    public List<Question> Questions { get {  return _questions; } }\n\n    public QuestionService()\n    {\n        _questions = new List<Question>();\n    }\n    public void AddQuestion(Question question) => _questions.Add(question);\n    public void Answer(int question, int option)\n    {\n\n        switch (option)\n        {\n            case 1:\n                _houses[\"Frontend\"]++;\n                break;\n            case 2:\n                _houses[\"Backend\"]++;\n                break;\n            case 3:\n                _houses[\"Mobile\"]++;\n                break;\n            case 4:\n                _houses[\"Data\"]++;\n                break;\n            default:\n                Console.WriteLine(\"Opción no válida...\");\n                break;\n        }\n    }\n    public void ShowResults()\n    {\n        int maxScore = _houses.Values.Max();\n        var maxScoreHouses = _houses.Where(h => h.Value == maxScore);\n        KeyValuePair<string, int> selectedHouse;\n        if (maxScoreHouses.Count() == 1)\n        {\n            selectedHouse = maxScoreHouses.First();\n            Console.WriteLine($\"El sombrero seleccionador te ha envíado a la casa: {selectedHouse.Key}\");\n        } \n        else\n        {\n            Random random = new Random();\n            selectedHouse = maxScoreHouses.ElementAt(random.Next(maxScoreHouses.Count()));\n            Console.WriteLine($\"Ha sido una decisión díficil, pero el sombrero seleccionador ha \" +\n                $\"decido enviarte a la casa : {selectedHouse.Key}\");\n        }\n    }\n}\nclass Program\n{\n    static void Main(string[] args)\n    {\n        QuestionService questionService = new QuestionService();\n        questionService.AddQuestion(\n            new Question(\n                \"¿Qué tipo de proyectos te interesa más desarrollar?\",\n                new Dictionary<int, string>(){\n                    {3, \"1.- Aplicaciones móviles nativas para múltiples plataformas.\"},\n                    {1, \"2.- Interfaces visualmente atractivas y responsivas.\"},\n                    {4, \"3.- Procesamiento y análisis de grandes volúmenes de datos.\"},\n                    {2, \"4- Sistemas robustos y optimización de rendimiento del servidor.\"}\n\n                }\n            )\n        );\n        questionService.AddQuestion(\n            new Question(\n                \"¿Qué aspecto del desarrollo disfrutas más?\",\n                new Dictionary<int, string>(){\n                    {2, \"1.- Resolver problemas complejos de lógica y escalabilidad.\"},\n                    {4, \"2.- Analizar datos para tomar decisiones basadas en estadísticas.\"},\n                    {3, \"3.- Crear aplicaciones móviles eficientes y funcionales.\"},\n                    {1, \"4.- Trabajar en el diseño y la experiencia de usuario.\"}\n\n                }\n            )\n        );\n        questionService.AddQuestion(\n            new Question(\n                \"¿Qué herramienta prefieres usar en tu día a día?\",\n                new Dictionary<int, string>(){\n                    {3, \"1.- Kotlin o Swift para desarrollar apps móviles nativas.\"},\n                    {4, \"2.- Python o R para análisis de datos.\"},\n                    {1, \"3.- Frameworks como React o Angular.\"},\n                    {2, \"4.- Lenguajes como Node.js o Python para la gestión de servidores.\"}\n\n                }\n            )\n        );\n        questionService.AddQuestion(\n            new Question(\n                \"¿Cómo te ves en un equipo de desarrollo?\",\n                new Dictionary<int, string>(){\n                    {4, \"1.- Modelando datos y construyendo dashboards de análisis.\"},\n                    {2, \"2.- Encargado de la lógica del servidor y las APIs.\"},\n                    {3, \"3.- Desarrollando la interfaz y funcionalidad de una app móvil.\"},\n                    {1, \"4.- Diseñando las interacciones y los componentes visuales.\"}\n\n                }\n            )\n        );\n        questionService.AddQuestion(\n            new Question(\n                \"¿Qué te motiva más al trabajar en un proyecto?\",\n                new Dictionary<int, string>(){\n                    {1, \"1.- Ver cómo el diseño cobra vida en la pantalla.\"},\n                    {4, \"2.- Descubrir insights a partir del análisis de datos.\"},\n                    {2, \"3.- Optimizar el rendimiento y escalabilidad del sistema.\"},\n                    {3, \"4.- Lograr que una aplicación móvil funcione perfectamente en cualquier dispositivo.\"}\n                }\n            )\n        );\n        questionService.AddQuestion(\n            new Question(\n                \"¿Cuál es tu enfoque al aprender nuevas tecnologías?\",\n                new Dictionary<int, string>(){\n                    {4, \"1.- Explorar técnicas avanzadas de análisis de datos y machine learning.\"},\n                    {2, \"2.- Aprender sobre nuevas arquitecturas y lenguajes de servidor.\"},\n                    {3, \"3.- Probar nuevas plataformas y herramientas para desarrollo móvil.\"},\n                    {1, \"4.- Experimentar con nuevas librerías y frameworks de interfaz de usuario.\"}\n                }\n            )\n        );\n        questionService.AddQuestion(\n            new Question(\n                \"¿Qué tipo de desafíos disfrutas más resolver?\",\n                new Dictionary<int, string>(){\n                    {2, \"1.- Solución de problemas de concurrencia y carga en servidores.\"},\n                    {1, \"2.- Optimización de interfaces para que se vean bien en cualquier dispositivo.\"},\n                    {4, \"3.- Análisis de grandes volúmenes de datos para detectar patrones ocultos.\"},\n                    {3, \"4.- Creación de experiencias de usuario fluídas en dispositivos móviles.\"}\n                }\n            )\n        );\n        questionService.AddQuestion(\n            new Question(\n                \"¿Cómo te gusta medir el éxito de tu trabajo?\",\n                new Dictionary<int, string>(){\n                    {2, \"1.- Por la estabilidad y rapidez del sistema bajo carga.\"},\n                    {1, \"2.- Mediante la satisfacción del usuario con la interfaz visual.\"},\n                    {3, \"3.- Por la fluidez y buen rendimiento de la app móvil en diferentes dispositivos.\"},\n                    {4, \"4.- Por la precisión y relevancia de los resultados obtenidos en el análisis de datos.\"}\n                }\n            )\n        );\n        questionService.AddQuestion(\n            new Question(\n                \"¿Qué te resulta más interesante al trabajar con tecnologías emergentes?\",\n                new Dictionary<int, string>(){\n                    {4, \"1.- Trabajar con tecnologías de big data o inteligencia artificial.\"},\n                    {2, \"2.- Explorar nuevas arquitecturas para mejorar el rendimiento del servidor.\"},\n                    {1, \"3.- Probar nuevas herramientas y metodologías para mejorar el diseño y la UX.\"},\n                    {3, \"4.- Desarrollar apps móviles que aprovechen nuevas capacidades de hardware.\"}\n                }\n            )\n        );\n        questionService.AddQuestion(\n            new Question(\n                \"¿Cómo te enfrentas a un nuevo problema en un proyecto?\",\n                new Dictionary<int, string>(){\n                    {4, \"1.- Buscando patrones y soluciones basadas en análisis de datos.\"},\n                    {1, \"2.- Replanteando la estructura visual y funcional de la interfaz.\"},\n                    {3, \"3.- Explorando cómo mejorar la experiencia del usuario en dispositivos móviles.\"},\n                    {2, \"4.- Analizando la estructura de datos y la lógica del backend.\"}\n                }\n            )\n        );\n\n        Console.WriteLine(\"---Sistema del sombrero seleccionador de Hogwarts---\");\n        Console.WriteLine(\"¿Cuál es tu nombre?\");\n        string name = Console.ReadLine();\n        Console.WriteLine($\"!Bienvenido {name}! a continuación te haremos una serie de \" +\n            $\"preguntas para determinar cuál será tu casa\");\n\n        int questionId = 0;\n        foreach (Question question in questionService.Questions)\n        {\n            Console.WriteLine(question._Question);\n            foreach (var option in question.Options)\n            {\n                Console.WriteLine(option.Value);\n            }\n            Console.WriteLine(\"Elige una respuesta...\");\n            int answer = 0;\n            int.TryParse(Console.ReadLine(), out answer);\n            var selection = question.Options.FirstOrDefault(o => o.Value.Contains(answer.ToString()));\n            questionService.Answer(questionId, selection.Key);\n            questionId++;\n        }\n        questionService.ShowResults();\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/c#/kenysdev.cs",
    "content": "namespace exs36;\n/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - C#\n_____________________________________\nEL SOMBRERO SELECCIONADOR\n------------------------------------\n* Cada 1 de septiembre, el Hogwarts Express parte hacia la escuela\n* de programación de Hogwarts para magos y brujas del código.\n* En ella, su famoso sombrero seleccionador ayuda a los programadores\n* a encontrar su camino...\n* Desarrolla un programa que simule el comportamiento del sombrero.\n* Requisitos:\n* 1. El sombrero realizará 10 preguntas para determinar la casa del alumno.\n* 2. Deben existir 4 casas. Por ejemplo: Frontend, Backend, Mobile y Data.\n*    (Puedes elegir las que quieras)\n* Acciones:\n* 1. Crea un programa que solicite el nombre del alumno y realice 10\n*    preguntas, con cuatro posibles respuestas cada una.\n* 2. Cada respuesta asigna puntos a cada una de las casas (a tu elección).\n* 3. Una vez finalizado, el sombrero indica el nombre del alumno\n*    y a qué casa pertenecerá (resuelve el posible empate de manera aleatoria,\n*    pero indicándole al alumno que la decisión ha sido complicada).\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nclass Program\n{\n    private static readonly string[] HOUSES = [\"Frontend\", \"Backend\", \"Mobile\", \"Data\"];\n\n    // NOTA: Preguntas y respuestas generadas por IA\n    private static readonly string[] QUESTIONS = [\n        \"¿Qué te atrae más?\",\n        \"¿Qué superhéroe de la programación te gustaría ser?\",\n        \"En un proyecto de software, ¿qué rol te emociona más?\",\n        \"Si tu código fuera una obra de arte, ¿qué estilo tendría?\",\n        \"¿Qué animal de programación serías?\",\n        \"En una hackathon, ¿qué tipo de proyecto propondrías?\",\n        \"Si tu carrera en tech fuera una película, ¿de qué género sería?\",\n        \"¿Qué herramienta de programación no puede faltar en tu caja de herramientas digital?\",\n        \"Si pudieras resolver un gran problema en tech, ¿cuál elegirías?\",\n        \"¿Qué tipo de equipo prefieres?\"\n    ];\n\n    private static readonly string[][] ANSWERS = [\n        [\"Crear experiencias visuales.\", \"Solucionar problemas de funcionamiento.\", \"Innovar en dispositivos portátiles.\", \"Descubrir tendencias ocultas.\"],\n        [\"Diseñador de Interfaces, creando experiencias asombrosas\", \"Arquitecto de Sistemas, construyendo estructuras robustas\", \"Mago de Apps, conjurando soluciones móviles\", \"Explorador de Datos, descubriendo tesoros ocultos\"],\n        [\"Director de UX, orquestando la sinfonía visual\", \"Ingeniero de Backend, dominando la lógica del servidor\", \"Desarrollador de Apps, llevando la potencia al bolsillo\", \"Científico de Datos, descifrando los secretos de la información\"],\n        [\"Minimalismo elegante, como una landing page perfecta\", \"Arquitectura compleja, como un sistema distribuido\", \"Diseño adaptativo, fluyendo en diferentes dispositivos\", \"Visualización de datos, pintando historias con números\"],\n        [\"Un camaleón, adaptándome a diferentes frameworks\", \"Un pulpo, manejando múltiples servicios a la vez\", \"Un colibrí, ágil y siempre en movimiento\", \"Una lechuza, analizando datos con sabiduría\"],\n        [\"Una web app que revolucione la experiencia del usuario\", \"Un sistema de IA que optimice procesos backend\", \"Una app móvil que cambie la forma de interactuar con el mundo\", \"Un proyecto de big data que prediga tendencias futuras\"],\n        [\"Comedia romántica con JavaScript y CSS\", \"Thriller de ciencia ficción con microservicios\", \"Aventura de acción en el mundo de las apps\", \"Documental profundo sobre el universo de los datos\"],\n        [\"Un editor de código con plugins para diseño visual\", \"Una robusta suite de testing y depuración\", \"Un emulador multi-dispositivo de última generación\", \"Una plataforma de análisis de datos en tiempo real\"],\n        [\"Hacer que la accesibilidad web sea universal\", \"Crear una arquitectura de software autorreparable\", \"Desarrollar una plataforma de AR/VR para educación móvil\", \"Construir un modelo de IA ético y transparente\"],\n        [\"Creativos enfocados en diseño.\", \"Técnicos que construyen sistemas.\", \"Especialistas en aplicaciones móviles.\", \"Expertos en datos y análisis.\"]\n    ];\n\n    class SortingHat\n    {\n        private readonly Dictionary<string, int> scores = HOUSES.ToDictionary(house => house, _ => 0);\n\n        public void AskQuestion(int qNum, string question, string[] answers)\n        {\n            Console.WriteLine($\"\\n#{qNum}: {question}\");\n            for (int i = 0; i < answers.Length; i++)\n            {\n                Console.WriteLine($\"{i + 1}) {answers[i]}\");\n            }\n\n            while (true)\n            {\n                Console.Write(\"Elige tu respuesta (1-4): \");\n                if (int.TryParse(Console.ReadLine(), out int choice) && choice >= 1 && choice <= 4)\n                {\n                    scores[HOUSES[choice - 1]]++;\n                    break;\n                }\n                else\n                {\n                    Console.WriteLine(\"Por favor, elige un número entre 1 y 4.\");\n                }\n            }\n        }\n\n        public string SelectHouse()\n        {\n            int maxScore = scores.Values.Max();\n            var topHouses = scores.Where(kv => kv.Value == maxScore).Select(kv => kv.Key).ToList();\n\n            if (topHouses.Count > 1)\n            {\n                Console.WriteLine(\"\\nLa decisión ha sido complicada.\");\n                return topHouses[new Random().Next(topHouses.Count)];\n            }\n            return topHouses[0];\n        }\n    }\n\n    static void Main()\n    {\n        Console.WriteLine(\"EL SOMBRERO SELECCIONADOR\");\n        Console.Write(\"¿Cuál es tu nombre? : \");\n        string name = Console.ReadLine() ?? string.Empty;\n        var hat = new SortingHat();\n\n        for (int i = 0; i < QUESTIONS.Length; i++)\n        {\n            hat.AskQuestion(i + 1, QUESTIONS[i], ANSWERS[i]);\n        }\n\n        string selectedHouse = hat.SelectHouse();\n        Console.WriteLine($\"\\n'{name}' pertenecerá a la casa '{selectedHouse}'\\n\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/c++/hectorio23.cpp",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\n#include <iostream>\n#include <vector>\n#include <string>\n#include <ctime>\n#include <cstdlib>\n#include <algorithm>\n\nusing namespace std;\n\n// Casas\nvector<string> houses = {\"Frontend\", \"Backend\", \"Mobile\", \"Data\"};\n\n// Preguntas y asignación de puntos\nstruct Question {\n    string question;\n    vector<int> scores;\n};\n\nvector<Question> questions = {\n    {\"¿Prefieres trabajar en interfaces visuales?\", {3, 1, 2, 0}},\n    {\"¿Te gusta optimizar el rendimiento del servidor?\", {0, 3, 1, 1}},\n    {\"¿Te interesa crear aplicaciones móviles?\", {1, 0, 3, 1}},\n    {\"¿Te apasiona analizar grandes conjuntos de datos?\", {0, 1, 0, 3}},\n    // 6 preguntas más...\n};\n\nvector<int> askQuestions() {\n    vector<int> scores(4, 0);\n    for (const auto& q : questions) {\n        cout << q.question << endl;\n        int answer;\n        cout << \"Responde 1, 2, 3 o 4: \";\n        cin >> answer;\n        answer -= 1;\n        for (int i = 0; i < 4; ++i) {\n            scores[i] += q.scores[answer];\n        }\n    }\n    return scores;\n}\n\nvoid sortingHat() {\n    string name;\n    cout << \"¿Cuál es tu nombre? \";\n    cin >> name;\n    \n    vector<int> scores = askQuestions();\n    int max_score = *max_element(scores.begin(), scores.end());\n    \n    vector<string> candidates;\n    for (int i = 0; i < 4; ++i) {\n        if (scores[i] == max_score) {\n            candidates.push_back(houses[i]);\n        }\n    }\n\n    srand(time(0));\n    \n    // Si hay empate, selecciona aleatoriamente\n    if (candidates.size() > 1) {\n        cout << name << \", la decisión ha sido complicada...\" << endl;\n        cout << name << \", has sido asignado a \" << candidates[rand() % candidates.size()] << \".\" << endl;\n    } else {\n        cout << name << \", has sido asignado a \" << candidates[0] << \".\" << endl;\n    }\n}\n\nint main() {\n    sortingHat();\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/dart/redom69.dart",
    "content": "import 'dart:io';\nimport 'dart:math';\n\nList<String> printQuiz() {\n  final List<Map<String, dynamic>> preguntas = [\n    {\n      \"pregunta\": \"¿Qué es lo que más disfrutas al programar?\",\n      \"opciones\": [\n        {\"respuesta\": \"Diseñar interfaces atractivas\", \"casa\": \"Frontend\"},\n        {\n          \"respuesta\": \"Optimizar el rendimiento del servidor\",\n          \"casa\": \"Backend\"\n        },\n        {\"respuesta\": \"Crear aplicaciones móviles útiles\", \"casa\": \"Mobile\"},\n        {\"respuesta\": \"Analizar grandes conjuntos de datos\", \"casa\": \"Data\"}\n      ]\n    },\n    {\n      \"pregunta\": \"¿Qué tipo de proyecto te atrae más?\",\n      \"opciones\": [\n        {\"respuesta\": \"Aplicaciones web con mucho estilo\", \"casa\": \"Frontend\"},\n        {\n          \"respuesta\": \"Sistemas que manejen grandes volúmenes de datos\",\n          \"casa\": \"Backend\"\n        },\n        {\n          \"respuesta\": \"Aplicaciones para teléfonos inteligentes\",\n          \"casa\": \"Mobile\"\n        },\n        {\"respuesta\": \"Dashboards para visualizar información\", \"casa\": \"Data\"}\n      ]\n    },\n    {\n      \"pregunta\": \"¿Qué herramienta te resulta más interesante?\",\n      \"opciones\": [\n        {\"respuesta\": \"HTML, CSS y JavaScript\", \"casa\": \"Frontend\"},\n        {\"respuesta\": \"Node.js o Python\", \"casa\": \"Backend\"},\n        {\"respuesta\": \"React Native o Swift\", \"casa\": \"Mobile\"},\n        {\"respuesta\": \"SQL o Python con Pandas\", \"casa\": \"Data\"}\n      ]\n    },\n    {\n      \"pregunta\": \"¿Cuál es tu mayor fortaleza como programador?\",\n      \"opciones\": [\n        {\"respuesta\": \"Crear interfaces amigables\", \"casa\": \"Frontend\"},\n        {\n          \"respuesta\": \"Solucionar problemas complejos en el servidor\",\n          \"casa\": \"Backend\"\n        },\n        {\"respuesta\": \"Desarrollar apps funcionales\", \"casa\": \"Mobile\"},\n        {\"respuesta\": \"Encontrar patrones en los datos\", \"casa\": \"Data\"}\n      ]\n    },\n    {\n      \"pregunta\": \"¿Qué prefieres en un equipo de desarrollo?\",\n      \"opciones\": [\n        {\"respuesta\": \"Ser quien diseña el look y feel\", \"casa\": \"Frontend\"},\n        {\n          \"respuesta\": \"Ser quien gestiona la arquitectura de la aplicación\",\n          \"casa\": \"Backend\"\n        },\n        {\n          \"respuesta\": \"Ser quien se encarga de la versión móvil\",\n          \"casa\": \"Mobile\"\n        },\n        {\n          \"respuesta\": \"Ser quien analiza el rendimiento del sistema\",\n          \"casa\": \"Data\"\n        }\n      ]\n    },\n    {\n      \"pregunta\": \"¿En qué te enfocas más cuando trabajas en un proyecto?\",\n      \"opciones\": [\n        {\n          \"respuesta\": \"En el diseño visual y la experiencia de usuario\",\n          \"casa\": \"Frontend\"\n        },\n        {\n          \"respuesta\": \"En la estabilidad y escalabilidad del sistema\",\n          \"casa\": \"Backend\"\n        },\n        {\n          \"respuesta\": \"En hacer que la app funcione en dispositivos móviles\",\n          \"casa\": \"Mobile\"\n        },\n        {\n          \"respuesta\": \"En el análisis y visualización de los datos\",\n          \"casa\": \"Data\"\n        }\n      ]\n    },\n    {\n      \"pregunta\": \"¿Cuál es tu mayor motivación como desarrollador?\",\n      \"opciones\": [\n        {\n          \"respuesta\": \"Crear experiencias de usuario memorables\",\n          \"casa\": \"Frontend\"\n        },\n        {\n          \"respuesta\": \"Resolver problemas complejos con eficiencia\",\n          \"casa\": \"Backend\"\n        },\n        {\n          \"respuesta\":\n              \"Desarrollar aplicaciones que la gente use todos los días\",\n          \"casa\": \"Mobile\"\n        },\n        {\"respuesta\": \"Descubrir patrones ocultos en los datos\", \"casa\": \"Data\"}\n      ]\n    },\n    {\n      \"pregunta\": \"¿Qué aspecto prefieres de un nuevo proyecto?\",\n      \"opciones\": [\n        {\n          \"respuesta\": \"Hacer que se vea genial y sea fácil de usar\",\n          \"casa\": \"Frontend\"\n        },\n        {\n          \"respuesta\": \"Asegurarme de que el servidor funcione sin problemas\",\n          \"casa\": \"Backend\"\n        },\n        {\n          \"respuesta\": \"Hacer que funcione bien en dispositivos móviles\",\n          \"casa\": \"Mobile\"\n        },\n        {\n          \"respuesta\": \"Organizar y visualizar los datos de forma eficiente\",\n          \"casa\": \"Data\"\n        }\n      ]\n    },\n    {\n      \"pregunta\": \"¿Qué tecnología te emociona más aprender?\",\n      \"opciones\": [\n        {\n          \"respuesta\": \"Frameworks de JavaScript como React o Angular\",\n          \"casa\": \"Frontend\"\n        },\n        {\n          \"respuesta\": \"Microservicios o arquitectura en la nube\",\n          \"casa\": \"Backend\"\n        },\n        {\"respuesta\": \"Desarrollo de aplicaciones móviles\", \"casa\": \"Mobile\"},\n        {\"respuesta\": \"Big Data o inteligencia artificial\", \"casa\": \"Data\"}\n      ]\n    },\n    {\n      \"pregunta\": \"Si pudieras elegir un área de especialización, ¿cuál sería?\",\n      \"opciones\": [\n        {\"respuesta\": \"Interfaz y experiencia de usuario\", \"casa\": \"Frontend\"},\n        {\n          \"respuesta\": \"Desarrollo y mantenimiento del servidor\",\n          \"casa\": \"Backend\"\n        },\n        {\"respuesta\": \"Aplicaciones móviles\", \"casa\": \"Mobile\"},\n        {\"respuesta\": \"Ciencia de datos y análisis\", \"casa\": \"Data\"}\n      ]\n    }\n  ];\n\n  List<String> answers = [];\n\n  preguntas.forEach((preguntaObj) {\n    print(preguntaObj['pregunta']);\n    List opciones = preguntaObj['opciones'];\n\n    // Imprimir las opciones y pedir la respuesta\n    for (int i = 0; i < opciones.length; i++) {\n      print(\"${String.fromCharCode(97 + i)}) ${opciones[i]['respuesta']}\");\n    }\n\n    String? answer = stdin.readLineSync();\n    answers.add(answer!);\n  });\n\n  return answers;\n}\n\nString selectHouse(List<String> answers) {\n  int countFront = answers.where((a) => a == 'a').length;\n  int countBackend = answers.where((a) => a == 'b').length;\n  int countMobile = answers.where((a) => a == 'c').length;\n  int countData = answers.where((a) => a == 'd').length;\n\n  Map<String, int> casas = {\n    \"Frontend\": countFront,\n    \"Backend\": countBackend,\n    \"Mobile\": countMobile,\n    \"Data\": countData\n  };\n\n  int maxCount = casas.values.reduce(max);\n\n  List<String> posiblesCasas =\n      casas.keys.where((casa) => casas[casa] == maxCount).toList();\n\n  if (posiblesCasas.length > 1) {\n    print(\"¡Ha sido una decisión complicada!\");\n    return posiblesCasas[Random().nextInt(posiblesCasas.length)];\n  }\n\n  return posiblesCasas[0];\n}\n\nvoid main() {\n  print(\"Introduce tu nombre: \");\n  String? name = stdin.readLineSync();\n  List<String> answers = printQuiz();\n  String house = selectHouse(answers);\n  print(\"$name, la casa seleccionada es: $house\");\n}\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/ejercicio.md",
    "content": "# #36 EL SOMBRERO SELECCIONADOR\n> #### Dificultad: Fácil | Publicación: 02/09/24 | Corrección: 09/09/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Cada 1 de septiembre, el Hogwarts Express parte hacia la escuela\n * de programación de Hogwarts para magos y brujas del código.\n * En ella, su famoso sombrero seleccionador ayuda a los programadores\n * a encontrar su camino...\n * Desarrolla un programa que simule el comportamiento del sombrero.\n * Requisitos:\n * 1. El sombrero realizará 10 preguntas para determinar la casa del alumno.\n * 2. Deben existir 4 casas. Por ejemplo: Frontend, Backend, Mobile y Data.\n *    (Puedes elegir las que quieras)\n * Acciones:\n * 1. Crea un programa que solicite el nombre del alumno y realice 10\n *    preguntas, con cuatro posibles respuestas cada una.\n * 2. Cada respuesta asigna puntos a cada una de las casas (a tu elección).\n * 3. Una vez finalizado, el sombrero indica el nombre del alumno \n *    y a qué casa pertenecerá (resuelve el posible empate de manera aleatoria,\n *    pero indicándole al alumno que la decisión ha sido complicada).\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/go/hozlucas28.go",
    "content": "package main\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"maps\"\n\trand \"math/rand/v2\"\n\t\"os\"\n\t\"slices\"\n\t\"strings\"\n)\n\n/* -------------------------------------------------------------------------- */\n/*                                   STRUCTS                                  */\n/* -------------------------------------------------------------------------- */\n\ntype Question struct {\n\tCorrectAnswer string\n\tOptions       []string\n\tPoints        float32\n\tQuestion      string\n\t_             struct{}\n}\n\ntype QuestionsPerHouse struct {\n\tBackend  [2]Question\n\tData     [2]Question\n\tFrontend [2]Question\n\tMobile   [2]Question\n\t_        struct{}\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    UTILS                                   */\n/* -------------------------------------------------------------------------- */\n\nfunc toLongDisjunction[T string](slice []T) string {\n\tvar arrayLength int = len(slice)\n\n\tif arrayLength == 0 {\n\t\tpanic(\"slice empty\")\n\t}\n\n\tvar rtn string = string(slice[0])\n\n\tif arrayLength == 1 {\n\t\treturn rtn\n\t}\n\n\tfor _, element := range slice[1 : arrayLength-1] {\n\t\trtn += fmt.Sprintf(\", %s\", element)\n\t}\n\n\trtn += fmt.Sprintf(\", and %s\", slice[arrayLength-1])\n\n\treturn rtn\n}\n\nfunc rndChoice[T string](choices []T) T {\n\tvar choicesLength int = len(choices)\n\n\tif choicesLength == 0 {\n\t\tpanic(\"slice of choices empty\")\n\t}\n\n\tif choicesLength == 1 {\n\t\treturn choices[0]\n\t}\n\n\tvar rndIndex int = rand.IntN(choicesLength - 1)\n\n\treturn choices[rndIndex]\n}\n\nfunc makeQuestion[T string](question *Question) float32 {\n\tvar reader *bufio.Reader = bufio.NewReader(os.Stdin)\n\n\tvar questionMsg string = fmt.Sprintf(\"> %s (%s): \", question.Question, toLongDisjunction(question.Options))\n\n\tfmt.Print(questionMsg)\n\tuserAnswer, err := reader.ReadString('\\n')\n\tif err == nil {\n\t\tuserAnswer = strings.ToUpper(strings.TrimSpace(userAnswer))\n\t}\n\n\tvar exit bool = slices.ContainsFunc(question.Options, func(opt string) bool {\n\t\treturn strings.Compare(userAnswer, strings.ToUpper(opt)) == 0\n\t})\n\n\tfor !exit {\n\t\tfmt.Printf(\"\\n> Invalid option! Try again...\\n\\n\")\n\n\t\tfmt.Print(questionMsg)\n\t\tuserAnswer, err := reader.ReadString('\\n')\n\t\tif err == nil {\n\t\t\tuserAnswer = strings.ToUpper(strings.TrimSpace(userAnswer))\n\t\t}\n\n\t\texit = slices.ContainsFunc(question.Options, func(opt string) bool {\n\t\t\treturn strings.Compare(userAnswer, strings.ToUpper(opt)) == 0\n\t\t})\n\t}\n\n\tif strings.Compare(userAnswer, strings.ToUpper(question.CorrectAnswer)) == 0 {\n\t\treturn question.Points\n\t} else {\n\t\treturn 0\n\t}\n\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\nfunc main() {\n\tvar reader *bufio.Reader = bufio.NewReader(os.Stdin)\n\n\tvar questionsPerHouse QuestionsPerHouse = QuestionsPerHouse{\n\t\tBackend: [2]Question{\n\t\t\t{\n\t\t\t\tCorrectAnswer: \"JavaScript\",\n\t\t\t\tOptions:       []string{\"Java\", \"JavaScript\", \"Python\", \"Ruby\"},\n\t\t\t\tQuestion:      \"What is the primary language used in backend development?\",\n\t\t\t\tPoints:        5,\n\t\t\t},\n\t\t\t{\n\t\t\t\tCorrectAnswer: \"PostgreSQL\",\n\t\t\t\tOptions:       []string{\"MySQL\", \"MongoDB\", \"PostgreSQL\", \"SQLite\"},\n\t\t\t\tPoints:        5,\n\t\t\t\tQuestion:      \"Which database is commonly used for storing data in backend applications?\",\n\t\t\t},\n\t\t},\n\t\tData: [2]Question{\n\t\t\t{\n\t\t\t\tCorrectAnswer: \"Data analysis\",\n\t\t\t\tOptions:       []string{\"Data analysis\", \"Data visualization\", \"Data mining\", \"Data modeling\"},\n\t\t\t\tPoints:        5,\n\t\t\t\tQuestion:      \"What is the process of analyzing and interpreting data called?\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tCorrectAnswer: \"Julia\",\n\t\t\t\tOptions:       []string{\"Python\", \"R\", \"SQL\", \"Julia\"},\n\t\t\t\tPoints:        5,\n\t\t\t\tQuestion:      \"Which programming language is commonly used for data analysis?\",\n\t\t\t},\n\t\t},\n\t\tFrontend: [2]Question{\n\t\t\t{\n\t\t\t\tCorrectAnswer: \"JavaScript\",\n\t\t\t\tOptions:       []string{\"HTML\", \"CSS\", \"JavaScript\", \"Python\"},\n\t\t\t\tPoints:        5,\n\t\t\t\tQuestion:      \"What is the primary language used in frontend development?\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tCorrectAnswer: \"Angular\",\n\t\t\t\tOptions:       []string{\"React\", \"Angular\", \"Vue\", \"Ember\"},\n\t\t\t\tPoints:        5,\n\t\t\t\tQuestion:      \"Which framework is commonly used for building user interfaces?\",\n\t\t\t},\n\t\t},\n\t\tMobile: [2]Question{\n\t\t\t{\n\t\t\t\tCorrectAnswer: \"Flutter\",\n\t\t\t\tOptions:       []string{\"iOS\", \"Android\", \"React Native\", \"Flutter\"},\n\t\t\t\tPoints:        5,\n\t\t\t\tQuestion:      \"Which platform is commonly used for developing mobile applications?\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tCorrectAnswer: \"Objective-C\",\n\t\t\t\tOptions:       []string{\"Swift\", \"Kotlin\", \"Java\", \"Objective-C\"},\n\t\t\t\tPoints:        5,\n\t\t\t\tQuestion:      \"What is the primary language used in mobile app development?\",\n\t\t\t},\n\t\t},\n\t}\n\n\tfmt.Print(\"> Enter your name: \")\n\tuserName, err := reader.ReadString('\\n')\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tuserName = strings.TrimSpace(userName)\n\n\tvar pointsPerHouse map[string]float32 = map[string]float32{\n\t\t\"backend\":  0,\n\t\t\"data\":     0,\n\t\t\"frontend\": 0,\n\t\t\"mobile\":   0,\n\t}\n\n\tfmt.Println()\n\tpointsPerHouse[\"backend\"] += makeQuestion(&questionsPerHouse.Backend[0])\n\n\tfmt.Println()\n\tpointsPerHouse[\"backend\"] += makeQuestion(&questionsPerHouse.Backend[1])\n\n\tfmt.Println()\n\tpointsPerHouse[\"data\"] += makeQuestion(&questionsPerHouse.Data[0])\n\n\tfmt.Println()\n\tpointsPerHouse[\"data\"] += makeQuestion(&questionsPerHouse.Data[1])\n\n\tfmt.Println()\n\tpointsPerHouse[\"frontend\"] += makeQuestion(&questionsPerHouse.Frontend[0])\n\n\tfmt.Println()\n\tpointsPerHouse[\"frontend\"] += makeQuestion(&questionsPerHouse.Frontend[1])\n\n\tfmt.Println()\n\tpointsPerHouse[\"mobile\"] += makeQuestion(&questionsPerHouse.Mobile[0])\n\n\tfmt.Println()\n\tpointsPerHouse[\"mobile\"] += makeQuestion(&questionsPerHouse.Mobile[1])\n\n\tvar maxPoint float32 = max(\n\t\tpointsPerHouse[\"backend\"],\n\t\tpointsPerHouse[\"data\"],\n\t\tpointsPerHouse[\"frontend\"],\n\t\tpointsPerHouse[\"mobile\"],\n\t)\n\n\tvar maxPoints map[string]float32 = map[string]float32{\n\t\t\"backend\":  pointsPerHouse[\"backend\"],\n\t\t\"data\":     pointsPerHouse[\"data\"],\n\t\t\"frontend\": pointsPerHouse[\"frontend\"],\n\t\t\"mobile\":   pointsPerHouse[\"mobile\"],\n\t}\n\n\tmaps.DeleteFunc(maxPoints, func(key string, value float32) bool {\n\t\treturn value != maxPoint\n\t})\n\n\tif len(maxPoints) == 1 {\n\t\tfor house := range maxPoints {\n\t\t\tfmt.Printf(\"\\n> %s will be part of the %s house!\", userName, house)\n\t\t\tbreak\n\t\t}\n\t\treturn\n\t}\n\n\tvar houses []string\n\tfor house := range maxPoints {\n\t\thouses = append(houses, house)\n\t}\n\n\tvar rndHouse string = rndChoice(houses)\n\n\tfmt.Printf(\"\\n> The decision has been complicated, but %s will be part of the %s house!\", userName, rndHouse)\n}\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/java/AmadorQuispe.java",
    "content": "package com.amsoft.roadmap.example36;\n\n\nimport java.util.Arrays;\nimport java.util.Scanner;\n\n\nenum House {\n    FRONTEND(\"🌐\"),\n    BACKEND(\"🔙\"),\n    MOBILE(\"📱\"),\n    DATA(\"💾\");\n\n    private final String emoji;\n\n    House(String emoji) {\n        this.emoji = emoji;\n    }\n\n    public String getEmoji() {\n        return emoji;\n    }\n\n}\n\nrecord Question(String question, String[] answers) {\n}\npublic class Example36 {\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n        Question[] questions = {\n                new Question(\"¿Qué lenguaje de programación prefieres?\", new String[]{\"JavaScript\", \"Java\", \"Kotlin\", \"Python\"}),\n                new Question(\"¿Qué tipo de proyecto te gustaría desarrollar?\", new String[]{\"Web\", \"Backend\", \"Mobile\", \"Big Data\"}),\n                new Question(\"¿Qué tipo de dispositivo prefieres?\", new String[]{\"PC\", \"Servidor\", \"Smartphone\", \"Servidor\"}),\n                new Question(\"¿Qué tipo de base de datos prefieres?\", new String[]{\"MongoDB\", \"MySQL\", \"SQLite\", \"PostgreSQL\"}),\n                new Question(\"¿Qué tipo de sistema operativo prefieres?\", new String[]{\"Windows\", \"Linux\", \"Android\", \"MacOS\"}),\n                new Question(\"¿Qué tipo de IDE prefieres?\", new String[]{\"Visual Studio Code\", \"IntelliJ IDEA\", \"Android Studio\", \"PyCharm\"}),\n                new Question(\"¿Qué tipo de framework prefieres?\", new String[]{\"React\", \"Spring\", \"Flutter\", \"Django\"}),\n                new Question(\"¿Qué tipo de control de versiones prefieres?\", new String[]{\"Git\", \"SVN\", \"Git\", \"Git\"}),\n                new Question(\"¿Qué tipo de metodología prefieres?\", new String[]{\"Agile\", \"Waterfall\", \"Scrum\", \"Kanban\"}),\n                new Question(\"¿Qué tipo de testing prefieres?\", new String[]{\"Unit\", \"Integration\", \"UI\", \"Performance\"})\n        };\n        System.out.println(\"¡Bienvenido al Sombrero Seleccionador de Hogwarts!\");\n        System.out.println(\"Te haré unas preguntas y según tus respuestas, te asignaré a una de las cuatro casas de la escuela.\");\n        System.out.println(\"¡Vamos a empezar!\");\n        System.out.println(\"Por favor, introduce tu nombre:\");\n        String name = scanner.nextLine();\n        System.out.println(\"¡Hola, \" + name + \"!\");\n        System.out.println(\"Por favor, responde a las siguientes preguntas con el número de la respuesta que prefieras:\");\n        int[] points = new int[House.values().length];\n        for (Question question : questions) {\n            System.out.println(question.question());\n            for (int i = 0; i < question.answers().length; i++) {\n                System.out.println((i + 1) + \". \" + question.answers()[i]);\n            }\n            int answer = scanner.nextInt();\n            if(answer < 1 || answer > question.answers().length) {\n                System.out.println(\"Respuesta no válida. Por favor, introduce un número entre 1 y \" + question.answers().length);\n                continue;\n            }\n            points[answer - 1] += 1;\n        }\n        int maxPoints = points[0];\n        int houseIndex = 0;\n        boolean tie = false;\n        System.out.println(\"¡El Sombrero Seleccionador ha terminado de analizar tus respuestas!\");\n        for (int i = 1; i < points.length; i++) {\n            if (points[i] > maxPoints) {\n                maxPoints = points[i];\n                houseIndex = i;\n                tie = false;\n            } else if (points[i] == maxPoints) {\n                tie = true;\n            }\n        }\n        House house = House.values()[houseIndex];\n        System.out.println(\"¡Enhorabuena, \" + name + \"!\");\n        if (tie) {\n            System.out.println(\"¡La decisión ha sido complicada!\");\n        }\n        System.out.println(\"¡Tu casa es \" + house + \" \" + house.getEmoji() + \"!\");\n\n        scanner.close();\n\n\n\n\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/java/Josegs95.java",
    "content": "import java.util.*;\n\npublic class Josegs95 {\n    public static void main(String[] args) {\n        new Josegs95().sortingHat();\n    }\n\n    private House hWarrior = new House(\"Guerrero\");\n    private House hRogue = new House(\"Pícaro\");\n    private House hWizard = new House(\"Mago\");\n    private House hBard = new House(\"Bardo\");\n\n    private List<House> houseList = Arrays.asList(hWarrior, hRogue, hWizard, hBard);\n    private List<Question> questionList = new ArrayList<>();\n    final private Scanner sc = new Scanner(System.in);\n    private String[] letters = new String[] {\"a\", \"b\", \"c\", \"d\"};\n\n    private boolean was_tied = false;\n\n    public void sortingHat(){\n        initQuestions();\n\n        try(sc){\n            System.out.println(\"Bienvenido/a al sombrero seleccionador, donde se \" +\n                    \"elegirá la casa a la que pertenecerás. Para ello deberás responder \" +\n                    \"10 preguntas\");\n            System.out.print(\"Introduce tu nombre: \");\n            String userName = sc.nextLine();\n\n            Collections.shuffle(questionList);\n            int counter = 1;\n            for (Question q : questionList){\n                Answer answer = askQuestion(q, counter++);\n                hWarrior.addAffPoints(answer.getWARRIOR_HOUSE_POINTS());\n                hRogue.addAffPoints(answer.getROGUE_HOUSE_POINTS());\n                hWizard.addAffPoints(answer.getWIZARD_HOUSE_POINTS());\n                hBard.addAffPoints(answer.getBARD_HOUSE_POINTS());\n            }\n\n            House chosenHouse = chooseHouse();\n            if (was_tied)\n                System.out.println(\"La desición ha sido muy complicada, pero...\");\n\n            System.out.println(userName + \", tu casa será.... ¡La casa del \" + chosenHouse.getNAME() + \"!\");\n            System.out.println(\"\\nResultados: \");\n            for (House house : houseList)\n                System.out.println(\"Casa del \" + house.getNAME() + \": \" + house.getAffinityPoints());\n        }\n\n\n    }\n\n    private void initQuestions(){\n        //Pregunta 1\n        Question question = new Question(\"¿Si fueras un animal, cuál serías?\");\n        Answer answer1 = new Answer(\"Un león\", 2, 0, 0,1);\n        Answer answer2 = new Answer(\"Un ratón\", 0, 2, 0,0);\n        Answer answer3 = new Answer(\"Un cuervo\", 0, 0, 2,0);\n        Answer answer4 = new Answer(\"Un grillo\", 0, 1, 0,2);\n        question.setAnswerList(Arrays.asList(answer1, answer2, answer3, answer4));\n        questionList.add(question);\n\n        //Pregunta 2\n        question = new Question(\"¿Qué atributo valoras mas?\");\n        answer1 = new Answer(\"La fuerza\", 2, 1, 0,0);\n        answer2 = new Answer(\"La destreza\", 1, 2, 0,0);\n        answer3 = new Answer(\"La inteligencia\", 0, 0, 2,1);\n        answer4 = new Answer(\"El carisma\", 0, 0, 1,2);\n        question.setAnswerList(Arrays.asList(answer1, answer2, answer3, answer4));\n        questionList.add(question);\n\n        //Pregunta 3\n        question = new Question(\"¿Cuál es tu comida favorita?\");\n        answer1 = new Answer(\"Pollo con patatas\", 2, 0, 0,0);\n        answer2 = new Answer(\"Una ensalada ligera\", 0, 2, 0,0);\n        answer3 = new Answer(\"Bacalao con costra de mahonesa de pera\", 0, 0, 2,0);\n        answer4 = new Answer(\"Lo que sea pero con cerveza\", 0, 0, 0,2);\n        question.setAnswerList(Arrays.asList(answer1, answer2, answer3, answer4));\n        questionList.add(question);\n\n        //Pregunta 4\n        question = new Question(\"¿Dónde irías de viaje?\");\n        answer1 = new Answer(\"A la montaña\", 2, 0, 0,0);\n        answer2 = new Answer(\"Al bosque\", 0, 2, 0,0);\n        answer3 = new Answer(\"A la playa\", 0, 0, 2,0);\n        answer4 = new Answer(\"A una gran capital\", 0, 0, 0,2);\n        question.setAnswerList(Arrays.asList(answer1, answer2, answer3, answer4));\n        questionList.add(question);\n\n        //Pregunta 5\n        question = new Question(\"¿Qué arma pillarías si hay una emergencia y te tienes que equipar rápido?\");\n        answer1 = new Answer(\"Un martillo a dos manos\", 2, 0, 0,0);\n        answer2 = new Answer(\"Un arco\", 0, 2, 0,0);\n        answer3 = new Answer(\"Una varita\", 0, 0, 2,0);\n        answer4 = new Answer(\"Una espada a una mano\", 0, 0, 0,2);\n        question.setAnswerList(Arrays.asList(answer1, answer2, answer3, answer4));\n        questionList.add(question);\n\n        //Pregunta 6\n        question = new Question(\"¿Cuál es tu película favorita?\");\n        answer1 = new Answer(\"Gladiator\", 2, 0, 0,0);\n        answer2 = new Answer(\"Robin Hood\", 0, 2, 0,0);\n        answer3 = new Answer(\"Harry Potter\", 0, 0, 2,0);\n        answer4 = new Answer(\"La La Land\", 0, 0, 0,2);\n        question.setAnswerList(Arrays.asList(answer1, answer2, answer3, answer4));\n        questionList.add(question);\n\n        //Pregunta 7\n        question = new Question(\"Hay una puerta cerrada, ¿Cómo la abres?\");\n        answer1 = new Answer(\"Con una patada\", 2, 0, 0,0);\n        answer2 = new Answer(\"Uso unas ganzuas\", 0, 2, 0,0);\n        answer3 = new Answer(\"Uso un hechizo\", 0, 0, 2,0);\n        answer4 = new Answer(\"Busco a alguien que tenga la llave y lo convenzo\", 0, 0, 0,2);\n        question.setAnswerList(Arrays.asList(answer1, answer2, answer3, answer4));\n        questionList.add(question);\n\n        //Pregunta 8\n        question = new Question(\"¿Qué lugar se te viene a la mente al decir <<Hogar>>?\");\n        answer1 = new Answer(\"Cualquier sitio con una buena cama limpia, como un hostal\", 2, 0, 0,0);\n        answer2 = new Answer(\"Un sitio cómodo y sin miradas indiscretas, como un callejón\", 0, 2, 0,0);\n        answer3 = new Answer(\"Una torre, donde estar tranquilo\", 0, 0, 2,0);\n        answer4 = new Answer(\"Una taverna, y si hay mucha gente, mejor\", 0, 0, 0,2);\n        question.setAnswerList(Arrays.asList(answer1, answer2, answer3, answer4));\n        questionList.add(question);\n\n\n        //Pregunta 9\n        question = new Question(\"Tienes que obtener un objeto que está en posesión de una\" +\n                \" persona ¿Cómo lo consigues?\");\n        answer1 = new Answer(\"Noqueo al que tiene el objeto y lo pillo\", 2, 0, 0,0);\n        answer2 = new Answer(\"Uso el sigilo y lo robo sin que se de cuenta\", 0, 2, 0,0);\n        answer3 = new Answer(\"Uso un hechizo para dormir a la persona y pillo el objeto\", 0, 0, 2,0);\n        answer4 = new Answer(\"Hablo con él y lo convenzo de que el objeto está mejor conmigo\", 0, 0, 0,2);\n        question.setAnswerList(Arrays.asList(answer1, answer2, answer3, answer4));\n        questionList.add(question);\n\n\n        //Pregunta 10\n        question = new Question(\"Necesitas dinero rápido ¿Cómo lo ganas?\");\n        answer1 = new Answer(\"Ayudo a cualquier comercio llevando carga\", 2, 0, 0,0);\n        answer2 = new Answer(\"Lo robo a alguna persona pudiente\", 0, 2, 0,0);\n        answer3 = new Answer(\"Creo alguna poción y la vendo en el mercado\", 0, 0, 2,0);\n        answer4 = new Answer(\"Interpreto en la plaza con mi laud\", 0, 0, 0,2);\n        question.setAnswerList(Arrays.asList(answer1, answer2, answer3, answer4));\n        questionList.add(question);\n    }\n\n    private Answer askQuestion(Question question, int qCounter){\n        System.out.println(\"---Pregunta \" + qCounter + \"---\");\n        System.out.println(question.getText());\n\n        List<Answer> answerList = question.getAnswerList();\n        Collections.shuffle(answerList);\n        int counter = 0;\n        for (Answer a : answerList){\n            System.out.println(letters[counter++] + \". \" + a.getText());\n        }\n\n        String userAnswer = askValidAnswerToUser();\n        System.out.println(\"------------------\");\n        return answerList.get(Arrays.asList(letters).indexOf(userAnswer));\n    }\n\n    private String askValidAnswerToUser(){\n        boolean validAnswer = false;\n        String userAnswer = null;\n        while(!validAnswer){\n            System.out.print(\"Respuesta: \");\n            userAnswer = sc.nextLine().strip().toLowerCase();\n\n            switch (userAnswer){\n                case \"a\": case \"b\":case \"c\": case \"d\":\n                    validAnswer = true;\n                    break;\n                default:\n                    System.out.println(\"Error. Elija una opción válida (a-d)\");\n            }\n        }\n\n        return userAnswer;\n    }\n\n    private House chooseHouse(){\n        House chosenHouse = null;\n        Set<House> tiedHouses = new HashSet<>();\n        for (House house : houseList){\n            if (chosenHouse == null){\n                chosenHouse = house;\n                continue;\n            }\n            if (house.getAffinityPoints() < chosenHouse.getAffinityPoints())\n                continue;\n            if (house.getAffinityPoints() == chosenHouse.getAffinityPoints()){\n                tiedHouses.add(house);\n                tiedHouses.add(chosenHouse);\n                continue;\n            }\n            chosenHouse = house;\n            tiedHouses.clear();\n        }\n        if (!tiedHouses.isEmpty()){\n            was_tied = true;\n            Random rnd = new Random();\n            chosenHouse = List.copyOf(tiedHouses).get(rnd.nextInt(tiedHouses.size()));\n        }\n\n        return chosenHouse;\n    }\n\n    public class House{\n        final private String NAME;\n        private int affinityPoints;\n\n        public House(String name) {\n            this.NAME = name;\n            affinityPoints = 0;\n        }\n\n        public String getNAME() {\n            return NAME;\n        }\n\n        public int getAffinityPoints() {\n            return affinityPoints;\n        }\n\n        public void addAffPoints(int amount){\n            affinityPoints += amount;\n        }\n    }\n\n    public class Question{\n        private String text;\n        private List<Answer> answerList;\n\n        public Question(String text) {\n            this.text = text;\n        }\n\n        public Question(String text, List<Answer> answerList) {\n            this.text = text;\n            this.answerList = answerList;\n        }\n\n        public String getText() {\n            return text;\n        }\n\n        public List<Answer> getAnswerList() {\n            return answerList;\n        }\n\n        public void setAnswerList(List<Answer> answerList) {\n            this.answerList = answerList;\n        }\n    }\n    public class Answer{\n        private String text;\n        final private int WARRIOR_HOUSE_POINTS;\n        final private int ROGUE_HOUSE_POINTS;\n        final private int WIZARD_HOUSE_POINTS;\n        final private int BARD_HOUSE_POINTS;\n\n        public Answer(String text, int WARRIOR_HOUSE_POINTS, int ROGUE_HOUSE_POINTS,\n                      int WIZARD_HOUSE_POINTS, int BARD_HOUSE_POINTS) {\n            this.WARRIOR_HOUSE_POINTS = WARRIOR_HOUSE_POINTS;\n            this.ROGUE_HOUSE_POINTS = ROGUE_HOUSE_POINTS;\n            this.WIZARD_HOUSE_POINTS = WIZARD_HOUSE_POINTS;\n            this.BARD_HOUSE_POINTS = BARD_HOUSE_POINTS;\n            this.text = text;\n        }\n\n        public String getText() {\n            return text;\n        }\n\n        public int getWARRIOR_HOUSE_POINTS() {\n            return WARRIOR_HOUSE_POINTS;\n        }\n\n        public int getROGUE_HOUSE_POINTS() {\n            return ROGUE_HOUSE_POINTS;\n        }\n\n        public int getWIZARD_HOUSE_POINTS() {\n            return WIZARD_HOUSE_POINTS;\n        }\n\n        public int getBARD_HOUSE_POINTS() {\n            return BARD_HOUSE_POINTS;\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/java/MohamedElderkaoui.java",
    "content": "import java.util.*;\n\npublic class MohamedElderkaoui {\n\n    static class House {\n        String name;\n        int score;\n\n        House(String name) {\n            this.name = name;\n            this.score = 0;\n        }\n    }\n\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n        Random random = new Random();\n\n        // Initial setup of houses\n        List<House> houses = Arrays.asList(\n            new House(\"Frontend\"),\n            new House(\"Backend\"),\n            new House(\"Mobile\"),\n            new House(\"Data\")\n        );\n\n        // Collect student information\n        System.out.print(\"¡Bienvenido! ¿Cuál es tu nombre? \");\n        String name = scanner.nextLine();\n        System.out.print(\"¿Qué edad tienes? \");\n        int age = scanner.nextInt();\n        scanner.nextLine(); // Consume the newline\n        System.out.print(\"¿Qué experiencia tienes en programación? (novato, intermedio, avanzado): \");\n        String experience = scanner.nextLine().toLowerCase();\n\n        // Personalized question sets based on experience\n        String[][] questions = generateQuestions(experience);\n\n        // Ask the questions with weights\n        for (int i = 0; i < questions.length; i++) {\n            System.out.println(\"\\n\" + questions[i][0]);\n            for (int j = 1; j <= 4; j++) {\n                System.out.println(j + \") \" + questions[i][j]);\n            }\n            System.out.print(\"Elige una opción (1-4): \");\n            int answer = scanner.nextInt();\n            \n            // Add weighted score to corresponding house\n            addWeightedScore(houses, answer, i + 1);\n        }\n\n        // Determine the house with the highest score\n        House selectedHouse = determineHouse(houses, random, age, experience);\n\n        // Display final result with personalized feedback\n        displayResult(name, selectedHouse);\n        scanner.close();\n    }\n\n\n    private static String[][] generateQuestions(String experience) {\n        if (experience.compareToIgnoreCase(\"novato\")==0) {\n            return new String[][] {\n                {\"¿Qué te gustaría aprender primero?\", \"HTML/CSS\", \"Bases de datos\", \"Desarrollo móvil básico\", \"Manipulación de datos\"},\n                {\"¿Qué tipo de proyectos te motivan?\", \"Sitios web\", \"Sistemas pequeños\", \"Apps sencillas\", \"Análisis simple\"},\n                {\"¿Cuál es tu entorno de aprendizaje preferido?\", \"Tutoriales en línea\", \"Cursos estructurados\", \"Aplicaciones de aprendizaje\", \"Proyectos con datos\"},\n                {\"¿Cómo prefieres trabajar?\", \"Diseñando interfaces\", \"Organizando datos\", \"Construyendo aplicaciones\", \"Analizando información\"},\n                {\"¿Qué lenguaje de programación te gustaría aprender primero?\", \"JavaScript\", \"SQL\", \"Kotlin\", \"Python\"},\n                {\"¿Qué te parece más interesante?\", \"Crear páginas web\", \"Gestionar bases de datos\", \"Desarrollar apps\", \"Analizar datos\"},\n                {\"¿En qué tipo de empresa te ves trabajando?\", \"Agencia digital\", \"Empresa de software\", \"Startup móvil\", \"Consultoría de datos\"},\n                {\"¿Qué prefieres en términos de desafíos?\", \"Diseñar una web atractiva\", \"Optimizar consultas\", \"Mejorar la usabilidad móvil\", \"Descubrir patrones en datos\"},\n                {\"¿Cuál sería tu rol/es ideal en un equipo?\", \"Diseñador web\", \"Administrador de bases de datos\", \"Desarrollador de apps\", \"Analista de datos\"},\n                {\"¿Cómo prefieres aprender?\", \"Con ejercicios prácticos\", \"Resolviendo problemas lógicos\", \"Desarrollando apps pequeñas\", \"Trabajando con datasets simples\"}\n            };\n            \n        } else if (experience.compareToIgnoreCase(\"intermedio\")==0) {\n            return new String[][] {\n                {\"¿Qué disfrutas optimizar?\", \"Experiencia visual\", \"Rendimiento del servidor\", \"Usabilidad móvil\", \"Procesos de datos\"},\n                {\"¿Qué es lo más importante en un proyecto?\", \"Usabilidad\", \"Eficiencia\", \"Compatibilidad\", \"Precisión de datos\"},\n                {\"¿Cómo abordas la resolución de problemas?\", \"Con creatividad\", \"Con análisis profundo\", \"Con prototipos rápidos\", \"Con datos empíricos\"},\n                {\"¿Qué prefieres en un entorno de desarrollo?\", \"Herramientas de diseño\", \"Depuradores avanzados\", \"Simuladores móviles\", \"Entornos de análisis de datos\"},\n                {\"¿Qué te impulsa en un proyecto?\", \"La estética\", \"La lógica\", \"La innovación\", \"Los resultados basados en datos\"},\n                {\"¿Cómo manejas el trabajo en equipo?\", \"Como líder de frontend\", \"Como arquitecto de backend\", \"Como desarrollador principal\", \"Como analista senior\"},\n                {\"¿Qué tendencia tecnológica te atrae?\", \"WebAssembly\", \"Serverless computing\", \"Realidad aumentada\", \"Machine learning\"},\n                {\"¿Qué lenguaje consideras esencial?\", \"JavaScript/TypeScript\", \"Go/Rust\", \"Swift/Java\", \"Python/R\"},\n                {\"¿Qué prefieres hacer en tu tiempo libre?\", \"Prototipar diseños\", \"Contribuir a proyectos open-source\", \"Desarrollar apps personales\", \"Trabajar en proyectos de análisis de datos\"},\n                {\"¿Cuál es tu objetivo a largo plazo?\", \"Ser un maestro de la experiencia de usuario\", \"Liderar la infraestructura de sistemas\", \"Crear apps de referencia\", \"Ser un gurú de los datos\"}\n            };\n            \n        } else {\n            return new String[][] {\n                {\"¿Qué disfrutas optimizar?\", \"Experiencia visual\", \"Rendimiento del servidor\", \"Usabilidad móvil\", \"Procesos de datos\"},\n                {\"¿Qué es lo más importante en un proyecto?\", \"Usabilidad\", \"Eficiencia\", \"Compatibilidad\", \"Precisión de datos\"},\n                {\"¿Cómo abordas la resolución de problemas?\", \"Con creatividad\", \"Con análisis profundo\", \"Con prototipos rápidos\", \"Con datos empíricos\"},\n                {\"¿Qué prefieres en un entorno de desarrollo?\", \"Herramientas de diseño\", \"Depuradores avanzados\", \"Simuladores móviles\", \"Entornos de análisis de datos\"},\n                {\"¿Qué te impulsa en un proyecto?\", \"La estética\", \"La lógica\", \"La innovación\", \"Los resultados basados en datos\"},\n                {\"¿Cómo manejas el trabajo en equipo?\", \"Como líder de frontend\", \"Como arquitecto de backend\", \"Como desarrollador principal\", \"Como analista senior\"},\n                {\"¿Qué tendencia tecnológica te atrae?\", \"WebAssembly\", \"Serverless computing\", \"Realidad aumentada\", \"Machine learning\"},\n                {\"¿Qué lenguaje consideras esencial?\", \"JavaScript/TypeScript\", \"Go/Rust\", \"Swift/Java\", \"Python/R\"},\n                {\"¿Qué prefieres hacer en tu tiempo libre?\", \"Prototipar diseños\", \"Contribuir a proyectos open-source\", \"Desarrollar apps personales\", \"Trabajar en proyectos de análisis de datos\"},\n                {\"¿Cuál es tu objetivo a largo plazo?\", \"Ser un maestro de la experiencia de usuario\", \"Liderar la infraestructura de sistemas\", \"Crear apps de referencia\", \"Ser un gurú de los datos\"}\n            };\n            \n        }\n    }\n\n    // Method to add weighted score to the corresponding house\n    private static void addWeightedScore(List<House> houses, int answer, int questionNumber) {\n        int weight = questionNumber; // More weight for later questions\n        houses.get(answer - 1).score += weight;\n    }\n\n    // Method to determine the house with the highest score and handle ties\n    private static House determineHouse(List<House> houses, Random random, int age, String experience) {\n        houses.sort((h1, h2) -> h2.score - h1.score);\n        List<House> topHouses = new ArrayList<>();\n        int maxScore = houses.get(0).score;\n\n        for (House house : houses) {\n            if (house.score == maxScore) {\n                topHouses.add(house);\n            }\n        }\n\n        // Consider age and experience as tie-breaker criteria\n        if (topHouses.size() > 1) {\n            System.out.println(\"\\n¡Fue una decisión difícil! Considerando tu edad y experiencia...\");\n            if (age < 20 && experience.equals(\"novato\")) {\n                return randomHouseSelection(topHouses, random, \"Frontend\");\n            } else if (age >= 20 && experience.equals(\"avanzado\")) {\n                return randomHouseSelection(topHouses, random, \"Backend\");\n            } else {\n                return topHouses.get(random.nextInt(topHouses.size()));\n            }\n        }\n\n        return topHouses.get(0);\n    }\n\n    // Method to randomly select a house, with preference based on certain conditions\n    private static House randomHouseSelection(List<House> topHouses, Random random, String preferredHouse) {\n        for (House house : topHouses) {\n            if (house.name.equals(preferredHouse)) {\n                return house;\n            }\n        }\n        return topHouses.get(random.nextInt(topHouses.size()));\n    }\n\n    // Method to display the final result with personalized feedback\n    private static void displayResult(String name, House selectedHouse) {\n        System.out.println(\"\\n¡Felicidades \" + name + \"! Has sido seleccionado para la casa \" + selectedHouse.name + \"!\");\n        System.out.println(\"Tu afinidad por la \" + selectedHouse.name + \" se refleja en tus respuestas.\");\n        if (selectedHouse.name.equals(\"Frontend\")) {\n            System.out.println(\"Eres una persona creativa, te encanta construir interfaces y mejorar la experiencia del usuario.\");\n        } else if (selectedHouse.name.equals(\"Backend\")) {\n            System.out.println(\"Disfrutas diseñar la lógica del servidor y crear sistemas eficientes y escalables.\");\n        } else if (selectedHouse.name.equals(\"Mobile\")) {\n            System.out.println(\"Te apasiona el desarrollo móvil y crear aplicaciones que lleguen a las manos de millones de usuarios.\");\n        } else if (selectedHouse.name.equals(\"Data\")) {\n            System.out.println(\"Te gusta analizar datos, encontrar patrones y dar sentido a la información compleja.\");\n        }\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/java/asjordi.java",
    "content": "import java.util.*;\n\npublic class Main {\n\n    public static void main(String[] args) {\n        Scanner sc = new Scanner(System.in);\n        Random random = new Random();\n\n        int[] puntos = new int[Casas.values().length];\n\n        welcome();\n        System.out.println(\"¿Cómo te llamas?\");\n        String nombre = sc.nextLine();\n\n        String[] preguntas = {\n                \"¿Cuál es tu lenguaje de programación favorito?\",\n                \"¿Qué prefieres hacer en tu tiempo libre?\",\n                \"¿Qué tipo de proyectos disfrutas más?\",\n                \"¿Cuál es tu herramienta preferida?\",\n                \"¿Qué prefieres aprender?\",\n                \"¿Qué tipo de desafíos te motivan más?\",\n                \"¿Cómo prefieres resolver problemas?\",\n                \"¿Qué tecnología te parece más interesante?\",\n                \"¿Cómo te gustaría que te reconocieran?\",\n                \"¿Qué tipo de ambiente de trabajo prefieres?\"\n        };\n\n        String[][] respuestas = {\n                {\"JavaScript\", \"Java\", \"Kotlin\", \"Python\"},\n                {\"Diseñar interfaces\", \"Desarrollar APIs\", \"Crear apps móviles\", \"Analizar datos\"},\n                {\"Sitios web\", \"Sistemas de backend\", \"Apps móviles\", \"Modelos de IA\"},\n                {\"Figma\", \"Postman\", \"Android Studio\", \"Jupyter Notebook\"},\n                {\"React\", \"Spring Boot\", \"Flutter\", \"Pandas\"},\n                {\"UX/UI\", \"Optimización\", \"Innovación\", \"Precisión\"},\n                {\"Prototipando\", \"Refactorizando\", \"Experimentando\", \"Investigando\"},\n                {\"HTML/CSS\", \"Microservicios\", \"IoT\", \"Big Data\"},\n                {\"Creatividad\", \"Eficiencia\", \"Innovación\", \"Precisión\"},\n                {\"Flexible\", \"Estructurado\", \"Dinámico\", \"Analítico\"}\n        };\n\n        int[][] asignacionPuntos = {\n                {10, 5, 2, 8},  // Respuestas a la pregunta 1\n                {8, 5, 10, 2},  // Respuestas a la pregunta 2\n                {10, 5, 8, 2},  // Respuestas a la pregunta 3\n                {5, 8, 10, 2},  // Respuestas a la pregunta 4\n                {10, 2, 5, 8},  // Respuestas a la pregunta 5\n                {8, 5, 10, 2},  // Respuestas a la pregunta 6\n                {10, 8, 5, 2},  // Respuestas a la pregunta 7\n                {5, 10, 8, 2},  // Respuestas a la pregunta 8\n                {10, 8, 5, 2},  // Respuestas a la pregunta 9\n                {8, 5, 10, 2}   // Respuestas a la pregunta 10\n        };\n\n        for (int i = 0; i < preguntas.length; i++) {\n            System.out.println(preguntas[i]);\n            for (int j = 0; j < respuestas[i].length; j++) {\n                System.out.println((j + 1) + \". \" + respuestas[i][j]);\n            }\n            System.out.print(\"Selecciona una opción (1-4): \");\n            int opcion = sc.nextInt() - 1;\n            for (int j = 0; j < puntos.length; j++) {\n                puntos[j] += asignacionPuntos[i][opcion];\n            }\n        }\n\n        int maxPuntos = 0;\n        int casaSeleccionada = -1;\n        boolean empate = false;\n\n        for (int i = 0; i < puntos.length; i++) {\n            if (puntos[i] > maxPuntos) {\n                maxPuntos = puntos[i];\n                casaSeleccionada = i;\n                empate = false;\n            } else if (puntos[i] == maxPuntos) empate = true;\n        }\n\n        if (empate) {\n            casaSeleccionada = random.nextInt(puntos.length);\n            System.out.println(\"¡Ha sido una decisión difícil!\");\n        }\n\n        System.out.println(\"El sombrero seleccionador ha decidido...\");\n        System.out.println(nombre + \", ¡pertenecerás a la casa \" + Casas.values()[casaSeleccionada] + \"!\");\n\n        sc.close();\n    }\n\n    private static void welcome() {\n        System.out.println(\"Bienvenido al Hogwarts Express\");\n        System.out.println(\"Con rumbo hacia la escuela de programación de Hogwarts para magos y brujas del código!\");\n        System.out.println(\"Soy el Sombrero Seleccionador, y te ayudaré a encontrar tu casa en la escuela de programación de Hogwarts.\");\n        System.out.println(\"Te haré unas preguntas y según tus respuestas, te asignaré a una de las cuatro casas de la escuela.\");\n        System.out.println(\"¡Vamos a empezar!\");\n    }\n\n\n    enum Casas {\n        FRONTEND, BACKEND, MOBILE, DATA\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/java/mantaras96.java",
    "content": "import java.util.ArrayList;\nimport java.util.List;\nimport java.util.Random;\nimport java.util.Scanner;\n\npublic class Mantaras96 {\n\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n        Respuestas respuestas = new Respuestas();\n\n        String name = obtenerNombreAlumno(scanner);\n\n        List<String> preguntas = cargarPreguntas();\n\n        // Aquí podrías llamar a otras funciones para continuar el programa, por\n        // ejemplo:\n        realizarPreguntas(scanner, respuestas, preguntas);\n        String casa = determinarCasa(respuestas);\n        System.out.println(\"El sombrero seleccionador ha decidido que perteneces a la casa: \" + casa);\n\n        scanner.close();\n    }\n\n    public static String determinarCasa(Respuestas respuestas) {\n        int maxPuntos = Math.max(Math.max(respuestas.getPuntosFront(), respuestas.getPuntosBack()),\n                Math.max(respuestas.getPuntosMobile(), respuestas.getPuntosData()));\n        List<String> casasEmpatadas = new ArrayList<>();\n\n        if (respuestas.getPuntosFront() == maxPuntos) {\n            casasEmpatadas.add(\"Frontend\");\n        }\n        if (respuestas.getPuntosBack() == maxPuntos) {\n            casasEmpatadas.add(\"Backend\");\n        }\n        if (respuestas.getPuntosMobile() == maxPuntos) {\n            casasEmpatadas.add(\"Mobile\");\n        }\n        if (respuestas.getPuntosData() == maxPuntos) {\n            casasEmpatadas.add(\"Data\");\n        }\n\n        if (casasEmpatadas.size() > 1) {\n            System.out.println(\"¡La decisión ha sido complicada! Hubo un empate.\");\n            Random random = new Random();\n            return casasEmpatadas.get(random.nextInt(casasEmpatadas.size()));\n        } else {\n            return casasEmpatadas.get(0);\n        }\n    }\n\n    public static void mostrarResultados(Respuestas respuestas) {\n        String casa = determinarCasa(respuestas);\n        System.out.println(\"El sombrero seleccionador ha decidido que perteneces a la casa: \" + casa);\n    }\n\n    public static List<String> cargarPreguntas() {\n        List<String> preguntas = new ArrayList<>();\n        preguntas.add(\n                \"Pregunta 1: ¿Qué lenguaje de programación prefieres? (Responde con 1 para JavaScript, 2 para Java, 3 para Swift, 4 para Python)\");\n        preguntas.add(\n                \"Pregunta 2: ¿Qué tipo de proyectos disfrutas más? (Responde con 1 para Aplicaciones web, 2 para Sistemas empresariales, 3 para Aplicaciones móviles, 4 para Análisis de datos)\");\n        preguntas.add(\n                \"Pregunta 3: ¿Qué herramienta prefieres usar? (Responde con 1 para React, 2 para Spring, 3 para Xcode, 4 para Pandas)\");\n        preguntas.add(\n                \"Pregunta 4: ¿Cuál es tu área de interés? (Responde con 1 para Diseño de interfaces, 2 para Arquitectura de software, 3 para Desarrollo de apps, 4 para Ciencia de datos)\");\n        preguntas.add(\n                \"Pregunta 5: ¿Qué prefieres hacer en tu tiempo libre? (Responde con 1 para Crear sitios web, 2 para Trabajar en backend, 3 para Desarrollar juegos móviles, 4 para Analizar grandes conjuntos de datos)\");\n        preguntas.add(\n                \"Pregunta 6: ¿Cuál es tu rol ideal en un equipo? (Responde con 1 para Diseñador UI/UX, 2 para Ingeniero de software, 3 para Desarrollador móvil, 4 para Científico de datos)\");\n        preguntas.add(\n                \"Pregunta 7: ¿Qué tecnología te emociona más? (Responde con 1 para CSS y HTML, 2 para Microservicios, 3 para Kotlin, 4 para Machine Learning)\");\n        preguntas.add(\n                \"Pregunta 8: ¿Qué tipo de problemas te gusta resolver? (Responde con 1 para Problemas de diseño, 2 para Problemas de lógica, 3 para Problemas de accesibilidad, 4 para Problemas de análisis de datos)\");\n        preguntas.add(\n                \"Pregunta 9: ¿Qué tipo de lectura prefieres? (Responde con 1 para Blogs de diseño, 2 para Libros técnicos, 3 para Artículos sobre desarrollo móvil, 4 para Investigaciones de datos)\");\n        preguntas.add(\n                \"Pregunta 10: ¿Dónde te ves en cinco años? (Responde con 1 para Desarrollando interfaces innovadoras, 2 para Liderando equipos de backend, 3 para Creando apps revolucionarias, 4 para Descubriendo insights en datos)\");\n        return preguntas;\n    }\n\n    public static void realizarPreguntas(Scanner scanner, Respuestas respuestas, List<String> preguntas) {\n        for (String pregunta : preguntas) {\n            boolean respuestaValida = false;\n            while (!respuestaValida) {\n                System.out.println(pregunta);\n                String respuesta = scanner.nextLine();\n                try {\n                    int puntos = Integer.parseInt(respuesta);\n                    respuestas.addPointsToHouse(puntos);\n                    respuestaValida = true;\n                } catch (NumberFormatException e) {\n                    System.out.println(\"Por favor, ingrese un número válido.\");\n                }\n            }\n        }\n    }\n\n    public static String obtenerNombreAlumno(Scanner scanner) {\n        System.out.println(\"Bienvenido a Hogwarts. Indica tu nombre al sombrero seleccionador:\");\n        String name = scanner.nextLine();\n        return name;\n    }\n\n    public static class Respuestas {\n        int puntosFront = 0;\n        int puntosBack = 0;\n        int puntosMobile = 0;\n        int puntosData = 0;\n\n        public int getPuntosFront() {\n            return puntosFront;\n        }\n\n        public void setPuntosFront(int puntosFront) {\n            this.puntosFront = puntosFront;\n        }\n\n        public int getPuntosBack() {\n            return puntosBack;\n        }\n\n        public void setPuntosBack(int puntosBack) {\n            this.puntosBack = puntosBack;\n        }\n\n        public int getPuntosMobile() {\n            return puntosMobile;\n        }\n\n        public void setPuntosMobile(int puntosMobile) {\n            this.puntosMobile = puntosMobile;\n        }\n\n        public int getPuntosData() {\n            return puntosData;\n        }\n\n        public void setPuntosData(int puntosData) {\n            this.puntosData = puntosData;\n        }\n\n        public Respuestas() {\n            // Constructor por defecto\n        }\n\n        public void addPointsToHouse(int points) {\n            switch (points) {\n                case 1:\n                    this.puntosFront++;\n                    break;\n                case 2:\n                    this.puntosBack++;\n                    break;\n                case 3:\n                    this.puntosMobile++;\n                    break;\n                case 4:\n                    this.puntosData++;\n                    break;\n            }\n\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/java/martinbohorquez.java",
    "content": "import java.util.*;\nimport java.util.concurrent.atomic.AtomicReference;\n\n/**\n * #36 EL SOMBRERO SELECCIONADOR\n *\n * @author martinbohorquez\n */\npublic class martinbohorquez {\n    static List<QuestionAnswers> questionAnswers = new ArrayList<>();\n    static Map<House, Integer> houses = new LinkedHashMap<>();\n    static Scanner sc = new Scanner(System.in);\n\n    public static void main(String[] args) {\n        houses.put(House.FRONTED, 0);\n        houses.put(House.BACKEND, 0);\n        houses.put(House.MOBILE, 0);\n        houses.put(House.DATA, 0);\n\n        questionAnswers = setQuestions();\n        System.out.println(\"\"\"\n                ¡Bienvenido a Hogwarts, la escuela de programación para magos y brujas del código!\n                El sombrero seleccionador decidirá cuál es tu casa como programador.\n                \"\"\");\n        System.out.print(\"Indicar su nombre: \");\n        String name = sc.nextLine();\n\n        displayQuestions();\n        displayResult(name);\n    }\n\n    private static List<QuestionAnswers> setQuestions() {\n        // QuestionAnswers 1\n        String question1 = \"¿Qué tipo de proyectos te interesa más desarrollar?\";\n        List<Answer> answers1 = new ArrayList<>(List.of(\n                new Answer(\"Interfaces visualmente atractivas y responsivas.\", House.FRONTED),\n                new Answer(\"Sistemas robustos y optimización de rendimiento del servidor.\", House.BACKEND),\n                new Answer(\"Aplicaciones móviles nativas para múltiples plataformas.\", House.MOBILE),\n                new Answer(\"Procesamiento y análisis de grandes volúmenes de datos.\", House.DATA)\n        ));\n        Collections.shuffle(answers1);\n        questionAnswers.add(new QuestionAnswers(question1, answers1));\n\n        // QuestionAnswers 2\n        String question2 = \"¿En qué parte del ciclo de desarrollo te sientes más cómodo?\";\n        List<Answer> answers2 = new ArrayList<>(List.of(\n                new Answer(\"Creación de interfaces de usuario.\", House.FRONTED),\n                new Answer(\"Desarrollo de sistemas de backend.\", House.BACKEND),\n                new Answer(\"Diseño y arquitectura de bases de datos.\", House.DATA),\n                new Answer(\"Desarrollo de aplicaciones móviles con gran experiencia de usuario.\", House.MOBILE)\n        ));\n        Collections.shuffle(answers2);\n        questionAnswers.add(new QuestionAnswers(question2, answers2));\n\n        // QuestionAnswers 3\n        String question3 = \"¿Qué herramienta prefieres usar en tu día a día?\";\n        List<Answer> answers3 = new ArrayList<>(List.of(\n                new Answer(\"Figma o Sketch para diseño UI/UX.\", House.FRONTED),\n                new Answer(\"Postman o cURL para probar APIs.\", House.BACKEND),\n                new Answer(\"SQL o Python para análisis de datos.\", House.DATA),\n                new Answer(\"Android Studio o Xcode.\", House.MOBILE)\n        ));\n        Collections.shuffle(answers3);\n        questionAnswers.add(new QuestionAnswers(question3, answers3));\n\n        // QuestionAnswers 4\n        String question4 = \"¿Qué lenguaje de programación prefieres?\";\n        List<Answer> answers4 = new ArrayList<>(List.of(\n                new Answer(\"JavaScript o TypeScript.\", House.FRONTED),\n                new Answer(\"Java o Kotlin.\", House.MOBILE),\n                new Answer(\"Python o R.\", House.DATA),\n                new Answer(\"Java o Go.\", House.BACKEND)\n        ));\n        Collections.shuffle(answers4);\n        questionAnswers.add(new QuestionAnswers(question4, answers4));\n\n        // QuestionAnswers 5\n        String question5 = \"¿Qué es lo que más disfrutas resolver en un proyecto?\";\n        List<Answer> answers5 = new ArrayList<>(List.of(\n                new Answer(\"Diseñar y construir pantallas interactivas.\", House.FRONTED),\n                new Answer(\"Optimizar la comunicación entre servidores y bases de datos.\", House.BACKEND),\n                new Answer(\"Extraer información valiosa de grandes conjuntos de datos.\", House.DATA),\n                new Answer(\"Optimizar el rendimiento de una aplicación móvil.\", House.MOBILE)\n        ));\n        Collections.shuffle(answers5);\n        questionAnswers.add(new QuestionAnswers(question5, answers5));\n\n        // QuestionAnswers 6\n        String question6 = \"¿Qué consideras esencial para un proyecto exitoso?\";\n        List<Answer> answers6 = new ArrayList<>(List.of(\n                new Answer(\"Una interfaz intuitiva y atractiva.\", House.FRONTED),\n                new Answer(\"Un backend eficiente y seguro.\", House.BACKEND),\n                new Answer(\"Datos limpios y bien estructurados.\", House.DATA),\n                new Answer(\"Una aplicación móvil sin fallos y rápida.\", House.MOBILE)\n        ));\n        Collections.shuffle(answers6);\n        questionAnswers.add(new QuestionAnswers(question6, answers6));\n\n        // QuestionAnswers 7\n        String question7 = \"¿Cómo prefieres abordar un problema complejo?\";\n        List<Answer> answers7 = new ArrayList<>(List.of(\n                new Answer(\"Dividiéndolo en pequeños componentes visuales.\", House.FRONTED),\n                new Answer(\"Optimizando el procesamiento del servidor.\", House.BACKEND),\n                new Answer(\"Modelando los datos de manera eficiente.\", House.DATA),\n                new Answer(\"Dividiendo la funcionalidad entre distintas plataformas móviles.\", House.MOBILE)\n        ));\n        Collections.shuffle(answers7);\n        questionAnswers.add(new QuestionAnswers(question7, answers7));\n\n        // QuestionAnswers 8\n        String question8 = \"¿En qué contexto te sientes más productivo?\";\n        List<Answer> answers8 = new ArrayList<>(List.of(\n                new Answer(\"Diseñando interfaces responsivas.\", House.FRONTED),\n                new Answer(\"Construyendo APIs o microservicios.\", House.BACKEND),\n                new Answer(\"Analizando grandes volúmenes de datos.\", House.DATA),\n                new Answer(\"Desarrollando aplicaciones para Android o iOS.\", House.MOBILE)\n        ));\n        Collections.shuffle(answers8);\n        questionAnswers.add(new QuestionAnswers(question8, answers8));\n\n        // QuestionAnswers 9\n        String question9 = \"¿Qué tecnología te gustaría dominar más?\";\n        List<Answer> answers9 = new ArrayList<>(List.of(\n                new Answer(\"React o Angular.\", House.FRONTED),\n                new Answer(\"Django o Spring Boot.\", House.BACKEND),\n                new Answer(\"Hadoop o Spark.\", House.DATA),\n                new Answer(\"Flutter o React Native.\", House.MOBILE)\n        ));\n        Collections.shuffle(answers9);\n        questionAnswers.add(new QuestionAnswers(question9, answers9));\n\n        // QuestionAnswers 10\n        String question10 = \"¿Qué tipo de problemas te entusiasma resolver?\";\n        List<Answer> answers10 = new ArrayList<>(List.of(\n                new Answer(\"Hacer que las aplicaciones sean visualmente impactantes.\", House.FRONTED),\n                new Answer(\"Garantizar la seguridad y escalabilidad del sistema.\", House.BACKEND),\n                new Answer(\"Procesar y extraer conocimientos de datos complejos.\", House.DATA),\n                new Answer(\"Optimizar el rendimiento en aplicaciones móviles.\", House.MOBILE)\n        ));\n        Collections.shuffle(answers10);\n        questionAnswers.add(new QuestionAnswers(question10, answers10));\n        Collections.shuffle(questionAnswers);\n        return questionAnswers;\n    }\n\n    private static void displayQuestions() {\n        AtomicReference<Integer> id = new AtomicReference<>(1);\n        questionAnswers.forEach(questionAnswers -> {\n                    AtomicReference<Integer> idA = new AtomicReference<>(1);\n                    while (true) {\n                        System.out.println(\"-\".repeat(80));\n                        System.out.printf(\"Pregunta %d: %s%n\", id.get(), questionAnswers.question());\n                        questionAnswers.answers.forEach(answer -> System.out.printf(\"%d. %s%n\",\n                                idA.getAndSet(idA.get() + 1), answer.option()));\n                        System.out.print(\"Selecciona una respuesta entre 1 y 4: \");\n                        try {\n                            int choice = Integer.parseInt(sc.nextLine());\n\n                            House house = questionAnswers.answers().get(choice - 1).house();\n                            houses.replace(house, houses.get(house), houses.get(house) + 1);\n                            id.set(id.get() + 1);\n                            break;\n                        } catch (NumberFormatException | IndexOutOfBoundsException e) {\n                            idA.set(1);\n                            System.out.println(\"Esa opción no es valida! Volver a responder la pregunta.\");\n                        }\n                    }\n                }\n        );\n    }\n\n    private static void displayResult(String name) {\n        House assignedHouse = Collections.max(houses.entrySet(), Map.Entry.comparingByValue()).getKey();\n        List<Integer> scores = houses.values().stream().toList();\n        System.out.println(\"-\".repeat(80));\n        System.out.println(\"<----- RESULTADOS DEL TEST ----->\");\n        System.out.println(\"Tus preferencias son:\");\n        houses.forEach((house, integer) ->\n                System.out.println(house + \" -> \" + (\"|\" + house.getEmoji() + \"|\").repeat(integer)));\n\n        Integer maxScore = scores.stream().max(Integer::compareTo).orElse(null);\n        List<Integer> maxScores = scores.stream().filter(s -> s.equals(maxScore)).toList();\n        if (maxScores.size() > 1) {\n\n            Random random = new Random();\n            assignedHouse = new ArrayList<>(houses.entrySet().stream()\n                    .filter(houseIntegerEntry -> houseIntegerEntry.getValue().equals(maxScore))\n                    .map(Map.Entry::getKey)\n                    .toList())\n                    .get(random.nextInt(0, maxScores.size()));\n            System.out.printf(\"\"\"\n                    Hmmm... Ha sido una decisión muy complicada %s.\n                    ¡Pero finalmente tu casa será %s [%s]\n                    \"\"\", name, assignedHouse, assignedHouse.getEmoji());\n        } else {\n            System.out.printf(\"\"\"\n                    Hmmm... Enhorabuena %s.\n                    ¡Tu casa será %s [%s]\n                    \"\"\", name, assignedHouse, assignedHouse.getEmoji());\n        }\n    }\n\n    private record QuestionAnswers(String question, List<Answer> answers) {\n    }\n\n    private record Answer(String option, House house) {\n    }\n\n    private enum House {\n        FRONTED(\"Fronted\", \"🌐\"),\n        BACKEND(\"Backend\", \"💻\"),\n        MOBILE(\"Mobile\", \"📲\"),\n        DATA(\"Data\", \"📊\");\n\n        private final String displayName;\n        private final String emoji;\n\n        House(String displayName, String emoji) {\n            this.displayName = displayName;\n            this.emoji = emoji;\n        }\n\n        public String getEmoji() {\n            return emoji;\n        }\n\n        @Override\n        public String toString() {\n            return displayName;\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/java/miguelex.java",
    "content": "import java.util.*;\n\nclass Casa {\n    private String nombre;\n    private int puntos;\n\n    public Casa(String nombre) {\n        this.nombre = nombre;\n        this.puntos = 0;\n    }\n\n    public String getNombre() {\n        return nombre;\n    }\n\n    public void agregarPuntos(int puntos) {\n        this.puntos += puntos;\n    }\n\n    public int getPuntos() {\n        return puntos;\n    }\n}\n\nclass Alumno {\n    private String nombre;\n\n    public Alumno(String nombre) {\n        this.nombre = nombre;\n    }\n\n    public String getNombre() {\n        return nombre;\n    }\n}\n\nclass Pregunta {\n    private String pregunta;\n    private List<Opcion> opciones;\n\n    public Pregunta(String pregunta, List<Opcion> opciones) {\n        this.pregunta = pregunta;\n        this.opciones = opciones;\n    }\n\n    public void mostrarPregunta() {\n        System.out.println(pregunta);\n        for (int i = 0; i < opciones.size(); i++) {\n            System.out.println((i + 1) + \": \" + opciones.get(i).getTexto());\n        }\n    }\n\n    public String obtenerCasaSegunRespuesta(int respuesta) {\n        return opciones.get(respuesta - 1).getCasa();\n    }\n}\n\nclass Opcion {\n    private String texto;\n    private String casa;\n\n    public Opcion(String texto, String casa) {\n        this.texto = texto;\n        this.casa = casa;\n    }\n\n    public String getTexto() {\n        return texto;\n    }\n\n    public String getCasa() {\n        return casa;\n    }\n}\n\nclass SombreroSeleccionador {\n    private Map<String, Casa> casas;\n    private List<Pregunta> preguntas;\n\n    public SombreroSeleccionador(Map<String, Casa> casas, List<Pregunta> preguntas) {\n        this.casas = casas;\n        this.preguntas = preguntas;\n    }\n\n    public void asignarCasa(Alumno alumno) {\n        List<Pregunta> preguntasSeleccionadas = seleccionarPreguntas();\n        Scanner scanner = new Scanner(System.in);\n\n        for (Pregunta pregunta : preguntasSeleccionadas) {\n            pregunta.mostrarPregunta();\n            int respuesta = leerRespuesta(scanner);\n            String casa = pregunta.obtenerCasaSegunRespuesta(respuesta);\n            casas.get(casa).agregarPuntos(1);\n        }\n\n        mostrarResultado(alumno);\n        scanner.close();\n    }\n\n    private List<Pregunta> seleccionarPreguntas() {\n        List<Pregunta> preguntasSeleccionadas = new ArrayList<>();\n        Set<Integer> indicesSeleccionados = new HashSet<>();\n        Random random = new Random();\n\n        while (preguntasSeleccionadas.size() < 10) {\n            int indice = random.nextInt(preguntas.size());\n            if (!indicesSeleccionados.contains(indice)) {\n                indicesSeleccionados.add(indice);\n                preguntasSeleccionadas.add(preguntas.get(indice));\n            }\n        }\n\n        return preguntasSeleccionadas;\n    }\n\n    private int leerRespuesta(Scanner scanner) {\n        int respuesta = 0;\n        while (respuesta < 1 || respuesta > 4) {\n            System.out.print(\"Selecciona una opción (1-4): \");\n            respuesta = scanner.nextInt();\n        }\n        return respuesta;\n    }\n\n    private void mostrarResultado(Alumno alumno) {\n        List<Casa> casasOrdenadas = new ArrayList<>(casas.values());\n        casasOrdenadas.sort(Comparator.comparingInt(Casa::getPuntos).reversed());\n\n        int maxPuntos = casasOrdenadas.get(0).getPuntos();\n        List<Casa> ganadoras = new ArrayList<>();\n        for (Casa casa : casasOrdenadas) {\n            if (casa.getPuntos() == maxPuntos) {\n                ganadoras.add(casa);\n            }\n        }\n\n        Casa ganadora;\n        if (ganadoras.size() > 1) {\n            System.out.println(\"\\n\\nLa decisión fue difícil...\");\n            Random random = new Random();\n            ganadora = ganadoras.get(random.nextInt(ganadoras.size()));\n        } else {\n            ganadora = ganadoras.get(0);\n        }\n\n        System.out.println(\"\\n\\n\" + alumno.getNombre() + \", el sombrero seleccionador te ha asignado a la casa \" + ganadora.getNombre().toUpperCase() + \"!!!!\\n\");\n    }\n}\n\npublic class miguelex {\n    public static void main(String[] args) {\n        Map<String, Casa> casas = new HashMap<>();\n        casas.put(\"frontend\", new Casa(\"Frontend\"));\n        casas.put(\"backend\", new Casa(\"Backend\"));\n        casas.put(\"mobile\", new Casa(\"Mobile\"));\n        casas.put(\"data\", new Casa(\"Data\"));\n\n        List<Pregunta> preguntas = Arrays.asList(\n            new Pregunta(\"¿Qué prefieres?\", Arrays.asList(\n                new Opcion(\"Diseñar interfaces\", \"frontend\"),\n                new Opcion(\"Crear APIs\", \"backend\"),\n                new Opcion(\"Desarrollar apps móviles\", \"mobile\"),\n                new Opcion(\"Analizar datos\", \"data\")\n            )),\n            new Pregunta(\"¿Cuál es tu lenguaje de programación favorito?\", Arrays.asList(\n                new Opcion(\"JavaScript\", \"frontend\"),\n                new Opcion(\"Python\", \"backend\"),\n                new Opcion(\"Kotlin\", \"mobile\"),\n                new Opcion(\"R\", \"data\")\n            )),\n            new Pregunta(\"¿Qué herramienta utilizas más a menudo?\", Arrays.asList(\n                new Opcion(\"Figma o Sketch\", \"frontend\"),\n                new Opcion(\"Docker o Kubernetes\", \"backend\"),\n                new Opcion(\"Android Studio o Xcode\", \"mobile\"),\n                new Opcion(\"Jupyter Notebooks o Excel\", \"data\")\n            )),\n            new Pregunta(\"¿Qué te interesa más aprender?\", Arrays.asList(\n                new Opcion(\"HTML/CSS y JavaScript avanzado\", \"frontend\"),\n                new Opcion(\"Patrones de diseño y arquitectura de software\", \"backend\"),\n                new Opcion(\"Programación nativa para dispositivos móviles\", \"mobile\"),\n                new Opcion(\"Estadística y Machine Learning\", \"data\")\n            )),\n            new Pregunta(\"¿Qué tipo de proyecto te gustaría liderar?\", Arrays.asList(\n                new Opcion(\"Un sitio web interactivo y atractivo\", \"frontend\"),\n                new Opcion(\"Una plataforma escalable con microservicios\", \"backend\"),\n                new Opcion(\"Una app móvil innovadora\", \"mobile\"),\n                new Opcion(\"Un sistema de recomendación basado en datos\", \"data\")\n            )),\n            new Pregunta(\"¿Qué es lo más importante para ti en un proyecto?\", Arrays.asList(\n                new Opcion(\"La experiencia de usuario\", \"frontend\"),\n                new Opcion(\"El rendimiento y la escalabilidad\", \"backend\"),\n                new Opcion(\"La adaptabilidad a diferentes dispositivos\", \"mobile\"),\n                new Opcion(\"La precisión de los análisis\", \"data\")\n            )),\n            new Pregunta(\"¿Qué prefieres trabajar?\", Arrays.asList(\n                new Opcion(\"En un entorno donde el diseño visual es clave\", \"frontend\"),\n                new Opcion(\"En la lógica del negocio y la arquitectura\", \"backend\"),\n                new Opcion(\"En apps móviles con buen rendimiento\", \"mobile\"),\n                new Opcion(\"En el análisis y visualización de datos\", \"data\")\n            )),\n            new Pregunta(\"¿Qué framework te parece más interesante?\", Arrays.asList(\n                new Opcion(\"React o Angular\", \"frontend\"),\n                new Opcion(\"Spring o Django\", \"backend\"),\n                new Opcion(\"Flutter o React Native\", \"mobile\"),\n                new Opcion(\"TensorFlow o Pandas\", \"data\")\n            )),\n            new Pregunta(\"¿Qué tipo de reto disfrutas más?\", Arrays.asList(\n                new Opcion(\"Hacer que un sitio web sea accesible y rápido\", \"frontend\"),\n                new Opcion(\"Optimizar la comunicación entre servicios\", \"backend\"),\n                new Opcion(\"Mejorar la experiencia del usuario en móviles\", \"mobile\"),\n                new Opcion(\"Encontrar patrones ocultos en los datos\", \"data\")\n            )),\n            new Pregunta(\"¿Qué prefieres resolver?\", Arrays.asList(\n                new Opcion(\"Problemas de diseño y maquetación\", \"frontend\"),\n                new Opcion(\"Problemas de concurrencia y escalabilidad\", \"backend\"),\n                new Opcion(\"Problemas de rendimiento en aplicaciones móviles\", \"mobile\"),\n                new Opcion(\"Problemas de predicción y análisis de datos\", \"data\")\n            )),\n            new Pregunta(\"¿Qué es lo que más te emociona en tecnología?\", Arrays.asList(\n                new Opcion(\"La evolución de las interfaces de usuario\", \"frontend\"),\n                new Opcion(\"La innovación en la arquitectura de software\", \"backend\"),\n                new Opcion(\"Las nuevas capacidades de los dispositivos móviles\", \"mobile\"),\n                new Opcion(\"Los avances en inteligencia artificial y análisis de datos\", \"data\")\n            )),\n            new Pregunta(\"¿Qué te gusta hacer en tu tiempo libre?\", Arrays.asList(\n                new Opcion(\"Diseñar sitios web personales o interfaces\", \"frontend\"),\n                new Opcion(\"Hacer proyectos con servidores y APIs\", \"backend\"),\n                new Opcion(\"Crear apps móviles para resolver problemas cotidianos\", \"mobile\"),\n                new Opcion(\"Hacer análisis de datos para tomar decisiones mejor informadas\", \"data\")\n            )),\n            new Pregunta(\"¿Qué te gustaría dominar?\", Arrays.asList(\n                new Opcion(\"Animaciones y transiciones en la web\", \"frontend\"),\n                new Opcion(\"Arquitectura de microservicios\", \"backend\"),\n                new Opcion(\"Optimización de aplicaciones móviles\", \"mobile\"),\n                new Opcion(\"Modelos predictivos y análisis de datos\", \"data\")\n            )),\n            new Pregunta(\"¿Qué tipo de problema prefieres resolver en un hackathon?\", Arrays.asList(\n                new Opcion(\"Mejorar la interfaz de usuario de una aplicación\", \"frontend\"),\n                new Opcion(\"Optimizar el rendimiento de una API\", \"backend\"),\n                new Opcion(\"Crear una aplicación móvil desde cero\", \"mobile\"),\n                new Opcion(\"Generar insights a partir de grandes conjuntos de datos\", \"data\")\n            )),\n            new Pregunta(\"¿Qué prefieres al trabajar en equipo?\", Arrays.asList(\n                new Opcion(\"Encargarte de la parte visual y de interacción del usuario\", \"frontend\"),\n                new Opcion(\"Asegurarte de que la lógica y los datos fluyan correctamente\", \"backend\"),\n                new Opcion(\"Hacer que la app funcione bien en diferentes dispositivos\", \"mobile\"),\n                new Opcion(\"Proveer métricas y análisis para tomar mejores decisiones\", \"data\")\n            )),\n            new Pregunta(\"¿Cuál es tu prioridad al optimizar código?\", Arrays.asList(\n                new Opcion(\"Que la interfaz cargue rápido y sea amigable\", \"frontend\"),\n                new Opcion(\"Que los servicios backend sean escalables y eficientes\", \"backend\"),\n                new Opcion(\"Que la app móvil consuma pocos recursos y sea fluida\", \"mobile\"),\n                new Opcion(\"Que el procesamiento de datos sea rápido y preciso\", \"data\")\n            )),\n            new Pregunta(\"¿Qué prefieres al probar una aplicación?\", Arrays.asList(\n                new Opcion(\"Verificar que el diseño y la usabilidad sean impecables\", \"frontend\"),\n                new Opcion(\"Asegurar que las funcionalidades y la lógica sean correctas\", \"backend\"),\n                new Opcion(\"Revisar que la app funcione correctamente en múltiples dispositivos\", \"mobile\"),\n                new Opcion(\"Validar que los resultados de los análisis sean exactos\", \"data\")\n            )),\n            new Pregunta(\"¿Qué tipo de proyectos sigues en la industria?\", Arrays.asList(\n                new Opcion(\"Proyectos de diseño web innovador y UX\", \"frontend\"),\n                new Opcion(\"Nuevas tecnologías de servidores y backends\", \"backend\"),\n                new Opcion(\"Aplicaciones móviles disruptivas y eficientes\", \"mobile\"),\n                new Opcion(\"Proyectos de inteligencia artificial y ciencia de datos\", \"data\")\n            )),\n            new Pregunta(\"¿Qué harías para mejorar una plataforma existente?\", Arrays.asList(\n                new Opcion(\"Mejorar la apariencia y usabilidad de la interfaz\", \"frontend\"),\n                new Opcion(\"Optimizar el rendimiento de las consultas y los servidores\", \"backend\"),\n                new Opcion(\"Hacer que la plataforma sea accesible desde dispositivos móviles\", \"mobile\"),\n                new Opcion(\"Incluir más análisis de datos para obtener mejor información\", \"data\")\n            )),\n            new Pregunta(\"¿Qué aspecto del desarrollo de software te parece más retador?\", Arrays.asList(\n                new Opcion(\"Hacer que una aplicación web sea visualmente atractiva\", \"frontend\"),\n                new Opcion(\"Crear sistemas backend que manejen millones de usuarios\", \"backend\"),\n                new Opcion(\"Optimizar la app móvil para diferentes sistemas operativos\", \"mobile\"),\n                new Opcion(\"Gestionar grandes volúmenes de datos y extraer conclusiones útiles\", \"data\")\n            ))\n        );\n\n        Scanner scanner = new Scanner(System.in);\n        System.out.print(\"Por favor, introduce tu nombre: \");\n        String nombreAlumno = scanner.nextLine();\n        Alumno alumno = new Alumno(nombreAlumno);\n\n        SombreroSeleccionador sombrero = new SombreroSeleccionador(casas, preguntas);\n        sombrero.asignarCasa(alumno);\n    }\n}\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #36 - JavaScript -> Jesus Antonio Escamilla */\n\n/**\n * EL SOMBRERO SELECCIONADOR.\n * Utilizando la Terminal para pedir datos y agregarlos.\n */\n\nconst readline = require('readline');\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\n// Casas y sus puntos iniciales\nconst house = {\n    Frontend: 0,\n    Backend: 0,\n    Mobile: 0,\n    Data: 0\n}\n\n// Preguntas y sus opciones con puntos asignados a cada casa\nconst questions = [\n    {\n        question: '1- ¿Qué tipo de proyectos te entusiasma más desarrollar?',\n        options: {\n            a: { text: 'APIs y lógica de negocio en el servidor.', points: { Backend: 2 } },\n            b: { text: 'Análisis de datos y modelos predictivos.', points: { Data: 2 } },\n            c: { text: 'Aplicaciones móviles con experiencia de usuario fluida.', points: { Mobile: 2 } },\n            d: { text: 'Aplicaciones web interactivas con diseño atractivo.', points: { Frontend: 2 } },\n        },\n    },\n    {\n        question: '2- ¿Cuál es tu entorno de trabajo favorito?',\n        options: {\n            a: { text: 'Terminales y scripts de automatización.', points: { Backend: 2 } },\n            b: { text: 'Emuladores y entornos móviles.', points: { Mobile: 2 } },\n            c: { text: 'Entornos visuales y herramientas de diseño.', points: { Frontend: 2 } },\n            d: { text: 'Herramientas de análisis de datos y estadísticas.', points: { Data: 2 } },\n        },\n    },\n    {\n        question: '3- ¿Qué lenguaje de programación prefieres?',\n        options: {\n            a: { text: 'Python o R para análisis de datos.', points: { Data: 2 } },\n            b: { text: 'JavaScript o TypeScript para desarrollo web.', points: { Frontend: 2 } },\n            c: { text: 'Python o Java para desarrollo backend.', points: { Backend: 2 } },\n            d: { text: 'Kotlin o Swift para desarrollo móvil.', points: { Mobile: 2 } },\n        },\n    },\n    {\n        question: '4- ¿Qué aspecto disfrutas más al resolver problemas?',\n        options: {\n            a: { text: 'Extraer y analizar patrones de grandes volúmenes de datos.', points: { Data: 2 } },\n            b: { text: 'Crear interfaces intuitivas y responsivas.', points: { Frontend: 2 } },\n            c: { text: 'Implementar funcionalidades en dispositivos móviles.', points: { Mobile: 2 } },\n            d: { text: 'Optimizar la lógica y la arquitectura del servidor.', points: { Backend: 2 } },\n        },\n    },\n    {\n        question: '5- ¿Qué tecnología o framework te interesa aprender más?',\n        options: {\n            a: { text: 'Node.js, Django, o Spring.', points: { Backend: 2 } },\n            b: { text: 'TensorFlow, Pandas, o Spark.', points: { Data: 2 } },\n            c: { text: 'React, Angular, o Vue.', points: { Frontend: 2 } },\n            d: { text: 'React Native, Flutter, o SwiftUI.', points: { Mobile: 2 } },\n        },\n    },\n    {\n        question: '6- ¿Cómo prefieres estructurar tu código?',\n        options: {\n            a: { text: 'Controladores de vistas y gestores de estado.', points: { Mobile: 2 } },\n            b: { text: 'Scripts y pipelines de datos organizados.', points: { Data: 2 } },\n            c: { text: 'Servicios y controladores bien definidos.', points: { Backend: 2 } },\n            d: { text: 'Componentes modulares y reutilizables.', points: { Frontend: 2 } },\n        },\n    },\n    {\n        question: '7- ¿Qué herramienta te parece más útil en tu desarrollo diario?',\n        options: {\n            a: { text: 'Simuladores y herramientas de debugging móvil.', points: { Mobile: 2 } },\n            b: { text: 'Inspectores de navegador y herramientas de diseño.', points: { Frontend: 2 } },\n            c: { text: 'Postman y bases de datos.', points: { Backend: 2 } },\n            d: { text: 'Jupyter Notebooks y herramientas de visualización de datos.', points: { Data: 2 } },\n        },\n    },\n    {\n        question: '8- ¿Qué te motiva más en tu carrera de desarrollo?',\n        options: {\n            a: { text: 'Llevar nuevas ideas al mercado rápidamente en dispositivos móviles.', points: { Mobile: 2 } },\n            b: { text: 'Asegurar la estabilidad y seguridad del sistema.', points: { Backend: 2 } },\n            c: { text: 'Descubrir conocimientos ocultos en los datos.', points: { Data: 2 } },\n            d: { text: 'Crear interfaces que los usuarios amen usar.', points: { Frontend: 2 } },\n        },\n    },\n    {\n        question: '9- ¿Qué consideras más importante en un proyecto?',\n        options: {\n            a: { text: 'La portabilidad y rendimiento en diferentes dispositivos.', points: { Mobile: 2 } },\n            b: { text: 'La eficiencia y escalabilidad del backend.', points: { Backend: 2 } },\n            c: { text: 'La precisión y utilidad de los insights de datos.', points: { Data: 2 } },\n            d: { text: 'La experiencia y estética del usuario.', points: { Frontend: 2 } },\n        },\n    },\n    {\n        question: '10- ¿En qué área te gustaría especializarte más?',\n        options: {\n            a: { text: 'Desarrollo de aplicaciones móviles innovadoras.', points: { Mobile: 2 } },\n            b: { text: 'Ciencia de datos y aprendizaje automático.', points: { Data: 2 } },\n            c: { text: 'Desarrollo de interfaces de usuario y experiencia.', points: { Frontend: 2 } },\n            d: { text: 'Arquitectura de software y servicios web.', points: { Backend: 2 } },\n        },\n    },\n];\n\n\nlet currentQuestion = 0;\nlet studentName = '';\n\n// Función para hacer preguntas\nfunction askQuestion() {\n    if (currentQuestion < questions.length) {\n        const q = questions[currentQuestion];\n        console.log(`\\n${q.question}`);\n        console.log(`a) ${q.options.a.text}`);\n        console.log(`b) ${q.options.b.text}`);\n        console.log(`c) ${q.options.c.text}`);\n        console.log(`d) ${q.options.d.text}`);\n\n        rl.question('Selección una opción (a, b, c, d): ', (answer) => {\n            const option = q.options[answer.toLowerCase()];\n\n            if (option) {\n                Object.keys(option.points).forEach((houseName) => {\n                    house[houseName] += option.points[houseName];\n                });\n                \n                currentQuestion++;\n                askQuestion();\n            } else {\n                console.log('Opción no válida. Intenta de nuevo.');\n                askQuestion();\n            }\n        });\n    } else {\n        sortStudent();\n    }\n}\n\n// Función para determinar la casa del estudiante\nfunction sortStudent() {\n    const sortedHouses  = Object.entries(house).sort(([, a], [, b]) => b - a);\n    const topHouse = sortedHouses[0];\n    const tiedHouse = sortedHouses.filter(([, points]) => points === topHouse[1]);\n\n    if (tiedHouse.length > 1) {\n        const chosenHouse = tiedHouse[Math.floor(Math.random() * tiedHouse.length)];\n        console.log(`\\n¡Vaya, ${studentName}! Fue una decisión complicada, pero te he colocado en ${chosenHouse[0]}!`);\n    } else {\n        console.log(`\\n${studentName}, te he colocado en ${topHouse[0]}!`);\n    }\n\n    rl.close();\n}\n\n// Inicio del programa\nconsole.log(\"\\n¡Bienvenido a Hogwarts, la escuela de programación para magos y brujas del código!\")\nconsole.log(\"El sombrero seleccionador decidirá cuál es tu casa como programador.\")\nrl.question('\\n¿Cuál es tu nombre? ', (name) => {\n    studentName = name;\n    askQuestion(); \n});"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/javascript/Rafacv23.js",
    "content": "const readline = require(\"readline\")\n\nconst preguntas = [\n  {\n    pregunta: \"¿Qué parte de un proyecto disfrutas más?\",\n    opciones: [\n      {\n        respuesta: \"Crear interfaces interactivas y atractivas\",\n        casa: \"Frontend\",\n      },\n      {\n        respuesta: \"Diseñar la estructura de datos y las bases de datos\",\n        casa: \"Backend\",\n      },\n      {\n        respuesta: \"Desarrollar aplicaciones móviles\",\n        casa: \"Mobile\",\n      },\n      {\n        respuesta: \"Implementar sistemas de seguridad y control de acceso\",\n        casa: \"Data\",\n      },\n    ],\n  },\n  {\n    pregunta: \"¿Cuál es tu lenguaje de programación favorito?\",\n    opciones: [\n      {\n        respuesta: \"JavaScript\",\n        casa: \"Frontend\",\n      },\n      {\n        respuesta: \"Python\",\n        casa: \"Backend\",\n      },\n      {\n        respuesta: \"Swift\",\n        casa: \"Mobile\",\n      },\n      {\n        respuesta: \"R\",\n        casa: \"Data\",\n      },\n    ],\n  },\n  {\n    pregunta: \"¿Qué herramienta te resulta más útil en tu trabajo diario?\",\n    opciones: [\n      {\n        respuesta: \"Visual Studio Code\",\n        casa: \"Frontend\",\n      },\n      {\n        respuesta: \"Git y GitHub\",\n        casa: \"Backend\",\n      },\n      {\n        respuesta: \"Docker y Kubernetes\",\n        casa: \"Mobile\",\n      },\n      {\n        respuesta: \"Jupyter Notebooks\",\n        casa: \"Data\",\n      },\n    ],\n  },\n  {\n    pregunta: \"¿Cómo prefieres gestionar tus proyectos?\",\n    opciones: [\n      {\n        respuesta: \"Utilizando versiones de control\",\n        casa: \"Frontend\",\n      },\n      {\n        respuesta: \"Utilizando un herramienta de planeamiento\",\n        casa: \"Backend\",\n      },\n      {\n        respuesta: \"Utilizando un herramienta de gestión de proyectos\",\n        casa: \"Mobile\",\n      },\n      {\n        respuesta: \"Utilizando un herramienta de planificación\",\n        casa: \"Data\",\n      },\n    ],\n  },\n  {\n    pregunta: \"¿Qué parte de la depuración de código disfrutas más?\",\n    opciones: [\n      {\n        respuesta: \"Encontrar errores visuales en las interfaces\",\n        casa: \"Frontend\",\n      },\n      {\n        respuesta: \"Corregir problemas de rendimiento en el servidor\",\n        casa: \"Backend\",\n      },\n      {\n        respuesta: \"Desarrollar nuevas características y funciones\",\n        casa: \"Mobile\",\n      },\n      {\n        respuesta: \"Optimizar algoritmos de procesamiento de datos\",\n        casa: \"Data\",\n      },\n    ],\n  },\n  {\n    pregunta: \"¿Cuál sería tu rol ideal en un equipo de desarrollo?\",\n    opciones: [\n      {\n        respuesta: \"Desarrollador/Diseñador Frontend\",\n        casa: \"Frontend\",\n      },\n      {\n        respuesta: \"Arquitecto de Soluciones Backend\",\n        casa: \"Backend\",\n      },\n      {\n        respuesta: \"Desarrollador de Aplicaciones Móviles\",\n        casa: \"Mobile\",\n      },\n      {\n        respuesta: \"Científico de Datos\",\n        casa: \"Data\",\n      },\n    ],\n  },\n  {\n    pregunta: \"¿Cómo prefieres aprender nuevas tecnologías?\",\n    opciones: [\n      {\n        respuesta:\n          \"Experimentando con nuevas librerías y frameworks de frontend\",\n        casa: \"Frontend\",\n      },\n      {\n        respuesta:\n          \"Trabajando con nuevas tecnologías de servidores y bases de datos\",\n        casa: \"Backend\",\n      },\n      {\n        respuesta: \"Explorando nuevas plataformas de desarrollo móvil\",\n        casa: \"Mobile\",\n      },\n      {\n        respuesta:\n          \"Analizando nuevos algoritmos y técnicas de procesamiento de datos\",\n        casa: \"Data\",\n      },\n    ],\n  },\n  {\n    pregunta: \"¿Qué tipo de proyectos te motivan más?\",\n    opciones: [\n      {\n        respuesta: \"Crear interfaces web interactivas y atractivas\",\n        casa: \"Frontend\",\n      },\n      {\n        respuesta: \"Desarrollar sistemas robustos y escalables en la nube\",\n        casa: \"Backend\",\n      },\n      {\n        respuesta:\n          \"Desarrollar aplicaciones móviles con excelente experiencia de usuario\",\n        casa: \"Mobile\",\n      },\n      {\n        respuesta: \"Proyectos de análisis y visualización de datos\",\n        casa: \"Data\",\n      },\n    ],\n  },\n  {\n    pregunta: \"¿Qué tecnología te gustaría dominar en el futuro?\",\n    opciones: [\n      {\n        respuesta: \"WebAssembly y animaciones avanzadas en la web\",\n        casa: \"Frontend\",\n      },\n      {\n        respuesta: \"Inteligencia Artificial y Machine Learning en servidores\",\n        casa: \"Backend\",\n      },\n      {\n        respuesta: \"Realidad aumentada en aplicaciones móviles\",\n        casa: \"Mobile\",\n      },\n      {\n        respuesta: \"Big Data y análisis de grandes volúmenes de información\",\n        casa: \"Data\",\n      },\n    ],\n  },\n  {\n    pregunta: \"¿Cómo te gusta colaborar en un equipo?\",\n    opciones: [\n      {\n        respuesta: \"Diseñando y mejorando la experiencia de usuario\",\n        casa: \"Frontend\",\n      },\n      {\n        respuesta: \"Integrando servicios y APIs en el backend\",\n        casa: \"Backend\",\n      },\n      {\n        respuesta: \"Asegurando la mejor experiencia en aplicaciones móviles\",\n        casa: \"Mobile\",\n      },\n      {\n        respuesta: \"Proporcionando análisis detallados a partir de los datos\",\n        casa: \"Data\",\n      },\n    ],\n  },\n]\n\nconst puntosCasas = {\n  Frontend: 0,\n  Backend: 0,\n  Mobile: 0,\n  Data: 0,\n}\n\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout,\n})\nconst prompt = (query) => new Promise((resolve) => rl.question(query, resolve))\n\n;(async () => {\n  try {\n    console.log(\n      \"Bienvenido a Hogwarts, la escuela de Programación para magos y brujas del código.\"\n    )\n\n    for (let i = 0; i < preguntas.length; i++) {\n      const pregunta = preguntas[i]\n\n      console.log(`\\n${pregunta.pregunta}`)\n      pregunta.opciones.forEach((opcion, index) => {\n        console.log(`${index + 1}) ${opcion.respuesta}`)\n      })\n\n      let respuesta = await prompt(\"Selecciona una opción (1-4): \")\n      respuesta = parseInt(respuesta) - 1\n\n      // Validar que la respuesta esté en el rango adecuado\n      if (respuesta >= 0 && respuesta < pregunta.opciones.length) {\n        const casaSeleccionada = pregunta.opciones[respuesta].casa\n        puntosCasas[casaSeleccionada]++\n      } else {\n        console.log(\n          \"Opción inválida, por favor selecciona un número entre 1 y 4.\"\n        )\n        i-- // Volver a preguntar si la opción es inválida\n      }\n    }\n\n    // Encontrar el puntaje más alto\n    const maxPuntos = Math.max(...Object.values(puntosCasas))\n\n    // Encontrar todas las casas que tienen el puntaje más alto\n    const casasEmpatadas = Object.keys(puntosCasas).filter(\n      (casa) => puntosCasas[casa] === maxPuntos\n    )\n\n    let casaGanadora\n\n    if (casasEmpatadas.length > 1) {\n      // Si hay empate, selecciona una casa al azar\n      console.log(\"\\nEl sombrero ha tenido dificultades para decidir...\")\n      const indiceAleatorio = Math.floor(Math.random() * casasEmpatadas.length)\n      casaGanadora = casasEmpatadas[indiceAleatorio]\n    } else {\n      // Si no hay empate, simplemente selecciona la casa ganadora\n      casaGanadora = casasEmpatadas[0]\n    }\n\n    console.log(`\\n¡Felicidades! Perteneces a la casa ${casaGanadora}.`)\n    rl.close()\n  } catch (e) {\n    console.error(\"Error en la selección\", e)\n  }\n})()\n\n// When done reading prompt, exit program\nrl.on(\"close\", () => process.exit(0))\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/javascript/RaulDoezon.js",
    "content": "/*\n  EJERCICIO:\n  Cada 1 de septiembre, el Hogwarts Express parte hacia la escuela\n  de programación de Hogwarts para magos y brujas del código.\n  En ella, su famoso sombrero seleccionador ayuda a los programadores\n  a encontrar su camino...\n  Desarrolla un programa que simule el comportamiento del sombrero.\n  Requisitos:\n  1. El sombrero realizará 10 preguntas para determinar la casa del alumno.\n  2. Deben existir 4 casas. Por ejemplo: Frontend, Backend, Mobile y Data.\n     (Puedes elegir las que quieras)\n  Acciones:\n  1. Crea un programa que solicite el nombre del alumno y realice 10\n     preguntas, con cuatro posibles respuestas cada una.\n  2. Cada respuesta asigna puntos a cada una de las casas (a tu elección).\n  3. Una vez finalizado, el sombrero indica el nombre del alumno \n     y a qué casa pertenecerá (resuelve el posible empate de manera aleatoria,\n     pero indicándole al alumno que la decisión ha sido complicada).\n*/\n\nlet userName = \"\";\nlet frontEndHouse = 0;\nlet backEndHouse = 0;\nlet mobileHouse = 0;\nlet dataScienceHouse = 0;\nconst questions = [\n  \"1. ¿Qué prefieres jugar?: \\na) Super Metroid \\nb) Ajedrez \\nc) Pokémon Go \\nd) Sudoku\",\n  \"2. ¿Con qué actividad te identificas más?: \\na) Dibujar \\nb) Doblar la ropa \\nc) Editar fotos en el teléfono \\nd) Acomodar la despensa\",\n  \"3. ¿Dónde te gusta más escuchar música?: \\na) Audífonos  \\nb) Mini componente \\nc) Bocina portatil \\nd) Donde sea pero Hi-Res\",\n  \"4. ¿Qué superhéroe es tu favorito?: \\na) Spider-Man \\nb) Superman \\nc) Flash \\nd) Doctor Strange\",\n  \"5. Si volvieras a cursar una materia, ¿cuál sería?: \\na) Biología \\nb) Cálculo diferencial e integral \\nc) Física \\nd) Probabilidad y estadística\",\n  \"6. Si te regalaran un dispositivo electrónico, ¿cuál elegirías?: \\na) MacBook \\nb) PC \\nc) Smartphone \\nd) Raspberry Pi\",\n  \"7. ¿Qué recurso utilizarías para administrar tus finanzas?: \\na) Aplicación de escritorio \\nb) Papel y lápiz \\nc) Aplicación móvil \\nd) Hoja de cálculo\",\n  \"8. ¿Qué te llama más la atención en un sitio web?: \\na) La apariencia \\nb) Las validaciones en un formulario \\nc) La adaptación a medidas pequeñas \\nd) La información que muestra\",\n  \"9. ¿Qué lenguaje de programación es tu favorito?: \\na) JavaScript \\nb) Python \\nc) Swift \\nd) SQL\",\n  \"10. ¿Con qué persona te sientes más identificado?: \\na) Miguel Durán \\nb) Héctor de León \\nc) Brais Moure \\nd) Rafa Gonzalez Gouveia\",\n];\n\nuserName = prompt(\"Por favor, ingresa tu nombre:\");\n\nfor (let index = 0; index < questions.length; index++) {\n  let quiz = prompt(questions[index]);\n\n  switch (quiz.toLowerCase()) {\n    case \"a\":\n      frontEndHouse += 4;\n      break;\n\n    case \"b\":\n      backEndHouse += 4;\n      break;\n\n    case \"c\":\n      mobileHouse += 4;\n      break;\n\n    case \"d\":\n      dataScienceHouse += 4;\n      break;\n\n    default:\n      alert(\"Por favor, selecciona una opción válida.\");\n\n      index--;\n      break;\n  }\n}\n\nlet allHouses = {\n  \"Front-end\": frontEndHouse,\n  \"Back-end\": backEndHouse,\n  \"Mobile\": mobileHouse,\n  \"Data Science\": dataScienceHouse,\n};\nlet houseNames = Object.keys(allHouses);\nlet higherScore = Math.max.apply(null, houseNames.map((houseScore) => allHouses[houseScore]));\nlet chosenHouse = houseNames.reduce((house, score) => {\n  if (allHouses[score] === higherScore) {\n    house.push(score);\n  }\n\n  return house;\n}, []);\nlet randomSelection = Math.round(Math.random() * (chosenHouse.length - 1) + 1) - 1;\n\nif (chosenHouse.length > 1) {\n  console.log(`${userName}, la decisión ha sido complicada, pero pertenecerás a la casa de ${chosenHouse[randomSelection]}.`);\n} else {\n  console.log(`${userName}, pertenecerás a la casa de ${chosenHouse[0]}.`);\n}\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/javascript/RicJDev.js",
    "content": "/*\n  EJERCICIO:\n\n  @RicJDev\n*/\n\n// Primero modelamos las preguntas y el cuestionario\n\nclass Question {\n  constructor(title) {\n    this.title = title\n    this.options = { A: null, B: null, C: null, D: null }\n  }\n\n  addOption(letter, option) {\n    if (Object.keys(this.options).includes(letter.toUpperCase())) {\n      if (this.options[letter] === option) {\n        throw new Error('You cannot repeat options.')\n      }\n\n      this.options[letter] = option\n    } else {\n      throw new Error(`Options avalaible: A, B, C or D. Cannot set '${letter}' option.`)\n    }\n  }\n}\n\nclass Questionary {\n  constructor() {\n    this.questions = {}\n  }\n\n  addQuestion(id, title) {\n    this.questions[id] = new Question(title)\n  }\n\n  addOption(id, letter, option) {\n    if (this.questions[id]) {\n      const question = this.questions[id]\n\n      question.addOption(letter, option)\n    }\n  }\n}\n\n// Creamos el cuestionario\n\nconst questionary = new Questionary()\n\nquestionary.addQuestion(1, '¿Qué parte de un sitio web te llama más la atención?')\nquestionary.addQuestion(\n  2,\n  'Si tuvieras que elegir entre crear una nueva aplicación móvil o diseñar una base de datos, ¿cuál preferirías?'\n)\nquestionary.addQuestion(3, '¿Qué te resulta más fácil de entender?')\nquestionary.addQuestion(4, '¿Qué tipo de problemas te gusta resolver?')\nquestionary.addQuestion(5, '¿Qué herramienta te resulta más interesante?')\nquestionary.addQuestion(6, '¿Qué te gustaría hacer en tu tiempo libre?')\nquestionary.addQuestion(7, '¿Qué tipo de proyectos te motivan más?')\nquestionary.addQuestion(8, '¿Qué habilidad consideras más importante para un desarrollador?')\nquestionary.addQuestion(9, '¿Qué tipo de equipo te gustaría formar parte?')\nquestionary.addQuestion(10, '¿Qué te gustaría lograr a largo plazo en tu carrera?')\n\n// Almacenamos las respuestas separadas por \"casas\" y las asignamos según las opciones\n\nconst houses = {\n  frontend: {\n    1: 'El diseño visual y la interfaz de usuario.',\n    2: 'Crear una aplicación móvil con una interfaz intuitiva.',\n    3: 'Diagramas de flujo y diseños visuales.',\n    4: 'Problemas relacionados con la estética y la experiencia del usuario.',\n    5: 'Photoshop o Figma.',\n    6: 'Diseñar interfaces de usuario para diferentes aplicaciones.',\n    7: 'Proyectos que tienen un impacto visual y estético.',\n    8: 'La creatividad y el sentido del diseño.',\n    9: 'Un equipo de diseño y UX.',\n    10: 'Crear productos digitales con una interfaz de usuario excepcional.',\n  },\n\n  backend: {\n    1: 'La lógica detrás de cómo funciona el sitio y cómo se conectan las diferentes partes.',\n    2: 'Diseñar una base de datos eficiente para almacenar grandes cantidades de información.',\n    3: 'Código y algoritmos.',\n    4: 'Problemas lógicos y de optimización.',\n    5: 'Python o Java.',\n    6: 'Desarrollar videojuegos o aplicaciones web.',\n    7: 'Proyectos que requieren resolver problemas complejos y optimizar el rendimiento.',\n    8: 'La capacidad de resolver problemas y pensar de forma lógica.',\n    9: 'Un equipo de desarrollo backend.',\n    10: 'Desarrollar aplicaciones escalables y eficientes.',\n  },\n\n  mobile: {\n    1: 'Cómo se ve y funciona la aplicación en un teléfono móvil.',\n    2: 'Ambas opciones me parecen igualmente interesantes.',\n    3: 'Prototipos y maquetas.',\n    4: 'Problemas relacionados con la portabilidad y la compatibilidad en diferentes dispositivos.',\n    5: 'XCode o Android Studio.',\n    6: 'Crear aplicaciones móviles para diferentes plataformas.',\n    7: 'Proyectos que pueden ser utilizados por muchas personas en sus dispositivos móviles.',\n    8: 'La adaptabilidad y la capacidad de aprender nuevas tecnologías.',\n    9: 'Un equipo de desarrollo móvil.',\n    10: 'Crear aplicaciones móviles que cambien la forma en que las personas interactúan con el mundo.',\n  },\n\n  data: {\n    1: 'Los datos que se recolectan y cómo se utilizan para mejorar el sitio.',\n    2: 'Ninguna de las opciones me llama la atención.',\n    3: 'Gráficos y estadísticas.',\n    4: 'Problemas relacionados con la extracción de información útil de grandes conjuntos de datos.',\n    5: 'SQL o Tableau.',\n    6: 'Analizar datos y crear visualizaciones.',\n    7: 'Proyectos que utilizan datos para tomar decisiones informadas.',\n    8: 'La capacidad de analizar datos y extraer insights.',\n    9: 'Un equipo de ciencia de datos.',\n    10: 'Utilizar datos para resolver problemas del mundo real y tomar decisiones estratégicas.',\n  },\n}\n\nfor (const id in questionary.questions) {\n  questionary.addOption(id, 'A', houses.frontend[id])\n  questionary.addOption(id, 'B', houses.backend[id])\n  questionary.addOption(id, 'C', houses.mobile[id])\n  questionary.addOption(id, 'D', houses.data[id])\n}\n\n/*\n  * Creamos la \"app\" en la terminal *\n\n- Se ejecuta en Node.js, importando el módulo Readline/promises para tener input por terminal (https://nodejs.org/api/readline.html)\n- Se ha instalado Picocolors, un librería para colorear texto en la terminal (https://www.npmjs.com/package/picocolors)\n\n*/\n\nimport * as readline from 'readline/promises'\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout,\n})\n\nimport pc from 'picocolors'\n\n// * Aquí empieza la magia *\n\nconst results = { A: 0, B: 0, C: 0, D: 0 }\n\nconsole.clear()\nconst name = await rl.question('\\nDime tu nombre, querido alumno. ')\n\nfor (const id in questionary.questions) {\n  const question = questionary.questions[id]\n\n  let message = '¡Descubre a cuál casa perteneces!'\n  let answer = ''\n\n  while (!Object.keys(question.options).includes(answer.toUpperCase())) {\n    console.clear()\n    console.log(`\\nBienvenido seas, ${pc.bold(name)}. ${message}`)\n\n    console.log(`\\n${pc.blue(id)}. ${question.title}\\n`)\n\n    for (const letter in question.options) {\n      console.log(` - ${pc.green(letter)}. ${question.options[letter] || 'Opción vacía.'}`)\n    }\n\n    answer = await rl.question('\\nIndica la opción de tu preferencia. ')\n\n    message = pc.yellow('Elije una opción válida, por favor.')\n  }\n\n  results[answer.toUpperCase()]++\n}\n\nrl.close()\n\n// Mostramos los resultados del cuestionario y finaliza el programa\n\nlet winner = Object.keys(results).reduce((previous, current) => {\n  if (results[current] > results[previous]) {\n    previous = current\n  }\n\n  return previous\n})\n\nconst tieValues = Object.keys(results).filter((same) => results[winner] === results[same])\n\nif (tieValues.length > 1) winner = tieValues[Math.floor(Math.random() * tieValues.length)]\n\nconsole.clear()\nconsole.log(\n  `\\nQuerido ${pc.bold(name)}, ¡el cuestionario ha terminado!\\nEstos son los resultados:\\n`\n)\n\nconst messages = {\n  A: `Tu casa será el desarrollo ${pc.blue('Frontend')}.`,\n  B: `Tu casa será el desarrollo ${pc.blue('Backend')}.`,\n  C: `Tu casa será el desarrollo ${pc.blue('Mobile')}.`,\n  D: `Tu casa será el análisis de ${pc.blue('Data')}.`,\n}\n\nconst resultMessage = messages[winner] || pc.red('Ha ocurrido algún error inesperado.')\n\nconsole.log(resultMessage)\n\nif (tieValues.length > 1) {\n  console.log('\\nFue una decisión difícil debido a que hubo empate en algunas preguntas.')\n}\n\nconsole.log(' ')\nconsole.log(`Total de respuestas ${pc.green('A')}: ${pc.yellow(results.A)}.`)\nconsole.log(`Total de respuestas ${pc.green('B')}: ${pc.yellow(results.B)}.`)\nconsole.log(`Total de respuestas ${pc.green('C')}: ${pc.yellow(results.C)}.`)\nconsole.log(`Total de respuestas ${pc.green('D')}: ${pc.yellow(results.D)}.`)\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/javascript/adrs1166ma.js",
    "content": "/*\nEJERCICIO:\nCada 1 de septiembre, el Hogwarts Express parte hacia la escuela\nde programación de Hogwarts para magos y brujas del código.\nEn ella, su famoso sombrero seleccionador ayuda a los programadores\na encontrar su camino...\nDesarrolla un programa que simule el comportamiento del sombrero.\nRequisitos:\n1. El sombrero realizará 10 preguntas para determinar la casa del alumno.\n2. Deben existir 4 casas. Por ejemplo: Frontend, Backend, Mobile y Data.\n   (Puedes elegir las que quieras)\nAcciones:\n1. Crea un programa que solicite el nombre del alumno y realice 10\n   preguntas, con cuatro posibles respuestas cada una.\n2. Cada respuesta asigna puntos a cada una de las casas (a tu elección).\n3. Una vez finalizado, el sombrero indica el nombre del alumno \n   y a qué casa pertenecerá (resuelve el posible empate de manera aleatoria,\n   pero indicándole al alumno que la decisión ha sido complicada).\n */\n//  🔥 SIMULADOR: Sombrero Seleccionador de Hogwarts para Programadores 🔥\n\nconsole.log(\"🎩 ¡Bienvenido al Sombrero Seleccionador de Hogwarts para Programadores! 🎩\");\n\n// Función principal del programa\nfunction iniciarSombreroSeleccionador() {\n    console.log(\"\\n--- INICIO DEL SELECCIONAMIENTO ---\");\n    const nombre = prompt(\"Ingrese el nombre del alumno: \");\n    if (!nombre) {\n        console.log(\"❌ El nombre del alumno es obligatorio.\");\n        return;\n    }\n\n    // Preguntas y asignación de puntos\n    const preguntas = [\n        \"1. ¿Qué prefieres hacer en tu tiempo libre?\\n   a) Crear interfaces bonitas\\n   b) Optimizar bases de datos\\n   c) Desarrollar apps móviles\\n   d) Analizar grandes volúmenes de datos\",\n        \"2. ¿Qué herramienta usas más a menudo?\\n   a) HTML/CSS\\n   b) SQL\\n   c) Flutter\\n   d) Python\",\n        \"3. ¿Qué tipo de proyecto te emociona más?\\n   a) Un sitio web interactivo\\n   b) Una API RESTful\\n   c) Una app móvil\\n   d) Un modelo de machine learning\",\n        \"4. ¿Qué prefieres aprender?\\n   a) Animaciones CSS\\n   b) Arquitectura de microservicios\\n   c) Kotlin\\n   d) TensorFlow\",\n        \"5. ¿Qué lenguaje prefieres?\\n   a) JavaScript\\n   b) Java\\n   c) Swift\\n   d) R\",\n        \"6. ¿Qué problema disfrutas resolviendo?\\n   a) Diseño visual\\n   b) Escalabilidad\\n   c) Interfaz móvil nativa\\n   d) Predicción de datos\",\n        \"7. ¿Qué te motiva más?\\n   a) Hacer que las cosas se vean bien\\n   b) Hacer que las cosas funcionen bien\\n   c) Hacer que las cosas estén disponibles en todas partes\\n   d) Hacer que las cosas sean inteligentes\",\n        \"8. ¿Qué prefieres depurar?\\n   a) Estilos visuales\\n   b) Lógica del servidor\\n   c) Compatibilidad de dispositivos\\n   d) Errores en pipelines de datos\",\n        \"9. ¿Qué prefieres diseñar?\\n   a) Layouts responsivos\\n   b) Esquemas de bases de datos\\n   c) Interfaces móviles\\n   d) Diagramas de flujo de datos\",\n        \"10. ¿Qué prefieres optimizar?\\n    a) Velocidad de carga\\n    b) Consultas SQL\\n    c) Uso de memoria en dispositivos móviles\\n    d) Precisión de modelos\"\n    ];\n\n    const casas = { Frontend: 0, Backend: 0, Mobile: 0, Data: 0 };\n\n    // Realizar las preguntas\n    for (const pregunta of preguntas) {\n        console.log(pregunta);\n        const respuesta = prompt(\"Seleccione una opción (a/b/c/d): \").toLowerCase();\n\n        switch (respuesta) {\n            case \"a\":\n                casas.Frontend += 1;\n                break;\n            case \"b\":\n                casas.Backend += 1;\n                break;\n            case \"c\":\n                casas.Mobile += 1;\n                break;\n            case \"d\":\n                casas.Data += 1;\n                break;\n            default:\n                console.log(\"⚠️ Respuesta no válida. No se asignaron puntos.\");\n        }\n    }\n\n    // Determinar la casa ganadora\n    const puntuaciones = Object.entries(casas);\n    const maxPuntos = Math.max(...puntuaciones.map(([_, puntos]) => puntos));\n    const casasGanadoras = puntuaciones.filter(([_, puntos]) => puntos === maxPuntos).map(([casa]) => casa);\n\n    let casaFinal;\n    if (casasGanadoras.length > 1) {\n        console.log(`\\n🤔 Decisión complicada... ${nombre}, has obtenido un empate entre: ${casasGanadoras.join(\", \")}.`);\n        casaFinal = casasGanadoras[Math.floor(Math.random() * casasGanadoras.length)];\n        console.log(`🎩 Después de mucho pensar, el sombrero ha decidido: ¡${casaFinal} será tu casa!`);\n    } else {\n        casaFinal = casasGanadoras[0];\n        console.log(`\\n🎉 ¡Felicidades, ${nombre}! El sombrero ha decidido que perteneces a la casa de ${casaFinal}.`);\n    }\n\n    // Mostrar puntuaciones finales\n    console.log(\"\\n--- PUNTUACIONES FINALES ---\");\n    for (const [casa, puntos] of puntuaciones) {\n        console.log(`${casa}: ${puntos} puntos`);\n    }\n}\n\niniciarSombreroSeleccionador();"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/javascript/duendeintemporal.js",
    "content": "//#36 - EL SOMBRERO SELECCIONADOR \n/*\n * EJERCICIO:\n * Cada 1 de septiembre, el Hogwarts Express parte hacia la escuela\n * de programación de Hogwarts para magos y brujas del código.\n * En ella, su famoso sombrero seleccionador ayuda a los programadores\n * a encontrar su camino...\n * Desarrolla un programa que simule el comportamiento del sombrero.\n * Requisitos:\n * 1. El sombrero realizará 10 preguntas para determinar la casa del alumno.\n * 2. Deben existir 4 casas. Por ejemplo: Frontend, Backend, Mobile y Data.\n *    (Puedes elegir las que quieras)\n * Acciones:\n * 1. Crea un programa que solicite el nombre del alumno y realice 10\n *    preguntas, con cuatro posibles respuestas cada una.\n * 2. Cada respuesta asigna puntos a cada una de las casas (a tu elección).\n * 3. Una vez finalizado, el sombrero indica el nombre del alumno \n *    y a qué casa pertenecerá (resuelve el posible empate de manera aleatoria,\n *    pero indicándole al alumno que la decisión ha sido complicada).\n */\nconst questions = [\n    {\n        \"question\": \"What type of projects are you most interested in developing?\",\n        \"answers\": [\n            {\n                \"option\": \"Native mobile applications for multiple platforms.\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"Visually appealing and responsive interfaces.\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Processing and analyzing large volumes of data.\",\n                \"house\": \"Data Analysis\"\n            },\n            {\n                \"option\": \"Robust systems and server performance optimization.\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"All of the above\",\n                \"house\": \"Fullstack\"\n            }\n        ]\n    },\n    {\n        \"question\": \"What aspect of development do you enjoy the most?\",\n        \"answers\": [\n            {\n                \"option\": \"Creating efficient and functional mobile applications.\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"Working on design and user experience.\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Analyzing data to make data-driven decisions.\",\n                \"house\": \"Data Analysis\"\n            },\n            {\n                \"option\": \"Solving complex logic and scalability problems.\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"All of the above\",\n                \"house\": \"Fullstack\"\n            }\n        ]\n    },\n    {\n        \"question\": \"What tool do you prefer to use in your day-to-day work?\",\n        \"answers\": [\n            {\n                \"option\": \"Kotlin or Swift for developing native mobile apps.\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"Frameworks like React or Angular.\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Python or R for data analysis.\",\n                \"house\": \"Data Analysis\"\n            },\n            {\n                \"option\": \"Languages like Node.js or Python for server management.\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"All of the above\",\n                \"house\": \"Fullstack\"\n            }\n        ]\n    },\n    {\n        \"question\": \"How do you see yourself in a development team?\",\n        \"answers\": [\n            {\n                \"option\": \"Developing the interface and functionality of a mobile app.\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"Designing interactions and visual components.\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Modeling data and building analysis dashboards.\",\n                \"house\": \"Data Analysis\"\n            },\n            {\n                \"option\": \"Responsible for server logic and APIs.\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"All of the above\",\n                \"house\": \"Fullstack\"\n            }\n        ]\n    },\n    {\n        \"question\": \"What motivates you the most when working on a project?\",\n        \"answers\": [\n            {\n                \"option\": \"Ensuring that a mobile application works perfectly on any device.\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"Seeing the design come to life on the screen.\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Discovering insights from data analysis.\",\n                \"house\": \"Data Analysis\"\n            },\n            {\n                \"option\": \"Optimizing system performance and scalability.\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"All of the above\",\n                \"house\": \"Fullstack\"\n            }\n        ]\n    },\n    {\n        \"question\": \"What is your approach to learning new technologies?\",\n        \"answers\": [\n            {\n                \"option\": \"Trying out new platforms and tools for mobile development.\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"Experimenting with new libraries and frameworks for user interfaces.\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Exploring advanced data analysis and machine learning techniques.\",\n                \"house\": \"Data Analysis\"\n            },\n            {\n                \"option\": \"Learning about new architectures and server languages.\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"All of the above\",\n                \"house\": \"Fullstack\"\n            }\n        ]\n    },\n    {\n        \"question\": \"What type of challenges do you enjoy solving the most?\",\n        \"answers\": [\n            {\n                \"option\": \"Creating smooth user experiences on mobile devices.\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"Optimizing interfaces to look good on any device.\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Analyzing large volumes of data to detect hidden patterns.\",\n                \"house\": \"Data Analysis\"\n            },\n            {\n                \"option\": \"Solving concurrency and load issues on servers.\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"All of the above\",\n                \"house\": \"Fullstack\"\n            }\n        ]\n    },\n    {\n        \"question\": \"How do you like to measure the success of your work?\",\n        \"answers\": [\n            {\n                \"option\": \"By the smoothness and performance of the mobile app on different devices.\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"By user satisfaction with the visual interface.\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"By the accuracy and relevance of the results obtained from data analysis.\",\n                \"house\": \"Data Analysis\"\n            },\n            {\n                \"option\": \"By the stability and speed of the system under load.\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"All of the above\",\n                \"house\": \"Fullstack\"\n            }\n        ]\n    },\n    {\n        \"question\": \"What do you find most interesting when working with emerging technologies?\",\n        \"answers\": [\n            {\n                \"option\": \"Developing mobile apps that leverage new hardware capabilities.\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"Trying out new tools and methodologies to improve design and UX.\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Working with big data or artificial intelligence technologies.\",\n                \"house\": \"Data Analysis\"\n            },\n            {\n                \"option\": \"Exploring new architectures to improve server performance.\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"All of the above\",\n                \"house\": \"Fullstack\"\n            }\n        ]\n    },\n    {\n        \"question\": \"How do you approach a new problem in a project?\",\n        \"answers\": [\n            {\n                \"option\": \"Exploring how to improve the user experience on mobile devices.\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"Reassessing the visual and functional structure of the interface.\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Looking for patterns and solutions based on data analysis.\",\n                \"house\": \"Data Analysis\"\n            },\n            {\n                \"option\": \"Analyzing the data structure and backend logic.\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"All of the above\",\n                \"house\": \"Fullstack\"\n            }\n        ]\n    }\n];\n\nconst log = console.log;\n\nconst readline = require('readline');\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout,\n});\n\nconst start = (questions) => {\n    log('\\n');\n    log('Welcome to the best roadmap for developers you have ever seen!');\n    log('\\n');\n    log('Every September 1st, the Hogwarts Express departs for the Hogwarts School of Code for wizards and witches of programming.');\n    log('\\n');\n    log('There, the famous Sorting Hat helps programmers find their path...');\n    log('\\n');\n    log(\"Let's get started! Happy coding!\");\n    log('\\n');\n\n    let answers = [];\n    let count = 0;\n    let question = questions;\n\n    const showResult = (answer) => {\n        let result = [];\n        let total, max = []; \n        let areas = ['Mobile', 'Frontend', 'Data Analysis', 'Backend', 'Fullstack'];\n\n        for (let i = 1; i <= 5; i++) {\n            total = answer.filter(num => num == i).length;\n            result.push(total);\n        }\n\n        // Find the maximum value(s)\n        result.forEach((ans, index) => {\n            if (ans === Math.max(...result)) {\n                max.push(index);\n            }\n        });\n\n        log('You seem to be oriented to the next area/areas:');\n        max.forEach((r) => log(`${areas[r]}`));\n    };\n\n    const makeQuestion = (count, question) => {\n        log('Options:')\n        question[count].answers.forEach(opt => {\n            log(`${opt.option}`);\n        });\n        log('Question:')\n        rl.question(`${question[count].question}. Please choose a # from 1 to 5 according to the option: `, (input) => {\n            log('\\n');\n            let result = parseInt(input);\n            if (result >= 1 && result <= 5) {\n                answers.push(result);\n                count++;\n                if (count <= question.length - 1) {\n                    makeQuestion(count, question);\n                } else {\n                    showResult(answers);\n                    rl.close();\n                }\n            } else {\n                log('Invalid input. You must select a # between 1 and 5. Please try again.');\n                makeQuestion(count, question); // Repeat the last question\n            }\n        });\n    };\n\n    makeQuestion(count, question);\n};\n\nstart(questions);\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/javascript/hectorio23.js",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\nconst readline = require('readline-sync');\n// npm install readline-sync\n\n// Casas\nconst houses = [\"Frontend\", \"Backend\", \"Mobile\", \"Data\"];\n\n// Preguntas y asignación de puntos\nconst questions = [\n    { question: \"¿Prefieres trabajar en interfaces visuales?\", scores: [3, 1, 2, 0] },\n    { question: \"¿Te gusta optimizar el rendimiento del servidor?\", scores: [0, 3, 1, 1] },\n    { question: \"¿Te interesa crear aplicaciones móviles?\", scores: [1, 0, 3, 1] },\n    { question: \"¿Te apasiona analizar grandes conjuntos de datos?\", scores: [0, 1, 0, 3] },\n    // 6 preguntas más...\n];\n\nfunction askQuestions() {\n    let scores = [0, 0, 0, 0];  // Puntos de cada casa\n    for (const q of questions) {\n        console.log(q.question);\n        const answer = readline.questionInt(\"Responde 1, 2, 3 o 4: \") - 1;\n        scores = scores.map((score, i) => score + q.scores[answer]);\n    }\n    return scores;\n}\n\nfunction sortingHat() {\n    const name = readline.question(\"¿Cuál es tu nombre? \");\n    const scores = askQuestions();\n    const maxScore = Math.max(...scores);\n    \n    const candidates = houses.filter((_, i) => scores[i] === maxScore);\n    \n    // Si hay empate, selecciona aleatoriamente\n    if (candidates.length > 1) {\n        console.log(`${name}, la decisión ha sido complicada...`);\n        const assignedHouse = candidates[Math.floor(Math.random() * candidates.length)];\n        console.log(`${name}, has sido asignado a ${assignedHouse}.`);\n    } else {\n        console.log(`${name}, has sido asignado a ${candidates[0]}.`);\n    }\n}\n\n// Ejecutar el sombrero seleccionador\nsortingHat();\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n_______________________________________________________\n# 36 EL SOMBRERO SELECCIONADOR\n-------------------------------------------------------\n* EJERCICIO:\n * Cada 1 de septiembre, el Hogwarts Express parte hacia la escuela\n * de programación de Hogwarts para magos y brujas del código.\n * En ella, su famoso sombrero seleccionador ayuda a los programadores\n * a encontrar su camino...\n * Desarrolla un programa que simule el comportamiento del sombrero.\n * Requisitos:\n * 1. El sombrero realizará 10 preguntas para determinar la casa del alumno.\n * 2. Deben existir 4 casas. Por ejemplo: Frontend, Backend, Mobile y Data.\n *    (Puedes elegir las que quieras)\n * Acciones:\n * 1. Crea un programa que solicite el nombre del alumno y realice 10\n *    preguntas, con cuatro posibles respuestas cada una.\n * 2. Cada respuesta asigna puntos a cada una de las casas (a tu elección).\n * 3. Una vez finalizado, el sombrero indica el nombre del alumno \n *    y a qué casa pertenecerá (resuelve el posible empate de manera aleatoria,\n *    pero indicándole al alumno que la decisión ha sido complicada).\n*/\n// ________________________________________________________\n\nconst readline = require(\"readline\");\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout,\n});\n\nconst getInput = (prompt) => {\n  return new Promise((resolve) => {\n    rl.question(prompt, (input) => {\n      resolve(input.trim());\n    });\n  });\n};\n\nconst HOUSES = [\"Frontend\", \"Backend\", \"Mobile\", \"Data\"];\n\nconst QUESTIONS = [\n  \"¿Qué te atrae más?\",\n  \"¿Qué superhéroe de la programación te gustaría ser?\",\n  \"En un proyecto de software, ¿qué rol te emociona más?\",\n  \"Si tu código fuera una obra de arte, ¿qué estilo tendría?\",\n  \"¿Qué animal de programación serías?\",\n  \"En una hackathon, ¿qué tipo de proyecto propondrías?\",\n  \"Si tu carrera en tech fuera una película, ¿de qué género sería?\",\n  \"¿Qué herramienta de programación no puede faltar en tu caja de herramientas digital?\",\n  \"Si pudieras resolver un gran problema en tech, ¿cuál elegirías?\",\n  \"¿Qué tipo de equipo prefieres?\",\n];\n\nconst ANSWERS = [\n  [\"Crear experiencias visuales.\", \"Solucionar problemas de funcionamiento.\", \"Innovar en dispositivos portátiles.\", \"Descubrir tendencias ocultas.\"],\n  [\"Diseñador de Interfaces, creando experiencias asombrosas\", \"Arquitecto de Sistemas, construyendo estructuras robustas\", \"Mago de Apps, conjurando soluciones móviles\", \"Explorador de Datos, descubriendo tesoros ocultos\"],\n  [\"Director de UX, orquestando la sinfonía visual\", \"Ingeniero de Backend, dominando la lógica del servidor\", \"Desarrollador de Apps, llevando la potencia al bolsillo\", \"Científico de Datos, descifrando los secretos de la información\"],\n  [\"Minimalismo elegante, como una landing page perfecta\", \"Arquitectura compleja, como un sistema distribuido\", \"Diseño adaptativo, fluyendo en diferentes dispositivos\", \"Visualización de datos, pintando historias con números\"],\n  [\"Un camaleón, adaptándome a diferentes frameworks\", \"Un pulpo, manejando múltiples servicios a la vez\", \"Un colibrí, ágil y siempre en movimiento\", \"Una lechuza, analizando datos con sabiduría\"],\n  [\"Una web app que revolucione la experiencia del usuario\", \"Un sistema de IA que optimice procesos backend\", \"Una app móvil que cambie la forma de interactuar con el mundo\", \"Un proyecto de big data que prediga tendencias futuras\"],\n  [\"Comedia romántica con JavaScript y CSS\", \"Thriller de ciencia ficción con microservicios\", \"Aventura de acción en el mundo de las apps\", \"Documental profundo sobre el universo de los datos\"],\n  [\"Un editor de código con plugins para diseño visual\", \"Una robusta suite de testing y depuración\", \"Un emulador multi-dispositivo de última generación\", \"Una plataforma de análisis de datos en tiempo real\"],\n  [\"Hacer que la accesibilidad web sea universal\", \"Crear una arquitectura de software autorreparable\", \"Desarrollar una plataforma de AR/VR para educación móvil\", \"Construir un modelo de IA ético y transparente\"],\n  [\"Creativos enfocados en diseño.\", \"Técnicos que construyen sistemas.\", \"Especialistas en aplicaciones móviles.\", \"Expertos en datos y análisis.\"],\n];\n\nclass SortingHat {\n  constructor(name) {\n    this.name = name;\n    this.scores = HOUSES.reduce((acc, house) => {\n      acc[house] = 0;\n      return acc;\n    }, {});\n  }\n\n  async askQuestion(qNum, question, answers) {\n    console.log(`\\n#${qNum}: ${question}`);\n    answers.forEach((answer, index) => {\n      console.log(`${index + 1}) ${answer}`);\n    });\n\n    while (true) {\n      const input = await getInput(\"Elige tu respuesta (1-4): \");\n      const choice = parseInt(input, 10) - 1;\n\n      if (!isNaN(choice) && choice >= 0 && choice < HOUSES.length) {\n        this.scores[HOUSES[choice]] += 1;\n        break;\n      } else {\n        console.log(\"Por favor, elige un número entre 1 y 4.\");\n      }\n    }\n  }\n\n  selectHouse() {\n    const maxScore = Math.max(...Object.values(this.scores));\n    const topHouses = Object.keys(this.scores).filter(\n      (house) => this.scores[house] === maxScore\n    );\n\n    if (topHouses.length > 1) {\n      console.log(\"\\nLa decisión ha sido complicada.\");\n      return topHouses[Math.floor(Math.random() * topHouses.length)];\n    }\n\n    return topHouses[0];\n  }\n}\n\nconst main = async () => {\n  console.log(\"EL SOMBRERO SELECCIONADOR\");\n  const name = await getInput(\"¿Cuál es tu nombre? : \");\n  const hat = new SortingHat(name);\n\n  for (let i = 0; i < QUESTIONS.length; i++) {\n    await hat.askQuestion(i + 1, QUESTIONS[i], ANSWERS[i]);\n  }\n\n  const selectedHouse = hat.selectHouse();\n  console.log(`\\n'${name}' pertenecerá a la casa '${selectedHouse}'\\n`);\n  rl.close();\n};\n\nmain();\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/javascript/miguelex.js",
    "content": "const readline = require('readline');\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nclass Casa {\n    constructor(nombre) {\n        this.nombre = nombre;\n        this.puntos = 0;\n    }\n\n    getNombre() {\n        return this.nombre;\n    }\n\n    agregarPuntos(puntos) {\n        this.puntos += puntos;\n    }\n\n    getPuntos() {\n        return this.puntos;\n    }\n}\n\nclass Alumno {\n    constructor(nombre) {\n        this.nombre = nombre;\n    }\n\n    getNombre() {\n        return this.nombre;\n    }\n}\n\nclass Pregunta {\n    constructor(pregunta, opciones) {\n        this.pregunta = pregunta;\n        this.opciones = opciones; \n    }\n\n    mostrarPregunta() {\n        console.log(this.pregunta);\n        this.opciones.forEach((opcion, index) => {\n            console.log(`${index + 1}: ${opcion.texto}`);\n        });\n    }\n\n    obtenerCasaSegunRespuesta(respuesta) {\n        return this.opciones[respuesta - 1].casa;\n    }\n}\n\nclass SombreroSeleccionador {\n    constructor(casas, preguntas) {\n        this.casas = casas;\n        this.preguntas = preguntas;\n    }\n\n    async asignarCasa(alumno) {\n        const preguntasSeleccionadas = this.seleccionarPreguntas();\n        for (let pregunta of preguntasSeleccionadas) {\n            pregunta.mostrarPregunta();\n            let respuesta = await this.leerRespuesta();\n            let casa = pregunta.obtenerCasaSegunRespuesta(respuesta);\n            this.casas[casa].agregarPuntos(1);\n        }\n\n        this.mostrarResultado(alumno);\n        rl.close();\n    }\n\n    seleccionarPreguntas() {\n        const preguntasSeleccionadas = [];\n        const indicesSeleccionados = new Set();\n\n        while (preguntasSeleccionadas.length < 10) {\n            let indice = Math.floor(Math.random() * this.preguntas.length);\n            if (!indicesSeleccionados.has(indice)) {\n                indicesSeleccionados.add(indice);\n                preguntasSeleccionadas.push(this.preguntas[indice]);\n            }\n        }\n\n        return preguntasSeleccionadas;\n    }\n\n    async leerRespuesta() {\n        return new Promise((resolve) => {\n            rl.question(\"Selecciona una opción (1-4): \", (respuesta) => {\n                resolve(parseInt(respuesta));\n            });\n        });\n    }\n\n    mostrarResultado(alumno) {\n        const casasOrdenadas = Object.values(this.casas).sort((a, b) => b.getPuntos() - a.getPuntos());\n\n        const maxPuntos = casasOrdenadas[0].getPuntos();\n        const ganadoras = casasOrdenadas.filter(casa => casa.getPuntos() === maxPuntos);\n\n        let ganadora;\n        if (ganadoras.length > 1) {\n            console.log(\"\\n\\nLa decisión fue difícil...\");\n            ganadora = ganadoras[Math.floor(Math.random() * ganadoras.length)];\n        } else {\n            ganadora = ganadoras[0];\n        }\n\n        console.log(`\\n\\n ${alumno.getNombre()}, el sombrero seleccionador te ha asignado a la casa ${ganadora.getNombre().toUpperCase()}!!!!\\n`);\n    }\n}\n\n\nconst casas = {\n    'frontend': new Casa('Frontend'),\n    'backend': new Casa('Backend'),\n    'mobile': new Casa('Mobile'),\n    'data': new Casa('Data')\n};\n\nconst preguntas = [\n    new Pregunta(\"¿Qué prefieres?\", [\n        { texto: 'Diseñar interfaces', casa: 'frontend' },\n        { texto: 'Crear APIs', casa: 'backend' },\n        { texto: 'Desarrollar apps móviles', casa: 'mobile' },\n        { texto: 'Analizar datos', casa: 'data' }\n    ]),\n    new Pregunta(\"¿Cuál es tu lenguaje de programación favorito?\", [\n        { texto: 'JavaScript', casa: 'frontend' },\n        { texto: 'Python', casa: 'backend' },\n        { texto: 'Kotlin', casa: 'mobile' },\n        { texto: 'R', casa: 'data' }\n    ]),\n    new Pregunta(\"¿Qué herramienta utilizas más a menudo?\", [\n        { texto: 'Figma o Sketch', casa: 'frontend' },\n        { texto: 'Docker o Kubernetes', casa: 'backend' },\n        { texto: 'Android Studio o Xcode', casa: 'mobile' },\n        { texto: 'Jupyter Notebooks o Excel', casa: 'data' }\n    ]),\n    new Pregunta(\"¿Qué te interesa más aprender?\", [\n        { texto: 'HTML/CSS y JavaScript avanzado', casa: 'frontend' },\n        { texto: 'Patrones de diseño y arquitectura de software', casa: 'backend' },\n        { texto: 'Programación nativa para dispositivos móviles', casa: 'mobile' },\n        { texto: 'Estadística y Machine Learning', casa: 'data' }\n    ]),\n    new Pregunta(\"¿Qué tipo de proyecto te gustaría liderar?\", [\n        { texto: 'Un sitio web interactivo y atractivo', casa: 'frontend' },\n        { texto: 'Una plataforma escalable con microservicios', casa: 'backend' },\n        { texto: 'Una app móvil innovadora', casa: 'mobile' },\n        { texto: 'Un sistema de recomendación basado en datos', casa: 'data' }\n    ]),\n    new Pregunta(\"¿Qué es lo más importante para ti en un proyecto?\", [\n        { texto: 'La experiencia de usuario', casa: 'frontend' },\n        { texto: 'El rendimiento y la escalabilidad', casa: 'backend' },\n        { texto: 'La adaptabilidad a diferentes dispositivos', casa: 'mobile' },\n        { texto: 'La precisión de los análisis', casa: 'data' }\n    ]),\n    new Pregunta(\"¿Qué prefieres trabajar?\", [\n        {texto : 'En un entorno donde el diseño visual es clave', casa :'frontend'},\n        {texto : 'En la lógica del negocio y la arquitectura', casa :'backend'},\n        {texto : 'En apps móviles con buen rendimiento', casa :'mobile'},\n        {texto : 'En el análisis y visualización de datos', casa :'data'}\n    ]),\n    new Pregunta(\"¿Qué framework te parece más interesante?\", [\n        {texto: 'React o Angular', casa :'frontend'},\n        {texto : 'Spring o Django', casa :'backend'},\n        {texto : 'Flutter o React Native', casa :'mobile'},\n        {texto : 'TensorFlow o Pandas', casa :'data'}\n    ]),\n    new Pregunta(\"¿Qué tipo de reto disfrutas más?\", [\n        {texto : 'Hacer que un sitio web sea accesible y rápido', casa :'frontend'},\n        {texto : 'Optimizar la comunicación entre servicios', casa :'backend'},\n        {texto : 'Mejorar la experiencia del usuario en móviles', casa :'mobile'},\n        {texto : 'Encontrar patrones ocultos en los datos', casa :'data'}\n    ]),\n    new Pregunta(\"¿Qué prefieres resolver?\", [\n        {texto : 'Problemas de diseño y maquetación', casa :'frontend'},\n        {texto : 'Problemas de concurrencia y escalabilidad', casa :'backend'},\n        {texto : 'Problemas de rendimiento en aplicaciones móviles', casa :'mobile'},\n        {texto : 'Problemas de predicción y análisis de datos', casa :'data'}\n    ]),\n    new Pregunta(\"¿Qué es lo que más te emociona en tecnología?\", [\n        {texto : 'La evolución de las interfaces de usuario', casa :'frontend'},\n        {texto : 'La innovación en la arquitectura de software', casa :'backend'},\n        {texto : 'Las nuevas capacidades de los dispositivos móviles', casa :'mobile'},\n        {texto : 'Los avances en inteligencia artificial y análisis de datos', casa : 'data'}\n    ]),\n    new Pregunta(\"¿Qué te gusta hacer en tu tiempo libre?\", [\n        {texto : 'Diseñar sitios web personales o interfaces', casa: 'frontend'},\n        {texto : 'Hacer proyectos con servidores y APIs', casa: 'backend'},\n        {texto : 'Crear apps móviles para resolver problemas cotidianos', casa: 'mobile'},\n        {texto : 'Hacer análisis de datos para tomar decisiones mejor informadas', casa: 'data'}\n    ]),\n    new Pregunta(\"¿Qué te gustaría dominar?\", [\n        {texto : 'Animaciones y transiciones en la web', casa: 'frontend'},\n        {texto : 'Arquitectura de microservicios', casa: 'backend'},\n        {texto : 'Optimización de aplicaciones móviles', casa: 'mobile'},\n        {texto : 'Modelos predictivos y análisis de datos', casa: 'data'}\n    ]),\n    new Pregunta(\"¿Qué tipo de problema prefieres resolver en un hackathon?\", [\n        {texto : 'Mejorar la interfaz de usuario de una aplicación', casa: 'frontend'},\n        {texto : 'Optimizar el rendimiento de una API', casa: 'backend'},\n        {texto : 'Crear una aplicación móvil desde cero', casa: 'mobile'},\n        {texto : 'Generar insights a partir de grandes conjuntos de datos', casa: 'data'}\n    ]),\n    new Pregunta(\"¿Qué prefieres al trabajar en equipo?\", [\n        {texto : 'Encargarte de la parte visual y de interacción del usuario', casa: 'frontend'},\n        {texto : 'Asegurarte de que la lógica y los datos fluyan correctamente', casa: 'backend'},\n        {texto : 'Hacer que la app funcione bien en diferentes dispositivos', casa: 'mobile'},\n        {texto : 'Proveer métricas y análisis para tomar mejores decisiones', casa: 'data'}\n    ]),\n    new Pregunta(\"¿Cuál es tu prioridad al optimizar código?\", [\n        {texto : 'Que la interfaz cargue rápido y sea amigable', casa: 'frontend'},\n        {texto : 'Que los servicios backend sean escalables y eficientes', casa: 'backend'},\n        {texto : 'Que la app móvil consuma pocos recursos y sea fluida', casa: 'mobile'},\n        {texto : 'Que el procesamiento de datos sea rápido y preciso', casa: 'data'}\n    ]),\n    new Pregunta(\"¿Qué prefieres al probar una aplicación?\", [\n        {texto : 'Verificar que el diseño y la usabilidad sean impecables', casa: 'frontend'},\n        {texto : 'Asegurar que las funcionalidades y la lógica sean correctas', casa :'backend'},\n        {texto : 'Revisar que la app funcione correctamente en múltiples dispositivos', casa : 'mobile'},\n        {texto : 'Validar que los resultados de los análisis sean exactos', casa : 'data'}\n    ]),\n    new Pregunta(\"¿Qué tipo de proyectos sigues en la industria?\", [\n        {texto : 'Proyectos de diseño web innovador y UX', casa : 'frontend'},\n        {texto : 'Nuevas tecnologías de servidores y backends', casa : 'backend'},\n        {texto : 'Aplicaciones móviles disruptivas y eficientes', casa : 'mobile'},\n        {texto : 'Proyectos de inteligencia artificial y ciencia de datos', casa : 'data'}\n    ]),\n    new Pregunta(\"¿Qué harías para mejorar una plataforma existente?\", [\n        {texto : 'Mejorar la apariencia y usabilidad de la interfaz', casa : 'frontend'},\n        {texto : 'Optimizar el rendimiento de las consultas y los servidores', casa : 'backend'},\n        {texto : 'Hacer que la plataforma sea accesible desde dispositivos móviles', casa : 'mobile'},\n        {texto : 'Incluir más análisis de datos para obtener mejor información', casa : 'data'}\n    ]),\n    new Pregunta(\"¿Qué aspecto del desarrollo de software te parece más retador?\", [\n        {texto : 'Hacer que una aplicación web sea visualmente atractiva', casa : 'frontend'},\n        {texto : 'Crear sistemas backend que manejen millones de usuarios', casa : 'backend'},\n        {texto : 'Optimizar la app móvil para diferentes sistemas operativos', casa : 'mobile'},\n        {texto : 'Gestionar grandes volúmenes de datos y extraer conclusiones útiles', casa : 'data'}\n    ]),\n];\n\nrl.question(\"Por favor, introduce tu nombre: \", (nombreAlumno) => {\n    const alumno = new Alumno(nombreAlumno);\n\n    const sombrero = new SombreroSeleccionador(casas, preguntas);\n    sombrero.asignarCasa(alumno);\n});\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/javascript/pedamoci.js",
    "content": "import readline from \"readline\"\n\nconst colors = {\n  red: \"\\x1b[31m\",\n  green: \"\\x1b[32m\",\n  yellow: \"\\x1b[33m\",\n  cyan: \"\\x1b[34m\",\n  reset: \"\\x1b[0m\",\n}\n\nconst QUESTIONS = [\n  {\n    question: \"1. What gives you the most satisfaction when finishing a project?\",\n    answers: {\n      A: \"A) That the interface is pixel-perfect and animations are fluid.\",\n      B: \"B) That the logic is robust, secure, and scales well under pressure.\",\n      C: \"C) Seeing people using my creation anywhere from their phone.\",\n      D: \"D) Discovering hidden patterns and predicting behaviors with data.\"\n    }\n  },\n  {\n    question: \"2. You encounter a terrible bug on a Friday afternoon. What is it?\",\n    answers: {\n      A: \"A) A `div` that refuses to center in Safari.\",\n      B: \"B) A database query that takes 10 seconds to respond.\",\n      C: \"C) The app crashes unexpectedly only on old Android models.\",\n      D: \"D) The prediction model has a 40% bias and gives wrong data.\"\n    }\n  },\n  {\n    question: \"3. If you had to choose a magic weapon (tool), which would you pick?\",\n    answers: {\n      A: \"A) The React/Vue Brush: To paint interactive realities.\",\n      B: \"B) The Docker/Kubernetes Hammer: To build indestructible fortresses.\",\n      C: \"C) The Swift/Kotlin Mirror: To reflect the world in the palm of your hand.\",\n      D: \"D) The Python/Pandas Crystal Ball: To see the future through numbers.\"\n    }\n  },\n  {\n    question: \"4. Which phrase best defines your work philosophy?\",\n    answers: {\n      A: \"A) Everything enters through the eyes; if it's not pretty, it's not used.\",\n      B: \"B) The essential is invisible to the eyes; what matters is the engine.\",\n      C: \"C) Accessibility and immediacy are everything.\",\n      D: \"D) Data doesn't lie, opinions do.\"\n    }\n  },\n  {\n    question: \"5. You are in a dark dungeon (terminal). What command do you type first?\",\n    answers: {\n      A: \"A) npm start (I want to see visual changes now).\",\n      B: \"B) sudo systemctl status (I need to know if the service is alive).\",\n      C: \"C) flutter run / ./gradlew (Let's see how this runs in the emulator).\",\n      D: \"D) jupyter notebook (Let's clean this dataset).\"\n    }\n  },\n  {\n    question: \"6. The Hat offers you a superpower. Which do you choose?\",\n    answers: {\n      A: \"A) Total Compatibility: Your code looks the same in all browsers.\",\n      B: \"B) Infinite Uptime: Your server never goes down, no matter what.\",\n      C: \"C) Eternal Battery: Your app never consumes excessive resources.\",\n      D: \"D) Omniscience: Knowing the exact answer to any question based on statistics.\"\n    }\n  },\n  {\n    question: \"7. What is your natural enemy in the world of code?\",\n    answers: {\n      A: \"A) Internet Explorer and browser cache.\",\n      B: \"B) Spaghetti Code and SQL injections.\",\n      C: \"C) Old Android models.\",\n      D: \"D) Data doesn't lie, opinions do.\"\n    }\n  },\n  {\n    question: \"8. You have to explain your job to a Muggle (non-programmer). What do you say?\",\n    answers: {\n      A: \"A) I want to see visual changes now.\",\n      B: \"B) I need to know if the service is alive.\",\n      C: \"C) Let's see how this runs in the emulator.\",\n      D: \"D) Let's clean this dataset.\"\n    }\n  },\n  {\n    question: \"9. Which environment do you prefer to perform your magic?\",\n    answers: {\n      A: \"A) A browser with DevTools open and three monitors.\",\n      B: \"B) A black terminal with green text and lyric-less music.\",\n      C: \"C) A device emulator and a cable connected to the real phone.\",\n      D: \"D) Charts, spreadsheets, and interactive notebook environments.\"\n    }\n  },\n  {\n    question: \"10. Finally, how would you like to be remembered in Hogwarts history?\",\n    answers: {\n      A: \"A) As the artist who designed the ultimate user experience.\",\n      B: \"B) As the architect who built the most secure system in the world.\",\n      C: \"C) As the creator of the app that changed the daily lives of millions.\",\n      D: \"D) As the sage who discovered the hidden truth in the chaos of information.\"\n    }\n  }\n]\n\nclass Asks {\n  constructor() {\n    this.readline = readline.createInterface({\n      input: process.stdin,\n      output: process.stdout\n    })\n  }\n\n  #ask(question) {\n    return new Promise(resolve => {\n      this.readline.question(question, (answer) => resolve(answer))\n    })\n  }\n\n  close() {\n    this.readline.close()\n  }\n\n  async askLabel(info) {\n    const response = (await this.#ask(colors.cyan + info + colors.reset))\n    return response\n  }\n  \n  async askQuestion(question) {\n    const response = (await this.#ask(colors.cyan + question +  colors.reset)).toUpperCase()\n    return response\n  }\n}\n\nconst asks = new Asks()\n\nclass Validator {\n  static isValidAnswer(answer) {\n    return answer === 'A' || answer === 'B' || answer === 'C' || answer === 'D'\n  }\n}\n\nclass Renderer {\n  static error(msg){\n    console.error(colors.red + msg + colors.reset)\n  }\n\n  static info(msg){\n    console.info(colors.yellow + msg + colors.reset)\n  }\n}\n\nclass SortingHat {\n  constructor() {\n    this.points = {\n      Frontend: 0,\n      Backend: 0,\n      Mobile: 0,\n      Data: 0\n    }\n\n    this.HOUSES_FOR_ANSWER = {\n      A: \"Frontend\",\n      B: \"Backend\",\n      C: \"Mobile\",\n      D: \"Data\"\n    }\n  }\n\n  setPoints(answers) {\n    for (const answer of answers) {\n      this.points[this.HOUSES_FOR_ANSWER[answer]]++\n    }\n  }\n\n  checkHouse(answers){\n    this.setPoints(answers)\n\n    const maxPoints = Math.max(...Object.values(this.points))\n\n    const houses = Object.keys(this.points).filter(key => this.points[key] === maxPoints)\n\n    if (houses.length > 1) {\n      Renderer.info(\"The decision was complicated...\")\n    }\n\n    return houses[Math.floor(Math.random() * houses.length)]\n  }\n}\n\nclass QuestionController {\n  constructor(sortingHat) {\n    this.sortingHat = sortingHat\n    this.answers = []\n  }\n\n  async askQuestion(question) {\n\n    const answer = await asks.askQuestion(question)\n\n    if (Validator.isValidAnswer(answer)) {\n      this.answers.push(answer)\n    } else {\n      Renderer.error(\"Invalid answer. Please try again.\")\n      return this.askQuestion(question)\n    }\n  }\n\n  formatQA({ question, answers }) {\n    return `\\n${question}\n      \\n${answers.A}\n      \\n${answers.B}\n      \\n${answers.C}\n      \\n${answers.D}\n      \\n\\n(Answer with 'A', 'B', 'C' or 'D') Answer: `\n  }\n\n  async askQuestions() {\n    for (let i = 0; i < QUESTIONS.length; i++) {\n      await this.askQuestion(this.formatQA(QUESTIONS[i]))\n    }\n  }\n\n  async run() {\n    const name = await asks.askLabel(\"\\nWhat is your name? \")\n    await this.askQuestions()\n    const house = this.sortingHat.checkHouse(this.answers)\n    Renderer.info(`${name}, you are in ${house}`)\n    asks.close()\n  }\n}\n\nconst questionController = new QuestionController(new SortingHat())\nquestionController.run()"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/javascript/redom69.js",
    "content": "const readline = require('readline');\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nfunction printQuiz() {\n    const preguntas = [\n        {\n            pregunta: \"¿Qué es lo que más disfrutas al programar?\",\n            opciones: [\n                { respuesta: \"Diseñar interfaces atractivas\", casa: \"Frontend\" },\n                { respuesta: \"Optimizar el rendimiento del servidor\", casa: \"Backend\" },\n                { respuesta: \"Crear aplicaciones móviles útiles\", casa: \"Mobile\" },\n                { respuesta: \"Analizar grandes conjuntos de datos\", casa: \"Data\" }\n            ]\n        },\n        {\n            pregunta: \"¿Qué tipo de proyecto te atrae más?\",\n            opciones: [\n                { respuesta: \"Aplicaciones web con mucho estilo\", casa: \"Frontend\" },\n                { respuesta: \"Sistemas que manejen grandes volúmenes de datos\", casa: \"Backend\" },\n                { respuesta: \"Aplicaciones para teléfonos inteligentes\", casa: \"Mobile\" },\n                { respuesta: \"Dashboards para visualizar información\", casa: \"Data\" }\n            ]\n        },\n        {\n            pregunta: \"¿Qué herramienta te resulta más interesante?\",\n            opciones: [\n                { respuesta: \"HTML, CSS y JavaScript\", casa: \"Frontend\" },\n                { respuesta: \"Node.js o Python\", casa: \"Backend\" },\n                { respuesta: \"React Native o Swift\", casa: \"Mobile\" },\n                { respuesta: \"SQL o Python con Pandas\", casa: \"Data\" }\n            ]\n        },\n        {\n            pregunta: \"¿Cuál es tu mayor fortaleza como programador?\",\n            opciones: [\n                { respuesta: \"Crear interfaces amigables\", casa: \"Frontend\" },\n                { respuesta: \"Solucionar problemas complejos en el servidor\", casa: \"Backend\" },\n                { respuesta: \"Desarrollar apps funcionales\", casa: \"Mobile\" },\n                { respuesta: \"Encontrar patrones en los datos\", casa: \"Data\" }\n            ]\n        },\n        {\n            pregunta: \"¿Qué prefieres en un equipo de desarrollo?\",\n            opciones: [\n                { respuesta: \"Ser quien diseña el look y feel\", casa: \"Frontend\" },\n                { respuesta: \"Ser quien gestiona la arquitectura de la aplicación\", casa: \"Backend\" },\n                { respuesta: \"Ser quien se encarga de la versión móvil\", casa: \"Mobile\" },\n                { respuesta: \"Ser quien analiza el rendimiento del sistema\", casa: \"Data\" }\n            ]\n        },\n        {\n            pregunta: \"¿En qué te enfocas más cuando trabajas en un proyecto?\",\n            opciones: [\n                { respuesta: \"En el diseño visual y la experiencia de usuario\", casa: \"Frontend\" },\n                { respuesta: \"En la estabilidad y escalabilidad del sistema\", casa: \"Backend\" },\n                { respuesta: \"En hacer que la app funcione en dispositivos móviles\", casa: \"Mobile\" },\n                { respuesta: \"En el análisis y visualización de los datos\", casa: \"Data\" }\n            ]\n        },\n        {\n            pregunta: \"¿Cuál es tu mayor motivación como desarrollador?\",\n            opciones: [\n                { respuesta: \"Crear experiencias de usuario memorables\", casa: \"Frontend\" },\n                { respuesta: \"Resolver problemas complejos con eficiencia\", casa: \"Backend\" },\n                { respuesta: \"Desarrollar aplicaciones que la gente use todos los días\", casa: \"Mobile\" },\n                { respuesta: \"Descubrir patrones ocultos en los datos\", casa: \"Data\" }\n            ]\n        },\n        {\n            pregunta: \"¿Qué aspecto prefieres de un nuevo proyecto?\",\n            opciones: [\n                { respuesta: \"Hacer que se vea genial y sea fácil de usar\", casa: \"Frontend\" },\n                { respuesta: \"Asegurarme de que el servidor funcione sin problemas\", casa: \"Backend\" },\n                { respuesta: \"Hacer que funcione bien en dispositivos móviles\", casa: \"Mobile\" },\n                { respuesta: \"Organizar y visualizar los datos de forma eficiente\", casa: \"Data\" }\n            ]\n        },\n        {\n            pregunta: \"¿Qué tecnología te emociona más aprender?\",\n            opciones: [\n                { respuesta: \"Frameworks de JavaScript como React o Angular\", casa: \"Frontend\" },\n                { respuesta: \"Microservicios o arquitectura en la nube\", casa: \"Backend\" },\n                { respuesta: \"Desarrollo de aplicaciones móviles\", casa: \"Mobile\" },\n                { respuesta: \"Big Data o inteligencia artificial\", casa: \"Data\" }\n            ]\n        },\n        {\n            pregunta: \"Si pudieras elegir un área de especialización, ¿cuál sería?\",\n            opciones: [\n                { respuesta: \"Interfaz y experiencia de usuario\", casa: \"Frontend\" },\n                { respuesta: \"Desarrollo y mantenimiento del servidor\", casa: \"Backend\" },\n                { respuesta: \"Aplicaciones móviles\", casa: \"Mobile\" },\n                { respuesta: \"Ciencia de datos y análisis\", casa: \"Data\" }\n            ]\n        }\n    ];\n\n    const answers = [];\n\n    const askQuestion = (index) => {\n        if (index < preguntas.length) {\n            console.log(preguntas[index].pregunta);\n            preguntas[index].opciones.forEach((opcion, idx) => {\n                console.log(`${String.fromCharCode(97 + idx)}: ${opcion.respuesta}`);\n            });\n            rl.question('Selecciona una opción: ', (answer) => {\n                answers.push(answer);\n                askQuestion(index + 1);\n            });\n        } else {\n            rl.close();\n            const house = selectHouse(answers);\n            console.log(`La casa seleccionada es: ${house}`);\n        }\n    };\n\n    askQuestion(0);\n}\n\nfunction selectHouse(answers) {\n    const countFront = answers.filter((a) => a === 'a').length;\n    const countBackend = answers.filter((a) => a === 'b').length;\n    const countMobile = answers.filter((a) => a === 'c').length;\n    const countData = answers.filter((a) => a === 'd').length;\n\n    const casas = { Frontend: countFront, Backend: countBackend, Mobile: countMobile, Data: countData };\n    const maxCount = Math.max(...Object.values(casas));\n\n    const posiblesCasas = Object.keys(casas).filter(casa => casas[casa] === maxCount);\n\n    if (posiblesCasas.length > 1) {\n        console.log(\"¡Ha sido una decisión complicada!\");\n        return posiblesCasas[Math.floor(Math.random() * posiblesCasas.length)];\n    }\n\n    return posiblesCasas[0];\n}\n\nfunction main() {\n    rl.question('Introduce tu nombre: ', (name) => {\n        printQuiz();\n    });\n}\n\nmain();\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/kotlin/blackriper.kt",
    "content": "import kotlinx.coroutines.coroutineScope\r\nimport kotlinx.coroutines.flow.asFlow\r\nimport kotlinx.coroutines.flow.transform\r\nimport kotlinx.coroutines.launch\r\nimport kotlinx.coroutines.runBlocking\r\nimport kotlin.jvm.optionals.toList\r\n\r\n//1.- definir estructuras de datos y mock de datos\r\n\r\nenum class School{\r\n    FRONTEND, BACKEND, MOBILE, DATA\r\n}\r\n\r\ntypealias Option= Pair<String,School>\r\n\r\ndata class Question constructor(var text:String=\"\", var options:List<Option> = emptyList())\r\n\r\nfun question(block: Question.()->Unit):Question= Question().apply(block)\r\n\r\n\r\ndata class Magician constructor(val name: String=\"\", var frontend:Int=0, var backend:Int=0, var mobile:Int=0, var data:Int=0)\r\n\r\n\r\nval quetions= listOf(\r\n   question {\r\n      text=\"¿Que parte del desarrollo de software llama mas tu atencion?\"\r\n      options= listOf(\r\n         \"Diseño de interfaces UX\" to School.FRONTEND,\r\n         \"Diseño de Api para la consulta de datos \" to School.BACKEND,\r\n         \"Diseño de la base de datos \" to School.DATA,\r\n         \"Diseño de la interfaz de usuario mediante codigo o xml \" to School.MOBILE\r\n      )\r\n   },\r\n   question {\r\n       text=\"¿Es de tu interes la gestión de servidores y la arquitectura de sistemas?\"\r\n       options= listOf(\r\n           \"Si totalmente \" to School.BACKEND,\r\n           \"No prefiero el diseño UX para web \" to School.FRONTEND,\r\n           \"No me interesa  esa parte prefiero trabajar con los datos de estos servidores\" to School.DATA,\r\n           \"Prefiero diseñar apps para dispositivos moviles\" to School.MOBILE\r\n       )\r\n   },\r\n   question {\r\n       text=\"Qué lenguaje de programación dominas mejor actualmente\"\r\n       options= listOf(\r\n           \"JavaScript/TypeScript\" to School.FRONTEND,\r\n           \"Go/Java/Python\" to School.BACKEND,\r\n           \"Kotlin/Swift\" to School.MOBILE,\r\n           \"C/C++/Scala\" to School.DATA\r\n       )\r\n   },\r\n   question {\r\n     text=\"¿Qué frameworks o herramientas dominas o te gustaria aprender mas ?\"\r\n     options= listOf(\r\n         \"React/express/Vue/Angular\" to School.FRONTEND,\r\n         \"Gin/Spring boot/FastApi\" to School.BACKEND,\r\n         \"Jetpack Compose/SwiftUI\" to School.MOBILE,\r\n         \"Spark Mlib,NumPy\" to School.DATA\r\n     )\r\n   },\r\n   question {\r\n       text=\"¿Es de tu interes el manejo de altos volumenes de datos?\"\r\n       options= listOf(\r\n           \"No me interesa\" to School.FRONTEND,\r\n           \"Me interesa un poco pero uso librerias como Room para gestionar su manejo\" to School.MOBILE,\r\n           \"Me interesa solo el acceso y proteccion de como los datos son guardados\" to School.BACKEND,\r\n           \"Me interesa su manejo y la optimizacion de algoritmos\" to School.DATA\r\n       )\r\n   },\r\n\r\n   question {\r\n       text=\"¿Qué plataforma es mas de tu preferencia ?\"\r\n       options= listOf(\r\n           \"Windows\" to School.FRONTEND,\r\n           \"Linux\" to School.BACKEND,\r\n           \"Android/IOS\" to School.MOBILE,\r\n           \"Me da igual prefiero el trabajo con la data\" to School.DATA\r\n       )\r\n   },\r\n\r\n  question {\r\n      text=\"¿Haz escuchado alguno de los siguientes conceptos?\"\r\n      options= listOf(\r\n          \"Css,Html,async/await\" to School.FRONTEND,\r\n          \"Http/Jwt/Cors/concurrencia\" to School.BACKEND,\r\n          \"Intents/xml/permissions\" to School.MOBILE,\r\n          \"Pandas/bigdata\" to School.DATA\r\n      )\r\n  },\r\n  question {\r\n      text=\"¿Manejas algun administrador de dependencias?\"\r\n      options= listOf(\r\n          \"Npm,bun,yarn\" to School.FRONTEND,\r\n          \"Pip,maven,go\" to School.BACKEND,\r\n          \"Swift package manager,gradle\" to School.MOBILE,\r\n          \"Ninguna de las anteriores\" to School.DATA\r\n      )\r\n  },\r\n\r\n question {\r\n     text=\"¿Eres habil con el diseño?\"\r\n     options= listOf(\r\n         \"Si pero me acomodo hacerlo con Css o algun framework\" to School.FRONTEND,\r\n         \"Si pero me gusta hacerlo con codigo o Xml \" to School.MOBILE,\r\n         \"No es de mi interes prefiero las cosas que pasan por detras de la vision\" to School.BACKEND,\r\n         \"No prefiero el modelo de datos\" to School.DATA\r\n     )\r\n },\r\n\r\n question {\r\n     text=\"¿Cuanto dinero aspiras a ganar cuando te conviertas en un hechicero del ministerio?\"\r\n     options= listOf(\r\n         \"$ 60 K\" to School.FRONTEND,\r\n         \"$ 80 K\" to School.BACKEND,\r\n         \"$ 75 K\" to School.MOBILE,\r\n         \"$ 100 K\" to School.DATA\r\n     )\r\n }\r\n)\r\n\r\n// 2.- definir funcioneamiento  del sombrero\r\n\r\ninterface  Sorting{\r\n    fun registerMagician()\r\n    fun evaluteAnswer(answer: String,options: List<Option>)\r\n    fun printResult()\r\n}\r\n\r\n// 3.- Implementar clases\r\n\r\nclass Hat: Sorting{\r\n    private lateinit var magician:Magician\r\n\r\n    override fun registerMagician() {\r\n       println(\"¿cual es tu nombre aspirante ?\")\r\n       val name = readLine()?.let { it.toString() } ?: \"\"\r\n       magician = Magician(name)\r\n    }\r\n\r\n    override fun evaluteAnswer(answer: String, options: List<Option>) {\r\n        val  school = options.first { it.first == answer }.second\r\n        magician.apply {\r\n            when (school) {\r\n                School.FRONTEND -> frontend++\r\n                School.BACKEND -> backend++\r\n                School.MOBILE -> mobile++\r\n                School.DATA -> data++\r\n            }\r\n        }\r\n    }\r\n\r\n    override fun printResult() {\r\n      val scores= listOf(\r\n          School.FRONTEND to magician.frontend,\r\n          School.BACKEND to magician.backend,\r\n          School.MOBILE to magician.mobile,\r\n          School.DATA to magician.data\r\n      )\r\n      val numSchool= scores.count { it.second==scores.maxOf { it.second } }\r\n\r\n      if (numSchool>1){\r\n          val winners= scores.filter { it.second==scores.maxOf { it.second } }\r\n          val winner=winners.random().first\r\n          println(\"La decisión fue complicada pero tu casa aspirante ${magician.name} es ${winner.name.capitalizeWord()}\")\r\n      }\r\n\r\n       if (numSchool==1){\r\n           val winner= scores.first { it.second==scores.maxOf { it.second } }.first\r\n           println(\"Tu casa aspirante ${magician.name} es ${winner.name.capitalizeWord()}\")\r\n       }\r\n\r\n    }\r\n\r\n\r\n}\r\ncontext(Sorting)\r\nsuspend fun startSelection():Unit= coroutineScope{\r\n    registerMagician()\r\n    for (question in quetions) {\r\n        println(question.text)\r\n        var ind=1\r\n        question.options.forEach {\r\n            println(\"$ind.- ${it.first}\")\r\n            ind++\r\n        }\r\n        val option= readLine()?.let { it.toInt() } ?: 0\r\n        evaluteAnswer(question.options[option-1].first,question.options)\r\n    }\r\n    printResult()\r\n}\r\n\r\nfun main()= runBlocking {\r\n   val job= launch {\r\n       with(Hat()){\r\n           var option = \"\"\r\n           while (option != \"N\") {\r\n               startSelection()\r\n               println(\"¿Deseas registrar una nuevo aspirante Y/N?\")\r\n               option = readLine()?.let { it.uppercase() } ?: \"N\"\r\n           }\r\n       }\r\n   }\r\n   job.join()\r\n}\r\n\r\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/php/miguelex.php",
    "content": "<?php\n\ninterface Casa {\n    public function getNombre(): string;\n    public function agregarPuntos(int $puntos): void;\n    public function getPuntos(): int;\n}\n\nclass BaseCasa implements Casa {\n    private string $nombre;\n    private int $puntos = 0;\n\n    public function __construct(string $nombre) {\n        $this->nombre = $nombre;\n    }\n\n    public function getNombre(): string {\n        return $this->nombre;\n    }\n\n    public function agregarPuntos(int $puntos): void {\n        $this->puntos += $puntos;\n    }\n\n    public function getPuntos(): int {\n        return $this->puntos;\n    }\n}\n\nclass Alumno {\n    private string $nombre;\n\n    public function __construct(string $nombre) {\n        $this->nombre = $nombre;\n    }\n\n    public function getNombre(): string {\n        return $this->nombre;\n    }\n}\n\nclass Pregunta {\n    private string $pregunta;\n    private array $opciones; // ['opción' => 'Casa']\n\n    public function __construct(string $pregunta, array $opciones) {\n        $this->pregunta = $pregunta;\n        $this->opciones = $opciones;\n    }\n\n    public function mostrarPregunta(): void {\n        echo $this->pregunta . PHP_EOL;\n        foreach ($this->opciones as $index => $opcion) {\n            echo ($index + 1) . \": \" . $opcion['texto'] . PHP_EOL;\n        }\n    }\n\n    public function obtenerCasaSegunRespuesta(int $respuesta): string {\n        return $this->opciones[$respuesta - 1]['casa'];\n    }\n}\n\nclass SombreroSeleccionador {\n    private array $casas;\n    private array $preguntas;\n\n    public function __construct(array $casas, array $preguntas) {\n        $this->casas = $casas;\n        $this->preguntas = $preguntas;\n    }\n\n    public function asignarCasa(Alumno $alumno): void {\n        $preguntasSeleccionadas = $this->seleccionarPreguntas();\n        foreach ($preguntasSeleccionadas as $pregunta) {\n            $pregunta->mostrarPregunta();\n            $respuesta = (int)readline(\"Selecciona una opción (1-4): \");\n            $casa = $pregunta->obtenerCasaSegunRespuesta($respuesta);\n            $this->casas[$casa]->agregarPuntos(1);\n        }\n\n        $this->mostrarResultado($alumno);\n    }\n\n    private function seleccionarPreguntas(): array {\n        $preguntasSeleccionadas = array_rand($this->preguntas, 10);\n        return array_map(fn($indice) => $this->preguntas[$indice], $preguntasSeleccionadas);\n    }\n\n    private function mostrarResultado(Alumno $alumno): void {\n        usort($this->casas, fn($casa1, $casa2) => $casa2->getPuntos() <=> $casa1->getPuntos());\n        \n        $maxPuntos = $this->casas[0]->getPuntos();\n        $ganadoras = array_filter($this->casas, fn($casa) => $casa->getPuntos() === $maxPuntos);\n        \n        if (count($ganadoras) > 1) {\n            echo \"\\n\\nLa decisión fue difícil...\\n\";\n            $ganadora = $ganadoras[array_rand($ganadoras)];\n        } else {\n            $ganadora = $ganadoras[0];\n        }\n\n        echo \"\\n\\n \".$alumno->getNombre() . \", el sombrero seleccionador te ha asignado a la casa \" . strtoupper($ganadora->getNombre()) . \"!!!!\\n\" . PHP_EOL;\n    }\n}\n\n$casas = [\n    'frontend' => new BaseCasa('Frontend'),\n    'backend' => new BaseCasa('Backend'),\n    'mobile' => new BaseCasa('Mobile'),\n    'data' => new BaseCasa('Data')\n];\n\n$preguntas = [\n    new Pregunta(\"¿Qué prefieres?\", [\n        ['texto' => 'Diseñar interfaces', 'casa' => 'frontend'],\n        ['texto' => 'Crear APIs', 'casa' => 'backend'],\n        ['texto' => 'Desarrollar apps móviles', 'casa' => 'mobile'],\n        ['texto' => 'Analizar datos', 'casa' => 'data']\n    ]),\n    new Pregunta(\"¿Cuál es tu lenguaje de programación favorito?\", [\n        ['texto' => 'JavaScript', 'casa' => 'frontend'],\n        ['texto' => 'Python', 'casa' => 'backend'],\n        ['texto' => 'Kotlin', 'casa' => 'mobile'],\n        ['texto' => 'R', 'casa' => 'data']\n    ]),\n    new Pregunta(\"¿Qué herramienta utilizas más a menudo?\", [\n        ['texto' => 'Figma o Sketch', 'casa' => 'frontend'],\n        ['texto' => 'Docker o Kubernetes', 'casa' => 'backend'],\n        ['texto' => 'Android Studio o Xcode', 'casa' => 'mobile'],\n        ['texto' => 'Jupyter Notebooks o Excel', 'casa' => 'data']\n    ]),\n    new Pregunta(\"¿Qué te interesa más aprender?\", [\n        ['texto' => 'HTML/CSS y JavaScript avanzado', 'casa' => 'frontend'],\n        ['texto' => 'Patrones de diseño y arquitectura de software', 'casa' => 'backend'],\n        ['texto' => 'Programación nativa para dispositivos móviles', 'casa' => 'mobile'],\n        ['texto' => 'Estadística y Machine Learning', 'casa' => 'data']\n    ]),\n    new Pregunta(\"¿Qué tipo de proyecto te gustaría liderar?\", [\n        ['texto' => 'Un sitio web interactivo y atractivo', 'casa' => 'frontend'],\n        ['texto' => 'Una plataforma escalable con microservicios', 'casa' => 'backend'],\n        ['texto' => 'Una app móvil innovadora', 'casa' => 'mobile'],\n        ['texto' => 'Un sistema de recomendación basado en datos', 'casa' => 'data']\n    ]),\n    new Pregunta(\"¿Qué es lo más importante para ti en un proyecto?\", [\n        ['texto' => 'La experiencia de usuario', 'casa' => 'frontend'],\n        ['texto' => 'El rendimiento y la escalabilidad', 'casa' => 'backend'],\n        ['texto' => 'La adaptabilidad a diferentes dispositivos', 'casa' => 'mobile'],\n        ['texto' => 'La precisión de los análisis', 'casa' => 'data']\n    ]),\n    new Pregunta(\"¿Qué prefieres trabajar?\", [\n        ['texto' => 'En un entorno donde el diseño visual es clave', 'casa' => 'frontend'],\n        ['texto' => 'En la lógica del negocio y la arquitectura', 'casa' => 'backend'],\n        ['texto' => 'En apps móviles con buen rendimiento', 'casa' => 'mobile'],\n        ['texto' => 'En el análisis y visualización de datos', 'casa' => 'data']\n    ]),\n    new Pregunta(\"¿Qué framework te parece más interesante?\", [\n        ['texto' => 'React o Angular', 'casa' => 'frontend'],\n        ['texto' => 'Spring o Django', 'casa' => 'backend'],\n        ['texto' => 'Flutter o React Native', 'casa' => 'mobile'],\n        ['texto' => 'TensorFlow o Pandas', 'casa' => 'data']\n    ]),\n    new Pregunta(\"¿Qué tipo de reto disfrutas más?\", [\n        ['texto' => 'Hacer que un sitio web sea accesible y rápido', 'casa' => 'frontend'],\n        ['texto' => 'Optimizar la comunicación entre servicios', 'casa' => 'backend'],\n        ['texto' => 'Mejorar la experiencia del usuario en móviles', 'casa' => 'mobile'],\n        ['texto' => 'Encontrar patrones ocultos en los datos', 'casa' => 'data']\n    ]),\n    new Pregunta(\"¿Qué prefieres resolver?\", [\n        ['texto' => 'Problemas de diseño y maquetación', 'casa' => 'frontend'],\n        ['texto' => 'Problemas de concurrencia y escalabilidad', 'casa' => 'backend'],\n        ['texto' => 'Problemas de rendimiento en aplicaciones móviles', 'casa' => 'mobile'],\n        ['texto' => 'Problemas de predicción y análisis de datos', 'casa' => 'data']\n    ]),\n    new Pregunta(\"¿Qué es lo que más te emociona en tecnología?\", [\n        ['texto' => 'La evolución de las interfaces de usuario', 'casa' => 'frontend'],\n        ['texto' => 'La innovación en la arquitectura de software', 'casa' => 'backend'],\n        ['texto' => 'Las nuevas capacidades de los dispositivos móviles', 'casa' => 'mobile'],\n        ['texto' => 'Los avances en inteligencia artificial y análisis de datos', 'casa' => 'data']\n    ]),\n    new Pregunta(\"¿Qué te gusta hacer en tu tiempo libre?\", [\n        ['texto' => 'Diseñar sitios web personales o interfaces', 'casa' => 'frontend'],\n        ['texto' => 'Hacer proyectos con servidores y APIs', 'casa' => 'backend'],\n        ['texto' => 'Crear apps móviles para resolver problemas cotidianos', 'casa' => 'mobile'],\n        ['texto' => 'Hacer análisis de datos para tomar decisiones mejor informadas', 'casa' => 'data']\n    ]),\n    new Pregunta(\"¿Qué te gustaría dominar?\", [\n        ['texto' => 'Animaciones y transiciones en la web', 'casa' => 'frontend'],\n        ['texto' => 'Arquitectura de microservicios', 'casa' => 'backend'],\n        ['texto' => 'Optimización de aplicaciones móviles', 'casa' => 'mobile'],\n        ['texto' => 'Modelos predictivos y análisis de datos', 'casa' => 'data']\n    ]),\n    new Pregunta(\"¿Qué tipo de problema prefieres resolver en un hackathon?\", [\n        ['texto' => 'Mejorar la interfaz de usuario de una aplicación', 'casa' => 'frontend'],\n        ['texto' => 'Optimizar el rendimiento de una API', 'casa' => 'backend'],\n        ['texto' => 'Crear una aplicación móvil desde cero', 'casa' => 'mobile'],\n        ['texto' => 'Generar insights a partir de grandes conjuntos de datos', 'casa' => 'data']\n    ]),\n    new Pregunta(\"¿Qué prefieres al trabajar en equipo?\", [\n        ['texto' => 'Encargarte de la parte visual y de interacción del usuario', 'casa' => 'frontend'],\n        ['texto' => 'Asegurarte de que la lógica y los datos fluyan correctamente', 'casa' => 'backend'],\n        ['texto' => 'Hacer que la app funcione bien en diferentes dispositivos', 'casa' => 'mobile'],\n        ['texto' => 'Proveer métricas y análisis para tomar mejores decisiones', 'casa' => 'data']\n    ]),\n    new Pregunta(\"¿Cuál es tu prioridad al optimizar código?\", [\n        ['texto' => 'Que la interfaz cargue rápido y sea amigable', 'casa' => 'frontend'],\n        ['texto' => 'Que los servicios backend sean escalables y eficientes', 'casa' => 'backend'],\n        ['texto' => 'Que la app móvil consuma pocos recursos y sea fluida', 'casa' => 'mobile'],\n        ['texto' => 'Que el procesamiento de datos sea rápido y preciso', 'casa' => 'data']\n    ]),\n    new Pregunta(\"¿Qué prefieres al probar una aplicación?\", [\n        ['texto' => 'Verificar que el diseño y la usabilidad sean impecables', 'casa' => 'frontend'],\n        ['texto' => 'Asegurar que las funcionalidades y la lógica sean correctas', 'casa' => 'backend'],\n        ['texto' => 'Revisar que la app funcione correctamente en múltiples dispositivos', 'casa' => 'mobile'],\n        ['texto' => 'Validar que los resultados de los análisis sean exactos', 'casa' => 'data']\n    ]),\n    new Pregunta(\"¿Qué tipo de proyectos sigues en la industria?\", [\n        ['texto' => 'Proyectos de diseño web innovador y UX', 'casa' => 'frontend'],\n        ['texto' => 'Nuevas tecnologías de servidores y backends', 'casa' => 'backend'],\n        ['texto' => 'Aplicaciones móviles disruptivas y eficientes', 'casa' => 'mobile'],\n        ['texto' => 'Proyectos de inteligencia artificial y ciencia de datos', 'casa' => 'data']\n    ]),\n    new Pregunta(\"¿Qué harías para mejorar una plataforma existente?\", [\n        ['texto' => 'Mejorar la apariencia y usabilidad de la interfaz', 'casa' => 'frontend'],\n        ['texto' => 'Optimizar el rendimiento de las consultas y los servidores', 'casa' => 'backend'],\n        ['texto' => 'Hacer que la plataforma sea accesible desde dispositivos móviles', 'casa' => 'mobile'],\n        ['texto' => 'Incluir más análisis de datos para obtener mejor información', 'casa' => 'data']\n    ]),\n    new Pregunta(\"¿Qué aspecto del desarrollo de software te parece más retador?\", [\n        ['texto' => 'Hacer que una aplicación web sea visualmente atractiva', 'casa' => 'frontend'],\n        ['texto' => 'Crear sistemas backend que manejen millones de usuarios', 'casa' => 'backend'],\n        ['texto' => 'Optimizar la app móvil para diferentes sistemas operativos', 'casa' => 'mobile'],\n        ['texto' => 'Gestionar grandes volúmenes de datos y extraer conclusiones útiles', 'casa' => 'data']\n    ]),\n    \n];\n\n\necho \"Bienvenido al sombrero seleccionador de Hogwarts de programación.\\n\";\n$nombreAlumno = readline(\"Por favor, introduce tu nombre: \");\n$alumno = new Alumno($nombreAlumno);\n\n$sombrero = new SombreroSeleccionador($casas, $preguntas);\n$sombrero->asignarCasa($alumno);\n\n\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/python/Alecraft8.py",
    "content": "from random import randint\n\n# Array de Preguntas del Sombrero\n\npreguntas = [\n    \"¿Te sientes cómodo manejando servidores?\",\n    \"¿Eres bueno con Javascript y CSS?\",\n    \"¿Manejas bases de datos?\",\n    \"¿Programas en Python, Ruby, C, u otro lenguaje de Backend?\",\n    \"¿Te gusta tomar café?\",\n    \"¿Haz hecho algun proyecto de páginas web?\",\n    \"¿Conoces tecnologías de manejo de datos?\",\n    \"¿Te gusta programar programas de escritorio?\",\n    \"¿Usas PHP?\",\n    \"¿Usas Kotlin y/o Java?\"\n]\n\n# Variables de respuestas\n\nn = \"no\"\ns = \"si\"\nl = \"lo manejo\"\nm = \"no mucho\"\n\n# Posibles variaciones de respuestas\n# N de Array = N de Preguntas\n\nresponses = {\n    \"Frontend\": [n, s, n, n, m, l, n, m, m, m],\n    \"Backend\":  [l, m, l, s, s, s, l, l, l, l],\n    \"Mobile\":   [m, l, m, m, l, n, m, n, n, s],\n    \"Data\":     [s, n, s, l, n, m, s, s, s, n]\n    }\n\nhouses_points = {\n    \"Frontend\": 0,\n    \"Backend\":  0,\n    \"Mobile\":   0,\n    \"Data\":     0\n    }\n\ndef main():\n    name = input(\"Ingrese el nombre del alumno: \")\n    print(\"Bienvenido al Hogwarts Express, %s!\" % (name))\n    print(\"Este es tu sombrero seleccionador, encuentra tu camino hacia la escuela de programación de Hogwarts.\")\n    print(\"Empezamos las preguntas.\")\n    for pregunta in range(len(preguntas)):\n        bad_answer = True\n        while bad_answer:\n            respuesta = input(preguntas[pregunta] + \" (Si/No/No mucho/Lo manejo): \").lower()\n            if respuesta in [\"si\", \"no\", \"lo manejo\", \"no mucho\"]:\n                for i in responses.keys():\n                    if responses[i][pregunta] == respuesta:\n                        houses_points[i] += 1\n                bad_answer = False\n            else:\n                print(\"Respuesta incorrecta, intenta nuevamente.\")\n    \n    casas_mas_probables = []\n\n    for i in houses_points.keys():\n        casas_mas_probables.append((houses_points[i], i))\n    casas_mas_probables.sort(reverse=True)\n    \n    casa_mas_probable = 0\n    \n    if casas_mas_probables[0][0] == casas_mas_probables[1][0]:\n        print(\"La decision ha sido dificil...\")\n        casa_mas_probable = randint(0,1)\n    \n    return name, casas_mas_probables[casa_mas_probable][1]\n\nif __name__ == \"__main__\":\n    nombre_alumno, estancia = main()\n    print(\"¡%s, te ha tocado %s!\" % (nombre_alumno, estancia))\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/python/CesarCarmona30.py",
    "content": "'''\n  EJERCICIO\n'''\n\nimport random, time\n\nhouses = {\n  \"a\": [\"Frontend\", 0],\n  \"b\": [\"Backend\", 0],\n  \"c\": [\"Desarrollo de videojuegos\", 0],\n  \"d\": [\"Ciberseguridad\", 0]\n}\n\npets = {\n   \"Frontend\": \"𖤍\",\n   \"Backend\": \"𓅓\",\n   \"Desarrollo de videojuegos\": \"𓅛\",\n   \"Ciberseguridad\": \"𓃠\"\n}\n\nprint(f\"\"\"Bienvenido a la escuela de la programación de Hogwarts para magos y brujas del código.\nA continuación el sombrero te guiará a través de preguntas para encontrar tu camino hacia tu casa ideal.\nCuál de estás casas será la que te consolide...\\n\"\"\")\n\nfor house, animal in pets.items():\n   print(f'{animal} {house} {animal}')\n\nname = input(\"\\nEmpecemos... ¿Cuál es tu nombre?: \")\n\nquestions = [\n  { 1: \"¿Qué parte de un proyecto te resulta más interesante?\",\n    \"options\": {\n      \"a\": \"Crear una interfaz de usuario atractiva y fácil de usar.\",\n      \"b\": \"Desarrollar la lógica de negocio y gestionar bases de datos.\",\n      \"c\": \"Diseñar mecánicas y físicas de inmersivas.\",\n      \"d\": \"Asegurar la protección de los datos y prevenir ataques.\"\n    }},\n    { 2: \"¿Qué herramienta preferirías utilizar?\",\n    \"options\": {\n      \"a\": \"Figma o Sketch.\",\n      \"b\": \"Docker o Kubernetes.\",\n      \"c\": \"Unity o Unreal Engine.\",\n      \"d\": \"Wireshark o Burp Suite.\"\n    }},\n    { 3: \"¿Qué tipo de errores disfrutas resolver?\",\n    \"options\": {\n      \"a\": \"Fallos de estilo o funcionalidad en una página web.\",\n      \"b\": \"Bugs en la lógica del servidor o en una base de datos.\",\n      \"c\": \"Problemas de comportamiento o física en un juego.\",\n      \"d\": \"Vulnerabilidades en el sistema o posibles puntos de ataque.\"\n    }},\n    { 4: \"Lenguaje de programación (o tecnología) favorito:\",\n    \"options\": {\n      \"a\": \"JavaScript o TypeScript.\",\n      \"b\": \"Python, Java o Node.js.\",\n      \"c\": \"C++ o C#.\",\n      \"d\": \"C, Python o Bash.\"\n    }},\n    { 5: \"¿Qué prefieres optimizar en un proyecto?\",\n    \"options\": {\n      \"a\": \"La experiencia de usuario y la velocidad de carga de la interfaz.\",\n      \"b\": \"El rendimiento del servidor y las consultas de la base de datos.\",\n      \"c\": \"Los gráficos y la jugabilidad en tiempo real.\",\n      \"d\": \"La seguridad de los datos y la prevención de intrusiones.\"\n    }},\n    { 6: \"¿Qué tipo de desafíos te emocionan más?\",\n    \"options\": {\n      \"a\": \"Crear animaciones fluidas y transiciones en la interfaz.\",\n      \"b\": \"Diseñar una API robusta y eficiente.\",\n      \"c\": \"Implementar inteligencia artificial para NPCs en un videojuego.\",\n      \"d\": \"Descubrir y mitigar una nueva vulnerabilidad de seguridad.\"\n    }},\n    { 7: \"¿Qué tecnología te gustaría dominar?\",\n    \"options\": {\n      \"a\": \"React, Vue o Angular\",\n      \"b\": \"Express, Django o Flask\",\n      \"c\": \"Unreal Engine o Unity\",\n      \"d\": \"Metasploit o herramientas de análisis forense digital.\"\n    }},\n    { 8: \"¿En qué área preferirías trabajar a largo plazo?\",\n    \"options\": {\n      \"a\": \"Creación de interfaces y experiencias de usuario visuales.\",\n      \"b\": \"Diseño de la lógica interna y los servicios de backend.\",\n      \"c\": \"Desarrollo de mundos y mecánicas en videojuegos.\",\n      \"d\": \"Auditoría de seguridad y pentesting.\"\n    }},\n    { 9: \"¿Qué proyecto te resulta más atractivo?\",\n    \"options\": {\n      \"a\": \"Desarrollar una aplicación web interactiva y dinámica.\",\n      \"b\": \"Crear una API que sirva datos a múltiples plataformas.\",\n      \"c\": \"Desarrollar un videojuego inmersivo en 3D.\",\n      \"d\": \"Desarrollar un sistema de protección contra ataques DDoS.\"\n    }},\n    { 10: \"¿Qué prefieres como objetivo principal en tu trabajo?\",\n    \"options\": {\n      \"a\": \"Hacer que la aplicación sea visualmente atractiva y fácil de usar.\",\n      \"b\": \"Asegurarte de que la aplicación funcione sin problemas en el servidor.\",\n      \"c\": \"Crear una experiencia de juego envolvente y divertida.\",\n      \"d\": \"Garantizar que los sistemas estén seguros contra ataques.\"\n    }}\n]\n  \n\nfor id, question in enumerate(questions):\n  print(f\"\\nPregunta {id + 1}: {question[id + 1]}\")\n  for option, answer in question[\"options\"].items():\n    print(f\"{option}) {answer}\")\n\n  reply = input(\"Elige una opción:\\n>_ \").lower()\n\n  while reply not in question[\"options\"]:\n    reply = input(\"Opción no válida. Por favor intenta de nuevo. a) b) c) o d): \").lower()\n\n  houses[reply][1] += 1\n\nmax_score = max(house[1] for house in houses.values())\nwinning_houses = [house_name for house_name, house in houses.items() if house[1] == max_score]\n\nchosen_house = None\n\nprint(f\"¡Felicidades {name.capitalize()}!\")\n\nif len(winning_houses) > 1:\n    chosen_house_key = random.choice(winning_houses)\n    chosen_house = houses[chosen_house_key][0]\n    print(f\"¡La decisión ha sido complicada! Pero finalmente, el sombrero te ha asignado a la casa...\")\nelse:\n    chosen_house = houses[winning_houses[0]][0]\n    print(f\"El sombrero te ha asignado a la casa...\")\n\nfor sec in range(1, 4):\n   time.sleep(1)\n   print('.' * sec)\n\ntime.sleep(1)\nprint(f'{pets[chosen_house]}' * 20, end='')\nprint(f\"\\n──⊹¡{chosen_house.upper()}!⊹──\")\nprint(f'{pets[chosen_house]}' * 20, end='')"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/python/DavidVilem.py",
    "content": "\r\nimport random\r\n\r\n# Definimos las casas\r\ncasas = [\"Frontend\", \"Backend\", \"Mobile\", \"Data\"]\r\n\r\n# Definimos un diccionario para almacenar los puntos de cada casa\r\npuntos = {casa: 0 for casa in casas}\r\n\r\n# Preguntas y opciones \r\npreguntas = [\r\n    {\r\n        \"pregunta\": \"¿Cuál es tu lenguaje de programación favorito?\",\r\n        \"opciones\": {\r\n            \"a\": (\"JavaScript\", \"Frontend\"),\r\n            \"b\": (\"Python\", \"Backend\"),\r\n            \"c\": (\"Swift\", \"Mobile\"),\r\n            \"d\": (\"R\", \"Data\")\r\n        }\r\n    },\r\n    {\r\n        \"pregunta\": \"¿Qué tipo de proyectos te gusta más desarrollar?\",\r\n        \"opciones\": {\r\n            \"a\": (\"Aplicaciones web\", \"Frontend\"),\r\n            \"b\": (\"Sistemas distribuidos\", \"Backend\"),\r\n            \"c\": (\"Aplicaciones móviles\", \"Mobile\"),\r\n            \"d\": (\"Análisis de datos\", \"Data\")\r\n        }\r\n    },\r\n    {\r\n        \"pregunta\": \"¿Cuál es tu herramienta preferida para desarrollo?\",\r\n        \"opciones\": {\r\n            \"a\": (\"React\", \"Frontend\"),\r\n            \"b\": (\"Django\", \"Backend\"),\r\n            \"c\": (\"Flutter\", \"Mobile\"),\r\n            \"d\": (\"Pandas\", \"Data\")\r\n        }\r\n    },\r\n    {\r\n        \"pregunta\": \"¿Qué es lo que más valoras en un proyecto?\",\r\n        \"opciones\": {\r\n            \"a\": (\"Interfaz de usuario\", \"Frontend\"),\r\n            \"b\": (\"Rendimiento y escalabilidad\", \"Backend\"),\r\n            \"c\": (\"Compatibilidad en dispositivos\", \"Mobile\"),\r\n            \"d\": (\"Información y análisis\", \"Data\")\r\n        }\r\n    },\r\n    {\r\n        \"pregunta\": \"¿Cuál es tu entorno de trabajo favorito?\",\r\n        \"opciones\": {\r\n            \"a\": (\"Navegador\", \"Frontend\"),\r\n            \"b\": (\"Servidor\", \"Backend\"),\r\n            \"c\": (\"Dispositivo móvil\", \"Mobile\"),\r\n            \"d\": (\"Ambiente de análisis\", \"Data\")\r\n        }\r\n    },\r\n    {\r\n        \"pregunta\": \"¿Qué prefieres aprender en tu tiempo libre?\",\r\n        \"opciones\": {\r\n            \"a\": (\"Nuevas tecnologías web\", \"Frontend\"),\r\n            \"b\": (\"Arquitectura de software\", \"Backend\"),\r\n            \"c\": (\"Desarrollo de apps\", \"Mobile\"),\r\n            \"d\": (\"Machine learning\", \"Data\")\r\n        }\r\n    },\r\n    {\r\n        \"pregunta\": \"¿En qué tipo de equipo te gustaría trabajar?\",\r\n        \"opciones\": {\r\n            \"a\": (\"Equipo de UX/UI\", \"Frontend\"),\r\n            \"b\": (\"Equipo de DevOps\", \"Backend\"),\r\n            \"c\": (\"Equipo de desarrollo móvil\", \"Mobile\"),\r\n            \"d\": (\"Equipo de ciencia de datos\", \"Data\")\r\n        }\r\n    },\r\n    {\r\n        \"pregunta\": \"¿Qué consideras más desafiante?\",\r\n        \"opciones\": {\r\n            \"a\": (\"Diseño responsivo\", \"Frontend\"),\r\n            \"b\": (\"Optimización de consultas\", \"Backend\"),\r\n            \"c\": (\"Compatibilidad multiplataforma\", \"Mobile\"),\r\n            \"d\": (\"Limpieza de datos\", \"Data\")\r\n        }\r\n    },\r\n    {\r\n        \"pregunta\": \"¿Cuál es tu prioridad en un proyecto?\",\r\n        \"opciones\": {\r\n            \"a\": (\"Experiencia de usuario\", \"Frontend\"),\r\n            \"b\": (\"Seguridad\", \"Backend\"),\r\n            \"c\": (\"Accesibilidad\", \"Mobile\"),\r\n            \"d\": (\"Precisión de los resultados\", \"Data\")\r\n        }\r\n    },\r\n    {\r\n        \"pregunta\": \"¿Qué te motiva más?\",\r\n        \"opciones\": {\r\n            \"a\": (\"Crear interfaces atractivas\", \"Frontend\"),\r\n            \"b\": (\"Resolver problemas complejos\", \"Backend\"),\r\n            \"c\": (\"Desarrollar apps innovadoras\", \"Mobile\"),\r\n            \"d\": (\"Descubrir patrones en datos\", \"Data\")\r\n        }\r\n    }\r\n]\r\n\r\n# Solicitar el nombre del alumno\r\nnombre_alumno = input(\"¡Bienvenido al sombrero seleccionador! ¿Cuál es tu nombre? \")\r\n\r\n# Realizar las preguntas\r\nfor idx, pregunta in enumerate(preguntas):\r\n    print(f\"\\nPregunta {idx + 1}: {pregunta['pregunta']}\")\r\n    for opcion, (respuesta, casa) in pregunta[\"opciones\"].items():\r\n        print(f\"  {opcion}. {respuesta}\")\r\n    \r\n    eleccion = input(\"Elige una opción (a, b, c, d): \").lower()\r\n    \r\n    while eleccion not in pregunta[\"opciones\"]:\r\n        eleccion = input(\"Opción inválida. Por favor, elige entre a, b, c, d: \").lower()\r\n    \r\n    # Asignar puntos a la casa correspondiente\r\n    casa_asignada = pregunta[\"opciones\"][eleccion][1]\r\n    puntos[casa_asignada] += 1\r\n\r\n# Determinar la casa con mayor puntaje\r\nmax_puntos = max(puntos.values())\r\ncasas_ganadoras = [casa for casa, puntaje in puntos.items() if puntaje == max_puntos]\r\n\r\n# Resolver empates si es necesario\r\nif len(casas_ganadoras) > 1:\r\n    casa_final = random.choice(casas_ganadoras)\r\n    print(f\"\\n¡Vaya, {nombre_alumno}! El sombrero ha tenido una decisión difícil...\")\r\nelse:\r\n    casa_final = casas_ganadoras[0]\r\n\r\n# Mostrar el resultado final\r\nprint(f\"\\n{nombre_alumno}, has sido seleccionado para la casa de {casa_final}!\")"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/python/EmmanuelMMontesinos.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Cada 1 de septiembre, el Hogwarts Express parte hacia la escuela\n * de programación de Hogwarts para magos y brujas del código.\n * En ella, su famoso sombrero seleccionador ayuda a los programadores\n * a encontrar su camino...\n * Desarrolla un programa que simule el comportamiento del sombrero.\n * Requisitos:\n * 1. El sombrero realizará 10 preguntas para determinar la casa del alumno.\n * 2. Deben existir 4 casas. Por ejemplo: Frontend, Backend, Mobile y Data.\n *    (Puedes elegir las que quieras)\n * Acciones:\n * 1. Crea un programa que solicite el nombre del alumno y realice 10\n *    preguntas, con cuatro posibles respuestas cada una.\n * 2. Cada respuesta asigna puntos a cada una de las casas (a tu elección).\n * 3. Una vez finalizado, el sombrero indica el nombre del alumno \n *    y a qué casa pertenecerá (resuelve el posible empate de manera aleatoria,\n *    pero indicándole al alumno que la decisión ha sido complicada).\n */\n\"\"\"\n# importo choice para elegir al azar si hay empate\nfrom random import choice\n# Casas remplazables:\ncasas = {\n        0:\"Sofistas: Se enfocan en la retórica y la persuasión. Creen que la verdad es relativa y cambiante\",\n        1:\"Aristotélicos: Valoran la lógica, la observación empírica y el razonamiento estructurado. Buscan conocimiento a través de la experiencia\",\n        2:\"Platónicos: Creen en un mundo de ideas eterno e inmutable. Buscan verdades absolutas más allá de lo material\",\n        3:\"Epicúreos: Enfatizan la búsqueda del placer moderado y la eliminación del dolor como el objetivo principal de la vida\"\n        }\n\n# Preguntas remplazables:\npreguntas = {\n        1: \"¿Qué valoras más en un debate filosófico?\\n\"\n            \"A) La persuasión y la retórica\\n\"\n            \"B) La lógica y la evidencia empírica\\n\"\n            \"C) La búsqueda de verdades absolutas e inmutables\\n\"\n            \"D) La búsqueda del placer y la eliminación del dolor\",\n\n        2: \"¿Cuál es tu enfoque preferido para resolver problemas?\\n\"\n            \"A) Adaptarse y usar cualquier argumento disponible\\n\"\n            \"B) Analizar sistemáticamente los datos y llegar a una conclusión lógica\\n\"\n            \"C) Buscar en el mundo de las ideas para encontrar respuestas eternas\\n\"\n            \"D) Encontrar la solución que brinde mayor paz y felicidad\",\n\n        3: \"¿Qué opinas sobre la naturaleza de la realidad?\\n\"\n            \"A) La realidad es relativa y depende de la percepción individual\\n\"\n            \"B) La realidad está compuesta de sustancias y formas que podemos observar\\n\"\n            \"C) La verdadera realidad es el mundo de las ideas, más allá de lo material\\n\"\n            \"D) La realidad es material y nuestros sentidos son la clave para disfrutarla\",\n\n        4: \"¿Cómo crees que se debe enseñar la sabiduría?\\n\"\n            \"A) Mediante discursos convincentes y carismáticos\\n\"\n            \"B) A través de la lógica y el razonamiento estructurado\\n\"\n            \"C) Con diálogos que lleven al interlocutor a descubrir verdades universales\\n\"\n            \"D) Enseñando a las personas cómo vivir vidas placenteras y sin angustia\",\n\n        5: \"¿Cuál es el mayor objetivo de la vida?\\n\"\n            \"A) Ser capaz de influir y convencer a los demás\\n\"\n            \"B) Alcanzar el conocimiento a través de la observación y el estudio\\n\"\n            \"C) Comprender las verdades fundamentales del universo\\n\"\n            \"D) Vivir en tranquilidad y evitar el sufrimiento\",\n\n        6: \"¿Qué piensas sobre el placer?\\n\"\n            \"A) Es un medio para persuadir y manipular opiniones\\n\"\n            \"B) El placer debe ser controlado por la razón y la ética\\n\"\n            \"C) Es secundario en la búsqueda de la verdad\\n\"\n            \"D) Es el objetivo principal de la vida, pero debe buscarse con prudencia\",\n\n        7: \"¿Cómo responderías a una crítica?\\n\"\n            \"A) Usando argumentos retóricos y desviando el tema\\n\"\n            \"B) Presentando evidencia lógica y razonada\\n\"\n            \"C) Invitando a un diálogo filosófico para encontrar la verdad subyacente\\n\"\n            \"D) Buscando un entendimiento mutuo para minimizar el conflicto\",\n\n        8: \"¿Qué es más importante: la apariencia o la realidad?\\n\"\n            \"A) La apariencia, ya que es lo que perciben los demás\\n\"\n            \"B) La realidad, que se puede comprender a través de la experiencia\\n\"\n            \"C) La realidad ideal y eterna más allá de las apariencias\\n\"\n            \"D) La realidad, en tanto proporciona placer y evita el dolor\",\n\n        9: \"¿Qué tipo de conocimiento valoras más?\\n\"\n            \"A) El conocimiento práctico que se puede aplicar en la vida cotidiana\\n\"\n            \"B) El conocimiento científico y empírico\\n\"\n            \"C) El conocimiento de las ideas y principios eternos\\n\"\n            \"D) El conocimiento que nos lleva a una vida feliz y sin estrés\",\n\n        10: \"¿Cómo describirías la verdad?\\n\"\n            \"A) La verdad es relativa y puede cambiar\\n\"\n            \"B) La verdad es objetiva y puede descubrirse a través de la investigación\\n\"\n            \"C) La verdad es una realidad abstracta y eterna\\n\"\n            \"D) La verdad es aquello que conduce al bienestar\"\n    }\n\nclass Sombrero:\n    def __init__(self) -> None:\n        self.calificacion = {\n            \"a\":0,\n            \"b\":0,\n            \"c\":0,\n            \"d\":0,\n            }\n        self.casas = casas\n        self.preguntas = preguntas\n\n    def puntuar_pregunta(self,num,pregunta):\n        check = False\n\n        while not check:\n            print(f\"Pregunta - {num}\\n{pregunta}\")\n            respuesta = input(\"\").lower()\n            check = True\n            match respuesta:\n                case \"a\":\n                    self.calificacion[respuesta] += 1\n                    \n                case \"b\":\n                    self.calificacion[respuesta] += 1\n\n                case \"c\":\n                    self.calificacion[respuesta] += 1\n\n                case \"d\":\n                    self.calificacion[respuesta] += 1\n                \n                case _:\n                    print(f\"{respuesta} no es una de las opciones disponibles {self.nombre}\")\n                    check = False\n\n    def asignar_mi_casa(self,resultado):\n        match resultado[0]:\n            case \"a\":\n                self.mi_casa = self.casas[0]\n\n            case \"b\":\n                self.mi_casa = self.casas[1]\n\n            case \"c\":\n                self.mi_casa = self.casas[2]\n\n            case \"d\":\n                self.mi_casa = self.casas[3]\n\n    def asignar_casa(self):\n        resultado = [\"\",0]\n        final = []\n        for respuesta, cantidad in self.calificacion.items():\n            if cantidad > resultado[1]:\n                resultado = [respuesta,cantidad]\n                final = [[respuesta,cantidad]]\n            elif cantidad == resultado[1]:\n                resultado = [respuesta,cantidad]\n                final.append([respuesta,cantidad])\n            \n        if len(final) == 1:\n            self.asignar_mi_casa(final[0])\n        elif len(final) > 1:\n            self.asignar_mi_casa(choice(final))\n            print(\"Esta siendo difícil.\\nPodrías ir a esta... pero...\")\n\n    def hablar_sombrero(self):\n\n        print(\"Parece que tenemos un nuevo alumno! No seas tímido, ¿Cuál es tu nombre?\")\n        self.nombre = input(\"\").capitalize()\n        print(f\"Un placer {self.nombre}, ahora voy ha hacerte una serie de preguntas\")\n        print(\"Esta son las casas:\")\n        print(\"--------------------\")\n        for casa in self.casas.values():\n            print()\n            print(casa)\n        print(\"--------------------\")\n        \n        input(\"Responde con la letra que corresponda\\nenter para empezar preguntas: \")\n        for num,pregunta in self.preguntas.items():\n            print()\n            self.puntuar_pregunta(num,pregunta)\n\n        self.asignar_casa()\n        print(f\"{self.calificacion}\\n{self.nombre} tu casa será:\\n{self.mi_casa}\")\n\n# Prueba\nemmanuel = Sombrero()\nemmanuel.hablar_sombrero()"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/python/Gordo-Master.py",
    "content": "# 36- El sombrero selecionador\nimport random\n\nquestions = {}\n\nfor i in range(1, 11):\n    questions[i] = ['a','b','c','d']\n\nclass SortingHat():\n\n    def __init__(self, questions: dict):\n        self.questions = questions\n\n    def ask_questions(self) -> dict:\n        frontend = 0\n        backend = 0\n        mobile = 0\n        data = 0\n\n        for quest in self.questions:\n            print(f\"Pregunta: {quest}\")\n            print(f\"Opciones: \")\n            for index, responses in enumerate(self.questions[quest]):\n                print(f\"{index+1}. {responses}\")\n            while True:\n                response = input(\"Respuesta elegida: \")\n                match response:\n                    case '1':\n                        frontend += 1\n                        break\n                    case '2':\n                        backend += 1\n                        break\n                    case '3':\n                        mobile += 1\n                        break\n                    case '4':\n                        data += 1\n                        break\n                    case _:\n                        print(\"Valor incorrecto, vuelve a intentar\")\n        return {\n            'frontend': frontend,\n            'backend' : backend,\n            'mobile' :mobile,\n            'data' : data\n        }\n    \n    def election(self, results: dict, name):\n        max_afinity = max([x for x in results.values()])\n        afinity = {k: v for k, v in results.items() if v == max_afinity}\n        if len(afinity) > 1:\n            final_election = random.choice(list(afinity.keys()))\n            print(\n                f\"\"\"\\nHmmmm... Ha sido una decisión muy complicada, {\n                    name}.\\n¡Pero finalmente tu casa será {final_election}!\"\"\"\n                )\n        else:\n            final_election = list(afinity.keys())[0]\n            print(f\"\\nEnhorabuena, {name}.\\n¡Tu casa será {final_election}!\")\n\n\nprint(\"\\n¡Bienvenido a Hogwarts, la escuela de programación para magos y brujas del código!\")\nprint(\"El sombrero seleccionador decidirá cuál es tu casa como programador.\")\n\nname = input(\"\\n¿Cuál es tu nombre? \")\n\nsortinghat = SortingHat(questions)\n\nsortinghat.election(sortinghat.ask_questions(), name)"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/python/JesusWay69.py",
    "content": "import os, platform, random\n\nif (platform.platform().startswith(\"macOS\") or platform.platform().startswith(\"Linux\")):\n    os.system('clear')\nelse:\n    os.system('cls')\n\n\n\"\"\" * EJERCICIO:\n * Cada 1 de septiembre, el Hogwarts Express parte hacia la escuela\n * de programación de Hogwarts para magos y brujas del código.\n * En ella, su famoso sombrero seleccionador ayuda a los programadores\n * a encontrar su camino...\n * Desarrolla un programa que simule el comportamiento del sombrero.\n * Requisitos:\n * 1. El sombrero realizará 10 preguntas para determinar la casa del alumno.\n * 2. Deben existir 4 casas. Por ejemplo: Frontend, Backend, Mobile y Data.\n *    (Puedes elegir las que quieras)\n * Acciones:\n * 1. Crea un programa que solicite el nombre del alumno y realice 10\n *    preguntas, con cuatro posibles respuestas cada una.\n * 2. Cada respuesta asigna puntos a cada una de las casas (a tu elección).\n * 3. Una vez finalizado, el sombrero indica el nombre del alumno \n *    y a qué casa pertenecerá (resuelve el posible empate de manera aleatoria,\n *    pero indicándole al alumno que la decisión ha sido complicada).\"\"\"\n\n\nhouses_score = [0,0,0,0]\nhouses_dict = {\"Frontend\":0, \"Backend\":0, \"Mobile\":0 , \"Data\":0}\n\npoints_distribution =  [{1:[1,4,2,6],2:[1,6,2,4],3:[1,4,6,2],4:[6,1,4,2]},\n                        {1:[2,4,6,1],2:[6,1,4,2],3:[1,4,2,6],4:[2,6,1,4]},\n                        {1:[1,2,4,6],2:[6,1,4,2],3:[1,6,2,4],4:[1,2,6,4]},\n                        {1:[1,4,6,2],2:[1,4,2,6],3:[1,6,4,2],4:[6,1,4,2]},\n                        {1:[1,6,2,4],2:[2,1,6,4],3:[6,2,4,1],4:[2,1,4,6]},\n                        {1:[1,6,2,4],2:[6,1,4,2],3:[1,4,2,6],4:[4,1,6,2]},\n                        {1:[1,6,2,4],2:[6,2,4,1],3:[1,4,2,6],4:[4,1,6,2]},\n                        {1:[1,6,4,2],2:[2,4,1,6],3:[4,2,6,1],4:[6,2,4,1]},\n                        {1:[6,2,1,4],2:[4,2,1,6],3:[4,6,1,2],4:[1,4,6,2]},\n                        {1:[6,1,4,2],2:[2,6,4,1],3:[4,2,6,1],4:[2,1,4,6]}]\n\nquestions = {\"\\nPregunta 1: ¿Cual de estas definiciones se ajusta más a tu personalidad?\":\n             [\"1 - Analítico, me gusta tener todo perféctamente calculado\",\n             \"2 - Introvertido, me gusta tener perfil bajo y trabajar en la sombra\",\n             \"3 - Nómada digital, me gusta viajar pero estar siempre conectado\",\n             \"4 - Creativo, me gusta enseñar mis obras y disfruto con el estilo\"],\n\n              \"\\nPregunta 2: ¿Cual de estas tecnologías te gusta más?\":\n              [\"1 - Kotlin\", \"2 - CSS\", \"3 - MySQL\", \"4 - Python\"],\n\n              \"\\nPregunta 3: ¿Cual de estos dispositivos portátiles preferirías como regalo?\":\n              [\"1 - Un Chromebook\", \"2 - Un iPad con apple pencil\", \"3 - Un laptop con Arch Linux\", \"4 - Un smartphone de gama alta\"],\n\n              \"\\nPregunta 4: ¿Cual de estas asignaturas te gusta o te gustó más estudiar?\":\n              [\"1 - Telecomunicaciones\", \"2 - Matemáticas\", \"3 - Robótica\", \"4 - Dibujo artístico\"],\n\n              \"\\nPregunta 5: ¿Cual de 4 películas según tu personalidad crees que más se adapte a ti por temática?, (si no la has visto busca la sinopsis)\":\n              [\"1 - El indomable will Hunting--back\", \"2 - Her--mobile\", \"3 - Ghost in the shell--front\", \"4 - Moneyball--data\"],\n\n              \"\\nPregunta 6: ¿Cual de estos coches crees que va mejor contigo?\":[\"1 - Cualquier utilitario barato, funcional y discreto\",\n              \"2 - Uno con estilo tipo Fiat 500 o Mini Cooper\", \"3 - El que mejor relación específica tenga entre CV/Cilindrada/Consumo\",\n              \"4 - Un Tesla o similar, que sea eléctrico y con conectividad de todo tipo con mi smartphone a bordo y en remoto\"],\n\n              \"\\nPregunta 7: ¿Cual de estas carreras hubieses elegido de no haber sido la de informática?\":[\"1 - Cualquier otra ingeniería\",\n              \"2 - Bellas artes\", \"3 - Sin duda administración de empresas\", \"4 - Si existe, alguna que estudie nanotecnología\"],\n\n              \"\\nPregunta 8: Otra de tecnologías , ¿Cual de estas te gusta más?\":[\"1 - Java\", \"2 - MongoDB\", \"3 - Swift\", \"4 - Tailwind\"],\n\n              \"\\nPregunta 9: ¿Qué programa/aplicación de estas te gusta o usas más?\":[\"1 - Google Chrome\", \"2 - PowerBI\", \"3 - VScode\", \"4 - Android Studio\"],\n\n              \"\\nPregunta 10: ¿Cual de estas características de la marca Apple crees que es más importante en su éxito?\":\n                [\"1 - Su interfaz visual , el diseño de sus dispositivos, su enfoque hacia el mundo creativo y visual y su framework gráfico SwiftUI\",\n                 \"2 - Su lenguaje propio Swift y lo buenos y productivos que son sus ordenadores para trabajo con cualquier lenguaje de programación en general\"\n                 \"3 - Sus dispositivos y los sistemas operativos iOS, IpadOS, watchOS, tvOS y sobre todo la joya de la corona, el iPhone\",\n                 \"4 - Su capacidad de innovación y de mantenerse siempre en los ranking de ventas, 9 de cada 10 personas en el mundo conocen a Apple\"]\n              }\n\n\nname = input(\"introduzca su nombre: \").title()\n\ndef points_management(answer:int, round:int):\n    distribution_question:dict = points_distribution[round-1]\n    distribution_answer:list = distribution_question[answer]\n    for points in range (0,len(houses_score),1):\n            \n            houses_score[points] = houses_score[points] + distribution_answer[points]\n            \ndef quest_printer(questions:dict):\n    round = 0\n    for question in list(questions.keys()):  \n        print(question)\n        for answers in questions[question]:\n            print(answers)\n        answer = input(\"Elija una de las 4 opciones--> \")\n        while not answer.isdigit() or int(answer) < 1 or int(answer) > 4:\n            print(\"Sólo se pueden introducir números del 1 al 4, pruebe de nuevo\")\n            answer = input(\"Elija una de las 4 opciones--> \")\n            \n        round += 1\n        points_management(int(answer), round)\n\nquest_printer(questions)\n\ntie = False\nfor result in houses_score:\n    while houses_score.count(result) > 1: \n        my_bool = random.randint(0, 1)\n        bool(my_bool)  \n        if bool:\n            result -= 1\n        tie = True\n          \nhouses_dict[\"Frontend\"] = houses_score[0]\nhouses_dict[\"Backend\"] = houses_score[1]\nhouses_dict[\"Mobile\"] = houses_score[2]\nhouses_dict[\"Data\"] = houses_score[3]\nwin = max(houses_dict.items(), key=lambda x: x[1])[0]\n\nprint(f\"Por las respuestas que has dado {name} parece que el sector de programación que más se adapta a ti es el de {win}\")\nif tie:\n    print(\"Pero la decisión ha sido difícil\")\n\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/python/JohnAlexGuerrero.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"#36-el-sombrero-seleccionador.ipynb\n\nAutomatically generated by Colab.\n\nOriginal file is located at\n    https://colab.research.google.com/drive/1FeZc3xRWVqqOFn7EfMpHUBIU0IFGdOFh\n\n* EJERCICIO:\n * Cada 1 de septiembre, el Hogwarts Express parte hacia la escuela\n * de programación de Hogwarts para magos y brujas del código.\n * En ella, su famoso sombrero seleccionador ayuda a los programadores\n * a encontrar su camino...\n * Desarrolla un programa que simule el comportamiento del sombrero.\n * Requisitos:\n * 1. El sombrero realizará 10 preguntas para determinar la casa del alumno.\n * 2. Deben existir 4 casas. Por ejemplo: Frontend, Backend, Mobile y Data.\n *    (Puedes elegir las que quieras)\n * Acciones:\n * 1. Crea un programa que solicite el nombre del alumno y realice 10\n *    preguntas, con cuatro posibles respuestas cada una.\n * 2. Cada respuesta asigna puntos a cada una de las casas (a tu elección).\n * 3. Una vez finalizado, el sombrero indica el nombre del alumno\n *    y a qué casa pertenecerá (resuelve el posible empate de manera aleatoria,\n *    pero indicándole al alumno que la decisión ha sido complicada).\n\"\"\"\n\npreguntas_respuestas = [\n\n    # Frontend\n        {\n        \"id\":1,\n        \"pregunta\": \"¿Cuál de los siguientes lenguajes se utiliza comúnmente para diseñar el aspecto visual de una página web?\",\n        \"respuestas\": {\n            \"a\": \"HTML\",\n            \"b\": \"Java\",\n            \"c\": \"CSS\",  # Correcta\n            \"d\": \"Python\"\n        } ,\n        \"correcta\": \"c\",\n        \"casa\":\"fronted\"\n    },\n    {\n        \"id\":2,\n        \"pregunta\": \"¿Cuál es el propósito principal de JavaScript en el desarrollo web frontend?\",\n        \"respuestas\": {\n            \"a\": \"Crear gráficos 3D\",\n            \"b\": \"Añadir interactividad a las páginas web\",  # Correcta\n            \"c\": \"Definir la estructura de una página\",\n            \"d\": \"Estilizar la página web\"\n        },\n        \"correcta\": \"b\",\n        \"casa\":\"fronted\"\n    },\n    {\n        \"id\":3,\n        \"pregunta\": \"¿Cuál de los siguientes frameworks es utilizado principalmente para el desarrollo frontend?\",\n        \"respuestas\": {\n            \"a\": \"Django\",\n            \"b\": \"Flask\",\n            \"c\": \"React\",  # Correcta\n            \"d\": \"PostgreSQL\"\n        },\n        \"correcta\": \"c\"\n    },\n    {\n        \"id\":4,\n        \"pregunta\": \"¿Qué propiedad CSS se usa para cambiar el tamaño de un elemento?\",\n        \"respuestas\": {\n            \"a\": \"color\",\n            \"b\": \"margin\",\n            \"c\": \"width\",  # Correcta\n            \"d\": \"display\"\n        },\n        \"correcta\": \"c\",\n        \"casa\":\"fronted\"\n    },\n\n    # Backend\n    {\n        \"id\":5,\n        \"pregunta\": \"¿Cuál de los siguientes lenguajes es más comúnmente usado para el desarrollo backend?\",\n        \"respuestas\": {\n            \"a\": \"CSS\",\n            \"b\": \"JavaScript\",\n            \"c\": \"Python\",  # Correcta\n            \"d\": \"HTML\"\n        },\n        \"correcta\": \"c\",\n        \"casa\":\"backend\"\n    },\n    {\n        \"id\":6,\n        \"pregunta\": \"¿Qué es una API en el contexto de desarrollo backend?\",\n        \"respuestas\": {\n            \"a\": \"Una biblioteca para crear gráficos\",\n            \"b\": \"Un método de autenticación\",\n            \"c\": \"Una interfaz para que las aplicaciones se comuniquen\",  # Correcta\n            \"d\": \"Una base de datos\"\n        },\n        \"correcta\": \"c\",\n        \"casa\":\"backend\"\n    },\n    {\n        \"id\":7,\n        \"pregunta\": \"¿Cuál es un ejemplo de un servidor de aplicaciones backend?\",\n        \"respuestas\": {\n            \"a\": \"Apache\",  # Correcta\n            \"b\": \"Bootstrap\",\n            \"c\": \"React\",\n            \"d\": \"MySQL\"\n        },\n        \"correcta\": \"a\",\n        \"casa\":\"backend\"\n    },\n    {\n        \"id\":8,\n        \"pregunta\": \"¿Qué tipo de base de datos utiliza SQL?\",\n        \"respuestas\": {\n            \"a\": \"NoSQL\",\n            \"b\": \"Relacional\",  # Correcta\n            \"c\": \"Archivo plano\",\n            \"d\": \"Jerárquica\"\n        },\n        \"correcta\": \"b\",\n        \"casa\":\"backend\"\n    },\n\n    # Data\n    {\n        \"id\":9,\n        \"pregunta\": \"¿Qué lenguaje es más popular para el análisis de datos?\",\n        \"respuestas\": {\n            \"a\": \"Java\",\n            \"b\": \"R\",  # Correcta\n            \"c\": \"C++\",\n            \"d\": \"PHP\"\n        },\n        \"correcta\": \"b\",\n        \"casa\":\"data\"\n    },\n    {\n        \"id\":10,\n        \"pregunta\": \"¿Qué biblioteca de Python es ampliamente utilizada para el análisis de datos?\",\n        \"respuestas\": {\n            \"a\": \"TensorFlow\",\n            \"b\": \"Django\",\n            \"c\": \"pandas\",  # Correcta\n            \"d\": \"Flask\"\n        },\n        \"correcta\": \"c\",\n        \"casa\":\"data\"\n    },\n    {\n        \"id\":11,\n        \"pregunta\": \"¿Qué significa el término 'Big Data'?\",\n        \"respuestas\": {\n            \"a\": \"Pequeñas cantidades de datos\",\n            \"b\": \"Un proceso de minería de datos\",\n            \"c\": \"Conjuntos de datos extremadamente grandes\",  # Correcta\n            \"d\": \"Una estructura de base de datos\"\n        },\n        \"correcta\": \"c\",\n        \"casa\":\"data\"\n    },\n    {\n        \"id\":12,\n        \"pregunta\": \"¿Cuál es la principal ventaja de una base de datos NoSQL sobre una base de datos relacional?\",\n        \"respuestas\": {\n            \"a\": \"Soporte para transacciones ACID\",\n            \"b\": \"Mejor rendimiento en grandes cantidades de datos no estructurados\",  # Correcta\n            \"c\": \"Mayor seguridad\",\n            \"d\": \"Compatibilidad con SQL\"\n        },\n        \"correcta\": \"b\",\n        \"casa\":\"data\"\n    },\n\n    # Mobile\n    {\n        \"id\":13,\n        \"pregunta\": \"¿Qué lenguaje es usado principalmente para el desarrollo nativo de aplicaciones Android?\",\n        \"respuestas\": {\n            \"a\": \"Swift\",\n            \"b\": \"Kotlin\",  # Correcta\n            \"c\": \"JavaScript\",\n            \"d\": \"C#\"\n        },\n        \"correcta\": \"b\",\n        \"casa\":\"mobile\"\n    },\n    {\n        \"id\":14,\n        \"pregunta\": \"¿Qué lenguaje se utiliza para desarrollar aplicaciones nativas de iOS?\",\n        \"respuestas\": {\n            \"a\": \"Java\",\n            \"b\": \"Python\",\n            \"c\": \"Swift\",  # Correcta\n            \"d\": \"Ruby\"\n        },\n        \"correcta\": \"c\",\n        \"casa\":\"mobile\"\n    },\n    {\n        \"id\":15,\n        \"pregunta\": \"¿Cuál de las siguientes plataformas permite el desarrollo de aplicaciones móviles multiplataforma?\",\n        \"respuestas\": {\n            \"a\": \"Xcode\",\n            \"b\": \"Android Studio\",\n            \"c\": \"Flutter\",  # Correcta\n            \"d\": \"Jupyter Notebook\"\n        },\n        \"correcta\": \"c\",\n        \"casa\":\"mobile\"\n    }\n]\n\nimport math\nimport random\n\n#alumno candidato para ingresar a la escuela de programacion de Hogwarts\nclass Alumno:\n\n  def __init__(self, nombre):\n    self.nombre = nombre\n\n#sombrero que realiza un test para asignar a un alumno a una casa de programacion en Hogwarts\nclass Sombrero:\n\n  def __init__(self, alumno, preguntas):\n    self.alumno = alumno\n    self.preguntas = preguntas\n    self.puntuacion = {\n        \"fronted\": 0,\n        \"backend\": 0,\n        \"mobile\": 0,\n        \"data\": 0\n    }\n    self.escuelas = [\n          {\n            \"casa\":\"fronted\",\n            \"alumnos\":[],\n          },\n          {\n          \"casa\":\"backend\",\n          \"alumnos\":[],\n          },\n          {\n          \"casa\":\"mobile\",\n          \"alumnos\":[]\n          },\n          {\n          \"casa\":\"data\",\n          \"alumnos\":[]\n          }\n        ]\n\n  def test(self):\n    pass\n\n  def seleccionar_pregunta(self):\n    index_pregunta = random.randint(1, len(self.preguntas))\n    res = self.preguntas[index_pregunta - 1]\n    return res\n\n  def adicionar_punto_casa(self, nombre_casa):\n    self.puntuacion[nombre_casa] += 1\n\n  def restar_punto_casa(self, nombre_casa):\n    if self.puntuacion[nombre_casa] == 0:\n      return\n    self.puntuacion[nombre_casa] -= 1\n\n  def mostrar_puntuacion(self):\n    return self.puntuacion\n\n  def asignar_casa_ganadora(self):\n    casa = [(k, v) for k, v in self.puntuacion.items() if v > 2]\n    print(casa)\n    #return casa\n\ncandidatos = ['Juan Gabriel','Peter Ortiz','John Guerrero']\n\nfor name in candidatos:\n  total_preguntas = 0\n  print('Bienvenido a la Escuela de Programación de Hagwarts\\n')\n  print('cual es tu nombre?: ')\n  print(f'hola, {name}')\n\n  al = Alumno(name)\n  s = Sombrero(al, preguntas_respuestas)\n\n  while total_preguntas <= 10:\n    total_preguntas += 1\n    pregunta = s.seleccionar_pregunta()\n\n    print(f'N. pregunta: {total_preguntas}')\n    nombre_casa = pregunta[\"casa\"]\n    print(pregunta[\"pregunta\"])\n    print('='*len(pregunta['pregunta']))\n\n    print('RESPUESTAS: \\n')\n    for key, value in pregunta['respuestas'].items():\n      print(f'{key}: {value}')\n\n    respuesta = str(input('Cual es la respuesta? '))\n    if respuesta == pregunta['correcta']:\n      print(\"Respuesta correcta\")\n      s.adicionar_punto_casa(nombre_casa)\n    elif respuesta != pregunta['correcta']:\n      print(\"Respuesta incorrecta\")\n      s.restar_punto_casa(nombre_casa)\n\n    print(s.mostrar_puntuacion())\n    print(s.asignar_casa_ganadora())\n    print('='*50)"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/python/Nicojsuarez2.py",
    "content": "# #36 EL SOMBRERO SELECCIONADOR\n> #### Dificultad: Fácil | Publicación: 02/09/24 | Corrección: 09/09/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Cada 1 de septiembre, el Hogwarts Express parte hacia la escuela\n * de programación de Hogwarts para magos y brujas del código.\n * En ella, su famoso sombrero seleccionador ayuda a los programadores\n * a encontrar su camino...\n * Desarrolla un programa que simule el comportamiento del sombrero.\n * Requisitos:\n * 1. El sombrero realizará 10 preguntas para determinar la casa del alumno.\n * 2. Deben existir 4 casas. Por ejemplo: Frontend, Backend, Mobile y Data.\n *    (Puedes elegir las que quieras)\n * Acciones:\n * 1. Crea un programa que solicite el nombre del alumno y realice 10\n *    preguntas, con cuatro posibles respuestas cada una.\n * 2. Cada respuesta asigna puntos a cada una de las casas (a tu elección).\n * 3. Una vez finalizado, el sombrero indica el nombre del alumno \n *    y a qué casa pertenecerá (resuelve el posible empate de manera aleatoria,\n *    pero indicándole al alumno que la decisión ha sido complicada).\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/python/SooHav.py",
    "content": "# 36 EL SOMBRERO SELECCIONADOR\n\ndef menu():\n    while True:\n        print(\"\\nMenú:\")\n        print(\"1. Responder preguntas del sombrero\")\n        print(\"2. Calcular puntos\")\n        print(\"3. Asignar casa\")\n        print(\"4. Salir\")\n        opcion = input(\"Ingrese una opción: \")\n        try:\n            return int(opcion)\n        except ValueError:\n            print(\"Opción inválida. Por favor, ingrese un número entero.\")\n\n\nlista_preguntas = {\n    \"1. ¿Qué es una base de datos NoSQL y cuándo es preferible utilizarla en lugar de una base de datos relacional?\": {\n        \"a\": {\"respuesta\": \"Una base de datos NoSQL es un sistema de gestión de bases de datos que no se basa en el modelo relacional tradicional de tablas, filas y columnas.\", \"puntaje\": 10, \"habilidad\": \"Data\"},\n        \"b\": {\"respuesta\": \"Las bases de datos NoSQL son ideales para aplicaciones que requieren almacenar grandes cantidades de datos con alta disponibilidad y baja latencia.\", \"puntaje\": 10, \"habilidad\": \"Backend\"},\n        \"c\": {\"respuesta\": \"Las bases de datos NoSQL ofrecen una variedad de modelos de datos, como documentos, clave-valor, gráficos y columnas, lo que permite elegir el modelo más adecuado para cada tipo de aplicación.\", \"puntaje\": 10, \"habilidad\": \"Data\"},\n        \"d\": {\"respuesta\": \"Las bases de datos NoSQL son más lentas y menos eficientes que las bases de datos relacionales.\", \"puntaje\": -5, \"habilidad\": None}\n    },\n    \"2. ¿Por qué es importante utilizar un sistema de control de versiones como Git?\": {\n        \"a\": {\"respuesta\": \"Git permite realizar un seguimiento de los cambios en el código a lo largo del tiempo.\", \"puntaje\": 5, \"habilidad\": \"Backend\"},\n        \"b\": {\"respuesta\": \"Git facilita la colaboración entre desarrolladores y permite revertir cambios si es necesario.\", \"puntaje\": 10, \"habilidad\": \"Backend\"},\n        \"c\": {\"respuesta\": \"Git solo se utiliza para almacenar código fuente.\", \"puntaje\": -5, \"habilidad\": None},\n        \"d\": {\"respuesta\": \"Git permite resolver conflictos de manera eficiente cuando varios desarrolladores modifican el mismo archivo al mismo tiempo.\", \"puntaje\": 10, \"habilidad\": \"Backend\"}\n    },\n    \"3. ¿Qué herramientas y plataformas se utilizan para el despliegue de aplicaciones web y móviles?\": {\n        \"a\": {\"respuesta\": \"Docker, Kubernetes.\", \"puntaje\": 10, \"habilidad\": \"Backend\"},\n        \"b\": {\"respuesta\": \"AWS, Azure, GCP.\", \"puntaje\": 10, \"habilidad\": \"Backend\"},\n        \"c\": {\"respuesta\": \"Flutter, React Native.\", \"puntaje\": 10, \"habilidad\": \"Mobile\"},\n        \"d\": {\"respuesta\": \"VSCode.\", \"puntaje\": -25, \"habilidad\": None}\n    },\n    \"4. ¿Cuáles son las operaciones más frecuentes que se realizan con Git?\": {\n        \"a\": {\"respuesta\": \"Clonar.\", \"puntaje\": 5, \"habilidad\": \"Backend\"},\n        \"b\": {\"respuesta\": \"Commit.\", \"puntaje\": 5, \"habilidad\": \"Backend\"},\n        \"c\": {\"respuesta\": \"Push y Pull.\", \"puntaje\": 10, \"habilidad\": \"Backend\"},\n        \"d\": {\"respuesta\": \"Rebase.\", \"puntaje\": -5, \"habilidad\": None}\n    },\n    \"5. ¿Cuáles son las ventajas de utilizar la nube?\": {\n        \"a\": {\"respuesta\": \"Escalabilidad.\", \"puntaje\": 10, \"habilidad\": \"Data\"},\n        \"b\": {\"respuesta\": \"Flexibilidad.\", \"puntaje\": 10, \"habilidad\": \"Backend\"},\n        \"c\": {\"respuesta\": \"Reducción de costos.\", \"puntaje\": 10, \"habilidad\": \"Data\"},\n        \"d\": {\"respuesta\": \"Menor seguridad.\", \"puntaje\": -15, \"habilidad\": None}\n    },\n    \"6. ¿Cuáles son los diferentes tipos de pruebas que se pueden realizar en un software?\": {\n        \"a\": {\"respuesta\": \"Las pruebas unitarias verifican el funcionamiento correcto de unidades individuales de código.\", \"puntaje\": 10, \"habilidad\": \"Backend\"},\n        \"b\": {\"respuesta\": \"Las pruebas de integración aseguran que los diferentes componentes de la aplicación interactúen correctamente.\", \"puntaje\": 10, \"habilidad\": \"Backend\"},\n        \"c\": {\"respuesta\": \"Las pruebas de aceptación validan que el software cumpla con los requisitos del usuario.\", \"puntaje\": 10, \"habilidad\": \"Frontend\"},\n        \"d\": {\"respuesta\": \"Las pruebas manuales permiten detectar errores que las pruebas automatizadas no pueden encontrar.\", \"puntaje\": -5, \"habilidad\": None}\n    },\n    \"7. ¿Cuáles son las principales diferencias entre HTML, CSS y JavaScript?\": {\n        \"a\": {\"respuesta\": \"HTML estructura el contenido de una página web, CSS define su estilo y apariencia, y JavaScript agrega interactividad y dinamismo.\", \"puntaje\": 10, \"habilidad\": \"Frontend\"},\n        \"b\": {\"respuesta\": \"HTML, CSS y JavaScript son sinónimos y se utilizan indistintamente para crear páginas web.\", \"puntaje\": -5, \"habilidad\": None},\n        \"c\": {\"respuesta\": \"HTML es el esqueleto, CSS la piel y JavaScript el cerebro de una página web.\", \"puntaje\": 10, \"habilidad\": \"Frontend\"},\n        \"d\": {\"respuesta\": \"JavaScript puede modificar el DOM (Document Object Model) creado por HTML y CSS para cambiar el contenido y el estilo de una página en tiempo real.\", \"puntaje\": 10, \"habilidad\": \"Frontend\"}\n    },\n    \"8. ¿Qué es un API y cuál es su función en una aplicación?\": {\n        \"a\": {\"respuesta\": \"Un API (Interfaz de Programación de Aplicaciones) es un conjunto de reglas y especificaciones que permiten que diferentes aplicaciones se comuniquen entre sí.\", \"puntaje\": 10, \"habilidad\": \"Backend\"},\n        \"b\": {\"respuesta\": \"En una aplicación web, el frontend utiliza un API para solicitar datos al backend y mostrarlos al usuario.\", \"puntaje\": 10, \"habilidad\": \"Frontend\"},\n        \"c\": {\"respuesta\": \"Un API es un lenguaje de programación utilizado para crear aplicaciones web.\", \"puntaje\": -15, \"habilidad\": None},\n        \"d\": {\"respuesta\": \"Las APIs permiten que diferentes aplicaciones se integren y compartan datos.\", \"puntaje\": 10, \"habilidad\": \"Backend\"}\n    },\n    \"9. ¿Cuáles son los principales métodos HTTP?\": {\n        \"a\": {\"respuesta\": \"GET se utiliza para obtener datos.\", \"puntaje\": 10, \"habilidad\": \"Frontend\"},\n        \"b\": {\"respuesta\": \"POST para crear nuevos recursos.\", \"puntaje\": 10, \"habilidad\": \"Backend\"},\n        \"c\": {\"respuesta\": \"PUT para actualizar recursos existentes.\", \"puntaje\": 10, \"habilidad\": \"Backend\"},\n        \"d\": {\"respuesta\": \"DELETE para eliminar recursos.\", \"puntaje\": 10, \"habilidad\": \"Backend\"}\n    },\n    \"10. ¿Cuál de las siguientes afirmaciones sobre el DOM (Document Object Model) es CORRECTA?\": {\n        \"a\": {\"respuesta\": \"El DOM es una estructura jerárquica que representa los elementos de una página web como objetos.\", \"puntaje\": 10, \"habilidad\": \"Frontend\"},\n        \"b\": {\"respuesta\": \"JavaScript es el lenguaje principal para manipular el DOM y crear interfaces interactivas.\", \"puntaje\": 10, \"habilidad\": \"Frontend\"},\n        \"c\": {\"respuesta\": \"El DOM es estatico y no se actualiza constantemente.\", \"puntaje\": -10, \"habilidad\": None},\n        \"d\": {\"respuesta\": \"JavaScript puede crear, modificar y eliminar elementos del DOM.\", \"puntaje\": 10, \"habilidad\": \"Frontend\"}\n    }\n}\n\nresultados = []\npuntaje_total = 0\nalumno = \"\"\n\nwhile True:\n    opcion = menu()\n\n    if opcion == 1:\n        if not alumno:\n            alumno = input(\n                \"Si quieres saber tu casa, ingresa tu nombre: \").lower()\n            print(f\"Soy el sombrero seleccionador! {\n                  alumno}, necesito que respondas algunas preguntas!\\n\")\n\n        # Mostrar preguntas\n        if not resultados:\n            for pregunta, respuestas in lista_preguntas.items():\n                print(pregunta)\n                for letra, detalles in respuestas.items():\n                    print(f\"{letra}) {detalles['respuesta']}\")\n                print()\n\n                puntos = input(f\"Ingrese su respuesta para '{\n                               pregunta}' (a, b, c o d): \")\n                print()\n                if puntos in respuestas:\n                    puntaje = respuestas[puntos][\"puntaje\"]\n                    resultados.append(puntaje)\n                else:\n                    print(\"Respuesta no válida, intenta nuevamente.\")\n\n        else:\n            print(\"Ya has respondido las preguntas. Pasa a la opción 2 para calcular tus puntos o la opción 3 para asignar casa.\\n\")\n\n    elif opcion == 2:\n        if resultados:\n            puntaje_total = sum(resultados)\n            print(f\"¡Excelente, {alumno}! Tu puntaje total es: {\n                  puntaje_total}\")\n        else:\n            print(\"Primero responde las preguntas en la opción 1.\\n\")\n\n    elif opcion == 3:\n        if puntaje_total:\n            if puntaje_total > 90:\n                print(f\"{alumno}, te he asignado a la casa Mobile.\")\n            elif 70 < puntaje_total <= 90:\n                print(f\"{alumno}, te he asignado a la casa Backend.\")\n            elif 60 < puntaje_total <= 70:\n                print(f\"{alumno}, te he asignado a la casa Frontend.\")\n            else:\n                print(f\"{alumno}, te he asignado a la casa Data.\")\n        else:\n            print(\"Primero calcula tu puntaje en la opción 2.\\n\")\n\n        if puntaje_total:\n            if 85 < puntaje_total < 95 or 65 < puntaje_total < 75 or 55 < puntaje_total < 65:\n                print(f\"La decisión fue muy difición de tomar!\")\n\n    elif opcion == 4:\n        print(\"¡Hasta el próximo año!\")\n        break\n    else:\n        print(\"Opción no válida. Intenta nuevamente.\")\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/python/adra-dev.py",
    "content": "\"\"\"\nEJERCICIO:\nCada 1 de septiembre el Hogwarts Express parte hacia la escuela de \nprogramación de Hogwarts para magos y brujas del código.\nEn ella, su famoso sombrero seleccionar ayuda a los programadores a\nencontrar su camino. . . \nDesarrolla un programa que simule el comportamiento del sombrero.\nRequisitos: \n1. El sombrero realizará 10 preguntas para determinar la casa del \nalumno.\n2. Deben existir 4 casas. Por ejemplo: Frontend, Backend, Mobile y \nData. (Puedes elegir las que quieras)\n1. Crea un programa que solicite el nombre del alumno y realice 10 \npreguntas, con cuatro posibles respuestas cada una.\n2. Cada respuesta asigna puntos a cada una de las casas (a tu \nelección). \n3. Una vez finalizado, el sombrero indica el nombre del alumno y a \nqué casa pertenecerá (resuelve el posible empate de manera aleatoria,\npero indicándole al alumno que la decisión ha sido complicada).\n\nby adra-dev\n\"\"\"\n\nimport random\n\n\nhouses = {\n    \"Frontend\": 0,\n    \"Backend\": 0,\n    \"Mobile\": 0,\n    \"Data\": 0\n}\n\nquestions = [\n    {\n        \"question\": \"¿Qué tipo de proyectos te interesa más desarrollar?\",\n        \"answers\": [\n            {\n                \"option\": \"Aplicaciones móviles nativas para múltiples plataformas.\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"Interfaces visualmente atractivas y responsivas.\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Procesamiento y análisis de grandes volúmenes de datos.\",\n                \"house\": \"Data\"\n            },\n            {\n                \"option\": \"Sistemas robustos y optimización de rendimiento del servidor.\",\n                \"house\": \"Backend\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Qué aspecto del desarrollo disfrutas más?\",\n        \"answers\": [\n            {\n                \"option\": \"Resolver problemas complejos de lógica y escalabilidad.\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"Analizar datos para tomar decisiones basadas en estadísticas.\",\n                \"house\": \"Data\"\n            },\n            {\n                \"option\": \"Crear aplicaciones móviles eficientes y funcionales.\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"Trabajar en el diseño y la experiencia de usuario.\",\n                \"house\": \"Frontend\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Qué herramienta prefieres usar en tu día a día?\",\n        \"answers\": [\n            {\n                \"option\": \"Kotlin o Swift para desarrollar apps móviles nativas.\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"Python o R para análisis de datos.\",\n                \"house\": \"Data\"\n            },\n            {\n                \"option\": \"Frameworks como React o Angular.\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Lenguajes como Node.js o Python para la gestión de servidores.\",\n                \"house\": \"Backend\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Cómo te ves en un equipo de desarrollo?\",\n        \"answers\": [\n            {\n                \"option\": \"Modelando datos y construyendo dashboards de análisis.\",\n                \"house\": \"Data\"\n            },\n            {\n                \"option\": \"Encargado de la lógica del servidor y las APIs.\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"Desarrollando la interfaz y funcionalidad de una app móvil.\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"Diseñando las interacciones y los componentes visuales.\",\n                \"house\": \"Frontend\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Qué te motiva más al trabajar en un proyecto?\",\n        \"answers\": [\n            {\n                \"option\": \"Ver cómo el diseño cobra vida en la pantalla.\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Descubrir insights a partir del análisis de datos.\",\n                \"house\": \"Data\"\n            },\n            {\n                \"option\": \"Optimizar el rendimiento y escalabilidad del sistema.\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"Lograr que una aplicación móvil funcione perfectamente en cualquier dispositivo.\",\n                \"house\": \"Mobile\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Cuál es tu enfoque al aprender nuevas tecnologías?\",\n        \"answers\": [\n            {\n                \"option\": \"Explorar técnicas avanzadas de análisis de datos y machine learning.\",\n                \"house\": \"Data\"\n            },\n            {\n                \"option\": \"Aprender sobre nuevas arquitecturas y lenguajes de servidor.\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"Probar nuevas plataformas y herramientas para desarrollo móvil.\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"Experimentar con nuevas librerías y frameworks de interfaz de usuario.\",\n                \"house\": \"Frontend\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Qué tipo de desafíos disfrutas más resolver?\",\n        \"answers\": [\n            {\n                \"option\": \"Solución de problemas de concurrencia y carga en servidores.\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"Optimización de interfaces para que se vean bien en cualquier dispositivo.\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Análisis de grandes volúmenes de datos para detectar patrones ocultos.\",\n                \"house\": \"Data\"},\n            {\n                \"option\": \"Creación de experiencias de usuario fluídas en dispositivos móviles.\",\n                \"house\": \"Mobile\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Cómo te gusta medir el éxito de tu trabajo?\",\n        \"answers\": [\n            {\n                \"option\": \"Por la estabilidad y rapidez del sistema bajo carga.\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"Mediante la satisfacción del usuario con la interfaz visual.\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Por la fluidez y buen rendimiento de la app móvil en diferentes dispositivos.\",\n                \"house\": \"Mobile\"},\n            {\n                \"option\": \"Por la precisión y relevancia de los resultados obtenidos en el análisis de datos.\",\n                \"house\": \"Data\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Qué te resulta más interesante al trabajar con tecnologías emergentes?\",\n        \"answers\": [\n            {\n                \"option\": \"Trabajar con tecnologías de big data o inteligencia artificial.\",\n                \"house\": \"Data\"\n            },\n            {\n                \"option\": \"Explorar nuevas arquitecturas para mejorar el rendimiento del servidor.\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"Probar nuevas herramientas y metodologías para mejorar el diseño y la UX.\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Desarrollar apps móviles que aprovechen nuevas capacidades de hardware.\",\n                \"house\": \"Mobile\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Cómo te enfrentas a un nuevo problema en un proyecto?\",\n        \"answers\": [\n            {\n                \"option\": \"Buscando patrones y soluciones basadas en análisis de datos.\",\n                \"house\": \"Data\"\n            },\n            {\n                \"option\": \"Replanteando la estructura visual y funcional de la interfaz.\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Explorando cómo mejorar la experiencia del usuario en dispositivos móviles.\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"Analizando la estructura de datos y la lógica del backend.\",\n                \"house\": \"Backend\"\n            }\n        ]\n    }\n]\n\nprint(\"\\n¡Bienvenido a Hogwarts, la escuela de programación para magos y brujas del código!\")\nprint(\"El sombrero seleccionador decidirá cuál es tu casa como programador.\")\n\nname = input(\"\\n¿Cuál es tu nombre? \")\n\nfor index, question in enumerate(questions):\n\n    print(f\"\\nPregunta {index + 1}: {question[\"question\"]}\\n\")\n\n    for i, answer in enumerate(question[\"answers\"]):\n        print(f\"{i + 1}. {answer[\"option\"]}\")\n\n    choice = int(input(\"\\nSelecciona una respuesta entre 1 y 4: \"))\n\n    selected_answer = question[\"answers\"][choice - 1]\n    houses[selected_answer[\"house\"]] += 1\n\nassigned_house = max(houses, key=houses.get)\nscores = list(houses.values())\n\nif scores.count(max(scores)) > 1:\n    possible_houses = [\n        house for house,\n        points in houses.items() if points == max(scores)\n    ]\n    assigned_house = random.choice(possible_houses)\n\n    print(\n        f\"\"\"\\nHmmmm... Ha sido una decisión muy complicada, {\n            name}.\\n¡Pero finalmente tu casa será {assigned_house}!\"\"\"\n    )\nelse:\n    print(f\"\\nEnhorabuena, {name}.\\n¡Tu casa será {assigned_house}!\")\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/python/arperezinf.py",
    "content": "import random\n\nhouses = {\n    \"Frontend\": 0,\n    \"Backend\": 0,\n    \"Mobile\": 0,\n    \"Data\": 0\n}\n\nquestions = [\n    {\n        \"question\": \"¿Qué tipo de proyectos te interesa más desarrollar?\",\n        \"answers\": [\n            {\n                \"option\": \"Aplicaciones móviles nativas para múltiples plataformas.\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"Interfaces visualmente atractivas y responsivas.\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Procesamiento y análisis de grandes volúmenes de datos.\",\n                \"house\": \"Data\"\n            },\n            {\n                \"option\": \"Sistemas robustos y optimización de rendimiento del servidor.\",\n                \"house\": \"Backend\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Qué aspecto del desarrollo disfrutas más?\",\n        \"answers\": [\n            {\n                \"option\": \"Resolver problemas complejos de lógica y escalabilidad.\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"Analizar datos para tomar decisiones basadas en estadísticas.\",\n                \"house\": \"Data\"\n            },\n            {\n                \"option\": \"Crear aplicaciones móviles eficientes y funcionales.\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"Trabajar en el diseño y la experiencia de usuario.\",\n                \"house\": \"Frontend\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Qué herramienta prefieres usar en tu día a día?\",\n        \"answers\": [\n            {\n                \"option\": \"Kotlin o Swift para desarrollar apps móviles nativas.\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"Python o R para análisis de datos.\",\n                \"house\": \"Data\"\n            },\n            {\n                \"option\": \"Frameworks como React o Angular.\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Lenguajes como Node.js o Python para la gestión de servidores.\",\n                \"house\": \"Backend\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Cómo te ves en un equipo de desarrollo?\",\n        \"answers\": [\n            {\n                \"option\": \"Modelando datos y construyendo dashboards de análisis.\",\n                \"house\": \"Data\"\n            },\n            {\n                \"option\": \"Encargado de la lógica del servidor y las APIs.\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"Desarrollando la interfaz y funcionalidad de una app móvil.\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"Diseñando las interacciones y los componentes visuales.\",\n                \"house\": \"Frontend\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Qué te motiva más al trabajar en un proyecto?\",\n        \"answers\": [\n            {\n                \"option\": \"Ver cómo el diseño cobra vida en la pantalla.\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Descubrir insights a partir del análisis de datos.\",\n                \"house\": \"Data\"\n            },\n            {\n                \"option\": \"Optimizar el rendimiento y escalabilidad del sistema.\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"Lograr que una aplicación móvil funcione perfectamente en cualquier dispositivo.\",\n                \"house\": \"Mobile\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Cuál es tu enfoque al aprender nuevas tecnologías?\",\n        \"answers\": [\n            {\n                \"option\": \"Explorar técnicas avanzadas de análisis de datos y machine learning.\",\n                \"house\": \"Data\"\n            },\n            {\n                \"option\": \"Aprender sobre nuevas arquitecturas y lenguajes de servidor.\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"Probar nuevas plataformas y herramientas para desarrollo móvil.\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"Experimentar con nuevas librerías y frameworks de interfaz de usuario.\",\n                \"house\": \"Frontend\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Qué tipo de desafíos disfrutas más resolver?\",\n        \"answers\": [\n            {\n                \"option\": \"Solución de problemas de concurrencia y carga en servidores.\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"Optimización de interfaces para que se vean bien en cualquier dispositivo.\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Análisis de grandes volúmenes de datos para detectar patrones ocultos.\",\n                \"house\": \"Data\"},\n            {\n                \"option\": \"Creación de experiencias de usuario fluídas en dispositivos móviles.\",\n                \"house\": \"Mobile\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Cómo te gusta medir el éxito de tu trabajo?\",\n        \"answers\": [\n            {\n                \"option\": \"Por la estabilidad y rapidez del sistema bajo carga.\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"Mediante la satisfacción del usuario con la interfaz visual.\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Por la fluidez y buen rendimiento de la app móvil en diferentes dispositivos.\",\n                \"house\": \"Mobile\"},\n            {\n                \"option\": \"Por la precisión y relevancia de los resultados obtenidos en el análisis de datos.\",\n                \"house\": \"Data\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Qué te resulta más interesante al trabajar con tecnologías emergentes?\",\n        \"answers\": [\n            {\n                \"option\": \"Trabajar con tecnologías de big data o inteligencia artificial.\",\n                \"house\": \"Data\"\n            },\n            {\n                \"option\": \"Explorar nuevas arquitecturas para mejorar el rendimiento del servidor.\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"Probar nuevas herramientas y metodologías para mejorar el diseño y la UX.\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Desarrollar apps móviles que aprovechen nuevas capacidades de hardware.\",\n                \"house\": \"Mobile\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Cómo te enfrentas a un nuevo problema en un proyecto?\",\n        \"answers\": [\n            {\n                \"option\": \"Buscando patrones y soluciones basadas en análisis de datos.\",\n                \"house\": \"Data\"\n            },\n            {\n                \"option\": \"Replanteando la estructura visual y funcional de la interfaz.\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Explorando cómo mejorar la experiencia del usuario en dispositivos móviles.\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"Analizando la estructura de datos y la lógica del backend.\",\n                \"house\": \"Backend\"\n            }\n        ]\n    }\n]\n\nprint(\"\\n¡Bienvenido a Hogwarts, la escuela de programación para magos y brujas del código!\")\nprint(\"El sombrero seleccionador decidirá cuál es tu casa como programador.\")\n\nname = input(\"\\n¿Cuál es tu nombre? \")\n\nfor index, question in enumerate(questions):\n\n    print(f\"\\nPregunta {index + 1}: {question[\"question\"]}\\n\")\n\n    for i, answer in enumerate(question[\"answers\"]):\n        print(f\"{i + 1}. {answer[\"option\"]}\")\n\n    choice = None\n    while choice not in range(1, 5):\n        try:\n            choice = int(input(\"\\nSelecciona una respuesta entre 1 y 4: \"))\n            if choice not in range(1, 5): \n                print(\"Por favor, selecciona un número válido entre 1 y 4.\")\n        except ValueError:\n            print(\"Entrada inválida. Por favor ingresa un número entre 1 y 4.\")\n\n    selected_answer = question[\"answers\"][choice - 1]\n    houses[selected_answer[\"house\"]] += 1\n\nassigned_house = max(houses, key=houses.get)\nscores = list(houses.values())\n\nif scores.count(max(scores)) > 1:\n    possible_houses = [\n        house for house,\n        points in houses.items() if points == max(scores)\n    ]\n    assigned_house = random.choice(possible_houses)\n\n    print(\n        f\"\"\"\\nHmmmm... Ha sido una decisión muy complicada, {\n            name}.\\n¡Pero finalmente tu casa será {assigned_house}!\"\"\"\n    )\nelse:\n    print(f\"\\nEnhorabuena, {name}.\\n¡Tu casa será {assigned_house}!\")\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/python/d1d4cum.py",
    "content": "import sys, random\nfrom typing import List\n\n\nclass Question:\n    question: str\n    answers: List[str]\n\n    def __init__(self, question, answers) -> None:\n        self.question = question\n        self.answers = answers\n\n\nquestions = [\n    Question(\n        \"¿Qué tipo de proyecto te interesa más desarrollar?\",\n        [\n            \"Crear una interfaz web atractiva y funcional\",\n            \"Diseñar una API robusta que gestione la lógica del negocio\",\n            \"Desarrollar una aplicación nativa para smartphones\",\n            \"Analizar grandes volúmenes de datos para extraer información útil\"\n        ]\n    ),\n    Question(\n        \"¿Qué herramienta o lenguaje prefieres usar para trabajar?\",\n        [\n            \"HTML, CSS, o JavaScript\",\n            \"Node.js, Java, o Python para el lado del servidor\",\n            \"Swift o Kotlin para aplicaciones móviles\",\n            \"SQL, Python (con Pandas), o R para análisis de datos\"\n        ]\n    ),\n    Question(\n        \"¿Qué te parece más interesante en tu día a día como desarrollador?\",\n        [\n            \"Mejorar la experiencia de usuario a través de interfaces intuitivas\",\n            \"Optimizar la lógica del servidor y la eficiencia de las consultas\",\n            \"Aprovechar las capacidades nativas de los dispositivos móviles\",\n            \"Aplicar técnicas de machine learning para obtener predicciones y patrones\"\n        ]\n    ),\n    Question(\n        \"¿Qué problema preferirías resolver?\",\n        [\n            \"Un diseño web que se ve bien en todas las resoluciones de pantalla\",\n            \"La creación de una arquitectura eficiente para gestionar múltiples usuarios y peticiones\",\n            \"Conseguir que una aplicación funcione sin problemas tanto en iOS como en Android\",\n            \"Limpiar y procesar grandes conjuntos de datos para hacerlos útiles\"\n        ]\n    ),\n    Question(\n        \"¿Qué tipo de testeo prefieres realizar?\",\n        [\n            \"Comprobar que la interfaz es accesible y responsiva\",\n            \"Asegurarte de que las consultas a la base de datos son rápidas y precisas\",\n            \"Testear cómo una app responde en diferentes versiones de sistemas operativos móviles\",\n            \"Validar la precisión de un modelo predictivo en un conjunto de datos\"\n        ]\n    ),\n    Question(\n        \"¿En qué te gustaría especializarte?\",\n        [\n            \"Desarrollo de interfaces gráficas y usabilidad\",\n            \"En la arquitectura de servidores y bases de datos\",\n            \"Programación de aplicaciones nativas que utilicen recursos del dispositivo\",\n            \"Análisis de datos, ciencia de datos, o inteligencia artificial\"\n        ]\n    ),\n    Question(\n        \"¿Qué te gustaría automatizar más en tu trabajo?\",\n        [\n            \"La generación de componentes reutilizables en una interfaz\",\n            \"La ejecución de procesos en segundo plano que optimicen el rendimiento del servidor\",\n            \"La sincronización de datos entre una app móvil y el servidor\",\n            \"La limpieza, procesamiento y visualización de datos de forma eficiente\"\n        ]\n    ),\n    Question(\n        \"¿Cómo prefieres desplegar tus proyectos?\",\n        [\n            \"Configurando un CDN para entregar rápidamente archivos estáticos\",\n            \"Desplegando un servicio web con balanceadores de carga y escalabilidad automática\",\n            \"Publicando una aplicación en las tiendas de iOS y Android\",\n            \"Implementando pipelines de datos para el procesamiento en tiempo real o batch\"\n        ]\n    ),\n    Question(\n        \"¿Qué tipo de herramientas disfrutas más usar?\",\n        [\n            \"Herramientas como React, Vue o Angular\",\n            \"Frameworks como Django, Express o Spring\",\n            \"IDEs como Xcode o Android Studio\",\n            \"Herramientas de análisis de datos como Jupyter Notebook, Hadoop o Power BI\"\n        ]\n    ),\n    Question(\n        \"¿Qué retos técnicos prefieres enfrentar?\",\n        [\n            \"Hacer que una página web se vea increíble en diferentes navegadores\",\n            \"Manejar eficientemente grandes volúmenes de tráfico y asegurar integridad en las transacciones\",\n            \"Garantizar que una app aproveche bien los recursos del teléfono sin consumir demasiada batería\",\n            \"Trabajar con datos faltantes o inconsistentes para obtener insights valiosos\"\n        ]\n    )\n]\n\n\ndef main():\n    frontend = 0\n    backend = 0\n    mobile = 0\n    data = 0\n\n    for question in questions:\n        print(f\"\\n{question.question}\")\n        print(f\"1. {question.answers[0]}\")\n        print(f\"2. {question.answers[1]}\")\n        print(f\"3. {question.answers[2]}\")\n        print(f\"4. {question.answers[3]}\")\n\n        choice = input(\"> \")\n\n        match choice:\n            case \"1\":\n                frontend += 1\n            case \"2\":\n                backend += 1\n            case \"3\":\n                mobile += 1\n            case \"4\":\n                data += 1\n            case _:\n                print(\"\\n⚠️ Opción no válida\")\n                print(\"Prueba finalizada con error\")\n                sys.exit(1)\n\n    results = {'frontend': frontend, 'backend': backend, 'mobile': mobile, 'data': data}\n    max_value = max(results.values())\n    max_keys = [k for k, v in results.items() if v == max_value]\n    selected_key = random.choice(max_keys)\n\n    print(f\"\\nPerteneces a la casa {selected_key}\")\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/python/davidrguez98.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Cada 1 de septiembre, el Hogwarts Express parte hacia la escuela\n * de programación de Hogwarts para magos y brujas del código.\n * En ella, su famoso sombrero seleccionador ayuda a los programadores\n * a encontrar su camino...\n * Desarrolla un programa que simule el comportamiento del sombrero.\n * Requisitos:\n * 1. El sombrero realizará 10 preguntas para determinar la casa del alumno.\n * 2. Deben existir 4 casas. Por ejemplo: Frontend, Backend, Mobile y Data.\n *    (Puedes elegir las que quieras)\n * Acciones:\n * 1. Crea un programa que solicite el nombre del alumno y realice 10\n *    preguntas, con cuatro posibles respuestas cada una.\n * 2. Cada respuesta asigna puntos a cada una de las casas (a tu elección).\n * 3. Una vez finalizado, el sombrero indica el nombre del alumno \n *    y a qué casa pertenecerá (resuelve el posible empate de manera aleatoria,\n *    pero indicándole al alumno que la decisión ha sido complicada).\n */ \"\"\"\n\n#EJERCICIO\n\nimport random\n\nhouses = {\n    \"Frontend\": 0,\n    \"Backend\": 0,\n    \"Mobile\": 0,\n    \"Data\": 0\n}\n\nquestions = [\n    {\n        \"question\": \"¿Qué tipo de desarrollo disfrutas más?\",\n        \"answers\": [\n            {\"option\": \"Analizar y procesar grandes volúmenes de datos\", \"house\": \"Data\"},\n            {\"option\": \"Construir la lógica y la estructura detrás de una aplicación\", \"house\": \"Backend\"},\n            {\"option\": \"Crear interfaces atractivas y dinámicas\", \"house\": \"Frontend\"},\n            {\"option\": \"Desarrollar aplicaciones para dispositivos móviles\", \"house\": \"Mobile\"}\n        ]\n    },\n    {\n        \"question\": \"¿Qué lenguaje de programación prefieres?\",\n        \"answers\": [\n            {\"option\": \"Swift/Kotlin\", \"house\": \"Mobile\"},\n            {\"option\": \"JavaScript/TypeScript\", \"house\": \"Frontend\"},\n            {\"option\": \"SQL/Python (Pandas, NumPy)\", \"house\": \"Data\"},\n            {\"option\": \"Python/Java\", \"house\": \"Backend\"}\n        ]\n    },\n    {\n        \"question\": \"¿Qué parte de un proyecto disfrutas más?\",\n        \"answers\": [\n            {\"option\": \"Trabajar en la integración con hardware y sensores\", \"house\": \"Mobile\"},\n            {\"option\": \"Realizar análisis de datos y crear reportes\", \"house\": \"Data\"},\n            {\"option\": \"Construir la API y manejar bases de datos\", \"house\": \"Backend\"},\n            {\"option\": \"Diseñar y optimizar la experiencia del usuario\", \"house\": \"Frontend\"}\n        ]\n    },\n    {\n        \"question\": \"¿Qué herramienta te resulta más interesante?\",\n        \"answers\": [\n            {\"option\": \"Node.js/Django\", \"house\": \"Backend\"},\n            {\"option\": \"Flutter/React Native\", \"house\": \"Mobile\"},\n            {\"option\": \"React/Vue.js\", \"house\": \"Frontend\"},\n            {\"option\": \"BigQuery/Tableau\", \"house\": \"Data\"}\n        ]\n    },\n    {\n        \"question\": \"¿Qué tipo de desafíos te gustan más?\",\n        \"answers\": [\n            {\"option\": \"Crear aplicaciones que funcionen bien en distintos dispositivos\", \"house\": \"Mobile\"},\n            {\"option\": \"Optimizar la velocidad y la accesibilidad de una web\", \"house\": \"Frontend\"},\n            {\"option\": \"Encontrar patrones en conjuntos de datos complejos\", \"house\": \"Data\"},\n            {\"option\": \"Mejorar la eficiencia de las consultas en una base de datos\", \"house\": \"Backend\"}\n        ]\n    },\n    {\n        \"question\": \"¿Dónde te gustaría trabajar?\",\n        \"answers\": [\n            {\"option\": \"En una compañía de tecnología desarrollando apps móviles\", \"house\": \"Mobile\"},\n            {\"option\": \"En una startup creando experiencias visuales innovadoras\", \"house\": \"Frontend\"},\n            {\"option\": \"En una empresa analizando datos para la toma de decisiones\", \"house\": \"Data\"},\n            {\"option\": \"En una gran empresa optimizando servidores y APIs\", \"house\": \"Backend\"}\n        ]\n    },\n    {\n        \"question\": \"¿Cómo te gusta resolver problemas?\",\n        \"answers\": [\n            {\"option\": \"Estructurando datos y optimizando procesos\", \"house\": \"Backend\"},\n            {\"option\": \"Diseñando interfaces intuitivas\", \"house\": \"Frontend\"},\n            {\"option\": \"Asegurando compatibilidad en distintas plataformas\", \"house\": \"Mobile\"},\n            {\"option\": \"Utilizando modelos estadísticos y machine learning\", \"house\": \"Data\"}\n        ]\n    },\n    {\n        \"question\": \"¿Cuál consideras tu mayor fortaleza como programador?\",\n        \"answers\": [\n            {\"option\": \"Adaptabilidad y optimización\", \"house\": \"Mobile\"},\n            {\"option\": \"Creatividad y diseño\", \"house\": \"Frontend\"},\n            {\"option\": \"Lógica y estructura\", \"house\": \"Backend\"},\n            {\"option\": \"Análisis y resolución de problemas\", \"house\": \"Data\"}\n        ]\n    },\n    {\n        \"question\": \"¿Qué tecnología te gustaría dominar?\",\n        \"answers\": [\n            {\"option\": \"GraphQL y microservicios\", \"house\": \"Backend\"},\n            {\"option\": \"WebAssembly y animaciones avanzadas\", \"house\": \"Frontend\"},\n            {\"option\": \"Desarrollo de apps con IA\", \"house\": \"Mobile\"},\n            {\"option\": \"Deep Learning y análisis predictivo\", \"house\": \"Data\"}\n        ]\n    },\n    {\n        \"question\": \"¿Cuál sería tu proyecto ideal?\",\n        \"answers\": [\n            {\"option\": \"Un sistema escalable con alta concurrencia\", \"house\": \"Backend\"},\n            {\"option\": \"Un modelo de machine learning con predicciones precisas\", \"house\": \"Data\"},\n            {\"option\": \"Un sitio web con interacciones innovadoras\", \"house\": \"Frontend\"},\n            {\"option\": \"Una aplicación móvil con funciones avanzadas\", \"house\": \"Mobile\"}\n        ]\n    }\n]\n\nprint(\"¿Bienvenido a la escuela de programación para magos y brujas del código!\")\nname = input(\"\\n¿Cuál es tu nombre?: \")\n\nfor index, question in enumerate(questions):\n\n    print(f\"Pregunta {index + 1}: {question[\"question\"]}\")\n\n    for i, answer in enumerate(question[\"answers\"]):\n        print(f\"{i + 1}. {answer[\"option\"]}\")\n\n    choice = int(input(\"\\nSelecciona una respuesta entre 1 y 4. \"))\n\n    selected_asnwer = question[\"answers\"][choice - 1]\n    houses[selected_asnwer[\"house\"]] += 1\n\n\nassigned_house = max(houses, key=houses.get)\nscores = list(houses.values())\n\nif scores.count(max(scores)) > 1:\n    possible_houses = [\n        house for house, points in houses.items() if points == max(scores)\n    ]\n\n    assigned_house = random.choice(possible_houses)\n\n    print(f\"Tras una difícil decisión el alumno {name} ha sido seleccionado por el sombrero para la casa {assigned_house}\")\nelse:\n    print(f\"El alumno/a {name} ha sido seleccionado por el sombrero para la casa {assigned_house}.\")"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/python/duendeintemporal.py",
    "content": "#36 { Retos para Programadores } EL SOMBRERO SELECCIONADOR \n\n# Bibliography reference:\n# I use GPT as a reference and sometimes to correct or generate proper comments.\n\n\"\"\"  \n * EJERCICIO:\n * Cada 1 de septiembre, el Hogwarts Express parte hacia la escuela\n * de programación de Hogwarts para magos y brujas del código.\n * En ella, su famoso sombrero seleccionador ayuda a los programadores\n * a encontrar su camino...\n * Desarrolla un programa que simule el comportamiento del sombrero.\n * Requisitos:\n * 1. El sombrero realizará 10 preguntas para determinar la casa del alumno.\n * 2. Deben existir 4 casas. Por ejemplo: Frontend, Backend, Mobile y Data.\n *    (Puedes elegir las que quieras)\n * Acciones:\n * 1. Crea un programa que solicite el nombre del alumno y realice 10\n *    preguntas, con cuatro posibles respuestas cada una.\n * 2. Cada respuesta asigna puntos a cada una de las casas (a tu elección).\n * 3. Una vez finalizado, el sombrero indica el nombre del alumno \n *    y a qué casa pertenecerá (resuelve el posible empate de manera aleatoria,\n *    pero indicándole al alumno que la decisión ha sido complicada).\n\n\"\"\"\n\nlog = print\n\nquestions = [\n    {\n        \"question\": \"What type of projects are you most interested in developing?\",\n        \"answers\": [\n            {\"option\": \"Native mobile applications for multiple platforms.\", \"house\": \"Mobile\"},\n            {\"option\": \"Visually appealing and responsive interfaces.\", \"house\": \"Frontend\"},\n            {\"option\": \"Processing and analyzing large volumes of data.\", \"house\": \"Data Analysis\"},\n            {\"option\": \"Robust systems and server performance optimization.\", \"house\": \"Backend\"},\n            {\"option\": \"All of the above\", \"house\": \"Fullstack\"}\n        ]\n    },\n    {\n        \"question\": \"What aspect of development do you enjoy the most?\",\n        \"answers\": [\n            {\"option\": \"Creating efficient and functional mobile applications.\", \"house\": \"Mobile\"},\n            {\"option\": \"Working on design and user experience.\", \"house\": \"Frontend\"},\n            {\"option\": \"Analyzing data to make data-driven decisions.\", \"house\": \"Data Analysis\"},\n            {\"option\": \"Solving complex logic and scalability problems.\", \"house\": \"Backend\"},\n            {\"option\": \"All of the above\", \"house\": \"Fullstack\"}\n        ]\n    },\n    {\n        \"question\": \"What tool do you prefer to use in your day-to-day work?\",\n        \"answers\": [\n            {\"option\": \"Kotlin or Swift for developing native mobile apps.\", \"house\": \"Mobile\"},\n            {\"option\": \"Frameworks like React or Angular.\", \"house\": \"Frontend\"},\n            {\"option\": \"Python or R for data analysis.\", \"house\": \"Data Analysis\"},\n            {\"option\": \"Languages like Node.js or Python for server management.\", \"house\": \"Backend\"},\n            {\"option\": \"All of the above\", \"house\": \"Fullstack\"}\n        ]\n    },\n    {\n        \"question\": \"How do you see yourself in a development team?\",\n        \"answers\": [\n            {\"option\": \"Developing the interface and functionality of a mobile app.\", \"house\": \"Mobile\"},\n            {\"option\": \"Designing interactions and visual components.\", \"house\": \"Frontend\"},\n            {\"option\": \"Modeling data and building analysis dashboards.\", \"house\": \"Data Analysis\"},\n            {\"option\": \"Responsible for server logic and APIs.\", \"house\": \"Backend\"},\n            {\"option\": \"All of the above\", \"house\": \"Fullstack\"}\n        ]\n    },\n    {\n        \"question\": \"What motivates you the most when working on a project?\",\n        \"answers\": [\n            {\"option\": \"Ensuring that a mobile application works perfectly on any device.\", \"house\": \"Mobile\"},\n            {\"option\": \"Seeing the design come to life on the screen.\", \"house\": \"Frontend\"},\n            {\"option\": \"Discovering insights from data analysis.\", \"house\": \"Data Analysis\"},\n            {\"option\": \"Optimizing system performance and scalability.\", \"house\": \"Backend\"},\n            {\"option\": \"All of the above\", \"house\": \"Fullstack\"}\n        ]\n    },\n    {\n        \"question\": \"What is your approach to learning new technologies?\",\n        \"answers\": [\n            {\"option\": \"Trying out new platforms and tools for mobile development.\", \"house\": \"Mobile\"},\n            {\"option\": \"Experimenting with new libraries and frameworks for user interfaces.\", \"house\": \"Frontend\"},\n            {\"option\": \"Exploring advanced data analysis and machine learning techniques.\", \"house\": \"Data Analysis\"},\n            {\"option\": \"Learning about new architectures and server languages.\", \"house\": \"Backend\"},\n            {\"option\": \"All of the above\", \"house\": \"Fullstack\"}\n        ]\n    },\n    {\n        \"question\": \"What type of challenges do you enjoy solving the most?\",\n        \"answers\": [\n            {\"option\": \"Creating smooth user experiences on mobile devices.\", \"house\": \"Mobile\"},\n            {\"option\": \"Optimizing interfaces to look good on any device.\", \"house\": \"Frontend\"},\n            {\"option\": \"Analyzing large volumes of data to detect hidden patterns.\", \"house\": \"Data Analysis\"},\n            {\"option\": \"Solving concurrency and load issues on servers.\", \"house\": \"Backend\"},\n            {\"option\": \"All of the above\", \"house\": \"Fullstack\"}\n        ]\n    },\n    {\n        \"question\": \"How do you like to measure the success of your work?\",\n        \"answers\": [\n            {\"option\": \"By the smoothness and performance of the mobile app on different devices.\", \"house\": \"Mobile\"},\n            {\"option\": \"By user satisfaction with the visual interface.\", \"house\": \"Frontend\"},\n            {\"option\": \"By the accuracy and relevance of the results obtained from data analysis.\", \"house\": \"Data Analysis\"},\n            {\"option\": \"By the stability and speed of the system under load.\", \"house\": \"Backend\"},\n            {\"option\": \"All of the above\", \"house\": \"Fullstack\"}\n        ]\n    },\n    {\n        \"question\": \"What do you find most interesting when working with emerging technologies?\",\n        \"answers\": [\n            {\"option\": \"Developing mobile apps that leverage new hardware capabilities.\", \"house\": \"Mobile\"},\n            {\"option\": \"Trying out new tools and methodologies to improve design and UX.\", \"house\": \"Frontend\"},\n            {\"option\": \"Working with big data or artificial intelligence technologies.\", \"house\": \"Data Analysis\"},\n            {\"option\": \"Exploring new architectures to improve server performance.\", \"house\": \"Backend\"},\n            {\"option\": \"All of the above\", \"house\": \"Fullstack\"}\n        ]\n    },\n    {\n        \"question\": \"How do you approach a new problem in a project?\",\n        \"answers\": [\n            {\"option\": \"Exploring how to improve the user experience on mobile devices.\", \"house\": \"Mobile\"},\n            {\"option\": \"Reassessing the visual and functional structure of the interface.\", \"house\": \"Frontend\"},\n            {\"option\": \"Looking for patterns and solutions based on data analysis.\", \"house\": \"Data Analysis\"},\n            {\"option\": \"Analyzing the data structure and backend logic.\", \"house\": \"Backend\"},\n            {\"option\": \"All of the above\", \"house\": \"Fullstack\"}\n        ]\n    }\n]\n\ndef start(questions):\n    log('\\n')\n    log('Welcome to the best roadmap for developers you have ever seen!')\n    log('\\n')\n    log('Every September 1st, the Hogwarts Express departs for the Hogwarts School of Code for Wizards and Witches of programming.')\n    log('\\n')\n    log('There, the famous Sorting Hat helps programmers find their path...')\n    log('\\n')\n    log(\"Let's get started! Happy coding!\")\n    log('\\n')\n\n    answers = []\n    count = 0\n\n    def show_result(answer):\n        result = []\n        areas = ['Mobile', 'Frontend', 'Data Analysis', 'Backend', 'Fullstack']\n\n        for i in range(1, 6):\n            total = answer.count(i)\n            result.append(total)\n\n        max_value = max(result)\n        max_indices = [index for index, value in enumerate(result) if value == max_value]\n\n        log('You seem to be oriented to the next area/areas:')\n        for r in max_indices:\n            log(f\"{areas[r]}\")\n\n    def make_question(count):\n        if count < len(questions):\n            log('Options:')\n            for idx, opt in enumerate(questions[count]['answers']):\n                log(f\"{idx + 1}. {opt['option']}\")\n            log('Question:')\n            user_input = input(f\"{questions[count]['question']} Please choose a # from 1 to 5 according to the option: \")\n            log('\\n')\n            try:\n                result = int(user_input)\n                if 1 <= result <= 5:\n                    answers.append(result)\n                    make_question(count + 1)\n                else:\n                    log('Invalid input. You must select a # between 1 and 5. Please try again.')\n                    make_question(count)  # Repeat the last question\n            except ValueError:\n                log('Invalid input. Please enter a number.')\n                make_question(count)  # Repeat the last question\n        else:\n            show_result(answers)\n\n    make_question(count)\n\nstart(questions)\n\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/python/fborjalv.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Cada 1 de septiembre, el Hogwarts Express parte hacia la escuela\n * de programación de Hogwarts para magos y brujas del código.\n * En ella, su famoso sombrero seleccionador ayuda a los programadores\n * a encontrar su camino...\n * Desarrolla un programa que simule el comportamiento del sombrero.\n * Requisitos:\n * 1. El sombrero realizará 10 preguntas para determinar la casa del alumno.\n * 2. Deben existir 4 casas. Por ejemplo: Frontend, Backend, Mobile y Data.\n *    (Puedes elegir las que quieras)\n * Acciones:\n * 1. Crea un programa que solicite el nombre del alumno y realice 10\n *    preguntas, con cuatro posibles respuestas cada una.\n * 2. Cada respuesta asigna puntos a cada una de las casas (a tu elección).\n * 3. Una vez finalizado, el sombrero indica el nombre del alumno \n *    y a qué casa pertenecerá (resuelve el posible empate de manera aleatoria,\n *    pero indicándole al alumno que la decisión ha sido complicada).\n */\n\n\"\"\"\n\nimport random\nhouses = {\"Frontend\": 0, \"Backend\": 0, \"Data\": 0, \"Mobile\": 0}\n\nquestions = [\n    {\n        \"question\" :\"¿Cuál es tu lenguaje de programación favorito?\",\n        \"answer\" : [{\n            \"option\": \"JavaScript\",\n            \"house\": \"Frontend\"\n        },\n        {\n            \"option\": \"Python\",\n            \"house\": \"Data\"\n        },\n        {\n            \"option\": \"Swift\",\n            \"house\": \"Mobile\"\n        },\n        {\n            \"option\": \"SQL\",\n            \"house\": \"Backend\"\n        }\n        \n        ]\n    },\n    {\n        \"question\": \"¿Qué tipo de tareas disfrutas más en un proyecto de desarrollo?\",\n        \"answer\": [\n        {\n            \"option\": \"Analizar información y extraer conocimientos a partir de datos\",\n            \"house\": \"Data\"\n        },\n        {\n            \"option\" : \"Diseñar la estructura lógica y gestionar la base del sistema\",\n            \"house\": \"Backend\"\n        },\n        {\n            \"option\": \"Desarrollar soluciones optimizadas para dispositivos móviles\",\n            \"house\": \"Mobile\"\n        },\n        {\n            \"option\" : \"Crear experiencias visuales y mejorar la interacción del usuario\", \n            \"house\" : \"Frontend\"\n        }\n        ]\n    },\n    {\n        \"question\": \"¿Qué disfrutas más en un proyecto de software?\",\n        \"answer\": [\n            {\n                \"option\": \"Implementar sistemas eficientes\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"Diseñar interfaces atractivas\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Trabajar con grandes volúmenes de datos\",\n                \"house\": \"Data\"\n            },\n            {\n                \"option\": \"Crear apps móviles innovadoras\",\n                \"house\": \"Mobile\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Qué tipo de problemas prefieres resolver?\",\n        \"answer\": [\n            {\n                \"option\": \"Estéticos y de diseño\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Funcionalidad en dispositivos móviles\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"Escalabilidad y rendimiento\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"Predicción y análisis de datos\",\n                \"house\": \"Data\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Qué entorno de desarrollo prefieres?\",\n        \"answer\": [\n            {\n                \"option\": \"Un dispositivo móvil\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"Un clúster de datos\",\n                \"house\": \"Data\"\n            },\n            {\n                \"option\": \"Un navegador\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Un servidor\",\n                \"house\": \"Backend\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Cómo prefieres aprender nuevas tecnologías? \",\n        \"answer\": [\n            {\n                \"option\": \"Diseñando interfaces\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Creando APIs\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"Programando apps móviles\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"Explorando datasets\",\n                \"house\": \"Data\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Qué herramienta te es más cómoda usar?\",\n        \"answer\": [\n            {\n                \"option\": \"HTML/CSS\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Xcode\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"Node.js\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"Jupyter Notebook\",\n                \"house\": \"Data\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Qué es más importante para ti en un proyecto?\",\n        \"answer\": [\n            {\n                \"option\": \"La experiencia del usuario\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"La arquitectura del sistema\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"La compatibilidad con múltiples plataformas móviles\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"El manejo eficiente de datos\",\n                \"house\": \"Data\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿En qué parte de un equipo de desarrollo te sientes más cómodo? \",\n        \"answer\": [\n            {\n                \"option\": \"Diseñando y desarrollando interfaces\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Implementando la lógica del sistema\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"Creando apps móviles\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"Analizando datos y creando modelos\",\n                \"house\": \"Data\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Qué crees que dominará el futuro de la programación?\",\n        \"answer\": [\n            {\n                \"option\": \"Inteligencia artificial y big data\",\n                \"house\": \"Data\"\n            }, \n            {\n                \"option\": \"Aplicaciones web dinámicas\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Aplicaciones móviles\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"Computación en la nube\",\n                \"house\": \"Backend\"\n            }\n        ]\n    },\n\n]\n\n\n\nfor index, text in enumerate(questions):\n    print(f\"\\n{index+1}-\", text[\"question\"]+\"\\n\")\n    for num, op in enumerate(text[\"answer\"]):\n        print(f\"{num+1}.\", op[\"option\"])\n    user_option = int(input(\"Elige una de las cuatro opciones: \"))\n    house = text[\"answer\"][user_option-1][\"house\"]\n    houses[house] += 1\n    print(houses)\n    \nresult_house = max(houses, key= lambda x: houses[x])\n\nscores = list(houses.values())\n\nif scores.count(max(scores)) > 1: \n    print(\"Se ha producido un empate...\")\n    print(\"Dificil decisión.....\")\n    possible_houses = [house for house, point in houses.items() if point == max(scores) ]\n    print(f\"Tu casa será... {random.choice(possible_houses)}\")\nelse: \n    print(f\"La casa ganadora es {result_house}\")\n    \nsorted_houses = sorted(houses, key= lambda x: houses[x], reverse=True)\nprint(\"Resultados: \")\nprint(\"\\n\".join(i for i in sorted_houses))\n\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/python/ggtorca.py",
    "content": "import random\n\n#Definicion casas\nCasas = {\n    \"Frontend\": 0,\n    \"Backend\": 0,\n    \"Mobile\": 0,\n    \"Data\": 0\n}\n\n#Definicion preguntas\nPreguntas = [\n    {\n        \"Pregunta\": \"Si no fueras quisieras ser programador, ¿Cual seria tu profesión favorita?\",\n        \"Opciones\": {\n            \"a\": (\"Pintor\", \"Frontend\"),\n            \"b\": (\"Arquitecto\", \"Backend\"),\n            \"c\": (\"Influencer\", \"Mobile\"),\n            \"d\": (\"Estadista\", \"Data\")\n        }\n\n    },\n\n    {\n        \"Pregunta\": \"¿Cual es tu lenguaje de programacion favorito?\",\n        \"Opciones\": {\n            \"a\": (\"JavaScript\", \"Frontend\"),\n            \"b\": (\"C#\", \"Backend\"),\n            \"c\": (\"Java\", \"Mobile\"),\n            \"d\": (\"Python\", \"Data\")\n        }\n\n    },\n\n    {\n        \"Pregunta\": \"¿Donde te sientes mas comodo?\",\n        \"Opciones\": {\n            \"a\": (\"Navegadores web\", \"Frontend\"),\n            \"b\": (\"Sistemas distribuidos\", \"Backend\"),\n            \"c\": (\"Plataformas móviles\", \"Mobile\"),\n            \"d\": (\"Entornos de big data\", \"Data\")\n        }\n\n    },\n\n    {\n        \"Pregunta\": \"¿Cual seria tu rol ideal en un equipo de desarrollo?\",\n        \"Opciones\": {\n            \"a\": (\"Diseñador de interfaces de usuario\", \"Frontend\"),\n            \"b\": (\"Ingeniero de sistemas\", \"Backend\"),\n            \"c\": (\"Desarrollador de aplicaciones móviles\", \"Mobile\"),\n            \"d\": (\"Científico de datos\", \"Data\")\n        }\n    },\n\n    {\n        \"Pregunta\": \"¿Que herramienta te resulta mas interesante?\",\n        \"Opciones\": {\n            \"a\": (\"Figma\", \"Frontend\"),\n            \"b\": (\"Docker\", \"Backend\"),\n            \"c\": (\"Android Studio\", \"Mobile\"),\n            \"d\": (\"Jupyter Notebook\", \"Data\")\n        }\n    },\n\n    {\n        \"Pregunta\": \"¿Que consideras más importante en un producto tecnologico?\",\n        \"Opciones\": {\n            \"a\": (\"La usabilidad y el diseño\", \"Frontend\"),\n            \"b\": (\"La robustez y escalabilidad\", \"Backend\"),\n            \"c\": (\"La accesibilidad en cualquier dispositivo\", \"Mobile\"),\n            \"d\": (\"La capacidad de extraer informacion valiosa\", \"Data\")\n        }\n    },\n\n    {\n        \"Pregunta\": \"¿Como definirias el exito en un proyecto?\",\n        \"Opciones\": {\n            \"a\": (\"Una interfaz atractiva y funcional\", \"Frontend\"),\n            \"b\": (\"Un sistema eficiente y seguro\", \"Backend\"),\n            \"c\": (\"Una aplicacion que funcione sin problemas en cualquier dispositivo\", \"Mobile\"),\n            \"d\": (\"Tomar decisiones basadas en datos solidos\", \"Data\")\n        }\n    },\n\n{\n        \"Pregunta\": \"¿Que te motiva mas al iniciar un nuevo proyecto?\",\n        \"Opciones\": {\n            \"a\": (\"Crear una experiencia visual impresionante\", \"Frontend\"),\n            \"b\": (\"Resolver problemas complejos con codigo eficiente\", \"Backend\"),\n            \"c\": (\"Innovar con funciones mobiles nunca vistas\", \"Mobile\"),\n            \"d\": (\"Descubrir nuevas tendencias a base del estudio de datos\", \"Data\")\n        }\n    },\n\n    {\n        \"Pregunta\": \"¿Que aspectos consideras mas desafiantes en el desarrollo de software?\",\n        \"Opciones\": {\n            \"a\": (\"Hacer una interfaz sencilla y atractiva\", \"Frontend\"),\n            \"b\": (\"Hacer un sistema escalable\", \"Backend\"),\n            \"c\": (\"Adaptar la app a diferentes sistemas operativos\", \"Mobile\"),\n            \"d\": (\"Gestionar grandes volumenes de informacion con precision\", \"Data\")\n        }\n    },\n\n    {\n        \"Pregunta\": \"¿Si tuvieras que especializarte en una tecnología ¿Cual elegirias?\",\n        \"Opciones\": {\n            \"a\": (\"React o Vue.js para interfaces dinamicas\", \"Frontend\"),\n            \"b\": (\"Node.js o Django para desarrollo backend\", \"Backend\"),\n            \"c\": (\"Swift o Kotlin para aplicaciones moviles\", \"Mobile\"),\n            \"d\": (\"SQL o Hadoop para manejo de grandes datos\", \"Data\")\n        }\n    }\n]\n\n#Funcion Principal\ndef SombreroMagico():\n    nombre = input(\"Cual es tu nombre? \")\n    print(f\"\\nHola {nombre}! Vamos a ver a que casa perteneces...\\n\")\n          \n    for Pregunta in Preguntas:\n        print(Pregunta[\"Pregunta\"])\n        for key, value in Pregunta[\"Opciones\"].items():\n            print(f\"{key}) {value[0]}\")\n        respuesta = input(\"\\nSelecciona una opción (a/b/c/d): \").lower()\n\n        while respuesta not in Pregunta[\"Opciones\"]:\n            print(\"Respuesta no válida. Intenta nuevamente.\")\n            respuesta = input(\"Selecciona una opción (a/b/c/d): \").lower()\n\n            # Asignar el punto\n            casa_elegida = Pregunta[\"Opciones\"][respuesta][1]\n            Casas[casa_elegida] += 1\n\n    # Decidir  casa con más puntos\n    casa_ganadora = max(Casas, key = Casas.get)\n    max_puntos = max(Casas.values())\n    \n    # Si hay empate, elegimos una al azar\n    casas_empate = [Casa for Casa, puntos in Casas.items() if puntos == max_puntos]\n\n    if len(casas_empate) > 1:\n        casa_ganadora = random.choice(casas_empate)\n        print(f\"\\n¡Decisión difícil! {nombre}, el sombrero ha decidido finalmente colocarte en... ¡{casa_ganadora}!\\n\")\n    else:\n        print(f\"\\n¡Felicidades {nombre}! El sombrero te ha colocado en... ¡{casa_ganadora}!\\n\")\n\n# Ejecutar el programa\nSombreroMagico()"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/python/hectorio23.py",
    "content": "# Autor: Héctor Adán\n# GitHub: https://github.com/hectorio23\n\nimport random\n\n# Casas\nhouses = [\"Frontend\", \"Backend\", \"Mobile\", \"Data\"]\n\n# Preguntas y asignación de puntos\nquestions = [\n    {\"question\": \"¿Prefieres trabajar en interfaces visuales?\", \"scores\": [3, 1, 2, 0]},\n    {\"question\": \"¿Te gusta optimizar el rendimiento del servidor?\", \"scores\": [0, 3, 1, 1]},\n    {\"question\": \"¿Te interesa crear aplicaciones móviles?\", \"scores\": [1, 0, 3, 1]},\n    {\"question\": \"¿Te apasiona analizar grandes conjuntos de datos?\", \"scores\": [0, 1, 0, 3]},\n    # Aquí podrías agregar 6 preguntas más...\n]\n\ndef ask_question():\n    # Función para realizar las preguntas y sumar puntos a cada casa\n    scores = [0, 0, 0, 0]  # Puntos de cada casa\n    for q in questions:\n        print(q[\"question\"])\n        answer = int(input(\"Responde 1, 2, 3 o 4: \")) - 1\n        # Aumentar los puntos de cada casa según la respuesta seleccionada\n        for i in range(4):\n            scores[i] += q[\"scores\"][i] if i == answer else 0\n    return scores\n\ndef sorting_hat():\n    name = input(\"¿Cuál es tu nombre? \")\n    scores = ask_question()\n    max_score = max(scores)\n    candidates = [houses[i] for i, score in enumerate(scores) if score == max_score]\n    \n    # Si hay empate, selecciona aleatoriamente\n    if len(candidates) > 1:\n        print(f\"{name}, la decisión ha sido complicada...\")\n        assigned_house = random.choice(candidates)\n    else:\n        assigned_house = candidates[0]\n    \n    print(f\"{name}, has sido asignado a {assigned_house}.\")\n\n# Ejecutar el sombrero seleccionador\nsorting_hat()\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/python/hozlucas28.py",
    "content": "# pylint: disable=missing-module-docstring,missing-class-docstring,missing-function-docstring,redefined-outer-name\n\nfrom typing import TypedDict, TypeVar, Literal, Any\nfrom random import choice\n\n\n# ---------------------------------------------------------------------------- #\n#                                     TYPES                                    #\n# ---------------------------------------------------------------------------- #\n\nT = TypeVar(\"T\", bound=str)\n\n\nclass Question[T](TypedDict):\n    correct_answer: T\n    options: list[T]\n    points: float\n    question: str\n\n\nQuestionsPerHouse = TypedDict(\n    \"QuestionsPerHouse\",\n    {\n        \"backend\": tuple[\n            Question[Literal[\"Java\", \"JavaScript\", \"Python\", \"Ruby\"]],\n            Question[Literal[\"MySQL\", \"MongoDB\", \"PostgreSQL\", \"SQLite\"]],\n        ],\n        \"data\": tuple[\n            Question[\n                Literal[\n                    \"Data analysis\",\n                    \"Data visualization\",\n                    \"Data mining\",\n                    \"Data modeling\",\n                ]\n            ],\n            Question[Literal[\"Python\", \"R\", \"SQL\", \"Julia\"]],\n        ],\n        \"frontend\": tuple[\n            Question[Literal[\"HTML\", \"CSS\", \"JavaScript\", \"Python\"]],\n            Question[Literal[\"React\", \"Angular\", \"Vue\", \"Ember\"]],\n        ],\n        \"mobile\": tuple[\n            Question[Literal[\"iOS\", \"Android\", \"React Native\", \"Flutter\"]],\n            Question[Literal[\"Swift\", \"Kotlin\", \"Java\", \"Objective-C\"]],\n        ],\n    },\n)\n\n\n# ---------------------------------------------------------------------------- #\n#                                     UTILS                                    #\n# ---------------------------------------------------------------------------- #\n\n\ndef list_to_long_disjunction(*, _list: list[T]) -> str:\n    rtn: str = str(object=_list[0])\n\n    for element in _list[1 : len(_list) - 1]:\n        rtn += f\", {element}\"\n\n    if len(_list) > 1:\n        rtn += f\", and {str(object=_list[-1])}\"\n\n    return rtn\n\n\ndef make_question(question: Question[T]) -> float:\n    user_answer: str = (\n        input(\n            f\"> {question.get('question')} \"\n            f\"({list_to_long_disjunction(_list=question.get('options'))}): \"\n        )\n        .strip()\n        .upper()\n    )\n\n    uppercased_options: list[str] = [\n        str(object=opt).upper() for opt in question.get(\"options\")\n    ]\n\n    while user_answer not in uppercased_options:\n        print(\"\\n> Invalid option! Try again...\")\n\n        user_answer: str = (\n            input(\n                f\"\\n> {question.get('question')} \"\n                f\"({list_to_long_disjunction(_list=question.get('options'))}): \"\n            )\n            .strip()\n            .upper()\n        )\n\n    return (\n        question.get(\"points\")\n        if user_answer == str(object=question.get(\"correct_answer\")).upper()\n        else 0\n    )\n\n\n# ---------------------------------------------------------------------------- #\n#                                     MAIN                                     #\n# ---------------------------------------------------------------------------- #\n\nquestions_per_house: QuestionsPerHouse = {\n    \"backend\": (\n        {\n            \"correct_answer\": \"JavaScript\",\n            \"options\": [\"Java\", \"JavaScript\", \"Python\", \"Ruby\"],\n            \"question\": \"What is the primary language used in backend development?\",\n            \"points\": 5,\n        },\n        {\n            \"correct_answer\": \"PostgreSQL\",\n            \"options\": [\"MySQL\", \"MongoDB\", \"PostgreSQL\", \"SQLite\"],\n            \"points\": 5,\n            \"question\": \"Which database is commonly used for storing data in backend applications?\",\n        },\n    ),\n    \"data\": (\n        {\n            \"correct_answer\": \"Data analysis\",\n            \"options\": [\n                \"Data analysis\",\n                \"Data visualization\",\n                \"Data mining\",\n                \"Data modeling\",\n            ],\n            \"points\": 5,\n            \"question\": \"What is the process of analyzing and interpreting data called?\",\n        },\n        {\n            \"correct_answer\": \"Julia\",\n            \"options\": [\"Python\", \"R\", \"SQL\", \"Julia\"],\n            \"points\": 5,\n            \"question\": \"Which programming language is commonly used for data analysis?\",\n        },\n    ),\n    \"frontend\": (\n        {\n            \"correct_answer\": \"JavaScript\",\n            \"options\": [\"HTML\", \"CSS\", \"JavaScript\", \"Python\"],\n            \"points\": 5,\n            \"question\": \"What is the primary language used in frontend development?\",\n        },\n        {\n            \"correct_answer\": \"Angular\",\n            \"options\": [\"React\", \"Angular\", \"Vue\", \"Ember\"],\n            \"points\": 5,\n            \"question\": \"Which framework is commonly used for building user interfaces?\",\n        },\n    ),\n    \"mobile\": (\n        {\n            \"correct_answer\": \"Flutter\",\n            \"options\": [\"iOS\", \"Android\", \"React Native\", \"Flutter\"],\n            \"points\": 5,\n            \"question\": \"Which platform is commonly used for developing mobile applications?\",\n        },\n        {\n            \"correct_answer\": \"Objective-C\",\n            \"options\": [\"Swift\", \"Kotlin\", \"Java\", \"Objective-C\"],\n            \"points\": 5,\n            \"question\": \"What is the primary language used in mobile app development?\",\n        },\n    ),\n}\n\nuser_name: str = input(\"> Enter your name: \").strip()\n\npoints: list[list[Any]] = [\n    [\"backend\", 0],\n    [\"data\", 0],\n    [\"frontend\", 0],\n    [\"mobile\", 0],\n]\n\nprint()\npoints[0][1] += make_question(question=questions_per_house.get(\"backend\")[0])\n\nprint()\npoints[0][1] += make_question(question=questions_per_house.get(\"backend\")[1])\n\nprint()\npoints[1][1] += make_question(question=questions_per_house.get(\"data\")[0])\n\nprint()\npoints[1][1] += make_question(question=questions_per_house.get(\"data\")[1])\n\nprint()\npoints[2][1] += make_question(question=questions_per_house.get(\"frontend\")[0])\n\nprint()\npoints[2][1] += make_question(question=questions_per_house.get(\"frontend\")[1])\n\nprint()\npoints[3][1] += make_question(question=questions_per_house.get(\"mobile\")[0])\n\nprint()\npoints[3][1] += make_question(question=questions_per_house.get(\"mobile\")[1])\n\nmax_points: list[list[Any]] = []\n\nfor [house, housePoints] in points:\n    if len(max_points) == 0:\n        max_points.append([house, housePoints])\n        continue\n\n    if max_points[0][1] > housePoints:\n        continue\n\n    if max_points[0][1] == housePoints:\n        max_points.append([house, housePoints])\n    else:\n        max_points[0] = [house, housePoints]\n\n\nif len(max_points) == 1:\n    print(f\"\\n> {user_name} will be part of the {max_points[0][0]} house!\")\nelse:\n    print(max_points)\n    rnd_choice: list[Any] = choice(seq=max_points)\n\n    print(\n        f\"\\n> The decision has been complicated,\"\n        f\" but {user_name} will be part of the {rnd_choice[0]} house!\"\n    )\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/python/idiegorojas.py",
    "content": "\"\"\"\n# 36 - Sombrero seleccionador\n\"\"\"\n#  Desarrolla un programa que simule el comportamiento del sombrero.\n\n\"\"\"\nRequisitos:\n\"\"\"\n#  1. El sombrero realizará 10 preguntas para determinar la casa del alumno.\n#  2. Deben existir 4 casas. Por ejemplo: Frontend, Backend, Mobile y Data.\n#  (Puedes elegir las que quieras)\n\n\n\"\"\" Acciones: \"\"\"\n\n#  1. Crea un programa que solicite el nombre del alumno y realice 10 preguntas, con cuatro posibles respuestas cada una.\n#  2. Cada respuesta asigna puntos a cada una de las casas (a tu elección).\n#  3. Una vez finalizado, el sombrero indica el nombre del alumno y a qué casa pertenecerá (resuelve el posible empate de manera aleatoria, pero indicándole al alumno que la decisión ha sido complicada).\n\nimport random\n\n\nall_questions = {\n    \"¿Qué valoras más en ti mismo?\": {\n        \"a\": \"Creatividad y diseño\",\n        \"b\": \"Lógica y resolución de problemas\",\n        \"c\": \"Adaptabilidad y portabilidad\",\n        \"d\": \"Análisis y patrones\"\n    },\n    \"¿Qué herramienta te gustaría dominar?\": {\n        \"a\": \"Figma y librerías de UI\",\n        \"b\": \"Docker y bases de datos\",\n        \"c\": \"Flutter o Swift\",\n        \"d\": \"Python y bibliotecas de análisis\"\n    },\n    \"¿Qué tipo de proyecto te emociona más?\": {\n        \"a\": \"Una interfaz innovadora e intuitiva\",\n        \"b\": \"Una API robusta y escalable\",\n        \"c\": \"Una app que funcione en cualquier dispositivo\",\n        \"d\": \"Un modelo predictivo preciso\"\n    },\n    \"¿Cuál es tu mayor fortaleza?\": {\n        \"a\": \"Atención al detalle visual\",\n        \"b\": \"Pensamiento estructurado\",\n        \"c\": \"Adaptabilidad a diferentes entornos\",\n        \"d\": \"Pensamiento analítico\"\n    },\n    \"¿Qué te gusta aprender en tu tiempo libre?\": {\n        \"a\": \"Tendencias de diseño y experiencia de usuario\",\n        \"b\": \"Arquitectura de sistemas y patrones\",\n        \"c\": \"Nuevos frameworks móviles\",\n        \"d\": \"Técnicas de machine learning\"\n    },\n    \"¿Qué problema te gustaría resolver?\": {\n        \"a\": \"Mejorar la interacción humano-computador\",\n        \"b\": \"Crear sistemas distribuidos eficientes\",\n        \"c\": \"Llevar la tecnología a todas partes\",\n        \"d\": \"Extraer conocimiento de datos complejos\"\n    },\n    \"¿Qué tipo de feedback valoras más?\": {\n        \"a\": \"Sobre la usabilidad y apariencia\",\n        \"b\": \"Sobre el rendimiento y mantenibilidad\",\n        \"c\": \"Sobre la experiencia en distintos dispositivos\",\n        \"d\": \"Sobre la precisión de los resultados\"\n    },\n    \"¿Qué habilidad quieres mejorar?\": {\n        \"a\": \"Diseño de interfaces atractivas\",\n        \"b\": \"Diseño de arquitectura de software\",\n        \"c\": \"Optimización para diferentes dispositivos\",\n        \"d\": \"Modelado estadístico\"\n    },\n    \"¿Qué te motiva a programar?\": {\n        \"a\": \"Ver cómo los usuarios interactúan con mi producto\",\n        \"b\": \"Construir sistemas robustos que soporten todo\",\n        \"c\": \"Crear aplicaciones que la gente lleve consigo\",\n        \"d\": \"Descubrir insights ocultos en los datos\"\n    },\n    \"¿Qué consideras un código exitoso?\": {\n        \"a\": \"El que brinda una experiencia fluida al usuario\",\n        \"b\": \"El que es escalable, mantenible y eficiente\",\n        \"c\": \"El que funciona en todos los dispositivos sin problemas\",\n        \"d\": \"El que transforma datos en información útil\"\n    }\n}\n\n\nclass SombreroSeleccionador:\n    def __init__(self):\n        self.frontend = 0\n        self.backend = 0\n        self.mobile = 0\n        self.data = 0\n        \n    def hacer_preguntas(self):\n        print(\"\\n🎩 EL SOMBRERO SELECCIONADOR 🎩\")\n        print(\"================================\")\n        \n        nombre = input(\"\\nBienvenido/a, ¿cuál es tu nombre? \")\n        \n        print(f\"\\nMuy bien {nombre}, te haré 10 preguntas para determinar tu casa.\")\n        print(\"Para cada pregunta, elige la opción (a, b, c, d) que más te identifique.\\n\")\n        \n        for i, (pregunta, opciones) in enumerate(all_questions.items(), 1):\n            print(f\"\\nPregunta {i}: {pregunta}\")\n            for letra, respuesta in opciones.items():\n                print(f\"{letra}) {respuesta}\")\n            \n            respuesta = \"\"\n            while respuesta not in [\"a\", \"b\", \"c\", \"d\"]:\n                respuesta = input(\"Tu respuesta (a/b/c/d): \").lower()\n                \n            # Asignar puntos según la respuesta\n            if respuesta == \"a\":\n                self.frontend += 1\n            elif respuesta == \"b\":\n                self.backend += 1\n            elif respuesta == \"c\":\n                self.mobile += 1\n            elif respuesta == \"d\":\n                self.data += 1\n        \n        return nombre\n                \n    def determinar_casa(self):\n        puntuaciones = {\n            \"Frontend\": self.frontend,\n            \"Backend\": self.backend, \n            \"Mobile\": self.mobile,\n            \"Data\": self.data\n        }\n        \n        # Encontrar el puntaje máximo\n        max_puntuacion = max(puntuaciones.values())\n        \n        # Encontrar todas las casas con la puntuación máxima\n        casas_maximas = [casa for casa, puntuacion in puntuaciones.items() \n                         if puntuacion == max_puntuacion]\n        \n        # Si hay empate, elegir aleatoriamente\n        casa_elegida = random.choice(casas_maximas)\n        \n        return casa_elegida, len(casas_maximas) > 1\n    \n    def iniciar(self):\n        nombre = self.hacer_preguntas()\n        casa, hubo_empate = self.determinar_casa()\n        \n        print(\"\\n\" + \"=\" * 50)\n        print(f\"\\n🎩 Mmm, interesante {nombre}...\")\n        \n        if hubo_empate:\n            print(\"La decisión ha sido complicada, pero finalmente...\")\n        \n        print(f\"\\n¡TU CASA ES {casa.upper()}! 🎉\")\n        \n        if casa == \"Frontend\":\n            print(\"\\n✨ Tienes un ojo para el diseño y una pasión por crear experiencias de usuario excepcionales.\")\n        elif casa == \"Backend\":\n            print(\"\\n🔧 Tu fortaleza está en construir sistemas robustos y eficientes que sostienen todo lo demás.\")\n        elif casa == \"Mobile\":\n            print(\"\\n📱 Tienes el talento para llevar la tecnología a todos los dispositivos y a cualquier lugar.\")\n        elif casa == \"Data\":\n            print(\"\\n📊 Tu capacidad analítica te permite descubrir información valiosa donde otros no la ven.\")\n\n\n# Ejecutar el programa si se ejecuta como script principal\nif __name__ == \"__main__\":\n    sombrero = SombreroSeleccionador()\n    sombrero.iniciar()"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/python/ignaciovihe.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Cada 1 de septiembre, el Hogwarts Express parte hacia la escuela\n * de programación de Hogwarts para magos y brujas del código.\n * En ella, su famoso sombrero seleccionador ayuda a los programadores\n * a encontrar su camino...\n * Desarrolla un programa que simule el comportamiento del sombrero.\n * Requisitos:\n * 1. El sombrero realizará 10 preguntas para determinar la casa del alumno.\n * 2. Deben existir 4 casas. Por ejemplo: Frontend, Backend, Mobile y Data.\n *    (Puedes elegir las que quieras)\n * Acciones:\n * 1. Crea un programa que solicite el nombre del alumno y realice 10\n *    preguntas, con cuatro posibles respuestas cada una.\n * 2. Cada respuesta asigna puntos a cada una de las casas (a tu elección).\n * 3. Una vez finalizado, el sombrero indica el nombre del alumno \n *    y a qué casa pertenecerá (resuelve el posible empate de manera aleatoria,\n *    pero indicándole al alumno que la decisión ha sido complicada).\n\"\"\"\n\nimport os\nimport time\nimport random\n\nseconds = 1\n\nhouses = {\n    \"Frontend\": 0,\n    \"Backend\": 0,\n    \"Mobile\": 0,\n    \"Data\": 0\n}\n\nquestions = {\n    \"1. ¿Qué parte de un proyecto te entusiasma más?\":\n    {\n        \"a) Diseñar interfaces atractivas y accesibles\": \"Frontend\",\n        \"b) Crear la lógica del servidor y manejar bases de datos\": \"Backend\",\n        \"c) Desarrollar aplicaciones que funcionen en cualquier dispositivo\": \"Mobile\",\n        \"d) Analizar grandes volúmenes de datos para tomar decisiones\": \"Data\"\n    },\n    \"2. ¿Qué editor o herramienta prefieres usar?\":\n    {\n        \"a) Jupyter Notebook o herramientas de visualización\": \"Data\",\n        \"b) Postman, SQL clients, terminal\": \"Backend\",\n        \"c) Figma o herramientas de diseño UI/UX\": \"Frontend\",\n        \"d) Android Studio o Xcode\": \"Mobile\"\n    },\n    \"3. ¿Cuál sería tu proyecto ideal?\":\n    {\n        \"a) Construir una API robusta para un sistema financiero\": \"Backend\",\n        \"b) Predecir el clima con aprendizaje automático\": \"Data\",\n        \"c) Diseñar una app para gestionar tareas diarias\": \"Mobile\",\n        \"d) Crear una web interactiva y moderna\": \"Frontend\"\n    },\n    \"4. ¿Qué te resulta más satisfactorio al programar?\":\n    {\n        \"a) Ver algo visual funcionando perfectamente\": \"Frontend\",\n        \"b) Probar tu app en diferentes móviles y ver que todo funcione\": \"Mobile\",\n        \"c) Limpiar y visualizar datos complejos con claridad\": \"Data\",\n        \"d) Hacer que todo se comunique sin errores entre servicios\": \"Backend\"\n    },\n    \"5. ¿Qué lenguaje te atrae más?\":\n    {\n        \"a) Kotlin o Swift\": \"Mobile\",\n        \"b) Java o Go\": \"Backend\",\n        \"c) JavaScript o TypeScript\": \"Frontend\",\n        \"d) Python o R\": \"Data\"\n    },\n    \"6. ¿Cuál de estas habilidades te gustaría perfeccionar?\":\n    {\n        \"a) Modelado estadístico y análisis predictivo\": \"Data\",\n        \"b) Uso de sensores y funciones nativas del dispositivo\": \"Mobile\",\n        \"c) Seguridad web y eficiencia de APIs\": \"Backend\",\n        \"d) Animaciones CSS y frameworks como React\": \"Frontend\"\n    },\n    \"7. ¿Qué superpoder de programación querrías tener?\":\n    {\n        \"a) Optimizar cualquier algoritmo\": \"Backend\",\n        \"b) Encontrar patrones ocultos en cualquier conjunto de datos\": \"Data\",\n        \"c) Crear experiencias que atrapen al usuario\": \"Frontend\",\n        \"d) Hacer que tu app se adapte a cualquier pantalla sin errores\": \"Mobile\"\n    },\n    \"8. ¿Qué parte del proceso de desarrollo disfrutas más?\":\n    {\n        \"a) Transformar datos crudos en información útil\": \"Data\",\n        \"b) Resolver problemas complejos del sistema\": \"Backend\",\n        \"c) La creatividad del diseño y la usabilidad\": \"Frontend\",\n        \"d) Asegurarme de que todo funcione bien en el móvil\": \"Mobile\"\n    },\n    \"9. ¿Con qué tipo de proyecto grupal te identificas más?\":\n    {\n        \"a) Diseñar la arquitectura de un sistema completo\": \"Backend\",\n        \"b) Coordinar la apariencia y estilo de una plataforma\": \"Frontend\",\n        \"c) Realizar dashboards y análisis para el equipo\": \"Data\",\n        \"d) Integrar funciones móviles con el resto del equipo\": \"Mobile\"\n    },\n    \"10. ¿Qué frase te representa mejor?\":\n    {\n        \"a) 'Los datos hablan por sí solos'\": \"Data\",\n        \"b) 'La base lo es todo'\": \"Backend\",\n        \"c) 'La primera impresión lo es todo'\": \"Frontend\",\n        \"d) 'Todo en la palma de tu mano'\": \"Mobile\"\n    }\n\n}\n\ndef limpiar_consola():\n    os.system('cls' if os.name == 'nt' else 'clear')\n\ndef get_results():\n    for question, answers in questions.items():\n        print(question)\n        for answer in answers:\n            print(\"\\t\" + answer)\n        while True:\n            try:\n                selected = input(\"Selecciona tu respuesta: \")\n                if selected not in(\"a\", \"b\", \"c\", \"d\"):\n                    raise ValueError(\"Elige una opcion correcta.\")\n                break\n            except ValueError as e:\n                print(e)\n        for answer in answers:\n            if answer.startswith(selected):\n                houses[answers[answer]] += 5\n        limpiar_consola()\n\ndef get_house() -> list:\n    max_points = max(houses.values())\n    return [house for house, points in houses.items() if points == max_points]\n\n\ndef sorting_hat():\n    limpiar_consola()\n    print(\"Bienvenido a la escuela para programadores de Hogwarts!\")\n    time.sleep(seconds)\n    limpiar_consola()\n    print(\"Vamos a asignarte una de las casas.\")\n    time.sleep(seconds)\n    limpiar_consola()\n    print(\"Es un proceso complicado así que contesta con sinceridad.\")\n    time.sleep(seconds)\n    limpiar_consola()\n    name = input(\"Lo primero de todo necesito tu nombre: \")\n    limpiar_consola()\n    print(f\"De acuerdo, {name}. Vamos allá.\")\n    time.sleep(seconds)\n    limpiar_consola()\n    get_results()\n    print(\"De acuerdo...\")\n    time.sleep(seconds)\n    limpiar_consola()\n    print(\"mmm....\")\n    time.sleep(seconds)\n    limpiar_consola()\n    print(\"Interesante...\")\n    time.sleep(seconds)\n    limpiar_consola()\n    result = get_house()\n    if len(result) > 1:\n        print(\"Lo tengo! No ha sido una decisión fácil.\")\n        time.sleep(seconds)\n        limpiar_consola()\n        numero = random.randint(0, len(result) - 1)\n        final_house = result[numero]\n    else:\n        print(\"Lo tengo! Lo tengo muy claro.\")\n        time.sleep(seconds)\n        limpiar_consola()\n        final_house = result[0]\n    print(f\"{name}, tu casa es... {final_house}\")\n\nsorting_hat()"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/python/javi-kl.py",
    "content": "import random\n\nl_preguntas = [\n    \"1. Horas al día programando?\",\n    \"2. Edad?\",\n    \"3. Hobby?\",\n    \"4. Serie favorita?\",\n    \"5. Lenguaje favorito?\",\n    \"6. Profesor favorito?,\",\n    \"7. Nivel de convicción?\",\n    \"8. Que IA utilizas?\",\n    \"9. Proyecto actual?\",\n    \"10. Como te ves en 3 años?\",\n]\n\nvalid_answers = [\"a\", \"b\", \"c\", \"d\"]\n\n\ndef pedir_nombre():\n    print(\"bienvenido a Hogwarts escuela de programación\")\n    nombre = input(\"Dime tu nombre\\n-> \")\n    return nombre\n\n\ndef asignar_puntos(l_preguntas):\n    c_hogwarts = {\"frontend\": 0, \"backend\": 0, \"mobile\": 0, \"data\": 0}\n    for p in l_preguntas:\n        print(p)\n        while True:\n            respuesta = input(\"Opciones:\\na\\nb\\nc\\nd\\n-> \").lower()\n            if respuesta not in valid_answers:\n                print(\"Presta atención!!!\\nIntroduce una opción válida\")\n            else:\n                break\n\n        match respuesta:\n            case \"a\":\n                c_hogwarts[\"frontend\"] += 1\n            case \"b\":\n                c_hogwarts[\"backend\"] += 1\n            case \"c\":\n                c_hogwarts[\"mobile\"] += 1\n            case \"d\":\n                c_hogwarts[\"data\"] += 1\n\n    return c_hogwarts\n\n\ndef asignar_alumno(c_hogwarts):\n    casas = []\n    n_max = max(c_hogwarts.values())\n    for casa, puntos in c_hogwarts.items():\n        if puntos == n_max:\n            casas.append(casa)\n\n    if len(casas) > 1:\n        print(\n            f\"Ha habido un empate entre {', '.join(casas)}\\nSe elegirá de forma aleatoria\"\n        )\n        ganador = random.choice(casas)\n        return ganador\n    else:\n        return casas[0]\n\n\ndef retornar_decisión(c_final, n_alumno):\n    return f\"El alumno {n_alumno} ha sido elegido para entrar en: {c_final}\"\n\n\nif __name__ == \"__main__\":  # Sirve para que no se pueda ejecutar como un modulo\n    # (requiere lanzar este archivo directamente)\n    n_alumno = pedir_nombre()\n    c_hogwarts = asignar_puntos(l_preguntas)\n    c_final = asignar_alumno(c_hogwarts)\n    print(retornar_decisión(c_final, n_alumno))\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/python/javierfiestasbotella.py",
    "content": "'''* EJERCICIO:\n * Cada 1 de septiembre, el Hogwarts Express parte hacia la escuela\n * de programación de Hogwarts para magos y brujas del código.\n * En ella, su famoso sombrero seleccionador ayuda a los programadores\n * a encontrar su camino...\n * Desarrolla un programa que simule el comportamiento del sombrero.\n * Requisitos:\n * 1. El sombrero realizará 10 preguntas para determinar la casa del alumno.\n * 2. Deben existir 4 casas. Por ejemplo: Frontend, Backend, Mobile y Data.\n *    (Puedes elegir las que quieras)\n * Acciones:\n * 1. Crea un programa que solicite el nombre del alumno y realice 10\n *    preguntas, con cuatro posibles respuestas cada una.\n * 2. Cada respuesta asigna puntos a cada una de las casas (a tu elección).\n * 3. Una vez finalizado, el sombrero indica el nombre del alumno \n *    y a qué casa pertenecerá (resuelve el posible empate de manera aleatoria,\n *    pero indicándole al alumno que la decisión ha sido complicada).\n */'''\nFrontend = 0\nBackend = 0\nMobile = 0\nData = 0\n\ndef puntaje(n):\n    global Frontend\n    global Backend\n    global Mobile\n    global Data\n    if n == 1:\n        Frontend += 3\n        Backend += 1\n        Mobile += 2\n        Data += 0\n    elif n == 2:\n        Frontend += 1\n        Backend += 3\n        Mobile += 0\n        Data += 2\n    elif n == 3:\n        Frontend += 1\n        Backend += 0\n        Mobile += 3\n        Data += 1\n    elif n == 4:\n        Frontend += 0\n        Backend += 2\n        Mobile += 0\n        Data += 3\n    else:\n        print(\"Respuesta no válida, por favor elige una opción entre 1 y 4.\")\n\nif __name__ == \"__main__\":\n    name = input('Introduce tu nombre: ')\n    print(f'{name}, voy a realizarte 10 preguntas para asignarte un perfil de desarrollador.')\n\n    preguntas = [\n        '''¿Cuál es tu principal motivación al desarrollar?\n        1) Crear interfaces visuales atractivas.\n        2) Optimizar la lógica de procesamiento.\n        3) Hacer que la aplicación funcione de manera fluida en dispositivos móviles.\n        4) Analizar grandes volúmenes de datos para extraer información útil.''',\n        \n        '''¿Qué lenguaje te gusta usar más?\n        1) JavaScript o TypeScript.\n        2) Python o Java.\n        3) Swift o Kotlin.\n        4) R o SQL.''',\n\n        '''¿Qué herramienta usas con más frecuencia?\n        1) Frameworks como React o Angular.\n        2) Servidores y bases de datos como Node.js o PostgreSQL.\n        3) IDEs para desarrollo móvil como Android Studio o Xcode.\n        4) Herramientas de análisis de datos como Pandas o TensorFlow.''',\n\n        '''¿Qué disfrutas más de tu trabajo?\n        1) Crear experiencias de usuario.\n        2) Gestionar y procesar datos en servidores.\n        3) Desarrollar aplicaciones móviles que funcionen bien en diferentes dispositivos.\n        4) Resolver problemas usando análisis de datos.''',\n\n        '''¿Qué tipo de bugs disfrutas resolviendo?\n        1) Errores en el diseño o comportamiento de la interfaz.\n        2) Fallos en la lógica del servidor o base de datos.\n        3) Problemas de compatibilidad entre dispositivos.\n        4) Inconsistencias en los modelos de datos o análisis.''',\n\n        '''¿Cómo prefieres abordar la resolución de un problema?\n        1) Pensando en cómo afectará la experiencia del usuario.\n        2) Optimizando los procesos en el backend para mayor eficiencia.\n        3) Asegurando que la solución funcione en cualquier dispositivo móvil.\n        4) Aplicando algoritmos de análisis de datos.''',\n\n        '''¿Qué tipo de proyecto te resulta más interesante?\n        1) Un sitio web interactivo y visualmente impresionante.\n        2) Una API robusta y escalable.\n        3) Una aplicación móvil innovadora.\n        4) Un sistema de análisis de grandes datos para insights de negocio.''',\n\n        '''¿Con qué tipo de tecnologías te sientes más cómodo?\n        1) HTML, CSS, JavaScript.\n        2) Node.js, Django, Ruby on Rails.\n        3) Flutter, React Native.\n        4) Spark, Hadoop.''',\n\n        '''¿Qué prefieres hacer en tu tiempo libre?\n        1) Jugar con diseños y CSS para hacer una web más bonita.\n        2) Crear una API que haga un proceso más eficiente.\n        3) Probar nuevas aplicaciones móviles y crear las tuyas.\n        4) Trabajar con grandes conjuntos de datos.''',\n\n        '''¿Cuál consideras tu principal fortaleza?\n        1) Cuidar la experiencia y diseño visual del usuario.\n        2) Crear procesos eficientes y escalables.\n        3) Adaptar aplicaciones móviles para múltiples dispositivos.\n        4) Interpretar y analizar datos complejos.'''\n    ]\n\n    for pregunta in preguntas:\n        while True:\n            try:\n                p = int(input(pregunta + '\\n'))\n                if p >= 1 and p <= 4:\n                    puntaje(p)\n                    break\n                else:\n                    print(\"Por favor, elige una opción válida entre 1 y 4.\")\n            except ValueError:\n                print(\"Por favor, introduce un número válido.\")\n\n    dic = {'Frontend': Frontend, 'Backend': Backend, 'Mobile': Mobile, 'Data': Data}\n    \n    casa = max(dic, key=dic.get)\n\n    print(f'{name}, La casa que le ha sido otorgada es: {casa}')\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/python/juamax2.py",
    "content": "\"\"\"\n* EJERCICIO:\n * Cada 1 de septiembre, el Hogwarts Express parte hacia la escuela\n * de programación de Hogwarts para magos y brujas del código.\n * En ella, su famoso sombrero seleccionador ayuda a los programadores\n * a encontrar su camino...\n * Desarrolla un programa que simule el comportamiento del sombrero.\n * Requisitos:\n * 1. El sombrero realizará 10 preguntas para determinar la casa del alumno.\n * 2. Deben existir 4 casas. Por ejemplo: Frontend, Backend, Mobile y Data.\n *    (Puedes elegir las que quieras)\n * Acciones:\n * 1. Crea un programa que solicite el nombre del alumno y realice 10\n *    preguntas, con cuatro posibles respuestas cada una.\n * 2. Cada respuesta asigna puntos a cada una de las casas (a tu elección).\n * 3. Una vez finalizado, el sombrero indica el nombre del alumno \n *    y a qué casa pertenecerá (resuelve el posible empate de manera aleatoria,\n *    pero indicándole al alumno que la decisión ha sido complicada).\n\"\"\"\nimport random\n\ncasas = {\n    \"Frontend\": 0,\n    \"Backend\": 0,\n    \"Mobile\": 0,\n    \"Data\": 0\n}\n\nquestions = [\n    {\n        \"question\": \"¿Qué tipo de proyectos te interesa más desarrollar?\",\n        \"answers\": [\n            {\n                \"option\": \"Aplicaciones móviles nativas para múltiples plataformas.\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"Interfaces visualmente atractivas y responsivas.\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Procesamiento y análisis de grandes volúmenes de datos.\",\n                \"house\": \"Data\"\n            },\n            {\n                \"option\": \"Sistemas robustos y optimización de rendimiento del servidor.\",\n                \"house\": \"Backend\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Qué aspecto del desarrollo disfrutas más?\",\n        \"answers\": [\n            {\n                \"option\": \"Resolver problemas complejos de lógica y escalabilidad.\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"Analizar datos para tomar decisiones basadas en estadísticas.\",\n                \"house\": \"Data\"\n            },\n            {\n                \"option\": \"Crear aplicaciones móviles eficientes y funcionales.\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"Trabajar en el diseño y la experiencia de usuario.\",\n                \"house\": \"Frontend\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Qué herramienta prefieres usar en tu día a día?\",\n        \"answers\": [\n            {\n                \"option\": \"Kotlin o Swift para desarrollar apps móviles nativas.\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"Python o R para análisis de datos.\",\n                \"house\": \"Data\"\n            },\n            {\n                \"option\": \"Frameworks como React o Angular.\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Lenguajes como Node.js o Python para la gestión de servidores.\",\n                \"house\": \"Backend\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Cómo te ves en un equipo de desarrollo?\",\n        \"answers\": [\n            {\n                \"option\": \"Modelando datos y construyendo dashboards de análisis.\",\n                \"house\": \"Data\"\n            },\n            {\n                \"option\": \"Encargado de la lógica del servidor y las APIs.\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"Desarrollando la interfaz y funcionalidad de una app móvil.\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"Diseñando las interacciones y los componentes visuales.\",\n                \"house\": \"Frontend\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Qué te motiva más al trabajar en un proyecto?\",\n        \"answers\": [\n            {\n                \"option\": \"Ver cómo el diseño cobra vida en la pantalla.\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Descubrir insights a partir del análisis de datos.\",\n                \"house\": \"Data\"\n            },\n            {\n                \"option\": \"Optimizar el rendimiento y escalabilidad del sistema.\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"Lograr que una aplicación móvil funcione perfectamente en cualquier dispositivo.\",\n                \"house\": \"Mobile\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Cuál es tu enfoque al aprender nuevas tecnologías?\",\n        \"answers\": [\n            {\n                \"option\": \"Explorar técnicas avanzadas de análisis de datos y machine learning.\",\n                \"house\": \"Data\"\n            },\n            {\n                \"option\": \"Aprender sobre nuevas arquitecturas y lenguajes de servidor.\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"Probar nuevas plataformas y herramientas para desarrollo móvil.\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"Experimentar con nuevas librerías y frameworks de interfaz de usuario.\",\n                \"house\": \"Frontend\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Qué tipo de desafíos disfrutas más resolver?\",\n        \"answers\": [\n            {\n                \"option\": \"Solución de problemas de concurrencia y carga en servidores.\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"Optimización de interfaces para que se vean bien en cualquier dispositivo.\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Análisis de grandes volúmenes de datos para detectar patrones ocultos.\",\n                \"house\": \"Data\"},\n            {\n                \"option\": \"Creación de experiencias de usuario fluídas en dispositivos móviles.\",\n                \"house\": \"Mobile\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Cómo te gusta medir el éxito de tu trabajo?\",\n        \"answers\": [\n            {\n                \"option\": \"Por la estabilidad y rapidez del sistema bajo carga.\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"Mediante la satisfacción del usuario con la interfaz visual.\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Por la fluidez y buen rendimiento de la app móvil en diferentes dispositivos.\",\n                \"house\": \"Mobile\"},\n            {\n                \"option\": \"Por la precisión y relevancia de los resultados obtenidos en el análisis de datos.\",\n                \"house\": \"Data\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Qué te resulta más interesante al trabajar con tecnologías emergentes?\",\n        \"answers\": [\n            {\n                \"option\": \"Trabajar con tecnologías de big data o inteligencia artificial.\",\n                \"house\": \"Data\"\n            },\n            {\n                \"option\": \"Explorar nuevas arquitecturas para mejorar el rendimiento del servidor.\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"Probar nuevas herramientas y metodologías para mejorar el diseño y la UX.\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Desarrollar apps móviles que aprovechen nuevas capacidades de hardware.\",\n                \"house\": \"Mobile\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Cómo te enfrentas a un nuevo problema en un proyecto?\",\n        \"answers\": [\n            {\n                \"option\": \"Buscando patrones y soluciones basadas en análisis de datos.\",\n                \"house\": \"Data\"\n            },\n            {\n                \"option\": \"Replanteando la estructura visual y funcional de la interfaz.\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Explorando cómo mejorar la experiencia del usuario en dispositivos móviles.\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"Analizando la estructura de datos y la lógica del backend.\",\n                \"house\": \"Backend\"\n            }\n        ]\n    }\n]\n\nprint(\"Bienvenido el sombrero seleccionador decidira cual es tu casa como programador\")\n\nnombre = input(\"Cual es tu nombre? \")\n\nfor index, question in enumerate(questions):\n    \n    print(f\"Pregunta {index + 1}: {question[\"question\"]}\")\n    \n    for i, answer in enumerate(question[\"answers\"]):\n        print(f\"{i + 1}. {answer[\"option\"]}\")\n        \n    eleccion = int(input(\"Selecciona una respuesta entre 1 y 4. \"))\n        \n    respuesta_seleccionada = question[\"answers\"][eleccion - 1]\n    casas[respuesta_seleccionada[\"house\"]] += 1\n        \n    casa_asignada = max(casas, key=casas.get)\n    resultados = list(casas.values())\n    \n    if resultados.count(max(resultados)) > 1:\n        posibles_casas = [\n            house for house, points in casas.items() if points == max(resultados)\n        ]\n        \n        casa_asignada = random.choice(posibles_casas)\n\n        print(f\"Mmmmmm... Ha sido una elección muy complicada, {nombre}. Finalmente tu casa sera {casa_asignada}\")\n        \n    else:\n        print(f\"Enhorabuena, {nombre}. Tu casa será {casa_asignada}\")\n        "
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/python/juanppdev.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Cada 1 de septiembre, el Hogwarts Express parte hacia la escuela\n * de programación de Hogwarts para magos y brujas del código.\n * En ella, su famoso sombrero seleccionador ayuda a los programadores\n * a encontrar su camino...\n * Desarrolla un programa que simule el comportamiento del sombrero.\n * Requisitos:\n * 1. El sombrero realizará 10 preguntas para determinar la casa del alumno.\n * 2. Deben existir 4 casas. Por ejemplo: Frontend, Backend, Mobile y Data.\n *    (Puedes elegir las que quieras)\n * Acciones:\n * 1. Crea un programa que solicite el nombre del alumno y realice 10\n *    preguntas random, con cuatro posibles respuestas cada una.\n * 2. Cada respuesta asigna puntos a cada una de las casas (a tu elección).\n * 3. Una vez finalizado, el sombrero indica el nombre del alumno \n *    y a qué casa pertenecerá (resuelve el posible empate de manera aleatoria,\n *    pero indicándole al alumno que la decisión ha sido complicada).\n\"\"\"\n\nimport random\n\n# Definimos las casas\ncasas = [\"Frontend\", \"Backend\", \"Mobile\", \"Data\"]\n\n# Definimos las preguntas y las respuestas\npreguntas = [\n    (\"¿Qué prefieres hacer en tu tiempo libre?\", [\"Leer documentación\", \"Desarrollar una app\", \"Analizar datos\", \"Diseñar interfaces\"]),\n    (\"¿Qué lenguaje de programación te gusta más?\", [\"JavaScript\", \"Python\", \"Swift\", \"SQL\"]),\n    (\"¿Qué tipo de proyectos te interesan más?\", [\"Web\", \"Backend\", \"Móvil\", \"Big Data\"]),\n    (\"¿Qué herramienta prefieres usar?\", [\"React\", \"Django\", \"Flutter\", \"Pandas\"]),\n    (\"¿Qué tipo de problemas te gusta resolver?\", [\"Interfaz de usuario\", \"Lógica de negocio\", \"Optimización de rendimiento\", \"Análisis de datos\"]),\n    (\"¿Qué tipo de empresa te gustaría trabajar?\", [\"Startup\", \"Corporación\", \"Freelance\", \"Investigación\"]),\n    (\"¿Qué tipo de tareas disfrutas más?\", [\"Diseño\", \"Programación\", \"Pruebas\", \"Análisis\"]),\n    (\"¿Qué prefieres aprender?\", [\"CSS\", \"Docker\", \"Kotlin\", \"Machine Learning\"]),\n    (\"¿Qué tipo de equipo prefieres?\", [\"Diseñadores\", \"Desarrolladores\", \"Ingenieros de software\", \"Científicos de datos\"]),\n    (\"¿Qué tipo de retos te motivan?\", [\"Creativos\", \"Técnicos\", \"Innovadores\", \"Analíticos\"])\n]\n\n# Función para asignar puntos a las casas\ndef asignar_puntos(respuesta):\n    if respuesta == 0:\n        return [1, 0, 0, 0]\n    elif respuesta == 1:\n        return [0, 1, 0, 0]\n    elif respuesta == 2:\n        return [0, 0, 1, 0]\n    elif respuesta == 3:\n        return [0, 0, 0, 1]\n\n# Función principal\ndef sombrero_seleccionador():\n    nombre = input(\"¿Cuál es tu nombre? \")\n    puntos = [0, 0, 0, 0]\n    \n    for i in range(10):\n        pregunta, respuestas = random.choice(preguntas)\n        print(f\"\\nPregunta {i+1}: {pregunta}\")\n        for j, respuesta in enumerate(respuestas):\n            print(f\"{j+1}. {respuesta}\")\n        eleccion = int(input(\"Elige una opción (1-4): \")) - 1\n        puntos = [x + y for x, y in zip(puntos, asignar_puntos(eleccion))]\n    \n    max_puntos = max(puntos)\n    posibles_casas = [casas[i] for i, p in enumerate(puntos) if p == max_puntos]\n    \n    if len(posibles_casas) > 1:\n        casa_final = random.choice(posibles_casas)\n        print(f\"\\n{nombre}, la decisión ha sido complicada, pero finalmente perteneces a la casa {casa_final}!\")\n    else:\n        casa_final = posibles_casas[0]\n        print(f\"\\n{nombre}, perteneces a la casa {casa_final}!\")\n\n# Ejecutar el programa\nsombrero_seleccionador()\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/python/kenysdev.py",
    "content": "# _____________________________________\n# https://github.com/kenysdev\n# 2024 - Python\n# _____________________________________\n# 36 EL SOMBRERO SELECCIONADOR\n# ------------------------------------\n# * Cada 1 de septiembre, el Hogwarts Express parte hacia la escuela\n#  * de programación de Hogwarts para magos y brujas del código.\n#  * En ella, su famoso sombrero seleccionador ayuda a los programadores\n#  * a encontrar su camino...\n#  * Desarrolla un programa que simule el comportamiento del sombrero.\n#  * Requisitos:\n#  * 1. El sombrero realizará 10 preguntas para determinar la casa del alumno.\n#  * 2. Deben existir 4 casas. Por ejemplo: Frontend, Backend, Mobile y Data.\n#  *    (Puedes elegir las que quieras)\n#  * Acciones:\n#  * 1. Crea un programa que solicite el nombre del alumno y realice 10\n#  *    preguntas, con cuatro posibles respuestas cada una.\n#  * 2. Cada respuesta asigna puntos a cada una de las casas (a tu elección).\n#  * 3. Una vez finalizado, el sombrero indica el nombre del alumno\n#  *    y a qué casa pertenecerá (resuelve el posible empate de manera aleatoria,\n#  *    pero indicándole al alumno que la decisión ha sido complicada).\n\nfrom random import choice\nfrom typing import List\n\nHOUSES = [\"Frontend\", \"Backend\", \"Mobile\", \"Data\"]\n\n# Nota: Preguntas y respuestas generadas por IA\n\nQUESTIONS = [\n    \"¿Qué te atrae más?\",\n    \"¿Qué superhéroe de la programación te gustaría ser?\",\n    \"En un proyecto de software, ¿qué rol te emociona más?\",\n    \"Si tu código fuera una obra de arte, ¿qué estilo tendría?\",\n    \"¿Qué animal de programación serías?\",\n    \"En una hackathon, ¿qué tipo de proyecto propondrías?\",\n    \"Si tu carrera en tech fuera una película, ¿de qué género sería?\",\n    \"¿Qué herramienta de programación no puede faltar en tu caja de herramientas digital?\",\n    \"Si pudieras resolver un gran problema en tech, ¿cuál elegirías?\",\n    \"¿Qué tipo de equipo prefieres?\"\n]\n\nANSWERS = [\n    [\"Crear experiencias visuales.\", \"Solucionar problemas de funcionamiento.\", \"Innovar en dispositivos portátiles.\", \"Descubrir tendencias ocultas.\"],\n    [\"Diseñador de Interfaces, creando experiencias asombrosas\", \"Arquitecto de Sistemas, construyendo estructuras robustas\", \"Mago de Apps, conjurando soluciones móviles\", \"Explorador de Datos, descubriendo tesoros ocultos\"],\n    [\"Director de UX, orquestando la sinfonía visual\", \"Ingeniero de Backend, dominando la lógica del servidor\", \"Desarrollador de Apps, llevando la potencia al bolsillo\", \"Científico de Datos, descifrando los secretos de la información\"],\n    [\"Minimalismo elegante, como una landing page perfecta\", \"Arquitectura compleja, como un sistema distribuido\", \"Diseño adaptativo, fluyendo en diferentes dispositivos\", \"Visualización de datos, pintando historias con números\"],\n    [\"Un camaleón, adaptándome a diferentes frameworks\", \"Un pulpo, manejando múltiples servicios a la vez\", \"Un colibrí, ágil y siempre en movimiento\", \"Una lechuza, analizando datos con sabiduría\"],\n    [\"Una web app que revolucione la experiencia del usuario\", \"Un sistema de IA que optimice procesos backend\", \"Una app móvil que cambie la forma de interactuar con el mundo\", \"Un proyecto de big data que prediga tendencias futuras\"],\n    [\"Comedia romántica con JavaScript y CSS\", \"Thriller de ciencia ficción con microservicios\", \"Aventura de acción en el mundo de las apps\", \"Documental profundo sobre el universo de los datos\"],\n    [\"Un editor de código con plugins para diseño visual\", \"Una robusta suite de testing y depuración\", \"Un emulador multi-dispositivo de última generación\", \"Una plataforma de análisis de datos en tiempo real\"],\n    [\"Hacer que la accesibilidad web sea universal\", \"Crear una arquitectura de software autorreparable\", \"Desarrollar una plataforma de AR/VR para educación móvil\", \"Construir un modelo de IA ético y transparente\"],\n    [\"Creativos enfocados en diseño.\", \"Técnicos que construyen sistemas.\", \"Especialistas en aplicaciones móviles.\", \"Expertos en datos y análisis.\"]\n]\n\nclass SortingHat:\n    def __init__(self, name: str):\n        self.name = name\n        self.scores = {house: 0 for house in HOUSES}\n\n    def ask_question(self, q_num: int, question: str, answers: List[str]):\n        print(f\"\\n#{q_num}: {question}\")\n        for i, answer in enumerate(answers, start=1):\n            print(f\"{i}) {answer}\")\n        \n        while True:\n            try:\n                choice = int(input(\"Elige tu respuesta (1-4): \")) - 1\n                if 0 <= choice < len(HOUSES):\n                    self.scores[HOUSES[choice]] += 1\n                    break\n                else:\n                    print(\"Por favor, elige un número entre 1 y 4.\")\n            except ValueError:\n                print(\"Por favor, ingresa un número válido.\")\n\n    def select_house(self) -> str:\n        max_score = max(self.scores.values())\n        top_houses = [house for house, score in self.scores.items() if score == max_score]\n        \n        if len(top_houses) > 1:\n            print(\"\\nLa decisión ha sido complicada.\")\n            return choice(top_houses)\n        return top_houses[0]\n\ndef main():\n    print(\"EL SOMBRERO SELECCIONADOR\")\n    name = input(\"¿Cuál es tu nombre? : \")\n    hat = SortingHat(name)\n\n    for i, (question, answers) in enumerate(zip(QUESTIONS, ANSWERS), start=1):\n        hat.ask_question(i, question, answers)\n\n    selected_house = hat.select_house()\n    print(f\"\\n'{name}' pertenecerá a la casa '{selected_house}'\\n\")\n\nif __name__ == \"__main__\":\n    main()\n\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/python/mhayhem.py",
    "content": "# @Author Daniel Grande Calderon (Mhayhem)\n\nfrom enum import Enum\nfrom random import choice\n\n# EJERCICIO:\n# Cada 1 de septiembre, el Hogwarts Express parte hacia la escuela\n# de programación de Hogwarts para magos y brujas del código.\n# En ella, su famoso sombrero seleccionador ayuda a los programadores\n# a encontrar su camino...\n# Desarrolla un programa que simule el comportamiento del sombrero.\n# Requisitos:\n# 1. El sombrero realizará 10 preguntas para determinar la casa del alumno.\n# 2. Deben existir 4 casas. Por ejemplo: Frontend, Backend, Mobile y Data.\n#    (Puedes elegir las que quieras)\n# Acciones:\n# 1. Crea un programa que solicite el nombre del alumno y realice 10\n#    preguntas, con cuatro posibles respuestas cada una.\n# 2. Cada respuesta asigna puntos a cada una de las casas (a tu elección).\n# 3. Una vez finalizado, el sombrero indica el nombre del alumno \n#    y a qué casa pertenecerá (resuelve el posible empate de manera aleatoria,\n#    pero indicándole al alumno que la decisión ha sido complicada).\n        \n# List of questions\nquestions = [\n    {\n        \"question\": \"¿Qué es lo que más te motiva al empezar un proyecto?\",\n        \"options\": {\n            1: \"Diseñar una interfaz atractiva y que sea intuitiva para el usuario.\",\n            2: \"Definir la lógica del sistema y cómo se van a gestionar los datos.\",\n            3: \"Crear mecánicas divertidas y mundos interactivos.\",\n            4: \"Pensar cómo se va a usar la app en el día a día desde el móvil.\"\n        }\n    },\n    {\n        \"question\": \"¿Qué tipo de problema disfrutas más resolver?\",\n        \"options\": {\n            1: \"Que una web se vea bien en cualquier pantalla y navegador.\",\n            2: \"Optimizar consultas y mejorar el rendimiento del servidor.\",\n            3: \"Ajustar físicas, colisiones o comportamiento de enemigos.\",\n            4: \"Gestionar permisos, sensores y notificaciones del sistema.\"\n        }\n    },\n    {\n        \"question\": \"Si te dan un diseño, ¿qué harías primero?\",\n        \"options\": {\n            1: \"Convertirlo en HTML, CSS y animaciones.\",\n            2: \"Crear la API que soporte todas las funcionalidades.\",\n            3: \"Implementarlo dentro del motor de juego como una escena.\",\n            4: \"Adaptarlo a pantallas pequeñas y gestos táctiles.\"\n        }\n    },\n    {\n        \"question\": \"¿Qué tecnología te llama más la atención?\",\n        \"options\": {\n            1: \"React, Vue o Angular.\",\n            2: \"Django, Spring o Node.js.\",\n            3: \"Unity, Unreal Engine o Godot.\",\n            4: \"Swift, Kotlin o Flutter.\"\n        }\n    },\n    {\n        \"question\": \"¿Qué te molesta más cuando usas una app?\",\n        \"options\": {\n            1: \"Que la interfaz sea fea o poco clara.\",\n            2: \"Que tarde mucho en cargar o falle el servidor.\",\n            3: \"Que el juego tenga bugs o mecánicas mal balanceadas.\",\n            4: \"Que consuma mucha batería o vaya lenta en el móvil.\"\n        }\n    },\n    {\n        \"question\": \"¿Cómo te imaginas tu código la mayor parte del tiempo?\",\n        \"options\": {\n            1: \"Relacionado con estilos, componentes y eventos de usuario.\",\n            2: \"Lleno de reglas de negocio, validaciones y seguridad.\",\n            3: \"Controlando estados, animaciones y lógica en tiempo real.\",\n            4: \"Integrándose con cámaras, GPS o notificaciones.\"\n        }\n    },\n    {\n        \"question\": \"¿Qué tipo de proyecto personal harías por diversión?\",\n        \"options\": {\n            1: \"Una web interactiva con animaciones modernas.\",\n            2: \"Una API robusta para gestionar usuarios y datos.\",\n            3: \"Un juego indie con niveles y puntuaciones.\",\n            4: \"Una app para organizar tareas o hábitos diarios.\"\n        }\n    },\n    {\n        \"question\": \"¿Qué frase te representa más?\",\n        \"options\": {\n            1: \"“Si el usuario no lo entiende, es un problema de diseño.”\",\n            2: \"“Los datos deben ser seguros y consistentes.”\",\n            3: \"“Si no es divertido, no funciona.”\",\n            4: \"“Tiene que sentirse natural en el móvil.”\"\n        }\n    },\n    {\n        \"question\": \"¿Qué tipo de errores te resultan más interesantes de arreglar?\",\n        \"options\": {\n            1: \"Elementos desalineados o animaciones rotas.\",\n            2: \"Errores de concurrencia o lógica compleja.\",\n            3: \"Bugs impredecibles durante el gameplay.\",\n            4: \"Fallos específicos de un dispositivo o sistema operativo.\"\n        }\n    },\n    {\n        \"question\": \"¿Qué te gustaría que dijeran de tu trabajo?\",\n        \"options\": {\n            1: \"“Es bonito y muy fácil de usar.”\",\n            2: \"“Es sólido y nunca se cae.”\",\n            3: \"“Es muy divertido y engancha.”\",\n            4: \"“La uso todos los días en mi móvil.”\"\n        }\n    }\n]\n\n# init respondent and table score\nclass Student:\n    def __init__(self, name: str):\n        self.name = name.capitalize()\n        self.houses = {\n            \"Frontend\": 0,\n            \"Backend\": 0,\n            \"Videogames\": 0,\n            \"Mobile\": 0\n        }\n    \n    def add_points(self, cls: str):\n        self.houses[cls] = self.houses[cls] + 1\n\n    def high_score(self):\n        max_score = max(self.houses.values())\n        your_stack = [stack for stack, score in self.houses.items() if score == max_score]\n        if len(your_stack) < 2:\n            return f\"Alumno {self.name}, tu stack ideal es: {(your_stack[0])}\"\n        else:\n            return f\"Alumno {self.name},ha sido una decisión muy complicada pero creoque tu stack ideal es: {str(choice(your_stack))}\"\n\n# Enum opf stacks\nclass Stacks(Enum):\n    Frontend = \"Frontend\"\n    Backend = \"Backend\"\n    Videogames = \"Videogames\"\n    Mobile = \"Mobile\"\n\n\n# main app\ndef quitz_programming(array: list, cls=Stacks,):\n    name = input(\"Indique el nombre del estudiante: \")\n    student = Student(name)\n    stacks = [stack.value for stack in Stacks]\n    for question in array:\n        print(question[\"question\"])\n        for key, values in question[\"options\"].items():\n            print(f\"{key}: {values}\")\n        while True:\n            try:\n                answer = int(input())\n                if answer > len(question[\"options\"]) or answer <= 0:\n                    print(\"No es una opción valida\")\n                else:\n                    choose = stacks[answer - 1] \n                    student.add_points(choose)\n                    break\n            except ValueError:\n                print(\"Usa solo números.\")\n        print(\"\\n\")\n    print(student.high_score())\n\nquitz_programming(questions, Stacks)"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/python/miguelex.py",
    "content": "import random\n\nclass Casa:\n    def __init__(self, nombre):\n        self.nombre = nombre\n        self.puntos = 0\n\n    def get_nombre(self):\n        return self.nombre\n\n    def agregar_puntos(self, puntos):\n        self.puntos += puntos\n\n    def get_puntos(self):\n        return self.puntos\n\nclass Alumno:\n    def __init__(self, nombre):\n        self.nombre = nombre\n\n    def get_nombre(self):\n        return self.nombre\n\nclass Pregunta:\n    def __init__(self, pregunta, opciones):\n        self.pregunta = pregunta\n        self.opciones = opciones\n\n    def mostrar_pregunta(self):\n        print(self.pregunta)\n        for idx, opcion in enumerate(self.opciones):\n            print(f\"{idx + 1}: {opcion['texto']}\")\n\n    def obtener_casa_segun_respuesta(self, respuesta):\n        return self.opciones[respuesta - 1]['casa']\n\nclass SombreroSeleccionador:\n    def __init__(self, casas, preguntas):\n        self.casas = casas\n        self.preguntas = preguntas\n\n    def asignar_casa(self, alumno):\n        preguntas_seleccionadas = self.seleccionar_preguntas()\n        for pregunta in preguntas_seleccionadas:\n            pregunta.mostrar_pregunta()\n            respuesta = self.leer_respuesta()\n            casa = pregunta.obtener_casa_segun_respuesta(respuesta)\n            self.casas[casa].agregar_puntos(1)\n\n        self.mostrar_resultado(alumno)\n\n    def seleccionar_preguntas(self):\n        preguntas_seleccionadas = []\n        indices_seleccionados = set()\n\n        while len(preguntas_seleccionadas) < 10:\n            indice = random.randint(0, len(self.preguntas) - 1)\n            if indice not in indices_seleccionados:\n                indices_seleccionados.add(indice)\n                preguntas_seleccionadas.append(self.preguntas[indice])\n\n        return preguntas_seleccionadas\n\n    def leer_respuesta(self):\n        while True:\n            try:\n                respuesta = int(input(\"Selecciona una opción (1-4): \"))\n                if 1 <= respuesta <= 4:\n                    return respuesta\n                else:\n                    print(\"Por favor, elige un número entre 1 y 4.\")\n            except ValueError:\n                print(\"Por favor, introduce un número válido.\")\n\n    def mostrar_resultado(self, alumno):\n        casas_ordenadas = sorted(self.casas.values(), key=lambda casa: casa.get_puntos(), reverse=True)\n\n        max_puntos = casas_ordenadas[0].get_puntos()\n        ganadoras = [casa for casa in casas_ordenadas if casa.get_puntos() == max_puntos]\n\n        if len(ganadoras) > 1:\n            print(\"\\n\\nLa decisión fue difícil...\")\n            ganadora = random.choice(ganadoras)\n        else:\n            ganadora = ganadoras[0]\n\n        print(f\"\\n\\n{alumno.get_nombre()}, el sombrero seleccionador te ha asignado a la casa {ganadora.get_nombre().upper()}!!!!\\n\")\n\n\n# Definir las casas\ncasas = {\n    'frontend': Casa('Frontend'),\n    'backend': Casa('Backend'),\n    'mobile': Casa('Mobile'),\n    'data': Casa('Data')\n}\n\n# Definir las preguntas\npreguntas = [\n    Pregunta(\"¿Qué prefieres?\", [\n        {'texto': 'Diseñar interfaces', 'casa': 'frontend'},\n        {'texto': 'Crear APIs', 'casa': 'backend'},\n        {'texto': 'Desarrollar apps móviles', 'casa': 'mobile'},\n        {'texto': 'Analizar datos', 'casa': 'data'}\n    ]),\n    Pregunta(\"¿Cuál es tu lenguaje de programación favorito?\", [\n        {'texto': 'JavaScript', 'casa': 'frontend'},\n        {'texto': 'Python', 'casa': 'backend'},\n        {'texto': 'Kotlin', 'casa': 'mobile'},\n        {'texto': 'R', 'casa': 'data'}\n    ]),\n    Pregunta(\"¿Qué herramienta utilizas más a menudo?\", [\n        {'texto': 'Figma o Sketch', 'casa': 'frontend'},\n        {'texto': 'Docker o Kubernetes', 'casa': 'backend'},\n        {'texto': 'Android Studio o Xcode', 'casa': 'mobile'},\n        {'texto': 'Jupyter Notebooks o Excel', 'casa': 'data'}\n    ]),\n    Pregunta(\"¿Qué te interesa más aprender?\", [\n        { 'texto': 'HTML/CSS y JavaScript avanzado', 'casa': 'frontend' },\n        { 'texto': 'Patrones de diseño y arquitectura de software', 'casa': 'backend' },\n        { 'texto': 'Programación nativa para dispositivos móviles', 'casa': 'mobile' },\n        { 'texto': 'Estadística y Machine Learning', 'casa': 'data' }\n    ]),\n    Pregunta(\"¿Qué tipo de proyecto te gustaría liderar?\", [\n        { 'texto': 'Un sitio web interactivo y atractivo', 'casa': 'frontend' },\n        { 'texto': 'Una plataforma escalable con microservicios', 'casa': 'backend' },\n        { 'texto': 'Una app móvil innovadora', 'casa': 'mobile' },\n        { 'texto': 'Un sistema de recomendación basado en datos', 'casa': 'data' }\n    ]),\n    Pregunta(\"¿Qué es lo más importante para ti en un proyecto?\", [\n        { 'texto': 'La experiencia de usuario', 'casa': 'frontend' },\n        { 'texto': 'El rendimiento y la escalabilidad', 'casa': 'backend' },\n        { 'texto': 'La adaptabilidad a diferentes dispositivos', 'casa': 'mobile' },\n        { 'texto': 'La precisión de los análisis', 'casa': 'data' }\n    ]),\n    Pregunta(\"¿Qué prefieres trabajar?\", [\n        {'texto' : 'En un entorno donde el diseño visual es clave', 'casa' :'frontend'},\n        {'texto' : 'En la lógica del negocio y la arquitectura', 'casa' :'backend'},\n        {'texto' : 'En apps móviles con buen rendimiento', 'casa' :'mobile'},\n        {'texto' : 'En el análisis y visualización de datos', 'casa' :'data'}\n    ]),\n    Pregunta(\"¿Qué framework te parece más interesante?\", [\n        {'texto' : 'React o Angular', 'casa' :'frontend'},\n        {'texto' : 'Spring o Django', 'casa' :'backend'},\n        {'texto' : 'Flutter o React Native', 'casa' :'mobile'},\n        {'texto' : 'TensorFlow o Pandas', 'casa' :'data'}\n    ]),\n    Pregunta(\"¿Qué tipo de reto disfrutas más?\", [\n        {'texto' : 'Hacer que un sitio web sea accesible y rápido', 'casa' :'frontend'},\n        {'texto' : 'Optimizar la comunicación entre servicios', 'casa' :'backend'},\n        {'texto' : 'Mejorar la experiencia del usuario en móviles', 'casa' :'mobile'},\n        {'texto' : 'Encontrar patrones ocultos en los datos', 'casa' :'data'}\n    ]),\n    Pregunta(\"¿Qué prefieres resolver?\", [\n        {'texto' : 'Problemas de diseño y maquetación', 'casa' :'frontend'},\n        {'texto' : 'Problemas de concurrencia y escalabilidad', 'casa' :'backend'},\n        {'texto' : 'Problemas de rendimiento en aplicaciones móviles', 'casa' :'mobile'},\n        {'texto' : 'Problemas de predicción y análisis de datos', 'casa' :'data'}\n    ]),\n    Pregunta(\"¿Qué es lo que más te emociona en tecnología?\", [\n        {'texto' : 'La evolución de las interfaces de usuario', 'casa' :'frontend'},\n        {'texto' : 'La innovación en la arquitectura de software', 'casa' :'backend'},\n        {'texto' : 'Las nuevas capacidades de los dispositivos móviles', 'casa' :'mobile'},\n        {'texto' : 'Los avances en inteligencia artificial y análisis de datos', 'casa' : 'data'}\n    ]),\n    Pregunta(\"¿Qué te gusta hacer en tu tiempo libre?\", [\n        {'texto' : 'Diseñar sitios web personales o interfaces', 'casa': 'frontend'},\n        {'texto' : 'Hacer proyectos con servidores y APIs', 'casa': 'backend'},\n        {'texto' : 'Crear apps móviles para resolver problemas cotidianos', 'casa': 'mobile'},\n        {'texto' : 'Hacer análisis de datos para tomar decisiones mejor informadas', 'casa': 'data'}\n    ]),\n    Pregunta(\"¿Qué te gustaría dominar?\", [\n        {'texto' : 'Animaciones y transiciones en la web', 'casa': 'frontend'},\n        {'texto' : 'Arquitectura de microservicios', 'casa': 'backend'},\n        {'texto' : 'Optimización de aplicaciones móviles', 'casa': 'mobile'},\n        {'texto' : 'Modelos predictivos y análisis de datos', 'casa': 'data'}\n    ]),\n    Pregunta(\"¿Qué tipo de problema prefieres resolver en un hackathon?\", [\n        {'texto' : 'Mejorar la interfaz de usuario de una aplicación', 'casa': 'frontend'},\n        {'texto' : 'Optimizar el rendimiento de una API', 'casa': 'backend'},\n        {'texto' : 'Crear una aplicación móvil desde cero', 'casa': 'mobile'},\n        {'texto' : 'Generar insights a partir de grandes conjuntos de datos', 'casa': 'data'}\n    ]),\n    Pregunta(\"¿Qué prefieres al trabajar en equipo?\", [\n        {'texto' : 'Encargarte de la parte visual y de interacción del usuario', 'casa': 'frontend'},\n        {'texto' : 'Asegurarte de que la lógica y los datos fluyan correctamente', 'casa': 'backend'},\n        {'texto' : 'Hacer que la app funcione bien en diferentes dispositivos', 'casa': 'mobile'},\n        {'texto' : 'Proveer métricas y análisis para tomar mejores decisiones', 'casa': 'data'}\n    ]),\n    Pregunta(\"¿Cuál es tu prioridad al optimizar código?\", [\n        {'texto' : 'Que la interfaz cargue rápido y sea amigable', 'casa': 'frontend'},\n        {'texto' : 'Que los servicios backend sean escalables y eficientes', 'casa': 'backend'},\n        {'texto' : 'Que la app móvil consuma pocos recursos y sea fluida', 'casa': 'mobile'},\n        {'texto' : 'Que el procesamiento de datos sea rápido y preciso', 'casa': 'data'}\n    ]),\n    Pregunta(\"¿Qué prefieres al probar una aplicación?\", [\n        {'texto' : 'Verificar que el diseño y la usabilidad sean impecables', 'casa': 'frontend'},\n        {'texto' : 'Asegurar que las funcionalidades y la lógica sean correctas', 'casa' :'backend'},\n        {'texto' : 'Revisar que la app funcione correctamente en múltiples dispositivos', 'casa' : 'mobile'},\n        {'texto' : 'Validar que los resultados de los análisis sean exactos', 'casa' : 'data'}\n    ]),\n    Pregunta(\"¿Qué tipo de proyectos sigues en la industria?\", [\n        {'texto' : 'Proyectos de diseño web innovador y UX', 'casa' : 'frontend'},\n        {'texto' : 'Nuevas tecnologías de servidores y backends', 'casa' : 'backend'},\n        {'texto' : 'Aplicaciones móviles disruptivas y eficientes', 'casa' : 'mobile'},\n        {'texto' : 'Proyectos de inteligencia artificial y ciencia de datos', 'casa' : 'data'}\n    ]),\n    Pregunta(\"¿Qué harías para mejorar una plataforma existente?\", [\n        {'texto' : 'Mejorar la apariencia y usabilidad de la interfaz', 'casa' : 'frontend'},\n        {'texto' : 'Optimizar el rendimiento de las consultas y los servidores', 'casa' : 'backend'},\n        {'texto' : 'Hacer que la plataforma sea accesible desde dispositivos móviles', 'casa' : 'mobile'},\n        {'texto' : 'Incluir más análisis de datos para obtener mejor información', 'casa' : 'data'}\n    ]),\n    Pregunta(\"¿Qué aspecto del desarrollo de software te parece más retador?\", [\n        {'texto' : 'Hacer que una aplicación web sea visualmente atractiva', 'casa' : 'frontend'},\n        {'texto' : 'Crear sistemas backend que manejen millones de usuarios', 'casa' : 'backend'},\n        {'texto' : 'Optimizar la app móvil para diferentes sistemas operativos', 'casa' : 'mobile'},\n        {'texto' : 'Gestionar grandes volúmenes de datos y extraer conclusiones útiles', 'casa' : 'data'}\n    ]),\n]\n\n# Solicitar nombre del alumno\nnombre_alumno = input(\"Por favor, introduce tu nombre: \")\nalumno = Alumno(nombre_alumno)\n\n# Crear instancia del sombrero seleccionador y asignar casa\nsombrero = SombreroSeleccionador(casas, preguntas)\nsombrero.asignar_casa(alumno)\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/python/mouredev.py",
    "content": "import random\n\nhouses = {\n    \"Frontend\": 0,\n    \"Backend\": 0,\n    \"Mobile\": 0,\n    \"Data\": 0\n}\n\nquestions = [\n    {\n        \"question\": \"¿Qué tipo de proyectos te interesa más desarrollar?\",\n        \"answers\": [\n            {\n                \"option\": \"Aplicaciones móviles nativas para múltiples plataformas.\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"Interfaces visualmente atractivas y responsivas.\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Procesamiento y análisis de grandes volúmenes de datos.\",\n                \"house\": \"Data\"\n            },\n            {\n                \"option\": \"Sistemas robustos y optimización de rendimiento del servidor.\",\n                \"house\": \"Backend\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Qué aspecto del desarrollo disfrutas más?\",\n        \"answers\": [\n            {\n                \"option\": \"Resolver problemas complejos de lógica y escalabilidad.\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"Analizar datos para tomar decisiones basadas en estadísticas.\",\n                \"house\": \"Data\"\n            },\n            {\n                \"option\": \"Crear aplicaciones móviles eficientes y funcionales.\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"Trabajar en el diseño y la experiencia de usuario.\",\n                \"house\": \"Frontend\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Qué herramienta prefieres usar en tu día a día?\",\n        \"answers\": [\n            {\n                \"option\": \"Kotlin o Swift para desarrollar apps móviles nativas.\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"Python o R para análisis de datos.\",\n                \"house\": \"Data\"\n            },\n            {\n                \"option\": \"Frameworks como React o Angular.\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Lenguajes como Node.js o Python para la gestión de servidores.\",\n                \"house\": \"Backend\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Cómo te ves en un equipo de desarrollo?\",\n        \"answers\": [\n            {\n                \"option\": \"Modelando datos y construyendo dashboards de análisis.\",\n                \"house\": \"Data\"\n            },\n            {\n                \"option\": \"Encargado de la lógica del servidor y las APIs.\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"Desarrollando la interfaz y funcionalidad de una app móvil.\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"Diseñando las interacciones y los componentes visuales.\",\n                \"house\": \"Frontend\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Qué te motiva más al trabajar en un proyecto?\",\n        \"answers\": [\n            {\n                \"option\": \"Ver cómo el diseño cobra vida en la pantalla.\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Descubrir insights a partir del análisis de datos.\",\n                \"house\": \"Data\"\n            },\n            {\n                \"option\": \"Optimizar el rendimiento y escalabilidad del sistema.\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"Lograr que una aplicación móvil funcione perfectamente en cualquier dispositivo.\",\n                \"house\": \"Mobile\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Cuál es tu enfoque al aprender nuevas tecnologías?\",\n        \"answers\": [\n            {\n                \"option\": \"Explorar técnicas avanzadas de análisis de datos y machine learning.\",\n                \"house\": \"Data\"\n            },\n            {\n                \"option\": \"Aprender sobre nuevas arquitecturas y lenguajes de servidor.\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"Probar nuevas plataformas y herramientas para desarrollo móvil.\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"Experimentar con nuevas librerías y frameworks de interfaz de usuario.\",\n                \"house\": \"Frontend\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Qué tipo de desafíos disfrutas más resolver?\",\n        \"answers\": [\n            {\n                \"option\": \"Solución de problemas de concurrencia y carga en servidores.\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"Optimización de interfaces para que se vean bien en cualquier dispositivo.\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Análisis de grandes volúmenes de datos para detectar patrones ocultos.\",\n                \"house\": \"Data\"},\n            {\n                \"option\": \"Creación de experiencias de usuario fluídas en dispositivos móviles.\",\n                \"house\": \"Mobile\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Cómo te gusta medir el éxito de tu trabajo?\",\n        \"answers\": [\n            {\n                \"option\": \"Por la estabilidad y rapidez del sistema bajo carga.\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"Mediante la satisfacción del usuario con la interfaz visual.\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Por la fluidez y buen rendimiento de la app móvil en diferentes dispositivos.\",\n                \"house\": \"Mobile\"},\n            {\n                \"option\": \"Por la precisión y relevancia de los resultados obtenidos en el análisis de datos.\",\n                \"house\": \"Data\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Qué te resulta más interesante al trabajar con tecnologías emergentes?\",\n        \"answers\": [\n            {\n                \"option\": \"Trabajar con tecnologías de big data o inteligencia artificial.\",\n                \"house\": \"Data\"\n            },\n            {\n                \"option\": \"Explorar nuevas arquitecturas para mejorar el rendimiento del servidor.\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"Probar nuevas herramientas y metodologías para mejorar el diseño y la UX.\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Desarrollar apps móviles que aprovechen nuevas capacidades de hardware.\",\n                \"house\": \"Mobile\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Cómo te enfrentas a un nuevo problema en un proyecto?\",\n        \"answers\": [\n            {\n                \"option\": \"Buscando patrones y soluciones basadas en análisis de datos.\",\n                \"house\": \"Data\"\n            },\n            {\n                \"option\": \"Replanteando la estructura visual y funcional de la interfaz.\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Explorando cómo mejorar la experiencia del usuario en dispositivos móviles.\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"Analizando la estructura de datos y la lógica del backend.\",\n                \"house\": \"Backend\"\n            }\n        ]\n    }\n]\n\nprint(\"\\n¡Bienvenido a Hogwarts, la escuela de programación para magos y brujas del código!\")\nprint(\"El sombrero seleccionador decidirá cuál es tu casa como programador.\")\n\nname = input(\"\\n¿Cuál es tu nombre? \")\n\nfor index, question in enumerate(questions):\n\n    print(f\"\\nPregunta {index + 1}: {question[\"question\"]}\\n\")\n\n    for i, answer in enumerate(question[\"answers\"]):\n        print(f\"{i + 1}. {answer[\"option\"]}\")\n\n    choice = int(input(\"\\nSelecciona una respuesta entre 1 y 4: \"))\n\n    selected_answer = question[\"answers\"][choice - 1]\n    houses[selected_answer[\"house\"]] += 1\n\nassigned_house = max(houses, key=houses.get)\nscores = list(houses.values())\n\nif scores.count(max(scores)) > 1:\n    possible_houses = [\n        house for house,\n        points in houses.items() if points == max(scores)\n    ]\n    assigned_house = random.choice(possible_houses)\n\n    print(\n        f\"\"\"\\nHmmmm... Ha sido una decisión muy complicada, {\n            name}.\\n¡Pero finalmente tu casa será {assigned_house}!\"\"\"\n    )\nelse:\n    print(f\"\\nEnhorabuena, {name}.\\n¡Tu casa será {assigned_house}!\")\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/python/mvidalb.py",
    "content": "'''\nEjercicio mvidalb\n'''\n\nimport random\nimport pprint\n\n# Inicializo las distinas casas\nhouses = {\n    \"Frontend\": 0,\n    \"Backend\": 0,\n    \"Mobile\": 0,\n    \"Data\" : 0\n    }\n\n# Preguntas con sus respuestas y soluciones\nquestions = [\n    {\n        \"pregunta\": \"¿Cuál de los siguientes lenguajes es más comúnmente utilizado para el desarrollo frontend?\",\n        \"respuestas\": {\n            \"a)\": \"Java\",\n            \"b)\": \"Python\",\n            \"c)\": \"JavaScript\",\n            \"d)\": \"Kotlin\"\n        },\n        \"soluciones\": {\n            \"a)\": \"Backend\",\n            \"b)\": \"Data\",\n            \"c)\": \"Frontend\",\n            \"d)\": \"Mobile\"\n        }\n    },\n    {\n        \"pregunta\": \"En el contexto del desarrollo backend, ¿cuál es un framework popular para Node.js?\",\n        \"respuestas\": {\n            \"a)\": \"React\",\n            \"b)\": \"Laravel\",\n            \"c)\": \"Django\",\n            \"d)\": \"Express\"\n        },\n        \"soluciones\": {\n            \"a)\": \"Frontend\",\n            \"b)\": \"Backend\",\n            \"c)\": \"Data\",\n            \"d)\": \"Mobile\"\n        }\n    },\n    {\n        \"pregunta\": \"¿Qué lenguaje es conocido por ser ampliamente utilizado en el desarrollo de aplicaciones móviles nativas para Android?\",\n        \"respuestas\": {\n            \"a)\": \"Swift\",\n            \"b)\": \"Kotlin\",\n            \"c)\": \"Flutter\",\n            \"d)\": \"Objective-C\"\n        },\n        \"soluciones\": {\n            \"a)\": \"Mobile\",\n            \"b)\": \"Mobile\",\n            \"c)\": \"Frontend\",\n            \"d)\": \"Backend\"\n        }\n    },\n    {\n        \"pregunta\": \"En ciencia de datos, ¿qué biblioteca de Python es más conocida para trabajar con grandes volúmenes de datos?\",\n        \"respuestas\": {\n            \"a)\": \"Pandas\",\n            \"b)\": \"TensorFlow\",\n            \"c)\": \"NumPy\",\n            \"d)\": \"Keras\"\n        },\n        \"soluciones\": {\n            \"a)\": \"Data\",\n            \"b)\": \"Mobile\",\n            \"c)\": \"Frontend\",\n            \"d)\": \"Backend\"\n        }\n    },\n    {\n        \"pregunta\": \"¿Cuál de estas tecnologías es comúnmente usada para la gestión del estado en aplicaciones frontend?\",\n        \"respuestas\": {\n            \"a)\": \"Redux\",\n            \"b)\": \"Flask\",\n            \"c)\": \"MongoDB\",\n            \"d)\": \"Spring Boot\"\n        },\n        \"soluciones\": {\n            \"a)\": \"Frontend\",\n            \"b)\": \"Backend\",\n            \"c)\": \"Data\",\n            \"d)\": \"Mobile\"\n        }\n    },\n    {\n        \"pregunta\": \"En el desarrollo backend, ¿cuál de las siguientes bases de datos es relacional?\",\n        \"respuestas\": {\n            \"a)\": \"MongoDB\",\n            \"b)\": \"Redis\",\n            \"c)\": \"MySQL\",\n            \"d)\": \"Cassandra\"\n        },\n        \"soluciones\": {\n            \"a)\": \"Data\",\n            \"b)\": \"Mobile\",\n            \"c)\": \"Backend\",\n            \"d)\": \"Frontend\"\n        }\n    },\n    {\n        \"pregunta\": \"¿Qué framework es comúnmente utilizado para desarrollar aplicaciones móviles multiplataforma?\",\n        \"respuestas\": {\n            \"a)\": \"Xamarin\",\n            \"b)\": \"Swift\",\n            \"c)\": \"Kotlin\",\n            \"d)\": \"React Native\"\n        },\n        \"soluciones\": {\n            \"a)\": \"Mobile\",\n            \"b)\": \"Frontend\",\n            \"c)\": \"Backend\",\n            \"d)\": \"Data\"\n        }\n    },\n    {\n        \"pregunta\": \"¿Qué es un concepto clave de las bases de datos en el campo de los datos masivos (Big Data)?\",\n        \"respuestas\": {\n            \"a)\": \"DOM\",\n            \"b)\": \"Cluster\",\n            \"c)\": \"ORM\",\n            \"d)\": \"CDN\"\n        },\n        \"soluciones\": {\n            \"a)\": \"Frontend\",\n            \"b)\": \"Data\",\n            \"c)\": \"Backend\",\n            \"d)\": \"Mobile\"\n        }\n    },\n    {\n        \"pregunta\": \"¿Cuál de las siguientes tecnologías es esencial para el diseño de interfaces de usuario en el desarrollo frontend?\",\n        \"respuestas\": {\n            \"a)\": \"CSS\",\n            \"b)\": \"Flask\",\n            \"c)\": \"Hadoop\",\n            \"d)\": \"Redis\"\n        },\n        \"soluciones\": {\n            \"a)\": \"Frontend\",\n            \"b)\": \"Backend\",\n            \"c)\": \"Data\",\n            \"d)\": \"Mobile\"\n        }\n    },\n    {\n        \"pregunta\": \"¿Cuál de estos es un patrón de diseño común en la arquitectura backend?\",\n        \"respuestas\": {\n            \"a)\": \"MVC (Model-View-Controller)\",\n            \"b)\": \"CSS Grid\",\n            \"c)\": \"JWT (JSON Web Token)\",\n            \"d)\": \"Kafka\"\n        },\n        \"soluciones\": {\n            \"a)\": \"Backend\",\n            \"b)\": \"Frontend\",\n            \"c)\": \"Mobile\",\n            \"d)\": \"Data\"\n        }\n    }\n]\n\n# Método para calcular la puntuación de cada casa en función de la respuesta seleccionada\ndef add_score(houses, question, final_answer) -> dict:\n    answer_selected = question[\"soluciones\"][final_answer + \")\"]\n    for house in houses:\n        if answer_selected == house:\n            houses[answer_selected] += 2   # 2 puntos para una casa si seleccionas esta respuesta\n   \n    return houses\n\n# Comienzo el programa\nprint(\"\\nSOMBRERO SELECCIONADOR!\")\nname = input(\"¿Cuál es tu nombre, querido mago?: \")\nprint(f\"\\nGracias por hacerme saber tu nombre, {name}! Elige sabiamente para que el sombrero seleccionador escoja bien tu destino:\")\n\n# Recorro el diccionario de preguntas\nfor i, question in enumerate(questions):\n    print(f\"\\n{i+1}. \" +  question[\"pregunta\"])\n    for answers in question[\"respuestas\"].items():\n        print(\"  \" + answers[0] + \" \" + answers[1])  # Opciones en cada pregunta mostradas por consola\n\n    while True:  # Ejecutar hasta que se seleccione una respuesta correcta\n        final_answer = input(\"\\nSelecciona respuesta: \")\n        if final_answer in [\"a\", \"b\", \"c\", \"d\"]:\n            houses = add_score(houses, question, final_answer)  # Calculo la nueva puntuación de cada casa\n            break\n        else:\n            print(\"Cáspitas! Ha ocurrido un error, selecciona una respuesta correcta.\")\n    \n    print(\"\\nPuntuación en tiempo real:\")\n    pprint.pprint(houses, width = 20)\n\n\n# Compruebo qué casa ha obtenido mayor puntuación\nwinning_house = [key for key, value in houses.items() if value == max(houses.values())] # Máximo valor del dict houses\nif len(winning_house) != 1:\n    winning_house = [random.choice(winning_house)]\n    print(f\"\\nENHORABUENA {name}! Ha sido una decisión muuuy difícil, pero eres nuevo integrante de la casa {winning_house[0].upper()}, buena suerte!\\n\")\nelse: \n    print(f\"\\nENHORABUENA {name}! Eres nuevo integrante de la casa {winning_house[0].upper()}, buena suerte!\\n\")\n\n\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/python/neslarra.py",
    "content": "\"\"\"\n EJERCICIO:\n Cada 1 de septiembre, el Hogwarts Express parte hacia la escuela\n de programación de Hogwarts para magos y brujas del código.\n En ella, su famoso sombrero seleccionador ayuda a los programadores\n a encontrar su camino...\n Desarrolla un programa que simule el comportamiento del sombrero.\n Requisitos:\n 1. El sombrero realizará 10 preguntas para determinar la casa del alumno.\n 2. Deben existir 4 casas. Por ejemplo: Frontend, Backend, Mobile y Data.\n    (Puedes elegir las que quieras)\n Acciones:\n 1. Crea un programa que solicite el nombre del alumno y realice 10\n    preguntas, con cuatro posibles respuestas cada una.\n 2. Cada respuesta asigna puntos a cada una de las casas (a tu elección).\n 3. Una vez finalizado, el sombrero indica el nombre del alumno \n    y a qué casa pertenecerá (resuelve el posible empate de manera aleatoria,\n    pero indicándole al alumno que la decisión ha sido complicada).\n\"\"\"\nfrom random import randint, choice\n\n\ndef casa(backend, data_science, frontend, mobile):\n    decision = \"fácil\"\n    resultados = {\"Backend\": backend, \"Data Science\": data_science, \"Frontend\": frontend, \"Mobile\": mobile}\n    maximo_puntaje = max(resultados.values())\n    if [resultados.values()].count(maximo_puntaje) > 1:\n        decision = \"reñida\"\n    return choice([x for x, y in resultados.items() if y == maximo_puntaje]), decision\n\n\ncasas = {\"Backend\": [], \"Data Science\": [], \"Frontend\": [], \"Mobile\": []}\npreguntas = {1: {\"pregunta\": \"¿Qué valoras más en tus amigos?\",\n                 \"respuestas\": [\"Lealtad\",\n                                \"Inteligencia\",\n                                \"Valentía\",\n                                \"Ambición\"]},\n             2: {\"pregunta\": \"¿Cuál de estas actividades prefieres hacer en tu tiempo libre?\",\n                 \"respuestas\": [\"Leer un libro interesante\",\n                                \"Explorar lugares desconocidos\",\n                                \"Participar en un duelo amistoso\",\n                                \"Planificar tu futuro éxito\"]},\n             3: {\"pregunta\": \"Si te enfrentas a un desafío, ¿cómo reaccionas?\",\n                 \"respuestas\": [\"Analizas todas las opciones antes de actuar\",\n                                \"Enfrentas el problema de frente sin miedo\",\n                                \"Buscas la ayuda de tus amigos y trabajas en equipo\",\n                                \"Encuentras una forma ingeniosa de resolverlo para salir beneficiado\"]},\n             4: {\"pregunta\": \"¿Cuál de estas criaturas mágicas te parece más fascinante?\",\n                 \"respuestas\": [\"Un Fénix, por su capacidad de renacer\",\n                                \"Un Dragón, por su fuerza y poder\",\n                                \"Un Hipogrifo, por su nobleza y orgullo\",\n                                \"Un Nundu, por su letalidad y sigilo\"]},\n             5: {\"pregunta\": \"Si tuvieras que elegir una poción mágica, ¿cuál preferirías?\",\n                 \"respuestas\": [\"Una poción que te hiciera invencible\",\n                                \"Una poción de inteligencia suprema\",\n                                \"Una poción de suerte infinita\",\n                                \"Una poción de invisibilidad\"]},\n             6: {\"pregunta\": \"¿Qué es lo más importante para ti en un líder?\",\n                 \"respuestas\": [\"Su sabiduría y capacidad para guiar\",\n                                \"Su coraje y determinación\",\n                                \"Su integridad y justicia\",\n                                \"Su ambición y visión\"]},\n             7: {\"pregunta\": \"Si pudieras elegir una habilidad mágica, ¿cuál sería?\",\n                 \"respuestas\": [\"La habilidad de volar\",\n                                \"La capacidad de hablar con animales\",\n                                \"El poder de la transformación\",\n                                \"La capacidad de leer mentes\"]},\n             8: {\"pregunta\": \"¿Qué tipo de compañeros de clase prefieres?\",\n                 \"respuestas\": [\"Aquellos que te desafían intelectualmente\",\n                                \"Aquellos que te apoyan en todo momento\",\n                                \"Aquellos que te inspiran a ser valiente\",\n                                \"Aquellos que te ayudan a alcanzar tus metas\"]},\n             9: {\"pregunta\": \"¿Cómo te sentirías si tuvieras que romper las reglas para lograr algo importante?\",\n                 \"respuestas\": [\"Lo haría solo si es absolutamente necesario\",\n                                \"Lo haría con valentía y sin remordimientos\",\n                                \"Preferiría encontrar una manera de evitar romperlas\",\n                                \"Lo haría estratégicamente para obtener el máximo beneficio\"]},\n             10: {\"pregunta\": \"¿Qué cualidad crees que te define mejor?\",\n                  \"respuestas\": [\"Sabiduría\",\n                                 \"Valentía\",\n                                 \"Lealtad\",\n                                 \"Ambición\"]}\n             }\n\npuntaje = []\n\nwhile True:\n    alumno = input(\"\\nNombre: \").title()\n    if not alumno:\n        break\n    for numero, pregunta in preguntas.items():\n        print(f'\\tPregunta nro {numero}: {pregunta[\"pregunta\"]}')\n        seleccion = randint(0, 3)\n        print(f'\\tRespuesta: {pregunta[\"respuestas\"][seleccion]}')\n        puntaje.append(seleccion)\n    casa_seleccionada, decision = casa(puntaje.count(0), puntaje.count(1), puntaje.count(2), puntaje.count(3))\n    casas[casa_seleccionada].append(alumno)\n    print(f\"{alumno} has sido elegido para {casa_seleccionada} y fue una decisión {decision}\")\n    puntaje.clear()\n\nfor casa, alumnos in casas.items():\n    print(f\"\\nLa casa {casa} tiene {alumnos.__len__()} alumnos\")\n    for alno in alumnos:\n        print(f\"\\tAlumno: {alno}\")\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/python/oriaj3.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Cada 1 de septiembre, el Hogwarts Express parte hacia la escuela\n * de programación de Hogwarts para magos y brujas del código.\n * En ella, su famoso sombrero seleccionador ayuda a los programadores\n * a encontrar su camino...\n * Desarrolla un programa que simule el comportamiento del sombrero.\n * Requisitos:\n * 1. El sombrero realizará 10 preguntas para determinar la casa del alumno.\n * 2. Deben existir 4 casas. Por ejemplo: Frontend, Backend, Mobile y Data.\n *    (Puedes elegir las que quieras)\n * Acciones:\n * 1. Crea un programa que solicite el nombre del alumno y realice 10\n *    preguntas, con cuatro posibles respuestas cada una.\n * 2. Cada respuesta asigna puntos a cada una de las casas (a tu elección).\n * 3. Una vez finalizado, el sombrero indica el nombre del alumno \n *    y a qué casa pertenecerá (resuelve el posible empate de manera aleatoria,\n *    pero indicándole al alumno que la decisión ha sido complicada).\n */\n\"\"\"\n#Introduction to the program\nprint(\"¡Bienvenido al Sombrero Seleccionador de Hogwarts para personalidades!\")\nprint(\"Responde a las siguientes preguntas para descubrir a qué casa perteneces según tu personalidad.\")\nprint(\"Por favor, elige la opción que mejor te describa en cada pregunta.\")\nprint(\"Las opciones siempre son: A, B, C, D.\")\nprint(\"Para responder, escribe la letra correspondiente y pulsa Enter.\")\ninput(\"Pulsa Enter para comenzar...\")\n\n# Dictionary with the questions and answers\nquestions_answers = {\n    \"¿Cómo te enfrentas a los problemas complejos?\": {\n        \"Analítico\": \"Divido el problema en partes y analizo cada una.\",\n        \"Creativo\": \"Busco soluciones fuera de lo común.\",\n        \"Pragmático\": \"Me concentro en resolverlo de la manera más efectiva y directa.\",\n        \"Emocional\": \"Sigo mis instintos para encontrar la solución.\"\n    },\n    \"¿Qué te motiva en tu trabajo?\": {\n        \"Analítico\": \"Resolver problemas difíciles con lógica.\",\n        \"Creativo\": \"Innovar y crear nuevas ideas.\",\n        \"Pragmático\": \"Cumplir con las expectativas y ser eficiente.\",\n        \"Emocional\": \"Trabajar en algo que me apasione.\"\n    },\n    \"¿Cómo organizas tu día?\": {\n        \"Analítico\": \"Creo un plan detallado y lo sigo estrictamente.\",\n        \"Creativo\": \"Prefiero dejar espacio para la espontaneidad.\",\n        \"Pragmático\": \"Me aseguro de completar las tareas esenciales primero.\",\n        \"Emocional\": \"Organizo mi día según mi estado de ánimo.\"\n    },\n    \"¿Cómo manejas la presión?\": {\n        \"Analítico\": \"Mantengo la calma y analizo la situación lógicamente.\",\n        \"Creativo\": \"Encuentro formas creativas de lidiar con ella.\",\n        \"Pragmático\": \"Me enfoco en las prioridades y actúo con eficacia.\",\n        \"Emocional\": \"Me apoyo en mis emociones para superar el estrés.\"\n    },\n    \"¿Qué prefieres hacer en tu tiempo libre?\": {\n        \"Analítico\": \"Resolver acertijos o problemas lógicos.\",\n        \"Creativo\": \"Hacer arte o actividades creativas.\",\n        \"Pragmático\": \"Realizar actividades prácticas y productivas.\",\n        \"Emocional\": \"Conectar con amigos o actividades que me hagan sentir bien.\"\n    },\n    \"¿Cómo tomas decisiones importantes?\": {\n        \"Analítico\": \"Analizo todos los datos antes de decidir.\",\n        \"Creativo\": \"Pienso en soluciones innovadoras.\",\n        \"Pragmático\": \"Tomo decisiones rápidas y eficaces.\",\n        \"Emocional\": \"Dejo que mis emociones me guíen.\"\n    },\n    \"¿Qué prefieres en un proyecto de grupo?\": {\n        \"Analítico\": \"Organizar y dividir las tareas por lógica.\",\n        \"Creativo\": \"Aportar ideas nuevas y creativas.\",\n        \"Pragmático\": \"Asegurar que el proyecto se mantenga en el camino correcto.\",\n        \"Emocional\": \"Motivarme a través de las emociones del equipo.\"\n    },\n    \"¿Cómo reaccionas cuando algo no sale según lo planeado?\": {\n        \"Analítico\": \"Reevalúo el problema y busco una solución lógica.\",\n        \"Creativo\": \"Pienso en alternativas fuera de lo común.\",\n        \"Pragmático\": \"Busco la forma más práctica de corregirlo.\",\n        \"Emocional\": \"Me dejo llevar por la frustración o tristeza pero luego encuentro una forma de avanzar.\"\n    },\n    \"¿Qué prefieres en un ambiente laboral?\": {\n        \"Analítico\": \"Tener claro qué hacer y cómo hacerlo.\",\n        \"Creativo\": \"Espacio para innovar y explorar nuevas ideas.\",\n        \"Pragmático\": \"Procesos organizados y eficientes.\",\n        \"Emocional\": \"Un ambiente en el que se valoren los sentimientos y la colaboración.\"\n    },\n    \"¿Cómo manejas el fracaso?\": {\n        \"Analítico\": \"Lo analizo para aprender de los errores.\",\n        \"Creativo\": \"Lo uso como inspiración para pensar de manera diferente.\",\n        \"Pragmático\": \"Acepto el fracaso y busco la manera de corregirlo rápidamente.\",\n        \"Emocional\": \"Me afecta emocionalmente, pero lo uso como motivación para mejorar.\"\n    }\n}\n\n#Print the questions and answers to the user and save the answers\nanswers_user = []\n\n# Lista de letras válidas\nletter_index = [\"A\", \"B\", \"C\", \"D\"]\n\ndef ask_answer() -> str:\n    # Bucle para pedir opciones al usuario\n    while True:\n        # Solicita la entrada del usuario\n        option = input(\"Introduce una opción (A, B, C, D): \").upper()\n\n        # Comprueba si la opción es válida\n        if option in letter_index:\n            # Devuelve la opción válida\n            return option\n        else:\n            # Si la opción no es válida, muestra un mensaje y repite el bucle\n            print(\"Opción inválida. Inténtalo de nuevo.\")\n\nfor index, (question, answers) in enumerate(questions_answers.items()):\n    print(f\"{index + 1}. {question}\")\n    for index, (_, answer) in enumerate(answers.items()):\n        print(f\"  - {letter_index[index]}: {answer}\")\n    answers_user.append(ask_answer())\n\n#Count answers\ncount ={\n    \"Analítico\": 0,\n    \"Creativo\": 0,\n    \"Pragmático\": 0, \n    \"Emocional\": 0    \n}\n\n#Mapping the answers a, b, c, d to the personality types\ncount_mapping = {\n    \"A\": \"Analítico\",\n    \"B\": \"Creativo\",\n    \"C\": \"Pragmático\",\n    \"D\": \"Emocional\"\n}\n\nfor answer in answers_user:\n    count[count_mapping[answer]] += 1\n\n#Check if there is a tie\nmax_value = max(count.values())\nif list(count.values()).count(max_value) > 1:\n    print(\"La decisión ha sido complicada, pero...\")\nelse:\n    print(\"El sombrero seleccionador ha decidido que...\")\nprint(\"Tu casa es:\")\nprint(max(count, key=count.get))\n\n    \n\n\n\n\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/python/pyramsd.py",
    "content": "import random\n\ncasas = {\n    \"a\":\"Fronted\",\n    \"b\":\"Backend\",\n    \"c\":\"Mobile\",\n    \"d\":\"Data\"\n}\n\npreguntas_y_alternativas = [\n    {\n        \"pregunta\":\"1. ¿Qué enfoque es clave para garantizar una experiencia de usuario atractiva y funcional?\",\n        \"alternativas\":[\n            \"a) Diseño responsivo \",\n            \"b) Creación de una API robusta\",\n            \"c) Optimización de la aplicación para múltiples dispositivos\",\n            \"d) Uso eficiente de análisis de datos\"\n        ]\n    },\n    {\n        \"pregunta\":\"2. ¿Cuál es la prioridad principal al trabajar con seguridad en un proyecto?\",\n        \"alternativas\":[\n            \"a) Sanitizar entradas en formularios\",\n            \"b) Implementar autenticación y control de acceso\",\n            \"c) Garantizar permisos correctos en aplicaciones móviles\",\n            \"d) Cifrar datos sensibles almacenados\"\n        ]\n    },\n    {\n        \"pregunta\":\"3. ¿Qué se debe considerar al mejorar el rendimiento de un sistema?\",\n        \"alternativas\":[\n            \"a) Minimizar archivos CSS y JavaScript\",\n            \"b) Optimizar consultas a la base de datos\",\n            \"c) Reducir el tamaño de la app para descargas rápidas\",\n            \"d) Procesar grandes volúmenes de datos en paralelo\"\n        ]\n    },\n    {\n        \"pregunta\":\"4. ¿Cuál sería el mejor enfoque para personalizar la experiencia del usuario?\",\n        \"alternativas\":[\n            \"a) Usar cookies o almacenamiento local para recordar preferencias\",\n            \"b) Crear endpoints específicos para cada usuario\",\n            \"c) Integrar notificaciones push personalizadas\",\n            \"d) Utilizar modelos de recomendación basados en datos\"\n        ]\n    },\n    {\n        \"pregunta\":\"5. ¿Qué técnica es fundamental para la escalabilidad de un sistema?\",\n        \"alternativas\":[\n            \"a) Usar frameworks modernos para optimizar el DOM\",\n            \"b) Implementar microservicios\",\n            \"c) Escalar la aplicación a diferentes plataformas\",\n            \"d) Aplicar particionamiento en bases de datos\"\n        ]\n    },\n    {\n        \"pregunta\":\"6. ¿Qué enfoque es esencial para un desarrollo ágil y colaborativo?\",\n        \"alternativas\":[\n            \"a) Uso de componentes reutilizables en UI\",\n            \"b) Configuración de un servidor de desarrollo local\",\n            \"c) Pruebas en múltiples simuladores y dispositivos\",\n            \"d) Versionamiento adecuado de conjuntos de datos\"\n        ]\n    },\n    {\n        \"pregunta\":\"7. ¿Qué característica mejora la accesibilidad del sistema?\",\n        \"alternativas\":[\n            \"a) Implementar navegación por teclado y lectores de pantalla\",\n            \"b) Generar mensajes de error claros desde el servidor\",\n            \"c) Ajustar el tamaño del texto y elementos táctiles\",\n            \"d) Garantizar datos fácilmente interpretables en visualizaciones\"\n        ]\n    },\n    {\n        \"pregunta\":\"8. ¿Qué aspecto es crítico al realizar pruebas en el desarrollo?\",\n        \"alternativas\":[\n            \"a) Validar interacciones y animaciones de la interfaz\",\n            \"b) Probar endpoints de la API con datos de prueba\",\n            \"c) Verificar comportamiento en distintas versiones del sistema operativo\",\n            \"d) Evaluar precisión de los modelos predictivos\"\n        ]\n    },\n    {\n        \"pregunta\":\"9. ¿Cómo manejar eficientemente errores en el sistema?\",\n        \"alternativas\":[\n            \"a) Mostrar mensajes amigables y descriptivos para el usuario\",\n            \"b) Registrar errores en archivos de log centralizados\",\n            \"c) Implementar seguimiento de fallos con herramientas como Crashlytics\",\n            \"d) Detectar valores anómalos en flujos de datos\"\n        ]\n    },\n    {\n        \"pregunta\":\"10. ¿Qué es importante al trabajar con integraciones de terceros?\",\n        \"alternativas\":[\n            \"a) Implementar SDKs con compatibilidad garantizada\",\n            \"b) Configurar endpoints para servicios externos\",\n            \"c) Gestionar dependencias de bibliotecas móviles\",\n            \"d) Normalizar los datos provenientes de múltiples fuentes\"\n        ]\n    }\n]\n\npnts = {\"a\":0, \"b\":0, \"c\":0, \"d\":0}\n\nprint(\"\\t\\t\\tBinvenido a la escuela de desarrollo!\\\n    \\n\\t\\t\\t-------------------\\\n    \\nEl sombrero seleccionardor se encargará de seleccionar tu casa de desarrollo\\\n    \\n--------------------------------------------------------------------------\")\n\nr_valida = False\n\nwhile not r_valida:\n    try:\n        for pregunta in preguntas_y_alternativas:\n            print(f'\\n{pregunta[\"pregunta\"]}')\n            for alternativa in pregunta[\"alternativas\"]:\n                print(alternativa)\n            r = input(\"Rpta (a, b, c, d): \").lower()\n            if r not in pnts:\n                raise ValueError(f\"Alternativa no válida: {r}\")\n            pnts[r] += 1\n        r_valida = True\n    except ValueError as e:\n        print(f\"Error: {e}\\nIntente de nuevo\")\n\nmax_pnts = max(pnts.values())\nempates = [casa for casa, puntos in pnts.items() if puntos == max_pnts]\n\nif len(empates) > 1:\n    print(\"\\nLa decisión fue complicada...\")\n    casa_final = casas[random.choice(empates)]\nelse:\n    casa_final = casas[empates[0]]\n\nprint(f\"Eres {casa_final}!\")\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/python/raulG91.py",
    "content": "import random\nhouse = {\n    'frontend': 0,\n    'backend': 0,\n    'mobile': 0,\n    'data':0\n}\n\nname = input('Enter your name ')\n\nprint(\"1 - WHat's your favourite framework ?\")\nprint(\" a React\")\nprint(\" b Node.js\")\nprint(\" c Flutter\")\nprint(\" d Keras\")\nchoice = input(\"> \")\nchoice = choice.lower()\n\nmatch choice:\n    case 'a': house['frontend'] += 1\n    case 'b': house['backend'] += 1\n    case 'c': house['mobile'] += 1\n    case 'd': house['data'] += 1\n    case _: print(\"Incorrect option \")\n\nprint(\"2 - which language do you prefer?\")\nprint(\" a Python\")\nprint(\" b HTML/CSS\")\nprint(\" c Java\")\nprint(\" d Kotlin\")\nchoice = input(\"> \")\nchoice = choice.lower()\nmatch choice:\n    case 'a': house['data'] += 1\n    case 'b': house['frontend'] += 1\n    case 'c': house['backend'] += 1\n    case 'd': house['mobile'] += 1\n    case _: print(\"Incorrect option \")\n\nprint(\"3 - Which activity do you prefer\")\nprint(\" a Build UI interfaces\")\nprint(\" b Develop APIs\")\nprint(\" c Apps for mobile\")\nprint(\" d Analyse data from a source\")\nchoice = input(\"> \")\nchoice = choice.lower()\nmatch choice:\n    case 'a': house['frontend'] += 1\n    case 'b': house['backend'] += 1\n    case 'c': house['mobile'] += 1\n    case 'd': house['data'] += 1\n    case _: print(\"Incorrect option \")\n\nprint(\"4 - Where do you want to view your apps\")\nprint(\" a Browser\")\nprint(\" b SAAS\")\nprint(\" c App store/Play store\")\nprint(\" d Other\")\nchoice = input(\"> \")\nchoice = choice.lower()\nmatch choice:\n    case 'a': house['frontend'] += 1\n    case 'b': house['backend'] += 1\n    case 'c': house['mobile'] += 1\n    case 'd': house['data'] += 1\n    case _: print(\"Incorrect option \")\n\nprint(\"5 - What is more valuable for you?\")\nprint(\" a Create a nice UI\")\nprint(\" b Analyse data and create reports\")\nprint(\" c Use your app everywhere with your phone\")\nprint(\" d Create a solution for a problem\")\nchoice = input(\"> \")\nchoice = choice.lower()\nmatch choice:\n    case 'a': house['frontend'] += 1\n    case 'b': house['data'] += 1\n    case 'c': house['mobile'] += 1\n    case 'd': house['backend'] += 1\n    case _: print(\"Incorrect option \")\n\n\nprint(\"6 - Which tool do you prefer to learn?\")\nprint(\" a Android studio\")\nprint(\" b Figma\")\nprint(\" c Power BI\")\nprint(\" d Mongo DB\")\nchoice = input(\"> \")\nchoice = choice.lower()\nmatch choice:\n    case 'a': house['mobile'] += 1\n    case 'b': house['frontend'] += 1\n    case 'c': house['data'] += 1\n    case 'd': house['backend'] += 1\n    case _: print(\"Incorrect option \")\n\nprint(\"7 - if you need to optimze something what do you prefer?\")\nprint(\" a Optimize database access\")\nprint(\" b Optimize response time\")\nprint(\" c Optimize UI\")\nprint(\" d Other\")\nchoice = input(\"> \")\nchoice = choice.lower()\nmatch choice:\n    case 'a': house['backend'] += 1\n    case 'b': house['mobile'] += 1\n    case 'c': house['frontend'] += 1\n    case 'd': house['data'] += 1\n    case _: print(\"Incorrect option \")\n\nprint(\"8 - Do you know any of the following technologies?\")\nprint(\" a Docker\")\nprint(\" b Vue\")\nprint(\" c Swift\")\nprint(\" d Bigquery\")\nchoice = input(\"> \")\nchoice = choice.lower()\nmatch choice:\n    case 'a': house['backend'] += 1\n    case 'b': house['frontend'] += 1\n    case 'c': house['mobile'] += 1\n    case 'd': house['data'] += 1\n    case _: print(\"Incorrect option \")\n\nprint(\"9 - How do you see your carreer in 5 years?\")\nprint(\" a UI Master\")\nprint(\" b Backend master\")\nprint(\" c Mobile master\")\nprint(\" d Data master\")\nchoice = input(\"> \")\nchoice = choice.lower()\nmatch choice:\n    case 'a': house['frontend'] += 1\n    case 'b': house['backend'] += 1\n    case 'c': house['mobile'] += 1\n    case 'd': house['data'] += 1\n    case _: print(\"Incorrect option \")\n\nbigger = 0\nhouses_selected = []\nprint(house)\nfor element in house:\n    if house[element]> bigger:\n        bigger = house[element]\n        houses_selected = []\n        houses_selected.append(element)\n    elif house[element] == bigger:\n        houses_selected.append(element)   \n\nprint(f'Name {name} house: {random.choices(houses_selected)}')        "
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/python/redom69.py",
    "content": "\"\"\"\n EJERCICIO:\n Cada 1 de septiembre, el Hogwarts Express parte hacia la escuela\n de programación de Hogwarts para magos y brujas del código.\n En ella, su famoso sombrero seleccionador ayuda a los programadores\n a encontrar su camino...\n Desarrolla un programa que simule el comportamiento del sombrero.\n Requisitos:\n 1. El sombrero realizará 10 preguntas para determinar la casa del alumno.\n 2. Deben existir 4 casas. Por ejemplo: Frontend, Backend, Mobile y Data.\n    (Puedes elegir las que quieras)\n Acciones:\n 1. Crea un programa que solicite el nombre del alumno y realice 10\n    preguntas, con cuatro posibles respuestas cada una.\n 2. Cada respuesta asigna puntos a cada una de las casas (a tu elección).\n 3. Una vez finalizado, el sombrero indica el nombre del alumno \n    y a qué casa pertenecerá (resuelve el posible empate de manera aleatoria,\n    pero indicándole al alumno que la decisión ha sido complicada).\n\"\"\"\n\npreguntas = {\n    \"pregunta_1\": {\n        \"pregunta\": \"¿Qué es lo que más disfrutas al programar?\",\n        \"opciones\": {\n            \"a\": {\"respuesta\": \"Diseñar interfaces atractivas\", \"casa\": \"Frontend\"},\n            \"b\": {\"respuesta\": \"Optimizar el rendimiento del servidor\", \"casa\": \"Backend\"},\n            \"c\": {\"respuesta\": \"Crear aplicaciones móviles útiles\", \"casa\": \"Mobile\"},\n            \"d\": {\"respuesta\": \"Analizar grandes conjuntos de datos\", \"casa\": \"Data\"}\n        }\n    },\n    \"pregunta_2\": {\n        \"pregunta\": \"¿Qué tipo de proyecto te atrae más?\",\n        \"opciones\": {\n            \"a\": {\"respuesta\": \"Aplicaciones web con mucho estilo\", \"casa\": \"Frontend\"},\n            \"b\": {\"respuesta\": \"Sistemas que manejen grandes volúmenes de datos\", \"casa\": \"Backend\"},\n            \"c\": {\"respuesta\": \"Aplicaciones para teléfonos inteligentes\", \"casa\": \"Mobile\"},\n            \"d\": {\"respuesta\": \"Dashboards para visualizar información\", \"casa\": \"Data\"}\n        }\n    },\n    \"pregunta_3\": {\n        \"pregunta\": \"¿Qué herramienta te resulta más interesante?\",\n        \"opciones\": {\n            \"a\": {\"respuesta\": \"HTML, CSS y JavaScript\", \"casa\": \"Frontend\"},\n            \"b\": {\"respuesta\": \"Node.js o Python\", \"casa\": \"Backend\"},\n            \"c\": {\"respuesta\": \"React Native o Swift\", \"casa\": \"Mobile\"},\n            \"d\": {\"respuesta\": \"SQL o Python con Pandas\", \"casa\": \"Data\"}\n        }\n    },\n    \"pregunta_4\": {\n        \"pregunta\": \"¿Cuál es tu mayor fortaleza como programador?\",\n        \"opciones\": {\n            \"a\": {\"respuesta\": \"Crear interfaces amigables\", \"casa\": \"Frontend\"},\n            \"b\": {\"respuesta\": \"Solucionar problemas complejos en el servidor\", \"casa\": \"Backend\"},\n            \"c\": {\"respuesta\": \"Desarrollar apps funcionales\", \"casa\": \"Mobile\"},\n            \"d\": {\"respuesta\": \"Encontrar patrones en los datos\", \"casa\": \"Data\"}\n        }\n    },\n    \"pregunta_5\": {\n        \"pregunta\": \"¿Qué prefieres en un equipo de desarrollo?\",\n        \"opciones\": {\n            \"a\": {\"respuesta\": \"Ser quien diseña el look y feel\", \"casa\": \"Frontend\"},\n            \"b\": {\"respuesta\": \"Ser quien gestiona la arquitectura de la aplicación\", \"casa\": \"Backend\"},\n            \"c\": {\"respuesta\": \"Ser quien se encarga de la versión móvil\", \"casa\": \"Mobile\"},\n            \"d\": {\"respuesta\": \"Ser quien analiza el rendimiento del sistema\", \"casa\": \"Data\"}\n        }\n    },\n    \"pregunta_6\": {\n        \"pregunta\": \"¿En qué te enfocas más cuando trabajas en un proyecto?\",\n        \"opciones\": {\n            \"a\": {\"respuesta\": \"En el diseño visual y la experiencia de usuario\", \"casa\": \"Frontend\"},\n            \"b\": {\"respuesta\": \"En la estabilidad y escalabilidad del sistema\", \"casa\": \"Backend\"},\n            \"c\": {\"respuesta\": \"En hacer que la app funcione en dispositivos móviles\", \"casa\": \"Mobile\"},\n            \"d\": {\"respuesta\": \"En el análisis y visualización de los datos\", \"casa\": \"Data\"}\n        }\n    },\n    \"pregunta_7\": {\n        \"pregunta\": \"¿Cuál es tu mayor motivación como desarrollador?\",\n        \"opciones\": {\n            \"a\": {\"respuesta\": \"Crear experiencias de usuario memorables\", \"casa\": \"Frontend\"},\n            \"b\": {\"respuesta\": \"Resolver problemas complejos con eficiencia\", \"casa\": \"Backend\"},\n            \"c\": {\"respuesta\": \"Desarrollar aplicaciones que la gente use todos los días\", \"casa\": \"Mobile\"},\n            \"d\": {\"respuesta\": \"Descubrir patrones ocultos en los datos\", \"casa\": \"Data\"}\n        }\n    },\n    \"pregunta_8\": {\n        \"pregunta\": \"¿Qué aspecto prefieres de un nuevo proyecto?\",\n        \"opciones\": {\n            \"a\": {\"respuesta\": \"Hacer que se vea genial y sea fácil de usar\", \"casa\": \"Frontend\"},\n            \"b\": {\"respuesta\": \"Asegurarme de que el servidor funcione sin problemas\", \"casa\": \"Backend\"},\n            \"c\": {\"respuesta\": \"Hacer que funcione bien en dispositivos móviles\", \"casa\": \"Mobile\"},\n            \"d\": {\"respuesta\": \"Organizar y visualizar los datos de forma eficiente\", \"casa\": \"Data\"}\n        }\n    },\n    \"pregunta_9\": {\n        \"pregunta\": \"¿Qué tecnología te emociona más aprender?\",\n        \"opciones\": {\n            \"a\": {\"respuesta\": \"Frameworks de JavaScript como React o Angular\", \"casa\": \"Frontend\"},\n            \"b\": {\"respuesta\": \"Microservicios o arquitectura en la nube\", \"casa\": \"Backend\"},\n            \"c\": {\"respuesta\": \"Desarrollo de aplicaciones móviles\", \"casa\": \"Mobile\"},\n            \"d\": {\"respuesta\": \"Big Data o inteligencia artificial\", \"casa\": \"Data\"}\n        }\n    },\n    \"pregunta_10\": {\n        \"pregunta\": \"Si pudieras elegir un área de especialización, ¿cuál sería?\",\n        \"opciones\": {\n            \"a\": {\"respuesta\": \"Interfaz y experiencia de usuario\", \"casa\": \"Frontend\"},\n            \"b\": {\"respuesta\": \"Desarrollo y mantenimiento del servidor\", \"casa\": \"Backend\"},\n            \"c\": {\"respuesta\": \"Aplicaciones móviles\", \"casa\": \"Mobile\"},\n            \"d\": {\"respuesta\": \"Ciencia de datos y análisis\", \"casa\": \"Data\"}\n        }\n    }\n}\n\ndef print_quiz():\n    # Ejemplo para acceder a las preguntas\n    answers = []\n    for clave, contenido in preguntas.items():\n        print(contenido[\"pregunta\"])\n        for opcion, detalle in contenido[\"opciones\"].items():\n            print(f\"{opcion}: {detalle['respuesta']}\")\n        answer = input(\"Selecciona una de las opciones: \")\n        answers.append(answer)\n    return answers\n\ndef select_house(answers):\n    # Contar las respuestas para cada casa\n    countFront = answers.count('a')\n    countBackend = answers.count('b')\n    countMobile = answers.count('c')\n    countData = answers.count('d')\n\n    casas = {\n        \"Frontend\": countFront,\n        \"Backend\": countBackend,\n        \"Mobile\": countMobile,\n        \"Data\": countData\n    }\n\n    max_count = max(casas.values())\n\n    posibles_casas = [casa for casa, count in casas.items() if count == max_count]\n\n    if len(posibles_casas) > 1:\n        print(\"¡Ha sido una decisión complicada!\")\n        return random.choice(posibles_casas)\n    \n    return posibles_casas[0]\n\ndef main():\n    name = input(\"Introduce tu nombre: \")\n    answers = print_quiz()\n    house = select_house(answers)\n    print(f\"{name } la casa seleccionada es: {house}\")\n\nif __name__ == \"__main__\":\n    main()"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/python/rigo93acosta.py",
    "content": "'''\n/*\n * EJERCICIO:\n * Cada 1 de septiembre, el Hogwarts Express parte hacia la escuela\n * de programación de Hogwarts para magos y brujas del código.\n * En ella, su famoso sombrero seleccionador ayuda a los programadores\n * a encontrar su camino...\n * Desarrolla un programa que simule el comportamiento del sombrero.\n * Requisitos:\n * 1. El sombrero realizará 10 preguntas para determinar la casa del alumno.\n * 2. Deben existir 4 casas. Por ejemplo: Frontend, Backend, Mobile y Data.\n *    (Puedes elegir las que quieras)\n * Acciones:\n * 1. Crea un programa que solicite el nombre del alumno y realice 10\n *    preguntas, con cuatro posibles respuestas cada una.\n * 2. Cada respuesta asigna puntos a cada una de las casas (a tu elección).\n * 3. Una vez finalizado, el sombrero indica el nombre del alumno \n *    y a qué casa pertenecerá (resuelve el posible empate de manera aleatoria,\n *    pero indicándole al alumno que la decisión ha sido complicada).\n */\n'''\nimport random\n\nhouses = {\n    \"Frontend\": 0,\n    \"Backend\": 0,\n    \"Mobile\": 0,\n    \"Data\": 0\n}\n\nquestions = [\n    {\n        \"question\": \"¿Qué tipo de proyectos te interesa más desarrollar?\",\n        \"answers\": [\n            {\n                \"option\": \"Aplicaciones móviles nativas para múltiples plataformas.\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"Interfaces visualmente atractivas y responsivas.\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Procesamiento y análisis de grandes volúmenes de datos.\",\n                \"house\": \"Data\"\n            },\n            {\n                \"option\": \"Sistemas robustos y optimización de rendimiento del servidor.\",\n                \"house\": \"Backend\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Qué aspecto del desarrollo disfrutas más?\",\n        \"answers\": [\n            {\n                \"option\": \"Resolver problemas complejos de lógica y escalabilidad.\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"Analizar datos para tomar decisiones basadas en estadísticas.\",\n                \"house\": \"Data\"\n            },\n            {\n                \"option\": \"Crear aplicaciones móviles eficientes y funcionales.\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"Trabajar en el diseño y la experiencia de usuario.\",\n                \"house\": \"Frontend\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Qué herramienta prefieres usar en tu día a día?\",\n        \"answers\": [\n            {\n                \"option\": \"Kotlin o Swift para desarrollar apps móviles nativas.\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"Python o R para análisis de datos.\",\n                \"house\": \"Data\"\n            },\n            {\n                \"option\": \"Frameworks como React o Angular.\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Lenguajes como Node.js o Python para la gestión de servidores.\",\n                \"house\": \"Backend\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Cómo te ves en un equipo de desarrollo?\",\n        \"answers\": [\n            {\n                \"option\": \"Modelando datos y construyendo dashboards de análisis.\",\n                \"house\": \"Data\"\n            },\n            {\n                \"option\": \"Encargado de la lógica del servidor y las APIs.\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"Desarrollando la interfaz y funcionalidad de una app móvil.\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"Diseñando las interacciones y los componentes visuales.\",\n                \"house\": \"Frontend\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Qué te motiva más al trabajar en un proyecto?\",\n        \"answers\": [\n            {\n                \"option\": \"Ver cómo el diseño cobra vida en la pantalla.\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Descubrir insights a partir del análisis de datos.\",\n                \"house\": \"Data\"\n            },\n            {\n                \"option\": \"Optimizar el rendimiento y escalabilidad del sistema.\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"Lograr que una aplicación móvil funcione perfectamente en cualquier dispositivo.\",\n                \"house\": \"Mobile\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Cuál es tu enfoque al aprender nuevas tecnologías?\",\n        \"answers\": [\n            {\n                \"option\": \"Explorar técnicas avanzadas de análisis de datos y machine learning.\",\n                \"house\": \"Data\"\n            },\n            {\n                \"option\": \"Aprender sobre nuevas arquitecturas y lenguajes de servidor.\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"Probar nuevas plataformas y herramientas para desarrollo móvil.\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"Experimentar con nuevas librerías y frameworks de interfaz de usuario.\",\n                \"house\": \"Frontend\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Qué tipo de desafíos disfrutas más resolver?\",\n        \"answers\": [\n            {\n                \"option\": \"Solución de problemas de concurrencia y carga en servidores.\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"Optimización de interfaces para que se vean bien en cualquier dispositivo.\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Análisis de grandes volúmenes de datos para detectar patrones ocultos.\",\n                \"house\": \"Data\"},\n            {\n                \"option\": \"Creación de experiencias de usuario fluídas en dispositivos móviles.\",\n                \"house\": \"Mobile\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Cómo te gusta medir el éxito de tu trabajo?\",\n        \"answers\": [\n            {\n                \"option\": \"Por la estabilidad y rapidez del sistema bajo carga.\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"Mediante la satisfacción del usuario con la interfaz visual.\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Por la fluidez y buen rendimiento de la app móvil en diferentes dispositivos.\",\n                \"house\": \"Mobile\"},\n            {\n                \"option\": \"Por la precisión y relevancia de los resultados obtenidos en el análisis de datos.\",\n                \"house\": \"Data\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Qué te resulta más interesante al trabajar con tecnologías emergentes?\",\n        \"answers\": [\n            {\n                \"option\": \"Trabajar con tecnologías de big data o inteligencia artificial.\",\n                \"house\": \"Data\"\n            },\n            {\n                \"option\": \"Explorar nuevas arquitecturas para mejorar el rendimiento del servidor.\",\n                \"house\": \"Backend\"\n            },\n            {\n                \"option\": \"Probar nuevas herramientas y metodologías para mejorar el diseño y la UX.\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Desarrollar apps móviles que aprovechen nuevas capacidades de hardware.\",\n                \"house\": \"Mobile\"\n            }\n        ]\n    },\n    {\n        \"question\": \"¿Cómo te enfrentas a un nuevo problema en un proyecto?\",\n        \"answers\": [\n            {\n                \"option\": \"Buscando patrones y soluciones basadas en análisis de datos.\",\n                \"house\": \"Data\"\n            },\n            {\n                \"option\": \"Replanteando la estructura visual y funcional de la interfaz.\",\n                \"house\": \"Frontend\"\n            },\n            {\n                \"option\": \"Explorando cómo mejorar la experiencia del usuario en dispositivos móviles.\",\n                \"house\": \"Mobile\"\n            },\n            {\n                \"option\": \"Analizando la estructura de datos y la lógica del backend.\",\n                \"house\": \"Backend\"\n            }\n        ]\n    }\n]\n\nprint(\"¡Bienvenido al Hogwarts para magos y brujas del código!\")\nprint(\"El sombrero seleccionador te ayudará a encontrar tu casa ideal.\")\nname = input(\"¿Cuál es tu nombre? \")\n\nfor index, question in enumerate(questions):\n    print(f\"\\nPregunta {index + 1}: {question['question']}\\n\")\n\n    for i, answer in enumerate(question['answers']):\n        print(f\"{i + 1}. {answer['option']}\")\n\n    choice = int(input(\"\\nElige una opción (1-4): \"))\n    house = question['answers'][choice - 1]['house']\n    houses[house] += 1\n\nprint(f\"\\n¡{name.capitalize()}! El sombrero seleccionador ha tomado una decisión...\")\nassig_house = max(houses, key=houses.get)\nscores = list(houses.values())\n\nif scores.count(max(scores)) > 1:\n    print(f\"Hmmmm.... La decisión ha sido complicada, pero......\")\n    possible_houses = [\n        house for house, points in houses.items() if points == max(scores)\n    ]\n    assig_house = random.choice(possible_houses)\n    print(f\"¡{name.capitalize()} tu casa es... {assig_house}!\")\nelse:\n    print(f\"¡{name.capitalize()} tu casa es... {assig_house}!\")\n\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/python/santyjl.py",
    "content": "# #36 EL SOMBRERO SELECCIONADOR\n#### Dificultad: Fácil | Publicación: 02/09/24 | Corrección: 09/09/24\n\n\n\"\"\"\n/*\n * EJERCICIO:\n * Cada 1 de septiembre, el Hogwarts Express parte hacia la escuela\n * de programación de Hogwarts para magos y brujas del código.\n * En ella, su famoso sombrero seleccionador ayuda a los programadores\n * a encontrar su camino...\n * Desarrolla un programa que simule el comportamiento del sombrero.\n * Requisitos:\n * 1. El sombrero realizará 10 preguntas para determinar la casa del alumno.\n * 2. Deben existir 4 casas. Por ejemplo: Frontend, Backend, Mobile y Data.\n *    (Puedes elegir las que quieras)\n * Acciones:\n * 1. Crea un programa que solicite el nombre del alumno y realice 10\n *    preguntas, con cuatro posibles respuestas cada una.\n * 2. Cada respuesta asigna puntos a cada una de las casas (a tu elección).\n * 3. Una vez finalizado, el sombrero indica el nombre del alumno\n *    y a qué casa pertenecerá (resuelve el posible empate de manera aleatoria,\n *    pero indicándole al alumno que la decisión ha sido complicada).\n */\n\"\"\"\n\n# Variables globales\nfront_end = 0\nback_end = 0\nmobile = 0\ndata = 0\n\n\nPreguntas = [\n    \"¿Qué tipo de trabajo disfrutas más?\",\n    \"¿Qué tipo de herramientas prefieres usar en tu día a día?\",\n    \"¿Qué lenguaje de programación te llama más la atención?\",\n    \"¿Qué prefieres al resolver problemas?\",\n    \"¿Qué consideras más importante en un proyecto?\",\n    \"¿Qué tipo de desafíos te motivan más?\",\n    \"¿Cómo te sientes al trabajar con interfaces visuales?\",\n    \"¿Qué tipo de datos prefieres manejar?\",\n    \"¿Cómo te ves trabajando en equipo?\",\n    \"¿Qué te interesa más del mundo de la tecnología?\"\n]\n\nrespuestas = [\n    [\"Crear interfaces amigables para usuarios (UI/UX)\",\n     \"Diseñar sistemas robustos y funcionales\",\n     \"Crear aplicaciones móviles innovadoras\",\n     \"Trabajar con grandes volúmenes de datos\"],\n\n    [\"Editores de diseño visual\",\n     \"Herramientas de línea de comandos y servidores\",\n     \"Simuladores y entornos móviles\",\n     \"Herramientas de análisis de datos y gráficas\"],\n\n    [\"JavaScript o TypeScript\",\n     \"Python o Java\",\n     \"Swift o Kotlin\",\n     \"SQL o R\"],\n\n    [\"Soluciones que mejoren la experiencia del usuario\",\n     \"Implementar lógica compleja\",\n     \"Optimizar rendimiento en dispositivos móviles\",\n     \"Encontrar patrones en datos\"],\n\n    [\"La facilidad de uso\",\n     \"La estabilidad y escalabilidad\",\n     \"El diseño innovador\",\n     \"La precisión y análisis\"],\n\n    [\"Construir algo visualmente impactante\",\n     \"Resolver problemas técnicos complejos\",\n     \"Hacer que una app funcione en todos los dispositivos\",\n     \"Desentrañar información útil de datos\"],\n\n    [\"Me emociona crear interfaces atractivas\",\n     \"Prefiero trabajar con la lógica detrás de la interfaz\",\n     \"Me gusta la fluidez y simplicidad en móviles\",\n     \"Quiero analizar datos para tomar decisiones\"],\n\n    [\"Estructurados y bien organizados\",\n     \"Cualquier tipo, siempre que el sistema sea funcional\",\n     \"Fáciles de consumir y eficientes\",\n     \"Datos masivos y complejos\"],\n\n    [\"Colaborando activamente y compartiendo ideas\",\n     \"Contribuyendo a construir sistemas sólidos\",\n     \"Asegurando la calidad en diferentes plataformas\",\n     \"Proporcionando insights claros a partir de los datos\"],\n\n    [\"El diseño y la experiencia de usuario\",\n     \"El backend y la infraestructura\",\n     \"La movilidad y accesibilidad\",\n     \"El impacto de los datos en la toma de decisiones\"]\n]\n\ndef dar_puntos(valor: int):\n    \"\"\"Asigna puntos a las casas dependiendo del valor.\"\"\"\n    global front_end, back_end, mobile, data  # Usamos variables globales para modificarlas\n    match valor:\n        case 1:\n            front_end += 1\n        case 2:\n            back_end += 1\n        case 3:\n            mobile += 1\n        case 4:\n            data += 1\n\ndef main():\n    global front_end, back_end, mobile, data  # Aseguramos modificar las globales\n    print(\"Buenas futuro desarrollador, te vamos a hacer unas preguntas para ver en qué casa te quedas:\")\n\n    for i in range(len(Preguntas)):\n        print(f\"\\n{Preguntas[i]}\")  # Pregunta actual\n        for j in range(4):\n            print(f\"{j + 1}. {respuestas[i][j]}\")  # Mostramos opciones empezando en 1\n\n        while True:  # Ciclo para garantizar una entrada válida\n            try:\n                respuesta = int(input(\"Introduce la respuesta de acuerdo al índice (1-4): \"))\n                if 1 <= respuesta <= 4:  # Verificamos que esté en el rango\n                    dar_puntos(respuesta)  # Asignamos puntos\n                    break  # Salimos del ciclo si la entrada es válida\n                else:\n                    print(\"Por favor, introduce un número entre 1 y 4.\")\n            except ValueError:\n                print(\"Entrada inválida. Introduce un número entre 1 y 4.\")\n\n    # Determinamos la casa final\n    print(\"\\nResultados:\")\n    if front_end > back_end and front_end > mobile and front_end > data:\n        print(\"Tú irás a la casa front_end.\")\n    elif back_end > front_end and back_end > mobile and back_end > data:\n        print(\"Tú irás a la casa back_end.\")\n    elif mobile > front_end and mobile > back_end and mobile > data:\n        print(\"Tú irás a la casa mobile.\")\n    elif data > front_end and data > back_end and data > mobile:\n        print(\"Tú irás a la casa data.\")\n    else:\n        print(\"Tu eres diferente, tu tienes que ir a la casa full-stack\")\n\n# Ejecutamos el programa\nmain()\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/rust/kenysdev.rs",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - Rust\n_____________________________________\n36 EL SOMBRERO SELECCIONADOR\n------------------------------------\n* Cada 1 de septiembre, el Hogwarts Express parte hacia la escuela\n* de programación de Hogwarts para magos y brujas del código.\n* En ella, su famoso sombrero seleccionador ayuda a los programadores\n* a encontrar su camino...\n* Desarrolla un programa que simule el comportamiento del sombrero.\n* Requisitos:\n* 1. El sombrero realizará 10 preguntas para determinar la casa del alumno.\n* 2. Deben existir 4 casas. Por ejemplo: Frontend, Backend, Mobile y Data.\n*    (Puedes elegir las que quieras)\n* Acciones:\n* 1. Crea un programa que solicite el nombre del alumno y realice 10\n*    preguntas, con cuatro posibles respuestas cada una.\n* 2. Cada respuesta asigna puntos a cada una de las casas (a tu elección).\n* 3. Una vez finalizado, el sombrero indica el nombre del alumno\n*    y a qué casa pertenecerá (resuelve el posible empate de manera aleatoria,\n*    pero indicándole al alumno que la decisión ha sido complicada).\n*/\n\nuse std::collections::HashMap;\nuse std::io::{self, Write};\n\n// [dependencies]\n// rand = \"0.8.5\"\n// https://crates.io/crates/rand\nuse rand::Rng;\n\nconst HOUSES: [&str; 4] = [\"Frontend\", \"Backend\", \"Mobile\", \"Data\"];\n\n// NOTA: Preguntas y respuestas generadas por IA\nconst QUESTIONS: [&str; 10] = [\n    \"¿Qué te atrae más?\",\n    \"¿Qué superhéroe de la programación te gustaría ser?\",\n    \"En un proyecto de software, ¿qué rol te emociona más?\",\n    \"Si tu código fuera una obra de arte, ¿qué estilo tendría?\",\n    \"¿Qué animal de programación serías?\",\n    \"En una hackathon, ¿qué tipo de proyecto propondrías?\",\n    \"Si tu carrera en tech fuera una película, ¿de qué género sería?\",\n    \"¿Qué herramienta de programación no puede faltar en tu caja de herramientas digital?\",\n    \"Si pudieras resolver un gran problema en tech, ¿cuál elegirías?\",\n    \"¿Qué tipo de equipo prefieres?\",\n];\n\nconst ANSWERS: [[&str; 4]; 10] = [\n    [\"Crear experiencias visuales.\", \"Solucionar problemas de funcionamiento.\", \"Innovar en dispositivos portátiles.\", \"Descubrir tendencias ocultas.\"],\n    [\"Diseñador de Interfaces, creando experiencias asombrosas\", \"Arquitecto de Sistemas, construyendo estructuras robustas\", \"Mago de Apps, conjurando soluciones móviles\", \"Explorador de Datos, descubriendo tesoros ocultos\"],\n    [\"Director de UX, orquestando la sinfonía visual\", \"Ingeniero de Backend, dominando la lógica del servidor\", \"Desarrollador de Apps, llevando la potencia al bolsillo\", \"Científico de Datos, descifrando los secretos de la información\"],\n    [\"Minimalismo elegante, como una landing page perfecta\", \"Arquitectura compleja, como un sistema distribuido\", \"Diseño adaptativo, fluyendo en diferentes dispositivos\", \"Visualización de datos, pintando historias con números\"],\n    [\"Un camaleón, adaptándome a diferentes frameworks\", \"Un pulpo, manejando múltiples servicios a la vez\", \"Un colibrí, ágil y siempre en movimiento\", \"Una lechuza, analizando datos con sabiduría\"],\n    [\"Una web app que revolucione la experiencia del usuario\", \"Un sistema de IA que optimice procesos backend\", \"Una app móvil que cambie la forma de interactuar con el mundo\", \"Un proyecto de big data que prediga tendencias futuras\"],\n    [\"Comedia romántica con JavaScript y CSS\", \"Thriller de ciencia ficción con microservicios\", \"Aventura de acción en el mundo de las apps\", \"Documental profundo sobre el universo de los datos\"],\n    [\"Un editor de código con plugins para diseño visual\", \"Una robusta suite de testing y depuración\", \"Un emulador multi-dispositivo de última generación\", \"Una plataforma de análisis de datos en tiempo real\"],\n    [\"Hacer que la accesibilidad web sea universal\", \"Crear una arquitectura de software autorreparable\", \"Desarrollar una plataforma de AR/VR para educación móvil\", \"Construir un modelo de IA ético y transparente\"],\n    [\"Creativos enfocados en diseño.\", \"Técnicos que construyen sistemas.\", \"Especialistas en aplicaciones móviles.\", \"Expertos en datos y análisis.\"],\n];\n\nstruct SortingHat {\n    scores: HashMap<String, i32>,\n}\n\nimpl SortingHat {\n    fn new() -> Self {\n        let scores = HOUSES.iter().map(|&house| (house.to_string(), 0)).collect();\n        SortingHat { scores }\n    }\n\n    fn ask_question(&mut self, q_num: usize, question: &str, answers: &[&str]) {\n        println!(\"\\n#{}: {}\", q_num, question);\n        for (i, answer) in answers.iter().enumerate() {\n            println!(\"{}) {}\", i + 1, answer);\n        }\n\n        loop {\n            print!(\"Elige tu respuesta (1-4): \");\n            io::stdout().flush().unwrap();\n            \n            let mut choice = String::new();\n            io::stdin().read_line(&mut choice).unwrap();\n            \n            if let Ok(num) = choice.trim().parse::<usize>() {\n                if num >= 1 && num <= 4 {\n                    *self.scores.get_mut(HOUSES[num - 1]).unwrap() += 1;\n                    break;\n                }\n            }\n            println!(\"Por favor, elige un número entre 1 y 4.\");\n        }\n    }\n\n    fn select_house(&self) -> String {\n        let max_score = self.scores.values().max().unwrap();\n        let top_houses: Vec<_> = self.scores\n            .iter()\n            .filter(|(_, &score)| score == *max_score)\n            .map(|(house, _)| house)\n            .collect();\n\n        if top_houses.len() > 1 {\n            println!(\"\\nLa decisión ha sido complicada.\");\n            top_houses[rand::thread_rng().gen_range(0..top_houses.len())].clone()\n        } else {\n            top_houses[0].clone()\n        }\n    }\n}\n\nfn main() {\n    println!(\"EL SOMBRERO SELECCIONADOR\");\n    print!(\"¿Cuál es tu nombre? : \");\n    io::stdout().flush().unwrap();\n    \n    let mut name = String::new();\n    io::stdin().read_line(&mut name).unwrap();\n    let name = name.trim();\n\n    let mut hat = SortingHat::new();\n\n    for (i, (&question, answers)) in QUESTIONS.iter().zip(ANSWERS.iter()).enumerate() {\n        hat.ask_question(i + 1, question, answers);\n    }\n\n    let selected_house = hat.select_house();\n    println!(\"\\n'{}' pertenecerá a la casa '{}'\\n\", name, selected_house);\n}\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/sql/Nicojsuarez2.sql",
    "content": "# #36 EL SOMBRERO SELECCIONADOR\n> #### Dificultad: Fácil | Publicación: 02/09/24 | Corrección: 09/09/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Cada 1 de septiembre, el Hogwarts Express parte hacia la escuela\n * de programación de Hogwarts para magos y brujas del código.\n * En ella, su famoso sombrero seleccionador ayuda a los programadores\n * a encontrar su camino...\n * Desarrolla un programa que simule el comportamiento del sombrero.\n * Requisitos:\n * 1. El sombrero realizará 10 preguntas para determinar la casa del alumno.\n * 2. Deben existir 4 casas. Por ejemplo: Frontend, Backend, Mobile y Data.\n *    (Puedes elegir las que quieras)\n * Acciones:\n * 1. Crea un programa que solicite el nombre del alumno y realice 10\n *    preguntas, con cuatro posibles respuestas cada una.\n * 2. Cada respuesta asigna puntos a cada una de las casas (a tu elección).\n * 3. Una vez finalizado, el sombrero indica el nombre del alumno \n *    y a qué casa pertenecerá (resuelve el posible empate de manera aleatoria,\n *    pero indicándole al alumno que la decisión ha sido complicada).\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/typescript/hozlucas28.ts",
    "content": "import readline from 'node:readline/promises'\n\n/* -------------------------------------------------------------------------- */\n/*                                    TYPES                                   */\n/* -------------------------------------------------------------------------- */\n\ninterface Question<T extends string[]> {\n    correctAnswer: T[number]\n    options: [...T]\n    points: number\n    question: `${string}?`\n}\n\ninterface QuestionsPerHouse {\n    backend: [\n        Question<['Java', 'JavaScript', 'Python', 'Ruby']>,\n        Question<['MySQL', 'MongoDB', 'PostgreSQL', 'SQLite']>\n    ]\n    data: [\n        Question<\n            [\n                'Data analysis',\n                'Data visualization',\n                'Data mining',\n                'Data modeling'\n            ]\n        >,\n        Question<['Python', 'R', 'SQL', 'Julia']>\n    ]\n    frontend: [\n        Question<['HTML', 'CSS', 'JavaScript', 'Python']>,\n        Question<['React', 'Angular', 'Vue', 'Ember']>\n    ]\n    mobile: [\n        Question<['iOS', 'Android', 'React Native', 'Flutter']>,\n        Question<['Swift', 'Kotlin', 'Java', 'Objective-C']>\n    ]\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    UTILS                                   */\n/* -------------------------------------------------------------------------- */\n\nfunction randomChoice<T>(...choices: T[]): T {\n    const rndChoice: T = choices[Math.floor(Math.random() * choices.length)]\n    return rndChoice\n}\n\nasync function makeQuestion<T extends string[]>(\n    question: Question<T>\n): Promise<number> {\n    const rl: readline.Interface = readline.createInterface({\n        input: process.stdin,\n        output: process.stdout,\n    })\n\n    const formatter: Intl.ListFormat = new Intl.ListFormat('en', {\n        style: 'long',\n        type: 'disjunction',\n    })\n\n    const optionsFormatted: string = formatter.format(question.options)\n\n    const optionsNormalized: string[] = question.options.map((opt) =>\n        opt.toUpperCase()\n    )\n\n    let userAnswer: string = (\n        await rl.question(`> ${question.question} (${optionsFormatted}): `)\n    )\n        .trim()\n        .toUpperCase()\n\n    while (!optionsNormalized.includes(userAnswer)) {\n        console.log('\\n> Invalid option! Try again...')\n\n        userAnswer = (\n            await rl.question(\n                `\\n> ${question.question} (${optionsFormatted}): `\n            )\n        )\n            .trim()\n            .toUpperCase()\n    }\n    rl.close()\n\n    return userAnswer === question.correctAnswer ? question.points : 0\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\nconst questionsPerHouse: QuestionsPerHouse = {\n    backend: [\n        {\n            correctAnswer: 'JavaScript',\n            options: ['Java', 'JavaScript', 'Python', 'Ruby'],\n            question:\n                'What is the primary language used in backend development?',\n            points: 5,\n        },\n        {\n            correctAnswer: 'PostgreSQL',\n            options: ['MySQL', 'MongoDB', 'PostgreSQL', 'SQLite'],\n            points: 5,\n            question:\n                'Which database is commonly used for storing data in backend applications?',\n        },\n    ],\n    data: [\n        {\n            correctAnswer: 'Data analysis',\n            options: [\n                'Data analysis',\n                'Data visualization',\n                'Data mining',\n                'Data modeling',\n            ],\n            points: 5,\n            question:\n                'What is the process of analyzing and interpreting data called?',\n        },\n        {\n            correctAnswer: 'Julia',\n            options: ['Python', 'R', 'SQL', 'Julia'],\n            points: 5,\n            question:\n                'Which programming language is commonly used for data analysis?',\n        },\n    ],\n    frontend: [\n        {\n            correctAnswer: 'JavaScript',\n            options: ['HTML', 'CSS', 'JavaScript', 'Python'],\n            points: 5,\n            question:\n                'What is the primary language used in frontend development?',\n        },\n        {\n            correctAnswer: 'Angular',\n            options: ['React', 'Angular', 'Vue', 'Ember'],\n            points: 5,\n            question:\n                'Which framework is commonly used for building user interfaces?',\n        },\n    ],\n    mobile: [\n        {\n            correctAnswer: 'Flutter',\n            options: ['iOS', 'Android', 'React Native', 'Flutter'],\n            points: 5,\n            question:\n                'Which platform is commonly used for developing mobile applications?',\n        },\n        {\n            correctAnswer: 'Objective-C',\n            options: ['Swift', 'Kotlin', 'Java', 'Objective-C'],\n            points: 5,\n            question:\n                'What is the primary language used in mobile app development?',\n        },\n    ],\n}\n\n;(async () => {\n    const rl: readline.Interface = readline.createInterface({\n        input: process.stdin,\n        output: process.stdout,\n    })\n\n    const userName: string = (await rl.question('> Enter your name: ')).trim()\n    rl.close()\n\n    const points: [keyof QuestionsPerHouse, number][] = [\n        ['backend', 0],\n        ['data', 0],\n        ['frontend', 0],\n        ['mobile', 0],\n    ]\n\n    console.log()\n    points[0][1] += await makeQuestion(questionsPerHouse.backend[0])\n\n    console.log()\n    points[0][1] += await makeQuestion(questionsPerHouse.backend[1])\n\n    console.log()\n    points[1][1] += await makeQuestion(questionsPerHouse.data[0])\n\n    console.log()\n    points[1][1] += await makeQuestion(questionsPerHouse.data[1])\n\n    console.log()\n    points[2][1] += await makeQuestion(questionsPerHouse.frontend[0])\n\n    console.log()\n    points[2][1] += await makeQuestion(questionsPerHouse.frontend[1])\n\n    console.log()\n    points[3][1] += await makeQuestion(questionsPerHouse.mobile[0])\n\n    console.log()\n    points[3][1] += await makeQuestion(questionsPerHouse.mobile[1])\n\n    const maxPoints: [keyof QuestionsPerHouse, number][] = []\n\n    for (const [house, housePoints] of points) {\n        if (maxPoints.length === 0) {\n            maxPoints.push([house, housePoints])\n            continue\n        }\n\n        if (maxPoints[0][1] > housePoints) continue\n\n        if (maxPoints[0][1] === housePoints)\n            maxPoints.push([house, housePoints])\n        else maxPoints[0] = [house, housePoints]\n    }\n\n    if (maxPoints.length === 1) {\n        console.log(\n            `\\n> ${userName} will be part of the ${maxPoints[0][0]} house!`\n        )\n        return\n    }\n\n    const rndChoice: [keyof QuestionsPerHouse, number] = randomChoice(\n        ...maxPoints\n    )\n\n    console.log(\n        `\\n> The decision has been complicated,` +\n            ` but ${userName} will be part of the ${rndChoice[0]} house!`\n    )\n})()\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/typescript/miguelex.ts",
    "content": "import * as readline from 'readline';\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nclass Casa {\n    private nombre: string;\n    private puntos: number;\n\n    constructor(nombre: string) {\n        this.nombre = nombre;\n        this.puntos = 0;\n    }\n\n    public getNombre(): string {\n        return this.nombre;\n    }\n\n    public agregarPuntos(puntos: number): void {\n        this.puntos += puntos;\n    }\n\n    public getPuntos(): number {\n        return this.puntos;\n    }\n}\n\nclass Alumno {\n    private nombre: string;\n\n    constructor(nombre: string) {\n        this.nombre = nombre;\n    }\n\n    public getNombre(): string {\n        return this.nombre;\n    }\n}\n\ninterface Opcion {\n    texto: string;\n    casa: string;\n}\n\nclass Pregunta {\n    private pregunta: string;\n    private opciones: Opcion[];\n\n    constructor(pregunta: string, opciones: Opcion[]) {\n        this.pregunta = pregunta;\n        this.opciones = opciones;\n    }\n\n    public mostrarPregunta(): void {\n        console.log(this.pregunta);\n        this.opciones.forEach((opcion, index) => {\n            console.log(`${index + 1}: ${opcion.texto}`);\n        });\n    }\n\n    public obtenerCasaSegunRespuesta(respuesta: number): string {\n        return this.opciones[respuesta - 1].casa;\n    }\n}\n\nclass SombreroSeleccionador {\n    private casas: Record<string, Casa>;\n    private preguntas: Pregunta[];\n\n    constructor(casas: Record<string, Casa>, preguntas: Pregunta[]) {\n        this.casas = casas;\n        this.preguntas = preguntas;\n    }\n\n    public async asignarCasa(alumno: Alumno): Promise<void> {\n        const preguntasSeleccionadas = this.seleccionarPreguntas();\n        for (const pregunta of preguntasSeleccionadas) {\n            pregunta.mostrarPregunta();\n            const respuesta = await this.leerRespuesta();\n            const casa = pregunta.obtenerCasaSegunRespuesta(respuesta);\n            this.casas[casa].agregarPuntos(1);\n        }\n\n        this.mostrarResultado(alumno);\n        rl.close();\n    }\n\n    private seleccionarPreguntas(): Pregunta[] {\n        const preguntasSeleccionadas: Pregunta[] = [];\n        const indicesSeleccionados = new Set<number>();\n\n        while (preguntasSeleccionadas.length < 10) {\n            const indice = Math.floor(Math.random() * this.preguntas.length);\n            if (!indicesSeleccionados.has(indice)) {\n                indicesSeleccionados.add(indice);\n                preguntasSeleccionadas.push(this.preguntas[indice]);\n            }\n        }\n\n        return preguntasSeleccionadas;\n    }\n\n    private leerRespuesta(): Promise<number> {\n        return new Promise((resolve) => {\n            rl.question(\"Selecciona una opción (1-4): \", (respuesta) => {\n                resolve(parseInt(respuesta));\n            });\n        });\n    }\n\n    private mostrarResultado(alumno: Alumno): void {\n        const casasOrdenadas = Object.values(this.casas).sort((a, b) => b.getPuntos() - a.getPuntos());\n\n        const maxPuntos = casasOrdenadas[0].getPuntos();\n        const ganadoras = casasOrdenadas.filter(casa => casa.getPuntos() === maxPuntos);\n\n        let ganadora: Casa;\n        if (ganadoras.length > 1) {\n            console.log(\"\\n\\nLa decisión fue difícil...\");\n            ganadora = ganadoras[Math.floor(Math.random() * ganadoras.length)];\n        } else {\n            ganadora = ganadoras[0];\n        }\n\n        console.log(`\\n\\n ${alumno.getNombre()}, el sombrero seleccionador te ha asignado a la casa ${ganadora.getNombre().toUpperCase()}!!!!\\n`);\n    }\n}\n\nconst casas: Record<string, Casa> = {\n    'frontend': new Casa('Frontend'),\n    'backend': new Casa('Backend'),\n    'mobile': new Casa('Mobile'),\n    'data': new Casa('Data')\n};\n\nconst preguntas = [\n    new Pregunta(\"¿Qué prefieres?\", [\n        { texto: 'Diseñar interfaces', casa: 'frontend' },\n        { texto: 'Crear APIs', casa: 'backend' },\n        { texto: 'Desarrollar apps móviles', casa: 'mobile' },\n        { texto: 'Analizar datos', casa: 'data' }\n    ]),\n    new Pregunta(\"¿Cuál es tu lenguaje de programación favorito?\", [\n        { texto: 'JavaScript', casa: 'frontend' },\n        { texto: 'Python', casa: 'backend' },\n        { texto: 'Kotlin', casa: 'mobile' },\n        { texto: 'R', casa: 'data' }\n    ]),\n    new Pregunta(\"¿Qué herramienta utilizas más a menudo?\", [\n        { texto: 'Figma o Sketch', casa: 'frontend' },\n        { texto: 'Docker o Kubernetes', casa: 'backend' },\n        { texto: 'Android Studio o Xcode', casa: 'mobile' },\n        { texto: 'Jupyter Notebooks o Excel', casa: 'data' }\n    ]),\n    new Pregunta(\"¿Qué te interesa más aprender?\", [\n        { texto: 'HTML/CSS y JavaScript avanzado', casa: 'frontend' },\n        { texto: 'Patrones de diseño y arquitectura de software', casa: 'backend' },\n        { texto: 'Programación nativa para dispositivos móviles', casa: 'mobile' },\n        { texto: 'Estadística y Machine Learning', casa: 'data' }\n    ]),\n    new Pregunta(\"¿Qué tipo de proyecto te gustaría liderar?\", [\n        { texto: 'Un sitio web interactivo y atractivo', casa: 'frontend' },\n        { texto: 'Una plataforma escalable con microservicios', casa: 'backend' },\n        { texto: 'Una app móvil innovadora', casa: 'mobile' },\n        { texto: 'Un sistema de recomendación basado en datos', casa: 'data' }\n    ]),\n    new Pregunta(\"¿Qué es lo más importante para ti en un proyecto?\", [\n        { texto: 'La experiencia de usuario', casa: 'frontend' },\n        { texto: 'El rendimiento y la escalabilidad', casa: 'backend' },\n        { texto: 'La adaptabilidad a diferentes dispositivos', casa: 'mobile' },\n        { texto: 'La precisión de los análisis', casa: 'data' }\n    ]),\n    new Pregunta(\"¿Qué prefieres trabajar?\", [\n        {texto : 'En un entorno donde el diseño visual es clave', casa :'frontend'},\n        {texto : 'En la lógica del negocio y la arquitectura', casa :'backend'},\n        {texto : 'En apps móviles con buen rendimiento', casa :'mobile'},\n        {texto : 'En el análisis y visualización de datos', casa :'data'}\n    ]),\n    new Pregunta(\"¿Qué framework te parece más interesante?\", [\n        {texto: 'React o Angular', casa :'frontend'},\n        {texto : 'Spring o Django', casa :'backend'},\n        {texto : 'Flutter o React Native', casa :'mobile'},\n        {texto : 'TensorFlow o Pandas', casa :'data'}\n    ]),\n    new Pregunta(\"¿Qué tipo de reto disfrutas más?\", [\n        {texto : 'Hacer que un sitio web sea accesible y rápido', casa :'frontend'},\n        {texto : 'Optimizar la comunicación entre servicios', casa :'backend'},\n        {texto : 'Mejorar la experiencia del usuario en móviles', casa :'mobile'},\n        {texto : 'Encontrar patrones ocultos en los datos', casa :'data'}\n    ]),\n    new Pregunta(\"¿Qué prefieres resolver?\", [\n        {texto : 'Problemas de diseño y maquetación', casa :'frontend'},\n        {texto : 'Problemas de concurrencia y escalabilidad', casa :'backend'},\n        {texto : 'Problemas de rendimiento en aplicaciones móviles', casa :'mobile'},\n        {texto : 'Problemas de predicción y análisis de datos', casa :'data'}\n    ]),\n    new Pregunta(\"¿Qué es lo que más te emociona en tecnología?\", [\n        {texto : 'La evolución de las interfaces de usuario', casa :'frontend'},\n        {texto : 'La innovación en la arquitectura de software', casa :'backend'},\n        {texto : 'Las nuevas capacidades de los dispositivos móviles', casa :'mobile'},\n        {texto : 'Los avances en inteligencia artificial y análisis de datos', casa : 'data'}\n    ]),\n    new Pregunta(\"¿Qué te gusta hacer en tu tiempo libre?\", [\n        {texto : 'Diseñar sitios web personales o interfaces', casa: 'frontend'},\n        {texto : 'Hacer proyectos con servidores y APIs', casa: 'backend'},\n        {texto : 'Crear apps móviles para resolver problemas cotidianos', casa: 'mobile'},\n        {texto : 'Hacer análisis de datos para tomar decisiones mejor informadas', casa: 'data'}\n    ]),\n    new Pregunta(\"¿Qué te gustaría dominar?\", [\n        {texto : 'Animaciones y transiciones en la web', casa: 'frontend'},\n        {texto : 'Arquitectura de microservicios', casa: 'backend'},\n        {texto : 'Optimización de aplicaciones móviles', casa: 'mobile'},\n        {texto : 'Modelos predictivos y análisis de datos', casa: 'data'}\n    ]),\n    new Pregunta(\"¿Qué tipo de problema prefieres resolver en un hackathon?\", [\n        {texto : 'Mejorar la interfaz de usuario de una aplicación', casa: 'frontend'},\n        {texto : 'Optimizar el rendimiento de una API', casa: 'backend'},\n        {texto : 'Crear una aplicación móvil desde cero', casa: 'mobile'},\n        {texto : 'Generar insights a partir de grandes conjuntos de datos', casa: 'data'}\n    ]),\n    new Pregunta(\"¿Qué prefieres al trabajar en equipo?\", [\n        {texto : 'Encargarte de la parte visual y de interacción del usuario', casa: 'frontend'},\n        {texto : 'Asegurarte de que la lógica y los datos fluyan correctamente', casa: 'backend'},\n        {texto : 'Hacer que la app funcione bien en diferentes dispositivos', casa: 'mobile'},\n        {texto : 'Proveer métricas y análisis para tomar mejores decisiones', casa: 'data'}\n    ]),\n    new Pregunta(\"¿Cuál es tu prioridad al optimizar código?\", [\n        {texto : 'Que la interfaz cargue rápido y sea amigable', casa: 'frontend'},\n        {texto : 'Que los servicios backend sean escalables y eficientes', casa: 'backend'},\n        {texto : 'Que la app móvil consuma pocos recursos y sea fluida', casa: 'mobile'},\n        {texto : 'Que el procesamiento de datos sea rápido y preciso', casa: 'data'}\n    ]),\n    new Pregunta(\"¿Qué prefieres al probar una aplicación?\", [\n        {texto : 'Verificar que el diseño y la usabilidad sean impecables', casa: 'frontend'},\n        {texto : 'Asegurar que las funcionalidades y la lógica sean correctas', casa :'backend'},\n        {texto : 'Revisar que la app funcione correctamente en múltiples dispositivos', casa : 'mobile'},\n        {texto : 'Validar que los resultados de los análisis sean exactos', casa : 'data'}\n    ]),\n    new Pregunta(\"¿Qué tipo de proyectos sigues en la industria?\", [\n        {texto : 'Proyectos de diseño web innovador y UX', casa : 'frontend'},\n        {texto : 'Nuevas tecnologías de servidores y backends', casa : 'backend'},\n        {texto : 'Aplicaciones móviles disruptivas y eficientes', casa : 'mobile'},\n        {texto : 'Proyectos de inteligencia artificial y ciencia de datos', casa : 'data'}\n    ]),\n    new Pregunta(\"¿Qué harías para mejorar una plataforma existente?\", [\n        {texto : 'Mejorar la apariencia y usabilidad de la interfaz', casa : 'frontend'},\n        {texto : 'Optimizar el rendimiento de las consultas y los servidores', casa : 'backend'},\n        {texto : 'Hacer que la plataforma sea accesible desde dispositivos móviles', casa : 'mobile'},\n        {texto : 'Incluir más análisis de datos para obtener mejor información', casa : 'data'}\n    ]),\n    new Pregunta(\"¿Qué aspecto del desarrollo de software te parece más retador?\", [\n        {texto : 'Hacer que una aplicación web sea visualmente atractiva', casa : 'frontend'},\n        {texto : 'Crear sistemas backend que manejen millones de usuarios', casa : 'backend'},\n        {texto : 'Optimizar la app móvil para diferentes sistemas operativos', casa : 'mobile'},\n        {texto : 'Gestionar grandes volúmenes de datos y extraer conclusiones útiles', casa : 'data'}\n    ]),\n];\n\n\nrl.question(\"Por favor, introduce tu nombre: \", (nombreAlumno) => {\n    const alumno = new Alumno(nombreAlumno);\n    const sombrero = new SombreroSeleccionador(casas, preguntas);\n    sombrero.asignarCasa(alumno);\n});\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/typescript/redom69.ts",
    "content": "import * as readline from 'readline';\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\ninterface Opcion {\n    respuesta: string;\n    casa: string;\n}\n\ninterface Pregunta {\n    pregunta: string;\n    opciones: Opcion[];\n}\n\nconst preguntas: Pregunta[] = [\n    {\n        pregunta: \"¿Qué es lo que más disfrutas al programar?\",\n        opciones: [\n            { respuesta: \"Diseñar interfaces atractivas\", casa: \"Frontend\" },\n            { respuesta: \"Optimizar el rendimiento del servidor\", casa: \"Backend\" },\n            { respuesta: \"Crear aplicaciones móviles útiles\", casa: \"Mobile\" },\n            { respuesta: \"Analizar grandes conjuntos de datos\", casa: \"Data\" }\n        ]\n    },\n    {\n        pregunta: \"¿Qué tipo de proyecto te atrae más?\",\n        opciones: [\n            { respuesta: \"Aplicaciones web con mucho estilo\", casa: \"Frontend\" },\n            { respuesta: \"Sistemas que manejen grandes volúmenes de datos\", casa: \"Backend\" },\n            { respuesta: \"Aplicaciones para teléfonos inteligentes\", casa: \"Mobile\" },\n            { respuesta: \"Dashboards para visualizar información\", casa: \"Data\" }\n        ]\n    },\n    {\n        pregunta: \"¿Qué herramienta te resulta más interesante?\",\n        opciones: [\n            { respuesta: \"HTML, CSS y JavaScript\", casa: \"Frontend\" },\n            { respuesta: \"Node.js o Python\", casa: \"Backend\" },\n            { respuesta: \"React Native o Swift\", casa: \"Mobile\" },\n            { respuesta: \"SQL o Python con Pandas\", casa: \"Data\" }\n        ]\n    },\n    {\n        pregunta: \"¿Cuál es tu mayor fortaleza como programador?\",\n        opciones: [\n            { respuesta: \"Crear interfaces amigables\", casa: \"Frontend\" },\n            { respuesta: \"Solucionar problemas complejos en el servidor\", casa: \"Backend\" },\n            { respuesta: \"Desarrollar apps funcionales\", casa: \"Mobile\" },\n            { respuesta: \"Encontrar patrones en los datos\", casa: \"Data\" }\n        ]\n    },\n    {\n        pregunta: \"¿Qué prefieres en un equipo de desarrollo?\",\n        opciones: [\n            { respuesta: \"Ser quien diseña el look y feel\", casa: \"Frontend\" },\n            { respuesta: \"Ser quien gestiona la arquitectura de la aplicación\", casa: \"Backend\" },\n            { respuesta: \"Ser quien se encarga de la versión móvil\", casa: \"Mobile\" },\n            { respuesta: \"Ser quien analiza el rendimiento del sistema\", casa: \"Data\" }\n        ]\n    },\n    {\n        pregunta: \"¿En qué te enfocas más cuando trabajas en un proyecto?\",\n        opciones: [\n            { respuesta: \"En el diseño visual y la experiencia de usuario\", casa: \"Frontend\" },\n            { respuesta: \"En la estabilidad y escalabilidad del sistema\", casa: \"Backend\" },\n            { respuesta: \"En hacer que la app funcione en dispositivos móviles\", casa: \"Mobile\" },\n            { respuesta: \"En el análisis y visualización de los datos\", casa: \"Data\" }\n        ]\n    },\n    {\n        pregunta: \"¿Cuál es tu mayor motivación como desarrollador?\",\n        opciones: [\n            { respuesta: \"Crear experiencias de usuario memorables\", casa: \"Frontend\" },\n            { respuesta: \"Resolver problemas complejos con eficiencia\", casa: \"Backend\" },\n            { respuesta: \"Desarrollar aplicaciones que la gente use todos los días\", casa: \"Mobile\" },\n            { respuesta: \"Descubrir patrones ocultos en los datos\", casa: \"Data\" }\n        ]\n    },\n    {\n        pregunta: \"¿Qué aspecto prefieres de un nuevo proyecto?\",\n        opciones: [\n            { respuesta: \"Hacer que se vea genial y sea fácil de usar\", casa: \"Frontend\" },\n            { respuesta: \"Asegurarme de que el servidor funcione sin problemas\", casa: \"Backend\" },\n            { respuesta: \"Hacer que funcione bien en dispositivos móviles\", casa: \"Mobile\" },\n            { respuesta: \"Organizar y visualizar los datos de forma eficiente\", casa: \"Data\" }\n        ]\n    },\n    {\n        pregunta: \"¿Qué tecnología te emociona más aprender?\",\n        opciones: [\n            { respuesta: \"Frameworks de JavaScript como React o Angular\", casa: \"Frontend\" },\n            { respuesta: \"Microservicios o arquitectura en la nube\", casa: \"Backend\" },\n            { respuesta: \"Desarrollo de aplicaciones móviles\", casa: \"Mobile\" },\n            { respuesta: \"Big Data o inteligencia artificial\", casa: \"Data\" }\n        ]\n    },\n    {\n        pregunta: \"Si pudieras elegir un área de especialización, ¿cuál sería?\",\n        opciones: [\n            { respuesta: \"Interfaz y experiencia de usuario\", casa: \"Frontend\" },\n            { respuesta: \"Desarrollo y mantenimiento del servidor\", casa: \"Backend\" },\n            { respuesta: \"Aplicaciones móviles\", casa: \"Mobile\" },\n            { respuesta: \"Ciencia de datos y análisis\", casa: \"Data\" }\n        ]\n    }\n];\n\nfunction printQuiz() {\n    const answers: string[] = [];\n\n    const askQuestion = (index: number): void => {\n        if (index < preguntas.length) {\n            console.log(preguntas[index].pregunta);\n            preguntas[index].opciones.forEach((opcion, idx) => {\n                console.log(`${String.fromCharCode(97 + idx)}: ${opcion.respuesta}`);\n            });\n            rl.question('Selecciona una opción: ', (answer) => {\n                answers.push(answer);\n                askQuestion(index + 1);\n            });\n        } else {\n            rl.close();\n            const house = selectHouse(answers);\n            console.log(`La casa seleccionada es: ${house}`);\n        }\n    };\n\n    askQuestion(0);\n}\n\nfunction selectHouse(answers: string[]): string {\n    const countFront = answers.filter((a) => a === 'a').length;\n    const countBackend = answers.filter((a) => a === 'b').length;\n    const countMobile = answers.filter((a) => a === 'c').length;\n    const countData = answers.filter((a) => a === 'd').length;\n\n    const casas: { [key: string]: number } = { Frontend: countFront, Backend: countBackend, Mobile: countMobile, Data: countData };\n    const maxCount = Math.max(...Object.values(casas));\n\n    const posiblesCasas = Object.keys(casas).filter(casa => casas[casa] === maxCount);\n\n    if (posiblesCasas.length > 1) {\n        console.log(\"¡Ha sido una decisión complicada!\");\n        return posiblesCasas[Math.floor(Math.random() * posiblesCasas.length)];\n    }\n\n    return posiblesCasas[0];\n}\n\nfunction main() {\n    rl.question('Introduce tu nombre: ', (name) => {\n        printQuiz();\n    });\n}\n\nmain();\n"
  },
  {
    "path": "Roadmap/36 - EL SOMBRERO SELECCIONADOR/vb.net/kenysdev.vb",
    "content": "' _____________________________________\n' https://github.com/kenysdev\n' 2024 - vb.net\n' _____________________________________\n' 36 EL SOMBRERO SELECCIONADOR\n' ------------------------------------\n' * Cada 1 de septiembre, el Hogwarts Express parte hacia la escuela\n' * de programación de Hogwarts para magos y brujas del código.\n' * En ella, su famoso sombrero seleccionador ayuda a los programadores\n' * a encontrar su camino...\n' * Desarrolla un programa que simule el comportamiento del sombrero.\n' * Requisitos:\n' * 1. El sombrero realizará 10 preguntas para determinar la casa del alumno.\n' * 2. Deben existir 4 casas. Por ejemplo: Frontend, Backend, Mobile y Data.\n' *    (Puedes elegir las que quieras)\n' * Acciones:\n' * 1. Crea un programa que solicite el nombre del alumno y realice 10\n' *    preguntas, con cuatro posibles respuestas cada una.\n' * 2. Cada respuesta asigna puntos a cada una de las casas (a tu elección).\n' * 3. Una vez finalizado, el sombrero indica el nombre del alumno\n' *    y a qué casa pertenecerá (resuelve el posible empate de manera aleatoria,\n' *    pero indicándole al alumno que la decisión ha sido complicada).\n\n\nModule Program\n    Private ReadOnly HOUSES As String() = {\"Frontend\", \"Backend\", \"Mobile\", \"Data\"}\n\n    ' NOTA: Preguntas y respuestas generadas por IA\n    Private ReadOnly QUESTIONS As String() = {\n        \"¿Qué te atrae más?\",\n        \"¿Qué superhéroe de la programación te gustaría ser?\",\n        \"En un proyecto de software, ¿qué rol te emociona más?\",\n        \"Si tu código fuera una obra de arte, ¿qué estilo tendría?\",\n        \"¿Qué animal de programación serías?\",\n        \"En una hackathon, ¿qué tipo de proyecto propondrías?\",\n        \"Si tu carrera en tech fuera una película, ¿de qué género sería?\",\n        \"¿Qué herramienta de programación no puede faltar en tu caja de herramientas digital?\",\n        \"Si pudieras resolver un gran problema en tech, ¿cuál elegirías?\",\n        \"¿Qué tipo de equipo prefieres?\"\n    }\n\n    Private ReadOnly ANSWERS As String()() = {\n        New String() {\"Crear experiencias visuales.\", \"Solucionar problemas de funcionamiento.\", \"Innovar en dispositivos portátiles.\", \"Descubrir tendencias ocultas.\"},\n        New String() {\"Diseñador de Interfaces, creando experiencias asombrosas\", \"Arquitecto de Sistemas, construyendo estructuras robustas\", \"Mago de Apps, conjurando soluciones móviles\", \"Explorador de Datos, descubriendo tesoros ocultos\"},\n        New String() {\"Director de UX, orquestando la sinfonía visual\", \"Ingeniero de Backend, dominando la lógica del servidor\", \"Desarrollador de Apps, llevando la potencia al bolsillo\", \"Científico de Datos, descifrando los secretos de la información\"},\n        New String() {\"Minimalismo elegante, como una landing page perfecta\", \"Arquitectura compleja, como un sistema distribuido\", \"Diseño adaptativo, fluyendo en diferentes dispositivos\", \"Visualización de datos, pintando historias con números\"},\n        New String() {\"Un camaleón, adaptándome a diferentes frameworks\", \"Un pulpo, manejando múltiples servicios a la vez\", \"Un colibrí, ágil y siempre en movimiento\", \"Una lechuza, analizando datos con sabiduría\"},\n        New String() {\"Una web app que revolucione la experiencia del usuario\", \"Un sistema de IA que optimice procesos backend\", \"Una app móvil que cambie la forma de interactuar con el mundo\", \"Un proyecto de big data que prediga tendencias futuras\"},\n        New String() {\"Comedia romántica con JavaScript y CSS\", \"Thriller de ciencia ficción con microservicios\", \"Aventura de acción en el mundo de las apps\", \"Documental profundo sobre el universo de los datos\"},\n        New String() {\"Un editor de código con plugins para diseño visual\", \"Una robusta suite de testing y depuración\", \"Un emulador multi-dispositivo de última generación\", \"Una plataforma de análisis de datos en tiempo real\"},\n        New String() {\"Hacer que la accesibilidad web sea universal\", \"Crear una arquitectura de software autorreparable\", \"Desarrollar una plataforma de AR/VR para educación móvil\", \"Construir un modelo de IA ético y transparente\"},\n        New String() {\"Creativos enfocados en diseño.\", \"Técnicos que construyen sistemas.\", \"Especialistas en aplicaciones móviles.\", \"Expertos en datos y análisis.\"}\n    }\n\n    Private Class SortingHat\n        Private ReadOnly scores As Dictionary(Of String, Integer)\n\n        Public Sub New()\n            scores = HOUSES.ToDictionary(Function(house) house, Function(house) 0)\n        End Sub\n\n        Public Sub AskQuestion(qNum As Integer, question As String, answers As String())\n            Console.WriteLine($\"{vbCrLf}#{qNum}: {question}\")\n            For i As Integer = 0 To answers.Length - 1\n                Console.WriteLine($\"{i + 1}) {answers(i)}\")\n            Next\n\n            While True\n                Console.Write(\"Elige tu respuesta (1-4): \")\n                Dim choice As Integer\n                If Integer.TryParse(Console.ReadLine(), choice) AndAlso choice >= 1 AndAlso choice <= 4 Then\n                    scores(HOUSES(choice - 1)) += 1\n                    Exit While\n                Else\n                    Console.WriteLine(\"Por favor, elige un número entre 1 y 4.\")\n                End If\n            End While\n        End Sub\n\n        Public Function SelectHouse() As String\n            Dim maxScore = scores.Values.Max()\n            Dim topHouses = scores.Where(Function(kv) kv.Value = maxScore).Select(Function(kv) kv.Key).ToList()\n\n            If topHouses.Count > 1 Then\n                Console.WriteLine(vbCrLf & \"La decisión ha sido complicada.\")\n                Return topHouses(New Random().Next(topHouses.Count))\n            End If\n            Return topHouses(0)\n        End Function\n    End Class\n\n    Sub Main()\n        Console.WriteLine(\"EL SOMBRERO SELECCIONADOR\")\n        Console.Write(\"¿Cuál es tu nombre? : \")\n        Dim name As String = If(Console.ReadLine(), String.Empty)\n        Dim hat As New SortingHat()\n\n        For i As Integer = 0 To QUESTIONS.Length - 1\n            hat.AskQuestion(i + 1, QUESTIONS(i), ANSWERS(i))\n        Next\n\n        Dim selectedHouse As String = hat.SelectHouse()\n        Console.WriteLine($\"{vbCrLf}'{name}' pertenecerá a la casa '{selectedHouse}'{vbCrLf}\")\n    End Sub\nEnd Module\n"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/c#/NachitoE.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Metrics;\nusing System.Security.Cryptography;\nusing System.Text;\nusing System.Text.Json;\nusing System.Text.Json.Nodes;\nusing System.Text.Json.Serialization;\n\n/*\n * EJERCICIO:\n * ¡Dos de las bandas más grandes de la historia están de vuelta!\n * Oasis y Linkin Park han anunciado nueva gira, pero, ¿quién es más popular?\n * Desarrolla un programa que se conecte al API de Spotify y los compare.\n * Requisitos:\n * 1. Crea una cuenta de desarrollo en https://developer.spotify.com.\n * 2. Conéctate al API utilizando tu lenguaje de programación.\n * 3. Recupera datos de los endpoint que tú quieras.\n * Acciones:\n * 1. Accede a las estadísticas de las dos bandas.\n *    Por ejemplo: número total de seguidores, escuchas mensuales,\n *    canción con más reproducciones...\n * 2. Compara los resultados de, por lo menos, 3 endpoint.\n * 3. Muestra todos los resultados por consola para notificar al usuario.\n * 4. Desarrolla un criterio para seleccionar qué banda es más popular.\n */\n\npublic class Program\n{\n    static async Task Main()\n    {\n        string clientId = Environment.GetEnvironmentVariable(\"SPOTIFY_CLIENT_ID\");\n        string clientSecret = Environment.GetEnvironmentVariable(\"SPOTIFY_CLIENT_SECRET\");\n        SpotifyAPI api = new SpotifyAPI(clientId, clientSecret);\n        List<String> bandsIDs = new List<string>();\n        List<String> defaultbandIDs = [\"2DaxqgrOhkeH0fpeiQq2f4\", \"6XyY86QOPPrYVGvF9ch6wz\"];\n        string token = await api.GetAuthToken();\n        if (token == \"\")\n        {\n            Console.WriteLine(\"Invalid Token. Check if ClientID and ClientSecret are correctly written.\");\n            return;\n        }\n\n        Console.WriteLine(\"Write your desired band ID and press Enter.\\nIf you don't want to add any more bands, just press Enter.\\nNOTE : By default this program will compare Linkin Park against Oasis.\");\n        Console.Write(\"Write your band ID (or just Enter if you want to go with Linking Park and Oasis): \");\n        string newBandId = Console.ReadLine();\n        while (newBandId != \"\" || bandsIDs.Count < 2)\n        {\n            newBandId = newBandId.Trim();\n            if (newBandId == \"\" && bandsIDs.Count == 0) //Going with Linkin Park and Oasis\n            {\n                bandsIDs = defaultbandIDs;\n                break;\n            }\n            else if (newBandId == \"\" && bandsIDs.Count > 1) break; //User has written more than 1 band\n            else if (newBandId == \"\" && bandsIDs.Count == 1) Console.WriteLine(\"Please enter at least one more band before proceeding\");\n\n            if (bandsIDs.Contains(newBandId))\n            {\n                Console.WriteLine(\"You've already added that band. Please add another one.\");\n            }\n            else\n            {\n                string? json = await api.GetArtistInfo(newBandId, token);\n                if (json != null) bandsIDs.Add(newBandId);\n                else Console.WriteLine(\"Invalid band ID. Please check for typos.\");\n            }\n\n\n            Console.Write(\"Write your band ID\");\n            //If user has written more than 1 band, inform him that he can continue\n            if (bandsIDs.Count > 1) Console.Write(\" (or just Enter to proceed)\");\n            Console.Write(\": \");\n\n            newBandId = Console.ReadLine();\n        }\n\n        //We'll be storing the artists data here\n        List<ArtistData> artistsData = new List<ArtistData>();\n\n        foreach (string bandId in bandsIDs)\n        {\n            int accumPopularity = 0;\n\n            //Get artist's name and number of followers\n            string artistJsonString = await api.GetArtistInfo(bandId, token);\n            Artist artist = JsonSerializer.Deserialize<Artist>(artistJsonString);\n\n            Console.ForegroundColor = ConsoleColor.DarkGreen;\n            Console.WriteLine($\"\\n~~~~~BAND: {artist.Name}~~~~~\");\n            Console.ForegroundColor = ConsoleColor.White;\n\n            Console.WriteLine($\"\\n{artist.Name} has {artist.Followers.TotalFollowers} followers.\");\n            accumPopularity += ((int)(artist.Followers.TotalFollowers * 0.00001));\n\n            //Get top tracks\n            string topTracksJsonString = await api.GetTopTracksInfo(bandId, token);\n\n            TopTracks topTracks = JsonSerializer.Deserialize<TopTracks>(topTracksJsonString);\n            //Get Popularity of the last 10 tracks\n            Console.WriteLine($\"\\nWriting Top 10 Tracks for {artist.Name}\");\n            int i = 0;\n            foreach (TrackObject track in topTracks.trackObjects)\n            {\n                Console.WriteLine($\"The track called {track.Name} has {track.Popularity} popularity\");\n                accumPopularity += track.Popularity;\n                i++;\n                if (i >= 10) break;\n            }\n\n            //Get Albums\n            string AlbumsJsonString = await api.GetAlbumsInfo(bandId, token);\n\n            Albums simplifiedAlbums = JsonSerializer.Deserialize<Albums>(AlbumsJsonString);\n            List<Album> albums = new List<Album>();\n\n\n            foreach (SimplifiedAlbumObject sAlbum in simplifiedAlbums.AlbumObjects)\n            {\n                //Get Albums from SimplifiedAlbumObject, append them to an array\n                string albumJsonString = await api.GetAlbumInfo(sAlbum.Id, token);\n                Album album = JsonSerializer.Deserialize<Album>(albumJsonString);\n\n\n                albums.Add(album);\n            }\n            List<Album> sortedAlbums = albums.OrderByDescending(x => x.Popularity).ToList();\n\n\n            Album? mostFamousAlbum = null;\n            Console.WriteLine($\"\\nWriting Top 10 Albums for {artist.Name}\");\n            i = 0;\n            foreach (Album album in sortedAlbums)\n            {\n                if (mostFamousAlbum == null || album.Popularity > mostFamousAlbum.Popularity) mostFamousAlbum = album;\n                Console.WriteLine($\"The album called {album.Name} has {album.Popularity} popularity\");\n                accumPopularity += album.Popularity;\n                i++;\n                if (i >= 10) break;\n            }\n\n            ArtistData artistData = new ArtistData(bandId, artist.Name, artist.Followers.TotalFollowers, accumPopularity, mostFamousAlbum.Name);\n            artistsData.Add(artistData);\n        }\n\n        //Sort by popularity, pick the most famous one\n        List<ArtistData> sortedArtists = artistsData.OrderByDescending(x => x.Popularity).ToList();\n        ArtistData mostFamousArtist = sortedArtists.First();\n\n        Console.WriteLine($\"\\nThe most famous artist is {mostFamousArtist.Name}! (https://open.spotify.com/artist/{mostFamousArtist.Id})\\nHe has the incredible amount of {mostFamousArtist.Followers} followers and his current most famous album is {mostFamousArtist.MostFamousAlbumName}\");\n    }\n}\n\npublic class SpotifyAPI\n{\n    const string APIURL = \"https://accounts.spotify.com/api/token\";\n    private string _clientId;\n    private string _clientSecret;\n    HttpClient httpClient;\n\n    public SpotifyAPI(string clientId, string clientSecret)\n    {\n        httpClient = new HttpClient();\n        _clientId = clientId;\n        _clientSecret = clientSecret;\n    }\n\n    public async Task<string?> GetArtistInfo(string artistId, string token)\n    {\n        //Create url\n        var url = $\"https://api.spotify.com/v1/artists/{artistId}\";\n        var rString = await GetJSONStringFromGETRequest(url, token);\n\n        return rString;\n    }\n\n    public async Task<string?> GetTopTracksInfo(string artistId, string token)\n    {\n        var url = $\"https://api.spotify.com/v1/artists/{artistId}/top-tracks\";\n        var rString = await GetJSONStringFromGETRequest(url, token);\n\n        return rString;\n    }\n    public async Task<string?> GetAlbumsInfo(string artistId, string token)\n    {\n        var url = $\"https://api.spotify.com/v1/artists/{artistId}/albums\";\n        var rString = await GetJSONStringFromGETRequest(url, token);\n\n        return rString;\n    }\n\n    public async Task<string?> GetAlbumInfo(string artistId, string token)\n    {\n        var url = $\"https://api.spotify.com/v1/albums/{artistId}\";\n        var rString = await GetJSONStringFromGETRequest(url, token);\n\n        return rString;\n    }\n\n    public async Task<string?> GetJSONStringFromGETRequest(string url, string token)\n    {\n        //send GET request\n        var r = await CreateGETRequestAtUrl(url, token);\n        if (r == null) return null;\n\n        //Make response \"r\" a String\n        string responseStr = await r.Content.ReadAsStringAsync();\n        return responseStr;\n    }\n\n    public async Task<HttpResponseMessage?> CreateGETRequestAtUrl(string url, string token)\n    {\n        //Set Headers\n        httpClient.DefaultRequestHeaders.Clear();\n        httpClient.DefaultRequestHeaders.Add(\"Authorization\", $\"Bearer {token}\");\n        HttpResponseMessage response = await httpClient.GetAsync(url);\n        if (response.IsSuccessStatusCode)\n        {\n            return response;\n        }\n        return null;\n    }\n\n    public async Task<string> GetAuthToken()\n    {\n        //Format to Base64, grant_type to client_credentials\n        string authHeader = Convert.ToBase64String(Encoding.UTF8.GetBytes($\"{_clientId}:{_clientSecret}\"));\n        var requestKey = new List<KeyValuePair<string, string>>\n    {\n        new KeyValuePair<string, string>(\"grant_type\", \"client_credentials\")\n    };\n\n        httpClient.DefaultRequestHeaders.Clear();\n        httpClient.DefaultRequestHeaders.Add(\"Authorization\", $\"Basic {authHeader}\");\n\n        //Encode requestKey\n        FormUrlEncodedContent content = new FormUrlEncodedContent(requestKey);\n\n        HttpResponseMessage response = await httpClient.PostAsync(APIURL, content);\n        if (response.IsSuccessStatusCode)\n        {\n            string responseStr = await response.Content.ReadAsStringAsync();\n            Console.WriteLine(response.StatusCode);\n\n            //Deserialize to dict\n            var responseDict = JsonSerializer.Deserialize<Dictionary<string, object>>(responseStr);\n            return responseDict[\"access_token\"].ToString();\n        }\n\n        Console.WriteLine($\"Error: {response.StatusCode}\");\n        return \"\";\n    }\n}\n\n\npublic class Artist\n{\n    [JsonPropertyName(\"name\")]\n    public string Name { get; set; }\n    [JsonPropertyName(\"followers\")]\n    public Followers Followers { get; set; }\n}\n\npublic class Followers\n{\n    [JsonPropertyName(\"total\")]\n    public int TotalFollowers { get; set; }\n}\n\npublic class TopTracks\n{\n    [JsonPropertyName(\"tracks\")]\n    public TrackObject[] trackObjects { get; set; }\n}\n\npublic class TrackObject\n{\n    [JsonPropertyName(\"name\")]\n    public string Name { get; set; }\n    [JsonPropertyName(\"popularity\")]\n    public int Popularity { get; set; }\n}\n\npublic class Albums\n{\n    [JsonPropertyName(\"items\")]\n    public SimplifiedAlbumObject[] AlbumObjects { get; set; }\n}\n\npublic class SimplifiedAlbumObject\n{\n    [JsonPropertyName(\"id\")]\n    public string Id { get; set; }\n}\n\npublic class Album\n{\n    [JsonPropertyName(\"name\")]\n    public string Name { get; set; }\n    [JsonPropertyName(\"popularity\")]\n    public int Popularity { get; set; }\n}\n\npublic class ArtistData\n{\n    public string Id;\n    public string Name;\n    public int Followers;\n    public int Popularity;\n    public string MostFamousAlbumName;\n\n    public ArtistData(string id, string name, int followers, int popularity, string mostFamousAlbumName)\n    {\n        Id = id;\n        Name = name;\n        Followers = followers;\n        Popularity = popularity;\n        MostFamousAlbumName = mostFamousAlbumName;\n    }\n}"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/c#/deathwing696.cs",
    "content": "﻿using System;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json.Linq;\nusing System.Configuration;\n\n/*\n * EJERCICIO:\n * ¡Dos de las bandas más grandes de la historia están de vuelta!\n * Oasis y Linkin Park han anunciado nueva gira, pero, ¿quién es más popular?\n * Desarrolla un programa que se conecte al API de Spotify y los compare.\n * Requisitos:\n * 1. Crea una cuenta de desarrollo en https://developer.spotify.com.\n * 2. Conéctate al API utilizando tu lenguaje de programación.\n * 3. Recupera datos de los endpoint que tú quieras.\n * Acciones:\n * 1. Accede a las estadísticas de las dos bandas.\n *    Por ejemplo: número total de seguidores, escuchas mensuales,\n *    canción con más reproducciones...\n * 2. Compara los resultados de, por lo menos, 3 endpoint.\n * 3. Muestra todos los resultados por consola para notificar al usuario.\n * 4. Desarrolla un criterio para seleccionar qué banda es más popular.\n */\n\nnamespace Reto_37\n{\n    internal class deathwing696\n    {\n        public class Spotify\n        {\n            private string urlAPI = \"https://api.spotify.com/v1/\";\n            private string urlApiToken = \"https://accounts.spotify.com/api/token\";\n            private static string clientId = ConfigurationManager.AppSettings[\"SpotifyClientId\"];\n            private static string clientSecret = ConfigurationManager.AppSettings[\"SpotifyClientSecret\"];\n            private string artist1;\n            private string artist2;\n            private int artist1Points = 0;\n            private int artist2Points = 0;\n\n            public Spotify(string artist1, string artist2)\n            {\n                this.artist1 = artist1;\n                this.artist2 = artist2;\n            }\n\n            internal async Task<string> GetSpotifyAccessToken()\n            {\n                using (var client = new HttpClient())\n                {\n                    var request = new HttpRequestMessage(HttpMethod.Post, urlApiToken);\n                    var clientCredentials = Convert.ToBase64String(Encoding.UTF8.GetBytes($\"{clientId}:{clientSecret}\"));\n\n                    request.Headers.Authorization = new AuthenticationHeaderValue(\"Basic\", clientCredentials);\n                    request.Content = new StringContent(\"grant_type=client_credentials\", Encoding.UTF8, \"application/x-www-form-urlencoded\");\n\n                    var response = await client.SendAsync(request);\n                    response.EnsureSuccessStatusCode();\n\n                    var responseBody = await response.Content.ReadAsStringAsync();\n                    var json = JObject.Parse(responseBody);\n\n                    return json[\"access_token\"].ToString();\n                }\n            }\n\n            internal async Task CompareArtists(string token)\n            {\n                var artist1Data = await GetArtistData(token, artist1);\n                var artist2Data = await GetArtistData(token, artist2);\n\n                Console.WriteLine($\"Artista: {artist1Data.Name}\");\n                Console.WriteLine($\"Seguidores: {artist1Data.Followers}\");\n                Console.WriteLine($\"Popularidad: {artist1Data.Popularity}\");\n                Console.WriteLine($\"Canción más popular: {artist1Data.TopTrack} con {artist1Data.TopTrackPopularity} de popularidad\");\n                Console.WriteLine();\n\n                Console.WriteLine($\"Artista: {artist2Data.Name}\");\n                Console.WriteLine($\"Seguidores: {artist2Data.Followers}\");\n                Console.WriteLine($\"Popularidad: {artist2Data.Popularity}\");\n                Console.WriteLine($\"Canción más popular: {artist2Data.TopTrack} con {artist2Data.TopTrackPopularity} de popularidad\");\n                Console.WriteLine();\n\n                // Comparación\n                Console.WriteLine(\"Comparación:\");\n                string moreFollowers;\n\n                if (artist1Data.Followers > artist2Data.Followers)\n                {\n                    moreFollowers = artist1Data.Name;\n                    artist1Points++;\n                }\n                else \n                {\n                    moreFollowers = artist2Data.Name;\n                    artist2Points++;\n                }\n                Console.WriteLine($\"Artista con más seguidores: {moreFollowers}\");\n\n                string morePopular;\n                if (artist1Data.Popularity > artist2Data.Popularity)\n                {\n                    morePopular = artist1Data.Name;\n                    artist1Points++;\n                }\n                else\n                {\n                    morePopular = artist2Data.Name;\n                    artist2Points++;\n                }\n                Console.WriteLine($\"Artista más popular: {morePopular}\");\n\n                string topTrack, artistTopTrack;\n                if (artist1Data.TopTrackPopularity > artist2Data.TopTrackPopularity)\n                {\n                    topTrack = artist1Data.TopTrack;\n                    artistTopTrack = artist1Data.Name;\n                    artist1Points++;\n                }\n                else\n                {\n                    topTrack = artist2Data.TopTrack;\n                    artistTopTrack = artist2Data.Name;\n                    artist2Points++;\n                }\n                Console.WriteLine($\"Canción con más popularidad: {topTrack} de {artistTopTrack}\");\n\n                Console.WriteLine(\"PUNTUACIÓN FINAL:\");\n                \n                if (artist1Points > artist2Points)\n                {\n                    Console.WriteLine($\"El ganador de este duelo es {artist1Data.Name} con {artist1Points} puntos\");\n                }\n                else if (artist2Points > artist1Points)\n                {\n                    Console.WriteLine($\"El ganador de este duelo es {artist2Data.Name} con {artist2Points} puntos\");\n                }\n                else\n                {\n                    Console.WriteLine($\"Ha habido un empate en el duelo entre {artist1Data.Name} y {artist2Data.Name} con {artist1Points} puntos\");\n                }\n            }\n\n            private async Task<(string Name, int Followers, int Popularity, string TopTrack, int TopTrackPopularity)> GetArtistData(string token, string artistName)\n            {\n                using (var client = new HttpClient())\n                {\n                    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(\"Bearer\", token);\n\n                    // Buscar al artista\n                    var searchResponse = await client.GetAsync($\"{urlAPI}search?q={Uri.EscapeDataString(artistName)}&type=artist\");\n                    searchResponse.EnsureSuccessStatusCode();\n                    var searchResult = JObject.Parse(await searchResponse.Content.ReadAsStringAsync());\n\n                    var artist = searchResult[\"artists\"][\"items\"].First;\n                    string artistId = artist[\"id\"].ToString();\n                    string name = artist[\"name\"].ToString();\n                    int followers = (int)artist[\"followers\"][\"total\"];\n                    int popularity = (int)artist[\"popularity\"];\n\n                    // Obtener las canciones más populares\n                    var tracksResponse = await client.GetAsync($\"{urlAPI}artists/{artistId}/top-tracks?market=US\");\n                    tracksResponse.EnsureSuccessStatusCode();\n                    var tracksResult = JObject.Parse(await tracksResponse.Content.ReadAsStringAsync());\n\n                    var topTrack = tracksResult[\"tracks\"].First;\n                    string topTrackName = topTrack[\"name\"].ToString();\n                    int topTrackPopularity = (int)topTrack[\"popularity\"];\n\n                    return (name, followers, popularity, topTrackName, topTrackPopularity);\n                }\n            }\n        }\n\n        static async Task Main(string[] args)\n        {\n            Spotify spotify = new Spotify(\"Oasis\", \"Linkin Park\");\n\n            string token = await spotify.GetSpotifyAccessToken();\n\n            await spotify.CompareArtists(token);            \n\n            Console.ReadKey();\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/c#/hequebo.cs",
    "content": "using Newtonsoft.Json.Linq;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Text.Json;\n\nclass Artist\n{\n    public string? Id { get; set; }\n    public string? Name { get; set; }\n    public List<string>? Genres { get; set; }\n    public int Popularity { get; set; }\n    public int Followers { get; set; }\n    public int Points {  get; set; }\n    public TopTrack TopTrack { get; set; }\n    public Artist()\n    {\n        Genres = new List<string>(); \n        Points = 0;\n    }\n}\nclass TopTrack\n{\n    public string Id { get; set; }\n    public string Name { get; set; }\n    public int Popularity { get; set; }\n}\n\nclass Spotify\n{\n    private string? _clientId = Environment.GetEnvironmentVariable(\"CLIENT_ID\");\n    private string? _clientSecret = Environment.GetEnvironmentVariable(\"CLIENT_SECRET\");\n    public async Task<string> GetToken(HttpClient httpClient)\n    {\n        if (string.IsNullOrEmpty(_clientId) || string.IsNullOrEmpty(_clientSecret))\n        {\n            await Console.Out.WriteLineAsync(\"No se cuenta con las credenciales necesarias...\");\n            return \"\";\n        }\n        var content = new Dictionary<string, string>\n        {\n            { \"grant_type\", \"client_credentials\" }\n        };\n        httpClient.BaseAddress = new Uri(\"https://accounts.spotify.com/api\");\n        var authenticationString = Encoding.ASCII.GetBytes($\"{_clientId}:{_clientSecret}\");\n        httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(\"Basic\", Convert.ToBase64String(authenticationString));\n\n        var response = await httpClient.PostAsync($\"{httpClient.BaseAddress}/token\", new FormUrlEncodedContent(content));\n\n        if (response.StatusCode != System.Net.HttpStatusCode.OK)\n            return \"\";\n\n        var jsonResponse = await response.Content.ReadAsStringAsync();\n        string token = JObject.Parse(jsonResponse)[\"access_token\"].ToString();\n\n        return token;\n    }\n\n    public async Task<string> SearchArtist(HttpClient httpClient, string name, string token)\n    {\n        var url = $\"https://api.spotify.com/v1/search?q={name}&type=artist&limit=1\";\n\n        httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(\"Bearer\", token);\n\n        var response = await httpClient.GetAsync(new Uri(url));\n        if (response.StatusCode != System.Net.HttpStatusCode.OK)\n        {\n            return \"\";\n        }\n\n        var jsonResponse = await response.Content.ReadAsStringAsync();\n        var resultObject = JObject.Parse(jsonResponse);\n        var artist = resultObject[\"artists\"];\n        var item = artist[\"items\"][0];\n        return item[\"id\"].ToString();\n    }\n\n    public async Task<Artist> GetArtist(string id, HttpClient httpClient, string token)\n    {\n        var url = $\"https://api.spotify.com/v1/artists/{id}\";\n\n        httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(\"Bearer\", token);\n\n        var response = await httpClient.GetAsync(new Uri(url));\n        if (response.StatusCode != System.Net.HttpStatusCode.OK)\n        {\n            return null;\n        }\n        var jsonResponse = await response.Content.ReadAsStringAsync();\n        var resultObject = JObject.Parse(jsonResponse);\n\n        var artist = new Artist();\n        artist.Id = id;\n        artist.Name = resultObject[\"name\"].ToString();\n        foreach (string genre in resultObject[\"genres\"])\n            artist.Genres.Add(genre);\n        artist.Popularity = (int)resultObject[\"popularity\"];\n        artist.Followers = (int)resultObject[\"followers\"][\"total\"];\n\n        return artist;\n    }\n\n    public async Task<TopTrack> GetTopTrack(string id, HttpClient httpClient, string token)\n    {\n        var url = $\"https://api.spotify.com/v1/artists/{id}/top-tracks\";\n        httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(\"Bearer\", token);\n\n        var response = await httpClient.GetAsync(new Uri(url));\n        if (response.StatusCode != System.Net.HttpStatusCode.OK)\n        {\n            return null;\n        }\n        var jsonResponse = await response.Content.ReadAsStringAsync();\n\n        var resultObject = JObject.Parse(jsonResponse);\n        var tracks = new List<TopTrack>();\n\n        foreach(var item in resultObject[\"tracks\"])\n        {\n            var track = new TopTrack();\n            track.Id = item[\"id\"].ToString();\n            track.Name = item[\"name\"].ToString();\n            track.Popularity = (int)item[\"popularity\"];\n            tracks.Add(track);\n        }\n        var maxPoularity = tracks.Max(track => track.Popularity);\n        var topTrack = tracks.Where(t => t.Popularity == maxPoularity).FirstOrDefault();\n\n        return topTrack;\n    }\n\n}\nclass Program\n{\n    private static HttpClient _httpClient = new HttpClient();\n    static async Task Main(string[] args)\n    {\n        var spotify = new Spotify();\n        string token = await spotify.GetToken(_httpClient);\n        Console.WriteLine(\"---Enfrentamiento de Artistas---\");\n        Console.WriteLine(\"Ingresa el nombre del primera artista\");\n        string artist1Name = Console.ReadLine();\n\n\n        string artist1Id = await spotify.SearchArtist(_httpClient, artist1Name, token);\n\n        if (artist1Id == \"\")\n        {\n            Console.WriteLine($\"No se ha encontrado información del artista {artist1Name}...\");\n            return;\n        }\n        \n        var artist1 = await spotify.GetArtist(artist1Id, _httpClient, token);\n\n        Console.WriteLine(\"Ingresa el nombre del segundo artista\");\n        string artist2Name = Console.ReadLine();\n\n\n        string artist2Id = await spotify.SearchArtist(_httpClient, artist2Name, token);\n\n        if (artist2Id == \"\")\n        {\n            Console.WriteLine($\"No se ha encontrado información del artista {artist2Name}...\");\n            return;\n        }\n\n        var artist2 = await spotify.GetArtist(artist2Id, _httpClient, token);\n\n        Console.WriteLine($\"{artist1.Name} VS {artist2.Name}\");\n        Console.WriteLine(\"---Seguidores---\");\n        Console.WriteLine($\"{artist1.Name}: {artist1.Followers}\\t{artist2.Name}:{artist2.Followers}\");\n        if (artist1.Followers > artist2.Followers)\n        {\n            Console.WriteLine($\"{artist1.Name} supera a {artist2.Name} en seguidores con un total de \" +\n                $\"{artist1.Followers} seguidores en Spotify...\");\n            artist1.Points++;\n        }\n        else if (artist1.Followers == artist2.Followers)\n        {\n            Console.WriteLine($\"{artist1.Name} y {artist2.Name} empatan este round con \" +\n                $\"{artist1.Followers} cada uno\");\n        }\n        else\n        {\n            Console.WriteLine($\"{artist2.Name} gana este round con un total de {artist2.Followers}\");\n            artist2.Points++;\n        }\n        Console.WriteLine(\"---Popularidad---\");\n        Console.WriteLine($\"{artist1.Name}: {artist1.Popularity}\\t{artist2.Name}: {artist2.Popularity}\");\n        if (artist1.Popularity > artist2.Popularity)\n        {\n            Console.WriteLine($\"{artist1.Name} gana el round de popularidad\");\n            artist1.Points++;\n        }\n        else if (artist1.Popularity == artist2.Popularity)\n        {\n            Console.WriteLine($\"{artist1.Name} y {artist2.Name} empatan este round\");\n            artist1.Points++;\n            artist2.Points++;\n        }\n        else\n        {\n            Console.WriteLine($\"{artist2.Name} supera a {artist1.Name} en popularidad\");\n            artist2.Points++;\n        }\n\n        artist1.TopTrack = await spotify.GetTopTrack(artist1.Id, _httpClient, token);\n        artist2.TopTrack = await spotify.GetTopTrack(artist2.Id, _httpClient, token);\n\n        Console.WriteLine(\"---Canciones más populares---\");\n        Console.WriteLine($\"{artist1.Name}.- {artist1.TopTrack.Name}: {artist1.TopTrack.Popularity}\");\n        Console.WriteLine($\"{artist2.Name}.- {artist2.TopTrack.Name}: {artist2.TopTrack.Popularity}\");\n        \n        if (artist1.TopTrack.Popularity > artist2.TopTrack.Popularity)\n        {\n            Console.WriteLine($\"{artist1.Name} gana este round con {artist1.TopTrack.Name}\");\n            artist1.Points++;\n        }\n        else if (artist1.TopTrack.Popularity  == artist2.TopTrack.Popularity)\n        {\n            Console.WriteLine($\"Las canciones {artist1.TopTrack.Name} y {artist2.TopTrack.Name} \" +\n                $\"están empatadas en cuanto popularidad\");\n            artist1.Points++;\n            artist2.Points++;\n        }\n        else\n        {\n            Console.WriteLine($\"{artist2.Name} supera a {artist1.Name} con {artist2.TopTrack.Name}\");\n            artist2.Points++;\n        }\n\n        Console.WriteLine(\"---RESULTADOS---\");\n        if (artist1.Points > artist2.Points)\n            Console.WriteLine($\"{artist1.Name} es el ganador de esta batalla\");\n        else if (artist1.Points == artist2.Points)\n            Console.WriteLine($\"{artist1.Name} y {artist2.Name} han empatado\");\n        else\n            Console.WriteLine($\"{artist2.Name} se lleva la victoria\");\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/c#/kenysdev.cs",
    "content": "namespace exs37;\n/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - C#\n_____________________________________\nOASIS VS LINKIN PARK\n------------------------------------\n* ¡Dos de las bandas más grandes de la historia están de vuelta!\n* Oasis y Linkin Park han anunciado nueva gira, pero, ¿quién es más popular?\n* Desarrolla un programa que se conecte al API de Spotify y los compare.\n* Requisitos:\n* 1. Crea una cuenta de desarrollo en https://developer.spotify.com.\n* 2. Conéctate al API utilizando tu lenguaje de programación.\n* 3. Recupera datos de los endpoint que tú quieras.\n* Acciones:\n* 1. Accede a las estadísticas de las dos bandas.\n*    Por ejemplo: número total de seguidores, escuchas mensuales,\n*    canción con más reproducciones...\n* 2. Compara los resultados de, por lo menos, 3 endpoint.\n* 3. Muestra todos los resultados por consola para notificar al usuario.\n* 4. Desarrolla un criterio para seleccionar qué banda es más popular.\n*/\n\n\nusing System.Linq;\nusing System.Threading.Tasks;\n\n// https://www.nuget.org/packages/SpotifyAPI.Web/\n// https://johnnycrazy.github.io/SpotifyAPI-NET/docs/introduction\nusing SpotifyAPI.Web;\n\n// https://www.nuget.org/packages/DotNetEnv/\nusing DotNetEnv;\n\npublic class Spotify\n{\n    private readonly SpotifyClient _spotify;\n\n    public Spotify()\n    {\n        Env.Load();\n        var clientId = Environment.GetEnvironmentVariable(\"SPOTIFY_CLIENT_ID\");\n        var clientSecret = Environment.GetEnvironmentVariable(\"SPOTIFY_CLIENT_SECRET\");\n\n        if (string.IsNullOrEmpty(clientId) || string.IsNullOrEmpty(clientSecret))\n        {\n            throw new ArgumentException(\"Se debe proporcionar 'CLIENT_ID' y 'CLIENT_SECRET'.\");\n        }\n\n        var config = SpotifyClientConfig\n            .CreateDefault()\n            .WithAuthenticator(new ClientCredentialsAuthenticator(clientId, clientSecret));\n\n        _spotify = new SpotifyClient(config);\n    }\n\n    public async Task<SearchResponse> GetArtistsAsync(string name)\n    {\n        var searchRequest = new SearchRequest(SearchRequest.Types.Artist, name)\n        {\n            Limit = 3\n        };\n        return await _spotify.Search.Item(searchRequest);\n    }\n\n    public async Task<FullArtist?> GetMostPopularArtistAsync(string name)\n    {\n        var searchResult = await GetArtistsAsync(name);\n\n        if (searchResult?.Artists?.Items == null || searchResult.Artists.Items.Count == 0)\n        {\n            return null;\n        }\n\n        var mostPopularArtist = searchResult.Artists.Items\n            .OrderByDescending(artist => artist.Popularity)\n            .FirstOrDefault();\n\n        return mostPopularArtist;\n    }\n\n    public async Task<ArtistsTopTracksResponse> ArtistTopTracksAsync(string artistId)\n    {\n        return await _spotify.Artists.GetTopTracks(artistId, new ArtistsTopTracksRequest(\"US\"));\n    }\n\n}\n\npublic class Versus(FullArtist artist1, FullArtist artist2, Spotify spotifyInstance)\n{\n    private readonly FullArtist _artist1 = artist1;\n    private readonly FullArtist _artist2 = artist2;\n    private readonly Spotify _spotify = spotifyInstance;\n    private int _artist1Score = 0;\n    private int _artist2Score = 0;\n\n    private Task Popularity()\n    {\n        if (_artist1 == null || _artist2 == null)\n        {\n            Console.WriteLine(\"Uno o ambos artistas no están disponibles.\");\n            return Task.CompletedTask;\n        }\n\n        int a1Pop = _artist1.Popularity;\n        int a2Pop = _artist2.Popularity;\n\n        Console.WriteLine($\"Popularidad: {a1Pop} vs {a2Pop}\");\n        if (a1Pop > a2Pop)\n        {\n            _artist1Score++;\n        }\n        else if (a2Pop > a1Pop)\n        {\n            _artist2Score++;\n        }\n\n        return Task.CompletedTask;\n    }\n\n    private Task Followers()\n    {\n        if (_artist1 == null || _artist2 == null)\n        {\n            Console.WriteLine(\"Uno o ambos artistas no están disponibles.\");\n            return Task.CompletedTask;\n        }\n\n        int a1Foll = _artist1.Followers.Total;\n        int a2Foll = _artist2.Followers.Total;\n\n        Console.WriteLine($\"Seguidores: {a1Foll} vs {a2Foll}\");\n        if (a1Foll > a2Foll)\n        {\n            _artist1Score++;\n        }\n        else if (a2Foll > a1Foll)\n        {\n            _artist2Score++;\n        }\n\n        return Task.CompletedTask;\n    }\n\n    private async Task Top3TracksAsync()\n    {\n        if (_artist1 == null || _artist2 == null)\n        {\n            Console.WriteLine(\"Uno o ambos artistas no están disponibles.\");\n            return;\n        }\n\n        var a1Top = await _spotify.ArtistTopTracksAsync(_artist1.Id);\n        var a2Top = await _spotify.ArtistTopTracksAsync(_artist2.Id);\n\n        int a1Pop = a1Top.Tracks.Take(3).Sum(track => track.Popularity);\n        int a2Pop = a2Top.Tracks.Take(3).Sum(track => track.Popularity);\n\n        Console.WriteLine($\"Popularidad Top 3 canciones: {a1Pop} vs {a2Pop}\");\n        if (a1Pop > a2Pop)\n        {\n            _artist1Score++;\n        }\n        else if (a2Pop > a1Pop)\n        {\n            _artist2Score++;\n        }\n    }\n\n    private void FinalResult()\n    {\n        Console.WriteLine(\"\\nRESULTADO FINAL:\");\n        Console.WriteLine($\"{_artist1.Name}: {_artist1Score} puntos\");\n        Console.WriteLine($\"{_artist2.Name}: {_artist2Score} puntos\");\n\n        if (_artist1Score > _artist2Score)\n        {\n            Console.WriteLine($\"\\n¡'{_artist1.Name}' gana el versus!\");\n        }\n        else if (_artist2Score > _artist1Score)\n        {\n            Console.WriteLine($\"\\n¡'{_artist2.Name}' gana el versus!\");\n        }\n        else\n        {\n            Console.WriteLine(\"\\n¡Es un empate!\");\n        }\n    }\n\n    public async Task StartAsync()\n    {\n        Console.WriteLine($\"{_artist1.Name} vs {_artist2.Name}\");\n        await Popularity();\n        await Followers();\n        await Top3TracksAsync();\n        FinalResult();\n    }\n}\n\npublic class Program\n{\n    public static async Task Main()\n    {\n        Console.WriteLine(\"VERSUS\");\n        var spotify = new Spotify();\n\n        var artist1 = await spotify.GetMostPopularArtistAsync(\"Oasis\");\n        var artist2 = await spotify.GetMostPopularArtistAsync(\"Linkin Park\");\n\n        if (artist1 == null || artist2 == null)\n        {\n            Console.WriteLine(\"Artistas no encontrados\");\n            return;\n        }\n\n        var versus = new Versus(artist1, artist2, spotify);\n        await versus.StartAsync();\n    }\n}\n"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/c++/hectorio23.cpp",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\n#include <iostream>\n#include <string>\n#include <curl/curl.h>\n#include <json/json.h>\n\n// Función para manejar la respuesta de cURL\nstatic size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userp) {\n    ((std::string*)userp)->append((char*)contents, size * nmemb);\n    return size * nmemb;\n}\n\n// Función para obtener el token de acceso\nstd::string getAccessToken(const std::string& client_id, const std::string& client_secret) {\n    CURL* curl;\n    CURLcode res;\n    std::string readBuffer;\n\n    curl = curl_easy_init();\n    if(curl) {\n        curl_easy_setopt(curl, CURLOPT_URL, \"https://accounts.spotify.com/api/token\");\n        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);\n        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);\n\n        struct curl_slist* headers = nullptr;\n        headers = curl_slist_append(headers, \"Content-Type: application/x-www-form-urlencoded\");\n        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);\n\n        std::string data = \"grant_type=client_credentials&client_id=\" + client_id + \"&client_secret=\" + client_secret;\n        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data.c_str());\n\n        res = curl_easy_perform(curl);\n        curl_easy_cleanup(curl);\n    }\n\n    Json::Reader reader;\n    Json::Value jsonData;\n    reader.parse(readBuffer, jsonData);\n    return jsonData[\"access_token\"].asString();\n}\n\n// Función para obtener los datos de la banda\nJson::Value getArtistData(const std::string& artist_name, const std::string& token) {\n    CURL* curl;\n    CURLcode res;\n    std::string readBuffer;\n\n    curl = curl_easy_init();\n    if(curl) {\n        std::string url = \"https://api.spotify.com/v1/search?q=\" + artist_name + \"&type=artist&limit=1\";\n        curl_easy_setopt(curl, CURLOPT_URL, url.c_str());\n        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);\n        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);\n\n        struct curl_slist* headers = nullptr;\n        std::string authHeader = \"Authorization: Bearer \" + token;\n        headers = curl_slist_append(headers, authHeader.c_str());\n        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);\n\n        res = curl_easy_perform(curl);\n        curl_easy_cleanup(curl);\n    }\n\n    Json::Reader reader;\n    Json::Value jsonData;\n    reader.parse(readBuffer, jsonData);\n    return jsonData[\"artists\"][\"items\"][0];\n}\n\n// Comparación entre Oasis y Linkin Park\nvoid compareBands() {\n    std::string client_id = \"your_client_id\";\n    std::string client_secret = \"your_client_secret\";\n    std::string token = getAccessToken(client_id, client_secret);\n\n    Json::Value oasis_data = getArtistData(\"Oasis\", token);\n    Json::Value linkin_park_data = getArtistData(\"Linkin Park\", token);\n\n    std::cout << \"Oasis: \" << oasis_data[\"followers\"][\"total\"].asInt() << \" seguidores\" << std::endl;\n    std::cout << \"Linkin Park: \" << linkin_park_data[\"followers\"][\"total\"].asInt() << \" seguidores\" << std::endl;\n\n    if (oasis_data[\"followers\"][\"total\"].asInt() > linkin_park_data[\"followers\"][\"total\"].asInt()) {\n        std::cout << \"Oasis es más popular en seguidores.\" << std::endl;\n    } else {\n        std::cout << \"Linkin Park es más popular en seguidores.\" << std::endl;\n    }\n}\n\nint main() {\n    compareBands();\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/ejercicio.md",
    "content": "# #37 OASIS VS LINKIN PARK\n> #### Dificultad: Media | Publicación: 09/09/24 | Corrección: 16/09/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * ¡Dos de las bandas más grandes de la historia están de vuelta!\n * Oasis y Linkin Park han anunciado nueva gira, pero, ¿quién es más popular?\n * Desarrolla un programa que se conecte al API de Spotify y los compare.\n * Requisitos:\n * 1. Crea una cuenta de desarrollo en https://developer.spotify.com.\n * 2. Conéctate al API utilizando tu lenguaje de programación.\n * 3. Recupera datos de los endpoint que tú quieras.\n * Acciones:\n * 1. Accede a las estadísticas de las dos bandas.\n *    Por ejemplo: número total de seguidores, escuchas mensuales,\n *    canción con más reproducciones...\n * 2. Compara los resultados de, por lo menos, 3 endpoint.\n * 3. Muestra todos los resultados por consola para notificar al usuario.\n * 4. Desarrolla un criterio para seleccionar qué banda es más popular.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/go/hozlucas28.go",
    "content": "package main\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n)\n\n/* -------------------------------------------------------------------------- */\n/*                                   STRUCTS                                  */\n/* -------------------------------------------------------------------------- */\n\ntype Artist struct {\n\tID   string `json:\"id\"`\n\tName string `json:\"name\"`\n\t_    struct{}\n}\n\ntype ArtistData struct {\n\tFollowers  Followers `json:\"followers\"`\n\tId         string    `json:\"id\"`\n\tName       string    `json:\"name\"`\n\tPopularity int       `json:\"popularity\"`\n\t_          struct{}\n}\n\ntype ArtistTopTracks struct {\n\tTracks []Track `json:\"tracks\"`\n}\n\ntype Followers struct {\n\tTotal int `json:\"total\"`\n\t_     struct{}\n}\n\ntype Search struct {\n\tArtists struct {\n\t\tItems []Artist `json:\"Items\"`\n\t} `json:\"Artists\"`\n\t_ struct{}\n}\n\ntype Token struct {\n\tAccessToken string `json:\"access_token\"`\n\tTokenType   string `json:\"token_type\"`\n\tExpiresIn   int    `json:\"expires_in\"`\n\t_           struct{}\n}\n\ntype Track struct {\n\tName       string `json:\"name\"`\n\tPopularity int    `json:\"popularity\"`\n\t_          struct{}\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                  FUNCTIONS                                 */\n/* -------------------------------------------------------------------------- */\n\nfunc SearchArtist(fullName string, accessToken string) (Artist, error) {\n\tvar artist Artist\n\n\tqueries := url.Values{\n\t\t\"q\":     {fullName},\n\t\t\"type\":  {\"artist\"},\n\t\t\"limit\": {\"1\"},\n\t}\n\n\tvar endPoint string = \"https://api.spotify.com/v1/search?\" + queries.Encode()\n\n\trequest, err := http.NewRequest(\"GET\", endPoint, nil)\n\tif err != nil {\n\t\treturn artist, err\n\t}\n\n\trequest.Header = map[string][]string{\n\t\t\"Authorization\": {fmt.Sprintf(\"Bearer %s\", accessToken)},\n\t}\n\n\tclient := &http.Client{}\n\tresponse, err := client.Do(request)\n\tif err != nil {\n\t\treturn artist, err\n\t}\n\n\tif response.StatusCode == http.StatusOK {\n\t\tbody, err := io.ReadAll(response.Body)\n\t\tif err != nil {\n\t\t\treturn artist, err\n\t\t}\n\n\t\tvar search Search\n\t\terr = json.Unmarshal(body, &search)\n\t\tif err != nil {\n\t\t\treturn artist, err\n\t\t}\n\n\t\tartist = search.Artists.Items[0]\n\t} else {\n\t\tvar errMsg string = fmt.Sprintf(\"%s: %v\", request.Response.Status, request.Response.Body)\n\t\treturn artist, errors.New(errMsg)\n\t}\n\n\treturn artist, nil\n}\n\nfunc GetArtistData(id string, accessToken string) (ArtistData, error) {\n\tvar artistData ArtistData\n\n\tvar url string = fmt.Sprintf(\"https://api.spotify.com/v1/artists/%s\", id)\n\n\trequest, err := http.NewRequest(\"GET\", url, nil)\n\tif err != nil {\n\t\treturn artistData, err\n\t}\n\n\trequest.Header = map[string][]string{\n\t\t\"Authorization\": {fmt.Sprintf(\"Bearer %s\", accessToken)},\n\t}\n\n\tclient := &http.Client{}\n\tresponse, err := client.Do(request)\n\tif err != nil {\n\t\treturn artistData, err\n\t}\n\n\tif response.StatusCode == http.StatusOK {\n\t\tbody, err := io.ReadAll(response.Body)\n\t\tif err != nil {\n\t\t\treturn artistData, err\n\t\t}\n\n\t\terr = json.Unmarshal(body, &artistData)\n\t\tif err != nil {\n\t\t\treturn artistData, err\n\t\t}\n\t} else {\n\t\tvar errMsg string = fmt.Sprintf(\"%s: %v\", request.Response.Status, request.Response.Body)\n\t\treturn artistData, errors.New(errMsg)\n\t}\n\n\treturn artistData, nil\n}\n\nfunc GetTopTrack(tracks []Track) Track {\n\tvar topTrack Track = tracks[0]\n\n\tfor _, track := range tracks[1:] {\n\t\tif track.Popularity > topTrack.Popularity {\n\t\t\ttopTrack = track\n\t\t}\n\t}\n\n\treturn topTrack\n}\n\nfunc GetArtistTopTracks(id string, accessToken string) (ArtistTopTracks, error) {\n\tvar topTracks ArtistTopTracks\n\n\tvar url string = fmt.Sprintf(\"https://api.spotify.com/v1/artists/%s/top-tracks\", id)\n\n\trequest, err := http.NewRequest(\"GET\", url, nil)\n\tif err != nil {\n\t\treturn topTracks, err\n\t}\n\n\trequest.Header = map[string][]string{\n\t\t\"Authorization\": {fmt.Sprintf(\"Bearer %s\", accessToken)},\n\t}\n\n\tclient := &http.Client{}\n\tresponse, err := client.Do(request)\n\tif err != nil {\n\t\treturn topTracks, err\n\t}\n\n\tif response.StatusCode == http.StatusOK {\n\t\tbody, err := io.ReadAll(response.Body)\n\t\tif err != nil {\n\t\t\treturn topTracks, err\n\t\t}\n\n\t\terr = json.Unmarshal(body, &topTracks)\n\t\tif err != nil {\n\t\t\treturn topTracks, err\n\t\t}\n\t} else {\n\t\tvar errMsg string = fmt.Sprintf(\"%s: %v\", request.Response.Status, request.Response.Body)\n\t\treturn topTracks, errors.New(errMsg)\n\t}\n\n\treturn topTracks, nil\n}\n\nfunc GetSpotifyToken() (Token, error) {\n\tvar token Token\n\n\tvar clientID string = \"*****\"\n\tvar clientSecret string = \"*****\"\n\n\tvar url string = \"https://accounts.spotify.com/api/token\"\n\tvar contentType string = \"application/x-www-form-urlencoded\"\n\tvar body string = fmt.Sprintf(\"grant_type=client_credentials&client_id=%s&client_secret=%s\", clientID, clientSecret)\n\n\tresponse, err := http.Post(url, contentType, bytes.NewBufferString(body))\n\tif err != nil {\n\t\treturn token, err\n\t}\n\n\tif response.StatusCode == http.StatusOK {\n\t\tbody, err := io.ReadAll(response.Body)\n\t\tif err != nil {\n\t\t\treturn token, err\n\t\t}\n\n\t\terr = json.Unmarshal(body, &token)\n\t\tif err != nil {\n\t\t\treturn token, err\n\t\t}\n\t} else {\n\t\tvar errMsg string = fmt.Sprintf(\"%s: %v\", response.Status, response.Body)\n\t\treturn token, errors.New(errMsg)\n\t}\n\n\treturn token, nil\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\nfunc main() {\n\tspotifyToken, err := GetSpotifyToken()\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tvar bandNames map[string]string = map[string]string{\"first\": \"oasis\", \"second\": \"linkin park\"}\n\n\tfirstBand, err := SearchArtist(bandNames[\"first\"], spotifyToken.AccessToken)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tfirstBandData, err := GetArtistData(firstBand.ID, spotifyToken.AccessToken)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tfirstBandTopTracks, err := GetArtistTopTracks(firstBand.ID, spotifyToken.AccessToken)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tvar firstBandTopTrack Track = GetTopTrack(firstBandTopTracks.Tracks)\n\n\tsecondBand, err := SearchArtist(bandNames[\"second\"], spotifyToken.AccessToken)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tsecondBandData, err := GetArtistData(secondBand.ID, spotifyToken.AccessToken)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tsecondBandTopTracks, err := GetArtistTopTracks(secondBand.ID, spotifyToken.AccessToken)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tvar secondBandTopTrack Track = GetTopTrack(secondBandTopTracks.Tracks)\n\n\tvar pointsPerBand map[string]int = map[string]int{\"first\": 0, \"second\": 0}\n\n\tfmt.Printf(\"> Which band is more popular (%s, or %s)?\\n\", firstBandData.Name, secondBandData.Name)\n\n\tfmt.Println(\"\\n> Comparison of popularity...\")\n\tfmt.Printf(\"\\n> Popularity of %s: %d points of popularity.\\n\", firstBandData.Name, firstBandData.Popularity)\n\tfmt.Printf(\"> Popularity of %s: %d points of popularity.\\n\", secondBandData.Name, secondBandData.Popularity)\n\n\tif firstBandData.Popularity > secondBandData.Popularity {\n\t\tfmt.Printf(\"> %s has more popularity points than %s.\\n\", firstBandData.Name, secondBandData.Name)\n\t\tpointsPerBand[\"first\"]++\n\t} else if firstBandData.Popularity < secondBandData.Popularity {\n\t\tfmt.Printf(\"> %s has more popularity points than %s.\\n\", secondBandData.Name, firstBandData.Name)\n\t\tpointsPerBand[\"second\"]++\n\t} else {\n\t\tfmt.Printf(\"> %s has the same popularity points than %s.\\n\", firstBandData.Name, secondBandData.Name)\n\t}\n\n\tfmt.Println(\"\\n> Comparison of followers...\")\n\tfmt.Printf(\"\\n> Followers of %s: %d followers.\\n\", firstBandData.Name, firstBandData.Followers.Total)\n\tfmt.Printf(\"> Followers of %s: %d followers.\\n\", secondBandData.Name, secondBandData.Followers.Total)\n\n\tif firstBandData.Followers.Total > secondBandData.Followers.Total {\n\t\tfmt.Printf(\"> %s has more followers than %s.\\n\", firstBandData.Name, secondBandData.Name)\n\t\tpointsPerBand[\"first\"]++\n\t} else if firstBandData.Followers.Total < secondBandData.Followers.Total {\n\t\tfmt.Printf(\"> %s has more followers than %s.\\n\", secondBandData.Name, firstBandData.Name)\n\t\tpointsPerBand[\"second\"]++\n\t} else {\n\t\tfmt.Printf(\"> %s has the same number of followers than %s.\\n\", firstBandData.Name, secondBandData.Name)\n\t}\n\n\tfmt.Println(\"\\n> Comparison of top track of each band...\")\n\tfmt.Printf(\"\\n> Top track of %s (name, and popularity): %s (%d points of popularity).\\n\", firstBandData.Name, firstBandTopTrack.Name, firstBandTopTrack.Popularity)\n\tfmt.Printf(\"> Top track of %s (name, and popularity): %s (%d points of popularity).\\n\", secondBandData.Name, secondBandTopTrack.Name, secondBandTopTrack.Popularity)\n\n\tif firstBandTopTrack.Popularity > secondBandTopTrack.Popularity {\n\t\tfmt.Printf(\n\t\t\t\"> %s of %s band is more popular than %s of %s band.\\n\", firstBandTopTrack.Name, firstBandData.Name, secondBandTopTrack.Name, secondBandData.Name)\n\t\tpointsPerBand[\"first\"]++\n\t} else if firstBandTopTrack.Popularity < secondBandTopTrack.Popularity {\n\t\tfmt.Printf(\n\t\t\t\"> %s of %s band is more popular than %s of %s band.\\n\", secondBandTopTrack.Name, secondBandData.Name, firstBandTopTrack.Name, firstBandData.Name)\n\t\tpointsPerBand[\"second\"]++\n\t} else {\n\t\tfmt.Printf(\n\t\t\t\"> %s of %s band has the same popularity points than %s of %s band.\\n\", secondBandTopTrack.Name, secondBandData.Name, firstBandTopTrack.Name, firstBandData.Name)\n\t}\n\n\tfmt.Println(\"\\n> In conclusion...\")\n\n\tif pointsPerBand[\"first\"] > pointsPerBand[\"second\"] {\n\t\tfmt.Printf(\"\\n> %s band is more popular than %s band.\\n\", firstBandData.Name, secondBandData.Name)\n\t} else if pointsPerBand[\"first\"] < pointsPerBand[\"second\"] {\n\t\tfmt.Printf(\"\\n> %s band is more popular than %s band.\\n\", secondBandData.Name, firstBandData.Name)\n\t} else {\n\t\tfmt.Printf(\"\\n> %s band is as popular as %s band.\\n\", firstBandData.Name, secondBandData.Name)\n\t}\n}\n"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/java/AmadorQuispe.java",
    "content": "package com.amsoft.roadmap.example37;\n\nimport com.google.gson.JsonObject;\nimport com.google.gson.JsonParser;\n\nimport java.net.URI;\nimport java.net.URLEncoder;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\nimport java.nio.charset.StandardCharsets;\nimport java.util.Comparator;\nimport java.util.Objects;\n\nrecord Artist(String name,int followers,int popularity){}\nrecord Track(String name,int duration,int popularity){}\n\npublic class Example37 {\n    public static void main(String[] args) {\n\n        String token = getToken();\n        var idArtist1 = searchArtist(token, \"Oasis\");\n        var idArtist2 = searchArtist(token, \"The Beatles\");\n        Artist artist1 = getArtistData(token, idArtist1);\n        Artist artist2 = getArtistData(token, idArtist2);\n        Track topTrack1 = getTopTrack(token, idArtist1);\n        Track topTrack2 = getTopTrack(token, idArtist2);\n        if(artist1 == null || artist2 == null || topTrack1 == null || topTrack2 == null){\n            System.out.println(\"Error getting data\");\n            return;\n        }\n\n        String winnerPopularity = artist1.popularity() > artist2.popularity() ? artist1.name() : artist2.name();\n        String winnerFollowers = artist1.followers() > artist2.followers() ? artist1.name() : artist2.name();\n        String winnerTrack = topTrack1.popularity() > topTrack2.popularity() ? artist1.name() : artist2.name();\n\n        System.out.println(\"----------------------Results----------------------\");\n        System.out.println(\"Variable\\t | Artist1\\t | Artist2 \\t |winner\");\n        System.out.println(\"Name\\t\\t |\" + artist1.name() + \"\\t\\t |\" + artist2.name() + \"|\");\n        System.out.println(\"Followers\\t |\" + artist1.followers() + \"\\t |\" + artist2.followers() + \"\\t |\" + winnerPopularity);\n        System.out.println(\"Popularity\\t |\" + artist1.popularity() + \"\\t\\t |\" + artist2.popularity() + \"\\t\\t |\" + winnerFollowers);\n        System.out.println(\"Top Track\\t |\" + topTrack1.popularity() + \"\\t\\t |\" + topTrack2.popularity() + \"\\t\\t |\" + winnerTrack);\n    }\n\n    public static String getToken() {\n        HttpClient client = HttpClient.newHttpClient();\n        String grantType = \"client_credentials\";\n        String clientId = System.getenv(\"SPOTIFY_CLIENT_ID\");\n        String clientSecret = System.getenv(\"SPOTIFY_CLIENT_SECRET\");\n        HttpRequest request = HttpRequest.newBuilder()\n                .uri(URI.create(\"https://accounts.spotify.com/api/token\"))\n                .headers(\"Content-Type\", \"application/x-www-form-urlencoded\")\n                .method(\"POST\", HttpRequest.BodyPublishers.ofString(\"grant_type=\" + grantType + \"&client_id=\" + clientId + \"&client_secret=\" + clientSecret))\n                .build();\n        try {\n            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());\n            JsonObject json = JsonParser.parseString(response.body()).getAsJsonObject();\n\n\n            return json.get(\"access_token\").getAsString();\n        } catch (Exception e) {\n            e.printStackTrace(System.out);\n            return null;\n        }\n    }\n\n    public static String searchArtist(String token, String artist) {\n        String artistName = URLEncoder.encode(artist, StandardCharsets.UTF_8);\n        HttpClient client = HttpClient.newHttpClient();\n        HttpRequest request = HttpRequest.newBuilder()\n                .uri(URI.create(\"https://api.spotify.com/v1/search?q=\" + artistName + \"&type=artist&limit=1\"))\n                .headers(\"Authorization\", \"Bearer \" + token)\n                .build();\n        try {\n            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());\n            var itemsFound = JsonParser.parseString(response.body()).getAsJsonObject().get(\"artists\").getAsJsonObject().get(\"items\").getAsJsonArray();\n            if (itemsFound.size() <= 0){\n                throw new Exception(\"No artist found\");\n            }\n            return itemsFound.get(0).getAsJsonObject().get(\"id\").getAsString();\n        } catch (Exception e) {\n            e.printStackTrace(System.out);\n            return null;\n        }\n    }\n    public static Artist getArtistData(String token, String artistId) {\n        HttpClient client = HttpClient.newHttpClient();\n        HttpRequest request = HttpRequest.newBuilder()\n                .uri(URI.create(\"https://api.spotify.com/v1/artists/\" + artistId))\n                .headers(\"Authorization\", \"Bearer \" + token)\n                .build();\n        try {\n            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());\n            if(response.statusCode() != 200){\n                throw new Exception(\"Error getting artist data\");\n            }\n            JsonObject artist = JsonParser.parseString(response.body()).getAsJsonObject();\n            String name = artist.get(\"name\").getAsString();\n            int followers = artist.get(\"followers\").getAsJsonObject().get(\"total\").getAsInt();\n            int popularity = artist.get(\"popularity\").getAsInt();\n            return new Artist(name,followers,popularity);\n        } catch (Exception e) {\n            e.printStackTrace(System.out);\n            return null;\n        }\n    }\n\n    public static Track getTopTrack(String token, String artistId) {\n        HttpClient client = HttpClient.newHttpClient();\n        HttpRequest request = HttpRequest.newBuilder()\n                .uri(URI.create(\"https://api.spotify.com/v1/artists/\" + artistId + \"/top-tracks\"))\n                .headers(\"Authorization\", \"Bearer \" + token)\n                .build();\n        try {\n            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());\n            if(response.statusCode() != 200){\n                throw new Exception(\"Error getting top track\");\n            }\n            var tracks = JsonParser.parseString(response.body()).getAsJsonObject().get(\"tracks\").getAsJsonArray();\n            if (tracks.size() <= 0){\n                throw new Exception(\"No tracks found\");\n            }\n            //order by popularity\n            JsonObject topTrack = Objects.requireNonNull(tracks.asList().stream()\n                    .max(Comparator.comparingInt(a -> a.getAsJsonObject().get(\"popularity\").getAsInt()))\n                    .orElseThrow()).getAsJsonObject();\n            String name = topTrack.get(\"name\").getAsString();\n            int duration = topTrack.get(\"duration_ms\").getAsInt();\n            int popularity = topTrack.get(\"popularity\").getAsInt();\n            return new Track(name,duration,popularity);\n        } catch (Exception e) {\n            e.printStackTrace(System.out);\n            return null;\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/java/Josegs95.java",
    "content": "import com.google.gson.JsonElement;\nimport com.google.gson.JsonObject;\nimport com.google.gson.JsonParser;\n\nimport java.io.IOException;\nimport java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\nimport java.nio.charset.StandardCharsets;\nimport java.util.Base64;\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class Josegs95 {\n    public static void main(String[] args) {\n        new Josegs95().mostPopularBand();\n    }\n\n    final private String CLIENT_ID = \"3e3909179f7041ebbf1d487900a18465\";\n    final private String CLIENT_SECRET = \"5f1cbde87539487ea47baccc13aca4db\";\n    private String accessToken;\n\n    public void mostPopularBand() {\n        accessToken = getAccessToken();\n        String idArtist1 = getArtistID(\"Oasis\");\n        String idArtist2 = getArtistID(\"Linkin Park\");\n\n        Map<String, String> artist1Data = getArtistData(idArtist1);\n        Map<String, String> artist2Data = getArtistData(idArtist2);\n\n        if (artist1Data == null || artist2Data == null){\n            return;\n        }\n\n        String artist1Name = artist1Data.get(\"name\");\n        String artist2Name = artist2Data.get(\"name\");\n        Integer artist1Popularity = Integer.valueOf(artist1Data.get(\"popularity\"));\n        Integer artist2Popularity = Integer.valueOf(artist2Data.get(\"popularity\"));\n\n        System.out.println(\"Comparativa: \" + artist1Data.get(\"name\") + \" vs \" + artist2Data.get(\"name\"));\n\n        System.out.println(\"\\nSeguidores\");\n        System.out.println(artist1Name + \": \" + String.format(\"%,d\", Long.valueOf(artist1Data.get(\"followers\"))));\n        System.out.println(artist2Name + \": \" + String.format(\"%,d\", Long.valueOf(artist2Data.get(\"followers\"))));\n\n        System.out.println(\"\\nPopularidad (cuanto mas alto, mas popular)\");\n        System.out.println(artist1Name + \": \" + artist1Popularity);\n        System.out.println(artist2Name + \": \" + artist2Popularity);\n\n        System.out.println(\"\\nCanción mas popular\");\n        System.out.println(artist1Data.get(\"most_popular_track_name\") + \" (\" + artist1Name + \"): \"\n                + artist1Data.get(\"most_popular_track_popularity\") + \" de popularidad\");\n        System.out.println(artist2Data.get(\"most_popular_track_name\") + \" (\" + artist2Name + \"): \"\n                + artist2Data.get(\"most_popular_track_popularity\") + \" de popularidad\");\n\n        System.out.println();\n        if (artist1Popularity > artist2Popularity){\n            System.out.println(artist1Name + \" es mas popular que \" + artist2Name);\n        } else if (artist2Popularity > artist1Popularity) {\n            System.out.println(artist2Name + \" es mas popular que \" + artist1Name);\n        } else\n            System.out.println(artist1Name + \" y \" + artist2Name + \" son igual de populares\");\n\n    }\n\n    private String getAccessToken() {\n        String url = \"https://accounts.spotify.com/api/token\";\n        String clientCredentials = CLIENT_ID + \":\" + CLIENT_SECRET;\n        String encodedCredentials = Base64.getEncoder().encodeToString(clientCredentials.getBytes(StandardCharsets.UTF_8));\n\n        HttpClient client = HttpClient.newHttpClient();\n        HttpRequest request = HttpRequest.newBuilder(URI.create(url))\n                .header(\"Authorization\", \"Basic \" + encodedCredentials)\n                .header(\"Content-Type\", \"application/x-www-form-urlencoded\")\n                .POST(HttpRequest.BodyPublishers.ofString(\"grant_type=client_credentials\"))\n                .build();\n\n        String accessToken;\n        try {\n            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());\n            if (response.statusCode() != 200) {\n                System.out.println(\"Error al intentar obtener el token de autentificación\");\n                System.out.println(\"Respuesta: \" + response.body());\n                return null;\n            }\n\n            JsonObject data = JsonParser.parseString(response.body()).getAsJsonObject();\n            accessToken = data.get(\"access_token\").getAsString();\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        } catch (InterruptedException e) {\n            throw new RuntimeException(e);\n        }\n\n        return accessToken;\n    }\n\n    private String getArtistID(String artist) {\n        String url = \"https://api.spotify.com/v1/search?\";\n        url += \"q=\" + artist.replace(\" \", \"+\");\n        url += \"&type=artist\";\n        url += \"&limit=1\";\n\n        JsonObject data = getDataFromURL(url);\n        String artistID = data.get(\"artists\").getAsJsonObject()\n                .get(\"items\").getAsJsonArray()\n                .get(0).getAsJsonObject()\n                .get(\"id\").getAsString();\n\n        return artistID;\n    }\n\n    private Map<String, String> getArtistData(String artistID) {\n        Map<String, String> artistData = new HashMap<>();\n\n        String url = \"https://api.spotify.com/v1/artists/\";\n        url += artistID;\n\n        JsonObject data = getDataFromURL(url);\n        if (data == null){\n            System.out.println(\"Error al intentar obtener los datos del artista con ID: \" + artistID);\n            return null;\n        }\n\n        artistData.put(\"name\", data.get(\"name\").getAsString());\n        artistData.put(\"popularity\", data.get(\"popularity\").getAsString());\n        artistData.put(\"followers\", data.get(\"followers\").getAsJsonObject()\n                .get(\"total\").getAsString());\n\n        JsonObject mostPopularTrackData = getMostPopularTrackFromArtist(artistID);\n        if (mostPopularTrackData == null){\n            System.out.println(\"Error al intentar obtener la canción mas popular del artista con ID: \" + artistID);\n            return null;\n        }\n\n        artistData.put(\"most_popular_track_name\", mostPopularTrackData.get(\"name\").getAsString());\n        artistData.put(\"most_popular_track_popularity\", mostPopularTrackData.get(\"popularity\").getAsString());\n\n        return artistData;\n    }\n\n    private JsonObject getMostPopularTrackFromArtist(String artistID){\n        String url = \"https://api.spotify.com/v1/artists/\" + artistID + \"/top-tracks\";\n        JsonObject topTracksData = getDataFromURL(url);\n        if (topTracksData == null)\n            return null;\n\n        JsonObject mostPopularTrackData = null;\n        Integer mostPopularTrackPopularity = 0;\n        for (JsonElement trackData : topTracksData.get(\"tracks\").getAsJsonArray()){\n            String trackPopularity = trackData.getAsJsonObject()\n                    .get(\"popularity\").getAsString();\n            if (mostPopularTrackData == null || Integer.valueOf(trackPopularity) > mostPopularTrackPopularity){\n                mostPopularTrackData = trackData.getAsJsonObject();\n                mostPopularTrackPopularity = Integer.valueOf(mostPopularTrackData.get(\"popularity\").getAsString());\n            }\n        }\n\n        return mostPopularTrackData;\n    }\n\n    private JsonObject getDataFromURL(String url){\n        HttpClient client = HttpClient.newHttpClient();\n        HttpRequest request = HttpRequest.newBuilder(URI.create(url))\n                .header(\"Authorization\", \"Bearer \" + accessToken)\n                .GET()\n                .build();\n\n        try {\n            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());\n            if (response.statusCode() != 200) {\n                System.out.println(\"Ha ocurrido un error: \" + response.statusCode());\n                System.out.println(\"Url: \" + url);\n                System.out.println(\"Respuesta: \" + response.body());\n                return null;\n            }\n\n            return JsonParser.parseString(response.body()).getAsJsonObject();\n\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        } catch (InterruptedException e) {\n            throw new RuntimeException(e);\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/java/MohamedElderkaoui.java",
    "content": "import org.apache.http.client.methods.CloseableHttpResponse;\nimport org.apache.http.client.methods.HttpPost;\nimport org.apache.http.client.methods.HttpGet;\nimport org.apache.http.impl.client.CloseableHttpClient;\nimport org.apache.http.impl.client.HttpClients;\nimport org.apache.http.entity.StringEntity;\nimport org.apache.http.util.EntityUtils;\nimport org.apache.http.impl.client.HttpClientBuilder;\nimport org.json.JSONObject;\n\nimport java.io.IOException;\nimport java.nio.charset.StandardCharsets;\nimport java.util.Base64;\npublic class MohamedElderkaoui {\n\n private static final String CLIENT_ID = System.getenv(\"SPOTIFY_CLIENT_ID\");\nprivate static final String CLIENT_SECRET = System.getenv(\"SPOTIFY_CLIENT_SECRET\");\n    private static final String TOKEN_URL = \"https://accounts.spotify.com/api/token\";\n    private static final String ARTIST_OASIS_ID = \"2DaxqgrOhkeH0fpeiQq2f4\"; // ID de Spotify para Oasis\n    private static final String ARTIST_LP_ID = \"6XyY86QOPPrYVGvF9ch6wz\"; // ID de Spotify para Linkin Park\n    \n    public static void main(String[] args) throws IOException {\n        String accessToken = getSpotifyAccessToken();\n        \n        JSONObject oasisData = getArtistData(accessToken, ARTIST_OASIS_ID);\n        JSONObject lpData = getArtistData(accessToken, ARTIST_LP_ID);\n        \n        compareBands(oasisData, lpData);\n    }\n    \n    private static String getSpotifyAccessToken() throws IOException {\n        CloseableHttpClient httpClient = HttpClients.createDefault();\n        HttpPost post = new HttpPost(TOKEN_URL);\n\n        String auth = CLIENT_ID + \":\" + CLIENT_SECRET;\n        String encodedAuth = Base64.getEncoder().encodeToString(auth.getBytes(StandardCharsets.UTF_8));\n\n        post.setHeader(\"Authorization\", \"Basic \" + encodedAuth);\n        post.setHeader(\"Content-Type\", \"application/x-www-form-urlencoded\");\n        post.setEntity(new StringEntity(\"grant_type=client_credentials\"));\n\n        CloseableHttpResponse response = httpClient.execute(post);\n        String jsonResponse = EntityUtils.toString(response.getEntity());\n        JSONObject jsonObject = new JSONObject(jsonResponse);\n\n        return jsonObject.getString(\"access_token\");\n    }\n\n    private static JSONObject getArtistData(String accessToken, String artistId) throws IOException {\n        CloseableHttpClient httpClient = HttpClients.createDefault();\n        String url = \"https://api.spotify.com/v1/artists/\" + artistId;\n\n        HttpGet get = new HttpGet(url);\n        get.setHeader(\"Authorization\", \"Bearer \" + accessToken);\n\n        CloseableHttpResponse response = httpClient.execute(get);\n        String jsonResponse = EntityUtils.toString(response.getEntity());\n        return new JSONObject(jsonResponse);\n    }\n\n    private static void compareBands(JSONObject oasisData, JSONObject lpData) {\n        System.out.println(\"Comparación entre Oasis y Linkin Park:\");\n\n        int oasisFollowers = oasisData.getJSONObject(\"followers\").getInt(\"total\");\n        int lpFollowers = lpData.getJSONObject(\"followers\").getInt(\"total\");\n\n        int oasisPopularity = oasisData.getInt(\"popularity\");\n        int lpPopularity = lpData.getInt(\"popularity\");\n\n        System.out.println(\"Oasis - Seguidores: \" + oasisFollowers);\n        System.out.println(\"Linkin Park - Seguidores: \" + lpFollowers);\n\n        System.out.println(\"Oasis - Popularidad: \" + oasisPopularity);\n        System.out.println(\"Linkin Park - Popularidad: \" + lpPopularity);\n\n        if (oasisFollowers > lpFollowers) {\n            System.out.println(\"Oasis tiene más seguidores que Linkin Park.\");\n        } else {\n            System.out.println(\"Linkin Park tiene más seguidores que Oasis.\");\n        }\n\n        if (oasisPopularity > lpPopularity) {\n            System.out.println(\"Oasis es más popular según la popularidad en Spotify.\");\n        } else {\n            System.out.println(\"Linkin Park es más popular según la popularidad en Spotify.\");\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/java/asjordi.java",
    "content": "import org.apache.hc.core5.http.ParseException;\nimport se.michaelthelin.spotify.SpotifyApi;\nimport se.michaelthelin.spotify.exceptions.SpotifyWebApiException;\nimport se.michaelthelin.spotify.model_objects.credentials.ClientCredentials;\nimport se.michaelthelin.spotify.model_objects.specification.Artist;\nimport se.michaelthelin.spotify.requests.authorization.client_credentials.ClientCredentialsRequest;\nimport se.michaelthelin.spotify.requests.data.artists.GetArtistRequest;\n\nimport java.io.IOException;\nimport java.util.Arrays;\n\npublic class Main {\n\n    private final String clientId = System.getenv(\"SPOTIFY_CLIENT_ID\");\n    private final String clientSecret = System.getenv(\"SPOTIFY_CLIENT_SECRET\");\n    private String clientToken;\n    private SpotifyApi spotifyApi = new SpotifyApi.Builder()\n            .setClientId(clientId)\n            .setClientSecret(clientSecret)\n            .build();\n    private final ClientCredentialsRequest clientCredentialsRequest = spotifyApi.clientCredentials()\n            .build();\n\n    public static void main(String[] args) {\n        Main m = new Main();\n        m.getClientToken();\n        ArtistInfo oasis = m.getArtistInfo(\"2DaxqgrOhkeH0fpeiQq2f4\");\n        ArtistInfo lp = m.getArtistInfo(\"6XyY86QOPPrYVGvF9ch6wz\");\n\n        System.out.println(oasis);\n        System.out.println(lp);\n\n        System.out.println(\"Who is more popular?\");\n        System.out.println(oasis.popularity() > lp.popularity() ? \"Oasis\" : \"Linkin Park\");\n    }\n\n    public ArtistInfo getArtistInfo(String id) {\n        GetArtistRequest getArtistRequest = spotifyApi.getArtist(id).build();\n        try {\n            Artist artist = getArtistRequest.execute();\n            return new ArtistInfo(artist.getName(), artist.getPopularity(), artist.getFollowers().getTotal(), artist.getGenres());\n        } catch (IOException | SpotifyWebApiException | ParseException e) {\n            System.out.println(\"Error: \" + e.getMessage());\n        }\n        return null;\n    }\n\n    private void getClientToken() {\n        try {\n            final ClientCredentials clientCredentials = clientCredentialsRequest.execute();\n            this.clientToken = clientCredentials.getAccessToken();\n            spotifyApi.setAccessToken(clientCredentials.getAccessToken());\n        } catch (IOException | SpotifyWebApiException | ParseException e) {\n            System.out.println(\"Error: \" + e.getMessage());\n        }\n    }\n\n    record ArtistInfo(String name, int popularity, int followers, String[] genres) {\n        @Override\n        public String toString() {\n            return \"ArtistInfo{\" +\n                    \"name='\" + name + '\\'' +\n                    \", popularity=\" + popularity +\n                    \", followers=\" + followers +\n                    \", genres=\" + Arrays.toString(genres) +\n                    '}';\n        }\n    }\n\n}\n\n// https://github.com/spotify-web-api-java/spotify-web-api-java\n"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/java/mantaras96.java",
    "content": "package org.example;\n\nimport org.apache.http.client.methods.CloseableHttpResponse;\nimport org.apache.http.client.methods.HttpGet;\nimport org.apache.http.client.methods.HttpPost;\nimport org.apache.http.client.utils.URIBuilder;\nimport org.apache.http.impl.client.CloseableHttpClient;\nimport org.apache.http.impl.client.HttpClients;\nimport org.apache.http.util.EntityUtils;\nimport org.apache.http.entity.StringEntity;\nimport org.json.JSONObject;\n\nimport java.io.IOException;\nimport java.net.URISyntaxException;\nimport java.nio.charset.StandardCharsets;\nimport java.util.Base64;\n\npublic class Main {\n\n    private static final String CLIENT_ID = \"\";\n    private static final String CLIENT_SECRET = \"\";\n    private static final String TOKEN_URL = \"https://accounts.spotify.com/api/token\";\n    private static final String SEARCH_URL = \"https://api.spotify.com/v1/search\";\n    private static final String ARTIST_URL = \"https://api.spotify.com/v1/artists\";\n\n    private static final String ARTIST_NAME_1 = \"Oasis\";\n    private static final String ARTIST_NAME_2 = \"Linkin Park\";\n\n    private static String getSpotifyAccessToken() throws IOException {\n        CloseableHttpClient httpClient = HttpClients.createDefault();\n        HttpPost post = new HttpPost(TOKEN_URL);\n\n        // Encode credentials\n        String auth = CLIENT_ID + \":\" + CLIENT_SECRET;\n        String encodedAuth = Base64.getEncoder().encodeToString(auth.getBytes(StandardCharsets.UTF_8));\n\n        // Set headers\n        post.setHeader(\"Authorization\", \"Basic \" + encodedAuth);\n        post.setHeader(\"Content-Type\", \"application/x-www-form-urlencoded\");\n\n        // Set entity\n        StringEntity entity = new StringEntity(\"grant_type=client_credentials\");\n        post.setEntity(entity);\n\n        // Execute request\n        try (CloseableHttpResponse response = httpClient.execute(post)) {\n            String jsonResponse = EntityUtils.toString(response.getEntity());\n            JSONObject jsonObject = new JSONObject(jsonResponse);\n            return jsonObject.getString(\"access_token\");\n        } finally {\n            httpClient.close();\n        }\n    }\n\n    private static String getArtistId(String accessToken, String artistName) throws IOException, URISyntaxException {\n        CloseableHttpClient httpClient = HttpClients.createDefault();\n\n        // Build URL with encoded artist name\n        URIBuilder uriBuilder = new URIBuilder(SEARCH_URL);\n        uriBuilder.addParameter(\"q\", artistName);\n        uriBuilder.addParameter(\"type\", \"artist\");\n        String requestUrl = uriBuilder.toString();\n\n        HttpGet get = new HttpGet(requestUrl);\n\n        // Set headers\n        get.setHeader(\"Authorization\", \"Bearer \" + accessToken);\n\n        // Execute request\n        try (CloseableHttpResponse response = httpClient.execute(get)) {\n            String jsonResponse = EntityUtils.toString(response.getEntity());\n            JSONObject jsonObject = new JSONObject(jsonResponse);\n            // Get the artist ID from the first result\n            JSONObject artist = jsonObject.getJSONObject(\"artists\").getJSONArray(\"items\").getJSONObject(0);\n            return artist.getString(\"id\");\n        } finally {\n            httpClient.close();\n        }\n    }\n\n    private static JSONObject getArtistInformation(String accessToken, String artistId) throws IOException, URISyntaxException {\n        CloseableHttpClient httpClient = HttpClients.createDefault();\n\n        // Build URL with encoded artist name\n        URIBuilder uriBuilder = new URIBuilder(ARTIST_URL + \"/\" + artistId);\n        String requestUrl = uriBuilder.toString();\n\n        HttpGet get = new HttpGet(requestUrl);\n\n        // Set headers\n        get.setHeader(\"Authorization\", \"Bearer \" + accessToken);\n\n        // Execute request\n        try (CloseableHttpResponse response = httpClient.execute(get)) {\n            String jsonResponse = EntityUtils.toString(response.getEntity());\n            JSONObject jsonObject = new JSONObject(jsonResponse);\n            System.out.println(jsonObject);\n            //Integer popularity = jsonObject.getInt(\"popularity\");\n            //System.out.println(\"Popularity:\" + jsonObject.getJSONObject(\"followers\").getInt(\"total\"));\n            return jsonObject;\n        } finally {\n            httpClient.close();\n        }\n    }\n\n\n    public static void main(String[] args) throws Exception {\n        try {\n            String accessToken = getSpotifyAccessToken();\n\n            System.out.println(\"Access Token: \" + accessToken);\n            String artistID = getArtistId(accessToken, ARTIST_NAME_1);\n            String artistID2 = getArtistId(accessToken, ARTIST_NAME_2);\n\n\n            JSONObject jsonObjectArtist1 = getArtistInformation(accessToken, artistID);\n            JSONObject jsonObjectArtist2 = getArtistInformation(accessToken, artistID2);\n\n            if (jsonObjectArtist1.getInt(\"popularity\") > jsonObjectArtist2.getInt(\"popularity\")){\n                System.out.println(\"El grupo mas popular es \" + ARTIST_NAME_1);\n            } else {\n                System.out.println(\"El grupo mas popular es \" + ARTIST_NAME_2);\n            }\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/java/martinbohorquez.java",
    "content": "import com.google.gson.JsonArray;\nimport com.google.gson.JsonObject;\nimport com.google.gson.JsonParser;\n\nimport java.io.IOException;\nimport java.net.URI;\nimport java.net.URLEncoder;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\nimport java.nio.charset.StandardCharsets;\nimport java.util.Base64;\nimport java.util.Comparator;\nimport java.util.Map;\n\nimport static java.net.http.HttpClient.newHttpClient;\n\n/**\n * #37 OASIS VS LINKIN PARK\n * <dependency>\n * <groupId>com.google.code.gson</groupId>\n * <artifactId>gson</artifactId>\n * <version>2.10.1</version>\n * </dependency>\n *\n * @author martinbohorquez\n */\n\npublic class SpotifyTest {\n    private static final String CLIENT_ID = System.getenv(\"CLIENT_ID\");\n    private static final String CLIENT_SECRET = System.getenv(\"CLIENT_SECRET\");\n    private static final String TOKEN_URL = \"https://accounts.spotify.com/api/token\";\n\n    public static void main(String[] args) throws Exception {\n        int artistCounter1 = 0;\n        int artistCounter2 = 0;\n\n        // 1. Token\n        String token = getToken();\n\n        // 2. IDs\n        String artistId1 = searchArtist(token, \"Linkin Park\");\n        String artistId2 = searchArtist(token, \"Green Day\");\n\n        // 3. Data\n        Map<String, String> artistData1 = getArtistData(token, artistId1);\n        Map<String, String> artistData2 = getArtistData(token, artistId2);\n        System.out.println(artistData1);\n        System.out.println(artistData2);\n        // 3.1. Seguidores\n        System.out.println(\"Banda con más seguidores:\");\n        if (Integer.parseInt(artistData1.get(\"followers\")) > Integer.parseInt(artistData2.get(\"followers\"))) {\n            System.out.printf(\"%s es más popular en número de seguidores!%n\", artistData1.get(\"name\"));\n            artistCounter1++;\n        } else {\n            System.out.printf(\"%s es más popular en número de seguidores!%n\", artistData2.get(\"name\"));\n            artistCounter2++;\n        }\n        // 3.2. Popularidad\n        System.out.println(\"Banda con más popularidad:\");\n        if (Integer.parseInt(artistData1.get(\"popularity\")) > Integer.parseInt(artistData2.get(\"popularity\"))) {\n            System.out.printf(\"%s es más popular a nivel general!%n\", artistData1.get(\"name\"));\n            artistCounter1++;\n        } else {\n            System.out.printf(\"%s es más popular a nivel general!%n\", artistData2.get(\"name\"));\n            artistCounter2++;\n        }\n\n        // 4. Canción más popular\n        Map<String, String> artistTopTrack1 = getArtistTopTrack(token, artistId1);\n        Map<String, String> artistTopTrack2 = getArtistTopTrack(token, artistId2);\n        System.out.printf(\"%s: %s%n\", artistData1.get(\"name\"), artistTopTrack1);\n        System.out.printf(\"%s: %s%n\", artistData2.get(\"name\"), artistTopTrack2);\n\n        System.out.println(\"Canción con más popularidad:\");\n        if (Integer.parseInt(artistTopTrack1.get(\"popularity\")) > Integer.parseInt(artistTopTrack2.get(\"popularity\"))) {\n            System.out.printf(\"La canción %s de %s es más popular!%n\", artistTopTrack1.get(\"name\"), artistData1.get(\"name\"));\n            artistCounter1++;\n        } else {\n            System.out.printf(\"La canción %s de %s es más popular!%n\", artistTopTrack2.get(\"name\"), artistData2.get(\"name\"));\n            artistCounter2++;\n        }\n\n        // 5. Resultados\n        System.out.println(\"Resultado final:\");\n        System.out.printf(\"%s es más popular!\", artistCounter1 > artistCounter2 ? artistData1.get(\"name\") : artistData2.get(\"name\"));\n\n    }\n\n    private static String getToken() {\n        String auth = CLIENT_ID + \":\" + CLIENT_SECRET;\n        String encodedAuth = Base64.getEncoder().encodeToString(auth.getBytes(StandardCharsets.UTF_8));\n        JsonObject jsonObject = responseJsonPost(TOKEN_URL, encodedAuth);\n        return jsonObject.get(\"access_token\").getAsString();\n    }\n\n    private static String searchArtist(String token, String artist) throws Exception {\n        String encodedArtist = URLEncoder.encode(artist, StandardCharsets.UTF_8);\n        String url = \"https://api.spotify.com/v1/search?q=\" + encodedArtist + \"&type=artist&limit=1\";\n        JsonObject responseJson = responseJsonGet(token, url);\n\n        JsonArray artistsList = responseJson.getAsJsonObject(\"artists\").getAsJsonArray(\"items\");\n        if (artistsList.isEmpty()) {\n            throw new Exception(\"El artista\" + artist + \"no se ha encontrado!\");\n        }\n        return artistsList.get(0).getAsJsonObject()\n                .get(\"id\").getAsString();\n    }\n\n    private static Map<String, String> getArtistData(String token, String id) {\n        String url = \"https://api.spotify.com/v1/artists/\" + id;\n        JsonObject responseJson = responseJsonGet(token, url);\n\n        return Map.of(\"name\", responseJson.get(\"name\").getAsString(),\n                \"followers\", responseJson.getAsJsonObject(\"followers\").get(\"total\").getAsString(),\n                \"popularity\", responseJson.get(\"popularity\").getAsString());\n    }\n\n    private static Map<String, String> getArtistTopTrack(String token, String id) {\n        String url = \"https://api.spotify.com/v1/artists/\" + id + \"/top-tracks\";\n        JsonObject responseJson = responseJsonGet(token, url);\n\n        JsonObject topTrack = responseJson.getAsJsonArray(\"tracks\").asList().stream()\n                .max(Comparator.comparing(t -> t.getAsJsonObject().get(\"popularity\").getAsInt()))\n                .orElseThrow().getAsJsonObject();\n\n        return Map.of(\"name\", topTrack.get(\"name\").getAsString(),\n                \"popularity\", topTrack.get(\"popularity\").getAsString());\n    }\n\n    private static JsonObject responseJsonGet(String token, String url) {\n        HttpRequest request = HttpRequest.newBuilder()\n                .uri(URI.create(url))\n                .header(\"Authorization\", \"Bearer \" + token) // Authorization header if needed\n                .build();\n        HttpResponse<String> response;\n\n        try (HttpClient client = newHttpClient()) {\n            response = client.send(request, HttpResponse.BodyHandlers.ofString());\n        } catch (IOException | InterruptedException e) {\n            throw new RuntimeException(e);\n        }\n\n        String responseBody = response.body();\n        return JsonParser.parseString(responseBody).getAsJsonObject();\n    }\n\n    private static JsonObject responseJsonPost(String url, String encodedAuth) {\n        HttpRequest request = HttpRequest.newBuilder()\n                .uri(URI.create(url))\n                .header(\"Content-Type\", \"application/x-www-form-urlencoded\") // Add headers\n                .header(\"Authorization\", \"Basic \" + encodedAuth) // Authorization header if needed\n                .POST(HttpRequest.BodyPublishers.ofString(\"grant_type=client_credentials\"))\n                .build();\n        HttpResponse<String> response;\n\n        try (HttpClient client = newHttpClient()) {\n            response = client.send(request, HttpResponse.BodyHandlers.ofString());\n        } catch (IOException | InterruptedException e) {\n            throw new RuntimeException(e);\n        }\n        String responseBody = response.body();\n\n        return JsonParser.parseString(responseBody).getAsJsonObject();\n    }\n}\n"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/java/miguelex.java",
    "content": "import java.io.BufferedReader;\nimport java.io.InputStreamReader;\nimport java.net.HttpURLConnection;\nimport java.net.URL;\nimport java.util.Base64;\nimport java.util.Scanner;\nimport org.json.JSONArray;\nimport org.json.JSONObject;\n\npublic class SpotifyComparison {\n\n    private static final String CLIENT_ID = \"YOUR_CLIENT_ID\";\n    private static final String CLIENT_SECRET = \"YOUR_CLIENT_SECRET\";\n\n    public static void main(String[] args) throws Exception {\n        Scanner scanner = new Scanner(System.in);\n\n        System.out.print(\"Introduce el nombre del primer grupo: \");\n        String band1 = scanner.nextLine();\n        System.out.print(\"Introduce el nombre del segundo grupo: \");\n        String band2 = scanner.nextLine();\n\n        String token = getAccessToken();\n\n        JSONObject band1Data = getArtistData(token, band1);\n        JSONObject band2Data = getArtistData(token, band2);\n\n        JSONObject band1Stats = getArtistStats(band1Data.getString(\"id\"), token);\n        JSONObject band2Stats = getArtistStats(band2Data.getString(\"id\"), token);\n\n        JSONObject band1TopTrack = getArtistTopTrack(band1Data.getString(\"id\"), token);\n        JSONObject band2TopTrack = getArtistTopTrack(band2Data.getString(\"id\"), token);\n\n        System.out.println(\"\\n\" + band1 + \" Stats: \" + band1Stats);\n        System.out.println(\"Canción más popular de \" + band1 + \": \" + band1TopTrack);\n\n        System.out.println(\"\\n\" + band2 + \" Stats: \" + band2Stats);\n        System.out.println(\"Canción más popular de \" + band2 + \": \" + band2TopTrack);\n\n        String moreFollowers = band1Stats.getInt(\"followers\") > band2Stats.getInt(\"followers\") ? band1 : band2;\n        String morePopularTrack = band1TopTrack.getInt(\"playCount\") > band2TopTrack.getInt(\"playCount\") ? band1 : band2;\n\n        System.out.println(\"\\nLa banda con más seguidores es: \" + moreFollowers);\n        System.out.println(\"La banda con la canción más popular es: \" + morePopularTrack);\n    }\n\n    private static String getAccessToken() throws Exception {\n        String auth = CLIENT_ID + \":\" + CLIENT_SECRET;\n        String encodedAuth = Base64.getEncoder().encodeToString(auth.getBytes());\n\n        URL url = new URL(\"https://accounts.spotify.com/api/token\");\n        HttpURLConnection conn = (HttpURLConnection) url.openConnection();\n        conn.setRequestMethod(\"POST\");\n        conn.setRequestProperty(\"Authorization\", \"Basic \" + encodedAuth);\n        conn.setRequestProperty(\"Content-Type\", \"application/x-www-form-urlencoded\");\n        conn.setDoOutput(true);\n\n        String data = \"grant_type=client_credentials\";\n        conn.getOutputStream().write(data.getBytes());\n\n        BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));\n        String inputLine;\n        StringBuilder response = new StringBuilder();\n\n        while ((inputLine = in.readLine()) != null) {\n            response.append(inputLine);\n        }\n        in.close();\n\n        JSONObject json = new JSONObject(response.toString());\n        return json.getString(\"access_token\");\n    }\n\n    private static JSONObject getArtistData(String token, String artistName) throws Exception {\n        URL url = new URL(\"https://api.spotify.com/v1/search?q=\" + artistName + \"&type=artist\");\n        HttpURLConnection conn = (HttpURLConnection) url.openConnection();\n        conn.setRequestMethod(\"GET\");\n        conn.setRequestProperty(\"Authorization\", \"Bearer \" + token);\n\n        BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));\n        String inputLine;\n        StringBuilder response = new StringBuilder();\n\n        while ((inputLine = in.readLine()) != null) {\n            response.append(inputLine);\n        }\n        in.close();\n\n        JSONObject json = new JSONObject(response.toString());\n        JSONArray items = json.getJSONObject(\"artists\").getJSONArray(\"items\");\n        return items.getJSONObject(0);\n    }\n\n    private static JSONObject getArtistStats(String artistId, String token) throws Exception {\n        URL url = new URL(\"https://api.spotify.com/v1/artists/\" + artistId);\n        HttpURLConnection conn = (HttpURLConnection) url.openConnection();\n        conn.setRequestMethod(\"GET\");\n        conn.setRequestProperty(\"Authorization\", \"Bearer \" + token);\n\n        BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));\n        String inputLine;\n        StringBuilder response = new StringBuilder();\n\n        while ((inputLine = in.readLine()) != null) {\n            response.append(inputLine);\n        }\n        in.close();\n\n        return new JSONObject(response.toString());\n    }\n\n    private static JSONObject getArtistTopTrack(String artistId, String token) throws Exception {\n        URL url = new URL(\"https://api.spotify.com/v1/artists/\" + artistId + \"/top-tracks?market=US\");\n        HttpURLConnection conn = (HttpURLConnection) url.openConnection();\n        conn.setRequestMethod(\"GET\");\n        conn.setRequestProperty(\"Authorization\", \"Bearer \" + token);\n\n        BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));\n        String inputLine;\n        StringBuilder response = new StringBuilder();\n\n        while ((inputLine = in.readLine()) != null) {\n            response.append(inputLine);\n        }\n        in.close();\n\n        JSONObject json = new JSONObject(response.toString());\n        JSONArray tracks = json.getJSONArray(\"tracks\");\n        return tracks.getJSONObject(0);\n    }\n}\n"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #37 - JavaScript -> Jesus Antonio Escamilla */\n\n/**\n * OASIS VS LINKIN PARK.\n * Utilizando la Terminal para pedir datos y agregarlos.\n */\n\nconst clientId = SPOTIFY_CLIENT_ID_MY;\nconst clientSecret = SPOTIFY_CLIENT_SECRET_MY;\n// Para el contador\nlet artist_1_counter = 0;\nlet artist_2_counter = 0;\n\n// Obtener token de acceso\nasync function getAccessToken() {\n    const response = await fetch('https://accounts.spotify.com/api/token', {\n        method: 'POST',\n        headers: {\n            'Authorization': 'Basic ' + btoa(clientId + ':' + clientSecret),\n            'Content-Type': 'application/x-www-form-urlencoded'\n        },\n        body: 'grant_type=client_credentials'\n    });\n\n    if (response.status != 200) {\n        console.error(`Error obteniendo el token de Spotify: ${response.json()}`)\n    }\n    const data = await response.json();\n    return data.access_token;\n}\n\n// Obtener los Id de las bandas\nasync function getSearchArtist(artistName, accessToken) {\n    const response = await fetch(`https://api.spotify.com/v1/search?q=${artistName}&type=artist&limit=1`, {\n        headers: {\n            'Authorization': `Bearer ${accessToken}`\n        }\n    });\n\n    if (response.status != 200) {\n        console.error('Error obteniendo el artista')\n    }\n    const data = await response.json();\n    return data.artists.items[0].id;\n}\n\n// Obtener los Datos de las bandas\nasync function getArtistData(artistId, accessToken) {\n    const response = await fetch(`https://api.spotify.com/v1/artists/${artistId}`, {\n        method: 'GET',\n        headers: {\n            'Authorization': `Bearer ${accessToken}`\n        }\n    });\n\n    if (response.status != 200) {\n        console.error('Error obteniendo los datos del artista')\n    }\n    const data = await response.json();\n    return {\n        \"name\": data.name,\n        \"followers\": data.followers.total,\n        \"popularity\": data.popularity,\n    }\n}\n\n// Obtener la música mas sonada de las bandas\nasync function getArtistTopTrack(artistId, accessToken) {\n    const response = await fetch(`https://api.spotify.com/v1/artists/${artistId}/top-tracks`, {\n        method: 'GET',\n        headers: {\n            'Authorization': `Bearer ${accessToken}`\n        }\n    });\n\n    if (response.status != 200) {\n        console.error('Error obteniendo las canciones del artista')\n    }\n    const data = await response.json();\n    const result = data.tracks[0]\n    return {\n        \"name\": result.name,\n        \"popularity\": result.popularity,\n    }\n}\n\n// Comparar datos de Oasis y Linkin Park\nasync function compareBands() {\n    // Acceso al Token\n    const accessToken = await getAccessToken(clientId, clientSecret);\n    \n    // El Id de las bandas\n    const artist_1_id = await getSearchArtist('Oasis', accessToken);\n    const artist_2_id = await getSearchArtist('Linkin Park', accessToken);\n\n    const artist_1_data = await getArtistData(artist_1_id, accessToken);\n    const artist_2_data = await getArtistData(artist_2_id, accessToken);\n\n    const artist_1_topTrack = await getArtistTopTrack(artist_1_id, accessToken);\n    const artist_2_topTrack = await getArtistTopTrack(artist_2_id, accessToken);\n\n    console.group('Los artistas:');\n        console.group(artist_1_data.name);\n        console.log(`Seguidores es de ${artist_1_data.followers}`);\n        console.log(`Popularidad al mundo es ${artist_1_data.popularity}`);\n        console.log(`Canción mas popular es ${artist_1_topTrack.popularity}`);\n        console.groupEnd();\n\n        console.group(artist_2_data.name);\n        console.log(`Seguidores es de ${artist_2_data.followers}`);\n        console.log(`Popularidad al mundo es ${artist_2_data.popularity}`);\n        console.log(`Canción mas popular es ${artist_2_topTrack.popularity}`);\n        console.groupEnd();\n    console.groupEnd();\n\n    console.group('\\nComparación de los artistas:');\n        artist_1_data.followers > artist_2_data.followers ? (console.log(`${artist_1_data.name} es más popular en número de seguidores.`), artist_1_counter++) : (console.log(`${artist_2_data.name} es más popular en número de seguidores.`), artist_2_counter++);\n        artist_1_data.popularity > artist_2_data.popularity ? (console.log(`${artist_1_data.name} es más popular a nivel general.`), artist_1_counter++) : (console.log(`${artist_2_data.name}  es más popular a nivel general.`), artist_2_counter++);\n        artist_1_topTrack.popularity > artist_2_topTrack.popularity ? (console.log(`La canción ${artist_1_topTrack.name} de ${artist_1_data.name} es más popular.`), artist_1_counter++) : (console.log(`La canción ${artist_2_topTrack.name} de ${artist_2_data.name} es más popular.`), artist_2_counter++);\n    console.groupEnd();\n\n    console.log(`\\nGanador es ${artist_1_counter > artist_2_counter ? artist_1_data.name : artist_2_data.name}`)\n}\n\n// Uso del programa\ncompareBands();"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/javascript/Rafacv23.js",
    "content": "// Hecho por @Rafacv23 | https://github.com/Rafacv23 | https://twitter.com/rafacanosa | https://www.rafacanosa.dev\n\n// ID's generados por spotify, para ejecutar este código debes usar los tuyos propios, también sería interesante utilizar una extensión de archivo .mjs, para que funcione correctamente la asincronia\nconst CLIENT_ID = \"your-client-id\"\nconst CLIENT_SECRET = \"your-client-secret\"\n\n// función para obtener el token de acceso a la api de spotify\nasync function getSpotifyToken(clientId, clientSecret) {\n  const tokenResponse = await fetch(\"https://accounts.spotify.com/api/token\", {\n    method: \"POST\",\n    headers: {\n      \"Content-Type\": \"application/x-www-form-urlencoded\",\n    },\n    body: new URLSearchParams({\n      grant_type: \"client_credentials\",\n      client_id: clientId,\n      client_secret: clientSecret,\n    }),\n  })\n\n  if (tokenResponse.status !== 200) {\n    const error = await tokenResponse.json()\n    throw new Error(`Error: ${JSON.stringify(error)}`)\n  }\n\n  const token = await tokenResponse.json()\n  return token.access_token\n}\n\n// almacenamos el token de acceso a la api de spotify\nconst accessToken = await getSpotifyToken(CLIENT_ID, CLIENT_SECRET)\nconst authorization = { headers: { Authorization: `Bearer ${accessToken}` } }\n\n// función encargada de recuperar la información de un artista, pasandole su nombre\nasync function getArtistData(artist) {\n  const url = `https://api.spotify.com/v1/search?q=${encodeURIComponent(\n    artist\n  )}&type=artist&limit=1`\n\n  const res = await fetch(url, authorization)\n\n  if (res.status !== 200) {\n    const error = await res.json()\n    throw new Error(\n      `Error retrieving artist data ${artist}: ${JSON.stringify(error)}`\n    )\n  }\n\n  const results = await res.json()\n\n  if (!results.artists || results.artists.items.length === 0) {\n    throw new Error(`Artista ${artist} no ha sido encontrado.`)\n  }\n\n  const artistData = results.artists.items[0]\n\n  return {\n    id: artistData.id,\n    name: artistData.name,\n    followers: artistData.followers.total,\n    popularity: artistData.popularity,\n    genres: artistData.genres,\n  }\n}\n\n// almacenamos los datos de los artistas\nconst linkinPark = await getArtistData(\"Linkin Park\")\nconst oasis = await getArtistData(\"Oasis\")\n\n// comparamos la popularidad de los dos artistas\nconst morePopularBand =\n  linkinPark.popularity > oasis.popularity ? \"Linkin Park\" : \"Oasis\"\n\nconsole.log(\"Linkin Park Data:\", linkinPark)\nconsole.log(\"Oasis Data:\", oasis)\nconsole.log(`El más popular de los dos es ${morePopularBand}.`)\n\n/**Salida esperada por consola\n * Linkin Park Data: {\n  id: '6XyY86QOPPrYVGvF9ch6wz',\n  name: 'Linkin Park',\n  followers: 27123544,\n  popularity: 92,\n  genres: [\n    'alternative metal',\n    'nu metal',\n    'post-grunge',\n    'rap metal',\n    'rock'\n  ]\n}\nOasis Data: {\n  id: '2DaxqgrOhkeH0fpeiQq2f4',\n  name: 'Oasis',\n  followers: 10740804,\n  popularity: 83,\n  genres: [ 'beatlesque', 'britpop', 'madchester', 'permanent wave', 'rock' ]\n}\nEl más popular de los dos es Linkin Park.\n */\n"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/javascript/RaulDoezon.js",
    "content": "/*\n  EJERCICIO:\n  ¡Dos de las bandas más grandes de la historia están de vuelta!\n  Oasis y Linkin Park han anunciado nueva gira, pero, ¿quién es más popular?\n  Desarrolla un programa que se conecte al API de Spotify y los compare.\n  Requisitos:\n  1. Crea una cuenta de desarrollo en https://developer.spotify.com.\n  2. Conéctate al API utilizando tu lenguaje de programación.\n  3. Recupera datos de los endpoint que tú quieras.\n  Acciones:\n  1. Accede a las estadísticas de las dos bandas.\n     Por ejemplo: número total de seguidores, escuchas mensuales,\n     canción con más reproducciones...\n  2. Compara los resultados de, por lo menos, 3 endpoint.\n  3. Muestra todos los resultados por consola para notificar al usuario.\n  4. Desarrolla un criterio para seleccionar qué banda es más popular.\n*/\n\n// SPOTIFY DEVELOPER DOCUMENTATION: https://developer.spotify.com/documentation/web-api\nlet oasisData = {}\nlet linkinParkData = {};\nlet oasisPoints = 0;\nlet linkinParkPoints = 0;\nconst accessToken = 'BQAA3qx2W-B2a48L9gNndfSRf4uxIUUzUHQh9Z7VNMgPoO3bCK3v1jAACqbRHTU9mtu6_24NUgvg1P7FFFmZ0tr6mW_8YX30aMWRRh1Oc6X0-EMzFwo';\nconst oasisID = '2DaxqgrOhkeH0fpeiQq2f4';\nconst linkinParkID = '6XyY86QOPPrYVGvF9ch6wz';\n\nasync function fetchWebApi(endpoint, method, body) {\n  const response = await fetch(`https://api.spotify.com/${endpoint}`, {\n    headers: {\n      Authorization: `Bearer ${accessToken}`,\n    },\n    method,\n    body:JSON.stringify(body),\n  });\n\n  return await response.json();\n}\n\nconst getArtist = async (artistID) => await fetchWebApi(`v1/artists/${artistID}`, 'GET');\nconst getAlbums = async (artistID) => await fetchWebApi(`v1/artists/${artistID}/albums`, 'GET');\nconst getTopTracks = async (artistID) => await fetchWebApi(`v1/artists/${artistID}/top-tracks`, 'GET');\n\nconst oasisInformation = getArtist(oasisID);\nconst oasisAlbums = getAlbums(oasisID);\nconst oasisTopTracks = getTopTracks(oasisID);\nconst linkinParkInformation = getArtist(linkinParkID);\nconst linkinParkAlbums = getAlbums(linkinParkID);\nconst linkinParkTopTracks = getTopTracks(linkinParkID);\n\nconst artistInformation = ((artistArray, data) => {\n  artistArray.artist_name = data.name;\n  artistArray.total_followers = data.followers.total;\n  artistArray.popularity = data.popularity;\n});\n\nconst albumInformation = ((artistArray, data) => {\n  artistArray.recent_album = data.items[0].name;\n  artistArray.album_release_date = data.items[0].release_date;\n});\n\nconst topTracksInformation = ((artistArray, data) => {\n  artistArray.track_name = data.tracks[0].name;\n  artistArray.track_popularity = data.tracks[0].popularity;\n});\n\noasisInformation.then((response) => artistInformation(oasisData, response));\noasisAlbums.then((response) => albumInformation(oasisData, response));\noasisTopTracks.then((response) => topTracksInformation(oasisData, response));\nlinkinParkInformation.then((response) => artistInformation(linkinParkData, response));\nlinkinParkAlbums.then((response) => albumInformation(linkinParkData, response));\nlinkinParkTopTracks.then((response) => topTracksInformation(linkinParkData, response));\n\nconst showData = () => {\n  console.log(`${oasisData.artist_name} vs ${linkinParkData.artist_name}`);\n  console.log(`Popularity:\\n${oasisData.popularity} | ${linkinParkData.popularity}`);\n  console.log(`Followers:\\n${oasisData.total_followers} | ${linkinParkData.total_followers}`);\n  console.log(`Top Track:\\n${oasisData.track_name} | ${linkinParkData.track_name}`);\n  console.log(`Track popularity:\\n${oasisData.track_popularity} | ${linkinParkData.track_popularity}`);\n  console.log(`Recent album:\\n${oasisData.recent_album} | ${linkinParkData.recent_album}`);\n  console.log(`Release date:\\n${oasisData.album_release_date} | ${linkinParkData.album_release_date}`);\n\n  oasisData.popularity > linkinParkData.popularity ? oasisPoints += 1 : linkinParkPoints += 1;\n  oasisData.total_followers > linkinParkData.total_followers ? oasisPoints += 1 : linkinParkPoints += 1;\n  oasisData.track_popularity > linkinParkData.track_popularity ? oasisPoints += 1 : linkinParkPoints += 1;\n\n  console.log(`\\n¡${oasisPoints > linkinParkPoints ? oasisData.artist_name : linkinParkData.artist_name} es más popular!`);\n}\n\nasync function main() {\n  await Promise.all([oasisInformation, oasisAlbums, oasisTopTracks, linkinParkInformation, linkinParkAlbums, linkinParkTopTracks]);\n\n  showData();\n}\n\nmain();\n"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/javascript/RicJDev.js",
    "content": "/*\n  EJERCICIO:\n\n  @RicJDev\n*/\n\nimport { CLIENT_ID, CLIENT_SECRET } from './client.js'\n\n/*\nIMPORTANTE:\n\nEstoy importando mis id's del archivo client.js, el cual no está subido al repo.\nSi desea ejecutar este código deberá usar sus propias id's.\n*/\n\n// Creamos una función para obtener el token de acceso.\n\nasync function getToken(clientId, clientSecret) {\n  const token = await fetch('https://accounts.spotify.com/api/token', {\n    method: 'POST',\n    headers: {\n      'Content-Type': 'application/x-www-form-urlencoded',\n    },\n    body: new URLSearchParams({\n      grant_type: 'client_credentials',\n      client_id: clientId,\n      client_secret: clientSecret,\n    }),\n  }).then((response) => {\n    if (response.status !== 200) {\n      throw new Error(`Falla al obtener respuesta de la API. ${response.json()}`)\n    }\n\n    return response.json()\n  })\n\n  return token.access_token\n}\n\n// Nos almacenamos el método de autenticación que usaremos para las peticiones.\n\nconst accessToken = await getToken(CLIENT_ID, CLIENT_SECRET)\nconst authorization = { headers: { Authorization: `Bearer  ${accessToken}` } }\n\n// Creamos una función para aprovechar el sitema de búsqueda de la API.\n\nasync function getArtistId(artist) {\n  const url = `https://api.spotify.com/v1/search?q=${artist}&type=artist&limit=1`\n  const results = await fetch(url, authorization).then((response) => {\n    if (response.status !== 200) throw new Error(`Error al obtener el artista ${artist}.`)\n\n    return response.json()\n  })\n\n  if (!results.artists.items) throw new Error(`Artista ${artist} no ha sido encontrado.`)\n\n  return results.artists.items[0].id\n}\n\n// E iremos almacenando la información de nuestros artistas.\n\nconst artist1 = {\n  id: await getArtistId('Linkin Park'),\n}\n\nconst artist2 = {\n  id: await getArtistId('Oasis'),\n}\n\n// Creamos una función que nos retorne los datos del artista desde la API.\n\nasync function getArtistData(artistId) {\n  const url = `https://api.spotify.com/v1/artists/${artistId}`\n  const results = await fetch(url, authorization).then((response) => {\n    if (response.status !== 200) throw new Error(`Error al obtener datos del artista.`)\n\n    return response.json()\n  })\n\n  return {\n    name: results.name,\n    followers: results.followers.total,\n    popularity: results.popularity,\n  }\n}\n\nartist1.data = await getArtistData(artist1.id)\nartist2.data = await getArtistData(artist2.id)\n\n// Creamos otra función para obtener la canción más escuchada de la semana.\n\nasync function getArtistTopTrack(artistId) {\n  const url = `https://api.spotify.com/v1/artists/${artistId}/top-tracks?market=VE`\n  const results = await fetch(url, authorization).then((response) => {\n    if (response.status !== 200) throw new Error(`Error al obtener canción más popular.`)\n\n    return response.json()\n  })\n\n  return {\n    name: results.tracks[0].name,\n    popularity: results.tracks[0].popularity,\n    album: results.tracks[0].album.name,\n  }\n}\n\nartist1.topTrack = await getArtistTopTrack(artist1.id)\nartist2.topTrack = await getArtistTopTrack(artist2.id)\n\n// Aquí empezamos a comparar.\n\nconsole.log('COMPARANDO ARTISTAS.\\n')\n\nconsole.log(`- ${artist1.data.name}.`)\nconsole.log(`- ${artist2.data.name}.`)\n\nartist1.points = 0\nartist2.points = 0\n\n// Ronda 1: seguidores.\n\nconsole.log('\\n¿Quién tiene más seguidores?')\n\nconsole.log(`${artist1.data.name}:`, artist1.data.followers)\nconsole.log(`${artist2.data.name}:`, artist2.data.followers)\n\nif (artist1.data.followers > artist2.data.followers) {\n  console.log(`\\n¡Punto para ${artist1.data.name}!`)\n\n  artist1.points++\n} else {\n  console.log(`\\n¡Punto para ${artist2.data.name}!`)\n\n  artist2.points++\n}\n\n// Ronda 2: popularidad.\n\nconsole.log('\\n¿Quién tiene más popularidad a nivel general?')\n\nconsole.log(`${artist1.data.name}:`, artist1.data.popularity)\nconsole.log(`${artist2.data.name}:`, artist2.data.popularity)\n\nif (artist1.data.popularity > artist2.data.popularity) {\n  console.log(`\\n¡Punto para ${artist1.data.name}!`)\n\n  artist1.points++\n} else {\n  console.log(`\\n¡Punto para ${artist2.data.name}!`)\n\n  artist2.points++\n}\n\n// Ronda 3: canción más escuchada.\n\nconsole.log(\n  '\\nTenemos la canción más escuchada de cada artista. ¿Cuál tiene mayor popularidad general?'\n)\n\nconsole.log(`${artist1.data.name}: ${artist1.topTrack.name}:`, artist1.topTrack.popularity)\nconsole.log(`${artist2.data.name}: ${artist2.topTrack.name} :`, artist2.topTrack.popularity)\n\nif (artist1.topTrack.popularity > artist2.topTrack.popularity) {\n  console.log(`\\n¡Punto para ${artist1.data.name}!`)\n\n  artist1.points++\n} else {\n  console.log(`\\n¡Punto para ${artist2.data.name}!`)\n\n  artist2.points++\n}\n\nconsole.log('\\nRESULTADOS:')\n\nartist1.points > artist2.points\n  ? console.log(`Ha ganado ${artist1.data.name}:`, artist1.points)\n  : console.log(`Ha ganado ${artist2.data.name}:`, artist2.points)\n"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/javascript/adrs1166ma.js",
    "content": "/* 🔥 EJERCICIO:\n¡Dos de las bandas más grandes de la historia están de vuelta!\nOasis y Linkin Park han anunciado nueva gira, pero, ¿quién es más popular?\nDesarrolla un programa que se conecte al API de Spotify y los compare.\nRequisitos:\n1. Crea una cuenta de desarrollo en https://developer.spotify.com.\n2. Conéctate al API utilizando tu lenguaje de programación.\n3. Recupera datos de los endpoint que tú quieras.\nAcciones:\n1. Accede a las estadísticas de las dos bandas.\n   Por ejemplo: número total de seguidores, escuchas mensuales,\n   canción con más reproducciones...\n2. Compara los resultados de, por lo menos, 3 endpoint.\n3. Muestra todos los resultados por consola para notificar al usuario.\n4. Desarrolla un criterio para seleccionar qué banda es más popular.\n */\n// 🔥 SIMULADOR: Comparador de Popularidad entre Oasis y Linkin Park 🔥\n// Para ejecutar este programa, necesitarás Node.js y una cuenta en Spotify Developer.\n\nconst axios = require(\"axios\"); // npm install axios\n\n// Configuración del API de Spotify\nconst CLIENT_ID = \"TU_CLIENT_ID\"; // Reemplaza con tu Client ID de Spotify\nconst CLIENT_SECRET = \"TU_CLIENT_SECRET\"; // Reemplaza con tu Client Secret de Spotify\nlet accessToken = null;\n\n// Función principal del programa\nasync function compararBandas() {\n    console.log(\"🎸 ¡Bienvenido al comparador de popularidad entre Oasis y Linkin Park! 🎤\");\n\n    try {\n        // Paso 1: Obtener el token de acceso\n        await obtenerAccessToken();\n\n        // Paso 2: Buscar información de las bandas\n        const oasis = await buscarArtista(\"Oasis\");\n        const linkinPark = await buscarArtista(\"Linkin Park\");\n\n        if (!oasis || !linkinPark) {\n            console.log(\"❌ No se pudo encontrar información de una o ambas bandas.\");\n            return;\n        }\n\n        // Paso 3: Obtener estadísticas de las bandas\n        const statsOasis = await obtenerEstadisticas(oasis.id);\n        const statsLinkinPark = await obtenerEstadisticas(linkinPark.id);\n\n        // Paso 4: Mostrar resultados\n        console.log(\"\\n--- ESTADÍSTICAS DE LAS BANDAS ---\");\n        console.log(`Oasis: ${statsOasis.seguidores} seguidores, ${statsOasis.popularidad} de popularidad`);\n        console.log(`Linkin Park: ${statsLinkinPark.seguidores} seguidores, ${statsLinkinPark.popularidad} de popularidad`);\n\n        // Paso 5: Comparar y determinar la banda más popular\n        const ganador = determinarGanador(statsOasis, statsLinkinPark);\n        console.log(`\\n🏆 ¡${ganador} es la banda más popular según los criterios establecidos! 🏆`);\n    } catch (error) {\n        console.error(\"❌ Error durante la ejecución:\", error.message);\n    }\n}\n\n// Función para obtener el token de acceso\nasync function obtenerAccessToken() {\n    const authOptions = {\n        url: \"https://accounts.spotify.com/api/token\",\n        method: \"post\",\n        headers: {\n            \"Content-Type\": \"application/x-www-form-urlencoded\",\n            Authorization: `Basic ${Buffer.from(`${CLIENT_ID}:${CLIENT_SECRET}`).toString(\"base64\")}`,\n        },\n        data: \"grant_type=client_credentials\",\n    };\n\n    const response = await axios(authOptions);\n    accessToken = response.data.access_token;\n}\n\n// Función para buscar un artista por nombre\nasync function buscarArtista(nombre) {\n    const response = await axios.get(\"https://api.spotify.com/v1/search\", {\n        headers: { Authorization: `Bearer ${accessToken}` },\n        params: { q: nombre, type: \"artist\" },\n    });\n\n    const artistas = response.data.artists.items;\n    return artistas.find(artista => artista.name.toLowerCase() === nombre.toLowerCase());\n}\n\n// Función para obtener estadísticas de un artista\nasync function obtenerEstadisticas(idArtista) {\n    const response = await axios.get(`https://api.spotify.com/v1/artists/${idArtista}`, {\n        headers: { Authorization: `Bearer ${accessToken}` },\n    });\n\n    const artista = response.data;\n    return {\n        seguidores: artista.followers.total,\n        popularidad: artista.popularity,\n    };\n}\n\n// Función para determinar la banda más popular\nfunction determinarGanador(statsOasis, statsLinkinPark) {\n    let puntosOasis = 0;\n    let puntosLinkinPark = 0;\n\n    // Criterio 1: Número de seguidores\n    if (statsOasis.seguidores > statsLinkinPark.seguidores) {\n        puntosOasis += 1;\n    } else if (statsOasis.seguidores < statsLinkinPark.seguidores) {\n        puntosLinkinPark += 1;\n    }\n\n    // Criterio 2: Popularidad\n    if (statsOasis.popularidad > statsLinkinPark.popularidad) {\n        puntosOasis += 1;\n    } else if (statsOasis.popularidad < statsLinkinPark.popularidad) {\n        puntosLinkinPark += 1;\n    }\n\n    // Determinar ganador\n    if (puntosOasis > puntosLinkinPark) {\n        return \"Oasis\";\n    } else if (puntosOasis < puntosLinkinPark) {\n        return \"Linkin Park\";\n    } else {\n        return \"Empate\";\n    }\n}\n\ncompararBandas();"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/javascript/duendeintemporal.js",
    "content": "//#37 - OASIS VS LINKING PARK   \n/*\n * EJERCICIO:\n * Oasis y Linkin Park han anunciado nueva gira, pero, ¿quién es más popular?\n * ¡Dos de las bandas más grandes de la historia están de vuelta!\n * Desarrolla un programa que se conecte al API de Spotify y los compare.\n * Requisitos:\n * 1. Crea una cuenta de desarrollo en https://developer.spotify.com.\n * 2. Conéctate al API utilizando tu lenguaje de programación.\n * 3. Recupera datos de los endpoint que tú quieras.\n * Acciones:\n * 1. Accede a las estadísticas de las dos bandas.\n *    Por ejemplo: número total de seguidores, escuchas mensuales,\n *    canción con más reproducciones...\n * 2. Compara los resultados de, por lo menos, 3 endpoint.\n * 3. Muestra todos los resultados por consola para notificar al usuario.\n * 4. Desarrolla un criterio para seleccionar qué banda es más popular.\n */\n\n// Note: This code is written in TypeScript, a superset of JavaScript that adds optional static typing and other features. The code is almost identical to JavaScript, with the main difference being the addition of type annotations to reference values. This allows for better code completion, error checking, and maintainability.\n\n// For example, the `getArtistId` function is annotated with the return type `Promise<string | null>`, indicating that it returns a promise that resolves to either a string or null. This helps catch type-related errors at compile-time rather than runtime.\n\n// alert('Script is running!');\n\n\n\n/* Instructions: You need to create a developer account on Spotify.\nRun these commands in a console in a Node.js environment:\n\nnpm create vite@latest spotify-profile-demo -- --template vanilla-ts\n\ncd spotify-profile-demo\nnpm install\nnpm run dev\n\nThen, delete the files in the src and public folders. \n\nReplace the index.html file with the following code:\n\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>User Profile Data</title>\n</head>\n<body>\n    <h1>Display Your Spotify Profile Data</h1>\n\n<section id=\"profile\">\n<h2>Logged in as <span id=\"displayName\"></span></h2>\n<span id=\"avatar\"></span>\n<ul>\n    <li>User ID: <span id=\"id\"></span></li>\n    <li>Email: <span id=\"email\"></span></li>\n    <li>Spotify URI: <a id=\"uri\" href=\"#\"></a></li>\n    <li>Link: <a id=\"url\" href=\"#\"></a></li>\n    <li>Profile Image: <span id=\"imgUrl\"></span></li>\n</ul>\n<p id=\"result\"></p>\n</section>\n<script src=\"./src/script.ts\"></script>\n\n</body>\n</html>\n\n*/\n\n/* You will also need to create a new app and set the configuration settings as follows... \n\nClient ID\n[insert your client_id here]\nApp Status\nDevelopment mode\nApp Name\nRoadMapExercise37\nApp Description\nIt compares results from two bands and displays a prediction of which will be more popular...\nWebsite\nRedirect URIs\nhttp://localhost:5173/callback\nBundle IDs\nAndroid packages\nAPIs Used\nWeb API\n*/\n\n/* Then create a file named script.ts in the src folder with the following code: */\nasync function main() {\n    const clientId = \"use the app id_client code\";\n    const params = new URLSearchParams(window.location.href.split('?')[1]);\n    const code = params.get(\"code\");\n\n    console.log(\"Authorization Code:\", code); // Debugging log\n\n    if (!code) {\n        console.log(\"No authorization code found. Redirecting to auth flow...\");\n        sessionStorage.setItem(\"lastAuthAttempt\", JSON.stringify({ timestamp: Date.now() }));\n        redirectToAuthCodeFlow(clientId);\n    } else {\n        try {\n            const accessToken = await getAccessToken(clientId, code);\n            console.log(\"Access Token:\", accessToken); // Debugging log\n\n            const profile = await fetchProfile(accessToken);\n            console.log(\"User Profile:\", profile); // Debugging log\n            populateUI(profile);\n            sessionStorage.setItem(\"userProfile\", JSON.stringify(profile)); // Store user profile\n\n            const oasisId = await getArtistId(accessToken, \"Oasis\");\n            const linkinParkId = await getArtistId(accessToken, \"Linkin Park\");\n            console.log(\"Oasis ID:\", oasisId);\n            console.log(\"Linkin Park ID:\", linkinParkId);\n\n            if (oasisId && linkinParkId) {\n                const oasisData = await getArtistData(accessToken, oasisId);\n                const linkinParkData = await getArtistData(accessToken, linkinParkId);\n        \n                // Fetch top tracks for both artists\n                const oasisTopTracks = await getTopTracks(accessToken, oasisId);\n                const linkinParkTopTracks = await getTopTracks(accessToken, linkinParkId);\n        \n                // Add top tracks to the data objects\n                oasisData.tracks = oasisTopTracks.tracks;\n                linkinParkData.tracks = linkinParkTopTracks.tracks;\n\n                if (oasisData && linkinParkData) {\n                    compareArtists(oasisData, linkinParkData);\n                }\n            }\n        } catch (error) {\n            console.error(\"Failed to fetch profile or access token:\", error);\n            // Check if the error is related to fetching the access token or profile\n            if (error instanceof Error && (error.message.includes(\"Failed to fetch profile\") || error.message.includes(\"Failed to get access token\"))) {\n                redirectToAuthCodeFlow(clientId);\n            } else {\n                console.error(\"An unexpected error occurred:\", error);\n            }\n        }\n    }\n}\n\n\n\nasync function getArtistId(accessToken: string, artistName: string): Promise<string | null> {\n    const result = await fetch(`https://api.spotify.com/v1/search?q=${artistName}&type=artist`, {\n        method: \"GET\",\n        headers: { Authorization: `Bearer ${accessToken}` }\n    });\n\n    const data = await result.json();\n    if (data.artists.items.length > 0) {\n        return data.artists.items[0].id;\n    } else {\n        return null;\n    }\n}\n\ninterface TopTrack {\n    name: string;\n    popularity: number;\n}\n\nfunction compareArtists(oasisData: any, linkinParkData: any) {\n    let oasisTopTrack: TopTrack | null = null;\n    let linkinParkTopTrack: TopTrack | null = null;\n\n    // Check if oasisData.tracks exists and has length\n    if (oasisData.tracks && oasisData.tracks.length > 0) {\n        oasisTopTrack = {\n            name: oasisData.tracks[0].name,\n            popularity: oasisData.tracks[0].popularity\n        };\n    }\n\n    // Check if linkinParkData.tracks exists and has length\n    if (linkinParkData.tracks && linkinParkData.tracks.length > 0) {\n        linkinParkTopTrack = {\n            name: linkinParkData.tracks[0].name,\n            popularity: linkinParkData.tracks[0].popularity\n        };\n    }\n\n    console.log(\"Oasis:\");\n    if (oasisTopTrack) {\n        console.log(`Oasis top track: ${oasisTopTrack.name}, popularity: ${oasisTopTrack.popularity}`);\n    } else {\n        console.log(\"No top track found for Oasis.\");\n    }\n    console.log(`Followers: ${oasisData.followers?.total ?? 'N/A'}`);\n    console.log(`Popularity: ${oasisData.popularity ?? 'N/A'}`);\n    console.log(`Genres: ${oasisData.genres?.join(\", \") ?? 'N/A'}`);\n\n    console.log(\"Linkin Park:\");\n    if (linkinParkTopTrack) {\n        console.log(`Linkin Park top track: ${linkinParkTopTrack.name}, popularity: ${linkinParkTopTrack.popularity}`);\n    } else {\n        console.log(\"No top track found for Linkin Park.\");\n    }\n    console.log(`Followers: ${linkinParkData.followers?.total ?? 'N/A'}`);\n    console.log(`Popularity: ${linkinParkData.popularity ?? 'N/A'}`);\n    console.log(`Genres: ${linkinParkData.genres?.join(\", \") ?? 'N/A'}`);\n\n    // Compare followers\n    if (oasisData.followers && linkinParkData.followers) {\n        if (oasisData.followers.total > linkinParkData.followers.total) {\n            console.log(\"Oasis is more popular based on followers.\");\n        } else if (oasisData.followers.total < linkinParkData.followers.total) {\n            console.log(\"Linkin Park is more popular based on followers.\");\n        } else {\n            console.log(\"Both artists have the same number of followers.\");\n        }\n    }\n\n    // Compare popularity\n    if (oasisData.popularity !== undefined && linkinParkData.popularity !== undefined) {\n        if (oasisData.popularity > linkinParkData.popularity) {\n            console.log(\"Oasis is more popular based on popularity score.\");\n        } else if (oasisData.popularity < linkinParkData.popularity) {\n            console.log(\"Linkin Park is more popular based on popularity score.\");\n        } else {\n            console.log(\"Both artists have the same popularity score.\");\n        }\n    }\n\n    // Compare top track popularity\n    if (oasisTopTrack && linkinParkTopTrack) {\n        if (oasisTopTrack.popularity > linkinParkTopTrack.popularity) {\n            console.log(\"Oasis is more popular based on top track popularity score.\");\n        } else if (oasisTopTrack.popularity < linkinParkTopTrack.popularity) {\n            console.log(\"Linkin Park is more popular based on top track popularity score.\");\n        } else {\n            console.log(\"Both artists have the same top track popularity score.\");\n        }\n    }\n\n    document.getElementById(\"result\")!.innerText = \"Display the Console DeveloperTools to See all The result Comparations\";\n}\n\n\nasync function redirectToAuthCodeFlow(clientId: string) {\n    \n    const verifier = generateCodeVerifier(128);\n    const challenge = await generateCodeChallenge(verifier);\n\n    localStorage.setItem(\"verifier\", verifier); // Store the verifier for later use\n\n    const params = new URLSearchParams();\n    params.append(\"client_id\", clientId);\n    params.append(\"response_type\", \"code\");\n    params.append(\"redirect_uri\", \"http://localhost:5173/callback\"); // Ensure this matches your Spotify app settings\n    params.append(\"scope\", \"user-read-private user-read-email user-top-read\");\n    params.append(\"code_challenge_method\", \"S256\");\n    params.append(\"code_challenge\", challenge);\n\n    // Redirect the user to the Spotify authorization page\n    document.location = `https://accounts.spotify.com/authorize?${params.toString()}`;\n}\n\n\nfunction generateCodeVerifier(length: number) {\n    let text = '';\n    let possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n\n    for (let i = 0; i < length; i++) {\n        text += possible.charAt(Math.floor(Math.random() * possible.length));\n    }\n    return text;\n}\n\nasync function generateCodeChallenge(codeVerifier: string) {\n    const data = new TextEncoder().encode(codeVerifier);\n    const digest = await window.crypto.subtle.digest('SHA-256', data);\n    return btoa(String.fromCharCode.apply(null, [...new Uint8Array(digest)]))\n        .replace(/\\+/g, '-')\n        .replace(/\\//g, '_')\n        .replace(/=+$/, '');\n}\n\nasync function getArtistData(accessToken: string, artistId: string): Promise<any> {\n    const result = await fetch(`https://api.spotify.com/v1/artists/${artistId}`, {\n        method: \"GET\",\n        headers: { Authorization: `Bearer ${accessToken}` }\n    });\n\n    if (!result.ok) {\n        const errorData = await result.json();\n        console.error(\"Failed to fetch artist data:\", errorData);\n        throw new Error(`Failed to fetch artist data: ${result.status} ${result.statusText}`);\n    }\n\n    return await result.json();\n}\n\nasync function getTopTracks(accessToken: string, artistId: string, market: string = 'US'): Promise<any> {\n    const response = await fetch(`https://api.spotify.com/v1/artists/${artistId}/top-tracks?market=${market}`, {\n        method: \"GET\",\n        headers: { Authorization: `Bearer ${accessToken}` }\n    });\n\n    if (!response.ok) {\n        const errorData = await response.json();\n        console.error(\"Failed to fetch top tracks:\", errorData);\n        throw new Error(`Failed to fetch top tracks: ${response.status} ${response.statusText}`);\n    }\n\n    return await response.json();\n}\n\n\nasync function getAccessToken(clientId: string, code: string): Promise<string> {\n    const primaryUrl = 'https://accounts.spotify.com/api/token';\n    const verifier = localStorage.getItem(\"verifier\");\n\n    const params = new URLSearchParams();\n    params.append(\"client_id\", clientId);\n    params.append(\"grant_type\", \"authorization_code\");\n    params.append(\"code\", code);\n    params.append(\"redirect_uri\", \"http://localhost:5173/callback\");\n    params.append(\"code_verifier\", verifier!); // Use the verifier stored in local storage\n\n    try {\n        const result = await fetch(primaryUrl, {\n            method: \"POST\",\n            headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n            body: params\n        });\n\n        if (result.ok) {\n            const { access_token } = await result.json();\n            return access_token;\n        } else {\n            const errorData = await result.json();\n            console.error(\"Failed to get access token:\", errorData);\n            throw new Error(`Failed to get access token: ${result.status} ${errorData.error_description}`);\n        }\n    } catch (error: any) {\n        console.error(`Error using primary URL: ${error.message}`);\n        throw error; // Rethrow the error for further handling\n    }\n}\n\n\ninterface UserProfile {\n    country: string;\n    display_name: string;\n    email: string;\n    explicit_content: {\n        filter_enabled: boolean,\n        filter_locked: boolean\n    },\n    external_urls: { spotify: string; };\n    followers: { href: string; total: number; };\n    href: string;\n    id: string;\n    images: Image[];\n    product: string;\n    type: string;\n    uri: string;\n}\n\ninterface Image {\n    url: string;\n    height: number;\n    width: number;\n}\n\nfunction populateUI(profile: UserProfile) {\n    document.getElementById(\"displayName\")!.innerText = profile.display_name;\n    if (profile.images[0]) {\n        const profileImage = new Image(200, 200);\n        profileImage.src = profile.images[0].url;\n        document.getElementById(\"avatar\")!.appendChild(profileImage);\n    }\n    document.getElementById(\"id\")!.innerText = profile.id;\n    document.getElementById(\"email\")!.innerText = profile.email;\n    document.getElementById(\"uri\")!.innerText = profile.uri;\n    document.getElementById(\"uri\")!.setAttribute(\"href\", profile.external_urls.spotify);\n    document.getElementById(\"url\")!.innerText = profile.href;\n    document.getElementById(\"url\")!.setAttribute(\"href\", profile.href);\n    document.getElementById(\"imgUrl\")!.innerText = profile.images[0]?.url ?? '(no profile image)';\n}\n\nasync function fetchProfile(token: string): Promise<UserProfile> {\n    const result = await fetch(\"https://api.spotify.com/v1/me\", {\n        method: \"GET\",\n        headers: { Authorization: `Bearer ${token}` }\n    });\n\n    if (!result.ok) {\n        const errorData = await result.json();\n        console.error(\"Failed to fetch profile:\", errorData);\n        throw new Error(`Failed to fetch profile: ${result.status} ${result.statusText}`);\n    }\n\n    return await result.json();\n}\n\n\n// Start the main function\nmain();\n"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/javascript/hectorio23.js",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\nconst axios = require('axios');\n\n// Credenciales\nconst clientId = 'client_id';\nconst clientSecret = 'client_secret';\n\n// Función para obtener el token de acceso\nasync function getAccessToken() {\n  const response = await axios.post('https://accounts.spotify.com/api/token', null, {\n    params: {\n      grant_type: 'client_credentials',\n      client_id: clientId,\n      client_secret: clientSecret\n    },\n    headers: {\n      'Content-Type': 'application/x-www-form-urlencoded'\n    }\n  });\n  return response.data.access_token;\n}\n\n// Función para obtener los datos de una banda/artista\nasync function getArtistData(artistName, token) {\n  const response = await axios.get(`https://api.spotify.com/v1/search?q=${artistName}&type=artist&limit=1`, {\n    headers: {\n      Authorization: `Bearer ${token}`\n    }\n  });\n  return response.data.artists.items[0];\n}\n\n// Comparación de bandas\nasync function compareBands() {\n  const token = await getAccessToken();\n  const oasisData = await getArtistData('Oasis', token);\n  const linkinParkData = await getArtistData('Linkin Park', token);\n\n  console.log('Oasis:', oasisData.followers.total, 'seguidores');\n  console.log('Linkin Park:', linkinParkData.followers.total, 'seguidores');\n\n  if (oasisData.followers.total > linkinParkData.followers.total) {\n    console.log('Oasis es más popular en seguidores.');\n  } else {\n    console.log('Linkin Park es más popular en seguidores.');\n  }\n}\n\ncompareBands();\n"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/javascript/isaacus98.js",
    "content": "/*\n * EJERCICIO:\n * Oasis y Linkin Park han anunciado nueva gira, pero, ¿quién es más popular?\n * ¡Dos de las bandas más grandes de la historia están de vuelta!\n * Desarrolla un programa que se conecte al API de Spotify y los compare.\n * Requisitos:\n * 1. Crea una cuenta de desarrollo en https://developer.spotify.com.\n * 2. Conéctate al API utilizando tu lenguaje de programación.\n * 3. Recupera datos de los endpoint que tú quieras.\n * Acciones:\n * 1. Accede a las estadísticas de las dos bandas.\n *    Por ejemplo: número total de seguidores, escuchas mensuales,\n *    canción con más reproducciones...\n * 2. Compara los resultados de, por lo menos, 3 endpoint.\n * 3. Muestra todos los resultados por consola para notificar al usuario.\n * 4. Desarrolla un criterio para seleccionar qué banda es más popular.\n */\n\nclass Band {\n    constructor(name, followers, bandPopularity, songName, songPopularity) {\n        this.name = name\n        this.followers = followers\n        this.bandPopularity = bandPopularity\n        this.songName = songName\n        this.songPopularity = songPopularity\n    }\n}\nconst idLinkinPark = \"6XyY86QOPPrYVGvF9ch6wz\"\nconst idOasis = \"2DaxqgrOhkeH0fpeiQq2f4\"\n\nlet client_id = \"\"//'CLIENT_ID';\nlet client_secret = \"\" //'CLIENT_SECRET';\n\n// Obtener token de spotify\nasync function getTokenAsync() {\n    const response = await fetch('https://accounts.spotify.com/api/token', {\n        method: 'POST',\n        body: new URLSearchParams({\n            'grant_type': 'client_credentials',\n        }),\n        headers: {\n            'Content-Type': 'application/x-www-form-urlencoded',\n            'Authorization': 'Basic ' + (Buffer.from(client_id + ':' + client_secret).toString('base64')),\n        },\n    });\n    \n    return await response.json();\n}\n\nasync function getArtistInfoAsync(access_token, idArtist) {\n    const response = await fetch(\"https://api.spotify.com/v1/artists/\" + idArtist, {\n        method: \"GET\",\n        headers: { 'Authorization': 'Bearer ' + access_token }\n    })\n\n    return await response.json()\n}\n\nasync function getTopTracksAsync(access_token, idArtist) {\n    const response = await fetch(\"https://api.spotify.com/v1/artists/\" + idArtist + \"/top-tracks\", {\n        method: \"GET\",\n        headers: { 'Authorization': 'Bearer ' + access_token }\n    })\n\n    return await response.json()\n}\n\nasync function mainAsync() {\n    const token = await getTokenAsync()\n    const infoLinkinPark = await getArtistInfoAsync(token.access_token, idLinkinPark)\n    const topTrackLinkinPark = await getTopTracksAsync(token.access_token, idLinkinPark)\n    const infoOasis = await getArtistInfoAsync(token.access_token, idOasis)\n    const topTrackOasis = await getTopTracksAsync(token.access_token, idOasis)\n\n    let linkinPark = new Band(infoLinkinPark.name, infoLinkinPark.followers.total, infoLinkinPark.popularity, topTrackLinkinPark.tracks[0].name, topTrackLinkinPark.tracks[0].popularity)\n    let oasis = new Band(infoOasis.name, infoOasis.followers.total, infoOasis.popularity, topTrackOasis.tracks[0].name, topTrackOasis.tracks[0].popularity)\n    \n    console.group(linkinPark.name)\n    console.log(`Número de seguidores: ${linkinPark.followers}`)\n    console.log(`Popularidad de la banda: ${linkinPark.bandPopularity}`)\n    console.log(`Canción mas escuchada actualmente: ${linkinPark.songName}, popularidad: ${linkinPark.songPopularity}`)\n    console.groupEnd()\n\n    console.group(oasis.name)\n    console.log(`Número de seguidores: ${oasis.followers}`)\n    console.log(`Popularidad de la banda: ${oasis.bandPopularity}`)\n    console.log(`Canción mas escuchada actualmente: ${oasis.songName}, popularidad: ${oasis.songPopularity}`)\n    console.groupEnd()\n\n    // Comparación\n    let linkinParkScore = 0\n    let oasisScore = 0\n\n    linkinPark.followers > oasis.followers ? linkinParkScore++ : oasisScore++\n    linkinPark.bandPopularity > oasis.bandPopularity ? linkinParkScore++ : oasisScore++\n    linkinPark.songPopularity > oasis.songPopularity ? linkinParkScore++ : oasisScore++\n\n    console.log(`La banda ${linkinParkScore > oasisScore ? linkinPark.name : oasis.name} es mas popular que ${linkinParkScore < oasisScore ? linkinPark.name : oasis.name}`)\n}\n\nmainAsync()"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n_______________________________________________________\n#37 OASIS VS LINKIN PARK\n-------------------------------------------------------\n* ¡Dos de las bandas más grandes de la historia están de vuelta!\n* Oasis y Linkin Park han anunciado nueva gira, pero, ¿quién es más popular?\n* Desarrolla un programa que se conecte al API de Spotify y los compare.\n* Requisitos:\n* 1. Crea una cuenta de desarrollo en https://developer.spotify.com.\n* 2. Conéctate al API utilizando tu lenguaje de programación.\n* 3. Recupera datos de los endpoint que tú quieras.\n* Acciones:\n* 1. Accede a las estadísticas de las dos bandas.\n*    Por ejemplo: número total de seguidores, escuchas mensuales,\n*    canción con más reproducciones...\n* 2. Compara los resultados de, por lo menos, 3 endpoint.\n* 3. Muestra todos los resultados por consola para notificar al usuario.\n* 4. Desarrolla un criterio para seleccionar qué banda es más popular.\n*/\n// ________________________________________________________\nrequire('dotenv').config();\nconst https = require('https');\n\nconst SPOTIFY_CLIENT_ID = process.env.SPOTIFY_CLIENT_ID;\nconst SPOTIFY_CLIENT_SECRET = process.env.SPOTIFY_CLIENT_SECRET;\n\nconst getSpotifyAccessToken = async () => {\n  const options = {\n    hostname: \"accounts.spotify.com\",\n    path: \"/api/token\",\n    method: \"POST\",\n    headers: {\n      \"Content-Type\": \"application/x-www-form-urlencoded\",\n      Authorization: `Basic ${Buffer.from(\n        `${SPOTIFY_CLIENT_ID}:${SPOTIFY_CLIENT_SECRET}`\n      ).toString(\"base64\")}`,\n    },\n  };\n\n  return new Promise((resolve, reject) => {\n    const req = https.request(options, (res) => {\n      let data = \"\";\n\n      res.on(\"data\", (chunk) => {\n        data += chunk;\n      });\n\n      res.on(\"end\", () => {\n        const response = JSON.parse(data);\n        resolve(response.access_token);\n      });\n    });\n\n    req.on(\"error\", (e) => {\n      reject(e);\n    });\n\n    req.write(\"grant_type=client_credentials\");\n    req.end();\n  });\n};\n\nconst spotifyAPIRequest = async (endpoint, accessToken) => {\n  const options = {\n    hostname: \"api.spotify.com\",\n    path: endpoint,\n    method: \"GET\",\n    headers: {\n      Authorization: `Bearer ${accessToken}`,\n    },\n  };\n\n  return new Promise((resolve, reject) => {\n    const req = https.request(options, (res) => {\n      let data = \"\";\n\n      res.on(\"data\", (chunk) => {\n        data += chunk;\n      });\n\n      res.on(\"end\", () => {\n        resolve(JSON.parse(data));\n      });\n    });\n\n    req.on(\"error\", (e) => {\n      reject(e);\n    });\n\n    req.end();\n  });\n};\n\nclass Spotify {\n  constructor() {\n    this.accessToken = null;\n  }\n\n  async authenticate() {\n    this.accessToken = await getSpotifyAccessToken();\n  }\n\n  async getArtists(name) {\n    const results = await spotifyAPIRequest(\n      `/v1/search?q=artist:${encodeURIComponent(name)}&type=artist&limit=3`,\n      this.accessToken\n    );\n    return results.artists ? results.artists.items : [];\n  }\n\n  async getMostPopularArtist(name) {\n    const artists = await this.getArtists(name);\n    if (artists.length === 0) return null;\n\n    return artists.sort((a, b) => b.popularity - a.popularity)[0];\n  }\n\n  async artistTopTracks(artistId) {\n    const results = await spotifyAPIRequest(\n      `/v1/artists/${artistId}/top-tracks?market=US`,\n      this.accessToken\n    );\n    return results.tracks || [];\n  }\n\n  async artistAlbums(artistId) {\n    const results = await spotifyAPIRequest(\n      `/v1/artists/${artistId}/albums?album_type=album`,\n      this.accessToken\n    );\n    return results.items || [];\n  }\n}\n\n// Clase Versus\nclass Versus {\n  constructor(artist1, artist2, spotifyInstance) {\n    this.a1 = artist1;\n    this.a2 = artist2;\n    this.sp = spotifyInstance;\n    this.a1Score = 0;\n    this.a2Score = 0;\n  }\n\n  popularity() {\n    console.log(`Popularidad: ${this.a1.popularity} vs ${this.a2.popularity}`);\n    if (this.a1.popularity > this.a2.popularity) this.a1Score++;\n    else if (this.a2.popularity > this.a1.popularity) this.a2Score++;\n  }\n\n  followers() {\n    console.log(\n      `Seguidores: ${this.a1.followers.total} vs ${this.a2.followers.total}`\n    );\n    if (this.a1.followers.total > this.a2.followers.total) this.a1Score++;\n    else if (this.a2.followers.total > this.a1.followers.total) this.a2Score++;\n  }\n\n  async top3Tracks() {\n    const a1Tracks = await this.sp.artistTopTracks(this.a1.id);\n    const a2Tracks = await this.sp.artistTopTracks(this.a2.id);\n\n    const a1Popularity = a1Tracks.slice(0, 3).reduce((sum, track) => sum + track.popularity, 0);\n    const a2Popularity = a2Tracks.slice(0, 3).reduce((sum, track) => sum + track.popularity, 0);\n\n    console.log(`Popularidad Top 3 canciones: ${a1Popularity} vs ${a2Popularity}`);\n    if (a1Popularity > a2Popularity) this.a1Score++;\n    else if (a2Popularity > a1Popularity) this.a2Score++;\n  }\n\n  async albumsAndActiveYears() {\n    const a1Albums = await this.sp.artistAlbums(this.a1.id);\n    const a2Albums = await this.sp.artistAlbums(this.a2.id);\n\n    console.log(`Número de álbumes: ${a1Albums.length} vs ${a2Albums.length}`);\n    if (a1Albums.length > a2Albums.length) this.a1Score++;\n    else if (a2Albums.length > a1Albums.length) this.a2Score++;\n\n    const a1Years = new Set(a1Albums.map((album) => album.release_date.slice(0, 4)));\n    const a2Years = new Set(a2Albums.map((album) => album.release_date.slice(0, 4)));\n\n    console.log(`Años activos: ${a1Years.size} vs ${a2Years.size}`);\n    if (a1Years.size > a2Years.size) this.a1Score++;\n    else if (a2Years.size > a1Years.size) this.a2Score++;\n  }\n\n  finalResult() {\n    console.log(\"\\nRESULTADO FINAL:\");\n    console.log(`${this.a1.name}: ${this.a1Score} puntos`);\n    console.log(`${this.a2.name}: ${this.a2Score} puntos`);\n\n    if (this.a1Score > this.a2Score) {\n      console.log(`\\n¡'${this.a1.name}' gana el versus!`);\n    } else if (this.a2Score > this.a1Score) {\n      console.log(`\\n¡'${this.a2.name}' gana el versus!`);\n    } else {\n      console.log(\"\\n¡Es un empate!\");\n    }\n  }\n\n  async start() {\n    console.log(`${this.a1.name} vs ${this.a2.name}`);\n    this.popularity();\n    this.followers();\n    await this.top3Tracks();\n    await this.albumsAndActiveYears();\n    this.finalResult();\n  }\n}\n\nconst main = async () => {\n  const spotify = new Spotify();\n  await spotify.authenticate();\n\n  const artist1 = await spotify.getMostPopularArtist(\"Oasis\");\n  const artist2 = await spotify.getMostPopularArtist(\"Linkin Park\");\n\n  if (!artist1 || !artist2) {\n    console.log(\"Artistas no encontrados\");\n    return;\n  }\n\n  const versus = new Versus(artist1, artist2, spotify);\n  await versus.start();\n};\n\nmain();\n"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/javascript/miguelex.js",
    "content": "const readline = require('readline');\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nconst clientId = '4cc0a0d989f54e4f8e44da158cf646b0';\nconst clientSecret = '05fa3d3be3c54a4d941d648c980ca228';\n\nasync function getAccessToken() {\n    const response = await fetch('https://accounts.spotify.com/api/token', {\n        method: 'POST',\n        headers: {\n            'Content-Type': 'application/x-www-form-urlencoded',\n            'Authorization': 'Basic ' + btoa(clientId + ':' + clientSecret),\n        },\n        body: 'grant_type=client_credentials'\n    });\n    const data = await response.json();\n    return data.access_token;\n}\n\nasync function getArtistData(token, artistName) {\n    const response = await fetch(`https://api.spotify.com/v1/search?q=${artistName}&type=artist`, {\n        method: 'GET',\n        headers: {\n            'Authorization': `Bearer ${token}`\n        }\n    });\n    const data = await response.json();\n    return data.artists.items[0];  \n}\n\nasync function getArtistStats(artistId, token) {\n    const response = await fetch(`https://api.spotify.com/v1/artists/${artistId}`, {\n        method: 'GET',\n        headers: {\n            'Authorization': `Bearer ${token}`\n        }\n    });\n    const data = await response.json();\n    return {\n        name: data.name,\n        followers: data.followers.total,\n        popularity: data.popularity,\n        genres: data.genres,\n    };\n}\n\nasync function getArtistTopTracks(artistId, token) {\n    const response = await fetch(`https://api.spotify.com/v1/artists/${artistId}/top-tracks?market=US`, {\n        method: 'GET',\n        headers: {\n            'Authorization': `Bearer ${token}`\n        }\n    });\n    const data = await response.json();\n    const mostPopularTrack = data.tracks[0]; \n    return {\n        name: mostPopularTrack.name,\n        playCount: mostPopularTrack.popularity, \n        album: mostPopularTrack.album.name\n    };\n}\n\nasync function compareBands(band1, band2) {\n    const token = await getAccessToken();\n    \n    const band1Data = await getArtistData(token, band1);\n    const band2Data = await getArtistData(token, band2);\n    \n    const band1Stats = await getArtistStats(band1Data.id, token);\n    const band2Stats = await getArtistStats(band2Data.id, token);\n    \n    const band1TopTrack = await getArtistTopTracks(band1Data.id, token);\n    const band2TopTrack = await getArtistTopTracks(band2Data.id, token);\n    \n    console.log(`\\n${band1} Stats:`, band1Stats);\n    console.log(`Canción más popular de ${band1}:`, band1TopTrack);\n    \n    console.log(`\\n${band2} Stats:`, band2Stats);\n    console.log(`Canción más popular de ${band2}:`, band2TopTrack);\n    \n    const moreFollowers = (band1Stats.followers > band2Stats.followers)\n        ? band1\n        : band2;\n    \n    const morePopularTrack = (band1TopTrack.playCount > band2TopTrack.playCount)\n        ? band1\n        : band2;\n    \n    console.log(`\\nLa banda con más seguidores es: ${moreFollowers}`);\n    console.log(`La banda con la canción más popular es: ${morePopularTrack}`);\n}\n\nrl.question('Introduce el nombre del primer grupo: ', (band1) => {\n    rl.question('Introduce el nombre del segundo grupo: ', (band2) => {\n        compareBands(band1, band2).then(() => {\n            rl.close();  \n        }).catch(err => {\n            console.error('Error al comparar las bandas:', err);\n            rl.close();\n        });\n    });\n});\n"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/javascript/pedamoci.js",
    "content": "import readline from \"readline\"\n\nconst colors = {\n  red: \"\\x1b[31m\",\n  green: \"\\x1b[32m\",\n  yellow: \"\\x1b[33m\",\n  cyan: \"\\x1b[34m\",\n  reset: \"\\x1b[0m\",\n}\n\nclass Asks {\n  constructor() {\n    this.readline = readline.createInterface({\n      input: process.stdin,\n      output: process.stdout\n    })\n  }\n\n  #ask(question) {\n    return new Promise(resolve => {\n      this.readline.question(question, (answer) => resolve(answer))\n    })\n  }\n\n  close() {\n    this.readline.close()\n  }\n\n  async askLabel(label) {\n    const response = await this.#ask(colors.cyan + `Enter the ${label}: ` + colors.reset)\n    return response\n  }\n}\n\nclass Renderer {\n  static error(message) {\n    console.log(colors.red + \"Error: \" + message + colors.reset)\n  }\n\n  static success(message) {\n    console.log(colors.green + \"Success: \" + message + colors.reset)\n  }\n\n  static info(info) {\n    console.log(colors.yellow + info + colors.reset)\n  }\n}\n\nconst asks = new Asks()\n\nclass APISpotify {\n  constructor() {\n    this.token = 'undefined';\n  }\n\n  async fetchWebApi(endpoint, method) {\n    const res = await fetch(`https://api.spotify.com/v1/${endpoint}`, {\n      headers: {\n        Authorization: `Bearer ${this.token}`,\n      },\n      method\n    });\n    return await res.json();\n  }\n\n  async searchArtist(name) {\n    const res = await this.fetchWebApi(\n      `search?q=${encodeURIComponent(name)}&type=artist&limit=10`, \n      \"GET\"\n    );\n    return res.artists.items;\n  }\n\n  async searchSongsArtist(id) {\n    const res = await this.fetchWebApi(\n      `artists/${id}/top-tracks?market=AR`, \n      \"GET\"\n    );\n    return res.tracks;\n  }\n}\n\nclass GetInfo {\n  constructor(apiSpotify){\n    this.apiSpotify = apiSpotify\n  }\n\n  async getArtist(name) {\n    let artists = await this.apiSpotify.searchArtist(name)\n\n    for (const artist of artists) {\n      if (artist.name.toLowerCase() === name.toLowerCase()){\n        return artist\n      }\n    }\n    return artists[0]\n  }\n\n  async songMostPopular(id) {\n    let songs = await this.apiSpotify.searchSongsArtist(id)\n\n    const maxPopularity = Math.max(...songs.map(s => s.popularity))\n\n    const song = songs.filter(s => s.popularity === maxPopularity)\n\n    return song[0]\n  }\n\n  async artistData(name) {\n    const artist = await this.getArtist(name)\n    const popularity = artist.popularity\n    const followers = artist.followers.total\n\n    const song = await this.songMostPopular(artist.id)\n    const songName = song.name\n    const songPopularity = song.popularity\n\n    const artistData = {name: artist.name, popularity: popularity, followers: followers, songName: songName, songPopularity: songPopularity}\n\n    return artistData\n  }\n}\n\nclass Comparator {\n  constructor() {\n    this.winner = {}\n    this.countArtistOne = 0\n    this.countArtistTwo = 0\n  }\n\n  popularity(artistOne, artistTwo) {\n    if (artistOne.popularity > artistTwo.popularity) {\n      this.winner.popularity = {name: artistOne.name, popularity: artistOne.popularity}\n      this.countArtistOne++\n    }\n\n    if (artistOne.popularity < artistTwo.popularity) {\n      this.winner.popularity = {name: artistTwo.name, popularity: artistTwo.popularity}\n      this.countArtistTwo++\n    }\n  }\n\n  followers(artistOne, artistTwo){\n    if (artistOne.followers > artistTwo.followers) {\n      this.winner.followers = {name: artistOne.name, followers: artistOne.followers}\n      this.countArtistOne++\n    }\n\n    if (artistOne.followers < artistTwo.followers) {\n      this.winner.followers = {name: artistTwo.name, followers: artistTwo.followers}\n      this.countArtistTwo++\n    }\n  }\n\n  songPopularity(artistOne, artistTwo) {\n    if (artistOne.songPopularity > artistTwo.songPopularity) {\n      this.winner.song = {name: artistOne.name, songName: artistOne.songName, songPopularity: artistOne.songPopularity}\n      this.countArtistOne++\n    }\n\n    if (artistOne.songPopularity < artistTwo.songPopularity) {\n      this.winner.song = {name: artistTwo.name, songName: artistTwo.songName, songPopularity: artistTwo.songPopularity}\n      this.countArtistTwo++\n    }\n  }\n\n  artist(artistOne, artistTwo) {\n    this.popularity(artistOne, artistTwo)\n    this.followers(artistOne, artistTwo)\n    this.songPopularity(artistOne, artistTwo)\n\n    if (this.countArtistOne > this.countArtistTwo) this.winner.winnerName = artistOne.name\n    if (this.countArtistOne < this.countArtistTwo) this.winner.winnerName = artistTwo.name\n\n    return this.winner\n  }\n}\n\nclass CreatorTXT {\n  constructor() {\n    this.info = \"\"\n  }\n\n  txt(data) {\n    if (!!data.winnerName) {\n      this.info += `\\nWINNER: ${data.winnerName}`\n    } else {\n      this.info += \"\\nDRAW\"\n    }\n\n    if (!!data.popularity) {\n      this.info += `\\n${data.popularity.name} wins by popularity with ${data.popularity.popularity} points`\n    } else {\n      this.info += \"\\nThe two artists tied in popularity\"\n    }\n\n    if (!!data.followers) {\n      this.info += `\\n${data.followers.name} wins by followers with ${data.followers.followers}`\n    } else {\n      this.info += \"\\nThe two artists tied in followers\"\n    }\n\n    if (!!data.song) {\n      this.info += `\\nThe artist ${data.song.name} won with the song \"${data.song.songName}\", with a popularity rating of ${data.song.songPopularity}`\n    } else {\n      this.info += \"\\nThe two artists tied in popularity with their songs\"\n    }\n\n    return this.info\n  }\n}\n\nclass Controller {\n  constructor(creatorTXT, comparator, getInfo) {\n    this.creatorTXT = creatorTXT\n    this.comparator = comparator\n    this.getInfo = getInfo\n    this.artistOne\n    this.artistTwo\n  }\n\n  async start() {\n    const nameArtistOne = await asks.askLabel(\"artist's name\")\n\n    this.artistOne = await this.getInfo.artistData(nameArtistOne)\n\n    while (true) {\n      const nameArtistTwo = await asks.askLabel(\"second artist's name\")\n      if (nameArtistTwo !== nameArtistOne && nameArtistTwo !== this.artistOne.name){\n        this.artistTwo = await this.getInfo.artistData(nameArtistTwo)\n        break\n      }\n\n      Renderer.error(\"The artist's name must be different from the first one\")\n    }\n\n    const winner = this.comparator.artist(this.artistOne, this.artistTwo)\n\n    const info = this.creatorTXT.txt(winner)\n\n    Renderer.info(info)\n\n    asks.close()\n  }\n}\n\nconst controller = new Controller(new CreatorTXT(), new Comparator(), new GetInfo(new APISpotify))\ncontroller.start()"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/kotlin/blackriper.kt",
    "content": "import io.ktor.client.HttpClient\r\nimport io.ktor.client.call.body\r\nimport io.ktor.client.engine.cio.CIO\r\nimport io.ktor.client.plugins.contentnegotiation.ContentNegotiation\r\nimport io.ktor.client.request.forms.FormDataContent\r\nimport io.ktor.client.request.get\r\nimport io.ktor.client.request.headers\r\nimport io.ktor.client.request.post\r\nimport io.ktor.client.request.setBody\r\nimport io.ktor.client.statement.bodyAsText\r\nimport io.ktor.http.HttpHeaders\r\nimport io.ktor.http.parameters\r\nimport io.ktor.serialization.kotlinx.json.json\r\nimport io.ktor.util.decodeBase64String\r\nimport kotlinx.coroutines.async\r\nimport kotlinx.coroutines.coroutineScope\r\nimport kotlinx.coroutines.flow.asFlow\r\nimport kotlinx.coroutines.flow.map\r\nimport kotlinx.coroutines.flow.transform\r\nimport kotlinx.coroutines.launch\r\nimport kotlinx.coroutines.runBlocking\r\nimport kotlinx.serialization.SerialName\r\nimport kotlinx.serialization.Serializable\r\nimport kotlinx.serialization.json.Json\r\nimport java.util.Base64\r\nimport java.util.Comparator\r\n\r\n\r\n//1.-data para reponses y request\r\nconst val CLIENT_ID=\"YOUR_CLIENT_ID\"\r\nconst val CLIENT_SECRET=\"YOUR_CLIENT_SECRET\"\r\n\r\nobject Endpoints{\r\n    const val TOKEND=\"https://accounts.spotify.com/api/token\"\r\n    val searhArtist={name: String->\"https://api.spotify.com/v1/search?q=$name&type=artist&limit=1\"}\r\n    val getArtistOrTrack={id: String,isTrack: Boolean->\r\n        if (isTrack) \"https://api.spotify.com/v1/artists/$id/top-tracks\"\r\n        else \"https://api.spotify.com/v1/artists/$id\"\r\n    }\r\n}\r\n\r\n\r\nval base64Credentials=Base64.getEncoder().encodeToString(\"$CLIENT_ID:$CLIENT_SECRET\".toByteArray())\r\n\r\n@Serializable\r\ndata class ResponseToken(\r\n    @SerialName(\"access_token\")\r\n    val accessToken: String\r\n)\r\n\r\n//obtener el id del artista gracias ala configuracion de json puedo omitir campos que no necesito\r\n@Serializable\r\ndata class Item(val id: String)\r\n\r\n@Serializable\r\ndata class DataArtist( val items: List<Item>)\r\n\r\n\r\n@Serializable\r\ndata class ResponseArtistID(\r\n    val artists:DataArtist\r\n)\r\n\r\n\r\n@Serializable\r\ndata class Artist(val name: String,val followers: Follower, val popularity: Int){\r\n    companion object{\r\n        fun toArtistDto(artist: Artist,track: Track):ArtistDto{\r\n            return ArtistDto(\r\n                artist.name,\r\n                artist.followers,\r\n                artist.popularity,\r\n                track\r\n            )\r\n        }\r\n    }\r\n}\r\n\r\n@Serializable\r\ndata class Follower(val total: Long)\r\n\r\n\r\n@Serializable\r\ndata class Track(val name: String,val popularity: Int)\r\n\r\n@Serializable\r\ndata class Tracks(val tracks: List<Track>)\r\n\r\n// creando una clase adicional para poder hacer mas optima la comparacion\r\ndata class ArtistDto(val name: String,val followers: Follower, val popularity: Int,val track: Track)\r\n\r\n\r\n\r\n//2.-configurar cliente para  solicitudes http con ktor\r\n//https://ktor.io/docs/client-create-new-application.html\r\nval client= HttpClient(CIO){\r\n    install(ContentNegotiation){\r\n        json(Json{\r\n            prettyPrint=true\r\n            ignoreUnknownKeys=true\r\n         })\r\n    }\r\n}\r\n\r\n\r\n\r\n\r\n//3.-obtener token para poder acceder ala api\r\n\r\nsuspend fun getToken(): String{\r\n   val response=client.post(Endpoints.TOKEND){\r\n       headers {\r\n           append(HttpHeaders.Authorization,\"Basic $base64Credentials\")\r\n           append(HttpHeaders.ContentType,\"application/x-www-form-urlencoded\")\r\n       }\r\n       setBody(FormDataContent(parameters {\r\n           append(\"grant_type\",\"client_credentials\")\r\n       }))\r\n   }\r\n    if (response.status.value!=200) throw Exception(\"error conecting spotify ${response.bodyAsText()}\")\r\n\r\n    return response.body<ResponseToken>().accessToken\r\n}\r\n\r\n\r\n//4.-consultar informacion de artista\r\nsuspend fun getArtistID(token: String,name: String): String{\r\n    val response=client.get(Endpoints.searhArtist(name)){\r\n        headers {\r\n            append(HttpHeaders.Authorization,\"Bearer $token\")\r\n        }\r\n    }\r\n    if (response.status.value!=200) throw Exception(\"error to get Artist Id  for name $name\")\r\n    return response.body<ResponseArtistID>().artists.items[0].id\r\n}\r\n\r\n\r\n//5.-obtener informacion del artista\r\nsuspend fun getDataArtist(token: String,id: String):Artist{\r\n    val response=client.get(Endpoints.getArtistOrTrack(id,false)){\r\n        headers {\r\n            append(HttpHeaders.Authorization,\"Bearer $token\")\r\n        }\r\n    }\r\n    if (response.status.value!=200) throw Exception(\"error to get artist data ${response.bodyAsText()}\")\r\n    return response.body<Artist>()\r\n}\r\n\r\n\r\n//6.-optener la cancion mas popular\r\nsuspend fun getTopTrack(token: String,id: String):Track{\r\n    val response=client.get(Endpoints.getArtistOrTrack(id,true)){\r\n        headers {\r\n            append(HttpHeaders.Authorization,\"Bearer $token\")\r\n        }\r\n    }\r\n    if (response.status.value!=200) throw Exception(\"error to get artist data ${response.bodyAsText()}\")\r\n    val bestTrack=response.body<Tracks>().tracks.maxByOrNull { it.popularity }\r\n    return bestTrack?:Track(\"\",0)\r\n}\r\n\r\n\r\nsuspend fun comparateArtist(artists: List<ArtistDto>){\r\n    var counter1: Int=0\r\n    var counter2: Int=0\r\n\r\n    println(\"Comparate Artist\")\r\n    println(\"${artists.get(0).name} vs ${artists.get(1).name} \")\r\n\r\n    //seguidores\r\n    println(\"Comparate followers\")\r\n    val winnerfoll=artists.maxByOrNull { it.followers.total }\r\n    if (winnerfoll!=null) {\r\n        println(\"artist ${winnerfoll.name} is more popular in number of followers\")\r\n        if (artists.get(0).name==winnerfoll.name) counter1++\r\n        else counter2++\r\n    }\r\n    else println(\"tie no artist is more followers than another \")\r\n\r\n\r\n    //popularidad\r\n    println(\"Comparate popularity\")\r\n    val winnerPop=artists.maxByOrNull { it.popularity }\r\n    if (winnerPop!=null){\r\n        println(\"artist ${winnerPop.name} is most popular artist\")\r\n        if (artists.get(0).name==winnerPop.name) counter1++\r\n        else counter2++\r\n    }\r\n    else println(\" no artist is more popular than another \")\r\n\r\n    println(\"Comparate popularity song\")\r\n    val winnerTrack=artists.maxByOrNull { it.track.popularity }\r\n    if (winnerTrack!=null){\r\n        println(\"the song ${winnerTrack.track.name} is most popular\")\r\n        if (artists.get(0).name==winnerTrack.name) counter1++\r\n        else counter2++\r\n    }\r\n\r\n    if (counter1>counter2){\r\n        println(\"the ${artists.get(0).name} is most popular artist\")\r\n    }\r\n\r\n    if (counter2>counter1){\r\n        println(\"the ${artists.get(1).name} is most popular artist\")\r\n    }\r\n\r\n    if (counter1==counter2){\r\n        println(\"it´s like seeging the gods of Olympus\")\r\n    }\r\n\r\n}\r\n\r\n\r\n\r\n\r\nfun main()= runBlocking {\r\n    //tokens\r\n   val token= async{ getToken()}.await()\r\n    //ids\r\n   val artistIDOne= async{getArtistID(token,\"JoseJose\")}.await()\r\n   val artistIDTwo= async{getArtistID(token,\"JuanGabriel\")}.await()\r\n    // artist data\r\n   val info1=async{getDataArtist(token,artistIDOne)}.await()\r\n   val info2=async{getDataArtist(token,artistIDTwo)}.await()\r\n\r\n   //best track\r\n   val topTrack1=async{getTopTrack(token,artistIDOne)}.await()\r\n   val topTrack2= async{getTopTrack(token,artistIDTwo)}.await()\r\n\r\n   val  job= launch{\r\n       val artistsDto=listOf<ArtistDto>(Artist.toArtistDto(info1,topTrack1),Artist.toArtistDto(info2,topTrack2))\r\n       comparateArtist(artistsDto)\r\n   }\r\n\r\n   job.join()\r\n}"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/php/miguelex.php",
    "content": "<?php\n\n$clientId = '';\n$clientSecret = '';\n\nfunction getAccessToken() {\n    global $clientId, $clientSecret;\n    \n    $auth = base64_encode($clientId . ':' . $clientSecret);\n    $options = [\n        'http' => [\n            'header' => \"Content-Type: application/x-www-form-urlencoded\\r\\n\" .\n                        \"Authorization: Basic \" . $auth . \"\\r\\n\",\n            'method'  => 'POST',\n            'content' => http_build_query(['grant_type' => 'client_credentials']),\n        ]\n    ];\n    \n    $context  = stream_context_create($options);\n    $result = file_get_contents('https://accounts.spotify.com/api/token', false, $context);\n    \n    if ($result === FALSE) {\n        die('Error getting access token.');\n    }\n    \n    $data = json_decode($result, true);\n    return $data['access_token'];\n}\n\nfunction getArtistData($token, $artistName) {\n    $artistName = urlencode($artistName);\n    $options = [\n        'http' => [\n            'header' => \"Authorization: Bearer \" . $token . \"\\r\\n\",\n            'method'  => 'GET',\n        ]\n    ];\n\n    $context  = stream_context_create($options);\n    $result = file_get_contents(\"https://api.spotify.com/v1/search?q=$artistName&type=artist\", false, $context);\n    \n    if ($result === FALSE) {\n        die('Error getting artist data.');\n    }\n    \n    $data = json_decode($result, true);\n    return $data['artists']['items'][0];  \n}\n\nfunction getArtistStats($artistId, $token) {\n    $options = [\n        'http' => [\n            'header' => \"Authorization: Bearer \" . $token . \"\\r\\n\",\n            'method'  => 'GET',\n        ]\n    ];\n\n    $context  = stream_context_create($options);\n    $result = file_get_contents(\"https://api.spotify.com/v1/artists/$artistId\", false, $context);\n    \n    if ($result === FALSE) {\n        die('Error getting artist stats.');\n    }\n    \n    $data = json_decode($result, true);\n    return [\n        'name' => $data['name'],\n        'followers' => $data['followers']['total'],\n        'popularity' => $data['popularity'],\n        'genres' => $data['genres'],\n    ];\n}\n\nfunction getArtistTopTracks($artistId, $token) {\n    $options = [\n        'http' => [\n            'header' => \"Authorization: Bearer \" . $token . \"\\r\\n\",\n            'method'  => 'GET',\n        ]\n    ];\n\n    $context  = stream_context_create($options);\n    $result = file_get_contents(\"https://api.spotify.com/v1/artists/$artistId/top-tracks?market=US\", false, $context);\n    \n    if ($result === FALSE) {\n        die('Error getting top tracks.');\n    }\n    \n    $data = json_decode($result, true);\n    $mostPopularTrack = $data['tracks'][0];  \n    return [\n        'name' => $mostPopularTrack['name'],\n        'playCount' => $mostPopularTrack['popularity'], \n        'album' => $mostPopularTrack['album']['name']\n    ];\n}\n\nfunction compareBands($band1, $band2) {\n    $token = getAccessToken();\n    \n    $band1Data = getArtistData($token, $band1);\n    $band2Data = getArtistData($token, $band2);\n    \n    $band1Stats = getArtistStats($band1Data['id'], $token);\n    $band2Stats = getArtistStats($band2Data['id'], $token);\n    \n    $band1TopTrack = getArtistTopTracks($band1Data['id'], $token);\n    $band2TopTrack = getArtistTopTracks($band2Data['id'], $token);\n    \n    echo \"\\n{$band1} Stats:\\n\";\n    print_r($band1Stats);\n    echo \"Canción más popular de {$band1}: \";\n    print_r($band1TopTrack);\n    \n    echo \"\\n{$band2} Stats:\\n\";\n    print_r($band2Stats);\n    echo \"Canción más popular de {$band2}: \";\n    print_r($band2TopTrack);\n    \n    $moreFollowers = ($band1Stats['followers'] > $band2Stats['followers'])\n        ? $band1\n        : $band2;\n    \n    $morePopularTrack = ($band1TopTrack['playCount'] > $band2TopTrack['playCount'])\n        ? $band1\n        : $band2;\n    \n    echo \"\\nLa banda con más seguidores es: {$moreFollowers}\\n\";\n    echo \"La banda con la canción más popular es: {$morePopularTrack}\\n\";\n}\n\necho \"Introduce el nombre del primer grupo: \";\n$band1 = trim(fgets(STDIN));\n\necho \"Introduce el nombre del segundo grupo: \";\n$band2 = trim(fgets(STDIN));\n\ncompareBands($band1, $band2);"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/python/CesarCarmona30.py",
    "content": "import os\nimport requests\nfrom dotenv import load_dotenv\n\nload_dotenv()\n\n# Spotify API credentials\nCLIENT_ID = os.getenv(\"SPOTIFY_CLIENT_ID\")\nCLIENT_SECRET = os.getenv(\"SPOTIFY_CLIENT_SECRET\")\n\ndef get_token():\n  \"\"\" Obtener el token de OAuth de Spotify API \"\"\"\n  url = 'https://accounts.spotify.com/api/token'\n  data = {\n    'grant_type': 'client_credentials'\n  }\n  response = requests.post(url, data=data, auth=(CLIENT_ID, CLIENT_SECRET))\n  token = response.json().get(\"access_token\")\n  return token\n\ndef get_artist_data(artist_id, token):\n  \"\"\" Obtener los datos de un artista de Spotify \"\"\"\n  url = f'https://api.spotify.com/v1/artists/{artist_id}'\n  headers = {\n    'Authorization': f'Bearer {token}'\n  }\n  response = requests.get(url, headers=headers)\n  return response.json()\n\ndef get_artist_top_tracks(artist_id, token):\n  \"\"\" Obtener las canciones más populares de un artista \"\"\"\n  url = f'https://api.spotify.com/v1/artists/{artist_id}/top-tracks?market=US'\n  headers = {\n    'Authorization': f'Bearer {token}'\n  }\n  response = requests.get(url, headers=headers)\n  return response.json()\n\ndef compare_stat(oasis_stat, lp_stat, label, unit='', score=(0, 0), is_track=False):\n  \"\"\"Comparar estadísticas entre Oasis y Linkin Park y actualizar el marcador\"\"\"\n  print(f\"> {label}\")\n\n  if is_track:\n    oasis_track, oasis_popularity = oasis_stat\n    lp_track, lp_popularity = lp_stat\n    print(f\"    Oasis: \\\"{oasis_track}\\\" con {oasis_popularity}{unit}\")\n    print(f\"    Linkin Park: \\\"{lp_track}\\\" con {lp_popularity}{unit}\")\n  else:\n    print(f\"    Oasis: {oasis_stat}{unit}\")\n    print(f\"    Linkin Park: {lp_stat}{unit}\")\n\n  oasis_score, linkin_park_score = score\n\n  # Comparar por popularidad si es una canción, o directamente los valores si no es canción\n  if (is_track and oasis_stat[1] > lp_stat[1]) or (not is_track and oasis_stat > lp_stat):\n    oasis_score += 1\n  else:\n    linkin_park_score += 1\n\n  print(f\"Oasis {oasis_score} - Linkin Park {linkin_park_score}\\n\")\n  return oasis_score, linkin_park_score\n\ndef compare_bands():\n  token = get_token()\n\n  oasis_id = '2DaxqgrOhkeH0fpeiQq2f4'\n  linkin_park_id = '6XyY86QOPPrYVGvF9ch6wz'\n\n  # Obtener datos de ambas bandas\n  oasis_data = get_artist_data(oasis_id, token)\n  linkin_park_data = get_artist_data(linkin_park_id, token)\n\n  # Obtener las canciones más populares de ambas bandas\n  oasis_top_tracks = get_artist_top_tracks(oasis_id, token)\n  linkin_park_top_tracks = get_artist_top_tracks(linkin_park_id, token)\n\n  oasis_score = 0\n  linkin_park_score = 0\n\n  # Formatear datos\n  oasis_followers = f\"{oasis_data.get('followers', {}).get('total'):,}\"\n  oasis_popularity = oasis_data.get(\"popularity\")\n  oasis_top_track = (oasis_top_tracks['tracks'][0]['name'], oasis_top_tracks['tracks'][0]['popularity'])\n    \n  linkin_park_followers = f\"{linkin_park_data.get('followers', {}).get('total'):,}\"\n  linkin_park_popularity = linkin_park_data.get(\"popularity\")\n  linkin_park_top_track = (linkin_park_top_tracks['tracks'][0]['name'], linkin_park_top_tracks['tracks'][0]['popularity'])\n\n  # Comparar seguidores\n  print(\"Oasis vs Linkin Park\\n\")\n  oasis_score, linkin_park_score = compare_stat(oasis_followers, linkin_park_followers, \"Seguidores\", \"\", (oasis_score, linkin_park_score))\n\n  # Comparar popularidad\n  oasis_score, linkin_park_score = compare_stat(oasis_popularity, linkin_park_popularity, \"Popularidad\", \"/100 pts.\", (oasis_score, linkin_park_score))\n\n  # Comparar canciones más populares (usando tuplas para nombre y popularidad)\n  oasis_score, linkin_park_score = compare_stat(oasis_top_track, linkin_park_top_track, \"Canción más popular\", \"/100 pts.\", (oasis_score, linkin_park_score), is_track=True)\n\n  # Determinar la banda más popular\n  print(f\"BANDA MÁS POPULAR: {'Oasis' if oasis_score > linkin_park_score else 'Linkin Park'}\")\n\nif __name__ == \"__main__\":\n  compare_bands()"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/python/DavidVilem.py",
    "content": "import spotipy\r\nfrom spotipy.oauth2 import SpotifyClientCredentials\r\n\r\n# Reemplaza con tus credenciales\r\nclient_id = '****'\r\nclient_secret = '****'\r\n\r\n# Autenticación\r\nauth_manager = SpotifyClientCredentials(client_id=client_id, client_secret=client_secret)\r\nsp = spotipy.Spotify(auth_manager=auth_manager)\r\n\r\n# Funciones definidas\r\ndef obtener_id_artista(sp, nombre_artista):\r\n    resultado = sp.search(q=f'artist:\"{nombre_artista}\"', type='artist')\r\n    if resultado['artists']['items']:\r\n        return resultado['artists']['items'][0]['id']\r\n    else:\r\n        print(f\"No se encontró el artista: {nombre_artista}\")\r\n        return None\r\n\r\ndef obtener_info_artista(sp, artista_id):\r\n    return sp.artist(artista_id)\r\n\r\ndef obtener_cancion_mas_popular(sp, artista_id, pais='US'):\r\n    top_tracks = sp.artist_top_tracks(artista_id, country=pais)\r\n    if top_tracks['tracks']:\r\n        return top_tracks['tracks'][0]\r\n    else:\r\n        print(\"No se encontraron canciones top para este artista.\")\r\n        return None\r\n\r\ndef obtener_numero_albumes(sp, artista_id):\r\n    albums = sp.artist_albums(artista_id, album_type='album')\r\n    return len(albums['items'])\r\n\r\ndef comparar_metricas(artistas, metrica):\r\n    artista1, artista2 = list(artistas.keys())\r\n    puntos = {artista1: 0, artista2: 0}\r\n    \r\n    valor1 = artistas[artista1][metrica]\r\n    valor2 = artistas[artista2][metrica]\r\n    \r\n    if valor1 > valor2:\r\n        puntos[artista1] = 1\r\n        print(f\"{artista1} gana en {metrica.replace('_', ' ')}.\")\r\n    elif valor2 > valor1:\r\n        puntos[artista2] = 1\r\n        print(f\"{artista2} gana en {metrica.replace('_', ' ')}.\")\r\n    else:\r\n        print(f\"Empate en {metrica.replace('_', ' ')}.\")\r\n    \r\n    return puntos\r\n\r\ndef comparar_popularidad_cancion(artistas):\r\n    artista1, artista2 = list(artistas.keys())\r\n    puntos = {artista1: 0, artista2: 0}\r\n    \r\n    valor1 = artistas[artista1]['cancion_popular']['popularidad']\r\n    valor2 = artistas[artista2]['cancion_popular']['popularidad']\r\n    \r\n    if valor1 > valor2:\r\n        puntos[artista1] = 1\r\n        print(f\"{artista1} tiene la canción más popular.\")\r\n    elif valor2 > valor1:\r\n        puntos[artista2] = 1\r\n        print(f\"{artista2} tiene la canción más popular.\")\r\n    else:\r\n        print(\"Empate en popularidad de la canción más popular.\")\r\n    \r\n    return puntos\r\n\r\n# Lista de artistas a comparar\r\nartistas = {\r\n    'Oasis': {},\r\n    'Linkin Park': {}\r\n}\r\n\r\n# Obtener datos de cada artista\r\nfor nombre_artista in artistas.keys():\r\n    artista_id = obtener_id_artista(sp, nombre_artista)\r\n    if artista_id:\r\n        info = obtener_info_artista(sp, artista_id)\r\n        cancion_popular = obtener_cancion_mas_popular(sp, artista_id)\r\n        numero_albumes = obtener_numero_albumes(sp, artista_id)\r\n        \r\n        artistas[nombre_artista]['id'] = artista_id\r\n        artistas[nombre_artista]['seguidores'] = info['followers']['total']\r\n        artistas[nombre_artista]['popularidad'] = info['popularity']\r\n        artistas[nombre_artista]['cancion_popular'] = {\r\n            'nombre': cancion_popular['name'],\r\n            'popularidad': cancion_popular['popularity']\r\n        }\r\n        artistas[nombre_artista]['numero_albumes'] = numero_albumes\r\n    else:\r\n        print(f\"No se pudieron obtener datos para {nombre_artista}.\")\r\n\r\n# Mostrar la información recopilada\r\nfor nombre_artista, datos in artistas.items():\r\n    print(f\"\\n{nombre_artista} tiene {datos['seguidores']} seguidores y una popularidad de {datos['popularidad']}.\")\r\n    print(f\"La canción más popular de {nombre_artista} es '{datos['cancion_popular']['nombre']}' con una popularidad de {datos['cancion_popular']['popularidad']}.\")\r\n    print(f\"{nombre_artista} tiene {datos['numero_albumes']} álbumes.\")\r\n\r\n# Comparación y asignación de puntos\r\nmetricas = ['seguidores', 'popularidad', 'numero_albumes']\r\npuntos_totales = {artista: 0 for artista in artistas.keys()}\r\n\r\n# Comparación de seguidores\r\npuntos = comparar_metricas(artistas, 'seguidores')\r\nfor artista in puntos_totales:\r\n    puntos_totales[artista] += puntos[artista]\r\n\r\n# Comparación de popularidad general\r\npuntos = comparar_metricas(artistas, 'popularidad')\r\nfor artista in puntos_totales:\r\n    puntos_totales[artista] += puntos[artista]\r\n\r\n# Comparación de popularidad de la canción más popular\r\npuntos = comparar_popularidad_cancion(artistas)\r\nfor artista in puntos_totales:\r\n    puntos_totales[artista] += puntos[artista]\r\n\r\n# Comparación de número de álbumes\r\npuntos = comparar_metricas(artistas, 'numero_albumes')\r\nfor artista in puntos_totales:\r\n    puntos_totales[artista] += puntos[artista]\r\n\r\n# Mostrar la puntuación final y el ganador\r\nprint(f\"\\nPuntuación final:\")\r\nfor artista, puntos in puntos_totales.items():\r\n    print(f\"{artista}: {puntos} puntos\")\r\n\r\n# Determinar el ganador\r\nartista1, artista2 = list(artistas.keys())\r\nif puntos_totales[artista1] > puntos_totales[artista2]:\r\n    print(f\"\\n¡{artista1} es la banda más popular!\")\r\nelif puntos_totales[artista2] > puntos_totales[artista1]:\r\n    print(f\"\\n¡{artista2} es la banda más popular!\")\r\nelse:\r\n    print(\"\\nAmbas bandas son igual de populares\")\r\n"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/python/EmmanuelMMontesinos.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * ¡Dos de las bandas más grandes de la historia están de vuelta!\n * Oasis y Linkin Park han anunciado nueva gira, pero, ¿quién es más popular?\n * Desarrolla un programa que se conecte al API de Spotify y los compare.\n * Requisitos:\n * 1. Crea una cuenta de desarrollo en https://developer.spotify.com.\n * 2. Conéctate al API utilizando tu lenguaje de programación.\n * 3. Recupera datos de los endpoint que tú quieras.\n * Acciones:\n * 1. Accede a las estadísticas de las dos bandas.\n *    Por ejemplo: número total de seguidores, escuchas mensuales,\n *    canción con más reproducciones...\n * 2. Compara los resultados de, por lo menos, 3 endpoint.\n * 3. Muestra todos los resultados por consola para notificar al usuario.\n * 4. Desarrolla un criterio para seleccionar qué banda es más popular.\n */\n\"\"\"\nimport spotipy\nfrom spotipy.oauth2 import SpotifyClientCredentials\n\n# Datos de tu cuenta Spotify Developer\nAPI_ID = 'TU_PUBLIC_ID'\nAPI_KEY = 'TU_SECRET_KEY'\n\ncredenciales = SpotifyClientCredentials(client_id=API_ID, client_secret=API_KEY)\napi = spotipy.Spotify(client_credentials_manager=credenciales)\n\n# Accede a las estadísticas de las dos bandas.\nclass Grupo:\n    def __init__(self,nombre) -> None:\n        self.nombre = nombre\n        try:\n            self.resultado = api.search(self.nombre, type='artist')\n            self.id = self.resultado[\"artists\"][\"items\"][0][\"id\"]\n            self.top_canciones = api.artist_top_tracks(self.id,country='es')\n            \n            seguidores = api.artist(self.id)\n            self.seguidores = seguidores['followers']['total']\n            self.registro = {}\n            check = 0\n            self.popular = 0\n            self.cancion_top = (self.top_canciones['tracks'][0]['name'],self.top_canciones['tracks'][0]['popularity'])\n            for track in self.top_canciones['tracks']:\n                if check == 5:\n                    break\n                else:\n                    check += 1\n                    track_id = track['id']\n                    track_name = track['name']\n                    track_info = api.track(track_id)\n                    self.popular += int(track_info['popularity'])\n                    self.registro[track_name] = track_info['popularity']\n\n            self.popular /= 5\n                \n        except Exception as e:\n            print(f\"El grupo {self.nombre} no existe\\nError: {e}\")\n\n    # Muestra todos los resultados por consola para notificar al usuario\n    def mostrar_resultado(self):\n        print(\"-\"*10)\n        print(f\"{self.nombre.upper()}\")\n        print(f\"{self.seguidores} seguidores : {self.popular} popularidad\")\n        print(\"-----TOP 5 CANCIONES-----\")\n        for cancion,rankin in self.registro.items():\n            print(f\"{cancion} : {rankin} popularidad\")\n        print(\"-\"*20)\n        print()\n            \n\n# Compara los resultados de, por lo menos, 3 endpoint\ndef comparar_grupos(grupo1, grupo2):\n    puntuacion_1 = 0\n    puntuacion_2 = 0\n\n    # Desarrolla un criterio para seleccionar qué banda es más popular\n    print(\"Criterios de puntuación:\")\n    print(\"1. Seguidores\")\n    print(\"2. Popularidad\")\n    print(\"3. Popularidad de canción más escuchada\")\n    print()\n    print(\"-\"*10)\n    # Seguidores\n    if grupo1.seguidores > grupo2.seguidores:\n        puntuacion_1 += 1\n        print(f\"{grupo1.nombre} es más seguido que {grupo2.nombre}\")\n    elif grupo1.seguidores < grupo2.seguidores:\n        puntuacion_2 += 1\n        print(f\"{grupo2.nombre} es más seguido que {grupo1.nombre}\")\n    # Popularidad\n    if grupo1.popular > grupo2.popular:\n        puntuacion_1 += 1\n        print(f\"{grupo1.nombre} es más popular que {grupo2.nombre}\")\n    elif grupo1.popular < grupo2.popular:\n        puntuacion_2 += 1\n        print(f\"{grupo2.nombre} es más popular que {grupo1.nombre}\")\n    # Canción mas escuchada\n    if grupo1.cancion_top[1] > grupo2.cancion_top[1]:\n        puntuacion_1 += 1\n        print(f\"{grupo1.cancion_top[0]} es más popular que {grupo2.cancion_top[0]}\")\n    elif grupo1.cancion_top[1] < grupo2.cancion_top[1]:\n        puntuacion_2 += 1\n        print(f\"{grupo2.cancion_top[0]} es más popular que {grupo1.cancion_top[0]}\")\n\n    print()\n    print(\"-\"*10)\n\n    if puntuacion_1 > puntuacion_2:\n        print(f\"{grupo1.nombre} es más popular\")\n    elif puntuacion_1 < puntuacion_2:\n        print(f\"{grupo2.nombre} es más popular\")\n    else:\n        print(\"Los grupos tienen la misma puntuación\")\n        \n\n    \n# Prueba\noasis = Grupo('Oasis')\nlinkin = Grupo('Linkin Park')\n\noasis.mostrar_resultado()\nlinkin.mostrar_resultado()\n\ncomparar_grupos(oasis,linkin)"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/python/Gordo-Master.py",
    "content": "import requests\nimport env\n\nCLIENT_ID = env.CLIENT_ID\nCLIENT_SECRET = env.CLIENT_SECRET\n\ndef get_token():\n    url = \"https://accounts.spotify.com/api/token\"\n    header = {\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n    }\n    data = {\"grant_type\" : \"client_credentials\",\n            \"client_id\": CLIENT_ID,\n            \"client_secret\" : CLIENT_SECRET\n            }\n\n    response = requests.post(url,headers=header, data= data)\n    if response.status_code == 200:\n        data = response.json()\n        return data[\"access_token\"]\n    else:\n        raise Exception(\"Error opteniendo el token de spotify \", response.status_code, response.text)\n\n\nclass Artist():\n    def __init__(self, name, artist_id):\n        self.name = name\n        self.artist_id = artist_id\n        self.number_followers = 0\n        self.popularity = 0\n        self.albums = []\n        self.album_url = f\"https://api.spotify.com/v1/artists/{self.artist_id}/albums?include_groups=album\"\n        self.most_populars_albums = []\n        self.top_track = {}\n    \n\n    def get_artist_data(self, access_token):\n        url = f\"https://api.spotify.com/v1/artists/{self.artist_id}\"\n        header = {\n            \"Authorization\": f\"Bearer {access_token}\"\n        }\n\n        response = requests.get(url,headers= header)\n        if response.status_code == 200:\n            return response.json()\n        else:\n            print(\"Error: \", response.status_code, response.text)\n\n    def get_albums(self,access_token,  url):\n        if url == None:\n            return\n        else:\n            header = {\n                \"Authorization\": f\"Bearer {access_token}\"\n            }\n\n            response = requests.get(url,headers= header)\n\n            if response.status_code == 200:\n                data = response.json()\n                for albums in data[\"items\"]:\n                    self.albums.append(\n                        {\n                            \"id\" : len(self.albums)+1,\n                            \"album\" : albums[\"name\"],\n                            \"album_id\": albums[\"id\"]\n                        }\n                    )\n                next_item = data[\"next\"]\n                self.get_albums(access_token, next_item)\n            else:\n                print(\"Error: \", response.status_code, response.text)\n\n    def get_album_popularity(self,access_token, id):\n        url = f\"https://api.spotify.com/v1/albums/{id}\"\n        header = {\n                \"Authorization\": f\"Bearer {access_token}\"\n            }\n        response = requests.get(url,headers= header)\n\n        if response.status_code == 200:\n            return response.json()\n        else:\n            print(\"Error: \", response.status_code, response.text)\n    \n    def get_top_track(self, access_token):\n\n        url = f\"https://api.spotify.com/v1/artists/{self.artist_id}/top-tracks\"\n        headers = {\"Authorization\": f\"Bearer {access_token}\"}\n\n        response = requests.get(url, headers=headers)\n        if response.status_code != 200:\n            raise Exception(\n                f\"Error obteniendo las canciones del artista: {response.json()}.\"\n            )\n\n        results = response.json()\n\n        top_track = max(results[\"tracks\"], key=lambda track: track[\"popularity\"])\n\n        return {\n            \"name\": top_track[\"name\"],\n            \"popularity\": top_track[\"popularity\"]\n        }\n\n    def print_profile(self):\n        print(f\"Perfil de : {self.name}\")\n        print(f\"Numero de seguidores: {self.number_followers}\")\n        print(f\"Popularidad: {self.popularity}\")\n        print(f\"Los albumes mas populares: \")\n        # print(json.dumps(self.most_populars_albums,indent=4))\n        # print(f\"El top tracks: \")\n        print(self.top_track)\n\n\ndef three_most_popular(albums: list):\n    albums.sort(key = lambda x: x[\"Popularity\"], reverse= True)\n    return albums[0],albums[1],albums[2]\n\ndef make_artist_profile(artist: Artist, access_token):\n    url = artist.album_url\n    artist.get_albums(access_token, url)\n\n    for album in artist.albums:\n        data = artist.get_album_popularity(access_token, album[\"album_id\"])\n        album[\"Popularity\"] = data[\"popularity\"]\n\n    for album in three_most_popular(artist.albums):\n        artist.most_populars_albums.append(\n            {\n                \"name\": album[\"album\"],\n                \"Popularity\" : album[\"Popularity\"]\n            }\n        )\n\n    data_2 = artist.get_artist_data(access_token)\n    artist.number_followers = data_2[\"followers\"][\"total\"]\n    artist.popularity = data_2[\"popularity\"]\n    artist.top_track = artist.get_top_track(access_token)\n\ndef search_artist(access_token: str, name: str):\n    url = f\"https://api.spotify.com/v1/search?q={name}&type=artist&limit=1\"\n    headers = {\"Authorization\": f\"Bearer {access_token}\"}\n\n    response = requests.get(url, headers=headers)\n    if response.status_code != 200:\n        raise Exception(\n            f\"Error obteniendo el artista: {response.json()}.\"\n        )\n\n    results = response.json()\n    if results[\"artists\"][\"items\"]:\n        return results[\"artists\"][\"items\"][0][\"id\"]\n    else:\n        raise Exception(\n            f\"El artista {name} no se ha encontrado.\"\n        )\n\ndef main():\n    access_token = get_token()\n    artist_1 = Artist(\"Linkin Park\", search_artist(access_token, \"Linkin Park\"))\n    artist_2 = Artist(\"Oasis\", search_artist(access_token, \"Oasis\"))\n    make_artist_profile(artist_1, access_token)\n    make_artist_profile(artist_2, access_token)\n    # linkin_park.print_profile()\n    # oasis.print_profile()\n    artist_1_counter = 0\n    artist_2_counter = 0\n    print(f\"\\nComparación de artistas:\\n\")\n    print(f\"{artist_1.name}\")\n    print(f\"{artist_2.name}\")\n\n    # Seguidores\n    print(f\"\\nComparación seguidores:\\n\")\n    print(f\"Seguidores {artist_1.name}: {artist_1.number_followers}\")\n    print(f\"Seguidores {artist_2.name}: {artist_2.number_followers}\")\n    if artist_1.number_followers > artist_2.number_followers:\n        print(f\"{artist_1.name} es más popular en número de seguidores.\")\n        artist_1_counter += 1\n    else:\n        print(f\"{artist_2.name} es más popular en número de seguidores.\")\n        artist_2_counter += 1\n    \n    # Popularidad\n    print(f\"\\nComparación popularidad:\\n\")\n    print(f\"Popularidad {artist_1.name}: {artist_1.popularity}\")\n    print(f\"Popularidad {artist_2.name}: {artist_2.popularity}\")\n\n    if artist_1.popularity > artist_2.popularity:\n        print(f\"{artist_1.name} es más popular a nivel general.\")\n        artist_1_counter += 1\n    else:\n        print(f\"{artist_2.name} es más popular a nivel general.\")\n        artist_2_counter += 1\n    \n    # Cancion\n    print(f\"\\nComparación canción:\\n\")\n    print(\n        f\"Canción {artist_1.top_track[\"name\"]} ({artist_1.name}): {artist_1.top_track[\"popularity\"]} popularidad.\")\n    print(\n        f\"Canción {artist_2.top_track[\"name\"]} ({artist_2.name}): {artist_2.top_track[\"popularity\"]} popularidad.\")\n\n    if artist_1.top_track[\"popularity\"] > artist_2.top_track[\"popularity\"]:\n        print(\n            f\"La canción {artist_1.top_track[\"name\"]} de {artist_1.name} es más popular.\")\n        artist_1_counter += 1\n    else:\n        print(\n            f\"La canción {artist_2.top_track[\"name\"]} de {artist_2.name} es más popular.\")\n        artist_2_counter += 1\n\n    # Resultado\n    print(f\"\\nResultado final:\\n\")\n    print(\n        f\"{artist_1.name if artist_1_counter > artist_2_counter else artist_2.name} es más popular.\")\n\nif __name__ == \"__main__\":\n    main()"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/python/JUANPPDEV.PY",
    "content": "\"\"\"\n * EJERCICIO:\n * ¡Dos de las bandas más grandes de la historia están de vuelta!\n * Oasis y Linkin Park han anunciado nueva gira, pero, ¿quién es más popular?\n * Desarrolla un programa que se conecte al API de Spotify y los compare.\n * Requisitos:\n * 1. Crea una cuenta de desarrollo en https://developer.spotify.com.\n * 2. Conéctate al API utilizando tu lenguaje de programación.\n * 3. Recupera datos de los endpoint que tú quieras.\n * Acciones:\n * 1. Accede a las estadísticas de las dos bandas.\n *    Por ejemplo: número total de seguidores, escuchas mensuales,\n *    canción con más reproducciones...\n * 2. Compara los resultados de, por lo menos, 3 endpoint.\n * 3. Muestra todos los resultados por consola para notificar al usuario.\n * 4. Desarrolla un criterio para seleccionar qué banda es más popular.\n\"\"\"\n\nimport spotipy\nfrom spotipy.oauth2 import SpotifyClientCredentials\n\n# Configura tus credenciales\nclient_id = 'TU_CLIENT_ID'\nclient_secret = 'TU_CLIENT_SECRET'\n\n# Autenticación\nsp = spotipy.Spotify(auth_manager=SpotifyClientCredentials(client_id=client_id, client_secret=client_secret))\n\n# Función para obtener estadísticas de una banda\ndef obtener_estadisticas(artista):\n    resultados = sp.search(q='artist:' + artista, type='artist')\n    artista_info = resultados['artists']['items'][0]\n    seguidores = artista_info['followers']['total']\n    popularidad = artista_info['popularity']\n    top_tracks = sp.artist_top_tracks(artista_info['id'])\n    cancion_mas_popular = top_tracks['tracks'][0]['name']\n    reproducciones_cancion_mas_popular = top_tracks['tracks'][0]['popularity']\n    \n    return {\n        'seguidores': seguidores,\n        'popularidad': popularidad,\n        'cancion_mas_popular': cancion_mas_popular,\n        'reproducciones_cancion_mas_popular': reproducciones_cancion_mas_popular\n    }\n\n# Obtener estadísticas de Oasis y Linkin Park\nestadisticas_oasis = obtener_estadisticas('Oasis')\nestadisticas_linkin_park = obtener_estadisticas('Linkin Park')\n\n# Comparar resultados\nprint(\"Estadísticas de Oasis:\", estadisticas_oasis)\nprint(\"Estadísticas de Linkin Park:\", estadisticas_linkin_park)\n\n# Criterio para determinar la banda más popular\nif estadisticas_oasis['seguidores'] > estadisticas_linkin_park['seguidores']:\n    print(\"Oasis es más popular en términos de seguidores.\")\nelse:\n    print(\"Linkin Park es más popular en términos de seguidores.\")\n\nif estadisticas_oasis['popularidad'] > estadisticas_linkin_park['popularidad']:\n    print(\"Oasis es más popular en términos de popularidad.\")\nelse:\n    print(\"Linkin Park es más popular en términos de popularidad.\")\n\nif estadisticas_oasis['reproducciones_cancion_mas_popular'] > estadisticas_linkin_park['reproducciones_cancion_mas_popular']:\n    print(\"Oasis tiene la canción más popular.\")\nelse:\n    print(\"Linkin Park tiene la canción más popular.\")\n\n\n\"\"\"\nExplicación\n1. Autenticación: Utilizamos SpotifyClientCredentials para autenticar nuestra aplicación.\n2. Obtener estadísticas: La función obtener_estadisticas busca al artista, obtiene su número de seguidores, popularidad y la canción más popular.\n3. Comparar resultados: Comparamos las estadísticas de Oasis y Linkin Park y mostramos los resultados en la consola.\n\"\"\""
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/python/JesusWay69.py",
    "content": "import os, platform, spotipy, credentials\nfrom spotipy.oauth2 import SpotifyClientCredentials\n\n\nif (platform.platform().startswith(\"macOS\") or platform.platform().startswith(\"Linux\")):\n    os.system('clear')\nelse:\n    os.system('cls')\n\n\"\"\"* EJERCICIO:\n * Oasis y Linkin Park han anunciado nueva gira, pero, ¿quién es más popular?\n * ¡Dos de las bandas más grandes de la historia están de vuelta!\n * Desarrolla un programa que se conecte al API de Spotify y los compare.\n * Requisitos:\n * 1. Crea una cuenta de desarrollo en https://developer.spotify.com.\n * 2. Conéctate al API utilizando tu lenguaje de programación.\n * 3. Recupera datos de los endpoint que tú quieras.\n * Acciones:\n * 1. Accede a las estadísticas de las dos bandas.\n *    Por ejemplo: número total de seguidores, escuchas mensuales,\n *    canción con más reproducciones...\n * 2. Compara los resultados de, por lo menos, 3 endpoint.\n * 3. Muestra todos los resultados por consola para notificar al usuario.\n * 4. Desarrolla un criterio para seleccionar qué banda es más popular.\"\"\"\n\nclient_ID = credentials.client_ID #clave de cliente propia de 32 caracteres\nsecret_ID = credentials.secret_ID #clave secreta propia de 32 caracteres\n\nccm = SpotifyClientCredentials(client_id=client_ID, client_secret=secret_ID)\nsp = spotipy.Spotify(client_credentials_manager=ccm)\n\n\ndef get_artist(artist_name:str)->object:\n    artist = sp.search(q=artist_name, limit=1, type=\"artist\", offset=0)\n    if artist == None:\n        return f\"El artista {artist_name} no existe\"\n    return artist\n\ndef get_artist_stats(artist:object)->tuple:\n    total_popularity_songs = 0\n    artist_id = artist[\"artists\"][\"items\"][0][\"id\"]\n    top_songs = sp.artist_top_tracks(artist_id)\n    artist_name = artist[\"artists\"][\"items\"][0][\"name\"]\n    artist_followers = artist[\"artists\"][\"items\"][0][\"followers\"][\"total\"]\n    popularity_level = artist[\"artists\"][\"items\"][0][\"popularity\"]\n    for song in top_songs[\"tracks\"]:\n        total_popularity_songs = total_popularity_songs + song[\"popularity\"]\n\n    return artist_name, artist_followers, popularity_level, total_popularity_songs\n\ndef print_top_songs(artist:object): \n    artist = artist[\"artists\"][\"items\"][0]\n    print(f\"\\nCanciones más populares de {artist[\"name\"]}\")\n    print(\"************************************************\")\n    print('{:<30}'.format(\"   TITULO\"), \"PUNTUACIÓN\")\n    top_songs = sp.artist_top_tracks(artist[\"id\"])\n    for song in top_songs[\"tracks\"]:\n        song_name = song[\"name\"].split(\" - \")\n        print(\"- \",'{:<30}'.format(song_name[0]), song[\"popularity\"])\n        \n\ndef print_artist_stats(artist:object):\n    artist = artist[\"artists\"][\"items\"][0]\n    print (f\"\"\"\\nNombre del artista: {artist[\"name\"]}\nGénero musical: {artist[\"genres\"][0]}/{artist[\"genres\"][1]}\nNúmero de followers: {artist[\"followers\"][\"total\"]}\nNivel de popularidad: {artist[\"popularity\"]}\"\"\")\n\ndef print_albums(artist:object):\n    artist = artist[\"artists\"][\"items\"][0]\n    print(f\"\\nDiscografía de {artist[\"name\"]}:\")\n    print(\"**********************************************************************************\")\n    print('{:<63}'.format(\"  TITULO\"), \"AÑO DE LANZAMIENTO\")\n    albums = sp.artist_albums(artist[\"id\"], album_type=\"album\",offset=0, limit=30)\n    for album in albums[\"items\"]:\n        print(f\"- \" '{:<63}'.format(album[\"name\"]), album[\"release_date\"][:4])\n\ndef compare(artist1:object, artist2:object):\n    name1, followers1, popularity1, popularity_songs1 = get_artist_stats(artist1)\n    name2, followers2, popularity2, popularity_songs2 = get_artist_stats(artist2)\n\n    print(f\"\\n{name1} tiene {followers1} seguidores y su índice de popularidad es de {popularity1} puntos.\")\n    print(f\"\\n{name2} tiene {followers2} seguidores y su índice de popularidad es de {popularity2} puntos.\")\n    print(f\"\\nLa suma de la puntuación por escuchas de las 10 mejores canciones de {name1} es de: {popularity_songs1} puntos.\")\n    print(f\"\\nLa suma de la puntuación por escuchas de las 10 mejores canciones de {name2} es de: {popularity_songs2} puntos.\")\n\n    if followers1 > followers2 and popularity1 > popularity2:\n        print(f\"\\n{name1} tiene más seguidores e índice de popularidad que {name2}\")\n        if popularity_songs1 > popularity_songs2:\n            print(f\"Además {name1} acumula más puntos que {name2} en las escuchas de sus 10 mejores canciones...\")\n            print(f\"\\n..por lo tanto el ganador claro es: {name1.upper()}\")\n        elif popularity_songs1 == popularity_songs2:\n            print(f\"En puntuación acumulada de las escuchas de sus 10 mejores canciones están empatados..\")\n            print(f\"\\n..aun así el ganador es: {name1.upper()}\")\n        else:\n            print(f\"{name2} tiene mejor puntuación en sus 10 mejores canciones pero {name1} ha ganado en todo lo demás..\")\n            print(f\"\\n...por lo tanto el ganador es: {name1.upper()}\")\n            \n    elif followers1 < followers2 and popularity1 < popularity2:\n        print(f\"\\n{name2} tiene más seguidores e índice de popularidad que {name1}\")\n        if popularity_songs1 < popularity_songs2:\n            print(f\"Además {name2} acumula más puntos que {name1} en las escuchas de sus 10 mejores canciones...\")\n            print(f\"\\n..por lo tanto el ganador claro es: {name2.upper()}\")\n        elif popularity_songs1 == popularity_songs2:\n            print(f\"En puntuación acumulada de las escuchas de sus 10 mejores canciones están empatados..\")\n            print(f\"\\n..aun así el ganador es: {name2.upper()}\")\n        else:\n            print(f\"{name1} tiene mejor puntuación en las escuchas de sus 10 mejores canciones pero {name2} ha ganado en todo lo demás..\")\n            print(f\"\\n...por lo tanto el ganador es: {name2.upper()}\")\n\n    elif followers1 > followers2 and popularity1 < popularity2:\n        print(f\"\\n{name1} tiene más seguidores que {name2} pero este tiene mejor índice de popularidad\")\n        if popularity_songs1 > popularity_songs2:\n            print(f\"{name1} acumula más puntos que {name2} en las escuchas de sus 10 mejores canciones y acumula también más seguidores...\")\n            print(f\"\\n..aunque {name2} tenga más índice de popularidad el ganador es: {name1.upper()}\")\n        elif popularity_songs1 == popularity_songs2:\n            print(f\"En puntuación acumulada de las escuchas de sus 10 mejores canciones están empatados..\")\n            print(f\"\\n..no hay un ganador claro, ambos artistas tienen estadísticas muy similares.\")\n        else:\n            print(f\"{name2} tiene mejor puntuación en las escuchas de sus 10 mejores canciones que {name1} y ha ganado también en popularidad..\")\n            print(f\"\\n...aunque {name1} tenga más seguidores el ganador es: {name2.upper()}\")\n\n    elif followers1 < followers2 and popularity1 > popularity2:\n        print(f\"\\n{name2}tiene más seguidores que {name1} pero este tiene mejor índice de popularidad\")\n        if popularity_songs1 < popularity_songs2:\n            print(f\"{name2} acumula más puntos que {name1} en las escuchas de sus 10 mejores canciones y acumula también más seguidores...\")\n            print(f\"..aunque {name1} tenga más índice de popularidad el ganador es: {name2.upper()}\")\n        elif popularity_songs1 == popularity_songs2:\n            print(f\"En puntuación acumulada de las escuchas de sus 10 mejores canciones están empatados..\")\n            print(f\"\\n..no hay un ganador claro, ambos artistas tienen estadísticas muy similares.\")\n        else:\n            print(f\"{name1} tiene mejor puntuación en las escuchas de sus 10 mejores canciones que {name2} y ha ganado también en popularidad..\")\n            print(f\"\\n...aunque {name2} tenga más seguidores el ganador es: {name1.upper()}\")\n\n    elif followers1 < followers2 and popularity1 == popularity2:\n        print(f\"\\n{name2}tiene más seguidores que {name1} pero en índice de popularidad están empatados\")\n        if popularity_songs1 < popularity_songs2:\n            print(f\"{name2} acumula más puntos que {name1} en las escuchas de sus 10 mejores canciones y acumula también más seguidores...\")\n            print(f\"..aunque ambos tengan el índice de popularidad empatado el ganador es: {name2.upper()}\")\n        elif popularity_songs1 == popularity_songs2:\n            print(f\"En puntuación acumulada de las escuchas de sus 10 mejores canciones están empatados..\")\n            print(f\"\\n..no hay un ganador claro, ambos artistas tienen estadísticas muy similares.\")\n        else:\n            print(f\"{name1} tiene mejor puntuación en las escuchas de sus 10 mejores canciones que {name2} y han empatado en popularidad..\")\n            print(f\"\\n...pero {name2} tiene más seguidores así que no hay un ganador claro.\")\n\n    elif followers1 > followers2 and popularity1 == popularity2:\n        print(f\"\\n{name1}tiene más seguidores que {name2} pero en índice de popularidad están empatado\")\n        if popularity_songs1 < popularity_songs2:\n            print(f\"{name2} acumula más puntos que {name1} en las escuchas de sus 10 mejores canciones y en popularidad están empatados...\")\n            print(f\"\\n...como {name1} tiene más seguidores no hay un ganador claro\")\n        elif popularity_songs1 == popularity_songs2:\n            print(f\"En puntuación acumulada de las escuchas de sus 10 mejores canciones están empatados..\")\n            print(f\"\\n..no hay un ganador claro, ambos artistas tienen estadísticas muy similares.\")\n        else:\n            print(f\"{name1} tiene mejor puntuación en las escuchas de sus 10 mejores canciones que {name2} y han empatado en popularidad..\")\n            print(f\"..y aunque ambos tengan el índice de popularidad empatado el ganador es: {name1.upper()}\")  \n    print()\n\n    \noasis = get_artist(\"Oasis\")\nlinkin_park = get_artist(\"Linkin park\")\n\nprint_artist_stats(linkin_park)\nprint_albums(linkin_park)\nprint_top_songs(linkin_park)\n\nprint_artist_stats(oasis)\nprint_albums(oasis)\nprint_top_songs(oasis) \n\ncompare(linkin_park, oasis)\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/python/Nicojsuarez2.py",
    "content": "# #37 OASIS VS LINKIN PARK\n> #### Dificultad: Media | Publicación: 09/09/24 | Corrección: 16/09/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * ¡Dos de las bandas más grandes de la historia están de vuelta!\n * Oasis y Linkin Park han anunciado nueva gira, pero, ¿quién es más popular?\n * Desarrolla un programa que se conecte al API de Spotify y los compare.\n * Requisitos:\n * 1. Crea una cuenta de desarrollo en https://developer.spotify.com.\n * 2. Conéctate al API utilizando tu lenguaje de programación.\n * 3. Recupera datos de los endpoint que tú quieras.\n * Acciones:\n * 1. Accede a las estadísticas de las dos bandas.\n *    Por ejemplo: número total de seguidores, escuchas mensuales,\n *    canción con más reproducciones...\n * 2. Compara los resultados de, por lo menos, 3 endpoint.\n * 3. Muestra todos los resultados por consola para notificar al usuario.\n * 4. Desarrolla un criterio para seleccionar qué banda es más popular.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/python/SooHav.py",
    "content": "# 37 - OASIS VS LINKIN PARK\n\nimport pandas as pd\nimport spotipy\nfrom spotipy.oauth2 import SpotifyOAuth\nimport os\nfrom dotenv import load_dotenv\n\n# Datos de la aplicación\nload_dotenv()\n\n# Obtener los valores del entorno\nCLIENT_ID = os.getenv(\"CLIENT_ID\")\nCLIENT_SECRET = os.getenv(\"CLIENT_SECRET\")\nREDIRECT_URI = os.getenv(\"REDIRECT_URI\")\nscope = os.getenv(\"scope\")\n\nsp = spotipy.Spotify(auth_manager=SpotifyOAuth(client_id=CLIENT_ID,\n                                               client_secret=CLIENT_SECRET,\n                                               redirect_uri=REDIRECT_URI,\n                                               scope=scope))\n\n# Clase para buscar información sobre artistas\n\n\nclass SpotifyAPI:\n    def __init__(self, sp):\n        \"\"\"Inicializa la clase con una instancia autenticada de Spotify.\"\"\"\n        self.sp = sp\n\n    def buscar_artista(self, nombre_artista):\n        \"\"\"Busca un artista por endpoint: search.\"\"\"\n        resultados = self.sp.search(q=nombre_artista, type='artist')\n        if resultados['artists']['items']:\n            return resultados['artists']['items'][0]\n        return None\n\n    def obtener_info_artista(self, artist_id):\n        \"\"\"Obtiene información detallada de un artista por endpoint: artist.\"\"\"\n        return self.sp.artist(artist_id)\n\n    def obtener_top_tracks(self, artist_uri):\n        \"\"\"Obtiene las canciones más populares por endpoint: artist_top_tracks.\"\"\"\n        top_tracks = self.sp.artist_top_tracks(artist_uri)\n        return top_tracks['tracks']\n\n    def comparar_artistas(self, artist_id1, artist_id2):\n        \"\"\"Compara dos artistas y devuelve un DataFrame.\"\"\"\n        # Buscar artistas\n        artista_1_data = self.obtener_info_artista(artist_id1)\n        artista_2_data = self.obtener_info_artista(artist_id2)\n        popularidad_artista1 = artista_1_data['popularity']\n        popularidad_artista2 = artista_2_data['popularity']\n        seguidores_artista1 = artista_1_data['followers']['total']\n        seguidores_artista2 = artista_2_data['followers']['total']\n\n        if not artista_1_data or not artista_2_data:\n            return None\n\n        data = {\n            \"Nombre\": [artista_1_data['name'], artista_2_data['name']],\n            \"Géneros\": [\", \".join(artista_1_data['genres']), \", \".join(artista_2_data['genres'])],\n            \"Popularidad\": [artista_1_data['popularity'], artista_2_data['popularity']],\n            \"Seguidores\": [artista_1_data['followers']['total'], artista_2_data['followers']['total']]\n        }\n\n        df = pd.DataFrame(data)\n\n        # Determinar cuál es más exitoso\n        if popularidad_artista1 > popularidad_artista2:\n            mensaje = f\"{artista_1_data['name']} es más popular.\"\n        elif popularidad_artista2 > popularidad_artista1:\n            mensaje = f\"{artista_2_data['name']} es más popular.\"\n        else:\n            mensaje = f\"Ambos artistas tienen la misma popularidad.\"\n        print(mensaje)\n\n        if seguidores_artista1 > seguidores_artista2:\n            mensaje = f\"{artista_1_data['name']} tiene mas seguidores.\"\n        elif seguidores_artista2 > seguidores_artista1:\n            mensaje = f\"{artista_2_data['name']} tiene mas seguidores.\"\n        else:\n            mensaje = f\"Ambos artistas tienen la misma cantidad de seguidores.\"\n        print(mensaje)\n        print()\n        return df\n\n    def comparar_top_tracks(self, artista_id1, artista_id2, num_tracks=1):\n        \"\"\"Compara los tracks más populares de dos artistas.\"\"\"\n\n        # Buscar artistas\n        artista_1 = self.obtener_info_artista(artista_id1)\n        artista_2 = self.obtener_info_artista(artista_id2)\n        nombre_real_artista1 = artista_1['name']\n        nombre_real_artista2 = artista_2['name']\n\n        if not artista_1 or not artista_2:\n            return None\n\n        # Obtener los top tracks de cada artista\n        top_tracks_artista1 = self.obtener_top_tracks(artista_1['uri'])[\n            :num_tracks]\n        top_tracks_artista2 = self.obtener_top_tracks(artista_2['uri'])[\n            :num_tracks]\n\n        cancion_mas_popular_artista1 = max(\n            top_tracks_artista1, key=lambda x: x['popularity'])\n        cancion_mas_popular_artista2 = max(\n            top_tracks_artista2, key=lambda x: x['popularity'])\n\n        # DataFrame\n        data = {\n            \"Artista\": [nombre_real_artista1, nombre_real_artista2],\n            \"Tema\": [cancion_mas_popular_artista1['name'], cancion_mas_popular_artista2['name']],\n            \"Popularidad\": [cancion_mas_popular_artista1['popularity'], cancion_mas_popular_artista2['popularity']]\n        }\n\n        df = pd.DataFrame(data)\n\n        # Artista más popular\n        if cancion_mas_popular_artista1['popularity'] > cancion_mas_popular_artista2['popularity']:\n            artista_mas_popular = nombre_real_artista1\n            mensaje = f\"{artista_mas_popular} tiene una canción más popular.\"\n        else:\n            artista_mas_popular = nombre_real_artista2\n            mensaje = f\"{artista_mas_popular} tiene una canción más popular.\"\n        print(mensaje)\n        print()\n\n        return df\n\n\n# Uso del codigo\n\nsp_api = SpotifyAPI(sp)\nprint(\"Bandas de ayer, hoy y siempre:\")\nprint(\"Hoy comparamos ...\")\nartista_nombre = \"Oasis\"\nartista = sp_api.buscar_artista(artista_nombre)\nartista_id_1 = artista['id']\nprint(artista['name'])\n\nartista_nombre = \"Linkin Park\"\nartista = sp_api.buscar_artista(artista_nombre)\nartista_id_2 = artista['id']\nprint(artista['name'])\nprint(\"De los dos concluimos que ...\")\n\n# Comparar dos artistas\ndf_comparacion = sp_api.comparar_artistas(artista_id_1, artista_id_2)\nif df_comparacion is not None:\n    print(df_comparacion)\nelse:\n    print(\"Uno o ambos artistas no fueron encontrados.\")\nprint()\n\n# Comparar los track de dos artistas\ndf_comparacion = sp_api.comparar_top_tracks(artista_id_1, artista_id_2)\nif df_comparacion is not None:\n    print(df_comparacion)\nelse:\n    print(\"Uno o ambos artistas no fueron encontrados.\")\n"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/python/bellodeveloper.py",
    "content": "# */\n#  * Enunciado\n#  * EJERCICIO:\n#  * ¡Dos de las bandas más grandes de la historia están de vuelta!\n#  * Oasis y Linkin Park han anunciado nueva gira, pero, ¿quién es más popular?\n#  * Desarrolla un programa que se conecte al API de Spotify y los compare.\n#  * Requisitos:\n#  * 1. Crea una cuenta de desarrollo en https://developer.spotify.com.\n#  * 2. Conéctate al API utilizando tu lenguaje de programación.\n#  * 3. Recupera datos de los endpoint que tú quieras.\n#  * Acciones:\n#  * 1. Accede a las estadísticas de las dos bandas.\n#  *    Por ejemplo: número total de seguidores, escuchas mensuales,\n#  *    canción con más reproducciones...\n#  * 2. Compara los resultados de, por lo menos, 3 endpoint.\n#  * 3. Muestra todos los resultados por consola para notificar al usuario.\n#  * 4. Desarrolla un criterio para seleccionar qué banda es más popular.\n#  */\n\n# Import\nimport requests\nimport base64\nfrom dotenv import load_dotenv\nimport os\n\n# Variables de entorno (fichero oculto)\nload_dotenv()\nclient_id = os.getenv('SPOTIFY_CLIENT_ID')\nclient_secret = os.getenv('SPOTIFY_CLIENT_SECRET')\n\n# URLs del API (Spotify)\nauth_url = 'https://accounts.spotify.com/api/token'\nbase_url = 'https://api.spotify.com/v1/'\n\n# Artistas que se van a comparar (Oasis y Linkin Park)\nartists = {\n    \"Oasis\": \"2DaxqgrOhkeH0fpeiQq2f4\",\n    \"Linkin Park\": \"6XyY86QOPPrYVGvF9ch6wz\"\n}\n\n# Función para obtener el token de autenticación\ndef get_token(client_id, client_secret):\n    auth_str = f\"{client_id}:{client_secret}\"\n    b64_auth_str = base64.b64encode(auth_str.encode()).decode()\n\n    headers = {\n        'Authorization': f'Basic {b64_auth_str}',\n    }\n    data = {\n        'grant_type': 'client_credentials'\n    }\n    \n    response = requests.post(auth_url, headers=headers, data=data)\n    if response.status_code != 200:\n        raise Exception(\"Error en la autenticación. Verifica tus credenciales.\")\n    \n    response_data = response.json()\n    return response_data['access_token']\n\n# Función para obtener datos del artista (Oasis y Linkin Park)\ndef get_artist_data(artist_id, token):\n    headers = {\n        'Authorization': f'Bearer {token}',\n    }\n    try:\n        artist_url = f'{base_url}artists/{artist_id}'\n        artist_data = requests.get(artist_url, headers=headers).json()\n\n        top_tracks_url = f'{base_url}artists/{artist_id}/top-tracks?market=US'\n        top_tracks_data = requests.get(top_tracks_url, headers=headers).json()\n        \n        return artist_data, top_tracks_data\n    except requests.exceptions.RequestException as e:\n        print(f\"Error al obtener datos del artista: {e}\")\n        return None, None\n\n# Función para comparar estadísticas entre los artistas (Oasis y Linkin Park)\ndef compare_artists(artists_data):\n    for artist, data in artists_data.items():\n        artist_info, top_tracks = data\n        if artist_info and top_tracks:\n            print(f\"Artista: {artist}\")\n            print(f\"Seguidores: {artist_info['followers']['total']}\")\n            print(f\"Popularidad: {artist_info['popularity']}\")\n            print(f\"Canción más popular: {top_tracks['tracks'][0]['name']} - {top_tracks['tracks'][0]['popularity']} popularidad\\n\")\n        else:\n            print(f\"No se pudo obtener datos para {artist}\")\n\n# Función principal\ndef main():\n    # Obtener el token de acceso\n    token = get_token(client_id, client_secret)\n    \n    # Obtener datos de ambos artistas\n    artists_data = {}\n    for artist_name, artist_id in artists.items():\n        artist_info, top_tracks = get_artist_data(artist_id, token)\n        artists_data[artist_name] = (artist_info, top_tracks)\n    \n    # Comparar los resultados\n    compare_artists(artists_data)\n\nif __name__ == \"__main__\":\n    main()"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/python/bereverte.py",
    "content": "import os\nimport requests\nfrom dotenv import load_dotenv\n\nload_dotenv()\n\n\ndef get_access_token():\n    client_id = os.getenv(\"SPOTIFY_CLIENT_ID\")\n    client_secret = os.getenv(\"SPOTIFY_CLIENT_SECRET\")\n\n    url = \"https://accounts.spotify.com/api/token\"\n    headers = {\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n    }\n    data = {\n        \"grant_type\": \"client_credentials\"\n    }\n    try:\n        response = requests.post(url, headers=headers, data=data, auth=(client_id, client_secret))\n        token_info = response.json()\n        return token_info['access_token']\n    \n    except Exception as e:\n        print(f\"Error obteniendo el access token: {e}\")\n        return None\n\ndef get_artist_data(artist_id, access_token):\n    url = f\"https://api.spotify.com/v1/artists/{artist_id}\"\n    headers = {\"Authorization\": f\"Bearer {access_token}\"}\n    \n    try:\n        response = requests.get(url, headers=headers)\n        artist_data = response.json()\n        \n        followers = artist_data['followers']['total']\n        popularity = artist_data['popularity']\n        \n        return followers, popularity\n    \n    except Exception as e:\n        print(f\"Ha ocurrido un error: {e}\")\n        return None, None\n\ndef get_album_data(artist_id, access_token):\n    url = f\"https://api.spotify.com/v1/artists/{artist_id}/albums\"\n    headers = {\"Authorization\": f\"Bearer {access_token}\"}\n\n    params = {\"include_groups\": \"album\"} \n    total_albums = []\n\n    try:    \n        while url:\n            response = requests.get(url, headers=headers, params=params)\n            album_data = response.json()\n            total_albums.extend(album_data['items'])\n            url = album_data['next']\n        \n        return len(total_albums)\n    \n    except Exception as e:\n        print(f\"Ha ocurrido un error: {e}\")\n        return None\n\ndef get_artist_top_tracks(artist_id, access_token):\n    url = f\"https://api.spotify.com/v1/artists/{artist_id}/top-tracks\"\n    headers = {\"Authorization\": f\"Bearer {access_token}\"}\n\n    try:\n        response = requests.get(url, headers=headers)\n        top_tracks_data = response.json()\n        \n        top_track_name = top_tracks_data['tracks'][0]['name']\n        top_track_popularity = top_tracks_data['tracks'][0]['popularity']\n\n        return top_track_name, top_track_popularity\n\n    except Exception as e:\n        print(f\"Ha ocurrido un error: {e}\")\n        return None, None\n    \ndef compare(follO, follLP, popO, popLP, albumsO, albumsLP, topSongO, topSongLP):\n\n    try:\n        if (follO > follLP):\n            print(\"Oasis tiene más seguidores.\")\n        elif (follO < follLP):\n            print(\"Linkin Park tiene más seguidores.\")\n        else:\n            print(\"Ambas bandas tienen el mismo número de seguidores.\")\n\n        if (popO > popLP):\n            print(\"Oasis tiene una puntuación de popularidad superior.\")\n        elif (popO < popLP):\n            print(\"Linkin Park tiene una puntuación de popularidad superior.\")\n        else:\n            print(\"Ambas bandas tienen la misma puntuación de popularidad.\")\n\n        if (albumsO > albumsLP):\n            print(\"Oasis sacó más álbumes.\")\n        elif (albumsO < albumsLP):\n            print(\"Linkin Park sacó más álbumes.\")\n        else:\n            print(\"Ambas bandas sacaron el mimso número de álbumes.\")\n\n        if (topSongO > topSongLP):\n            print(\"La canción más popular es de Oasis.\")\n        elif (topSongO < topSongLP):\n            print(\"La canción más popular es de Linkin Park.\")\n        else:\n            print(\"Ambas bandas tienen la mimsa popularidad en su canción más top.\")\n    \n    except Exception as e:\n        print(f\"Ha ocurrido un error: {e}\")\n\n\ndef main():\n\n    access_token = \"BQCTQL7k82YgsiEJWPCUzcQh3KRTr5Vv37bocLQemNTzpV-9iJluHBnEQSPmT9GFOfIXyPG2WfRZN4zZrW7KL6kCwmE4gPJ-4cYA06Cf5FurSiIjI_M\"\n    oasis_id = \"2DaxqgrOhkeH0fpeiQq2f4\"\n    linkin_park_id = \"6XyY86QOPPrYVGvF9ch6wz\"\n\n    print(\"\\nOasis:\\n\")\n    followers_Oasis, popularity_Oasis = get_artist_data(oasis_id, access_token)\n    print(f\"Seguidores: {followers_Oasis}, Popularidad de la banda: {popularity_Oasis}/100\")\n    albums_Oasis = get_album_data(oasis_id, access_token)\n    print(f\"Álbumes de estudio totales: {albums_Oasis}\")\n    top_song_Oasis, top_song_popularity_Oasis = get_artist_top_tracks(oasis_id, access_token)\n    print(f\"Canción más popular: {top_song_Oasis}, Popularidad de la canción: {top_song_popularity_Oasis}/100\")\n\n    print(\"\\nLinkin Park:\\n\")\n    followers_LinkinPark, popularity_LinkinPark = get_artist_data(linkin_park_id, access_token)\n    print(f\"Seguidores: {followers_LinkinPark}, Popularidad de la banda: {popularity_LinkinPark}/100\")\n    albums_LinkinPark = get_album_data(linkin_park_id, access_token)\n    print(f\"Álbumes de estudio totales: {albums_LinkinPark}\")\n    top_song_LinkinPark, top_song_popularity_LinkinPark = get_artist_top_tracks(linkin_park_id, access_token)\n    print(f\"Canción más popular: {top_song_LinkinPark}, Popularidad de la canción: {top_song_popularity_LinkinPark}/100\")\n\n    print(\"\\n¿Qué banda es más popular?\\n\")\n    compare(followers_Oasis, followers_LinkinPark, popularity_Oasis, popularity_LinkinPark, albums_Oasis, albums_LinkinPark, top_song_popularity_Oasis, top_song_popularity_LinkinPark)\n\n\nif __name__ == '__main__':\n    main()"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/python/cdryampi.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * ¡Dos de las bandas más grandes de la historia están de vuelta!\n#  * Oasis y Linkin Park han anunciado nueva gira, pero, ¿quién es más popular?\n#  * Desarrolla un programa que se conecte al API de Spotify y los compare.\n#  * Requisitos:\n#  * 1. Crea una cuenta de desarrollo en https://developer.spotify.com.\n#  * 2. Conéctate al API utilizando tu lenguaje de programación.\n#  * 3. Recupera datos de los endpoint que tú quieras.\n#  * Acciones:\n#  * 1. Accede a las estadísticas de las dos bandas.\n#  *    Por ejemplo: número total de seguidores, escuchas mensuales,\n#  *    canción con más reproducciones...\n#  * 2. Compara los resultados de, por lo menos, 3 endpoint.\n#  * 3. Muestra todos los resultados por consola para notificar al usuario.\n#  * 4. Desarrolla un criterio para seleccionar qué banda es más popular.\n#  */\n\n\nimport base64\nimport urllib.parse\nimport aiohttp\nimport asyncio\n\nclass ConnSpotify():\n\n    __CLIENT_ID = \":)\"\n    __CLIENT_SECRET = \":(\"\n    \n    __ACCESS_TOKEN = None\n    __HEADERS = None\n    __URL_CONN_API = \"https://api.spotify.com\"\n    __URL_CONN_TOKEN = \"https://accounts.spotify.com/api/token\"\n\n    __ENDPOINTS = {\n        \"artist\": \"/v1/artists/\",\n        \"top_tracks\": \"/v1/artists/{id}/top-tracks\",\n        \"albums\": \"/v1/artists/{id}/albums\"\n    }\n\n    __ARTIST = {\n        \"linkinpark\": \"6XyY86QOPPrYVGvF9ch6wz\",\n        \"oasis\": \"2DaxqgrOhkeH0fpeiQq2f4\"\n    }\n\n    async def __get_access_token(self, session):\n        credentials = f\"{self.__CLIENT_ID}:{self.__CLIENT_SECRET}\"\n        encoded_credentials = base64.b64encode(credentials.encode(\"utf-8\")).decode(\"utf-8\")\n\n        headers = {\n            'Authorization': f'Basic {encoded_credentials}',\n            'Content-Type': 'application/x-www-form-urlencoded'\n        }\n\n        body = urllib.parse.urlencode({\n            'grant_type': 'client_credentials'\n        })\n\n        async with session.post(self.__URL_CONN_TOKEN, data=body, headers=headers) as response:\n            if response.status == 200:\n                token_info = await response.json()\n                self.__ACCESS_TOKEN = token_info[\"access_token\"]\n                self.__HEADERS = {\n                    'Authorization': f'Bearer {self.__ACCESS_TOKEN}',\n                    'Content-Type': 'application/json'\n                }\n            else:\n                print(f'Error: {response.status}')\n\n    async def get_headers(self, session):\n        if self.__HEADERS is None:\n            await self.__get_access_token(session)\n        return self.__HEADERS\n\n    async def api_call(self, session):\n        raw_data = []\n        headers = await self.get_headers(session)\n        \n        for artist_name, artist_id in self.__ARTIST.items():\n            url = f\"{self.__URL_CONN_API}{self.__ENDPOINTS['artist']}{artist_id}\"\n            async with session.get(url, headers=headers) as response:\n                if response.status == 200:\n                    data = await response.json()\n                    raw_data.append(data)\n                else:\n                    print(f'Error fetching {artist_name}: {response.status}')\n        return raw_data\n    \n    async def get_top_track(self, session, artist_id):\n        url = self.__URL_CONN_API+f\"{self.__ENDPOINTS['top_tracks']}\".format(id = artist_id)+\"?market=US\"\n        headers = await self.get_headers(session)\n        async with session.get(url, headers=headers) as response:\n            if response.status == 200:\n                return await response.json()\n            else:\n                print(f\"Ha habido un problema a la hora de recuperar los datos... {response.status}\")\n                return None\n            \n    async def get_albums(self, session, artist_id):\n        url = self.__URL_CONN_API+f\"{self.__ENDPOINTS['albums']}\".format(id = artist_id)+\"?market=US\"\n        headers = await self.get_headers(session)\n        async with session.get(url, headers=headers) as response:\n            if response.status == 200:\n                return await response.json()\n            else:\n                print(f\"Ha habido un problema a la hora de recuperar los datos... {response.status}\")\n                return None\n\n    async def comparar_bandas(self, session):\n        bandas = await self.api_call(session)\n\n        banda_1, banda_2 = bandas[:2]\n        banda_1_point, banda_2_point = 0,0\n        band_data = {\n            \"top_tracks\": [],\n            \"albums\": []\n        }\n        for banda in bandas:\n            uri =  banda['uri'].split(\":\")[-1]\n\n            band_data[\"top_tracks\"].append(\n                await self.get_top_track(session=session, artist_id= uri)\n            )\n            band_data[\"albums\"].append(\n                await self.get_top_track(session=session, artist_id= uri)\n            )\n\n        if \"tracks\" in band_data['top_tracks'][0] and \"tracks\" in band_data['top_tracks'][1]:\n            banda_1_point += len(band_data['top_tracks'][0][\"tracks\"]) > len(band_data['top_tracks'][1][\"tracks\"])\n            banda_2_point += len(band_data['top_tracks'][0][\"tracks\"]) < len(band_data['top_tracks'][1][\"tracks\"])\n\n        \n        pop_albums_1 = sum([album['popularity'] for album in band_data['albums'][0][\"tracks\"]])/ len(band_data['albums'][0][\"tracks\"])\n\n        pop_albums_2 = sum([album['popularity'] for album in band_data['albums'][1][\"tracks\"]])/ len(band_data['albums'][1][\"tracks\"])\n\n        if pop_albums_1 != pop_albums_2:\n\n            banda_1_point += pop_albums_1 > pop_albums_2\n            banda_2_point += pop_albums_1 < pop_albums_2\n        \n            \n\n        banda_1_point += banda_1['popularity'] > banda_2['popularity']\n        banda_2_point += banda_1['popularity'] < banda_2['popularity']\n\n\n        banda_1_point += banda_1['followers']['total'] > banda_2['followers']['total']\n        banda_2_point += banda_1['followers']['total'] < banda_2['followers']['total']\n        \n        if len(banda_1['genres']) != len(banda_2['genres']):\n            banda_1_point += len(banda_1['genres']) > len(banda_2['genres'])\n            banda_2_point += len(banda_1['genres']) < len(banda_2['genres'])\n\n        if banda_1_point != banda_2_point:\n            ganador = banda_1 if banda_1_point > banda_2_point else banda_2\n            print(f\"El ganador es: {ganador['name']}\")\n        else:\n            print(\"Ha habido un empate técnico.\")\n\nasync def main():\n    api = ConnSpotify()\n\n    async with aiohttp.ClientSession() as session:\n        await api.comparar_bandas(session)\n\nif __name__ == '__main__':\n    asyncio.get_event_loop().run_until_complete(main())\n"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/python/d1d4cum.py",
    "content": "import requests\nfrom requests.adapters import Response\n\n\nACCESS_TOKEN = 'BQDskkWetddthiddwtbTTkJS_H5lg-LgNAxs82vlR1rP9tQVusdakSVPLY_DjisoPASLrXZrYhPc0eNR3GSTsU2-2XCXxmCPk03MvpFJQ1atgp9n3GY'\nOASIS_ID = '2DaxqgrOhkeH0fpeiQq2f4'\nLININ_PARK_ID = '6XyY86QOPPrYVGvF9ch6wz'\nURL = 'https://api.spotify.com/v1/artists/'\nHEADERS = {\n    'Authorization': f\"Bearer {ACCESS_TOKEN}\"\n}\n\n\ndef get_data(artist_id):\n\n    response = requests.get(f\"{URL}{artist_id}\", headers=HEADERS)\n\n    if response.status_code == 200:\n        data = response.json()\n\n        return data\n\n    else:\n        print(f\"Error: {response.status_code}\")\n\ndef main():\n    oasis_data = get_data(OASIS_ID)\n    linkin_park_data = get_data(LININ_PARK_ID)\n\n    oasis_followers = oasis_data[\"followers\"][\"total\"]\n    linkin_park_followers = linkin_park_data[\"followers\"][\"total\"]\n\n    oasis_popularity = oasis_data[\"popularity\"]\n    linkin_park_popularity = linkin_park_data[\"popularity\"]\n\n    print(\"> Oasis\")\n    print(f\"- Followers: {oasis_followers}\")\n    print(f\"- Popularity: {oasis_popularity}\")\n    print(\"\\n> Linkin Park\")\n    print(f\"- Followers: {linkin_park_followers}\")\n    print(f\"- Popularity: {linkin_park_popularity}\")\n\n    if oasis_popularity > linkin_park_popularity:\n        print(\"\\nOasis es más popular\")\n    elif oasis_popularity < linkin_park_popularity:\n        print(\"\\nLinkin Park es más popular\")\n    else:\n        if oasis_followers > linkin_park_followers:\n            print(\"\\nOasis es más popular\")\n        elif oasis_followers < linkin_park_followers:\n            print(\"\\nLinkin Park es más popular\")\n        else:\n            print(\"\\nSon igual de populares\")\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/python/davidrguez98.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * ¡Dos de las bandas más grandes de la historia están de vuelta!\n * Oasis y Linkin Park han anunciado nueva gira, pero, ¿quién es más popular?\n * Desarrolla un programa que se conecte al API de Spotify y los compare.\n * Requisitos:\n * 1. Crea una cuenta de desarrollo en https://developer.spotify.com.\n * 2. Conéctate al API utilizando tu lenguaje de programación.\n * 3. Recupera datos de los endpoint que tú quieras.\n * Acciones:\n * 1. Accede a las estadísticas de las dos bandas.\n *    Por ejemplo: número total de seguidores, escuchas mensuales,\n *    canción con más reproducciones...\n * 2. Compara los resultados de, por lo menos, 3 endpoint.\n * 3. Muestra todos los resultados por consola para notificar al usuario.\n * 4. Desarrolla un criterio para seleccionar qué banda es más popular.\n */ \"\"\"\n\n#EJERCICIO\n\nimport requests\nimport base64\nimport env\n\nCLIENT_ID = \"4f9f3bdc792649ad984cfcbd05be06d2\"\nCLIENT_SECRET = env.CLIENT_SECRET\n\ndef get_token() -> str:\n    url = \"https://accounts.spotify.com/api/token\"\n    headers = {\n        \"Authorization\": \"Basic \" + base64.b64encode(f\"{CLIENT_ID}:{CLIENT_SECRET}\".encode()).decode(),\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n    }\n    data = {\"grant_type\": \"client_credentials\"}\n\n    response = requests.post(url, headers=headers, data=data)\n    if response.status_code != 200:\n        raise Exception(\n            f\"Error obteniendo el token de Spotify: {response.json()}.\"\n        )\n\n    return response.json()[\"access_token\"]\n\ndef search_artist(token: str, name: str):\n    url = f\"https://api.spotify.com/v1/search?q={name}&type=artist&limit=1\"\n    headers = {\"Authorization\": f\"Bearer {token}\"}\n\n    response = requests.get(url, headers=headers)\n    if response.status_code != 200:\n        raise Exception(f\"Error obteniendo el artista: {response.json()}\")\n    \n    results = response.json()\n    if results[\"artists\"][\"items\"]:\n        return results[\"artists\"][\"items\"][0][\"id\"]\n    else:\n        raise Exception(f\"El artista {name} no se ha encontrado.\")\n    \ndef get_artist_data(token: str, id: str):\n    url = f\"https://api.spotify.com/v1/artists/{id}\"\n    headers = {\"Authorization\": f\"Bearer {token}\"}\n\n    response = requests.get(url, headers=headers)\n    if response.status_code != 200:\n        raise Exception(f\"Error obteniendo los datos del artista: {response.json()}\")\n    \n    results = response.json()\n    return {\n        \"name\": results[\"name\"],\n        \"followers\": results[\"followers\"][\"total\"],\n        \"popularity\": results[\"popularity\"],\n    }\n\ndef get_artist_top_track(token: str, id: str):\n    url = f\"https://api.spotify.com/v1/artists/{id}/top-tracks\"\n    headers = {\"Authorization\": f\"Bearer {token}\"}\n\n    response = requests.get(url, headers=headers)\n    if response.status_code != 200:\n        raise Exception(f\"Error obteniendo las canciones del artista: {response.json()}\")\n    \n    results = response.json()\n    top_track = max(results[\"tracks\"], key=lambda track: track[\"popularity\"])\n\n    return {\n        \"name\": top_track[\"name\"],\n        \"popularity\": top_track[\"popularity\"]\n    }\n\n\ntoken = get_token()\n\nartist_1_id = search_artist(token, \"Oasis\")\nartist_2_id = search_artist(token, \"Linkin Park\")\n\nartist_1 = get_artist_data(token, artist_1_id)\nartist_2 = get_artist_data(token, artist_2_id)\n\ntop_track_artist_1 = get_artist_top_track(token, artist_1_id)\ntop_track_artist_2 = get_artist_top_track(token, artist_2_id)\n\nartist_1_counter = 0\nartist_2_counter = 0\n\nprint(f\"\\nComparación de artistas:\\n\")\nprint(f\"{artist_1[\"name\"]}\")\nprint(f\"{artist_2[\"name\"]}\")\n\nprint(f\"\\nComparación de seguidores:\\n\")\nprint(f\"Seguidores {artist_1[\"name\"]}: {artist_1[\"followers\"]}\")\nprint(f\"Seguidores {artist_2[\"name\"]}: {artist_2[\"followers\"]}\")\n\nif artist_1[\"followers\"] > artist_2[\"followers\"]:\n    print(f\"\\nEl artista {artist_1[\"name\"]} tiene más seguidores que {artist_2[\"name\"]}\")\n    artist_1_counter += 1\nelse:\n    print(f\"\\nEl artista {artist_2[\"name\"]} tiene más seguidores que {artist_1[\"name\"]}\")\n    artist_2_counter += 1\n\nprint(f\"\\nComparación popularidad:\\n\")\nprint(f\"Popularidad {artist_1[\"name\"]}: {artist_1[\"popularity\"]}\")\nprint(f\"Popularidad {artist_2[\"name\"]}: {artist_2[\"popularity\"]}\")\n\nif artist_1[\"popularity\"] > artist_2[\"popularity\"]:\n    print(f\"{artist_1[\"name\"]} es más popular a nivel general.\")\n    artist_1_counter += 1\nelse:\n    print(f\"{artist_2[\"name\"]} es más popular a nivel general.\")\n    artist_2_counter += 1\n\nprint(f\"\\nComparación de popularidad de la canción más escuchada:\\n\")\nprint(f\"Canción {top_track_artist_1[\"name\"]} ({artist_1[\"name\"]}): {top_track_artist_1[\"popularity\"]} popularidad.\")\nprint(f\"Canción {top_track_artist_2[\"name\"]} ({artist_2[\"name\"]}): {top_track_artist_2[\"popularity\"]} popularidad.\")\n\nif top_track_artist_1[\"popularity\"] > top_track_artist_2[\"popularity\"]:\n    print(f\"La canción más escuchada del artista {artist_1[\"name\"]} es más popular que {artist_2[\"name\"]}\")\n    artist_1_counter += 1\nelse:\n    print(f\"\\nLa canción más escuchada del artista {artist_2[\"name\"]} es más popular que {artist_1[\"name\"]}\")\n    artist_2_counter += 1\n\nif artist_1_counter > artist_2_counter:\n    print(f\"\\nEl artista {artist_1[\"name\"]} es más popular que el artista {artist_2[\"name\"]}\")\nelse:\n    print(f\"\\nEl artista {artist_2[\"name\"]} es más popular que el artista {artist_1[\"name\"]}\")"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/python/duendeintemporal.py",
    "content": "#37 { Retos para Programadores } OASIS VS LINKIN PARK \n\n# Bibliography reference:\n# I use GPT as a reference and sometimes to correct or generate proper comments.\n\n\"\"\"  \n  * EJERCICIO:\n * Oasis y Linkin Park han anunciado nueva gira, pero, ¿quién es más popular?\n * ¡Dos de las bandas más grandes de la historia están de vuelta!\n * Desarrolla un programa que se conecte al API de Spotify y los compare.\n * Requisitos:\n * 1. Crea una cuenta de desarrollo en https://developer.spotify.com.\n * 2. Conéctate al API utilizando tu lenguaje de programación.\n * 3. Recupera datos de los endpoint que tú quieras.\n * Acciones:\n * 1. Accede a las estadísticas de las dos bandas.\n *    Por ejemplo: número total de seguidores, escuchas mensuales,\n *    canción con más reproducciones...\n * 2. Compara los resultados de, por lo menos, 3 endpoint.\n * 3. Muestra todos los resultados por consola para notificar al usuario.\n * 4. Desarrolla un criterio para seleccionar qué banda es más popular.\n\n\"\"\"\n\nlog = print\n\nimport requests\nfrom flask import Flask, request, redirect, session, jsonify\nimport os\nimport base64\nimport hashlib\nimport random\nimport string\n\napp = Flask(__name__)\napp.secret_key = os.urandom(24)  # Set a secret key for session management\n\nCLIENT_ID = \"YOUR_CLIENT_ID\"\nREDIRECT_URI = \"YOUR_APP_REDIRECT_URI\"\nSCOPE = \"user-read-private user-read-email user-top-read\"\n\ndef generate_code_verifier(length=128):\n    return ''.join(random.choices(string.ascii_letters + string.digits, k=length))\n\ndef generate_code_challenge(code_verifier):\n    digest = hashlib.sha256(code_verifier.encode()).digest()\n    return base64.urlsafe_b64encode(digest).decode().rstrip(\"=\")\n\n@app.route('/')\ndef index():\n    code_verifier = generate_code_verifier()\n    session['verifier'] = code_verifier\n    code_challenge = generate_code_challenge(code_verifier)\n\n    auth_url = (\n        f\"https://accounts.spotify.com/authorize?client_id={CLIENT_ID}&\"\n        f\"response_type=code&redirect_uri={REDIRECT_URI}&\"\n        f\"scope={SCOPE}&code_challenge_method=S256&code_challenge={code_challenge}\"\n    )\n    return redirect(auth_url)\n\n@app.route('/callback')\ndef callback():\n    code = request.args.get('code')\n    if not code:\n        return \"No authorization code found.\", 400\n\n    access_token = get_access_token(code)\n    if access_token:\n        profile = fetch_profile(access_token)\n        oasis_id = get_artist_id(access_token, \"Oasis\")\n        linkin_park_id = get_artist_id(access_token, \"Linkin Park\")\n\n        oasis_data = get_artist_data(access_token, oasis_id)\n        linkin_park_data = get_artist_data(access_token, linkin_park_id)\n\n        oasis_top_tracks = get_top_tracks(access_token, oasis_id)\n        linkin_park_top_tracks = get_top_tracks(access_token, linkin_park_id)\n\n        oasis_data['tracks'] = oasis_top_tracks['tracks']\n        linkin_park_data['tracks'] = linkin_park_top_tracks['tracks']\n\n        comparison_result = compare_artists(oasis_data, linkin_park_data)\n        return jsonify(comparison_result)\n    else:\n        return \"Failed to get access token.\", 400\n\nCLIENT_SECRET = \"YOUR_CLIENT_SECRET\"  # Add your client secret here\n\ndef get_access_token(code):\n    verifier = session.get('verifier')\n    print(\"Code Verifier:\", verifier)\n    token_url = 'https://accounts.spotify.com/api/token'\n    \n    data = {\n        \"client_id\": CLIENT_ID,\n        \"client_secret\": CLIENT_SECRET,\n        \"grant_type\": \"authorization_code\",\n        \"code\": code,\n        \"redirect_uri\": REDIRECT_URI,\n        \"code_verifier\": verifier\n    }\n    \n    response = requests.post(token_url, data=data)\n\n    # Log the response for debugging\n    print(\"Request URL:\", token_url)\n    print(\"Request Data:\", data)\n    print(\"Response Status Code:\", response.status_code)\n    print(\"Response Body:\", response.text)\n\n    if response.status_code == 200:\n        access_token = response.json().get('access_token')\n        return access_token\n    else:\n        print(\"Failed to get access token:\", response.status_code, response.text)\n        return None\n\n\n\n\ndef fetch_profile(token):\n    response = requests.get(\"https://api.spotify.com/v1/me\", headers={\"Authorization\": f\"Bearer {token}\"})\n    response.raise_for_status()\n    return response.json()\n\ndef get_artist_id(token, artist_name):\n    response = requests.get(f\"https://api.spotify.com/v1/search?q={artist_name}&type=artist\", headers={\"Authorization\": f\"Bearer {token}\"})\n    data = response.json()\n    if data['artists']['items']:\n        return data['artists']['items'][0]['id']\n    return None\n\ndef get_artist_data(token, artist_id):\n    response = requests.get(f\"https://api.spotify.com/v1/artists/{artist_id}\", headers={\"Authorization\": f\"Bearer {token}\"})\n    response.raise_for_status()\n    return response.json()\n\ndef get_top_tracks(token, artist_id, market='US'):\n    response = requests.get(f\"https://api.spotify.com/v1/artists/{artist_id}/top-tracks?market={market}\", headers={\"Authorization\": f\"Bearer {token}\"})\n    response.raise_for_status()\n    return response.json()\n\ndef compare_artists(oasis_data, linkin_park_data):\n    comparison = {\n        \"oasis\": {\n            \"followers\": oasis_data['followers']['total'],\n            \"popularity\": oasis_data['popularity'],\n            \"top_track\": oasis_data['tracks'][0] if oasis_data['tracks'] else None\n        },\n        \"linkin_park\": {\n            \"followers\": linkin_park_data['followers']['total'],\n            \"popularity\": linkin_park_data['popularity'],\n            \"top_track\": linkin_park_data['tracks'][0] if linkin_park_data['tracks'] else None\n        }\n    }\n    \n    # Compare followers\n    if comparison['oasis']['followers'] > comparison['linkin_park']['followers']:\n        comparison['winner'] = \"Oasis is more popular based on followers.\"\n    elif comparison['oasis']['followers'] < comparison['linkin_park']['followers']:\n        comparison['winner'] = \"Linkin Park is more popular based on followers.\"\n    else:\n        comparison['winner'] = \"Both artists have the same number of followers.\"\n\n    # Compare popularity\n    if comparison['oasis']['popularity'] > comparison['linkin_park']['popularity']:\n        comparison['popularity_winner'] = \"Oasis is more popular based on popularity score.\"\n    elif comparison['oasis']['popularity'] < comparison['linkin_park']['popularity']:\n        comparison['popularity_winner'] = \"Linkin Park is more popular based on popularity score.\"\n    else:\n        comparison['popularity_winner'] = \"Both artists have the same popularity score.\"\n\n    # Compare top track popularity\n    if comparison['oasis']['top_track'] and comparison['linkin_park']['top_track']:\n        if comparison['oasis']['top_track']['popularity'] > comparison['linkin_park']['top_track']['popularity']:\n            comparison['top_track_winner'] = \"Oasis is more popular based on top track popularity score.\"\n        elif comparison['oasis']['top_track']['popularity'] < comparison['linkin_park']['top_track']['popularity']:\n            comparison['top_track_winner'] = \"Linkin Park is more popular based on top track popularity score.\"\n        else:\n            comparison['top_track_winner'] = \"Both artists have the same top track popularity score.\"\n    else:\n        comparison['top_track_winner'] = \"One or both artists do not have top tracks available.\"\n\n    return comparison\n\nif __name__ == '__main__':\n    app.run(port=5173, debug=True)\n\n\n"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/python/fborjalv.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Oasis y Linkin Park han anunciado nueva gira, pero, ¿quién es más popular?\n * ¡Dos de las bandas más grandes de la historia están de vuelta!\n * Desarrolla un programa que se conecte al API de Spotify y los compare.\n * Requisitos:\n * 1. Crea una cuenta de desarrollo en https://developer.spotify.com.\n * 2. Conéctate al API utilizando tu lenguaje de programación.\n * 3. Recupera datos de los endpoint que tú quieras.\n * Acciones:\n * 1. Accede a las estadísticas de las dos bandas.\n *    Por ejemplo: número total de seguidores, escuchas mensuales,\n *    canción con más reproducciones...\n * 2. Compara los resultados de, por lo menos, 3 endpoint.\n * 3. Muestra todos los resultados por consola para notificar al usuario.\n * 4. Desarrolla un criterio para seleccionar qué banda es más popular.\n */\n\n\"\"\"\nimport base64\nimport requests\n\nCLIENT_ID = \"YOUR_CLIENT_ID\"\nCLIENT_SECRET = \"YOUR_CLIENT_SECRET\"\n\n\ndef get_token() -> str:\n    url = \"https://accounts.spotify.com/api/token\"\n    headers = {\n        \"Authorization\": \"Basic \" + base64.b64encode(f\"{CLIENT_ID}:{CLIENT_SECRET}\".encode()).decode(),\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n    }\n    data = {\n        \"grant_type\": \"client_credentials\"\n    }\n    response = requests.post(url, headers=headers, data=data)\n    if response.status_code != 200:\n        raise Exception(f\"Error obteniendo el token de spotify: {response.json()} \")\n    return response.json()[\"access_token\"]\n\n\ndef search_artist(artist, token):\n\n    url = f\"https://api.spotify.com/v1/search?q=artist:{artist}&type=artist&limit=1\"\n    headers = {\"Authorization\": \"Bearer \" + token}\n    response = requests.get(url=url,headers=headers)\n    \n    if response.status_code != 200:\n        raise Exception(f\"Error obteniendo el artista: {response.json()} \")\n    \n    results = response.json()\n    if results[\"artists\"][\"items\"]:\n        return results[\"artists\"][\"items\"][0][\"id\"]\n    else: \n        raise Exception(f\"El {artist} no se ha encontrado\")\n\n\ndef get_followers_popularity(artist_id, token):\n    url = f\"https://api.spotify.com/v1/artists/{artist_id}\"\n    headers = {\"Authorization\": \"Bearer \" + token}\n    response = requests.get(url, headers=headers)\n    \n    if response.status_code != 200:\n        print(\"Se ha producido un error al obtener el número de seguidores\")\n\n    results = response.json()\n    return {\n        \"followers\": results[\"followers\"][\"total\"],\n        \"popularity\": results[\"popularity\"]\n    }\n\n\n\ndef get_top_tracks(artist_id, token):\n    url = f\"https://api.spotify.com/v1/artists/{artist_id}/top-tracks\"\n    headers = {\"Authorization\": \"Bearer \" + token }\n    response = requests.get(url=url, headers=headers)\n    if response.status_code != 200:\n        print(\"Se ha producido un error al obtener las canciones\")\n    results = response.json()\n    return {\n        \"top_track\": results[\"tracks\"][0][\"name\"],\n        \"popularity_track\": results[\"tracks\"][0][\"popularity\"]\n    }\n\n\ntoken = get_token()\n\nartista_1 = input(\"Introduce el nombre del primer artista: \")\nartista_1_id = search_artist(artista_1, token)\nartista_2 = input(\"Introduce el nombre del segundo artista: \")\nartista_2_id = search_artist(artista_2, token)\n\n# ids\n\n\n#artist data\nartista_1_data = get_followers_popularity(artista_1_id, token)\nartista_2_data = get_followers_popularity(artista_2_id, token)\n\n# song data\nartista_1_song = get_top_tracks(artista_1_id, token)\nartista_2_song = get_top_tracks(artista_2_id, token)\n\npopularidad_artista_1 = 0\npopularidad_artista_2 = 0\n\nprint(f\"Vamos a comparar la popularidad entre {artista_1} y {artista_2} \")\nprint(f\"Popularidad de {artista_1}: {artista_1_data['popularity']}\")\nprint(f\"Popularidad de {artista_2}: {artista_2_data['popularity']}\")\n\nif artista_1_data['popularity'] > artista_2_data['popularity']:\n    print(f\"{artista_1} es más popular que {artista_2}\")\n    popularidad_artista_1 += 1\nelse:\n    print(f\"{artista_2} es más popular que {artista_1}\") \n    popularidad_artista_2 += 1\n\nprint(f\"Número de seguidores de {artista_1}: {artista_1_data['followers']} \")\nprint(f\"Número de seguidores de {artista_2}: {artista_2_data['followers']} \")\n\nif artista_1_data['followers'] > artista_2_data['followers']:\n    print(f\"{artista_1} tiene más seguidores que {artista_2}\")\n    popularidad_artista_1 += 1\nelse: \n    print(f\"{artista_2} tiene más seguidores que {artista_1}\")\n    popularidad_artista_2 += 1\n\nprint(f\"Canción más popular de {artista_1}: {artista_1_song['top_track']}\")\nprint(f\"Canción más popular de {artista_2}: {artista_2_song['top_track']}\")\nprint(f\"Popularidad de la canción Top de {artista_1}: {artista_1_song['popularity_track']}\")\nprint(f\"Popularidad de la canción Top de {artista_2}: {artista_2_song['popularity_track']}\")\n\nif artista_1_song['popularity_track'] > artista_2_song['popularity_track']:\n    print(f\"La canción {artista_1_song['top_track']} es más popular que {artista_2_song['top_track']} \")\n    popularidad_artista_1 += 1\nelse:\n    print(f\"La canción {artista_2_song['top_track']} es más popular que {artista_1_song['top_track']} \")\n    popularidad_artista_2 += 1\n\nprint(\"Resultados: \")\nprint(f\"Popularidad de {artista_1}: {popularidad_artista_1}\")\nprint(f\"Popularidad de {artista_2}: {popularidad_artista_2}\")\n\nif popularidad_artista_1 > popularidad_artista_2:\n    print(f\"{artista_1} es más popular que {artista_2}\")\nelse:\n    print(f\"{artista_2} es más popular que {artista_1}\")"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/python/hectorio23.py",
    "content": "# Autor: Héctor Adán\n# GitHub: https://github.com/hectorio23\n\nimport requests\nimport json\n\n# Credenciales (Obtenidas desde la cuenta de Spotify)\nCLIENT_ID = \"client_id\"\nCLIENT_SECRET = \"client_secret\"\n\n# Autenticación con Spotify API\ndef get_access_token():\n    url = \"https://accounts.spotify.com/api/token\"\n    headers = {\"Content-Type\": \"application/x-www-form-urlencoded\"}\n    data = {\n        \"grant_type\": \"client_credentials\",\n        \"client_id\": CLIENT_ID,\n        \"client_secret\": CLIENT_SECRET\n    }\n    response = requests.post(url, headers=headers, data=data)\n    return response.json().get(\"access_token\")\n\n# Función para obtener datos de una banda/artista\ndef get_artist_data(artist_name, token):\n    search_url = f\"https://api.spotify.com/v1/search?q={artist_name}&type=artist&limit=1\"\n    headers = {\"Authorization\": f\"Bearer {token}\"}\n    response = requests.get(search_url, headers=headers)\n    artist_data = response.json()[\"artists\"][\"items\"][0]\n    return {\n        \"name\": artist_data[\"name\"],\n        \"followers\": artist_data[\"followers\"][\"total\"],\n        \"popularity\": artist_data[\"popularity\"],\n        \"monthly_listeners\": artist_data[\"popularity\"] * 1000  # Simplificación\n    }\n\n# Comparación de bandas\ndef compare_bands():\n    token = get_access_token()\n    oasis_data = get_artist_data(\"Oasis\", token)\n    linkin_park_data = get_artist_data(\"Linkin Park\", token)\n\n    print(f\"Oasis: {oasis_data}\")\n    print(f\"Linkin Park: {linkin_park_data}\")\n\n    # Criterio de comparación\n    if oasis_data[\"followers\"] > linkin_park_data[\"followers\"]:\n        print(\"Oasis es más popular en seguidores.\")\n    else:\n        print(\"Linkin Park es más popular en seguidores.\")\n\nif __name__ == \"__main__\":\n    compare_bands()\n"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/python/hozlucas28.py",
    "content": "# pylint: disable=missing-module-docstring,missing-function-docstring,broad-exception-raised\n\nfrom typing import Any\nimport requests as request\n\n\n# ---------------------------------------------------------------------------- #\n#                                      ENV                                     #\n# ---------------------------------------------------------------------------- #\n\n\nSPOTIFY_API_CLIENT_ID: str = \"******\"\nSPOTIFY_API_CLIENT_SECRET: str = \"******\"\n\n\n# ---------------------------------------------------------------------------- #\n#                                   FUNCTIONS                                  #\n# ---------------------------------------------------------------------------- #\n\n\ndef get_artist_data(*, _id: str, token: str) -> dict[Any, Any]:\n    url: str = f\"https://api.spotify.com/v1/artists/{_id}\"\n\n    headers: dict[str, str] = {\n        \"Authorization\": f\"Bearer {token}\",\n    }\n\n    response: request.Response = request.get(url=url, headers=headers, timeout=10)\n    data: dict[Any, Any] = response.json()\n\n    if response.status_code != 200:\n        raise Exception(data)\n\n    return data\n\n\ndef search_artist(\n    *,\n    fullName: str,\n    token: str,\n) -> dict[Any, Any]:\n    url: str = f\"https://api.spotify.com/v1/search?q={fullName}&type=artist&limit=1\"\n\n    headers: dict[str, str] = {\n        \"Authorization\": f\"Bearer {token}\",\n    }\n\n    response: request.Response = request.get(url=url, headers=headers, timeout=10)\n    data: dict[Any, Any] = response.json()\n\n    if response.status_code != 200:\n        raise Exception(data)\n\n    return data[\"artists\"][\"items\"][0]\n\n\ndef get_artist(\n    *,\n    _id: str,\n    token: str,\n) -> dict[Any, Any]:\n    url: str = f\"https://api.spotify.com/v1/artists/{_id}\"\n\n    headers: dict[str, str] = {\n        \"Authorization\": f\"Bearer {token}\",\n    }\n\n    response: request.Response = request.get(url=url, headers=headers, timeout=10)\n    data: dict[Any, Any] = response.json()\n\n    if response.status_code != 200:\n        raise Exception(data)\n\n    return data\n\n\ndef get_artist_top_tracks(\n    *,\n    _id: str,\n    token: str,\n) -> dict[Any, Any]:\n    url: str = f\"https://api.spotify.com/v1/artists/{_id}/top-tracks\"\n\n    headers: dict[str, str] = {\n        \"Authorization\": f\"Bearer {token}\",\n    }\n\n    response: request.Response = request.get(url=url, headers=headers, timeout=10)\n    data: dict[Any, Any] = response.json()\n\n    if response.status_code != 200:\n        raise Exception(data)\n\n    return data\n\n\ndef get_spotify_token() -> dict[Any, Any]:\n    url: str = \"https://accounts.spotify.com/api/token\"\n\n    headers: dict[str, str] = {\n        \"Content-Type\": \"application/x-www-form-urlencoded\",\n    }\n\n    data: str = (\n        f\"grant_type=client_credentials\"\n        f\"&client_id={SPOTIFY_API_CLIENT_ID}\"\n        f\"&client_secret={SPOTIFY_API_CLIENT_SECRET}\"\n    )\n\n    response: request.Response = request.post(\n        url=url, headers=headers, data=data, timeout=10\n    )\n\n    if response.status_code != 200:\n        raise Exception(response.json())\n\n    return response.json()\n\n\n# ---------------------------------------------------------------------------- #\n#                                     MAIN                                     #\n# ---------------------------------------------------------------------------- #\n\n\nspotify_token: dict[Any, Any] = get_spotify_token()\n\nband_names: dict[Any, Any] = {\n    \"first\": \"oasis\",\n    \"second\": \"linkin park\",\n}\n\nfirst_band: dict[Any, Any] = search_artist(\n    fullName=band_names[\"first\"],\n    token=spotify_token[\"access_token\"],\n)\n\nfirst_band_data: dict[Any, Any] = get_artist_data(\n    _id=first_band[\"id\"],\n    token=spotify_token[\"access_token\"],\n)\n\nfirst_band_top_tracks: dict[Any, Any] = get_artist_top_tracks(\n    _id=first_band[\"id\"],\n    token=spotify_token[\"access_token\"],\n)\n\nfirst_band_top_track: dict[Any, Any] = max(\n    first_band_top_tracks[\"tracks\"], key=lambda track: track[\"popularity\"]\n)\n\nsecond_band: dict[Any, Any] = search_artist(\n    fullName=band_names[\"second\"],\n    token=spotify_token[\"access_token\"],\n)\n\nsecond_band_data: dict[Any, Any] = get_artist_data(\n    _id=second_band[\"id\"],\n    token=spotify_token[\"access_token\"],\n)\n\nsecond_band_top_tracks: dict[Any, Any] = get_artist_top_tracks(\n    _id=second_band[\"id\"],\n    token=spotify_token[\"access_token\"],\n)\n\nsecond_band_top_track: dict[Any, Any] = max(\n    second_band_top_tracks[\"tracks\"], key=lambda track: track[\"popularity\"]\n)\n\npoints_per_band: dict[str, int] = {\n    \"first\": 0,\n    \"second\": 0,\n}\n\nprint(\n    f\"> Which band is more popular ({first_band_data['name']}, or {second_band_data['name']})?\"\n)\n\nprint(\"\\n> Comparison of popularity...\")\nprint(\n    f\"\\n> Popularity of {first_band_data['name']}: {first_band_data['popularity']} \"\n    f\"points of popularity.\"\n)\nprint(\n    f\"> Popularity of {second_band_data['name']}: {second_band_data['popularity']} \"\n    f\"points of popularity.\"\n)\n\nif first_band_data[\"popularity\"] > second_band_data[\"popularity\"]:\n    print(\n        f\"> {first_band_data['name']} has more popularity points than {second_band_data['name']}.\"\n    )\n    points_per_band[\"first\"] += 1\nelif first_band_data[\"popularity\"] < second_band_data[\"popularity\"]:\n    print(\n        f\"> {second_band_data['name']} has more popularity points than {first_band_data['name']}.\"\n    )\n    points_per_band[\"second\"] += 1\nelse:\n    print(\n        f\"> {first_band_data['name']} has the same popularity points than \"\n        f\"{second_band_data['name']}.\"\n    )\n\n\nprint(\"\\n> Comparison of followers...\")\nprint(\n    f\"\\n> Followers of {first_band_data['name']}: {first_band_data['followers']['total']} \"\n    f\"followers.\"\n)\nprint(\n    f\"> Followers of {second_band_data['name']}: {second_band_data['followers']['total']} \"\n    f\"followers.\"\n)\n\nif first_band_data[\"followers\"][\"total\"] > second_band_data[\"followers\"][\"total\"]:\n    print(\n        f\"> {first_band_data['name']} has more followers than {second_band_data['name']}.\"\n    )\n    points_per_band[\"first\"] += 1\nelif first_band_data[\"followers\"][\"total\"] < second_band_data[\"followers\"][\"total\"]:\n    print(\n        f\"> {second_band_data['name']} has more followers than {first_band_data['name']}.\"\n    )\n    points_per_band[\"second\"] += 1\nelse:\n    print(\n        f\"> {first_band_data['name']} has the same number of followers than \"\n        f\"{second_band_data['name']}.\"\n    )\n\n\nprint(\"\\n> Comparison of top track of each band...\")\nprint(\n    f\"\\n> Top track of {first_band_data['name']} (name, and popularity): \"\n    f\"{first_band_top_track['name']} \"\n    f\"(${first_band_top_track['popularity']} points of popularity).\"\n)\nprint(\n    f\"> Top track of {second_band_data['name']} (name, and popularity): \"\n    f\"{second_band_top_track['name']} (${second_band_top_track['popularity']} \"\n    f\"points of popularity).\"\n)\n\nif first_band_top_track[\"popularity\"] > second_band_top_track[\"popularity\"]:\n    print(\n        f\"> {first_band_top_track['name']} of {first_band_data['name']} band is more popular \"\n        f\"than {second_band_top_track['name']} of {second_band_data['name']} band.\"\n    )\n    points_per_band[\"first\"] += 1\nelif first_band_top_track[\"popularity\"] < second_band_top_track[\"popularity\"]:\n    print(\n        f\"> {second_band_top_track['name']} of {second_band_data['name']} band is more \"\n        f\"popular than {first_band_top_track['name']} of {first_band_data['name']} band.\"\n    )\n    points_per_band[\"second\"] += 1\nelse:\n    print(\n        f\"> {second_band_top_track['name']} of {second_band_data['name']} band has the same \"\n        f\"popularity points than {first_band_top_track['name']} of {first_band_data['name']} band.\"\n    )\n\n\nprint(\"\\n> In conclusion...\")\n\nif points_per_band[\"first\"] > points_per_band[\"second\"]:\n    print(\n        f\"\\n> {first_band_data['name']} band is more popular than {second_band_data['name']} band\"\n    )\nelif points_per_band[\"first\"] < points_per_band[\"second\"]:\n    print(\n        f\"\\n> {second_band_data['name']} band is more popular than {first_band_data['name']} band\"\n    )\nelse:\n    print(\n        f\"\\n> {first_band_data['name']} band is as popular as {second_band_data['name']} band.\"\n    )\n"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/python/idiegorojas.py",
    "content": "\"\"\" \n# 37 - Oasis vs Linkin Park \n\"\"\"\n\n#  Desarrolla un programa que se conecte al API de Spotify y los compare.\"\n\n\"\"\"\nRequisitos:\n\"\"\"\n# 1. Crea una cuenta de desarrollo en https://developer.spotify.com.\n# 2. Conéctate al API utilizando tu lenguaje de programación.\n# 3. Recupera datos de los endpoint que tú quieras.\n\n\"\"\"\nAcciones:\n\"\"\"\n# 1. Accede a las estadísticas de las dos bandas.\n    # Por ejemplo: número total de seguidores, escuchas mensuales,\n    # canción con más reproducciones...\n# 2. Compara los resultados de, por lo menos, 3 endpoint.\n# 3. Muestra todos los resultados por consola para notificar al usuario.\n# 4. Desarrolla un criterio para seleccionar qué banda es más popular.\n\n\nimport spotipy\nfrom spotipy.oauth2 import SpotifyClientCredentials\nimport os\nfrom dotenv import load_dotenv\n\n# Cargar variables de entorno desde .env (opcional)\nload_dotenv()\n\n# Configuración de credenciales\nclient_id = os.getenv('SPOTIFY_CLIENT_ID')\nclient_secret = os.getenv('SPOTIFY_CLIENT_SECRET')\n\n\n# Inicializar el cliente de Spotify\nsp = spotipy.Spotify(auth_manager=SpotifyClientCredentials(\n    client_id=client_id,\n    client_secret=client_secret\n))\n\n# IDs de Oasis y Linkin Park\noasis_id = '2DaxqgrOhkeH0fpeiQq2f4'\nlinkin_park_id = '6XyY86QOPPrYVGvF9ch6wz'\n\ndef get_artist_info(artist_id):\n    \"\"\"Obtiene información básica del artista\"\"\"\n    return sp.artist(artist_id)\n\ndef get_artist_top_tracks(artist_id, country='US'):\n    \"\"\"Obtiene las canciones más populares del artista\"\"\"\n    return sp.artist_top_tracks(artist_id, country=country)\n\ndef get_artist_albums(artist_id):\n    \"\"\"Obtiene los álbumes del artista\"\"\"\n    return sp.artist_albums(artist_id, album_type='album')\n\ndef get_related_artists(artist_id):\n    \"\"\"Obtiene artistas relacionados\"\"\"\n    return sp.artist_related_artists(artist_id)\n\ndef compare_artists(artist1_id, artist2_id):\n    # 1. Comparar información general (seguidores, popularidad, géneros)\n    artist1 = get_artist_info(artist1_id)\n    artist2 = get_artist_info(artist2_id)\n    \n    print(f\"\\n--- COMPARANDO {artist1['name']} VS {artist2['name']} ---\\n\")\n    \n    # Mostrar información general\n    print(f\"--- INFORMACIÓN GENERAL ---\")\n    print(f\"{artist1['name']}:\")\n    print(f\"- Seguidores: {artist1['followers']['total']:,}\")\n    print(f\"- Popularidad: {artist1['popularity']}/100\")\n    print(f\"- Géneros: {', '.join(artist1['genres'])}\")\n    \n    print(f\"\\n{artist2['name']}:\")\n    print(f\"- Seguidores: {artist2['followers']['total']:,}\")\n    print(f\"- Popularidad: {artist2['popularity']}/100\")\n    print(f\"- Géneros: {', '.join(artist2['genres'])}\")\n    \n    # 2. Comparar canciones más populares\n    top_tracks1 = get_artist_top_tracks(artist1_id)\n    top_tracks2 = get_artist_top_tracks(artist2_id)\n    \n    print(f\"\\n--- TOP 5 CANCIONES ---\")\n    print(f\"{artist1['name']}:\")\n    for i, track in enumerate(top_tracks1['tracks'][:5], 1):\n        print(f\"{i}. {track['name']} - Popularidad: {track['popularity']}/100\")\n    \n    print(f\"\\n{artist2['name']}:\")\n    for i, track in enumerate(top_tracks2['tracks'][:5], 1):\n        print(f\"{i}. {track['name']} - Popularidad: {track['popularity']}/100\")\n    \n    # 3. Comparar álbumes\n    albums1 = get_artist_albums(artist1_id)\n    albums2 = get_artist_albums(artist2_id)\n    \n    print(f\"\\n--- ÁLBUMES ---\")\n    print(f\"{artist1['name']}: {len(albums1['items'])} álbumes\")\n    print(f\"{artist2['name']}: {len(albums2['items'])} álbumes\")\n    \n    # 4. Desarrollar criterio de popularidad\n    # Podemos usar una combinación de seguidores y popularidad\n    popularity_score1 = artist1['followers']['total'] * artist1['popularity'] / 100\n    popularity_score2 = artist2['followers']['total'] * artist2['popularity'] / 100\n    \n    print(f\"\\n--- RESULTADO DE POPULARIDAD ---\")\n    print(f\"{artist1['name']}: {popularity_score1:,.0f} puntos\")\n    print(f\"{artist2['name']}: {popularity_score2:,.0f} puntos\")\n    \n    if popularity_score1 > popularity_score2:\n        print(f\"\\n¡{artist1['name']} es más popular según nuestros criterios!\")\n    elif popularity_score2 > popularity_score1:\n        print(f\"\\n¡{artist2['name']} es más popular según nuestros criterios!\")\n    else:\n        print(\"\\n¡Ambas bandas tienen la misma popularidad!\")\n\n# Ejecutar la comparación\ncompare_artists(oasis_id, linkin_park_id)"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/python/ignaciovihe.py",
    "content": "\"\"\"\n* ¡Dos de las bandas más grandes de la historia están de vuelta!\n * Oasis y Linkin Park han anunciado nueva gira, pero, ¿quién es más popular?\n * Desarrolla un programa que se conecte al API de Spotify y los compare.\n * Requisitos:\n * 1. Crea una cuenta de desarrollo en https://developer.spotify.com.\n * 2. Conéctate al API utilizando tu lenguaje de programación.\n * 3. Recupera datos de los endpoint que tú quieras.\n * Acciones:\n * 1. Accede a las estadísticas de las dos bandas.\n *    Por ejemplo: número total de seguidores, escuchas mensuales,\n *    canción con más reproducciones...\n * 2. Compara los resultados de, por lo menos, 3 endpoint.\n * 3. Muestra todos los resultados por consola para notificar al usuario.\n * 4. Desarrolla un criterio para seleccionar qué banda es más popular.\n\"\"\"\n\nimport base64\nimport requests\nimport aiohttp #para hacer llamadas a la api de forma asincrona\nimport asyncio\n\nCLIENT_ID = \"Mi CLIENT_ID\"\nCLIENT_SECRET = \"Mi CLIENT_SECRET\"\n\n\ndef get_token():\n    # Configuracion de una autenticacion OAuth\n    # Codificamos las credenciales para conseguir el token de acceso, el cual usaremos para hacer peticiones get.\n    auth_string = f\"{CLIENT_ID}:{CLIENT_SECRET}\"# Este es el formato de user:pass que se necesita codificar en base 64.\n    b64_auth_string = base64.b64encode(auth_string.encode()).decode()#encode para un string a bytes, luego se codifica en base 64 y al final se vuelve a pasar a string.\n\n    # Armamos la petición post: Url\n    url = \"https://accounts.spotify.com/api/token\"\n    #Headers\n    headers = {\n        \"Authorization\": f\"Basic {b64_auth_string}\",#aqui le pasamos el user:pass codificado\n        \"Content-Type\": \"application/x-www-form-urlencoded\" # indicando que lo pasamos como un formulario\n    }\n    #Body\n    data = {\n        \"grant_type\": \"client_credentials\"# indica que el tipo de credenciales son para acceso a datos de la api sin usuario\n    }\n\n    # Enviamos la petición POST\n    response = requests.post(url, headers=headers, data=data)\n    if response.status_code != 200:\n        raise Exception(\"Error obteniendo el token de Spotify.\")\n    token_data = response.json()\n\n    return token_data[\"access_token\"]\n\n\n\nasync def call_api(session, url, headers):\n    #Funcion asincronaque se encarga de hacer el get  con la session y url pasadas\n    async with session.get(url, headers=headers) as answer:\n        if answer.status != 200:\n            return None\n        else:\n            return await answer.json()# Tiene que esperar a que reciba los datos y los genere, por eso el await.\n        \nasync def search_artists(token: str, artist_1: str, artist_2: str):\n    url_artist1_query = f\"https://api.spotify.com/v1/search?q={artist_1}&type=artist&limit=1\"\n    url_artist2_query = f\"https://api.spotify.com/v1/search?q={artist_2}&type=artist&limit=1\"\n\n    headers = {\n        \"Authorization\": f\"Bearer {token}\"\n    }\n\n    async with aiohttp.ClientSession() as session:# Se crea la sesion para llamadas asincronas. Session = request\n        info_artist_1, info_artist_2 = await asyncio.gather(# Lanzamos la llamadas que no dependen entre ellas\n                                                            call_api(session, url_artist1_query, headers), \n                                                            call_api(session, url_artist2_query, headers),\n                                                            )\n        if info_artist_1 and info_artist_2:\n            return info_artist_1[\"artists\"][\"items\"][0][\"id\"], info_artist_2[\"artists\"][\"items\"][0][\"id\"]\n        else:\n            raise Exception(\"Hubo un problema al buscar los ids de los artistas\")\n\n\nasync def compare_artists(token: str, artist_id1: str, artist_id2):\n    url_artist_id1 = f\"https://api.spotify.com/v1/artists/{artist_id1}\"\n    url_artist_id2 = f\"https://api.spotify.com/v1/artists/{artist_id2}\"\n    url_tracks_id1 = f\"https://api.spotify.com/v1/artists/{artist_id1}/top-tracks\"\n    url_tracks_id2 = f\"https://api.spotify.com/v1/artists/{artist_id2}/top-tracks\"\n\n\n    headers = {\n        \"Authorization\": f\"Bearer {token}\"\n    }\n\n    async with aiohttp.ClientSession() as session:\n\n        info_artist_1, info_artist_2, info_tracks_1, info_tracks_2  = await asyncio.gather(\n                                                            call_api(session, url_artist_id1, headers), \n                                                            call_api(session, url_artist_id2, headers),\n                                                            call_api(session, url_tracks_id1, headers), \n                                                            call_api(session, url_tracks_id2, headers)\n                                                            )\n        \n        if info_artist_1 and info_artist_2:\n            name1, name2 = info_artist_1[\"name\"], info_artist_2[\"name\"]\n            followers1, followers2 = info_artist_1[\"followers\"][\"total\"], info_artist_2[\"followers\"][\"total\"]\n            popularity1, popularity2 = info_artist_1[\"popularity\"], info_artist_2[\"popularity\"]\n        else:\n            raise Exception(\"Error obteniendo los datos de los artistas.\")\n\n        if info_tracks_1 and info_tracks_2:\n            sorted_tracks1 = sorted(info_tracks_1[\"tracks\"], key=lambda t: t[\"popularity\"], reverse=True)\n            sorted_tracks2 = sorted(info_tracks_2[\"tracks\"], key=lambda t: t[\"popularity\"], reverse=True)\n            name_track_1 = sorted_tracks1[0][\"name\"]\n            name_track_2 = sorted_tracks2[0][\"name\"]\n            popularity_track1 = sorted_tracks1[0][\"popularity\"]\n            popularity_track2 = sorted_tracks2[0][\"popularity\"]\n        else:\n            raise Exception(\"Error obteniendo los datos de los tracks.\")\n\n        points={\n            name1: 0,\n            name2: 0\n        }\n        \n        print(\"Comparacion de artistas:\")        \n\n        print(f\"\\t {name1} VS {name2}\\n\")\n\n        print(\"Número de seguidores:\")\n        print(f\"\\tSeguidores de {name1}: {followers1}\")\n        print(f\"\\tSeguidores de {name2}: {followers2}\")\n        more_popular = max((followers1, name1), (followers2, name2))\n        print(f\"{more_popular[1]} es más popular en número de seguidores.\\n\")\n        points[more_popular[1]] += 2\n\n        print(\"Popularidad:\")\n        print(f\"\\t{name1}: {popularity1}\")\n        print(f\"\\t{name2}: {popularity2}\")\n        more_popular = max((popularity1, name1), (popularity2, name2))\n        print(f\"{more_popular[1]} es más popular según el ranking de Spotify.\\n\")\n        points[more_popular[1]] += 3\n\n        print(\"Canciones más populares:\")\n        print(f\"\\tCanción de {name1}: {name_track_1} - {popularity_track1}\")\n        print(f\"\\tCanción de {name2}: {name_track_2} - {popularity_track2}\")\n        more_popular = max((popularity_track1, name_track_1, name1), (popularity_track2, name_track_2, name2))\n        print(f\"La canción {more_popular[1]} de {more_popular[2]} es más popular.\\n\")\n        points[more_popular[2]] += 1.5\n\n        print(\"RESULTADO FINAL:\")\n        print(f\"{name1}: {points[name1]}\")\n        print(f\"{name2}: {points[name2]}\")\n        if points[name1] > points[name2]:\n            print(f\"{name1} es más popular\")\n        else:\n            print(f\"{name2} es más popular\")\n\n\nasync def main():\n    token = get_token()\n    query1 = input(\"Introduce el nombre del primer artista: \")\n    query2 = input(\"Introduce el nombre del segundo artista: \")\n    id_artist_1, id_artist_2 = await search_artists(token, query1, query2)\n    await compare_artists(token, id_artist_1, id_artist_2)\n\nasyncio.run(main())\n\n"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/python/kenysdev.py",
    "content": "# _____________________________________\n# https://github.com/kenysdev\n# 2024 - Python\n# _____________________________________\n# 37 OASIS VS LINKIN PARK\n# ------------------------------------\n\"\"\"\n* ¡Dos de las bandas más grandes de la historia están de vuelta!\n* Oasis y Linkin Park han anunciado nueva gira, pero, ¿quién es más popular?\n* Desarrolla un programa que se conecte al API de Spotify y los compare.\n* Requisitos:\n* 1. Crea una cuenta de desarrollo en https://developer.spotify.com.\n* 2. Conéctate al API utilizando tu lenguaje de programación.\n* 3. Recupera datos de los endpoint que tú quieras.\n* Acciones:\n* 1. Accede a las estadísticas de las dos bandas.\n*    Por ejemplo: número total de seguidores, escuchas mensuales,\n*    canción con más reproducciones...\n* 2. Compara los resultados de, por lo menos, 3 endpoint.\n* 3. Muestra todos los resultados por consola para notificar al usuario.\n* 4. Desarrolla un criterio para seleccionar qué banda es más popular.\n\"\"\"\n\n# https://spotipy.readthedocs.io/en/2.24.0/\nimport spotipy\nfrom spotipy.oauth2 import SpotifyClientCredentials\n\n# https://pypi.org/project/python-dotenv/\nfrom dotenv import load_dotenv\n\nclass Spotify:\n    def __init__(self):\n        load_dotenv() # SPOTIPY_CLIENT_ID, SPOTIPY_CLIENT_SECRET\n        self.sp = spotipy.Spotify(client_credentials_manager=SpotifyClientCredentials())\n    \n    def get_artists(self, name: str) -> dict:\n        results = self.sp.search(q='artist:' + name, type='artist', limit=3)\n        if not results:\n            return {}\n\n        artists = results['artists']['items']\n        return artists\n    \n    def get_most_popular_artist(self, name: str) -> dict:\n        artists: dict = self.get_artists(name)\n        if not artists:\n            return {}\n\n        artists_sorted = sorted(artists, key=lambda x: x['popularity'], reverse=True)\n        most_popular_artist = artists_sorted[0]\n        return most_popular_artist\n\n    def artist_top_tracks(self, id_artist) -> dict:\n        top_track = self.sp.artist_top_tracks(id_artist)\n        if not top_track:\n            return {}\n        return top_track\n\n    def artist_albums(self, id_artist) -> dict:\n        albums = self.sp.artist_albums(id_artist, album_type='album')\n        if not albums:\n            return {}\n        return albums\n    \nclass Versus:\n    def __init__(self, artist1: dict, artist2: dict, spotify_instance):\n        self.a1 = artist1\n        self.a2 = artist2\n        self.sp = spotify_instance\n        self.a1_score = 0\n        self.a2_score = 0\n\n    def __popularity(self):\n        a1_pop: int = self.a1['popularity']\n        a2_pop: int = self.a2['popularity']\n\n        print(f\"Popularidad: {a1_pop} vs {a2_pop}\")\n        if a1_pop > a2_pop:\n            self.a1_score += 1\n        elif a2_pop > a1_pop:\n            self.a2_score += 1\n    \n    def __followers(self):\n        a1_foll: int = self.a1['followers']['total']\n        a2_foll: int = self.a2['followers']['total']\n\n        print(f\"Seguidores: {a1_foll} vs {a2_foll}\")\n        if a1_foll > a2_foll:\n            self.a1_score += 1\n        elif a2_foll > a1_foll:\n            self.a2_score += 1\n\n    def __top3_tracks(self):\n        a1_top: dict = self.sp.artist_top_tracks(self.a1['id'])\n        a2_top: dict = self.sp.artist_top_tracks(self.a2['id'])\n        a1_pop: int = sum(track['popularity'] for track in a1_top['tracks'][:3])\n        a2_pop: int = sum(track['popularity'] for track in a2_top['tracks'][:3])\n        print(f\"Popularidad Top 3 canciones: {a1_pop} vs {a2_pop}\")\n\n        if a1_pop > a2_pop:\n            self.a1_score += 1\n        elif a2_pop > a1_pop:\n            self.a2_score += 1\n\n    def __albums_and_active_years(self):\n        a1_albums: list = self.sp.artist_albums(self.a1['id'])['items']\n        a2_albums: list = self.sp.artist_albums(self.a2['id'])['items']\n        print(f\"Número de álbumes: {len(a1_albums)} vs {len(a2_albums)}\")\n        if len(a1_albums) > len(a2_albums):\n            self.a1_score += 1\n        elif len(a2_albums) > len(a1_albums):\n            self.a2_score += 1\n\n        a1_years = set(album['release_date'][:4] for album in a1_albums)\n        a2_years = set(album['release_date'][:4] for album in a2_albums)\n        print(f\"Años activos: {len(a1_years)} vs {len(a2_years)}\")\n        if len(a1_years) > len(a2_years):\n            self.a1_score += 1\n        elif len(a2_years) > len(a1_years):\n            self.a2_score += 1\n\n    def __final_result(self):\n        print(\"\\nRESULTADO FINAL:\")\n        print(f\"{self.a1['name']}: {self.a1_score} puntos\")\n        print(f\"{self.a2['name']}: {self.a2_score} puntos\")\n\n        if self.a1_score > self.a2_score:\n            print(f\"\\n¡'{self.a1['name']}' gana el versus!\")\n        elif self.a2_score > self.a1_score:\n            print(f\"\\n¡'{self.a2['name']}' gana el versus!\")\n        else:\n            print(\"\\n¡Es un empate!\")\n\n    def start(self):\n        print(f\"{self.a1['name']} vs {self.a2['name']}\")\n        self.__popularity()\n        self.__followers()\n        self.__top3_tracks()\n        self.__albums_and_active_years()\n        self.__final_result()\n\n\ndef main():\n    print(\"VERSUS\")\n    sp = Spotify()\n    artist1: dict = sp.get_most_popular_artist(name=\"Oasis\")\n    artist2: dict = sp.get_most_popular_artist(name=\"Linkin Park\")\n\n    if not artist1 and not artist2:\n        print(\"Artistas no encontrados\")\n        return\n\n    vs = Versus(artist1, artist2, sp)\n    vs.start()\n    \n\nif __name__ == \"__main__\":\n    main()\n\n"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/python/mhayhem.py",
    "content": "# @Author Daniel Grande (Mhayhem)\n\nimport requests\nimport os\nimport base64\nimport json\n\n# EJERCICIO:\n# ¡Dos de las bandas más grandes de la historia están de vuelta!\n# Oasis y Linkin Park han anunciado nueva gira, pero, ¿quién es más popular?\n# Desarrolla un programa que se conecte al API de Spotify y los compare.\n# Requisitos:\n# 1. Crea una cuenta de desarrollo en https://developer.spotify.com.\n# 2. Conéctate al API utilizando tu lenguaje de programación.\n# 3. Recupera datos de los endpoint que tú quieras.\n# Acciones:\n# 1. Accede a las estadísticas de las dos bandas.\n#    Por ejemplo: número total de seguidores, escuchas mensuales,\n#    canción con más reproducciones...\n# 2. Compara los resultados de, por lo menos, 3 endpoint.\n# 3. Muestra todos los resultados por consola para notificar al usuario.\n# 4. Desarrolla un criterio para seleccionar qué banda es más popular.\n\n# get api token\ndef get_access_token():\n    client_id = \"client_id\" # colocar información necesaria\n    client_secret = \"client_secret\" # colocar información necesaria\n    \n    auth_string = f\"{client_id}:{client_secret}\"\n    auth_base64 = base64.b64encode(auth_string.encode()).decode()\n    \n    url = \"https://accounts.spotify.com/api/token\"\n    headers = {\n        \"Authorization\":f\"Basic {auth_base64}\",\n        \"Content-type\":\"application/x-www-form-urlencoded\"\n    }\n    data = {\n        \"grant_type\":\"client_credentials\"\n    }\n    \n    response = requests.post(url, headers=headers, data=data)\n    response.raise_for_status()\n    \n    return response.json()[\"access_token\"]\n\ndef get_artist(token, artist_name):\n    url = \"https://api.spotify.com/v1/search\"\n    headers = {\n        \"Authorization\":f\"Bearer {token}\"\n    }\n    params = {\n        \"q\":artist_name,\n        \"type\":\"artist\",\n        \"limit\":1\n    }\n    \n    response = requests.get(url, headers=headers, params=params)\n    response.raise_for_status()\n    \n    return response.json()[\"artists\"][\"items\"][0]\n\ndef get_top_track(token, artist_id):\n    url = f\"https://api.spotify.com/v1/artists/{artist_id}/top-tracks\"\n    headers = {\n        \"Authorization\":f\"Bearer {token}\"\n    }\n    params = {\n        \"market\":\"US\"\n    }\n    response = requests.get(url, headers=headers, params=params)\n    response.raise_for_status()\n    \n    return response.json()[\"tracks\"][0]\n\ndef get_album_count(token, artist_id):\n    url = f\"https://api.spotify.com/v1/artists/{artist_id}/albums\"\n    headers = {\n        \"Authorization\":f\"Bearer {token}\"\n    }\n    params = {\n        \"limit\": 50\n    }\n    \n    response = requests.get(url , headers=headers, params=params)\n    response.raise_for_status()\n    \n    return response.json()[\"total\"]\n\ndef print_artist_status(artist, top_track, album_count):\n    print(f\"\\n{artist['name']}\")\n    print(f\"Seguidores: {artist['followers'][\"total\"]}\")\n    print(f\"Popularidad: {artist['popularity']}\")\n    print(f\"Generos: {', '.join(artist['genres'])}\")\n    print(f\"Canción mas popular: {top_track['name']} (popularity: {top_track['popularity']})\")\n    print(f\"Número de albunes: {album_count}\")\n\ndef calculate_score(artist, top_track):\n    return (\n        artist[\"followers\"][\"total\"] * 0.5 +\n        artist[\"popularity\"] * 1.0 +\n        top_track[\"popularity\"]\n    )\n\ndef main():\n    token = get_access_token()\n    \n    oasis = get_artist(token, \"Oasis\")\n    linkin_park = get_artist(token, \"Linkin Park\")\n    \n    oasis_top = get_top_track(token, oasis[\"id\"])\n    lp_top = get_top_track(token, linkin_park[\"id\"])\n    \n    oasis_albums = get_album_count(token, oasis[\"id\"])\n    lp_albums = get_album_count(token, linkin_park[\"id\"])\n    \n    print_artist_status(oasis, oasis_top, oasis_albums)\n    print_artist_status(linkin_park, lp_top, lp_albums)\n    \n    oasis_scores = calculate_score(oasis, oasis_top)\n    lp_scores = calculate_score(linkin_park, lp_top)\n    \n    print(\"\\n RESULTADO FINAL\")\n    if oasis_scores > lp_scores:\n        print(f\"Oasis gana en populareidad, {oasis_scores}.\")\n    else:\n        print(f\"Linkin Park gana en populardiada, {lp_scores}\")\n\nmain()"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/python/miguelex.py",
    "content": "import base64\nimport requests\n\nclient_id = 'YOUR_CLIENT_ID'\nclient_secret = 'YOUR_CLIENT_SECRET'\n\ndef get_access_token():\n    auth = base64.b64encode(f\"{client_id}:{client_secret}\".encode()).decode()\n    headers = {\n        'Authorization': f'Basic {auth}',\n        'Content-Type': 'application/x-www-form-urlencoded'\n    }\n    data = {\n        'grant_type': 'client_credentials'\n    }\n    response = requests.post('https://accounts.spotify.com/api/token', headers=headers, data=data)\n    return response.json()['access_token']\n\ndef get_artist_data(token, artist_name):\n    headers = {\n        'Authorization': f'Bearer {token}'\n    }\n    response = requests.get(f\"https://api.spotify.com/v1/search?q={artist_name}&type=artist\", headers=headers)\n    return response.json()['artists']['items'][0]  \ndef get_artist_stats(artist_id, token):\n    headers = {\n        'Authorization': f'Bearer {token}'\n    }\n    response = requests.get(f\"https://api.spotify.com/v1/artists/{artist_id}\", headers=headers)\n    data = response.json()\n    return {\n        'name': data['name'],\n        'followers': data['followers']['total'],\n        'popularity': data['popularity'],\n        'genres': data['genres']\n    }\n\ndef get_artist_top_tracks(artist_id, token):\n    headers = {\n        'Authorization': f'Bearer {token}'\n    }\n    response = requests.get(f\"https://api.spotify.com/v1/artists/{artist_id}/top-tracks?market=US\", headers=headers)\n    data = response.json()\n    most_popular_track = data['tracks'][0]  \n    return {\n        'name': most_popular_track['name'],\n        'playCount': most_popular_track['popularity'],  \n        'album': most_popular_track['album']['name']\n    }\n\ndef compare_bands(band1, band2):\n    token = get_access_token()\n    \n    band1_data = get_artist_data(token, band1)\n    band2_data = get_artist_data(token, band2)\n    \n    band1_stats = get_artist_stats(band1_data['id'], token)\n    band2_stats = get_artist_stats(band2_data['id'], token)\n    \n    band1_top_track = get_artist_top_tracks(band1_data['id'], token)\n    band2_top_track = get_artist_top_tracks(band2_data['id'], token)\n    \n    print(f\"\\n{band1} Stats:\", band1_stats)\n    print(f\"Canción más popular de {band1}:\", band1_top_track)\n    \n    print(f\"\\n{band2} Stats:\", band2_stats)\n    print(f\"Canción más popular de {band2}:\", band2_top_track)\n    \n    more_followers = band1 if band1_stats['followers'] > band2_stats['followers'] else band2\n    more_popular_track = band1 if band1_top_track['playCount'] > band2_top_track['playCount'] else band2\n    \n    print(f\"\\nLa banda con más seguidores es: {more_followers}\")\n    print(f\"La banda con la canción más popular es: {more_popular_track}\")\n\nband1 = input(\"Introduce el nombre del primer grupo: \")\nband2 = input(\"Introduce el nombre del segundo grupo: \")\n\ncompare_bands(band1, band2)\n"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/python/mouredev.py",
    "content": "import base64\nimport requests\n\nCLIENT_ID = \"Mi CLIENT_ID\"\nCLIENT_SECRET = \"Mi CLIENT_SECRET\"\n\n\ndef get_token() -> str:\n    url = \"https://accounts.spotify.com/api/token\"\n    headers = {\n        \"Authorization\": \"Basic \" + base64.b64encode(f\"{CLIENT_ID}:{CLIENT_SECRET}\".encode()).decode(),\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n    }\n    data = {\"grant_type\": \"client_credentials\"}\n\n    response = requests.post(url, headers=headers, data=data)\n    if response.status_code != 200:\n        raise Exception(\n            f\"Error obteniendo el token de Spotify: {response.json()}.\"\n        )\n\n    return response.json()[\"access_token\"]\n\n\ndef search_artist(token: str, name: str):\n    url = f\"https://api.spotify.com/v1/search?q={name}&type=artist&limit=1\"\n    headers = {\"Authorization\": f\"Bearer {token}\"}\n\n    response = requests.get(url, headers=headers)\n    if response.status_code != 200:\n        raise Exception(\n            f\"Error obteniendo el artista: {response.json()}.\"\n        )\n\n    results = response.json()\n    if results[\"artists\"][\"items\"]:\n        return results[\"artists\"][\"items\"][0][\"id\"]\n    else:\n        raise Exception(\n            f\"El artista {name} no se ha encontrado.\"\n        )\n\n\ndef get_artist_data(token: str, id: str):\n\n    url = f\"https://api.spotify.com/v1/artists/{id}\"\n    headers = {\"Authorization\": f\"Bearer {token}\"}\n\n    response = requests.get(url, headers=headers)\n    if response.status_code != 200:\n        raise Exception(\n            f\"Error obteniendo los datos del artista: {response.json()}.\"\n        )\n\n    results = response.json()\n    return {\n        \"name\": results[\"name\"],\n        \"followers\": results[\"followers\"][\"total\"],\n        \"popularity\": results[\"popularity\"]\n    }\n\n\ndef get_artist_top_track(token: str, id: str):\n\n    url = f\"https://api.spotify.com/v1/artists/{id}/top-tracks\"\n    headers = {\"Authorization\": f\"Bearer {token}\"}\n\n    response = requests.get(url, headers=headers)\n    if response.status_code != 200:\n        raise Exception(\n            f\"Error obteniendo las canciones del artista: {response.json()}.\"\n        )\n\n    results = response.json()\n\n    top_track = max(results[\"tracks\"], key=lambda track: track[\"popularity\"])\n\n    return {\n        \"name\": top_track[\"name\"],\n        \"popularity\": top_track[\"popularity\"]\n    }\n\n\n# 1. Token\ntoken = get_token()\n\n# 2. IDs\nartist_1_id = search_artist(token, \"Taylor Swift\")\nartist_2_id = search_artist(token, \"Linkin Park\")\n\n# 3. Data\n\n# 3.1. Seguidores y popularidad\nartist_1 = get_artist_data(token, artist_1_id)\nartist_2 = get_artist_data(token, artist_2_id)\n\n# 3.2. Canción más popular\ntop_track_artist_1 = get_artist_top_track(token, artist_1_id)\ntop_track_artist_2 = get_artist_top_track(token, artist_2_id)\n\n# 4. Comparativa\nartist_1_counter = 0\nartist_2_counter = 0\n\nprint(f\"\\nComparación de artistas:\\n\")\nprint(f\"{artist_1[\"name\"]}\")\nprint(f\"{artist_2[\"name\"]}\")\n\n# 4.1. Seguidores\nprint(f\"\\nComparación seguidores:\\n\")\nprint(f\"Seguidores {artist_1[\"name\"]}: {artist_1[\"followers\"]}\")\nprint(f\"Seguidores {artist_2[\"name\"]}: {artist_2[\"followers\"]}\")\n\nif artist_1[\"followers\"] > artist_2[\"followers\"]:\n    print(f\"{artist_1[\"name\"]} es más popular en número de seguidores.\")\n    artist_1_counter += 1\nelse:\n    print(f\"{artist_2[\"name\"]} es más popular en número de seguidores.\")\n    artist_2_counter += 1\n\n# 4.2. Popularidad\nprint(f\"\\nComparación popularidad:\\n\")\nprint(f\"Popularidad {artist_1[\"name\"]}: {artist_1[\"popularity\"]}\")\nprint(f\"Popularidad {artist_2[\"name\"]}: {artist_2[\"popularity\"]}\")\n\nif artist_1[\"popularity\"] > artist_2[\"popularity\"]:\n    print(f\"{artist_1[\"name\"]} es más popular a nivel general.\")\n    artist_1_counter += 1\nelse:\n    print(f\"{artist_2[\"name\"]} es más popular a nivel general.\")\n    artist_2_counter += 1\n\n# 4.3. Canción\nprint(f\"\\nComparación canción:\\n\")\nprint(\n    f\"Canción {top_track_artist_1[\"name\"]} ({artist_1[\"name\"]}): {top_track_artist_1[\"popularity\"]} popularidad.\")\nprint(\n    f\"Canción {top_track_artist_2[\"name\"]} ({artist_2[\"name\"]}): {top_track_artist_2[\"popularity\"]} popularidad.\")\n\nif top_track_artist_1[\"popularity\"] > top_track_artist_2[\"popularity\"]:\n    print(\n        f\"La canción {top_track_artist_1[\"name\"]} de {artist_1[\"name\"]} es más popular.\")\n    artist_1_counter += 1\nelse:\n    print(\n        f\"La canción {top_track_artist_2[\"name\"]} de {artist_2[\"name\"]} es más popular.\")\n    artist_2_counter += 1\n\n# 5. Resultado\nprint(f\"\\nResultado final:\\n\")\nprint(\n    f\"{artist_1[\"name\"] if artist_1_counter > artist_2_counter else artist_2[\"name\"]} es más popular.\")\n"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/python/neslarra.py",
    "content": "\"\"\"\n EJERCICIO:\n ¡Dos de las bandas más grandes de la historia están de vuelta!\n Oasis y Linkin Park han anunciado nueva gira, pero, ¿quién es más popular?\n Desarrolla un programa que se conecte al API de Spotify y los compare.\n Requisitos:\n 1. Crea una cuenta de desarrollo en https://developer.spotify.com.\n 2. Conéctate al API utilizando tu lenguaje de programación.\n 3. Recupera datos de los endpoint que tú quieras.\n Acciones:\n 1. Accede a las estadísticas de las dos bandas.\n    Por ejemplo: número total de seguidores, escuchas mensuales,\n    canción con más reproducciones...\n 2. Compara los resultados de, por lo menos, 3 endpoint.\n 3. Muestra todos los resultados por consola para notificar al usuario.\n 4. Desarrolla un criterio para seleccionar qué banda es más popular.\n\"\"\"\nimport spotipy\nfrom spotipy.oauth2 import SpotifyClientCredentials\n\n\nclass Artist:\n\n    def __init__(self, name: str):\n        artists = spotify.search(q='artist:' + name, type='artist')['artists']\n        for art in artists['items']:\n            if art['name'] == name:\n                self.artist_name = name\n                self.artist_id = art['id']\n                self.artist_image = art['images'][0]['url']\n                self.artist_followers = art['followers']['total']\n                self.artist_genres = art['genres']\n                self.artist_popularity = art['popularity']\n                self.artist_songs_url = art['external_urls']['spotify']\n            break\n        if not self.artist_name:\n            raise \"Exception: Artista NO encontrado.\"\n\n    def get_name(self):\n        return self.artist_name\n\n    def get_popularity(self):\n        return self.artist_popularity\n\n    def get_id(self):\n        return self.artist_id\n\n    def get_followers(self):\n        return self.artist_followers\n\n    def get_genres(self):\n        return self.artist_genres\n\n    def get_image(self):\n        return self.artist_image\n\n    def get_albums(self):\n        albums = spotify.artist_albums(self.artist_id, country='AR')\n        return [x['name'] for x in albums['items'] if x['album_type'] == 'album']\n\n    def get_most_popular_song(self):\n        top_tracks = spotify.artist_top_tracks(self.artist_id)\n        track = top_tracks[\"tracks\"][0]\n        return [track[\"name\"], track[\"popularity\"]]\n\n    def where_listen(self):\n        return self.artist_songs_url\n\n\nclass Comparision:\n\n    def __init__(self, artist_1: Artist, artist_2: Artist):\n        self.artist_1 = artist_1\n        self.artist_2 = artist_2\n        self.rank = [0, 0]\n\n    def add_point(self, artist: int):\n        self.rank[artist] += 1\n\n    def get_common_genres(self):\n        g1 = self.artist_1.get_genres()\n        g2 = self.artist_2.get_genres()\n        genres = set.intersection(set(g1), set(g2))\n        return genres\n\n    def get_most_popular_band(self):\n        f1 = self.artist_1.get_popularity()\n        f2 = self.artist_2.get_popularity()\n        if f1 > f2:\n            self.add_point(0)\n            return self.artist_1.get_name()\n        elif f2 > f1:\n            self.add_point(1)\n            return self.artist_2.get_name()\n        else:\n            self.add_point(0)\n            self.add_point(1)\n            return \"\"\n\n    def get_most_popular_song(self):\n        s1 = self.artist_1.get_most_popular_song()\n        s2 = self.artist_2.get_most_popular_song()\n        if s1[1] > s2[1]:\n            self.add_point(0)\n            return [s1[0], self.artist_1.get_name()]\n        elif s2[1] > s1[1]:\n            self.add_point(1)\n            return [s2[0], self.artist_2.get_name()]\n        else:\n            self.add_point(0)\n            self.add_point(1)\n            return [s1[0], self.artist_1.get_name(), s2[0], self.artist_2.get_name()]\n\n    def get_most_follwed(self):\n        f1 = self.artist_1.get_followers()\n        f2 = self.artist_2.get_followers()\n        if f1 > f2:\n            self.add_point(0)\n            return self.artist_1.get_name()\n        elif f2 > f1:\n            self.add_point(1)\n            return self.artist_2.get_name()\n        else:\n            self.add_point(0)\n            self.add_point(1)\n            return \"\"\n\n    def get_greater_number_of_albums(self):\n        a1 = self.artist_1.get_albums()\n        a2 = self.artist_2.get_albums()\n        if a1.__len__() > a2.__len__():\n            self.add_point(0)\n            return [self.artist_1.get_name(), a1.__len__()]\n        elif a2.__len__() > a1.__len__():\n            self.add_point(1)\n            return [self.artist_2.get_name(), a2.__len__()]\n        else:\n            self.add_point(0)\n            self.add_point(1)\n            return [a1.__len__()]\n\n    def get_better_band(self):\n        if self.rank[0] > self.rank[1]:\n            return self.artist_1.get_name()\n        elif self.rank[1] > self.rank[0]:\n            return self.artist_2.get_name()\n        else:\n            return \"\"\n\n    def get_report(self):\n        report = []\n        message = f\"Las bandas {self.artist_1.get_name()} y {self.artist_2.get_name()} \"\n        common_genres = \"\"\n        for genre in self.get_common_genres():\n            common_genres += genre + \", \"\n        report.append(message + \"tocan en común \" + common_genres[:-2] if common_genres else message + \"no tienen géneros en común.\")\n\n        band = self.get_most_follwed()\n        report.append(band + \" es la más seguida.\" if band else \"Ambas bandas son igual de seguidas.\")\n\n        band = self.get_most_popular_band()\n        report.append(band + \" es la más popular.\" if band else \"Ambas bandas son igual de populares.\")\n\n        song = self.get_most_popular_song()\n        if song.__len__() == 2:\n            report.append(f\"La canción más popular es {song[0]} de {song[1]}\")\n        else:\n            report.append(f\"Las canciones más populares son {song[0]} de {song[1]} y {song[2]} de {song[3]}\")\n\n        albums = self.get_greater_number_of_albums()\n        if albums.__len__() == 2:\n            report.append(f\"La banda {albums[0]} editó más álbumes ({albums[1]}).\")\n        else:\n            report.append(f\"Ambas bandas editaron ({albums[1]}) álbumes.\")\n\n        band = self.get_better_band()\n        report.append(band + \" es la mejor banda.\" if band else \"Ambas bandas son igual de buenas.\")\n\n        report.append(f\"Escuchá a {self.artist_1.get_name()} en {self.artist_1.where_listen()}\")\n        report.append(f\"Escuchá a {self.artist_2.get_name()} en {self.artist_2.where_listen()}\")\n\n        return report\n\n\nmy_client_id = input(\"Ingresá tu Spotify client_id: \")\nmy_client_secret = input(\"Ingresa tu Spotify client_secret: \")\n\nmy_creds = SpotifyClientCredentials(client_id=my_client_id, client_secret=my_client_secret)\nspotify = spotipy.Spotify(client_credentials_manager=my_creds)\n\noasis = Artist('Oasis')\nlpark = Artist('Linkin Park')\n\ncomparision = Comparision(oasis, lpark)\nfor result in comparision.get_report():\n    print(result)\n"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/python/oriaj3.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * ¡Dos de las bandas más grandes de la historia están de vuelta!\n * Oasis y Linkin Park han anunciado nueva gira, pero, ¿quién es más popular?\n * Desarrolla un programa que se conecte al API de Spotify y los compare.\n * Requisitos:\n * 1. Crea una cuenta de desarrollo en https://developer.spotify.com.\n * 2. Conéctate al API utilizando tu lenguaje de programación.\n * 3. Recupera datos de los endpoint que tú quieras.\n * Acciones:\n * 1. Accede a las estadísticas de las dos bandas.\n *    Por ejemplo: número total de seguidores, escuchas mensuales,\n *    canción con más reproducciones...\n * 2. Compara los resultados de, por lo menos, 3 endpoint.\n * 3. Muestra todos los resultados por consola para notificar al usuario.\n * 4. Desarrolla un criterio para seleccionar qué banda es más popular.\n */\n\"\"\"\n\nimport os\nimport requests\nfrom dotenv import load_dotenv\n\nload_dotenv() #Carga las variables del archivo .env\n\nCLIENT_ID = os.getenv(\"SPOTIFY_CLIENT_ID\")\nCLIENT_SECRET = os.getenv(\"SPOTIFY_CLIENT_SECRET\")\nX_RAPIDAPI_KEY = os.getenv(\"X_RAPIDAPI_KEY\")\n\n#TODO: IMPLEMENTAR EXCEPCIONES PARA MANEJAR ERRORES DE CONEXIÓN\n\n#Función para obtener el token de acceso\ndef get_access_token(client_id, client_secret):\n    url = \"https://accounts.spotify.com/api/token\"\n    data={\"grant_type\":\"client_credentials\" }\n    auth=(client_id, client_secret)\n    response = requests.post(url=url, data=data, auth=auth)\n    #Verificar si la respuesta es correcta\n    if response.status_code == 200:\n        token_data = response.json()\n        return token_data.get(\"access_token\")\n    else:\n        #Mostrar error\n        print(f\"Error: Unable to get access token. Status Code {response.status_code}.\")\n        return None\n\n\n#Función para obtener el ID de un artista\ndef get_artist_ID(artist_name, token):\n    url = f\"https://api.spotify.com/v1/search?q={artist_name}&type=artist\"\n    headers = {\"Authorization\": f\"Bearer {token}\"}\n    response = requests.get(url=url, headers=headers)\n\n    if response.status_code == 200:\n        response_data = response.json()\n        items = response_data.get(\"artists\", {}).get(\"items\", [])\n\n        if items:\n            # Buscar el artista cuyo nombre coincide con el proporcionado\n            for artist in items:\n                if artist.get(\"name\").lower() == artist_name.lower():\n                    artist_id = artist.get(\"id\")\n                    return artist_id\n            \n            # Si no se encontró coincidencia exacta, devolver el primer resultado\n            return items[0].get(\"id\")\n        else:\n            print(\"No se encontraron artistas.\")\n            return None\n    else:\n        print(f\"Error: Unable to get artist data. Status Code {response.status_code}.\")\n        return None\n\n#Función para obtener el nombre de un artista, sus generos, seguidores y su popularidad dado un ID\ndef get_artist_data(artist_id, token):\n    url = f\"https://api.spotify.com/v1/artists/{artist_id}\"\n    headers = {\"Authorization\": f\"Bearer {token}\"}\n    response = requests.get(url=url, headers=headers)\n\n    if response.status_code == 200:\n        response_data = response.json()\n        artist_name = response_data.get(\"name\")\n        artist_genres = response_data.get(\"genres\")\n        artist_followers = response_data.get(\"followers\").get(\"total\")\n        artist_popularity = response_data.get(\"popularity\")\n\n        return artist_name, artist_genres, artist_followers, artist_popularity\n    else:\n        print(f\"Error: Unable to get artist data. Status Code {response.status_code}.\")\n        return None, None, None\n    \n# Función para obtener el número de escuchas mensuales de un artista con el API de RapidAPI\ndef get_monthly_listeners(artist_id, x_rapidapi_key):\n    url = \"https://spotify-artist-monthly-listeners.p.rapidapi.com/artists/spotify_artist_monthly_listeners\"\n    querystring = {\"spotify_artist_id\": artist_id}\n    headers = {\n        \"x-rapidapi-key\": x_rapidapi_key,\n        \"x-rapidapi-host\": \"spotify-artist-monthly-listeners.p.rapidapi.com\"\n    }\n\n    try:\n        response = requests.get(url, headers=headers, params=querystring)\n        if response.status_code == 200:\n            response_data = response.json()\n            monthly_listeners = response_data.get(\"monthly_listeners\")\n            return monthly_listeners\n        else:\n            print(f\"Error: Unable to get monthly listeners. Status Code {response.status_code}.\")\n            print(response.json())  # Imprimir el contenido de la respuesta para más detalles\n            return None\n    except Exception as e:\n        print(f\"An error occurred: {e}\")\n        return None\n    \n#Función para obtener las mejores canciones de un artista\ndef get_artist_top_tracks(artist_id, token):\n    url = f\"https://api.spotify.com/v1/artists/{artist_id}/top-tracks?market=ES\"\n    headers = {\"Authorization\": f\"Bearer {token}\"}\n    response = requests.get(url=url, headers=headers)\n    if response.status_code == 200:\n        response_data = response.json()\n        return response_data\n    else:\n        print(f\"Error: Unable to get top tracks. Status Code {response.status_code}.\")\n        return None\n\n#Función para obtener los índices de popularidad de mejores canciones de un artista\ndef get_top_tracks_popularity(top_tracks):\n    top_tracks_popularity = []\n    for track in top_tracks.get(\"tracks\", []):\n        track_name = track.get(\"name\")\n        track_popularity = track.get(\"popularity\")\n        top_tracks_popularity.append((track_name, track_popularity))\n    mean = sum([track[1] for track in top_tracks_popularity]) / len(top_tracks_popularity)\n    #Obtiene la canción más popular\n    top_tracks_popularity.sort(key=lambda x: x[1], reverse=True)\n    return mean, top_tracks_popularity, top_tracks_popularity[0]\n\n#Función para comparar la popularidad de dos artistas:\ndef compare_two_artist(artist1_name, artist2_name, token):\n    id1 = get_artist_ID(artist1_name, token)\n    id2 = get_artist_ID(artist2_name, token)\n\n    top_tracks1 = get_artist_top_tracks(id1, token)\n    top_tracks2 = get_artist_top_tracks(id2, token)\n\n    mean1, top_tracks1, top_track1 = get_top_tracks_popularity(top_tracks1)\n    mean2, top_tracks2, top_track2 = get_top_tracks_popularity(top_tracks2)\n\n    name1, gen1, popularity1, followers1 = get_artist_data(id1, token)\n    name2, gen2, popularity2, followers2 = get_artist_data(id2, token)\n\n    points1 = 0\n    points2 = 0 \n    #Mostrar los datos de los artistas\n    print(f\"\\n*** Comparación de popularidad entre {name1} y {name2}: ***\\n\")\n    print(f\"[Artista 1]: {name1}\")\n    print(f\"Géneros: {gen1}\")\n    print(f\"Popularidad: {popularity1}\")\n    print(f\"Seguidores: {followers1}\")\n    print(f\"Media de popularidad mejores canciones: {mean1}\")\n    print(f\"Mejores canciones: {top_tracks1}\\n\")\n\n    print(f\"\\n[Artista 2]: {name2}\")\n    print(f\"Géneros: {gen2}\")\n    print(f\"Popularidad: {popularity2}\")\n    print(f\"Seguidores: {followers2}\")\n    print(f\"Media de popularidad mejores canciones: {mean2}\")\n    print(f\"Mejores canciones: {top_tracks2}\\n\")\n\n    input(\"Presiona Enter para continuar...\")\n    #Comparar seguidores\n    print(\"\\n - Batalla 1: Comparación de seguidores\")\n    if followers1 > followers2:\n        print(f\"{artist1_name} tiene más seguidores.\")\n        points1 += 1 \n    elif followers1 < followers2:\n        print(f\"{artist2_name} tiene más seguidores.\")\n        points2 += 1\n    else:\n        print(f\"{artist1_name} y {artist2_name} tienen el mismo número de seguidores.\")\n\n    # Comparar índices de popularidad total\n    print(\"\\n - Batalla 2: Comparación de popularidad\")\n    if popularity1 > popularity2:\n        print(f\"{artist1_name} tiene un índice de popularidad mayor.\")\n        points1 += 1\n    elif popularity1 < popularity2:\n        print(f\"{artist2_name} tiene un índice de popularidad mayor.\")\n        points2 += 1\n    else:\n        print(f\"{artist1_name} y {artist2_name} tienen el mismo índice de popularidad.\")\n\n    # Comparar popularidad de la mejor canción\n    print(\"\\n - Batalla 3: Mejor canción\")\n    if top_track1[1] > top_track2[1]:\n        print(f\"La canción más popular de {artist1_name} es más popular\")\n        points1 += 1\n    elif top_track1[1] < top_track2[1]:\n        print(f\"La canción más popular de {artist2_name} es más popular\")\n        points2 += 1\n    else:\n        print(f\"La canción más popular de {artist1_name} y {artist2_name} tienen la misma popularidad.\")\n\n    #Comparar la media de popularidad de las canciones más populares\n    print(\"\\n - Batalla Final: Mejores canciones\")\n    if mean1 > mean2:\n        print(f\"La media de popularidad de las canciones de {artist1_name} es mayor\")\n        points1 += 1\n    elif mean1 < mean2:\n        print(f\"La media de popularidad de las canciones de {artist2_name} es mayor\")\n        points2 += 1\n    else:\n        print(f\"La media de popularidad de las canciones de {artist1_name} y {artist2_name} es la misma.\")\n\n    #Recuento de puntos\n    print(\"\\n***El ganador es ... ***\")\n    if points1 > points2:\n        print(f\"{artist1_name}!\\n\\n\")\n    elif points1 < points2:\n        print(f\"{artist2_name}!\\n\\n\")\n    else:\n        print(\"¡Es un empate!\")\n    input(\"Presiona Enter para continuar...\")\n\n\n#Ejemplos de funcionamiento del programa\n#Obtener el token de acceso\nTOKEN_LOGIN = get_access_token(CLIENT_ID, CLIENT_SECRET)\n\n#Comparar dos artistas\ncompare_two_artist(\"Natos y Waor\", \"Ajax y Prok\", TOKEN_LOGIN)\ncompare_two_artist(\"Oasis\", \"Linkin Park\", TOKEN_LOGIN)\n"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/python/pyramsd.py",
    "content": "import requests\nimport base64\n\nclient_id = \"CLIENT_ID\"\nclient_secret = \"CLIENT_SECRET\"\n\nauth_url = 'https://accounts.spotify.com/api/token'\nbase_url = 'https://api.spotify.com/v1/'\n\nartists = {\n    \"Oasis\": \"2DaxqgrOhkeH0fpeiQq2f4\",\n    \"Linkin Park\": \"6XyY86QOPPrYVGvF9ch6wz\"\n}\n\n# Función para obtener el token de autenticación\ndef get_token(client_id, client_secret):\n    auth_str = f\"{client_id}:{client_secret}\"\n    b64_auth_str = base64.b64encode(auth_str.encode()).decode()\n\n    headers = {\n        'Authorization': f'Basic {b64_auth_str}',\n    }\n    data = {\n        'grant_type': 'client_credentials'\n    }\n    \n    response = requests.post(auth_url, headers=headers, data=data)\n    if response.status_code != 200:\n        raise Exception(\"Error en la autenticación. Verifica tus credenciales.\")\n    \n    response_data = response.json()\n    return response_data['access_token']\n\n# Función para obtener datos del artista (Oasis y Linkin Park)\ndef get_artist_data(artist_id, token):\n    headers = {\n        'Authorization': f'Bearer {token}',\n    }\n    try:\n        artist_url = f'{base_url}artists/{artist_id}'\n        artist_data = requests.get(artist_url, headers=headers).json()\n\n        top_tracks_url = f'{base_url}artists/{artist_id}/top-tracks?market=US'\n        top_tracks_data = requests.get(top_tracks_url, headers=headers).json()\n        \n        return artist_data, top_tracks_data\n    except requests.exceptions.RequestException as e:\n        print(f\"Error al obtener datos del artista: {e}\")\n        return None, None\n\ndef compare_artists(artists_data):\n    for artist, data in artists_data.items():\n        artist_info, top_tracks = data\n        if artist_info and top_tracks:\n            print(f\"Artista: {artist}\")\n            print(f\"Seguidores: {artist_info['followers']['total']}\")\n            print(f\"Popularidad: {artist_info['popularity']}\")\n            print(f\"Canción más popular: {top_tracks['tracks'][0]['name']} - {top_tracks['tracks'][0]['popularity']} popularidad\\n\")\n        else:\n            print(f\"No se pudo obtener datos para {artist}\")\n\ndef main():\n    # Obtener el token de acceso\n    token = get_token(client_id, client_secret)\n    \n    # Obtener datos\n    artists_data = {}\n    for artist_name, artist_id in artists.items():\n        artist_info, top_tracks = get_artist_data(artist_id, token)\n        artists_data[artist_name] = (artist_info, top_tracks)\n    \n    compare_artists(artists_data)\n\nif __name__ == \"__main__\":\n    main()\n    \n"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/python/raulG91.py",
    "content": "import requests\nimport json\ndef getToken()->str:\n    token_url = \"https://accounts.spotify.com/api/token\"\n    data = {\n        'grant_type':'client_credentials',\n        'client_id': \"YOUR CLIENT ID\",\n        'client_secret': \"YOUR SECRET\"\n\n    }\n    result =  requests.post(token_url,data=data)\n    return json.loads(result.text)['access_token']\n   \ndef getGroupDetails(groupId:str,name:str):\n\n    artist_info = {\n        'name':name,\n        'popularity': 0,\n        'followers': 0,\n        'songs_popularity':0,\n        'total_albums':0\n    }\n    api_url = \"https://api.spotify.com/v1/\"\n    bearer_token = getToken()\n    headers = {\n        \"Authorization\": f'Bearer {bearer_token}'\n    }\n\n    #Get popularity and followers from artists API\n    url = f'{api_url}artists/{groupId}'\n    result = requests.get(url=url,headers=headers)\n\n    if result.status_code >= 200 and result.status_code < 300:\n        artist_dict = json.loads(result.text)\n        artist_info['popularity'] = artist_dict['popularity']\n        artist_info['followers'] = artist_dict['followers']['total']\n    else:\n        print(\"Connection error\")\n\n    #Get averrage  top-tracks popularity\n    url = f'{api_url}artists/{groupId}/top-tracks?market=ES'\n    result = requests.get(url=url,headers=headers)\n    averrage_popularity = 0\n\n    if result.status_code >= 200 and result.status_code < 300:\n        tracks = json.loads(result.text)['tracks']\n        sum = 0\n        for track in tracks:\n            sum += track['popularity']\n        averrage_popularity = sum / len(tracks)\n        artist_info['songs_popularity']=averrage_popularity\n    else:\n        print(\"Connection error\")\n\n    #Get albums\n    url = f'{api_url}artists/{groupId}/albums'\n\n    result = requests.get(url=url,headers=headers)\n    if result.status_code >= 200 and result.status_code < 300:\n        items = json.loads(result.text)['items']\n        artist_info['total_albums'] = len(items)\n\n    else:\n        print(\"Connection error\")\n\n    return artist_info\n\ndef choose_band(band1:dict,band2:dict)->str:\n    band1_count = 0\n    band2_count = 0\n    if band1['popularity'] > band2['popularity']:\n        band1_count += 1\n    elif band1['popularity'] < band2['popularity']:\n        band2_count += 1\n\n    if band1['followers'] > band2['followers']:\n        band1_count += 1\n    elif band1['followers'] < band2['followers']:\n        band2_count +=1\n\n    if band1['songs_popularity'] > band2['songs_popularity']:\n        band1_count += 1\n    elif band1['songs_popularity'] < band2['songs_popularity']:\n        band2_count += 1\n\n    if band1['total_albums'] > band2['total_albums']   :\n        band1_count += 1\n    elif band1['total_albums'] < band2['total_albums']:\n        band2_count += 1     \n\n    if band1_count > band2_count:\n        return band1['name']\n    else:\n        return band2['name']\n\n    \n\noasis_id = \"2DaxqgrOhkeH0fpeiQq2f4\"\nlinkin_park_id = \"6XyY86QOPPrYVGvF9ch6wz\"\n\noasis_details = getGroupDetails(oasis_id,\"Oasis\")\nprint('Details for Oasis',oasis_details)\nlinkin_park = getGroupDetails(linkin_park_id,\"Linkin Park\")\nprint(\"Linkin Park details\", linkin_park)\n\nprint(\"Bast band is: \", choose_band(oasis_details,linkin_park))"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/python/rigo93acosta.py",
    "content": "'''\n/*\n * EJERCICIO:\n * ¡Dos de las bandas más grandes de la historia están de vuelta!\n * Oasis y Linkin Park han anunciado nueva gira, pero, ¿quién es más popular?\n * Desarrolla un programa que se conecte al API de Spotify y los compare.\n * Requisitos:\n * 1. Crea una cuenta de desarrollo en https://developer.spotify.com.\n * 2. Conéctate al API utilizando tu lenguaje de programación.\n * 3. Recupera datos de los endpoint que tú quieras.\n * Acciones:\n * 1. Accede a las estadísticas de las dos bandas.\n *    Por ejemplo: número total de seguidores, escuchas mensuales,\n *    canción con más reproducciones...\n * 2. Compara los resultados de, por lo menos, 3 endpoint.\n * 3. Muestra todos los resultados por consola para notificar al usuario.\n * 4. Desarrolla un criterio para seleccionar qué banda es más popular.\n */\n'''\nimport requests\nimport base64\n\nCLIENT_ID = \"\"\nCLIENT_SECRET = \"\"\n\ndef get_token() -> str:\n    url = \"https://accounts.spotify.com/api/token\"\n    headers = {\n        \"Authorization\": \"Basic \" + base64.b64encode(f\"{CLIENT_ID}:{CLIENT_SECRET}\".encode()).decode(),\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n    }\n    data = {\"grant_type\": \"client_credentials\"}\n\n    response = requests.post(url, headers=headers, data=data)\n    if response.status_code != 200:\n        raise Exception(\n            f\"Error obteniendo el token de Spotify: {response.json()}.\"\n        )\n    \n    return response.json()[\"access_token\"]\n\ndef search_artist(token: str, artist: str):\n\n    url = f\"https://api.spotify.com/v1/search?q={artist}&type=artist&limit=1\"\n    headers = {\"Authorization\": f\"Bearer {token}\"}\n    response = requests.get(url, headers=headers)\n    if response.status_code != 200:\n        raise Exception(\n            f\"Error obteniendo el artista: {response.json()}.\"\n    )\n\n    results = response.json()\n    if results[\"artists\"][\"items\"]:\n        return results[\"artists\"][\"items\"][0][\"id\"]\n    else:\n        raise Exception(\n            f\"No se encontró el artista {artist}.\"\n            )\n    \ndef get_artist_data(token: str, id: str):\n    url = f\"https://api.spotify.com/v1/artists/{id}\"\n    headers = {\"Authorization\": f\"Bearer {token}\"}\n    response = requests.get(url, headers=headers)\n    if response.status_code != 200:\n        raise Exception(\n            f\"Error obteniendo datos del artista: {response.json()}.\"\n    )\n\n    results = response.json()\n    return {\n        \"name\": results[\"name\"],\n        \"followers\": results[\"followers\"][\"total\"],\n        \"popularity\": results[\"popularity\"]\n    }\n\ndef get_top_tracks(token: str, id: str):\n    url = f\"https://api.spotify.com/v1/artists/{id}/top-tracks\"\n    headers = {\"Authorization\": f\"Bearer {token}\"}\n\n    response = requests.get(url, headers=headers)\n    if response.status_code != 200:\n        raise Exception(\n            f\"Error obteniendo los top tracks del artista: {response.json()}.\"\n        )\n    \n    results = response.json()\n    top_track = max(results[\"tracks\"], key=lambda track: track[\"popularity\"])\n\n    return {\n        \"name\": top_track[\"name\"],\n        \"popularity\": top_track[\"popularity\"]\n    }\n\ntoken = get_token()\nartist_1_id = search_artist(token, \"Taylor Swift\")\nartist_2_id = search_artist(token, \"Linkin Park\")\n\nart_1 = get_artist_data(token, artist_1_id)\nart_2 = get_artist_data(token, artist_2_id)\n\nart_1_top = get_top_tracks(token, artist_1_id)\nart_2_top = get_top_tracks(token, artist_2_id)\n\nart_1_counter = 0\nart_2_counter = 0\n\nprint(f\"Comparación de seguidores entre \\n {art_1[\"name\"]} y {art_2[\"name\"]}:\")\n\nprint(f\"{art_1[\"name\"]} tiene {art_1[\"followers\"]} de seguidores\")\nprint(f\"{art_2[\"name\"]} tiene {art_2[\"followers\"]} de seguidores\")\n\nif art_1[\"followers\"] > art_2[\"followers\"]:\n    print(f\"{art_1[\"name\"]} tiene más seguidores que {art_2[\"name\"]}\")\n    art_1_counter += 1\nelse:\n    print(f\"{art_2[\"name\"]} tiene más seguidores que {art_1[\"name\"]}\")\n    art_2_counter += 1\n\nprint(f\"\\nComparación de popularidad entre \\n {art_1[\"name\"]} y {art_2[\"name\"]}:\")\nprint(f\"{art_1[\"name\"]} tiene {art_1[\"popularity\"]} de popularidad\")\nprint(f\"{art_2[\"name\"]} tiene {art_2[\"popularity\"]} de popularidad\")\n\nif art_1[\"popularity\"] > art_2[\"popularity\"]:\n    print(f\"{art_1[\"name\"]} es más popular que {art_2[\"name\"]}\")\n    art_1_counter += 1\nelse:\n    print(f\"{art_2[\"name\"]} es más popular que {art_1[\"name\"]}\")\n    art_2_counter += 1\n\nprint(f\"\\nComparación de canción entre \\n {art_1[\"name\"]} y {art_2[\"name\"]}:\")\nprint(f\"{art_1[\"name\"]}, canción popular {art_1_top[\"name\"]} con {art_1_top[\"popularity\"]} de popularidad\")\nprint(f\"{art_2[\"name\"]}, canción popular {art_2_top[\"name\"]} con {art_2_top[\"popularity\"]} de popularidad\")\n\nif art_1_top[\"popularity\"] > art_2_top[\"popularity\"]:\n    print(f\"La canción {art_1_top[\"name\"]} de {art_1[\"name\"]} es más popular.\")\n    art_1_counter += 1\nelse:\n    print(f\"La canción {art_2_top[\"name\"]} de {art_2[\"name\"]} es más popular.\")\n    art_2_counter += 1\n\nprint(f\"\\nResultado final:\")\nprint(\"=\"*64)\nif art_1_counter > art_2_counter:\n    print(f\"{art_1[\"name\"]} es más popular que {art_2[\"name\"]}\")\nelse:\n    print(f\"{art_2[\"name\"]} es más popular que {art_1[\"name\"]}\")\nprint(\"=\"*64)\n"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/python/santyjl.py",
    "content": "#37 OASIS VS LINKIN PARK\n#### Dificultad: Media | Publicación: 09/09/24 | Corrección: 16/09/24\n\n## Ejercicio\n\"\"\"\n/*\n * EJERCICIO:\n * ¡Dos de las bandas más grandes de la historia están de vuelta!\n * Oasis y Linkin Park han anunciado nueva gira, pero, ¿quién es más popular?\n * Desarrolla un programa que se conecte al API de Spotify y los compare.\n * Requisitos:\n * 1. Crea una cuenta de desarrollo en https://developer.spotify.com.\n * 2. Conéctate al API utilizando tu lenguaje de programación.\n * 3. Recupera datos de los endpoint que tú quieras.\n * Acciones:\n * 1. Accede a las estadísticas de las dos bandas.\n *    Por ejemplo: número total de seguidores, escuchas mensuales,\n *    canción con más reproducciones...\n * 2. Compara los resultados de, por lo menos, 3 endpoint.\n * 3. Muestra todos los resultados por consola para notificar al usuario.\n * 4. Desarrolla un criterio para seleccionar qué banda es más popular.\n */\n\"\"\"\nimport base64\n\nimport requests\n\n# Credenciales de Spotify\nclient_id = ''\nclient_secret = ''\n\n# Obtener el token de acceso\ndef get_access_token(client_id, client_secret):\n    auth_url = 'https://accounts.spotify.com/api/token'\n    auth_header = base64.b64encode(f\"{client_id}:{client_secret}\".encode()).decode()\n    headers = {\n        'Authorization': f'Basic {auth_header}',\n        'Content-Type': 'application/x-www-form-urlencoded'\n    }\n    data = {\n        'grant_type': 'client_credentials'\n    }\n    response = requests.post(auth_url, headers=headers, data=data)\n    response_data = response.json()\n    return response_data['access_token']\n\n# Obtener datos del artista\ndef get_artist_data(artist_name, access_token):\n    search_url = 'https://api.spotify.com/v1/search'\n    headers = {\n        'Authorization': f'Bearer {access_token}'\n    }\n    params = {\n        'q': artist_name,\n        'type': 'artist'\n    }\n    response = requests.get(search_url, headers=headers, params=params)\n    artist_data = response.json()['artists']['items'][0]\n    return artist_data\n\n# Comparar estadísticas de las bandas\ndef compare_bands(artist1, artist2):\n    access_token = get_access_token(client_id, client_secret)\n    artist1_data = get_artist_data(artist1, access_token)\n    artist2_data = get_artist_data(artist2, access_token)\n\n    print(f\"\"\"{artist1}:\n            Followers: {artist1_data['followers']['total']} de seguidores en total\n            Popularity: {artist1_data['popularity']} puntos de popularidad\n            Generos: {artist1_data['genres']}\n            \"\"\")\n    print(f\"\"\"{artist2}:\n            Followers: {artist2_data['followers']['total']} de seguidores en total\n            Popularity: {artist2_data['popularity']} puntos de popularidad\n            Generos: {artist2_data['genres']}\n            \"\"\")\n\n    if artist1_data['followers']['total'] > artist2_data['followers']['total']:\n        print(f\"{artist1} es más popular que {artist2}.\")\n    else:\n        print(f\"{artist2} es más popular que {artist1}.\")\n\n# Uso del programa\ncompare_bands('soda stereo', 'Los enanitos verdes')"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/rust/kenysdev.rs",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - Rust\n_____________________________________\n37 OASIS VS LINKIN PARK\n------------------------------------\n* ¡Dos de las bandas más grandes de la historia están de vuelta!\n* Oasis y Linkin Park han anunciado nueva gira, pero, ¿quién es más popular?\n* Desarrolla un programa que se conecte al API de Spotify y los compare.\n* Requisitos:\n* 1. Crea una cuenta de desarrollo en https://developer.spotify.com.\n* 2. Conéctate al API utilizando tu lenguaje de programación.\n* 3. Recupera datos de los endpoint que tú quieras.\n* Acciones:\n* 1. Accede a las estadísticas de las dos bandas.\n*    Por ejemplo: número total de seguidores, escuchas mensuales,\n*    canción con más reproducciones...\n* 2. Compara los resultados de, por lo menos, 3 endpoint.\n* 3. Muestra todos los resultados por consola para notificar al usuario.\n* 4. Desarrolla un criterio para seleccionar qué banda es más popular.\n\n[dependencies]\ntokio = { version = \"1.37.0\", features = [\"full\"] }\ndotenv = \"0.15.0\"\nrspotify = \"0.13.3\"\n*/\n\nuse dotenv::dotenv;\nuse rspotify::{\n    model::{ArtistId, FullArtist, SearchType, SearchResult},\n    prelude::*,\n    ClientCredsSpotify, Credentials,\n};\n\nstruct Spotify {\n    sp: ClientCredsSpotify,\n}\n\nimpl Spotify {\n    async fn new() -> Result<Self, Box<dyn std::error::Error>> {\n        dotenv().ok();\n        let creds = Credentials::from_env().unwrap();\n        let sp = ClientCredsSpotify::new(creds);\n        sp.request_token().await?;\n        Ok(Self { sp })\n    }\n\n    async fn get_most_popular_artist(&self, name: &str) -> Result<FullArtist, Box<dyn std::error::Error>> {\n    let search_result = self.sp.search(\n        name,\n        SearchType::Artist,\n        None,\n        None,\n        Some(3),\n        None,\n    ).await?;\n\n    match search_result {\n        SearchResult::Artists(page) => {\n            page.items.into_iter().max_by_key(|artist| artist.popularity)\n                .ok_or_else(|| format!(\"No artists found for '{}'\", name).into())\n        },\n        _ => Err(format!(\"Unexpected search result for '{}'\", name).into()),\n    }\n}\n\n    async fn artist_top_tracks(&self, id_artist: ArtistId<'_>) -> Option<Vec<rspotify::model::FullTrack>> {\n        self.sp.artist_top_tracks(id_artist, None).await.ok()\n    }\n    \n}\n\nstruct Versus {\n    a1: FullArtist,\n    a2: FullArtist,\n    sp: Spotify,\n    a1_score: u32,\n    a2_score: u32,\n}\n\nimpl Versus {\n    fn new(artist1: FullArtist, artist2: FullArtist, spotify_instance: Spotify) -> Self {\n        Self {\n            a1: artist1,\n            a2: artist2,\n            sp: spotify_instance,\n            a1_score: 0,\n            a2_score: 0,\n        }\n    }\n\n    fn popularity(&mut self) {\n        let a1_pop = self.a1.popularity;\n        let a2_pop = self.a2.popularity;\n\n        println!(\"Popularidad: {} vs {}\", a1_pop, a2_pop);\n        if a1_pop > a2_pop {\n            self.a1_score += 1;\n        } else if a2_pop > a1_pop {\n            self.a2_score += 1;\n        }\n    }\n\n    fn followers(&mut self) {\n        let a1_foll = self.a1.followers.total;\n        let a2_foll = self.a2.followers.total;\n\n        println!(\"Seguidores: {} vs {}\", a1_foll, a2_foll);\n        if a1_foll > a2_foll {\n            self.a1_score += 1;\n        } else if a2_foll > a1_foll {\n            self.a2_score += 1;\n        }\n    }\n\n    async fn top3_tracks(&mut self) -> Result<(), Box<dyn std::error::Error>> {\n        let a1_top = self.sp.artist_top_tracks(self.a1.id.clone()).await.unwrap_or_default();\n        let a2_top = self.sp.artist_top_tracks(self.a2.id.clone()).await.unwrap_or_default();\n        let a1_pop: u32 = a1_top.iter().take(3).map(|track| track.popularity).sum();\n        let a2_pop: u32 = a2_top.iter().take(3).map(|track| track.popularity).sum();\n        println!(\"Popularidad Top 3 canciones: {} vs {}\", a1_pop, a2_pop);\n\n        if a1_pop > a2_pop {\n            self.a1_score += 1;\n        } else if a2_pop > a1_pop {\n            self.a2_score += 1;\n        }\n        Ok(())\n    }\n\n    fn final_result(&self) {\n        println!(\"\\nRESULTADO FINAL:\");\n        println!(\"{}: {} puntos\", self.a1.name, self.a1_score);\n        println!(\"{}: {} puntos\", self.a2.name, self.a2_score);\n\n        if self.a1_score > self.a2_score {\n            println!(\"\\n¡'{}' gana el versus!\", self.a1.name);\n        } else if self.a2_score > self.a1_score {\n            println!(\"\\n¡'{}' gana el versus!\", self.a2.name);\n        } else {\n            println!(\"\\n¡Es un empate!\");\n        }\n    }\n\n    async fn start(&mut self) -> Result<(), Box<dyn std::error::Error>> {\n        println!(\"{} vs {}\", self.a1.name, self.a2.name);\n        self.popularity();\n        self.followers();\n        self.top3_tracks().await?;\n        self.final_result();\n        Ok(())\n    }\n}\n\n#[tokio::main]\nasync fn main() -> Result<(), Box<dyn std::error::Error>> {\n    println!(\"VERSUS\");\n    let sp = Spotify::new().await?;\n    \n    let artist1 = sp.get_most_popular_artist(\"Oasis\").await?;\n    let artist2 = sp.get_most_popular_artist(\"Linkin Park\").await?;\n\n    let mut vs = Versus::new(artist1, artist2, sp);\n    vs.start().await?;\n\n    Ok(())\n}\n"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/sql/Nicojsuarez2.sql",
    "content": "# #37 OASIS VS LINKIN PARK\n> #### Dificultad: Media | Publicación: 09/09/24 | Corrección: 16/09/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * ¡Dos de las bandas más grandes de la historia están de vuelta!\n * Oasis y Linkin Park han anunciado nueva gira, pero, ¿quién es más popular?\n * Desarrolla un programa que se conecte al API de Spotify y los compare.\n * Requisitos:\n * 1. Crea una cuenta de desarrollo en https://developer.spotify.com.\n * 2. Conéctate al API utilizando tu lenguaje de programación.\n * 3. Recupera datos de los endpoint que tú quieras.\n * Acciones:\n * 1. Accede a las estadísticas de las dos bandas.\n *    Por ejemplo: número total de seguidores, escuchas mensuales,\n *    canción con más reproducciones...\n * 2. Compara los resultados de, por lo menos, 3 endpoint.\n * 3. Muestra todos los resultados por consola para notificar al usuario.\n * 4. Desarrolla un criterio para seleccionar qué banda es más popular.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/typescript/hozlucas28.ts",
    "content": "/* -------------------------------------------------------------------------- */\n/*                                SPOTIFY TYPES                               */\n/* -------------------------------------------------------------------------- */\n\nexport interface ArtistTopTracks {\n    readonly tracks: Track[]\n}\n\nexport interface Track {\n    readonly album: Album\n    readonly artists: Artist[]\n    readonly available_markets: string[]\n    readonly disc_number: number\n    readonly duration_ms: number\n    readonly explicit: boolean\n    readonly external_ids: ExternalIDS\n    readonly external_urls: ExternalUrls\n    readonly href: string\n    readonly id: string\n    readonly is_local: boolean\n    readonly is_playable: boolean\n    readonly name: string\n    readonly popularity: number\n    readonly preview_url: string\n    readonly track_number: number\n    readonly type: string\n    readonly uri: string\n}\n\nexport interface Album {\n    readonly album_type: string\n    readonly artists: Artist[]\n    readonly available_markets: string[]\n    readonly external_urls: ExternalUrls\n    readonly href: string\n    readonly id: string\n    readonly images: Image[]\n    readonly is_playable: boolean\n    readonly name: string\n    readonly release_date: Date\n    readonly release_date_precision: string\n    readonly total_tracks: number\n    readonly type: string\n    readonly uri: string\n}\n\nexport interface Token {\n    readonly access_token: string\n    readonly token_type: string\n    readonly expires_in: number\n}\n\nexport interface TokenError {\n    readonly error: string\n    readonly error_description: string\n}\n\nexport interface ArtistData {\n    readonly external_urls: ExternalUrls\n    readonly followers: Followers\n    readonly genres: string[]\n    readonly href: string\n    readonly id: string\n    readonly images: Image[]\n    readonly name: string\n    readonly popularity: number\n    readonly type: string\n    readonly uri: string\n}\n\nexport interface ExternalUrls {\n    readonly spotify: string\n}\n\nexport interface Followers {\n    readonly href: string\n    readonly total: number\n}\n\nexport interface Image {\n    readonly url: string\n    readonly height: number\n    readonly width: number\n}\n\nexport interface SearchData {\n    readonly tracks: Tracks\n    readonly artists: Artists\n    readonly albums: Albums\n    readonly playlists: Playlists\n    readonly shows: Audiobooks\n    readonly episodes: Episodes\n    readonly audiobooks: Audiobooks\n}\n\nexport interface DataError {\n    readonly error: Error\n}\n\nexport interface Error {\n    readonly status: number\n    readonly message: string\n}\n\nexport interface Albums {\n    readonly href: string\n    readonly limit: number\n    readonly next: string\n    readonly offset: number\n    readonly previous: string\n    readonly total: number\n    readonly items: AlbumElement[]\n}\n\nexport interface AlbumElement {\n    readonly album_type: string\n    readonly total_tracks: number\n    readonly available_markets: string[]\n    readonly external_urls: ExternalUrls\n    readonly href: string\n    readonly id: string\n    readonly images: Image[]\n    readonly name: string\n    readonly release_date: string\n    readonly release_date_precision: string\n    readonly restrictions: Restrictions\n    readonly type: string\n    readonly uri: string\n    readonly artists: Artist[]\n}\n\nexport interface Artist {\n    readonly external_urls: ExternalUrls\n    readonly href: string\n    readonly id: string\n    readonly name: string\n    readonly type: string\n    readonly uri: string\n}\n\nexport interface Restrictions {\n    readonly reason: string\n}\n\nexport interface Artists {\n    readonly href: string\n    readonly limit: number\n    readonly next: string\n    readonly offset: number\n    readonly previous: string\n    readonly total: number\n    readonly items: ArtistsItem[]\n}\n\nexport interface ArtistsItem {\n    readonly external_urls: ExternalUrls\n    readonly followers: Followers\n    readonly genres: string[]\n    readonly href: string\n    readonly id: string\n    readonly images: Image[]\n    readonly name: string\n    readonly popularity: number\n    readonly type: string\n    readonly uri: string\n}\n\nexport interface Audiobooks {\n    readonly href: string\n    readonly limit: number\n    readonly next: string\n    readonly offset: number\n    readonly previous: string\n    readonly total: number\n    readonly items: AudiobooksItem[]\n}\n\nexport interface AudiobooksItem {\n    readonly authors?: Author[]\n    readonly available_markets: string[]\n    readonly copyrights: Copyright[]\n    readonly description: string\n    readonly html_description: string\n    readonly edition?: string\n    readonly explicit: boolean\n    readonly external_urls: ExternalUrls\n    readonly href: string\n    readonly id: string\n    readonly images: Image[]\n    readonly languages: string[]\n    readonly media_type: string\n    readonly name: string\n    readonly narrators?: Author[]\n    readonly publisher: string\n    readonly type: string\n    readonly uri: string\n    readonly total_chapters?: number\n    readonly is_externally_hosted?: boolean\n    readonly total_episodes?: number\n}\n\nexport interface Author {\n    readonly name: string\n}\n\nexport interface Copyright {\n    readonly text: string\n    readonly type: string\n}\n\nexport interface Episodes {\n    readonly href: string\n    readonly limit: number\n    readonly next: string\n    readonly offset: number\n    readonly previous: string\n    readonly total: number\n    readonly items: EpisodesItem[]\n}\n\nexport interface EpisodesItem {\n    readonly audio_preview_url: string\n    readonly description: string\n    readonly html_description: string\n    readonly duration_ms: number\n    readonly explicit: boolean\n    readonly external_urls: ExternalUrls\n    readonly href: string\n    readonly id: string\n    readonly images: Image[]\n    readonly is_externally_hosted: boolean\n    readonly is_playable: boolean\n    readonly language: string\n    readonly languages: string[]\n    readonly name: string\n    readonly release_date: Date\n    readonly release_date_precision: string\n    readonly resume_point: ResumePoint\n    readonly type: string\n    readonly uri: string\n    readonly restrictions: Restrictions\n}\n\nexport interface ResumePoint {\n    readonly fully_played: boolean\n    readonly resume_position_ms: number\n}\n\nexport interface Playlists {\n    readonly href: string\n    readonly limit: number\n    readonly next: string\n    readonly offset: number\n    readonly previous: string\n    readonly total: number\n    readonly items: PlaylistsItem[]\n}\n\nexport interface PlaylistsItem {\n    readonly collaborative: boolean\n    readonly description: string\n    readonly external_urls: ExternalUrls\n    readonly href: string\n    readonly id: string\n    readonly images: Image[]\n    readonly name: string\n    readonly owner: Owner\n    readonly public: boolean\n    readonly snapshot_id: string\n    readonly tracks: Followers\n    readonly type: string\n    readonly uri: string\n}\n\nexport interface Owner {\n    readonly external_urls: ExternalUrls\n    readonly followers: Followers\n    readonly href: string\n    readonly id: string\n    readonly type: string\n    readonly uri: string\n    readonly display_name: string\n}\n\nexport interface Tracks {\n    readonly href: string\n    readonly limit: number\n    readonly next: string\n    readonly offset: number\n    readonly previous: string\n    readonly total: number\n    readonly items: TracksItem[]\n}\n\nexport interface TracksItem {\n    readonly album: AlbumElement\n    readonly artists: Artist[]\n    readonly available_markets: string[]\n    readonly disc_number: number\n    readonly duration_ms: number\n    readonly explicit: boolean\n    readonly external_ids: ExternalIDS\n    readonly external_urls: ExternalUrls\n    readonly href: string\n    readonly id: string\n    readonly is_playable: boolean\n    readonly linked_from: LinkedFrom\n    readonly restrictions: Restrictions\n    readonly name: string\n    readonly popularity: number\n    readonly preview_url: string\n    readonly track_number: number\n    readonly type: string\n    readonly uri: string\n    readonly is_local: boolean\n}\n\nexport interface ExternalIDS {\n    readonly isrc: string\n}\n\nexport interface LinkedFrom {}\n\n/* -------------------------------------------------------------------------- */\n/*                                  FUNCTIONS                                 */\n/* -------------------------------------------------------------------------- */\n\nfunction getTopTrack(tracks: Track[]): Track {\n    let topTrack: Track = tracks.splice(0, 1)[0]\n\n    for (const track of tracks) {\n        if (track.popularity > topTrack.popularity) topTrack = track\n    }\n\n    return topTrack\n}\n\ninterface FetchArtistDataParams {\n    artistID: string\n    token: string\n}\n\nasync function fetchArtistData({\n    artistID,\n    token,\n}: FetchArtistDataParams): Promise<ArtistData> {\n    const url: string = `https://api.spotify.com/v1/artists/${artistID}`\n\n    const headers: Record<PropertyKey, string> = {\n        Authorization: `Bearer ${token}`,\n    }\n\n    const response: Response = await fetch(url, {method: 'GET', headers})\n    const data: ArtistData | DataError = await response.json()\n\n    if ('error' in data)\n        throw new Error(`${data.error.status}: ${data.error.message}`)\n\n    return data\n}\n\ninterface FetchArtistIDParams {\n    fullName: string\n    token: string\n}\n\nasync function fetchArtistID({\n    fullName,\n    token,\n}: FetchArtistIDParams): Promise<string> {\n    const urlBase: string = 'https://api.spotify.com/v1/search'\n    const urlSearchParams: URLSearchParams = new URLSearchParams({\n        q: fullName,\n        type: 'artist',\n        limit: '1',\n    })\n    const url: string = `${urlBase}?${urlSearchParams}`\n\n    const headers: Record<PropertyKey, string> = {\n        Authorization: `Bearer ${token}`,\n    }\n\n    const response: Response = await fetch(url, {method: 'GET', headers})\n    const data: SearchData | DataError = await response.json()\n\n    if ('error' in data)\n        throw new Error(`${data.error.status}: ${data.error.message}`)\n\n    return data.artists.items[0].id\n}\n\ninterface FetchArtistTopTracksParams {\n    artistID: string\n    token: string\n}\n\nasync function fetchArtistTopTracks({\n    artistID,\n    token,\n}: FetchArtistTopTracksParams): Promise<ArtistTopTracks> {\n    const url: string = `https://api.spotify.com/v1/artists/${artistID}/top-tracks`\n\n    const headers: Record<PropertyKey, string> = {\n        Authorization: `Bearer ${token}`,\n    }\n\n    const response: Response = await fetch(url, {method: 'GET', headers})\n    const data: ArtistTopTracks | DataError = await response.json()\n\n    if ('error' in data)\n        throw new Error(`${data.error.status}: ${data.error.message}`)\n\n    return data\n}\n\nasync function fetchSpotifyToken(): Promise<Token> {\n    if (!process.env.SPOTIFY_API_CLIENT_ID)\n        throw new Error(\n            '`SPOTIFY_API_CLIENT_ID` (environment variable) is not defined'\n        )\n\n    if (!process.env.SPOTIFY_API_CLIENT_SECRET)\n        throw new Error(\n            '`SPOTIFY_API_CLIENT_SECRET` (environment variable) is not defined'\n        )\n\n    const url: string = 'https://accounts.spotify.com/api/token'\n\n    const headers: Record<PropertyKey, string> = {\n        'Content-Type': 'application/x-www-form-urlencoded',\n    }\n\n    const clientID: string = process.env.SPOTIFY_API_CLIENT_ID\n    const clientSecret: string = process.env.SPOTIFY_API_CLIENT_SECRET\n    const body: string = `grant_type=client_credentials&client_id=${clientID}&client_secret=${clientSecret}`\n\n    const response: Response = await fetch(url, {method: 'POST', headers, body})\n    const data: Token | TokenError = await response.json()\n\n    if ('error' in data)\n        throw new Error(`${data.error}: ${data.error_description}`)\n\n    return data\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\n;(async () => {\n    const spotifyToken: Token = await fetchSpotifyToken()\n\n    const bandNames = {\n        first: 'oasis',\n        second: 'linkin park',\n    }\n\n    const firstBandID: string = await fetchArtistID({\n        fullName: bandNames.first,\n        token: spotifyToken.access_token,\n    })\n\n    const firstBandData: ArtistData = await fetchArtistData({\n        artistID: firstBandID,\n        token: spotifyToken.access_token,\n    })\n\n    const firstBandTopTracks: ArtistTopTracks = await fetchArtistTopTracks({\n        artistID: firstBandID,\n        token: spotifyToken.access_token,\n    })\n\n    const firstBandTopTrack: Track = getTopTrack(firstBandTopTracks.tracks)\n\n    const secondBandID: string = await fetchArtistID({\n        fullName: bandNames.second,\n        token: spotifyToken.access_token,\n    })\n\n    const secondBandData: ArtistData = await fetchArtistData({\n        artistID: secondBandID,\n        token: spotifyToken.access_token,\n    })\n\n    const secondBandTopTracks: ArtistTopTracks = await fetchArtistTopTracks({\n        artistID: secondBandID,\n        token: spotifyToken.access_token,\n    })\n\n    const secondBandTopTrack: Track = getTopTrack(secondBandTopTracks.tracks)\n\n    const pointsPerBand: Record<keyof typeof bandNames, number> = {\n        first: 0,\n        second: 0,\n    }\n\n    console.log(\n        `> Which band is more popular (${firstBandData.name}, or ${secondBandData.name})?`\n    )\n\n    console.log('\\n> Comparison of popularity...')\n    console.log(\n        `\\n> Popularity of ${firstBandData.name}: ${firstBandData.popularity} points of popularity.`\n    )\n    console.log(\n        `> Popularity of ${secondBandData.name}: ${secondBandData.popularity} points of popularity.`\n    )\n\n    if (firstBandData.popularity > secondBandData.popularity) {\n        console.log(\n            `> ${firstBandData.name} has more popularity points than ${secondBandData.name}.`\n        )\n        pointsPerBand.first++\n    } else if (firstBandData.popularity < secondBandData.popularity) {\n        console.log(\n            `> ${secondBandData.name} has more popularity points than ${firstBandData.name}.`\n        )\n        pointsPerBand.second++\n    } else {\n        console.log(\n            `> ${firstBandData.name} has the same popularity points than ${secondBandData.name}.`\n        )\n    }\n\n    console.log('\\n> Comparison of followers...')\n    console.log(\n        `\\n> Followers of ${firstBandData.name}: ${firstBandData.followers.total} followers.`\n    )\n    console.log(\n        `> Followers of ${secondBandData.name}: ${secondBandData.followers.total} followers.`\n    )\n\n    if (firstBandData.followers.total > secondBandData.followers.total) {\n        console.log(\n            `> ${firstBandData.name} has more followers than ${secondBandData.name}.`\n        )\n        pointsPerBand.first++\n    } else if (firstBandData.followers.total < secondBandData.followers.total) {\n        console.log(\n            `> ${secondBandData.name} has more followers than ${firstBandData.name}.`\n        )\n        pointsPerBand.second++\n    } else {\n        console.log(\n            `> ${firstBandData.name} has the same number of followers than ${secondBandData.name}.`\n        )\n    }\n\n    console.log('\\n> Comparison of top track of each band...')\n    console.log(\n        `\\n> Top track of ${firstBandData.name} (name, and popularity): ${firstBandTopTrack.name} (${firstBandTopTrack.popularity} points of popularity).`\n    )\n    console.log(\n        `> Top track of ${secondBandData.name} (name, and popularity): ${secondBandTopTrack.name} (${secondBandTopTrack.popularity} points of popularity).`\n    )\n\n    if (firstBandTopTrack.popularity > secondBandTopTrack.popularity) {\n        console.log(\n            `> ${firstBandTopTrack.name} of ${firstBandData.name} band is more popular than ${secondBandTopTrack.name} of ${secondBandData.name} band.`\n        )\n        pointsPerBand.first++\n    } else if (firstBandTopTrack.popularity < secondBandTopTrack.popularity) {\n        console.log(\n            `> ${secondBandTopTrack.name} of ${secondBandData.name} band is more popular than ${firstBandTopTrack.name} of ${firstBandData.name} band.`\n        )\n        pointsPerBand.second++\n    } else {\n        console.log(\n            `> ${secondBandTopTrack.name} of ${secondBandData.name} band has the same popularity points than ${firstBandTopTrack.name} of ${firstBandData.name} band.`\n        )\n    }\n\n    console.log('\\n> In conclusion...')\n\n    if (pointsPerBand.first > pointsPerBand.second) {\n        console.log(\n            `\\n> ${firstBandData.name} band is more popular than ${secondBandData.name} band`\n        )\n    } else if (pointsPerBand.first < pointsPerBand.second) {\n        console.log(\n            `\\n> ${secondBandData.name} band is more popular than ${firstBandData.name} band`\n        )\n    } else {\n        console.log(\n            `\\n> ${firstBandData.name} band is as popular as ${secondBandData.name} band`\n        )\n    }\n})()\n"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/typescript/miguelex.ts",
    "content": "import fetch from 'node-fetch';\nimport readlineSync from 'readline-sync';\n\nconst clientId = 'YOUR_CLIENT_ID';\nconst clientSecret = 'YOUR_CLIENT_SECRET';\n\nasync function getAccessToken(): Promise<string> {\n    const response = await fetch('https://accounts.spotify.com/api/token', {\n        method: 'POST',\n        headers: {\n            'Authorization': `Basic ${Buffer.from(`${clientId}:${clientSecret}`).toString('base64')}`,\n            'Content-Type': 'application/x-www-form-urlencoded',\n        },\n        body: 'grant_type=client_credentials',\n    });\n    \n    const data = await response.json();\n    return data.access_token;\n}\n\nasync function getArtistData(token: string, artistName: string) {\n    const response = await fetch(`https://api.spotify.com/v1/search?q=${encodeURIComponent(artistName)}&type=artist`, {\n        headers: {\n            'Authorization': `Bearer ${token}`\n        }\n    });\n    const data = await response.json();\n    return data.artists.items[0];  \n}\n\nasync function getArtistStats(artistId: string, token: string) {\n    const response = await fetch(`https://api.spotify.com/v1/artists/${artistId}`, {\n        headers: {\n            'Authorization': `Bearer ${token}`\n        }\n    });\n    const data = await response.json();\n    return {\n        name: data.name,\n        followers: data.followers.total,\n        popularity: data.popularity,\n        genres: data.genres\n    };\n}\n\nasync function getArtistTopTracks(artistId: string, token: string) {\n    const response = await fetch(`https://api.spotify.com/v1/artists/${artistId}/top-tracks?market=US`, {\n        headers: {\n            'Authorization': `Bearer ${token}`\n        }\n    });\n    const data = await response.json();\n    const mostPopularTrack = data.tracks[0];\n    return {\n        name: mostPopularTrack.name,\n        playCount: mostPopularTrack.popularity,\n        album: mostPopularTrack.album.name\n    };\n}\n\nasync function compareBands(band1: string, band2: string) {\n    const token = await getAccessToken();\n    \n    const band1Data = await getArtistData(token, band1);\n    const band2Data = await getArtistData(token, band2);\n    \n    const band1Stats = await getArtistStats(band1Data.id, token);\n    const band2Stats = await getArtistStats(band2Data.id, token);\n    \n    const band1TopTrack = await getArtistTopTracks(band1Data.id, token);\n    const band2TopTrack = await getArtistTopTracks(band2Data.id, token);\n    \n    console.log(`${band1} Stats:`, band1Stats);\n    console.log(`Canción más popular de ${band1}:`, band1TopTrack);\n    \n    console.log(`${band2} Stats:`, band2Stats);\n    console.log(`Canción más popular de ${band2}:`, band2TopTrack);\n    \n    const moreFollowers = (band1Stats.followers > band2Stats.followers) ? band1 : band2;\n    const morePopularTrack = (band1TopTrack.playCount > band2TopTrack.playCount) ? band1 : band2;\n    \n    console.log(`\\nLa banda con más seguidores es: ${moreFollowers}`);\n    console.log(`La banda con la canción más popular es: ${morePopularTrack}`);\n}\n\nconst band1 = readlineSync.question('Introduce el nombre del primer grupo: ');\nconst band2 = readlineSync.question('Introduce el nombre del segundo grupo: ');\n\ncompareBands(band1, band2);\n"
  },
  {
    "path": "Roadmap/37 - OASIS VS LINKIN PARK/vb.net/kenysdev.vb",
    "content": "' _____________________________________\n' https://github.com/kenysdev\n' 2024 - vb.net\n' _____________________________________\n' 37 OASIS VS LINKIN PARK\n' ------------------------------------\n'* ¡Dos de las bandas más grandes de la historia están de vuelta!\n'* Oasis y Linkin Park han anunciado nueva gira, pero, ¿quién es más popular?\n'* Desarrolla un programa que se conecte al API de Spotify y los compare.\n'* Requisitos:\n'* 1. Crea una cuenta de desarrollo en https//developer.spotify.com.\n'* 2. Conéctate al API utilizando tu lenguaje de programación.\n'* 3. Recupera datos de los endpoint que tú quieras.\n'* Acciones:\n'* 1. Accede a las estadísticas de las dos bandas.\n'*    Por ejemplo: número total de seguidores, escuchas mensuales,\n'*    canción con más reproducciones...\n'* 2. Compara los resultados de, por lo menos, 3 endpoint.\n'* 3. Muestra todos los resultados por consola para notificar al usuario.\n'* 4. Desarrolla un criterio para seleccionar qué banda es más popular.\n\nImports SpotifyAPI.Web\nImports DotNetEnv\n\nPublic Class Spotify\n    Private ReadOnly _spotify As SpotifyClient\n\n    Public Sub New()\n        Env.Load()\n        Dim clientId = Environment.GetEnvironmentVariable(\"SPOTIFY_CLIENT_ID\")\n        Dim clientSecret = Environment.GetEnvironmentVariable(\"SPOTIFY_CLIENT_SECRET\")\n\n        If String.IsNullOrEmpty(clientId) OrElse String.IsNullOrEmpty(clientSecret) Then\n            Throw New ArgumentException(\"Se debe proporcionar 'CLIENT_ID' y 'CLIENT_SECRET'.\")\n        End If\n\n        Dim config = SpotifyClientConfig.CreateDefault().\n            WithAuthenticator(New ClientCredentialsAuthenticator(clientId, clientSecret))\n\n        _spotify = New SpotifyClient(config)\n    End Sub\n\n    Public Async Function GetMostPopularArtistAsync(name As String) As Task(Of FullArtist)\n        Dim searchRequest As New SearchRequest(SearchRequest.Types.Artist, name) With {\n            .Limit = 3\n        }\n        Dim searchResult = Await _spotify.Search.Item(searchRequest)\n\n        Return searchResult?.Artists?.Items?.\n            OrderByDescending(Function(artist) artist.Popularity).\n            FirstOrDefault()\n    End Function\n\n    Public Async Function ArtistTopTracksAsync(artistId As String) As Task(Of ArtistsTopTracksResponse)\n        Return Await _spotify.Artists.GetTopTracks(artistId, New ArtistsTopTracksRequest(\"US\"))\n    End Function\nEnd Class\n\nPublic Class Versus\n    Private ReadOnly _artist1 As FullArtist\n    Private ReadOnly _artist2 As FullArtist\n    Private ReadOnly _spotify As Spotify\n    Private _artist1Score As Integer = 0\n    Private _artist2Score As Integer = 0\n\n    Public Sub New(artist1 As FullArtist, artist2 As FullArtist, spotifyInstance As Spotify)\n        _artist1 = artist1\n        _artist2 = artist2\n        _spotify = spotifyInstance\n    End Sub\n\n    Private Sub ComparePopularity()\n        Console.WriteLine($\"Popularidad: {_artist1.Popularity} vs {_artist2.Popularity}\")\n        IncrementScore(_artist1.Popularity, _artist2.Popularity)\n    End Sub\n\n    Private Sub CompareFollowers()\n        Console.WriteLine($\"Seguidores: {_artist1.Followers.Total} vs {_artist2.Followers.Total}\")\n        IncrementScore(_artist1.Followers.Total, _artist2.Followers.Total)\n    End Sub\n\n    Private Async Function CompareTopTracksAsync() As Task\n        Dim a1Top = Await _spotify.ArtistTopTracksAsync(_artist1.Id)\n        Dim a2Top = Await _spotify.ArtistTopTracksAsync(_artist2.Id)\n\n        Dim a1Pop = a1Top.Tracks.Take(3).Sum(Function(track) track.Popularity)\n        Dim a2Pop = a2Top.Tracks.Take(3).Sum(Function(track) track.Popularity)\n\n        Console.WriteLine($\"Popularidad Top 3 canciones: {a1Pop} vs {a2Pop}\")\n        IncrementScore(a1Pop, a2Pop)\n    End Function\n\n    Private Sub IncrementScore(value1 As Integer, value2 As Integer)\n        If value1 > value2 Then\n            _artist1Score += 1\n        ElseIf value2 > value1 Then\n            _artist2Score += 1\n        End If\n    End Sub\n\n    Private Sub ShowFinalResult()\n        Console.WriteLine($\"{vbCrLf}RESULTADO FINAL:\")\n        Console.WriteLine($\"{_artist1.Name}: {_artist1Score} puntos\")\n        Console.WriteLine($\"{_artist2.Name}: {_artist2Score} puntos\")\n\n        Dim winner = If(_artist1Score > _artist2Score, _artist1.Name,\n                        If(_artist2Score > _artist1Score, _artist2.Name, \"Empate\"))\n\n        Console.WriteLine($\"{vbCrLf}¡{If(winner = \"Empate\", \"Es un empate\", $\"'{winner}' gana el versus\")}!\")\n    End Sub\n\n    Public Async Function StartAsync() As Task\n        Console.WriteLine($\"{_artist1.Name} vs {_artist2.Name}\")\n        ComparePopularity()\n        CompareFollowers()\n        Await CompareTopTracksAsync()\n        ShowFinalResult()\n    End Function\nEnd Class\n\nModule Program\n    <STAThread>\n    Public Sub Main()\n        Console.WriteLine(\"VERSUS\")\n        Dim spotify = New Spotify()\n\n        Dim artist1 = spotify.GetMostPopularArtistAsync(\"Oasis\").GetAwaiter().GetResult()\n        Dim artist2 = spotify.GetMostPopularArtistAsync(\"Linkin Park\").GetAwaiter().GetResult()\n\n        If artist1 Is Nothing OrElse artist2 Is Nothing Then\n            Console.WriteLine(\"Artistas no encontrados\")\n            Return\n        End If\n\n        Dim versus = New Versus(artist1, artist2, spotify)\n        versus.StartAsync().GetAwaiter().GetResult()\n    End Sub\nEnd Module\n"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/c#/Daichiko.cs",
    "content": "﻿/*\n * EJERCICIO:\n * He presentado mi proyecto más importante del año: mouredev pro.\n * Un campus para la comunidad, que lanzaré en octubre, donde estudiar\n * programación de una manera diferente.\n * Cualquier persona suscrita a la newsletter de https://mouredev.pro\n * accederá a sorteos mensuales de suscripciones, regalos y descuentos.\n *\n * Desarrolla un programa que lea los registros de un fichero .csv y\n * seleccione de manera aleatoria diferentes ganadores.\n * Requisitos:\n * 1. Crea un .csv con 3 columnas: id, email y status con valor \"activo\"\n *    o \"inactivo\" (y datos ficticios).\n *    Ejemplo: 1 | test@test.com | activo\n *             2 | test2@test.com | inactivo\n *    (El .csv no debe subirse como parte de la corrección)\n * 2. Recupera los datos desde el programa y selecciona email aleatorios.\n * Acciones:\n * 1. Accede al fichero .csv y selecciona de manera aleatoria un email\n *    ganador de una suscripción, otro ganador de un descuento y un último\n *    ganador de un libro (sólo si tiene status \"activo\" y no está repetido).\n * 2. Muestra los emails ganadores y su id.\n * 3. Ten en cuenta que la primera fila (con el nombre de las columnas)\n *    no debe tenerse en cuenta.\n */\n\nnamespace retos_programacion._2024.Reto_38\n{\n    public class reto_38\n    {\n        //Enumerado de tipos de estatus\n        internal enum Status {activo, inactivo};\n\n        //clase base para manejos de usuarios\n        internal class user\n        {\n            private int id;\n            private string email;\n            private Status status;\n\n            public user(int id, string email, Status status)\n            {\n                this.id = id;\n                this.email = email;\n                this.status = status;\n            }\n\n            public int Id { get => id;}\n            public string Email { get => email;}\n            public Status Status { get => status;}\n        }\n\n        //logica principal del programa\n        public class mainLogic\n        {\n            //lista de usuarios necesaria\n            private List<user> users = new List<user>();\n\n            //Obtener datos de usuarios de .CSV\n            public bool ImportCSV(string path)\n            {\n                try\n                {\n                    var file = File.ReadAllLines(path);\n\n                    for (int i = 1; i < file.Length; i++)\n                    {\n                        var values = file[i].Split(',');\n\n                        var id = int.Parse(values[0].Trim());\n                        var email = values[1].Trim();\n                        var status = values[2].Trim().ToLower().Equals(\"activo\") ? Status.activo : Status.inactivo;\n\n                        var Usuario = new user(id, email, status);\n                        users.Add(Usuario);\n                    }\n                    return true;\n                }\n                catch\n                {\n                    Console.WriteLine(\"Ha ocurrido un error al leer el csv. Asegúrese de que el fichero existe y tiene un formato correcto.\");\n                    return false;\n                }\n            }\n\n            //Seleccion de ganadores\n            public void SelectWinners ()\n            {\n                if (users.Count <= 0) \n                {\n                    Console.WriteLine(\"No se han cargado usuarios al sistema\");\n                    return;\n                };\n\n                List<user> usersCopyActivos = (new List<user>(users)).Where(u => u.Status == Status.activo).ToList();\n\n                if (usersCopyActivos.Count <= 0)\n                {\n                    Console.WriteLine(\"No hay mas usuarios en el sistema activos para seleccionar un ganador de suscripcion\");\n                    return;\n                };\n\n                // Crear selectores para cada tipo de premio\n                IWinnerSelector subscriptionSelector = new SubscriptionWinnerSelector();\n                IWinnerSelector discountSelector = new DiscountWinnerSelector();\n                IWinnerSelector bookSelector = new BookWinnerSelector();\n\n                // Seleccionar ganadores para cada tipo de premio\n                SelectWinnerMessage(subscriptionSelector, usersCopyActivos, \"No hay más usuarios activos para seleccionar un ganador de suscripción\");\n                SelectWinnerMessage(discountSelector, usersCopyActivos, \"No hay más usuarios activos para seleccionar un ganador de descuento\");\n                SelectWinnerMessage(bookSelector, usersCopyActivos, \"No hay más usuarios activos para seleccionar un ganador de libro\");\n\n\n            }\n\n            //Se crea una funcion para mostrar los diferentes resultados del ganador\n            private void SelectWinnerMessage(IWinnerSelector selector, List<user> users, string message)\n            {\n                if (users.Count <= 0)\n                {\n                    Console.WriteLine(message);\n                    return;\n                }\n\n                selector.SelectWinner(users);\n            }\n\n            //Se crea una interfaz para la seleccion del ganador\n            private interface IWinnerSelector\n            {\n                void SelectWinner(List<user> users);\n            }\n\n            //Se crea la clase para la seleccion del ganador de suscripcion\n            private class SubscriptionWinnerSelector : IWinnerSelector\n            {\n                public void SelectWinner(List<user> users)\n                {\n                    // Selección del ganador de la suscripción\n                    Random rnd = new Random();\n                    int winnerIndex = rnd.Next(users.Count);\n                    user winner = users[winnerIndex];\n                    Console.WriteLine($\"El ganador de la suscripción es: \\n\\t{winner.Id} - {winner.Email}\");\n                    users.RemoveAt(winnerIndex);\n                }\n            }\n\n            //Se crea la clase para la seleccion del ganador de descuento\n            private class DiscountWinnerSelector : IWinnerSelector\n            {\n                public void SelectWinner(List<user> users)\n                {\n                    // Selección del ganador del descuento\n                    Random rnd = new Random();\n                    int winnerIndex = rnd.Next(users.Count);\n                    user winner = users[winnerIndex];\n                    Console.WriteLine($\"El ganador del descuento es: \\n\\t{winner.Id} - {winner.Email}\");\n                    users.RemoveAt(winnerIndex);\n                }\n            }\n\n            //Se crea la clase para la seleccion del ganador del libro\n            private class BookWinnerSelector : IWinnerSelector\n            {\n                public void SelectWinner(List<user> users)\n                {\n                    // Selección del ganador del libro\n                    Random rnd = new Random();\n                    int winnerIndex = rnd.Next(users.Count);\n                    user winner = users[winnerIndex];\n                    Console.WriteLine($\"El ganador del libro es: \\n\\t{winner.Id} - {winner.Email}\");\n                    users.RemoveAt(winnerIndex);\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/c#/deathwing696.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\n/*\n * EJERCICIO:\n * He presentado mi proyecto más importante del año: mouredev pro.\n * Un campus para la comunidad, que lanzaré en octubre, donde estudiar\n * programación de una manera diferente.\n * Cualquier persona suscrita a la newsletter de https://mouredev.pro\n * accederá a sorteos mensuales de suscripciones, regalos y descuentos.\n *\n * Desarrolla un programa que lea los registros de un fichero .csv y\n * seleccione de manera aleatoria diferentes ganadores.\n * Requisitos:\n * 1. Crea un .csv con 3 columnas: id, email y status con valor \"activo\"\n *    o \"inactivo\" (y datos ficticios).\n *    Ejemplo: 1 | test@test.com | activo\n *             2 | test2@test.com | inactivo\n *    (El .csv no debe subirse como parte de la corrección)\n * 2. Recupera los datos desde el programa y selecciona email aleatorios.\n * Acciones:\n * 1. Accede al fichero .csv y selecciona de manera aleatoria un email\n *    ganador de una suscripción, otro ganador de un descuento y un último\n *    ganador de un libro (sólo si tiene status \"activo\" y no está repetido).\n * 2. Muestra los emails ganadores y su id.\n * 3. Ten en cuenta que la primera fila (con el nombre de las columnas)\n *    no debe tenerse en cuenta.\n */\n\nnamespace Reto_38\n{\n    internal class deathwing696\n    {\n        internal enum Estado_t\n        {\n            activo,\n            inactivo\n        };\n\n        public class Usuario\n        {\n            private int id;\n            private string email;\n            private Estado_t estado;\n\n            public int Id { get { return id; } }\n            public string Email { get { return email; } }\n            public Estado_t Estado { get { return estado; } }\n\n            public Usuario(int id, string email, Estado_t status) \n            {\n                this.id = id;\n                this.email = email;\n                this.estado = status;\n            }\n        }\n\n        public class MoureDevPRO\n        {\n            private List<Usuario> usuarios = new List<Usuario>();\n            public void ImportCSV(string path)\n            {\n                try\n                {\n                    var file = File.ReadAllLines(path);\n\n                    for (int i = 1; i < file.Length; i++)\n                    {\n                        var values = file[i].Split(',');\n\n                        var id = int.Parse(values[0].Trim());\n                        var email = values[1].Trim();\n                        var status = values[2].Trim().ToLower().Equals(\"activo\") ? Estado_t.activo : Estado_t.inactivo;\n\n                        var Usuario = new Usuario(id, email, status);\n                        usuarios.Add(Usuario);\n                    }\n                }\n                catch \n                {\n                    Console.WriteLine(\"Ha ocurrido un error al leer el csv. Asegúrese de que el fichero existe y tiene un formato correcto.\");\n                }\n            }\n\n            internal void SelectWinners()\n            {\n                if (usuarios.Count <= 0)\n                {\n                    Console.WriteLine(\"No hay usuarios importados desde el csv, por tanto, no pueden haber ganadores\");\n                    return;\n                }\n\n                List<Usuario> usuarios_copy = new List<Usuario>(usuarios);\n\n                //Seleccionamos el ganador de la suscripción\n                Random rnd = new Random();\n                var suscriptionIndex = rnd.Next(0, usuarios_copy.Count);\n                Usuario selectedUser = usuarios_copy[suscriptionIndex];\n                Console.WriteLine($\"El ganador de la suscripción es: \\n\\t{selectedUser.Id} - {selectedUser.Email}\");\n\n                if (usuarios_copy.Count < 2)\n                {\n                    Console.WriteLine(\"No hay más usuarios importados desde el csv, por tanto, no pueden haber más ganadores\");\n                    return;\n                }\n\n                //Seleccionamos el ganador del descuento\n                usuarios_copy.RemoveAt(suscriptionIndex);\n                var discountIndex = rnd.Next(0, usuarios_copy.Count);                                    \n                selectedUser = usuarios_copy[discountIndex];\n                Console.WriteLine($\"El ganador de la suscripción es: \\n\\t{selectedUser.Id} - {selectedUser.Email}\");\n\n                if (usuarios.Count < 2)\n                {\n                    Console.WriteLine(\"No hay más usuarios importados desde el csv, por tanto, no pueden haber más ganadores\");\n                    return;\n                }\n\n                //Seleccionamos el ganador del descuento\n                usuarios_copy.RemoveAt(discountIndex);\n                selectedUser = null;\n\n                while (usuarios_copy.Count > 0)\n                {\n                    var bookIndex = rnd.Next(0, usuarios_copy.Count);\n                    selectedUser = usuarios_copy[bookIndex];\n\n                    if (selectedUser.Estado == Estado_t.activo)\n                    {\n                        break;\n                    }\n                    else\n                    {\n                        usuarios_copy.RemoveAt(bookIndex);\n                        selectedUser = null;\n                    }\n                }\n\n                if (selectedUser != null)\n                    Console.WriteLine($\"El ganador de la suscripción es: \\n\\t{selectedUser.Id} - {selectedUser.Email}\");\n                else\n                    Console.WriteLine(\"No hay más usuarios importados desde el csv que tengan el estado activo, por tanto, no hay ganador del libro\");\n            }\n        }\n\n        static void Main(string[] args)\n        {\n            var moureDevPRO = new MoureDevPRO();\n            moureDevPRO.ImportCSV($\"{AppDomain.CurrentDomain.BaseDirectory}mouredevPro.csv\");\n            moureDevPRO.SelectWinners();\n\n\n\n            Console.ReadKey();\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/c#/hequebo.cs",
    "content": "class Participant\n{\n    public int Id { get; set; }\n    public string Email { get; set; }\n    public string Status { get; set; }\n\n    public Participant(int id, string email, string status) \n    {\n        Id = id;\n        Email = email;\n        Status = status;\n    }\n\n}\nclass Program\n{\n    static void Main(string[] args)\n    {\n        Console.WriteLine(\"---Ganadores de Sortea MoureDevPro---\");\n\n        using (var reader =  new StreamReader(\"participantes.csv\"))\n        {\n            List<Participant> list = new List<Participant>();\n\n            reader.ReadLine(); // Saltar primera linea con nombre de columnas\n\n            while (!reader.EndOfStream)\n            {\n                var line = reader.ReadLine();\n                var values = line.Split(\",\");\n\n                list.Add(new Participant(int.Parse(values[0]), values[1].Trim(), values[2].Trim()));\n            }\n\n            if (list.Count < 3)\n            {\n                Console.WriteLine(\"Error.- Deben de existir por lo menos tres participantes...\");\n                return;\n            }\n            List<Participant> activeList = list.Where(p => p.Status.ToLower() == \"activo\").ToList();\n            if (activeList.Count() < 3)\n            {\n                Console.WriteLine(\"Error.- Deben de existir por lo menos tres participantes \" +\n                    \"con el campo Status en 'Activo'...\");\n                return;\n            }\n            Console.WriteLine(\"Participantes Activos en el sorteo\");\n            foreach (var participant in activeList)\n                Console.WriteLine($\"{participant.Id}.- {participant.Email}\");\n\n            Random random = new Random();\n            int winnerIndex = random.Next(0, activeList.Count - 1);\n\n            var winner = activeList[winnerIndex];\n            activeList.RemoveAt(winnerIndex);\n\n            Console.WriteLine($\"¡{winner.Email} ha ganado una suscripción!\");\n\n            winnerIndex = random.Next(0, activeList.Count - 1);\n            winner = activeList[winnerIndex];\n            activeList.RemoveAt(winnerIndex);\n\n            Console.WriteLine($\"¡{winner.Email} ha ganado un descuento del 30% en la suscripción anual!\");\n\n            winnerIndex = random.Next(0, activeList.Count - 1);\n            winner = activeList[winnerIndex];\n            activeList.RemoveAt(winnerIndex);\n\n            Console.WriteLine($\"¡{winner.Email} ha ganado el libro de progrmación!\");\n\n            Console.WriteLine(\"Felicidades a los ganadores y suerte en el próximo sorteo a:\");\n            foreach (var participant in activeList)\n                Console.WriteLine($\"{participant.Id}.- {participant.Email}\");\n            Console.WriteLine(\"¡Hasta la próxima!\");\n        }\n\n    }\n}"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/c#/kenysdev.cs",
    "content": "namespace exs38;\n/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - C#\n_____________________________________\nMOUREDEV PRO\n------------------------------------\n* He presentado mi proyecto más importante del año: mouredev pro.\n * Un campus para la comunidad, que lanzaré en octubre, donde estudiar\n * programación de una manera diferente.\n * Cualquier persona suscrita a la newsletter de https://mouredev.pro\n * accederá a sorteos mensuales de suscripciones, regalos y descuentos.\n *\n * Desarrolla un programa que lea los registros de un fichero .csv y\n * seleccione de manera aleatoria diferentes ganadores.\n * Requisitos:\n * 1. Crea un .csv con 3 columnas: id, email y status con valor \"activo\"\n *    o \"inactivo\" (y datos ficticios).\n *    Ejemplo: 1 | test@test.com | activo\n *             2 | test2@test.com | inactivo\n *    (El .csv no debe subirse como parte de la corrección)\n * 2. Recupera los datos desde el programa y selecciona email aleatorios.\n * Acciones:\n * 1. Accede al fichero .csv y selecciona de manera aleatoria un email\n *    ganador de una suscripción, otro ganador de un descuento y un último\n *    ganador de un libro (sólo si tiene status \"activo\" y no está repetido).\n * 2. Muestra los emails ganadores y su id.\n * 3. Ten en cuenta que la primera fila (con el nombre de las columnas)\n *    no debe tenerse en cuenta.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\n\nclass Program\n{\n    static List<Dictionary<string, string>>? ReadCsv(string filePath)\n    {\n        try\n        {\n            var lines = File.ReadAllLines(filePath);\n            var headers = lines[0].Split(',');\n            return lines.Skip(1).Select(line => \n                line.Split(',')\n                    .Select((value, index) => new { Header = headers[index], Value = value })\n                    .ToDictionary(item => item.Header, item => item.Value)\n            ).ToList();\n        }\n        catch (Exception e)\n        {\n            Console.WriteLine($\"Error reading '{filePath}': {e.Message}\");\n            return null;\n        }\n    }\n\n    static List<Dictionary<string, string>> GetActiveEntries(List<Dictionary<string, string>> entries)\n    {\n        return entries.Where(entry => entry[\"status\"]\n                      .Equals(\"active\", StringComparison.CurrentCultureIgnoreCase))\n                      .Select(entry => new Dictionary<string, string>\n                      {\n                          [\"id\"] = entry[\"id\"],\n                          [\"email\"] = entry[\"email\"],\n                          [\"status\"] = entry[\"status\"]\n                      })\n                      .ToList();\n    }\n\n    static List<Dictionary<string, string>> SelectWinners(List<Dictionary<string, string>> activeEntries, int numWinners)\n    {\n        var random = new Random();\n        return activeEntries.OrderBy(x => random.Next()).Take(Math.Min(numWinners, activeEntries.Count)).ToList();\n    }\n\n    static void DistributePrizes(List<Dictionary<string, string>> winners, List<string> prizes)\n    {\n        var random = new Random();\n        prizes = [.. prizes.OrderBy(x => random.Next())];\n        for (int i = 0; i < Math.Min(winners.Count, prizes.Count); i++)\n        {\n            Console.WriteLine($\"{prizes[i],-11} -> Id({winners[i][\"id\"]}): {winners[i][\"email\"]}\");\n        }\n    }\n\n    static void Main()\n    {\n        Console.WriteLine(\"Usuarios ganadores de 'MOUREDEV PRO:'\");\n        string csvFile = \"users.csv\";\n        var prizes = new List<string> { \"Suscripción\", \"Descuento\", \"Libro\" };\n\n        var entries = ReadCsv(csvFile);\n        if (entries != null && entries.Count >= 3)\n        {\n            var activeEntries = GetActiveEntries(entries);\n            var winners = SelectWinners(activeEntries, 3);\n            DistributePrizes(winners, prizes);\n        }\n        else\n        {\n            Console.WriteLine(\"Debe haber más de 3 entradas activas.\");\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/c++/hectorio23.cpp",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\n#include <iostream>\n#include <fstream>\n#include <vector>\n#include <string>\n#include <sstream>\n#include <random>\n#include <algorithm>\n\nstruct Participante {\n    std::string id;\n    std::string email;\n    std::string status;\n};\n\nstd::vector<Participante> leerCSV(const std::string& filename) {\n    std::vector<Participante> participantes;\n    std::ifstream file(filename);\n    std::string line, word;\n\n    // Leer archivo línea por línea\n    if (file.is_open()) {\n        // Omitir la primera línea (cabeceras)\n        std::getline(file, line);\n        while (std::getline(file, line)) {\n            std::stringstream s(line);\n            Participante p;\n            std::getline(s, p.id, ',');\n            std::getline(s, p.email, ',');\n            std::getline(s, p.status, ',');\n\n            if (p.status == \"activo\") {\n                participantes.push_back(p);\n            }\n        }\n        file.close();\n    }\n    return participantes;\n}\n\nvoid seleccionarGanadores(const std::vector<Participante>& participantes) {\n    if (participantes.size() < 3) {\n        std::cout << \"No hay suficientes participantes activos.\\n\";\n        return;\n    }\n\n    std::vector<Participante> ganadores = participantes;\n    std::random_device rd;\n    std::mt19937 g(rd());\n    std::shuffle(ganadores.begin(), ganadores.end(), g);\n\n    std::cout << \"Ganador de suscripción: ID \" << ganadores[0].id << \" | Email: \" << ganadores[0].email << \"\\n\";\n    std::cout << \"Ganador de descuento: ID \" << ganadores[1].id << \" | Email: \" << ganadores[1].email << \"\\n\";\n    std::cout << \"Ganador de libro: ID \" << ganadores[2].id << \" | Email: \" << ganadores[2].email << \"\\n\";\n}\n\nint main() {\n    std::string filename = \"suscriptores.csv\";\n    std::vector<Participante> participantes = leerCSV(filename);\n\n    seleccionarGanadores(participantes);\n\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/ejercicio.md",
    "content": "# #38 MOUREDEV PRO\n> #### Dificultad: Fácil | Publicación: 16/09/24 | Corrección: 23/09/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * He presentado mi proyecto más importante del año: mouredev pro.\n * Un campus para la comunidad, que lanzaré en octubre, donde estudiar\n * programación de una manera diferente.\n * Cualquier persona suscrita a la newsletter de https://mouredev.pro\n * accederá a sorteos mensuales de suscripciones, regalos y descuentos.\n *\n * Desarrolla un programa que lea los registros de un fichero .csv y\n * seleccione de manera aleatoria diferentes ganadores.\n * Requisitos:\n * 1. Crea un .csv con 3 columnas: id, email y status con valor \"activo\"\n *    o \"inactivo\" (y datos ficticios).\n *    Ejemplo: 1 | test@test.com | activo\n *             2 | test2@test.com | inactivo\n *    (El .csv no debe subirse como parte de la corrección)\n * 2. Recupera los datos desde el programa y selecciona email aleatorios.\n * Acciones:\n * 1. Accede al fichero .csv y selecciona de manera aleatoria un email\n *    ganador de una suscripción, otro ganador de un descuento y un último\n *    ganador de un libro (sólo si tiene status \"activo\" y no está repetido).\n * 2. Muestra los emails ganadores y su id.\n * 3. Ten en cuenta que la primera fila (con el nombre de las columnas)\n *    no debe tenerse en cuenta.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/go/hozlucas28.go",
    "content": "package main\n\nimport (\n\t\"encoding/csv\"\n\t\"fmt\"\n\t\"math/rand\"\n\t\"os\"\n\t\"slices\"\n\t\"strings\"\n)\n\n/* -------------------------------------------------------------------------- */\n/*                                 STRUCTURES                                 */\n/* -------------------------------------------------------------------------- */\n\ntype User struct {\n\tEmail  string\n\tID     string\n\tStatus string\n\t_      struct{}\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                  FUNCTIONS                                 */\n/* -------------------------------------------------------------------------- */\n\nfunc createCSV(content *[][]string, path string) error {\n\tcsvFile, err := os.Create(path)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer csvFile.Close()\n\n\twriter := csv.NewWriter(csvFile)\n\tdefer writer.Flush()\n\n\terr = writer.WriteAll(*content)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc getCSVData(path string) (*[][]string, error) {\n\tvar csvData [][]string\n\n\tcsvFileContent, err := os.ReadFile(path)\n\tif err != nil {\n\t\treturn &csvData, err\n\t}\n\n\treader := csv.NewReader(strings.NewReader(string(csvFileContent)))\n\n\tcsvData, err = reader.ReadAll()\n\tif err != nil {\n\t\treturn &csvData, err\n\t}\n\n\treturn &csvData, nil\n}\n\nfunc getUniqueChoices(choices *[]User, nUniqueChoices int) *[]*User {\n\tvar uniqueChoices []*User\n\n\tfor len(uniqueChoices) < nUniqueChoices {\n\t\tvar rndIndex int = rand.Intn(len(*choices))\n\t\tvar rndChoice *User = &(*choices)[rndIndex]\n\n\t\tif !slices.Contains(uniqueChoices, rndChoice) {\n\t\t\tuniqueChoices = append(uniqueChoices, rndChoice)\n\t\t}\n\t}\n\n\treturn &uniqueChoices\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\nfunc main() {\n\tvar csvContent [][]string = [][]string{\n\t\t{\"email\", \"id\", \"status\"},\n\t\t{\"test01@gmail.com\", \"1\", \"active\"},\n\t\t{\"test02@gmail.com\", \"2\", \"inactive\"},\n\t\t{\"test03@gmail.com\", \"3\", \"inactive\"},\n\t\t{\"test04@gmail.com\", \"4\", \"active\"},\n\t\t{\"test05@gmail.com\", \"5\", \"inactive\"},\n\t\t{\"test06@gmail.com\", \"6\", \"active\"},\n\t\t{\"test07@gmail.com\", \"7\", \"active\"},\n\t\t{\"test08@gmail.com\", \"8\", \"active\"},\n\t}\n\n\tvar err error = createCSV(&csvContent, \"./users.csv\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tcsvUsers, err := getCSVData(\"./users.csv\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tvar users []User\n\tfor _, csvUser := range (*csvUsers)[1:] {\n\t\tvar user User = User{\n\t\t\tEmail:  csvUser[0],\n\t\t\tID:     csvUser[1],\n\t\t\tStatus: csvUser[2],\n\t\t}\n\n\t\tusers = append(users, user)\n\t}\n\n\tusers = slices.DeleteFunc(users, func(user User) bool {\n\t\treturn user.Status == \"inactive\"\n\t})\n\n\tvar winners *[]*User = getUniqueChoices(&users, 3)\n\n\tfmt.Println(winners)\n\n\tfmt.Println(\"> The first winner is...\")\n\tfmt.Printf(\"> Congratulations %s with id %s, you won a subscription!\\n\", (*winners)[0].Email, (*winners)[0].ID)\n\n\tfmt.Println(\"\\n> The second winner is...\")\n\tfmt.Printf(\"> Congratulations %s with id %s, you won a discount!\\n\", (*winners)[1].Email, (*winners)[1].ID)\n\n\tfmt.Println(\"\\n> The third winner is...\")\n\tfmt.Printf(\"> Congratulations %s with id %s, you won a book!\", (*winners)[2].Email, (*winners)[2].ID)\n}\n"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/java/AmadorQuispe.java",
    "content": "package com.amsoft.roadmap.example38;\n\nimport java.io.IOException;\nimport java.nio.file.FileSystems;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.util.List;\nimport java.util.Random;\n\npublic class Example38 {\n\n    public static void main(String[] args) {\n\n        List<Subscriptor> subs = getSubscribers();\n        List<Subscriptor> winners = getWinners(subs, 3);\n        System.out.println(\"Ganador suscripción : \" + winners.get(0).id + \" \" + winners.get(0).email);\n        System.out.println(\"Ganador Descuento : \" + winners.get(1).id + \" \" + winners.get(1).email);\n        System.out.println(\"Ganador Libro : \" + winners.get(2).id + \" \" + winners.get(2).email);\n\n    }\n\n    static List<Subscriptor> getSubscribers() {\n        var filePath = FileSystems.getDefault().getPath(\"\");\n        var fileDir = filePath.toAbsolutePath().toString();\n        Path path = Path.of(fileDir.concat(\"/subs.csv\"));\n        List<String> lines;\n        try {\n            lines = Files.readAllLines(path);\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        }\n        return lines.subList(1, lines.size() - 1).stream()\n                .map(l -> l.split(\",\"))\n                .map(l -> new Subscriptor(Integer.parseInt(l[0]), l[1], l[2]))\n                .filter(s -> s.status.equals(\"activo\"))\n                .toList();\n    }\n\n    static List<Subscriptor> getWinners(List<Subscriptor> subs, int numWinners) {\n        if (subs.size() < numWinners) {\n            throw new RuntimeException(\"No hay suficientes subs para obtener ganadores\");\n        }\n        Random random = new Random();\n        return random.ints(0, subs.size())\n                .distinct()\n                .limit(numWinners)\n                .mapToObj(subs::get)\n                .toList();\n    }\n\n    private record Subscriptor(Integer id, String email, String status) {\n\n        @Override\n        public String toString() {\n            return \"Subscriptor{\"\n                    + \"id=\" + id\n                    + \", email='\" + email + '\\''\n                    + \", status='\" + status + '\\''\n                    + '}';\n        }\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/java/Josegs95.java",
    "content": "import java.io.File;\nimport java.io.IOException;\nimport java.nio.charset.StandardCharsets;\nimport java.nio.file.Files;\nimport java.nio.file.StandardOpenOption;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\n\npublic class Josegs95 {\n    public static void main(String[] args) {\n        new Josegs95().mouredevPro();\n    }\n\n    final private File file = new File(\"Josegs95.csv\");\n\n    public void mouredevPro(){\n        initCSVFile();\n\n        selectWinners(getSubListFromCSVFile());\n\n        deleteFile();\n    }\n\n    private void selectWinners(List<String> subscriberList){\n        if (subscriberList.size() < 3){\n            System.out.println(\"No hay suficientes participantes para el sorteo\");\n            return;\n        }\n\n        Collections.shuffle(subscriberList);\n        List<String> winners = subscriberList.subList(0, 3);\n\n        String[] twitchSubWinner = winners.get(0).split(\",\");\n        String[] discountWinner = winners.get(1).split(\",\");\n        String[] bookWinner = winners.get(2).split(\",\");\n        System.out.println(\"El usuario con id:\" + twitchSubWinner[0] + \" e email: \"\n                + twitchSubWinner[1] + \" ha ganado una subscripción a Twitch!\");\n        System.out.println(\"El usuario con id:\" + discountWinner[0] + \" e email: \"\n                + discountWinner[1] + \" ha ganado un descuento en la web!\");\n        System.out.println(\"El usuario con id:\" + bookWinner[0] + \" e email: \"\n                + bookWinner[1] + \" ha ganado un libro de programación!\");\n    }\n\n    private void initCSVFile(){\n        try {\n            if (!file.createNewFile())\n                return;\n\n            List<String> subscriberList = new ArrayList<>();\n            subscriberList.add(\"1,ejemplo@gmail.com,activo\");\n            subscriberList.add(\"2,ejemplo2@gmail.com,inactivo\");\n            subscriberList.add(\"3,ejemplo3@gmail.com,activo\");\n            subscriberList.add(\"4,ejemplo4@gmail.com,activo\");\n            subscriberList.add(\"5,ejemplo5@gmail.com,inactivo\");\n            subscriberList.add(\"6,ejemplo6@gmail.com,activo\");\n            subscriberList.add(\"7,ejemplo7@gmail.com,activo\");\n\n\n            Files.writeString(file.toPath(), \"id,email,status\" + System.lineSeparator(),\n                    StandardCharsets.UTF_8);\n            populateFile(subscriberList);\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        }\n    }\n\n    private void populateFile(List<String> dataList){\n        try{\n            for (String dataLine : dataList){\n                Files.writeString(file.toPath(), dataLine + System.lineSeparator(),\n                        StandardCharsets.UTF_8, StandardOpenOption.APPEND);\n            }\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        }\n\n    }\n\n    private List<String> getSubListFromCSVFile(){\n        try{\n            List<String> readList = Files.readAllLines(file.toPath());\n            List<String> subList = new ArrayList<>();\n            for (int i = 1; i < readList.size(); i++){\n                if (!readList.get(i).contains(\"inactivo\"))\n                    subList.add(readList.get(i));\n            }\n\n            return subList;\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        }\n    }\n\n    private void deleteFile(){\n        if (file.delete())\n            System.out.println(\"Archivo \" + file.getName() + \" borrado correctamente\");\n        else\n            System.out.println(\"Error al intentar borrar el archivo \" + file.getName());\n    }\n}\n"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/java/MohamedElderkaoui.java",
    "content": "import java.io.*;\nimport java.nio.file.*;\nimport java.util.*;\nimport java.util.stream.Collectors;\n\npublic class MohamedElderkaoui {\n\n    public static void main(String[] args) {\n        String filePath = \"participants.csv\"; // Path to your CSV file\n        \n        List<Participant> activeParticipants = new ArrayList<>();\n\n        // Step 1: Read the CSV file and filter \"activo\" participants\n        try (BufferedReader br = Files.newBufferedReader(Paths.get(filePath))) {\n            String line;\n            // Skip the first line (header)\n            br.readLine();\n            \n            while ((line = br.readLine()) != null) {\n                String[] data = line.split(\",\"); // Assuming CSV is comma-separated\n                int id = Integer.parseInt(data[0].trim());\n                String email = data[1].trim();\n                String status = data[2].trim();\n                \n                // Only consider \"activo\" participants\n                if (status.equalsIgnoreCase(\"activo\")) {\n                    activeParticipants.add(new Participant(id, email));\n                }\n            }\n        } catch (IOException e) {\n            System.out.println(\"Error reading the file: \" + e.getMessage());\n        }\n\n        // Step 2: Randomly select winners if there are enough participants\n        if (activeParticipants.size() >= 3) {\n            Collections.shuffle(activeParticipants); // Randomize the list\n\n            // Select three unique winners\n            Participant subscriptionWinner = activeParticipants.get(0);\n            Participant discountWinner = activeParticipants.get(1);\n            Participant bookWinner = activeParticipants.get(2);\n\n            // Step 3: Display the winners\n            System.out.println(\"Winners:\");\n            System.out.println(\"Subscription Winner: \" + subscriptionWinner);\n            System.out.println(\"Discount Winner: \" + discountWinner);\n            System.out.println(\"Book Winner: \" + bookWinner);\n        } else {\n            System.out.println(\"Not enough active participants to select winners.\");\n        }\n    }\n\n    // Helper class to represent a participant\n    static class Participant {\n        int id;\n        String email;\n\n        Participant(int id, String email) {\n            this.id = id;\n            this.email = email;\n        }\n\n        @Override\n        public String toString() {\n            return \"ID: \" + id + \", Email: \" + email;\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/java/asjordi.java",
    "content": "import com.fasterxml.jackson.annotation.JsonPropertyOrder;\nimport com.fasterxml.jackson.databind.MappingIterator;\nimport com.fasterxml.jackson.databind.SequenceWriter;\nimport com.fasterxml.jackson.dataformat.csv.CsvMapper;\nimport com.fasterxml.jackson.dataformat.csv.CsvSchema;\nimport net.datafaker.Faker;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.security.SecureRandom;\nimport java.util.*;\n\npublic class Main {\n\n    private static File csvFile = new File(\"persons.csv\");\n\n    public static void main(String[] args) {\n//        createCsvFile();\n        Random r = new SecureRandom();\n        var persons = readCsvFile();\n        var uniquePersons = new ArrayList<>(persons.stream().distinct().filter(p -> p.status().equals(\"active\")).toList());\n        Collections.shuffle(uniquePersons);\n\n        var winnerSubscription = uniquePersons.get(r.nextInt(uniquePersons.size()));\n        var winnerDiscount = uniquePersons.get(r.nextInt(uniquePersons.size()));\n        var winnerBook = uniquePersons.get(r.nextInt(uniquePersons.size()));\n\n        System.out.println(\"Winner subscription: \" + winnerSubscription.id + \" \" + winnerSubscription.email());\n        System.out.println(\"Winner discount: \" + winnerDiscount.id + \" \" + winnerDiscount.email());\n        System.out.println(\"Winner book: \" + winnerBook.id + \" \" + winnerBook.email());\n\n    }\n\n    @JsonPropertyOrder({\"id\", \"email\", \"status\"})\n    record Person(int id, String email, String status) {\n        @Override\n        public boolean equals(Object o) {\n            if (this == o) return true;\n            if (!(o instanceof Person person)) return false;\n            return id == person.id && Objects.equals(email, person.email) && Objects.equals(status, person.status);\n        }\n\n        @Override\n        public int hashCode() {\n            return Objects.hash(id, email, status);\n        }\n    }\n\n    public static List<Person> readCsvFile() {\n        CsvMapper mapper = new CsvMapper();\n        CsvSchema schema = CsvSchema.emptySchema().withHeader();\n\n        try (MappingIterator<Person> iterator = mapper\n                .readerFor(Person.class)\n                .with(schema)\n                .readValues(csvFile)) {\n\n            return iterator.readAll();\n        }\n        catch (IOException e) {\n            throw new RuntimeException(e);\n        }\n    }\n\n    public static void createCsvFile() {\n        List<Person> persons = generatePersons();\n\n        CsvMapper mapper = new CsvMapper();\n        CsvSchema schema = mapper\n                .schemaFor(Person.class)\n                .withHeader();\n\n        try {\n            mapper.writer(schema).writeValue(csvFile, persons);\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        }\n    }\n\n    public static List<Person> generatePersons() {\n        List<Person> list = new LinkedList<>();\n        Faker f = new Faker();\n\n        for (int i = 1; i <= 1000; i++) {\n            list.add(new Person(i, f.internet().emailAddress(), f.options().option(\"active\", \"inactive\")));\n        }\n\n        return list;\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/java/martinbohorquez.java",
    "content": "import java.io.IOException;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.LinkedList;\nimport java.util.List;\n\npublic class martinbohorquez {\n    public static void main(String[] args) throws Exception {\n        List<Suscriptor> subscribers = getSubscribers();\n        List<Suscriptor> winners = selectWinners(subscribers);\n        displayWinners(winners);\n    }\n\n    private static List<Suscriptor> getSubscribers() {\n        List<String> lines;\n        try {\n            lines = Files.readAllLines(Paths.get(\"fichero.csv\"));\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        }\n\n        // Devolver una lista modificable (para realizar luego el shuffle)\n        return new ArrayList<>(lines.stream()\n                .map(l -> l.split(\",\\\\s*\"))\n                .filter(l -> l[2].trim().equals(\"activo\"))\n                .map(l -> new Suscriptor(Integer.parseInt(l[0].trim()), l[1].trim()))\n                .toList());\n    }\n\n    private static List<Suscriptor> selectWinners(List<Suscriptor> subscribers) throws Exception {\n        if (subscribers.size() < 3) throw new Exception(\"El número de suscriptores activos debe ser mínimo 3!\");\n        Collections.shuffle(subscribers); // Ordenar la lista aleatoriamente\n        return subscribers.subList(0, 3); // Escoger los 3 primeros\n    }\n\n    private static void displayWinners(List<Suscriptor> suscriptors) {\n        List<String> prizes = new LinkedList<>(List.of(\"Suscripción\", \"Descuento\", \"Libro\"));\n        for (int i = 0; i < 3; i++) {\n            System.out.printf(\"%s: %s%n\", prizes.get(i), suscriptors.get(i));\n        }\n    }\n\n    private static class Suscriptor {\n        Integer id;\n        String email;\n\n        public Suscriptor(Integer id, String email) {\n            this.id = id;\n            this.email = email;\n        }\n\n        @Override\n        public String toString() {\n            return email + \" (ID=\" + id + \")\";\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/java/miguelex.java",
    "content": "import java.io.*;\nimport java.nio.file.*;\nimport java.util.*;\nimport java.util.stream.*;\n\npublic class miguelex {\n    public static List<Suscriptor> obtenerSuscriptoresActivos(String archivoCsv) throws IOException {\n        List<Suscriptor> suscriptores = new ArrayList<>();\n\n        List<String> lines = Files.readAllLines(Paths.get(archivoCsv));\n        lines.remove(0); \n\n        for (String line : lines) {\n            String[] data = line.split(\",\");\n            if (data[2].trim().equalsIgnoreCase(\"activo\")) {\n                suscriptores.add(new Suscriptor(data[0].trim(), data[1].trim()));\n            }\n        }\n\n        return suscriptores;\n    }\n\n    public static List<Suscriptor> seleccionarGanadores(List<Suscriptor> suscriptores, int numeroGanadores) {\n        if (suscriptores.size() < numeroGanadores) {\n            return null;\n        }\n\n        Collections.shuffle(suscriptores);\n        return suscriptores.subList(0, numeroGanadores);\n    }\n\n    public static void main(String[] args) throws IOException {\n        String archivoCsv = \"suscriptores.csv\";\n        List<Suscriptor> suscriptoresActivos = obtenerSuscriptoresActivos(archivoCsv);\n\n        if (suscriptoresActivos.size() > 0) {\n            List<Suscriptor> ganadores = seleccionarGanadores(suscriptoresActivos, 3);\n            if (ganadores != null) {\n                System.out.println(\"Ganador de la suscripción: \" + ganadores.get(0));\n                System.out.println(\"Ganador del descuento: \" + ganadores.get(1));\n                System.out.println(\"Ganador del libro: \" + ganadores.get(2));\n            } else {\n                System.out.println(\"No hay suficientes suscriptores activos para seleccionar 3 ganadores.\");\n            }\n        } else {\n            System.out.println(\"No hay suscriptores activos.\");\n        }\n    }\n}\n\nclass Suscriptor {\n    String id;\n    String email;\n\n    public Suscriptor(String id, String email) {\n        this.id = id;\n        this.email = email;\n    }\n\n    @Override\n    public String toString() {\n        return \"ID: \" + id + \" | Email: \" + email;\n    }\n}\n"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #38 - JavaScript -> Jesus Antonio Escamilla */\n\n/**\n * MOUREDEV PRO.\n * Utilizando la Terminal para pedir datos y agregarlos.\n */\n\nconst fs = require('fs');\nconst readline = require('readline');\n\n// Función para leer los datos del CSV\nfunction readCSV(filePath) {\n    return new Promise((resolve, reject) => {\n        const suscriptores = [];\n        const rl = readline.createInterface({\n            input: fs.createReadStream(filePath),\n            crlfDelay: Infinity\n        });\n\n        rl.on('line', (line) => {\n            const [id, email, status] = line.split(',');\n            if (status === 'activo') {\n                suscriptores.push({id, email});\n            }\n        });\n\n        rl.on('close', () => {\n            resolve(suscriptores);\n        });\n\n        rl.on('error', (err) => {\n            reject(err);\n        });\n    });\n}\n\n// Función para seleccionar en ganador\nfunction selectWinners(suscriptor) {\n    const winners = [];\n    while (winners.length < 3) {\n        const randomIndex = Math.floor(Math.random() * suscriptor.length);\n        const winner = suscriptor[randomIndex];\n        if (!winners.some(w => w.email === winner.email)) {\n            winners.push(winner);\n        }\n    }\n\n    return {\n        suscripcion: winners[0],\n        descuento: winners[1],\n        libro: winners[2]\n    }\n}\n\nasync function winnersMorueDevPRO() {\n    try {\n        const fileCSV = './suscriptores.csv'\n        const emails = await readCSV(fileCSV)\n\n        if (emails.length < 3) {\n            console.log(`Error: No hay suficientes participantes activos. Se necesitan al menos 3, pero solo hay ${emails.length}.`);\n            return;\n        }\n\n        const winners = selectWinners(emails)\n\n        console.log(`Ganador suscripción: ${winners.suscripcion.email}`);\n        console.log(`Ganador descuento: ${winners.descuento.email}`);\n        console.log(`Ganador libro: ${winners.libro.email}`);\n    } catch (error) {\n        console.error('Error al iniciar el programa: ', error)\n    }\n}\n\n// Usando el programa\nwinnersMorueDevPRO()"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/javascript/Rafacv23.js",
    "content": "const fs = require(\"fs\") //importamos libreria nativa de node para leer archivos del sistema\nconst readline = require(\"readline\")\n\n// utilizamos el método readFile para obtener la información del .csv\n\nconst stream = fs.createReadStream(\"./usuarios.csv\")\n\nconst reader = readline.createInterface({ input: stream })\n\nlet data = []\nlet isFirstLine = true\n\n// función para coger un item random del array de usuarios\nfunction getRandomItem(exclude = []) {\n  let item\n  do {\n    item = data[Math.floor(Math.random() * data.length)]\n  } while (exclude.includes(item)) //buscamos otro ganador si el usuario previo ya ha sido premiado\n  return item\n}\n\nreader.on(\"line\", (row) => {\n  if (isFirstLine) {\n    isFirstLine = false\n    return // salimos del evento linea ya que no queremos procesar la primera línea (cabecera) del CSV.\n  }\n\n  const columns = row.split(\",\")\n  const status = columns[2].trim() //cogemos el valor de columna status\n\n  // solo añadimos al \"sorteo\" a los usuarios con el status === activo\n  if (status === \"activo\") {\n    data.push(columns)\n  }\n})\n\nreader.on(\"close\", () => {\n  // manejo de errores por si no hubiese suficientes usuarios\n\n  if (data.length === 0) {\n    console.log(\"No hay usuarios activos disponibles para seleccionar.\")\n    return\n  }\n\n  const suscriptionWinner = getRandomItem() // Elegimos el primer ganador\n  console.log(`${suscriptionWinner} es el ganador de una suscripción`)\n\n  const discountWinner = getRandomItem([suscriptionWinner]) // Elegimos otro ganador distinto\n  console.log(`${discountWinner} es el ganador de un descuento`)\n\n  const bookWinner = getRandomItem([suscriptionWinner, discountWinner]) // Elegimos un tercer ganador distinto\n  console.log(`${bookWinner} es el ganador de un libro`)\n})\n"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/javascript/RaulDoezon.js",
    "content": "/*\nHe presentado mi proyecto más importante del año: mouredev pro.\nEJERCICIO:\n  Un campus para la comunidad, que lanzaré en octubre, donde estudiar\n  programación de una manera diferente.\n  Cualquier persona suscrita a la newsletter de https://mouredev.pro\n  accederá a sorteos mensuales de suscripciones, regalos y descuentos.\n \n  Desarrolla un programa que lea los registros de un fichero .csv y\n  seleccione de manera aleatoria diferentes ganadores.\n  Requisitos:\n  1. Crea un .csv con 3 columnas: id, email y status con valor \"activo\"\n     o \"inactivo\" (y datos ficticios).\n     Ejemplo: 1 | test@test.com | activo\n              2 | test2@test.com | inactivo\n     (El .csv no debe subirse como parte de la corrección)\n  2. Recupera los datos desde el programa y selecciona email aleatorios.\n  Acciones:\n  1. Accede al fichero .csv y selecciona de manera aleatoria un email\n     ganador de una suscripción, otro ganador de un descuento y un último\n     ganador de un libro (sólo si tiene status \"activo\" y no está repetido).\n  2. Muestra los emails ganadores y su id.\n  3. Ten en cuenta que la primera fila (con el nombre de las columnas)\n     no debe tenerse en cuenta.\n*/\n\nconst fs = require('fs');\nconst readline = require('readline');\nconst stream = fs.createReadStream('/ruta-del/archivo.csv');\nconst reader = readline.createInterface({ input: stream });\nconst awards = ['Suscripción', 'Descuento', 'Libro'];\nlet participants = [];\nlet aleatoryNumbers = [];\nlet selectedEmails = [];\nlet assignedAwards = -1;\n\nreader.on('line', (line) => {\n  const row = line.split(',');\n\n  participants.push(row);\n});\n\nreader.on('close', () => {\n  console.table(participants);\n\n  const numberOfParticipants = participants.length - 1;\n\n  while(aleatoryNumbers.length < numberOfParticipants) {\n    let randomNumber = Math.round((Math.random() * (numberOfParticipants - 1) + 1));\n\n    if (aleatoryNumbers.indexOf(randomNumber)  === -1) {\n      aleatoryNumbers.push(randomNumber);\n    }\n  }\n\n  for (let index = 0; assignedAwards < 2; index++) {\n    let selectedNumber = aleatoryNumbers[index];\n    let currentEmail = selectedEmails.find((email) => {\n      return email === participants[selectedNumber][1];\n    });\n\n    if (currentEmail === undefined && participants[selectedNumber][2] === 'activo') {\n      selectedEmails.push(participants[selectedNumber][1]);\n      assignedAwards++;\n\n      console.log(`🎁 El participante con correo ${participants[selectedNumber][1]} y ID ${participants[selectedNumber][0]} recibe el premio de ${awards[assignedAwards]}.`);\n    } else {\n      console.log(`⚠️ El participante con correo ${participants[selectedNumber][1]} salió premiado, pero no se le puede entregar premio porque está inactivo y/o repetido.`);\n    }\n  }\n\n  console.log(`\\nOrden de números aleatorios: ${aleatoryNumbers}`);\n  console.log(`Correos seleccionados: ${selectedEmails}`);\n});\n"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/javascript/RicJDev.js",
    "content": "/*\n  EJERCICIO:\n\n  @RicJDev\n*/\n\n// Creamos una función para convertir los datos del .csv en un array de objetos, usando las cabeceras como las claves de los valores de cada usuario.\n\nimport fs from 'fs/promises'\n\nasync function getActiveUsers() {\n  const usersArray = []\n\n  const filePath = new URL('./subs.csv', import.meta.url)\n  const data = await fs.readFile(filePath, 'utf8')\n\n  const lines = data.trim().split('\\n')\n  const headers = lines[0].split(',')\n\n  for (let i = 1; i < lines.length; i++) {\n    const user = {}\n    const values = lines[i].split(',')\n\n    headers.forEach((header, index) => {\n      user[header.trim()] = values[index].trim()\n    })\n\n    if (user.status === 'activo') usersArray.push(user)\n  }\n\n  return usersArray\n}\n\n// Una vez obtenidos los datos, creamos una función que nos retornará un usuario al azar.\n\nconst activeUsers = await getActiveUsers()\nconst getRandomUser = () => activeUsers[Math.floor(Math.random() * activeUsers.length)]\n\n// Haremos las comprobaciones para el ganador de cada premio y lo almacenaremos en un objeto.\n\nconst winners = {\n  suscription: null,\n  discount: null,\n  book: null,\n}\n\nlet winner = getRandomUser()\n\nwinners.suscription = winner\n\nwhile (Object.values(winners).includes(winner)) {\n  winner = getRandomUser()\n}\n\nwinners.discount = winner\n\nwhile (Object.values(winners).includes(winner)) {\n  winner = getRandomUser()\n}\n\nwinners.book = winner\n\n// Finalmente mostramos los resultados en consola.\n\nconsole.log('\\nEstos son los resultados:')\n\nconsole.log(`\\nEl ganador de una suscripción es:\n  ${winners.suscription.id}. ${winners.suscription.email}`)\n\nconsole.log(`\\nEl ganador de un descuento es:\n  ${winners.discount.id}. ${winners.discount.email}`)\n\nconsole.log(`\\nEl ganador de un libro es:\n  ${winners.book.id}. ${winners.book.email}`)\n"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/javascript/ddanone.js",
    "content": "/*\n*  Solución mixta con html y javascript para poder ser testeada en local\n*/\n<input type='file' onchange='openFile(event)'>\n\n<script>\nvar openFile = function(event) {\n\tvar input  = event.target;\n\tvar reader = new FileReader();\n\treader.onload = function() {\n\n    \t\t// Leer archivo\n    \t\tvar file = reader.result.split(\"\\n\");\n    \t\tfile.splice(0,1);\t// quitamos cabecera\n\n    \t\t// Sólo queremos los activos\n    \t\tvar activos = ''.split('');\t// nuevo array\n    \t\tfile=file.filter(function(cv,i){\n    \t\t\tif( cv.split(',')[2]=='activo' )\n    \t\t\t\tactivos.push(cv);\n    \t\t});\n\n    \t\t// Barajamos el array 3 veces\n\t\t    for (let i = activos.length-1; i >activos.length-4; i--) { \n    \t\t  const j = Math.floor(Math.random() * (i + 1)); \n          [activos[i], activos[j]] = [activos[j], activos[i]]; // intercambiar elemento del array\n  \t\t  } \n\n  \t\t  // Nos quedamos con los tres primeros\n  \t\t  activos=activos.splice(0,3);\n\n  \t\t  // Mostramos el id y el email por consola\n  \t\t  for(var k in activos){\n  \t\t\t  console.log(\"Winner %d: %s (%d)\", (k*1+1), activos[k].split(',')[1], activos[k].split(',')[0] );\n  \t\t  }\n  };\n  reader.readAsText(input.files[0]);\n};\n</script>\n"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/javascript/duendeintemporal.js",
    "content": "//#38 - MOUREDEV PRO \n/*\n * EJERCICIO:\n * He presentado mi proyecto más importante del año: mouredev pro.\n * Un campus para la comunidad, que lanzaré en octubre, donde estudiar\n * programación de una manera diferente.\n * Cualquier persona suscrita a la newsletter de https://mouredev.pro\n * accederá a sorteos mensuales de suscripciones, regalos y descuentos.\n *\n * Desarrolla un programa que lea los registros de un fichero .csv y\n * seleccione de manera aleatoria diferentes ganadores.\n * Requisitos:\n * 1. Crea un .csv con 3 columnas: id, email y status con valor \"activo\"\n *    o \"inactivo\" (y datos ficticios).\n *    Ejemplo: 1 | test@test.com | activo\n *             2 | test2@test.com | inactivo\n *    (El .csv no debe subirse como parte de la corrección)\n * 2. Recupera los datos desde el programa y selecciona email aleatorios.\n * Acciones:\n * 1. Accede al fichero .csv y selecciona de manera aleatoria un email\n *    ganador de una suscripción, otro ganador de un descuento y un último\n *    ganador de un libro (sólo si tiene status \"activo\" y no está repetido).\n * 2. Muestra los emails ganadores y su id.\n * 3. Ten en cuenta que la primera fila (con el nombre de las columnas)\n *    no debe tenerse en cuenta.\n */\n\n/*  Example of csv:\nid,email,status\n1,softbaby@hotmail.com,active\n2,psicotrogato@gmail.com,active\n3,coders@io.com,inactive\n4,chap_gtp@microsoft.com,active\n5,applesupport@mac.com,active\n6,someone@proton.me,inactive\n7,zeigest@movement.sw,active\n8,duendeintemporal@hotmail.com,active\n9,freelancer@developer.dev,inactivo\n10,crazycat@miau.miau,active\n*/\n\n/* In a console run the next comands:\nmkdir mouredev-pro\ncd mouredev-pro\nnpm init -y\nnpm install csv-parser\n*/\n\nlet log = console.log;\n\nconst fs = require('fs');\nconst csv = require('csv-parser');\n\nconst winners = {\n    subscription: null,\n    discount: null,\n    book: null\n};\n\nconst activeEmails = [];\n\n// Read the CSV file\nfs.createReadStream('subscribers.csv')\n    .pipe(csv())\n    .on('data', (row) => {\n        if (row.status === 'active') {\n            activeEmails.push({ id: row.id, email: row.email });\n        }\n    })\n    .on('end', () => {\n        selectWinners();\n        displayWinners();\n    });\n\nfunction selectWinners() {\n    // Shuffle the array of active emails\n    const shuffled = activeEmails.sort(() => 0.5 - Math.random());\n\n    // Select unique winners\n    winners.subscription = shuffled[0];\n    winners.discount = shuffled[1];\n    winners.book = shuffled[2];\n}\n\nfunction displayWinners() {\n    log('Winners:');\n    log(`Subscription: ID: ${winners.subscription.id}, Email: ${winners.subscription.email}`);\n    log(`Discount: ID: ${winners.discount.id}, Email: ${winners.discount.email}`);\n    log(`Book: ID: ${winners.book.id}, Email: ${winners.book.email}`);\n}\n\n/*\nWinners:\nSubscription: ID: 5, Email: applesupport@mac.com\nDiscount: ID: 4, Email: chap_gtp@microsoft.com\nBook: ID: 2, Email: psicotrogato@gmail.com\n*/"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/javascript/hectorio23.js",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\nconst fs = require('fs');\nconst readline = require('readline');\n\n// Leer archivo CSV\nfunction leerCSV(filepath) {\n    return new Promise((resolve, reject) => {\n        const participantes = [];\n        const rl = readline.createInterface({\n            input: fs.createReadStream(filepath),\n            crlfDelay: Infinity\n        });\n\n        rl.on('line', (line) => {\n            const [id, email, status] = line.split(',');\n            if (status === 'activo') {\n                participantes.push({ id, email, status });\n            }\n        });\n\n        rl.on('close', () => resolve(participantes));\n    });\n}\n\n// Seleccionar ganadores de forma aleatoria\nfunction seleccionarGanadores(participantes) {\n    if (participantes.length < 3) {\n        console.log(\"No hay suficientes participantes activos para seleccionar 3 ganadores.\");\n        return;\n    }\n\n    const shuffled = participantes.sort(() => 0.5 - Math.random());\n    const ganadores = shuffled.slice(0, 3);\n\n    console.log(`Ganador de suscripción: ID ${ganadores[0].id} | Email: ${ganadores[0].email}`);\n    console.log(`Ganador de descuento: ID ${ganadores[1].id} | Email: ${ganadores[1].email}`);\n    console.log(`Ganador de libro: ID ${ganadores[2].id} | Email: ${ganadores[2].email}`);\n}\n\n// Ejecutar el programa\nasync function main() {\n    const participantes = await leerCSV('suscriptores.csv');\n    seleccionarGanadores(participantes);\n}\n\nmain();\n"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/javascript/isaacus98.js",
    "content": "/*\n * EJERCICIO:\n * He presentado mi proyecto más importante del año: mouredev pro.\n * Un campus para la comunidad, que lanzaré en octubre, donde estudiar\n * programación de una manera diferente.\n * Cualquier persona suscrita a la newsletter de https://mouredev.pro\n * accederá a sorteos mensuales de suscripciones, regalos y descuentos.\n *\n * Desarrolla un programa que lea los registros de un fichero .csv y\n * seleccione de manera aleatoria diferentes ganadores.\n * Requisitos:\n * 1. Crea un .csv con 3 columnas: id, email y status con valor \"activo\"\n *    o \"inactivo\" (y datos ficticios).\n *    Ejemplo: 1 | test@test.com | activo\n *             2 | test2@test.com | inactivo\n *    (El .csv no debe subirse como parte de la corrección)\n * 2. Recupera los datos desde el programa y selecciona email aleatorios.\n * Acciones:\n * 1. Accede al fichero .csv y selecciona de manera aleatoria un email\n *    ganador de una suscripción, otro ganador de un descuento y un último\n *    ganador de un libro (sólo si tiene status \"activo\" y no está repetido).\n * 2. Muestra los emails ganadores y su id.\n * 3. Ten en cuenta que la primera fila (con el nombre de las columnas)\n *    no debe tenerse en cuenta.\n */\n\nclass User{\n    constructor(id, email, state) {\n        this.id = id\n        this.email = email\n        this.state = state\n    }\n}\n\nfunction readCSV(path) {\n    const fs = require('node:fs');\n    \n    try {\n        const data = fs.readFileSync(path, 'utf8');\n        const allLines = data.split(/\\r\\n|\\n/)\n        return allLines\n    } catch (err) {\n        console.error(err);\n        return null\n    }\n}\n\nconst lines = readCSV(\"C:\\\\Users\\\\isaac\\\\Desktop\\\\usuarios.csv\")\nlet users = new Map()\n\n// Asignar datos al Map\nif (lines != null) {\n    for (let line of lines) {\n        const data = line.split(\",\")\n        \n        if (!parseInt(data[0])) {\n            continue\n        }\n\n        users.set(parseInt(data[0]), new User(data[0], data[1], data[2]))\n    }\n    //console.log(users)\n}\n\n// Generar ganadores\nlet winner1\nlet winner2\nlet winner3\nlet id = 0\n\ndo {\n    id = Math.floor(Math.random() * users.size) + 1\n\n    if (users.has(id)) {\n        winner1 = users.get(id)\n    }\n} while (winner1 == undefined)\n\ndo {\n    id = Math.floor(Math.random() * users.size) + 1\n\n    if (users.has(id) & winner1 != users.get(id)) {\n        winner2 = users.get(id)\n    }\n} while (winner2 == undefined)\n\ndo {\n    id = Math.floor(Math.random() * users.size) + 1\n\n    if (users.has(id) & winner1 != users.get(id) & winner2 != users.get(id) & users.get(id).state == \"activo\") {\n        winner3 = users.get(id)\n    }\n} while (winner3 == undefined)\n\nconsole.log(`Ganador suscripción: ${winner1.id} - ${winner1.email}`)\nconsole.log(`Ganador descuento: ${winner2.id} - ${winner2.email}`)\nconsole.log(`Ganador libro: ${winner3.id} - ${winner3.email}`)\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n_______________________________________________________\n#38 MOUREDEV PRO\n-------------------------------------------------------\n * He presentado mi proyecto más importante del año: mouredev pro.\n * Un campus para la comunidad, que lanzaré en octubre, donde estudiar\n * programación de una manera diferente.\n * Cualquier persona suscrita a la newsletter de https://mouredev.pro\n * accederá a sorteos mensuales de suscripciones, regalos y descuentos.\n *\n * Desarrolla un programa que lea los registros de un fichero .csv y\n * seleccione de manera aleatoria diferentes ganadores.\n * Requisitos:\n * 1. Crea un .csv con 3 columnas: id, email y status con valor \"activo\"\n *    o \"inactivo\" (y datos ficticios).\n *    Ejemplo: 1 | test@test.com | activo\n *             2 | test2@test.com | inactivo\n *    (El .csv no debe subirse como parte de la corrección)\n * 2. Recupera los datos desde el programa y selecciona email aleatorios.\n * Acciones:\n * 1. Accede al fichero .csv y selecciona de manera aleatoria un email\n *    ganador de una suscripción, otro ganador de un descuento y un último\n *    ganador de un libro (sólo si tiene status \"activo\" y no está repetido).\n * 2. Muestra los emails ganadores y su id.\n * 3. Ten en cuenta que la primera fila (con el nombre de las columnas)\n *    no debe tenerse en cuenta.\n*/\n// ________________________________________________________\n// users.csv\n/*\nid,email,status\n1,john.doe1@example.com,active\n2,jane.smith2@example.com,active\n3,michael.johnson3@example.com,active\n4,emily.davis4@example.com,active\n5,daniel.brown5@example.com,active\n6,sarah.miller6@example.com,active\n7,william.moore7@example.com,active\n8,olivia.jones8@example.com,active\n9,james.wilson9@example.com,active\n10,lisa.taylor10@example.com,active\n*/\n\nconst fs = require('fs');\n\nconst readCsv = (filePath) => {\n    try {\n        const data = fs.readFileSync(filePath, 'utf8');\n        const lines = data.split('\\n').map(line => line.trim());\n        const headers = lines[0].split(',');\n        const rows = lines.slice(1).filter(line => line).map(line => {\n            const values = line.split(',');\n            const entry = {};\n            headers.forEach((header, index) => {\n                entry[header.trim()] = values[index].trim();\n            });\n            return entry;\n        });\n        return rows;\n    } catch (error) {\n        console.error(`Error reading '${filePath}': ${error.message}`);\n        return null;\n    }\n};\n\nconst getActiveEntries = (entries) => {\n    return entries.filter(entry => entry.status.toLowerCase() === 'active')\n        .map(({ id, email, status }) => ({ id, email, status }));\n};\n\nconst selectWinners = (activeEntries, numWinners) => {\n    const shuffled = [...activeEntries].sort(() => Math.random() - 0.5);\n    return shuffled.slice(0, Math.min(numWinners, activeEntries.length));\n};\n\nconst distributePrizes = (winners, prizes) => {\n    const shuffledPrizes = [...prizes].sort(() => Math.random() - 0.5);\n    winners.forEach((winner, index) => {\n        const prize = shuffledPrizes[index];\n        console.log(`${prize.padEnd(11)} -> Id(${winner.id}): ${winner.email}`);\n    });\n};\n\nconst main = () => {\n    console.log(\"Usuarios ganadores de 'MOUREDEV PRO:'\");\n    const csvFile = 'users.csv';\n    const prizes = [\"Suscripción\", \"Descuento\", \"Libro\"];\n\n    const entries = readCsv(csvFile);\n    if (entries) {\n        const activeEntries = getActiveEntries(entries);\n        const winners = selectWinners(activeEntries, 3);\n        if (winners.length > 0) {\n            distributePrizes(winners, prizes);\n        } else {\n            console.log(\"No se encontraron entradas activas.\");\n        }\n    } else {\n        console.log(\"No se pudieron leer los datos del archivo CSV.\");\n    }\n};\n\nmain();\n"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/javascript/miguelex.js",
    "content": "const fs = require('fs');\n\nfunction obtenerSuscriptoresActivos(archivoCsv) {\n    const data = fs.readFileSync(archivoCsv, 'utf-8');\n    const filas = data.split('\\n').slice(1); // Saltar la primera fila (cabeceras)\n\n    const suscriptores = [];\n    for (let fila of filas) {\n        const [id, email, status] = fila.split(',');\n        if (status.trim().toLowerCase() === 'activo') {\n            suscriptores.push({ id: id.trim(), email: email.trim() });\n        }\n    }\n\n    return suscriptores;\n}\n\nfunction seleccionarGanadores(suscriptores, numeroGanadores) {\n    if (suscriptores.length < numeroGanadores) {\n        return null; \n    }\n\n    const ganadores = [];\n    const indicesSeleccionados = new Set();\n\n    while (ganadores.length < numeroGanadores) {\n        const indiceAleatorio = Math.floor(Math.random() * suscriptores.length);\n        if (!indicesSeleccionados.has(indiceAleatorio)) {\n            ganadores.push(suscriptores[indiceAleatorio]);\n            indicesSeleccionados.add(indiceAleatorio);\n        }\n    }\n\n    return ganadores;\n}\n\nconst archivoCsv = 'suscriptores.csv';\n\nconst suscriptoresActivos = obtenerSuscriptoresActivos(archivoCsv);\n\nif (suscriptoresActivos.length > 0) {\n    const ganadores = seleccionarGanadores(suscriptoresActivos, 3);\n    if (ganadores) {\n        console.log(\"Ganador de la suscripción:\", ganadores[0]);\n        console.log(\"Ganador del descuento:\", ganadores[1]);\n        console.log(\"Ganador del libro:\", ganadores[2]);\n    } else {\n        console.log(\"No hay suficientes suscriptores activos para seleccionar 3 ganadores.\");\n    }\n} else {\n    console.log(\"No hay suscriptores activos.\");\n}\n"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/javascript/pedamoci.js",
    "content": "import  fs  from \"fs\"\n\nconst colors = {\n  red: \"\\x1b[31m\",\n  green: \"\\x1b[32m\",\n  yellow: \"\\x1b[33m\",\n  cyan: \"\\x1b[34m\",\n  reset: \"\\x1b[0m\",\n}\n\nclass Renderer {\n  static error(message) {\n    console.log(colors.red + \"Error: \" + message + colors.reset)\n  }\n\n  static success(message) {\n    console.log(colors.green + \"Success: \" + message + colors.reset)\n  }\n\n  static info(info) {\n    console.log(info + colors.reset)\n  }\n}\n\nfunction getUsers(csv) {\n  const usersActives = (csv.split('\\r\\n')).map(arr => arr.split(',')).filter(arr => arr[2] === 'activo')\n\n  const visited = new Set()\n\n  const users = [...usersActives.filter(user => {\n      if (!visited.has(user[0]) || !visited.has(user[1])) {\n        visited.add(user[0])\n        visited.add(user[1])\n        return true\n      } else {\n        return false\n      }\n    })]\n\n  return users\n}\n\nfunction printWinners(winners) {\n  Renderer.info(colors.yellow + \"The winner of a subscription is:\")\n  Renderer.info(colors.green + `   Email --> ${winners[0][1]}` + \n                    `\\n   ID --> ${winners[0][0]}`)\n\n  Renderer.info(colors.yellow + \"\\nThe winner of a discount is:\")\n  Renderer.info(colors.green + `   Email --> ${winners[1][1]}` + \n                    `\\n   ID --> ${winners[1][0]}`)\n\n  Renderer.info(colors.yellow + \"\\nThe winner of a book is:\")\n  Renderer.info(colors.green + `   Email --> ${winners[2][1]}` + \n                    `\\n   ID --> ${winners[2][0]}`)\n}\n\nfunction program() {\n  const csv = fs.readFileSync('text.csv', 'utf-8')\n\n  const users = getUsers(csv)\n  let winners = []\n\n  if (users.length >= 3) {\n    for (let i = 0; i < 3; i++) {\n      winners.push(users[Math.floor(Math.random() * users.length)])\n    }\n\n    printWinners(winners)\n\n  } else Renderer.error(\"There are not enough active users to hold the draw\")\n}\n\nprogram()"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/javascript/raulG91.js",
    "content": "const { stat } = require('fs')\nconst path = require('path')\nconst fs = require('fs').promises\n\nasync function readFile(filename){\n\n    const filePath = path.join(__dirname,filename)\n\n    let fileData =  await fs.readFile(filePath)\n    //Generate a list with all rows in the file\n    dataList =  fileData.toString().split(\"\\n\")\n    //Remove header\n    return dataList.slice(1,dataList.length)\n}\n\n\nasync function main(){\n    try{\n        fileData =  await readFile('file.csv')\n        let active_users = []\n        for(element of fileData){\n            let[id,email,status] = element.split(\"|\")\n            status = status.trim().toLowerCase()\n            if(status == \"activo\"){\n                active_users.push({\"id\":id,\"email\":email,\"status\":status})\n            }\n        }\n\n        if(active_users.length >= 3){\n            //Get subscription winner\n            index = Math.floor(Math.random() * active_users.length)\n            console.log(\"Subscription winner \" + active_users[index].email + \" with id: \"+active_users[index].id)\n            active_users.splice(index,1) //Remove selected user\n            //Get discount winner\n\n            index = Math.floor(Math.random() *active_users.length)\n            console.log(\"Discount winner \" + active_users[index].email + \" with id: \"+active_users[index].id)\n            active_users.splice(index,1) //Remove selected user\n            // Get book winner\n            index = Math.floor(Math.random() *active_users.length)\n            console.log(\"Book winner \" + active_users[index].email + \" with id: \"+active_users[index].id)\n            active_users.splice(index,1)\n        }\n        else{\n            console.log(\"There are least than 3 active users\")\n        }\n\n    \n    }catch (error){\n        console.log(\"Error opening the file: \" + error.message)\n    }\n    \n\n\n}\n\nmain()"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/kotlin/blackriper.kt",
    "content": "import kotlinx.coroutines.Dispatchers\r\nimport kotlinx.coroutines.async\r\nimport kotlinx.coroutines.coroutineScope\r\nimport kotlinx.coroutines.flow.Flow\r\nimport kotlinx.coroutines.flow.asFlow\r\nimport kotlinx.coroutines.flow.filter\r\nimport kotlinx.coroutines.flow.flow\r\nimport kotlinx.coroutines.flow.map\r\nimport kotlinx.coroutines.flow.toList\r\nimport kotlinx.coroutines.flow.transform\r\nimport kotlinx.coroutines.launch\r\nimport kotlinx.coroutines.runBlocking\r\nimport java.io.FileInputStream\r\nimport java.io.InputStream\r\n\r\n//1.- definir una clase para parsear la info\r\n\r\nenum class Status(val state: String){\r\n    ACTIVE(\"active\"),\r\n    INACTIVE(\"inactive\")\r\n\r\n}\r\n\r\nenum class Prize{\r\n    Suscription,\r\n    Discount,\r\n    Book,\r\n    NotWinner\r\n}\r\n\r\ndata class Suscriptor(val id: Int,val email: String,val status: Status) {\r\n  companion object {\r\n      fun parseStatus(name: String): Status = when (name) {\r\n          Status.ACTIVE.state -> Status.ACTIVE\r\n          Status.ACTIVE.state -> Status.INACTIVE\r\n          else -> Status.INACTIVE\r\n      }\r\n  }\r\n\r\n  fun toWinner(prize:Prize):Winner{\r\n      return Winner(\r\n          id,\r\n          email,\r\n          prize\r\n      )\r\n  }\r\n}\r\n\r\ndata class Winner(val id: Int, val email: String, val prize:Prize)\r\n\r\n//2.- Definir comportamiento\r\ninterface CSVParse{\r\n    suspend fun readCsv(): Flow<Suscriptor>\r\n}\r\n\r\n//3.- implementar interface\r\nclass CSVProcessor( private val input: InputStream):CSVParse{\r\n\r\n   override suspend fun readCsv(): Flow<Suscriptor>{\r\n       val reader= input.bufferedReader()\r\n       val header= reader.readLine()\r\n\r\n      val suscriptors= reader.lineSequence()\r\n           .filter { it.isNotBlank() }\r\n           .map { toSuscriptor(it) }\r\n          .asFlow()\r\n\r\n       return suscriptors\r\n    }\r\n\r\n\r\n   private fun toSuscriptor(value: String):Suscriptor{\r\n      val(id,email,status)=value.split(',', ignoreCase = false, limit = 3)\r\n      return Suscriptor(\r\n           id.toInt(),\r\n           email,\r\n           Suscriptor.parseStatus(status)\r\n      )\r\n   }\r\n}\r\n\r\n//4.- funciones auxiliares\r\nfun getInputStream(src: String): InputStream{\r\n    val file= runCatching {\r\n        FileInputStream(src)\r\n    }\r\n    if (file.isFailure) println(\"error to read file ${file.exceptionOrNull()}\")\r\n    return file.getOrDefault(FileInputStream(\"src/main/resources/datamoure.csv\"))\r\n}\r\n\r\nfun getPrize(numWinner: Int):Prize=when(numWinner){\r\n    1-> Prize.Suscription\r\n    2->Prize.Discount\r\n    3->Prize.Book\r\n    else -> Prize.NotWinner\r\n}\r\n\r\n\r\nfun randomWinners(suscriptors: List<Suscriptor>): List<Winner>{\r\n    return mutableListOf<Winner>().apply {\r\n        var numWinner=0\r\n        while (size != 3) {\r\n            val ind = (0..suscriptors.size).random()\r\n            val suscriptor = suscriptors.get(ind)\r\n            if(count { it.email == suscriptor.email } == 0) {\r\n                numWinner++\r\n                val winner=Winner(\r\n                    suscriptor.id,\r\n                    suscriptor.email,\r\n                    getPrize(numWinner)\r\n                )\r\n                add(winner)\r\n            }\r\n        }\r\n    }\r\n\r\n  }\r\n\r\nsuspend fun getWinners(suscriptors: Flow<Suscriptor>){\r\n    val activeSuscriptor = suscriptors\r\n        .filter { it.status == Status.ACTIVE }.toList()\r\n\r\n    randomWinners(activeSuscriptor).run {\r\n        println(\"Results\")\r\n        println(\"| Id   |   Email    |     Prize\")\r\n        this.forEach {\r\n            println(\"  ${it.id}   ${it.email}   ${it.prize}\")\r\n        }\r\n    }\r\n}\r\n\r\n\r\nfun main()= runBlocking {\r\n    val file=getInputStream(\"src/main/resources/datamoure.csv\")\r\n    val csvParser=CSVProcessor(file)\r\n    val suscriptors= async{csvParser.readCsv()}.await()\r\n    val job=launch{getWinners(suscriptors)}\r\n    job.join()\r\n}"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/php/ddanone.php",
    "content": "<?php\n// Cargar el csv en un array\n$file  \t\t= file( dirname(__FILE__).\"/fichero.csv\", FILE_IGNORE_NEW_LINES|FILE_SKIP_EMPTY_LINES);\n\n// Nos quedamos sólo con los activos\n$file  \t\t= array_filter($file, function($k) { return explode(',',$k)[2] == 'activo'; });\n\n// Seleccionamos 3 registros al azar\n$winners \t= array_rand($file, 3);\n\n// Los imprimimos\nforeach($winners as $k=>$v){ echo sprintf(\"Winner %d: %s (%d) <br>\", $k+1, explode(',',$file[$v])[1], explode(',',$file[$v])[0]); }\n\n// 4 líneas de código !! ;)\n"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/php/miguelex.php",
    "content": "<?php\nfunction obtenerSuscriptoresActivos($archivoCsv) {\n    $suscriptores = [];\n\n    if (($handle = fopen($archivoCsv, \"r\")) !== FALSE) {\n        fgetcsv($handle); \n        \n        while (($data = fgetcsv($handle, 1000, \",\")) !== FALSE) {\n            $id = $data[0];\n            $email = $data[1];\n            $status = $data[2];\n\n            if (strtolower($status) === \"activo\") {\n                $suscriptores[] = ['id' => $id, 'email' => $email];\n            }\n        }\n        fclose($handle);\n    }\n\n    return $suscriptores;\n}\n\nfunction seleccionarGanadores($suscriptores, $numeroGanadores) {\n    if (count($suscriptores) < $numeroGanadores) {\n        return null; \n    }\n\n    $ganadores = [];\n    $indicesSeleccionados = [];\n\n    while (count($ganadores) < $numeroGanadores) {\n        $indiceAleatorio = rand(0, count($suscriptores) - 1);\n\n        if (!in_array($indiceAleatorio, $indicesSeleccionados)) {\n            $ganadores[] = $suscriptores[$indiceAleatorio];\n            $indicesSeleccionados[] = $indiceAleatorio;\n        }\n    }\n\n    return $ganadores;\n}\n\n$archivoCsv = 'suscriptores.csv';\n\n$suscriptoresActivos = obtenerSuscriptoresActivos($archivoCsv);\n\nif (count($suscriptoresActivos) > 0) {\n    $ganadores = seleccionarGanadores($suscriptoresActivos, 3);\n\n    if ($ganadores) {\n        echo \"Ganador de la suscripción:\\n\";\n        echo \"ID: \" . $ganadores[0]['id'] . \" | Email: \" . $ganadores[0]['email'] . \"\\n\\n\";\n\n        echo \"Ganador del descuento:\\n\";\n        echo \"ID: \" . $ganadores[1]['id'] . \" | Email: \" . $ganadores[1]['email'] . \"\\n\\n\";\n\n        echo \"Ganador del libro:\\n\";\n        echo \"ID: \" . $ganadores[2]['id'] . \" | Email: \" . $ganadores[2]['email'] . \"\\n\\n\";\n    } else {\n        echo \"No hay suficientes suscriptores activos para seleccionar 3 ganadores.\\n\";\n    }\n} else {\n    echo \"No hay suscriptores activos.\\n\";\n}\n\n"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/python/CarlosVR48.py",
    "content": "import csv,random\n                \ndef cantidad_lineas():\n    cantidad = 0\n\n    with open (\"mouredevpro.csv\") as file:\n        datos = csv.reader(file , delimiter =\"|\")\n    \n        for dato in datos:\n            cantidad = cantidad + 1\n        return cantidad -1 \n    \ndef ganador(posicion):\n    num = 0\n\n    with open (\"mouredevpro.csv\") as file:\n        lineas = csv.reader(file , delimiter =\"|\")\n    \n        for linea in lineas:\n            if num == posicion:\n                ganador = linea\n            num = num + 1\n        \n        return ganador     \n    \ncantidad = cantidad_lineas()  \n\nwhile True:\n    posicion1 = random.randint (1,cantidad)\n    subscripcion = ganador(posicion1)\n    if subscripcion [2] == \" activo\":\n        break\n\nwhile True:\n    posicion2 = random.randint (1,cantidad) \n    if not(posicion2 == posicion1):\n        descuento = ganador(posicion2)\n        if descuento [2] == \" activo\":\n            break\n        \nwhile True:\n    posicion3 = random.randint (1,cantidad) \n    if not(posicion3 == posicion2 or posicion3 == posicion1):\n        libro = ganador (posicion3)\n        if libro [2] == \" activo\":\n            break \n         \nprint (f\"EL GANADOR DE LA SUBSCRIPCION ES: {subscripcion[1]} . CON ID: {subscripcion[0]}.\\n\")\nprint (f\"EL GANADOR DE LA DESCUENTO ES: {descuento[1]} . CON ID: {descuento[0]}.\\n\")\nprint (f\"EL GANADOR DE LA LIBRO ES: {libro[1]} . CON ID: {libro[0]}.\\n\")\n           \n    "
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/python/CesarCarmona30.py",
    "content": "import os\nimport csv\nimport random\n\ndef read_csv_data():\n  file_dir = os.path.dirname(os.path.abspath(__file__))\n  csv_file = f\"{file_dir}/subs.csv\"\n\n  data = []\n\n  with open(csv_file, mode=\"r\") as file:\n    reader = csv.DictReader(file)\n    for row in reader:\n      if row[\"status\"] == \"activo\":\n        data.append(row)\n\n  return data\n\n\ndef select_winners(data):\n  if len(data) < 3:\n    raise ValueError(\"El número de elementos debe ser de mínimo 3.\")\n  \n  return random.sample(data, 3)\n\ndef display_winners(winners):\n  prizes = [\"Suscripcion\", \"Descuento\", \"Libro\"]\n  for winner, prize in zip(winners, prizes):\n    print(f\"{prize}: {winner[\"email\"]} (ID: {winner[\"id\"]})\")\n\ntry:\n  data = read_csv_data()\n  winners = select_winners(data)\n  display_winners(winners)\nexcept Exception as e:\n  print(e)"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/python/EmmanuelMMontesinos.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * He presentado mi proyecto más importante del año: mouredev pro.\n * Un campus para la comunidad, que lanzaré en octubre, donde estudiar\n * programación de una manera diferente.\n * Cualquier persona suscrita a la newsletter de https://mouredev.pro\n * accederá a sorteos mensuales de suscripciones, regalos y descuentos.\n *\n * Desarrolla un programa que lea los registros de un fichero .csv y\n * seleccione de manera aleatoria diferentes ganadores.\n * Requisitos:\n * 1. Crea un .csv con 3 columnas: id, email y status con valor \"activo\"\n *    o \"inactivo\" (y datos ficticios).\n *    Ejemplo: 1 | test@test.com | activo\n *             2 | test2@test.com | inactivo\n *    (El .csv no debe subirse como parte de la corrección)\n * 2. Recupera los datos desde el programa y selecciona email aleatorios.\n * Acciones:\n * 1. Accede al fichero .csv y selecciona de manera aleatoria un email\n *    ganador de una suscripción, otro ganador de un descuento y un último\n *    ganador de un libro (sólo si tiene status \"activo\" y no está repetido).\n * 2. Muestra los emails ganadores y su id.\n * 3. Ten en cuenta que la primera fila (con el nombre de las columnas)\n *    no debe tenerse en cuenta.\n */\n\"\"\"\nimport csv\nfrom random import choice\n\nnombre_csv = \"roadmap/38 - MOUREDEV PRO/python/Prueba.csv\"\n\nclass Archivo:\n    def __init__(self,nombre,delimitador):\n        self.nombre = nombre\n        self.delimitador = delimitador\n\n    def sorteo(self):\n        self.leer_csv()\n        Ganadores.seleccionar_ganador(Ganadores)\n    \n    def leer_csv(self):\n        with open(self.nombre,\"r\") as archivo:\n            lector = csv.reader(archivo,delimiter=self.delimitador)\n            lector = list(lector)\n            for row in lector[1::]:\n                id,email,status = row\n                Ganadores(id,email,status)\n                \n                print(f\"{id} Email: {email} Status: {status}\")\n            \nclass Ganadores:\n    lista_participantes = []\n    lista_ganadores = []\n    def __init__(self,id,email,status):\n        self.id = id\n        self.email = email\n        self.status = status\n        if self.status == \"activo\":\n            Ganadores.lista_participantes.append(self)\n    \n    def seleccionar_ganador(self):\n        print()\n        print(\"Sorteo de MoureDev Pro\")\n        while len(Ganadores.lista_ganadores) < 3:\n            participante = choice(Ganadores.lista_participantes)\n            if participante not in Ganadores.lista_ganadores:\n                Ganadores.lista_ganadores.append(participante)\n            else:\n                continue\n        self.ganador_libro = Ganadores.lista_ganadores[0]\n        self.ganador_descuento = Ganadores.lista_ganadores[1]\n        self.subscripcion = Ganadores.lista_ganadores[2]\n\n        print(f\"Ganador de la subscripción: ID: {self.subscripcion.id} Email: {self.subscripcion.email}\")\n        print(f\"Ganador del descuento: ID: {self.ganador_descuento.id} Email: {self.ganador_descuento.email}\")\n        print(f\"Ganador del libro: ID: {self.ganador_libro.id} Email: {self.ganador_libro.email}\")\n\n# Pruebas\nprueba = Archivo(nombre_csv,delimitador=\"|\")\nprueba.leer_csv()\n\nprueba.sorteo()"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/python/Gordo-Master.py",
    "content": "# 38 - Mouredev pro\nimport os\nimport csv\nimport random\n\n\ndef read_csv() -> list:\n    # Variable que almacena los datos del csv\n    data = []\n    # Variable que almacena los valores que estan activos\n    active_list = list()\n\n    # Obtener la ruta\n    file_dir = os.path.dirname(os.path.abspath(__file__))\n    file_dir += \"\\\\lista.csv\"\n\n    # Trabajando con el archivo csv\n    with open(file=file_dir,encoding=\"utf-8\", mode= \"r\") as archivo:\n        data = csv.reader(archivo)\n\n        # Tomando solo los valores que son activos\n        for fila in data:\n            if fila[2] == \"activo\":\n                active_list.append(fila)\n\n    return active_list    \n\ndef select_winners(active_list: list) -> list:\n    if len(active_list) < 3:\n        raise ValueError(\"El numero de elementos debe ser mínimo 3.\")\n    # Crea una lista con 3 secciones aleatorias (toma el nombre como referencia). Sample que no toma repetidos\n    winners = random.sample([element[1] for element in active_list],3)\n    # Crea la nueva lista usando los resultados de winners como referencia\n    winners_list = [element for element in active_list if element[1] in winners]\n    # Reordena todos los valores\n    random.shuffle(winners_list)\n    return winners_list\n\ndef display_winners(winners_list):\n    # Imprimir los ganadores\n    print(\"Ganadores del concurso:\")\n    print()\n    print(f\"1er premio: Una suscripción a MouredevPro!!!\") \n    print(f\"Ganador: {winners_list[0][1]} (ID: {winners_list[0][0]})\") \n    print()\n    print(f\"2do premio: Una descuento a MouredevPro!!!\") \n    print(f\"Ganador: {winners_list[1][1]} (ID: {winners_list[1][0]})\")\n    print()\n    print(f\"3er premio: Una libro!!!\") \n    print(f\"Ganador: {winners_list[2][1]} (ID: {winners_list[2][0]})\") \n\ntry:\n    data = read_csv()\n    winners = select_winners(data)\n    display_winners(winners)\nexcept Exception as e:\n    print(e)"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/python/JesusWay69.py",
    "content": "import os, platform, csv, random, time\n\nif (platform.platform().startswith(\"macOS\") or platform.platform().startswith(\"Linux\")):\n    os.system('clear')\nelse:\n    os.system('cls')\n\n\"\"\" * EJERCICIO:\n * He presentado mi proyecto más importante del año: mouredev pro.\n * Un campus para la comunidad, que lanzaré en octubre, donde estudiar\n * programación de una manera diferente.\n * Cualquier persona suscrita a la newsletter de https://mouredev.pro\n * accederá a sorteos mensuales de suscripciones, regalos y descuentos.\n *\n * Desarrolla un programa que lea los registros de un fichero .csv y\n * seleccione de manera aleatoria diferentes ganadores.\n * Requisitos:\n * 1. Crea un .csv con 3 columnas: id, email y status con valor \"activo\"\n *    o \"inactivo\" (y datos ficticios).\n *    Ejemplo: 1 | test@test.com | activo\n *             2 | test2@test.com | inactivo\n *    (El .csv no debe subirse como parte de la corrección)\n * 2. Recupera los datos desde el programa y selecciona email aleatorios.\n * Acciones:\n * 1. Accede al fichero .csv y selecciona de manera aleatoria un email\n *    ganador de una suscripción, otro ganador de un descuento y un último\n *    ganador de un libro (sólo si tiene status \"activo\" y no está repetido).\n * 2. Muestra los emails ganadores y su id.\n * 3. Ten en cuenta que la primera fila (con el nombre de las columnas)\n *    no debe tenerse en cuenta.\"\"\"\n\nmy_file = \"newsletter_users.csv\"\ncolumns = ['id', 'email', 'status']\nusers = [{'id':1, 'email':'supermario@mouredev.com', 'status':'activo'},\n         {'id':2, 'email':'darkvader@mouredev.com', 'status':'activo'},\n         {'id':3, 'email':'pikachu@mouredev.com', 'status':'activo'},\n         {'id':4, 'email':'joseluistorrente@mouredev.com', 'status':'activo'},\n         {'id':5, 'email':'homersimpson@mouredev.com', 'status':'activo'},\n         {'id':6, 'email':'mickeymouse@mouredev.com', 'status':'activo'},\n         {'id':7, 'email':'sansastark@mouredev.com', 'status':'activo'},\n         {'id':8, 'email':'fionagalagher@mouredev.com', 'status':'activo'},\n         {'id':9, 'email':'michaelscott@mouredev.com', 'status':'activo'},\n         {'id':10, 'email':'sheldoncooper@mouredev.com', 'status':'activo'},\n         {'id':11, 'email':'spiderman@mouredev.com', 'status':'activo'},\n         {'id':12, 'email':'walterwhite@mouredev.com', 'status':'activo'},\n         {'id':13, 'email':'petergriffin@mouredev.com', 'status':'activo'},\n         {'id':14, 'email':'rachelgreen@mouredev.com', 'status':'activo'},\n         {'id':15, 'email':'jessicajones@mouredev.com', 'status':'activo'},\n         {'id':16, 'email':'ricksanchez@mouredev.com', 'status':'activo'},\n         {'id':17, 'email':'maxrockatansky@mouredev.com', 'status':'activo'},\n         {'id':18, 'email':'hackerman@mouredev.com', 'status':'activo'},\n         {'id':19, 'email':'elliotalderson@mouredev.com', 'status':'activo'},\n         {'id':20, 'email':'jesusway69@mouredev.com', 'status':'activo'},]\n\ndef create_csv(users_list:list):\n    with open(my_file, mode='w', newline='') as file:\n        writer = csv.DictWriter(file, delimiter = ';', fieldnames = columns )\n        writer.writeheader()\n        for user in users_list:\n           writer.writerow(user)\n    \n\n\ndef read_dict_csv():\n    with open(my_file) as file:\n        content_dict_csv = csv.DictReader(file, delimiter = ';')\n        for row in content_dict_csv:\n            print(\"ID:\", '{:<4}'.format(row['id']), \"Email:\", '{:<30}'.format(row['email']), \"Estado: \", row['status'])\n            content_dict_csv\n    print()\n\ndef lottery()->list:\n    active_list = []\n    with open(my_file) as file:\n        content_dict_csv = csv.DictReader(file, delimiter = ';')\n        content_list_csv = list(content_dict_csv)\n    for user in content_list_csv:\n        if user['status'] == 'activo':\n            active_list.append(dict(user))  \n    if len(active_list) < 3:\n        print(\"No quedan suficientes participantes para lanzar los 3 sorteos, fin del programa.\")\n        return []\n    return active_list  \n\n        \ndef menu():\n    while True:\n        print(\"\"\"\\n1- Mostrar listado de participantes\n2- Lanzar sorteo\n3- Resetear toda la lista de participantes con estado activo \n4- Salir\"\"\")\n        option = input(\"Elija entre estas 4 opciones -> \")\n        if not option.isdigit() or int(option) < 1 or int(option) > 4:\n            print(\"Sólo se pueden introducir números del 1 al 3\")\n        elif option == '1':\n            read_dict_csv()\n        elif option == '2':\n            if len(lottery()) == 0:\n                break\n            subscription_winner = random.choice(lottery())\n            print(f\"\\nEl ganador de la subscripción tiene el ID: {subscription_winner['id']} y su email es {subscription_winner['email']}\")\n            subscription_winner['status'] = 'inactivo'\n            create_csv(list(lottery()))\n            time.sleep(1)\n\n            discount_winner = random.choice(lottery())\n            print(f\"El ganador del descuento tiene el ID: {discount_winner['id']} y su email es {discount_winner['email']}\")\n            discount_winner['status'] = 'inactivo'\n            create_csv(list(lottery()))\n            time.sleep(1)\n\n            book_winner = random.choice(lottery())\n            print(f\"El ganador del libro tiene el ID: {book_winner['id']} y su email es {book_winner['email']}\")\n            book_winner['status'] = 'inactivo'\n            create_csv(list(lottery()))\n\n        elif option == '3':\n            create_csv(users)\n        else:\n            break\nmenu()\n\n\n\n\n\n        \n\n\n\n\n\n\n\n#ejemplos: https://pywombat.com/articles/archivos-csv-python"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/python/JohnAlexGuerrero.py",
    "content": "\n\"\"\"#38-mourodev-pro.ipynb\n\nAutomatically generated by Colab.\n\nOriginal file is located at\n    https://colab.research.google.com/drive/1QD6r-2pvRV1RgmkqXQWAlZJc-knZLOkg\n\n/*\n * EJERCICIO:\n * He presentado mi proyecto más importante del año: mouredev pro.\n * Un campus para la comunidad, que lanzaré en octubre, donde estudiar\n * programación de una manera diferente.\n * Cualquier persona suscrita a la newsletter de https://mouredev.pro\n * accederá a sorteos mensuales de suscripciones, regalos y descuentos.\n *\n * Desarrolla un programa que lea los registros de un fichero .csv y\n * seleccione de manera aleatoria diferentes ganadores.\n * Requisitos:\n * 1. Crea un .csv con 3 columnas: id, email y status con valor \"activo\"\n *    o \"inactivo\" (y datos ficticios).\n *    Ejemplo: 1 | test@test.com | activo\n *             2 | test2@test.com | inactivo\n *    (El .csv no debe subirse como parte de la corrección)\n * 2. Recupera los datos desde el programa y selecciona email aleatorios.\n * Acciones:\n * 1. Accede al fichero .csv y selecciona de manera aleatoria un email\n *    ganador de una suscripción, otro ganador de un descuento y un último\n *    ganador de un libro (sólo si tiene status \"activo\" y no está repetido).\n * 2. Muestra los emails ganadores y su id.\n * 3. Ten en cuenta que la primera fila (con el nombre de las columnas)\n *    no debe tenerse en cuenta.\n */\n'''\n\"\"\"\n\nimport pandas as pd\nimport random\n\nfichero = pd.read_csv('./test.csv')\n\ndef seleccionar_ganador(archivo):\n  df_activos = archivo[archivo['status'] == 'activo']\n  if not df_activos.empty:\n    ganador_indice = random.randint(0, len(df_activos) - 1)\n    ganador = df_activos.iloc[ganador_indice]\n    return ganador['id'], ganador['email']\n  else:\n    return None, None\n\n\nganador_suscripcion_id, ganador_suscripcion_email = seleccionar_ganador(fichero)\nganador_descuento_id, ganador_descuento_email = seleccionar_ganador(fichero)\nganador_libro_id, ganador_libro_email = seleccionar_ganador(fichero)\n\n\nprint(\"Ganador de suscripción:\")\nif ganador_suscripcion_email:\n  print(\"ID:\", ganador_suscripcion_id, \", Email:\", ganador_suscripcion_email)\nelse:\n  print(\"No hay ganadores activos.\")\n\nprint(\"\\nGanador de descuento:\")\nif ganador_descuento_email:\n  print(\"ID:\", ganador_descuento_id, \", Email:\", ganador_descuento_email)\nelse:\n  print(\"No hay ganadores activos.\")\n\nprint(\"\\nGanador de libro:\")\nif ganador_libro_email:\n  print(\"ID:\", ganador_libro_id, \", Email:\", ganador_libro_email)\nelse:\n  print(\"No hay ganadores activos.\")"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/python/Juanppdev.py",
    "content": "\"\"\"\n * EJERCICIO:\n * He presentado mi proyecto más importante del año: mouredev pro.\n * Un campus para la comunidad, que lanzaré en octubre, donde estudiar\n * programación de una manera diferente.\n * Cualquier persona suscrita a la newsletter de https://mouredev.pro\n * accederá a sorteos mensuales de suscripciones, regalos y descuentos.\n *\n * Desarrolla un programa que lea los registros de un fichero .csv y\n * seleccione de manera aleatoria diferentes ganadores.\n * Requisitos:\n * 1. Crea un .csv con 3 columnas: id, email y status con valor \"activo\"\n *    o \"inactivo\" (y datos ficticios).\n *    Ejemplo: 1 | test@test.com | activo\n *             2 | test2@test.com | inactivo\n *    (El .csv no debe subirse como parte de la corrección)\n * 2. Recupera los datos desde el programa y selecciona email aleatorios.\n * Acciones:\n * 1. Accede al fichero .csv y selecciona de manera aleatoria un email\n *    ganador de una suscripción, otro ganador de un descuento y un último\n *    ganador de un libro (sólo si tiene status \"activo\" y no está repetido).\n * 2. Muestra los emails ganadores y su id.\n * 3. Ten en cuenta que la primera fila (con el nombre de las columnas)\n *    no debe tenerse en cuenta.\n\"\"\"\n\nimport csv\nimport random\n\n# Leer el archivo CSV\ndef leer_csv(filename):\n    with open(filename, mode='r') as file:\n        reader = csv.DictReader(file)\n        return [row for row in reader]\n\n# Seleccionar ganadores aleatorios\ndef seleccionar_ganadores(suscriptores):\n    activos = [s for s in suscriptores if s['status'] == 'activo']\n    ganadores = random.sample(activos, 3)\n    return ganadores\n\n# Mostrar los ganadores\ndef mostrar_ganadores(ganadores):\n    premios = ['suscripción', 'descuento', 'libro']\n    for ganador, premio in zip(ganadores, premios):\n        print(f\"Ganador de {premio}: ID {ganador['id']}, Email {ganador['email']}\")\n\n# Main\nif __name__ == \"__main__\":\n    suscriptores = leer_csv('d:/Proyectos Github/roadmap-retos-programacion/Roadmap/38 - MOUREDEV PRO/python/suscriptores.csv')\n    ganadores = seleccionar_ganadores(suscriptores)\n    mostrar_ganadores(ganadores)\n"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/python/Nicojsuarez2.py",
    "content": "# #38 MOUREDEV PRO\n> #### Dificultad: Fácil | Publicación: 16/09/24 | Corrección: 23/09/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * He presentado mi proyecto más importante del año: mouredev pro.\n * Un campus para la comunidad, que lanzaré en octubre, donde estudiar\n * programación de una manera diferente.\n * Cualquier persona suscrita a la newsletter de https://mouredev.pro\n * accederá a sorteos mensuales de suscripciones, regalos y descuentos.\n *\n * Desarrolla un programa que lea los registros de un fichero .csv y\n * seleccione de manera aleatoria diferentes ganadores.\n * Requisitos:\n * 1. Crea un .csv con 3 columnas: id, email y status con valor \"activo\"\n *    o \"inactivo\" (y datos ficticios).\n *    Ejemplo: 1 | test@test.com | activo\n *             2 | test2@test.com | inactivo\n *    (El .csv no debe subirse como parte de la corrección)\n * 2. Recupera los datos desde el programa y selecciona email aleatorios.\n * Acciones:\n * 1. Accede al fichero .csv y selecciona de manera aleatoria un email\n *    ganador de una suscripción, otro ganador de un descuento y un último\n *    ganador de un libro (sólo si tiene status \"activo\" y no está repetido).\n * 2. Muestra los emails ganadores y su id.\n * 3. Ten en cuenta que la primera fila (con el nombre de las columnas)\n *    no debe tenerse en cuenta.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/python/SooHav.py",
    "content": "# 38 MOUREDEV PRO\nimport csv\nimport os\nimport random\n\n# Ruta al directorio\ndirectorio = os.path.join(\"sofiah\", \"documentos\", \"temporal\", \"datos\")\n\n\n# Crea el directorio si no existe\nif not os.path.exists(directorio):\n    os.makedirs(directorio)\n\n# Nombre del archivo\nnombre_archivo = \"fichero.csv\"\n\n# Ruta completa del archivo\nruta_archivo = os.path.join(directorio, nombre_archivo)\n\n# Datos a escribir en el archivo\ndatos_usuario = [\n    {\n        'id': 1,\n        'email': 'soo@gmail.com',\n        'estatus': 'Activo'\n    },\n    {\n        'id': 2,\n        'email': 'pepe@gmail.com',\n        'estatus': 'Activo'\n    },\n    {\n        'id': 3,\n        'email': 'juani@gmail.com',\n        'estatus': 'Inactivo'\n    },\n    {\n        'id': 4,\n        'email': 'luquitas@gmail.com',\n        'estatus': 'Activo'\n    },\n    {\n        'id': 5,\n        'email': 'nico@gmail.com',\n        'estatus': 'Inactivo'\n    },\n    {\n        'id': 6,\n        'email': 'alma@gmail.com',\n        'estatus': 'Activo'\n    },\n]\n\n# Nombre de las columnas\ncolumnas = ['id', 'email', 'estatus']\n\n# Crea el fichero\nwith open(ruta_archivo, mode='w', newline='') as file:\n    documento = csv.DictWriter(file, delimiter=',', fieldnames=columnas)\n    documento.writeheader()\n    for dato in datos_usuario:\n        documento.writerow(dato)\n\nprint(f\"Archivo guardado en: {ruta_archivo}\")\n\n# Lista para guardar la información\ninfo = []\n\n# Lectura de fichero\nwith open(ruta_archivo, mode='r', newline='') as file:\n    documento = csv.DictReader(file, delimiter=',')\n    for fila in documento:\n        info.append([fila['id'], fila['email'], fila['estatus']])\n\n# Usuarios con estatus 'Activo'\nactivos = [usuario for usuario in info if usuario[2] == 'Activo']\n\n# Lista filtrada\nprint(\"Usuarios activos:\", activos)\n\n# Selección aleatoria de 3 usuarios activos sin repetición\nif len(activos) >= 3:\n    ganador1, ganador2, ganador3 = random.sample(activos, 3)\n\n    # Imprimir los ganadores\n    print(f\"ID ganador de la suscripción: {ganador1[0]} email: {ganador1[1]}\")\n    print(f\"ID ganador del descuento: {ganador2[0]} email: {ganador2[1]}\")\n    print(f\"ID ganador del libro: {ganador3[0]} email: {ganador3[1]}\")\nelse:\n    print(\"No hay suficientes usuarios activos para realizar el sorteo.\")\n"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/python/a-mayans.py",
    "content": "import csv\nimport random\n\n# Leer los datos del archivo CSV\ndef leer_datos_csv(archivo_csv):\n    with open(archivo_csv, mode='r') as file:\n        reader = csv.DictReader(file)\n        usuarios_activos = [row for row in reader if row['status'] == 'activo']\n    return usuarios_activos\n\n# Seleccionar ganadores aleatorios\ndef seleccionar_ganadores(usuarios):\n    if len(usuarios) < 3:\n        raise ValueError(\"No hay suficientes usuarios activos para seleccionar 3 ganadores.\")\n    \n    ganadores = random.sample(usuarios, 3)\n    \n    ganador_suscripcion = ganadores[0]\n    ganador_descuento = ganadores[1]\n    ganador_libro = ganadores[2]\n    \n    return {\n        \"suscripcion\": ganador_suscripcion,\n        \"descuento\": ganador_descuento,\n        \"libro\": ganador_libro\n    }\n\n# Mostrar ganadores\ndef mostrar_ganadores(ganadores):\n    print(\"Ganador de la suscripción:\")\n    print(f\"ID: {ganadores['suscripcion']['id']}, Email: {ganadores['suscripcion']['email']}\")\n    \n    print(\"\\nGanador del descuento:\")\n    print(f\"ID: {ganadores['descuento']['id']}, Email: {ganadores['descuento']['email']}\")\n    \n    print(\"\\nGanador del libro:\")\n    print(f\"ID: {ganadores['libro']['id']}, Email: {ganadores['libro']['email']}\")\n\n# Archivo CSV con usuarios\narchivo_csv = 'usuarios.csv'\n\n# Leer los datos del archivo CSV\nusuarios_activos = leer_datos_csv(archivo_csv)\n\n# Seleccionar ganadores aleatorios\nganadores = seleccionar_ganadores(usuarios_activos)\n\n# Mostrar los ganadores\nmostrar_ganadores(ganadores)"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/python/annaviper.py",
    "content": "import pandas as pd\n\n\ndef filter_active(df: pd.DataFrame) -> pd.DataFrame:\n    return df[df.status == 'active']\n\n\ndef choose_three_random_users(df: pd.DataFrame) -> pd.DataFrame:\n    return df[['id', 'email']].sample(n=3)\n\n\nif __name__ == \"__main__\":\n    df = pd.read_csv('users.csv')\n    active_users = filter_active(df)\n    winners = choose_three_random_users(active_users)\n    print(winners)\n"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/python/bereverte.py",
    "content": "import csv\nimport random\n\ndef seleccionar_activos(csvfile):\n\n    activos = []\n    emails_activos = []\n\n    with open(csvfile) as file:\n        csv_reader = csv.reader(file, delimiter=',')\n\n        next(csv_reader)    # saltar la cabecera\n\n        for row in csv_reader:\n            id, email, status = row\n            if status == \"activo\" and email not in emails_activos:\n                emails_activos.append(email)    # evitar correos duplicados\n                activos.append((id, email))     # añadir la tupla (id, email) de los usuarios activos\n\n    return activos\n\ndef seleccionar_ganadores(activos, cantidad_ganadores=3):\n    \n    if len(activos) >= cantidad_ganadores:\n        ganadores = random.sample(activos, cantidad_ganadores)  # seleccionar de manera aleatoria\n\n        ganador_suscripcion = ganadores[0]\n        ganador_descuento = ganadores[1]\n        ganador_libro = ganadores[2]\n\n        print(f\"\\nGanador/a de la suscripción:\")\n        print(f\"id: {ganador_suscripcion[0]}, email: {ganador_suscripcion[1]}\")\n        print(f\"\\nGanador/a del descuento:\")\n        print(f\"id: {ganador_descuento[0]}, email: {ganador_descuento[1]}\")\n        print(f\"\\nGanador/a del libro:\")\n        print(f\"id: {ganador_libro[0]}, email: {ganador_libro[1]}\")\n        return ganadores\n    \n    else:\n        print(\"No hay suficientes usuarios activos para seleccionar 3 ganadores.\")\n        return []\n\n\nif __name__ == '__main__':\n    \n    seleccionar_ganadores(activos=seleccionar_activos('registros.csv'))"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/python/cdryampi.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * He presentado mi proyecto más importante del año: mouredev pro.\n#  * Un campus para la comunidad, que lanzaré en octubre, donde estudiar\n#  * programación de una manera diferente.\n#  * Cualquier persona suscrita a la newsletter de https://mouredev.pro\n#  * accederá a sorteos mensuales de suscripciones, regalos y descuentos.\n#  *\n#  * Desarrolla un programa que lea los registros de un fichero .csv y\n#  * seleccione de manera aleatoria diferentes ganadores.\n#  * Requisitos:\n#  * 1. Crea un .csv con 3 columnas: id, email y status con valor \"activo\"\n#  *    o \"inactivo\" (y datos ficticios).\n#  *    Ejemplo: 1 | test@test.com | activo\n#  *             2 | test2@test.com | inactivo\n#  *    (El .csv no debe subirse como parte de la corrección)\n#  * 2. Recupera los datos desde el programa y selecciona email aleatorios.\n#  * Acciones:\n#  * 1. Accede al fichero .csv y selecciona de manera aleatoria un email\n#  *    ganador de una suscripción, otro ganador de un descuento y un último\n#  *    ganador de un libro (sólo si tiene status \"activo\" y no está repetido).\n#  * 2. Muestra los emails ganadores y su id.\n#  * 3. Ten en cuenta que la primera fila (con el nombre de las columnas)\n#  *    no debe tenerse en cuenta.\n#  */\nimport os.path\nimport csv\nimport uuid\nimport random\n\n\nclass Subscriptor():\n    \"\"\"\n        Clase que representa a un subscriptor.\n    \"\"\"\n    __headers = ['email', 'status','id']\n\n    def __init__(self,email: str, status: bool, id = uuid.uuid1()) -> None:\n        self.id = id\n        self.email = email\n        self.status = status\n    \n    def __str__(self) -> str:\n\n        estado  = \"activo\" if self.status  else \"inactivo\"\n\n        return f\"El subscritor {self.id} - {self.email} - {estado} \"\n\n    @classmethod\n    def get_headers(cls):\n        return cls.__headers\n\nclass CSVFile():\n    \"\"\"\n        Clase que representa a un CSV.\n    \"\"\"\n\n    __path_file = \"subscriptores.csv\"\n    __subscriptores = []\n\n    def __init__(self)-> None:\n\n        if self.check_file():\n            self.cargar_datos()\n        else:\n            self.crear_fichero()\n\n    def check_file(self)-> bool:\n        return True if os.path.isfile(self.__path_file) else False\n    \n    def add_subscriptor(self, subscriptor: Subscriptor)-> bool:\n        if any([value for value in self.__subscriptores if value.email == subscriptor.email]):\n            print(f'el subscriptor {subscriptor.email} ya existe por lo tanto no se añadirá.')\n            return False\n        self.__subscriptores.append(subscriptor)\n        return True\n\n    def cargar_datos(self)-> bool:\n        print(f\"Cargando fichero {self.__path_file}....\")\n        try:\n            self.__subscriptores = []\n            with open(self.__path_file, 'r', encoding='utf-8') as file:\n                reader = csv.DictReader(file)\n                for line in reader:\n                    status = True if line[Subscriptor.get_headers()[1]] == \"True\" else False\n                    subscriptor = Subscriptor(line[Subscriptor.get_headers()[0]], status , line[Subscriptor.get_headers()[2]])\n                    self.__subscriptores.append(subscriptor)\n\n        except Exception as e:\n            print(f\"No se ha podido cargar los datos {e}\")\n            print(\"Creando nuevo fichero....\")\n            self.crear_fichero()\n\n    def crear_fichero(self)-> bool:\n        try:\n            with open(self.__path_file, 'w', newline='', encoding='utf-8') as file:\n                writer = csv.DictWriter(file, fieldnames=Subscriptor.get_headers())\n                writer.writeheader()\n        except Exception as e:\n            print(f\"Ha habido un error al crear el fichero {e}\")\n            return False\n        return True\n\n    def guardar_datos(self)-> bool:\n\n        if len(self.__subscriptores) !=0:\n            try:\n                with open(self.__path_file, 'w', newline='', encoding='utf-8') as file:\n                    writer = csv.DictWriter(file, fieldnames=Subscriptor.get_headers())\n\n                    writer.writeheader()\n\n                    for subscriptor in self.__subscriptores:\n                        writer.writerow({\n                            'email': subscriptor.email,\n                            'status': subscriptor.status,\n                            'id': subscriptor.id\n                        })\n            except Exception as e:\n                print(f\"No se ha podido guardar los datos {e}\")\n                return False\n        else:\n            return False\n        \n        return True\n\n    def leer_datos(self)-> None:\n        if len(self.__subscriptores) !=0:\n\n            for subscriptor in self.__subscriptores:\n\n                print(subscriptor)\n\n    def generar_ganador(self) -> Subscriptor:\n        \n        return random.choice(self.__subscriptores)\n\n    def sorteo(self) -> None:\n        ganadores = []\n        def backtracking(ganadores_provicionales: list, indice: int):\n            if len(ganadores_provicionales) == 3:\n                ganadores.extend(ganadores_provicionales)\n                return\n            if indice >= len(self.__subscriptores):\n                return\n            \n            for i in range(indice, len(self.__subscriptores)):\n                subscriptor_random = random.choice(self.__subscriptores)\n                if subscriptor_random not in ganadores_provicionales and subscriptor_random.status:\n                    ganadores_provicionales.append(subscriptor_random)\n                    backtracking(ganadores_provicionales, i+1)\n                    if len(ganadores) == 3:\n                        return\n                    ganadores_provicionales.pop()\n\n        if len([subs for subs in self.__subscriptores if subs.status]) > 3:\n            backtracking([],0)\n\n            if len(ganadores) == 3:\n                print(f\"El ganador de la subscripción es: {ganadores[0]}\")\n                print(f\"El ganador del descuento es: {ganadores[1]}\")\n                print(f\"El ganador del libro es: {ganadores[2]}\")\n            else:\n                print(\"No se ha podido encontrar una combinación ganadora, intentalo otra vez.\")\n        else:\n            print(\"No tenemos suficientes subscriptores activos para hacer el sorteo.\")\n\n\ncsv_gestion = CSVFile()\n\nsubscriptor_1 = Subscriptor('sub10@gmail.com',True)\nsubscriptor_2 = Subscriptor('sub0@gmail.com',True)\nsubscriptor_3 = Subscriptor('sub2@gmail.com',False)\nsubscriptor_4 = Subscriptor('sub1@gmail.com',True)\nsubscriptor_5 = Subscriptor('sub3@gmail.com',False)\n\n\n\ncsv_gestion.add_subscriptor(subscriptor_1)\ncsv_gestion.add_subscriptor(subscriptor_2)\ncsv_gestion.add_subscriptor(subscriptor_3)\ncsv_gestion.add_subscriptor(subscriptor_4)\ncsv_gestion.add_subscriptor(subscriptor_5)\n\n\n\n# csv_gestion.guardar_datos()\n\n#csv_gestion.leer_datos()\ncsv_gestion.sorteo()"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/python/d1d4cum.py",
    "content": "import csv\nimport random\n\nPATH = './d1d4cum.csv'\n\ndef main():\n    active_users = []\n\n    with open(PATH, mode='r', newline='', encoding='utf-8') as file:\n        csv_reader = csv.reader(file)\n        next(csv_reader)\n\n        for row in csv_reader:\n            if row[2] == 'activo':\n                active_users.append(row)\n\n    print(\"> Ganador de la suscripción:\")\n    sus_winner = random.choice(active_users)\n    print(f\"{sus_winner[0]} - {sus_winner[1]}\")\n    active_users.remove(sus_winner)\n\n    print(\"> Ganador de un descuento:\")\n    dis_winner = random.choice(active_users)\n    print(f\"{dis_winner[0]} - {dis_winner[1]}\")\n    active_users.remove(dis_winner)\n\n    print(\"> Ganador de un libro:\")\n    book_winner = random.choice(active_users)\n    print(f\"{book_winner[0]} - {book_winner[1]}\")\n    active_users.remove(book_winner)\n\n\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/python/davidrguez98.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * He presentado mi proyecto más importante del año: mouredev pro.\n * Un campus para la comunidad, que lanzaré en octubre, donde estudiar\n * programación de una manera diferente.\n * Cualquier persona suscrita a la newsletter de https://mouredev.pro\n * accederá a sorteos mensuales de suscripciones, regalos y descuentos.\n *\n * Desarrolla un programa que lea los registros de un fichero .csv y\n * seleccione de manera aleatoria diferentes ganadores.\n * Requisitos:\n * 1. Crea un .csv con 3 columnas: id, email y status con valor \"activo\"\n *    o \"inactivo\" (y datos ficticios).\n *    Ejemplo: 1 | test@test.com | activo\n *             2 | test2@test.com | inactivo\n *    (El .csv no debe subirse como parte de la corrección)\n * 2. Recupera los datos desde el programa y selecciona email aleatorios.\n * Acciones:\n * 1. Accede al fichero .csv y selecciona de manera aleatoria un email\n *    ganador de una suscripción, otro ganador de un descuento y un último\n *    ganador de un libro (sólo si tiene status \"activo\" y no está repetido).\n * 2. Muestra los emails ganadores y su id.\n * 3. Ten en cuenta que la primera fila (con el nombre de las columnas)\n *    no debe tenerse en cuenta.\n */ \"\"\"\n\n#EJERCICIO\n\nimport os\nimport csv\nimport random\n\ndef read_csv_data() -> list:\n\n    file_dir = os.path.dirname(os.path.abspath(__file__))\n    csv_file = f\"{file_dir}/sub.csv\"\n\n    data = []\n\n    with open(csv_file, \"r\") as file:\n        reader = csv.DictReader(file)\n        for row in reader:\n            if row[\"status\"] == \"activo\":\n                data.append(row)\n    return data\n\ndef select_winners(data: list) -> list:\n\n    if len(data) < 3:\n        raise ValueError(\"El número de elementos debe de ser mínimo 3.\")\n    \n    return random.sample(data, 3)\n\ndef display_winners(winners):\n    prizes = [\"Suscripción\", \"Descuento\", \"Libro\"]\n    for winner, prizes in zip(winners, prizes):\n        print(f\"{prizes}: {winner[\"email\"]} (ID: {winner[\"id\"]})\")\n\ntry:\n    data = read_csv_data()\n    winners = select_winners(data)\n    display_winners(winners)\nexcept Exception as e:\n    print(e)"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/python/duendeintemporal.py",
    "content": "#38 { Retos para Programadores } MOUREDEV PRO \n\n# Bibliography reference:\n# I use GPT as a reference and sometimes to correct or generate proper comments.\n\n\"\"\"\n * EJERCICIO:\n * He presentado mi proyecto más importante del año: mouredev pro.\n * Un campus para la comunidad, que lanzaré en octubre, donde estudiar\n * programación de una manera diferente.\n * Cualquier persona suscrita a la newsletter de https://mouredev.pro\n * accederá a sorteos mensuales de suscripciones, regalos y descuentos.\n *\n * Desarrolla un programa que lea los registros de un fichero .csv y\n * seleccione de manera aleatoria diferentes ganadores.\n * Requisitos:\n * 1. Crea un .csv con 3 columnas: id, email y status con valor \"activo\"\n *    o \"inactivo\" (y datos ficticios).\n *    Ejemplo: 1 | test@test.com | activo\n *             2 | test2@test.com | inactivo\n *    (El .csv no debe subirse como parte de la corrección)\n * 2. Recupera los datos desde el programa y selecciona email aleatorios.\n * Acciones:\n * 1. Accede al fichero .csv y selecciona de manera aleatoria un email\n *    ganador de una suscripción, otro ganador de un descuento y un último\n *    ganador de un libro (sólo si tiene status \"activo\" y no está repetido).\n * 2. Muestra los emails ganadores y su id.\n * 3. Ten en cuenta que la primera fila (con el nombre de las columnas)\n *    no debe tenerse en cuenta.\n \"\"\"\n\n\"\"\"  Example of csv:\nid,email,status\n1,softbaby@hotmail.com,active\n2,psicotrogato@gmail.com,active\n3,coders@io.com,inactive\n4,chap_gtp@microsoft.com,active\n5,applesupport@mac.com,active\n6,someone@proton.me,inactive\n7,zeigest@movement.sw,active\n8,duendeintemporal@hotmail.com,active\n9,freelancer@developer.dev,inactivo\n10,crazycat@miau.miau,active\n\"\"\"\n\n\"\"\" In a console run the next comands:\nmkdir mouredev-pro\ncd mouredev-pro\nnpm init -y\nnpm install csv-parser\n\"\"\"\n\nlog = print\n\nimport csv\nimport random\n\n# Define a dictionary to hold the winners\nwinners = {\n    'subscription': None,\n    'discount': None,\n    'book': None\n}\n\nactive_emails = []\n\n# Read the CSV file\nwith open('subscribers.csv', mode='r') as file:\n    reader = csv.DictReader(file)\n    for row in reader:\n        if row['status'] == 'active':\n            active_emails.append({'id': row['id'], 'email': row['email']})\n\ndef select_winners():\n    # Shuffle the list of active emails\n    shuffled = random.sample(active_emails, len(active_emails))\n\n    # Select unique winners\n    winners['subscription'] = shuffled[0]\n    winners['discount'] = shuffled[1]\n    winners['book'] = shuffled[2]\n\ndef display_winners():\n    log('Winners:')\n    log(f\"Subscription: ID: {winners['subscription']['id']}, Email: {winners['subscription']['email']}\")\n    log(f\"Discount: ID: {winners['discount']['id']}, Email: {winners['discount']['email']}\")\n    log(f\"Book: ID: {winners['book']['id']}, Email: {winners['book']['email']}\")\n\n# Select winners and display them\nselect_winners()\ndisplay_winners()\n\n\n\"\"\"\nPossible Output: \n\nWinners:\nSubscription: ID: 10, Email: crazycat@miau.miau\nDiscount: ID: 7, Email: zeigest@movement.sw\nBook: ID: 5, Email: applesupport@mac.com\n\n\"\"\"\n\n\n"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/python/hectorio23.py",
    "content": "# Autor: Héctor Adán\n# GitHub: https://github.com/hectorio23\n\nimport csv\nimport random\n\ndef leer_csv(filename):\n    with open(filename, newline='') as csvfile:\n        reader = csv.DictReader(csvfile)\n        # Filtrar solo los registros con status \"activo\"\n        activos = [row for row in reader if row['status'] == 'activo']\n    return activos\n\ndef seleccionar_ganadores(participantes):\n    # Evitar que un participante gane más de una vez\n    ganadores = random.sample(participantes, 3)\n    \n    suscripcion = ganadores[0]\n    descuento = ganadores[1]\n    libro = ganadores[2]\n    \n    print(f\"Ganador de suscripción: ID {suscripcion['id']} | Email: {suscripcion['email']}\")\n    print(f\"Ganador de descuento: ID {descuento['id']} | Email: {descuento['email']}\")\n    print(f\"Ganador de libro: ID {libro['id']} | Email: {libro['email']}\")\n\nif __name__ == \"__main__\":\n    participantes_activos = leer_csv('suscriptores.csv')\n    if len(participantes_activos) < 3:\n        print(\"No hay suficientes participantes activos para seleccionar 3 ganadores.\")\n    else:\n        seleccionar_ganadores(participantes_activos)\n"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/python/hozlucas28.py",
    "content": "# pylint: disable=missing-module-docstring,missing-function-docstring,expression-not-assigned,redefined-outer-name\n\nfrom typing import TypedDict, Literal\nimport csv\nimport os\nimport random\n\n\n# ---------------------------------------------------------------------------- #\n#                                   FUNCTIONS                                  #\n# ---------------------------------------------------------------------------- #\n\n\ndef create_csv(*, content: list[list[str]], path: str) -> None:\n    if os.path.exists(path=path):\n        os.remove(path=path)\n\n    with open(file=path, mode=\"x\", encoding=\"utf8\") as file:\n        writer = csv.writer(file, delimiter=\",\", lineterminator=\"\\n\")\n\n        for row in content:\n            writer.writerow(row)\n\n\ndef get_csv_content(*, path: str) -> list[dict[str, str]]:\n    csv_content: list[list[str]] = []\n\n    with open(file=path, mode=\"r\", encoding=\"utf8\") as file:\n        reader = csv.reader(file, delimiter=\",\")\n\n        for row in reader:\n            csv_content.append(row)\n\n    csv_content_fmt: list[dict[str, str]] = []\n\n    for row in csv_content[1:]:\n        row_fmt: dict[str, str] = {}\n\n        for i, col in enumerate(iterable=row):\n            row_fmt[csv_content[0][i]] = col\n\n        csv_content_fmt.append(row_fmt)\n\n    return csv_content_fmt\n\n\n# ---------------------------------------------------------------------------- #\n#                                     MAIN                                     #\n# ---------------------------------------------------------------------------- #\n\n\ntype Status = Literal[\"active\"] | Literal[\"inactive\"]\n\nUser = TypedDict(\n    \"User\",\n    {\n        \"id\": int,\n        \"email\": str,\n        \"status\": Status,\n    },\n)\n\nusers: list[User] = [\n    {\n        \"email\": \"test01@gmail.com\",\n        \"id\": 1,\n        \"status\": \"active\",\n    },\n    {\n        \"email\": \"test02@gmail.com\",\n        \"id\": 2,\n        \"status\": \"inactive\",\n    },\n    {\n        \"email\": \"test03@gmail.com\",\n        \"id\": 3,\n        \"status\": \"inactive\",\n    },\n    {\n        \"email\": \"test04@gmail.com\",\n        \"id\": 4,\n        \"status\": \"active\",\n    },\n    {\n        \"email\": \"test05@gmail.com\",\n        \"id\": 5,\n        \"status\": \"inactive\",\n    },\n    {\n        \"email\": \"test06@gmail.com\",\n        \"id\": 6,\n        \"status\": \"active\",\n    },\n    {\n        \"email\": \"test07@gmail.com\",\n        \"id\": 7,\n        \"status\": \"active\",\n    },\n    {\n        \"email\": \"test08@gmail.com\",\n        \"id\": 8,\n        \"status\": \"active\",\n    },\n]\n\ncsvContent: list[list[str]] = [\n    list(users[0].keys()),\n]\n\nfor user in users:\n    csvContent.append([str(object=user.get(key)) for key in list(users[0].keys())])\n\ncreate_csv(content=csvContent, path=\"./users.csv\")\n\ncsvUsers: list[dict[str, str]] = get_csv_content(path=\"./users.csv\")\n\nactiveUsers: list[dict[str, str]] = list(\n    filter(lambda user: user[\"status\"] == \"active\", csvUsers)\n)\n\nwinners: list[dict[str, str]] = random.sample(population=activeUsers, k=3)\n\nprint(\"> The first winner is...\")\nprint(\n    f\"> Congratulations {winners[0]['email']} with id {winners[0]['id']}, you won a subscription!\"\n)\n\nprint(\"\\n> The second winner is...\")\nprint(\n    f\"> Congratulations {winners[1]['email']} with id {winners[1]['id']}, you won a discount!\"\n)\n\nprint(\"\\n> The third winner is...\")\nprint(\n    f\"> Congratulations {winners[2]['email']} with id {winners[2]['id']}, you won a book!\"\n)\n"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/python/idiegorojas.py",
    "content": "\"\"\" # 38 - Mouredev Pro  \"\"\"\n\n# Desarrolla un programa que lea los registros de un fichero .csv y seleccione de manera aleatoria diferentes ganadores.\n\n\"\"\"\nRequisitos:\n\"\"\"\n# 1. Crea un .csv con 3 columnas: id, email y status con valor \"activo\" o \"inactivo\" (y datos ficticios).\n    # Ejemplo: 1 | test@test.com | activo\n    # 2 | test2@test.com | inactivo\n    # (El .csv no debe subirse como parte de la corrección)\n# 2. Recupera los datos desde el programa y selecciona email aleatorios.\n\n\"\"\"\nAcciones: \n\"\"\"\n# 1. Accede al fichero .csv y selecciona de manera aleatoria un email\n    # ganador de una suscripción, otro ganador de un descuento y un último\n    # ganador de un libro (sólo si tiene status \"activo\" y no está repetido).\n# 2. Muestra los emails ganadores y su id.\n# 3. Ten en cuenta que la primera fila (con el nombre de las columnas) no debe tenerse en cuenta.\n\n\n\nimport csv\nimport random\n\ndef select_winners(csv_file):\n    \"\"\"\n    Selecciona ganadores aleatorios de un archivo CSV.\n    \"\"\"\n    # Lista para almacenar usuarios activos\n    active_users = []\n    \n    # Leer el archivo CSV\n    with open(csv_file, 'r') as file:\n        reader = csv.reader(file)\n        next(reader)  # Saltamos la primera fila (cabecera)\n        \n        for row in reader:\n            if len(row) >= 3 and row[2].lower() == 'true':\n                active_users.append({\"id\": row[0], \"email\": row[1]})\n    \n    # Verificar si hay suficientes usuarios activos\n    if len(active_users) < 3:\n        print(\"No hay suficientes usuarios activos para seleccionar 3 ganadores.\")\n        return\n    \n    # Seleccionar ganadores aleatorios sin repetición\n    winners = random.sample(active_users, 3)\n    \n    # Mostrar los ganadores\n    prizes = [\"suscripción\", \"descuento\", \"libro\"]\n    \n    print(\"\\n=== GANADORES ===\")\n    for i, winner in enumerate(winners):\n        print(f\"Ganador de {prizes[i]}:\")\n        print(f\"ID: {winner['id']}, Email: {winner['email']}\")\n\n# Ruta del archivo CSV\ncsv_file = \"users.csv\"\n\n# Ejecutar el programa\ntry:\n    select_winners(csv_file)\nexcept FileNotFoundError:\n    print(f\"Error: No se encontró el archivo '{csv_file}'.\")\n    print(\"Primero debes crear el archivo CSV con los datos requeridos.\")\nexcept Exception as e:\n    print(f\"Error: {e}\")"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/python/ignaciovihe.py",
    "content": "\"\"\"\n * He presentado mi proyecto más importante del año: mouredev pro.\n * Un campus para la comunidad, que lanzaré en octubre, donde estudiar\n * programación de una manera diferente.\n * Cualquier persona suscrita a la newsletter de https://mouredev.pro\n * accederá a sorteos mensuales de suscripciones, regalos y descuentos.\n *\n * Desarrolla un programa que lea los registros de un fichero .csv y\n * seleccione de manera aleatoria diferentes ganadores.\n * Requisitos:\n * 1. Crea un .csv con 3 columnas: id, email y status con valor \"activo\"\n *    o \"inactivo\" (y datos ficticios).\n *    Ejemplo: 1 | test@test.com | activo\n *             2 | test2@test.com | inactivo\n *    (El .csv no debe subirse como parte de la corrección)\n * 2. Recupera los datos desde el programa y selecciona email aleatorios.\n * Acciones:\n * 1. Accede al fichero .csv y selecciona de manera aleatoria un email\n *    ganador de una suscripción, otro ganador de un descuento y un último\n *    ganador de un libro (sólo si tiene status \"activo\" y no está repetido).\n * 2. Muestra los emails ganadores y su id.\n * 3. Ten en cuenta que la primera fila (con el nombre de las columnas)\n *    no debe tenerse en cuenta.\n\"\"\"\n\nimport csv\nimport random\nimport os\n\n\nusers = [\n    [1 , \"pedro@test.com\" , \"activo\"],\n    [2 , \"juan@test.com\" , \"activo\"],\n    [3 , \"carlos@test.com\" , \"activo\"],\n    [4 , \"rodrigo@test.com\" , \"activo\"],\n    [5 , \"palomana@test.com\" , \"activo\"],\n    [6 , \"carmen@test.com\" , \"inactivo\"],\n    [7 , \"maria@test.com\" , \"activo\"],\n    [8 , \"teresa@test.com\" , \"inactivo\"],\n    [9 , \"susanat@test.com\" , \"activo\"],\n    [10 , \"manuel@test.com\" , \"activo\"],\n]\n\n\nfile_dir = os.path.dirname(os.path.abspath(__file__))\nfile_name = f\"{file_dir}/subs.csv\"\n\ndef create_csv(f_name):\n    with open(f_name, \"w\", newline=\"\", encoding=\"utf-8\") as archivo:\n        writer = csv.writer(archivo)\n        writer.writerow([\"id\", \"email\", \"estado\"])\n        writer.writerows(users)\n\ndef get_participants(f_name):\n    subs = []\n    with open(f_name, \"r\", newline='', encoding='utf-8') as archivo:\n        reader = csv.DictReader(archivo)\n        for fila in reader:\n            if fila[\"estado\"] == \"activo\":\n                subs.append(fila)\n    return subs\n\ndef get_winners(data: list):\n    if len(data) >=3:\n        return random.sample(data, 3)\n    else:\n        raise ValueError(\"El número de participantes debe ser minimo 3\")\n\ndef print_winners(data: list):\n    \n    prizes = [\"suscripción\", \"descuebto\", \"libro\"]\n    print(\"GANADORES DE LOS PREMIOS\")\n    for prize , winner in zip(prizes, data):\n        print(f\"Premio: {prize} - Ganador: (ID:{winner[\"id\"]}) - {winner[\"email\"]}\")\n\ntry:\n    create_csv(file_name)\n    participants = get_participants(file_name)\n    winners = get_winners(participants)\n    print_winners(winners)\nexcept Exception as e:\n    print(e)\n"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/python/javierfiestasbotella.py",
    "content": "'''\n/*\n * EJERCICIO:\n * He presentado mi proyecto más importante del año: mouredev pro.\n * Un campus para la comunidad, que lanzaré en octubre, donde estudiar\n * programación de una manera diferente.\n * Cualquier persona suscrita a la newsletter de https://mouredev.pro\n * accederá a sorteos mensuales de suscripciones, regalos y descuentos.\n *\n * Desarrolla un programa que lea los registros de un fichero .csv y\n * seleccione de manera aleatoria diferentes ganadores.\n * Requisitos:\n * 1. Crea un .csv con 3 columnas: id, email y status con valor \"activo\"\n *    o \"inactivo\" (y datos ficticios).\n *    Ejemplo: 1 | test@test.com | activo\n *             2 | test2@test.com | inactivo\n *    (El .csv no debe subirse como parte de la corrección)\n * 2. Recupera los datos desde el programa y selecciona email aleatorios.\n * Acciones:\n * 1. Accede al fichero .csv y selecciona de manera aleatoria un email\n *    ganador de una suscripción, otro ganador de un descuento y un último\n *    ganador de un libro (sólo si tiene status \"activo\" y no está repetido).\n * 2. Muestra los emails ganadores y su id.\n * 3. Ten en cuenta que la primera fila (con el nombre de las columnas)\n *    no debe tenerse en cuenta.\n */'''\nimport pandas as pd\nimport random\n\ndf = pd.read_csv('csv.csv')\nlista = []\n\nfor index, row in df.iterrows():\n    if row['status'] == 'activo':\n        lista.append([row['id'], row['email']])\n\nprint(lista)\n\npremios = []\n\nfor _ in range(3):\n    p = random.choice(lista)\n    premios.append(p)\n    lista = [x for x in lista if x != p]  \nprint(f'''\nGanador de una suscripción --> ID: {premios[0][0]}, Email: {premios[0][1]}\nGanador de un descuento --> ID: {premios[1][0]}, Email: {premios[1][1]}\nGanador de un libro --> ID: {premios[2][0]}, Email: {premios[2][1]}\n''')\n"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/python/juamax2.py",
    "content": "import os\nimport csv\nimport random\n\ndef read_csv() -> list:\n    \n    file_dir = os.path.dirname(os.path.abspath(__file__))\n    csv_file = f\"{file_dir}/subs.csv\"\n    \n    data = []\n    \n    with open(csv_file, mode=\"r\") as file:\n        reader = csv.DictReader(file)\n        \n        for row in reader:\n            if row[\"status\"] == \"Activo\":\n                data.append(row)\n    return data\n\ndef seleccionar_ganadores(data):\n    \n    if len(data) < 3:\n        raise ValueError(\"El número de elementos debe ser mínimo 3.\")\n    return random.sample(data, 3)\n    \n\ndef mostrar_ganadores(winners):\n    premios = [\"Suscripción\", \"Descuento\", \"Libro\"]\n    for winner, premio in zip(winners, premios):\n        print(f\"{winner[\"email\"]} ID: {winner[\"id\"]}. Premio: {premio}\")\n    \ntry:   \n    data = read_csv()\n    winners = seleccionar_ganadores(data)\n    mostrar_ganadores(winners)\nexcept Exception as e:\n    print({e})"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/python/juanmjimenezs.py",
    "content": "\"\"\"\n * EJERCICIO:\n * He presentado mi proyecto más importante del año: mouredev pro.\n * Un campus para la comunidad, que lanzaré en octubre, donde estudiar\n * programación de una manera diferente.\n * Cualquier persona suscrita a la newsletter de https://mouredev.pro\n * accederá a sorteos mensuales de suscripciones, regalos y descuentos.\n *\n * Desarrolla un programa que lea los registros de un fichero .csv y\n * seleccione de manera aleatoria diferentes ganadores.\n * Requisitos:\n * 1. Crea un .csv con 3 columnas: id, email y status con valor \"activo\"\n *    o \"inactivo\" (y datos ficticios).\n *    Ejemplo: 1 | test@test.com | activo\n *             2 | test2@test.com | inactivo\n *    (El .csv no debe subirse como parte de la corrección)\n * 2. Recupera los datos desde el programa y selecciona email aleatorios.\n * Acciones:\n * 1. Accede al fichero .csv y selecciona de manera aleatoria un email\n *    ganador de una suscripción, otro ganador de un descuento y un último\n *    ganador de un libro (sólo si tiene status \"activo\" y no está repetido).\n * 2. Muestra los emails ganadores y su id.\n * 3. Ten en cuenta que la primera fila (con el nombre de las columnas)\n *    no debe tenerse en cuenta.\n\"\"\"\nimport csv\nimport random\n\ndef get_data_from_csv(file_name):\n    \"\"\"Method to get data from csv file\"\"\"\n    data = []\n    with open(file_name, 'r', encoding=\"utf-8\", newline='') as csvfile:\n        csv_reader = csv.reader(csvfile)\n        next(csv_reader)  # Skip the header row\n        for row in csv_reader:\n            if row[2] == 'activo':\n                data.append(row)\n    return data\n\n\ndef get_random_winners(data):\n    \"\"\"Method to get random winners\"\"\"\n    used_numbers = []\n    winners = []\n    # Winner 1\n    random_number = get_unique_random_number(len(data)-1, used_numbers)\n    winners.append(data[random_number])\n    # Winner 2\n    random_number = get_unique_random_number(len(data)-1, used_numbers)\n    winners.append(data[random_number])\n    # Winner 3\n    random_number = get_unique_random_number(len(data)-1, used_numbers)\n    winners.append(data[random_number])\n    return winners\n\n\ndef print_winners(winners):\n    \"\"\"Method to print winners\"\"\"\n    prizes = ['Suscripción', 'Descuento', 'Libro']\n    for i, winner in enumerate(winners):\n        print(f\"Ganador {prizes[i]} -> Id: {winner[0]}, Email: {winner[1]}\")\n\n\ndef get_unique_random_number(max_number, used_numbers):\n    \"\"\"Method to get unique random number\"\"\"\n    random_number = random.randint(0, max_number)\n    while random_number in used_numbers:\n        random_number = random.randint(0, max_number)\n    used_numbers.append(random_number)\n    return random_number\n\n\n# import os\n# print(os.getcwd())\ncsv_data = get_data_from_csv('38/mouredev38.csv')\n# print(csv_data)\nchosen = get_random_winners(csv_data)\nprint_winners(chosen)\n"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/python/kenysdev.py",
    "content": "# _____________________________________\n# https://github.com/kenysdev\n# 2024 - Python\n# _____________________________________\n# 38 MOUREDEV PRO\n# ------------------------------------\n\"\"\"\n * He presentado mi proyecto más importante del año: mouredev pro.\n * Un campus para la comunidad, que lanzaré en octubre, donde estudiar\n * programación de una manera diferente.\n * Cualquier persona suscrita a la newsletter de https://mouredev.pro\n * accederá a sorteos mensuales de suscripciones, regalos y descuentos.\n *\n * Desarrolla un programa que lea los registros de un fichero .csv y\n * seleccione de manera aleatoria diferentes ganadores.\n * Requisitos:\n * 1. Crea un .csv con 3 columnas: id, email y status con valor \"activo\"\n *    o \"inactivo\" (y datos ficticios).\n *    Ejemplo: 1 | test@test.com | activo\n *             2 | test2@test.com | inactivo\n *    (El .csv no debe subirse como parte de la corrección)\n * 2. Recupera los datos desde el programa y selecciona email aleatorios.\n * Acciones:\n * 1. Accede al fichero .csv y selecciona de manera aleatoria un email\n *    ganador de una suscripción, otro ganador de un descuento y un último\n *    ganador de un libro (sólo si tiene status \"activo\" y no está repetido).\n * 2. Muestra los emails ganadores y su id.\n * 3. Ten en cuenta que la primera fila (con el nombre de las columnas)\n *    no debe tenerse en cuenta.\n\"\"\"\n\nimport csv\nimport random\nfrom typing import Optional\n\ndef read_csv(file_path) -> Optional[list]:\n    try:\n        with open(file_path, 'r') as file:\n            reader = csv.DictReader(file)\n            return list(reader)\n    except Exception as e:\n        print(f\"Error reading '{file_path}': {e}\")\n        return None\n\ndef get_active_entries(entries) -> list:\n    active_entries = []\n    \n    for entry in entries:\n        if entry['status'].lower() == \"active\":\n            active_entry = {\n                'id': entry['id'],\n                'email': entry['email'],\n                'status': entry['status']\n            }\n            active_entries.append(active_entry)\n    \n    return active_entries\n\ndef select_winners(active_entries, num_winners) -> list:\n    return random.sample(active_entries, min(num_winners, len(active_entries)))\n\ndef distribute_prizes(winners, prizes):\n    random.shuffle(prizes)\n    for winner, prize in zip(winners, prizes):\n        print(f\"{prize:<11} -> Id({winner['id']}): {winner['email']}\")\n\nif __name__ == \"__main__\":\n    print(\"Usuarios ganadores de 'MOUREDEV PRO:'\")\n    csv_file = 'users.csv'\n    prizes = [\"Suscripción\", \"Descuento\", \"Libro\"]\n    \n    entries = read_csv(csv_file)\n    if entries:\n        active_entries = get_active_entries(entries)\n        winners = select_winners(active_entries, 3)\n        distribute_prizes(winners, prizes)\n\n    else:\n        print(\"No se encontraron entradas activas.\")\n\n"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/python/mhayhem.py",
    "content": "# @Author Daniel Grande (Mhayhem)\n\nimport csv\nimport random\n\n# EJERCICIO:\n# He presentado mi proyecto más importante del año: mouredev pro.\n# Un campus para la comunidad, que lanzaré en octubre, donde estudiar\n# programación de una manera diferente.\n# Cualquier persona suscrita a la newsletter de https://mouredev.pro\n# accederá a sorteos mensuales de suscripciones, regalos y descuentos.\n#\n# Desarrolla un programa que lea los registros de un fichero .csv y\n# seleccione de manera aleatoria diferentes ganadores.\n# Requisitos:\n# 1. Crea un .csv con 3 columnas: id, email y status con valor \"activo\"\n#    o \"inactivo\" (y datos ficticios).\n#    Ejemplo: 1 | test@test.com | activo\n#             2 | test2@test.com | inactivo\n#    (El .csv no debe subirse como parte de la corrección)\n# 2. Recupera los datos desde el programa y selecciona email aleatorios.\n# Acciones:\n# 1. Accede al fichero .csv y selecciona de manera aleatoria un email\n#    ganador de una suscripción, otro ganador de un descuento y un último\n#    ganador de un libro (sólo si tiene status \"activo\" y no está repetido).\n# 2. Muestra los emails ganadores y su id.\n# 3. Ten en cuenta que la primera fila (con el nombre de las columnas)\n#    no debe tenerse en cuenta.\n\n\ndef get_info_csv(path: str):\n    active_users = []\n    with open(path, newline=\"\", encoding=\"utf-8\") as file:\n        reader = csv.DictReader(file)\n    \n        for row in reader:\n            if row[\"status\"].lower() == \"active\":\n                active_users.append(row)\n    \n    return active_users\n\ndef lottery(array: list):\n    if len(array) < 3:\n        print(\"No hay suficientes subscriptores para el sorteo.\")\n        return\n    \n    winners = random.sample(array, 3)\n    annual_subscribe = winners[0]\n    discount = winners[1]\n    book = winners[2]\n    \n    print(f\"El correo {annual_subscribe['email']} con ID {annual_subscribe[\"id\"]}, ha ganado una subscripcion a Mouredev.pro.\")\n    print(f\"El correo {discount['email']} con ID {discount[\"id\"]}, ha ganado un descuento del 15%.\")\n    print(f\"El correo {book['email']} con ID {book[\"id\"]}, ha ganado el libro de Brais Moure\")\n\ndef main():\n    array = get_info_csv(path)\n    lottery(array)\n\nif __name__==\"__main__\":\n    main()"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/python/miguelex.py",
    "content": "import csv\nimport random\n\ndef obtener_suscriptores_activos(archivo_csv):\n    suscriptores = []\n    with open(archivo_csv, newline='') as csvfile:\n        reader = csv.reader(csvfile)\n        next(reader)  \n        for row in reader:\n            id_, email, status = row\n            if status.strip().lower() == 'activo':\n                suscriptores.append({'id': id_.strip(), 'email': email.strip()})\n    return suscriptores\n\ndef seleccionar_ganadores(suscriptores, numero_ganadores):\n    if len(suscriptores) < numero_ganadores:\n        return None  \n    return random.sample(suscriptores, numero_ganadores)\n\narchivo_csv = 'suscriptores.csv'\n\nsuscriptores_activos = obtener_suscriptores_activos(archivo_csv)\n\nif suscriptores_activos:\n    ganadores = seleccionar_ganadores(suscriptores_activos, 3)\n    if ganadores:\n        print(f\"Ganador de la suscripción: {ganadores[0]}\")\n        print(f\"Ganador del descuento: {ganadores[1]}\")\n        print(f\"Ganador del libro: {ganadores[2]}\")\n    else:\n        print(\"No hay suficientes suscriptores activos para seleccionar 3 ganadores.\")\nelse:\n    print(\"No hay suscriptores activos.\")\n"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/python/mmariob.py",
    "content": "import csv\nimport random\n\n# Creo lista para guardar los datos del csv\nresults = []\n\n# Leo el csv\nwith open('data.csv', 'r', newline='') as File:\n    reader = csv.DictReader(File)\n    for row in reader:\n        results.append(row)\n\n# Función para seleccionar un ganador aleatorio y eliminarlo de la lista\ndef seleccionar_ganador(lista):\n    if not lista:\n        return None\n    indice = random.randint(0, len(lista) - 1)\n    return lista.pop(indice)\n\n# Ganador de suscripción\nganador_sub = seleccionar_ganador(results)\nif ganador_sub:\n    print(f\"El ganador de la suscripción es: {ganador_sub['email']}\")\nelse:\n    print(\"No hay participantes para la suscripción\")\n\n# Ganador de descuento\nganador_des = seleccionar_ganador(results)\nif ganador_des:\n    print(f\"El ganador del descuento es: {ganador_des['email']}\")\nelse:\n    print(\"No hay participantes para el descuento\")\n\n# Ganador del libro (solo si es activo)\nganador_libro = None\nwhile results and not ganador_libro:\n    posible_ganador = seleccionar_ganador(results)\n    if posible_ganador['status'] == 'activo':\n        ganador_libro = posible_ganador\n        print(f\"El ganador del libro es: {ganador_libro['email']}\")\n    else:\n        print(f\"El participante {posible_ganador['email']} no es elegible para el libro (inactivo)\")\n\nif not ganador_libro:\n    print(\"No se encontró un ganador activo para el libro\")\n\n# Imprimir participantes restantes\nprint(f\"\\nParticipantes restantes: {len(results)}\")\nfor participante in results:\n    print(f\"ID: {participante['id']}, Email: {participante['email']}, Status: {participante['status']}\")"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/python/mouredev.py",
    "content": "import os\nimport csv\nimport random\n\n\ndef read_csv_data() -> list:\n\n    file_dir = os.path.dirname(os.path.abspath(__file__))\n    csv_file = f\"{file_dir}/subs.csv\"\n\n    data = []\n\n    with open(csv_file, mode=\"r\") as file:\n        reader = csv.DictReader(file)\n        for row in reader:\n            if row[\"status\"] == \"activo\":\n                data.append(row)\n\n    return data\n\n\ndef select_winners(data: list) -> list:\n\n    if len(data) < 3:\n        raise ValueError(\"El número de elementos debe ser mínimo 3.\")\n\n    return random.sample(data, 3)\n\n\ndef display_winners(winners):\n    prizes = [\"Suscripción\", \"Descuento\", \"Libro\"]\n    for winner, prize in zip(winners, prizes):\n        print(f\"{prize}: {winner[\"email\"]} (ID: {winner[\"id\"]})\")\n\n\ntry:\n    data = read_csv_data()\n    winners = select_winners(data)\n    display_winners(winners)\nexcept Exception as e:\n    print(e)\n"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/python/neslarra.py",
    "content": "\"\"\"\n EJERCICIO:\n He presentado mi proyecto más importante del año: mouredev pro.\n Un campus para la comunidad, que lanzaré en octubre, donde estudiar\n programación de una manera diferente.\n Cualquier persona suscrita a la newsletter de https://mouredev.pro\n accederá a sorteos mensuales de suscripciones, regalos y descuentos.\n\n Desarrolla un programa que lea los registros de un fichero .csv y\n seleccione de manera aleatoria diferentes ganadores.\n Requisitos:\n 1. Crea un .csv con 3 columnas: id, email y status con valor \"activo\"\n    o \"inactivo\" (y datos ficticios).\n    Ejemplo: 1 | test@test.com | activo\n             2 | test2@test.com | inactivo\n    (El .csv no debe subirse como parte de la corrección)\n 2. Recupera los datos desde el programa y selecciona email aleatorios.\n Acciones:\n 1. Accede al fichero .csv y selecciona de manera aleatoria un email\n    ganador de una suscripción, otro ganador de un descuento y un último\n    ganador de un libro (sólo si tiene status \"activo\" y no está repetido).\n 2. Muestra los emails ganadores y su id.\n 3. Ten en cuenta que la primera fila (con el nombre de las columnas)\n    no debe tenerse en cuenta.\n\"\"\"\nimport csv\nfrom os import remove\nfrom random import randint\n\n\ndef create_csv():\n    users = [\n        {\"id\": 1, \"email\": \"tito@gmail.com\", \"status\": 0},\n        {\"id\": 2, \"email\": \"pepe@gmail.com\", \"status\": 0},\n        {\"id\": 3, \"email\": \"salo@gmail.com\", \"status\": 1},\n        {\"id\": 4, \"email\": \"tula@gmail.com\", \"status\": 1},\n        {\"id\": 5, \"email\": \"tilo@gmail.com\", \"status\": 1},\n        {\"id\": 6, \"email\": \"pipa@gmail.com\", \"status\": 1},\n        {\"id\": 7, \"email\": \"toto@gmail.com\", \"status\": 0},\n        {\"id\": 8, \"email\": \"calo@gmail.com\", \"status\": 0},\n        {\"id\": 9, \"email\": \"tolo@gmail.com\", \"status\": 0},\n        {\"id\": 10, \"email\": \"pepo@gmail.com\", \"status\": 1},\n        {\"id\": 11, \"email\": \"sali@gmail.com\", \"status\": 1},\n        {\"id\": 12, \"email\": \"chino@gmail.com\", \"status\": 0},\n        {\"id\": 13, \"email\": \"chona@gmail.com\", \"status\": 1},\n        {\"id\": 14, \"email\": \"tano@gmail.com\", \"status\": 0},\n        {\"id\": 15, \"email\": \"tina@gmail.com\", \"status\": 1},\n    ]\n\n    with open(\"reto_38_neslarra.csv\", \"w\", newline=\"\") as fichero:\n        writer = csv.writer(fichero, delimiter=\",\")\n        writer.writerow([\"id\", \"email\", \"status\"])\n        for line in users:\n            writer.writerow([line[\"id\"], line[\"email\"], line[\"status\"]])\n\n\ndef read_csv():\n    users = []\n    with open(\"reto_38_neslarra.csv\", \"r\") as fichero:\n        reader = csv.reader(fichero, delimiter=\",\")\n        for row in reader:\n            if reader.line_num == 1:\n                headers = row\n                continue\n            users.append({headers[0]: row[0], headers[1]: row[1], headers[2]: row[2]})\n    return users\n\n\ndef remove_csv():\n    remove(\"reto_38_neslarra.csv\")\n\n\ncreate_csv()\n\nusers = read_csv()\nactive_users = [x for x in users if x[\"status\"] == \"1\"]              # status 1 = ACTIVO / status 0 = INACTIVO\n\nganador_suscripcion = active_users.pop(randint(0, active_users.__len__() - 1))\nprint(f\"El ganador de la suscripción es {ganador_suscripcion['email']}\")\n\nganador_libro = active_users.pop(randint(0, active_users.__len__() - 1))\nprint(f\"El ganador del libro es {ganador_libro['email']}\")\n\nganador_descuento = active_users.pop(randint(0, active_users.__len__() - 1))\nprint(f\"El ganador del descuento es {ganador_descuento['email']}\")\n\nremove_csv()\n"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/python/oriaj3.py",
    "content": "\"\"\"\n * EJERCICIO:\n * He presentado mi proyecto más importante del año: mouredev pro.\n * Un campus para la comunidad, que lanzaré en octubre, donde estudiar\n * programación de una manera diferente.\n * Cualquier persona suscrita a la newsletter de https://mouredev.pro\n * accederá a sorteos mensuales de suscripciones, regalos y descuentos.\n *\n * Desarrolla un programa que lea los registros de un fichero .csv y\n * seleccione de manera aleatoria diferentes ganadores.\n * Requisitos:\n * 1. Crea un .csv con 3 columnas: id, email y status con valor \"activo\"\n *    o \"inactivo\" (y datos ficticios).\n *    Ejemplo: 1 | test@test.com | activo\n *             2 | test2@test.com | inactivo\n *    (El .csv no debe subirse como parte de la corrección)\n * 2. Recupera los datos desde el programa y selecciona email aleatorios.\n * Acciones:\n * 1. Accede al fichero .csv y selecciona de manera aleatoria un email\n *    ganador de una suscripción, otro ganador de un descuento y un último\n *    ganador de un libro (sólo si tiene status \"activo\" y no está repetido).\n * 2. Muestra los emails ganadores y su id.\n * 3. Ten en cuenta que la primera fila (con el nombre de las columnas)\n *    no debe tenerse en cuenta.\n */\n\"\"\"\t\n\nimport csv\nimport random\n\n#Introduce la url del archivo\nPATH_CSV_FILE = \"D:\\\\Desarrollo\\\\roadmap-retos-programacion\\\\Roadmap\\\\38 - MOUREDEV PRO\\\\python\\\\concurso.csv\"\n\n#Abrir el archivo\ndef open_csv(file):\n    with open (file, newline='') as csvfile:\n        reader = csv.reader(csvfile, delimiter='|')\n        #Borra la primera fila\n        next(reader)\n        #ID, email, status\n        listdata = list(reader)\n        #Diccionario para almacenar los datos\n        data = {}\n        for row in listdata[1:]:\n            id = row[0]\n            email = row[1]\n            status = row[2]\n            data[id] = {\"email\": email, \"status\": status}\n        return data\n    \ndef select_winners(data):\n    winners = {\"subscription\": None, \"discount\": None, \"book\": None}\n    set_winners = set()\n    while len(set_winners) < 3:\n        if len(set_winners) == 0:\n            winner = random.choice(list(data.keys()))\n            if winner not in set_winners:\n                winners[\"subscription\"] = data[winner][\"email\"]\n                set_winners.add(winner)\n        \n        elif len(set_winners) == 1:\n            winner = random.choice(list(data.keys()))\n            if winner not in set_winners:\n                winners[\"discount\"] = data[winner][\"email\"]\n                set_winners.add(winner)\n        elif len(set_winners) == 2:\n            winner = random.choice(list(data.keys()))\n            active = data[winner][\"status\"].strip() == \"activo\"\n            if winner not in set_winners and active:\n                winners[\"book\"] = data[winner][\"email\"]\n                set_winners.add(winner)\n\n    return winners\n\ndef print_winners(winners):\n    print(\"Ganador de la suscripción: \", winners[\"subscription\"])\n    print(\"Ganador del descuento: \", winners[\"discount\"])\n    print(\"Ganador del libro: \", winners[\"book\"])\n\ndef main():\n    data = open_csv(PATH_CSV_FILE)\n    winners = select_winners(data)\n    print_winners(winners)\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/python/pyramsd.py",
    "content": "import pandas as pd\n\ncvs_file = \"D:\\\\Programacion\\\\registros.csv\"\n\ndf = pd.read_csv(cvs_file)\n\nprint(\"Participantes:\")\nprint(df)\n\nemails_activos = df[df[\"status\"] == \"activo\"][[\"id\", \"email\"]]\n\nganadores = emails_activos.sample(3)\ncategorias = [\"ganador de una suscripción\", \"ganador de un descuento\", \"ganador de un libro\"]\n\nprint(\"\\nGanadores:\")\n\nfor index, (row, categoria) in enumerate(zip(ganadores.iterrows(), categorias)):\n    _, ganador = row\n    print(f\"ID: {ganador['id']}, Email: {ganador['email']} -> {categoria}\")\n"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/python/raulG91.py",
    "content": "import csv\nimport os\nimport random\n\ndef read_csv(filename):\n    values = []\n    try:\n        with open(filename,newline='') as csvfile:\n            reader = csv.reader(csvfile,delimiter=\"|\")\n            for index,row in enumerate(reader):\n                if index != 0 and row[2].lower()==\"activo\":\n                    values.append(row)\n    except:\n        print(\"Error opening the file\")\n    return values\n          \n\n#Get path for the file \npath = os.path.join(os.path.dirname(__file__),\"file.csv\")\n#Read csv values from the file\nvalues = read_csv(path)\n\nif len(values)>=3:\n    #Get 3 random elements from the list\n    list_winners = random.sample(values,k=3)\n\n    #First one win a subscription\n    print(f'Ganadaor de la subscripcion {list_winners[0][1]} con id: {list_winners[0][0]}')\n\n    #Second wins a discount\n    print(f'Ganador del descuento {list_winners[1][1]} con id {list_winners[1][0]}')\n\n    #Third one wins a book\n    print(f'Ganador del libro {list_winners[2][1]} con id {list_winners[2][0]}')\nelse:\n    print(\"Debe haber al menos 3 usuarios\")"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/python/rigo93acosta.py",
    "content": "'''\n/*\n * EJERCICIO:\n * He presentado mi proyecto más importante del año: mouredev pro.\n * Un campus para la comunidad, que lanzaré en octubre, donde estudiar\n * programación de una manera diferente.\n * Cualquier persona suscrita a la newsletter de https://mouredev.pro\n * accederá a sorteos mensuales de suscripciones, regalos y descuentos.\n *\n * Desarrolla un programa que lea los registros de un fichero .csv y\n * seleccione de manera aleatoria diferentes ganadores.\n * Requisitos:\n * 1. Crea un .csv con 3 columnas: id, email y status con valor \"activo\"\n *    o \"inactivo\" (y datos ficticios).\n *    Ejemplo: 1 | test@test.com | activo\n *             2 | test2@test.com | inactivo\n *    (El .csv no debe subirse como parte de la corrección)\n * 2. Recupera los datos desde el programa y selecciona email aleatorios.\n * Acciones:\n * 1. Accede al fichero .csv y selecciona de manera aleatoria un email\n *    ganador de una suscripción, otro ganador de un descuento y un último\n *    ganador de un libro (sólo si tiene status \"activo\" y no está repetido).\n * 2. Muestra los emails ganadores y su id.\n * 3. Ten en cuenta que la primera fila (con el nombre de las columnas)\n *    no debe tenerse en cuenta.\n */\n'''\n\nimport csv\nimport os\nimport random\n\ndef read_csv() -> list:\n\n    file_dir = os.path.dirname(os.path.realpath(__file__))\n    csv_file = f\"{file_dir}/subs.csv\"\n\n    data = []\n\n    with open(csv_file, mode='r') as file:\n        reader = csv.DictReader(file)\n        for row in reader:\n            if row['status'] == 'activo':\n                data.append(row)\n\n    return data\n\ndef select_winner(data: list) -> list:\n\n    if len(data) < 3:\n        raise Exception(\"No hay suficientes registros activos, mínimo 3.\")\n    \n    winners = random.sample(data, 3)\n\n    return winners\n\ndef print_winners(winners: list):\n    \n    for winner, trophy in zip(winners, ['una suscripción', 'un descuento', 'un libro']):\n        print(f'El suscriptor \"{winner['email']}\" (ID:{winner['id']}) ha ganado {trophy}.')\n\ntry:\n    data = read_csv()\n    select_winner(data)\n    print_winners(select_winner(data))\nexcept Exception as e:\n    print(e)\n\n"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/ruby/emanuelgauler.rb",
    "content": "require 'csv'\n\nACTIVE   = \"activo\"\nINACTIVE = \"inactivo\"\n\ndef main participants_file\n   return \"ERROR: Debes proporcionar un fichero CSV\" if participants_file.nil?\n   return \"ERROR: File Not Found\" unless File.exist? participants_file\n   participants   = []\n   awards = [\"ganador de una suscripción\", \"ganó un descuento\", \"ganó un libro\"]\n\n   CSV.foreach participants_file, headers: true do |participant_row|\n      participant = { \n         id: participant_row[\"id\"],\n         email: participant_row[\"email\"],\n         status: participant_row[\"status\"]\n      }\n      participants << participant unless participant[:status] == INACTIVE\n   end\n\n   winners = 3.times.map do  \n      p = participants.shuffle!.shift\n\n      \"#{p[:id]} #{p[:email]} #{awards.shift}\"\n   end\n\nend\n\nparticipants_file = ARGV.first\n\nputs main( participants_file )"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/rust/kenysdev.rs",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - Rust\n_____________________________________\n38 MOUREDEV PRO\n------------------------------------\n* He presentado mi proyecto más importante del año: mouredev pro.\n * Un campus para la comunidad, que lanzaré en octubre, donde estudiar\n * programación de una manera diferente.\n * Cualquier persona suscrita a la newsletter de https://mouredev.pro\n * accederá a sorteos mensuales de suscripciones, regalos y descuentos.\n *\n * Desarrolla un programa que lea los registros de un fichero .csv y\n * seleccione de manera aleatoria diferentes ganadores.\n * Requisitos:\n * 1. Crea un .csv con 3 columnas: id, email y status con valor \"activo\"\n *    o \"inactivo\" (y datos ficticios).\n *    Ejemplo: 1 | test@test.com | activo\n *             2 | test2@test.com | inactivo\n *    (El .csv no debe subirse como parte de la corrección)\n * 2. Recupera los datos desde el programa y selecciona email aleatorios.\n * Acciones:\n * 1. Accede al fichero .csv y selecciona de manera aleatoria un email\n *    ganador de una suscripción, otro ganador de un descuento y un último\n *    ganador de un libro (sólo si tiene status \"activo\" y no está repetido).\n * 2. Muestra los emails ganadores y su id.\n * 3. Ten en cuenta que la primera fila (con el nombre de las columnas)\n *    no debe tenerse en cuenta.\n \n[dependencies]\ncsv = \"1.3.0\"\nrand = \"0.8.5\"\n*/\n\nuse std::collections::HashMap;\nuse std::error::Error;\nuse std::fs::File;\nuse csv::Reader;\nuse rand::seq::SliceRandom;\nuse rand::thread_rng;\n\n#[derive(Debug, Clone)]\nstruct Entry {\n    id: String,\n    email: String,\n    status: String,\n}\n\nfn read_csv(file_path: &str) -> Result<Vec<Entry>, Box<dyn Error>> {\n    let file = File::open(file_path)?;\n    let mut reader = Reader::from_reader(file);\n    let mut entries = Vec::new();\n\n    for result in reader.deserialize() {\n        let record: HashMap<String, String> = result?;\n        entries.push(Entry {\n            id: record.get(\"id\").unwrap_or(&String::new()).to_string(),\n            email: record.get(\"email\").unwrap_or(&String::new()).to_string(),\n            status: record.get(\"status\").unwrap_or(&String::new()).to_string(),\n        });\n    }\n\n    Ok(entries)\n}\n\nfn get_active_entries(entries: &[Entry]) -> Vec<Entry> {\n    entries\n        .iter()\n        .filter(|entry| entry.status.to_lowercase() == \"active\")\n        .cloned()\n        .collect()\n}\n\nfn select_winners(active_entries: &[Entry], num_winners: usize) -> Vec<Entry> {\n    let mut rng = thread_rng();\n    let mut indices: Vec<usize> = (0..active_entries.len()).collect();\n    indices.shuffle(&mut rng);\n    indices.into_iter()\n        .take(num_winners.min(active_entries.len()))\n        .map(|i| active_entries[i].clone())\n        .collect()\n}\n\nfn distribute_prizes(winners: &[Entry], prizes: &[&str]) {\n    let mut rng = thread_rng();\n    let mut shuffled_prizes = prizes.to_vec();\n    shuffled_prizes.shuffle(&mut rng);\n\n    for (winner, prize) in winners.iter().zip(shuffled_prizes.iter()) {\n        println!(\"{:<11} -> Id({}): {}\", prize, winner.id, winner.email);\n    }\n}\n\nfn main() -> Result<(), Box<dyn Error>> {\n    println!(\"Usuarios ganadores de 'MOUREDEV PRO:'\");\n    let csv_file = \"users.csv\";\n    let prizes = vec![\"Suscripción\", \"Descuento\", \"Libro\"];\n\n    match read_csv(csv_file) {\n        Ok(entries) => {\n            let active_entries = get_active_entries(&entries);\n            let winners = select_winners(&active_entries, 3);\n            distribute_prizes(&winners, &prizes);\n        }\n        Err(e) => println!(\"No se encontraron entradas activas: {}\", e),\n    }\n\n    Ok(())\n}\n"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/sql/Nicojsuarez2.sql",
    "content": "# #38 MOUREDEV PRO\n> #### Dificultad: Fácil | Publicación: 16/09/24 | Corrección: 23/09/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * He presentado mi proyecto más importante del año: mouredev pro.\n * Un campus para la comunidad, que lanzaré en octubre, donde estudiar\n * programación de una manera diferente.\n * Cualquier persona suscrita a la newsletter de https://mouredev.pro\n * accederá a sorteos mensuales de suscripciones, regalos y descuentos.\n *\n * Desarrolla un programa que lea los registros de un fichero .csv y\n * seleccione de manera aleatoria diferentes ganadores.\n * Requisitos:\n * 1. Crea un .csv con 3 columnas: id, email y status con valor \"activo\"\n *    o \"inactivo\" (y datos ficticios).\n *    Ejemplo: 1 | test@test.com | activo\n *             2 | test2@test.com | inactivo\n *    (El .csv no debe subirse como parte de la corrección)\n * 2. Recupera los datos desde el programa y selecciona email aleatorios.\n * Acciones:\n * 1. Accede al fichero .csv y selecciona de manera aleatoria un email\n *    ganador de una suscripción, otro ganador de un descuento y un último\n *    ganador de un libro (sólo si tiene status \"activo\" y no está repetido).\n * 2. Muestra los emails ganadores y su id.\n * 3. Ten en cuenta que la primera fila (con el nombre de las columnas)\n *    no debe tenerse en cuenta.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/typescript/hozlucas28.ts",
    "content": "import fs from 'node:fs/promises'\n\n/* -------------------------------------------------------------------------- */\n/*                                    TYPES                                   */\n/* -------------------------------------------------------------------------- */\n\ntype Status = 'active' | 'inactive'\n\ninterface User {\n    id: number\n    email: `${string}@${string}.com`\n    status: Status\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                  FUNCTIONS                                 */\n/* -------------------------------------------------------------------------- */\n\ninterface CreateCSVParams<T extends object> {\n    data: T[]\n    path: `${string}.csv`\n}\n\nasync function createCSV<T extends object>({path, data}: CreateCSVParams<T>) {\n    const columns: string[] = Object.keys(data[0])\n    const rows: string[] = [columns.join(',')]\n\n    for (const element of data) {\n        const row: string = Object.values(element).join(',')\n        rows.push(row)\n    }\n\n    await fs.writeFile(path, rows.join('\\n'), {encoding: 'utf-8'})\n}\n\ninterface GetChoicesParams<T> {\n    amount: number\n    choices: T[]\n    uniqueKey?: keyof T\n}\n\nfunction getChoices<T>({amount, choices, uniqueKey}: GetChoicesParams<T>): T[] {\n    const selectedChoices: T[] = []\n\n    while (selectedChoices.length < amount) {\n        const randomIndex: number = Math.floor(Math.random() * choices.length)\n        const choiceSelected: T = choices[randomIndex]\n\n        const cmpFn = (value: T) => {\n            return uniqueKey\n                ? value[uniqueKey] === choiceSelected[uniqueKey]\n                : value === choiceSelected\n        }\n\n        if (selectedChoices.findIndex(cmpFn) != -1) continue\n        selectedChoices.push(choiceSelected)\n    }\n\n    return selectedChoices\n}\n\ninterface GetCSVParams {\n    path: `${string}.csv`\n}\n\nasync function getCSV<T extends object>({path}: GetCSVParams): Promise<T[]> {\n    const data: T[] = []\n\n    const csvContent = await fs.readFile(path, {encoding: 'utf-8'})\n\n    const csvContentArr: string[] = csvContent.split('\\n')\n    const csvColumnsArr: string[] = csvContentArr[0].split(',')\n    const csvRowsArr: string[] = csvContentArr.slice(1)\n\n    for (const row of csvRowsArr) {\n        const rowArr = row.split(',')\n\n        const newData: any = {}\n        for (let j = 0; j < csvColumnsArr.length; j++) {\n            const column: string = csvColumnsArr[j]\n            newData[column] = rowArr[j]\n        }\n\n        data.push(newData)\n    }\n\n    return data\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\n;(async () => {\n    const users: User[] = [\n        {\n            email: 'test01@gmail.com',\n            id: 1,\n            status: 'active',\n        },\n        {\n            email: 'test02@gmail.com',\n            id: 2,\n            status: 'inactive',\n        },\n        {\n            email: 'test03@gmail.com',\n            id: 3,\n            status: 'inactive',\n        },\n        {\n            email: 'test04@gmail.com',\n            id: 4,\n            status: 'active',\n        },\n        {\n            email: 'test05@gmail.com',\n            id: 5,\n            status: 'inactive',\n        },\n        {\n            email: 'test06@gmail.com',\n            id: 6,\n            status: 'active',\n        },\n        {\n            email: 'test07@gmail.com',\n            id: 7,\n            status: 'active',\n        },\n        {\n            email: 'test08@gmail.com',\n            id: 8,\n            status: 'active',\n        },\n    ]\n\n    await createCSV({data: users, path: './users.csv'})\n    const csvUsers: User[] = await getCSV<User>({path: './users.csv'})\n\n    const activeUsers = csvUsers.filter((user) => user.status === 'active')\n\n    const winners: User[] = getChoices<User>({\n        amount: 3,\n        choices: activeUsers,\n        uniqueKey: 'id',\n    })\n\n    console.log('> The first winner is...')\n    console.log(\n        `> Congratulations ${winners[0].email} with id ${winners[0].id}, you won a subscription!`\n    )\n\n    console.log('\\n> The second winner is...')\n    console.log(\n        `> Congratulations ${winners[1].email} with id ${winners[1].id}, you won a discount!`\n    )\n\n    console.log('\\n> The third winner is...')\n    console.log(\n        `> Congratulations ${winners[2].email} with id ${winners[2].id}, you won a book!`\n    )\n})()\n"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/typescript/miguelex.ts",
    "content": "import * as fs from 'fs';\n\ninterface Suscriptor {\n    id: string;\n    email: string;\n}\n\nfunction obtenerSuscriptoresActivos(archivoCsv: string): Suscriptor[] {\n    const data = fs.readFileSync(archivoCsv, 'utf-8');\n    const filas = data.split('\\n').slice(1); // Saltar la primera fila (cabeceras)\n\n    const suscriptores: Suscriptor[] = [];\n    for (const fila of filas) {\n        const [id, email, status] = fila.split(',');\n        if (status.trim().toLowerCase() === 'activo') {\n            suscriptores.push({ id: id.trim(), email: email.trim() });\n        }\n    }\n\n    return suscriptores;\n}\n\nfunction seleccionarGanadores(suscriptores: Suscriptor[], numeroGanadores: number): Suscriptor[] | null {\n    if (suscriptores.length < numeroGanadores) {\n        return null; \n    }\n\n    const ganadores: Suscriptor[] = [];\n    const indicesSeleccionados = new Set<number>();\n\n    while (ganadores.length < numeroGanadores) {\n        const indiceAleatorio = Math.floor(Math.random() * suscriptores.length);\n        if (!indicesSeleccionados.has(indiceAleatorio)) {\n            ganadores.push(suscriptores[indiceAleatorio]);\n            indicesSeleccionados.add(indiceAleatorio);\n        }\n    }\n\n    return ganadores;\n}\n\nconst archivoCsv = 'suscriptores.csv';\n\nconst suscriptoresActivos = obtenerSuscriptoresActivos(archivoCsv);\n\nif (suscriptoresActivos.length > 0) {\n    const ganadores = seleccionarGanadores(suscriptoresActivos, 3);\n    if (ganadores) {\n        console.log(\"Ganador de la suscripción:\", ganadores[0]);\n        console.log(\"Ganador del descuento:\", ganadores[1]);\n        console.log(\"Ganador del libro:\", ganadores[2]);\n    } else {\n        console.log(\"No hay suficientes suscriptores activos para seleccionar 3 ganadores.\");\n    }\n} else {\n    console.log(\"No hay suscriptores activos.\");\n}\n"
  },
  {
    "path": "Roadmap/38 - MOUREDEV PRO/vb.net/kenysdev.vb",
    "content": "' _____________________________________\n' https://github.com/kenysdev\n' 2024 - vb.net\n' _____________________________________\n' 38 MOUREDEV PRO\n' ------------------------------------\n'* He presentado mi proyecto más importante del año: mouredev pro.\n' * Un campus para la comunidad, que lanzaré en octubre, donde estudiar\n' * programación de una manera diferente.\n' * Cualquier persona suscrita a la newsletter de https://mouredev.pro\n' * accederá a sorteos mensuales de suscripciones, regalos y descuentos.\n' *\n' * Desarrolla un programa que lea los registros de un fichero .csv y\n' * seleccione de manera aleatoria diferentes ganadores.\n' * Requisitos:\n' * 1. Crea un .csv con 3 columnas id, email y status con valor \"activo\"\n' *    o \"inactivo\" (y datos ficticios).\n' *    Ejemplo: 1 | test@test.com | activo\n' *             2 | test2@test.com | inactivo\n' *    (El .csv no debe subirse como parte de la corrección)\n' * 2. Recupera los datos desde el programa y selecciona email aleatorios.\n' * Acciones:\n' * 1. Accede al fichero .csv y selecciona de manera aleatoria un email\n' *    ganador de una suscripción, otro ganador de un descuento y un último\n' *    ganador de un libro (sólo si tiene status \"activo\" y no está repetido).\n' * 2. Muestra los emails ganadores y su id.\n' * 3. Ten en cuenta que la primera fila (con el nombre de las columnas)\n' *    no debe tenerse en cuenta.\n\n\nImports Microsoft.VisualBasic.FileIO\n\nModule Program\n    Sub Main()\n        Console.WriteLine(\"Usuarios ganadores de 'MOUREDEV PRO:'\")\n        Dim csvFile As String = \"users.csv\"\n        Dim prizes As List(Of String) = New List(Of String) From {\"Suscripción\", \"Descuento\", \"Libro\"}\n\n        Dim entries = ReadCsv(csvFile)\n        If entries IsNot Nothing Then\n            Dim activeEntries = GetActiveEntries(entries)\n            Dim winners = SelectWinners(activeEntries, 3)\n            DistributePrizes(winners, prizes)\n        Else\n            Console.WriteLine(\"No se encontraron entradas activas.\")\n        End If\n    End Sub\n\n    Private Function ReadCsv(filePath As String) As List(Of Dictionary(Of String, String))\n        Try\n            Using parser As New TextFieldParser(filePath)\n                parser.TextFieldType = FieldType.Delimited\n                parser.SetDelimiters(\",\")\n\n                Dim headers = parser.ReadFields()\n                Dim entries As New List(Of Dictionary(Of String, String))\n\n                While Not parser.EndOfData\n                    Dim fields = parser.ReadFields()\n                    Dim entry As New Dictionary(Of String, String)\n                    For i As Integer = 0 To headers.Length - 1\n                        entry.Add(headers(i), fields(i))\n                    Next\n                    entries.Add(entry)\n                End While\n\n                Return entries\n            End Using\n        Catch ex As Exception\n            Console.WriteLine($\"Error reading '{filePath}': {ex.Message}\")\n            Return Nothing\n        End Try\n    End Function\n\n    Private Function GetActiveEntries(entries As List(Of Dictionary(Of String, String))) As List(Of Dictionary(Of String, String))\n        Return entries.Where(Function(entry) entry(\"status\").ToLower() = \"active\").\n                       Select(Function(entry) New Dictionary(Of String, String) From {\n                           {\"id\", entry(\"id\")},\n                           {\"email\", entry(\"email\")},\n                           {\"status\", entry(\"status\")}\n                       }).ToList()\n    End Function\n\n    Private Function SelectWinners(activeEntries As List(Of Dictionary(Of String, String)), numWinners As Integer) As List(Of Dictionary(Of String, String))\n        Dim rnd As New Random()\n        Return activeEntries.OrderBy(Function(x) rnd.Next()).\n                             Take(Math.Min(numWinners, activeEntries.Count)).\n                             ToList()\n    End Function\n\n    Private Sub DistributePrizes(winners As List(Of Dictionary(Of String, String)), prizes As List(Of String))\n        Dim rnd As New Random()\n        prizes = prizes.OrderBy(Function(x) rnd.Next()).ToList()\n\n        For i As Integer = 0 To Math.Min(winners.Count, prizes.Count) - 1\n            Console.WriteLine($\"{prizes(i),-11} -> Id({winners(i)(\"id\")}): {winners(i)(\"email\")}\")\n        Next\n    End Sub\nEnd Module\n"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/c#/hequebo.cs",
    "content": "// Reto # 1\nclass BatmanAnniversary\n{\n    private int _anniversaryYear;\n    private int _anniversary;\n    private DateTime _anniversaryDate;\n\n    public int AnniversaryYear { get { return _anniversaryYear; } }\n    public int Anniversary { get { return _anniversary; } }\n    public DateTime AnniversaryDate { get {  return _anniversaryDate; } }\n\n    public BatmanAnniversary(int anniversaryYear, int anniversary, DateTime anniversaryDate)\n    {\n        _anniversaryYear = anniversaryYear;\n        _anniversary = anniversary;\n        _anniversaryDate = anniversaryDate;\n    }\n}\nclass Program\n{\n    static void Main(string[] args)\n    {\n        int yearOfCreation = 1939;\n        int anniversaryYear = yearOfCreation + 85;\n\n        var anniversaryList = new List<BatmanAnniversary>();\n        while (anniversaryYear <= yearOfCreation + 100)\n        {\n            var september = new DateTime(anniversaryYear, 9, 1);\n            if (september.DayOfWeek == DayOfWeek.Saturday)\n            {\n                september = september.AddDays(14);\n                var anniversary = new BatmanAnniversary(anniversaryYear, anniversaryYear - yearOfCreation, september);\n                anniversaryList.Add(anniversary);\n            }\n            else\n            {\n                int firstSaturday = september.Day + 6 - (int)september.DayOfWeek;\n                september = new DateTime(anniversaryYear, 9, firstSaturday);\n\n                september = september.AddDays(14);\n                var anniversary = new BatmanAnniversary(anniversaryYear, anniversaryYear - yearOfCreation, september);\n                anniversaryList.Add(anniversary);\n            }\n            anniversaryYear++;\n        }\n\n        Console.WriteLine(\"Próximos aniversarios de Batman hasta el No. 100\");\n        foreach (var anniversary in anniversaryList)\n            Console.WriteLine($\"Año: {anniversary.AnniversaryYear} Aniversario: {anniversary.Anniversary} \" +\n                $\"Fecha: {anniversary.AnniversaryDate.ToShortDateString()}\");\n\n        // Reto #2\n\n        List<(int, int, int)> sensors = new List<(int, int, int)>\n        {\n            (2, 3, 7),\n            (4, 3, 8),\n            (2, 2, 7),\n            (10, 12, 8),\n            (11, 11, 8),\n            (10, 11, 8),\n            (15, 18, 4)\n        };\n\n        var result = BatcaveSecuritySistem(sensors);\n        Console.WriteLine($\"Centro cuadrícula con más amenaza: {result.Item1.Item1}, {result.Item1.Item2}\");\n        Console.WriteLine($\"Máximo nivel de alerta: {result.Item2}\");\n        Console.WriteLine($\"Distancia a la Baticueva: {result.Item3}\");\n        Console.WriteLine($\"Activar protocolo de emergencia: {(result.Item4 ? \"Sí\" : \"No\")}\");\n    }\n    static int SumAlerts(List<(int, int, int)> sensors, int centerX, int centerY)\n    {\n        int total = 0;\n\n        for (int i = centerX - 1; i <= centerX + 1; i++)\n        {\n            for (int j = centerY - 1; j <= centerY + 1; j++)\n            {\n                foreach(var sensor in sensors)\n                {\n                    if (sensor.Item1 == i && sensor.Item2 == j)\n                        total += sensor.Item3;\n                }\n            }\n        }\n        return total;\n    }\n    static ((int, int), int, int, bool) BatcaveSecuritySistem(List<(int, int, int)> sensors)\n    {\n        int maxAlertLevel = 0;\n        (int, int) maxAlertCoordinates = (0, 0);\n\n        for (int i = 0; i <= 19;  i++)\n        {\n            for (int j = 0; j  <= 19; j++)\n            {\n                int alertLevel = SumAlerts(sensors, i, j);\n                if (alertLevel > maxAlertLevel)\n                {\n                    maxAlertLevel = alertLevel;\n                    maxAlertCoordinates = (i, j);\n                }\n            }\n        }\n\n        int distance = Math.Abs(maxAlertCoordinates.Item1) + Math.Abs(maxAlertCoordinates.Item2);\n        bool activateProtocol = maxAlertLevel > 20;\n\n\n        return (maxAlertCoordinates, maxAlertLevel, distance, activateProtocol);\n    }\n}"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/c#/kenysdev.cs",
    "content": "namespace exs39;\n/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - C#\n_____________________________________\nBATMAN DAY\n------------------------------------\n\n* RETO 1:\n* Crea un programa que calcule cuándo se va a celebrar el Batman Day hasta \n* su 100 aniversario.\n*/\n\npublic class BatmanDay\n{\n    private static string ThirdSaturdayOfSeptember(int year)\n    {\n        var date = new DateTime(year, 9, 15);\n        int daysToAdd = ((int)DayOfWeek.Saturday - (int)date.DayOfWeek + 7) % 7;\n        date = date.AddDays(daysToAdd);\n        return date.ToString(\"dd-MM-yyyy\");\n    }\n\n    public static void CalculateAnniversaryDates(int totalAnniversaries)\n    {\n        Console.WriteLine(\"Batman Day\");\n        const int batmanDayStart = 2014;\n        int currentYear = DateTime.Today.Year;\n\n        if (currentYear < batmanDayStart)\n        {\n            Console.WriteLine(\"xd\");\n            return;\n        }\n\n        int pastAnniversaries = currentYear - batmanDayStart;\n        Console.WriteLine($\"Aniversarios que ya han pasado: {pastAnniversaries}\");\n\n        for (int i = 0; i < totalAnniversaries - pastAnniversaries; i++)\n        {\n            int num = pastAnniversaries + i + 1;\n            string theDate = ThirdSaturdayOfSeptember(currentYear);\n            Console.WriteLine($\"- Aniversario #{num}: {theDate}\");\n            currentYear++;\n        }\n    }\n\n    /*\n     * RETO 2:\n     * Crea un programa que implemente el sistema de seguridad de la Batcueva. \n     * Este sistema está diseñado para monitorear múltiples sensores distribuidos\n     * por Gotham, detectar intrusos y activar respuestas automatizadas. \n     * Cada sensor reporta su estado en tiempo real, y Batman necesita un programa \n     * que procese estos datos para tomar decisiones estratégicas.\n     * Requisitos:\n     * - El mapa de Gotham y los sensores se representa con una cuadrícula 20x20.\n     * - Cada sensor se identifica con una coordenada (x, y) y un nivel\n     *   de amenaza entre 0 a 10 (número entero).\n     * - Batman debe concentrar recursos en el área más crítica de Gotham.\n     * - El programa recibe un listado de tuplas representando coordenadas de los \n     *   sensores y su nivel de amenaza. El umbral de activación del protocolo de\n     *   seguridad es 20 (sumatorio de amenazas en una cuadrícula 3x3).\n     * Acciones: \n     * - Identifica el área con mayor concentración de amenazas\n     *   (sumatorio de amenazas en una cuadrícula 3x3).\n     * - Si el sumatorio de amenazas es mayor al umbral, activa el \n     *   protocolo de seguridad.\n     * - Calcula la distancia desde la Batcueva, situada en (0, 0). La distancia es\n     *   la suma absoluta de las coordenadas al centro de la cuadrícula amenazada.\n     * - Muestra la coordenada al centro de la cuadrícula más amenazada, la suma de\n     *   sus amenazas, la distancia a la Batcueva y si se debe activar el\n     *   protocolo de seguridad.\n    */\n\n    static string[,] CreateMap((int, int) size, (int, int) batcave, List<(int, int, int)> sensors, List<(int, int)> threats)\n    {\n        var gotham = new string[size.Item1, size.Item2];\n        for (int i = 0; i < size.Item1; i++)\n            for (int j = 0; j < size.Item2; j++)\n                gotham[i,j] = \"| \";\n        \n        gotham[batcave.Item1, batcave.Item2] = \"|B\";\n        \n        foreach (var s in sensors)\n            gotham[s.Item1, s.Item2] = \"|S\";\n        \n        foreach (var t in threats)\n            gotham[t.Item1, t.Item2] = \"|T\";\n        \n        return gotham;\n    }\n\n    static void PrintMap(string[,] gotham, (int, int) size)\n    {\n        Console.WriteLine(\"\\nMapa de Gotham:\");\n        for (int i = 0; i < size.Item1; i++)\n        {\n            for (int j = 0; j < size.Item2; j++)\n                Console.Write(gotham[i,j]);\n            Console.WriteLine();\n        }\n    }\n\n    static void ScanMap(string[,] gotham, List<(int, int, int)> sensors, (int, int) size)\n    {\n        var dangerList = new List<(int, int)>();\n\n        for (int c = 0; c < sensors.Count; c++)\n        {\n            var s = sensors[c];\n            int dangerCounter = 0;\n\n            for (int i = s.Item1 - 1; i <= s.Item1 + 1; i++)\n                for (int j = s.Item2 - 1; j <= s.Item2 + 1; j++)\n                    if (i >= 0 && i < size.Item1 && j >= 0 && j < size.Item2 && gotham[i,j] == \"|T\")\n                        dangerCounter += s.Item3;\n\n            dangerList.Add((c, dangerCounter));\n        }\n\n        var maxDanger = dangerList.MaxBy(x => x.Item2);\n        var location = sensors[maxDanger.Item1];\n\n        Console.WriteLine(\"\\nInforme:\");\n        Console.WriteLine($\"Cuadrícula más amenazada: '{location.Item1}, {location.Item2}'\");\n        Console.WriteLine($\"Máximo nivel de alerta: '{maxDanger.Item2}'\");\n\n        if (maxDanger.Item2 >= 20)\n        {\n            Console.WriteLine(\"Protocolo de seguridad activado.\");\n            Console.WriteLine($\"Distancia: '{location.Item1 + location.Item2}'\");\n        }\n        else\n            Console.WriteLine(\"No hay amenazas relevantes.\");\n    }\n\n    public static void Main()\n    {\n        CalculateAnniversaryDates(100);\n\n        // exs #2\n        var size = (20, 20);\n        var batcave = (0, 0);\n        var sensors = new List<(int, int, int)> { (2, 2, 10), (6, 8, 9), (10, 12, 8), (17, 15, 7) };\n        var threats = new List<(int, int)> { (2, 3), (2, 1), (6, 9), (17, 16), (15, 4) };\n\n        var gotham = CreateMap(size, batcave, sensors, threats);\n        PrintMap(gotham, size);\n        ScanMap(gotham, sensors, size);\n    }\n}\n"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/c++/hectorio23.cpp",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\n#include <iostream>\n#include <ctime>\n#include <iomanip>\n#include <cmath>\n#include <map>\n\n//////////////////////////////////////////////////\n///////////////////// RETO 1 /////////////////////\n//////////////////////////////////////////////////\n\nvoid calculate_batman_day() {\n    std::time_t t = std::time(nullptr);\n    std::tm* now = std::localtime(&t);\n    int current_year = now->tm_year + 1900;\n\n    for (int year = current_year; year <= 2039; ++year) {\n        std::tm september_first = {0, 0, 0, 1, 8, year - 1900};\n        std::mktime(&september_first);\n        int weekday = september_first.tm_wday;\n        int third_saturday_offset = (5 - weekday + 7) % 7 + 14;\n\n        std::tm third_saturday = september_first;\n        third_saturday.tm_mday += third_saturday_offset;\n        std::mktime(&third_saturday);\n        \n        std::cout << \"Batman Day \" << year << \": \" \n                  << std::put_time(&third_saturday, \"%Y-%m-%d\") << std::endl;\n    }\n}\n\n//////////////////////////////////////////////////\n///////////////////// RETO 2 /////////////////////\n//////////////////////////////////////////////////\n\nvoid batcave_security_system(const std::map<std::pair<int, int>, int>& sensors) {\n    int grid_size = 20;\n    int threshold = 20;\n    int max_threat = 0;\n    std::pair<int, int> critical_area = {-1, -1};\n\n    // Analizar todas las áreas de 3x3 en la cuadrícula\n    for (int i = 0; i <= grid_size - 3; ++i) {\n        for (int j = 0; j <= grid_size - 3; ++j) {\n            int threat_sum = 0;\n            for (int x = i; x < i + 3; ++x) {\n                for (int y = j; y < j + 3; ++y) {\n                    threat_sum += sensors.count({x, y}) ? sensors.at({x, y}) : 0;\n                }\n            }\n\n            if (threat_sum > max_threat) {\n                max_threat = threat_sum;\n                critical_area = {i + 1, j + 1};  // Centro de la cuadrícula\n            }\n        }\n    }\n\n    // Calcular distancia desde la Batcueva (0, 0)\n    if (critical_area.first != -1) {\n        int distance = std::abs(critical_area.first) + std::abs(critical_area.second);\n        std::cout << \"Área más amenazada: (\" << critical_area.first << \", \" << critical_area.second\n                  << \"), Amenazas: \" << max_threat \n                  << \", Distancia a la Batcueva: \" << distance << std::endl;\n        if (max_threat > threshold) {\n            std::cout << \"Protocolo de seguridad activado.\" << std::endl;\n        }\n    }\n}\n\nint main() {\n    calculate_batman_day();\n\n    // Ejemplo de sensores\n    std::map<std::pair<int, int>, int> sensors = {\n        {{5, 5}, 8}, {{5, 6}, 7}, {{5, 7}, 6},\n        {{6, 5}, 9}, {{6, 6}, 5}, {{6, 7}, 4},\n        {{7, 5}, 3}, {{7, 6}, 2}, {{7, 7}, 10}\n    };\n    \n    batcave_security_system(sensors);\n\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/ejercicio.md",
    "content": "# #39 BATMAN DAY\n> #### Dificultad: Media | Publicación: 23/09/24 | Corrección: 30/09/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Cada año se celebra el Batman Day durante la tercera semana de septiembre... \n * ¡Y este año cumple 85 años! Te propongo un reto doble:\n *\n * RETO 1:\n * Crea un programa que calcule cuándo se va a celebrar el Batman Day hasta \n * su 100 aniversario.\n *\n * RETO 2:\n * Crea un programa que implemente el sistema de seguridad de la Batcueva. \n * Este sistema está diseñado para monitorear múltiples sensores distribuidos\n * por Gotham, detectar intrusos y activar respuestas automatizadas. \n * Cada sensor reporta su estado en tiempo real, y Batman necesita un programa \n * que procese estos datos para tomar decisiones estratégicas.\n * Requisitos:\n * - El mapa de Gotham y los sensores se representa con una cuadrícula 20x20.\n * - Cada sensor se identifica con una coordenada (x, y) y un nivel\n *   de amenaza entre 0 a 10 (número entero).\n * - Batman debe concentrar recursos en el área más crítica de Gotham.\n * - El programa recibe un listado de tuplas representando coordenadas de los \n *   sensores y su nivel de amenaza. El umbral de activación del protocolo de\n *   seguridad es 20 (sumatorio de amenazas en una cuadrícula 3x3).\n * Acciones: \n * - Identifica el área con mayor concentración de amenazas\n *   (sumatorio de amenazas en una cuadrícula 3x3).\n * - Si el sumatorio de amenazas es mayor al umbral, activa el \n *   protocolo de seguridad.\n * - Calcula la distancia desde la Batcueva, situada en (0, 0). La distancia es\n *   la suma absoluta de las coordenadas al centro de la cuadrícula amenazada.\n * - Muestra la coordenada al centro de la cuadrícula más amenazada, la suma de\n *   sus amenazas, la distancia a la Batcueva y si se debe activar el\n *   protocolo de seguridad.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/go/hozlucas28.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"math\"\n\t\"slices\"\n\t\"time\"\n)\n\n/* -------------------------------------------------------------------------- */\n/*                                  FUNCTIONS                                 */\n/* -------------------------------------------------------------------------- */\n\n/* ----------------------------- First Challenge ---------------------------- */\n\nfunc GetBatmanDayAnniversary(anniversary uint16) *time.Time {\n\tvar anniversaryDate time.Time = time.Date(1939, 9, 16, 0, 0, 0, 0, time.Local)\n\n\tif anniversary > 0 {\n\t\tanniversaryDate = time.Date(1939+int(anniversary), 9, 1, 0, 0, 0, 0, time.Local)\n\n\t\tvar saturdayCounter uint8 = 0\n\t\tif anniversaryDate.Weekday() == time.Saturday {\n\t\t\tsaturdayCounter = 1\n\t\t}\n\n\t\tfor saturdayCounter < 3 {\n\t\t\tanniversaryDate = anniversaryDate.AddDate(0, 0, 1)\n\n\t\t\tif anniversaryDate.Weekday() == time.Saturday {\n\t\t\t\tsaturdayCounter += 1\n\t\t\t}\n\t\t}\n\t}\n\n\treturn &anniversaryDate\n}\n\n/* ---------------------------- Second Challenge ---------------------------- */\n\ntype ThreatLevel struct {\n\tX           uint\n\tY           uint\n\tLevel uint\n\t_           struct{}\n}\n\ntype Sensors struct {\n\tArray2D [][]uint\n\t_       struct{}\n}\n\nfunc (sensors *Sensors) GetThreatLevels() []*ThreatLevel {\n\tvar threatLevels []*ThreatLevel = make([]*ThreatLevel, 0, (len(sensors.Array2D)-2)*(len(sensors.Array2D[0])-2))\n\n\tvar rows uint = uint(len(sensors.Array2D))\n\tvar cols uint = uint(len(sensors.Array2D[0]))\n\n\tfor i := uint(1); i < rows-1; i++ {\n\t\tfor j := uint(1); j < cols-1; j++ {\n\t\t\tvar threatLevel uint = 0\n\n\t\t\tthreatLevel += sensors.Array2D[i-1][j-1]\n\t\t\tthreatLevel += sensors.Array2D[i-1][j]\n\t\t\tthreatLevel += sensors.Array2D[i-1][j+1]\n\n\t\t\tthreatLevel += sensors.Array2D[i][j-1]\n\t\t\tthreatLevel += sensors.Array2D[i][j]\n\t\t\tthreatLevel += sensors.Array2D[i][j+1]\n\n\t\t\tthreatLevel += sensors.Array2D[i+1][j-1]\n\t\t\tthreatLevel += sensors.Array2D[i+1][j]\n\t\t\tthreatLevel += sensors.Array2D[i+1][j+1]\n\n\t\t\tthreatLevels = append(threatLevels, &ThreatLevel{X: j, Y: i, Level: threatLevel})\n\t\t}\n\t}\n\n\treturn threatLevels\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\nfunc main() {\n\tfmt.Println(\"> First challenge...\")\n\n\tvar batmanDay85thAnniversary *time.Time = GetBatmanDayAnniversary(85)\n\tvar batmanDay100thAnniversary *time.Time = GetBatmanDayAnniversary(100)\n\n\tfmt.Printf(\n\t\t\"\\n> The 85th anniversary of Batman day is on %d/%d/%d.\\n\",\n\t\tbatmanDay85thAnniversary.Month(),\n\t\tbatmanDay85thAnniversary.Day(),\n\t\tbatmanDay85thAnniversary.Year(),\n\t)\n\n\tfmt.Printf(\n\t\t\"> The 100th anniversary of Batman day is on %d/%d/%d.\\n\",\n\t\tbatmanDay100thAnniversary.Month(),\n\t\tbatmanDay100thAnniversary.Day(),\n\t\tbatmanDay100thAnniversary.Year(),\n\t)\n\n\tfmt.Println(\"\\n> Second challenge...\")\n\n\tvar batmanCavePos [2]uint = [2]uint{0, 0}\n\n\tvar sensors Sensors = Sensors{\n\t\tArray2D: [][]uint{\n\t\t\t{1, 0, 1, 1, 2, 0, 1, 2, 0, 1, 0, 1, 2, 0, 1, 0, 1, 2, 0, 1},\n\t\t\t{2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0},\n\t\t\t{1, 0, 1, 2, 0, 1, 0, 1, 2, 0, 1, 0, 1, 2, 0, 1, 0, 1, 0, 1},\n\t\t\t{0, 9, 8, 0, 2, 0, 9, 2, 8, 1, 0, 1, 3, 7, 8, 1, 0, 2, 7, 6},\n\t\t\t{1, 0, 1, 1, 2, 0, 1, 2, 0, 1, 0, 1, 2, 0, 1, 0, 1, 2, 0, 1},\n\t\t\t{3, 1, 8, 7, 9, 6, 1, 7, 9, 0, 1, 0, 1, 9, 2, 1, 3, 0, 8, 0},\n\t\t\t{1, 6, 9, 1, 2, 8, 0, 2, 1, 3, 2, 8, 7, 2, 8, 0, 1, 7, 9, 0},\n\t\t\t{1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 1, 0},\n\t\t\t{0, 1, 0, 1, 2, 0, 1, 0, 1, 2, 0, 1, 0, 1, 2, 0, 1, 0, 1, 0},\n\t\t\t{2, 0, 1, 0, 1, 2, 0, 1, 0, 1, 0, 1, 2, 0, 1, 0, 1, 0, 1, 2},\n\t\t\t{7, 8, 6, 1, 0, 9, 2, 8, 1, 3, 7, 1, 0, 2, 0, 9, 1, 6, 7, 8},\n\t\t\t{0, 1, 7, 9, 2, 8, 1, 6, 7, 8, 1, 2, 0, 3, 1, 8, 2, 7, 0, 1},\n\t\t\t{3, 0, 9, 1, 8, 6, 1, 0, 7, 9, 2, 0, 1, 2, 8, 0, 1, 9, 6, 1},\n\t\t\t{1, 1, 0, 1, 2, 0, 1, 0, 1, 2, 0, 1, 0, 1, 2, 0, 1, 0, 1, 0},\n\t\t\t{0, 1, 0, 1, 2, 0, 1, 0, 1, 2, 0, 1, 0, 1, 2, 0, 1, 0, 1, 0},\n\t\t\t{2, 0, 1, 0, 1, 2, 0, 1, 0, 1, 0, 1, 2, 0, 1, 0, 1, 0, 1, 2},\n\t\t\t{9, 6, 1, 0, 9, 8, 7, 2, 8, 0, 1, 0, 3, 6, 2, 7, 9, 2, 8, 1},\n\t\t\t{0, 7, 8, 9, 6, 2, 1, 9, 6, 7, 8, 0, 9, 7, 6, 8, 1, 0, 2, 8},\n\t\t\t{2, 0, 1, 0, 1, 2, 0, 1, 0, 1, 0, 1, 2, 0, 1, 0, 1, 0, 1, 2},\n\t\t\t{3, 2, 1, 9, 6, 7, 0, 3, 1, 8, 2, 7, 9, 2, 0, 9, 7, 6, 8, 0},\n\t\t},\n\t}\n\n\tvar threatLevels []*ThreatLevel = sensors.GetThreatLevels()\n\n\tvar threatLevelsGreaterThanTwenty []*ThreatLevel = slices.DeleteFunc(threatLevels, func(threatLevel *ThreatLevel) bool {\n\t\treturn threatLevel.Level < 20\n\t})\n\n\tfmt.Println(\"\\n> Threat levels greater than 20 (security protocol activated)...\")\n\n\tfor _, threatLevel := range threatLevelsGreaterThanTwenty {\n\t\tfmt.Printf(\"\\n> Coordinates (x, y): (%d, %d).\\n\", threatLevel.X, threatLevel.Y)\n\t\tfmt.Printf(\"> Threat level: %d.\\n\", threatLevel.Level)\n\t}\n\n\tfmt.Println(\"\\n> Position with the maximum threat level...\")\n\n\tvar maxThreatLevel *ThreatLevel = slices.MaxFunc(threatLevelsGreaterThanTwenty, func(a *ThreatLevel, b *ThreatLevel) int {\n\t\treturn int(a.Level - b.Level)\n\t})\n\n\tvar distanceToBatmanCave uint = uint(math.Abs(float64(maxThreatLevel.X-batmanCavePos[0])) +\n\t\tmath.Abs(float64(maxThreatLevel.Y-batmanCavePos[1])))\n\n\tfmt.Printf(\"\\n> Coordinates (x, y): (%d, %d).\\n\", maxThreatLevel.X, maxThreatLevel.Y)\n\tfmt.Printf(\"> Threat level: %d.\\n\", maxThreatLevel.Level)\n\tfmt.Printf(\"> Distance to batman cave: %d cells.\\n\", distanceToBatmanCave)\n}\n"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/java/Josegs95.java",
    "content": "import java.time.DayOfWeek;\nimport java.time.LocalDate;\nimport java.time.format.DateTimeFormatter;\nimport java.time.temporal.TemporalAdjusters;\nimport java.util.*;\n\npublic class Josegs95 {\n    public static void main(String[] args) {\n        new Josegs95().batmanDay();\n    }\n\n    private int[][] gothamMap = new int[20][20];\n\n    public void batmanDay(){\n        //Reto 1\n        System.out.println(\"Reto 1:\");\n        calculateFutureBatmanDays();\n\n        //Reto 2\n        System.out.println(\"\\nReto2:\");\n        List<Integer[]> sensorList = createRandomSensors(25);\n        putSensorOnMap(sensorList);\n        Map<String, Integer> mostDangerousAreaData = identifyMostDangerousArea();\n\n        int xCoord = mostDangerousAreaData.get(\"X\");\n        int yCoord = mostDangerousAreaData.get(\"Y\");\n        int dangerLevel = mostDangerousAreaData.get(\"dangerLevel\");\n        System.out.println(\"Zona mas peligrosa\");\n        System.out.print(\"X: \" + xCoord + \", \");\n        System.out.print(\"Y: \" + yCoord + \", \");\n        System.out.println(\"Nivel de peligro: \" + dangerLevel);\n        System.out.println((dangerLevel > 19 ? \"Se\" : \"No se\") + \" debe activar el protocolo de seguridad\");\n        System.out.println(\"Distancia a la Batcueva: \" + (xCoord + yCoord) + \" casillas.\");\n    }\n\n    //Reto 1\n    private void calculateFutureBatmanDays(){\n        LocalDate date = LocalDate.of(2024, 9, 1);\n        int anniversaryCount = 85;\n        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(\"dd 'de' LLLL 'del' yyyy\");\n        while(anniversaryCount <= 100){\n            date = date.with(TemporalAdjusters.dayOfWeekInMonth(3, DayOfWeek.SATURDAY));\n            System.out.println(\"El aniversario nª\" + anniversaryCount + \" será el: \" + date.format(formatter));\n\n            date = date.plusYears(1);\n            anniversaryCount++;\n        }\n    }\n\n    //Reto 2\n    private List<Integer[]> createRandomSensors(int sensorCount){\n        Random rnd = new Random();\n        List<Integer[]> sensorList = new ArrayList<>();\n        int[][] aux = new int[gothamMap.length][gothamMap[0].length];\n\n        Arrays.stream(aux).forEach(row -> Arrays.fill(row, -1));\n\n        for (int i = 0; i < sensorCount; i++){\n            int x = rnd.nextInt(aux.length);\n            int y = rnd.nextInt(aux.length);\n            if (aux[x][y] != -1){\n                i--;\n                continue;\n            }\n\n            int value = rnd.nextInt(11);\n            sensorList.add(new Integer[] {x, y, value});\n            aux[x][y] = value;\n        }\n\n        return sensorList;\n    }\n\n    private void putSensorOnMap(List<Integer[]> sensors){\n        for (Integer[] sensor : sensors){\n            gothamMap[sensor[0]][sensor[1]] = sensor[2];\n        }\n    }\n\n    private Map<String, Integer> identifyMostDangerousArea(){\n        int coordX = 0;\n        int coordY = 0;\n        int mostDangerLevel = 0;\n        for (int i = 0; i < gothamMap.length - 2; i++){\n            for (int j = 0; j < gothamMap[0].length - 2; j++){\n                int[][] area = getSubmatrixFromMatrix(gothamMap, i, j);\n                int dangerLevel = Arrays.stream(area)\n                        .map(row -> Arrays.stream(row).sum())\n                        .reduce(Integer::sum)\n                        .get();\n\n                if (dangerLevel > mostDangerLevel){\n                    coordX = i + 1;\n                    coordY = j + 1;\n                    mostDangerLevel = dangerLevel;\n                }\n            }\n        }\n        Map<String, Integer> data = new HashMap<>();\n        data.put(\"X\", coordX);\n        data.put(\"Y\", coordY);\n        data.put(\"dangerLevel\", mostDangerLevel);\n\n        return data;\n    }\n\n    private int[][] getSubmatrixFromMatrix(int[][] matrix, int xCoord, int yCoord, Integer... size){\n        int length = size.length != 0 ? size[0] : 3;\n\n        return Arrays.stream(Arrays.copyOfRange(matrix, yCoord, yCoord + length))\n                .map(row -> Arrays.copyOfRange(row, xCoord, xCoord + length))\n                .toArray(int[][]::new);\n    }\n\n    private void printMatrix(int[][] matrix){\n        Arrays.stream(matrix)\n                .map(Arrays::toString)\n                .forEach(System.out::println);\n    }\n}\n"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/java/MohamedElderkaoui.java",
    "content": "import java.util.*;\n\npublic class MohamedElderkaoui {\n\n    public static void main(String[] args) {\n        // Challenge 1: Batman Day calculation until 100th anniversary using Calendar\n        int currentYear = 2024;\n        int batmanAge = 85;\n        System.out.println(\"Batman Day until 100th Anniversary:\");\n        calculateBatmanDayUsingCalendar(currentYear, batmanAge);\n\n        // Challenge 2: Batcave Security System\n        System.out.println(\"\\nBatcave Security System:\");\n        // Sample sensor data: (x, y, threat level)\n        List<int[]> sensors = List.of(\n            new int[]{3, 3, 5},\n            new int[]{4, 4, 8},\n            new int[]{5, 5, 2},\n            new int[]{10, 10, 9},\n            new int[]{11, 11, 3},\n            new int[]{12, 12, 7}\n        );\n        batcaveSecuritySystem(sensors);\n    }\n\n    // CHALLENGE 1: Calculate Batman Day until his 100th anniversary using Calendar\n    public static void calculateBatmanDayUsingCalendar(int currentYear, int batmanAge) {\n        int yearsLeft = 100 - batmanAge;\n        for (int i = 0; i <= yearsLeft; i++) {\n            int year = currentYear + i;\n            Calendar thirdSaturday = getThirdSaturdayOfSeptember(year);\n            System.out.printf(\"Batman Day in %d: %tF\\n\", year, thirdSaturday.getTime());\n        }\n    }\n\n    // Get the third Saturday of September using Calendar\n    private static Calendar getThirdSaturdayOfSeptember(int year) {\n        // Create a calendar instance set to September 1st of the given year\n        Calendar calendar = Calendar.getInstance();\n        calendar.set(year, Calendar.SEPTEMBER, 1);\n\n        // Find the first Saturday of September\n        while (calendar.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY) {\n            calendar.add(Calendar.DAY_OF_MONTH, 1);\n        }\n\n        // Move to the third Saturday\n        calendar.add(Calendar.DAY_OF_MONTH, 14); // Add 2 more weeks\n\n        return calendar;\n    }\n\n    // CHALLENGE 2: Batcave Security System\n    public static void batcaveSecuritySystem(List<int[]> sensors) {\n        // 20x20 grid of Gotham\n        int[][] gothamGrid = new int[20][20];\n\n        // Fill the grid with the threat levels from the sensor data\n        for (int[] sensor : sensors) {\n            int x = sensor[0];\n            int y = sensor[1];\n            int threatLevel = sensor[2];\n            gothamGrid[x][y] = threatLevel;\n        }\n\n        int maxThreatSum = 0;\n        int centerX = 0, centerY = 0;\n\n        // Find the 3x3 grid with the maximum threat level\n        for (int i = 0; i <= 17; i++) {\n            for (int j = 0; j <= 17; j++) {\n                int threatSum = calculateThreatSum(gothamGrid, i, j);\n                if (threatSum > maxThreatSum) {\n                    maxThreatSum = threatSum;\n                    centerX = i + 1;\n                    centerY = j + 1;\n                }\n            }\n        }\n\n        // Calculate the distance from Batcave (0, 0) to the center of the most threatened grid\n        int distanceToBatcave = Math.abs(centerX) + Math.abs(centerY);\n\n        // Display the results\n        System.out.println(\"Most threatened 3x3 grid center: (\" + centerX + \", \" + centerY + \")\");\n        System.out.println(\"Sum of threats: \" + maxThreatSum);\n        System.out.println(\"Distance to Batcave: \" + distanceToBatcave);\n\n        // Check if the security protocol should be activated\n        if (maxThreatSum > 20) {\n            System.out.println(\"Security Protocol Activated!\");\n        } else {\n            System.out.println(\"Security Protocol NOT Activated.\");\n        }\n    }\n\n    // Helper function to calculate the sum of threats in a 3x3 grid starting from (x, y)\n    private static int calculateThreatSum(int[][] grid, int x, int y) {\n        int sum = 0;\n        for (int i = x; i < x + 3; i++) {\n            for (int j = y; j < y + 3; j++) {\n                sum += grid[i][j];\n            }\n        }\n        return sum;\n    }\n}\n"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/java/asjordi.java",
    "content": "import java.time.DayOfWeek;\nimport java.time.LocalDate;\nimport java.time.temporal.TemporalAdjusters;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.Random;\n\npublic class Main {\n\n    public static void main(String[] args) {\n        calculateBatmanDay();\n        batcaveSecuritySystem();\n    }\n\n    /*\n        RETO 1:\n        Crea un programa que calcule cuándo se va a celebrar el Batman Day hasta su 100 aniversario.\n        El Batman Day se celebra el tercer sábado de septiembre de cada año.\n     */\n    public static void calculateBatmanDay() {\n        List<LocalDate> batmanDayAnniversary = new LinkedList<>();\n        int year = 1939;\n\n        for (int i = 0; i < 100; i++) {\n            LocalDate firstDayOfSeptember = LocalDate.of(year, 9, 1);\n            LocalDate firstSaturday = firstDayOfSeptember.with(TemporalAdjusters.firstInMonth(DayOfWeek.SATURDAY));\n            LocalDate thirdSaturday = firstSaturday.plusWeeks(2);\n            batmanDayAnniversary.add(thirdSaturday);\n            year++;\n        }\n\n        batmanDayAnniversary.forEach(day -> System.out.println(\"El sábado de la tercera semana de septiembre de \" + day.getYear() + \" es el día \" + day.getDayOfMonth()));\n    }\n\n    /*\n        Reto 2:\n     */\n    public static void batcaveSecuritySystem() {\n        Sensor[][] grid = new Sensor[20][20];\n        Random random = new Random();\n\n        for (int x = 0; x < 20; x++) {\n            for (int y = 0; y < 20; y++) {\n                grid[x][y] = new Sensor(x, y, random.nextInt(11));\n            }\n        }\n\n        int centerX = 0, centerY = 0, maxSum = 0;\n\n        for (int x = 0; x <= 17; x++) {\n            for (int y = 0; y <= 17; y++) {\n                int currSum = calculateSum(grid, x, y);\n                if (currSum > maxSum) {\n                    maxSum = currSum;\n                    centerX = x + 1;\n                    centerY = y + 1;\n                }\n            }\n        }\n\n        int distanceToBatcave = Math.abs(centerX) + Math.abs(centerY);\n\n        System.out.println(\"Most intense area is at (\" + centerX + \", \" + centerY + \") with a sum of \" + maxSum);\n        System.out.println(\"Distance to Batcave: \" + distanceToBatcave);\n        System.out.println(\"Security protocol should be activated? \" + ((maxSum > 20) ? \"YES\" : \"NO\"));\n    }\n\n    private static int calculateSum(Sensor[][] grid, int x, int y) {\n        int sum = 0;\n        for (int i = x; i < x + 3; i++) {\n            for (int j = y; j < y + 3; j++) {\n                sum += grid[i][j].level;\n            }\n        }\n        return sum;\n    }\n\n    record Sensor(int x, int y, int level) {}\n}\n"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/java/martinbohorquez.java",
    "content": "import java.time.LocalDate;\nimport java.time.format.DateTimeFormatter;\nimport java.time.temporal.TemporalAdjusters;\nimport java.util.*;\nimport java.util.concurrent.atomic.AtomicReference;\n\nimport static java.time.DayOfWeek.*;\n\npublic class martinbohorquez {\n    public static void main(String[] args) {\n        // RETO 1\n        System.out.println(\"La fechas de celebración para el día de Batman hasta su  100 aniversario:\");\n        getBatmanDay100().forEach(map -> System.out.printf(\"Batman day %s (%s aniversario): %s%n\",\n                map.get(\"year\"), map.get(\"aniversaryYear\"), map.get(\"aniversaryDate\")));\n\n        // RETO 2\n        List<Sensor> sensor = getGothamMap(25, 30, 5);\n\n        batCaveSecuritySystem(sensor);\n\n    }\n\n    private static List<Map<String, String>> getBatmanDay100() {\n        int initialYear = 1939;\n        int month = 9;\n        int dayOfMonth = 1;\n        List<Map<String, String>> batmanDayAnniversaryDates = new ArrayList<>();\n        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(\"dd/MM/yyyy\");\n\n        for (int i = 85; i <= 100; i++) {\n            LocalDate date = LocalDate.of(initialYear + i, month, dayOfMonth)\n                    .with(TemporalAdjusters.dayOfWeekInMonth(3, SATURDAY));\n            batmanDayAnniversaryDates.add(Map.of(\"year\", String.valueOf(initialYear + i),\n                    \"aniversaryYear\", String.valueOf(i),\n                    \"aniversaryDate\", date.format(formatter)));\n        }\n        return batmanDayAnniversaryDates;\n    }\n\n    private static List<Sensor> getGothamMap(int x, int y, int threatMaxLevel) {\n        List<Sensor> sensores = new ArrayList<>();\n        Random random = new Random();\n        for (int i = 0; i < x; i++)\n            for (int j = 0; j < y; j++) {\n                Sensor sensor = new Sensor(i, j, random.nextInt(0, threatMaxLevel + 1));\n                sensores.add(sensor);\n            }\n        return sensores;\n    }\n\n    private static void batCaveSecuritySystem(List<Sensor> sensores) {\n        int x = Sensor.getxMax();\n        int y = Sensor.getyMax();\n        int maxAlertLevel = 0;\n        Sensor sensor = null;\n        for (int i = 1; i < x - 1; i++) {\n            for (int j = 1; j < y - 1; j++) {\n                int sum = 0;\n                Sensor candidateSensor = null;\n                for (Sensor s : sensores) {\n                    if (Math.abs(s.getX() - i) <= 1 && Math.abs(s.getY() - j) <= 1) {\n                        sum += s.getThreatLevel();\n                        if (s.getX() == i && s.getY() == j) candidateSensor = s;\n                    }\n                }\n\n                if (sum > maxAlertLevel && candidateSensor != null) {\n                    maxAlertLevel = sum;\n                    sensor = candidateSensor;\n                }\n            }\n        }\n        if (sensor != null) {\n            System.out.printf(\"El centro de cuadrícula (3x3) más amenazada es: (%d, %d)%n\",\n                    sensor.getX(), sensor.getY());\n            System.out.printf(\"La suma de las amenazas dentro de la cuadrícula es: %d%n\",\n                    maxAlertLevel);\n            System.out.printf(\"La distancia entre la Batcueva (0,0) y el centro de la cuadrícula más amenazada: %s%n\",\n                    sensor.getX() + sensor.getY());\n            System.out.printf(\"Se activó el protocolo de seguridad: %s%n\", maxAlertLevel > 20 ? \"Sí\" : \"No\");\n        }\n    }\n\n    private static class Sensor {\n        private Integer x;\n        private Integer y;\n        private Integer threatLevel;\n        private static Integer xMax = 0;\n        private static Integer yMax = 0;\n\n        public Sensor() {\n        }\n\n        public Sensor(Integer xPosition, Integer yPosition, Integer threatLevel) {\n            this.x = xPosition;\n            this.y = yPosition;\n            this.threatLevel = threatLevel;\n            xMax++;\n            yMax++;\n        }\n\n        public Integer getX() {\n            return x;\n        }\n\n        public Integer getY() {\n            return y;\n        }\n\n        public Integer getThreatLevel() {\n            return threatLevel;\n        }\n\n        public static Integer getxMax() {\n            return xMax;\n        }\n\n        public static Integer getyMax() {\n            return yMax;\n        }\n\n        @Override\n        public String toString() {\n            return \"Sensor{\" +\n                    \"xPosition=\" + x +\n                    \", yPosition=\" + y +\n                    \", threatLevel=\" + threatLevel +\n                    '}';\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/java/miguelex.java",
    "content": "import java.time.LocalDate;\nimport java.time.temporal.TemporalAdjusters;\nimport java.time.DayOfWeek;\nimport java.util.Random;\n\npublic class miguelex {\n    \n    // RETO 1: Cálculo de Batman Day hasta su 100 aniversario\n    public static void calcularBatmanDay(int anioInicio, int anioFinal) {\n        System.out.println(\"Fechas del Batman Day hasta su 100 aniversario:\");\n        for (int anio = anioInicio; anio <= anioFinal; anio++) {\n            LocalDate tercerSabado = LocalDate.of(anio, 9, 1)\n                    .with(TemporalAdjusters.dayOfWeekInMonth(3, DayOfWeek.SATURDAY));\n            System.out.println(\"Batman Day en el año \" + anio + \": \" + tercerSabado);\n        }\n    }\n    \n    // RETO 2: Sistema de seguridad de la Batcueva\n    public static void activarSistemaSeguridad(int[][] sensores) {\n        int tamanoMapa = 20;\n        int umbralSeguridad = 20;\n        int mejorSumaAmenazas = 0;\n        int[] mejorCentro = null;\n\n        for (int i = 0; i <= tamanoMapa - 3; i++) {\n            for (int j = 0; j <= tamanoMapa - 3; j++) {\n                int sumaAmenazas = 0;\n                for (int x = i; x < i + 3; x++) {\n                    for (int y = j; y < j + 3; y++) {\n                        sumaAmenazas += sensores[x][y];\n                    }\n                }\n                if (sumaAmenazas > mejorSumaAmenazas) {\n                    mejorSumaAmenazas = sumaAmenazas;\n                    mejorCentro = new int[]{i + 1, j + 1};\n                }\n            }\n        }\n        if (mejorCentro != null) {\n            int distanciaABatcueva = Math.abs(mejorCentro[0]) + Math.abs(mejorCentro[1]);\n            System.out.println(\"\\nArea más amenazada en coordenadas (\" + mejorCentro[0] + \", \" + mejorCentro[1] + \")\");\n            System.out.println(\"Suma de amenazas: \" + mejorSumaAmenazas);\n            System.out.println(\"Distancia a la Batcueva: \" + distanciaABatcueva);\n\n            if (mejorSumaAmenazas > umbralSeguridad) {\n                System.out.println(\"¡Protocolo de seguridad activado!\");\n            } else {\n                System.out.println(\"Protocolo de seguridad NO activado.\");\n            }\n        }\n    }\n\n    public static void main(String[] args) {\n        // Ejecutar el reto 1\n        int anioInicio = 2024;\n        int anioFinal = 2024 + (100 - 85);\n        calcularBatmanDay(anioInicio, anioFinal);\n\n        // Ejecutar el reto 2\n        Random random = new Random();\n        int[][] sensores = new int[20][20];\n        for (int i = 0; i < 20; i++) {\n            for (int j = 0; j < 20; j++) {\n                sensores[i][j] = random.nextInt(11);\n            }\n        }\n        activarSistemaSeguridad(sensores);\n    }\n}\n"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #39 - JavaScript -> Jesus Antonio Escamilla */\n\n/**\n * BATMAN DAY.\n * Utilizando la Terminal para pedir datos y agregarlos.\n */\n\n// RETO 1\nfunction saturdayDay(years, month) {\n    let date = new Date(years, month - 1, 1)\n    let dayOfWeek = date.getDay()\n\n    let daysUntilSaturday = (6 - dayOfWeek + 7) % 7\n\n    date.setDate((date.getDate() + daysUntilSaturday) + 15)\n\n    return date.toLocaleDateString()\n}\n\nfunction getBatmanDay(startYear, endYear, month) {\n    let saturdays = [];\n\n    for (let year = startYear; year <= endYear; year++) {\n        let thirdSaturdayDay = saturdayDay(year, month)\n        saturdays.push({year: year, date: thirdSaturdayDay})\n    }\n\n    return saturdays\n}\n\n// Ejecutando RETO 1\nconst saturdayBetween = (getBatmanDay(2024, 2024 + 15, 9))\nconsole.group('RETO 1')\nconsole.group('¡¡Los siguientes Batman Day en este año 2024 es 85 aniversario!!')\nsaturdayBetween.forEach(({year, date}) => {\n    console.log(`Batman Day en el año ${year}: ${date}`)\n})\nconsole.groupEnd()\nconsole.groupEnd()\n\n\n\n// RETO 2\n// Tamaño de la cuadricula y el umbral del protocolo de seguridad\nconst Grid_SIZE = 20;\nconst Threat_THRESHOLD = 20;\n\n// Coordenadas de la Batcueva\nconst BATCAVE_X = 0;\nconst BATCAVE_Y = 0;\n\n// Función para calcular la distancia de Manhattan\nconst calcularDistancia = (x, y) => {\n    return Math.abs(BATCAVE_X - x) + Math.abs(BATCAVE_Y - y);\n};\n\n// Función para procesar la cuadrícula y encontrar el área más crítica\nfunction analyzeSensors(sensors) {\n    // Mapa de Gotham\n    const grid = Array.from({ length: Grid_SIZE }, () => Array(Grid_SIZE).fill(0));\n\n    // Rellenar con los niveles de amenaza a cada sensor\n    sensors.forEach(([x, y, threat]) => {\n        grid[x][y] = threat;\n    })\n\n    let maxThreat = 0;\n    let coordinateMaximum = [0, 0];\n\n    // Analizar el area 3x3 para encontrar mas critica\n    for (let i = 0; i <= Grid_SIZE - 3; i++) {\n        for (let j = 0; j <= Grid_SIZE - 3; j++) {\n            let sumThreat = 0;\n\n            // Calcular el sumatorio de amenazas en la cuadrícula 3x3\n            for (let x = i; x < i + 3; x++) {\n                for (let y = j; y < j + 3; y++) {\n                    sumThreat += grid[x][y];\n                }\n            }\n\n            // Actualizar si encontramos una zona con mayor concentración de amenazas\n            if (sumThreat > maxThreat) {\n                maxThreat = sumThreat;\n                coordinateMaximum = [i + 1, j + 1]; // El centro de la cuadrícula 3x3\n            }\n        }\n    }\n\n    // Calcular la distancia desde la Batcueva\n    const [xCenter, yCenter] = coordinateMaximum;\n    const distance = calcularDistancia(xCenter, yCenter);\n\n    // Imprimir solución\n    console.group('RETO 2');\n    console.log(`Coordenada más amenazada: (${xCenter}, ${yCenter})`);\n    console.log(`Suma de amenazas: ${maxThreat}`);\n    console.log(`Distancia a la Batcueva: ${distance}`);\n    if (maxThreat > Threat_THRESHOLD) {\n        console.log(\"Protocolo de seguridad activado\");\n    } else {\n        console.log(\"Protocolo de seguridad no activado\");\n    }\n    console.groupEnd();\n};\n\n// Ejemplo de uso: lista de sensores (x, y, nivel de amenaza)\nconst sensors = [\n    [5, 5, 7],\n    [6, 5, 8],\n    [7, 5, 5],\n    [10, 10, 9],\n    [11, 10, 6],\n    [12, 10, 8],\n    [15, 15, 4],\n    [16, 15, 2],\n    [17, 15, 1],\n];\n\n// Ejecutando RETO 2\nanalyzeSensors(sensors);"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/javascript/RaulDoezon.js",
    "content": "/*\n  EJERCICIO:\n  Cada año se celebra el Batman Day durante la tercera semana de septiembre... \n  ¡Y este año cumple 85 años! Te propongo un reto doble:\n \n  RETO 1:\n  Crea un programa que calcule cuándo se va a celebrar el Batman Day hasta \n  su 100 aniversario.\n \n  RETO 2:\n  Crea un programa que implemente el sistema de seguridad de la Batcueva. \n  Este sistema está diseñado para monitorear múltiples sensores distribuidos\n  por Gotham, detectar intrusos y activar respuestas automatizadas. \n  Cada sensor reporta su estado en tiempo real, y Batman necesita un programa \n  que procese estos datos para tomar decisiones estratégicas.\n  Requisitos:\n  - El mapa de Gotham y los sensores se representa con una cuadrícula 20x20.\n  - Cada sensor se identifica con una coordenada (x, y) y un nivel\n    de amenaza entre 0 a 10 (número entero).\n  - Batman debe concentrar recursos en el área más crítica de Gotham.\n  - El programa recibe un listado de tuplas representando coordenadas de los \n    sensores y su nivel de amenaza. El umbral de activación del protocolo de\n    seguridad es 20 (sumatorio de amenazas en una cuadrícula 3x3).\n  Acciones: \n  - Identifica el área con mayor concentración de amenazas\n    (sumatorio de amenazas en una cuadrícula 3x3).\n  - Si el sumatorio de amenazas es mayor al umbral, activa el \n    protocolo de seguridad.\n  - Calcula la distancia desde la Batcueva, situada en (0, 0). La distancia es\n    la suma absoluta de las coordenadas al centro de la cuadrícula amenazada.\n  - Muestra la coordenada al centro de la cuadrícula más amenazada, la suma de\n    sus amenazas, la distancia a la Batcueva y si se debe activar el\n    protocolo de seguridad.\n*/\n\nconsole.log('+++++++++ RETO 1: BATMAN DAY HASTA EL ANIVERSARIO 100 +++++++++');\n\nlet initialDate = new Date(2024, 9, 0).getDate();\nlet yearsCounter = 0;\nlet saturdayIndex = 0;\n\nfor (let year = 85; year <= 100; year++) {\n  for (let day = 1; day <= initialDate; day++) {\n    let newDate = new Date(new Date().getFullYear() + yearsCounter, new Date().getMonth(), day);\n\n    if (newDate.getDay() === 6) {\n      saturdayIndex++;\n\n      if (saturdayIndex === 3) {\n        console.log(`Aniversario ${year}: ${day} de Septiembre del ${new Date().getFullYear() + yearsCounter}`);\n\n        saturdayIndex = 0;\n        break;\n      }\n    }\n  }\n\n  yearsCounter++;\n}\n\nconsole.log('\\n+++++++++ RETO 2: SISTEMA DE SEGURIDAD DE LA BATICUEVA +++++++++');\n\nlet gothamMap = [];\n\nfor (let row = 0; row < 20; row++) {\n  gothamMap[row] = [];\n\n  for (let column = 0; column < 20; column++) {\n    let threatLevel = Math.round((Math.random() * (10 - 0) + 0));\n\n    gothamMap[row][column] = threatLevel;\n  }\n}\n\nfunction securityProtocol(matrix, subMatrix) {\n  let activationThreshold = 0;\n  let axisX = 0;\n  let axisY = 0;\n\n  for (let firstRow = 0; firstRow <= matrix.length - subMatrix; firstRow++) {\n    for (let firstColumn = 0; firstColumn <= matrix[0].length - subMatrix; firstColumn++) {\n      let sumOfThreats = 0;\n\n      for (let row = 0; row < subMatrix; row++) {\n        for (let column = 0; column < subMatrix; column++) {\n          sumOfThreats += matrix[firstRow + row][firstColumn + column];\n        }\n      }\n\n      if (activationThreshold < sumOfThreats) {\n        activationThreshold = sumOfThreats;\n        axisX = firstRow + 1;\n        axisY = firstColumn + 1;\n      }\n    }\n  }\n\n  return [activationThreshold, axisX, axisY];\n}\n\nfunction calculateDistance(x2, y2) {\n  let distance = Math.sqrt(Math.pow(x2 - 0, 2) + Math.pow(y2 - 0, 2));\n\n  return distance;\n}\n\nlet [activationThreshold, centerSensorX, centerSensorY] = securityProtocol(gothamMap, 3);\n\nconsole.table(gothamMap);\nconsole.log(`Coordenadas del centro de la amenaza: ${centerSensorX}, ${centerSensorY}`);\nconsole.log(`Suma de amenazas: ${activationThreshold}`);\nconsole.log(`Distancia desde la Baticueva: ${calculateDistance(centerSensorX, centerSensorY)}`);\n\nif (activationThreshold >= 20) {\n  console.log('\\nActivando el procolo de seguridad...');\n} else {\n  console.log('\\nEl protocolo de seguridad no será activado.');\n}\n"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/javascript/RicJDev.js",
    "content": "/*\n  EJERCICIO:\n\n  @RicJDev\n*/\n\nconsole.log('RETO 1: Día de Batman.')\n\n// Nos creamos una función que generará un día de Batman para el año que le pasemos como parámetro.\n\nfunction getBatmanDay(year = 2014) {\n  let day = 1,\n    date = new Date(year, 8, day)\n\n  while (date.getDay() !== 6) {\n    day++\n    date = new Date(year, 8, day)\n  }\n\n  date = new Date(year, 8, day + 14)\n\n  return date\n}\n\n// Luego mostramos los días de Batman de los siguientes 15 años. El último será el aniversario 100.\n\nconsole.log(' ')\n\nlet currentYear = 2024\nconst creationYear = 1939\n\nwhile (currentYear - creationYear <= 100) {\n  const aniversary = currentYear - creationYear\n\n  console.log(`${getBatmanDay(currentYear).toLocaleDateString()}. ${aniversary} aniversario.`)\n\n  currentYear++\n}\n\nconsole.log('\\nRETO 2: El Bati-sistema de seguridad.')\n\n// Creamos nuestro tablero de 20x20 que representará a Gotham City. Inicialmente todos los cuadros tendran un nivel de amenaza 0.\n\nconst GothamCity = Array(20)\n\nfor (let i = 0; i < GothamCity.length; i++) {\n  GothamCity[i] = Array(20).fill(0)\n}\n\n/*\n    Creamos una función que reciba una lista con los reportes de amenazas.\n\n    Debido a que en JavaScript no hay tuplas, las simularemos con arrays.\n    Cada reporte tendrá tres valores: [coordenada y, coordenada x, nivel de amenaza]\n\n    Usaremos esto para ubicar y asignar el valor de cada amenaza dentro de nuestro GothamCity.\n*/\n\nfunction updateCityStatus(reports) {\n  reports.forEach((report) => {\n    const [y, x, level] = report\n\n    GothamCity[y][x] = level\n  })\n}\n\nconst reports = [\n  [4, 5, 9],\n  [2, 8, 5],\n  [4, 10, 8],\n  [0, 19, 10],\n  [1, 16, 8],\n  [15, 1, 9],\n  [12, 2, 9],\n  [2, 5, 5],\n  [17, 9, 6],\n  [1, 16, 7],\n  [9, 4, 8],\n  [10, 5, 10],\n  [10, 6, 10],\n  [2, 9, 6],\n  [7, 15, 8],\n  [1, 9, 2],\n  [17, 3, 4],\n]\n\nupdateCityStatus(reports)\n\n// Esta función copia 'áreas' de 3x3 del mapa según las coordenadas que le pasemos.\n\nfunction getArea(y, x) {\n  const area = []\n\n  for (let i = 0; i < 3; i++) area.push(GothamCity[y + i].slice(x, x + 3))\n\n  return area\n}\n\n// Para obtener el nivel de amenaza (la sumatoria total) de cada área tendremos la siguiente función.\n\nfunction getThreatLevelOf(area) {\n  const total = []\n\n  area.forEach((row) => total.push(row.reduce((counter, value) => counter + value)))\n\n  return total.reduce((counter, value) => counter + value)\n}\n\n/*\n    Finalmente creamos una función para escanear toda la ciudad.\n\n    Esta devuelve un objeto con las siguientes claves:\n    - level: la sumatoria de los sensores de área.\n    - coords: las coordenadas del centro de área ( [coordenada y, coordenada x] ).\n*/\n\nfunction scanCity() {\n  const result = { level: 0, coords: [0, 0] }\n\n  for (let i = 0; i < GothamCity.length - 3; i++) {\n    for (let j = 0; j < GothamCity[0].length - 3; j++) {\n      const area = getArea(i, j),\n        level = getThreatLevelOf(area)\n\n      if (level > result.level) {\n        result.level = level\n        result.coords = [i + 1, j + 1]\n      }\n    }\n  }\n\n  return result\n}\n\n/*\n    Implementamos esto en nuestro sistema de seguridad.\n\n    Al pasar el umbral, Batman se dirige a la zona y empieza a repartir putazos (actualizando los valores a cero en esa área).\n*/\n\nfunction securitySystem() {\n  const { level, coords } = scanCity(),\n    [y, x] = coords\n\n  console.log('Analizando ciudad en busca de amenazas potenciales...')\n\n  //prettier-ignore\n  console.log(\n    `Se ha detectado un nivel de amenaza ${level} en las coordenadas (${x}, ${y}), a ${x + y} kilómetros de la Bati-cueva.`\n  )\n\n  if (level < 20) {\n    console.log(`No supera el umbral de amenaza. No se ha activado el protocolo de seguridad.`)\n    return\n  }\n\n  console.log('El protocolo de seguridad ha sido activado. Batman está en camino.')\n\n  for (let i = y - 1; i < y + 2; i++) {\n    for (let j = x - 1; j < x + 2; j++) {\n      GothamCity[i][j] = 0\n    }\n  }\n}\n\nconsole.log(' ')\nsecuritySystem()\n\nconsole.log(' ')\nsecuritySystem()\n"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/javascript/hectorio23.js",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\n\n//////////////////////////////////////////////////\n///////////////////// RETO 1 /////////////////////\n//////////////////////////////////////////////////\n\nfunction calculateBatmanDay() {\n    const currentYear = new Date().getFullYear();\n    for (let year = currentYear; year <= 2039; year++) {\n        const septemberFirst = new Date(year, 8, 1);  // Mes 8 es septiembre\n        const dayOfWeek = septemberFirst.getDay();\n        const thirdSaturday = new Date(septemberFirst);\n        thirdSaturday.setDate(septemberFirst.getDate() + ((5 - dayOfWeek + 7) % 7) + 14);\n        console.log(`Batman Day ${year}: ${thirdSaturday.toISOString().slice(0, 10)}`);\n    }\n}\n\ncalculateBatmanDay();\n\n\n//////////////////////////////////////////////////\n///////////////////// RETO 2 /////////////////////\n//////////////////////////////////////////////////\n\nfunction batcaveSecuritySystem(sensors) {\n    const gridSize = 20;\n    const threshold = 20;\n    let maxThreat = 0;\n    let criticalArea = null;\n\n    // Analizar todas las áreas de 3x3 en la cuadrícula\n    for (let i = 0; i <= gridSize - 3; i++) {\n        for (let j = 0; j <= gridSize - 3; j++) {\n            let threatSum = 0;\n            for (let x = i; x < i + 3; x++) {\n                for (let y = j; y < j + 3; y++) {\n                    threatSum += sensors[`${x},${y}`] || 0;\n                }\n            }\n            if (threatSum > maxThreat) {\n                maxThreat = threatSum;\n                criticalArea = [i + 1, j + 1];  // Centro de la cuadrícula\n            }\n        }\n    }\n\n    // Calcular distancia desde la Batcueva (0, 0)\n    if (criticalArea) {\n        const distance = Math.abs(criticalArea[0]) + Math.abs(criticalArea[1]);\n        console.log(`Área más amenazada: ${criticalArea}, Amenazas: ${maxThreat}, Distancia a la Batcueva: ${distance}`);\n        if (maxThreat > threshold) {\n            console.log('Protocolo de seguridad activado.');\n        }\n    }\n}\n\n// Ejemplo de sensores\nconst sensors = {\n    '5,5': 8, '5,6': 7, '5,7': 6,\n    '6,5': 9, '6,6': 5, '6,7': 4,\n    '7,5': 3, '7,6': 2, '7,7': 10\n};\n\nbatcaveSecuritySystem(sensors);\n\n\n"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n_______________________________________________________\n#39 BATMAN DAY\n-------------------------------------------------------\n* EJERCICIO:\n * Cada año se celebra el Batman Day durante la tercera semana de septiembre... \n * ¡Y este año cumple 85 años! Te propongo un reto doble:\n *\n * RETO 1:\n * Crea un programa que calcule cuándo se va a celebrar el Batman Day hasta \n * su 100 aniversario.\n *\n * RETO 2:\n * Crea un programa que implemente el sistema de seguridad de la Batcueva. \n * Este sistema está diseñado para monitorear múltiples sensores distribuidos\n * por Gotham, detectar intrusos y activar respuestas automatizadas. \n * Cada sensor reporta su estado en tiempo real, y Batman necesita un programa \n * que procese estos datos para tomar decisiones estratégicas.\n * Requisitos:\n * - El mapa de Gotham y los sensores se representa con una cuadrícula 20x20.\n * - Cada sensor se identifica con una coordenada (x, y) y un nivel\n *   de amenaza entre 0 a 10 (número entero).\n * - Batman debe concentrar recursos en el área más crítica de Gotham.\n * - El programa recibe un listado de tuplas representando coordenadas de los \n *   sensores y su nivel de amenaza. El umbral de activación del protocolo de\n *   seguridad es 20 (sumatorio de amenazas en una cuadrícula 3x3).\n * Acciones: \n * - Identifica el área con mayor concentración de amenazas\n *   (sumatorio de amenazas en una cuadrícula 3x3).\n * - Si el sumatorio de amenazas es mayor al umbral, activa el \n *   protocolo de seguridad.\n * - Calcula la distancia desde la Batcueva, situada en (0, 0). La distancia es\n *   la suma absoluta de las coordenadas al centro de la cuadrícula amenazada.\n * - Muestra la coordenada al centro de la cuadrícula más amenazada, la suma de\n *   sus amenazas, la distancia a la Batcueva y si se debe activar el\n *   protocolo de seguridad.\n */\n// ________________________________________________________\n// Reto #1\nconst getThirdSaturdayOfSeptember = (year) => {\n    const date = new Date(year, 8, 15); // Septiembre es el mes 8 (0-indexed)\n    const day = date.getDay();\n    const offset = (6 - day + 7) % 7; // Calcula el sábado más cercano\n    date.setDate(date.getDate() + offset);\n    return date.toISOString().slice(0, 10); // YYYY-MM-DD\n};\n\nconst anniversaryDates = (totalAnniversaries) => {\n    const batmanDayStart = 2014;\n    const currentYear = new Date().getFullYear();\n    if (currentYear < batmanDayStart) {\n        console.log(\"Batman Day aún no ha comenzado.\");\n        return;\n    }\n\n    const pastAnniversaries = currentYear - batmanDayStart;\n    console.log(`Aniversarios que ya han pasado: ${pastAnniversaries}`);\n    \n    for (let i = pastAnniversaries; i < totalAnniversaries; i++) {\n        const num = i + 1;\n        const date = getThirdSaturdayOfSeptember(currentYear + (i - pastAnniversaries));\n        console.log(`- Aniversario #${num}: ${date}`);\n    }\n};\n\nconsole.log(\"Batman Day\");\nanniversaryDates(100);\n\n\n// ________________________________________________________\n// Reto $2\nconst createMap = (size, batcave, sensors, threats) => {\n    const gotham = Array.from({ length: size[0] }, () => Array(size[1]).fill('| '));\n    gotham[batcave[0]][batcave[1]] = '|B';\n\n    sensors.forEach(([x, y]) => {\n        gotham[x][y] = '|S';\n    });\n\n    threats.forEach(([x, y]) => {\n        gotham[x][y] = '|T';\n    });\n\n    return gotham;\n};\n\nconst printMap = (gotham) => {\n    console.log(\"\\nMapa de Gotham:\");\n    gotham.forEach(row => console.log(row.join('')));\n};\n\nconst scanMap = (gotham, sensors) => {\n    const dangerList = sensors.map(([x, y, threat]) => {\n        let dangerCounter = 0;\n        for (let i = Math.max(0, x - 1); i <= Math.min(gotham.length - 1, x + 1); i++) {\n            for (let j = Math.max(0, y - 1); j <= Math.min(gotham[0].length - 1, y + 1); j++) {\n                if (gotham[i][j] === '|T') {\n                    dangerCounter += threat;\n                }\n            }\n        }\n        return { location: [x, y], danger: dangerCounter };\n    });\n\n    const maxDanger = dangerList.reduce((max, current) => (current.danger > max.danger ? current : max), { danger: 0 });\n\n    console.log(\"\\nInforme:\");\n    console.log(`Cuadrícula más amenazada: '${maxDanger.location[0]}, ${maxDanger.location[1]}'`);\n    console.log(`Máximo nivel de alerta: '${maxDanger.danger}'`);\n    if (maxDanger.danger >= 20) {\n        console.log(\"Protocolo de seguridad activado.\");\n        console.log(`Distancia: '${Math.abs(maxDanger.location[0]) + Math.abs(maxDanger.location[1])}'`);\n    } else {\n        console.log(\"No hay amenazas relevantes.\");\n    }\n};\n\nconst batcave = [0, 0];\nconst sensors = [\n    [2, 2, 10],\n    [6, 8, 9],\n    [10, 12, 8],\n    [17, 15, 7]\n];\nconst threats = [\n    [2, 3],\n    [2, 1],\n    [6, 9],\n    [17, 16],\n    [15, 4]\n];\n\nconst gotham = createMap([20, 20], batcave, sensors, threats);\nprintMap(gotham);\nscanMap(gotham, sensors);\n"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/javascript/miguelex.js",
    "content": "// RETO 1: \nfunction calcularBatmanDay(anioInicio, anioFinal) {\n    console.log(\"Fechas del Batman Day hasta su 100 aniversario:\");\n    for (let anio = anioInicio; anio <= anioFinal; anio++) {\n        let tercerSabado = new Date(anio, 8, 1); // Septiembre es el mes 8 (0-index)\n        tercerSabado.setDate(1 + (6 - tercerSabado.getDay() + 21) % 7); // Ajustar al tercer sábado\n        console.log(`Batman Day en el año ${anio}: ${tercerSabado.toLocaleDateString()}`);\n    }\n}\n\n// RETO 2: \nfunction activarSistemaSeguridad(sensores) {\n    const tamanoMapa = 20;\n    const umbralSeguridad = 20;\n    let mejorSumaAmenazas = 0;\n    let mejorCentro = null;\n\n    for (let i = 0; i <= tamanoMapa - 3; i++) {\n        for (let j = 0; j <= tamanoMapa - 3; j++) {\n            let sumaAmenazas = 0;\n            for (let x = i; x < i + 3; x++) {\n                for (let y = j; y < j + 3; y++) {\n                    sumaAmenazas += sensores[x][y];\n                }\n            }\n            if (sumaAmenazas > mejorSumaAmenazas) {\n                mejorSumaAmenazas = sumaAmenazas;\n                mejorCentro = [i + 1, j + 1];\n            }\n        }\n    }\n    if (mejorCentro) {\n        const distanciaABatcueva = Math.abs(mejorCentro[0]) + Math.abs(mejorCentro[1]);\n        console.log(`\\nÁrea más amenazada en coordenadas (${mejorCentro[0]}, ${mejorCentro[1]})`);\n        console.log(`Suma de amenazas: ${mejorSumaAmenazas}`);\n        console.log(`Distancia a la Batcueva: ${distanciaABatcueva}`);\n        \n        if (mejorSumaAmenazas > umbralSeguridad) {\n            console.log(\"¡Protocolo de seguridad activado!\");\n        } else {\n            console.log(\"Protocolo de seguridad NO activado.\");\n        }\n    }\n}\n\n// Ejecutar el reto 1\nconst anioInicio = 2024;\nconst anioFinal = 2024 + (100 - 85);\ncalcularBatmanDay(anioInicio, anioFinal);\n\n// Ejecutar el reto 2\nlet sensores = Array.from({ length: 20 }, () => Array.from({ length: 20 }, () => Math.floor(Math.random() * 11)));\nactivarSistemaSeguridad(sensores);\n"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/javascript/pedamoci.js",
    "content": "/* -------------------------- RETO 1 -------------------------- */\nfunction getBatmanDay(year) {\n  const date = new Date(`September 1, ${year} 12:00:00`)\n\n  const day = 21 - date.getDay()\n\n  return day \n}\n\nfunction celebrateBatmanDay() {\n  let numberOfYearsCelebrated = 85\n  let year = 2024\n\n  while (numberOfYearsCelebrated <= 100) {\n    const batmanDay = getBatmanDay(year)\n\n    console.log(`In ${year}, Batman Day will be ${numberOfYearsCelebrated} years old and will be celebrated on September ${batmanDay}\\n`)\n\n    year++\n    numberOfYearsCelebrated++\n  }\n}\n\ncelebrateBatmanDay()\n\n/* -------------------------- RETO 2 -------------------------- */\nconst colors = {\n  red: \"\\x1b[31m\",\n  green: \"\\x1b[32m\",\n  yellow: \"\\x1b[33m\",\n  cyan: \"\\x1b[34m\",\n  reset: \"\\x1b[0m\",\n}\n\nclass Renderer {\n  static error(message) {\n    console.log(colors.red + \"Error: \" + message + colors.reset)\n  }\n\n  static success(message) {\n    console.log(colors.green + \"Success: \" + message + colors.reset)\n  }\n\n  static info(info) {\n    console.log(info + colors.reset)\n  }\n}\n\nclass Creator {\n  constructor() {\n    this.map = []\n    this.txt = \"\"\n  }\n\n  crateMap(dimensions) {\n    for (let row = 0; row < dimensions; row++) {\n      this.map.push([])\n      for (let column = 0; column < dimensions; column++) {\n        this.map[row].push(0)\n      }\n    }\n\n    return this.map\n  }\n\n  createTXT(info) {\n    this.txt += `Coordinates of the most threatened area: X = ${info.coords[0]}  Y = ${info.coords[1]}`\n    this.txt += `\\nSums of threats: ${info.threatValues.join(\" + \")}`\n    this.txt += `\\nDistance from the Batcave to the center of the threat: ${info.coords[0] + info.coords[1]}`\n\n    return this.txt\n  }\n}\n\nclass Sensors {\n  constructor() {\n    this.report = []\n  }\n\n  theartLevelReport(map) {\n    const rows = map.length\n    const columns = map[0].length\n\n    for (let row = 0; row < rows; row++) {\n      for (let column = 0; column < columns; column++) {\n        this.report.push([column, row, Math.floor(Math.random() * 11)])\n      }\n      \n    }\n\n    return this.report\n  }\n}\n\nclass Analyzer {\n  constructor() {\n    this.greatestThreat = {threat: 0, threatValues: [], coords: [0, 0]}\n  }\n\n  analyzeThreatLevel(report, dimensions) {\n    for (let row = 0; row < dimensions - 2; row++) {\n      for (let column = 0; column < dimensions - 2; column++) {\n        const levelThreat = (report[row * dimensions + column][2] + report[row * dimensions + column + 1][2] + report[row * dimensions + column + 2][2] +\n                            report[(row + 1) * dimensions + column][2] + report[(row + 1) * dimensions + column + 1][2] + report[(row + 1) * dimensions + column + 2][2] +\n                            report[(row + 2) * dimensions + column][2] + report[(row + 2) * dimensions + column + 1][2] + report[(row + 2) * dimensions + column + 2][2])\n\n        if (levelThreat > this.greatestThreat.threat) {\n          this.greatestThreat.threat = levelThreat\n          this.greatestThreat.threatValues = [report[row * dimensions + column][2], report[row * dimensions + column + 1][2], report[row * dimensions + column + 2][2],\n                                              report[(row + 1) * dimensions + column][2], report[(row + 1) * dimensions + column + 1][2], report[(row + 1) * dimensions + column + 2][2],\n                                              report[(row + 2) * dimensions + column][2], report[(row + 2) * dimensions + column + 1][2], report[(row + 2) * dimensions + column + 2][2]]\n          this.greatestThreat.coords = [column + 1, row + 1]\n        }\n      }\n    }\n\n    return this.greatestThreat\n  }\n}\n\nclass Controller {\n  constructor(creator, sensors, analyzer) {\n    this.creator = creator\n    this.sensors =sensors\n    this.analyzer = analyzer\n    this.dimensions = 20\n  }\n\n  start() {\n    const map = this.creator.crateMap(this.dimensions)\n\n    const report = this.sensors.theartLevelReport(map)\n\n    const greatestThreat = this.analyzer.analyzeThreatLevel(report, this.dimensions)\n\n    const txt = this.creator.createTXT(greatestThreat)\n\n    Renderer.info(colors.yellow + txt)\n\n    if (greatestThreat.threat >= 20)\n      Renderer.info(colors.red + `\\nThe threat level is ${greatestThreat.threat}, activate security protocol`)\n  }\n}\n\nconst controller = new Controller(new Creator(), new Sensors(), new Analyzer())\ncontroller.start()"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/kotlin/blackriper.kt",
    "content": "\r\nimport java.time.DayOfWeek\r\nimport java.time.LocalDate\r\nimport java.time.format.DateTimeFormatter\r\nimport java.time.temporal.IsoFields\r\nimport kotlin.math.abs\r\n\r\n\r\n/*\r\nReto 1\r\nA partir de 2015, se estableció que el tercer sábado de septiembre sería la fecha oficial para celebrar el Batman Day en todo el mundo\r\n**/\r\nfun getWeekNameAndNum(date: String): Pair<DayOfWeek, Int>{\r\n    val dt= LocalDate.parse(date,DateTimeFormatter.ofPattern(\"dd/MM/yyyy\"))\r\n    val numWeek=dt.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR)\r\n    return Pair(dt.dayOfWeek,numWeek)\r\n}\r\n\r\nfun calculateCenturyBatmanDay(){\r\n    var anniversary=85\r\n    var year= LocalDate.now().year\r\n\r\n    while (anniversary<=100){\r\n        for (i in 1..30){\r\n            val day=if (i<10) \"0$i\" else \"$i\"\r\n            val date=getWeekNameAndNum(\"$day/09/$year\")\r\n            if (date.first== DayOfWeek.SATURDAY && date.second==38){\r\n                println(\"Batman's ${anniversary}th anniversary of the year $year is on $day/09/$year\")\r\n            }\r\n        }\r\n        anniversary++\r\n        year++\r\n    }\r\n\r\n}\r\n\r\n\r\n//reto 2\r\n\r\nconst val GOTHAM_MAP=20\r\nconst val MAX_UMBRAL=20\r\n\r\n\r\n\r\ndata class Sensor constructor(\r\n    var nameSector: String=\"\",\r\n    var postionX: Int=0,\r\n    var postionY: Int=0,\r\n    var warningLevel: Int=0,\r\n    var sumThreat: Int=0\r\n)\r\n\r\nfun sensor(block: Sensor.()-> Unit):Sensor =Sensor().apply(block)\r\n\r\n\r\nfun calculateSumThreat(sensor:Sensor): Int {\r\n    var sum=0\r\n   for (i in sensor.postionX-1..sensor.postionX+1){\r\n       for (j in sensor.postionY-1..sensor.postionY+1){\r\n           if (i>=0 && i<GOTHAM_MAP && j>=0 && j<GOTHAM_MAP) sum+=sensor.warningLevel\r\n\r\n       }\r\n   }\r\n    return sum\r\n}\r\n\r\nfun scanningSensors(sensors: List<Sensor>){\r\n    sensors.forEach {\r\n         it.sumThreat=calculateSumThreat(it)\r\n      \r\n\r\n    }\r\n    val criticalZone=sensors.maxByOrNull { it.sumThreat }\r\n    if (criticalZone!=null){\r\n        val center= Triple(criticalZone.nameSector,criticalZone.postionX,criticalZone.postionY)\r\n        val distance= abs(center.second)+abs(center.third)\r\n        println(\"El sector mas peligroso es ${center.first} ubicado en [${center.second},${center.third}]\")\r\n        println(\"El sector ${center.first} se encuentra a una distancia de $distance de la baticueva\")\r\n        if (criticalZone.sumThreat>MAX_UMBRAL) println(\"Protocolo de seguridad Activado\")\r\n        else println(\"Protocolo de seguridad no Activado\")\r\n\r\n    }\r\n}\r\n\r\nfun readGotham(){\r\n    val sensors=listOf(\r\n        sensor {\r\n            nameSector=\"Distrito Diamante\"\r\n            postionX=3\r\n            postionY=3\r\n            warningLevel=5\r\n        },\r\n        sensor {\r\n            nameSector=\"Iceberg Lounge\"\r\n            postionX=12\r\n            postionY=12\r\n            warningLevel=7\r\n        },\r\n        sensor {\r\n            nameSector=\"Gotica Bank\"\r\n            postionX=4\r\n            postionY=4\r\n            warningLevel=8\r\n        }\r\n    )\r\n\r\n    scanningSensors(sensors)\r\n}\r\n\r\n\r\n\r\n\r\nfun main() {\r\n  calculateCenturyBatmanDay()\r\n  readGotham()\r\n }"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/php/miguelex.php",
    "content": "<?php\n\n// RETO 1: \nfunction calcularBatmanDay($anioInicio, $anioFinal) {\n    echo \"Fechas del Batman Day hasta su 100 aniversario:\\n\";\n    for ($anio = $anioInicio; $anio <= $anioFinal; $anio++) {\n        $tercerSabado = new DateTime(\"third saturday of september $anio\");\n        echo \"Batman Day en el año $anio: \" . $tercerSabado->format('d-m-Y') . \"\\n\";\n    }\n}\n\n$anioInicio = 2024;\n$anioFinal = 2024 + (100 - 85); \ncalcularBatmanDay($anioInicio, $anioFinal);\n\n\n// RETO 2\nfunction activarSistemaSeguridad($sensores) {\n    $tamanoMapa = 20;\n    $umbralSeguridad = 20;\n    $mejorSumaAmenazas = 0;\n    $mejorCentro = null;\n\n    for ($i = 0; $i <= $tamanoMapa - 3; $i++) {\n        for ($j = 0; $j <= $tamanoMapa - 3; $j++) {\n            $sumaAmenazas = 0;\n            for ($x = $i; $x < $i + 3; $x++) {\n                for ($y = $j; $y < $j + 3; $y++) {\n                    $sumaAmenazas += $sensores[$x][$y];\n                }\n            }\n\n            if ($sumaAmenazas > $mejorSumaAmenazas) {\n                $mejorSumaAmenazas = $sumaAmenazas;\n                $mejorCentro = [$i + 1, $j + 1]; // Centro de la cuadrícula\n            }\n        }\n    }\n\n    if ($mejorCentro) {\n        $distanciaABatcueva = abs($mejorCentro[0]) + abs($mejorCentro[1]);\n        echo \"\\nÁrea más amenazada en coordenadas (\" . $mejorCentro[0] . \", \" . $mejorCentro[1] . \")\\n\";\n        echo \"Suma de amenazas: $mejorSumaAmenazas\\n\";\n        echo \"Distancia a la Batcueva: $distanciaABatcueva\\n\";\n\n        if ($mejorSumaAmenazas > $umbralSeguridad) {\n            echo \"¡Protocolo de seguridad activado!\\n\";\n        } else {\n            echo \"Protocolo de seguridad NO activado.\\n\";\n        }\n    }\n}\n\n$sensores = [];\nfor ($i = 0; $i < 20; $i++) {\n    for ($j = 0; $j < 20; $j++) {\n        $sensores[$i][$j] = rand(0, 10);\n    }\n}\n\nactivarSistemaSeguridad($sensores);\n\n\n"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/python/CarlosVR48.py",
    "content": "\"\"\"* EJERCICIO:\n * Cada año se celebra el Batman Day durante la tercera semana de septiembre... \n * ¡Y este año cumple 85 años! Te propongo un reto doble:\n *\n * RETO 1:\n * Crea un programa que calcule cuándo se va a celebrar el Batman Day hasta \n * su 100 aniversario.\n *\n * RETO 2:\n * Crea un programa que implemente el sistema de seguridad de la Batcueva. \n * Este sistema está diseñado para monitorear múltiples sensores distribuidos\n * por Gotham, detectar intrusos y activar respuestas automatizadas. \n * Cada sensor reporta su estado en tiempo real, y Batman necesita un programa \n * que procese estos datos para tomar decisiones estratégicas.\n * Requisitos:\n * - El mapa de Gotham y los sensores se representa con una cuadrícula 20x20.\n * - Cada sensor se identifica con una coordenada (x, y) y un nivel\n *   de amenaza entre 0 a 10 (número entero).\n * - Batman debe concentrar recursos en el área más crítica de Gotham.\n * - El programa recibe un listado de tuplas representando coordenadas de los \n *   sensores y su nivel de amenaza. El umbral de activación del protocolo de\n *   seguridad es 20 (sumatorio de amenazas en una cuadrícula 3x3).\n * Acciones: \n * - Identifica el área con mayor concentración de amenazas\n *   (sumatorio de amenazas en una cuadrícula 3x3).\n * - Si el sumatorio de amenazas es mayor al umbral, activa el \n *   protocolo de seguridad.\n * - Calcula la distancia desde la Batcueva, situada en (0, 0). La distancia es\n *   la suma absoluta de las coordenadas al centro de la cuadrícula amenazada.\n * - Muestra la coordenada al centro de la cuadrícula más amenazada, la suma de\n *   sus amenazas, la distancia a la Batcueva y si se debe activar el\n *   protocolo de seguridad.\"\"\"\n\n\nfrom os import system\nimport random,time\nimport calendar\n\nprint (\"PRIMER EJERCICIO PARA CALCULAR EL DIA DEL 100 ANIVERSARIO DE BATMAN DAY\")\n#calculamos primero el año que sera el 100 aniversario\nyear = ((100-85)+2024)\n#introducimos el mes que es el aniversario\nmes = 9\n#calculamos el calendario de ese mes y mostramos el numero de semanas\nlista_mes = calendar.monthcalendar(year,mes)\nprint (\"NUMERO DE SEMANAS QUE TIENE EL MES: \",len(lista_mes))\n#introducimos la semana que sera el aniversario\nsemana_aniversario = 3\n#muetra calendario\nfor index in lista_mes:\n    print (index)\n#guardamos el dia del aniversario y lo mostramos\ndia_aniversario = lista_mes [semana_aniversario-1] [0]\nprint (f\"EL 100 ANIVERSARIO SERA {dia_aniversario} - {mes} - {year}\" )\ninput (\"PULSA ENTER PARA CONTINUAR\")\n\nsalir = \"\"\n\nmapa = [[\"🦇\",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \"],\n        [\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \"],\n        [\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \"],\n        [\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \"],\n        [\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \"],\n        [\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \"],\n        [\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \"],\n        [\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \"],\n        [\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \"],\n        [\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \"],\n        [\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \"],\n        [\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \"],\n        [\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \"],\n        [\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \"],\n        [\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \"],\n        [\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \"],\n        [\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \"],\n        [\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \"],\n        [\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \"],\n        [\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \",\" \"],\n        ]\n\n#funcion que se le tiene que dar parametros numero de sensor, posicion central del \n#sensor y el nivel de cada casilla del sensor\n\ndef sensor_3x3(posicion,x,y,a,b,c,d,e,f,g,h,i):\n    index = x\n    indey = y\n    #obtengo las codenadas de cada casilla del sensor\n    xa1 = index - 1\n    xa2 = index\n    xa3 = index + 1\n    ya = indey - 1\n    yb = indey\n    yc = indey +1\n\n    monitor = (posicion,xa1,xa2,xa3,ya,yb,yc,a,b,c,d,e,f,g,h,i)\n    protocolo = ((monitor [7] + monitor [8] + monitor [9] + monitor [10] + monitor [11] + monitor [12] + monitor [13] + monitor [14] + monitor [15]))\n    \n    #para cada casilla de sensor 3x3 muestro si su nivel es alto o bajo a partir de 7\n    if monitor [7] >=7:\n        aa = (\"ALTO\")\n    else:\n        aa = (\"BAJO\")\n    if monitor [8] >=7:\n        ab = (\"ALTO\")\n    else:\n        ab = (\"BAJO\")\n    if monitor [9] >=7:\n        ac = (\"ALTO\")\n    else:\n        ac = (\"BAJO\")\n\n    if monitor [10] >=7:\n        ba = (\"ALTO\")\n    else:\n        ba = (\"BAJO\")\n    if monitor [11] >=7:\n        bb = (\"ALTO\")\n    else:\n        bb = (\"BAJO\")\n    if monitor [12] >=7:\n        bc = (\"ALTO\")\n    else:\n        bc = (\"BAJO\")\n    \n    if monitor [13] >=7:\n        ca = (\"ALTO\")\n    else:\n        ca = (\"BAJO\")\n    if monitor [14] >=7:\n        cb = (\"ALTO\")\n    else:\n        cb = (\"BAJO\")\n    if monitor [15] >=7:\n        cc = (\"ALTO\")\n    else:\n        cc = (\"BAJO\")\n    \n    #muestro por pantalla cada sensor\n    print (f\"{monitor [0]}  {type(monitor)} \")\n    print (f\"X: {monitor [1]} Y: {monitor [4]} | X: {monitor [2]} Y: {monitor [4]} | X: {monitor [3]} Y: {monitor [4]}\")  \n    print (f\"NIVEL: {monitor [7]}      NIVEL: {monitor [8]}      NIVEL: {monitor [9]}\")\n    print (f\"{aa}          {ab}          {ac} \")\n    print (f\"\\nX: {monitor [1]} Y: {monitor [5]} | X: {monitor [2]} Y: {monitor [5]} | X: {monitor [3]} Y: {monitor [5]}\")  \n    print (f\"NIVEL: {monitor [10]}     NIVEL: {monitor [11]}      NIVEL: {monitor [12]}\")\n    print (f\"{ba}          {bb}         {bc} \")\n    print (f\"\\nX: {monitor [1]} Y: {monitor [6]} | X: {monitor [2]} Y: {monitor [6]} | X: {monitor [3]} Y: {monitor [6]}\")  \n    print (f\"NIVEL: {monitor [13]}      NIVEL: {monitor [14]}      NIVEL: {monitor [15]}\")\n    print (f\"{ca}          {cb}          {cc} \")\n    \n    #el umbral de activacioon para el sensor tiene que ser 20 o mas \n    if protocolo >= 20:\n        print (f\"\\nLA SUMA DE TODAS LAS CASILLAS ES {protocolo}\")\n        print (\"MAYOR O IGUAL A 20 PROTOCOLO ACTIVADO \\n\")\n        print (\"───────────────────────────────────────────────\")\n    else:\n        print (f\"\\nLA SUMA DE TODAS  LAS CASILLAS ES {protocolo}\")\n        print (\"MENOR DE 20 PROTOCOLO DESACTIVADO\\n\")\n        print (\"───────────────────────────────────────────────\")\n\n#inicio del programa que se repite hasta que escribamos salir \nwhile not(salir == \"SALIR\"):\n    system(\"cls\")\n    cantidad_sensores = 1\n   \n    #creo 6 sensores en el bucle while\n    while cantidad_sensores<7:\n        suma_sensor = int()\n        sensor_a = []\n        sensor_b = []\n        sensor_c = []\n        #creador de nivel de alerta en el sensor para cada casilla 3x3\n        for index1 in range(3):\n            sensor_a.append(random.randint(1,10))\n        for index1 in range(3):\n            sensor_b.append(random.randint(1,10))    \n        for index1 in range(3):\n            sensor_c.append(random.randint(1,10))\n\n        #suma todos los sensores de la cuadricula 3x3 y los gurdo sumar_sensor\n        for index_a,index_b,index_c in (sensor_a,sensor_b,sensor_c):\n            suma_sensor = suma_sensor + index_a + index_b + index_c\n        \n        #segun el numero de sensor lo muestro en las cordenadas y escribo\n        #la lista con numero de senso, cordenadas y distancia.\n        #llamo a la funcion sensor_3x3 para monitorear el sensor\n        if cantidad_sensores == 1:    \n            mapa [4] [2] = str(sensor_a[0])\n            mapa [4] [3] = str(sensor_a[1])\n            mapa [4] [4] = str(sensor_a[2])\n            mapa [5] [2] = str(sensor_b[0])\n            mapa [5] [3] = str(sensor_b[1])\n            mapa [5] [4] = str(sensor_b[2])\n            mapa [6] [2] = str(sensor_c[0])\n            mapa [6] [3] = str(sensor_c[1])\n            mapa [6] [4] = str(sensor_c[2])\n            mostrar_sensor1 = [suma_sensor,3,5,\"Distancia: 8\"]\n            \n            x = mostrar_sensor1 [1]\n            y = mostrar_sensor1 [2]\n            a = sensor_a [0]\n            b = sensor_a [1]\n            c = sensor_a [2]\n            d = sensor_b [0]\n            e = sensor_b [1]\n            f = sensor_b [2]\n            g = sensor_c [0]\n            h = sensor_c [1]\n            i = sensor_c [2]\n            sensor_3x3(cantidad_sensores,x,y,a,b,c,d,e,f,g,h,i)\n\n        if cantidad_sensores == 2:    \n            mapa [1] [9] = str(sensor_a[0])\n            mapa [1] [10] = str(sensor_a[1])\n            mapa [1] [11] = str(sensor_a[2])\n\n            mapa [2] [9] = str(sensor_b[0])\n            mapa [2] [10] = str(sensor_b[1])\n            mapa [2] [11] = str(sensor_b[2])\n\n            mapa [3] [9] = str(sensor_c[0])\n            mapa [3] [10] = str(sensor_c[1])\n            mapa [3] [11] = str(sensor_c[2])    \n            mostrar_sensor2 = [suma_sensor,10,2,\"Distancia: 12\"]\n            \n            x = mostrar_sensor2 [1]\n            y = mostrar_sensor2 [2]\n            a = sensor_a [0]\n            b = sensor_a [1]\n            c = sensor_a [2]\n            d = sensor_b [0]\n            e = sensor_b [1]\n            f = sensor_b [2]\n            g = sensor_c [0]\n            h = sensor_c [1]\n            i = sensor_c [2]\n            sensor_3x3(cantidad_sensores,x,y,a,b,c,d,e,f,g,h,i)\n\n        if cantidad_sensores == 3:    \n            mapa [4] [15] = str(sensor_a[0])\n            mapa [4] [16] = str(sensor_a[1])\n            mapa [4] [17] = str(sensor_a[2])\n\n            mapa [5] [15] = str(sensor_b[0])\n            mapa [5] [16] = str(sensor_b[1])\n            mapa [5] [17] = str(sensor_b[2])\n\n            mapa [6] [15] = str(sensor_c[0])\n            mapa [6] [16] = str(sensor_c[1])\n            mapa [6] [17] = str(sensor_c[2])\n            mostrar_sensor3 = [suma_sensor,16,5,\"Distancia: 21\"]\n\n            x = mostrar_sensor3 [1]\n            y = mostrar_sensor3 [2]\n            a = sensor_a [0]\n            b = sensor_a [1]\n            c = sensor_a [2]\n            d = sensor_b [0]\n            e = sensor_b [1]\n            f = sensor_b [2]\n            g = sensor_c [0]\n            h = sensor_c [1]\n            i = sensor_c [2]\n            sensor_3x3(cantidad_sensores,x,y,a,b,c,d,e,f,g,h,i)\n\n        if cantidad_sensores == 4:    \n            mapa [11] [9] = str(sensor_a[0])\n            mapa [11] [10] = str(sensor_a[1])\n            mapa [11] [11] = str(sensor_a[2])\n\n            mapa [12] [9] = str(sensor_b[0])\n            mapa [12] [10] = str(sensor_b[1])\n            mapa [12] [11] = str(sensor_b[2])\n\n            mapa [13] [9] = str(sensor_c[0])\n            mapa [13] [10] = str(sensor_c[1])\n            mapa [13] [11] = str(sensor_c[2])\n            mostrar_sensor4 = [suma_sensor,10,12,\"Distancia: 21\"]\n\n            x = mostrar_sensor4 [1]\n            y = mostrar_sensor4 [2]\n            a = sensor_a [0]\n            b = sensor_a [1]\n            c = sensor_a [2]\n            d = sensor_b [0]\n            e = sensor_b [1]\n            f = sensor_b [2]\n            g = sensor_c [0]\n            h = sensor_c [1]\n            i = sensor_c [2]\n            sensor_3x3(cantidad_sensores,x,y,a,b,c,d,e,f,g,h,i)\n\n        if cantidad_sensores == 5:    \n            mapa [16] [2] = str(sensor_a[0])\n            mapa [16] [3] = str(sensor_a[1])\n            mapa [16] [4] = str(sensor_a[2])\n\n            mapa [17] [2] = str(sensor_b[0])\n            mapa [17] [3] = str(sensor_b[1])\n            mapa [17] [4] = str(sensor_b[2])\n\n            mapa [18] [2] = str(sensor_c[0])\n            mapa [18] [3] = str(sensor_c[1])\n            mapa [18] [4] = str(sensor_c[2])\n            mostrar_sensor5 = [suma_sensor,3,17,\"Distancia: 20\"]\n\n            x = mostrar_sensor5 [1]\n            y = mostrar_sensor5 [2]\n            a = sensor_a [0]\n            b = sensor_a [1]\n            c = sensor_a [2]\n            d = sensor_b [0]\n            e = sensor_b [1]\n            f = sensor_b [2]\n            g = sensor_c [0]\n            h = sensor_c [1]\n            i = sensor_c [2]\n            sensor_3x3(cantidad_sensores,x,y,a,b,c,d,e,f,g,h,i)\n\n        if cantidad_sensores == 6:    \n            mapa [16] [15] = str(sensor_a[0])\n            mapa [16] [16] = str(sensor_a[1])\n            mapa [16] [17] = str(sensor_a[2])\n\n            mapa [17] [15] = str(sensor_b[0])\n            mapa [17] [16] = str(sensor_b[1])\n            mapa [17] [17] = str(sensor_b[2])\n\n            mapa [18] [15] = str(sensor_c[0])\n            mapa [18] [16] = str(sensor_c[1])\n            mapa [18] [17] = str(sensor_c[2])\n            mostrar_sensor6 = [suma_sensor,16,17,\"Distancia: 33\"]\n\n            x = mostrar_sensor6 [1]\n            y = mostrar_sensor6[2]\n            a = sensor_a [0]\n            b = sensor_a [1]\n            c = sensor_a [2]\n            d = sensor_b [0]\n            e = sensor_b [1]\n            f = sensor_b [2]\n            g = sensor_c [0]\n            h = sensor_c [1]\n            i = sensor_c [2]\n            sensor_3x3(cantidad_sensores,x,y,a,b,c,d,e,f,g,h,i)\n\n        cantidad_sensores += 1\n\n    #Muestro por pantalla el mapa de Gotham\n    print (\"────────────────────────────────────────\")\n    for index in mapa: \n        print (\"|\".join(index))\n        print (\"────────────────────────────────────────\")\n    print()\n\n    #Busco el de la suma de sensores 3x3 el mas grande\n    s1 = mostrar_sensor1 [0]\n    s2 = mostrar_sensor2 [0]\n    s3 = mostrar_sensor3 [0]\n    s4 = mostrar_sensor4 [0]\n    s5 = mostrar_sensor5 [0]\n    s6 = mostrar_sensor6 [0]\n    \n    s7 = [s1,s2,s3,s4,s5,s6]\n    \n    if  s1 > s2 and  s1 > s3 and s1 > s4 and s1 > s5 and s1 > s6:\n        if s7.count(s1) == 1:\n            print (f\"\\nEL NIVEL DE ALERTA SENSOR 1 ES EL MAS ALTO: {mostrar_sensor1 [0] }.\")\n            print (f\"LAS CORDENADAS SON X: {mostrar_sensor1 [1]}  Y; {mostrar_sensor1 [2]}.\")\n            print (f\"LA {mostrar_sensor1 [3]} Km.\")\n        else:\n            print (\"DOS SENSORES O MAS ESTAN MIDIENDO LO MISMO, REFRESCA LA PANTALLA.\")\n\n    elif s2 > s3 and s2 > s4 and s2 > s5 and s2 > s6:\n        if s7.count(s2) == 1:\n            print (f\"\\nEL NIVEL DE ALERTA SENSOR 2 ES EL MAS ALTO: {mostrar_sensor2 [0]}.\")\n            print (f\"LAS CORDENADAS SON X: {mostrar_sensor2 [1] }  Y: {mostrar_sensor2 [2]}.\")\n            print (f\"La {mostrar_sensor2 [3] } Km.\")\n        else:\n            print (\"DOS SENSORES O MAS ESTAN MIDIENDO LO MISMO, REFRESCA LA PANTALLA.\")\n\n    elif s3 > s4 and s3 > s5 and s3 > s6:\n        if s7.count(s3) == 1:\n            print (f\"\\nEL NIVEL DE ALERTA SENSOR 3 ES EL MAS ALTO: {mostrar_sensor3 [0]}.\")\n            print (f\"LAS CORDENADAS SON X: {mostrar_sensor3 [1]}  Y: {mostrar_sensor3 [2]}.\")\n            print (f\"La {mostrar_sensor3 [3]} Km.\")\n        else:\n            print (\"DOS SENSORES O MAS ESTAN MIDIENDO LO MISMO, REFRESCA LA PANTALLA.\")\n\n    elif s4 > s5 and s4 > s6:\n        if s7.count(s4) == 1:\n            print (f\"\\nEL NIVEL DE ALERTA SENSOR 4 ES EL MAS ALTO: {mostrar_sensor4 [0]}.\")\n            print (f\"LAS CORDENADAS SON X: {mostrar_sensor4 [1]}  Y: {mostrar_sensor4 [2]}.\")\n            print (f\"La {mostrar_sensor4 [3]} Km.\")\n        else:\n            print (\"DOS SENSORES O MAS ESTAN MIDIENDO LO MISMO, REFRESCA LA PANTALLA.\")\n\n    elif s5 > s6:\n        if s7.count(s5) == 1:\n            print (f\"\\nEL NIVEL DE ALERTA SENSOR 5 ES EL MAS ALTO: {mostrar_sensor5 [0]}.\")\n            print (f\"LAS CORDENADAS SON X: {mostrar_sensor5 [1]}  Y: {mostrar_sensor5 [2]}.\")\n            print (f\"La {mostrar_sensor5 [3]} Km.\")\n        else:\n            print (\"DOS SENSORES O MAS ESTAN MIDIENDO LO MISMO, REFRESCA LA PANTALLA.\")\n\n    else :\n        if s7.count(s6) == 1:\n            print (f\"\\nEL NIVEL DE ALERTA SENSOR 6 ES EL MAS ALTO: {mostrar_sensor6 [0]}.\")\n            print (f\"LAS CORDENADAS SON X: {mostrar_sensor6 [1]}  Y: {mostrar_sensor6 [2]}.\")\n            print (f\"La {mostrar_sensor6 [3]} Km.\")\n        else:\n            print (\"DOS SENSORES O MAS ESTAN MIDIENDO LO MISMO, REFRESCA LA PANTALLA.\")\n\n    salir = input (\"PARA REFRESCAR LOS SENSORES PULSA ENTER, PARA SALIR ESCRIBE SALIR Y PULSA ENTER \")\n    salir = str(salir).upper()\n"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/python/CesarCarmona30.py",
    "content": "from datetime import datetime, timedelta\n\nyear_of_creation = 1939\nanniversary_year = year_of_creation + 85\n\nbatman_day_anniversary_dates = []\n\nwhile anniversary_year <= year_of_creation + 100:\n  \n  september = datetime(anniversary_year, 9, 1)\n\n  first_saturday = 5 - september.weekday() if september.weekday() <= 5 else \\\n    12 - september.weekday()\n\n  third_saturday = september + timedelta(days=first_saturday + 14)\n\n  batman_day_anniversary_dates.append(\n    (\n      anniversary_year,\n      anniversary_year - year_of_creation,\n      third_saturday.strftime(\"%d-%m-%Y\")\n    )\n  )\n\n  anniversary_year += 1\n\nfor year, anniversary, batman_day in batman_day_anniversary_dates:\n  print(f\"Batman day {year} ({anniversary} aniversario): {batman_day}\")\n\n\ndef sum_subgrid_alerts(sensors, center_x, center_y):\n  total = 0\n\n  for x in range(center_x - 1, center_x + 2):\n    for y in range(center_y - 1, center_y + 2):\n      for sensor in sensors:\n        if sensor[0] == x and sensor[1] == y:\n          total += sensor[2]\n\n  return total\n\ndef batcave_security_system(sensors):\n  \n  max_alert_level = 0\n  max_alert_coordinate = (0, 0)\n\n  for x in range(1, 19):\n    for y in range(1, 19):\n      alert_level = sum_subgrid_alerts(sensors, x, y)\n      if alert_level > max_alert_level:\n        max_alert_level = alert_level\n        max_alert_coordinate = (x, y)\n\n  distance = abs(max_alert_coordinate[0]) + abs(max_alert_coordinate[1])\n  activate_protocol = max_alert_level > 20\n\n  return max_alert_coordinate, max_alert_level, distance, activate_protocol\n\nsensors = [\n  (2, 3, 7),\n  (4, 3, 8),\n  (2, 2, 7),\n  (10, 12, 8),\n  (11, 11, 8),\n  (10, 11, 8),\n  (15, 18, 4)\n]\n\nresult = batcave_security_system(sensors)\n\nprint(f\"Centro de cuadrícula mas amenzada: {result[0]}\")\nprint(f\"Máximo nivel de alerta: {result[1]}\")\nprint(f\"Distancia a la Baticueva: {result[2]}\")\nprint(f\"Activar protocolo de seguridad: {result[3]}\")"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/python/DavidVilem.py",
    "content": "import numpy as np\r\nimport matplotlib.pyplot as plt\r\nimport datetime\r\n\r\n# Función para calcular Batman Day\r\ndef obtener_batman_day(anio):\r\n    # Fecha del 1 de septiembre de cada año\r\n    fecha_base = datetime.date(anio, 9, 1)\r\n    # Día de la semana de esa fecha (0 es lunes)\r\n    dia_de_la_semana = fecha_base.weekday()\r\n    # Si no es sábado (5), nos movemos a la tercera semana (15 días más el ajuste para el sábado)\r\n    dias_a_sumar = 14 + (5 - dia_de_la_semana)\r\n    # El Batman Day cae en el sábado de la tercera semana de septiembre\r\n    batman_day = fecha_base + datetime.timedelta(days=dias_a_sumar)\r\n    return batman_day\r\n\r\n# Función para celebrar el Batman Day hasta su 100 aniversario\r\ndef celebrar_batman_day():\r\n    anio_actual = datetime.date.today().year\r\n    anio_batman = 1939\r\n    for anio in range(anio_actual, anio_batman + 101):  # Hasta el año 2039\r\n        print(f\"Batman Day en el año {anio}: {obtener_batman_day(anio)}\")\r\n\r\n# Ejecutar celebración de Batman Day\r\ncelebrar_batman_day()\r\n\r\n# Función para encontrar el área más amenazada\r\ndef encontrar_area_critica(sensor_data, umbral):\r\n    # Crear una matriz 20x20 para representar el mapa de Gotham\r\n    gotham_map = np.zeros((20, 20), dtype=int)\r\n    \r\n    # Colocar los niveles de amenaza en la matriz\r\n    for sensor in sensor_data:\r\n        x, y, amenaza = sensor\r\n        gotham_map[x, y] = amenaza\r\n    \r\n    # Variables para guardar el área más crítica\r\n    max_amenaza = 0\r\n    coord_centro_max = (0, 0)\r\n    zona_critica = None\r\n    \r\n    # Recorrer la cuadrícula buscando la zona 3x3 con mayor sumatorio de amenazas\r\n    for i in range(18):  # 18 porque estamos buscando áreas de 3x3\r\n        for j in range(18):\r\n            # Extraer el área 3x3\r\n            submatriz = gotham_map[i:i+3, j:j+3]\r\n            suma_amenazas = np.sum(submatriz)\r\n            \r\n            # Verificar si es la mayor suma encontrada\r\n            if suma_amenazas > max_amenaza:\r\n                max_amenaza = suma_amenazas\r\n                coord_centro_max = (i+1, j+1)  # El centro de la cuadrícula 3x3\r\n                zona_critica = (i, j)  # Guardar coordenadas superiores izquierdas del área 3x3\r\n    \r\n    # Calcular la distancia a la Batcueva (0,0)\r\n    distancia_batcueva = abs(coord_centro_max[0]) + abs(coord_centro_max[1])\r\n    \r\n    # Verificar si se debe activar el protocolo de seguridad\r\n    activar_protocolo = max_amenaza > umbral\r\n    \r\n    # Mostrar resultados\r\n    print(f\"Centro de la zona más amenazada: {coord_centro_max}\")\r\n    print(f\"Suma de amenazas en la zona: {max_amenaza}\")\r\n    print(f\"Distancia a la Batcueva: {distancia_batcueva}\")\r\n    if activar_protocolo:\r\n        print(\"¡Protocolo de seguridad activado!\")\r\n    else:\r\n        print(\"No es necesario activar el protocolo de seguridad.\")\r\n    \r\n    # Visualizar el mapa\r\n    visualizar_mapa(gotham_map, coord_centro_max, zona_critica, max_amenaza, activar_protocolo)\r\n\r\n# Función para visualizar el mapa de Gotham\r\ndef visualizar_mapa(mapa, centro, zona_critica, suma_amenazas, activar_protocolo):\r\n    fig, ax = plt.subplots(figsize=(10, 10))\r\n    \r\n    # Mostrar la cuadrícula con el mapa de Gotham\r\n    ax.imshow(mapa, cmap='magma', origin='upper', alpha=0.8)\r\n    \r\n    # Marcar los puntos de los sensores\r\n    for i in range(20):\r\n        for j in range(20):\r\n            if mapa[i, j] > 0:\r\n                ax.text(j, i, str(mapa[i, j]), ha='center', va='center', color='black', fontsize=12)\r\n    \r\n    # Resaltar el área más crítica (zona 3x3)\r\n    if zona_critica:\r\n        rect = plt.Rectangle((zona_critica[1]-0.5, zona_critica[0]-0.5), 3, 3, linewidth=5, edgecolor='red', facecolor='none')\r\n        ax.add_patch(rect)\r\n    \r\n    # Título con los resultados\r\n    titulo = f\"Zona más crítica: Centro en {centro}, Amenazas = {suma_amenazas}\"\r\n    if activar_protocolo:\r\n        titulo += \" (Protocolo activado)\"\r\n    else:\r\n        titulo += \" (Protocolo no activado)\"\r\n    ax.set_title(titulo)\r\n    \r\n    # Configuración del gráfico\r\n    ax.set_xticks(np.arange(20))\r\n    ax.set_yticks(np.arange(20))\r\n    ax.grid(True)\r\n    ax.set_xticklabels(np.arange(20))\r\n    ax.set_yticklabels(np.arange(20))\r\n    \r\n    # Mostrar el gráfico\r\n    plt.show()\r\n\r\n# Datos de prueba (coordenadas de sensores y su nivel de amenaza)\r\nsensor_data = [\r\n    (5, 5, 8), (6, 7, 8), (5, 6, 8), (14, 4, 9), (10, 3, 4),\r\n    (15, 9, 10), (13, 5, 5), (16, 2, 7), (8, 8, 9), (12, 4, 3)\r\n]\r\n\r\n# Umbral de activación del protocolo de seguridad\r\numbral_activacion = 20\r\n\r\n# Ejecutar el sistema de seguridad\r\nencontrar_area_critica(sensor_data, umbral_activacion)"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/python/EmmanuelMMontesinos.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * Cada año se celebra el Batman Day durante la tercera semana de septiembre... \n * ¡Y este año cumple 85 años! Te propongo un reto doble:\n *\n * RETO 1:\n * Crea un programa que calcule cuándo se va a celebrar el Batman Day hasta \n * su 100 aniversario.\n *\n * RETO 2:\n * Crea un programa que implemente el sistema de seguridad de la Batcueva. \n * Este sistema está diseñado para monitorear múltiples sensores distribuidos\n * por Gotham, detectar intrusos y activar respuestas automatizadas. \n * Cada sensor reporta su estado en tiempo real, y Batman necesita un programa \n * que procese estos datos para tomar decisiones estratégicas.\n * Requisitos:\n * - El mapa de Gotham y los sensores se representa con una cuadrícula 20x20.\n * - Cada sensor se identifica con una coordenada (x, y) y un nivel\n *   de amenaza entre 0 a 10 (número entero).\n * - Batman debe concentrar recursos en el área más crítica de Gotham.\n * - El programa recibe un listado de tuplas representando coordenadas de los \n *   sensores y su nivel de amenaza. El umbral de activación del protocolo de\n *   seguridad es 20 (sumatorio de amenazas en una cuadrícula 3x3).\n * Acciones: \n * - Identifica el área con mayor concentración de amenazas\n *   (sumatorio de amenazas en una cuadrícula 3x3).\n * - Si el sumatorio de amenazas es mayor al umbral, activa el \n *   protocolo de seguridad.\n * - Calcula la distancia desde la Batcueva, situada en (0, 0). La distancia es\n *   la suma absoluta de las coordenadas al centro de la cuadrícula amenazada.\n * - Muestra la coordenada al centro de la cuadrícula más amenazada, la suma de\n *   sus amenazas, la distancia a la Batcueva y si se debe activar el\n *   protocolo de seguridad.\n */\n\"\"\"\n\n# Reto 1\n\"\"\"\n    * Crea un programa que calcule cuándo se va a celebrar el Batman Day hasta \n* su 100 aniversario.\n\"\"\"\nimport datetime\n\nclass Batday:\n    def __init__(self):\n        self.aniversario_actual = 85\n        self.year = datetime.datetime.now().year \n\n    def get_batday(self,aniversario):\n        print(\"Batman Weeks\")\n        print(\"Aniversario - Dias de la Batman Weeks\")\n        for year in range(self.aniversario_actual, aniversario+1):\n            print(f\"{year} - {self.get_days_week(self.year + (year - self.aniversario_actual))}\")\n            \n    def get_days_week(self, year):\n        first_day_september = datetime.date(year, 9, 1)\n        first_monday_september = first_day_september - datetime.timedelta(days=(7 - first_day_september.weekday()) % 7)\n        threerd_week = first_monday_september + datetime.timedelta(days=21)\n        batweek_list = [threerd_week + datetime.timedelta(days=i) for i in range(7)]\n        batweek_format = [i.strftime(\"%d/%m/%Y\") for i in batweek_list]\n        batweek = \", \".join(batweek_format)\n        return batweek\n\n# Prueba\nreto_1 = Batday()\nreto_1.get_batday(100)\nprint()\n# Reto 2\nclass Batcueva:\n    mapa = {}\n    sectores_control = {}\n    def __init__(self,matriz) -> None:\n        mapa = {}\n        for sensor in matriz:\n            mapa[sensor.x, sensor.y] = sensor\n        Batcueva.mapa = mapa\n\n        for x in range(1,19,3):\n            for y in range(1,19,3):\n                Batcueva.sectores_control[(x,y)] = [\n                    (x-1, y-1), (x, y-1), (x+1, y-1),\n                    (x-1, y), (x, y), (x+1, y),\n                    (x-1, y+1), (x, y+1), (x+1, y+1)\n                ]\n        \n        \n    def scan_sectors(self,printeable=False) -> list:\n        sectores_criticos = []\n        for name, sector in Batcueva.sectores_control.items():\n            level = 0\n            sub_sections = []\n            for sensor_area in sector:\n                sensor = Batcueva.mapa[sensor_area]\n                area_level = sensor.get_level()\n                sub_sections.append((sensor_area, area_level))\n                level += area_level\n\n                \"\"\"\n                * - Si el sumatorio de amenazas es mayor al umbral, activa el \n                *   protocolo de seguridad.\n                \"\"\"\n                if level >= 20:\n                    if (name, level,sub_sections) not in sectores_criticos:\n                        sectores_criticos.append((name, level,sub_sections))\n            if printeable:\n                print(f\"Area: {name} sensores: {sector} - Amenaza: {level}\")\n        return sectores_criticos\n    def scan_map(self) -> None:\n        \"\"\"\n        * - Muestra la coordenada al centro de la cuadrícula más amenazada, la suma de\n        *   sus amenazas, la distancia a la Batcueva y si se debe activar el\n        *   protocolo de seguridad.\n        \"\"\"\n        print(\"Iniciando Analisis de Sectores Criticos\")\n        check = 0\n        sectores_criticos = self.scan_sectors()\n        sectores_criticos.sort(key=lambda x: x[1], reverse=True)\n        \n        \"\"\"\n        * - Identifica el área con mayor concentración de amenazas\n        *   (sumatorio de amenazas en una cuadrícula 3x3).\"\"\"\n        if len(sectores_criticos) > 0:\n            print(\"-\"*10)\n            print(f\"Areas Criticas Encontradas: {len(sectores_criticos)}\")\n            print(f\"Area más critica:\\nArea:{sectores_criticos[0][0]} - Nivel de amenaza: {sectores_criticos[0][1]}\")\n            print(\"-\"*10)\n            for number, sector in enumerate(sectores_criticos):\n                print(\"-\"*5)\n                print(f\"Activando Medidas de Emergencia {number+1} de {len(sectores_criticos)}\")\n                print(f\"Sector central del area: {sector[0]}\")\n\n                \"\"\"\n                * - Calcula la distancia desde la Batcueva, situada en (0, 0). La distancia es\n                *   la suma absoluta de las coordenadas al centro de la cuadrícula amenazada\n                \"\"\"\n                print(f\"Distancia desde la batcueva: {sector[0][0] + sector[0][1]} cuadrantes\")\n\n                print(f\"Nivel de amenaza general: {sector[1]}\")\n                print(f\"Sectores amenazados del area {sector[0]}:\")\n                for num,area in enumerate(sector[2]):\n                    print(\"-\"*2)\n                    print(f\" Sub-area {num+1} : Sensor del sector: {area[0]} - Nivel de amenaza: {area[1]}\")\n                print(f\"Batman esta de camino a {sector[0]}\")\n        else:\n            print(\"No hay sectores criticos\")\n            print(\"Niveles actuales de amenaza:\")\n            for sector in Batcueva.mapa:\n                print(f\"Coordenadas: {sector.x}, {sector.y} - {sector.get_level()}\")\n\n# Para poder probar el reto he creado esta clase\n\"\"\"\n* - Cada sensor se identifica con una coordenada (x, y) y un nivel\n*   de amenaza entre 0 a 10 (número entero).\n\"\"\"\nclass Sensor:\n    def __init__(self, x, y, level) -> None:\n        self.x = x\n        self.y = y\n        self.__level = level\n    def get_level(self):\n        return self.__level\n    # Para poder cambiar el nivel de amenaza\n    def set_level(self, level):\n        self.__level = level\n    \n\n# Prueba\n\n\"\"\"El mapa de Gotham y los sensores se representa con una cuadrícula 20x20\"\"\"\nmatriz = [Sensor(fila, columna, 0) for fila in range(20) for columna in range(20)]\n\nreto_2 = Batcueva(matriz)\nx = 1\ny = 5\nfor sensor in Batcueva.mapa.values():\n    if sensor.x == x and sensor.y == y:\n        sensor.set_level(10)\n    if sensor.x == x and sensor.y == y + 1:\n        sensor.set_level(10)\n    if sensor.x == x - 1 and sensor.y == y:\n        sensor.set_level(5)\n    if sensor.x == x + 1 and sensor.y == y:\n        sensor.set_level(5)\nx = 8\ny = 3\nfor sensor in Batcueva.mapa.values():\n    if sensor.x == x and sensor.y == y:\n        sensor.set_level(10)\n    if sensor.x == x and sensor.y == y + 1:\n        sensor.set_level(10)\n    if sensor.x == x - 1 and sensor.y == y:\n        sensor.set_level(5)\n    if sensor.x == x + 1 and sensor.y == y:\n        sensor.set_level(5)\n\nreto_2.scan_map()"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/python/Gordo-Master.py",
    "content": "# 39 - Batman Day\nfrom datetime import datetime\nimport calendar\nimport random\n\n\"\"\"\nEjercicio 1\n\"\"\"\n# Regresa el \ndef set_batman_date(year = 2025):\n    start = datetime(year=2024,month=9,day=21).date()\n    start_aniversary = 85\n    target = datetime(year,9,get_weekday(year)).date()\n    target_aniversary = start_aniversary + (target.year - start.year)\n    print(f\"El {target_aniversary}º aniversario es el sábado, {target.strftime(\"%d/%m/%Y\")}\")\n    return target_aniversary\n\n# Buscador de el puesto(position) de dia buscado (desired_day)(5 es sabado) pero seteado para los valores que estoy buscando\ndef get_weekday(year, month = 9, position = 3, desired_day = 5):\n    calendar_month = calendar.monthcalendar(year, month)\n    days = [week[desired_day] for week in calendar_month if week[desired_day] != 0]\n    return days[position-1]\n\n# Recuperar todos los aniversarios dando un inicio y el numero de aniversario final\ndef get_date_to(number = 2024, year_to = 100):\n    while True:\n        number += 1\n        aniversary = set_batman_date(number)\n        if aniversary == year_to:\n            break\n\n#Ejecutando el codigo\n# get_date_to()\n\n\"\"\"\nEjercicio 2\n\"\"\"\n\nvalues = list(range(0,10))\n\n# Ponderacion cuadratica inversa: peso alto al inicio y bajo al final\n\nweight = [(10 - v)**2 for v in values]\n\ngotham = [[(random.choices(values,weights=weight,k=1))[0] for i in range(20)] for i in range(20)]\n\nfor row in gotham:\n    print(row)\n\ndef is_center(coord: tuple, matrix: list, size = 3):\n    offset = size // 2\n    if coord[0] in range(0+offset, (len(matrix)-offset)):\n        if coord[1] in range(0+offset, (len(matrix[0])-offset)):\n            return True\n    return False\n\ndef get_center_zone(matrix, size = 3):\n    zone = []\n    for i in range(len(matrix)):\n        for j in range(len(matrix[i])):\n            if is_center((i,j), matrix, size):\n                zone.append((i,j))\n    \n    return zone\n\ncenter_zone = get_center_zone(gotham,3)\n\ndef get_threat_level(mini_matrix):\n    threat_level = 0\n    for row in mini_matrix:\n        threat_level += sum(row)\n    return threat_level\n\n\ndef get_submatrix(matrix, center_x, center_y, size = 3):\n    offset = size // 2\n    submatrix = []\n    for i in range(center_x - offset, center_x + offset + 1):\n        row = []\n        for j in range(center_y - offset, center_y + offset + 1):\n            row.append(matrix[i][j])\n        submatrix.append(row)\n    return submatrix\n\n\ndef threat_to_city(matrix):\n    center_zone = get_center_zone(matrix,3)\n    emergency_zones = []\n    for zone in center_zone:\n        submatrix = get_submatrix(matrix,zone[0],zone[1])\n        threat_level = get_threat_level(submatrix)\n        x,y = zone\n        z = threat_level\n        emergency_zones.append((x,y,z))\n    \n    return emergency_zones\n\ndef dist_to_baticueva(baticueva: list, zone: list):\n    dist = (zone[1] - baticueva[1])+(zone[0] - baticueva[0])\n    return dist\n\ndef defense_system(x,y,threat_level):\n    baticueva = [0,0]\n    print(f\"Tenemos una situacion en las coordenadas: {x}, {y}\")\n    print(f\"Nivel de peligro: {threat_level}\")\n    print(f\"Distancia de la baticueva a la zona: {dist_to_baticueva(baticueva,[x,y])}\")\n    print(f\"Activar el protocolo de seguridad: {\"SI\" if threat_level>20 else \"NO\"}\")\n\nzones_levels = threat_to_city(gotham)\ntop_priority = max(zones_levels,key=lambda x: x[2])\nx,y,threat_level = top_priority\ndefense_system(x,y,threat_level)"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/python/JesusWay69.py",
    "content": "import os, platform\nfrom random import randint\nfrom datetime import date \nif (platform.platform().startswith(\"macOS\") or platform.platform().startswith(\"Linux\")):\n    os.system('clear')\nelse:\n    os.system('cls')\n\n\"\"\" * EJERCICIO:\n * Cada año se celebra el Batman Day durante la tercera semana de septiembre...\n * ¡Y este año cumple 85 años! Te propongo un reto doble:\n *\n * RETO 1:\n * Crea un programa que calcule cuándo se va a celebrar el Batman Day hasta\n * su 100 aniversario.\n *\n * RETO 2:\n * Crea un programa que implemente el sistema de seguridad de la Batcueva.\n * Este sistema está diseñado para monitorear múltiples sensores distribuidos\n * por Gotham, detectar intrusos y activar respuestas automatizadas.\n * Cada sensor reporta su estado en tiempo real, y Batman necesita un programa\n * que procese estos datos para tomar decisiones estratégicas.\n * Requisitos:\n * - El mapa de Gotham y los sensores se representa con una cuadrícula 20x20.\n * - Cada sensor se identifica con una coordenada (x, y) y un nivel\n *   de amenaza entre 0 a 10 (número entero).\n * - Batman debe concentrar recursos en el área más crítica de Gotham.\n * - El programa recibe un listado de tuplas representando coordenadas de los\n *   sensores y su nivel de amenaza. El umbral de activación del protocolo de\n *   seguridad es 20 (sumatorio de amenazas en una cuadrícula 3x3).\n * Acciones:\n * - Identifica el área con mayor concentración de amenazas\n *   (sumatorio de amenazas en una cuadrícula 3x3).\n * - Si el sumatorio de amenazas es mayor al umbral, activa el\n *   protocolo de seguridad.\n * - Calcula la distancia desde la Batcueva, situada en (0, 0). La distancia es\n *   la suma absoluta de las coordenadas al centro de la cuadrícula amenazada.\n * - Muestra la coordenada al centro de la cuadrícula más amenazada, la suma de\n *   sus amenazas, la distancia a la Batcueva y si se debe activar el\n *   protocolo de seguridad.\"\"\"\n\n#### RETO 1 ####\nbatman_day_2024 = '{} / {} / {}'.format(date(2024,9,21).day, date(2024,9,21).month, date(2024,9,21).year)\nprint(f\"El Batman Day de 2024 se celebró el {batman_day_2024} , este evento se celebra cada 3º Sábado de Septiembre,\")\nprint(\"este año 2024 se celebra el 85º aniversario, estas serán las próximas fechas en las que se celebre este evento \")\nprint(\"hasta llegar al centenario que será en 2039:\")\nfor year in range(2025, 2040):\n    week:int = 0\n    batman_day = date(year, 9, 1)\n    for day in range(1, 31):\n        batman_day = date(year, 9, day)\n        if batman_day.weekday() == 5:\n            week += 1\n            if week == 3:\n                print('{} / {} / {}'.format(batman_day.day, batman_day.month, batman_day.year))\n\n#### RETO 2 ####\nsensor1, sensor2, sensor3, sensor4 = (5, 5), (5, 16), (16, 5), (16, 16)\n\ndef create_map(map:list)->list:\n    map, batcave, sensor  = [], '▓', '⌺'\n    for i in range(20):\n        map.append([])\n        for j in range(20): \n            if i == 0 and j == 0:\n                map[i].append(batcave)\n            elif (i == sensor1[0]-1 and j == sensor1[1]-1 ) or (i == sensor2[0]-1 and j == sensor2[1]-1):\n                map[i].append(sensor)\n            elif (i == sensor3[0]-1 and j == sensor3[1]-1) or (i == sensor4[0]-1 and j == sensor4[1]-1):\n                map[i].append(sensor)\n            else:\n                map[i].append(randint(0,9))\n    return map\n\ngotham_map = create_map(map)\n\ndef print_map(map:list):\n    print(\"\\n--------------------  MAPA DE GOTHAM  --------------------\")\n    for row in map:\n        print()\n        for column in row:\n            print('{:<2}'.format(column), end=' ')\n    print(\"\\n\")\n\ndef threat_level(map:list)->tuple:\n    threat, threat_area = 0, []\n    for i , row in enumerate(map):\n        for j, column in enumerate(row):\n            if column == '⌺':\n                threat = sum([map[i-1][j-1], map[i-1][j],\n                              map[i-1][j+1], map[i][j-1],                             \n                              map[i][j+1], map[i+1][j-1],                            \n                              map[i+1][j], map[i+1][j+1]])                                                \n                threat_area.append(threat)        \n    return tuple(threat_area)\n\ndef max_threat(threats:tuple)->tuple:\n    hight_threat = max(threats)\n    hight_index = threats.index(hight_threat) + 1\n    return hight_index, hight_threat\n\ndef create_report(s1:tuple,s2:tuple,s3:tuple,s4:tuple)->list:\n    report_list = []\n    sensor1 = threat_level(gotham_map)[0], s1\n    sensor2 = threat_level(gotham_map)[1], s2\n    sensor3 = threat_level(gotham_map)[2], s3\n    sensor4 = threat_level(gotham_map)[3], s4\n    report_list.append(sensor1)\n    report_list.append(sensor2)\n    report_list.append(sensor3)\n    report_list.append(sensor4)\n    return report_list\n\ndef print_report(report:list):\n    print_map(gotham_map)\n    [print(f\"Nivel de amenaza del sensor {i} : {threat_level(gotham_map)[i-1]}\") for i in range(1,5)]     \n    index, threat = max_threat(threat_level(gotham_map))\n    print(f\"\\nNivel de la amenaza máxima: {threat} y sus coordenadas son: x={report[index-1][1][0]} y={report[index-1][1][1]}\")\n    print(f\"\\nEl sensor {index} está en la zona más amenazada y la distancia desde la batcueva es de {report[index-1][1][0] + report[index-1][1][1]}\")\n    if threat>20:\n        print(\"\\nLa zona más amenazada supera el umbral del protocolo de seguridad de 20\")\n        print(\"\\n¡¡ACTIVAR PROTOCOLO DE SEGURIDAD!! \")\n\nprint_report(create_report(sensor1, sensor2, sensor3, sensor4))\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n               \n#print('◈') # █ ▓ ■ ░ ▒ ╬ ⌧ ⌺ ↂ ◈ 〓 ⓵ ⓶ ⓷ ⓸ ⓹ ⓺ ⓻ ⓼ ⓽ ⑩ Ⓑ ☠ ⚫ ◯ 𝐁 ❶ ⑴ 𝐀\n\n#web special chars: https://www.caracteresespeciales.com/n%C3%BAmero-caracteres-especiales.html"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/python/Juanppdev.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Cada año se celebra el Batman Day durante la tercera semana de septiembre... \n * ¡Y este año cumple 85 años! Te propongo un reto doble:\n *\n * RETO 1:\n * Crea un programa que calcule cuándo se va a celebrar el Batman Day hasta \n * su 100 aniversario.\n *\n * RETO 2:\n * Crea un programa que implemente el sistema de seguridad de la Batcueva. \n * Este sistema está diseñado para monitorear múltiples sensores distribuidos\n * por Gotham, detectar intrusos y activar respuestas automatizadas. \n * Cada sensor reporta su estado en tiempo real, y Batman necesita un programa \n * que procese estos datos para tomar decisiones estratégicas.\n * Requisitos:\n * - El mapa de Gotham y los sensores se representa con una cuadrícula 20x20.\n * - Cada sensor se identifica con una coordenada (x, y) y un nivel\n *   de amenaza entre 0 a 10 (número entero).\n * - Batman debe concentrar recursos en el área más crítica de Gotham.\n * - El programa recibe un listado de tuplas representando coordenadas de los \n *   sensores y su nivel de amenaza. El umbral de activación del protocolo de\n *   seguridad es 20 (sumatorio de amenazas en una cuadrícula 3x3).\n * Acciones: \n * - Identifica el área con mayor concentración de amenazas\n *   (sumatorio de amenazas en una cuadrícula 3x3).\n * - Si el sumatorio de amenazas es mayor al umbral, activa el \n *   protocolo de seguridad.\n * - Calcula la distancia desde la Batcueva, situada en (0, 0). La distancia es\n *   la suma absoluta de las coordenadas al centro de la cuadrícula amenazada.\n * - Muestra la coordenada al centro de la cuadrícula más amenazada, la suma de\n *   sus amenazas, la distancia a la Batcueva y si se debe activar el\n *   protocolo de seguridad.\n\"\"\"\n\n# Reto 1\nfrom datetime import datetime, timedelta\n\ndef calcular_batman_day(anio_inicio, anios):\n    batman_days = []\n    for i in range(anios):\n        anio = anio_inicio + i\n        # Encuentra el primer día de la tercera semana de septiembre\n        primer_dia_septiembre = datetime(anio, 9, 1)\n        tercer_lunes = primer_dia_septiembre + timedelta(days=(14 - primer_dia_septiembre.weekday() + 7) % 7)\n        batman_days.append(tercer_lunes)\n    return batman_days\n\n# Ejemplo de uso\nanio_inicio = 2024\nanios = 100 - 85  # Hasta el 100 aniversario\nbatman_days = calcular_batman_day(anio_inicio, anios)\nfor dia in batman_days:\n    print(dia.strftime(\"%Y-%m-%d\"))\n\n\n# Reto 2\ndef calcular_amenaza(sensor_data):\n    max_amenaza = 0\n    coordenada_max = (0, 0)\n    activar_protocolo = False\n\n    for i in range(18):  # 20x20 grid, 3x3 subgrid\n        for j in range(18):\n            suma_amenaza = sum(sensor_data[x][y] for x in range(i, i+3) for y in range(j, j+3))\n            if suma_amenaza > max_amenaza:\n                max_amenaza = suma_amenaza\n                coordenada_max = (i+1, j+1)\n                activar_protocolo = suma_amenaza > 20\n\n    distancia_batcueva = abs(coordenada_max[0] - 1) + abs(coordenada_max[1] - 1)\n    return coordenada_max, max_amenaza, distancia_batcueva, activar_protocolo\n\n# Ejemplo de uso\nsensor_data = [[0]*20 for _ in range(20)]\n# Añadir datos de sensores (coordenada x, y, nivel de amenaza)\nsensores = [(5, 5, 8), (6, 6, 7), (7, 7, 6), (8, 8, 9), (9, 9, 10)]\nfor x, y, amenaza in sensores:\n    sensor_data[x][y] = amenaza\n\ncoordenada_max, max_amenaza, distancia_batcueva, activar_protocolo = calcular_amenaza(sensor_data)\nprint(f\"Coordenada más amenazada: {coordenada_max}\")\nprint(f\"Suma de amenazas: {max_amenaza}\")\nprint(f\"Distancia a la Batcueva: {distancia_batcueva}\")\nprint(f\"Activar protocolo de seguridad: {'Sí' if activar_protocolo else 'No'}\")\n"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/python/Nicojsuarez2.py",
    "content": "# #39 BATMAN DAY\n> #### Dificultad: Media | Publicación: 23/09/24 | Corrección: 30/09/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Cada año se celebra el Batman Day durante la tercera semana de septiembre... \n * ¡Y este año cumple 85 años! Te propongo un reto doble:\n *\n * RETO 1:\n * Crea un programa que calcule cuándo se va a celebrar el Batman Day hasta \n * su 100 aniversario.\n *\n * RETO 2:\n * Crea un programa que implemente el sistema de seguridad de la Batcueva. \n * Este sistema está diseñado para monitorear múltiples sensores distribuidos\n * por Gotham, detectar intrusos y activar respuestas automatizadas. \n * Cada sensor reporta su estado en tiempo real, y Batman necesita un programa \n * que procese estos datos para tomar decisiones estratégicas.\n * Requisitos:\n * - El mapa de Gotham y los sensores se representa con una cuadrícula 20x20.\n * - Cada sensor se identifica con una coordenada (x, y) y un nivel\n *   de amenaza entre 0 a 10 (número entero).\n * - Batman debe concentrar recursos en el área más crítica de Gotham.\n * - El programa recibe un listado de tuplas representando coordenadas de los \n *   sensores y su nivel de amenaza. El umbral de activación del protocolo de\n *   seguridad es 20 (sumatorio de amenazas en una cuadrícula 3x3).\n * Acciones: \n * - Identifica el área con mayor concentración de amenazas\n *   (sumatorio de amenazas en una cuadrícula 3x3).\n * - Si el sumatorio de amenazas es mayor al umbral, activa el \n *   protocolo de seguridad.\n * - Calcula la distancia desde la Batcueva, situada en (0, 0). La distancia es\n *   la suma absoluta de las coordenadas al centro de la cuadrícula amenazada.\n * - Muestra la coordenada al centro de la cuadrícula más amenazada, la suma de\n *   sus amenazas, la distancia a la Batcueva y si se debe activar el\n *   protocolo de seguridad.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/python/SooHav.py",
    "content": "# 39 Batman day\n\nfrom tkinter import *\nfrom tkinter import ttk\nimport numpy as np\nimport calendar\nimport datetime\n# Reto 1\n\n\nclass BatmanDay:\n    def __init__(self, root, anio=2039, mes=9):\n        self.root = root\n        self.root.title(\"Días para el centenario de Batman\")\n        self.root.configure(background='black')\n        self.root.geometry(\"600x140\")\n        self.anio = anio\n        self.mes = mes\n\n        # Etiqueta\n        self.etiqueta = ttk.Label(self.root, font=(\"Helvetica\", 20),\n                                  foreground=\"yellow\", background=\"black\")\n        self.etiqueta.pack(pady=20)\n\n        # Estilo\n        self.style = ttk.Style()\n        self.style.configure(\n            'TButton', foreground='yellow', background='black')\n\n        # Botón para cerrar la ventana\n        self.boton_apagado = ttk.Button(self.root, text=\"Cerrar\",\n                                        style='TButton', command=self.root.destroy)\n        self.boton_apagado.pack(pady=10)\n\n        # Calcular los días y mostrar el resultado\n        self.mostrar_dias(anio, mes)  # Centenario de Batman\n\n    def tercer_sabado_de_mes(self, anio, mes):\n        \"\"\"\n        Calcula la fecha del tercer sábado de un mes dado.\n        \"\"\"\n        calendario = calendar.Calendar(firstweekday=calendar.SATURDAY)\n        dias_del_mes = calendario.itermonthdates(anio, mes)\n\n        sabados = 0\n        for dia in dias_del_mes:\n            if dia.weekday() == calendar.SATURDAY:\n                sabados += 1\n            if sabados == 3:\n                return dia\n\n        return None\n\n    def calcular_dias(self, anio, mes):\n        \"\"\"Calcula los días entre la fecha actual y la fecha final.\"\"\"\n        fecha1 = datetime.date.today()\n        fecha2 = self.tercer_sabado_de_mes(anio, mes)\n        diferencia = (fecha2 - fecha1)\n        return diferencia.days\n\n    def mostrar_dias(self, anio, mes):\n        \"\"\"Muestra el número de días restantes.\"\"\"\n        dias_restantes = self.calcular_dias(anio, mes)\n        self.etiqueta.config(\n            text=f\"Faltan {dias_restantes} días para el centenario de Batman\")\n\n\n# Inicializar la aplicación\nif __name__ == \"__main__\":\n    root = Tk()\n    app = BatmanDay(root)\n    root.mainloop()\n\n# Reto 2\n\n# Crear el mapa de ciudad Gothica\n\n\ndef crear_grilla(filas=20, columnas=20, amenaza=10, sensores=0.8):\n    if filas < 20 or columnas < 20:\n        raise ValueError(\n            \"La grilla debe tener al menos 20 filas y 20 columnas\")\n\n    # Grilla\n    grilla = [[None for _ in range(columnas)] for _ in range(filas)]\n\n    # Asignar entrada (🦇)\n    fila_entrada = np.random.randint(0, filas)\n    columna_entrada = np.random.randint(0, columnas)\n    grilla[fila_entrada][columna_entrada] = (fila_entrada, columna_entrada, 0)\n    print(f\"La baticueva está en {fila_entrada} y {columna_entrada}\")\n\n    # Llenar la grilla con celdas sin amenaza y con amenazas detectadas por sensores\n    for i in range(filas):\n        for j in range(columnas):\n            if grilla[i][j] is None:\n                if np.random.random() > sensores:\n                    grilla[i][j] = (i, j, 0)\n                else:\n                    nivel_amenaza = np.random.randint(0, amenaza + 1)\n                    grilla[i][j] = (i, j, nivel_amenaza)\n\n    return grilla, fila_entrada, columna_entrada\n\n# Encontrar la máxima amenaza de la ciudad\n\n\ndef encontrar_max_amenaza(grilla, fila, columna):\n    amenazas = []\n\n    # Poner los límites de la subgrilla\n    fila_inicial = max(0, fila - 1)\n    fila_final = min(len(grilla), fila + 2)\n    columna_inicial = max(0, columna - 1)\n    columna_final = min(len(grilla[0]), columna + 2)\n\n    # Subgrilla 3x3\n    subgrilla = [grilla[i][columna_inicial:columna_final]\n                 for i in range(fila_inicial, fila_final)]\n\n    # Extraer los niveles de amenaza de la subgrilla\n    for fil_sub in subgrilla:\n        for celda in fil_sub:\n            amenazas.append(celda[2])\n\n    # Suma de amenaza de la subgrilla\n    suma_amenaza = sum(amenazas)\n\n    return (fila, columna, suma_amenaza) if suma_amenaza >= 20 else None\n\n# Calcular la distancia al punto crítico donde se está produciendo el delito\n\n\ndef calcular_distancia_manhattan(fila, fila_entrada, columna, columna_entrada):\n    return abs(fila - fila_entrada) + abs(columna - columna_entrada)\n\n# Mostrar el menú\n\n\ndef menu():\n    while True:\n        print(\"Menú:\")\n        print(\"1. Generar grilla\")\n        print(\"2. Determinar máxima amenaza\")\n        print(\"3. Salir\")\n        opcion = input(\"Ingrese una opción: \")\n        try:\n            return int(opcion)\n        except ValueError:\n            print(\"Opción inválida. Por favor, ingrese un número entero.\")\n\n\n# Variables globales\ngrilla = None\nfila_bati = None\ncolumna_bati = None\n\nwhile True:\n    opcion = menu()\n\n    if opcion == 1:\n        try:\n            filas = int(input(\"Ingrese el número de filas: \"))\n            columnas = int(input(\"Ingrese el número de columnas: \"))\n            amenaza = int(input(\"Ingrese el nivel máximo de amenaza: \"))\n            sensores = float(\n                input(\"Ingrese el porcentaje de sensores (entre 0.5 y 1.0): \"))\n            grilla, fila_bati, columna_bati = crear_grilla(\n                filas, columnas, amenaza, sensores)\n\n            for fila in grilla:\n                print(fila)\n        except ValueError:\n            print(\"Intente nuevamente.\")\n\n    elif opcion == 2:\n        if grilla is None:\n            print(\"Primero debe generar la grilla.\")\n        else:\n            max_amenaza = None\n\n            for i in range(1, filas - 1):\n                for j in range(1, columnas - 1):\n                    tupla = encontrar_max_amenaza(grilla, i, j)\n                    if tupla is not None:\n                        if max_amenaza is None or tupla[2] > max_amenaza[2]:\n                            max_amenaza = tupla\n\n            if max_amenaza is not None:\n                distancia = calcular_distancia_manhattan(\n                    max_amenaza[0], fila_bati, max_amenaza[1], columna_bati)\n                print(f\"El área donde se desarrolla el crimen está en {\n                      max_amenaza[0]} y {max_amenaza[1]}\")\n                print(f\"Con un nivel de amenaza de {\n                      max_amenaza[2]} se activó el protocolo de seguridad.\")\n                print(f\"La distancia al punto crítico es {distancia}\")\n            else:\n                print(f\"No se detectaron amenazas en la zona ({i}, {j}).\")\n\n    elif opcion == 3:\n        print(\"¡Hasta la próxima!\")\n        break\n"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/python/cdryampi.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * Cada año se celebra el Batman Day durante la tercera semana de septiembre... \n#  * ¡Y este año cumple 85 años! Te propongo un reto doble:\n#  *\n#  * RETO 1:\n#  * Crea un programa que calcule cuándo se va a celebrar el Batman Day hasta \n#  * su 100 aniversario.\n#  *\n#  * RETO 2:\n#  * Crea un programa que implemente el sistema de seguridad de la Batcueva. \n#  * Este sistema está diseñado para monitorear múltiples sensores distribuidos\n#  * por Gotham, detectar intrusos y activar respuestas automatizadas. \n#  * Cada sensor reporta su estado en tiempo real, y Batman necesita un programa \n#  * que procese estos datos para tomar decisiones estratégicas.\n#  * Requisitos:\n#  * - El mapa de Gotham y los sensores se representa con una cuadrícula 20x20.\n#  * - Cada sensor se identifica con una coordenada (x, y) y un nivel\n#  *   de amenaza entre 0 a 10 (número entero).\n#  * - Batman debe concentrar recursos en el área más crítica de Gotham.\n#  * - El programa recibe un listado de tuplas representando coordenadas de los \n#  *   sensores y su nivel de amenaza. El umbral de activación del protocolo de\n#  *   seguridad es 20 (sumatorio de amenazas en una cuadrícula 3x3).\n#  * Acciones: \n#  * - Identifica el área con mayor concentración de amenazas\n#  *   (sumatorio de amenazas en una cuadrícula 3x3).\n#  * - Si el sumatorio de amenazas es mayor al umbral, activa el \n#  *   protocolo de seguridad.\n#  * - Calcula la distancia desde la Batcueva, situada en (0, 0). La distancia es\n#  *   la suma absoluta de las coordenadas al centro de la cuadrícula amenazada.\n#  * - Muestra la coordenada al centro de la cuadrícula más amenazada, la suma de\n#  *   sus amenazas, la distancia a la Batcueva y si se debe activar el\n#  *   protocolo de seguridad.\n#  */\nfrom datetime import date, timedelta\nimport locale\nimport random\n\n\nclass Coordenada():\n\n    def __init__(self, x:int, y:int) -> None:\n        self.x = x\n        self.y = y\n\n\n\nclass Sensor():\n\n    def __init__(self, coordenada: Coordenada, amenaza: int, neutralizado :bool = False, total_amenaza :int = 0) -> None:\n\n        self.amenaza = 0 if amenaza < 0 else amenaza\n        self.amenaza = 10 if amenaza > 10 else amenaza\n        self.coordenada = coordenada\n        self.neutralizado = neutralizado\n\n    def __str__(self) -> str:\n        return '📡'\n\nclass Gotham():\n    # suma absoluta = ∣3−1∣+∣4−1∣=2+3=5\n    __superficie = [[\"🏢\" for _ in range(20)] for _ in range(20)]\n    __amenazas = []\n    __problemas = [\n        \"El Joker ha colocado bombas en la ciudad\",\n        \"Dos Caras está planeando un ataque en el banco central\",\n        \"El Acertijo ha dejado pistas encriptadas en los edificios\",\n        \"Bane está reclutando mercenarios para controlar Gotham\",\n        \"El Pingüino está traficando armas en los muelles\",\n        \"Hiedra Venenosa ha liberado toxinas en el parque central\",\n        \"Mr. Freeze está congelando zonas de la ciudad\",\n        \"El Espantapájaros está extendiendo su gas del miedo por los barrios\",\n        \"Harley Quinn está preparando una emboscada en el circo\",\n        \"Ra's al Ghul está atacando con la Liga de las Sombras\",\n        \"Man-Bat está atacando desde los cielos\",\n        \"Hush ha infiltrado a sus secuaces entre la policía\",\n        \"El Sombrerero Loco está controlando las mentes de los ciudadanos\",\n        \"Clayface está causando caos en las calles con su transformación\",\n        \"El Tribunal de los Búhos está moviendo sus piezas en la sombra\",\n    ]\n\n    \n    def __init__(self, sensores: list[Sensor]) -> None:\n        \n        for sensor in sensores:\n            self.__superficie[sensor.coordenada.x][sensor.coordenada.y] = sensor\n        # por las dudas sí me envían una coordenada 0,0 y nos quedamos sin el Batman.\n        self.batman_pos = Coordenada(0,0)\n        self.__superficie[self.batman_pos.x][self.batman_pos.y] = '🦇'\n\n    def print_gotham(self) -> None:\n        print(\"Ciudad de Gotham:\")\n        for barrio in self.__superficie:\n            barrio_group = ' '.join([str(calle) for calle in barrio])\n            print(barrio_group)\n\n\n    def cal_amenaza(self) -> None:\n        self.__amenazas = []\n        for index_x, x in enumerate(self.__superficie):\n            for index_y, y in enumerate(x):\n                if self.__superficie[index_x][index_y].__str__() == '📡':\n                    amenaza = 0\n                    \n                    # Recorremos los vecinos en un área de 3x3 alrededor del sensor\n                    for i in range(-1, 2):\n                        for j in range(-1, 2):\n                            vecino_x = index_x + i\n                            vecino_y = index_y + j\n                            \n                            if 0 <= vecino_x < 20 and 0 <= vecino_y < 20:\n                                if self.__superficie[vecino_x][vecino_y].__str__() == '📡' and self.__superficie[vecino_x][vecino_y].neutralizado == False:\n                                    try:\n                                        amenaza += self.__superficie[vecino_x][vecino_y].amenaza\n                                    except AttributeError:\n                                        pass\n                    if amenaza >= 20 and self.__superficie[index_x][index_y].neutralizado == False:\n                        self.__amenazas.append(self.__superficie[index_x][index_y])\n                        self.__superficie[index_x][index_y].total_amenaza = amenaza\n        \n        if len(self.__amenazas) > 0:\n            self.neutralizar_amenaza()\n        else:\n            print(\"Sin anemazas cercanas...\")\n            self.print_gotham()\n\n    def neutralizar_amenaza(self) -> None:\n        # Neutralizar cada amenaza en la lista de amenazas\n        self.__amenazas = sorted(self.__amenazas, key=lambda x: x.total_amenaza, reverse=True)\n        print(f\"amenazas: {len(self.__amenazas)}\")\n        while len(self.__amenazas) > 0:\n            amenaza = self.__amenazas.pop(0)\n            # Neutralizar la amenaza en la superficie\n            self.__superficie[amenaza.coordenada.x][amenaza.coordenada.y].amenaza = 0\n            self.__superficie[amenaza.coordenada.x][amenaza.coordenada.y].neutralizado = True\n            # Guardamos el símbolo actual en la nueva posición (sensor o edificio)\n            simbolo_anterior = self.__superficie[amenaza.coordenada.x][amenaza.coordenada.y]\n\n            # Cambiamos la posición actual de Batman a '🏢' (donde estaba antes)\n            self.__superficie[self.batman_pos.x][self.batman_pos.y] = '🏢'\n\n            # Temporalmente colocamos el símbolo de Batman en la nueva posición\n            self.__superficie[amenaza.coordenada.x][amenaza.coordenada.y] = '🦇'\n\n            # Imprimimos el mapa con Batman en su nueva posición\n            \n            distancia = abs(amenaza.coordenada.x - 1) + abs(amenaza.coordenada.y - 1)\n\n            problema = random.choice(self.__problemas)\n            print(f\"Amenaza detectada lv {amenaza.total_amenaza}: {problema} en la coordenada ({amenaza.coordenada.x}, {amenaza.coordenada.y})\")\n\n            print(f\"Batman se ha movido {distancia} cuadrados para poder neutralizar la amenaza del sensor ({amenaza.coordenada.x}, {amenaza.coordenada.y})....\")\n            \n            self.print_gotham()\n\n            # Restauramos el símbolo anterior del sensor o el edificio\n            self.__superficie[amenaza.coordenada.x][amenaza.coordenada.y] = simbolo_anterior\n            self.__superficie[self.batman_pos.x][self.batman_pos.y] = '🦇'\n            # Recalcular las amenazas después de neutralizarlas\n            self.cal_amenaza()\n\n\n    def agregar_sensor(self, sensor: Sensor) -> None:\n        \"\"\"Agrega un nuevo sensor a la superficie y recalcula las amenazas.\"\"\"\n        # Añadimos el sensor a la superficie\n        self.__superficie[sensor.coordenada.x][sensor.coordenada.y] = sensor\n        print(f\"Sensor añadido en la coordenada ({sensor.coordenada.x}, {sensor.coordenada.y}) con nivel de amenaza {sensor.amenaza}.\")\n        # Recalculamos las amenazas después de agregar el sensor\n        self.cal_amenaza()\n\ndef print_batman_day(dias_de_batman_day: list) -> None:\n\n    for i in dias_de_batman_day:\n        print(i.strftime(\"%A, %d de %B de %Y\"))\n    print(\"\\n\")\n\n\ndef get_batman_day(limit:int = 30)-> list:\n\n    days = []\n\n\n    today = date.today()\n    for i in range(0,limit):\n        year = today.year + i\n        #formatear y setear al principio de mes\n        primer_dia_septiembre = date(year, 9, 1)\n        # primer sábado de septiembre\n        primer_sabado = primer_dia_septiembre + timedelta(days= (5 - primer_dia_septiembre.weekday()) % 7)\n        # sumamos dos semana para poder cuadrar las semanas\n        next_batman_day = primer_sabado + timedelta(weeks=2)\n        # comprobar si ya pasó el dia de batman.\n        if i == 0:\n            if next_batman_day.year == today.year and next_batman_day.month == today.month and next_batman_day.day== today.day:\n                days.append(next_batman_day)\n        else:\n            days.append(next_batman_day)\n\n    return days\n\n\n\n\n\nif __name__ == '__main__':\n\n    locale.setlocale(locale.LC_TIME, 'es_ES')\n\n    # dias_de_batman_day = get_batman_day()\n    # print(\"Las próximas fechas de los batmandays:\")\n    # print_batman_day(dias_de_batman_day)\n    sesores = [\n        Sensor(Coordenada(10,10), 2),\n        Sensor(Coordenada(8,10), 10),\n        Sensor(Coordenada(9,11), 8),\n        Sensor(Coordenada(10,12), 6),\n        Sensor(Coordenada(7,8), 3),\n        Sensor(Coordenada(15,8), 10),\n        Sensor(Coordenada(5,3), 5),\n        Sensor(Coordenada(1,7), 9),\n        Sensor(Coordenada(19,13), 1),\n        Sensor(Coordenada(3, 4), 7),\n        Sensor(Coordenada(12, 14), 4),\n        Sensor(Coordenada(18, 6), 6),\n        Sensor(Coordenada(14, 16), 9),\n        Sensor(Coordenada(16, 19), 10),\n        Sensor(Coordenada(13, 14), 5),\n        Sensor(Coordenada(19, 19), 8),\n        Sensor(Coordenada(6, 6), 10),\n        Sensor(Coordenada(3, 17), 3),\n        Sensor(Coordenada(13, 9), 6),\n        Sensor(Coordenada(5, 5), 9),\n        Sensor(Coordenada(6, 5), 10),\n        Sensor(Coordenada(5, 6), 8),\n\n    ]\n\n\n    ciudad = Gotham(sensores=sesores)\n\n    #ciudad.print_gotham()\n\n    ciudad.cal_amenaza()\n    # nuevos_sensores = [\n    #     Sensor(Coordenada(15, 15), 10),\n    #     Sensor(Coordenada(15, 16), 9),\n    #     Sensor(Coordenada(16, 16), 8),\n    #     Sensor(Coordenada(1, 1), 2),\n    #     Sensor(Coordenada(3, 3), 1),\n    #     Sensor(Coordenada(17, 18), 1),\n    #     Sensor(Coordenada(19, 19), 1)\n    # ]\n    # for nuevo in nuevos_sensores:\n    #     ciudad.agregar_sensor(nuevo)\n    # ciudad.cal_amenaza()\n"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/python/davidrguez98.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Cada año se celebra el Batman Day durante la tercera semana de septiembre... \n * ¡Y este año cumple 85 años! Te propongo un reto doble:\n *\n * RETO 1:\n * Crea un programa que calcule cuándo se va a celebrar el Batman Day hasta \n * su 100 aniversario.\n *\n * RETO 2:\n * Crea un programa que implemente el sistema de seguridad de la Batcueva. \n * Este sistema está diseñado para monitorear múltiples sensores distribuidos\n * por Gotham, detectar intrusos y activar respuestas automatizadas. \n * Cada sensor reporta su estado en tiempo real, y Batman necesita un programa \n * que procese estos datos para tomar decisiones estratégicas.\n * Requisitos:\n * - El mapa de Gotham y los sensores se representa con una cuadrícula 20x20.\n * - Cada sensor se identifica con una coordenada (x, y) y un nivel\n *   de amenaza entre 0 a 10 (número entero).\n * - Batman debe concentrar recursos en el área más crítica de Gotham.\n * - El programa recibe un listado de tuplas representando coordenadas de los \n *   sensores y su nivel de amenaza. El umbral de activación del protocolo de\n *   seguridad es 20 (sumatorio de amenazas en una cuadrícula 3x3).\n * Acciones: \n * - Identifica el área con mayor concentración de amenazas\n *   (sumatorio de amenazas en una cuadrícula 3x3).\n * - Si el sumatorio de amenazas es mayor al umbral, activa el \n *   protocolo de seguridad.\n * - Calcula la distancia desde la Batcueva, situada en (0, 0). La distancia es\n *   la suma absoluta de las coordenadas al centro de la cuadrícula amenazada.\n * - Muestra la coordenada al centro de la cuadrícula más amenazada, la suma de\n *   sus amenazas, la distancia a la Batcueva y si se debe activar el\n *   protocolo de seguridad.\n */ \"\"\"\n\n#RETO 1\n\nfrom datetime import datetime, timedelta\n\nyear_of_creation = 1939\nanniversary_year = year_of_creation + 85\n\nbatman_day_anniversary_dates = []\n\nwhile anniversary_year <= year_of_creation + 100:\n\n    september = datetime(anniversary_year, 9, 1)\n\n    first_saturday = 5 - september.weekday() if september.weekday() <= 5 else 12 - september.weekday()\n\n    third_saturday = september + timedelta(days=first_saturday + 14)\n    \n    batman_day_anniversary_dates.append((anniversary_year, anniversary_year - year_of_creation, third_saturday.strftime(\"%d-%m-%Y\")))\n\n    anniversary_year += 1\n\nfor year, anniversary, batman_day in batman_day_anniversary_dates:\n    print(f\"Batman day {year} ({anniversary} aniversario): {batman_day}\")\n\n#RETO 2\n\ndef sum_subgrid_alerts(sensors, x, y) -> int:\n\n    total = 0\n\n    for x in range(x - 1, x + 2):\n        for y in range(y - 1, y + 2):\n            for sensor in sensors:\n                if sensor[0] == x and sensor[1] == y:\n                    total += sensor[2]\n\n    return total\n\n\ndef batcave_security_system(sensors):\n\n    max_alert_level = 0\n    max_alert_coordinate = (0,0)\n    \n    for x in range(1, 19):\n        for y in range(1, 19):\n            alert_level = sum_subgrid_alerts(sensors, x, y)\n            if alert_level > max_alert_level:\n                max_alert_level = alert_level\n                max_alert_coordinate = (x, y)\n    \n    distance = abs(max_alert_coordinate[0]) + abs(max_alert_coordinate[1])\n    activate_protocol = max_alert_level > 20\n    \n\n    return max_alert_coordinate, max_alert_level, distance, activate_protocol\n\nsensors = [\n    (1, 5, 9),\n    (3, 8, 2),\n    (6, 1, 7),\n    (9, 4, 5),\n    (12, 7, 6),\n    (14, 10, 3),\n    (17, 13, 9),\n    (16, 13, 9),\n    (15, 13, 9),\n    (19, 15, 4),\n    (21, 18, 7),\n    (25, 20, 6)\n]\n\nresult = batcave_security_system(sensors)\nprint(f\"Centro cuadrícula más amenazada: {result[0]}.\")\nprint(f\"Máximo nivel de alerta: {result[1]}.\")\nprint(f\"Distancia a la Batcueva: {result[2]}.\")\nprint(f\"Activar protocolo de seguridad: {result[3]}.\")"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/python/duendeintemporal.py",
    "content": "#39 { Retos para Programadores } BATMAN DAY\n\n# Bibliography reference:\n# I use GPT as a reference and sometimes to correct or generate proper comments.\n\n\"\"\"\n * EJERCICIO:\n * Cada año se celebra el Batman Day durante la tercera semana de septiembre...\n * ¡Y este año cumple 85 años! Te propongo un reto doble:\n *\n * RETO 1:\n * Crea un programa que calcule cuándo se va a celebrar el Batman Day hasta\n * su 100 aniversario.\n *\n * RETO 2:\n * Crea un programa que implemente el sistema de seguridad de la Batcueva.\n * Este sistema está diseñado para monitorear múltiples sensores distribuidos\n * por Gotham, detectar intrusos y activar respuestas automatizadas.\n * Cada sensor reporta su estado en tiempo real, y Batman necesita un programa\n * que procese estos datos para tomar decisiones estratégicas.\n * Requisitos:\n * - El mapa de Gotham y los sensores se representa con una cuadrícula 20x20.\n * - Cada sensor se identifica con una coordenada (x, y) y un nivel\n *   de amenaza entre 0 a 10 (número entero).\n * - Batman debe concentrar recursos en el área más crítica de Gotham.\n * - El programa recibe un listado de tuplas representando coordenadas de los\n *   sensores y su nivel de amenaza. El umbral de activación del protocolo de\n *   seguridad es 20 (sumatorio de amenazas en una cuadrícula 3x3).\n * Acciones:\n * - Identifica el área con mayor concentración de amenazas\n *   (sumatorio de amenazas en una cuadrícula 3x3).\n * - Si el sumatorio de amenazas es mayor al umbral, activa el\n *   protocolo de seguridad.\n * - Calcula la distancia desde la Batcueva, situada en (0, 0). La distancia es\n *   la suma absoluta de las coordenadas al centro de la cuadrícula amenazada.\n * - Muestra la coordenada al centro de la cuadrícula más amenazada, la suma de\n *   sus amenazas, la distancia a la Batcueva y si se debe activar el\n *   protocolo de seguridad.\n\n\"\"\"\n\nlog = print\n\nimport datetime\nimport time\n\n# First Challenge\n\ndef calculate_batman_day():\n    start_year = 1939  # Year Batman was created\n    end_year = 2039    # 100th anniversary\n    batman_days = []\n\n    for year in range(start_year, end_year + 1):\n        batman_days.append(datetime.date(year, 9, 15))  # 9 represents September\n    return batman_days\n\nbat_days = calculate_batman_day()\nfor bd in bat_days:\n    log(bd)\n\n# Second Challenge\n\ndef security_system(sensors):\n    threshold = 20\n    grid_size = 20\n    max_threat = 0\n    best_coordinate = None\n\n    # Function to calculate the sum of threats in a 3x3 grid\n    def calculate_threat_sum(x, y):\n        sum_threat = 0\n        for i in range(-1, 2):\n            for j in range(-1, 2):\n                nx = x + i\n                ny = y + j\n                if 0 <= nx < grid_size and 0 <= ny < grid_size:\n                    sensor = next((s for s in sensors if s['x'] == nx and s['y'] == ny), None)\n                    if sensor:\n                        sum_threat += sensor['threatLevel']\n        return sum_threat\n\n    # Evaluate each sensor\n    for sensor in sensors:\n        threat_sum = calculate_threat_sum(sensor['x'], sensor['y'])\n        if threat_sum > max_threat:\n            max_threat = threat_sum\n            best_coordinate = {'x': sensor['x'], 'y': sensor['y']}\n\n    # Calculate distance to the Batcave\n    distance = abs(best_coordinate['x']) + abs(best_coordinate['y']) if best_coordinate else 0\n    activate_protocol = max_threat > threshold\n\n    if activate_protocol:\n        log(f\"There's a potential risk level at X: {best_coordinate['x']} and Y: {best_coordinate['y']} coords, \"\n              f\"at {distance} meters of the Batcave. The Secure System Protocol is activated. \"\n              \"It could be dangerous for any intruder.\\n\")\n        log(\"Speakers Sound in the Batcave: You'll be wishing to better not disturb the Bat rest!\")\n    else:\n        log(f\"The biggest risk is at {best_coordinate}, at {distance} meters of the Batcave. \"\n              \"It isn't considered too high to activate the Secure System Protocol.\")\n\n    log(f'coordinate: {best_coordinate}, threatSum: {max_threat}, distance: {distance}, activateProtocol: {activate_protocol}')\n\n    return {\n        'coordinate': best_coordinate,\n        'threatSum': max_threat,\n        'distance': distance,\n        'activateProtocol': activate_protocol\n    }\n\n# Example usage\nsensors = [\n    {'x': 0, 'y': 0, 'threatLevel': 7},\n    {'x': 0, 'y': 1, 'threatLevel': 2},\n    {'x': 1, 'y': 0, 'threatLevel': 8},\n    {'x': 1, 'y': 1, 'threatLevel': 3},\n    {'x': 2, 'y': 2, 'threatLevel': 4},\n    {'x': 1, 'y': 2, 'threatLevel': 6},\n    {'x': 2, 'y': 1, 'threatLevel': 4},\n    {'x': 2, 'y': 3, 'threatLevel': 5},\n    {'x': 3, 'y': 2, 'threatLevel': 7},\n    {'x': 3, 'y': 3, 'threatLevel': 9},\n    # Add more sensors as needed\n]\n\nlog(security_system(sensors))\n\n# Simulate the alert after 2 seconds\ntime.sleep(2)\nlog('Retosparaprogramadores #39.')\n\n\"\"\"\nOutput:\n\nDates from: 1939-09-15 to 2039-09-15\n\nThere's a potential risk level at X: 2 and Y: 2 coords, at 4 meters of the Batcave. The Secure System Protocol is activated. It could be dangerous for any intruder.\n\nSpeakers Sound in the Batcave: You'll be wishing to better not disturb the Bat rest!\ncoordinate: {'x': 2, 'y': 2}, threatSum: 38, distance: 4, activateProtocol: True\n{'coordinate': {'x': 2, 'y': 2}, 'threatSum': 38, 'distance': 4, 'activateProtocol': True}\n\n\"\"\"\n"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/python/hectorio23.py",
    "content": "# Autor: Héctor Adán\n# GitHub: https://github.com/hectorio23\n\n#################################################3\n##################### RETO 1 #####################\n##################################################\n\nfrom datetime import datetime, timedelta\n\ndef calculate_batman_day():\n    current_year = datetime.now().year\n    for year in range(current_year, 2039):  # Desde el año actual hasta el 100 aniversario\n        september_first = datetime(year, 9, 1)\n        third_saturday = september_first + timedelta(days=(5 - september_first.weekday()) % 7 + 14)\n        print(f\"Batman Day {year}: {third_saturday.strftime('%Y-%m-%d')}\")\n\ncalculate_batman_day()\n\n\n#################################################3\n##################### RETO 2 #####################\n##################################################\n\nimport math\n\ndef batcave_security_system(sensors):\n    grid_size = 20\n    threshold = 20\n    max_threat = 0\n    critical_area = None\n\n    # Analizar todas las áreas de 3x3 en la cuadrícula\n    for i in range(grid_size - 2):\n        for j in range(grid_size - 2):\n            threat_sum = 0\n            for x in range(i, i + 3):\n                for y in range(j, j + 3):\n                    threat_sum += sensors.get((x, y), 0)\n            \n            if threat_sum > max_threat:\n                max_threat = threat_sum\n                critical_area = (i + 1, j + 1)  # Centro de la cuadrícula\n\n    # Calcular distancia desde la Batcueva (0, 0)\n    if critical_area:\n        distance = abs(critical_area[0]) + abs(critical_area[1])\n        print(f\"Área más amenazada: {critical_area}, Amenazas: {max_threat}, Distancia a la Batcueva: {distance}\")\n        if max_threat > threshold:\n            print(\"Protocolo de seguridad activado.\")\n\n# Ejemplo de sensores\nsensors = {\n    (5, 5): 8, (5, 6): 7, (5, 7): 6,\n    (6, 5): 9, (6, 6): 5, (6, 7): 4,\n    (7, 5): 3, (7, 6): 2, (7, 7): 10,\n}\nbatcave_security_system(sensors)\n"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/python/hozlucas28.py",
    "content": "# pylint: disable=missing-module-docstring,missing-function-docstring\n\nfrom datetime import datetime\nfrom typing import Literal, Tuple, TypedDict, List\n\n\n# ---------------------------------------------------------------------------- #\n#                                FIRST CHALLENGE                               #\n# ---------------------------------------------------------------------------- #\n\n\ndef get_batman_day_anniversary(*, anniversary: int) -> datetime:\n    anniversary_date: datetime = datetime(year=1939, month=9, day=16)\n\n    if anniversary > 0:\n        anniversary_date = datetime(\n            year=anniversary_date.year + anniversary,\n            month=anniversary_date.month,\n            day=1,\n        )\n\n        i: int = 1\n        saturday_counter: int = 1 if anniversary_date.weekday() == 5 else 0\n\n        while saturday_counter < 3:\n            anniversary_date = datetime(\n                year=anniversary_date.year, month=anniversary_date.month, day=i\n            )\n\n            if anniversary_date.weekday() == 5:\n                saturday_counter += 1\n\n            i += 1\n\n    return anniversary_date\n\n\nbatman_day_85th_anniversary: datetime = get_batman_day_anniversary(anniversary=85)\nbatman_day_100th_anniversary: datetime = get_batman_day_anniversary(anniversary=100)\n\nprint(\"> First challenge...\")\n\nprint(\n    f\"\\n> The 85th anniversary of Batman day is on \"\n    f\"{batman_day_85th_anniversary.month}/\"\n    f\"{batman_day_85th_anniversary.day}/\"\n    f\"{batman_day_85th_anniversary.year}.\"\n)\n\nprint(\n    f\"\\n> The 100th anniversary of Batman day is on \"\n    f\"{batman_day_100th_anniversary.month}/\"\n    f\"{batman_day_100th_anniversary.day}/\"\n    f\"{batman_day_100th_anniversary.year}.\"\n)\n\n\n# ---------------------------------------------------------------------------- #\n#                               SECOND CHALLENGE                               #\n# ---------------------------------------------------------------------------- #\n\n\n# ----------------------------------- Types ---------------------------------- #\n\n\ntype ThreatLevel = Literal[\n    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20\n]\n\ntype RowSensors = Tuple[\n    ThreatLevel,\n    ThreatLevel,\n    ThreatLevel,\n    ThreatLevel,\n    ThreatLevel,\n    ThreatLevel,\n    ThreatLevel,\n    ThreatLevel,\n    ThreatLevel,\n    ThreatLevel,\n    ThreatLevel,\n    ThreatLevel,\n    ThreatLevel,\n    ThreatLevel,\n    ThreatLevel,\n    ThreatLevel,\n    ThreatLevel,\n    ThreatLevel,\n    ThreatLevel,\n    ThreatLevel,\n]\n\ntype Sensors = Tuple[\n    RowSensors,\n    RowSensors,\n    RowSensors,\n    RowSensors,\n    RowSensors,\n    RowSensors,\n    RowSensors,\n    RowSensors,\n    RowSensors,\n    RowSensors,\n    RowSensors,\n    RowSensors,\n    RowSensors,\n    RowSensors,\n    RowSensors,\n    RowSensors,\n    RowSensors,\n    RowSensors,\n    RowSensors,\n    RowSensors,\n]\n\nThreatLevelPos = TypedDict(\"ThreatLevelPos\", {\"x\": int, \"y\": int, \"threat_level\": int})\n\n\n# ----------------------------------- Main ----------------------------------- #\n\n\ndef get_threat_levels(*, _sensors: Sensors) -> List[ThreatLevelPos]:\n    _threat_levels: List[ThreatLevelPos] = []\n\n    for i in range(1, len(_sensors) - 1):\n        for j in range(1, len(_sensors[i]) - 1):\n            _threat_level: int = 0\n\n            _threat_level += _sensors[i - 1][j - 1]\n            _threat_level += _sensors[i - 1][j]\n            _threat_level += _sensors[i - 1][j + 1]\n\n            _threat_level += _sensors[i][j - 1]\n            _threat_level += _sensors[i][j]\n            _threat_level += _sensors[i][j + 1]\n\n            _threat_level += _sensors[i + 1][j - 1]\n            _threat_level += _sensors[i + 1][j]\n            _threat_level += _sensors[i + 1][j + 1]\n\n            _threat_levels.append({\"x\": j, \"threat_level\": _threat_level, \"y\": i})\n\n    return _threat_levels\n\n\nbatman_cave_pos: Tuple[int, int] = (0, 0)\n\nsensors: Sensors = (\n    (1, 0, 1, 1, 2, 0, 1, 2, 0, 1, 0, 1, 2, 0, 1, 0, 1, 2, 0, 1),\n    (2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0),\n    (1, 0, 1, 2, 0, 1, 0, 1, 2, 0, 1, 0, 1, 2, 0, 1, 0, 1, 0, 1),\n    (0, 9, 8, 0, 2, 0, 9, 2, 8, 1, 0, 1, 3, 7, 8, 1, 0, 2, 7, 6),\n    (1, 0, 1, 1, 2, 0, 1, 2, 0, 1, 0, 1, 2, 0, 1, 0, 1, 2, 0, 1),\n    (3, 1, 8, 7, 9, 6, 1, 7, 9, 0, 1, 0, 1, 9, 2, 1, 3, 0, 8, 0),\n    (1, 6, 9, 1, 2, 8, 0, 2, 1, 3, 2, 8, 7, 2, 8, 0, 1, 7, 9, 0),\n    (1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 1, 0),\n    (0, 1, 0, 1, 2, 0, 1, 0, 1, 2, 0, 1, 0, 1, 2, 0, 1, 0, 1, 0),\n    (2, 0, 1, 0, 1, 2, 0, 1, 0, 1, 0, 1, 2, 0, 1, 0, 1, 0, 1, 2),\n    (7, 8, 6, 1, 0, 9, 2, 8, 1, 3, 7, 1, 0, 2, 0, 9, 1, 6, 7, 8),\n    (0, 1, 7, 9, 2, 8, 1, 6, 7, 8, 1, 2, 0, 3, 1, 8, 2, 7, 0, 1),\n    (3, 0, 9, 1, 8, 6, 1, 0, 7, 9, 2, 0, 1, 2, 8, 0, 1, 9, 6, 1),\n    (1, 1, 0, 1, 2, 0, 1, 0, 1, 2, 0, 1, 0, 1, 2, 0, 1, 0, 1, 0),\n    (0, 1, 0, 1, 2, 0, 1, 0, 1, 2, 0, 1, 0, 1, 2, 0, 1, 0, 1, 0),\n    (2, 0, 1, 0, 1, 2, 0, 1, 0, 1, 0, 1, 2, 0, 1, 0, 1, 0, 1, 2),\n    (9, 6, 1, 0, 9, 8, 7, 2, 8, 0, 1, 0, 3, 6, 2, 7, 9, 2, 8, 1),\n    (0, 7, 8, 9, 6, 2, 1, 9, 6, 7, 8, 0, 9, 7, 6, 8, 1, 0, 2, 8),\n    (2, 0, 1, 0, 1, 2, 0, 1, 0, 1, 0, 1, 2, 0, 1, 0, 1, 0, 1, 2),\n    (3, 2, 1, 9, 6, 7, 0, 3, 1, 8, 2, 7, 9, 2, 0, 9, 7, 6, 8, 0),\n)\n\nthreat_levels: List[ThreatLevelPos] = get_threat_levels(_sensors=sensors)\n\nthreat_levels_greater_than_twenty = list(\n    filter(lambda threat_level: threat_level[\"threat_level\"] >= 20, threat_levels)\n)\n\nprint(\"\\n> Second challenge...\")\n\nprint(\"\\n> Threat levels greater than 20 (security protocol activated)...\")\n\nfor threat_level in threat_levels_greater_than_twenty:\n    print(f\"\\n> Coordinates (x, y): ({threat_level['x']}, {threat_level['y']}).\")\n    print(f\"> Threat level: {threat_level['threat_level']}.\")\n\nprint(\"\\n> Position with the maximum threat level...\")\n\nmax_threat_level: ThreatLevelPos = max(\n    iter(threat_levels_greater_than_twenty),\n    key=lambda threat_level: threat_level[\"threat_level\"],\n)\n\ndistance_to_batman_cave: int = abs(max_threat_level[\"x\"] - batman_cave_pos[0]) + abs(\n    max_threat_level[\"y\"] - batman_cave_pos[1]\n)\n\nprint(f\"\\n> Coordinates (x, y): ({max_threat_level['x']}, {max_threat_level['y']}).\")\nprint(f\"> Threat level: {max_threat_level['threat_level']}.\")\nprint(f\"> Distance to batman cave: {distance_to_batman_cave} cells.\")\n"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/python/idiegorojas.py",
    "content": "\"\"\" # 39 - Batman Day\"\"\"\n\n\"\"\" * RETO 1: \"\"\"\n# Crea un programa que calcule cuándo se va a celebrar el Batman Day hasta su 100 aniversario.\n\n\"\"\" * RETO 2: \"\"\"\n# Crea un programa que implemente el sistema de seguridad de la Batcueva.\n# Este sistema está diseñado para monitorear múltiples sensores distribuidos por Gotham, detectar intrusos y activar respuestas automatizadas.\n# Cada sensor reporta su estado en tiempo real, y Batman necesita un programa que procese estos datos para tomar decisiones estratégicas.\n\n\"\"\" Requisitos: \"\"\"\n# El mapa de Gotham y los sensores se representa con una cuadrícula 20x20.\n# Cada sensor se identifica con una coordenada (x, y) y un nivel de amenaza entre 0 a 10 (número entero).\n# Batman debe concentrar recursos en el área más crítica de Gotham.\n# El programa recibe un listado de tuplas representando coordenadas de los sensores y su nivel de amenaza. El umbral de activación del protocolo de seguridad es 20 (sumatorio de amenazas en una cuadrícula 3x3).\n\n\"\"\" Acciones: \"\"\"\n# Identifica el área con mayor concentración de amenazas (sumatorio de amenazas en una cuadrícula 3x3).\n# Si el sumatorio de amenazas es mayor al umbral, activa el protocolo de seguridad.\n# Calcula la distancia desde la Batcueva, situada en (0, 0). La distancia es\n# la suma absoluta de las coordenadas al centro de la cuadrícula amenazada.\n# Muestra la coordenada al centro de la cuadrícula más amenazada, la suma de sus amenazas, la distancia a la Batcueva y si se debe activar el protocolo de seguridad.\n\n\n\"\"\" Reto #1 \"\"\"\nfrom datetime import datetime, timedelta\n\nyear_of_creation = 1939\nanniversary_year = year_of_creation + 85\n\nbatman_day_anniversary_dates = []\n\nwhile anniversary_year <= year_of_creation + 100:\n\n    september = datetime(anniversary_year, 9, 1)\n\n    first_saturday = 5 - september.weekday() if september.weekday() <= 5 else 12 - \\\n        september.weekday()\n\n    third_saturday = september + timedelta(days=first_saturday + 14)\n\n    batman_day_anniversary_dates.append(\n        (\n            anniversary_year,\n            anniversary_year - year_of_creation,\n            third_saturday.strftime(\"%d-%m-%Y\")\n        )\n    )\n\n    anniversary_year += 1\n\nfor year, anniversary, batman_day in batman_day_anniversary_dates:\n    print(f\"Batman day {year} ({anniversary} aniversario): {batman_day}\")\n\n\n\n\"\"\" Reto #2 \"\"\"\ndef sistema_seguridad_batcueva(sensores):\n    # Inicializar la cuadrícula 20x20 con ceros\n    cuadricula_gotham = [[0 for _ in range(20)] for _ in range(20)]\n    \n    # Poblar la cuadrícula con niveles de amenaza de los sensores\n    for x, y, nivel_amenaza in sensores:\n        if 0 <= x < 20 and 0 <= y < 20:\n            cuadricula_gotham[y][x] = nivel_amenaza\n    \n    suma_amenazas_maxima = 0\n    centro_amenaza_maxima = (0, 0)\n    \n    # Comprobar cada posible cuadrícula 3x3\n    for centro_y in range(1, 19):\n        for centro_x in range(1, 19):\n            suma_amenazas = 0\n            \n            # Sumar amenazas en la cuadrícula 3x3 alrededor del centro\n            for dy in range(-1, 2):\n                for dx in range(-1, 2):\n                    suma_amenazas += cuadricula_gotham[centro_y + dy][centro_x + dx]\n            \n            # Actualizar si esta es el área con mayor amenaza\n            if suma_amenazas > suma_amenazas_maxima:\n                suma_amenazas_maxima = suma_amenazas\n                centro_amenaza_maxima = (centro_x, centro_y)\n    \n    # Calcular distancia desde la Batcueva (0,0) hasta el centro de amenaza\n    distancia_a_batcueva = abs(centro_amenaza_maxima[0]) + abs(centro_amenaza_maxima[1])\n    \n    # Determinar si se debe activar el protocolo de seguridad\n    activar_protocolo = suma_amenazas_maxima >= 20\n    \n    return {\n        \"centro_amenaza\": centro_amenaza_maxima,\n        \"suma_amenazas\": suma_amenazas_maxima,\n        \"distancia\": distancia_a_batcueva,\n        \"activar_protocolo\": activar_protocolo\n    }\n\n# Ejemplo de uso:\nif __name__ == \"__main__\":\n    # Lista de ejemplo de sensores: (x, y, nivel_amenaza)\n    sensores_ejemplo = [\n        (5, 5, 8),\n        (6, 5, 7),\n        (7, 5, 6),\n        (5, 6, 5),\n        (6, 6, 9),\n        (7, 6, 4),\n        (5, 7, 3),\n        (6, 7, 2),\n        (7, 7, 1),\n        (10, 15, 10),\n        (2, 3, 6)\n    ]\n    \n    resultado = sistema_seguridad_batcueva(sensores_ejemplo)\n    \n    print(\"\\nInforme del Sistema de Seguridad de la Batcueva:\")\n    print(f\"Área más amenazada: {resultado['centro_amenaza']}\")\n    print(f\"Suma de nivel de amenaza: {resultado['suma_amenazas']}\")\n    print(f\"Distancia desde la Batcueva: {resultado['distancia']}\")\n    print(f\"Protocolo de seguridad activado: {'SÍ' if resultado['activar_protocolo'] else 'NO'}\")"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/python/ignaciovihe.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Cada año se celebra el Batman Day durante la tercera semana de septiembre... \n * ¡Y este año cumple 85 años! Te propongo un reto doble:\n *\n * RETO 1:\n * Crea un programa que calcule cuándo se va a celebrar el Batman Day hasta \n * su 100 aniversario.\n *\n * RETO 2:\n * Crea un programa que implemente el sistema de seguridad de la Batcueva. \n * Este sistema está diseñado para monitorear múltiples sensores distribuidos\n * por Gotham, detectar intrusos y activar respuestas automatizadas. \n * Cada sensor reporta su estado en tiempo real, y Batman necesita un programa \n * que procese estos datos para tomar decisiones estratégicas.\n * Requisitos:\n * - El mapa de Gotham y los sensores se representa con una cuadrícula 20x20.\n * - Cada sensor se identifica con una coordenada (x, y) y un nivel\n *   de amenaza entre 0 a 10 (número entero).\n * - Batman debe concentrar recursos en el área más crítica de Gotham.\n * - El programa recibe un listado de tuplas representando coordenadas de los \n *   sensores y su nivel de amenaza. El umbral de activación del protocolo de\n *   seguridad es 20 (sumatorio de amenazas en una cuadrícula 3x3).\n * Acciones: \n * - Identifica el área con mayor concentración de amenazas\n *   (sumatorio de amenazas en una cuadrícula 3x3).\n * - Si el sumatorio de amenazas es mayor al umbral, activa el \n *   protocolo de seguridad.\n * - Calcula la distancia desde la Batcueva, situada en (0, 0). La distancia es\n *   la suma absoluta de las coordenadas al centro de la cuadrícula amenazada.\n * - Muestra la coordenada al centro de la cuadrícula más amenazada, la suma de\n *   sus amenazas, la distancia a la Batcueva y si se debe activar el\n *   protocolo de seguridad.\n\"\"\"\n\n#Reto 1 Calcular semana Batmanday\n\nimport calendar\n\n\ndef get_batman_weeks():\n    edition = 85\n    for  year in range(2024,2040):\n        september = calendar.monthcalendar(year, 9)\n        batman_day = september[2][5]\n        print(f\"En {year}, la {edition} BatmanWeek es día {batman_day} de septiembre.\")\n        edition += 1\n\nget_batman_weeks()\n\nprint(\"##########################################\")\n# Reto 2 \n\nfrom abc import ABC, abstractmethod\nfrom typing import Tuple, Set, Optional\n\nthreats = [\n    ((5,17),3),\n    ((4,7),6),\n    ((19,5),8),\n    ((8,14),5),\n    ((9,13),2),\n    ((2,0),9),\n    ((15,1),10),\n    ((13,14),5),\n    ((10,10),7),\n    ((2,16),9),\n    ((9,19),2),\n    ((5,8),9),\n    ((9,4),10),\n    ((15,16),6),\n    ((17,8),6),\n    ((2, 3), 7),\n    ((4, 3), 8),\n    ((2, 2), 7),\n    ((10, 12), 8),\n    ((11, 11), 8),\n    ((10, 11), 8),\n    ((15, 18), 4),\n    ((12, 11), 1),\n]\n\nclass IGothamMap(ABC):\n    @abstractmethod\n    def get_size(self) -> int:\n        pass\n\n    @abstractmethod\n    def get_sensor(self, x: int, y: int):\n        pass\n\n    @abstractmethod\n    def get_max_threats(self) -> Set[Tuple[int, int]]:\n        pass\n\n    @abstractmethod\n    def clear_max_threats(self):\n        pass\n\n    @abstractmethod\n    def add_max_threat(self, coord: Tuple[int,int]):\n        pass\n\n\nclass Sensor:\n    def __init__(self, local_threat = 0, area_threat = 0, batcave = False) -> None:\n        self.local_threat = local_threat\n        self.area_threat = area_threat\n        self.batcave = batcave\n\n\nclass GothamMap(IGothamMap):\n    def __init__(self, gotham_size = 20) -> None:\n        self.gotham_size = gotham_size\n        self.map = [[Sensor() for _ in range(gotham_size)] for _ in range(gotham_size)]\n        self.max_threats = set()\n        self.map[0][0].batcave = True\n\n    def get_size(self) -> int:\n        return self.gotham_size\n    \n    def get_sensor(self, x: int, y: int) -> Optional[Sensor]:\n        if 0 <= x < self.gotham_size and 0 <= y < self.gotham_size:\n            return self.map[x][y]\n        return None\n    \n    def get_max_threats(self) -> Set[Tuple[int, int]]:\n        return self.max_threats\n    \n    def clear_max_threats(self):\n        self.max_threats.clear()\n\n    def add_max_threat(self, coord: Tuple[int, int]):\n        self.max_threats.add(coord)\n\n    def print_local_threats(self):\n        for line in self.map:\n            for sensor in line:\n                valor = \"B\" if sensor.batcave else str(sensor.local_threat)\n                print(f\"{valor:>3}\", end=\" \")\n            print()\n\n    def print_area_threats(self):\n        for line in self.map:\n            for sensor in line:\n                valor = \"B\" if sensor.batcave else str(sensor.area_threat)\n                print(f\"{valor:>3}\", end=\" \")\n            print()\n\n\nclass ThreatsManager:\n    def __init__(self, gotham_map: IGothamMap) -> None:\n        self.gotham_map = gotham_map\n\n    def update_local_threats(self, threats):\n        for threat in threats:\n            x, y = threat[0]\n            sensor = self.gotham_map.get_sensor(x, y)\n            if sensor:\n                sensor.local_threat = threat[1]\n            else:\n                print(f\"Advertencia: coordenadas inválidas ({x}, {y})\")\n\n    def update_area_threats(self):\n        max_threat = 0\n        size = self.gotham_map.get_size()\n        for line_index in range(size):\n            for sensor_index in range(size):\n                sensor = self.gotham_map.get_sensor(line_index, sensor_index)\n                if sensor:\n                    sensor.area_threat = 0\n                    for x in range(-1,2):\n                        for y in range(-1,2):\n                            neighbour_x = line_index + x\n                            neighbour_y = sensor_index + y\n                            if (0 <= (neighbour_x) < size) and (0 <= (neighbour_y) < size):\n                                neighbour_sensor = gotham_map.get_sensor(neighbour_x,neighbour_y)\n                                if neighbour_sensor:\n                                    sensor.area_threat += neighbour_sensor.local_threat\n\n                    if sensor.area_threat >= max_threat:\n                        if sensor.area_threat > max_threat:\n                            self.gotham_map.clear_max_threats()\n                        self.gotham_map.add_max_threat((line_index, sensor_index))\n                        max_threat = sensor.area_threat\n\n\nclass SecurityProtocolChecker:\n    def __init__(self, gotham_map: IGothamMap) -> None:\n        self.gotham_map = gotham_map\n\n    def calculate_distance(self, coordinate):\n        return abs(coordinate[0]) + abs(coordinate[1])\n\n    def activate_protocol(self):\n        for threat in self.gotham_map.get_max_threats():\n            x, y = threat\n            sensor = self.gotham_map.get_sensor(x, y)\n            if sensor:\n                area_threat = sensor.area_threat\n                print(f\"Centro cuadrícula más amenazada: {threat}.\")\n                print(f\"Máximo nivel de alerta: {area_threat}\")\n                print(f\"Distancia a la Batcueva: {self.calculate_distance(threat)}\")\n                print(f\"Activar protocolo de seguridad: {\"Si.\" if area_threat >= 20 else \"No.\"}\")\n                print()\n\n\n\ngotham_map = GothamMap()\nthreats_manager = ThreatsManager(gotham_map)\nsecurity_protocol_checker = SecurityProtocolChecker(gotham_map)\n\nthreats_manager.update_local_threats(threats)\nthreats_manager.update_area_threats()\n\ngotham_map.print_local_threats()\nprint()\ngotham_map.print_area_threats()\nprint()\n\nsecurity_protocol_checker.activate_protocol()\n"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/python/juanmax2.py",
    "content": "\"\"\"\n * RETO 1:\n * Crea un programa que calcule cuándo se va a celebrar el Batman Day hasta \n * su 100 aniversario.\n\"\"\"\n\nfrom datetime import datetime, timedelta ,time\n\naño_creacion = 1939\n\naño_aniversario = año_creacion + 86\n\ndia_aniversario_fechas = []\n\nwhile año_aniversario <= año_creacion + 100:\n    \n    septiembre = datetime(año_aniversario, 9, 1)\n    \n    primer_sabado = 5 - septiembre.weekday() if septiembre.weekday() <= 5 else 12 - septiembre.weekday()\n    \n    tercer_sabado = septiembre + timedelta(days=primer_sabado + 14)\n    \n    \n    dia_aniversario_fechas.append(\n        (\n            año_aniversario,\n            año_aniversario - año_creacion,\n            tercer_sabado.strftime(\"%d-%m-%Y\")\n        )\n        \n    )\n    año_aniversario += 1\nfor year, aniversario, batman_day in dia_aniversario_fechas:\n    print(f\"Batman day {year} ({aniversario} aniversario): {batman_day}\")\n    \n\n\n\"\"\"\nReto 2 - Sistema seguridad batcueva\n\n\"\"\"\n\ndef sum_subgrid(sensores, x, y):\n    \n    total = 0\n    \n    for x in range(x - 1, x + 2):\n        for y in range(y - 1, y + 2):\n            for sensor in sensores:\n                if sensor[0] == x and sensor[1] == y:\n                    total += sensor[2]\n    return total\n\ndef sistema_seguridad(sensores):\n    \n    mayor_nivel_alerta = 0\n    mayor_alerta_cordenada = (0, 0)\n    \n    for x in range(1, 19):\n        for y in range(1, 19):\n            nivel_alerta = sum_subgrid(sensores, x, y)\n            if nivel_alerta > mayor_nivel_alerta:\n                mayor_nivel_alerta = nivel_alerta\n                mayor_alerta_cordenada = (x, y)\n    activar_protocolo = mayor_nivel_alerta > 20\n    distancia = abs(mayor_alerta_cordenada[0]) + abs(mayor_alerta_cordenada[1])\n    return mayor_nivel_alerta, mayor_alerta_cordenada, activar_protocolo, distancia\n                \n\n\nsensores = [\n    (2, 3, 6),\n    (4, 3, 5),\n    (2, 2, 7),\n    (10, 12, 8),\n    (15, 16, 4),\n    (14, 16, 6),\n    (2, 4, 10)\n]\n\nresultado = sistema_seguridad(sensores)\nprint(f\"Maximo nivel de alaerta: {resultado[0]}\")\nprint(f\"Cordenadas de la alerta: {resultado[1]}\")\nprint(f\"Activar protocolo: {resultado[2]}\")\nprint(f\"Distancia hasta las cordenadas: {resultado[3]}\")"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/python/kenysdev.py",
    "content": "# _____________________________________\n# https://github.com/kenysdev\n# 2024 - Python\n# _____________________________________\n# 39 BATMAN DAY\n# ------------------------------------\n\n\"\"\"\n* RETO 1:\n* Crea un programa que calcule cuándo se va a celebrar el Batman Day hasta \n* su 100 aniversario.\n\"\"\"\n\nfrom datetime import timedelta, date\n\ndef third_saturday_of_september(year) -> str:\n    d = date(year, 9, 15)\n    d += timedelta(days=(5 - d.weekday() + 7) % 7)\n    return d.strftime(\"%d-%m-%Y\")\n\ndef anniversary_dates(total_anniversarys: int) -> None:\n    batman_day_start = 2014\n    current_year = date.today().year\n    if current_year < batman_day_start:\n        print(\"xd\")\n        return\n\n    past_anniversaries = current_year - batman_day_start\n    print(f\"Aniversarios que ya han pasado: {past_anniversaries}\")\n    \n    for i in range(total_anniversarys - past_anniversaries):\n        num: int = past_anniversaries + i + 1\n        the_date: str = third_saturday_of_september(current_year)\n        print(f\"- Aniversario #{num}: {the_date}\")\n        current_year +=1\n\nprint(\"Batman Day\")\nanniversary_dates(100)\n\n\"\"\"\n * RETO 2:\n * Crea un programa que implemente el sistema de seguridad de la Batcueva. \n * Este sistema está diseñado para monitorear múltiples sensores distribuidos\n * por Gotham, detectar intrusos y activar respuestas automatizadas. \n * Cada sensor reporta su estado en tiempo real, y Batman necesita un programa \n * que procese estos datos para tomar decisiones estratégicas.\n * Requisitos:\n * - El mapa de Gotham y los sensores se representa con una cuadrícula 20x20.\n * - Cada sensor se identifica con una coordenada (x, y) y un nivel\n *   de amenaza entre 0 a 10 (número entero).\n * - Batman debe concentrar recursos en el área más crítica de Gotham.\n * - El programa recibe un listado de tuplas representando coordenadas de los \n *   sensores y su nivel de amenaza. El umbral de activación del protocolo de\n *   seguridad es 20 (sumatorio de amenazas en una cuadrícula 3x3).\n * Acciones: \n * - Identifica el área con mayor concentración de amenazas\n *   (sumatorio de amenazas en una cuadrícula 3x3).\n * - Si el sumatorio de amenazas es mayor al umbral, activa el \n *   protocolo de seguridad.\n * - Calcula la distancia desde la Batcueva, situada en (0, 0). La distancia es\n *   la suma absoluta de las coordenadas al centro de la cuadrícula amenazada.\n * - Muestra la coordenada al centro de la cuadrícula más amenazada, la suma de\n *   sus amenazas, la distancia a la Batcueva y si se debe activar el\n *   protocolo de seguridad.\n\"\"\"\n\ndef create_map(size: tuple, batcave: tuple, sensors: list, threats: list) -> list:\n    gotham: list = [['| '] * 20 for _ in range(20)]\n    gotham[batcave[0]][batcave[1]] = '|B'\n\n    for s in sensors:\n        gotham[s[0]][s[1]] = '|S'\n\n    for t in threats:\n        gotham[t[0]][t[1]] = '|T'\n\n    return gotham\n\ndef print_map(gotham: list) -> None:\n    print(\"\\nMapa de Gotham:\")\n    for row in gotham:\n        print(\"\".join(map(str, row)))\n\ndef scan_map(gotham: list, sensors: list) -> None:\n    danger_list = []\n    for c, s in enumerate(sensors):\n        danger_counter: int = 0\n        for i in range(s[0] - 1, s[0] + 2):\n            for j in range(s[1] - 1, s[1] + 2):\n                if gotham[i][j] == '|T':\n                    danger_counter += s[2]\n        danger_list.append((c, danger_counter))\n    \n    max_danger: tuple = max(danger_list, key=lambda x: x[1])\n    location: tuple = sensors[max_danger[0]]\n\n    print(\"\\nInforme:\")\n    print(f\"Cuadrícula más amenazada: '{location[0]}, {location[1]}'\")\n    print(f\"Máximo nivel de alerta: '{max_danger[1]}'\")\n    if max_danger[1] >= 20:\n        print(\"Protocolo de seguridad activado.\")\n        print(f\"Distancia: '{location[0] + location[1]}'\")\n    else:\n        print(\"No hay amenazas relevantes.\")\n\nbatcave: tuple = (0, 0)\nsensors: list = [(2, 2, 10), (6, 8, 9), (10, 12, 8), (17, 15, 7)]\nthreats: list = [(2, 3), (2, 1), (6, 9), (17, 16), (15, 4)]\ngotham: list = create_map((20, 20), batcave, sensors, threats)\nprint_map(gotham)\nscan_map(gotham, sensors)\n"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/python/mhayhem.py",
    "content": "# @Author Daniel Grande (Mhayhemn)\n\n\n# EJERCICIO:\n# Cada año se celebra el Batman Day durante la tercera semana de septiembre... \n# ¡Y este año cumple 85 años! Te propongo un reto doble:\n#\n# RETO 1:\n# Crea un programa que calcule cuándo se va a celebrar el Batman Day hasta \n# su 100 aniversario.\n#\n# RETO 2:\n# Crea un programa que implemente el sistema de seguridad de la Batcueva. \n# Este sistema está diseñado para monitorear múltiples sensores distribuidos\n# por Gotham, detectar intrusos y activar respuestas automatizadas. \n# Cada sensor reporta su estado en tiempo real, y Batman necesita un programa \n# que procese estos datos para tomar decisiones estratégicas.\n# Requisitos:\n# - El mapa de Gotham y los sensores se representa con una cuadrícula 20x20.\n# - Cada sensor se identifica con una coordenada (x, y) y un nivel\n#   de amenaza entre 0 a 10 (número entero).\n# - Batman debe concentrar recursos en el área más crítica de Gotham.\n# - El programa recibe un listado de tuplas representando coordenadas de los \n#   sensores y su nivel de amenaza. El umbral de activación del protocolo de\n#   seguridad es 20 (sumatorio de amenazas en una cuadrícula 3x3).\n# Acciones: \n# - Identifica el área con mayor concentración de amenazas\n#   (sumatorio de amenazas en una cuadrícula 3x3).\n# - Si el sumatorio de amenazas es mayor al umbral, activa el \n#   protocolo de seguridad.\n# - Calcula la distancia desde la Batcueva, situada en (0, 0). La distancia es\n#   la suma absoluta de las coordenadas al centro de la cuadrícula amenazada.\n# - Muestra la coordenada al centro de la cuadrícula más amenazada, la suma de\n#   sus amenazas, la distancia a la Batcueva y si se debe activar el\n#   protocolo de seguridad.\n\n\n\"\"\"    RETO BATMAN DAY     \"\"\"\n\nfrom datetime import date\nimport locale\n\nlocale.setlocale(locale.LC_TIME, \"es_ES.UTF-8\")\n\n\n\"\"\"_summary_\n    calculated which day of the week batman day will fall on over a peroid of years\n    \n    _args_\n    None\n    \n    _return_\n    None\n\"\"\"\ndef batman_day_100th():\n    anniversary = 85\n    for year in range(2024, 2040):\n        first_day_september = date(year, 9, 1).weekday()\n        days_to_saturday = 5 - first_day_september\n        if days_to_saturday < 0:\n            days_to_saturday += 7\n        first_saturday = days_to_saturday + 1\n        third_saturday = first_saturday + 14\n        batman_day = date(year, 9, third_saturday)\n        print(f\"El {anniversary} aniversario del batman day sera el {batman_day.day} {batman_day.strftime(\"%A\")} de {batman_day.strftime(\"%B\")} del año {batman_day.strftime(\"%Y\")}.\")\n        anniversary += 1\n\n\n\"\"\"    RETO BATCUEVA     \"\"\"\nimport random\n\n\"\"\"_summary_\n    grid creation\n    \n    create grid with X number of row an X number of columns and initial crime rate of 0\n    \n    _args_\n    size (int) grid size (size x size)\n    \n    _returns_\n    crated list\n\"\"\"\ndef create_gotham(size: int) -> list:\n    gotham = [[(x, y, random.randint(0, 10)) for x in range(size)] for y in range(size)] \n    return gotham\n\n\"\"\"_summary_\n    creation of a 3x3 grid\n    \n    _args_ \n    gotham map (array) coordinates (center_x, center_y)\n    \n    _returns_\n    array whit 9 elements\n\"\"\"\ndef get_submarix(array: list, center_x: int, center_y: int) -> list:\n    grid_areas = []\n    for x in range(center_x - 1, center_x + 2):\n        for y in range(center_y - 1, center_y + 2):\n            grid_areas.append(array[y][x])\n    return grid_areas\n\n\"\"\"_summary_\n    calculate crime index of a 3x3 grid\n    \n    _args_\n    3x3 grid (array)\n    \n    _returns_\n    total crime rate\n\"\"\"\ndef sum_grid_areas(array: list) -> int:\n    total = sum(cell[2] for cell in array)\n    return total\n\n\"\"\"_summary_\n    calculate the distance between bat cave (0, 0) to center of 3x3 grid whit most crime rate\n    \n    _args_\n    coordinates of center cell (x, y)\n    \n    _returns_\n    absolute sum of crime rates\n\"\"\"\ndef calculate_distance( x: int, y:int) -> int:\n    return abs(x) + abs(y)\n\n\n\"\"\"_summary_\n    main app, obtains the data provided to the functions\n    \n    _args_\n    number for matrix size (int)\n    \n    _returns_\n    report whit data obtained in the each functions\n\"\"\"\ndef main_loop(num: int) -> str:\n    gotham = create_gotham(num)\n    security_protocol = False\n    security_protocol_index = 20\n    most_dangerous_cell = None\n    max_crime_index = 0\n    for x in range(1, num - 1):\n        for y in range(1, num - 1):\n            submatrix = get_submarix(gotham, x, y)\n            total = sum_grid_areas(submatrix)\n            if total > max_crime_index:\n                max_crime_index = total\n                most_dangerous_cell = gotham[y][x]\n    if max_crime_index > security_protocol_index:\n        security_protocol = True\n    distance = calculate_distance(most_dangerous_cell[0], most_dangerous_cell[1])\n    return (f\"Centro de la cuadricula mas amenazada: {most_dangerous_cell}.\\n\"\n        f\"Nivel máximo de alerta: {max_crime_index}.\\n\"\n        f\"Distancia desde la Bat cueva: {distance}.\\n\"\n        f\"Activar protocolo de seguridad: {security_protocol}.\")"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/python/miguelex.py",
    "content": "import datetime\nimport random\n\n# RETO 1: Cálculo de Batman Day hasta su 100 aniversario\ndef calcular_batman_day(anio_inicio, anio_final):\n    print(\"Fechas del Batman Day hasta su 100 aniversario:\")\n    for anio in range(anio_inicio, anio_final + 1):\n        tercer_sabado = datetime.datetime(anio, 9, 1) + datetime.timedelta((5 - datetime.datetime(anio, 9, 1).weekday()) % 7 + 14)\n        print(f\"Batman Day en el año {anio}: {tercer_sabado.strftime('%d-%m-%Y')}\")\n\n# RETO 2: Sistema de seguridad de la Batcueva\ndef activar_sistema_seguridad(sensores):\n    tamano_mapa = 20\n    umbral_seguridad = 20\n    mejor_suma_amenazas = 0\n    mejor_centro = None\n\n    for i in range(tamano_mapa - 2):\n        for j in range(tamano_mapa - 2):\n            suma_amenazas = sum(sensores[x][y] for x in range(i, i + 3) for y in range(j, j + 3))\n            if suma_amenazas > mejor_suma_amenazas:\n                mejor_suma_amenazas = suma_amenazas\n                mejor_centro = (i + 1, j + 1)\n\n    if mejor_centro:\n        distancia_batcueva = abs(mejor_centro[0]) + abs(mejor_centro[1])\n        print(f\"\\nÁrea más amenazada en coordenadas {mejor_centro}\")\n        print(f\"Suma de amenazas: {mejor_suma_amenazas}\")\n        print(f\"Distancia a la Batcueva: {distancia_batcueva}\")\n\n        if mejor_suma_amenazas > umbral_seguridad:\n            print(\"¡Protocolo de seguridad activado!\")\n        else:\n            print(\"Protocolo de seguridad NO activado.\")\n\n# Ejecutar el reto 1\nanio_inicio = 2024\nanio_final = 2024 + (100 - 85)\ncalcular_batman_day(anio_inicio, anio_final)\n\n# Ejecutar el reto 2\nsensores = [[random.randint(0, 10) for _ in range(20)] for _ in range(20)]\nactivar_sistema_seguridad(sensores)\n"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/python/mouredev.py",
    "content": "from datetime import datetime, timedelta\n\n# Reto 1\n\nyear_of_creation = 1939\nanniversary_year = year_of_creation + 85\n\nbatman_day_anniversary_dates = []\n\nwhile anniversary_year <= year_of_creation + 100:\n\n    september = datetime(anniversary_year, 9, 1)\n\n    first_saturday = 5 - september.weekday() if september.weekday() <= 5 else 12 - \\\n        september.weekday()\n\n    third_saturday = september + timedelta(days=first_saturday + 14)\n\n    batman_day_anniversary_dates.append(\n        (\n            anniversary_year,\n            anniversary_year - year_of_creation,\n            third_saturday.strftime(\"%d-%m-%Y\")\n        )\n    )\n\n    anniversary_year += 1\n\nfor year, anniversary, batman_day in batman_day_anniversary_dates:\n    print(f\"Batman day {year} ({anniversary} aniversario): {batman_day}\")\n\n# Reto 2\n\n\ndef sum_subgrid_alerts(sensors, center_x, center_y) -> int:\n\n    total = 0\n\n    for x in range(center_x - 1, center_x + 2):\n        for y in range(center_y - 1, center_y + 2):\n            for sensor in sensors:\n                if sensor[0] == x and sensor[1] == y:\n                    total += sensor[2]\n\n    return total\n\n\ndef batcave_security_system(sensors):\n\n    max_alert_level = 0\n    max_alert_coordinate = (0, 0)\n\n    for x in range(1, 19):\n        for y in range(1, 19):\n            alert_level = sum_subgrid_alerts(sensors, x, y)\n            if alert_level > max_alert_level:\n                max_alert_level = alert_level\n                max_alert_coordinate = (x, y)\n\n    distance = abs(max_alert_coordinate[0]) + abs(max_alert_coordinate[1])\n    activate_protocol = max_alert_level > 20\n\n    return max_alert_coordinate, max_alert_level, distance, activate_protocol\n\n\nsensors = [\n    (2, 3, 7),\n    (4, 3, 8),\n    (2, 2, 7),\n    (10, 12, 8),\n    (11, 11, 8),\n    (10, 11, 8),\n    (15, 18, 4)\n]\n\nresult = batcave_security_system(sensors)\nprint(f\"Centro cuadrícula más amenazada: {result[0]}.\")\nprint(f\"Máximo nivel de alerta: {result[1]}.\")\nprint(f\"Distancia a la Batcueva: {result[2]}.\")\nprint(f\"Activar protocolo de seguridad: {\"Sí\" if result[3] else \"No\"}.\")\n"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/python/neslarra.py",
    "content": "\"\"\"\n EJERCICIO:\n Cada año se celebra el Batman Day durante la tercera semana de septiembre... \n ¡Y este año cumple 85 años! Te propongo un reto doble:\n\n RETO 1:\n Crea un programa que calcule cuándo se va a celebrar el Batman Day hasta \n su 100 aniversario.\n\n RETO 2:\n Crea un programa que implemente el sistema de seguridad de la Batcueva. \n Este sistema está diseñado para monitorear múltiples sensores distribuidos\n por Gotham, detectar intrusos y activar respuestas automatizadas. \n Cada sensor reporta su estado en tiempo real, y Batman necesita un programa \n que procese estos datos para tomar decisiones estratégicas.\n Requisitos:\n - El mapa de Gotham y los sensores se representa con una cuadrícula 20x20.\n - Cada sensor se identifica con una coordenada (x, y) y un nivel\n   de amenaza entre 0 a 10 (número entero).\n - Batman debe concentrar recursos en el área más crítica de Gotham.\n - El programa recibe un listado de tuplas representando coordenadas de los \n   sensores y su nivel de amenaza. El umbral de activación del protocolo de\n   seguridad es 20 (sumatorio de amenazas en una cuadrícula 3x3).\n Acciones: \n - Identifica el área con mayor concentración de amenazas\n   (sumatorio de amenazas en una cuadrícula 3x3).\n - Si el sumatorio de amenazas es mayor al umbral, activa el \n   protocolo de seguridad.\n - Calcula la distancia desde la Batcueva, situada en (0, 0). La distancia es\n   la suma absoluta de las coordenadas al centro de la cuadrícula amenazada.\n - Muestra la coordenada al centro de la cuadrícula más amenazada, la suma de\n   sus amenazas, la distancia a la Batcueva y si se debe activar el\n   protocolo de seguridad.\n\"\"\"\nfrom datetime import datetime as dt, timedelta as td\nfrom random import randint\n\n\ndef batman_day() -> None:\n    anniversary = 75\n    for year in range(2024, 2050):\n        sep_fst = dt.strptime(str(year) + \"-09-01\", \"%Y-%m-%d\")\n        # Batman's day is celebrated every 3rd Saturday of September\n        days = 20 - int(sep_fst.strftime(\"%w\"))\n        bat_day = sep_fst + td(days=days)\n        print(f\"Batman celebrates its {anniversary}th anniversary on  {bat_day.strftime('%A %B %d, %Y')}\")\n        anniversary += 1\n\n\ndef gotham_map() -> list:\n    map_ = []\n    for x in range(0, 20, 3):\n        for y in range(0, 20, 3):\n            # The 20x20 map is divided in 3x3 blocks (and the block's center is the fourth pos)\n            map_.append(((x, y), (x, y + 1), (x, y + 2), (x + 1, y), (x + 1, y + 1), (x + 1, y + 2), (x + 2, y), (x + 2, y + 1), (x + 2, y + 2)))\n    return map_\n\n\ndef gotham_sensors() -> list:\n    menaces_map = []\n    for x in range(0, 49):\n        menaces_map.append((randint(0, 10), [randint(0, 19), randint(0, 19)]))\n    return menaces_map\n\n\ndef system_monitor(map_, sensors) -> list:\n\n    def get_block(coord: tuple) -> int:\n        # look for the block containing the alerted coord\n        for ind, block in enumerate(map_):\n            if tuple(coord) in block:\n                return ind\n        return -1\n\n    level_alert = dict()\n    for sensor in sensors:\n        block = get_block(sensor[1])\n        level_alert[block] = sensor[0] if block not in level_alert.keys() else level_alert[block] + sensor[0]\n    return [(block, level) for block, level in level_alert.items() if level >= 20]\n\n\ndef calculate_distance(coord: tuple) -> float:\n    return pow(pow(coord[0], 2) + pow(coord[1], 2), 0.5).__round__(2)\n\n\ndef max_alert(alerted_blocks: list) -> list:\n    if alerted_blocks.__len__() == 1:\n        return alerted_blocks\n    maximal_alert = max([y for y in alerted_blocks[1]])\n    return [x for x in alerted_blocks if x[1] == maximal_alert]\n\n\ndef activate_protocol(alerted_blocks: list) -> bool:\n    activated = False\n    for alert in max_alert(alerted_blocks):\n        print(f\"\\nAlert Level: {alert[1]} / Distance from batcave to coord {gotham[alert[0]][4]} = {calculate_distance(gotham[alert[0]][4])}\")\n        activated = True\n        break\n    return activated\n\n\nbatman_day()\ngotham = gotham_map()\nwhile True:\n    sensors = gotham_sensors()\n    alerted_blocks = system_monitor(gotham, sensors)\n    if alerted_blocks:\n        if activate_protocol(alerted_blocks):\n            print(\"To the Batmobile, Robin.\")\n            break\n        else:\n            print(\"\\nNo alert rises over the minimal level of risk => police can be in charge.\")\n    else:\n        print(\"\\nAll quiet on Gotham.\")\n    print(\"Keep tracking.\")\n"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/python/oriaj3.py",
    "content": "\"\"\"\n\n/*\n * EJERCICIO:\n * Cada año se celebra el Batman Day durante la tercera semana de septiembre... \n * ¡Y este año cumple 85 años! Te propongo un reto doble:\n *\n * RETO 1:\n * Crea un programa que calcule cuándo se va a celebrar el Batman Day hasta \n * su 100 aniversario.\n *\n * RETO 2:\n * Crea un programa que implemente el sistema de seguridad de la Batcueva. \n * Este sistema está diseñado para monitorear múltiples sensores distribuidos\n * por Gotham, detectar intrusos y activar respuestas automatizadas. \n * Cada sensor reporta su estado en tiempo real, y Batman necesita un programa \n * que procese estos datos para tomar decisiones estratégicas.\n * Requisitos:\n * - El mapa de Gotham y los sensores se representa con una cuadrícula 20x20.\n * - Cada sensor se identifica con una coordenada (x, y) y un nivel\n *   de amenaza entre 0 a 10 (número entero).\n * - Batman debe concentrar recursos en el área más crítica de Gotham.\n * - El programa recibe un listado de tuplas representando coordenadas de los \n *   sensores y su nivel de amenaza. El umbral de activación del protocolo de\n *   seguridad es 20 (sumatorio de amenazas en una cuadrícula 3x3).\n * Acciones: \n * - Identifica el área con mayor concentración de amenazas\n *   (sumatorio de amenazas en una cuadrícula 3x3).\n * - Si el sumatorio de amenazas es mayor al umbral, activa el \n *   protocolo de seguridad.\n * - Calcula la distancia desde la Batcueva, situada en (0, 0). La distancia es\n *   la suma absoluta de las coordenadas al centro de la cuadrícula amenazada.\n * - Muestra la coordenada al centro de la cuadrícula más amenazada, la suma de\n *   sus amenazas, la distancia a la Batcueva y si se debe activar el\n *   protocolo de seguridad.\n */\n\n\"\"\"\n\n# Reto 1\nfrom datetime import datetime, timedelta\n\nyear_of_creation = 1939\nanniversary_year = year_of_creation + 85\n\nbatman_day_anniversary_dates = []\n\nwhile anniversary_year <= year_of_creation + 100:\n\n    september = datetime(anniversary_year, 9, 1)\n    #Resto 5 para que sea el primer sábado de septiembre\n    #Si el primer día de la semana es 6 (sábado) entonces el primer sábado es el mismo día\n    first_saturday = 5 - september.weekday() if september.weekday() <= 5 else 12 - september.weekday() \n    \n    third_saturday = september + timedelta(days=first_saturday + 14)\n    \n    batman_day_anniversary_dates.append(\n        (\n        anniversary_year, \n        anniversary_year - year_of_creation,\n        third_saturday.strftime(\"%Y-%m-%d\")\n        )\n    )\n    anniversary_year += 1\n\nfor year, anniversary, date in batman_day_anniversary_dates:\n    print(f\"Batman Day {year} - {anniversary}º Aniversario: {date}\")\n\n\"\"\"\n * RETO 2:\n * Crea un programa que implemente el sistema de seguridad de la Batcueva. \n * Este sistema está diseñado para monitorear múltiples sensores distribuidos\n * por Gotham, detectar intrusos y activar respuestas automatizadas. \n * Cada sensor reporta su estado en tiempo real, y Batman necesita un programa \n * que procese estos datos para tomar decisiones estratégicas.\n * Requisitos:\n * - El mapa de Gotham y los sensores se representa con una cuadrícula 20x20.\n * - Cada sensor se identifica con una coordenada (x, y) y un nivel\n *   de amenaza entre 0 a 10 (número entero).\n * - Batman debe concentrar recursos en el área más crítica de Gotham.\n * - El programa recibe un listado de tuplas representando coordenadas de los \n *   sensores y su nivel de amenaza. El umbral de activación del protocolo de\n *   seguridad es 20 (sumatorio de amenazas en una cuadrícula 3x3).\n * Acciones: \n * - Identifica el área con mayor concentración de amenazas\n *   (sumatorio de amenazas en una cuadrícula 3x3).\n * - Si el sumatorio de amenazas es mayor al umbral, activa el \n *   protocolo de seguridad.\n * - Calcula la distancia desde la Batcueva, situada en (0, 0). La distancia es\n *   la suma absoluta de las coordenadas al centro de la cuadrícula amenazada.\n * - Muestra la coordenada al centro de la cuadrícula más amenazada, la suma de\n *   sus amenazas, la distancia a la Batcueva y si se debe activar el\n *   protocolo de seguridad.\n */\n\n\"\"\"\ndef sum_subgrib_alerts(sensors, center_x, center_y) -> int:\n    total = 0 \n    for x in range(center_x-1, center_x+2):\n        for y in range(center_y-1, center_y+2):\n            for sensor in sensors:\n                if sensor[0] == x and sensor[1] == y:\n                    total += sensor[2]\n    return total\n\ndef batcave_security_system(sensors):\n    max_alert_level = 0\n    max_alert_center = (0, 0)\n\n    for x in range(1,19):\n        for y in range(1,19):\n            alert_level = sum_subgrib_alerts(sensors, x, y)\n            if alert_level > max_alert_level:\n                max_alert_level = alert_level\n                max_alert_center = (x, y)\n    activate_protocol = max_alert_level > 20\n    distance = abs(max_alert_center[0]) + abs(max_alert_center[1])\n\n    return max_alert_center, max_alert_level, distance, activate_protocol\n\n# Function draw grid, with the lvl of alert of each sensor\ndef draw_grid(sensors):\n    grid = [[\"-\" for x in range(20)] for y in range(20)]\n    for sensor in sensors:\n        grid[sensor[0]][sensor[1]] = sensor[2]\n    for row in grid:\n        print(row)\n\nsensors = [\n    (2, 3, 5),\n    (4, 5, 8),\n    (6, 7, 3),\n    (8, 9, 1),\n    (10, 11, 2),\n    (12, 13, 10),\n    (14, 15, 7),\n    (14, 14, 8),\n    (16, 17, 4),\n    (18, 19, 9),\n    (19, 19, 6)\n]\n\nresult = batcave_security_system(sensors)\ndraw_grid(sensors)\n\nprint(f\"Centro cuadrícula más amenzada: {result[0]}.\")\nprint(f\"Máximo nivel de alerta: {result[1]}.\")\nprint(f\"Distancia a la Batcueva: {result[2]}.\")\nprint(f\"Activar protocolo de seguridad: {'Sí' if result[3] else 'No'}.\")\n"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/python/pyramsd.py",
    "content": "from os import system\nimport random,time\nimport calendar\n\nprint (\"RETO 1\")\n\nyear = ((100-85)+2024)\n\nmes = 9\n\n#calculamos el calendario de ese mes y mostramos el numero de semanas\nlista_mes = calendar.monthcalendar(year,mes)\n\nsemana_aniversario = 3\n\ndia_aniversario = lista_mes [semana_aniversario-1] [0]\nprint (f\"EL 100 ANIVERSARIO SERA el {dia_aniversario}/{mes}/{year}\" )\n\nprint(\"\\nRETO 2\")\n\nimport numpy as np\n\ndef procesar_sensores(sensores, umbral_activacion=20):\n    # Crear una cuadrícula 20x20 inicializada en 0\n    gotham = np.zeros((20, 20), dtype=int)\n    \n    # Poblar la cuadrícula con los niveles de amenaza de los sensores\n    for x, y, amenaza in sensores:\n        gotham[x, y] = amenaza\n    \n    # Variables para rastrear el área más crítica\n    max_amenaza = 0\n    coordenada_central = None\n    \n    # Recorrer la cuadrícula para calcular sumas en áreas 3x3\n    for i in range(18):  # Hasta 18 para evitar desbordar el rango 3x3\n        for j in range(18):\n            suma_amenazas = gotham[i:i+3, j:j+3].sum()  # Suma en la subcuadrícula 3x3\n            \n            if suma_amenazas > max_amenaza:\n                max_amenaza = suma_amenazas\n                coordenada_central = (i+1, j+1)  # Centro de la cuadrícula 3x3\n    \n    # Calcular la distancia desde la Batcueva al centro de la cuadrícula más amenazada\n    distancia_batcueva = abs(coordenada_central[0] - 0) + abs(coordenada_central[1] - 0)\n    \n    # Determinar si se activa el protocolo de seguridad\n    activar_protocolo = max_amenaza >= umbral_activacion\n    \n    # Mostrar resultados\n    print(f\"Coordenada central del área más amenazada: {coordenada_central}\")\n    print(f\"Suma de amenazas en el área: {max_amenaza}\")\n    print(f\"Distancia a la Batcueva: {distancia_batcueva}\")\n    print(f\"¿Activar protocolo de seguridad?: {'Sí' if activar_protocolo else 'No'}\")\n\n# Ejemplo de datos de sensores\nsensores = [\n    (2, 3, 5), (13, 4, 7), (5, 5, 3), (15, 10, 8), (10, 11, 17), (11, 11, 16),\n    (15, 18, 9), (16, 15, 10), (15, 16, 18), (18, 18, 14)\n]\n\n# Ejecutar el programa con los datos de sensores\nprocesar_sensores(sensores)\n"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/python/raulG91.py",
    "content": "from datetime import datetime,date\nfrom calendar import Calendar\n\n# Reto 1\n#Batman day is the 3rd Saturday of september\n\nfor year in range(2024,2040):\n   c = Calendar()\n   weeks = c.monthdatescalendar(year=year,month=9)\n   #Find the thrid saturday of the month\n   saturdays = 0\n\n   for week in weeks:\n      for day in week:\n         if day.weekday() == 5 and day.month == 9:\n            saturdays += 1\n            if saturdays == 3:\n               print(f'El dia de batman {year} se celebrara el dia {day.day}')\ndef calculateSum(matrix,row,column):\n   sum = 0\n\n   for i in range(row,row+3):\n      for j in range(column,column+3):\n         sum += matrix[i][j]\n   return sum      \n\ndef batmanSecurity(sensors:list):\n   #Initialize the matrix\n   matrix = 20*[0]\n   for row in range(0,20):\n      matrix[row] = 20*[0]\n   \n   #Set the values from the sensors\n   for sensor in sensors: \n      matrix[sensor[0]][sensor[1]] = sensor[2]\n\n   # Find the 3x3 submatrix with more level of danger\n   max_threat = 0\n   centerX = 0\n   centerY = 0\n   distance_batcave = 0\n   for i in range(0,18):\n      for j in range(0,18):\n        sum =  calculateSum(matrix,i,j)\n        if sum >= max_threat:\n           distance_batcave = abs((i+1)+(j+1))\n           centerX = i+1\n           centerY = j+1       \n           max_threat = sum\n   print(f'Suma de amenazas cuadricula mas amenazada: {max_threat}')\n   print(f'Centro cuadricula mas amenazada: {centerX},{centerY}')\n   print(f'Distancia a la  batcueva: {distance_batcave}')\n   if max_threat >= 20:\n      print(\"Activando protocolo de alerta\")\n   else:\n      print(\"Protocolo de alerta no activado\")   \n           \nprint(\"--- Batman security system ---\")\nsensors = [(0,0,2),(0,1,8),(0,2,3),(1,0,4),(1,1,0),(1,2,3),(2,0,0),(2,1,3),(2,2,3),\n           (17,3,24),(17,4,5),(17,5,9),(18,3,23),(18,4,0),(18,5,24),(19,3,0),(19,4,0),(19,5,6)]\nbatmanSecurity(sensors)\n"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/python/rigo93acosta.py",
    "content": "'''\n/*\n * EJERCICIO:\n * Cada año se celebra el Batman Day durante la tercera semana de septiembre... \n * ¡Y este año cumple 85 años! Te propongo un reto doble:\n *\n * RETO 1:\n * Crea un programa que calcule cuándo se va a celebrar el Batman Day hasta \n * su 100 aniversario.\n *\n * RETO 2:\n * Crea un programa que implemente el sistema de seguridad de la Batcueva. \n * Este sistema está diseñado para monitorear múltiples sensores distribuidos\n * por Gotham, detectar intrusos y activar respuestas automatizadas. \n * Cada sensor reporta su estado en tiempo real, y Batman necesita un programa \n * que procese estos datos para tomar decisiones estratégicas.\n * Requisitos:\n * - El mapa de Gotham y los sensores se representa con una cuadrícula 20x20.\n * - Cada sensor se identifica con una coordenada (x, y) y un nivel\n *   de amenaza entre 0 a 10 (número entero).\n * - Batman debe concentrar recursos en el área más crítica de Gotham.\n * - El programa recibe un listado de tuplas representando coordenadas de los \n *   sensores y su nivel de amenaza. El umbral de activación del protocolo de\n *   seguridad es 20 (sumatorio de amenazas en una cuadrícula 3x3).\n * Acciones: \n * - Identifica el área con mayor concentración de amenazas\n *   (sumatorio de amenazas en una cuadrícula 3x3).\n * - Si el sumatorio de amenazas es mayor al umbral, activa el \n *   protocolo de seguridad.\n * - Calcula la distancia desde la Batcueva, situada en (0, 0). La distancia es\n *   la suma absoluta de las coordenadas al centro de la cuadrícula amenazada.\n * - Muestra la coordenada al centro de la cuadrícula más amenazada, la suma de\n *   sus amenazas, la distancia a la Batcueva y si se debe activar el\n *   protocolo de seguridad.\n */\n'''\n\n# When Saturday 3th Week September\nfrom datetime import datetime, timedelta\nimport math\n\n## Reto 1\nyear_of_creation: int = 1939\nanniversary: int = year_of_creation + 85\nbatman_day_ann_dates = []\nwhile anniversary <= year_of_creation + 100:\n    september = datetime(anniversary, 9, 1)\n    first_saturday = 5 - september.weekday() \\\n                        if september.weekday() <= 5 \\\n                        else 12 - september.weekday()\n    third_saturday = september + timedelta(days=first_saturday + 14)\n\n    batman_day_ann_dates.append(\n        (\n            anniversary, \n            anniversary - year_of_creation, \n            third_saturday.strftime(\"%d-%m-%Y\")\n        )\n    )\n    anniversary += 1\n\nfor year, anniversary, date in batman_day_ann_dates:\n    print(f\"Batman Day {anniversary}º Aniversario: {date}\")\n\n## Reto 2\nsensors = [\n    (2, 3, 7),\n    (4, 3, 8),\n    (2, 2, 7),\n    (10, 12, 8),\n    (11, 12, 8),\n    (10, 11, 8),\n    (15, 18, 4)\n]\n\nmap_gotham = [[0 for _ in range(20)] for _ in range(20)]\nthreshold = 20\nall_alarm = []\n\ndef update_map(map_gotham, sensors):\n    map_gotham_tmp = map_gotham.copy()\n    for x, y, threat in sensors:\n        map_gotham_tmp[x][y] = threat\n    \n    return map_gotham_tmp\n\ndef print_map(map_gotham):\n    for row in map_gotham:\n        print(row)\n\ndef sum_subgrid(values):\n    values = [value for sublist in values for value in sublist]\n    return sum(values)\n\ndef select_alarm(alarms):\n    alarm = max(alarms, key=lambda x: x[2])\n    return alarm\n\ndef batcave_security(map_gotham):\n    for y in range(1, 19):\n        for x in range(1, 19):\n            values = [\n                map_gotham[y-1][x-1:x+2],\n                map_gotham[y][x-1:x+2],\n                map_gotham[y+1][x-1:x+2]\n            ]\n            \n            all_alarm.append((y, x, sum_subgrid(values)))\n                \n    alarm = select_alarm(all_alarm)\n    if not alarm:\n        print(\"No hay amenazas.\")\n    else:\n        center_coor = (alarm[0], alarm[1])\n        distance = abs(alarm[0]) + abs(alarm[1])\n        protocol = \"activar\" \\\n                    if alarm[2] > threshold \\\n                    else \"no activar\"\n             \n        print(f\"Máxima ameneza en {center_coor}\" +\\\n            f\" con {alarm[2]} de amenaza,\" +\\\n                f\" distancia {distance:.2f} u.a,\" +\\\n                f\" {protocol} protocolo de seguridad.\")\n\nmap_gotham = update_map(map_gotham, sensors)   \nprint_map(map_gotham)\nbatcave_security(map_gotham)"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/rust/kenysdev.rs",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - Rust\n_____________________________________\n39 BATMAN DAY\n------------------------------------\n\n* RETO 1:\n* Crea un programa que calcule cuándo se va a celebrar el Batman Day hasta\n* su 100 aniversario.\n\n[dependencies]\nchrono = \"0.4.37\"\n*/\n\nuse chrono::{Datelike, NaiveDate, Weekday};\nuse std::cmp::Ordering;\n\nfn third_saturday_of_september(year: i32) -> String {\n    let mut date = NaiveDate::from_ymd_opt(year, 9, 15).unwrap();\n    let days_to_add = ((Weekday::Sat.num_days_from_monday() as i32\n        - date.weekday().num_days_from_monday() as i32\n        + 7)\n        % 7) as i64;\n    date = date + chrono::Duration::days(days_to_add);\n    date.format(\"%d-%m-%Y\").to_string()\n}\n\nfn calculate_anniversary_dates(total_anniversaries: i32) {\n    println!(\"Batman Day\");\n    const BATMAN_DAY_START: i32 = 2014;\n    let current_year = chrono::Local::now().year();\n\n    if current_year < BATMAN_DAY_START {\n        println!(\"xd\");\n        return;\n    }\n\n    let past_anniversaries = current_year - BATMAN_DAY_START;\n    println!(\"Aniversarios que ya han pasado: {}\", past_anniversaries);\n\n    for i in 0..(total_anniversaries - past_anniversaries) {\n        let num = past_anniversaries + i + 1;\n        let the_date = third_saturday_of_september(current_year + i as i32);\n        println!(\"- Aniversario #{}: {}\", num, the_date);\n    }\n}\n\n/*\n* RETO 2:\n* Crea un programa que implemente el sistema de seguridad de la Batcueva.\n* Este sistema está diseñado para monitorear múltiples sensores distribuidos\n* por Gotham, detectar intrusos y activar respuestas automatizadas.\n* Cada sensor reporta su estado en tiempo real, y Batman necesita un programa\n* que procese estos datos para tomar decisiones estratégicas.\n* Requisitos:\n* - El mapa de Gotham y los sensores se representa con una cuadrícula 20x20.\n* - Cada sensor se identifica con una coordenada (x, y) y un nivel\n*   de amenaza entre 0 a 10 (número entero).\n* - Batman debe concentrar recursos en el área más crítica de Gotham.\n* - El programa recibe un listado de tuplas representando coordenadas de los\n*   sensores y su nivel de amenaza. El umbral de activación del protocolo de\n*   seguridad es 20 (sumatorio de amenazas en una cuadrícula 3x3).\n* Acciones:\n* - Identifica el área con mayor concentración de amenazas\n*   (sumatorio de amenazas en una cuadrícula 3x3).\n* - Si el sumatorio de amenazas es mayor al umbral, activa el\n*   protocolo de seguridad.\n* - Calcula la distancia desde la Batcueva, situada en (0, 0). La distancia es\n*   la suma absoluta de las coordenadas al centro de la cuadrícula amenazada.\n* - Muestra la coordenada al centro de la cuadrícula más amenazada, la suma de\n*   sus amenazas, la distancia a la Batcueva y si se debe activar el\n*   protocolo de seguridad.\n*/\n\ntype Point = (i32, i32);\ntype Sensor = (i32, i32, i32);\n\nfn create_map(\n    size: Point,\n    batcave: Point,\n    sensors: &Vec<Sensor>,\n    threats: &Vec<Point>,\n) -> Vec<Vec<String>> {\n    \n    let mut gotham = vec![vec![String::from(\"| \"); size.1 as usize]; size.0 as usize];\n\n    gotham[batcave.0 as usize][batcave.1 as usize] = String::from(\"|B\");\n\n    for s in sensors {\n        gotham[s.0 as usize][s.1 as usize] = String::from(\"|S\");\n    }\n\n    for t in threats {\n        gotham[t.0 as usize][t.1 as usize] = String::from(\"|T\");\n    }\n\n    gotham\n}\n\nfn print_map(gotham: &Vec<Vec<String>>) {\n    println!(\"\\nMapa de Gotham:\");\n    for row in gotham {\n        for cell in row {\n            print!(\"{}\", cell);\n        }\n        println!();\n    }\n}\n\nfn scan_map(gotham: &Vec<Vec<String>>, sensors: &Vec<Sensor>, size: Point) {\n    let mut danger_list: Vec<(usize, i32)> = Vec::new();\n\n    for (c, s) in sensors.iter().enumerate() {\n        let mut danger_counter = 0;\n\n        for i in (s.0 - 1)..=(s.0 + 1) {\n            for j in (s.1 - 1)..=(s.1 + 1) {\n                if i >= 0 && i < size.0 && j >= 0 && j < size.1 {\n                    if gotham[i as usize][j as usize] == \"|T\" {\n                        danger_counter += s.2;\n                    }\n                }\n            }\n        }\n\n        danger_list.push((c, danger_counter));\n    }\n\n    let max_danger = danger_list\n        .iter()\n        .max_by(|a, b| a.1.partial_cmp(&b.1).unwrap_or(Ordering::Equal))\n        .unwrap();\n    let location = sensors[max_danger.0];\n\n    println!(\"\\nInforme:\");\n    println!(\"Cuadrícula más amenazada: '{}, {}'\", location.0, location.1);\n    println!(\"Máximo nivel de alerta: '{}'\", max_danger.1);\n\n    if max_danger.1 >= 20 {\n        println!(\"Protocolo de seguridad activado.\");\n        println!(\"Distancia: '{}'\", location.0 + location.1);\n    } else {\n        println!(\"No hay amenazas relevantes.\");\n    }\n}\n\nfn main() {\n    // Reto 1\n    calculate_anniversary_dates(100);\n\n    // Reto 2\n    let size = (20, 20);\n    let batcave = (0, 0);\n    let sensors = vec![(2, 2, 10), (6, 8, 9), (10, 12, 8), (17, 15, 7)];\n    let threats = vec![(2, 3), (2, 1), (6, 9), (17, 16), (15, 4)];\n\n    let gotham = create_map(size, batcave, &sensors, &threats);\n    print_map(&gotham);\n    scan_map(&gotham, &sensors, size);\n}\n"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/sql/Nicojsuarez2.sql",
    "content": "# #39 BATMAN DAY\n> #### Dificultad: Media | Publicación: 23/09/24 | Corrección: 30/09/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Cada año se celebra el Batman Day durante la tercera semana de septiembre... \n * ¡Y este año cumple 85 años! Te propongo un reto doble:\n *\n * RETO 1:\n * Crea un programa que calcule cuándo se va a celebrar el Batman Day hasta \n * su 100 aniversario.\n *\n * RETO 2:\n * Crea un programa que implemente el sistema de seguridad de la Batcueva. \n * Este sistema está diseñado para monitorear múltiples sensores distribuidos\n * por Gotham, detectar intrusos y activar respuestas automatizadas. \n * Cada sensor reporta su estado en tiempo real, y Batman necesita un programa \n * que procese estos datos para tomar decisiones estratégicas.\n * Requisitos:\n * - El mapa de Gotham y los sensores se representa con una cuadrícula 20x20.\n * - Cada sensor se identifica con una coordenada (x, y) y un nivel\n *   de amenaza entre 0 a 10 (número entero).\n * - Batman debe concentrar recursos en el área más crítica de Gotham.\n * - El programa recibe un listado de tuplas representando coordenadas de los \n *   sensores y su nivel de amenaza. El umbral de activación del protocolo de\n *   seguridad es 20 (sumatorio de amenazas en una cuadrícula 3x3).\n * Acciones: \n * - Identifica el área con mayor concentración de amenazas\n *   (sumatorio de amenazas en una cuadrícula 3x3).\n * - Si el sumatorio de amenazas es mayor al umbral, activa el \n *   protocolo de seguridad.\n * - Calcula la distancia desde la Batcueva, situada en (0, 0). La distancia es\n *   la suma absoluta de las coordenadas al centro de la cuadrícula amenazada.\n * - Muestra la coordenada al centro de la cuadrícula más amenazada, la suma de\n *   sus amenazas, la distancia a la Batcueva y si se debe activar el\n *   protocolo de seguridad.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/typescript/hozlucas28.ts",
    "content": "/* -------------------------------------------------------------------------- */\n/*                               FIRST CHALLENGE                              */\n/* -------------------------------------------------------------------------- */\n\nfunction getBatmanDayAnniversary(anniversary: number): Date {\n    const anniversaryDate: Date = new Date(1939, 8, 16)\n\n    for (let i = 0; i < anniversary; i++) {\n        const currentYear: number = anniversaryDate.getFullYear()\n\n        anniversaryDate.setFullYear(currentYear + 1)\n        anniversaryDate.setMonth(8, 1)\n\n        let saturdayCounter: number = anniversaryDate.getDay() === 6 ? 1 : 0\n\n        while (saturdayCounter < 3) {\n            const currentDate: number = anniversaryDate.getDate()\n            anniversaryDate.setDate(currentDate + 1)\n\n            if (anniversaryDate.getDay() === 6) saturdayCounter++\n        }\n    }\n\n    return anniversaryDate\n}\n\nconst batmanDay85thAnniversary: Date = getBatmanDayAnniversary(85)\nconst batmanDay100thAnniversary: Date = getBatmanDayAnniversary(100)\n\nconsole.log('> First challenge...')\n\nconsole.log(\n    `\\n> The 85th anniversary of Batman day is on ${batmanDay85thAnniversary.toLocaleDateString()}.`\n)\n\nconsole.log(\n    `\\n> The 100th anniversary of Batman day is on ${batmanDay100thAnniversary.toLocaleDateString()}.`\n)\n\n/* -------------------------------------------------------------------------- */\n/*                              SECOND CHALLENGE                              */\n/* -------------------------------------------------------------------------- */\n\n/* ---------------------------------- Types --------------------------------- */\n\ntype ArrayOfN<\n    T extends any,\n    N extends number,\n    Acc extends T[] = []\n> = Acc['length'] extends N ? Acc : ArrayOfN<T, N, [T, ...Acc]>\n\ntype ToRange<\n    Stop extends number,\n    Counter extends 0[] = [],\n    Acc extends number[] = []\n> = Counter['length'] extends Stop\n    ? Acc[number]\n    : ToRange<Stop, [0, ...Counter], [Counter['length'], ...Acc]>\n\ntype ThreatLevel = ToRange<21>\n\ntype Sensors = ArrayOfN<ArrayOfN<ThreatLevel, 20>, 20>\n\ntype SensorPosX = ToRange<20>\ntype SensorPosY = ToRange<20>\n\n/* ---------------------------------- Main ---------------------------------- */\n\nfunction getThreatLevels(\n    sensors: Sensors\n): [SensorPosX, SensorPosY, ThreatLevel][] {\n    const threatLevels: [SensorPosX, SensorPosY, ThreatLevel][] = []\n\n    for (let i = 1; i < sensors.length - 1; i++) {\n        for (let j = 1; j < sensors[i].length - 1; j++) {\n            let threatLevel: ThreatLevel = 0\n\n            threatLevel += sensors[i - 1][j - 1]\n            threatLevel += sensors[i - 1][j]\n            threatLevel += sensors[i - 1][j + 1]\n\n            threatLevel += sensors[i][j - 1]\n            threatLevel += sensors[i][j]\n            threatLevel += sensors[i][j + 1]\n\n            threatLevel += sensors[i + 1][j - 1]\n            threatLevel += sensors[i + 1][j]\n            threatLevel += sensors[i + 1][j + 1]\n\n            threatLevels.push([\n                j as SensorPosX,\n                i as SensorPosY,\n                threatLevel as ThreatLevel,\n            ])\n        }\n    }\n\n    return threatLevels\n}\n\nconst batmanCavePos = [0, 0]\n\nconst sensors: Sensors = [\n    [1, 0, 1, 1, 2, 0, 1, 2, 0, 1, 0, 1, 2, 0, 1, 0, 1, 2, 0, 1],\n    [2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0],\n    [1, 0, 1, 2, 0, 1, 0, 1, 2, 0, 1, 0, 1, 2, 0, 1, 0, 1, 0, 1],\n    [0, 9, 8, 0, 2, 0, 9, 2, 8, 1, 0, 1, 3, 7, 8, 1, 0, 2, 7, 6],\n    [1, 0, 1, 1, 2, 0, 1, 2, 0, 1, 0, 1, 2, 0, 1, 0, 1, 2, 0, 1],\n    [3, 1, 8, 7, 9, 6, 1, 7, 9, 0, 1, 0, 1, 9, 2, 1, 3, 0, 8, 0],\n    [1, 6, 9, 1, 2, 8, 0, 2, 1, 3, 2, 8, 7, 2, 8, 0, 1, 7, 9, 0],\n    [1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 1, 0],\n    [0, 1, 0, 1, 2, 0, 1, 0, 1, 2, 0, 1, 0, 1, 2, 0, 1, 0, 1, 0],\n    [2, 0, 1, 0, 1, 2, 0, 1, 0, 1, 0, 1, 2, 0, 1, 0, 1, 0, 1, 2],\n    [7, 8, 6, 1, 0, 9, 2, 8, 1, 3, 7, 1, 0, 2, 0, 9, 1, 6, 7, 8],\n    [0, 1, 7, 9, 2, 8, 1, 6, 7, 8, 1, 2, 0, 3, 1, 8, 2, 7, 0, 1],\n    [3, 0, 9, 1, 8, 6, 1, 0, 7, 9, 2, 0, 1, 2, 8, 0, 1, 9, 6, 1],\n    [1, 1, 0, 1, 2, 0, 1, 0, 1, 2, 0, 1, 0, 1, 2, 0, 1, 0, 1, 0],\n    [0, 1, 0, 1, 2, 0, 1, 0, 1, 2, 0, 1, 0, 1, 2, 0, 1, 0, 1, 0],\n    [2, 0, 1, 0, 1, 2, 0, 1, 0, 1, 0, 1, 2, 0, 1, 0, 1, 0, 1, 2],\n    [9, 6, 1, 0, 9, 8, 7, 2, 8, 0, 1, 0, 3, 6, 2, 7, 9, 2, 8, 1],\n    [0, 7, 8, 9, 6, 2, 1, 9, 6, 7, 8, 0, 9, 7, 6, 8, 1, 0, 2, 8],\n    [2, 0, 1, 0, 1, 2, 0, 1, 0, 1, 0, 1, 2, 0, 1, 0, 1, 0, 1, 2],\n    [3, 2, 1, 9, 6, 7, 0, 3, 1, 8, 2, 7, 9, 2, 0, 9, 7, 6, 8, 0],\n]\n\nconst threatLevels: [SensorPosX, SensorPosY, ThreatLevel][] =\n    getThreatLevels(sensors)\n\nconst threatLevelsGreaterThanTwenty: [SensorPosX, SensorPosY, ThreatLevel][] =\n    threatLevels.filter((sensor) => sensor[2] >= 20)\n\nconsole.log('\\n> Second challenge...')\n\nconsole.log(\n    '\\n> Threat levels greater than 20 (security protocol activated)...'\n)\n\nfor (let i = 0; i < threatLevelsGreaterThanTwenty.length; i++) {\n    const [x, y, threatLevel] = threatLevelsGreaterThanTwenty[i]\n    console.log(`\\n> Coordinates (x, y): (${x}, ${y}).`)\n    console.log(`> Threat level: ${threatLevel}.`)\n}\n\nconsole.log('\\n> Position with the maximum threat level...')\n\nlet maxThreatLevel: [SensorPosX, SensorPosY, ThreatLevel] =\n    threatLevelsGreaterThanTwenty[0]\n\nfor (const threatLevel of threatLevelsGreaterThanTwenty) {\n    if (threatLevel[2] > maxThreatLevel[2]) maxThreatLevel = threatLevel\n}\n\nconst distanceToBatmanCave: number =\n    Math.abs(maxThreatLevel[0] - batmanCavePos[0]) +\n    Math.abs(maxThreatLevel[1] - batmanCavePos[1])\n\nconsole.log(\n    `\\n> Coordinates (x, y): (${maxThreatLevel[0]}, ${maxThreatLevel[1]}).`\n)\nconsole.log(`> Threat level: ${maxThreatLevel[2]}.`)\nconsole.log(`> Distance to batman cave: ${distanceToBatmanCave} cells.`)\n"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/typescript/miguelex.ts",
    "content": "// RETO 1: Cálculo de Batman Day hasta su 100 aniversario\nfunction calcularBatmanDay(anioInicio: number, anioFinal: number): void {\n    console.log(\"Fechas del Batman Day hasta su 100 aniversario:\");\n    for (let anio = anioInicio; anio <= anioFinal; anio++) {\n        const tercerSabado = new Date(anio, 8, 1); // Septiembre es el mes 8\n        tercerSabado.setDate(1 + (6 - tercerSabado.getDay() + 21) % 7); // Ajuste al tercer sábado\n        console.log(`Batman Day en el año ${anio}: ${tercerSabado.toLocaleDateString()}`);\n    }\n}\n\n// RETO 2: Sistema de seguridad de la Batcueva\nfunction activarSistemaSeguridad(sensores: number[][]): void {\n    const tamanoMapa = 20;\n    const umbralSeguridad = 20;\n    let mejorSumaAmenazas = 0;\n    let mejorCentro: [number, number] | null = null;\n\n    for (let i = 0; i <= tamanoMapa - 3; i++) {\n        for (let j = 0; j <= tamanoMapa - 3; j++) {\n            let sumaAmenazas = 0;\n            for (let x = i; x < i + 3; x++) {\n                for (let y = j; y < j + 3; y++) {\n                    sumaAmenazas += sensores[x][y];\n                }\n            }\n            if (sumaAmenazas > mejorSumaAmenazas) {\n                mejorSumaAmenazas = sumaAmenazas;\n                mejorCentro = [i + 1, j + 1];\n            }\n        }\n    }\n    if (mejorCentro) {\n        const distanciaABatcueva = Math.abs(mejorCentro[0]) + Math.abs(mejorCentro[1]);\n        console.log(`\\nÁrea más amenazada en coordenadas (${mejorCentro[0]}, ${mejorCentro[1]})`);\n        console.log(`Suma de amenazas: ${mejorSumaAmenazas}`);\n        console.log(`Distancia a la Batcueva: ${distanciaABatcueva}`);\n        \n        if (mejorSumaAmenazas > umbralSeguridad) {\n            console.log(\"¡Protocolo de seguridad activado!\");\n        } else {\n            console.log(\"Protocolo de seguridad NO activado.\");\n        }\n    }\n}\n\n// Ejecutar el reto 1\nconst anioInicio = 2024;\nconst anioFinal = 2024 + (100 - 85);\ncalcularBatmanDay(anioInicio, anioFinal);\n\n// Ejecutar el reto 2\nlet sensores: number[][] = Array.from({ length: 20 }, () => Array.from({ length: 20 }, () => Math.floor(Math.random() * 11)));\nactivarSistemaSeguridad(sensores);\n"
  },
  {
    "path": "Roadmap/39 - BATMAN DAY/vb.net/kenysdev.vb",
    "content": "' _____________________________________\n' https://github.com/kenysdev\n' 2024 - vb.net\n' _____________________________________\n' 39 BATMAN DAY\n' ------------------------------------\n\nPublic Class BatmanDay\n    '__________________________________________________________________________\n    '* RETO 1:\n    '* Crea un programa que calcule cuándo se va a celebrar el Batman Day hasta \n    '* su 100 aniversario.\n\n    Private Shared Function ThirdSaturdayOfSeptember(year As Integer) As String\n        Dim [date] = New DateTime(year, 9, 15)\n        Dim daysToAdd = (CInt(DayOfWeek.Saturday) - CInt([date].DayOfWeek) + 7) Mod 7\n        [date] = [date].AddDays(daysToAdd)\n        Return [date].ToString(\"dd-MM-yyyy\")\n    End Function\n\n    Public Shared Sub CalculateAnniversaryDates(totalAnniversaries As Integer)\n        Console.WriteLine(\"Batman Day\")\n        Const batmanDayStart As Integer = 2014\n        Dim currentYear As Integer = DateTime.Today.Year\n\n        If currentYear < batmanDayStart Then\n            Console.WriteLine(\"xd\")\n            Return\n        End If\n\n        Dim pastAnniversaries As Integer = currentYear - batmanDayStart\n        Console.WriteLine($\"Aniversarios que ya han pasado: {pastAnniversaries}\")\n\n        For i As Integer = 0 To totalAnniversaries - pastAnniversaries - 1\n            Dim num As Integer = pastAnniversaries + i + 1\n            Dim theDate As String = ThirdSaturdayOfSeptember(currentYear)\n            Console.WriteLine($\"- Aniversario #{num}: {theDate}\")\n            currentYear += 1\n        Next\n    End Sub\n\n    '__________________________________________________________________________\n    '* RETO 2\n    '* Crea un programa que implemente el sistema de seguridad de la Batcueva. \n    '* Este sistema está diseñado para monitorear múltiples sensores distribuidos\n    '* por Gotham, detectar intrusos y activar respuestas automatizadas. \n    '* Cada sensor reporta su estado en tiempo real, y Batman necesita un programa \n    '* que procese estos datos para tomar decisiones estratégicas.\n    '* Requisitos:\n    '* - El mapa de Gotham y los sensores se representa con una cuadrícula 20x20.\n    '* - Cada sensor se identifica con una coordenada (x, y) y un nivel\n    '*   de amenaza entre 0 a 10 (número entero).\n    '* - Batman debe concentrar recursos en el área más crítica de Gotham.\n    '* - El programa recibe un listado de tuplas representando coordenadas de los \n    '*   sensores y su nivel de amenaza. El umbral de activación del protocolo de\n    '*   seguridad es 20 (sumatorio de amenazas en una cuadrícula 3x3).\n    '* Acciones: \n    '* - Identifica el área con mayor concentración de amenazas\n    '*   (sumatorio de amenazas en una cuadrícula 3x3).\n    '* - Si el sumatorio de amenazas es mayor al umbral, activa el \n    '*   protocolo de seguridad.\n    '* - Calcula la distancia desde la Batcueva, situada en (0, 0). La distancia es\n    '*   la suma absoluta de las coordenadas al centro de la cuadrícula amenazada.\n    '* - Muestra la coordenada al centro de la cuadrícula más amenazada, la suma de\n    '*   sus amenazas, la distancia a la Batcueva y si se debe activar el\n    '*   protocolo de seguridad.\n\n    Private Shared Function CreateMap(size As (Integer, Integer), batcave As (Integer, Integer),\n                                    sensors As List(Of (Integer, Integer, Integer)),\n                                    threats As List(Of (Integer, Integer))) As String(,)\n        Dim gotham(size.Item1 - 1, size.Item2 - 1) As String\n\n        For i As Integer = 0 To size.Item1 - 1\n            For j As Integer = 0 To size.Item2 - 1\n                gotham(i, j) = \"| \"\n            Next\n        Next\n\n        gotham(batcave.Item1, batcave.Item2) = \"|B\"\n\n        For Each s In sensors\n            gotham(s.Item1, s.Item2) = \"|S\"\n        Next\n\n        For Each t In threats\n            gotham(t.Item1, t.Item2) = \"|T\"\n        Next\n\n        Return gotham\n    End Function\n\n    Private Shared Sub PrintMap(gotham As String(,), size As (Integer, Integer))\n        Console.WriteLine(vbCrLf & \"Mapa de Gotham:\")\n\n        For i As Integer = 0 To size.Item1 - 1\n            For j As Integer = 0 To size.Item2 - 1\n                Console.Write(gotham(i, j))\n            Next\n            Console.WriteLine()\n        Next\n    End Sub\n\n    Private Shared Sub ScanMap(gotham As String(,), sensors As List(Of (Integer, Integer, Integer)), size As (Integer, Integer))\n        Dim dangerList As New List(Of (Integer, Integer))\n\n        For c As Integer = 0 To sensors.Count - 1\n            Dim s = sensors(c)\n            Dim dangerCounter As Integer = 0\n\n            For i As Integer = s.Item1 - 1 To s.Item1 + 1\n                For j As Integer = s.Item2 - 1 To s.Item2 + 1\n                    If i >= 0 AndAlso i < size.Item1 AndAlso j >= 0 AndAlso j < size.Item2 AndAlso gotham(i, j) = \"|T\" Then\n                        dangerCounter += s.Item3\n                    End If\n                Next\n            Next\n\n            dangerList.Add((c, dangerCounter))\n        Next\n\n        Dim maxDanger = dangerList.MaxBy(Function(x) x.Item2)\n        Dim location = sensors(maxDanger.Item1)\n\n        Console.WriteLine(vbCrLf & \"Informe:\")\n        Console.WriteLine($\"Cuadrícula más amenazada: '{location.Item1}, {location.Item2}'\")\n        Console.WriteLine($\"Máximo nivel de alerta: '{maxDanger.Item2}'\")\n\n        If maxDanger.Item2 >= 20 Then\n            Console.WriteLine(\"Protocolo de seguridad activado.\")\n            Console.WriteLine($\"Distancia: '{location.Item1 + location.Item2}'\")\n        Else\n            Console.WriteLine(\"No hay amenazas relevantes.\")\n        End If\n    End Sub\n\n    Public Shared Sub Main()\n        ' Reto 1\n        CalculateAnniversaryDates(100)\n\n        ' Reto 2\n        Dim size = (20, 20)\n        Dim batcave = (0, 0)\n        Dim sensors As New List(Of (Integer, Integer, Integer)) From {\n            (2, 2, 10), (6, 8, 9), (10, 12, 8), (17, 15, 7)\n        }\n        Dim threats As New List(Of (Integer, Integer)) From {\n            (2, 3), (2, 1), (6, 9), (17, 16), (15, 4)\n        }\n\n        Dim gotham = CreateMap(size, batcave, sensors, threats)\n        PrintMap(gotham, size)\n        ScanMap(gotham, sensors, size)\n    End Sub\n\nEnd Class\n"
  },
  {
    "path": "Roadmap/40 - FORTNITE RUBIUS CUP/c#/hequebo.cs",
    "content": "using Newtonsoft.Json.Linq;\nusing System.Net.Http.Headers;\n\nclass Streamer\n{\n    public string? Id { get; set; }\n    public string? Login { get; set; }\n    public string? DisplayName { get; set; }\n    public DateTime CreatedAt { get; set; }\n    public int Followers {  get; set; }\n}\nclass Twitch\n{\n    private string? _clientId;\n    private string? _clientSecret;\n    private HttpClient _httpClient = new HttpClient();\n\n    public Twitch()\n    {\n        _clientId = Environment.GetEnvironmentVariable(\"CLIENT_ID\");\n        _clientSecret = Environment.GetEnvironmentVariable(\"CLIENT_SECRET\");\n        _httpClient.DefaultRequestHeaders.Add(\"client-id\", _clientId);\n    }\n\n    public async Task<bool> GetToken()\n    {\n        if (string.IsNullOrWhiteSpace(_clientId) || string.IsNullOrEmpty(_clientSecret))\n        {\n            Console.WriteLine(\"No se cuenta con las credenciales necesarias...\");\n            return false;\n        }\n        string url = \"https://id.twitch.tv/oauth2/token\";\n\n        var content = new Dictionary<string, string>\n        {\n            {\"grant_type\", \"client_credentials\"},\n            {\"client_id\", _clientId},\n            {\"client_secret\", _clientSecret}\n        };\n\n\n        var response = await _httpClient.PostAsync(url, new FormUrlEncodedContent(content));\n        if (response.StatusCode != System.Net.HttpStatusCode.OK)\n            return false;\n\n        var jsonResponse = await response.Content.ReadAsStringAsync();\n        string token = JObject.Parse(jsonResponse)[\"access_token\"].ToString();\n\n        _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(\"Bearer\", token);\n        \n        return true;\n    }\n\n    public async Task<Streamer?> GetUserInfo(string user)\n    {\n        string url = $\"https://api.twitch.tv/helix/users?login={user}\";\n\n        var response = await _httpClient.GetAsync(url);\n        if (response.StatusCode != System.Net.HttpStatusCode.OK)\n            return null;\n\n        var jsonResponse = await response.Content.ReadAsStringAsync();\n\n        var objectResponse = JObject.Parse(jsonResponse);\n        if (objectResponse[\"data\"].Count() == 0)\n            return null;\n        var streamer = new Streamer();\n        streamer.Id = objectResponse[\"data\"][0][\"id\"].ToString();\n        streamer.Login = objectResponse[\"data\"][0][\"login\"].ToString();\n        streamer.DisplayName = objectResponse[\"data\"][0][\"display_name\"].ToString();\n        streamer.CreatedAt = (DateTime)objectResponse[\"data\"][0][\"created_at\"];\n\n        return streamer;\n    }\n    public async Task<int> GetFollowers(string id)\n    {\n        string url = $\"https://api.twitch.tv/helix/channels/followers?broadcaster_id={id}\";\n\n        var response = await _httpClient.GetAsync(url);\n        if (response.StatusCode != System.Net.HttpStatusCode.OK)\n            return 0;\n\n        var jsonResponse = await response.Content.ReadAsStringAsync();\n\n        var objectResponse = JObject.Parse(jsonResponse);\n\n        int followers = (int)objectResponse[\"total\"];\n\n        return followers;\n    }\n}\nclass Program\n{\n    static async Task Main(string[] args)\n    {\n\n        Twitch twitch = new Twitch();\n        \n        bool authorized = await twitch.GetToken();\n        if (!authorized)\n        {\n            Console.WriteLine(\"No ha sido posible obtener autorización...\");\n            return;\n        }\n\n        var users = new List<string>\n        {\n            \"littleragergirl\", \"ache\", \"adricontreras4\", \"agustin51\", \"alexby11\", \"ampeterby7\", \"tvander\",\n            \"arigameplays\", \"arigeli_\", \"auronplay\", \"axozer\", \"beniju03\", \"bycalitos\",\n            \"byviruzz\", \"carreraaa\", \"celopan\", \"srcheeto\", \"crystalmolly\", \"darioemehache\",\n            \"dheylo\", \"djmariio\", \"doble\", \"elvisayomastercard\", \"elyas360\", \"folagorlives\", \"thegrefg\",\n            \"guanyar\", \"hika\", \"hiperop\", \"ibai\", \"ibelky_\", \"illojuan\", \"imantado\",\n            \"irinaissaia\", \"jesskiu\", \"jopa\", \"jordiwild\", \"kenaivsouza\", \"mrkeroro10\",\n            \"thekiddkeo95\", \"kikorivera\", \"knekro\", \"kokoop\", \"kronnozomberoficial\", \"leviathan\",\n            \"litkillah\", \"lolalolita\", \"lolitofdez\", \"luh\", \"luzu\", \"mangel\", \"mayichi\",\n            \"melo\", \"missasinfonia\", \"mixwell\", \"jaggerprincesa\", \"nategentile7\", \"nexxuz\",\n            \"lakshartnia\", \"nilojeda\", \"nissaxter\", \"olliegamerz\", \"orslok\", \"outconsumer\", \"papigavitv\",\n            \"paracetamor\", \"patica1999\", \"paulagonu\", \"pausenpaii\", \"perxitaa\", \"nosoyplex\",\n            \"polispol1\", \"quackity\", \"recuerd0p\", \"reventxz\", \"rivers_gg\", \"robertpg\", \"roier\",\n            \"ceuvebrokenheart\", \"rubius\", \"shadoune666\", \"silithur\", \"spok_sponha\", \"elspreen\", \"spursito\",\n            \"bystaxx\", \"suzyroxx\", \"vicens\", \"vitu\", \"werlyb\", \"xavi\", \"xcry\", \"elxokas\",\n            \"thezarcort\", \"zeling\", \"zormanworld\", \"mouredev\"\n        };\n        var userDataList = new List<Streamer>();\n        var notFoundList = new List<string>();\n        foreach (var user in users)\n        {\n            var streamer = await twitch.GetUserInfo(user);\n            if (streamer == null)\n                notFoundList.Add(user);\n            else\n            {\n                streamer.Followers = await twitch.GetFollowers(streamer.Id);\n                userDataList.Add(streamer);\n            }\n        }\n\n        var followersSortedList = userDataList.OrderByDescending(u => u.Followers).ToList();\n        var dateSortedList = userDataList.OrderBy(u => u.CreatedAt).ToList();\n\n        Console.WriteLine(\"----Ranking por número de seguidores----\");\n        foreach (var (user, id) in followersSortedList.Select((item, index) => (item, index)))\n            Console.WriteLine($\"{id + 1} {user.DisplayName} Seguidores: {user.Followers}\");\n\n        Console.WriteLine(\"----Ranking por antigüedad----\");\n        foreach (var (user, id) in dateSortedList.Select((item, index) => (item, index)))\n            Console.WriteLine($\"{id + 1} {user.DisplayName} Creado el {user.CreatedAt.ToShortDateString()}\");\n\n        if (notFoundList.Count > 0)\n        {\n            Console.WriteLine(\"----Usuarios no encontrados----\");\n            foreach (var user in notFoundList)\n                Console.WriteLine(user);\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/40 - FORTNITE RUBIUS CUP/c#/kenysdev.cs",
    "content": "namespace exs40;\n/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - C#\n_____________________________________\n40 FORTNITE RUBIUS CUP\n------------------------------------\n\n* EJERCICIO:\n* ¡Rubius tiene su propia skin en Fortnite!\n* Y va a organizar una competición para celebrarlo.\n* Esta es la lista de participantes:\n* https://x.com/Rubiu5/status/1840161450154692876\n*\n* Desarrolla un programa que obtenga el número de seguidores en\n* Twitch de cada participante, la fecha de creación de la cuenta \n* y ordene los resultados en dos listados.\n* - Usa el API de Twitch: https://dev.twitch.tv/docs/api/reference\n*   (NO subas las credenciales de autenticación)\n* - Crea un ranking por número de seguidores y por antigüedad.\n* - Si algún participante no tiene usuario en Twitch, debe reflejarlo.\n*/\n\nusing System.Net.Http;\nusing System.Text.Json;\n// https://www.nuget.org/packages/DotNetEnv/\nusing DotNetEnv;\n\npublic class Twitch(string clientId, string clientSecret)\n{\n    private readonly string clientId = clientId;\n    private readonly string clientSecret = clientSecret;\n    private string? accessToken;\n\n    public class UserData\n    {\n        public required string Username { get; set; }\n        public DateTime CreatedAt { get; set; }\n        public int Followers { get; set; }\n    }\n\n    private async Task EnsureAccessTokenAsync()\n    {\n        if (string.IsNullOrEmpty(accessToken))\n        {\n            using var client = new HttpClient();\n            var tokenContent = new FormUrlEncodedContent(new Dictionary<string, string>\n            {\n                { \"client_id\", clientId },\n                { \"client_secret\", clientSecret },\n                { \"grant_type\", \"client_credentials\" }\n            });\n\n            var tokenResponse = await client.PostAsync(\"https://id.twitch.tv/oauth2/token\", tokenContent);\n\n            if (!tokenResponse.IsSuccessStatusCode)\n            {\n                throw new Exception($\"Error al obtener el token: {tokenResponse.StatusCode}\");\n            }\n\n            var tokenJson = await tokenResponse.Content.ReadAsStringAsync();\n            var tokenData = JsonSerializer.Deserialize<JsonElement>(tokenJson);\n            accessToken = tokenData.GetProperty(\"access_token\").GetString();\n        }\n    }\n\n    private static async Task<int> GetFollowers(HttpClient client, string? idUser)\n    {\n        var response = await client.GetAsync($\"https://api.twitch.tv/helix/channels/followers?broadcaster_id={idUser}\");\n        var json = await response.Content.ReadAsStringAsync();\n        var data = JsonSerializer.Deserialize<JsonElement>(json);\n        var total = data.GetProperty(\"total\").GetInt32();\n        return total;\n    }\n\n    private async Task<UserData?> GetUserData(string userName)\n    {\n        await EnsureAccessTokenAsync();\n\n        using var client = new HttpClient();\n        client.DefaultRequestHeaders.Add(\"Client-Id\", clientId);\n        client.DefaultRequestHeaders.Add(\"Authorization\", $\"Bearer {accessToken}\");\n\n        var response = await client.GetAsync($\"https://api.twitch.tv/helix/users?login={userName}\");\n        var json = await response.Content.ReadAsStringAsync();\n        var data = JsonSerializer.Deserialize<JsonElement>(json);\n        if (data.GetProperty(\"data\").EnumerateArray().Any())\n        {\n            var dt = data.GetProperty(\"data\")[0];\n            var idUser = dt.GetProperty(\"id\").GetString();\n            var createdAtString = dt.GetProperty(\"created_at\").GetString();\n\n            if (createdAtString != null)\n            {\n                var createdAt = DateTime.Parse(createdAtString);\n                var totalFolowers = await GetFollowers(client, idUser);\n\n                return new UserData\n                {\n                    Username = userName,\n                    CreatedAt = createdAt,\n                    Followers = totalFolowers\n                };\n            }\n        }\n        return null;\n    }\n\n    public class Program\n    {\n        private static void PrintRankings(List<UserData> usersData)\n        {\n            var byFollowers = usersData.OrderByDescending(x => x.Followers).ToList();\n            var byDate = usersData.OrderBy(x => x.CreatedAt).ToList();\n\n            Console.WriteLine(\"\\nRanking por número de seguidores:\");\n            for (int i = 0; i < byFollowers.Count; i++)\n            {\n                Console.WriteLine($\"{i + 1} - {byFollowers[i].Username}: {byFollowers[i].Followers:N0} seguidores\");\n            }\n\n            Console.WriteLine(\"\\nRanking por antigüedad:\");\n            for (int i = 0; i < byDate.Count; i++)\n            {\n                Console.WriteLine($\"{i + 1} - {byDate[i].Username}: Creado el {byDate[i].CreatedAt:dd/MM/yyyy}\");\n            }\n        }\n\n        public static async Task ProcessUsers(List<string> users, Twitch Tw)\n        {\n\n            var usersData = new List<UserData>();\n            var notFoundUsers = new List<string>();\n\n            Console.WriteLine(\"Obteniendo datos...\");\n\n            foreach (var name in users)\n            {\n                var userData = await Tw.GetUserData(name);\n                if (userData != null)\n                {\n                    usersData.Add(userData);\n                }\n                else\n                {\n                    notFoundUsers.Add(name);\n                }\n            }\n\n            PrintRankings(usersData);\n\n            if (notFoundUsers.Count != 0)\n            {\n                Console.WriteLine(\"\\nUsuarios no encontrados:\");\n                foreach (var user in notFoundUsers)\n                {\n                    Console.WriteLine(user);\n                }\n            }\n        }\n    }\n\n    public static async Task Main()\n    {\n        Env.Load();\n        string clientId = Environment.GetEnvironmentVariable(\"TWITCH_CLIENT_ID\") ?? \"defaultClientId\";\n        string clientSecret = Environment.GetEnvironmentVariable(\"TWITCH_CLIENT_SECRET\") ?? \"defaultClientSecret\";\n        var Tw = new Twitch(clientId, clientSecret);\n\n        var users = new List<string>\n        {\n            \"abby\", \"ache\", \"adricontreras\", \"agustin\", \"alexby\", \"ampeter\", \"ander\", \"arigameplays\",\n            \"arigeli\", \"auronplay\", \"axozer\", \"beniju\", \"bycalitos\", \"byviruzz\", \"carrera\", \"celopan\",\n            \"cheeto\", \"crystalmolly\", \"darioemehache\", \"dheyo\",\n            \"djmario\", \"doble\", \"elvisa\", \"elyas360\", \"folagor\", \"grefg\", \"guanyar\", \"hika\",\n            \"hiper\", \"ibai\", \"ibelky\", \"illojuan\", \"imantado\", \"irinaisasia\", \"jesskiu\", \"jopa\",\n            \"jordiwild\", \"kenaisouza\", \"keroro\", \"kiddkeo\",\n            \"kikorivera\", \"knekro\", \"koko\", \"kronnozomber\", \"leviathan\", \"litkillah\", \"lolalolita\", \"lolito\",\n            \"luh\", \"luzu\", \"mangel\", \"mayichi\", \"melo\", \"missasinonia\", \"mixwell\", \"mrjagger\",\n            \"nategentile\", \"nexxuz\", \"nia\", \"nilojeda\",\n            \"nissaxter\", \"ollie\", \"orslok\", \"outconsumer\", \"papigavi\", \"paracetamor\", \"patica\", \"paulagonu\",\n            \"pausenpaii\", \"perxitaa\", \"plex\", \"polispol\", \"quackity\", \"recuerdop\", \"reven\", \"rivers\",\n            \"robertpg\", \"roier\", \"rojuu\", \"rubius\",\n            \"shadoune\", \"silithur\", \"spoksponha\", \"spreen\", \"spursito\", \"staxx\", \"suzyroxx\", \"vicens\",\n            \"vituber\", \"werlyb\", \"xavi\", \"xcry\", \"xokas\", \"zarcort\", \"zeling\", \"zorman\"\n        };\n\n        await Program.ProcessUsers(users, Tw);\n    }\n}\n"
  },
  {
    "path": "Roadmap/40 - FORTNITE RUBIUS CUP/c++/hectorio23.cpp",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\n#include <iostream>\n#include <vector>\n#include <string>\n#include <curl/curl.h>\n#include <json/json.h>  // Incluye la biblioteca JSONcpp (debe estar instalada)\n\n// Función callback para manejar la respuesta HTTP y almacenarla en una cadena\nsize_t WriteCallback(void* contents, size_t size, size_t nmemb, std::string* s) {\n    s->append((char*)contents, size * nmemb);\n    return size * nmemb;\n}\n\n// Realiza la solicitud HTTP a la API de Twitch y devuelve la respuesta como cadena\nstd::string make_request(const std::string& url, const std::string& auth_token) {\n    CURL* curl;\n    CURLcode res;\n    std::string response_string;\n\n    curl = curl_easy_init();\n    if (curl) {\n        struct curl_slist* headers = NULL;\n        headers = curl_slist_append(headers, (\"Authorization: Bearer \" + auth_token).c_str());\n        headers = curl_slist_append(headers, \"Client-ID: YOUR_CLIENT_ID\");\n        curl_easy_setopt(curl, CURLOPT_URL, url.c_str());\n        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);\n        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);\n        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_string);\n\n        res = curl_easy_perform(curl);\n        curl_easy_cleanup(curl);\n    }\n    return response_string;\n}\n\n// Procesa la respuesta JSON para obtener el número de seguidores y la fecha de creación\nvoid process_data(const std::vector<std::string>& participants, const std::string& auth_token) {\n    Json::CharReaderBuilder readerBuilder;\n    Json::Value root;\n    std::string errs;\n    \n    for (const auto& user : participants) {\n        std::string url = \"https://api.twitch.tv/helix/users?login=\" + user;\n        std::string response = make_request(url, auth_token);\n\n        // Parseamos la respuesta JSON\n        std::stringstream ss(response);\n        if (Json::parseFromStream(readerBuilder, ss, &root, &errs)) {\n            const auto& data = root[\"data\"];\n            if (!data.empty()) {\n                const std::string userId = data[0][\"id\"].asString();\n                const std::string creationDate = data[0][\"created_at\"].asString();\n\n                // Solicitar el número de seguidores para este usuario\n                std::string followers_url = \"https://api.twitch.tv/helix/users/follows?to_id=\" + userId;\n                std::string followers_response = make_request(followers_url, auth_token);\n                \n                Json::Value followers_root;\n                std::stringstream ss_followers(followers_response);\n                if (Json::parseFromStream(readerBuilder, ss_followers, &followers_root, &errs)) {\n                    int total_followers = followers_root[\"total\"].asInt();\n\n                    // Imprime la información del usuario\n                    std::cout << \"Usuario: \" << user << \"\\n\";\n                    std::cout << \"Seguidores: \" << total_followers << \"\\n\";\n                    std::cout << \"Fecha de creación: \" << creationDate << \"\\n\\n\";\n                } else {\n                    std::cerr << \"Error al parsear la respuesta de seguidores de \" << user << \": \" << errs << \"\\n\";\n                }\n            } else {\n                std::cout << \"El usuario \" << user << \" no existe en Twitch.\\n\\n\";\n            }\n        } else {\n            std::cerr << \"Error al parsear la respuesta de Twitch para \" << user << \": \" << errs << \"\\n\";\n        }\n    }\n}\n\nint main() {\n    std::vector<std::string> participants = {\"user1\", \"user2\", \"user3\"};  // Lista de participantes\n    std::string auth_token = \"YOUR_AUTH_TOKEN\";  // Debes usar un token válido\n\n    process_data(participants, auth_token);\n\n    return 0;\n}\n\n// Para cmpilar el programa en un sistema tipo UNIX usa la siguiente instruccion \n// g++ -std=c++11 -lcurl -ljsoncpp -o twitch_ranking twitch_ranking.cpp\n"
  },
  {
    "path": "Roadmap/40 - FORTNITE RUBIUS CUP/ejercicio.md",
    "content": "# #40 FORTNITE RUBIUS CUP\n> #### Dificultad: Media | Publicación: 30/09/24 | Corrección: 07/10/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * ¡Rubius tiene su propia skin en Fortnite!\n * Y va a organizar una competición para celebrarlo.\n * Esta es la lista de participantes:\n * https://x.com/Rubiu5/status/1840161450154692876\n *\n * Desarrolla un programa que obtenga el número de seguidores en\n * Twitch de cada participante, la fecha de creación de la cuenta \n * y ordene los resultados en dos listados.\n * - Usa el API de Twitch: https://dev.twitch.tv/docs/api/reference\n *   (NO subas las credenciales de autenticación)\n * - Crea un ranking por número de seguidores y por antigüedad.\n * - Si algún participante no tiene usuario en Twitch, debe reflejarlo.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/40 - FORTNITE RUBIUS CUP/java/Josegs95.java",
    "content": "import com.google.gson.JsonArray;\nimport com.google.gson.JsonObject;\nimport com.google.gson.JsonParser;\n\nimport java.io.IOException;\nimport java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\nimport java.time.LocalDateTime;\nimport java.time.format.DateTimeFormatter;\nimport java.util.*;\n\npublic class Josegs95 {\n    public static void main(String[] args) {\n        new Josegs95().forniteCup();\n    }\n\n    private final String CLIENT_ID = System.getenv(\"Client_ID\");\n    private final String CLIENT_SECRET = System.getenv(\"Client_Secret\");\n    private String AUTH_TOKEN;\n\n    private void forniteCup(){\n        getAuthToken();\n\n        String[] participants = getUsersList();\n        List<Map<String, String>> userDataList = new ArrayList<>();\n        List<String> notFoundUserList = new ArrayList<>();\n\n        for (String participant : participants) {\n            Map userData = getUserInfo(participant);\n            if (userData == null) {\n                notFoundUserList.add(participant);\n                continue;\n            }\n            userDataList.add(userData);\n        }\n\n        List<Map<String, String>> sortedListByFollowers = userDataList.stream()\n                .sorted((x, y) -> {\n                    int followers1 = Integer.valueOf(x.get(\"followers\"));\n                    int followers2 = Integer.valueOf(y.get(\"followers\"));\n                    return (followers1 - followers2) * -1;\n                }).toList();\n\n        List<Map<String, String>> sortedListByDateTime = userDataList.stream()\n                .sorted((x, y) -> {\n                    LocalDateTime date1 = LocalDateTime.parse(x.get(\"creation_date\"));\n                    LocalDateTime date2 = LocalDateTime.parse(y.get(\"creation_date\"));\n                    return date1.compareTo(date2);\n                }).toList();\n\n        System.out.println(\"Usuarios encontrados (ordenados por seguidores):\");\n        int counter = 0;\n        for (Map<String, String> userData : sortedListByFollowers){\n            System.out.println(++counter + \". \" + userData.get(\"name\") + \": \"\n                    + String.format(\"%,d\", Long.valueOf(userData.get(\"followers\"))) + \" seguidores\");\n        }\n        System.out.println(\"Usuarios encontrados (ordenados por antigüedad):\");\n        counter = 0;\n        for (Map<String, String> userData : sortedListByDateTime){\n            System.out.println(++counter + \". \" + userData.get(\"name\") + \": \"\n                    + LocalDateTime.parse(userData.get(\"creation_date\")).format(DateTimeFormatter.ofPattern(\"dd'/'MM'/'yyyy\")));\n        }\n\n        if (!notFoundUserList.isEmpty()){\n            System.out.println(\"Lista de usuarios que no se ha podido encontrar información:\");\n            for (String userName : notFoundUserList)\n                System.out.println(userName);\n        }\n    }\n\n    private void getAuthToken(){\n        String url = \"https://id.twitch.tv/oauth2/token\";\n        String body = \"client_id=\" + CLIENT_ID + \"&client_secret=\" + CLIENT_SECRET\n                + \"&grant_type=client_credentials\";\n\n        HttpClient client = HttpClient.newHttpClient();\n        HttpRequest request = HttpRequest.newBuilder(URI.create(url))\n                .header(\"Content-Type\", \"application/x-www-form-urlencoded\")\n                .POST(HttpRequest.BodyPublishers.ofString(body))\n                .build();\n\n        try{\n            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());\n            if (response.statusCode() != 200){\n                System.out.println(\"Error al intentar obtener el token de autorización\");\n                System.out.println(\"Código: \" + response.statusCode());\n                System.out.println(\"Respuesta: \" + response.body());\n            }\n\n            JsonObject data = JsonParser.parseString(response.body()).getAsJsonObject();\n            AUTH_TOKEN = data.get(\"access_token\").getAsString();\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        } catch (InterruptedException e) {\n            throw new RuntimeException(e);\n        }\n    }\n\n    private Map<String, String> getUserInfo(String userName){\n        Map<String, String> userData = new HashMap<>();\n\n        String url = \"https://api.twitch.tv/helix/users\";\n        url += \"?login=\" + userName.replace(\" \", \"\");\n        JsonObject data = getDataFromGETRequest(url);\n        if (data == null)\n            return null;\n\n        JsonArray userArray = data.get(\"data\").getAsJsonArray();\n        if (userArray.isEmpty()){\n            System.out.println(\"No se ha podido encontrar información de: \" + userName);\n            return null;\n        }\n        JsonObject userJson = userArray.get(0).getAsJsonObject();\n\n        userData.put(\"name\", userJson.get(\"display_name\").getAsString());\n        LocalDateTime date = LocalDateTime.parse(userJson.get(\"created_at\").getAsString(),\n                DateTimeFormatter.ofPattern(\"yyyy-MM-dd'T'HH:mm:ss'Z'\"));\n        userData.put(\"creation_date\", date.toString());\n\n        String userID = userJson.get(\"id\").getAsString();\n        url = \"https://api.twitch.tv/helix/channels/followers\";\n        url += \"?broadcaster_id=\" + userID;\n        JsonObject followerInfo = getDataFromGETRequest(url);\n        if (followerInfo == null)\n            return null;\n\n        userData.put(\"followers\", followerInfo.get(\"total\").getAsString());\n\n        return userData;\n    }\n\n    private JsonObject getDataFromGETRequest(String url){\n        HttpClient client = HttpClient.newHttpClient();\n        HttpRequest request = HttpRequest.newBuilder(URI.create(url))\n                .header(\"Authorization\", \"Bearer \" + AUTH_TOKEN)\n                .header(\"Client-Id\", CLIENT_ID)\n                .build();\n\n        try {\n            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());\n            if (response.statusCode() != 200) {\n                System.out.println(\"Error al intentar obtener información del usuario\");\n                System.out.println(\"Código: \" + response.statusCode() + \" URL: \" + url);\n                System.out.println(\"Respuesta: \" + response.body());\n            }\n\n            return JsonParser.parseString(response.body()).getAsJsonObject();\n\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        } catch (InterruptedException e) {\n            throw new RuntimeException(e);\n        }\n    }\n\n    //Quedan muchos nombres, pero el ejercicio lo doy por terminado\n    private String[] getUsersList(){\n        return new String[] {\n                \"ibai\", \"elxokas\", \"auronplay\", \"rubius\", \"thegrefg\",\n                \"rivers_gg\", \"djmariio\", \"alexby11\", \"ampeterby7\", \"mayichi\",\n                \"mrkeroro10\", \"quackity\", \"elspreen\", \"litkillah\", \"illojuan\",\n                \"werlyb\", \"zeling\", \"paracetamor\", \"paulagonu\", \"celopan\",\n                \"elmariana\", \"littleragergirl\", \"zormanworld\", \"silithur\", \"luzu\",\n                \"outconsumer\", \"FolagorLives\", \"bysTaXx\", \"suzyroxx\", \"spok_sponha\",\n                \"LOLITOFDEZ\", \"jaggerprincesa\", \"nexxuz\", \"ElvisaYomastercard\", \"ReventXz\"\n        };\n\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/40 - FORTNITE RUBIUS CUP/java/MohamedElderkaoui.java",
    "content": "import java.io.IOException;\nimport java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\nimport java.net.http.HttpResponse.BodyHandlers;\nimport java.text.SimpleDateFormat;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Calendar;\nimport java.util.Comparator;\nimport java.util.List;\nimport java.util.TimeZone;\nimport java.io.UnsupportedEncodingException;\nimport java.net.URLEncoder;\n\nimport org.json.JSONArray;\nimport org.json.JSONException;\nimport org.json.JSONObject;\n\npublic class MohamedElderkaoui {\n\n    private static final String CLIENT_ID =\"\"; // Replace with your Client ID\n    private static final String CLIENT_SECRET = \"\";  // Replace with your Client Secret\n    private static final String TOKEN_URL = \"https://id.twitch.tv/oauth2/token\";\n    private static final String TWITCH_API_URL = \"https://api.twitch.tv/helix/users\";\n    private static final String FOLLOWERS_API_URL = \"https://api.twitch.tv/helix/users/follows\";\n    private static String accessToken = \"\";\n\n    public static void main(String[] args) {\n        try {\n            // List of participants from the Twitter post\n            List<String> participants = Arrays.asList(\n                    \"ABBY\", \"ACHE\", \"ADRI CONTRERAS\", \"AGUSTIN\", \"ALEXBY\", \"AMPETER\", \"ANDER\", \"ARI GAMEPLAYS\",\n                    \"ARIGELI\", \"AURONPLAY\", \"AXOZER\", \"BENIJU\", \"BY CALITOS\", \"BYVIRUZZ\", \"CARRERA\", \"CELOPAN\",\n                    \"CHEETO\", \"CRYSTALMOLLY\", \"DARIO EMEHACHE\", \"DHEYLO\", \"DJMARIO\", \"DOBLE\", \"ELVISA\", \"ELYAS360\",\n                    \"FOLAGOR\", \"GREFG\", \"GUANYAR\", \"HIKA\", \"HIPER\", \"IBAI\", \"IBELKY\", \"ILLOJUAN\", \"IMANTADO\",\n                    \"IRINA ISSAIA\", \"JESSKIU\", \"JOPA\", \"JORDIWILD\", \"KENAI SOUZA\", \"KERORO\", \"KIDD KEO\", \"KIKO RIVERA\",\n                    \"KNEKRO\", \"KOKO\", \"KRONNOZOMBER\", \"LEVIATHAN\", \"LIT KILLAH\", \"LOLA LOLITA\", \"LOLITO\", \"LUH\", \"LUZU\",\n                    \"MANGEL\", \"MAYICHI\", \"MELO\", \"MISSASINOFIA\", \"MIXWELL\", \"MR.JAGGER\", \"NATE GENTILE\", \"NEXXUZ\",\n                    \"NIA\", \"NIL OJEDA\", \"NISSAXTER\", \"OLLIE\", \"ORSLOK\", \"OUTCONSUMER\", \"PAPI GAVI\", \"PARCETAMOR\",\n                    \"PATICA\", \"PAULA GONU\", \"PAUSENPAII\", \"PERXITAA\", \"PLEX\", \"POLISPOL\", \"QUACKITY\", \"RECUERDOP\",\n                    \"REVEN\", \"RIVERS\", \"ROBERTPG\", \"ROIER\", \"ROJUU\", \"RUBIUS\", \"SHADOUNE\", \"SILITHUR\", \"SPOKSPONHA\",\n                    \"SPREEN\", \"SPURSITO\", \"STAXX\", \"SUZYROXX\", \"VICENS\", \"VITUBER\", \"WERLYB\", \"XAVI\", \"XCRY\", \"XOKAS\",\n                    \"ZARCORT\", \"ZELING\", \"ZORMAN\"\n            );\n\n            // Get access token\n            accessToken = getAccessToken();\n\n            // Get Twitch user information\n            List<TwitchUser> users = getTwitchUsers(participants);\n\n            // Filter out users that were not found\n            List<TwitchUser> foundUsers = new ArrayList<>();\n            List<String> notFoundUsers = new ArrayList<>();\n\n            for (TwitchUser user : users) {\n                if (user != null) {\n                    foundUsers.add(user);\n                } else {\n                    notFoundUsers.add(\"Unknown User\"); // Placeholder for unknown users\n                }\n            }\n\n            // Sort by number of followers\n            foundUsers.sort(Comparator.comparingLong(TwitchUser::getFollowers).reversed());\n\n            // Print ranking by number of followers\n            System.out.println(\"Ranking por número de seguidores:\");\n            for (TwitchUser user : foundUsers) {\n                System.out.println(user.getDisplayName() + \": \" + user.getFollowers() + \" seguidores\");\n            }\n\n            // Sort by account creation date (seniority)\n            foundUsers.sort(Comparator.comparing(TwitchUser::getCreationDate));\n\n            // Print ranking by account creation date\n            System.out.println(\"\\nRanking por antigüedad de la cuenta:\");\n            for (TwitchUser user : foundUsers) {\n                System.out.println(user.getDisplayName() + \": \" + user.getCreationDateStr());\n            }\n\n            // Print unknown users\n            System.out.println(\"\\nUsuarios no encontrados:\");\n            for (String notFound : notFoundUsers) {\n                System.out.println(notFound);\n            }\n\n        } catch (IOException | InterruptedException e) {\n            e.printStackTrace();\n        }\n    }\n\n    private static String getAccessToken() throws IOException, InterruptedException {\n        // Create the body for the request to obtain the access token\n        String body = \"client_id=\" + CLIENT_ID\n                    + \"&client_secret=\" + CLIENT_SECRET\n                    + \"&grant_type=client_credentials\";\n\n        // Make the HTTP POST request to get the access token\n        HttpRequest request = HttpRequest.newBuilder()\n                .uri(URI.create(TOKEN_URL))\n                .header(\"Content-Type\", \"application/x-www-form-urlencoded\")\n                .POST(HttpRequest.BodyPublishers.ofString(body))\n                .build();\n\n        HttpClient client = HttpClient.newHttpClient();\n        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());\n\n        // Check if the response is successful (status code 200)\n        if (response.statusCode() != 200) {\n            throw new IOException(\"Error en la solicitud de token: \" + response.body());\n        }\n\n        // Parse the response to get the access token\n        JSONObject jsonResponse = new JSONObject(response.body());\n        if (!jsonResponse.has(\"access_token\")) {\n            throw new JSONException(\"Token de acceso no encontrado en la respuesta: \" + response.body());\n        }\n\n        return jsonResponse.getString(\"access_token\");\n    }\n\n    // Method to get Twitch users\n    private static List<TwitchUser> getTwitchUsers(List<String> usernames) throws IOException, InterruptedException {\n        List<TwitchUser> users = new ArrayList<>();\n        HttpClient client = HttpClient.newHttpClient();\n\n        for (String username : usernames) {\n            try {\n                // URL encode the username to handle spaces and special characters\n                String encodedUsername = URLEncoder.encode(username, \"UTF-8\");\n                HttpRequest request = HttpRequest.newBuilder()\n                        .uri(URI.create(TWITCH_API_URL + \"?login=\" + encodedUsername))\n                        .GET()\n                        .header(\"Authorization\", \"Bearer \" + accessToken)\n                        .header(\"Client-Id\", CLIENT_ID)\n                        .build();\n\n                HttpResponse<String> response = client.send(request, BodyHandlers.ofString());\n                JSONObject json = new JSONObject(response.body());\n                JSONArray data = json.optJSONArray(\"data\");\n\n                if (data != null && data.length() > 0) {\n                    JSONObject userData = data.getJSONObject(0);\n                    long followersCount = getFollowersCount(userData.getString(\"id\")); // Get follower count\n                    TwitchUser user = new TwitchUser(\n                            userData.getString(\"id\"),\n                            userData.getString(\"display_name\"),\n                            followersCount,\n                            userData.getString(\"created_at\")\n                    );\n                    users.add(user);\n                } else {\n                    users.add(null); // User not found\n                }\n            } catch (UnsupportedEncodingException e) {\n                e.printStackTrace(); // Handle URL encoding exceptions\n                users.add(null); // If encoding fails, consider the user as not found\n            }\n        }\n\n        return users;\n    }\n\n    private static long getFollowersCount(String userId) throws IOException, InterruptedException {\n        HttpClient client = HttpClient.newHttpClient();\n        HttpRequest request = HttpRequest.newBuilder()\n                .uri(URI.create(FOLLOWERS_API_URL + \"?to_id=\" + userId))\n                .GET()\n                .header(\"Authorization\", \"Bearer \" + accessToken)\n                .header(\"Client-Id\", CLIENT_ID)\n                .build();\n\n        HttpResponse<String> response = client.send(request, BodyHandlers.ofString());\n        JSONObject json = new JSONObject(response.body());\n        JSONArray data = json.optJSONArray(\"data\");\n\n        // Return the count of followers\n        return data != null ? data.length() : 0; // Return 0 if no followers\n    }\n}\n\n// Class to model Twitch users\nclass TwitchUser {\n    private String id;\n    private String displayName;\n    private long followers;\n    private Calendar creationDate;\n\n    public TwitchUser(String id, String displayName, long followers, String creationDate) {\n        this.id = id;\n        this.displayName = displayName;\n        this.followers = followers;\n        this.creationDate = parseCreationDate(creationDate);\n    }\n\n    private Calendar parseCreationDate(String creationDateString) {\n        Calendar calendar = Calendar.getInstance();\n        SimpleDateFormat sdf = new SimpleDateFormat(\"yyyy-MM-dd'T'HH:mm:ss'Z'\");\n        sdf.setTimeZone(TimeZone.getTimeZone(\"UTC\"));\n        try {\n            calendar.setTime(sdf.parse(creationDateString));\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n        return calendar;\n    }\n\n    public String getId() {\n        return id;\n    }\n\n    public String getDisplayName() {\n        return displayName;\n    }\n\n    public long getFollowers() {\n        return followers;\n    }\n\n    public Calendar getCreationDate() {\n        return creationDate;\n    }\n\n    public String getCreationDateStr() {\n        SimpleDateFormat sdf = new SimpleDateFormat(\"dd-MM-yyyy\");\n        return sdf.format(creationDate.getTime());\n    }\n}\n"
  },
  {
    "path": "Roadmap/40 - FORTNITE RUBIUS CUP/java/albmartinez.java",
    "content": "public class albmartinez {\n\n    private static final String CLIENT_ID = \"\";\n    private static final String CLIENT_SECRET = \"\";\n    private static final String TOKEN_URL = \"https://id.twitch.tv/oauth2/token\";\n    private static final String TWITCH_API_URL_USERS = \"https://api.twitch.tv/helix/users\";\n    private static final String TWITCH_API_URL_FOLLOWERS = \"https://api.twitch.tv/helix/channels/followers\";\n\n    private static String accessToken = \"\";\n    private static final HttpClient httpClient = HttpClient.newHttpClient();\n    private static final DateTimeFormatter creationDateFormat = DateTimeFormatter.ofPattern(\"yyyy-MM-dd'T'HH:mm:ss'Z'\");\n    private static final DateTimeFormatter outputDateFormat = DateTimeFormatter.ofPattern(\"dd-MM-yyyy\");\n\n    public static void main(String[] args) {\n        try {\n            List<String> participants = getListParticipants();\n            accessToken = getAccessToken();\n            List<TwitchUser> userWithFollowers = new ArrayList<>();\n            List<String> userWithoutAccount = new ArrayList<>();\n\n            for (String username : participants) {\n                Optional<TwitchUser> optionalUser = getTwitchUserInfo(username);\n                optionalUser.ifPresentOrElse(userWithFollowers::add,\n                        () -> userWithoutAccount.add(username));\n            }\n\n            printRanking(userWithFollowers, userWithoutAccount);\n\n        } catch (IOException | InterruptedException e) {\n            e.printStackTrace();\n        }\n\n    }\n\n    private static List<String> getListParticipants() {\n        return Arrays.asList(\n                \"ABBY\", \"ACHE\", \"ADRI CONTRERAS\", \"AGUSTIN\", \"ALEXBY\", \"AMPETER\", \"ANDER\", \"ARI GAMEPLAYS\",\n                \"ARIGELI\", \"AURONPLAY\", \"AXOZER\", \"BENIJU\", \"BY CALITOS\", \"BYVIRUZZ\", \"CARRERA\", \"CELOPAN\",\n                \"CHEETO\", \"CRYSTALMOLLY\", \"DARIO EMEHACHE\", \"DHEYLO\", \"DJMARIO\", \"DOBLE\", \"ELVISA\", \"ELYAS360\",\n                \"FOLAGOR\", \"GREFG\", \"GUANYAR\", \"HIKA\", \"HIPER\", \"IBAI\", \"IBELKY\", \"ILLOJUAN\", \"IMANTADO\",\n                \"IRINA ISSAIA\", \"JESSKIU\", \"JOPA\", \"JORDIWILD\", \"KENAI SOUZA\", \"KERORO\", \"KIDD KEO\", \"KIKO RIVERA\",\n                \"KNEKRO\", \"KOKO\", \"KRONNOZOMBER\", \"LEVIATHAN\", \"LIT KILLAH\", \"LOLA LOLITA\", \"LOLITO\", \"LUH\", \"LUZU\",\n                \"MANGEL\", \"MAYICHI\", \"MELO\", \"MISSASINOFIA\", \"MIXWELL\", \"MR.JAGGER\", \"NATE GENTILE\", \"NEXXUZ\",\n                \"NIA\", \"NIL OJEDA\", \"NISSAXTER\", \"OLLIE\", \"ORSLOK\", \"OUTCONSUMER\", \"PAPI GAVI\", \"PARCETAMOR\",\n                \"PATICA\", \"PAULA GONU\", \"PAUSENPAII\", \"PERXITAA\", \"PLEX\", \"POLISPOL\", \"QUACKITY\", \"RECUERDOP\",\n                \"REVEN\", \"RIVERS\", \"ROBERTPG\", \"ROIER\", \"ROJUU\", \"RUBIUS\", \"SHADOUNE\", \"SILITHUR\", \"SPOKSPONHA\",\n                \"SPREEN\", \"SPURSITO\", \"STAXX\", \"SUZYROXX\", \"VICENS\", \"VITUBER\", \"WERLYB\", \"XAVI\", \"XCRY\", \"XOKAS\",\n                \"ZARCORT\", \"ZELING\", \"ZORMAN\"\n        );\n    }\n\n    private static String getAccessToken() throws IOException, InterruptedException {\n        // Crear el cuerpo de la solicitud\n        String body = \"client_id=\" + CLIENT_ID\n                + \"&client_secret=\" + CLIENT_SECRET\n                + \"&grant_type=client_credentials\";\n\n        HttpRequest request = HttpRequest.newBuilder()\n                .uri(URI.create(TOKEN_URL))\n                .header(\"Content-Type\", \"application/x-www-form-urlencoded\")\n                .POST(HttpRequest.BodyPublishers.ofString(body))\n                .build();\n\n        HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());\n\n        if (response.statusCode() != 200) {\n            throw new IOException(\"Error en la solicitud del token: \" + response.body());\n        }\n\n        JSONObject jsonResponse = new JSONObject(response.body());\n        if (!jsonResponse.has(\"access_token\")) {\n            throw new JSONException(\"Token de acceso no encontrado en la respuesta: \" + response.body());\n        }\n\n        return jsonResponse.getString(\"access_token\");\n    }\n\n    private static Optional<TwitchUser> getTwitchUserInfo(String username) {\n        try {\n            String encodedUsername = URLEncoder.encode(username, StandardCharsets.UTF_8);\n            HttpRequest request = HttpRequest.newBuilder()\n                    .uri(URI.create(TWITCH_API_URL_USERS + \"?login=\" + encodedUsername))\n                    .GET()\n                    .header(\"Authorization\", \"Bearer \" + accessToken)\n                    .header(\"Client-ID\", CLIENT_ID)\n                    .build();\n\n            HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());\n            if (response.statusCode() != 200) {\n                return Optional.empty();\n            }\n\n            JSONObject json = new JSONObject(response.body());\n            JSONArray data = json.optJSONArray(\"data\");\n            if (data != null && data.length() > 0) {\n                JSONObject userData = data.getJSONObject(0);\n                long followers = getFollowersCount(userData.getString(\"id\"));\n                return Optional.of(new TwitchUser(userData.getString(\"id\"),\n                        userData.getString(\"display_name\"), followers, userData.getString(\"created_at\")));\n            }\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n        return Optional.empty();\n    }\n\n    private static long getFollowersCount(String userId) throws IOException, InterruptedException {\n        HttpRequest request = HttpRequest.newBuilder()\n                .uri(URI.create(TWITCH_API_URL_FOLLOWERS + \"?broadcaster_id=\" + userId))\n                .GET()\n                .header(\"Authorization\", \"Bearer \" + accessToken)\n                .header(\"Client-ID\", CLIENT_ID)\n                .build();\n\n        HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());\n        if (response.statusCode() != 200) {\n            throw new IOException(\"Error obteniendo el número de seguidores: \" + response.body());\n        }\n\n        JSONObject json = new JSONObject(response.body());\n        return json.getLong(\"total\");\n    }\n\n    private static void printRanking(List<TwitchUser> usersWithFollowers, List<String> usersWithoutAccount) {\n        System.out.println(\"\\nRanking por número de seguidores\");\n        usersWithFollowers.sort(Comparator.comparingLong(TwitchUser::getFollowers).reversed());\n        usersWithFollowers.forEach(user ->\n                System.out.println(user.getDisplayName() + \": \" + user.getFollowers() + \" seguidores\"));\n\n        System.out.println(\"\\nRanking por antigüedad de la cuenta:\");\n        usersWithFollowers.sort(Comparator.comparing(TwitchUser::getCreationDate));\n        usersWithFollowers.forEach(user ->\n                System.out.println(user.getDisplayName() + \": \" + user.getCreationDataString()));\n\n        if (!usersWithoutAccount.isEmpty()) {\n            System.out.println(\"\\nUsuarios sin cuenta en Twitch:\");\n            System.out.println(String.join(\", \", usersWithoutAccount));\n        } else {\n            System.out.println(\"\\nTodos los participantes tienen cuenta en Twitch\");\n        }\n    }\n\n    static class TwitchUser {\n        private String id;\n        private String displayName;\n        private long followers;\n        private LocalDateTime creationDate;\n\n        public TwitchUser(String id, String displayName, long followers, String creationDate) {\n            this.id = id;\n            this.displayName = displayName;\n            this.followers = followers;\n            this.creationDate = (creationDate != null) ? parseCreationDate(creationDate) : null;\n        }\n\n        private LocalDateTime parseCreationDate(String creationDateString) {\n            return LocalDateTime.parse(creationDateString, creationDateFormat)\n                    .atOffset(ZoneOffset.UTC).toLocalDateTime();\n        }\n\n        public String getDisplayName() {\n            return displayName;\n        }\n\n        public long getFollowers() {\n            return followers;\n        }\n\n        public LocalDateTime getCreationDate() {\n            return creationDate;\n        }\n\n        public String getCreationDataString() {\n            return (creationDate != null) ? creationDate.format(outputDateFormat) : \"Fecha no disponible\";\n        }\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/40 - FORTNITE RUBIUS CUP/java/asjordi.java",
    "content": "import com.github.philippheuer.credentialmanager.domain.OAuth2Credential;\nimport com.github.twitch4j.ITwitchClient;\nimport com.github.twitch4j.TwitchClientBuilder;\nimport com.github.twitch4j.helix.domain.UserList;\n\nimport java.time.LocalDate;\nimport java.time.ZoneId;\nimport java.util.*;\n\npublic class asjordi {\n\n    static String clientId = \"\";\n    static String accessToken = \"\";\n\n    static ITwitchClient twitchClient = TwitchClientBuilder.builder()\n            .withDefaultAuthToken(new OAuth2Credential(clientId, accessToken))\n            .withEnableHelix(true)\n            .build();\n\n    public static void main(String[] args) {\n        List<Streamer> streamers = getStreamers();\n\n        streamers.forEach(streamer -> streamer.setFollowers(getTotalFollowers(String.valueOf(streamer.getId()))));\n\n        // sort by followers\n        streamers.sort(Comparator.comparing(Streamer::getFollowers).reversed());\n        System.out.println(\"Ranking by followers:\");\n        streamers.forEach(streamer -> System.out.println(streamer.getDisplayName() + \" has \" + streamer.getFollowers() + \" followers\"));\n\n        // sort by joined date\n        streamers.sort(Comparator.comparing(Streamer::getJoined));\n        System.out.println(\"Ranking by joined date:\");\n        streamers.forEach(streamer -> System.out.println(streamer.getDisplayName() + \" joined on \" + streamer.getJoined()));\n    }\n\n    public static List<Streamer> getStreamers() {\n        List<String> streamerNames = Arrays.asList(\n                \"littleragergirl\", \"ache\", \"adricontreras4\", \"agustin51\", \"alexby11\", \"ampeterby7\", \"tvander\", \"arigameplays\", \"arigeli_\", \"auronplay\",\n                \"axozer\", \"beniju03\", \"bycalitos\", \"byviruzz\", \"carreraaa\", \"celopan\", \"srcheeto\", \"crystalmolly\", \"darioemehache\", \"dheylo\",\n                \"djmariio\", \"doble\", \"elvisayomastercard\", \"elyas360\", \"folagorlives\", \"thegrefg\", \"guanyar\", \"hika\", \"hiperop\", \"ibai\",\n                \"ibelky_\", \"illojuan\", \"imantado\", \"irinaisasia\", \"jesskiu\", \"jopa\", \"jordiwild\", \"kenaivsouza\", \"mrkeroro10\", \"thekiddkeo95\",\n                \"kikorivera\", \"knekro\", \"a_big_koko\", \"kronnozomberoficial\", \"leviathan\", \"litkillah\", \"lolalolita\", \"lolitofdez\", \"luh\", \"luzu\",\n                \"mangel\", \"mayichi\", \"melo\", \"missasinfonia\", \"mixwell\", \"jaggerprincesa\", \"nategentile7\", \"nexxuz\", \"lakshartnia\", \"nilojeda\",\n                \"nissaxter\", \"olliegamerz\", \"orslok\", \"outconsumer\", \"papigavitv\", \"paracetamor\", \"patica1999\", \"paulagonu\", \"pausenpaii\", \"perxitaa\",\n                \"nosoyplex\", \"polispol1\", \"quackity\", \"recuerd0p\", \"reventxz\", \"rivers_gg\", \"robertpg\", \"roier\", \"rojuu\", \"rubius\",\n                \"shadoune666\", \"silithur\", \"spok_sponha\", \"elspreen\", \"spursito\", \"bystaxx\", \"suzyroxx\", \"vicens\", \"vitu\", \"werlyb\",\n                \"xavi\", \"xcry\", \"elxokas\", \"thezarcort\", \"zeling\", \"zormanworld\"\n        );\n\n        List<Streamer> streamers = new LinkedList<>();\n\n        UserList resultList = twitchClient.getHelix().getUsers(null, null, streamerNames).execute();\n        resultList.getUsers().forEach(user -> streamers.add(new Streamer(Long.parseLong(user.getId()), user.getLogin(), user.getDisplayName(), user.getCreatedAt().atZone(ZoneId.systemDefault()).toLocalDate())));\n\n        return streamers;\n    }\n\n    public static int getTotalFollowers(String id) {\n        var followers = twitchClient.getHelix().getChannelFollowers(accessToken, id, null, 100, null).execute();\n        return followers.getTotal();\n    }\n\n    static class Streamer {\n        private long id;\n        private String login;\n        private String displayName;\n        private int followers;\n        private LocalDate joined;\n\n        public Streamer(long id, String login, String displayName, LocalDate joined) {\n            this.id = id;\n            this.login = login;\n            this.displayName = displayName;\n            this.joined = joined;\n        }\n\n        public long getId() {\n            return id;\n        }\n\n        public String getLogin() {\n            return login;\n        }\n\n        public String getDisplayName() {\n            return displayName;\n        }\n\n        public int getFollowers() {\n            return followers;\n        }\n\n        public LocalDate getJoined() {\n            return joined;\n        }\n\n        public void setFollowers(int followers) {\n            this.followers = followers;\n        }\n\n        @Override\n        public String toString() {\n            return new StringJoiner(\", \", Streamer.class.getSimpleName() + \"[\", \"]\")\n                    .add(\"id=\" + id)\n                    .add(\"login='\" + login + \"'\")\n                    .add(\"displayName='\" + displayName + \"'\")\n                    .add(\"followers=\" + followers)\n                    .add(\"joined=\" + joined)\n                    .toString();\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/40 - FORTNITE RUBIUS CUP/java/martinbohorquez.java",
    "content": "import com.google.gson.JsonArray;\nimport com.google.gson.JsonObject;\nimport com.google.gson.JsonParser;\n\nimport java.io.IOException;\nimport java.net.*;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\nimport java.nio.charset.StandardCharsets;\nimport java.util.*;\nimport java.util.concurrent.atomic.AtomicInteger;\n\nimport static java.net.http.HttpClient.newHttpClient;\n\n/**\n * #40 FORTNITE RUBIUS CUP\n * <dependency>\n * <groupId>com.google.code.gson</groupId>\n * <artifactId>gson</artifactId>\n * <version>2.10.1</version>\n * </dependency>\n *\n * @author martinbohorquez\n */\n\n\npublic class martinbohorquez {\n    private static final String TWITCH_ID = System.getenv(\"TWITCH_ID\");\n    private static final String TWITCH_SECRET = System.getenv(\"TWITCH_SECRET\");\n    private static final String TOKEN_URL = \"https://id.twitch.tv/oauth2/token\";\n    private static final String USER_URL = \"https://api.twitch.tv/helix/users?login=\";\n    private static final String FOLLOWERS_URL = \"https://api.twitch.tv/helix/channels/followers?broadcaster_id=\";\n\n    public static void main(String[] args) throws Exception {\n        // 1. Token\n        String token = getToken();\n\n        // 2. IDs\n        List<Map<String, String>> usersData = new ArrayList<>();\n        List<String> usersNoData = new ArrayList<>();\n        List<String> users = List.of(\n                \"littleragergirl\", \"ache\", \"adricontreras4\", \"agustin51\", \"alexby11\", \"ampeterby7\", \"tvander\",\n                \"arigameplays\", \"arigeli_\", \"auronplay\", \"axozer\", \"beniju03\", \"bycalitos\",\n                \"byviruzz\", \"carreraaa\", \"celopan\", \"srcheeto\", \"crystalmolly\", \"darioemehache\",\n                \"dheylo\", \"djmariio\", \"doble\", \"elvisayomastercard\", \"elyas360\", \"folagorlives\", \"thegrefg\",\n                \"guanyar\", \"hika\", \"hiperop\", \"ibai\", \"ibelky_\", \"illojuan\", \"imantado\",\n                \"irinaissaia\", \"jesskiu\", \"jopa\", \"jordiwild\", \"kenaivsouza\", \"mrkeroro10\",\n                \"thekiddkeo95\", \"kikorivera\", \"knekro\", \"kokoop\", \"kronnozomberoficial\", \"leviathan\",\n                \"litkillah\", \"lolalolita\", \"lolitofdez\", \"luh\", \"luzu\", \"mangel\", \"mayichi\",\n                \"melo\", \"missasinfonia\", \"mixwell\", \"jaggerprincesa\", \"nategentile7\", \"nexxuz\",\n                \"lakshartnia\", \"nilojeda\", \"nissaxter\", \"olliegamerz\", \"orslok\", \"outconsumer\", \"papigavitv\",\n                \"paracetamor\", \"patica1999\", \"paulagonu\", \"pausenpaii\", \"perxitaa\", \"nosoyplex\",\n                \"polispol1\", \"quackity\", \"recuerd0p\", \"reventxz\", \"rivers_gg\", \"robertpg\", \"roier\",\n                \"ceuvebrokenheart\", \"rubius\", \"shadoune666\", \"silithur\", \"spok_sponha\", \"elspreen\", \"spursito\",\n                \"bystaxx\", \"suzyroxx\", \"vicens\", \"vitu\", \"werlyb\", \"xavi\", \"xcry\", \"elxokas\",\n                \"thezarcort\", \"zeling\", \"zormanworld\", \"mouredev\"\n        );\n        for (String username: users) {\n            JsonObject user = getUserInfo(token, username);\n            if (user == null) usersNoData.add(username);\n            else {\n                Map<String, String> userMap = new HashMap<>();\n                userMap.put(\"username\", username);\n                userMap.put(\"created_at\", user.get(\"created_at\").getAsString());\n                int followers = getTotalFollowers(token, user.get(\"id\").getAsString());\n                userMap.put(\"followers\", Integer.toString(followers));\n                usersData.add(userMap);\n            }\n        }\n        System.out.println(\"Lista de usuarios que no tienen cuenta de Twitch:\");\n        usersNoData.forEach(user -> System.out.printf(\"- %s%n\", user));\n\n        System.out.println(\"Lista de usuarios que tienen cuenta de Twitch:\");\n\n        System.out.println(\"Ordenado por followers de forma descendente\");\n        usersData.sort(Comparator.comparing(u -> u.get(\"followers\")));\n        AtomicInteger i = new AtomicInteger(1);\n        usersData.reversed().forEach(user -> System.out.printf(\"%d.- %s%n\", i.getAndIncrement(),\n                user.get(\"username\") + \": \" + user.get(\"followers\") + \" followers\"));\n\n        System.out.println(\"Ordenado por fecha de creación de forma ascendente\");\n        usersData.sort(Comparator.comparing(u -> u.get(\"created_at\")));\n        AtomicInteger j = new AtomicInteger(1);\n        usersData.forEach(user -> System.out.printf(\"%d.- %s%n\", j.getAndIncrement(),\n                user.get(\"username\") + \": \" + user.get(\"created_at\")));\n\n    }\n\n    private static String getToken() {\n        HttpRequest request = HttpRequest.newBuilder()\n                .uri(URI.create(TOKEN_URL))\n                .header(\"Content-Type\", \"application/x-www-form-urlencoded\") // Add headers\n                .POST(HttpRequest.BodyPublishers.ofString(\n                        \"client_id=\" + TWITCH_ID + \"&client_secret=\" + TWITCH_SECRET + \"&grant_type=client_credentials\"))\n                .build();\n        JsonObject jsonObject = getJsonObject(request);\n        return jsonObject.get(\"access_token\").getAsString();\n    }\n\n    private static JsonObject getUserInfo(String token, String user) {\n        String encodedUser = URLEncoder.encode(user, StandardCharsets.UTF_8);\n        JsonObject json = getJson(token, USER_URL + encodedUser);\n        JsonArray userList = json.getAsJsonArray(\"data\");\n        if (userList == null) return null;\n        if (userList.isEmpty()) return null;\n        return userList.get(0).getAsJsonObject();\n    }\n\n    private static int getTotalFollowers(String token, String id) {\n        JsonObject json = getJson(token, FOLLOWERS_URL + id);\n        return json.get(\"total\").getAsInt();\n    }\n\n    private static JsonObject getJson(String token, String url) {\n        HttpRequest request = HttpRequest.newBuilder()\n                .uri(URI.create(url))\n                .header(\"Authorization\", \"Bearer \" + token) // Authorization header if needed\n                .header(\"Client-Id\", TWITCH_ID)\n                .build();\n        return getJsonObject(request);\n    }\n\n    private static JsonObject getJsonObject(HttpRequest request) {\n        HttpResponse<String> response;\n        try (HttpClient client = newHttpClient()) {\n            response = client.send(request, HttpResponse.BodyHandlers.ofString());\n        } catch (IOException | InterruptedException e) {\n            throw new RuntimeException(e);\n        }\n        String responseBody = response.body();\n        return JsonParser.parseString(responseBody).getAsJsonObject();\n    }\n}\n"
  },
  {
    "path": "Roadmap/40 - FORTNITE RUBIUS CUP/java/miguelex.java",
    "content": "import java.io.*;\nimport java.net.*;\nimport java.nio.charset.StandardCharsets;\nimport java.util.*;\nimport org.json.*;\n\npublic class miguelex {\n\n    public static String obtenerTokenOAuth(String clientId, String clientSecret) throws IOException {\n        String url = \"https://id.twitch.tv/oauth2/token\";\n        String urlParameters = \"client_id=\" + clientId + \"&client_secret=\" + clientSecret + \"&grant_type=client_credentials\";\n\n        byte[] postData = urlParameters.getBytes(StandardCharsets.UTF_8);\n        int postDataLength = postData.length;\n\n        URL obj = new URL(url);\n        HttpURLConnection con = (HttpURLConnection) obj.openConnection();\n\n        con.setDoOutput(true);\n        con.setRequestMethod(\"POST\");\n        con.setRequestProperty(\"Content-Type\", \"application/x-www-form-urlencoded\");\n        con.setRequestProperty(\"Content-Length\", Integer.toString(postDataLength));\n\n        try (DataOutputStream wr = new DataOutputStream(con.getOutputStream())) {\n            wr.write(postData);\n        }\n\n        BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));\n        String inputLine;\n        StringBuilder response = new StringBuilder();\n\n        while ((inputLine = in.readLine()) != null) {\n            response.append(inputLine);\n        }\n        in.close();\n\n        JSONObject jsonResponse = new JSONObject(response.toString());\n        return jsonResponse.getString(\"access_token\");\n    }\n\n    public static JSONObject obtenerInfoUsuarioTwitch(String accessToken, String clientId, String username) throws IOException {\n        username = username.replaceAll(\"[^a-zA-Z0-9_]\", \"\");\n        String url = \"https://api.twitch.tv/helix/users?login=\" + URLEncoder.encode(username, \"UTF-8\");\n\n        HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();\n        con.setRequestMethod(\"GET\");\n        con.setRequestProperty(\"Authorization\", \"Bearer \" + accessToken);\n        con.setRequestProperty(\"Client-ID\", clientId);\n\n        int responseCode = con.getResponseCode();\n        if (responseCode != 200) {\n            return null;\n        }\n\n        BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));\n        String inputLine;\n        StringBuilder response = new StringBuilder();\n\n        while ((inputLine = in.readLine()) != null) {\n            response.append(inputLine);\n        }\n        in.close();\n\n        JSONObject jsonResponse = new JSONObject(response.toString());\n        return jsonResponse.getJSONArray(\"data\").isEmpty() ? null : jsonResponse.getJSONArray(\"data\").getJSONObject(0);\n    }\n\n    public static int obtenerNumeroSeguidoresTwitch(String accessToken, String clientId, String userId) throws IOException {\n        String url = \"https://api.twitch.tv/helix/channels/followers?broadcaster_id=\" + userId;\n\n        HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();\n        con.setRequestMethod(\"GET\");\n        con.setRequestProperty(\"Authorization\", \"Bearer \" + accessToken);\n        con.setRequestProperty(\"Client-ID\", clientId);\n\n        int responseCode = con.getResponseCode();\n        if (responseCode != 200) {\n            return 0;\n        }\n\n        BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));\n        String inputLine;\n        StringBuilder response = new StringBuilder();\n\n        while ((inputLine = in.readLine()) != null) {\n            response.append(inputLine);\n        }\n        in.close();\n\n        JSONObject jsonResponse = new JSONObject(response.toString());\n        return jsonResponse.has(\"total\") ? jsonResponse.getInt(\"total\") : 0;\n    }\n\n    public static void main(String[] args) {\n        String clientId = \"TU_CLIENT_ID\";\n        String clientSecret = \"TU_CLIENT_SECRET\";\n\n        String[] participantes = {\n        \"Abby\", \"Ache\", \"Adri Contreras\", \"Agustin\", \"Alexby\", \"Ampeter\", \"Ander\", \"Ari Gameplays\",\n        \"Arigely\", \"Auronplay\", \"Axozer\", \"Beniju\", \"By Calitos\", \"Byviruzz\", \"Carrera\", \"Celopan\",\n        \"Cheto\", \"CrystalMolly\", \"Dario Eme Hache\", \"Dheyo\", \"DjMariio\", \"Doble\", \"Elvisa\", \"Elyas360\",\n        \"Folagor\", \"Grefg\", \"Guanyar\", \"Hika\", \"Hiper\", \"Ibai\", \"Ibelky\", \"Illojuan\", \"Imantado\",\n        \"Irina Isasia\", \"JessKiu\", \"Jopa\", \"JordiWild\", \"Kenai Souza\", \"Keroro\", \"Kidd Keo\", \"Kiko Rivera\",\n        \"Knekro\", \"Koko\", \"KronnoZomber\", \"Leviathan\", \"Lit Killah\", \"Lola Lolita\", \"Lolito\", \"Luh\",\n        \"Luzu\", \"Mangel\", \"Mayichi\", \"Melo\", \"MissaSinfonia\", \"Mixwell\", \"Mr. Jagger\", \"Nate Gentile\",\n        \"Nexxuz\", \"Nia\", \"Nil Ojeda\", \"NissaXter\", \"Ollie\", \"Orslok\", \"Outconsumer\", \"Papi Gavi\",\n        \"Paracetamor\", \"Patica\", \"Paula Gonu\", \"Pausenpaii\", \"Perxitaa\", \"Plex\", \"Polispol\", \"Quackity\",\n        \"RecueroDP\", \"Reven\", \"Rivers\", \"RobertPG\", \"Roier\", \"Rojuu\", \"Rubius\", \"Shadoune\", \"Silithur\",\n        \"SpokSponha\", \"Spreen\", \"Spursito\", \"Staxx\", \"SuzyRoxx\", \"Vicens\", \"Vituber\", \"Werlyb\", \"Xavi\",\n        \"Xcry\", \"Xokas\", \"Zarcort\", \"Zeling\", \"Zorman\"\n        };\n\n        try {\n            String accessToken = obtenerTokenOAuth(clientId, clientSecret);\n\n            List<Map<String, Object>> infoUsuarios = new ArrayList<>();\n            List<String> errores = new ArrayList<>();\n\n            for (String participante : participantes) {\n                JSONObject usuario = obtenerInfoUsuarioTwitch(accessToken, clientId, participante);\n\n                if (usuario != null) {\n                    int seguidores = obtenerNumeroSeguidoresTwitch(accessToken, clientId, usuario.getString(\"id\"));\n\n                    Map<String, Object> userInfo = new HashMap<>();\n                    userInfo.put(\"username\", usuario.getString(\"display_name\"));\n                    userInfo.put(\"followers\", seguidores);\n                    userInfo.put(\"creation_date\", usuario.getString(\"created_at\"));\n\n                    infoUsuarios.add(userInfo);\n                } else {\n                    errores.add(\"El participante \" + participante + \" no tiene usuario en Twitch.\");\n                }\n            }\n\n            infoUsuarios.sort((a, b) -> Integer.compare((int) b.get(\"followers\"), (int) a.get(\"followers\")));\n\n            System.out.println(\"Ranking por número de seguidores:\");\n            for (Map<String, Object> usuario : infoUsuarios) {\n                System.out.println(usuario.get(\"username\") + \" - \" + usuario.get(\"followers\") + \" seguidores\");\n            }\n\n            infoUsuarios.sort((a, b) -> ((String) a.get(\"creation_date\")).compareTo((String) b.get(\"creation_date\")));\n\n            System.out.println(\"\\nRanking por antigüedad de la cuenta:\");\n            for (Map<String, Object> usuario : infoUsuarios) {\n                System.out.println(usuario.get(\"username\") + \" - Cuenta creada el \" + usuario.get(\"creation_date\"));\n            }\n\n            if (!errores.isEmpty()) {\n                System.out.println(\"\\nErrores:\");\n                for (String error : errores) {\n                    System.out.println(error);\n                }\n            }\n\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/40 - FORTNITE RUBIUS CUP/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #40 - JavaScript -> Jesus Antonio Escamilla */\n\n/**\n * FORTNITE RUBIUS CUP.\n * Utilizando la Terminal para pedir datos y agregarlos.\n */\n\nconst participants = [\n    \"littleragergirl\", \"ache\", \"adricontreras4\", \"agustin51\", \"alexby11\", \"ampeterby7\", \"tvander\",\n    \"arigameplays\", \"arigeli_\", \"auronplay\", \"axozer\", \"beniju03\", \"bycalitos\",\n    \"byviruzz\", \"carreraaa\", \"celopan\", \"srcheeto\", \"crystalmolly\", \"darioemehache\",\n    \"dheylo\", \"djmariio\", \"doble\", \"elvisayomastercard\", \"elyas360\", \"folagorlives\", \"thegrefg\",\n    \"guanyar\", \"hika\", \"hiperop\", \"ibai\", \"ibelky_\", \"illojuan\", \"imantado\",\n    \"irinaissaia\", \"jesskiu\", \"jopa\", \"jordiwild\", \"kenaivsouza\", \"mrkeroro10\",\n    \"thekiddkeo95\", \"kikorivera\", \"knekro\", \"kokoop\", \"kronnozomberoficial\", \"leviathan\",\n    \"litkillah\", \"lolalolita\", \"lolitofdez\", \"luh\", \"luzu\", \"mangel\", \"mayichi\",\n    \"melo\", \"missasinfonia\", \"mixwell\", \"jaggerprincesa\", \"nategentile7\", \"nexxuz\",\n    \"lakshartnia\", \"nilojeda\", \"nissaxter\", \"olliegamerz\", \"orslok\", \"outconsumer\", \"papigavitv\",\n    \"paracetamor\", \"patica1999\", \"paulagonu\", \"pausenpaii\", \"perxitaa\", \"nosoyplex\",\n    \"polispol1\", \"quackity\", \"recuerd0p\", \"reventxz\", \"rivers_gg\", \"robertpg\", \"roier\",\n    \"ceuvebrokenheart\", \"rubius\", \"shadoune666\", \"silithur\", \"spok_sponha\", \"elspreen\", \"spursito\",\n    \"bystaxx\", \"suzyroxx\", \"vicens\", \"vitu\", \"werlyb\", \"xavi\", \"xcry\", \"elxokas\",\n    \"thezarcort\", \"zeling\", \"zormanworld\", \"mouredev\"\n];\n\nconst twitch_clientId = 'MY_ID_TWITCH';\nconst twitch_clientSecret = 'MY_SECRET_TWITCH';\n\n// Para obtener un token\nasync function tokenAccessTwitch(clientId, clientSecret) {\n    const response = await fetch(`https://id.twitch.tv/oauth2/token`, {\n        method: 'POST',\n        headers: {\n            'Content-Type': 'application/x-www-form-urlencoded'\n        },\n        body: `client_id=${clientId}&client_secret=${clientSecret}&grant_type=client_credentials`\n    });\n\n    if (!response.ok) {\n        console.error(`HTTP error! status: ${response.status}`);\n    }\n\n    const result = await response.json();\n    return result.access_token;\n}\n\n// Para obtener el acceso a Twitch\nasync function fetchTwitchAPI(endpoint) {\n    const tokenAccess = await tokenAccessTwitch(twitch_clientId, twitch_clientSecret)\n    const response = await fetch(`https://api.twitch.tv/helix${endpoint}`, {\n        headers:{\n            'Client-ID': twitch_clientId,\n            'Authorization': `Bearer ${tokenAccess}`\n        }\n    });\n\n    if (!response.ok) {\n        console.error(`Error en la API de Twitch: ${response.status}`);\n    }\n    return response.json();\n}\n\n// Para obtener los datos los participantes\nasync function getUserInfo(username) {\n    const userData = await fetchTwitchAPI(`/users?login=${username}`)\n    if (userData.data.length > 0) {\n        const user = userData.data[0];\n        const followersData = await fetchTwitchAPI(`/channels/followers?broadcaster_id=${user.id}`)\n        return{\n            username: user.login,\n            displayName: user.display_name,\n            followers: followersData.total,\n            createdAt: user.created_at\n        };\n    }\n    return null;\n}\n\nasync function rankingGammer() {\n    const participantInfo = [];\n\n    for (const participant of participants) {\n        const info = await getUserInfo(participant)\n        if (info) {\n            participantInfo.push(info);\n        } else {\n            console.log(`${participant} no tiene cuenta de Twitch o no se pudo obtener la información.`);\n        }\n    }\n\n    // Ranking por número de seguidores\n    const followerRanking = [...participantInfo].sort((a, b) => b.followers - a.followers);\n    \n    console.log(\"Ranking por número de seguidores:\");\n    followerRanking.forEach((p, index) => {\n        console.log(`${index + 1}. ${p.displayName}: ${p.followers} seguidores`);\n    });\n\n    // Ranking por antigüedad\n    const ageRanking = [...participantInfo].sort((a, b) => new Date(a.createdAt) - new Date(b.createdAt));\n    \n    console.log(\"\\nRanking por antigüedad de cuenta:\");\n    ageRanking.forEach((p, index) => {\n        console.log(`${index + 1}. ${p.displayName}: Cuenta creada el ${new Date(p.createdAt).toLocaleDateString()}`);\n    });\n}\n\n// Ejecutar el programa\nrankingGammer()"
  },
  {
    "path": "Roadmap/40 - FORTNITE RUBIUS CUP/javascript/RaulDoezon.js",
    "content": "/*\n  EJERCICIO:\n  ¡Rubius tiene su propia skin en Fortnite!\n  Y va a organizar una competición para celebrarlo.\n  Esta es la lista de participantes:\n  https://x.com/Rubiu5/status/1840161450154692876\n \n  Desarrolla un programa que obtenga el número de seguidores en\n  Twitch de cada participante, la fecha de creación de la cuenta \n  y ordene los resultados en dos listados.\n  - Usa el API de Twitch: https://dev.twitch.tv/docs/api/reference\n    (NO subas las credenciales de autenticación)\n  - Crea un ranking por número de seguidores y por antigüedad.\n  - Si algún participante no tiene usuario en Twitch, debe reflejarlo.\n*/\n\nconst accessToken = 'ACCESS_TOKEN';\nconst clientID = 'CLIENT_ID';\nconst userNames = [\n  'abby', 'Ache', 'AdriContreras4', 'agustin51', 'Alexby11', 'Ampeterby7', 'tvandeR', 'AriGameplays', 'AriGeli', 'auronplay',\n  'aXoZer', 'BENIJU03', 'bycalitos', 'byViruZz', 'Carreraaa', 'Celopan', 'srcheeto', 'CrystalMolly', 'darioemehache', 'Dheylo',\n  'DjMaRiiO', 'Doble', 'ElvisaYomastercard', 'elyas360', 'FolagorLives', 'TheGrefg', 'GUANYAR', 'Hika', 'Hiperop', 'ibai',\n  'ibelky_', 'IlloJuan', 'imantado', 'IRINA__ISASIA', 'Jesskiu', 'JOPA', 'JordiWild', 'kenaivsouza', 'MrKeroro10', 'TheKiddKeo95',\n  'KikoRivera', 'knekro', 'KOKO', 'KronnoZomberOficial', 'Leviathan', 'LITkillah', 'lolalolita', 'LolitoLp', 'Luh', 'Luzu',\n  'Mangel', 'Mayichi', 'melo', 'MissaSinfonia', 'Mixwell', 'JaggerPrincesa', 'NateGentile7', 'Nexxuz', 'LakshartNia', 'nilojeda',\n  'Nissaxter', 'OllieGamerz', 'orslok', 'Outconsumer', 'PapiGaviTV', 'paracetamor', 'patica1999', 'paulagonu', 'PauSenpaii', 'Perxitaa',\n  'NoSoyPlex', 'polispol1', 'Quackity', 'Recuerd0p', 'ReventXz', 'rivers_gg', 'robertpg', 'Roier', 'ROJUU', 'Rubius',\n  'Shadoune666', 'Silithur', 'spok_sponha', 'ElSpreen', 'Spursito', 'bysTaXx', 'Suzyroxx', 'Vicens', 'vitu', 'Werlyb',\n  'Xavi', 'xCry', 'elxokas', 'theZARCORT', 'Zeling', 'ZormanWorld',\n].map((nickname) => nickname.toLowerCase());\nlet streamersList = '';\nlet streamers = [];\nlet sortByDate;\nlet sortByFollowers;\n\nfor (let index = 0; index < userNames.length; index++) {\n  streamersList += `${index > 0 ? '&' : ''}login=${userNames[index]}`;\n}\n\nasync function fetchTwichAPI(endpoint, method, body) {\n  try {\n    const response = await fetch(`https://api.twitch.tv/helix/${endpoint}`, {\n      headers: {\n        Authorization: `Bearer ${accessToken}`,\n        \"Client-id\": clientID,\n      },\n      method,\n      body: JSON.stringify(body),\n    });\n\n    return await response.json();\n  } catch(error) {\n    console.log(error);\n  }\n}\n\nconst prepareData = async (login) => {\n  const broadcasters = await fetchTwichAPI(`users?${login}`, 'GET');\n\n  for (const broadcaster of broadcasters.data) {\n    let broadcasterFollowers = await fetchTwichAPI(`channels/followers?broadcaster_id=${broadcaster.id}`, 'GET');\n\n    streamers.push({ name: broadcaster.login, date: broadcaster.created_at, followers: broadcasterFollowers.total });\n  }\n\n  sortByDate = [...streamers].sort((a, b) => new Date(a.date) - new Date(b.date));\n  sortByFollowers = [...streamers].sort((c, d) => d.followers - c.followers);\n}\n\nconst createTables = () => {\n  console.log('\\nRANKING POR ANTIGÜEDAD');\n\n  for (let index = 0; index < sortByDate.length; index++) {\n    console.log(`${index + 1}. Streamer: ${sortByDate[index].name} | Fecha de creación: ${sortByDate[index].date}`);\n  }\n\n  console.log('\\nRANKING POR SEGUIDORES');\n\n  for (let index = 0; index < sortByFollowers.length; index++) {\n    console.log(`${index + 1}. Streamer: ${sortByFollowers[index].name} | Seguidores: ${sortByFollowers[index].followers}`);\n  }\n\n  console.log('\\nPERSONAS SIN CUENTA EN TWICH');\n\n  for (let index = 0; index < userNames.length; index++) {\n    if (streamers.map(element => element.name).indexOf(userNames[index]) === -1) {\n      console.log(`- ${userNames[index]}`);\n    }\n  }\n}\n\nasync function showInformation() {\n  await Promise.all([prepareData(streamersList)]);\n\n  createTables();\n}\n\nshowInformation();\n"
  },
  {
    "path": "Roadmap/40 - FORTNITE RUBIUS CUP/javascript/RicJDev.js",
    "content": "/*\n  EJERCICIO:\n\n  @RicJDev\n*/\n\nimport { CLIENT_ID, CLIENT_SECRET } from './client.js'\n\n/*\n  Función para obtener token de autenticación.\n  Solo se ejecuta si se le pasa un client_id y un client_secret (los cuales no subiré al repo).\n\n  Consulta la documentación de la API de Twitch para más información (https://dev.twitch.tv/docs).\n*/\n\nasync function getAccessToken(clientId, clientSecret) {\n  const token = await fetch('https://id.twitch.tv/oauth2/token', {\n    method: 'POST',\n    headers: {\n      'Content-Type': 'application/x-www-form-urlencoded',\n    },\n    body: new URLSearchParams({\n      grant_type: 'client_credentials',\n      client_id: clientId,\n      client_secret: clientSecret,\n    }),\n  }).then((response) => {\n    if (response.status !== 200)\n      throw new Error(`Falla al obtener respuesta de la API. ${response.json()}`)\n\n    return response.json()\n  })\n\n  return token.access_token\n}\n\n// Métodos de auntenticación que necesitaremos para las peticiones.\n\nconst accessToken = await getAccessToken(CLIENT_ID, CLIENT_SECRET)\n\nconst requestBody = {\n  headers: {\n    'Client-ID': CLIENT_ID,\n    Accept: 'application/vnd.twitchtv.v5+json',\n    Authorization: `Bearer ${accessToken}`,\n  },\n}\n\n// Usaremos esta función para obtener el número total de seguidores del usuario.\n\nasync function getTotalFollowers(userId) {\n  const url = `https://api.twitch.tv/helix/channels/followers?broadcaster_id=${userId}`\n\n  const results = await fetch(url, requestBody).then((response) => {\n    if (response.status !== 200)\n      throw new Error(`Error al obtener seguidores del canal con la id: ${userId}.`)\n\n    return response.json()\n  })\n\n  return results.total\n}\n\n// Y con esta obtendremos los datos los participantes.\n\nasync function getUsersData(users, ...more) {\n  if (users.constructor.name === 'Array') users = users.join('&login=')\n  if (more.length > 0) users += `&login=${more.join('&login=')}`\n\n  const url = `https://api.twitch.tv/helix/users?login=${users}`\n  const result = await fetch(url, requestBody).then((response) => {\n    if (response.status !== 200) throw new Error(`Error al obtener los datos solicitados ${users}`)\n\n    return response.json()\n  })\n\n  const usersData = []\n\n  for (let i = 0; i < result.data.length; i++) {\n    const user = result.data[i]\n\n    usersData.push({\n      id: user.id,\n      login: user.login,\n      displayName: user.display_name,\n      followers: await getTotalFollowers(user.id),\n      createdAt: user.created_at,\n    })\n  }\n\n  return usersData\n}\n\n// Esta es la lista de participantes. La lista original ha sido modificada para que cada elemento corresponda al login del participante.\n\nconst participants = [\n  'littleragergirl', 'ache', 'adricontreras4', 'agustin51', 'alexby11', 'ampeterby7', 'tvander',\n  'arigameplays', 'arigeli_', 'auronplay', 'axozer', 'beniju03', 'bycalitos',\n  'byviruzz', 'carreraaa', 'celopan', 'srcheeto', 'crystalmolly', 'darioemehache',\n  'dheylo', 'djmariio', 'doble', 'elvisayomastercard', 'elyas360', 'folagorlives', 'thegrefg',\n  'guanyar', 'hika', 'hiperop', 'ibai', 'ibelky_', 'illojuan', 'imantado',\n  'irinaissaia', 'jesskiu', 'jopa', 'jordiwild', 'kenaivsouza', 'mrkeroro10',\n  'thekiddkeo95', 'kikorivera', 'knekro', 'kokoop', 'kronnozomberoficial', 'leviathan',\n  'litkillah', 'lolalolita', 'lolitofdez', 'luh', 'luzu', 'mangel', 'mayichi',\n  'melo', 'missasinfonia', 'mixwell', 'jaggerprincesa', 'nategentile7', 'nexxuz',\n  'lakshartnia', 'nilojeda', 'nissaxter', 'olliegamerz', 'orslok', 'outconsumer', 'papigavitv',\n  'paracetamor', 'patica1999', 'paulagonu', 'pausenpaii', 'perxitaa', 'nosoyplex',\n  'polispol1', 'quackity', 'recuerd0p', 'reventxz', 'rivers_gg', 'robertpg', 'roier',\n  'ceuvebrokenheart', 'rubius', 'shadoune666', 'silithur', 'spok_sponha', 'elspreen', 'spursito',\n  'bystaxx', 'suzyroxx', 'vicens', 'vitu', 'werlyb', 'xavi', 'xcry', 'elxokas',\n  'thezarcort', 'zeling', 'zormanworld'\n]\n\nconst participantsData = await getUsersData(participants)\n\n// Ordenar por antigüedad.\n\nconst sortedByOld = participantsData.toSorted((a, b) => new Date(a.createdAt) - new Date(b.createdAt))\n\nconsole.log('\\nRanking por antigüedad.')\nsortedByOld.forEach((streamer, index) => {\n  console.log(`${index + 1}. ${streamer.displayName}. ${new Date(streamer.createdAt).toLocaleDateString()}`)\n})\n\n// Ordenar por número de seguidores.\n\nconst sortedByFollowers = participantsData.toSorted((a, b) => b.followers - a.followers)\n\nconsole.log('\\nRanking de seguidores.')\nsortedByFollowers.forEach((streamer, index) => {\n  console.log(`${index + 1}. ${streamer.displayName}: ${streamer.followers.toLocaleString()}`)\n})\n\n// Resultados no encontrados.\n\nconst notFound = [...participants]\n\nparticipantsData.forEach((streamer) => {\n  if (notFound.includes(streamer.login)) {\n    notFound.splice(notFound.indexOf(streamer.login), 1)\n  }\n})\n\nconsole.log('\\nResultados no encontrados:')\nnotFound.forEach((participant, index) => console.log(`${index + 1}. ${participant}`))\n"
  },
  {
    "path": "Roadmap/40 - FORTNITE RUBIUS CUP/javascript/duendeintemporal.js",
    "content": "//#40 - FORTNITE RUBIUS CUP\n/*\n * EJERCICIO:\n * ¡Rubius tiene su propia skin en Fortnite!\n * Y va a organizar una competición para celebrarlo.\n * Esta es la lista de participantes:\n * https://x.com/Rubiu5/status/1840161450154692876\n *\n * Desarrolla un programa que obtenga el número de seguidores en\n * Twitch de cada participante, la fecha de creación de la cuenta \n * y ordene los resultados en dos listados.\n * - Usa el API de Twitch: https://dev.twitch.tv/docs/api/reference\n *   (NO subas las credenciales de autenticación)\n * - Crea un ranking por número de seguidores y por antigüedad.\n * - Si algún participante no tiene usuario en Twitch, debe reflejarlo.\n */\n\n//We will use https://jpgtoexcel.com/es to extract the list of the participants from the post image related with the first url of the challenge to a Excell file an then incorpore it to a participant list.\n\n/* We will use Axios to make HTTP requests. You can install it using npm:\n#bash\nnpm install axios */\n\nlet log = console.log;\n\nconst axios = require('axios');\n\n// Replace here with your Twitch client ID and client secret\nconst CLIENT_ID = 'YOUR_CLIENT_ID';\nconst CLIENT_SECRET = 'YOUR_CLIENT_SECRET';\n\nconst participants = [\n    'ABBY',\n    'DJMARIIO',\t\n    'KIKO RIVERA',\n    'NISSAXTER',\n    'SHADOUNE',\t\n    'SILTHURA',\n    'ACHE',\n    'DOBLE',\n    'KNEKRO',\n    'OLLI',\n    'SPOKSPHORA',\n    'SPREEN',\n    'ADRI CONTRERAS',\n    'ELVISA',\n    'KOKO',\n    'OUTCONSUMER',\n    'PAPI GAVI',\n    'PARACETAMOR',\n    'AGUSTIN',\n    'ELYAS360',\n    'KRONONOMZOR',\n    'LEVIATHAN',\n    'LT KILAH',\n    'PATTAC',\n    'ALEXBY',\n    'FOLAGOR',\n    'LOLA LOLITA',\n    'PAULA GONI',\n    'PAUSENPAI',\n    'PERKITA',\n    'AMPETER',\n    'GREGR',\n    'LUH',\n    'MANGEL',\n    'PLEX',\n    'QUACKITY',\n    'ARI GAMEPLAYS',\n    'HIKA',\n    'HIPER',\n    'ILAI',\n    'MELO',\n    'RECEDROP',\n    'AUXOZER',\n    'IBELKY',\n    'ILOI JUAN',\n    'MAYICH',\n    'RIVERS',\n    'ROBERTP',\n    'BYCLITOS',\n    'IMANOTAD',\n    'IRINA ISAIA',\n    'MIKEL',\n    'ROJER',\n    'ROHI',\n    'BYVIRUZZ',\n    'JESKSU',\n    'JOPA',\n    'MR. JAGGER',\n    'ROJER',\n    'RUBIUS',\n    'CARRERA',\n    'JORIDWILD',\n    'KEANI SOUZA',\n    'NEXUZ',\n    'RIVERA',\n    'ZELIN',\n    'CHEETO',\n    'KERSO',\n    'KIDD KEO',\n    'NIL OJEDA',\n    'SUZYROXX',\n    'VICENS',\n    'CRYSTALMOLLY',\n    'DARIO MELACHE',\n    'DHEYO',\n    'MOUREDEV',\n    'FATZ',\n    'BUBBCODE',\n    'CODETRAIN',\n    'NINJACODE',\n\n];\n\nasync function getOAuthToken() {\n    const response = await axios.post('https://id.twitch.tv/oauth2/token', null, {\n        params: {\n            client_id: CLIENT_ID,\n            client_secret: CLIENT_SECRET,\n            grant_type: 'client_credentials'\n        }\n    });\n    return response.data.access_token;\n}\n\nasync function getUserData(username, token) {\n    try {\n        const response = await axios.get(`https://api.twitch.tv/helix/users?login=${username}`, {\n            headers: {\n                'Client-ID': CLIENT_ID,\n                'Authorization': `Bearer ${token}`\n            }\n        });\n        return response.data.data[0]; // Return the first user data\n    } catch (error) {\n        console.error(`Error fetching data for ${username}:`, error.message);\n        return null; \n    }\n}\n\nasync function getFollowerCount(username, token) {\n    try {\n        // First, get the user ID for the username\n        const userResponse = await axios.get(`https://api.twitch.tv/helix/users?login=${username}`, {\n            headers: {\n                'Client-ID': CLIENT_ID,\n                'Authorization': `Bearer ${token}`\n            }\n        });\n\n        const userId = userResponse.data.data[0].id;\n\n        // Now, get the followers for that user\n        const followsResponse = await axios.get(`https://api.twitch.tv/helix/users/follows?to_id=${userId}`, {\n            headers: {\n                'Client-ID': CLIENT_ID,\n                'Authorization': `Bearer ${token}`\n            }\n        });\n\n        // The number of followers is the total count\n        return followsResponse.data.total; // This gives the total number of followers\n    } catch (error) {\n        console.error(`Error fetching follower count for ${username}:`, error.message);\n        return 'N/A'; // Return 'N/A' if there's an error\n    }\n}\n\n// Main function to fetch and display data\nasync function fetchParticipantsData() {\n    const token = await getOAuthToken();\n    const results = [];\n\n    for (const username of participants) {\n        const userData = await getUserData(username, token);\n        if (userData) {\n            const followerCount = await getFollowerCount(username, token);\n            results.push({\n                username: userData.login,\n                followers: followerCount,\n                createdAt: new Date(userData.created_at),\n            });\n        } else {\n            results.push({\n                username: username,\n                followers: 'N/A',\n                createdAt: 'N/A',\n            });\n        }\n    }\n\n    // Sort by followers\n    const sortedByFollowers = results.sort((a, b) => {\n        return (b.followers === 'N/A' ? -1 : b.followers) - (a.followers === 'N/A' ? -1 : a.followers);\n    });\n\n    // Sort by account creation date\n    const sortedByCreationDate = results.sort((a, b) => {\n        return new Date(b.createdAt) - new Date(a.createdAt);\n    });\n\n    log('Ranking by Followers:');\n    console.table(sortedByFollowers);\n\n    log('Ranking by Account Creation Date:');\n    console.table(sortedByCreationDate);\n}\n\nfetchParticipantsData();\n"
  },
  {
    "path": "Roadmap/40 - FORTNITE RUBIUS CUP/javascript/hectorio23.js",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\n// npm install axios\nconst axios = require('axios');\n\n// Función para obtener datos de un usuario de Twitch.\nasync function getTwitchUserData(username, authToken) {\n    const headers = {\n        'Client-ID': 'YOUR_CLIENT_ID',\n        'Authorization': `Bearer ${authToken}`\n    };\n    \n    try {\n        const response = await axios.get(`https://api.twitch.tv/helix/users?login=${username}`, { headers });\n        if (response.data.data.length > 0) {\n            const user = response.data.data[0];\n            const followers = await getTwitchFollowers(user.id, authToken);\n            return { username, followers, created_at: user.created_at };\n        } else {\n            return { username, followers: null, created_at: null };\n        }\n    } catch (error) {\n        console.error(`Error fetching data for ${username}:`, error);\n    }\n}\n\n// Función para obtener el número de seguidores de un usuario de Twitch.\nasync function getTwitchFollowers(userId, authToken) {\n    const headers = {\n        'Client-ID': 'YOUR_CLIENT_ID',\n        'Authorization': `Bearer ${authToken}`\n    };\n    \n    const response = await axios.get(`https://api.twitch.tv/helix/users/follows?to_id=${userId}`, { headers });\n    return response.data.total;\n}\n\n// Genera el ranking por seguidores y por antigüedad.\nasync function generateRankings(participants, authToken) {\n    const userData = await Promise.all(participants.map(user => getTwitchUserData(user, authToken)));\n    \n    // Ranking por seguidores.\n    const byFollowers = userData.filter(u => u.followers !== null).sort((a, b) => b.followers - a.followers);\n    \n    // Ranking por antigüedad.\n    const byCreationDate = userData.filter(u => u.created_at !== null).sort((a, b) => new Date(a.created_at) - new Date(b.created_at));\n    \n    return { byFollowers, byCreationDate };\n}\n\n// Ejemplo de uso.\n(async () => {\n    const participants = [\"user1\", \"user2\", \"user3\"];\n    const authToken = \"YOUR_AUTH_TOKEN\";\n\n    const { byFollowers, byCreationDate } = await generateRankings(participants, authToken);\n\n    console.log(\"Ranking por seguidores:\");\n    byFollowers.forEach(user => console.log(`${user.username} - ${user.followers} seguidores`));\n\n    console.log(\"\\nRanking por antigüedad:\");\n    byCreationDate.forEach(user => console.log(`${user.username} - Creado el ${user.created_at}`));\n})();\n"
  },
  {
    "path": "Roadmap/40 - FORTNITE RUBIUS CUP/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n_______________________________________________________\n#40 FORTNITE RUBIUS CUP\n-------------------------------------------------------\n* EJERCICIO:\n * ¡Rubius tiene su propia skin en Fortnite!\n * Y va a organizar una competición para celebrarlo.\n * Esta es la lista de participantes:\n * https://x.com/Rubiu5/status/1840161450154692876\n *\n * Desarrolla un programa que obtenga el número de seguidores en\n * Twitch de cada participante, la fecha de creación de la cuenta \n * y ordene los resultados en dos listados.\n * - Usa el API de Twitch: https://dev.twitch.tv/docs/api/reference\n *   (NO subas las credenciales de autenticación)\n * - Crea un ranking por número de seguidores y por antigüedad.\n * - Si algún participante no tiene usuario en Twitch, debe reflejarlo.\n */\n// ________________________________________________________\nconst axios = require('axios');\nconst dotenv = require('dotenv');\nconst { DateTime } = require('luxon');\n\nclass Twitch {\n    constructor(clientId, clientSecret) {\n        this.clientId = clientId;\n        this.clientSecret = clientSecret;\n        this.accessToken = null;\n    }\n\n    async ensureAccessToken() {\n        if (!this.accessToken) {\n            const params = new URLSearchParams({\n                client_id: this.clientId,\n                client_secret: this.clientSecret,\n                grant_type: 'client_credentials'\n            });\n\n            try {\n                const response = await axios.post('https://id.twitch.tv/oauth2/token', params);\n                this.accessToken = response.data.access_token;\n            } catch (error) {\n                throw new Error(`Error obtaining token: ${error.message}`);\n            }\n        }\n    }\n\n    getHeaders() {\n        return {\n            'Client-Id': this.clientId,\n            'Authorization': `Bearer ${this.accessToken}`\n        };\n    }\n\n    async getFollowers(userId) {\n        const url = `https://api.twitch.tv/helix/channels/followers?broadcaster_id=${userId}`;\n        \n        try {\n            const response = await axios.get(url, { headers: this.getHeaders() });\n            return response.data.total || 0;\n        } catch (error) {\n            throw new Error(`Error getting followers: ${error.message}`);\n        }\n    }\n\n    async getUserData(userName) {\n        await this.ensureAccessToken();\n        const url = `https://api.twitch.tv/helix/users?login=${userName}`;\n\n        try {\n            const response = await axios.get(url, { headers: this.getHeaders() });\n            const userData = response.data.data[0];\n\n            if (!userData) {\n                return null;\n            }\n\n            const followers = await this.getFollowers(userData.id);\n\n            return {\n                username: userName,\n                createdAt: DateTime.fromISO(userData.created_at),\n                followers\n            };\n        } catch (error) {\n            throw new Error(`Error getting user data: ${error.message}`);\n        }\n    }\n}\n\nfunction printRankings(usersData) {\n    const byFollowers = [...usersData].sort((a, b) => b.followers - a.followers);\n    const byDate = [...usersData].sort((a, b) => a.createdAt.toMillis() - b.createdAt.toMillis());\n\n    console.log('\\nRanking por número de seguidores:');\n    byFollowers.forEach((user, i) => {\n        console.log(`${i + 1} - ${user.username}: ${user.followers} seguidores`);\n    });\n\n    console.log('\\nRanking por antigüedad:');\n    byDate.forEach((user, i) => {\n        console.log(`${i + 1} - ${user.username}: Creado el ${user.createdAt.toFormat('dd/MM/yyyy')}`);\n    });\n}\n\nasync function processUsers(users, tw) {\n    const usersData = [];\n    const notFoundUsers = [];\n    console.log('Obteniendo datos...');\n\n    for (const name of users) {\n        try {\n            const userData = await tw.getUserData(name);\n            if (userData) {\n                usersData.push(userData);\n            } else {\n                notFoundUsers.push(name);\n            }\n        } catch (error) {\n            notFoundUsers.push(name);\n        }\n    }\n\n    printRankings(usersData);\n\n    if (notFoundUsers.length > 0) {\n        console.log('\\nUsuarios no encontrados:');\n        notFoundUsers.forEach(user => console.log(user));\n    }\n}\n\nasync function main() {\n    dotenv.config();\n    const clientId = process.env.TWITCH_CLIENT_ID;\n    const clientSecret = process.env.TWITCH_CLIENT_SECRET;\n\n    if (!clientId || !clientSecret) {\n        console.error('CLIENT_ID o CLIENT_SECRET no encontrados en .env');\n        process.exit(1);\n    }\n\n    const twitch = new Twitch(clientId, clientSecret);\n    \n    const users = [\n        \"abby\", \"ache\", \"adricontreras\", \"agustin\", \"alexby\", \"ampeter\", \"ander\",\n        \"arigameplays\", \"arigeli\", \"auronplay\", \"axozer\", \"beniju\", \"bycalitos\",\n        \"byviruzz\", \"carrera\", \"celopan\", \"cheeto\", \"crystalmolly\", \"darioemehache\",\n        \"dheyo\", \"djmario\", \"doble\", \"elvisa\", \"elyas360\", \"folagor\", \"grefg\",\n        \"guanyar\", \"hika\", \"hiper\", \"ibai\", \"ibelky\", \"illojuan\", \"imantado\",\n        \"irinaisasia\", \"jesskiu\", \"jopa\", \"jordiwild\", \"kenaisouza\", \"keroro\",\n        \"kiddkeo\", \"kikorivera\", \"knekro\", \"koko\", \"kronnozomber\", \"leviathan\",\n        \"litkillah\", \"lolalolita\", \"lolito\", \"luh\", \"luzu\", \"mangel\", \"mayichi\",\n        \"melo\", \"missasinonia\", \"mixwell\", \"mrjagger\", \"nategentile\", \"nexxuz\",\n        \"nia\", \"nilojeda\", \"nissaxter\", \"ollie\", \"orslok\", \"outconsumer\", \"papigavi\",\n        \"paracetamor\", \"patica\", \"paulagonu\", \"pausenpaii\", \"perxitaa\", \"plex\",\n        \"polispol\", \"quackity\", \"recuerdop\", \"reven\", \"rivers\", \"robertpg\", \"roier\",\n        \"rojuu\", \"rubius\", \"shadoune\", \"silithur\", \"spoksponha\", \"spreen\", \"spursito\",\n        \"staxx\", \"suzyroxx\", \"vicens\", \"vituber\", \"werlyb\", \"xavi\", \"xcry\", \"xokas\",\n        \"zarcort\", \"zeling\", \"zorman\"\n    ];\n\n    try {\n        await processUsers(users, twitch);\n    } catch (error) {\n        console.error('Error:', error.message);\n    }\n}\n\nmain();\n"
  },
  {
    "path": "Roadmap/40 - FORTNITE RUBIUS CUP/javascript/miguelex.js",
    "content": "async function obtenerTokenOAuth(clientId, clientSecret) {\n    const url = 'https://id.twitch.tv/oauth2/token';\n    \n    const data = new URLSearchParams();\n    data.append('client_id', clientId);\n    data.append('client_secret', clientSecret);\n    data.append('grant_type', 'client_credentials');\n\n    const response = await fetch(url, {\n        method: 'POST',\n        headers: {\n            'Content-Type': 'application/x-www-form-urlencoded'\n        },\n        body: data\n    });\n\n    if (!response.ok) {\n        throw new Error('Error al obtener el token OAuth');\n    }\n\n    const result = await response.json();\n    return result.access_token;\n}\n\nasync function obtenerInfoUsuarioTwitch(accessToken, clientId, username) {\n    username = username.replace(/[^a-zA-Z0-9_]/g, '');\n    \n    const url = `https://api.twitch.tv/helix/users?login=${encodeURIComponent(username)}`;\n    \n    const response = await fetch(url, {\n        method: 'GET',\n        headers: {\n            'Authorization': `Bearer ${accessToken}`,\n            'Client-ID': clientId\n        }\n    });\n\n    if (!response.ok) {\n        return null;\n    }\n\n    const result = await response.json();\n    return result.data[0] || null;\n}\n\nasync function obtenerNumeroSeguidoresTwitch(accessToken, clientId, userId) {\n    const url = `https://api.twitch.tv/helix/channels/followers?broadcaster_id=${userId}`;\n\n    const response = await fetch(url, {\n        method: 'GET',\n        headers: {\n            'Authorization': `Bearer ${accessToken}`,\n            'Client-ID': clientId\n        }\n    });\n\n    if (!response.ok) {\n        return 0;\n    }\n\n    const result = await response.json();\n    return result.total || 0;\n}\n\n(async () => {\n    const participantes = [\n        'Abby', 'Ache', 'Adri Contreras', 'Agustin', 'Alexby', 'Ampeter', 'Ander', 'Ari Gameplays',\n        'Arigely', 'Auronplay', 'Axozer', 'Beniju', 'By Calitos', 'Byviruzz', 'Carrera', 'Celopan',\n        'Cheto', 'CrystalMolly', 'Dario Eme Hache', 'Dheyo', 'DjMariio', 'Doble', 'Elvisa', 'Elyas360',\n        'Folagor', 'Grefg', 'Guanyar', 'Hika', 'Hiper', 'Ibai', 'Ibelky', 'Illojuan', 'Imantado',\n        'Irina Isasia', 'JessKiu', 'Jopa', 'JordiWild', 'Kenai Souza', 'Keroro', 'Kidd Keo', 'Kiko Rivera',\n        'Knekro', 'Koko', 'KronnoZomber', 'Leviathan', 'Lit Killah', 'Lola Lolita', 'Lolito', 'Luh',\n        'Luzu', 'Mangel', 'Mayichi', 'Melo', 'MissaSinfonia', 'Mixwell', 'Mr. Jagger', 'Nate Gentile',\n        'Nexxuz', 'Nia', 'Nil Ojeda', 'NissaXter', 'Ollie', 'Orslok', 'Outconsumer', 'Papi Gavi',\n        'Paracetamor', 'Patica', 'Paula Gonu', 'Pausenpaii', 'Perxitaa', 'Plex', 'Polispol', 'Quackity',\n        'RecueroDP', 'Reven', 'Rivers', 'RobertPG', 'Roier', 'Rojuu', 'Rubius', 'Shadoune', 'Silithur',\n        'SpokSponha', 'Spreen', 'Spursito', 'Staxx', 'SuzyRoxx', 'Vicens', 'Vituber', 'Werlyb', 'Xavi',\n        'Xcry', 'Xokas', 'Zarcort', 'Zeling', 'Zorman'\n    ];\n\n    const clientId = 'TU_CLIENT_ID';\n    const clientSecret = 'TU_CLIENT_SECRET';\n\n    try {\n        const accessToken = await obtenerTokenOAuth(clientId, clientSecret);\n\n        const infoUsuarios = [];\n        const errores = [];\n\n        for (const participante of participantes) {\n            const usuario = await obtenerInfoUsuarioTwitch(accessToken, clientId, participante);\n\n            if (usuario) {\n                const seguidores = await obtenerNumeroSeguidoresTwitch(accessToken, clientId, usuario.id);\n\n                infoUsuarios.push({\n                    username: usuario.display_name,\n                    followers: seguidores,\n                    creation_date: usuario.created_at\n                });\n            } else {\n                errores.push(`El participante ${participante} no tiene usuario en Twitch.`);\n            }\n        }\n\n        // Ordenar por número de seguidores\n        const rankingPorSeguidores = [...infoUsuarios].sort((a, b) => b.followers - a.followers);\n\n        console.log(\"Ranking por número de seguidores:\");\n        rankingPorSeguidores.forEach(usuario => {\n            console.log(`${usuario.username} - ${usuario.followers} seguidores`);\n        });\n\n        // Ordenar por antigüedad\n        const rankingPorAntiguedad = [...infoUsuarios].sort((a, b) => new Date(a.creation_date) - new Date(b.creation_date));\n\n        console.log(\"\\nRanking por antigüedad de la cuenta:\");\n        rankingPorAntiguedad.forEach(usuario => {\n            console.log(`${usuario.username} - Cuenta creada el ${new Date(usuario.creation_date).toLocaleDateString()}`);\n        });\n\n        if (errores.length > 0) {\n            console.log(\"\\nErrores:\");\n            errores.forEach(error => console.log(error));\n        }\n\n    } catch (error) {\n        console.error('Error:', error);\n    }\n})();\n"
  },
  {
    "path": "Roadmap/40 - FORTNITE RUBIUS CUP/javascript/pedamoci.js",
    "content": "const rubiusCupParticipants = ['abby_', 'Ache', 'AdriContreras4', 'agustin51', 'Alexby11', 'Ampeterby7', 'tvandeR', 'AriGameplays', 'Arigeli_', 'auronplay', 'aXoZer', 'BENIJU03', 'bycalitos', 'byViruZz', 'Carreraaa', 'Celopan', 'srcheeto', 'CrystalMolly', 'darioemehache', 'Dheylo', 'DjMaRiiO', 'Doble', 'ElvisaYomastercard', 'elyas360', 'FolagorLives', 'TheGrefg', 'GUANYAR', 'Hika', 'Hiperop', 'ibai', 'ibelky_', 'IlloJuan', 'imantado', 'Irina Isaia', 'Jesskiu', 'JOPA', 'JordiWild', 'kenaivsouza', 'MrKeroro10', 'TheKiddKeo95', 'KikoRivera', 'knekro', 'koko', 'KronnoZomberOficial', 'Leviathan', 'LITkillah', 'lolalolita', 'LOLITOFDEZ', 'Luh', 'Luzu', 'Mangel', 'Mayichi', 'melo', 'MissaSinfonia', 'Mixwell', 'JaggerPrincesa', 'NateGentile7', 'Nexxuz', 'LakshartNia', 'nilojeda', 'Nissaxter', 'OllieGamerz', 'orslok', 'Outconsumer', 'PapiGaviTV', 'paracetamor', 'patica1999', 'paulagonu', 'PauSenpaii', 'Perxitaa', 'NoSoyPlex',  'polispol1', 'Quackity', 'Recuerd0p', 'REVENANT', 'rivers_gg', 'robertpg', 'Roier', 'Rojuu', 'Rubius', 'Shadoune666', 'Silithur', 'spok_sponha', 'ElSpreen', 'Spursito', 'bysTaXx', 'Suzyroxx', 'Vicens', 'vituber', 'Werlyb', 'Xavi', 'xCry', 'elxokas', 'zZarcort', 'Zeling', 'ZormanWorld']\n\nconst colors = {\n  red: \"\\x1b[31m\",\n  green: \"\\x1b[32m\",\n  yellow: \"\\x1b[33m\",\n  cyan: \"\\x1b[34m\",\n  reset: \"\\x1b[0m\",\n}\n\nclass Renderer {\n  static error(message) {\n    console.log(colors.red + \"Error: \" + message + colors.reset)\n  }\n\n  static success(message) {\n    console.log(colors.green + \"Success: \" + message + colors.reset)\n  }\n\n  static table(info, columns) {\n    console.table(info, columns)\n  }\n}\n\nclass APITwitch {\n  constructor() {\n    this.client_id = \"undefined\"\n    this.client_secret = \"undefined\"\n    this.access_token = \"undefined\"\n  }\n\n  async  getToken() {\n    const res = await fetch(\"https://id.twitch.tv/oauth2/token\", {\n      method: \"POST\",\n      body: new URLSearchParams({\n        client_id: this.client_id,\n        client_secret: this.client_secret,\n        grant_type: \"client_credentials\"\n      })\n    })\n  \n    const data = await res.json();\n\n    this.access_token = data.access_token \n  }\n\n  async fetchWebApi(endpoint, method) {\n    const res = await fetch(`https://api.twitch.tv/helix/${endpoint}`, {\n      method,\n      headers: {\n        \"Client-ID\": this.client_id,\n        \"Authorization\": `Bearer ${this.access_token}`\n      }\n    })\n\n    return await res.json();\n  }\n\n  async searchStreamer(name) {\n    const res = await this.fetchWebApi(\n      `users?login=${encodeURIComponent(name)}`, \n      \"GET\"\n    )\n\n    return res.data\n  }\n\n  async searchFollowers(streamerID) {\n    const res = await this.fetchWebApi(\n      `channels/followers?broadcaster_id=${streamerID}`, \n      \"GET\"\n    )\n\n    return res.total\n  }\n}\n\nclass Order {\n  constructor() {\n    this.participantsOrderByFollowers = []\n    this.participantsOrderBySeniority = []\n  }\n\n  byFollowers(participants) {\n    let nonTwitch = participants.filter(participant => !participant.followers)\n\n    this.participantsOrderByFollowers = participants.filter(participant => !!participant.followers)\n\n    this.participantsOrderByFollowers.sort((a, b) => {\n      return b.followers - a.followers\n    })\n\n    for (let i = 0; i < nonTwitch.length; i++) {\n      nonTwitch[i].followers = \"doesn't have a Twitch channel\"\n    }\n\n    this.participantsOrderByFollowers = this.participantsOrderByFollowers.concat(nonTwitch)\n\n    return this.participantsOrderByFollowers\n  }\n\n  bySeniority(participants) {\n    let nonTwitch = participants.filter(participant => !participant.created_at)\n\n    this.participantsOrderBySeniority = participants.filter(participant => !!participant.created_at)\n\n    this.participantsOrderBySeniority.sort((a, b) => {\n      const dateA = a.created_at.split('-')\n      const yearA = parseInt(dateA[0])\n      const monthA = parseInt(dateA[1])\n      const dayA = parseInt(dateA[2])\n\n      const dateB = b.created_at.split('-')\n      const yearB = parseInt(dateB[0])\n      const monthB = parseInt(dateB[1])\n      const dayB = parseInt(dateB[2])\n\n      return (yearA - yearB) ||\n            (monthA - monthB) ||\n            (dayA - dayB)\n    })\n\n    for (let i = 0; i < nonTwitch.length; i++) {\n      nonTwitch[i].created_at = \"doesn't have a Twitch channel\"\n    }\n\n    this.participantsOrderBySeniority = this.participantsOrderBySeniority.concat(nonTwitch)\n\n    return this.participantsOrderBySeniority\n  }\n}\n\nclass Controller {\n  constructor(apiTwitch, order) {\n    this.apiTwitch = apiTwitch\n    this.order = order\n    this.participants = []\n  }\n\n  async start(participants) {\n    for (let i = 0; i < participants.length; i++) {\n      const participantData = await this.apiTwitch.searchStreamer(participants[i])\n\n      if (!participantData || participantData[0] === undefined) {\n        this.participants.push({name: participants[i]})\n      } else {\n        const participantID = participantData[0].id\n        const participantDate = participantData[0].created_at.split('T')[0]\n\n        const followers = await this.apiTwitch.searchFollowers(participantID)\n\n        this.participants.push({id: participantID, name: participants[i], created_at: participantDate, followers: followers})\n      }\n\n      Renderer.success(`The information from streamer no. ${i} was collected correctly`)\n    }\n\n    const participantsOrderByFollowers = this.order.byFollowers(this.participants)\n    Renderer.table(participantsOrderByFollowers, ['name', 'followers'])\n\n    const participantsOrderBySeniority = this.order.bySeniority(this.participants)\n    Renderer.table(participantsOrderBySeniority, ['name', 'created_at'])\n  }\n}\n\nconst controller = new Controller(new APITwitch(), new Order())\ncontroller.start(rubiusCupParticipants)"
  },
  {
    "path": "Roadmap/40 - FORTNITE RUBIUS CUP/javascript/raulG91.js",
    "content": "const https = require('node:https')\n\nconst CLIENT_ID = \"Your Client ID \"\nconst CLIENT_SECRET = \"Your client secret\"\n\n\nasync function getToken() {\n    return new Promise(async function (resolve, reject) {\n\n        const options = {\n            hostname: 'id.twitch.tv',\n            path: \"/oauth2/token\",\n            method: \"POST\",\n            headers: {\n                'Content-type': \"application/x-www-form-urlencoded\"\n\n            }\n        };\n        let body = {\n            'grant_type': 'client_credentials',\n            'client_secret': CLIENT_SECRET,\n            'client_id': CLIENT_ID\n        }\n\n        // Encode body\n        let form_body = []\n        for (let element in body) {\n\n            let encoded_prop = encodeURIComponent(element);\n            let encoded_value = encodeURIComponent(body[element])\n            form_body.push(encoded_prop + \"=\" + encoded_value);\n\n        }\n        form_body = form_body.join(\"&\")\n\n        let response_body = \"\";\n        const req = https.request(options,res => {\n\n            res.on('data', d => {\n                response_body += d;\n            });\n            res.on('end', ()=>{\n                let token = JSON.parse(response_body).access_token;\n                resolve(token)\n            });\n            res.on('error',(e)=>{\n                reject(e);\n            })\n        });\n\n        req.on('error',(e) => {\n            reject(e);\n        });\n        //Execute post request\n        req.write(form_body);\n        //End request\n        req.end()\n    })\n}\nasync function getFollowers(token,id){\n\n    return new Promise(function(resolve,reject){\n\n        let query =`?broadcaster_id=${id}`;\n        const header = {\n            'Authorization': \"Bearer \"+ token,\n            'Client-Id': CLIENT_ID\n        };\n        const options = {\n            'hostname': 'api.twitch.tv',\n            'path': `/helix/channels/followers${query}`,\n            \"method\": \"GET\",\n            \"headers\": header\n        };\n        let incoming_message = \"\";\n        const req = https.get(options,(res)=>{\n            if(res.statusCode == 200){\n                res.on('data',(data)=>{\n                    incoming_message += data\n                })\n                res.on(\"error\",(error)=>{\n                    reject(error.message)\n                });\n                res.on(\"end\",()=>{\n                    let user = JSON.parse(incoming_message)\n                    resolve(user.total)\n                })\n            }\n            else{\n                reject(\"Error obteniendo seguidores\")\n            }\n        })\n\n\n    })\n}\nasync function basicInfo(token,user){\n\n    return new Promise(function(resolve,reject){\n\n        let user_name = user.replace(\" \",\"\");\n        let query = `?login=${user_name}`\n        const header = {\n            'Authorization': \"Bearer \"+ token,\n            'Client-Id': CLIENT_ID\n        };\n        const options = {\n            'hostname': 'api.twitch.tv',\n            'path': `/helix/users${query}`,\n            \"method\": \"GET\",\n            \"headers\": header\n        };\n        let incoming_message = \"\";\n        const req = https.get(options,(res)=>{\n\n            if(res.statusCode == 200){\n\n                res.on(\"data\",(data)=>{\n                    incoming_message+= data\n                })\n                res.on(\"error\",(error)=>{\n                    reject(error.message)\n                })\n                res.on(\"end\",()=>{\n                    let user = JSON.parse(incoming_message)\n                    if(user.data[0]){\n                        let create_at = user.data[0].created_at;\n                        let id = user.data[0].id\n                        resolve([id,create_at])\n\n                    }\n                    else{\n                        reject()\n                    }\n\n         \n                })\n            }\n            else{\n                reject(`Error obteniendo usuario para ${user}`)\n            }\n\n        })\n\n    })\n\n\n}\nasync function getInfo(users){\n    try{\n        token = await getToken();\n\n        let user_list = [];\n\n        for(let user in users){\n            try{\n\n                let list = await basicInfo(token,users[user])\n                let followers = await getFollowers(token,list[0])\n    \n                user_list.push( {\n    \n                    \"username\": users[user],\n                    \"created_at\": list[1],\n                    \"followers\": followers\n                });\n            }\n            catch{\n                console.log(`Error obteniendo datos para ${users[user]}`)\n            }\n\n\n        }\n        return user_list\n    }\n    catch(Error){\n\n        console.log(\"Error obteniendo token\")\n\n        }\n}\n\nfunction orderByFollowers(list){\n\n    let new_list = list.sort((a,b)=>a.followers > b.followers?-1:1);\n\n    return new_list; \n}\n\nfunction orderByCreationDate(list){\n    let new_list = list.sort((a,b)=>a.created_at < b.created_at?-1:1);\n\n    return new_list; \n\n}\n\nasync function main(){\n    let users = [\n        'Abby', 'Ache', 'Adri Contreras', 'Agustin', 'Alexby', 'Ampeter', 'Ander', 'Ari Gameplays',\n        'Arigely', 'Auronplay', 'Axozer', 'Beniju', 'By Calitos', 'Byviruzz', 'Carrera', 'Celopan',\n        'Cheto', 'CrystalMolly', 'Dario Eme Hache', 'Dheyo', 'DjMariio', 'Doble', 'Elvisa', 'Elyas360',\n        'Folagor', 'Grefg', 'Guanyar', 'Hika', 'Hiper', 'Ibai', 'Ibelky', 'Illojuan', 'Imantado',\n        'Irina Isasia', 'JessKiu', 'Jopa', 'JordiWild', 'Kenai Souza', 'Keroro', 'Kidd Keo', 'Kiko Rivera',\n        'Knekro', 'Koko', 'KronnoZomber', 'Leviathan', 'Lit Killah', 'Lola Lolita', 'Lolito', 'Luh',\n        'Luzu', 'Mangel', 'Mayichi', 'Melo', 'MissaSinfonia', 'Mixwell', 'Mr. Jagger', 'Nate Gentile',\n        'Nexxuz', 'Nia', 'Nil Ojeda', 'NissaXter', 'Ollie', 'Orslok', 'Outconsumer', 'Papi Gavi',\n        'Paracetamor', 'Patica', 'Paula Gonu', 'Pausenpaii', 'Perxitaa', 'Plex', 'Polispol', 'Quackity',\n        'RecueroDP', 'Reven', 'Rivers', 'RobertPG', 'Roier', 'Rojuu', 'Rubius', 'Shadoune', 'Silithur',\n        'SpokSponha', 'Spreen', 'Spursito', 'Staxx', 'SuzyRoxx', 'Vicens', 'Vituber', 'Werlyb', 'Xavi',\n        'Xcry', 'Xokas', 'Zarcort', 'Zeling', 'Zorman'\n    ]\n    let user_list = await getInfo(users)\n    let odered_list_followers = orderByFollowers(user_list);\n\n    for(let i=0; i< odered_list_followers.length; i++){\n\n        console.log(`User: ${odered_list_followers[i].username}, followers: ${odered_list_followers[i].followers},`)\n    }\n    let odered_list_date = orderByCreationDate(user_list);\n\n    for(let i=0; i< odered_list_date.length; i++){\n\n        console.log(`User: ${odered_list_date[i].username}, fecha de creacion: ${odered_list_date[i].created_at},`)\n    }\n\n\n}\n\nmain()\n\n\n\n"
  },
  {
    "path": "Roadmap/40 - FORTNITE RUBIUS CUP/kotlin/blackriper.kt",
    "content": "import io.ktor.client.HttpClient\r\nimport io.ktor.client.call.body\r\nimport io.ktor.client.engine.cio.CIO\r\nimport io.ktor.client.plugins.contentnegotiation.ContentNegotiation\r\nimport io.ktor.client.request.forms.FormDataContent\r\nimport io.ktor.client.request.get\r\nimport io.ktor.client.request.headers\r\nimport io.ktor.client.request.post\r\nimport io.ktor.client.request.setBody\r\nimport io.ktor.client.statement.bodyAsText\r\nimport io.ktor.http.HttpHeaders\r\nimport io.ktor.http.parameters\r\nimport io.ktor.serialization.kotlinx.json.json\r\nimport kotlinx.coroutines.Dispatchers\r\nimport kotlinx.coroutines.async\r\nimport kotlinx.coroutines.coroutineScope\r\nimport kotlinx.coroutines.flow.Flow\r\nimport kotlinx.coroutines.flow.asFlow\r\nimport kotlinx.coroutines.flow.toList\r\nimport kotlinx.coroutines.runBlocking\r\nimport kotlinx.serialization.SerialName\r\nimport kotlinx.serialization.Serializable\r\nimport kotlinx.serialization.json.Json\r\nimport java.time.Instant\r\nimport java.time.LocalDateTime\r\nimport java.time.ZoneId\r\nimport java.time.format.DateTimeFormatter\r\n\r\n\r\n//1.- traer lista de usuarios\r\nval participans= listOf(\r\n    \"Abby\",\"Ache\",\"Adricontreras\",\r\n    \"Agustin\",\"Alexby\",\"Ampeter\",\r\n    \"Ander\",\"AriGameplays\",\"AriGeli\",\r\n    \"Auronplay\",\"Axozer\",\"Beniju\",\r\n    \"ByCalitos\",\"Byviruzz\",\"Carrera\",\r\n    \"Celopan\",\"Cheeto\",\"CrystalMolly\",\r\n    \"DarioEmehache\",\"Dheylo\",\"DjMariio\",\r\n    \"Doble\",\"Elvisa\",\"Elyas360\",\"Folagor\",\r\n    \"Grefg\",\"Guanyar\",\"Hika\",\"Hiper\",\r\n    \"Ibai\",\"Ibelky\",\"illojuan\",\"Imantado\",\r\n    \"IrinaIsasia\",\"Jesskiu\",\"Jopa\",\"JordiWild\",\r\n    \"KenaiSouza\",\"Keroro\",\"KiddKeo\",\"KikoRivera\",\r\n    \"Knekro\",\"Koko\",\"KronnoZomber\",\"Leviathan\",\"LitKillan\",\r\n    \"Lolalolita\",\"Lolito\",\"Luh\",\"Luzu\",\"Mangel\",\"Mayichi\",\r\n    \"Melo\",\"MissaSinfonia\",\"MixWell\",\"MrJagger\",\"NateGentile7\",\r\n    \"Nexxuz\",\"Nia\",\"NilOjeda\",\"Nissaxter\",\"Ollie\",\"Orslok\",\"Outconsumer\",\r\n    \"PapiGavi\",\"Paracetamor\",\"Patica\",\"PaulaGonu\",\"Pausenpall\",\"Perxitaa\",\r\n    \"Plex\",\"PolisPol\",\"Quackitty\",\"Recuerdop\",\"Reven\",\"Rivers\",\"Roberttpg\",\"Roier\",\r\n    \"Rojuu\",\"Rubius\",\"Shadoune\",\"Silithur\",\"Spoksponha\",\"Spreen\",\"Spursito\",\"Staxx\",\r\n    \"Suzyroxx\",\"Vicens\",\"Vituber\",\"Werlyb\",\"Xavi\",\"Xcry\",\"Xokas\",\"Zarcort\",\"Zeling\",\"Zorman\")\r\n\r\n//2.- Configurar cliente Http Ktor\r\n//https://ktor.io/docs/client-create-new-application.html\r\n\r\nval ktorClient= HttpClient(CIO){\r\n    install(ContentNegotiation){\r\n        json(Json{\r\n            prettyPrint=true\r\n            ignoreUnknownKeys=true\r\n        })\r\n    }\r\n}\r\n\r\n//3.-Data clases para response , request\r\nconst val CLIENTID=\"<YOUR CLIENT ID>\"\r\nconst val SECRET=\"<YOUR SECRET>\"\r\n\r\n@Serializable\r\ndata class Token(\r\n    @SerialName(\"access_token\")\r\n    val token: String\r\n)\r\n\r\n\r\n@Serializable\r\ndata class Data(val data: List<TwitchUserDto>)\r\n\r\n@Serializable\r\ndata class TwitchUserDto(\r\n    val id: String,\r\n    @SerialName(\"display_name\")\r\n    val userName: String,\r\n    @SerialName(\"created_at\")\r\n    val createdAt: String\r\n)\r\n\r\n@Serializable\r\ndata class Followers(val total: Long)\r\n\r\n\r\ndata class TwitchUser(\r\n    val userName: String,\r\n    val createdAt: LocalDateTime,\r\n    val followers: Long\r\n)\r\n\r\n//extension para convertir el usuario\r\nfun TwitchUserDto.toTwicthUser(total: Long):TwitchUser{\r\n    val created= Instant.parse(createdAt).let {\r\n       it.atZone(ZoneId.systemDefault()).toLocalDateTime()\r\n    }\r\n    return TwitchUser(\r\n        userName = userName,\r\n        createdAt=created,\r\n        followers = total\r\n    )\r\n}\r\n\r\n//4.- clase para consumir la Api y clase para retornar rakings\r\nclass ParticipansApi{\r\n   lateinit var  token: String\r\n\r\n   suspend fun getJwtToken(){\r\n       val response=ktorClient.post(\"https://id.twitch.tv/oauth2/token\"){\r\n           headers {\r\n              append(HttpHeaders.ContentType,\"application/x-www-form-urlencoded\")\r\n           }\r\n           setBody(FormDataContent(parameters {\r\n               append(\"client_id\",CLIENTID)\r\n               append(\"client_secret\",SECRET)\r\n               append(\"grant_type\",\"client_credentials\")\r\n           }))\r\n       }\r\n       if (response.status.value!=200) throw Exception(\"error conecting twitch ${response.bodyAsText()}\")\r\n\r\n       token=response.body<Token>().token\r\n   }\r\n\r\n  suspend fun getTwitchUser(userName:String):TwitchUserDto?{\r\n      val response=ktorClient.get(\"https://api.twitch.tv/helix/users?login=$userName\"){\r\n          headers {\r\n              append(HttpHeaders.Authorization,\"Bearer $token\")\r\n              append(\"Client-Id\",CLIENTID)\r\n          }\r\n      }\r\n      if (response.status.value!=200) return null\r\n      return if (response.body<Data>().data.isEmpty()) null else response.body<Data>().data.first()\r\n  }\r\n\r\n  suspend fun getNumberFollwers(userId: String): Long {\r\n      val response = ktorClient.get(\"https://api.twitch.tv/helix/channels/followers?broadcaster_id=$userId\") {\r\n          headers {\r\n              append(HttpHeaders.Authorization, \"Bearer $token\")\r\n              append(\"Client-Id\", CLIENTID)\r\n          }\r\n      }\r\n      if (response.status.value != 200) return 0\r\n      return response.body<Followers>().total\r\n  }\r\n\r\n}\r\n\r\nclass Ranking(private val api:ParticipansApi){\r\n\r\n  suspend fun getListTwitchUsers(): Flow<TwitchUser> = coroutineScope {\r\n     return@coroutineScope async(Dispatchers.IO){\r\n          val users= mutableListOf<TwitchUser>()\r\n          for (par in participans){\r\n              val user=api.getTwitchUser(par)\r\n              if (user==null) users.add(TwitchUser(par, LocalDateTime.now(),0))\r\n              if (user!=null){\r\n                  val followers=api.getNumberFollwers(user.id)\r\n                  users.add(user.toTwicthUser(followers))\r\n              }\r\n\r\n          }\r\n         users.asFlow()\r\n      }.await()\r\n  }\r\n\r\n  suspend fun rankOfFollowers(usersTwitch: List<TwitchUser>){\r\n     usersTwitch.sortedByDescending{ it.followers }.run {\r\n         println(\"Ranking for followers\")\r\n         this.forEach {\r\n             if (it.followers==0L) println(\"The user ${it.userName} does not have a twitch account\")\r\n             else println(\"${it.userName}  followers: ${it.followers}\")\r\n         }\r\n     }\r\n\r\n  }\r\n\r\n    suspend fun rankOfCreatedAt(usersTwitch: List<TwitchUser>){\r\n        usersTwitch.sortedBy{ it.createdAt }.run {\r\n            println(\"Ranking for Created At\")\r\n            this.forEach {\r\n                if (it.followers==0L) println(\"The user ${it.userName} does not have a twitch account\")\r\n                else println(\"${it.userName}  createdAr: ${it.createdAt.format(DateTimeFormatter.ofPattern(\"dd/MM/yyyy\"))}\")\r\n            }\r\n        }\r\n\r\n    }\r\n\r\n}\r\n\r\n\r\nfun main(): Unit= runBlocking {\r\n    val api = ParticipansApi()\r\n    api.getJwtToken()\r\n    val rank=Ranking(api)\r\n    val usersTwitch=rank.getListTwitchUsers().toList()\r\n    rank.rankOfFollowers(usersTwitch)\r\n    rank.rankOfCreatedAt(usersTwitch)\r\n\r\n}\r\n"
  },
  {
    "path": "Roadmap/40 - FORTNITE RUBIUS CUP/php/miguelex.php",
    "content": "<?php\nfunction obtenerTokenOAuth($clientId, $clientSecret) {\n    $url = 'https://id.twitch.tv/oauth2/token';\n    \n    $data = [\n        'client_id' => $clientId,\n        'client_secret' => $clientSecret,\n        'grant_type' => 'client_credentials'\n    ];\n\n    $options = [\n        'http' => [\n            'header'  => \"Content-type: application/x-www-form-urlencoded\\r\\n\",\n            'method'  => 'POST',\n            'content' => http_build_query($data)\n        ]\n    ];\n\n    $context  = stream_context_create($options);\n    $result = file_get_contents($url, false, $context);\n    \n    if ($result === FALSE) {\n        die('Error al obtener el token OAuth');\n    }\n\n    $response = json_decode($result, true);\n    return $response['access_token'];\n}\n\nfunction obtenerInfoUsuarioTwitch($accessToken, $clientId, $username) {\n    $username = preg_replace('/[^a-zA-Z0-9_]/', '', $username);\n    \n    $url = \"https://api.twitch.tv/helix/users?login=\" . urlencode($username);\n\n    $options = [\n        'http' => [\n            'header' => [\n                \"Authorization: Bearer $accessToken\",\n                \"Client-ID: $clientId\"\n            ]\n        ]\n    ];\n\n    $context = stream_context_create($options);\n    $result = @file_get_contents($url, false, $context);\n    \n    if ($result === FALSE) {\n        return null;\n    }\n\n    $response = json_decode($result, true);\n    return $response['data'][0] ?? null;\n}\n\nfunction obtenerNumeroSeguidoresTwitch($accessToken, $clientId, $userId) {\n    \n    $url = \"https://api.twitch.tv/helix/channels/followers?broadcaster_id=\" . $userId;\n\n    $options = [\n        'http' => [\n            'header' => [\n                \"Authorization: Bearer $accessToken\",\n                \"Client-ID: $clientId\"\n            ]\n        ]\n    ];\n\n    $context = stream_context_create($options);\n    $result = @file_get_contents($url, false, $context);\n    \n    if ($result === FALSE) {\n        return 0; \n    }\n\n    $response = json_decode($result, true);\n    return $response['total'] ?? 0; \n}\n\n$participantes = [\n    'Abby', 'Ache', 'Adri Contreras', 'Agustin', 'Alexby', 'Ampeter', 'Ander', 'Ari Gameplays', 'Arigely', 'Auronplay',\n    'Axozer', 'Beniju', 'By Calitos', 'Byviruzz', 'Carrera', 'Celopan', 'Cheto', 'CrystalMolly', 'Dario Eme Hache', 'Dheyo',\n    'DjMariio', 'Doble', 'Elvisa', 'Elyas360', 'Folagor', 'Grefg', 'Guanyar', 'Hika', 'Hiper', 'Ibai', 'Ibelky',\n    'Illojuan', 'Imantado', 'Irina Isasia', 'JessKiu', 'Jopa', 'JordiWild', 'Kenai Souza', 'Keroro', 'Kidd Keo', 'Kiko Rivera',\n    'Knekro', 'Koko', 'KronnoZomber', 'Leviathan', 'Lit Killah', 'Lola Lolita', 'Lolito', 'Luh', 'Luzu', 'Mangel',\n    'Mayichi', 'Melo', 'MissaSinfonia', 'Mixwell', 'Mr. Jagger', 'Nate Gentile', 'Nexxuz', 'Nia', 'Nil Ojeda', 'NissaXter',\n    'Ollie', 'Orslok', 'Outconsumer', 'Papi Gavi', 'Paracetamor', 'Patica', 'Paula Gonu', 'Pausenpaii', 'Perxitaa', 'Plex',\n    'Polispol', 'Quackity', 'RecueroDP', 'Reven', 'Rivers', 'RobertPG', 'Roier', 'Rojuu', 'Rubius', 'Shadoune',\n    'Silithur', 'SpokSponha', 'Spreen', 'Spursito', 'Staxx', 'SuzyRoxx', 'Vicens', 'Vituber', 'Werlyb', 'Xavi',\n    'Xcry', 'Xokas', 'Zarcort', 'Zeling', 'Zorman'\n];\n\n$clientId = 'TU_CLIENT_ID';\n$clientSecret = 'TU_CLIENT_SECRET';\n\n$accessToken = obtenerTokenOAuth($clientId, $clientSecret);\n\n$infoUsuarios = [];\n$errores = [];\n\nforeach ($participantes as $participante) {\n    $usuario = obtenerInfoUsuarioTwitch($accessToken, $clientId, $participante);\n\n    if ($usuario) {\n        $seguidores = obtenerNumeroSeguidoresTwitch($accessToken, $clientId, $usuario['id']);\n        \n        $infoUsuarios[] = [\n            'username' => $usuario['display_name'],\n            'followers' => $seguidores, \n            'creation_date' => $usuario['created_at']\n        ];\n    } else {\n        $errores[] = \"El participante $participante no tiene usuario en Twitch.\";\n    }\n}\n\n$rankingPorSeguidores = $infoUsuarios;\nusort($rankingPorSeguidores, function($a, $b) {\n    return $b['followers'] <=> $a['followers'];\n});\n\n$rankingPorAntiguedad = $infoUsuarios;\nusort($rankingPorAntiguedad, function($a, $b) {\n    return strtotime($a['creation_date']) <=> strtotime($b['creation_date']);\n});\n\necho \"Ranking por número de seguidores:\\n\";\nforeach ($rankingPorSeguidores as $usuario) {\n    echo $usuario['username'] . \" - \" . $usuario['followers'] . \" seguidores\\n\";\n}\n\necho \"\\nRanking por antigüedad de la cuenta:\\n\";\nforeach ($rankingPorAntiguedad as $usuario) {\n    echo $usuario['username'] . \" - Cuenta creada el \" . date('d-m-Y', strtotime($usuario['creation_date'])) . \"\\n\";\n}\n\nif (!empty($errores)) {\n    echo \"\\nErrores:\\n\";\n    foreach ($errores as $error) {\n        echo $error . \"\\n\";\n    }\n}"
  },
  {
    "path": "Roadmap/40 - FORTNITE RUBIUS CUP/python/CesarCarmona30.py",
    "content": "import requests\n\ndef get_access_token(client_id, client_secret):\n  url = \"https://id.twitch.tv/oauth2/token\"\n  params = {\n    \"client_id\": client_id,\n    \"client_secret\": client_secret,\n    \"grant_type\": \"client_credentials\"\n  }\n  response = requests.post(url, params=params)\n  response.raise_for_status()\n  return response.json().get(\"access_token\")\n\ndef get_user_info(token, client_id, login):\n  url = \"https://api.twitch.tv/helix/users\"\n  headers ={\n    \"Authorization\": f\"Bearer {token}\",\n    \"Client-Id\": client_id\n  }\n  params = {\"login\": login}\n  response = requests.get(url, headers=headers, params=params)\n  response.raise_for_status()\n  data = response.json().get(\"data\", None)\n\n  if not data:\n    return None\n  \n  return data[0]\n\ndef get_total_followers(token, client_id, id):\n  url = \"https://api.twitch.tv/helix/channels/followers\"\n  headers = {\n    \"Authorization\": f\"Bearer {token}\",\n    \"Client-Id\": client_id\n  }\n  params = {\"broadcaster_id\": id}\n  response = requests.get(url, headers=headers, params=params)\n  response.raise_for_status()\n  return response.json().get(\"total\", 0)\n\nCLIENT_ID = \"client_id\"\nCLIENT_SECRET = \"client_secret\"\n\nusers = [\n  \"littleragergirl\", \"ache\", \"adricontreras4\", \"agustin51\", \"alexby11\", \"ampeterby7\", \"tvander\",\n  \"arigameplays\", \"arigeli_\", \"auronplay\", \"axozer\", \"beniju03\", \"bycalitos\",\n  \"byviruzz\", \"carreraaa\", \"celopan\", \"srcheeto\", \"crystalmolly\", \"darioemehache\",\n  \"dheylo\", \"djmariio\", \"doble\", \"elvisayomastercard\", \"elyas360\", \"folagorlives\", \"thegrefg\",\n  \"guanyar\", \"hika\", \"hiperop\", \"ibai\", \"ibelky_\", \"illojuan\", \"imantado\",\n  \"irinaissaia\", \"jesskiu\", \"jopa\", \"jordiwild\", \"kenaivsouza\", \"mrkeroro10\",\n  \"thekiddkeo95\", \"kikorivera\", \"knekro\", \"kokoop\", \"kronnozomberoficial\", \"leviathan\",\n  \"litkillah\", \"lolalolita\", \"lolitofdez\", \"luh\", \"luzu\", \"mangel\", \"mayichi\",\n  \"melo\", \"missasinfonia\", \"mixwell\", \"jaggerprincesa\", \"nategentile7\", \"nexxuz\",\n  \"lakshartnia\", \"nilojeda\", \"nissaxter\", \"olliegamerz\", \"orslok\", \"outconsumer\", \"papigavitv\",\n  \"paracetamor\", \"patica1999\", \"paulagonu\", \"pausenpaii\", \"perxitaa\", \"nosoyplex\",\n  \"polispol1\", \"quackity\", \"recuerd0p\", \"reventxz\", \"rivers_gg\", \"robertpg\", \"roier\",\n  \"ceuvebrokenheart\", \"rubius\", \"shadoune666\", \"silithur\", \"spok_sponha\", \"elspreen\", \"spursito\",\n  \"bystaxx\", \"suzyroxx\", \"vicens\", \"vitu\", \"werlyb\", \"xavi\", \"xcry\", \"elxokas\",\n  \"thezarcort\", \"zeling\", \"zormanworld\", \"mouredev\"\n]\nusers_data = []\nnot_found_users = []\n\ntoken = get_access_token(CLIENT_ID, CLIENT_SECRET)\n\nfor username in users:\n\n  user = get_user_info(token, CLIENT_ID, username)\n\n  if user is None:\n    not_found_users.append(username)\n  else:\n    followers = get_total_followers(token, CLIENT_ID, user[\"id\"])\n    users_data.append({\n      \"username\": username,\n      \"created_at\": user[\"created_at\"],\n      \"followers\": followers\n        })\n\nsort_by_followers = sorted(\n  users_data, key=lambda x: x[\"followers\"], reverse=True)\n\nsort_by_date = sorted(\n  users_data, key=lambda x: x[\"created_at\"])\n\nprint(\"\\nRanking por número de seguidores:\")\nfor id, user, in enumerate(sort_by_followers):\n  print(f\"{id + 1} - {user[\"username\"]}: {user[\"followers\"]} seguidores\")\n\nprint(\"\\nRanking por antigüedad:\")\nfor id, user, in enumerate(sort_by_date):\n  print(f\"{id + 1} - {user[\"username\"]}: Creado el {user[\"created_at\"]}\")\n\nif not_found_users:\n  print(\"\\nUsuarios no encontrados:\")\n  for user in not_found_users:\n    print(user)"
  },
  {
    "path": "Roadmap/40 - FORTNITE RUBIUS CUP/python/EmmanuelMMontesinos.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * ¡Rubius tiene su propia skin en Fortnite!\n * Y va a organizar una competición para celebrarlo.\n * Esta es la lista de participantes:\n * https://x.com/Rubiu5/status/1840161450154692876\n *\n * Desarrolla un programa que obtenga el número de seguidores en\n * Twitch de cada participante, la fecha de creación de la cuenta \n * y ordene los resultados en dos listados.\n * - Usa el API de Twitch: https://dev.twitch.tv/docs/api/reference\n *   (NO subas las credenciales de autenticación)\n * - Crea un ranking por número de seguidores y por antigüedad.\n * - Si algún participante no tiene usuario en Twitch, debe reflejarlo.\n */\n\"\"\"\nimport requests\nimport datetime\nimport os\n\n# NO subas las credenciales de autenticación\nos.environ[\"TWITCH_CLIENT_ID\"] = \"tu-id-de-twitch\"\nos.environ[\"TWITCH_CLIENT_SECRET\"] = \"tu-key-secret-de-twitch\"\n\n\nid = os.environ.get(\"TWITCH_CLIENT_ID\")\nsecret = os.environ.get(\"TWITCH_CLIENT_SECRET\")\n\n# Clase para el token de acceso\nclass Token:\n    def __init__(self,id,secret) -> None:\n        self.id = id\n        self.secret = secret\n        self.token = self.generate_token()\n    def generate_token(self):\n        url = \"https://id.twitch.tv/oauth2/token\"\n        params = {\n            \"client_id\": self.id,\n            \"client_secret\": self.secret,\n            \"grant_type\": \"client_credentials\"\n        }\n\n        response = requests.post(url,params=params)\n\n        if response.status_code == 200:\n            return response.json()[\"access_token\"]\n        \n        else:\n            response = response.json()\n            print(f\"Error: {response['status']}\\n{response['message']}\")\n            return None\n\n\nclass Participante:\n    lista_participantes = []\n    mas_antiguo = []\n    mas_seguido = []\n    token = Token(id,secret)\n    def __init__(self,nombre) -> None:\n        self.nombre = nombre\n        self.fecha_registro = None\n        self.seguidores = 0\n        self.tiempo_total = 0\n        self.id = None\n\n        Participante.lista_participantes.append(self)\n\n    # Ordene los resultados en dos listados\n    def ordenar_mas_antiguo(self):\n        Participante.mas_antiguo = sorted(Participante.lista_participantes, key=lambda p: p.tiempo_total, reverse=True)\n\n    def ordenar_mas_seguido(self):\n        Participante.mas_seguido = sorted(Participante.lista_participantes, key=lambda p: p.seguidores, reverse=True)\n\n\n    # Crea un ranking por número de seguidores y por antigüedad\n    def mostrar_tabla_mas_antiguo(self):\n        print(\"RANKING DE MAS ANTIGUOS\")\n        print(\"-\"*50)\n        for position, participante in enumerate(Participante.mas_antiguo):\n            if participante.fecha_registro is None:\n                print(f\"{position+1}. {participante.nombre.upper()} no tiene cuenta de Twitch\")\n            else:\n                print(f\"{position+1}. {participante.nombre.upper()} creado el {participante.fecha_registro}\")\n            print(\"-\"*30)\n            print()\n        print()\n    def mostrar_tabla_mas_seguido(self):\n        print(\"RANKING DE MAS SEGUIDOS\")\n        print(\"-\"*50)\n        for position, participante in enumerate(Participante.mas_seguido):\n            if participante.seguidores == 0:\n                print(f\"{position+1}. {participante.nombre.upper()} no tiene seguidores o cuenta de Twitch\")\n            else:\n                print(f\"{position+1}. {participante.nombre.upper()} con {participante.seguidores} seguidores\")\n            print(\"-\"*30)\n            print()\n        print()\n\n    # Desarrolla un programa que obtenga el número de seguidores en\n    # Twitch de cada participante, la fecha de creación de la cuenta\n    def obtener_datos(self):\n            # Usa el API de Twitch\n\n            url = f\"https://api.twitch.tv/helix/users?login={self.nombre}\"\n            headers = {\n                'Client-ID': Participante.token.id,\n                'Authorization': f'Bearer {Participante.token.token}',\n            }\n\n            response = requests.get(url, headers=headers)\n\n            if response.status_code == 200 and len(response.json()[\"data\"]) > 0:\n                datos = response.json()\n                self.id = datos[\"data\"][0][\"id\"]\n                # Obtenga la fecha de creación de la cuenta\n                fecha_regisro = datos[\"data\"][0][\"created_at\"][0:10]\n                self.fecha_registro = datetime.datetime.strptime(fecha_regisro, \"%Y-%m-%d\").strftime(\"%d/%m/%Y\")\n                self.tiempo_total = datetime.datetime.now() - datetime.datetime.strptime(self.fecha_registro, \"%d/%m/%Y\")\n                self.tiempo_total = self.tiempo_total.days\n\n                print(f\"Usuario {self.nombre.upper()} registrado\")\n            else:\n                # Si algún participante no tiene usuario en Twitch, debe reflejarlo\n                print(f\"No se encontro el usuario {self.nombre.upper()}\")\n                self.tiempo_total = 0\n\n\n    # Obtenga el número de seguidores\n    def obtener_seguidores(self):\n        if self.id is None:\n            self.seguidores = 0\n        else:\n            url = f\"https://api.twitch.tv/helix/channels/followers\"\n            \n            params = {\n                \"broadcaster_id\": self.id\n                }\n            headers = {\n                'Client-ID': Participante.token.id,\n                'Authorization': f'Bearer {Participante.token.token}',\n            }\n\n            response = requests.get(url, headers=headers,params=params)\n\n            if response.status_code == 200:\n                response = response.json()\n                self.seguidores = response['total']\n\n            else:\n                print(f\"Error: {response.status_code}\\n{response.json()['message']}\")\n                self.seguidores = 0\n\n\n    \n\n\n# Pruebas\n\nlista = [\n    \"littleragergirl\",\"ache\",\"AdriContreras4\",\"agustin51\",\"alexby11\",\"ampeterby7\",\n    \"tvandeR\",\"arigameplays\",\"arigeli_\",\"auronplay\",\"axozer\",\"beniju03\",\"bycalitos\",\n    \"byviruzz\",\"carreraaa\",\"celopan\",\"srcheeto\",\"crystalmolly\",\"darioemehache\",\n    \"dheylo\",\"djmariio\",\"doble\",\"elvisayomastercard\",\"elyas360\",\"folagorlives\",\n    \"thegrefg\",\"guanyar\",\"hika\",\"hiperop\",\"ibai\",\"ibelky_\",\"illojuan\",\"imantado\",\n    \"irinaisasia\",\"jesskiu\",\"jopa\",\"jordiwild\",\"kenaisouza\",\"keroro\",\"kiddkeo\",\n    \"kikorivera\",\"knekro\",\"kokorok\",\"kronnozomber\",\"leviathan\",\"lolkilla\",\"lola_lolita\",\n    \"lolito\",\"luzu\",\"mangel\",\"mayichi\",\"meelo\",\"missasofia\",\"mixwell\",\"mrjagger\",\n    \"nategentile\",\"nexxuz\",\"nissaxter\",\"ollie\",\"orslok\",\"outconsumer\",\"papigavi\",\n    \"paracetamor\",\"patica\",\"paulagonu\",\"pausenpaii\",\"perxita\",\"plex\",\"polispol\",\n    \"quackity\",\"recuerdop\",\"reven\",\"rivers\",\"robertpg\",\"roier\",\"rojuu\",\"rubius\",\n    \"shadoune\",\"silithur\",\"spreen\",\"spursito\",\"staxx\",\"suzyrox\",\"vicens\",\"vituber\",\n    \"werlyb\",\"xavi\",\"xcrystal\",\"xokas\",\"zarcort\",\"zeling\",\"zorman\"\n]\n\nfor i in lista:\n    p = Participante(i)\n    p.obtener_datos()\n    p.obtener_seguidores()\n\nParticipante.ordenar_mas_antiguo(Participante)\nParticipante.ordenar_mas_seguido(Participante)\n\nParticipante.mostrar_tabla_mas_seguido(Participante)\nParticipante.mostrar_tabla_mas_antiguo(Participante)\n"
  },
  {
    "path": "Roadmap/40 - FORTNITE RUBIUS CUP/python/Gordo-Master.py",
    "content": "# 40 - Fornite Rubius Cup\nimport env\nimport requests\n\nCLIENT_ID = env.CLIENT_ID\nCLIENT_SECRET = env.CLIENT_SECRET\n\nusers = [\n    \"littleragergirl\", \"ache\", \"adricontreras4\", \"agustin51\", \"alexby11\", \"ampeterby7\", \"tvander\",\n    \"arigameplays\", \"arigeli_\", \"auronplay\", \"axozer\", \"beniju03\", \"bycalitos\",\n    \"byviruzz\", \"carreraaa\", \"celopan\", \"srcheeto\", \"crystalmolly\", \"darioemehache\",\n    \"dheylo\", \"djmariio\", \"doble\", \"elvisayomastercard\", \"elyas360\", \"folagorlives\", \"thegrefg\",\n    \"guanyar\", \"hika\", \"hiperop\", \"ibai\", \"ibelky_\", \"illojuan\", \"imantado\",\n    \"irinaissaia\", \"jesskiu\", \"jopa\", \"jordiwild\", \"kenaivsouza\", \"mrkeroro10\",\n    \"thekiddkeo95\", \"kikorivera\", \"knekro\", \"kokoop\", \"kronnozomberoficial\", \"leviathan\",\n    \"litkillah\", \"lolalolita\", \"lolitofdez\", \"luh\", \"luzu\", \"mangel\", \"mayichi\",\n    \"melo\", \"missasinfonia\", \"mixwell\", \"jaggerprincesa\", \"nategentile7\", \"nexxuz\",\n    \"lakshartnia\", \"nilojeda\", \"nissaxter\", \"olliegamerz\", \"orslok\", \"outconsumer\", \"papigavitv\",\n    \"paracetamor\", \"patica1999\", \"paulagonu\", \"pausenpaii\", \"perxitaa\", \"nosoyplex\",\n    \"polispol1\", \"quackity\", \"recuerd0p\", \"reventxz\", \"rivers_gg\", \"robertpg\", \"roier\",\n    \"ceuvebrokenheart\", \"rubius\", \"shadoune666\", \"silithur\", \"spok_sponha\", \"elspreen\", \"spursito\",\n    \"bystaxx\", \"suzyroxx\", \"vicens\", \"vitu\", \"werlyb\", \"xavi\", \"xcry\", \"elxokas\",\n    \"thezarcort\", \"zeling\", \"zormanworld\", \"mouredev\"\n]\n\ndef get_token(client_id, client_secret):\n    url = \"https://id.twitch.tv/oauth2/token\"\n    headers = {'Content-Type': 'application/x-www-form-urlencoded'}\n    data = {\n        \"client_id\" : client_id,\n        \"client_secret\" : client_secret,\n        \"grant_type\" : \"client_credentials\"\n    }\n    response = requests.post(url=url, headers= headers, data=data)\n    respuesta =response.json()\n    return respuesta[\"access_token\"]\n\ndef get_user(token,client_id, name):\n    url = f\"https://api.twitch.tv/helix/users?login={name}\"\n    headers = {\n        'Authorization': f'Bearer {token}',\n        'Client-Id' : client_id\n        }\n    response = requests.get(url,headers=headers)\n    return response.json()\n\ndef get_followers(token, client_id, id):\n    url = f\"https://api.twitch.tv/helix/channels/followers?broadcaster_id={id}\"\n    headers = {\n        'Authorization': f'Bearer {token}',\n        'Client-Id' : client_id\n        }\n    response = requests.get(url, headers=headers)\n    return response.json()[\"total\"]\n\ntoken = get_token(CLIENT_ID,CLIENT_SECRET)\n\nno_twitch_users = []\ntwitch_users = []\ncount = 0\nnumber_users = len(users)\nfor user in users:\n    count += 1\n    print(f\"[*] Progreso: {count}/{number_users} ({count/number_users*100:.0f}%)\",end=\"\\r\")\n    data = get_user(token,CLIENT_ID,user)\n    if not data[\"data\"]:\n        no_twitch_users.append(user)\n    else:\n        followers = get_followers(token,CLIENT_ID,data[\"data\"][0][\"id\"])\n        twitch_users.append(\n            {\n                \"name\": user,\n                \"date_creation\" : data[\"data\"][0][\"created_at\"],\n                \"followers\" : followers\n            }\n        )\n\nranking_followers = sorted(twitch_users,key= lambda x: x[\"followers\"],reverse=True)\nranking_date_creation = sorted(twitch_users,key= lambda x: x[\"date_creation\"])\n\nprint(\"\\nRanking segun followers:\")\nfor index, streamer in enumerate(ranking_followers):\n    print(f\"{index+1}. {streamer[\"name\"]} : {streamer[\"followers\"]:,}\")\nprint(\"\\n Ranking segun fecha de creación\")\nfor index, streamer in enumerate(ranking_date_creation):\n    print(f\"{index+1}. {streamer[\"name\"]} : {streamer[\"date_creation\"]}\")\n\nprint(\"\\nNo Twitch Users:\")\nfor index, streamer in enumerate(no_twitch_users):\n    print(f\"{index+1}. {streamer}\")"
  },
  {
    "path": "Roadmap/40 - FORTNITE RUBIUS CUP/python/JesusWay69.py",
    "content": "import os, platform, credentials, asyncio, requests\nfrom twitchAPI.twitch import Twitch\nfrom twitchAPI.helper import first\n\nif (platform.platform().startswith(\"macOS\") or platform.platform().startswith(\"Linux\")):\n    os.system('clear')\nelse:\n    os.system('cls')\n\n\"\"\" * EJERCICIO:\n * ¡Rubius tiene su propia skin en Fortnite!\n * Y va a organizar una competición para celebrarlo.\n * Esta es la lista de participantes:\n * https://x.com/Rubiu5/status/1840161450154692876\n *\n * Desarrolla un programa que obtenga el número de seguidores en\n * Twitch de cada participante, la fecha de creación de la cuenta \n * y ordene los resultados en dos listados.\n * - Usa el API de Twitch: https://dev.twitch.tv/docs/api/reference\n *   (NO subas las credenciales de autenticación)\n * - Crea un ranking por número de seguidores y por antigüedad.\n * - Si algún participante no tiene usuario en Twitch, debe reflejarlo.\"\"\"\n\nstreamers_list = [\"Abby\", \"Ache\", \"AdriContreras4\", \"agustin51\", \"alexby11\", \"ampeterby7\" , \"AriGameplays\", \"Arigeli_\",\n                 \"auronplay\",\"axozer\", \"beniju03\", \"bycalitos\", \"byViruZz\" ,\"Carreraaa\" , \"celopan\", \"crystalmolly\",\n                 \"darioemehache\",\"dheylo\", \"djmariio\", \"doble\", \"elvisayomastercard\", \"elxokas\", \"elyas360\" , \"FolagorLives\", \n                 \"guanyar\", \"hika\",\"hiperop\", \"ibai\", \"ibelky_\", \"IlloJuan\" ,\"imantado\" , \"irinaisasia\", \"jesskiu\",\n                 \"jopa\",\"jordiwild\", \"kenaisouza\", \"keroro\", \"TheKiddKeo95\" ,\"kikorivera\" , \"knekro\", \"kokorok\", \"kronnozomber\",\n                 \"leviathan\", \"littleragergirl\", \"lola_lolita\", \"lolito\" ,\"lolkilla\" , \"luzu\", \"mangel\", \"mayichi\",\n                 \"meelo\", \"MissaSinfonia\", \"mixwell\", \"mrjagger\" ,\"NateGentile7\" , \"nexxuz\", \"nissaxter\", \"NoSoyPlex\", \"OllieGamerz\",\n                 \"orslok\", \"outconsumer\", \"papigavi\", \"paracetamor\" ,\"patica\" , \"paulagonu\", \"pausenpaii\", \"perxitaa\",\n                 \"polispol1\", \"quackity\", \"recuerdop\" ,\"reven\" , \"rivers_gg\", \"robertpg\", \"roier\",\n                 \"rojuu\", \"Rubius\", \"shadoune\", \"silithur\" ,\"ElSpreen\" , \"Spursito\", \"srcheeto\", \"staxx\",\n                 \"suzyrox\", \"TheGrefg\", \"tvandeR\", \"Vicens\" ,\"vitu\" , \"werlyb\", \"Xavi\", \"xcrystal\",\n                  \"zarcort\", \"Zeling\", \"ZormanWorld\"]\n\ndev_streamers_list = [\"afor_digital\", \"altaskur\", \"AppleCoding\", \"CarlosAzaustre\", \"CarlosGameDeveloper\",\n                     \"CursosDeDesarrollo\", \"dimaspython\", \"ElPinguinoDeMario\",\"Guinxu\", \n                     \"ManzDev\", \"MelenitasDev\", \"midudev\", \"MoureDev\", \"programacion_es\",\n                     \"r2d2_Coder\", \"RafaLagoon\", \"RothioTome\", \"todocode\", \"vamoacodear\"]\n\nclient_id = credentials.client_id_v3\nsecret_id = credentials.secret_id_v3\n\ndef get_token(client_id, client_secret) -> str:\n    url = 'https://id.twitch.tv/oauth2/token'\n\n    response = requests.post(url, data = {\n        'client_id': client_id,\n        'client_secret': client_secret,\n        'grant_type': 'client_credentials'\n    })\n\n    if response.status_code != 200:\n        return f\"Error token: {response.status_code}\"\n        \n    result = response.json()\n    if result['token_type'] != \"bearer\":\n        raise Exception(\"Unexpected token type\")\n    return result.get(\"access_token\")\n\nasync def get_user_data(channel:str) -> tuple:\n    client = await Twitch(client_id,secret_id)\n    user = await first(client.get_users(logins=channel))\n    if user == None:\n        return None, None, None\n    return user.id, user.display_name, user.created_at\n\n\ndef get_followers(id, token, client_id) -> int:\n    url = f'https://api.twitch.tv/helix/channels/followers'\n\n    response = requests.get(url, headers = {\n        'Client-ID': client_id,\n        'Authorization': f'Bearer {token}'\n    }, params={\"broadcaster_id\":id})\n\n    if response.status_code == 200:\n        return response.json().get('total')\n        \n    else:\n        return f\"Error data: {response.json()}\"\n\ndef sort_by_date(streamers:list):\n    print(\"\\nSTREAMERS ORDENADOS POR ANTIGÜEDAD\")\n    print(\"------------------------------------\")\n    [print (f\"{name}-> Fecha de creación del canal: {date}\") for name, date in zip(list((map(lambda streamer: '{:<20}'.format(streamer[0]),\n    sorted(streamers, key=lambda streamer: streamer[1])))), list(map(lambda streamer: streamer[1].strftime('%d/%m/%Y'),\n    sorted(streamers, key=lambda streamer: streamer[1]))))]\n\ndef sort_by_followers(streamers:list):\n    print(\"\\nSTREAMERS ORDENADOS POR SEGUIDORES\")                                          \n    print(\"--------------------------------------\")\n    [print (f\"{name}-> Seguidores totales: {followers}\") for name, followers in zip(list((map(lambda streamer: '{:<20}'.format(streamer[0]),\n    sorted(streamers, key=lambda streamer: streamer[2], reverse=True)))), list(map(lambda streamer: streamer[2],\n    sorted(streamers, key=lambda streamer: streamer[2], reverse=True))))]\n\ntoken = get_token(client_id, secret_id)\nsorted_list:list = []\nprint(\"STREAMERS DE PROGRAMACIÓN EN ESPAÑOL\")\nprint(\"------------------------------------\")\nfor index, streamer in enumerate(dev_streamers_list):\n    sorted_list.append([])\n    id, name, since = asyncio.run(get_user_data(streamer))\n    followers = get_followers(id, token, client_id)\n    if id == None:\n        print(f\"{index}- Usuario '{streamer}' no encontrado\")\n        dev_streamers_list.pop(index)\n        index+=1\n        continue\n    print(f\"{index+1}- {name}, Antiguedad: {since.day}/{since.month}/{since.year}, Seguidores: {followers}\")\n    sorted_list[index].append(name)\n    sorted_list[index].append(since.strptime(f\"{since.day}/{since.month}/{since.year}\", \"%d/%m/%Y\"))\n    sorted_list[index].append(followers)\n\nsort_by_date(sorted_list)\nsort_by_followers(sorted_list)\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/40 - FORTNITE RUBIUS CUP/python/Nicojsuarez2.py",
    "content": "# #40 FORTNITE RUBIUS CUP\n> #### Dificultad: Media | Publicación: 30/09/24 | Corrección: 07/10/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * ¡Rubius tiene su propia skin en Fortnite!\n * Y va a organizar una competición para celebrarlo.\n * Esta es la lista de participantes:\n * https://x.com/Rubiu5/status/1840161450154692876\n *\n * Desarrolla un programa que obtenga el número de seguidores en\n * Twitch de cada participante, la fecha de creación de la cuenta \n * y ordene los resultados en dos listados.\n * - Usa el API de Twitch: https://dev.twitch.tv/docs/api/reference\n *   (NO subas las credenciales de autenticación)\n * - Crea un ranking por número de seguidores y por antigüedad.\n * - Si algún participante no tiene usuario en Twitch, debe reflejarlo.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/40 - FORTNITE RUBIUS CUP/python/SooHav.py",
    "content": "# 40 FORTNITE RUBIUS CUP\n\nimport requests\nimport base64\nfrom datetime import datetime\nimport os\nfrom dotenv import load_dotenv\n\n# Cargar las variables de entorno desde .env para obtener CLIENT_ID y CLIENT_SECRET\nload_dotenv()\n\nCLIENT_ID = os.getenv(\"CLIENT_ID\")\nCLIENT_SECRET = os.getenv(\"CLIENT_SECRET\")\n\n# Funciones\n\n\ndef obtener_token() -> str:\n    url = \"https://id.twitch.tv/oauth2/token\"\n    data = {\n        \"client_id\": CLIENT_ID,\n        \"client_secret\": CLIENT_SECRET,\n        \"grant_type\": \"client_credentials\"\n    }\n\n    headers = {\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n    }\n\n    response = requests.post(url, headers=headers, data=data)\n    if response.status_code != 200:\n        raise Exception(f\"Error obteniendo el token de Twitch: {\n                        response.json()}.\")\n\n    return response.json()[\"access_token\"]\n\n\ndef buscar_participante(token: str, login: str):\n    url = f\"https://api.twitch.tv/helix/users?login={login}\"\n    headers = {\n        \"Authorization\": f\"Bearer {token}\",\n        \"Client-Id\": CLIENT_ID\n    }\n\n    response = requests.get(url, headers=headers)\n    if response.status_code != 200:\n        return {\n            \"login\": login,\n            \"estado del usuario de twitch\": \"Inactivo\"\n        }\n    resultados = response.json().get(\"data\", [])\n    if resultados:\n        return {\n            \"id\": resultados[0][\"id\"],\n            \"login\": resultados[0][\"login\"],\n            \"usuario twitch\": resultados[0][\"display_name\"],\n            \"creación de cuenta\": (datetime.strptime(resultados[0][\"created_at\"], \"%Y-%m-%dT%H:%M:%SZ\")),\n            \"descripción\": resultados[0][\"description\"],\n            \"estado del usuario de twitch\": \"activo\"\n        }\n    return {}\n\n\ndef buscar_seguidores_participante(token: str, id: str):\n    url = f\"https://api.twitch.tv/helix/channels/followers?broadcaster_id={id}\"\n    headers = {\n        \"Authorization\": f\"Bearer {token}\",\n        \"Client-Id\": CLIENT_ID\n    }\n    response = requests.get(url, headers=headers)\n    if response.status_code != 200:\n        return {\n            \"total de seguidores\": 0,\n            \"estado del usuario de twitch\": \"Inactivo\",\n            \"seguido desde\": \"Sin informacion disponible\"\n        }\n\n    resultados = response.json()\n    total_seguidores = resultados.get(\"total\", 0)\n\n    if resultados.get(\"data\"):\n        resultados_canal = resultados[\"data\"][0]\n        return {\n            \"total de seguidores\": total_seguidores,\n            \"broadcaster id\": resultados_canal['user_id'],\n            \"login del usuario\": resultados_canal['user_login'],\n            \"seguido desde\": resultados_canal['followed_at']\n        }\n    return {\n        \"total de seguidores\": total_seguidores,\n        \"estado del usuario de twitch\": \"Activo\",\n        \"seguido desde\": \"Sin informacion disponible\"\n    }\n\n\ndef buscar_info_canal(token: str, broadcaster_id: str):\n    url = f\"https://api.twitch.tv/helix/channels?broadcaster_id={\n        broadcaster_id}\"\n    headers = {\n        \"Authorization\": f\"Bearer {token}\",\n        \"Client-Id\": CLIENT_ID\n    }\n    response = requests.get(url, headers=headers)\n    if response.status_code != 200:\n        return {\n            \"juegos\": \"sin información\",\n            \"tópicos del canal\": \"sin información\",\n        }\n    resultados_canal = response.json().get(\"data\", [])\n    if resultados_canal:\n        return {\n            \"juegos\": resultados_canal[0]['game_name'],\n            \"tópicos del canal\": resultados_canal[0]['content_classification_labels']\n        }\n    return {\n        \"juegos\": \"sin información\",\n        \"tópicos del canal\": \"sin información\",\n    }\n\n# Uso de codigo\n\n\ntoken = obtener_token()\n\nparticipantes_lista = [\n    'littleragergirl', 'DJMARIIO', 'KikoRivera', 'NISSAXTER',\n    'SHADOUNE666', 'ACHE', 'DOBLE', 'KNEKRO',\n    'OllieGamerz', 'SILITHUR', 'AdriContreras4', 'ElvisaYomastercard',\n    'KOKO', 'ORSLOK', 'spok_sponha', 'agustin51',\n    'elyas360', 'KronnoZomberOficial', 'Outconsumer', 'SPREEN',\n    'ElSpreen', 'FolagorLives', 'Leviathan', 'PapiGaviTV',\n    'Spursito', 'Ampeterby7', 'TheGrefg', 'LITkillah',\n    'paracetamor', 'bysTaXx', 'tvandeR', 'GUANYAR',\n    'LOLALOLITA', 'patica1999', 'SUZYROXX', 'ARIGAMEPLAYS',\n    'HIKA', 'LOLITOFDEZ', 'PAULAGONU', 'VICENS',\n    'ARIGELI_', 'Hiperop', 'LUH', 'PAUSENPAII',\n    'VITU', 'AURONPLAY', 'IBAI', 'LUZU',\n    'PERXITAA', 'WERLYB', 'AXOZER', 'IBELKY_',\n    'MANGEL', 'NoSoyPlex', 'XAVI', 'BENIJU03',\n    'ILLOJUAN', 'MAYICHI', 'POLISPOL1', 'XCRY',\n    'BYCALITOS', 'IMANTADO', 'MELO', 'QUACKITY',\n    'elxokas', 'BYVIRUZZ', 'IRINA ISASIA', 'MISSASINFONIA',\n    'Recuerd0p', 'THEZARCORT', 'CARRERAAA', 'JESSKIU',\n    'MIXWELL', 'REVENXZ', 'ZELING', 'CELOPAN',\n    'JOPA', 'JaggerPrincesa', 'rivers_gg', 'ZormanWorld',\n    'srcheeto', 'JORDIWILD', 'NATEGENTILE7', 'ROBERTPG',\n    'CRYSTALMOLLY', 'kenaivsouza', 'NEXXUZ', 'ROIER',\n    'DARIOEMEHACHE', 'MrKeroro10', 'LakshartNia', 'ROJUU',\n    'DHEYLO', 'TheKiddKeo95', 'nilojeda', 'RUBIUS'\n]\n\n\ninformacion_participantes_seguidores = []\ninformacion_participantes_antiguedad = []\n\n\nfor nombre in participantes_lista:\n    try:\n        participante = buscar_participante(token, nombre)\n        info = {\"usuario twitch\": nombre}\n\n        if \"id\" in participante:\n            info[\"id\"] = participante[\"id\"]\n            info[\"estado del usuario de twitch\"] = participante.get(\n                \"estado del usuario de twitch\", \"Inactivo\")\n            seguidores = buscar_seguidores_participante(\n                token, participante[\"id\"])\n            info[\"total seguidores\"] = int(\n                seguidores.get(\"total de seguidores\", 0))\n\n            if \"broadcaster id\" in seguidores:\n                canal = buscar_info_canal(token, seguidores[\"broadcaster id\"])\n                info[\"juegos\"] = canal.get(\n                    \"juegos\", \"Informacion no disponible\")\n                info[\"tópicos del canal\"] = canal.get()\n        else:\n            info[\"estado del usuario de twitch\"] = \"No tiene cuenta de twitch\"\n            info[\"total seguidores\"] = 0\n\n        informacion_participantes_seguidores.append(info)\n\n    except Exception as e:\n        print(f\"Error al procesar {nombre}: {e}\")\n\nfor nombre in participantes_lista:\n    try:\n        participante = buscar_participante(token, nombre)\n        cuenta = {\"usuario twitch\": nombre}\n        if \"id\" in participante:\n            cuenta[\"id\"] = participante[\"id\"]\n            cuenta[\"estado del usuario de twitch\"] = participante.get(\n                \"estado del usuario de twitch\", \"Inactivo\")\n            cuenta[\"creación de cuenta\"] = participante.get(\n                \"creación de cuenta\", None)\n            creacion = buscar_seguidores_participante(\n                token, participante[\"id\"])\n            creacion[\"seguido desde\"] = creacion. get(\"seguido desde\", None)\n        else:\n            cuenta[\"estado del usuario de twitch\"] = \"No tiene cuenta de twitch\"\n            cuenta[\"creación de cuenta\"] = None\n\n        informacion_participantes_antiguedad.append(cuenta)\n\n    except Exception as e:\n        print(f\"Error al procesar {nombre}: {e}\")\n\n\ninformacion_participantes_seguidores = sorted(\n    informacion_participantes_seguidores,\n    key=lambda x: x.get(\"total seguidores\", 0),\n    reverse=True\n)\n\n\ninformacion_participantes_antiguedad = sorted(\n    informacion_participantes_antiguedad,\n    key=lambda x: x.get(\"creación de cuenta\") if x.get(\n        \"creación de cuenta\") is not None else datetime.min,\n    reverse=True\n)\n# Participantes del evento Rubius Cup\nprint(\"\\nLista de los seguidores de los participantes del evento Rubius Cup en Twitch\\n\")\nfor participante_evento_fortnite in informacion_participantes_seguidores:\n    print(f\"Participante: {participante_evento_fortnite['usuario twitch']}, Estado: {\n          participante_evento_fortnite['estado del usuario de twitch']}, Seguidores: {participante_evento_fortnite['total seguidores']}\")\n\nprint(\"\\nLista de antiguedad de las cuentas de los participantes del evento Rubius Cup en Twitch\\n\")\n\n# Participantes del evento Rubius Cup\nfor participante_evento_fortnite in informacion_participantes_antiguedad:\n    fecha_creacion = participante_evento_fortnite.get(\"creación de cuenta\")\n\n    if isinstance(fecha_creacion, datetime):\n        fecha = fecha_creacion.strftime(\"%d-%m-%Y %H:%M:%S\")\n    elif isinstance(fecha_creacion, str):\n        fecha = fecha_creacion\n    else:\n        fecha = \"Información no disponible\"\n\n    print(f\"Participante: {participante_evento_fortnite['usuario twitch']}, Estado: {\n          participante_evento_fortnite['estado del usuario de twitch']}, Creación de cuenta: {fecha}\")\n"
  },
  {
    "path": "Roadmap/40 - FORTNITE RUBIUS CUP/python/cdryampi.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * ¡Rubius tiene su propia skin en Fortnite!\n#  * Y va a organizar una competición para celebrarlo.\n#  * Esta es la lista de participantes:\n#  * https://x.com/Rubiu5/status/1840161450154692876\n#  *\n#  * Desarrolla un programa que obtenga el número de seguidores en\n#  * Twitch de cada participante, la fecha de creación de la cuenta \n#  * y ordene los resultados en dos listados.\n#  * - Usa el API de Twitch: https://dev.twitch.tv/docs/api/reference\n#  *   (NO subas las credenciales de autenticación)\n#  * - Crea un ranking por número de seguidores y por antigüedad.\n#  * - Si algún participante no tiene usuario en Twitch, debe reflejarlo.\n#  */\n\n\nimport urllib.parse\nimport aiohttp\nimport asyncio\nfrom datetime import datetime\n\n\nclass ApiTwitch():\n    \"\"\"\"\"\"\n    __CLIENT_ID = ':('\n    __CLIENT_SECRET = ':)'\n\n    __ACCESS_TOKEN = None\n    __HEADERS = None\n    __URL_CONN_API = 'https://api.twitch.tv/'\n    __URL_CONN_TOKEN = 'https://id.twitch.tv/oauth2/token'\n    __ENDPOINTS = {\n        \"followers\": \"helix/channels/followers?broadcaster_id={streamer}\",\n        \"channels\": \"helix/users?login={streamer}\",\n        \"id\": \"helix/users?login={streamer}\"\n    }\n    __STREAMERS = {\n        'ABBY': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'ACHE': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'adricontreras4': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'agustin51': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'ALEXBY11': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'ampeterby7': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'ANDER': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'ARIGAMPLAYS': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'ARIGELI': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'AURONPLAY': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'AXOZER': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'BENIJU': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'BYCALITOS': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'BYVIRUZZ': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'CARRERA': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'CELOPAN': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'CHEETO': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'CRYSTALMOLLY': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'DARIOEMEHACHE': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'DHEYLO': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'DJMARIO': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'DOBLE': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'ELVISA': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'ELYAS360': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'FOLAGOR': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'GREFG': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'GUNYAR': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'HIKA': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'HIPER': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'IBAI': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'IBELKY': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'ILLOJUAN': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'IMANTADO': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'IRINAISASIA': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'JESSKIU': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'JOPA': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'JORDIWILD': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'KENAISOUZA': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'KERORO': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'KIDDKEO': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'KIKORIVERA': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'KNEKRO': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'KOKO': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'KRONNZOMBER': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'LEVIATHAN': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'LITKILLAH': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'LOLALOLITA': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'LOLITO': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'LUH': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'LUZO': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'MANGEL': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'MAYICHI': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'MELO': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'MISSASINFONIA': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'MIXWELL': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'jaggerprincesa': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'NATEGENTILE': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'NEXXUZ': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'lakshartnia': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'NILOJEDA': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'NISSAXTER': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'OLLIE': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'ORSLOK': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'OUTCONSUMER': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'PAPIGAVI': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'PARACETAMOR': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'PATICA': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'PAULAGONU': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'PERXITAA': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'nosoyplex': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'polispol1': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'QUACKITY': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'RECUERDOP': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'REVEN': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'RIVERS': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'ROBERTPG': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'ROIER': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'ROJUU': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'RUBIUS': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'SHADOUNE': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'SLITHUR': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'SPOKSPONHA': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'SPREEN': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'SPURSITO': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'STAXX': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'SUZYROXX': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'VICENS': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'VITUBER': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'WERLYB': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'XAVI': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'XCRY': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'XOKAS': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'ZARCORT': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'ZELING': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        },\n        'ZORMAN': {\n            'id': '',\n            'followers': 0,\n            'antiguedad': ''\n        }\n    }\n\n\n\n    async def __get_access_token(self, session):\n\n\n        headers = {\n            'Content-Type': 'application/x-www-form-urlencoded',\n        }\n        body = urllib.parse.urlencode({\n            'grant_type': 'client_credentials',\n            'client_id': self.__CLIENT_ID,\n            'client_secret': self.__CLIENT_SECRET\n        })\n\n        async with session.post(self.__URL_CONN_TOKEN, data= body, headers= headers) as response:\n            if response.status == 200:\n                token_info = await response.json()\n                self.__ACCESS_TOKEN = token_info[\"access_token\"]\n                self.__HEADERS = {\n                    'Authorization': f'Bearer {self.__ACCESS_TOKEN}',\n                    'Client-Id': self.__CLIENT_ID\n                }\n            else:\n                print(f'Error {response}')\n\n    async def get_headers(self, session):\n        if self.__HEADERS is None:\n            await self.__get_access_token(session)\n        return self.__HEADERS\n    \n    async def get_channel_id_and_created_at(self, session):\n        headers = await self.get_headers(session)\n\n        tasks = []\n        for streamer in list(self.__STREAMERS.items()):\n            url = f'{self.__URL_CONN_API}{self.__ENDPOINTS[\"id\"]}'.format(streamer=streamer[0].lower())\n            tasks.append(self.fetch_channel_data(session, headers, streamer[0], url))\n        \n        await asyncio.gather(*tasks)\n        await self.get_followers(session=session)\n\n    async def fetch_channel_data(self, session, headers, streamer_name, url):\n        async with session.get(url, headers=headers) as response:\n            if response.status == 200:\n                data = await response.json()\n                if data[\"data\"]:\n                    self.__STREAMERS[streamer_name][\"id\"] = data['data'][0][\"id\"]\n                    self.__STREAMERS[streamer_name][\"antiguedad\"] = data['data'][0][\"created_at\"]\n                else:\n                    print(f\"Usuario {streamer_name} no tiene canal por lo tanto sale del concurso.\")\n                    self.__STREAMERS.pop(streamer_name, None)\n            else:\n                print(f\"Error al llamar a {streamer_name}: {response.status}\")\n                self.__STREAMERS.pop(streamer_name, None)\n\n    async def get_followers(self, session):\n            headers = await self.get_headers(session)\n            \n            tasks = []\n            for streamer in list(self.__STREAMERS.items()):\n                url = f'{self.__URL_CONN_API}{self.__ENDPOINTS[\"followers\"]}'.format(streamer=streamer[1][\"id\"])\n                tasks.append(self.fetch_follower_data(session, headers, streamer[0], url))\n            \n            await asyncio.gather(*tasks)\n\n    async def fetch_follower_data(self, session, headers, streamer_name, url):\n        async with session.get(url, headers=headers) as response:\n            if response.status == 200:\n                data = await response.json()\n                if data[\"total\"]:\n                    self.__STREAMERS[streamer_name][\"followers\"] = int(data[\"total\"])\n                    if self.__STREAMERS[streamer_name][\"followers\"] == 0:\n                        print(f\"Usuario {streamer_name} tiene 0 seguidores, lo sacamos del concurso.\")\n                        self.__STREAMERS.pop(streamer_name, None)\n                else:\n                    print(f\"Usuario {streamer_name} tiene 0 seguidores, lo sacamos del concurso.\")\n                    self.__STREAMERS.pop(streamer_name, None)\n            else:\n                print(f\"Error al obtener seguidores de {streamer_name}: {response.status}\")\n\n    def ranking_followers(self):\n\n        sorted_by_followers = dict(sorted(self.__STREAMERS.items(), key= lambda streamer: streamer[1][\"followers\"], reverse=True))\n\n        for ranking, streamer in enumerate(sorted_by_followers.items(), start=1):\n            print(f'{ranking}. {streamer[0]} -> {streamer[1][\"followers\"]} followers.')\n\n    def ranking_by_created_at(self):\n        format_data = \"%Y-%m-%dT%H:%M:%SZ\"\n        sorted_by_created_at = dict(\n            sorted(\n                self.__STREAMERS.items(),\n                key= lambda streamer: datetime.strptime(\n                    streamer[1]['antiguedad'],\n                    format_data)\n                    if streamer[1]['antiguedad'] else datetime.max\n                )\n        )\n\n        for ranking, streamer in enumerate(sorted_by_created_at.items(), start=1):\n            print(f'{ranking}. {streamer[0]} -> {datetime.strptime(streamer[1][\"antiguedad\"], format_data).date()}.')\n\n\n\nasync def main():\n    api = ApiTwitch()\n\n    async with aiohttp.ClientSession() as session:\n        await api.get_channel_id_and_created_at(session)\n        print(\"Ranking de participantes por seguidores en Twitch:\")\n        print(\"\\n\")\n        api.ranking_followers()\n        print(\"\\n\")\n        print(\"\\n\")\n        print(\"Ranking de participantes por seguidores en Twitch:\")\n        print(\"\\n\")\n        api.ranking_by_created_at()\nif __name__ == '__main__':\n    asyncio.get_event_loop().run_until_complete(main())"
  },
  {
    "path": "Roadmap/40 - FORTNITE RUBIUS CUP/python/davidrguez98.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * ¡Rubius tiene su propia skin en Fortnite!\n * Y va a organizar una competición para celebrarlo.\n * Esta es la lista de participantes:\n * https://x.com/Rubiu5/status/1840161450154692876\n *\n * Desarrolla un programa que obtenga el número de seguidores en\n * Twitch de cada participante, la fecha de creación de la cuenta \n * y ordene los resultados en dos listados.\n * - Usa el API de Twitch: https://dev.twitch.tv/docs/api/reference\n *   (NO subas las credenciales de autenticación)\n * - Crea un ranking por número de seguidores y por antigüedad.\n * - Si algún participante no tiene usuario en Twitch, debe reflejarlo.\n */\n``` \"\"\"\n\n#EJERCICIO\n\nimport env\nimport requests\n\nCLIENT_ID = env.CLIENT_ID\nCLIENT_SECRET = env.CLIENT_SECRET\n\ndef get_access_token(client_id: str, client_secret: str) -> str:\n\n    url = \"https://id.twitch.tv/oauth2/token\"\n\n    params = {\n        \"client_id\": client_id,\n        \"client_secret\": client_secret,\n        \"grant_type\": \"client_credentials\"\n    }\n\n    response = requests.post(url, params=params)\n    return response.json().get(\"access_token\")\n\ndef get_user_info(token: str, client_id: str, login: str):\n\n    url = \"https://api.twitch.tv/helix/users\"\n\n    headers = {\n        \"Authorization\": f\"Bearer {token}\",\n        \"Client-Id\": client_id\n    }\n\n    params = {\"login\": login}\n\n    response = requests.get(url, headers=headers, params=params)\n    response.raise_for_status()\n    data = response.json().get(\"data\", None)\n    \n\n    if not data:\n        return None\n    return data[0]\n\ndef get_total_followers(token: str, client_id: str, id: str) -> int:\n\n    url = \"https://api.twitch.tv/helix/channels/followers\"\n\n    headers = {\n        \"Authorization\": f\"Bearer {token}\",\n        \"Client-Id\": client_id\n    }\n\n    params = {\"broadcaster_id\": id}\n\n    response = requests.get(url, headers=headers, params=params)\n    response.raise_for_status()\n    return response.json().get(\"total\", 0)\n\nusers = [\n    \"littleragergirl\", \"ache\", \"adricontreras4\", \"agustin51\", \"alexby11\", \"ampeterby7\", \"tvander\",\n    \"arigameplays\", \"arigeli_\", \"auronplay\", \"axozer\", \"beniju03\", \"bycalitos\",\n    \"byviruzz\", \"carreraaa\", \"celopan\", \"srcheeto\", \"crystalmolly\", \"darioemehache\",\n    \"dheylo\", \"djmariio\", \"doble\", \"elvisayomastercard\", \"elyas360\", \"folagorlives\", \"thegrefg\",\n    \"guanyar\", \"hika\", \"hiperop\", \"ibai\", \"ibelky_\", \"illojuan\", \"imantado\",\n    \"irinaissaia\", \"jesskiu\", \"jopa\", \"jordiwild\", \"kenaivsouza\", \"mrkeroro10\",\n    \"thekiddkeo95\", \"kikorivera\", \"knekro\", \"kokoop\", \"kronnozomberoficial\", \"leviathan\",\n    \"litkillah\", \"lolalolita\", \"lolitofdez\", \"luh\", \"luzu\", \"mangel\", \"mayichi\",\n    \"melo\", \"missasinfonia\", \"mixwell\", \"jaggerprincesa\", \"nategentile7\", \"nexxuz\",\n    \"lakshartnia\", \"nilojeda\", \"nissaxter\", \"olliegamerz\", \"orslok\", \"outconsumer\", \"papigavitv\",\n    \"paracetamor\", \"patica1999\", \"paulagonu\", \"pausenpaii\", \"perxitaa\", \"nosoyplex\",\n    \"polispol1\", \"quackity\", \"recuerd0p\", \"reventxz\", \"rivers_gg\", \"robertpg\", \"roier\",\n    \"ceuvebrokenheart\", \"rubius\", \"shadoune666\", \"silithur\", \"spok_sponha\", \"elspreen\", \"spursito\",\n    \"bystaxx\", \"suzyroxx\", \"vicens\", \"vitu\", \"werlyb\", \"xavi\", \"xcry\", \"elxokas\",\n    \"thezarcort\", \"zeling\", \"zormanworld\", \"mouredev\"\n]\nusers_data = []\nnot_found_users = []\n\ntoken = get_access_token(CLIENT_ID, CLIENT_SECRET)\n\nfor user_name in users:\n\n    user = get_user_info(token, CLIENT_ID, user_name)\n\n    if user is None:\n        not_found_users.append(user_name)\n    else:\n        followers = get_total_followers(token, CLIENT_ID, user[\"id\"])\n        users_data.append({\n            \"user_name\": user_name,\n            \"created_at\": user[\"created_at\"],\n            \"followers\": followers\n        })\n\nsort_by_followers = sorted(users_data, key=lambda x: x[\"followers\"], reverse=True)\nsort_by_date = sorted(users_data, key=lambda x: x[\"created_at\"])\n\nprint(\"Ranking por número de seguidores:\")\nfor id, user, in enumerate(sort_by_followers):\n    print(f\"{id + 1} - {user[\"user_name\"]}: {user[\"followers\"]} seguidores.\")\n\nprint()\n\nprint(\"Ranking por antiguedad:\")\nfor id, user, in enumerate(sort_by_date):\n    print(f\"{id + 1} - {user[\"user_name\"]}: Creado el {user[\"created_at\"]}.\")\n\nprint()\n\nif not_found_users:\n    print(\"Usuarios no encontrados:\")\n    for user in not_found_users:\n        print(user)\n"
  },
  {
    "path": "Roadmap/40 - FORTNITE RUBIUS CUP/python/duendeintemporal.py",
    "content": "#40 { Retos para Programadores } FORTNITE RUBIUS CUP \n\n# Bibliography reference:\n# I use GPT as a reference and sometimes to correct or generate proper comments.\n\n\"\"\"\n * EJERCICIO:\n * ¡Rubius tiene su propia skin en Fortnite!\n * Y va a organizar una competición para celebrarlo.\n * Esta es la lista de participantes:\n * https://x.com/Rubiu5/status/1840161450154692876\n *\n * Desarrolla un programa que obtenga el número de seguidores en\n * Twitch de cada participante, la fecha de creación de la cuenta \n * y ordene los resultados en dos listados.\n * - Usa el API de Twitch: https://dev.twitch.tv/docs/api/reference\n *   (NO subas las credenciales de autenticación)\n * - Crea un ranking por número de seguidores y por antigüedad.\n * - Si algún participante no tiene usuario en Twitch, debe reflejarlo.\n\n\"\"\"\nlog = print\n\nimport requests\nfrom datetime import datetime\n\n# Replace here with your Twitch client ID and client secret\nCLIENT_ID = 'YOUR_CLIENT_ID'\nCLIENT_SECRET = 'YOUR_CLIENT_SECRET'\n\n\"\"\"  \nWe will use https://jpgtoexcel.com/es to extract the list of the participants from the post image related with the first url of the challenge to a Excell file an then incorpore it to a participant list.\n\"\"\"\n\nparticipants = [\n    'ABBY', 'DJMARIIO', 'KIKO RIVERA', 'NISSAXTER', 'SHADOUNE', 'SILTHURA',\n    'ACHE', 'DOBLE', 'KNEKRO', 'OLLI', 'SPOKSPHORA', 'SPREEN', 'ADRI CONTRERAS',\n    'ELVISA', 'KOKO', 'OUTCONSUMER', 'PAPI GAVI', 'PARACETAMOR', 'AGUSTIN',\n    'ELYAS360', 'KRONONOMZOR', 'LEVIATHAN', 'LT KILAH', 'PATTAC', 'ALEXBY',\n    'FOLAGOR', 'LOLA LOLITA', 'PAULA GONI', 'PAUSENPAI', 'PERKITA', 'AMPETER',\n    'GREGR', 'LUH', 'MANGEL', 'PLEX', 'QUACKITY', 'ARI GAMEPLAYS', 'HIKA',\n    'HIPER', 'ILAI', 'MELO', 'RECEDROP', 'AUXOZER', 'IBELKY', 'ILOI JUAN',\n    'MAYICH', 'RIVERS', 'ROBERTP', 'BYCLITOS', 'IMANOTAD', 'IRINA ISAIA',\n    'MIKEL', 'ROJER', 'ROHI', 'BYVIRUZZ', 'JESKSU', 'JOPA', 'MR. JAGGER',\n    'ROJER', 'RUBIUS', 'CARRERA', 'JORIDWILD', 'KEANI SOUZA', 'NEXUZ',\n    'RIVERA', 'ZELIN', 'CHEETO', 'KERSO', 'KIDD KEO', 'NIL OJEDA', 'SUZYROXX',\n    'VICENS', 'CRYSTALMOLLY', 'DARIO MELACHE', 'DHEYO', 'MOUREDEV', 'FATZ',\n    'BUBBCODE', 'CODETRAIN', 'NINJACODE',\n]\n\nimport requests\nfrom datetime import datetime\nimport time\n\n# Replace here with your Twitch client ID and client secret\nCLIENT_ID = 'YOUR_CLIENT_ID'\nCLIENT_SECRET = 'YOUR_CLIENT_SECRET'\n\nparticipants = [\n    # ... (your list of participants)\n]\n\ndef get_oauth_token():\n    response = requests.post('https://id.twitch.tv/oauth2/token', params={\n        'client_id': CLIENT_ID,\n        'client_secret': CLIENT_SECRET,\n        'grant_type': 'client_credentials'\n    })\n    return response.json().get('access_token')\n\ndef get_user_data(username, token):\n    try:\n        response = requests.get(f'https://api.twitch.tv/helix/users?login={username}', headers={\n            'Client-ID': CLIENT_ID,\n            'Authorization': f'Bearer {token}'\n        })\n        return response.json().get('data', [None])[0]  # Return the first user data\n    except Exception as e:\n        print(f'Error fetching data for {username}: {e}')\n        return None\n\ndef get_follower_count(username, token):\n    try:\n        user_data = get_user_data(username, token)\n        if user_data:\n            user_id = user_data['id']\n            response = requests.get(f'https://api.twitch.tv/helix/users/follows?to_id={user_id}', headers={\n                'Client-ID': CLIENT_ID,\n                'Authorization': f'Bearer {token}'\n            })\n            return response.json().get('total', 0)  # Return the total number of followers\n    except Exception as e:\n        print(f'Error fetching follower count for {username}: {e}')\n        return 'N/A'  # Return 'N/A' if there's an error\n\ndef fetch_participants_data():\n    token = get_oauth_token()\n    results = []\n\n    for username in participants:\n        user_data = get_user_data(username, token)\n        if user_data:\n            follower_count = get_follower_count(username, token)\n            results.append({\n                'username': user_data['login'],\n                'followers': follower_count,\n                'createdAt': datetime.fromisoformat(user_data['created_at'].replace('Z', '+00:00')),\n            })\n        else:\n            results.append({\n                'username': username,\n                'followers': 'N/A',\n                'createdAt': 'N/A',\n            })\n        \n        # Introduce a delay to avoid hitting rate limits\n        time.sleep(1)  # Adjust the sleep time as necessary\n\n    # Sort by followers\n    sorted_by_followers = sorted(results, key=lambda x: (x['followers'] == 'N/A', -x['followers'] if isinstance(x['followers'], int) else 0))\n    \n    # Sort by account creation date\n    sorted_by_creation_date = sorted(results, key=lambda x: (x['createdAt'] == 'N/A', x['createdAt'] if isinstance(x['createdAt'], datetime) else datetime.min), reverse=True)\n\n    print('Ranking by Followers:')\n    for result in sorted_by_followers:\n        print(result)\n\n    print('\\nRanking by Account Creation Date:')\n    for result in sorted_by_creation_date:\n        print(result)\n\nif __name__ == '__main__':\n    fetch_participants_data()\n\n"
  },
  {
    "path": "Roadmap/40 - FORTNITE RUBIUS CUP/python/hectorio23.py",
    "content": "# Autor: Héctor Adán\n# GitHub: https://github.com/hectorio23\n\nimport requests\n\n# Función para obtener datos de un usuario de Twitch.\ndef get_twitch_user_data(username, auth_token):\n    url = f\"https://api.twitch.tv/helix/users?login={username}\"\n    headers = {\n        'Client-ID': 'YOUR_CLIENT_ID',\n        'Authorization': f'Bearer {auth_token}'\n    }\n    response = requests.get(url, headers=headers)\n    \n    if response.status_code == 200:\n        data = response.json()['data']\n        if data:\n            return {\n                'username': username,\n                'followers': get_twitch_followers(data[0]['id'], auth_token),\n                'created_at': data[0]['created_at']\n            }\n        else:\n            return {'username': username, 'followers': None, 'created_at': None}\n    else:\n        raise Exception(f\"Error in API request: {response.status_code}\")\n\n# Función para obtener el número de seguidores de un usuario de Twitch.\ndef get_twitch_followers(user_id, auth_token):\n    url = f\"https://api.twitch.tv/helix/users/follows?to_id={user_id}\"\n    headers = {\n        'Client-ID': 'YOUR_CLIENT_ID',\n        'Authorization': f'Bearer {auth_token}'\n    }\n    response = requests.get(url, headers=headers)\n    if response.status_code == 200:\n        return response.json()['total']\n    return None\n\n# Genera el ranking por seguidores y por antigüedad.\ndef generate_rankings(participants, auth_token):\n    user_data = [get_twitch_user_data(user, auth_token) for user in participants]\n    \n    # Ranking por seguidores.\n    by_followers = sorted([u for u in user_data if u['followers'] is not None], key=lambda x: x['followers'], reverse=True)\n    \n    # Ranking por antigüedad.\n    by_creation_date = sorted([u for u in user_data if u['created_at'] is not None], key=lambda x: x['created_at'])\n    \n    return by_followers, by_creation_date\n\n# Ejemplo de uso:\nif __name__ == \"__main__\":\n    participants = [\"user1\", \"user2\", \"user3\"]\n    auth_token = \"YOUR_AUTH_TOKEN\"\n    \n    followers_ranking, creation_ranking = generate_rankings(participants, auth_token)\n    \n    print(\"Ranking por seguidores:\")\n    for user in followers_ranking:\n        print(f\"{user['username']} - {user['followers']} seguidores\")\n\n    print(\"\\nRanking por antigüedad:\")\n    for user in creation_ranking:\n        print(f\"{user['username']} - Creado el {user['created_at']}\")\n"
  },
  {
    "path": "Roadmap/40 - FORTNITE RUBIUS CUP/python/idiegorojas.py",
    "content": "\"\"\"\n# 40 - Fornite Rubius\n\"\"\"\nimport requests\nimport json\nfrom dotenv import load_dotenv\nimport os\nimport time\n\n# Lista de participantes\nparticipants = [\n    \"ABBY\",\"DJMARIIO\", \"KIKO RIVERA\", \"NISSAXTER\", \"SHADOUNE\", \"ACHE\", \"DOBLE\", \"KNEKRO\", \n    \"OLLIE\", \"SILITHUR\", \"ADRI CONTRERAS\", \"ELVISA\", \"KOKO\", \"ORSLOK\", \"SPOKSPONHA\", \n    \"AGUSTIN\", \"ELYAS360\", \"KRONNOZOMBER\", \"OUTCONSUMER\", \"SPREEN\",\"ALEXBY\",\"FOLAGOR\",\n    \"LEVIATHAN\",\"PAPI GAVI\",\"SPURSITO\",\"AMPETER\",\"GREFG\",\"LIT KILLAH\",\"PARACETAMOR\",\n    \"STAXX\",\"ANDER\",\"GUANYAR\",\"LOLA LOLITA\",\"PATICA\",\"SUZYROXX\",\"ARI GAMEPLAYS\",\"HIKA\",\n    \"LOLITO\",\"PAULA GONU\",\"VICENS\",\"ARIGELI\",\"HIPER\",\"LUH\",\"PAUSENPAII\",\"VITUBER\",\n    \"AURONPLAY\",\"IBAI\",\"LUZU\",\"PERXITAA\",\"WERLYB\",\"AXOZER\",\"IBELKY\",\"MANGEL\",\"PLEX\",\n    \"XAVI\",\"BENIJU\",\"ILLOJUAN\",\"MAYICHI\",\"POLISPOL\",\"XCRY\",\"BY CALITOS\",\"IMANTADO\",\n    \"MELO\",\"QUACKITY\",\"XOKAS\",\"BYVIRUZZ\",\"IRINA ISASIA\",\"MISSASINFONIA\",\"RECUERDOP\",\n    \"ZARCORT\",\"CARRERA\",\"JESSKIU\",\"MIXWELL\",\"REVEN\",\"ZELING\",\"CELOPAN\",\"JOPA\",\"MR.JAGGER\",\n    \"RIVERS\",\"ZORMAN\",\"CHEETO\",\"JORDIWILD\",\"NATE GENTILE\",\"ROBERTPG\",\"CRYSTALMOLLY\",\n    \"KENAI SOUZA\",\"NEXXUZ\",\"ROIER\",\"DARIO EMEHACHE\",\"KERORO\",\"NIA\",\"ROJUU\",\"DHEYLO\",\n    \"KIDD KEO\",\"NIL OJEDA\",\"RUBIUS\"\n]\n\n# Cargar credenciales del archivo .env\nload_dotenv()\nCLIENT_ID = os.getenv(\"TWITCH_CLIENT_ID\")\nCLIENT_SECRET = os.getenv(\"TWITCH_CLIENT_SECRET\")\n\n# Validar credenciales\nif not CLIENT_ID or not CLIENT_SECRET:\n    raise ValueError(\"Las credenciales de Twitch no están configuradas en el archivo .env\")\n\ndef get_app_access_token():\n    \"\"\"Obtener el token de acceso para la API de Twitch\"\"\"\n    url = 'https://id.twitch.tv/oauth2/token'\n    params = {\n        \"client_id\": CLIENT_ID,\n        \"client_secret\": CLIENT_SECRET,\n        \"grant_type\": \"client_credentials\"\n    }\n\n    try:\n        response = requests.post(url, params=params)\n        response.raise_for_status()\n        token_data = response.json()\n        access_token = token_data[\"access_token\"]\n        print(\"Token de acceso obtenido correctamente\")\n        return access_token\n    except requests.exceptions.RequestException as e:\n        print(f\"Error al obtener el token: {e}\")\n        return None\n\ndef get_user_info(username, access_token):\n    \"\"\"\n    Obtiene información de un usuario de Twitch incluyendo ID, nombre y fecha de creación\n    \"\"\"\n    url = 'https://api.twitch.tv/helix/users'\n    headers = {\n        'Client-ID': CLIENT_ID,\n        'Authorization': f'Bearer {access_token}'\n    }\n    params = {'login': username.lower()}\n    \n    try:\n        response = requests.get(url, headers=headers, params=params)\n        response.raise_for_status()\n        data = response.json()\n        \n        if data['data'] and len(data['data']) > 0:\n            user = data['data'][0]\n            # Obtener el recuento de seguidores\n            follower_count = get_follower_count(user['id'], access_token)\n            \n            return {\n                'id': user['id'],\n                'display_name': user['display_name'],\n                'followers': follower_count,\n                'created_at': user['created_at']\n            }\n        print(f\"Usuario no encontrado: {username}\")\n        return None\n    except requests.exceptions.RequestException as e:\n        print(f\"Error al consultar {username}: {e}\")\n        return None\n\ndef get_follower_count(user_id, access_token):\n    \"\"\"\n    Obtiene el número de seguidores de un usuario usando su ID\n    \"\"\"\n    url = 'https://api.twitch.tv/helix/users/follows'\n    headers = {\n        'Client-ID': CLIENT_ID,\n        'Authorization': f'Bearer {access_token}'\n    }\n    params = {'to_id': user_id}\n    \n    try:\n        response = requests.get(url, headers=headers, params=params)\n        response.raise_for_status()\n        data = response.json()\n        return data.get('total', 0)\n    except requests.exceptions.RequestException as e:\n        print(f\"Error al obtener seguidores: {e}\")\n        return 0\n\ndef create_rankings(participants, access_token):\n    \"\"\"\n    Crea y muestra rankings de streamers por número de seguidores y antigüedad\n    \"\"\"\n    user_data = []\n    total = len(participants)\n    \n    print(f\"Obteniendo datos de {total} participantes...\")\n    \n    for i, participant in enumerate(participants, 1):\n        print(f\"Procesando ({i}/{total}): {participant}\")\n        info = get_user_info(participant, access_token)\n        \n        if info:\n            user_data.append({\n                'username': participant,\n                'display_name': info['display_name'],\n                'followers': info['followers'],\n                'created_at': info['created_at']\n            })\n        else:\n            user_data.append({\n                'username': participant,\n                'display_name': participant,\n                'followers': 0,\n                'created_at': None\n            })\n        \n        # Añadir pequeña pausa para evitar límites de rate\n        time.sleep(0.5)\n    \n    # Ranking por seguidores (descendente)\n    followers_ranking = sorted(user_data, key=lambda x: x['followers'], reverse=True)\n    print(\"\\nRanking por número de seguidores:\")\n    for i, user in enumerate(followers_ranking, 1):\n        print(f\"{i}. {user['display_name']} - Seguidores: {user['followers']}\")\n    \n    # Ranking por antigüedad (fecha de creación más antigua primero)\n    antiquity_ranking = sorted(\n        user_data, \n        key=lambda x: x['created_at'] or '9999-12-31', \n        reverse=False\n    )\n    print(\"\\nRanking por antigüedad:\")\n    for i, user in enumerate(antiquity_ranking, 1):\n        created_at = user['created_at'] or 'No disponible'\n        print(f\"{i}. {user['display_name']} - Fecha de creación: {created_at}\")\n\ndef main():\n    \"\"\"Función principal\"\"\"\n    # Obtener token de acceso\n    access_token = get_app_access_token()\n    if not access_token:\n        print(\"No se pudo continuar sin token de acceso.\")\n        return\n    \n    # Crear rankings\n    create_rankings(participants, access_token)\n\nif __name__ == '__main__':\n    main()"
  },
  {
    "path": "Roadmap/40 - FORTNITE RUBIUS CUP/python/ignaciovihe.py",
    "content": "\"\"\"\n * EJERCICIO:\n * ¡Rubius tiene su propia skin en Fortnite!\n * Y va a organizar una competición para celebrarlo.\n * Esta es la lista de participantes:\n * https://x.com/Rubiu5/status/1840161450154692876\n *\n * Desarrolla un programa que obtenga el número de seguidores en\n * Twitch de cada participante, la fecha de creación de la cuenta \n * y ordene los resultados en dos listados.\n * - Usa el API de Twitch: https://dev.twitch.tv/docs/api/reference\n *   (NO subas las credenciales de autenticación)\n * - Crea un ranking por número de seguidores y por antigüedad.\n * - Si algún participante no tiene usuario en Twitch, debe reflejarlo.\n\"\"\"\nfrom dotenv import load_dotenv, find_dotenv\nimport os\nimport requests\nimport json\nimport aiohttp #para hacer llamadas a la api de forma asincrona\nimport asyncio\n\n\n# Cargar automáticamente el archivo .env - find_dotenv buscar automaticamente el directorio donde esta el archivo.\nload_dotenv(find_dotenv())\n\n# Obtener las variables de entorno\nCLIENT_ID = os.getenv(\"TWITCH_CLIENT_ID\")\nCLIENT_SECRET = os.getenv(\"TWITCH_CLIENT_SECRET\")\n\n\ndef get_token():\n    #Url para obtener el token de twitch\n    url = \"https://id.twitch.tv/oauth2/token\"\n\n    #Parametros para la llamada \n    params = {\n        \"client_id\": CLIENT_ID,\n        \"client_secret\": CLIENT_SECRET,\n        \"grant_type\": \"client_credentials\"\n    }\n\n    #Llmada post para obtener el token\n    response = requests.post(url, params=params)\n    if response.status_code != 200:\n        raise Exception(\"Error obteniendo el token de Twitch.\")\n    token_data = response.json()\n\n    return token_data['access_token']\n\n\nasync def call_api(session: aiohttp.ClientSession, url, headers):\n    async with session.get(url, headers=headers)as answer:\n        if answer.status != 200:\n            return None\n        else:\n            return await answer.json()# Tiene que esperar a que reciba los datos y los genere, por eso el await.\n\nasync def get_info_users(token: str, users: list):\n\n    usernames_query = \"&\".join([f\"login={user}\" for user in usernames[:100]])\n    users_info_url = f\"https://api.twitch.tv/helix/users?{usernames_query}\"\n\n    headers = {\n    \"Client-ID\": CLIENT_ID,\n    \"Authorization\": f\"Bearer {token}\"\n    }\n\n    async with aiohttp.ClientSession() as session:# Se crea la sesion para llamadas asincronas. Session = request\n        data_users = await call_api(session, users_info_url, headers)\n\n        if data_users:\n            info_users = {\n                streamer[\"display_name\"]:{\n                    \"id\": streamer[\"id\"],\n                    \"fecha\": streamer[\"created_at\"],\n                    \"followers\": 0.0\n                } for streamer in data_users.get(\"data\", [])\n            }\n    return info_users\n\nasync def get_followers(token:str, info_users):\n\n    async with aiohttp.ClientSession() as session:\n\n        headers = {\n        \"Client-ID\": CLIENT_ID,\n        \"Authorization\": f\"Bearer {token}\"\n        }\n\n        tasks = [\n            call_api(session, f\"https://api.twitch.tv/helix/channels/followers?broadcaster_id={info['id']}\", headers)\n            for name, info in info_users.items()\n        ]\n\n        channel_data = await asyncio.gather(*tasks)\n\n        if channel_data:\n            for i, (name, info) in enumerate(info_users.items()):\n                channel = channel_data[i]\n                if channel:\n                    followers = channel[\"total\"]\n                    info[\"followers\"] = followers\n\n        return info_users\n    \n\nasync def get_ranking(participants: list, twitch_users: dict):\n    followers = dict(sorted(twitch_users.items(), key=lambda item: item[1][\"followers\"], reverse=True))\n    old = dict(sorted(twitch_users.items(), key=lambda item: item[1][\"fecha\"]))\n    print(\"Ranking de followers:\")\n    for i, (name, info) in enumerate(followers.items()):\n        print(f\"{i+1}. {name} - {info[\"followers\"]} followers\")\n        participants.remove(name.lower())\n    for name in participants:\n        print(f\"{name} no tiene cuenta de Twitch\")\n    print(\"-----------------------------------\")\n    print(\"Ranking de antiguedad:\")\n    for i, (name, info) in enumerate(old.items()):\n        print(f\"{i+1}. {name} - {info[\"fecha\"]}\")\n    for name in participants:\n        print(f\"{name} no tiene cuenta de Twitch\")\n\n\n\n\n############################################\n\nusernames = [\n    \"littleragergirl\", \"ache\", \"adricontreras4\", \"agustin51\", \"alexby11\", \"ampeterby7\", \"tvander\",\n    \"arigameplays\", \"arigeli_\", \"auronplay\", \"axozer\", \"beniju03\", \"bycalitos\",\n    \"byviruzz\", \"carreraaa\", \"celopan\", \"srcheeto\", \"crystalmolly\", \"darioemehache\",\n    \"dheylo\", \"djmariio\", \"doble\", \"elvisayomastercard\", \"elyas360\", \"folagorlives\", \"thegrefg\",\n    \"guanyar\", \"hika\", \"hiperop\", \"ibai\", \"ibelky_\", \"illojuan\", \"imantado\",\n    \"irinaissaia\", \"jesskiu\", \"jopa\", \"jordiwild\", \"kenaivsouza\", \"mrkeroro10\",\n    \"thekiddkeo95\", \"kikorivera\", \"knekro\", \"kokoop\", \"kronnozomberoficial\", \"leviathan\",\n    \"litkillah\", \"lolalolita\", \"lolitofdez\", \"luh\", \"luzu\", \"mangel\", \"mayichi\",\n    \"melo\", \"missasinfonia\", \"mixwell\", \"jaggerprincesa\", \"nategentile7\", \"nexxuz\",\n    \"lakshartnia\", \"nilojeda\", \"nissaxter\", \"olliegamerz\", \"orslok\", \"outconsumer\", \"papigavitv\",\n    \"paracetamor\", \"patica1999\", \"paulagonu\", \"pausenpaii\", \"perxitaa\", \"nosoyplex\",\n    \"polispol1\", \"quackity\", \"recuerd0p\", \"reventxz\", \"rivers_gg\", \"robertpg\", \"roier\",\n    \"ceuvebrokenheart\", \"rubius\", \"shadoune666\", \"silithur\", \"spok_sponha\", \"elspreen\", \"spursito\",\n    \"bystaxx\", \"suzyroxx\", \"vicens\", \"vitu\", \"werlyb\", \"xavi\", \"xcry\", \"elxokas\",\n    \"thezarcort\", \"zeling\", \"zormanworld\"\n]\n\n\nasync def main():\n    token = get_token()\n    info_users = await get_info_users(token, usernames)\n    info_users = await get_followers(token, info_users)\n    #print(json.dumps(info_users, indent= 4, ensure_ascii=False))\n    await get_ranking(usernames, info_users)\n\n\nasyncio.run(main())"
  },
  {
    "path": "Roadmap/40 - FORTNITE RUBIUS CUP/python/juanppdev.py",
    "content": "\"\"\"\n * EJERCICIO:\n * ¡Rubius tiene su propia skin en Fortnite!\n * Y va a organizar una competición para celebrarlo.\n * Esta es la lista de participantes:\n * https://x.com/Rubiu5/status/1840161450154692876\n *\n * Desarrolla un programa que obtenga el número de seguidores en\n * Twitch de cada participante, la fecha de creación de la cuenta \n * y ordene los resultados en dos listados.\n * - Usa el API de Twitch: https://dev.twitch.tv/docs/api/reference\n *   (NO subas las credenciales de autenticación)\n * - Crea un ranking por número de seguidores y por antigüedad.\n * - Si algún participante no tiene usuario en Twitch, debe reflejarlo.\n\"\"\"\n\nimport requests\n\n# Configura tus credenciales de Twitch\nCLIENT_ID = 'CLIENT_ID'\nCLIENT_SECRET = 'CLIENT_SECRET'\n\n# Obtén el token de acceso\ndef get_access_token(client_id, client_secret):\n    url = 'https://id.twitch.tv/oauth2/token'\n    params = {\n        'client_id': client_id,\n        'client_secret': client_secret,\n        'grant_type': 'client_credentials'\n    }\n    response = requests.post(url, params=params)\n    return response.json()['access_token']\n\n# Obtén la información del usuario de Twitch\ndef get_user_info(username, access_token):\n    url = f'https://api.twitch.tv/helix/users?login={username}'\n    headers = {\n        'Client-ID': CLIENT_ID,\n        'Authorization': f'Bearer {access_token}'\n    }\n    response = requests.get(url, headers=headers)\n    data = response.json()\n    if 'data' in data and data['data']:\n        return data['data'][0]\n    else:\n        return None\n\n# Lista de participantes\nparticipants = [\n    \"abby\", \"djmariio\", \"kiko rivera\", \"nissaxter\", \"shadoune\", \"ache\", \"doble\", \"knekro\",\n    \"ollie\", \"silithur\", \"adri contreras\", \"elvisa\", \"koko\", \"orslok\", \"spokspongha\", \"agustin\",\n    \"elyas360\", \"kronnozomber\", \"outconsumer\", \"spreen\", \"alexby\", \"folagor\", \"leviathan\",\n    \"papi gavi\", \"spursito\", \"ampeter\", \"grefg\", \"lit killah\", \"paracetamor\", \"staxx\", \"ander\",\n    \"guanyar\", \"lola lolita\", \"patica\", \"suzyroxx\", \"ari gameplays\", \"hika\", \"lolito\", \"paula gonu\",\n    \"vicens\", \"arigeli\", \"hiper\", \"luh\", \"pausenpaii\", \"vituber\", \"auronplay\", \"ibai\", \"luzu\",\n    \"perxitaa\", \"werlyb\", \"axozer\", \"ibelky\", \"mangel\", \"plex\", \"xavi\", \"beniju\", \"illojuan\",\n    \"mayichi\", \"polispol\", \"xcry\", \"by calitos\", \"imantado\", \"melo\", \"quackity\", \"xokas\", \"byviruzz\",\n    \"irina isasia\", \"missasinfonia\", \"recuerdop\", \"zarcort\", \"carrera\", \"jesskiu\", \"mixwell\",\n    \"reven\", \"zeling\", \"celopan\", \"jopa\", \"mr.jagger\", \"rivers\", \"zorman\", \"cheeto\", \"jordiwild\",\n    \"nate gentile\", \"robertpg\", \"crystalmolly\", \"kenai souza\", \"nexxuz\", \"roier\", \"dario emehache\",\n    \"keroro\", \"nia\", \"rojuu\", \"dheylo\", \"kidd keo\", \"nil ojeda\", \"rubius\"\n]\n\naccess_token = get_access_token(CLIENT_ID, CLIENT_SECRET)\n\nfollowers_ranking = []\ncreation_date_ranking = []\n\nfor participant in participants:\n    user_info = get_user_info(participant, access_token)\n    if user_info:\n        print(user_info)  # Imprime la información del usuario para verificar las claves disponibles\n        followers_ranking.append((participant, user_info.get('view_count', 'N/A')))\n        creation_date_ranking.append((participant, user_info['created_at']))\n    else:\n        print(f\"{participant} no tiene usuario en Twitch.\")\n\n# Ordenar por número de seguidores (view_count en este caso)\nfollowers_ranking.sort(key=lambda x: x[1], reverse=True)\n\n# Ordenar por fecha de creación\ncreation_date_ranking.sort(key=lambda x: x[1])\n\nprint(\"Ranking por número de seguidores:\")\nfor user in followers_ranking:\n    print(user)\n\nprint(\"\\nRanking por antigüedad:\")\nfor user in creation_date_ranking:\n    print(user)\n"
  },
  {
    "path": "Roadmap/40 - FORTNITE RUBIUS CUP/python/kenysdev.py",
    "content": "# _____________________________________\n# https://github.com/kenysdev\n# 2024 - Python\n# _____________________________________\n# 40 FORTNITE RUBIUS CUP\n# ------------------------------------\n\n\"\"\"\n * EJERCICIO:\n * ¡Rubius tiene su propia skin en Fortnite!\n * Y va a organizar una competición para celebrarlo.\n * Esta es la lista de participantes:\n * https://x.com/Rubiu5/status/1840161450154692876\n *\n * Desarrolla un programa que obtenga el número de seguidores en\n * Twitch de cada participante, la fecha de creación de la cuenta \n * y ordene los resultados en dos listados.\n * - Usa el API de Twitch: https://dev.twitch.tv/docs/api/reference\n *   (NO subas las credenciales de autenticación)\n * - Crea un ranking por número de seguidores y por antigüedad.\n * - Si algún participante no tiene usuario en Twitch, debe reflejarlo.\n\"\"\"\n\nimport asyncio\nfrom os import getenv\n\n# https://pytwitchapi.dev/en/stable/\nfrom twitchAPI.twitch import Twitch\nfrom twitchAPI.helper import first\n\n# https://pypi.org/project/python-dotenv/\nfrom dotenv import load_dotenv\n\nasync def get_user_info(user_name, twitch) -> dict:\n    user = await first(twitch.get_users(logins=user_name))\n    if user is not None:\n        followers = await twitch.get_channel_followers(user.id)\n        return {\"username\": user_name, \"created_at\": user.created_at, \"followers\": followers.total}\n\n    return {}\n\ndef print_rankings(users_data) -> None:\n    sort_by_followers = sorted(users_data, key=lambda x: x[\"followers\"], reverse=True)\n    sort_by_date = sorted(users_data, key=lambda x: x[\"created_at\"])\n\n    print(\"\\nRanking por número de seguidores:\")\n    for i, user, in enumerate(sort_by_followers):\n        print(f\"{i + 1} - {user['username']}: {user['followers']} seguidores\")\n\n    print(\"\\nRanking por antigüedad:\")\n    for i, user, in enumerate(sort_by_date):\n        print(f\"{i + 1} - {user['username']}: Creado el {user['created_at']}\")\n\nasync def main(users) -> None:\n    load_dotenv()\n    twitch = await Twitch(str(getenv(\"TWITCH_CLIENT_ID\")), getenv(\"TWITCH_CLIENT_SECRET\"))\n    users_data = []\n    not_found_users = []\n\n    print(\"Obteniendo datos...\")\n    for name in users:\n        user = await get_user_info(name, twitch)\n        if user:\n            users_data.append(user)\n        else:\n            not_found_users.append(name)\n\n    print_rankings(users_data)\n\n    if not_found_users:\n        print(\"\\nUsuarios no encontrados:\")\n        for user in not_found_users:\n            print(user)\n\nusers = [\n    \"abby\", \"ache\", \"adricontreras\", \"agustin\", \"alexby\", \"ampeter\", \"ander\", \"arigameplays\", \n    \"arigeli\", \"auronplay\", \"axozer\", \"beniju\", \"bycalitos\", \"byviruzz\", \"carrera\", \"celopan\", \n    \"cheeto\", \"crystalmolly\", \"darioemehache\", \"dheyo\",\n    \"djmario\", \"doble\", \"elvisa\", \"elyas360\", \"folagor\", \"grefg\", \"guanyar\", \"hika\", \n    \"hiper\", \"ibai\", \"ibelky\", \"illojuan\", \"imantado\", \"irinaisasia\", \"jesskiu\", \"jopa\", \n    \"jordiwild\", \"kenaisouza\", \"keroro\", \"kiddkeo\",\n    \"kikorivera\", \"knekro\", \"koko\", \"kronnozomber\", \"leviathan\", \"litkillah\", \"lolalolita\", \"lolito\", \n    \"luh\", \"luzu\", \"mangel\", \"mayichi\", \"melo\", \"missasinonia\", \"mixwell\", \"mrjagger\", \n    \"nategentile\", \"nexxuz\", \"nia\", \"nilojeda\",\n    \"nissaxter\", \"ollie\", \"orslok\", \"outconsumer\", \"papigavi\", \"paracetamor\", \"patica\", \"paulagonu\", \n    \"pausenpaii\", \"perxitaa\", \"plex\", \"polispol\", \"quackity\", \"recuerdop\", \"reven\", \"rivers\", \n    \"robertpg\", \"roier\", \"rojuu\", \"rubius\",\n    \"shadoune\", \"silithur\", \"spoksponha\", \"spreen\", \"spursito\", \"staxx\", \"suzyroxx\", \"vicens\", \n    \"vituber\", \"werlyb\", \"xavi\", \"xcry\", \"xokas\", \"zarcort\", \"zeling\", \"zorman\"\n]\n\nasyncio.run(main(users))\n\n"
  },
  {
    "path": "Roadmap/40 - FORTNITE RUBIUS CUP/python/mhayhem.py",
    "content": "# @Author Daniel Grande (Mhayhem)\n\n\n# ¡Rubius tiene su propia skin en Fortnite!\n# Y va a organizar una competición para celebrarlo.\n# Esta es la lista de participantes:\n# https://x.com/Rubiu5/status/1840161450154692876\n#\n# Desarrolla un programa que obtenga el número de seguidores en\n# Twitch de cada participante, la fecha de creación de la cuenta \n# y ordene los resultados en dos listados.\n# - Usa el API de Twitch: https://dev.twitch.tv/docs/api/reference\n#   (NO subas las credenciales de autenticación)\n# - Crea un ranking por número de seguidores y por antigüedad.\n# - Si algún participante no tiene usuario en Twitch, debe reflejarlo.\n\n\nimport os\nimport json\nimport requests\nimport dotenv\nfrom datetime import datetime\n\ndotenv.load_dotenv()\n\nstreamers = [\n    \"abby\",\"ache\",\"adricontreras\",\"agustin\",\"alexby\",\"ampeter\",\n    \"ander\",\"arigameplays\",\"arigeli\",\"auronplay\",\"axocer\",\"beniju\",\"bycalitos\",\"byviruzz\",\"carrera\",\"celopan\",\n    \"cheeto\",\"crystalmolly\",\"darioemehache\",\"dheylo\",\"djmariio\",\"doble\",\"elvisa\",\"elyas360\",\"folagor\",\"grefg\",\n    \"guanyar\",\"hika\",\"hiper\",\"ibai\",\"ibelky\",\"illojuan\",\"imantado\",\"irinaisasia\",\"jesskiu\",\"jopa\",\n    \"jordiwild\",\"kenaisouza\",\"keroro\",\"kiddkeo\",\"kikorivera\",\"knekro\",\"koko\",\"kronnozomber\",\"leviathan\",\"litkillah\",\n    \"lolalolita\",\"lolito\",\"luh\",\"luzu\",\"mangel\",\"mayichi\",\"melo\",\"missasinfonia\",\"mixwell\",\"mrjagger\",\n    \"nategentile\",\"nexxuz\",\"nia\",\"nilojeada\",\"nissaxter\",\"ollie\",\"orslok\",\"outconsumer\",\"papigavi\",\"paracetamor\",\n    \"patica\",\"paulagoonu\",\"pausenpaii\",\"perxitaa\",\"plex\",\"polispol\",\"quackity\",\"recuerdop\",\"reven\",\"rivers\",\n    \"robertpg\",\"roier\",\"rojuu\",\"rubius\",\"shadoune\",\"silithur\",\"spokspohnha\",\"spreen\",\"spursito\",\"staxx\",\n    \"suzyroxx\",\"vicens\",\"vituber\",\"werlyb\",\"xavi\",\"xcry\",\"xokas\",\"zarcort\",\"zeling\",\"zorman\"\n]\n\n\nclass Streamer:\n    def __init__(self, name: str, id: str, followers: int, created_at: str, twitch_user: bool):\n        self.name = name\n        self.id = id\n        self.followers = followers\n        self.created_at = created_at\n        self.twitch_user = twitch_user\n    \n    def __str__(self):\n        if not self.twitch_user:\n            return f\"Nombre: {self.name}, No es usuario de Twitch.\"\n        return f\"Nombre: {self.name}, seguidores: {self.followers}, año de creación: {self.created_at}\"\n\ndef credentials(token: str) -> dict:\n    headers = {\n        \"Authorization\": f\"Bearer {token}\",\n        \"Client-Id\": os.getenv(\"CLIENT_ID\")\n    }\n    \n    return headers\n\ndef get_token_api() -> str:\n    \n    url = \"https://id.twitch.tv/oauth2/token\"\n    \n    data = {\n        \"client_id\": os.getenv(\"CLIENT_ID\"),\n        \"client_secret\": os.getenv(\"CLIENT_SECRET\"),\n        \"grant_type\": \"client_credentials\"\n    }\n    \n    response = requests.post(url, data=data)\n    if response.status_code != 200:\n        raise Exception(f\"ERROR: No se ha obtenido el token. {response.text}.\")\n    token_info = response.json()\n    return token_info[\"access_token\"]\n\ndef get_channel_info(array: list, headers: dict) -> list:\n    \n    for item in array:\n        if item.twitch_user:\n            url = f\"https://api.twitch.tv/helix/channels/followers?broadcaster_id={item.id}\"\n    \n            response = requests.get(url, headers=headers)\n            if response.status_code != 200:\n                return response.status_code\n            \n            info = response.json()\n            item.followers = info['total']\n    \n    return array\n\ndef get_user_info(array: list, headers: dict) -> list:\n    participants_object = []\n    login_user = {}\n    for i in range(0, len(array), 50):\n        block = array[i:i + 50]\n        params = [(\"login\", name) for name in block]\n        url = f\"https://api.twitch.tv/helix/users\"\n        response = requests.get(url, headers=headers, params=params)\n        info = response.json()\n        login_user.update({\n            user['login']: user\n            for user in info['data']\n        })\n    \n    \n    \n    for name in array:\n        if name in login_user:\n            data = login_user[name]\n            date = datetime.strptime(data['created_at'], \"%Y-%m-%dT%H:%M:%SZ\")\n            format_date = date.strftime((\"%Y/%m/%d\"))\n            streamer = Streamer(\n                data['login'],\n                data['id'],\n                0,\n                format_date,\n                True\n            )\n        else:\n            streamer = Streamer(name, None, None, None, False)\n        participants_object.append(streamer)\n    return participants_object\n\ndef separete_user_active(array: list) -> list:\n    inactive_users = [item for item in array if not item.twitch_user]\n    active_users = [item for item in array if item.twitch_user]\n    \n    return active_users, inactive_users\n\ndef followers_ranking(array: list) -> list:\n    folowers_ranking = sorted(array, key=lambda x: x.followers)\n    \n    return folowers_ranking\n\ndef senority_ranking(array: list) -> list:\n    senority_ranking = sorted(array, key=lambda x: datetime.strptime(x.created_at), reverse=False)\n    return senority_ranking\n\ndef display_Rankings(arrayf: list, arrays: list, arrayi: list):\n    positionf = 1\n    print(\"Ranking por seguidores:\\n\")\n    for item in arrayf:\n        print(f\"{positionf}- {item.name} {item.followers}.\\n\")\n        positionf += 1\n    print(\"Ranking por antigüedad:\\n\")\n    positions = 1\n    for item in arrays:\n        print(f\"{positions}- {item.name} {item.created_at}\\n\")\n        positions += 1\n    print(\"Aquí los usuarios sin twitch:\\n\")\n    for item in arrayi:\n        print(f\"{item.name}\\n\")\n\ntry:\n    headers = credentials(get_token_api())\n    participants = get_user_info(streamers, headers)\n    participants_update = get_channel_info(participants, headers)\n    active, inactive = separete_user_active(participants_update)\n    followers = followers_ranking(active)\n    senority = senority_ranking(active)\n    display_Rankings(followers, senority, inactive)\nexcept TimeoutError:\n    print(\"Tiempo excedido\")"
  },
  {
    "path": "Roadmap/40 - FORTNITE RUBIUS CUP/python/miguelex.py",
    "content": "import requests\nimport urllib.parse\n\ndef obtener_token_oauth(client_id, client_secret):\n    url = 'https://id.twitch.tv/oauth2/token'\n    \n    data = {\n        'client_id': client_id,\n        'client_secret': client_secret,\n        'grant_type': 'client_credentials'\n    }\n\n    response = requests.post(url, data=data)\n\n    if response.status_code != 200:\n        raise Exception('Error al obtener el token OAuth')\n\n    result = response.json()\n    return result['access_token']\n\ndef obtener_info_usuario_twitch(access_token, client_id, username):\n    username = ''.join([c for c in username if c.isalnum() or c == '_'])\n    url = f\"https://api.twitch.tv/helix/users?login={urllib.parse.quote(username)}\"\n    \n    headers = {\n        'Authorization': f'Bearer {access_token}',\n        'Client-ID': client_id\n    }\n\n    response = requests.get(url, headers=headers)\n\n    if response.status_code != 200:\n        return None\n\n    result = response.json()\n    return result['data'][0] if 'data' in result and result['data'] else None\n\ndef obtener_numero_seguidores_twitch(access_token, client_id, user_id):\n    url = f\"https://api.twitch.tv/helix/channels/followers?broadcaster_id={user_id}\"\n\n    headers = {\n        'Authorization': f'Bearer {access_token}',\n        'Client-ID': client_id\n    }\n\n    response = requests.get(url, headers=headers)\n\n    if response.status_code != 200:\n        return 0\n\n    result = response.json()\n    return result.get('total', 0)\n\ndef main():\n    participantes = [\n        'Abby', 'Ache', 'Adri Contreras', 'Agustin', 'Alexby', 'Ampeter', 'Ander', 'Ari Gameplays',\n        'Arigely', 'Auronplay', 'Axozer', 'Beniju', 'By Calitos', 'Byviruzz', 'Carrera', 'Celopan',\n        'Cheto', 'CrystalMolly', 'Dario Eme Hache', 'Dheyo', 'DjMariio', 'Doble', 'Elvisa', 'Elyas360',\n        'Folagor', 'Grefg', 'Guanyar', 'Hika', 'Hiper', 'Ibai', 'Ibelky', 'Illojuan', 'Imantado',\n        'Irina Isasia', 'JessKiu', 'Jopa', 'JordiWild', 'Kenai Souza', 'Keroro', 'Kidd Keo', 'Kiko Rivera',\n        'Knekro', 'Koko', 'KronnoZomber', 'Leviathan', 'Lit Killah', 'Lola Lolita', 'Lolito', 'Luh',\n        'Luzu', 'Mangel', 'Mayichi', 'Melo', 'MissaSinfonia', 'Mixwell', 'Mr. Jagger', 'Nate Gentile',\n        'Nexxuz', 'Nia', 'Nil Ojeda', 'NissaXter', 'Ollie', 'Orslok', 'Outconsumer', 'Papi Gavi',\n        'Paracetamor', 'Patica', 'Paula Gonu', 'Pausenpaii', 'Perxitaa', 'Plex', 'Polispol', 'Quackity',\n        'RecueroDP', 'Reven', 'Rivers', 'RobertPG', 'Roier', 'Rojuu', 'Rubius', 'Shadoune', 'Silithur',\n        'SpokSponha', 'Spreen', 'Spursito', 'Staxx', 'SuzyRoxx', 'Vicens', 'Vituber', 'Werlyb', 'Xavi',\n        'Xcry', 'Xokas', 'Zarcort', 'Zeling', 'Zorman'\n    ]\n\n    client_id = 'TU_ID_DE_CLIENTE'\n    client_secret = 'TU_SECRETO_DE_CLIENTE'\n\n    try:\n        access_token = obtener_token_oauth(client_id, client_secret)\n        \n        info_usuarios = []\n        errores = []\n\n        for participante in participantes:\n            usuario = obtener_info_usuario_twitch(access_token, client_id, participante)\n\n            if usuario:\n                seguidores = obtener_numero_seguidores_twitch(access_token, client_id, usuario['id'])\n\n                info_usuarios.append({\n                    'username': usuario['display_name'],\n                    'followers': seguidores,\n                    'creation_date': usuario['created_at']\n                })\n            else:\n                errores.append(f\"El participante {participante} no tiene usuario en Twitch.\")\n\n        # Ordenar por número de seguidores\n        ranking_por_seguidores = sorted(info_usuarios, key=lambda u: u['followers'], reverse=True)\n\n        print(\"Ranking por número de seguidores:\")\n        for usuario in ranking_por_seguidores:\n            print(f\"{usuario['username']} - {usuario['followers']} seguidores\")\n\n        # Ordenar por antigüedad\n        ranking_por_antiguedad = sorted(info_usuarios, key=lambda u: u['creation_date'])\n\n        print(\"\\nRanking por antigüedad de la cuenta:\")\n        for usuario in ranking_por_antiguedad:\n            print(f\"{usuario['username']} - Cuenta creada el {usuario['creation_date']}\")\n\n        if errores:\n            print(\"\\nErrores:\")\n            for error in errores:\n                print(error)\n\n    except Exception as e:\n        print(f'Error: {str(e)}')\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/40 - FORTNITE RUBIUS CUP/python/mouredev.py",
    "content": "import requests\n\n\ndef get_access_token(client_id: str, client_secret: str) -> str:\n    url = \"https://id.twitch.tv/oauth2/token\"\n    params = {\n        \"client_id\": client_id,\n        \"client_secret\": client_secret,\n        \"grant_type\": \"client_credentials\"\n    }\n    response = requests.post(url, params=params)\n    response.raise_for_status()\n    return response.json().get(\"access_token\")\n\n\ndef get_user_info(token: str, client_id: str, login: str):\n    url = \"https://api.twitch.tv/helix/users\"\n    headers = {\n        \"Authorization\": f\"Bearer {token}\",\n        \"Client-Id\": client_id\n    }\n    params = {\"login\": login}\n    response = requests.get(url, headers=headers, params=params)\n    response.raise_for_status()\n    data = response.json().get(\"data\", None)\n\n    if not data:\n        return None\n\n    return data[0]\n\n\ndef get_total_followers(token: str, client_id: str, id: str) -> int:\n    url = \"https://api.twitch.tv/helix/channels/followers\"\n    headers = {\n        \"Authorization\": f\"Bearer {token}\",\n        \"Client-Id\": client_id\n    }\n    params = {\"broadcaster_id\": id}\n    response = requests.get(url, headers=headers, params=params)\n    response.raise_for_status()\n    return response.json().get(\"total\", 0)\n\n\nCLIENT_ID = \"mi_client_id\"\nCLIENT_SECRET = \"mi_client_secret\"\n\nusers = [\n    \"littleragergirl\", \"ache\", \"adricontreras4\", \"agustin51\", \"alexby11\", \"ampeterby7\", \"tvander\",\n    \"arigameplays\", \"arigeli_\", \"auronplay\", \"axozer\", \"beniju03\", \"bycalitos\",\n    \"byviruzz\", \"carreraaa\", \"celopan\", \"srcheeto\", \"crystalmolly\", \"darioemehache\",\n    \"dheylo\", \"djmariio\", \"doble\", \"elvisayomastercard\", \"elyas360\", \"folagorlives\", \"thegrefg\",\n    \"guanyar\", \"hika\", \"hiperop\", \"ibai\", \"ibelky_\", \"illojuan\", \"imantado\",\n    \"irinaissaia\", \"jesskiu\", \"jopa\", \"jordiwild\", \"kenaivsouza\", \"mrkeroro10\",\n    \"thekiddkeo95\", \"kikorivera\", \"knekro\", \"kokoop\", \"kronnozomberoficial\", \"leviathan\",\n    \"litkillah\", \"lolalolita\", \"lolitofdez\", \"luh\", \"luzu\", \"mangel\", \"mayichi\",\n    \"melo\", \"missasinfonia\", \"mixwell\", \"jaggerprincesa\", \"nategentile7\", \"nexxuz\",\n    \"lakshartnia\", \"nilojeda\", \"nissaxter\", \"olliegamerz\", \"orslok\", \"outconsumer\", \"papigavitv\",\n    \"paracetamor\", \"patica1999\", \"paulagonu\", \"pausenpaii\", \"perxitaa\", \"nosoyplex\",\n    \"polispol1\", \"quackity\", \"recuerd0p\", \"reventxz\", \"rivers_gg\", \"robertpg\", \"roier\",\n    \"ceuvebrokenheart\", \"rubius\", \"shadoune666\", \"silithur\", \"spok_sponha\", \"elspreen\", \"spursito\",\n    \"bystaxx\", \"suzyroxx\", \"vicens\", \"vitu\", \"werlyb\", \"xavi\", \"xcry\", \"elxokas\",\n    \"thezarcort\", \"zeling\", \"zormanworld\", \"mouredev\"\n]\nusers_data = []\nnot_found_users = []\n\ntoken = get_access_token(CLIENT_ID, CLIENT_SECRET)\n\nfor username in users:\n\n    user = get_user_info(token, CLIENT_ID, username)\n\n    if user is None:\n        not_found_users.append(username)\n    else:\n        followers = get_total_followers(token, CLIENT_ID, user[\"id\"])\n        users_data.append({\n            \"username\": username,\n            \"created_at\": user[\"created_at\"],\n            \"followers\": followers\n        })\n\nsort_by_followers = sorted(\n    users_data, key=lambda x: x[\"followers\"], reverse=True)\n\nsort_by_date = sorted(\n    users_data, key=lambda x: x[\"created_at\"])\n\nprint(\"\\nRanking por número de seguidores:\")\nfor id, user, in enumerate(sort_by_followers):\n    print(f\"{id + 1} - {user[\"username\"]}: {user[\"followers\"]} seguidores\")\n\nprint(\"\\nRanking por antigüedad:\")\nfor id, user, in enumerate(sort_by_date):\n    print(f\"{id + 1} - {user[\"username\"]}: Creado el {user[\"created_at\"]}\")\n\nif not_found_users:\n    print(\"\\nUsuarios no encontrados:\")\n    for user in not_found_users:\n        print(user)\n"
  },
  {
    "path": "Roadmap/40 - FORTNITE RUBIUS CUP/python/neslarra.py",
    "content": "import twitch\nfrom datetime import timedelta\nimport requests\n\n\nmy_id = input(\"Ingresar nro cliente: \")\nmy_secret = input(\"Ingresar secret: \")\n\nmy_twitch = twitch.Helix(my_id, my_secret, use_cache=True, cache_duration=timedelta(minutes=10))\nusers = [\n    \"littleragergirl\", \"ache\", \"adricontreras4\", \"agustin51\", \"alexby11\", \"ampeterby7\", \"tvander\",\n    \"arigameplays\", \"arigeli_\", \"auronplay\", \"axozer\", \"beniju03\", \"bycalitos\",\n    \"byviruzz\", \"carreraaa\", \"celopan\", \"srcheeto\", \"crystalmolly\", \"darioemehache\",\n    \"dheylo\", \"djmariio\", \"doble\", \"elvisayomastercard\", \"elyas360\", \"folagorlives\", \"thegrefg\",\n    \"guanyar\", \"hika\", \"hiperop\", \"ibai\", \"ibelky_\", \"illojuan\", \"imantado\",\n    \"irinaissaia\", \"jesskiu\", \"jopa\", \"jordiwild\", \"kenaivsouza\", \"mrkeroro10\",\n    \"thekiddkeo95\", \"kikorivera\", \"knekro\", \"kokoop\", \"kronnozomberoficial\", \"leviathan\",\n    \"litkillah\", \"lolalolita\", \"lolitofdez\", \"luh\", \"luzu\", \"mangel\", \"mayichi\",\n    \"melo\", \"missasinfonia\", \"mixwell\", \"jaggerprincesa\", \"nategentile7\", \"nexxuz\",\n    \"lakshartnia\", \"nilojeda\", \"nissaxter\", \"olliegamerz\", \"orslok\", \"outconsumer\", \"papigavitv\",\n    \"paracetamor\", \"patica1999\", \"paulagonu\", \"pausenpaii\", \"perxitaa\", \"nosoyplex\",\n    \"polispol1\", \"quackity\", \"recuerd0p\", \"reventxz\", \"rivers_gg\", \"robertpg\", \"roier\",\n    \"ceuvebrokenheart\", \"rubius\", \"shadoune666\", \"silithur\", \"spok_sponha\", \"elspreen\", \"spursito\",\n    \"bystaxx\", \"suzyroxx\", \"vicens\", \"vitu\", \"werlyb\", \"xavi\", \"xcry\", \"elxokas\",\n    \"thezarcort\", \"zeling\", \"zormanworld\", \"mouredev\"\n]\n\nurl_token = \"https://id.twitch.tv/oauth2/token\"\nresponse = requests.post(url_token, params={\"client_id\": my_id, \"client_secret\": my_secret, \"grant_type\": \"client_credentials\"})\nresponse.raise_for_status()\ntoken = response.json().get(\"access_token\")\n\nurl_followers = \"https://api.twitch.tv/helix/channels/followers\"\n\nusers_data = []\nfor user in my_twitch.users(users):\n    dict_ = {\"name\": user.display_name, \"id\": user.id, \"created\": user.created_at, \"followers\": 0}\n    params = {\"broadcaster_id\": id}\n    response = requests.get(url_followers, headers={\"Authorization\": f\"Bearer {token}\", \"Client-Id\": my_id}, params={\"broadcaster_id\": user.id})\n    response.raise_for_status()\n    dict_[\"followers\"] = response.json().get(\"total\", 0)\n    users_data.append(dict_)\n\nprint(\"\\nOrdenado por cantidad ed seguidores\")\nfor x in sorted(users_data, key=lambda x: x[\"followers\"], reverse=True):\n    print(x)\nprint(\"\\n\\nOrednado por antigüedad\")\nfor x in sorted(users_data, key=lambda x: x[\"created\"]):\n    print(x)\nprint(\"\\n\\nUsuarios que no se encontraron\")\nprint([x for x in users if x not in [y[\"name\"].lower() for y in users_data]])\n"
  },
  {
    "path": "Roadmap/40 - FORTNITE RUBIUS CUP/python/oriaj3.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * ¡Rubius tiene su propia skin en Fortnite!\n * Y va a organizar una competición para celebrarlo.\n * Esta es la lista de participantes:\n * https://x.com/Rubiu5/status/1840161450154692876\n *\n * Desarrolla un programa que obtenga el número de seguidores en\n * Twitch de cada participante, la fecha de creación de la cuenta \n * y ordene los resultados en dos listados.\n * - Usa el API de Twitch: https://dev.twitch.tv/docs/api/reference\n *   (NO subas las credenciales de autenticación)\n * - Crea un ranking por número de seguidores y por antigüedad.\n * - Si algún participante no tiene usuario en Twitch, debe reflejarlo.\n */\n\"\"\"\nimport requests\nimport os\nfrom dotenv import load_dotenv\n\nload_dotenv()\n\nCLIENT_ID = os.getenv(\"TWITCH_CLIENT_ID\")\nCLIENT_SECRET = os.getenv(\"TWITCH_CLIENT_SECRET\")\n\n\"\"\"\ncurl -X POST 'https://id.twitch.tv/oauth2/token' \\\n-H 'Content-Type: application/x-www-form-urlencoded' \\\n-d 'client_id=<your client id goes here>&client_secret=<your client secret goes here>&grant_type=client_credentials'\n\"\"\"\ndef get_access_token(client_id: str, client_secret: str) -> str:\n    url = \"https://id.twitch.tv/oauth2/token\"\n    data = {\n        \"client_id\": client_id,\n        \"client_secret\": client_secret,\n        \"grant_type\": \"client_credentials\"\n    }\n    \n    response = requests.post(url=url, data=data)\n\n    #Verificar si la respuesta es correcta, se puede hacer con response.raise_for_status() también\n    if response.status_code == 200:\n        token_data = response.json()\n        return token_data.get(\"access_token\")\n    else:\n        print(f\"Error: Unable to get access token. Status Code {response.status_code}.\")\n        return None\n\"\"\"\ncurl -X GET 'https://api.twitch.tv/helix/users?id=141981764' \\\n-H 'Authorization: Bearer cfabdegwdoklmawdzdo98xt2fo512y' \\\n-H 'Client-Id: uo6dggojyb8d6soh92zknwmi5ej1q2'\n\"\"\"\ndef get_user_info(token: str, client_id: str, login: str):\n    url = \"https://api.twitch.tv/helix/users\"\n    headers = {\n        \"Authorization\": f\"Bearer {token}\", \n        \"Client-Id\": client_id\n    }\n    params = {\"login\": login}\n\n    response = requests.get(url=url, headers=headers, params=params)\n    response.raise_for_status()\n    data = response.json().get(\"data\", []) #Si no hay data, devolver lista vacía, lo hace el \", [])\"\n    if not data:\n        return None\n    \n    return data[0]\n\n\"\"\"\ncurl -X GET 'https://api.twitch.tv/helix/channels/followers?broadcaster_id=123456' \\\n-H 'Authorization: Bearer kpvy3cjboyptmiacwr0c19hotn5s' \\\n-H 'Client-Id: hof5gwx0su6owfn0nyan9c87zr6t'\n\"\"\"\ndef get_user_followers(token: str, client_id: str, user_id: str) -> int:\n    url = \"https://api.twitch.tv/helix/channels/followers\"\n    headers = {\n        \"Authorization\": f\"Bearer {token}\", \n        \"Client-Id\": client_id\n    }\n    params = {\"broadcaster_id\": user_id}\n    response = requests.get(url=url, headers=headers, params=params)\n    response.raise_for_status()\n    return response.json().get(\"total\", 0)\n\nusers = [\n    \"littleragergirl\", \"ache\", \"adricontreras4\", \"agustin51\", \"alexby11\", \"ampeterby7\", \"tvander\",\n    \"arigameplays\", \"arigeli_\", \"auronplay\", \"axozer\", \"beniju03\", \"bycalitos\",\n    \"byviruzz\", \"carreraaa\", \"celopan\", \"srcheeto\", \"crystalmolly\", \"darioemehache\",\n    \"dheylo\", \"djmariio\", \"doble\", \"elvisayomastercard\", \"elyas360\", \"folagorlives\", \"thegrefg\",\n    \"guanyar\", \"hika\", \"hiperop\", \"ibai\", \"ibelky_\", \"illojuan\", \"imantado\",\n    \"irinaissaia\", \"jesskiu\", \"jopa\", \"jordiwild\", \"kenaivsouza\", \"mrkeroro10\",\n    \"thekiddkeo95\", \"kikorivera\", \"knekro\", \"kokoop\", \"kronnozomberoficial\", \"leviathan\",\n    \"litkillah\", \"lolalolita\", \"lolitofdez\", \"luh\", \"luzu\", \"mangel\", \"mayichi\",\n    \"melo\", \"missasinfonia\", \"mixwell\", \"jaggerprincesa\", \"nategentile7\", \"nexxuz\",\n    \"lakshartnia\", \"nilojeda\", \"nissaxter\", \"olliegamerz\", \"orslok\", \"outconsumer\", \"papigavitv\",\n    \"paracetamor\", \"patica1999\", \"paulagonu\", \"pausenpaii\", \"perxitaa\", \"nosoyplex\",\n    \"polispol1\", \"quackity\", \"recuerd0p\", \"reventxz\", \"rivers_gg\", \"robertpg\", \"roier\",\n    \"ceuvebrokenheart\", \"rubius\", \"shadoune666\", \"silithur\", \"spok_sponha\", \"elspreen\", \"spursito\",\n    \"bystaxx\", \"suzyroxx\", \"vicens\", \"vitu\", \"werlyb\", \"xavi\", \"xcry\", \"elxokas\",\n    \"thezarcort\", \"zeling\", \"zormanworld\", \"mouredev\"\n]\nusers_data = []\nnot_found_users = []\n\nTOKEN = get_access_token(CLIENT_ID, CLIENT_SECRET)\n\nfor user_name in users:\n    user = get_user_info(TOKEN, CLIENT_ID, user_name)\n    if user is None:\n        not_found_users.append(user_name)\n    else:\n\n        followers = get_user_followers(TOKEN, CLIENT_ID, user.get(\"id\"))\n        users_data.append({  \n                \"username\": user_name,\n                \"created_at\": user.get(\"created_at\"),\n                \"followers\": followers\n            })\n        \n#Usuarios no encontrados\nprint (not_found_users)\n\n#Ordenar por seguidores\nusers_data.sort(key=lambda x: x[\"followers\"], reverse=True)\n\nprint(\"Ranking por seguidores:\")\nfor id, user, in enumerate(users_data):\n    print(f\"{id + 1} - {user['username']}: {user['followers']} seguidores\")\n\n#Ordenar por antigüedad\nusers_data.sort(key=lambda x: x[\"created_at\"])\n\nprint(\"Ranking por antigüedad:\")\nfor id, user, in enumerate(users_data):\n    print(f\"{id + 1} - {user['username']}: {user['created_at']}\")\n\n\n\n\n"
  },
  {
    "path": "Roadmap/40 - FORTNITE RUBIUS CUP/python/raulG91.py",
    "content": "import requests\nimport json\nfrom datetime import datetime\nimport urllib.parse \n\nclient_id = \"Your ID\"\nclient_secret = \"Your secret\"\n\ndef getToken():\n    headers = {'Content-Type': 'application/x-www-form-urlencoded'}\n    data = {\n        'grant_type': 'client_credentials',\n        'client_secret': client_secret,\n        'client_id': client_id\n    }\n    try:\n        result = requests.post(\"https://id.twitch.tv/oauth2/token\",headers=headers,data=data)\n        if result.status_code == 200:\n            return result.json()['access_token']\n        else:\n            return None\n    except Exception as err:\n        print(\"Error getting token: \")\n\ndef getInfo(users:list):\n    \n    #Get token\n    token = getToken()\n\n    users_info = []\n    for user in users:\n        user_name = str(user).replace(\" \",\"\")\n        user_name = urllib.parse.quote_plus(user_name)\n        #Get Twicth profile for user\n        query = f'?login={user_name}'\n        header = {\n            'Authorization': f'Bearer {token}',\n            'Client-Id': client_id\n        }\n        try:\n            #Get channel general info\n            result = requests.get('https://api.twitch.tv/helix/users'+query,headers=header)\n            if result.status_code == 200:\n                user_info = result.json()\n                broadcaster_id = user_info['data'][0]['id']\n                created_at = user_info['data'][0]['created_at']\n                #Get followers \n                query = f'?broadcaster_id={broadcaster_id}'\n                result = requests.get(\"https://api.twitch.tv/helix/channels/followers\"+query,headers=header)\n                followers = 0\n                if result.status_code == 200:\n                    followers = result.json()['total']    \n                else:\n                    print(f'Error getting followers for {user_name}')    \n                user_info =  {\n                    'user_name': user,\n                    'followers': followers,\n                    'creation_date': created_at\n                }\n                users_info.append(user_info)\n    \n            else:\n                 print(f'Error obteniendo cuenta de twitch para {user} con status: {result.status_code}')     \n        except:\n            print(f'Error obteniendo cuenta twicth para: {user}')\n\n    return users_info     \n\ndef order_by_followers(users:list):\n    #Order list by followers descending\n    new_list = sorted(users,key=lambda x: x['followers'],reverse=True)\n    return new_list\n\ndef order_by_creation_date(users:list):\n    new_list = sorted(users,key=lambda user: user['creation_date'],reverse=True)\n    return new_list\n\nusers = [\n        'Abby', 'Ache', 'Adri Contreras', 'Agustin', 'Alexby', 'Ampeter', 'Ander', 'Ari Gameplays',\n        'Arigely', 'Auronplay', 'Axozer', 'Beniju', 'By Calitos', 'Byviruzz', 'Carrera', 'Celopan',\n        'Cheto', 'CrystalMolly', 'Dario Eme Hache', 'Dheyo', 'DjMariio', 'Doble', 'Elvisa', 'Elyas360',\n        'Folagor', 'Grefg', 'Guanyar', 'Hika', 'Hiper', 'Ibai', 'Ibelky', 'Illojuan', 'Imantado',\n        'Irina Isasia', 'JessKiu', 'Jopa', 'JordiWild', 'Kenai Souza', 'Keroro', 'Kidd Keo', 'Kiko Rivera',\n        'Knekro', 'Koko', 'KronnoZomber', 'Leviathan', 'Lit Killah', 'Lola Lolita', 'Lolito', 'Luh',\n        'Luzu', 'Mangel', 'Mayichi', 'Melo', 'MissaSinfonia', 'Mixwell', 'Mr. Jagger', 'Nate Gentile',\n        'Nexxuz', 'Nia', 'Nil Ojeda', 'NissaXter', 'Ollie', 'Orslok', 'Outconsumer', 'Papi Gavi',\n        'Paracetamor', 'Patica', 'Paula Gonu', 'Pausenpaii', 'Perxitaa', 'Plex', 'Polispol', 'Quackity',\n        'RecueroDP', 'Reven', 'Rivers', 'RobertPG', 'Roier', 'Rojuu', 'Rubius', 'Shadoune', 'Silithur',\n        'SpokSponha', 'Spreen', 'Spursito', 'Staxx', 'SuzyRoxx', 'Vicens', 'Vituber', 'Werlyb', 'Xavi',\n        'Xcry', 'Xokas', 'Zarcort', 'Zeling', 'Zorman'\n    ]\nusers_info = getInfo(users)\n\norder_followers = order_by_followers(users_info)\nprint(\"Participantes ordenados por numero de followers\")\nfor element in order_followers:\n    print(f'User: {element['user_name']} followers: {element['followers']}')\n\nlist_order_creation = order_by_creation_date(users_info)\nprint(\"Participantes ordenados por fecha de creacion del canal\")\nfor element in list_order_creation:\n    print(f'User {element['user_name']} creation date: {element['creation_date']}')    "
  },
  {
    "path": "Roadmap/40 - FORTNITE RUBIUS CUP/python/rigo93acosta.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * ¡Rubius tiene su propia skin en Fortnite!\n * Y va a organizar una competición para celebrarlo.\n * Esta es la lista de participantes:\n * https://x.com/Rubiu5/status/1840161450154692876\n *\n * Desarrolla un programa que obtenga el número de seguidores en\n * Twitch de cada participante, la fecha de creación de la cuenta \n * y ordene los resultados en dos listados.\n * - Usa el API de Twitch: https://dev.twitch.tv/docs/api/reference\n *   (NO subas las credenciales de autenticación)\n * - Crea un ranking por número de seguidores y por antigüedad.\n * - Si algún participante no tiene usuario en Twitch, debe reflejarlo.\n */\n\"\"\"\n\n\"\"\"\nTasks:\n1. Get the list of participants from the URL\n2. Get the number of followers in Twitch for each participant\n3. Get the account creation date for each participant\n4. Sort the results by number of followers and by account creation date.\n\"\"\"\n\n## TODO: Borrar luego\nCLIENT_ID = ''\nCLIENT_SECRET = ''\n\nimport requests\n\n\"\"\"\ncurl -X POST 'https://id.twitch.tv/oauth2/token' \\\n-H 'Content-Type: application/x-www-form-urlencoded' \\\n-d 'client_id=<your client id goes here>&client_secret=<your client secret goes here>&grant_type=client_credentials'\n\"\"\"\ndef get_access_token(client_id: str, client_secret: str) -> str:\n    url = 'https://id.twitch.tv/oauth2/token'\n    params = {\n        'client_id': client_id,\n        'client_secret': client_secret,\n        'grant_type': 'client_credentials'\n    }\n    \n    response = requests.post(url, params=params)\n    response.raise_for_status()\n    response = response.json().get(\"access_token\")\n    return response\n\n\n\"\"\"\ncurl -X GET 'https://api.twitch.tv/helix/users?id=141981764' \\\n-H 'Authorization: Bearer cfabdegwdoklmawdzdo98xt2fo512y' \\\n-H 'Client-Id: uo6dggojyb8d6soh92zknwmi5ej1q2'\n\"\"\"\ndef get_user_info(access_token: str, client_id: str, login: str):\n    \n    url = f'https://api.twitch.tv/helix/users'\n    params ={\"login\": login}\n    headers = {\n        'Authorization': f\"Bearer {access_token}\",\n        \"Client-Id\": client_id\n        }\n    \n    response = requests.get(url, headers=headers, params=params)\n    response.raise_for_status()\n    data = response.json().get(\"data\", None)\n\n    if not data:\n        return None\n    \n    return data[0]\n\n\"\"\"\ncurl -X GET 'https://api.twitch.tv/helix/channels/followers?broadcaster_id=123456' \\\n-H 'Authorization: Bearer kpvy3cjboyptmiacwr0c19hotn5s' \\\n-H 'Client-Id: hof5gwx0su6owfn0nyan9c87zr6t'\n\"\"\"\ndef get_followers(access_token: str, client_id: str, user_id: str) -> int:\n        \n        url = f'https://api.twitch.tv/helix/channels/followers'\n        params ={\"broadcaster_id\": user_id}\n        headers = {\n            'Authorization': f\"Bearer {access_token}\",\n            \"Client-Id\": client_id\n        }\n\n        response = requests.get(url, headers=headers, params=params)\n        response.raise_for_status()\n        return response.json().get(\"total\", 0)\n\n\nif __name__ == '__main__':\n\n    # users = ['rubius', 'ibai', 'mouredev']\n    users = [\n        \"littleragergirl\", \"ache\", \"adricontreras4\", \"agustin51\", \"alexby11\", \"ampeterby7\", \"tvander\",\n        \"arigameplays\", \"arigeli_\", \"auronplay\", \"axozer\", \"beniju03\", \"bycalitos\",\n        \"byviruzz\", \"carreraaa\", \"celopan\", \"srcheeto\", \"crystalmolly\", \"darioemehache\",\n        \"dheylo\", \"djmariio\", \"doble\", \"elvisayomastercard\", \"elyas360\", \"folagorlives\", \"thegrefg\",\n        \"guanyar\", \"hika\", \"hiperop\", \"ibai\", \"ibelky_\", \"illojuan\", \"imantado\",\n        \"irinaissaia\", \"jesskiu\", \"jopa\", \"jordiwild\", \"kenaivsouza\", \"mrkeroro10\",\n        \"thekiddkeo95\", \"kikorivera\", \"knekro\", \"kokoop\", \"kronnozomberoficial\", \"leviathan\",\n        \"litkillah\", \"lolalolita\", \"lolitofdez\", \"luh\", \"luzu\", \"mangel\", \"mayichi\",\n        \"melo\", \"missasinfonia\", \"mixwell\", \"jaggerprincesa\", \"nategentile7\", \"nexxuz\",\n        \"lakshartnia\", \"nilojeda\", \"nissaxter\", \"olliegamerz\", \"orslok\", \"outconsumer\", \"papigavitv\",\n        \"paracetamor\", \"patica1999\", \"paulagonu\", \"pausenpaii\", \"perxitaa\", \"nosoyplex\",\n        \"polispol1\", \"quackity\", \"recuerd0p\", \"reventxz\", \"rivers_gg\", \"robertpg\", \"roier\",\n        \"ceuvebrokenheart\", \"rubius\", \"shadoune666\", \"silithur\", \"spok_sponha\", \"elspreen\", \"spursito\",\n        \"bystaxx\", \"suzyroxx\", \"vicens\", \"vitu\", \"werlyb\", \"xavi\", \"xcry\", \"elxokas\",\n        \"thezarcort\", \"zeling\", \"zormanworld\", \"mouredev\"\n    ]\n    users_data = []\n    not_found = []\n\n    token = get_access_token(CLIENT_ID, CLIENT_SECRET)\n\n    for user_name in users:\n\n        user = get_user_info(token, CLIENT_ID, user_name)\n\n        if user is None:\n            print(f\"User {user_name} not found\")\n            not_found.append(user_name)\n        else:\n            followers = get_followers(token, CLIENT_ID, user[\"id\"])\n            users_data.append(\n                {\n                    \"user_name\": user_name,\n                    \"created_at\": user.get(\"created_at\", \"\"),\n                    \"followers\": followers\n                }\n            )\n\n    sorted_followers = sorted(users_data, \n                              key=lambda x: x[\"followers\"], \n                              reverse=True)\n    \n    sorted_created_at = sorted(users_data, \n                               key=lambda x: x[\"created_at\"], \n                               reverse=False)\n    \n    print(\"===Sorted by followers===\")\n    for num, user in enumerate(sorted_followers):\n        print(f\"{num + 1} - {user['user_name']}: {user['followers']} followers\")\n\n    print(\"===Sorted by created_at===\")\n    for num, user in enumerate(sorted_created_at):\n        print(f\"{num+1} - {user['user_name']}: {user['created_at']}\")\n"
  },
  {
    "path": "Roadmap/40 - FORTNITE RUBIUS CUP/rust/kenysdev.rs",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - Rust\n_____________________________________\n40 FORTNITE RUBIUS CUP\n------------------------------------\n\n* EJERCICIO:\n* ¡Rubius tiene su propia skin en Fortnite!\n* Y va a organizar una competición para celebrarlo.\n* Esta es la lista de participantes:\n* https://x.com/Rubiu5/status/1840161450154692876\n*\n* Desarrolla un programa que obtenga el número de seguidores en\n* Twitch de cada participante, la fecha de creación de la cuenta\n* y ordene los resultados en dos listados.\n* - Usa el API de Twitch: https://dev.twitch.tv/docs/api/reference\n*   (NO subas las credenciales de autenticación)\n* - Crea un ranking por número de seguidores y por antigüedad.\n* - Si algún participante no tiene usuario en Twitch, debe reflejarlo.\n\n[dependencies]\nchrono = { version = \"0.4.37\", features = [\"serde\"] }\ndotenvy = \"0.15.7\"\nitertools = \"0.13.0\"\nreqwest = { version = \"0.12.9\", features = [\"json\"] }\nserde = { version = \"1.0.215\", features = [\"derive\"] }\nserde_json = \"1.0.133\"\ntokio = { version = \"1.41.1\", features = [\"full\"] }\n*/\n\nuse chrono::{DateTime, Utc};\nuse dotenvy::dotenv;\nuse std::env;\nuse itertools::Itertools;\nuse reqwest::Client;\nuse serde::{Deserialize, Serialize};\n\npub struct Twitch {\n    client_id: String,\n    client_secret: String,\n    access_token: Option<String>,\n}\n\n#[derive(Debug, Serialize, Deserialize)]\npub struct UserData {\n    username: String,\n    created_at: DateTime<Utc>,\n    followers: i32,\n}\n\nimpl Twitch {\n    pub fn new(client_id: String, client_secret: String) -> Self {\n        Self {\n            client_id,\n            client_secret,\n            access_token: None,\n        }\n    }\n\n    async fn ensure_access_token(&mut self) -> Result<(), Box<dyn std::error::Error>> {\n        if self.access_token.is_none() {\n            let client = Client::new();\n\n            let params = [\n                (\"client_id\", self.client_id.as_str()),\n                (\"client_secret\", self.client_secret.as_str()),\n                (\"grant_type\", \"client_credentials\"),\n            ];\n\n            let res = client\n                .post(\"https://id.twitch.tv/oauth2/token\")\n                .form(&params)\n                .send()\n                .await?;\n\n            if !res.status().is_success() {\n                return Err(format!(\"Error al obtener el token: {}\", res.status()).into());\n            }\n\n            let token_data: serde_json::Value = res.json().await?;\n            self.access_token = Some(\n                token_data[\"access_token\"]\n                    .as_str()\n                    .ok_or(\"Token no encontrado.\")?\n                    .to_string(),\n            );\n        }\n        Ok(())\n    }\n\n    pub fn access_token(&mut self) -> &str {\n        self.access_token.as_ref().unwrap()\n    }\n\n    async fn get_followers(\n        &mut self,\n        client: &reqwest::Client, \n        id_user: &str, \n    ) -> Result<i32, Box<dyn std::error::Error>> {\n        let url = format!(\"https://api.twitch.tv/helix/channels/followers?broadcaster_id={}\", id_user);\n        \n        let response = client\n            .get(&url)\n            .header(\"Client-Id\", self.client_id.as_str())\n            .header(\"Authorization\", format!(\"Bearer {}\", self.access_token()))\n            .send()\n            .await?;\n        \n        let json: serde_json::Value = response.json().await?;\n        let total = json[\"total\"].as_u64().unwrap_or(0) as u32;\n        Ok(total as i32)\n    }\n\n    async fn get_user_data(\n        &mut self,\n        user_name: &str,\n    ) -> Result<Option<UserData>, Box<dyn std::error::Error>> {\n        let client = reqwest::Client::new();\n        let url = format!(\"https://api.twitch.tv/helix/users?login={}\", user_name);\n\n        let response = client\n            .get(&url)\n            .header(\"Client-Id\", self.client_id.as_str())\n            .header(\"Authorization\", format!(\"Bearer {}\", self.access_token()))\n            .send()\n            .await?;\n\n        let json: serde_json::Value = response.json().await?;\n\n        let user_data = json[\"data\"]\n            .as_array()\n            .and_then(|data_array| data_array.first())\n            .ok_or(\"No user data found\")?;\n\n        let id_user = user_data[\"id\"]\n            .as_str()\n            .ok_or(\"Invalid user ID\")?;\n\n        let created_at_str = user_data[\"created_at\"]\n            .as_str()\n            .ok_or(\"Missing creation date\")?;\n\n        let created_at = DateTime::parse_from_rfc3339(created_at_str)\n            .map_err(|_| \"Failed to parse date\")?\n            .with_timezone(&Utc);\n\n        let total_followers = self.get_followers(&client, id_user).await?;\n\n        Ok(Some(UserData {\n            username: user_name.to_string(),\n            created_at,\n            followers: total_followers,\n        }))\n    }\n}\n\nfn print_rankings(users_data: &[UserData]) {\n    let by_followers = users_data\n        .iter()\n        .sorted_by(|a, b| b.followers.cmp(&a.followers))\n        .collect::<Vec<_>>();\n\n    let by_date = users_data\n        .iter()\n        .sorted_by_key(|x| x.created_at)\n        .collect::<Vec<_>>();\n\n    println!(\"\\nRanking por número de seguidores:\");\n    by_followers\n        .iter()\n        .enumerate()\n        .for_each(|(i, user)| {\n            println!(\"{} - {}: {} seguidores\", \n                i + 1, \n                user.username, \n                user.followers\n            )\n        });\n\n    println!(\"\\nRanking por antigüedad:\");\n    by_date\n        .iter()\n        .enumerate()\n        .for_each(|(i, user)| {\n            println!(\"{} - {}: Creado el {}\", \n                i + 1, \n                user.username, \n                user.created_at.format(\"%d/%m/%Y\")\n            )\n        });\n}\n\nasync fn process_users(users: &[String], tw: &mut Twitch) -> Result<(), Box<dyn std::error::Error>> {\n    let mut users_data = Vec::new();\n    let mut not_found_users = Vec::new();\n    println!(\"Obteniendo datos...\");\n\n    for name in users {\n        match tw.get_user_data(name).await {\n            Ok(Some(user_data)) => users_data.push(user_data),\n            Ok(None) => not_found_users.push(name.clone()),\n            Err(_) => not_found_users.push(name.clone()),\n        }\n    }\n\n    print_rankings(&users_data);\n\n    if !not_found_users.is_empty() {\n        println!(\"\\nUsuarios no encontrados:\");\n        not_found_users.iter().for_each(|user| println!(\"{}\", user));\n    }\n\n    Ok(())\n}\n\n#[tokio::main]\nasync fn main() {\n    dotenv().expect(\"No se encontró archivo .env\");\n    let client_id = env::var(\"TWITCH_CLIENT_ID\").expect(\"CLIENT_ID no encontrado\");\n    let client_secret = env::var(\"TWITCH_CLIENT_SECRET\").expect(\"CLIENT_SECRET no encontrado\");\n\n    let mut twitch = Twitch::new(client_id.clone(), client_secret);\n    if let Err(e) = twitch.ensure_access_token().await {\n        eprintln!(\"Error: {}\", e);\n        return;\n    }\n    \n    let users: Vec<String> = vec![\n    \"abby\", \"ache\", \"adricontreras\", \"agustin\", \"alexby\", \"ampeter\", \"ander\", \n    \"arigameplays\", \"arigeli\", \"auronplay\", \"axozer\", \"beniju\", \"bycalitos\", \n    \"byviruzz\", \"carrera\", \"celopan\", \"cheeto\", \"crystalmolly\", \"darioemehache\", \n    \"dheyo\", \"djmario\", \"doble\", \"elvisa\", \"elyas360\", \"folagor\", \"grefg\", \n    \"guanyar\", \"hika\", \"hiper\", \"ibai\", \"ibelky\", \"illojuan\", \"imantado\", \n    \"irinaisasia\", \"jesskiu\", \"jopa\", \"jordiwild\", \"kenaisouza\", \"keroro\", \n    \"kiddkeo\", \"kikorivera\", \"knekro\", \"koko\", \"kronnozomber\", \"leviathan\", \n    \"litkillah\", \"lolalolita\", \"lolito\", \"luh\", \"luzu\", \"mangel\", \"mayichi\", \n    \"melo\", \"missasinonia\", \"mixwell\", \"mrjagger\", \"nategentile\", \"nexxuz\", \n    \"nia\", \"nilojeda\", \"nissaxter\", \"ollie\", \"orslok\", \"outconsumer\", \"papigavi\", \n    \"paracetamor\", \"patica\", \"paulagonu\", \"pausenpaii\", \"perxitaa\", \"plex\", \n    \"polispol\", \"quackity\", \"recuerdop\", \"reven\", \"rivers\", \"robertpg\", \"roier\", \n    \"rojuu\", \"rubius\", \"shadoune\", \"silithur\", \"spoksponha\", \"spreen\", \"spursito\", \n    \"staxx\", \"suzyroxx\", \"vicens\", \"vituber\", \"werlyb\", \"xavi\", \"xcry\", \"xokas\", \n    \"zarcort\", \"zeling\", \"zorman\"\n    ].iter().map(|&s| s.to_string()).collect();\n\n    if let Err(e) = process_users(&users, &mut twitch).await {\n        eprintln!(\"Error: {}\", e);\n        return;\n    }    \n}\n"
  },
  {
    "path": "Roadmap/40 - FORTNITE RUBIUS CUP/sql/Nicojsuarez2.sql",
    "content": "# #40 FORTNITE RUBIUS CUP\n> #### Dificultad: Media | Publicación: 30/09/24 | Corrección: 07/10/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * ¡Rubius tiene su propia skin en Fortnite!\n * Y va a organizar una competición para celebrarlo.\n * Esta es la lista de participantes:\n * https://x.com/Rubiu5/status/1840161450154692876\n *\n * Desarrolla un programa que obtenga el número de seguidores en\n * Twitch de cada participante, la fecha de creación de la cuenta \n * y ordene los resultados en dos listados.\n * - Usa el API de Twitch: https://dev.twitch.tv/docs/api/reference\n *   (NO subas las credenciales de autenticación)\n * - Crea un ranking por número de seguidores y por antigüedad.\n * - Si algún participante no tiene usuario en Twitch, debe reflejarlo.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/40 - FORTNITE RUBIUS CUP/typescript/miguelex.ts",
    "content": "const obtenerTokenOAuth = async (clientId: string, clientSecret: string): Promise<string> => {\n    const url = 'https://id.twitch.tv/oauth2/token';\n    \n    const data = new URLSearchParams({\n        'client_id': clientId,\n        'client_secret': clientSecret,\n        'grant_type': 'client_credentials'\n    });\n\n    const response = await fetch(url, {\n        method: 'POST',\n        headers: {\n            'Content-Type': 'application/x-www-form-urlencoded',\n        },\n        body: data\n    });\n\n    if (!response.ok) {\n        throw new Error('Error al obtener el token OAuth');\n    }\n\n    const result = await response.json();\n    return result.access_token;\n}\n\nconst obtenerInfoUsuarioTwitch = async (accessToken: string, clientId: string, username: string): Promise<any | null> => {\n    username = username.replace(/[^a-zA-Z0-9_]/g, '');\n    const url = `https://api.twitch.tv/helix/users?login=${encodeURIComponent(username)}`;\n\n    const response = await fetch(url, {\n        headers: {\n            'Authorization': `Bearer ${accessToken}`,\n            'Client-ID': clientId\n        }\n    });\n\n    if (!response.ok) {\n        return null;\n    }\n\n    const result = await response.json();\n    return result.data[0] ?? null;\n}\n\nconst obtenerNumeroSeguidoresTwitch = async (accessToken: string, clientId: string, userId: string): Promise<number> => {\n    const url = `https://api.twitch.tv/helix/channels/followers?broadcaster_id=${userId}`;\n\n    const response = await fetch(url, {\n        headers: {\n            'Authorization': `Bearer ${accessToken}`,\n            'Client-ID': clientId\n        }\n    });\n\n    if (!response.ok) {\n        return 0;\n    }\n\n    const result = await response.json();\n    return result.total ?? 0;\n}\n\nconst main = async () => {\n    const participantes = [\n        'Abby', 'Ache', 'Adri Contreras', 'Agustin', 'Alexby', 'Ampeter', 'Ander', 'Ari Gameplays',\n        'Arigely', 'Auronplay', 'Axozer', 'Beniju', 'By Calitos', 'Byviruzz', 'Carrera', 'Celopan',\n        'Cheto', 'CrystalMolly', 'Dario Eme Hache', 'Dheyo', 'DjMariio', 'Doble', 'Elvisa', 'Elyas360',\n        'Folagor', 'Grefg', 'Guanyar', 'Hika', 'Hiper', 'Ibai', 'Ibelky', 'Illojuan', 'Imantado',\n        'Irina Isasia', 'JessKiu', 'Jopa', 'JordiWild', 'Kenai Souza', 'Keroro', 'Kidd Keo', 'Kiko Rivera',\n        'Knekro', 'Koko', 'KronnoZomber', 'Leviathan', 'Lit Killah', 'Lola Lolita', 'Lolito', 'Luh',\n        'Luzu', 'Mangel', 'Mayichi', 'Melo', 'MissaSinfonia', 'Mixwell', 'Mr. Jagger', 'Nate Gentile',\n        'Nexxuz', 'Nia', 'Nil Ojeda', 'NissaXter', 'Ollie', 'Orslok', 'Outconsumer', 'Papi Gavi',\n        'Paracetamor', 'Patica', 'Paula Gonu', 'Pausenpaii', 'Perxitaa', 'Plex', 'Polispol', 'Quackity',\n        'RecueroDP', 'Reven', 'Rivers', 'RobertPG', 'Roier', 'Rojuu', 'Rubius', 'Shadoune', 'Silithur',\n        'SpokSponha', 'Spreen', 'Spursito', 'Staxx', 'SuzyRoxx', 'Vicens', 'Vituber', 'Werlyb', 'Xavi',\n        'Xcry', 'Xokas', 'Zarcort', 'Zeling', 'Zorman'\n    ];\n\n    const clientId = 'TU_CLIENT_ID';\n    const clientSecret = 'TU_CLIENT_SECRET';\n\n    try {\n        const accessToken = await obtenerTokenOAuth(clientId, clientSecret);\n\n        const infoUsuarios: Array<any> = [];\n        const errores: Array<string> = [];\n\n        for (const participante of participantes) {\n            const usuario = await obtenerInfoUsuarioTwitch(accessToken, clientId, participante);\n\n            if (usuario) {\n                const seguidores = await obtenerNumeroSeguidoresTwitch(accessToken, clientId, usuario.id);\n\n                infoUsuarios.push({\n                    username: usuario.display_name,\n                    followers: seguidores,\n                    creation_date: usuario.created_at\n                });\n            } else {\n                errores.push(`El participante ${participante} no tiene usuario en Twitch.`);\n            }\n        }\n\n        // Ordenar por número de seguidores\n        const rankingPorSeguidores = infoUsuarios.sort((a, b) => b.followers - a.followers);\n\n        console.log(\"Ranking por número de seguidores:\");\n        rankingPorSeguidores.forEach(usuario => {\n            console.log(`${usuario.username} - ${usuario.followers} seguidores`);\n        });\n\n        // Ordenar por antigüedad\n        const rankingPorAntiguedad = infoUsuarios.sort((a, b) => new Date(a.creation_date).getTime() - new Date(b.creation_date).getTime());\n\n        console.log(\"\\nRanking por antigüedad de la cuenta:\");\n        rankingPorAntiguedad.forEach(usuario => {\n            const creationDate = new Date(usuario.creation_date).toLocaleDateString('es-ES');\n            console.log(`${usuario.username} - Cuenta creada el ${creationDate}`);\n        });\n\n        if (errores.length > 0) {\n            console.log(\"\\nErrores:\");\n            errores.forEach(error => console.log(error));\n        }\n    } catch (error) {\n        console.error('Error:', error);\n    }\n}\n\nmain();\n"
  },
  {
    "path": "Roadmap/40 - FORTNITE RUBIUS CUP/vb.net/kenysdev.vb",
    "content": "' _____________________________________\n' https://github.com/kenysdev\n' 2024 - vb.net\n' _____________________________________\n' 40 FORTNITE RUBIUS CUP\n' ------------------------------------\n'* EJERCICIO\n'* ¡Rubius tiene su propia skin en Fortnite!\n'* Y va a organizar una competición para celebrarlo.\n'* Esta es la lista de participantes:\n'* https//x.com/Rubiu5/status/1840161450154692876\n'*\n'* Desarrolla un programa que obtenga el número de seguidores en\n'* Twitch de cada participante, la fecha de creación de la cuenta \n'* y ordene los resultados en dos listados.\n'* - Usa el API de Twitch: https : //dev.twitch.tv/docs/api/reference\n'*   (NO subas las credenciales de autenticación)\n'* - Crea un ranking por número de seguidores y por antigüedad.\n'* - Si algún participante no tiene usuario en Twitch, debe reflejarlo.\n\n\nImports System.Net.Http\nImports System.Text.Json\nImports DotNetEnv\n\nPublic Class Twitch\n    Private ReadOnly clientId As String\n    Private ReadOnly clientSecret As String\n    Private accessToken As String\n\n    Public Sub New(clientId As String, clientSecret As String)\n        Me.clientId = clientId\n        Me.clientSecret = clientSecret\n    End Sub\n\n    Public Class UserData\n        Public Property Username As String\n        Public Property CreatedAt As DateTime\n        Public Property Followers As Integer\n    End Class\n\n    Public Async Function EnsureAccessTokenAsync() As Task\n        If String.IsNullOrEmpty(accessToken) Then\n            Using client As New HttpClient()\n                Dim tokenContent As New FormUrlEncodedContent(New Dictionary(Of String, String) From {\n                    {\"client_id\", clientId},\n                    {\"client_secret\", clientSecret},\n                    {\"grant_type\", \"client_credentials\"}\n                })\n\n                Dim tokenResponse = Await client.PostAsync(\"https://id.twitch.tv/oauth2/token\", tokenContent)\n\n                If Not tokenResponse.IsSuccessStatusCode Then\n                    Throw New Exception($\"Error al obtener el token: {tokenResponse.StatusCode}\")\n                End If\n\n                Dim tokenJson = Await tokenResponse.Content.ReadAsStringAsync()\n                Dim tokenData = JsonDocument.Parse(tokenJson).RootElement\n                Me.accessToken = tokenData.GetProperty(\"access_token\").GetString()\n            End Using\n        End If\n    End Function\n\n    Private Shared Async Function GetFollowers(client As HttpClient, idUser As String) As Task(Of Integer)\n        Dim response = Await client.GetAsync($\"https://api.twitch.tv/helix/channels/followers?broadcaster_id={idUser}\")\n        Dim json = Await response.Content.ReadAsStringAsync()\n        Dim data = JsonDocument.Parse(json).RootElement\n        Return data.GetProperty(\"total\").GetInt32()\n    End Function\n\n    Public Async Function GetUserData(userName As String) As Task(Of UserData)\n        Using client As New HttpClient()\n            client.DefaultRequestHeaders.Add(\"Client-Id\", clientId)\n            client.DefaultRequestHeaders.Add(\"Authorization\", $\"Bearer {accessToken}\")\n\n            Dim response = Await client.GetAsync($\"https://api.twitch.tv/helix/users?login={userName}\")\n            Dim json = Await response.Content.ReadAsStringAsync()\n            Dim data = JsonDocument.Parse(json).RootElement\n\n            Dim userArray = data.GetProperty(\"data\").EnumerateArray().FirstOrDefault()\n\n            If userArray.ValueKind <> JsonValueKind.Undefined Then\n                Dim idUser = userArray.GetProperty(\"id\").GetString()\n                Dim createdAtString = userArray.GetProperty(\"created_at\").GetString()\n\n                If Not String.IsNullOrEmpty(createdAtString) Then\n                    Dim createdAt = DateTime.Parse(createdAtString)\n                    Dim totalFollowers = Await GetFollowers(client, idUser)\n\n                    Return New UserData With {\n                        .Username = userName,\n                        .CreatedAt = createdAt,\n                        .Followers = totalFollowers\n                    }\n                End If\n            End If\n        End Using\n\n        Return Nothing\n    End Function\nEnd Class\n\nModule Program\n    Private Sub PrintRankings(usersData As List(Of Twitch.UserData))\n        Dim byFollowers = usersData.OrderByDescending(Function(x) x.Followers).ToList()\n        Dim byDate = usersData.OrderBy(Function(x) x.CreatedAt).ToList()\n\n        Console.WriteLine(vbCrLf & \"Ranking por número de seguidores:\")\n        For i = 0 To byFollowers.Count - 1\n            Console.WriteLine($\"{i + 1} - {byFollowers(i).Username}: {byFollowers(i).Followers:N0} seguidores\")\n        Next\n\n        Console.WriteLine(vbCrLf & \"Ranking por antigüedad:\")\n        For i = 0 To byDate.Count - 1\n            Console.WriteLine($\"{i + 1} - {byDate(i).Username}: Creado el {byDate(i).CreatedAt:dd/MM/yyyy}\")\n        Next\n    End Sub\n\n    Public Async Function ProcessUsers(users As List(Of String), Tw As Twitch) As Task\n        Dim usersData As New List(Of Twitch.UserData)\n        Dim notFoundUsers As New List(Of String)\n\n        Console.WriteLine(\"Obteniendo datos...\")\n\n        For Each name In users\n            Dim userData = Await Tw.GetUserData(name)\n            If userData IsNot Nothing Then\n                usersData.Add(userData)\n            Else\n                notFoundUsers.Add(name)\n            End If\n        Next\n\n        PrintRankings(usersData)\n\n        If notFoundUsers.Count > 0 Then\n            Console.WriteLine(vbCrLf & \"Usuarios no encontrados:\")\n            For Each user In notFoundUsers\n                Console.WriteLine(user)\n            Next\n        End If\n    End Function\n\n    Public Async Function Run() As Task\n        DotNetEnv.Env.Load()\n        Dim clientId = Environment.GetEnvironmentVariable(\"TWITCH_CLIENT_ID\")\n        Dim clientSecret = Environment.GetEnvironmentVariable(\"TWITCH_CLIENT_SECRET\")\n\n        Dim Tw = New Twitch(clientId, clientSecret)\n        Await Tw.EnsureAccessTokenAsync()\n\n        Dim users As New List(Of String) From {\n            \"abby\", \"ache\", \"adricontreras\", \"agustin\", \"alexby\", \"ampeter\", \"ander\", \"arigameplays\",\n            \"arigeli\", \"auronplay\", \"axozer\", \"beniju\", \"bycalitos\", \"byviruzz\", \"carrera\", \"celopan\",\n            \"cheeto\", \"crystalmolly\", \"darioemehache\", \"dheyo\",\n            \"djmario\", \"doble\", \"elvisa\", \"elyas360\", \"folagor\", \"grefg\", \"guanyar\", \"hika\",\n            \"hiper\", \"ibai\", \"ibelky\", \"illojuan\", \"imantado\", \"irinaisasia\", \"jesskiu\", \"jopa\",\n            \"jordiwild\", \"kenaisouza\", \"keroro\", \"kiddkeo\",\n            \"kikorivera\", \"knekro\", \"koko\", \"kronnozomber\", \"leviathan\", \"litkillah\", \"lolalolita\", \"lolito\",\n            \"luh\", \"luzu\", \"mangel\", \"mayichi\", \"melo\", \"missasinonia\", \"mixwell\", \"mrjagger\",\n            \"nategentile\", \"nexxuz\", \"nia\", \"nilojeda\",\n            \"nissaxter\", \"ollie\", \"orslok\", \"outconsumer\", \"papigavi\", \"paracetamor\", \"patica\", \"paulagonu\",\n            \"pausenpaii\", \"perxitaa\", \"plex\", \"polispol\", \"quackity\", \"recuerdop\", \"reven\", \"rivers\",\n            \"robertpg\", \"roier\", \"rojuu\", \"rubius\",\n            \"shadoune\", \"silithur\", \"spoksponha\", \"spreen\", \"spursito\", \"staxx\", \"suzyroxx\", \"vicens\",\n            \"vituber\", \"werlyb\", \"xavi\", \"xcry\", \"xokas\", \"zarcort\", \"zeling\", \"zorman\"}\n\n        Await ProcessUsers(users, Tw)\n    End Function\n\n    Public Sub Main()\n        Run().Wait()\n    End Sub\nEnd Module\n"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/c#/hequebo.cs",
    "content": "using System.IO.Compression;\n\nclass Program\n{\n    static void Main(string[] args)\n    {\n        string filePath = @\".\\Semana 41\";\n        string zipPath = @\".\\result.zip\";\n\n        ZipFile.CreateFromDirectory(filePath, zipPath);\n    }\n}"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/c#/isaacus98.cs",
    "content": "﻿/*\n * EJERCICIO:\n * ¿Has visto la camiseta.rar?\n * https://x.com/MoureDev/status/1841531938961592740\n *\n * Crea un programa capaz de comprimir un archivo \n * en formato .zip (o el que tú quieras).\n * - No subas el archivo o el zip.\n */\n\n\n\nusing System.IO.Compression;\n\nnamespace ComprimirArchivo\n{\n    internal class Program\n    {\n        static void Main(string[] args)\n        {\n            using (ZipArchive zip = ZipFile.Open(\"test.zip\", ZipArchiveMode.Create))\n            {\n                zip.CreateEntryFromFile(\"test.txt\", \"test.txt\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/c#/kenysdev.cs",
    "content": "namespace exs41;\n/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - C#\n_____________________________________\n41 CAMISETA RAR\n------------------------------------\n\n* EJERCICIO:\n * ¿Has visto la camiseta.rar?\n * https://x.com/MoureDev/status/1841531938961592740\n *\n * Crea un programa capaz de comprimir un archivo \n * en formato .zip (o el que tú quieras).\n * - No subas el archivo o el zip\n*/\n\nusing System.IO;\nusing System.IO.Compression;\n\npublic class FileCompressor\n{\n    public static void CompressFile(string sourceFile, string zipFile)\n    {\n        if (!File.Exists(sourceFile))\n            throw new FileNotFoundException($\"El archivo fuente '{sourceFile}' no existe.\");\n\n        string zipDir = Path.GetDirectoryName(zipFile) ?? Directory.GetCurrentDirectory();\n        if (!Directory.Exists(zipDir))\n            throw new DirectoryNotFoundException($\"El directorio '{zipDir}' no existe.\");\n\n        if (File.Exists(zipFile))\n            throw new IOException($\"El archivo zip '{zipFile}' ya existe.\");\n\n        try\n        {\n            using (FileStream zipToCreate = new(zipFile, FileMode.Create))\n            {\n                using ZipArchive archive = new(zipToCreate, ZipArchiveMode.Create);\n                archive.CreateEntryFromFile(sourceFile, Path.GetFileName(sourceFile), CompressionLevel.Optimal);\n            }\n\n            Console.WriteLine($\"Comprimido exitosamente '{sourceFile}' a '{zipFile}'\");\n        }\n        catch (UnauthorizedAccessException)\n        {\n            throw new UnauthorizedAccessException($\"No tienes permiso de escritura para '{zipFile}'\");\n        }\n        catch (Exception ex)\n        {\n            throw new Exception($\"Se produjo un error al comprimir el archivo: {ex.Message}\", ex);\n        }\n    }\n\n    public static void Main()\n    {\n        try\n        {\n            CompressFile(\"tmp.txt\", @\"D:\\dev\\tmp\\file.zip\");\n        }\n        catch (Exception ex)\n        {\n            Console.WriteLine($\"Error al comprimir: {ex.Message}\");\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/c++/hectorio23.cpp",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\n// FOR UBUNTU:\n// sudo apt install zlib1g-dev\n\n// FOR ARCH LINUX\n// sudo pacman -S zlib1g-dev\n\n// For compiling the program use:\n// g++ hectorio23.cpp -o hectorio23 -lz\n\n\n#include <iostream>\n#include <fstream>\n#include <zlib.h> // Librería para manejar gzip\n#include <stdexcept>\n\n// Función para comprimir en formato gzip usando zlib\nvoid comprimirGzip(const std::string& archivo) {\n    std::ifstream file(archivo, std::ios_base::binary);\n    if (!file.is_open()) {\n        throw std::runtime_error(\"No se pudo abrir el archivo.\");\n    }\n\n    std::string compressedFile = archivo + \".gz\";\n    gzFile outFile = gzopen(compressedFile.c_str(), \"wb\");\n    if (!outFile) {\n        throw std::runtime_error(\"No se pudo crear el archivo comprimido.\");\n    }\n\n    char buffer[128];\n    while (file.read(buffer, sizeof(buffer)) || file.gcount()) {\n        gzwrite(outFile, buffer, file.gcount());\n    }\n\n    gzclose(outFile);\n    std::cout << \"Archivo comprimido exitosamente en formato gzip: \" << compressedFile << std::endl;\n}\n\nint main(int argc, char* argv[]) {\n    if (argc != 3) {\n        std::cerr << \"Uso: \" << argv[0] << \" <archivo> <formato(gzip)>\" << std::endl;\n        return 1;\n    }\n\n    try {\n        comprimirGzip(argv[1]);  // Por ahora, solo manejo gzip\n    } catch (const std::exception& e) {\n        std::cerr << \"Error: \" << e.what() << std::endl;\n        return 1;\n    }\n\n    return 0;\n}\n\n\n"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/ejercicio.md",
    "content": "# #41 CAMISETA RAR\n> #### Dificultad: Fácil | Publicación: 07/10/24 | Corrección: 14/10/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * ¿Has visto la camiseta.rar?\n * https://x.com/MoureDev/status/1841531938961592740\n *\n * Crea un programa capaz de comprimir un archivo \n * en formato .zip (o el que tú quieras).\n * - No subas el archivo o el zip.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/go/hozlucas28.go",
    "content": "package main\n\nimport (\n\t\"archive/zip\"\n\t\"io\"\n\t\"os\"\n\t\"strings\"\n)\n\n/* -------------------------------------------------------------------------- */\n/*                                  FUNCTIONS                                 */\n/* -------------------------------------------------------------------------- */\n\nfunc createZip(filePaths []string, zipFilePath string) error {\n\tarchive, err := os.Create(zipFilePath)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer archive.Close()\n\n\tvar zipWriter *zip.Writer = zip.NewWriter(archive)\n\tdefer zipWriter.Close()\n\n\tfor _, filePath := range filePaths {\n\t\tfile, err := os.Open(filePath)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tdefer file.Close()\n\n\t\tfileStats, err := file.Stat()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tfileZipped, err := zipWriter.Create(fileStats.Name())\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t_, err = io.Copy(fileZipped, file)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tzipWriter.Close()\n\n\treturn nil\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\nfunc main() {\n\tvar filePaths []string = make([]string, 2, 2)\n\tfilePaths[0] = \"./hozlucas28.go\"\n\tfilePaths[1] = \"./hozlucas28.txt\"\n\n\tvar zipFilePath string = \"./hozlucas28.zip\"\n\n\tfor _, filePath := range append(filePaths[1:], zipFilePath) {\n\t\tif _, err := os.Stat(filePath); err == nil {\n\t\t\tif err = os.Remove(filePath); err != nil {\n\t\t\t\tpanic(err)\n\t\t\t}\n\t\t}\n\t}\n\n\tvar fileContent []string = make([]string, 3, 3)\n\tfileContent[0] = \"Lucas Nahuel Hoz\"\n\tfileContent[1] = \"23\"\n\tfileContent[2] = \"Argentina\"\n\n\tfile, err := os.Create(filePaths[1])\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\t_, err = file.WriteString(strings.Join(fileContent, \"|\"))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tcreateZip(filePaths, zipFilePath)\n\n\tfile.Close()\n\n\t// Uncomment to remove files on program finish\n\t// for _, filePath := range append(filePaths[1:], zipFilePath) {\n\t// \tif _, err := os.Stat(filePath); err == nil {\n\t// \t\tif err = os.Remove(filePath); err != nil {\n\t// \t\t\tpanic(err)\n\t// \t\t}\n\t// \t}\n\t// }\n}\n"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/java/Josegs95.java",
    "content": "import java.io.*;\nimport java.math.BigDecimal;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.text.DecimalFormat;\nimport java.util.zip.Deflater;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipOutputStream;\n\npublic class Josegs95 {\n    public static void main(String[] args) {\n        new Josegs95().RARShirt();\n    }\n\n    public void RARShirt(){\n        Path fileToZip = Path.of(\"./src/Josegs95.java\");\n        String zipName = \"Josegs95\";\n\n        zipFile(fileToZip, zipName);\n    }\n\n    private void zipFile(Path fileToZipPath, String zipFileName){\n        File sourceFile = fileToZipPath.toFile();\n        if (!Files.isRegularFile(sourceFile.toPath())){\n            System.out.printf(\"Error, %s no es un archivo válido\", fileToZipPath);\n            return;\n        }\n\n        File zipFile = Path.of(sourceFile.getParent(), zipFileName + \".zip\").toFile();\n        try(ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile))){\n            zos.setLevel(Deflater.BEST_COMPRESSION);\n            zos.putNextEntry(new ZipEntry(sourceFile.getName()));\n\n            byte[] bytes = Files.readAllBytes(fileToZipPath);\n            zos.write(bytes, 0, bytes.length);\n        } catch (FileNotFoundException e) {\n            throw new RuntimeException(e);\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        }\n\n        Long sourceFileSize = sourceFile.length();\n        Long zipFileSize = zipFile.length();\n        Double ratio = ((double) zipFileSize) / sourceFileSize;\n\n        System.out.println(\"Archivo comprimido con éxito\");\n        System.out.print(zipFile.getName() + \": \" + zipFileSize + \" bytes\");\n        System.out.println(\" (ratio: \" + ((int)(ratio * 100)) / 100.00 + \")\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/java/MohamedElderkaoui.java",
    "content": "import java.io.*;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipOutputStream;\n\npublic class MohamedElderkaoui {\n\n    public static void main(String[] args) {\n        String filePath = \"archivo.txt\";  // Cambia esta ruta por la del archivo a comprimir\n        String zipFilePath = \"archivo.zip\";  // Ruta donde se guardará el archivo comprimido\n\n        try {\n            compressToZip(filePath, zipFilePath);\n            System.out.println(\"Archivo comprimido correctamente en: \" + zipFilePath);\n        } catch (IOException e) {\n            System.err.println(\"Error al comprimir el archivo: \" + e.getMessage());\n        }\n    }\n\n    // Método para comprimir un archivo en formato ZIP\n    public static void compressToZip(String filePath, String zipFilePath) throws IOException {\n        File fileToZip = new File(filePath);\n        if (!fileToZip.exists()) {\n            throw new FileNotFoundException(\"El archivo no existe: \" + filePath);\n        }\n\n        // Crear flujo de salida para el archivo ZIP\n        try (FileOutputStream fos = new FileOutputStream(zipFilePath);\n             ZipOutputStream zipOut = new ZipOutputStream(fos);\n             FileInputStream fis = new FileInputStream(fileToZip)) {\n\n            // Crear una entrada de ZIP para el archivo\n            ZipEntry zipEntry = new ZipEntry(fileToZip.getName());\n            zipOut.putNextEntry(zipEntry);\n\n            // Leer y escribir los datos del archivo en el archivo ZIP\n            byte[] buffer = new byte[1024];\n            int length;\n            while ((length = fis.read(buffer)) >= 0) {\n                zipOut.write(buffer, 0, length);\n            }\n\n            // Cerrar la entrada ZIP\n            zipOut.closeEntry();\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/java/almartinez.java",
    "content": "import java.io.FileNotFoundException;\nimport java.io.IOException;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.Paths;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipOutputStream;\n\npublic class almartinez {\n    public static void main(String[] args) {\n        Path sourceFile = Paths.get(\"ruta/nombre_fichero_a_comprimir.txt\");\n        Path zipFileName = Paths.get(\"ruta/nombre_del_archivo_comprimido.zip\");\n\n        try {\n            compressFile(sourceFile, zipFileName);\n            System.out.println(\"Archivo comprimido creado: \" + zipFileName);\n        } catch (IOException ioe) {\n            System.err.println(\"Error al comprimir el archivo: \" + ioe.getMessage());\n        }\n    }\n\n    private static void compressFile(Path sourceFile, Path zipFileName) throws IOException {\n        try (ZipOutputStream zipOutputStream = new ZipOutputStream(Files.newOutputStream(zipFileName))) {\n            \n            ZipEntry zipEntry = new ZipEntry(sourceFile.getFileName().toString());\n            zipOutputStream.putNextEntry(zipEntry);\n\n            Files.copy(sourceFile, zipOutputStream);\n\n        } catch (FileNotFoundException fnfe) {\n            System.err.println(\"Archivo no encontrado: \" + fnfe.getMessage());\n            throw fnfe;\n        } catch (IOException ioe) {\n            System.err.println(\"Error de I/O: \" + ioe.getMessage());\n            throw ioe;\n        }\n        \n    }\n\n}\n"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/java/asjordi.java",
    "content": "import java.io.*;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipOutputStream;\n\npublic class Main {\n\n    public static void main(String[] args) throws IOException {\n        var res = compressFile(\"persons.csv\");\n        System.out.println(res ? \"File compressed successfully\" : \"Failed to compress file\");\n    }\n\n    public static boolean compressFile(String sourceFile) {\n        try (FileOutputStream fos = new FileOutputStream(\"compressed.zip\");\n             ZipOutputStream zipOut = new ZipOutputStream(fos) ) {\n\n            File fileToZip = new File(sourceFile);\n\n            try (FileInputStream fis = new FileInputStream(fileToZip)) {\n\n                ZipEntry zipEntry = new ZipEntry(fileToZip.getName());\n                zipOut.putNextEntry(zipEntry);\n                byte[] bytes = new byte[2048];\n                int length;\n\n                while ((length = fis.read(bytes)) >= 0) {\n                    zipOut.write(bytes, 0, length);\n                }\n\n            }\n        } catch (Exception e) {\n            System.out.println(e.getMessage());\n            return false;\n        }\n\n        return true;\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/java/martinbohorquez.java",
    "content": "import java.io.*;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipInputStream;\nimport java.util.zip.ZipOutputStream;\n\npublic class martinbohorquez {\n    public static void main(String[] args) throws FileNotFoundException {\n        File sourceFile = new File(\"AZ900-2024.pdf\");\n        File zipFile = zipFile(sourceFile);\n        System.out.printf(\"El archivo '%s' ha sido comprimido: %s%n\", sourceFile, zipFile);\n        File unzipFile = unzipFile(zipFile);\n        System.out.printf(\"El archivo '%s' ha sido descomprimido: %s%n\", zipFile, unzipFile);\n    }\n\n    private static File zipFile(File sourceFile) throws FileNotFoundException {\n        if (!sourceFile.exists()) throw new FileNotFoundException(\"El archivo no existe: \" + sourceFile);\n\n        String fileName = sourceFile.toString()\n                .substring(0, sourceFile.toString().lastIndexOf(\".\"));\n        File targetFile = new File(fileName.concat(\".zip\"));\n\n        try (FileOutputStream fos = new FileOutputStream(targetFile);\n             ZipOutputStream zipOut = new ZipOutputStream(fos);\n             FileInputStream fis = new FileInputStream(sourceFile)) {\n\n            ZipEntry zipEntry = new ZipEntry(sourceFile.getName());\n            zipOut.putNextEntry(zipEntry);\n\n            byte[] buffer = new byte[1024];\n            int length;\n            while ((length = fis.read(buffer)) >= 0) zipOut.write(buffer, 0, length);\n\n            zipOut.closeEntry();\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        }\n        return targetFile;\n    }\n\n    private static File unzipFile(File sourceFile) throws FileNotFoundException {\n        if (!sourceFile.exists()) throw new FileNotFoundException(\"El archivo no existe: \" + sourceFile);\n        File targetFile = null;\n        try (FileInputStream fis = new FileInputStream(sourceFile);\n             ZipInputStream zipOut = new ZipInputStream(fis)) {\n\n            ZipEntry zipEntry;\n\n            if ((zipEntry = zipOut.getNextEntry()) != null) {\n                targetFile = new File(\"unzip-\" + zipEntry.getName());\n                try (FileOutputStream fos = new FileOutputStream(targetFile)) {\n                    byte[] buffer = new byte[1024];\n                    int length;\n                    while ((length = zipOut.read(buffer)) >= 0) fos.write(buffer, 0, length);\n                }\n\n                zipOut.closeEntry();\n            }\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        }\n        return targetFile;\n    }\n}\n"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/java/miguelex.java",
    "content": "import java.io.*;\nimport java.util.Scanner;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipOutputStream;\n\npublic class miguelex {\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n\n        System.out.println(\"Selecciona lo que quieres comprimir:\");\n        System.out.println(\"1. Archivo\");\n        System.out.println(\"2. Directorio\");\n        int tipoSeleccionado = Integer.parseInt(scanner.nextLine());\n\n        String tipo;\n        if (tipoSeleccionado == 1) {\n            tipo = \"archivo\";\n        } else if (tipoSeleccionado == 2) {\n            tipo = \"directorio\";\n        } else {\n            System.out.println(\"Selección no válida\");\n            return;\n        }\n\n        System.out.println(\"Introduce la ruta del \" + tipo + \" que deseas comprimir:\");\n        String inputPath = scanner.nextLine();\n\n        System.out.println(\"Selecciona el formato de compresión:\");\n        System.out.println(\"1. ZIP\");\n        int formatoSeleccionado = Integer.parseInt(scanner.nextLine());\n\n        if (formatoSeleccionado != 1) {\n            System.out.println(\"Formato no válido\");\n            return;\n        }\n\n        System.out.println(\"Introduce el nombre de salida (sin la extensión):\");\n        String nombreSalida = scanner.nextLine() + \".zip\";\n\n        try {\n            FileOutputStream fos = new FileOutputStream(nombreSalida);\n            ZipOutputStream zos = new ZipOutputStream(fos);\n\n            File inputFile = new File(inputPath);\n            if (tipo.equals(\"archivo\")) {\n                agregarArchivoAlZip(inputFile, zos);\n            } else {\n                agregarDirectorioAlZip(inputFile, inputFile.getName(), zos);\n            }\n\n            zos.close();\n            fos.close();\n            System.out.println(\"Archivo/directorio comprimido con éxito en \" + nombreSalida);\n        } catch (IOException e) {\n            System.out.println(\"Error al comprimir: \" + e.getMessage());\n        }\n    }\n\n    private static void agregarArchivoAlZip(File archivo, ZipOutputStream zos) throws IOException {\n        FileInputStream fis = new FileInputStream(archivo);\n        ZipEntry zipEntry = new ZipEntry(archivo.getName());\n        zos.putNextEntry(zipEntry);\n\n        byte[] buffer = new byte[1024];\n        int length;\n        while ((length = fis.read(buffer)) >= 0) {\n            zos.write(buffer, 0, length);\n        }\n\n        zos.closeEntry();\n        fis.close();\n    }\n\n    private static void agregarDirectorioAlZip(File carpeta, String nombreBase, ZipOutputStream zos) throws IOException {\n        File[] archivos = carpeta.listFiles();\n        if (archivos != null) {\n            for (File archivo : archivos) {\n                if (archivo.isDirectory()) {\n                    agregarDirectorioAlZip(archivo, nombreBase + \"/\" + archivo.getName(), zos);\n                } else {\n                    FileInputStream fis = new FileInputStream(archivo);\n                    ZipEntry zipEntry = new ZipEntry(nombreBase + \"/\" + archivo.getName());\n                    zos.putNextEntry(zipEntry);\n\n                    byte[] buffer = new byte[1024];\n                    int length;\n                    while ((length = fis.read(buffer)) >= 0) {\n                        zos.write(buffer, 0, length);\n                    }\n\n                    zos.closeEntry();\n                    fis.close();\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #41 - JavaScript -> Jesus Antonio Escamilla */\n\n/**\n * CAMISETA RAR.\n * Utilizando la Terminal para pedir datos y agregarlos.\n */\n\n// Los recursos requeridos para ejerció\nconst fs = require('fs');\nconst zlib = require('zlib');\n\n// La función en concreto\nfunction compressZip(inputFilePath, outputFilePath) {\n    // Leemos el Archivo\n    const input = fs.createReadStream(inputFilePath);\n\n    // Escribimos el Archivo\n    const output = fs.createWriteStream(outputFilePath);\n\n    // El recursos de comprimir\n    const gzip = zlib.createGzip();\n\n    // Aquí se comprime el archivo\n    input.pipe(gzip).pipe(output)\n        .on('finish', () => console.log('Archivo comprimido con éxito.'))\n        .on('error', (err) => console.error('Error al comprimir el archivo:', err))\n}\n\n// Se obtenía el archivo y como se llama después de comprimidlo\nconst inputFile = './archivo.txt';\nconst outputFile = './archivo.txt.gz';\n\n// Ejecutado la función\ncompressZip(inputFile, outputFile)"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/javascript/Rafacv23.js",
    "content": "// Módulos requeridos, necesitamos este paquete https://github.com/archiverjs/node-archiver\nconst fs = require(\"fs\")\nconst archiver = require(\"archiver\")\n\n// Crear un flujo de escritura para el archivo ZIP de salida\nconst output = fs.createWriteStream(__dirname + \"/archivo.zip\")\nconst archive = archiver(\"zip\", {\n  zlib: { level: 9 }, // Establece el nivel de compresión\n})\n\n// Comprobar si hay errores\narchive.on(\"error\", function (err) {\n  throw err\n})\n\n// Redirigir los datos del archivo comprimido al archivo de salida\narchive.pipe(output)\n\n// Agregar archivos al archivo comprimido\narchive.file(\"/path/to/file0.txt\", {\n  name: \"file0-or-change-this-whatever.txt\", // Nuevo nombre en el archivo ZIP\n})\narchive.file(\"example.txt\", { name: \"example.txt\" })\n\n// Finalizar el archivo comprimido (no olvides escuchar el evento close)\narchive\n  .finalize()\n  .then(() => {\n    console.log(\"Archivo comprimido finalizado con éxito.\")\n  })\n  .catch((err) => {\n    console.error(\"Error al finalizar el archivo comprimido:\", err)\n  })\n\n// Opcionalmente, escuchar el evento finish del flujo de salida\noutput.on(\"close\", function () {\n  console.log(archive.pointer() + \" bytes totales escritos en archivo.zip\")\n})\n"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/javascript/RaulDoezon.js",
    "content": "/*\n  EJERCICIO:\n  ¿Has visto la camiseta.rar?\n  https://x.com/MoureDev/status/1841531938961592740\n \n  Crea un programa capaz de comprimir un archivo \n  en formato .zip (o el que tú quieras).\n  - No subas el archivo o el zip.\n*/\n\nconst fs = require('fs');\nconst zlib = require('zlib');\nconst zip = zlib.createGzip();\nconst input = fs.createReadStream('archivo.txt');\nconst output = fs.createWriteStream('archivo.zip');\n\ninput.pipe(zip).pipe(output);\n\nconsole.log(`El archivo fue comprimido.`);\n"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/javascript/RicJDev.js",
    "content": "/*\n  EJERCICIO:\n\n  - Para crear el archivo .zip se ha instalado la libreria 'adm-zip'.\n  - Se ejecuta en Node.js, importando los modulos 'node:path' y 'node:url' para trabajar con rutas.\n\n  @RicJDev\n*/\n\nimport AdmZip from 'adm-zip'\n\nimport * as path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url))\nconst zip = new AdmZip()\n\ntry {\n  const filePath = path.join(__dirname, './gatito.png')\n  const zipName = 'fotos.zip'\n\n  zip.addLocalFile(filePath)\n  zip.writeZip(zipName)\n\n  console.log(`Se ha creado el archivo ${zipName} de manera exitosa!`)\n} catch (error) {\n  console.error(error.message)\n}\n"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/javascript/duendeintemporal.js",
    "content": "//#41 - CAMISETA RAR\n/*\n * EJERCICIO:\n * ¿Has visto la camiseta.rar?\n * https://x.com/MoureDev/status/1841531938961592740\n *\n * Crea un programa capaz de comprimir un archivo \n * en formato .zip (o el que tú quieras).\n * - No subas el archivo o el zip.\n */\n\n//We will use JSZip library, which allows us to create and manipulate ZIP files in the browser or in a Node.js environment. \n\nlet log = console.log;\n\nconst JSZip = require('jszip');\nconst fs = require('fs');\n\n// Function to compress a file\nasync function compressFile(inputFilePath, outputZipPath) {\n    const zip = new JSZip();\n\n    // Read the file to be compressed\n    const fileData = fs.readFileSync(inputFilePath);\n    \n    // Add the file to the zip\n    zip.file(inputFilePath.split('/').pop(), fileData);\n\n    // Generate the zip file\n    const zipContent = await zip.generateAsync({ type: 'nodebuffer' });\n\n    // Write the zip file to the output path\n    fs.writeFileSync(outputZipPath, zipContent);\n    log(`File compressed and saved as ${outputZipPath}`);\n}\n\nconst inputFilePath = 'C:/Users/Niko Zen/Documents/a Nany.docx'; // Replace with the file path to compress\nconst outputZipPath = 'test_output.zip'; // Desired output zip file name\n\ncompressFile(inputFilePath, outputZipPath)\n    .then(() => log('Compression complete!'))\n    .catch(err => error('Error during compression:', err));\n\n// Possible output: \n//File compressed and saved as test_output.zip\n//Compression complete!"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/javascript/hectorio23.js",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\nconst fs = require('fs');\nconst zlib = require('zlib');\nconst argparse = require('argparse');\n\n// Función para comprimir en formato gzip\nfunction comprimirGzip(archivo) {\n    const archivoSalida = archivo + '.gz';\n    const input = fs.createReadStream(archivo);\n    const output = fs.createWriteStream(archivoSalida);\n    const gzip = zlib.createGzip();\n\n    input.pipe(gzip).pipe(output).on('finish', () => {\n        console.log(`Archivo comprimido exitosamente: ${archivoSalida}`);\n    });\n}\n\n// Argumentos usando ArgumentParser\nconst parser = new argparse.ArgumentParser({\n    description: 'Comprimir un archivo en formato gzip',\n});\nparser.add_argument('archivo', { help: 'El archivo que se desea comprimir' });\nparser.add_argument('formato', {\n    help: 'Formato de compresión (gzip por defecto)',\n    choices: ['gzip'],\n});\n\nconst args = parser.parseArgs();\n\n// Llamar a la función de compresión\nif (args.formato === 'gzip') {\n    comprimirGzip(args.archivo);\n}\n\n"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n_______________________________________________________\n#41 CAMISETA RAR\n-------------------------------------------------------\n* EJERCICIO:\n * ¿Has visto la camiseta.rar?\n * https://x.com/MoureDev/status/1841531938961592740\n *\n * Crea un programa capaz de comprimir un archivo \n * en formato .zip (o el que tú quieras).\n * - No subas el archivo o el zip.\n */\n// ________________________________________________________\nconst fs = require('fs');\nconst path = require('path');\nconst archiver = require('archiver');\n\nfunction compressFile(sourceFile, zipFile) {\n    if (!fs.existsSync(sourceFile)) {\n        throw new Error(`El archivo fuente '${sourceFile}' no existe.`);\n    }\n\n    const zipDir = path.dirname(zipFile) || '.';\n    if (!fs.existsSync(zipDir)) {\n        throw new Error(`El directorio '${zipDir}' no existe.`);\n    }\n\n    if (fs.existsSync(zipFile)) {\n        throw new Error(`El archivo zip '${zipFile}' ya existe.`);\n    }\n\n    const output = fs.createWriteStream(zipFile);\n    const archive = archiver('zip', {\n        zlib: { level: 9 } // Nivel de compresión (máximo)\n    });\n\n    return new Promise((resolve, reject) => {\n        output.on('close', () => {\n            console.log(`Comprimido exitosamente '${sourceFile}' a '${zipFile}'`);\n            resolve();\n        });\n\n        archive.on('error', (err) => {\n            reject(new Error(`Se produjo un error al comprimir el archivo: ${err.message}`));\n        });\n\n        archive.pipe(output);\n        archive.file(sourceFile, { name: path.basename(sourceFile) });\n        archive.finalize();\n    });\n}\n\n// Ejemplo de uso\ncompressFile('people.json', 'file.zip')\n    .then(() => console.log('Operación completada.'))\n    .catch(err => console.error(err.message));\n"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/javascript/miguelex.js",
    "content": "const fs = require('fs');\nconst archiver = require('archiver');\nconst readline = require('readline');\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nfunction preguntar(query) {\n    return new Promise(resolve => rl.question(query, resolve));\n}\n\nasync function main() {\n    console.log(\"Selecciona lo que quieres comprimir:\");\n    console.log(\"1. Archivo\");\n    console.log(\"2. Directorio\");\n    const tipoSeleccionado = await preguntar('Tu elección: ');\n\n    let tipo;\n    if (tipoSeleccionado === '1') {\n        tipo = 'archivo';\n    } else if (tipoSeleccionado === '2') {\n        tipo = 'directorio';\n    } else {\n        console.log(\"Selección no válida\");\n        rl.close();\n        return;\n    }\n\n    const inputPath = await preguntar(`Introduce la ruta del ${tipo} que deseas comprimir: `);\n    const nombreSalida = await preguntar(\"Introduce el nombre de salida (sin la extensión): \") + '.zip';\n\n    const output = fs.createWriteStream(nombreSalida);\n    const archive = archiver('zip', {\n        zlib: { level: 9 }\n    });\n\n    output.on('close', function () {\n        console.log(`Archivo comprimido con éxito en ${nombreSalida}, total ${archive.pointer()} bytes`);\n        rl.close();\n    });\n\n    archive.on('error', function (err) {\n        throw err;\n    });\n\n    archive.pipe(output);\n\n    if (tipo === 'archivo') {\n        archive.file(inputPath, { name: require('path').basename(inputPath) });\n    } else {\n        archive.directory(inputPath, false);\n    }\n\n    archive.finalize();\n}\n\nmain();\n"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/javascript/pedamoci.js",
    "content": "import fs from \"fs\"\nimport { stat } from \"fs/promises\"\nimport zlib from \"zlib\"\nimport { pipeline } from \"stream/promises\"\n\nconst filePathToCompress = \"archivo.txt\"\nconst pathToCompressedFileSaved = \"archivo.txt.gz\"\n\nasync function compressFile(inputPath, outboundPath) {\n  const reading = fs.createReadStream(inputPath)\n\n  const compresion = zlib.createGzip()\n\n  const writing = fs.createWriteStream(outboundPath)\n\n  try {\n    await pipeline(reading, compresion, writing)\n    console.log('✅ File successfully compressed')\n  } catch (e) {\n    console.error('❌ Compression failed:', e)\n  }\n}\n\nasync function checkSize(inputPath) {\n  const size = await stat(inputPath)\n  return size.size\n}\n\nasync function program(inputPath, outboundPath) {\n  const initialSize = await checkSize(inputPath)\n\n  console.info(\"Initial file size: \" + initialSize)\n\n  await compressFile(inputPath, outboundPath)\n\n  const finalSize = await checkSize(outboundPath)\n\n  console.info(\"Final file size: \" + finalSize)\n}\n\nprogram(filePathToCompress, pathToCompressedFileSaved)"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/kotlin/Rickmij.kt",
    "content": "\nimport net.lingala.zip4j.ZipFile\nimport java.io.File\n\nfun main() {\n    val archive = File(\"\") //dirección del archivo (hasta el propio archivo)\n    val out = \"\" //dirección de destino (incluyyendo nombre que le pongamos al archivo comprimido)\n\n    val archives = listOf(File(\"\"), File(\"\"))\n    //Poner en la lista los distintos archivos a comprimir\n\n    val folder = File(\"\")\n    //Dirección de la carpeta que vayamos a comprimir\n\n    //Llamamos a una función y al ejecutar el programa ya comprime donde hayamos especificado\n    \n    /*\n    Podríamos combinar y crear el archivo comprimiedo y posteriormente añadirle una carpeta o archivos\n    con estas mismas funciones, pues además de crearlos, permite añadir archivos\n     */\n}\n\n// función que comprime 1 archivo\nfun archiveToZip(file: File, destiny: String) {\n    val zip = ZipFile(destiny)\n    zip.addFile(file)\n}\n\n// función que comprime varios archivos\nfun someArchivesToZip(files: List<File>, destiny: String) {\n    val zip = ZipFile(destiny)\n    zip.addFiles(files)\n}\n\n// función que comprime una carpeta\nfun archivesWithFolderToZip(folder: File, destiny: String) {\n    val zip = ZipFile(destiny)\n    zip.addFolder(folder)\n}\n"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/kotlin/blackriper.kt",
    "content": "import kotlinx.coroutines.Dispatchers\r\nimport kotlinx.coroutines.delay\r\nimport kotlinx.coroutines.launch\r\nimport kotlinx.coroutines.runBlocking\r\nimport net.lingala.zip4j.ZipFile\r\nimport net.lingala.zip4j.model.ZipParameters\r\nimport net.lingala.zip4j.model.enums.AesKeyStrength\r\nimport net.lingala.zip4j.model.enums.EncryptionMethod\r\nimport net.lingala.zip4j.progress.ProgressMonitor\r\nimport java.io.File\r\n\r\n// libreria para comprimir\r\n//https://github.com/srikanth-lingala/zip4j\r\n\r\n//1.- crear una factoria para simplificar la liberia opcional\r\nclass ZipFactory{\r\n   var password: String=\"\"\r\n   var folder:File?=null\r\n   var files:List<File> = emptyList()\r\n   var dirOut: String=\"\"\r\n\r\n\r\n   private val zipParamaters=ZipParameters().apply {\r\n       isEncryptFiles=true\r\n       encryptionMethod= EncryptionMethod.AES\r\n       aesKeyStrength= AesKeyStrength.KEY_STRENGTH_256\r\n   }\r\n\r\n    internal fun buildZip():ZipFile{\r\n\r\n       if (password.isNotEmpty() && folder!=null) {\r\n           return ZipFile(\"$dirOut\",password.toCharArray()).apply {\r\n               addFolder(folder,zipParamaters)\r\n           }\r\n       }\r\n       if (files.isNotEmpty() && password.isNotEmpty()){\r\n           return ZipFile(\"$dirOut\",password.toCharArray()).apply {\r\n               if (files.size==1) addFile(files.first(),zipParamaters) else addFiles(files,zipParamaters)\r\n           }\r\n       }\r\n\r\n       if (folder!=null) return  ZipFile(\"$dirOut\").apply {addFolder(folder)}\r\n\r\n       return ZipFile(\"$dirOut\").apply {\r\n           if (files.size==1) addFile(files.first()) else addFiles(files)\r\n        }\r\n      }\r\n\r\n}\r\n\r\nfun zipFactory(block: ZipFactory.()-> Unit):ZipFactory= ZipFactory().apply(block)\r\n\r\n\r\n//1.- definir comportamiento\r\n\r\ninterface Compress {\r\n    suspend fun compressZipFolder(folderName: File, pass: String?): ZipFile\r\n    suspend fun compressZipFiles(filesCompress: List<File>, pass: String?,nameZip: String): ZipFile\r\n}\r\n\r\ninterface FactoryCompress{\r\n    suspend fun readFiles()\r\n    suspend fun compressData(): ZipFile\r\n}\r\n\r\n//2.- Crear implementaciones\r\n\r\nclass ZipCompress:Compress{\r\n    override suspend fun compressZipFolder(folderName: File, pass: String?): ZipFile {\r\n       if (pass!=null) return  zipFactory {\r\n           folder=folderName\r\n           password=pass\r\n           dirOut=\"src/main/resources/${folderName.name}.zip\"\r\n       }.buildZip()\r\n\r\n      return zipFactory {\r\n          folder=folderName\r\n          dirOut=\"src/main/resources/${folderName.name}.zip\"\r\n      }.buildZip()\r\n\r\n    }\r\n\r\n    override suspend fun compressZipFiles(\r\n        filesCompress: List<File>,\r\n        pass: String?,\r\n        nameZip: String\r\n    ): ZipFile {\r\n        if (pass!=null) return  zipFactory {\r\n            files=filesCompress\r\n            password=pass\r\n            dirOut=\"src/main/resources/${nameZip}.zip\"\r\n        }.buildZip()\r\n\r\n        return zipFactory {\r\n            files=filesCompress\r\n            dirOut=\"src/main/resources/${nameZip}.zip\"\r\n        }.buildZip()\r\n   }\r\n\r\n}\r\n\r\nclass Factory(private val zip:ZipCompress):FactoryCompress{\r\n    private var filesReading:MutableList<File> =mutableListOf()\r\n    private var folderName: String=\"\"\r\n\r\n     override suspend fun readFiles() {\r\n        println(\"you are going to compress a folder o file ?\")\r\n        val option= readLine().toString().lowercase()\r\n\r\n        when(option){\r\n            \"folder\"-> {\r\n                println(\"Enter the path value where the folder is located\")\r\n                folderName=readLine().toString()\r\n            }\r\n            \"file\"-> readMultipleFiles()\r\n        }\r\n    }\r\n\r\n    override suspend fun compressData(): ZipFile {\r\n        val password =addEncrpty()\r\n        if (folderName.isEmpty()) return zip.compressZipFiles(filesReading,password,\"files\")\r\n        return zip.compressZipFolder(File(folderName),password)\r\n\r\n    }\r\n\r\n    private fun  readMultipleFiles(){\r\n        var option=\"\"\r\n        while (option!=\"N\"){\r\n            println(\"Enter the path value where the file is located\")\r\n            val path= readLine().toString()\r\n            if (path.isEmpty()){\r\n                println(\"the path is empty\")\r\n                continue\r\n            }\r\n            val file= File(path)\r\n            filesReading.add(file)\r\n            println(\"there is another file to add (Y/N)\")\r\n            option=readLine().toString().uppercase()\r\n        }\r\n    }\r\n\r\n    private fun addEncrpty(): String?{\r\n        println(\"you want to add a key to your compress file password(optional)\")\r\n        return readlnOrNull()\r\n     }\r\n}\r\n\r\n\r\n\r\n\r\nfun main() = runBlocking{\r\n  val zip=ZipCompress()\r\n  val factory=Factory(zip)\r\n  val job= launch(Dispatchers.IO) {\r\n      factory.readFiles()\r\n      val zipFile = factory.compressData().run {\r\n          val progressMonitor = this.progressMonitor\r\n          this.isRunInThread = true\r\n          if (progressMonitor.result == ProgressMonitor.Result.SUCCESS) println(\"Successfully added folder to zip\")\r\n          if (progressMonitor.result == ProgressMonitor.Result.ERROR) println(\"Error occurred. Error message: \" + progressMonitor.exception.message);\r\n          else if (progressMonitor.result == ProgressMonitor.Result.CANCELLED) println(\"Task cancelled\")\r\n      }\r\n  }\r\n   job.join()\r\n}"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/php/edalmava.php",
    "content": "<?php\nfunction crearYComprimirArchivo($mensaje, $nombreTxt = \"mensaje.txt\", $nombreZip = \"archivo_comprimido.zip\") {\n    // Crear el archivo de texto con el mensaje\n    file_put_contents($nombreTxt, $mensaje);\n    echo \"Archivo de texto '$nombreTxt' creado con el mensaje.\\n\";\n\n    // Crear y abrir el archivo .zip\n    $zip = new ZipArchive();\n    if ($zip->open($nombreZip, ZipArchive::CREATE) === TRUE) {\n        // Añadir el archivo de texto al archivo .zip\n        $zip->addFile($nombreTxt, basename($nombreTxt));\n        $zip->close();\n        echo \"Archivo comprimido como '$nombreZip'.\\n\";\n    } else {\n        echo \"Error al crear el archivo .zip.\\n\";\n    }\n\n    // Eliminar el archivo de texto después de comprimirlo, si no quieres conservarlo\n    if (file_exists($nombreTxt)) {\n        unlink($nombreTxt);\n        echo \"Archivo de texto '$nombreTxt' eliminado después de la compresión.\\n\";\n    }\n}\n\n// Ejemplo de uso\n$mensaje = \"Este es un mensaje corto dentro del archivo de texto.\";\ncrearYComprimirArchivo($mensaje);\n"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/php/miguelex.php",
    "content": "<?php\n\nfunction comprimirArchivoEnZip($archivo, $nombreZip) {\n    $zip = new ZipArchive();\n    if ($zip->open($nombreZip, ZipArchive::CREATE) === TRUE) {\n        $zip->addFile($archivo, basename($archivo));\n        $zip->close();\n        echo \"Archivo comprimido con éxito en $nombreZip\\n\";\n    } else {\n        echo \"Error al crear el archivo ZIP\\n\";\n    }\n}\n\nfunction comprimirDirectorioEnZip($directorio, $nombreZip) {\n    $zip = new ZipArchive();\n\n    function agregarDirectorioAlZip($carpeta, $zip, $carpetaRaiz) {\n        $archivos = scandir($carpeta);\n        foreach ($archivos as $archivo) {\n            if ($archivo == '.' || $archivo == '..') continue;\n            $rutaCompleta = $carpeta . '/' . $archivo;\n            $rutaEnZip = $carpetaRaiz . '/' . $archivo;\n            if (is_file($rutaCompleta)) {\n                $zip->addFile($rutaCompleta, $rutaEnZip);\n            } elseif (is_dir($rutaCompleta)) {\n                $zip->addEmptyDir($rutaEnZip);\n                agregarDirectorioAlZip($rutaCompleta, $zip, $rutaEnZip);\n            }\n        }\n    }\n\n    if ($zip->open($nombreZip, ZipArchive::CREATE) === TRUE) {\n        agregarDirectorioAlZip($directorio, $zip, basename($directorio));\n        $zip->close();\n        echo \"Directorio comprimido con éxito en $nombreZip\\n\";\n    } else {\n        echo \"Error al crear el archivo ZIP\\n\";\n    }\n}\n\nfunction comprimirEnRar($input, $nombreRar, $tipo) {\n    if ($tipo == 'archivo') {\n        $comando = \"rar a $nombreRar $input\";\n    } else {\n        $comando = \"rar a -r $nombreRar $input\"; // Opción -r para incluir subdirectorios\n    }\n    \n    exec($comando, $salida, $resultado);\n    if ($resultado === 0) {\n        echo \"Archivo/directorio comprimido en RAR con éxito: $nombreRar\\n\";\n    } else {\n        echo \"Error al comprimir en RAR\\n\";\n    }\n}\n\nfunction comprimir($input, $tipo, $formato, $nombreSalida) {\n    if ($formato == 'zip') {\n        if ($tipo == 'archivo') {\n            comprimirArchivoEnZip($input, $nombreSalida);\n        } else {\n            comprimirDirectorioEnZip($input, $nombreSalida);\n        }\n    } elseif ($formato == 'rar') {\n        comprimirEnRar($input, $nombreSalida, $tipo);\n    } else {\n        echo \"Formato de compresión no soportado\\n\";\n    }\n}\n\necho \"Selecciona lo que quieres comprimir:\\n\";\necho \"1. Archivo\\n\";\necho \"2. Directorio\\n\";\n$tipoSeleccionado = trim(fgets(STDIN));\n\nif ($tipoSeleccionado == '1') {\n    $tipo = 'archivo';\n} elseif ($tipoSeleccionado == '2') {\n    $tipo = 'directorio';\n} else {\n    die(\"Selección no válida\\n\");\n}\n\necho \"Introduce la ruta del $tipo que deseas comprimir: \";\n$input = trim(fgets(STDIN));\n\necho \"Selecciona el formato de compresión:\\n\";\necho \"1. ZIP\\n\";\necho \"2. RAR\\n\";\n$formatoSeleccionado = trim(fgets(STDIN));\n\nif ($formatoSeleccionado == '1') {\n    $formato = 'zip';\n} elseif ($formatoSeleccionado == '2') {\n    $formato = 'rar';\n} else {\n    die(\"Formato no válido\\n\");\n}\n\necho \"Introduce el nombre de salida (sin la extensión): \";\n$nombreSalida = trim(fgets(STDIN));\n\nif ($formato == 'zip') {\n    $nombreSalida .= '.zip';\n} elseif ($formato == 'rar') {\n    $nombreSalida .= '.rar';\n}\n\ncomprimir($input, $tipo, $formato, $nombreSalida);\n\n?>\n"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/python/CarlosVR48.py",
    "content": "\"\"\"\nEJERCICIO:\n¿Has visto la camiseta.rar?\nhttps://x.com/MoureDev/status/1841531938961592740\n\nCrea un programa capaz de comprimir un archivo en formato .zip (o el que tú quieras).\nNo subas el archivo o el zip.\n \"\"\"\n\nimport zipfile,os\n\narchivo_org = input(\"DIME EL ARCHIVO A COMPRIMIR? <nombre.extension>: \")\narchivo_zip=input (\"QUE NOMBRE LE QUIERES PONER AL ARCHIVO COMPRIMIDO? <nombre.zip>: \")\n\ntry:    \n    \n    with zipfile.ZipFile(archivo_zip, mode='w') as comprime:\n        print (\"\\nCOMPRIMIENDO ........\")\n        comprime.write(archivo_org)\n        print (f\"\\nEL ARCHIVO {archivo_org} a sido satisfactoria.\")\n        comprime.printdir()\nexcept:\n    os.remove(archivo_zip)\n    print(\"\\nNO SE HA PODIDO CREAR EL ARCHIVO!!!\")\n\nprint()\n"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/python/EmmanuelMMontesinos.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * ¿Has visto la camiseta.rar?\n * https://x.com/MoureDev/status/1841531938961592740\n *\n * Crea un programa capaz de comprimir un archivo \n * en formato .zip (o el que tú quieras).\n * - No subas el archivo o el zip.\n */\n\"\"\"\n\nimport zipfile\nimport os\n\nclass ZipFileManager:\n    def __init__(self, path):\n        self.path = path\n        self.name = os.path.splitext(os.path.basename(self.path))[0]\n\n    def compress(self):\n        with zipfile.ZipFile(f\"{self.name}.zip\", mode=\"w\") as archive:\n            archive.write(self.path)\n\n# prueba\nif __name__ == \"__main__\":\n    manager = ZipFileManager(\"RUTA_DE_ARCHIVO_O_CARPETA\")\n    manager.compress()"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/python/Gordo-Master.py",
    "content": "# 41 - Camiseta RAR\n\nimport zipfile\nimport os\n\ndef zip_file(path:str, file: str) -> str:\n    \n    file_path = os.path.join(path, file)\n\n    if os.path.exists(file_path):\n\n        zip_file_name = f\"{file}.zip\"\n        zip_file_path = os.path.join(path, zip_file_name)\n\n        with zipfile.ZipFile(zip_file_path, \"w\", zipfile.ZIP_DEFLATED) as zip_file:\n            zip_file.write(file_path, file)\n            print(f\"Archivo {file} comprimido como {zip_file_name}\")\n            return file\n\n    else:\n        print(f\"El archivo {file} no existe en el directorio {path}\")\n    \n    return None\n\ndef unzip_file(path: str, file: str):\n\n    file_path = os.path.join(path, file)\n\n    if os.path.exists(file_path):\n\n        zip_path = os.path.join(path, file)\n\n        with zipfile.ZipFile(zip_path, \"r\") as zipf:\n            zipf.extractall(path)\n            print(f\"Archivo {file} descomprimido como {path}\")\n\n    else:\n        print(f\"El archivo {file} no existe en el directorio {path}\")\n\n\npath = os.path.dirname(os.path.abspath(__file__))\nfile = \"text.txt\"\n\nzip = zip_file(path,file)\n\nif zip != None:\n\n    # Borro el fichero original antes de descomprimir el zip\n    os.remove(os.path.join(path,zip))\n\n    unzip_file(path,zip)"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/python/JesusWay69.py",
    "content": "import os, platform, zipfile\nfrom datetime import datetime\nif (platform.platform().startswith(\"macOS\") or platform.platform().startswith(\"Linux\")):\n    os.system('clear')\nelse:\n    os.system('cls')\n\n\"\"\" * EJERCICIO:\n * ¿Has visto la camiseta.rar?\n * https://x.com/MoureDev/status/1841531938961592740\n *\n * Crea un programa capaz de comprimir un archivo \n * en formato .zip (o el que tú quieras).\n * - No subas el archivo o el zip.\"\"\"\n\ncurrent_datetime = datetime.today().strftime(\"%Y_%m_%d_%H_%M_%S\")#Creamos un objeto datetime\nzip_name = \"python_zip\" + current_datetime + \".zip\"#Guardamos en una variable el nombre del zip a crear\nnew_folder = \"files\"                             # añadiendo la fecha y hora para que siempre sea un fichero único\nrelative_path = \"#41 - ZIP/\" + new_folder + \"/\" \n\nif not os.path.exists(\"./\" + new_folder):#Si no existe creamos una carpeta dentro del directorio del ejercicio\n    os.mkdir(\"./\" + new_folder)\nelse:\n    print(\"El directorio ya existe en esta ubicación\")\n\nfor i in range(5):#Generamos 5 archivos txt numerados dentro de la carpeta creada\n    with open(f\"#41 - ZIP/{new_folder}/file{i+1}.txt\", \"w\") as file: \n        file.write(f\"Este es el fichero nº {i+1}\")#Añadimos texto descriptivo en cada fichero\n\n\n\ndef zip_files(zip_name, relative_path):#Creamos una función para generar el zip\n    with zipfile.ZipFile(zip_name, 'w', zipfile.ZIP_DEFLATED) as zip_file:#Creamos el zip\n        os.chdir(relative_path)#Cambiamos el directorio al de la nueva carpeta\n        for file in os.listdir(\"./\"):#Recorremos el contenido de la nueva carpeta con los 5 ficheros txt\n            zip_file.write(file)     # y los añadimos al zip\n\n\nzip_files(zip_name, relative_path)\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n# current_datetime = datetime.today().strftime(\"%Y_%m_%d_%H_%M_%S\")\n# backup = \"#41 - ZIP/files/\"\n# zip_name = \"#41 - ZIP/files/python_zip\" + current_datetime + \".zip\"\n# os.chdir(backup)\n# files_folder = os.listdir(\"./\")\n# with zipfile.ZipFile(zip_name, \"w\", zipfile.ZIP_DEFLATED) as zip_file:\n\n#     for root, dir, files in os.walk(backup):\n#         for file in file:\n#             path = os.path.join(root, file)\n#             zip_file.write(backup+file, compress_type=zipfile.ZIP_DEFLATED)"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/python/Nicojsuarez2.py",
    "content": "# #41 CAMISETA RAR\n> #### Dificultad: Fácil | Publicación: 07/10/24 | Corrección: 14/10/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * ¿Has visto la camiseta.rar?\n * https://x.com/MoureDev/status/1841531938961592740\n *\n * Crea un programa capaz de comprimir un archivo \n * en formato .zip (o el que tú quieras).\n * - No subas el archivo o el zip.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/python/Rickmij.py",
    "content": "\nimport os\nimport zipfile\n\n# Comprimir 1 archivo\ndef archive_to_zip(archive, destiny):\n    zip_archive = zipfile.ZipFile(destiny, \"w\")\n    #con basename aseguramos que añada el último elemento y no toda la ruta\n    zip_archive.write(archive, os.path.basename(archive))\n\n# Comprimir varios archivos\ndef archives_to_zip(archives, destiny):\n    zip_archive = zipfile.ZipFile(destiny, \"w\")\n    for archiv in archives:\n        zip_archive.write(archiv, os.path.basename(archiv))\n\n# Comprimir una carpeta\ndef folder_to_zip(folder, destiny):\n    zip_archive = zipfile.ZipFile(destiny, \"w\")\n    # _ es para variables que no hay por qué declarar porque no vamos a usar.\n    # Aquí serían las subcarpetas \n    for root, _, files in os.walk(folder):\n        for file in files:\n            # recorremos los archivos y combinamos en un path la raíz (root) con el archivo en cuestión\n            file_path = os.path.join(root, file)\n\n            # cogemos una ruta relativa dentro del archivo zip\n            archive_name = os.path.relpath(file_path, os.path.dirname(folder))\n        \n            zip_archive.write(file_path, archive_name)\n\narchive = \"\" #archivo que queramos (incluyendo el .txt final)\n\narchives = [\"\", \"\"] #ponemos en la lista los archivos que queramos añadir\n\nfolder = \"\" #dirección de la carpeta (con nombre incluído)\n\ndestiny = \"\" #ubicación del destino (con nombre del .zip incluído)\n"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/python/SooHav.py",
    "content": "# 41 - CAMISETA RAR\nimport zipfile\nimport os\nimport gzip\nimport shutil\n\n\n# ZIPFILE\n\"\"\"\nzipfile - Módulo para trabajar con archivos ZIP\n\nEste módulo proporciona herramientas para crear, leer, escribir, agregar y listar archivos ZIP.\nPermite manipular archivos comprimidos utilizando diferentes algoritmos de compresión.\n\nCLASE: class zipfile.ZipFile(file, mode='r', compression=ZIP_STORED, allowZip64=True,\n                  compresslevel=None, *, strict_timestamps=True)\n\nEsta clase permite abrir, crear y manipular archivos ZIP. Los archivos ZIP pueden ser comprimidos\nutilizando diferentes algoritmos de compresión.\n\nParámetros del constructor:\n---------------------------\nfile : str\n    El nombre del archivo ZIP que se va a abrir o crear.\n\nmode : str, opcional\n    Especifica cómo se debe abrir el archivo. Los valores posibles son:\n    - 'r': Leer un archivo ZIP existente.\n    - 'w': Truncar y escribir un nuevo archivo ZIP. Esto sobrescribirá\n      cualquier archivo ZIP existente con el mismo nombre.\n    - 'a': Agregar archivos a un archivo ZIP existente. Si el archivo no\n      existe, se creará.\n    - 'x': Crear y escribir un nuevo archivo ZIP, pero fallará si el\n      archivo ya existe.\n\ncompression : int, opcional\n    Define el método de compresión a utilizar al escribir el archivo. Las\n    opciones disponibles son:\n    - ZIP_STORED: No comprime los archivos. Simplemente almacena los\n      archivos sin comprimirlos.\n    - ZIP_DEFLATED: Utiliza el algoritmo de compresión DEFLATE (el más\n      común y utilizado).\n    - ZIP_BZIP2: Utiliza el algoritmo BZIP2 para la compresión.\n    - ZIP_LZMA: Utiliza el algoritmo LZMA para la compresión, que ofrece\n      una mejor tasa de compresión que DEFLATE, pero puede ser más lento.\n\nallowZip64 : bool, opcional\n    Si se establece en True, permite crear archivos ZIP de más de 4 GiB.\n    Por defecto, está habilitado.\n\ncompresslevel : int, opcional\n    Permite especificar el nivel de compresión (de 0 a 9) cuando se usa\n    ZIP_DEFLATED. Un nivel más alto implica más compresión pero más tiempo\n    de procesamiento.\n\nstrict_timestamps : bool, opcional\n    Si se establece en True, el código se apegará estrictamente a las\n    marcas de tiempo al crear archivos ZIP.\n\nMÉTODOS PRINCIPALES:\n---------------------\nextract(self, member, path=None, pwd=None):\n    Extrae el contenido de un archivo ZIP específico y lo guarda en\n    el directorio especificado. Si no se proporciona un directorio, se utilizará\n    el directorio de trabajo actual.\n\n    Parámetros:\n    -----------\n    member : str o ZipInfo\n        El nombre completo del miembro a extraer o un objeto ZipInfo que\n        representa el archivo dentro del archivo ZIP.\n\n    path : str, opcional\n        El directorio donde se extraerá el archivo. Si no se proporciona, el\n        archivo se extraerá en el directorio de trabajo actual.\n\n    pwd : bytes, opcional\n        La contraseña utilizada para archivos ZIP cifrados. Si el archivo no\n        está cifrado, este parámetro se puede omitir.\n\nclose(self):\n    Cierra el archivo ZIP.\n\nextractall(self, path=None, members=None, pwd=None):\n    Extrae todos los miembros del archivo ZIP al directorio especificado.\n\ngetinfo(self, name):\n    Devuelve un objeto ZipInfo para el miembro especificado.\n\nnamelist(self):\n    Devuelve una lista de nombres de los miembros del archivo ZIP.\n\nprintdir(self):\n    Imprime en la consola la lista de miembros del archivo ZIP.\n\nread(self, name, pwd=None):\n    Lee el contenido del miembro especificado y lo devuelve como bytes.\n\nwrite(self, filename, arcname=None, compress_type=None):\n    Añade un archivo al archivo ZIP.\n\nwritestr(self, zinfo_or_arcname, data, compress_type=None):\n    Escribe una cadena de texto como un miembro en el archivo ZIP.\n\nsetpassword(self, pwd):\n    Establece una contraseña para el archivo ZIP.\n\ninfolist(self):\n    Devuelve una lista de objetos ZipInfo que representan los miembros\n    del archivo ZIP. Esto permite iterar sobre los archivos dentro del ZIP.\n\ntestzip(self):\n    Prueba todos los miembros del archivo ZIP y devuelve el nombre\n    del primer archivo que falla.\n\n\"\"\"\n\n\ndef compress_with_zipfile(filename, output_dir):\n    if not os.path.exists(filename):\n        print(f\"Error: No se encontró el archivo '{filename}'.\")\n        return\n\n    # Asegurar que el directorio de salida existe\n    if not os.path.exists(output_dir):\n        os.makedirs(output_dir)\n\n    # Definir la ruta completa del archivo comprimido\n    output_path = os.path.join(output_dir, os.path.basename(filename) + \".zip\")\n\n    # Verificar si el archivo comprimido ya existe\n    if os.path.exists(output_path):\n        respuesta = input(\n            f\"El archivo '{output_path}' ya existe. ¿Deseas reemplazarlo? (s/n): \")\n        if respuesta.lower() != 's':\n            print(\"Operación cancelada. No se ha comprimido el archivo.\")\n            return\n\n    try:\n        # Comprimir el archivo\n        with zipfile.ZipFile(output_path, 'w', zipfile.ZIP_DEFLATED, compresslevel=8) as zipf:\n            zipf.write(filename, os.path.basename(filename))\n        print(f\"Archivo comprimido guardado en: {output_path}\")\n    except Exception as e:\n        print(f\"Error al comprimir el archivo: {e}\")\n\n\ndef decompress_with_zipfile(zip_filename, output_dir):\n    if not os.path.exists(zip_filename):\n        print(f\"Error: No se encontró el archivo '{zip_filename}'.\")\n        return\n\n    # Asegurar de que el directorio de salida exista\n    if not os.path.exists(output_dir):\n        os.makedirs(output_dir)\n\n    try:\n        with zipfile.ZipFile(zip_filename, 'r') as zipf:\n            # Descomprimir uno o varios archivos del zip\n            for item in zipf.infolist():\n                extracted_file_path = os.path.join(output_dir, item.filename)\n\n                # Verificar si el archivo a descomprimir ya existe\n                if os.path.exists(extracted_file_path):\n                    respuesta = input(\n                        f\"El archivo '{extracted_file_path}' ya existe. ¿Deseas reemplazarlo? (s/n): \")\n                    if respuesta.lower() != 's':\n                        print(f\"Archivo '{item.filename}' no reemplazado.\")\n                        continue\n\n                # Extraer el archivo\n                zipf.extract(item, output_dir)\n                print(f\"Archivo '{item.filename}' descomprimido en: {\n                      output_dir}\")\n\n    except Exception as e:\n        print(f\"Error al descomprimir el archivo: {e}\")\n\n\n# Uso\nfilename = \"/home/sofiah/Documentos/temporal/clientes-exportados.csv\"\noutput_dir = \"/home/sofiah/Documentos/temporal/comprimidos\"\ncompress_with_zipfile(filename, output_dir)\n\nzip_filename = \"/home/sofiah/Documentos/temporal/aglomerados_eph_json.zip\"\noutput_dir = \"/home/sofiah/Documentos/temporal/descompresion\"\ndecompress_with_zipfile(zip_filename, output_dir)\n\n\n# GZIP\n\"\"\"\nEste módulo proporciona una interfaz simple para comprimir y descomprimir archivos en formato gzip.\n\nLa compresión de datos es proporcionada por el módulo zlib. El formato gzip se usa\nen sistemas Unix/Linux para la compresión de archivos, especialmente archivos de texto.\n\n1. Funciones del módulo:\n   - gzip.open(filename, mode='rb', compresslevel=9, encoding=None, errors=None, newline=None):\n     Abre un archivo comprimido gzip en modo binario o de texto, retornando un objeto de archivo.\n     - `filename`: Nombre de archivo.\n     - `mode`: Puede ser 'r', 'rb', 'a', 'ab', 'w', 'wb', 'x', 'xb' para modo binario, o 'rt', 'at', \n     'wt', 'xt' para modo texto. El valor predeterminado es 'rb'.\n     - `compresslevel`: Un entero de 0 a 9 que define el nivel de compresión.\n     - Los argumentos `encoding`, `errors`, y `newline` son utilizados solo en modo texto.\n\n   - gzip.compress(data, compresslevel=9):\n     Comprime los datos proporcionados (bytes) y retorna los datos comprimidos. El argumento `compresslevel` \n     es un entero de 0 a 9 que controla el nivel de compresión, siendo 1 la compresión más rápida y 9 la más \n     lenta pero con la mayor compresión.\n\n   - gzip.decompress(data):\n     Descomprime los datos comprimidos (bytes) y retorna los datos originales. Se espera que los datos de \n     entrada sean un objeto bytes.\n\n2. Clase `GzipFile`: gzip.GzipFile(filename=None, mode=None, compresslevel=9, fileobj=None, mtime=None):\n    \n    Constructor para la clase `GzipFile`, que simula la mayoría de los métodos de un objeto de archivo \n    (excepto `truncate()`). Debe proporcionarse al menos uno de `fileobj` o `filename`.\n\n    - `filename`: Nombre del archivo a abrir.\n    - `mode`: Modo de apertura ('r', 'rb', 'a', 'ab', 'w', 'wb', 'x', 'xb'). Por defecto es 'rb'.\n    - `compresslevel`: Controla el nivel de compresión (0 a 9).\n    - `fileobj`: Archivo, objeto `io.BytesIO` o cualquier objeto que simule un archivo. Si es `None`, \n      se abrirá `filename`.\n    - `mtime`: Timestamp en formato Unix (segundos desde el 1 de enero de 1970). Por defecto, se usa \n      la hora actual.\n\n    El método `close()` de un objeto `GzipFile` no cierra `fileobj`, permitiendo agregar más datos \n    después de la compresión. \n\"\"\"\n\n\ndef compress_with_gzip(filename, output_dir):\n    if not os.path.exists(filename):\n        print(f\"Error: No se encontró el archivo '{filename}'.\")\n        return\n\n    # Asegurar que el directorio de salida existe\n    if not os.path.exists(output_dir):\n        os.makedirs(output_dir)\n\n    # Definir la ruta completa del archivo comprimido\n    output_path = os.path.join(output_dir, os.path.basename(filename) + \".gz\")\n\n    # Verificar si el archivo comprimido ya existe\n    if os.path.exists(output_path):\n        respuesta = input(\n            f\"El archivo '{output_path}' ya existe. ¿Deseas reemplazarlo? (s/n): \")\n        if respuesta.lower() != 's':\n            print(\"Operación cancelada. No se ha comprimido el archivo.\")\n            return\n\n    try:\n        # Comprimir el archivo\n        with open(filename, 'rb') as f_in:\n            with gzip.GzipFile(output_path, 'wb', compresslevel=9) as f_out:\n                shutil.copyfileobj(f_in, f_out)\n        print(f\"Archivo comprimido guardado en: {output_path}\")\n    except Exception as e:\n        print(f\"Error al comprimir el archivo: {e}\")\n\n\ndef decompress_with_gzip(gzip_filename, output_dir):\n    if not os.path.exists(gzip_filename):\n        print(f\"Error: No se encontró el archivo '{gzip_filename}'.\")\n        return\n\n    # Asegurar que el directorio de salida existe\n    if not os.path.exists(output_dir):\n        os.makedirs(output_dir)\n\n    # Definir la ruta completa del archivo descomprimido\n    output_path = os.path.join(\n        output_dir, os.path.basename(gzip_filename[:-3]))\n\n    # Verificar si el archivo descomprimido ya existe\n    if os.path.exists(output_path):\n        respuesta = input(\n            f\"El archivo '{output_path}' ya existe. ¿Deseas reemplazarlo? (s/n): \")\n        if respuesta.lower() != 's':\n            print(\"Operación cancelada. No se ha descomprimido el archivo.\")\n            return\n\n    try:\n        # Descomprimir el archivo\n        with gzip.GzipFile(gzip_filename, 'rb') as f_in:\n            with open(output_path, 'wb') as f_out:\n                shutil.copyfileobj(f_in, f_out)\n        print(f\"Archivo descomprimido guardado en: {output_path}\")\n    except Exception as e:\n        print(f\"Error al descomprimir el archivo: {e}\")\n\n\n# Uso\n\nfilename = \"/home/sofiah/Documentos/temporal/clientes-exportados.csv\"\noutput_dir = \"/home/sofiah/Documentos/temporal/comprimidos\"\ncompress_with_gzip(filename, output_dir)\n\ngzip_filename = \"/home/sofiah/Documentos/temporal/comprimidos/clientes-exportados.csv.gz\"\noutput_dir = \"/home/sofiah/Documentos/temporal/descompresion\"\ndecompress_with_gzip(gzip_filename, output_dir)\n"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/python/antroc.py",
    "content": "\n # EJERCICIO:\n # ¿Has visto la camiseta.rar?\n # https://x.com/MoureDev/status/1841531938961592740\n #\n # Crea un programa capaz de comprimir un archivo \n # en formato .zip (o el que tú quieras).\n # - No subas el archivo o el zip.\n #/\n\n\nimport zipfile\nimport os\n\n\ndirectorio_actual = os.path.dirname(__file__)\nnombre_fichero=\"MiFichero.txt\"\nnombre_Zip=\"FicheroComprimido.zip\"\n\nfileToZip = os.path.join(directorio_actual,nombre_fichero)\nZipFile = os.path.join(directorio_actual,nombre_Zip)\n\nwith zipfile.ZipFile(ZipFile, 'w') as ficheroComprimido:\n    ficheroComprimido.write(fileToZip, arcname=nombre_fichero)\n    \n\n    \n"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/python/cdryampi.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * ¿Has visto la camiseta.rar?\n#  * https://x.com/MoureDev/status/1841531938961592740\n#  *\n#  * Crea un programa capaz de comprimir un archivo \n#  * en formato .zip (o el que tú quieras).\n#  * - No subas el archivo o el zip.\n#  */\nimport gzip\nimport zipfile\nimport tarfile\nimport os \nimport tkinter as tk\nfrom tkinter import filedialog\n\n\nclass ControlFiles():\n    __PATH_COMPRESS = ''\n    __FILES_NAMES = []\n\n    def __init__(self) ->None:\n        self.__PATH_COMPRESS = ''\n        self.__FILES_NAMES = []\n\n    def clear(self)-> None:\n        \"\"\"Limpia los atributos de la clase.\"\"\"\n        self.__PATH_COMPRESS = ''\n        self.__FILES_NAMES = []\n        print(\"Se han limpiado la ruta de salida y los ficheros seleccionados.\")\n\n    def compress_files(self, system)->None:\n        \"\"\"Comprime los archivos en el formato indicado.\"\"\"\n        output_file = self.__PATH_COMPRESS\n\n        self.check_files()\n        self.check_folder()\n        if len(self.__FILES_NAMES) > 0:\n            match system:\n                case 'gzip':\n                    output_file = os.path.join(\n                        self.__PATH_COMPRESS,\n                        'archivo_comprimido.gz'\n                    )\n                    self.compress_gzip(output_file)\n                case 'zipfile':\n                    output_file = os.path.join(\n                        self.__PATH_COMPRESS,\n                        'archivo_comprimido.zip'\n                    )\n                    self.compress_zip(output_file)\n                case 'bz2':\n                    output_file = os.path.join(\n                        self.__PATH_COMPRESS,\n                        'archivo_comprimido.tar.bz2'\n                    )\n                    self.compress_tar_bz2(output_file)\n                case _:\n                    print(\"No se ha seleccionado un formato correcto para la compresión.\")\n                    return\n        else:\n            print(f'Aún no tenemos ningún fichero seleccionado')\n    \n    def check_files(self)->None:\n        \"\"\"Elimina archivos de la lista si las rutas son inválidas.\"\"\"\n        for index, file in enumerate(list(self.__FILES_NAMES)):\n            if not os.path.isfile(file):\n                self.__FILES_NAMES.pop(index)\n                print(f'Se ha eliminado el fichero \"{file}\" porque la ruta esta corrupta.')\n\n    def check_folder(self)->None:\n        \"\"\"Establece una carpeta por defecto si no se ha seleccionado ninguna.\"\"\"\n        if not os.path.isdir(self.__PATH_COMPRESS):\n            self.__PATH_COMPRESS = os.getcwd()\n            print(f\"Al no haber ruta hemos asignado la caperta por defecto.\")\n\n    def select_folder_output(self)-> None:\n        \"\"\"Selecciona la carpeta de salida para el archivo comprimido.\"\"\"\n        output_folder = self.select_foler_tk()\n        \n        if output_folder:\n            print(f\"Ruta seleccionada: {output_folder}\")\n            self.__PATH_COMPRESS = output_folder\n        else:\n            print(\"No se seleccionó ninguna carpeta.\")\n\n    def select_files(self)->None:\n        \"\"\"Selecciona los archivos que se quieren comprimir.\"\"\"\n        files = self.select_files_tk()\n        if files:\n            for file in files:\n                self.__FILES_NAMES.append(\n                    file\n                )\n\n    def select_foler_tk(self)-> str:\n        \"\"\"Utiliza tkinter para seleccionar la carpeta de salida.\"\"\"\n        root = tk.Tk()\n        root.withdraw()\n        ruta = filedialog.askdirectory(\n            title=\"Selecciona la carpeta de salida\"\n        )\n        return ruta\n    \n    def select_files_tk(self)-> str:\n        \"\"\"Utiliza tkinter para seleccionar los archivos a comprimir.\"\"\"\n        root = tk.Tk()\n        root.withdraw()\n        archivos = filedialog.askopenfilenames(\n            title=\"Selecciona los ficheros\"\n        )\n        return archivos\n    \n    def compress_zip(self, outputname) -> None:\n        \"\"\"Comprime los archivos seleccionados en un archivo ZIP.\"\"\"\n        with zipfile.ZipFile(outputname, 'w') as zipFile:\n            for file in self.__FILES_NAMES:\n                zipFile.write(\n                    file\n                )\n        print(\"Compresión con zip completada\")\n\n    def compress_gzip(self, output_file):\n        \"\"\"Comprime los archivos seleccionados en formato GZIP.\"\"\"\n        for file in self.__FILES_NAMES:\n            with open(file, 'rb') as f_in:\n                with gzip.open(output_file, 'wb') as f_out:\n                    f_out.writelines(f_in)\n        print(f'Se ha comprimido los ficheros en {output_file}')\n\n    def compress_tar_bz2(self, output_file):\n        \"\"\"Comprime los archivos seleccionados en formato TAR.BZ2.\"\"\"\n        with tarfile.open(output_file, 'w:bz2') as bz2_tar:\n            for file in self.__FILES_NAMES:\n                bz2_tar.add(\n                    file\n                )\n\ndef main():\n    gestion_ficheros = ControlFiles()\n\n    while True:\n        print(\"\\n--- Menú de compresión de ficheros ---\")\n        print(\"1. Seleccionar ficheros a comprimir\")\n        print(\"2. Seleccionar carpeta de salida\")\n        print(\"3. Comprimir archivos (elige formato)\")\n        print(\"   a) gzip\")\n        print(\"   b) zipfile\")\n        print(\"   c) bz2\")\n        print(\"4. Limpiar\")\n        print(\"5. Salir\")\n\n        opcion = input(\"Elige una opción (1-5): \").strip()\n        match opcion:\n            case '1':\n                gestion_ficheros.select_files()\n                if len(gestion_ficheros._ControlFiles__FILES_NAMES) > 0:\n                    print(\"Archivos seleccionados:\")\n                    for file in gestion_ficheros._ControlFiles__FILES_NAMES:\n                        print(f\" - {file}\")\n                else:\n                    print(\"No se seleccionaron archivos.\")\n            case '2':\n                gestion_ficheros.select_folder_output()\n                if gestion_ficheros._ControlFiles__PATH_COMPRESS:\n                    print(f\"Carpeta de salida seleccionada: {gestion_ficheros._ControlFiles__PATH_COMPRESS}\")\n                else:\n                    print(\"No se seleccionó ninguna carpeta.\")\n            case '3':\n                formato = input(\"Elige el formato de compresión (a=gzip, b=zipfile, c=bz2): \").strip().lower()\n                if formato == 'a':\n                    gestion_ficheros.compress_files('gzip')\n                elif formato == 'b':\n                    gestion_ficheros.compress_files('zipfile')\n                elif formato == 'c':\n                    gestion_ficheros.compress_files('bz2')\n                else:\n                    print(\"Formato de compresión no válido.\")\n            case '4':\n                gestion_ficheros.clear()\n            case '5':\n                print(\"Saliendo del programa.\")\n                break\n\n            case _:\n                print(\"Opción no válida, por favor elige una opción entre 1 y 4.\")\n\n\nif __name__ == '__main__':\n    main()"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/python/davidrguez98.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * ¿Has visto la camiseta.rar?\n * https://x.com/MoureDev/status/1841531938961592740\n *\n * Crea un programa capaz de comprimir un archivo \n * en formato .zip (o el que tú quieras).\n * - No subas el archivo o el zip.\n */ \"\"\"\n\n#EJERCICIO\n\nimport zipfile\nimport os\n\ndef zip_file(path: str, file: str) -> str:\n\n    file_path = os.path.join(path, file)\n\n    if os.path.exists(file_path):\n\n        zip_file = f\"{file}.zip\"\n\n        zip_path = os.path.join(path, zip_file)\n\n        with zipfile.ZipFile(zip_path, \"w\", zipfile.ZIP_DEFLATED) as zipf:\n            zipf.write(file_path, file)\n            print(f\"El archivo {file} comprimido como {zip_file}.\")\n            return zip_file\n    \n    else: \n        print(f\"El archivo {file} no existe en el directorio {path}\")\n\n    return None\n\ndef unzip_file(path: str, file: str):\n    \n    file_path = os.path.join(path, file)\n\n    if os.path.exists(file_path):\n\n        zip_path = os.path.join(path, file)\n\n        with zipfile.ZipFile(zip_path, \"r\") as zipf:\n            zipf.extractall(path)\n            print(f\"El archivo {file} descomprimido en {path}.\")\n\n    else: \n        print(f\"El archivo {file} no existe en el directorio {path}\")\n\n\npath = os.path.dirname(os.path.abspath(__file__))\nfile = \"Matisseprint3.pdf\"\n\nzip = zip_file(path, file)\n\nif zip != None:\n\n    os.remove(os.path.join(path, file))\n\n    unzip_file(path, zip)"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/python/duendeintemporal.py",
    "content": "#41 { Retos para Programadores } CAMISETA RAR \n\n# Bibliography reference:\n# I use GPT as a reference and sometimes to correct or generate proper comments.\n\n\"\"\"\n * EJERCICIO:\n * ¿Has visto la camiseta.rar?\n * https://x.com/MoureDev/status/1841531938961592740\n *\n * Crea un programa capaz de comprimir un archivo \n * en formato .zip (o el que tú quieras).\n * - No subas el archivo o el zip.\n\n\"\"\"\n\nlog = print\n\n# zipfile module to create and manipulate ZIP files\nimport zipfile\nimport os\n\n# Function to compress a file\ndef compress_file(input_file_path, output_zip_path):\n    # Create a ZipFile object in write mode\n    with zipfile.ZipFile(output_zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:\n        # Read the file to be compressed\n        zipf.write(input_file_path, os.path.basename(input_file_path))\n    \n    log(f'File compressed and saved as {output_zip_path}')\n\n# Specify the input file path and output zip file name\ninput_file_path = 'C:/Users/Niko Zen/Documents/a Nany.docx'  # Replace with the file path to compress\noutput_zip_path = 'test_output.zip'  # Desired output zip file name\n\n# Compress the file and handle any potential errors\ntry:\n    compress_file(input_file_path, output_zip_path)\n    log('Compression complete!')\nexcept Exception as e:\n    log('Error during compression:', e)\n\n# Possible output: \n# File compressed and saved as test_output.zip\n# Compression complete!\n"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/python/edalmava.py",
    "content": "import zipfile\nimport os\n\ndef crear_y_comprimir_archivo(mensaje, nombre_txt=\"mensaje.txt\", nombre_zip=\"archivo_comprimido.zip\"):\n    # Crear archivo de texto con el mensaje\n    with open(nombre_txt, 'w') as archivo:\n        archivo.write(mensaje)\n    \n    print(f\"Archivo de texto '{nombre_txt}' creado con el mensaje.\")\n\n    # Comprimir el archivo en un archivo .zip\n    with zipfile.ZipFile(nombre_zip, 'w') as archivo_zip:\n        archivo_zip.write(nombre_txt, os.path.basename(nombre_txt), compress_type=zipfile.ZIP_DEFLATED)\n    \n    print(f\"Archivo comprimido como '{nombre_zip}'\")\n\n    # Eliminar el archivo de texto después de comprimirlo\n    os.remove(nombre_txt)\n    print(f\"Archivo de texto '{nombre_txt}' eliminado después de la compresión.\")\n\n# Ejemplo de uso\nmensaje = \"Este es un mensaje corto dentro del archivo de texto.\"\ncrear_y_comprimir_archivo(mensaje)\n"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/python/hectorio23.py",
    "content": "# Autor: Héctor Adán\n# GitHub: https://github.com/hectorio23\n\nimport argparse\nimport zipfile\nimport gzip\nimport bz2\nimport os\n\n# Argumentos mediante ArgumentParser\nparser = argparse.ArgumentParser(description='Comprimir un archivo en diferentes formatos.')\nparser.add_argument('archivo', help='El archivo que se desea comprimir')\nparser.add_argument('formato', choices=['zip', 'gzip', 'bzip'], help='Formato de compresión (zip, gzip, bzip)')\nargs = parser.parse_args()\n\ndef comprimir_archivo(archivo, formato):\n    \"\"\"Comprime un archivo usando la librería estándar de Python según el formato indicado.\"\"\"\n    \n    if formato == \"zip\":\n        with zipfile.ZipFile(f\"{archivo}.zip\", 'w') as zipf:\n            zipf.write(archivo, os.path.basename(archivo))\n        print(f\"Archivo comprimido como: {archivo}.zip\")\n\n    elif formato == \"gzip\":\n        with open(archivo, 'rb') as f_in, gzip.open(f\"{archivo}.gz\", 'wb') as f_out:\n            f_out.writelines(f_in)\n        print(f\"Archivo comprimido como: {archivo}.gz\")\n\n    elif formato == \"bzip\":\n        with open(archivo, 'rb') as f_in, bz2.open(f\"{archivo}.bz2\", 'wb') as f_out:\n            f_out.writelines(f_in)\n        print(f\"Archivo comprimido como: {archivo}.bz2\")\n\n    else:\n        raise ValueError(\"Formato de compresión no soportado.\")\n\n# Llamar a la función de compresión\ncomprimir_archivo(args.archivo, args.formato)\n\n\n"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/python/hozlucas28.py",
    "content": "# pylint: disable=missing-module-docstring,missing-function-docstring\n\nimport os\nfrom zipfile import ZipFile\n\n\n# ---------------------------------------------------------------------------- #\n#                                   FUNCTIONS                                  #\n# ---------------------------------------------------------------------------- #\n\n\ndef create_zip(*, file_paths: list[str], zip_file_path: str) -> None:\n    with ZipFile(file=zip_file_path, mode=\"w\") as zip_file:\n        for _file_path in file_paths:\n            zip_file.write(filename=_file_path, arcname=os.path.basename(p=_file_path))\n\n\n# ---------------------------------------------------------------------------- #\n#                                     MAIN                                     #\n# ---------------------------------------------------------------------------- #\n\n\nFILE_PATHS: list[str] = [\"./hozlucas28.py\", \"./hozlucas28.txt\"]\nZIP_FILE_PATH: str = \"./hozlucas28.zip\"\n\nfor file_path in [*FILE_PATHS[1:], ZIP_FILE_PATH]:\n    if os.path.exists(path=file_path):\n        os.remove(path=file_path)\n\nFILE_CONTENT: list[str] = [\"Lucas Nahuel Hoz\", \"22\", \"Argentina\"]\nwith open(file=FILE_PATHS[1], mode=\"w\", encoding=\"utf8\") as file:\n    file.write(\"|\".join(FILE_CONTENT))\n\ncreate_zip(file_paths=FILE_PATHS, zip_file_path=ZIP_FILE_PATH)\n\n# Uncomment to remove files on program finish\n# for file_path in [*FILE_PATHS[1:], ZIP_FILE_PATH]:\n#     os.remove(path=file_path)\n"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/python/idiegorojas.py",
    "content": "\"\"\" \n# 41 - Zip \n\"\"\"\n# Crea un programa capaz de comprimir un archivo en formato .zip (o el que tú quieras).\n\nimport zipfile\nimport os\n\n# Archivo a comprimir\npdf_file = \"GuiaPython.pdf\"\n\n# Nombre del archivo zip que se creara\nzip_file = \"GuiaPython.zip\"\n\n# Crear archivo zip\nwith zipfile.ZipFile(zip_file, \"w\", compression=zipfile.ZIP_DEFLATED) as zipf:\n        zipf.write(pdf_file)\n\n# Comparar tamaños\ntamaño_pdf = os.path.getsize(pdf_file)\ntamaño_zip = os.path.getsize(zip_file)\n\nprint(f\"El tamaño del pdf: {tamaño_pdf} bytes.\")\nprint(f\"El tamaño del zip: {tamaño_zip} bytes.\")\nprint(f\"El archivo {pdf_file}, ha sido comprimido en {zip_file}.\")"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/python/ignaciovihe.py",
    "content": "\"\"\"\n * EJERCICIO:\n * ¿Has visto la camiseta.rar?\n * https://x.com/MoureDev/status/1841531938961592740\n *\n * Crea un programa capaz de comprimir un archivo \n * en formato .zip (o el que tú quieras).\n * - No subas el archivo o el zip.\n\"\"\"\n\nimport zipfile\nimport os\n\ninput_texts = { \"1\":{ \"input\": \"Introcuce el nombre del archivo o carpeta a comprimir: \",\n                    \"output\": \"Introcuce el nombre del archivo zip de salida: \"},\n                \"2\":{ \"input\": \"Introcuce el nombre del archivo o carpeta zip a descomprimir: \",\n                    \"output\": \"Introcuce el path de salida: \"},\n                \"3\":{ \"input\": \"Introcuce el nombre del archivo zip a descomprimir: \",\n                    \"output\": \"Introcuce el path de salida: \",\n                    \"inside\": \"Introduce el nombre del archivo concreto a descomprimir: \"},    \n                \"4\":{ \"input\": \"Introcuce el nombre del archivo zip: \",\n                    \"inside\": \"Introcuce el path del archivo a leer dentro del zip: \"},\n                \"5\":{ \"input\": \"Introcuce el nombre del archivo zip a abrir: \"}\n                    }\n\n\ndef get_input_data(opt: str):\n\n    result=[]\n\n    try:\n        if opt in {\"1\", \"2\", \"3\", \"4\", \"5\"}:\n            input_path = input(f\"{input_texts[opt]['input']}\")\n            if os.path.exists(input_path):\n                result.append(input_path)\n            else:\n                print(f\"El archivo de entrada {input_path} no se encuentra/ no existe.\")\n        if opt in {\"1\", \"2\", \"3\"}:\n            output_path = input(f\"{input_texts[opt]['output']}\")\n            if opt == \"1\":\n                output_path = check_output_name(output_path)\n            result.append(output_path)\n        if opt in {\"3\", \"4\"}:\n            print_files_in_path(input_path)\n            indise_path = input(f\"{input_texts[opt]['inside']}\")\n            result.append(indise_path)\n\n        return result\n    \n    except Exception as e :\n        print(e)\n\n\ndef compress(input_path: str, zip_file_output: str):\n    if os.path.exists(input_path):\n        with zipfile.ZipFile(zip_file_output, 'w', compression=zipfile.ZIP_DEFLATED) as zipf:# Abro archivo en modo w\n            if os.path.isfile(input_path):                                    # Si es un archivo\n                zipf.write(input_path, arcname=os.path.basename(input_path))        #Lo escribo con su basename(su nombre) arcname= es la ruta \n                                                                        #con que se guradara dentro del zip.\n            if os.path.isdir(input_path):                                     # Si es un directorio\n                for current_folder, subfolder, files in os.walk(input_path):  # recorre todos los archivos y carpetas paso a paso.\n                                                                        #os.walk(Sólo funciona con carpetas, no con archivos)\n                    for file in files:\n                        full_path = os.path.join(current_folder, file)  #Crea la el path completo concatenendo la carpeta act, y el file.\n                        rel_path = os.path.relpath(full_path, os.path.dirname(input_path)) # relpath es como full_path - os.path.dirname(path)\n                        zipf.write(full_path, arcname=rel_path)         # Se escribe cada fichelo con su estructura\n    else:\n        print(f\"El archivo de entrada {input_path} no se encuentra/ no existe.\")\n\ndef extraxt_all(zip_file: str, output_path: str = ''):\n    with zipfile.ZipFile(zip_file, 'r') as zipf:\n        zipf.extractall(output_path)\n\ndef extract_file(zip_file, file_to_extract, output_path):\n    with zipfile.ZipFile(zip_file, 'r') as zipf:\n        zipf.extract(file_to_extract, path=output_path)\n\ndef read_file_zip(zip_file: str, file_to_read):\n    with zipfile.ZipFile(zip_file, 'r') as zipf:\n        with zipf.open(file_to_read) as f:\n            content = f.read().decode('utf-8')\n            print(content)\n\ndef open_zip(input_path: str):\n    print_files_in_path(input_path)\n\ndef check_output_name(file_name: str):\n    if not file_name.lower().endswith('.zip'):\n        file_name += '.zip'\n    return file_name\n\ndef print_files_in_path(path: str):\n    print(\"Contenido del archivo zip:\")\n    with zipfile.ZipFile(path, 'r') as z:\n        for name in z.namelist():\n            print(\" -\", name)\n\ndef main():\n    while True:\n        print(f\"8zip\")\n        print(f\"Opciones:\")\n        print(f\"1. Comprimir archivo/carpeta\")\n        print(f\"2. Extraer todo.\")\n        print(f\"3. Extraer archivo.\")\n        print(f\"4. Leer archivo\")\n        print(f\"5. Abrir zip - Ver archivos contenidos en el zip\")\n        print(f\"6. Salir\")\n\n        try:\n            option = input(\"Elige una opción: \")\n            if option == \"6\":\n                break\n            input_data = get_input_data(option)\n            if input_data:\n                match option:\n                    case \"1\":\n                        if len(input_data) == 2:\n                            compress(input_data[0],input_data[1])\n                    case \"2\":\n                        if len(input_data) == 2:\n                            extraxt_all(input_data[0],input_data[1])\n                    case \"3\":\n                        if len(input_data) == 3:\n                            extract_file(input_data[0], input_data[2], input_data[1])\n                    case \"4\":\n                        if len(input_data) == 2:\n                            read_file_zip(input_data[0], input_data[1])\n                    case \"5\":\n                        if len(input_data) == 1:\n                            open_zip(input_data[0])\n\n        except Exception as e:\n            print(e)\n\nmain()"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/python/joselorentelopez.py",
    "content": "\"\"\"\nOwner: José Lorente López | joselorente1105@gmail.com | Linkedin: www.linkedin.com/in/josé-lorente-lópez-0121b7148\n\nDescription: Program capable of compressing a file to .zip format\n\nCoding: UTF-8\n\"\"\"\n\nimport os\nimport zipfile\n\nclass FileCompression():\n    def __init__(self) -> None:\n        \"\"\"\n        Initializes the FileCompression class, which is the parent class of the other\n        compression classes. \n\n        Args:\n            None\n\n        Returns:\n            None\n        \"\"\"\n        pass\n\nclass ZipCompression(FileCompression):\n    def __init__(self, file_path: str):\n        \"\"\"\n        Initializes the ZipCompression class with the path of the file to be compressed.\n\n        Args:\n            file_path (str): The path to the file that needs to be compressed\n        \"\"\"\n\n        super().__init__()\n        self.file_path = file_path\n    \n    def compress_to_zip(self):\n        \"\"\"\n        Compresses the specified file to a .zip archive.\n\n        This method uses the zipfile.ZipFile class to create a .zip archive\n        with the name of the file, and adds the file to the archive.\n\n        Args:\n            None\n\n        Returns:\n            None\n        \"\"\"\n        try:\n            if not os.path.exists(self.file_path):\n                raise FileNotFoundError\n\n            file_dir = os.path.dirname(self.file_path)\n            filename_ext = os.path.basename(self.file_path)\n            filename = os.path.splitext(os.path.basename(self.file_path))[0]\n\n            zip_path = os.path.join(file_dir, f\"{filename}.zip\")\n\n            with zipfile.ZipFile(zip_path, \"a\") as zip_file:\n                zip_file.write(self.file_path, arcname=filename_ext) \n        \n        except FileNotFoundError:\n            print(f\"The specified path does not exist.\")\n\ndef main():\n    \"\"\"\n    Runs the main function of the project.\n    \"\"\"\n\n    file_path = input(\"Introduce the path of the file to compress into a .zip format: \")\n    ZipCompression(file_path=file_path).compress_to_zip()\n\nif __name__ == \"__main__\":\n    main()"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/python/juanppdev.py",
    "content": "\"\"\"\n * EJERCICIO:\n * ¿Has visto la camiseta.rar?\n * https://x.com/MoureDev/status/1841531938961592740\n *\n * Crea un programa capaz de comprimir un archivo \n * en formato .zip (o el que tú quieras).\n * - No subas el archivo o el zip.\n\"\"\"\n\nimport zipfile\nimport os\n\ndef compress_file(file_path, zip_name):\n    # Crea un archivo zip\n    with zipfile.ZipFile(zip_name, 'w') as zipf:\n        # Agrega el archivo al zip\n        zipf.write(file_path, os.path.basename(file_path))\n    print(f'{file_path} ha sido comprimido en {zip_name}')\n\n# Uso del programa\nfile_path = 'ruta/del/archivo.ext'  # Reemplaza con la ruta de tu archivo\nzip_name = 'archivo_comprimido.zip'  # Nombre del archivo zip que se va a crear\ncompress_file(file_path, zip_name)\n"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/python/kenysdev.py",
    "content": "# _____________________________________\n# https://github.com/kenysdev\n# 2024 - Python\n# _____________________________________\n# 41 CAMISETA RAR\n# ------------------------------------\n\n\"\"\"\n * EJERCICIO:\n * ¿Has visto la camiseta.rar?\n * https://x.com/MoureDev/status/1841531938961592740\n *\n * Crea un programa capaz de comprimir un archivo \n * en formato .zip (o el que tú quieras).\n * - No subas el archivo o el zip.\n\"\"\"\n\nimport zipfile # https://docs.python.org/es/3.13/library/zipfile.html\nimport os\n\ndef compress_file(source_file, zip_file):\n    if not os.path.exists(source_file):\n        raise FileNotFoundError(f\"El archivo fuente '{source_file}' no existe.\")\n\n    if not os.access(source_file, os.R_OK):\n        raise PermissionError(f\"No tienes permiso de lectura para '{source_file}'\")\n\n    zip_dir = os.path.dirname(zip_file) or '.'\n    if not os.path.exists(zip_dir):\n        raise FileNotFoundError(f\"El directorio '{zip_dir}' no existe.\")\n\n    if os.path.exists(zip_file):\n        raise FileExistsError(f\"El archivo zip '{zip_file}' ya existe.\")\n\n    try:\n        with zipfile.ZipFile(zip_file, 'w', zipfile.ZIP_DEFLATED) as zipf:\n            zipf.write(source_file, arcname=os.path.basename(source_file))\n        \n        print(f\"Comprimido exitosamente '{source_file}' a '{zip_file}'\")\n    \n    except PermissionError:\n        raise PermissionError(f\"No tienes permiso de escritura para '{zip_file}'\")\n    except Exception as e:\n        raise RuntimeError(f\"Se produjo un error al comprimir el archivo.: {e}\")\n\n\ncompress_file('tmp.mp4', 'file.zip')\n"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/python/mhayhem.py",
    "content": "# @Author Daniel Grande (Mhayhem)\n\n# EJERCICIO:\n# ¿Has visto la camiseta.rar?\n# https://x.com/MoureDev/status/1841531938961592740\n#\n# Crea un programa capaz de comprimir un archivo \n# en formato .zip (o el que tú quieras).\n# - No subas el archivo o el zip.\n\nimport zipfile\n\ndef crate_zip_file(file):\n    with zipfile.ZipFile(\"rar.zip\", \"w\") as zipf:\n        zipf.write(file)\n"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/python/miguelex.py",
    "content": "import zipfile\nimport os\n\ndef comprimir_archivo_en_zip(ruta_archivo, nombre_zip):\n    with zipfile.ZipFile(nombre_zip, 'w') as zipf:\n        zipf.write(ruta_archivo, os.path.basename(ruta_archivo))\n    print(f\"Archivo comprimido con éxito en {nombre_zip}\")\n\ndef comprimir_directorio_en_zip(ruta_directorio, nombre_zip):\n    with zipfile.ZipFile(nombre_zip, 'w') as zipf:\n        for foldername, subfolders, filenames in os.walk(ruta_directorio):\n            for filename in filenames:\n                file_path = os.path.join(foldername, filename)\n                zipf.write(file_path, os.path.relpath(file_path, ruta_directorio))\n    print(f\"Directorio comprimido con éxito en {nombre_zip}\")\n\nif __name__ == \"__main__\":\n    tipo = input(\"Selecciona lo que quieres comprimir (archivo/directorio): \").strip().lower()\n    ruta = input(f\"Introduce la ruta del {tipo} que deseas comprimir: \").strip()\n    nombre_salida = input(\"Introduce el nombre de salida (sin la extensión): \").strip() + '.zip'\n\n    if tipo == 'archivo':\n        comprimir_archivo_en_zip(ruta, nombre_salida)\n    elif tipo == 'directorio':\n        comprimir_directorio_en_zip(ruta, nombre_salida)\n    else:\n        print(\"Selección no válida\")\n"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/python/mouredev.py",
    "content": "import zipfile\nimport os\n\n\ndef zip_file(path: str, file: str) -> str:\n\n    file_path = os.path.join(path, file)\n\n    if os.path.exists(file_path):\n\n        zip_file = f\"{file}.zip\"\n        zip_path = os.path.join(path, zip_file)\n\n        with zipfile.ZipFile(zip_path, \"w\", zipfile.ZIP_DEFLATED) as zipf:\n            zipf.write(file_path, file)\n            print(f\"Archivo {file} comprimido como {zip_file}.\")\n            return zip_file\n\n    else:\n        print(f\"El archivo {file} no existe el directorio {path}.\")\n\n    return None\n\n\ndef unzip_file(path: str, file: str):\n\n    file_path = os.path.join(path, file)\n\n    if os.path.exists(file_path):\n\n        zip_path = os.path.join(path, file)\n\n        with zipfile.ZipFile(zip_path) as zipf:\n            zipf.extractall(path)\n            print(f\"Archivo {file} descomprimido en {path}.\")\n\n    else:\n        print(f\"El archivo {file} no existe el directorio {path}.\")\n\n\npath = os.path.dirname(os.path.abspath(__file__))  # Directorio actual\nfile = \"nombre_de_mi_archivo\"\n\nzip = zip_file(path, file)\n\nif zip != None:\n\n    # Borro el fichero original antes de descomprimir el zip\n    os.remove(os.path.join(path, file))\n\n    unzip_file(path, zip)\n"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/python/neslarra.py",
    "content": "\"\"\"\n EJERCICIO:\n ¿Has visto la camiseta.rar?\n https://x.com/MoureDev/status/1841531938961592740\n\n Crea un programa capaz de comprimir un archivo\n en formato .zip (o el que tú quieras).\n - No subas el archivo o el zip.\n\"\"\"\nimport gzip, os\n\n\n# Comprimir\ntry:\n    with open('reto_41_neslarra.txt', 'rb') as regular_file:\n        data = regular_file.read()\n        regular_file.flush()\n\n    with gzip.open('reto_41_neslarra.txt.gz', 'wb') as compressed_file:\n        compressed_file.write(data)\n        compressed_file.flush()\nexcept Exception as e:\n    print(f\"Exception: {str(e)}\")\n    os.remove(\"reto_41_neslarra.txt.gz\")\nelse:\n    os.remove(\"reto_41_neslarra.txt\")\n\n_ = input(\"Revisar y apretar Enter para contiuar...\")\n\n# Descomprimir\ntry:\n    with gzip.open('reto_41_neslarra.txt.gz', 'rb') as compressed_file:\n        data = compressed_file.read()\n        compressed_file.flush()\n\n    with open('reto_41_neslarra.txt', 'wb') as regular_file:\n        regular_file.write(data)\n        regular_file.flush()\nexcept Exception as e:\n    print(f\"Exception: {str(e)}\")\n    os.remove(\"reto_41_neslarra.txt\")\nelse:\n    os.remove(\"reto_41_neslarra.txt.gz\")\n"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/python/oriaj3.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * ¿Has visto la camiseta.rar?\n * https://x.com/MoureDev/status/1841531938961592740\n *\n * Crea un programa capaz de comprimir un archivo \n * en formato .zip (o el que tú quieras).\n * - No subas el archivo o el zip.\n */\n\"\"\"\n\nimport zipfile\nimport os \n\ndef compress_file(file_path: str, zip_path: str):\n    \n    if os.path.exists(file_path):\n        with zipfile.ZipFile(zip_path, \"w\", zipfile.ZIP_DEFLATED) as zipf:\n            zipf.write(file_path, os.path.basename(file_path))\n            print(f\"Archivo {file_path} comprimido como {zip_path}.\")\n            return zip_path\n    else:\n        print(f\"El archivo {file_path} no existe.\")\n        return None\n    \ndef decompress_file(zip_path: str, dest_path: str):\n        \n        if os.path.exists(zip_path):\n            with zipfile.ZipFile(zip_path) as zipf:\n                zipf.extractall(dest_path)\n                print(f\"Archivo {zip_path} descomprimido en {dest_path}.\")\n        else:\n            print(f\"El archivo {zip_path} no existe.\")\n    \npath = os.path.dirname(os.path.abspath(__file__))  # Directorio actual\nfile = \"prueba.txt\"\nzip_file = f\"{file}.zip\"\n\nzip = compress_file(os.path.join(path, file), os.path.join(path, zip_file))\n\nif zip != None:\n    decompress_file(os.path.join(path, zip), path)\n    #os.remove(os.path.join(path, zip))\n\n\n"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/python/pyramsd.py",
    "content": "import zipfile\n\ndef compress_file(file_path, output_zip):\n    with zipfile.ZipFile(output_zip, 'w', zipfile.ZIP_DEFLATED) as zipf:\n        zipf.write(file_path, arcname=file_path.split(\"/\")[-1])\n\nfile = \"D:\\\\Programacion\\\\comandos importantes de git.txt\"\noutput = \"archivo.zip\"\n\ncompress_file(file, output)\nprint(f\"Archivo comprimido creado: {output}\")\n"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/python/raulG91.py",
    "content": "import os\nfrom zipfile import ZipFile\n\ntry:\n\n    with ZipFile(file=\"file.zip\",mode='w') as my_zip:\n        my_zip.write(\"file.txt\")\nexcept :\n    print(\"Error creating ZIP file\")        "
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/python/rigo93acosta.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * ¿Has visto la camiseta.rar?\n * https://x.com/MoureDev/status/1841531938961592740\n *\n * Crea un programa capaz de comprimir un archivo \n * en formato .zip (o el que tú quieras).\n * - No subas el archivo o el zip.\n */\n\"\"\"\n\nimport zipfile\nimport os\nimport logging\n\ndef zip_file(path: str, file: str):\n\n    file_path = os.path.join(path, file)\n\n    if os.path.exists(file_path):       \n        zip_file = f\"{file}.zip\"\n        zip_file_path = os.path.join(path, zip_file)     \n        \n        with zipfile.ZipFile(zip_file_path, \"w\", zipfile.ZIP_DEFLATED) as zfile:\n            zfile.write(file_path, file)\n            print(f\"Archivo {file} comprimido en {zip_file_path}!\")\n            return zip_file\n    else:\n        print(f\"El archivo {file} no existe en la ruta {path}\")\n\n    return None\n\ndef unzip_file(path: str, file: str):\n    \n    file_path = os.path.join(path, file)\n\n    if os.path.exists(file_path):\n        with zipfile.ZipFile(file_path, \"r\") as zfile:\n            zfile.extractall(path)\n            print(f\"Archivo {file} descomprimido en {path}!\")\n    else:\n        print(f\"El archivo {file} no existe en la ruta {path}\")\n\nif __name__ == \"__main__\":\n    logging.basicConfig(level=logging.INFO)\n    path = os.path.dirname(os.path.abspath(__file__))\n    file = \"Notes_Git.pdf\"\n    zip = zip_file(path, file)\n\n    if zip != None:\n\n        # Erase the original file\n        os.remove(os.path.join(path, file))\n        \n        unzip_file(path, f\"{file}.zip\")\n\n"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/rust/kenysdev.rs",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - Rust\n_____________________________________\n41 CAMISETA RAR\n-------------------------------------\n* EJERCICIO:\n* ¿Has visto la camiseta.rar?\n * https://x.com/MoureDev/status/1841531938961592740\n *\n * Crea un programa capaz de comprimir un archivo\n * en formato .zip (o el que tú quieras).\n * - No subas el archivo o el zip.\n\n[dependencies]\nzip = \"2.2.1\"\n*/\n\nuse std::fs::File;\nuse std::io::{self, Write};\nuse std::path::Path;\nuse zip::{write::FileOptions, CompressionMethod, ZipWriter};\n\npub fn compress_file<P: AsRef<Path>>(source_file: P, zip_file: P) -> io::Result<()> {\n    if !source_file.as_ref().exists() {\n        return Err(io::Error::new(\n            io::ErrorKind::NotFound,\n            format!(\n                \"El archivo fuente '{}' no existe.\",\n                source_file.as_ref().display()\n            ),\n        ));\n    }\n\n    if let Some(zip_dir) = zip_file.as_ref().parent() {\n        if !zip_dir.exists() {\n            return Err(io::Error::new(\n                io::ErrorKind::NotFound,\n                format!(\"El directorio '{}' no existe.\", zip_dir.display()),\n            ));\n        }\n    }\n\n    if zip_file.as_ref().exists() {\n        return Err(io::Error::new(\n            io::ErrorKind::AlreadyExists,\n            format!(\n                \"El archivo zip '{}' ya existe.\",\n                zip_file.as_ref().display()\n            ),\n        ));\n    }\n\n    let file = File::create(zip_file.as_ref())?;\n    let mut zip = ZipWriter::new(file);\n\n    let file_name = source_file\n        .as_ref()\n        .file_name()\n        .and_then(|n| n.to_str())\n        .ok_or_else(|| {\n            io::Error::new(\n                io::ErrorKind::InvalidInput,\n                \"No se pudo obtener el nombre del archivo\",\n            )\n        })?;\n\n    let options = FileOptions::default().compression_method(CompressionMethod::Deflated)\n        as FileOptions<'_, ()>;\n\n    zip.start_file(file_name, options)?;\n\n    let source_content = std::fs::read(source_file.as_ref())?;\n    zip.write_all(&source_content)?;\n    zip.finish()?;\n    \n    Ok(())\n}\n\nfn main() {\n    match compress_file(\"D:\\\\dev\\\\tmp\\\\users.csv\", \"D:\\\\dev\\\\tmp\\\\file.zip\") {\n        Ok(_) => println!(\"Compresión completada exitosamente\"),\n        Err(e) => eprintln!(\"Error al comprimir: {}\", e),\n    }\n}\n"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/sql/Nicojsuarez2.sql",
    "content": "# #41 CAMISETA RAR\n> #### Dificultad: Fácil | Publicación: 07/10/24 | Corrección: 14/10/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * ¿Has visto la camiseta.rar?\n * https://x.com/MoureDev/status/1841531938961592740\n *\n * Crea un programa capaz de comprimir un archivo \n * en formato .zip (o el que tú quieras).\n * - No subas el archivo o el zip.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/typescript/EdiedRamos.ts",
    "content": "// Author: EdiedRamos\n// Github: https://github.com/EdiedRamos\n\nimport { createGzip, type Gzip } from \"node:zlib\";\nimport { pipeline } from \"node:stream\";\nimport { createReadStream, createWriteStream } from \"node:fs\";\nimport { join } from \"node:path\";\n\n// ===========\n// = CLASSES =\n// ===========\nclass Compression {\n  private gzip: Gzip;\n\n  constructor() {\n    this.gzip = createGzip();\n  }\n\n  public compress(sourcePath: string, destinationPath: string): Promise<void> {\n    return new Promise((resolve, reject) => {\n      const source = createReadStream(sourcePath);\n      const destination = createWriteStream(destinationPath);\n\n      pipeline(source, this.gzip, destination, (err) => {\n        if (err) {\n          reject(err);\n        } else {\n          resolve();\n        }\n      });\n    });\n  }\n}\n\n// ========\n// = MAIN =\n// ========\n\n(() => {\n  const compression = new Compression();\n  compression.compress(\"YOUR_SOURCE_PATH\", \"YOUR_DESTINATION_PATH\");\n})();\n"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/typescript/hozlucas28.ts",
    "content": "import arc from 'archiver'\nimport fs from 'node:fs'\nimport fsP from 'node:fs/promises'\nimport path from 'node:path'\n\n/* -------------------------------------------------------------------------- */\n/*                                    TYPES                                   */\n/* -------------------------------------------------------------------------- */\n\ntype FilePath = `${string}/${string}.${string}`\ntype ZipFilePath = `${string}/${string}.zip`\n\n/* -------------------------------------------------------------------------- */\n/*                                  FUNCTIONS                                 */\n/* -------------------------------------------------------------------------- */\n\nasync function createZipFile(\n    filePaths: FilePath[],\n    zipFilePath: ZipFilePath\n): Promise<void> {\n    const ws: fs.WriteStream = fs.createWriteStream(zipFilePath)\n    const archive = arc.create('zip', {\n        zlib: {level: 9},\n    })\n\n    archive.pipe(ws)\n\n    for (const filePath of filePaths) {\n        const fileContent: string = await fsP.readFile(filePath, {\n            encoding: 'utf-8',\n        })\n        archive.append(fileContent, {name: path.basename(filePath)})\n    }\n\n    await archive.finalize()\n    ws.close()\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\n;(async () => {\n    const filePaths: FilePath[] = ['./hozlucas28.ts', './hozlucas28.txt']\n    const compressPath: ZipFilePath = './hozlucas28.zip'\n\n    for (const filePath of [...filePaths.slice(1), compressPath]) {\n        if (fs.existsSync(filePath)) await fsP.rm(filePath)\n    }\n\n    const fileContent: string[] = ['Lucas Nahuel Hoz', '22', 'Argentina']\n    await fsP.writeFile(filePaths[1], fileContent.join('|'), {\n        encoding: 'utf-8',\n    })\n\n    await createZipFile(filePaths, compressPath)\n\n    // Uncomment to remove files on program finish\n    // for (const filePath of [...filePaths.slice(1), compressPath]) {\n    //     await fsP.rm(filePath)\n    // }\n})()\n"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/typescript/miguelex.ts",
    "content": "import * as fs from 'fs';\nimport * as archiver from 'archiver';\nimport * as readline from 'readline';\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nfunction preguntar(query: string): Promise<string> {\n    return new Promise(resolve => rl.question(query, resolve));\n}\n\nasync function main() {\n    console.log(\"Selecciona lo que quieres comprimir:\");\n    console.log(\"1. Archivo\");\n    console.log(\"2. Directorio\");\n    const tipoSeleccionado = await preguntar('Tu elección: ');\n\n    let tipo: string;\n    if (tipoSeleccionado === '1') {\n        tipo = 'archivo';\n    } else if (tipoSeleccionado === '2') {\n        tipo = 'directorio';\n    } else {\n        console.log(\"Selección no válida\");\n        rl.close();\n        return;\n    }\n\n    const inputPath = await preguntar(`Introduce la ruta del ${tipo} que deseas comprimir: `);\n    const nombreSalida = await preguntar(\"Introduce el nombre de salida (sin la extensión): \") + '.zip';\n\n    const output = fs.createWriteStream(nombreSalida);\n    const archive = archiver('zip', {\n        zlib: { level: 9 }\n    });\n\n    output.on('close', () => {\n        console.log(`Archivo comprimido con éxito en ${nombreSalida}, total ${archive.pointer()} bytes`);\n        rl.close();\n    });\n\n    archive.on('error', (err) => {\n        throw err;\n    });\n\n    archive.pipe(output);\n\n    if (tipo === 'archivo') {\n        archive.file(inputPath, { name: require('path').basename(inputPath) });\n    } else {\n        archive.directory(inputPath, false);\n    }\n\n    archive.finalize();\n}\n\nmain();\n"
  },
  {
    "path": "Roadmap/41 - CAMISETA RAR/vb.net/kenysdev.vb",
    "content": "' _____________________________________\n' https://github.com/kenysdev\n' 2024 - vb.net\n' _____________________________________\n' 41 CAMISETA RAR\n' ------------------------------------\n'* EJERCICIO\n'* ¿Has visto la camiseta.rar?\n'* https://x.com/MoureDev/status/1841531938961592740\n'*\n'* Crea un programa capaz de comprimir un archivo \n'* en formato .zip (o el que tú quieras).\n'* - No subas el archivo o el zip.\n\nImports System.IO\nImports System.IO.Compression\n\n\nPublic Class FileCompressor\n    Public Shared Sub CompressFile(sourceFile As String, zipFile As String)\n        If Not File.Exists(sourceFile) Then\n            Throw New FileNotFoundException($\"El archivo fuente '{sourceFile}' no existe.\")\n        End If\n\n        Dim zipDir = If(Path.GetDirectoryName(zipFile), Directory.GetCurrentDirectory())\n\n        If Not Directory.Exists(zipDir) Then\n            Throw New DirectoryNotFoundException($\"El directorio '{zipDir}' no existe.\")\n        End If\n\n        If File.Exists(zipFile) Then\n            Throw New IOException($\"El archivo zip '{zipFile}' ya existe.\")\n        End If\n\n        Try\n            Using zipToCreate As New FileStream(zipFile, FileMode.Create),\n                  archive As New ZipArchive(zipToCreate, ZipArchiveMode.Create)\n\n                archive.CreateEntryFromFile(sourceFile, Path.GetFileName(sourceFile), CompressionLevel.Optimal)\n            End Using\n\n            Console.WriteLine($\"Comprimido exitosamente '{sourceFile}' a '{zipFile}'\")\n\n        Catch ex As UnauthorizedAccessException\n            Throw New UnauthorizedAccessException($\"No tienes permiso de escritura para '{zipFile}'\")\n        Catch ex As Exception\n            Throw New Exception($\"Se produjo un error al comprimir el archivo: {ex.Message}\", ex)\n        End Try\n    End Sub\n\n    Public Shared Sub Main()\n        Try\n            CompressFile(\"D:\\dev\\tmp\\tmp.txt\", \"D:\\dev\\tmp\\file.zip\")\n        Catch ex As Exception\n            Console.WriteLine($\"Error al comprimir: {ex.Message}\")\n        End Try\n    End Sub\nEnd Class\n"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/c#/hequebo.cs",
    "content": "class Fighter\n{\n    private int _id;\n    private string _name;\n    private int _speed;\n    private int _attack;\n    private int _defense;\n    private double _hp;\n\n    public static int id = 1;\n\n    public int Id {  get { return _id; } }\n    public string Name { get { return _name; } }\n    public int Speed { get { return _speed;} }\n    public int Attack { get { return _attack;} }\n    public int Defense { get { return _defense;} }\n    public double Hp { get { return _hp;} set { _hp = value; } }\n\n\n    public Fighter(string name, int speed, int attack, int defense)\n    { \n        _id = id;\n        id++;\n        _name = name;\n        _speed = speed;\n        _attack = attack;\n        _defense = defense;\n        _hp = 100;\n    }\n    public void TakeDamage(int attack)\n    {\n        Random random = new Random();\n        if (random.NextDouble() < 0.20)\n        {\n            Console.WriteLine($\"{_name} ha esquivado el ataque y no recibió daño\");\n        }\n        else\n        {\n            double damage;\n            if (_defense >= attack)\n                 damage = attack * 0.10;\n            else\n                damage = attack - _defense;\n            Console.WriteLine($\"{_name} ha recibido {damage} puntos de daño\");\n            _hp -= damage;\n        }\n        Console.WriteLine($\"La salud de {_name} es de {(_hp > 0 ? _hp : 0)}hp\");\n    }   \n}\nclass BattleSimulator\n{\n    private Fighter _fighter1;\n    private Fighter _fighter2;\n\n    public BattleSimulator(Fighter fighter1, Fighter fighter2)\n    {\n        _fighter1 = fighter1;\n        _fighter2 = fighter2;\n    }\n    public Fighter Battle()\n    {\n        Console.WriteLine($\"---{_fighter1.Name} VS {_fighter2.Name}---\");\n\n        while (_fighter1.Hp > 0 && _fighter2.Hp > 0)\n        {\n            if (_fighter1.Speed > _fighter2.Speed)\n            {\n                _fighter2.TakeDamage(_fighter1.Attack);\n                Thread.Sleep(1500);\n                if (_fighter2.Hp > 0)\n                {\n                    _fighter1.TakeDamage(_fighter2.Attack);\n                    Thread.Sleep(1500);\n                }\n                    \n            }\n            else\n            {\n                _fighter1.TakeDamage(_fighter2.Attack);\n                Thread.Sleep(1500);\n                if (_fighter1.Hp > 0)\n                {\n                    _fighter2.TakeDamage(_fighter1.Attack);\n                    Thread.Sleep(1500);\n                }\n                    \n            }\n        }\n        var winner = _fighter1.Hp > 0 ? _fighter1 : _fighter2;\n        Console.WriteLine($\"¡{winner.Name} ha sido el ganador!\");\n        winner.Hp = 100;\n        return winner;\n        \n    }\n}\nclass Tournament\n{\n    private List<Fighter> _fighters;\n\n    public Tournament(List<Fighter> fighters)\n    {\n        _fighters = fighters;\n    }\n    public void Start()\n    {\n        int round = 1;\n        _fighters = _fighters.OrderBy(f => Guid.NewGuid()).ToList();\n        while (_fighters.Count > 1)\n        {\n            Console.WriteLine($\"---Ronda {(_fighters.Count == 2 ? \"Final\" : round)}---\");\n\n            var winnersList = new List<Fighter>();\n\n            for (int i = 0; i < _fighters.Count; i+= 2)\n            {\n                BattleSimulator battleSimulator = new BattleSimulator(_fighters[i], _fighters[i + 1]);\n                var winner = battleSimulator.Battle();\n                winnersList.Add(winner);\n                Thread.Sleep(1500);\n            }\n            _fighters = winnersList; \n            round++;\n        }\n        Console.WriteLine($\"¡{_fighters[0].Name} es el ganador del torneo!\");\n    }\n}\nclass Program\n{\n    static void Main(string[] args)\n    {\n\n        List<Fighter> roster = new List<Fighter>\n        {\n            new Fighter(\"Gokú\", 90, 85, 80),\n            new Fighter(\"Vegeta\", 85, 90, 80),\n            new Fighter(\"Gohan\", 80, 80, 80),\n            new Fighter(\"Picoro\", 80, 75, 80),\n            new Fighter(\"Goten\", 70, 75, 70),\n            new Fighter(\"Trunks\", 75, 75, 70),\n            new Fighter(\"Trunks F\", 85, 80, 90),\n            new Fighter(\"Krilin\", 65, 65, 60),\n            new Fighter(\"Yamcha\", 60, 55, 50),\n            new Fighter(\"Tenchinhan\", 75, 70, 65),\n            new Fighter(\"Nappa\", 65, 80, 70),\n            new Fighter(\"Freezer\", 85, 80, 75),\n            new Fighter(\"Cell\", 80, 85, 85),\n            new Fighter(\"Majin Buu\", 70, 80, 90),\n            new Fighter(\"Bills\", 90, 90, 85),\n            new Fighter(\"Whis\", 99, 99, 99),\n            new Fighter(\"Hit\", 95, 80, 85),\n            new Fighter(\"Gokú Black\", 85, 80, 75),\n            new Fighter(\"Zamasu\", 80, 85, 75),\n            new Fighter(\"Jiren\", 95, 90, 85),\n            new Fighter(\"Gokú UI\", 95, 85, 90),\n            new Fighter(\"Vegeta UE\", 85, 95, 80),\n            new Fighter(\"Gohan B.\", 80, 85, 90),\n            new Fighter(\"O. Picoro\", 80, 85, 90),\n            new Fighter(\"Vegito\", 95, 90, 95),\n            new Fighter(\"Gogeta\", 90, 95, 95),\n            new Fighter(\"Kefla\", 85, 85, 80),\n            new Fighter(\"No. 17\", 80, 80, 75),\n            new Fighter(\"No. 18\", 80, 80, 75),\n            new Fighter(\"Bardock\", 80, 75, 70),\n            new Fighter(\"Gotenks\", 90, 85, 80),\n            new Fighter(\"Broly\", 80, 95, 85)\n        };\n\n        Console.WriteLine(\"!Bienvenido al torneo de artes marciales¡\");\n        Console.WriteLine(\"Ingresa el número de peleadores a participar (Máx. 32)\");\n        int fightersAmount;\n        if (!int.TryParse(Console.ReadLine(), out fightersAmount))\n        {\n            Console.WriteLine(\"No se ha ingresado una cantidad correcta...\");\n            return;\n        }\n        if (fightersAmount > 32)\n        {\n            Console.WriteLine(\"La cantidad máxima de participantes es 32...\");\n            return;\n        }\n        if (!IsPowerOfTwo(fightersAmount))\n        {\n            Console.WriteLine(\"La cantidad de participantes tiene que ser potencia de 2...\");\n            return;\n        }\n\n        for (int i = 0; i < roster.Count; i += 4)\n        {\n            Console.WriteLine($\"{roster[i].Id}.- {roster[i].Name}\\t\\t\" +\n                $\"{roster[i + 1].Id}.- {roster[i + 1].Name}\\t\\t\" +\n                $\"{roster[i + 2].Id}.- {roster[i + 2].Name}\\t\\t\" +\n                $\"{roster[i + 3].Id}.- {roster[i + 3].Name}\");\n        }\n        Console.WriteLine(\"Ingresa los Id de los peleadores que desees seleccionar\");\n        Console.WriteLine(\"Si deseas elegir aleatoriamente ingresa la tecla 'R'\");\n\n        bool randomSelection = Console.ReadLine().ToLower() == \"r\";\n        var participantsList = new List<Fighter>();\n        if (randomSelection)\n        {\n            Console.WriteLine(\"Se seleccionarán los peleadores aleatoriamente... \");\n            int selectedAmount = 0;\n            Random random = new Random();\n            while (selectedAmount < fightersAmount)\n            {\n                int index = random.Next(0, roster.Count);\n                var fighter = roster[index];\n                participantsList.Add(fighter);\n                roster.RemoveAt(index);\n                selectedAmount++;\n            }\n        }\n        else\n        {\n            int selectedAmount = 0;\n            while (selectedAmount < fightersAmount)\n            {\n                Console.WriteLine($\"Selecciona un luchador ({selectedAmount + 1})\");\n                int id;\n                if (!int.TryParse (Console.ReadLine(), out id))\n                {\n                    Console.WriteLine(\"No se ha ingresado un id válido...\");\n                }\n                else\n                {\n                    var fighter = roster.Where(f => f.Id == id).FirstOrDefault();\n                    if (fighter == null)\n                    {\n                        Console.WriteLine($\"No se ha podido obtener el peleador con id {id}\");\n                    }\n                    else\n                    {\n                        Console.WriteLine($\"¡{fighter.Name} ha sido seleccionado!\");\n                        participantsList.Add(fighter);\n                        roster.Remove(fighter);\n                        selectedAmount++;\n                    }\n                }\n            }\n        }\n\n        Console.WriteLine(\"Estos son los participantes del torneo:\");\n        foreach (var (figter, index) in participantsList.Select((item, index) => (item, index)))\n            Console.WriteLine($\"{index + 1}.- {figter.Name}\");\n\n        Tournament tournament = new Tournament(participantsList);\n        tournament.Start();\n    }\n    static bool IsPowerOfTwo(int x)\n    {\n        return (x != 0) && ((x & (x - 1)) == 0);\n    }\n}"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/c#/kenysdev.cs",
    "content": "namespace exs42;\n/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - C#\n_____________________________________\n42 TORNEO DRAGON BALL\n------------------------------------\n\n* EJERCICIO:\n * ¡El último videojuego de Dragon Ball ya está aquí!\n * Se llama Dragon Ball: Sparking! ZERO.\n *\n * Simula un Torneo de Artes Marciales, al más puro estilo\n * de la saga, donde participarán diferentes luchadores, y el\n * sistema decidirá quién es el ganador.\n *\n * Luchadores:\n * - Nombre.\n * - Tres atributos: velocidad, ataque y defensa\n *   (con valores entre 0 a 100 que tú decidirás).\n * - Comienza cada batalla con 100 de salud.\n * Batalla:\n * - En cada batalla se enfrentan 2 luchadores.\n * - El luchador con más velocidad comienza atacando.\n * - El daño se calcula restando el daño de ataque del\n *   atacante menos la defensa del oponente.\n * - El oponente siempre tiene un 20% de posibilidad de\n *   esquivar el ataque.\n * - Si la defensa es mayor que el ataque, recibe un 10%\n *   del daño de ataque.\n * - Después de cada turno y ataque, el oponente pierde salud.\n * - La batalla finaliza cuando un luchador pierde toda su salud.\n * Torneo:\n * - Un torneo sólo es válido con un número de luchadores\n *   potencia de 2.\n * - El torneo debe crear parejas al azar en cada ronda.\n * - Los luchadores se enfrentan en rondas eliminatorias.\n * - El ganador avanza a la siguiente ronda hasta que sólo\n *   quede uno.\n * - Debes mostrar por consola todo lo que sucede en el torneo,\n *   así como el ganador.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\n\npublic class Fighter(string name, int speed, int attack, int defense)\n{\n    public string Name { get; } = name;\n    public int Speed { get; } = speed;\n    public int Attack { get; } = attack;\n    public int Defense { get; } = defense;\n    public double Health { get; set; } = 100;\n\n    public void ExecuteAttack(Fighter opponent)\n    {\n        Console.WriteLine($\"'{Name}' ataca a '{opponent.Name}'\");\n\n        double damage = opponent.Defense >= Attack \n            ? Attack * 0.1 // 10%\n            : Attack - opponent.Defense;\n\n        if (!ActivateDefense())\n        {\n            opponent.Health -= damage;\n            Console.WriteLine($\"'{opponent.Name}' ha recibido '{damage}' de daño\");\n            Console.WriteLine($\"Salud restante '{opponent.Health}'\\n\");\n        }\n        else\n        {\n            Console.WriteLine($\"'{opponent.Name}' ha esquivado el ataque.\\n\");\n        }\n    }\n\n    private static bool ActivateDefense() => Random.Shared.NextDouble() <= 0.2; // 20%\n\n}\n\n// __________________________________________________________\npublic class Battle\n{\n    private readonly Fighter _fighter1;\n    private readonly Fighter _fighter2;\n\n    public Battle(Fighter fighter1, Fighter fighter2)\n    {\n        _fighter1 = fighter1;\n        _fighter2 = fighter2;\n        Console.WriteLine($\"__'{_fighter1.Name} VS '{_fighter2.Name}'__\\n\");\n    }\n\n    private static Fighter Combat(Fighter fighterA, Fighter fighterB)\n    {\n        while (true)\n        {\n            fighterA.ExecuteAttack(fighterB);\n            if (fighterB.Health <= 0)\n            {\n                Console.WriteLine($\"--> '{fighterA.Name}' gana la batalla.__\\n\");\n                return fighterA;\n            }\n\n            fighterB.ExecuteAttack(fighterA);\n            if (fighterA.Health <= 0)\n            {\n                Console.WriteLine($\"--> '{fighterB.Name}' gana la batalla.\\n\");\n                return fighterB;\n            }\n        }\n    }\n\n    public Fighter Start() =>\n        _fighter1.Speed > _fighter2.Speed \n            ? Combat(_fighter1, _fighter2) \n            : Combat(_fighter2, _fighter1);\n}\n\n// __________________________________________________________\npublic record FighterStats(int Speed, int Attack, int Defense);\n\npublic class Tournament(Dictionary<string, FighterStats> fighters)\n{\n    private Dictionary<string, FighterStats> _fighters = fighters;\n\n    private bool IsPowerOf2() =>\n        _fighters.Count > 1 && Math.Log2(_fighters.Count) % 1 == 0;\n\n    private (Fighter, Fighter) GetRandomPairs()\n    {\n        var randomFighters = _fighters.Keys.OrderBy(_ => Random.Shared.Next()).Take(2).ToArray();\n        \n        var fighter1Data = _fighters[randomFighters[0]];\n        var fighter2Data = _fighters[randomFighters[1]];\n\n        var fighter1 = new Fighter(randomFighters[0], fighter1Data.Speed, fighter1Data.Attack, fighter1Data.Defense);\n        var fighter2 = new Fighter(randomFighters[1], fighter2Data.Speed, fighter2Data.Attack, fighter2Data.Defense);\n\n        _fighters.Remove(randomFighters[0]);\n        _fighters.Remove(randomFighters[1]);\n\n        return (fighter1, fighter2);\n    }\n\n    public void StartRounds(int roundNum = 1)\n    {\n        if (!IsPowerOf2())\n        {\n            Console.WriteLine(\"El número de luchadores debe ser una potencia de 2.\");\n            return;\n        }\n\n        Console.WriteLine($\"\\n__Ronda #{roundNum}__\");\n        var nextRound = new Dictionary<string, FighterStats>();\n\n        while (true)\n        {\n            var (fighter1, fighter2) = GetRandomPairs();\n            var battle = new Battle(fighter1, fighter2);\n            var winner = battle.Start();\n\n            nextRound[winner.Name] = new FighterStats(\n                Speed: fighter1.Speed,\n                Attack: fighter1.Attack,\n                Defense: fighter1.Defense\n            );\n\n            if (_fighters.Count == 0 && nextRound.Count > 1)\n            {\n                _fighters = nextRound;\n                StartRounds(roundNum + 1);\n                break;\n            }\n\n            if (_fighters.Count == 0 && nextRound.Count == 1)\n            {\n                Console.WriteLine($\"\\n--> El vencedor del torneo es '{winner.Name}'.\");\n                break;\n            }\n        }\n    }\n}\n\n// __________________________________________________________\npublic static class Program\n{\n    private static readonly Dictionary<string, FighterStats> Fighters = new()\n    {\n        [\"Goku\"] = new(Speed: 100, Attack: 95, Defense: 85),\n        [\"Vegeta\"] = new(Speed: 95, Attack: 90, Defense: 90),\n        [\"Gohan\"] = new(Speed: 85, Attack: 95, Defense: 85),\n        [\"Freezer\"] = new(Speed: 90, Attack: 90, Defense: 90),\n        [\"Piccolo\"] = new(Speed: 90, Attack: 85, Defense: 90),\n        [\"Krillin\"] = new(Speed: 85, Attack: 75, Defense: 75),\n        [\"Cell\"] = new(Speed: 90, Attack: 95, Defense: 85),\n        [\"Majin Buu\"] = new(Speed: 80, Attack: 85, Defense: 95)\n    };\n\n    public static void Main()\n    {\n        Console.WriteLine(\"Simulación del Torneo de Artes Marciales\");\n        var tournament = new Tournament(Fighters);\n        tournament.StartRounds();\n    }\n}\n"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/c++/hectorio23.cpp",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\n#include <algorithm>\n#include <iostream>\n#include <vector>\n#include <string>\n#include <random>\n#include <ctime>\n\nclass Fighter {\npublic:\n    std::string name;\n    int speed, attack, defense, health;\n\n    Fighter(std::string n, int s, int a, int d)\n        : name(n), speed(s), attack(a), defense(d), health(100) {}\n\n    void takeDamage(const Fighter &attacker) {\n        // Determinar si esquiva\n        if (rand() % 100 < 20) {\n            std::cout << name << \" esquivó el ataque de \" << attacker.name << \"!\\n\";\n            return;\n        }\n\n        int damage = std::max(0, attacker.attack - defense);\n        if (defense > attacker.attack) {\n            // Recibe solo el 10% del daño\n            damage *= 0.1; \n        }\n        health -= damage;\n        std::cout << name << \" recibió \" << damage << \" puntos de daño de \" << attacker.name\n                  << \". Salud restante: \" << health << \"\\n\";\n    }\n};\n\nFighter battle(Fighter f1, Fighter f2) {\n    std::cout << \"¡Comienza la batalla entre \" << f1.name << \" y \" << f2.name << \"!\\n\";\n    Fighter *attacker = (f1.speed >= f2.speed) ? &f1 : &f2;\n    Fighter *defender = (attacker == &f1) ? &f2 : &f1;\n\n    while (f1.health > 0 && f2.health > 0) {\n        defender->takeDamage(*attacker);\n        \n        // Cambiar roles\n        std::swap(attacker, defender); \n    }\n\n    Fighter &winner = (f1.health > 0) ? f1 : f2;\n    std::cout << \"¡\" << winner.name << \" gana la batalla!\\n\\n\";\n    return winner;\n}\n\nvoid tournament(std::vector<Fighter> &fighters) {\n    if ((fighters.size() & (fighters.size() - 1)) != 0) {\n        throw std::invalid_argument(\"El número de luchadores debe ser potencia de 2.\");\n    }\n\n    int round = 1;\n    while (fighters.size() > 1) {\n        std::cout << \"--- Ronda \" << round << \" ---\\n\";\n        std::shuffle(fighters.begin(), fighters.end(), std::default_random_engine(std::time(0)));\n\n        std::vector<Fighter> nextRound;\n        for (size_t i = 0; i < fighters.size(); i += 2) {\n            Fighter winner = battle(fighters[i], fighters[i + 1]);\n            nextRound.push_back(winner);\n        }\n        fighters = nextRound;\n        round++;\n    }\n\n    std::cout << \"¡El ganador del torneo es \" << fighters[0].name << \"!\\n\";\n}\n\nint main() {\n    std::vector<Fighter> fighters = {\n        Fighter(\"Goku\", 90, 95, 80),\n        Fighter(\"Vegeta\", 85, 90, 85),\n        Fighter(\"Piccolo\", 75, 80, 90),\n        Fighter(\"Frieza\", 80, 85, 75),\n    };\n\n    try {\n        tournament(fighters);\n    } catch (const std::exception &e) {\n        std::cerr << e.what() << '\\n';\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/dart/misaelBentPerez.dart",
    "content": "import 'dart:math';\n\n//Defino la clase personaje (Character)\n//Con sus metodos publicos de esquivar y atacar\nclass Character {\n  String name;\n  int speed;\n  int attack;\n  int def;\n  int health;\n\n  Character(\n      {required this.name,\n      required this.speed,\n      required this.attack,\n      required this.def,\n      required this.health});\n\n  //Funcion que determina si hay evasion de ataque o no.\n  bool aboidAttack() {\n    Random evasionRandom = Random();\n    double evasion = evasionRandom.nextDouble();\n    if (evasion <= 0.2) {\n      return true;\n    } else {\n      return false;\n    }\n  }\n\n  //Funcion de ataque\n  void atackOponent(Character oponent) {\n    int damage = _getDamage(oponent);\n    if (health <= 0) {\n    } else {\n      if (oponent.aboidAttack()) {\n        print('${name.toUpperCase()} ATTACK');\n        print('${oponent.name} esquivo el ataque!');\n        oponent._printStatus(oponent);\n      } else {\n        oponent.health = oponent.health - damage;\n        if (_oponentIsAlive(oponent)) {\n          print('${name.toUpperCase()} ATTACK');\n          oponent._printStatus(oponent);\n        } else {\n          print('${oponent.name} lose');\n        }\n      }\n    }\n  }\n\n  void _printStatus(Character oponent) {\n    print(name);\n    print('Health: ${health}');\n    print('');\n  }\n\n  bool _oponentIsAlive(Character oponent) {\n    while (oponent.health > 0) {\n      return true;\n    }\n    return false;\n  }\n\n  int _getDamage(Character oponent) {\n    int damage = 0;\n    if (attack <= oponent.def) {\n      damage = (attack * 0.1).toInt();\n    } else {\n      damage = attack - oponent.def;\n    }\n    return damage;\n  }\n}\n\n//Defino la clase que se encarga de manejar lo referente a cada combate\n//Con su metodo getKombatWinner\nclass KombatManager {\n  Character oponent1;\n  Character oponent2;\n\n  KombatManager({required this.oponent1, required this.oponent2});\n\n  //Funcion que pone en accion el combate y obtiene el ganador del mismo\n  Future<Character> getKombatWinner(int turn, int combatNumber) async {\n    print('-- COMBAT $combatNumber --');\n    print('(${oponent1.name} vs ${oponent2.name})');\n    print('');\n    while (oponent1.health > 0 && oponent2.health > 0) {\n      turn++;\n      print('- TURN: $turn -');\n      print('');\n      if (oponent1.speed > oponent2.speed) {\n        oponent1.atackOponent(oponent2);\n        oponent2.atackOponent(oponent1);\n      } else {\n        oponent2.atackOponent(oponent1);\n        oponent1.atackOponent(oponent2);\n      }\n      await Future.delayed(\n          const Duration(seconds: 2)); // Parte del codigo encargada del delay\n    }\n    if (oponent1.health <= 0) {\n      oponent1._printStatus(oponent2);\n      print('The winner is: ${oponent2.name}');\n      print('');\n      return oponent2;\n    }\n    oponent2._printStatus(oponent1);\n    print('The winner is: ${oponent1.name}');\n    print('');\n    return oponent1;\n  }\n}\n\n//Defino la clase que se encargara de manejar todo lo referente al torneo\n//Con un metodo que se encarga de accionar el torneo\nclass TournamentManager {\n  List<Character> tournamentCharacters;\n  int turn;\n\n  TournamentManager({required this.tournamentCharacters, required this.turn});\n\n  //Metodo privado para obtener la lista de competidores aleatoria\n  List<Character> _getRandomCharacters() {\n    List<Character> randomCharacters = List.from(tournamentCharacters);\n    randomCharacters.shuffle(Random());\n    return randomCharacters;\n  }\n\n  //Funcion que pone en marcha el torneo.\n  tournamentStart() async {\n    if (tournamentCharacters.length == 1) {\n    } else {\n      int roundCant = 3;\n      for (var i = 0; i < roundCant; i++) {\n        print('*** ROUND ${i + 1} ***');\n        print('');\n        await _tournamentRound();\n      }\n    }\n    print('🥇 THE CHAMP IS ${(tournamentCharacters[0].name).toUpperCase()} 🥇');\n  }\n\n  //Metodo privado que maneja cada round\n  _tournamentRound() async {\n    List<Character> randomList = _getRandomCharacters();\n    tournamentCharacters = [];\n    int combatNumber = 0;\n    if (randomList.length % 2 == 0) {\n      for (var i = 0; i < randomList.length; i += 2) {\n        combatNumber++;\n        Character clasificated = await KombatManager(\n                oponent1: randomList[i], oponent2: randomList[i + 1])\n            .getKombatWinner(turn, combatNumber);\n        tournamentCharacters.add(clasificated);\n      }\n    } else {\n      print('an even number of partitioners is required');\n    }\n    print('-- Qualified participants -- ');\n    for (var character in tournamentCharacters) {\n      print(character.name);\n    }\n    print('');\n  }\n}\n\n//Aqui se utiliza el metodo main para ejecutar el codigo\nvoid main() {\n  TournamentManager(tournamentCharacters: characters, turn: turn)\n      .tournamentStart();\n}\n\nint turn = 0;\n\n//Este es el listado de personajes que participaran en el torneo\nList<Character> characters = [\n  krillin,\n  rochi,\n  yamcha,\n  picolo,\n  satan,\n  videl,\n  ten,\n  chaos\n];\n\n//Estos son las instancias de personaje (Character) que representan a los participantes\n//Por defecto los atributos de todos son iguales, pueden ser cambiados aqui...\nCharacter krillin =\n    Character(name: 'Krillin', speed: 10, attack: 180, def: 100, health: 200);\n\nCharacter rochi = Character(\n    name: 'Master Rochi', speed: 10, attack: 180, def: 100, health: 200);\n\nCharacter yamcha =\n    Character(name: 'Yamcha', speed: 10, attack: 180, def: 100, health: 200);\n\nCharacter picolo =\n    Character(name: 'Picolo', speed: 10, attack: 180, def: 100, health: 200);\n\nCharacter satan =\n    Character(name: 'Mr Satan', speed: 10, attack: 180, def: 100, health: 200);\n\nCharacter videl =\n    Character(name: 'Videl', speed: 10, attack: 180, def: 100, health: 200);\n\nCharacter chaos =\n    Character(name: 'Chaos', speed: 10, attack: 180, def: 100, health: 200);\n\nCharacter ten = Character(\n    name: 'Ten Chin Jan', speed: 10, attack: 180, def: 100, health: 200);\n"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/ejercicio.md",
    "content": "# #42 TORNEO DRAGON BALL\n> #### Dificultad: Difícil | Publicación: 14/10/24 | Corrección: 21/10/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * ¡El último videojuego de Dragon Ball ya está aquí!\n * Se llama Dragon Ball: Sparking! ZERO.\n *\n * Simula un Torneo de Artes Marciales, al más puro estilo\n * de la saga, donde participarán diferentes luchadores, y el\n * sistema decidirá quién es el ganador.\n *\n * Luchadores:\n * - Nombre.\n * - Tres atributos: velocidad, ataque y defensa\n *   (con valores entre 0 a 100 que tú decidirás).\n * - Comienza cada batalla con 100 de salud.\n * Batalla:\n * - En cada batalla se enfrentan 2 luchadores.\n * - El luchador con más velocidad comienza atacando.\n * - El daño se calcula restando el daño de ataque del\n *   atacante menos la defensa del oponente.\n * - El oponente siempre tiene un 20% de posibilidad de\n *   esquivar el ataque.\n * - Si la defensa es mayor que el ataque, recibe un 10%\n *   del daño de ataque.\n * - Después de cada turno y ataque, el oponente pierde salud.\n * - La batalla finaliza cuando un luchador pierde toda su salud.\n * Torneo:\n * - Un torneo sólo es válido con un número de luchadores\n *   potencia de 2.\n * - El torneo debe crear parejas al azar en cada ronda.\n * - Los luchadores se enfrentan en rondas eliminatorias.\n * - El ganador avanza a la siguiente ronda hasta que sólo\n *   quede uno.\n * - Debes mostrar por consola todo lo que sucede en el torneo,\n *   así como el ganador.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/go/hozlucas28.go",
    "content": "package main\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"math\"\n\t\"math/rand/v2\"\n\t\"slices\"\n)\n\n/* -------------------------------------------------------------------------- */\n/*                                   CLASSES                                  */\n/* -------------------------------------------------------------------------- */\n\n/* --------------------------------- Fighter -------------------------------- */\n\ntype IFighter interface {\n\tGetAttack() float64\n\tGetDefense() float64\n\tGetLife() float64\n\tGetName() string\n\tGetSpeed() float64\n\tSetLife(newLife float64) IFighter\n\tClone() IFighter\n}\n\ntype fighter struct {\n\tattack  float64\n\tdefense float64\n\tlife    float64\n\tname    string\n\tspeed   float64\n\t_       struct{}\n}\n\nfunc NewFighter(attack float64, defense float64, life float64, name string, speed float64) IFighter {\n\tvar fighter fighter = fighter{\n\t\tattack:  attack,\n\t\tdefense: defense,\n\t\tlife:    100,\n\t\tname:    name,\n\t\tspeed:   speed,\n\t}\n\n\treturn &fighter\n}\n\nfunc (fgt *fighter) GetAttack() float64 {\n\treturn fgt.attack\n}\n\nfunc (fighter *fighter) GetDefense() float64 {\n\treturn fighter.defense\n}\n\nfunc (fighter *fighter) GetLife() float64 {\n\treturn fighter.life\n}\n\nfunc (fighter *fighter) GetName() string {\n\treturn fighter.name\n}\n\nfunc (fighter *fighter) GetSpeed() float64 {\n\treturn fighter.speed\n}\n\nfunc (fighter *fighter) SetLife(newLife float64) IFighter {\n\tif newLife > 0 {\n\t\tfighter.life = newLife\n\t} else {\n\t\tfighter.life = 0\n\t}\n\n\treturn fighter\n}\n\nfunc (fgt *fighter) Clone() IFighter {\n\tvar fighter IFighter = NewFighter(\n\t\tfgt.attack,\n\t\tfgt.defense,\n\t\tfgt.life,\n\t\tfgt.name,\n\t\tfgt.speed,\n\t)\n\n\treturn fighter\n}\n\n/* ------------------------------- Tournament ------------------------------- */\n\ntype ShiftInformation struct {\n\tAttackDamage float64\n\tAttacker     IFighter\n\tShift        int\n\tVictim       IFighter\n\t_            struct{}\n}\n\ntype Round struct {\n\tInfoPerShift []ShiftInformation\n\tLooser       IFighter\n\tShifts       int\n\tWinner       IFighter\n\t_            struct{}\n}\n\ntype ITournament interface {\n\tGetPhase() int\n\tGetTeamA() []IFighter\n\tGetTeamB() []IFighter\n\tGetWinner() (IFighter, error)\n\tHasWinner() bool\n\tExecuteNextRound() (Round, error)\n}\n\ntype tournament struct {\n\tpairOfFighters []IFighter\n\tphase          int\n\tround          int\n\tteamA          []IFighter\n\tteamB          []IFighter\n\twinner         IFighter\n\thasWinner      bool\n}\n\nfunc NewTournament(teamA []IFighter, teamB []IFighter) (ITournament, error) {\n\tif len(teamA) != len(teamB) {\n\t\treturn nil, errors.New(\"The number of fighters in both teams must be equal\")\n\t}\n\n\tif (len(teamA)%2 != 0) || (len(teamB)%2 != 0) {\n\t\treturn nil, errors.New(\"The number of fighters in both teams must be even\")\n\t}\n\n\tvar tournament tournament = tournament{\n\t\tteamA: teamA,\n\t\tteamB: teamB,\n\t}\n\n\ttournament.setRndPairOfFighters()\n\n\treturn &tournament, nil\n}\n\nfunc (tournament *tournament) GetPhase() int {\n\treturn tournament.phase\n}\n\nfunc (tournament *tournament) GetTeamA() []IFighter {\n\treturn tournament.teamA\n}\n\nfunc (tournament *tournament) GetTeamB() []IFighter {\n\treturn tournament.teamB\n}\n\nfunc (tournament *tournament) GetWinner() (IFighter, error) {\n\tif !tournament.hasWinner {\n\t\treturn tournament.winner, errors.New(\"The tournament has no winner\")\n\t}\n\n\treturn tournament.winner, nil\n}\n\nfunc (tournament *tournament) HasWinner() bool {\n\treturn tournament.hasWinner\n}\n\nfunc (tournament *tournament) setRndPairOfFighters() {\n\tvar indexesToIgnoreA []int\n\tvar indexesToIgnoreB []int\n\n\tvar rndIndex int\n\tvar rndFighter IFighter\n\n\tfor range tournament.teamA {\n\t\trndIndex = rand.IntN(len(tournament.teamA))\n\t\tfor slices.Contains(indexesToIgnoreA, rndIndex) {\n\t\t\trndIndex = rand.IntN(len(tournament.teamA))\n\t\t}\n\n\t\trndFighter = tournament.teamA[rndIndex]\n\n\t\ttournament.pairOfFighters = append(tournament.pairOfFighters, rndFighter)\n\t\tindexesToIgnoreA = append(indexesToIgnoreA, rndIndex)\n\n\t\trndIndex = rand.IntN(len(tournament.teamB))\n\t\tfor slices.Contains(indexesToIgnoreB, rndIndex) {\n\t\t\trndIndex = rand.IntN(len(tournament.teamB))\n\t\t}\n\n\t\trndFighter = tournament.teamB[rndIndex]\n\n\t\ttournament.pairOfFighters = append(tournament.pairOfFighters, rndFighter)\n\t\tindexesToIgnoreB = append(indexesToIgnoreB, rndIndex)\n\t}\n}\n\nfunc (tournament *tournament) ExecuteNextRound() (Round, error) {\n\tvar round Round\n\n\tif tournament.hasWinner {\n\t\treturn round, errors.New(\"The tournament already has a winner\")\n\t}\n\n\tif len(tournament.pairOfFighters) < 2 {\n\t\treturn round, errors.New(\"Not enough fighters to execute the next round\")\n\t}\n\n\ttournament.round += 1\n\tvar offset int = tournament.round - 1\n\n\tvar fighter01 IFighter = tournament.pairOfFighters[offset]\n\tvar fighter02 IFighter = tournament.pairOfFighters[offset+1]\n\tvar fighterAux IFighter\n\n\tif fighter01.GetSpeed() < fighter02.GetSpeed() {\n\t\tfighterAux = fighter01\n\t\tfighter01 = fighter02\n\t\tfighter02 = fighterAux\n\t}\n\n\tvar shifts int = 0\n\tvar infoPerShift []ShiftInformation\n\n\tfor fighter01.GetLife() > 0 && fighter02.GetLife() > 0 {\n\t\tvar attackDamage float64 = 0\n\n\t\tif rand.Float32() > 0.2 {\n\t\t\tvar attack float64 = fighter01.GetAttack()\n\t\t\tvar defense float64 = fighter02.GetDefense()\n\n\t\t\tattackDamage = math.Abs(attack - defense)\n\t\t\tif defense > attack {\n\t\t\t\tattackDamage = attackDamage * 0.1\n\t\t\t}\n\n\t\t\tfighter02.SetLife(fighter02.GetLife() - attackDamage)\n\t\t}\n\n\t\tshifts++\n\n\t\tinfoPerShift = append(infoPerShift, ShiftInformation{\n\t\t\tAttackDamage: attackDamage,\n\t\t\tAttacker:     fighter01.Clone(),\n\t\t\tVictim:       fighter02.Clone(),\n\t\t\tShift:        shifts,\n\t\t})\n\n\t\tfighterAux = fighter01\n\t\tfighter01 = fighter02\n\t\tfighter02 = fighterAux\n\t}\n\n\tfighter01 = tournament.pairOfFighters[offset]\n\tfighter02 = tournament.pairOfFighters[offset+1]\n\n\tvar looserIndex int\n\n\tif fighter01.GetLife() > 0 {\n\t\tlooserIndex = offset + 1\n\t} else {\n\t\tlooserIndex = offset\n\t}\n\n\ttournament.pairOfFighters = slices.Delete(tournament.pairOfFighters, looserIndex, looserIndex+1)\n\n\tif len(tournament.pairOfFighters) < 2 {\n\t\ttournament.winner = tournament.pairOfFighters[0]\n\t\ttournament.hasWinner = true\n\t}\n\n\tif tournament.round == len(tournament.pairOfFighters) {\n\t\ttournament.round = 0\n\t\ttournament.phase += 1\n\t}\n\n\tif fighter01.GetLife() > 0 {\n\t\tround.Winner = fighter01.Clone()\n\t\tround.Looser = fighter02.Clone()\n\t} else {\n\t\tround.Winner = fighter02.Clone()\n\t\tround.Looser = fighter01.Clone()\n\t}\n\n\tround.Shifts = shifts\n\tround.InfoPerShift = infoPerShift\n\n\treturn round, nil\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\nfunc main() {\n\tvar teamA []IFighter = []IFighter{\n\t\tNewFighter(90, 80, 100, \"Goku\", 95),\n\t\tNewFighter(85, 75, 100, \"Vegeta\", 90),\n\t\tNewFighter(70, 65, 100, \"Piccolo\", 80),\n\t\tNewFighter(60, 55, 100, \"Krillin\", 70),\n\t}\n\n\tvar teamB []IFighter = []IFighter{\n\t\tNewFighter(88, 78, 100, \"Frieza\", 92),\n\t\tNewFighter(82, 72, 100, \"Cell\", 88),\n\t\tNewFighter(75, 65, 100, \"Majin Buu\", 85),\n\t\tNewFighter(65, 60, 100, \"Broly\", 75),\n\t}\n\n\ttournament, err := NewTournament(teamA, teamB)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tvar rounds int = 0\n\n\tfor !tournament.HasWinner() {\n\t\tround, err := tournament.ExecuteNextRound()\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\n\t\trounds++\n\n\t\tfmt.Printf(\"> Round %d (%s vs %s)...\\n\\n\", rounds, round.Winner.GetName(), round.Looser.GetName())\n\n\t\tfor _, shift := range round.InfoPerShift {\n\t\t\tif shift.AttackDamage > 0 {\n\t\t\t\tfmt.Printf(\n\t\t\t\t\t\"> Shift %d: %s attacks %s with an attack damage of %.2f.\\n\",\n\t\t\t\t\tshift.Shift,\n\t\t\t\t\tshift.Attacker.GetName(),\n\t\t\t\t\tshift.Victim.GetName(),\n\t\t\t\t\tshift.AttackDamage,\n\t\t\t\t)\n\t\t\t} else {\n\t\t\t\tfmt.Printf(\n\t\t\t\t\t\"> Shift %d: %s attacks %s, but %s evades the attack.\\n\",\n\t\t\t\t\tshift.Shift,\n\t\t\t\t\tshift.Attacker.GetName(),\n\t\t\t\t\tshift.Victim.GetName(),\n\t\t\t\t\tshift.Victim.GetName(),\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\n\t\tfmt.Printf(\n\t\t\t\"\\n> %s wins the fight against %s in %d shifts!\\n\\n\",\n\t\t\tround.Winner.GetName(),\n\t\t\tround.Looser.GetName(),\n\t\t\tround.Shifts,\n\t\t)\n\t}\n\n\twinner, err := tournament.GetWinner()\n\tfmt.Printf(\"> The winner of the tournament is %s!\", winner.GetName())\n}\n"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/java/Josegs95.java",
    "content": "import java.util.*;\n\npublic class Josegs95 {\n    public static void main(String[] args) {\n        new Josegs95().DragonBallTournament();\n    }\n\n    private double delay = 1;\n\n    public void DragonBallTournament(){\n        List<Fighter> participantList = getFighters();\n\n        if (!checkParticipantCount(participantList.size())){\n            System.out.println(\"No se puede empezar el torneo porque no hay suficientes participantes\");\n            return;\n        }\n        System.out.print(\"Introduzca el delay para las peleas (en segundos): \");\n        delay = Double.parseDouble(new Scanner(System.in).nextLine());\n\n        System.out.println(\"¡¡ Comienza el torneo de artes marciales !!\");\n        System.out.println();\n\n        Fighter winner = tournament(new ArrayList<>(participantList));\n\n        System.out.println(\"\\n\");\n        System.out.println(\"¡¡\" + winner.getNAME() + \" ha ganado el torneo de artes marciales!!\");\n    }\n\n    private Fighter tournament(ArrayList<Fighter> participants){\n        int nParticipants = participants.size();\n        switch (nParticipants){\n            case 2:\n                System.out.println(\"¡ Empieza la final !\");\n                break;\n            case 4:\n                System.out.println(\"¡ Empieza las semifinales !\");\n                break;\n            case 8:\n                System.out.println(\"¡ Empieza los cuartos de final !\");\n                break;\n            case 16:\n                System.out.println(\"¡ Empieza los octavos de final !\");\n                break;\n            default:\n                System.out.println(\"¡ Empieza la ronda de \" + nParticipants + \" !\");\n                break;\n        }\n        Collections.shuffle(participants);\n        System.out.print(\"COMBATES: \");\n        for (int i = 0; i < nParticipants; i += 2){\n            System.out.print(\"[\" + participants.get(i).getNAME() + \" vs \" + participants.get(i + 1).getNAME() + \"] \");\n        }\n        System.out.println();\n\n        System.out.println(\"Pulse INTRO para continuar la simulación\");\n        new Scanner(System.in).nextLine();\n\n        List<Fighter> loserList = new ArrayList<>();\n        for (int i = 0; i < nParticipants; i += 2){\n            battle(participants.get(i), participants.get(i + 1), loserList);\n            System.out.println();\n        }\n\n        participants.removeAll(loserList);\n\n        if (participants.size() == 1)\n            return participants.get(0);\n        else\n            return tournament(participants);\n    }\n\n    private void battle (Fighter fighter1, Fighter fighter2, List<Fighter> loserList){\n        Fighter first, last;\n        if (fighter1.getSPD() > fighter2.getSPD()) {\n            first = fighter1;\n            last = fighter2;\n        } else if (fighter1.getSPD() < fighter2.getSPD()) {\n            first = fighter2;\n            last = fighter1;\n        } else {\n            first = Math.random() < 0.5 ? fighter1 : fighter2;\n            last = first == fighter1 ? fighter2 : fighter1;\n        }\n\n        try {\n            int round = 1;\n            while(first.isAlive()){\n                System.out.print(\"Ronda \" + round++ + \". \");\n                System.out.print(first.getNAME() + \"(\" + first.getHp() + \"/100) \");\n                System.out.println(last.getNAME() + \"(\" + last.getHp() + \"/100)\");\n\n                attack(first, last);\n                if (!last.isAlive())\n                    break;\n                attack(last, first);\n\n                if (round < 20)\n                    Thread.sleep((long) (delay * 1000));\n                System.out.println();\n            }\n        } catch (InterruptedException e) {\n            throw new RuntimeException(e);\n        }\n\n\n        if (first.isAlive()) {\n            System.out.println(first.getNAME() + \" ha ganado el combate.\");\n            first.heal();\n            loserList.add(last);\n        } else {\n            System.out.println(last.getNAME() + \" ha ganado el combate.\");\n            last.heal();\n            loserList.add(first);\n        }\n    }\n\n    private void attack(Fighter attacker, Fighter defender){\n        if (Math.random() < 0.2){\n            System.out.println(defender.getNAME() + \" ha esquivado el ataque de \" + attacker.getNAME());\n            return;\n        }\n\n        int attackerATK = attacker.getATK();\n        int defenderDEF = defender.getDEF();\n        double damageDealt = Math.max(attackerATK - defenderDEF, 10);\n\n        if (attackerATK < defenderDEF)\n            damageDealt *= 0.1;\n\n        defender.takeDamage(damageDealt);\n        System.out.println(attacker.getNAME() + \" ha hecho \" + damageDealt + \" puntos de daño a \"\n                + defender.getNAME());\n    }\n\n    private boolean checkParticipantCount(int nParticipants){\n        for (int i = 1, participantLimit; (participantLimit = (int) Math.pow(2, i)) <= nParticipants; i++){\n            if (participantLimit == nParticipants)\n                return true;\n        }\n\n        return false;\n    }\n\n    private List<Fighter> getFighters(){\n        Fighter goku = new Fighter(\"Goku\", 80, 50, 60);\n        Fighter vegeta = new Fighter(\"Vegeta\", 70, 60, 55);\n        Fighter piccolo = new Fighter(\"Piccolo\");\n        Fighter gohan = new Fighter(\"Gohan\");\n        Fighter krilin = new Fighter(\"Krilin\");\n        Fighter yamcha = new Fighter(\"Yamcha\");\n        Fighter tien = new Fighter(\"Tien\");\n        Fighter jackie = new Fighter(\"Jackie Chun\");\n\n        return Arrays.asList(goku, vegeta, piccolo, gohan,\n                krilin, yamcha, tien, jackie);\n    }\n\n    public class Fighter{\n        final private String NAME;\n        final private int ATK;\n        final private int DEF;\n        final private int SPD;\n        private int hp = 100;\n\n        public Fighter(String name, int attack, int defense, int speed) {\n            this.NAME = name;\n            this.ATK = attack;\n            this.DEF = defense;\n            this.SPD = speed;\n        }\n        \n        public Fighter(String name){\n            this.NAME = name;\n            Random rnd = new Random();\n            ATK = rnd.nextInt(0, 101);\n            DEF = rnd.nextInt(0, 101);\n            SPD = rnd.nextInt(0, 101);\n        }\n\n        public void takeDamage(double amount){\n            hp -= amount;\n            hp = (hp < 0) ? 0 : hp;\n        }\n\n        public void heal(){\n            hp = 100;\n        }\n\n        public boolean isAlive(){\n            return hp > 0;\n        }\n\n        public String getNAME() {\n            return NAME;\n        }\n\n        public int getATK() {\n            return ATK;\n        }\n\n        public int getDEF() {\n            return DEF;\n        }\n\n        public int getSPD() {\n            return SPD;\n        }\n\n        public int getHp() {\n            return hp;\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/java/MohamedElderkaoui.java",
    "content": "import java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Random;\n\nclass Fighter {\n    private String nombre;\n    private int velocidad;\n    private int ataque;\n    private int defensa;\n    private int salud;\n    private Random rand = new Random();\n\n    public Fighter(String nombre, int velocidad, int ataque, int defensa) {\n        this.nombre = nombre;\n        this.velocidad = velocidad;\n        this.ataque = ataque;\n        this.defensa = defensa;\n        this.salud = 100;\n    }\n\n    public String getNombre() {\n        return nombre;\n    }\n\n    public int getVelocidad() {\n        return velocidad;\n    }\n\n    public boolean estaVivo() {\n        return salud > 0;\n    }\n\n    public void recibirDanio(int danio) {\n        salud -= danio;\n        if (salud < 0) {\n            salud = 0;\n        }\n    }\n\n    public void atacar(Fighter oponente) throws InterruptedException {\n        if (rand.nextDouble() < 0.2) {\n            // 20% de posibilidad de esquivar\n            System.out.println(oponente.getNombre() + \" esquivó el ataque!\");\n            Thread.sleep(4000); // Espera de 4 segundos entre golpes\n            return;\n        }\n\n        int danio;\n        if (this.ataque > oponente.defensa) {\n            danio = this.ataque - oponente.defensa;\n        } else {\n            danio = (int) (0.1 * this.ataque); // 10% del daño de ataque si defensa > ataque\n        }\n\n        System.out.println(this.nombre + \" ataca a \" + oponente.getNombre() + \" por \" + danio + \" de daño!\");\n        oponente.recibirDanio(danio);\n        System.out.println(oponente.getNombre() + \" tiene \" + oponente.salud + \" de salud restante.\");\n        Thread.sleep(4000); // Espera de 4 segundos entre golpes\n    }\n\n    @Override\n    public String toString() {\n        return nombre + \" (Velocidad: \" + velocidad + \", Ataque: \" + ataque + \", Defensa: \" + defensa + \", Salud: \" + salud + \")\";\n    }\n}\n\nclass Batalla {\n    private Fighter luchador1;\n    private Fighter luchador2;\n\n    public Batalla(Fighter luchador1, Fighter luchador2) {\n        this.luchador1 = luchador1;\n        this.luchador2 = luchador2;\n    }\n\n    public Fighter iniciar() throws InterruptedException {\n        System.out.println(\"Batalla: \" + luchador1.getNombre() + \" vs \" + luchador2.getNombre());\n\n        // Determinar quién ataca primero basado en la velocidad\n        Fighter atacante = (luchador1.getVelocidad() >= luchador2.getVelocidad()) ? luchador1 : luchador2;\n        Fighter defensor = (atacante == luchador1) ? luchador2 : luchador1;\n\n        // Pelear hasta que uno de los luchadores pierda toda su salud\n        while (luchador1.estaVivo() && luchador2.estaVivo()) {\n            atacante.atacar(defensor);\n            if (!defensor.estaVivo()) {\n                System.out.println(defensor.getNombre() + \" está fuera de combate!\");\n                break;\n            }\n            // Cambiar atacante y defensor\n            Fighter temp = atacante;\n            atacante = defensor;\n            defensor = temp;\n        }\n\n        return luchador1.estaVivo() ? luchador1 : luchador2;\n    }\n}\n\nclass Torneo {\n    private ArrayList<Fighter> luchadores;\n\n    public Torneo(ArrayList<Fighter> luchadores) {\n        if (!esPotenciaDeDos(luchadores.size())) {\n            throw new IllegalArgumentException(\"El número de luchadores debe ser una potencia de 2.\");\n        }\n        this.luchadores = luchadores;\n    }\n\n    private boolean esPotenciaDeDos(int n) {\n        return (n > 0) && ((n & (n - 1)) == 0);\n    }\n\n    public Fighter iniciar() throws InterruptedException {\n        System.out.println(\"Iniciando el torneo con \" + luchadores.size() + \" luchadores!\");\n        imprimirCuadro(luchadores);\n\n        int ronda = 1;\n        while (luchadores.size() > 1) {\n            Collections.shuffle(luchadores); // Emparejamientos aleatorios en cada ronda\n            ArrayList<Fighter> siguienteRonda = new ArrayList<>();\n\n            System.out.println(\"\\n---- RONDA \" + ronda + \" ----\");\n            for (int i = 0; i < luchadores.size(); i += 2) {\n                Fighter luchador1 = luchadores.get(i);\n                Fighter luchador2 = luchadores.get(i + 1);\n\n                System.out.println(luchador1.getNombre() + \" vs \" + luchador2.getNombre());\n                Batalla batalla = new Batalla(luchador1, luchador2);\n                Fighter ganador = batalla.iniciar();\n                System.out.println(ganador.getNombre() + \" gana la batalla!\\n\");\n\n                siguienteRonda.add(ganador);\n                // Esperar 1 minuto entre las peleas\n                System.out.println(\"Preparando la siguiente batalla... (esperando 1 minuto)\");\n                extracted();\n            }\n\n            luchadores = siguienteRonda; // Los ganadores avanzan a la siguiente ronda\n            ronda++;\n            imprimirCuadro(luchadores); // Imprimir el cuadro del torneo después de cada ronda\n        }\n\n        return luchadores.get(0); // El último luchador restante es el campeón\n    }\n\n    private void extracted() throws InterruptedException {\n        Thread.sleep(60000); // 1 minuto (60 segundos) entre batallas\n    }\n\n    // Función para imprimir el cuadro del torneo\n    public void imprimirCuadro(ArrayList<Fighter> luchadores) {\n        int size = luchadores.size();\n        String[] lineas = new String[size];\n\n        // Inicializar líneas en blanco para mostrar el cuadro\n        for (int i = 0; i < size; i++) {\n            lineas[i] = \"\";\n        }\n\n        // Llenar las líneas con los nombres de los luchadores\n        int indiceCombate = 0;\n        for (int i = 0; i < size / 2; i++) {\n            String luchador1 = luchadores.get(i * 2).getNombre();\n            String luchador2 = luchadores.get(i * 2 + 1).getNombre();\n\n            lineas[indiceCombate++] += String.format(\"%-15s vs %-15s\", luchador1, luchador2);\n        }\n\n        System.out.println(\"\\nCuadro del Torneo:\");\n        for (String linea : lineas) {\n            System.out.println(linea);\n        }\n    }\n}\n\npublic class MohamedElderkaoui {\n    public static void main(String[] args)  {\n        // Crear una lista de luchadores\n        ArrayList<Fighter> luchadores = new ArrayList<>();\n        luchadores.add(new Fighter(\"Goku\", 90, 95, 85));\n        luchadores.add(new Fighter(\"Vegeta\", 88, 90, 80));\n        luchadores.add(new Fighter(\"Piccolo\", 70, 80, 90));\n        luchadores.add(new Fighter(\"Freezer\", 85, 85, 75));\n        luchadores.add(new Fighter(\"Cell\", 80, 88, 82));\n        luchadores.add(new Fighter(\"Majin Buu\", 75, 90, 90));\n        luchadores.add(new Fighter(\"Gohan\", 85, 89, 78));\n        luchadores.add(new Fighter(\"Trunks\", 80, 86, 80));\n\n        // Crear e iniciar el torneo\n        try {\n            Torneo torneo = new Torneo(luchadores);\n            Fighter campeon = torneo.iniciar();\n\n            // Anunciar el ganador\n            System.out.println(\"\\nEl campeón del torneo es \" + campeon.getNombre() + \"!\");\n        } catch (InterruptedException e) {\n            // TODO Auto-generated catch block\n            e.printStackTrace();\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/java/alb-martinez.java",
    "content": "import java.util.*;\n\npublic class AlbMartinez {\n\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n        List<Fighter> fighters = createFighters();\n\n        while (true) {\n            showMenu();\n            int choice = -1;\n\n            try {\n                choice = scanner.nextInt();\n                scanner.nextLine();\n            } catch (InputMismatchException e) {\n                System.out.println(\"Invalid input! Please enter a valid number\");\n                scanner.nextLine();\n                continue;\n            }\n\n            switch (choice) {\n                case 1 -> listFighters(fighters);\n                case 2 -> startTournament(fighters);\n                case 3 -> {\n                    System.out.println(\"Exiting...\");\n                    scanner.close();\n                    return;\n                }\n                default -> System.out.println(\"Invalid option. Please try again.\");\n            }\n        }\n    }\n\n    private static List<Fighter> createFighters() {\n        List<Fighter> fighters = new ArrayList<>();\n        fighters.add(new Fighter(\"Goku\", 90, 95, 80));\n        fighters.add(new Fighter(\"Vegeta\", 85, 100, 75));\n        fighters.add(new Fighter(\"Gohan\", 80, 90, 70));\n        fighters.add(new Fighter(\"Frieza\", 70, 85, 60));\n        fighters.add(new Fighter(\"Cell\", 75, 88, 65));\n        fighters.add(new Fighter(\"Piccolo\", 60, 80, 70));\n        fighters.add(new Fighter(\"Krillin\", 65, 70, 60));\n        fighters.add(new Fighter(\"Majin Buu\", 55, 75, 85));\n        return fighters;\n    }\n\n    private static void showMenu() {\n        System.out.println(\"--- Dragon Ball Tournament Menu ---\");\n        System.out.println(\"1. List Fighters\");\n        System.out.println(\"2. Start Tournament\");\n        System.out.println(\"3. Exit\");\n        System.out.println(\"Choose an option: \");\n    }\n\n    private static void addFighter(Scanner scaner, List<Fighter> fighters) {\n        System.out.println(\"Enter fighter name: \");\n        String name = scaner.nextLine();\n\n        System.out.println(\"Enter speed (0-100): \");\n        int speed = getValidInput(scaner);\n\n        System.out.println(\"Enter attack (0-100): \");\n        int attack = getValidInput(scaner);\n\n        System.out.println(\"Enter defense (0-100): \");\n        int defense = getValidInput(scaner);\n\n        fighters.add(new Fighter(name, speed, attack, defense));\n        System.out.println(name + \" has been added.\");\n    }\n\n    private static int getValidInput(Scanner scanner) {\n        int value;\n        while (true) {\n            value = scanner.nextInt();\n            if (value >= 0 && value <= 100) {\n                break;\n            } else {\n                System.out.println(\"Please enter a value between 0 and 100\");\n            }\n        }\n        scanner.nextLine();\n        return value;\n    }\n\n    private static void listFighters(List<Fighter> fighters) {\n        System.out.println(\"--- Fighters List ---\");\n        for (Fighter figther : fighters) {\n            System.out.println(\"Name \" + figther.name + \", Speed: \" + figther.speed +\n                    \", Attack: \" + figther.attack + \", Defense: \" + figther.defense +\n                    \", Health: \" + figther.health);\n        }\n    }\n\n    private static void startTournament(List<Fighter> fighters) {\n        if (fighters.size() == 0 || (fighters.size() & (fighters.size() - 1)) != 0) {\n            System.out.println(\"Number of fighters must be a power of 2!\");\n            return;\n        }\n        List<Fighter> roundWinners = new ArrayList<>();\n        int round = 1;\n\n        while (fighters.size() > 1) {\n            System.out.println(\"\\n=== 🥋 Round \" + round + \" 🥋 ===\");\n            System.out.println(\"Fighters in this round: \" + fighters.size() + \"\\n\");\n\n            for (int i = 0; i < fighters.size(); i += 2) {\n                Fighter fighter1 = fighters.get(i);\n                Fighter fighter2 = fighters.get(i + 1);\n\n                System.out.println(\">>> Battle \" + ((i / 2) + 1) + \": \" + fighter1.name + \" 🆚 \" + fighter2.name);\n                battle(fighter1, fighter2);\n\n                // Determinar el ganador\n                roundWinners.add(fighter1.health > 0 ? fighter1 : fighter2);\n\n                fighter1.resetHealth();\n                fighter2.resetHealth();\n            }\n            fighters = roundWinners;\n            roundWinners = new ArrayList<>();\n            round++;\n        }\n\n        System.out.println(\"\\n🏆 The champion of the tournament is: \" + fighters.get(0).name + \"! 🏆\");\n\n        System.exit(0);\n    }\n\n    public static void battle(Fighter fighter1, Fighter fighter2) {\n        Fighter attacker = fighter1.speed >= fighter2.speed ? fighter1 : fighter2;\n        Fighter defender = attacker == fighter1 ? fighter2 : fighter1;\n\n        System.out.println(\"🔽 \" + attacker.name + \" starts attacking.\");\n\n        while (fighter1.health > 0 && fighter2.health > 0) {\n            // Verificar si el defensor esquiva\n            if (Math.random() < 0.2) {\n                System.out.println(\"💨 \" + defender.name + \" dodged the attack!\");\n            } else {\n                int damage;\n\n                // Calcular daño según la defensa y el ataque\n                if (defender.defense > attacker.attack) {\n                    // Defensa mayor que ataque, recibe 10% del daño de ataque\n                    damage = (int) (attacker.attack * 0.1);\n                } else {\n                    // Daño normal\n                    damage = attacker.attack - defender.defense;\n                    damage = Math.max(damage, 0); // Asegurarse de que no sea negativo\n                }\n\n                defender.health -= damage;\n\n                if (defender.health < 0) {\n                    defender.health = 0;\n                }\n\n                System.out.println(\"⚔️ \" + attacker.name + \" attacks \" + defender.name + \" for \" + damage + \" damage.\");\n                System.out.println(\"❤️ \" + defender.name + \"'s health is now \" + defender.health);\n            }\n\n            // Cambiar turno\n            Fighter temp = attacker;\n            attacker = defender;\n            defender = temp;\n        }\n\n        if (fighter1.health <= 0) {\n            System.out.println(\"🎉 \" + fighter2.name + \" wins the battle!\\n\");\n        } else {\n            System.out.println(\"🎉 \" + fighter1.name + \" wins the battle!\\n\");\n        }\n    }\n\n    static class Fighter {\n        String name;\n        int speed;\n        int attack;\n        int defense;\n        int health;\n        int initialHealth;\n\n        public Fighter(String name, int speed, int attack, int defense) {\n            this.name = name;\n            this.speed = speed;\n            this.attack = attack;\n            this.defense = defense;\n            this.health = 100;\n            this.initialHealth = 100;\n        }\n\n        public void resetHealth() {\n            this.health = this.initialHealth;\n        }\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/java/asjordi.java",
    "content": "import java.util.*;\n\npublic class asjordi {\n\n    private static final Random r = new Random();\n\n    public static void main(String[] args) {\n        Tournament tournament = new Tournament(\n                new Fighter(\"Goku\"), new Fighter(\"Vegeta\"), new Fighter(\"Gohan\"), new Fighter(\"Trunks\"),\n                new Fighter(\"Goten\"), new Fighter(\"Picoro\"), new Fighter(\"Krilin\"), new Fighter(\"Yamcha\"),\n                new Fighter(\"Cell\"), new Fighter(\"Freezer\"), new Fighter(\"Buu\"), new Fighter(\"Jiren\"),\n                new Fighter(\"Broly\"), new Fighter(\"Kale\"), new Fighter(\"Caulifla\"), new Fighter(\"Hit\")\n        );\n\n        var winner = tournament.start();\n        System.out.println(\"Champion: \" + winner.getName());\n    }\n\n    static class Tournament {\n\n        private List<Fighter> fighters;\n\n        public Tournament(Fighter... fighters) {\n            if (!isAPowerOfTwo(fighters.length)) {\n                throw new IllegalArgumentException(\"The number of fighters must be a power of two\");\n            }\n            this.fighters = Arrays.asList(fighters);\n            Collections.shuffle(this.fighters);\n        }\n\n        public Fighter start() {\n            while (fighters.size() > 1) {\n                fighters = startRound();\n            }\n            return fighters.get(0);\n        }\n\n        public List<Fighter> startRound() {\n            var winners = new ArrayList<Fighter>();\n\n            for (int i = 0; i < fighters.size(); i += 2) {\n                var fighter1 = fighters.get(i);\n                var fighter2 = fighters.get(i + 1);\n                System.out.println(\"Fight: \" + fighter1.getName() + \" vs \" + fighter2.getName());\n                var battle = new Battle(fighter1, fighter2);\n                var winner = battle.startRound();\n                System.out.println(\"Winner of the fight: \" + winner.getName());\n                winners.add(winner);\n            }\n\n            return winners;\n        }\n\n        public void showFighters() {\n            fighters.forEach(f -> System.out.println(f.getName()));\n        }\n\n        private boolean isAPowerOfTwo(int numero) {\n            return numero > 0 && (numero & (numero - 1)) == 0;\n        }\n\n    }\n\n    static class Battle {\n        private Fighter fighter1;\n        private Fighter fighter2;\n\n        public Battle(Fighter fighter1, Fighter fighter2) {\n            this.fighter1 = fighter1.getSpeed() > fighter2.getSpeed() ? fighter1 : fighter2;\n            this.fighter2 = fighter1.getSpeed() > fighter2.getSpeed() ? fighter2 : fighter1;\n        }\n\n        public Fighter startRound() {\n            Fighter winner = null;\n\n            while (winner == null) {\n                fight(fighter1, fighter2);\n                if (fighter2.getHealth() <= 0) winner = fighter1;\n\n                fight(fighter2, fighter1);\n                if (fighter1.getHealth() <= 0) winner = fighter2;\n            }\n\n            return winner;\n        }\n\n        public void fight(Fighter a, Fighter b) {\n            var damage = Math.abs(a.getAttack() - b.getDefense());\n\n            if (getProbabilitySkipAttack() < 0.2) {\n                System.out.println(b.getName() + \" skip attack\");\n                return;\n            }\n\n            if (b.getDefense() > a.getAttack()) {\n                damage = damage * 0.1;\n            }\n\n            b.setHealth(b.getHealth() - damage);\n            System.out.println(a.getName() + \" attack \" + b.getName() + \" with \" + damage + \" damage\");\n        }\n\n        private double getProbabilitySkipAttack() {\n            return r.nextDouble(0, 1);\n        }\n    }\n\n    static class Fighter {\n        private final String name;\n        private double health;\n        private double speed;\n        private double attack;\n        private double defense;\n\n        public Fighter(String name) {\n            this.name = name;\n            this.health = 100;\n            this.speed = getValue();\n            this.attack = getValue();\n            this.defense = getValue();\n        }\n\n        private double getValue() {\n            return r.nextInt(50, 101);\n        }\n\n        public String getName() {\n            return name;\n        }\n\n        public double getHealth() {\n            return health;\n        }\n\n        public void setHealth(double health) {\n            this.health = health;\n        }\n\n        public double getSpeed() {\n            return speed;\n        }\n\n        public double getAttack() {\n            return attack;\n        }\n\n        public double getDefense() {\n            return defense;\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/java/martinbohorquez.java",
    "content": "import java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.concurrent.TimeUnit;\nimport java.util.stream.Collectors;\n\npublic class martinbohorquez {\n    public static void main(String[] args) throws InterruptedException {\n        // 1. Mostrar luchadores a participar\n        List<Figther> figthers = createFigthers();\n        System.out.println(\"Los participan en el torneo de 'Dragon Ball: Sparking! ZERO!' son:\");\n        figthers.forEach(System.out::println);\n\n        // 2. Simular torneo\n        simulateTournament(figthers);\n    }\n\n    private static void simulateTournament(List<Figther> figthers) throws InterruptedException {\n        printTittle(\"Torneo Dragon Ball: Sparking! ZERO\");\n        int rounds = (int) (Math.log(figthers.size())/Math.log(2));\n        for (int i = 1; i <= rounds; i++) {\n            if (i == rounds) printTittle(\"Ronda Final\");\n            else printTittle(\"Ronda número \" + i);\n            figthers = figthers.stream().filter(figther -> figther.getHealth().equals(100))\n                    .collect(Collectors.toList());\n            Collections.shuffle(figthers);\n            for (int j = 0; j < figthers.size() / 2; j++) {\n                Figther winner = battle(figthers.get(j), figthers.get(figthers.size() - 1 - j));\n                winner.setHealth(100);\n                System.out.printf(\"🌟 %s ha ganado la batalla!%n\", winner.getName());\n                if (i == rounds) printTittle(\"👑 \" + winner.getName() + \" es el ganador del torneo Dragon Ball: Sparking! ZERO!\");\n            }\n        }\n    }\n\n    private static Figther battle(Figther f1, Figther f2) throws InterruptedException {\n        printSubtitle(f1.getName().toUpperCase() + \" 🆚 \" + f2.getName().toUpperCase());\n        Figther fa = f1.getSpeed() > f2.getSpeed()? f1: f2;\n        Figther fb = fa == f1? f2: f1;\n        System.out.printf(\"🏁 %s da el primer ataque.%n\", fa.getName());\n        int turn = 0;\n        while (f1.getHealth() > 0 && f2.getHealth() > 0) {\n            System.out.printf(\"▶️ Turno %s:%n\", ++turn);\n            if (fa.attack(fb)) break;\n            if (fb.attack(fa)) break;\n            TimeUnit.SECONDS.sleep(1);\n        }\n        return fb.getHealth().equals(0)? fa: fb;\n    }\n\n    private static void printTittle(String tittle) {\n        int length = tittle.length();\n        String blankSpaces = \" \".repeat(Math.max(20 - length / 2, 0));\n        System.out.println(\"\\n\" + blankSpaces + \"╔\" + \"═\".repeat(length + 2) + \"╗\");\n        System.out.println(blankSpaces + \"║ \" + tittle + \" ║\");\n        System.out.println(blankSpaces + \"╚\" + \"═\".repeat(length + 2) + \"╝\");\n    }\n\n    private static void printSubtitle(String subtitle) {\n        int length = subtitle.length();\n        System.out.println(\"╔\" + \"═\".repeat(length + 2) + \"╗\");\n        System.out.println(\"║ \" + subtitle + \" ║\");\n        System.out.println(\"╚\" + \"═\".repeat(length + 2) + \"╝\");\n    }\n\n    private static List<Figther> createFigthers(){\n        return new ArrayList<>(List.of(\n            new Figther(\"Goku\", 90, 95, 80),\n            new Figther(\"Vegeta\", 85, 100, 75),\n            new Figther(\"Gohan\", 80, 90, 70),\n            new Figther(\"Frieza\", 70, 85, 60),\n            new Figther(\"Cell\", 75, 88, 65),\n            new Figther(\"Piccolo\", 60, 80, 70),\n            new Figther(\"Krillin\", 65, 70, 60),\n            new Figther(\"Majin Buu\", 55, 75, 85)));\n    }\n\n    private static class Figther {\n        private Integer id;\n        private String name;\n        private Integer speed;\n        private Integer attack;\n        private Integer defense;\n        private Integer health;\n        private static Integer count = 0;\n\n        public Figther(String name, Integer speed, Integer attack, Integer defense) {\n            this.id = ++count;\n            this.name = name;\n            this.speed = speed;\n            this.attack = attack;\n            this.defense = defense;\n            this.health = 100;\n        }\n\n        public Integer getId() {\n            return id;\n        }\n\n        public void setId(Integer id) {\n            this.id = id;\n        }\n\n        public String getName() {\n            return name;\n        }\n\n        public Integer getSpeed() {\n            return speed;\n        }\n\n        public Integer getAttack() {\n            return attack;\n        }\n\n        public Integer getDefense() {\n            return defense;\n        }\n\n        public Integer getHealth() {\n            return health;\n        }\n\n        public void setHealth(Integer health) {\n            this.health = health;\n        }\n\n        public void decreseHealth(Integer damage) {\n            this.health = Math.max(health - damage, 0);\n        }\n\n        public boolean attack(Figther f) {\n            int damage = f.getDefense() > this.getAttack()\n                    ? (int) (this.getAttack() * 0.1): this.getAttack() - f.getDefense();\n            System.out.printf(\"⚔️ %s ataca a %s con una daño de %d.%n\", this.name, f.name, damage);\n\n            if (Math.random() < 0.2) System.out.printf(\"🌀 %s esquivó el ataque.%n\", f.getName());\n            else {\n                f.decreseHealth(damage);\n                System.out.printf(\"❤️ Salud de %s se reduce a %d.%n\", f.name, f.getHealth());\n            }\n            return f.getHealth().equals(0);\n        }\n\n        @Override\n        public String toString() {\n            return \"id: \" + id + \", {name: '\" + name + \"', speed: \" + speed + \", attack: \" + attack\n                    + \", defense: \" + defense + \", health: \" + health + \"}\";\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/java/miguelex.java",
    "content": "import java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Scanner;\n\nclass Luchador {\n    String nombre;\n    int velocidad;\n    int ataque;\n    int defensa;\n    int salud = 100;\n\n    public Luchador(String nombre, int velocidad, int ataque, int defensa) {\n        this.nombre = nombre;\n        this.velocidad = velocidad;\n        this.ataque = ataque;\n        this.defensa = defensa;\n    }\n\n    public boolean esquivar() {\n        return Math.random() < 0.2;\n    }\n}\n\npublic class miguelex {\n    public static Luchador batalla(Luchador luchador1, Luchador luchador2) {\n        System.out.println(\"¡Batalla entre \" + luchador1.nombre + \" y \" + luchador2.nombre + \"!\");\n        Luchador atacante = (luchador1.velocidad >= luchador2.velocidad) ? luchador1 : luchador2;\n        Luchador defensor = (atacante == luchador1) ? luchador2 : luchador1;\n\n        while (luchador1.salud > 0 && luchador2.salud > 0) {\n            if (defensor.esquivar()) {\n                System.out.println(defensor.nombre + \" esquivó el ataque de \" + atacante.nombre + \"!\");\n            } else {\n                int danio = atacante.ataque - defensor.defensa;\n                if (danio <= 0) {\n                    danio = (int) (atacante.ataque * 0.1);\n                }\n                defensor.salud -= danio;\n                System.out.println(atacante.nombre + \" ataca a \" + defensor.nombre + \" y causa \" + danio + \" de daño. Salud restante de \" + defensor.nombre + \": \" + defensor.salud);\n            }\n            Luchador temp = atacante;\n            atacante = defensor;\n            defensor = temp;\n        }\n\n        Luchador ganador = (luchador1.salud > 0) ? luchador1 : luchador2;\n        System.out.println(\"¡\" + ganador.nombre + \" es el ganador de la batalla!\\n\");\n        return ganador;\n    }\n\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n        ArrayList<Luchador> luchadores = new ArrayList<>();\n\n        System.out.print(\"Ingrese el número de luchadores (debe ser una potencia de 2): \");\n        int numLuchadores = scanner.nextInt();\n        scanner.nextLine(); // Consumir nueva línea\n\n        if ((numLuchadores & (numLuchadores - 1)) != 0 || numLuchadores <= 0) {\n            System.out.println(\"El número de luchadores debe ser una potencia de 2.\");\n            return;\n        }\n\n        for (int i = 0; i < numLuchadores; i++) {\n            System.out.print(\"Ingrese el nombre del luchador \" + (i + 1) + \": \");\n            String nombre = scanner.nextLine();\n\n            System.out.print(\"Ingrese la velocidad de \" + nombre + \" (0-100): \");\n            int velocidad = scanner.nextInt();\n\n            System.out.print(\"Ingrese el ataque de \" + nombre + \" (0-100): \");\n            int ataque = scanner.nextInt();\n\n            System.out.print(\"Ingrese la defensa de \" + nombre + \" (0-100): \");\n            int defensa = scanner.nextInt();\n            scanner.nextLine(); // Consumir nueva línea\n\n            luchadores.add(new Luchador(nombre, velocidad, ataque, defensa));\n        }\n\n        System.out.println(\"¡Comienza el torneo de Dragon Ball: Sparking! ZERO!\\n\");\n        while (luchadores.size() > 1) {\n            ArrayList<Luchador> ganadores = new ArrayList<>();\n            Collections.shuffle(luchadores);\n\n            for (int i = 0; i < luchadores.size(); i += 2) {\n                Luchador ganador = batalla(luchadores.get(i), luchadores.get(i + 1));\n                ganadores.add(ganador);\n            }\n            luchadores = ganadores;\n        }\n\n        System.out.println(\"¡El ganador del torneo es \" + luchadores.get(0).nombre + \"!\");\n        scanner.close();\n    }\n}\n\n"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/java/thompson6626.java",
    "content": "\nimport java.util.*;\n\npublic class thompson6626 {\n\n    public static void main(String[] args) {\n        List<Luchador> luchadores = randomLuchadores();\n        Torneo torneo = new Torneo(luchadores);\n        torneo.iniciar();\n    }\n    public static List<Luchador> randomLuchadores() {\n        List<String> dragonBallFighters = Arrays.asList(\n                \"Goku\", \"Vegeta\", \"Piccolo\", \"Gohan\", \"Freezer\", \"Cell\",\n                \"Majin Boo\", \"Trunks\", \"Krilin\", \"Ten Shin Han\", \"Yamcha\",\n                \"Broly\", \"Bills\", \"Whis\", \"Jiren\", \"Hit\",\n                \"Zamas\", \"Androide 18\", \"Androide 17\", \"Gotenks\", \"Raditz\",\n                \"Nappa\", \"Bardock\", \"Kid Boo\", \"Kaiosama\", \"Maestro Roshi\",\n                \"Dende\", \"Videl\", \"Pan\", \"Mr. Satán\", \"Chichi\", \"Bulma\",\n                \"Zarbon\", \"Dodoria\", \"Ginyu\", \"Recoome\", \"Burter\", \"Jeice\", \"Guldo\",\n                \"Shenlong\", \"Tapion\", \"Puar\", \"Oolong\"\n        );\n\n        var random = new Random();\n        int numeroDeLuchadores;\n        do {\n            numeroDeLuchadores = random.nextInt(dragonBallFighters.size() + 1);\n        }while (numeroDeLuchadores < 2 || !Utils.esPotenciadeDos(numeroDeLuchadores));\n\n        Set<String> nombresTomados = new HashSet<>();\n        List<Luchador> luchadores = new ArrayList<>();\n        for (int i = 0; i < numeroDeLuchadores; i++) {\n            int nombreIndex;\n            do {\n                nombreIndex = random.nextInt(numeroDeLuchadores);\n            }while (nombresTomados.contains(dragonBallFighters.get(nombreIndex)));\n            nombresTomados.add(dragonBallFighters.get(nombreIndex));\n            luchadores.add(new Luchador(\n                    dragonBallFighters.get(nombreIndex),\n                    random.nextInt(101),\n                    random.nextInt(101),\n                    random.nextInt(101)\n            ));\n        }\n        return luchadores;\n    }\n\n\n\n    static class Luchador{\n\n        private static final int VIDA_MAXIMA = 100;\n        private static final int CHANCE_DE_EVASION = 20;\n        private final Random random = new Random();\n        private final String nombre;\n        private final int velocidad;\n        private final int ataque;\n        private final int defensa;\n        private int vida;\n        public Luchador(String nombre,int velocidad, int ataque, int defensa) {\n            this.nombre = nombre;\n            this.velocidad = velocidad;\n            this.ataque = ataque;\n            this.defensa = defensa;\n            this.vida = VIDA_MAXIMA;\n        }\n        public void descansar(){\n            this.vida = VIDA_MAXIMA;\n        }\n        public boolean atacar(Luchador contrincante){\n            int vidaRestanteDelContrincaten = contrincante.recibirDaño(this);\n            boolean fatal = vidaRestanteDelContrincaten <= 0;\n            return fatal;\n        }\n        public int recibirDaño(Luchador atacante){\n            if (esquivar()){\n                System.out.printf(\n                        \"%s esquivo el ataque de %s %n\",\n                        this.nombre ,\n                        atacante.nombre\n                );\n                return this.vida;\n            }\n            int dañoARecibir;\n            if (this.defensa > atacante.ataque){\n                dañoARecibir = Utils.porcentajeDe(10 , atacante.ataque);// Si la defensa es mayor al ataque\n                System.out.printf(\n                        \"%s tuvo una defensa mayor al ataque de %s y el daño se reduce a 10%% del total! (%d -> %d) %n\",\n                        this.nombre,\n                        atacante.nombre,\n                        atacante.ataque,\n                        dañoARecibir\n                );\n            }else{\n                dañoARecibir = Math.max(0 , atacante.ataque - this.defensa);\n            }\n\n            int vidaAntesDeAtaque = this.vida;\n            this.vida -= dañoARecibir;\n            System.out.printf(\"%s recibe un daño total de %d (%d -> %d)%n\",\n                    this.nombre,\n                    dañoARecibir,\n                    vidaAntesDeAtaque,\n                    this.vida\n            );\n            return this.vida;\n        }\n        public boolean esquivar() {\n            int chance = random.nextInt(100);\n            return chance < CHANCE_DE_EVASION;\n        }\n        public int getVelocidad() {\n            return velocidad;\n        }\n        public int getVida() {\n            return vida;\n        }\n\n        public String getNombre() {\n            return nombre;\n        }\n    }\n\n    static class Batalla{\n        private final Luchador rapido;\n        private final Luchador lento;\n        public Batalla(Luchador luchador1, Luchador luchador2) {\n            if (luchador1.getVelocidad() > luchador2.getVelocidad()){\n                this.rapido = luchador1;\n                this.lento = luchador2;\n            }else {\n                this.rapido = luchador2;\n                this.lento = luchador1;\n            }\n        }\n        // True gano el rapido false gano el lento\n        public Map<Resultado,Luchador> iniciar(){\n            System.out.printf(\"--- %S VS %S --- %n\",\n                    rapido.getNombre(),\n                    lento.getNombre()\n            );\n            boolean rapidoGano = false;\n            do{\n                if (rapido.atacar(lento)){\n                    rapidoGano = true;\n                    break;\n                }\n                lento.atacar(rapido);\n            }while (rapido.getVida() > 0 && lento.getVida() > 0);\n\n            Luchador ganador;\n            Luchador perdedor;\n            if (rapidoGano){\n                ganador = rapido;\n                perdedor = lento;\n            }else{\n                ganador = lento;\n                perdedor = rapido;\n            }\n            // Recuperar vida\n            System.out.printf(\n                    \"%S gana con %d de vida restante! %n\",\n                    ganador.getNombre(),\n                    ganador.getVida()\n            );\n            ganador.descansar();\n            return Map.of(Resultado.GANADOR, ganador,Resultado.PERDEDOR,perdedor);\n        }\n\n\n    }\n    static class Torneo{\n        List<Luchador> luchadores;\n        private final Random RANDOM = new Random();\n        private int ronda = 1;\n        public Torneo(List<Luchador> luchadores) {\n            if (luchadores.size() % 2 != 0) throw new IllegalArgumentException(\"Numero de luchadores invalido.\");\n            this.luchadores = luchadores;\n        }\n        public Torneo(Luchador... luchadores){\n            if (luchadores.length % 2 != 0) throw new IllegalArgumentException(\"Numero de luchadores invalido.\");\n            this.luchadores = Arrays.asList(luchadores);\n        }\n\n        public void siguienteEtapa(){\n            int luchadoresRestantes = luchadores.size();\n            Etapa etapa = Etapa.etapaPorLuchadores(luchadoresRestantes);\n\n            if (etapa != null) System.out.printf(\"-- %s -- %n\", etapa.getNombre());\n            else System.out.printf(\"-- Ronda %d -- %n\",ronda);\n\n            Set<Integer> yaJugaron = new HashSet<>();\n            List<Luchador> pasaron = new ArrayList<>();\n            while (yaJugaron.size() < luchadoresRestantes){\n                int participante1;\n                do {\n                    participante1 = RANDOM.nextInt(luchadoresRestantes);\n                }while (yaJugaron.contains(participante1));\n                int participante2;\n                do {\n                    participante2 = RANDOM.nextInt(luchadoresRestantes);\n                }while (yaJugaron.contains(participante2) || participante2 == participante1);\n\n                var batalla = new Batalla(\n                        luchadores.get(participante1),\n                        luchadores.get(participante2)\n                );\n\n                Map<Resultado,Luchador> resultado = batalla.iniciar();\n                System.out.printf(\n                        \"%S ha sido eliminado! %n\",\n                        resultado.get(Resultado.PERDEDOR).getNombre()\n                );\n                pasaron.add(resultado.get(Resultado.GANADOR));\n                yaJugaron.add(participante1);\n                yaJugaron.add(participante2);\n                luchadores.forEach(e -> System.out.println(e.getNombre()));\n                System.out.println(participante1 +\" \"+participante2);\n                System.out.println(yaJugaron);\n                System.out.println(luchadoresRestantes);\n            }\n            System.out.println(\".....\");\n            luchadores = pasaron;\n            ronda++;\n        }\n        public void iniciar(){\n            while (luchadores.size() > 1) {\n                siguienteEtapa();\n            }\n            Luchador ganador = luchadores.removeLast();\n            String mensaje = String.format(\"%S es el ganador del torneo!!!\", ganador.getNombre());\n\n            int ancho = mensaje.length() + 6;\n            String borde = \"*\".repeat(ancho);\n\n            System.out.println(borde);\n            System.out.printf(\"* %-\" + (ancho - 4) + \"s *%n\", \" \");\n            System.out.printf(\"* %-\" + (ancho - 4) + \"s *%n\", mensaje);\n            System.out.printf(\"* %-\" + (ancho - 4) + \"s *%n\", \" \");\n            System.out.println(borde);\n        }\n\n        enum Etapa {\n            GRAN_FINAL(\"Gran Final\",2),\n            SEMIFINALES(\"Semifinales\",4),\n            CUARTOS_DE_FINAL(\"Cuartos de Final\",8),\n            OCTAVOS_DE_FINAL(\"Octavos de Final\",16);\n            private final String nombre;\n            private final int jugadores;\n            public static final Etapa[] ETAPAS = values();\n            Etapa(String nombre, int luchadores) {\n                this.nombre = nombre;\n                this.jugadores = luchadores;\n            }\n            public String getNombre() {\n                return nombre;\n            }\n            public static Etapa etapaPorLuchadores(int luchadores){\n                for(Etapa etapa : ETAPAS){\n                    if (etapa.jugadores == luchadores){\n                        return etapa;\n                    }\n                }\n                return null;\n            }\n        }\n\n    }\n    enum Resultado{\n        GANADOR,\n        PERDEDOR\n    }\n    public static class Utils{\n        public static int porcentajeDe(int porcentaje,int valor){\n            return Math.round(((float) porcentaje / 100) * valor);\n        }\n        public static boolean esPotenciadeDos(int n) {\n            if (n == 0)\n                return false;\n\n            while (n != 1) {\n                if (n % 2 != 0)\n                    return false;\n                n = n / 2;\n            }\n            return true;\n        }\n    }\n\n}"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #42 - JavaScript -> Jesus Antonio Escamilla */\n\n/**\n * TORNEO DRAGON BALL.\n * Utilizando la Terminal para pedir datos y agregarlos.\n */\n\nclass Fighter{\n    constructor(name, speed, attack, defense){\n        this.name = name;\n        this.speed = speed;\n        this.attack = attack;\n        this.defense = defense;\n        this.health = 100;\n    }\n\n    isAlive(){\n        return this.health > 0;\n    }\n\n    attackOpponent(opponent){\n        if (Math.random() < 0.2) {\n            console.log(`${opponent.name} esquivó el ataque de ${this.name}!`);\n            return;\n        }\n\n        let damage = this.attack - opponent.defense;\n        if (damage <= 0) {\n            damage = this.attack * 0.1;\n        }\n\n        opponent.health = Math.max(opponent.health - damage, 0);\n        console.log(\n            `${this.name} ataca a ${opponent.name} causando ${damage.toFixed(2)} de daño. Salud restante de ${opponent.name}: ${opponent.health.toFixed(2)}`\n        );\n    }\n\n}\n\nfunction battle(fighter1, fighter2) {\n    console.log(`\\nInicia la batalla entre ${fighter1.name} y ${fighter2.name}!`);\n    \n    let [attacker, defender] = fighter1.speed >= fighter2.speed\n        ? [fighter1, fighter2]\n        : [fighter1, fighter2];\n\n    while (fighter1.isAlive() && fighter2.isAlive()){\n        attacker.attackOpponent(defender);\n        [attacker, defender] = [defender, attacker];\n    }\n\n    const winner = fighter1.isAlive() ? fighter1 : fighter2;\n    console.log(`\\n${winner.name} gana la batalla!\\n`);\n    return winner;\n}\n\nfunction tournament(fighters) {\n    if (!Number.isInteger(Math.log2(fighters.length))) {\n        throw new Error(\"El número de luchadores debe ser una potencia de 2.\");\n    }\n\n    console.log(\"\\nInicia el Torneo de Artes Marciales!\\n\");\n    let round = 1;\n\n    while (fighters.length > 1) {\n        console.log(`\\n--- Ronda ${round} ---\\n`);\n        const nextRound = [];\n\n        while (fighters.length > 0) {\n            const fighter1 = fighters.splice(Math.floor(Math.random() * fighters.length), 1)[0];\n            const fighter2 = fighters.splice(Math.floor(Math.random() * fighters.length), 1)[0];\n\n            console.log(`\\nPareja: ${fighter1.name} vs ${fighter2.name}`);\n            const winner = battle(fighter1, fighter2);\n            nextRound.push(winner);\n        }\n\n        fighters = nextRound;\n        round++;\n\n    }\n\n    console.log(`\\nEl ganador del torneo es ${fighters[0].name}!`);\n    return fighters[0];\n}\n\n\n\n// Crear luchadores\nconst fighters = [\n    new Fighter(\"Goku\", 95, 90, 85),\n    new Fighter(\"Vegeta\", 90, 92, 88),\n    new Fighter(\"Gohan\", 88, 85, 90),\n    new Fighter(\"Piccolo\", 80, 75, 95),\n    new Fighter(\"Freezer\", 93, 89, 80),\n    new Fighter(\"Cell\", 85, 88, 85),\n    new Fighter(\"Majin Buu\", 87, 84, 92),\n    new Fighter(\"Trunks\", 91, 86, 87),\n];\n\n// Ejecutar el torneo\ntournament(fighters);"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/javascript/Rafacv23.js",
    "content": "// Hecho por @Rafacv23 | https://github.com/Rafacv23 | https://twitter.com/rafacanosa  | https://www.rafacanosa.dev\n\n// Global constants\nconst EVADE_CHANCE = 0.2\nconst HEALTH = 100\n\nclass Fighter {\n  constructor(nombre, velocidad, ataque, defensa) {\n    this.nombre = nombre\n    this.velocidad = this.checkAttribute(velocidad, \"velocidad\")\n    this.ataque = this.checkAttribute(ataque, \"ataque\")\n    this.defensa = this.checkAttribute(defensa, \"defensa\")\n    this.salud = HEALTH // Inicialmente, todos tienen 100 de salud\n  }\n\n  // ensure that the attribute are between 0 and 100\n  checkAttribute(value, attribute) {\n    if (value < 0 || value > 100) {\n      throw new Error(`El valor de ${attribute} debe ser entre 0 y 100`)\n    }\n    return value\n  }\n\n  attack(defender) {\n    if (defender.salud === 0) {\n      console.log(`${defender.nombre} ha perdido toda su salud`)\n      return\n    }\n\n    // calculamos si el defensor evita el ataque o no\n    const evade = Math.random()\n\n    if (evade < EVADE_CHANCE) {\n      console.log(`${defender.nombre} ha esquivado el ataque`)\n      return\n    }\n    // Calcular el daño\n    let damage\n\n    if (defender.defensa > this.ataque || defender.defensa === this.ataque) {\n      damage = this.ataque * 0.1 // Recibe solo el 10% del ataque\n      console.log(`${defender.nombre} bloquea gran parte del daño!`)\n    } else {\n      damage = this.ataque - defender.defensa // Full damage\n    }\n\n    // Evitar que el daño sea negativo\n    if (damage < 0) damage = 0\n\n    // Aplicar el daño al defensor\n    defender.salud -= damage\n\n    console.log(\n      `${this.nombre} ha atacado a ${defender.nombre} con ${damage.toFixed(\n        2\n      )} de daño`\n    )\n    console.log(`Salud restante de ${defender.nombre}: ${defender.salud}`)\n  }\n\n  showInfo() {\n    console.log(`Nombre: ${this.nombre}`)\n    console.log(`Velocidad: ${this.velocidad}`)\n    console.log(`Ataque: ${this.ataque}`)\n    console.log(`Defensa: ${this.defensa}`)\n    console.log(`Salud: ${this.salud}`)\n  }\n}\n\nconst fighters = [\n  new Fighter(\"Goku\", 85, 95, 80),\n  new Fighter(\"Vegeta\", 80, 90, 85),\n  new Fighter(\"Piccolo\", 70, 75, 90),\n  new Fighter(\"Gohan\", 88, 92, 78),\n  new Fighter(\"Trunks\", 78, 88, 82),\n  new Fighter(\"Kefla\", 60, 90, 85),\n  new Fighter(\"Freezer\", 75, 85, 80),\n  new Fighter(\"Cell\", 83, 87, 90),\n]\n\nfunction shuffleFighters(fighters) {\n  for (let i = fighters.length - 1; i > 0; i--) {\n    const j = Math.floor(Math.random() * (i + 1))\n    ;[fighters[i], fighters[j]] = [fighters[j], fighters[i]]\n  }\n  return fighters\n}\n\nfunction drawFighters() {\n  let round = 1\n\n  while (fighters.length > 1) {\n    if (fighters.length === 2) {\n      console.log(`\\n--- Ronda Final ---`)\n    } else {\n      console.log(`\\n--- Ronda ${round} ---`)\n    }\n\n    // Shuffle fighters for random matchups\n    shuffleFighters(fighters)\n\n    // Process battles in pairs\n    for (let i = 0; i < fighters.length; i++) {\n      const fighter1 = fighters[i]\n      const fighter2 = fighters[i + 1]\n\n      console.log(\n        `\\n${fighter1.nombre} (Salud: ${fighter1.salud}) vs ${fighter2.nombre} (Salud: ${fighter2.salud})`\n      )\n\n      // Decide who attacks first based on speed\n      let attacker, defender\n      if (fighter1.velocidad >= fighter2.velocidad) {\n        attacker = fighter1\n        defender = fighter2\n      } else {\n        attacker = fighter2\n        defender = fighter1\n      }\n\n      // Fight until one of them loses\n      while (attacker.salud > 0 && defender.salud > 0) {\n        attacker.attack(defender)\n        if (defender.salud > 0) {\n          defender.attack(attacker)\n        }\n      }\n\n      // Remove the defeated fighter\n      if (attacker.salud <= 0) {\n        console.log(`${attacker.nombre} ha sido eliminado`)\n        console.log(`${defender.nombre} avanza a la siguiente ronda`)\n        fighters.splice(fighters.indexOf(attacker), 1)\n      } else if (defender.salud <= 0) {\n        console.log(`${defender.nombre} ha sido eliminado`)\n        console.log(`${attacker.nombre} avanza a la siguiente ronda`)\n        fighters.splice(fighters.indexOf(defender), 1)\n      }\n    }\n\n    round++\n  }\n\n  // The last remaining fighter is the winner\n  if (fighters.length === 1) {\n    console.log(\"\\n¡El torneo ha terminado! El ganador/a es:\")\n    fighters[0].showInfo()\n  }\n}\n\n// function that sims the tournament\n;(function tournament() {\n  if (\n    (fighters.length & (fighters.length - 1)) !== 0 ||\n    fighters.length === 0\n  ) {\n    console.log(\"El número de luchadores debe ser una potencia de 2\")\n    return\n  }\n  drawFighters()\n})()\n"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/javascript/RaulDoezon.js",
    "content": "/*\n  EJERCICIO:\n  ¡El último videojuego de Dragon Ball ya está aquí!\n  Se llama Dragon Ball: Sparking! ZERO.\n\n  Simula un Torneo de Artes Marciales, al más puro estilo\n  de la saga, donde participarán diferentes luchadores, y el\n  sistema decidirá quién es el ganador.\n\n  Luchadores:\n  - Nombre.\n  - Tres atributos: velocidad, ataque y defensa\n    (con valores entre 0 a 100 que tú decidirás).\n  - Comienza cada batalla con 100 de salud.\n  Batalla:\n  - En cada batalla se enfrentan 2 luchadores.\n  - El luchador con más velocidad comienza atacando.\n  - El daño se calcula restando el daño de ataque del\n    atacante menos la defensa del oponente.\n  - El oponente siempre tiene un 20% de posibilidad de\n    esquivar el ataque.\n  - Si la defensa es mayor que el ataque, recibe un 10%\n    del daño de ataque.\n  - Después de cada turno y ataque, el oponente pierde salud.\n  - La batalla finaliza cuando un luchador pierde toda su salud.\n  Torneo:\n  - Un torneo sólo es válido con un número de luchadores\n    potencia de 2.\n  - El torneo debe crear parejas al azar en cada ronda.\n  - Los luchadores se enfrentan en rondas eliminatorias.\n  - El ganador avanza a la siguiente ronda hasta que sólo\n    quede uno.\n  - Debes mostrar por consola todo lo que sucede en el torneo,\n    así como el ganador.\n*/\n\nconst fighters = [\n  {\n    name: \"Goku\",\n    attributes: { speed: 90, attack: 90, defense: 65 },\n    health: 100,\n  },\n  {\n    name: \"Vegeta\",\n    attributes: { speed: 85, attack: 85, defense: 70 },\n    health: 100,\n  },\n  {\n    name: \"Piccolo\",\n    attributes: { speed: 75, attack: 75, defense: 70 },\n    health: 100,\n  },\n  {\n    name: \"Gohan\",\n    attributes: { speed: 80, attack: 80, defense: 65 },\n    health: 100,\n  },\n  {\n    name: \"Trunks\",\n    attributes: { speed: 70, attack: 70, defense: 55 },\n    health: 100,\n  },\n  {\n    name: \"Goten\",\n    attributes: { speed: 70, attack: 65, defense: 60 },\n    health: 100,\n  },\n  {\n    name: \"Krillin\",\n    attributes: { speed: 60, attack: 60, defense: 55 },\n    health: 100,\n  },\n  {\n    name: \"Tien Shinhan\",\n    attributes: { speed: 65, attack: 60, defense: 60 },\n    health: 100,\n  },\n];\n\nif (Math.log2(fighters.length) % 1 === 0) {\n  let definePositions = new Set();\n\n  while(definePositions.size !== fighters.length) {\n    definePositions.add(Math.floor(Math.random() * fighters.length));\n  }\n\n  let positions = [...definePositions];\n\n  for (let roundIndex = 0; roundIndex <= positions.length; roundIndex++) {\n    let numberOfFights = positions.length / 2;\n    let fightCounter = 0;\n    let positionsBackup = [];\n    let fights = [];\n\n    for (let index = 0; index < numberOfFights; index++) {\n      fights.push(positions.slice(fightCounter, fightCounter + 2));\n\n      function combat(fighter1Health, fighter2Health) {\n        let fighter1 = fighters[fights[index][0]];\n        let fighter2 = fighters[fights[index][1]];\n        const fighter1Speed = fighter1.attributes.speed;\n        const fighter2Speed = fighter2.attributes.speed;\n\n        if (fighter2Speed > fighter1Speed) {\n          fighter1 = fighters[fights[index][1]];\n          fighter2 = fighters[fights[index][0]];\n        }\n\n        const fighter1Attack = Math.random() <= 0.20 ? 0 : fighter1.attributes.attack;\n        const fighter2Attack = Math.random() <= 0.20 ? 0 : fighter2.attributes.attack;\n        const fighter1Defense = fighter1.attributes.defense;\n        const fighter2Defense = fighter2.attributes.defense;\n\n        if (fighter1Health <= 0) {\n          console.log(`\\n✌🏼 ${fighter2.name} derrotó a ${fighter1.name}`);\n          positionsBackup.push(fighters.findIndex(x => x.name === fighter2.name));\n\n          return;\n        } else if (fighter2Health <= 0) {\n          console.log(`\\n✌🏼 ${fighter1.name} derrotó a ${fighter2.name}`);\n          positionsBackup.push(fighters.findIndex(x => x.name === fighter1.name));\n\n          return;\n        }\n\n        console.log(`\\n🏁 ${fighter1.name} (${fighter1Health}) vs ${fighter2.name} (${fighter2Health})`);\n        console.log(`💥 ${fighter1.name} ataca`);\n\n        if (fighter1Attack === 0) {\n          console.log(`🔴 ${fighter2.name} esquivó el ataque`);\n        } else {\n          if (fighter1Attack > fighter2Defense) {\n            fighter2Health = fighter2Health - (fighter1Attack - fighter2Defense);\n          } else {\n            fighter2Health = fighter2Health - ((fighter1Attack * 10) / 100);\n          }\n        }\n\n        console.log(`💥 ${fighter2.name} ataca`);\n\n        if (fighter2Attack === 0) {\n          console.log(`🔴 ${fighter1.name} esquivó el ataque`);\n        } else {\n          if (fighter2Attack > fighter1Defense) {\n            fighter1Health = fighter1Health - (fighter2Attack - fighter1Defense);\n          } else {\n            fighter1Health = fighter1Health - ((fighter2Attack * 10) / 100);\n          }\n        }\n\n        return combat(fighter1Health, fighter2Health);\n      }\n      \n      combat(100, 100);\n\n      fightCounter = fightCounter + 2;\n\n      console.log('----------------------------------');\n    }\n\n    positions = [...positionsBackup];\n\n    console.log('--------- FINAL DE RONDA ---------');\n\n    if (positions.length === 1) {\n      console.log(`\\n¡${fighters[positions[0]].name} es el campeón! 🏆`);\n    }\n  }\n} else {\n  console.log('El torneo no puede llevarse a cabo porque no hay participantes suficientes.');\n}\n"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/javascript/didix16.js",
    "content": "/*\n * Autor: didix16\n * EJERCICIO:\n * ¡El último videojuego de Dragon Ball ya está aquí!\n * Se llama Dragon Ball: Sparking! ZERO.\n *\n * Simula un Torneo de Artes Marciales, al más puro estilo\n * de la saga, donde participarán diferentes luchadores, y el\n * sistema decidirá quién es el ganador.\n *\n * Luchadores:\n * - Nombre.\n * - Tres atributos: velocidad, ataque y defensa\n *   (con valores entre 0 a 100 que tú decidirás).\n * - Comienza cada batalla con 100 de salud.\n * Batalla:\n * - En cada batalla se enfrentan 2 luchadores.\n * - El luchador con más velocidad comienza atacando.\n * - El daño se calcula restando el daño de ataque del\n *   atacante menos la defensa del oponente.\n * - El oponente siempre tiene un 20% de posibilidad de\n *   esquivar el ataque.\n * - Si la defensa es mayor que el ataque, recibe un 10%\n *   del daño de ataque.\n * - Después de cada turno y ataque, el oponente pierde salud.\n * - La batalla finaliza cuando un luchador pierde toda su salud.\n * Torneo:\n * - Un torneo sólo es válido con un número de luchadores\n *   potencia de 2.\n * - El torneo debe crear parejas al azar en cada ronda.\n * - Los luchadores se enfrentan en rondas eliminatorias.\n * - El ganador avanza a la siguiente ronda hasta que sólo\n *   quede uno.\n * - Debes mostrar por consola todo lo que sucede en el torneo,\n *   así como el ganador.\n *  --------------\n *  NOTAS: Algunos retoques añadidos\n *  1. Asumo que cada vez que un luchado pasa de ronda, se le cura la vida\n *  2. Mecánica de crítico: Si el atacante tiene 70 o más de ataque, tiene un 20% de probabilidad de hacer un crítico, sino solo un 10%\n *  3. Los críticos hacen el doble de daño y si el defensor tiene más defensa que el ataque del atacante o son iguales, el crítico ignora la defensa\n *  4. Si el personaje tiene una velocidad de 70 o más, tendrá más probabilidad de esquivar el ataque (+10%) pero menos probabilidad de hacer un crítico (-5%)\n *  5. En caso de que el daño sea 0 o negativo, el daño será el 10% del ataque del atacante.\n *  6. Si un personaje tiene 0 de velocidad, no podrá esquivar los ataques pero tendrá superarmadura, haciendo que los golpes con daño positivo solo le quiten el 10% (min 1)\n *  7. Si un personaje tiene 100 de velocidad, será supersónico y tendrá un 50% de probabilidad de esquivar los ataques!!!\n *  8. Mecánica de ki y SPARKING! MODE. Los personajes tienen 50 de ki máximo (y pueden empezar con 20 o 30) y disponen de 3 ataques especiales que comsumen ki, el débil consume 20, el fuerte 40 y la definitiva 50.\n *  Los turnos deberán usarse para atacar o recuperar ki. Si un personaje se queda sin ki, no podrá usar ataques especiales y está obligado a recuperar ki.\n *  Cada personaje dipondrá de una velocidad de recuperación de ki (cantidad a recuperar entre 10 o 20 por turno) y una probabilidad de recuperar ki que dependerá de la cantidad de ki restante\n *  en su turno. La probabilidad de recuperar ki dependerá de la cantidad de recuperación de ki del personaje, a cuanta más cantidad menos probabilidad.\n *  La probabilidad de escoger recuperación en vez de ataque dependerá de la cantidad de ki restante. Para ello generaremos 2 tipos de curvas cúbicas a trozos (natural cubic spline) que aproximen la probabilidad:\n *      - una para los que recuperan 10 de ki por turno (Ki Recharge = 10)\n *      - otra para los que recuperan 20 de ki por turno (Ki Recharge = 20)\n *  Si un personaje tiene menos de 20 de ataque se considerará débil pero como bonificación para balancear un poco la cosa, sus ataques de ki débil tendrán un 20% más de daño y los fuertes un 50% más de daño además de tener 10% más de probabilidad de ignorar la defensa del defensor.\n *  Los ataques de ki no se calculan como los ataques normales, sino que tienen un daño base (atk+%) y una probabilidad de ignorar la defensa del defensor además de no tener críticos:\n *  Los ataques de ki débiles producen un daño equivalente al atk + 25% (+50% si personaje debil; min 2 daño) y tienen una probabilidad del 20% (30% si personaje debil) de ignorar el 80% de la defensa del defensor.\n *  Los ataques de ki fuertes producen un daño equivalente al atk + 50% (+100% si personaje debil; min 5 daño) y tienen una probabilidad del 40% (50% si personaje debil) de ignorar el 80% de la defensa del defensor.\n *  Los ataques de ki definitivos producen un daño equivalente al atk + 200% (+300% si personaje debil; min 10 daño) y tienen un 70% de probabilidad de ignorar el 100% de la defensa del defensor.\n *  Además, para realizar un ataque de ki definitivo, el personaje debe entrar en modo SPARKING!. Para ello, el personaje debe tener 50 de ki y la probabilidad de entrar en modo SPARKING! se calcula como:\n *     - 50% si el personaje no es considerado débil\n *     - 60% si el personaje es considerado débil\n *     - 65% + ((atk-70)/30)*20% si el personaje es considerado fuerte (70atk => 65%, 100atk => 85%)\n *  Entrar en modo SPARKING! consumirá un turno. En este modo, el personaje obtendrá:\n *     - +5% de probabilidad de crítico adicional\n *     - +10% de probabilidad de esquivar adicional\n *     - +10% de atk adicional\n *     - -20% de reducción defensa\n *     - posibilidad de realizar el ataque definitivo de ki\n *  Este modo consta de un contador especial de 50 unidades las cuales cuando llegue a 0, el personaje saldrá del modo SPARKING!\n *  Durante el modo SPARKING! el personaje consumirá contador SPARKING! según el ataque que realice:\n *     - 5 unidades por ataque físico\n *     - 20 unidades por ataque de ki débil\n *     - 40 unidades por ataque de ki fuerte\n *     - 50 unidades por ataque de ki definitivo (consume 50 de ki y sale del modo SPARKING!)\n *  Mientras el contador sea positivo, se podrá realizar cualquier combinación de ataque posible. Cuando el contador llegue a 0, el personaje saldrá del modo SPARKING!. Realizar un ataque definitivo de ki consumirá el contador y el ki del personaje.\n *  Para elegir entre ataque físico o de ki, dependerá de si tiene ki disponible (o contador SPARKING!) y si lo tiene entonces la probabilidad se calcula como:\n *     - Si modo SPARKING! activo\n *          - 10% para el ataque de ki débil\n *          - 20% para el ataque de ki fuerte\n *          - 10% para ataques físicos\n *          - 60% para ataque definitivo de ki\n *     - Si ki disponible >= 40\n *          - 15% para el ataque de ki débil\n *          - 25% para el ataque de ki fuerte\n *          - 60% para ataques físicos\n *     - Si ki disponible >= 20 y < 40\n *         - 25% para el ataque de ki débil\n *         - 75% para ataques físicos\n *    - Si ki disponible < 20\n *      -  100% para ataques físicos\n */\n\n// utils\nconst rand = Math.random;\nconst randInt = (min, max) => Math.floor(rand() * (max - min + 1) + min);\nconst randValuesFrom = (list) => list[randInt(0, list.length - 1)];\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst AttackType = {\n    PHYISICAL_ATK: 0,\n    KI_WEAK_ATK: 1,\n    KI_STRONG_ATK: 2,\n    KI_ULTIMATE_ATK: 3,\n    isPhysicalAtk: (atkType) => atkType === AttackType.PHYISICAL_ATK,\n    isKiWeakAtk: (atkType) => atkType === AttackType.KI_WEAK_ATK,\n    isKiStrongAtk: (atkType) => atkType === AttackType.KI_STRONG_ATK,\n    isKiUltimateAtk: (atkType) => atkType === AttackType.KI_ULTIMATE_ATK,\n};\n\nconst printAtack = (fighter1, fighter2, damage, evaded, isCrit, defenseIgnored) => {\n    if (!evaded)\n        console.log(\n            `${fighter1.name} ataca 🤜 a ${fighter2.name} y le hace ${damage} de daño 💔⬇️. ${\n                isCrit ? ' 💥💥 ¡UUH ESO HA SIDO UN CRÍTICO! 💥💥' : ''\n            }${defenseIgnored ? ' 💥🛡️ ¡UUH LE HA PUESTO TODA SU ENERGÍA Y HA ATRAVESADO LA DEFENSA! 🛡️💥' : ''}`\n        );\n    else console.log(`${fighter1.name} ataca 🤜 a ${fighter2.name} pero ${fighter2.name} esquiva el ataque! 🤸‍♂️💨`);\n};\n\nconst kiAtackTypeMsg = {\n    [AttackType.KI_WEAK_ATK]: 'un ataque de ki débil',\n    [AttackType.KI_STRONG_ATK]: 'un ataque de ki fuerte',\n    [AttackType.KI_ULTIMATE_ATK]: 'el ataque definitivo de ki',\n};\n\nconst printKiAtack = (fighter1, fighter2, damage, evaded, ignoreDefense, atkType) => {\n    const fighter1Name = fighter1.getName();\n    const fighter2Name = fighter2.getName();\n    const kiAtkIcon = `🫸〰️${AttackType.isKiUltimateAtk(atkType) ? '🧿' : ''}`;\n    if (!evaded)\n        console.log(\n            `${fighter1Name} ataca ${kiAtkIcon} a ${fighter2Name} con ${\n                kiAtackTypeMsg[atkType]\n            } y le hace ${damage} de daño 💔⬇️. ${ignoreDefense ? ' 💥💥 ¡UUH ESA ATAQUE HA HECHO MELLA! 💥💥' : ''}`\n        );\n    else\n        console.log(\n            `${fighter1Name} ataca ${kiAtkIcon} a ${fighter2Name} con ${kiAtackTypeMsg[atkType]} pero ${fighter2Name} esquiva el ataque! 🤸‍♂️💨`\n        );\n};\n\nconst printHealthAndKiOf = (fighter) => {\n    console.log(\n        `${fighter.getName()} tiene ${fighter.getHealth()} de vida ❤️ y ${\n            !fighter.isInSparkingMode()\n                ? fighter.getKi() + ' de ki ⚡'\n                : fighter.getSparkingGauge() + ' de SPARKING! MODE 🌟⚡'\n        }`\n    );\n};\n\n// some names and its usage\nconst names = {\n    Goku: 0,\n    Vegeta: 0,\n    Piccolo: 0,\n    Gohan: 0,\n    Krillin: 0,\n    Yamcha: 0,\n    Tien: 0,\n    Chiaotzu: 0,\n    'Master Roshi': 0,\n    Trunks: 0,\n    Goten: 0,\n    Pan: 0,\n    Frieza: 0,\n    Cell: 0,\n    'Majin Buu': 0,\n    Beerus: 0,\n    Whis: 0,\n    Jiren: 0,\n    Hit: 0,\n    Kale: 0,\n    Caulifla: 0,\n    Cabba: 0,\n    Broly: 0,\n    Zamasu: 0,\n    'Black Goku': 0,\n    Vegito: 0,\n    Gogeta: 0,\n    Kefla: 0,\n    Toppo: 0,\n    Dyspo: 0,\n    'Android 17': 0,\n    'Android 18': 0,\n    'Android 16': 0,\n    'Android 19': 0,\n    'Android 20': 0,\n    'Android 21': 0,\n};\n\n// some ki natural cubic spline functions\nconst rechargeProbabilities = {\n    10: (ki) =>\n        ki >= 0 && ki <= 10\n            ? -2.9508e-5 * ki ** 3 - 1.7049e-2 * ki + 1\n            : ki > 10 && ki <= 20\n            ? 4.7541e-5 * ki ** 3 - 2.3115e-3 * ki ** 2 + 6.0656e-3 * ki + 0.92295\n            : ki > 20 && ki <= 40\n            ? -3.6885e-6 * ki ** 3 + 7.623e-4 * ki ** 2 - 5.541e-2 * ki + 1.3328\n            : ki > 40 && ki <= 50\n            ? -1.0656e-5 * ki ** 3 + 1.5984e-3 * ki ** 2 - 8.8852e-2 * ki + 1.7787\n            : 0,\n    20: (ki) =>\n        ki >= 0 && ki <= 10\n            ? 1.1639e-4 * ki ** 3 - 7.163e-2 * ki + 1\n            : ki > 10 && ki <= 20\n            ? -1.3197e-4 * ki ** 3 + 7.4508e-3 * ki ** 2 - 1.4615e-1 * ki + 1.2484\n            : ki > 20 && ki <= 40\n            ? 1.4549e-5 * ki ** 3 - 1.3402e-3 * ki ** 2 + 2.9672e-2 * ki + 7.623e-2\n            : ki > 40 && ki <= 50\n            ? -1.3525e-5 * ki ** 3 + 2.0287e-3 * ki ** 2 - 1.0508e-1 * ki + 1.873\n            : 0,\n};\n\n// ki/sparking gauge amount to discharge by atk type\nconst dischargeKiAmountByType = {\n    [AttackType.PHYISICAL_ATK]: 5,\n    [AttackType.KI_WEAK_ATK]: 20,\n    [AttackType.KI_STRONG_ATK]: 40,\n    [AttackType.KI_ULTIMATE_ATK]: 50,\n};\n\n// class Fighter\nclass Fighter {\n    static MAX_KI = 50;\n    health = 100;\n    ki;\n    initialKi;\n    kiRechargeAmount = 10;\n    name;\n    atk;\n    def;\n    speed;\n    evasionProbability;\n    kiRechargeProbability = (ki) => 0;\n    sparkingGauge = 0;\n\n    constructor(name, atk, def, speed, ki = 20, kiRecharge = 10) {\n        this.name = name;\n        this.atk = atk;\n        this.def = def;\n        this.speed = speed;\n        this.ki = Math.max(0, Math.min(Fighter.MAX_KI, ki));\n        this.initialKi = ki;\n        this.evasionProbability = this.isSuperSonic() ? 0.5 : this.isFast() ? 0.3 : !this.hasSuperArmor() ? 0.2 : 0.0;\n        this.kiRechargeAmount = kiRecharge;\n        this.kiRechargeProbability = rechargeProbabilities[kiRecharge];\n    }\n\n    getName() {\n        return this.name;\n    }\n\n    getAtk() {\n        return !this.isInSparkingMode() ? this.atk : parseInt(this.atk * 1.1);\n    }\n\n    getDef() {\n        return !this.isInSparkingMode() ? this.def : parseInt(this.def * 0.8);\n    }\n\n    getSpeed() {\n        return this.speed;\n    }\n\n    getKiRechargeAmount() {\n        return this.kiRechargeAmount;\n    }\n\n    getHealth() {\n        return this.health;\n    }\n\n    getKi() {\n        return this.ki;\n    }\n\n    getSparkingGauge() {\n        return this.sparkingGauge;\n    }\n\n    isInSparkingMode() {\n        return this.sparkingGauge > 0;\n    }\n\n    enterInSparkingMode() {\n        if (this.ki === Fighter.MAX_KI) {\n            const sparkingProbability = this.isStrong()\n                ? 0.65 + ((this.atk - 70) / 30) * 0.2\n                : this.isWeak()\n                ? 0.6\n                : 0.5;\n            if (rand() < sparkingProbability) {\n                this.sparkingGauge = Fighter.MAX_KI;\n                return true;\n                console.log(`${this.name} entra en modo SPARKING! 🌟🔥`);\n            } else {\n                return false;\n            }\n        }\n        return false;\n    }\n\n    exitSparkingMode() {\n        this.sparkingGauge = 0;\n        return this;\n    }\n\n    dischargeSparkingGauge(amount) {\n        this.sparkingGauge = Math.max(0, this.sparkingGauge - amount);\n        return this;\n    }\n\n    // if true, the fighter will recharge ki, if false, the fighter will attack\n    hasToRechargeKi() {\n        return rand() < this.kiRechargeProbability(this.ki);\n    }\n\n    evade() {\n        return rand() < (!this.isInSparkingMode() ? this.evasionProbability : this.evasionProbability + 0.1);\n    }\n\n    useKiOrPhysicalAttack() {\n        const r = rand();\n\n        // check if the fighter is in sparking mode\n        if (this.isInSparkingMode()) {\n            // 10% for weak ki atk, 20% for strong ki atk, 10% for physical atk and 60% for ultimate ki atk\n            return r < 0.1\n                ? AttackType.KI_WEAK_ATK\n                : r < 0.3\n                ? AttackType.KI_STRONG_ATK\n                : r < 0.4\n                ? AttackType.PHYISICAL_ATK\n                : AttackType.KI_ULTIMATE_ATK;\n        }\n\n        if (this.ki >= 40) {\n            // 15% for weak ki atk, 25% for strong ki atk and 60% for physical atk\n            return r < 0.15 ? AttackType.KI_WEAK_ATK : r < 0.4 ? AttackType.KI_STRONG_ATK : AttackType.PHYISICAL_ATK;\n        } else if (this.ki >= 20) {\n            // 25% for weak ki atk and 75% for physical at\n            return r < 0.25 ? AttackType.KI_WEAK_ATK : AttackType.PHYISICAL_ATK;\n        } else {\n            return AttackType.PHYISICAL_ATK;\n        }\n    }\n\n    // return the damage and if the defense was ignored partially or totally\n    takeKiDamageFrom(fighter, kiType) {\n        let damage = 0;\n        let ignoreDefense = false;\n        let minDamage = 0;\n        let tempDef = this.getDef();\n        switch (kiType) {\n            case AttackType.KI_WEAK_ATK:\n                damage = parseInt(fighter.getAtk() * (fighter.isWeak() ? 1.5 : 1.25));\n                minDamage = 2;\n                tempDef = rand() < (fighter.isWeak() ? 0.3 : 0.2) ? parseInt(tempDef * 0.8) : tempDef;\n                break;\n            case AttackType.KI_STRONG_ATK:\n                damage = parseInt(fighter.getAtk() * (fighter.isWeak() ? 2 : 1.5));\n                minDamage = 5;\n                tempDef = rand() < (fighter.isWeak() ? 0.5 : 0.4) ? parseInt(tempDef * 0.8) : tempDef;\n                break;\n            case AttackType.KI_ULTIMATE_ATK:\n                damage = parseInt(fighter.getAtk() * (fighter.isWeak() ? 4 : 3));\n                minDamage = 10;\n                ignoreDefense = rand() < 0.7;\n                break;\n            default:\n                throw new Error('Invalid ki type');\n        }\n\n        if (!ignoreDefense) {\n            damage = damage - tempDef;\n        }\n\n        this.health -= damage = Math.max(minDamage, damage);\n        return [damage, ignoreDefense || this.getDef() !== tempDef];\n    }\n\n    takePhysicalDamageFrom(fighter) {\n        let damage = fighter.getAtk() - this.getDef();\n        let critProbability = (fighter.isStrong() ? 0.2 : 0.1) - (fighter.isFast() ? 0.05 : 0);\n        let defenseIgnored = false;\n        critProbability += fighter.isInSparkingMode() ? 0.05 : 0;\n\n        const isCrit = rand() < critProbability;\n        if (isCrit) {\n            // if the defender has more defense than the atk of the atacker or they are the same, the crit ignores the defense\n            if (damage <= 0) {\n                damage = fighter.getAtk() << 1; // double the damage (fighter atk) ignoring the defense\n                defenseIgnored = true;\n            } else {\n                damage <<= 1; // double the damage\n            }\n        }\n        // if the defender has more defense than the atk of the atacker or they are the same, the damage  is the 10% of the atk of the atacker\n        else if (damage <= 0) damage = parseInt(fighter.getAtk() * 0.1); // get the integer part;\n\n        // if the defender has super armor, the damage is reduced by 90% (min 1)\n        if (this.hasSuperArmor()) {\n            damage = Math.max(1, parseInt(damage * 0.1));\n        }\n\n        this.health -= damage;\n        return [damage, isCrit, defenseIgnored];\n    }\n\n    hasSuperArmor() {\n        return this.speed === 0;\n    }\n\n    isSuperSonic() {\n        return this.speed === 100;\n    }\n\n    isFast() {\n        return this.speed >= 70;\n    }\n\n    isStrong() {\n        return this.atk >= 70;\n    }\n\n    isWeak() {\n        return this.atk < 20;\n    }\n\n    isDead() {\n        return this.health <= 0;\n    }\n\n    heal() {\n        this.health = 100;\n        return this;\n    }\n\n    healKi() {\n        this.ki = this.initialKi;\n        return this;\n    }\n\n    dischargeKiAmount(amount) {\n        this.ki = Math.max(0, this.ki - amount);\n        return this;\n    }\n\n    rechargeKi() {\n        this.ki = Math.min(Fighter.MAX_KI, this.ki + this.kiRechargeAmount);\n        return this;\n    }\n}\n\n// Singleton Tournament\n/**\n * Usage:\n *  reset() -> reset the tournament after it ends. return the torunament object\n *  init(numOfFighters, timeInMsBetweenAttacks) -> start the tournament with numOfFighters and simulate the time between attacks and rounds if timeInMsBetweenAttacks is set\n *  return the winner of the tournament\n *  Example 1 (first time) with 8 fighters and no time between attacks:\n *  await Tournament.init(8);\n *  Example 2 (first time) with 8 fighters and 1.1s between attacks and rounds:\n *  await Tournament.init(8, 1100);\n *  Example 3 (reset the tournament) with 16 fighters and no time between attacks:\n *  await Tournament.reset().init(16);\n */\nconst Tournament = {\n    fighters: [],\n    rounds: 0,\n    winner: null,\n    timmer: null, // If set, use this to simulate the time between attacks and rounds\n    async generateFighters(n, timmerIsSet) {\n        // check if n is integer, is positive and max 2^10, its min 2 and is a power of 2\n        if (!Number.isInteger(n) || (n & (n - 1)) !== 0 || n < 2 || n > 1024) {\n            throw new Error(\n                'El torneo solo es válido con un número de luchadores potencia de 2,un mínimo de 2 luchadores y máximo de 1024'\n            );\n        }\n\n        const nameList = Object.keys(names);\n        const namesLength = nameList.length;\n\n        for (let i = 0; i < n; i++) {\n            const idx = randInt(0, namesLength - 1);\n            let name = nameList[idx];\n            // add #number to the name if it is repeated\n            names[name]++ && (name += `#${names[name]}`);\n            const atk = randInt(10, 100); // min 10 atk to make some damage\n            const def = randInt(0, 100);\n            const speed = randInt(0, 100);\n            const initialKi = randValuesFrom([20, 30]);\n            const rechargeAmount = randValuesFrom([10, 20]);\n            this.fighters.push(new Fighter(name, atk, def, speed, initialKi, rechargeAmount));\n            console.log(\n                `${name} se une al torneo con ataque: ${atk} 💪, defensa: ${def} 🛡️, velocidad: ${speed} 🪽, ki inicial: ${initialKi} ⚡ y ${rechargeAmount} de carga de ki ⬆️⚡ `,\n                speed === 0 ? '¡¡¡INCLUSO TIENE SUPER ARMADURA!!! 🧱' : '[no tiene super armadura]',\n                speed === 100 ? '¡¡¡ES SUPERSÓNICO, ESQUIVARÁ CASI TODO!!! 🏃‍♂️💨' : '[no es supersónico]'\n            );\n            timmerIsSet && (await sleep(250));\n        }\n        // sort the fighters by random\n        this.fighters.sort(() => randInt(-1, 1));\n\n        return this;\n    },\n\n    reset() {\n        this.fighters = [];\n        this.rounds = 0;\n        this.winner = null;\n        this.timmer = null;\n        return this;\n    },\n\n    async init(numOfFighters, timeInMsBetweenAttacks = 0) {\n        await this.generateFighters(numOfFighters, timeInMsBetweenAttacks > 0);\n        this.rounds = Math.log2(this.fighters.length);\n        this.timmer = timeInMsBetweenAttacks;\n        return await this.startAsync();\n    },\n\n    async startAsync() {\n        let winners = this.fighters;\n        for (let i = 0; i < this.rounds - 1; i++) {\n            console.log(`Ronda ${i + 1}`);\n            await sleep(this.timmer);\n            winners = await this.roundAsync(winners);\n        }\n\n        console.log(`Ronda final entre 🤜 ${winners[0].getName()} y ${winners[1].getName()} 🤛`);\n        winners = await this.roundAsync(winners, true);\n\n        this.winner = winners[0];\n        console.log(`El ganador es ${this.winner.getName()} 🎉`);\n        return this.winner;\n    },\n\n    async roundAsync(fighters, isFinal = false) {\n        let winners = [];\n        for (let i = 0; i < fighters.length; i += 2) {\n            const fighter1 = fighters[i];\n            const fighter2 = fighters[i + 1];\n            !isFinal &&\n                console.log(\n                    `Empieza la batalla #${(i >>> 1) + 1} 🤜 entre ${fighter1.getName()} y ${fighter2.getName()} 🤛!`\n                ) &&\n                (await sleep(this.timmer));\n            const winner = await this.battleAsync(fighter1, fighter2);\n            !isFinal && console.log(`${winner.getName()} avanza a la siguiente ronda 👏`) && (await sleep(this.timmer));\n            winners.push(winner);\n        }\n        return winners;\n    },\n\n    async battleAsync(fighter1, fighter2) {\n        let turn = fighter1.getSpeed() > fighter2.getSpeed() ? [fighter1, fighter2] : [fighter2, fighter1];\n        while (true) {\n            const atacker = turn[0];\n            const defender = turn[1];\n\n            // check if the atacker attacks or recharges ki\n            if (atacker.hasToRechargeKi()) {\n                atacker.rechargeKi();\n                console.log(\n                    `${atacker.getName()} recarga ki 🔄🧘 y recupera ${atacker.getKiRechargeAmount()} de ki ⚡⬆️. Ahora tiene ${atacker.getKi()} de ki ⚡`\n                );\n                await sleep(this.timmer);\n                turn = [defender, atacker];\n                continue;\n            }\n\n            // check if the atacker enters in sparking mode\n            const atackerInSparkingMode = atacker.isInSparkingMode();\n            if (!atackerInSparkingMode && atacker.enterInSparkingMode()) {\n                console.log(`${atacker.getName()} entra en modo SPARKING! 🌟🔥. La cosa se pone seria ⚠️`);\n                await sleep(this.timmer);\n                turn = [defender, atacker];\n                continue;\n            }\n\n            // atacker attacks\n            // check if the atacker uses ki or physical attack\n            const atkType = atacker.useKiOrPhysicalAttack();\n\n            // check if the defender evades the attack\n            const evaded = defender.evade();\n            let damage = 0;\n\n            // if the atacker uses ki, the defender takes ki damage\n            if (!AttackType.isPhysicalAtk(atkType)) {\n                let ignoreDefense = false;\n\n                if (!evaded) [damage, ignoreDefense] = defender.takeKiDamageFrom(atacker, atkType);\n                atackerInSparkingMode\n                    ? atacker.dischargeSparkingGauge(dischargeKiAmountByType[atkType]) &&\n                      AttackType.isKiUltimateAtk(atkType) &&\n                      atacker.dischargeKiAmount(dischargeKiAmountByType[atkType])\n                    : atacker.dischargeKiAmount(dischargeKiAmountByType[atkType]);\n\n                printKiAtack(atacker, defender, damage, evaded, ignoreDefense, atkType);\n                if (defender.isDead()) {\n                    console.log(`${defender.getName()} ha muerto 💀`);\n                    atacker.heal().healKi().exitSparkingMode();\n                    await sleep(this.timmer);\n                    return atacker;\n                } else {\n                    // print if the atacker leaves the sparking mode\n                    const atackerLeavesSparkingMode = atackerInSparkingMode && !atacker.isInSparkingMode();\n                    atackerLeavesSparkingMode && console.log(`${atacker.getName()} sale del modo SPARKING! 🌟🔥`);\n\n                    printHealthAndKiOf(atacker);\n                    printHealthAndKiOf(defender);\n\n                    await sleep(this.timmer);\n                }\n                turn = [defender, atacker];\n                continue;\n            }\n\n            let isCrit = false;\n            let defenseIgnored = false;\n\n            if (!evaded) [damage, isCrit, defenseIgnored] = defender.takePhysicalDamageFrom(atacker);\n            atackerInSparkingMode && atacker.dischargeSparkingGauge(dischargeKiAmountByType[AttackType.PHYISICAL_ATK]);\n\n            printAtack(atacker, defender, damage, evaded, isCrit, defenseIgnored);\n\n            if (defender.isDead()) {\n                console.log(`${defender.getName()} ha muerto 💀`);\n                atacker.heal().healKi().exitSparkingMode();\n                await sleep(this.timmer);\n                return atacker;\n            } else {\n                // print if the atacker leaves the sparking mode\n                const atackerLeavesSparkingMode = atackerInSparkingMode && !atacker.isInSparkingMode();\n                atackerLeavesSparkingMode && console.log(`${atacker.getName()} sale del modo SPARKING! 🌟🔥`);\n\n                printHealthAndKiOf(atacker);\n                printHealthAndKiOf(defender);\n\n                await sleep(this.timmer);\n            }\n            turn = [defender, atacker];\n            await sleep(this.timmer);\n        }\n    },\n};\n\n// Versión síncrona  con 8 luchadores sin simulación de tiempo\n//await Tournament.init(8);\n// Versión asíncrona con 8 luchadores y simulación de tiempo entre ataques y rondas\nawait Tournament.reset().init(8, 1100);\n"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/javascript/duendeintemporal.js",
    "content": "//42 - TORNEO DRAGON BALL\n/*\n * EJERCICIO:\n * ¡El último videojuego de Dragon Ball ya está aquí!\n * Se llama Dragon Ball: Sparking! ZERO.\n *\n * Simula un Torneo de Artes Marciales, al más puro estilo\n * de la saga, donde participarán diferentes luchadores, y el\n * sistema decidirá quién es el ganador.\n *\n * Luchadores:\n * - Nombre.\n * - Tres atributos: velocidad, ataque y defensa\n *   (con valores entre 0 a 100 que tú decidirás).\n * - Comienza cada batalla con 100 de salud.\n * Batalla:\n * - En cada batalla se enfrentan 2 luchadores.\n * - El luchador con más velocidad comienza atacando.\n * - El daño se calcula restando el daño de ataque del\n *   atacante menos la defensa del oponente.\n * - El oponente siempre tiene un 20% de posibilidad de\n *   esquivar el ataque.\n * - Si la defensa es mayor que el ataque, recibe un 10%\n *   del daño de ataque.\n * - Después de cada turno y ataque, el oponente pierde salud.\n * - La batalla finaliza cuando un luchador pierde toda su salud.\n * Torneo:\n * - Un torneo sólo es válido con un número de luchadores\n *   potencia de 2.\n * - El torneo debe crear parejas al azar en cada ronda.\n * - Los luchadores se enfrentan en rondas eliminatorias.\n * - El ganador avanza a la siguiente ronda hasta que sólo\n *   quede uno.\n * - Debes mostrar por consola todo lo que sucede en el torneo,\n *   así como el ganador.\n */\n\n//We use https://sigmawire.net/image-to-url-converter service to include image in our javascript code\n\nclass Fighter {\n    constructor(id, name, speed, attack, defense) {\n        this.id = id;\n        this.name = name;\n        this.speed = speed;\n        this.attack = attack;\n        this.defense = defense;\n        this.health = 100; // Each fighter starts with 100 health\n    }\n\n    calculateDamage(opponent) {\n        let damage = Math.max(this.attack - opponent.defense, 0); // No negative damage\n\n        // Check if the opponent dodges the attack\n        if (Math.random() < 0.2) { // 20% chance to dodge\n            return 0; // No damage dealt\n        }\n\n        // If the opponent's defense is greater than the attack, reduce damage\n        if (opponent.defense > this.attack) {\n            damage *= 0.1; // 10% of the attack damage\n        }\n\n        return Math.floor(damage); // Return the damage as an integer\n    }\n}\n\n\nclass Battle {\n    constructor(fighter1, fighter2) {\n        this.fighter1 = fighter1;\n        this.fighter2 = fighter2;\n        this.attacker = fighter1.speed >= fighter2.speed ? fighter1 : fighter2;\n        this.defender = this.attacker === fighter1 ? fighter2 : fighter1;\n    }\n    winner(winFighter) {\n        let fighter = winFighter;\n        let element = document.querySelectorAll('.contrincant')[fighter.id - 1];\n\n        if (element.classList.contains('loser')) {\n            element.classList.remove('loser');\n        }\n\n        element.classList.add('winner');\n    }\n\n\n    loser(losFighter) {\n        let fighter = losFighter;\n        let element = document.querySelectorAll('.contrincant')[fighter.id - 1];\n\n        if (element.classList.contains('winner')) {\n            element.classList.remove('winner');\n        }\n\n        element.classList.add('loser');\n    }\n\n    async start() {\n        while (this.fighter1.health > 0 && this.fighter2.health > 0) {\n            const damage = this.attacker.calculateDamage(this.defender);\n\n            // Ensure a minimum level of damage\n            const minDamage = 10;\n            const actualDamage = Math.max(minDamage, damage);\n\n            this.defender.health -= actualDamage;\n\n            // Log the attack and damage\n            if (actualDamage === minDamage) {\n                logMessage(`${this.attacker.name}'s attack was partially blocked by ${this.defender.name}, dealing ${actualDamage} damage.`);\n            } else {\n                logMessage(`${this.attacker.name} attacks ${this.defender.name} for ${actualDamage} damage.`);\n            }\n            logMessage(`${this.defender.name} has ${this.defender.health} health left.`);\n\n            // Swap roles for the next turn\n            [this.attacker, this.defender] = [this.defender, this.attacker];\n\n            // Introduce a delay between attacks\n            await new Promise(resolve => setTimeout(resolve, 500));\n        }\n\n        const winner = this.fighter1.health > 0 ? this.fighter1 : this.fighter2;\n        logMessage(`${winner.name} wins the battle!`);\n        const winningFighter = this.fighter1.health > 0 ? this.fighter1 : this.fighter2;\n        const losingFighter = winningFighter === this.fighter1 ? this.fighter2 : this.fighter1;\n\n        // Add Winner and Loser class to fighter containers respectibily\n            this.winner(winningFighter);\n            this.loser(losingFighter);\n\n        return winner;\n    }\n}\n\nclass Tournament {\n    constructor(fighters) {\n        if (!this.isPowerOfTwo(fighters.length)) {\n            throw new Error(\"Number of fighters must be a power of 2.\");\n        }\n        this.fighters = fighters;\n    }\n\n    isPowerOfTwo(n) {\n        return (n & (n - 1)) === 0 && n > 0; // Check if n is a power of two\n    }\n\n    async start() {\n        logMessage(\"Starting the tournament...\");\n        let round = 1;\n\n        while (this.fighters.length > 1) {\n            logMessage(`\\n--- Round ${round} ---`);\n\n            const winners = [];\n            for (let i = 0; i < this.fighters.length; i += 2) {\n                const battle = new Battle(this.fighters[i], this.fighters[i + 1]);\n                const winner = await battle.start();\n                winners.push(winner);\n            }\n\n            logMessage(\"\\nWinners of Round \" + round + \":\");\n            winners.forEach(fighter => {\n                logMessage(\"- \" + fighter.name);\n            });\n\n            this.fighters = winners; // Update fighters for the next round\n            round++;\n        }\n\n        logMessage(`\\nThe champion of the tournament is ${this.fighters[0].name}!`);\n    }\n}\n\n\nconst fighters = [\n    new Fighter(1, 'Goku', 95, 80, 50),\n    new Fighter(2, 'Vegeta', 90, 85, 45),\n    new Fighter(3, 'Gohan', 85, 75, 55),\n    new Fighter(4, 'Piccolo', 80, 70, 60),\n    new Fighter(5, 'Frieza', 88, 90, 40),\n    new Fighter(6, 'Cell', 85, 80, 50),\n    new Fighter(7, 'Majin Buu', 70, 60, 70),\n    new Fighter(8, 'Trunks', 75, 65, 65)\n];\n\n// DOM Manipulation\nconst styles = `\n    body {\n        background: #000;\n        display: flex;\n        justify-content: center;\n        align-items: center;\n        transition: background .5s ease;\n        margin: 0;\n        padding: 0;\n    }\n\n    .winner{\n        display: flex;\n        justify-content: center;\n        align-items: center;\n        opacity: 1;\n        transform: scale(1.1);\n        font-weight: 600;\n    }\n    .winner::before{\n        content: 'WINNER';\n        color: rgba(0,255,0,0.4);\n    }\n\n    .loser{\n        display: flex;\n        justify-content: center;\n        align-items: center;\n        opacity: 0.5;\n        font-weight: 600;\n    }\n\n    .loser::after{\n        content: 'LOSER';\n        color: rgba(255,0,0,0.7);\n    }\n    \n    .contrincants_wrapper {\n        margin-top: 20px;\n        display: flex;\n        justify-content: center;\n        align-items: center;\n        flex-flow: row wrap;\n        width: 95vw;\n        gap: 10px;\n    }\n\n    .contrincant {\n        width: 200px;\n        height: 200px;\n        border: 1px solid #fff outset;\n        object-fit: cover;\n        object-position: center center;\n        flex: 0 0 70px;\n        background-size: cover;\n        background-position: center;\n    }\n\n    .log_container {\n        background: rgba(0, 0, 0, 0.7);\n        padding: 10px;\n        border-radius: 5px;\n        max-height: 200px;\n        overflow-y: auto;\n        z-index: 1;\n        border: 1px solid #fff;\n        color: #fff;\n        margin-top: 20px;\n        width: 100%;\n        text-align: center;\n    }\n`;\n\n// Create a <style> element and append the styles\nlet styleSheet = document.createElement(\"style\");\nstyleSheet.type = \"text/css\";\nstyleSheet.innerText = styles;\ndocument.head.appendChild(styleSheet);\n\n// Create the combatants' wrapper\nlet div_wrapper = document.createElement('div');\ndiv_wrapper.classList.add('contrincants_wrapper');\n\n// Create a DocumentFragment to batch updates\nlet fragment = document.createDocumentFragment();\n\n// Create and append combatants to the fragment\nfor (let i = 0; i < fighters.length; i++) {\n    let div = document.createElement('div');\n    div.classList.add('contrincant');\n    div.style.backgroundImage = `url(https://i.imgur.com/${['vDUO50X', 'fDitnqa', 'XHhWd32', 'yea6HcH', 'BTaQ8g4', 'LACYE3s', 'QIUnWuQ', 'SHXxvjC'][i]}.jpeg)`;\n    fragment.appendChild(div);\n}\n\n// Append the fragment to the wrapper\ndiv_wrapper.appendChild(fragment);\n\n// Create the log container\nlet logContainer = document.createElement('div');\nlogContainer.classList.add('log_container');\ndiv_wrapper.appendChild(logContainer);\n\n// Append the wrapper to the body\ndocument.body.appendChild(div_wrapper);\n\n// Function to log messages to the log container\nfunction logMessage(message) {\n    const logEntry = document.createElement('div');\n    logEntry.textContent = message;\n    logContainer.appendChild(logEntry);\n    logContainer.scrollTop = logContainer.scrollHeight; // Auto-scroll to the bottom\n}\n\n// Override console.log to also log to the log container\nconsole.log = (function(originalLog) {\n    return function(...args) {\n        originalLog.apply(console, args); // Call the original console.log\n        logMessage(args.join(' ')); // Log to the log container\n    };\n})(console.log);\n\n// Start the tournament\nconst tournament = new Tournament(fighters);\ntournament.start();\n"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/javascript/hectorio23.js",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\nclass Fighter {\n    constructor(name, speed, attack, defense) {\n        this.name = name;\n        this.speed = speed;\n        this.attack = attack;\n        this.defense = defense;\n        this.health = 100;\n    }\n\n    takeDamage(attacker) {\n        // Determinar si esquiva\n        if (Math.random() < 0.2) {\n            console.log(`${this.name} esquivó el ataque de ${attacker.name}!`);\n            return;\n        }\n\n        let damage = Math.max(0, attacker.attack - this.defense);\n        if (this.defense > attacker.attack) {\n            damage *= 0.1; // Recibe solo el 10% del daño\n        }\n        this.health -= damage;\n        console.log(`${this.name} recibió ${damage.toFixed(2)} puntos de daño de ${attacker.name}. Salud restante: ${this.health.toFixed(2)}`);\n    }\n}\n\nfunction battle(fighter1, fighter2) {\n    console.log(`¡Comienza la batalla entre ${fighter1.name} y ${fighter2.name}!`);\n    let [attacker, defender] = fighter1.speed >= fighter2.speed ? [fighter1, fighter2] : [fighter2, fighter1];\n\n    while (fighter1.health > 0 && fighter2.health > 0) {\n        defender.takeDamage(attacker);\n        [attacker, defender] = [defender, attacker]; // Cambiar roles\n    }\n\n    const winner = fighter1.health > 0 ? fighter1 : fighter2;\n    console.log(`¡${winner.name} gana la batalla!\\n`);\n    return winner;\n}\n\nfunction tournament(fighters) {\n    if ((fighters.length & (fighters.length - 1)) !== 0) {\n        throw new Error(\"El número de luchadores debe ser potencia de 2.\");\n    }\n\n    let round = 1;\n    while (fighters.length > 1) {\n        console.log(`--- Ronda ${round} ---`);\n        fighters.sort(() => Math.random() - 0.5); // Barajar luchadores\n\n        const nextRound = [];\n        for (let i = 0; i < fighters.length; i += 2) {\n            const winner = battle(fighters[i], fighters[i + 1]);\n            nextRound.push(winner);\n        }\n        fighters = nextRound;\n        round++;\n    }\n\n    console.log(`¡El ganador del torneo es ${fighters[0].name}!`);\n}\n\n// Ejemplo de uso\nconst fighters = [\n    new Fighter(\"Goku\", 90, 95, 80),\n    new Fighter(\"Vegeta\", 85, 90, 85),\n    new Fighter(\"Piccolo\", 75, 80, 90),\n    new Fighter(\"Frieza\", 80, 85, 75),\n];\n\ntournament(fighters);\n"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n_______________________________________________________\n#42 TORNEO DRAGON BALL\n-------------------------------------------------------\n* EJERCICIO:\n * ¡El último videojuego de Dragon Ball ya está aquí!\n * Se llama Dragon Ball: Sparking! ZERO.\n *\n * Simula un Torneo de Artes Marciales, al más puro estilo\n * de la saga, donde participarán diferentes luchadores, y el\n * sistema decidirá quién es el ganador.\n *\n * Luchadores:\n * - Nombre.\n * - Tres atributos: velocidad, ataque y defensa\n *   (con valores entre 0 a 100 que tú decidirás).\n * - Comienza cada batalla con 100 de salud.\n * Batalla:\n * - En cada batalla se enfrentan 2 luchadores.\n * - El luchador con más velocidad comienza atacando.\n * - El daño se calcula restando el daño de ataque del\n *   atacante menos la defensa del oponente.\n * - El oponente siempre tiene un 20% de posibilidad de\n *   esquivar el ataque.\n * - Si la defensa es mayor que el ataque, recibe un 10%\n *   del daño de ataque.\n * - Después de cada turno y ataque, el oponente pierde salud.\n * - La batalla finaliza cuando un luchador pierde toda su salud.\n * Torneo:\n * - Un torneo sólo es válido con un número de luchadores\n *   potencia de 2.\n * - El torneo debe crear parejas al azar en cada ronda.\n * - Los luchadores se enfrentan en rondas eliminatorias.\n * - El ganador avanza a la siguiente ronda hasta que sólo\n *   quede uno.\n * - Debes mostrar por consola todo lo que sucede en el torneo,\n *   así como el ganador.\n */\n// ________________________________________________________\nconst Fighter = class {\n    constructor(name, speed, attack, defense) {\n        this._name = name;\n        this._speed = speed;\n        this._attack = attack;\n        this._defense = defense;\n        this._health = 100;\n    }\n\n    executeAttack(opponent) {\n        console.log(`'${this._name}' ataca a '${opponent._name}'`);\n        \n        let damage = 0;\n        if (opponent._defense >= this._attack) {\n            damage = this._attack * 0.1; // 10%\n        } else {\n            damage = this._attack - opponent._defense;\n        }\n\n        if (!opponent.activateDefense()) {\n            opponent._health -= damage;\n            console.log(`'${opponent._name}' ha recibido '${damage}' de daño`);\n            console.log(`Salud restante '${opponent._health}'\\n`);\n        } else {    \n            console.log(`'${opponent._name}' ha esquivado el ataque.\\n`);\n        }\n    }\n    \n    activateDefense() {\n        return Math.random() <= 0.2;  // 20%\n    }\n}\n\nclass Battle {\n    constructor(fighter1, fighter2) {\n        this._fighter1 = fighter1;\n        this._fighter2 = fighter2;\n        console.log(`__'${this._fighter1._name} VS '${this._fighter2._name}'__\\n`);\n    }\n\n    _combat(fighterA, fighterB) {\n        while (true) {\n            fighterA.executeAttack(fighterB);\n            if (fighterB._health <= 0) {\n                console.log(`--> '${fighterA._name}' gana la batalla.__\\n`);\n                return fighterA;\n            }\n\n            fighterB.executeAttack(fighterA);\n            if (fighterA._health <= 0) {\n                console.log(`--> '${fighterB._name}' gana la batalla.\\n`);\n                return fighterB;\n            }\n        }\n    }\n\n    start() {\n        if (this._fighter1._speed > this._fighter2._speed) {\n            return this._combat(this._fighter1, this._fighter2);\n        } else {\n            return this._combat(this._fighter2, this._fighter1);\n        }\n    }\n}\n\nclass Tournament {\n    constructor(fighter, battle, fighters) {\n        this._fighter = fighter;\n        this._battle = battle;\n        this._fighters = fighters;\n        this._isValidTournament = this._isPowerOf2();\n    }\n\n    _isPowerOf2() {\n        const n = Object.keys(this._fighters).length;\n        if (n <= 1) return false;\n        return Number.isInteger(Math.log2(n));\n    }\n\n    _getRandomPairs() {\n        const fightersArray = Object.entries(this._fighters);\n        const randomIndexes = Array.from({ length: 2 }, () => \n            Math.floor(Math.random() * fightersArray.length)\n        );\n\n        const [name1, data1] = fightersArray[randomIndexes[0]];\n        const [name2, data2] = fightersArray[randomIndexes[1]];\n\n        const fighter1 = new this._fighter(name1, data1.speed, data1.attack, data1.defense);\n        const fighter2 = new this._fighter(name2, data2.speed, data2.attack, data2.defense);\n\n        delete this._fighters[name1];\n        delete this._fighters[name2];\n\n        return [fighter1, fighter2];\n    }\n\n    startRounds(roundNum = 1) {\n        if (roundNum === 1 && !this._isValidTournament) {\n            console.log(\"El número de luchadores debe ser una potencia de 2.\");\n            return;\n        }\n\n        console.log(`\\n__Ronda #${roundNum}__`);\n        const nextRound = {};\n\n        while (true) {\n            const [fighter1, fighter2] = this._getRandomPairs();\n            const battle = new this._battle(fighter1, fighter2);\n            const winner = battle.start();\n\n            nextRound[winner._name] = {\n                speed: winner._speed,\n                attack: winner._attack,\n                defense: winner._defense\n            };\n\n            if (Object.keys(this._fighters).length === 0 && Object.keys(nextRound).length > 1) {\n                this._fighters = nextRound;\n                this.startRounds(roundNum + 1);\n                break;\n            }\n            \n            if (Object.keys(this._fighters).length === 0 && Object.keys(nextRound).length === 1) {\n                console.log(`\\n--> El vencedor del torneo es '${winner._name}'.`);\n                break;\n            }\n        }\n    }\n}\n\nconst FIGHTERS = {\n    \"Goku\": { speed: 100, attack: 95, defense: 85 },\n    \"Vegeta\": { speed: 95, attack: 90, defense: 90 },\n    \"Gohan\": { speed: 85, attack: 95, defense: 85 },\n    \"Freezer\": { speed: 90, attack: 90, defense: 90 },\n    \"Piccolo\": { speed: 90, attack: 85, defense: 90 },\n    \"Krillin\": { speed: 85, attack: 75, defense: 75 },\n    \"Cell\": { speed: 90, attack: 95, defense: 85 },\n    \"Majin Buu\": { speed: 80, attack: 85, defense: 95 }\n};\n\nconsole.log(\"Simulación del Torneo de Artes Marciales\");\nconst tournament = new Tournament(Fighter, Battle, { ...FIGHTERS });\ntournament.startRounds();\n"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/javascript/lioarce01.js",
    "content": "//======= GLOBAL CONSTANTS =======//\nconst EVADE_CHANCE = 0.2;\nconst HEALTH = 100;\nconst FIGHTERS = [\n  {\n    name: \"Goku\",\n    speed: 90,\n    attack_damage: 100,\n    defense: 80,\n  },\n  {\n    name: \"Vegeta\",\n    speed: 85,\n    attack_damage: 95,\n    defense: 85,\n  },\n  {\n    name: \"Piccolo\",\n    speed: 80,\n    attack_damage: 85,\n    defense: 90,\n  },\n  {\n    name: \"Gohan\",\n    speed: 88,\n    attack_damage: 90,\n    defense: 86,\n  },\n  {\n    name: \"Frieza\",\n    speed: 95,\n    attack_damage: 98,\n    defense: 70,\n  },\n  {\n    name: \"Cell\",\n    speed: 90,\n    attack_damage: 95,\n    defense: 75,\n  },\n  {\n    name: \"Buu\",\n    speed: 70,\n    attack_damage: 92,\n    defense: 100,\n  },\n  {\n    name: \"Broly\",\n    speed: 80,\n    attack_damage: 110,\n    defense: 90,\n  },\n  {\n    name: \"Trunks\",\n    speed: 82,\n    attack_damage: 88,\n    defense: 80,\n  },\n  {\n    name: \"Android 18\",\n    speed: 84,\n    attack_damage: 89,\n    defense: 82,\n  },\n  {\n    name: \"Tien Shinhan\",\n    speed: 75,\n    attack_damage: 80,\n    defense: 85,\n  },\n  {\n    name: \"Krillin\",\n    speed: 78,\n    attack_damage: 75,\n    defense: 78,\n  },\n  {\n    name: \"Yamcha\",\n    speed: 77,\n    attack_damage: 73,\n    defense: 75,\n  },\n  {\n    name: \"Goten\",\n    speed: 85,\n    attack_damage: 80,\n    defense: 70,\n  },\n  {\n    name: \"Pan\",\n    speed: 88,\n    attack_damage: 82,\n    defense: 72,\n  },\n  {\n    name: \"Raditz\",\n    speed: 80,\n    attack_damage: 85,\n    defense: 78,\n  },\n];\n\n//===============================//\n\nclass Fighter {\n  constructor(name, speed, attack_damage, defense) {\n    this.name = name;\n    this.speed = this.attributeCheck(speed, 100);\n    this.attack_damage = this.attributeCheck(attack_damage, 100);\n    this.defense = this.attributeCheck(defense, 100);\n    this.health = HEALTH;\n  }\n\n  attributeCheck(value, max) {\n    if (value < 0) {\n      console.warn(`Attribute cannot be negative: ${attribute}. Setting to 0`);\n      return 0;\n    }\n\n    if (value > max) {\n      console.warn(`Attribute exceeds maximum of ${max}. Setting to ${max}`);\n      return max;\n    }\n\n    return value;\n  }\n\n  resetHealth() {\n    this.health = HEALTH;\n  }\n\n  attack(defender) {\n    const evade = Math.random();\n\n    if (!defender.isAlive()) {\n      console.log(`${defender.name} has lost all of its health`);\n      return;\n    }\n\n    if (evade < EVADE_CHANCE) {\n      console.log(`${defender.name} has evaded the attack`);\n      return;\n    }\n\n    let damage;\n\n    if (defender.defense >= this.attack_damage) {\n      damage = this.attack_damage * 0.1;\n      console.log(\n        `${this.name} has dealt ${damage.toFixed()} damage to ${defender.name}`\n      );\n    } else {\n      damage = this.attack_damage - defender.defense;\n    }\n\n    defender.health = Math.max(defender.health - damage, 0);\n\n    console.log(\n      `${this.name} has dealt ${damage.toFixed()} damage to ${defender.name}, ${\n        defender.name\n      } has ${defender.health.toFixed()} health left`\n    );\n  }\n\n  isAlive() {\n    return this.health > 0;\n  }\n\n  showInfo() {\n    console.log(`Name: ${this.name}`);\n    console.log(`Speed: ${this.speed}`);\n    console.log(`Attack: ${this.attack_damage}`);\n    console.log(`Defense: ${this.defense}`);\n    console.log(`Health: ${this.health.toFixed()}`);\n  }\n}\n\nclass Tournament {\n  constructor(fighters) {\n    if (fighters.length < 4 || fighters.length % 2 !== 0) {\n      throw new Error(\n        \"Teams must have at least four fighters and an even number of fighters\"\n      );\n    }\n\n    this.teamA = fighters\n      .slice(0, fighters.length / 2)\n      .map((f) => new Fighter(f.name, f.speed, f.attack_damage, f.defense));\n    this.teamB = fighters\n      .slice(fighters.length / 2)\n      .map((f) => new Fighter(f.name, f.speed, f.attack_damage, f.defense));\n  }\n\n  shuffleArray(array) {\n    for (let i = array.length - 1; i > 0; i--) {\n      const j = Math.floor(Math.random() * (i + 1));\n      [array[i], array[j]] = [array[j], array[i]];\n    }\n    return array;\n  }\n\n  start() {\n    console.log(\"\\n==== Tournament Begins ====\");\n\n    let winnerA = this.startKey(this.teamA, \"A\");\n    let winnerB = this.startKey(this.teamB, \"B\");\n\n    console.log(\n      `\\n${winnerA.name} and ${winnerB.name} resting for the final match`\n    );\n\n    winnerA.resetHealth();\n    winnerB.resetHealth();\n\n    this.finalMatch(winnerA, winnerB);\n  }\n\n  startKey(team, teamName) {\n    let round = 1;\n\n    this.shuffleArray(team);\n\n    while (team.length > 1) {\n      console.log(`=== Round ${round} of team ${teamName} ===`);\n\n      this.shuffleArray(team);\n\n      let nextRoundFighters = [];\n      for (let i = 0; i < team.length; i += 2) {\n        let fighter1 = team[i];\n        let fighter2 = team[i + 1];\n\n        console.log(`Battle between ${fighter1.name} and ${fighter2.name}`);\n        let winner = this.fight(fighter1, fighter2);\n        console.log(`${winner.name} WON THE BATTLE!`);\n        nextRoundFighters.push(winner);\n      }\n\n      team = nextRoundFighters;\n      round++;\n    }\n\n    console.log(`\\n==== Team ${teamName} Winner: ${team[0].name} ====`);\n\n    return team[0];\n  }\n\n  fight(fighter1, fighter2) {\n    let turn = 0;\n\n    while (fighter1.isAlive() && fighter2.isAlive()) {\n      if (turn % 2 === 0) {\n        fighter1.attack(fighter2);\n      } else {\n        fighter2.attack(fighter1);\n      }\n\n      turn++;\n    }\n\n    return fighter1.isAlive() ? fighter1 : fighter2;\n  }\n\n  finalMatch(winnerA, winnerB) {\n    console.log(\"\\n==== Grand Final ====\");\n    console.log(`\\n==== ${winnerA.name} vs ${winnerB.name} ====`);\n\n    let finalWinner = this.fight(winnerA, winnerB);\n    console.log(`\\n${finalWinner.name} WON THE TOURNAMENT!`);\n\n    console.log(`\\n==== WINNER STATS ====`);\n    finalWinner.showInfo();\n  }\n}\n\nlet tournament = new Tournament(FIGHTERS);\ntournament.start();\n"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/javascript/miguelex.js",
    "content": "const readline = require('readline').createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nclass Luchador {\n    constructor(nombre, velocidad, ataque, defensa) {\n        this.nombre = nombre;\n        this.velocidad = velocidad;\n        this.ataque = ataque;\n        this.defensa = defensa;\n        this.salud = 100;\n    }\n\n    esquivar() {\n        return Math.random() < 0.2;\n    }\n}\n\nfunction batalla(luchador1, luchador2) {\n    console.log(`¡Batalla entre ${luchador1.nombre} y ${luchador2.nombre}!`);\n    let atacante = luchador1.velocidad >= luchador2.velocidad ? luchador1 : luchador2;\n    let defensor = atacante === luchador1 ? luchador2 : luchador1;\n\n    while (luchador1.salud > 0 && luchador2.salud > 0) {\n        if (defensor.esquivar()) {\n            console.log(`${defensor.nombre} esquivó el ataque de ${atacante.nombre}!`);\n        } else {\n            let danio = atacante.ataque - defensor.defensa;\n            if (danio <= 0) {\n                danio = atacante.ataque * 0.1;\n            }\n            defensor.salud -= danio;\n            console.log(`${atacante.nombre} ataca a ${defensor.nombre} y causa ${danio.toFixed(2)} de daño. Salud restante de ${defensor.nombre}: ${defensor.salud}`);\n        }\n        [atacante, defensor] = [defensor, atacante];\n    }\n\n    let ganador = luchador1.salud > 0 ? luchador1 : luchador2;\n    console.log(`¡${ganador.nombre} es el ganador de la batalla!\\n`);\n    return ganador;\n}\n\nfunction leerEntrada(pregunta) {\n    return new Promise(resolve => readline.question(pregunta, respuesta => resolve(respuesta)));\n}\n\nasync function main() {\n    const luchadores = [];\n    const numLuchadores = parseInt(await leerEntrada(\"Ingrese el número de luchadores (debe ser una potencia de 2): \"));\n\n    if ((numLuchadores & (numLuchadores - 1)) !== 0 || numLuchadores <= 0) {\n        console.log(\"El número de luchadores debe ser una potencia de 2.\");\n        readline.close();\n        return;\n    }\n\n    for (let i = 0; i < numLuchadores; i++) {\n        const nombre = await leerEntrada(`Ingrese el nombre del luchador ${i + 1}: `);\n        const velocidad = parseInt(await leerEntrada(`Ingrese la velocidad de ${nombre} (0-100): `));\n        const ataque = parseInt(await leerEntrada(`Ingrese el ataque de ${nombre} (0-100): `));\n        const defensa = parseInt(await leerEntrada(`Ingrese la defensa de ${nombre} (0-100): `));\n\n        luchadores.push(new Luchador(nombre, velocidad, ataque, defensa));\n    }\n\n    console.log(\"¡Comienza el torneo de Dragon Ball: Sparking! ZERO!\\n\");\n    while (luchadores.length > 1) {\n        const ganadores = [];\n        luchadores.sort(() => Math.random() - 0.5);\n\n        for (let i = 0; i < luchadores.length; i += 2) {\n            const ganador = batalla(luchadores[i], luchadores[i + 1]);\n            ganadores.push(ganador);\n        }\n        luchadores.splice(0, luchadores.length, ...ganadores);\n    }\n\n    console.log(`¡El ganador del torneo es ${luchadores[0].nombre}!`);\n    readline.close();\n}\n\nmain();\n"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/javascript/pedamoci.js",
    "content": "import readline from \"readline\"\n\nconst EVADE_CHANCE = 0.2\nconst REDUCTOR_DAMAGE_FACTOR = 0.1\n\nconst COLORS = Object.freeze({\n  red: \"\\x1b[31m\",\n  green: \"\\x1b[32m\",\n  yellow: \"\\x1b[33m\",\n  cyan: \"\\x1b[34m\",\n  purple: \"\\x1b[35m\",\n  reset: \"\\x1b[0m\",\n})\n\nconst INITIAL_FIGHTERS = [\n  {name : \"Goku\", stats: {health: 100, attack: 94, defense: 92, speed: 95}},\n  {name : \"Vegeta\", stats: {health: 100, attack: 97, defense: 90, speed: 95}},\n  {name : \"Gohan\", stats: {health: 100, attack: 91, defense: 88, speed: 88}},\n  {name : \"Piccolo\", stats: {health: 100, attack: 84, defense: 89, speed: 85}},\n  {name : \"Freezer\", stats: {health: 100, attack: 94, defense: 85, speed: 92}},\n  {name : \"Cell\", stats: {health: 100, attack: 90, defense: 91, speed: 88}},\n  {name : \"Majin Buu\", stats: {health: 100, attack: 92, defense: 99, speed: 80}},\n  {name : \"Trunks of the Future\", stats: {health: 100, attack: 89, defense: 85, speed: 88}},\n  {name : \"Android 18\", stats: {health: 100, attack: 81, defense: 86, speed: 80}},\n  {name : \"Broly\", stats: {health: 100, attack: 100, defense: 95, speed: 85}},\n  {name : \"Jiren\", stats: {health: 100, attack: 99, defense: 96, speed: 98}},\n  {name : \"Hit\", stats: {health: 100, attack: 90, defense: 80, speed: 98}},\n  {name : \"Krillin\", stats: {health: 100, attack: 70, defense: 65, speed: 75}},\n  {name : \"Ten Shin Han\", stats: {health: 100, attack: 72, defense: 68, speed: 75}},\n  {name : \"Black Goku\", stats: {health: 100, attack: 93, defense: 87, speed: 92}}\n]\n\nfunction delay(ms) {\n  return new Promise(resolve => {\n    setTimeout(() => {\n      resolve()\n    }, ms);\n  })\n}\n\nclass Asks {\n  constructor() {\n    this.readline = readline.createInterface({\n      input: process.stdin,\n      output: process.stdout\n    })\n  }\n\n  #ask(question) {\n    return new Promise(resolve => {\n      this.readline.question(question, (answer) => resolve(answer))\n    })\n  }\n\n  close() {\n    this.readline.close()\n  }\n\n  async askLabel() {\n    const response = await this.#ask(COLORS.cyan + `Would you like to add a fighter?` + '\\n' + \"(Y/N): \" + COLORS.reset)\n    return response\n  }\n}\n\nconst asks = new Asks()\n\nclass Renderer {\n  static error(message) {\n    console.log(COLORS.red + \"Error: \" + message + COLORS.reset)\n  }\n\n  static success(message) {\n    console.log(COLORS.green + \"Success: \" + message + COLORS.reset)\n  }\n\n  static info(message) {\n    console.log(COLORS.purple + message + COLORS.reset)\n  }\n\n  static evade(name) {\n    console.log(`${COLORS.green}${name} evaded the attack${COLORS.reset}`)\n  }\n\n  static damage(name, damage) {\n    console.log(`🗡️   ${name} inflicted ${damage} points of damage`)\n  }\n\n  static round(num) {\n    console.log(COLORS.cyan + `--- Round ${num} ---` + COLORS.reset)\n  }\n\n  static status(fighterOneName, fighterOneHealth, fighterTwoName, fighterTwoHealth) {\n    console.log(`❤️   ${COLORS.red}${fighterOneName} health: ${fighterOneHealth}` + '\\n' +\n                `❤️   ${fighterTwoName} health: ${fighterTwoHealth}${COLORS.reset}` + '\\n')\n  }\n\n  static winFight(fighterName) {\n    console.log(COLORS.yellow + `WINNER ${fighterName}` + '\\n' + COLORS.reset)\n  }\n\n  static winTournament(fighterName) {\n    console.log(COLORS.green + `The winner of the torunament is ${fighterName}` + COLORS.reset)\n  }\n}\n\nclass Validator {\n  isExistingFighter(name, fighters) {\n    return fighters.some(fighter => fighter.name.toLowerCase() === name.toLowerCase())\n  }\n\n  isValidAttribute(attribute) {\n    if (typeof attribute !== \"number\" || attribute < 0 || attribute > 100) {\n      return false\n    }\n\n    return true\n  }\n\n  isValidName(name) {\n    if (typeof name !== \"string\") {\n      return false\n    }\n\n    return true\n  }\n\n  isValidFighter(name, attack, defense, speed, fighters) {\n    if (!this.isValidAttribute(attack)) {\n      const msg = \"The fighter's attack must be a number between 0 and 100\"\n      return {\n        valid: false,\n        message: msg\n      }\n    }\n\n    if (!this.isValidAttribute(defense)) {\n      const msg = \"The fighter's defense must be a number between 0 and 100\"\n      return {\n        valid: false,\n        message: msg\n      }\n    }\n\n    if (!this.isValidAttribute(speed)) {\n      const msg = \"The fighter's speed must be a number between 0 and 100\"\n      return {\n        valid: false,\n        message: msg\n      }\n    }\n\n    if (!this.isValidName(name)) {\n      const msg = \"The fighter's name must be a string\"\n      return {\n        valid: false,\n        message: msg\n      }\n    }\n\n    if (this.isExistingFighter(name, fighters)) {\n      const msg = \"Fighter already added to the tournament\"\n      return {\n        valid: false,\n        message: msg\n      }\n    }\n\n    const msg = \"The fighter was added\"\n    return {\n      valid: true,\n      message: msg\n    } \n  }\n\n  isValidNumberOfFighters(fighters) {\n    const num = fighters.length\n\n    if (num <= 1 || (num & (num - 1)) !== 0) {\n      const msg = `the tournament can't start with ${num} participants`\n      return {\n        valid: false,\n        message: msg\n      }\n    }\n    return {\n      valid: true\n    }\n  }\n}\n\nclass FightController {\n  calculateDamage(attack, defense) {\n    if (defense >= attack) {\n      let dmg = Math.round(attack * REDUCTOR_DAMAGE_FACTOR)\n      return dmg\n    }\n\n    return (attack - defense)\n  }\n\n  evade() {\n    return (Math.random() < EVADE_CHANCE)\n  }\n\n  checkFighterStart(fighterOne, fighterTwo){\n    if (fighterOne.stats.speed > fighterTwo.stats.speed){\n      return [fighterOne, fighterTwo]\n    } else if (fighterOne.stats.speed < fighterTwo.stats.speed){\n      return [fighterTwo, fighterOne]\n    } else if (Math.random() > 0.5) {\n      return [fighterOne, fighterTwo]\n    } else {\n      return [fighterTwo, fighterOne]\n    }\n  }\n\n  async fight(fighterOne, fighterTwo) {\n    let [attacker, defender] = this.checkFighterStart(fighterOne, fighterTwo)\n\n    for (let i = 0; attacker.stats.health > 0 ; i++) {\n      Renderer.round(i + 1)\n      if (this.evade()) {\n        Renderer.evade(defender.name)\n      } else {\n        const damage = this.calculateDamage(attacker.stats.attack, defender.stats.defense)\n        defender.stats.health = Math.max(0, defender.stats.health - damage)\n        Renderer.damage(attacker.name, damage)\n      }\n\n      (i % 2 === 0) ? Renderer.status(attacker.name, attacker.stats.health, defender.name, defender.stats.health)\n                    : Renderer.status(defender.name, defender.stats.health, attacker.name, attacker.stats.health)\n\n      await delay(500)\n\n      if (defender.stats.health < 1) {\n        attacker.stats.health = 100\n\n        Renderer.winFight(attacker.name)\n\n        await delay(1000)\n\n        return defender.name\n      } else {\n        [attacker, defender] = [defender, attacker]\n      }\n    }\n  }\n}\n\nclass TournamentController {\n  constructor(validator, fightController) {\n    this.participants = [...INITIAL_FIGHTERS]\n    this.validator = validator\n    this.fightController = fightController\n  }\n\n  addParticipant() {\n      const name = \"Android 17\"\n      const attack = 88\n      const defense = 92\n      const speed = 92\n\n      let result = this.validator.isValidFighter(name, attack, defense, speed, this.participants)\n\n      if (!result.valid) {\n        Renderer.error(result.msg)\n        return\n      }\n\n      this.participants.push({name, stats: {health: 100, attack, defense, speed}})\n      Renderer.success(result.msg)\n      return \n  }\n\n  getRandomFighter(fighters) {\n    const index = Math.floor(Math.random() * fighters.length)\n    const fighter = fighters[index]\n    fighters.splice(index, 1)\n    return fighter\n  }\n\n  async startTournament() {\n    Renderer.info(`current number of participants in the tournament: ${this.participants.length}`)\n\n    let response\n\n    do {\n      response = await asks.askLabel()\n\n      if (response.toLowerCase() === \"y\") {\n        this.addParticipant()\n      }\n    } while (response.toLowerCase() !== \"n\")\n\n    let result = this.validator.isValidNumberOfFighters(this.participants)\n    if (!result.valid) {\n      Renderer.error(result.message)\n      return this.startTournament()\n    }\n\n    while (this.participants.length > 1) {\n      let fighters = [...this.participants]\n      let rounds = fighters.length / 2\n\n      for (let i = 0; i < rounds; i++) {\n        const fighterOne = this.getRandomFighter(fighters)\n        const fighterTwo = this.getRandomFighter(fighters)\n\n        const loserName = await this.fightController.fight(fighterOne, fighterTwo)\n\n        this.participants = this.participants.filter(fighter => fighter.name !== loserName)\n      }\n\n      if (this.participants.length > 1) {\n        Renderer.info(`There are ${this.participants.length} fighters left in the tournament` + '\\n')\n      }\n\n      await delay(1500)\n    }\n\n    Renderer.winTournament(this.participants[0].name)\n\n    asks.close()\n  }\n}\n\nconst tournamentController = new TournamentController(new Validator(), new FightController())\ntournamentController.startTournament()"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/kotlin/blackriper.kt",
    "content": "import kotlinx.coroutines.CoroutineDispatcher\r\nimport kotlinx.coroutines.Dispatchers\r\nimport kotlinx.coroutines.asCoroutineDispatcher\r\nimport kotlinx.coroutines.async\r\nimport kotlinx.coroutines.coroutineScope\r\nimport kotlinx.coroutines.launch\r\nimport kotlinx.coroutines.runBlocking\r\nimport org.jetbrains.annotations.BlockingExecutor\r\nimport java.util.concurrent.Executors\r\nimport kotlin.math.atan\r\n\r\n// me gusta experimentar con conceptos en este caso concurrencia si eres muy nuevo puedes ignorar\r\n//las funciones suspend y solo ver la logica\r\n\r\n\r\ninterface ActionWarrior{\r\n    fun attackEnemy(): Int\r\n    fun dodgeAttack(): Boolean\r\n    fun getStatus(): String\r\n}\r\n\r\ninterface Tournament {\r\n    suspend fun tournament(warriors: List<WarriorZ>)\r\n}\r\n\r\n\r\n\r\ndata class Technique constructor(\r\n    var name:String=\"\",\r\n    var attack: Int=0\r\n)\r\n\r\ndata class WarriorZ constructor(\r\n    var name:String=\"\",\r\n    var speed: Int=0,\r\n    var defense: Int=0,\r\n    var health:Int=100,\r\n    var techniques: List<Technique> = emptyList()\r\n):ActionWarrior{\r\n    override fun attackEnemy(): Int {\r\n        val tech= techniques[(0..<techniques.size).random()]\r\n        println(\"El participante $name ha usado ${tech.name} para atacar\")\r\n        return tech.attack\r\n    }\r\n\r\n    override fun dodgeAttack(): Boolean= (0..100).random() < 20\r\n\r\n    override fun getStatus(): String = \" Warrior $name  health: ${if(health<0)0 else health}\"\r\n\r\n}\r\n\r\n// contruir objetos con dsl basico\r\nfun technique(block:Technique.()-> Unit):Technique= Technique().apply(block)\r\nfun warriorZ(block: WarriorZ.() -> Unit):WarriorZ=WarriorZ().apply(block)\r\n\r\n\r\nclass TekiachiBudokai:Tournament{\r\n    private suspend fun figthing(warrior1: WarriorZ, warrior2: WarriorZ): WarriorZ {\r\n        var attacker=if (warrior1.speed>warrior2.speed) warrior1 else warrior2\r\n        var defenser= if (attacker==warrior1) warrior2 else warrior1\r\n\r\n        while (warrior1.health>0 && warrior2.health>0){\r\n            attacker.attackEnemy().run {\r\n                val damage = if (!defenser.dodgeAttack()) maxOf(defenser.defense-this, 0) else 0\r\n                val finalDamage=if (defenser.defense > this) (this * 0.1).toInt() else damage\r\n                defenser.health -= finalDamage\r\n                println(\"El partipante ${defenser.name} ha recibido ${finalDamage} de daño\")\r\n            }\r\n            println(attacker.getStatus())\r\n            println(defenser.getStatus())\r\n\r\n            attacker=defenser.also {\r\n                defenser=attacker\r\n            }\r\n        }\r\n        return if (warrior1.health>0) warrior1 else warrior2\r\n    }\r\n\r\n    override suspend fun tournament(warriors: List<WarriorZ>): Unit= coroutineScope {\r\n        if (warriors.size%2!=0){\r\n            println(\"Solo se permite que el numero de participantes sea un numero potencia 2\")\r\n            return@coroutineScope\r\n        }\r\n       var rounds=warriors.shuffled()\r\n       var counterRound=1\r\n       while (rounds.size>1) {\r\n           val winners = mutableListOf<WarriorZ>()\r\n           for (i in rounds.indices step 2) {\r\n               val winner = async(Dispatchers.LOOM) { figthing(rounds[i], rounds[i + 1]) }.await()\r\n               winners.add(winner)\r\n           }\r\n           println(\"loa ganadores de la ronda $counterRound son\")\r\n           winners.forEach { println(it.name) }\r\n           rounds = winners\r\n           counterRound++\r\n       }\r\n        println(\"¡El ganador del torneo es ${rounds.first().name}!\")\r\n    }\r\n\r\n}\r\n\r\nval warriorsMock= listOf(\r\n    warriorZ {\r\n        name=\"Goku\"\r\n        speed=90\r\n        defense=85\r\n        techniques=listOf(\r\n            technique {\r\n                name=\"Kame Hame Ha !\"\r\n                attack=45\r\n            },\r\n            technique {\r\n                name=\"Kaio Ken !\"\r\n                attack=40\r\n            }\r\n        )\r\n    },\r\n    warriorZ {\r\n        name=\"Vegeta\"\r\n        speed=85\r\n        defense=90\r\n        techniques= listOf(\r\n            technique {\r\n                name=\"Harlic Ho!!\"\r\n                attack=40\r\n            },\r\n            technique {\r\n                name=\"Final flash\"\r\n                attack=67\r\n            }\r\n        )\r\n    } ,\r\n    warriorZ {\r\n       name=\"Piccolo\"\r\n       speed=85\r\n       defense=80\r\n       techniques=listOf(\r\n           technique {\r\n               name=\"Mankankosappoo \"\r\n               attack=63\r\n           },\r\n           technique {\r\n               name=\"Giganta Max\"\r\n               attack=32\r\n           }\r\n       )\r\n      },\r\n\r\n    warriorZ {\r\n        name=\"Krillin\"\r\n        speed=90\r\n        defense=50\r\n        techniques=listOf(\r\n            technique {\r\n                name=\"Kienzan \"\r\n                attack=70\r\n            },\r\n            technique {\r\n                name=\"taioken\"\r\n                attack=5\r\n            }\r\n        )\r\n\r\n    }\r\n)\r\n\r\n\r\nfun main()= runBlocking {\r\n  val toournament= TekiachiBudokai()\r\n  val job= launch{\r\n       toournament.tournament(warriorsMock)\r\n  }\r\n  job.join()\r\n}\r\n\r\n\r\n\r\n\r\n// experimentar con loom proyect en kotlin ignorar\r\nval Dispatchers.LOOM: @BlockingExecutor CoroutineDispatcher\r\n    get() = Executors.newVirtualThreadPerTaskExecutor().asCoroutineDispatcher()\r\n\r\n\r\n\r\n"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/php/didix16.php",
    "content": "<?php\n\n/*\n * Autor: didix16\n * EJERCICIO:\n * ¡El último videojuego de Dragon Ball ya está aquí!\n * Se llama Dragon Ball: Sparking! ZERO.\n *\n * Simula un Torneo de Artes Marciales, al más puro estilo\n * de la saga, donde participarán diferentes luchadores, y el\n * sistema decidirá quién es el ganador.\n *\n * Luchadores:\n * - Nombre.\n * - Tres atributos: velocidad, ataque y defensa\n *   (con valores entre 0 a 100 que tú decidirás).\n * - Comienza cada batalla con 100 de salud.\n * Batalla:\n * - En cada batalla se enfrentan 2 luchadores.\n * - El luchador con más velocidad comienza atacando.\n * - El daño se calcula restando el daño de ataque del\n *   atacante menos la defensa del oponente.\n * - El oponente siempre tiene un 20% de posibilidad de\n *   esquivar el ataque.\n * - Si la defensa es mayor que el ataque, recibe un 10%\n *   del daño de ataque.\n * - Después de cada turno y ataque, el oponente pierde salud.\n * - La batalla finaliza cuando un luchador pierde toda su salud.\n * Torneo:\n * - Un torneo sólo es válido con un número de luchadores\n *   potencia de 2.\n * - El torneo debe crear parejas al azar en cada ronda.\n * - Los luchadores se enfrentan en rondas eliminatorias.\n * - El ganador avanza a la siguiente ronda hasta que sólo\n *   quede uno.\n * - Debes mostrar por consola todo lo que sucede en el torneo,\n *   así como el ganador.\n *  --------------\n *  NOTAS: Algunos retoques añadidos\n *  1. Asumo que cada vez que un luchado pasa de ronda, se le cura la vida\n *  2. Mecánica de crítico: Si el atacante tiene 70 o más de ataque, tiene un 20% de probabilidad de hacer un crítico, sino solo un 10%\n *  3. Los críticos hacen el doble de daño y si el defensor tiene más defensa que el ataque del atacante o son iguales, el crítico ignora la defensa\n *  4. Si el personaje tiene una velocidad de 70 o más, tendrá más probabilidad de esquivar el ataque (+10%) pero menos probabilidad de hacer un crítico (-5%)\n *  5. En caso de que el daño sea 0 o negativo, el daño será el 10% del ataque del atacante.\n *  6. Si un personaje tiene 0 de velocidad, no podrá esquivar los ataques pero tendrá superarmadura, haciendo que los golpes con daño positivo solo le quiten el 10% (min 1)\n *  7. Si un personaje tiene 100 de velocidad, será supersónico y tendrá un 50% de probabilidad de esquivar los ataques!!!\n *  8. Mecánica de ki y SPARKING! MODE. Los personajes tienen 50 de ki máximo (y pueden empezar con 20 o 30) y disponen de 3 ataques especiales que comsumen ki, el débil consume 20, el fuerte 40 y la definitiva 50.\n *  Los turnos deberán usarse para atacar o recuperar ki. Si un personaje se queda sin ki, no podrá usar ataques especiales y está obligado a recuperar ki.\n *  Cada personaje dipondrá de una velocidad de recuperación de ki (cantidad a recuperar entre 10 o 20 por turno) y una probabilidad de recuperar ki que dependerá de la cantidad de ki restante\n *  en su turno. La probabilidad de recuperar ki dependerá de la cantidad de recuperación de ki del personaje, a cuanta más cantidad menos probabilidad.\n *  La probabilidad de escoger recuperación en vez de ataque dependerá de la cantidad de ki restante. Para ello generaremos 2 tipos de curvas cúbicas a trozos (natural cubic spline) que aproximen la probabilidad:\n *      - una para los que recuperan 10 de ki por turno (Ki Recharge = 10)\n *      - otra para los que recuperan 20 de ki por turno (Ki Recharge = 20)\n *  Si un personaje tiene menos de 20 de ataque se considerará débil pero como bonificación para balancear un poco la cosa, sus ataques de ki débil tendrán un 20% más de daño y los fuertes un 50% más de daño además de tener 10% más de probabilidad de ignorar la defensa del defensor.\n *  Los ataques de ki no se calculan como los ataques normales, sino que tienen un daño base (atk+%) y una probabilidad de ignorar la defensa del defensor además de no tener críticos:\n *  Los ataques de ki débiles producen un daño equivalente al atk + 25% (+50% si personaje debil; min 2 daño) y tienen una probabilidad del 20% (30% si personaje debil) de ignorar el 80% de la defensa del defensor.\n *  Los ataques de ki fuertes producen un daño equivalente al atk + 50% (+100% si personaje debil; min 5 daño) y tienen una probabilidad del 40% (50% si personaje debil) de ignorar el 80% de la defensa del defensor.\n *  Los ataques de ki definitivos producen un daño equivalente al atk + 200% (+300% si personaje debil; min 10 daño) y tienen un 70% de probabilidad de ignorar el 100% de la defensa del defensor.\n *  Además, para realizar un ataque de ki definitivo, el personaje debe entrar en modo SPARKING!. Para ello, el personaje debe tener 50 de ki y la probabilidad de entrar en modo SPARKING! se calcula como:\n *     - 50% si el personaje no es considerado débil\n *     - 60% si el personaje es considerado débil\n *     - 65% + ((atk-70)/30)*20% si el personaje es considerado fuerte (70atk => 65%, 100atk => 85%)\n *  Entrar en modo SPARKING! consumirá un turno. En este modo, el personaje obtendrá:\n *     - +5% de probabilidad de crítico adicional\n *     - +10% de probabilidad de esquivar adicional\n *     - +10% de atk adicional\n *     - -20% de reducción defensa\n *     - posibilidad de realizar el ataque definitivo de ki\n *  Este modo consta de un contador especial de 50 unidades las cuales cuando llegue a 0, el personaje saldrá del modo SPARKING!\n *  Durante el modo SPARKING! el personaje consumirá contador SPARKING! según el ataque que realice:\n *     - 5 unidades por ataque físico\n *     - 20 unidades por ataque de ki débil\n *     - 40 unidades por ataque de ki fuerte\n *     - 50 unidades por ataque de ki definitivo (consume 50 de ki y sale del modo SPARKING!)\n *  Mientras el contador sea positivo, se podrá realizar cualquier combinación de ataque posible. Cuando el contador llegue a 0, el personaje saldrá del modo SPARKING!. Realizar un ataque definitivo de ki consumirá el contador y el ki del personaje.\n *  Para elegir entre ataque físico o de ki, dependerá de si tiene ki disponible (o contador SPARKING!) y si lo tiene entonces la probabilidad se calcula como:\n *     - Si modo SPARKING! activo\n *          - 10% para el ataque de ki débil\n *          - 20% para el ataque de ki fuerte\n *          - 10% para ataques físicos\n *          - 60% para ataque definitivo de ki\n *     - Si ki disponible >= 40\n *          - 15% para el ataque de ki débil\n *          - 25% para el ataque de ki fuerte\n *          - 60% para ataques físicos\n *     - Si ki disponible >= 20 y < 40\n *         - 25% para el ataque de ki débil\n *         - 75% para ataques físicos\n *    - Si ki disponible < 20\n *      -  100% para ataques físicos\n */\n\nnamespace didix16\\DragonBallTourament;\n\nfunction msleep(int $milliseconds)\n{\n    usleep($milliseconds * 1000);\n}\n\nfunction randomValueFrom(array $list)\n{\n    return $list[array_rand($list)];\n}\n\nenum AttackType\n{\n    case PHYSICAL_ATK;\n    case KI_WEAK_ATK;\n    case KI_STRONG_ATK;\n    case KI_ULTIMATE_ATK;\n\n    public static function isPhysicalAtk(AttackType $type): bool\n    {\n        return $type === self::PHYSICAL_ATK;\n    }\n\n    public static function isKiWeakAtk(AttackType $type): bool\n    {\n        return $type === self::KI_WEAK_ATK;\n    }\n\n    public static function isKiStrongAtk(AttackType $type): bool\n    {\n        return $type === self::KI_STRONG_ATK;\n    }\n\n    public static function isKiUltimateAtk(AttackType $type): bool\n    {\n        return $type === self::KI_ULTIMATE_ATK;\n    }\n}\n\nfunction printAtack(Fighter $fighter1, Fighter $fighter2, int $damage, bool $evaded, bool $isCritical = false, bool $defenseIgnored): void\n{\n    $fighter1Name = $fighter1->getName();\n    $fighter2Name = $fighter2->getName();\n\n    if (!$evaded) {\n        printf(\n            \"%s ataca 🤜 a %s y le hace %d de daño 💔⬇️.%s%s\\n\",\n            $fighter1Name,\n            $fighter2Name,\n            $damage,\n            $isCritical ? ' 💥💥 ¡UUH ESO HA SIDO UN CRÍTICO! 💥💥' : '',\n            $defenseIgnored ? ' 💥🛡️ ¡UUH LE HA PUESTO TODA SU ENERGÍA Y HA ATRAVESADO LA DEFENSA! 🛡️💥' : ''\n        );\n    } else {\n        printf(\n            \"%s ataca 🤜 a %s pero %s esquiva el ataque! 🤸‍♂️💨\\n\",\n            $fighter1Name,\n            $fighter2Name,\n            $fighter2Name\n        );\n    }\n}\n\nfunction kiAtackTypeMsg(AttackType $atk): string\n{\n    return match ($atk) {\n        AttackType::KI_WEAK_ATK => 'un ataque de ki débil',\n        AttackType::KI_STRONG_ATK => 'un ataque de ki fuerte',\n        AttackType::KI_ULTIMATE_ATK => 'el ataque de ki definitivo',\n    };\n};\n\nfunction printKiAtack(Fighter $fighter1, Fighter $fighter2, int $damage, bool $evaded, bool $defenseIgnored, AttackType $atkType): void\n{\n    $fighter1Name = $fighter1->getName();\n    $fighter2Name = $fighter2->getName();\n    $kiAtkIcon = '🫸〰️' . (AttackType::isKiUltimateAtk($atkType) ? '🧿' : '');\n\n    if (!$evaded) {\n        printf(\n            \"%s ataca %s a %s con %s y le hace %d de daño 💔⬇️.%s\\n\",\n            $fighter1Name,\n            $kiAtkIcon,\n            $fighter2Name,\n            kiAtackTypeMsg($atkType),\n            $damage,\n            $defenseIgnored ? ' 💥💥 ¡UUH ESA ATAQUE HA HECHO MELLA! 💥💥' : ''\n        );\n    } else {\n        printf(\n            \"%s ataca %s a %s con %s pero %s esquiva el ataque! 🤸‍♂️💨\\n\",\n            $fighter1Name,\n            $kiAtkIcon,\n            $fighter2Name,\n            kiAtackTypeMsg($atkType),\n            $fighter2Name\n        );\n    }\n}\n\nfunction printHealthAndKiOf(Fighter $fighter): void\n{\n    printf(\n        \"%s tiene %d de vida ❤️ y %s.\\n\",\n        $fighter->getName(),\n        $fighter->getHealth(),\n        !$fighter->isInSparkingMode() ? $fighter->getKi() . ' de ki ⚡' : $fighter->getSparkingGauge() . ' de SPARKING! MODE 🌟⚡'\n    );\n}\n\n// ki/sparking gauge amount to discharge by atk type\nfunction dischargeKiAmountByType(AttackType $atk)\n{\n\n    return match ($atk) {\n        AttackType::PHYSICAL_ATK => 5,\n        AttackType::KI_WEAK_ATK => 20,\n        AttackType::KI_STRONG_ATK => 40,\n        AttackType::KI_ULTIMATE_ATK => 50,\n    };\n};\n\n// some ki natural cubic spline functions\ninterface KiRechargeInterface\n{\n\n    public function kiRechargeProbability(int $ki): float;\n}\n\nclass KiRecharge10 implements KiRechargeInterface\n{\n\n    public function kiRechargeProbability(int $ki): float\n    {\n        return ($ki >= 0 && $ki <= 10)\n            ? (-2.9508e-5 * $ki ** 3 - 1.7049e-2 * $ki + 1)\n            : (($ki > 10 && $ki <= 20)\n                ? (4.7541e-5 * $ki ** 3 - 2.3115e-3 * $ki ** 2 + 6.0656e-3 * $ki + 0.92295)\n                : (($ki > 20 && $ki <= 40)\n                    ? (-3.6885e-6 * $ki ** 3 + 7.623e-4 * $ki ** 2 - 5.541e-2 * $ki + 1.3328)\n                    : (($ki > 40 && $ki <= 50)\n                        ? (-1.0656e-5 * $ki ** 3 + 1.5984e-3 * $ki ** 2 - 8.8852e-2 * $ki + 1.7787)\n                        : 0\n                    )\n                )\n            );\n    }\n}\n\nclass KiRecharge20 implements KiRechargeInterface\n{\n\n    public function kiRechargeProbability(int $ki): float\n    {\n        return ($ki >= 0 && $ki <= 10)\n            ? (1.1639e-4 * $ki ** 3 - 7.163e-2 * $ki + 1)\n            : (($ki > 10 && $ki <= 20)\n                ? (-1.3197e-4 * $ki ** 3 + 7.4508e-3 * $ki ** 2 - 1.4615e-1 * $ki + 1.2484)\n                : (($ki > 20 && $ki <= 40)\n                    ? (1.4549e-5 * $ki ** 3 - 1.3402e-3 * $ki ** 2 + 2.9672e-2 * $ki + 7.623e-2)\n                    : (($ki > 40 && $ki <= 50)\n                        ? (-1.3525e-5 * $ki ** 3 + 2.0287e-3 * $ki ** 2 - 1.0508e-1 * $ki + 1.873)\n                        : 0\n                    )\n                )\n            );\n    }\n}\n\n// class Fighter\nclass Fighter implements KiRechargeInterface\n{\n    protected const MAX_KI = 50;\n    protected int $health = 100;\n    protected int $evasionProbability = 0;\n    protected int $sparkingGauge = 0;\n    protected int $initialKi = 0;\n    protected KiRechargeInterface $kiRecharger;\n\n    public function __construct(\n        protected string $name,\n        protected int $attack,\n        protected int $defense,\n        protected int $speed,\n        protected int $ki = 0,\n        protected int $kiRechargeAmount = 10,\n    ) {\n        $this->kiRecharger = match ($kiRechargeAmount) {\n            10 => new KiRecharge10(),\n            20 => new KiRecharge20(),\n            default => new KiRecharge10(),\n        };\n        $this->ki = max(0, min($this->ki, self::MAX_KI));\n        $this->initialKi = $this->ki;\n        $this->evasionProbability = $this->isSuperSonic() ? 50 : ($this->isFast() ? 30 : (!$this->hasSuperArmor() ? 20 : 0));\n    }\n\n    public function getName(): string\n    {\n        return $this->name;\n    }\n\n    public function getAtk(): int\n    {\n        return ! $this->isInSparkingMode() ? $this->attack : intval($this->attack * 1.1);\n    }\n\n    public function getDef(): int\n    {\n        return ! $this->isInSparkingMode() ? $this->defense : intval($this->defense * 0.8);\n    }\n\n    public function getSpeed(): int\n    {\n        return $this->speed;\n    }\n\n    public function getKiRechargeAmount(): int\n    {\n        return $this->kiRechargeAmount;\n    }\n\n    public function getHealth(): int\n    {\n        return $this->health;\n    }\n\n    public function getKi(): int\n    {\n        return $this->ki;\n    }\n\n    public function getSparkingGauge(): int\n    {\n        return $this->sparkingGauge;\n    }\n\n    public function kiRechargeProbability(int $ki): float\n    {\n        return $this->kiRecharger->kiRechargeProbability($ki) * 100;\n    }\n\n    public function isInSparkingMode(): bool\n    {\n        return $this->sparkingGauge > 0;\n    }\n\n    public function enterInSparkingMode(): bool\n    {\n        if ($this->ki === self::MAX_KI) {\n            $sparkingProbability = match (true) {\n                $this->isStrong() => 65 + (($this->attack - 70) / 30) * 20,\n                $this->isWeak() => 60,\n                default => 50,\n            };\n\n            if (rand(1, 100) <= $sparkingProbability) {\n                $this->sparkingGauge = self::MAX_KI;\n                return true;\n            } else {\n                return false;\n            }\n        }\n        return false;\n    }\n\n    public function exitSparkingMode(): self\n    {\n        $this->sparkingGauge = 0;\n        return $this;\n    }\n\n    public function dischargeSparkingGauge(int $amount): self\n    {\n        $this->sparkingGauge = max(0, $this->sparkingGauge - $amount);\n        return $this;\n    }\n\n    // if true, the fighter will recharge ki, if false, the fighter will attack\n    public function hasToRechageKi(): bool\n    {\n        return rand(1, 100) <= $this->kiRechargeProbability($this->ki);\n    }\n\n    public function evade(): bool\n    {\n        return rand(1, 100) <= (!$this->isInSparkingMode() ? $this->evasionProbability : $this->evasionProbability + 10);\n    }\n\n    public function useKiOrPhysicalAttack(): AttackType\n    {\n\n        $r = rand(1, 100);\n\n        // check if the fighter is in sparking mode\n        if ($this->isInSparkingMode()) {\n            // 10% for weak ki atk, 20% for strong ki atk, 10% for physical atk and 60% for ultimate ki atk\n            return match (true) {\n                $r <= 10 => AttackType::KI_WEAK_ATK,\n                $r <= 30 => AttackType::KI_STRONG_ATK,\n                $r <= 40 => AttackType::PHYSICAL_ATK,\n                default => AttackType::KI_ULTIMATE_ATK,\n            };\n        }\n\n        if ($this->ki >= 40) {\n            // 15% for weak ki atk, 25% for strong ki atk, 60% for physical atk\n            return match (true) {\n                $r <= 15 => AttackType::KI_WEAK_ATK,\n                $r <= 40 => AttackType::KI_STRONG_ATK,\n                default => AttackType::PHYSICAL_ATK,\n            };\n        } else if ($this->ki >= 20) {\n            // 25% for weak ki atk, 75% for physical atk\n            return $r <= 25 ? AttackType::KI_WEAK_ATK : AttackType::PHYSICAL_ATK;\n        } else {\n            return AttackType::PHYSICAL_ATK;\n        }\n    }\n\n    // return the damage and if the defense was ignored partially or totally\n    public function takeKiDamageFrom(Fighter $fighter, AttackType $kiType): array\n    {\n\n        $damage = 0;\n        $ignoreDefense = false;\n        $minDamage = 0;\n        $tempDef = $this->getDef();\n\n        switch ($kiType) {\n            case AttackType::KI_WEAK_ATK:\n                $damage = intval($fighter->getAtk() * ($fighter->isWeak() ? 1.25 : 1.2));\n                $tempDef = rand(1, 100) <= ($fighter->isWeak() ? 30 : 20) ? intval($tempDef * 0.8) : $tempDef;\n                $minDamage = 2;\n                break;\n            case AttackType::KI_STRONG_ATK:\n                $damage = intval($fighter->getAtk() * ($fighter->isWeak() ? 2 : 1.5));\n                $tempDef = rand(1, 100) <= ($fighter->isWeak() ? 50 : 40) ? intval($tempDef * 0.8) : $tempDef;\n                $minDamage = 5;\n                break;\n            case AttackType::KI_ULTIMATE_ATK:\n                $damage = intval($fighter->getAtk() * ($fighter->isWeak() ? 4 : 3));\n                $ignoreDefense = rand(1, 100) <= 70;\n                $minDamage = 10;\n                break;\n            default:\n                throw new \\Exception('Invalid ki type');\n        }\n\n        if (!$ignoreDefense) {\n            $damage = $damage - $tempDef;\n        }\n\n        $this->health -= $damage = max($minDamage, $damage);\n        return [$damage, $ignoreDefense || $this->getDef() !== $tempDef];\n    }\n\n    public function takePhysicalDamageFrom(Fighter $fighter): array\n    {\n\n        $damage = $fighter->getAtk() - $this->getDef();\n        $critProbability = ($fighter->isStrong() ? 20 : 10) - ($fighter->isFast() ? 5 : 0);\n        $critProbability += $fighter->isInSparkingMode() ? 5 : 0;\n        $defenseIgnored = false;\n\n        $isCritical = rand(1, 100) <= $critProbability;\n        if ($isCritical) {\n            // if the defender has more defense than the atk of the atacker or they are the same, the crit ignores the defense\n            if ($damage <= 0) {\n                $damage = $fighter->getAtk() << 1; // double the damage (fighter atk) ignoring the defense\n                $defenseIgnored = true;\n            } else {\n                $damage = $damage << 1; // double the damage (fighter atk)\n            }\n        }\n        // if the defender has more defense than the atk of the atacker or they are the same, the damage  is the 10% of the atk of the atacker\n        else if ($damage <= 0) $damage = intval($fighter->getAtk() * 0.1); // get the integer part;\n\n        // if the defender has super armor, the damage is reduced by 90% (min 1)\n        if ($this->hasSuperArmor()) {\n            $damage = max(1, intval($damage * 0.1));\n        }\n\n        $this->health -= $damage;\n        return [$damage, $isCritical, $defenseIgnored];\n    }\n\n    public function hasSuperArmor(): bool\n    {\n        return $this->speed === 0;\n    }\n\n    public function isSuperSonic(): bool\n    {\n        return $this->speed === 100;\n    }\n\n    public function isFast(): bool\n    {\n        return $this->speed >= 70;\n    }\n\n    public function isStrong(): bool\n    {\n        return $this->attack >= 70;\n    }\n\n    public function isWeak(): bool\n    {\n        return $this->attack < 20;\n    }\n\n    public function isDead(): bool\n    {\n        return $this->health <= 0;\n    }\n\n    public function heal(): self\n    {\n        $this->health = 100;\n        return $this;\n    }\n\n    public function healKi(): self\n    {\n        $this->ki = $this->initialKi;\n        return $this;\n    }\n\n    public function dischargeKiAmount(int $amount): self\n    {\n        $this->ki = max(0, $this->ki - $amount);\n        return $this;\n    }\n\n    public function rechargeKi(): self\n    {\n        $this->ki = min(self::MAX_KI, $this->ki + $this->kiRechargeAmount);\n        return $this;\n    }\n}\n\n// Singleton Tournament\n/**\n * Usage:\n * $tournament = Tournament::getInstance();\n * reset(); reset the tournament after it ends. return the torunament object\n * init($numOfFighters, timeInMsBetweenAttacks); start the tournament with numOfFighters and simulate the time between attacks and rounds if timeInMsBetweenAttacks is set\n * returns the winner of the tournament\n * \n * Example 1 (first time) with 8 fighters and no time between attacks:\n * $tournament->init(8);\n * Example 2 (first time) with 8 fighters and 1.1s between attacks and rounds:\n * $tournament->init(8, 1100);\n * Example 3 (reset the tournament) with 16 fighters and no time between attacks:\n * $tournament->reset()->init(16);\n */\nclass Tournament\n{\n    protected static ?Tournament $instance = null;\n    protected array $fighters = [];\n    protected int $rounds = 0;\n    protected int $timmer = 0; // use this to simulate the time between attacks and rounds\n    protected ?Fighter $winner = null;\n\n    // some names and its usage\n    protected static array $names = [\n        'Goku' => 0,\n        'Vegeta' => 0,\n        'Piccolo' => 0,\n        'Gohan' => 0,\n        'Krillin' => 0,\n        'Yamcha' => 0,\n        'Tien' => 0,\n        'Chiaotzu' => 0,\n        'Master Roshi' => 0,\n        'Trunks' => 0,\n        'Goten' => 0,\n        'Pan' => 0,\n        'Frieza' => 0,\n        'Cell' => 0,\n        'Majin Buu' => 0,\n        'Beerus' => 0,\n        'Whis' => 0,\n        'Jiren' => 0,\n        'Hit' => 0,\n        'Kale' => 0,\n        'Caulifla' => 0,\n        'Cabba' => 0,\n        'Broly' => 0,\n        'Zamasu' => 0,\n        'Black Goku' => 0,\n        'Vegito' => 0,\n        'Gogeta' => 0,\n        'Kefla' => 0,\n        'Toppo' => 0,\n        'Dyspo' => 0,\n        'Android 17' => 0,\n        'Android 18' => 0,\n        'Android 16' => 0,\n        'Android 19' => 0,\n        'Android 20' => 0,\n        'Android 21' => 0,\n    ];\n\n\n    private function __construct() {}\n\n    public static function getInstance(): Tournament\n    {\n        if (self::$instance === null) {\n            self::$instance = new Tournament();\n        }\n        return self::$instance;\n    }\n\n    public function generateFighters(int $n, bool $timmerIsSet = false): self\n    {\n        // check if n is integer, is positive and max 2^10, its min 2 and is a power of 2\n        if (!is_int($n) || ($n & ($n - 1)) !== 0 || $n < 2 || $n > 1024) {\n            throw new \\Exception('El torneo solo es válido con un número de luchadores potencia de 2,un mínimo de 2 luchadores y máximo de 1024');\n        }\n\n        while ($n--) {\n            $name = array_rand(self::$names);\n            // add #number to the name if it is repeated\n            self::$names[$name]++ && ($name .= ' ' . self::$names[$name]);\n            $atk = rand(10, 100); // min 10 atk to make some damage\n            $def = rand(0, 100);\n            $speed = rand(0, 100);\n            $initialKi = randomValueFrom([20, 30]);\n            $kiRechargeAmount = randomValueFrom([10, 20]);\n\n            $this->fighters[] = new Fighter($name, $atk, $def, $speed, $initialKi, $kiRechargeAmount);\n            printf(\n                \"%s se une al torneo con %d 💪 de ataque, %d de defensa 🛡️, %d de velocidad 🪽, %d de ki inicial ⚡ y %d de recarga de ki ⬆️⚡%s%s.\\n\",\n                $name,\n                $atk,\n                $def,\n                $speed,\n                $initialKi,\n                $kiRechargeAmount,\n                $speed === 0 ? '¡¡¡INCLUSO TIENE SUPER ARMADURA!!! 🧱' : '[no tiene super armadura]',\n                $speed === 100 ? '¡¡¡ES SUPERSÓNICO, ESQUIVARÁ CASI TODO!!! 🏃‍♂️💨' : '[no es supersónico]'\n            );\n            $timmerIsSet && msleep(250);\n        }\n\n        // sort the fighters by random order\n        shuffle($this->fighters);\n\n\n        return $this;\n    }\n\n    public function reset(): self\n    {\n        $this->fighters = [];\n        $this->rounds = 0;\n        $this->timmer = 0;\n        $this->winner = null;\n        self::$names = array_map(fn($v) => 0, self::$names);\n        return $this;\n    }\n\n    public function init(int $numOfFighters, $timeInMsBetweenAttacks = 0): Fighter\n    {\n        $this->generateFighters($numOfFighters, $timeInMsBetweenAttacks > 0);\n        $this->timmer = $timeInMsBetweenAttacks;\n        $this->rounds = log($numOfFighters, 2);\n        return $this->start();\n    }\n\n    protected function start(): Fighter\n    {\n\n        $winners = $this->fighters;\n        for ($i = 0; $i < $this->rounds - 1; $i++) {\n            printf(\"Ronda %d\\n\", $i + 1);\n            msleep($this->timmer);\n            $winners = $this->round($winners);\n        }\n\n        printf(\"Ronda final entre 🤜 %s y %s 🤛\\n\", $winners[0]->getName(), $winners[1]->getName());\n        $winners = $this->round($winners, true);\n\n        $this->winner = $winners[0];\n        printf(\"¡¡¡%s ha ganado el torneo!!! 🏆🎉\\n\", $this->winner->getName());\n\n        return $this->winner;\n    }\n\n    protected function round(array $fighters, bool $isFinal = false): array\n    {\n\n        $winners = [];\n        $fightersLen = count($fighters);\n        for ($i = 0; $i < $fightersLen; $i += 2) {\n            $fighter1 = $fighters[$i];\n            $fighter2 = $fighters[$i + 1];\n            !$isFinal && printf(\"Empieza la batalla #%d entre 🤜 %s y %s 🤛!\\n\", ($i >> 1) + 1, $fighter1->getName(), $fighter2->getName());\n            msleep($this->timmer);\n            $winner = $this->battle($fighter1, $fighter2);\n            !$isFinal && printf(\"%s avanza a la siguiente ronda 👏\\n\", $winner->getName());\n            $winners[] = $winner;\n        }\n\n        return $winners;\n    }\n\n    protected function battle(Fighter $fighter1, Fighter $fighter2): Fighter\n    {\n        $turn = $fighter1->getSpeed() > $fighter2->getSpeed() ? [$fighter1, $fighter2] : [$fighter2, $fighter1];\n\n        while (true) {\n            $attacker = $turn[0];\n            $defender = $turn[1];\n\n            // check if the atacker attacks or recharges ki\n            if ($attacker->hasToRechageKi()) {\n                $attacker->rechargeKi();\n                printf(\n                    \"%s recarga ki 🔄🧘 y recupera %d de ki⚡⬆️. Ahora tiene %d de ki ⚡\\n\",\n                    $attacker->getName(),\n                    $attacker->getKiRechargeAmount(),\n                    $attacker->getKi()\n                );\n                msleep($this->timmer);\n                $turn = [$defender, $attacker];\n                continue;\n            }\n\n            // check if the attacker enters in sparking mode\n            $attackerInSparkingMode = $attacker->isInSparkingMode();\n            if (!$attackerInSparkingMode && $attacker->enterInSparkingMode()) {\n                printf(\n                    \"%s entra en modo SPARKING! 🌟🔥 y aumenta sus habilidades 📈. La cosa se pone seria ⚠️\\n\",\n                    $attacker->getName()\n                );\n                msleep($this->timmer);\n                $turn = [$defender, $attacker];\n                continue;\n            }\n\n            // attacker attacks\n            // check if the attacker uses ki or physical attack\n            $atkType = $attacker->useKiOrPhysicalAttack();\n\n            // check if the defender evades the attack\n            $evaded = $defender->evade();\n\n            $damage = 0;\n\n            // if the attacker uses ki attack, the defender takes ki damage\n            if (!AttackType::isPhysicalAtk($atkType)) {\n\n                [$damage, $defenseIgnored] = !$evaded ? $defender->takeKiDamageFrom($attacker, $atkType) : [0, false];\n\n                $attackerInSparkingMode\n                    ?   $attacker->dischargeSparkingGauge(dischargeKiAmountByType($atkType)) &&\n                    AttackType::isKiUltimateAtk($atkType) &&\n                    $attacker->dischargeKiAmount(dischargeKiAmountByType($atkType))\n                    : $attacker->dischargeKiAmount(dischargeKiAmountByType($atkType));\n\n                printKiAtack($attacker, $defender, $damage, $evaded, $defenseIgnored, $atkType);\n                if ($defender->isDead()) {\n                    printf(\"%s ha sido derrotado 💀😵\\n\", $defender->getName());\n                    $attacker\n                        ->heal()\n                        ->healKi()\n                        ->exitSparkingMode();\n                    msleep($this->timmer);\n                    return $attacker;\n                } else {\n                    // print if the attacker leaves the sparking mode\n                    $attackerLeavesSparkingMode = $attackerInSparkingMode && !$attacker->isInSparkingMode();\n                    $attackerLeavesSparkingMode && printf(\"%s sale del modo SPARKING! 🌟🔥\\n\", $attacker->getName());\n\n                    printHealthAndKiOf($attacker);\n                    printHealthAndKiOf($defender);\n\n                    msleep($this->timmer);\n                }\n\n                $turn = [$defender, $attacker];\n                continue;\n            }\n\n            [$damage, $isCritical, $defenseIgnored] = !$evaded ? $defender->takePhysicalDamageFrom($attacker) : [0, false, false];\n            $attackerInSparkingMode && $attacker->dischargeSparkingGauge(dischargeKiAmountByType(AttackType::PHYSICAL_ATK));\n\n            printAtack($attacker, $defender, $damage, $evaded, $isCritical, $defenseIgnored);\n\n            if ($defender->isDead()) {\n                printf(\"%s ha sido derrotado 💀😵\\n\", $defender->getName());\n\n                $attacker\n                    ->heal()\n                    ->healKi()\n                    ->exitSparkingMode();\n\n                msleep($this->timmer);\n                return $attacker;\n            } else {\n                // print if the attacker leaves the sparking mode\n                $attackerLeavesSparkingMode = $attackerInSparkingMode && !$attacker->isInSparkingMode();\n                $attackerLeavesSparkingMode && printf(\"%s sale del modo SPARKING! 🌟🔥\\n\", $attacker->getName());\n\n                printHealthAndKiOf($attacker);\n                printHealthAndKiOf($defender);\n\n                msleep($this->timmer);\n            }\n\n            $turn = [$defender, $attacker];\n        }\n    }\n}\n\nif (php_sapi_name() === 'cli') {\n    // start the tournament\n    $numOfFighters = $argc > 1 ? intval($argv[1]) : 8;\n    $timeInMsBetweenAttacks = $argc > 2 ? intval($argv[2]) : 0;\n    Tournament::getInstance()->init($numOfFighters, $timeInMsBetweenAttacks);\n} else {\n\n    // start the tournament\n    Tournament::getInstance()->init(8);\n}\n"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/php/miguelex.php",
    "content": "<?php\n\nclass Luchador {\n    public $nombre;\n    public $velocidad;\n    public $ataque;\n    public $defensa;\n    public $salud = 100;\n\n    public function __construct($nombre, $velocidad, $ataque, $defensa) {\n        $this->nombre = $nombre;\n        $this->velocidad = $velocidad;\n        $this->ataque = $ataque;\n        $this->defensa = $defensa;\n    }\n\n    public function esquivar() {\n        return mt_rand(1, 100) <= 20;\n    }\n}\n\nfunction batalla($luchador1, $luchador2) {\n    echo \"¡Batalla entre {$luchador1->nombre} y {$luchador2->nombre}!\\n\";\n\n    $atacante = $luchador1->velocidad >= $luchador2->velocidad ? $luchador1 : $luchador2;\n    $defensor = $atacante === $luchador1 ? $luchador2 : $luchador1;\n\n    while ($luchador1->salud > 0 && $luchador2->salud > 0) {\n        if ($defensor->esquivar()) {\n            echo \"{$defensor->nombre} esquivó el ataque de {$atacante->nombre}!\\n\";\n        } else {\n            $danio = $atacante->ataque - $defensor->defensa;\n            if ($danio <= 0) {\n                $danio = $atacante->ataque * 0.1; // Recibe un 10% del ataque si la defensa es mayor\n            }\n            $defensor->salud -= $danio;\n            echo \"{$atacante->nombre} ataca a {$defensor->nombre} y causa {$danio} de daño. Salud restante de {$defensor->nombre}: {$defensor->salud}\\n\";\n        }\n\n        $temp = $atacante;\n        $atacante = $defensor;\n        $defensor = $temp;\n    }\n\n    $ganador = $luchador1->salud > 0 ? $luchador1 : $luchador2;\n    echo \"¡{$ganador->nombre} es el ganador de la batalla!\\n\\n\";\n    return $ganador;\n}\n\nfunction torneo($luchadores) {\n    if ((count($luchadores) & (count($luchadores) - 1)) != 0) {\n        echo \"El número de luchadores debe ser una potencia de 2.\\n\";\n        return;\n    }\n\n    echo \"¡Comienza el torneo de Dragon Ball: Sparking! ZERO!\\n\\n\";\n    while (count($luchadores) > 1) {\n        $luchadoresRestantes = [];\n        shuffle($luchadores);\n        for ($i = 0; $i < count($luchadores); $i += 2) {\n            $ganador = batalla($luchadores[$i], $luchadores[$i + 1]);\n            $luchadoresRestantes[] = $ganador;\n        }\n        $luchadores = $luchadoresRestantes;\n    }\n\n    echo \"¡El ganador del torneo es {$luchadores[0]->nombre}!\\n\";\n}\n\nfunction agregarLuchadores() {\n    $luchadores = [];\n    echo \"Ingrese el número de luchadores (debe ser una potencia de 2): \";\n    $numLuchadores = (int)trim(fgets(STDIN));\n\n    if (($numLuchadores & ($numLuchadores - 1)) != 0 || $numLuchadores <= 0) {\n        echo \"El número de luchadores debe ser una potencia de 2.\\n\";\n        exit();\n    }\n\n    for ($i = 0; $i < $numLuchadores; $i++) {\n        echo \"Ingrese el nombre del luchador \" . ($i + 1) . \": \";\n        $nombre = trim(fgets(STDIN));\n\n        echo \"Ingrese la velocidad de {$nombre} (0-100): \";\n        $velocidad = (int)trim(fgets(STDIN));\n\n        echo \"Ingrese el ataque de {$nombre} (0-100): \";\n        $ataque = (int)trim(fgets(STDIN));\n\n        echo \"Ingrese la defensa de {$nombre} (0-100): \";\n        $defensa = (int)trim(fgets(STDIN));\n\n        $luchadores[] = new Luchador($nombre, $velocidad, $ataque, $defensa);\n    }\n\n    return $luchadores;\n}\n\n$luchadores = agregarLuchadores();\ntorneo($luchadores);\n\n\n"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/php/snaisel.php",
    "content": "<?php\nclass Luchador\n{\n    public $nombre = \"\";\n    public $velocidad = 0;\n    public $ataque = 0;\n    public $defensa = 0;\n    public $salud = 100;\n    public $color = \"#000000\";\n\n    public function __construct($i, $v)\n    {\n        if (isset($v)) {\n            $this->nombre = \"<span class='badge text-bg-info'>\" . $i . \"</span> \" . $v[0];\n            $this->velocidad = $this->checkAtributo($v[1]);\n            $this->ataque = $this->checkAtributo($v[2]);\n            $this->defensa = $this->checkAtributo($v[3]);\n        } else {\n            $this->nombre = \"<span class='badge text-bg-info'>\" . $i . \"</span> \" . $this->nombre();\n            $this->velocidad = mt_rand(1, 100);\n            $this->ataque =  mt_rand(1, 100);\n            $this->defensa = mt_rand(1, 100);\n        }\n        $this->color = \"#\" . $this->colorAleatorio();\n    }\n    private function nombre()\n    {\n        return ucfirst(strtolower(substr(str_shuffle(\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\"), 0, 6)));\n    }\n    private function checkAtributo($a)\n    {\n        if ($a >= 0 && $a <= 100) {\n            return $a;\n        } else {\n            throw new Error(\"El valor debe estar entre 0 y 100\");\n        }\n    }\n    private function colorAleatorio()\n    {\n        return ucfirst(strtolower(substr(str_shuffle(\"0123456789ABCDEF\"), 0, 6)));\n    }\n    public function getLuchador()\n    {\n        $html = \"<div class='card mb-4 rounded-3 shadow-sm'><div class='card-header'><h4>\";\n        $html .= '<svg xmlns=\"http://www.w3.org/2000/svg\" style=\"color:' . $this->color . '\" width=\"1em\" height=\"1em\" fill=\"currentColor\" class=\"bi bi-person-arms-up flex-shrink-0 me-3\" viewBox=\"0 0 16 16\">\n<path d=\"M8 3a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3\"/>\n<path d=\"m5.93 6.704-.846 8.451a.768.768 0 0 0 1.523.203l.81-4.865a.59.59 0 0 1 1.165 0l.81 4.865a.768.768 0 0 0 1.523-.203l-.845-8.451A1.5 1.5 0 0 1 10.5 5.5L13 2.284a.796.796 0 0 0-1.239-.998L9.634 3.84a.7.7 0 0 1-.33.235c-.23.074-.665.176-1.304.176-.64 0-1.074-.102-1.305-.176a.7.7 0 0 1-.329-.235L4.239 1.286a.796.796 0 0 0-1.24.998l2.5 3.216c.317.316.475.758.43 1.204Z\"/>\n</svg>';\n        $html .= $this->nombre;\n        $html .= \"</h4></div><div class='card-body'>\";\n        $html .= \"<div class='col d-flex align-items-start mb-0'>\";\n        $html .= '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1.75em\" height=\"1.75em\" fill=\"currentColor\" class=\"bi bi-crosshair flex-shrink-0 me-3\" viewBox=\"0 0 16 16\">\n<path d=\"M8.5.5a.5.5 0 0 0-1 0v.518A7 7 0 0 0 1.018 7.5H.5a.5.5 0 0 0 0 1h.518A7 7 0 0 0 7.5 14.982v.518a.5.5 0 0 0 1 0v-.518A7 7 0 0 0 14.982 8.5h.518a.5.5 0 0 0 0-1h-.518A7 7 0 0 0 8.5 1.018zm-6.48 7A6 6 0 0 1 7.5 2.02v.48a.5.5 0 0 0 1 0v-.48a6 6 0 0 1 5.48 5.48h-.48a.5.5 0 0 0 0 1h.48a6 6 0 0 1-5.48 5.48v-.48a.5.5 0 0 0-1 0v.48A6 6 0 0 1 2.02 8.5h.48a.5.5 0 0 0 0-1zM8 10a2 2 0 1 0 0-4 2 2 0 0 0 0 4\"/>\n</svg>';\n        $html .= \"<div><h5 class='fw-bold mb-2 fs-5 text-body-emphasis'>Ataque</h5>\";\n        $html .= \"</div></div>\";\n        $html .= '<div class=\"progress\" role=\"progressbar\" aria-label=\"Ataque\" aria-valuenow=\"' . $this->ataque . '\" aria-valuemin=\"0\" aria-valuemax=\"100\">\n        <div class=\"progress-bar bg-danger\" style=\"width: ' . $this->ataque . '%\">' . $this->ataque . '</div></div>';\n\n        $html .= \"<div class='col d-flex align-items-start mb-0 mt-3'>\";\n        $html .= '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1.75em\" height=\"1.75em\" fill=\"currentColor\" class=\"bi bi-bricks flex-shrink-0 me-3\" viewBox=\"0 0 16 16\">\n        <path d=\"M0 .5A.5.5 0 0 1 .5 0h15a.5.5 0 0 1 .5.5v3a.5.5 0 0 1-.5.5H14v2h1.5a.5.5 0 0 1 .5.5v3a.5.5 0 0 1-.5.5H14v2h1.5a.5.5 0 0 1 .5.5v3a.5.5 0 0 1-.5.5H.5a.5.5 0 0 1-.5-.5v-3a.5.5 0 0 1 .5-.5H2v-2H.5a.5.5 0 0 1-.5-.5v-3A.5.5 0 0 1 .5 6H2V4H.5a.5.5 0 0 1-.5-.5zM3 4v2h4.5V4zm5.5 0v2H13V4zM3 10v2h4.5v-2zm5.5 0v2H13v-2zM1 1v2h3.5V1zm4.5 0v2h5V1zm6 0v2H15V1zM1 7v2h3.5V7zm4.5 0v2h5V7zm6 0v2H15V7zM1 13v2h3.5v-2zm4.5 0v2h5v-2zm6 0v2H15v-2z\"/>\n      </svg>';\n        $html .= \"<div><h5 class='fw-bold mb-2 fs-5 text-body-emphasis'>Defensa</h5>\";\n        $html .= \"</div></div>\";\n        $html .= '<div class=\"progress\" role=\"progressbar\" aria-label=\"Defensa\" aria-valuenow=\"' . $this->defensa . '\" aria-valuemin=\"0\" aria-valuemax=\"100\">\n        <div class=\"progress-bar bg-warning\" style=\"width: ' . $this->defensa . '%\">' . $this->defensa . '</div></div>';\n\n        $html .= \"<div class='col d-flex align-items-start mb-0 mt-3'>\";\n        $html .= '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1.75em\" height=\"1.75em\" fill=\"currentColor\" class=\"bi bi-hurricane flex-shrink-0 me-3\" viewBox=\"0 0 16 16\">\n<path d=\"M6.999 2.6A5.5 5.5 0 0 1 15 7.5a.5.5 0 0 0 1 0 6.5 6.5 0 1 0-13 0 5 5 0 0 0 6.001 4.9A5.5 5.5 0 0 1 1 7.5a.5.5 0 0 0-1 0 6.5 6.5 0 1 0 13 0 5 5 0 0 0-6.001-4.9M10 7.5a2 2 0 1 1-4 0 2 2 0 0 1 4 0\"/>\n</svg>';\n        $html .= \"<div><h5 class='fw-bold mb-2 fs-5 text-body-emphasis'>Velocidad</h5>\";\n        $html .= \"</div></div>\";\n        $html .= '<div class=\"progress\" role=\"progressbar\" aria-label=\"Velocidad\" aria-valuenow=\"' . $this->velocidad . '\" aria-valuemin=\"0\" aria-valuemax=\"100\">\n<div class=\"progress-bar bg-info\" style=\"width: ' . $this->velocidad . '%\">' . $this->velocidad . '</div></div>';\n        $html .= \"</div><div class='card-footer'><div class='col d-flex align-items-start mb-0'>\";\n        $html .= '<svg xmlns=\"http://www.w3.org/2000/svg\" idth=\"1.75em\" height=\"1.75em\" fill=\"currentColor\" class=\"bi bi-battery-half flex-shrink-0 me-3\" viewBox=\"0 0 16 16\">\n        <path d=\"M2 6h5v4H2z\"/>\n        <path d=\"M2 4a2 2 0 0 0-2 2v4a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2zm10 1a1 1 0 0 1 1 1v4a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V6a1 1 0 0 1 1-1zm4 3a1.5 1.5 0 0 1-1.5 1.5v-3A1.5 1.5 0 0 1 16 8\"/>\n      </svg>';\n        $html .= \"<div><h5 class='fw-bold mb-0 fs-5 text-body-emphasis'>Salud</h5></div></div>\";\n        $html .= '<div class=\"progress\" role=\"progressbar\" aria-label=\"Salud\" aria-valuenow=\"' . $this->salud . '\" aria-valuemin=\"0\" aria-valuemax=\"100\">\n      <div class=\"progress-bar bg-success\" style=\"width: ' . $this->salud . '%\">' . $this->salud . '</div></div>';\n        $html .= \"</div></div>\";\n        return $html;\n    }\n    public function getNombre()\n    {\n        $html = \"<span>\";\n        $html .= '<svg xmlns=\"http://www.w3.org/2000/svg\" style=\"color:' . $this->color . '\" width=\"1em\" height=\"1em\" fill=\"currentColor\" class=\"bi bi-person-arms-up flex-shrink-0 me-3\" viewBox=\"0 0 16 16\">\n<path d=\"M8 3a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3\"/>\n<path d=\"m5.93 6.704-.846 8.451a.768.768 0 0 0 1.523.203l.81-4.865a.59.59 0 0 1 1.165 0l.81 4.865a.768.768 0 0 0 1.523-.203l-.845-8.451A1.5 1.5 0 0 1 10.5 5.5L13 2.284a.796.796 0 0 0-1.239-.998L9.634 3.84a.7.7 0 0 1-.33.235c-.23.074-.665.176-1.304.176-.64 0-1.074-.102-1.305-.176a.7.7 0 0 1-.329-.235L4.239 1.286a.796.796 0 0 0-1.24.998l2.5 3.216c.317.316.475.758.43 1.204Z\"/>\n</svg>';\n        $html .= $this->nombre;\n        $html .= '<div class=\"progress\" role=\"progressbar\" aria-label=\"Salud\" aria-valuenow=\"' . $this->salud . '\" aria-valuemin=\"0\" aria-valuemax=\"100\">\n      <div class=\"progress-bar bg-success\" style=\"width: ' . $this->salud . '%\">' . $this->salud . '</div></div></span>';\n        return $html;\n    }\n}\n\n\nfunction veintePorCiento()\n{\n    return mt_rand(1, 100) >= 20;\n}\n\nfunction turnoAtaque($i, $j)\n{\n    $html = '<br>' . $i->salud . ' <svg xmlns=\"http://www.w3.org/2000/svg\" style=\"color:' . $i->color . '\" width=\"1em\" height=\"1em\" fill=\"currentColor\" class=\"bi bi-person-arms-up flex-shrink-0 me-1\" viewBox=\"0 0 16 16\">\n    <path d=\"M8 3a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3\"/>\n    <path d=\"m5.93 6.704-.846 8.451a.768.768 0 0 0 1.523.203l.81-4.865a.59.59 0 0 1 1.165 0l.81 4.865a.768.768 0 0 0 1.523-.203l-.845-8.451A1.5 1.5 0 0 1 10.5 5.5L13 2.284a.796.796 0 0 0-1.239-.998L9.634 3.84a.7.7 0 0 1-.33.235c-.23.074-.665.176-1.304.176-.64 0-1.074-.102-1.305-.176a.7.7 0 0 1-.329-.235L4.239 1.286a.796.796 0 0 0-1.24.998l2.5 3.216c.317.316.475.758.43 1.204Z\"/>\n    </svg>';\n    $html .= $i->nombre . \" ataca - \";\n    $html .= $j->salud . ' <svg xmlns=\"http://www.w3.org/2000/svg\" style=\"color:' . $j->color . '\" width=\"1em\" height=\"1em\" fill=\"currentColor\" class=\"bi bi-person-arms-up flex-shrink-0 me-1\" viewBox=\"0 0 16 16\">\n            <path d=\"M8 3a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3\"/>\n            <path d=\"m5.93 6.704-.846 8.451a.768.768 0 0 0 1.523.203l.81-4.865a.59.59 0 0 1 1.165 0l.81 4.865a.768.768 0 0 0 1.523-.203l-.845-8.451A1.5 1.5 0 0 1 10.5 5.5L13 2.284a.796.796 0 0 0-1.239-.998L9.634 3.84a.7.7 0 0 1-.33.235c-.23.074-.665.176-1.304.176-.64 0-1.074-.102-1.305-.176a.7.7 0 0 1-.329-.235L4.239 1.286a.796.796 0 0 0-1.24.998l2.5 3.216c.317.316.475.758.43 1.204Z\"/>\n            </svg>';\n    $html .= $j->nombre . \" defiende \";\n    echo $html;\n    $t = mt_rand(1, 100);\n    if ($t >= 20) {\n        $dano = $i->ataque - $j->defensa;\n        if ($dano <= 0) {\n            $dano = $i->ataque * 0.1;\n            $dano = round($dano);\n        }\n        echo \"El ataque ha causado \" . $dano . \" de daño\";\n        return $dano;\n    } else {\n        echo \"<span class='badge text-bg-warning'>Esquiva el ataque</span>\";\n        return  0;\n    }\n}\nfunction combate($i, $j)\n{\n    while ($i->salud > 0 && $j->salud > 0) {\n        $j->salud -= turnoAtaque($i, $j);\n        if ($j->salud > 0) {\n            $i->salud -= turnoAtaque($j, $i);\n        }\n    }\n\n    return ($i->salud > 0) ? $i : $j;\n}\nfunction combates($luchadores, $numerodeluchadores)\n{\n    $html = \"<div class='row'>\";\n    for ($i = 0; $i < $numerodeluchadores; $i++) {\n        if ($i == 0) {\n            $html .= \"<div class='col-sm-3'>\";\n        }\n        if ($i == $numerodeluchadores / 2) {\n            $html .= \"</div><div class='col-sm-3 offset-sm-6'>\";\n        }\n        if ($i % 2 == 0) {\n            $html .= \"<div class='card mb-4 rounded-3 shadow-sm'><ul class='list-group'><li class='list-group-item'><h4>\" . $luchadores[$i]->getNombre() . \"</h4></li>\";\n        } else if ($i % 2 != 0 && $numerodeluchadores == 2) {\n            $html .= \"</ul></div></div><div class='col-sm-3 offset-sm-6'><div class='card mb-4 rounded-3 shadow-sm'><ul class='list-group'><li class='list-group-item'><h4>\" . $luchadores[$i]->getNombre() . \"</h4></li></ul></div>\";\n        } else {\n            $html .= \"<li class='list-group-item text-center'>VS</li><li class='list-group-item'><h4>\" . $luchadores[$i]->getNombre() . \"</h4></li></ul></div>\";\n        }\n    }\n    $html.= \"</div></div>\";\n    return $html;\n}\n?>\n<!doctype html>\n<html>\n\n<head>\n    <meta charset=\"utf-8\" />\n    <title>Torneo Dragon Ball</title>\n    <link href=\"https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css\" rel=\"stylesheet\" integrity=\"sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH\" crossorigin=\"anonymous\">\n</head>\n\n<body>\n\n    <main class=\"container\">\n        <h1>Comienza el torneo</h1>\n        <?php\n        $numerodeluchadores = pow(2, 4);\n        //Si lo queremos hacer en aleatorio\n        // for ($i = 1; $i <= $numerodeluchadores; $i++) {\n        //     $luchadores[$i] = new Luchador($i, null);\n        // }\n        $contendientes = array(\n            array(\"Goku\", 89, 85, 90),\n            array(\"Vegeta\", 92, 92, 80),\n            array(\"Trunks\", 80, 69, 81),\n            array(\"Gohan\", 75, 79, 90),\n            array(\"Krillin\", 76, 60, 65),\n            array(\"Picollo\", 75, 80, 99),\n            array(\"A17\", 92, 80, 99),\n            array(\"A18\", 79, 70, 99),\n            array(\"Ten\", 79, 60, 50),\n            array(\"Chaoz\", 30, 30, 30),\n            array(\"Yamcha\", 35, 10, 40),\n            array(\"Cabba\", 75, 86, 80),\n            array(\"Hit\", 89, 30, 99),\n            array(\"Kafla \", 99, 90, 60),\n            array(\"Satan\", 1, 1, 1),\n            array(\"Arale\", 99, 99, 20),\n            \n\n        );\n        for ($i = 1; $i <= $numerodeluchadores; $i++) {\n            $luchadores[$i] = new Luchador($i, $contendientes[$i - 1]);\n        }\n        echo \"<div class='row row-cols-sm-4 row-cols-xs-2'>\";\n        for ($i = 1; $i <= $numerodeluchadores; $i++) {\n            echo \"<div class='luchador col'>\" . $luchadores[$i]->getLuchador() . \"</div>\";\n        }\n        echo \"</div><hr>\";\n        echo \"<h2>Primera Ronda</h2>\";\n\n        do {\n            shuffle($luchadores);\n            echo combates($luchadores, $numerodeluchadores);\n            $clasificados = array();\n            for ($i = 0; $i < $numerodeluchadores; $i += 2) {\n                if ($i % 2 == 0) {\n                    if ($luchadores[$i]->velocidad >= $luchadores[$i + 1]->velocidad) {\n                        $vencedor = combate($luchadores[$i], $luchadores[$i + 1]);\n                    } else {\n                        $vencedor = combate($luchadores[$i + 1], $luchadores[$i]);\n                    }\n                }\n                echo \"<br><div class='alert alert-success'>El combate entre \" . $luchadores[$i]->nombre . \" y \" . $luchadores[$i + 1]->nombre . \" ha concluido con la victoria de <b>\" . $vencedor->nombre . \"</b></div>\";\n                $clasificados[] = $vencedor;\n            }\n            if (count($clasificados) > 1) {\n                $numerodeluchadores = count($clasificados);\n                if ($numerodeluchadores > 4) {\n                    echo \"<hr><h3>Siguiente Ronda</h3>\";\n                } else if ($numerodeluchadores == 4) {\n                    echo \"<hr><div class='alert alert-warning'><h3 class='text-center'>SEMIFINALES</h3></div>\";\n                } else {\n                    echo \"<hr><div class='alert alert-info'><h3 class='text-center'>RONDA FINAL</h3></div>\";\n                }\n                $luchadores = $clasificados;               \n            } else {\n                echo \"<hr><h3>Ganador del torneo</h3><div class='row'>\";\n                echo '<div class=\"col-sm-12 iz\">' . $clasificados[0]->getLuchador() . '</div></div>';\n            }\n        } while (count($clasificados) > 1)\n        ?>\n\n    </main>\n</body>\n\n\n</html>"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/python/CRaphaelAM.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * ¡El último videojuego de Dragon Ball ya está aquí!\n * Se llama Dragon Ball: Sparking! ZERO.\n *\n * Simula un Torneo de Artes Marciales, al más puro estilo\n * de la saga, donde participarán diferentes luchadores, y el\n * sistema decidirá quién es el ganador.\n *\n * Luchadores:\n * - Nombre.\n * - Tres atributos: velocidad, ataque y defensa\n *   (con valores entre 0 a 100 que tú decidirás).\n * - Comienza cada batalla con 100 de salud.\n * Batalla:\n * - En cada batalla se enfrentan 2 luchadores.\n * - El luchador con más velocidad comienza atacando.\n * - El daño se calcula restando el daño de ataque del\n *   atacante menos la defensa del oponente.\n * - El oponente siempre tiene un 20% de posibilidad de\n *   esquivar el ataque.\n * - Si la defensa es mayor que el ataque, recibe un 10%\n *   del daño de ataque.\n * - Después de cada turno y ataque, el oponente pierde salud.\n * - La batalla finaliza cuando un luchador pierde toda su salud.\n * Torneo:\n * - Un torneo sólo es válido con un número de luchadores\n *   potencia de 2.\n * - El torneo debe crear parejas al azar en cada ronda.\n * - Los luchadores se enfrentan en rondas eliminatorias.\n * - El ganador avanza a la siguiente ronda hasta que sólo\n *   quede uno.\n * - Debes mostrar por consola todo lo que sucede en el torneo,\n *   así como el ganador.\n */\n\"\"\"\n\nfrom __future__ import annotations\nfrom random import random,randint\nimport math\n\nclass Luchador():\n    def __init__(self,name:str,speed:float,attack:float,defense:float) -> None:\n        self._name = name\n        self._speed = speed\n        self._attack = attack\n        self._defense = defense\n        self._health = 100\n    \n    #----Getters-----\n    @property\n    def name(self)->str:\n        return self._name\n    @property\n    def speed(self)->float:\n        return self._speed\n    @property\n    def attack(self)->float:\n        return self._attack\n    @property\n    def defense(self)->float:\n        return self._defense\n    @property\n    def health(self)->float:\n        return self._health\n    \n\n    #----Setters----\n    @name.setter\n    def name(self,n_nombre:str)->None:\n        self._name = n_nombre\n    @speed.setter\n    def speed(self,n_speed:float)->None:\n        self._speed = n_speed\n    @attack.setter\n    def attack(self,n_attack:float)->None:\n        self._attack = n_attack\n    @defense.setter\n    def defense(self,n_def:float)->None:\n        self._defense = n_def\n    @health.setter\n    def health(self,n_health:float)->None:\n        self._health = n_health\n    \n\n    def Atacar(self)->float:\n        return self._attack\n    \n\n    def __str__(self)->str:\n        return self._name\n\ndef atacar(atacante:Luchador,defensor:Luchador):\n    miss = random()\n    if miss <= 0.20:\n        print(f\"{atacante} falló el ataque\")\n        return defensor.health\n    elif defensor.defense > atacante.attack:\n        damage = 0.10 * atacante.attack\n    else: damage = atacante.attack - defensor.defense\n    \n    defensor.health -= damage\n    print(f\"{defensor.name} recibio {damage} de daño, salud actual: {defensor.health}\")\n    return defensor.health\n\ndef Combate(luchador1:Luchador,luchador2:Luchador)->Luchador:\n\n    print(f\"{luchador1} vs {luchador2}\")\n    #Definir el primero en atacar\n    #Reglas: Primero ataca el que más velocidad tenga, si tienen igual velocidad\n    #voy a generar un número aleatorio entre 1 y 10, si el número <5 ataca primero el 1 y viceversa\n    end = False\n    coin = randint(1,10)\n    \n    if luchador1.speed > luchador2.speed or (luchador1.speed == luchador2.speed and coin <=5):\n        while not end:\n            luchador2.health = atacar(luchador1,luchador2)\n            if luchador2.health <= 0:\n                winner = luchador1\n                break\n            luchador1.health = atacar(luchador2,luchador1)\n            if luchador1.health <= 0:\n                winner = luchador2\n                break\n    else: \n        while not end:\n            luchador1.health = atacar(luchador2,luchador1)\n            if luchador1.health <= 0:\n                winner = luchador2\n                break\n            luchador2.health = atacar(luchador1,luchador2)\n            if luchador2.health <= 0:\n                winner = luchador1\n                break\n    print(f\"El ganador de la ronda es: {winner}\")\n    winner.health = 100\n    return winner\n\n\ndef Torneo(Luchadores):\n\n    end = False\n\n    while not end:\n        cant_luchadores = len(Luchadores)\n        cant_grupos = math.log2(cant_luchadores)\n        cursor = 0\n        grupos = []\n        winners = []\n        for n in range(int(cant_grupos)):\n            grupos.append([Luchadores[cursor],Luchadores[cursor+1]])\n            cursor += 2\n        for n in range(int(cant_grupos)):\n            winners.append(Combate(grupos[n][0],grupos[n][1]))\n        Luchadores = winners[::]\n        if len(Luchadores) == 1:\n            end = True\n        \n\n    \n    print(f\"El ganador del torneo es {Luchadores[0]}\")\n\ndef main():\n    \n    fighter1 = Luchador(\"A\",40,80,20)\n    fighter2 = Luchador(\"B\",70,90,10)\n    fighter3 = Luchador(\"C\",20,70,40)\n    fighter4 = Luchador(\"D\",50,50,50)\n    pausa = input(\"pausa\")\n    Luchadores = [fighter1,fighter2,fighter3,fighter4]\n\n    Torneo(Luchadores)\n\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/python/CarlosVR48.py",
    "content": "import random\n\n\"\"\"\nEJERCICIO:\n * ¡El último videojuego de Dragon Ball ya está aquí!\n * Se llama Dragon Ball: Sparking! ZERO.\n *\n * Simula un Torneo de Artes Marciales, al más puro estilo\n * de la saga, donde participarán diferentes luchadores, y el\n * sistema decidirá quién es el ganador.\n *\n * Luchadores:\n * - Nombre.\n * - Tres atributos: velocidad, ataque y defensa\n *   (con valores entre 0 a 100 que tú decidirás).\n * - Comienza cada batalla con 100 de salud.\n * Batalla:\n * - En cada batalla se enfrentan 2 luchadores.\n * - El luchador con más velocidad comienza atacando.\n * - El daño se calcula restando el daño de ataque del\n *   atacante menos la defensa del oponente.\n * - El oponente siempre tiene un 20% de posibilidad de\n *   esquivar el ataque.\n * - Si la defensa es mayor que el ataque, recibe un 10%\n *   del daño de ataque.\n * - Después de cada turno y ataque, el oponente pierde salud.\n * - La batalla finaliza cuando un luchador pierde toda su salud.\n * Torneo:\n * - Un torneo sólo es válido con un número de luchadores\n *   potencia de 2.\n * - El torneo debe crear parejas al azar en cada ronda.\n * - Los luchadores se enfrentan en rondas eliminatorias.\n * - El ganador avanza a la siguiente ronda hasta que sólo\n *   quede uno.\n * - Debes mostrar por consola todo lo que sucede en el torneo,\n *   así como el ganador.\"\"\"\n\n\n\"\"\"\nYamcha , Jackie Chun , Krilin , Bacterian\nGiran , Son Goku , Ranfan , Namu\n\"\"\"\ndef esquivar_20(velocidad):\n    # Calculamos numero entre 0 y 100. Como el 20% de 100 es 20 , si el numero que tiene esquivar_20 es menor\n    # o igual a 20 , entoces esquiva el golpe. Retornamos un True\n    esquivar_20 = random.randint(0,100)\n    if esquivar_20 <= 20:\n        return True\n    else:\n        return False\n\ndef luchar_1(tatami1_1,tatami1_2,tatami):\n    # recupero la salud y la velocidad de los datos el diccionario, de cada luchador\n    salud1 = int(luchadores[tatami1_1].get(\"Salud\"))\n    salud2 = int(luchadores[tatami1_2].get(\"Salud\"))\n    velocidad1 = luchadores[tatami1_1].get(\"Velocidad\")\n    velocidad2 = luchadores[tatami1_2].get(\"Velocidad\")\n    \n    print (f\"\\nTATAMI {tatami}:\\n {luchadores[tatami1_1].get(\"Nombre\")} contra {luchadores[tatami1_2].get(\"Nombre\")}\")\n    print (f\" SALUD: {salud1}      SALUD: {salud2}\")\n\n    # el ataque primero es dependido de mayor velocidad\n    if velocidad1 > velocidad2:\n        primero = 1\n        # Hay un 20% de posibilidades de esquivar el ataque con la velocidad del defensor.\n        # True se guarda en esquivar si el 20% de velocidad es mayor a un numero aleatorio de velocidad\n        esquivar = esquivar_20(velocidad2)\n\n        if esquivar == False:\n            # Si la defensa es mayor que el ataque se calculara un 10% de daño \n            if (luchadores[tatami1_2].get(\"Defensa\")) > (luchadores[tatami1_1].get(\"Ataque\")):\n                salud2 = int(salud2 - -((luchadores[tatami1_1].get(\"Ataque\") -  luchadores[tatami1_2].get(\"Defensa\"))*10)/100)\n                print (f\"\\n {luchadores[tatami1_1].get(\"Nombre\")} GOLPEA A {luchadores[tatami1_2].get(\"Nombre\")}\")\n            else:    \n                salud2 = int(salud2 - (luchadores[tatami1_1].get(\"Ataque\") -  luchadores[tatami1_2].get(\"Defensa\")))\n                print (f\"\\n {luchadores[tatami1_1].get(\"Nombre\")} GOLPEA A {luchadores[tatami1_2].get(\"Nombre\")}\")\n        else:\n            print (f\"\\n  {luchadores[tatami1_2].get(\"Nombre\")} ESQUIVA EL GOLPE\")            \n\n    else:\n        primero = 2\n        esquivar = esquivar_20(velocidad1)\n        \n        if esquivar == False:\n            if (luchadores[tatami1_1].get(\"Defensa\")) > (luchadores[tatami1_2].get(\"Ataque\")):\n                salud1 = int(salud1 - -((((luchadores[tatami1_2].get(\"Ataque\") -  luchadores[tatami1_1].get(\"Defensa\")))*10)/100))\n                print (f\"\\n {luchadores[tatami1_2].get(\"Nombre\")} GOLPEA A {luchadores[tatami1_1].get(\"Nombre\")}\")\n            else:    \n                salud1 = int(salud1 - (luchadores[tatami1_2].get(\"Ataque\") -  luchadores[tatami1_1].get(\"Defensa\")))\n                print (f\"\\n {luchadores[tatami1_2].get(\"Nombre\")} GOLPEA A {luchadores[tatami1_1].get(\"Nombre\")}\")\n        else:\n            print (f\"\\n {luchadores[tatami1_1].get(\"Nombre\")} ESQUIVA EL GOLPE\") \n    \n    print (f\"\\n {luchadores[tatami1_1].get(\"Nombre\")}--------{luchadores[tatami1_2].get(\"Nombre\")}\")\n    print (f\" SALUD: {salud1}      SALUD: {salud2}\")\n    #el valor de salud cambia y lo escribo en cada valor asignado\n    luchadores[tatami1_1][\"Salud\"]=salud1\n    luchadores[tatami1_2][\"Salud\"]=salud2\n    return primero\n\ndef luchar_2(primero,tatami1_1,tatami1_2):\n    ronda = int()\n    salud1 = int(luchadores[tatami1_1].get(\"Salud\"))\n    salud2 = int(luchadores[tatami1_2].get(\"Salud\"))\n    #bucle repetitivo asta que el valor de salud de un luchador es igual o menor que 0\n    while True:\n        velocidad1 = luchadores[tatami1_1].get(\"Velocidad\")\n        velocidad2 = luchadores[tatami1_2].get(\"Velocidad\")\n        \n        if primero == 1:\n            if salud2<=0:\n                #asigno al ganador 100 de salud\n                luchadores[tatami1_1][\"Salud\"] = 100\n                ronda=tatami1_1\n                break\n            esquivar = esquivar_20(velocidad1)\n            primero = 2\n            if esquivar == False:\n                if (luchadores[tatami1_1].get(\"Defensa\")) > (luchadores[tatami1_2].get(\"Ataque\")):\n                    print (f\"\\n {luchadores[tatami1_2].get(\"Nombre\")} GOLPEA A {luchadores[tatami1_1].get(\"Nombre\")}\")\n                    salud1 = int(salud1 - -((((luchadores[tatami1_2].get(\"Ataque\") -  luchadores[tatami1_1].get(\"Defensa\")))*10)/100))\n                else:    \n                    print (f\"\\n {luchadores[tatami1_2].get(\"Nombre\")} GOLPEA A {luchadores[tatami1_1].get(\"Nombre\")}\")\n                    salud1 = int(salud1 - (luchadores[tatami1_2].get(\"Ataque\") -  luchadores[tatami1_1].get(\"Defensa\")))\n            else:\n                print (f\"\\n {luchadores[tatami1_1].get(\"Nombre\")} ESQUIVA EL GOLPE\")\n        else:   \n            if salud1<=0:\n                luchadores[tatami1_2][\"Salud\"] = 100\n                ronda=tatami1_2\n                break\n            primero = 1\n            esquivar = esquivar_20(velocidad2)\n\n            if esquivar == False:\n                #Si la defensa es mayor que el ataque se calculara un 10% de daño \n                if (luchadores[tatami1_2].get(\"Defensa\")) > (luchadores[tatami1_1].get(\"Ataque\")):\n                    print (f\"\\n {luchadores[tatami1_1].get(\"Nombre\")} GOLPEA A {luchadores[tatami1_2].get(\"Nombre\")}\")\n                    salud2 = int(salud2 - -((luchadores[tatami1_1].get(\"Ataque\") -  luchadores[tatami1_2].get(\"Defensa\"))*10)/100)\n                else:    \n                    print (f\"\\n {luchadores[tatami1_1].get(\"Nombre\")} GOLPEA A {luchadores[tatami1_2].get(\"Nombre\")}\")\n                    salud2 = int (salud2 - (luchadores[tatami1_1].get(\"Ataque\") -  luchadores[tatami1_2].get(\"Defensa\")))\n            else:\n                print (f\"\\n {luchadores[tatami1_2].get(\"Nombre\")} ESQUIVA EL GOLPE\") \n        \n        print (f\"\\n {luchadores[tatami1_1].get(\"Nombre\")}--------{luchadores[tatami1_2].get(\"Nombre\")}\")\n        print (f\" SALUD: {salud1}      SALUD: {salud2}\")\n    return ronda\n\nluchadores = [\n            {\"Nombre\":\"Son Goku\",\"Velocidad\": 95,\"Ataque\": 95,\"Defensa\": 91,\"Salud\": 100},\n            {\"Nombre\":\"Jackie Chun\",\"Velocidad\": 90,\"Ataque\": 95,\"Defensa\": 96,\"Salud\": 100},\n            {\"Nombre\":\"Yamcha\",\"Velocidad\": 92,\"Ataque\": 86,\"Defensa\": 85,\"Salud\": 100},\n            {\"Nombre\":\"Krilin\",\"Velocidad\": 88,\"Ataque\": 89,\"Defensa\": 93,\"Salud\": 100},\n            {\"Nombre\":\"Bacterian\",\"Velocidad\": 77,\"Ataque\": 95,\"Defensa\": 89,\"Salud\": 100},\n            {\"Nombre\":\"Giran\",\"Velocidad\": 77,\"Ataque\": 82,\"Defensa\": 88,\"Salud\": 100},\n            {\"Nombre\":\"Ranfan\",\"Velocidad\": 89,\"Ataque\": 88,\"Defensa\": 93,\"Salud\": 100},\n            {\"Nombre\":\"Namu\",\"Velocidad\": 69,\"Ataque\": 81,\"Defensa\": 92,\"Salud\": 100}]\n\n#en estas listas se insertaran los ganadores de cada ronda\nronda2 = []\nronda3 = []\nronda4 = []\n# creo una lista numerada con todo los participantes\nlista = [0,1,2,3,4,5,6,7]\n# Desordeno la lista para luego crear el soteo \nrandom.shuffle(lista)\n\ntatami1_1 = lista[0] \ntatami1_2 = lista[1] \ntatami2_1 = lista[2]\ntatami2_2 = lista[3]\ntatami3_1 = lista[4]\ntatami3_2 = lista[5]\ntatami4_1 = lista[6]\ntatami4_2 = lista[7]\n\nprint(\"                                               ------- GRAN TORNEO DE ARTES MARCIALES -------\\n\")\n\n# Muestra todos los participantes y su ficha\nfor index in luchadores:\n    print (index)\ninput(\"PULSA ENTER PARA CONTINUAR\")\n\n#llamamos a la funcion que se encarga de que luche primero el de mayor velocidad y asigna a primero el que ya ha dado golpe\ntatami=1\nprimero = luchar_1(tatami1_1,tatami1_2,tatami)\ninput(\"PULSA ENTER PARA CONTINUAR\")\n#una vez tenemos la sequencia de lucha guardada en la variable primero, continuamos y se guarda el ganador ronda2(lista)\nronda = luchar_2(primero,tatami1_1,tatami1_2)\nronda2.append(ronda)\nluchador = ronda\nprint (f\"\\n--- EL GANADOR ES {luchadores[luchador].get(\"Nombre\")} ---\")\ninput(\"PULSA ENTER PARA CONTINUAR\")\n\ntatami = 2\nprimero = luchar_1(tatami2_1,tatami2_2,tatami)\ninput(\"PULSA ENTER PARA CONTINUAR\")\nronda = luchar_2(primero,tatami2_1,tatami2_2)\nronda2.append(ronda)\nluchador = ronda\nprint (f\"\\n--- EL GANADOR ES {luchadores[luchador].get(\"Nombre\")} ---\")\ninput(\"PULSA ENTER PARA CONTINUAR\")\n\ntatami = 3\nprimero = luchar_1(tatami3_1,tatami3_2,tatami)\ninput(\"PULSA ENTER PARA CONTINUAR\")\nronda = luchar_2(primero,tatami3_1,tatami3_2)\nronda2.append(ronda)\nluchador = ronda\nprint (f\"\\n--- EL GANAADOR ES {luchadores[luchador].get(\"Nombre\")} ---\")\ninput(\"PULSA ENTER PARA CONTINUAR\")\n\ntatami = 4\nprimero = luchar_1(tatami4_1,tatami4_2,tatami)\ninput(\"PULSA ENTER PARA CONTINUAR\")\nronda = luchar_2(primero,tatami4_1,tatami4_2)\nronda2.append(ronda)\nluchador = ronda\nprint (f\"\\n--- EL GANADOR ES {luchadores[luchador].get(\"Nombre\")} ---\\n\")\ninput(\"PULSA ENTER PARA CONTINUAR\")\nprint (f\"\\n- CLASIFICADOS PARA LA SEMIFINAL:\\n    {luchadores[ronda2[0]].get(\"Nombre\")}\\n    {luchadores[ronda2[1]].get(\"Nombre\")}\\n    {luchadores[ronda2[2]].get(\"Nombre\")}\\n    {luchadores[ronda2[3]].get(\"Nombre\")} \\n\")\n\n# Semifinal\n# Ahora es una lucha de 4 participante y todo es igual que lo anterior\nfor index in ronda2:\n    print(luchadores[index])\n\ninput(\"PULSA ENTER PARA CONTINUAR\")    \ntatami1_1 = ronda2 [0]\ntatami1_2 = ronda2 [1]\ntatami2_1 = ronda2 [2]\ntatami2_2 = ronda2 [3]\n\ntatami = 1\nprimero = luchar_1(tatami1_1,tatami1_2,tatami)\ninput(\"PULSA ENTER PARA CONTINUAR\")\nronda = luchar_2(primero,tatami1_1,tatami1_2)\nronda3.append(ronda)\nluchador_semifinal = ronda\nprint (f\"\\n--- EL GANADOR ES {luchadores[luchador_semifinal].get(\"Nombre\")} ---\")\ninput(\"PULSA ENTER PARA CONTINUAR\")\n\ntatami = 2\nprimero = luchar_1(tatami2_1,tatami2_2,tatami)\ninput(\"PULSA ENTER PARA CONTINUAR\")\nronda = luchar_2(primero,tatami2_1,tatami2_2)\nronda3.append(ronda)\nluchador_semifinal = ronda\nprint (f\"\\n--- EL GANADOR ES {luchadores[luchador_semifinal].get(\"Nombre\")} ---\")\ninput(\"PULSA ENTER PARA CONTINUAR\")\nprint (f\"\\n- CLASIFICADOS PARA LA FINAL:\\n    {luchadores[ronda3[0]].get(\"Nombre\")}\\n    {luchadores[ronda3[1]].get(\"Nombre\")}\\n\") \n\n# Final \nfor index in ronda3:\n    print(luchadores[index])\n\ninput(\"PULSA ENTER PARA CONTINUAR\")\n    \ntatami1_1 = ronda3 [0]\ntatami1_2 = ronda3 [1]\n\ntatami = 1\nprimero = luchar_1(tatami1_1,tatami1_2,tatami)\ninput(\"PULSA ENTER PARA CONTINUAR\")\nronda = luchar_2(primero,tatami1_1,tatami1_2)\nronda4.append(ronda)\nluchador_final = ronda\nprint (f\"\\n---EL VENCEDOR DEL GRAN TORNEO DE ARTES MARCIALES ES {luchadores[luchador_final].get(\"Nombre\")}!!!!! ---\")\ninput(\"PULSA ENTER PARA CONTINUAR\")"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/python/EmmanuelMMontesinos.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * ¡El último videojuego de Dragon Ball ya está aquí!\n * Se llama Dragon Ball: Sparking! ZERO.\n *\n * Simula un Torneo de Artes Marciales, al más puro estilo\n * de la saga, donde participarán diferentes luchadores, y el\n * sistema decidirá quién es el ganador.\n *\n * Luchadores:\n * - Nombre.\n * - Tres atributos: velocidad, ataque y defensa\n *   (con valores entre 0 a 100 que tú decidirás).\n * - Comienza cada batalla con 100 de salud.\n * Batalla:\n * - En cada batalla se enfrentan 2 luchadores.\n * - El luchador con más velocidad comienza atacando.\n * - El daño se calcula restando el daño de ataque del\n *   atacante menos la defensa del oponente.\n * - El oponente siempre tiene un 20% de posibilidad de\n *   esquivar el ataque.\n * - Si la defensa es mayor que el ataque, recibe un 10%\n *   del daño de ataque.\n * - Después de cada turno y ataque, el oponente pierde salud.\n * - La batalla finaliza cuando un luchador pierde toda su salud.\n * Torneo:\n * - Un torneo sólo es válido con un número de luchadores\n *   potencia de 2.\n * - El torneo debe crear parejas al azar en cada ronda.\n * - Los luchadores se enfrentan en rondas eliminatorias.\n * - El ganador avanza a la siguiente ronda hasta que sólo\n *   quede uno.\n * - Debes mostrar por consola todo lo que sucede en el torneo,\n *   así como el ganador.\n */\n\"\"\"\n\nimport random\n\nclass Luchador:\n    def __init__(self, nombre, velocidad, ataque, defensa):\n        self.nombre = nombre\n        self.velocidad = velocidad\n        self.ataque = ataque\n        self.defensa = defensa\n        self.salud = 100\n        self.descripcion_ataque = [\n            \"Patada Baja\",\n            \"Patada Media\",\n            \"Patada Alta\",\n            \"Golpe Lateral\",\n            \"Puñetazo\",\n            \"Rafaga de Golpes\",\n            \"Bola de Ki\",\n            \"Tactica especial\",\n        ]\n\n    def __str__(self) -> str:\n        return f\"{self.nombre} - Salud: {self.salud}\\n(Velocidad: {self.velocidad}, Ataque: {self.ataque}, Defensa: {self.defensa})\"\n\n    def atacar(self, oponente):\n        if random.randint(1,101) < 20:\n            print(f\"{oponente.nombre} esquiva el ataque de {self.nombre}\")\n        else:\n            if self.ataque > oponente.defensa:\n                damage = self.ataque - oponente.defensa\n                oponente.salud -= damage\n            \n            else:\n                print(f\"{oponente.nombre} ha recibido 10% de daño\")\n                damage = self.ataque * 0.1\n                oponente.salud -= damage\n        \n            print(f\"{oponente.nombre} ha recibido {damage} de daño por {random.choice(self.descripcion_ataque)} de {self.nombre}\\n\")\n    \n\nclass Torneo:\n\n    def __init__(self,lista_luchadores):\n        random.shuffle(lista_luchadores)\n        self.lista_luchadores = lista_luchadores\n        self.nombre = \" Torneo Dragon Ball: Sparking! ZERO\"\n        self.edicion = 1\n        self.grupo_1 = []\n        self.grupo_2 = []\n        self.eliminados = []\n        self.ganadores = {}\n        self.rondas = {\n            1: \"Final\",\n            2: \"Semifinal\",\n            4: \"Cuartos de final\",\n            8: \"Octavos de final\",\n        }\n    def __str__(self) -> str:\n        return f\"{self.nombre} - Edicion: {self.edicion}\\nLuchadores inscritos: {len(self.lista_luchadores)}\\n{[luchador.nombre for luchador in self.lista_luchadores]}\"\n\n    def iniciar_torneo(self):\n        num_luchadores = len(self.lista_luchadores)\n\n        if num_luchadores % 2 == 0:\n            print(\"-\"*20)\n            print(\"Iniciando torneo...\")\n\n            if num_luchadores > 16:\n                print(\"Hay demasiados luchadores, solo son seleccionados los primeros 16 inscritos.\")\n                self.lista_luchadores = self.lista_luchadores[:15]\n            elif num_luchadores <= 0:\n                print(\"No hay luchadores inscritos\")\n                return False\n\n            \n\n            for luchador in range(0, len(self.lista_luchadores), 2):\n                self.grupo_1.append(self.lista_luchadores[luchador])\n                self.grupo_2.append(self.lista_luchadores[luchador+1])\n\n            print()\n            print(f\"Grupo 1: {[luchador.nombre for luchador in self.grupo_1]}\")\n            print(\"-\"*20)\n            print(f\"Grupo 2: {[luchador.nombre for luchador in self.grupo_2]}\\n\")\n\n            self.bucle()\n    def ronda(self, grupo, nombre_grupo):\n        clase_ronda = self.rondas[len(grupo)] if nombre_grupo != 'Finalistas' else 'Final'\n        grupo_ronda = grupo.copy()\n        random.shuffle(grupo_ronda)\n        print(nombre_grupo)\n        for luchador in range(0, len(grupo_ronda), 2):\n            luchador_1 = grupo[luchador]\n            luchador_2 = grupo[luchador+1]\n            primero, segundo = (luchador_1, luchador_2) if luchador_1.velocidad > luchador_2.velocidad else (luchador_2, luchador_1)\n\n            print(f\"{primero.nombre} vs. {segundo.nombre}\")\n            print(\"-\"*20)\n\n            ronda = 0\n            while primero.salud >= 1 and segundo.salud >= 1:\n                ronda += 1\n                print(\"-\"*20)\n                print(f\"Ronda: {ronda}\")\n                print(f\"Vida de {luchador_1.nombre}: {luchador_1.salud} | Velocidad: {luchador_1.velocidad} | Ataque: {luchador_1.ataque} | Defensa: {luchador_1.defensa}\") \n                print(f\"Vida de {luchador_2.nombre}: {luchador_2.salud} | Velocidad: {luchador_2.velocidad} | Ataque: {luchador_2.ataque} | Defensa: {luchador_2.defensa}\\n\")\n                primero.atacar(segundo)\n                if segundo.salud <= 0:\n                    break\n                segundo.atacar(primero)\n                print(f\"Vida de {luchador_1.nombre}: {luchador_1.salud}\")\n                print(f\"Vida de {luchador_2.nombre}: {luchador_2.salud}\\n\")\n\n            perdedor = luchador_1 if luchador_1.salud < luchador_2.salud else luchador_2\n            ganador = luchador_1 if luchador_1.salud > luchador_2.salud else luchador_2\n            print(f\"{ganador.nombre} ha ganado la pelea de {clase_ronda} del {nombre_grupo}\")\n            self.eliminados.append(perdedor)\n            grupo_ronda.remove(perdedor)\n            \n        return grupo_ronda\n\n    def bucle(self):\n        while len(self.grupo_1) >= 2 and len(self.grupo_2) >= 2:\n            print(\"-\"*20)\n            print(f\"Ronda: {self.rondas[len(self.grupo_1)]}\\n\")\n            \n            self.grupo_1 = self.ronda(self.grupo_1, \"Grupo 1\")\n            self.grupo_2 = self.ronda(self.grupo_2, \"Grupo 2\")\n            print(\"-\"*20)\n            print(f\"Clasificando Grupo 1: {[luchador.nombre for luchador in self.grupo_1]}\")\n            print(f\"Clasificando Grupo 2: {[luchador.nombre for luchador in self.grupo_2]}\")\n            print(f\"Eliminados: {[luchador.nombre for luchador in self.eliminados]}\\n\")\n            print(\"-\"*20)\n\n        print(f\"Combate final entre {self.grupo_1[0].nombre} y {self.grupo_2[0].nombre}\")\n        finalistas = [self.grupo_1[0], self.grupo_2[0]]\n        self.ronda(finalistas, \"Finalistas\")\n        print(\"-\"*20)\n        print(f\"El ganador del torneo nº {self.edicion} es: {finalistas[0].nombre}\")\n        self.ganadores[self.edicion] = finalistas[0].nombre\n        self.edicion += 1\n\n\n            \n\n# Prueba\ngoku = Luchador(\"Goku\", 100, 100, 100)\ngohan = Luchador(\"Gohan\", 90, 90, 90)\nvegeta = Luchador(\"Vegeta\", 80, 80, 80)\npicolo = Luchador(\"Picolo\", 70, 70, 70)\nyamcha = Luchador(\"Yamcha\", 60, 60, 60)\nkrilin = Luchador(\"Krilin\", 50, 50, 50)\nfreezer = Luchador(\"Freezer\", 40, 40, 40)\ncell = Luchador(\"Cell\", 30, 30, 30)\n\nprint(goku)\nprint(gohan)\nprint(vegeta)\nprint(picolo)\n\ntorneo = Torneo([goku, gohan, vegeta, picolo, yamcha, krilin, freezer, cell])\nprint(torneo)\n\ntorneo.iniciar_torneo()"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/python/Gordo-Master.py",
    "content": "# 42 - Torneo de Dragon Ball\nimport random\n\ndef is_pow(a: int, b: int):\n    if a < 1 or b < 1:\n        return False\n    if b == 1:\n        return a == 1\n    \n    while a % b == 0:\n        a = a // b\n    return a == 1\n\ndef append_two(elements: list):\n    groups = []\n    for i in range(0,len(elements),2):\n        group = elements[i:i+2]\n        groups.append(group)\n    return groups\n\n\nclass Figther:\n\n    def __init__(self, name: str, attack: int, defense: int, speed: int):\n        self.name = name\n        self.attack = attack\n        self.defense = defense\n        self.speed = speed\n        self.health = 100\n        self.dodge_chance = 20\n\nclass Duel:\n\n    def show_hp(self, figther1: Figther):\n        print(f\"{figther1.name} tiene {figther1.health} HP\")\n\n    def round_duel(self, attacker: Figther, defender: Figther): # Aca esta la logica de como se comporta en cada round las interacciones\n        damage = attacker.attack - defender.defense\n        if damage <= 0: \n                damage = int(0.1 * attacker.attack)\n        if random.random() > (defender.dodge_chance / 100):  # Si esquiva\n            defender.health -= damage\n            print(f\"{attacker.name} ha hecho {damage} daño a {defender.name}\")\n        else:\n            print(f\"{defender.name} ha esquivado el ataque!\")\n        self.show_hp(defender)\n\n    def duel(self, figther1 : Figther, figther2 : Figther): # Este seria el conjunto de rounds hasta que se determine un ganador\n        figther1.health = 100\n        figther2.health = 100\n        print(f\"Combate: {figther1.name}({figther1.health}) VS {figther2.name}({figther2.health})\")\n        count = 0\n        while True:\n            if figther1.speed > figther2.speed:\n                attacker = figther1\n                defender = figther2\n            elif figther2.speed > figther1.speed:\n                attacker = figther2\n                defender = figther1\n            else:\n                aux_list = [figther1, figther2]\n                random.shuffle(aux_list)\n                attacker, defender = aux_list\n            count += 1\n            print(f\"\\nRonda {count}\")\n            self.round_duel(attacker, defender)\n            if defender.health <= 0:\n                print(f\"{defender.name} ya no puede continuar!\")\n                print(f\"El ganador es {attacker.name}!!\")\n                return attacker\n            count += 1\n            print(f\"\\nRonda {count}\")\n            self.round_duel(defender,attacker)\n            if attacker.health <= 0:\n                print(f\"{attacker.name} ya no puede continuar!\")\n                print(f\"El ganador es {defender.name}!!\")\n                return defender\n\n\nclass Tournament:\n\n\n    def matches(self, *figthers): # Logica del sorteo de los participantes\n        if len(figthers) == 1 :\n            print(f\"Enhorabuena, tenemos un ganador: {figthers[0].name}!!!\")\n            return\n        \n        winner_list = []\n        if not is_pow(len(figthers),2) :\n            print(\"Cantidad de participante incorrecto. \\nSe deben registra cantidades potencia de 2. \\nEj: 2, 4, 8, 16, etc\")\n            return\n        else:\n            figthers_list = list(figthers)\n            random.shuffle(figthers_list)\n            figthers_list = append_two(figthers_list)\n            for two_f in figthers_list:\n                winner = Duel().duel(two_f[0], two_f[1])\n                winner_list.append(winner)\n                input(\"Para mostrar el siguiente duelo, presione enter\")\n            self.matches(*winner_list)\n\n\nandroid17 = Figther(\"Andoide 17\", 87, 80, 80)\ntrunks = Figther(\"Trunks\", attack=85, defense=75, speed=80)\nyamcha = Figther(\"Yamcha\", 50, 50, 50)\ngoku = Figther(\"Goku\", attack=95, defense=85, speed=90)\nvegeta = Figther(\"Vegeta\", attack=90, defense=80, speed=85)\ngohan = Figther(\"Gohan\", attack=88, defense=82, speed=87)\npiccolo = Figther(\"Piccolo\", attack=80, defense=88, speed=70)\nfrieza = Figther(\"Frieza\", attack=92, defense=78, speed=86)\ncell = Figther(\"Cell\", attack=89, defense=83, speed=82)\nmajin_buu = Figther(\"Majin Buu\", attack=87, defense=90, speed=65)\n\ntorneo_artes_marciales = Tournament()\n\ntorneo_artes_marciales.matches(goku, vegeta, gohan, piccolo, yamcha, frieza, cell, majin_buu)"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/python/JesusWay69.py",
    "content": "import os, platform, random\n\nif (platform.platform().startswith(\"macOS\") or platform.platform().startswith(\"Linux\")):\n    os.system('clear')\nelse:\n    os.system('cls')\n\n\"\"\" * EJERCICIO:\n * ¡El último videojuego de Dragon Ball ya está aquí!\n * Se llama Dragon Ball: Sparking! ZERO.\n *\n * Simula un Torneo de Artes Marciales, al más puro estilo\n * de la saga, donde participarán diferentes luchadores, y el\n * sistema decidirá quién es el ganador.\n *\n * Luchadores:\n * - Nombre.\n * - Tres atributos: velocidad, ataque y defensa\n *   (con valores entre 0 a 100 que tú decidirás).\n * - Comienza cada batalla con 100 de salud.\n * Batalla:\n * - En cada batalla se enfrentan 2 luchadores.\n * - El luchador con más velocidad comienza atacando.\n * - El daño se calcula restando el daño de ataque del\n *   atacante menos la defensa del oponente.\n * - El oponente siempre tiene un 20% de posibilidad de\n *   esquivar el ataque.\n * - Si la defensa es mayor que el ataque, recibe un 10%\n *   del daño de ataque.\n * - Después de cada turno y ataque, el oponente pierde salud.\n * - La batalla finaliza cuando un luchador pierde toda su salud.\n * Torneo:\n * - Un torneo sólo es válido con un número de luchadores\n *   potencia de 2.\n * - El torneo debe crear parejas al azar en cada ronda.\n * - Los luchadores se enfrentan en rondas eliminatorias.\n * - El ganador avanza a la siguiente ronda hasta que sólo\n *   quede uno.\n * - Debes mostrar por consola todo lo que sucede en el torneo,\n *   así como el ganador.\"\"\"\n\nclass Character:\n    def __init__(self, items) -> None:\n        self.items = items\n    def __getitem__(self, index):\n        return self.items[index]\n\nson_goku = Character([\"Son Goku\", 83, 69, 54])\nvegeta = Character([\"Vegeta\", 78, 77, 49])\nson_gohan = Character([\"Son Gohan\", 76, 59, 50])\ntrunks = Character([\"Trunks\", 77, 61, 39])\nfreezer = Character([\"Freezer\", 73, 69, 41])\npiccolo = Character([\"Piccolo\", 87, 55, 32])\nkrilin = Character([\"Krilin\", 49, 78, 25])\nbulma = Character([\"Bulma\", 66, 56, 44])\ncell = Character([\"Cell\", 59, 80, 22])\nbroly = Character([\"Broly\", 70, 52, 29])\nkame_sennin = Character([\"Kame Sennin\", 83, 48, 33])\nten_shin_han = Character([\"Ten Shin Han\", 67, 59, 31])\nraditz = Character([\"Raditz\", 59, 77, 18])\nbeerus = Character([\"Beerus\", 63, 80, 15])\nkaio = Character([\"Kaiõ\", 71, 52, 39])\nmr_satan = Character([\"Mr. Satán\", 80, 51, 36])\nzamasu = Character([\"Zamasu\", 69, 71, 43])\nyamcha = Character([\"Yamcha\", 72, 59, 29])\nmajin_boo = Character([\"Majin Boo\", 70, 49, 45])\nvegetto = Character([\"Vegetto\", 82, 54, 37])#20\nandroide_n_17 = Character([\"Androide nº17\", 58, 84, 12])\ngotenks = Character([\"Gotenks\", 81, 52, 35])\nbardock = Character([\"Bardock\", 76, 59, 30])\nwhis = Character([\"Whis\", 52, 73, 23])\nchi_chi = Character([\"Chi-Chi\", 56, 86, 20])\nshenlong = Character([\"Shenlong\", 58, 80, 26])\nyamoshi = Character([\"Yamoshi\", 68, 50, 48])\nvidel = Character([\"Videl\", 81, 52, 46])\nnappa = Character([\"Nappa\", 75, 51, 42])\nbra = Character([\"Bra\", 81, 54, 39])\ndabra = Character([\"Dabra\", 53, 87, 16])\njeice = Character([\"Jeice\", 80, 58, 45])\n\ncharacters = [son_goku, vegeta, son_gohan, trunks, freezer, piccolo, krilin, bulma, cell, broly,\n              kame_sennin, ten_shin_han, raditz, beerus, kaio, mr_satan, zamasu, yamcha, majin_boo,\n              vegetto, androide_n_17, gotenks, bardock, whis, chi_chi, shenlong, yamoshi, videl, \n              nappa, bra, dabra, jeice]\n\ndef couples(characters:list)->list:\n    tournament_list = []\n    random.shuffle(characters)\n    counter = 0\n    for i in range (len(characters)//2):\n        tournament_list.append([])\n        tournament_list[i].append(characters[counter])\n        tournament_list[i].append(characters[counter+1])\n        counter += 2\n    return tournament_list\n\ndef show_battles(tournament:list):\n    for battle in tournament:\n        print(f\"{battle[0][0]} ---VS--- {battle[1][0]}\") \n\ndef fight1vs1(fighter1:object, fighter2:object)->object:\n    score1, score2 = 100, 100\n    damage1, damage2 = 0, 0\n    power1, shield1 = int(fighter1[2]), int(fighter1[3])\n    power2, shield2 = int(fighter2[2]), int(fighter2[3])\n    print(f\"\\nBatalla entre {fighter1[0]} y {fighter2[0]}\")\n    print(\"--------------------------------------------\")\n    print(f\"Ataca primero {fighter1[0] if fighter1[1] >= fighter2[1] else fighter2[0]}\\n\")\n    while score1 > 0 and score2 > 0:\n        if fighter1[1] >= fighter2[1]:\n\n            if power1 >= shield2:\n\n                if random.random() > 0.2:\n                    damage2 = power1 - shield2\n                    score2 -= damage2\n                    print(f\"-El ataque de {fighter1[0]} le resta {damage2} puntos a {fighter2[0]}\", end=\" \")\n\n                    if score2 < 0: score2 = 0\n                    print(f\"que se queda con {score2} puntos\")\n                    damage2 = 0\n\n                    if score2 <= 0:\n                        print(f\"\\nEl ganador de la batalla es {fighter1[0]}\\n\")\n                        return fighter1\n                        \n                else:\n                    print(f\"-{fighter2[0]} repele el ataque de {fighter1[0]} , turno para {fighter2[0]}\")\n                    \n                if random.random() > 0.2:\n                    damage1 = power2 - shield1\n                    score1 -= damage1\n\n                    print(f\"-El ataque de {fighter2[0]} le resta {damage1} puntos a {fighter1[0]}\", end=\" \")\n                    if score1 < 0: score1 = 0\n                    print(f\"que se queda con {score1} puntos\")\n                    damage1 = 0\n\n                    if score1 <= 0:\n                        print(f\"\\nEl ganador de la batalla es {fighter2[0]}\\n\")\n                        return fighter2\n                        \n                else:\n                    print(f\"-{fighter1[0]} repele el ataque de {fighter2[0]}, turno para {fighter1[0]}\")\n                    continue\n            elif power1 < shield2:\n                 damage2 = power1 // 10\n                 score2 -= damage2\n        \n        else:\n            if power2 >= shield1:\n\n                if random.random() > 0.2:\n\n                    damage1 = power2 - shield1\n                    score1 -= damage1\n                    print(f\"-El ataque de {fighter2[0]} le resta {damage1} puntos a {fighter1[0]}\", end=\" \")\n\n                    if score1 < 0: score1 = 0\n                    print(f\"que se queda con {score1} puntos\")\n                    damage1 = 0\n\n                    if score1 <=0:\n                        print(f\"\\nEl ganador de la batalla es {fighter2[0]}\\n\")\n                        return fighter2\n                        \n                else:\n                    print(f\"-{fighter1[0]} repele el ataque de {fighter2[0]}, turno para {fighter1[0]}\")\n                    \n                if random.random() > 0.2:\n                    damage2 = power1 - shield2\n                    score2 -= damage2\n                    print(f\"-El ataque de {fighter1[0]} le resta {damage2} puntos a {fighter2[0]}\", end=\" \")\n\n                    if score2 < 0: score2 = 0\n                    print(f\"que se queda con {score2} puntos\")\n                    damage2 = 0\n\n                    if score2 <= 0:\n                        print(f\"\\nEl ganador de la batalla es {fighter1[0]}\\n\")\n                        return fighter1\n                        \n                else:\n                    print(f\"-{fighter2[0]} repele el ataque de {fighter1[0]}, turno para {fighter2[0]}\")\n                    continue\n\n            elif power2 < shield1:\n                    damage1 = fighter2[1] // 10\n                    score1 -= damage1\n\nrounds = [\"Eliminatoria de dieciseisavos\",\"Eliminatoria de octavos\",\"Eliminatoria de cuartos\",\"Semifinal\",\"Final\"]\nfor i, round in enumerate(rounds):\n    \n    print (\"\\n\",round)\n    print(\"----------------------------------------------------------------------------------------\")\n    if i == 0:\n        fights = couples(characters)\n        show_battles(fights)\n    else:\n        fights = couples(winners)\n        show_battles(fights)\n    winners = []   \n    for fight in fights:\n        winner = fight1vs1(fight[0], fight[1])\n        winners.append(winner)\nprint(f\"\\n---------------------- EL GANADOR DEL TORNEO ES: {winner[0]} ----------------------\\n\")\n    \n\n\n"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/python/Juanppdev.py",
    "content": "\"\"\"\n * EJERCICIO:\n * ¡El último videojuego de Dragon Ball ya está aquí!\n * Se llama Dragon Ball: Sparking! ZERO.\n *\n * Simula un Torneo de Artes Marciales, al más puro estilo\n * de la saga, donde participarán diferentes luchadores, y el\n * sistema decidirá quién es el ganador.\n *\n * Luchadores:\n * - Nombre.\n * - Tres atributos: velocidad, ataque y defensa\n *   (con valores entre 0 a 100 que tú decidirás).\n * - Comienza cada batalla con 100 de salud.\n * Batalla:\n * - En cada batalla se enfrentan 2 luchadores.\n * - El luchador con más velocidad comienza atacando.\n * - El daño se calcula restando el daño de ataque del\n *   atacante menos la defensa del oponente.\n * - El oponente siempre tiene un 20% de posibilidad de\n *   esquivar el ataque.\n * - Si la defensa es mayor que el ataque, recibe un 10%\n *   del daño de ataque.\n * - Después de cada turno y ataque, el oponente pierde salud.\n * - La batalla finaliza cuando un luchador pierde toda su salud.\n * Torneo:\n * - Un torneo sólo es válido con un número de luchadores\n *   potencia de 2.\n * - El torneo debe crear parejas al azar en cada ronda.\n * - Los luchadores se enfrentan en rondas eliminatorias.\n * - El ganador avanza a la siguiente ronda hasta que sólo\n *   quede uno.\n * - Debes mostrar por consola todo lo que sucede en el torneo,\n *   así como el ganador.\n\"\"\"\n\nimport random\n\nclass Luchador:\n    def __init__(self, nombre, velocidad, ataque, defensa):\n        self.nombre = nombre\n        self.velocidad = velocidad\n        self.ataque = ataque\n        self.defensa = defensa\n        self.salud = 100\n\n    def esquivar(self):\n        return random.random() < 0.2\n\n    def recibir_danio(self, danio):\n        if self.esquivar():\n            print(f\"{self.nombre} esquivó el ataque!\")\n            return\n\n        if self.defensa > danio:\n            danio *= 0.1\n        else:\n            danio -= self.defensa\n        self.salud -= danio\n        print(f\"{self.nombre} recibe {danio} de daño. Salud actual: {self.salud}\")\n\ndef batalla(luchador1, luchador2):\n    print(f\"¡{luchador1.nombre} vs {luchador2.nombre}!\")\n\n    while luchador1.salud > 0 and luchador2.salud > 0:\n        if luchador1.velocidad >= luchador2.velocidad:\n            luchador1, luchador2 = luchador1, luchador2\n        else:\n            luchador1, luchador2 = luchador2, luchador1\n\n        luchador2.recibir_danio(luchador1.ataque)\n        if luchador2.salud <= 0:\n            print(f\"¡{luchador1.nombre} gana!\")\n            return luchador1\n\n        luchador1, luchador2 = luchador2, luchador1\n\ndef torneo(luchadores):\n    if (len(luchadores) & (len(luchadores) - 1)) != 0:\n        raise ValueError(\"El número de luchadores debe ser una potencia de 2\")\n\n    while len(luchadores) > 1:\n        random.shuffle(luchadores)\n        ganadores = []\n\n        for i in range(0, len(luchadores), 2):\n            ganador = batalla(luchadores[i], luchadores[i + 1])\n            ganadores.append(ganador)\n\n        luchadores = ganadores\n\n    print(f\"¡El ganador del torneo es {luchadores[0].nombre}!\")\n\n# Ejemplo de uso\nluchadores = [\n    Luchador(\"Goku\", 90, 95, 85),\n    Luchador(\"Vegeta\", 85, 90, 90),\n    Luchador(\"Piccolo\", 75, 85, 95),\n    Luchador(\"Gohan\", 80, 80, 80),\n]\n\ntorneo(luchadores)\n"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/python/Nicojsuarez2.py",
    "content": "# #42 TORNEO DRAGON BALL\n> #### Dificultad: Difícil | Publicación: 14/10/24 | Corrección: 21/10/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * ¡El último videojuego de Dragon Ball ya está aquí!\n * Se llama Dragon Ball: Sparking! ZERO.\n *\n * Simula un Torneo de Artes Marciales, al más puro estilo\n * de la saga, donde participarán diferentes luchadores, y el\n * sistema decidirá quién es el ganador.\n *\n * Luchadores:\n * - Nombre.\n * - Tres atributos: velocidad, ataque y defensa\n *   (con valores entre 0 a 100 que tú decidirás).\n * - Comienza cada batalla con 100 de salud.\n * Batalla:\n * - En cada batalla se enfrentan 2 luchadores.\n * - El luchador con más velocidad comienza atacando.\n * - El daño se calcula restando el daño de ataque del\n *   atacante menos la defensa del oponente.\n * - El oponente siempre tiene un 20% de posibilidad de\n *   esquivar el ataque.\n * - Si la defensa es mayor que el ataque, recibe un 10%\n *   del daño de ataque.\n * - Después de cada turno y ataque, el oponente pierde salud.\n * - La batalla finaliza cuando un luchador pierde toda su salud.\n * Torneo:\n * - Un torneo sólo es válido con un número de luchadores\n *   potencia de 2.\n * - El torneo debe crear parejas al azar en cada ronda.\n * - Los luchadores se enfrentan en rondas eliminatorias.\n * - El ganador avanza a la siguiente ronda hasta que sólo\n *   quede uno.\n * - Debes mostrar por consola todo lo que sucede en el torneo,\n *   así como el ganador.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/python/cdryampi.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * ¡El último videojuego de Dragon Ball ya está aquí!\n#  * Se llama Dragon Ball: Sparking! ZERO.\n#  *\n#  * Simula un Torneo de Artes Marciales, al más puro estilo\n#  * de la saga, donde participarán diferentes luchadores, y el\n#  * sistema decidirá quién es el ganador.\n#  *\n#  * Luchadores:\n#  * - Nombre.\n#  * - Tres atributos: velocidad, ataque y defensa\n#  *   (con valores entre 0 a 100 que tú decidirás).\n#  * - Comienza cada batalla con 100 de salud.\n#  * Batalla:\n#  * - En cada batalla se enfrentan 2 luchadores.\n#  * - El luchador con más velocidad comienza atacando.\n#  * - El daño se calcula restando el daño de ataque del\n#  *   atacante menos la defensa del oponente.\n#  * - El oponente siempre tiene un 20% de posibilidad de\n#  *   esquivar el ataque.\n#  * - Si la defensa es mayor que el ataque, recibe un 10%\n#  *   del daño de ataque.\n#  * - Después de cada turno y ataque, el oponente pierde salud.\n#  * - La batalla finaliza cuando un luchador pierde toda su salud.\n#  * Torneo:\n#  * - Un torneo sólo es válido con un número de luchadores\n#  *   potencia de 2.\n#  * - El torneo debe crear parejas al azar en cada ronda.\n#  * - Los luchadores se enfrentan en rondas eliminatorias.\n#  * - El ganador avanza a la siguiente ronda hasta que sólo\n#  *   quede uno.\n#  * - Debes mostrar por consola todo lo que sucede en el torneo,\n#  *   así como el ganador.\n#  */\nimport random\n\nclass Stat():\n    \"\"\"\n        Clase que representa a los stats de un luchador.\n    \"\"\"\n    def __init__(self, velocidad, ataque, defensa):\n        self.velocidad = velocidad\n        self.ataque = ataque\n        self.defensa = defensa\n        self.vida = 100\n\nclass Luchador():\n    \"\"\"\n        Clase que representa a un luchador\n    \"\"\"\n\n    def __init__(self, nombre:str, stats:Stat) -> None:\n        self.nombre = nombre\n        self.stats = stats\n\n    def esquiva(self):\n        return random.randint(1,100) <= 20\n\n    def cal_defensa_mayor_que_ataque(self, luchador_2)-> bool:\n        return True if self.stats.ataque < luchador_2.stats.defensa else False\n    \n    def restablecer_vida(self)-> None:\n        self.stats.vida = 100\n    def es_golpe_critico(self) -> bool:\n        return random.randint(0,100) <= 15\n\nclass Batalla():\n    \"\"\"\n        Clase que representa el esenario de una batalla.\n    \"\"\"\n    __DANY_MINIM = 5\n    def __init__(self, luchador_1: Luchador, luchador_2: Luchador) -> None:\n        self.luchador_1 = luchador_1\n        self.luchador_2 = luchador_2\n        self.turno = True\n        self.batalla = True\n        self.mas_rapido()\n        if self.turno:\n            print(f\"El luchador {self.luchador_1.nombre} es el más rápido y comienza atacando.\")\n        else:\n            print(f\"El luchador {self.luchador_2.nombre} es el más rápido y comienza atacando.\")\n\n\n\n    def mas_rapido(self)-> bool:\n        self.turno = True if self.luchador_1.stats.velocidad >= self.luchador_2.stats.velocidad else False\n    \n\n    def cal_defensa(self)-> bool:\n        atacante = self.luchador_1 if self.turno else self.luchador_2\n        defensor = self.luchador_2 if self.turno else self.luchador_1\n        if atacante.cal_defensa_mayor_que_ataque(defensor):\n            contra_ataque = defensor.stats.ataque*0.1\n            atacante.stats.vida -=contra_ataque\n            print(f\"La defensa de {defensor.nombre} supera el ataque de {atacante.nombre}.\")\n            print(f\"{defensor.nombre} recibe {contra_ataque} puntos de daño por rebote.\")\n            return False\n        return True\n\n\n\n    \n    def batallar(self)-> None:\n        while self.batalla:\n            if self.cal_defensa():\n                atacante = self.luchador_1 if self.turno else self.luchador_2\n                defensor = self.luchador_2 if self.turno else self.luchador_1\n\n                if defensor.esquiva():\n                    print(f\"{defensor.nombre} ha esquivado el ataque de {atacante.nombre}.\")\n                else:\n                    if atacante.es_golpe_critico():\n                        daño = atacante.stats.ataque - defensor.stats.defensa*0.5\n                        print(f\"¡Golpe crítico! {atacante.nombre} ha infligido un golpe crítico a {defensor.nombre}.\")\n                    else:\n                        daño = atacante.stats.ataque - defensor.stats.defensa\n                        if daño <= 0:\n                            daño = self.__DANY_MINIM\n                    defensor.stats.vida -= daño\n                    print(f\"{atacante.nombre} ha atacado a {defensor.nombre}.\")\n                    print(f\"{defensor.nombre} ha perdido {daño} puntos de vida. Vida restante: {defensor.stats.vida}\")\n\n                self.finalizar_batalla() if defensor.stats.vida <= 0 else None\n                self.turno = not self.turno\n            else:\n                self.turno = not self.turno\n\n    \n    def finalizar_batalla(self)-> bool:\n\n        if self.luchador_1.stats.vida <=0:\n            print(f\"El luchador {self.luchador_1.nombre} ha sido derrotado.\")\n        else:\n            print(f\"El luchador {self.luchador_2.nombre} ha sido derrotado.\")\n\n        self.batalla = False\n\n    def estado(self)-> str:\n\n        print(f'El luchador {self.luchador_1.nombre} tiene {self.luchador_1.stats.vida} puntos de vida y el luchador {self.luchador_2.nombre} tiene {self.luchador_2.stats.vida} puntos de vida.')\n\n\nclass Torneo():\n    __LISTA_DE_PARTICIPANTES_DEL_TORNEO = [\n        Luchador(\"Goku\", Stat(velocidad=99, ataque=99, defensa=99)),\n        Luchador(\"Vegeta\", Stat(velocidad=90, ataque=95, defensa=85)),\n        Luchador(\"Gohan\", Stat(velocidad=85, ataque=90, defensa=80)),\n        Luchador(\"Piccolo\", Stat(velocidad=75, ataque=80, defensa=85)),\n        Luchador(\"Krillin\", Stat(velocidad=70, ataque=65, defensa=60)),\n        Luchador(\"Bulma\", Stat(velocidad=30, ataque=10, defensa=20)),\n        Luchador(\"Trunks\", Stat(velocidad=80, ataque=85, defensa=75)),\n        Luchador(\"Freezer\", Stat(velocidad=85, ataque=90, defensa=80)),\n        Luchador(\"Cell\", Stat(velocidad=85, ataque=95, defensa=85)),\n        Luchador(\"Majin Buu\", Stat(velocidad=70, ataque=90, defensa=95)),\n        Luchador(\"Yamcha\", Stat(velocidad=60, ataque=55, defensa=50)),\n        Luchador(\"Tenshinhan\", Stat(velocidad=65, ataque=60, defensa=55)),\n        Luchador(\"Chaoz\", Stat(velocidad=50, ataque=40, defensa=35)),\n        Luchador(\"Videl\", Stat(velocidad=55, ataque=50, defensa=45)),\n        Luchador(\"Mr. Satán\", Stat(velocidad=40, ataque=30, defensa=35)),\n        Luchador(\"Chi-Chi\", Stat(velocidad=50, ataque=45, defensa=40)),\n        Luchador(\"Androide 18\", Stat(velocidad=80, ataque=85, defensa=80)),\n        Luchador(\"Androide 17\", Stat(velocidad=80, ataque=85, defensa=80)),\n        Luchador(\"Dende\", Stat(velocidad=30, ataque=20, defensa=25)),\n        Luchador(\"Shenlong\", Stat(velocidad=100, ataque=100, defensa=100)),\n        Luchador(\"Kaiō-sama\", Stat(velocidad=70, ataque=75, defensa=70)),\n        Luchador(\"Beerus\", Stat(velocidad=100, ataque=100, defensa=100)),\n        Luchador(\"Whis\", Stat(velocidad=100, ataque=100, defensa=100)),\n        Luchador(\"Jiren\", Stat(velocidad=95, ataque=100, defensa=95)),\n        Luchador(\"Zamasu\", Stat(velocidad=90, ataque=95, defensa=90)),\n        Luchador(\"Broly\", Stat(velocidad=85, ataque=100, defensa=90)),\n        Luchador(\"Raditz\", Stat(velocidad=60, ataque=65, defensa=55)),\n        Luchador(\"Nappa\", Stat(velocidad=55, ataque=70, defensa=60)),\n        Luchador(\"Zarbon\", Stat(velocidad=65, ataque=60, defensa=55)),\n        Luchador(\"Dodoria\", Stat(velocidad=50, ataque=60, defensa=55)),\n        Luchador(\"Ginyu\", Stat(velocidad=65, ataque=70, defensa=65)),\n        Luchador(\"Recoome\", Stat(velocidad=60, ataque=65, defensa=60))\n    ]\n    __SIGUIENTE_RONDA = []\n    __CAMPEON:Luchador = None\n    __RONDA = 1\n\n\n    def __init__(self):\n        self.__LISTA_DE_PARTICIPANTES_DEL_TORNEO = self.obtener_lista_participantes(self.seleccionar_participantes())\n\n    def seleccionar_participantes(self)-> int:\n        while True:\n            try:\n                num_participantes = int(input(\"Selecciona el tamaño del torneo (32, 16, 8, 4): \"))\n                if num_participantes in [32, 16, 8, 4]:\n                    return num_participantes\n                else:\n                    print(\"Por favor, selecciona un número válido (32, 16, 8, o 4).\")\n            except ValueError:\n                print(\"Entrada no válida. Por favor, introduce un número entero.\")\n    \n    def obtener_lista_participantes(self, num_participantes)-> list:\n        return random.sample(self.__LISTA_DE_PARTICIPANTES_DEL_TORNEO, num_participantes)\n\n    def iniciar_torneo(self)->None:\n\n        self.__SIGUIENTE_RONDA = []\n        self.__CAMPEON = None\n        self.__RONDA = 1\n\n        if self.torneo_valido():\n            print(f'Se inicia el torneo Dragon Ball: Sparking! ZERO.')\n            while(self.__CAMPEON == None):\n                self.siguiente_ronda()\n            print(f'El ganador del torneo es {self.__CAMPEON.nombre}')\n            \n    \n    def eliminatoria(self, duelo: Batalla):\n        duelo.luchador_1.restablecer_vida()\n        duelo.luchador_2.restablecer_vida()\n        while(duelo.batalla ==True):\n            duelo.batallar()\n            yield(duelo.luchador_1, duelo.luchador_2)\n        yield duelo.luchador_1 if duelo.luchador_1.stats.vida > 0 else duelo.luchador_2\n    \n    def siguiente_ronda(self) -> None:\n        print(f'\\nRonda {self.__RONDA}:\\n')\n        if len(self.__LISTA_DE_PARTICIPANTES_DEL_TORNEO) == 1:\n            self.__CAMPEON = self.__LISTA_DE_PARTICIPANTES_DEL_TORNEO.pop()\n        else:\n            while len(self.__LISTA_DE_PARTICIPANTES_DEL_TORNEO) > 1:\n                luchadores = random.sample(self.__LISTA_DE_PARTICIPANTES_DEL_TORNEO, 2)\n                luchador_1, luchador_2 = luchadores\n                self.__LISTA_DE_PARTICIPANTES_DEL_TORNEO.remove(luchador_1)\n                self.__LISTA_DE_PARTICIPANTES_DEL_TORNEO.remove(luchador_2)\n                print(f\"\\nLuchadores seleccionados: {luchador_1.nombre} vs {luchador_2.nombre}\")\n                try:\n                    # Llamamos a la eliminatoria como generador\n                    respuesta = int(input(f\"Presiona un número para simular el duelo entre {luchador_1.nombre} vs {luchador_2.nombre}\\n\"))\n                    if not isinstance(respuesta, int):\n                        raise TypeError(\"Haz de poner número para poder simular\")\n\n                    if respuesta == 1:\n                        self.gestionar_duelo(luchador_1, luchador_2)\n                    else:\n                        self.gestionar_duelo(luchador_1, luchador_2)\n                except ValueError as e:\n                    print(\"Debes introducir un número válido. Saltamos la simulación\")\n\n\n\n            # Actualizar la lista para la siguiente ronda\n            self.__LISTA_DE_PARTICIPANTES_DEL_TORNEO = self.__SIGUIENTE_RONDA[:]\n            self.__SIGUIENTE_RONDA = []\n            self.__RONDA += 1\n            self.print_ronda()\n\n\n\n    def print_ronda(self) -> None:\n        print(f\"Lista de participantes de la ronda {self.__RONDA}\")\n        for index, luchador in enumerate(self.__LISTA_DE_PARTICIPANTES_DEL_TORNEO):\n            print(f'{index+1}. {luchador.nombre}')\n\n    def torneo_valido(self)->bool:\n        num_participantes = len(self.__LISTA_DE_PARTICIPANTES_DEL_TORNEO)\n        if num_participantes >= 2 and (num_participantes & (num_participantes - 1) == 0):\n            print('Torneo válido')\n            self.print_ronda()\n            return True\n        else:\n            potencia = 1\n            while potencia * 2 <= num_participantes:\n                potencia *= 2\n            while len(self.__LISTA_DE_PARTICIPANTES_DEL_TORNEO) > potencia:\n                eliminado = self.__LISTA_DE_PARTICIPANTES_DEL_TORNEO.pop(random.randint(0, len(self.__LISTA_DE_PARTICIPANTES_DEL_TORNEO) - 1))\n                print(f'El luchador {eliminado.nombre} ha sido eliminado del torneo.')\n            print('Ahora el número de participantes es una potencia de 2. Torneo válido.')\n            self.print_ronda()\n            return True\n\n\n    def gestionar_duelo(self, luchador_1, luchador_2):\n        \"\"\"Gestiona el duelo entre dos luchadores y muestra el ganador.\"\"\"\n        duelo = Batalla(luchador_1, luchador_2)\n        \n        for index, estado in enumerate(self.eliminatoria(duelo)):\n            if isinstance(estado, tuple):\n                luchador_1, luchador_2 = estado\n                print(f\"Duelo entre {luchador_1.nombre} y {luchador_2.nombre} Finalizado.\")\n            else:\n                ganador = estado\n                print(f\"Ganador del duelo: {ganador.nombre}\")\n                self.__SIGUIENTE_RONDA.append(ganador)\n                break\n        \n\n\ndef main():\n    torneo = Torneo()\n    torneo.iniciar_torneo()\n\nif __name__ == '__main__':\n    main()"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/python/davidrguez98.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * ¡El último videojuego de Dragon Ball ya está aquí!\n * Se llama Dragon Ball: Sparking! ZERO.\n *\n * Simula un Torneo de Artes Marciales, al más puro estilo\n * de la saga, donde participarán diferentes luchadores, y el\n * sistema decidirá quién es el ganador.\n *\n * Luchadores:\n * - Nombre.\n * - Tres atriotasobutos: velocidad, ataque y defensa\n *   (con valores entre 0 a 100 que tú decidirás).\n * - Comienza cada batalla con 100 de salud.\n * Batalla:\n * - En cada batalla se enfrentan 2 luchadores.\n * - El luchador con más velocidad comienza atacando.\n * - El daño se calcula restando el daño de ataque del\n *   atacante menos la defensa del oponente.\n * - El oponente siempre tiene un 20% de posibilidad de\n *   esquivar el ataque.\n * - Si la defensa es mayor que el ataque, recibe un 10%\n *   del daño de ataque.\n * - Después de cada turno y ataque, el oponente pierde salud.\n * - La batalla finaliza cuando un luchador pierde toda su salud.\n * Torneo:\n * - Un torneo sólo es válido con un número de luchadores\n *   potencia de 2.\n * - El torneo debe crear parejas al azar en cada ronda.\n * - Los luchadores se enfrentan en rondas eliminatorias.\n * - El ganador avanza a la siguiente ronda hasta que sólo\n *   quede uno.\n * - Debes mostrar por consola todo lo que sucede en el torneo,\n *   así como el ganador.\n */ \"\"\"\n\n#EJERCICIO\n\nimport random\n\nclass Fighter:\n \n    def __init__(self, name: str, speed: int, attack: int, defense: int):\n        self.name = name\n        self.speed = speed\n        self.attack = attack\n        self.defense = defense\n        self.health = 100\n\n    def reset_health(self):\n        self.health = 100\n\n    def is_alive(self) -> bool:\n        return self.health > 0\n    \n    def take_damage(self, damage: int):\n\n        attack_damage = 0\n        \n        if random.random() < 0.2:\n            print(f\"{self.name} ha esquivado el ataque.\")\n        else:\n            if self.defense >= damage:\n                attack_damage = damage * 0.1\n            else:\n                attack_damage = damage - self.defense\n\n            attack_damage = int(attack_damage)\n\n        self.health = max(self.health - attack_damage, 0)\n        print(f\"El luchador {self.name} recibe {attack_damage} de daño.\")\n        print(f\"Salud restante {self.health}\")\n\nclass Battle:\n\n    def __init__(self, fighter1: Fighter, fighter2: Fighter):\n        self.fighter1 = fighter1\n        self.fighter2 = fighter2\n    \n    def fight(self) -> Fighter:\n\n        print(f\"\\n=== {self.fighter1.name} vs {self.fighter2.name} ===\")\n\n        while self.fighter1.is_alive() and self.fighter2.is_alive():\n            \n            if self.fighter1.speed > self.fighter2.speed:\n                self.turn(self.fighter1, self.fighter2)\n                if self.fighter2.is_alive():\n                    self.turn(self.fighter2, self.fighter1)\n            else:\n                self.turn(self.fighter2, self.fighter1)\n                if self.fighter1.is_alive():\n                    self.turn(self.fighter1, self.fighter2)\n\n        if self.fighter1.is_alive():\n            print(f\"\\nEl luchador {self.fighter1.name} ha ganado la batalla.\")\n            return self.fighter1\n        else:\n            print(f\"\\nEl luchador {self.fighter2.name} ha ganado la batalla.\")\n            return self.fighter2\n        \n    def turn(self, attacker: Fighter, defender: Fighter):\n        print(f\"\\n{attacker.name} ataca a {defender.name}\")\n        defender.take_damage(attacker.attack)\n\nclass Tournament:\n\n    def __init__(self, fighters: list):\n        if not self.is_power_of_two(len(fighters)):\n            raise ValueError(\"El número de luchadores debe de ser una potencia de 2.\")\n        self.fighters = fighters\n\n    def start(self):\n        round = 1\n        while len(self.fighters) > 1:\n\n            print(f\"\\n=== Ronda: {round} ===\")\n\n            random.shuffle(self.fighters)\n\n            winners = []\n\n            for index in range(0, len(self.fighters), 2):\n                fighter1 = self.fighters[index]\n                fighter2 = self.fighters[index + 1]\n\n                battle = Battle(fighter1, fighter2)\n                winner = battle.fight()\n                winners.append(winner)\n\n            self.fighters = winners\n            round += 1\n\n        print(f\"\\nEl ganador del torneo es {self.fighters[0].name}\")\n\n    def is_power_of_two(self, n) -> bool:\n        if n <= 0:\n            return False\n        while n % 2 == 0:\n            n //= 2\n        return n == 1\n\n\n\n\n\nfighters = [\n    Fighter(\"Goku\", 90, 95, 80),\n    Fighter(\"Vegeta\", 95, 90, 82),\n    Fighter(\"Piccolo\", 80, 85, 90),\n    Fighter(\"Freezer\", 95, 90, 75),\n    Fighter(\"Krillin\", 95, 90, 75),\n    Fighter(\"Célula\", 92, 70, 73),\n    Fighter(\"Gohan\", 97, 95, 70),\n    Fighter(\"Trunks\", 88, 88, 88)\n]\n\ntournament = Tournament(fighters)\ntournament.start()\n"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/python/duendeintemporal.py",
    "content": "#42 { Retos para Programadores } TORNEO DRAGON BALL\n\n# Bibliography reference:\n# I use GPT as a reference and sometimes to correct or generate proper comments.\n\n\"\"\"\n * EJERCICIO:\n * ¡El último videojuego de Dragon Ball ya está aquí!\n * Se llama Dragon Ball: Sparking! ZERO.\n *\n * Simula un Torneo de Artes Marciales, al más puro estilo\n * de la saga, donde participarán diferentes luchadores, y el\n * sistema decidirá quién es el ganador.\n *\n * Luchadores:\n * - Nombre.\n * - Tres atributos: velocidad, ataque y defensa\n *   (con valores entre 0 a 100 que tú decidirás).\n * - Comienza cada batalla con 100 de salud.\n * Batalla:\n * - En cada batalla se enfrentan 2 luchadores.\n * - El luchador con más velocidad comienza atacando.\n * - El daño se calcula restando el daño de ataque del\n *   atacante menos la defensa del oponente.\n * - El oponente siempre tiene un 20% de posibilidad de\n *   esquivar el ataque.\n * - Si la defensa es mayor que el ataque, recibe un 10%\n *   del daño de ataque.\n * - Después de cada turno y ataque, el oponente pierde salud.\n * - La batalla finaliza cuando un luchador pierde toda su salud.\n * Torneo:\n * - Un torneo sólo es válido con un número de luchadores\n *   potencia de 2.\n * - El torneo debe crear parejas al azar en cada ronda.\n * - Los luchadores se enfrentan en rondas eliminatorias.\n * - El ganador avanza a la siguiente ronda hasta que sólo\n *   quede uno.\n * - Debes mostrar por consola todo lo que sucede en el torneo,\n *   así como el ganador.\n\n\"\"\"\n\nlog = print\n\nimport random\nimport time\nimport asyncio\n\nclass Fighter:\n    def __init__(self, id, name, speed, attack, defense):\n        self.id = id\n        self.name = name\n        self.speed = speed\n        self.attack = attack\n        self.defense = defense\n        self.health = 100  # Each fighter starts with 100 health\n\n    def calculate_damage(self, opponent):\n        damage = max(self.attack - opponent.defense, 0)  # No negative damage\n\n        # Check if the opponent dodges the attack\n        if random.random() < 0.2:  # 20% chance to dodge\n            return 0  # No damage dealt\n\n        # If the opponent's defense is greater than the attack, reduce damage\n        if opponent.defense > self.attack:\n            damage *= 0.1  # 10% of the attack damage\n\n        return int(damage)  # Return the damage as an integer\n\n\nclass Battle:\n    def __init__(self, fighter1, fighter2):\n        self.fighter1 = fighter1\n        self.fighter2 = fighter2\n        self.attacker = fighter1 if fighter1.speed >= fighter2.speed else fighter2\n        self.defender = fighter2 if self.attacker == fighter1 else fighter1\n\n    def winner(self, win_fighter):\n        log(f\"{win_fighter.name} is the winner!\")\n\n    def loser(self, los_fighter):\n        log(f\"{los_fighter.name} is the loser!\")\n\n    async def start(self):\n        while self.fighter1.health > 0 and self.fighter2.health > 0:\n            damage = self.attacker.calculate_damage(self.defender)\n\n            # Ensure a minimum level of damage\n            min_damage = 10\n            actual_damage = max(min_damage, damage)\n\n            self.defender.health -= actual_damage\n\n            # Log the attack and damage\n            if actual_damage == min_damage:\n                log(f\"{self.attacker.name}'s attack was partially blocked by {self.defender.name}, dealing {actual_damage} damage.\")\n            else:\n                log(f\"{self.attacker.name} attacks {self.defender.name} for {actual_damage} damage.\")\n            log(f\"{self.defender.name} has {self.defender.health} health left.\")\n\n            # Swap roles for the next turn\n            self.attacker, self.defender = self.defender, self.attacker\n\n            # Introduce a delay between attacks\n            await asyncio.sleep(0.5)\n\n        winner = self.fighter1 if self.fighter1.health > 0 else self.fighter2\n        log(f\"{winner.name} wins the battle!\")\n        self.winner(winner)\n        self.loser(self.fighter1 if winner == self.fighter2 else self.fighter2)\n\n        return winner\n\n\nclass Tournament:\n    def __init__(self, fighters):\n        if not self.is_power_of_two(len(fighters)):\n            raise ValueError(\"Number of fighters must be a power of 2.\")\n        self.fighters = fighters\n\n    @staticmethod\n    def is_power_of_two(n):\n        return (n & (n - 1)) == 0 and n > 0  # Check if n is a power of two\n\n    async def start(self):\n        log(\"Starting the tournament...\")\n        round = 1\n\n        while len(self.fighters) > 1:\n            log(f\"\\n--- Round {round} ---\")\n\n            winners = []\n            for i in range(0, len(self.fighters), 2):\n                battle = Battle(self.fighters[i], self.fighters[i + 1])\n                winner = await battle.start()\n                winners.append(winner)\n\n            log(\"\\nWinners of Round \" + str(round) + \":\")\n            for fighter in winners:\n                log(\"- \" + fighter.name)\n\n            self.fighters = winners  # Update fighters for the next round\n            round += 1\n\n        log(f\"\\nThe champion of the tournament is {self.fighters[0].name}!\")\n\n\n# Create fighters\nfighters = [\n    Fighter(1, 'Goku', 95, 80, 50),\n    Fighter(2, 'Vegeta', 90, 85, 45),\n    Fighter(3, 'Gohan', 85, 75, 55),\n    Fighter(4, 'Piccolo', 80, 70, 60),\n    Fighter(5, 'Frieza', 88, 90, 40),\n    Fighter(6, 'Cell', 85, 80, 50),\n    Fighter(7, 'Majin Buu', 70, 60, 70),\n    Fighter(8, 'Trunks', 75, 65, 65)\n]\n\n# Function to start the tournament\nasync def main():\n    tournament = Tournament(fighters)\n    await tournament.start()\n\n# Run the tournament\nif __name__ == \"__main__\":\n    asyncio.run(main())\n\n\n# Possible Output:\n\"\"\"   \nStarting the tournament...\n\n--- Round 1 ---\nGoku attacks Vegeta for 35 damage.\nVegeta has 65 health left.\nVegeta attacks Goku for 35 damage.\nGoku has 65 health left.\nGoku attacks Vegeta for 35 damage.\nVegeta has 30 health left.\nVegeta's attack was partially blocked by Goku, dealing 10 damage.\nGoku has 55 health left.\nGoku attacks Vegeta for 35 damage.\nVegeta has -5 health left.\nGoku wins the battle!\nGoku is the winner!\nVegeta is the loser!\nGohan attacks Piccolo for 15 damage.\nPiccolo has 85 health left.\nPiccolo attacks Gohan for 15 damage.\nGohan has 85 health left.\nGohan's attack was partially blocked by Piccolo, dealing 10 damage.\nPiccolo has 75 health left.\nPiccolo attacks Gohan for 15 damage.\nGohan has 70 health left.\nGohan attacks Piccolo for 15 damage.\nPiccolo has 60 health left.\nPiccolo's attack was partially blocked by Gohan, dealing 10 damage.\nGohan has 60 health left.\nGohan attacks Piccolo for 15 damage.\nPiccolo has 45 health left.\nPiccolo attacks Gohan for 15 damage.\nGohan has 45 health left.\nGohan attacks Piccolo for 15 damage.\nPiccolo has 30 health left.\nPiccolo attacks Gohan for 15 damage.\nGohan has 30 health left.\nGohan attacks Piccolo for 15 damage.\nPiccolo has 15 health left.\nPiccolo attacks Gohan for 15 damage.\nGohan has 15 health left.\nGohan attacks Piccolo for 15 damage.\nPiccolo has 0 health left.\nGohan wins the battle!\nGohan is the winner!\nPiccolo is the loser!\nFrieza's attack was partially blocked by Cell, dealing 10 damage.\nCell has 90 health left.\nCell's attack was partially blocked by Frieza, dealing 10 damage.\nFrieza has 90 health left.\nFrieza attacks Cell for 40 damage.\nCell has 50 health left.\nCell attacks Frieza for 40 damage.\nFrieza has 50 health left.\nFrieza attacks Cell for 40 damage.\nCell has 10 health left.\nCell attacks Frieza for 40 damage.\nFrieza has 10 health left.\nFrieza attacks Cell for 40 damage.\nCell has -30 health left.\nFrieza wins the battle!\nFrieza is the winner!\nCell is the loser!\nTrunks's attack was partially blocked by Majin Buu, dealing 10 damage.\nMajin Buu has 90 health left.\nMajin Buu's attack was partially blocked by Trunks, dealing 10 damage.\nTrunks has 90 health left.\nTrunks's attack was partially blocked by Majin Buu, dealing 10 damage.\nMajin Buu has 80 health left.\nMajin Buu's attack was partially blocked by Trunks, dealing 10 damage.\nTrunks has 80 health left.\nTrunks's attack was partially blocked by Majin Buu, dealing 10 damage.\nMajin Buu has 70 health left.\nMajin Buu's attack was partially blocked by Trunks, dealing 10 damage.\nTrunks has 70 health left.\nTrunks's attack was partially blocked by Majin Buu, dealing 10 damage.\nMajin Buu has 60 health left.\nMajin Buu's attack was partially blocked by Trunks, dealing 10 damage.\nTrunks has 60 health left.\nTrunks's attack was partially blocked by Majin Buu, dealing 10 damage.\nMajin Buu has 50 health left.\nMajin Buu's attack was partially blocked by Trunks, dealing 10 damage.\nTrunks has 50 health left.\nTrunks's attack was partially blocked by Majin Buu, dealing 10 damage.\nMajin Buu has 40 health left.\nMajin Buu's attack was partially blocked by Trunks, dealing 10 damage.\nTrunks has 40 health left.\nTrunks's attack was partially blocked by Majin Buu, dealing 10 damage.\nMajin Buu has 30 health left.\nMajin Buu's attack was partially blocked by Trunks, dealing 10 damage.\nTrunks has 30 health left.\nTrunks's attack was partially blocked by Majin Buu, dealing 10 damage.\nMajin Buu has 20 health left.\nMajin Buu's attack was partially blocked by Trunks, dealing 10 damage.\nTrunks has 20 health left.\nTrunks's attack was partially blocked by Majin Buu, dealing 10 damage.\nMajin Buu has 10 health left.\nMajin Buu's attack was partially blocked by Trunks, dealing 10 damage.\nTrunks has 10 health left.\nTrunks's attack was partially blocked by Majin Buu, dealing 10 damage.\nMajin Buu has 0 health left.\nTrunks wins the battle!\nTrunks is the winner!\nMajin Buu is the loser!\n\nWinners of Round 1:\n- Goku\n- Gohan\n- Frieza\n- Trunks\n\n--- Round 2 ---\nGoku attacks Gohan for 25 damage.\nGohan has -10 health left.\nGoku wins the battle!\nGoku is the winner!\nGohan is the loser!\nFrieza attacks Trunks for 25 damage.\nTrunks has -15 health left.\nFrieza wins the battle!\nFrieza is the winner!\nTrunks is the loser!\n\nWinners of Round 2:\n- Goku\n- Frieza\n\n--- Round 3 ---\nGoku's attack was partially blocked by Frieza, dealing 10 damage.\nFrieza has 0 health left.\nGoku wins the battle!\nGoku is the winner!\nFrieza is the loser!\n\nWinners of Round 3:\n- Goku\n\nThe champion of the tournament is Goku!\n\n\"\"\""
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/python/hectorio23.py",
    "content": "# Autor: Héctor Adán\n# GitHub: https://github.com/hectorio23\nimport random\n\nclass Fighter:\n    \"\"\"Representa un luchador con atributos y salud inicial.\"\"\"\n    def __init__(self, name, speed, attack, defense):\n        self.name = name\n        self.speed = speed\n        self.attack = attack\n        self.defense = defense\n        self.health = 100\n\n    def take_damage(self, attacker):\n        \"\"\"Calcula el daño recibido tras un ataque.\"\"\"\n        \n        # 20% posibilidad de esquivar\n        if random.random() < 0.2:  \n            print(f\"{self.name} esquivó el ataque de {attacker.name}!\")\n            return\n        damage = max(0, attacker.attack - self.defense)\n        if self.defense > attacker.attack:\n\n            # Recibe solo el 10% del daño\n            damage *= 0.1  \n        self.health -= damage\n        print(f\"{self.name} recibió {damage:.2f} puntos de daño de {attacker.name}. Salud restante: {self.health:.2f}\")\n\ndef battle(fighter1, fighter2):\n    \"\"\"Simula una batalla entre dos luchadores.\"\"\"\n    print(f\"¡Comienza la batalla entre {fighter1.name} y {fighter2.name}!\")\n    attacker, defender = (fighter1, fighter2) if fighter1.speed >= fighter2.speed else (fighter2, fighter1)\n    \n    while fighter1.health > 0 and fighter2.health > 0:\n        defender.take_damage(attacker)\n        \n        # Cambiar roles\n        attacker, defender = defender, attacker  \n    \n    winner = fighter1 if fighter1.health > 0 else fighter2\n    print(f\"¡{winner.name} gana la batalla!\\n\")\n    return winner\n\ndef tournament(fighters):\n    \"\"\"Organiza un torneo de eliminación directa.\"\"\"\n    if len(fighters) & (len(fighters) - 1) != 0:\n        raise ValueError(\"El número de luchadores debe ser potencia de 2.\")\n    \n    round_number = 1\n    while len(fighters) > 1:\n        print(f\"--- Ronda {round_number} ---\")\n        random.shuffle(fighters)\n        next_round = []\n        for i in range(0, len(fighters), 2):\n            winner = battle(fighters[i], fighters[i + 1])\n            next_round.append(winner)\n        fighters = next_round\n        round_number += 1\n    \n    print(f\"¡El ganador del torneo es {fighters[0].name}!\")\n\n# Ejemplo de uso\nfighters = [\n    Fighter(\"Goku\", 90, 95, 80),\n    Fighter(\"Vegeta\", 85, 90, 85),\n    Fighter(\"Piccolo\", 75, 80, 90),\n    Fighter(\"Frieza\", 80, 85, 75),\n]\n\ntournament(fighters)\n"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/python/hozlucas28.py",
    "content": "# pylint: disable=missing-module-docstring,missing-class-docstring,missing-function-docstring,broad-exception-raised,too-many-arguments\n\nfrom abc import ABCMeta, abstractmethod\nfrom typing import TypedDict\nfrom random import choice, random\n\n\n# ---------------------------------------------------------------------------- #\n#                                    CLASSES                                   #\n# ---------------------------------------------------------------------------- #\n\n\n# ---------------------------------- Fighter --------------------------------- #\n\n\nclass AbcFighter(metaclass=ABCMeta):\n    @property\n    @abstractmethod\n    def life(self) -> float:\n        pass\n\n    @property\n    @abstractmethod\n    def attack(self) -> float:\n        pass\n\n    @property\n    @abstractmethod\n    def defense(self) -> float:\n        pass\n\n    @property\n    @abstractmethod\n    def name(self) -> str:\n        pass\n\n    @property\n    @abstractmethod\n    def speed(self) -> float:\n        pass\n\n    @life.setter\n    def life(self, new_life: float) -> None:\n        pass\n\n    @abstractmethod\n    def copy(self) -> \"AbcFighter\":\n        pass\n\n\nclass Fighter(AbcFighter):\n    __life: float\n    __attack: float\n    __defense: float\n    __name: str\n    __speed: float\n\n    def __init__(\n        self,\n        *,\n        life: float = 100,\n        attack: float,\n        defense: float,\n        name: str,\n        speed: float,\n    ) -> None:\n        self.__life = life\n        self.__attack = attack\n        self.__defense = defense\n        self.__name = name\n        self.__speed = speed\n\n    @property\n    def life(self) -> float:\n        return self.__life\n\n    @property\n    def attack(self) -> float:\n        return self.__attack\n\n    @property\n    def defense(self) -> float:\n        return self.__defense\n\n    @property\n    def name(self) -> str:\n        return self.__name\n\n    @property\n    def speed(self) -> float:\n        return self.__speed\n\n    @life.setter\n    def life(self, new_life: float) -> None:\n        self.__life = max(new_life, 0)\n\n    def copy(self) -> AbcFighter:\n        return Fighter(\n            life=self.__life,\n            attack=self.__attack,\n            defense=self.__defense,\n            name=self.__name,\n            speed=self.__speed,\n        )\n\n\n# -------------------------------- Tournament -------------------------------- #\n\n\nShiftInformation = TypedDict(\n    \"ShiftInformation\",\n    {\n        \"attack_damage\": float,\n        \"attacker\": AbcFighter,\n        \"shift\": float,\n        \"victim\": AbcFighter,\n    },\n)\n\nRound = TypedDict(\n    \"Round\",\n    {\n        \"info_per_shifts\": list[ShiftInformation],\n        \"looser\": AbcFighter,\n        \"shifts\": float,\n        \"winner\": AbcFighter,\n    },\n)\n\n\nclass AbcTournament(metaclass=ABCMeta):\n    @property\n    @abstractmethod\n    def phase(self) -> int:\n        pass\n\n    @property\n    @abstractmethod\n    def team_a(self) -> list[AbcFighter]:\n        pass\n\n    @property\n    @abstractmethod\n    def team_b(self) -> list[AbcFighter]:\n        pass\n\n    @property\n    @abstractmethod\n    def winner(self) -> AbcFighter | None:\n        pass\n\n    @abstractmethod\n    def execute_next_round(self) -> Round:\n        pass\n\n\nclass Tournament(AbcTournament):\n    __pair_of_fighters: list[AbcFighter]\n    __phase: int\n    __round: int\n    __team_a: list[AbcFighter]\n    __team_b: list[AbcFighter]\n    __winner: AbcFighter | None\n\n    def __init__(self, *, _team_a: list[AbcFighter], _team_b: list[AbcFighter]) -> None:\n        if len(_team_a) != len(_team_b):\n            raise Exception(\"The number of fighters in both teams must be equal\")\n\n        if len(_team_a) % 2 or len(_team_b) % 2:\n            raise Exception(\"The number of fighters in both teams must be even\")\n\n        self.__pair_of_fighters = []\n        self.__phase = 0\n        self.__round = 0\n        self.__team_a = _team_a\n        self.__team_b = _team_b\n        self.__winner = None\n\n        self.__set_rnd_pair_of_fighters()\n\n    @property\n    def phase(self) -> int:\n        return self.__phase\n\n    @property\n    def team_a(self) -> list[AbcFighter]:\n        return self.__team_a\n\n    @property\n    def team_b(self) -> list[AbcFighter]:\n        return self.__team_b\n\n    @property\n    def winner(self) -> AbcFighter | None:\n        return self.__winner\n\n    def __set_rnd_pair_of_fighters(self) -> None:\n\n        team_a_cpy: list[AbcFighter] = self.__team_a.copy()\n        team_b_cpy: list[AbcFighter] = self.__team_b.copy()\n\n        for _ in range(len(self.__team_a)):\n            rnd_fighter_a: AbcFighter = choice(seq=team_a_cpy)\n            rnd_fighter_b: AbcFighter = choice(seq=team_b_cpy)\n\n            team_a_cpy.remove(rnd_fighter_a)\n            team_b_cpy.remove(rnd_fighter_b)\n\n            self.__pair_of_fighters.append(rnd_fighter_a)\n            self.__pair_of_fighters.append(rnd_fighter_b)\n\n    def execute_next_round(self) -> Round:\n        if self.__winner is not None:\n            raise Exception(\"The tournament already has a winner\")\n        if len(self.__pair_of_fighters) < 2:\n            raise Exception(\"Not enough fighters to execute the next round\")\n\n        self.__round += 1\n        offset: int = self.__round - 1\n\n        fighter_01: AbcFighter = self.__pair_of_fighters[offset]\n        fighter_02: AbcFighter = self.__pair_of_fighters[offset + 1]\n\n        if fighter_01.speed < fighter_02.speed:\n            fighter_01, fighter_02 = fighter_02, fighter_01\n\n        shifts = 0\n        info_per_shifts: list[ShiftInformation] = []\n\n        while fighter_01.life and fighter_02.life:\n            attack_damage = 0\n\n            if random() > 0.2:\n                attack: float = fighter_01.attack\n                defense: float = fighter_02.defense\n\n                attack_damage: float = abs(attack - defense)\n                if defense > attack:\n                    attack_damage = attack_damage * 0.1\n\n                fighter_02.life = fighter_02.life - attack_damage\n\n            shifts += 1\n\n            info_per_shifts.append(\n                {\n                    \"attack_damage\": attack_damage,\n                    \"attacker\": fighter_01.copy(),\n                    \"victim\": fighter_02.copy(),\n                    \"shift\": shifts,\n                }\n            )\n\n            fighter_01, fighter_02 = fighter_02, fighter_01\n\n        fighter_01 = self.__pair_of_fighters[offset]\n        fighter_02 = self.__pair_of_fighters[offset + 1]\n\n        looser_index: int = (offset + 1) if fighter_01.life else offset\n        looser: AbcFighter = self.__pair_of_fighters.pop(looser_index)\n\n        if len(self.__pair_of_fighters) < 2:\n            self.__winner = self.__pair_of_fighters[0]\n\n        if self.__round == len(self.__pair_of_fighters):\n            self.__round = 0\n            self.__phase += 1\n\n        return {\n            \"winner\": fighter_01.copy() if fighter_01.life else fighter_02.copy(),\n            \"looser\": looser,\n            \"shifts\": shifts,\n            \"info_per_shifts\": info_per_shifts,\n        }\n\n\n# ---------------------------------------------------------------------------- #\n#                                     MAIN                                     #\n# ---------------------------------------------------------------------------- #\n\n\nteam_a: list[AbcFighter] = [\n    Fighter(attack=90, defense=80, name=\"Goku\", speed=95),\n    Fighter(attack=85, defense=75, name=\"Vegeta\", speed=90),\n    Fighter(attack=70, defense=65, name=\"Piccolo\", speed=80),\n    Fighter(attack=60, defense=55, name=\"Krillin\", speed=70),\n]\n\nteam_b: list[AbcFighter] = [\n    Fighter(attack=88, defense=78, name=\"Frieza\", speed=92),\n    Fighter(attack=82, defense=72, name=\"Cell\", speed=88),\n    Fighter(attack=75, defense=65, name=\"Majin Buu\", speed=85),\n    Fighter(attack=65, defense=60, name=\"Broly\", speed=75),\n]\n\ntournament: AbcTournament = Tournament(_team_a=team_a, _team_b=team_b)\n\nrounds: int = 0\n\nwhile tournament.winner is None:\n    _round: Round = tournament.execute_next_round()\n\n    rounds += 1\n\n    print(\n        f\"> Round {rounds} \"\n        f\"({_round['winner'].name} vs \"\n        f\"{_round['looser'].name})...\\n\"\n    )\n\n    for shift in _round[\"info_per_shifts\"]:\n        if shift[\"attack_damage\"] > 0:\n            print(\n                f\"> Shift {shift['shift']}: \"\n                f\"{shift['attacker'].name} attacks \"\n                f\"{shift['victim'].name} with an attack damage of \",\n                shift[\"attack_damage\"],\n            )\n        else:\n            print(\n                f\"> Shift {shift['shift']}: \"\n                f\"{shift['attacker'].name} attacks \"\n                f\"{shift['victim'].name}, but {shift['victim'].name} \"\n                \"evades the attack.\"\n            )\n\n    print(\n        f\"\\n> {_round['winner'].name} wins the fight against \"\n        f\"{_round['looser'].name} in {_round['shifts']} shifts!\\n\"\n    )\n\n\nprint(f\"> The winner of the tournament is {tournament.winner.name}!\")\n"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/python/idiegorojas.py",
    "content": "\"\"\" \n# 42 - Torneo Dragon Ball \n\"\"\"\n\n# Simula un Torneo de Artes Marciales, al más puro estilo de la saga, donde participarán diferentes luchadores, y el sistema decidirá quién es el ganador.\n\n# Luchadores:\n    # Nombre.\n    # Tres atributos: velocidad, ataque y defensa\n    # (con valores entre 0 a 100 que tú decidirás).\n    # Comienza cada batalla con 100 de salud.\n\n# Batalla:\n    # En cada batalla se enfrentan 2 luchadores.\n    # El luchador con más velocidad comienza atacando.\n    # El daño se calcula restando el daño de ataque del\n    # atacante menos la defensa del oponente.\n    # El oponente siempre tiene un 20% de posibilidad de\n    # esquivar el ataque.\n    # Si la defensa es mayor que el ataque, recibe un 10%\n    # del daño de ataque.\n    # Después de cada turno y ataque, el oponente pierde salud.\n    # La batalla finaliza cuando un luchador pierde toda su salud.\n\n# Torneo:\n    # Un torneo sólo es válido con un número de luchadores\n    # potencia de 2.\n    # El torneo debe crear parejas al azar en cada ronda.\n    # Los luchadores se enfrentan en rondas eliminatorias.\n    # El ganador avanza a la siguiente ronda hasta que sólo\n    # quede uno.\n    # Debes mostrar por consola todo lo que sucede en el torneo,\n    # así como el ganador.\n\n\nimport random\nimport math\n\nclass Luchador:\n    def __init__(self, nombre: str, velocidad: int, ataque: int, defensa: int) -> None:\n        self.nombre = nombre\n        self.velocidad = velocidad\n        self.ataque = ataque\n        self.defensa = defensa\n        self.salud = 100\n\n    def reset_salud(self):\n        self.salud = 100\n\n    def __str__(self) -> str:\n        return f\"{self.nombre} (VEL:{self.velocidad} ATK:{self.ataque} DEF:{self.defensa})\"\n    \nclass Torneo:\n    def __init__(self):\n        self.participantes = []\n\n    def agregar_participante(self, luchador: Luchador):\n        self.participantes.append(luchador)\n        \n    def es_valido(self):\n        \"\"\"Verifica si el número de participantes es potencia de 2\"\"\"\n        num_participantes = len(self.participantes)\n        return num_participantes > 0 and math.log2(num_participantes).is_integer()\n    \n    def batalla(self, luchador1, luchador2):\n        \"\"\"Simula una batalla entre dos luchadores y retorna al ganador\"\"\"\n        print(f\"\\n🥊 BATALLA: {luchador1.nombre} vs {luchador2.nombre} 🥊\")\n        print(f\"{luchador1}\")\n        print(f\"{luchador2}\")\n        \n        # Resetear salud para la batalla\n        luchador1.reset_salud()\n        luchador2.reset_salud()\n        \n        # Determinar quién ataca primero (el más rápido)\n        if luchador1.velocidad >= luchador2.velocidad:\n            turno = 1  # Luchador 1 empieza\n        else:\n            turno = 2  # Luchador 2 empieza\n        \n        ronda = 1\n        # Mientras ambos tengan salud\n        while luchador1.salud > 0 and luchador2.salud > 0:\n            if turno == 1:\n                atacante, defensor = luchador1, luchador2\n            else:\n                atacante, defensor = luchador2, luchador1\n                \n            print(f\"\\nRonda {ronda} - Ataca {atacante.nombre}\")\n            \n            # Comprobar si el defensor esquiva (20% de probabilidad)\n            if random.random() < 0.2:\n                print(f\"¡{defensor.nombre} esquiva el ataque!\")\n            else:\n                # Calcular daño\n                daño = atacante.ataque - defensor.defensa\n                \n                # Si la defensa es mayor que el ataque\n                if daño <= 0:\n                    daño = int(atacante.ataque * 0.1)  # 10% del ataque\n                    print(f\"¡Defensa superior! {defensor.nombre} recibe sólo {daño} de daño\")\n                else:\n                    print(f\"{defensor.nombre} recibe {daño} de daño\")\n                \n                # Aplicar daño\n                defensor.salud = max(0, defensor.salud - daño)\n                \n            # Mostrar salud actualizada\n            print(f\"Salud de {luchador1.nombre}: {luchador1.salud}\")\n            print(f\"Salud de {luchador2.nombre}: {luchador2.salud}\")\n            \n            # Cambiar turno\n            turno = 1 if turno == 2 else 2\n            ronda += 1\n        \n        # Determinar ganador\n        ganador = luchador1 if luchador1.salud > 0 else luchador2\n        print(f\"\\n🏆 ¡{ganador.nombre} gana la batalla! 🏆\")\n        return ganador\n    \n    def ejecutar_torneo(self):\n        \"\"\"Ejecuta todas las rondas del torneo hasta determinar un campeón\"\"\"\n        if not self.es_valido():\n            print(f\"Error: El número de participantes ({len(self.participantes)}) no es una potencia de 2\")\n            return None\n        \n        ronda = 1\n        luchadores = self.participantes.copy()\n        \n        # Mientras haya más de un luchador\n        while len(luchadores) > 1:\n            print(f\"\\n===== RONDA {ronda} =====\")\n            print(f\"Participantes: {len(luchadores)}\")\n            \n            # Mezclar luchadores para emparejarlos aleatoriamente\n            random.shuffle(luchadores)\n            \n            ganadores = []\n            \n            # Crear parejas y hacer que luchen\n            for i in range(0, len(luchadores), 2):\n                luchador1 = luchadores[i]\n                luchador2 = luchadores[i + 1]\n                \n                ganador = self.batalla(luchador1, luchador2)\n                ganadores.append(ganador)\n            \n            # Actualizar lista de luchadores para la siguiente ronda\n            luchadores = ganadores\n            ronda += 1\n        \n        # El último que queda es el campeón\n        campeon = luchadores[0]\n        print(f\"\\n🌟🏆🌟 ¡{campeon.nombre} ES EL CAMPEÓN DEL TORNEO! 🌟🏆🌟\")\n        return campeon\n\n# Crear luchadores\ndef main():\n    # Crear algunos luchadores de Dragon Ball\n    goku = Luchador(\"Goku\", 85, 90, 70)\n    vegeta = Luchador(\"Vegeta\", 80, 85, 75)\n    piccolo = Luchador(\"Piccolo\", 70, 75, 85)\n    gohan = Luchador(\"Gohan\", 75, 80, 80)\n    krillin = Luchador(\"Krillin\", 65, 60, 65)\n    trunks = Luchador(\"Trunks\", 78, 83, 72)\n    cell = Luchador(\"Cell\", 88, 87, 86)\n    freezer = Luchador(\"Freezer\", 82, 89, 78)\n    \n    # Crear torneo\n    torneo = Torneo()\n    \n    # Agregar luchadores\n    torneo.agregar_participante(goku)\n    torneo.agregar_participante(vegeta)\n    torneo.agregar_participante(piccolo)\n    torneo.agregar_participante(gohan)\n    torneo.agregar_participante(krillin)\n    torneo.agregar_participante(trunks)\n    torneo.agregar_participante(cell)\n    torneo.agregar_participante(freezer)\n    \n    # Ejecutar torneo\n    print(\"¡BIENVENIDOS AL TORNEO DE ARTES MARCIALES!\")\n    print(\"Participantes:\")\n    for i, luchador in enumerate(torneo.participantes, 1):\n        print(f\"{i}. {luchador}\")\n        \n    torneo.ejecutar_torneo()\n\nif __name__ == \"__main__\":\n    main()"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/python/ignaciovihe.py",
    "content": "\"\"\"\n * EJERCICIO:\n * ¡El último videojuego de Dragon Ball ya está aquí!\n * Se llama Dragon Ball: Sparking! ZERO.\n *\n * Simula un Torneo de Artes Marciales, al más puro estilo\n * de la saga, donde participarán diferentes luchadores, y el\n * sistema decidirá quién es el ganador.\n *\n * Luchadores:\n * - Nombre.\n * - Tres atributos: velocidad, ataque y defensa\n *   (con valores entre 0 a 100 que tú decidirás).\n * - Comienza cada batalla con 100 de salud.\n * Batalla:\n * - En cada batalla se enfrentan 2 luchadores.\n * - El luchador con más velocidad comienza atacando.\n * - El daño se calcula restando el daño de ataque del\n *   atacante menos la defensa del oponente.\n * - El oponente siempre tiene un 20% de posibilidad de\n *   esquivar el ataque.\n * - Si la defensa es mayor que el ataque, recibe un 10%\n *   del daño de ataque.\n * - Después de cada turno y ataque, el oponente pierde salud.\n * - La batalla finaliza cuando un luchador pierde toda su salud.\n * Torneo:\n * - Un torneo sólo es válido con un número de luchadores\n *   potencia de 2.\n * - El torneo debe crear parejas al azar en cada ronda.\n * - Los luchadores se enfrentan en rondas eliminatorias.\n * - El ganador avanza a la siguiente ronda hasta que sólo\n *   quede uno.\n * - Debes mostrar por consola todo lo que sucede en el torneo,\n *   así como el ganador.\n\"\"\"\n\nimport random\nimport json\nimport itertools\n\n# La clase Warrior se encarga de gestionar los datos de cada guerrero.\n# He decidido que las estadisticas de cada guerrero se generen aleatoriamente.\nclass Warrior:\n    def __init__(self, name) -> None:\n        self.name = name\n        self.speed = random.randint(0, 100)\n        self.attack = random.randint(0, 100)\n        self.defense = random.randint(0, 100)\n        self.health = 100.0\n\n    def get_name(self):\n        return self.name\n\n    def get_speed(self):\n        return self.speed\n    \n    def get_attack(self):\n        return self.attack\n    \n    def get_minimun_attack(self):\n        return self.attack * 0.1\n    \n    def get_defense(self):\n        return self.defense\n    \n    def get_health(self):\n        return self.health\n    \n    def set_health(self, new_health):\n        self.health = new_health\n    \n    def reduce_health(self, hit: float):\n        self.health = max(0, self.health - hit)\n\n    def evade_attack(self) -> bool:\n        evade = random.randint(1,10)\n        if evade == 2 or evade == 9:\n            return True\n        return False\n    \n    def is_alive(self) -> bool:\n        return self.health > 0\n    \n    def print_statictics(self):\n        print(f\"Nombre: {self.name}\")\n        print(f\"\\tSpeed: {self.speed}\")\n        print(f\"\\tAttack: {self.attack}\")\n        print(f\"\\tDefense: {self.defense}\")\n\n\n# La clase Combat strategy sirve como clase padre para las diferentes estrategias de combate.\n# en principio utilizo las reglas que se indicaba en el enunciado, pero si quisiera añadir\n# nuevas reglas de lucha (pe. el mas veloz ataca con un ratio) con crear una nueva estrategia seria suficiente.\n# De esta forma cuple el principio Solid Abierto a extensión, cerrado a modificación.    \nclass CombatStrategy:\n    def decide_turn_order(self, warrior1, warrior2):\n        raise NotImplementedError\n    \n    def perform_attack(self, attacker, defender):\n        raise NotImplementedError\n    \nclass DefaultCombatStrategy(CombatStrategy):\n    def decide_turn_order(self, warrior1, warrior2):\n        if warrior1.get_speed() >= warrior2.get_speed():\n            return [warrior1, warrior2]\n        else:\n            return [warrior2, warrior1]\n        \n    def perform_attack(self, attacker: Warrior, defender: Warrior):\n        print(f\"\\t{attacker.get_name()} ataca\")            \n        print(f\"\\t{defender.get_name()} intenta evadir el ataque.\")\n        if not defender.evade_attack():\n            print(f\"\\t{defender.get_name()} no consigue evadir el ataque.\")\n            if defender.get_defense() >= attacker.get_attack():\n                damage = attacker.get_minimun_attack()\n                print(f\"\\tLa defensa de {defender.get_name()} es muy fuerte, recibe daño mínimo.\")\n            else:\n                damage = attacker.get_attack() - defender.get_defense()\n                print(f\"\\t{attacker.get_name()} tiene un gran ataque y golpea de lleno.\")\n            defender.reduce_health(damage)\n            return f\"\\t{attacker.get_name()} ataca y causa {damage} puntos de daño a {defender.get_name()}.\"\n        else:\n            return f\"\\t{defender.get_name()} evade el ataque de {attacker.get_name()}.\"\n\n    \n# Esta clase se encarga de gestionar y ejecutar la batalla entre dos contrincantes.\n# gestionando los turnos y utilizando la estrategia de combate indicada,\n# devolviendo al final el ganadopr y el perdedor  \nclass BattleManager:\n    def __init__(self, warriors: dict, strategy: CombatStrategy) -> None:\n        self.warriors = warriors\n        self.strategy = strategy\n\n    def run_fight(self, battle, round):\n        warrior_1: Warrior = self.warriors[battle[0]]\n        warrior_2: Warrior = self.warriors[battle[1]]\n\n        print(f\"{'RONDA':<10} - {round}\")\n        print(f\"{'Batalla:':<10} {warrior_1.get_name():<15} vs {warrior_2.get_name():<15}\")\n        print(f\"{'Velocidad':<10} {warrior_1.get_speed():<15} vs {warrior_2.get_speed():<15}\")\n        print(f\"{'Ataque':<10} {warrior_1.get_attack():<15} vs {warrior_2.get_attack():<15}\")\n        print(f\"{'Defensa':<10} {warrior_1.get_defense():<15} vs {warrior_2.get_defense():<15}\")\n\n        turn_order = self.strategy.decide_turn_order(warrior_1, warrior_2)\n        turn_cycle = itertools.cycle(turn_order)\n\n        while warrior_1.is_alive() and warrior_2.is_alive():\n            attacker = next(turn_cycle)\n            defender = next(turn_cycle)\n            result = self.strategy.perform_attack(attacker, defender)\n            print(result)\n            print(f\"\\t-{warrior_1.get_name()} - {warrior_1.get_health()} PV\")\n            print(f\"\\t-{warrior_2.get_name()} - {warrior_2.get_health()} PV\")\n            next(turn_cycle)# paso de turno para que en la siguiente ronda se cambien los turnos.\n            print(\"\")\n\n        if warrior_1.get_health() > 0:\n            winner , looser = warrior_1.get_name(), warrior_2.get_name()\n            warrior_1.set_health(100)\n        else:\n            winner, looser = warrior_2.get_name(), warrior_1.get_name()\n            warrior_2.set_health(100)\n\n        print(f\"{winner} gana la batalla y sigue adelante\")\n        print(f\"{looser} queda eliminado\")\n        return winner, looser\n\n    \n# La clase Tournamet se encarga de gestionar el torneo, sorteando los emparejamiento de cada ronda \n# y lanzando los combates.\nclass Tournament:\n    def __init__(self, participants_names: list, strategy : CombatStrategy):\n        self.participants_names = participants_names\n        self.warriors = {name : Warrior(name) for name in self.participants_names}\n        strategy = DefaultCombatStrategy()\n        self.battle_manager = BattleManager(self.warriors, strategy)\n        self.battles = []\n        self.round = 0\n\n    def set_new_round(self):\n        self.battles.clear()\n        self.round += 1 \n        while self.participants_names:\n            p1 = self.participants_names.pop(random.randint(0, len(self.participants_names) - 1))\n            p2 = self.participants_names.pop(random.randint(0, len(self.participants_names) - 1))\n            self.battles.append((p1, p2))\n\n    def fight_round(self):\n        for battle in self.battles:\n            winner , looser = self.battle_manager.run_fight(battle, self.round)\n            self.participants_names.append(winner)\n\n\n\ndef main():\n\n    participants = [\n        \"Goku\", \"Vegeta\", \"Gohan\", \"Piccolo\", \"Krillin\", \"Trunks\", \"Bulma\", \"Freezer\",\n        \"Cell\", \"Majin Buu\", \"Yamcha\", \"Tien\", \"Chiaotzu\", \"Master Roshi\", \"Chi-Chi\",\n        \"Android 18\", \"Android 17\", \"Android 16\", \"Bardock\", \"Raditz\", \"Nappa\", \"Videl\",\n        \"Hercule\", \"Pan\", \"Goten\", \"King Kai\", \"Supreme Kai\", \"Kibito\", \"Dende\", \"Korin\",\n        \"Yajirobe\", \"Shenron\", \"Whis\", \"Beerus\", \"Jiren\", \"Hit\", \"Zamasu\", \"Goku Black\",\n        \"Fused Zamasu\", \"Future Trunks\", \"Broly (DBZ)\", \"Broly (DB Super)\", \"Paragus\",\n        \"Kale\", \"Caulifla\", \"Cabba\", \"Toppo\", \"Dyspo\", \"Granolah\", \"Moro\", \"Gas\", \"Merus\",\n        \"Zeno\", \"Grand Priest\", \"King Cold\", \"Cooler\", \"Garlic Jr.\", \"Bojack\", \"Janemba\",\n        \"Tapion\", \"Dabura\", \"Pikkon\", \"Arale\", \"Uub\", \"Launch\", \"Pilaf\", \"Mai\", \"Shu\",\n        \"Dr. Gero\", \"Dr. Briefs\", \"Android 19\", \"Android 13\", \"Android 14\", \"Android 15\",\n        \"Android 21\", \"Turles\", \"Lord Slug\", \"Zarbon\", \"Dodoria\", \"Recoome\", \"Burter\",\n        \"Jeice\", \"Guldo\", \"Captain Ginyu\", \"Babidi\", \"Sorbet\", \"Tagoma\", \"Jaco\", \"Monaka\",\n        \"Vados\", \"Champa\", \"Basil\", \"Lavender\", \"Bergamo\", \"Ribrianne\", \"Kakunsa\", \"Rozie\",\n        \"Cumber\", \"Fu\", \"Hearts\", \"Omega Shenron\", \"Syn Shenron\", \"Nova Shenron\",\n        \"Eis Shenron\", \"Haze Shenron\", \"Oceanus Shenron\", \"Rage Shenron\", \"Naturon Shenron\",\n        \"Baby\", \"General Rilldo\", \"Dr. Myuu\", \"Super 17\", \"Vegeta Jr.\", \"Goku Jr.\",\n        \"Majuub\", \"Puar\", \"Oolong\", \"Gregory\", \"Bubbles\", \"Fortuneteller Baba\", \"Annin\",\n        \"Princess Snake\", \"Gine\", \"Cell Jr.\", \"Zarama\", \"Moro's Goons\", \"Granolahs mother\",\n        \"OG73-I\"\n    ]\n\n    print(f\"Cuantos guerreros quieres que participen en el torneo?\")\n    print(f\"1: 2 Participantes\")\n    print(f\"2: 4 Participantes\")\n    print(f\"3: 8 Participantes\")\n    print(f\"4: 16 Participantes\")\n    print(f\"5: 32 Participantes\")\n    print(f\"6: 64 Participantes\")\n    print(f\"7: 128 Participantes\")\n    number_of_participants = int(input(\" Introduce la opción: \"))\n    participants = participants[0 : 2 ** number_of_participants]\n\n    strategy = DefaultCombatStrategy()\n    my_tournamet = Tournament(participants, strategy)\n    while len(my_tournamet.participants_names) > 1:\n        my_tournamet.set_new_round()\n        my_tournamet.fight_round()\n    print(f\"El ganador del torneo ha sido {my_tournamet.participants_names[0]}\")\n    print(f\"Estadisticas del campeon:\")\n    my_tournamet.warriors[my_tournamet.participants_names[0]].print_statictics()\n\nmain()"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/python/javierfiestasbotella.py",
    "content": "import random\n\nclass Personaje:\n    def __init__(self, nombre, velocidad, ataque, defensa):\n        self.nombre = nombre\n        self.velocidad = velocidad\n        self.ataque = ataque\n        self.defensa = defensa\n        self.salud = 100\n\n    def __str__(self):\n        return f\"{self.nombre} (Velocidad: {self.velocidad}, Ataque: {self.ataque}, Defensa: {self.defensa}, Salud: {self.salud})\"\n    \n    def resetear_salud(self):\n        self.salud = 100\n\n\nclass Torneo:\n    def __init__(self, luchadores):\n        if len(luchadores) & (len(luchadores) - 1) != 0:\n            raise ValueError(\"El número de luchadores debe ser una potencia de 2.\")\n        self.luchadores = luchadores\n        self.rondas = []  # Para almacenar el progreso de cada ronda\n\n    def emparejar_luchadores(self):\n        random.shuffle(self.luchadores)\n        parejas = [(self.luchadores[i], self.luchadores[i + 1]) for i in range(0, len(self.luchadores), 2)]\n        return parejas\n\n    def realizar_batalla(self, luchador1, luchador2):\n        print(f\"\\nBatalla: {luchador1.nombre} vs {luchador2.nombre}\")\n        \n        while luchador1.salud > 0 and luchador2.salud > 0:\n            if luchador1.velocidad >= luchador2.velocidad:\n                atacante, defensor = luchador1, luchador2\n            else:\n                atacante, defensor = luchador2, luchador1\n\n            # Posibilidad de esquivar al 20%\n            if random.random() < 0.2:\n                print(f\"{defensor.nombre} esquiva el ataque de {atacante.nombre}!\")\n            else:\n                # Cálculo de daño\n                if defensor.defensa >= atacante.ataque:\n                    dano = 0.1 * atacante.ataque  # Recibe 10% del daño si la defensa es mayor\n                else:\n                    dano = atacante.ataque - defensor.defensa\n\n                defensor.salud -= max(dano, 0)\n                print(f\"{atacante.nombre} inflige {dano:.2f} puntos de daño a {defensor.nombre}. Salud restante de {defensor.nombre}: {defensor.salud:.2f}\")\n            \n            # Cambiamos rles en la siguiente iteracion\n            luchador1, luchador2 = luchador2, luchador1\n\n        ganador = luchador1 if luchador2.salud <= 0 else luchador2\n        print(f\"¡{ganador.nombre} gana la batalla!\\n\")\n        return ganador\n\n    def realizar_torneo(self):\n        ronda_num = 1\n        while len(self.luchadores) > 1:\n            print(f\"\\n===== Ronda {ronda_num} =====\")\n            parejas = self.emparejar_luchadores()\n            ganadores = []\n\n            for luchador1, luchador2 in parejas:\n                ganador = self.realizar_batalla(luchador1, luchador2)\n                ganadores.append(ganador)\n                ganador.resetear_salud()  # Restablecemos salud para la próxima ronda\n\n            self.luchadores = ganadores\n            self.rondas.append(parejas)\n            ronda_num += 1\n\n        print(f\"\\n===== ¡{self.luchadores[0].nombre} es el ganador del torneo! =====\")\n\n    def mostrar_esquema(self):\n        print(\"\\n===== Esquema del Torneo =====\")\n        for ronda, parejas in enumerate(self.rondas, start=1):\n            print(f\"\\nRonda {ronda}:\")\n            for luchador1, luchador2 in parejas:\n                print(f\"{luchador1.nombre} vs {luchador2.nombre}\")\n\n\ngoku_1 = Personaje('Goku', 89, 92, 88)\nvegeta = Personaje('Vegeta', 89, 92, 88)\npiccolo = Personaje('Piccolo', 75, 95, 70)\ngohan = Personaje('Gohan', 85, 88, 80)\nkrillin = Personaje('Krillin', 60, 50, 55)\ntrunks = Personaje('Trunks', 89, 92, 88)\nfreezer = Personaje('Freezer', 88, 100, 89)\ncell = Personaje('Cell', 88, 95, 80)\nmajin_buu = Personaje('Majin Buu', 81, 85, 95)\nbroly = Personaje('Broly', 78, 70, 85)\nyamcha = Personaje('Yamcha', 55, 45, 40)\nten_shin_han = Personaje('Ten Shin Han', 65, 70, 60)\nandroid_18 = Personaje('Android 18', 80, 85, 75)\nandroid_17 = Personaje('Android 17', 82, 88, 78)\nginyu = Personaje('Ginyu', 68, 72, 65)\nzarbon = Personaje('Zarbon', 63, 66, 62)\nbulma = Personaje('Bulma', 25, 15, 20)\nvidel = Personaje('Videl', 55, 60, 50)\nnappa = Personaje('Nappa', 50, 75, 70)\nraditz = Personaje('Raditz', 60, 68, 60)\n\n\nluchadores = [goku_1, vegeta, piccolo, gohan, krillin, trunks, freezer, cell, majin_buu, \n              broly, yamcha, ten_shin_han, android_18, android_17, ginyu, zarbon]\ntorneo = Torneo(luchadores)\ntorneo.mostrar_esquema()\n\ntorneo.realizar_torneo()\n"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/python/joselorentelopez.py",
    "content": "\"\"\"\nOwner: José Lorente López | joselorente1105@gmail.com | Linkedin: www.linkedin.com/in/josé-lorente-lópez-0121b7148\n\nDescription: A Dragon Ball Sparking Zero-themed Python tournament simulator with classes for managing fighters and orchestrating battles, including speed-based turns and dynamic matchups.\n\nCoding: UTF-8\n\"\"\"\n\nimport random\n\nclass Fighter():\n    \"\"\"\n    A class representing a fighter in the tournament.\n    \"\"\"\n    \n    def __init__(self, name, speed, attack, defense, health=100, turn=False):\n        \"\"\"\n        Initialize a Fighter with specified attributes.\n\n        Args:\n            name (str): The name of the fighter.\n            speed (int): The speed of the fighter, used to determine turn order.\n            attack (int): The attack power of the fighter.\n            defense (int): The defense rating of the fighter.\n            health (float, optional): Initial health of the fighter. Defaults to 100.\n            turn (bool, optional): Indicates if the fighter starts with the turn. Defaults to False.\n\n        Returns:\n            None\n        \"\"\"\n\n        self.name = name\n        self.speed = speed\n        self.attack = attack\n        self.defense = defense\n        self.health = health\n        self.turn = turn\n    \n    def get_name(self):\n        \"\"\"\n        Get the name of the fighter.\n\n        Returns:\n            str: The name of the fighter.\n        \"\"\"\n\n        return self.name\n    \n    def get_speed(self):\n        \"\"\"\n        Get the speed attribute of the fighter.\n\n        Returns:\n            int: The speed of the fighter.\n        \"\"\"\n\n        return self.speed\n    \n    def get_attack(self):\n        \"\"\"\n        Get the attack attribute of the fighter.\n\n        Returns:\n            int: The attack power of the fighter.\n        \"\"\"\n        return self.attack\n    \n    def get_defense(self):\n        \"\"\"\n        Get the defense attribute of the fighter.\n\n        Returns:\n            int: The defense capability of the fighter.\n        \"\"\"\n\n        return self.defense\n    \n    def get_health(self):\n        \"\"\"\n        Get the current health of the fighter.\n\n        Returns:\n            float: The remaining health of the fighter.\n        \"\"\"\n\n        return self.health\n\n    def get_turn(self):\n        \"\"\"\n        Get the current turn status of the fighter.\n\n        Returns:\n            bool: True if it's the fighter's turn, otherwise False.\n        \"\"\"\n\n        return self.turn\n    \n    def set_health(self, health):\n        \"\"\"\n        Set the health of the fighter.\n\n        Args:\n            health (float): The new health value to set for the fighter.\n\n        Returns:\n            None\n        \"\"\"\n\n        self.health = health\n    \n    def set_turn(self, turn):\n        \"\"\"\n        Set the turn status of the fighter.\n\n        Args:\n            turn (bool): True if the fighter should have the next turn, otherwise False.\n\n        Returns:\n            None\n        \"\"\"\n\n        self.turn = turn\n\n\nclass Tournament():\n    \"\"\"\n    A class representing a Dragon Ball Sparking Zero tournament where fighters compete in rounds.\n    \"\"\"\n    \n    def __init__(self) -> None:\n        \"\"\"\n        Initialize the Tournament class.\n        \"\"\"\n        pass\n\n    @staticmethod\n    def round(attacker, defender):\n        \"\"\"\n        Simulates a round where the attacker attacks the defender, potentially causing damage.\n\n        Args:\n            attacker (Fighter): The fighter initiating the attack.\n            defender (Fighter): The fighter attempting to defend against the attack.\n\n        Returns:\n            None\n        \"\"\"\n\n        # Calculate the potential damage based on the difference between attack and defense.\n        # If the defense of the defender is greater than the attack of the attacker, the minimum damage is 5.0\n        attack_damage = max(attacker.get_attack() - defender.get_defense(), 5.0)\n\n        # If the defender's defense is greater than the attacker's attack, reduce the damage.\n        if defender.get_defense() > attacker.get_attack():\n            # Reduce the defender's health by 10% of the calculated damage.\n            reduced_damage = 0.1 * attack_damage\n            defender.set_health(health=defender.get_health() - reduced_damage)\n        else:\n            # Apply the full damage if the defense is insufficient.\n            defender.set_health(health=defender.get_health() - attack_damage)\n                \n    @staticmethod\n    def fight(fighter1, fighter2):\n        \"\"\"\n        Simulates a fight between two fighters until one of them loses all their health.\n\n        Args:\n            fighter1 (Fighter): The first fighter participating in the battle.\n            fighter2 (Fighter): The second fighter participating in the battle.\n\n        Returns:\n            tuple: A tuple containing the winner (Fighter) and the loser (Fighter).\n\n        The fight proceeds in turns, determined by the speed of the fighters:\n            - The faster fighter gets the first turn.\n            - During a turn, the attacking fighter has an 80% chance to successfully hit the opponent.\n            - If the attack is successful, the 'round' method is called to calculate and apply damage.\n            - If the attack fails, the opponent avoids the attack.\n            - Turns alternate between the fighters until one of them has no health remaining.\n        \"\"\"\n\n        # Determine who starts based on speed.\n        if fighter1.get_speed() < fighter2.get_speed():\n            fighter2.set_turn(turn=True)\n        else:\n            fighter1.set_turn(turn=True)\n\n        while fighter1.get_health() > 0 and fighter2.get_health() > 0:\n            # If it is fighter1's turn\n            if fighter1.get_turn():\n                if random.random() < 0.8:\n                    Tournament.round(attacker=fighter1, defender=fighter2)\n                    print(f\"   {fighter2.get_name()} has been injured. Health: {fighter2.get_health()}\")\n                else:\n                    print(f\"   {fighter2.get_name()} has avoided the attack!\")\n\n                # Change the turn to fighter2\n                fighter1.set_turn(turn=False)\n                fighter2.set_turn(turn=True)\n\n            # If it is fighter2's turn\n            else:\n                if random.random() < 0.8:\n                    Tournament.round(attacker=fighter2, defender=fighter1)\n                    print(f\"   {fighter1.get_name()} has been injured. Health: {fighter1.get_health()}\")\n                else:\n                    print(f\"   {fighter1.get_name()} has avoided the attack!\")\n\n                # Change the turn to fighter1\n                fighter2.set_turn(turn=False)\n                fighter1.set_turn(turn=True)\n    \n        # Determine the winner based on remaining health.\n        if fighter1.get_health() > 0:\n            return fighter1, fighter2\n        else:\n            return fighter2, fighter1\n\n    def __define_fighters(self):\n        \"\"\"\n        Defines a list of fighters participating in the tournament.\n\n        This method creates a list of Fighter objects, each representing a character\n        with specific attributes like speed, attack, and defense. The list includes\n        well-known characters from the Dragon Ball universe with varying combat abilities.\n\n        Args:\n            None\n\n        Returns:\n            None\n        \"\"\"\n\n        self.fighters = [\n            Fighter(\"Goku\", speed=95, attack=100, defense=75),\n            Fighter(\"Vegeta\", speed=90, attack=95, defense=70),\n            Fighter(\"Piccolo\", speed=80, attack=75, defense=60),\n            Fighter(\"Gohan\", speed=85, attack=90, defense=65),\n            Fighter(\"Trunks\", speed=88, attack=85, defense=60),\n            Fighter(\"Krillin\", speed=70, attack=60, defense=55),\n            Fighter(\"Frieza\", speed=92, attack=98, defense=65),\n            Fighter(\"Cell\", speed=89, attack=97, defense=70),\n            Fighter(\"Majin Buu\", speed=75, attack=93, defense=65),\n            Fighter(\"Android 18\", speed=85, attack=80, defense=55),\n            Fighter(\"Broly\", speed=94, attack=99, defense=80),\n            Fighter(\"Tien\", speed=72, attack=65, defense=40),\n            Fighter(\"Yamcha\", speed=68, attack=55, defense=10),\n            Fighter(\"Beerus\", speed=100, attack=100, defense=80),\n            Fighter(\"Jiren\", speed=99, attack=98, defense=78),\n            Fighter(\"Hit\", speed=95, attack=97, defense=75)\n        ]\n\n    def __select_number_fighters(self):\n        \"\"\"\n        Prompts the user to select the number of fighters for the tournament.\n\n        This method asks the user to input the desired number of fighters.\n        The input must be a positive integer, a power of 2, and less than or equal \n        to the total number of available fighters. If the input is invalid, the user \n        is prompted to try again until a valid input is provided.\n\n        Args:\n            None\n\n        Returns:\n            None\n        \"\"\"\n\n        while True:\n            try:\n                print('Select the number of fighters: ')\n                self.number_of_fighters = int(input())\n                print(\" \")\n\n                if self.number_of_fighters > len(self.fighters):\n                    print(f\"The number must be less than or equal to {len(self.fighters)}. Please try again.\")\n                elif self.number_of_fighters > 0 and (self.number_of_fighters & (self.number_of_fighters - 1)) == 0:\n                    print(f\"Selected {self.number_of_fighters} fighters.\\n\")\n                    break\n                else:\n                    print(\"The number must be a power of 2 (e.g., 2, 4, 8, 16). Please try again.\")\n\n            except ValueError:\n                print(\"Invalid input. Please enter a positive integer.\")\n\n    def __pair_fighters(self):\n        \"\"\"\n        Randomly pairs up fighters for the tournament battles.\n\n        This method selects a random subset of fighters based on the specified number\n        of fighters and pairs them for the initial matchups. Each pair represents a \n        matchup between two fighters, which will later engage in combat.\n\n        Args:\n            None\n\n        Returns:\n            None\n        \"\"\"\n\n        selected_fighters = random.sample(self.fighters, self.number_of_fighters)\n        self.pairs = [(selected_fighters[i], selected_fighters[i+1]) for i in range(0, len(selected_fighters), 2)]\n        \n        print(\"Matchups generated:\")\n        for fighter1, fighter2 in self.pairs:\n            print(f\"   {fighter1.name} vs {fighter2.name}\")\n\n    def __tournament_fights(self):\n        \"\"\"\n        Conducts the tournament rounds until a final winner is determined.\n\n        This method iteratively manages the rounds of the tournament by pairing fighters,\n        conducting fights, and advancing the winners to the next round. It prints out\n        the details of each matchup, including fighters' stats, and the outcome of each match.\n        After each round, it re-pairs the winners for the next round and announces the losers.\n        The process continues until only one final winner remains.\n\n        Args:\n            None\n\n        Returns:\n            None\n        \"\"\"\n\n        round_number = 1\n        while len(self.pairs) >= 2:\n            winners = []\n            lossers = []\n\n            print(f\"\\n================== Round {round_number} ==================\\n\")\n\n            for i, pair in enumerate(self.pairs):\n                # Print the details of the fighters\n                print(f\"Match {i + 1}: {pair[0].get_name()} vs {pair[1].get_name()}\\n\")\n                print(f\"Health of {pair[0].get_name()}: {pair[0].get_health()} - Speed: {pair[0].get_speed()} - Defense: {pair[0].get_defense()} - Attack: {pair[0].get_attack()}\")\n                print(f\"Health of {pair[1].get_name()}: {pair[1].get_health()} - Speed: {pair[1].get_speed()} - Defense: {pair[1].get_defense()} - Attack: {pair[1].get_attack()}\\n\")\n\n                # Call the fight method and get the winner and loser\n                winner, losser = Tournament.fight(fighter1=pair[0], fighter2=pair[1])\n                winners.append(winner)\n                lossers.append(losser)\n                print(f\"\\nThe winner is: {winner.get_name()}\\n\")\n\n            # Generate new pairings with the winners\n            self.pairs = [(winners[i], winners[i+1]) for i in range(0, len(winners), 2)]\n            print(\" \")\n            print(f\"Round losers: {[losser.get_name() for losser in lossers]}\\n\")\n\n            # Increment the round number for the next iteration\n            round_number += 1\n\n        # Final round between the last two fighters\n        print(f\"\\n================== FINAL ROUND ==================\\n\")\n        \n        print(f\"Health of {self.pairs[0][0].get_name()}: {self.pairs[0][0].get_health()} - Speed: {self.pairs[0][0].get_speed()} - Defense: {self.pairs[0][0].get_defense()} - Attack: {self.pairs[0][0].get_attack()}\")\n        print(f\"Health of {self.pairs[0][1].get_name()}: {self.pairs[0][1].get_health()} - Speed: {self.pairs[0][1].get_speed()} - Defense: {self.pairs[0][1].get_defense()} - Attack: {self.pairs[0][1].get_attack()}\\n\")\n\n        winner, losser = Tournament.fight(fighter1=self.pairs[0][0], fighter2=self.pairs[0][1])\n        final_winner = winner\n\n        print(f\"\\n=========== Winner ===========\\n\")\n        print(f\"The ultimate champion is: {final_winner.get_name()}\\n\")\n\n    def run(self):\n        \"\"\"\n        Runs the complete process of the tournament.\n\n        This method orchestrates the entire tournament flow by calling the necessary \n        methods in sequence. It defines the fighters, allows the user to select the \n        number of participants, pairs up the fighters, and initiates the tournament \n        matches until a champion is determined.\n        \"\"\"\n\n        self.__define_fighters()\n        self.__select_number_fighters()\n        self.__pair_fighters()\n        self.__tournament_fights()\n\n\ndef main():\n    \"\"\"\n    Runs the main function of the project.\n    \"\"\"\n\n    print(\"\\nWELCOME TO DRAGON BALL SPARKING ZERO TOURNAMENT!!!\\n\")\n\n    Tournament().run()\n\n\nif __name__ == \"__main__\":\n    main()"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/python/jstr14.py",
    "content": "import random\nimport math\n\n# Function to check if a number is a power of 2\ndef is_power_of_two(n):\n    if n <= 0:\n        return False\n    log2_n = math.log2(n)\n    return log2_n.is_integer()\n\n# Get the number of fighters ensuring it's a power of 2\ndef get_number_of_fighters() -> int:\n    while True:\n        number_of_fighters = input(\"Enter the number of fighters (must be a power of 2): \")\n        if validate_input(number_of_fighters, min_value=2) and is_power_of_two(int(number_of_fighters)):\n            return int(number_of_fighters)\n        else:\n            print(\"Please enter a number that is a power of 2 (e.g., 2, 4, 8, 16, 32, etc.)\")\n\n# Unified validation function for input\ndef validate_input(input_value, even=False, min_value=0, max_value=100) -> bool:\n    try:\n        number = int(input_value)\n        if even and number % 2 != 0:\n            print(\"Please enter an even number.\")\n            return False\n        if not (min_value <= number <= max_value):\n            print(f\"Please enter a number between {min_value} and {max_value}.\")\n            return False\n        return True\n    except ValueError:\n        print(\"Invalid input. Please enter a valid number.\")\n        return False\n\n# Function to create a list of fighters by collecting their stats\ndef create_fighters(number_of_fighters) -> list:\n    fighters_list = []\n    for i in range(number_of_fighters):\n        name = input(f\"Enter fighter's name #{i + 1}: \")\n        strength = get_fighter_property(f\"Enter {name}'s strength (1-100): \", min_value=1)\n        defense = get_fighter_property(f\"Enter {name}'s defense (0-100): \")\n        velocity = get_fighter_property(f\"Enter {name}'s speed (0-100): \")\n        fighters_list.append(Fighter(name, strength, defense, velocity))\n        print()\n    return fighters_list\n\n# Function to get and validate a fighter's property\ndef get_fighter_property(property_text, min_value = 0) -> int:\n    while True:\n        property_value = input(property_text)\n        if validate_input(property_value, min_value=min_value):\n            return int(property_value)\n\n# Function to shuffle fighters and pair them up\ndef prepare_combats(fighters):\n    print(\"Preparing matchups...\\n\")\n    random.shuffle(fighters)\n    return [fighters[i:i + 2] for i in range(0, len(fighters), 2)]\n\n# Start the tournament and progress through rounds\ndef start_tournament(fighters):\n    print(\"The tournament begins!\\n\")\n    round_number = 1\n    while len(fighters) > 1:\n        print(f\"Round #{round_number}\")\n        combats = prepare_combats(fighters)\n        fighters = play_round(combats)\n        for fighter in fighters:\n            fighter.reset_health()  # Reset health for the next round\n        round_number += 1\n    return fighters[0]\n\n# Play a round and return the list of winners\ndef play_round(fights):\n    winners = []\n    for fighters in fights:\n        print(f\"{fighters[0].name} vs {fighters[1].name}\")\n        winner = combat(fighters)\n        winners.append(winner)\n        print(f\"{winner.name} wins the match!\\n\")\n    return winners\n\n# Manage the combat logic between two fighters\ndef combat(fighters):\n    fighter_1, fighter_2 = (fighters[0], fighters[1]) if fighters[0].velocity > fighters[1].velocity else (fighters[1], fighters[0])\n    turn = 1\n    while fighter_1.health_points > 0 and fighter_2.health_points > 0:\n        print(f\"Turn #{turn}: {fighter_1.name} attacks {fighter_2.name}\")\n        combat_turn(fighter_1, fighter_2)\n        if fighter_2.health_points > 0:  # If fighter 2 survives, they counterattack\n            print(f\"Turn #{turn}: {fighter_2.name} counterattacks {fighter_1.name}\")\n            combat_turn(fighter_2, fighter_1)\n        print(f\"{fighter_1.name}: {fighter_1.health_points} HP, {fighter_2.name}: {fighter_2.health_points} HP\\n\")\n        turn += 1\n    return fighter_1 if fighter_2.health_points <= 0 else fighter_2\n\n# Simulate one attack between two fighters\ndef combat_turn(attacker, defender):\n    if random.random() > 0.2:  # 80% chance to hit\n        damage = max(1, attacker.strength * 0.1) if attacker.strength >= defender.defense else max(1, attacker.strength - defender.defense)\n        defender.health_points -= damage  # Ensure defender loses health points\n        print(f\"{attacker.name} hits {defender.name} for {damage:.2f} damage!\")\n    else:\n        print(f\"{defender.name} dodges the attack!\")\n\n# Fighter class definition with a health reset method\nclass Fighter:\n    def __init__(self, name, strength, defense, velocity):\n        self.name = name\n        self.strength = strength\n        self.defense = defense\n        self.velocity = velocity\n        self.health_points = 100\n\n    def reset_health(self):\n        self.health_points = 100  # Reset health to 100 before each new round\n\n    def __repr__(self):\n        return f\"{self.name}: Strength {self.strength}, Defense {self.defense}, Speed {self.velocity}\"\n\n# Main function to initiate the tournament\ndef main():\n    print(\"Welcome to the Budokai Tenkaichi Tournament!\\n\")\n    number_of_fighters = get_number_of_fighters()\n    fighters = create_fighters(number_of_fighters)\n    print(\"\\nThe participants are:\")\n    for fighter in fighters:\n        print(fighter)\n    winner = start_tournament(fighters)\n    print(f\"\\nThe tournament champion is {winner.name}!\")\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/python/kenysdev.py",
    "content": "# _____________________________________\n# https://github.com/kenysdev\n# 2024 - Python\n# _____________________________________\n# 42 TORNEO DRAGON BALL\n# ------------------------------------\n\n\"\"\"\n* EJERCICIO:\n * ¡El último videojuego de Dragon Ball ya está aquí!\n * Se llama Dragon Ball: Sparking! ZERO.\n *\n * Simula un Torneo de Artes Marciales, al más puro estilo\n * de la saga, donde participarán diferentes luchadores, y el\n * sistema decidirá quién es el ganador.\n *\n * Luchadores:\n * - Nombre.\n * - Tres atributos: velocidad, ataque y defensa\n *   (con valores entre 0 a 100 que tú decidirás).\n * - Comienza cada batalla con 100 de salud.\n * Batalla:\n * - En cada batalla se enfrentan 2 luchadores.\n * - El luchador con más velocidad comienza atacando.\n * - El daño se calcula restando el daño de ataque del\n *   atacante menos la defensa del oponente.\n * - El oponente siempre tiene un 20% de posibilidad de\n *   esquivar el ataque.\n * - Si la defensa es mayor que el ataque, recibe un 10%\n *   del daño de ataque.\n * - Después de cada turno y ataque, el oponente pierde salud.\n * - La batalla finaliza cuando un luchador pierde toda su salud.\n * Torneo:\n * - Un torneo sólo es válido con un número de luchadores\n *   potencia de 2.\n * - El torneo debe crear parejas al azar en cada ronda.\n * - Los luchadores se enfrentan en rondas eliminatorias.\n * - El ganador avanza a la siguiente ronda hasta que sólo\n *   quede uno.\n * - Debes mostrar por consola todo lo que sucede en el torneo,\n *   así como el ganador.\n\"\"\"\n\nimport random\nimport math\n\nclass Fighter:\n    def __init__(self, name: str, speed: int, attack: int, defense: int):\n        self._name: str = name\n        self._speed: int = speed\n        self._attack: int = attack\n        self._defense: int = defense\n        self._health: float = 100\n\n    def execute_attack(self, opponent):\n        print(f\"'{self._name}' ataca a '{opponent._name}'\")\n        \n        damage: float = 0\n        if opponent._defense >= self._attack:\n            damage = self._attack * 0.1 # 10%\n        else: \n            damage = self._attack - opponent._defense\n\n        if not opponent.activate_defense():\n            opponent._health -= damage\n            print(f\"'{opponent._name}' ha recibido '{damage}' de daño\")\n            print(f\"Salud restante '{opponent._health}'\\n\")\n        else:    \n            print(f\"'{opponent._name}' ha esquivado el ataque.\\n\")\n    \n    def activate_defense(self) -> bool:\n        return random.random() <= 0.2  # 20%\n\n# __________________________________________________________\nclass Battle:\n    def __init__(self, fighter1, fighter2):\n        self._fighter1 = fighter1\n        self._fighter2 = fighter2\n        print(f\"__'{self._fighter1._name} VS '{self._fighter2._name}'__\\n\")\n\n    def __combat(self, fighter_a, fighter_b) -> Fighter:\n        while True:\n            fighter_a.execute_attack(fighter_b)\n            if fighter_b._health <= 0:\n                print(f\"--> '{fighter_a._name}' gana la batalla.__\\n\")\n                return fighter_a\n\n            fighter_b.execute_attack(fighter_a)\n            if fighter_a._health <= 0:\n                print(f\"--> '{fighter_b._name}' gana la batalla.\\n\")\n                return fighter_b\n\n    def start(self) -> Fighter:\n        if self._fighter1._speed > self._fighter2._speed:\n            return self.__combat(self._fighter1, self._fighter2)\n        else:\n            return self.__combat(self._fighter2, self._fighter1)\n            \n# __________________________________________________________\nclass Tournament:\n    def __init__(self, fighter, battle, fighters: dict):\n        self._fighter = fighter\n        self._battle = battle\n        self._fighters: dict = fighters\n\n    def __is_power_of_2(self) -> bool:\n        n: int = len(self._fighters)\n        if n <= 1:\n            return False\n        return math.log2(n).is_integer()\n\n    def __get_random_pairs(self) -> tuple:\n        fighters_random = random.sample(list(self._fighters.keys()), 2)\n        fighter1_data = {**self._fighters[fighters_random[0]], 'name': fighters_random[0]}\n        fighter2_data = {**self._fighters[fighters_random[1]], 'name': fighters_random[1]}\n\n        fighter1 = self._fighter(**fighter1_data)\n        fighter2 = self._fighter(**fighter2_data)\n\n        del self._fighters[fighters_random[0]]\n        del self._fighters[fighters_random[1]]\n\n        return fighter1, fighter2\n\n    def start_rounds(self, round_num = 1):\n        if not self.__is_power_of_2():\n            print(\"El número de luchadores debe ser una potencia de 2.\")\n            return\n\n        print(f\"\\n__Ronda #{round_num}__\")\n        next_round: dict = {}\n        while True:\n            fighter1, fighter2 = self.__get_random_pairs()\n            battle = self._battle(fighter1, fighter2)\n            winner = battle.start()\n\n            next_round[winner._name] = {\n                \"speed\": winner._speed, \n                \"attack\": winner._attack, \n                \"defense\": winner._defense\n            }\n\n            if len(self._fighters) == 0 and len(next_round) > 1:\n                self._fighters = next_round\n                self.start_rounds(round_num + 1)\n                break\n            \n            if len(self._fighters) == 0 and len(next_round) == 1:\n                print(f\"\\n--> El vencedor del torneo es '{winner._name}'.\")\n                break        \n\n# __________________________________________________________\nFIGHTERS: dict = {\n    \"Goku\": {\"speed\": 100, \"attack\": 95, \"defense\": 85},\n    \"Vegeta\": {\"speed\": 95, \"attack\": 90, \"defense\": 90},\n    \"Gohan\": {\"speed\": 85, \"attack\": 95, \"defense\": 85},\n    \"Freezer\": {\"speed\": 90, \"attack\": 90, \"defense\": 90},\n    \"Piccolo\": {\"speed\": 90, \"attack\": 85, \"defense\": 90},\n    \"Krillin\": {\"speed\": 85, \"attack\": 75, \"defense\": 75},\n    \"Cell\": {\"speed\": 90, \"attack\": 95, \"defense\": 85},\n    \"Majin Buu\": {\"speed\": 80, \"attack\": 85, \"defense\": 95},\n}\n\nif __name__ == \"__main__\":\n    print(\"Simulación del Torneo de Artes Marciales\")\n    tournament = Tournament(Fighter, Battle, FIGHTERS)\n    tournament.start_rounds()\n\n# end\n"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/python/mhayhem.py",
    "content": "# @Author Daniel Grande (Mhayhem)\n\n# EJERCICIO:\n# ¡El último videojuego de Dragon Ball ya está aquí!\n# Se llama Dragon Ball: Sparking! ZERO.\n#\n# Simula un Torneo de Artes Marciales, al más puro estilo\n# de la saga, donde participarán diferentes luchadores, y el\n# sistema decidirá quién es el ganador.\n#\n# Luchadores:\n# - Nombre.\n# - Tres atributos: velocidad, ataque y defensa\n#   (con valores entre 0 a 100 que tú decidirás).\n# - Comienza cada batalla con 100 de salud.\n# Batalla:\n# - En cada batalla se enfrentan 2 luchadores.\n# - El luchador con más velocidad comienza atacando.\n# - El daño se calcula restando el daño de ataque del\n#   atacante menos la defensa del oponente.\n# - El oponente siempre tiene un 20% de posibilidad de\n#   esquivar el ataque.\n# - Si la defensa es mayor que el ataque, recibe un 10%\n#   del daño de ataque.\n# - Después de cada turno y ataque, el oponente pierde salud.\n# - La batalla finaliza cuando un luchador pierde toda su salud.\n# Torneo:\n# - Un torneo sólo es válido con un número de luchadores\n#   potencia de 2.\n# - El torneo debe crear parejas al azar en cada ronda.\n# - Los luchadores se enfrentan en rondas eliminatorias.\n# - El ganador avanza a la siguiente ronda hasta que sólo\n#   quede uno.\n# - Debes mostrar por consola todo lo que sucede en el torneo,\n#   así como el ganador.\n\nimport random\n\nclass Fighter:\n    def __init__(self, name: str, speed: int, attack: int, defense: int):\n        self.name = name.capitalize()\n        self.speed = speed\n        self.attack = attack\n        self.defense = defense\n        self.health = 0\n\ndef random_attributes() -> int:\n    return random.randint(0, 100)\n\ndef is_power_of_two(num):\n    return num >= 2 and (num & (num - 1)) == 0\n\ndef set_num_participants() -> list:\n    participants = []\n    while True:\n        num = int(input(\"Indique un número\\n\"))\n        if is_power_of_two(num):\n            break\n        else:\n            print(\"Comprueba que el numero sea potencia de 2.\")\n    \n    while len(participants) < num:\n        num_fighter = 1\n        name = input(f\"nombre del luchador {num_fighter}: \")\n        speed = random_attributes()\n        attack = random_attributes()\n        defense = random_attributes()\n        \n        fighter = Fighter(name, speed, attack, defense)\n        \n        participants.append(fighter)\n        num_fighter += 1\n    \n    return participants\n\ndef select_fighters(array) -> object:\n    fighter_1, fighter_2 = random.sample(array, 2)\n    array.remove(fighter_1)\n    array.remove(fighter_2)\n    return fighter_1, fighter_2\n\n\n\ndef check_evasion() -> bool:\n    return random.random() < 0.2\n\ndef damage(fighter_defense: object, fighter_attack: object) -> list:\n    print(f\"Ataca {fighter_attack.name} su poder de ataque es {fighter_attack.attack}.\")\n    if fighter_defense.defense > fighter_attack.attack:\n        damage_attack = fighter_attack.attack * 0.1\n    else:\n        damage_attack = fighter_attack.attack - fighter_defense.defense\n    return damage_attack\n\ndef Kombat(fighter_1: object, fighter_2: object, array: list):\n    if fighter_2.speed > fighter_1.speed:\n        fighter_1, fighter_2 = fighter_2, fighter_1\n    \n    fighter_1.health = 100\n    fighter_2.health = 100\n    round = 0\n    \n    while True:\n        round += 1\n        input(\"Pulsar enter.\")\n        print(f\"Round - {round}\\n\"\n            f\"{fighter_1.name} {fighter_1.health} VS {fighter_2.name} {fighter_2.health}\\n\")\n        \n        if check_evasion():\n            print(f\"{fighter_2.name} esquiva el ataque.\\n\")\n            \n        else:\n            fighter_1_damage = int(damage(fighter_2, fighter_1))\n            print(f\"{fighter_2.name} recibe {fighter_1_damage} puntos de daño.\\n\")\n            fighter_2.health -= fighter_1_damage\n            if fighter_2.health < 0:\n                fighter_2.health = 0\n                \n        if fighter_2.health == 0:\n            break\n        \n        if  check_evasion():\n            print(f\"{fighter_1.name} esquiva el ataque.\\n\")\n            \n        else:\n            fighter_2_damage = int(damage(fighter_1, fighter_2))\n            print(f\"{fighter_1.name} recibe {fighter_2_damage} puntos de daño.\\n\")\n            fighter_1.health -= fighter_2_damage\n            if fighter_1.health < 0:\n                fighter_1.health = 0\n                \n        if fighter_1.health == 0:\n            break\n        \n    if fighter_1.health == 0:\n            print(f\"El ganador es {fighter_2.name} en la ronda {round}\")\n            array.append(fighter_2)\n    else:\n        print(f\"El ganador es {fighter_1.name} en la ronda {round}\")\n        array.append(fighter_1)\n    \n    \n    return array\n\ndef main():\n    fighters = set_num_participants()\n    new_phase = []\n    print(\"¡Va a comenzar el torneo mundial de artes marciales!\\n\"\n        f\"Con un total de {len(fighters)} participantes\\n\")\n    print(\"Los combates seran entre dos luchadores, quien gane pasara a la siguiente fase.\\n\"\n        \"Empecemos con los combates.\\n\")\n    phase = 1\n    kombat_num = 1\n    while True:\n        print(f\"Combate {kombat_num}\")\n        fighter_1, fighter_2 = select_fighters(fighters)\n        Kombat(fighter_1, fighter_2,new_phase)\n        kombat_num += 1\n        if len(fighters) == 0:\n            if len(new_phase) > 1:\n                fighters = new_phase.copy()\n                new_phase.clear()\n                phase += 1\n            else:\n                print(\"¡¡¡¡¡Torneo terminado!!!!!\\n\"\n                    f\"EL ganador es {new_phase[0].name}\")\n                break\n\nif __name__==\"__main__\":\n    main()"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/python/miguelex.py",
    "content": "import random\n\nclass Luchador:\n    def __init__(self, nombre, velocidad, ataque, defensa):\n        self.nombre = nombre\n        self.velocidad = velocidad\n        self.ataque = ataque\n        self.defensa = defensa\n        self.salud = 100\n\n    def esquivar(self):\n        return random.random() < 0.2\n\ndef batalla(luchador1, luchador2):\n    print(f\"¡Batalla entre {luchador1.nombre} y {luchador2.nombre}!\")\n    atacante = luchador1 if luchador1.velocidad >= luchador2.velocidad else luchador2\n    defensor = luchador2 if atacante == luchador1 else luchador1\n\n    while luchador1.salud > 0 and luchador2.salud > 0:\n        if defensor.esquivar():\n            print(f\"{defensor.nombre} esquivó el ataque de {atacante.nombre}!\")\n        else:\n            danio = atacante.ataque - defensor.defensa\n            if danio <= 0:\n                danio = atacante.ataque * 0.1\n            defensor.salud -= danio\n            print(f\"{atacante.nombre} ataca a {defensor.nombre} y causa {danio:.2f} de daño. Salud restante de {defensor.nombre}: {defensor.salud:.2f}\")\n        atacante, defensor = defensor, atacante\n\n    ganador = luchador1 if luchador1.salud > 0 else luchador2\n    print(f\"¡{ganador.nombre} es el ganador de la batalla!\\n\")\n    return ganador\n\ndef main():\n    num_luchadores = int(input(\"Ingrese el número de luchadores (debe ser una potencia de 2): \"))\n    if (num_luchadores & (num_luchadores - 1)) != 0 or num_luchadores <= 0:\n        print(\"El número de luchadores debe ser una potencia de 2.\")\n        return\n\n    luchadores = []\n    for i in range(num_luchadores):\n        nombre = input(f\"Ingrese el nombre del luchador {i + 1}: \")\n        velocidad = int(input(f\"Ingrese la velocidad de {nombre} (0-100): \"))\n        ataque = int(input(f\"Ingrese el ataque de {nombre} (0-100): \"))\n        defensa = int(input(f\"Ingrese la defensa de {nombre} (0-100): \"))\n        luchadores.append(Luchador(nombre, velocidad, ataque, defensa))\n\n    print(\"¡Comienza el torneo de Dragon Ball: Sparking! ZERO!\\n\")\n    while len(luchadores) > 1:\n        ganadores = []\n        random.shuffle(luchadores)\n        for i in range(0, len(luchadores), 2):\n            ganador = batalla(luchadores[i], luchadores[i + 1])\n            ganadores.append(ganador)\n        luchadores = ganadores\n\n    print(f\"¡El ganador del torneo es {luchadores[0].nombre}!\")\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/python/mouredev.py",
    "content": "import random\n\n\nclass Fighter:\n    def __init__(self, name: str, speed: int, attack: int, defense: int):\n        self.name = name\n        self.speed = speed\n        self.attack = attack\n        self.defense = defense\n        self.health = 100\n\n    def reset_health(self):\n        self.health = 100\n\n    def is_alive(self) -> bool:\n        return self.health > 0\n\n    def take_damage(self, damage: int):\n\n        attack_damage = 0\n\n        if random.random() < 0.2:\n            print(f\"{self.name} ha esquivado el ataque\")\n        else:\n            if self.defense >= damage:\n                attack_damage = damage * 0.1\n            else:\n                attack_damage = damage - self.defense\n\n            attack_damage = int(attack_damage)\n\n        self.health = max(self.health - attack_damage, 0)\n        print(f\"{self.name} ha recibido {attack_damage} de daño\")\n        print(f\"Salud restante de {self.name}: {self.health}\")\n\n\nclass Battle:\n\n    def __init__(self, fighter1: Fighter, fighter2: Fighter):\n        self.fighter1 = fighter1\n        self.fighter2 = fighter2\n\n    def fight(self) -> Fighter:\n\n        print(f\"\\n=== {self.fighter1.name} vs. {self.fighter2.name} ===\")\n\n        while self.fighter1.is_alive() and self.fighter2.is_alive():\n\n            if self.fighter1.speed >= self.fighter2.speed:\n                self.turn(self.fighter1, self.fighter2)\n                if self.fighter2.is_alive():\n                    self.turn(self.fighter2, self.fighter1)\n            else:\n                self.turn(self.fighter2, self.fighter1)\n                if self.fighter1.is_alive():\n                    self.turn(self.fighter1, self.fighter2)\n\n        if self.fighter1.is_alive():\n            print(f\"\\n{self.fighter1.name} es el ganador de la batalla\")\n            return self.fighter1\n        else:\n            print(f\"\\n{self.fighter2.name} es el ganador de la batalla\")\n            return self.fighter2\n\n    def turn(self, attacker: Fighter, defender: Fighter):\n        print(f\"\\n{attacker.name} ataca a {defender.name}\")\n        defender.take_damage(attacker.attack)\n\n\nclass Tournament:\n\n    def __init__(self, fighters: list):\n        if not self.is_power_of_two(len(fighters)):\n            raise ValueError(\n                \"El número de luchadores debe ser una potencia de 2\")\n        self.fighters = fighters\n\n    def start(self):\n        round = 1\n        while len(self.fighters) > 1:\n\n            print(f\"\\n=== Ronda {round} ===\")\n\n            random.shuffle(self.fighters)\n\n            winners = []\n\n            for index in range(0, len(self.fighters), 2):\n                fighter1 = self.fighters[index]\n                fighter2 = self.fighters[index + 1]\n\n                battle = Battle(fighter1, fighter2)\n                winner = battle.fight()\n                winner.reset_health()\n                winners.append(winner)\n\n            self.fighters = winners\n            round += 1\n\n        print(f\"\\n¡El ganador del torneo es {self.fighters[0].name}!\")\n\n    def is_power_of_two(self, n) -> bool:\n        if n <= 0:\n            return False\n        while n % 2 == 0:\n            n //= 2\n        return n == 1\n\n\nfighters = [\n    Fighter(\"Goku\", 90, 95, 80),\n    Fighter(\"Vegeta\", 95, 90, 82),\n    Fighter(\"Piccolo\", 80, 85, 90),\n    Fighter(\"Freezer\", 95, 90, 75),\n    Fighter(\"Krillin\", 95, 90, 75),\n    Fighter(\"Célula\", 92, 70, 73),\n    Fighter(\"Gohan\", 97, 95, 70),\n    Fighter(\"Trunks\", 88, 88, 88)\n]\n\ntournament = Tournament(fighters)\ntournament.start()\n"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/python/neslarra.py",
    "content": "r\"\"\"\n EJERCICIO:\n ¡El último videojuego de Dragon Ball ya está aquí!\n Se llama Dragon Ball: Sparking! ZERO.\n\n Simula un Torneo de Artes Marciales, al más puro estilo\n de la saga, donde participarán diferentes luchadores, y el\n sistema decidirá quién es el ganador.\n\n Luchadores:\n - Nombre.\n - Tres atributos: velocidad, ataque y defensa\n   (con valores entre 0 a 100 que tú decidirás).\n - Comienza cada batalla con 100 de salud.\n Batalla:\n - En cada batalla se enfrentan 2 luchadores.\n - El luchador con más velocidad comienza atacando.\n - El daño se calcula restando el daño de ataque del\n   atacante menos la defensa del oponente.\n - El oponente siempre tiene un 20% de posibilidad de\n   esquivar el ataque.\n - Si la defensa es mayor que el ataque, recibe un 10%\n   del daño de ataque.\n - Después de cada turno y ataque, el oponente pierde salud.\n - La batalla finaliza cuando un luchador pierde toda su salud.\n Torneo:\n - Un torneo sólo es válido con un número de luchadores\n   potencia de 2.\n - El torneo debe crear parejas al azar en cada ronda.\n - Los luchadores se enfrentan en rondas eliminatorias.\n - El ganador avanza a la siguiente ronda hasta que sólo\n   quede uno.\n - Debes mostrar por consola aquello lo que sucede en el torneo,\n   así como el ganador.\n\"\"\"\nfrom random import randint\n\n\nclass Fighter:\n\n    def __init__(self, name: str, attack: int, defense: int, speed: int):\n        self.name = name\n        self.attack = attack\n        self.defense = defense\n        self.health = 100\n        self.speed = speed\n\n    def set_health(self, damage: int):\n        self.health -= damage\n\n\nclass Fight:\n\n    def __init__(self, fighter1: Fighter, fighter2: Fighter):\n        self.fighter1 = fighter1\n        self.fighter2 = fighter2\n        self.round = 1\n\n    @staticmethod\n    def attack(attack, defense, dodge):\n        damage = attack - defense if attack >= defense else ((defense - attack) / 10).__ceil__()\n        damage = damage if dodge > 2 else 0\n        if dodge < 3:\n            print(\"\\t\\tAttack dodged => damage 0\")\n        else:\n            print(f\"\\t\\tEffective attack: damage injuried {damage}\")\n        return damage\n\n    @staticmethod\n    def dodge():\n        y = 0\n        for x in range(0, 1000):\n            y = randint(1, 10)\n        return y\n\n    def fight(self):\n        if self.round % 2:\n            if self.fighter1.speed >= self.fighter2.speed:\n                attacker = self.fighter1\n                defender = self.fighter2\n            else:\n                attacker = self.fighter2\n                defender = self.fighter1\n        else:\n            if self.fighter1.speed >= self.fighter2.speed:\n                attacker = self.fighter2\n                defender = self.fighter1\n            else:\n                attacker = self.fighter1\n                defender = self.fighter2\n        self.round += 1\n        dodging = self.dodge()\n        print(f\"\\t{attacker.name} attacks with power/speed {attacker.attack}/{attacker.speed} <=> health level = {attacker.health}\")\n        print(f\"\\t{defender.name} defends with power/speed {defender.defense}/{defender.speed} <=> health level = {defender.health}\")\n        damage = self.attack(attacker.attack, defender.defense, dodging)\n        defender.set_health(damage)\n\n\nclass Tournament:\n\n    def __init__(self, competitors: list):\n        if competitors.__len__() in [pow(2, x) for x in range(1, 11)]:\n            pass\n        else:\n            raise \"No hay suficientes inscriptos.\"\n        self.fight = None\n        self.competitors = competitors\n\n    def combat(self):\n        winner = None\n        self.fight = Fight(self.competitors.pop(randint(0, self.competitors.__len__() - 1)), self.competitors.pop(randint(0, self.competitors.__len__() - 1)))\n        print(f\"\\nRound {self.fight.fighter1.name} vs {self.fight.fighter2.name}\")\n        while True:\n            self.fight.fight()\n            if self.fight.fighter1.health <= 0:\n                winner = self.fight.fighter2\n                break\n            if self.fight.fighter2.health <= 0:\n                winner = self.fight.fighter1\n                break\n        self.competitors.append(winner)\n        return winner\n\n\ntolo = Fighter(\"Tolo\", 77, 48, 27)\npipa = Fighter(\"Pipa\", 69, 81, 42)\nchino = Fighter(\"Chino\", 91, 37, 31)\nlalo = Fighter(\"Lalo\", 65, 78, 33)\n\ntorneo = Tournament([tolo, pipa, chino, lalo])\n\nwhile torneo.competitors.__len__() > 1:\n    winner = torneo.combat()\n    print(f\"\\n{winner.name} Won this combat and pass to the next round\")\n\nprint(f\"\\nn{torneo.competitors[0].name} Won the tounament.\")\n"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/python/oriaj3.py",
    "content": "\"\"\"\n * EJERCICIO:\n * ¡El último videojuego de Dragon Ball ya está aquí!\n * Se llama Dragon Ball: Sparking! ZERO.\n *\n * Simula un Torneo de Artes Marciales, al más puro estilo\n * de la saga, donde participarán diferentes luchadores, y el\n * sistema decidirá quién es el ganador.\n *\n */\n\"\"\"\nfrom colorama import Fore, Style\nimport random\n\n# Funciones para imprimir texto con colores\ndef title(text: str):\n    print(f\"{Fore.CYAN}{text}{Style.RESET_ALL}\")\n\ndef result(text: str):\n    print(f\"{Fore.LIGHTYELLOW_EX}{text}{Style.RESET_ALL}\")\n\ndef info(text: str):\n    print(f\"{Fore.WHITE}{text}{Style.RESET_ALL}\")\n\n# Clase para definir a los luchadores\n# La suma de velocidad, ataque y defensa debe ser 100\nclass fighter: \n\n    def __init__(self, name: str, speed: int, attack: int, defense: int):\n        if speed < 0 or attack < 0 or defense < 0:\n            raise ValueError(\"Los valores de velocidad, ataque y defensa deben ser positivos\")\n        if speed + attack + defense != 100:\n            raise ValueError(\"La suma de velocidad, ataque y defensa debe ser 100\")\n        self.name = name\n        self.speed = speed\n        self.attack = attack\n        self.defense = defense\n        self.health = 100\n# Clase para definir una batalla entre dos luchadores\n# Después de las batallas, el luchador ganador recupera 50 de vida\nclass battle:\n    def __init__(self, fighter1: fighter, fighter2: fighter):\n        title(f\"\\n --* Batalla entre {fighter1.name} y {fighter2.name} *--\") \n        self.turn = 0\n        if fighter1.speed > fighter2.speed:\n            self.attacker = fighter1\n            self.defender = fighter2\n            info(f\"{fighter1.name} ataca primero\")\n        elif fighter1.speed < fighter2.speed:\n            self.attacker = fighter2\n            self.defender = fighter1\n            info(f\"{fighter2.name} ataca primero\")\t\n        else:\n            random_money = random.randint(1, 2)\n            if random_money == 1:\n                self.attacker = fighter1\n                self.defender = fighter2\n                info(\"A misma velocidad, luchador 1 ataca primero\")\n            else:\n                self.attacker = fighter2\n                self.defender = fighter1\n                info(\"A misma velocidad, luchador 2 ataca primero\")\n    \n    def attack(self):\n        title(f\"\\n [Turno {self.turn}]: {self.attacker.name} ataca a {self.defender.name}\")\n        if self.defender.defense > self.attacker.attack:\n            damage = 0.1 * self.attacker.attack\n        else:\n            damage = self.attacker.attack - self.defender.defense\n        squish = random.randint(1, 5)\n        if squish == 1:\n            damage = 0\n            info(\"El ataque ha fallado\")\n        else: \n            info(f\"{self.attacker.name} ha atacado a {self.defender.name} y le ha hecho {damage} de daño\")\n        self.defender.health -= damage\n        \n        info(f\"{self.defender.name} tiene {self.defender.health} de vida.\") \n\n    def change_turn(self):\n        self.attacker, self.defender = self.defender, self.attacker\n\n    def start(self):\n        while self.attacker.health > 0 and self.defender.health > 0:\n            self.attack()\n            self.change_turn()\n            self.turn += 1\n        if self.attacker.health > 0:\n            result(f\"¹... {self.attacker.name} ha ganado\")\n            #Cuando gana el luchador, se le suma 50 de vida\n            self.attacker.health += 50    \n        else:\n            result(f\"¹... {self.defender.name} ha ganado\")\n            #Cuando gana el luchador, se le suma 50 de vida\n            self.defender.health += 50\n\n# Clase para definir un torneo\nclass tournament:\n    def __init__ (self, fighters: list):\n        if len(fighters) % 2 != 0:\n            raise ValueError(\"El número de luchadores debe ser par\")\n        self.fighters = fighters\n        self.round = 0\n        self.winners = []\n        self.loosers = []\n\n    def start(self):\n        while len(self.fighters) >= 2:\n            self.round += 1\n            title(f\"\\n [*] Ronda {self.round}[*]\")\n            random.shuffle(self.fighters) # Barajamos los luchadores\n            for i in range(0, len(self.fighters), 2):\n                batalla = battle(self.fighters[i], self.fighters[i+1])\n                batalla.start()\n                if self.fighters[i].health > 0:\n                    self.winners.append(self.fighters[i])\n                    self.loosers.append(self.fighters[i+1])\n                else:\n                    self.winners.append(self.fighters[i+1])\n                    self.loosers.append(self.fighters[i])\n            self.fighters = self.winners\n            self.winners = []\n        result(f\"\\n 🏁🏁🏁 El torneo ha terminado [*]\")\n        result(f\"🏆🏆🏆 El ganador del torneo es {self.fighters[0].name}\")\n\n\"\"\"\n    * TORNEO DRAGON BALL *\n\"\"\"\n\nluchador1 = fighter(name=\"Goku\", speed=33, attack=34, defense=33)\nluchador2 = fighter(name=\"Vegeta\", speed=34, attack=30, defense=36)\nluchador3 = fighter(name=\"Piccolo\", speed=30, attack=35, defense=35)\nluchador4 = fighter(name=\"Krillin\", speed=0, attack=50, defense=50)\nluchador5 = fighter(name=\"Yamcha\", speed=50, attack=25, defense=25)\nluchador6 = fighter(name=\"Tenshinhan\", speed=20, attack=40, defense=40)\nluchador7 = fighter(name=\"Chaoz\", speed=24, attack=38, defense=38)\nluchador8 = fighter(name=\"Yajirobe\", speed=15, attack=37, defense=48)\n\ntorneo = tournament([luchador1, luchador2, luchador3, luchador4, luchador5, luchador6, luchador7, luchador8])\ntorneo.start()\n\n"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/python/pyramsd.py",
    "content": "import random\nfrom dataclasses import dataclass\n\ndef gen_values():\n    while True:\n        yield random.randint(0, 100)\ngen = gen_values()\n\ndef es_potencia_de_dos(n):\n    return n > 0 and (n & (n - 1)) == 0\n\ndef gen_parejas(luchadores_con_poderes):\n    # Creamos una lista de luchadores que aún no han sido emparejados\n    disponibles = luchadores_con_poderes[:]\n    parejas = []\n    \n    while len(disponibles) > 1:\n        # Elegimos dos luchadores aleatorios de la lista de luchadores disponibles\n        luchador1 = random.choice(disponibles)\n        disponibles.remove(luchador1)  # Quitamos el luchador1 de la lista\n        luchador2 = random.choice(disponibles)\n        disponibles.remove(luchador2)  # Quitamos el luchador2 de la lista\n        \n        # Añadimos la pareja a la lista de parejas\n        parejas.append((luchador1, luchador2))\n    \n    return parejas\n\n@dataclass\nclass Luchador:\n    nombre: str\n    velocidad: int\n    ataque: int\n    defensa: int\n    salud: int = 100\n\nlista_luchadores = [\"Goku\", \"Vegeta\", \"Piccolo\", \"Gohan\", \"Krillin\", \"Trunks\", \"Freezer\", \"Majin Buu\"]\nluchadores_con_poderes = []\n\nif not es_potencia_de_dos(len(lista_luchadores)):\n        raise ValueError(\"El número de luchadores debe ser una potencia de 2.\")\n\nprint(\"+\"+\"-\"*16+\"+\")\nprint(\"| Participantes: |\")\nprint(\"+\"+\"-\"*51+\"+\")\nprint(f\"| {'Nombre':<10} {'|':<3} {'Velocidad':<11} {'|':<3} {'Ataque':<8} | {'Defensa'} |\")\nprint(\"=\"*52+\"+\")\n\nfor luchador in lista_luchadores:\n    luchador_valores = Luchador(luchador, next(gen), next(gen), next(gen))\n    luchadores_con_poderes.append(luchador_valores)\n    print(f\"| {luchador_valores.nombre:<10} {'|':<7} {luchador_valores.velocidad:<7} {'|':<5} {luchador_valores.ataque:<6} {'|':<4} {luchador_valores.defensa:<4} |\")\n    print(\"+------------+---------------+------------+---------+\")\n\nparejas = gen_parejas(luchadores_con_poderes)\n\nprint(\"\\n+\"+\"-\"*35+\"+\")\nprint(f\"| {'Parejas de batalla:':<34}|\")\nprint(\"+\"+\"-\"*35+\"+\")\nfor pareja in parejas:\n    print(f\"| {pareja[0].nombre:<10} {'|':<3} {'vs':<4} {'|':<3} {pareja[1].nombre:<9} |\")\nprint(\"+\"+\"-\"*35+\"+\")\n\ndef batalla(luchador1, luchador2):\n    print(f\"\\n\\033[38;5;214m[!!] Inicia batalla: {luchador1.nombre} vs {luchador2.nombre}\\033[0m\")\n\n    # Determinar quién ataca primero\n    atacante, defensor = (luchador1, luchador2) if luchador1.velocidad >= luchador2.velocidad else (luchador2, luchador1)\n\n    while luchador1.salud > 0 and luchador2.salud > 0:\n        print(f\"\\nTurno de {atacante.nombre} atacando a {defensor.nombre}\")\n\n        # Determinar si el ataque es esquivado\n        if random.random() < 0.2:\n            print(f\"{defensor.nombre} esquiva el ataque!\")\n        else:\n            # Calcular daño\n            if atacante.ataque > defensor.defensa:\n                dano = atacante.ataque - defensor.defensa\n            else:\n                dano = int(atacante.ataque * 0.1)\n\n            defensor.salud -= dano\n            print(f\"\\033[31m[-] {defensor.nombre} recibe {dano} de daño. Salud restante: {defensor.salud} \\033[0m\")\n\n        # Cambiar roles para el siguiente turno\n        atacante, defensor = defensor, atacante\n\n    ganador = luchador1 if luchador1.salud > 0 else luchador2\n    return ganador\n\n\ndef torneo(parejas_iniciales):\n\n    ronda = 1\n    \n    print(\"\\n¡Comienza el torneo!\")\n\n    luchadores = [l for pareja in parejas_iniciales for l in pareja]\n\n    while len(luchadores) > 1:\n        print(f\"\\n--- Ronda {ronda} ---\")\n        \n        # Usar las parejas iniciales en la primera ronda\n        if ronda == 1:\n            parejas = parejas_iniciales\n        else:\n            parejas = gen_parejas(luchadores)  # Generar nuevas parejas en rondas siguientes\n    \n        ganadores = []\n\n        for pareja in parejas:\n            ganador = batalla(pareja[0], pareja[1])\n            ganadores.append(ganador)\n            print(f\"\\n\\033[34m[!] Ganador de la batalla entre {pareja[0].nombre} y {pareja[1].nombre}: {ganador.nombre}\\033[0m\")\n\n        luchadores = ganadores\n        ronda += 1\n\n    print(\"\\n¡El torneo ha terminado!\")\n    print(f\"\\033[32m[+] El ganador del torneo es: {luchadores[0].nombre}\\033[0m\")\n\ntorneo(parejas)\n"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/python/raulG91.py",
    "content": "import random\nclass Figther:\n\n    def __init__(self,name,speed,attack,defense):\n        self.name = name\n        self.speed = speed\n        self.attack = attack\n        self.defense = defense\n        self._health = 100\n    def setHeath(self,value:int):\n        self._health = value\n    def getHealth(self):\n        return self._health\n    def getName(self):\n        return self.name    \n    def getAttack(self):\n        return self.attack\n    def getDefense(self):\n        return self.defense\n    def getSpeed(self):\n        return self.speed\n    def reduceHealth(self,value):\n        self._health -= value\n\ndef is_pow_of_two(number):\n    if number <= 0:\n        return False\n    return (number & (number - 1)) == 0        \ndef simulate_combat(figther1:Figther,figther2:Figther)->Figther:\n\n    figth_turn = []\n    figther1.setHeath(100)\n    figther2.setHeath(100)\n    if figther1.getSpeed() > figther2.getSpeed():\n        figth_turn.append(figther1)\n        figth_turn.append(figther2)\n    else:\n        figth_turn.append(figther2)\n        figth_turn.append(figther1)\n\n    i = 0\n    turno = 1\n    print(f'Combate entre {figth_turn[i].getName()} y {figth_turn[(i+1)%2].getName()}')\n    while figther1.getHealth() > 0 and figther2.getHealth() > 0:\n        print(f'Turno {turno}')\n        damage = abs(figth_turn[i].getAttack() - figth_turn[(i+1)%2].getDefense())\n        skip = random.randint(0,100)\n        if skip > 20:\n            #Oponent doesn't skip the attack\n            if figth_turn[(i+1)%2].getDefense() > damage:\n                figth_turn[(i+1)%2].reduceHealth(damage*0.1)\n            else:\n                figth_turn[(i+1)%2].reduceHealth(damage)  \n            print(f'Luchador {figth_turn[i].getName()} ataca con {damage} a {figth_turn[(i+1)%2].getName()} salud restante es: {figth_turn[(i+1)%2].getHealth()}')\n        else:\n            print(f'{figth_turn[(i+1)%2].getName()} esquiva el ataque de {figth_turn[i].getName()} ')\n        i = (i+1) %2 \n        turno += 1\n\n    if figther1.getHealth() > 0:\n        print(f'Ganador del combate es: {figther1.getName()}')\n        return figther1\n    else:\n        print(f'El ganador del combate es: {figther2.getName()}')\n        return figther2\n\ndef main():\n\n    figthers = []\n    figther = Figther(\"Goku\",98,88,70)\n    figthers.append(figther)\n    figther = Figther(\"Krilin\",90,80,50)\n    figthers.append(figther)\n    figther = Figther(\"Vegeta\",95,85,45)\n    figthers.append(figther)\n    figther = Figther(\"Tortuga duende\",80,90,53)\n    figthers.append(figther)\n    figther = Figther(\"Piccolo\",85,78,51)\n    figthers.append(figther)\n    figther = Figther(\"Freezer\",94,81,42)\n    figthers.append(figther)\n    figther = Figther(\"Celula\",90,89,65)\n    figthers.append(figther)\n    figther = Figther(\"Zarbon\",50,50,30)\n    figthers.append(figther)\n    if is_pow_of_two(len(figthers)):\n        number_rounds = len(figthers)//2\n        round = figthers.copy()\n    \n        for round_number in range(1,number_rounds):\n            print(f'Empezando ronda {round_number}')\n            winners = []\n            while len(round) > 0:\n                choice = random.randint(0,len(round)-1)\n                figther1 = round[choice]\n                del(round[choice])\n                choice = random.randint(0,len(round)-1)\n                fighter2 = round[choice]\n                del(round[choice])\n                winner = simulate_combat(figther1=figther1,figther2=fighter2)\n                winners.append(winner)\n            round = winners.copy() \n            if len(round) == 1:\n                print(f'Ganador del torneo es: {round[0].getName()}')   \n    else:\n        print(\"Numero de participantes debe ser potencia de 2\")\n\n\nmain()"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/python/rigo93acosta.py",
    "content": "\"\"\"\n* EJERCICIO:\n * ¡El último videojuego de Dragon Ball ya está aquí!\n * Se llama Dragon Ball: Sparking! ZERO.\n *\n * Simula un Torneo de Artes Marciales, al más puro estilo\n * de la saga, donde participarán diferentes luchadores, y el\n * sistema decidirá quién es el ganador.\n *\n * Luchadores:\n * - Nombre.\n * - Tres atributos: velocidad, ataque y defensa\n *   (con valores entre 0 a 100 que tú decidirás).\n * - Comienza cada batalla con 100 de salud.\n * Batalla:\n * - En cada batalla se enfrentan 2 luchadores.\n * - El luchador con más velocidad comienza atacando.\n * - El daño se calcula restando el daño de ataque del\n *   atacante menos la defensa del oponente.\n * - El oponente siempre tiene un 20% de posibilidad de\n *   esquivar el ataque.\n * - Si la defensa es mayor que el ataque, recibe un 10%\n *   del daño de ataque.\n * - Después de cada turno y ataque, el oponente pierde salud.\n * - La batalla finaliza cuando un luchador pierde toda su salud.\n * Torneo:\n * - Un torneo sólo es válido con un número de luchadores\n *   potencia de 2.\n * - El torneo debe crear parejas al azar en cada ronda.\n * - Los luchadores se enfrentan en rondas eliminatorias.\n * - El ganador avanza a la siguiente ronda hasta que sólo\n *   quede uno.\n * - Debes mostrar por consola todo lo que sucede en el torneo,\n *   así como el ganador.\n\"\"\"\nimport random\n\nclass Fighter:\n    \n    def __init__(self, name: str, attr: dict, health: int) -> None:\n        self.name = name\n        self.attr = attr\n        self.health = health\n\n    def __str__(self) -> str:\n        return f\"{self.name} - {self.health} HP\"\n    \n    def __repr__(self) -> str:\n        return f\"{self.name}\"\n    \n    def reset_health(self) -> None:\n        self.health = 100\n\n    @property\n    def speed(self) -> int:\n        return self.attr['speed']\n    \n    @property\n    def attack(self) -> int:\n        return self.attr['attack']\n    \n    @property\n    def defense(self) -> int:\n        return self.attr['defense']\n    \n    @property\n    def is_alive(self) -> bool:\n        return self.health > 0\n    \n    def take_damage(self, damage: int) -> None:\n        \n        attack_damage = 0\n\n        if random.random() < 0.2:\n            # print(f\"{self.name} ha esquivado el ataque\")\n            attack_damage = 0\n        else:\n            if self.defense >= damage:\n                attack_damage = damage * 0.1\n            else:\n                attack_damage = damage - self.defense\n\n            attack_damage = int(attack_damage)\n\n        self.health = max(self.health - attack_damage, 0)\n        # print(f\"{self.name} ha recibido {attack_damage} de daño\")\n        # print(f\"Salud restante de {self.name}: {self.health}\")\n\n\nclass Battle:\n    \n    def __init__(self, fighterA: Fighter, fighterB: Fighter) -> None:\n        self.FighterA = fighterA\n        self.FighterB = fighterB\n\n    def start(self, verbose=True) -> Fighter:\n        if verbose:\n            print(f\"\\n***** {self.FighterA.name} vs. {self.FighterB.name} *****\")\n\n        if self.FighterA.speed > self.FighterB.speed:\n            attacker = self.FighterA\n            defender = self.FighterB\n        else:\n            attacker = self.FighterB\n            defender = self.FighterA\n\n        while attacker.is_alive and defender.is_alive:\n            \n            defender.take_damage(attacker.attack)\n            if defender.is_alive:\n                attacker.take_damage(defender.attack)\n\n        if self.FighterA.is_alive:\n            # print(f\"\\n{self.FighterA.name} es el ganador de la batalla\")\n            return self.FighterA\n        else:\n            # print(f\"\\n{self.FighterB.name} es el ganador de la batalla\")\n            return self.FighterB\n\n\nclass Tournament:\n    \n    def __init__(self, fighters: list, verbose: bool) -> None:\n        self.fighters = fighters\n        self.verbose = verbose\n\n    def start(self) -> Fighter:\n        round = 1\n        if self.verbose:\n            print(\"¡¡¡TORNEO DRAGON BALL!!!\")\n            print(f\"Participantes: {', '.join([fighter.name for fighter in self.fighters])}\")\n\n\n        if len(self.fighters) % 2 != 0:\n            raise ValueError(f\"El número de luchadores debe ser potencia de 2 y hay {len(self.fighters)} luchadores.\")\n        \n        while len(self.fighters) > 1:\n            if self.verbose:\n                print(f\"\\n***** Ronda {round} *****\")\n\n            random.shuffle(self.fighters)\n            winners = []\n            for i in range(0, len(self.fighters), 2):\n                battle = Battle(self.fighters[i], self.fighters[i+1])\n                if self.verbose:\n                    winner = battle.start()\n                else:\n                    winner = battle.start(verbose=False)\n                if self.verbose:\n                    print(f\"{winner.name} es el ganador de la batalla\")\n                winners.append(winner)\n            \n            self.fighters = winners\n            self.reset_health()\n            round += 1\n\n        return self.fighters[0]\n\n    def reset_health(self) -> None:\n        for fighter in self.fighters:\n            fighter.reset_health()\n\nif __name__ == \"__main__\":\n\n    fighters = [\n        Fighter(\"Goku\", {\"speed\": 80, \"attack\": 95, \"defense\": 85}, 100),\n        Fighter(\"Vegeta\", {\"speed\": 70, \"attack\": 80, \"defense\": 90}, 100),\n        Fighter(\"Gohan\", {\"speed\": 90, \"attack\": 70, \"defense\": 80}, 100),\n        Fighter(\"Piccolo\", {\"speed\": 60, \"attack\": 60, \"defense\": 60}, 100),\n        Fighter(\"Freezer\", {\"speed\": 95, \"attack\": 90, \"defense\": 75}, 100),\n        Fighter(\"Krillin\", {\"speed\": 95, \"attack\": 90, \"defense\": 75}, 100),\n        Fighter(\"Célula\", {\"speed\": 92, \"attack\": 70, \"defense\": 73}, 100),\n        Fighter(\"Trunks\", {\"speed\": 88, \"attack\": 88, \"defense\": 88}, 100)\n    ]\n\n    print(\"\\nSIMULACIÓN DE TORNEO\")\n    result_sim = [Tournament(fighters, verbose=False).start().name\n                  for _ in range(1000)]\n    \n    from collections import Counter\n    print(\"\\nRESULTADOS DE LA SIMULACIÓN\")\n    counter = dict(Counter(result_sim))\n    counter = sorted(counter.items(), key=lambda x: x[1], reverse=True)\n    print(f\"El favorito para ganar es: {counter[0][0]} con {counter[0][1]/1000} de probabilidades.\\n\\n\")\n\n    tournament = Tournament(fighters, verbose=True)\n    winner = tournament.start()\n    print(\"\\n¡¡¡TORNEO FINALIZADO!!!\")\n    print(f\"El ganador del torneo es: {winner.name}\")\n    print(\"¡¡¡Felicidades!!!\")\n\n\n\n    "
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/rust/kenysdev.rs",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - Rust\n_____________________________________\n42 TORNEO DRAGON BALL\n-------------------------------------\n* EJERCICIO:\n * ¡El último videojuego de Dragon Ball ya está aquí!\n * Se llama Dragon Ball: Sparking! ZERO.\n *\n * Simula un Torneo de Artes Marciales, al más puro estilo\n * de la saga, donde participarán diferentes luchadores, y el\n * sistema decidirá quién es el ganador.\n *\n * Luchadores:\n * - Nombre.\n * - Tres atributos: velocidad, ataque y defensa\n *   (con valores entre 0 a 100 que tú decidirás).\n * - Comienza cada batalla con 100 de salud.\n * Batalla:\n * - En cada batalla se enfrentan 2 luchadores.\n * - El luchador con más velocidad comienza atacando.\n * - El daño se calcula restando el daño de ataque del\n *   atacante menos la defensa del oponente.\n * - El oponente siempre tiene un 20% de posibilidad de\n *   esquivar el ataque.\n * - Si la defensa es mayor que el ataque, recibe un 10%\n *   del daño de ataque.\n * - Después de cada turno y ataque, el oponente pierde salud.\n * - La batalla finaliza cuando un luchador pierde toda su salud.\n * Torneo:\n * - Un torneo sólo es válido con un número de luchadores\n *   potencia de 2.\n * - El torneo debe crear parejas al azar en cada ronda.\n * - Los luchadores se enfrentan en rondas eliminatorias.\n * - El ganador avanza a la siguiente ronda hasta que sólo\n *   quede uno.\n * - Debes mostrar por consola todo lo que sucede en el torneo,\n *   así como el ganador.\n\n[dependencies]\nrand = \"0.8.5\"\n*/\n\nuse rand::Rng;\nuse std::collections::HashMap;\nuse std::f64;\n\n// __________________________________________________________\n#[derive(Debug)]\nstruct Fighter {\n    name: String,\n    speed: i32,\n    attack: i32,\n    defense: i32,\n    health: f64,\n}\n\nimpl Fighter {\n    fn new(name: &str, speed: i32, attack: i32, defense: i32) -> Self {\n        Self {\n            name: name.to_string(), speed, attack, defense, health: 100.0,\n        }\n    }\n\n    fn execute_attack(&self, opponent: &mut Fighter) {\n        println!(\"'{}' ataca a '{}'\", self.name, opponent.name);\n\n        let damage = if opponent.defense >= self.attack {\n            self.attack as f64 * 0.1 // 10%\n        } else {\n            (self.attack - opponent.defense) as f64\n        };\n\n        if !Self::activate_defense() {\n            opponent.health -= damage;\n            println!(\"'{}' ha recibido '{}' de daño\", opponent.name, damage);\n            println!(\"Salud restante '{}'\\n\", opponent.health);\n        } else {\n            println!(\"'{}' ha esquivado el ataque.\\n\", opponent.name);\n        }\n    }\n\n    fn activate_defense() -> bool {\n        rand::thread_rng().gen_bool(0.2) // 20%\n    }\n}\n\n// __________________________________________________________\nstruct Battle {fighter1: Fighter, fighter2: Fighter}\n\nimpl Battle {\n    fn new(fighter1: Fighter, fighter2: Fighter) -> Self {\n        println!(\"__'{} VS '{}'__\\n\", fighter1.name, fighter2.name);\n        Self { fighter1, fighter2 }\n    }\n\n    fn combat(mut fighter_a: Fighter, mut fighter_b: Fighter) -> Fighter {\n        loop {\n            fighter_a.execute_attack(&mut fighter_b);\n            if fighter_b.health <= 0.0 {\n                println!(\"--> '{}' gana la batalla.__\\n\", fighter_a.name);\n                return fighter_a;\n            }\n\n            fighter_b.execute_attack(&mut fighter_a);\n            if fighter_a.health <= 0.0 {\n                println!(\"--> '{}' gana la batalla.\\n\", fighter_b.name);\n                return fighter_b;\n            }\n        }\n    }\n\n    fn start(self) -> Fighter {\n        if self.fighter1.speed > self.fighter2.speed {\n            Self::combat(self.fighter1, self.fighter2)\n        } else {\n            Self::combat(self.fighter2, self.fighter1)\n        }\n    }\n}\n\n// __________________________________________________________\n#[derive(Clone, Debug)]\nstruct FighterStats {speed: i32, attack: i32, defense: i32,}\n\nstruct Tournament {fighters: HashMap<String, FighterStats>,}\n\nimpl Tournament {\n    fn new(fighters: HashMap<String, FighterStats>) -> Self {\n        Self { fighters }\n    }\n\n    fn is_power_of_2(&self) -> bool {\n        self.fighters.len() > 1 && (self.fighters.len() as f64).log2().fract() == 0.0\n    }\n\n    fn get_random_pairs(&mut self) -> (Fighter, Fighter) {\n        use rand::seq::SliceRandom;\n        \n        let selected_names: Vec<String> = self.fighters.keys()\n            .cloned()\n            .collect::<Vec<_>>()\n            .choose_multiple(&mut rand::thread_rng(), 2)\n            .cloned()\n            .collect();\n    \n        let stats1 = self.fighters.remove(&selected_names[0]).unwrap();\n        let stats2 = self.fighters.remove(&selected_names[1]).unwrap();\n    \n        (\n            Fighter::new(&selected_names[0], stats1.speed, stats1.attack, stats1.defense),\n            Fighter::new(&selected_names[1], stats2.speed, stats2.attack, stats2.defense)\n        )\n    }\n\n    fn start_rounds(&mut self, round_num: i32) {\n        if !self.is_power_of_2() {\n            println!(\"El número de luchadores debe ser una potencia de 2.\");\n            return;\n        }\n\n        println!(\"\\n__Ronda #{}__\", round_num);\n        let mut next_round = HashMap::new();\n\n        loop {\n            let (fighter1, fighter2) = self.get_random_pairs();\n            let battle = Battle::new(fighter1, fighter2);\n            let winner = battle.start();\n\n            next_round.insert(\n                winner.name.clone(),\n                FighterStats {\n                    speed: winner.speed,\n                    attack: winner.attack,\n                    defense: winner.defense,\n                },\n            );\n\n            if self.fighters.is_empty() {\n                if next_round.len() > 1 {\n                    self.fighters = next_round;\n                    self.start_rounds(round_num + 1);\n                    break;\n                } else {\n                    println!(\"\\n--> El vencedor del torneo es '{}'.\", winner.name);\n                    break;\n                }\n            }\n        }\n    }\n}\n\n// __________________________________________________________\nfn main() {\n    let fighters = HashMap::from([\n        (String::from(\"Goku\"), FighterStats { speed: 100, attack: 95, defense: 85 }),\n        (String::from(\"Vegeta\"), FighterStats { speed: 95, attack: 90, defense: 90 }),\n        (String::from(\"Gohan\"), FighterStats { speed: 85, attack: 95, defense: 85 }),\n        (String::from(\"Freezer\"), FighterStats { speed: 90, attack: 90, defense: 90 }),\n        (String::from(\"Piccolo\"), FighterStats { speed: 90, attack: 85, defense: 90 }),\n        (String::from(\"Krillin\"), FighterStats { speed: 85, attack: 75, defense: 75 }),\n        (String::from(\"Cell\"), FighterStats { speed: 90, attack: 95, defense: 85 }),\n        (String::from(\"Majin Buu\"), FighterStats { speed: 80, attack: 85, defense: 95 })\n    ]);\n\n    println!(\"Simulación del Torneo de Artes Marciales\");\n    let mut tournament = Tournament::new(fighters);\n    tournament.start_rounds(1);\n}\n"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/sql/Nicojsuarez2.sql",
    "content": "# #42 TORNEO DRAGON BALL\n> #### Dificultad: Difícil | Publicación: 14/10/24 | Corrección: 21/10/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * ¡El último videojuego de Dragon Ball ya está aquí!\n * Se llama Dragon Ball: Sparking! ZERO.\n *\n * Simula un Torneo de Artes Marciales, al más puro estilo\n * de la saga, donde participarán diferentes luchadores, y el\n * sistema decidirá quién es el ganador.\n *\n * Luchadores:\n * - Nombre.\n * - Tres atributos: velocidad, ataque y defensa\n *   (con valores entre 0 a 100 que tú decidirás).\n * - Comienza cada batalla con 100 de salud.\n * Batalla:\n * - En cada batalla se enfrentan 2 luchadores.\n * - El luchador con más velocidad comienza atacando.\n * - El daño se calcula restando el daño de ataque del\n *   atacante menos la defensa del oponente.\n * - El oponente siempre tiene un 20% de posibilidad de\n *   esquivar el ataque.\n * - Si la defensa es mayor que el ataque, recibe un 10%\n *   del daño de ataque.\n * - Después de cada turno y ataque, el oponente pierde salud.\n * - La batalla finaliza cuando un luchador pierde toda su salud.\n * Torneo:\n * - Un torneo sólo es válido con un número de luchadores\n *   potencia de 2.\n * - El torneo debe crear parejas al azar en cada ronda.\n * - Los luchadores se enfrentan en rondas eliminatorias.\n * - El ganador avanza a la siguiente ronda hasta que sólo\n *   quede uno.\n * - Debes mostrar por consola todo lo que sucede en el torneo,\n *   así como el ganador.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/typescript/Rafacv23.ts",
    "content": "// Hecho por @Rafacv23 | https://github.com/Rafacv23 | https://twitter.com/rafacanosa  | https://www.rafacanosa.dev\n\n// Global constants\nconst EVADE_CHANCE: number = 0.2\nconst HEALTH: number = 100\n\nclass Fighter {\n  nombre: string\n  velocidad: number\n  ataque: number\n  defensa: number\n  salud: number\n\n  constructor(\n    nombre: string,\n    velocidad: number,\n    ataque: number,\n    defensa: number\n  ) {\n    this.nombre = nombre\n    this.velocidad = this.checkAttribute(velocidad, \"velocidad\")\n    this.ataque = this.checkAttribute(ataque, \"ataque\")\n    this.defensa = this.checkAttribute(defensa, \"defensa\")\n    this.salud = HEALTH // Inicialmente, todos tienen 100 de salud\n  }\n\n  // ensure that the attribute are between 0 and 100\n  checkAttribute(value: number, attribute: string): number {\n    if (value < 0 || value > 100) {\n      throw new Error(`El valor de ${attribute} debe ser entre 0 y 100`)\n    }\n    return value\n  }\n\n  attack(defender: Fighter) {\n    if (defender.salud === 0) {\n      console.log(`${defender.nombre} ha perdido toda su salud`)\n      return\n    }\n\n    // calculamos si el defensor evita el ataque o no\n    const evade = Math.random()\n\n    if (evade < EVADE_CHANCE) {\n      console.log(`${defender.nombre} ha esquivado el ataque`)\n      return\n    }\n    // Calcular el daño\n    let damage: number\n\n    if (defender.defensa > this.ataque || defender.defensa === this.ataque) {\n      damage = this.ataque * 0.1 // Recibe solo el 10% del ataque\n      console.log(`${defender.nombre} bloquea gran parte del daño!`)\n    } else {\n      damage = this.ataque - defender.defensa // Full damage\n    }\n\n    // Evitar que el daño sea negativo\n    if (damage < 0) damage = 0\n\n    // Aplicar el daño al defensor\n    defender.salud -= damage\n\n    console.log(\n      `${this.nombre} ha atacado a ${defender.nombre} con ${damage.toFixed(\n        2\n      )} de daño`\n    )\n    console.log(`Salud restante de ${defender.nombre}: ${defender.salud}`)\n  }\n\n  showInfo() {\n    console.log(`Nombre: ${this.nombre}`)\n    console.log(`Velocidad: ${this.velocidad}`)\n    console.log(`Ataque: ${this.ataque}`)\n    console.log(`Defensa: ${this.defensa}`)\n    console.log(`Salud: ${this.salud}`)\n  }\n}\n\nconst fighters: Fighter[] = [\n  new Fighter(\"Goku\", 85, 95, 80),\n  new Fighter(\"Vegeta\", 80, 90, 85),\n  new Fighter(\"Piccolo\", 70, 75, 90),\n  new Fighter(\"Gohan\", 88, 92, 78),\n  new Fighter(\"Trunks\", 78, 88, 82),\n  new Fighter(\"Kefla\", 60, 90, 85),\n  new Fighter(\"Freezer\", 75, 85, 80),\n  new Fighter(\"Cell\", 83, 87, 90),\n]\n\nfunction shuffleFighters(fighters: Fighter[]): Fighter[] {\n  for (let i = fighters.length - 1; i > 0; i--) {\n    const j = Math.floor(Math.random() * (i + 1))\n    ;[fighters[i], fighters[j]] = [fighters[j], fighters[i]]\n  }\n  return fighters\n}\n\nfunction drawFighters() {\n  let round = 1\n\n  while (fighters.length > 1) {\n    if (fighters.length === 2) {\n      console.log(`\\n--- Ronda Final ---`)\n    } else {\n      console.log(`\\n--- Ronda ${round} ---`)\n    }\n\n    // Shuffle fighters for random matchups\n    shuffleFighters(fighters)\n\n    // Process battles in pairs\n    for (let i = 0; i < fighters.length; i++) {\n      const fighter1 = fighters[i]\n      const fighter2 = fighters[i + 1]\n\n      console.log(\n        `\\n${fighter1.nombre} (Salud: ${fighter1.salud}) vs ${fighter2.nombre} (Salud: ${fighter2.salud})`\n      )\n\n      // Decide who attacks first based on speed\n      let attacker: Fighter, defender: Fighter\n      if (fighter1.velocidad >= fighter2.velocidad) {\n        attacker = fighter1\n        defender = fighter2\n      } else {\n        attacker = fighter2\n        defender = fighter1\n      }\n\n      // Fight until one of them loses\n      while (attacker.salud > 0 && defender.salud > 0) {\n        attacker.attack(defender)\n        if (defender.salud > 0) {\n          defender.attack(attacker)\n        }\n      }\n\n      // Remove the defeated fighter\n      if (attacker.salud <= 0) {\n        console.log(`${attacker.nombre} ha sido eliminado`)\n        console.log(`${defender.nombre} avanza a la siguiente ronda`)\n        fighters.splice(fighters.indexOf(attacker), 1)\n      } else if (defender.salud <= 0) {\n        console.log(`${defender.nombre} ha sido eliminado`)\n        console.log(`${attacker.nombre} avanza a la siguiente ronda`)\n        fighters.splice(fighters.indexOf(defender), 1)\n      }\n    }\n\n    round++\n  }\n\n  // The last remaining fighter is the winner\n  if (fighters.length === 1) {\n    console.log(\"\\n¡El torneo ha terminado! El ganador/a es:\")\n    fighters[0].showInfo()\n  }\n}\n\n// function that sims the tournament\n;(function tournament() {\n  if (\n    (fighters.length & (fighters.length - 1)) !== 0 ||\n    fighters.length === 0\n  ) {\n    console.log(\"El número de luchadores debe ser una potencia de 2\")\n    return\n  }\n  drawFighters()\n})()\n"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/typescript/didix16.ts",
    "content": "/*\n * Autor: didix16\n * EJERCICIO:\n * ¡El último videojuego de Dragon Ball ya está aquí!\n * Se llama Dragon Ball: Sparking! ZERO.\n *\n * Simula un Torneo de Artes Marciales, al más puro estilo\n * de la saga, donde participarán diferentes luchadores, y el\n * sistema decidirá quién es el ganador.\n *\n * Luchadores:\n * - Nombre.\n * - Tres atributos: velocidad, ataque y defensa\n *   (con valores entre 0 a 100 que tú decidirás).\n * - Comienza cada batalla con 100 de salud.\n * Batalla:\n * - En cada batalla se enfrentan 2 luchadores.\n * - El luchador con más velocidad comienza atacando.\n * - El daño se calcula restando el daño de ataque del\n *   atacante menos la defensa del oponente.\n * - El oponente siempre tiene un 20% de posibilidad de\n *   esquivar el ataque.\n * - Si la defensa es mayor que el ataque, recibe un 10%\n *   del daño de ataque.\n * - Después de cada turno y ataque, el oponente pierde salud.\n * - La batalla finaliza cuando un luchador pierde toda su salud.\n * Torneo:\n * - Un torneo sólo es válido con un número de luchadores\n *   potencia de 2.\n * - El torneo debe crear parejas al azar en cada ronda.\n * - Los luchadores se enfrentan en rondas eliminatorias.\n * - El ganador avanza a la siguiente ronda hasta que sólo\n *   quede uno.\n * - Debes mostrar por consola todo lo que sucede en el torneo,\n *   así como el ganador.\n *  --------------\n *  NOTAS: Algunos retoques añadidos\n *  1. Asumo que cada vez que un luchado pasa de ronda, se le cura la vida\n *  2. Mecánica de crítico: Si el atacante tiene 70 o más de ataque, tiene un 20% de probabilidad de hacer un crítico, sino solo un 10%\n *  3. Los críticos hacen el doble de daño y si el defensor tiene más defensa que el ataque del atacante o son iguales, el crítico ignora la defensa\n *  4. Si el personaje tiene una velocidad de 70 o más, tendrá más probabilidad de esquivar el ataque (+10%) pero menos probabilidad de hacer un crítico (-5%)\n *  5. En caso de que el daño sea 0 o negativo, el daño será el 10% del ataque del atacante.\n *  6. Si un personaje tiene 0 de velocidad, no podrá esquivar los ataques pero tendrá superarmadura, haciendo que los golpes con daño positivo solo le quiten el 10% (min 1)\n *  7. Si un personaje tiene 100 de velocidad, será supersónico y tendrá un 50% de probabilidad de esquivar los ataques!!!\n *  8. Mecánica de ki y SPARKING! MODE. Los personajes tienen 50 de ki máximo (y pueden empezar con 20 o 30) y disponen de 3 ataques especiales que comsumen ki, el débil consume 20, el fuerte 40 y la definitiva 50.\n *  Los turnos deberán usarse para atacar o recuperar ki. Si un personaje se queda sin ki, no podrá usar ataques especiales y está obligado a recuperar ki.\n *  Cada personaje dipondrá de una velocidad de recuperación de ki (cantidad a recuperar entre 10 o 20 por turno) y una probabilidad de recuperar ki que dependerá de la cantidad de ki restante\n *  en su turno. La probabilidad de recuperar ki dependerá de la cantidad de recuperación de ki del personaje, a cuanta más cantidad menos probabilidad.\n *  La probabilidad de escoger recuperación en vez de ataque dependerá de la cantidad de ki restante. Para ello generaremos 2 tipos de curvas cúbicas a trozos (natural cubic spline) que aproximen la probabilidad:\n *      - una para los que recuperan 10 de ki por turno (Ki Recharge = 10)\n *      - otra para los que recuperan 20 de ki por turno (Ki Recharge = 20)\n *  Si un personaje tiene menos de 20 de ataque se considerará débil pero como bonificación para balancear un poco la cosa, sus ataques de ki débil tendrán un 20% más de daño y los fuertes un 50% más de daño además de tener 10% más de probabilidad de ignorar la defensa del defensor.\n *  Los ataques de ki no se calculan como los ataques normales, sino que tienen un daño base (atk+%) y una probabilidad de ignorar la defensa del defensor además de no tener críticos:\n *  Los ataques de ki débiles producen un daño equivalente al atk + 25% (+50% si personaje debil; min 2 daño) y tienen una probabilidad del 20% (30% si personaje debil) de ignorar el 80% de la defensa del defensor.\n *  Los ataques de ki fuertes producen un daño equivalente al atk + 50% (+100% si personaje debil; min 5 daño) y tienen una probabilidad del 40% (50% si personaje debil) de ignorar el 80% de la defensa del defensor.\n *  Los ataques de ki definitivos producen un daño equivalente al atk + 200% (+300% si personaje debil; min 10 daño) y tienen un 70% de probabilidad de ignorar el 100% de la defensa del defensor.\n *  Además, para realizar un ataque de ki definitivo, el personaje debe entrar en modo SPARKING!. Para ello, el personaje debe tener 50 de ki y la probabilidad de entrar en modo SPARKING! se calcula como:\n *     - 50% si el personaje no es considerado débil\n *     - 60% si el personaje es considerado débil\n *     - 65% + ((atk-70)/30)*20% si el personaje es considerado fuerte (70atk => 65%, 100atk => 85%)\n *  Entrar en modo SPARKING! consumirá un turno. En este modo, el personaje obtendrá:\n *     - +5% de probabilidad de crítico adicional\n *     - +10% de probabilidad de esquivar adicional\n *     - +10% de atk adicional\n *     - -20% de reducción defensa\n *     - posibilidad de realizar el ataque definitivo de ki\n *  Este modo consta de un contador especial de 50 unidades las cuales cuando llegue a 0, el personaje saldrá del modo SPARKING!\n *  Durante el modo SPARKING! el personaje consumirá contador SPARKING! según el ataque que realice:\n *     - 5 unidades por ataque físico\n *     - 20 unidades por ataque de ki débil\n *     - 40 unidades por ataque de ki fuerte\n *     - 50 unidades por ataque de ki definitivo (consume 50 de ki y sale del modo SPARKING!)\n *  Mientras el contador sea positivo, se podrá realizar cualquier combinación de ataque posible. Cuando el contador llegue a 0, el personaje saldrá del modo SPARKING!. Realizar un ataque definitivo de ki consumirá el contador y el ki del personaje.\n *  Para elegir entre ataque físico o de ki, dependerá de si tiene ki disponible (o contador SPARKING!) y si lo tiene entonces la probabilidad se calcula como:\n *     - Si modo SPARKING! activo\n *          - 10% para el ataque de ki débil\n *          - 20% para el ataque de ki fuerte\n *          - 10% para ataques físicos\n *          - 60% para ataque definitivo de ki\n *     - Si ki disponible >= 40\n *          - 15% para el ataque de ki débil\n *          - 25% para el ataque de ki fuerte\n *          - 60% para ataques físicos\n *     - Si ki disponible >= 20 y < 40\n *         - 25% para el ataque de ki débil\n *         - 75% para ataques físicos\n *    - Si ki disponible < 20\n *      -  100% para ataques físicos\n */\n\n// utils\nconst rand = Math.random;\nconst randInt = (min: number, max: number) => Math.floor(rand() * (max - min + 1) + min);\nconst randValuesFrom = <T>(list: Array<T>) => list[randInt(0, list.length - 1)];\nconst sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));\n\nenum AttackType {\n    PHYSICAL_ATK,\n    KI_WEAK_ATK,\n    KI_STRONG_ATK,\n    KI_ULTIMATE_ATK,\n}\n\nnamespace AttackType {\n    export function isPhysicalAtk(atkType: AttackType): boolean {\n        return atkType === AttackType.PHYSICAL_ATK;\n    }\n\n    export function isKiWeakAtk(atkType: AttackType): boolean {\n        return atkType === AttackType.KI_WEAK_ATK;\n    }\n\n    export function isKiStrongAtk(atkType: AttackType): boolean {\n        return atkType === AttackType.KI_STRONG_ATK;\n    }\n\n    export function isKiUltimateAtk(atkType: AttackType): boolean {\n        return atkType === AttackType.KI_ULTIMATE_ATK;\n    }\n}\n\nconst printAtack = (\n    fighter1: Fighter,\n    fighter2: Fighter,\n    damage: number,\n    evaded: boolean,\n    isCrit: boolean,\n    defenseIgnored: boolean\n) => {\n    if (!evaded)\n        console.log(\n            `${fighter1.getName()} ataca 🤜 a ${fighter2.getName()} y le hace ${damage} de daño 💔⬇️. ${\n                isCrit ? ' 💥💥 ¡UUH ESO HA SIDO UN CRÍTICO! 💥💥' : ''\n            }${defenseIgnored ? ' 💥🛡️ ¡UUH LE HA PUESTO TODA SU ENERGÍA Y HA ATRAVESADO LA DEFENSA! 🛡️💥' : ''}`\n        );\n    else\n        console.log(\n            `${fighter1.getName()} ataca 🤜 a ${fighter2.getName()} pero ${fighter2.getName()} esquiva el ataque! 🤸‍♂️💨`\n        );\n};\n\nconst kiAtackTypeMsg: Record<AttackType | number, string> = {\n    [AttackType.KI_WEAK_ATK]: 'un ataque de ki débil',\n    [AttackType.KI_STRONG_ATK]: 'un ataque de ki fuerte',\n    [AttackType.KI_ULTIMATE_ATK]: 'el ataque definitivo de ki',\n};\n\nconst printKiAtack = (\n    fighter1: Fighter,\n    fighter2: Fighter,\n    damage: number,\n    evaded: boolean,\n    ignoreDefense: boolean,\n    atkType: AttackType\n) => {\n    const fighter1Name = fighter1.getName();\n    const fighter2Name = fighter2.getName();\n    const kiAtkIcon = `🫸〰️${AttackType.isKiUltimateAtk(atkType) ? '🧿' : ''}`;\n    if (!evaded)\n        console.log(\n            `${fighter1Name} ataca ${kiAtkIcon} a ${fighter2Name} con ${\n                kiAtackTypeMsg[atkType]\n            } y le hace ${damage} de daño 💔⬇️. ${ignoreDefense ? ' 💥💥 ¡UUH ESA ATAQUE HA HECHO MELLA! 💥💥' : ''}`\n        );\n    else\n        console.log(\n            `${fighter1Name} ataca ${kiAtkIcon} a ${fighter2Name} con ${kiAtackTypeMsg[atkType]} pero ${fighter2Name} esquiva el ataque! 🤸‍♂️💨`\n        );\n};\n\nconst printHealthAndKiOf = (fighter: Fighter) => {\n    console.log(\n        `${fighter.getName()} tiene ${fighter.getHealth()} de vida ❤️ y ${\n            !fighter.isInSparkingMode()\n                ? fighter.getKi() + ' de ki ⚡'\n                : fighter.getSparkingGauge() + ' de SPARKING! MODE 🌟⚡'\n        }`\n    );\n};\n\n// some ki natural cubic spline functions\nconst rechargeProbabilities: Record<10 | 20, (ki: number) => number> = {\n    10: (ki) =>\n        ki >= 0 && ki <= 10\n            ? -2.9508e-5 * ki ** 3 - 1.7049e-2 * ki + 1\n            : ki > 10 && ki <= 20\n            ? 4.7541e-5 * ki ** 3 - 2.3115e-3 * ki ** 2 + 6.0656e-3 * ki + 0.92295\n            : ki > 20 && ki <= 40\n            ? -3.6885e-6 * ki ** 3 + 7.623e-4 * ki ** 2 - 5.541e-2 * ki + 1.3328\n            : ki > 40 && ki <= 50\n            ? -1.0656e-5 * ki ** 3 + 1.5984e-3 * ki ** 2 - 8.8852e-2 * ki + 1.7787\n            : 0,\n    20: (ki) =>\n        ki >= 0 && ki <= 10\n            ? 1.1639e-4 * ki ** 3 - 7.163e-2 * ki + 1\n            : ki > 10 && ki <= 20\n            ? -1.3197e-4 * ki ** 3 + 7.4508e-3 * ki ** 2 - 1.4615e-1 * ki + 1.2484\n            : ki > 20 && ki <= 40\n            ? 1.4549e-5 * ki ** 3 - 1.3402e-3 * ki ** 2 + 2.9672e-2 * ki + 7.623e-2\n            : ki > 40 && ki <= 50\n            ? -1.3525e-5 * ki ** 3 + 2.0287e-3 * ki ** 2 - 1.0508e-1 * ki + 1.873\n            : 0,\n};\n\n// ki/sparking gauge amount to discharge by atk type\nconst dischargeKiAmountByType: Record<AttackType | number, number> = {\n    [AttackType.PHYSICAL_ATK]: 5,\n    [AttackType.KI_WEAK_ATK]: 20,\n    [AttackType.KI_STRONG_ATK]: 40,\n    [AttackType.KI_ULTIMATE_ATK]: 50,\n};\n\n// class Fighter\nclass Fighter {\n    protected static MAX_KI = 50;\n    protected health = 100;\n    protected ki: number;\n    protected initialKi: number;\n    protected kiRechargeAmount = 10;\n    protected name: string;\n    protected atk: number;\n    protected def: number;\n    protected speed: number;\n    protected evasionProbability: number;\n    protected kiRechargeProbability = (ki: number) => 0;\n    protected sparkingGauge = 0;\n\n    constructor(name: string, atk: number, def: number, speed: number, ki = 20, kiRecharge: 10 | 20 = 10) {\n        this.name = name;\n        this.atk = atk;\n        this.def = def;\n        this.speed = speed;\n        this.ki = Math.max(0, Math.min(Fighter.MAX_KI, ki));\n        this.initialKi = ki;\n        this.evasionProbability = this.isSuperSonic() ? 0.5 : this.isFast() ? 0.3 : !this.hasSuperArmor() ? 0.2 : 0.0;\n        this.kiRechargeAmount = kiRecharge;\n        this.kiRechargeProbability = rechargeProbabilities[kiRecharge];\n    }\n\n    getName(): string {\n        return this.name;\n    }\n\n    getAtk(): number {\n        return !this.isInSparkingMode() ? this.atk : Math.trunc(this.atk * 1.1);\n    }\n\n    getDef(): number {\n        return !this.isInSparkingMode() ? this.def : Math.trunc(this.def * 0.8);\n    }\n\n    getSpeed(): number {\n        return this.speed;\n    }\n\n    getKiRechargeAmount(): number {\n        return this.kiRechargeAmount;\n    }\n\n    getHealth(): number {\n        return this.health;\n    }\n\n    getKi(): number {\n        return this.ki;\n    }\n\n    getSparkingGauge(): number {\n        return this.sparkingGauge;\n    }\n\n    isInSparkingMode(): boolean {\n        return this.sparkingGauge > 0;\n    }\n\n    enterInSparkingMode(): boolean {\n        if (this.ki === Fighter.MAX_KI) {\n            const sparkingProbability = this.isStrong()\n                ? 0.65 + ((this.atk - 70) / 30) * 0.2\n                : this.isWeak()\n                ? 0.6\n                : 0.5;\n            if (rand() < sparkingProbability) {\n                this.sparkingGauge = Fighter.MAX_KI;\n                return true;\n            } else {\n                return false;\n            }\n        }\n        return false;\n    }\n\n    exitSparkingMode(): this {\n        this.sparkingGauge = 0;\n        return this;\n    }\n\n    dischargeSparkingGauge(amount: number): this {\n        this.sparkingGauge = Math.max(0, this.sparkingGauge - amount);\n        return this;\n    }\n\n    // if true, the fighter will recharge ki, if false, the fighter will attack\n    hasToRechargeKi(): boolean {\n        return rand() < this.kiRechargeProbability(this.ki);\n    }\n\n    evade(): boolean {\n        return rand() < (!this.isInSparkingMode() ? this.evasionProbability : this.evasionProbability + 0.1);\n    }\n\n    useKiOrPhysicalAttack(): AttackType {\n        const r = rand();\n\n        // check if the fighter is in sparking mode\n        if (this.isInSparkingMode()) {\n            // 10% for weak ki atk, 20% for strong ki atk, 10% for physical atk and 60% for ultimate ki atk\n            return r < 0.1\n                ? AttackType.KI_WEAK_ATK\n                : r < 0.3\n                ? AttackType.KI_STRONG_ATK\n                : r < 0.4\n                ? AttackType.PHYSICAL_ATK\n                : AttackType.KI_ULTIMATE_ATK;\n        }\n\n        if (this.ki >= 40) {\n            // 15% for weak ki atk, 25% for strong ki atk and 60% for physical atk\n            return r < 0.15 ? AttackType.KI_WEAK_ATK : r < 0.4 ? AttackType.KI_STRONG_ATK : AttackType.PHYSICAL_ATK;\n        } else if (this.ki >= 20) {\n            // 25% for weak ki atk and 75% for physical at\n            return r < 0.25 ? AttackType.KI_WEAK_ATK : AttackType.PHYSICAL_ATK;\n        } else {\n            return AttackType.PHYSICAL_ATK;\n        }\n    }\n\n    // return the damage and if the defense was ignored partially or totally\n    takeKiDamageFrom(fighter: Fighter, kiType: AttackType): [number, boolean] {\n        let damage = 0;\n        let ignoreDefense = false;\n        let minDamage = 0;\n        let tempDef = this.getDef();\n        switch (kiType) {\n            case AttackType.KI_WEAK_ATK:\n                damage = Math.trunc(fighter.getAtk() * (fighter.isWeak() ? 1.5 : 1.25));\n                minDamage = 2;\n                tempDef = rand() < (fighter.isWeak() ? 0.3 : 0.2) ? Math.trunc(tempDef * 0.8) : tempDef;\n                break;\n            case AttackType.KI_STRONG_ATK:\n                damage = Math.trunc(fighter.getAtk() * (fighter.isWeak() ? 2 : 1.5));\n                minDamage = 5;\n                tempDef = rand() < (fighter.isWeak() ? 0.5 : 0.4) ? Math.trunc(tempDef * 0.8) : tempDef;\n                break;\n            case AttackType.KI_ULTIMATE_ATK:\n                damage = Math.trunc(fighter.getAtk() * (fighter.isWeak() ? 4 : 3));\n                minDamage = 10;\n                ignoreDefense = rand() < 0.7;\n                break;\n            default:\n                throw new Error('Invalid ki type');\n        }\n\n        if (!ignoreDefense) {\n            damage = damage - tempDef;\n        }\n\n        this.health -= damage = Math.max(minDamage, damage);\n        return [damage, ignoreDefense || this.getDef() !== tempDef];\n    }\n\n    takePhysicalDamageFrom(fighter: Fighter): [number, boolean, boolean] {\n        let damage = fighter.getAtk() - this.getDef();\n        let critProbability = (fighter.isStrong() ? 0.2 : 0.1) - (fighter.isFast() ? 0.05 : 0);\n        let defenseIgnored = false;\n        critProbability += fighter.isInSparkingMode() ? 0.05 : 0;\n\n        const isCrit = rand() < critProbability;\n        if (isCrit) {\n            // if the defender has more defense than the atk of the atacker or they are the same, the crit ignores the defense\n            if (damage <= 0) {\n                damage = fighter.getAtk() << 1; // double the damage (fighter atk) ignoring the defense\n                defenseIgnored = true;\n            } else {\n                damage <<= 1; // double the damage\n            }\n        }\n        // if the defender has more defense than the atk of the atacker or they are the same, the damage  is the 10% of the atk of the atacker\n        else if (damage <= 0) damage = Math.trunc(fighter.getAtk() * 0.1); // get the integer part;\n\n        // if the defender has super armor, the damage is reduced by 90% (min 1)\n        if (this.hasSuperArmor()) {\n            damage = Math.max(1, Math.trunc(damage * 0.1));\n        }\n\n        this.health -= damage;\n        return [damage, isCrit, defenseIgnored];\n    }\n\n    hasSuperArmor(): boolean {\n        return this.speed === 0;\n    }\n\n    isSuperSonic(): boolean {\n        return this.speed === 100;\n    }\n\n    isFast(): boolean {\n        return this.speed >= 70;\n    }\n\n    isStrong(): boolean {\n        return this.atk >= 70;\n    }\n\n    isWeak(): boolean {\n        return this.atk < 20;\n    }\n\n    isDead(): boolean {\n        return this.health <= 0;\n    }\n\n    heal(): this {\n        this.health = 100;\n        return this;\n    }\n\n    healKi(): this {\n        this.ki = this.initialKi;\n        return this;\n    }\n\n    dischargeKiAmount(amount: number): this {\n        this.ki = Math.max(0, this.ki - amount);\n        return this;\n    }\n\n    rechargeKi(): this {\n        this.ki = Math.min(Fighter.MAX_KI, this.ki + this.kiRechargeAmount);\n        return this;\n    }\n}\n\n// Singleton Tournament\n/**\n * Usage:\n *  reset() -> reset the tournament after it ends. return the torunament object\n *  init(numOfFighters, timeInMsBetweenAttacks) -> start the tournament with numOfFighters and simulate the time between attacks and rounds if timeInMsBetweenAttacks is set\n *  return the winner of the tournament\n *  Example 1 (first time) with 8 fighters and no time between attacks:\n *  await Tournament.getInstance().init(8);\n *  Example 2 (first time) with 8 fighters and 1.1s between attacks and rounds:\n *  await Tournament.getInstance().init(8, 1100);\n *  Example 3 (reset the tournament) with 16 fighters and no time between attacks:\n *  await Tournament.getInstance().reset().init(16);\n */\nclass Tournament {\n    protected static instance: Tournament | null = null;\n    protected fighters: Array<Fighter> = [];\n    protected rounds: number = 0;\n    protected winner: Fighter | null = null;\n    protected timmer: number = 0; // If set, use this to simulate the time between attacks and rounds\n    // some names and its usage\n    protected static NAMES: Record<string, number> = {\n        Goku: 0,\n        Vegeta: 0,\n        Piccolo: 0,\n        Gohan: 0,\n        Krillin: 0,\n        Yamcha: 0,\n        Tien: 0,\n        Chiaotzu: 0,\n        'Master Roshi': 0,\n        Trunks: 0,\n        Goten: 0,\n        Pan: 0,\n        Frieza: 0,\n        Cell: 0,\n        'Majin Buu': 0,\n        Beerus: 0,\n        Whis: 0,\n        Jiren: 0,\n        Hit: 0,\n        Kale: 0,\n        Caulifla: 0,\n        Cabba: 0,\n        Broly: 0,\n        Zamasu: 0,\n        'Black Goku': 0,\n        Vegito: 0,\n        Gogeta: 0,\n        Kefla: 0,\n        Toppo: 0,\n        Dyspo: 0,\n        'Android 17': 0,\n        'Android 18': 0,\n        'Android 16': 0,\n        'Android 19': 0,\n        'Android 20': 0,\n        'Android 21': 0,\n    };\n\n    protected constructor() {}\n\n    public static getInstance(): Tournament {\n        if (!Tournament.instance) {\n            Tournament.instance = new Tournament();\n        }\n        return Tournament.instance;\n    }\n\n    async generateFighters(n: number, timmerIsSet: boolean) {\n        // check if n is integer, is positive and max 2^10, its min 2 and is a power of 2\n        if (!Number.isInteger(n) || (n & (n - 1)) !== 0 || n < 2 || n > 1024) {\n            throw new Error(\n                'El torneo solo es válido con un número de luchadores potencia de 2,un mínimo de 2 luchadores y máximo de 1024'\n            );\n        }\n\n        const nameList = Object.keys(Tournament.NAMES);\n        const namesLength = nameList.length;\n\n        for (let i = 0; i < n; i++) {\n            const idx = randInt(0, namesLength - 1);\n            let name = nameList[idx];\n            // add #number to the name if it is repeated\n            Tournament.NAMES[name]++ && (name += `#${Tournament.NAMES[name]}`);\n            const atk = randInt(10, 100); // min 10 atk to make some damage\n            const def = randInt(0, 100);\n            const speed = randInt(0, 100);\n            const initialKi = randValuesFrom([20, 30]);\n            const rechargeAmount = randValuesFrom([10, 20]) satisfies 10 | 20;\n            this.fighters.push(new Fighter(name, atk, def, speed, initialKi, rechargeAmount));\n            console.log(\n                `${name} se une al torneo con ataque: ${atk} 💪, defensa: ${def} 🛡️, velocidad: ${speed} 🪽, ki inicial: ${initialKi} ⚡ y ${rechargeAmount} de carga de ki ⬆️⚡ `,\n                speed === 0 ? '¡¡¡INCLUSO TIENE SUPER ARMADURA!!! 🧱' : '[no tiene super armadura]',\n                speed === 100 ? '¡¡¡ES SUPERSÓNICO, ESQUIVARÁ CASI TODO!!! 🏃‍♂️💨' : '[no es supersónico]'\n            );\n            timmerIsSet && (await sleep(250));\n        }\n        // sort the fighters by random\n        this.fighters.sort(() => randInt(-1, 1));\n\n        return this;\n    }\n\n    reset(): this {\n        this.fighters = [];\n        this.rounds = 0;\n        this.winner = null;\n        this.timmer = 0;\n        // reset the names\n        for (const name in Tournament.NAMES) {\n            Tournament.NAMES[name] = 0;\n        }\n\n        return this;\n    }\n\n    async init(numOfFighters: number, timeInMsBetweenAttacks = 0) {\n        await this.generateFighters(numOfFighters, timeInMsBetweenAttacks > 0);\n        this.rounds = Math.log2(this.fighters.length);\n        this.timmer = timeInMsBetweenAttacks;\n        return await this.startAsync();\n    }\n\n    async startAsync(): Promise<Fighter> {\n        let winners = this.fighters;\n        for (let i = 0; i < this.rounds - 1; i++) {\n            console.log(`Ronda ${i + 1}`);\n            await sleep(this.timmer);\n            winners = await this.roundAsync(winners);\n        }\n\n        console.log(`Ronda final entre 🤜 ${winners[0].getName()} y ${winners[1].getName()} 🤛`);\n        winners = await this.roundAsync(winners, true);\n\n        this.winner = winners[0];\n        console.log(`El ganador es ${this.winner.getName()} 🎉`);\n        return this.winner;\n    }\n\n    async roundAsync(fighters: Array<Fighter>, isFinal = false): Promise<Array<Fighter>> {\n        let winners = [];\n        for (let i = 0; i < fighters.length; i += 2) {\n            const fighter1 = fighters[i];\n            const fighter2 = fighters[i + 1];\n            !isFinal &&\n                console.log(\n                    `Empieza la batalla #${(i >>> 1) + 1} 🤜 entre ${fighter1.getName()} y ${fighter2.getName()} 🤛!`\n                ) &&\n                (await sleep(this.timmer));\n            const winner = await this.battleAsync(fighter1, fighter2);\n            !isFinal && console.log(`${winner.getName()} avanza a la siguiente ronda 👏`) && (await sleep(this.timmer));\n            winners.push(winner);\n        }\n        return winners;\n    }\n\n    async battleAsync(fighter1: Fighter, fighter2: Fighter): Promise<Fighter> {\n        let turn = fighter1.getSpeed() > fighter2.getSpeed() ? [fighter1, fighter2] : [fighter2, fighter1];\n        while (true) {\n            const atacker = turn[0];\n            const defender = turn[1];\n\n            // check if the atacker attacks or recharges ki\n            if (atacker.hasToRechargeKi()) {\n                atacker.rechargeKi();\n                console.log(\n                    `${atacker.getName()} recarga ki 🔄🧘 y recupera ${atacker.getKiRechargeAmount()} de ki ⚡⬆️. Ahora tiene ${atacker.getKi()} de ki ⚡`\n                );\n                await sleep(this.timmer);\n                turn = [defender, atacker];\n                continue;\n            }\n\n            // check if the atacker enters in sparking mode\n            const atackerInSparkingMode = atacker.isInSparkingMode();\n            if (!atackerInSparkingMode && atacker.enterInSparkingMode()) {\n                console.log(`${atacker.getName()} entra en modo SPARKING! 🌟🔥. La cosa se pone seria ⚠️`);\n                await sleep(this.timmer);\n                turn = [defender, atacker];\n                continue;\n            }\n\n            // atacker attacks\n            // check if the atacker uses ki or physical attack\n            const atkType = atacker.useKiOrPhysicalAttack();\n\n            // check if the defender evades the attack\n            const evaded = defender.evade();\n            let damage = 0;\n\n            // if the atacker uses ki, the defender takes ki damage\n            if (!AttackType.isPhysicalAtk(atkType)) {\n                let ignoreDefense = false;\n\n                if (!evaded) [damage, ignoreDefense] = defender.takeKiDamageFrom(atacker, atkType);\n                atackerInSparkingMode\n                    ? atacker.dischargeSparkingGauge(dischargeKiAmountByType[atkType]) &&\n                      AttackType.isKiUltimateAtk(atkType) &&\n                      atacker.dischargeKiAmount(dischargeKiAmountByType[atkType])\n                    : atacker.dischargeKiAmount(dischargeKiAmountByType[atkType]);\n\n                printKiAtack(atacker, defender, damage, evaded, ignoreDefense, atkType);\n                if (defender.isDead()) {\n                    console.log(`${defender.getName()} ha muerto 💀`);\n                    atacker.heal().healKi().exitSparkingMode();\n                    await sleep(this.timmer);\n                    return atacker;\n                } else {\n                    // print if the atacker leaves the sparking mode\n                    const atackerLeavesSparkingMode = atackerInSparkingMode && !atacker.isInSparkingMode();\n                    atackerLeavesSparkingMode && console.log(`${atacker.getName()} sale del modo SPARKING! 🌟🔥`);\n\n                    printHealthAndKiOf(atacker);\n                    printHealthAndKiOf(defender);\n\n                    await sleep(this.timmer);\n                }\n                turn = [defender, atacker];\n                continue;\n            }\n\n            let isCrit = false;\n            let defenseIgnored = false;\n\n            if (!evaded) [damage, isCrit, defenseIgnored] = defender.takePhysicalDamageFrom(atacker);\n            atackerInSparkingMode && atacker.dischargeSparkingGauge(dischargeKiAmountByType[AttackType.PHYSICAL_ATK]);\n\n            printAtack(atacker, defender, damage, evaded, isCrit, defenseIgnored);\n\n            if (defender.isDead()) {\n                console.log(`${defender.getName()} ha muerto 💀`);\n                atacker.heal().healKi().exitSparkingMode();\n                await sleep(this.timmer);\n                return atacker;\n            } else {\n                // print if the atacker leaves the sparking mode\n                const atackerLeavesSparkingMode = atackerInSparkingMode && !atacker.isInSparkingMode();\n                atackerLeavesSparkingMode && console.log(`${atacker.getName()} sale del modo SPARKING! 🌟🔥`);\n\n                printHealthAndKiOf(atacker);\n                printHealthAndKiOf(defender);\n\n                await sleep(this.timmer);\n            }\n            turn = [defender, atacker];\n            await sleep(this.timmer);\n        }\n    }\n}\n\n// 8 fighters and 1s between attacks and rounds\n(async () => await Tournament.getInstance().init(8, 1000))();\n"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/typescript/hozlucas28.ts",
    "content": "/* -------------------------------------------------------------------------- */\n/*                                   CLASSES                                  */\n/* -------------------------------------------------------------------------- */\n\n/* --------------------------------- Fighter -------------------------------- */\n\ninterface IFighter {\n    getLife: () => number\n    getAttack: () => number\n    getDefense: () => number\n    getName: () => string\n    getSpeed: () => number\n    setLife: (newLife: number) => this\n    clone: () => IFighter\n}\n\ninterface FighterConstructor {\n    attack: number\n    defense: number\n    name: string\n    speed: number\n    life?: number\n}\n\nclass Fighter implements IFighter {\n    private life: number\n    private readonly attack: number\n    private readonly defense: number\n    private readonly name: string\n    private readonly speed: number\n\n    public constructor({\n        attack,\n        defense,\n        name,\n        speed,\n        life = 100,\n    }: FighterConstructor) {\n        this.life = life\n        this.attack = attack\n        this.defense = defense\n        this.name = name\n        this.speed = speed\n    }\n\n    public getLife(): number {\n        return this.life\n    }\n\n    public getAttack(): number {\n        return this.attack\n    }\n\n    public getDefense(): number {\n        return this.defense\n    }\n\n    public getName(): string {\n        return this.name\n    }\n\n    public getSpeed(): number {\n        return this.speed\n    }\n\n    public setLife(newLife: number): this {\n        this.life = Math.max(newLife, 0)\n        return this\n    }\n\n    public clone(): IFighter {\n        return new Fighter({\n            attack: this.attack,\n            defense: this.defense,\n            name: this.name,\n            speed: this.speed,\n            life: this.life,\n        })\n    }\n}\n\n/* ------------------------------- Tournament ------------------------------- */\n\ninterface ShiftInformation {\n    attackDamage: number\n    attacker: IFighter\n    shift: number\n    victim: IFighter\n}\n\ninterface Round {\n    infoPerShift?: ShiftInformation[]\n    looser: IFighter\n    shifts: number\n    winner: IFighter\n}\n\ninterface ITournament {\n    getPhase: () => number\n    getTeamA: () => IFighter[]\n    getTeamB: () => IFighter[]\n    getWinner: () => IFighter | undefined\n    executeNextRound: () => Round\n}\n\ninterface TournamentConstructor {\n    teamA: IFighter[]\n    teamB: IFighter[]\n}\n\nclass Tournament implements ITournament {\n    private pairOfFighters: IFighter[]\n    private phase: number\n    private readonly teamA: IFighter[]\n    private readonly teamB: IFighter[]\n    private round: number\n    private winner?: IFighter\n\n    public constructor({teamA, teamB}: TournamentConstructor) {\n        if (teamA.length != teamB.length)\n            throw new Error(\n                'The number of fighters in both teams must be equal'\n            )\n\n        if (teamA.length % 2 || teamB.length % 2)\n            throw new Error('The number of fighters in both teams must be even')\n\n        this.pairOfFighters = []\n        this.phase = 1\n        this.teamA = teamA\n        this.teamB = teamB\n        this.round = 0\n        this.winner = undefined\n\n        this.setRndPairOfFighters()\n    }\n\n    public getPhase(): number {\n        return this.phase\n    }\n\n    public getTeamA(): IFighter[] {\n        return this.teamA\n    }\n\n    public getTeamB(): IFighter[] {\n        return this.teamB\n    }\n\n    public getWinner(): IFighter | undefined {\n        return this.winner\n    }\n\n    private setRndPairOfFighters(): void {\n        const indexesToIgnoreA: number[] = []\n        const indexesToIgnoreB: number[] = []\n\n        let rndIndex: number\n        let rndFighter: IFighter\n\n        for (let i = 0; i < this.teamA.length; i++) {\n            do {\n                rndIndex = Math.floor(Math.random() * this.teamA.length)\n            } while (indexesToIgnoreA.includes(rndIndex))\n\n            rndFighter = this.teamA[rndIndex]\n\n            this.pairOfFighters.push(rndFighter)\n            indexesToIgnoreA.push(rndIndex)\n\n            do {\n                rndIndex = Math.floor(Math.random() * this.teamB.length)\n            } while (indexesToIgnoreB.includes(rndIndex))\n\n            rndFighter = this.teamB[rndIndex]\n\n            this.pairOfFighters.push(rndFighter)\n            indexesToIgnoreB.push(rndIndex)\n        }\n    }\n\n    public executeNextRound(): Round {\n        if (this.winner) throw new Error('The tournament already has a winner')\n        if (this.pairOfFighters.length < 2)\n            throw new Error('Not enough fighters to execute the next round')\n\n        this.round += 1\n        const offset: number = this.round - 1\n\n        let fighter01: IFighter = this.pairOfFighters[offset]\n        let fighter02: IFighter = this.pairOfFighters[offset + 1]\n        let fighterAux: IFighter\n\n        if (fighter01.getSpeed() < fighter02.getSpeed()) {\n            fighterAux = fighter01\n            fighter01 = fighter02\n            fighter02 = fighterAux\n        }\n\n        let shifts: number = 0\n        const infoPerShift: ShiftInformation[] = []\n\n        while (fighter01.getLife() && fighter02.getLife()) {\n            let attackDamage: number = 0\n\n            if (Math.random() > 0.2) {\n                const attack: number = fighter01.getAttack()\n                const defense: number = fighter02.getDefense()\n\n                attackDamage = Math.abs(attack - defense)\n                if (defense > attack) attackDamage = attackDamage * 0.1\n\n                fighter02.setLife(fighter02.getLife() - attackDamage)\n            }\n\n            infoPerShift.push({\n                attackDamage,\n                attacker: fighter01.clone(),\n                victim: fighter02.clone(),\n                shift: ++shifts,\n            })\n\n            fighterAux = fighter01\n            fighter01 = fighter02\n            fighter02 = fighterAux\n        }\n\n        fighter01 = this.pairOfFighters[offset]\n        fighter02 = this.pairOfFighters[offset + 1]\n\n        const looserIndex: number = fighter01.getLife() ? offset + 1 : offset\n        const looser: IFighter = this.pairOfFighters.splice(looserIndex, 1)[0]\n\n        if (this.pairOfFighters.length < 2) this.winner = this.pairOfFighters[0]\n\n        if (this.round == this.pairOfFighters.length) {\n            this.round = 0\n            this.phase += 1\n        }\n\n        return {\n            winner: fighter01.getLife() ? fighter01.clone() : fighter02.clone(),\n            looser,\n            shifts,\n            infoPerShift,\n        }\n    }\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\nconst teamA: IFighter[] = [\n    new Fighter({attack: 90, defense: 80, name: 'Goku', speed: 95}),\n    new Fighter({attack: 85, defense: 75, name: 'Vegeta', speed: 90}),\n    new Fighter({attack: 70, defense: 65, name: 'Piccolo', speed: 80}),\n    new Fighter({attack: 60, defense: 55, name: 'Krillin', speed: 70}),\n]\n\nconst teamB: IFighter[] = [\n    new Fighter({attack: 88, defense: 78, name: 'Frieza', speed: 92}),\n    new Fighter({attack: 82, defense: 72, name: 'Cell', speed: 88}),\n    new Fighter({attack: 75, defense: 65, name: 'Majin Buu', speed: 85}),\n    new Fighter({attack: 65, defense: 60, name: 'Broly', speed: 75}),\n]\n\nconst tournament: ITournament = new Tournament({teamA, teamB})\n\nlet rounds: number = 0\n\nwhile (!tournament.getWinner()) {\n    const round: Round = tournament.executeNextRound()\n\n    if (round.infoPerShift) {\n        console.log(\n            `> Round ${++rounds} ` +\n                `(${round.winner.getName()} vs ` +\n                `${round.looser.getName()})...\\n`\n        )\n\n        for (const shift of round.infoPerShift) {\n            if (shift.attackDamage > 0) {\n                console.log(\n                    `> Shift ${shift.shift}: ` +\n                        `${shift.attacker.getName()} attacks ` +\n                        `${shift.victim.getName()} with an attack damage of ` +\n                        `${shift.attackDamage}.`\n                )\n            } else {\n                console.log(\n                    `> Shift ${shift.shift}: ` +\n                        `${shift.attacker.getName()} attacks ` +\n                        `${shift.victim.getName()}, but ${shift.victim.getName()} ` +\n                        `evades the attack.`\n                )\n            }\n        }\n    }\n\n    console.log(\n        `\\n> ${round.winner.getName()} wins the fight against ` +\n            `${round.looser.getName()} in ${round.shifts} shifts!\\n`\n    )\n}\n\nconsole.log(\n    `> The winner of the tournament is ${tournament.getWinner()?.getName()}!`\n)\n"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/typescript/miguelex.ts",
    "content": "class Luchador {\n    nombre: string;\n    velocidad: number;\n    ataque: number;\n    defensa: number;\n    salud: number = 100;\n\n    constructor(nombre: string, velocidad: number, ataque: number, defensa: number) {\n        this.nombre = nombre;\n        this.velocidad = velocidad;\n        this.ataque = ataque;\n        this.defensa = defensa;\n    }\n\n    esquivar(): boolean {\n        return Math.random() < 0.2;\n    }\n}\n\nfunction batalla(luchador1: Luchador, luchador2: Luchador): Luchador {\n    console.log(`¡Batalla entre ${luchador1.nombre} y ${luchador2.nombre}!`);\n    let atacante = luchador1.velocidad >= luchador2.velocidad ? luchador1 : luchador2;\n    let defensor = atacante === luchador1 ? luchador2 : luchador1;\n\n    while (luchador1.salud > 0 && luchador2.salud > 0) {\n        if (defensor.esquivar()) {\n            console.log(`${defensor.nombre} esquivó el ataque de ${atacante.nombre}!`);\n        } else {\n            let danio = atacante.ataque - defensor.defensa;\n            if (danio <= 0) {\n                danio = atacante.ataque * 0.1;\n            }\n            defensor.salud -= danio;\n            console.log(`${atacante.nombre} ataca a ${defensor.nombre} y causa ${danio.toFixed(2)} de daño. Salud restante de ${defensor.nombre}: ${defensor.salud.toFixed(2)}`);\n        }\n        [atacante, defensor] = [defensor, atacante];\n    }\n\n    const ganador = luchador1.salud > 0 ? luchador1 : luchador2;\n    console.log(`¡${ganador.nombre} es el ganador de la batalla!\\n`);\n    return ganador;\n}\n\nasync function main(): Promise<void> {\n    const luchadores: Luchador[] = [];\n    const numLuchadores = parseInt(prompt(\"Ingrese el número de luchadores (debe ser una potencia de 2): \")!);\n\n    if ((numLuchadores & (numLuchadores - 1)) !== 0 || numLuchadores <= 0) {\n        console.log(\"El número de luchadores debe ser una potencia de 2.\");\n        return;\n    }\n\n    for (let i = 0; i < numLuchadores; i++) {\n        const nombre = prompt(`Ingrese el nombre del luchador ${i + 1}: `)!;\n        const velocidad = parseInt(prompt(`Ingrese la velocidad de ${nombre} (0-100): `)!);\n        const ataque = parseInt(prompt(`Ingrese el ataque de ${nombre} (0-100): `)!);\n        const defensa = parseInt(prompt(`Ingrese la defensa de ${nombre} (0-100): `)!);\n        luchadores.push(new Luchador(nombre, velocidad, ataque, defensa));\n    }\n\n    console.log(\"¡Comienza el torneo de Dragon Ball: Sparking! ZERO!\\n\");\n    while (luchadores.length > 1) {\n        const ganadores: Luchador[] = [];\n        luchadores.sort(() => Math.random() - 0.5);\n\n        for (let i = 0; i < luchadores.length; i += 2) {\n            const ganador = batalla(luchadores[i], luchadores[i + 1]);\n            ganadores.push(ganador);\n        }\n        luchadores.length = 0;\n        luchadores.push(...ganadores);\n    }\n\n    console.log(`¡El ganador del torneo es ${luchadores[0].nombre}!`);\n}\n\nmain();\n"
  },
  {
    "path": "Roadmap/42 - TORNEO DRAGON BALL/vb.net/kenysdev.vb",
    "content": "' _____________________________________\n' https://github.com/kenysdev\n' 2024 - vb.net\n' _____________________________________\n' 42 TORNEO DRAGON BALL\n' ------------------------------------\n'* EJERCICIO\n' * ¡El último videojuego de Dragon Ball ya está aquí!\n' * Se llama Dragon Ball: Sparking! ZERO.\n' *\n' * Simula un Torneo de Artes Marciales, al más puro estilo\n' * de la saga, donde participarán diferentes luchadores, y el\n' * sistema decidirá quién es el ganador.\n' *\n' * Luchadores:\n' * - Nombre.\n' * - Tres atributos: velocidad, ataque y defensa\n' *   (con valores entre 0 a 100 que tú decidirás).\n' * - Comienza cada batalla con 100 de salud.\n' * Batalla:\n' * - En cada batalla se enfrentan 2 luchadores.\n' * - El luchador con más velocidad comienza atacando.\n' * - El daño se calcula restando el daño de ataque del\n' *   atacante menos la defensa del oponente.\n' * - El oponente siempre tiene un 20% de posibilidad de\n' *   esquivar el ataque.\n' * - Si la defensa es mayor que el ataque, recibe un 10%\n' *   del daño de ataque.\n' * - Después de cada turno y ataque, el oponente pierde salud.\n' * - La batalla finaliza cuando un luchador pierde toda su salud.\n' * Torneo:\n' * - Un torneo sólo es válido con un número de luchadores\n' *   potencia de 2.\n' * - El torneo debe crear parejas al azar en cada ronda.\n' * - Los luchadores se enfrentan en rondas eliminatorias.\n' * - El ganador avanza a la siguiente ronda hasta que sólo\n' *   quede uno.\n' * - Debes mostrar por consola todo lo que sucede en el torneo,\n' *   así como el ganador.\n\nPublic Class Fighter\n    Public ReadOnly Property Name As String\n    Public ReadOnly Property Speed As Integer\n    Public ReadOnly Property Attack As Integer\n    Public ReadOnly Property Defense As Integer\n    Public Property Health As Double = 100\n\n    Public Sub New(name As String, speed As Integer, attack As Integer, defense As Integer)\n        Me.Name = name\n        Me.Speed = speed\n        Me.Attack = attack\n        Me.Defense = defense\n    End Sub\n\n    Public Sub ExecuteAttack(opponent As Fighter)\n        Console.WriteLine($\"'{Name}' ataca a '{opponent.Name}'\")\n\n        Dim damage As Double = If(opponent.Defense >= Attack,\n                                 Attack * 0.1, ' 10%\n                                 Attack - opponent.Defense)\n\n        If Not ActivateDefense() Then\n            opponent.Health -= damage\n            Console.WriteLine($\"'{opponent.Name}' ha recibido '{damage}' de daño\")\n            Console.WriteLine($\"Salud restante '{opponent.Health}'{Environment.NewLine}\")\n        Else\n            Console.WriteLine($\"'{opponent.Name}' ha esquivado el ataque.{Environment.NewLine}\")\n        End If\n    End Sub\n\n    Private Shared Function ActivateDefense() As Boolean\n        Return Random.Shared.NextDouble() <= 0.2 ' 20%\n    End Function\nEnd Class\n\n'  __________________________________________________________\nPublic Class Battle\n    Private ReadOnly _fighter1 As Fighter\n    Private ReadOnly _fighter2 As Fighter\n\n    Public Sub New(fighter1 As Fighter, fighter2 As Fighter)\n        _fighter1 = fighter1\n        _fighter2 = fighter2\n        Console.WriteLine($\"__'{_fighter1.Name} VS '{_fighter2.Name}'__{Environment.NewLine}\")\n    End Sub\n\n    Private Shared Function Combat(fighterA As Fighter, fighterB As Fighter) As Fighter\n        While True\n            fighterA.ExecuteAttack(fighterB)\n            If fighterB.Health <= 0 Then\n                Console.WriteLine($\"--> '{fighterA.Name}' gana la batalla.__{Environment.NewLine}\")\n                Return fighterA\n            End If\n\n            fighterB.ExecuteAttack(fighterA)\n            If fighterA.Health <= 0 Then\n                Console.WriteLine($\"--> '{fighterB.Name}' gana la batalla.{Environment.NewLine}\")\n                Return fighterB\n            End If\n        End While\n\n        Return Nothing\n    End Function\n\n    Public Function Start() As Fighter\n        Return If(_fighter1.Speed > _fighter2.Speed,\n                 Combat(_fighter1, _fighter2),\n                 Combat(_fighter2, _fighter1))\n    End Function\nEnd Class\n\n'  __________________________________________________________\nPublic Class FighterStats\n    Public Property Speed As Integer\n    Public Property Attack As Integer\n    Public Property Defense As Integer\n\n    Public Sub New(speed As Integer, attack As Integer, defense As Integer)\n        Me.Speed = speed\n        Me.Attack = attack\n        Me.Defense = defense\n    End Sub\nEnd Class\n\nPublic Class Tournament\n    Private _fighters As Dictionary(Of String, FighterStats)\n\n    Public Sub New(fighters As Dictionary(Of String, FighterStats))\n        _fighters = fighters\n    End Sub\n\n    Private Function IsPowerOf2() As Boolean\n        Return _fighters.Count > 1 AndAlso Math.Log2(_fighters.Count) Mod 1 = 0\n    End Function\n\n    Private Function GetRandomPairs() As (Fighter1 As Fighter, Fighter2 As Fighter)\n        Dim names = _fighters.Keys.ToList()\n        Dim selected = names.OrderBy(Function(x) Random.Shared.Next()).Take(2).ToList()\n\n        Dim stats1 = _fighters(selected(0))\n        Dim stats2 = _fighters(selected(1))\n        _fighters.Remove(selected(0))\n        _fighters.Remove(selected(1))\n\n        Dim fighter1 = New Fighter(selected(0), stats1.Speed, stats1.Attack, stats1.Defense)\n        Dim fighter2 = New Fighter(selected(1), stats2.Speed, stats2.Attack, stats2.Defense)\n\n        Return (fighter1, fighter2)\n    End Function\n\n    Public Sub StartRounds(Optional roundNum As Integer = 1)\n        If Not IsPowerOf2() Then\n            Console.WriteLine(\"El número de luchadores debe ser una potencia de 2.\")\n            Return\n        End If\n\n        Console.WriteLine($\"{Environment.NewLine}__Ronda #{roundNum}__\")\n        Dim nextRound As New Dictionary(Of String, FighterStats)\n\n        While True\n            Dim pair = GetRandomPairs()\n            Dim fighter1 = pair.Fighter1\n            Dim fighter2 = pair.Fighter2\n            Dim battle = New Battle(fighter1, fighter2)\n            Dim winner = battle.Start()\n\n            nextRound(winner.Name) = New FighterStats(winner.Speed, winner.Attack, winner.Defense)\n\n            If _fighters.Count = 0 Then\n                If nextRound.Count > 1 Then\n                    _fighters = nextRound\n                    StartRounds(roundNum + 1)\n                    Exit While\n                Else\n                    Console.WriteLine($\"{Environment.NewLine}--> El vencedor del torneo es '{winner.Name}'.\")\n                    Exit While\n                End If\n            End If\n        End While\n    End Sub\nEnd Class\n\n'  __________________________________________________________\nPublic Module Program\n    Private ReadOnly Fighters As New Dictionary(Of String, FighterStats) From {\n        {\"Goku\", New FighterStats(100, 95, 85)},\n        {\"Vegeta\", New FighterStats(95, 90, 90)},\n        {\"Gohan\", New FighterStats(85, 95, 85)},\n        {\"Freezer\", New FighterStats(90, 90, 90)},\n        {\"Piccolo\", New FighterStats(90, 85, 90)},\n        {\"Krillin\", New FighterStats(85, 75, 75)},\n        {\"Cell\", New FighterStats(90, 95, 85)},\n        {\"Majin Buu\", New FighterStats(80, 85, 95)}\n    }\n\n    Public Sub Main()\n        Console.WriteLine(\"Simulación del Torneo de Artes Marciales\")\n        Dim tournament = New Tournament(Fighters)\n        tournament.StartRounds()\n    End Sub\nEnd Module\n"
  },
  {
    "path": "Roadmap/43 - GIT GITHUB CLI/c#/deivisaherreraj.cs",
    "content": "﻿using System;\nusing System.Diagnostics;\nusing System.IO;\n\nclass GitCLI\n{\n    static void Main()\n    {\n        var cli = new GitCommandLine();\n        cli.Run();\n    }\n}\n\n/// <summary>\n/// Clase principal que gestiona la interacción con el usuario y el flujo del programa\n/// </summary>\nclass GitCommandLine\n{\n    private bool exit = false;  // Controla el ciclo del menú principal\n    private string _directory;  // Almacena el directorio de trabajo actual\n\n    /// <summary>\n    /// Inicia el menú principal del CLI y espera la selección del usuario\n    /// </summary>\n    public void Run()\n    {\n        while (!exit)\n        {\n            ShowMenu();\n            string choice = Console.ReadLine();\n            HandleChoice(choice);\n        }\n    }\n\n    /// <summary>\n    /// Muestra el menú principal de opciones para el usuario\n    /// </summary>\n    private void ShowMenu()\n    {\n        Console.WriteLine(\"\\nMenú de Git CLI:\");\n        Console.WriteLine(\"1. Establecer directorio de trabajo\");\n        Console.WriteLine(\"2. Configurar autenticación en GitHub\");\n        Console.WriteLine(\"3. Crear nuevo repositorio\");\n        Console.WriteLine(\"4. Crear nueva rama\");\n        Console.WriteLine(\"5. Cambiar de rama\");\n        Console.WriteLine(\"6. Renombrar rama\");\n        Console.WriteLine(\"7. Mostrar archivos pendientes de commit\");\n        Console.WriteLine(\"8. Hacer commit\");\n        Console.WriteLine(\"9. Mostrar historial de commits\");\n        Console.WriteLine(\"10. Eliminar rama\");\n        Console.WriteLine(\"11. Establecer repositorio remoto\");\n        Console.WriteLine(\"12. Hacer pull\");\n        Console.WriteLine(\"13. Hacer push\");\n        Console.WriteLine(\"14. Crear README.md\");\n        Console.WriteLine(\"15. Salir\");\n        Console.Write(\"Selecciona una opción: \");\n    }\n\n    /// <summary>\n    /// Ejecuta la acción seleccionada por el usuario en el menú\n    /// </summary>\n    /// <param name=\"choice\">Opción seleccionada por el usuario</param>\n    private void HandleChoice(string choice)\n    {\n        switch (choice)\n        {\n            case \"1\": SetWorkingDirectory(); break;\n            case \"2\": ConfigureGitHubAuthentication(); break;\n            case \"3\": GitCommands.CreateNewRepo(_directory); break;\n            case \"4\": GitCommands.CreateNewBranch(); break;\n            case \"5\": GitCommands.SwitchBranch(); break;\n            case \"6\": GitCommands.RenameBranch(); break;\n            case \"7\": GitCommands.ShowUnstagedFiles(); break;\n            case \"8\": GitCommands.CommitChanges(); break;\n            case \"9\": GitCommands.ShowCommitHistory(); break;\n            case \"10\": GitCommands.DeleteBranch(); break;\n            case \"11\": GitCommands.SetRemoteRepository(); break;\n            case \"12\": GitCommands.PullChanges(); break;\n            case \"13\": GitCommands.PushChanges(); break;\n            case \"14\": GitCommands.CreateReadMe(_directory); break;\n            case \"15\": exit = true; Console.WriteLine(\"Saliendo...\"); break;\n            default: Console.WriteLine(\"Opción inválida. Por favor, elige una opción válida.\"); break;\n        }\n    }\n\n    /// <summary>\n    /// Configura el directorio de trabajo para los comandos de Git.\n    /// Verifica que el directorio exista y maneja errores de forma controlada\n    /// </summary>\n    private void SetWorkingDirectory()\n    {\n        Console.Write(\"Ingresa la ruta del directorio de trabajo: \");\n        string directory = Console.ReadLine();\n\n        // Validación de existencia del directorio\n        if (Directory.Exists(directory))\n        {\n            try\n            {\n                _directory = directory;\n                Console.WriteLine($\"Directorio cambiado a: {directory}\");\n            }\n            catch (Exception e)\n            {\n                Console.WriteLine(\"Error al cambiar el directorio: \" + e.Message);\n            }\n        }\n        else\n        {\n            Console.WriteLine($\"El directorio '{directory}' no existe. Por favor, ingresa una ruta válida.\");\n        }\n    }\n\n    /// <summary>\n    /// Configura las credenciales de autenticación para GitHub\n    /// </summary>\n    private void ConfigureGitHubAuthentication()\n    {\n        Console.WriteLine(\"Configurando autenticación de GitHub...\");\n        Console.Write(\"Ingresa tu nombre de usuario de GitHub: \");\n        string username = Console.ReadLine();\n        Console.Write(\"Ingresa tu PAT (Personal Access Token): \");\n        string token = Console.ReadLine();\n        GitCommands.ConfigureAuthentication(username, token);\n    }\n}\n\n/// <summary>\n/// Clase que encapsula los comandos de Git para realizar diversas operaciones\n/// </summary>\nstatic class GitCommands\n{\n    /// <summary>\n    /// Crea un nuevo repositorio Git en el directorio especificado\n    /// </summary>\n    /// <param name=\"directory\">Directorio de trabajo</param>\n    public static void CreateNewRepo(string directory)\n    {\n        if (!string.IsNullOrEmpty(directory))\n        {\n            Console.WriteLine(\"Inicializando un nuevo repositorio Git...\");\n            RunCommand(\"git init\", directory);\n        }\n        else\n        {\n            Console.WriteLine(\"No se ha configurado un directorio de trabajo. Establécelo antes de crear un repositorio.\");\n        }\n    }\n\n    /// <summary>\n    /// Crea una nueva rama en el repositorio actual\n    /// </summary>\n    public static void CreateNewBranch()\n    {\n        Console.Write(\"Ingresa el nombre de la nueva rama: \");\n        string branch = Console.ReadLine();\n        if (!string.IsNullOrWhiteSpace(branch))\n            RunCommand($\"git checkout -b {branch}\");\n        else\n            Console.WriteLine(\"El nombre de la rama no puede estar vacío.\");\n    }\n\n    /// <summary>\n    /// Cambia a la rama especificada por el usuario\n    /// </summary>\n    public static void SwitchBranch()\n    {\n        Console.Write(\"Ingresa el nombre de la rama a la que deseas cambiar: \");\n        string branch = Console.ReadLine();\n        if (BranchExists(branch))\n            RunCommand($\"git checkout {branch}\");\n        else\n            Console.WriteLine($\"La rama '{branch}' no existe.\");\n    }\n\n    /// <summary>\n    /// Renombra una rama existente.\n    /// </summary>\n    public static void RenameBranch()\n    {\n        Console.Write(\"Ingresa el nuevo nombre para la rama: \");\n        string newBranchName = Console.ReadLine();\n\n        // Ejecutar el comando para renombrar la rama\n        RunCommand($\"git branch -M {newBranchName}\");\n    }\n\n    /// <summary>\n    /// Muestra los archivos pendientes de ser commit\n    /// </summary>\n    public static void ShowUnstagedFiles() => RunCommand(\"git status --short\");\n\n    /// <summary>\n    /// Realiza un commit con todos los cambios actuales\n    /// </summary>\n    public static void CommitChanges()\n    {\n        Console.Write(\"Ingresa el mensaje para el commit: \");\n        string message = Console.ReadLine();\n        if (!string.IsNullOrWhiteSpace(message))\n        {\n            RunCommand(\"git add .\");\n            RunCommand($\"git commit -m \\\"{message}\\\"\");\n        }\n        else\n        {\n            Console.WriteLine(\"El mensaje de commit no puede estar vacío.\");\n        }\n    }\n\n    /// <summary>\n    /// Muestra el historial de commits del repositorio actual\n    /// </summary>\n    public static void ShowCommitHistory() => RunCommand(\"git log --oneline\");\n\n    /// <summary>\n    /// Elimina una rama especificada\n    /// </summary>\n    public static void DeleteBranch()\n    {\n        Console.Write(\"Ingresa el nombre de la rama a eliminar: \");\n        string branch = Console.ReadLine();\n        if (BranchExists(branch))\n            RunCommand($\"git branch -d {branch}\");\n        else\n            Console.WriteLine($\"La rama '{branch}' no existe.\");\n    }\n\n    /// <summary>\n    /// Establece el repositorio remoto para el repositorio local\n    /// </summary>\n    public static void SetRemoteRepository()\n    {\n        Console.Write(\"Ingresa la URL del repositorio remoto: \");\n        string remoteUrl = Console.ReadLine();\n        if (Uri.IsWellFormedUriString(remoteUrl, UriKind.Absolute))\n            RunCommand($\"git remote add origin {remoteUrl}\");\n        else\n            Console.WriteLine(\"La URL es inválida.\");\n    }\n\n    /// <summary>\n    /// Realiza un pull de los cambios desde el repositorio remoto\n    /// </summary>\n    public static void PullChanges() => RunCommand(\"git pull origin\");\n\n    /// <summary>\n    /// Realiza un push de los cambios al repositorio remoto\n    /// </summary>\n    public static void PushChanges() => RunCommand(\"git push origin\");\n\n    /// <summary>\n    /// Crea un README.md y agrega un título al archivo en el directorio establecido.\n    /// </summary>\n    public static void CreateReadMe(string directory)\n    {\n        // Verifica que el directorio haya sido establecido\n        if (string.IsNullOrEmpty(directory))\n        {\n            Console.WriteLine(\"Por favor, establece el directorio de trabajo primero.\");\n            return;\n        }\n\n        string readmePath = Path.Combine(directory, \"README.md\");\n\n        // Verifica si el archivo ya existe\n        if (!File.Exists(readmePath))\n        {\n            // Agrega contenido al README.md\n            File.WriteAllText(readmePath, \"# Readme para el contenido\");\n            Console.WriteLine(\"README.md creado con el contenido: '# Readme'\");\n        }\n        else\n        {\n            Console.WriteLine(\"El archivo README.md ya existe en el directorio: \" + directory);\n        }\n    }\n\n    /// <summary>\n    /// Configura las credenciales de autenticación para GitHub\n    /// </summary>\n    /// <param name=\"username\">Nombre de usuario de GitHub</param>\n    /// <param name=\"token\">Token de acceso personal</param>\n    public static void ConfigureAuthentication(string username, string token)\n    {\n        if (!string.IsNullOrWhiteSpace(username) && !string.IsNullOrWhiteSpace(token))\n        {\n            RunCommand($\"git config --global user.name \\\"{username}\\\"\");\n            RunCommand($\"git config --global user.password \\\"{token}\\\"\");\n            Console.WriteLine(\"Autenticación de GitHub configurada exitosamente.\");\n        }\n        else\n        {\n            Console.WriteLine(\"El nombre de usuario y el token no pueden estar vacíos.\");\n        }\n    }\n\n    /// <summary>\n    /// Verifica si una rama existe en el repositorio actual\n    /// </summary>\n    /// <param name=\"branch\">Nombre de la rama a verificar</param>\n    /// <returns>true si la rama existe, false en caso contrario</returns>\n    private static bool BranchExists(string branch)\n    {\n        string branches = RunCommandAndGetOutput(\"git branch\");\n        return branches.Contains(branch);\n    }\n\n    /// <summary>\n    /// Ejecuta un comando de Git en el sistema\n    /// </summary>\n    /// <param name=\"command\">Comando a ejecutar</param>\n    /// <param name=\"workingDirectory\">Directorio de trabajo</param>\n    private static void RunCommand(string command, string workingDirectory = \"\")\n    {\n        try\n        {\n            ProcessStartInfo processInfo = new ProcessStartInfo(\"cmd.exe\", \"/c \" + command)\n            {\n                RedirectStandardOutput = true,\n                RedirectStandardError = true,\n                UseShellExecute = false,\n                CreateNoWindow = true,\n                WorkingDirectory = workingDirectory\n            };\n\n            using (Process process = Process.Start(processInfo))\n            {\n                process.WaitForExit();\n                string output = process.StandardOutput.ReadToEnd();\n                string error = process.StandardError.ReadToEnd();\n\n                if (!string.IsNullOrEmpty(output))\n                    Console.WriteLine(output);\n                if (!string.IsNullOrEmpty(error))\n                    Console.WriteLine(\"Error: \" + error);\n            }\n        }\n        catch (Exception ex)\n        {\n            Console.WriteLine(\"Error al ejecutar el comando: \" + ex.Message);\n        }\n    }\n\n    /// <summary>\n    /// Ejecuta un comando de Git y devuelve el resultado como string\n    /// </summary>\n    /// <param name=\"command\">Comando a ejecutar</param>\n    /// <returns>Resultado del comando</returns>\n    private static string RunCommandAndGetOutput(string command)\n    {\n        try\n        {\n            ProcessStartInfo processInfo = new ProcessStartInfo(\"cmd.exe\", \"/c \" + command)\n            {\n                RedirectStandardOutput = true,\n                RedirectStandardError = true,\n                UseShellExecute = false,\n                CreateNoWindow = true\n            };\n\n            using (Process process = Process.Start(processInfo))\n            {\n                process.WaitForExit();\n                return process.StandardOutput.ReadToEnd();\n            }\n        }\n        catch (Exception ex)\n        {\n            Console.WriteLine(\"Error al ejecutar el comando: \" + ex.Message);\n            return string.Empty;\n        }\n    }\n}"
  },
  {
    "path": "Roadmap/43 - GIT GITHUB CLI/c#/hequebo.cs",
    "content": "using System.Diagnostics;\n\nclass Git\n{\n    public void ChangeDirectory(string path)\n    {\n        if (!Directory.Exists(path))\n            Console.WriteLine(\"El directorio indicado no existe...\");\n        else\n            Environment.CurrentDirectory = path;\n        Console.WriteLine($\"El directorio actual es: {Environment.CurrentDirectory}\");\n    }\n    public void CreateRepository()\n    {\n        if (Directory.Exists($@\"{Environment.CurrentDirectory}\\.git\"))\n        {\n            Console.WriteLine(\"Se encuentra dentro de un repositorio...\");\n            return;\n        }\n        RunCommand(\"git init\");\n        RunCommand(\"git branch -M main\");\n        Console.WriteLine(\"Se ha inicializado el repositorio\");\n    }\n    public void CreateBranch(string branchName) => RunCommand($\"git branch {branchName}\");\n    public void Checkout(string branchName) => RunCommand($\"git checkout {branchName}\");\n    public void ShowPendingFiles() => RunCommand(\"git status\");\n    public void Commit(string commitMessage)\n    {\n        RunCommand(\"git add .\");\n        RunCommand($\"git commit -m \\\"{commitMessage}\\\"\");\n    }\n    public void ShowCommitHistory() => RunCommand(\"git log --oneline\");\n    public void DeleteBranch(string branchName) => RunCommand($\"git branch -d {branchName}\");\n    public void SetRemoteRepository(string url)\n    {\n        RunCommand($\"git remote add origin {url}\");\n        RunCommand(\"git push -u origin main\");\n    }\n    public void Pull() => RunCommand(\"git pull\");\n    public void Push()\n    {\n        string? branchName = RunCommand(\"git branch --show-current\");\n        RunCommand($\"git push origin {branchName}\");\n    }\n    private string? RunCommand(string command)\n    {\n        var process = new Process();\n        process.StartInfo.FileName = \"cmd.exe\";\n        process.StartInfo.Arguments = $\"/c {command}\";\n        process.StartInfo.UseShellExecute = false;\n        process.StartInfo.RedirectStandardOutput = true;\n        process.StartInfo.RedirectStandardError = true;\n\n        process.Start();\n\n        string output = process.StandardOutput.ReadToEnd();\n        string error = process.StandardError.ReadToEnd();\n        process.WaitForExit();\n        if (command.Contains(\"--show-current\"))\n            return output;\n        if (!string.IsNullOrEmpty(output))\n            Console.WriteLine(output);\n        if (!string.IsNullOrEmpty(error))\n            Console.WriteLine(error);\n        \n        return null;\n    }\n}\nclass Program\n{\n    static void Main(string[] args)\n    {\n        Environment.CurrentDirectory = Environment.GetEnvironmentVariable(\"DEFAULT_DIRECTORY\");\n        Console.WriteLine(\"---Git y Github CLI---\");\n        bool exit = false;\n        Git git = new Git();\n        do\n        {\n            Menu();\n\n            int option = 0;\n            int.TryParse(Console.ReadLine(), out option);\n\n            switch (option)\n            {\n                case 1:\n                    Console.Clear();\n                    Console.WriteLine(\"Ingresa el directorio completo:\");\n                    string path = Console.ReadLine();\n                    git.ChangeDirectory(path);\n                    break;\n                case 2:\n                    Console.Clear();\n                    git.CreateRepository();\n                    break;\n                case 3:\n                    Console.Clear();\n                    Console.WriteLine(\"Ingresa el nombre de la nueva rama:\");\n                    Console.WriteLine(\"Ten en cuenta que es necesario realizar un \" +\n                        \"commit a tu rama principal antes de crear una nueva rama\");\n                    string? branchName = Console.ReadLine();\n                    git.CreateBranch(branchName);\n                    break;\n                case 4:\n                    Console.Clear();\n                    Console.WriteLine(\"Ingresa el nombre de la rama a la que quieres cambiar:\");\n                    branchName = Console.ReadLine();\n                    git.Checkout(branchName);\n                    break;\n                case 5:\n                    Console.Clear();\n                    git.ShowPendingFiles();\n                    break;\n                case 6:\n                    Console.Clear();\n                    Console.WriteLine(\"Ingresa el mensaja de tu commit:\");\n                    string? commitMessage = Console.ReadLine();\n                    git.Commit(commitMessage);\n                    break;\n                case 7:\n                    Console.Clear();\n                    git.ShowCommitHistory();\n                    break;\n                case 8:\n                    Console.Clear();\n                    Console.WriteLine(\"Ingresa el nombre de la rama que quieres eliminar:\");\n                    branchName = Console.ReadLine();\n                    git.DeleteBranch(branchName);\n                    break;\n                case 9:\n                    Console.Clear();\n                    Console.WriteLine(\"Ingresa la url del remositorio remoto:\");\n                    string? url = Console.ReadLine();\n                    git.SetRemoteRepository(url);\n                    break;\n                case 10: \n                    Console.Clear();\n                    git.Pull();\n                    break;\n                case 11:\n                    Console.Clear();\n                    git.Push();\n                    break;\n                case 12:\n                    Console.Clear();\n                    exit = true;\n                    Console.WriteLine(\"Hasta la próxima...\");\n                    Thread.Sleep(1000);\n                    break;\n                default:\n                    Console.WriteLine(\"La opción no es válida...\");\n                    break;\n            }\n        } while (!exit);\n    }\n    static void Menu()\n    {\n        Console.WriteLine(\"1.- Establecer Directorio.\");\n        Console.WriteLine(\"2.- Crear un nuevo repositorio.\");\n        Console.WriteLine(\"3.- Crear una nueva rama.\");\n        Console.WriteLine(\"4.- Cambiar de rama.\");\n        Console.WriteLine(\"5.- Mostrar ficheros pendientes de hacer commit.\");\n        Console.WriteLine(\"6.- Hacer Commit.\");\n        Console.WriteLine(\"7.- Mostrar historial de commits\");\n        Console.WriteLine(\"8.- Eliminar una rama.\");\n        Console.WriteLine(\"9.- Establecer repositorio remoto.\");\n        Console.WriteLine(\"10.- Hacer pull.\");\n        Console.WriteLine(\"11.- Hacer push\");\n        Console.WriteLine(\"12.- Salir.\");\n        Console.WriteLine(\"Seleccione una opción...\");\n    }\n}"
  },
  {
    "path": "Roadmap/43 - GIT GITHUB CLI/c#/kenysdev.cs",
    "content": "namespace exs43;\n/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - C#\n_____________________________________\n43 GIT GITHUB CLI\n------------------------------------\n\n* EJERCICIO:\n * ¡Me voy de viaje al GitHub Universe 2024 de San Francisco!\n *\n * Desarrolla un CLI (Command Line Interface) que permita \n * interactuar con Git y GitHub de manera real desde terminal.\n * \n * El programa debe permitir las siguientes opciones:\n * 1. Establecer el directorio de trabajo\n * 2. Crear un nuevo repositorio\n * 3. Crear una nueva rama\n * 4. Cambiar de rama\n * 5. Mostrar ficheros pendientes de hacer commit\n * 6. Hacer commit (junto con un add de todos los ficheros)\n * 7. Mostrar el historial de commits\n * 8. Eliminar rama\n * 9. Establecer repositorio remoto\n * 10. Hacer pull\n * 11. Hacer push\n * 12. Salir\n*/\n\nusing System;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Net;\n\nclass GitCommandTool\n{\n    private static readonly string MENU = \"\"\" \n    Comandos Git:: \n    ------------------------------------------------------------\n    | 1. Establecer directorio       | 7. Historial de commits |\n    | 2. Crear repositorio           | 8. Eliminar rama        |\n    | 3. Crear rama                  | 9. Configurar remoto    |\n    | 4. Cambiar rama                | 10. pull                |\n    | 5. Mostrar cambios pendientes  | 11. push                |\n    | 6. 'add' + 'commit'            | 12. Salir               |\n    ------------------------------------------------------------\n    \"\"\";\n\n    private record GitCommand(string Name, string Command, string? Prompt = null);\n\n    private static readonly GitCommand[] COMMANDS = \n    [\n        new(\"Establecer directorio\", \"cd\", \"Ruta: \"),\n        new(\"Crear repositorio\", \"git init && git branch -M main\"),\n        new(\"Crear rama\", \"git branch -c\", \"Nombre: \"),\n        new(\"Cambiar rama\", \"git switch\", \"Nombre: \"),\n        new(\"Mostrar cambios\", \"git status -s\"),\n        new(\"Commit\", \"git add . && git commit -m\", \"Mensaje: \"),\n        new(\"Historial\", \"git log --oneline\"),\n        new(\"Eliminar rama\", \"git branch -d\", \"Nombre: \"),\n        new(\"Configurar remoto\", \"git remote add origin\", \"URL: \"),\n        new(\"Pull\", \"git pull origin\", \"rama: \"),\n        new(\"Push\", \"git push origin\", \"rama: \"),\n        new(\"Exit\", \"exit\")\n    ];\n\n    private static bool RunCommand(string command)\n    {\n        try\n        {\n            var processInfo = new ProcessStartInfo(\"cmd.exe\", $\"/c {command}\")\n            {\n                RedirectStandardOutput = true,\n                RedirectStandardError = true,\n                UseShellExecute = false,\n                CreateNoWindow = true\n            };\n\n            using var process = Process.Start(processInfo);\n            var output = process.StandardOutput.ReadToEnd();\n            var error = process.StandardError.ReadToEnd();\n            process.WaitForExit();\n\n            if (!string.IsNullOrEmpty(output))\n            {\n                Console.ForegroundColor = ConsoleColor.Green;\n                Console.WriteLine($\"✅: {output.Trim()}\");\n                Console.ResetColor();\n            }\n\n            if (!string.IsNullOrEmpty(error))\n            {\n                Console.ForegroundColor = ConsoleColor.Red;\n                Console.WriteLine($\"❌: {error.Trim()}\");\n                Console.ResetColor();\n            }\n\n            return process.ExitCode == 0;\n        }\n        catch (Exception ex)\n        {\n            Console.ForegroundColor = ConsoleColor.Red;\n            Console.WriteLine($\"❌: Error ejecutando el comando: {ex.Message}\");\n            Console.ResetColor();\n            return false;\n        }\n    }\n\n    private static string ReadInput(string prompt)\n    {\n        Console.Write(prompt);\n        return Console.ReadLine()?.Trim() ?? string.Empty;\n    }\n\n    private static void Execute(GitCommand cmd)\n    {\n        Console.WriteLine($\"\\n=> {cmd.Name}\");\n        Console.WriteLine(\"--------------------\");\n\n        if (cmd.Name == \"Exit\") {Environment.Exit(0);}\n\n        if (string.IsNullOrEmpty(cmd.Prompt))\n        {\n            RunCommand(cmd.Command);\n            return;\n        }\n\n        var userInput = ReadInput(cmd.Prompt);\n\n        if (cmd.Name == \"Establecer directorio\")\n        {\n            if (!Directory.Exists(userInput))\n            {\n                Console.WriteLine(\"Esta ruta no existe.\");\n                return;\n            }\n\n            try\n            {\n                Environment.CurrentDirectory = userInput;\n                Console.WriteLine($\"Directorio cambiado a: {userInput}\");\n            }\n            catch (Exception ex)\n            {\n                Console.WriteLine($\"Error cambiando directorio: {ex.Message}\");\n            }\n        }\n        else\n        {\n            RunCommand($\"{cmd.Command} {userInput}\");\n        }\n    }\n\n    static void Main()\n    {\n        while (true)\n        {\n            Console.WriteLine(MENU);\n            Console.WriteLine($\"Directorio actual: {Environment.CurrentDirectory}\");\n            Console.WriteLine(\"--------------------\");\n\n            var input = ReadInput(\"\\nOpción: \");\n\n            if (!int.TryParse(input, out int option) || option <= 0 || option > COMMANDS.Length)\n            {\n                Console.WriteLine(\"Opción inválida\");\n                continue;\n            }\n\n            if (option == COMMANDS.Length + 1)\n                break;\n\n            Execute(COMMANDS[option - 1]);\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/43 - GIT GITHUB CLI/c++/hectorio23.cpp",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\n#include <iostream>\n#include <cstdlib>\n#include <map>\n#include <functional>\n\n// Para chdir en sistemas POSIX\n#include <unistd.h> \n\n// Función para ejecutar comandos del sistema\nvoid runCommand(const std::string& command) {\n    system(command.c_str());\n}\n\n// Definir acciones con nombres descriptivos\nstd::map<int, std::pair<std::string, std::function<void()>>> actions = {\n    {1, {\"Set working directory\", [] {\n        std::string path;\n        std::cout << \"Enter the working directory path: \";\n        std::cin >> path;\n        // Cambiar el directorio de trabajo\n        if (chdir(path.c_str()) == 0) \n            std::cout << \"Working directory set to \" << path << std::endl;\n        else\n            std::cerr << \"Invalid directory path.\" << std::endl;\n    }}},\n    {2, {\"Create a new repository\", [] { runCommand(\"git init\"); }}},\n    {3, {\"Create a new branch\", [] {\n        std::string branch;\n        std::cout << \"Enter branch name: \";\n        std::cin >> branch;\n        runCommand(\"git branch \" + branch);\n    }}},\n    {4, {\"Switch branch\", [] {\n        std::string branch;\n        std::cout << \"Enter branch name: \";\n        std::cin >> branch;\n        runCommand(\"git checkout \" + branch);\n    }}},\n    {5, {\"Show pending files\", [] { runCommand(\"git status\"); }}},\n    {6, {\"Commit changes\", [] {\n        std::string message;\n        std::cout << \"Enter commit message: \";\n        std::cin.ignore();\n        std::getline(std::cin, message);\n        runCommand(\"git add . && git commit -m \\\"\" + message + \"\\\"\");\n    }}},\n    {7, {\"Show commit history\", [] { runCommand(\"git log --oneline\"); }}},\n    {8, {\"Delete branch\", [] {\n        std::string branch;\n        std::cout << \"Enter branch name to delete: \";\n        std::cin >> branch;\n        runCommand(\"git branch -d \" + branch);\n    }}},\n    {9, {\"Set remote repository\", [] {\n        std::string remoteUrl;\n        std::cout << \"Enter remote repository URL: \";\n        std::cin >> remoteUrl;\n        runCommand(\"git remote add origin \" + remoteUrl);\n    }}},\n    {10, {\"Pull changes\", [] { runCommand(\"git pull origin\"); }}},\n    {11, {\"Push changes\", [] { runCommand(\"git push origin\"); }}},\n    {12, {\"Exit\", [] {\n        std::cout << \"Goodbye!\" << std::endl;\n        exit(0);\n    }}},\n};\n\nint main() {\n    while (true) {\n        std::cout << \"\\nOptions:\\n\";\n        for (const auto& [key, value] : actions)\n            std::cout << key << \". \" << value.first << std::endl;\n\n        int choice;\n        std::cout << \"\\nSelect an option: \";\n        std::cin >> choice;\n\n        if (actions.count(choice)) {\n            actions[choice].second();\n        } else {\n            std::cout << \"Invalid option.\" << std::endl;\n        }\n    }\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/43 - GIT GITHUB CLI/ejercicio.md",
    "content": "# #43 GIT GITHUB CLI\n> #### Dificultad: Difícil | Publicación: 21/10/24 | Corrección: 04/11/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * ¡Me voy de viaje al GitHub Universe 2024 de San Francisco!\n *\n * Desarrolla un CLI (Command Line Interface) que permita \n * interactuar con Git y GitHub de manera real desde terminal.\n * \n * El programa debe permitir las siguientes opciones:\n * 1. Establecer el directorio de trabajo\n * 2. Crear un nuevo repositorio\n * 3. Crear una nueva rama\n * 4. Cambiar de rama\n * 5. Mostrar ficheros pendientes de hacer commit\n * 6. Hacer commit (junto con un add de todos los ficheros)\n * 7. Mostrar el historial de commits\n * 8. Eliminar rama\n * 9. Establecer repositorio remoto\n * 10. Hacer pull\n * 11. Hacer push\n * 12. Salir\n *\n * Puedes intentar controlar los diferentes errores.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/43 - GIT GITHUB CLI/java/Josegs95.java",
    "content": "import java.io.*;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.util.Scanner;\n\npublic class Josegs95 {\n    public static void main(String[] args) {\n        new Josegs95().gitCLI();\n    }\n\n    final private Scanner sc = new Scanner(System.in);\n    private String workingDirectory = System.getProperty(\"user.dir\");\n\n    public void gitCLI(){\n        try(sc) {\n            app:\n            while(true){\n                printMenu();\n                printWorkingDirectory();\n                System.out.print(\"Selecciona una opción: \");\n                String option = sc.nextLine();\n                switch (option){\n                    case \"1\":\n                        setWorkingDirectory();\n                        break;\n                    case \"2\":\n                        createNewRepository();\n                        break;\n                    case \"3\":\n                        createNewBranch();\n                        break;\n                    case \"4\":\n                        changeCurrentBranch();\n                        break;\n                    case \"5\":\n                        checkUncommittedFiles();\n                        break;\n                    case \"6\":\n                        commitFiles();\n                        break;\n                    case \"7\":\n                        showCommits();\n                        break;\n                    case \"8\":\n                        deleteBranch();\n                        break;\n                    case \"9\":\n                        setRemoteRepository();\n                        break;\n                    case \"10\":\n                        makePull();\n                        break;\n                    case \"11\":\n                        makePush();\n                        break;\n                    case \"12\":\n                        break app;\n                    default:\n                        System.out.println(\"Error. Opción no válida.\");\n                }\n                System.out.println();\n            }\n        }\n    }\n\n    private void setWorkingDirectory(){\n        System.out.print(\"Introduce la ruta absoluta del directorio de trabajo: \");\n        String path = sc.nextLine().strip();\n\n        if (!Files.isDirectory(Path.of(path))){\n            System.out.println(\"La ruta introducida no corresponde con un directorio existente\");\n            return;\n        }\n\n        workingDirectory = path;\n    }\n\n    private void createNewRepository(){\n        runCommand(\"git init\");\n        System.out.println(\"Repositorio creado en \" + workingDirectory);\n    }\n\n    private void createNewBranch(){\n        System.out.print(\"Introduzca el nombre de la rama: \");\n        String branchName = sc.nextLine();\n        runCommand(\"git branch \" + branchName);\n    }\n\n    private void changeCurrentBranch(){\n        System.out.print(\"Ramas: \");\n        runCommand(\"git branch\");\n\n        System.out.print(\"Introduzca el nombre de la rama: \");\n        String branchName = sc.nextLine();\n\n        runCommand(\"git checkout \" + branchName);\n    }\n\n    private void checkUncommittedFiles(){\n        runCommand(\"git status\");\n    }\n\n    private void commitFiles(){\n        System.out.print(\"Introduzca el mensaje del commit: \");\n        String commitMessage = sc.nextLine();\n        runCommand(\"git add .\");\n        runCommand(\"git commit -m \\\"\" + commitMessage + \"\\\"\");\n    }\n\n    private void showCommits(){\n        runCommand(\"git log --oneline\");\n    }\n\n    private void deleteBranch(){\n        System.out.print(\"Ramas: \");\n        runCommand(\"git branch\");\n\n        System.out.print(\"Introduzca el nombre de la rama: \");\n        String branchName = sc.nextLine();\n\n        runCommand(\"git branch -d \" + branchName);\n    }\n\n    private void setRemoteRepository(){\n        System.out.print(\"Introduce la URL del repositorio remoto: \");\n        String repositoryURL = sc.nextLine();\n        runCommand(\"git remote add origin \" + repositoryURL);\n    }\n\n    private void makePull(){\n        runCommand(\"git pull\");\n    }\n\n    private void makePush(){\n        runCommand(\"git push\");\n    }\n\n    private void runCommand(String command){\n        try {\n            ProcessBuilder pb = new ProcessBuilder().redirectErrorStream(true);\n            pb.command(\"cmd\", \"/c\", command);\n            pb.directory(new File(workingDirectory));\n            Process process = pb.start();\n            StringWriter result = new StringWriter();\n            try (BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream())))\n            {\n                in.transferTo(result);\n                System.out.print(result);\n            }\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        }\n    }\n\n    private void printWorkingDirectory(){\n        System.out.println(\"Ruta de trabajo: \" + workingDirectory);\n        System.out.println();\n    }\n\n    private void printMenu(){\n        System.out.println(\"================== Menu ==================\");\n        System.out.println(\"1. Establecer el directorio de trabajo\");\n        System.out.println(\"2. Crear un nuevo repositorio\");\n        System.out.println(\"3. Crear una nueva rama\");\n        System.out.println(\"4. Cambiar de rama\");\n        System.out.println(\"5. Mostrar ficheros pendientes de hacer commit\");\n        System.out.println(\"6. Hacer commit (junto con un add de todos los ficheros)\");\n        System.out.println(\"7. Mostrar el historial de commits\");\n        System.out.println(\"8. Eliminar rama\");\n        System.out.println(\"9. Establecer repositorio remoto\");\n        System.out.println(\"10. Hacer pull\");\n        System.out.println(\"11. Hacer push\");\n        System.out.println(\"12. Salir\");\n        System.out.println(\"==========================================\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/43 - GIT GITHUB CLI/java/MohamedElderkaoui.java",
    "content": "import java.io.BufferedReader;\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.InputStreamReader;\nimport java.util.Scanner;\n\npublic class MohamedElderkaoui {\n\n    // Directorio de trabajo actual. Por defecto, es el directorio desde donde se ejecuta el programa.\n    private static File workingDirectory = new File(System.getProperty(\"user.dir\"));\n\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n        boolean running = true; // Controla si el programa sigue activo\n\n        // Bucle principal del menú\n        while (running) {\n            System.out.println(\"\\nGitHub CLI - GitHub Universe 2024\");\n            System.out.println(\"1. Establecer el directorio de trabajo\");\n            System.out.println(\"2. Crear un nuevo repositorio\");\n            System.out.println(\"3. Crear una nueva rama\");\n            System.out.println(\"4. Cambiar de rama\");\n            System.out.println(\"5. Mostrar ficheros pendientes de hacer commit\");\n            System.out.println(\"6. Hacer commit\");\n            System.out.println(\"7. Mostrar el historial de commits\");\n            System.out.println(\"8. Eliminar rama\");\n            System.out.println(\"9. Establecer repositorio remoto\");\n            System.out.println(\"10. Hacer pull\");\n            System.out.println(\"11. Hacer push\");\n            System.out.println(\"12. Salir\");\n            System.out.print(\"Seleccione una opción: \");\n            \n            // Capturamos la opción del usuario\n            int choice = scanner.nextInt();\n            scanner.nextLine(); // Consumimos el salto de línea\n\n            try {\n                // Evaluamos la opción elegida por el usuario\n                switch (choice) {\n                    case 1 -> setWorkingDirectory(scanner);\n                    case 2 -> createRepository();\n                    case 3 -> createBranch(scanner);\n                    case 4 -> switchBranch(scanner);\n                    case 5 -> showStatus();\n                    case 6 -> commitChanges(scanner);\n                    case 7 -> showCommitHistory();\n                    case 8 -> deleteBranch(scanner);\n                    case 9 -> setRemote(scanner);\n                    case 10 -> pullChanges();\n                    case 11 -> pushChanges();\n                    case 12 -> running = false; // Salimos del bucle\n                    default -> System.out.println(\"Opción no válida, intente de nuevo.\");\n                }\n            } catch (IOException | InterruptedException e) {\n                // Captura y muestra errores de entrada/salida o interrupciones\n                System.err.println(\"Error: \" + e.getMessage());\n            }\n        }\n        scanner.close(); // Cerramos el escáner al salir del programa\n        System.out.println(\"Saliendo del CLI de Git.\");\n    }\n\n    // Método para establecer el directorio de trabajo\n    private static void setWorkingDirectory(Scanner scanner) {\n        System.out.print(\"Ingrese la ruta del nuevo directorio de trabajo: \");\n        String path = scanner.nextLine();\n        File newDir = new File(path);\n\n        // Verificamos si la ruta ingresada es válida\n        if (newDir.exists() && newDir.isDirectory()) {\n            workingDirectory = newDir;\n            System.out.println(\"Directorio de trabajo actualizado a: \" + workingDirectory.getAbsolutePath());\n        } else {\n            System.out.println(\"Ruta no válida.\");\n        }\n    }\n\n    // Método para inicializar un nuevo repositorio Git\n    private static void createRepository() throws IOException, InterruptedException {\n        executeCommand(\"git init\");\n    }\n\n    // Método para crear una nueva rama en el repositorio actual\n    private static void createBranch(Scanner scanner) throws IOException, InterruptedException {\n        System.out.print(\"Ingrese el nombre de la nueva rama: \");\n        String branchName = scanner.nextLine();\n        executeCommand(\"git branch \" + branchName);\n    }\n\n    // Método para cambiar a una rama existente\n    private static void switchBranch(Scanner scanner) throws IOException, InterruptedException {\n        System.out.print(\"Ingrese el nombre de la rama a la que desea cambiar: \");\n        String branchName = scanner.nextLine();\n        executeCommand(\"git checkout \" + branchName);\n    }\n\n    // Método para mostrar el estado de los archivos pendientes de hacer commit\n    private static void showStatus() throws IOException, InterruptedException {\n        executeCommand(\"git status\");\n    }\n\n    // Método para añadir todos los archivos y hacer un commit con un mensaje proporcionado\n    private static void commitChanges(Scanner scanner) throws IOException, InterruptedException {\n        System.out.print(\"Ingrese el mensaje del commit: \");\n        String message = scanner.nextLine();\n        executeCommand(\"git add .\"); // Añadimos todos los archivos al área de staging\n        executeCommand(\"git commit -m \\\"\" + message + \"\\\"\"); // Hacemos commit con el mensaje\n    }\n\n    // Método para mostrar el historial de commits en formato breve\n    private static void showCommitHistory() throws IOException, InterruptedException {\n        executeCommand(\"git log --oneline\");\n    }\n\n    // Método para eliminar una rama especificada por el usuario\n    private static void deleteBranch(Scanner scanner) throws IOException, InterruptedException {\n        System.out.print(\"Ingrese el nombre de la rama a eliminar: \");\n        String branchName = scanner.nextLine();\n        executeCommand(\"git branch -d \" + branchName);\n    }\n\n    // Método para configurar un repositorio remoto (URL proporcionada por el usuario)\n    private static void setRemote(Scanner scanner) throws IOException, InterruptedException {\n        System.out.print(\"Ingrese la URL del repositorio remoto: \");\n        String remoteUrl = scanner.nextLine();\n        executeCommand(\"git remote add origin \" + remoteUrl);\n    }\n\n    // Método para hacer pull desde el repositorio remoto\n    private static void pullChanges() throws IOException, InterruptedException {\n        executeCommand(\"git pull origin main\"); // Nota: Especificar la rama 'main' o la rama predeterminada del repositorio\n    }\n\n    // Método para hacer push de los cambios al repositorio remoto\n    private static void pushChanges() throws IOException, InterruptedException {\n        executeCommand(\"git push origin main\"); // Nota: Especificar la rama 'main' o la rama predeterminada del repositorio\n    }\n\n    // Método auxiliar que ejecuta un comando del sistema en el directorio de trabajo actual\n    private static void executeCommand(String command) throws IOException, InterruptedException {\n        ProcessBuilder builder = new ProcessBuilder(command.split(\" \")); // Dividimos el comando en partes\n        builder.directory(workingDirectory); // Establecemos el directorio de trabajo\n        Process process = builder.start(); // Iniciamos el proceso\n\n        // Lectura de la salida estándar del proceso\n        BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));\n        // Lectura de la salida de errores del proceso\n        BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));\n\n        // Imprimimos la salida del comando línea por línea\n        String line;\n        while ((line = reader.readLine()) != null) {\n            System.out.println(line);\n        }\n\n        // Imprimimos cualquier error que ocurra durante la ejecución del comando\n        while ((line = errorReader.readLine()) != null) {\n            System.err.println(line);\n        }\n\n        // Esperamos a que el proceso termine\n        process.waitFor();\n    }\n}\n"
  },
  {
    "path": "Roadmap/43 - GIT GITHUB CLI/java/asjordi.java",
    "content": "import java.io.BufferedReader;\nimport java.io.File;\nimport java.io.InputStreamReader;\nimport java.util.Scanner;\n\npublic class Main {\n    private String workingDirectory;\n    private final Scanner scanner;\n\n    public Main() {\n        this.scanner = new Scanner(System.in);\n        this.workingDirectory = System.getProperty(\"user.dir\");\n    }\n\n    public void start() {\n        int option;\n        do {\n            showMenu();\n            option = getOption();\n            executeOption(option);\n        } while (option != 12);\n    }\n\n    private void showMenu() {\n        System.out.println(\"\\n=== Git CLI ===\");\n        System.out.println(\"Directorio actual: \" + workingDirectory);\n        System.out.println(\"1. Establecer directorio de trabajo\");\n        System.out.println(\"2. Crear nuevo repositorio\");\n        System.out.println(\"3. Crear nueva rama\");\n        System.out.println(\"4. Cambiar de rama\");\n        System.out.println(\"5. Mostrar ficheros pendientes\");\n        System.out.println(\"6. Hacer commit\");\n        System.out.println(\"7. Mostrar historial de commits\");\n        System.out.println(\"8. Eliminar rama\");\n        System.out.println(\"9. Establecer repositorio remoto\");\n        System.out.println(\"10. Hacer pull\");\n        System.out.println(\"11. Hacer push\");\n        System.out.println(\"12. Salir\");\n    }\n\n    private int getOption() {\n        System.out.print(\"\\nSeleccione una opción: \");\n        try {\n            return Integer.parseInt(scanner.nextLine());\n        } catch (NumberFormatException e) {\n            return 0;\n        }\n    }\n\n    private void executeOption(int option) {\n        try {\n            switch (option) {\n                case 1 -> setWorkingDirectory();\n                case 2 -> initRepository();\n                case 3 -> createBranch();\n                case 4 -> checkoutBranch();\n                case 5 -> showStatus();\n                case 6 -> makeCommit();\n                case 7 -> showLog();\n                case 8 -> deleteBranch();\n                case 9 -> setRemoteRepository();\n                case 10 -> pull();\n                case 11 -> push();\n                case 12 -> System.out.println(\"Exiting...\");\n                default -> System.out.println(\"Opción no válida\");\n            }\n        } catch (Exception e) {\n            System.out.println(\"Error: \" + e.getMessage());\n        }\n    }\n\n    private void setWorkingDirectory() {\n        System.out.print(\"Introduce la ruta del directorio: \");\n        String newPath = scanner.nextLine();\n        File directory = new File(newPath);\n\n        if (directory.exists() && directory.isDirectory()) {\n            workingDirectory = newPath;\n            System.out.println(\"Directorio establecido correctamente\");\n        } else {\n            System.out.println(\"El directorio no existe\");\n        }\n    }\n\n    private void initRepository() throws Exception {\n        executeCommand(\"git init\");\n        System.out.println(\"Repositorio inicializado correctamente\");\n    }\n\n    private void createBranch() throws Exception {\n        System.out.print(\"Nombre de la nueva rama: \");\n        String branchName = scanner.nextLine();\n        executeCommand(\"git branch \" + branchName);\n        System.out.println(\"Rama creada correctamente\");\n    }\n\n    private void checkoutBranch() throws Exception {\n        System.out.print(\"Nombre de la rama: \");\n        String branchName = scanner.nextLine();\n        executeCommand(\"git checkout \" + branchName);\n        System.out.println(\"Cambio de rama realizado\");\n    }\n\n    private void showStatus() throws Exception {\n        executeCommand(\"git status\");\n    }\n\n    private void makeCommit() throws Exception {\n        executeCommand(\"git add .\");\n        System.out.print(\"Mensaje del commit: \");\n        String message = scanner.nextLine();\n        executeCommand(\"git commit -m \\\"\" + message + \"\\\"\");\n        System.out.println(\"Commit realizado correctamente\");\n    }\n\n    private void showLog() throws Exception {\n        executeCommand(\"git log --oneline\");\n    }\n\n    private void deleteBranch() throws Exception {\n        System.out.print(\"Nombre de la rama a eliminar: \");\n        String branchName = scanner.nextLine();\n        executeCommand(\"git branch -d \" + branchName);\n        System.out.println(\"Rama eliminada correctamente\");\n    }\n\n    private void setRemoteRepository() throws Exception {\n        System.out.print(\"URL del repositorio remoto: \");\n        String url = scanner.nextLine();\n        executeCommand(\"git remote add origin \" + url);\n        System.out.println(\"Repositorio remoto establecido correctamente\");\n    }\n\n    private void pull() throws Exception {\n        executeCommand(\"git pull\");\n        System.out.println(\"Pull realizado correctamente\");\n    }\n\n    private void push() throws Exception {\n        System.out.print(\"¿Es el primer push? (s/n): \");\n        String response = scanner.nextLine();\n        if (response.toLowerCase().equals(\"s\")) {\n            executeCommand(\"git push -u origin master\");\n        } else {\n            executeCommand(\"git push\");\n        }\n        System.out.println(\"Push realizado correctamente\");\n    }\n\n    private void executeCommand(String command) throws Exception {\n        ProcessBuilder processBuilder = new ProcessBuilder();\n        if (System.getProperty(\"os.name\").toLowerCase().startsWith(\"windows\")) {\n            processBuilder.command(\"cmd.exe\", \"/c\", command);\n        } else {\n            processBuilder.command(\"bash\", \"-c\", command);\n        }\n\n        processBuilder.directory(new File(workingDirectory));\n        Process process = processBuilder.start();\n\n        BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));\n        String line;\n        while ((line = reader.readLine()) != null) {\n            System.out.println(line);\n        }\n\n        BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));\n        while ((line = errorReader.readLine()) != null) {\n            System.out.println(\"Error: \" + line);\n        }\n\n        int exitCode = process.waitFor();\n        if (exitCode != 0) {\n            throw new Exception(\"Error ejecutando el comando. Código de salida: \" + exitCode);\n        }\n    }\n\n    public static void main(String[] args) {\n        Main cli = new Main();\n        cli.start();\n    }\n}\n"
  },
  {
    "path": "Roadmap/43 - GIT GITHUB CLI/java/miguelex.java",
    "content": "import java.io.*;\nimport java.util.Scanner;\n\npublic class miguelex {\n    private String workingDirectory;\n\n    public void setWorkingDirectory(String dir) {\n        File file = new File(dir);\n        if (file.isDirectory()) {\n            workingDirectory = file.getAbsolutePath();\n            System.out.println(\"Directorio de trabajo establecido en: \" + workingDirectory);\n        } else {\n            System.out.println(\"Error: El directorio no existe.\");\n        }\n    }\n\n    public void createRepository(String name) {\n        if (workingDirectory == null) {\n            System.out.println(\"Error: Debe establecer un directorio de trabajo primero.\");\n            return;\n        }\n        executeCommand(\"cd \" + workingDirectory + \" && git init \" + name);\n    }\n\n    public void createBranch(String branchName) {\n        executeCommand(\"cd \" + workingDirectory + \" && git checkout -b \" + branchName);\n    }\n\n    public void changeBranch(String branchName) {\n        executeCommand(\"cd \" + workingDirectory + \" && git checkout \" + branchName);\n    }\n\n    public void showPendingCommits() {\n        executeCommand(\"cd \" + workingDirectory + \" && git status\");\n    }\n\n    public void commitChanges(String message) {\n        executeCommand(\"cd \" + workingDirectory + \" && git add . && git commit -m \\\"\" + message + \"\\\"\");\n    }\n\n    public void showCommitHistory() {\n        executeCommand(\"cd \" + workingDirectory + \" && git log\");\n    }\n\n    public void deleteBranch(String branchName) {\n        executeCommand(\"cd \" + workingDirectory + \" && git branch -d \" + branchName);\n    }\n\n    public void setRemoteRepository(String url) {\n        executeCommand(\"cd \" + workingDirectory + \" && git remote add origin \" + url);\n    }\n\n    public void pull() {\n        executeCommand(\"cd \" + workingDirectory + \" && git pull\");\n    }\n\n    public void push() {\n        executeCommand(\"cd \" + workingDirectory + \" && git push origin HEAD\");\n    }\n\n    private void executeCommand(String command) {\n        try {\n            Process process = Runtime.getRuntime().exec(new String[]{\"cmd.exe\", \"/c\", command});\n            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));\n            String line;\n            while ((line = reader.readLine()) != null) {\n                System.out.println(line);\n            }\n        } catch (IOException e) {\n            System.out.println(\"Error al ejecutar el comando: \" + e.getMessage());\n        }\n    }\n\n    public void run() {\n        Scanner scanner = new Scanner(System.in);\n        while (true) {\n            System.out.println(\"\\nSelecciona una opción:\");\n            System.out.println(\"1. Establecer el directorio de trabajo\");\n            System.out.println(\"2. Crear un nuevo repositorio\");\n            System.out.println(\"3. Crear una nueva rama\");\n            System.out.println(\"4. Cambiar de rama\");\n            System.out.println(\"5. Mostrar ficheros pendientes de hacer commit\");\n            System.out.println(\"6. Hacer commit\");\n            System.out.println(\"7. Mostrar el historial de commits\");\n            System.out.println(\"8. Eliminar rama\");\n            System.out.println(\"9. Establecer repositorio remoto\");\n            System.out.println(\"10. Hacer pull\");\n            System.out.println(\"11. Hacer push\");\n            System.out.println(\"12. Salir\");\n\n            int option = scanner.nextInt();\n            scanner.nextLine(); // Consume newline\n\n            switch (option) {\n                case 1:\n                    System.out.print(\"Introduce el directorio de trabajo: \");\n                    String dir = scanner.nextLine();\n                    setWorkingDirectory(dir);\n                    break;\n                case 2:\n                    System.out.print(\"Introduce el nombre del repositorio: \");\n                    String name = scanner.nextLine();\n                    createRepository(name);\n                    break;\n                case 3:\n                    System.out.print(\"Introduce el nombre de la nueva rama: \");\n                    String branchName = scanner.nextLine();\n                    createBranch(branchName);\n                    break;\n                case 4:\n                    System.out.print(\"Introduce el nombre de la rama a la que deseas cambiar: \");\n                    String changeBranch = scanner.nextLine();\n                    changeBranch(changeBranch);\n                    break;\n                case 5:\n                    showPendingCommits();\n                    break;\n                case 6:\n                    System.out.print(\"Introduce el mensaje del commit: \");\n                    String message = scanner.nextLine();\n                    commitChanges(message);\n                    break;\n                case 7:\n                    showCommitHistory();\n                    break;\n                case 8:\n                    System.out.print(\"Introduce el nombre de la rama a eliminar: \");\n                    String deleteBranch = scanner.nextLine();\n                    deleteBranch(deleteBranch);\n                    break;\n                case 9:\n                    System.out.print(\"Introduce la URL del repositorio remoto: \");\n                    String url = scanner.nextLine();\n                    setRemoteRepository(url);\n                    break;\n                case 10:\n                    pull();\n                    break;\n                case 11:\n                    push();\n                    break;\n                case 12:\n                    System.out.println(\"Saliendo...\");\n                    scanner.close();\n                    System.exit(0);\n                default:\n                    System.out.println(\"Opción no válida.\");\n            }\n        }\n    }\n\n    public static void main(String[] args) {\n        GitHubCLI cli = new GitHubCLI();\n        cli.run();\n    }\n}\n"
  },
  {
    "path": "Roadmap/43 - GIT GITHUB CLI/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #43 - JavaScript -> Jesus Antonio Escamilla */\n\n/**\n * GIT GITHUB CLI.\n * Utilizando la Terminal para pedir datos y agregarlos.\n */\n\nconst readline = require('readline');\nconst { execSync } = require('child_process');\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nlet currentDirectory = process.cwd();\n\nfunction executeCommand(command){\n    try {\n        const result = execSync(command, {cwd: currentDirectory, stdio: 'pipe'});\n        console.log(result.toString());\n    } catch (error) {\n        console.error(`Error: ${error.message}`);\n    }\n}\n\nfunction askQuestion(question) {\n    return new Promise((resolve) => rl.question(question, resolve));\n}\n\nasync function mainMenu() {\n    console.log(`\\nCurrent Directory: ${currentDirectory}`);\n    console.log('1. Establecer el directorio de trabajo');\n    console.log('2. Crear un nuevo repositorio');\n    console.log('3. Crear una nueva rama');\n    console.log('4. Cambiar de rama');\n    console.log('5. Mostrar ficheros pendientes de hacer commit');\n    console.log('6. Hacer commit (+ add)');\n    console.log('7. Mostrar el historial de commits');\n    console.log('8. Eliminar rama');\n    console.log('9. Establecer repositorio remoto');\n    console.log('10. Hacer Pull');\n    console.log('11. Hacer Push');\n    console.log('12. Salir');\n\n    const choice = await askQuestion('Seleccione una opción: ');\n\n    switch (choice) {\n        case '1':\n            currentDirectory = await askQuestion('Introduzca el nuevo directorio de trabajo: ');\n            console.log(`Directorio de trabajo establecido en: ${currentDirectory}`);\n            break;\n    \n        case '2':\n            executeCommand('git init');\n            break;\n    \n        case '3':\n            const newBranch = await askQuestion('Introduzca el nombre de la rama: ');\n            executeCommand(`git branch ${newBranch}`);\n            break;\n    \n        case '4':\n            const branchToSwitch = await askQuestion('Introduzca el nombre de la rama a la que desea cambiar: ');\n            executeCommand(`git checkout ${branchToSwitch}`);\n            break;\n    \n        case '5':\n            executeCommand('git status');\n            break;\n    \n        case '6':\n            const commitMessage = await askQuestion('Introduzca commit del mensaje: ');\n            executeCommand('git add .');\n            executeCommand(`git commit -m \"${commitMessage}\"`);\n            break;\n    \n        case '7':\n            executeCommand('git log --oneline');\n            break;\n    \n        case '8':\n            const branchToDelete = await askQuestion('Introduzca el nombre de la rama a eliminar: ');\n            executeCommand(`git branch -d ${branchToDelete}`);\n            break;\n    \n        case '9':\n            const remoteName = await askQuestion('Introduzca el nombre remoto (e.g., origin): ');\n            const remoteUrl = await askQuestion('Introduzca la URL remota: ');\n            executeCommand(`git remote add ${remoteName} ${remoteUrl}`);\n            break;\n    \n        case '10':\n            executeCommand('git pull');\n            break;\n    \n        case '11':\n            executeCommand('git push');\n            break;\n    \n        case '12':\n            console.log('Adios!');\n            rl.close();\n            return;\n    \n        default:\n            console.log('Opción no válida, por favor inténtelo nuevamente.');\n    }\n    await mainMenu();\n}\n\nconsole.log('Bienvenido a GitHub CLI!');\nmainMenu();"
  },
  {
    "path": "Roadmap/43 - GIT GITHUB CLI/javascript/RaulDoezon.js",
    "content": "/*\n * EJERCICIO:\n * ¡Me voy de viaje al GitHub Universe 2024 de San Francisco!\n *\n * Desarrolla un CLI (Command Line Interface) que permita \n * interactuar con Git y GitHub de manera real desde terminal.\n * \n * El programa debe permitir las siguientes opciones:\n * 1. Establecer el directorio de trabajo\n * 2. Crear un nuevo repositorio\n * 3. Crear una nueva rama\n * 4. Cambiar de rama\n * 5. Mostrar ficheros pendientes de hacer commit\n * 6. Hacer commit (junto con un add de todos los ficheros)\n * 7. Mostrar el historial de commits\n * 8. Eliminar rama\n * 9. Establecer repositorio remoto\n * 10. Hacer pull\n * 11. Hacer push\n * 12. Salir\n *\n * Puedes intentar controlar los diferentes errores.\n */\n\nconst fs = require(\"fs\");\nconst { chdir, cwd } = require(\"process\");\nconst { exec } = require('child_process');\nconst readLine = require(\"readline\");\nconst { stdin: input, stdout: output } = require(\"process\");\nconst rl = readLine.createInterface({ input, output });\nlet menuText = \"\\n1. Establecer el directorio de trabajo.\\n2. Crear un nuevo repositorio.\\n3. Crear una nueva rama.\\n4. Cambiar de rama.\\n5. Mostrar ficheros pendientes de hacer commit.\\n6. Hacer commit (junto con un add de todos los ficheros).\\n7. Mostrar el historial de commits.\\n8. Eliminar rama.\\n9. Establecer repositorio remoto.\\n10. Hacer pull.\\n11. Hacer push.\\n12. Salir.\\n\";\n\nfunction runCommand(command) {\n  exec(command, (error, stdout) => {\n    if (error) {\n      console.log(`\\nOcurrió un error: ${error}`);\n    } else {\n      console.log(`\\n${stdout}`);\n    }\n  });\n}\n\nfunction menuCLI() {\n  console.log(`\\nDirectorio actual: ${cwd()}`);\n\n  rl.question(menuText, (answer) => {\n    let option = parseInt(answer, 10);\n\n    if (option === 1) {\n      rl.question(\"\\nIngresa el directorio: \", (path) => {\n        try {\n          chdir(path);\n        } catch (error) {\n          console.log(`\\nEl directorio no existe: ${error}`);\n        }\n\n        menuCLI();\n      });\n    } else if (option === 2) {\n      if (fs.existsSync(`${cwd()}/.git`)) {\n        console.log(\"\\nYa se ha inicializado un repositorio.\");\n      } else {\n        runCommand(\"git init && git branch -M main\");\n      }\n\n      menuCLI();\n    } else if (option  === 3) {\n      rl.question(\"\\nIngresa el nombre de la rama que quieres crear: \", (branch) => {\n        runCommand(`git branch ${branch}`);\n        menuCLI();\n      });\n    } else if (option === 4) {\n      rl.question(\"\\nIngresa el nombre de la rama a la cual quieres cambiar: \", (branch) => {\n        runCommand(`git checkout ${branch}`);\n        menuCLI();\n      });\n    } else if (option === 5) {\n      runCommand(\"git status\");\n      menuCLI();\n    } else if (option === 6) {\n      runCommand(\"git add .\");\n\n      rl.question(\"\\nIngresa el mensaje del commit: \", (message) => {\n        runCommand(`git commit -m \"${message}\"`);\n        menuCLI();\n      });\n    } else if (option === 7) {\n      runCommand(\"git log\");\n      menuCLI();\n    } else if (option === 8) {\n      rl.question(\"\\nIngresa el nombre de la rama que quieres eliminar: \", (branch) => {\n        runCommand(`git branch -D ${branch}`);\n        menuCLI();\n      });\n    } else if (option === 9) {\n      rl.question(\"\\nIngresa la URL del repositorio: \", (url) => {\n        runCommand(`git remote add origin ${url}`);\n        menuCLI();\n      });\n    } else if (option === 10) {\n      rl.question(\"\\nIngresa el nombre de la rama que quieres fusionar: \", (branch) => {\n        runCommand(`git pull origin ${branch}`);\n        menuCLI();\n      });\n    } else if (option === 11) {\n      rl.question(\"\\nIngresa el nombre de la rama: \", (branch) => {\n        runCommand(`git push -u origin ${branch}`);\n        menuCLI();\n      });\n    } else if (option === 12) {\n      console.log(\"Cerrando CLI...\");\n\n      return rl.close();\n    }\n    else {\n      console.log(\"\\nSelecciona una de las opciones del menú.\");\n\n      menuCLI();\n    }\n  });\n}\n\nmenuCLI();\n"
  },
  {
    "path": "Roadmap/43 - GIT GITHUB CLI/javascript/duendeintemporal.js",
    "content": "//43 - GIT GITHUB CLI \n/*\n * EJERCICIO:\n * ¡Me voy de viaje al GitHub Universe 2024 de San Francisco!\n *\n * Desarrolla un CLI (Command Line Interface) que permita\n * interactuar con Git y GitHub de manera real desde terminal.\n *\n * El programa debe permitir las siguientes opciones:\n * 1. Establecer el directorio de trabajo\n * 2. Crear un nuevo repositorio\n * 3. Crear una nueva rama\n * 4. Cambiar de rama\n * 5. Mostrar ficheros pendientes de hacer commit\n * 6. Hacer commit (junto con un add de todos los ficheros)\n * 7. Mostrar el historial de commits\n * 8. Eliminar rama\n * 9. Establecer repositorio remoto\n * 10. Hacer pull\n * 11. Hacer push\n * 12. Salir\n *\n * Puedes intentar controlar los diferentes errores.\n */\n\nlet log = console.log;\n\nconst { exec } = require('child_process');\nconst readline = require('readline');\n\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout\n});\n\nlet currentDirectory = process.cwd();\nlet currentBranch = 'main';\nlet remoteRepository = '';\n\nfunction runGitCommand(command) {\n  return new Promise((resolve, reject) => {\n    exec(`git ${command}`, { cwd: currentDirectory }, (error, stdout, stderr) => {\n      if (error) {\n        reject(stderr);\n      } else {\n        resolve(stdout.trim());\n      }\n    });\n  });\n}\n\nasync function main() {\n  log('Welcome to the GitHub Universe 2024 CLI!');\n\n  while (true) {\n    const options = [\n      '1. Set working directory',\n      '2. Create new repository',\n      '3. Create new branch',\n      '4. Switch branch',\n      '5. Show pending files',\n      '6. Commit changes',\n      '7. Show commit history',\n      '8. Delete branch',\n      '9. Set remote repository',\n      '10. Pull from remote',\n      '11. Push to remote',\n      '12. Exit'\n    ];\n\n    log('\\nPlease select an option:');\n    log(options.join('\\n'));\n\n    const choice = await new Promise(resolve => rl.question('Enter your choice: ', resolve));\n\n    switch (choice) {\n      case '1':\n        currentDirectory = await new Promise(resolve => rl.question('Enter the new working directory: ', resolve));\n        log(`Working directory set to: ${currentDirectory}`);\n        break;\n      case '2':\n        const newRepoName = await new Promise(resolve => rl.question('Enter the name of the new repository: ', resolve));\n        await runGitCommand(`init ${newRepoName}`);\n        log(`New repository created: ${newRepoName}`);\n        break;\n      case '3':\n        const newBranchName = await new Promise(resolve => rl.question('Enter the name of the new branch: ', resolve));\n        await runGitCommand(`checkout -b ${newBranchName}`);\n        currentBranch = newBranchName;\n        log(`New branch created: ${newBranchName}`);\n        break;\n      case '4':\n        const branchToSwitch = await new Promise(resolve => rl.question('Enter the name of the branch to switch to: ', resolve));\n        await runGitCommand(`checkout ${branchToSwitch}`);\n        currentBranch = branchToSwitch;\n        log(`Switched to branch: ${branchToSwitch}`);\n        break;\n      case '5':\n        const pendingFiles = await runGitCommand('status --porcelain');\n        log('Pending files:');\n        log(pendingFiles);\n        break;\n      case '6':\n        await runGitCommand('add .');\n        const commitMessage = await new Promise(resolve => rl.question('Enter the commit message: ', resolve));\n        await runGitCommand(`commit -m \"${commitMessage}\"`);\n        log('Changes committed successfully');\n        break;\n      case '7':\n        const commitHistory = await runGitCommand('log --oneline');\n        log('Commit history:');\n        log(commitHistory);\n        break;\n      case '8':\n        const branchToDelete = await new Promise(resolve => rl.question('Enter the name of the branch to delete: ', resolve));\n        await runGitCommand(`branch -d ${branchToDelete}`);\n        log(`Branch ${branchToDelete} deleted`);\n        break;\n      case '9':\n        remoteRepository = await new Promise(resolve => rl.question('Enter the URL of the remote repository: ', resolve));\n        await runGitCommand(`remote add origin ${remoteRepository}`);\n        log(`Remote repository set to: ${remoteRepository}`);\n        break;\n        case '10':\n            await runGitCommand(`pull origin ${currentBranch}`);\n            log('Pulled changes from remote repository');\n            break;\n          case '11':\n            await runGitCommand(`push -u origin ${currentBranch}`);\n            log('Pushed changes to remote repository');\n            break;\n          case '12':\n            log('Exiting the GitHub Universe 2024 CLI...');\n            rl.close();\n            return;\n          default:\n            log('Invalid choice. Please try again.');\n            break;\n    }\n  }\n}  \n          main();"
  },
  {
    "path": "Roadmap/43 - GIT GITHUB CLI/javascript/hectorio23.js",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\nconst readline = require(\"readline\");\nconst { execSync } = require(\"child_process\");\n\n// Configurar readline para manejar entradas del usuario\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout,\n});\n\n// Función para solicitar entrada al usuario de forma síncrona\nconst prompt = (query) => new Promise((resolve) => rl.question(query, resolve));\n\n// Opciones del CLI con nombres descriptivos\nconst actions = {\n    1: { name: \"Set working directory\", action: async () => {\n        const path = await prompt(\"Enter the working directory path: \");\n        try {\n            process.chdir(path);\n            console.log(`Working directory set to ${process.cwd()}`);\n        } catch (err) {\n            console.error(\"Invalid directory path.\");\n        }\n    }},\n    2: { name: \"Create a new repository\", action: () => execSync(\"git init\", { stdio: \"inherit\" }) },\n    3: { name: \"Create a new branch\", action: async () => {\n        const branch = await prompt(\"Enter branch name: \");\n        execSync(`git branch ${branch}`, { stdio: \"inherit\" });\n    }},\n    4: { name: \"Switch branch\", action: async () => {\n        const branch = await prompt(\"Enter branch name: \");\n        execSync(`git checkout ${branch}`, { stdio: \"inherit\" });\n    }},\n    5: { name: \"Show pending files\", action: () => execSync(\"git status\", { stdio: \"inherit\" }) },\n    6: { name: \"Commit changes\", action: async () => {\n        const message = await prompt(\"Enter commit message: \");\n        execSync(\"git add .\", { stdio: \"inherit\" });\n        execSync(`git commit -m \"${message}\"`, { stdio: \"inherit\" });\n    }},\n    7: { name: \"Show commit history\", action: () => execSync(\"git log --oneline\", { stdio: \"inherit\" }) },\n    8: { name: \"Delete branch\", action: async () => {\n        const branch = await prompt(\"Enter branch name to delete: \");\n        execSync(`git branch -d ${branch}`, { stdio: \"inherit\" });\n    }},\n    9: { name: \"Set remote repository\", action: async () => {\n        const remoteUrl = await prompt(\"Enter remote repository URL: \");\n        execSync(`git remote add origin ${remoteUrl}`, { stdio: \"inherit\" });\n    }},\n    10: { name: \"Pull changes\", action: () => execSync(\"git pull origin\", { stdio: \"inherit\" }) },\n    11: { name: \"Push changes\", action: () => execSync(\"git push origin\", { stdio: \"inherit\" }) },\n    12: { name: \"Exit\", action: () => {\n        console.log(\"Goodbye!\");\n        rl.close();\n        process.exit(0);\n    }},\n};\n\n// Loop principal para mostrar opciones y ejecutar comandos\n(async function main() {\n    while (true) {\n        console.log(\"\\nOptions:\");\n        Object.entries(actions).forEach(([key, { name }]) => {\n            console.log(`${key}. ${name}`);\n        });\n\n        const choice = await prompt(\"\\nSelect an option: \");\n        const actionObj = actions[choice];\n        if (actionObj) await actionObj.action();\n        else console.log(\"Invalid option.\");\n    }\n})();\n"
  },
  {
    "path": "Roadmap/43 - GIT GITHUB CLI/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n_______________________________________________________\n#43 GIT GITHUB CLI\n-------------------------------------------------------\n* EJERCICIO:\n * ¡Me voy de viaje al GitHub Universe 2024 de San Francisco!\n *\n * Desarrolla un CLI (Command Line Interface) que permita \n * interactuar con Git y GitHub de manera real desde terminal.\n * \n * El programa debe permitir las siguientes opciones:\n * 1. Establecer el directorio de trabajo\n * 2. Crear un nuevo repositorio\n * 3. Crear una nueva rama\n * 4. Cambiar de rama\n * 5. Mostrar ficheros pendientes de hacer commit\n * 6. Hacer commit (junto con un add de todos los ficheros)\n * 7. Mostrar el historial de commits\n * 8. Eliminar rama\n * 9. Establecer repositorio remoto\n * 10. Hacer pull\n * 11. Hacer push\n * 12. Salir\n *\n * Puedes intentar controlar los diferentes errores.\n */\n// ________________________________________________________\nconst { exec } = require('child_process');\nconst readline = require('readline');\nconst path = require('path');\nconst fs = require('fs');\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nconst question = (query) => new Promise((resolve) => rl.question(query, resolve));\n\nfunction runCommand(command, msg = \"\") {\n    return new Promise((resolve) => {\n        if (msg) console.log(msg);\n        \n        exec(command, { encoding: 'utf8' }, (error, stdout, stderr) => {\n            if (error) {\n                console.log(`❌: ${stderr.trim()}`);\n            } else {\n                console.log(`✅: ${stdout.trim()}`);\n            }\n            resolve();\n        });\n    });\n}\n\nasync function setDirectory() {\n    console.log(\"Establecer directorio de trabajo:\");\n    const dirPath = await question(\"Ruta: \");\n    \n    if (fs.existsSync(dirPath) && fs.statSync(dirPath).isDirectory()) {\n        process.chdir(dirPath);\n    } else {\n        console.log(\"Esta ruta no existe.\");\n    }\n}\n\nasync function setRemoteRepository() {\n    const remoteUrl = await question(\"URL del repositorio: \");\n    await runCommand(`git remote add origin ${remoteUrl}`);\n    await runCommand(\"git push -u origin main\");\n}\n\nconst MENU = `\nInteractuar con Git y GitHub:\n------------------------------------------------------------\n| 1. Establecer directorio       | 7. Historial de commits |  \n| 2. Crear repositorio           | 8. Eliminar rama        |\n| 3. Crear rama                  | 9. Configurar remoto    |\n| 4. Cambiar rama                | 10. pull                | \n| 5. Mostrar cambios pendientes  | 11. push                | \n| 6. 'add' + 'commit'            | 12. Salir               | \n------------------------------------------------------------\nDirectorio actual:`;\n\nasync function main() {\n    while (true) {\n        console.log(MENU);\n        await runCommand(process.platform === \"win32\" ? \"cd\" : \"pwd\");\n        \n        const option = await question(\"\\nOpción: \");\n\n        switch (option) {\n            case \"1\":\n                await setDirectory();\n                break;\n\n            case \"2\":\n                await runCommand(\"git init && git branch -M main\", \"Crear repositorio\");\n                break;\n\n            case \"3\":\n                console.log(\"Crear nueva rama:\");\n                const newBranch = await question(\"Nombre: \");\n                await runCommand(`git branch -c ${newBranch}`);\n                break;\n\n            case \"4\":\n                console.log(\"Cambiar de rama:\");\n                const switchBranch = await question(\"Nombre: \");\n                await runCommand(`git switch ${switchBranch}`);\n                break;\n\n            case \"5\":\n                await runCommand(\"git status -s\", \"Mostrar cambios\");\n                break;\n\n            case \"6\":\n                console.log(\"Nuevo commit:\");\n                const commitMsg = await question(\"Mensaje: \");\n                await runCommand(`git add . && git commit -m '${commitMsg}'`);\n                break;\n\n            case \"7\":\n                await runCommand(\"git log --oneline\", \"Historial de commits\");\n                break;\n\n            case \"8\":\n                console.log(\"Eliminar rama\");\n                const deleteBranch = await question(\"Nombre: \");\n                await runCommand(`git branch -d ${deleteBranch}`);\n                break;\n\n            case \"9\":\n                await setRemoteRepository();\n                break;\n\n            case \"10\":\n                const pullBranch = await question(\"rama: \");\n                await runCommand(`git pull origin ${pullBranch}`);\n                break;\n\n            case \"11\":\n                const pushBranch = await question(\"rama: \");\n                await runCommand(`git push origin ${pushBranch}`);\n                break;\n\n            case \"12\":\n                console.log(\"Bye.\");\n                rl.close();\n                return;\n\n            default:\n                console.log(\"Opción no válida.\");\n        }\n    }\n}\n\nrl.on('close', () => process.exit(0));\nmain().catch(console.error);\n"
  },
  {
    "path": "Roadmap/43 - GIT GITHUB CLI/javascript/lioarce01.js",
    "content": "import simpleGit from \"simple-git\";\nimport { Octokit } from \"@octokit/rest\";\nimport { hideBin } from \"yargs/helpers\";\nimport yargs from \"yargs/yargs\";\nimport fs from \"fs\";\nimport path from \"path\";\nimport dotenv from \"dotenv\";\n\ndotenv.config();\n\nconst TOKEN = process.env.GITHUB_TOKEN;\n\nconst git = simpleGit();\nconst octokit = new Octokit({ auth: TOKEN });\n\n//GIT CLONE COMMAND\nyargs(hideBin(process.argv))\n  .command(\n    \"clone [repoUrl] [dir]\",\n    \"Clone a repository\",\n    (yargs) => {\n      yargs\n        .positional(\"repoUrl\", {\n          describe: \"URL of the repository to clone\",\n          type: \"string\",\n          demandOption: true,\n        })\n        .positional(\"dir\", {\n          describe: \"Directory to clone the repository into\",\n          type: \"string\",\n          default: \".\",\n        });\n    },\n    async (argv) => {\n      try {\n        const destinationDir = path.resolve(argv.dir);\n        const files = fs.readdirSync(destinationDir);\n\n        if (destinationDir === process.cwd() && files.length > 0) {\n          console.error(\"Error: Directory is not empty.\");\n          return;\n        }\n\n        console.log(`Cloning repository from ${argv.repoUrl} into ${argv.dir}`);\n        await git.clone(argv.repoUrl, destinationDir);\n        console.log(`Repository cloned into ${destinationDir}`);\n      } catch (error) {\n        console.error(\"Error cloning repository:\", error.message);\n      }\n    }\n  )\n  // GIT ADD COMMAND\n  .command(\n    \"add [files]\",\n    \"Add files to the Git index (staging area)\",\n    (yargs) => {\n      yargs.positional(\"files\", {\n        describe: \"Files to add (use '.' to add all files)\",\n        type: \"string\",\n        demandOption: true,\n      });\n    },\n    async (argv) => {\n      try {\n        await git.add(argv.files);\n        console.log(`Files added: ${argv.files}`);\n      } catch (error) {\n        console.error(\"Error adding files:\", error.message);\n      }\n    }\n  )\n  // GIT COMMIT COMMAND\n  .command(\n    \"commit [message]\",\n    \"Commit changes with a message\",\n    (yargs) => {\n      yargs.positional(\"message\", {\n        describe: \"Commit message\",\n        type: \"string\",\n        demandOption: true,\n      });\n    },\n    async (argv) => {\n      try {\n        await git.commit(argv.message);\n        console.log(`Changes committed with message: \"${argv.message}\"`);\n      } catch (error) {\n        console.error(\"Error committing changes:\", error.message);\n      }\n    }\n  )\n  // GIT PUSH COMMAND\n  .command(\n    \"push\",\n    \"Push changes to a remote repository\",\n    () => {},\n    async () => {\n      try {\n        await git.push(\"origin\", \"main\");\n        console.log(\"Changes pushed to a remote repository\");\n      } catch (error) {\n        console.error(\"Error pushing changes:\", error.message);\n      }\n    }\n  )\n  //GIT PULL COMMAND\n  .command(\n    \"pull\",\n    \"Pull changes from a remote repository\",\n    () => {},\n    async () => {\n      try {\n        await git.pull(\"origin\", \"main\");\n        console.log(\"Changes pulled from a remote repository\");\n      } catch (error) {\n        console.error(\"Error pulling changes:\", error.message);\n      }\n    }\n  )\n  //GIT STATUS COMMAND\n  .command(\n    \"status\",\n    \"Show the status of the repository\",\n    () => {},\n    async () => {\n      try {\n        const status = await git.status();\n        console.log(\"Repository status:\");\n        console.log(status);\n      } catch (error) {\n        console.error(\"Error retrieving repository status:\", error.message);\n      }\n    }\n  )\n  //GIT LOG COMMAND\n  .command(\n    \"log\",\n    \"Show commit history\",\n    () => {},\n    async () => {\n      try {\n        const log = await git.log();\n        console.log(\"Commit history:\");\n        console.log(log);\n      } catch (error) {\n        console.error(\"Error retrieving commit history:\", error.message);\n      }\n    }\n  )\n  //CREATE REPO COMMAND\n  .command(\n    \"create-repo [repoName]\",\n    \"Create a new repository\",\n    (yargs) => {\n      yargs.positional(\"repoName\", {\n        describe: \"Name of the new repository\",\n        type: \"string\",\n        demandOption: true,\n      });\n    },\n    async (argv) => {\n      try {\n        const response = await octokit.repos.createForAuthenticatedUser({\n          name: argv.repoName,\n          private: false,\n        });\n        console.log(`Repository ${argv.repoName} created successfully`);\n        console.log(`URL: ${response.data.html_url}`);\n      } catch (error) {\n        console.error(\"Error creating repository:\", error.message);\n      }\n    }\n  )\n  //GIT CREATE BRANCH COMMAND\n  .command(\n    \"create-branch [branchName]\",\n    \"Create a new branch\",\n    (yargs) => {\n      yargs.positional(\"branchName\", {\n        describe: \"Name of the new branch\",\n        type: \"string\",\n        demandOption: true,\n      });\n    },\n    async (argv) => {\n      try {\n        await git.checkoutLocalBranch(argv.branchName);\n        console.log(`Branch \"${argv.branchName}\" created successfully`);\n      } catch (error) {\n        console.error(\"Error creating branch:\", error.message);\n      }\n    }\n  )\n  //GIT SWITCH BRANCH  COMMAND\n  .command(\n    \"switch-branch [branchName]\",\n    \"Switch to a branch\",\n    (yargs) => {\n      yargs.positional(\"branchName\", {\n        describe: \"Name of the branch to switch to\",\n        type: \"string\",\n        demandOption: true,\n      });\n    },\n    async (argv) => {\n      try {\n        await git.checkout(argv.branchName);\n        console.log(`Switched to branch \"${argv.branchName}\".`);\n      } catch (error) {\n        console.error(\"Error switching branches:\", error.message);\n      }\n    }\n  )\n  //GIT DELETE BRANCH COMMAND\n  .command(\n    \"delete-branch\",\n    \"Delete a branch\",\n    (yargs) => {\n      yargs.positional(\"branchName\", {\n        describe: \"Name of the branch to delete\",\n        type: \"string\",\n        demandOption: true,\n      });\n    },\n    async (argv) => {\n      try {\n        await git.deleteLocalBranch(argv.branchName);\n        console.log(`Branch \"${argv.branchName}\" deleted successfully`);\n      } catch (error) {\n        console.error(\"Error deleting branch:\", error.message);\n      }\n    }\n  )\n  //GIT SET REMOTE REPOSITORY COMMAND\n  .command(\n    \"set-remote [name] [url]\",\n    \"Set a remote repository\",\n    (yargs) => {\n      yargs\n        .positional(\"name\", {\n          describe: \"Name of the remote (e.g., origin)\",\n          type: \"string\",\n          demandOption: true,\n        })\n        .positional(\"url\", {\n          describe: \"URL of the remote repository\",\n          type: \"string\",\n          demandOption: true,\n        });\n    },\n    async (argv) => {\n      try {\n        await git.addRemote(argv.name, argv.url);\n        console.log(`Remote \"${argv.name}\" set to ${argv.url}`);\n      } catch (error) {\n        console.error(\"Error setting remote repository:\", error.message);\n      }\n    }\n  )\n  //SET WORKING DIRECTORY COMMAND\n  .command(\n    \"set-dir [directory]\",\n    \"Set working directory for Git commands\",\n    (yargs) => {\n      yargs.positional(\"directory\", {\n        describe: \"Path to the directory\",\n        type: \"string\",\n        demandOption: true,\n      });\n    },\n    async (argv) => {\n      try {\n        const dir = path.resolve(argv.directory);\n        if (!fs.existsSync(dir)) {\n          console.error(\"The specified directory does not exist.\");\n          return;\n        }\n\n        git.cwd(dir);\n        console.log(`Working diretory set to: ${dir}`);\n      } catch (error) {\n        console.error(\"Error setting working directory\");\n      }\n    }\n  )\n  //EXIT FROM CLI COMMAND\n  .command(\n    \"exit\",\n    \"Exit the CLI\",\n    () => {},\n    () => {\n      console.log(\"Exiting the CLI, Goodbye!\");\n      process.exit(0);\n    }\n  )\n  .help().argv;\n"
  },
  {
    "path": "Roadmap/43 - GIT GITHUB CLI/javascript/miguelex.js",
    "content": "const { exec } = require('child_process');\nconst readline = require('readline');\n\nclass GitHubCLI {\n    constructor() {\n        this.workingDirectory = '';\n    }\n\n    setWorkingDirectory(dir) {\n        exec(`cd ${dir}`, (error) => {\n            if (error) {\n                console.log(\"Error: El directorio no existe.\");\n            } else {\n                this.workingDirectory = dir;\n                console.log(`Directorio de trabajo establecido en: ${this.workingDirectory}`);\n            }\n        });\n    }\n\n    createRepository(name) {\n        if (!this.workingDirectory) {\n            console.log(\"Error: Debe establecer un directorio de trabajo primero.\");\n            return;\n        }\n        exec(`cd ${this.workingDirectory} && git init ${name}`, (error) => {\n            if (error) {\n                console.log(\"Error al crear el repositorio.\");\n            } else {\n                console.log(`Repositorio '${name}' creado.`);\n            }\n        });\n    }\n\n    createBranch(branchName) {\n        exec(`cd ${this.workingDirectory} && git checkout -b ${branchName}`, (error) => {\n            if (error) {\n                console.log(\"Error al crear la rama.\");\n            } else {\n                console.log(`Rama '${branchName}' creada.`);\n            }\n        });\n    }\n\n    changeBranch(branchName) {\n        exec(`cd ${this.workingDirectory} && git checkout ${branchName}`, (error) => {\n            if (error) {\n                console.log(\"Error al cambiar de rama.\");\n            } else {\n                console.log(`Cambiado a la rama '${branchName}'.`);\n            }\n        });\n    }\n\n    showPendingCommits() {\n        exec(`cd ${this.workingDirectory} && git status`, (error, stdout) => {\n            if (error) {\n                console.log(\"Error al mostrar el estado.\");\n            } else {\n                console.log(stdout);\n            }\n        });\n    }\n\n    commitChanges(message) {\n        exec(`cd ${this.workingDirectory} && git add . && git commit -m \"${message}\"`, (error) => {\n            if (error) {\n                console.log(\"Error al hacer commit.\");\n            } else {\n                console.log(`Cambios comprometidos con el mensaje: \"${message}\".`);\n            }\n        });\n    }\n\n    showCommitHistory() {\n        exec(`cd ${this.workingDirectory} && git log`, (error, stdout) => {\n            if (error) {\n                console.log(\"Error al mostrar el historial de commits.\");\n            } else {\n                console.log(stdout);\n            }\n        });\n    }\n\n    deleteBranch(branchName) {\n        exec(`cd ${this.workingDirectory} && git branch -d ${branchName}`, (error) => {\n            if (error) {\n                console.log(\"Error al eliminar la rama.\");\n            } else {\n                console.log(`Rama '${branchName}' eliminada.`);\n            }\n        });\n    }\n\n    setRemoteRepository(url) {\n        exec(`cd ${this.workingDirectory} && git remote add origin ${url}`, (error) => {\n            if (error) {\n                console.log(\"Error al establecer el repositorio remoto.\");\n            } else {\n                console.log(`Repositorio remoto establecido en: ${url}.`);\n            }\n        });\n    }\n\n    pull() {\n        exec(`cd ${this.workingDirectory} && git pull`, (error) => {\n            if (error) {\n                console.log(\"Error al realizar pull.\");\n            } else {\n                console.log(\"Pull realizado correctamente.\");\n            }\n        });\n    }\n\n    push() {\n        exec(`cd ${this.workingDirectory} && git push origin HEAD`, (error) => {\n            if (error) {\n                console.log(\"Error al realizar push.\");\n            } else {\n                console.log(\"Push realizado correctamente.\");\n            }\n        });\n    }\n\n    run() {\n        const rl = readline.createInterface({\n            input: process.stdin,\n            output: process.stdout\n        });\n\n        const askQuestion = () => {\n            console.log(\"\\nSelecciona una opción:\");\n            console.log(\"1. Establecer el directorio de trabajo\");\n            console.log(\"2. Crear un nuevo repositorio\");\n            console.log(\"3. Crear una nueva rama\");\n            console.log(\"4. Cambiar de rama\");\n            console.log(\"5. Mostrar ficheros pendientes de hacer commit\");\n            console.log(\"6. Hacer commit\");\n            console.log(\"7. Mostrar el historial de commits\");\n            console.log(\"8. Eliminar rama\");\n            console.log(\"9. Establecer repositorio remoto\");\n            console.log(\"10. Hacer pull\");\n            console.log(\"11. Hacer push\");\n            console.log(\"12. Salir\");\n\n            rl.question('Opción: ', (option) => {\n                switch (option) {\n                    case '1':\n                        rl.question('Introduce el directorio de trabajo: ', (dir) => {\n                            this.setWorkingDirectory(dir);\n                            askQuestion();\n                        });\n                        break;\n                    case '2':\n                        rl.question('Introduce el nombre del repositorio: ', (name) => {\n                            this.createRepository(name);\n                            askQuestion();\n                        });\n                        break;\n                    case '3':\n                        rl.question('Introduce el nombre de la nueva rama: ', (branchName) => {\n                            this.createBranch(branchName);\n                            askQuestion();\n                        });\n                        break;\n                    case '4':\n                        rl.question('Introduce el nombre de la rama a la que deseas cambiar: ', (branchName) => {\n                            this.changeBranch(branchName);\n                            askQuestion();\n                        });\n                        break;\n                    case '5':\n                        this.showPendingCommits();\n                        askQuestion();\n                        break;\n                    case '6':\n                        rl.question('Introduce el mensaje del commit: ', (message) => {\n                            this.commitChanges(message);\n                            askQuestion();\n                        });\n                        break;\n                    case '7':\n                        this.showCommitHistory();\n                        askQuestion();\n                        break;\n                    case '8':\n                        rl.question('Introduce el nombre de la rama a eliminar: ', (branchName) => {\n                            this.deleteBranch(branchName);\n                            askQuestion();\n                        });\n                        break;\n                    case '9':\n                        rl.question('Introduce la URL del repositorio remoto: ', (url) => {\n                            this.setRemoteRepository(url);\n                            askQuestion();\n                        });\n                        break;\n                    case '10':\n                        this.pull();\n                        askQuestion();\n                        break;\n                    case '11':\n                        this.push();\n                        askQuestion();\n                        break;\n                    case '12':\n                        console.log(\"Saliendo...\");\n                        rl.close();\n                        break;\n                    default:\n                        console.log(\"Opción no válida.\");\n                        askQuestion();\n                }\n            });\n        };\n        askQuestion();\n    }\n}\n\nconst cli = new GitHubCLI();\ncli.run();\n"
  },
  {
    "path": "Roadmap/43 - GIT GITHUB CLI/javascript/pedamoci.js",
    "content": "import { exec } from \"child_process\"\nimport readline from \"readline\"\nimport fs from \"fs/promises\"\n\nconst COLORS = Object.freeze({\n  red: \"\\x1b[31m\",\n  green: \"\\x1b[32m\",\n  cyan: \"\\x1b[34m\",\n  purple: \"\\x1b[35m\",\n  reset: \"\\x1b[0m\",\n})\n\nconst GIT_COMMANDS = Object.freeze({\n  initRepository: \"git init\",\n  setRemote: \"git remote add origin\",\n  newBranch: \"git branch\",\n  switchBranch: \"git switch\",\n  deleteBranch: \"git branch -d\",\n  showPendings: \"git status\",\n  addAll: \"git add .\",\n  commit: \"git commit -m\",\n  commitHistory: \"git log\",\n  pull: \"git pull\",\n  push: \"git push\",\n})\n\nconst rL = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout\n})\n\nconst asks = question => new Promise(resolve => {\n  rL.question(COLORS.cyan + question + COLORS.reset, resolve)\n})\n\nconst success = message => console.log(COLORS.green + \"Success: \" + message + COLORS.reset)\nconst error = message => console.log(COLORS.red + \"Error: \" + message + COLORS.reset)\nconst printMenu = () => console.log(COLORS.purple + \n                                    \"--------------------------- ACTIONS ---------------------------\" + \"\\n\" +\n                                    \"| 1. Set up working repository       2. Initialize repository |\" + \"\\n\" +\n                                    \"| 3. Set remote repository           4. Create new branch     |\" + \"\\n\" +\n                                    \"| 5. Switch branch                   6. Show pendings         |\" + \"\\n\" +\n                                    \"| 7. Make a commit                   8. show commit history   |\" + \"\\n\" +\n                                    \"| 9. Delete branch                  10. Make a pull request   |\" + \"\\n\" +\n                                    \"| 11. Make a push                   12. Exit                  |\" + \"\\n\" +\n                                    \"---------------------------------------------------------------\" + \"\\n\" +\n                                    COLORS.reset)\n\nconst validateDirectory = async path => {\n  try {\n    const stats = await fs.stat(path)\n\n    if (stats.isDirectory()) {\n      return {\n        valid: true,\n        msg: \"DIRECTORY_CHANGED\"\n      }\n    }\n\n    return {\n      valid: false,\n      msg: \"INCORRECT_PATH\"\n    }\n\n  } catch (error) {\n    return {\n      valid: false,\n      msg: \"PATH_NOT_FOUND\"\n    }\n  }\n}\n\nconst runCommand = command =>{\n  exec(command, (error, stdout, stderr) => {\n    if (error) {\n      error(stderr || error.message)\n      return\n    }\n\n    if (stdout && stdout.trim()) {\n      success(stdout)\n      return\n    }\n\n    success(\"Command executed successfully\")\n  })\n}\n\nasync function main() {\n  let option\n  do {\n    printMenu()\n    option = await asks(\"Enter the option (1-12):\")\n    switch (option) {\n      case \"1\":\n        const path = await asks(\"Enter the working directory path:\")\n        const result = await validateDirectory(path)\n        if (!result.valid) {\n          error(result.msg)\n          break;\n        }\n        process.chdir(path)\n        success(result.msg)\n        break;\n\n      case \"2\":\n        runCommand(GIT_COMMANDS.initRepository)\n        break;\n\n      case \"3\":\n        const url = await asks(\"Enter the remote repository URL:\")\n        const cmdRemoteRepository = GIT_COMMANDS.setRemote + ` ${url}`\n        runCommand(cmdRemoteRepository)\n        break;\n\n      case \"4\":\n        const branchName = await asks(\"Enter the new branch name: \")\n        const cmdNewBranch = GIT_COMMANDS.newBranch + ` ${branchName}`\n        runCommand(cmdNewBranch)\n        break;\n\n      case \"5\":\n        const switchBranchName = await asks(\"Enter the branch name to switch: \")\n        const cmdSwitchBranch = GIT_COMMANDS.switchBranch + ` ${switchBranchName}`\n        runCommand(cmdSwitchBranch)\n        break;\n\n      case \"6\":\n        runCommand(GIT_COMMANDS.showPendings)\n        break;\n\n      case \"7\":\n        const message = await asks(\"Enter the commit message: \")\n        runCommand(GIT_COMMANDS.addAll)\n        const cmdCommit = `${GIT_COMMANDS.commit} \"${message}\"`\n        runCommand(cmdCommit)\n        break;\n\n      case \"8\":\n        runCommand(GIT_COMMANDS.commitHistory)\n        break;\n\n      case \"9\":\n        const deleteBranchName = await asks(\"Enter the branch name to delete: \")\n        const cmdDeleteBranch = GIT_COMMANDS.deleteBranch + ` ${deleteBranchName}`\n        runCommand(cmdDeleteBranch)\n        break;\n\n      case \"10\":\n        const pullBranchName = await asks(\"Enter the branch name to pull: \")\n        const cmdPull = GIT_COMMANDS.pull + ` ${pullBranchName}`\n        runCommand(cmdPull)\n        break;\n\n      case \"11\":\n        const pushBranchName = await asks(\"Enter the branch name to push: \")\n        const cmdPush = GIT_COMMANDS.push + ` ${pushBranchName}`\n        runCommand(cmdPush)\n        break;\n\n      default:break;\n    }\n  } while (option !== \"12\")\n\n  rL.close()\n}\n\nmain()\n\n/*\nclass Asks {\n  constructor() {\n    this.readline = readline.createInterface({\n      input: process.stdin,\n      output: process.stdout\n    })\n  }\n\n  #ask(question) {\n    return new Promise(resolve => {\n      this.readline.question(question, (answer) => resolve(answer))\n    })\n  }\n\n  close() {\n    this.readline.close()\n  }\n\n  async askLabel(info) {\n    const response = await this.#ask(COLORS.cyan + `Enter the ${info}: ` + COLORS.reset)\n    return response\n  }\n}\n\nconst asks = new Asks()\n\nclass Renderer {\n  static error(message) {\n    console.log(COLORS.red + \"Error: \" + message + COLORS.reset)\n  }\n\n  static success(message) {\n    console.log(COLORS.green + \"Success: \" + message + COLORS.reset)\n  }\n\n  static actionsMenu() {\n    console.log(COLORS.purple + \n      \"--------------------------- ACTIONS ---------------------------\" + \"\\n\" +\n      \"| 1. Set up working repository       2. Initialize repository |\" + \"\\n\" +\n      \"| 3. Set remote repository           4. Create new branch     |\" + \"\\n\" +\n      \"| 5. Switch branch                   6. Show pendings         |\" + \"\\n\" +\n      \"| 7. Make a commit                   8. show commit history   |\" + \"\\n\" +\n      \"| 9. Delete branch                  10. Make a pull request   |\" + \"\\n\" +\n      \"| 11. Make a push                   12. Exit                  |\" + \"\\n\" +\n      \"---------------------------------------------------------------\" + \"\\n\" +\n      COLORS.reset)\n  }\n}\n\nclass Validator {\n  static async validateDirectory(path) {\n    try {\n      await fs.access(path)\n\n      const stats = await fs.stat(path)\n\n      if (stats.isDirectory()) {\n        return [true, null]\n      }\n\n      return [false, \"INCORRECT_PATH\"]\n\n    } catch (error) {\n      return [false, \"PATH_NOT_FOUND\"]\n    }\n  }\n}\n\nclass GitController {\n  static runCommand(command) {\n    exec(command, (error, stdout, stderr) => {\n      if (error) {\n        Renderer.error(stderr || error.message)\n        return\n      }\n\n      if (stdout && stdout.trim()) {\n        Renderer.success(stdout)\n        return\n      }\n\n      Renderer.success(\"Command executed successfully\")\n    })\n  }\n}\n\nclass Controller {\n  constructor() {\n    this.command = null\n  }\n\n  async startProgram() {\n    let option \n\n    do { \n    Renderer.actionsMenu()\n    option = await asks.askLabel(\"option (1-11)\")\n\n      switch (option) {\n        case \"1\":\n          const path = await asks.askLabel(\"working directory path\")\n          const [isValid, error] = await Validator.validateDirectory(path)\n\n          if (!isValid) {\n            Renderer.error(error)\n            break;\n          }\n\n          process.chdir(path)\n          break;\n\n        case \"2\":\n          GitController.runCommand(GIT_COMMANDS.initRepository)\n          break;\n\n        case \"3\":\n          const url = await asks.askLabel(\"remote repository URL\")\n          this.command = GIT_COMMANDS.setRemote + ` ${url}`\n\n          GitController.runCommand(this.command)\n          break;\n\n        case \"4\":\n          const branchName = await asks.askLabel(\"new branch name\")\n          this.command = GIT_COMMANDS.newBranch + ` ${branchName}`\n\n          GitController.runCommand(this.command)\n          break;\n\n        case \"5\":\n          const switchBranchName = await asks.askLabel(\"branch name to switch\")\n          this.command = GIT_COMMANDS.switchBranch + ` ${switchBranchName}`\n\n          GitController.runCommand(this.command)\n          break;\n\n        case \"6\":\n          GitController.runCommand(GIT_COMMANDS.showPendings)\n          break;\n\n        case \"7\":\n          const message = await asks.askLabel(\"commit message\")\n          GitController.runCommand(GIT_COMMANDS.addAll)\n          this.command = `${GIT_COMMANDS.commit} \"${message}\"`\n\n          GitController.runCommand(this.command)\n          break;\n\n        case \"8\":\n          GitController.runCommand(GIT_COMMANDS.commitHistory)\n          break;\n\n        case \"9\":\n          const deleteBranchName = await asks.askLabel(\"branch name to delete\")\n          this.command = GIT_COMMANDS.deleteBranch + ` ${deleteBranchName}`\n\n          GitController.runCommand(this.command)\n          break;\n\n        case \"10\":\n          const pullBranchName = await asks.askLabel(\"branch name to pull\")\n          this.command = GIT_COMMANDS.pull + ` ${pullBranchName}`\n\n          GitController.runCommand(this.command)\n          break;\n\n        case \"11\":\n          const pushBranchName = await asks.askLabel(\"branch name to push\")\n          this.command = GIT_COMMANDS.push + ` ${pushBranchName}`\n\n          GitController.runCommand(this.command)\n          break;\n\n        default:\n          break;\n      }\n\n    } while (option !== \"12\") \n\n    asks.close()\n  }\n}\n\nconst controller = new Controller()\ncontroller.startProgram() */\n\n"
  },
  {
    "path": "Roadmap/43 - GIT GITHUB CLI/kotlin/blackriper.kt",
    "content": "import org.eclipse.jgit.api.Git\r\nimport org.eclipse.jgit.api.RemoteAddCommand\r\nimport org.eclipse.jgit.lib.Repository\r\nimport org.eclipse.jgit.storage.file.FileRepositoryBuilder\r\nimport org.eclipse.jgit.transport.RefSpec\r\nimport org.eclipse.jgit.transport.URIish\r\nimport org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider\r\nimport java.io.File\r\nimport kotlin.io.path.Path\r\n\r\n/*\r\npara no depender del cliente del http client y tener mejor modularizacion\r\nusaremos la siguiente libreria:\r\n\r\n  -Git : https://git-scm.com/book/es/v2/Ap%C3%A9ndice-B:-Integrando-Git-en-tus-Aplicaciones-JGit\r\n*/\r\n\r\n\r\ndata class GithubAuth(val  username: String, val  password: String)\r\n\r\n\r\n// acciones que se pueden realizar desde el repositorio remoto y con las diferentes operaciones con las branches\r\nenum class BranchOptions{\r\n    NEW,\r\n    CHANGE,\r\n    DELETE\r\n}\r\nenum class GitAction{\r\n    PULL,\r\n    PUSH\r\n}\r\n\r\n// definir funcionamiento de la aplicacion\r\ninterface CliRepository{\r\n    fun workDirectory(src: String)\r\n    fun actionBranch(nameBranch: String, option:BranchOptions)\r\n    fun gitStatus()\r\n    fun createCommit(message : String)\r\n    fun addingRemoteRepo(url: String)\r\n    fun actionRemote(action:GitAction,remoteBranchName: String,user:GithubAuth)\r\n    fun existRemoteRepository(): Boolean\r\n}\r\n\r\n// implementar logica con jgit y kotlin\r\n\r\nclass GitRespository:CliRepository{\r\n\r\n    private lateinit var git: Git\r\n    private lateinit var uriRemote: String\r\n\r\n\r\n    override fun workDirectory(src: String) {\r\n       val aboslutePath= Path(src)\r\n       val result= runCatching { File(\"${aboslutePath.toAbsolutePath()}\") }\r\n       if (result.isFailure) println(\"directory not found ${result.exceptionOrNull()}\")\r\n       if (result.isSuccess){\r\n           git= Git.init().apply { setDirectory(result.getOrNull())}.call()\r\n           println(\"created a new repository at ${git.repository.directory}\")\r\n       }\r\n     }\r\n\r\n    override fun actionBranch(nameBranch: String,option: BranchOptions) {\r\n\r\n     val result= runCatching {\r\n         when (option) {\r\n             BranchOptions.NEW -> git.branchCreate().apply {\r\n                 setName(nameBranch)\r\n             }.call()\r\n\r\n             BranchOptions.CHANGE -> git.checkout().apply {\r\n                 setName(nameBranch)\r\n             }.call()\r\n\r\n             BranchOptions.DELETE -> git.branchDelete().apply {\r\n                 setBranchNames(nameBranch)\r\n                 setForce(true)\r\n             }.call()\r\n         }\r\n     }\r\n\r\n       if (result.isSuccess)  println(\"the ${nameBranch} executed operation ${option.name}\")\r\n       if (result.isFailure)  println(\"branch operation error ${result.exceptionOrNull()}\")\r\n    }\r\n\r\n    override fun gitStatus() {\r\n        var status=\"\"\r\n        git.status().call().run {\r\n            status=\"\"\"\r\n                Git Status  branch ${git.repository.branch}\r\n                Added: ${this.added}\r\n                Changed: ${this.changed}\r\n                Conflicting: ${this.conflicting}\r\n                Missing:   ${this.missing}\r\n                Modified:  ${this.modified}\r\n                Removed:   ${this.removed}\r\n                Untracked:   ${this.untracked}\r\n                UntrackedFolders:  ${this.untrackedFolders}\r\n            \"\"\".trimIndent()\r\n            println(status)\r\n        }\r\n    }\r\n\r\n    override fun createCommit(message: String) {\r\n       git.run {\r\n           val result= runCatching {\r\n               add().apply { addFilepattern(\".\") }.call()\r\n               commit().apply { setMessage(message) }.call()\r\n           }\r\n\r\n           if (result.isSuccess) println(\"commit added sucessfully\")\r\n           if (result.isFailure) println(\"error to create commit ${result.exceptionOrNull()}\")\r\n       }\r\n\r\n    }\r\n\r\n    override fun addingRemoteRepo(url: String) {\r\n      val result= runCatching {\r\n          git.remoteAdd().apply {\r\n              setName(\"origin\")\r\n              setUri(URIish(url))\r\n          }.call()\r\n      }\r\n       if (result.isSuccess) {\r\n           println(\"remote repo ${url} added sucessfully\")\r\n           uriRemote=url\r\n       }\r\n        if (result.isFailure) println(\"error to adding remote repository ${result.exceptionOrNull()}\")\r\n    }\r\n\r\n    override fun actionRemote(action: GitAction,remoteBranchName: String,user:GithubAuth) {\r\n\r\n        val result= runCatching {\r\n            when (action) {\r\n                GitAction.PULL -> git.pull().apply {\r\n                    setRemoteBranchName(remoteBranchName)\r\n                    setRebase(true)\r\n                }.call()\r\n\r\n                GitAction.PUSH -> git.push().apply {\r\n                    setCredentialsProvider(UsernamePasswordCredentialsProvider(user.username,user.password))\r\n                    setRefSpecs(RefSpec(remoteBranchName))\r\n                    setForce(true)\r\n                }.call()\r\n            }\r\n        }\r\n        if (result.isSuccess) println(\"operation ${action.name}  execute sucessfully\")\r\n        if (result.isFailure) println(\"error to execute ${action.name} ${result.exceptionOrNull()}\")\r\n    }\r\n\r\n    override fun existRemoteRepository(): Boolean = git.remoteList().call().isNotEmpty()\r\n\r\n}\r\n\r\nclass CliApp(private  val repository: CliRepository){\r\n   private lateinit var userGithub:GithubAuth\r\n\r\n   fun showMenuOptions(){\r\n       var option=0\r\n       while (option!=6){\r\n           println(\"KGit App\")\r\n           println(\"\"\"\r\n               1.- Create new Repository\r\n               2.- Create Commit\r\n               3.- Repo Status\r\n               4.- Actions Branch\r\n               5.- Actions Remote\r\n               6.- Exit\r\n               \r\n           \"\"\".trimIndent())\r\n           option= readLine()?.toInt() ?:0\r\n           when(option){\r\n               1-> createRepository()\r\n               2-> createCommit()\r\n               3-> repository.gitStatus()\r\n               4-> operationsBranch()\r\n               5-> operationsRemote()\r\n               6-> break\r\n\r\n           }\r\n\r\n       }\r\n   }\r\n\r\n    private fun createRepository(){\r\n        println(\"introduce path  where the project is located:  \")\r\n        val src= readLine().toString()\r\n        repository.workDirectory(src)\r\n    }\r\n\r\n    private fun operationsBranch(){\r\n        println(\"Select operation branch to execute 1.-New, 2.-Change , 3.-Delete\")\r\n        var action= readLine()?.toInt() ?:0\r\n        println(\"name the branch to ${if (action==1) \"New\" else if (action==2) \"Change\" else \"Delete\"} ?\")\r\n        var nameBranch= readLine()?:\"\"\r\n        val actionBranch= when(action){\r\n            1-> BranchOptions.NEW\r\n            2->BranchOptions.CHANGE\r\n            3->BranchOptions.DELETE\r\n            else -> BranchOptions.NEW\r\n        }\r\n        repository.actionBranch(nameBranch,actionBranch)\r\n    }\r\n\r\n    private fun operationsRemote(){\r\n        if (repository.existRemoteRepository().not()){\r\n            println(\"There is no remote repository copy the url of one\")\r\n            val remoteUrl= readLine().toString()\r\n            repository.addingRemoteRepo(remoteUrl)\r\n\r\n        }\r\n        println(\"selected operation remote to execute 1.-Pull , 2.-Push\")\r\n        val action=readLine()?.toInt()?:0\r\n\r\n        println(\"name the remote branch to work \")\r\n        var remoteBranch= readLine()?:\"\"\r\n\r\n        println(\"username to use in github\")\r\n        val name=readLine()?:\"\"\r\n\r\n        println(\"generate github token  and paste this \")\r\n        val password=readLine()?:\"\"\r\n\r\n        userGithub=GithubAuth(username = name,password=password)\r\n\r\n        val actionRemote= when(action){\r\n            1 -> GitAction.PULL\r\n            2 -> GitAction.PUSH\r\n            else -> GitAction.PUSH\r\n        }\r\n        repository.actionRemote(actionRemote,remoteBranch,userGithub)\r\n\r\n    }\r\n\r\n\r\n    private fun createCommit(){\r\n        println(\"Adding message commit \")\r\n        val message= readLine()?:\"first commit\".let { if (it.isEmpty()) \"first commit\" else it }\r\n        repository.createCommit(message)\r\n    }\r\n}\r\n\r\n\r\n\r\n\r\nfun main() {\r\n    val repoGit =GitRespository()\r\n    val appCli= CliApp(repoGit)\r\n    appCli.showMenuOptions()\r\n}"
  },
  {
    "path": "Roadmap/43 - GIT GITHUB CLI/php/miguelex.php",
    "content": "<?php\n\nclass GitHubCLI {\n    private $workingDirectory;\n\n    public function setWorkingDirectory($dir) {\n        if (is_dir($dir)) {\n            $this->workingDirectory = realpath($dir);\n            echo \"Directorio de trabajo establecido en: \" . $this->workingDirectory . PHP_EOL;\n        } else {\n            echo \"Error: El directorio no existe.\" . PHP_EOL;\n        }\n    }\n\n    public function createRepository($name) {\n        if (empty($this->workingDirectory)) {\n            echo \"Error: Debe establecer un directorio de trabajo primero.\" . PHP_EOL;\n            return;\n        }\n        exec(\"cd $this->workingDirectory && git init $name\", $output, $return_var);\n        if ($return_var === 0) {\n            echo \"Repositorio '$name' creado.\" . PHP_EOL;\n        } else {\n            echo \"Error al crear el repositorio.\" . PHP_EOL;\n        }\n    }\n\n    public function createBranch($branchName) {\n        exec(\"cd $this->workingDirectory && git checkout -b $branchName\", $output, $return_var);\n        if ($return_var === 0) {\n            echo \"Rama '$branchName' creada.\" . PHP_EOL;\n        } else {\n            echo \"Error al crear la rama.\" . PHP_EOL;\n        }\n    }\n\n    public function changeBranch($branchName) {\n        exec(\"cd $this->workingDirectory && git checkout $branchName\", $output, $return_var);\n        if ($return_var === 0) {\n            echo \"Cambiado a la rama '$branchName'.\" . PHP_EOL;\n        } else {\n            echo \"Error al cambiar de rama.\" . PHP_EOL;\n        }\n    }\n\n    public function showPendingCommits() {\n        exec(\"cd $this->workingDirectory && git status\", $output);\n        echo implode(PHP_EOL, $output);\n    }\n\n    public function commitChanges($message) {\n        exec(\"cd $this->workingDirectory && git add . && git commit -m \\\"$message\\\"\", $output, $return_var);\n        if ($return_var === 0) {\n            echo \"Cambios comprometidos con el mensaje: \\\"$message\\\".\" . PHP_EOL;\n        } else {\n            echo \"Error al hacer commit.\" . PHP_EOL;\n        }\n    }\n\n    public function showCommitHistory() {\n        exec(\"cd $this->workingDirectory && git log\", $output);\n        echo implode(PHP_EOL, $output);\n    }\n\n    public function deleteBranch($branchName) {\n        exec(\"cd $this->workingDirectory && git branch -d $branchName\", $output, $return_var);\n        if ($return_var === 0) {\n            echo \"Rama '$branchName' eliminada.\" . PHP_EOL;\n        } else {\n            echo \"Error al eliminar la rama.\" . PHP_EOL;\n        }\n    }\n\n    public function setRemoteRepository($url) {\n        exec(\"cd $this->workingDirectory && git remote add origin $url\", $output, $return_var);\n        if ($return_var === 0) {\n            echo \"Repositorio remoto establecido en: $url.\" . PHP_EOL;\n        } else {\n            echo \"Error al establecer el repositorio remoto.\" . PHP_EOL;\n        }\n    }\n\n    public function pull() {\n        exec(\"cd $this->workingDirectory && git pull\", $output, $return_var);\n        if ($return_var === 0) {\n            echo \"Pull realizado correctamente.\" . PHP_EOL;\n        } else {\n            echo \"Error al realizar pull.\" . PHP_EOL;\n        }\n    }\n\n    public function push() {\n        exec(\"cd $this->workingDirectory && git push origin HEAD\", $output, $return_var);\n        if ($return_var === 0) {\n            echo \"Push realizado correctamente.\" . PHP_EOL;\n        } else {\n            echo \"Error al realizar push.\" . PHP_EOL;\n        }\n    }\n\n    public function run() {\n        while (true) {\n            echo PHP_EOL . \"Selecciona una opción:\" . PHP_EOL;\n            echo \"1. Establecer el directorio de trabajo\" . PHP_EOL;\n            echo \"2. Crear un nuevo repositorio\" . PHP_EOL;\n            echo \"3. Crear una nueva rama\" . PHP_EOL;\n            echo \"4. Cambiar de rama\" . PHP_EOL;\n            echo \"5. Mostrar ficheros pendientes de hacer commit\" . PHP_EOL;\n            echo \"6. Hacer commit\" . PHP_EOL;\n            echo \"7. Mostrar el historial de commits\" . PHP_EOL;\n            echo \"8. Eliminar rama\" . PHP_EOL;\n            echo \"9. Establecer repositorio remoto\" . PHP_EOL;\n            echo \"10. Hacer pull\" . PHP_EOL;\n            echo \"11. Hacer push\" . PHP_EOL;\n            echo \"12. Salir\" . PHP_EOL;\n\n            $option = (int)readline(\"Opción: \");\n\n            switch ($option) {\n                case 1:\n                    $dir = readline(\"Introduce el directorio de trabajo: \");\n                    $this->setWorkingDirectory($dir);\n                    break;\n                case 2:\n                    $name = readline(\"Introduce el nombre del repositorio: \");\n                    $this->createRepository($name);\n                    break;\n                case 3:\n                    $branchName = readline(\"Introduce el nombre de la nueva rama: \");\n                    $this->createBranch($branchName);\n                    break;\n                case 4:\n                    $branchName = readline(\"Introduce el nombre de la rama a la que deseas cambiar: \");\n                    $this->changeBranch($branchName);\n                    break;\n                case 5:\n                    $this->showPendingCommits();\n                    break;\n                case 6:\n                    $message = readline(\"Introduce el mensaje del commit: \");\n                    $this->commitChanges($message);\n                    break;\n                case 7:\n                    $this->showCommitHistory();\n                    break;\n                case 8:\n                    $branchName = readline(\"Introduce el nombre de la rama a eliminar: \");\n                    $this->deleteBranch($branchName);\n                    break;\n                case 9:\n                    $url = readline(\"Introduce la URL del repositorio remoto: \");\n                    $this->setRemoteRepository($url);\n                    break;\n                case 10:\n                    $this->pull();\n                    break;\n                case 11:\n                    $this->push();\n                    break;\n                case 12:\n                    echo \"Saliendo...\" . PHP_EOL;\n                    exit;\n                default:\n                    echo \"Opción no válida.\" . PHP_EOL;\n            }\n        }\n    }\n}\n\n$cli = new GitHubCLI();\n$cli->run();\n"
  },
  {
    "path": "Roadmap/43 - GIT GITHUB CLI/python/EmmanuelMMontesinos.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * ¡Me voy de viaje al GitHub Universe 2024 de San Francisco!\n *\n * Desarrolla un CLI (Command Line Interface) que permita \n * interactuar con Git y GitHub de manera real desde terminal.\n * \n * El programa debe permitir las siguientes opciones:\n * 1. Establecer el directorio de trabajo\n * 2. Crear un nuevo repositorio\n * 3. Crear una nueva rama\n * 4. Cambiar de rama\n * 5. Mostrar ficheros pendientes de hacer commit\n * 6. Hacer commit (junto con un add de todos los ficheros)\n * 7. Mostrar el historial de commits\n * 8. Eliminar rama\n * 9. Establecer repositorio remoto\n * 10. Hacer pull\n * 11. Hacer push\n * 12. Salir\n *\n * Puedes intentar controlar los diferentes errores.\n */\n\"\"\"\nimport os\n\nclass GitCLI:\n    def __init__(self):\n        self.directorio = None\n        self.remoto = None\n\n    def mostrar_info(self):\n        print(f\"Directorio de trabajo: {self.directorio}\")\n        print(f\"Repositorio remoto: {self.remoto}\")\n    def asignar_directorio(self):\n        self.directorio = input(\"Introduce el directorio de trabajo: \")\n        os.chdir(self.directorio)\n\n    def nuevo_repositorio(self):\n        os.system(\"git init\")\n        os.system(\"git branch -m main\")\n\n    def crear_rama(self):\n        nombre_rama = input(\"Introduce el nombre de la rama para crear: \")\n        os.system(f\"git branch {nombre_rama}\")\n\n    def cambiar_rama(self):\n        nombre_rama = input(\"Introduce el nombre de la rama a cambiar: \")\n        os.system(f\"git checkout {nombre_rama}\")\n\n    def mostrar_ficheros_pendientes(self):\n        os.system(\"git status -s\")\n\n    def hacer_commit(self):\n        os.system(\"git add .\")\n        mensaje = input(\"Introduce el mensaje del commit: \")\n        os.system(f\"git commit -m {mensaje}\")\n\n    def historial_commits(self):\n        os.system(\"git log\")\n\n    def eliminar_rama(self):\n        nombre_rama = input(\"Introduce el nombre de la rama a eliminar: \")\n        os.system(f\"git branch -d {nombre_rama}\")\n\n    def establecer_remoto(self):\n        url = input(\"Introduce la URL del repositorio remoto: \")\n        os.system(f\"git remote add origin {url}\")\n        self.remoto = url\n        os.system(\"git push -u origin main\")\n\n    def hacer_pull(self):\n        os.system(\"git pull origin main\")\n\n    def hacer_push(self):\n        os.system(\"git push\")\n\n    def bucle(self):\n        while True:\n            self.mostrar_info()\n            print(\"\\nSelecciona una opción: \")\n            print(\"1. Establecer el directorio de trabajo\")\n            print(\"2. Crear un nuevo repositorio\")\n            print(\"3. Crear una nueva rama\")\n            print(\"4. Cambiar de rama\")\n            print(\"5. Mostrar ficheros pendientes de hacer commit\")\n            print(\"6. Hacer commit\")\n            print(\"7. Mostrar el historial de commits\")\n            print(\"8. Eliminar rama\")\n            print(\"9. Establecer repositorio remoto\")\n            print(\"10. Hacer pull\")\n            print(\"11. Hacer push\")\n            print(\"12. Salir\")\n\n            option = input(\"Opción: \")\n            \n            match option:\n                case \"1\":\n                    self.asignar_directorio()\n                case \"2\":\n                    self.nuevo_repositorio()\n                case \"3\":\n                    self.crear_rama()\n                case \"4\":\n                    self.cambiar_rama()\n                case \"5\":\n                    self.mostrar_ficheros_pendientes()\n                case \"6\":\n                    self.hacer_commit()\n                case \"7\":\n                    self.historial_commits()\n                case \"8\":\n                    self.eliminar_rama()\n                case \"9\":\n                    self.establecer_remoto()\n                case \"10\":\n                    self.hacer_pull()    \n                case \"11\":\n                    self.hacer_push()\n                case \"12\":\n                    break\n                case _:\n                    print(\"Opcion incorrecta\")\n\n# Prueba\n\nif __name__ == \"__main__\":\n    cli = GitCLI()\n    cli.bucle()"
  },
  {
    "path": "Roadmap/43 - GIT GITHUB CLI/python/Gordo-Master.py",
    "content": "# 43 - Git Github CLI\nimport os\nimport subprocess\n\ndef show_return_menu():\n    input(\"Enter para volver al menu...\")\n\ndef run_command(command: str):\n\n    try:\n        result = subprocess.run(\n            [\"pwsh\",\"-Command\",command],\n            check=True,\n            text=True,\n            capture_output=True\n        )\n        print(result.stdout.strip())\n    except subprocess.CalledProcessError as e:\n        print(f\"Error: {e.stderr.strip()}\")\n\ndef show_menu():\n    os.system(\"cls\")\n    print(\"\\nDirectorio actual de trabajo:\")\n    run_command(\"(Get-Location).Path\")\n    print(\"\\n=== [+] Bienvenido al CLI de GIT/GITHUB by Gordo-Master [+] ===\")\n    print(\"Seleccione un opción: \")\n    text = \"\"\"1. Establecer el directorio de trabajo\n2. Crear un nuevo repositorio\n3. Crear una nueva rama\n4. Cambiar de rama\n5. Mostrar ficheros pendientes de hacer commit\n6. Hacer commit (junto con un add de todos los ficheros)\n7. Mostrar el historial de commits\n8. Eliminar rama\n9. Establecer repositorio remoto\n10. Hacer pull\n11. Hacer push\n12. Salir\"\"\"\n    print(text)\n    option = input(\"Selecciona una opcion (1 al 12): \")\n    try:\n        option = int(option)\n    except ValueError:\n        print(\"Valor incorrecto. \\nSelecciona un número entero entre 1 - 12\")\n        show_return_menu()\n        return None\n    else:\n        if option <= 0 or option > 12:\n            print(\"Valor fuera de rango. \\nSelecciona un número entero entre 1 - 12\")\n            show_return_menu()\n            return None\n        return option\n\ndef run_option(option):\n    match option:\n        case 1:\n            set_working_directory()\n            show_return_menu()\n            return True\n        case 2:\n            new_repository()\n            show_return_menu()\n            return True\n        case 3:\n            new_branch()\n            show_return_menu()\n            return True\n        case 4:\n            switch_branch()\n            show_return_menu()\n            return True\n        case 5:\n            show_branch_status()\n            show_return_menu()\n            return True\n        case 6:\n            make_commit()\n            show_return_menu()\n            return True\n        case 7:\n            show_history()\n            show_return_menu()\n            return True\n        case 8:\n            del_branch()\n            show_return_menu()\n            return True\n        case 9:\n            set_remote_repository()\n            show_return_menu()\n            return True\n        case 10:\n            make_pull()\n            show_return_menu()\n            return True\n        case 11:\n            make_push()\n            show_return_menu()\n            return True\n        case 12:\n            print(\"[*] Saliendo de la aplicación...\")\n            return False\n        case _:\n            print(\"Valor incorrecto, ¿como llegaste a este lugar?\")\n            return True\n\ndef set_working_directory():\n\n    path = input(\"Introduce el directorio de trabajo: \")\n    if os.path.isdir(path):\n        os.chdir(path)\n        print(f\"Se a cambiado el directorio de trabajo: {path}\")\n    else:\n        print(f\"El directorio introducido no existe.\")\n        \ndef new_repository():\n    if os.path.isdir(\".git\"):\n        print(\"Ya existe un repositorio en la ubicación\")\n    else:\n        run_command(\"git init\")\n        run_command(\"git branch -M main\")\n        print(\"Repositorio iniciado\")\n\ndef new_branch():\n    branch_name = input(\"Ingrese el nombre de la nueva rama: \")\n    run_command(f\"git branch -c {branch_name}\")\n\ndef switch_branch():\n    branch_name = input(\"Cambiar a la rama: \")\n    run_command(f\"git switch {branch_name}\")\n\ndef show_branch_status():\n    run_command(\"git status\")\n\ndef make_commit(): # Hacer el add y el commit - hay que agregar el comentario\n    comment = input(\"Ingrese el comentario para el commit: \")\n    run_command(\"git add .\")\n    run_command(f\"git commit -m '{comment}'\")\n\ndef show_history():\n    run_command(\"git log --oneline\")\n\ndef del_branch():\n    branch_name = input(\"Ingrese el nombre de la rama que desea eliminar: \")\n    run_command(f\"git branch -d {branch_name}\")\n\ndef set_remote_repository():\n    url = input(\"Indique la URL del reposotorio remoto a establecer: \")\n    run_command(f\"git remote add origion {url}\")\n    run_command(f\"git push -u origin/{url}\")\n\ndef make_pull():\n    run_command(f\"git pull\")\n\ndef make_push():\n    run_command(f\"git push\")\n\n\ndef main():\n    while True:\n        while True:\n            option = show_menu()\n            if not option is None:\n                break\n        status = run_option(option)\n        if status is False:\n            break\n\nif __name__ == \"__main__\":\n    main()"
  },
  {
    "path": "Roadmap/43 - GIT GITHUB CLI/python/JesusWay69.py",
    "content": "import os, platform\nfrom datetime import datetime as DT\nfrom git import Repo\nfrom git import exc\n\nif platform.platform().startswith(\"macOS\"):\n    path = \"/Users/jesus/python3_project/GitProjectPython\"\n    os.system('clear')\nelif platform.platform().startswith(\"Linux\"):\n    path = \"/Users/jesus/Documents/python3_project/GitProjectPython\"\n    os.system('clear')\nelif platform.platform().startswith(\"Windows\"):\n    path = r\"C:\\Users\\jesus\\Documents\\Python3project\\GitProjectPython\\\\\"\n    os.system('cls')\n\n\"\"\"* EJERCICIO:\n * Desarrolla un CLI (Command Line Interface) que permita\n * interactuar con Git y GitHub de manera real desde terminal.\n * El programa debe permitir las siguientes opciones:\n * 1. Establecer el directorio de trabajo\n * 2. Crear un nuevo repositorio\n * 3. Crear una nueva rama\n * 4. Cambiar de rama\n * 5. Mostrar ficheros pendientes de hacer commit\n * 6. Hacer commit (junto con un add de todos los ficheros)\n * 7. Mostrar el historial de commits\n * 8. Eliminar rama\n * 9. Establecer repositorio remoto\n * 10. Hacer pull\n * 11. Hacer push\n * 12. Salir\"\"\"\n\nrepo_url = 'https://github.com/Jesusway69/GitProjectPython'\n\ndef git_init(local_path:str)->object:\n    if os.path.exists(local_path):\n        repo = Repo.init(local_path)\n    else:\n        print(\"la ruta especificada no existe en este ordenador\")\n        return\n    return repo\n\ndef git_clone(github_url:str, local_path:str)->object:\n    if not os.path.exists(local_path):\n        repo = Repo.clone_from(github_url, local_path)\n    else:\n        repo = Repo(path)\n    return repo\n\ndef git_branch(repo:object):\n    print(\"Ramas actuales en este repositorio:\")\n    print(repo.git.branch())\n    branch_name = input(\"Escriba el nombre de la nueva rama a crear: \")\n    try:\n        repo.git.branch(branch_name)\n        print(\"Nueva rama creada: \", branch_name)\n    except exc.GitCommandError as ex:\n        print(f\"\\n{ex} la rama {branch_name} ya existe\")\n    \ndef git_checkout(repo:object):\n    print(\"Ramas actuales en este repositorio:\")\n    print(repo.git.branch())\n    try:  \n        branch_name = input(\"Escriba el nombre de la rama a la que quiere cambiar (con asterisco la actual): \")\n        repo.git.checkout(branch_name)\n    except exc.GitCommandError as ex:\n        print(f\"\\n{ex} la rama {branch_name} no existe\")\n\ndef git_add(repo:object):\n    try:\n        repo.git.add('.')\n        print(\"\\nCambios añadidos a stage correctamente\")\n    except exc.GitError as ex:\n        print(ex)\n\ndef git_commit(repo:object):\n    message = input(\"Introduzca el mensaje del commit: \")\n    current_date = '{}{}{}'.format(DT.now().year, DT.now().month, DT.now().day)\n    try:\n        repo.index.commit(current_date + \" \" + message)\n        print(f\"\\nCommit realizado correctamente con el mensaje '{message}' \")\n    except exc.GitError as ex:\n        print(ex)\n\ndef modify_repository(local_path:str):\n    current_datetime = '{}/{}/{} a las {}:{}'.format(DT.now().day, DT.now().month, DT.now().year, DT.now().hour, DT.now().minute)\n    with open(f'{local_path}/file1.txt', 'a') as f:\n        f.writelines(f'\\nañadimos otra línea el {current_datetime}')\n\ndef git_status(repo:object):\n    print(\"\\nEstado actual del repositorio:\")\n    print (repo.git.status())\n\ndef git_log(repo:object):\n    print(\"\\nCommits realizados:\")\n    print(repo.git.log())\n\ndef git_remote_add(repo:object):\n    try:\n        remote_branch = input(\"Introduzca el nombre de la rama principal remota (origin por defecto pulsando enter): \")\n        if len(remote_branch) == 0: remote_branch = 'origin'\n        repo_url = input(\"Introduzca una url válida para crear repositorio remoto en github: \")\n        repo.create_remote(remote_branch, repo_url)\n    except exc.InvalidGitRepositoryError as ex:\n        print(f\"\\n{ex} la url {repo_url} no existe o la rama remota ya existe\")\n\ndef git_pull(repo:object):\n    try:\n        repo.git.pull('origin', 'main')\n        print(\"\\nRepositorio remoto origin fusionado correctamente en main\")\n    except exc.GitError as ex:\n        print(ex)\n\ndef git_push(repo:object):\n    try:\n        repo.git.push(\"--set-upstream\", 'origin', 'main')\n        print(\"\\nRepositorio remoto origin actualizado correctamente\")\n    except exc.GitError as ex:\n        print(ex)\n\ndef delete_branch(repo:object):\n    print(\"Ramas actuales en este repositorio:\")\n    print(repo.git.branch())\n    branch_name = input(\"Escriba el nombre de la rama a eliminar: \")\n    try:\n        repo.git.branch(\"-d\", branch_name)\n        print(f\"Rama {branch_name} eliminada con éxito \" )\n    except exc.InvalidGitRepositoryError as ex:\n        print(f\"\\n{ex} la rama {branch_name} no existe\")\n    except exc.GitError as ex:\n        print(f\"La rama {branch_name} no está fusionada con HEAD\")\n\nmy_repo = git_init(path)\n\n\nwhile True:\n    print(\"\"\"\n    \n    1- Crear repositorio local (init)\n    2- Clonar repositorio desde Github (clone)\n    3- Crear nueva rama (branch)\n    4- Cambiar de rama (checkout)\n    5- Mostrar estado de repositorio (status)\n    6- Añadir todos los cambios a stage (add .)\n    7- Hacer commit del repositorio (commit)\n    8- Mostrar historial de commits (log)\n    9- Establecer repositorio remoto (remote)\n    10- Actualizar fichero txt (branch -d)\n    11- Actualizar repositorio local desde remoto (pull)\n    12- Subir cambios locales a remoto (push)\n    13- Eliminar rama\n    14- Salir\"\"\")\n\n    option = input(\"Selecciona una opción del 1 al 12: \")\n\n    match option:\n        case \"1\":\n            git_init(path)\n        case \"2\":\n            git_clone(repo_url, path)\n        case \"3\":\n            git_branch(my_repo)\n        case \"4\":\n            git_checkout(my_repo)\n        case \"5\":\n            git_status(my_repo)\n        case \"6\":\n            git_add(my_repo)\n        case \"7\":\n            git_commit(my_repo)\n        case \"8\":\n            git_log(my_repo)\n        case \"9\":\n            git_remote_add(my_repo)\n        case \"10\":\n            modify_repository(path)\n        case \"11\":\n            git_pull(my_repo)\n        case \"12\":\n            git_push(my_repo)\n        case \"13\":\n            delete_branch(my_repo)\n        case \"14\":\n            print(\"Fin del programa\")\n            break\n        case _:\n            print(\"Opción no válida.\")"
  },
  {
    "path": "Roadmap/43 - GIT GITHUB CLI/python/Nicojsuarez2.py",
    "content": "# #43 GIT GITHUB CLI\n> #### Dificultad: Difícil | Publicación: 21/10/24 | Corrección: 04/11/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * ¡Me voy de viaje al GitHub Universe 2024 de San Francisco!\n *\n * Desarrolla un CLI (Command Line Interface) que permita \n * interactuar con Git y GitHub de manera real desde terminal.\n * \n * El programa debe permitir las siguientes opciones:\n * 1. Establecer el directorio de trabajo\n * 2. Crear un nuevo repositorio\n * 3. Crear una nueva rama\n * 4. Cambiar de rama\n * 5. Mostrar ficheros pendientes de hacer commit\n * 6. Hacer commit (junto con un add de todos los ficheros)\n * 7. Mostrar el historial de commits\n * 8. Eliminar rama\n * 9. Establecer repositorio remoto\n * 10. Hacer pull\n * 11. Hacer push\n * 12. Salir\n *\n * Puedes intentar controlar los diferentes errores.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/43 - GIT GITHUB CLI/python/cdryampi.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * ¡Me voy de viaje al GitHub Universe 2024 de San Francisco!\n#  *\n#  * Desarrolla un CLI (Command Line Interface) que permita \n#  * interactuar con Git y GitHub de manera real desde terminal.\n#  * \n#  * El programa debe permitir las siguientes opciones:\n#  * 1. Establecer el directorio de trabajo\n#  * 2. Crear un nuevo repositorio\n#  * 3. Crear una nueva rama\n#  * 4. Cambiar de rama\n#  * 5. Mostrar ficheros pendientes de hacer commit\n#  * 6. Hacer commit (junto con un add de todos los ficheros)\n#  * 7. Mostrar el historial de commits\n#  * 8. Eliminar rama\n#  * 9. Establecer repositorio remoto\n#  * 10. Hacer pull\n#  * 11. Hacer push\n#  * 12. Salir\n#  *\n#  * Puedes intentar controlar los diferentes errores.\n#  */\n\nimport os\nimport subprocess\nimport http.client\nfrom urllib.parse import urlparse\n\n\nclass Directory:\n    __PATH_DIRECTORY = None\n\n    def __init__(self) -> None:\n        self.__PATH_DIRECTORY = os.getcwd()\n\n    def select_folder(self) -> None:\n        \"\"\"Selecciona una ruta válida\"\"\"\n        while self.__PATH_DIRECTORY is None:\n            route = input(\"Introduce una ruta o presiona 0 para usar la carpeta actual:\\n\")\n            self.check_folder(route)\n\n    def check_folder(self, route) -> bool:\n        \"\"\"Establece una carpeta por defecto si no se ha seleccionado ninguna.\"\"\"\n        if route == '0':\n            self.__PATH_DIRECTORY = os.getcwd()\n            print(\"Hemos asignado la carpeta por defecto.\")\n            return True\n        elif os.path.isdir(route):\n            self.__PATH_DIRECTORY = route\n            print(f\"Nueva ruta establecida: {self.__PATH_DIRECTORY}\")\n            return True\n        else:\n            print(\"La ruta no es válida.\")\n            return False\n\n    def clear_path(self) -> None:\n        self.__PATH_DIRECTORY = None\n\n    def get_path(self) -> str:\n        return self.__PATH_DIRECTORY if self.__PATH_DIRECTORY else \"No se ha establecido una ruta.\"\n\n\nclass CLIControl:\n    def __init__(self):\n        self.__DIRECTORY = Directory()\n        self.__SUBPROCESS = subprocess\n        self.__CURRENT_BRANCH = None\n\n    def is_git_initialized(self) -> bool:\n        \"\"\"Verificar si .git existe en el directorio actual\"\"\"\n        directory_path = self.__DIRECTORY.get_path()\n        \n        # Asegurarse de que la ruta esté configurada\n        if not directory_path or directory_path == \"Aún no se ha establecido una ruta.\":\n            print(\"No se ha establecido un directorio de trabajo válido.\")\n            return False\n        \n        git_path = os.path.join(directory_path, '.git')\n        \n        # Debug: Imprimir la ruta donde se está buscando la carpeta .git\n        print(f\"Verificando si existe .git en la ruta: {git_path}\")\n        \n        if os.path.isdir(git_path):\n            return True\n        else:\n            print(\"Git no está inicializado en este directorio. Utiliza un directorio con un repositorio Git.\")\n            return False\n\n\n    def create_repository(self):\n        \"\"\"Crear un repositorio Git en el directorio actual\"\"\"\n        if not self.is_git_initialized():\n            resultado = self.__SUBPROCESS.run(\n                [\"git\", \"init\"],\n                capture_output=True,\n                text=True,\n                cwd=self.__DIRECTORY.get_path()\n            )\n            print(resultado.stdout)\n        else:\n            print(\"Ya hay un repositorio Git en el directorio.\")\n\n    def create_branch(self, branch_name):\n        \"\"\"Crear una nueva rama\"\"\"\n        if self.is_git_initialized():\n            resultado = self.__SUBPROCESS.run(\n                [\"git\", \"branch\", branch_name],\n                capture_output=True,\n                text=True,\n                cwd=self.__DIRECTORY.get_path()\n            )\n                    # Verificar si la creación de la rama fue exitosa\n        if resultado.returncode == 0:\n            print(f\"La rama '{branch_name}' ha sido creada con éxito.\")\n        else:\n            print(\"Error al crear la rama:\")\n            print(resultado.stderr)\n\n    def select_folder_CLI(self):\n        \"\"\"Limpiar todo y volver a pedir carpeta\"\"\"\n        self.__DIRECTORY.clear_path()\n        self.__DIRECTORY.select_folder()\n        self.__CURRENT_BRANCH = None\n\n    def status(self):\n        \"\"\"Mostrar archivos pendientes de commit\"\"\"\n        if self.is_git_initialized():\n            resultado = self.__SUBPROCESS.run(\n                [\"git\", \"status\"],\n                capture_output=True,\n                text=True,\n                cwd=self.__DIRECTORY.get_path()\n            )\n            print(resultado.stdout)\n\n    def commit_git(self, msg='Commit desde CLI'):\n        \"\"\"Agregar y hacer commit de todos los cambios\"\"\"\n        if self.is_git_initialized():\n            self.__SUBPROCESS.run([\"git\", \"add\", \".\"], cwd=self.__DIRECTORY.get_path())\n            resultado = self.__SUBPROCESS.run(\n                [\"git\", \"commit\", \"-m\", msg],\n                capture_output=True,\n                text=True,\n                cwd=self.__DIRECTORY.get_path()\n            )\n            print(resultado.stdout)\n\n    def log(self):\n        \"\"\"Mostrar historial de commits\"\"\"\n        if self.is_git_initialized():\n            resultado = self.__SUBPROCESS.run(\n                [\"git\", \"log\", \"--oneline\"],\n                capture_output=True,\n                text=True,\n                cwd=self.__DIRECTORY.get_path()\n            )\n            print(resultado.stdout)\n\n    def delete_branch(self):\n        \"\"\"Eliminar la rama actual\"\"\"\n        if self.is_git_initialized():\n            # Por si acaso llamamos a la función para seleccionar rama para no eliminar la rama sin querer.\n            self.select_remote_or_local_branch()\n            if self.__CURRENT_BRANCH:\n                resultado = self.__SUBPROCESS.run(\n                    [\"git\", \"branch\", \"-d\", self.__CURRENT_BRANCH],\n                    capture_output=True,\n                    text=True,\n                    cwd=self.__DIRECTORY.get_path()\n                )\n                print(resultado.stdout)\n                self.__CURRENT_BRANCH = None\n            else:\n                print(\"Selecciona una rama primero.\")\n\n    def add_remote(self, url_remote):\n        \"\"\"Establecer un repositorio remoto\"\"\"\n        if self.is_git_initialized():\n            resultado = self.__SUBPROCESS.run(\n                [\"git\", \"remote\", \"add\", \"origin\", url_remote],\n                capture_output=True,\n                text=True,\n                cwd=self.__DIRECTORY.get_path()\n            )\n            print(resultado.stdout)\n\n    def select_remote_or_local_branch(self):\n        \"\"\"Función para seleccionar una rama local o remota\"\"\"\n        if self.is_git_initialized():\n            resultado = self.__SUBPROCESS.run(\n                [\"git\", \"branch\", \"-a\"],\n                capture_output=True,\n                text=True,\n                cwd=self.__DIRECTORY.get_path()\n            )\n            \n            # Obtiene la lista de ramas y elimina líneas en blanco\n            branches = [branch.strip() for branch in resultado.stdout.splitlines() if branch.strip()]\n            \n            # Muestra las opciones al usuario de forma numerada\n            print(\"Selecciona la rama que deseas utilizar:\")\n            for idx, branch in enumerate(branches, 1):\n                print(f\"{idx}. {branch}\")\n            \n            # Verifica la elección del usuario\n            while True:\n                try:\n                    choice = int(input(\"Introduce el número de la rama: \"))\n                    if 1 <= choice <= len(branches):\n                        selected_branch = branches[choice - 1].replace(\"*\", \"\").strip()\n                        self.__CURRENT_BRANCH = selected_branch\n                        print(f\"Has seleccionado la rama: {self.__CURRENT_BRANCH}\")\n                        break\n                    else:\n                        print(\"Número fuera de rango. Por favor, selecciona un número válido.\")\n                except ValueError:\n                    print(\"Entrada no válida. Por favor, introduce un número.\")\n\n    def check_url_github(self, url) -> bool:\n        \"\"\"Comprueba si la URL devuelve un estado 200 o un estado 301 usando http.client.\"\"\"\n        parsed_url = urlparse(url)\n        connection = http.client.HTTPConnection(parsed_url.netloc)\n        try:\n            connection.request(\"GET\", parsed_url.path or \"/\")\n            response = connection.getresponse()\n            \n            # Verificar el estado\n            if response.status == 200 or response.status == 301:\n                print(f\"Conexión exitosa a {url} (Estado 200).\")\n                return True\n            else:\n                print(f\"Error: estado {response.status} en {url}.\")\n                return False\n        except Exception as e:\n            print(f\"Hubo un problema con la solicitud: {e}\")\n            return False\n        finally:\n            connection.close()\n\n    def git_pull(self):\n        \"\"\"Hacer pull de la rama actual\"\"\"\n        if self.is_git_initialized():\n            resultado = self.__SUBPROCESS.run(\n                [\"git\", \"pull\"],\n                capture_output=True,\n                text=True,\n                cwd=self.__DIRECTORY.get_path()\n            )\n            print(resultado.stdout)\n\n    def git_push(self):\n        \"\"\"Hacer push de la rama actual\"\"\"\n        if self.is_git_initialized():\n            # Asegúrate de que haya una rama seleccionada\n            if self.__CURRENT_BRANCH:\n                print(f\"Intentando hacer push a la rama '{self.__CURRENT_BRANCH}' en el remoto 'origin'...\")\n                \n                # Comprueba si el remoto 'origin' está configurado\n                remote_check = self.__SUBPROCESS.run(\n                    [\"git\", \"remote\", \"-v\"],\n                    capture_output=True,\n                    text=True,\n                    cwd=self.__DIRECTORY.get_path()\n                )\n                if 'origin' not in remote_check.stdout:\n                    print(\"El remoto 'origin' no está configurado. Por favor, agrega un repositorio remoto.\")\n                    return\n                \n                # Realiza el push\n                resultado = self.__SUBPROCESS.run(\n                    [\"git\", \"push\", \"-u\", \"origin\", self.__CURRENT_BRANCH],\n                    capture_output=True,\n                    text=True,\n                    cwd=self.__DIRECTORY.get_path()\n                )\n                \n                # Verifica la salida y los errores\n                if resultado.returncode == 0:\n                    print(\"Push exitoso:\")\n                    print(resultado.stdout)\n                else:\n                    print(\"Error al hacer push:\")\n                    print(resultado.stderr)\n            else:\n                print(\"Selecciona una rama primero.\")\n\n\n    def menu(self):\n        \"\"\"Menú interactivo\"\"\"\n        while True:\n            print(\"\\nSelecciona una opción:\")\n            print(\"1. Establecer directorio de trabajo\")\n            print(\"2. Crear repositorio\")\n            print(\"3. Crear rama\")\n            print(\"4. Cambiar de rama\")\n            print(\"5. Mostrar ficheros pendientes de commit\")\n            print(\"6. Hacer commit\")\n            print(\"7. Mostrar historial de commits\")\n            print(\"8. Eliminar rama\")\n            print(\"9. Establecer repositorio remoto\")\n            print(\"10. Hacer pull\")\n            print(\"11. Hacer push\")\n            print(\"12. Salir\")\n\n            opcion = input(\"Opción: \")\n            match opcion:\n                case '1':\n                    self.select_folder_CLI()\n                case '2':\n                    self.create_repository()\n                case '3':\n                    branch_name = input(\"Nombre de la nueva rama: \")\n                    self.create_branch(branch_name)\n                case '4':\n                    self.select_remote_or_local_branch()\n                case '5':\n                    self.status()\n                case '6':\n                    msg = input(\"Mensaje de commit: \")\n                    self.commit_git(msg)\n                case '7':\n                    self.log()\n                case '8':\n                    self.delete_branch()\n                case '9':\n                    url = input(\"URL del repositorio remoto: \")\n                    if self.check_url_github(url):\n                        self.add_remote(url)\n                    else:\n                        print(\"URL no válida. No se ha establecido el remoto.\")\n                case '10':\n                    self.git_pull()\n                case '11':\n                    self.git_push()\n                case '12':\n                    print(\"Saliendo...\")\n                    break\n                case _:\n                    print(\"Opción no válida.\")\n\ndef main():\n    cli = CLIControl()\n    cli.menu()\n\nif __name__ == '__main__':\n    main()"
  },
  {
    "path": "Roadmap/43 - GIT GITHUB CLI/python/davidrguez98.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * ¡Me voy de viaje al GitHub Universe 2024 de San Francisco!\n *\n * Desarrolla un CLI (Command Line Interface) que permita \n * interactuar con Git y GitHub de manera real desde terminal.\n * \n * El programa debe permitir las siguientes opciones:\n * 1. Establecer el directorio de trabajo\n * 2. Crear un nuevo repositorio\n * 3. Crear una nueva rama\n * 4. Cambiar de rama\n * 5. Mostrar ficheros pendientes de hacer commit\n * 6. Hacer commit (junto con un add de todos los ficheros)\n * 7. Mostrar el historial de commits\n * 8. Eliminar rama\n * 9. Establecer repositorio remoto\n * 10. Hacer pull\n * 11. Hacer push\n * 12. Salir\n *\n * Puedes intentar controlar los diferentes errores.\n */ \"\"\"\n\n\n#EJERCICIO\n\nimport os\nimport subprocess\n\ndef run_command(command: str):\n\n    try:\n        result = subprocess.run(\n            command,\n            shell=True,\n            check=True,\n            text=True,\n            capture_output=True\n        )\n        print(result.stdout.strip())\n    except subprocess.CalledProcessError as e:\n        print(f\"Error: {e.stderr.strip()}\")\n\ndef set_working_directory():\n\n    path = input(\"Introduce el directorio completo de trabajo: \")\n    if os.path.isdir(path):\n        os.chdir(path)\n        print(f\"El directorio de trabajo ha cambiado a: {path}\")\n    else:\n        print(\"El directorio introducido no existe.\")\n\ndef create_repository():\n\n    if os.path.isdir(\".git\"):\n        print(\"Ya existe un repositorio en este directorio.\")\n    else:\n        run_command(\"git init\")\n        run_command(\"git branch -M main\")\n        print(\"Repositorio inicializado.\")\n\ndef create_branch():\n\n    branch_name = input(\"Nombre de la nueva rama: \")\n\n    run_command(f\"git branch {branch_name}\")\n    print(f\"La rama {branch_name} ha sido creada.\")\n\ndef switch_branch():\n\n    branch_name = input(\"Nombre de la nueva rama a la que quieres cambiar: \")\n\n    run_command(f\"git checkout {branch_name}\")\n\ndef show_pending_files():\n\n    run_command(\"git status -s\")\n\ndef make_commit():\n\n    message = input(\"Mensjae del commit: \")\n\n    run_command(\"git add .\")\n    run_command(f\"git commit -m \\\"{message}\\\"\")\n\ndef show_commit_history():\n\n    run_command(\"git log --oneline\")\n\ndef delete_branch():\n\n    branch_name = input(\"Nombre de la rama a eliminar: \")\n    run_command(f\"git branch -d {branch_name}\")\n\ndef set_remote_repository():\n\n    remote_url = input(\"url del repositorio remoto: \")\n    run_command(f\"git remote add origin {remote_url}\")\n    run_command(\"git push -u origin main\")\n\ndef make_pull():\n\n    run_command(\"git pull\")\n\ndef make_push():\n\n    run_command(\"git push\")\n\n\n\n\nwhile True:\n\n    print(\"\\nDirectorio actual de trabajo\")\n    run_command(\"cd\")\n\n    print(\"\\nGit y GitHub CLI - Opciones:\\n\")\n    print(\"1. Establecer el directorio de trabajo\")\n    print(\"2. Crear un nuevo repositorio\")\n    print(\"3. Crear una nueva rama\")\n    print(\"4. Cambiar de rama\")\n    print(\"5. Mostrar ficheros pendientes de hacer commit\")\n    print(\"6. Hacer commit (+ add)\")\n    print(\"7. Mostrar el historial de commits\")\n    print(\"8. Eliminar rama\")\n    print(\"9. Establecer repositorio remoto\")\n    print(\"10. Hacer pull\")\n    print(\"11. Hacer push\")\n    print(\"12. Salir\")\n\n    choice = input(\"\\nSelecciona una opción: \")\n\n    match choice:\n        case \"1\":\n            set_working_directory()\n        case \"2\":\n            create_repository()\n        case \"3\":\n            create_branch()\n        case \"4\":\n            switch_branch()\n        case \"5\":\n            show_pending_files()\n        case \"6\":\n            make_commit()\n        case \"7\":\n            show_commit_history()\n        case \"8\":\n            delete_branch()\n        case \"9\":\n            set_remote_repository()\n        case \"10\":\n            make_pull\n        case \"11\":\n            make_push()\n        case \"12\":\n            print(\"Saliendo del programa.\")\n            break\n        case _:\n            print(\"Opción no válida.\")\n"
  },
  {
    "path": "Roadmap/43 - GIT GITHUB CLI/python/duendeintemporal.py",
    "content": "#43 { Retos para Programadores } GIT GITHUB CLI \n\n# Bibliography reference:\n# I use GPT as a reference and sometimes to correct or generate proper comments.\n\n\"\"\"\n * EJERCICIO:\n * ¡Me voy de viaje al GitHub Universe 2024 de San Francisco!\n *\n * Desarrolla un CLI (Command Line Interface) que permita\n * interactuar con Git y GitHub de manera real desde terminal.\n *\n * El programa debe permitir las siguientes opciones:\n * 1. Establecer el directorio de trabajo\n * 2. Crear un nuevo repositorio\n * 3. Crear una nueva rama\n * 4. Cambiar de rama\n * 5. Mostrar ficheros pendientes de hacer commit\n * 6. Hacer commit (junto con un add de todos los ficheros)\n * 7. Mostrar el historial de commits\n * 8. Eliminar rama\n * 9. Establecer repositorio remoto\n * 10. Hacer pull\n * 11. Hacer push\n * 12. Salir\n *\n * Puedes intentar controlar los diferentes errores.\n\n\"\"\"\n\nimport os\nimport subprocess\n\n# Set up logging\nlog = print\n\ncurrent_directory = os.getcwd()\ncurrent_branch = 'main'\nremote_repository = ''\n\ndef is_git_repository():\n    return os.path.isdir(os.path.join(current_directory, '.git'))\n\ndef run_git_command(command):\n    global current_directory\n    try:\n        result = subprocess.run(\n            ['git'] + command.split(),\n            cwd=current_directory,\n            check=True,\n            stdout=subprocess.PIPE,\n            stderr=subprocess.PIPE,\n            text=True\n        )\n        return result.stdout.strip()\n    except subprocess.CalledProcessError as e:\n        raise Exception(e.stderr.strip())\n\ndef main():\n    log('Welcome to the GitHub Universe 2024 CLI!')\n\n    while True:\n        options = [\n            '1. Set working directory',\n            '2. Create new repository',\n            '3. Create new branch',\n            '4. Switch branch',\n            '5. Show pending files',\n            '6. Commit changes',\n            '7. Show commit history',\n            '8. Delete branch',\n            '9. Set remote repository',\n            '10. Pull from remote',\n            '11. Push to remote',\n            '12. Exit'\n        ]\n\n        log('\\nPlease select an option:')\n        log('\\n'.join(options))\n\n        choice = input('Enter your choice: ')\n\n        if choice == '1':\n            current_directory = input('Enter the new working directory: ')\n            log(f'Working directory set to: {current_directory}')\n        elif choice == '2':\n            new_repo_name = input('Enter the name of the new repository: ')\n            run_git_command(f'init {new_repo_name}')\n            log(f'New repository created: {new_repo_name}')\n        elif choice == '3':\n            if not is_git_repository():\n                log('Error: Not in a Git repository. Please initialize a repository first.')\n                continue\n            new_branch_name = input('Enter the name of the new branch: ')\n            run_git_command(f'checkout -b {new_branch_name}')\n            global current_branch\n            current_branch = new_branch_name\n            log(f'New branch created: {new_branch_name}')\n        elif choice == '4':\n            if not is_git_repository():\n                log('Error: Not in a Git repository. Please initialize a repository first.')\n                continue\n            branch_to_switch = input('Enter the name of the branch to switch to: ')\n            run_git_command(f'checkout {branch_to_switch}')\n            current_branch = branch_to_switch\n            log(f'Switched to branch: {branch_to_switch}')\n        elif choice == '5':\n            if not is_git_repository():\n                log('Error: Not in a Git repository. Please initialize a repository first.')\n                continue\n            pending_files = run_git_command('status --porcelain')\n            log('Pending files:')\n            log(pending_files)\n        elif choice == '6':\n            if not is_git_repository():\n                log('Error: Not in a Git repository. Please initialize a repository first.')\n                continue\n            run_git_command('add .')\n            commit_message = input('Enter the commit message: ')\n            run_git_command(f'commit -m \"{commit_message}\"')\n            log('Changes committed successfully')\n        elif choice == '7':\n            if not is_git_repository():\n                log('Error: Not in a Git repository. Please initialize a repository first.')\n                continue\n            commit_history = run_git_command('log --oneline')\n            log('Commit history:')\n            log(commit_history)\n        elif choice == '8':\n            if not is_git_repository():\n                log('Error: Not in a Git repository. Please initialize a repository first.')\n                continue\n            branch_to_delete = input('Enter the name of the branch to delete: ')\n            run_git_command(f'branch -d {branch_to_delete}')\n            log(f'Branch {branch_to_delete} deleted')\n        elif choice == '9':\n            if not is_git_repository():\n                log('Error: Not in a Git repository. Please initialize a repository first.')\n                continue\n            global remote_repository\n            remote_repository = input('Enter the URL of the remote repository: ')\n            run_git_command(f'remote add origin {remote_repository}')\n            log(f'Remote repository set to: {remote_repository}')\n        elif choice == '10':\n            if not is_git_repository():\n                log('Error: Not in a Git repository. Please initialize a repository first.')\n                continue\n            run_git_command(f'pull origin {current_branch}')\n            log('Pulled changes from remote repository')\n        elif choice == '11':\n            if not is_git_repository():\n                log('Error: Not in a Git repository. Please initialize a repository first.')\n                continue\n            run_git_command(f'push -u origin {current_branch}')\n            log('Pushed changes to remote repository')\n        elif choice == '12':\n            log('Exiting the GitHub Universe 2024 CLI...')\n            break\n        else:\n            log('Invalid choice. Please try again.')\n\nif __name__ == '__main__':\n    main()\n\n"
  },
  {
    "path": "Roadmap/43 - GIT GITHUB CLI/python/hectorio23.py",
    "content": "# Autor: Héctor Adán\n# GitHub: https://github.com/hectorio23\n\nimport os\nimport subprocess\n\ndef set_working_directory():\n    path = input(\"Enter the working directory path: \")\n    try:\n        os.chdir(path)\n        print(f\"Working directory set to {os.getcwd()}\")\n    except FileNotFoundError:\n        print(\"Invalid directory path.\")\n\ndef create_repository():\n    subprocess.run([\"git\", \"init\"])\n    print(\"Repository initialized.\")\n\ndef create_branch():\n    branch = input(\"Enter branch name: \")\n    subprocess.run([\"git\", \"branch\", branch])\n    print(f\"Branch '{branch}' created.\")\n\ndef switch_branch():\n    branch = input(\"Enter branch name: \")\n    subprocess.run([\"git\", \"checkout\", branch])\n\ndef show_pending_files():\n    subprocess.run([\"git\", \"status\"])\n\ndef commit_changes():\n    message = input(\"Enter commit message: \")\n    subprocess.run([\"git\", \"add\", \".\"])\n    subprocess.run([\"git\", \"commit\", \"-m\", message])\n\ndef show_commit_history():\n    subprocess.run([\"git\", \"log\", \"--oneline\"])\n\ndef delete_branch():\n    branch = input(\"Enter branch name to delete: \")\n    subprocess.run([\"git\", \"branch\", \"-d\", branch])\n\ndef set_remote():\n    remote_url = input(\"Enter remote repository URL: \")\n    subprocess.run([\"git\", \"remote\", \"add\", \"origin\", remote_url])\n\ndef pull_changes():\n    subprocess.run([\"git\", \"pull\", \"origin\"])\n\ndef push_changes():\n    subprocess.run([\"git\", \"push\", \"origin\"])\n\ndef exit_program():\n    print(\"Goodbye!\")\n    exit()\n\nactions = {\n    \"1\": set_working_directory,\n    \"2\": create_repository,\n    \"3\": create_branch,\n    \"4\": switch_branch,\n    \"5\": show_pending_files,\n    \"6\": commit_changes,\n    \"7\": show_commit_history,\n    \"8\": delete_branch,\n    \"9\": set_remote,\n    \"10\": pull_changes,\n    \"11\": push_changes,\n    \"12\": exit_program\n}\n\nwhile True:\n    print(\"\\nOptions:\")\n    for key, func in actions.items():\n        print(f\"{key}. {func.__name__.replace('_', ' ').capitalize()}\")\n    choice = input(\"\\nSelect an option: \")\n    action = actions.get(choice)\n    if action:\n        action()\n    else:\n        print(\"Invalid option.\")\n"
  },
  {
    "path": "Roadmap/43 - GIT GITHUB CLI/python/idiegorojas.py",
    "content": "\"\"\"\n# 43 - Git Github CLI\n\"\"\"\n\n# Desarrolla un CLI (Command Line Interface) que permita interactuar con Git y GitHub de manera real desde terminal.\n# El programa debe permitir las siguientes opciones:\n    # 1. Establecer el directorio de trabajo\n    # 2. Crear un nuevo repositorio\n    # 3. Crear una nueva rama\n    # 4. Cambiar de rama\n    # 5. Mostrar ficheros pendientes de hacer commit\n    # 6. Hacer commit (junto con un add de todos los ficheros)\n    # 7. Mostrar el historial de commits\n    # 8. Eliminar rama\n    # 9. Establecer repositorio remoto\n    # 10. Hacer pull\n    # 11. Hacer push\n    # 12. Salir\n# Puedes intentar controlar los diferentes errores.\n\nimport argparse\nimport requests\nimport subprocess\nimport os\nimport sys\n\ncurrent_dir = os.getcwd()\n\ndef set_working_directory(path):\n    \"\"\"Set the working directory for git operations\"\"\"\n    global current_dir\n    if os.path.exists(path):\n        current_dir = path\n        print(f\"Working directory set to: {current_dir}\")\n        return True\n    else:\n        print(f\"Error: Directory {path} does not exist\")\n        return False\n\ndef create_repository():\n    \"\"\"Create a new git repository in the current directory\"\"\"\n    try:\n        subprocess.run([\"git\", \"init\"], cwd=current_dir, check=True)\n        print(f\"Repository initialized in {current_dir}\")\n        return True\n    except subprocess.CalledProcessError as e:\n        print(f\"Error creating repository: {e}\")\n        return False\n\ndef create_branch(branch_name):\n    \"\"\"Create a new git branch\"\"\"\n    try:\n        subprocess.run([\"git\", \"checkout\", \"-b\", branch_name], cwd=current_dir, check=True)\n        print(f\"Branch '{branch_name}' created\")\n        return True\n    except subprocess.CalledProcessError as e:\n        print(f\"Error creating branch: {e}\")\n        return False\n\n# Add more functions for the remaining operations\n\ndef main():\n    parser = argparse.ArgumentParser(description=\"Git and GitHub CLI\")\n    parser.add_argument(\"--dir\", help=\"Set working directory\")\n    parser.add_argument(\"--init-repo\", action=\"store_true\", help=\"Create a new repository\")\n    parser.add_argument(\"--create-branch\", metavar=\"BRANCH\", help=\"Create a new branch\")\n    parser.add_argument(\"--checkout\", metavar=\"BRANCH\", help=\"Switch to branch\")\n    parser.add_argument(\"--status\", action=\"store_true\", help=\"Show pending files\")\n    parser.add_argument(\"--commit\", metavar=\"MESSAGE\", help=\"Add and commit all files\")\n    parser.add_argument(\"--log\", action=\"store_true\", help=\"Show commit history\")\n    parser.add_argument(\"--delete-branch\", metavar=\"BRANCH\", help=\"Delete a branch\")\n    parser.add_argument(\"--set-remote\", metavar=\"URL\", help=\"Set remote repository\")\n    parser.add_argument(\"--pull\", action=\"store_true\", help=\"Pull changes\")\n    parser.add_argument(\"--push\", action=\"store_true\", help=\"Push changes\")\n    \n    args = parser.parse_args()\n    \n    # Process arguments and call appropriate functions\n    if args.dir:\n        set_working_directory(args.dir)\n    elif args.init_repo:\n        create_repository()\n    # Add more conditions for other arguments\n    \nif __name__ == \"__main__\":\n    main()"
  },
  {
    "path": "Roadmap/43 - GIT GITHUB CLI/python/ignaciovihe.py",
    "content": "\"\"\"\n * EJERCICIO:\n * ¡Me voy de viaje al GitHub Universe 2024 de San Francisco!\n *\n * Desarrolla un CLI (Command Line Interface) que permita \n * interactuar con Git y GitHub de manera real desde terminal.\n * \n * El programa debe permitir las siguientes opciones:\n * 1. Establecer el directorio de trabajo\n * 2. Crear un nuevo repositorio\n * 3. Crear una nueva rama\n * 4. Cambiar de rama\n * 5. Mostrar ficheros pendientes de hacer commit\n * 6. Hacer commit (junto con un add de todos los ficheros)\n * 7. Mostrar el historial de commits\n * 8. Eliminar rama\n * 9. Establecer repositorio remoto\n * 10. Hacer pull\n * 11. Hacer push\n * 12. Salir\n *\n * Puedes intentar controlar los diferentes errores.\n\"\"\"\n\nfrom git import Repo, GitCommandError\nimport os\n\ndef clear_console():\n    \"\"\"\n    Limpia la consola, tneiendo en cuenta el sistema operativo.\n    \"\"\"\n    os.system('cls' if os.name =='nt' else 'clear')\n\n\ndef exist_repo(path):\n    \"\"\"\n    Comprueba si existe un repositorio de git, comprobando si existe el ficrero .git en el path pasado.\n    \"\"\"\n    git_folder = os.path.join(path, '.git')\n    return os.path.isdir(git_folder)\n\n\ndef set_working_directory():\n    \"\"\"\n    Establece el nuevo directorio de trabajo y comprueba si ya existe un repositorio en él.\n    Devuelve el nuevo directorio y el objeto Repo si ya existe o None si no.\n    \"\"\"\n    new_directory = input(\"Introduce el nuevo directorio:\")\n    if os.path.exists(new_directory) and os.path.isdir(new_directory):\n        print(f\"Se ha modificado el directorio de trabajo.\")\n        if exist_repo(new_directory): # Si ya hay un repositorio en el directorio.\n            new_repo = Repo(new_directory)\n            print(f\"Se ha encontrado un repositorio en el directorio. Se establece como repositorio actual.\")\n        else:\n            new_repo = None\n        input(\"ENTER para continuar\")\n        return new_directory, new_repo\n    else:\n        raise Exception(\"El nuevo directorio de trabajo no existe. No se modifica.\")\n    \n\ndef init_new_repository(path):\n    \"\"\"\n    Comprueba si existe un repositorio en el directorio pasado.\n    Si ya existe lanza una excepción y si no, crea el repsitorio y lo devuelve.\n    \"\"\"\n    if exist_repo(path):\n        raise Exception(\"Ya existe un repositorio creado en el directorio de trabajo. No se hace nada.\")\n    print(f\"Nuevo repositorio iniciado en '{path}'\")\n    input(\"ENTER para continuar\")\n    return Repo.init(path)\n\n\ndef create_new_branch(repo: Repo):\n    \"\"\"\n    Crea una nueva rama y cambia el Head a esa nueva rama.\n    \"\"\"\n    branch_name = input(\"Nombre de la nueva rama: \")\n    repo.git.checkout(\"-b\", branch_name)\n    print(f\"Nueva rama {branch_name} creada correctamente.\")\n    input(\"ENTER para continuar\")\n\n\ndef change_branch(repo: Repo):\n    \"\"\"\n    Cambia la rama activa a la que le pasemos comprobando si existe la rama.\n    \"\"\"\n    branch_name = input(\"Nombre de la nueva rama: \")\n    if branch_name in repo.heads and branch_name != repo.active_branch:\n        repo.git.checkout(branch_name)\n    else:\n        print(f\"La rama '{branch_name}' no existe o ya es la rama activa.\")\n        input(\"ENTER para continuar\")\n        return\n    print(f\"Nueva rama activa '{branch_name}'\")\n    input(\"ENTER para continuar\")\n\n\ndef check_repo_status(repo :Repo):\n    \"\"\"\n    Comprueba el estado del repositorio e imprime el resultado.\n    Equivalente a 'git status'\n    \"\"\"\n    print(repo.git.status())\n    input(\"ENTER para continuar\")\n\n\ndef commit_files(repo: Repo, all= True):\n    \"\"\"\n    Realiza el add y commit de:\n    -Todos los archivos nuevos.\n    -Un directorio en particular(buscando los ficheros nuevos en su interior).\n    -Un archivo en particular.\n    Dependiendo de la opcion pasada del menu.\n    \"\"\"\n    if not repo.is_dirty(untracked_files=True):# Esto comprueba si hay cambios en el repo\n        print(\"No hay cambios para commitear.\")\n        input(\"ENTER para continuar\")\n        return\n    \n    result=\"\"\n\n    if all:\n        repo.git.add(all=True)\n        result = \"todos los archivos.\"\n    else:\n        file = input(\"Nombre del archivo a commitear: \").strip()\n        modified_files = [diff.a_path for diff in repo.index.diff(None)]\n        files_to_add = []\n\n        # Ruta absoluta al archivo/carpeta\n        if repo.working_tree_dir:\n            abs_path = os.path.join(repo.working_tree_dir, file)\n        else:\n            raise Exception(\"No se pudo determinar el directorio raíz del repositorio.\")\n\n        # Si es carpeta, buscar archivos dentro\n        if os.path.isdir(abs_path):\n            for root, _, filenames in os.walk(abs_path):\n                for name in filenames:\n                    full_path = os.path.join(root, name)\n                    # Normalizar la ruta relativa a la raíz del repo\n                    rel_path = os.path.relpath(full_path, repo.working_tree_dir)\n                    rel_path = rel_path.replace(os.sep, \"/\")\n                    print(f\"rel_path: {rel_path}\")\n                    print(f\"Untracked: {repo.untracked_files}\")\n                    print(f\"Modified: {modified_files}\")\n                    if rel_path in repo.untracked_files or rel_path in modified_files:\n                        files_to_add.append(rel_path)\n\n        # Si es archivo directamente                \n        elif file in repo.untracked_files or file in modified_files: #archivos no trackeados - archivos modificados\n            files_to_add.append(file)\n\n        if not files_to_add:\n            print(\"No existe el fichero/carpeta a comitear o no contiene archivos nuevos.\")\n            input(\"ENTER para continuar\")\n            return\n        # Añadir todos los archivos detectados\n        repo.index.add(files_to_add)\n        result = \", \".join(files_to_add)\n\n    message = input(\"Mensaje de commit: \")\n    repo.index.commit(message)\n    print(f\"Commit de {result} correcto.\")\n    input(\"ENTER para continuar\")\n\n\ndef show_commits_history(repo: Repo):\n    \"\"\"\n    Imprime el historial de commits del repositorio pasado.\n    \"\"\"\n    for commit in repo.iter_commits():\n        print(f\"Hash: {commit.hexsha}\")\n        print(f\"Autor: {commit.author.name} <{commit.author.email}>\")\n        print(f\"Fecha: {commit.committed_datetime}\")\n        print(f\"Mensaje: {commit.message.strip()}\")\n        print(\"-\" * 40)\n    input(\"ENTER para continuar\")\n\n\ndef merge_branch(repo: Repo):\n    \"\"\"\n    Realiza el merge de una rama source a la rama activa. Comprueba si hay archivos que mergear,\n    y si es asi los mergea. Si hay conflictos lanza una excepción y te proporciona instrucciones para \n    recolver los conflictos manualmente, haciendo una pausa en la ejecución para poder solucionarlos.\n    Finalmente hace un commit automatico de mergeo.\n    \"\"\"\n    print(f\"Rama activa: {repo.active_branch}\")\n    if repo.is_dirty(untracked_files=True):# Por seguridad comprobamos que no haya cambios sin commitear.\n        raise Exception(\"Hay cambios sin commitear. Haz commit antes de hacer merge\")\n    \n    target_branch = repo.active_branch\n    source_branch = input(\"Introduce el nombre de la rama fuente: \")\n\n    if source_branch not in repo.branches:# Comprobamos que la rama exista.\n        print(f\"No se encuentra la rama '{source_branch}'. Comprueba el nombre.\")\n        input(\"ENTER para continuar\")\n        return\n    \n    # Comprobamos si hay algo que mergear antes de lanzarlo\n    # repo.git.rev_list compara los commits entre dos ramas. left only = solo cuenta los de la izq\n    # count que cuente los commits del lado indicado\n    # source ... target(o alreves como se desee) que compare ambas ramas\n    # devuelve cuantos commits hay en source que no esten en target\n    commits_to_merge = int(repo.git.rev_list('--left-only', '--count', f'{source_branch}...{target_branch}'))\n    if commits_to_merge == 0:\n        print(f\"No hay cambios nuevos en '{source_branch}' que mergear en '{target_branch}'.\")\n        input(\"ENTER para continuar\")\n        return\n\n    try:\n        repo.git.merge(source_branch)# Hacemos el merge. Si hay conflicto lanza una excepcion GitCommandError\n        print(f\"Se hizo merge de '{source_branch}' a '{target_branch}' correctamente.\")\n        input(\"ENTER para continuar\")\n\n    except GitCommandError as e:\n        # Mostrar archivos en conflicto\n        unmerged_paths = list(repo.index.unmerged_blobs().keys())\n        print(\"\\nArchivos en conflicto:\")\n        for path in unmerged_paths:\n            print(f\"  - {path}\")\n\n        if \"Merge conflict\" in str(e):# si hay conflicto en el mensaje de la excepción. Lanzamos instrucciones.\n            print(\"Conflicto detectado durante el merge.\")\n            print(\"Edita manualmente los archivos en conflicto y guarda los cambios.\")\n            input(\"Pulsa ENTER cuando hayas resuelto todos los conflictos...\")\n\n            # Intentar hacer add a esos archivos\n            for path in unmerged_paths:\n                try:\n                    repo.git.add(path) # Esta linea no puede ser repo.index.add(path). porque eso no elimina el archivo como conflictivo.\n                except Exception as ex:# debe usar git.add que si tiene el contexto del merge.\n                    print(f\"Error al hacer add a {path}: {ex}\")\n                    input(\"ENTER para continuar\")\n\n            # Verifica si quedan conflictos sin resolver\n            if repo.index.unmerged_blobs():\n                print(\"Aún hay archivos en conflicto. No se puede hacer commit.\")\n                input(\"ENTER para continuar\")\n                return\n            \n            # Hacer commit automatico para concluir el merge. Debe ser con git.commit que tiene en cuenta el contexto del merge.\n            repo.git.commit('-m', f\"Conflictos resueltos y merge completado. ({target_branch}) <- ({source_branch})\")\n            print(\"Conflictos resueltos. Merge finalizado correctamente.\")\n            input(\"ENTER para continuar\")\n        else:\n            print(\"Error inesperado durante el merge:\", e)\n            input(\"ENTER para continuar\")\n\n\ndef delete_branch(repo: Repo):\n    \"\"\"\n    Borra la rama que le indiquemos, teniendo en cuenta antes, si esta ha sido ya mergeada.\n    En el caso de que no haya problemas la borra.\n    Enel caso de que todavia haya archivos sin mergear, nos dara la opción de borrarla a la fuerza.\n    teniendo que confirmar dos veces el borrado.\n    \"\"\"\n\n    if len(repo.branches) == 1:\n        print(f\"Solo existe main. No hay rama que borrar.\")\n        input(\"ENTER para continuar\")\n        return\n    \n    branch = input(f\"Nombre de la rama a borrar: \")\n\n    if branch not in repo.branches:\n        print(f\"La rama {branch} no existe.\")\n        input(\"ENTER para continuar\")\n        return\n    \n    if branch == repo.active_branch.name:\n        print(\"No puedes borrar la rama en la que estás actualmente.\")\n        input(\"ENTER para continuar\")\n        return\n\n    try:\n        repo.delete_head(branch, force=False)\n        print(f\"Rama {branch} borrada con exito.(Ya estaba mergeada)\")\n    except GitCommandError as e:\n        if 'is not fully merged' in str(e):\n            op1, op2 = 0, 0\n            print(f\"La rama '{branch}' No está mergeada. No se ha borrado.\")\n            print(f\"Quieres forzar el borrado?\")\n            print(f\"1. SI\")\n            print(f\"2. NO\")\n            while op1 not in [1, 2]:\n                try:\n                    op1 = int(input(\"Introduce una opción valida(1 o 2): \"))\n                except ValueError:\n                    print(\"Debes introducir un número.\")\n\n            if op1 == 1:\n                print(f\"Estas seguro. No se podra recuperar?\")\n                print(f\"1. SI\")\n                print(f\"2. NO\")\n                while op2 not in [1, 2]:\n                    try:\n                        op2 = int(input(\"Introduce una opción valida (1 o 2): \"))\n                    except ValueError:\n                        print(\"Debes introducir un número.\")\n                if  op2 == 1:\n                    repo.delete_head(branch, force=True)\n                    print(f\"Rama {branch} borrada con exito.(Borrado a la fuerza.)\")\n                else:\n                    print(\"No se ha borrado la rama. Haz merge y vuelve a initentarlo.\")\n        else:\n            print(f\"Error al intentar borrar la rama: {e}\")\n    input(\"ENTER para continuar\")\n\n\ndef show_branches(repo: Repo):\n    \"\"\"\n    Imprime la ramas del repositorio.\n    \"\"\"\n    branches = [head.name for head in repo.heads]\n    for branch in branches:\n        print(f\"-{branch}\")\n    input(\"ENTER para continuar\")\n\n\ndef show_remote(repo: Repo):\n    \"\"\"\n    Imprime los remotos asociados al repositorio actual con sus url\n    \"\"\"\n    for remote in repo.remotes:\n        print(f\"Remoto asociado al repositorio actual: {remote.name}\")\n        for url in remote.urls:\n            print(f\"\\t-URL: {url}\")\n\n\ndef set_remote_repository(repo: Repo, remote_url: str, remote_name: str = \"origin\"):\n    \"\"\"\n    Establece el remoto al repositorio local del directorio de trabajo.\n    Comprueba si ya existe el remoto en cuyo caso te permite cambiarlo.\n    En el caso de que sea la primera vez, también configura el upstream,\n    para evitar errores al hacer push por primera vez.\n    \"\"\"\n    try:\n        #Verificamos que existe el repositorio\n        if remote_name in repo.remotes:\n            print(f\"El remoto '{remote_name} ya existe.\")\n            update = \"\"\n            while update not in (\"s\", \"n\"):\n                update = input(\"¿Quieres alctualizar su URL? (s/n) \").lower()\n                if update not in (\"s\", \"n\"):\n                    print(\"Introduce una opción correcta: (s/n)\")\n            if update == \"s\":\n                remote = repo.remotes[remote_name]\n                repo.delete_remote(remote)\n                repo.create_remote(remote_name, remote_url)\n                print(f\"URl del remoto '{remote_name}' actualizada.\")\n            else:\n                print(f\"No se realiza ninguna acción.\")\n        else:\n            repo.create_remote(remote_name, remote_url)\n            print(f\"Remoto '{remote_name}' añadido con URL: {remote_url}\")\n\n        branch = repo.active_branch\n        tracking = branch.tracking_branch()\n        if tracking is None:\n            origin = repo.remote(name=\"origin\")\n            origin.push(refspec=\"main:main\", set_upstream=True)\n            print(f\"Upstream configurado: rama local 'main' sigue a 'origin/main'\")\n        else:\n            print(f\"La rama '{branch.name}' ya sigue a '{tracking}'\")\n\n        input(\"ENTER para continuar\")\n    except Exception as e:\n        raise Exception(e)\n    \n\ndef get_branch_sync_status(repo: Repo) -> tuple[int, int]:\n    \"\"\"\n    Comprueba la sincronizacion entre local y remoto indicando cuantos commits va uno u otro\n    por delante. Esta considerado el caso de que ambos tengan commits adelantados.\n    \"\"\"\n    branch = repo.active_branch\n    tracking_branch = branch.tracking_branch()\n\n    if not tracking_branch:\n        print(\"Esta rama no está vinculada a ninguna rama remota.\")\n        input(\"ENTER para continuar\")\n        return (-1, -1)\n    \n    # Actualizamos el remoto para comparar correctamente\n    repo.remotes.origin.fetch()\n\n    # Contar commits que están solo en local y solo en remoto\n    # rev-list --count A..B → cuenta los commits que están en B pero no en A\n    # ahead significa que el local va por delante. Habría que hacer push.\n    # behind significa que el remoto va por delante. Habría que hacer pull.\n    ahead = int(repo.git.rev_list('--count', f'{tracking_branch}..{branch}'))\n    behind = int(repo.git.rev_list('--count', f'{branch}..{tracking_branch}'))\n\n    print(f\"Commits por delante (local): {ahead}\")\n    print(f\"Commits por detrás (remoto): {behind}\")\n\n    return (ahead, behind)\n\n\ndef pull(repo: Repo):\n    \"\"\"\n    Hace 'pull' de la rama actual desde el remoto 'origin' si hay commits nuevos.\n    - Verifica si el remoto y la rama remota (upstream) están configurados.\n    - No permite hacer pull si hay cambios sin guardar en el repositorio local.\n    - Compara con el estado remoto y solo hace pull si hay commits nuevos (behind > 0).\n    \"\"\"\n\n    if 'origin' not in repo.remotes:\n        print(f\"No hay un remoto 'origin' configurado.\")\n        input(\"ENTER para continuar\")\n        return\n    \n    if not repo.active_branch.tracking_branch():\n        print(\"Esta rama no está vinculada a ninguna rama remota (upstream).\")\n        input(\"ENTER para continuar\")\n        return\n    \n    if repo.is_dirty(untracked_files=True):\n        print(\"Hay cambios sin commitear. Haz commit o stash antes de hacer pull.\")\n        input(\"ENTER para continuar\")\n        return\n\n    try:\n        ahead, behind = get_branch_sync_status(repo)\n\n        if behind == -1:\n            return\n        if behind == 0:\n            print(\"Ya estás actualizado con el remoto. Nada que hacer.\")\n        else:\n            repo.remotes.origin.pull()\n            print(f\"Pull completado correctamente. (Había {behind} commit/s nuevos)\")\n    except GitCommandError as e:\n        print(\"Error al hacer pull.\", e)\n\n    input(\"ENTER para continuar\")\n\n\ndef push(repo: Repo):\n    \"\"\"\n    Hace push de la rama actual si está por delante del remoto.\n    - Si hay commits pendientes en remoto: muestra advertencia y no hace push.(antes necesario pull)\n    - Si todo está sincronizado: indica que no hay nada que subir.\n    \"\"\"\n\n    branch = repo.active_branch.name\n\n    if 'origin' not in repo.remotes:\n        print(f\"El remoto no esta configurado.\")\n        input(\"ENTER para continuar\")\n        return\n    \n    ahead, behind = get_branch_sync_status(repo)\n\n    if ahead == -1:\n        return\n    if ahead > 0:\n        if behind > 0:\n            print(\"Hay cambios en el remoto. Haz pull antes de hacer push.\")\n        else:\n            origin = repo.remotes.origin\n            try:\n                origin.push()\n                print(f\"Push completado con exito.\")\n\n            except GitCommandError as e:\n                print(f\"Error al hacer push: {e}\")\n    else:\n        print(\"Ya esta todo actualizado.\")\n\n    input(\"ENTER para continuar\")\n\n\n\n\n\n\ndef main():\n    current_working_directory = os.getcwd()\n    current_repository = None\n\n    while True:\n        print(f\"=== GIT CLI ===\")\n        print(f\"1. Establecer nuevo directorio de trabajo\")\n        print(f\"2. Crear un nuevo repositorio\")\n        print(f\"3. Crear una nueva rama\")\n        print(f\"4. Cambiar de rama\")\n        print(f\"5. Mostrar estado del repositorio\")\n        print(f\"6. Hacer commit (junto con un add de todos los ficheros)\")\n        print(f\"7. Hacer commit (junto con un add de un fichero)\")\n        print(f\"8. Mostrar el historial de commits\")\n        print(f\"9. Mergear rama\")\n        print(f\"10. Eliminar rama\")\n        print(f\"11. Listar ramas\")\n        print(f\"12. Establecer repositorio remoto\")\n        print(f\"13. Hacer pull\")\n        print(f\"14. Hacer push\")\n        print(f\"15. Salir\")\n        print(\"\")\n        print(f\"Directorio de trabajo actual: '{current_working_directory}'\")\n        print(\"Repositorio activo: SI\" if current_repository else \"Repositorio activo: NO\" )\n        print(f\"Rama activa: {current_repository.active_branch.name}\" if current_repository else \"\")\n        if current_repository and current_repository.remotes:\n            show_remote(current_repository)\n\n\n        try:\n            option = int(input(\"Opción: \"))\n            match option:\n                case 1:\n                    current_working_directory, current_repository = set_working_directory()\n                    clear_console()\n                case 2:\n                    current_repository = init_new_repository(current_working_directory)\n                    clear_console()\n                case 3:\n                    if current_repository:\n                        create_new_branch(current_repository)\n                        clear_console()\n                    else:\n                        raise Exception(\"Todavia no hay un repositorio en el diretorio de trabajo actual. Incicializa uno primero.\")\n                case 4:\n                    if current_repository:\n                        change_branch(current_repository)\n                        clear_console()\n                    else:\n                        raise Exception(\"Todavia no hay un repositorio en el diretorio de trabajo actual. Incicializa uno primero.\")\n                case 5:\n                    if current_repository:\n                        check_repo_status(current_repository)\n                        clear_console()\n                    else:\n                        raise Exception(\"Todavia no hay un repositorio en el diretorio de trabajo actual. Incicializa uno primero.\")\n                case 6:\n                    if current_repository:\n                        commit_files(current_repository)\n                        clear_console()\n                    else:\n                        raise Exception(\"Todavia no hay un repositorio en el diretorio de trabajo actual. Incicializa uno primero.\")\n                case 7:\n                    if current_repository:\n                        commit_files(current_repository, all=False)\n                        clear_console()\n                    else:\n                        raise Exception(\"Todavia no hay un repositorio en el diretorio de trabajo actual. Incicializa uno primero.\")\n                case 8:\n                    if current_repository:\n                        show_commits_history(current_repository)\n                        clear_console()\n                    else:\n                        raise Exception(\"Todavia no hay un repositorio en el diretorio de trabajo actual. Incicializa uno primero.\")\n                case 9:\n                    if current_repository:\n                        merge_branch(current_repository)\n                        clear_console()\n                    else:\n                        raise Exception(\"Todavia no hay un repositorio en el diretorio de trabajo actual. Incicializa uno primero.\")\n                case 10:\n                    if current_repository:\n                        delete_branch(current_repository)\n                        clear_console()\n                    else:\n                        raise Exception(\"Todavia no hay un repositorio en el diretorio de trabajo actual. Incicializa uno primero.\")\n                case 11:\n                    if current_repository:\n                        show_branches(current_repository)\n                        clear_console()\n                    else:\n                        raise Exception(\"Todavia no hay un repositorio en el diretorio de trabajo actual. Incicializa uno primero.\")\n                case 12:\n                    if current_repository:\n                        remote_url = input(\" Introduce la URL del repositorio remoto: \")\n                        set_remote_repository(current_repository, remote_url)\n                        clear_console()\n                    else:\n                        raise Exception(\"Todavia no hay un repositorio en el diretorio de trabajo actual. Incicializa uno primero.\")\n                case 13:\n                    if current_repository:\n                        pull(current_repository)\n                        clear_console()\n                    else:\n                        raise Exception(\"Todavia no hay un repositorio en el diretorio de trabajo actual. Incicializa uno primero.\")\n                \n                case 14:\n                    if current_repository:\n                        push(current_repository)\n                        clear_console()\n                    else:\n                        raise Exception(\"Todavia no hay un repositorio en el diretorio de trabajo actual. Incicializa uno primero.\")\n                case 15:\n                    print(\"Saliendo...\")\n                    break\n        except Exception as e:\n            print(e)\n            input(\"ENTER para continuar\")\n            clear_console()\n\nmain()\n\n\n"
  },
  {
    "path": "Roadmap/43 - GIT GITHUB CLI/python/joselorentelopez.py",
    "content": "\"\"\"\nOwner: José Lorente López | joselorente1105@gmail.com | Linkedin: www.linkedin.com/in/josé-lorente-lópez-0121b7148\n\nDescription: CLI capable of interacting with Git and Github from the terminal.\n\nCoding: UTF-8\n\"\"\"\n\nimport os\nimport subprocess\n\nclass CLI():\n    def __init__(self) -> None:\n        pass\n\nclass Git_CLI(CLI):\n    def __init__(self):\n        super().__init__()\n\n    @staticmethod\n    def set_working_directory():\n        path_ = input(\"Enter the working directory: \").strip()\n        try:\n            os.chdir(path_)\n            print(f\"\\nWorking directory changed to: {os.getcwd()}\\n\")\n        except FileNotFoundError:\n            print(f\"\\nError: The directory '{path_}' does not exist.\\n\")\n        except Exception as e:\n            print(f\"\\nError {e}: An unexpected error occurred while setting the working directory.\\n\")\n\n    @staticmethod\n    def create_new_repo():\n        try:\n            subprocess.run([\"git\", \"init\"], check=True)\n            print(f\"\\nNew repository generated in {os.getcwd()}\\n\")\n        except subprocess.CalledProcessError as e:  # CalledProcessError means that a subprocess started by Python exited with an error\n            print(f\"\\nError {e}: Failed to create the new repository.\\n\")\n\n    @staticmethod\n    def create_new_branch():\n        branch_name = input(\"Enter the new branch name: \").strip()\n        if not branch_name:\n            print(\"Branch name cannot be empty.\")\n            return\n\n        # Check if the repository has an initial branch\n        result = subprocess.run([\"git\", \"branch\"], capture_output=True, text=True)\n        branches = result.stdout.splitlines()\n\n        if not branches:\n            # If there are no branches, create 'main' as the initial branch\n            try:\n                subprocess.run([\"git\", \"checkout\", \"-b\", \"main\"], check=True)\n                print(\"No initial branch found. 'main' created as the default branch.\")\n                \n                # Make an initial commit to avoid further issues\n                with open(\"README.md\", \"w\") as f:\n                    f.write(\"# Initial Commit\\n\")\n                \n                subprocess.run([\"git\", \"add\", \"README.md\"], check=True)\n                subprocess.run([\"git\", \"commit\", \"-m\", \"Initial commit\"], check=True)\n                print(\"Initial commit created in 'main'.\")\n            except subprocess.CalledProcessError as e:\n                print(f\"\\nError {e}: Failed to create the 'main' branch and initial commit.\\n\")\n                return\n\n        # Proceed with creating the new branch\n        try:\n            subprocess.run([\"git\", \"checkout\", \"main\"], check=True)\n            subprocess.run([\"git\", \"branch\", branch_name], check=True)\n            print(f\"\\nNew branch '{branch_name}' created.\\n\")\n        except subprocess.CalledProcessError as e:\n            print(f\"\\nError {e}: Failed to create the new branch '{branch_name}'.\\n\")\n\n    @staticmethod\n    def show_branch_list():\n        try:\n            subprocess.run([\"git\", \"branch\", \"-a\"], check=True)\n            print(\"\\nList of available branches:\")\n        except subprocess.CalledProcessError as e:\n            print(f\"\\nError {e}: Failed to display the branch list.\\n\")\n\n    @staticmethod\n    def change_branch():\n        branch_name = input(\"Enter the name of the branch you wish to move to: \").strip()\n        if not branch_name:\n            print(\"Branch name cannot be empty.\")\n            return\n\n        # Comprobar si es una rama remota\n        if branch_name.startswith(\"origin/\"):\n            local_branch_name = branch_name.split(\"/\")[1]  # Extraer el nombre de la rama local\n\n            try:\n                subprocess.run([\"git\", \"checkout\", \"-b\", local_branch_name, branch_name], check=True)\n                print(f\"\\nCreated and switched to local branch '{local_branch_name}' from remote '{branch_name}'.\\n\")\n            except subprocess.CalledProcessError as e:\n                print(f\"\\nError {e}: Failed to create and switch to local branch '{local_branch_name}'.\\n\")\n            return\n\n        try:\n            subprocess.run([\"git\", \"checkout\", branch_name], check=True)\n            print(f\"\\nMoved to branch '{branch_name}'.\\n\")\n        except subprocess.CalledProcessError as e:\n            print(f\"\\nError {e}: Failed to move to branch '{branch_name}'.\\n\")\n\n\n    @staticmethod\n    def show_pending_files():\n        try:\n            subprocess.run([\"git\", \"status\"], check=True)\n        except subprocess.CalledProcessError as e:\n            print(f\"\\nError {e}: Failed to show pending files.\\n\")\n\n    @staticmethod\n    def commit_changes():\n        commit_message = input(\"Enter the commit message: \").strip()\n        if not commit_message:\n            print(\"Commit message cannot be empty.\")\n            return\n        try:\n            subprocess.run([\"git\", \"add\", \".\"], check=True)\n            subprocess.run([\"git\", \"commit\", \"-m\", commit_message], check=True)\n            print(f\"\\nCommit made successfully.\\n\")\n        except subprocess.CalledProcessError as e:\n            print(f\"\\nError {e}: Failed to commit changes.\\n\")\n    \n    @staticmethod\n    def show_commit_history():\n        try:\n            subprocess.run([\"git\", \"log\", \"--oneline\"], check=True)\n        except subprocess.CalledProcessError as e:\n            print(f\"\\nError {e}: Failed to show commit history.\\n\")\n\n    @staticmethod\n    def delete_branch():\n        branch_name = input(\"Enter the name of the branch you wish to delete: \").strip()\n        if not branch_name:\n            print(\"Branch name cannot be empty.\")\n            return\n        try:\n            subprocess.run([\"git\", \"branch\", \"-d\", branch_name], check=True)\n            print(f\"\\nBranch '{branch_name}' deleted.\\n\")\n        except subprocess.CalledProcessError as e:\n            print(f\"\\nError {e}: Failed to delete branch '{branch_name}'.\\n\")    \n\n    @staticmethod\n    def set_remote_repository():\n        remote_url = input(\"Enter the remote repository URL: \").strip()\n        if not remote_url:\n            print(\"Remote repository URL cannot be empty.\")\n            return\n        try:\n            subprocess.run([\"git\", \"remote\", \"add\", \"origin\", remote_url], check=True)\n            print(f\"Remote repository '{remote_url}' set correctly.\\n\")\n        except subprocess.CalledProcessError as e:\n            print(f\"\\nError {e}: Failed to connect to remote repository '{remote_url}'.\\n\")\n\n    @staticmethod\n    def pull_changes(): # recommended pre push\n        try:\n            subprocess.run([\"git\", \"pull\"], check=True) # download and integrate changes from the server to your local repository\n            print(\"Changes pulled successfully.\\n\")\n        except subprocess.CalledProcessError as e:\n            print(f\"\\nError {e}: Failed to pull changes.\\n\")\n\n    @staticmethod\n    def push_changes():\n\n        result = subprocess.run([\"git\", \"rev-parse\", \"--is-inside-work-tree\"], capture_output=True, text=True)\n        \n        if result.returncode != 0:\n            print(\"Not a valid Git repository. Please ensure you are in a valid Git directory.\")\n            return\n\n        result = subprocess.run([\"git\", \"branch\", \"--show-current\"], capture_output=True, text=True)\n        current_branch = result.stdout.strip()\n\n        if not current_branch:\n            print(\"No branch detected. Please ensure you have a branch checked out before pushing.\")\n            return\n\n        commit_result = subprocess.run([\"git\", \"rev-parse\", current_branch], capture_output=True, text=True)\n\n        if commit_result.returncode != 0:\n            print(f\"The branch '{current_branch}' has no commits. Please make an initial commit before pushing.\")\n            return\n\n        try:\n            subprocess.run([\"git\", \"push\", \"-u\", \"origin\", current_branch], check=True)\n            print(f\"Changes pushed successfully to branch '{current_branch}'.\\n\")\n        except subprocess.CalledProcessError as e:\n            print(f\"Error {e}: Failed trying to push changes to branch '{current_branch}'.\\n\")\n\ndef main():\n    \"\"\"\n    Runs the main function of the project.\n    \"\"\"\n\n    git_cli = Git_CLI()\n\n    while True:\n        print(\"\\nOptions:\")\n        print(\"1. Set the working directory\")\n        print(\"2. Create a new repository\")\n        print(\"3. Create a new branch\")\n        print(\"4. Switch branches\")\n        print(\"5. Show branch list\")\n        print(\"6. Show files pending commit\")\n        print(\"7. Commit (along with adding all files)\")\n        print(\"8. Show commit history\")\n        print(\"9. Delete branch\")\n        print(\"10. Set remote repository\")\n        print(\"11. Pull\")\n        print(\"12. Push\")\n        print(\"13. Exit\")\n        \n        choice = input(\"Choose an option: \").strip()\n        print(\" \")\n\n        if choice == '1':\n            git_cli.set_working_directory()\n        elif choice == '2':\n            git_cli.create_new_repo()\n        elif choice == '3':\n            git_cli.create_new_branch()\n        elif choice == '4':\n            git_cli.change_branch()\n        elif choice == '5':\n            git_cli.show_branch_list()\n        elif choice == '6':\n            git_cli.show_pending_files()\n        elif choice == '7':\n            git_cli.commit_changes()\n        elif choice == '8':\n            git_cli.show_commit_history()\n        elif choice == '9':\n            git_cli.delete_branch()\n        elif choice == '10':\n            git_cli.set_remote_repository()\n        elif choice == '11':\n            git_cli.pull_changes()\n        elif choice == '12':\n            git_cli.push_changes()\n        elif choice == '13':\n            print(\"See you later!\")\n            break\n        else:\n            print(\"Invalid option. Please try again.\")\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/43 - GIT GITHUB CLI/python/juanppdev.py",
    "content": "\"\"\"\n * EJERCICIO:\n * ¡Me voy de viaje al GitHub Universe 2024 de San Francisco!\n *\n * Desarrolla un CLI (Command Line Interface) que permita \n * interactuar con Git y GitHub de manera real desde terminal.\n * \n * El programa debe permitir las siguientes opciones:\n * 1. Establecer el directorio de trabajo\n * 2. Crear un nuevo repositorio\n * 3. Crear una nueva rama\n * 4. Cambiar de rama\n * 5. Mostrar ficheros pendientes de hacer commit\n * 6. Hacer commit (junto con un add de todos los ficheros)\n * 7. Mostrar el historial de commits\n * 8. Eliminar rama\n * 9. Establecer repositorio remoto\n * 10. Hacer pull\n * 11. Hacer push\n * 12. Salir\n *\n * Puedes intentar controlar los diferentes errores.\n\"\"\"\n\n# Usar pip install gitpython\n\nimport os\nimport sys\nimport git\nfrom git import Repo, GitCommandError\n\ndef set_working_directory():\n    path = input(\"Introduce la ruta del directorio de trabajo: \")\n    if os.path.isdir(path):\n        os.chdir(path)\n        print(f\"Directorio cambiado a: {os.getcwd()}\")\n    else:\n        print(\"Ruta no válida. Inténtalo de nuevo.\")\n\ndef create_repository():\n    try:\n        Repo.init(os.getcwd())\n        print(\"Repositorio creado exitosamente.\")\n    except GitCommandError as e:\n        print(f\"Error al crear el repositorio: {e}\")\n\ndef create_branch(repo):\n    branch_name = input(\"Nombre de la nueva rama: \")\n    try:\n        repo.git.branch(branch_name)\n        repo.git.checkout(branch_name)\n        print(f\"Rama '{branch_name}' creada y cambiada.\")\n    except GitCommandError as e:\n        print(f\"Error al crear la rama: {e}\")\n\ndef switch_branch(repo):\n    branch_name = input(\"Nombre de la rama a la que quieres cambiar: \")\n    try:\n        repo.git.checkout(branch_name)\n        print(f\"Cambiado a la rama '{branch_name}'.\")\n    except GitCommandError as e:\n        print(f\"Error al cambiar de rama: {e}\")\n\ndef show_pending_files(repo):\n    try:\n        status = repo.git.status()\n        print(status)\n    except GitCommandError as e:\n        print(f\"Error al mostrar archivos pendientes: {e}\")\n\ndef make_commit(repo):\n    commit_message = input(\"Mensaje del commit: \")\n    try:\n        repo.git.add(all=True)\n        repo.git.commit(m=commit_message)\n        print(\"Commit realizado.\")\n    except GitCommandError as e:\n        print(f\"Error al hacer el commit: {e}\")\n\ndef show_commit_history(repo):\n    try:\n        log = repo.git.log(\"--oneline\")\n        print(log)\n    except GitCommandError as e:\n        print(f\"Error al mostrar el historial de commits: {e}\")\n\ndef delete_branch(repo):\n    branch_name = input(\"Nombre de la rama a eliminar: \")\n    try:\n        repo.git.branch(\"-d\", branch_name)\n        print(f\"Rama '{branch_name}' eliminada.\")\n    except GitCommandError as e:\n        print(f\"Error al eliminar la rama: {e}\")\n\ndef set_remote_repository(repo):\n    remote_url = input(\"URL del repositorio remoto: \")\n    try:\n        repo.create_remote(\"origin\", remote_url)\n        print(f\"Repositorio remoto '{remote_url}' añadido como 'origin'.\")\n    except GitCommandError as e:\n        print(f\"Error al añadir el repositorio remoto: {e}\")\n\ndef pull_changes(repo):\n    try:\n        repo.git.pull(\"origin\")\n        print(\"Pull realizado.\")\n    except GitCommandError as e:\n        print(f\"Error al hacer pull: {e}\")\n\ndef push_changes(repo):\n    try:\n        repo.git.push(\"origin\")\n        print(\"Push realizado.\")\n    except GitCommandError as e:\n        print(f\"Error al hacer push: {e}\")\n\ndef show_menu():\n    print(\"\\n--- Git CLI ---\")\n    print(\"1. Establecer el directorio de trabajo\")\n    print(\"2. Crear un nuevo repositorio\")\n    print(\"3. Crear una nueva rama\")\n    print(\"4. Cambiar de rama\")\n    print(\"5. Mostrar ficheros pendientes de hacer commit\")\n    print(\"6. Hacer commit\")\n    print(\"7. Mostrar el historial de commits\")\n    print(\"8. Eliminar rama\")\n    print(\"9. Establecer repositorio remoto\")\n    print(\"10. Hacer pull\")\n    print(\"11. Hacer push\")\n    print(\"12. Salir\")\n\ndef main():\n    repo = None\n    while True:\n        show_menu()\n        choice = input(\"Selecciona una opción: \")\n        \n        # Opciones\n        if choice == '1':\n            set_working_directory()\n            repo = Repo(os.getcwd()) if os.path.isdir(os.getcwd()) and \".git\" in os.listdir(os.getcwd()) else None\n        elif choice == '2':\n            create_repository()\n            repo = Repo(os.getcwd())\n        elif repo is None:\n            print(\"Primero establece el directorio de trabajo y crea o abre un repositorio.\")\n        elif choice == '3':\n            create_branch(repo)\n        elif choice == '4':\n            switch_branch(repo)\n        elif choice == '5':\n            show_pending_files(repo)\n        elif choice == '6':\n            make_commit(repo)\n        elif choice == '7':\n            show_commit_history(repo)\n        elif choice == '8':\n            delete_branch(repo)\n        elif choice == '9':\n            set_remote_repository(repo)\n        elif choice == '10':\n            pull_changes(repo)\n        elif choice == '11':\n            push_changes(repo)\n        elif choice == '12':\n            print(\"Saliendo...\")\n            break\n        else:\n            print(\"Opción no válida. Inténtalo de nuevo.\")\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/43 - GIT GITHUB CLI/python/kenysdev.py",
    "content": "# _____________________________________\n# https://github.com/kenysdev\n# 2024 - Python\n# _____________________________________\n# 43 GIT GITHUB CLI\n# ------------------------------------\n\n\"\"\"\n* EJERCICIO:\n * ¡Me voy de viaje al GitHub Universe 2024 de San Francisco!\n *\n * Desarrolla un CLI (Command Line Interface) que permita \n * interactuar con Git y GitHub de manera real desde terminal.\n * \n * El programa debe permitir las siguientes opciones:\n * 1. Establecer el directorio de trabajo\n * 2. Crear un nuevo repositorio\n * 3. Crear una nueva rama\n * 4. Cambiar de rama\n * 5. Mostrar ficheros pendientes de hacer commit\n * 6. Hacer commit (junto con un add de todos los ficheros)\n * 7. Mostrar el historial de commits\n * 8. Eliminar rama\n * 9. Establecer repositorio remoto\n * 10. Hacer pull\n * 11. Hacer push\n * 12. Salir\n *\n * Puedes intentar controlar los diferentes errores.\n\"\"\"\n\nimport subprocess\nimport os\n\ndef run_command(command: str, msg=\"\") -> None:\n    print(msg)\n    result = subprocess.run(command, shell=True, capture_output=True, text=True)\n\n    if result.returncode == 0:\n        print(f\"✅: {result.stdout.strip()}\")\n    else:\n        print(f\"❌: {result.stderr.strip()}\")\n\ndef set_directory() -> None:\n    print(\"Establecer directorio de trabajo:\")\n    path = input(\"Ruta: \")\n    if os.path.isdir(path):\n        os.chdir(path)\n    else:\n        print(\"Esta ruta no existe.\")\n\ndef set_remote_repository() -> None:\n    remote_url = input(\"URL del repositorio: \")\n    run_command(f\"git remote add origin {remote_url}\")\n    run_command(\"git push -u origin main\")\n\nMENU = \"\"\"\nInteractuar con Git y GitHub:\n------------------------------------------------------------\n| 1. Establecer directorio       | 7. Historial de commits |  \n| 2. Crear repositorio           | 8. Eliminar rama        |\n| 3. Crear rama                  | 9. Configurar remoto    |\n| 4. Cambiar rama                | 10. pull                | \n| 5. Mostrar cambios pendientes  | 11. push                | \n| 6. 'add' + 'commit'            | 12. Salir               | \n------------------------------------------------------------\nDirectorio actual:\"\"\"\n\nwhile True:\n    print(MENU)\n    run_command(\"cd\" if os.name == \"nt\" else \"pwd\")\n    option = input(\"\\nOpción: \")\n\n    match option:\n        case \"1\": \n            set_directory()\n        case \"2\":\n            run_command(\"git init && git branch -M main\", \"Crear repositorio\")\n\n        case \"3\":\n            print(\"Crear nueva rama:\")\n            run_command(f\"git branch -c {input('Nombre: ')}\")\n\n        case \"4\":\n            print(\"Cambiar de rama:\")\n            run_command(f\"git switch {input('Nombre: ')}\")\n\n        case \"5\":\n            run_command(\"git status -s\", \"Mostrar cambios\")\n\n        case \"6\":\n            print(\"Nuevo commit:\")\n            run_command(f\"git add . && git commit -m '{input('Mensaje: ')}'\")\n\n        case \"7\":\n            run_command(\"git log --oneline\", \"Historial de commits\")\n\n        case \"8\":\n            print(\"Eliminar rama\") \n            run_command(f\"git branch -d {input('Nombre: ')}\")\n\n        case \"9\":\n            set_remote_repository()\n\n        case \"10\": \n            run_command(f\"git pull origin {input('rama: ')}\")\n\n        case \"11\":\n            run_command(f\"git push origin {input('rama: ')}\")\n\n        case \"12\": \n            print(\"Bye.\")\n            break\n        case _: \n            print(\"Opción no válida.\")\n\n"
  },
  {
    "path": "Roadmap/43 - GIT GITHUB CLI/python/ljoecordoba.py",
    "content": "import os\nimport subprocess\nimport sys\n\n\ndef run_command(command):\n    try:\n        result = subprocess.run(command, shell=True, text=True, capture_output=True)\n        if result.returncode != 0:\n            print(f\"Error: {result.stderr.strip()}\")\n        else:\n            print(\"ejecuto bien\")\n            print(result.stdout.strip())\n    except Exception as e:\n        print(f\"Unexpected error: {e}\")\n\n\ndef main():\n    current_directory = os.getcwd()\n    print(f\"Starting in directory: {current_directory}\")\n    \n    while True:\n        print(\"\\nGit CLI Menu:\")\n        print(\"1. Establecer el directorio de trabajo\")\n        print(\"2. Crear un nuevo repositorio\")\n        print(\"3. Crear una nueva rama\")\n        print(\"4. Cambiar de rama\")\n        print(\"5. Mostrar ficheros pendientes de hacer commit\")\n        print(\"6. Hacer commit (junto con un add de todos los ficheros)\")\n        print(\"7. Mostrar el historial de commits\")\n        print(\"8. Eliminar rama\")\n        print(\"9. Establecer repositorio remoto\")\n        print(\"10. Hacer pull\")\n        print(\"11. Hacer push\")\n        print(\"12. Salir\")\n\n        choice = input(\"\\nSelecciona una opción: \")\n\n        if choice == \"1\":\n            new_directory = input(\"Introduce el nuevo directorio de trabajo: \")\n            if os.path.isdir(new_directory):\n                os.chdir(new_directory)\n                current_directory = os.getcwd()\n                print(f\"Directorio cambiado a: {current_directory}\")\n            else:\n                print(\"Directorio no válido.\")\n        \n        elif choice == \"2\":\n            run_command(\"git init\")\n        \n        elif choice == \"3\":\n            branch_name = input(\"Introduce el nombre de la nueva rama: \")\n            run_command(f\"git branch {branch_name}\")\n        \n        elif choice == \"4\":\n            branch_name = input(\"Introduce el nombre de la rama a la que deseas cambiar: \")\n            run_command(f\"git checkout {branch_name}\")\n        \n        elif choice == \"5\":\n            run_command(\"git status\")\n        \n        elif choice == \"6\":\n            commit_message = input(\"Introduce el mensaje del commit: \")\n            run_command(\"git add .\")\n            run_command(f'git commit -m \"{commit_message}\"')\n        \n        elif choice == \"7\":\n            run_command(\"git log --oneline\")\n        \n        elif choice == \"8\":\n            branch_name = input(\"Introduce el nombre de la rama a eliminar: \")\n            run_command(f\"git branch -d {branch_name}\")\n        \n        elif choice == \"9\":\n            remote_url = input(\"Introduce la URL del repositorio remoto: \")\n            run_command(f\"git remote add origin {remote_url}\")\n        \n        elif choice == \"10\":\n            run_command(\"git pull origin $(git branch --show-current)\")\n        \n        elif choice == \"11\":\n            run_command(\"git push origin $(git branch --show-current)\")\n        \n        elif choice == \"12\":\n            print(\"¡Hasta luego!\")\n            sys.exit(0)\n        \n        else:\n            print(\"Opción no válida. Inténtalo de nuevo.\")\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/43 - GIT GITHUB CLI/python/mhayhem.py",
    "content": "\n# EJERCICIO:\n# ¡Me voy de viaje al GitHub Universe 2024 de San Francisco!\n#\n# Desarrolla un CLI (Command Line Interface) que permita \n# interactuar con Git y GitHub de manera real desde terminal.\n# \n# El programa debe permitir las siguientes opciones:\n# 1. Establecer el directorio de trabajo\n# 2. Crear un nuevo repositorio\n# 3. Crear una nueva rama\n# 4. Cambiar de rama\n# 5. Mostrar ficheros pendientes de hacer commit\n# 6. Hacer commit (junto con un add de todos los ficheros)\n# 7. Mostrar el historial de commits\n# 8. Eliminar rama\n# 9. Establecer repositorio remoto\n# 10. Hacer pull\n# 11. Hacer push\n# 12. Salir\n#\n# Puedes intentar controlar los diferentes errores.\n\nimport os\nimport subprocess as sb\n\n\nclass Cli:\n    def __init__(self, directory):\n        self.directory = directory\n        self.not_git = \"Git no esta iniciado, inicialice Git primero.\"\n\n    def command(self, *args):\n        result = sb.run(args , cwd=self.directory, capture_output=True, text=True)\n        \n        if result.returncode != 0:\n            return result.stderr.strip()\n        return result.stdout.strip()\n\n    def its_repository(self):\n        repository = self.command(\"git\", \"remote\", \"-v\")\n        return bool(repository)\n\n    def has_commits(self):\n        return self.command(\"git\", \"rev-parse\" \"--verify HEAD\")\n\n    def check_git_init(self):\n        return os.path.isdir(os.path.join(self.directory, \".git\"))\n\n    def init_repository(self):\n        if self.check_git_init():\n            return \"Ya es un repositorio git.\"\n        else:\n            try:\n                return  self.command(\"git\", \"init\")\n            except FileNotFoundError as e:\n                return f\"ERROR: Git no esta instalado o no esta en el PATH.\"\n        \n\n    def create_branch(self, branch: str):\n        if self.check_git_init():\n            if not self.has_commits():\n                return \"El repositorio aún no tiene commits\"\n            return self.command(\"git\", \"branch\", branch)\n        \n        return self.not_git\n\n    def switch_branch(self, branch):\n        if self.check_git_init():\n            branches = self.command(\"git\", \"branch\",\"--format=%(refname:short)\")\n            branches_list = branches.splitlines()\n            if branch not in branches_list:\n                return \"La rama no existe.\"\n            return self.command(\"git\", \"switch\", branch)\n\n    def status(self):\n        if self.check_git_init():\n                return self.command(\"git\", \"status\")\n        return self.not_git\n\n    def add_all(self):\n        if self.check_git_init():\n            if self.command(\"git\", \"status\", \"--porcelain\"):\n                return self.command(\"git\", \"add\", \".\")\n            return \"No hay cambios que añadir.\"\n        return self.not_git\n\n    def commit(self, message: str):\n        if not self.check_git_init():\n            return self.not_git\n        if self.command(\"git\", \"status\", \"--porcelain\"):\n            return self.command(\"git\", \"commit\", \"-m\", message)\n        return \"No hay cambios en el work tree\"\n\n    def logs(self):\n        if self.check_git_init():\n            return self.command(\"git\", \"log\", \"--oneline\")\n\n    def delete_branch(self, branch: str):\n        if self.check_git_init():\n            branches = self.command(\"git\", \"branch\",\"--format=%(refname:shrot)\")\n            branches_list = branches.splitlines()\n            branches_no_merged = self.command(\"git\", \"branch\", \"--no-merged\", \"--format=%(refname:short)\")\n            branches_no_merged_list = branches_no_merged.splitlines()\n            if branch == \"main\" or branch == \"master\":\n                return \"La rama principal no se puede borrar.\"\n            if branch not in branches_list:\n                return \"La rama no existe.\"\n            \n            if branch in branches_no_merged_list:\n                return \"La rama no esta mergeada aún.\"\n            return self.command(\"git\", \"branch\",\"-d\", branch)\n\n    def add_remote(self, url: str):\n        if not self.its_repository():\n            return self.command(\"git\", \"remote\", \"add\", \"origin\", url)\n        return \"Ya existe un repositorio remoto.\"\n\n    def pull(self):\n        if self.its_repository():\n            return self.command(\"git\", \"pull\")\n        return \"No hay repositorio remoto.\"\n\n    def push(self):\n        if self.its_repository():\n            return self.command(\"git\", \"push\")\n        return \"No hay repositorio remoto.\"\n\ndef main():\n    directory_path = input(\"indicar dirección del directorio deonde quiere trabajar (si no existiese se creaara).\\n\")\n    if not os.path.isdir(directory_path):\n        os.mkdir(directory_path)\n    cli = Cli(directory_path)\n    while True:\n        print(\"Opciones del CLI.\")\n        print(\"1. Iniciar git en el directorio actual.\\n\"\n            \"2. Crear rama.\\n\"\n            \"3. Cambiar de rama.\\n\"\n            \"4. Mostrar archivos en workstage.\\n\"\n            \"5. Hacer commit.\\n\"\n            \"6. Mostrar historial de commits.\\n\"\n            \"7. Eliminar rama.\\n\"\n            \"8. Establecer repositorio remeto.\\n\"\n            \"9. Hacer pull.\\n\"\n            \"10. Hacer Push.\\n\"\n            \"11. Cerrar CLI.\")\n\n        choose = int(input())\n        match choose:\n            case 1:\n                print(cli.init_repository())\n            case 2:\n                branch_name = input(\"Nombre de la nueva rama: \").lower()\n                print(cli.create_branch(branch_name))\n            case 3:\n                switch = input(\"Rama a la que cambiar: \").lower()\n                print(cli.switch_branch(switch))\n            case 4:\n                print(cli.status())\n            case 5:\n                message = input(\"Mensaje del commit: \").lower()\n                print(cli.commit(message))\n            case 6:\n                print(cli.logs())\n            case 7:\n                del_branch = input(\"Rama que quiere eliminar: \").lower()\n                print(cli.delete_branch(del_branch))\n            case 8:\n                url = input(\"Url del proyecto a clonar: \")\n                print(cli.add_remote(url))\n            case 9:\n                print(cli.pull())\n            case 10:\n                print(cli.push())\n            case _:\n                print(\"Opción invalida, solo números entre 1 y 11.\")"
  },
  {
    "path": "Roadmap/43 - GIT GITHUB CLI/python/miguelex.py",
    "content": "import os\nimport subprocess\n\nclass GitHubCLI:\n    def __init__(self):\n        self.working_directory = \"\"\n\n    def set_working_directory(self, directory):\n        if os.path.isdir(directory):\n            self.working_directory = directory\n            print(f\"Directorio de trabajo establecido en: {self.working_directory}\")\n        else:\n            print(\"Error: El directorio no existe.\")\n\n    def create_repository(self, name):\n        if not self.working_directory:\n            print(\"Error: Debe establecer un directorio de trabajo primero.\")\n            return\n        os.chdir(self.working_directory)\n        subprocess.run(['git', 'init', name])\n        print(f\"Repositorio '{name}' creado.\")\n\n    def create_branch(self, branch_name):\n        os.chdir(self.working_directory)\n        subprocess.run(['git', 'checkout', '-b', branch_name])\n        print(f\"Rama '{branch_name}' creada.\")\n\n    def change_branch(self, branch_name):\n        os.chdir(self.working_directory)\n        subprocess.run(['git', 'checkout', branch_name])\n        print(f\"Cambiado a la rama '{branch_name}'.\")\n\n    def show_pending_commits(self):\n        os.chdir(self.working_directory)\n        result = subprocess.run(['git', 'status'], capture_output=True, text=True)\n        print(result.stdout)\n\n    def commit_changes(self, message):\n        os.chdir(self.working_directory)\n        subprocess.run(['git', 'add', '.'])\n        subprocess.run(['git', 'commit', '-m', message])\n        print(f\"Cambios comprometidos con el mensaje: '{message}'.\")\n\n    def show_commit_history(self):\n        os.chdir(self.working_directory)\n        result = subprocess.run(['git', 'log'], capture_output=True, text=True)\n        print(result.stdout)\n\n    def delete_branch(self, branch_name):\n        os.chdir(self.working_directory)\n        subprocess.run(['git', 'branch', '-d', branch_name])\n        print(f\"Rama '{branch_name}' eliminada.\")\n\n    def set_remote_repository(self, url):\n        os.chdir(self.working_directory)\n        subprocess.run(['git', 'remote', 'add', 'origin', url])\n        print(f\"Repositorio remoto establecido en: {url}.\")\n\n    def pull(self):\n        os.chdir(self.working_directory)\n        subprocess.run(['git', 'pull'])\n        print(\"Pull realizado correctamente.\")\n\n    def push(self):\n        os.chdir(self.working_directory)\n        subprocess.run(['git', 'push', 'origin', 'HEAD'])\n        print(\"Push realizado correctamente.\")\n\n    def run(self):\n        while True:\n            print(\"\\nSelecciona una opción:\")\n            print(\"1. Establecer el directorio de trabajo\")\n            print(\"2. Crear un nuevo repositorio\")\n            print(\"3. Crear una nueva rama\")\n            print(\"4. Cambiar de rama\")\n            print(\"5. Mostrar ficheros pendientes de hacer commit\")\n            print(\"6. Hacer commit\")\n            print(\"7. Mostrar el historial de commits\")\n            print(\"8. Eliminar rama\")\n            print(\"9. Establecer repositorio remoto\")\n            print(\"10. Hacer pull\")\n            print(\"11. Hacer push\")\n            print(\"12. Salir\")\n\n            option = input(\"Opción: \")\n            if option == '1':\n                dir_name = input(\"Introduce el directorio de trabajo: \")\n                self.set_working_directory(dir_name)\n            elif option == '2':\n                repo_name = input(\"Introduce el nombre del repositorio: \")\n                self.create_repository(repo_name)\n            elif option == '3':\n                branch_name = input(\"Introduce el nombre de la nueva rama: \")\n                self.create_branch(branch_name)\n            elif option == '4':\n                branch_name = input(\"Introduce el nombre de la rama a la que deseas cambiar: \")\n                self.change_branch(branch_name)\n            elif option == '5':\n                self.show_pending_commits()\n            elif option == '6':\n                message = input(\"Introduce el mensaje del commit: \")\n                self.commit_changes(message)\n            elif option == '7':\n                self.show_commit_history()\n            elif option == '8':\n                branch_name = input(\"Introduce el nombre de la rama a eliminar: \")\n                self.delete_branch(branch_name)\n            elif option == '9':\n                url = input(\"Introduce la URL del repositorio remoto: \")\n                self.set_remote_repository(url)\n            elif option == '10':\n                self.pull()\n            elif option == '11':\n                self.push()\n            elif option == '12':\n                print(\"Saliendo...\")\n                break\n            else:\n                print(\"Opción no válida.\")\n\nif __name__ == \"__main__\":\n    cli = GitHubCLI()\n    cli.run()\n"
  },
  {
    "path": "Roadmap/43 - GIT GITHUB CLI/python/mouredev.py",
    "content": "import os\nfrom pdb import run\nimport subprocess\n\n\ndef run_command(command: str):\n\n    try:\n        result = subprocess.run(\n            command,\n            shell=True,\n            check=True,\n            text=True,\n            capture_output=True\n        )\n        print(result.stdout.strip())\n    except subprocess.CalledProcessError as e:\n        print(f\"Error: {e.stderr.strip()}\")\n\n\ndef set_working_directory():\n\n    path = input(\"Introduce el directorio completo de trabajo: \")\n    if os.path.isdir(path):\n        os.chdir(path)\n        print(f\"El directorio de trabajo ha cambiado a: {path}\")\n    else:\n        print(\"El directorio introducido no existe.\")\n\n\ndef create_repository():\n    if os.path.isdir(\".git\"):\n        print(\"Ya existe un repositorio en este directorio.\")\n    else:\n        run_command(\"git init\")\n        run_command(\"git branch -M main\")\n        print(\"Repositorio inicializado.\")\n\n\ndef create_branch():\n    branch_name = input(\"Nombre de la nueva rama: \")\n    run_command(f\"git branch {branch_name}\")\n\n\ndef switch_branch():\n    branch_name = input(\"Nombre de la rama a la que quieres cambiar: \")\n    run_command(f\"git checkout {branch_name}\")\n\n\ndef show_pending_files():\n    run_command(\"git status -s\")\n\n\ndef make_commit():\n    message = input(\"Mensaje para el commit: \")\n    run_command(\"git add .\")\n    run_command(f\"git commit -m \\\"{message}\\\"\")\n\n\ndef show_commit_history():\n    run_command(\"git log --oneline\")\n\n\ndef delete_branch():\n    branch_name = input(\"Nombre de la rama a eliminar: \")\n    run_command(f\"git branch -d {branch_name}\")\n\n\ndef set_remote_repository():\n    remote_url = input(\"URL del repositorio remoto: \")\n    run_command(f\"git remote add origin {remote_url}\")\n    run_command(\"git push -u origin main\")\n\n\ndef make_pull():\n    run_command(\"git pull\")\n\n\ndef make_push():\n    run_command(\"git push\")\n\n\nwhile True:\n\n    print(\"\\nDirectorio actual de trabajo:\")\n    run_command(\"pwd\")\n\n    print(\"\\nGit y GitHub CLI - Opciones:\")\n    print(\"1. Establecer el directorio de trabajo\")\n    print(\"2. Crear un nuevo repositorio\")\n    print(\"3. Crear una nueva rama\")\n    print(\"4. Cambiar de rama\")\n    print(\"5. Mostrar ficheros pendientes de hacer commit\")\n    print(\"6. Hacer commit (+add)\")\n    print(\"7. Mostrar el historial de commits\")\n    print(\"8. Eliminar rama\")\n    print(\"9. Establecer repositorio remoto\")\n    print(\"10. Hacer pull\")\n    print(\"11. Hacer push\")\n    print(\"12. Salir\")\n\n    choice = input(\"Selecciona una opción (1 al 12): \")\n\n    match choice:\n        case \"1\":\n            set_working_directory()\n        case \"2\":\n            create_repository()\n        case \"3\":\n            create_branch()\n        case \"4\":\n            switch_branch()\n        case \"5\":\n            show_pending_files()\n        case \"6\":\n            make_commit()\n        case \"7\":\n            show_commit_history()\n        case \"8\":\n            delete_branch()\n        case \"9\":\n            set_remote_repository()\n        case \"10\":\n            make_pull()\n        case \"11\":\n            make_push()\n        case \"12\":\n            print(\"Saliendo...\")\n            break\n        case _:\n            print(\"Opción no válida.\")\n"
  },
  {
    "path": "Roadmap/43 - GIT GITHUB CLI/python/neslarra.py",
    "content": "r\"\"\"\n EJERCICIO:\n ¡Me voy de viaje al GitHub Universe 2024 de San Francisco!\n\n Desarrolla un CLI (Command Line Interface) que permita \n interactuar con Git y GitHub de manera real desde terminal.\n \n El programa debe permitir las siguientes opciones:\n 1. Establecer el directorio de trabajo\n 2. Crear un nuevo repositorio\n 3. Crear una nueva rama\n 4. Cambiar de rama\n 5. Mostrar ficheros pendientes de hacer commit\n 6. Hacer commit (junto con un add de todos los ficheros)\n 7. Mostrar el historial de commits\n 8. Eliminar rama\n 9. Establecer repositorio remoto\n 10. Hacer pull\n 11. Hacer push\n 12. Salir\n\n Puedes intentar controlar los diferentes errores.\n\"\"\"\nimport git\nimport os\n\n\ndef check_path(repo_path: str) -> bool:\n    return os.path.isdir(repo_path)\n\n\ndef is_repo(repo_path: str) -> bool:\n    return os.path.isdir(repo_path + \"/.git\")\n\n\ndef menu() -> int:\n    print(\"\\nIngresar número de opción\")\n    print(\"\\t1 - Ver ramas\")\n    print(\"\\t2 - Cambiar rama\")\n    print(\"\\t3 - Nueva rama\")\n    print(\"\\t4 - Eliminar rama\")\n    print(\"\\t5 - Ver status\")\n    print(\"\\t6 - Commit\")\n    print(\"\\t7 - Pull\")\n    print(\"\\t8 - Push\")\n    print(\"\\t9 - Log\")\n    print(\"\\t0 - Salir\\n\")\n    while True:\n        opcion = input(\"\\t\\t==> \")\n        if opcion.isnumeric() and int(opcion) in range(0, 10):\n            return int(opcion)\n\n\ndef branch_index() -> int:\n    for ind, r in enumerate(repo.heads):\n        if r == repo.active_branch:\n            print(f\"\\t{ind} - * {r}\")\n        else:\n            print(f\"\\t{ind} - {r}\")\n    while True:\n        repo_ind = input(\"\\nIngrese el número de rama: \")\n        if repo_ind.isnumeric() and int(repo_ind) in range(0, repo.heads.__len__()):\n            return int(repo_ind)\n\n\ndef new_branch():\n    while True:\n        branch_name = input(\"\\nIngrese el nombre de la nueva rama (Enter para cancelar): \")\n        if branch_name.lower() in [str(x).lower() for x in repo.heads]:\n            print(f\"La rama {branch_name} YA existe\")\n        else:\n            break\n    if branch_name:\n        repo.create_head(branch_name)\n        print(f\"Rama {branch_name} creada\")\n\n\ndef delete_branch():\n    deleting_branch = repo.heads[branch_index()]\n    if yes_no(f\"Eliminar {deleting_branch}\"):\n        repo.delete_head(deleting_branch)\n        print(f\"Rama {deleting_branch} eliminada.\")\n\n\ndef change_branch() -> None:\n    global repo\n\n    branch_num = branch_index()\n    if repo.heads[branch_num] != repo.active_branch:\n        repo.heads[branch_num].checkout()\n    print(f\"Rama actual {repo.active_branch}\")\n\n\ndef show_branches() -> None:\n    for r in repo.branches:\n        if r == repo.active_branch:\n            print(\"* \" + str(r))\n        else:\n            print(r)\n\n\ndef show_status() -> None:\n    untracked = repo.untracked_files\n    news_ = repo.index.diff(repo.head.commit)\n    modified = repo.index.diff(None)\n    sep_ = \"\\n\"\n\n    if untracked:\n        print(f\"\\nFicheros 'untracked'\")\n        for r in untracked:\n            print(f\"\\t{str(r).split(sep_)[0]}\")\n\n    if news_:\n        print(f\"\\nFicheros nuevos\")\n        for r in news_:\n            print(f\"\\t{str(r).split(sep_)[0]}\")\n\n    if modified:\n        print(f\"\\nFicheros modificados\")\n        for r in modified:\n            print(f\"\\t{str(r).split(sep_)[0]}\")\n\n\ndef show_log() -> None:\n    current_branch = repo.active_branch\n    for x in list(repo.iter_commits(current_branch, max_count=20)):\n        print(f\"{x.committed_date} - {x.message} - {x}\")\n\n\ndef yes_no(question: str) -> bool:\n    yes_no = input(question + \" (Y/N) => \")\n    return True if yes_no.lower().startswith(\"y\") else False\n\n\ndef new_directory(repo_path: str) -> bool:\n    try:\n        os.mkdir(repo_path)\n        return new_repo(repo_path)\n    except Exception as e:\n        print(str(e))\n        return False\n\n\ndef new_repo(repo_path: str) -> bool:\n    try:\n        _ = git.Repo.init(repo_path, bare=False)\n        return True\n    except Exception as e:\n        print(str(e))\n        return False\n\n\ndef set_repo() -> git.Repo:\n\n    repo_path = input(\"Ingresar directorio: \")\n    if check_path(repo_path):\n        if not is_repo(repo_path):\n            if yes_no(\"Crear nuevo repo?\"):\n                if new_repo(repo_path):\n                    print(f\"Repositorio creado en {repo_path}\")\n                else:\n                    quit(3)\n            else:\n                quit(2)\n    else:\n        if yes_no(\"Crear Directorio y generar repo?\"):\n            new_directory(repo_path)\n        else:\n            quit(1)\n    return git.Repo(repo_path)\n\n\ndef add_commit() -> None:\n    message = input(\"Ingrese detalle del commit: \")\n    message = \"Commit manual\" if not message else message\n    if repo.is_dirty():\n        untracked = repo.untracked_files\n        news_ = repo.index.diff(repo.head.commit)\n        modified = repo.index.diff(None)\n        sep_ = \"\\n\"\n\n        files = [str(r).split(sep_)[0] for r in untracked]\n        if files:\n            repo.index.add(files)\n\n        files = [str(r).split(sep_)[0] for r in news_]\n        if files:\n            repo.index.add(files)\n\n        files = [str(r).split(sep_)[0] for r in modified]\n        if files:\n            repo.index.add(files)\n\n        repo.index.commit(message)\n\n\ndef pull() -> None:\n    origin = repo.remote(name=\"origin\")\n    origin.pull()\n\n\ndef push() -> None:\n    origin = repo.remote(name=\"origin\")\n    origin.push()\n\n\nrepo = set_repo()\nwhile True:\n    option = menu()\n    match option:\n        case  0:\n            # Salir\n            break\n        case 1:\n            # Mostrar ramas\n            show_branches()\n        case 2:\n            # Cambiar de rama\n            change_branch()\n        case 3:\n            # Crear rama\n            new_branch()\n        case 4:\n            delete_branch()\n        case 5:\n            # Ver status\n            show_status()\n        case 6:\n            # Commit\n            add_commit()\n        case 7:\n            # Pull\n            pull()\n        case 8:\n            # Push\n            push()\n        case 9:\n            # Ver commits history\n            show_log()\n"
  },
  {
    "path": "Roadmap/43 - GIT GITHUB CLI/python/pyramsd.py",
    "content": "import os\n\nclass GitCli:\n    def __init__(self):\n        self.directorio = None\n        self.remoto = None\n\n    def mostrar_informacion(self):\n        print(f\"Directorio de trabajo: {self.directorio}\")\n        print(f\"Repositorio remoto: {self.remoto}\")\n        \n    def asignar_directorio(self):\n        self.directorio = input(\"Directorio de trabajo: \")\n        os.chdir(self.directorio)\n\n    def nuevo_repositorio(self):\n        os.system(\"git init\")\n        os.system(\"git branch -m main\")\n\n    def crear_rama(self):\n        nombre_rama = input(\"Nombre de la rama para crear: \")\n        os.system(f\"git branch {nombre_rama}\")\n\n    def cambiar_rama(self):\n        nombre_rama = input(\"Nombre de la rama a cambiar: \")\n        os.system(f\"git checkout {nombre_rama}\")\n\n    def mostrar_ficheros_pendientes(self):\n        os.system(\"git status -s\")\n\n    def hacer_commit(self):\n        os.system(\"git add .\")\n        mensaje = input(\"Mensaje del commit: \")\n        os.system(f\"git commit -m {mensaje}\")\n\n    def historial_commits(self):\n        os.system(\"git log\")\n\n    def eliminar_rama(self):\n        nombre_rama = input(\"Rama a eliminar: \")\n        os.system(f\"git branch -d {nombre_rama}\")\n\n    def establecer_remoto(self):\n        url = input(\"URL del repositorio remoto: \")\n        os.system(f\"git remote add origin {url}\")\n        self.remoto = url\n        os.system(\"git push -u origin main\")\n\n    def hacer_pull(self):\n        os.system(\"git pull origin main\")\n\n    def hacer_push(self):\n        os.system(\"git push\")\n\n    def bucle(self):\n        while True:\n            print(\"\\nOptiones:\")\n            self.mostrar_informacion()\n            print(\"\\nSelecciona una opción: \")\n            print(\"1. Establecer el directorio de trabajo\")\n            print(\"2. Crear un nuevo repositorio\")\n            print(\"3. Crear una nueva rama\")\n            print(\"4. Cambiar de rama\")\n            print(\"5. Mostrar ficheros pendientes de hacer commit\")\n            print(\"6. Hacer commit\")\n            print(\"7. Mostrar el historial de commits\")\n            print(\"8. Eliminar rama\")\n            print(\"9. Establecer repositorio remoto\")\n            print(\"10. Hacer pull\")\n            print(\"11. Hacer push\")\n            print(\"12. Salir\")\n\n            option = input(\"Opción: \")\n            \n            match option:\n                case \"1\":\n                    self.asignar_directorio()\n                case \"2\":\n                    self.nuevo_repositorio()\n                case \"3\":\n                    self.crear_rama()\n                case \"4\":\n                    self.cambiar_rama()\n                case \"5\":\n                    self.mostrar_ficheros_pendientes()\n                case \"6\":\n                    self.hacer_commit()\n                case \"7\":\n                    self.historial_commits()\n                case \"8\":\n                    self.eliminar_rama()\n                case \"9\":\n                    self.establecer_remoto()\n                case \"10\":\n                    self.hacer_pull()    \n                case \"11\":\n                    self.hacer_push()\n                case \"12\":\n                    break\n                case _:\n                    print(\"Opcion incorrecta\")\n\n# Prueba\n\nif __name__ == \"__main__\":\n    cli = GitCli()\n    cli.bucle()\n"
  },
  {
    "path": "Roadmap/43 - GIT GITHUB CLI/python/raulG91.py",
    "content": "import os\nimport subprocess\nclass GitClient:\n    def __init__(self) -> None:\n        self._directory = \"\"\n    def setDirectory(self,path:str):\n        path = path.strip()\n        try:\n            os.chdir(path)\n            self._directory = path \n            print(f'Directorio cambiado a : {self._directory}')   \n        except Exception as err:\n            print(f'Error cambiando directorio: {err}')\n    def _isDirectorySet(self):\n        if self._directory != \"\":\n            return True\n        else:\n            return False        \n    def createNewRepo(self):\n        try:\n            if self._isDirectorySet():\n                subprocess.run(\"git init\",shell=True,check=True,capture_output=True)\n                print(f'Repositorio inicializado en {os.getcwd()}')\n            else:\n                print(\"Debe indicar directorio de trabajo\")    \n        except:\n            print(\"Error inicializando el repositorio\") \n    \n    def createBranch(self,branch_name):\n\n        if self._isDirectorySet():\n\n            #Check if there is any branch \n\n            result = subprocess.run(\"git branch\",shell=True,check=True,capture_output=True)\n            branches = result.stdout.splitlines()\n            \n            if len(branches) == 0:\n                #There is not branch, so create main one first and commit it\n                try:\n                    result = subprocess.run(\"git checkout -b main\",shell= True, capture_output=True,check=True)\n                    subprocess.run(\"git add .\",shell=True,capture_output=True,check=True)\n                    subprocess.run(\"git commit -m \\\"Initial commit\\\"\",shell=True,capture_output=True,check=True)  \n                except:\n                    print(\"Error creando la rama principal\")\n            \n\n            try:  \n                subprocess.run(f'git branch {branch_name}',shell=True,check=True,capture_output=True)\n                print(f'Branch {branch_name} ha sido creada')\n            except:\n                print(f'Error creando la rama {branch_name}')\n        else:\n            print(\"Debe establecer un directorio de trabajo\")    \n    def changeBranch(self,branch_name):\n        if self._isDirectorySet():\n            try:\n                subprocess.run(f'git checkout {branch_name}',shell=True,capture_output=True,check=True)\n                print(f'Rama actual es: {branch_name}')  \n            except:\n                print(f'Error cambiando a rama {branch_name}')   \n        else:\n            print(\"Debe establecer un directorio de trabajo\")                       \n    def getPendingFiles(self):\n        if self._isDirectorySet():\n            try:\n                result = subprocess.run(\"git status\",shell=True,check=True,capture_output=True)       \n                pending = result.stdout.splitlines()       \n                print(pending)\n            except:\n                print(\"Error obteniendo ficheros pendientes\")   \n        else:\n            print(\"Debe establecer un directorio de trabajo\")  \n    def commitChanges(self,message):\n        if self._isDirectorySet():\n            try:\n                subprocess.run(\"git add .\",check=True,shell=True,capture_output=True)\n                subprocess.run(f'git commit -m \"{message}\"',shell=True,capture_output=True,check=True)\n                print(\"Commit ha sido realizado\")\n            except:\n                print(\"Error haciendo commit\") \n        else:\n            print(\"Debe establecer un directorio de trabajo\")             \n    def getCommitHistory(self):\n        if self._isDirectorySet():\n            try:\n                result = subprocess.run(\"git log\",shell=True,check=True,capture_output=True)\n                commit_history = result.stdout.splitlines()    \n                print(commit_history)\n            except:\n                print(\"Error obteniendo lista de commits\")    \n        else:\n            print(\"Debe establecer un directorio de trabajo\")                  \n    def deletebranch(self,branch_name:str):\n\n        branch_name = branch_name.strip()\n        try:\n            subprocess.run(f'git branch -d {branch_name}',shell=True,check=True,capture_output=True)\n            print(f'Rama {branch_name} borrada')\n        except:\n            print(f'Error borrando rama {branch_name}')    \n    def addRemoteRepo(self,repo):\n        \n        if self._isDirectorySet():\n            try:\n                subprocess.run(f'git remote add origin {repo}',check=True,shell=True,capture_output=True)\n                print(f'Repositorio {repo} ha sido establecido')\n            except:\n                print(\"Error añadiendo repositorio remoto\")    \n        else:\n            print(\"Debe establecer directorio de trabajo\")    \n    def push(self):\n        if self._isDirectorySet():\n            try:\n                result = subprocess.run(\"git push -u origin main\",check=True,shell=True,capture_output=True)\n                print(result)\n                print(\"Cambios enviados al repositorio remoto\")\n            except:\n                print(\"Error enviando cambios al repositorio remoto\")  \n        else:\n            print(\"Debe establecer el directorio de trabajo\")     \n    def pull(self):\n        if self._isDirectorySet():\n            try:\n                subprocess.run(\"git pull\",check=True,shell=True,capture_output=True)\n                print(\"Pull ejecutado corectamente\")        \n            except:\n                print(\"Error obteniendo cambios del repositorio remoto\")            \n        else:  \n            print(\"Debe establecer el directorio de trabajo\")           \nclient = GitClient()\n\nwhile True:\n    print(\"Pulsa 1 para establecer directorio de trabajo\")\n    print(\"Pulsa 2 para crear un nuevo repositorio\")\n    print(\"Pulsa 3 para crear una rama\")\n    print(\"Pulsa 4 para cambiar de rama\")\n    print(\"Pulsa 5 para mostrar ficheros pendientes\")\n    print(\"Pulsa 6 para hacer un commit\")\n    print(\"Pulsa 7 para motrar el historial de commit\")\n    print(\"Pulsa 8 para eliminar una rama\")\n    print(\"Pulsa 9 para establecer el repositorio remoto\")\n    print(\"Pulsa 10 para hacer un pull del repositorio remoto\")\n    print(\"Pulsa 11 para hacer un push al repositorio remoto\")\n    print(\"Pulsa 12 para salir\")\n\n    option = int(input('Introduzca opcion: '))\n\n    match option:\n        case 1:     \n            path = input(\"Introduzca directorio de trabajo \")\n            client.setDirectory(path)\n        case 2: client.createNewRepo()   \n        case 3: \n            branch = input(\"Introduzca el nombre para la nueva rama \")\n            client.createBranch(branch_name=branch)\n        case 4: \n            branch = input(\"Introduzca la rama a moverse \")\n            client.changeBranch(branch_name=branch)    \n        case 5:\n            client.getPendingFiles()   \n        case 6:\n            message = input(\"Intorduzca el mensaje para el commit \")\n            message = message.strip()\n            client.commitChanges(message)    \n        case 7: client.getCommitHistory()    \n        case 8: \n            branch = input(\"Introduzca la rama a eliminar \")\n            client.deletebranch(branch)\n        case 9:\n            repo = input(\"Introduzca el repositorio remoto \")\n            client.addRemoteRepo(repo)   \n        case 10:\n            client.pull()    \n        case 11:\n            client.push()    \n        case 12: break\n\n\n        "
  },
  {
    "path": "Roadmap/43 - GIT GITHUB CLI/python/rigo93acosta.py",
    "content": "'''\n * EJERCICIO:\n * ¡Me voy de viaje al GitHub Universe 2024 de San Francisco!\n *\n * Desarrolla un CLI (Command Line Interface) que permita \n * interactuar con Git y GitHub de manera real desde terminal.\n * \n * El programa debe permitir las siguientes opciones:\n * 1. Establecer el directorio de trabajo\n * 2. Crear un nuevo repositorio\n * 3. Crear una nueva rama\n * 4. Cambiar de rama\n * 5. Mostrar ficheros pendientes de hacer commit\n * 6. Hacer commit (junto con un add de todos los ficheros)\n * 7. Mostrar el historial de commits\n * 8. Eliminar rama\n * 9. Establecer repositorio remoto\n * 10. Hacer pull\n * 11. Hacer push\n * 12. Salir\n *\n * Puedes intentar controlar los diferentes errores.\n'''\n\nimport os\nimport subprocess\n\ndef run_command(command: str):\n    \n    try:\n        result = subprocess.run(\n            command, \n            shell=True,\n            check=True,\n            text=True,\n            capture_output=True)\n        print(result.stdout.strip())\n    except subprocess.CalledProcessError as e:\n        print(f\"Error: {e.stderr.strip()}\")\n\n\ndef set_working_directory():\n\n    path = input(\"Introduce la ruta del directorio de trabajo: \")\n    if os.path.isdir(path):\n        os.chdir(path)\n        print(f\"Directorio de trabajo establecido en: {path}\")\n    else:\n        print(f\"El directorio no existe, por favor verifique.\")\n\ndef create_repository():\n\n    if os.path.isdir(\".git\"):\n        print(\"El directorio ya es un repositorio git.\")\n    else:\n        run_command(\"git init\")\n        run_command(\"git branch -M main\")\n        print(\"Repositorio inicializado.\")\n\ndef create_branch(name: str):\n\n    run_command(f\"git branch {name}\")\n\ndef switch_branch(name: str):\n\n    run_command(f\"git switch {name}\")\n\ndef show_pending_files():\n    run_command(\"git status\")\n\ndef make_commit(msg: str):\n    run_command(\"git add .\")\n    run_command(f\"git commit -m \\\"{msg}\\\"\")\n\ndef show_commit_history():\n    run_command(\"git log --oneline\")\n\ndef delete_branch(name: str):\n    run_command(f\"git branch -d {name}\")\n\ndef set_remote_repository(remote_url: str):\n    run_command(f\"git remote add origin {remote_url}\")\n    run_command(\"git push -u origin main\")\n\ndef make_pull():\n    run_command(\"git pull\")\n\ndef make_push():\n    run_command(\"git push\")\n\n\nif __name__ == '__main__':\n\n    \"/home/riacosta/Desktop/Test\"\n    while True:\n        print(\"\\n Git y GitHub CLI\\n\")\n        run_command(\"pwd\")\n\n        print(f\"1-Establecer el directorio de trabajo\")\n        print(f\"2-Crear un nuevo repositorio\")\n        print(f\"3-Crear una nueva rama\")\n        print(f\"4-Cambiar de rama\")\n        print(f\"5-Mostrar ficheros pendientes de hacer commit\")\n        print(f\"6-Hacer commit (junto con un add de todos los ficheros)\")\n        print(f\"7-Mostrar el historial de commits\")\n        print(f\"8-Eliminar rama\")\n        print(f\"9-Establecer repositorio remoto\")\n        print(f\"10-Hacer pull\")\n        print(f\"11-Hacer push\")\n        print(f\"12-Salir\")\n\n        choice = int(input(\"Opción (1-12): \"))\n        \n\n        match choice:\n            case 1:\n                set_working_directory()\n            case 2:\n                create_repository()\n            case 3:\n                branch = input(\"Nombre de la rama: \")\n                create_branch(branch)\n            case 4:\n                branch = input(\"Nombre de la rama a ir: \")\n                switch_branch(branch)\n            case 5:\n                show_pending_files()\n            case 6:\n                msg = input(\"Mensaje del commit: \")\n                make_commit(msg)\n            case 7:\n                show_commit_history()\n            case 8:\n                branch = input(\"Nombre de la rama a eliminar: \")\n                delete_branch(branch)\n            case 9:\n                remote_url = input(\"URL del repositorio remoto: \")\n                set_remote_repository(remote_url)\n            case 10:\n                make_pull()\n            case 11:\n                make_push()\n            case 12:\n                print(\"Saliendo ...\")\n                break\n            case _:\n                print(\"Opción no válida\")"
  },
  {
    "path": "Roadmap/43 - GIT GITHUB CLI/rust/cyberingeniero.rs",
    "content": "/*\n_____________________________________\nhttps://github.com/cyberingeniero\noctubre 2024 - Rust\n_____________________________________\n43 GIT GITHUB CLI\n_____________________________________\n* Desarrolla un CLI (Command Line Interface) que permita\n* interactuar con Git y GitHub de manera real desde terminal.\n*\n* El programa debe permitir las siguientes opciones:\n* 1. Establecer el directorio de trabajo\n* 2. Crear un nuevo repositorio\n* 3. Crear una nueva rama\n* 4. Cambiar de rama\n* 5. Mostrar ficheros pendientes de hacer commit\n* 6. Hacer commit (junto con un add de todos los ficheros)\n* 7. Mostrar el historial de commits\n* 8. Eliminar rama\n* 9. Establecer repositorio remoto\n* 10. Hacer pull\n* 11. Hacer push\n* 12. Salir\n*/\n\n// [dependencies]\n// clap = \"4.0\"\n// git2 = \"0.19\"\n// colored = \"2.0\"\n\n// src/modules/git_commands.rs\n\n// use colored::*;\n// use git2::{BranchType, FetchOptions, PushOptions, RemoteCallbacks, Repository, Sort};\n// use std::io::{self};\n// use std::path::Path;\n// use std::{env, fs};\n\n// pub fn set_directory() {\n//     println!(\n//         \"{}\",\n//         \"Please enter the path to set the working directory:\"\n//             .blue()\n//             .bold()\n//     );\n\n//     let mut input = String::new();\n//     std::io::stdin()\n//         .read_line(&mut input)\n//         .expect(\"Failed to read input\");\n\n//     let path = input.trim();\n//     if env::set_current_dir(Path::new(path)).is_ok() {\n//         println!(\"{}\", format!(\"Changed directory to: {}\", path).green());\n//     } else {\n//         println!(\n//             \"{}\",\n//             \"Failed to change directory. Please check the path.\".red()\n//         );\n//     }\n// }\n\n// pub fn create_new_repo() {\n//     let repo = Repository::init(\".\");\n//     match repo {\n//         Ok(_) => println!(\n//             \"{}\",\n//             \"Initialized new repository in the current directory.\"\n//                 .green()\n//                 .bold()\n//         ),\n//         Err(e) => println!(\n//             \"{}\",\n//             format!(\"Failed to initialize repository: {}\", e).red()\n//         ),\n//     }\n// }\n\n// pub fn create_new_branch() {\n//     let repo = Repository::open(\".\").expect(\"Not a git repository\");\n\n//     println!(\"{}\", \"Enter the name of the new branch:\".blue().bold());\n//     let mut branch_name = String::new();\n//     std::io::stdin()\n//         .read_line(&mut branch_name)\n//         .expect(\"Failed to read input\");\n\n//     let branch_name = branch_name.trim();\n//     let head = repo.head().unwrap();\n//     let target = head.target().unwrap();\n//     let commit = repo.find_commit(target).unwrap();\n//     let _branch_result = repo.branch(branch_name, &commit, false);\n\n//     match _branch_result {\n//         Ok(_) => println!(\n//             \"{}\",\n//             format!(\"Branch '{}' created successfully.\", branch_name).green()\n//         ),\n//         Err(e) => println!(\"{}\", format!(\"Failed to create branch: {}\", e).red()),\n//     }\n// }\n\n// pub fn switch_branch() {\n//     let repo = Repository::open(\".\").expect(\"Not a git repository\");\n\n//     println!(\n//         \"{}\",\n//         \"Enter the name of the branch to switch to:\".blue().bold()\n//     );\n//     let mut branch_name = String::new();\n//     std::io::stdin()\n//         .read_line(&mut branch_name)\n//         .expect(\"Failed to read input\");\n//     let branch_name = branch_name.trim();\n\n//     match repo.set_head(&format!(\"refs/heads/{}\", branch_name)) {\n//         Ok(_) => println!(\n//             \"{}\",\n//             format!(\"Switched to branch '{}'.\", branch_name).green()\n//         ),\n//         Err(e) => println!(\"{}\", format!(\"Failed to switch branches: {}\", e).red()),\n//     }\n// }\n\n// pub fn git_status() {\n//     let repo = Repository::open(\".\").expect(\"Not a git repository\");\n//     let mut status_options = git2::StatusOptions::new();\n//     status_options.include_untracked(true);\n\n//     let statuses = repo.statuses(Some(&mut status_options)).unwrap();\n//     if statuses.is_empty() {\n//         println!(\"{}\", \"No files to commit.\".yellow());\n//     } else {\n//         for entry in statuses.iter() {\n//             let status = entry.status();\n//             let path = entry.path().unwrap();\n//             if status.contains(git2::Status::INDEX_NEW) || status.contains(git2::Status::WT_NEW) {\n//                 println!(\"{}\", format!(\"New file: {}\", path).cyan());\n//             } else if status.contains(git2::Status::INDEX_MODIFIED)\n//                 || status.contains(git2::Status::WT_MODIFIED)\n//             {\n//                 println!(\"{}\", format!(\"Modified file: {}\", path).magenta());\n//             }\n//         }\n//     }\n// }\n\n// pub fn commit_changes() {\n//     let repo = match Repository::open(\".\") {\n//         Ok(repo) => repo,\n//         Err(e) => {\n//             println!(\"Failed to open the repository: {}\", e);\n//             return;\n//         }\n//     };\n\n//     let mut index = match repo.index() {\n//         Ok(index) => index,\n//         Err(e) => {\n//             println!(\"Failed to get index: {}\", e);\n//             return;\n//         }\n//     };\n\n//     // Agregar todos los archivos al índice\n//     if let Err(e) = index.add_all([\"*\"].iter(), git2::IndexAddOption::DEFAULT, None) {\n//         println!(\"Failed to add files to index: {}\", e);\n//         return;\n//     }\n\n//     if let Err(e) = index.write() {\n//         println!(\"Failed to write index: {}\", e);\n//         return;\n//     }\n\n//     let oid = match index.write_tree() {\n//         Ok(oid) => oid,\n//         Err(e) => {\n//             println!(\"Failed to write tree: {}\", e);\n//             return;\n//         }\n//     };\n\n//     let signature = match repo.signature() {\n//         Ok(sig) => sig,\n//         Err(e) => {\n//             println!(\"Failed to get signature: {}\", e);\n//             return;\n//         }\n//     };\n\n//     // Verificar si el repositorio tiene commits previos o es un primer commit (unborn branch)\n//     let parent_commit = match repo.head() {\n//         Ok(head) => match head.peel_to_commit() {\n//             Ok(commit) => Some(commit),\n//             Err(e) => {\n//                 println!(\"Failed to get parent commit: {}\", e);\n//                 return;\n//             }\n//         },\n//         Err(_e) => {\n//             // No hay HEAD, por lo que estamos en el primer commit\n//             None\n//         }\n//     };\n\n//     let tree = match repo.find_tree(oid) {\n//         Ok(tree) => tree,\n//         Err(e) => {\n//             println!(\"Failed to find tree: {}\", e);\n//             return;\n//         }\n//     };\n\n//     println!(\"Enter a commit message:\");\n//     let mut message = String::new();\n//     if let Err(e) = io::stdin().read_line(&mut message) {\n//         println!(\"Failed to read input: {}\", e);\n//         return;\n//     }\n\n//     let message = message.trim();\n//     if message.is_empty() {\n//         println!(\"Commit message cannot be empty.\");\n//         return;\n//     }\n\n//     // Crear el commit: si no hay `parent_commit`, es el primer commit.\n//     let commit_result = if let Some(parent) = parent_commit {\n//         repo.commit(\n//             Some(\"HEAD\"),\n//             &signature,\n//             &signature,\n//             message,\n//             &tree,\n//             &[&parent],\n//         )\n//     } else {\n//         // Primer commit, no hay padres\n//         repo.commit(Some(\"HEAD\"), &signature, &signature, message, &tree, &[])\n//     };\n\n//     match commit_result {\n//         Ok(_) => println!(\"Commit successful with message: {}\", message),\n//         Err(e) => println!(\"Failed to create commit: {}\", e),\n//     }\n// }\n\n// pub fn git_log() {\n//     let repo = Repository::open(\".\").expect(\"Not a git repository\");\n\n//     let mut revwalk = repo.revwalk().unwrap();\n//     revwalk.push_head().unwrap();\n//     revwalk.set_sorting(Sort::TIME).unwrap();\n\n//     for id in revwalk {\n//         let commit = repo.find_commit(id.unwrap()).unwrap();\n//         println!(\n//             \"{}: {}\\n{}: {}\\n{}: {}\\n\",\n//             \"Commit\".bold().blue(),\n//             commit.id(),\n//             \"Author\".bold().yellow(),\n//             commit.author(),\n//             \"Message\".bold().green(),\n//             commit.message().unwrap_or(\"No message\")\n//         );\n//     }\n// }\n\n// pub fn delete_branch() {\n//     let repo = Repository::open(\".\").expect(\"Not a git repository\");\n\n//     println!(\n//         \"{}\",\n//         \"Enter the name of the branch to delete:\".blue().bold()\n//     );\n//     let mut branch_name = String::new();\n//     std::io::stdin()\n//         .read_line(&mut branch_name)\n//         .expect(\"Failed to read input\");\n//     let branch_name = branch_name.trim();\n\n//     let find_result = repo.find_branch(branch_name, BranchType::Local);\n\n//     match find_result {\n//         Ok(mut branch) => {\n//             branch.delete().expect(\"Failed to delete branch\");\n//             println!(\n//                 \"{}\",\n//                 format!(\"Branch '{}' deleted successfully.\", branch_name).green()\n//             );\n//         }\n//         Err(_) => println!(\"{}\", format!(\"Branch '{}' not found.\", branch_name).red()),\n//     }\n// }\n\n// pub fn set_remote() {\n//     let repo = Repository::open(\".\").expect(\"Not a git repository\");\n\n//     println!(\n//         \"{}\",\n//         \"Enter the remote name (e.g., 'origin'):\".blue().bold()\n//     );\n//     let mut remote_name = String::new();\n//     std::io::stdin()\n//         .read_line(&mut remote_name)\n//         .expect(\"Failed to read input\");\n//     let remote_name = remote_name.trim();\n\n//     println!(\n//         \"{}\",\n//         \"Enter the remote URL (e.g., 'https://github.com/user/repo.git'):\"\n//             .blue()\n//             .bold()\n//     );\n//     let mut remote_url = String::new();\n//     std::io::stdin()\n//         .read_line(&mut remote_url)\n//         .expect(\"Failed to read input\");\n//     let remote_url = remote_url.trim();\n\n//     let remote_result = repo.remote(remote_name, remote_url);\n\n//     match remote_result {\n//         Ok(_) => println!(\n//             \"{}\",\n//             format!(\"Remote '{}' set to URL '{}'.\", remote_name, remote_url).green()\n//         ),\n//         Err(e) => println!(\"{}\", format!(\"Failed to set remote: {}\", e).red()),\n//     }\n// }\n\n// pub fn git_pull() {\n//     let repo = Repository::open(\".\").expect(\"Not a git repository\");\n//     let mut remote = repo\n//         .find_remote(\"origin\")\n//         .expect(\"No 'origin' remote found\");\n\n//     let mut callbacks = RemoteCallbacks::new();\n//     callbacks.credentials(|_url, _username_from_url, _allowed_types| {\n//         git2::Cred::ssh_key(\n//             \"git\",\n//             None,\n//             std::path::Path::new(&format!(\"{}/.ssh/id_rsa\", std::env::var(\"HOME\").unwrap())),\n//             None,\n//         )\n//     });\n\n//     let mut fetch_options = FetchOptions::new();\n//     fetch_options.remote_callbacks(callbacks);\n\n//     remote\n//         .fetch(\n//             &[\"refs/heads/main:refs/heads/main\"],\n//             Some(&mut fetch_options),\n//             None,\n//         )\n//         .unwrap();\n//     println!(\"{}\", \"Pull successful\".green());\n// }\n\n// pub fn git_push() {\n//     let repo = Repository::open(\".\").expect(\"Not a git repository\");\n//     let mut remote = repo\n//         .find_remote(\"origin\")\n//         .expect(\"No 'origin' remote found\");\n\n//     let mut callbacks = RemoteCallbacks::new();\n//     callbacks.credentials(|_url, _username_from_url, _allowed_types| {\n//         git2::Cred::ssh_key(\n//             \"git\",\n//             None,\n//             std::path::Path::new(&format!(\"{}/.ssh/id_rsa\", std::env::var(\"HOME\").unwrap())),\n//             None,\n//         )\n//     });\n\n//     let mut push_options = PushOptions::new();\n//     push_options.remote_callbacks(callbacks);\n\n//     remote\n//         .push(&[\"refs/heads/main\"], Some(&mut push_options))\n//         .unwrap();\n//     println!(\"{}\", \"Push successful\".green());\n// }\n\n// pub fn show_repo_path() {\n//     match Repository::discover(\".\") {\n//         Ok(repo) => {\n//             let repo_path = repo.path();\n//             println!(\"Repository path: {}\", repo_path.display());\n//         }\n//         Err(e) => {\n//             println!(\"Not a git repository: {}\", e);\n//         }\n//     }\n// }\n\n// pub fn delete_repo() {\n//     let repo_path = \".git\";\n\n//     if Path::new(repo_path).exists() {\n//         match fs::remove_dir_all(repo_path) {\n//             Ok(_) => println!(\"Repository deleted successfully.\"),\n//             Err(e) => println!(\"Failed to delete repository: {}\", e),\n//         }\n//     } else {\n//         println!(\"No git repository found in this directory.\");\n//     }\n// }\n\n// src/main.rs\nuse clap::{Arg, Command};\n\nmod modules {\n    pub mod git_commands;\n}\n\nuse modules::git_commands;\n\nfn main() {\n    let matches = Command::new(\"GitHub CLI\")\n        .version(\"1.0\")\n        .about(\"Interacts with Git and GitHub\")\n        .arg(Arg::new(\"option\").required(true).index(1))\n        .get_matches();\n\n    let option = matches.get_one::<String>(\"option\").unwrap();\n\n    match option.as_str() {\n        \"set-dir\" => git_commands::set_directory(),\n        \"new-repo\" => git_commands::create_new_repo(),\n        \"new-branch\" => git_commands::create_new_branch(),\n        \"switch-branch\" => git_commands::switch_branch(),\n        \"status\" => git_commands::git_status(),\n        \"commit\" => git_commands::commit_changes(),\n        \"log\" => git_commands::git_log(),\n        \"delete-branch\" => git_commands::delete_branch(),\n        \"set-remote\" => git_commands::set_remote(),\n        \"pull\" => git_commands::git_pull(),\n        \"push\" => git_commands::git_push(),\n        \"exit\" => println!(\"Exiting...\"),\n        \"show-repo-path\" => git_commands::show_repo_path(),\n        \"delete-repo\" => git_commands::delete_repo(),\n        _ => println!(\"Invalid option!\"),\n    }\n}\n"
  },
  {
    "path": "Roadmap/43 - GIT GITHUB CLI/rust/kenysdev.rs",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - Rust\n_____________________________________\n43 GIT GITHUB CLI\n-------------------------------------\n* EJERCICIO:\n * ¡Me voy de viaje al GitHub Universe 2024 de San Francisco!\n *\n * Desarrolla un CLI (Command Line Interface) que permita \n * interactuar con Git y GitHub de manera real desde terminal.\n * \n * El programa debe permitir las siguientes opciones:\n * 1. Establecer el directorio de trabajo\n * 2. Crear un nuevo repositorio\n * 3. Crear una nueva rama\n * 4. Cambiar de rama\n * 5. Mostrar ficheros pendientes de hacer commit\n * 6. Hacer commit (junto con un add de todos los ficheros)\n * 7. Mostrar el historial de commits\n * 8. Eliminar rama\n * 9. Establecer repositorio remoto\n * 10. Hacer pull\n * 11. Hacer push\n * 12. Salir\n *\n * Puedes intentar controlar los diferentes errores.\n*/\n\nuse std::env;\nuse std::io::{self, Write};\nuse std::path::Path;\nuse std::process::Command;\n\nconst MENU: &str = r#\"\nComandos Git::\n------------------------------------------------------------\n| 1. Establecer directorio       | 7. Historial de commits |  \n| 2. Crear repositorio           | 8. Eliminar rama        |\n| 3. Crear rama                  | 9. Configurar remoto    |\n| 4. Cambiar rama                | 10. pull                | \n| 5. Mostrar cambios pendientes  | 11. push                | \n| 6. 'add' + 'commit'            | 12. Salir               | \n------------------------------------------------------------\"#;\n\nconst COMMANDS: &[GitCommand] = &[\n    GitCommand { name: \"Establecer directorio\", command: \"cd\", prompt: Some(\"Ruta: \") },\n    GitCommand { name: \"Crear repositorio\", command: \"git init && git branch -M main\", prompt: None },\n    GitCommand { name: \"Crear rama\", command: \"git branch -c\", prompt: Some(\"Nombre: \") },\n    GitCommand { name: \"Cambiar rama\", command: \"git switch\", prompt: Some(\"Nombre: \") },\n    GitCommand { name: \"Mostrar cambios\", command: \"git status -s\", prompt: None },\n    GitCommand { name: \"Commit\", command: \"git add . && git commit -m\", prompt: Some(\"Mensaje: \") },\n    GitCommand { name: \"Historial\", command: \"git log --oneline\", prompt: None },\n    GitCommand { name: \"Eliminar rama\", command: \"git branch -d\", prompt: Some(\"Nombre: \") },\n    GitCommand { name: \"Configurar remoto\", command: \"git remote add origin\", prompt: Some(\"URL: \") },\n    GitCommand { name: \"Pull\", command: \"git pull origin\", prompt: Some(\"rama: \") },\n    GitCommand { name: \"Push\", command: \"git push origin\", prompt: Some(\"rama: \") },\n];\n\nfn run_command(command: &str) {\n    let (program, args) = if cfg!(windows) {\n        (\"cmd\", vec![\"/C\", command])\n    } else {\n        (\"sh\", vec![\"-c\", command])\n    };\n\n    match Command::new(program).args(&args).output() {\n        Ok(output) => {\n            if output.status.success() {\n                println!(\"✅: {}\", String::from_utf8_lossy(&output.stdout).trim());\n            } else {\n                println!(\"❌: {}\", String::from_utf8_lossy(&output.stderr).trim());\n            }\n        }\n        Err(e) => println!(\"❌: Error ejecutando el comando: {}\", e),\n    }\n}\n\nfn read_input(prompt: &str) -> String {\n    print!(\"{}\", prompt);\n    io::stdout().flush().unwrap();\n    let mut input = String::new();\n    io::stdin().read_line(&mut input).unwrap();\n    input.trim().to_string()\n}\n\nstruct GitCommand {\n    name: &'static str,\n    command: &'static str,\n    prompt: Option<&'static str>,\n}\n\nfn execute(cmd: &GitCommand) {\n    println!(\"\\n=> {}\", cmd.name);\n    println!(\"--------------------\");\n    match (cmd.command, cmd.prompt) {\n        (\"cd\", Some(prompt)) => {\n            let path = read_input(prompt);\n            if Path::new(&path).is_dir() {\n                env::set_current_dir(&path)\n                    .unwrap_or_else(|_| println!(\"Error cambiando directorio\"));\n            } else {\n                println!(\"Esta ruta no existe.\");\n            }\n        },\n        (cmd, Some(prompt)) => run_command(&format!(\"{} {}\", cmd, read_input(prompt))),\n        (cmd, None) => run_command(cmd),\n    }\n}\n\nfn main() {\n    loop {\n        println!(\"{}\", MENU);\n        println!(\"Directorio actual: {}\", env::current_dir().unwrap().display());\n        println!(\"--------------------\");\n        match read_input(\"\\nOpción: \").parse::<usize>().ok() {\n            Some(n) if n == COMMANDS.len() + 1 => break,\n            Some(n) if n > 0 && n <= COMMANDS.len() => execute(&COMMANDS[n - 1]),\n            _ => println!(\"Opción inválida\"),\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/43 - GIT GITHUB CLI/sql/Nicojsuarez2.sql",
    "content": "# #43 GIT GITHUB CLI\n> #### Dificultad: Difícil | Publicación: 21/10/24 | Corrección: 04/11/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * ¡Me voy de viaje al GitHub Universe 2024 de San Francisco!\n *\n * Desarrolla un CLI (Command Line Interface) que permita \n * interactuar con Git y GitHub de manera real desde terminal.\n * \n * El programa debe permitir las siguientes opciones:\n * 1. Establecer el directorio de trabajo\n * 2. Crear un nuevo repositorio\n * 3. Crear una nueva rama\n * 4. Cambiar de rama\n * 5. Mostrar ficheros pendientes de hacer commit\n * 6. Hacer commit (junto con un add de todos los ficheros)\n * 7. Mostrar el historial de commits\n * 8. Eliminar rama\n * 9. Establecer repositorio remoto\n * 10. Hacer pull\n * 11. Hacer push\n * 12. Salir\n *\n * Puedes intentar controlar los diferentes errores.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/43 - GIT GITHUB CLI/typescript/miguelex.ts",
    "content": "import * as child_process from 'child_process';\nimport * as readline from 'readline';\nimport * as fs from 'fs';\n\nclass GitHubCLI {\n    private workingDirectory: string = '';\n\n    public setWorkingDirectory(dir: string) {\n        if (fs.existsSync(dir) && fs.lstatSync(dir).isDirectory()) {\n            this.workingDirectory = dir;\n            console.log(`Directorio de trabajo establecido en: ${this.workingDirectory}`);\n        } else {\n            console.log(\"Error: El directorio no existe.\");\n        }\n    }\n\n    public createRepository(name: string) {\n        if (!this.workingDirectory) {\n            console.log(\"Error: Debe establecer un directorio de trabajo primero.\");\n            return;\n        }\n        this.executeCommand(`cd ${this.workingDirectory} && git init ${name}`);\n    }\n\n    public createBranch(branchName: string) {\n        this.executeCommand(`cd ${this.workingDirectory} && git checkout -b ${branchName}`);\n    }\n\n    public changeBranch(branchName: string) {\n        this.executeCommand(`cd ${this.workingDirectory} && git checkout ${branchName}`);\n    }\n\n    public showPendingCommits() {\n        this.executeCommand(`cd ${this.workingDirectory} && git status`);\n    }\n\n    public commitChanges(message: string) {\n        this.executeCommand(`cd ${this.workingDirectory} && git add . && git commit -m \"${message}\"`);\n    }\n\n    public showCommitHistory() {\n        this.executeCommand(`cd ${this.workingDirectory} && git log`);\n    }\n\n    public deleteBranch(branchName: string) {\n        this.executeCommand(`cd ${this.workingDirectory} && git branch -d ${branchName}`);\n    }\n\n    public setRemoteRepository(url: string) {\n        this.executeCommand(`cd ${this.workingDirectory} && git remote add origin ${url}`);\n    }\n\n    public pull() {\n        this.executeCommand(`cd ${this.workingDirectory} && git pull`);\n    }\n\n    public push() {\n        this.executeCommand(`cd ${this.workingDirectory} && git push origin HEAD`);\n    }\n\n    private executeCommand(command: string) {\n        child_process.exec(command, (error, stdout, stderr) => {\n            if (error) {\n                console.log(`Error: ${stderr}`);\n            } else {\n                console.log(stdout);\n            }\n        });\n    }\n\n    public run() {\n        const rl = readline.createInterface({\n            input: process.stdin,\n            output: process.stdout\n        });\n\n        const askQuestion = () => {\n            console.log(\"\\nSelecciona una opción:\");\n            console.log(\"1. Establecer el directorio de trabajo\");\n            console.log(\"2. Crear un nuevo repositorio\");\n            console.log(\"3. Crear una nueva rama\");\n            console.log(\"4. Cambiar de rama\");\n            console.log(\"5. Mostrar ficheros pendientes de hacer commit\");\n            console.log(\"6. Hacer commit\");\n            console.log(\"7. Mostrar el historial de commits\");\n            console.log(\"8. Eliminar rama\");\n            console.log(\"9. Establecer repositorio remoto\");\n            console.log(\"10. Hacer pull\");\n            console.log(\"11. Hacer push\");\n            console.log(\"12. Salir\");\n\n            rl.question('Opción: ', (option) => {\n                switch (option) {\n                    case '1':\n                        rl.question('Introduce el directorio de trabajo: ', (dir) => {\n                            this.setWorkingDirectory(dir);\n                            askQuestion();\n                        });\n                        break;\n                    case '2':\n                        rl.question('Introduce el nombre del repositorio: ', (name) => {\n                            this.createRepository(name);\n                            askQuestion();\n                        });\n                        break;\n                    case '3':\n                        rl.question('Introduce el nombre de la nueva rama: ', (branchName) => {\n                            this.createBranch(branchName);\n                            askQuestion();\n                        });\n                        break;\n                    case '4':\n                        rl.question('Introduce el nombre de la rama a la que deseas cambiar: ', (branchName) => {\n                            this.changeBranch(branchName);\n                            askQuestion();\n                        });\n                        break;\n                    case '5':\n                        this.showPendingCommits();\n                        askQuestion();\n                        break;\n                    case '6':\n                        rl.question('Introduce el mensaje del commit: ', (message) => {\n                            this.commitChanges(message);\n                            askQuestion();\n                        });\n                        break;\n                    case '7':\n                        this.showCommitHistory();\n                        askQuestion();\n                        break;\n                    case '8':\n                        rl.question('Introduce el nombre de la rama a eliminar: ', (branchName) => {\n                            this.deleteBranch(branchName);\n                            askQuestion();\n                        });\n                        break;\n                    case '9':\n                        rl.question('Introduce la URL del repositorio remoto: ', (url) => {\n                            this.setRemoteRepository(url);\n                            askQuestion();\n                        });\n                        break;\n                    case '10':\n                        this.pull();\n                        askQuestion();\n                        break;\n                    case '11':\n                        this.push();\n                        askQuestion();\n                        break;\n                    case '12':\n                        console.log(\"Saliendo...\");\n                        rl.close();\n                        break;\n                    default:\n                        console.log(\"Opción no válida.\");\n                        askQuestion();\n                }\n            });\n        };\n        askQuestion();\n    }\n}\n\nconst cli = new GitHubCLI();\ncli.run();\n"
  },
  {
    "path": "Roadmap/43 - GIT GITHUB CLI/vb.net/kenysdev.vb",
    "content": "' _____________________________________\n' https://github.com/kenysdev\n' 2024 - vb.net\n' _____________________________________\n' 43 GIT GITHUB CLI\n' ------------------------------------\n'* EJERCICIO\n' * ¡Me voy de viaje al GitHub Universe 2024 de San Francisco!\n' *\n' * Desarrolla un CLI (Command Line Interface) que permita \n' * interactuar con Git y GitHub de manera real desde terminal.\n' * \n' * El programa debe permitir las siguientes opciones:\n' * 1. Establecer el directorio de trabajo\n' * 2. Crear un nuevo repositorio\n' * 3. Crear una nueva rama\n' * 4. Cambiar de rama\n' * 5. Mostrar ficheros pendientes de hacer commit\n' * 6. Hacer commit (junto con un add de todos los ficheros)\n' * 7. Mostrar el historial de commits\n' * 8. Eliminar rama\n' * 9. Establecer repositorio remoto\n' * 10. Hacer pull\n' * 11. Hacer push\n' * 12. Salir\n\nImports System.IO\n\nModule GitCommandTool\n    Private ReadOnly MENU As String = \" Comandos Git:: \" & vbCrLf &\n        \"------------------------------------------------------------\" & vbCrLf &\n        \"| 1. Establecer directorio       | 7. Historial de commits |\" & vbCrLf &\n        \"| 2. Crear repositorio           | 8. Eliminar rama        |\" & vbCrLf &\n        \"| 3. Crear rama                  | 9. Configurar remoto    |\" & vbCrLf &\n        \"| 4. Cambiar rama                | 10. pull                |\" & vbCrLf &\n        \"| 5. Mostrar cambios pendientes  | 11. push                |\" & vbCrLf &\n        \"| 6. 'add' + 'commit'            | 12. Salir               |\" & vbCrLf &\n        \"------------------------------------------------------------\"\n\n    Private Class GitCommand\n        Public Property Name As String\n        Public Property Command As String\n        Public Property Prompt As String\n\n        Public Sub New(name As String, command As String, Optional prompt As String = Nothing)\n            Me.Name = name\n            Me.Command = command\n            Me.Prompt = prompt\n        End Sub\n    End Class\n\n    Private ReadOnly COMMANDS As GitCommand() = {\n        New GitCommand(\"Establecer directorio\", \"cd\", \"Ruta: \"),\n        New GitCommand(\"Crear repositorio\", \"git init && git branch -M main\"),\n        New GitCommand(\"Crear rama\", \"git branch -c\", \"Nombre: \"),\n        New GitCommand(\"Cambiar rama\", \"git switch\", \"Nombre: \"),\n        New GitCommand(\"Mostrar cambios\", \"git status -s\"),\n        New GitCommand(\"Commit\", \"git add . && git commit -m\", \"Mensaje: \"),\n        New GitCommand(\"Historial\", \"git log --oneline\"),\n        New GitCommand(\"Eliminar rama\", \"git branch -d\", \"Nombre: \"),\n        New GitCommand(\"Configurar remoto\", \"git remote add origin\", \"URL: \"),\n        New GitCommand(\"Pull\", \"git pull origin\", \"rama: \"),\n        New GitCommand(\"Push\", \"git push origin\", \"rama: \"),\n        New GitCommand(\"Exit\", \"exit\")\n    }\n\n    Private Function RunCommand(command As String) As Boolean\n        Try\n            Dim processInfo As New ProcessStartInfo(\"cmd.exe\", $\"/c {command}\")\n            processInfo.RedirectStandardOutput = True\n            processInfo.RedirectStandardError = True\n            processInfo.UseShellExecute = False\n            processInfo.CreateNoWindow = True\n\n            Using process As Process = Process.Start(processInfo)\n                Dim output As String = process.StandardOutput.ReadToEnd()\n                Dim error_ As String = process.StandardError.ReadToEnd()\n                process.WaitForExit()\n\n                If Not String.IsNullOrEmpty(output) Then\n                    Console.ForegroundColor = ConsoleColor.Green\n                    Console.WriteLine($\"'^': {output.Trim()}\")\n                    Console.ResetColor()\n                End If\n\n                If Not String.IsNullOrEmpty(error_) Then\n                    Console.ForegroundColor = ConsoleColor.Red\n                    Console.WriteLine($\"'X': {error_.Trim()}\")\n                    Console.ResetColor()\n                End If\n\n                Return process.ExitCode = 0\n            End Using\n        Catch ex As Exception\n            Console.ForegroundColor = ConsoleColor.Red\n            Console.WriteLine($\"❌: Error ejecutando el comando: {ex.Message}\")\n            Console.ResetColor()\n            Return False\n        End Try\n    End Function\n\n    Private Function ReadInput(prompt As String) As String\n        Console.Write(prompt)\n        Return Console.ReadLine()?.Trim()\n    End Function\n\n    Private Sub Execute(cmd As GitCommand)\n        Console.WriteLine($\"{vbCrLf}=> {cmd.Name}\")\n        Console.WriteLine(\"--------------------\")\n        If cmd.Name = \"Exit\" Then\n            Console.WriteLine(\"Bye\")\n            End\n        End If\n\n        If Not String.IsNullOrEmpty(cmd.Prompt) Then\n            Dim userInput As String = ReadInput(cmd.Prompt)\n\n            If cmd.Name = \"Establecer directorio\" Then\n                If Directory.Exists(userInput) Then\n                    Try\n                        Environment.CurrentDirectory = userInput\n                        Console.WriteLine($\"Directorio cambiado a: {userInput}\")\n                    Catch ex As Exception\n                        Console.WriteLine($\"Error cambiando directorio: {ex.Message}\")\n                    End Try\n                Else\n                    Console.WriteLine(\"Esta ruta no existe.\")\n                End If\n            Else\n                RunCommand($\"{cmd.Command} {userInput}\")\n            End If\n        Else\n            RunCommand(cmd.Command)\n        End If\n    End Sub\n\n    Sub Main()\n        While True\n            Console.WriteLine(MENU)\n            Console.WriteLine($\"Directorio actual: {Environment.CurrentDirectory}\")\n            Console.WriteLine(\"--------------------\")\n\n            Dim input As String = ReadInput(vbCrLf & \"Opción: \")\n            Dim option_ As Integer\n\n            If Integer.TryParse(input, option_) AndAlso option_ > 0 AndAlso option_ <= COMMANDS.Length Then\n                If option_ = COMMANDS.Length + 1 Then\n                    Exit While\n                Else\n                    Execute(COMMANDS(option_ - 1))\n                End If\n            Else\n                Console.WriteLine(\"Opción inválida\")\n            End If\n        End While\n    End Sub\nEnd Module\n"
  },
  {
    "path": "Roadmap/44 - CUENTA ATRÁS MOUREDEV PRO/c#/hequebo.cs",
    "content": "class Timer\n{\n    private DateTime _targetDate;\n    private Thread _thread;\n\n    public Timer(DateTime targetDate)\n    {\n        _targetDate = targetDate.ToUniversalTime();\n        _thread = new Thread(CountDown);\n    }\n    public void Start()\n    {\n        _thread.Start();\n    }\n    void CountDown()\n    {\n        bool reached = false;\n        var currentDate = DateTime.UtcNow;\n        do\n        {\n            var remainingTime = _targetDate.Subtract(currentDate);\n            Console.Clear();\n            if (remainingTime.TotalSeconds <= 0)\n                reached = true;\n            else\n            {\n                int days = remainingTime.Days;\n                int hours = remainingTime.Hours;\n                int minutes = remainingTime.Minutes;\n                int seconds = remainingTime.Seconds;\n\n\n                Console.WriteLine(\"---Tiempo Restante---\");\n                Console.WriteLine($\"{days} días, {hours} horas, {minutes} minutos, {seconds} segundos\");\n\n                Thread.Sleep(1000);\n                currentDate = DateTime.UtcNow;\n            }\n\n        } while (!reached);\n        Console.WriteLine(\"¡Cuenta atrás finalizada!\");\n    }\n\n}\nclass Program\n{\n    static void Main(string[] args)\n    {\n        Timer timer = new Timer(new DateTime(2024, 12, 20, 13, 1, 00).ToUniversalTime());\n        timer.Start();\n    }\n    \n}"
  },
  {
    "path": "Roadmap/44 - CUENTA ATRÁS MOUREDEV PRO/c#/kenysdev.cs",
    "content": "namespace exs44;\n/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - C#\n_____________________________________\n44 CUENTA ATRÁS MOUREDEV PRO\n------------------------------------\n\n* EJERCICIO:\n * ¡El 12 de noviembre lanzo mouredev pro!\n * El campus de la comunidad para estudiar programación de\n * una manera diferente: https://mouredev.pro\n *\n * Crea un programa que funcione como una cuenta atrás.\n *\n * - Al iniciarlo tendrás que indicarle el día, mes, año,\n *   hora, minuto y segundo en el que quieres que finalice.\n * - Deberás transformar esa fecha local a UTC.\n * - La cuenta atrás comenzará y mostrará los días, horas,\n *   minutos y segundos que faltan.\n * - Se actualizará cada segundo y borrará la terminal en\n *   cada nueva representación del tiempo restante.\n * - Una vez finalice, mostrará un mensaje.\n * - Realiza la ejecución, si el lenguaje lo soporta, en\n *   un hilo independiente.\n*/\n\nusing System;\nusing System.Threading;\n\nclass ReverseTimer\n{\n    private readonly DateTime _endDate;\n    private readonly Thread _countdownThread;\n    private volatile bool _isRunning = true;\n\n    public ReverseTimer(string endDate)\n    {\n        _endDate = DateTime.Parse(endDate).ToUniversalTime();\n        _countdownThread = new Thread(RunCountdown);\n    }\n\n    private TimeSpan TimeRemaining \n        => _endDate > DateTime.UtcNow ? _endDate - DateTime.UtcNow : TimeSpan.Zero;\n\n    private void RunCountdown()\n    {\n        while (_isRunning && TimeRemaining > TimeSpan.Zero)\n        {\n            Console.Clear();\n            Console.WriteLine(\"Tiempo restante:\");\n            Console.WriteLine(FormatTimeRemaining());\n\n            Thread.Sleep(1000);\n        }\n\n        if (TimeRemaining <= TimeSpan.Zero)\n        {\n            Console.WriteLine(\"¡Cuenta atrás finalizada!\");\n        }\n    }\n\n    private string FormatTimeRemaining()\n    {\n        var delta = TimeRemaining;\n        return $\"{delta.Days} dias, {delta.Hours} horas, {delta.Minutes} minutos, {delta.Seconds} segundos.\";\n    }\n\n    public void Start()\n    {\n        _countdownThread.Start();\n    }\n\n    public void Stop()\n    {\n        _isRunning = false;\n        _countdownThread.Join();\n    }\n\n    public static void Main()\n    {\n        var endDate = \"2024-12-31T23:59:59.999999\";\n        var timer = new ReverseTimer(endDate);\n        \n        timer.Start();\n        //timer.Stop();\n    }\n}\n"
  },
  {
    "path": "Roadmap/44 - CUENTA ATRÁS MOUREDEV PRO/c++/hectorio23.cpp",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\n#include <iostream>\n#include <iomanip>\n#include <chrono>\n#include <thread>\n#include <ctime>\n\n// Limpia la pantalla\nvoid clearScreen() {\n#ifdef _WIN32\n    system(\"cls\");\n#else\n    system(\"clear\");\n#endif\n}\n\n// Función para calcular la diferencia entre dos tiempos\nvoid countdown(std::chrono::system_clock::time_point target) {\n    while (true) {\n        auto now = std::chrono::system_clock::now();\n        auto duration = std::chrono::duration_cast<std::chrono::seconds>(target - now);\n\n        if (duration.count() <= 0) {\n            clearScreen();\n            std::cout << \"¡Cuenta atrás finalizada!\" << std::endl;\n            break;\n        }\n\n        // Desglosamos días, horas, minutos y segundos\n        int days = duration.count() / (24 * 3600);\n        int hours = (duration.count() % (24 * 3600)) / 3600;\n        int minutes = (duration.count() % 3600) / 60;\n        int seconds = duration.count() % 60;\n\n        clearScreen();\n        std::cout << \"Tiempo restante: \" << days << \" días, \" << hours << \" horas, \"\n                  << minutes << \" minutos, \" << seconds << \" segundos\" << std::endl;\n        std::this_thread::sleep_for(std::chrono::seconds(1));\n    }\n}\n\nint main() {\n    int day, month, year, hour, minute, second;\n\n    std::cout << \"Día: \";\n    std::cin >> day;\n    std::cout << \"Mes: \";\n    std::cin >> month;\n    std::cout << \"Año: \";\n    std::cin >> year;\n    std::cout << \"Hora: \";\n    std::cin >> hour;\n    std::cout << \"Minuto: \";\n    std::cin >> minute;\n    std::cout << \"Segundo: \";\n    std::cin >> second;\n\n    // Crear la fecha objetivo en UTC\n    std::tm timeinfo = {};\n    timeinfo.tm_year = year - 1900; // Año desde 1900\n    timeinfo.tm_mon = month - 1;   // Meses desde 0\n    timeinfo.tm_mday = day;\n    timeinfo.tm_hour = hour;\n    timeinfo.tm_min = minute;\n    timeinfo.tm_sec = second;\n\n    auto target_time = std::chrono::system_clock::from_time_t(std::mktime(&timeinfo));\n    std::cout << \"Fecha objetivo (UTC): \" << std::put_time(&timeinfo, \"%Y-%m-%d %H:%M:%S\") << std::endl;\n\n    // Iniciar la cuenta atrás\n    std::thread countdownThread(countdown, target_time);\n    countdownThread.join();\n\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/44 - CUENTA ATRÁS MOUREDEV PRO/ejercicio.md",
    "content": "# #44 CUENTA ATRÁS MOUREDEV PRO\n> #### Dificultad: Fácil | Publicación: 04/11/24 | Corrección: 11/11/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * ¡El 12 de noviembre lanzo mouredev pro!\n * El campus de la comunidad para estudiar programación de\n * una manera diferente: https://mouredev.pro\n *\n * Crea un programa que funcione como una cuenta atrás.\n *\n * - Al iniciarlo tendrás que indicarle el día, mes, año,\n *   hora, minuto y segundo en el que quieres que finalice.\n * - Deberás transformar esa fecha local a UTC.\n * - La cuenta atrás comenzará y mostrará los días, horas,\n *   minutos y segundos que faltan.\n * - Se actualizará cada segundo y borrará la terminal en\n *   cada nueva representación del tiempo restante.\n * - Una vez finalice, mostrará un mensaje.\n * - Realiza la ejecución, si el lenguaje lo soporta, en\n *   un hilo independiente.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/44 - CUENTA ATRÁS MOUREDEV PRO/go/hozlucas28.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"os/exec\"\n\t\"sync\"\n\t\"time\"\n)\n\n/* -------------------------------------------------------------------------- */\n/*                                   STRUCTS                                  */\n/* -------------------------------------------------------------------------- */\n\ntype ITimer interface {\n\tGetEndDate() *time.Time\n\tTimerEnded() bool\n\tUpdateTimer(from time.Time, to time.Time)\n\tToString() string\n}\n\ntype timer struct {\n\tDays    int64\n\tHours   int64\n\tMinutes int64\n\tSeconds int64\n\n\tendDate time.Time\n\t_       struct{}\n}\n\nfunc NewTimer(from time.Time, to time.Time) ITimer {\n\tvar timer timer = timer{endDate: to}\n\n\tvar unixStartDate int64 = from.Unix()\n\tvar unixEndDate int64 = to.Unix()\n\n\tvar remainingTime int64 = unixEndDate - unixStartDate\n\tif remainingTime <= 0 {\n\t\treturn &timer\n\t}\n\n\ttimer.Days = remainingTime / 86400\n\tremainingTime -= timer.Days * 86400\n\n\ttimer.Hours = remainingTime / 3600\n\tremainingTime -= timer.Hours * 3600\n\n\ttimer.Minutes = remainingTime / 60\n\tremainingTime -= timer.Minutes * 60\n\n\ttimer.Seconds = remainingTime\n\n\treturn &timer\n}\n\nfunc (timer *timer) GetEndDate() *time.Time {\n\treturn &timer.endDate\n}\n\nfunc (timer *timer) TimerEnded() bool {\n\treturn timer.Days == 0 && timer.Hours == 0 && timer.Minutes == 0 && timer.Seconds == 0\n}\n\nfunc (timer *timer) UpdateTimer(from time.Time, to time.Time) {\n\ttimer.endDate = to\n\n\tvar unixStartDate int64 = from.Unix()\n\tvar unixEndDate int64 = to.Unix()\n\n\tvar remainingTime int64 = unixEndDate - unixStartDate\n\tif remainingTime <= 0 {\n\t\ttimer.Days = 0\n\t\ttimer.Hours = 0\n\t\ttimer.Minutes = 0\n\t\ttimer.Seconds = 0\n\t\treturn\n\t}\n\n\ttimer.Days = remainingTime / 86400\n\tremainingTime -= timer.Days * 86400\n\n\ttimer.Hours = remainingTime / 3600\n\tremainingTime -= timer.Hours * 3600\n\n\ttimer.Minutes = remainingTime / 60\n\tremainingTime -= timer.Minutes * 60\n\n\ttimer.Seconds = remainingTime\n}\n\nfunc (timer *timer) ToString() string {\n\treturn fmt.Sprintf(\n\t\t\"[ %06d days | %02d hours | %02d minutes | %02d seconds ]\",\n\t\ttimer.Days,\n\t\ttimer.Hours,\n\t\ttimer.Minutes,\n\t\ttimer.Seconds,\n\t)\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\nfunc main() {\n\tvar wg sync.WaitGroup\n\n\twg.Add(1)\n\n\tgo func() {\n\t\tvar startDate time.Time = time.Now()\n\t\tvar endDate time.Time = time.Date(2024, time.December, 25, 0, 0, 0, 0, time.Local)\n\t\tvar timer ITimer = NewTimer(startDate, endDate)\n\n\t\tvar command = exec.Command(\"clear\")\n\t\tcommand.Stdout = os.Stdout\n\t\tcommand.Run()\n\n\t\tfmt.Printf(\n\t\t\t\"> Time remaining for %s: %s.\\n\", endDate, timer.ToString(),\n\t\t)\n\n\t\tfor !timer.TimerEnded() {\n\t\t\ttime.Sleep(time.Second)\n\n\t\t\tstartDate = time.Now()\n\t\t\ttimer.UpdateTimer(startDate, *timer.GetEndDate())\n\n\t\t\tcommand = exec.Command(\"clear\")\n\t\t\tcommand.Stdout = os.Stdout\n\t\t\tcommand.Run()\n\n\t\t\tfmt.Printf(\n\t\t\t\t\"> Time remaining for %s: %s.\\n\", endDate.Local().UTC(), timer.ToString(),\n\t\t\t)\n\t\t}\n\n\t\tfmt.Println(\"\\n> The day has come!\")\n\t\twg.Done()\n\t}()\n\n\twg.Wait()\n}\n"
  },
  {
    "path": "Roadmap/44 - CUENTA ATRÁS MOUREDEV PRO/java/Josegs95.java",
    "content": "import java.time.*;\nimport java.time.temporal.ChronoUnit;\nimport java.time.temporal.TemporalUnit;\n\npublic class Josegs95 {\n    public static void main(String[] args) {\n        new Josegs95().countdown();\n    }\n\n    public void countdown(){\n        LocalDateTime targetDate = LocalDateTime.of\n                (2024, 12, 15, 17, 28, 00);\n        ZonedDateTime dateInUTC = targetDate.atZone(ZoneOffset.UTC);\n\n        Thread thread = new Thread(() -> {\n            while(true){\n                clearConsole();\n                if (printCountdown(dateInUTC))\n                    break;\n                try{\n                    Thread.sleep(1000);\n                } catch (InterruptedException e) {\n                    throw new RuntimeException(e);\n                }\n            }\n        });\n        thread.start();\n\n        try {\n            thread.join();\n        } catch (InterruptedException e) {\n            throw new RuntimeException(e);\n        }\n        System.out.println(\"¡Se ha llegado a la fecha!\");\n\n    }\n\n    private boolean printCountdown(ZonedDateTime target){\n        LocalDateTime currentDate = LocalDateTime.now(ZoneOffset.UTC);\n        Duration duration = Duration.between(currentDate, target);\n\n        if (duration.isZero() || duration.isNegative())\n            return true;\n\n        Long days = duration.toDaysPart();\n        int hours = duration.toHoursPart();\n        int minutes = duration.toMinutesPart();\n        int seconds = duration.toSecondsPart();\n\n        System.out.print(\"Quedan \" + days + \" días, \" + hours + \" horas\");\n        System.out.println(\", \" + minutes + \" minutos y \" + seconds + \" segundos\");\n\n        return false;\n    }\n\n    private void clearConsole(){\n        String[] command;\n        if (System.getProperty(\"os.name\").toLowerCase().contains(\"windows\"))\n            command = new String[] {\"cmd\", \"/c\", \"cls\"};\n        else\n            command = new String[] {\"clear\"};\n\n        try{\n            new ProcessBuilder(command).inheritIO().start().waitFor();\n        } catch (Exception e) {\n            throw new RuntimeException(e);\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/44 - CUENTA ATRÁS MOUREDEV PRO/java/MohamedElderkaoui.java",
    "content": "import java.text.SimpleDateFormat;\nimport java.util.Calendar;\nimport java.util.Date;\nimport java.util.Scanner;\nimport java.util.TimeZone;\nimport java.util.concurrent.TimeUnit;\n\npublic class MohamedElderkaoui {\n    public static void main(String[] args) {\n\n        Scanner scanner = new Scanner(System.in);\n        Calendar fechaFinalizacion = Calendar.getInstance();\n\n        // Get user input for countdown end date and time\n        while (true) {\n            System.out.print(\"Ingrese la fecha de finalización (dd/MM/yyyy HH:mm:ss): \");\n            String fechaFinalizacionStr = scanner.nextLine();\n\n            SimpleDateFormat sdf = new SimpleDateFormat(\"dd/MM/yyyy HH:mm:ss\");\n            sdf.setTimeZone(TimeZone.getDefault());  // Assume input is in local time\n\n            try {\n                // Parse the user-provided date and set it as UTC\n                Date date = sdf.parse(fechaFinalizacionStr);\n                fechaFinalizacion.setTime(date);\n                fechaFinalizacion.setTimeZone(TimeZone.getTimeZone(\"UTC\"));\n                System.out.println(\"Fecha de finalización parseada correctamente en UTC.\");\n                break;\n            } catch (Exception e) {\n                System.out.println(\"Error al parsear la fecha. Por favor, intente de nuevo.\");\n            }\n        }\n        scanner.close();\n\n        // Run the countdown in a separate thread\n        Thread countdownThread = new Thread(() -> startCountdown(fechaFinalizacion));\n        countdownThread.start();\n    }\n\n    private static void startCountdown(Calendar fechaFinalizacion) {\n        while (true) {\n            Calendar fechaActual = Calendar.getInstance(TimeZone.getTimeZone(\"UTC\"));\n            long diferenciaTiempo = fechaFinalizacion.getTimeInMillis() - fechaActual.getTimeInMillis();\n\n            if (diferenciaTiempo <= 0) {\n                System.out.println(\"¡La cuenta atrás ha finalizado!\");\n                break;\n            }\n\n            long dias = TimeUnit.MILLISECONDS.toDays(diferenciaTiempo);\n            long horas = TimeUnit.MILLISECONDS.toHours(diferenciaTiempo) % 24;\n            long minutos = TimeUnit.MILLISECONDS.toMinutes(diferenciaTiempo) % 60;\n            long segundos = TimeUnit.MILLISECONDS.toSeconds(diferenciaTiempo) % 60;\n\n            // Clear console by printing new lines (approximation)\n            System.out.print(\"\\033[H\\033[2J\");  \n            System.out.flush();\n\n            System.out.printf(\"Faltan %02d d as, %02d horas, %02d minutos y %02d segundos.%n\",\n                    dias, horas, minutos, segundos);\n\n            try {\n                Thread.sleep(1000);  // Wait for one second\n            } catch (InterruptedException e) {\n                Thread.currentThread().interrupt();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/44 - CUENTA ATRÁS MOUREDEV PRO/java/asjordi.java",
    "content": "import java.io.IOException;\nimport java.time.*;\nimport java.time.format.DateTimeFormatter;\n\npublic class asjordi {\n\n    public static void main(String[] args) {\n        LocalDateTime targetDate = LocalDateTime.of(2024, 11, 12, 9, 0, 0);\n        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(\"dd-MM-yyyy HH:mm:ss\");\n        ZonedDateTime utcTarget = targetDate.atZone(ZoneId.systemDefault()).withZoneSameInstant(ZoneOffset.UTC);\n\n        Thread t = new Thread(() -> {\n            while (true) {\n                ZonedDateTime now = ZonedDateTime.now(ZoneOffset.UTC);\n\n                if (now.isAfter(utcTarget)) {\n                    System.out.println(\"¡Cuenta regresiva finalizada!\");\n                    break;\n                }\n\n                Duration duration = Duration.between(now, utcTarget);\n                long days = duration.toDays();\n                long hours = duration.toHoursPart();\n                long minutes = duration.toMinutesPart();\n                long seconds = duration.toSecondsPart();\n\n                try {\n                    limpiarConsola();\n                } catch (IOException | InterruptedException e) {\n                    throw new RuntimeException(e);\n                }\n\n                System.out.println(\"Tiempo restante: \" + days + \" días, \" + hours + \" horas, \" + minutes + \" minutos, \" + seconds + \" segundos\");\n                System.out.println(\"Lanzamiento: \" + utcTarget.format(formatter));\n\n                try {\n                    Thread.sleep(1000);\n                } catch (InterruptedException e) {\n                    Thread.currentThread().interrupt();\n                    break;\n                }\n            }\n        });\n\n        t.start();\n    }\n\n    public static void limpiarConsola() throws IOException, InterruptedException {\n        if (System.getProperty(\"os.name\").contains(\"Windows\")) new ProcessBuilder(\"cmd\", \"/c\", \"cls\").inheritIO().start().waitFor();\n        else new ProcessBuilder(\"clear\").inheritIO().start().waitFor();\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/44 - CUENTA ATRÁS MOUREDEV PRO/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #44 - JavaScript -> Jesus Antonio Escamilla */\n\n/**\n * CUENTA ATRÁS MOUREDEV PRO.\n * Utilizando la Terminal para pedir datos y agregarlos.\n */\n\n//-------AQUÍ SIN INGRESAR DATOS-------\nfunction countdown(targetDate) {\n    const interval = setInterval(() => {\n        const now = new Date().getTime();\n        const remainingTime = targetDate.getTime() - now;\n\n        if (remainingTime <= 0) {\n            console.clear();\n            console.log(\"¡Cuenta atrás finalizada!\");\n            clearInterval(interval);\n            return;\n        }\n\n        const days = Math.floor(remainingTime / (1000 * 60 * 60 * 24));\n        const hours = Math.floor((remainingTime % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));\n        const minutes = Math.floor((remainingTime % (1000 * 60 * 60)) / (1000 * 60));\n        const seconds = Math.floor((remainingTime % (1000 * 60)) / 1000);\n\n        console.clear();\n        console.log(\n            `Tiempo restante: ${days} días, ${hours} horas, ${minutes} minutos, ${seconds} segundos`\n        );\n    }, 1000);\n}\n\nconst localDate = new Date(\"2024-12-09T04:46:00\");\nconst targetDateUTC = new Date(localDate.toISOString());\n\ncountdown(targetDateUTC);\n\n\n\n//-------AQUÍ CON INGRESAR DATOS-------\nconst readline = require(\"readline\");\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout,\n});\n\nconst askQuestion = (query) => {\n    return new Promise((resolve) => rl.question(query, (answer) => resolve(answer)));\n};\n\n(async function main() {\n    console.log(\"\\n--- Configuración de cuenta atrás ---\\n\");\n\n    const day = await askQuestion(\"Día (dd): \");\n    const month = await askQuestion(\"Mes (mm): \");\n    const year = await askQuestion(\"Año (yyyy): \");\n    const hour = await askQuestion(\"Hora (hh): \");\n    const minute = await askQuestion(\"Minuto (mm): \");\n    const second = await askQuestion(\"Segundo (ss): \");\n\n    rl.close();\n\n    const targetDate = new Date(`${year}-${month}-${day}T${hour}:${minute}:${second}Z`);\n\n    if (isNaN(targetDate.getTime())) {\n        console.error(\"\\nFecha inválida. Por favor, intenta de nuevo.\");\n        return;\n    }\n\n    console.log(\"\\nIniciando cuenta atrás...\\n\");\n\n    countdown(targetDate);\n})();\n\nfunction countdown(targetDate) {\n    const interval = setInterval(() => {\n        const now = new Date().getTime();\n        const remainingTime = targetDate.getTime() - now;\n\n        if (remainingTime <= 0) {\n            console.clear();\n            console.log(\"¡Cuenta atrás finalizada!\");\n            clearInterval(interval);\n            return;\n        }\n\n        const days = Math.floor(remainingTime / (1000 * 60 * 60 * 24));\n        const hours = Math.floor((remainingTime % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));\n        const minutes = Math.floor((remainingTime % (1000 * 60 * 60)) / (1000 * 60));\n        const seconds = Math.floor((remainingTime % (1000 * 60)) / 1000);\n\n        console.clear();\n        console.log(\n            `Tiempo restante: ${days} días, ${hours} horas, ${minutes} minutos, ${seconds} segundos`\n        );\n    }, 1000);\n}\n"
  },
  {
    "path": "Roadmap/44 - CUENTA ATRÁS MOUREDEV PRO/javascript/RaulDoezon.js",
    "content": "/*\n  EJERCICIO:\n  ¡El 12 de noviembre lanzo mouredev pro!\n  El campus de la comunidad para estudiar programación de\n  una manera diferente: https://mouredev.pro\n \n  Crea un programa que funcione como una cuenta atrás.\n \n  - Al iniciarlo tendrás que indicarle el día, mes, año,\n    hora, minuto y segundo en el que quieres que finalice.\n  - Deberás transformar esa fecha local a UTC.\n  - La cuenta atrás comenzará y mostrará los días, horas,\n    minutos y segundos que faltan.\n  - Se actualizará cada segundo y borrará la terminal en\n    cada nueva representación del tiempo restante.\n  - Una vez finalice, mostrará un mensaje.\n  - Realiza la ejecución, si el lenguaje lo soporta, en\n    un hilo independiente.\n*/\n\nlet promptData = [];\nconst getDay = prompt('Por favor, ingresa el día (1 - 31):');\nconst getMonth = prompt('Ingresa el mes (0 - 11):');\nconst getYear = prompt('Ingresa el año:');\nconst getHour = prompt('Ingresa la hora:');\nconst getMinute = prompt('Ingresa los minutos:');\nconst getSecond = prompt('Ingresa los segundos:');\n\npromptData.push(getDay, getMonth, getYear, getHour, getMinute, getSecond);\n\nconst utcData = promptData.map((dateElement) => parseInt(dateElement));\nconst [day, month, year, hour, minutes, seconds] = utcData;\nconst localDate = new Date(year, month, day, hour, minutes, seconds);\nconst releaseDate = Date.parse(localDate.toUTCString()) + 21600000;\n\nconst  countdown = setInterval(() => {\n  const currentDate = new Date().getTime();\n  const distance = releaseDate - currentDate;\n  const days = Math.floor(distance / (1000 * 60 * 60 * 24));\n  const hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));\n  const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));\n  const seconds = Math.floor((distance % (1000 * 60)) / 1000);\n\n  if (distance >= 0) {\n    setTimeout(() => {\n      console.clear();\n    }, 999);\n\n    console.log(`Cuenta regresiva: ${days} día${days !== 1 ? 's' : ''} ${hours}h ${minutes}m ${seconds}s`);\n  }\n\n  if (distance < 0) {\n    clearInterval(countdown);\n\n    console.log('¡La espera ha terminado!');\n  }\n}, 1000);\n"
  },
  {
    "path": "Roadmap/44 - CUENTA ATRÁS MOUREDEV PRO/javascript/duendeintemporal.js",
    "content": "//44 - CUENTA ATRAS MOUREDEV PRO \n/*\n * EJERCICIO:\n * ¡El 12 de noviembre lanzo mouredev pro!\n * El campus de la comunidad para estudiar programación de\n * una manera diferente: https://mouredev.pro\n *\n * Crea un programa que funcione como una cuenta atrás.\n *\n * - Al iniciarlo tendrás que indicarle el día, mes, año,\n *   hora, minuto y segundo en el que quieres que finalice.\n * - Deberás transformar esa fecha local a UTC.\n * - La cuenta atrás comenzará y mostrará los días, horas,\n *   minutos y segundos que faltan.\n * - Se actualizará cada segundo y borrará la terminal en\n *   cada nueva representación del tiempo restante.\n * - Una vez finalice, mostrará un mensaje.\n * - Realiza la ejecución, si el lenguaje lo soporta, en\n *   un hilo independiente.\n */\n\nlet log = console.log;\n\nlet styles = `\n    body{\n        background: #000;\n        display: flex;\n        flex-direction: column;\n        justify-content: center;\n        align-intems; center;\n        color: #fff;\n    }\n\n    .wrapper{\n        padding: 0 0 20px 0;\n        display: flex;\n        flex-flow: column;\n    }\n\n    .msgBox{\n        height: 6vw;\n        line-height: 6vw;\n        text-align: center;\n        font-size: 5vw;\n        font-weight: 700;\n        color: rgba(255,255,204,1);\n        text-shadow: 1px 1px 1px #fff;\n        margin-bottom: 60px;\n    }\n\n    .logBox{\n        height: 6vw;\n        line-height: 6vw;\n        text-align: center;\n        font-size: 5vw;\n        font-weight: 700;\n        color: rgba(7,55,99,1);\n        text-shadow: -1px -1px 1px blue, -2px -2px 3px #fff;\n        border: 2px solid rgba(255,255,204,1);\n        border-radius: 7px;\n    }\n`\n\nwindow.addEventListener('load', () => {\n    const body = document.querySelector('body');\n    const title = document.createElement('h1');\n    const wrapper = document.createElement('div');\n    wrapper.classList.add('wrapper');\n    const msgBox = document.createElement('h1');\n    msgBox.classList.add('msgBox');\n    msgBox.textContent = 'Days Remaining For The Initiation Day of MoureDev Pro';\n    const logBox = document.createElement('h1');\n    logBox.classList.add('logBox');\n\n    // Create a <style> element and append the styles\n    let styleSheet = document.createElement(\"style\");\n    styleSheet.type = \"text/css\";\n    styleSheet.innerText = styles;\n    document.head.appendChild(styleSheet);\n\n  \n    body.style.setProperty('background', '#000');\n    body.style.setProperty('text-align', 'center');\n  \n    title.textContent = 'Retosparaprogramadores #44.';\n    title.style.setProperty('font-size', '3.5vmax');\n    title.style.setProperty('color', '#fff');\n    title.style.setProperty('line-height', '20vh');\n  \n    body.appendChild(title);\n    wrapper.appendChild(msgBox);\n    wrapper.appendChild(logBox);\n    body.appendChild(wrapper);\n  \n    console.log('Retosparaprogramadores #44');\n  \n    const countBackFromDate = (day, month, year, hour, minutes, seconds) => {\n      // Create a new Date object\n      const dateTime = new Date(year, month - 1, day, hour, minutes, seconds);\n      // Convert the Date object to a UTC timestamp\n      const utcTimestamp = dateTime.getTime();\n  \n      const interval = setInterval(() => {\n        const currentTime = new Date().getTime();\n        const timeRemaining = utcTimestamp - currentTime;\n  \n        if (timeRemaining <= 0) {\n          clearInterval(interval);\n          logBox.innerText = 'Mouredev Pro has launched! Welcome to the community campus to study programming in a different way!';\n        } else {\n          const days = Math.floor(timeRemaining / (1000 * 60 * 60 * 24));\n          const hours = Math.floor((timeRemaining % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));\n          const minutes = Math.floor((timeRemaining % (1000 * 60 * 60)) / (1000 * 60));\n          const seconds = Math.floor((timeRemaining % (1000 * 60)) / 1000);\n  \n          logBox.innerText = `${days}d ${hours}h ${minutes}m ${seconds}s`;\n        }\n      }, 1000);\n  \n      // Return the UTC timestamp\n      return utcTimestamp;\n    };\n  \n    // Set the countdown to December 31, 2024 at 00:00:00 UTC\n    countBackFromDate(31, 12, 2024, 0, 0, 0);\n  });\n  "
  },
  {
    "path": "Roadmap/44 - CUENTA ATRÁS MOUREDEV PRO/javascript/hectorio23.js",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\nconst readline = require(\"readline\");\nconst { clearInterval, setInterval } = require(\"timers\");\n\n// Leer entrada del usuario\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout,\n});\n\n// Función para solicitar entrada\nconst prompt = (query) => new Promise((resolve) => rl.question(query, resolve));\n\n// Función para iniciar la cuenta atrás\nfunction startCountdown(targetDate) {\n    const timer = setInterval(() => {\n        const now = new Date();\n        const diff = targetDate - now;\n\n        if (diff <= 0) {\n            console.clear();\n            console.log(\"¡Cuenta atrás finalizada!\");\n            clearInterval(timer);\n            rl.close();\n            return;\n        }\n\n        const days = Math.floor(diff / (1000 * 60 * 60 * 24));\n        const hours = Math.floor((diff / (1000 * 60 * 60)) % 24);\n        const minutes = Math.floor((diff / (1000 * 60)) % 60);\n        const seconds = Math.floor((diff / 1000) % 60);\n\n        console.clear();\n        console.log(`Tiempo restante: ${days} días, ${hours} horas, ${minutes} minutos, ${seconds} segundos`);\n    }, 1000);\n}\n\n// Función principal\n(async function main() {\n    const day = await prompt(\"Día: \");\n    const month = await prompt(\"Mes: \");\n    const year = await prompt(\"Año: \");\n    const hour = await prompt(\"Hora: \");\n    const minute = await prompt(\"Minuto: \");\n    const second = await prompt(\"Segundo: \");\n\n    const targetDate = new Date(Date.UTC(year, month - 1, day, hour, minute, second));\n    console.log(`Fecha objetivo (UTC): ${targetDate.toISOString()}`);\n    startCountdown(targetDate);\n})();\n"
  },
  {
    "path": "Roadmap/44 - CUENTA ATRÁS MOUREDEV PRO/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n_______________________________________________________\n#44 CUENTA ATRÁS MOUREDEV PRO\n-------------------------------------------------------\n* EJERCICIO:\n * ¡El 12 de noviembre lanzo mouredev pro!\n * El campus de la comunidad para estudiar programación de\n * una manera diferente: https://mouredev.pro\n *\n * Crea un programa que funcione como una cuenta atrás.\n *\n * - Al iniciarlo tendrás que indicarle el día, mes, año,\n *   hora, minuto y segundo en el que quieres que finalice.\n * - Deberás transformar esa fecha local a UTC.\n * - La cuenta atrás comenzará y mostrará los días, horas,\n *   minutos y segundos que faltan.\n * - Se actualizará cada segundo y borrará la terminal en\n *   cada nueva representación del tiempo restante.\n * - Una vez finalice, mostrará un mensaje.\n * - Realiza la ejecución, si el lenguaje lo soporta, en\n *   un hilo independiente.\n */\n// ________________________________________________________\nconst readline = require('readline');\n\nclass ReverseTimer {\n    constructor(endDate) {\n        this.endDate = new Date(endDate);\n        if (isNaN(this.endDate)) {\n            throw new Error(\"La fecha de finalización no es válida.\");\n        }\n    }\n\n    timeRemaining() {\n        const now = new Date();\n        const delta = this.endDate - now;\n        return Math.max(delta, 0);\n    }\n\n    hasFinished() {\n        return this.timeRemaining() === 0;\n    }\n\n    toString() {\n        const delta = this.timeRemaining();\n        const days = Math.floor(delta / (1000 * 60 * 60 * 24));\n        const hours = Math.floor((delta % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));\n        const minutes = Math.floor((delta % (1000 * 60 * 60)) / (1000 * 60));\n        const seconds = Math.floor((delta % (1000 * 60)) / 1000);\n        return `${days} días, ${hours} horas, ${minutes} minutos, ${seconds} segundos.`;\n    }\n\n    printRemaining() {\n        const interval = setInterval(() => {\n            // Limpiar la consola\n            readline.cursorTo(process.stdout, 0, 0);\n            readline.clearScreenDown(process.stdout);\n\n            console.log(\"Tiempo restante:\");\n            console.log(this.toString());\n\n            if (this.hasFinished()) {\n                console.log(\"¡Cuenta atrás finalizada!\");\n                clearInterval(interval);\n            }\n        }, 1000);\n    }\n}\n\n// Uso del temporizador\nconst endDate = \"2024-12-31T23:59:59.999Z\"; // UTC explícito\nconst timer = new ReverseTimer(endDate);\ntimer.printRemaining();\n"
  },
  {
    "path": "Roadmap/44 - CUENTA ATRÁS MOUREDEV PRO/javascript/pedamoci.js",
    "content": "import readline from \"readline\"\n\nconst COLORS = Object.freeze({\n  red: \"\\x1b[31m\",\n  green: \"\\x1b[32m\",\n  yellow: \"\\x1b[33m\",\n  cyan: \"\\x1b[34m\",\n  reset: \"\\x1b[0m\",\n})\n\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout\n})\n\nconst ask = question => new Promise(resolve => \n  rl.question(question, resolve)\n)\n\nconst printError = msg => { console.error(COLORS.red + \"Error: \" + msg + COLORS.reset) }\nconst printFinish = () => { console.log(COLORS.green + \"The countdown is finished!\" + COLORS.reset) }\nconst printInfo = msg => { console.log(COLORS.cyan + \"Time remaining: \" + COLORS.yellow + msg + COLORS.reset) }\n\nconst asks = Object.freeze({\n  year: async () => { return await ask(\"Enter the full year for the countdown (ej: 2093): \") },\n  month: async () => { return await ask(\"Enter the month for the countdown (1 - 12): \") },\n  day: async () => { return await ask(\"Enter the day for the countdown (1 - 31): \") },\n  hour: async () => { return await ask(\"Enter the hour for the countdown (0 - 23): \") },\n  minutes: async () => { return await ask(\"Enter the minutes for the countdown (0 - 59): \") },\n  seconds: async () => { return await ask(\"Enter the seconds for the countdown (0 - 59): \") },\n})\n\nconst validators = Object.freeze({\n  year: async year => { \n    while (year < new Date().getFullYear()) {\n      printError(\"INVALID_YEAR\")\n      year = await asks.year()\n    }\n    return year\n  },\n  month: async month => { \n    while (month < 1 || month > 12) {\n      printError(\"INVALID_MONTH\")\n      month = await asks.month()\n    }\n    return month\n  },\n  day: async (year, month, day) => {\n    while (day <= 0 || day > (new Date(year, month, 0).getDate())) {\n      printError(\"INVALID_DAY\")\n      day = await asks.day()\n    }\n    return day\n  },\n  hour: async hour => { \n    while (hour < 0 || hour > 23) {\n      printError(\"HOUR_OUT_OF_RANGE\")\n      hour = await asks.hour()\n    }\n    return hour\n  },\n  minutes: async minutes => { \n    while (minutes < 0 || minutes > 59) {\n      printError(\"MINUTES_OUT_OF_RANGE\")\n      minutes = await asks.minutes()\n    }\n    return minutes\n  },\n  seconds: async seconds => { \n    while (seconds < 0 || seconds > 59) {\n      printError(\"SECONDS_OUT_OF_RANGE\")\n      seconds = await asks.seconds()\n    }\n    return seconds\n  },\n  date: date => {\n    if (date > new Date()) {\n      return true\n    }\n    return false\n  },\n  isNumber: num => {\n    if (Number.isNaN(Number(num))) {\n      return -1\n    }\n    return Number(num)\n  }\n})\n\nasync function getTargetDate() {\n  while (true) {\n    const year =  await validators.year( validators.isNumber( await asks.year()))\n    const month =  await validators.month( validators.isNumber( await asks.month()))\n    const day =  await validators.day( year, month, validators.isNumber( await asks.day()))\n    const hour =  await validators.hour( validators.isNumber( await asks.hour()))\n    const minutes =  await validators.minutes( validators.isNumber( await asks.minutes()))\n    const seconds =  await validators.seconds( validators.isNumber( await asks.seconds()))\n  \n    const targetDate = new Date(Date.UTC(year, (month - 1), day, hour, minutes, seconds) )\n\n    if (validators.date(targetDate)) return targetDate\n\n    printError(\"INVALID_DATE\")\n  }\n}\n\nfunction countdown(targetDate, intervalId) {\n    console.clear()\n  \n    const secondsToTargetTime = Math.floor((targetDate - new Date()) / 1000)\n  \n    const days = Math.floor(secondsToTargetTime / 60 / 60 / 24)\n    const hours = Math.floor(secondsToTargetTime / 60 / 60) - (days * 24)\n    const minutes = Math.floor(secondsToTargetTime / 60) - (days * 24 * 60) - (hours * 60)\n    const seconds = secondsToTargetTime - (days * 24 * 60 * 60) - (hours * 60 * 60) - (minutes * 60)\n  \n    if (days <= 0 && hours <= 0 && minutes <= 0 && seconds <= 0) {\n      clearInterval(intervalId)\n      printFinish()\n      rl.close()\n      return\n    }\n  \n    printInfo(`${`${days}`.padStart(2, \"0\")}:${`${hours}`.padStart(2, \"0\")}:${`${minutes}`.padStart(2, \"0\")}:${`${seconds}`.padStart(2, \"0\")}`)\n}\n\nasync function startProgram() {\n  const targetDate = await getTargetDate()\n\n  const intervalId = setInterval(() => {\n    countdown(targetDate, intervalId)\n  }, 1000)\n}\n\nstartProgram()"
  },
  {
    "path": "Roadmap/44 - CUENTA ATRÁS MOUREDEV PRO/kotlin/blackriper.kt",
    "content": "\r\nimport kotlinx.coroutines.delay\r\nimport kotlinx.coroutines.flow.flow\r\nimport kotlinx.coroutines.flow.onCompletion\r\nimport kotlinx.coroutines.runBlocking\r\nimport java.time.Duration\r\nimport java.time.LocalDateTime\r\nimport java.time.temporal.ChronoUnit\r\n\r\n//https://kotlinlang.org/docs/flow.html\r\n\r\ndata class CountDown(var days: Long, var seconds:Long)\r\n\r\nfun CountDown.showCountDown(): String{\r\n    val hours = Duration.ofSeconds(seconds).let {\r\n        String.format(\"%02d:%02d:%02d\", it.toHoursPart(), it.toMinutesPart(), it.toSecondsPart())\r\n    }\r\n\r\n    return \"$days days -$hours\"\r\n}\r\n\r\n\r\n\r\nfun getFinalDate(): LocalDateTime {\r\n    var valid=false\r\n    var data=\"\"\r\n\r\n   while (valid!=true) {\r\n       println(\r\n           \"Enter Enter a date using the following format:\\n\" +\r\n                   \"year,month,day,hour,minute\"\r\n       )\r\n       data = readLine().toString()\r\n       if (data.contains(\"^\\\\d+(,\\\\d+){4}\\$\".toRegex())) valid=true\r\n       else println(\"Incorrect format to date\")\r\n   }\r\n\r\n    return data.split(\",\").map { it.toInt() }.let {\r\n         LocalDateTime.of(it[0],it[1],it[2],it[3],it[4])\r\n    }\r\n}\r\n\r\nfun calculateDateRest(finalDate: LocalDateTime,today: LocalDateTime)=CountDown(\r\n        days = ChronoUnit.DAYS.between(today,finalDate),\r\n        seconds = ChronoUnit.SECONDS.between(today,finalDate)\r\n    )\r\n\r\n\r\n\r\n fun counterDown()= flow<String>{\r\n    val finalDate=  getFinalDate()\r\n    do {\r\n         val today= LocalDateTime.now()\r\n         val counter = calculateDateRest(finalDate, today)\r\n         delay(1000)\r\n         emit(counter.showCountDown())\r\n     } while (counter.days.toInt() !=0 || counter.seconds.toInt()!=0)\r\n\r\n}.onCompletion { println(\"The countdown is over, the day has arrived 😎😎😎 \") }\r\n\r\n\r\n\r\n\r\nfun main(): Unit = runBlocking {\r\n    counterDown().collect {\r\n        println(it)\r\n    }\r\n}"
  },
  {
    "path": "Roadmap/44 - CUENTA ATRÁS MOUREDEV PRO/php/jetiradoro.php",
    "content": "<?php\n\nclass CountDown\n{\n    private function checkFutureDate(DateTime $date): void\n    {\n        $now = new DateTime();\n        if ($date < $now) {\n            throw new Exception(\"El evento ya ha pasado!\");\n        }\n    }\n\n    private function drawCountDown(DateTime $date): void\n    {\n        system(\"clear\");\n        $now = new DateTime('now', new DateTimeZone('Europe/Madrid'));\n        $now_utc = $now->setTimezone(new DateTimeZone('UTC'));\n        $diff = $date->diff($now_utc);\n        $days = $diff->format(\"%a\");\n        $hours = $diff->format(\"%h\");\n        $minutes = $diff->format(\"%i\");\n        $seconds = $diff->format(\"%s\");\n\n        $str_date = $date->format(\"d-m-Y H:i:s\");\n        $str_now_utc = $now_utc->format(\"d-m-Y H:i:s\");\n\n        echo \"TU EVENTO TENDRÁ LUGAR EL PROXIMO $str_date HORA UTC\" . PHP_EOL . PHP_EOL;\n        $this->printSuccess(\"==============\");\n        echo \" Cuenta atrás \" . PHP_EOL;\n        $this->printSuccess(\"==============\");\n        echo \"Días: \" . $days . PHP_EOL;\n        echo \"Horas: \" . $hours . PHP_EOL;\n        echo \"Minutos: \" . $minutes . PHP_EOL;\n        echo \"Segundos: \" . $seconds . PHP_EOL;\n\n        if ($str_date === $str_now_utc) {\n            echo PHP_EOL . \" ============================================================================\" . PHP_EOL;\n            $this->printSuccess(\" ¡Felicidades! ES LA HORA : Comenzamos a divertirnos? .\");\n        } else {\n            sleep(1);\n            $this->drawCountDown($date);\n        }\n    }\n\n    private function checkYear(int $year)\n    {\n        if (strlen((string) $year) !== 4) {\n            throw new Exception(\"El año debe estar formado por 4 dígitos\");\n        }\n    }\n\n    private function checkMonth(string $month): void\n    {\n        $int_month = intval($month);\n        if ($int_month < 1 || $int_month > 12) {\n            throw new Exception(\"El mes debe estar entre 1 y 12\");\n        }\n    }\n\n    private function checkDay(int $day, int $month): void\n    {\n        $meses_largos = [1, 3, 5, 7, 8, 10, 12];\n        if ($month == 2 && $day > 29) {\n            throw new Exception(\"No puedes tener un día mayor a 29 en febrero\");\n        }\n        if (!in_array($month, $meses_largos) && $day > 31) {\n            throw new Exception(\"No puedes tener un día mayor al día 31 para el mes seleccionado\");\n        } else if ($day > 30) {\n            throw new Exception(\"No puedes tener un día mayor al día 30 para el mes seleccionado\");\n        }\n    }\n\n    private function checkHour(int $hour): void\n    {\n        if ($hour < 0 || $hour > 23) {\n            throw new Exception(\"La hora debe estar entre 0 y 23\");\n        }\n    }\n\n    private function checkMinute(int $minute): void\n    {\n        if ($minute < 0 || $minute > 59) {\n            throw new Exception(\"Los mintuos deben estar entre 0 y 59\");\n        }\n    }\n\n    private function checkSeconds(int $seconds): void\n    {\n        if ($seconds < 0 || $seconds > 59) {\n            throw new Exception(\"Los segundos deben estar entre 0 y 59\");\n        }\n    }\n\n\n    private function printError(string $message): void\n    {\n        echo \"\\033[0;31m$message\" . PHP_EOL;\n        echo \"\\033[0G\\033[0m\";\n    }\n\n    private function printSuccess(string $message): void\n    {\n        echo \"\\033[0;32m$message\" . PHP_EOL;\n        echo \"\\033[0G\\033[0m\";\n    }\n\n    private function getYear(): string\n    {\n        try {\n            $year = intval(trim(readline(\"Dame el año del evento:\")));\n            $this->checkYear($year);\n            return (string) $year;\n        } catch (Exception $e) {\n            $this->printError($e->getMessage());\n            return $this->getYear();\n        }\n    }\n\n    private function getMonth(): string\n    {\n        try {\n            echo \"1. Enero\" . PHP_EOL;\n            echo \"2. Febrero\" . PHP_EOL;\n            echo \"3. Marzo\" . PHP_EOL;\n            echo \"4. Abril\" . PHP_EOL;\n            echo \"5. Mayo\" . PHP_EOL;\n            echo \"6. Junio\" . PHP_EOL;\n            echo \"7. Julio\" . PHP_EOL;\n            echo \"8. Agosto\" . PHP_EOL;\n            echo \"9. Septiembre\" . PHP_EOL;\n            echo \"10. Octubre\" . PHP_EOL;\n            echo \"11. Noviembre\" . PHP_EOL;\n            echo \"12. Diciembre\" . PHP_EOL;\n            $month = intval(trim(readline(\"Dame el mes del evento:\")));\n            $month = str_pad((string) $month, 2, \"0\", STR_PAD_LEFT);\n            $this->checkMonth($month);\n            return (string) $month;\n        } catch (Exception $e) {\n            $this->printError($e->getMessage());\n            return $this->getMonth();\n        }\n    }\n\n    private function getDay(int $month): string\n    {\n        try {\n            $day = intval(trim(readline(\"Dame el día del evento:\")));\n            $this->checkDay($day, $month);\n            return (string) $day;\n        } catch (Exception $e) {\n            $this->printError($e->getMessage());\n            return $this->getDay($month);\n        }\n    }\n\n    private function getHour(): string\n    {\n        try {\n            $hour = intval(trim(readline(\"Dame la hora del evento:\")));\n            $this->checkHour($hour);\n            $hour = str_pad((string) $hour, 2, \"0\", STR_PAD_LEFT);\n            return $hour;\n        } catch (Exception $e) {\n            $this->printError($e->getMessage());\n            return $this->getHour();\n        }\n    }\n\n\n    private function getMinute(): string\n    {\n        try {\n            $minutes = intval(trim(readline(\"Dame el minuto del evento:\")));\n            $this->checkMinute($minutes);\n            $minutes = str_pad((string) $minutes, 2, \"0\", STR_PAD_LEFT);\n            return $minutes;\n        } catch (Exception $e) {\n            $this->printError($e->getMessage());\n            return $this->getMinute();\n        }\n    }\n\n    private function getSecond(): string\n    {\n        try {\n            $seconds = intval(trim(readline(\"Dame el segundo del evento:\")));\n            $this->checkSeconds($seconds);\n            $seconds = str_pad((string) $seconds, 2, \"0\", STR_PAD_LEFT);\n            return $seconds;\n        } catch (Exception $e) {\n            $this->printError($e->getMessage());\n            return $this->getSecond();\n        }\n    }\n\n\n    public function run()\n    {\n        system(\"clear\");\n        try {\n            $year = $this->getYear();\n            $month = $this->getMonth();\n            $day = $this->getDay((int) $month);\n            $hour = $this->getHour();\n            $minute = $this->getMinute();\n            $second = $this->getSecond();\n\n            $local_date = new DateTime($year . \"-\" . $month . \"-\" . $day . ' ' . $hour . ':' . $minute . ':' . $second, new DateTimeZone('Europe/Madrid'));\n            $utc_date = $local_date->setTimezone(new DateTimeZone('UTC'));\n            $this->checkFutureDate($utc_date);\n\n            $this->drawCountDown($utc_date);\n        } catch (Exception $e) {\n            $this->printError($e->getMessage());\n        }\n    }\n}\n\n$countdown = new CountDown();\n$countdown->run();\n"
  },
  {
    "path": "Roadmap/44 - CUENTA ATRÁS MOUREDEV PRO/python/CarlosVR48.py",
    "content": "import datetime,threading,pytz\nfrom pytz import timezone\nfrom os import system\n\ndef muestra_tiempo():\n    hora_actual_esp = datetime.datetime.now(timezone(\"Europe/Madrid\"))\n    hora_actual_utc = datetime.datetime.now(timezone(\"UTC\"))\n    print (f\"DIA Y HORA UTC :       {hora_actual_utc}\")\n    print (f\"DIA Y HORA DE ESPAÑA : {hora_actual_esp}\\n\")\n\ndef datos():\n    salir = True\n    while salir:\n        print (\"INTRODUCE LA FECHA Y LA HORA DE FINALIZACION \\n\")\n        year = input (\"AÑO (XXXX)? \")\n        mes = input (\"MES (XX)? \")\n        dia = input (\"DIA (XX)? \")\n        hora = input (\"HORA (XX)? \")\n        minuto = input (\"MINUTOS (XX)? \")\n        segundo = input (\"SEGUNDOS (XX)? \")\n\n        try:\n            fecha_final = datetime.datetime.strptime(year + mes + dia + hora + minuto + segundo , \"%Y%m%d%H%M%S\")\n            salir = False\n            return fecha_final\n        except:\n            print (\"\\nHAS INTRODUCIDO ALGUN DATO MAL\")\n\ndef programa():\n    system(\"cls\")            \n    muestra_tiempo()\n    #FECHA FINAL INTRODUCIDA POR CONSOLA (fecha_final)\n    fecha_final = datos()\n    #ASSIGNO A LA VARIABLE (europa) \"Europe/Madrid\" . FECHA FINAL DE EUROPA ESPAÑA (fecha_local)\n    europa = pytz.timezone(\"Europe/Madrid\")\n    fecha_local = europa.localize(fecha_final, is_dst=None)\n    #FECHA FINALIZACION UTC (fecha_utc)\n    fecha_utc = fecha_local.astimezone(pytz.utc)\n\n    while True:\n        system (\"cls\")\n        hora_actual_utc = datetime.datetime.now(timezone(\"UTC\"))\n        tiempo_final=(fecha_utc-hora_actual_utc)\n\n        muestra_tiempo()\n        print (f\"DIA Y HORA UTC DE FINALIZACION {fecha_utc} \")\n        # la variable tiempo_final es del tipo timedelte, dando su valor en dias , segundos y microsegundos\n        dias = tiempo_final.days\n        horas = int(tiempo_final.seconds / 3600)\n        minutos = int((tiempo_final.seconds % 3600) / 60)\n        segundos = int(tiempo_final.seconds % 3600) % 60\n        print (f\"\\n{dias} dias , {horas} h , {minutos} minutos y {segundos} segundos \\n\")\n        \n        if hora_actual_utc >= fecha_utc :\n            system(\"cls\")\n            print (f\"DIA Y HORA UTC DE FINALIZACION {fecha_utc} \\n\")\n            print (\"LA CUENTA A FINALIZADO\")\n            break\n\nprincipal = threading.Thread(target=programa)\nprincipal.start()\n\n\n\n\n        \n\n"
  },
  {
    "path": "Roadmap/44 - CUENTA ATRÁS MOUREDEV PRO/python/EmmanuelMMontesinos.py",
    "content": "\"\"\"\n * EJERCICIO:\n * ¡El 12 de noviembre lanzo mouredev pro!\n * El campus de la comunidad para estudiar programación de\n * una manera diferente: https://mouredev.pro\n *\n * Crea un programa que funcione como una cuenta atrás.\n *\n * - Al iniciarlo tendrás que indicarle el día, mes, año,\n *   hora, minuto y segundo en el que quieres que finalice.\n * - Deberás transformar esa fecha local a UTC.\n * - La cuenta atrás comenzará y mostrará los días, horas,\n *   minutos y segundos que faltan.\n * - Se actualizará cada segundo y borrará la terminal en\n *   cada nueva representación del tiempo restante.\n * - Una vez finalice, mostrará un mensaje.\n * - Realiza la ejecución, si el lenguaje lo soporta, en\n *   un hilo independiente.\n\"\"\"\nfrom datetime import datetime, timezone\nimport os\nimport time\nimport threading\n\nclass CuentaAtras:\n    def __init__(self, dia: int, mes: int, ano: int, hora: int, minutos: int, segundos: int):\n        self.fecha_final = datetime(ano, mes, dia, hora, minutos, segundos, tzinfo=timezone.utc)\n        \n    def limpiar_pantalla(self):\n        os.system(\"cls\")\n\n    def bucle(self):\n        while True:\n            self.diferencia = self.fecha_final - datetime.now(timezone.utc)\n            if self.diferencia.total_seconds() <= 0:\n                self.limpiar_pantalla()\n                print(\"¡Hemos llegado!\")\n                break\n\n            dias = self.diferencia.days\n            horas, resto = divmod(self.diferencia.seconds, 3600)\n            minutos, segundos = divmod(resto, 60)\n            \n\n            self.limpiar_pantalla()\n            print(f\"Quedan: {dias} días, {horas} horas, {minutos} minutos, {segundos} segundos\")\n            \n\n            time.sleep(1)\n\n# Prueba\ncuenta = CuentaAtras(7, 11, 2024, 20, 41, 0)\nproceso = threading.Thread(target=cuenta.bucle)\nproceso.start()\n"
  },
  {
    "path": "Roadmap/44 - CUENTA ATRÁS MOUREDEV PRO/python/Gordo-Master.py",
    "content": "# 44 - Cuenta atrás Mouredev Pro\nimport datetime\nimport time\nimport os\nimport threading\n\n# Formatear el timedelta para mostrar en dias, horas, min, seg.\ndef format_timedelta(td: datetime.timedelta) -> str:\n    total_seconds = td.total_seconds()\n    days = td.days\n    hours, remainder = divmod(total_seconds, 3600)\n    minutes, seconds = divmod(remainder, 60)\n    if days:\n        return f\"{days} dias {hours % 24:02.0f}:{minutes:02.0f}:{seconds:02.0f}\"\n    else:\n        return f\"{hours:02.0f}:{minutes:02.0f}:{seconds:02.0f}\"\n    \ndef count_down(target_date):\n    # Hacer el bucle de impresion infinita hasta llegar el momento\n    while True:\n        os.system(\"cls\")\n        # Imprimir hora del evento\n        print(\"Fecha del evento: \")\n        print(target_date.astimezone().strftime(\"%d/%m/%Y, %H:%M:%S\"))\n        print(\"El evento sera en: \")\n        now_date_utc = datetime.datetime.now().astimezone(datetime.timezone.utc)\n        remaining_time = target_date - now_date_utc\n        formated_time = format_timedelta(remaining_time)\n\n        if remaining_time.total_seconds() <= 0:\n            print(\"La cuenta atras ha terminado\")\n            break\n        \n        print(\"Cuenta regresiva: \")\n        print(formated_time)\n        time.sleep(1)\n    \n\n# Definir la fecha del evento\nlocal_date = datetime.datetime(2025,5,5,19,36,20)\nlocal_date = local_date.replace(tzinfo=datetime.datetime.now().astimezone().tzinfo)\n\n# Ejecucion con hilos\ntarget_date_utc = local_date.astimezone(datetime.timezone.utc)\ncountdown_treath = threading.Thread(target=count_down, args=(target_date_utc,))\ncountdown_treath.start()\ncountdown_treath.join()"
  },
  {
    "path": "Roadmap/44 - CUENTA ATRÁS MOUREDEV PRO/python/Nicojsuarez2.py",
    "content": "# #44 CUENTA ATRÁS MOUREDEV PRO\n> #### Dificultad: Fácil | Publicación: 04/11/24 | Corrección: 11/11/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * ¡El 12 de noviembre lanzo mouredev pro!\n * El campus de la comunidad para estudiar programación de\n * una manera diferente: https://mouredev.pro\n *\n * Crea un programa que funcione como una cuenta atrás.\n *\n * - Al iniciarlo tendrás que indicarle el día, mes, año,\n *   hora, minuto y segundo en el que quieres que finalice.\n * - Deberás transformar esa fecha local a UTC.\n * - La cuenta atrás comenzará y mostrará los días, horas,\n *   minutos y segundos que faltan.\n * - Se actualizará cada segundo y borrará la terminal en\n *   cada nueva representación del tiempo restante.\n * - Una vez finalice, mostrará un mensaje.\n * - Realiza la ejecución, si el lenguaje lo soporta, en\n *   un hilo independiente.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/44 - CUENTA ATRÁS MOUREDEV PRO/python/cdryampi.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * ¡El 12 de noviembre lanzo mouredev pro!\n#  * El campus de la comunidad para estudiar programación de\n#  * una manera diferente: https://mouredev.pro\n#  *\n#  * Crea un programa que funcione como una cuenta atrás.\n#  *\n#  * - Al iniciarlo tendrás que indicarle el día, mes, año,\n#  *   hora, minuto y segundo en el que quieres que finalice.\n#  * - Deberás transformar esa fecha local a UTC.\n#  * - La cuenta atrás comenzará y mostrará los días, horas,\n#  *   minutos y segundos que faltan.\n#  * - Se actualizará cada segundo y borrará la terminal en\n#  *   cada nueva representación del tiempo restante.\n#  * - Una vez finalice, mostrará un mensaje.\n#  * - Realiza la ejecución, si el lenguaje lo soporta, en\n#  *   un hilo independiente.\n#  */\nfrom datetime import datetime, timezone, timedelta\nimport threading\nimport time\nimport os\n\nclass CuentaAtras:\n    \"\"\"Clase que representa una cuenta atrás\"\"\"\n    __END_COUNTER = None\n    __RUNING = True\n\n    def __init__(self, dia: int, mes: int, any: int, hora: int, minuto: int, segundo: int):\n        self.__END_COUNTER = datetime(\n            year=any,\n            month=mes,\n            day=dia,\n            hour=hora,\n            minute=minuto,\n            second=segundo,\n            tzinfo=timezone.utc\n        )\n\n    def time_remaining(self) -> timedelta:\n        \"\"\"Devuelve el tiempo restante como un timedelta\"\"\"\n        return self.__END_COUNTER - datetime.now(timezone.utc)\n\n    def time_to_seconds(self) -> bool:\n        \"\"\"Verifica si el tiempo restante ha terminado\"\"\"\n        remaining = self.time_remaining()\n        if remaining.total_seconds() <= 0:\n            print(\"¡MoureDev Pro ha comenzado! Disfruta del programa.\")\n            return True\n        return False\n\n    def time_str(self) -> str:\n        \"\"\"Devuelve una cadena con el tiempo restante en días, horas, minutos y segundos\"\"\"\n        remaining = self.time_remaining()\n        \n        # Obtener días, horas, minutos y segundos restantes\n        dias = remaining.days\n        horas, resto_segundos = divmod(remaining.seconds, 3600)\n        minutos, segundos = divmod(resto_segundos, 60)\n\n        return f\"Encara falta {dias} dies, {horas} hores, {minutos} minuts i {segundos} segons.\\nPresiona Enter para detener el contador...\\n\"\n    \n    def safe_execute_clear_from_cmd(self) -> None:\n        \"\"\"Limpia la consola dependiendo del sistema operativo\"\"\"\n        try:\n            if os.name == 'nt':\n                os.system('cls')\n            else:\n                os.system('clear')\n        except Exception as e:\n            print(f\"Error al limpiar la consola: {e}\")\n\n    def print_next_second(self):\n        \"\"\"Imprime el tiempo restante cada segundo\"\"\"\n        print(self.time_str())\n\n    def run_to_end_counter_threat(self):\n        \"\"\"Inicia el contador en un hilo y lo detiene con la entrada del usuario\"\"\"\n        def countdown():\n            while not self.time_to_seconds() and self.__RUNING:\n                self.safe_execute_clear_from_cmd()\n                self.print_next_second()\n                time.sleep(1)\n            print(\"Contador detenido.\")\n\n        threat = threading.Thread(target=countdown)\n        threat.start()\n\n        input_thread = threading.Thread(target=self.stop)\n        input_thread.start()\n\n        threat.join()\n        input_thread.join()\n        \n    def stop(self):\n        input(\"Presiona Enter para detener el contador...\\n\")\n        self.__RUNING = False\n\n\ndef main():\n    compte_enrrere = CuentaAtras(\n        dia=12,\n        mes=11,\n        any=2024,\n        hora=0,\n        minuto=0,\n        segundo=0\n    )\n\n    compte_enrrere.run_to_end_counter_threat()\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Roadmap/44 - CUENTA ATRÁS MOUREDEV PRO/python/davidrguez98.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * ¡El 12 de noviembre lanzo mouredev pro!\n * El campus de la comunidad para estudiar programación de\n * una manera diferente: https://mouredev.pro\n *\n * Crea un programa que funcione como una cuenta atrás.\n *\n * - Al iniciarlo tendrás que indicarle el día, mes, año,\n *   hora, minuto y segundo en el que quieres que finalice.\n * - Deberás transformar esa fecha local a UTC.\n * - La cuenta atrás comenzará y mostrará los días, horas,\n *   minutos y segundos que faltan.\n * - Se actualizará cada segundo y borrará la terminal en\n *   cada nueva representación del tiempo restante.\n * - Una vez finalice, mostrará un mensaje.\n * - Realiza la ejecución, si el lenguaje lo soporta, en\n *   un hilo independiente.\n */ \"\"\"\n\nimport datetime\nimport time\nimport os\nimport threading\n\ndef countdown(target_date):\n\n    while True:\n\n        now_date_utc = datetime.datetime.now(datetime.timezone.utc) \n\n        remaining_time = target_date_utc - now_date_utc\n\n        if remaining_time.total_seconds() <= 0:\n            print(\"\\nCuenta atrás finalizada.\")\n            break\n\n        days, seconds = divmod(remaining_time.total_seconds(), 86400)\n        hours, seconds = divmod(seconds, 3600)\n        minutes, seconds = divmod(seconds, 60)\n\n        os.system(\"cls\")\n\n        print(f\"Tiempo restante: {int(days)} días, {int(hours)} horas, {int(minutes)} minutos y {int(seconds)} segundos.\")\n\n        time.sleep(1)\n\nlocal_date = datetime.datetime(2025, 2, 10, 17, 28, 00)\nlocal_date = local_date.replace(tzinfo=datetime.datetime.now().astimezone().tzinfo)\n\ntarget_date_utc = local_date.astimezone(datetime.timezone.utc)\n\ncountdown_thread = threading.Thread(target=countdown, args=(target_date_utc,))\ncountdown_thread.start()\ncountdown_thread.join()"
  },
  {
    "path": "Roadmap/44 - CUENTA ATRÁS MOUREDEV PRO/python/duendeintemporal.py",
    "content": "#44 { Retos para Programadores } CUENTA ATRAS MOUREDEV PRO \n\n# Bibliography reference:\n# I use GPT as a reference and sometimes to correct or generate proper comments.\n\n\"\"\"\n * EJERCICIO:\n * ¡El 12 de noviembre lanzo mouredev pro!\n * El campus de la comunidad para estudiar programación de\n * una manera diferente: https://mouredev.pro\n *\n * Crea un programa que funcione como una cuenta atrás.\n *\n * - Al iniciarlo tendrás que indicarle el día, mes, año,\n *   hora, minuto y segundo en el que quieres que finalice.\n * - Deberás transformar esa fecha local a UTC.\n * - La cuenta atrás comenzará y mostrará los días, horas,\n *   minutos y segundos que faltan.\n * - Se actualizará cada segundo y borrará la terminal en\n *   cada nueva representación del tiempo restante.\n * - Una vez finalice, mostrará un mensaje.\n * - Realiza la ejecución, si el lenguaje lo soporta, en\n *   un hilo independiente.\n\n\"\"\"\nfrom flask import Flask, render_template_string\n\napp = Flask(__name__)\n\n# HTML and CSS as a string\nhtml_content = '''\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>Countdown Timer</title>\n    <style>\n        body {\n            background: #000;\n            display: flex;\n            flex-direction: column;\n            justify-content: center;\n            align-items: center; /* Fixed typo from align-intems to align-items */\n            color: #fff;\n        }\n\n        .wrapper {\n            padding: 0 0 20px 0;\n            display: flex;\n            flex-flow: column;\n        }\n\n        .msgBox {\n            height: 6vw;\n            line-height: 6vw;\n            text-align: center;\n            font-size: 5vw;\n            font-weight: 700;\n            color: rgba(255, 255, 204, 1);\n            text-shadow: 1px 1px 1px #fff;\n            margin-bottom: 60px;\n        }\n\n        .logBox {\n            height: 6vw;\n            line-height: 6vw;\n            text-align: center;\n            font-size: 5vw;\n            font-weight: 700;\n            color: rgba(7, 55, 99, 1);\n            text-shadow: -1px -1px 1px blue, -2px -2px 3px #fff;\n            border: 2px solid rgba(255, 255, 204, 1);\n            border-radius: 7px;\n        }\n    </style>\n</head>\n<body>\n    <h1 id=\"title\">Retosparaprogramadores #44.</h1>\n    <div class=\"wrapper\">\n        <h1 class=\"msgBox\">Days Remaining For The Initiation Day of MoureDev Pro</h1>\n        <h1 class=\"logBox\" id=\"logBox\"></h1>\n    </div>\n    <script>\n        const logBox = document.getElementById('logBox');\n\n        const countBackFromDate = (day, month, year, hour, minutes, seconds) => {\n            const dateTime = new Date(year, month - 1, day, hour, minutes, seconds);\n            const utcTimestamp = dateTime.getTime();\n\n            const interval = setInterval(() => {\n                const currentTime = new Date().getTime();\n                const timeRemaining = utcTimestamp - currentTime;\n\n                if (timeRemaining <= 0) {\n                    clearInterval(interval);\n                    logBox.innerText = 'Mouredev Pro has launched! Welcome to the community campus to study programming in a different way!';\n                } else {\n                    const days = Math.floor(timeRemaining / (1000 * 60 * 60 * 24));\n                    const hours = Math.floor((timeRemaining % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));\n                    const minutes = Math.floor((timeRemaining % (1000 * 60 * 60)) / (1000 * 60));\n                    const seconds = Math.floor((timeRemaining % (1000 * 60)) / 1000);\n\n                    logBox.innerText = `${days}d ${hours}h ${minutes}m ${seconds}s`;\n                }\n            }, 1000);\n        };\n\n        // Set the countdown to December 31, 2024 at 00:00:00 UTC\n        countBackFromDate(31, 12, 2024, 0, 0, 0);\n    </script>\n</body>\n</html>\n'''\n\n@app.route('/')\ndef index():\n    return render_template_string(html_content)\n\nif __name__ == '__main__':\n    app.run(debug=True)\n"
  },
  {
    "path": "Roadmap/44 - CUENTA ATRÁS MOUREDEV PRO/python/hectorio23.py",
    "content": "# Autor: Héctor Adán\n# GitHub: https://github.com/hectorio23\n\nimport time\nimport datetime\nimport os\nimport threading\n\n# Función para la cuenta atrás\ndef countdown(target_datetime):\n    while True:\n        now = datetime.datetime.utcnow()\n        remaining = target_datetime - now\n\n        # Si el tiempo restante es menor o igual a cero, finalizamos\n        if remaining.total_seconds() <= 0:\n            os.system(\"cls\" if os.name == \"nt\" else \"clear\")\n            print(\"¡Cuenta atrás finalizada!\")\n            break\n\n        # Desglosamos días, horas, minutos y segundos\n        days = remaining.days\n        seconds = remaining.seconds\n        hours = seconds // 3600\n        minutes = (seconds % 3600) // 60\n        seconds = seconds % 60\n\n        os.system(\"cls\" if os.name == \"nt\" else \"clear\")\n        print(f\"Tiempo restante: {days} días, {hours} horas, {minutes} minutos, {seconds} segundos\")\n        time.sleep(1)\n\n# Entrada de usuario\ndef main():\n    day = int(input(\"Día: \"))\n    month = int(input(\"Mes: \"))\n    year = int(input(\"Año: \"))\n    hour = int(input(\"Hora: \"))\n    minute = int(input(\"Minuto: \"))\n    second = int(input(\"Segundo: \"))\n\n    # Convertimos la fecha local a UTC\n    local_time = datetime.datetime(year, month, day, hour, minute, second)\n    target_utc = local_time - datetime.timedelta(seconds=time.timezone)\n\n    print(f\"Fecha objetivo (UTC): {target_utc}\")\n\n    # Lanzamos el hilo\n    threading.Thread(target=countdown, args=(target_utc,), daemon=True).start()\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/44 - CUENTA ATRÁS MOUREDEV PRO/python/hozlucas28.py",
    "content": "# pylint: disable=missing-module-docstring,missing-function-docstring\n\nfrom datetime import date, datetime, timedelta\nfrom asyncio import sleep, run\nfrom os import system\nfrom threading import Thread\nfrom typing import TypedDict\nimport math\n\nTimeRemaining = TypedDict(\n    \"TimeRemaining\",\n    {\n        \"days\": int,\n        \"hours\": int,\n        \"minutes\": int,\n        \"seconds\": int,\n    },\n)\n\n\ndef get_time_remaining(*, _from: date, _to: date) -> TimeRemaining:\n    time_remaining: TimeRemaining = {\"days\": 0, \"hours\": 0, \"minutes\": 0, \"seconds\": 0}\n\n    diff_dates: timedelta = _to - _from\n    total_seconds: int = diff_dates.seconds\n\n    time_remaining[\"days\"] = diff_dates.days\n\n    time_remaining[\"hours\"] = math.floor(total_seconds / 3600)\n    total_seconds -= time_remaining[\"hours\"] * 3600\n\n    time_remaining[\"minutes\"] = math.floor(total_seconds / 60)\n    total_seconds -= time_remaining[\"minutes\"] * 60\n\n    time_remaining[\"seconds\"] = total_seconds\n\n    return time_remaining\n\n\nasync def main() -> None:\n    start_date: date = datetime.now()\n    end_date: date = datetime(year=2024, month=11, day=28, hour=0, minute=59, second=0)\n\n    remaining_time: TimeRemaining = get_time_remaining(_from=start_date, _to=end_date)\n\n    system(command=\"clear\")\n\n    print(\n        f\"> Time remaining for {end_date}: \"\n        f\"[ {remaining_time['days']:{0}6} days | \"\n        f\"{remaining_time['hours']:{0}2} hours | \"\n        f\"{remaining_time['minutes']:{0}2} minutes | \"\n        f\"{remaining_time['seconds']:{0}2} seconds ].\"\n    )\n\n    while (\n        remaining_time[\"days\"]\n        or remaining_time[\"hours\"]\n        or remaining_time[\"minutes\"]\n        or remaining_time[\"seconds\"]\n    ):\n        start_date: date = datetime.now()\n\n        await sleep(delay=1)\n        remaining_time = get_time_remaining(_from=start_date, _to=end_date)\n\n        system(command=\"clear\")\n\n        print(\n            f\"> Time remaining for {end_date}: \"\n            f\"[ {remaining_time['days']:{0}6} days | \"\n            f\"{remaining_time['hours']:{0}2} hours | \"\n            f\"{remaining_time['minutes']:{0}2} minutes | \"\n            f\"{remaining_time['seconds']:{0}2} seconds ].\"\n        )\n\n    print(\"\\n> The day has come!\")\n\n\nThread(\n    target=run,\n    kwargs={\n        \"main\": main(),\n    },\n).start()\n"
  },
  {
    "path": "Roadmap/44 - CUENTA ATRÁS MOUREDEV PRO/python/idiegorojas.py",
    "content": "\"\"\"\n44 - Cuneta regresiva Mouredev Pro\n\"\"\"\n# Crea un programa que funcione como una cuenta atrás.\n    # Al iniciarlo tendrás que indicarle el día, mes, año, hora, minuto y segundo en el que quieres que finalice.\n    # Deberás transformar esa fecha local a UTC.\n    # La cuenta atrás comenzará y mostrará los días, horas, minutos y segundos que faltan.\n    # Se actualizará cada segundo y borrará la terminal en cada nueva representación del tiempo restante.\n    # Una vez finalice, mostrará un mensaje.\n    # Realiza la ejecución, si el lenguaje lo soporta, en un hilo independiente.\n\n\nfrom datetime import datetime\nimport pytz\nimport time\nimport os\nimport threading\n\n# Diccionario de zonas horarias\ntime_zones = {\n    \"CO\": \"America/Bogota\",\n    \"MX\": \"America/Mexico_City\",\n    \"ES\": \"Europe/Madrid\",\n    \"US\": \"America/New_York\",\n}\n\ndef clear_terminal():\n    \"\"\"Limpia la terminal según el sistema operativo\"\"\"\n    os.system('cls' if os.name == 'nt' else 'clear')\n\ndef get_target_datetime():\n    \"\"\"Solicita al usuario la fecha y hora objetivo\"\"\"\n    print(\"Ingresa la fecha y hora objetivo para la cuenta regresiva\")\n    \n    try:\n        year = int(input(\"Año (ej. 2025): \"))\n        month = int(input(\"Mes (1-12): \"))\n        day = int(input(\"Día (1-31): \"))\n        hour = int(input(\"Hora (0-23): \"))\n        minute = int(input(\"Minuto (0-59): \"))\n        second = int(input(\"Segundo (0-59): \"))\n        \n        # Solicitar zona horaria\n        print(\"\\nSelecciona tu zona horaria:\")\n        for code, zone in time_zones.items():\n            print(f\"{code}: {zone}\")\n        \n        zone_code = input(\"Código de zona horaria: \").upper()\n        if zone_code not in time_zones:\n            print(\"Zona horaria no válida, usando UTC\")\n            timezone = pytz.UTC\n        else:\n            timezone = pytz.timezone(time_zones[zone_code])\n        \n        # Crear datetime y aplicar zona horaria\n        local_datetime = timezone.localize(datetime(year, month, day, hour, minute, second))\n        # Convertir a UTC\n        utc_datetime = local_datetime.astimezone(pytz.UTC)\n        \n        return utc_datetime\n        \n    except ValueError:\n        print(\"Valores incorrectos, usando fecha por defecto\")\n        return pytz.UTC.localize(datetime(2025, 4, 21, 6, 30, 0))\n\ndef countdown(target_datetime):\n    \"\"\"Ejecuta la cuenta regresiva hasta la fecha objetivo\"\"\"\n    while True:\n        # Obtener la hora actual en UTC\n        now = datetime.now(pytz.UTC)\n        \n        # Calcular diferencia\n        diff = target_datetime - now\n        total_seconds = diff.total_seconds()\n        \n        if total_seconds <= 0:\n            clear_terminal()\n            print(\"¡La cuenta regresiva ha terminado!\")\n            break\n        \n        # Calcular días, horas, minutos y segundos\n        days = int(total_seconds // (24 * 3600))\n        total_seconds %= (24 * 3600)\n        hours = int(total_seconds // 3600)\n        total_seconds %= 3600\n        minutes = int(total_seconds // 60)\n        seconds = int(total_seconds % 60)\n        \n        # Limpiar terminal y mostrar cuenta regresiva\n        clear_terminal()\n        print(f\"Tiempo restante: {days} días, {hours} horas, {minutes} minutos, {seconds} segundos\")\n        \n        # Esperar un segundo\n        time.sleep(1)\n\ndef main():\n    \"\"\"Función principal del programa\"\"\"\n    print(\"=== CUENTA REGRESIVA ===\")\n    target_datetime = get_target_datetime()\n    \n    print(f\"\\nFecha objetivo (UTC): {target_datetime}\")\n    print(\"Iniciando cuenta regresiva en 3 segundos...\")\n    time.sleep(3)\n    \n    # Iniciar la cuenta regresiva en un hilo separado\n    countdown_thread = threading.Thread(target=countdown, args=(target_datetime,))\n    countdown_thread.start()\n    \n    # El hilo principal puede hacer otras cosas mientras la cuenta regresiva se ejecuta\n    # Para este ejemplo simplemente esperamos a que termine\n    countdown_thread.join()\n    \n    print(\"Programa finalizado\")\n\nif __name__ == \"__main__\":\n    main()"
  },
  {
    "path": "Roadmap/44 - CUENTA ATRÁS MOUREDEV PRO/python/ignaciovihe.py",
    "content": "\"\"\" * EJERCICIO:\n * ¡El 12 de noviembre lanzo mouredev pro!\n * El campus de la comunidad para estudiar programación de\n * una manera diferente: https://mouredev.pro\n *\n * Crea un programa que funcione como una cuenta atrás.\n *\n * - Al iniciarlo tendrás que indicarle el día, mes, año,\n *   hora, minuto y segundo en el que quieres que finalice.\n * - Deberás transformar esa fecha local a UTC.\n * - La cuenta atrás comenzará y mostrará los días, horas,\n *   minutos y segundos que faltan.\n * - Se actualizará cada segundo y borrará la terminal en\n *   cada nueva representación del tiempo restante.\n * - Una vez finalice, mostrará un mensaje.\n * - Realiza la ejecución, si el lenguaje lo soporta, en\n *   un hilo independiente.\"\"\"\n\n\nfrom datetime import datetime, timedelta, timezone\nfrom dateutil.relativedelta import relativedelta\nimport threading\nimport time\nimport os\n\ndef print_resting_time(final_date: datetime, now: datetime):\n\n    diff = relativedelta(final_date, now)\n\n    print(f\"{diff.years} años - {diff.months} meses - {diff.days} días - {diff.hours} horas - {diff.minutes} minutos - {diff.seconds} segundos.\")\n\n\ndef counter(final_date_utc , now_utc):\n    os.system('cls' if os.name == 'nt' else 'clear')\n\n    while (final_date_utc - now_utc) > timedelta(0):\n        os.system('cls' if os.name == 'nt' else 'clear')\n        now_utc = datetime.now(timezone.utc).replace(microsecond=0)\n        print_resting_time(final_date_utc, now_utc)\n\n        time.sleep(1)\n\n    print(\"Temporizador terminado!!!\")\n\n\ndate = input(\"Introduce una fecha con el siguiente formato. ej: '30-07-2025 15:45:00'\")\n# Se obtiene un datetime de un str, pasandole el formato que tendrá la entrada.\nfinal_date = datetime.strptime(date, \"%d-%m-%Y %H:%M:%S\")\n\n# Como el datetime no tiene uso horario, lo reemplazamos (propiedad tzinfo) por el uso horario,\n# de un datenime.now con uso horario.\nfinal_date = final_date.replace(tzinfo=datetime.now().astimezone().tzinfo)\n\n# Una vez que nuestra fecha ya tiene uso horario, usamos astimezone para cambiarlo a utc.\nfinal_date_utc = final_date.astimezone(timezone.utc).replace(microsecond=0)\n\n# CVuando usamos now, no hace falta hacer lo anterior, podemos pedirlo como parametro directamente.\nnow_utc = datetime.now(timezone.utc).replace(microsecond=0)\n\n# Lanzamos un hilo para que se ejecute en segundo plano. daemon indica si debe parar cuando termine el resto de la ejecución.\n# en este caso pongo false porque como el programa no hace otra cosa, terminaria de inmediato si hacer la cuenta atras.\nthread = threading.Thread(target=counter,args=(final_date_utc ,now_utc,), daemon=False)\nthread.start()\n\n\n\n\n\n\n"
  },
  {
    "path": "Roadmap/44 - CUENTA ATRÁS MOUREDEV PRO/python/joselorentelopez.py",
    "content": "import os\nimport time\nfrom datetime import datetime\nfrom threading import Thread\n\nclass Error_Handler():\n    def __init__(self) -> None:\n        \"\"\"\n        Initializes the Error_Handler class.\n\n        This class is used to handle errors related to invalid inputs,\n        ensuring that the user inputs valid values within specified ranges.\n        \"\"\"\n        pass\n\n    @staticmethod\n    def get_valid_input(prompt, min_value, max_value):\n        \"\"\"\n        Prompts the user for input and validates it within the given range.\n\n        This method keeps asking the user for input until a valid integer\n        within the specified range is entered.\n\n        Args:\n            prompt (str): The message displayed to the user.\n            min_value (int): The minimum valid value for the input.\n            max_value (int): The maximum valid value for the input.\n\n        Returns:\n            int: The valid input entered by the user.\n        \"\"\"\n        while True:\n            try:\n                value = int(input(prompt))\n                if value < min_value or value > max_value:\n                    print(f\"Please enter a value between {min_value} and {max_value}.\")\n                else:\n                    return value\n            except ValueError:\n                print(\"Invalid input. Please enter an integer.\")\n\nclass Counter():\n    def __init__(self) -> None:\n        \"\"\"\n        Initializes the Counter class.\n\n        This class is responsible for managing the countdown process,\n        including gathering user input for the target date and time,\n        calculating the remaining time, and running the countdown.\n        \"\"\"\n\n        self.error_handler = Error_Handler()\n\n    def _mark_date(self):\n        \"\"\"\n        Prompts the user to enter a target date and time for the countdown.\n\n        This method asks the user for year, month, day, hour, minute, and second\n        to specify the target date and time. It also calculates the time difference\n        between the current time and the specified target time.\n\n        Args:\n            None\n\n        Returns:\n            None\n        \"\"\"\n\n        current_year = datetime.now().year\n\n        year = self.error_handler.get_valid_input(\"Enter the year (YYYY): \", current_year, current_year + 100)\n        month = self.error_handler.get_valid_input(\"Enter the month (MM): \", 1, 12)\n\n        while True:\n            day = self.error_handler.get_valid_input(\"Enter the day (DD): \", 1, 31) \n            try:\n                datetime(year, month, day)\n                break\n            except ValueError:\n                print(\"Invalid day for the given month and year. Please try again.\")\n\n        hour = self.error_handler.get_valid_input(\"Enter the hour (24-hour format HH): \", 0, 23)\n        minute = self.error_handler.get_valid_input(\"Enter the minute (MM): \", 0, 59)\n        second = self.error_handler.get_valid_input(\"Enter the second (SS): \", 0, 59)\n\n        end_time  = datetime(year, month, day, hour, minute, second)\n        diff = end_time - datetime.now()\n\n        self.days = diff.days\n        self.seconds = diff.seconds\n\n    def _counter(self):\n        \"\"\"\n        Starts the countdown from the calculated remaining time.\n\n        This method uses the total remaining time (in seconds) and counts down,\n        updating the display every second. It also handles clearing the console\n        to keep the display updated in real-time.\n\n        Args:\n            None\n\n        Returns:\n            None\n        \"\"\"\n\n        total_seconds = self.days * 86400 + self.seconds\n\n        for x in range(total_seconds, 0, -1):\n            days = x // 86400  \n            hours = (x % 86400) // 3600  \n            minutes = (x % 3600) // 60  \n            seconds = x % 60  \n\n            # Clear the console in every iteration\n            if os.name == 'posix':\n                os.system('clear')\n\n            print(\"{:02d}:{:02d}:{:02d}:{:02d}\".format(days, hours, minutes, seconds))\n            \n            time.sleep(1)  \n\n        print(\"Time's up!\")\n    \n    def run(self):\n        \"\"\"\n        Runs the complete countdown process.\n\n        This method initiates the process by calling `_mark_date` to get the target\n        time and `_counter` to start the countdown.\n        \"\"\"\n\n        self._mark_date()\n        self._counter()\n\ndef main():\n    \"\"\"\n    Runs the main function of the project.\n    \"\"\"\n    \n    counter = Counter()\n    counter_thread = Thread(target=counter.run())\n    counter_thread.start()\n\nif __name__ == \"__main__\":\n    main()"
  },
  {
    "path": "Roadmap/44 - CUENTA ATRÁS MOUREDEV PRO/python/juanppdev.py",
    "content": "\"\"\"\n * EJERCICIO:\n * ¡El 12 de noviembre lanzo mouredev pro!\n * El campus de la comunidad para estudiar programación de\n * una manera diferente: https://mouredev.pro\n *\n * Crea un programa que funcione como una cuenta atrás.\n *\n * - Al iniciarlo tendrás que indicarle el día, mes, año,\n *   hora, minuto y segundo en el que quieres que finalice.\n * - Deberás transformar esa fecha local a UTC.\n * - La cuenta atrás comenzará y mostrará los días, horas,\n *   minutos y segundos que faltan.\n * - Se actualizará cada segundo y borrará la terminal en\n *   cada nueva representación del tiempo restante.\n * - Una vez finalice, mostrará un mensaje.\n * - Realiza la ejecución, si el lenguaje lo soporta, en\n *   un hilo independiente.\n\"\"\"\n\nimport datetime\nimport time\nimport threading\nimport os\n\ndef clear_console():\n    # Borra la consola. Usa \"cls\" para Windows o \"clear\" para Linux/macOS.\n    os.system('cls' if os.name == 'nt' else 'clear')\n\ndef countdown(target_datetime_utc):\n    while True:\n        # Calculamos la diferencia entre la fecha objetivo y la fecha actual\n        current_time_utc = datetime.datetime.utcnow()\n        remaining_time = target_datetime_utc - current_time_utc\n\n        # Si la cuenta regresiva ha terminado, salimos del bucle\n        if remaining_time.total_seconds() <= 0:\n            clear_console()\n            print(\"¡La cuenta atrás ha finalizado!\")\n            break\n\n        # Extraemos días, horas, minutos y segundos de la diferencia\n        days = remaining_time.days\n        hours, remainder = divmod(remaining_time.seconds, 3600)\n        minutes, seconds = divmod(remainder, 60)\n\n        # Limpiamos la consola y mostramos el tiempo restante\n        clear_console()\n        print(f\"Tiempo restante: {days} días, {hours} horas, {minutes} minutos, {seconds} segundos\")\n        \n        # Esperamos un segundo antes de la siguiente actualización\n        time.sleep(1)\n\n# Solicitamos la fecha y hora de finalización al usuario\nday = int(input(\"Día de finalización: \"))\nmonth = int(input(\"Mes de finalización: \"))\nyear = int(input(\"Año de finalización: \"))\nhour = int(input(\"Hora de finalización: \"))\nminute = int(input(\"Minuto de finalización: \"))\nsecond = int(input(\"Segundo de finalización: \"))\n\n# Creamos el objeto datetime en el horario local\ntarget_datetime_local = datetime.datetime(year, month, day, hour, minute, second)\n\n# Convertimos la fecha local a UTC\ntarget_datetime_utc = target_datetime_local - datetime.timedelta(hours=time.localtime().tm_gmtoff // 3600)\n\n# Ejecutamos la cuenta regresiva en un hilo independiente\ncountdown_thread = threading.Thread(target=countdown, args=(target_datetime_utc,))\ncountdown_thread.start()\n"
  },
  {
    "path": "Roadmap/44 - CUENTA ATRÁS MOUREDEV PRO/python/kenysdev.py",
    "content": "# _____________________________________\n# https://github.com/kenysdev\n# 2024 - Python\n# _____________________________________\n# 44 CUENTA ATRÁS MOUREDEV PRO\n# ------------------------------------\n\n\"\"\"\n* EJERCICIO:\n * ¡El 12 de noviembre lanzo mouredev pro!\n * El campus de la comunidad para estudiar programación de\n * una manera diferente: https://mouredev.pro\n *\n * Crea un programa que funcione como una cuenta atrás.\n *\n * - Al iniciarlo tendrás que indicarle el día, mes, año,\n *   hora, minuto y segundo en el que quieres que finalice.\n * - Deberás transformar esa fecha local a UTC.\n * - La cuenta atrás comenzará y mostrará los días, horas,\n *   minutos y segundos que faltan.\n * - Se actualizará cada segundo y borrará la terminal en\n *   cada nueva representación del tiempo restante.\n * - Una vez finalice, mostrará un mensaje.\n * - Realiza la ejecución, si el lenguaje lo soporta, en\n *   un hilo independiente.\n\"\"\"\n\nfrom datetime import datetime, timezone, timedelta\nimport threading\nimport os\nimport time\n\nclass ReverseTimer:\n    def __init__(self, end_date: str) -> None:\n        self.__end_date = datetime.fromisoformat(\n            end_date\n        ).replace(tzinfo=timezone.utc)\n\n    def __time_remaining(self) -> timedelta:\n        now = datetime.now(timezone.utc)\n        delta = self.__end_date - now\n        return max(delta, timedelta(0))\n    \n    def __has_finished(self) -> bool:\n        return self.__time_remaining() == timedelta(0)\n\n    def __str__(self) -> str:\n        delta = self.__time_remaining()\n        hours, remainder = divmod(delta.seconds, 3600)\n        minutes, seconds = divmod(remainder, 60)\n        min_sec: str = f\"{minutes} minutos, {seconds} segundos\"\n        return f\"{delta.days} dias, {hours} horas, {min_sec}.\"\n        \n    def print_remaining(self) -> None:\n        while True:\n            os.system('cls' if os.name == 'nt' else 'clear')\n            print(\"Tiempo restante:\")\n            print(self.__str__())\n\n            if self.__has_finished():\n                print(\"¡Cuenta atrás finalizada!\")\n                return\n            time.sleep(1)\n\nif __name__ == \"__main__\":\n    end_date:str = \"2024-12-31T23:59:59.999999\"\n    timer = ReverseTimer(end_date)\n    reverse_timer_thread = threading.Thread(target=timer.print_remaining)\n    reverse_timer_thread.start()\n    reverse_timer_thread.join()\n\n"
  },
  {
    "path": "Roadmap/44 - CUENTA ATRÁS MOUREDEV PRO/python/ljoecordoba.py",
    "content": "import time\nimport datetime\nimport threading\nimport os\nimport pytz\n\ndef countdown(target_date_utc):\n    while True:\n        now_utc = datetime.datetime.now(datetime.timezone.utc)\n        time_diff = target_date_utc - now_utc\n\n        if time_diff.total_seconds() <= 0:\n            print(\"¡La cuenta atrás ha finalizado!\")\n            break\n\n        days = time_diff.days\n        hours, remainder = divmod(time_diff.seconds, 3600)\n        minutes, seconds = divmod(remainder, 60)\n\n        # Limpia la terminal para mostrar la cuenta atrás actualizada\n        os.system('cls' if os.name == 'nt' else 'clear')\n        print(f\"Tiempo restante: {days} días, {hours} horas, {minutes} minutos, {seconds} segundos\")\n\n        time.sleep(1)\n\nprint(\"Introduce la fecha y hora de finalización en formato de 24 horas.\")\nyear = int(input(\"Año (YYYY): \"))\nmonth = int(input(\"Mes (MM): \"))\nday = int(input(\"Día (DD): \"))\nhour = int(input(\"Hora (HH): \"))\nminute = int(input(\"Minuto (MM): \"))\nsecond = int(input(\"Segundo (SS): \"))\n\nlocal_time = datetime.datetime(year, month, day, hour, minute, second)\nlocal_timezone = datetime.datetime.now().astimezone().tzinfo\ntarget_date_utc = local_time.astimezone(pytz.utc)\n\ncountdown_thread = threading.Thread(target=countdown, args=(target_date_utc,))\ncountdown_thread.start()\ncountdown_thread.join()\n"
  },
  {
    "path": "Roadmap/44 - CUENTA ATRÁS MOUREDEV PRO/python/mhayhem.py",
    "content": "# @Author Daniel Grande  (Mhayhem)\n\n\n# ¡El 12 de noviembre lanzo mouredev pro!\n# El campus de la comunidad para estudiar programación de\n# una manera diferente: https://mouredev.pro\n#\n# Crea un programa que funcione como una cuenta atrás.\n#\n# - Al iniciarlo tendrás que indicarle el día, mes, año,\n#   hora, minuto y segundo en el que quieres que finalice.\n# - Deberás transformar esa fecha local a UTC.\n# - La cuenta atrás comenzará y mostrará los días, horas,\n#   minutos y segundos que faltan.\n# - Se actualizará cada segundo y borrará la terminal en\n#   cada nueva representación del tiempo restante.\n# - Una vez finalice, mostrará un mensaje.\n# - Realiza la ejecución, si el lenguaje lo soporta, en\n#   un hilo independiente.\n\nfrom datetime import timedelta, timezone, date, datetime\nimport os\nfrom time import sleep\nimport threading\n\ndef countdown(finally_date):\n    \n    \n    while True:\n        os.system(\"cls\" if os.name == \"nt\" else (\"clear\"))\n        final_countdown = finally_date - datetime.now()\n        \n        if final_countdown.total_seconds() <= 0:\n            print(\"La cuenta final ha terminado.\")\n            break\n        \n        seconds = int(final_countdown.total_seconds())\n        \n        days = seconds // 86400\n        hours = (seconds % 86400) // 3600\n        minutes = (seconds % 3600) // 60\n        secs = seconds % 60\n        \n        print(f\"Dias: {days}, horas: {hours:02}, minutos: {minutes:02}, segundos: {secs:02}.\")\n        sleep(1)\n\ndef main():\n    days, month, year = input(\"Diganos una fecha de finalizacion de la cuenta atras: (dd/mm/aaaa)\").split(\"/\")\n    optional = input(\"¿Quieres añadir una hora específica?\").lower()\n    match optional:\n        case \"si\":\n            hour, minutes, seconds = input(\"Indique la hora: (hh:mm:ss)\").split(\":\")\n            finally_date = datetime(int(year), int(month), int(days), int(hour), int(minutes), int(seconds))\n        case \"no\":\n            finally_date = datetime(int(year), int(month), int(days))\n        case _:\n            print(\"La opción no es valida.\")\n    \n    thread = threading.Thread(target=countdown, args=(finally_date,))\n    thread.start()\n    print(\"La cuenta atras se esta ejecutando en otro hilo.\")\n\n\nif __name__==\"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/44 - CUENTA ATRÁS MOUREDEV PRO/python/mouredev.py",
    "content": "import datetime\nimport time\nimport os\nimport threading\n\n\ndef countdown(target_date):\n\n    while True:\n\n        now_date_utc = datetime.datetime.now(datetime.timezone.utc)\n\n        remaining_time = target_date - now_date_utc\n\n        if remaining_time.total_seconds() <= 0:\n            print(\"\\n¡Cuenta atrás finalizada!\")\n            break\n\n        days, seconds = divmod(remaining_time.total_seconds(), 86400)\n        hours, seconds = divmod(seconds, 3600)\n        minutes, seconds = divmod(seconds, 60)\n\n        os.system(\"clear\")\n\n        print(\n            f\"Tiempo restante: {int(days)} días, {int(hours)} horas, {int(minutes)} minutos, {int(seconds)} segundos\")\n\n        time.sleep(1)\n\n\nlocal_date = datetime.datetime(2024, 11, 11, 20, 47, 00)\nlocal_date = local_date.replace(\n    tzinfo=datetime.datetime.now().astimezone().tzinfo)\n\ntarget_date_utc = local_date.astimezone(datetime.timezone.utc)\n\ncountdown_thread = threading.Thread(target=countdown, args=(target_date_utc,))\ncountdown_thread.start()\ncountdown_thread.join()\n"
  },
  {
    "path": "Roadmap/44 - CUENTA ATRÁS MOUREDEV PRO/python/neslarra.py",
    "content": "r\"\"\"\n EJERCICIO:\n ¡El 12 de noviembre lanzo mouredev pro!\n El campus de la comunidad para estudiar programación de\n una manera diferente: https://mouredev.pro\n\n Crea un programa que funcione como una cuenta atrás.\n\n - Al iniciarlo tendrás que indicarle el día, mes, año,\n   hora, minuto y segundo en el que quieres que finalice.\n - Deberás transformar esa fecha local a UTC.\n - La cuenta atrás comenzará y mostrará los días, horas,\n   minutos y segundos que faltan.\n - Se actualizará cada segundo y borrará la terminal en\n   cada nueva representación del tiempo restante.\n - Una vez finalice, mostrará un mensaje.\n - Realiza la ejecución, si el lenguaje lo soporta, en\n   un hilo independiente.\n\"\"\"\nfrom datetime import datetime as dt, timezone as tz\nfrom threading import Thread\nfrom os import system, name\nfrom time import sleep\n\nEND_TIME = dt.strptime('20241122112725', '%Y%m%d%H%M%S').replace(\n    tzinfo=dt.now().astimezone().tzinfo).astimezone(tz.utc)\n\n\nclass Clock(Thread):\n    def run(self):\n        while dt.now(tz.utc) < END_TIME:\n            if name == \"posix\":\n                system(\"clear\")\n            else:\n                system(\"cls\")\n            current_time = END_TIME - dt.now(tz.utc)\n            days_left = current_time.days\n            hours_left = current_time.seconds // 3600\n            minutes_left = (current_time.seconds % 3600) // 60\n            seconds_left = current_time.seconds - hours_left * 3600 - minutes_left * 60\n            print(f\"Faltan: {days_left} días, {hours_left} horas, {minutes_left} minutos, {seconds_left} segundos\")\n            sleep(1)\n        print(f\"TERMINADO: {END_TIME} {dt.now(tz.utc)}\")\n\n\nclass Counter(Thread):\n    def run(self):\n        count = 0\n        while dt.now(tz.utc) < END_TIME:\n            count += 1\n            print(f\"Vamos contando {count}\")\n            sleep(1)\n        print(f\"Terminé de contar en {count}\")\n\n\nClock().start()\nsleep(0.5)\nCounter().start()\n"
  },
  {
    "path": "Roadmap/44 - CUENTA ATRÁS MOUREDEV PRO/python/pyramsd.py",
    "content": "from datetime import datetime, timedelta, timezone\nimport time, os, threading\n\ndetener_evento = threading.Event()\n\ndef cuenta_regresiva(fecha_dada_utc, fecha_limite_utc):\n    # Inicializar el tiempo de inicio como la fecha dada\n    start = fecha_dada_utc\n\n    while not detener_evento.is_set():\n        # Calcular tiempo restante desde la fecha dada\n        tiempo_restante = fecha_limite_utc - start\n\n        if tiempo_restante <= timedelta(0):  # Si el tiempo restante es cero o negativo, se termina\n            os.system(\"cls\" if os.name == \"nt\" else \"clear\")\n            print(\"\\u00a1La cuenta regresiva ha terminado!\")\n            break\n\n        # Descomponer el tiempo restante\n        dias = tiempo_restante.days\n        horas, resto = divmod(tiempo_restante.seconds, 3600)\n        minutos, segundos = divmod(resto, 60)\n\n        # Limpiar la consola y mostrar el tiempo restante\n        os.system(\"cls\" if os.name == \"nt\" else \"clear\")\n        print(f\"Tiempo restante desde la fecha dada: {dias}d - {horas}h - {minutos}m - {segundos}s\")\n        print(\"Presiona Enter para detener el contador ¡Ctrl + C no funciona!...\")\n\n        # Incrementar la fecha de inicio en un segundo\n        start += timedelta(seconds=1)\n\n        time.sleep(1)\n\nyear = input(\"Año: \")\nmes = input(\"Mes: \")\ndia = input(\"Día: \")\nhora = input(\"Hora: \")\nminuto = input(\"Minuto: \")\nsegundos = input(\"Segundos: \")\n\nfecha_dada = f\"{year}-{mes}-{dia} {hora}:{minuto}:{segundos}\"\nfecha_dada = datetime.strptime(fecha_dada, \"%Y-%m-%d %H:%M:%S\")\nfecha_dada_utc = fecha_dada.replace(tzinfo=timezone.utc)\n\nfecha_limite = \"2024-12-31 23:59:00\"\nfecha_limite = datetime.strptime(fecha_limite, \"%Y-%m-%d %H:%M:%S\")\nfecha_limite_utc = fecha_limite.replace(tzinfo=timezone.utc)\n\ndef esperar_input():\n    input()\n    detener_evento.set()\n\nhilo_cuenta_regresiva = threading.Thread(target=cuenta_regresiva, args=(fecha_dada_utc, fecha_limite_utc))\nhilo_cuenta_regresiva.start()\n\nhilo_esperar_input = threading.Thread(target=esperar_input)\nhilo_esperar_input.start()\n\n# Esperar a que ambos hilos terminen\nhilo_cuenta_regresiva.join()\nhilo_esperar_input.join()\n\nprint(\"Programa terminado.\")\n"
  },
  {
    "path": "Roadmap/44 - CUENTA ATRÁS MOUREDEV PRO/python/rigo93acosta.py",
    "content": "\"\"\"\n * EJERCICIO:\n * ¡El 12 de noviembre lanzo mouredev pro!\n * El campus de la comunidad para estudiar programación de\n * una manera diferente: https://mouredev.pro\n *\n * Crea un programa que funcione como una cuenta atrás.\n *\n * - Al iniciarlo tendrás que indicarle el día, mes, año,\n *   hora, minuto y segundo en el que quieres que finalice.\n * - Deberás transformar esa fecha local a UTC.\n * - La cuenta atrás comenzará y mostrará los días, horas,\n *   minutos y segundos que faltan.\n * - Se actualizará cada segundo y borrará la terminal en\n *   cada nueva representación del tiempo restante.\n * - Una vez finalice, mostrará un mensaje.\n * - Realiza la ejecución, si el lenguaje lo soporta, en\n *   un hilo independiente.\n\"\"\"\n\nimport datetime\nimport time\nimport threading\n\ndef countdown(end):\n    target_end = end.astimezone(datetime.timezone.utc)\n\n    while True:\n        now = datetime.datetime.now().astimezone(datetime.timezone.utc)\n        diff = target_end - now\n\n        if diff.total_seconds() <= 0:\n            print(\"\\nCuenta atrás finalizada!!!\\n\")\n            break\n        else:\n            print(f\"Tiempo restante {diff.days:02} days \" +\n                  f\"{diff.seconds//3600:02} hours \" +\n                  f\"{diff.seconds//60%60:02} minutes \" +\n                  f\"{diff.seconds%60:02} seconds\", end='\\r')\n            time.sleep(1)\n\nif __name__ == '__main__':\n    end = datetime.datetime(2024, 11, 23, 11, 24, 00)\n    end = end.replace(\n        tzinfo=datetime.datetime.now().astimezone().tzinfo\n        )\n \n    thread = threading.Thread(target=countdown, args=(end,))\n    thread.start()\n    thread.join()\n    \n    # while True:\n    #     now = datetime.datetime.now().astimezone(datetime.timezone.utc)\n    #     diff = target_end - now\n\n    #     if diff.total_seconds() <= 0:\n    #         print(\"\\nCuenta atrás finalizada!!!\\n\")\n    #         break\n    #     else:\n    #         print(f\"Tiempo restante {diff.days:02} days \" +\n    #               f\"{diff.seconds//3600:02} hours \" +\n    #               f\"{diff.seconds//60%60:02} minutes \" +\n    #               f\"{diff.seconds%60:02} seconds\", end='\\r')\n    #         time.sleep(1)\n"
  },
  {
    "path": "Roadmap/44 - CUENTA ATRÁS MOUREDEV PRO/rust/kenysdev.rs",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - Rust\n_____________________________________\n44 CUENTA ATRÁS MOUREDEV PRO\n------------------------------------\n\n* EJERCICIO:\n * ¡El 12 de noviembre lanzo mouredev pro!\n * El campus de la comunidad para estudiar programación de\n * una manera diferente: https://mouredev.pro\n *\n * Crea un programa que funcione como una cuenta atrás.\n *\n * - Al iniciarlo tendrás que indicarle el día, mes, año,\n *   hora, minuto y segundo en el que quieres que finalice.\n * - Deberás transformar esa fecha local a UTC.\n * - La cuenta atrás comenzará y mostrará los días, horas,\n *   minutos y segundos que faltan.\n * - Se actualizará cada segundo y borrará la terminal en\n *   cada nueva representación del tiempo restante.\n * - Una vez finalice, mostrará un mensaje.\n * - Realiza la ejecución, si el lenguaje lo soporta, en\n *   un hilo independiente.\n*/\n\nuse chrono::{DateTime, Utc, Duration};\nuse std::error::Error;\nuse std::fmt;\nuse std::thread;\nuse std::time::Duration as StdDuration;\nuse std::sync::{Arc, atomic::{AtomicBool, Ordering}};\n\n#[derive(Debug)]\nstruct TimeComponents {\n    days: i64,\n    hours: i64,\n    minutes: i64,\n    seconds: i64,\n}\n\n#[derive(Debug)]\nstruct TimerError(String);\n\nimpl fmt::Display for TimerError {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        write!(f, \"Timer error: {}\", self.0)\n    }\n}\n\nimpl Error for TimerError {}\n\nstruct ReverseTimer {\n    end_date: DateTime<Utc>,\n    running: Arc<AtomicBool>,\n}\n\nimpl ReverseTimer {\n    fn new(end_date: &str) -> Result<Self, TimerError> {\n        Ok(ReverseTimer {\n            end_date: DateTime::parse_from_rfc3339(end_date)\n                .map_err(|e| TimerError(format!(\"Invalid date format: {}\", e)))?\n                .with_timezone(&Utc),\n            running: Arc::new(AtomicBool::new(true)),\n        })\n    }\n\n    #[inline]\n    fn time_remaining(&self) -> Duration {\n        (self.end_date - Utc::now()).max(Duration::zero())\n    }\n\n    #[inline]\n    fn get_time_components(remaining: Duration) -> TimeComponents {\n        TimeComponents {\n            days: remaining.num_days(),\n            hours: remaining.num_hours() % 24,\n            minutes: remaining.num_minutes() % 60,\n            seconds: remaining.num_seconds() % 60,\n        }\n    }\n\n    fn format_time(components: &TimeComponents) -> String {\n        format!(\n            \"{} días, {} horas, {} minutos, {} segundos\",\n            components.days, components.hours, components.minutes, components.seconds\n        )\n    }\n\n    fn display_time(&self) {\n        print!(\"\\x1B[2J\\x1B[1;1H\");\n        let remaining = self.time_remaining();\n        let components = Self::get_time_components(remaining);\n        println!(\"Tiempo restante:\");\n        println!(\"{}\", Self::format_time(&components));\n    }\n\n    fn start_countdown(self) -> thread::JoinHandle<()> {\n        thread::spawn(move || {\n            while self.running.load(Ordering::Relaxed) {\n                let remaining = self.time_remaining();\n                \n                if remaining == Duration::zero() {\n                    self.running.store(false, Ordering::Relaxed);\n                    break;\n                }\n\n                self.display_time();\n                thread::sleep(StdDuration::from_secs(1));\n            }\n            println!(\"¡Cuenta atrás finalizada!\");\n        })\n    }\n\n    fn stop(&self) {\n        self.running.store(false, Ordering::Relaxed);\n    }\n}\n\nfn main() -> Result<(), Box<dyn Error>> {\n    let timer = ReverseTimer::new(\"2024-12-31T23:59:59.999999Z\")?;\n    let timer_thread = timer.start_countdown();\n\n    // timer.stop();\n    timer_thread.join().unwrap();\n    Ok(())\n}\n"
  },
  {
    "path": "Roadmap/44 - CUENTA ATRÁS MOUREDEV PRO/sql/Nicojsuarez2.sql",
    "content": "# #44 CUENTA ATRÁS MOUREDEV PRO\n> #### Dificultad: Fácil | Publicación: 04/11/24 | Corrección: 11/11/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * ¡El 12 de noviembre lanzo mouredev pro!\n * El campus de la comunidad para estudiar programación de\n * una manera diferente: https://mouredev.pro\n *\n * Crea un programa que funcione como una cuenta atrás.\n *\n * - Al iniciarlo tendrás que indicarle el día, mes, año,\n *   hora, minuto y segundo en el que quieres que finalice.\n * - Deberás transformar esa fecha local a UTC.\n * - La cuenta atrás comenzará y mostrará los días, horas,\n *   minutos y segundos que faltan.\n * - Se actualizará cada segundo y borrará la terminal en\n *   cada nueva representación del tiempo restante.\n * - Una vez finalice, mostrará un mensaje.\n * - Realiza la ejecución, si el lenguaje lo soporta, en\n *   un hilo independiente.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/44 - CUENTA ATRÁS MOUREDEV PRO/typescript/hozlucas28.ts",
    "content": "import {setTimeout} from 'node:timers/promises'\nimport {isMainThread, parentPort, Worker} from 'node:worker_threads'\n\ninterface TimeRemaining {\n    days: number\n    hours: number\n    minutes: number\n    seconds: number\n}\n\nfunction getTimeRemaining(from: Date, to: Date): TimeRemaining {\n    const epochFrom: number = from.valueOf()\n    const epochTo: number = to.valueOf()\n\n    let conversion: number\n    let epochRemainingTime: number = epochTo - epochFrom\n\n    if (epochRemainingTime <= 0)\n        return {\n            days: 0,\n            hours: 0,\n            minutes: 0,\n            seconds: 0,\n        }\n\n    conversion = 24 * 60 * 60 * 1000\n    const days: number = Math.floor(epochRemainingTime / conversion)\n    epochRemainingTime -= days * conversion\n\n    conversion = 60 * 60 * 1000\n    const hours: number = Math.floor(epochRemainingTime / conversion)\n    epochRemainingTime -= hours * conversion\n\n    conversion = 60 * 1000\n    const minutes: number = Math.floor(epochRemainingTime / conversion)\n    epochRemainingTime -= minutes * conversion\n\n    conversion = 1000\n    const seconds: number = Math.floor(epochRemainingTime / conversion)\n    epochRemainingTime -= seconds * conversion\n\n    return {\n        days: Math.max(0, days),\n        hours: Math.max(0, hours),\n        minutes: Math.max(0, minutes),\n        seconds: Math.max(0, seconds),\n    }\n}\n\nasync function main() {\n    let startDate: Date = new Date() // Current date\n    const endDate: Date = new Date(2024, 10, 27, 23, 59, 0, 0)\n    let remainingTime: TimeRemaining = getTimeRemaining(startDate, endDate)\n\n    if (!isMainThread) parentPort?.postMessage('clearConsole')\n\n    console.log(\n        `> Time remaining for ${endDate.toUTCString()}: ` +\n            `[ ${remainingTime.days.toString().padStart(6, '0')} days | ` +\n            `${remainingTime.hours.toString().padStart(2, '0')} hours | ` +\n            `${remainingTime.minutes.toString().padStart(2, '0')} minutes | ` +\n            `${remainingTime.seconds.toString().padStart(2, '0')} seconds ].`\n    )\n\n    while (\n        remainingTime.days ||\n        remainingTime.hours ||\n        remainingTime.minutes ||\n        remainingTime.seconds\n    ) {\n        startDate = new Date() // Current date\n        remainingTime = await setTimeout(\n            1 * 1000,\n            getTimeRemaining(startDate, endDate)\n        )\n\n        if (!isMainThread) parentPort?.postMessage('clearConsole')\n\n        console.log(\n            `> Time remaining for ${endDate.toUTCString()}: ` +\n                `[ ${remainingTime.days.toString().padStart(6, '0')} days | ` +\n                `${remainingTime.hours.toString().padStart(2, '0')} hours | ` +\n                `${remainingTime.minutes\n                    .toString()\n                    .padStart(2, '0')} minutes | ` +\n                `${remainingTime.seconds\n                    .toString()\n                    .padStart(2, '0')} seconds ].`\n        )\n    }\n\n    console.log('\\n> The day has come!')\n}\n\nif (isMainThread) {\n    const worker: Worker = new Worker(__filename)\n\n    worker.on('message', (message) => {\n        if (message === 'clearConsole') console.clear()\n    })\n} else {\n    main()\n}\n"
  },
  {
    "path": "Roadmap/44 - CUENTA ATRÁS MOUREDEV PRO/vb.net/kenysdev.vb",
    "content": "' _____________________________________\n' https://github.com/kenysdev\n' 2024 - vb.net\n' _____________________________________\n' 44 CUENTA ATRÁS MOUREDEV PRO\n' ------------------------------------\n'* EJERCICIO\n'* ¡El 12 de noviembre lanzo mouredev pro!\n' * El campus de la comunidad para estudiar programación de\n' * una manera diferente: https : //mouredev.pro\n' *\n' * Crea un programa que funcione como una cuenta atrás.\n' *\n' * - Al iniciarlo tendrás que indicarle el día, mes, año,\n' *   hora, minuto y segundo en el que quieres que finalice.\n' * - Deberás transformar esa fecha local a UTC.\n' * - La cuenta atrás comenzará y mostrará los días, horas,\n' *   minutos y segundos que faltan.\n' * - Se actualizará cada segundo y borrará la terminal en\n' *   cada nueva representación del tiempo restante.\n' * - Una vez finalice, mostrará un mensaje.\n' * - Realiza la ejecución, si el lenguaje lo soporta, en\n' *   un hilo independiente.\n\nImports System\nImports System.Threading\n\nPublic Class ReverseTimer\n    Private ReadOnly _endDate As DateTime\n    Private ReadOnly _countdownThread As Thread\n    Private _isRunning As Boolean = True\n\n    Public Sub New(endDate As String)\n        _endDate = DateTime.Parse(endDate).ToUniversalTime()\n        _countdownThread = New Thread(AddressOf RunCountdown)\n    End Sub\n\n    Private ReadOnly Property TimeRemaining As TimeSpan\n        Get\n            Return If(_endDate > DateTime.UtcNow, _endDate - DateTime.UtcNow, TimeSpan.Zero)\n        End Get\n    End Property\n\n    Private Sub RunCountdown()\n        While _isRunning AndAlso TimeRemaining > TimeSpan.Zero\n            Console.Clear()\n            Console.WriteLine(\"Tiempo restante:\")\n            Console.WriteLine(FormatTimeRemaining())\n\n            Thread.Sleep(1000)\n        End While\n\n        If TimeRemaining <= TimeSpan.Zero Then\n            Console.WriteLine(\"¡Cuenta atrás finalizada!\")\n        End If\n    End Sub\n\n    Private Function FormatTimeRemaining() As String\n        Dim delta = TimeRemaining\n        Return $\"{delta.Days} dias, {delta.Hours} horas, \" &\n               $\"{delta.Minutes} minutos, {delta.Seconds} segundos.\"\n    End Function\n\n    Public Sub Start()\n        _countdownThread.Start()\n    End Sub\n\n    Public Sub [Stop]()\n        _isRunning = False\n        _countdownThread.Join()\n    End Sub\nEnd Class\n\nPublic Module Program\n    Public Sub Main()\n        Try\n            Dim endDate = \"2024-12-31T23:59:59.999999\"\n            Dim timer = New ReverseTimer(endDate)\n\n            ' Ctrl+C\n            AddHandler Console.CancelKeyPress,\n                Sub(sender, e)\n                    e.Cancel = True\n                    timer.Stop()\n                End Sub\n\n            timer.Start()\n\n        Catch ex As Exception\n            Console.WriteLine($\"Error: {ex.Message}\")\n        End Try\n    End Sub\nEnd Module\n"
  },
  {
    "path": "Roadmap/45 - GITHUB OCTOVERSE/c#/hequebo.cs",
    "content": "using Newtonsoft.Json.Linq;\nusing System.Text.Json;\n\nclass User\n{\n    public string? Login { get; set; }\n    private string? _company;\n    public int Public_Repos { get; set; }\n    public int Followers { get; set; }\n    public int Following { get; set; }\n    public string? Repos_Url { get; set; }\n    public DateTime Created_At { get; set; }\n    public List<Repository> Repos { get; set; }\n\n    public string Company\n    {\n        get\n        {\n            return _company ?? \"Ninguna\";\n        }\n        set\n        {\n            _company = value;\n        }\n    }\n}\nclass Repository\n{\n    public string Full_Name { get; set; }\n    private string _language;\n    public string Language\n    {\n        get\n        {\n            return _language ?? \"Ninguno\";\n        }\n        set\n        {\n            _language = value;\n        }\n    }\n    public int Stargazers_Count {  get; set; }\n    public int Forks_Count {  get; set; }\n}\nclass GitHub\n{\n    private static HttpClient _httpClient = new HttpClient();\n    public static async Task GenerateReport(string? username)\n    {\n        if (string.IsNullOrEmpty(username))\n        {\n            Console.WriteLine(\"No se ha ingresado ningún usuario...\");\n            return;\n        }\n        string url = $\"https://api.github.com/users/{username}\";\n        _httpClient.DefaultRequestHeaders.UserAgent.TryParseAdd(\"request\");\n        var response = await _httpClient.GetAsync(url);\n        if (!response.IsSuccessStatusCode)\n        {\n            Console.WriteLine($\"El usuario {username} no ha sido encontrado...\");\n            return;\n        }\n        var jsonResponse = await response.Content.ReadAsStringAsync();\n        JsonSerializerOptions options = new JsonSerializerOptions\n        {\n            PropertyNameCaseInsensitive = true,\n        };\n        var user = JsonSerializer.Deserialize<User>(jsonResponse, options);\n\n        Console.WriteLine($\"------Reporte de usuario {username}------\");\n        Console.WriteLine($\"Usuario: {user?.Login}\");\n        Console.WriteLine($\"Compañia: {user?.Company}\");\n        Console.WriteLine($\"Repositorios públicos: {user?.Public_Repos}\");\n        Console.WriteLine($\"Seguidores: {user?.Followers}\");\n        Console.WriteLine($\"Seguidos: {user.Following}\");\n        Console.WriteLine($\"Fecha de creación: {user.Created_At.ToShortDateString()}\");\n\n        if (user.Public_Repos == 0)\n            return;\n        response = await _httpClient.GetAsync(user.Repos_Url);\n        jsonResponse = await response.Content.ReadAsStringAsync();\n        user.Repos = JsonSerializer.Deserialize<List<Repository>>(jsonResponse, options);\n\n        var languages = new Dictionary<string, int>();\n        Console.WriteLine($\"------Repositorios de {user.Login}------\");\n        Console.WriteLine(\"-----------------------------------------\");\n        foreach (var repo in user.Repos)\n        {\n            Console.WriteLine($\"Nombre del Repositorio: {repo.Full_Name}\");\n            Console.WriteLine($\"Lenguaje: {repo.Language}\");\n            Console.WriteLine($\"Estrellas: {repo.Stargazers_Count}\");\n            Console.WriteLine($\"Forks: {repo.Forks_Count}\");\n            Console.WriteLine();\n            Console.WriteLine(\"-----------------------------------------\");\n\n            if (!languages.ContainsKey(repo.Language) && repo.Language != \"Ninguno\")\n                languages.Add(repo.Language, 1);\n            else if (repo.Language != \"Ninguno\")\n                languages[repo.Language] += 1;\n        }\n\n        int maxCount = languages.Max(l => l.Value);\n        var mostUsedLanguages = languages.Where(l => l.Value == maxCount).Select(l => l.Key).ToList();\n        \n        if (mostUsedLanguages.Count > 1)\n        {\n            Console.WriteLine($\"Los lenguajes más utilizados por {user.Login} son:\");\n            foreach(var language in mostUsedLanguages)\n            {\n                Console.WriteLine(language);\n            }\n        }\n        else\n        {\n            Console.WriteLine($\"El lenguaje más utilizado por {user.Login} es: {mostUsedLanguages[0]}\");\n        }\n    }\n}\n\nclass Program\n{\n    static async Task Main(string[] args)\n    {\n        Console.WriteLine(\"------Reporte de Usuario de Github------\");\n        Console.WriteLine(\"Ingresa el nombre del usuario que quieres consultar\");\n        string? userName = Console.ReadLine();\n        await GitHub.GenerateReport(userName);\n    }\n}"
  },
  {
    "path": "Roadmap/45 - GITHUB OCTOVERSE/c#/kenysdev.cs",
    "content": "namespace exs44;\n/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - C#\n_____________________________________\n45 GITHUB OCTOVERSE\n------------------------------------\n\n * EJERCICIO:\n * GitHub ha publicado el Octoverse 2024, el informe\n * anual del estado de la plataforma:\n * https://octoverse.github.com\n *\n * Utilizando el API de GitHub, crea un informe asociado\n * a un usuario concreto.\n * \n * - Se debe poder definir el nombre del usuario\n *   sobre el que se va a generar el informe.\n *   \n * - Crea un informe de usuario basándote en las 5 métricas\n *   que tú quieras, utilizando la informración que te\n *   proporciona GitHub. Por ejemplo:\n *   - Lenguaje más utilizado\n *   - Cantidad de repositorios\n *   - Seguidores/Seguidos\n *   - Stars/forks\n *   - Contribuciones\n *   (lo que se te ocurra)\n*/\nusing System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Text.Json;\nusing System.Linq;\nusing System.Threading.Tasks;\n\npublic class GitHubApi\n{\n    private readonly HttpClient _client = new();\n    private readonly Dictionary<string, JsonElement> _userData;\n\n    public GitHubApi(string userName)\n    {\n        _userData = GetUserDataAsync(userName).Result;\n    }\n\n    private async Task<Dictionary<string, JsonElement>> GetUserDataAsync(string userName)\n    {\n        try\n        {\n            _client.DefaultRequestHeaders.Add(\"User-Agent\", \"Mozilla/5.0\");\n            var response = await _client.GetStringAsync($\"https://api.github.com/users/{userName}\");\n            \n            var Json = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(response);\n            if (Json == null)\n            {\n                Console.WriteLine(\"Response: null\");\n                return [];\n            }\n            return Json;\n        }\n        catch (HttpRequestException ex)\n        {\n            Console.WriteLine($\"Error: {ex.Message}\");\n            return [];\n        }\n    }\n\n    private bool VerifyStatus()\n    {\n        if (_userData.TryGetValue(\"status\", out var status) && status.GetString() == \"404\")\n        {\n            Console.WriteLine($\"Usuario no encontrado.\");\n            return false;\n        }\n        return true;\n    }\n\n    private static string GetRepoInfo(JsonElement repo)\n    {\n        return $\"\"\"\n        Lang: {(repo.TryGetProperty(\"full_name\", out var name) ? name.GetString() : \"Desconocido\")}\n        Repo: {(repo.TryGetProperty(\"language\", out var lang) ? lang.GetString() : \"Desconocido\")}\n        Stars: {(repo.TryGetProperty(\"stargazers_count\", out var stars) ? stars.GetInt32() : 0)}\n        Forks: {(repo.TryGetProperty(\"forks_count\", out var forks) ? forks.GetInt32() : 0)}\n        \"\"\";\n    }\n\n    public void PrintBasicInfo()\n    {\n        if (!VerifyStatus()) return;\n\n        Console.WriteLine($\"\"\"\n        -------------------------------------------\n        Nombre: {(_userData.TryGetValue(\"name\", out var name) ? name.GetString() : \"Desconocido\")}\n        Creación: {(_userData.TryGetValue(\"created_at\", out var created) ? created.GetString() : \"Desconocido\")}\n        Repos: {(_userData.TryGetValue(\"public_repos\", out var repos) ? repos.GetInt32() : 0)}\n        Gists: {(_userData.TryGetValue(\"public_gists\", out var gists) ? gists.GetInt32() : 0)}\n        Seguidores: {(_userData.TryGetValue(\"followers\", out var followers) ? followers.GetInt32() : 0)}\n        Seguidos: {(_userData.TryGetValue(\"following\", out var following) ? following.GetInt32() : 0)}\n        -------------------------------------------\n        \"\"\");\n    }\n\n    public async Task PrintReposInfoAsync()\n    {\n        if (!VerifyStatus()) return;\n\n        if (_userData.TryGetValue(\"repos_url\", out var reposUrl))\n        {\n            var reposResponse = await _client.GetStringAsync(reposUrl.GetString());\n            var repos = JsonSerializer.Deserialize<List<JsonElement>>(reposResponse);\n            var languages = new Dictionary<string, int>();\n            Console.WriteLine(\"Repositorios publicos:\");\n\n            if (repos == null)\n            {\n                Console.WriteLine(\"Sin repositorios\");\n                return;\n            }\n\n            foreach (var repo in repos)\n            {\n                Console.WriteLine(\"\\n\" + GetRepoInfo(repo));\n\n                if (repo.TryGetProperty(\"language\", out var language))\n                {\n                    var lang = language.GetString();\n                    if (!string.IsNullOrEmpty(lang))\n                    {\n                        languages[lang] = languages.TryGetValue(lang, out int value) ? value + 1 : 1;\n                    }\n                }\n            }\n\n            var mostUsedLang = languages.OrderByDescending(x => x.Value).FirstOrDefault();\n            Console.WriteLine($\"________\\nTotal de repositorios: '{repos.Count}'\");\n            Console.WriteLine($\"El lenguaje más utilizado: '{mostUsedLang.Key}'({mostUsedLang.Value})\");\n        }\n    }\n\n    public static async Task Main()\n    {\n        Console.WriteLine(\"Informe sobre los datos del usuario en GitHub\");\n        Console.Write(\"Usuario: \");\n        string? userName = Console.ReadLine();\n\n        if (userName != null)\n        {\n            var github = new GitHubApi(userName);\n            await github.PrintReposInfoAsync();\n            github.PrintBasicInfo();\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/45 - GITHUB OCTOVERSE/c++/hectorio23.cpp",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\n// NOTES: You need to install the following dependencies\n// - vcpkg install cpr\n// - vcpkg install nlohmann-json\n\n// For compiling the code:\n// g++ -std=c++17 -Ipath_to_nlohmann_json -Ipath_to_cpr_include main.cpp -Lpath_to_cpr_library -lcpr -o github_report\n\n#include <nlohmann/json.hpp>\n#include <unordered_map>\n#include <algorithm>\n#include <cpr/cpr.h>\n#include <iostream>\n#include <string>\n#include <vector>\n\nusing json = nlohmann::json;\n\nclass GitHubUserReport {\npublic:\n    explicit GitHubUserReport(const std::string& username) : username(username), base_url(\"https://api.github.com\") {}\n\n    void generateReport() {\n        try {\n            auto user_info = fetchData(\"users/\" + username);\n            auto repos = fetchData(\"users/\" + username + \"/repos\");\n\n            // Metric 1: Most used language\n            std::unordered_map<std::string, int> language_count;\n            for (const auto& repo : repos) {\n                if (!repo[\"language\"].is_null()) {\n                    std::string language = repo[\"language\"];\n                    language_count[language]++;\n                }\n            }\n            std::string most_used_language = \"Unknown\";\n            if (!language_count.empty()) {\n                most_used_language = std::max_element(language_count.begin(), language_count.end(),\n                                                      [](const auto& a, const auto& b) {\n                                                          return a.second < b.second;\n                                                      })->first;\n            }\n\n            // Metric 2: Total repositories\n            int total_repos = repos.size();\n\n            // Metric 3: Total stars\n            int total_stars = 0;\n            for (const auto& repo : repos) {\n                total_stars += repo[\"stargazers_count\"];\n            }\n\n            // Metric 4: Followers\n            int followers = user_info[\"followers\"];\n\n            // Metric 5: Following\n            int following = user_info[\"following\"];\n\n            // Print the report\n            std::cout << \"GitHub User Report for: \" << username << \"\\n\";\n            std::cout << \"------------------------------------\\n\";\n            std::cout << \"Most Used Language: \" << most_used_language << \"\\n\";\n            std::cout << \"Total Repositories: \" << total_repos << \"\\n\";\n            std::cout << \"Total Stars: \" << total_stars << \"\\n\";\n            std::cout << \"Followers: \" << followers << \"\\n\";\n            std::cout << \"Following: \" << following << \"\\n\";\n\n        } catch (const std::exception& ex) {\n            std::cerr << \"Error: \" << ex.what() << std::endl;\n        }\n    }\n\nprivate:\n    std::string username;\n    std::string base_url;\n\n    json fetchData(const std::string& endpoint) {\n        auto response = cpr::Get(cpr::Url{base_url + \"/\" + endpoint},\n                                 cpr::Header{{\"User-Agent\", \"GitHub-User-Report\"}});\n        if (response.status_code != 200) {\n            throw std::runtime_error(\"Failed to fetch data from \" + endpoint + \": \" + response.error.message);\n        }\n        return json::parse(response.text);\n    }\n};\n\nint main() {\n    std::string username;\n    std::cout << \"Enter the GitHub username: \";\n    std::cin >> username;\n\n    GitHubUserReport report(username);\n    report.generateReport();\n\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/45 - GITHUB OCTOVERSE/ejercicio.md",
    "content": "# #45 GITHUB OCTOVERSE\n> #### Dificultad: Media | Publicación: 11/11/24 | Corrección: 18/11/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * GitHub ha publicado el Octoverse 2024, el informe\n * anual del estado de la plataforma:\n * https://octoverse.github.com\n *\n * Utilizando el API de GitHub, crea un informe asociado\n * a un usuario concreto.\n * \n * - Se debe poder definir el nombre del usuario\n *   sobre el que se va a generar el informe.\n *   \n * - Crea un informe de usuario basándote en las 5 métricas\n *   que tú quieras, utilizando la información que te\n *   proporciona GitHub. Por ejemplo:\n *   - Lenguaje más utilizado\n *   - Cantidad de repositorios\n *   - Seguidores/Seguidos\n *   - Stars/forks\n *   - Contribuciones\n *   (lo que se te ocurra)\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/45 - GITHUB OCTOVERSE/go/hozlucas28.go",
    "content": "package main\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"os/exec\"\n)\n\n/* -------------------------------------------------------------------------- */\n/*                                   STRUCTS                                  */\n/* -------------------------------------------------------------------------- */\n\n/* -------------------------------- Adapters -------------------------------- */\n\ntype Adapter struct{}\n\nfunc (_ *Adapter) UserData(userData *User) *UserData {\n\tvar forks uint = 0\n\tfor _, publicRepo := range userData.PublicRepositoriesData {\n\t\tif publicRepo.Fork {\n\t\t\tforks++\n\t\t}\n\t}\n\n\treturn &UserData{\n\t\tFollowers:          userData.Followers,\n\t\tFollowing:          userData.Following,\n\t\tForks:              forks,\n\t\tName:               userData.Name,\n\t\tPublicRepositories: userData.PublicRepositories,\n\t\tStars:              uint(len(userData.Stars)),\n\t\tUserName:           userData.Login,\n\t}\n\n}\n\n/* ------------------------------- GitHub API ------------------------------- */\n\ntype PublicRepositories struct {\n\tFork bool `json:\"fork\"`\n}\n\ntype Stars struct {\n\tUrl string `json:\"url\"`\n}\n\ntype User struct {\n\tFollowers              uint                 `json:\"followers\"`\n\tFollowing              uint                 `json:\"following\"`\n\tLogin                  string               `json:\"login\"`\n\tName                   string               `json:\"name\"`\n\tPublicRepositories     uint                 `json:\"public_repos\"`\n\tReposUrl               string               `json:\"repos_url\"`\n\tPublicRepositoriesData []PublicRepositories `json:\"public_repos_data\"`\n\tStars                  []Stars              `json:\"stars\"`\n}\n\ntype GitHubAPI struct {\n\tUser User\n}\n\n/* ------------------------------ GitHubService ----------------------------- */\n\ntype UserData struct {\n\tFollowers          uint   `json:\"followers\"`\n\tFollowing          uint   `json:\"following\"`\n\tForks              uint   `json:\"forks\"`\n\tName               string `json:\"name\"`\n\tPublicRepositories uint   `json:\"public_repositories\"`\n\tStars              uint   `json:\"stars\"`\n\tUserName           string `json:\"userName\"`\n}\n\ntype GitHubService interface {\n\tGetUserData(userName string) (*UserData, error)\n}\n\ntype githubService struct {\n\taccessToken string\n\t_           struct{}\n}\n\nfunc NewGitHubService(accessToken string) GitHubService {\n\tvar githubService githubService = githubService{accessToken: accessToken}\n\treturn &githubService\n}\n\nfunc (githubService *githubService) GetUserData(userName string) (*UserData, error) {\n\tvar userData User\n\tvar adapter Adapter\n\n\tvar err error\n\tvar errMsg string\n\n\tvar client *http.Client = &http.Client{}\n\tvar request *http.Request\n\n\tvar headers map[string][]string = map[string][]string{\n\t\t\"Authorization\":        {fmt.Sprintf(\"Bearer %s\", githubService.accessToken)},\n\t\t\"Accept\":               {\"application/vnd.github+json\"},\n\t\t\"X-GitHub-Api-Version\": {\"2022-11-28\"},\n\t}\n\n\tvar response *http.Response\n\tvar starsData []Stars\n\tvar publicReposData []PublicRepositories\n\n\trequest, err = http.NewRequest(\"GET\", fmt.Sprintf(\"https://api.github.com/users/%s\", userName), nil)\n\tif err != nil {\n\t\treturn &UserData{}, err\n\t}\n\n\trequest.Header = headers\n\n\tresponse, err = client.Do(request)\n\tif err != nil {\n\t\treturn &UserData{}, err\n\t}\n\n\tif response.StatusCode == http.StatusOK {\n\t\tbody, err := io.ReadAll(response.Body)\n\t\tif err != nil {\n\t\t\treturn &UserData{}, err\n\t\t}\n\n\t\terr = json.Unmarshal(body, &userData)\n\t\tif err != nil {\n\t\t\treturn &UserData{}, err\n\t\t}\n\n\t} else {\n\t\terrMsg = fmt.Sprintf(\"%s: %v\", request.Response.Status, request.Response.Body)\n\t\treturn &UserData{}, errors.New(errMsg)\n\t}\n\n\trequest, err = http.NewRequest(\"GET\", fmt.Sprintf(\"https://api.github.com/users/%s/starred\", userName), nil)\n\tif err != nil {\n\t\treturn &UserData{}, err\n\t}\n\n\trequest.Header = headers\n\n\tresponse, err = client.Do(request)\n\tif err != nil {\n\t\treturn &UserData{}, err\n\t}\n\n\tif response.StatusCode == http.StatusOK {\n\t\tbody, err := io.ReadAll(response.Body)\n\t\tif err != nil {\n\t\t\treturn &UserData{}, err\n\t\t}\n\n\t\terr = json.Unmarshal(body, &starsData)\n\t\tif err != nil {\n\t\t\treturn &UserData{}, err\n\t\t}\n\n\t\tuserData.Stars = starsData\n\t} else {\n\t\terrMsg = fmt.Sprintf(\"%s: %v\", request.Response.Status, request.Response.Body)\n\t\treturn &UserData{}, errors.New(errMsg)\n\t}\n\n\trequest, err = http.NewRequest(\"GET\", userData.ReposUrl, nil)\n\tif err != nil {\n\t\treturn &UserData{}, err\n\t}\n\n\trequest.Header = headers\n\n\tresponse, err = client.Do(request)\n\tif err != nil {\n\t\treturn &UserData{}, err\n\t}\n\n\tif response.StatusCode == http.StatusOK {\n\t\tbody, err := io.ReadAll(response.Body)\n\t\tif err != nil {\n\t\t\treturn &UserData{}, err\n\t\t}\n\n\t\terr = json.Unmarshal(body, &publicReposData)\n\t\tif err != nil {\n\t\t\treturn &UserData{}, err\n\t\t}\n\n\t\tuserData.PublicRepositoriesData = publicReposData\n\t} else {\n\t\terrMsg = fmt.Sprintf(\"%s: %v\", request.Response.Status, request.Response.Body)\n\t\treturn &UserData{}, errors.New(errMsg)\n\t}\n\n\treturn adapter.UserData(&userData), err\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\nfunc main() {\n\tconst accessToken string = \"XXX\" // Complete with your personal GitHub Access Token.\n\tvar githubService GitHubService = NewGitHubService(accessToken)\n\n\tvar userInput string\n\n\tvar userData *UserData\n\tvar err error\n\n\tvar cmd *exec.Cmd\n\n\tvar i int\n\tvar padding int\n\n\tfmt.Print(\"> Enter a GitHub username (-1 to exit): \")\n\tfmt.Scanf(\"%s\\n\", &userInput)\n\n\tfor userInput != \"-1\" {\n\t\tuserData, err = githubService.GetUserData(userInput)\n\n\t\tif err == nil {\n\t\t\tcmd = exec.Command(\"clear\")\n\t\t\tcmd.Stdout = os.Stdout\n\t\t\tcmd.Run()\n\n\t\t\tfmt.Print(\"+ \")\n\t\t\tfor i = 0; i < 52; i++ {\n\t\t\t\tfmt.Print(\"-\")\n\t\t\t}\n\t\t\tfmt.Print(\" +\\n\")\n\n\t\t\tpadding = len(userData.UserName) - 52\n\t\t\tfmt.Printf(\"+ %-*s%s%*s +\\n\", padding/2, \"\", userData.UserName, padding/2+padding%2, \"\")\n\n\t\t\tfmt.Print(\"+ \")\n\t\t\tfor i = 0; i < 52; i++ {\n\t\t\t\tfmt.Print(\"-\")\n\t\t\t}\n\t\t\tfmt.Print(\" +\\n\")\n\n\t\t\tfmt.Printf(\"+ %-52s +\\n\", fmt.Sprintf(\"%s: %s.\", \"Name\", userData.Name))\n\t\t\tfmt.Printf(\"+ %-52s +\\n\", fmt.Sprintf(\"%s: %d.\", \"Public repositories\", userData.PublicRepositories))\n\t\t\tfmt.Printf(\"+ %-52s +\\n\", fmt.Sprintf(\"%s: %d.\", \"Repositories stared\", userData.Stars))\n\t\t\tfmt.Printf(\"+ %-52s +\\n\", fmt.Sprintf(\"%s: %d.\", \"Number of repositories forked\", userData.Forks))\n\t\t\tfmt.Printf(\"+ %-52s +\\n\", fmt.Sprintf(\"%s: %d.\", \"Following\", userData.Following))\n\t\t\tfmt.Printf(\"+ %-52s +\\n\", fmt.Sprintf(\"%s: %d.\", \"Followers\", userData.Followers))\n\n\t\t\tfmt.Print(\"+ \")\n\t\t\tfor i = 0; i < 52; i++ {\n\t\t\t\tfmt.Print(\"-\")\n\t\t\t}\n\t\t\tfmt.Print(\" +\\n\")\n\t\t} else {\n\t\t\tfmt.Println(\"\\n> An error occurred on fetch '{user_input}' username! Try again...\")\n\t\t}\n\n\t\tfmt.Print(\"\\n> Enter a GitHub username (-1 to exit): \")\n\t\tfmt.Scanf(\"%s\\n\", &userInput)\n\t}\n}\n"
  },
  {
    "path": "Roadmap/45 - GITHUB OCTOVERSE/java/Josegs95.java",
    "content": "import com.google.gson.JsonArray;\nimport com.google.gson.JsonElement;\nimport com.google.gson.JsonObject;\nimport com.google.gson.JsonParser;\n\nimport java.io.IOException;\nimport java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\nimport java.util.*;\n\npublic class Josegs95 {\n    public static void main(String[] args) {\n        new Josegs95().GitHubOctoverse();\n    }\n\n    private String user = \"mouredev\";\n    final private String ACCESS_TOKEN = System.getenv(\"ACCESS_TOKEN\");\n\n    public void GitHubOctoverse(){\n        Map<String, String> userData = new HashMap<>();\n        userData.put(\"name\", user);\n\n        try{\n            String url = \"https://api.github.com/users/\" + user;\n            JsonElement data = makeGETRequest(url);\n            if (data == null){\n                throw new Exception();\n            }\n            JsonObject userJSONData = data.getAsJsonObject();\n            int publicRepositories = Integer.valueOf(userJSONData.get(\"public_repos\").getAsString());\n\n            userData.put(\"followers\", userJSONData.get(\"followers\").getAsString());\n            userData.put(\"following\", userJSONData.get(\"following\").getAsString());\n            userData.put(\"public_repos\", String.valueOf(publicRepositories));\n\n            JsonArray repositories = new JsonArray();\n            int pageCount = 1;\n            do{\n                url = userJSONData.get(\"repos_url\").getAsString().concat(\"?per_page=30&page=\" + pageCount);\n                data = makeGETRequest(url);\n                if (data == null){\n                    throw new Exception();\n                }\n\n                repositories.addAll(data.getAsJsonArray());\n                pageCount++;\n                publicRepositories -= 30;\n            }while(publicRepositories > 0);\n\n            userData.putAll(analyzeRepositories(repositories));\n        } catch (Exception e) {}\n\n        printUserData(userData);\n    }\n\n    private Map<String, String> analyzeRepositories(JsonArray repositories){\n        JsonObject mostPopularRepository = null;\n        Map<String, Integer> languageUse = new HashMap<>();\n        Map<String, String> data = new HashMap<>();\n\n        for ( JsonElement repository : repositories){\n            JsonObject repo = repository.getAsJsonObject();\n            JsonElement langElement = repo.get(\"language\");\n            if (!langElement.isJsonNull()){\n                String language = langElement.getAsString();\n                if (languageUse.containsKey(language))\n                    languageUse.replace(language, languageUse.get(language) + 1);\n                else\n                    languageUse.put(language, 1);\n            }\n\n            if (mostPopularRepository == null) {\n                mostPopularRepository = repo;\n                continue;\n            }\n\n            int stars = Integer.valueOf(repo.get(\"stargazers_count\").getAsString());\n            if (stars > Integer.valueOf(mostPopularRepository.get(\"stargazers_count\").getAsString())){\n                mostPopularRepository = repo;\n            }\n        }\n\n        List<Map.Entry<String, Integer>> aux = new ArrayList<>(languageUse.entrySet());\n        aux.sort(Collections.reverseOrder(Map.Entry.comparingByValue()));\n\n        data.put(\"most_popular_repository\", mostPopularRepository.get(\"name\").getAsString());\n        data.put(\"most_popular_repository_stars\", mostPopularRepository.get(\"stargazers_count\").getAsString());\n        data.put(\"most_used_language\", aux.get(0).getKey());\n        data.put(\"most_used_language_count\", aux.get(0).getValue().toString());\n\n        return data;\n    }\n\n    private void printUserData(Map<String, String> data){\n        System.out.println(\"Nombre del usuario: \" + data.get(\"name\"));\n        System.out.println(\"Seguidores: \" + data.get(\"followers\") + \", Siguiendo: \" + data.get(\"following\"));\n        System.out.println(\"Repositorios públicos: \" + data.get(\"public_repos\"));\n        System.out.println(\"Repositorio mas popular: '\" + data.get(\"most_popular_repository\")\n                + \"' con \" + data.get(\"most_popular_repository_stars\") + \" estrellas\");\n        System.out.println(\"Lenguaje mas utilizado: \" + data.get(\"most_used_language\") + \" en \"\n                + data.get(\"most_used_language_count\") + \"/\" +  data.get(\"public_repos\") + \" repositorios\");\n    }\n\n    private JsonElement makeGETRequest(String url){\n        HttpClient client = HttpClient.newHttpClient();\n        HttpRequest request = HttpRequest.newBuilder(URI.create(url))\n                .header(\"Accept\", \"application/vnd.github+json\")\n                .header(\"Authorization\", \"Bearer \" + ACCESS_TOKEN)\n                .GET()\n                .build();\n        try{\n            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());\n            if (response.statusCode() != 200){\n                System.out.println(\"Ha ocurrido un error al intentar hacer una petición a la API\");\n                System.out.println(\"Respuesta: \" + response.body() + \"\\n\");\n                return null;\n            }\n\n            return JsonParser.parseString(response.body());\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        } catch (InterruptedException e) {\n            throw new RuntimeException(e);\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/45 - GITHUB OCTOVERSE/java/MohamedElderkaoui.java",
    "content": "import java.io.*;\nimport java.net.HttpURLConnection;\nimport java.net.URL;\nimport java.util.*;\nimport org.json.*;\n\npublic class MohamedElderkaoui {\n    private static final String USER = \"MohamedElderkaoui\"; // GitHub user to generate the report for\n    private static final String TOKEN = System.getenv(\"GITHUB_TOKEN\");\n\n    public static void main(String[] args) throws IOException {\n        if (TOKEN == null || TOKEN.isEmpty()) {\n            System.out.println(\"Error: GitHub token is not set. Please set the GITHUB_TOKEN environment variable.\");\n            return;\n        }\n\n        GitHubClient client = GitHubClient.create(TOKEN);\n        User user = client.getUser(USER);\n\n        if (user == null) {\n            System.out.println(\"User not found or data unavailable.\");\n            return;\n        }\n\n        // Generate user report\n        StringBuilder report = new StringBuilder();\n        report.append(\"GitHub User Report for \").append(USER).append(\":\\n\")\n                .append(\"Name: \").append(user.getName()).append(\"\\n\")\n                .append(\"Location: \").append(user.getLocation()).append(\"\\n\")\n                .append(\"Bio: \").append(user.getBio()).append(\"\\n\")\n                .append(\"Public Repositories: \").append(user.getPublicRepos()).append(\"\\n\")\n                .append(\"Followers: \").append(user.getFollowers()).append(\"\\n\")\n                .append(\"Following: \").append(user.getFollowing()).append(\"\\n\")\n                .append(\"Most Used Language: \").append(user.getMostUsedLanguage()).append(\"\\n\")\n                .append(\"Total Stars: \").append(user.getStars()).append(\"\\n\")\n                .append(\"Total Forks: \").append(user.getForks()).append(\"\\n\");\n\n        System.out.println(report);\n    }\n}\n\nclass GitHubClient {\n    private final String token;\n\n    public GitHubClient(String token) {\n        this.token = token;\n    }\n\n    public static GitHubClient create(String token) {\n        return new GitHubClient(token);\n    }\n\n    public User getUser(String username) throws IOException {\n        String apiUrl = \"https://api.github.com/users/\" + username;\n        JSONObject userData = fetchJsonFromUrl(apiUrl);\n\n        if (userData == null) {\n            return null;\n        }\n\n        // Fetch user's repositories\n        JSONArray reposData = fetchJsonArrayFromUrl(apiUrl + \"/repos\");\n\n        return new User(userData, reposData);\n    }\n\n    private JSONObject fetchJsonFromUrl(String apiUrl) throws IOException {\n        HttpURLConnection connection = openConnection(apiUrl);\n        try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {\n            StringBuilder response = new StringBuilder();\n            String line;\n            while ((line = reader.readLine()) != null) {\n                response.append(line);\n            }\n            return new JSONObject(response.toString());\n        } catch (Exception e) {\n            System.out.println(\"Error fetching data: \" + e.getMessage());\n            return null;\n        }\n    }\n\n    private JSONArray fetchJsonArrayFromUrl(String apiUrl) throws IOException {\n        HttpURLConnection connection = openConnection(apiUrl);\n        try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {\n            StringBuilder response = new StringBuilder();\n            String line;\n            while ((line = reader.readLine()) != null) {\n                response.append(line);\n            }\n            return new JSONArray(response.toString());\n        } catch (Exception e) {\n            System.out.println(\"Error fetching data: \" + e.getMessage());\n            return null;\n        }\n    }\n\n    private HttpURLConnection openConnection(String apiUrl) throws IOException {\n        URL url = new URL(apiUrl);\n        HttpURLConnection connection = (HttpURLConnection) url.openConnection();\n        connection.setRequestMethod(\"GET\");\n        connection.setRequestProperty(\"Authorization\", \"Bearer \" + token);\n        connection.setRequestProperty(\"Accept\", \"application/vnd.github.v3+json\");\n        return connection;\n    }\n}\n\nclass User {\n    private final String name;\n    private final String location;\n    private final String bio;\n    private final int followers;\n    private final int following;\n    private final int publicRepos;\n    private final int stars;\n    private final int forks;\n    private final String mostUsedLanguage;\n\n    public User(JSONObject userData, JSONArray reposData) {\n        this.name = userData.optString(\"name\", \"N/A\");\n        this.location = userData.optString(\"location\", \"N/A\");\n        this.bio = userData.optString(\"bio\", \"N/A\");\n        this.followers = userData.optInt(\"followers\", 0);\n        this.following = userData.optInt(\"following\", 0);\n        this.publicRepos = userData.optInt(\"public_repos\", 0);\n\n        Map<String, Integer> languageCount = new HashMap<>();\n        int starsSum = 0;\n        int forksSum = 0;\n\n        if (reposData != null && reposData.length() > 0) {\n            for (int i = 0; i < reposData.length(); i++) {\n                JSONObject repo = reposData.getJSONObject(i);\n                starsSum += repo.optInt(\"stargazers_count\", 0);\n                forksSum += repo.optInt(\"forks_count\", 0);\n\n                String language = repo.optString(\"language\", \"Unknown\");\n                if (!language.equals(\"Unknown\")) {\n                    languageCount.put(language, languageCount.getOrDefault(language, 0) + 1);\n                }\n            }\n        }\n\n        this.stars = starsSum;\n        this.forks = forksSum;\n\n        this.mostUsedLanguage = languageCount.isEmpty()\n                ? \"No languages found\"\n                : languageCount.entrySet()\n                        .stream()\n                        .max(Map.Entry.comparingByValue())\n                        .map(Map.Entry::getKey)\n                        .orElse(\"Unknown\");\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public String getLocation() {\n        return location;\n    }\n\n    public String getBio() {\n        return bio;\n    }\n\n    public int getFollowers() {\n        return followers;\n    }\n\n    public int getFollowing() {\n        return following;\n    }\n\n    public int getPublicRepos() {\n        return publicRepos;\n    }\n\n    public int getStars() {\n        return stars;\n    }\n\n    public int getForks() {\n        return forks;\n    }\n\n    public String getMostUsedLanguage() {\n        return mostUsedLanguage;\n    }\n}"
  },
  {
    "path": "Roadmap/45 - GITHUB OCTOVERSE/java/asjordi.java",
    "content": "import com.google.gson.Gson;\nimport com.google.gson.JsonArray;\nimport java.io.IOException;\nimport java.net.URI;\nimport java.net.URISyntaxException;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\nimport java.util.*;\n\npublic class Main {\n\n    /*\n    * CLI to fetch the recent activity of a GitHub user and display it in the terminal.\n    * https://github.com/ASJordi/gh-user-activity-cli\n    */\n\n    public static void main(String[] args) {\n        Main m = new Main(\"asjordi\");\n\n        int gist = m.getNumGists();\n        int stars = m.getNumStars();\n        int followers = m.getNumFollowers();\n        int following = m.getNumFollowing();\n        int repos = m.getInfoRepos();\n\n        System.out.println(\"Stats for user: \" + m.getUsuario());\n        System.out.println(\"Repos: \" + repos);\n        System.out.println(\"Gists: \" + gist);\n        System.out.println(\"Stars: \" + stars);\n        System.out.println(\"Followers: \" + followers);\n        System.out.println(\"Following: \" + following);\n    }\n\n    private final String usuario;\n    private Gson gson = new Gson();\n    private HttpClient httpClient = HttpClient.newHttpClient();\n    private HttpRequest request = null;\n\n    public Main(String usuario) {\n        this.usuario = usuario;\n    }\n\n    public int getInfoRepos() {\n        String url = \"https://api.github.com/users/\" + this.usuario + \"/repos?per_page=100\";\n        Map<String, Integer> map = new HashMap<>();\n\n        HttpResponse<String> response = sendRequest(url);\n        int statusCode = response.statusCode();\n\n        if (statusCode != 200) return -1;\n        String responseBody = response.body();\n        JsonArray repos = gson.fromJson(responseBody, JsonArray.class);\n\n        return repos.size();\n    }\n\n    public int getNumFollowing() {\n        String url = \"https://api.github.com/users/\" + this.usuario + \"/following?per_page=100\";\n\n        HttpResponse<String> response = sendRequest(url);\n        int statusCode = response.statusCode();\n\n        if (statusCode != 200) return -1;\n        String responseBody = response.body();\n        JsonArray following = gson.fromJson(responseBody, JsonArray.class);\n\n        return following.size();\n    }\n\n    public int getNumFollowers() {\n        String url = \"https://api.github.com/users/\" + this.usuario + \"/followers?per_page=100\";\n\n        HttpResponse<String> response = sendRequest(url);\n        int statusCode = response.statusCode();\n\n        if (statusCode != 200) return -1;\n        String responseBody = response.body();\n        JsonArray followers = gson.fromJson(responseBody, JsonArray.class);\n\n        return followers.size();\n    }\n\n    public int getNumGists() {\n        String url = \"https://api.github.com/users/\" + this.usuario + \"/gists?per_page=100\";\n\n        HttpResponse<String> response = sendRequest(url);\n        int statusCode = response.statusCode();\n\n        if (statusCode != 200) return -1;\n        String responseBody = response.body();\n        JsonArray gists = gson.fromJson(responseBody, JsonArray.class);\n\n        return gists.size();\n    }\n\n    public int getNumStars() {\n        String url = \"https://api.github.com/users/\" + this.usuario + \"/starred?per_page=100\";\n\n        HttpResponse<String> response = sendRequest(url);\n        int statusCode = response.statusCode();\n\n        if (statusCode != 200) return -1;\n        String responseBody = response.body();\n        JsonArray stars = gson.fromJson(responseBody, JsonArray.class);\n\n        return stars.size();\n    }\n\n    private HttpResponse<String> sendRequest(String url) {\n        HttpResponse<String> response = null;\n        try {\n            this.request = HttpRequest.newBuilder()\n                    .uri(new URI(url))\n                    .GET()\n                    .build();\n\n            response = this.httpClient.send(request, HttpResponse.BodyHandlers.ofString());\n        } catch (URISyntaxException | IOException | InterruptedException e) {\n            throw new RuntimeException(e);\n        }\n\n        return response;\n    }\n\n    public String getUsuario() {\n        return this.usuario;\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/45 - GITHUB OCTOVERSE/java/miguelex.java",
    "content": "import java.io.BufferedReader;\nimport java.io.InputStreamReader;\nimport java.net.HttpURLConnection;\nimport java.net.URL;\nimport java.util.*;\n\npublic class miguelex {\n    private String username;\n    private final String baseApiUrl = \"https://api.github.com\";\n    private final Map<String, String> headers = Map.of(\n        \"User-Agent\", \"GitHub-Report-App\",\n        \"Accept\", \"application/vnd.github.v3+json\"\n    );\n\n    public miguelex(String username) {\n        this.username = username;\n    }\n\n    private String apiRequest(String endpoint) throws Exception {\n        String urlString = baseApiUrl + endpoint;\n        URL url = new URL(urlString);\n        HttpURLConnection connection = (HttpURLConnection) url.openConnection();\n\n        connection.setRequestMethod(\"GET\");\n        headers.forEach(connection::setRequestProperty);\n\n        int responseCode = connection.getResponseCode();\n\n        if (responseCode != 200) {\n            throw new Exception(\"Error al conectar con la API de GitHub (HTTP \" + responseCode + \"). Verifica el nombre de usuario.\");\n        }\n\n        BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));\n        StringBuilder response = new StringBuilder();\n        String line;\n        while ((line = in.readLine()) != null) {\n            response.append(line);\n        }\n        in.close();\n\n        return response.toString();\n    }\n\n    private Map<String, Object> parseJson(String jsonString) {\n        Map<String, Object> map = new HashMap<>();\n        jsonString = jsonString.replace(\"{\", \"\").replace(\"}\", \"\").trim();\n        String[] pairs = jsonString.split(\",\");\n        for (String pair : pairs) {\n            String[] keyValue = pair.split(\":\", 2);\n            if (keyValue.length == 2) {\n                String key = keyValue[0].trim().replace(\"\\\"\", \"\");\n                String value = keyValue[1].trim().replace(\"\\\"\", \"\");\n                map.put(key, value);\n            }\n        }\n        return map;\n    }\n\n    public void generateReport() {\n        try {\n            String userInfoResponse = apiRequest(\"/users/\" + username);\n            Map<String, Object> userInfo = parseJson(userInfoResponse);\n\n            String reposResponse = apiRequest(\"/users/\" + username + \"/repos\");\n            String[] repos = reposResponse.replace(\"[\", \"\").replace(\"]\", \"\").split(\"},\\\\{\");\n\n            int totalRepos = repos.length;\n            int followers = Integer.parseInt(userInfo.getOrDefault(\"followers\", \"0\").toString());\n            int following = Integer.parseInt(userInfo.getOrDefault(\"following\", \"0\").toString());\n\n            Map<String, Integer> languageCounts = new HashMap<>();\n            int totalStars = 0;\n            int totalForks = 0;\n\n            for (String repo : repos) {\n                Map<String, Object> repoData = parseJson(repo);\n\n                String language = repoData.getOrDefault(\"language\", null).toString();\n                if (language != null && !language.isEmpty()) {\n                    languageCounts.put(language, languageCounts.getOrDefault(language, 0) + 1);\n                }\n\n                totalStars += Integer.parseInt(repoData.getOrDefault(\"stargazers_count\", \"0\").toString());\n                totalForks += Integer.parseInt(repoData.getOrDefault(\"forks_count\", \"0\").toString());\n            }\n\n            String topLanguage = languageCounts.entrySet().stream()\n                .max(Map.Entry.comparingByValue())\n                .map(Map.Entry::getKey)\n                .orElse(\"N/A\");\n\n            System.out.println(\"=== Informe de GitHub para el usuario: \" + username + \" ===\");\n            System.out.println(\"Nombre: \" + userInfo.getOrDefault(\"name\", \"N/A\"));\n            System.out.println(\"Bio: \" + userInfo.getOrDefault(\"bio\", \"N/A\"));\n            System.out.println(\"Ubicación: \" + userInfo.getOrDefault(\"location\", \"N/A\"));\n            System.out.println(\"Total de repositorios: \" + totalRepos);\n            System.out.println(\"Seguidores: \" + followers);\n            System.out.println(\"Seguidos: \" + following);\n            System.out.println(\"Lenguaje más utilizado: \" + topLanguage);\n            System.out.println(\"Total de estrellas: \" + totalStars);\n            System.out.println(\"Total de forks: \" + totalForks);\n        } catch (Exception e) {\n            System.err.println(\"Error: \" + e.getMessage());\n        }\n    }\n\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n        System.out.print(\"Ingrese el nombre de usuario de GitHub: \");\n        String username = scanner.nextLine().trim();\n\n        if (username.isEmpty()) {\n            System.err.println(\"Debe ingresar un nombre de usuario.\");\n            return;\n        }\n\n        miguelex report = new miguelex(username);\n        report.generateReport();\n    }\n}\n"
  },
  {
    "path": "Roadmap/45 - GITHUB OCTOVERSE/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #45 - JavaScript -> Jesus Antonio Escamilla */\n\n/**\n * GITHUB OCTOVERSE.\n * Utilizando la Terminal para pedir datos y agregarlos.\n */\n\nconst GITHUB_API_URL = \"https://api.github.com\";\n\nasync function fetchGitHubData(username) {\n    try {\n        const headers = {\n            \"User-Agent\": \"GitHub-User-Report\",\n        };\n\n        // Obtener datos básicos del usuario\n        const userResponse = await fetch(`${GITHUB_API_URL}/users/${username}`, {\n            headers\n        });\n        if (!userResponse.ok) {\n            throw new Error(`Error en la solicitud: ${userResponse.statusText}`);\n        }\n        const userData = await userResponse.json();\n\n        // Obtener repositorios del usuario\n        const reposResponse = await fetch(`${GITHUB_API_URL}/users/${username}/repos?per_page=100`, {\n            headers\n        });\n        if (!reposResponse.ok) {\n            throw new Error(`Error en la solicitud: ${reposResponse.statusText}`);\n        }\n        const reposData = await reposResponse.json();\n\n        // Procesar métricas\n        const languageCount = {};\n        let totalStars = 0;\n        const topRepos = reposData\n            .map((repo) => {\n                totalStars += repo.stargazers_count;\n                if (repo.language) {\n                    languageCount[repo.language] = (languageCount[repo.language] || 0) + 1;\n                }\n                return { name: repo.name, stars: repo.stargazers_count };\n            })\n            .sort((a, b) => b.stars - a.stars)\n            .slice(0, 3);\n\n        const mostUsedLanguage = Object.keys(languageCount).reduce((a, b) =>\n            languageCount[a] > languageCount[b] ? a : b\n        );\n\n        // Crear informe\n        return {\n            username: userData.login,\n            name: userData.name || \"Nombre no disponible\",\n            publicRepos: userData.public_repos,\n            followers: userData.followers,\n            following: userData.following,\n            mostUsedLanguage,\n            topRepos,\n            totalStars,\n        };\n    } catch (error) {\n        throw new Error(`Error en la solicitud: ${error.message}`);\n    }\n}\n\n// Ejemplo de uso\n(async () => {\n    const username = \"mouredev\";\n    try {\n        const report = await fetchGitHubData(username);\n        printReport(report);\n    } catch (error) {\n        console.error(\"Error:\", error.message);\n    }\n})();\n\nfunction printReport(report) {\n    if (!report) return;\n    console.log(`\\n--- Informe de Usuario: ${report.username} ---`);\n    console.log(`Nombre: ${report.name}`);\n    console.log(`Repositorios Públicos: ${report.publicRepos}`);\n    console.log(`Seguidores: ${report.followers}, Seguidos: ${report.following}`);\n    console.log(`Lenguaje más utilizado: ${report.mostUsedLanguage}`);\n    console.log(`Repositorios con más estrellas:`);\n    report.topRepos.forEach((repo, index) => {\n        console.log(`  ${index + 1}. ${repo.name} - ${repo.stars} estrellas`);\n    });\n    console.log(\n        `Total de estrellas en todos los repositorios: ${report.totalStars}`\n    );\n}\n"
  },
  {
    "path": "Roadmap/45 - GITHUB OCTOVERSE/javascript/RaulDoezon.js",
    "content": "/*\n  EJERCICIO:\n  GitHub ha publicado el Octoverse 2024, el informe\n  anual del estado de la plataforma:\n  https://octoverse.github.com\n \n  Utilizando el API de GitHub, crea un informe asociado\n  a un usuario concreto.\n  \n  - Se debe poder definir el nombre del usuario\n    sobre el que se va a generar el informe.\n    \n  - Crea un informe de usuario basándote en las 5 métricas\n    que tú quieras, utilizando la informración que te\n    proporciona GitHub. Por ejemplo:\n    - Lenguaje más utilizado\n    - Cantidad de repositorios\n    - Seguidores/Seguidos\n    - Stars/forks\n    - Contribuciones\n    (lo que se te ocurra)\n*/\n\nconst userName = prompt('Por favor, ingresa el nombre de usuario de GitHub que quieres consultar:');\nconst apiRequest = async () => {\n  const apiURL = `https://api.github.com/users/${userName}`;\n  const starredAPI = `${apiURL}/starred`;\n\n  try {\n    const [data1, data2] = await Promise.all([\n      fetch(apiURL),\n      fetch(starredAPI),\n    ]);\n\n    const dataBase = await data1.json();\n    const dataStarred = await data2.json();\n\n    console.log(`Informe del usuario ${dataBase.login}:`);\n    console.log(`1. Fecha de creación de la cuenta: ${dataBase.created_at}`);\n    console.log(`2. Número de repositorios públicos: ${dataBase.public_repos}`);\n    console.log(`3. Número de estrellas: ${dataStarred.length}`);\n    console.log(`4. Número de seguidores:  ${dataBase.followers}`);\n    console.log(`5. Número de usuarios a los que sigue: ${dataBase.following}`);\n  } catch (error) {\n    console.log(error);\n  }\n}\n\napiRequest();\n"
  },
  {
    "path": "Roadmap/45 - GITHUB OCTOVERSE/javascript/duendeintemporal.js",
    "content": "//#45 GITHUB OCTOVERSE\n/*\n * EJERCICIO:\n * GitHub ha publicado el Octoverse 2024, el informe\n * anual del estado de la plataforma:\n * https://octoverse.github.com\n *\n * Utilizando el API de GitHub, crea un informe asociado\n * a un usuario concreto.\n * \n * - Se debe poder definir el nombre del usuario\n *   sobre el que se va a generar el informe.\n *\n * - Crea un informe de usuario basándote en las 5 métricas\n *   que tú quieras, utilizando la información que te\n *   proporciona GitHub. Por ejemplo:\n *   - Lenguaje más utilizado\n *   - Cantidad de repositorios\n *   - Seguidores/Seguidos\n *   - Stars/forks\n *   - Contribuciones\n *   (lo que se te ocurra)\n */\n\n//#45 GITHUB OCTOVERSE\n/*\n * EJERCICIO:\n * GitHub ha publicado el Octoverse 2024, el informe\n * anual del estado de la plataforma:\n * https://octoverse.github.com\n *\n * Utilizando el API de GitHub, crea un informe asociado\n * a un usuario concreto.\n * \n * - Se debe poder definir el nombre del usuario\n *   sobre el que se va a generar el informe.\n *\n * - Crea un informe de usuario basándote en las 5 métricas\n *   que tú quieras, utilizando la información que te\n *   proporciona GitHub. Por ejemplo:\n *   - Lenguaje más utilizado\n *   - Cantidad de repositorios\n *   - Seguidores/Seguidos\n *   - Stars/forks\n *   - Contribuciones\n *   (lo que se te ocurra)\n */\n\nlet log = console.log;\n\nwindow.addEventListener('load', () => {\n    const body = document.querySelector('body');\n    const title = document.createElement('h1');\n\n    body.style.setProperty('background', '#000');\n    body.style.setProperty('text-align', 'center');\n\n    title.textContent = 'Retosparaprogramadores #45.';\n    title.style.setProperty('font-size', '3.5vmax');\n    title.style.setProperty('color', '#fff');\n    title.style.setProperty('line-height', '100vh');\n\n    body.appendChild(title);\n\n    setTimeout(() => {\n        alert('Retosparaprogramadores #45. Please open the Browser Developer Tools.');\n    }, 2000);\n    log('Retosparaprogramadores #45');\n});\n\nasync function fetchGitHubData(username) {\n    const userResponse = await fetch(`https://api.github.com/users/${username}`);\n    const userData = await userResponse.json();\n\n    const reposResponse = await fetch(`https://api.github.com/users/${username}/repos`);\n    const reposData = await reposResponse.json();\n\n    return { userData, reposData };\n}\n\nasync function generateUserReport(username) {\n    const { userData, reposData } = await fetchGitHubData(username);\n\n    // Calculate metrics\n    const metrics = [\n        { name: 'Most Used Language', key: 'language' },\n        { name: 'Number of Repositories', key: 'public_repos' },\n        { name: 'Followers/Following', key: 'followers_following_ratio' },\n        { name: 'Stars/Forks', key: 'stars_forks_ratio' },\n        { name: 'Contributions', key: 'contributions' },\n    ];\n\n    let mostUsedLanguage = null;\n    let totalStars = 0;\n    const totalRepos = reposData.length;\n    const followers = userData.followers || 0;\n    const following = userData.following || 1; // Avoid division by zero\n    const contributions = userData.contributions || 'N/A'; // This may still be N/A\n\n    // Analyze repositories\n    const languageCount = {};\n    reposData.forEach(repo => {\n        if (repo.language) {\n            languageCount[repo.language] = (languageCount[repo.language] || 0) + 1;\n            totalStars += repo.stargazers_count || 0;\n        }\n    });\n\n    if (Object.keys(languageCount).length > 0) {\n        mostUsedLanguage = Object.keys(languageCount).reduce((a, b) => languageCount[a] > languageCount[b] ? a : b);\n    }\n\n    const followersFollowingRatio = (followers / following).toFixed(2);\n    const starsForksRatio = (totalRepos > 0) ? (totalStars / totalRepos).toFixed(2) : 'N/A';\n\n    let report = `GitHub User Report for ${username}:\\n\\n`;\n    for (const metric of metrics) {\n        let value;\n        switch (metric.key) {\n            case 'language':\n                value = mostUsedLanguage || 'N/A';\n                break;\n            case 'public_repos':\n                value = totalRepos;\n                break;\n            case 'followers_following_ratio':\n                value = followersFollowingRatio;\n                break;\n            case 'stars_forks_ratio':\n                value = starsForksRatio;\n                break;\n            case 'contributions':\n                value = contributions;\n                break;\n            default:\n                value = 'N/A';\n        }\n        report += `${metric.name}: ${value}\\n`;\n    }\n\n    return report;\n}\n\nlet username = 'mouredev';\ngenerateUserReport(username)\n    .then((report) => log(report))\n    .catch((error) => console.error(error));\n\n    //Output:\n    /*  Most Used Language: Swift\n        Number of Repositories: 30\n        Followers/Following: 13220.50\n        Stars/Forks: 1392.87\n        Contributions: N/A  */ "
  },
  {
    "path": "Roadmap/45 - GITHUB OCTOVERSE/javascript/hectorio23.js",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\nconst fetch = require(\"node-fetch\");\n// npm install node-fetch\n\nclass GitHubUserReport {\n    constructor(username) {\n        this.username = username;\n        this.BASE_URL = \"https://api.github.com\";\n    }\n\n    async fetchData(endpoint) {\n        const url = `${this.BASE_URL}/${endpoint}`;\n        const response = await fetch(url);\n        if (!response.ok) {\n            throw new Error(`[+] - Error fetching data from ${url}: ${response.status}`);\n        }\n        return await response.json();\n    }\n\n    async getUserInfo() {\n        return this.fetchData(`users/${this.username}`);\n    }\n\n    async getRepos() {\n        return this.fetchData(`users/${this.username}/repos`);\n    }\n\n    async generateReport() {\n        const userInfo = await this.getUserInfo();\n        const repos = await this.getRepos();\n\n        // Metric 1: Most used language\n        const languages = {};\n        repos.forEach(repo => {\n            if (repo.language) {\n                languages[repo.language] = (languages[repo.language] || 0) + 1;\n            }\n        });\n        const mostUsedLanguage = Object.keys(languages).reduce((a, b) =>\n            languages[a] > languages[b] ? a : b, \"Unknown\");\n\n        // Metric 2: Total number of repositories\n        const totalRepos = repos.length;\n\n        // Metric 3: Total stars received\n        const totalStars = repos.reduce((sum, repo) => sum + repo.stargazers_count, 0);\n\n        // Metric 4: Followers\n        const followers = userInfo.followers || 0;\n\n        // Metric 5: Following\n        const following = userInfo.following || 0;\n\n        // Generate the report\n        return {\n            Username: this.username,\n            \"Most Used Language\": mostUsedLanguage,\n            \"Total Repositories\": totalRepos,\n            \"Total Stars\": totalStars,\n            Followers: followers,\n            Following: following,\n        };\n    }\n}\n\n(async () => {\n    const username = process.argv[2];\n    if (!username) {\n        console.error(\"[+] - Please provide a GitHub username.\");\n        process.exit(1);\n    }\n\n    const reportGenerator = new GitHubUserReport(username);\n    try {\n        const report = await reportGenerator.generateReport();\n        console.log(\"\\n[+] - GitHub User Report:\");\n        for (const [key, value] of Object.entries(report)) {\n            console.log(`${key}: ${value}`);\n        }\n    } catch (error) {\n        console.error(`[-] - Error: ${error.message}`);\n    }\n})();\n"
  },
  {
    "path": "Roadmap/45 - GITHUB OCTOVERSE/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n_______________________________________________________\n#45 GITHUB OCTOVERSE\n-------------------------------------------------------\n* EJERCICIO:\n * GitHub ha publicado el Octoverse 2024, el informe\n * anual del estado de la plataforma:\n * https://octoverse.github.com\n *\n * Utilizando el API de GitHub, crea un informe asociado\n * a un usuario concreto.\n * \n * - Se debe poder definir el nombre del usuario\n *   sobre el que se va a generar el informe.\n *   \n * - Crea un informe de usuario basándote en las 5 métricas\n *   que tú quieras, utilizando la informración que te\n *   proporciona GitHub. Por ejemplo:\n *   - Lenguaje más utilizado\n *   - Cantidad de repositorios\n *   - Seguidores/Seguidos\n *   - Stars/forks\n *   - Contribuciones\n *   (lo que se te ocurra)\n */\n// ________________________________________________________\nimport fetch from 'node-fetch';\nimport readlineSync from 'readline-sync';\n\nclass GitHubApi {\n    constructor(userName) {\n        this.userName = userName;\n        this.userData = null;\n    }\n\n    async getJson(url) {\n        try {\n            const response = await fetch(url);\n\n            if (!response.ok) {\n                console.error(`Error: ${response.status} - ${response.statusText}`);\n                return {};\n            }\n\n            const text = await response.text();\n            if (text.trim() === \"\") {\n                console.error(\"Error: Respuesta vacía de la API.\");\n                return {};\n            }\n\n            try {\n                return JSON.parse(text);\n            } catch (jsonError) {\n                console.error(`Error al parsear JSON: ${jsonError.message}`);\n                return {};\n            }\n\n        } catch (error) {\n            console.error(`Error de red: ${error.message}`);\n            return {};\n        }\n    }\n\n    async verifyStatus() {\n        if (!this.userData) {\n            console.error(`Usuario '${this.userName}' no encontrado.`);\n            return false;\n        }\n        return true;\n    }\n\n    getRepoInfo(repo) {\n        return `\n            Lang:  ${repo.full_name || \"Desconocido\"}\n            Repo:  ${repo.language || \"Desconocido\"}\n            Stars: ${repo.stargazers_count || 0}\n            Forks: ${repo.forks_count || 0}\n        `.replace(/^\\s+/gm, '').trim();\n    }\n\n    async printBasicInfo() {\n        if (!await this.verifyStatus()) return;\n\n        const { name, created_at, public_repos, public_gists, followers, following } = this.userData;\n        console.log('');\n        console.log(`\n            -------------------------------------------\n            Nombre:     ${name || \"Desconocido\"}\n            Creación:   ${created_at || \"Desconocido\"}\n            Repos:      ${public_repos || 0}\n            Gists:      ${public_gists || 0}\n            Seguidores: ${followers || 0}\n            Seguidos:   ${following || 0}\n            -------------------------------------------\n        `.replace(/^\\s+/gm, '').trim());\n    }\n\n    async printReposInfo() {\n        if (!await this.verifyStatus()) return;\n\n        const reposUrl = this.userData.repos_url || null;\n        if (!reposUrl) {\n            console.error(\"No se encontró la URL de los repositorios.\");\n            return;\n        }\n\n        const reposData = await this.getJson(reposUrl);\n        const languages = new Map();\n\n        console.log(\"Repositorios públicos:\");\n        for (const repo of reposData) {\n            const language = repo.language;\n            console.log('')\n            console.log(this.getRepoInfo(repo));\n\n            if (language) {\n                languages.set(language, (languages.get(language) || 0) + 1);\n            }\n        }\n\n        // Encuentra el lenguaje más utilizado\n        let mostUsedLanguage = null;\n        let maxCount = 0;\n        for (const [language, count] of languages) {\n            if (count > maxCount) {\n                mostUsedLanguage = language;\n                maxCount = count;\n            }\n        }\n\n        console.log(\"________\");\n        console.log(`Total de repositorios: ${reposData.length}`);\n        console.log(`El lenguaje más utilizado: ${mostUsedLanguage} (${maxCount})`);\n    }\n\n    async init() {\n        const url = `https://api.github.com/users/${this.userName}`;\n        this.userData = await this.getJson(url);\n    }\n}\n\n// Ejecución principal\n(async () => {\n    console.log(\"Informe sobre los datos del usuario en GitHub\");\n    const userName = readlineSync.question(\"Usuario: \");\n    const github = new GitHubApi(userName);\n\n    await github.init();\n    await github.printBasicInfo();\n    await github.printReposInfo();\n})();\n"
  },
  {
    "path": "Roadmap/45 - GITHUB OCTOVERSE/javascript/miguelex.js",
    "content": "const https = require('https');\nconst readline = require('readline');\n\nclass GitHubUserReport {\n    constructor(username) {\n        this.username = username;\n        this.baseApiUrl = \"https://api.github.com\";\n        this.headers = {\n            \"User-Agent\": \"GitHub-Report-App\",\n            \"Accept\": \"application/vnd.github.v3+json\"\n        };\n    }\n\n    apiRequest(endpoint) {\n        const url = `${this.baseApiUrl}${endpoint}`;\n\n        return new Promise((resolve, reject) => {\n            const options = {\n                headers: this.headers\n            };\n\n            https.get(url, options, (res) => {\n                let data = '';\n\n                res.on('data', chunk => {\n                    data += chunk;\n                });\n\n                res.on('end', () => {\n                    if (res.statusCode === 200) {\n                        resolve(JSON.parse(data));\n                    } else {\n                        reject(new Error(`Error al conectar con la API de GitHub (HTTP ${res.statusCode}). Verifica el nombre de usuario.`));\n                    }\n                });\n            }).on('error', (err) => {\n                reject(new Error(`Error de conexión: ${err.message}`));\n            });\n        });\n    }\n\n    getUserInfo() {\n        return this.apiRequest(`/users/${this.username}`);\n    }\n\n    getUserRepos() {\n        return this.apiRequest(`/users/${this.username}/repos`);\n    }\n\n    async generateReport() {\n        try {\n            const userInfo = await this.getUserInfo();\n            const repos = await this.getUserRepos();\n\n            const totalRepos = repos.length;\n            const followers = userInfo.followers;\n            const following = userInfo.following;\n\n            const languages = repos.map(repo => repo.language).filter(Boolean);\n            const languageCounts = languages.reduce((counts, lang) => {\n                counts[lang] = (counts[lang] || 0) + 1;\n                return counts;\n            }, {});\n\n            const topLanguage = Object.keys(languageCounts).sort((a, b) => languageCounts[b] - languageCounts[a])[0] || \"N/A\";\n\n            const totalStars = repos.reduce((sum, repo) => sum + repo.stargazers_count, 0);\n            const totalForks = repos.reduce((sum, repo) => sum + repo.forks_count, 0);\n\n            console.log(`=== Informe de GitHub para el usuario: ${this.username} ===`);\n            console.log(`Nombre: ${userInfo.name}`);\n            console.log(`Bio: ${userInfo.bio}`);\n            console.log(`Ubicación: ${userInfo.location}`);\n            console.log(`Total de repositorios: ${totalRepos}`);\n            console.log(`Seguidores: ${followers}`);\n            console.log(`Seguidos: ${following}`);\n            console.log(`Lenguaje más utilizado: ${topLanguage}`);\n            console.log(`Total de estrellas: ${totalStars}`);\n            console.log(`Total de forks: ${totalForks}`);\n        } catch (error) {\n            console.error(error.message);\n        }\n    }\n}\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nrl.question(\"Ingrese el nombre de usuario de GitHub: \", (username) => {\n    if (!username) {\n        console.error(\"Debe ingresar un nombre de usuario.\");\n        rl.close();\n        return;\n    }\n\n    const report = new GitHubUserReport(username);\n    report.generateReport().finally(() => rl.close());\n});\n"
  },
  {
    "path": "Roadmap/45 - GITHUB OCTOVERSE/javascript/pedamoci.js",
    "content": "import  readline  from \"readline\"\n\nconst COLORS = Object.freeze({\n  red: \"\\x1b[31m\",\n  green: \"\\x1b[32m\",\n  yellow: \"\\x1b[33m\",\n  blue: \"\\x1b[34m\",\n  purple: \"\\x1b[35m\",\n  reset: \"\\x1b[0m\",\n})\n\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout\n})\n\nconst askUsername = () => new Promise(r => rl.question(COLORS.purple + \"Enter the username to generate the report: \" + COLORS.reset, r))\n\nconst printError = err => console.error(COLORS.red + \"Error: \" + err + COLORS.reset)\nconst printReport = (name, report) => console.log(`${COLORS.green}--- ${name}'s report ---\\n` +\n                                                  `${COLORS.blue}Followers:${COLORS.yellow} ${report.followers}\\n` +\n                                                  `${COLORS.blue}Gists:${COLORS.yellow} ${report.gists}\\n` +\n                                                  `${COLORS.blue}Total stars:${COLORS.yellow} ${report.stars}\\n` +\n                                                  `${COLORS.blue}Forks:${COLORS.yellow} ${report.forks}\\n` +\n                                                  `${COLORS.blue}All languages:${COLORS.yellow} ${report.languages.join(\", \")}${COLORS.reset}`\n)\n\nconst fetchUser = async (username) => {\n  const response = await fetch(`https://api.github.com/users/${username}`)\n\n  if (response.status === 404) {\n    throw new Error(\"User not found\")\n  }\n\n  return response.json()\n}\n\nconst fetchRepos = async (username) => {\n  const response = await fetch(`https://api.github.com/users/${username}/repos?per_page=100`)\n\n  return response.json()\n}\n\nconst createReport = (userInfo, userReposInfo) => {\n  const gists = userInfo.public_gists\n  const followers = userInfo.followers\n  const totalStars = userReposInfo.reduce((stars, repo) => stars + repo.stargazers_count, 0)\n  const totalForks = userReposInfo.reduce((forks, repo) => forks + repo.forks, 0)\n  const languages = [...new Set(\n    userReposInfo\n      .map(repo => repo.language)\n      .filter(Boolean)\n  )]\n\n  return {\n    gists,\n    followers,\n    stars: totalStars,\n    forks: totalForks,\n    languages\n  }\n}\n\nasync function getUser () {\n  while (true) {\n    const username = (await askUsername()).trim()\n\n    try {\n      if (!!username) return await fetchUser(username)\n\n      printError(\"Username cannot be empty\")\n    } catch (e) {\n      printError(e.message)\n    }\n  }\n}\n\nasync function main () {\n  try {\n    const user = await getUser()\n    const userReposInfo = await fetchRepos(user.login)\n\n    const report = createReport(user, userReposInfo)\n  \n    printReport(user.login, report)\n  \n    rl.close()\n\n  } catch (e) {\n    printError(e.message)\n  } finally {\n    rl.close()\n  }\n}\n\nmain() "
  },
  {
    "path": "Roadmap/45 - GITHUB OCTOVERSE/javascript/raulG91.js",
    "content": "\nconst https = require('node:https');\nconst { hostname } = require('node:os');\n\nconst TOKEN = 'YOUR TOKEN';\nconst HOSTNAME = 'api.github.com'\nconst header = {\n\n    'Authorization': `Bearer ${TOKEN}`,\n    \"Accept\": \"application/vnd.github+json\",\n    'User-Agent': 'raulG91'\n}\n\nasync function getUserInfo(user) {\n    return new Promise((resolve, reject) => {\n        const options = {\n            hostname: HOSTNAME,\n            path: `/users/${user}`,\n            method: 'GET',\n            headers: header\n\n        };\n        let userInfo = ''\n\n        https.get(options, (res) => {\n\n            res.on('data', (data) => {\n                userInfo += data\n            })\n\n            res.on('end', () => {\n                let info = JSON.parse(userInfo)\n                resolve(info)\n            })\n\n        }).on('error', (error) => {\n            reject('Error occurs')\n        })\n\n    })\n\n}\n\nasync function getReposInformation(user) {\n\n    return new Promise((resolve, reject) => {\n        const options = {\n            hostname: HOSTNAME,\n            path: `/users/${user}/repos`,\n            method: 'GET',\n            headers: header\n\n        };\n        let repo_info = '';\n\n        https.get(options, (res) => {\n\n            res.on('data', (data) => {\n                repo_info += data\n            })\n\n            res.on('end', () => {\n\n                let repos = []\n                repo_list = JSON.parse(repo_info)\n\n                for (let repo of repo_list) {\n                    repos.push({\n                        \"name\": repo.name,\n                        \"language\": repo.language,\n                        \"stars\": repo.stargazers_count,\n                        \"forks\": repo.forks\n                    })\n\n                }\n                resolve(repos)\n            })\n        }).on('error', (error) => {\n            console.log(\"Error occurs \" + error)\n            reject(error)\n        })\n\n    })\n}\n\n\nasync function main() {\n\n    const USER = \"mouredev\"\n    //Get user stats \n    try {\n        let userInfo = await getUserInfo(USER)\n        console.log(\"Number of followers is: \" + userInfo.followers)\n        console.log(\"Number of following users: \" + userInfo.following)\n        console.log(\"Number of public repositories: \" + userInfo.public_repos)\n    } catch (error) {\n        console.log(\"Error getting user data\")\n    }\n\n\n    //Get user's repos\n    try {\n        let repos = await getReposInformation(USER)\n        let languages = {}\n\n        for (let repo of repos) {\n\n            console.log(\"Repository name: \" + repo.name)\n            console.log(\"Repository  main language: \" + repo.language)\n            console.log(\"Repository stars: \" + repo.stars)\n            console.log(\"Repository forks: \" + repo.forks)\n\n            if ((repo.language != null) && !(repo.language in languages)) {\n\n                languages[repo.language] = 1\n\n            }\n            else if (repo.language != null) {\n                languages[repo.language] += 1\n            }\n        }\n        // Get most used language \n        let most_used_language = \"\"\n        let max_used_times = 0\n        for (let item in languages) {\n            if (languages[item] > max_used_times) {\n                max_used_times = languages[item]\n                most_used_language = item\n            }\n        }\n        console.log(\"Most used language is: \" + most_used_language + \" it has been used: \" + max_used_times + \" times\")\n    } catch (error) {\n\n        console.log(\"Error getting data for repositories\")\n    }\n\n\n}\n\nmain()"
  },
  {
    "path": "Roadmap/45 - GITHUB OCTOVERSE/kotlin/blackriper.kt",
    "content": "import kotlinx.coroutines.Dispatchers\r\nimport kotlinx.coroutines.launch\r\nimport kotlinx.coroutines.runBlocking\r\nimport org.kohsuke.github.GHRepositoryStatistics\r\nimport org.kohsuke.github.GitHub\r\nimport org.kohsuke.github.GitHubBuilder\r\n\r\n/**\r\n para simplificar el desarrollo vamos a utilizar una de las librerias recomendadas de github para java\r\n este ejercicio es kotlin pero hay que aprovechar su poder para usar cosas de java\r\n\r\n https://mvnrepository.com/artifact/org.kohsuke/github-api/1.326\r\n\r\n **/\r\n\r\n//1.- definir estructuras y comportamiento\r\n\r\ndata class GitReport(\r\n    var name: String,\r\n    var language: String,\r\n    var repoCount: Int,\r\n    var follow: Int,\r\n    var numCommits: Int\r\n)\r\n\r\ninterface OctoverseInfo{\r\n    suspend fun findGithubUser(): String\r\n    suspend fun generateUserRepo(userName: String):GitReport\r\n}\r\n\r\n\r\n\r\n//2.- implementacion y modulo auxiliar\r\n\r\nclass GitHubReport:OctoverseInfo{\r\n\r\n    private lateinit var userGit: GitHub\r\n\r\n    override suspend fun findGithubUser(): String {\r\n      println(\"Enter you github username \")\r\n      val username=readLine()?:\"\"\r\n      println(\"Generate personal token access in your github account and copy them\")\r\n      var accessToken=readLine()?:\"\"\r\n      userGit= GitHubBuilder().withOAuthToken(accessToken).build()\r\n      return username\r\n    }\r\n\r\n    override suspend fun generateUserRepo(userName: String): GitReport {\r\n       val dataUser=userGit.getUser(userName).run {\r\n           val language =\r\n               countRepeatElements(this.repositories.map { it.value.language }.filter { it != null }) ?: \"\"\r\n           return GitReport(\r\n               userName,\r\n               language,\r\n               this.publicRepoCount,\r\n               this.followersCount,\r\n               GHRepositoryStatistics.CommitActivity().total\r\n           )\r\n       }\r\n    }\r\n\r\n}\r\n\r\n//funcion para contar elementos repetidos\r\n private fun  GitHubReport.countRepeatElements(listE: List<String>): String? {\r\n    val countMap = mutableMapOf<String, Int>()\r\n     return listE.forEach { countMap[it] = countMap.getOrDefault(it, 0) + 1 }.let {countMap.maxByOrNull { it.value }?.key}\r\n\r\n}\r\n// funcion de extension para mostrar el reporte\r\nfun GitReport.getReport(): String=\"\"\"\r\n    Octoverse Report\r\n    Name: $name\r\n    Language more use this year : $language\r\n    Number of Repositories: $repoCount\r\n    Number of Follows: $follow\r\n    Number of Commits: $numCommits\r\n    \r\n\"\"\".trimIndent()\r\n\r\n\r\nfun main() = runBlocking{\r\n  val job= launch(Dispatchers.LOOM){\r\n      val gitInfo=GitHubReport()\r\n      val username= gitInfo.findGithubUser()\r\n      gitInfo.generateUserRepo(username).run {\r\n          println(this.getReport())\r\n      }\r\n  }\r\n  job.join()\r\n\r\n}"
  },
  {
    "path": "Roadmap/45 - GITHUB OCTOVERSE/php/miguelex.php",
    "content": "<?php\n\nclass GitHubUserReport\n{\n    private $username;\n    private $baseApiUrl = \"https://api.github.com\";\n    private $headers = [\n        \"User-Agent: GitHub-Report-App\",\n        \"Accept: application/vnd.github.v3+json\"\n    ];\n\n    public function __construct($username)\n    {\n        $this->username = $username;\n    }\n\n    private function apiRequest($endpoint)\n    {\n        $url = $this->baseApiUrl . $endpoint;\n        $curl = curl_init($url);\n\n        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);\n        curl_setopt($curl, CURLOPT_HTTPHEADER, $this->headers);\n        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // Asegura la validación SSL\n\n        $response = curl_exec($curl);\n        $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);\n        $curlError = curl_error($curl);\n\n        curl_close($curl);\n\n        if ($response === false) {\n            die(\"Error de conexión: $curlError\\n\");\n        }\n\n        if ($httpCode !== 200) {\n            die(\"Error al conectar con la API de GitHub (HTTP $httpCode). Verifica el nombre de usuario.\\n\");\n        }\n\n        return json_decode($response, true);\n    }\n\n\n    private function getUserInfo()\n    {\n        return $this->apiRequest(\"/users/{$this->username}\");\n    }\n\n    // Obtener todos los repositorios del usuario\n    private function getUserRepos()\n    {\n        return $this->apiRequest(\"/users/{$this->username}/repos\");\n    }\n\n    // Generar el informe\n    public function generateReport()\n    {\n        $userInfo = $this->getUserInfo();\n        $repos = $this->getUserRepos();\n\n        $totalRepos = count($repos);\n        $followers = $userInfo['followers'];\n        $following = $userInfo['following'];\n\n        // Analizar lenguajes utilizados\n        $languages = [];\n        foreach ($repos as $repo) {\n            if (!empty($repo['language'])) {\n                $languages[] = $repo['language'];\n            }\n        }\n        $mostUsedLanguage = $languages ? array_count_values($languages) : [];\n        arsort($mostUsedLanguage);\n        $topLanguage = $mostUsedLanguage ? array_key_first($mostUsedLanguage) : \"N/A\";\n\n        // Calcular estrellas totales y forks\n        $totalStars = array_sum(array_column($repos, 'stargazers_count'));\n        $totalForks = array_sum(array_column($repos, 'forks_count'));\n\n\n        echo \"=== Informe de GitHub para el usuario: {$this->username} ===\\n\";\n        echo \"Nombre: {$userInfo['name']}\\n\";\n        echo \"Bio: {$userInfo['bio']}\\n\";\n        echo \"Ubicación: {$userInfo['location']}\\n\";\n        echo \"Total de repositorios: $totalRepos\\n\";\n        echo \"Seguidores: $followers\\n\";\n        echo \"Seguidos: $following\\n\";\n        echo \"Lenguaje más utilizado: $topLanguage\\n\";\n        echo \"Total de estrellas: $totalStars\\n\";\n        echo \"Total de forks: $totalForks\\n\";\n    }\n}\n\n\necho \"Ingrese el nombre de usuario de GitHub: \";\n$username = trim(fgets(STDIN));\n\nif (empty($username)) {\n    die(\"Debe ingresar un nombre de usuario.\\n\");\n}\n\n$report = new GitHubUserReport($username);\n$report->generateReport();\n"
  },
  {
    "path": "Roadmap/45 - GITHUB OCTOVERSE/python/CarlosVR48.py",
    "content": "import requests\n\ndef preguntar(nombre):\n    url = f\"\\nhttps://api.github.com/users/{nombre}\"\n    print(url)\n    pregunta = requests.get(url).json()\n    return pregunta\n\nwhile True:\n    nombre = input (\"\\nDIME EL NOMBRE DE USUARIO GITHUB ? (SALIR) \").lower()\n    if nombre == \"salir\":\n        break\n    try:\n        pregunta = preguntar(nombre)\n        \n        name = pregunta.get(\"name\")\n        print(f\"\\nNombre: {name}\")\n        \n        if name == None:\n            print (\"\\nUSUARIO NO DISPONIBLE\")\n        else:\n            email = pregunta.get(\"email\")\n            print(f\"\\nEmail: {email}\") \n\n            location = pregunta.get(\"location\")\n            print(f\"\\nPaís: {location}\") \n\n            estrellas = pregunta.get(\"public_gists\")\n            print(f\"\\nEstrellas: {estrellas}\") \n\n            creacion = pregunta.get(\"created_at\")\n            print(f\"\\nCreación: {creacion}\") \n\n            bio = pregunta.get(\"bio\")\n            print(f\"\\nBio: {bio}\") \n\n    except:\n        print (\"EL USUARIO NO EXISTE O NO DISPONIBLE\\n\")"
  },
  {
    "path": "Roadmap/45 - GITHUB OCTOVERSE/python/EmmanuelMMontesinos.py",
    "content": "\"\"\"\n * EJERCICIO:\n * GitHub ha publicado el Octoverse 2024, el informe\n * anual del estado de la plataforma:\n * https://octoverse.github.com\n *\n * Utilizando el API de GitHub, crea un informe asociado\n * a un usuario concreto.\n * \n * - Se debe poder definir el nombre del usuario\n *   sobre el que se va a generar el informe.\n *   \n * - Crea un informe de usuario basándote en las 5 métricas\n *   que tú quieras, utilizando la informración que te\n *   proporciona GitHub. Por ejemplo:\n *   - Lenguaje más utilizado\n *   - Cantidad de repositorios\n *   - Seguidores/Seguidos\n *   - Stars/forks\n *   - Contribuciones\n *   (lo que se te ocurra)\n\"\"\"\nimport requests\n\nclass InformeGitHub:\n    def __init__(self, username):\n        self.username = username\n        self.url = f\"https://api.github.com/users/{username}\"\n        self.response = requests.get(self.url)\n        self.data = self.response.json()\n\n    def obtener_informe(self):\n        return {\n            \"Nombre\": self.data[\"name\"],\n            \"Avatar\": self.data[\"avatar_url\"],\n            \"Pais\": self.data[\"location\"],\n            \"Bio\": self.data[\"bio\"],\n            \"Empresa\": self.data[\"company\"],\n            \"Seguidores\": self.data[\"followers\"],\n            \"Seguidos\": self.data[\"following\"],\n            \"Repositorios\": self.data[\"public_repos\"],\n            \"Stars\": self.data[\"public_gists\"],\n        }\n    def actualizar_informe(self):\n        self.response = requests.get(self.url)\n        self.data = self.response.json()\n    def imprimir_informe(self):\n        informe = self.obtener_informe()\n        print(f\"Nombre: {informe['Nombre']}\")\n        print(f\"Seguidores: {informe['Seguidores']}\")\n        print(f\"Avatar: {informe['Avatar']}\")\n        print(f\"Bio: {informe['Bio']}\")\n        print(f\"Empresa: {informe['Empresa']}\")\n        print(f\"Seguidos: {informe['Seguidos']}\")\n        print(f\"Repositorios: {informe['Repositorios']}\")\n        print(f\"Stars: {informe['Stars']}\")\n        print(f\"Pais: {informe['Pais']}\")\n\n# Prueba\n\ninforme_Emmanuel = InformeGitHub(\"EmmanuelMMontesinos\")\ninforme_Emmanuel.imprimir_informe()\nprint()\ninforme_Mouredev = InformeGitHub(\"MoureDev\")\ninforme_Mouredev.imprimir_informe()"
  },
  {
    "path": "Roadmap/45 - GITHUB OCTOVERSE/python/Gordo-Master.py",
    "content": "# 45 - Github Octoverse\nimport requests\nimport env\n\n\ndef generate_report(name):\n    base_url = \"https://api.github.com\"\n    url = f\"{base_url}/users/{name}\"\n    headers = {\n        \"Accept\": \"application/vnd.github+json\", \n        \"Authorization\": f\"Bearer {env.token}\", \n        \"X-GitHub-Api-Version\": \"2022-11-28\"\n    }\n    \n    basic_info = requests.get(url,headers=headers).json()\n    \n    if \"status\" in basic_info and basic_info[\"status\"]==\"404\":\n        print(f\"Usuario {username} no encontrado\")\n        return\n    \n    report = {\n        \"Nombre\" : basic_info.get(\"name\", \"Desconocido\"),\n        \"Compañia\" : basic_info.get(\"company\", \"Desconocida\"),\n        \"Repositorio públicos\" : basic_info.get(\"public_repos\",0),\n        \"Gists\" : basic_info.get(\"public_gists\",0),\n        \"Seguidores\" : basic_info.get(\"followers\",0),\n        \"Seguidos\" : basic_info.get(\"following\",0),\n    }\n\n    print(f\"Informe del usuario: {username}:\")\n    for key, value in report.items():\n        print(f\"{key}: {value}\")\n    \n\n    repos_url = basic_info[\"repos_url\"]\n    repos_data = requests.get(repos_url).json()\n\n    languages = {}\n\n    for repo in repos_data:\n\n        language = repo.get(\"language\", \"No especificado\")\n        if language:\n            if language in languages:\n                languages[language] += 1\n            else:\n                languages[language] = 1\n\n        print(f\"\\nRepo: {repo.get(\"full_name\")}\")\n        print(f\"Stars: {repo.get(\"stargazers_count\",0)}\")\n        print(f\"Forks: {repo.get(\"forks_count\",0)}\")\n\n    if languages:\n        most_used_languages = max(languages,key=languages.get)\n    else:\n        most_used_languages = \"No definido\"\n    \n    print(f\"\\nEl lenguaje favorito de {username} es: {most_used_languages}\")\n\n    print(languages)\n\n\nusername = input(\"Ingresa el nombre del usuario: \")\ngenerate_report(username)\n\n"
  },
  {
    "path": "Roadmap/45 - GITHUB OCTOVERSE/python/Juanppdev.py",
    "content": "\"\"\"\n * EJERCICIO:\n * GitHub ha publicado el Octoverse 2024, el informe\n * anual del estado de la plataforma:\n * https://octoverse.github.com\n *\n * Utilizando el API de GitHub, crea un informe asociado\n * a un usuario concreto.\n * \n * - Se debe poder definir el nombre del usuario\n *   sobre el que se va a generar el informe.\n *   \n * - Crea un informe de usuario basándote en las 5 métricas\n *   que tú quieras, utilizando la informración que te\n *   proporciona GitHub. Por ejemplo:\n *   - Lenguaje más utilizado\n *   - Cantidad de repositorios\n *   - Seguidores/Seguidos\n *   - Stars/forks\n *   - Contribuciones\n *   (lo que se te ocurra)\n\"\"\"\n\nimport requests\n\ndef obtener_informe_usuario(usuario, token=None):\n    \"\"\"Genera un informe para un usuario de GitHub.\"\"\"\n    base_url = \"https://api.github.com\"\n    headers = {\"Authorization\": f\"token {token}\"} if token else {}\n\n    try:\n        # Obtener información básica del usuario\n        respuesta_usuario = requests.get(f\"{base_url}/users/{usuario}\", headers=headers)\n        respuesta_usuario.raise_for_status()\n        datos_usuario = respuesta_usuario.json()\n        \n        # Métricas básicas\n        nombre = datos_usuario.get(\"name\", \"N/A\")\n        seguidores = datos_usuario.get(\"followers\", 0)\n        seguidos = datos_usuario.get(\"following\", 0)\n        repos_publicos = datos_usuario.get(\"public_repos\", 0)\n\n        # Obtener los repositorios del usuario\n        respuesta_repos = requests.get(f\"{base_url}/users/{usuario}/repos\", headers=headers, params={\"per_page\": 100})\n        respuesta_repos.raise_for_status()\n        repositorios = respuesta_repos.json()\n\n        # Métricas de repositorios\n        lenguajes = {}\n        estrellas_totales = 0\n\n        for repo in repositorios:\n            leng = repo.get(\"language\")\n            if leng:\n                lenguajes[leng] = lenguajes.get(leng, 0) + 1\n            estrellas_totales += repo.get(\"stargazers_count\", 0)\n\n        # Determinar el lenguaje más utilizado\n        lenguaje_mas_utilizado = max(lenguajes, key=lenguajes.get, default=\"N/A\")\n\n        # Crear el informe\n        informe = f\"\"\"\n        Informe de Usuario de GitHub: {usuario}\n        ---------------------------------\n        Nombre: {nombre}\n        Seguidores: {seguidores}\n        Seguidos: {seguidos}\n        Repositorios Públicos: {repos_publicos}\n        Lenguaje más utilizado: {lenguaje_mas_utilizado}\n        Total de Stars recibidas: {estrellas_totales}\n        \"\"\"\n        print(informe)\n    except requests.exceptions.RequestException as e:\n        print(f\"Error al obtener datos: {e}\")\n\n# Ejemplo de uso\nusuario = \"juanppdev\"  # Cambia por el nombre de usuario deseado\ntoken = \"TU_TOKEN_PERSONAL\"  # Opcional, para evitar límites de la API\nobtener_informe_usuario(usuario, token)\n"
  },
  {
    "path": "Roadmap/45 - GITHUB OCTOVERSE/python/Nicojsuarez2.py",
    "content": "# #45 GITHUB OCTOVERSE\n> #### Dificultad: Media | Publicación: 11/11/24 | Corrección: 18/11/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * GitHub ha publicado el Octoverse 2024, el informe\n * anual del estado de la plataforma:\n * https://octoverse.github.com\n *\n * Utilizando el API de GitHub, crea un informe asociado\n * a un usuario concreto.\n * \n * - Se debe poder definir el nombre del usuario\n *   sobre el que se va a generar el informe.\n *   \n * - Crea un informe de usuario basándote en las 5 métricas\n *   que tú quieras, utilizando la información que te\n *   proporciona GitHub. Por ejemplo:\n *   - Lenguaje más utilizado\n *   - Cantidad de repositorios\n *   - Seguidores/Seguidos\n *   - Stars/forks\n *   - Contribuciones\n *   (lo que se te ocurra)\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/45 - GITHUB OCTOVERSE/python/cdryampi.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * GitHub ha publicado el Octoverse 2024, el informe\n * anual del estado de la plataforma:\n * https://octoverse.github.com\n *\n * Utilizando el API de GitHub, crea un informe asociado\n * a un usuario concreto.\n * \n * - Se debe poder definir el nombre del usuario\n *   sobre el que se va a generar el informe.\n *   \n * - Crea un informe de usuario basándote en las 5 métricas\n *   que tú quieras, utilizando la informración que te\n *   proporciona GitHub. Por ejemplo:\n *   - Lenguaje más utilizado\n *   - Cantidad de repositorios\n *   - Seguidores/Seguidos\n *   - Stars/forks\n *   - Contribuciones\n *   (lo que se te ocurra)\n */\n\"\"\"\n\nimport aiohttp\nimport asyncio\nfrom collections import defaultdict\n\nclass APIGitHub():\n    \"\"\"\n    https://docs.github.com/en/rest?apiVersion=2022-11-28\n    \"\"\"\n    __ACCESS_TOKEN = ':)'\n    __BASE_URL_API = \"https://api.github.com/\"\n    __HEADERS = None\n    __ENDPOINTS = {\n        \"repos\": \"users/{owner}/repos\",\n        \"languages\": \"repos/{owner}/{repo_name}/languages\",\n        \"user\": \"users/{owner}\",\n        \"commits\": 'repos/{owner}/{repo_name}/commits?author={owner}'\n    }\n\n    __USER_REPO_DATA = None\n    __OWNER = None\n\n\n    async def clear_data(self) -> None:\n        \"\"\"Función que sirve para limpiar las variables del fetch\"\"\"\n        self.__USER_REPO_DATA = None\n        self.__OWNER = None\n\n    async def set_user(self) -> str:\n        if self.__OWNER == None:\n            self.__OWNER = input(\"Intoduce un usuario de github:\\n\")\n\n    async def get_headers(self) -> dict:\n        \"\"\"Función para obtener la cabecera con el token sacado del settings de una cuenta del github\"\"\"\n        if self.__HEADERS is None:\n            self.__HEADERS = {\n                'Authorization': f'token {self.__ACCESS_TOKEN}',\n                'Accept': 'application/vnd.github.v3+json'\n            }\n        return self.__HEADERS\n\n    async def get_total_respos(self, session) -> None:\n        \"\"\"Función para obtener el total de repositorios\"\"\"\n        headers = await self.get_headers()\n        await self.set_user()\n        url = f\"{self.__BASE_URL_API}{self.__ENDPOINTS['repos']}\".format(owner = self.__OWNER)\n\n        async with session.get(url, headers=headers) as response:\n            if response.status == 200:\n                data = await response.json()\n                self.__USER_REPO_DATA = data\n            else:\n                print(f'Error fetching: {response.status}')\n\n    async def get_user_data(self, session) -> None:\n        languages_count = defaultdict(int)\n        headers = await self.get_headers()\n        await self.get_total_respos(session)\n\n        total_repos = 0\n        total_stars = 0\n        total_forks = 0\n        total_commits = 0\n\n        if self.__USER_REPO_DATA is not None:\n            total_repos = len(self.__USER_REPO_DATA)\n            for repo in self.__USER_REPO_DATA:\n                repo_name = repo['name']\n                owner = repo['owner']['login']\n                total_stars += repo.get(\"stargazers_count\", 0)\n                total_forks += repo.get(\"forks_count\", 0)\n                languages_url = f'{self.__BASE_URL_API}{self.__ENDPOINTS['languages']}'.format(owner = owner, repo_name = repo_name)\n                commits_url = f\"{self.__BASE_URL_API}{self.__ENDPOINTS['commits']}\".format(owner = owner, repo_name = repo_name)\n\n                async with session.get(commits_url, headers = headers) as response_commits:\n                    if response_commits.status == 200:\n                        commits = await response_commits.json()\n                        total_commits += len(commits)\n                    else:\n                        print(f\"Error al obtener commits para {repo_name}: {response_commits.status}\\nPuede ser que no tengas commits realizados\")\n\n                async with session.get(languages_url, headers = headers) as response_languages:\n                    if response_languages.status == 200:\n                        languages = await response_languages.json()\n                        for language, bytes_count in languages.items():\n                            languages_count[language] += bytes_count\n                    else:\n                        print(f\"Error fetching: {response_languages.status}\")\n\n        await self.print_user_data(session=session, languages_count=languages_count, total_repos=total_repos, total_stars= total_stars, total_forks = total_forks, total_commits= total_commits)\n    \n\n    async def print_user_data(self, session, languages_count, total_repos, total_stars, total_forks, total_commits):\n        \"\"\"Función que sirve para pintar los datos del usuario\"\"\"\n        await self.print_user_info(session)\n        if languages_count:\n            most_used_language = max(languages_count, key=languages_count.get)\n            print(f\"El lenguaje más utilizado es: {most_used_language}\")\n        else:\n            print(\"No se encontraron lenguajes en tus repositorios.\")\n        print(f'Total de repositorios:{total_repos}')\n        print(f\"Total de estrellas (stars) en todos los repositorios: {total_stars}\")\n        print(f\"Total de bifurcaciones (forks) en todos los repositorios: {total_forks}\")\n        print(f\"Total de commits realizados: {total_commits}\")\n\n    async def print_user_info(self, session):\n        headers = await self.get_headers()\n        url = f\"{self.__BASE_URL_API}{self.__ENDPOINTS['user']}\".format(owner = self.__OWNER)\n        async with session.get(url, headers =headers) as response:\n            if response.status == 200:\n                user_info = await response.json()\n                print(f\"Nombre: {user_info['name']}\")\n                print(f\"Empresa: {user_info['company']}\")\n                print(f\"Ubicación: {user_info['location']}\")\n                print(f\"Bio: {user_info['bio']}\")\n                print(f\"Blog: {user_info['blog']}\")\n                print(f\"Seguidores: {user_info['followers']}\")\n                print(f\"Siguiendo: {user_info['following']}\")\n            else:\n                print(f\"Error fetching: {response.status}\")\n\n\nasync def main():\n    api = APIGitHub()\n\n    async with aiohttp.ClientSession() as session:\n        await api.get_user_data(session)\n\nif __name__ == '__main__':\n    asyncio.get_event_loop().run_until_complete(main())"
  },
  {
    "path": "Roadmap/45 - GITHUB OCTOVERSE/python/davidrguez98.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * GitHub ha publicado el Octoverse 2024, el informe\n * anual del estado de la plataforma:\n * https://octoverse.github.com\n *\n * Utilizando el API de GitHub, crea un informe asociado\n * a un usuario concreto.\n * \n * - Se debe poder definir el nombre del usuario\n *   sobre el que se va a generar el informe.\n *   \n * - Crea un informe de usuario basándote en las 5 métricas\n *   que tú quieras, utilizando la informración que te\n *   proporciona GitHub. Por ejemplo:\n *   - Lenguaje más utilizado\n *   - Cantidad de repositorios\n *   - Seguidores/Seguidos\n *   - Stars/forks\n *   - Contribuciones\n *   (lo que se te ocurra)\n */ \"\"\"\n\nimport requests\n\ndef generate_github_report(username: str):\n\n    base_url = \"https://api.github.com\"\n\n    user_url = f\"{base_url}/users/{user_name}\"\n    user_data = requests.get(user_url).json()\n\n    if \"status\" in user_data and user_data[\"status\"] == \"404\":\n        print(f\"Usuario {user_name} no encontrado.\")\n        return\n\n    report = {\n        \"name\": user_data.get(\"name\", \"Desconocido\"),\n        \"company\": user_data.get(\"company\", \"Desconocida\"),\n        \"public_repos\": user_data.get(\"public_repos\", 0),\n        \"public_gists\": user_data.get(\"public_gists\", 0),\n        \"followers\": user_data.get(\"followers\", 0),\n        \"following\": user_data.get(\"following\", 0)\n    }\n\n    print(f\"Informe del usuario {user_name}:\")\n    for key,value in report.items():\n        print(f\"{key}: {value}\")\n\n    repos_url = user_data[\"repos_url\"]\n    repos_data = requests.get(repos_url).json()\n\n    languages = {}\n    \n    for repo in repos_data:\n\n        language = repo.get(\"language\")\n        if language:\n            if language in languages:\n                languages[language] += 1\n            else:\n                languages[language] = 1\n\n        print(f\"\\nRepo: {repo.get(\"full_name\")}\")\n        print(f\"Stars: {repo.get(\"stargazers_count\", 0)}\")\n        print(f\"Forks: {repo.get(\"forks_count\", 0)}\")\n\n    most_used_language = None\n    max_count = 0\n    for name, count in languages.items():\n        if count > max_count:\n            most_used_language = name\n            max_count = count\n\n    print(f\"\\nLenguaje más usado {most_used_language if most_used_language else \"Desconocido\"}\")\n\n\n\nuser_name = input(\"Ingresa el nombre de usuario de GitHub: \")\ngenerate_github_report(user_name)"
  },
  {
    "path": "Roadmap/45 - GITHUB OCTOVERSE/python/duendeintemporal.py",
    "content": "#45 { Retos para Programadores } GITHUB OCTOVERSE \n\n# Bibliography reference:\n# I use GPT as a reference and sometimes to correct or generate proper comments.\n\n\"\"\"\n * EJERCICIO:\n * GitHub ha publicado el Octoverse 2024, el informe\n * anual del estado de la plataforma:\n * https://octoverse.github.com\n *\n * Utilizando el API de GitHub, crea un informe asociado\n * a un usuario concreto.\n * \n * - Se debe poder definir el nombre del usuario\n *   sobre el que se va a generar el informe.\n *\n * - Crea un informe de usuario basándote en las 5 métricas\n *   que tú quieras, utilizando la información que te\n *   proporciona GitHub. Por ejemplo:\n *   - Lenguaje más utilizado\n *   - Cantidad de repositorios\n *   - Seguidores/Seguidos\n *   - Stars/forks\n *   - Contribuciones\n *   (lo que se te ocurra)\n\"\"\"\n\nimport asyncio\nimport aiohttp\nimport logging\n\n# Set up logging\nlogging.basicConfig(level=logging.INFO)\nlog = logging.info\n\nasync def fetch_github_data(username):\n    async with aiohttp.ClientSession() as session:\n        async with session.get(f'https://api.github.com/users/{username}') as response:\n            user_data = await response.json()\n        \n        async with session.get(f'https://api.github.com/users/{username}/repos') as response:\n            repos_data = await response.json()\n        \n        return user_data, repos_data\n\nasync def generate_user_report(username):\n    user_data, repos_data = await fetch_github_data(username)\n\n    # Calculate metrics\n    most_used_language = None\n    total_stars = 0\n    total_repos = len(repos_data)\n    followers = user_data.get('followers', 0)\n    following = user_data.get('following', 1)  # Avoid division by zero\n    contributions = user_data.get('contributions', 'N/A')  # This may still be N/A\n\n    # Analyze repositories\n    language_count = {}\n    for repo in repos_data:\n        if 'language' in repo and repo['language']:\n            language_count[repo['language']] = language_count.get(repo['language'], 0) + 1\n            total_stars += repo.get('stargazers_count', 0)\n\n    if language_count:\n        most_used_language = max(language_count, key=language_count.get)\n\n    followers_following_ratio = (followers / following) if following > 0 else 'N/A'\n    stars_forks_ratio = (total_stars / total_repos) if total_repos > 0 else 'N/A'\n\n    metrics = [\n        {'name': 'Most Used Language', 'key': 'language', 'value': most_used_language or 'N/A'},\n        {'name': 'Number of Repositories', 'key': 'public_repos', 'value': total_repos},\n        {'name': 'Followers/Following', 'key': 'followers_following_ratio', 'value': f\"{followers_following_ratio:.2f}\" if isinstance(followers_following_ratio, float) else 'N/A'},\n        {'name': 'Stars/Forks', 'key': 'stars_forks_ratio', 'value': stars_forks_ratio},\n        {'name': 'Contributions', 'key': 'contributions', 'value': contributions},\n    ]\n\n    report = f'GitHub User Report for {username}:\\n\\n'\n    for metric in metrics:\n        report += f\"{metric['name']}: {metric['value']}\\n\"\n\n    return report\n\n\nasync def main():\n    username = 'mouredev'\n    report = await generate_user_report(username)\n    log(report)\n\nif __name__ == '__main__':\n    asyncio.run(main())\n\n# Output:\n\"\"\"   \nMost Used Language: Swift\nNumber of Repositories: 30\nFollowers/Following: 13220.50\nStars/Forks: 1392.8666666666666\nContributions: N/A\n\n\"\"\""
  },
  {
    "path": "Roadmap/45 - GITHUB OCTOVERSE/python/hectorio23.py",
    "content": "# Autor: Héctor Adán\n# GitHub: https://github.com/hectorio23\n\nimport requests\n\nclass GitHubUserReport:\n    BASE_URL = \"https://api.github.com\"\n\n    def __init__(self, username):\n        self.username = username\n\n    def fetch_data(self, endpoint):\n        url = f\"{self.BASE_URL}/{endpoint}\"\n        response = requests.get(url)\n        if response.status_code != 200:\n            raise Exception(f\"Error fetching data from {url}: {response.status_code}\")\n        return response.json()\n\n    def get_user_info(self):\n        return self.fetch_data(f\"users/{self.username}\")\n\n    def get_repos(self):\n        return self.fetch_data(f\"users/{self.username}/repos\")\n\n    def generate_report(self):\n        user_info = self.get_user_info()\n        repos = self.get_repos()\n\n        # Metric 1: Most used language\n        languages = {}\n        for repo in repos:\n            if repo['language']:\n                languages[repo['language']] = languages.get(repo['language'], 0) + 1\n        most_used_language = max(languages, key=languages.get) if languages else \"Unknown\"\n\n        # Metric 2: Total number of repositories\n        total_repos = len(repos)\n\n        # Metric 3: Total stars received\n        total_stars = sum(repo['stargazers_count'] for repo in repos)\n\n        # Metric 4: Followers\n        followers = user_info.get('followers', 0)\n\n        # Metric 5: Following\n        following = user_info.get('following', 0)\n\n        # Generate the report\n        report = {\n            \"\\t[+] - Username\": self.username,\n            \"\\t[+] - Most Used Language\": most_used_language,\n            \"\\t[+] - Total Repositories\": total_repos,\n            \"\\t[+] - Total Stars\": total_stars,\n            \"\\t[+] - Followers\": followers,\n            \"\\t[+] - Following\": following,\n        }\n        return report\n\n\nif __name__ == \"__main__\":\n    username = input(\"[+] - Enter the GitHub username: \")\n    report_generator = GitHubUserReport(username)\n    try:\n        report = report_generator.generate_report()\n        print(\"\\n[+] - GitHub User Report:\")\n        for key, value in report.items():\n            print(f\"{key}: {value}\")\n    except Exception as e:\n        print(f\"[+] - Error: {e}\")\n"
  },
  {
    "path": "Roadmap/45 - GITHUB OCTOVERSE/python/hozlucas28.py",
    "content": "# pylint: disable=missing-module-docstring,missing-class-docstring,missing-function-docstring,too-few-public-methods,broad-exception-raised,broad-exception-caught\n\nfrom abc import ABCMeta, abstractmethod\nfrom os import system\nfrom typing import TypedDict\nimport requests\n\n\n# ---------------------------------------------------------------------------- #\n#                              TYPES - GITHUB API                              #\n# ---------------------------------------------------------------------------- #\n\nGitHubPublicRepos = TypedDict(\"GitHubPublicRepos\", {\"fork\": bool})\n\nGitHubStars = TypedDict(\"GitHubStars\", {\"url\": str})\n\nGitHubUserData = TypedDict(\n    \"GitHubUserData\",\n    {\n        \"followers\": int,\n        \"following\": int,\n        \"login\": str,\n        \"name\": str,\n        \"public_repos\": int,\n        \"repos_url\": str,\n        \"public_repos_data\": list[GitHubPublicRepos],\n        \"stars\": list[GitHubStars],\n    },\n)\n\nGitHubAPI = TypedDict(\"GitHubAPI\", {\"user\": GitHubUserData})\n\n\n# ---------------------------------------------------------------------------- #\n#                                    CLASSES                                   #\n# ---------------------------------------------------------------------------- #\n\nUserData = TypedDict(\n    \"UserData\",\n    {\n        \"followers\": int,\n        \"following\": int,\n        \"forks\": int,\n        \"name\": str,\n        \"public_repositories\": int,\n        \"stars\": int,\n        \"userName\": str,\n    },\n)\n\n\nclass GitHubAdapters:\n    @staticmethod\n    def user_data(*, _user_data: GitHubUserData) -> UserData:\n        forks: int = 0\n        for public_repo in _user_data[\"public_repos_data\"]:\n            if public_repo[\"fork\"]:\n                forks += 1\n\n        return {\n            \"followers\": _user_data[\"followers\"],\n            \"following\": _user_data[\"following\"],\n            \"forks\": forks,\n            \"name\": _user_data[\"name\"],\n            \"public_repositories\": _user_data[\"public_repos\"],\n            \"stars\": len(_user_data[\"stars\"]),\n            \"userName\": _user_data[\"login\"],\n        }\n\n\nclass AbcGitHubService(metaclass=ABCMeta):\n    @abstractmethod\n    def fetch_user_data(self, *, user_name: str) -> UserData:\n        pass\n\n\nclass GitHubService(AbcGitHubService):\n    __api_token: str\n\n    def __init__(self, *, api_token: str) -> None:\n        self.__api_token = api_token\n\n    def fetch_user_data(self, *, user_name: str) -> UserData:\n\n        headers: dict[str, str] = {\n            \"Authorization\": f\"Bearer {self.__api_token}\",\n            \"Accept\": \"application/vnd.github+json\",\n            \"X-GitHub-Api-Version\": \"2022-11-28\",\n        }\n\n        response: requests.Response = requests.get(\n            url=f\"https://api.github.com/users/{user_name}\",\n            headers=headers,\n            timeout=1000,\n        )\n\n        if response.status_code != 200:\n            raise Exception(\"An error occurred on fetch user data\")\n\n        _user_data: GitHubUserData = response.json()\n\n        response: requests.Response = requests.get(\n            url=f\"https://api.github.com/users/{user_name}/starred\",\n            headers=headers,\n            timeout=1000,\n        )\n\n        if response.status_code != 200:\n            raise Exception(\"An error occurred on fetch user data\")\n\n        stars: list[GitHubStars] = response.json()\n        _user_data[\"stars\"] = stars\n\n        response: requests.Response = requests.get(\n            url=_user_data[\"repos_url\"],\n            headers=headers,\n            timeout=1000,\n        )\n\n        if response.status_code != 200:\n            raise Exception(\"An error occurred on fetch user data\")\n\n        public_repos: list[GitHubPublicRepos] = response.json()\n        _user_data[\"public_repos_data\"] = public_repos\n\n        return GitHubAdapters.user_data(_user_data=_user_data)\n\n\n# ---------------------------------------------------------------------------- #\n#                                     MAIN                                     #\n# ---------------------------------------------------------------------------- #\n\nAPI_TOKEN: str = \"XXX\"  # Complete with your personal GitHub Access Token.\n\ngithub_service: AbcGitHubService = GitHubService(api_token=API_TOKEN)\nuser_input: str = input(\"> Enter a GitHub username (-1 to exit): \").strip()\n\nwhile user_input != \"-1\":\n    try:\n        user_data: UserData = github_service.fetch_user_data(user_name=user_input)\n\n        system(command=\"clear\")\n\n        print(f\"+ {'':{'-'}<52} +\")\n        print(f'+ {user_data[\"userName\"]:^52} +')\n        print(f\"+ {'':{'-'}<52} +\")\n\n        print(f\"{f'+ Name: {user_data[\"name\"]}.':<54} +\")\n        print(f\"{f'+ Public repositories: {user_data[\"public_repositories\"]}.':<54} +\")\n        print(f\"{f'+ Repositories stared: {user_data[\"stars\"]}':<54} +\")\n        print(f\"{f'+ Number of repositories forked: {user_data[\"forks\"]}.':<54} +\")\n        print(f\"{f'+ Following: {user_data[\"following\"]}.':<54} +\")\n        print(f\"{f'+ Followers: {user_data[\"followers\"]}.':<54} +\")\n\n        print(f\"+ {'':{'-'}<52} +\")\n    except Exception as error:\n        print(f\"\\n> An error occurred on fetch '{user_input}' username! Try again...\")\n\n    user_input: str = input(\"\\n> Enter a GitHub username (-1 to exit): \").strip()\n"
  },
  {
    "path": "Roadmap/45 - GITHUB OCTOVERSE/python/idiegorojas.py",
    "content": "\"\"\" \n# 45 - Github Octoverse \n\"\"\"\n\n# https://octoverse.github.com\n# Utilizando el API de GitHub, crea un informe asociado a un usuario concreto.\n\n# Se debe poder definir el nombre del usuario sobre el que se va a generar el informe.\n# Crea un informe de usuario basándote en las 5 métricas que tú quieras, utilizando la información que te proporciona GitHub. Por ejemplo:\n    # Lenguaje más utilizado\n    # Cantidad de repositorios\n    # Seguidores/Seguidos\n    # Stars/forks\n    # Contribuciones\n\n\nimport requests\nfrom datetime import datetime\n\ndef generate_github_report(username: str):\n    \n    base_url = \"https://api.github.com\"\n    \n    # Get user data\n    user_url = f\"{base_url}/users/{username}\"\n    response = requests.get(user_url)\n    \n    if response.status_code != 200:\n        print(f\"Error: No se pudo obtener información para el usuario {username}. Código: {response.status_code}\")\n        return\n        \n    user_data = response.json()\n    \n    # Get repositories data\n    repos_url = f\"{base_url}/users/{username}/repos\"\n    repos_response = requests.get(repos_url)\n    \n    if repos_response.status_code != 200:\n        print(f\"Error: No se pudo obtener los repositorios para {username}\")\n        repos = []\n    else:\n        repos = repos_response.json()\n    \n    # Basic user info\n    name = user_data.get(\"name\") or username\n    company = user_data.get(\"company\") or \"No especificado\"\n    location = user_data.get(\"location\") or \"No especificado\"\n    bio = user_data.get(\"bio\") or \"Sin biografía\"\n    followers = user_data.get(\"followers\", 0)\n    following = user_data.get(\"following\", 0)\n    created_at = user_data.get(\"created_at\")\n    updated_at = user_data.get(\"updated_at\")  # Fixed typo here\n    public_repos = user_data.get(\"public_repos\", 0)\n    \n    # Format dates\n    if created_at:\n        created_at = datetime.strptime(created_at, \"%Y-%m-%dT%H:%M:%SZ\").strftime(\"%d/%m/%Y\")\n    if updated_at:\n        updated_at = datetime.strptime(updated_at, \"%Y-%m-%dT%H:%M:%SZ\").strftime(\"%d/%m/%Y\")\n    \n    # Calculate metrics\n    languages = {}\n    total_stars = 0\n    total_forks = 0\n    \n    for repo in repos:\n        # Count stars and forks\n        total_stars += repo.get(\"stargazers_count\", 0)\n        total_forks += repo.get(\"forks_count\", 0)\n        \n        # Count languages\n        language = repo.get(\"language\")\n        if language:\n            languages[language] = languages.get(language, 0) + 1\n    \n    # Find most used language\n    most_used_language = max(languages, key=languages.get) if languages else \"No disponible\"\n    \n    # Print the report\n    print(\"\\n\" + \"=\" * 50)\n    print(f\"REPORTE DE GITHUB PARA: {name}\")\n    print(\"=\" * 50)\n    print(f\"Trabaja en: {company}\")\n    print(f\"Vive en: {location}\")\n    print(f\"Bio: {bio}\")\n    print(\"\\n--- MÉTRICAS ---\")\n    print(f\"1. Repositorios públicos: {public_repos}\")\n    print(f\"2. Lenguaje más utilizado: {most_used_language}\")\n    print(f\"3. Seguidores/Seguidos: {followers}/{following}\")\n    print(f\"4. Stars/Forks totales: {total_stars}/{total_forks}\")\n    print(f\"5. Perfil creado el: {created_at}\")\n    print(f\"Última actualización: {updated_at}\")\n    print(\"=\" * 50)\n\n# Main program\nusername = input(\"Ingresa el username del usuario que deseas consultar en GitHub: \")\ngenerate_github_report(username)"
  },
  {
    "path": "Roadmap/45 - GITHUB OCTOVERSE/python/ignaciovihe.py",
    "content": "\"\"\"\n * EJERCICIO:\n * GitHub ha publicado el Octoverse 2024, el informe\n * anual del estado de la plataforma:\n * https://octoverse.github.com\n *\n * Utilizando el API de GitHub, crea un informe asociado\n * a un usuario concreto.\n * \n * - Se debe poder definir el nombre del usuario\n *   sobre el que se va a generar el informe.\n *   \n * - Crea un informe de usuario basándote en las 5 métricas\n *   que tú quieras, utilizando la información que te\n *   proporciona GitHub. Por ejemplo:\n *   - Lenguaje más utilizado\n *   - Cantidad de repositorios\n *   - Seguidores/Seguidos\n *   - Stars/forks\n *   - Contribuciones\n *   (lo que se te ocurra)\n\"\"\"\n\nimport requests\nimport json\n\n\n\nname = input(\"Introduce el nombre del usuario de GitHub que quieres consultar: \")\nurl = \"https://api.github.com/users/\" + name\n\nanswer = requests.get(url)\nif answer.status_code == 200:\n    user_data = answer.json()\n    #print(json.dumps(user_data, indent=4))\n\n    print(f\"Nombre de usuario: {user_data[\"login\"]}\")\n    print(f\"Compañia: {user_data[\"company\"]}\")\n    print(f\"Repositorios públicos: {user_data[\"public_repos\"]}\")\n    print(f\"Gits públicos: {user_data[\"public_gists\"]}\")\n    print(f\"Seguidores: {user_data[\"followers\"]}\")\n    print(f\"Seguidos: {user_data[\"following\"]}\")\n\n    most_used_languages = dict()\n    repos_url = user_data[\"repos_url\"]\n\n    answer = requests.get(repos_url)\n    if answer.status_code == 200:\n        repos_data = answer.json()\n        #print(json.dumps(repos_data, indent=4))\n\n        for repo in repos_data:\n            print(f\"Nombre del repositorio: {repo[\"full_name\"]}\")\n            print(f\"\\tEstrellas: {repo[\"stargazers_count\"]}\")\n            print(f\"\\tForks: {repo[\"forks_count\"]}\")\n            \n            if not repo[\"fork\"]:\n                languages_url = repo[\"languages_url\"]\n                answer = requests.get(languages_url)\n                if answer.status_code == 200:\n                    languages_data = answer.json()\n                    #print(json.dumps(languages_data, indent=4))\n                    print(f\"\\tLenguages utilizados:\")\n                    for language, bytes in languages_data.items():\n                        print(f\"\\t\\t-{language} - {bytes} bytes.\")\n                        if language in most_used_languages:\n                            most_used_languages[language] += bytes\n                        else:\n                            most_used_languages[language] = bytes\n                else:\n                    print(\"Hubo un problema al obtener los lenguajes del repositorio.\")\n    else:\n        print(\"Problemas al obtener los repositorios del usuario.\")\n    most_used_languages_sorted = dict(sorted(most_used_languages.items(), key=lambda item: item[1], reverse=True))\n    print(f\"Lenguages mas utilizados:\")\n    for index , (lg, bytes) in enumerate(most_used_languages_sorted.items()):\n        print(f\"{index + 1}.- {lg}: {bytes} bytes\")\n\nelse:\n    print(f\"Hubo un problema al obtener la info del usuario\")\n\n\n\n"
  },
  {
    "path": "Roadmap/45 - GITHUB OCTOVERSE/python/kenysdev.py",
    "content": "# _____________________________________\n# https://github.com/kenysdev\n# 2024 - Python\n# _____________________________________\n# 45 GITHUB OCTOVERSE\n# ------------------------------------\n\n\"\"\"\n * EJERCICIO:\n * GitHub ha publicado el Octoverse 2024, el informe\n * anual del estado de la plataforma:\n * https://octoverse.github.com\n *\n * Utilizando el API de GitHub, crea un informe asociado\n * a un usuario concreto.\n * \n * - Se debe poder definir el nombre del usuario\n *   sobre el que se va a generar el informe.\n *   \n * - Crea un informe de usuario basándote en las 5 métricas\n *   que tú quieras, utilizando la informración que te\n *   proporciona GitHub. Por ejemplo:\n *   - Lenguaje más utilizado\n *   - Cantidad de repositorios\n *   - Seguidores/Seguidos\n *   - Stars/forks\n *   - Contribuciones\n *   (lo que se te ocurra)\n\"\"\"\n\nimport requests\nfrom collections import Counter\nimport textwrap\n\nclass GitHubApi:\n    def __init__(self, user_name: str) -> None:\n        # El límite es de 60 solicitudes por hora\n        url: str = f\"https://api.github.com/users/{user_name}\"\n        self.__user_data: dict = self.__get_json(url)\n\n    def __get_json(self, url: str) -> dict:\n        try:\n            user_data: dict = requests.get(url).json()\n            return user_data\n        except requests.exceptions.RequestException as err:\n            print(f\"Error: {err}\")\n            return {}\n\n    def __verify_status(self) -> bool:\n        if self.__user_data.get(\"status\") == \"404\":\n            print(f\"Usuario '{user_name}' no encontrado.\")\n            return False\n        return True\n\n    def __get_repo_info(self, dt: dict) -> str:\n        return textwrap.dedent(f\"\"\"\n            Lang:  {dt.get(\"full_name\", \"Desconocido\")}\")\n            Repo:  {dt.get(\"language\")}\")\n            Stars: {dt.get(\"stargazers_count\", 0)}\")\n            Forks: {dt.get(\"forks_count\", 0)}\")\"\"\"\n        )\n\n    def print_basic_info(self) -> None:\n        if not self.__verify_status:\n            return\n\n        dt: dict = self.__user_data\n        print(textwrap.dedent(f\"\"\"\n            -------------------------------------------\n            Nombre:     {dt.get(\"name\", \"Desconocido\")}\n            Creación:   {dt.get(\"created_at\", \"Desconocido\")}\n            Repos:      {dt.get(\"public_repos\", 0)}\n            Gists:      {dt.get(\"public_gists\", 0)}\n            Seguidores: {dt.get(\"followers\", 0)}\n            Seguidos:   {dt.get(\"following\", 0)}\n            -------------------------------------------\"\"\"\n        ))\n\n    def print_repos_info(self):\n        if not self.__verify_status:\n            return\n        \n        url: str = self.__user_data.get(\"repos_url\", \"None\")\n        repos_data = self.__get_json(url)\n        languages = Counter()\n\n        print(\"Repositorios publicos:\")\n        for repo in repos_data:\n            language = repo.get(\"language\")\n            print(self.__get_repo_info(repo))\n            if language:\n                languages[language] += 1\n        \n        most_c, count = languages.most_common(1)[0]\n        print(f\"________\\nTotal de repositorios: '{len(repos_data)}'\")\n        print(f\"El lenguaje más utilizado: '{most_c}'({count})\")\n\nif __name__ == \"__main__\":\n    print(\"Informe sobre los datos del usuario en GitHub\")\n    user_name: str = input(\"Usuario: \")\n    github = GitHubApi(user_name)\n    github.print_repos_info()\n    github.print_basic_info()\n"
  },
  {
    "path": "Roadmap/45 - GITHUB OCTOVERSE/python/ljoecordoba.py",
    "content": "import requests\nfrom collections import Counter\n\ndef get_user_info(username):\n    # URL base de GitHub API\n    base_url = \"https://api.github.com/users\"\n    # Obtener información del usuario\n    user_url = f\"{base_url}/{username}\"\n    user_data = requests.get(user_url).json()\n\n    # Obtener la lista de repositorios del usuario\n    repos_url = f\"{base_url}/{username}/repos\"\n    repos_data = requests.get(repos_url).json()\n\n    # Métricas a recolectar\n    total_repos = user_data.get(\"public_repos\", 0)\n    followers = user_data.get(\"followers\", 0)\n    following = user_data.get(\"following\", 0)\n\n    # 1. Lenguaje más utilizado\n    languages = [repo.get(\"language\") for repo in repos_data if repo.get(\"language\")]\n    most_common_language = Counter(languages).most_common(1)[0][0] if languages else \"No disponible\"\n\n    # 2. Repositorio con más estrellas\n    top_starred_repo = max(repos_data, key=lambda x: x.get(\"stargazers_count\", 0), default=None)\n    top_repo_name = top_starred_repo.get(\"name\") if top_starred_repo else \"No disponible\"\n    top_repo_stars = top_starred_repo.get(\"stargazers_count\", 0) if top_starred_repo else 0\n\n    # 3. Última fecha de contribución\n    recent_commit_url = f\"https://api.github.com/users/{username}/events\"\n    recent_events = requests.get(recent_commit_url).json()\n    push_events = [event for event in recent_events if event[\"type\"] == \"PushEvent\"]\n    last_contribution_date = push_events[0][\"created_at\"] if push_events else \"No disponible\"\n\n    # Generar informe\n    report = {\n        \"Usuario\": username,\n        \"Repositorios públicos\": total_repos,\n        \"Seguidores\": followers,\n        \"Seguidos\": following,\n        \"Lenguaje más utilizado\": most_common_language,\n        \"Repositorio más popular\": {\n            \"Nombre\": top_repo_name,\n            \"Estrellas\": top_repo_stars,\n        },\n        \"Última fecha de contribución\": last_contribution_date,\n    }\n\n    return report\n\n# Solicitar el nombre de usuario y generar el informe\nusername = input(\"Introduce el nombre de usuario de GitHub: \")\nuser_report = get_user_info(username)\n\n# Imprimir el informe de usuario\nfor key, value in user_report.items():\n    if isinstance(value, dict):\n        print(f\"{key}:\")\n        for sub_key, sub_value in value.items():\n            print(f\"  {sub_key}: {sub_value}\")\n    else:\n        print(f\"{key}: {value}\")\n"
  },
  {
    "path": "Roadmap/45 - GITHUB OCTOVERSE/python/mhayhem.py",
    "content": "# @Author Daniel Grande (Mhayhem)\n\n# EJERCICIO:\n# GitHub ha publicado el Octoverse 2024, el informe\n# anual del estado de la plataforma:\n# https://octoverse.github.com\n#\n# Utilizando el API de GitHub, crea un informe asociado\n# a un usuario concreto.\n# \n# - Se debe poder definir el nombre del usuario\n#   sobre el que se va a generar el informe.\n#   \n# - Crea un informe de usuario basándote en las 5 métricas\n#   que tú quieras, utilizando la información que te\n#   proporciona GitHub. Por ejemplo:\n#   - Lenguaje más utilizado\n#   - Cantidad de repositorios\n#   - Seguidores/Seguidos\n#   - Stars/forks\n#   - Contribuciones\n#   (lo que se te ocurra)\n\nimport requests\nimport json\nimport dotenv\nimport os\n\ndotenv.load_dotenv()\n\ndef get_user_info():\n    username = input(\"Nombre de usuario: \")\n    token = os.getenv('TOKEN')\n    url = f\"https://api.github.com/users/{username}\"\n    \n    if not token:\n        print(\"No se ha encontrado ningún token\")\n    \n    headers = {\"Authorization\": f\"Bearer {token}\",\n            \"Accept\": \"application/vnd.github+json\"}\n    \n    count_language = {}\n    \n    response = requests.get(url, headers=headers)\n    if response.status_code == 200:\n        data = response.json()\n        languages_dev = requests.get(url + \"/repos\", headers=headers)\n        language_data = languages_dev.json()\n        for item in language_data:\n            if item[\"language\"] != None:\n                if item[\"language\"] not in count_language:\n                    count_language.setdefault(item[\"language\"], 1)\n                else:\n                    count_language[item[\"language\"]] += 1\n        \n        if count_language:\n            favorite_language = max(count_language, key=count_language.get)\n        else:\n            favorite_language = \"Ninguno\"\n        \n        print(f\"Nombre: {data['name']}\\n\"\n            f\"Repos publicos: {data['public_repos']}\\n\"\n            f\"Seguidores: {data['followers']}\\n\"\n            f\"Siguiendo: {data['following']}\\n\"\n            f\"Lenguaje mas utilizado: {favorite_language}\"\n            )\n    \n    elif response.status_code == 404:\n        print(f\"Usuario {username} no encontrado.\")\n    elif response.status_code == 401:\n        print(\"Token invalido\")\n    else:\n        print(f\"ERROR: {response.status_code}\")\n    \n    \n\nget_user_info()\n\n"
  },
  {
    "path": "Roadmap/45 - GITHUB OCTOVERSE/python/miguelex.py",
    "content": "import requests\n\nclass GitHubUserReport:\n    def __init__(self, username: str):\n        self.username = username\n        self.base_api_url = \"https://api.github.com\"\n        self.headers = {\n            \"User-Agent\": \"GitHub-Report-App\",\n            \"Accept\": \"application/vnd.github.v3+json\"\n        }\n\n    def api_request(self, endpoint: str):\n        url = f\"{self.base_api_url}{endpoint}\"\n        response = requests.get(url, headers=self.headers)\n\n        if response.status_code != 200:\n            raise Exception(f\"Error al conectar con la API de GitHub (HTTP {response.status_code}). Verifica el nombre de usuario.\")\n\n        return response.json()\n\n    def get_user_info(self):\n        return self.api_request(f\"/users/{self.username}\")\n\n    def get_user_repos(self):\n        return self.api_request(f\"/users/{self.username}/repos\")\n\n    def generate_report(self):\n        try:\n            user_info = self.get_user_info()\n            repos = self.get_user_repos()\n\n            total_repos = len(repos)\n            followers = user_info.get(\"followers\", 0)\n            following = user_info.get(\"following\", 0)\n\n            languages = [repo[\"language\"] for repo in repos if repo[\"language\"]]\n            language_counts = {}\n            for lang in languages:\n                language_counts[lang] = language_counts.get(lang, 0) + 1\n\n            top_language = max(language_counts, key=language_counts.get, default=\"N/A\")\n\n            total_stars = sum(repo.get(\"stargazers_count\", 0) for repo in repos)\n            total_forks = sum(repo.get(\"forks_count\", 0) for repo in repos)\n\n            print(f\"=== Informe de GitHub para el usuario: {self.username} ===\")\n            print(f\"Nombre: {user_info.get('name', 'N/A')}\")\n            print(f\"Bio: {user_info.get('bio', 'N/A')}\")\n            print(f\"Ubicación: {user_info.get('location', 'N/A')}\")\n            print(f\"Total de repositorios: {total_repos}\")\n            print(f\"Seguidores: {followers}\")\n            print(f\"Seguidos: {following}\")\n            print(f\"Lenguaje más utilizado: {top_language}\")\n            print(f\"Total de estrellas: {total_stars}\")\n            print(f\"Total de forks: {total_forks}\")\n\n        except Exception as e:\n            print(f\"Error: {e}\")\n\nif __name__ == \"__main__\":\n    username = input(\"Ingrese el nombre de usuario de GitHub: \").strip()\n\n    if not username:\n        print(\"Debe ingresar un nombre de usuario.\")\n    else:\n        report = GitHubUserReport(username)\n        report.generate_report()\n"
  },
  {
    "path": "Roadmap/45 - GITHUB OCTOVERSE/python/mouredev.py",
    "content": "import requests\n\n\ndef generate_github_report(username: str):\n\n    base_url = \"https://api.github.com\"\n\n    user_url = f\"{base_url}/users/{username}\"\n    user_data = requests.get(user_url).json()\n\n    if \"status\" in user_data and user_data[\"status\"] == \"404\":\n        print(f\"Usuario {username} no encontrado.\")\n        return\n\n    report = {\n        \"Nombre\": user_data.get(\"name\", \"Desconocido\"),\n        \"Compañía\": user_data.get(\"company\", \"Desconocida\"),\n        \"Repositorios públicos\": user_data.get(\"public_repos\", 0),\n        \"Gists\": user_data.get(\"public_gists\", 0),\n        \"Seguidores\": user_data.get(\"followers\", 0),\n        \"Seguidos\": user_data.get(\"following\", 0)\n    }\n\n    print(f\"Informe para el usuario: {username}.\")\n    for key, value in report.items():\n        print(f\"{key}: {value}\")\n\n    repos_url = user_data[\"repos_url\"]\n    repos_data = requests.get(repos_url).json()\n\n    languages = {}\n\n    for repo in repos_data:\n\n        language = repo.get(\"language\")\n        if language:\n            if language in languages:\n                languages[language] += 1\n            else:\n                languages[language] = 1\n\n        print(f\"\\nRepo: {repo.get(\"full_name\")}\")\n        print(f\"Stars: {repo.get(\"stargazers_count\", 0)}\")\n        print(f\"Forks: {repo.get(\"forks_count\", 0)}\")\n\n    most_used_language = None\n    max_count = 0\n    for language_name, language_count in languages.items():\n        if language_count > max_count:\n            most_used_language = language_name\n            max_count = language_count\n\n    print(\n        f\"\\nLenguaje más usado: {\n            most_used_language if most_used_language else \"Desconocido\"}\"\n    )\n\n\nusername = input(\"Introduce el nombre de usuario de GitHub: \")\ngenerate_github_report(username)\n"
  },
  {
    "path": "Roadmap/45 - GITHUB OCTOVERSE/python/neslarra.py",
    "content": "r\"\"\"\n EJERCICIO:\n GitHub ha publicado el Octoverse 2024, el informe\n anual del estado de la plataforma:\n https://octoverse.github.com\n\n Utilizando el API de GitHub, crea un informe asociado\n a un usuario concreto.\n \n - Se debe poder definir el nombre del usuario\n   sobre el que se va a generar el informe.\n   \n - Crea un informe de usuario basándote en las 5 métricas\n   que tú quieras, utilizando la informración que te\n   proporciona GitHub. Por ejemplo:\n   - Lenguaje más utilizado\n   - Cantidad de repositorios\n   - Seguidores/Seguidos\n   - Stars/forks\n   - Contribuciones\n   (lo que se te ocurra)\n\"\"\"\nimport requests\n\n\nURL_BASE = \"https://api.github.com/users/\"\n\n\ndef get_github_data(url: str) -> dict:\n    response = requests.request(\"GET\", url)\n    if response.status_code != 200:\n        return {}\n    return response.json()\n\n\ndef menu(options: list) -> str:\n    while True:\n        print(\"\\nSeleccionar métrica:\\n\")\n        for ind, opt in enumerate(options):\n            print(f\"\\t{ind + 1} - {opt}\")\n        print(\"\\t0 - Salir\\n\")\n        option = input(f\"\\tOpción# [0-{metrics.__len__()}] => \")\n        if option.isnumeric() and 0 <= int(option) < metrics.__len__():\n            return \"\" if option == \"0\" else metrics[int(option) - 1]\n\n\nusername = input(\"Usuario: \")\ndata = get_github_data(URL_BASE + username)\nmetrics = []\nif data:\n    for k, v in data.items():\n        if v:\n            metrics.append(k)\n    while True:\n        metric = menu(metrics)\n        if not metric:\n            quit()\n        if data[metric].__class__.__name__ == \"str\" and data[metric].startswith(\"http\"):\n            try:\n                new_data = get_github_data(data[metric])\n            except requests.exceptions.JSONDecodeError:\n                new_data = {}\n            if new_data:\n                print(f\"{metric}:\")\n                print(f\"\\t{new_data}\")\n            else:\n                print(f\"{metric}: acceda manualmente a {data[metric]}\")\n        else:\n            print(f\"{metric}: {data[metric]}\")\n        _ = input(\"\\nPresiones ENTER para continuar...\")\nprint(f\"No se obtuvieron datos para {username}\")\n"
  },
  {
    "path": "Roadmap/45 - GITHUB OCTOVERSE/python/pyramsd.py",
    "content": "import requests, asyncio, aiohttp\n\nbase_url = \"https://api.github.com\"\nuser = input(\"Github user: \")\n\nasync def get_data(url, session):\n    async with session.get(url) as response:\n        return await response.json()\n\n\nasync def tareas():\n    async with aiohttp.ClientSession() as session:\n        followers_users = [follower[\"login\"] for follower in await get_data(f\"{base_url}/users/{user}/followers\", session)]\n        following_users = [follower[\"login\"] for follower in await get_data(f\"{base_url}/users/{user}/following\", session)]\n        starreds = [starred[\"full_name\"] for starred in await get_data(f\"{base_url}/users/{user}/starred\", session)]\n        user_repos = [repos[\"name\"] for repos in await get_data(f\"{base_url}/users/{user}/repos\", session)]\n        user_repos_forks = [(repos[\"name\"], repos[\"fork\"]) for repos in await get_data(f\"{base_url}/users/{user}/repos\", session) if repos[\"fork\"] == True]\n        return followers_users, following_users, starreds, user_repos, user_repos_forks\n\n\nasync def main():\n    followers_users, following_users, starreds, user_repos, user_repos_forks = await tareas()\n    print(\"Seguidores:\", ', '.join(i for i in followers_users))\n    print(\"Usuarios que sigue:\", ', '.join(i for i in following_users))\n    print(\"Repositorios favoritos: \", ', '.join(i for i in starreds))\n    print(\"Repositorios públicos:\", ', '.join(i for i in user_repos))\n    print(\"Repositorios forkeados:\", ', '.join(i[0] for i in user_repos_forks))\n\nasyncio.run(main())\n"
  },
  {
    "path": "Roadmap/45 - GITHUB OCTOVERSE/python/raulG91.py",
    "content": "import requests\nimport json\nfrom collections import Counter\n\nTOKEN = \"YOUR TOKEN\"\n\ndef getFollowers(user):\n    header =  {\n        \"Authorization\": f'Bearer {TOKEN}',\n        \"Accept\": \"application/vnd.github+json\"\n    }\n    try:\n        result = requests.get(f'https://api.github.com/users/{user}/followers',headers=header)\n        if result.status_code>=200 and result.status_code<=299:\n            followers = json.loads(result.text)\n            return len(followers)\n        else:\n            print(\"Error getting user followers with code\", result.status_code)\n            return 0\n    except Exception as e:\n        print(\"Error getting user followers \", e)    \n\ndef getFollowing(user):\n    header = {\n        \"Authorization\": f'Bearer {TOKEN}',\n        \"Accept\": \"application/vnd.github+json\"\n    }\n    try:\n        result = requests.get(f'https://api.github.com/users/{user}/following',headers=header)\n        if result.status_code>=200 and result.status_code<=299:\n            following = json.loads(result.text)\n            return len(following)\n        else:\n            print(\"Error getting user followings with code\", result.status_code)\n            return 0\n    except Exception as e:\n        print(\"Error getting user followings \", e)   \ndef getNumberRepos(user):\n    header = {\n        \"Authorization\": f'Bearer {TOKEN}',\n        \"Accept\": \"application/vnd.github+json\"\n    }\n    try:\n        result = requests.get(f'https://api.github.com/users/{user}/repos',headers=header)\n        if result.status_code>=200 and result.status_code<=299:\n            repos = json.loads(result.text)\n            return len(repos)\n        else:\n            print(\"Error getting user repositories with code\", result.status_code)\n            return 0\n    except Exception as e:\n        print(\"Error getting user repositories \", e)  \n\ndef getPullRequests(user):\n    header = {\n        \"Authorization\": f'Bearer {TOKEN}',\n        \"Accept\": \"application/vnd.github+json\"\n    }\n    try:\n        result = requests.get(f'https://api.github.com/users/{user}/events',headers=header)\n        if result.status_code>=200 and result.status_code<=299:\n            events_array = json.loads(result.text)\n            pull_request =  [event for event in events_array if event[\"type\"] == 'PullRequestEvent']\n            return len(pull_request)\n        else:\n            print(\"Error getting user events with code\", result.status_code)\n            return 0\n    except Exception as e:\n        print(\"Error getting user events \", e)   \ndef getLanguage(user):\n    languages = []\n    header = {\n        \"Authorization\": f'Bearer {TOKEN}',\n        \"Accept\": \"application/vnd.github+json\"\n    }\n    try:\n        result = requests.get(f'https://api.github.com/users/{user}/repos',headers=header)\n        if result.status_code>=200 and result.status_code<=299:\n            repos = json.loads(result.text)\n            for repo in repos:\n                if repo[\"language\"] != None:\n                    languages.append(repo[\"language\"])\n            #Get the most used language        \n            counter = Counter(languages)\n            return counter.most_common(1)[0][0]\n\n        else:\n            print(\"Error getting user repositories with code\", result.status_code)\n            return 0\n    except Exception as e:\n        print(\"Error getting user repositories \", e)                     \n\nuser = input(\"Insert user to get information \")\n\nprint(\"Followers user :\",getFollowers(user))\nprint(\"Following user \",getFollowing(user))\nprint(\"Repositories for user: \",getNumberRepos(user))\nprint(\"Number pull request: \",getPullRequests(user))\nprint(\"Most used languge is: \",getLanguage(user))"
  },
  {
    "path": "Roadmap/45 - GITHUB OCTOVERSE/python/rigo93acosta.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * GitHub ha publicado el Octoverse 2024, el informe\n * anual del estado de la plataforma:\n * https://octoverse.github.com\n *\n * Utilizando el API de GitHub, crea un informe asociado\n * a un usuario concreto.\n * \n * - Se debe poder definir el nombre del usuario\n *   sobre el que se va a generar el informe.\n *   \n * - Crea un informe de usuario basándote en las 5 métricas\n *   que tú quieras, utilizando la informración que te\n *   proporciona GitHub. Por ejemplo:\n *   - Lenguaje más utilizado\n *   - Cantidad de repositorios\n *   - Seguidores/Seguidos\n *   - Stars/forks\n *   - Contribuciones\n *   (lo que se te ocurra)\n */\n\"\"\"\n\nimport requests\nfrom collections import defaultdict\n\nbase_url = \"https://api.github.com/users/\"\n\ndef get_user_info(username):\n    \n    user_data = requests.get(base_url + username).json()\n    \n    if \"status\" in user_data and user_data[\"status\"] == \"404\":\n        return None\n    else:\n        return user_data\n\ndef get_info_basic(data):\n\n    print(f\"Name: {data.get('name', 'No name')}\")\n    print(f\"Company: {data.get('company', 'No company')}\")\n    print(f\"Total de repos: {data.get('public_repos', 0)}\")\n    print(f\"Followers: {data.get('followers', 0)}\")\n    print(f\"Following: {data.get('following', 0)}\")\n\ndef get_info_repos(repos_url):\n    ## Esta peticion se puede paginar si el usuario \n    ## tiene muchos repositorios\n    repos_data = requests.get(repos_url).json()\n    my_langauges = defaultdict(int)\n\n    for repo in repos_data:\n        lang = repo.get(\"language\", \"No language\")\n        my_langauges[lang] += 1\n        print(f'\\nRepo: {repo.get(\"full_name\", \"No name\")}')\n        print(f'Stars: {repo.get(\"stargazers_count\", 0)}')\n        print(f'Forks: {repo.get(\"forks_count\", 0)}')\n\n    most_lang = sorted(my_langauges.items(), \n                       key=lambda x: x[1], \n                       reverse=True)[0][0]\n    \n    print(f\"\\nLenguajes utilizados: {most_lang}\")\nif __name__ == \"__main__\":\n\n    username = input(\"Introduce el nombre de usuario de GitHub: \")\n    user_info = get_user_info(username)\n\n    if user_info != None:\n        print(f\"Informe para el usuario: {username}\")\n        get_info_basic(user_info)\n        repos_url = user_info[\"repos_url\"]\n        get_info_repos(repos_url)\n\n    else:\n        print(f\"El usuario {username} no existe\")"
  },
  {
    "path": "Roadmap/45 - GITHUB OCTOVERSE/rust/kenysdev.rs",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - Rust\n_____________________________________\n45 GITHUB OCTOVERSE\n------------------------------------\n\n * EJERCICIO:\n * GitHub ha publicado el Octoverse 2024, el informe\n * anual del estado de la plataforma:\n * https://octoverse.github.com\n *\n * Utilizando el API de GitHub, crea un informe asociado\n * a un usuario concreto.\n * \n * - Se debe poder definir el nombre del usuario\n *   sobre el que se va a generar el informe.\n *   \n * - Crea un informe de usuario basándote en las 5 métricas\n *   que tú quieras, utilizando la informración que te\n *   proporciona GitHub. Por ejemplo:\n *   - Lenguaje más utilizado\n *   - Cantidad de repositorios\n *   - Seguidores/Seguidos\n *   - Stars/forks\n *   - Contribuciones\n *   (lo que se te ocurra)\n*/\n\nuse std::collections::HashMap;\nuse reqwest;\nuse serde_json::Value;\nuse std::error::Error;\n\nstruct GitHubApi {\n    user_data: HashMap<String, Value>,\n}\n\nimpl GitHubApi {\n    async fn new(user_name: &str) -> Result<Self, Box<dyn Error>> {\n        let url = format!(\"https://api.github.com/users/{}\", user_name);\n        let client = reqwest::Client::new();\n        let user_data: HashMap<String, Value> = client.get(&url)\n            .header(\"User-Agent\", \"Mozilla/5.0\")\n            .send()\n            .await?\n            .json()\n            .await?;\n\n        Ok(Self { user_data })\n    }\n\n    fn verify_status(&self) -> bool {\n        match self.user_data.get(\"status\") {\n            Some(status) if status.as_str() == Some(\"404\") => {\n                println!(\"Usuario no encontrado.\");\n                false\n            }\n            _ => true\n        }\n    }\n\n    fn get_repo_info(repo: &Value) -> String {\n        format!(\n            \"Lang: {}\\nRepo: {}\\nStars: {}\\nForks: {}\",\n            repo.get(\"full_name\").and_then(|v| v.as_str()).unwrap_or(\"Desconocido\"),\n            repo.get(\"language\").and_then(|v| v.as_str()).unwrap_or(\"Desconocido\"),\n            repo.get(\"stargazers_count\").and_then(|v| v.as_u64()).unwrap_or(0),\n            repo.get(\"forks_count\").and_then(|v| v.as_u64()).unwrap_or(0)\n        )\n    }\n\n    fn print_basic_info(&self) {\n        if !self.verify_status() { return; }\n\n        println!(\n            \"-------------------------------------------\\n\\\n            Nombre: {}\\n\\\n            Creación: {}\\n\\\n            Repos: {}\\n\\\n            Gists: {}\\n\\\n            Seguidores: {}\\n\\\n            Seguidos: {}\\n\\\n            -------------------------------------------\",\n            self.user_data.get(\"name\").and_then(|v| v.as_str()).unwrap_or(\"Desconocido\"),\n            self.user_data.get(\"created_at\").and_then(|v| v.as_str()).unwrap_or(\"Desconocido\"),\n            self.user_data.get(\"public_repos\").and_then(|v| v.as_u64()).unwrap_or(0),\n            self.user_data.get(\"public_gists\").and_then(|v| v.as_u64()).unwrap_or(0),\n            self.user_data.get(\"followers\").and_then(|v| v.as_u64()).unwrap_or(0),\n            self.user_data.get(\"following\").and_then(|v| v.as_u64()).unwrap_or(0)\n        );\n    }\n\n    async fn print_repos_info(&self) -> Result<(), Box<dyn Error>> {\n        if !self.verify_status() { return Ok(()); }\n\n        if let Some(repos_url) = self.user_data.get(\"repos_url\").and_then(|v| v.as_str()) {\n            let client = reqwest::Client::new();\n            let repos: Vec<Value> = client.get(repos_url)\n                .header(\"User-Agent\", \"Mozilla/5.0\")\n                .send()\n                .await?\n                .json()\n                .await?;\n\n            let mut languages: HashMap<String, u32> = HashMap::new();\n            println!(\"Repositorios publicos:\");\n\n            for repo in &repos {\n                println!(\"\\n{}\", Self::get_repo_info(repo));\n\n                if let Some(language) = repo.get(\"language\").and_then(|v| v.as_str()) {\n                    *languages.entry(language.to_string()).or_insert(0) += 1;\n                }\n            }\n\n            let most_used_lang = languages.iter()\n                .max_by_key(|&(_, count)| *count)\n                .map(|(lang, count)| (lang, *count));\n\n            println!(\"________\\nTotal de repositorios: '{}'\", repos.len());\n            if let Some((lang, count)) = most_used_lang {\n                println!(\"El lenguaje más utilizado: '{}' ({})\", lang, count);\n            }\n        }\n\n        Ok(())\n    }\n}\n\n#[tokio::main]\nasync fn main() -> Result<(), Box<dyn Error>> {\n    println!(\"Informe sobre los datos del usuario en GitHub\");\n    print!(\"Usuario: \");\n    \n    use std::io::{self, Write};\n    io::stdout().flush()?;\n\n    let mut user_name = String::new();\n    io::stdin().read_line(&mut user_name)?;\n    let user_name = user_name.trim();\n\n    let github = GitHubApi::new(user_name).await?;\n    github.print_repos_info().await?;\n    github.print_basic_info();\n\n    Ok(())\n}\n"
  },
  {
    "path": "Roadmap/45 - GITHUB OCTOVERSE/sql/Nicojsuarez2.sql",
    "content": "# #45 GITHUB OCTOVERSE\n> #### Dificultad: Media | Publicación: 11/11/24 | Corrección: 18/11/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * GitHub ha publicado el Octoverse 2024, el informe\n * anual del estado de la plataforma:\n * https://octoverse.github.com\n *\n * Utilizando el API de GitHub, crea un informe asociado\n * a un usuario concreto.\n * \n * - Se debe poder definir el nombre del usuario\n *   sobre el que se va a generar el informe.\n *   \n * - Crea un informe de usuario basándote en las 5 métricas\n *   que tú quieras, utilizando la información que te\n *   proporciona GitHub. Por ejemplo:\n *   - Lenguaje más utilizado\n *   - Cantidad de repositorios\n *   - Seguidores/Seguidos\n *   - Stars/forks\n *   - Contribuciones\n *   (lo que se te ocurra)\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/45 - GITHUB OCTOVERSE/typescript/hozlucas28.ts",
    "content": "import readline from 'node:readline/promises'\n\n/* -------------------------------------------------------------------------- */\n/*                                    TYPES                                   */\n/* -------------------------------------------------------------------------- */\n\ninterface GitHubAPI {\n    user: {\n        avatar_url: string\n        bio: string\n        blog: string\n        company?: string\n        created_at: string\n        email?: string\n        events_url: string\n        followers_url: string\n        followers: number\n        following_url: string\n        following: number\n        gists_url: string\n        gravatar_id: string\n        hireable: true\n        html_url: string\n        id: number\n        location: string\n        login: string\n        name: string\n        node_id: string\n        organizations_url: string\n        public_gists: number\n        public_repos: number\n        received_events_url: string\n        repos_url: string\n        site_admin: boolean\n        starred_url: string\n        subscriptions_url: string\n        twitter_username: string\n        type: string\n        updated_at: string\n        url: string\n        user_view_type: string\n\n        public_repos_data: {\n            allow_forking: boolean\n            archive_url: string\n            archived: boolean\n            assignees_url: string\n            blobs_url: string\n            branches_url: string\n            clone_url: string\n            collaborators_url: string\n            comments_url: string\n            commits_url: string\n            compare_url: string\n            contents_url: string\n            contributors_url: string\n            created_at: string\n            default_branch: string\n            deployments_url: string\n            description: string\n            disabled: boolean\n            downloads_url: string\n            events_url: string\n            fork: boolean\n            forks_count: number\n            forks_url: string\n            forks: number\n            full_name: string\n            git_commits_url: string\n            git_refs_url: string\n            git_tags_url: string\n            git_url: string\n            has_discussions: boolean\n            has_downloads: boolean\n            has_issues: boolean\n            has_pages: boolean\n            has_projects: boolean\n            has_wiki: boolean\n            homepage: string\n            hooks_url: string\n            html_url: string\n            id: number\n            is_template: boolean\n            issue_comment_url: string\n            issue_events_url: string\n            issues_url: string\n            keys_url: string\n            labels_url: string\n            language: string\n            languages_url: string\n            merges_url: string\n            milestones_url: string\n            mirror_url?: string\n            name: string\n            node_id: string\n            notifications_url: string\n            open_issues_count: number\n            open_issues: number\n            private: boolean\n            pulls_url: string\n            pushed_at: string\n            releases_url: string\n            size: number\n            ssh_url: string\n            stargazers_count: number\n            stargazers_url: string\n            statuses_url: string\n            subscribers_url: string\n            subscription_url: string\n            svn_url: string\n            tags_url: string\n            teams_url: string\n            trees_url: string\n            updated_at: string\n            url: string\n            visibility: string\n            watchers_count: number\n            watchers: number\n            web_commit_signoff_required: boolean\n        }[]\n\n        stars: {\n            avatar_url: string\n            events_url: string\n            followers_url: string\n            following_url: string\n            gists_url: string\n            gravatar_id: string\n            html_url: string\n            id: number\n            login: string\n            node_id: string\n            organizations_url: string\n            received_events_url: string\n            repos_url: string\n            site_admin: boolean\n            starred_url: string\n            subscriptions_url: string\n            type: string\n            url: string\n            user_view_type: string\n        }[]\n    }\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                  FUNCTIONS                                 */\n/* -------------------------------------------------------------------------- */\n\ninterface GetUserInputParams {\n    message: string\n    onFail?: (userInput: string) => void\n    validator?: (userInput: string) => boolean\n}\n\nasync function getUserInput({\n    message,\n    onFail = () => {},\n    validator = () => true,\n}: GetUserInputParams): Promise<string> {\n    let userInput: string\n\n    const rl = readline.createInterface({\n        input: process.stdin,\n        output: process.stdout,\n    })\n\n    userInput = await rl.question(message)\n\n    while (!validator(userInput)) {\n        onFail(userInput)\n        userInput = await rl.question(message)\n    }\n\n    rl.close()\n\n    userInput = userInput.trim()\n\n    return userInput.trim()\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                   CLASSES                                  */\n/* -------------------------------------------------------------------------- */\n\ninterface GitHubUserData {\n    followers: number\n    following: number\n    forks: number\n    name: string\n    publicRepositories: number\n    stars: number\n    userName: string\n}\n\ninterface IGitHubService {\n    fetchUserData: (userName: string) => Promise<GitHubUserData>\n}\n\nclass GitHubService implements IGitHubService {\n    public constructor() {}\n\n    private userDataAdapter(userData: GitHubAPI['user']): GitHubUserData {\n        let forks: number = 0\n        for (const publicRepo of userData.public_repos_data) {\n            if (publicRepo.fork) forks++\n        }\n\n        return {\n            followers: userData.followers,\n            following: userData.following,\n            forks,\n            name: userData.name,\n            publicRepositories: userData.public_repos,\n            stars: userData.stars.length,\n            userName: userData.login,\n        }\n    }\n\n    public async fetchUserData(userName: string): Promise<GitHubUserData> {\n        let response = await fetch(`https://api.github.com/users/${userName}`)\n        if (!response.ok)\n            throw new Error('An error occurred on fetch user data')\n\n        const userData = (await response.json()) as GitHubAPI['user']\n\n        response = await fetch(\n            `https://api.github.com/users/${userName}/starred`\n        )\n        if (!response.ok)\n            throw new Error('An error occurred on fetch user data')\n\n        const stars = (await response.json()) as GitHubAPI['user']['stars']\n        userData.stars = stars\n\n        response = await fetch(userData.repos_url)\n        if (!response.ok)\n            throw new Error('An error occurred on fetch user data')\n\n        const publicRepositories =\n            (await response.json()) as GitHubAPI['user']['public_repos_data']\n        userData.public_repos_data = publicRepositories\n\n        return this.userDataAdapter(userData)\n    }\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\n;(async () => {\n    let userData: GitHubUserData\n    const githubService: IGitHubService = new GitHubService()\n\n    let userInput: string = await getUserInput({\n        message: '> Enter a GitHub username (-1 to exit): ',\n    })\n\n    while (userInput !== '-1') {\n        try {\n            userData = await githubService.fetchUserData(userInput)\n\n            console.clear()\n\n            console.log('+'.padEnd(55, '-') + '+')\n            console.log(\n                '+' + userData.userName.padStart(27, ' ').padEnd(54, ' ') + '+'\n            )\n            console.log('+'.padEnd(55, '-') + '+')\n\n            console.log(`+ Name: ${userData.name}.`.padEnd(55, ' ') + '+')\n            console.log(\n                `+ Public repositories: ${userData.publicRepositories}.`.padEnd(\n                    55,\n                    ' '\n                ) + '+'\n            )\n            console.log(\n                `+ Repositories stared: ${userData.stars}.`.padEnd(55, ' ') +\n                    '+'\n            )\n            console.log(\n                `+ Number of repositories forked: ${userData.forks}.`.padEnd(\n                    55,\n                    ' '\n                ) + '+'\n            )\n            console.log(\n                `+ Following: ${userData.following}.`.padEnd(55, ' ') + '+'\n            )\n            console.log(\n                `+ Followers: ${userData.followers}.`.padEnd(55, ' ') + '+'\n            )\n\n            console.log('+'.padEnd(55, '-') + '+')\n        } catch (error) {\n            console.log(\n                `\\n> An error occurred on fetch \"${userInput}\" username! Try again...`\n            )\n        }\n\n        userInput = await getUserInput({\n            message: '\\n> Enter a new GitHub username (-1 to exit): ',\n        })\n    }\n})()\n"
  },
  {
    "path": "Roadmap/45 - GITHUB OCTOVERSE/typescript/miguelex.ts",
    "content": "import https from 'https';\nimport readline from 'readline';\n\ntype Headers = { [key: string]: string };\n\nclass GitHubUserReport {\n    private username: string;\n    private baseApiUrl: string = \"https://api.github.com\";\n    private headers: Headers = {\n        \"User-Agent\": \"GitHub-Report-App\",\n        \"Accept\": \"application/vnd.github.v3+json\"\n    };\n\n    constructor(username: string) {\n        this.username = username;\n    }\n\n    private apiRequest<T>(endpoint: string): Promise<T> {\n        const url = `${this.baseApiUrl}${endpoint}`;\n\n        return new Promise((resolve, reject) => {\n            const options = {\n                headers: this.headers\n            };\n\n            https.get(url, options, (res) => {\n                let data = '';\n\n                res.on('data', chunk => {\n                    data += chunk;\n                });\n\n                res.on('end', () => {\n                    if (res.statusCode === 200) {\n                        resolve(JSON.parse(data));\n                    } else {\n                        reject(new Error(`Error al conectar con la API de GitHub (HTTP ${res.statusCode}). Verifica el nombre de usuario.`));\n                    }\n                });\n            }).on('error', (err) => {\n                reject(new Error(`Error de conexión: ${err.message}`));\n            });\n        });\n    }\n\n    private getUserInfo(): Promise<any> {\n        return this.apiRequest(`/users/${this.username}`);\n    }\n\n    private getUserRepos(): Promise<any[]> {\n        return this.apiRequest(`/users/${this.username}/repos`);\n    }\n\n    public async generateReport(): Promise<void> {\n        try {\n            const userInfo = await this.getUserInfo();\n            const repos = await this.getUserRepos();\n\n            const totalRepos = repos.length;\n            const followers = userInfo.followers;\n            const following = userInfo.following;\n\n            const languages = repos.map(repo => repo.language).filter(Boolean);\n            const languageCounts = languages.reduce((counts: { [key: string]: number }, lang: string) => {\n                counts[lang] = (counts[lang] || 0) + 1;\n                return counts;\n            }, {});\n\n            const topLanguage = Object.keys(languageCounts).sort((a, b) => languageCounts[b] - languageCounts[a])[0] || \"N/A\";\n\n            const totalStars = repos.reduce((sum, repo) => sum + repo.stargazers_count, 0);\n            const totalForks = repos.reduce((sum, repo) => sum + repo.forks_count, 0);\n\n            console.log(`=== Informe de GitHub para el usuario: ${this.username} ===`);\n            console.log(`Nombre: ${userInfo.name}`);\n            console.log(`Bio: ${userInfo.bio}`);\n            console.log(`Ubicación: ${userInfo.location}`);\n            console.log(`Total de repositorios: ${totalRepos}`);\n            console.log(`Seguidores: ${followers}`);\n            console.log(`Seguidos: ${following}`);\n            console.log(`Lenguaje más utilizado: ${topLanguage}`);\n            console.log(`Total de estrellas: ${totalStars}`);\n            console.log(`Total de forks: ${totalForks}`);\n        } catch (error: any) {\n            console.error(error.message);\n        }\n    }\n}\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nrl.question(\"Ingrese el nombre de usuario de GitHub: \", (username: string) => {\n    if (!username) {\n        console.error(\"Debe ingresar un nombre de usuario.\");\n        rl.close();\n        return;\n    }\n\n    const report = new GitHubUserReport(username);\n    report.generateReport().finally(() => rl.close());\n});\n"
  },
  {
    "path": "Roadmap/45 - GITHUB OCTOVERSE/vb.net/kenysdev.vb",
    "content": "' _____________________________________\n' https://github.com/kenysdev\n' 2024 - vb.net\n' _____________________________________\n' 45 GITHUB OCTOVERSE\n' ------------------------------------\n'* EJERCICIO:\n'* GitHub ha publicado el Octoverse 2024, el informe\n'* anual del estado de la plataforma:\n'* https://octoverse.github.com\n'*\n'* Utilizando el API de GitHub, crea un informe asociado\n'* a un usuario concreto.\n'* \n'* - Se debe poder definir el nombre del usuario\n'*   sobre el que se va a generar el informe.\n'*   \n'* - Crea un informe de usuario basándote en las 5 métricas\n'*   que tú quieras, utilizando la informración que te\n'*   proporciona GitHub. Por ejemplo:\n'*   - Lenguaje más utilizado\n'*   - Cantidad de repositorios\n'*   - Seguidores/Seguidos\n'*   - Stars/forks\n'*   - Contribuciones\n'*   (lo que se te ocurra)\n\nImports System.Net.Http\nImports System.Text.Json\n\nPublic Class GitHubApi\n    Private ReadOnly _client As New HttpClient()\n    Private _userData As Dictionary(Of String, JsonElement)\n\n    Public Sub New(userName As String)\n        _userData = GetUserDataAsync(userName).Result\n    End Sub\n\n    Private Async Function GetUserDataAsync(userName As String) As Task(Of Dictionary(Of String, JsonElement))\n        Try\n            _client.DefaultRequestHeaders.Add(\"User-Agent\", \"Mozilla/5.0\")\n            Dim response = Await _client.GetStringAsync($\"https://api.github.com/users/{userName}\")\n            Return JsonSerializer.Deserialize(Of Dictionary(Of String, JsonElement))(response)\n        Catch ex As HttpRequestException\n            Console.WriteLine($\"Error: {ex.Message}\")\n            Return New Dictionary(Of String, JsonElement)()\n        End Try\n    End Function\n\n    Private Function VerifyStatus() As Boolean\n        Dim status As JsonElement\n        If _userData.TryGetValue(\"message\", status) AndAlso status.GetString() = \"Not Found\" Then\n            Console.WriteLine(\"Usuario no encontrado.\")\n            Return False\n        End If\n        Return True\n    End Function\n\n    Private Function GetRepoInfo(repo As JsonElement) As String\n        Dim name As JsonElement\n        Dim lang As JsonElement\n        Dim stars As JsonElement\n        Dim forks As JsonElement\n\n        Return $\"Lang: {If(repo.TryGetProperty(\"language\", lang), lang.GetString(), \"Desconocido\")}\nRepo: {If(repo.TryGetProperty(\"full_name\", name), name.GetString(), \"Desconocido\")}\nStars: {If(repo.TryGetProperty(\"stargazers_count\", stars), stars.GetInt32(), 0)}\nForks: {If(repo.TryGetProperty(\"forks_count\", forks), forks.GetInt32(), 0)}\"\n    End Function\n\n    Public Sub PrintBasicInfo()\n        If Not VerifyStatus() Then Return\n\n        Dim name As JsonElement\n        Dim created As JsonElement\n        Dim repos As JsonElement\n        Dim gists As JsonElement\n        Dim followers As JsonElement\n        Dim following As JsonElement\n\n        Console.WriteLine($\"-------------------------------------------\nNombre: {If(_userData.TryGetValue(\"name\", name), name.GetString(), \"Desconocido\")}\nCreación: {If(_userData.TryGetValue(\"created_at\", created), created.GetString(), \"Desconocido\")}\nRepos: {If(_userData.TryGetValue(\"public_repos\", repos), repos.GetInt32(), 0)}\nGists: {If(_userData.TryGetValue(\"public_gists\", gists), gists.GetInt32(), 0)}\nSeguidores: {If(_userData.TryGetValue(\"followers\", followers), followers.GetInt32(), 0)}\nSeguidos: {If(_userData.TryGetValue(\"following\", following), following.GetInt32(), 0)}\n-------------------------------------------\")\n    End Sub\n\n    Public Async Function PrintReposInfoAsync() As Task\n        If Not VerifyStatus() Then Return\n\n        Dim reposUrl As JsonElement\n        If _userData.TryGetValue(\"repos_url\", reposUrl) Then\n            Dim reposResponse = Await _client.GetStringAsync(reposUrl.GetString())\n            Dim repos = JsonSerializer.Deserialize(Of List(Of JsonElement))(reposResponse)\n\n            Dim languages As New Dictionary(Of String, Integer)()\n            Console.WriteLine(\"Repositorios publicos:\")\n\n            For Each repo In repos\n                Console.WriteLine(vbCrLf + GetRepoInfo(repo))\n\n                Dim language As JsonElement\n                If repo.TryGetProperty(\"language\", language) Then\n                    Dim lang = language.GetString()\n                    If Not String.IsNullOrEmpty(lang) Then\n                        If languages.ContainsKey(lang) Then\n                            languages(lang) += 1\n                        Else\n                            languages(lang) = 1\n                        End If\n                    End If\n                End If\n            Next\n\n            Dim mostUsedLang = languages.OrderByDescending(Function(x) x.Value).FirstOrDefault()\n            Console.WriteLine(vbCrLf + $\"Total de repositorios: '{repos.Count}'\")\n            Console.WriteLine($\"El lenguaje más utilizado: '{mostUsedLang.Key}'({mostUsedLang.Value})\")\n        End If\n    End Function\n\n    Public Shared Sub Main()\n        Console.WriteLine(\"Informe sobre los datos del usuario en GitHub\")\n        Console.Write(\"Usuario: \")\n        Dim userName = Console.ReadLine()\n\n        Task.Run(Async Function()\n                     Dim github = New GitHubApi(userName)\n                     Await github.PrintReposInfoAsync()\n                     github.PrintBasicInfo()\n                 End Function).GetAwaiter().GetResult()\n    End Sub\nEnd Class\n"
  },
  {
    "path": "Roadmap/46 - X VS BLUESKY/c#/hequebo.cs",
    "content": "class User\n{\n    private int _id;\n    private string? _userName;\n    private List<User> _following;\n    private List<User> _followers;\n\n    public int Id { get { return _id; } }\n    public string? UserName {  get { return _userName; } }\n    public List<User> Following { get { return _following; } }\n    public List<User> Followers { get { return _followers; } }\n\n    public User(int id, string? userName)\n    {\n        _id = id;\n        _userName = userName;\n        _following = new List<User>();\n        _followers = new List<User>();\n    }\n\n    public void FollowUser(User user) => _following.Add(user);\n    public void UnFollowUser(User user) => _following.Remove(user);\n    public void AddFollower(User user) => _followers.Add(user);\n    public void RemoveFollower(User user) => _followers.Remove(user);\n}\nclass Post\n{\n    private int _id;\n    private User _user;\n    private string _content;\n    private DateTime _creationDate;\n    private List<User> _likes;\n\n    public int Id { get { return _id; } }\n    public User User { get { return _user; } }\n    public string Content { get { return _content; } }\n    public DateTime CreationDate { get { return _creationDate; } }\n    public List<User> Likes { get { return _likes; } }\n\n    public Post(int id, User user, string content)\n    {\n        _id = id;\n        _user = user;\n        _content = content;\n        _creationDate = DateTime.Now;\n        _likes = new List<User>();\n    }\n\n    public void AddLike(User user) => _likes.Add(user);\n    public void RemoveLike(User user) => _likes.Remove(user);\n}\nclass SocialNetwork\n{\n    private List<User> _users;\n    private List<Post> _posts;\n    private int _userId = 1;\n    private int _postId = 1;\n\n    public SocialNetwork()\n    {\n        _users = new List<User>();\n        _posts = new List<Post>();\n    }\n    public void RegisterUser(string? userName)\n    {\n        if (string.IsNullOrEmpty(userName))\n        {\n            Console.WriteLine(\"No se ha ingresado ningún nombre de usuario...\");\n            return;\n        }\n        if (_users.Where(u => u.UserName == userName).Any())\n        {\n            Console.WriteLine($\"El nombre de usuario {userName} ya existe...\");\n            return;\n        }\n        var user = new User(_userId, userName);\n        _users.Add(user);\n        Console.WriteLine(\"El usuario ha sido registrado correctamente\");\n        Console.WriteLine($\"Id: {user.Id}, Nombre de Usuario: {user.UserName}\");\n        _userId++;\n    }\n    public void FollowUser(string? userName1, string? userName2)\n    {\n        if (string.IsNullOrEmpty(userName1) || string.IsNullOrEmpty(userName2))\n        {\n            Console.WriteLine(\"Uno de los usuarios no se ha ingresado correctamente...\");\n            return;\n        }\n        var user1 = SearchUser(userName1);\n        var user2 = SearchUser(userName2);\n        if (user1 == null || user2 == null)\n            return;\n        if (user1.Following.Contains(user2))\n        {\n            Console.WriteLine($\"{user1.UserName} ya sigue a {user2.UserName}...\");\n            return;\n        }\n        if (user1 == user2)\n        {\n            Console.WriteLine($\"{user1.UserName} no puede seguirse a si mismo...\");\n            return;\n        }\n        user1.FollowUser(user2);\n        user2.AddFollower(user1);\n        Console.WriteLine($\"{user1.UserName} ahora sigue a {user2.UserName}\");\n    }\n    public void UnfollowUser(string? userName1, string? userName2)\n    {\n        if (string.IsNullOrEmpty(userName1) || string.IsNullOrEmpty(userName2))\n        {\n            Console.WriteLine(\"Uno de los usuarios no se ha ingresado correctamente...\");\n            return;\n        }\n        var user1 = SearchUser(userName1);\n        var user2 = SearchUser(userName2);\n        if (user1 == null || user2 == null)\n            return;\n        if (!user1.Following.Contains(user2))\n        {\n            Console.WriteLine($\"{user1.UserName} no seguía a {user2.UserName}...\");\n            return;\n        }\n        user1.UnFollowUser(user2);\n        user2.RemoveFollower(user1);\n        Console.WriteLine($\"{user1.UserName} dejó de seguir a {user2.UserName}\");\n    }\n    public void CreatePost(string? userName, string? content)\n    {\n        if (string.IsNullOrEmpty(userName))\n        {\n            Console.WriteLine(\"No se ingresó ningún usuario...\");\n            return;\n        }\n        var user = SearchUser(userName);\n        if (user == null)\n            return;\n        if (string.IsNullOrEmpty(content))\n        {\n            Console.WriteLine(\"La publicación está vacía...\");\n            return;\n        }\n        if (content.Length > 200)\n        {\n            Console.WriteLine(\"La publicación no puede contener más de 200 carácteres...\");\n            return;\n        }\n        var post = new Post(_postId, user, content);\n        _posts.Add(post);\n        Console.WriteLine(\"La publicación se ha creado correctamente...\");\n        _postId++;\n    }\n    public void DeletePost(string? userName)\n    {\n        if (string.IsNullOrEmpty(userName))\n        {\n            Console.WriteLine(\"No se ingresó ningún usuario...\");\n            return;\n        }\n        var user = SearchUser(userName);\n        if (user == null)\n            return;\n        var userPosts = _posts.Where(p => p.User == user).ToList();\n        if (userPosts.Count == 0)\n        {\n            Console.WriteLine($\"El usuario {user.UserName} no tiene publicaciones...\");\n            return;\n        }\n        Console.WriteLine($\"------------Publicaciones de {user.UserName}------------\");\n        foreach (var post in userPosts) \n            ShowPost(post);\n        \n        Console.WriteLine();\n        Console.WriteLine(\"Ingresa el id de la publicación a eliminar\");\n        var postToDelete = SearchPost();\n\n        if (postToDelete == null)\n            return;\n        _posts.Remove(postToDelete);\n        Console.WriteLine(\"Se ha eliminado la publicación correctamente\");\n    }\n    private void ShowPost(Post post)\n    {\n        Console.WriteLine(\"-------------------------------------------------\");\n        Console.WriteLine($\"Post ID: {post.Id}\\tUsuario: {post.User.UserName}\" +\n        $\"\\n{post.Content}\\n{post.Likes.Count} likes\\t\\t{post.CreationDate}\");\n    }\n    private bool SearchPosts()\n    {\n        if (_posts.Count == 0)\n        {\n            Console.WriteLine(\"No hay publicaciones disponibles...\");\n            return false;\n        }\n        Console.WriteLine($\"------------Publicaciones disponibles------------\");\n        foreach (var post in _posts)\n            ShowPost(post);\n        Console.WriteLine();\n        return true;\n    }\n    private Post? SearchPost()\n    {\n        int id = 0;\n        int.TryParse(Console.ReadLine(), out id);\n        var post = _posts.Where(p => p.Id == id).FirstOrDefault();\n        if (post == null)\n            Console.WriteLine(\"La publicación no existe...\");\n        return post;\n    }\n    public void LikePost(string? userName) \n    {\n        if (string.IsNullOrEmpty (userName))\n        {\n            Console.WriteLine(\"El usuario no se ingresó correctamente...\");\n            return;\n        }\n        var user = SearchUser(userName);\n        if (user == null)\n            return;\n        if (!SearchPosts()) \n            return;\n        \n        Console.WriteLine(\"Ingresa el id de la publicación a dar like\");\n        var postToLike = SearchPost();\n\n        if (postToLike == null)\n            return;\n\n        postToLike.AddLike(user);\n        Console.WriteLine($\"{user.UserName} ha dado like a la publicación de {postToLike.User.UserName}\");\n        ShowPost(postToLike);\n    }\n    public void DislikePost(string? userName)\n    {\n        if (string.IsNullOrEmpty(userName))\n        {\n            Console.WriteLine(\"El usuario no se ingresó correctamente...\");\n            return;\n        }\n        var user = SearchUser(userName);\n        if (user == null)\n            return;\n\n        if (!SearchPosts())\n            return;\n\n        Console.WriteLine(\"Ingresa el id de la publicación a quitar like\");\n        var postToDislike = SearchPost();\n        if (postToDislike == null)\n            return;\n\n        if (!postToDislike.Likes.Contains(user)) \n        {\n            Console.WriteLine($\"{user.UserName} no había dado like a la publicación de {postToDislike.User.UserName}\");\n            return;\n        }\n        Console.WriteLine($\"{user.UserName} ha eliminado su like de la publicación de {postToDislike.User.UserName}\");\n        postToDislike.RemoveLike(user);\n    }\n    public void ShowFeed(string? userName)\n    {\n        if (string.IsNullOrEmpty(userName))\n        {\n            Console.WriteLine(\"No se ingresó ningún usuario...\");\n            return;\n        }\n        var feed = _posts.Where(p => p.User.UserName == userName).ToList();\n\n        if (feed.Count == 0)\n        {\n            Console.WriteLine($\"El usuario {userName} no tiene publicaciones...\");\n            return;\n        }\n        feed = feed.OrderByDescending(f => f.CreationDate)\n            .ToList();\n        if (feed.Count > 10)\n            feed = feed.Slice(0, 10);\n        Console.WriteLine($\"------------Últimas 10 publicaciones de {userName}------------\");\n        foreach (var post in feed)\n            ShowPost(post);\n    }\n    public void ShowFollowingFeed(string? userName)\n    {\n        if (string.IsNullOrEmpty(userName))\n        {\n            Console.WriteLine(\"No se ingresó ningún usuairo...\");\n            return;\n        }\n        var user = SearchUser(userName);\n        if (user == null) \n            return;\n\n        if (user.Following.Count == 0)\n        {\n            Console.WriteLine($\"El usuario {user.UserName} no sigue a ninguna cuenta...\");\n            return;\n        }\n\n        var feed = _posts.Where(p => user.Following.Contains(p.User))\n            .OrderByDescending(p => p.CreationDate)\n            .ToList();\n        if (feed.Count > 10)\n            feed = feed.Slice(0, 10);\n        Console.WriteLine($\"------------Feed cuentas seguidas por {user.UserName}------------\");\n        foreach(var post in feed)\n            ShowPost(post);\n        \n    }\n    public User? SearchUser(string userName)\n    {\n        var user = _users.Where(u => u.UserName == userName).FirstOrDefault();\n        if (user == null)\n            Console.WriteLine($\"El usuario {userName} no existe...\");\n        return user;\n    }\n}\nclass Program\n{\n    static void Main(string[] args)\n    {\n        var sn = new SocialNetwork();\n        bool exit = false;\n\n        do\n        {\n            Menu();\n            int option = 0;\n            int.TryParse(Console.ReadLine(), out option);\n            switch (option)\n            {\n                case 1:\n                    Console.Clear();\n                    Console.WriteLine(\"Ingresa el nombre de usuario\");\n                    string? userName = Console.ReadLine();\n                    sn.RegisterUser(userName);\n                    break;\n                case 2:\n                    Console.Clear();\n                    Console.WriteLine(\"Ingresa el nombre del usuario\");\n                    string? userName1 = Console.ReadLine();\n                    Console.WriteLine(\"Ingresa el nombre del usuario a seguir\");\n                    string? userName2 = Console.ReadLine();\n                    sn.FollowUser(userName1, userName2);\n                    break;\n                case 3:\n                    Console.Clear();\n                    Console.WriteLine(\"Ingresa el nombre del usuario\");\n                    userName1 = Console.ReadLine();\n                    Console.WriteLine(\"Ingresa el nombre del usuario a dejar de seguir\");\n                    userName2 = Console.ReadLine();\n                    sn.UnfollowUser(userName1, userName2);\n                    break;\n                case 4:\n                    Console.Clear();\n                    Console.WriteLine(\"Ingresa el nombre del usuario\");\n                    userName = Console.ReadLine();\n                    Console.WriteLine(\"Ingresa el contenido de la publicación\");\n                    string? content = Console.ReadLine();\n                    sn.CreatePost(userName, content);\n                    break;\n                case 5:\n                    Console.Clear();\n                    Console.WriteLine(\"Ingresa el nombre del usuario\");\n                    userName = Console.ReadLine();\n                    sn.DeletePost(userName);\n                    break;\n                case 6:\n                    Console.Clear();\n                    Console.WriteLine(\"Ingresa el nombre del usuario\");\n                    userName = Console.ReadLine();\n                    sn.LikePost(userName);\n                    break;\n                case 7:\n                    Console.Clear();\n                    Console.WriteLine(\"Ingresa el nombre del usuario\");\n                    userName = Console.ReadLine();\n                    sn.DislikePost(userName);\n                    break;\n                case 8:\n                    Console.Clear();\n                    Console.WriteLine(\"Ingresa el nombre del usuario\");\n                    userName = Console.ReadLine();\n                    sn.ShowFeed(userName);\n                    break;\n                case 9:\n                    Console.Clear();\n                    Console.WriteLine(\"Ingresa el nombre del usuario\");\n                    userName = Console.ReadLine();\n                    sn.ShowFollowingFeed(userName);\n                    break;\n                case 10:\n                    Console.Clear();\n                    exit = true;\n                    Console.WriteLine(\"Hasta la próxima...\");\n                    Thread.Sleep(1000);\n                    break;\n                default:\n                    Console.WriteLine(\"Opción no válida...\");\n                    break;\n            }\n        } while (!exit);\n    }\n    static void Menu()\n    {\n        Console.WriteLine(\"------------MENU------------\");\n        Console.WriteLine(\"1.- Registrar usuario nuevo.\");\n        Console.WriteLine(\"2.- Seguir a un usuario.\");\n        Console.WriteLine(\"3.- Dejar de seguir a un usuario\");\n        Console.WriteLine(\"4.- Crear una publicación.\");\n        Console.WriteLine(\"5.- Eliminar una publicación.\");\n        Console.WriteLine(\"6.- Dar Like.\");\n        Console.WriteLine(\"7.- Quitar Like\");\n        Console.WriteLine(\"8.- Mostrar Feed de usuario\");\n        Console.WriteLine(\"9.- Mostrar Feed de usuarios seguidos\");\n        Console.WriteLine(\"10.- Salir.\");\n        Console.WriteLine(\"Ingrese la opción deseada...\");\n    }\n}"
  },
  {
    "path": "Roadmap/46 - X VS BLUESKY/c#/kenysdev.cs",
    "content": "namespace exs46;\n/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - C#\n_____________________________________\n46 X VS BLUESKY\n------------------------------------\n\n * EJERCICIO:\n * La alternativa descentralizada a X, Bluesky, comienza a atraer\n * a nuevos usuarios. ¿Cómo funciona una red de este estilo?\n * \n * Implementa un sistema que simule el comportamiento de estas\n * redes sociales.\n * \n * Debes crear las siguientes operaciones:\n * - Registrar un usuario por nombre e identificador único.\n * - Un usuario puede seguir/dejar de seguir a otro.\n * - Creación de post asociado a un usuario. Debe poseer\n *   texto (200 caracteres máximo), fecha de creación \n *   e identificador único.   \n * - Eliminación de un post.\n * - Posibilidad de hacer like (y eliminarlo) en un post.\n * - Visualización del feed de un usuario con sus 10 publicaciones\n *   más actuales ordenadas desde la más reciente.\n * - Visualización del feed de un usuario con las 10 publicaciones\n *   más actuales de los usuarios que sigue ordenadas \n *   desde la más reciente.\n *   \n * Cuando se visualiza un post, debe mostrarse:\n * ID de usuario, nombre de usuario, texto del post, \n * fecha de creación y número total de likes.\n * \n * Controla errores en duplicados o acciones no permitidas.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing Microsoft.Extensions.Logging;\n\npublic class Posts(ILogger<Posts> logger)\n{\n    private readonly Dictionary<int, Dictionary<int, PostData>> _postDt = [];\n    private readonly ILogger<Posts> _logger = logger;\n\n    public class PostData\n    {\n        public string Content { get; set; } = \"\";\n        public DateTime Timestamp { get; set; }\n        public HashSet<int> Likes { get; set; } = [];\n    }\n\n    private bool VerifyPost(int idUser, int idPost, string nameFunc)\n    {\n        if (!_postDt.TryGetValue(idUser, out Dictionary<int, PostData>? value))\n        {\n            _logger.LogError(\"'{NameFunc}': El ID {IdUser} no tiene posts.\", nameFunc, idUser);\n            return false;\n        }\n\n        if (!value.ContainsKey(idPost))\n        {\n            _logger.LogError(\"'{NameFunc}': El Post ({IdPost}) no existe.\", nameFunc, idPost);\n            return false;\n        }\n\n        return true;\n    }\n\n    public void CreatePost(int idUser, string content)\n    {\n        if (content.Length > 200)\n        {\n            _logger.LogError(\"'create_post': content > 200 caracteres.\");\n            return;\n        }\n\n        if (!_postDt.TryGetValue(idUser, out Dictionary<int, PostData>? value))\n        {\n            value = [];\n            _postDt[idUser] = value;\n        }\n\n        var idPost = value.Count + 1;\n        value[idPost] = new PostData\n        {\n            Content = content,\n            Timestamp = DateTime.Now,\n            Likes = []\n        };\n\n        _logger.LogInformation(\"El ID {IdUser} creó un post(ID: {IdPost}).\", idUser, idPost);\n    }\n\n    public void DeletePost(int idUser, int idPost)\n    {\n        if (VerifyPost(idUser, idPost, \"DeletePost\"))\n        {\n            _postDt[idUser].Remove(idPost);\n            _logger.LogInformation(\"El post: {IdPost} de usuario: {IdUser} ha sido eliminado.\", idPost, idUser);\n        }\n    }\n\n    public void LikePost(int idUser, int idAuthor, int idPost)\n    {\n        if (VerifyPost(idAuthor, idPost, \"LikePost\"))\n        {\n            _postDt[idAuthor][idPost].Likes.Add(idUser);\n            _logger.LogInformation(\"El usuario {IdUser} dio like al post {IdPost} de usuario {IdAuthor}.\", \n                idUser, idPost, idAuthor);\n        }\n    }\n\n    public void RemoveLike(int idUser, int idAuthor, int idPost)\n    {\n        if (VerifyPost(idAuthor, idPost, \"RemoveLike\"))\n        {\n            _postDt[idAuthor][idPost].Likes.Remove(idUser);\n            _logger.LogInformation(\"El usuario {IdUser} anuló el like al post {IdPost} de usuario {IdAuthor}.\",\n                idUser, idPost, idAuthor);\n        }\n    }\n\n    public List<PostData> GetRecentPosts(int idUser, int limit = 10)\n    {\n        if (_postDt.TryGetValue(idUser, out Dictionary<int, PostData>? value))\n        {\n            return value.Values\n                .OrderByDescending(p => p.Timestamp)\n                .Take(limit)\n                .ToList();\n        }\n\n        return [];\n    }\n}\n\npublic class Users(ILogger<Users> logger)\n{\n    private readonly Dictionary<int, UserData> _usersDt = [];\n    private readonly ILogger<Users> _logger = logger;\n\n    private class UserData\n    {\n        public string Name { get; set; } = \"\";\n        public HashSet<int> Following { get; set; } = [];\n        public HashSet<int> Followers { get; set; } = [];\n    }\n\n    private bool IdExists(int id, string nameFunc)\n    {\n        if (_usersDt.ContainsKey(id))\n            return true;\n\n        _logger.LogWarning(\"'{NameFunc}': ID: {Id} no encontrada.\", nameFunc, id);\n        return false;\n    }\n\n    public void AddUser(string name)\n    {\n        var id = _usersDt.Count + 1;\n        _usersDt[id] = new UserData\n        {\n            Name = name,\n            Following = [],\n            Followers = []\n        };\n\n        _logger.LogInformation(\"Usuario {Id}-{Name} registrado.\", id, name);\n    }\n\n    public void FollowUser(int id, int toId)\n    {\n        if (IdExists(id, \"FollowUser\") && IdExists(toId, \"FollowUser\"))\n        {\n            _usersDt[id].Following.Add(toId);\n            _usersDt[toId].Followers.Add(id);\n            _logger.LogInformation(\"ID: {Id} está siguiendo a ID: {ToId}.\", id, toId);\n        }\n    }\n\n    public void UnfollowUser(int id, int toId)\n    {\n        if (IdExists(id, \"UnfollowUser\") && IdExists(toId, \"UnfollowUser\"))\n        {\n            _usersDt[id].Following.Remove(toId);\n            _usersDt[toId].Followers.Remove(id);\n            _logger.LogInformation(\"El ID: {Id} dejó de seguir al ID: {ToId}.\", id, toId);\n        }\n    }\n\n    public string GetName(int idUser)\n    {\n        if (IdExists(idUser, \"GetName\"))\n        {\n            return _usersDt[idUser].Name;\n        }\n\n        return \"\";\n    }\n}\n\npublic class Program(ILogger<Posts> postsLogger, ILogger<Users> usersLogger)\n{\n    private readonly Posts _posts = new(postsLogger);\n    private readonly Users _users = new(usersLogger);\n\n    private void PrintFeed(int idUser)\n    {\n        var name = _users.GetName(idUser);\n        if (string.IsNullOrEmpty(name))\n        {\n            Console.WriteLine($\"Usuario ID: {idUser} no encontrado.\");\n            return;\n        }\n\n        var last10 = _posts.GetRecentPosts(idUser, 10);\n        Console.WriteLine($\"\\nFeed\\n_______\\nID: '{idUser}' - Nombre: '{name}'\");\n        \n        if (last10.Count == 0)\n        {\n            Console.WriteLine(\"No tiene publicaciones.\");\n            return;\n        }\n\n        foreach (var post in last10)\n        {\n            Console.WriteLine($\"_______\\n{post.Content}\");\n            Console.WriteLine($\"Creado: '{post.Timestamp}'\");\n            Console.WriteLine($\"Likes: '{post.Likes.Count}'\");\n        }\n    }\n\n    public void Run()\n    {\n        // CLI\n    }\n\n    public void Tests()\n    {\n        _users.AddUser(\"Ken\"); // id=1\n        _users.AddUser(\"Zoe\"); // id=2\n\n        _users.FollowUser(1, 2);\n        _users.FollowUser(2, 1);\n        _users.UnfollowUser(2, 1);\n\n        _posts.CreatePost(2, \"Primer post.\"); // id=1\n        _posts.CreatePost(2, \"Segundo post.\"); // id=2\n        _posts.DeletePost(2, 2);\n        _posts.CreatePost(2, \"Otro post.\"); // id=2\n        _posts.LikePost(1, 2, 1);\n        _posts.RemoveLike(1, 2, 1);\n        _posts.LikePost(1, 2, 2);\n\n        PrintFeed(2);\n        PrintFeed(1);\n    }\n\n    public static void Main()\n    {\n        using var loggerFactory = LoggerFactory.Create(builder =>\n        {\n            builder\n                .SetMinimumLevel(LogLevel.Debug)\n                .AddConsole();\n        });\n\n        var postsLogger = loggerFactory.CreateLogger<Posts>();\n        var usersLogger = loggerFactory.CreateLogger<Users>();\n\n        var program = new Program(postsLogger, usersLogger);\n        program.Tests();\n        //program.Run();\n    }\n}\n"
  },
  {
    "path": "Roadmap/46 - X VS BLUESKY/c++/hectorio23.cpp",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\n#include <iostream>\n#include <unordered_map>\n#include <unordered_set>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <ctime>\n\n/*\n * EJERCICIO:\n * La alternativa descentralizada a X, Bluesky, comienza a atraer\n * a nuevos usuarios. ¿Cómo funciona una red de este estilo?\n * \n * Implementa un sistema que simule el comportamiento de estas\n * redes sociales.\n * \n * Debes crear las siguientes operaciones:\n * - Registrar un usuario por nombre e identificador único.\n * - Un usuario puede seguir/dejar de seguir a otro.\n * - Creación de post asociado a un usuario. Debe poseer\n *   texto (200 caracteres máximo), fecha de creación \n *   e identificador único.   \n * - Eliminación de un post.\n * - Posibilidad de hacer like (y eliminarlo) en un post.\n * - Visualización del feed de un usuario con sus 10 publicaciones\n *   más actuales ordenadas desde la más reciente.\n * - Visualización del feed de un usuario con las 10 publicaciones\n *   más actuales de los usuarios que sigue ordenadas \n *   desde la más reciente.\n *   \n * Cuando se visualiza un post, debe mostrarse:\n * ID de usuario, nombre de usuario, texto del post, \n * fecha de creación y número total de likes.\n * \n * Controla errores en duplicados o acciones no permitidas.\n*/\n\n// Helper struct for representing a post\nstruct Post {\n    std::string postId;\n    std::string userId;\n    std::string text;\n    std::time_t createdAt;\n    int likes = 0;\n\n    void displayPost(const std::string &userName) const {\n        std::cout << \"User ID: \" << userId << \", Name: \" << userName\n                  << \", Post ID: \" << postId << \", Text: \" << text\n                  << \", Created At: \" << std::ctime(&createdAt)\n                  << \", Likes: \" << likes << '\\n';\n    }\n};\n\nclass SocialNetwork {\nprivate:\n    struct User {\n        std::string userId;\n        std::string name;\n        std::unordered_set<std::string> following;\n        std::vector<Post> posts;\n    };\n\n    std::unordered_map<std::string, User> users;\n    std::unordered_map<std::string, Post*> postMap;\n\npublic:\n    void registerUser(const std::string &userId, const std::string &name) {\n        if (users.count(userId)) {\n            throw std::runtime_error(\"User ID already exists.\");\n        }\n        users[userId] = {userId, name, {}, {}};\n    }\n\n    void toggleFollow(const std::string &followerId, const std::string &followedId) {\n        if (!users.count(followerId) || !users.count(followedId)) {\n            throw std::runtime_error(\"User ID not found.\");\n        }\n        auto &following = users[followerId].following;\n        if (!following.insert(followedId).second) {\n            following.erase(followedId);\n        }\n    }\n\n    void createPost(const std::string &userId, const std::string &postId, const std::string &text) {\n        if (!users.count(userId)) {\n            throw std::runtime_error(\"User ID not found.\");\n        }\n        if (postMap.count(postId)) {\n            throw std::runtime_error(\"Post ID already exists.\");\n        }\n        if (text.length() > 200) {\n            throw std::runtime_error(\"Text exceeds maximum length of 200 characters.\");\n        }\n        Post post = {postId, userId, text, std::time(nullptr)};\n        users[userId].posts.push_back(post);\n        postMap[postId] = &users[userId].posts.back();\n    }\n\n    void deletePost(const std::string &postId) {\n        if (!postMap.count(postId)) {\n            throw std::runtime_error(\"Post ID not found.\");\n        }\n        auto &post = *postMap[postId];\n        auto &userPosts = users[post.userId].posts;\n        userPosts.erase(std::remove_if(userPosts.begin(), userPosts.end(),\n                                       [&](const Post &p) { return p.postId == postId; }),\n                        userPosts.end());\n        postMap.erase(postId);\n    }\n\n    void toggleLike(const std::string &postId) {\n        if (!postMap.count(postId)) {\n            throw std::runtime_error(\"Post ID not found.\");\n        }\n        auto &post = *postMap[postId];\n        post.likes = post.likes == 0 ? 1 : 0;\n    }\n\n    void getUserFeed(const std::string &userId) const {\n        if (!users.count(userId)) {\n            throw std::runtime_error(\"User ID not found.\");\n        }\n        const auto &posts = users.at(userId).posts;\n        displayFeed(posts);\n    }\n\n    void getFollowingFeed(const std::string &userId) const {\n        if (!users.count(userId)) {\n            throw std::runtime_error(\"User ID not found.\");\n        }\n        std::vector<Post> feed;\n        for (const auto &followedId : users.at(userId).following) {\n            const auto &posts = users.at(followedId).posts;\n            feed.insert(feed.end(), posts.begin(), posts.end());\n        }\n        std::sort(feed.begin(), feed.end(), [](const Post &a, const Post &b) {\n            return a.createdAt > b.createdAt;\n        });\n        displayFeed(feed);\n    }\n\nprivate:\n    void displayFeed(const std::vector<Post> &posts) const {\n        int count = 0;\n        for (const auto &post : posts) {\n            if (++count > 10) break;\n            const auto &user = users.at(post.userId);\n            post.displayPost(user.name);\n        }\n    }\n};\n\nint main() {\n    SocialNetwork sn;\n    try {\n        sn.registerUser(\"u1\", \"Alice\");\n        sn.registerUser(\"u2\", \"Bob\");\n\n        sn.toggleFollow(\"u1\", \"u2\");\n\n        sn.createPost(\"u1\", \"p1\", \"Hello, this is Alice!\");\n        sn.createPost(\"u2\", \"p2\", \"Hi, this is Bob's post.\");\n        sn.toggleLike(\"p2\");\n\n        std::cout << \"\\n[+] - User Feed for Alice:\\n\";\n        sn.getUserFeed(\"u1\");\n\n        std::cout << \"\\n[+] - Following Feed for Alice:\\n\";\n        sn.getFollowingFeed(\"u1\");\n\n        sn.deletePost(\"p1\");\n        std::cout << \"\\n[+] - After Deleting Alice's Post:\\n\";\n        sn.getUserFeed(\"u1\");\n    } catch (const std::exception &ex) {\n        std::cerr << \"Error: \" << ex.what() << '\\n';\n    }\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/46 - X VS BLUESKY/ejercicio.md",
    "content": "# #46 X VS BLUESKY\n> #### Dificultad: Media | Publicación: 18/11/24 | Corrección: 25/11/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * La alternativa descentralizada a X, Bluesky, comienza a atraer\n * a nuevos usuarios. ¿Cómo funciona una red de este estilo?\n * \n * Implementa un sistema que simule el comportamiento de estas\n * redes sociales.\n * \n * Debes crear las siguientes operaciones:\n * - Registrar un usuario por nombre e identificador único.\n * - Un usuario puede seguir/dejar de seguir a otro.\n * - Creación de post asociado a un usuario. Debe poseer\n *   texto (200 caracteres máximo), fecha de creación \n *   e identificador único.   \n * - Eliminación de un post.\n * - Posibilidad de hacer like (y eliminarlo) en un post.\n * - Visualización del feed de un usuario con sus 10 publicaciones\n *   más actuales ordenadas desde la más reciente.\n * - Visualización del feed de un usuario con las 10 publicaciones\n *   más actuales de los usuarios que sigue ordenadas \n *   desde la más reciente.\n *   \n * Cuando se visualiza un post, debe mostrarse:\n * ID de usuario, nombre de usuario, texto del post, \n * fecha de creación y número total de likes.\n * \n * Controla errores en duplicados o acciones no permitidas.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/46 - X VS BLUESKY/go/hozlucas28.go",
    "content": "package main\n\nimport (\n\t\"bufio\"\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"slices\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n)\n\n/* -------------------------------------------------------------------------- */\n/*                                 STRUCTURES                                 */\n/* -------------------------------------------------------------------------- */\n\n/* ---------------------------------- Post ---------------------------------- */\n\ntype Post interface {\n\tGetAuthor() string\n\tGetContent() string\n\tGetDate() *time.Time\n\tGetID() string\n\tGetLikes() []string\n\n\tAddLike(uName string) error\n\tRemoveLike(uName string) error\n}\n\ntype post struct {\n\tauthor  string\n\tcontent string\n\tdate    *time.Time\n\tid      string\n\tlikes   []string\n\t_       struct{}\n}\n\nfunc NewPost(author string, content string) (Post, error) {\n\tvar database Database = DatabaseInstance()\n\n\tvar id string\n\tvar currentDate time.Time = time.Now()\n\n\tif len(content) > 200 {\n\t\treturn nil, errors.New(\"Content of the post exceed the maximum length (200 chars)\")\n\t}\n\n\tid = fmt.Sprintf(\"%s %d\", author, len(database.GetPosts()))\n\n\tvar post post = post{\n\t\tauthor:  author,\n\t\tcontent: content,\n\t\tdate:    &currentDate,\n\t\tid:      id,\n\t\tlikes:   []string{},\n\t}\n\n\treturn &post, nil\n}\n\nfunc (post *post) GetAuthor() string {\n\treturn post.author\n}\n\nfunc (post *post) GetContent() string {\n\treturn post.content\n}\n\nfunc (post *post) GetDate() *time.Time {\n\treturn post.date\n}\n\nfunc (post *post) GetID() string {\n\treturn post.id\n}\n\nfunc (post *post) GetLikes() []string {\n\treturn post.likes\n}\n\nfunc (post *post) AddLike(uName string) error {\n\tvar errMsg string\n\n\tif slices.Contains(post.likes, uName) {\n\t\terrMsg = fmt.Sprintf(\"\\\"%s\\\" like already exists\", uName)\n\t\treturn errors.New(errMsg)\n\t}\n\n\tpost.likes = append(post.likes, uName)\n\treturn nil\n}\n\nfunc (post *post) RemoveLike(uName string) error {\n\tvar errMsg string\n\n\tlikeI := slices.Index(post.likes, uName)\n\tif likeI == -1 {\n\t\terrMsg = fmt.Sprintf(\"\\\"%s\\\" like doesn't  exist\", uName)\n\t\treturn errors.New(errMsg)\n\t}\n\n\tpost.likes = slices.Concat(post.likes[0:likeI], post.likes[likeI+1:])\n\treturn nil\n}\n\n/* ---------------------------------- User ---------------------------------- */\n\ntype User interface {\n\tGetUName() string\n\tGetFollowers() []string\n\tGetFollowings() []string\n\tGetPosts() []string\n\n\tCreatePost(content string) error\n\tDeletePost(id string) error\n\tFollow(uName string) error\n\tLikePost(id string) error\n\tUnfollow(uName string) error\n\tUnlikePost(id string) error\n\n\taddFollower(uName string)\n\tremoveFollower(uName string) error\n}\n\ntype user struct {\n\tfollowers  []string\n\tfollowings []string\n\tposts      []string\n\tuName      string\n\t_          struct{}\n}\n\nfunc NewUser(uName string) User {\n\tvar user user = user{\n\t\tfollowers:  []string{},\n\t\tfollowings: []string{},\n\t\tposts:      []string{},\n\t\tuName:      uName,\n\t}\n\n\treturn &user\n}\n\nfunc (user *user) GetUName() string {\n\treturn user.uName\n}\n\nfunc (user *user) GetFollowers() []string {\n\treturn user.followers\n}\n\nfunc (user *user) GetFollowings() []string {\n\treturn user.followings\n}\n\nfunc (user *user) GetPosts() []string {\n\treturn user.posts\n}\n\nfunc (user *user) CreatePost(content string) error {\n\tvar database Database = DatabaseInstance()\n\n\tpost, err := NewPost((*user).GetUName(), content)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tdatabase.addNewPost(&post)\n\tuser.posts = append(user.posts, post.GetID())\n\treturn nil\n}\n\nfunc (user *user) DeletePost(id string) error {\n\tvar errMsg string\n\tvar database Database = DatabaseInstance()\n\n\tvar postI int = slices.Index(user.posts, id)\n\tif postI == -1 {\n\t\terrMsg = fmt.Sprintf(\"\\\"%s\\\" doesn't posted the post with \\\"%s\\\" id\", user.uName, id)\n\t\treturn errors.New(errMsg)\n\t}\n\n\tdatabase.deletePost(id)\n\tuser.posts = slices.Concat(user.posts[0:postI], user.posts[postI+1:])\n\treturn nil\n}\n\nfunc (user *user) Follow(uName string) error {\n\tvar errMsg string\n\tvar database Database = DatabaseInstance()\n\n\tvar followingI int = slices.Index(user.followings, uName)\n\tif followingI != -1 {\n\t\terrMsg = fmt.Sprintf(\"\\\"%s\\\" already follows \\\"%s\\\"\", user.uName, uName)\n\t\treturn errors.New(errMsg)\n\t}\n\n\tuserFollowed, err := database.GetUser(uName)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t(*userFollowed).addFollower(user.uName)\n\tuser.followings = append(user.followings, uName)\n\treturn nil\n}\n\nfunc (user *user) LikePost(id string) error {\n\tvar database Database = DatabaseInstance()\n\n\tpost, err := database.GetPost(id)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t(*post).AddLike(user.uName)\n\treturn nil\n}\n\nfunc (user *user) Unfollow(uName string) error {\n\tvar errMsg string\n\tvar database Database = DatabaseInstance()\n\n\tvar followingI int = slices.Index(user.followings, uName)\n\tif followingI == -1 {\n\t\terrMsg = fmt.Sprintf(\"\\\"%s\\\" doesn't follow \\\"%s\\\"\", user.uName, uName)\n\t\treturn errors.New(errMsg)\n\t}\n\n\tuserUnfollowed, err := database.GetUser(uName)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t(*userUnfollowed).removeFollower(user.uName)\n\tuser.followings = slices.Concat(user.followings[0:followingI], user.followings[followingI+1:])\n\treturn nil\n}\n\nfunc (user *user) UnlikePost(id string) error {\n\tvar database Database = DatabaseInstance()\n\n\tpost, err := database.GetPost(id)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t(*post).RemoveLike(user.uName)\n\treturn nil\n}\n\nfunc (user *user) addFollower(uName string) {\n\tuser.followers = append(user.followers, uName)\n}\n\nfunc (user *user) removeFollower(uName string) error {\n\tvar errMsg string\n\n\tvar followerI int = slices.Index(user.followers, uName)\n\tif followerI == -1 {\n\t\terrMsg = fmt.Sprintf(\"\\\"%s\\\" isn't follow by \\\"%s\\\"\", user.uName, uName)\n\t\treturn errors.New(errMsg)\n\t}\n\n\tuser.followers = slices.Concat(user.followers[0:followerI], user.followers[followerI+1:])\n\treturn nil\n}\n\n/* -------------------------------- Database -------------------------------- */\n\ntype Database interface {\n\tGetPosts() []*Post\n\tGetUsers() []*User\n\n\tGetUser(uName string) (*User, error)\n\tGetPost(id string) (*Post, error)\n\tGetUserFollowingsPosts(uName string) ([]*Post, error)\n\tGetUserPosts(uName string) ([]*Post, error)\n\tDeleteUser(uName string) error\n\tPostUser(newUser *User) error\n\n\taddNewPost(newPost *Post)\n\tdeletePost(postID string) error\n}\n\ntype database struct {\n\tposts []*Post\n\tusers []*User\n\t_     struct{}\n}\n\nvar databaseInstance *database\nvar databaseMutex *sync.Mutex = &sync.Mutex{}\n\nfunc DatabaseInstance() Database {\n\tif databaseInstance == nil {\n\t\tdatabaseMutex.Lock()\n\t\tdefer databaseMutex.Unlock()\n\n\t\tif databaseInstance == nil {\n\t\t\tdatabaseInstance = &database{}\n\t\t}\n\t}\n\n\treturn databaseInstance\n}\n\nfunc (database *database) GetPosts() []*Post {\n\treturn database.posts\n}\n\nfunc (database *database) GetUsers() []*User {\n\treturn database.users\n}\n\nfunc (database *database) GetUser(uName string) (*User, error) {\n\tvar errMsg string\n\n\tfor _, user := range database.users {\n\t\tif (*user).GetUName() == uName {\n\t\t\treturn user, nil\n\t\t}\n\t}\n\n\terrMsg = fmt.Sprintf(\"\\\"%s\\\" username not found\", uName)\n\treturn nil, errors.New(errMsg)\n}\n\nfunc (database *database) GetPost(id string) (*Post, error) {\n\tvar errMsg string\n\n\tfor _, post := range database.posts {\n\t\tif (*post).GetID() == id {\n\t\t\treturn post, nil\n\t\t}\n\t}\n\n\terrMsg = fmt.Sprintf(\"\\\"%s\\\" id post not found\", id)\n\treturn nil, errors.New(errMsg)\n}\n\nfunc (database *database) GetUserFollowingsPosts(uName string) ([]*Post, error) {\n\tvar followingPosts []*Post\n\tvar followingsPosts []*Post = []*Post{}\n\n\tuser, err := database.GetUser(uName)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tfor _, following := range (*user).GetFollowings() {\n\t\tfollowingPosts, err = database.GetUserPosts(following)\n\t\tif err == nil {\n\t\t\tfollowingsPosts = append(followingsPosts, followingPosts...)\n\t\t}\n\t}\n\n\treturn followingsPosts, nil\n}\n\nfunc (database *database) GetUserPosts(uName string) ([]*Post, error) {\n\tvar post *Post\n\tvar userPosts []*Post = []*Post{}\n\n\tuser, err := database.GetUser(uName)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tfor _, postID := range (*user).GetPosts() {\n\t\tpost, err = database.GetPost(postID)\n\t\tif err == nil {\n\t\t\tuserPosts = append(userPosts, post)\n\t\t}\n\t}\n\n\treturn userPosts, nil\n}\n\nfunc (database *database) DeleteUser(uName string) error {\n\tvar errMsg string\n\n\tvar userI int = slices.IndexFunc(database.users, func(user *User) bool {\n\t\treturn (*user).GetUName() == uName\n\t})\n\n\tif userI == -1 {\n\t\terrMsg = fmt.Sprintf(\"\\\"%s\\\" doesn't exist\", uName)\n\t\treturn errors.New(errMsg)\n\t}\n\n\tdatabase.users = slices.Concat(database.users[0:userI], database.users[userI+1:])\n\treturn nil\n}\n\nfunc (database *database) PostUser(newUser *User) error {\n\tvar errMsg string\n\n\tvar userI int = slices.IndexFunc(database.users, func(user *User) bool {\n\t\treturn (*user).GetUName() == (*newUser).GetUName()\n\t})\n\n\tif userI != -1 {\n\t\terrMsg = fmt.Sprintf(\"\\\"%s\\\" already exists\", (*newUser).GetUName())\n\t\treturn errors.New(errMsg)\n\t}\n\n\tdatabase.users = append(database.users, newUser)\n\treturn nil\n}\n\nfunc (database *database) addNewPost(newPost *Post) {\n\tdatabase.posts = append(database.posts, newPost)\n}\n\nfunc (database *database) deletePost(postID string) error {\n\tvar errMsg string\n\n\tvar postI int = slices.IndexFunc(database.posts, func(post *Post) bool {\n\t\treturn (*post).GetID() == postID\n\t})\n\n\tif postI == -1 {\n\t\terrMsg = fmt.Sprintf(\"\\\"%s\\\" id post doesn't exist\", postID)\n\t\treturn errors.New(errMsg)\n\t}\n\n\tdatabase.posts = slices.Concat(database.posts[0:postI], database.posts[postI+1:])\n\treturn nil\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\nfunc main() {\n\tvar err error\n\tvar database Database = DatabaseInstance()\n\n\tvar reader *bufio.Reader = bufio.NewReader(os.Stdin)\n\tvar input01 int\n\tvar input02 int\n\n\tvar uName string\n\tvar postID string\n\tvar postContent string\n\n\tvar user *User\n\tvar posts []*Post\n\n\tfmt.Println(\n\t\t\"> Available operations...\\n\\n\",\n\t\t\"  1 - Sign up a new user.\\n\",\n\t\t\"  2 - Sign in as user.\\n\",\n\t\t\"  0 - Exit.\",\n\t)\n\n\tfmt.Printf(\"\\n> Enter an operation: \")\n\tfmt.Scanf(\"%d\\n\", &input01)\n\n\tfor input01 != 0 {\n\tinput01SW:\n\t\tswitch input01 {\n\t\tcase 1:\n\t\t\tfmt.Printf(\"\\n> Username: \")\n\t\t\tuName, _ = reader.ReadString('\\n')\n\t\t\tuName = strings.TrimSpace(uName)\n\n\t\t\t_user := NewUser(uName)\n\t\t\tdatabase.PostUser(&_user)\n\t\t\tbreak input01SW\n\n\t\tcase 2:\n\t\t\tfmt.Printf(\"\\n> Username: \")\n\t\t\tuName, _ = reader.ReadString('\\n')\n\t\t\tuName = strings.TrimSpace(uName)\n\n\t\t\tuser, err = database.GetUser(uName)\n\t\t\tif err != nil {\n\t\t\t\tfmt.Println(\"\\n> Username not found.\")\n\t\t\t\tbreak input01SW\n\t\t\t}\n\n\t\t\tfmt.Println(\n\t\t\t\t\"\\n> Available operations...\\n\\n\",\n\t\t\t\t\"  1 - Create a new post.\\n\",\n\t\t\t\t\"  2 - Show personal feed.\\n\",\n\t\t\t\t\"  3 - Show following feed.\\n\",\n\t\t\t\t\"  4 - Delete post.\\n\",\n\t\t\t\t\"  5 - Follow user.\\n\",\n\t\t\t\t\"  6 - Unfollow user.\\n\",\n\t\t\t\t\"  7 - Like post.\\n\",\n\t\t\t\t\"  8 - Unlike post.\\n\",\n\t\t\t\t\"  0 - Exit.\",\n\t\t\t)\n\n\t\t\tfmt.Printf(\"\\n> Enter an operation: \")\n\t\t\tfmt.Scanf(\"%d\\n\", &input02)\n\n\t\t\tfor input02 != 0 {\n\t\t\tinput02SW:\n\t\t\t\tswitch input02 {\n\t\t\t\tcase 1:\n\t\t\t\t\tfmt.Printf(\"\\n> Post content (maximum 200 characters): \")\n\t\t\t\t\tpostContent, _ = reader.ReadString('\\n')\n\t\t\t\t\tpostContent = strings.TrimSpace(postContent)\n\n\t\t\t\t\t(*user).CreatePost(postContent)\n\t\t\t\t\tbreak input02SW\n\n\t\t\t\tcase 2:\n\t\t\t\t\tposts, err = database.GetUserPosts((*user).GetUName())\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tfmt.Println(\"\\n> Error! An error occurred on get user posts.\")\n\t\t\t\t\t\tbreak input02SW\n\t\t\t\t\t}\n\n\t\t\t\t\tslices.SortFunc(posts,\n\t\t\t\t\t\tfunc(a *Post, b *Post) int {\n\t\t\t\t\t\t\tvar _a Post = *a\n\t\t\t\t\t\t\tvar _b Post = *b\n\t\t\t\t\t\t\treturn _b.GetDate().Compare(*_a.GetDate())\n\t\t\t\t\t\t})\n\n\t\t\t\t\tfor _, _post := range posts {\n\t\t\t\t\t\tfmt.Printf(\"\\n> ID: \\\"%s\\\".\\n\", (*_post).GetID())\n\t\t\t\t\t\tfmt.Printf(\"> Author: \\\"%s\\\".\\n\", (*_post).GetAuthor())\n\t\t\t\t\t\tfmt.Printf(\"> Content: \\\"%s\\\".\\n\", (*_post).GetContent())\n\t\t\t\t\t\tfmt.Printf(\"> Creation date: \\\"%s\\\".\\n\", (*_post).GetDate())\n\t\t\t\t\t\tfmt.Printf(\"> Likes: %d.\\n\", len((*_post).GetLikes()))\n\t\t\t\t\t}\n\t\t\t\t\tbreak input02SW\n\n\t\t\t\tcase 3:\n\t\t\t\t\tposts, err = database.GetUserFollowingsPosts((*user).GetUName())\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tfmt.Println(\"\\n> Error! An error occurred on get user posts.\")\n\t\t\t\t\t\tbreak input02SW\n\t\t\t\t\t}\n\n\t\t\t\t\tslices.SortFunc(posts,\n\t\t\t\t\t\tfunc(a *Post, b *Post) int {\n\t\t\t\t\t\t\tvar _a Post = *a\n\t\t\t\t\t\t\tvar _b Post = *b\n\t\t\t\t\t\t\treturn _b.GetDate().Compare(*_a.GetDate())\n\t\t\t\t\t\t})\n\n\t\t\t\t\tfor _, _post := range posts {\n\t\t\t\t\t\tfmt.Printf(\"\\n> ID: \\\"%s\\\".\\n\", (*_post).GetID())\n\t\t\t\t\t\tfmt.Printf(\"> Author: \\\"%s\\\".\\n\", (*_post).GetAuthor())\n\t\t\t\t\t\tfmt.Printf(\"> Content: \\\"%s\\\".\\n\", (*_post).GetContent())\n\t\t\t\t\t\tfmt.Printf(\"> Creation date: \\\"%s\\\".\\n\", (*_post).GetDate())\n\t\t\t\t\t\tfmt.Printf(\"> Likes: %d.\\n\", len((*_post).GetLikes()))\n\t\t\t\t\t}\n\t\t\t\t\tbreak input02SW\n\n\t\t\t\tcase 4:\n\t\t\t\t\tfmt.Printf(\"\\n> Post ID: \")\n\t\t\t\t\tpostID, _ = reader.ReadString('\\n')\n\t\t\t\t\tpostID = strings.TrimSpace(postID)\n\n\t\t\t\t\t(*user).DeletePost(postID)\n\t\t\t\t\tbreak input02SW\n\n\t\t\t\tcase 5:\n\t\t\t\t\tfmt.Printf(\"\\n> Username: \")\n\t\t\t\t\tuName, _ = reader.ReadString('\\n')\n\t\t\t\t\tuName = strings.TrimSpace(uName)\n\n\t\t\t\t\t(*user).Follow(uName)\n\t\t\t\t\tbreak input02SW\n\n\t\t\t\tcase 6:\n\t\t\t\t\tfmt.Printf(\"\\n> Username: \")\n\t\t\t\t\tuName, _ = reader.ReadString('\\n')\n\t\t\t\t\tuName = strings.TrimSpace(uName)\n\n\t\t\t\t\t(*user).Unfollow(uName)\n\t\t\t\t\tbreak input02SW\n\n\t\t\t\tcase 7:\n\t\t\t\t\tfmt.Printf(\"\\n> Post ID: \")\n\t\t\t\t\tpostID, _ = reader.ReadString('\\n')\n\t\t\t\t\tpostID = strings.TrimSpace(postID)\n\n\t\t\t\t\t(*user).LikePost(postID)\n\t\t\t\t\tbreak input02SW\n\n\t\t\t\tcase 8:\n\t\t\t\t\tfmt.Printf(\"\\n> Post ID: \")\n\t\t\t\t\tpostID, _ = reader.ReadString('\\n')\n\t\t\t\t\tpostID = strings.TrimSpace(postID)\n\n\t\t\t\t\t(*user).UnlikePost(postID)\n\t\t\t\t\tbreak input02SW\n\n\t\t\t\tdefault:\n\t\t\t\t\tfmt.Println(\"\\n> Invalid operation! Try again...\")\n\t\t\t\t}\n\n\t\t\t\tfmt.Println(\n\t\t\t\t\t\"\\n> Available operations...\\n\\n\",\n\t\t\t\t\t\"  1 - Create a new post.\\n\",\n\t\t\t\t\t\"  2 - Show personal feed.\\n\",\n\t\t\t\t\t\"  3 - Show following feed.\\n\",\n\t\t\t\t\t\"  4 - Delete post.\\n\",\n\t\t\t\t\t\"  5 - Follow user.\\n\",\n\t\t\t\t\t\"  6 - Unfollow user.\\n\",\n\t\t\t\t\t\"  7 - Like post.\\n\",\n\t\t\t\t\t\"  8 - Unlike post.\\n\",\n\t\t\t\t\t\"  0 - Exit.\",\n\t\t\t\t)\n\n\t\t\t\tfmt.Printf(\"\\n> Enter an operation: \")\n\t\t\t\tfmt.Scanf(\"%d\\n\", &input02)\n\t\t\t}\n\t\t\tbreak input01SW\n\n\t\tdefault:\n\t\t\tfmt.Println(\"\\n> Invalid operation! Try again...\")\n\t\t}\n\n\t\tfmt.Println(\n\t\t\t\"\\n> Available operations...\\n\\n\",\n\t\t\t\"  1 - Sign up a new user.\\n\",\n\t\t\t\"  2 - Sign in as user.\\n\",\n\t\t\t\"  0 - Exit.\",\n\t\t)\n\n\t\tfmt.Printf(\"\\n> Enter an operation: \")\n\t\tfmt.Scanf(\"%d\\n\", &input01)\n\t}\n}\n"
  },
  {
    "path": "Roadmap/46 - X VS BLUESKY/java/JohnAlexGuerrero.java",
    "content": "package org.example;\n\nimport java.util.HashSet;\nimport java.util.Objects;\n\n// Press Shift twice to open the Search Everywhere dialog and type `show whitespaces`,\n// then press Enter. You can now see whitespace characters in your code.\npublic class Main {\n    public static void main(String[] args) {\n        SocialNetwork socialnetwork = new SocialNetwork();\n\n        //- Registrar un usuario por defecto con nombre e identificador único.\n        socialnetwork.registerUser(\"u123\", \"alexander guerrero\");\n        socialnetwork.registerUser(\"u456\", \"sandra estacio\");\n        socialnetwork.registerUser(\"u467\", \"carolina maigual\");\n        socialnetwork.registerUser(\"u897\", \"mileidy cruz\");\n        socialnetwork.registerUser(\"u230\", \"daniel botina\");\n        socialnetwork.registerUser(\"u239\", \"diego botina\");\n        socialnetwork.registerUser(\"u348\", \"gloria maigual\");\n        socialnetwork.registerUser(\"u438\", \"teresa maigual\");\n        socialnetwork.registerUser(\"u489\", \"alejandra rojas\");\n\n        //- Seleccionar un usuario\n        User u1 = socialnetwork.getUser(\"u489\");\n        //- Un usuario puede seguir/dejar de seguir a otro.\n        u1.followUser(\"u348\");\n        u1.followUser(\"u467\");\n        u1.followUser(\"u897\");\n\n        //- Mostrar usuarios\n        for (User user : socialnetwork.getUsers()) {\n            System.out.println(user.toString());\n        }\n    }\n}\n\nclass SocialNetwork{\n    private static HashSet<User> users;\n    public SocialNetwork() {\n        users = new HashSet<>();\n    }\n    public void registerUser(String id, String name){\n        users.add(new User(id, name));\n    }\n    public User getUser(String id){\n        for(User user: users){\n            if(user.getId().equals(id)){\n                return user;\n            }\n        }\n        return null;\n    }\n    public void unfollowUser(){}\n    public HashSet<User> getUsers() {\n        return users;\n    }\n}\n\nclass User{\n    private String id;\n    private String name;\n    private HashSet<String> followers;\n    private HashSet<String> following;\n    public void followUser(String followIdUser){\n        followers.add(followIdUser);\n    }\n\n    public User(String id, String name) {\n        this.id = id;\n        this.name = name;\n        this.followers = new HashSet<String>();\n        this.following = new HashSet<String>();\n    }\n\n    public String getId() {\n        return id;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public HashSet<String> getFollowers() {\n        return followers;\n    }\n\n    public HashSet<String> getFollowing() {\n        return following;\n    }\n\n    @Override\n    public String toString() {\n        return \"User{\" +\n                \"id='\" + id + '\\'' +\n                \", name='\" + name + '\\'' +\n                \", followers=\" + followers +\n                \", following=\" + following +\n                '}';\n    }\n\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) return true;\n        if (o == null || getClass() != o.getClass()) return false;\n        User user = (User) o;\n        return Objects.equals(id, user.id) && Objects.equals(name, user.name) && Objects.equals(followers, user.followers) && Objects.equals(following, user.following);\n    }\n\n    @Override\n    public int hashCode() {\n        return Objects.hash(id, name, followers, following);\n    }\n}\n"
  },
  {
    "path": "Roadmap/46 - X VS BLUESKY/java/Josegs95.java",
    "content": "import java.time.LocalDateTime;\nimport java.time.ZoneOffset;\nimport java.time.format.DateTimeFormatter;\nimport java.util.*;\n\npublic class Josegs95 {\n    public static void main(String[] args) {\n        new Josegs95().socialNetwork();\n    }\n\n    private Integer userIDCount = 1;\n    private Integer postIDCount = 1;\n    private List<User> userList;\n\n    public void socialNetwork(){\n        User user1 = createUser(\"Jose\");\n        User user2 = createUser(\"María\");\n        User user3 = createUser(\"Ramón\");\n        User user4 = createUser(\"Daniel\");\n        User user5 = createUser(\"Yolanda\");\n        userList = Arrays.asList(user1, user2, user3, user4, user5);\n\n        followUser(user1, user2);\n        followUser(user1, user5);\n        followUser(user2, user1);\n        followUser(user2, user3);\n        followUser(user2, user4);\n        followUser(user2, user5);\n        followUser(user3, user5);\n        followUser(user4, user5);\n        followUser(user5, user2);\n        followUser(user5, user3);\n\n        unfollowUser(user4, user5);\n\n        generatePosts();\n\n        for (Post post : user2.getPostList()){\n            likePost(user1, post);\n            likePost(user2, post);\n        }\n        for (User user : userList)\n            likePost(user, user1.getPostList().get(2));\n        likePost(user5, user2.getPostList().get(1));\n\n        unlikePost(user4, user2.getPostList().get(1));\n        likePost(user4, user2.getPostList().get(1));\n        unlikePost(user4, user2.getPostList().get(1));\n\n        for(User user : userList){\n            printOwnFeed(user);\n            printUserFeed(user);\n        }\n    }\n    private User createUser(String name){\n        return new User(userIDCount++, name);\n    }\n\n    private boolean followUser(User user, User following){\n        if (user == null || following == null)\n            return false;\n\n        return user.follow(following);\n    }\n\n    private boolean unfollowUser(User user, User unfollowing){\n        if (user == null || unfollowing == null)\n            return false;\n\n        return user.unfollow(unfollowing);\n    }\n\n    private void createPost(User owner, String text, Integer postId){\n        if (text.length() > 200){\n            System.out.println(\"El texto es demasiado largo (max 200).\");\n            return;\n        }\n        owner.createPost(text, postId);\n    }\n\n    private void deletePost(User owner, Post post){\n        if (!post.getOwner().equals(owner)){\n            System.out.println(\"El usuario \" + owner + \" no es el creador del post\");\n            return;\n        }\n        owner.deletePost(post);\n    }\n\n    private boolean likePost(User user, Post post){\n        if (user == null || post == null)\n            return false;\n\n        return user.like(post);\n    }\n\n    private boolean unlikePost(User user, Post post){\n        if (user == null || post == null)\n            return false;\n\n        return user.unlike(post);\n    }\n\n    private void printOwnFeed(User user){\n        List<Post> posts = getLatestPosts(Arrays.asList(user), 10);\n        System.out.println(\"Imprimiendo la feed de: \" + user);\n\n        if (posts.size() == 0){\n            System.out.println(\"No hay nada :( ¡Escribe tu primer post!\\n\");\n            return;\n        }\n        printPosts(posts);\n    }\n\n    private void printUserFeed(User user){\n        List<Post> posts = getLatestPosts(user.getFollowingUsers(), 10);\n        System.out.println(\"Imprimiendo la feed de los usuarios que sigue: \" + user);\n\n        if (posts.size() == 0){\n            System.out.println(\"No hay nada :( Sigue a usuarios para ver sus posts\\n\");\n            return;\n        }\n        printPosts(posts);\n    }\n\n    private void printPosts(List<Post> posts){\n        for (Post post : posts){\n            System.out.println(\"==============================\");\n            System.out.println(\"Usuario: \" + post.getOwner());\n            System.out.println(\"'\" + post.getText() + \"' Likes: \" + post.getLikesCount()\n                    + \" Fecha de creación: \" + post.getCreationDateFormatted());\n            System.out.println(\"==============================\");\n        }\n        System.out.println(\"\\n\");\n    }\n\n    private List<Post> getLatestPosts(List<User> users, int limit){\n        List<Post> posts = new ArrayList<>();\n        for (User user : users){\n            posts.addAll(user.getPostList());\n        }\n\n        posts.sort(Comparator.comparing(Post::getCreationDate).reversed());\n        if (posts.size() > limit)\n            posts = posts.subList(0, limit);\n\n        return posts;\n    }\n\n    //Lo hago de esta manera tan complicada para poder automatizar los post y así dormir el\n    //hilo principal para que se creen los post a diferentes fechas\n    private void generatePosts(){\n        List<Object[]> postToCreate = new ArrayList<>();\n        postToCreate.add(new Object[]{userList.get(0), \"Mi primer post\"});\n        postToCreate.add(new Object[]{userList.get(0), \"Mi segundo post\"});\n        postToCreate.add(new Object[]{userList.get(1), \"Hola a todos\"});\n        postToCreate.add(new Object[]{userList.get(3), \"Hola, soy nuevo\"});\n        for (int i = 1; i < 21; i++)\n            postToCreate.add(new Object[]{userList.get(4), \"Buenos días, hoy es \" + i + \" de Diciembre\"});\n        postToCreate.add(new Object[]{userList.get(1), \"Hoy empiezo el gym\"});\n        postToCreate.add(new Object[]{userList.get(0), \"Ya llega la Navidad\"});\n\n        try{\n            for (Object[] post : postToCreate) {\n                createPost((User) post[0], (String) post[1], postIDCount++);\n                Thread.sleep(100);\n            }\n        } catch (InterruptedException e) {\n            throw new RuntimeException(e);\n        }\n\n        deletePost(userList.get(1), userList.get(1).getPostList().get(1));\n        createPost(userList.get(1), \"Al final se cancela lo del gym, !A comer polvorones¡\", postIDCount++);\n    }\n\n    public class User{\n        final private Integer ID;\n        private String name;\n        private List<User> followingUsers;\n        private List<Post> postList;\n        private List<Post> likedPosts;\n\n        public User(Integer id, String name) {\n            this.ID = id;\n            this.name = name;\n            followingUsers = new ArrayList<>();\n            postList = new ArrayList<>();\n            likedPosts = new ArrayList<>();\n        }\n\n        public boolean follow(User user){\n            if (!this.equals(user) && !followingUsers.contains(user))\n                return followingUsers.add(user);\n            return false;\n        }\n\n        public boolean unfollow(User user){\n            return followingUsers.remove(user);\n        }\n\n        public boolean createPost(String text, Integer idPost){\n            return postList.add(new Post(idPost, text,\n                    LocalDateTime.now(ZoneOffset.UTC), this));\n        }\n\n        public boolean deletePost(Post post){\n            return postList.remove(post);\n        }\n\n        public boolean like(Post post){\n            if (!likedPosts.contains(post)){\n                post.like();\n                return likedPosts.add(post);\n            }\n            return false;\n        }\n\n        public boolean unlike(Post post){\n            if (likedPosts.contains(post))\n                post.deleteLike();\n            return likedPosts.remove(post);\n        }\n\n        public Integer getID() {\n            return ID;\n        }\n\n        public String getName() {\n            return name;\n        }\n\n        public List<Post> getPostList() {\n            return postList;\n        }\n\n        public List<User> getFollowingUsers() {\n            return followingUsers;\n        }\n\n        @Override\n        public String toString(){\n            return name + \" (ID:\" + ID + \")\";\n        }\n\n        @Override\n        public boolean equals(Object o) {\n            if (this == o) return true;\n            if (!(o instanceof User user)) return false;\n            return Objects.equals(ID, user.ID);\n        }\n\n        @Override\n        public int hashCode() {\n            return Objects.hash(ID, name, followingUsers, postList, likedPosts);\n        }\n    }\n\n    public class Post{\n        final private Integer ID;\n        private String text;\n        private LocalDateTime creationDate;\n        private Integer likesCount;\n        private User owner;\n\n        public Post(Integer id, String text, LocalDateTime creationDate, User owner) {\n            this.ID = id;\n            this.text = text;\n            this.creationDate = creationDate;\n            this.owner = owner;\n            likesCount = 0;\n        }\n\n        public void like(){\n            likesCount++;\n        }\n\n        public void deleteLike(){\n            likesCount--;\n        }\n\n        public Integer getID() {\n            return ID;\n        }\n\n        public String getText() {\n            return text;\n        }\n\n        public LocalDateTime getCreationDate() {\n            return creationDate;\n        }\n\n        public String getCreationDateFormatted(){\n            return creationDate.format(DateTimeFormatter.ofPattern(\"dd-MM-yyyy kk:mm:ss 'UTC'\"));\n        }\n\n        public User getOwner() {\n            return owner;\n        }\n\n        public Integer getLikesCount() {\n            return likesCount;\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/46 - X VS BLUESKY/java/MohamedElderkaoui.java",
    "content": "import java.time.LocalDateTime;\nimport java.util.ArrayList;\nimport java.util.Comparator;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.InputMismatchException;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Optional;\nimport java.util.Scanner;\nimport java.util.Set;\nimport java.util.UUID;\nimport java.util.stream.Collectors;\n\npublic class MohamedElderkaoui {\n    private static final Map<String, User> users = new HashMap<>();\n    private static final Scanner scanner = new Scanner(System.in);\n\n    public static void main(String[] args) {\n        System.out.println(\"¡Bienvenido a la red social descentralizada!\");\n        int option;\n\n        do {\n            System.out.println(\"\\nMenú:\");\n            System.out.println(\"1. Registrar usuario\");\n            System.out.println(\"2. Seguir a un usuario\");\n            System.out.println(\"3. Dejar de seguir a un usuario\");\n            System.out.println(\"4. Crear un post\");\n            System.out.println(\"5. Eliminar un post\");\n            System.out.println(\"6. Dar like a un post\");\n            System.out.println(\"7. Eliminar like de un post\");\n            System.out.println(\"8. Ver mi feed\");\n            System.out.println(\"9. Ver feed de usuarios seguidos\");\n            System.out.println(\"10. Listar usuarios registrados\"); // New Option\n            System.out.println(\"11. Salir\");\n            System.out.print(\"Seleccione una opción: \");\n            try {\n                option = scanner.nextInt();\n            } catch (InputMismatchException e) {\n                System.out.println(\"Entrada inválida. Por favor ingrese un número.\");\n                scanner.nextLine(); // limpiar el buffer del scanner\n                option = -1; // opción inválida para continuar el bucle\n            }\n            scanner.nextLine(); // Consumir la línea\n\n            switch (option) {\n                case 1 -> registerUser();\n                case 2 -> followUser();\n                case 3 -> unfollowUser();\n                case 4 -> createPost();\n                case 5 -> deletePost();\n                case 6 -> likePost();\n                case 7 -> unlikePost();\n                case 8 -> viewMyFeed();\n                case 9 -> viewFollowingFeed();\n                case 10 -> listUsers(); // Call the new method\n                case 11 -> System.out.println(\"Saliendo de la red social...\");\n                default -> System.out.println(\"Opción inválida. Intente nuevamente.\");\n            }\n        } while (option != 11);\n    }\n\n    private static void registerUser() {\n        System.out.print(\"Ingrese el nombre de usuario: \");\n        String name = scanner.nextLine();\n        if (users.containsKey(name)) {\n            System.out.println(\"Error: El usuario ya existe.\");\n        } else {\n            User newUser = new User(name);\n            users.put(name, newUser);\n            System.out.println(\"Usuario registrado exitosamente: \" + name);\n        }\n    }\n\n    private static void followUser() {\n        User user = findUser(\"Tu nombre de usuario: \");\n        User toFollow = findUser(\"Nombre del usuario a seguir: \");\n        if (user != null && toFollow != null) {\n            user.follow(toFollow);\n            System.out.println(\"Ahora sigues a \" + toFollow.getName());\n        }\n    }\n\n    private static void unfollowUser() {\n        User user = findUser(\"Tu nombre de usuario: \");\n        User toUnfollow = findUser(\"Nombre del usuario a dejar de seguir: \");\n        if (user != null && toUnfollow != null) {\n            user.unfollow(toUnfollow);\n            System.out.println(\"Has dejado de seguir a \" + toUnfollow.getName());\n        }\n    }\n\n    private static void createPost() {\n        User user = findUser(\"Tu nombre de usuario: \");\n        if (user != null) {\n            System.out.print(\"Ingrese el texto del post (máximo 200 caracteres): \");\n            String text = scanner.nextLine();\n            if (text.length() > 200) {\n                System.out.println(\"Error: El texto excede los 200 caracteres.\");\n            } else {\n                Post post = new Post(user, text);\n                user.addPost(post);\n                System.out.println(\"Post creado exitosamente: \" + post);\n            }\n        }\n    }\n\n    private static void deletePost() {\n        User user = findUser(\"Tu nombre de usuario: \");\n        if (user != null) {\n            System.out.print(\"Ingrese el ID del post a eliminar: \");\n            String postId = scanner.nextLine();\n            boolean success = user.deletePost(postId);\n            if (success) {\n                System.out.println(\"Post eliminado exitosamente.\");\n            } else {\n                System.out.println(\"Error: No se encontró el post con ese ID.\");\n            }\n        }\n    }\n\n    private static void likePost() {\n        User user = findUser(\"Tu nombre de usuario: \");\n        if (user != null) {\n            // Pedir el nombre del autor del post\n            System.out.print(\"Ingrese el nombre del usuario que publicó el post: \");\n            String authorName = scanner.nextLine();\n            User author = users.get(authorName);\n\n            if (author != null) {\n                // Pedir el número del post en el feed del autor\n                System.out.print(\"Ingrese el número del post que desea dar like (1 para el primero, 2 para el segundo, etc.): \");\n                int postNumber;\n                try {\n                    postNumber = scanner.nextInt();\n                    scanner.nextLine(); // Limpiar el buffer\n                    List<Post> posts = author.getPosts();\n                    \n                    // Validar el número de post\n                    if (postNumber > 0 && postNumber <= posts.size()) {\n                        Post post = posts.get(postNumber - 1); // Ajustar el índice (es 0-based)\n                        post.addLike(user);\n                        System.out.println(\"Diste like al post de \" + author.getName());\n                    } else {\n                        System.out.println(\"Error: Número de post inválido.\");\n                    }\n                } catch (InputMismatchException e) {\n                    System.out.println(\"Entrada inválida. Por favor ingrese un número.\");\n                    scanner.nextLine(); // Limpiar el buffer\n                }\n            } else {\n                System.out.println(\"Error: Usuario no encontrado.\");\n            }\n        }\n    }\n\n    private static void unlikePost() {\n        User user = findUser(\"Tu nombre de usuario: \");\n        if (user != null) {\n            System.out.print(\"Ingrese el ID del post a eliminar like: \");\n            String postId = scanner.nextLine();\n            Post post = findPost(postId);\n            if (post != null) {\n                post.removeLike(user);\n                System.out.println(\"Eliminaste tu like del post.\");\n            } else {\n                System.out.println(\"Error: No se encontró el post con ese ID.\");\n            }\n        }\n    }\n\n    private static void viewMyFeed() {\n        User user = findUser(\"Tu nombre de usuario: \");\n        if (user != null) {\n            System.out.println(\"Tu feed:\");\n            user.getMyFeed().forEach(System.out::println);\n        }\n    }\n\n    private static void viewFollowingFeed() {\n        User user = findUser(\"Tu nombre de usuario: \");\n        if (user != null) {\n            System.out.println(\"Feed de usuarios que sigues:\");\n            user.getFollowingFeed().forEach(System.out::println);\n        }\n    }\n\n    private static void listUsers() {\n        if (users.isEmpty()) {\n            System.out.println(\"No hay usuarios registrados actualmente.\");\n        } else {\n            System.out.println(\"Usuarios registrados:\");\n            users.values().forEach(user -> System.out.println(\"- \" + user.getName() + \" (ID: \" + user.getId() + \")\"));\n        }\n    }\n\n    private static User findUser(String prompt) {\n        System.out.print(prompt);\n        String name = scanner.nextLine();\n        User user = users.get(name);\n        if (user == null) {\n            System.out.println(\"Error: Usuario no encontrado.\");\n        }\n        return user;\n    }\n\n    private static Post findPost(String postId) {\n        for (User user : users.values()) {\n            Optional<Post> post = user.getPosts().stream()\n                                      .filter(p -> p.getId().equals(postId))\n                                      .findFirst();\n            if (post.isPresent()) {\n                return post.get();\n            }\n        }\n        return null;\n    }\n}\n\nclass User {\n    private final String id;\n    private final String name;\n    private final List<User> following = new ArrayList<>();\n    private final List<Post> posts = new ArrayList<>();\n\n    public User(String name) {\n        this.id = UUID.randomUUID().toString();\n        this.name = name;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public String getId() {\n        return id;\n    }\n\n    public List<Post> getPosts() {\n        return posts;\n    }\n\n    public void follow(User user) {\n        if (!following.contains(user)) {\n            following.add(user);\n        }\n    }\n\n    public void unfollow(User user) {\n        following.remove(user);\n    }\n\n    public void addPost(Post post) {\n        posts.add(post);\n    }\n\n    public boolean deletePost(String postId) {\n        return posts.removeIf(post -> post.getId().equals(postId));\n    }\n\n    public List<Post> getMyFeed() {\n        return posts.stream()\n                    .sorted(Comparator.comparing(Post::getCreationDate).reversed())\n                    .limit(10)\n                    .collect(Collectors.toList());\n    }\n\n    public List<Post> getFollowingFeed() {\n        return following.stream()\n                        .flatMap(user -> user.getPosts().stream())\n                        .sorted(Comparator.comparing(Post::getCreationDate).reversed())\n                        .limit(10)\n                        .collect(Collectors.toList());\n    }\n}\n\nclass Post {\n    private final String id;\n    private final User user;\n    private final String content;\n    private final LocalDateTime creationDate;\n    private final Set<User> likes = new HashSet<>();\n\n    public Post(User user, String content) {\n        this.id = UUID.randomUUID().toString();\n        this.user = user;\n        this.content = content;\n        this.creationDate = LocalDateTime.now();\n    }\n\n    public String getId() {\n        return id;\n    }\n\n    public LocalDateTime getCreationDate() {\n        return creationDate;\n    }\n\n    public void addLike(User user) {\n        likes.add(user);\n    }\n\n    public void removeLike(User user) {\n        likes.remove(user);\n    }\n\n    @Override\n    public String toString() {\n        return \"Post de \" + user.getName() + \": \" + content + \" | Likes: \" + likes.size();\n    }\n}\n"
  },
  {
    "path": "Roadmap/46 - X VS BLUESKY/java/asjordi.java",
    "content": "import lombok.*;\nimport java.time.LocalDate;\nimport java.util.*;\nimport java.util.UUID;\n\npublic class Main {\n\n    public static void main(String[] args) {\n        // Register users\n        User pedro = new User(\"Pedro\");\n        User juan = new User(\"Juan\");\n        User maria = new User(\"Maria\");\n        User ana = new User(\"Ana\");\n\n        // Follow users\n        pedro.follow(juan);\n        pedro.follow(maria);\n        pedro.follow(ana);\n\n        // Create post\n        Post postJava = new Post(\"Java ...\", LocalDate.of(2024, 1, 1));\n        Post postJs = new Post(\"JavaScript ...\", LocalDate.of(2024, 2, 1));\n        Post postPython = new Post(\"Python ...\", LocalDate.of(2024, 3, 1));\n        Post postSql = new Post(\"SQL ...\", LocalDate.of(2024, 4, 1));\n        Post postNginx = new Post(\"Nginx ...\", LocalDate.of(2024, 5, 1));\n        Post postDocker = new Post(\"Docker ...\", LocalDate.of(2024, 6, 1));\n        Post postKubernetes = new Post(\"Kubernetes ...\", LocalDate.of(2024, 7, 1));\n        Post postUbuntu = new Post(\"Ubuntu ...\", LocalDate.of(2024, 8, 1));\n        Post postCertbot = new Post(\"Certbot ...\", LocalDate.of(2024, 9, 1));\n        Post postCloudflare = new Post(\"Cloudflare ...\", LocalDate.of(2024, 10, 1));\n        Post postGithub = new Post(\"Github ...\", LocalDate.of(2024, 11, 1));\n        Post postGitlab = new Post(\"Gitlab ...\", LocalDate.of(2024, 12, 1));\n\n        pedro.createPost(postJava);\n        pedro.createPost(postJs);\n        pedro.createPost(postPython);\n        juan.createPost(postSql);\n        juan.createPost(postNginx);\n        juan.createPost(postDocker);\n        maria.createPost(postKubernetes);\n        maria.createPost(postUbuntu);\n        maria.createPost(postCertbot);\n        ana.createPost(postCloudflare);\n        ana.createPost(postGithub);\n        ana.createPost(postGitlab);\n\n        // Delete post\n        pedro.deletePost(postPython.getId());\n\n        // Like / Dislike\n        pedro.getPosts().get(0).like(juan);\n        pedro.getPosts().get(0).like(maria);\n        pedro.getPosts().get(0).like(ana);\n        pedro.getPosts().get(1).like(juan);\n        pedro.getPosts().get(1).like(maria);\n        pedro.getPosts().get(1).like(ana);\n        pedro.getPosts().get(1).dislike(ana);\n\n        // Show user posts\n        pedro.showPosts();\n\n        // Show feed\n        pedro.showFeed();\n\n    }\n\n    @Getter\n    @ToString\n    @EqualsAndHashCode\n    static class Post {\n        private final UUID id = UUID.randomUUID();\n        private String content;\n        private LocalDate pubDate;\n        @Setter\n        private User user;\n        private final List<User> likes = new ArrayList<>();\n\n        public Post(String content, LocalDate pubDate) {\n            if (content.length() > 200) throw new IllegalArgumentException(\"Post content must be less than 200 characters\");\n            this.content = content;\n            this.pubDate = pubDate;\n        }\n\n        public boolean like(User user) {\n            if (this.likes.contains(user)) return false;\n            this.likes.add(user);\n            return true;\n        }\n\n        public boolean dislike(User user) {\n            return this.likes.remove(user);\n        }\n\n        public int getLikes() {\n            return this.likes.size();\n        }\n    }\n\n    @Data\n    @AllArgsConstructor\n    @NoArgsConstructor\n    static class User {\n        private final UUID id = UUID.randomUUID();\n        private String username;\n        private final List<User> following = new ArrayList<>();\n        private final List<Post> posts = new ArrayList<>();\n\n        public boolean follow(User user) {\n            return this.following.add(user);\n        }\n\n        public boolean unfollow(User user) {\n            return this.following.remove(user);\n        }\n\n        public boolean createPost(Post post) {\n            post.setUser(this);\n            return this.posts.add(post);\n        }\n\n        public boolean deletePost(UUID id) {\n            return this.posts.removeIf(p -> p.getId().equals(id));\n        }\n\n        public void showPosts() {\n            this.posts.sort(Comparator.comparing(Post::getPubDate).reversed());\n            System.out.println(this.username + \" posts:\");\n            printPosts(this.posts);\n        }\n\n        public void showFeed() {\n            List<Post> post = new ArrayList<>();\n            this.following.stream()\n                    .map(User::getPosts)\n                    .forEach(post::addAll);\n\n            post.sort(Comparator.comparing(Post::getPubDate).reversed());\n            System.out.println(this.username + \" feed:\");\n            printPosts(post);\n        }\n\n        private void printPosts(List<Post> list) {\n            list.stream()\n                    .limit(10)\n                    .forEach(p -> System.out.println(\n                            \"{\" +\n                                    \"userId=\" + this.id +\n                                    \", username=\" + this.username +\n                                    \", content=\" + p.getContent() +\n                                    \", pubDate=\" + p.getPubDate() +\n                                    \", likes=\" + p.getLikes() +\n                                    \"}\"\n                    ));\n        }\n\n        public void printFollowing() {\n            System.out.println(this.username + \" is following:\");\n            this.following.forEach(user -> System.out.println(user.getUsername()));\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/46 - X VS BLUESKY/java/miguelex.java",
    "content": "import java.util.*;\n\nclass SocialNetwork {\n    private Map<Integer, String> users = new HashMap<>();\n    private Map<Integer, Post> posts = new HashMap<>();\n    private Map<Integer, Set<Integer>> follows = new HashMap<>();\n    private Map<Integer, Set<Integer>> likes = new HashMap<>();\n\n    public void registerUser(int userId, String username) {\n        if (users.containsKey(userId)) {\n            System.out.println(\"El usuario con ID \" + userId + \" ya existe.\");\n        } else {\n            users.put(userId, username);\n            System.out.println(\"Usuario \" + username + \" registrado con éxito.\");\n        }\n    }\n\n    public void followUser(int followerId, int followeeId) {\n        if (!users.containsKey(followerId) || !users.containsKey(followeeId)) {\n            System.out.println(\"Uno de los usuarios no existe.\");\n            return;\n        }\n        follows.putIfAbsent(followerId, new HashSet<>());\n        follows.get(followerId).add(followeeId);\n        System.out.println(\"Usuario \" + followerId + \" ahora sigue a \" + followeeId + \".\");\n    }\n\n    public void unfollowUser(int followerId, int followeeId) {\n        if (follows.containsKey(followerId) && follows.get(followerId).contains(followeeId)) {\n            follows.get(followerId).remove(followeeId);\n            System.out.println(\"Usuario \" + followerId + \" ha dejado de seguir a \" + followeeId + \".\");\n        } else {\n            System.out.println(\"El usuario \" + followerId + \" no sigue a \" + followeeId + \".\");\n        }\n    }\n\n    public void createPost(int userId, int postId, String text) {\n        if (!users.containsKey(userId)) {\n            System.out.println(\"El usuario no existe.\");\n            return;\n        }\n        if (text.length() > 200) {\n            System.out.println(\"El texto del post excede los 200 caracteres.\");\n            return;\n        }\n        String username = users.get(userId);\n        posts.put(postId, new Post(userId, username, postId, text));\n        System.out.println(\"Post creado con éxito.\");\n    }\n\n    public void deletePost(int postId) {\n        if (posts.containsKey(postId)) {\n            posts.remove(postId);\n            System.out.println(\"Post eliminado con éxito.\");\n        } else {\n            System.out.println(\"El post no existe.\");\n        }\n    }\n\n    public void likePost(int userId, int postId) {\n        if (!users.containsKey(userId)) {\n            System.out.println(\"El usuario no existe.\");\n            return;\n        }\n        if (!posts.containsKey(postId)) {\n            System.out.println(\"El post no existe.\");\n            return;\n        }\n        likes.putIfAbsent(userId, new HashSet<>());\n        if (likes.get(userId).add(postId)) {\n            posts.get(postId).incrementLikes();\n            System.out.println(\"Like añadido al post \" + postId + \".\");\n        } else {\n            System.out.println(\"Ya has hecho like en este post.\");\n        }\n    }\n\n    public void unlikePost(int userId, int postId) {\n        if (likes.containsKey(userId) && likes.get(userId).remove(postId)) {\n            posts.get(postId).decrementLikes();\n            System.out.println(\"Like eliminado del post \" + postId + \".\");\n        } else {\n            System.out.println(\"El usuario no ha hecho like en el post \" + postId + \".\");\n        }\n    }\n\n    public void viewUserFeed(int userId) {\n        if (!users.containsKey(userId)) {\n            System.out.println(\"El usuario no existe.\");\n            return;\n        }\n        List<Post> userPosts = new ArrayList<>();\n        for (Post post : posts.values()) {\n            if (post.getUserId() == userId) {\n                userPosts.add(post);\n            }\n        }\n        userPosts.sort(Comparator.comparing(Post::getCreatedAt).reversed());\n        userPosts.stream().limit(10).forEach(post -> {\n            System.out.println(post);\n        });\n    }\n\n    public void viewFollowedFeed(int userId) {\n        if (!users.containsKey(userId)) {\n            System.out.println(\"El usuario no existe.\");\n            return;\n        }\n        List<Post> followedPosts = new ArrayList<>();\n        if (follows.containsKey(userId)) {\n            for (Integer followeeId : follows.get(userId)) {\n                for (Post post : posts.values()) {\n                    if (post.getUserId() == followeeId) {\n                        followedPosts.add(post);\n                    }\n                }\n            }\n        }\n        followedPosts.sort(Comparator.comparing(Post::getCreatedAt).reversed());\n        followedPosts.stream().limit(10).forEach(post -> {\n            System.out.println(post);\n        });\n    }\n\n    public String getUsername(int userId) {\n        return users.get(userId);\n    }\n}\n\nclass Post {\n    private int userId;\n    private String username;\n    private int postId;\n    private String text;\n    private String createdAt;\n    private int likes;\n\n    public Post(int userId, String username, int postId, String text) {\n        this.userId = userId;\n        this.username = username;\n        this.postId = postId;\n        this.text = text;\n        this.createdAt = new Date().toString();\n        this.likes = 0;\n    }\n\n    public int getUserId() {\n        return userId;\n    }\n\n    public String getCreatedAt() {\n        return createdAt;\n    }\n\n    public void incrementLikes() {\n        likes++;\n    }\n\n    public void decrementLikes() {\n        likes--;\n    }\n\n    @Override\n    public String toString() {\n        return \"ID: \" + userId + \", Usuario: \" + username + \", Texto: \" + text + \", Fecha: \" + createdAt + \", Likes: \" + likes;\n    }\n}\n\npublic class miguelex {\n    public static void main(String[] args) {\n        SocialNetwork network = new SocialNetwork();\n        Scanner scanner = new Scanner(System.in);\n\n        while (true) {\n            System.out.println(\"Seleccione una opción:\");\n            System.out.println(\"1. Registrar usuario\");\n            System.out.println(\"2. Seguir a un usuario\");\n            System.out.println(\"3. Dejar de seguir a un usuario\");\n            System.out.println(\"4. Crear post\");\n            System.out.println(\"5. Eliminar post\");\n            System.out.println(\"6. Hacer like en un post\");\n            System.out.println(\"7. Eliminar like de un post\");\n            System.out.println(\"8. Ver feed del usuario\");\n            System.out.println(\"9. Ver feed de usuarios seguidos\");\n            System.out.println(\"0. Salir\");\n            System.out.print(\"Opción: \");\n\n            int option = scanner.nextInt();\n            scanner.nextLine();  // Consumir la nueva línea\n\n            switch (option) {\n                case 1:\n                    System.out.print(\"ID de usuario: \");\n                    int userId = scanner.nextInt();\n                    scanner.nextLine();\n                    System.out.print(\"Nombre de usuario: \");\n                    String username = scanner.nextLine();\n                    network.registerUser(userId, username);\n                    break;\n                case 2:\n                    System.out.print(\"ID del seguidor: \");\n                    int followerId = scanner.nextInt();\n                    System.out.print(\"ID del seguido: \");\n                    int followeeId = scanner.nextInt();\n                    network.followUser(followerId, followeeId);\n                    break;\n                case 3:\n                    System.out.print(\"ID del seguidor: \");\n                    followerId = scanner.nextInt();\n                    System.out.print(\"ID del seguido: \");\n                    followeeId = scanner.nextInt();\n                    network.unfollowUser(followerId, followeeId);\n                    break;\n                case 4:\n                    System.out.print(\"ID de usuario: \");\n                    userId = scanner.nextInt();\n                    System.out.print(\"ID del post: \");\n                    int postId = scanner.nextInt();\n                    scanner.nextLine();\n                    System.out.print(\"Texto del post: \");\n                    String text = scanner.nextLine();\n                    network.createPost(userId, postId, text);\n                    break;\n                case 5:\n                    System.out.print(\"ID del post: \");\n                    postId = scanner.nextInt();\n                    network.deletePost(postId);\n                    break;\n                case 6:\n                    System.out.print(\"ID de usuario: \");\n                    userId = scanner.nextInt();\n                    System.out.print(\"ID del post: \");\n                    postId = scanner.nextInt();\n                    network.likePost(userId, postId);\n                    break;\n                case 7:\n                    System.out.print(\"ID de usuario: \");\n                    userId = scanner.nextInt();\n                    System.out.print(\"ID del post: \");\n                    postId = scanner.nextInt();\n                    network.unlikePost(userId, postId);\n                    break;\n                case 8:\n                    System.out.print(\"ID de usuario: \");\n                    userId = scanner.nextInt();\n                    network.viewUserFeed(userId);\n                    break;\n                case 9:\n                    System.out.print(\"ID de usuario: \");\n                    userId = scanner.nextInt();\n                    network.viewFollowedFeed(userId);\n                    break;\n                case 0:\n                    System.out.println(\"¡Hasta luego!\");\n                    scanner.close();\n                    return;\n                default:\n                    System.out.println(\"Opción no válida. Intente de nuevo.\");\n                    break;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/46 - X VS BLUESKY/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #46 - JavaScript -> Jesus Antonio Escamilla */\n\n/**\n * X VS BLUESKY.\n * Utilizando la Terminal para pedir datos y agregarlos.\n */\n\nclass User {\n    constructor(id, name) {\n        this.id = id;\n        this.name = name;\n        this.following = new Set();\n        this.posts = [];\n    }\n\n    follow(user){\n        if (this.id === user.id) {\n            throw new Error('No puedes seguirte a ti mismo.');\n        }\n        if (this.following.has(user.id)) {\n            throw new Error('Ya sigues a este usuario.');\n        }\n\n        this.following.add(user.id);\n    }\n\n    unfollow(user){\n        if (!this.following.has(user.id)) {\n            throw new Error('No estás siguiendo a este usuario.');\n        }\n\n        this.following.delete(user.id);\n    }\n\n    createPost(text){\n        if (text.length > 200) {\n            throw new Error('El texto del post no puede exceder los 200 caracteres.');\n        }\n\n        const post = {\n            id: Date.now(),\n            userId: this.id,\n            userName: this.name,\n            text,\n            date: new Date(),\n            likes: new Set()\n        };\n\n        this.posts.push(post);\n        return post;\n    }\n\n    deletePost(postId){\n        const index = this.posts.findIndex(post => post.id === postId);\n        if (index === -1) {\n            throw new Error('El post no existe.');\n        }\n\n        this.posts.splice(index, 1);\n    }\n\n    likePost(post){\n        if (post.likes.has(this.id)) {\n            throw new Error('Ya has dado like a este post.');\n        }\n\n        post.likes.add(this.id);\n    }\n\n    unlikePost(post){\n        if (!post.likes.has(this.id)) {\n            throw new Error('No has dado like a este post.');\n        }\n\n        post.likes.delete(this.id);\n    }\n\n    getFeed(limit = 10){\n        return this.posts\n            .sort((a, b) => b.delete - a.delete)\n            .slice(0, limit)\n    }\n\n    getFollowingFeed(users, limit = 10){\n        const followingPost = [];\n        for(const userId of this.following){\n            const user = users.find(u => u.id === userId);\n            if (user) {\n                followingPost.push(...user.getFeed());\n            }\n        }\n        return followingPost\n            .sort((a, b) => b.date - a.date)\n            .slice(0, limit);\n    }\n}\n\nfunction displayPost(post) {\n    console.log(`ID de Usuario: ${post.userId}`);\n    console.log(`Nombre de Usuario: ${post.userName}`);\n    console.log(`Texto: ${post.text}`);\n    console.log(`Fecha de Creación: ${post.date}`);\n    console.log(`Número de Likes: ${post.likes.size}\\n`);\n}\n\n// Datos del ejemplo\nconst users = [];\nconst user1 = new User(1, 'Alice');\nconst user2 = new User(2, 'Bob');\nconst user3 = new User(3, 'Charlie');\n\nusers.push(user1, user2, user3);\n\n// Registrar de post:\nconst post1 = user1.createPost('Hola, este es mi primer post.');\nconst post2 = user1.createPost('¿Alguien más está emocionado por el nuevo lanzamiento?');\nconst post3 = user2.createPost('¡Hola a todos! Este es mi primer post.');\n\n// Seguimientos de usuarios\nuser1.follow(user2);\nuser1.follow(user3);\n\n// Like a un post\nuser1.likePost(post2);\n\n// Visualización de feed de un usuario\nconsole.log('Feed de Alice:');\nuser1.getFeed().forEach(displayPost);\n\n// Visualización de feed de un usuario con las publicaciones de los usuarios que sigue\nconsole.log('Feed de Alice con publicaciones de usuarios que sigue:');\nuser1.getFollowingFeed(users).forEach(displayPost);"
  },
  {
    "path": "Roadmap/46 - X VS BLUESKY/javascript/MohamedElderkaoui.js",
    "content": "const users = new Map();\nlet idCounter = 0;\n\nclass User {\n    constructor(name) {\n        this.id = idCounter++;\n        this.name = name;\n        this.following = [];\n        this.posts = [];\n    }\n\n    follow(user) {\n        if (!this.following.includes(user)) {\n            this.following.push(user);\n        }\n    }\n\n    unfollow(user) {\n        const index = this.following.indexOf(user);\n        if (index !== -1) {\n            this.following.splice(index, 1);\n        }\n    }\n\n    addPost(post) {\n        this.posts.push(post);\n    }\n\n    deletePost(postId) {\n        const index = this.posts.findIndex(post => post.id === postId);\n        if (index !== -1) {\n            this.posts.splice(index, 1);\n            return true;\n        }\n        return false;\n    }\n\n    getMyFeed() {\n        return this.posts.slice().sort((a, b) => b.creationDate - a.creationDate).slice(0, 10);\n    }\n\n    getFollowingFeed() {\n        let feed = [];\n        this.following.forEach(user => {\n            feed = feed.concat(user.posts);\n        });\n        return feed.sort((a, b) => b.creationDate - a.creationDate).slice(0, 10);\n    }\n}\n\nclass Post {\n    constructor(user, content) {\n        this.id = idCounter++;\n        this.user = user;\n        this.content = content;\n        this.creationDate = new Date();\n        this.likes = new Set();\n    }\n\n    addLike(user) {\n        this.likes.add(user);\n    }\n\n    removeLike(user) {\n        this.likes.delete(user);\n    }\n\n    toString() {\n        return `Post de ${this.user.name}: ${this.content} | Likes: ${this.likes.size}`;\n    }\n}\n\nfunction registerUser() {\n    const name = prompt(\"Ingrese el nombre de usuario: \");\n    if (users.has(name)) {\n        console.log(\"Error: El usuario ya existe.\");\n    } else {\n        const newUser = new User(name);\n        users.set(name, newUser);\n        console.log(\"Usuario registrado exitosamente: \" + name);\n    }\n}\n\nfunction followUser() {\n    const userName = prompt(\"Tu nombre de usuario: \");\n    const user = users.get(userName);\n    const toFollowName = prompt(\"Nombre del usuario a seguir: \");\n    const toFollow = users.get(toFollowName);\n    if (user && toFollow) {\n        user.follow(toFollow);\n        console.log(`Ahora sigues a ${toFollow.getName()}`);\n    }\n}\n\nfunction unfollowUser() {\n    const userName = prompt(\"Tu nombre de usuario: \");\n    const user = users.get(userName);\n    const toUnfollowName = prompt(\"Nombre del usuario a dejar de seguir: \");\n    const toUnfollow = users.get(toUnfollowName);\n    if (user && toUnfollow) {\n        user.unfollow(toUnfollow);\n        console.log(`Has dejado de seguir a ${toUnfollow.getName()}`);\n    }\n}\n\nfunction createPost() {\n    const userName = prompt(\"Tu nombre de usuario: \");\n    const user = users.get(userName);\n    if (user) {\n        const content = prompt(\"Ingrese el texto del post (máximo 200 caracteres): \");\n        if (content.length > 200) {\n            console.log(\"Error: El texto excede los 200 caracteres.\");\n        } else {\n            const post = new Post(user, content);\n            user.addPost(post);\n            console.log(\"Post creado exitosamente: \" + post);\n        }\n    }\n}\n\nfunction deletePost() {\n    const userName = prompt(\"Tu nombre de usuario: \");\n    const user = users.get(userName);\n    if (user) {\n        const postId = prompt(\"Ingrese el ID del post a eliminar: \");\n        const success = user.deletePost(postId);\n        if (success) {\n            console.log(\"Post eliminado exitosamente.\");\n        } else {\n            console.log(\"Error: No se encontró el post con ese ID.\");\n        }\n    }\n}\n\nfunction likePost() { // No implementado\n    const userName = prompt(\"Tu nombre de usuario: \");\n    const user = users.get(userName);\n    if (user) {\n        const authorName = prompt(\"Ingrese el nombre del usuario que publicó el post: \");\n        const author = users.get(authorName);\n        if (author) {\n            let postNumber;\n            do {\n                try {\n                    postNumber = parseInt(prompt(\"Ingrese el número del post que desea dar like (1 para el primero, 2 para el segundo, etc.): \"));\n                    break;\n                } catch (error) {\n                    console.log(\"Debe ingresar un número entero.\");\n                }\n            } while (true);\n            const posts = author.posts;\n            if (postNumber > 0 && postNumber <= posts.length) {\n                const post = posts[postNumber - 1];\n                post.addLike(user);\n                console.log(\"Diste like al post de \" + author.name);\n            } else {\n                console.log(\"Error: Número de post inválido.\");\n            }\n        } else {\n            console.log(\"Error: Usuario no encontrado.\");\n        }\n    }\n}\n\nfunction unlikePost() {\n    const userName = prompt(\"Tu nombre de usuario: \");\n    const user = users.get(userName);\n    if (user) {\n        const postId = prompt(\"Ingrese el ID del post a eliminar like: \");\n        let post = null;\n        for (let u of users.values()) {\n            post = u.posts.find(p => p.id === postId);\n            if (post) break;\n        }\n        if (post) {\n            post.removeLike(user);\n            console.log(\"Eliminaste tu like del post.\");\n        } else {\n            console.log(\"Error: No se encontró el post con ese ID.\");\n        }\n    }\n}\n\nfunction viewMyFeed() {\n    const userName = prompt(\"Tu nombre de usuario: \");\n    const user = users.get(userName);\n    if (user) {\n        console.log(\"Tu feed:\");\n        user.getMyFeed().forEach(post => console.log(post.toString()));\n    }\n}\n\nfunction viewFollowingFeed() {\n    const userName = prompt(\"Tu nombre de usuario: \");\n    const user = users.get(userName);\n    if (user) {\n        console.log(\"Feed de usuarios que sigues:\");\n        user.getFollowingFeed().forEach(post => console.log(post.toString()));\n    }\n}\n\nfunction listUsers() {\n    if (users.size === 0) {\n        console.log(\"No hay usuarios registrados actualmente.\");\n    } else {\n        console.log(\"Usuarios registrados:\");\n        users.forEach(user => {\n            console.log(`- ${user.name} (ID: ${user.id})`);\n        });\n    }\n}\n\nfunction main() {\n    let option;\n    do {\n        console.log(\"\\nMenú:\");\n        console.log(\"1. Registrar usuario\");\n        console.log(\"2. Seguir a un usuario\");\n        console.log(\"3. Dejar de seguir a un usuario\");\n        console.log(\"4. Crear un post\");\n        console.log(\"5. Eliminar un post\");\n        console.log(\"6. Dar like a un post\");\n        console.log(\"7. Eliminar like de un post\");\n        console.log(\"8. Ver mi feed\");\n        console.log(\"9. Ver feed de usuarios seguidos\");\n        console.log(\"10. Listar usuarios registrados\");\n        console.log(\"11. Salir\");\n        do {\n            try {\n                option = parseInt(prompt(\"Seleccione una opción: \"));\n            } catch (error) {\n                console.log(\"Debe ingresar un número entero.\");\n            }\n        } while (isNaN(option));\n        switch (option) {\n            case 1: registerUser(); break;\n            case 2: followUser(); break;\n            case 3: unfollowUser(); break;\n            case 4: createPost(); break;\n            case 5: deletePost(); break;\n            case 6: likePost(); break;\n            case 7: unlikePost(); break;\n            case 8: viewMyFeed(); break;\n            case 9: viewFollowingFeed(); break;\n            case 10: listUsers(); break;\n            case 11: console.log(\"Saliendo de la red social...\"); break;\n            default: console.log(\"Opción inválida. Intente nuevamente.\"); break;\n        }\n    } while (option !== 11);\n}\n\nmain();\n"
  },
  {
    "path": "Roadmap/46 - X VS BLUESKY/javascript/RaulDoezon.js",
    "content": "/*\n  EJERCICIO:\n  La alternativa descentralizada a X, Bluesky, comienza a atraer\n  a nuevos usuarios. ¿Cómo funciona una red de este estilo?\n  \n  Implementa un sistema que simule el comportamiento de estas\n  redes sociales.\n  \n  Debes crear las siguientes operaciones:\n  - Registrar un usuario por nombre e identificador único.\n  - Un usuario puede seguir/dejar de seguir a otro.\n  - Creación de post asociado a un usuario. Debe poseer\n    texto (200 caracteres máximo), fecha de creación \n    e identificador único.\n  - Eliminación de un post.\n  - Posibilidad de hacer like (y eliminarlo) en un post.\n  - Visualización del feed de un usuario con sus 10 publicaciones\n    más actuales ordenadas desde la más reciente.\n  - Visualización del feed de un usuario con las 10 publicaciones\n    más actuales de los usuarios que sigue ordenadas \n    desde la más reciente.\n    \n  Cuando se visualiza un post, debe mostrarse:\n  ID de usuario, nombre de usuario, texto del post, \n  fecha de creación y número total de likes.\n  \n  Controla errores en duplicados o acciones no permitidas.\n*/\n\nclass Register {\n  constructor() {\n    this.users = [];\n  }\n\n  createUser(name, userName) {\n    this.name = name;\n    this.userName = userName;\n    this.checkUserName = this.users.findIndex((user) => user.user_name === this.userName);\n\n    if (this.checkUserName === -1) {\n      this.users.push({ name: this.name, user_name: this.userName, following: [], posts: [] });\n    } else {\n      console.error(`El nombre de usuario \"${this.userName}\" ya existe.`);\n    }\n  }\n\n  follow(follower, userToFollow) {\n    const checkFollower = this.users.findIndex((user) => user.user_name === follower);\n    const checkUserToFollow = this.users.findIndex((user) => user.user_name === userToFollow);\n\n    if (checkFollower > -1 && checkUserToFollow > -1) {\n      if (follower !== userToFollow) {\n        this.users[checkFollower].following.push(userToFollow);\n\n        console.log(`${follower} sigue a ${userToFollow}`);\n      } else {\n        console.error(\"El usuario no puede seguirse a sí mismo.\");\n      }\n    } else {\n      console.error(`No es posible seguir al usuario \"${userToFollow}\"`);\n    }\n  }\n\n  unfollow(follower, userToUnfollow) {\n    const checkFollower = this.users.findIndex((user) => user.user_name === follower);\n    const checkUserToUnfollow = this.users[checkFollower].following.findIndex((user) => user === userToUnfollow);\n\n    if (checkFollower > -1 && checkUserToUnfollow > -1) {\n      this.users[checkFollower].following.splice(checkUserToUnfollow, 1);\n\n      console.log(`${follower} dejó de seguir a ${userToUnfollow}`);\n    } else {\n      console.error(`No es posible dejar de seguir al usuario \"${userToUnfollow}\"`);\n    }\n  }\n\n  createPost(postByUser, postContent) {\n    const checkUser = this.users.findIndex((user) => user.user_name === postByUser);\n\n    if (checkUser > -1) {\n      let postIndex = this.users[checkUser].posts.length;\n\n      this.users[checkUser].posts.push({ content: postContent, date: new Date(), id: `${checkUser}${postIndex}`, likes: [] });\n\n      console.log(`\"${postByUser}\" creó un post.`);\n    } else {\n      console.error(`No se puede crear el post porque el usuario \"${postByUser}\" no existe`);\n    }\n  }\n\n  removePost(postByUser, postID) {\n    const checkUser = this.users.findIndex((user) => user.user_name === postByUser);\n    const checkPostID = this.users[checkUser].posts.findIndex((post) => post.id === postID);\n\n    if (checkUser > -1 && checkPostID > -1) {\n      this.users[checkUser].posts.splice(checkPostID, 1);\n\n      console.log(`El post ${checkPostID} del usuario ${postByUser} fue eliminado`);\n    } else {\n      console.error(`No fue posible eliminar el post. Posiblemente el usuario \"${postByUser}\" no existe o, el post con ID \"${postID}\"`);\n    }\n  }\n\n  likePost(userLike, postUser, postID) {\n    const checkUserPost = this.users.findIndex((user) => user.user_name === postUser);\n    const checkUserLike = this.users.findIndex((user) => user.user_name === userLike);\n    const checkPostID = this.users[checkUserPost].posts.findIndex((post) => post.id === postID);\n\n    if (checkUserPost > -1 && checkUserLike > -1 && checkPostID > -1) {\n      this.users[checkUserPost].posts[checkPostID].likes.push(userLike);\n\n      console.log(`El usuario \"${userLike}\" dió Me Gusta al post ${postID}.`);\n    } else {\n      console.error(\"No fue posible dar Me gusta al post.\");\n    }\n  }\n\n  unlikePost(userUnlike, postUser, postID) {\n    const checkUserPost = this.users.findIndex((user) => user.user_name === postUser);\n    const checkUserUnlike = this.users.findIndex((user) => user.user_name === userUnlike);\n    const checkPostID = this.users[checkUserPost].posts.findIndex((post) => post.id === postID);\n\n    if (checkUserPost > -1 && checkUserUnlike > -1 && checkPostID > -1) {\n      this.users[checkUserPost].posts[checkPostID].likes.splice(checkPostID, 1);\n\n      console.log(`Al usuario \"${userUnlike}\" ya No le Gusta el post ${postID}.`);\n    } else {\n      console.error(\"No fue posible quitar el Me gusta al post.\");\n    }\n  }\n\n  feed(userName) {\n    const checkUserName = this.users.findIndex((user) => user.user_name === userName);\n\n    if (checkUserName > -1) {\n      const user = this.users[checkUserName].name;\n      const userName = this.users[checkUserName].user_name;\n\n      console.log(`\\n+++++++++ Feed de ${userName} +++++++++`);\n\n      for (const post of this.users[checkUserName].posts.reverse()) {\n        console.log(`Publicación: ${post.content}.\\nFecha: ${post.date}.\\nNombre: ${user}.\\nID: ${userName}.\\nNúmero de Me Gusta: ${post.likes.length}.`);\n      }\n    }\n  }\n\n  followingFeed(userName) {\n    const checkUserName = this.users.findIndex((user) => user.user_name === userName);\n\n    if (checkUserName > -1) {\n      console.log(`\\n+++++++++ Feed de los seguidores de ${userName} +++++++++`);\n\n      for (const following of this.users[checkUserName].following) {\n        const searchUser = this.users[this.users.findIndex((user) => user.user_name === following)];\n        const userPosts = searchUser.posts.reverse();\n\n        for (const post of userPosts) {\n          console.log(`Publicación: ${post.content}.\\nFecha: ${post.date}.\\nNombre: ${searchUser.name}.\\nID: ${searchUser.user_name}.\\nNúmero de Me Gusta: ${post.likes.length}.`);\n        }\n      }\n    }\n  }\n\n  viewArray() {\n    console.log(this.users);\n  }\n}\n\nlet user = new Register();\n\nuser.createUser('Ana', 'Anna');\nuser.createUser('Raúl', 'RaulDoezon');\nuser.createUser('Francisco', 'Paco');\nuser.createUser('Ana', 'Anna');\n\nuser.follow('RaulDoezon', 'Anna');\nuser.follow('RaulDoezon', 'Paco');\nuser.follow('Anna', 'RaulDoezon');\nuser.follow('Anna', 'Paco');\n\nuser.unfollow('RaulDoezon', 'Paco');\n\nuser.createPost('Anna', 'Romanos 3:23 RVR60');\nuser.createPost('Anna', '1 Juan 1:9 RVR60');\nuser.createPost('RaulDoezon', 'Juan 3:16 RVR60');\nuser.createPost('RaulDoezon', 'Porque de tal manera amó Dios al mundo que ha dado a su hijo unigénito.');\nuser.createPost('RaulDoezon', 'Para que todo aquel que en Él cree no se pierda, mas tenga vida eterna.');\nuser.createPost('Paco', 'Colosenses 3:23 RVR60');\n\nuser.removePost('RaulDoezon', '11');\n\nuser.likePost('Anna', 'RaulDoezon', '10');\nuser.likePost('Anna', 'RaulDoezon', '12');\nuser.likePost('Anna', 'Paco', '20');\nuser.likePost('RaulDoezon', 'Anna', '00');\nuser.likePost('RaulDoezon', 'Paco', '20');\nuser.likePost('Paco', 'RaulDoezon', '12');\nuser.likePost('Paco', 'Anna', '00');\n\nuser.unlikePost('Anna', 'RaulDoezon', '10');\n\nuser.feed('Anna')\n\nuser.followingFeed('Anna');\n\nuser.viewArray();\n"
  },
  {
    "path": "Roadmap/46 - X VS BLUESKY/javascript/duendeintemporal.js",
    "content": "//#46 - X VS BLUESKY\n/*\n * EJERCICIO:\n * La alternativa descentralizada a X, Bluesky, comienza a atraer\n * a nuevos usuarios. ¿Cómo funciona una red de este estilo?\n *\n * Implementa un sistema que simule el comportamiento de estas\n * redes sociales.\n *\n * Debes crear las siguientes operaciones:\n * - Registrar un usuario por nombre e identificador único.\n * - Un usuario puede seguir/dejar de seguir a otro.\n * - Creación de post asociado a un usuario. Debe poseer\n *   texto (200 caracteres máximo), fecha de creación \n *   e identificador único.  \n * - Eliminación de un post.\n * - Posibilidad de hacer like (y eliminarlo) en un post.\n * - Visualización del feed de un usuario con sus 10 publicaciones\n *   más actuales ordenadas desde la más reciente.\n * - Visualización del feed de un usuario con las 10 publicaciones\n *   más actuales de los usuarios que sigue ordenadas \n *   desde la más reciente.\n *\n * Cuando se visualiza un post, debe mostrarse:\n * ID de usuario, nombre de usuario, texto del post,\n * fecha de creación y número total de likes.\n *\n * Controla errores en duplicados o acciones no permitidas.\n */\n\nlet log = console.log;\n\nwindow.addEventListener('load', () => {\n    const body = document.querySelector('body');\n    const title = document.createElement('h1');\n\n    body.style.setProperty('background', '#000');\n    body.style.setProperty('text-align', 'center');\n\n    title.textContent = 'Retosparaprogramadores #46.';\n    title.style.setProperty('font-size', '3.5vmax');\n    title.style.setProperty('color', '#fff');\n    title.style.setProperty('line-height', '100vh');\n\n    body.appendChild(title);\n\n    setTimeout(() => {\n        alert('Retosparaprogramadores #46. Please open the Browser Developer Tools.');\n    }, 2000);\n    \n    log('Retosparaprogramadores #46');\n});\n\nclass User {\n    constructor(name, id) {\n        this.name = name;\n        this.id = id;\n        this.following = new Set();\n        this.posts = [];\n    }\n\n    follow(user) {\n        this.following.add(user);\n        log(`${this.name} followed ${user.name}`);\n    }\n\n    unfollow(user) {\n        this.following.delete(user);\n        log(`${this.name} unfollowed ${user.name}`);\n    }\n\n    createPost(text) {\n        if (text.length > 200) {\n            throw new Error(\"Post text cannot exceed 200 characters.\");\n        }\n        const post = new Post(this, text);\n        this.posts.push(post);\n        log(`${this.name} created a post: \"${text}\"`);\n        return post;\n    }\n\n    deletePost(post) {\n        const index = this.posts.indexOf(post);\n        if (index === -1) {\n            throw new Error(\"Post not found.\");\n        }\n        this.posts.splice(index, 1);\n        log(`${this.name} deleted a post: \"${post.text}\"`);\n    }\n\n    getFeed() {\n        const feed = this.posts.slice().sort((a, b) => b.createdAt - a.createdAt).slice(0, 10);\n        log(`${this.name}'s feed:`, feed.map(post => post.toString()));\n        return feed;\n    }\n\n    getFollowingFeed() {\n        const feed = [];\n        for (const user of this.following) {\n            feed.push(...user.posts.slice().sort((a, b) => b.createdAt - a.createdAt).slice(0, 10));\n        }\n        feed.sort((a, b) => b.createdAt - a.createdAt);\n        log(`${this.name}'s following feed:`, feed.map(post => post.toString()));\n        return feed.slice(0, 10);\n    }\n}\n\nclass Post {\n    constructor(user, text) {\n        this.id = crypto.randomUUID();\n        this.user = user;\n        this.text = text;\n        this.createdAt = new Date();\n        this.likes = new Set();\n    }\n\n    like(user) {\n        this.likes.add(user);\n        log(`${user.name} liked a post: \"${this.text}\" by ${this.user.name}`);\n    }\n\n    unlike(user) {\n        this.likes.delete(user);\n        log(`${user.name} unliked a post: \"${this.text}\" by ${this.user.name}`);\n    }\n\n    getTotalLikes() {\n        return this.likes.size;\n    }\n\n    toString() {\n        return `Post by ${this.user.name}: \"${this.text}\" (Likes: ${this.getTotalLikes()})`;\n    }\n}\n\nconst user1 = new User(\"Niko Zen\", 1);\nconst user2 = new User(\"Bob Marley\", 2);\nconst user3 = new User(\"Psicotrogato\", 3);\n\nuser1.follow(user2);\nuser1.follow(user3);\n\nconst post1 = user1.createPost(\"I'm almost finishing this roadmap for developers.\");\nconst post1_1 = user1.createPost(\"I'm thinking in the possibility of start some of the developer course in mouredev, to get more possibilities to find a remote job.\");\nconst post1_2 = user1.createPost(\"I start to feel comfortable with Javascript and its ecosystem, right now I'm studying Next.js.\");\nconst post2 = user2.createPost(\"But Jamming!\");\nconst post2_1 = user2.createPost(\"I'm not going to wait in vain for your love!\");\nconst post2_2 = user2.createPost(\"I shot the sheriff, but I didn't shoot the deputy!\");\nconst post3 = user3.createPost(\"In a society that has abolished every kind of adventure, the only adventure that remains is abolishing the society.\");\nconst post3_1 = user3.createPost(\"My life is perfect because I accept it as it is.\");\n\npost1.like(user2);\npost1.like(user3);\n\n// Log the feeds with informative output\nlog(\"User Feeds:\");\nlog(\"User 1 Feed:\", user1.getFeed());\nlog(\"User 1 Following Feed:\", user1.getFollowingFeed());\nlog(\"User 2 Feed:\", user2.getFeed());\nlog(\"User 2 Following Feed:\", user2.getFollowingFeed());\nlog(\"User 3 Feed:\", user3.getFeed());\nlog(\"User 3 Following Feed:\", user3.getFollowingFeed());\n\n\n  \n/*  Output Example:\nNiko Zen followed Bob Marley\n46.js:64 Niko Zen followed Psicotrogato\n46.js:78 Niko Zen created a post: \"I'm almost finishing this roadmap for developers.\"\n46.js:78 Niko Zen created a post: \"I'm thinking in the possibility of start some of the developer course in mouredev, to get more possibilities to find a remote job.\"\n46.js:78 Niko Zen created a post: \"I start to feel comfortable with Javascript and its ecosystem, right now I'm studying Next.js.\"\n46.js:78 Bob Marley created a post: \"But Jamming!\"\n46.js:78 Bob Marley created a post: \"I'm not going to wait in vain for your love!\"\n46.js:78 Bob Marley created a post: \"I shot the sheriff, but I didn't shoot the deputy!\"\n46.js:78 Psicotrogato created a post: \"In a society that has abolished every kind of adventure, the only adventure that remains is abolishing the society.\"\n46.js:78 Psicotrogato created a post: \"My life is perfect because I accept it as it is.\"\n46.js:119 Bob Marley liked a post: \"I'm almost finishing this roadmap for developers.\" by Niko Zen\n46.js:119 Psicotrogato liked a post: \"I'm almost finishing this roadmap for developers.\" by Niko Zen\n46.js:156 User Feeds:\n46.js:93 Niko Zen's feed: (3) [`Post by Niko Zen: \"I'm thinking in the possibility…e possibilities to find a remote job.\" (Likes: 0)`, `Post by Niko Zen: \"I start to feel comfortable wit…stem, right now I'm studying Next.js.\" (Likes: 0)`, `Post by Niko Zen: \"I'm almost finishing this roadmap for developers.\" (Likes: 2)`]\n46.js:157 User 1 Feed: (3) [Post, Post, Post]\n46.js:103 Niko Zen's following feed: (5) ['Post by Psicotrogato: \"In a society that has aboli…at remains is abolishing the society.\" (Likes: 0)', 'Post by Psicotrogato: \"My life is perfect because I accept it as it is.\" (Likes: 0)', `Post by Bob Marley: \"I shot the sheriff, but I didn't shoot the deputy!\" (Likes: 0)`, `Post by Bob Marley: \"I'm not going to wait in vain for your love!\" (Likes: 0)`, 'Post by Bob Marley: \"But Jamming!\" (Likes: 0)']\n46.js:158 User 1 Following Feed: (5) [Post, Post, Post, Post, Post]\n46.js:93 Bob Marley's feed: (3) [`Post by Bob Marley: \"I shot the sheriff, but I didn't shoot the deputy!\" (Likes: 0)`, `Post by Bob Marley: \"I'm not going to wait in vain for your love!\" (Likes: 0)`, 'Post by Bob Marley: \"But Jamming!\" (Likes: 0)']\n46.js:159 User 2 Feed: (3) [Post, Post, Post]\n46.js:103 Bob Marley's following feed: []\n46.js:160 User 2 Following Feed: []\n46.js:93 Psicotrogato's feed: (2) ['Post by Psicotrogato: \"In a society that has aboli…at remains is abolishing the society.\" (Likes: 0)', 'Post by Psicotrogato: \"My life is perfect because I accept it as it is.\" (Likes: 0)']\n46.js:161 User 3 Feed: (2) [Post, Post]\n46.js:103 Psicotrogato's following feed: []\n46.js:162 User 3 Following Feed: []\n46.js:51 Retosparaprogramadores #46\n*/\n"
  },
  {
    "path": "Roadmap/46 - X VS BLUESKY/javascript/hectorio23.js",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\nclass SocialNetwork {\n    constructor() {\n        this.users = new Map();\n        this.posts = new Map();\n        this.following = new Map();\n    }\n\n    registerUser(userId, name) {\n        if (this.users.has(userId)) {\n            throw new Error(\"User ID already exists.\");\n        }\n        this.users.set(userId, { name, posts: [] });\n        this.following.set(userId, new Set());\n    }\n\n    toggleFollow(followerId, followedId) {\n        if (!this.users.has(followerId) || !this.users.has(followedId)) {\n            throw new Error(\"User ID not found.\");\n        }\n        const following = this.following.get(followerId);\n        if (following.has(followedId)) {\n            following.delete(followedId);\n        } else {\n            following.add(followedId);\n        }\n    }\n\n    createPost(userId, postId, text) {\n        if (!this.users.has(userId)) {\n            throw new Error(\"User ID not found.\");\n        }\n        if (this.posts.has(postId)) {\n            throw new Error(\"Post ID already exists.\");\n        }\n        if (text.length > 200) {\n            throw new Error(\"Text exceeds maximum length of 200 characters.\");\n        }\n        const post = {\n            postId,\n            userId,\n            text,\n            createdAt: new Date(),\n            likes: 0\n        };\n        this.posts.set(postId, post);\n        this.users.get(userId).posts.push(post);\n    }\n\n    deletePost(postId) {\n        if (!this.posts.has(postId)) {\n            throw new Error(\"Post ID not found.\");\n        }\n        const post = this.posts.get(postId);\n        this.users.get(post.userId).posts = this.users.get(post.userId).posts.filter(p => p.postId !== postId);\n        this.posts.delete(postId);\n    }\n\n    toggleLike(postId) {\n        if (!this.posts.has(postId)) {\n            throw new Error(\"Post ID not found.\");\n        }\n        const post = this.posts.get(postId);\n        post.likes = post.likes === 0 ? 1 : 0;\n    }\n\n    getUserFeed(userId) {\n        if (!this.users.has(userId)) {\n            throw new Error(\"User ID not found.\");\n        }\n        const posts = [...this.users.get(userId).posts];\n        posts.sort((a, b) => b.createdAt - a.createdAt);\n        this.displayFeed(posts.slice(0, 10));\n    }\n\n    getFollowingFeed(userId) {\n        if (!this.users.has(userId)) {\n            throw new Error(\"User ID not found.\");\n        }\n        const feed = [];\n        for (const followedId of this.following.get(userId)) {\n            const followedPosts = this.users.get(followedId).posts;\n            feed.push(...followedPosts);\n        }\n        feed.sort((a, b) => b.createdAt - a.createdAt);\n        this.displayFeed(feed.slice(0, 10));\n    }\n\n    displayFeed(posts) {\n        posts.forEach(post => {\n            const userName = this.users.get(post.userId).name;\n            console.log(`User ID: ${post.userId}, Name: ${userName}, Text: ${post.text}, `\n                        + `Created At: ${post.createdAt}, Likes: ${post.likes}`);\n        });\n    }\n}\n\n// Example Usage\nconst sn = new SocialNetwork();\nsn.registerUser(\"u1\", \"Alice\");\nsn.registerUser(\"u2\", \"Bob\");\n\nsn.toggleFollow(\"u1\", \"u2\");\n\nsn.createPost(\"u1\", \"p1\", \"Hello, this is Alice!\");\nsn.createPost(\"u2\", \"p2\", \"Hi, this is Bob's post.\");\nsn.toggleLike(\"p2\");\n\nconsole.log(\"\\n[+] - User Feed for Alice:\");\nsn.getUserFeed(\"u1\");\n\nconsole.log(\"\\n[+] - Following Feed for Alice:\");\nsn.getFollowingFeed(\"u1\");\n\nsn.deletePost(\"p1\");\nconsole.log(\"\\n[+] - After Deleting Alice's Post:\");\nsn.getUserFeed(\"u1\");\n"
  },
  {
    "path": "Roadmap/46 - X VS BLUESKY/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n_______________________________________________________\n#46 X VS BLUESKY\n-------------------------------------------------------\n* EJERCICIO:\n * La alternativa descentralizada a X, Bluesky, comienza a atraer\n * a nuevos usuarios. ¿Cómo funciona una red de este estilo?\n * \n * Implementa un sistema que simule el comportamiento de estas\n * redes sociales.\n * \n * Debes crear las siguientes operaciones:\n * - Registrar un usuario por nombre e identificador único.\n * - Un usuario puede seguir/dejar de seguir a otro.\n * - Creación de post asociado a un usuario. Debe poseer\n *   texto (200 caracteres máximo), fecha de creación \n *   e identificador único.   \n * - Eliminación de un post.\n * - Posibilidad de hacer like (y eliminarlo) en un post.\n * - Visualización del feed de un usuario con sus 10 publicaciones\n *   más actuales ordenadas desde la más reciente.\n * - Visualización del feed de un usuario con las 10 publicaciones\n *   más actuales de los usuarios que sigue ordenadas \n *   desde la más reciente.\n *   \n * Cuando se visualiza un post, debe mostrarse:\n * ID de usuario, nombre de usuario, texto del post, \n * fecha de creación y número total de likes.\n * \n * Controla errores en duplicados o acciones no permitidas.\n */\n// ________________________________________________________\nconst { format } = require('util');\n\nconst log = {\n    info: (message, ...args) => console.log(`[INFO] ${format(message, ...args)}`),\n    warning: (message, ...args) => console.warn(`[WARN] ${format(message, ...args)}`),\n    error: (message, ...args) => console.error(`[ERROR] ${format(message, ...args)}`),\n};\n\nclass Posts {\n    constructor() {\n        this.__post_dt = {};\n    }\n\n    __verifyPost(idUser, idPost, nameFunc) {\n        if (!(idUser in this.__post_dt)) {\n            log.error(\"'%s': El ID %s no tiene posts.\", nameFunc, idUser);\n            return false;\n        }\n\n        if (!(idPost in this.__post_dt[idUser])) {\n            log.error(\"'%s': El Post (%s) no existe.\", nameFunc, idPost);\n            return false;\n        }\n\n        return true;\n    }\n\n    createPost(idUser, content) {\n        if (content.length > 200) {\n            log.error(\"'createPost': content > 200 caracteres.\");\n            return;\n        }\n\n        if (!(idUser in this.__post_dt)) {\n            this.__post_dt[idUser] = {};\n        }\n\n        const idPost = Object.keys(this.__post_dt[idUser]).length + 1;\n        this.__post_dt[idUser][idPost] = {\n            content,\n            timestamp: new Date(),\n            likes: new Set(),\n        };\n\n        log.info(\"El ID %s creó un post(ID: %s).\", idUser, idPost);\n    }\n\n    deletePost(idUser, idPost) {\n        if (this.__verifyPost(idUser, idPost, \"deletePost\")) {\n            delete this.__post_dt[idUser][idPost];\n            log.info(\"El post: %s de usuario: %s ha sido eliminado.\", idPost, idUser);\n        }\n    }\n\n    likePost(idUser, idAuthor, idPost) {\n        if (this.__verifyPost(idAuthor, idPost, \"likePost\")) {\n            this.__post_dt[idAuthor][idPost].likes.add(idUser);\n            log.info(\"El usuario %s dio like al post %s de usuario %s.\", idUser, idPost, idAuthor);\n        }\n    }\n\n    removeLike(idUser, idAuthor, idPost) {\n        if (this.__verifyPost(idAuthor, idPost, \"removeLike\")) {\n            this.__post_dt[idAuthor][idPost].likes.delete(idUser);\n            log.info(\"El usuario %s anuló el like al post %s de usuario %s.\", idUser, idPost, idAuthor);\n        }\n    }\n\n    getRecentPosts(idUser, limit = 10) {\n        if (idUser in this.__post_dt) {\n            const sortedPosts = Object.values(this.__post_dt[idUser])\n                .sort((a, b) => b.timestamp - a.timestamp);\n\n            return sortedPosts.slice(0, limit);\n        }\n\n        return [];\n    }\n}\n\nclass Users {\n    constructor() {\n        this.__users_dt = {};\n    }\n\n    __idExists(id, nameFunc = \"\") {\n        if (id in this.__users_dt) {\n            return true;\n        }\n\n        log.warning(\"'%s': ID: %s no encontrada.\", nameFunc, id);\n        return false;\n    }\n\n    addUser(name) {\n        const id = Object.keys(this.__users_dt).length + 1;\n        this.__users_dt[id] = {\n            name,\n            following: new Set(),\n            followers: new Set(),\n        };\n\n        log.info(\"Usuario %s-%s registrado.\", id, name);\n    }\n\n    followUser(id, toId) {\n        if (this.__idExists(id, \"followUser\") && this.__idExists(toId, \"followUser\")) {\n            this.__users_dt[id].following.add(toId);\n            this.__users_dt[toId].followers.add(id);\n            log.info(\"ID: %s está siguiendo a ID: %s.\", id, toId);\n        }\n    }\n\n    unfollowUser(id, toId) {\n        if (this.__idExists(id, \"unfollowUser\") && this.__idExists(toId, \"unfollowUser\")) {\n            this.__users_dt[id].following.delete(toId);\n            this.__users_dt[toId].followers.delete(id);\n            log.info(\"El ID: %s dejó de seguir al ID: %s.\", id, toId);\n        }\n    }\n\n    getName(idUser) {\n        if (this.__idExists(idUser, \"getName\")) {\n            return this.__users_dt[idUser].name;\n        }\n\n        return \"\";\n    }\n}\n\n// ________________________________________________________\nclass Program {\n    constructor(posts, users) {\n        this.__posts = new posts();\n        this.__users = new users();\n    }\n\n    __printFeed(idUser) {\n        const name = this.__users.getName(idUser);\n        if (!name) {\n            console.log(`Usuario ID: ${idUser} no encontrado.`);\n            return;\n        }\n\n        const last10 = this.__posts.getRecentPosts(idUser, 10);\n        console.log(`\\nFeed\\n_______\\nID: '${idUser}' - Nombre: '${name}'`);\n        if (last10.length === 0) {\n            console.log(\"No tiene publicaciones.\");\n            return;\n        }\n\n        last10.forEach(post => {\n            console.log(`_______\\n${post.content}`);\n            console.log(`Creado: '${post.timestamp}'`);\n            console.log(`Likes: '${post.likes.size}'`);\n        });\n    }\n\n    run() {\n        // CLI\n    }\n\n    tests() {\n        this.__users.addUser(\"Ken\"); // id=1\n        this.__users.addUser(\"Zoe\"); // id=2\n\n        this.__users.followUser(1, 2);\n        this.__users.followUser(2, 1);\n        this.__users.unfollowUser(2, 1);\n\n        this.__posts.createPost(2, \"Primer post.\"); // id=1\n        this.__posts.createPost(2, \"Segundo post.\"); // id=2\n        this.__posts.deletePost(2, 2);\n        this.__posts.createPost(2, \"Otro post.\"); // id=2\n        this.__posts.likePost(1, 2, 1);\n        this.__posts.removeLike(1, 2, 1);\n        this.__posts.likePost(1, 2, 2);\n\n        this.__printFeed(2);\n        this.__printFeed(1);\n    }\n}\n\n// _______________________________________\nconst program = new Program(Posts, Users);\nprogram.tests();\n// program.run();\n"
  },
  {
    "path": "Roadmap/46 - X VS BLUESKY/javascript/miguelex.js",
    "content": "const readline = require('readline');\n\nclass User {\n    constructor(id, name) {\n        this.id = id;\n        this.name = name;\n        this.following = [];\n        this.posts = [];\n    }\n\n    follow(user) {\n        if (this.following.includes(user.id)) {\n            console.log(`${this.name} ya sigue a ${user.name}.`);\n            return;\n        }\n        this.following.push(user.id);\n        console.log(`${this.name} comenzó a seguir a ${user.name}.`);\n    }\n\n    unfollow(user) {\n        if (!this.following.includes(user.id)) {\n            console.log(`${this.name} no sigue a ${user.name}.`);\n            return;\n        }\n        this.following = this.following.filter(id => id !== user.id);\n        console.log(`${this.name} dejó de seguir a ${user.name}.`);\n    }\n}\n\nclass Post {\n    constructor(id, text, userId) {\n        this.id = id;\n        this.text = text.slice(0, 200);\n        this.userId = userId;\n        this.createdAt = new Date();\n        this.likes = 0;\n    }\n\n    like() {\n        this.likes++;\n    }\n\n    unlike() {\n        if (this.likes > 0) {\n            this.likes--;\n        }\n    }\n}\n\nclass SocialNetwork {\n    constructor() {\n        this.users = {};\n        this.posts = {};\n    }\n\n    registerUser(id, name) {\n        if (this.users[id]) {\n            console.log(`El usuario con ID ${id} ya existe.`);\n            return;\n        }\n        this.users[id] = new User(id, name);\n        console.log(`Usuario ${name} registrado con éxito.`);\n    }\n\n    createPost(userId, text) {\n        if (!this.users[userId]) {\n            console.log(`El usuario con ID ${userId} no existe.`);\n            return;\n        }\n        const postId = `post_${Date.now()}`;\n        const post = new Post(postId, text, userId);\n        this.posts[postId] = post;\n        this.users[userId].posts.push(post);\n        console.log(`Post creado con éxito.`);\n    }\n\n    deletePost(postId) {\n        const post = this.posts[postId];\n        if (!post) {\n            console.log(`El post con ID ${postId} no existe.`);\n            return;\n        }\n        const user = this.users[post.userId];\n        user.posts = user.posts.filter(p => p.id !== postId);\n        delete this.posts[postId];\n        console.log(`Post eliminado con éxito.`);\n    }\n\n    likePost(postId) {\n        const post = this.posts[postId];\n        if (!post) {\n            console.log(`El post con ID ${postId} no existe.`);\n            return;\n        }\n        post.like();\n        console.log(`Post ${postId} recibió un like.`);\n    }\n\n    unlikePost(postId) {\n        const post = this.posts[postId];\n        if (!post) {\n            console.log(`El post con ID ${postId} no existe.`);\n            return;\n        }\n        post.unlike();\n        console.log(`Like eliminado del post ${postId}.`);\n    }\n\n    viewFeed(userId) {\n        const user = this.users[userId];\n        if (!user) {\n            console.log(`El usuario con ID ${userId} no existe.`);\n            return;\n        }\n\n        const posts = user.posts.sort((a, b) => b.createdAt - a.createdAt);\n\n        console.log(`Feed de ${user.name}:`);\n        posts.slice(0, 10).forEach(post => this.displayPost(post));\n    }\n\n    viewFollowedFeed(userId) {\n        const user = this.users[userId];\n        if (!user) {\n            console.log(`El usuario con ID ${userId} no existe.`);\n            return;\n        }\n\n        let followedPosts = [];\n        user.following.forEach(followedId => {\n            const followedUser = this.users[followedId];\n            if (followedUser) {\n                followedPosts = followedPosts.concat(followedUser.posts);\n            }\n        });\n\n        followedPosts.sort((a, b) => b.createdAt - a.createdAt);\n\n        console.log(`Feed de usuarios seguidos por ${user.name}:`);\n        followedPosts.slice(0, 10).forEach(post => this.displayPost(post));\n    }\n\n    displayPost(post) {\n        console.log(`ID: ${post.id}, Usuario: ${post.userId}, Texto: ${post.text}, Fecha: ${post.createdAt.toISOString()}, Likes: ${post.likes}`);\n    }\n\n    async interactiveMenu() {\n        const rl = readline.createInterface({\n            input: process.stdin,\n            output: process.stdout\n        });\n\n        const ask = (question) => new Promise(resolve => rl.question(question, resolve));\n\n        while (true) {\n            console.log(`\\n--- Menú Principal ---`);\n            console.log(`1. Registrar usuario`);\n            console.log(`2. Crear post`);\n            console.log(`3. Eliminar post`);\n            console.log(`4. Dar like a un post`);\n            console.log(`5. Quitar like de un post`);\n            console.log(`6. Ver feed del usuario`);\n            console.log(`7. Ver feed de usuarios seguidos`);\n            console.log(`8. Seguir a un usuario`);\n            console.log(`9. Dejar de seguir a un usuario`);\n            console.log(`10. Salir`);\n\n            const option = await ask(`Seleccione una opción: `);\n\n            switch (option) {\n                case \"1\":\n                    const id = await ask(`Ingrese ID del usuario: `);\n                    const name = await ask(`Ingrese nombre del usuario: `);\n                    this.registerUser(id, name);\n                    break;\n                case \"2\":\n                    const userId = await ask(`Ingrese ID del usuario: `);\n                    const text = await ask(`Ingrese texto del post: `);\n                    this.createPost(userId, text);\n                    break;\n                case \"3\":\n                    const postId = await ask(`Ingrese ID del post: `);\n                    this.deletePost(postId);\n                    break;\n                case \"4\":\n                    const likePostId = await ask(`Ingrese ID del post: `);\n                    this.likePost(likePostId);\n                    break;\n                case \"5\":\n                    const unlikePostId = await ask(`Ingrese ID del post: `);\n                    this.unlikePost(unlikePostId);\n                    break;\n                case \"6\":\n                    const feedUserId = await ask(`Ingrese ID del usuario: `);\n                    this.viewFeed(feedUserId);\n                    break;\n                case \"7\":\n                    const followedFeedUserId = await ask(`Ingrese ID del usuario: `);\n                    this.viewFollowedFeed(followedFeedUserId);\n                    break;\n                case \"8\":\n                    const followerId = await ask(`Ingrese tu ID: `);\n                    const followId = await ask(`Ingrese ID del usuario a seguir: `);\n                    if (this.users[followerId] && this.users[followId]) {\n                        this.users[followerId].follow(this.users[followId]);\n                    } else {\n                        console.log(`Usuario no encontrado.`);\n                    }\n                    break;\n                case \"9\":\n                    const unfollowerId = await ask(`Ingrese tu ID: `);\n                    const unfollowId = await ask(`Ingrese ID del usuario a dejar de seguir: `);\n                    if (this.users[unfollowerId] && this.users[unfollowId]) {\n                        this.users[unfollowerId].unfollow(this.users[unfollowId]);\n                    } else {\n                        console.log(`Usuario no encontrado.`);\n                    }\n                    break;\n                case \"10\":\n                    rl.close();\n                    console.log(`Saliendo...`);\n                    return;\n                default:\n                    console.log(`Opción no válida.`);\n            }\n        }\n    }\n}\n\n(async () => {\n    const socialNetwork = new SocialNetwork();\n    await socialNetwork.interactiveMenu();\n})();\n"
  },
  {
    "path": "Roadmap/46 - X VS BLUESKY/kotlin/blackriper.kt",
    "content": "import com.mongodb.client.model.Filters\nimport com.mongodb.client.model.Filters.eq\nimport com.mongodb.client.model.Updates\nimport com.mongodb.kotlin.client.coroutine.MongoClient\nimport com.mongodb.kotlin.client.coroutine.MongoDatabase\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.async\nimport kotlinx.coroutines.flow.firstOrNull\nimport kotlinx.coroutines.flow.flow\nimport kotlinx.coroutines.flow.toList\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.runBlocking\nimport org.bson.codecs.pojo.annotations.BsonId\nimport org.bson.codecs.pojo.annotations.BsonProperty\nimport org.bson.types.ObjectId\nimport java.time.LocalDateTime\nimport java.time.format.DateTimeFormatter\n\n/*\nBase de Datos  a utilizar MongoDB\nDriver de Koltin para mongo usando suspend\nhttps://www.mongodb.com/docs/drivers/kotlin/coroutine/current/quick-start/\n*/\n\n//obtener  base de datos de mongo y crear enum de colecciones\n\nconst val URI_MONGO=\"YOUR_MONGO_URI or MONGO_SRV\"\nconst val MONGO_DATABASE=\"Bluesky\"\nenum class Collections{\n    Posts,\n    Users\n}\n\n\nval getDatabaseMongo={\n    databaseName: String ->\n    val mongoClient=MongoClient.create(connectionString =URI_MONGO )\n    val database= mongoClient.getDatabase(databaseName)\n    Pair(mongoClient,database)\n}\n\n\n//1.-Capa Modelos\n\nclass UserNotFound(message: String): Exception(message)\n\ndata class User constructor(\n    @BsonId\n    val id: ObjectId= ObjectId(),\n    var name : String=\"\",\n    val following: MutableList<ObjectId> = mutableListOf<ObjectId>()\n     )\n\nfun userBuilder(block:User.()-> Unit):User= User().apply(block)\n\ndata class Post constructor(\n    @BsonId\n    val id: ObjectId= ObjectId(),\n    @BsonProperty(\"user_id\")\n    var userId: String=\"\",\n    @BsonProperty(\"user_name\")\n    var username: String=\"\",\n    var content: String=\"\",\n    @BsonProperty(\"total_likes\")\n    var totalLikes: Long=0,\n    @BsonProperty(\"created_At\")\n    val createdAt: LocalDateTime= LocalDateTime.now()\n)\nfun postBuilder(block :Post.()-> Unit):Post=Post().apply(block)\n\ninterface UserRepository{\n    suspend fun registerUser():User\n    suspend fun unOrfollowing(userId: ObjectId, follUser: ObjectId, isFollowing: Boolean)\n    suspend fun findUser(userName: String):User\n}\n\n\ninterface PostRepository{\n    suspend fun createNewPost(actualUser:User): Boolean\n    suspend fun deletePost(postId: ObjectId): Boolean\n    suspend fun unOrLike(postId: ObjectId,unlike: Boolean)\n    suspend fun getRecentPost(): List<Post>\n    suspend fun  getPostByUserId(userId: ObjectId): List<Post>\n}\n\n\ninterface SocialMedia{\n   suspend fun  renderUserMenu()\n}\n\n//2.- capa repository\n\nclass UserRepo(private  val database: MongoDatabase):UserRepository{\n    private val userColl=database.getCollection<User>(collectionName = Collections.Users.name)\n\n    override suspend fun registerUser(): User {\n       println(\"Enter your username\")\n       val nameUser=readLine()?:\"default\"\n       val user=userBuilder {\n           name=nameUser.lowercase()\n       }\n        userColl.insertOne(user).also {\n            println(\"user added with id= ${it.insertedId}\")\n        }\n        return user\n    }\n\n    override suspend fun unOrfollowing(userId: ObjectId, follUser: ObjectId, isFollowing: Boolean) {\n        val user=userColl.find(Filters.eq(\"_id\",userId)).firstOrNull()\n        var newFollowing= mutableListOf<ObjectId>()\n\n        if (user!=null) newFollowing=user.following\n        else throw UserNotFound(\"user with $userId not found\")\n\n        if (isFollowing){\n            newFollowing.removeIf{it==follUser}\n            userColl.updateOne(\n                Filters.eq(\"_id\",userId),\n                Updates.set(\"following\",newFollowing)\n            ).also {\n                println(\"${follUser}  has remove you follwing list\")\n            }\n        }\n\n        if (! isFollowing ){\n            newFollowing.add(follUser)\n            userColl.updateOne(\n                Filters.eq(\"_id\",userId),\n                Updates.set(\"following\",newFollowing)\n            ).also {\n                println(\"${follUser}  has added you follwing list\")\n            }\n        }\n    }\n\n    override suspend fun findUser(userName: String): User {\n       val user= userColl.find(Filters.eq(\"name\",userName.lowercase())).firstOrNull()\n       if(user!=null)  return user\n       else throw UserNotFound(\"user $userName not found\")\n      }\n\n\n}\n\nclass RepoPost(private val database: MongoDatabase):PostRepository{\n      private val postColl=database.getCollection<Post>(collectionName = Collections.Posts.name)\n\n    override suspend fun createNewPost( actualUser:User): Boolean {\n        var validContent=false\n        var postContent=\"\"\n        while (validContent!=true){\n            println(\"write content post \")\n            postContent = readLine()!!\n            if (postContent.length>200) println(\"the post can only contanins 200 caracters \")\n            else validContent=true\n        }\n        val newPost=postBuilder {\n            userId=actualUser.id.toHexString()\n            username=actualUser.name\n            content= postContent\n        }\n\n        val result=postColl.insertOne(newPost)\n\n        return  result.insertedId!=null\n    }\n\n    override suspend fun deletePost(postId: ObjectId): Boolean =\n       postColl.deleteOne(Filters.eq(\"_id\",postId)).let {  it.deletedCount== 1L }\n\n    override suspend fun unOrLike(postId: ObjectId, unlike: Boolean) {\n        val post=postColl.find(Filters.eq(\"_id\",postId)).firstOrNull()\n        var likes=0L\n        if (post!=null && unlike){\n            likes=post.totalLikes+1\n            postColl.updateOne(\n                Filters.eq(\"_id\",postId),\n                Updates.set(\"total_likes\",likes)\n            ).also {\n                println(\"you liked the post ${post.id}\")\n            }\n        }\n\n        if (post!=null && !unlike){\n            likes=post.totalLikes-1\n            postColl.updateOne(\n                Filters.eq(\"_id\",postId),\n                Updates.set(\"total_likes\",likes)\n            ).also {\n                println(\"you unliked the post ${post.id}\")\n            }\n        }\n\n    }\n\n    override suspend fun getRecentPost(): List<Post> =\n        postColl.find().limit(10).toList().sortedBy { it.createdAt }\n\n    override suspend fun getPostByUserId(userId: ObjectId): List<Post> =\n        postColl.find(Filters.eq(\"user_id\",userId.toHexString())).toList()\n\n\n}\n\nclass BlueSky(private val userRepo: UserRepo,private val postRepo: RepoPost):SocialMedia{\n\n    private lateinit var actualUser: User\n\n   suspend fun loginOrRegisterUser(){\n        println(\"Login user o Register user [L] Login [R] Register\")\n        val option=readLine()!!.uppercase()\n\n        when(option){\n            \"L\"-> runCatching {\n                    println(\"Enter a username to login \")\n                    val name=readLine()!!\n                    userRepo.findUser(name)\n                }.onFailure {  println(\"error find user cause is  ${it.message}\")  }\n                .onSuccess { actualUser=it  }\n\n            \"R\"-> runCatching { userRepo.registerUser()}\n                .onFailure {  println(\"error register user cause is  ${it.message}\")  }\n                .onSuccess { actualUser=it  }\n        }\n    }\n\n    override suspend fun renderUserMenu() {\n        var number=0\n        while (number!=3){\n            println(\":::::BlueSky Simulate::::::\")\n            println(\"welcome ${actualUser.name}\")\n            println(\"1.-view feed\")\n            println(\"2.- administrate post\")\n            println(\"3.- Exit\")\n            println(\"Select option\")\n            number=readLine()!!.toInt()\n            if (number==3) break\n            if (number>3) {\n                println(\"incorrect option\")\n                return\n            }\n            when(number){\n                1-> renderFeed()\n                2-> administratePost()\n            }\n\n        }\n    }\n\n    private suspend fun administratePost() {\n        var numpost=1\n        var option=\"\"\n        while (option!=\"E\") {\n            val posts = postRepo.getPostByUserId(actualUser.id)\n            actualUser=userRepo.findUser(actualUser.name)\n            posts.forEach { post ->\n              val post = \"\"\"\n              numPost: ${numpost}\n              postId: ${post.id}\n              ${post.content}\n              createdAt: ${post.createdAt.format(DateTimeFormatter.ofPattern(\"dd/MM/YYYY\"))}\n              totalLikes: ${post.totalLikes}\n             \"\"\".trimIndent()\n                println(post)\n                numpost++\n            }\n            numpost=1\n\n            println(\"select action post [A] Add new Post [D] delete post E[Exit]\")\n            option=readLine()!!.uppercase()\n            if (option==\"E\") break\n\n               when (option) {\n                    \"A\" -> postRepo.createNewPost(actualUser)\n                    \"D\"-> {\n                        println(\"select a post number: \")\n                        var selectNum = readLine()!!.toInt()\n                        if (selectNum > posts.size){\n                            println(\"number post incorrect\")\n                            return\n                        }\n                        val post=posts[selectNum-1]\n                        postRepo.deletePost(post.id)\n                    }\n                }\n\n\n        }\n\n    }\n    private suspend fun renderFeed() {\n        var numpost=1\n        var option=\"\"\n      while (option!=\"E\") {\n          val posts = postRepo.getRecentPost()\n          actualUser=userRepo.findUser(actualUser.name)\n          posts.forEach { post ->\n              val post = \"\"\"\n              numPost: ${numpost}\n              postId: ${post.id}\n              userName: ${post.username}\n              ${post.content}\n              createdAt: ${post.createdAt.format(DateTimeFormatter.ofPattern(\"dd/MM/YYYY\"))}\n              totalLikes: ${post.totalLikes}\n              following: ${if (actualUser.following.count { it== ObjectId(post.userId) }==1) \"following\" else \"follow\"}\n          \"\"\".trimIndent()\n              println(post)\n              numpost++\n          }\n          numpost=1\n\n          println(\"select action post [L] like [D] diske [F] following user post [UN] unfollowing user[E] exit\")\n          option=readLine()!!.uppercase()\n          if (option==\"E\") break\n          println(\"select a post number: \")\n          var selectNum = readLine()!!.toInt()\n          if (selectNum > posts.size){\n              println(\"number post incorrect\")\n              return\n          }else {\n              val post=posts[selectNum-1]\n              when (option) {\n                  \"L\" -> postRepo.unOrLike(post.id,true)\n                  \"D\"-> postRepo.unOrLike(post.id,false)\n                  \"F\"-> followingUser(ObjectId(post.userId),false)\n                  \"UN\"->followingUser(ObjectId(post.userId),true)\n               }\n          }\n\n      }\n\n    }\n\n    private  suspend fun followingUser(userId: ObjectId, isFollowing: Boolean=false){\n       if (userId==actualUser.id) println(\"you can't follow yourself don't be a cheater\")\n       else userRepo.unOrfollowing(actualUser.id, userId, isFollowing)\n    }\n\n  }\n\n\n\n\nfun main(): Unit= runBlocking {\n    runCatching { getDatabaseMongo(MONGO_DATABASE) }\n        .onFailure { println(\"failed to connect database ${it.message}\") }\n        .onSuccess {\n           val job=launch {\n               val userRepo = UserRepo(it.second)\n               val postRepo = RepoPost(it.second)\n               val social = BlueSky(userRepo, postRepo)\n               social.loginOrRegisterUser()\n               social.renderUserMenu()\n           }\n            job.join()\n            it.first.close()\n        }\n}"
  },
  {
    "path": "Roadmap/46 - X VS BLUESKY/php/miguelex.php",
    "content": "<?php\n\nclass SocialNetwork {\n    private $users = [];\n    private $posts = [];\n    private $follows = [];\n    private $likes = [];\n\n    public function registerUser($userId, $username) {\n        if (isset($this->users[$userId])) {\n            echo \"El usuario con ID $userId ya existe.\\n\";\n        } else {\n            $this->users[$userId] = $username;\n            echo \"Usuario $username registrado con éxito.\\n\";\n        }\n    }\n\n    public function followUser($followerId, $followeeId) {\n        if (!isset($this->users[$followerId]) || !isset($this->users[$followeeId])) {\n            echo \"Uno de los usuarios no existe.\\n\";\n            return;\n        }\n        $this->follows[$followerId][$followeeId] = true;\n        echo \"Usuario $followerId ahora sigue a $followeeId.\\n\";\n    }\n\n    public function unfollowUser($followerId, $followeeId) {\n        if (isset($this->follows[$followerId][$followeeId])) {\n            unset($this->follows[$followerId][$followeeId]);\n            echo \"Usuario $followerId ha dejado de seguir a $followeeId.\\n\";\n        } else {\n            echo \"El usuario $followerId no sigue a $followeeId.\\n\";\n        }\n    }\n\n    public function createPost($userId, $postId, $text) {\n        if (!isset($this->users[$userId])) {\n            echo \"El usuario no existe.\\n\";\n            return;\n        }\n        if (strlen($text) > 200) {\n            echo \"El texto del post excede los 200 caracteres.\\n\";\n            return;\n        }\n        $this->posts[$postId] = [\n            'userId' => $userId,\n            'text' => $text,\n            'createdAt' => date('Y-m-d H:i:s'),\n            'likes' => 0\n        ];\n        echo \"Post creado con éxito.\\n\";\n    }\n\n    public function deletePost($postId) {\n        if (isset($this->posts[$postId])) {\n            unset($this->posts[$postId]);\n            echo \"Post eliminado con éxito.\\n\";\n        } else {\n            echo \"El post no existe.\\n\";\n        }\n    }\n\n    public function likePost($userId, $postId) {\n        if (!isset($this->users[$userId])) {\n            echo \"El usuario no existe.\\n\";\n            return;\n        }\n        if (!isset($this->posts[$postId])) {\n            echo \"El post no existe.\\n\";\n            return;\n        }\n        $this->likes[$userId][$postId] = true;\n        $this->posts[$postId]['likes']++;\n        echo \"Like añadido al post $postId.\\n\";\n    }\n\n    public function unlikePost($userId, $postId) {\n        if (isset($this->likes[$userId][$postId])) {\n            unset($this->likes[$userId][$postId]);\n            $this->posts[$postId]['likes']--;\n            echo \"Like eliminado del post $postId.\\n\";\n        } else {\n            echo \"El usuario no ha hecho like en el post $postId.\\n\";\n        }\n    }\n\n    public function viewUserFeed($userId) {\n        if (!isset($this->users[$userId])) {\n            echo \"El usuario no existe.\\n\";\n            return;\n        }\n        $userPosts = array_filter($this->posts, function($post) use ($userId) {\n            return $post['userId'] == $userId;\n        });\n        usort($userPosts, function($a, $b) {\n            return strtotime($b['createdAt']) - strtotime($a['createdAt']);\n        });\n        $userPosts = array_slice($userPosts, 0, 10);\n        foreach ($userPosts as $post) {\n            echo \"ID: {$post['userId']}, Usuario: {$this->users[$post['userId']]}, Texto: {$post['text']}, Fecha: {$post['createdAt']}, Likes: {$post['likes']}\\n\";\n        }\n    }\n\n    public function viewFollowedFeed($userId) {\n        if (!isset($this->users[$userId])) {\n            echo \"El usuario no existe.\\n\";\n            return;\n        }\n        $followedPosts = [];\n        if (isset($this->follows[$userId])) {\n            foreach ($this->follows[$userId] as $followeeId => $value) {\n                foreach ($this->posts as $postId => $post) {\n                    if ($post['userId'] == $followeeId) {\n                        $followedPosts[] = $post;\n                    }\n                }\n            }\n        }\n        usort($followedPosts, function($a, $b) {\n            return strtotime($b['createdAt']) - strtotime($a['createdAt']);\n        });\n        $followedPosts = array_slice($followedPosts, 0, 10);\n        foreach ($followedPosts as $post) {\n            echo \"ID: {$post['userId']}, Usuario: {$this->users[$post['userId']]}, Texto: {$post['text']}, Fecha: {$post['createdAt']}, Likes: {$post['likes']}\\n\";\n        }\n    }\n}\n\n// Menú interactivo\n$network = new SocialNetwork();\n\nwhile (true) {\n    echo \"Seleccione una opción:\\n\";\n    echo \"1. Registrar usuario\\n\";\n    echo \"2. Seguir a un usuario\\n\";\n    echo \"3. Dejar de seguir a un usuario\\n\";\n    echo \"4. Crear post\\n\";\n    echo \"5. Eliminar post\\n\";\n    echo \"6. Hacer like en un post\\n\";\n    echo \"7. Eliminar like de un post\\n\";\n    echo \"8. Ver feed del usuario\\n\";\n    echo \"9. Ver feed de usuarios seguidos\\n\";\n    echo \"0. Salir\\n\";\n    $option = readline(\"Opción: \");\n\n    switch ($option) {\n        case 1:\n            $userId = readline(\"ID de usuario: \");\n            $username = readline(\"Nombre de usuario: \");\n            $network->registerUser($userId, $username);\n            break;\n        case 2:\n            $followerId = readline(\"ID del seguidor: \");\n            $followeeId = readline(\"ID del seguido: \");\n            $network->followUser($followerId, $followeeId);\n            break;\n        case 3:\n            $followerId = readline(\"ID del seguidor: \");\n            $followeeId = readline(\"ID del seguido: \");\n            $network->unfollowUser($followerId, $followeeId);\n            break;\n        case 4:\n            $userId = readline(\"ID de usuario: \");\n            $postId = readline(\"ID del post: \");\n            $text = readline(\"Texto del post: \");\n            $network->createPost($userId, $postId, $text);\n            break;\n        case 5:\n            $postId = readline(\"ID del post: \");\n            $network->deletePost($postId);\n            break;\n        case 6:\n            $userId = readline(\"ID de usuario: \");\n            $postId = readline(\"ID del post: \");\n            $network->likePost($userId, $postId);\n            break;\n        case 7:\n            $userId = readline(\"ID de usuario: \");\n            $postId = readline(\"ID del post: \");\n            $network->unlikePost($userId, $postId);\n            break;\n        case 8:\n            $userId = readline(\"ID de usuario: \");\n            $network->viewUserFeed($userId);\n            break;\n        case 9:\n            $userId = readline(\"ID de usuario: \");\n            $network->viewFollowedFeed($userId);\n            break;\n        case 0:\n            exit(\"¡Hasta luego!\\n\");\n        default:\n            echo \"Opción no válida. Intente de nuevo.\\n\";\n            break;\n    }\n}\n\n"
  },
  {
    "path": "Roadmap/46 - X VS BLUESKY/python/CarlosVR48.py",
    "content": "\"\"\"\nEJERCICIO:\n * La alternativa descentralizada a X, Bluesky, comienza a atraer\n * a nuevos usuarios. ¿Cómo funciona una red de este estilo?\n *\n * Implementa un sistema que simule el comportamiento de estas\n * redes sociales.\n *\n * Debes crear las siguientes operaciones:\n * - Registrar un usuario por nombre e identificador único.\n * - Un usuario puede seguir/dejar de seguir a otro.\n * - Creación de post asociado a un usuario. Debe poseer\n *   texto (200 caracteres máximo), fecha de creación \n *   e identificador único.  \n * - Eliminación de un post.\n * - Posibilidad de hacer like (y eliminarlo) en un post.\n * - Visualización del feed de un usuario con sus 10 publicaciones\n *   más actuales ordenadas desde la más reciente.\n * - Visualización del feed de un usuario con las 10 publicaciones\n *   más actuales de los usuarios que sigue ordenadas \n *   desde la más reciente.\n *\n * Cuando se visualiza un post, debe mostrarse:\n * ID de usuario, nombre de usuario, texto del post,\n * fecha de creación y número total de likes.\n *\n * Controla errores en duplicados o acciones no permitidas.\n\"\"\"\nfrom pytz import timezone\nfrom os import system\nimport datetime\n\ndef mostrar_posts(nombre):\n    try:\n        with open(\"post.txt\", \"x\", encoding = \"utf-8\") as a:\n            a.write(\"\")\n        with open(\"likes.txt\", \"x\", encoding = \"utf-8\") as a:\n            a.write(\"\")\n    except:\n        pass\n    #En la variable nombre esta puesto el nombre de usuario logeado\n    usuario=nombre\n    index = 1\n    no_muestra = list()\n    #Con la variable index se hace el recorrido 3 veces que son los datos del post\n    #y se mira si el usuario logeado no sigue el post. se guarda el nombre del post\n    #en la variable nombre\n    with open(nombre, \"r\", encoding = \"utf-8\") as posts:\n        for post in posts:\n            if index == 2:\n                nombre_desc = post\n            elif index == 3:\n                if post == \"N\\n\":\n                    no_muestra.append(nombre_desc)\n                index = 0\n            index = index + 1\n             \n    opcion = input(\"QUIERES CONTINUAR DONDE LO DEJASTES ? (S/N) \").upper()\n\n    if opcion == \"N\":\n        #Ahora se hace un recorrido por cada post\n        contador = 1\n        with open(\"post.txt\", \"r\", encoding = \"utf-8\") as posts:\n            for post in posts:\n                if contador == 1:\n                    numero_post = post\n                elif contador == 2:\n                    fecha = post\n                elif contador == 3:\n                    nombre = post    \n                elif contador == 4:\n                    contador = 0\n                    links_total = 0\n                    index = 1\n                    # Se cuentan los likes que tiene el post\n                    with open(\"likes.txt\", \"r\", encoding = \"utf-8\") as likes:    \n                        for like in likes:\n                            if index == 1:\n                                if numero_post == like: \n                                    links_total = links_total + 1\n                            elif index == 3:\n                                index = 0\n                            \n                            index = index + 1\n                    \n                    # Se comprueba el post y si esta en no_muestra no se enseña\n                    if no_muestra.count(nombre) == 0 :\n                        system(\"cls\")\n                        print (\"-------------------------------------- RED SOCIAL XBLUE ---------------------------------------------\\n\")\n                        print (f\"{fecha}\\n{nombre}\\n{post}\\nLIKES: {links_total}\")\n                        print (\"-----------------------------------------------------------------------------------------------------\\n\")\n                        sub_menu(nombre,numero_post,usuario)\n                \n                contador = contador + 1\n    \n    elif opcion == \"S\":\n        try:    \n            n=0\n            #se lee el archivo continuar.txt si el nombre del usuario esta en el archivo se captura donde lo dejo\n            index = 1\n            with open(\"continua.txt\", \"r\", encoding = \"utf-8\") as con:\n                for c in con:\n                    if index == 1:\n                        u = c\n                    elif index == 2:\n                        index = 0\n                        if f\"{nombre}\\n\" == u:\n                            n = c\n                    index = index + 1\n        except:\n            pass\n        \n        contador = 1\n        with open(\"post.txt\", \"r\", encoding = \"utf-8\") as posts:\n            for post in posts:\n                if contador == 1:\n                    numero_post = post\n                elif contador == 2:\n                    fecha = post\n                elif contador == 3:\n                    nombre = post    \n                elif contador == 4:\n                    contador = 0\n                    # Se cuentan los likes que tiene el post\n                    links_total = 0\n                    index = 1\n                    with open(\"likes.txt\", \"r\", encoding = \"utf-8\") as likes:    \n                        for like in likes:\n                            if index == 1:\n                                if numero_post == like: \n                                    links_total = links_total + 1\n                            elif index == 3:\n                                index = 0\n                            \n                            index = index + 1\n                \n                    if no_muestra.count(nombre) == 0 and int(n) <= int(numero_post):\n                        system(\"cls\")\n                        print (\"-------------------------------------- RED SOCIAL XBLUE ---------------------------------------------\\n\")\n                        print (f\"{fecha}\\n{nombre}\\n{post}\\nLIKES: {links_total}\")\n                        print (\"-----------------------------------------------------------------------------------------------------\\n\")\n                        sub_menu(nombre,numero_post,usuario) \n                contador = contador + 1\n\n#En este submenu se muestra la barra de navegacion y se escribe el resultado en el fichero del usuario logueado,\n# para controlar los datos principales de la red social\n \ndef sub_menu(nombre,numero_post,usuario):\n    index = 1\n    opcion = input (\"\\n(L)IKE (D)ISLIKE (N)OSEGUIR (G)RABAR (ENTER CONTINUA) \").upper()\n    \n    if opcion == \"G\":\n        try:\n            with open(\"continua.txt\", \"a\", encoding = \"utf-8\") as con:\n                con.write(f\"{usuario}\\n\")\n                con.write(f\"{numero_post}\")\n        except:\n            with open(\"continua.txt\", \"w\", encoding = \"utf-8\") as con:\n                con.write(f\"{usuario}\\n\")\n                con.write(f\"{numero_post}\")\n\n    if opcion == \"L\":\n        like = False\n        with open(\"likes.txt\", \"r\", encoding = \"utf-8\") as posts:\n            for post in posts:\n                if index == 1 :\n                    id_post = post\n                elif index == 3 :\n                    nom = post\n                    index = 0\n                    if id_post == numero_post and nom == f\"{usuario}\\n\" :\n                        like = True\n                        input (\"                 YA LE HAS DADO LIKE\")\n                index = index +1    \n        \n        if like == False:   \n            with open(\"likes.txt\", \"a\", encoding = \"utf-8\") as likes:\n                likes.write(numero_post)\n                likes.write(f\"{nombre}\")\n                likes.write(f\"{usuario}\\n\")\n        \n            with open(usuario, \"a\", encoding = \"utf-8\") as us:\n                us.write(f\"{numero_post}\")\n                us.write(f\"{nombre}\")\n                us.write(f\"{opcion}\\n\")\n\n    if opcion ==\"D\":\n        #copio archivo likes en disklikes excepto el post que se ha hecho el dislike\n        with open (\"likes.txt\", \"r\", encoding = \"utf-8\") as likes:\n            with open (\"dislike.bak\", \"w\", encoding = \"utf-8\") as disbak:\n                index = 1\n                for like in likes:\n                    if index == 1 :\n                        nume = like\n                    elif index == 2:\n                        no = like\n                    elif index == 3:\n                        index = 0\n                        use = like\n                        if  nume == numero_post and use == f\"{usuario}\\n\":\n                            pass\n                        else :\n                            disbak.write(nume)\n                            disbak.write(no)\n                            disbak.write(use)\n                    index = index + 1\n        #ahora copio el archivo dislike a like \n        with open (\"dislike.bak\", \"r\", encoding = \"utf-8\") as dislikes:\n            with open (\"likes.txt\", \"w\", encoding = \"utf-8\") as likes:\n                index = 1\n                for dislike in dislikes:\n                    if index == 1 :\n                        nume = dislike\n                    elif index == 2:\n                        no = dislike\n                    elif index == 3:\n                        use = dislike\n                        likes.write(nume)\n                        likes.write(no)\n                        likes.write(use)\n                        index = 0\n                    index = index + 1\n\n    if opcion == \"N\":    \n        with open(usuario, \"a\", encoding = \"utf-8\") as posts:\n            posts.write(f\"{numero_post}\")\n            posts.write(f\"{nombre}\")\n            posts.write(f\"{opcion}\\n\")\n\ndef registro():\n    #si no esta creado el archivo da un error\n    try:\n        with open(\"usuarios.txt\", \"x\", encoding = \"utf-8\") as a:\n            a.write(\"\")\n    except:\n        pass\n\n    index  = 1\n    salir = 1\n    coinciden = 0\n    while salir :\n        nombre = input (\"\\nCREA TU NOMBRE DE USUARIO (ENTER PARA SALIR) ? \")\n        if nombre == \"\":\n            salir = 0\n        else:    \n            #compruebo el nombre en la lista de usuarios que has introducido \n            with open(\"usuarios.txt\", \"r\", encoding = \"utf-8\") as usuarios:\n                for user in usuarios:\n                    if index == 1:\n                        usuario_log = user\n                        if usuario_log == f\"{nombre}\\n\":\n                            input ( \"    TU USUARIO YA ESTA INSCRITO!!! \")\n                            salir=0\n                            coinciden = 1\n\n                    elif index == 2:\n                        index = 0\n                    \n                    index = index +1\n                    \n                if coinciden == 0:\n                    pasword = input (\"    CREA TU CONTRASEÑA ? \")\n                    #escribo nombre y password en usuario.txt\n                    with open(\"usuarios.txt\", \"a\", encoding = \"utf-8\") as usuarios:\n                        usuarios.write(f\"{nombre}\")\n                        usuarios.write(f\"\\n{pasword}\\n\")\n                    #creo el archivo con el nombre de usuario para guardar datos\n                    with open(nombre, \"w\", encoding = \"utf-8\") as nom:\n                        nom.write(\"\")\n                    \n                    input (\"\\nMUY BIEN YA PUEDES UTILIZAR LA RED SOCIAL!!! \")\n                    return nombre\n\ndef id():\n    marcador = 1\n    nombre = input (\"\\n    DIME TU NOMBRE ? \")\n    pasword = input (\"    DIME TU CONTRASEÑA ? \")\n\n    while True:\n        #si el usuario quiere identificarse sin estar creado archivo usuarios da otro error\n        try:\n            #compruebo si existe el usuario\n            with open(\"usuarios.txt\", \"r\", encoding = \"utf-8\") as usuarios:\n                    for user in usuarios:\n                        if marcador == 1:\n                            nombre_fichero = user\n                        elif marcador == 2:\n                            pasword_fichero = user\n                            marcador = 0\n                            if f\"{nombre}\\n\" == nombre_fichero:\n                                if f\"{pasword}\\n\" == pasword_fichero:\n                                    print (f\"USUARIO: {nombre} \")\n                                    return nombre,pasword\n                                else:\n                                    input (\"CONTRASEÑA INVALIDA !!! \")\n                                    return None,None\n                        marcador = marcador + 1 \n        except:\n            input(\"    NO HAY USUARIOS INSCRITOS \")\n            return None,None\n           \n        input(\"    TU USUARIO NO EXISTE !!! \")\n        return None,None\n\ndef crear_post(nombre):\n    salir = True\n    fecha_hora = datetime.datetime.now(timezone(\"UTC\"))\n    fyh = datetime.datetime.strftime(fecha_hora,\"%d-%m-%Y %H:%M:%S %z\")\n    numero_id = 0\n    contador = 1\n    try:\n        with open(\"post.txt\", \"r\", encoding = \"utf-8\") as posts:\n            for post in posts:\n                if contador == 1:\n                    numero_id = post\n                elif contador == 4:\n                    contador = 0\n                contador = contador + 1            \n    except:\n        pass\n\n    numero_id = int(numero_id) + 1\n    \n    while salir:\n            print (\"\\nEL POST NO DEVE SUPERAR LOS 200 CARACTERES. INTRODUCE EL POST...\\n\")\n            post = input ()\n            if len(post)>200:\n                print (\"    EL POST SUPERA LOS 200 CARACTERES !!!\")\n            else:\n                salir = False\n\n    with open(\"post.txt\", \"a\", encoding = \"utf-8\") as pag:\n        pag.write(f\"{numero_id}\\n\")\n        pag.write(f\"{fyh}\\n\")\n        pag.write(f\"{nombre}\\n\")\n        pag.write(f\"{post}\\n\")\n\ndef elimina(nombre_log):\n    contador = 1\n    with open(\"post.txt\", \"r\", encoding = \"utf-8\") as posts:\n        with open(\"post.bak\", \"w\", encoding = \"utf-8\") as bak:\n            for post in posts:\n                if contador == 1:\n                    numero_post = post\n                elif contador == 2:\n                    fecha = post\n                elif contador == 3:\n                    nombre = post    \n                elif contador == 4:\n                    contador = 0\n                    system(\"cls\")\n                    print (\"-------------------------------------- RED SOCIAL XBLUE ---------------------------------------------\\n\")\n                    print (f\"{fecha}\\n{nombre}\\n{post}\\n\")\n                    print (\"-----------------------------------------------------------------------------------------------------\\n\")\n                    \n                    if nombre == f\"{nombre_log}\\n\":\n                        borrar = input  (\"    QUERES BORRARLO (S/N) ? \").upper()\n                        if borrar == \"S\":\n                            pass\n                        else:\n                            bak.write(numero_post)\n                            bak.write(fecha)\n                            bak.write(nombre)\n                            bak.write(post)\n                    else:\n                        bak.write(numero_post)\n                        bak.write(fecha)\n                        bak.write(nombre)\n                        bak.write(post)\n                contador = contador + 1\n    \n    with open(\"post.bak\", \"r\", encoding = \"utf-8\") as bak:\n        with open(\"post.txt\", \"w\", encoding = \"utf-8\") as posts:\n            for b in bak:\n                posts.write(b)\n\ndef vfeed(usuario):\n    index = 1\n    with open(\"post.txt\", \"r\", encoding = \"utf-8\") as posts:\n        for post in posts:\n            if index == 1 :\n               id = post\n            elif index == 2:\n               fecha = post\n            elif index == 3 :\n                nombre = post\n            elif index == 4 :\n                index = 0\n                text = post\n                \n                links_total = 0\n                ind = 1\n                with open(\"likes.txt\", \"r\", encoding = \"utf-8\") as likes:    \n                    for like in likes:\n                        if ind == 1:\n                            if id == like: \n                                links_total = links_total + 1\n                        elif ind == 3:\n                            ind = 0\n                        ind = ind + 1\n\n                if nombre == f\"{usuario}\\n\" :\n                    print (\"-------------------------------------- RED SOCIAL XBLUE ---------------------------------------------\\n\")\n                    print (f\"{fecha}\\n{nombre}\\n{text}\\nLIKES: {links_total}\")\n                    print (\"-----------------------------------------------------------------------------------------------------\\n\")\n                    \n            index = index + 1\n    \n    input(\"    PULSA ENTER PARA CONTINUAR\")\n\ndef vfeed_usuarios():\n    usuario = input (\"    DIME EL NOMBRE DEL USUARIO ? \")\n    index = 1\n    no_muestra = list()\n\n    with open(usuario, \"r\", encoding = \"utf-8\") as posts:\n        for post in posts:\n            if index == 2:\n                nombre_desc = post\n            elif index == 3:\n                if post == \"N\\n\":\n                    no_muestra.append(nombre_desc)\n                index = 0\n            index = index + 1\n    \n    index = 1\n    with open(\"post.txt\", \"r\", encoding = \"utf-8\") as posts:\n        for post in posts:\n            if index == 1 :\n               id = post\n            elif index == 2 :\n               fecha = post\n            elif index == 3 :\n                nombre = post\n            elif index == 4 :\n                index = 0\n                text = post\n                \n                ind = 1\n                links_total = 0\n\n                with open(\"likes.txt\", \"r\", encoding = \"utf-8\") as likes:    \n                    for like in likes:\n                        if ind == 1:\n                            if id == like: \n                                links_total = links_total + 1\n                        elif ind == 3:\n                            ind = 0\n                        ind = ind + 1\n                \n                if no_muestra.count(nombre) == 0 and nombre != f\"{usuario}\\n\":\n                    print (\"-------------------------------------- RED SOCIAL XBLUE ---------------------------------------------\\n\")\n                    print (f\"{fecha}\\n{nombre}\\n{text}\\nLIKES: {links_total}\")\n                    print (\"-----------------------------------------------------------------------------------------------------\\n\")\n\n            index = index + 1\n    \n    input(\"    PULSA ENTER PARA CONTINUAR\")\n\ndef menu_principal(nombre):\n    salir = True\n    while salir:\n        hora_or = datetime.datetime.today()\n        hora_utc = datetime.datetime.now(timezone(\"UTC\"))\n        hora_or_mod = datetime.datetime.strftime(hora_or,\"%d-%m-%Y %H:%M:%S LOCAL\")\n        hora_utc_mod = datetime.datetime.strftime(hora_utc,\"%d-%m-%Y %H:%M:%S UTC\")\n        system(\"cls\")\n        print (f\"{hora_utc_mod}\\n{hora_or_mod}\\n\\n--- RED SOCIAL XBLUE ---\\n\")\n        print (f\"    USUARIO: {nombre}\\n\")\n        print (\"    1 - REGISTRATE\\n    2 - IDENTIFICATE\\n    3 - CREAR POST\\n    4 - MOSTRAR POSTS\\n    5 - ELIMINA TUS POST\\n    6 - V. FEED DEL USUARIO\\n    7 - V. FEED DE LOS USUARIOS\\n    8 - SALIR\\n\")\n        seleccion = input(\"    QUE DESEAS HACER ? \")\n        if seleccion == \"1\":\n            nombre = registro()\n        elif seleccion == \"2\":\n            nombre, pasword = id()\n        elif seleccion == \"3\" and nombre != None:\n            crear_post(nombre)\n        elif seleccion == \"4\" and nombre != None:\n            mostrar_posts(nombre)\n        elif seleccion == \"5\" and nombre != None:\n            elimina(nombre)\n        elif seleccion == \"6\" and nombre != None:\n            vfeed(nombre)\n        elif seleccion == \"7\" and nombre != None:\n            vfeed_usuarios()\n        elif seleccion == \"8\" :\n            salir = False\n\nnombre = None\nmenu_principal(nombre)\n\n# Archivo (post.txt) guarda todos los post . Id post , fecha UTC de creacion , nombre del usuario y texto.\n# Archivo (usuarios) guarda todo los usuarios y sus contraseñas.\n# Archivo (nombreusuario) guarda todo el historial generado. Id del post , nombre al que le haces la accion y accion\n# Archivo (likes.txt) guarda todo lo relacionado con like. Id del mensage , nombre associado al post y nombre del usuario\n# Archivo (continua.txt) guarda el nombre del usuario y el numero donde lo has grabado"
  },
  {
    "path": "Roadmap/46 - X VS BLUESKY/python/Gordo-Master.py",
    "content": "# 46 - X vs Bluesky\nimport datetime\n\nclass Person:\n    def __init__(self, id, name):\n        self.id = id\n        self.name = name\n        self.followed = []\n        self.posts = []\n\n    def __eq__(self, other):\n        if not isinstance(other, Person):\n            return NotImplemented\n        return self.name == other.name and self.id == other.id\n    \n    def __hash__(self):\n        return hash((self.id,self.name))\n\n    def follow_user(self, user):\n        if user in self.followed:\n            print(f\"{self.name} ya esta siguiendo a esa cuenta ID[{user.id}]: {user.name}\")\n        else:\n            self.followed.append(user)\n            print(f\"{self.name} ha comenzado a seguir a ID[{user.id}]: {user.name}!\")\n\n    def unfollow_user(self, user):\n        if user in self.followed:\n            self.followed.remove(user)\n            print(f\"{self.name} ha dejado de seguir a ID[{user.id}]: {user.name}!\")\n        else:\n            print(\"Ese usuario no se encuentra en la lista de seguidos.\")\n\n    def show_followed(self):\n        print(f\"Lista de seguidos de {self.name}\")\n        if self.followed:\n            for user in self.followed:\n                print(f\"{user.name}[ID:{user.id}]\",end=\" - \")\n            print()\n        else:\n            print(f\"{self.name} no sigue a nadie\")\n\n    def create_post(self, post_item):\n        self.posts.append(post_item)\n\n    def del_post(self, post_item):\n        self.posts.remove(post_item)\n\n    def show_feeds(self):\n        list_feed_ordenate = sorted(self.posts, key = lambda x: x.create_date , reverse= True)\n        count = 0\n        for post in list_feed_ordenate:\n            count += 1\n            print(f\"Post: {count}\")\n            post.show_post(self)\n            if count >= 10:\n                break\n    \n    def return_feeds(self):\n        list_of_feeds = sorted(self.posts, key = lambda x: x.create_date , reverse= True)\n        return list_of_feeds\n\n    def show_followed_feeds(self):\n        followed_feeds = [x.return_feeds() for x in self.followed]\n        plain_followed_feeds = [x for sublist in followed_feeds for x in sublist]\n        plain_followed_feeds.sort(key=lambda x: x.create_date, reverse= True)\n        count = 0\n        for post in plain_followed_feeds:\n            count += 1\n            print(f\"Post: {count}\")\n            post.show_post(post.user)\n            if count >= 10:\n                break\n\n\nclass Post:\n    def __init__(self,user: Person ,post_id: int, created_date: datetime.datetime, text : str):\n        self.user = user\n        self.post_id = post_id\n        self.create_date = created_date\n        self.text = text\n        self.like_list = []\n\n    def __eq__(self, other):\n        if not isinstance(other, Post):\n            return NotImplemented\n        return self.user.id == other.user.id and self.post_id == other.post_id\n    \n    def __hash__(self):\n        return hash((self.user.id,self.post_id))\n    \n    def add_like_post(self, user: Person):\n        self.like_list.append(user)\n    \n    def remove_like_post(self, user: Person):\n        self.like_list.remove(user)\n\n    def show_post(self, user):\n        if not user == self.user:\n            print(\"Error: El usuario no es el que hizo este post\")\n            return\n        print(f\"Post [ID:{self.post_id}] de {user.name} [{user.id}]\")\n        print(f\"Fecha: {self.create_date.strftime(\"%d/%m/%Y\")}\")\n        print(f\"Text: {self.text}\")\n        print(f\"Likes: {len(self.like_list)}\")\n        if self.like_list:\n            print(f\"{[x.name for x in self.like_list]}\")\n\n\nclass GreenXsky:\n    def __init__(self):\n        self.users = []\n        self.posts = []\n    # Funcion para saber si existe el usuario en la lista de usuarios\n    def exist_user_ID(self, user_ID: int):\n        if self.users:\n            for user in self.users:\n                if user.id == user_ID:\n                    return True\n            return False\n        return False\n    # Funcion para saber si existe el nombre\n    def exist_user_name(self, user_name):\n        if self.users:\n            for user in self.users:\n                if user_name == user.name:\n                    return True\n            return False\n        return False\n    # Funcion para obtener un usuario (Person) a partir de una ID\n    def from_ID_obtain_user(self, user_id) -> Person|None:\n        for user in self.users:\n            if user.id == user_id:\n                return user\n        else:\n            print(\"No existe usuario con esa ID!\")\n    # Realiza una validacion de si existen los usuarios y luego aplica un funcion dada en \"metod_object\",\n    # que debe ser una funcion de la clase de user_ID (Person), dando como argumento other (Person), aunque\n    # se le pase solo el ID de other (other_ID)\n    def validate_and_run_user_un_follow(self, metod_object, user_ID, other_ID):\n        if not self.exist_user_ID(user_ID) or not self.exist_user_ID(other_ID):\n                print(\"Uno de los ID no existe.\")\n                return\n        if user_ID == other_ID:\n            print(\"No puede ser el mismo ID.\")\n            return\n        other = self.from_ID_obtain_user(other_ID)\n        for user in self.users:\n            if user.id == user_ID:\n                metod = getattr(user, metod_object, None)\n                if callable(metod):\n                    metod(other)\n                else:\n                    print(f\"El método '{metod_object}' no existe.\")\n                return\n    # Registra un usuario en la lista de usuario del objeto de clase GreenXsky\n    def register_user(self,id ,name):\n        if not self.exist_user_ID(id) and not self.exist_user_name(name):\n            self.users.append(Person(id,name))\n            print(f\"Usuario [ID:{id}]: {name} creado exitosamente\")\n        else:\n            print(f\"Ya existe el ID:[{id}] y/o el nombre: {name}\")\n\n    def show_user_followed(self, user_ID):\n        user = self.from_ID_obtain_user(user_ID)\n        user.show_followed()\n    # Funcion para verificar si el text es str y si tiene 200 caracteres como maximo\n    def verify_text(self, text):\n        if not isinstance(text,str):\n            print(\"Valor invalido. Ingrese una cadena de texto\")\n            return None\n        if not len(text)<=200:\n            print(\"Error: El texto debe poseer como maximo 200 caracteres\")\n            return None\n        return text\n        \n    def create_post(self, user_ID: int, post_ID: int, text: str, date: str):\n        # Verifica si existe el usuario\n        if not self.exist_user_ID(user_ID):\n            print(f\"No existe el usuario con ID: {user_ID}\")\n            return None\n        user = self.from_ID_obtain_user(user_ID)\n        print(f\"Creando el post de {user.name} [ID: {user.id}]!\")\n        # Se verifica el texto\n        verified_text = self.verify_text(text)\n        if not verified_text:\n            return None\n        # Verificar si existe el id del post\n        exist_post_id = next((u for u in self.posts if u.post_id == post_ID), None)\n        if exist_post_id:\n            print(f\"Id del post ({post_ID}) ya existe!\")\n            return None\n        # Si pasa las verificaciones se aplica el create post\n        formated_date = datetime.datetime.strptime(date,\"%d/%m/%Y\")\n        # Se crea el post\n        post_greenxsky = Post(user, post_ID, formated_date, verified_text)\n        # Se adhiere a las listas, del objeto de GreenXsky y al objeto de Person\n        user.create_post(post_greenxsky)\n        self.posts.append(post_greenxsky)\n        print(f\"Se ha creado el post exitosamente:\\nPost: {verified_text}\")\n\n    def del_post(self, post_ID):\n        # Se optiene el post\n        post = next((x for x in self.posts if x.post_id == post_ID), None)\n        # Se verifica si existe el post\n        if not post:\n            print(f\"No existe post con ese ID: {post_ID}\")\n            return None\n        # Se optiene el user\n        user: Person = next((x for x in self.users if x == post.user), None)\n        # Se verifica que existe el user\n        if not user:\n            print(f\"No existe ese usuario con ID: {post.user.id}\")\n            return None\n        # Se elimina el post de la lista de post general\n        self.posts.remove(post)\n        # Se elimina el post de la lista del post del usuario\n        user.del_post(post)\n        print(f\"Se elimino el post de ID: {post_ID} exitosamente\")\n\n    def like_post(self, user_ID: int, post_ID: int):\n        post: Post = next((x for x in self.posts if x.post_id == post_ID), None)\n        user = next((x for x in self.users if x.id == user_ID), None)\n        # Verifica si existen el user y el post\n        if not post or not user:\n            print(f\"No existe el post de ID: {post_ID} o el user de ID: {user_ID} \")\n            return None\n        post.add_like_post(user)\n\n    def unlike_post(self, user_ID: int, post_ID: int):\n        # Verifica si existe el post en la lista de posts\n        post = next((x for x in self.posts if x.post_id == post_ID), None)\n        if not post:\n            print(f\"No existe el post de ID: {post_ID}\")\n            return None\n        # Verifica si existe el user en la lista de likes del post\n        user = next((x for x in post.like_list if x.id == user_ID), None)\n        if not user:\n            print(f\"No existe el user de ID: {user_ID} en la lista de likes\")\n            return None\n        # Elimina el like\n        post.remove_like_post(user)\n\n    def show_user_feed(self, user_ID: int):\n        user = next((x for x in self.users if x.id == user_ID), None)\n        if user:\n            user.show_feeds()\n\n    def show_user_followed_feed(self, user_ID: int):\n        user: Person = next((x for x in self.users if x.id == user_ID), None)\n        if user:\n            print(f\"Actualizacion de los feed de seguidos de {user.name}\")\n            user.show_followed_feeds()\n\n# Instanciando la clase maestra\ngreenxsky = GreenXsky()\n# Creando Usuarios\ngreenxsky.register_user(1,\"Juan\")\ngreenxsky.register_user(2,\"Fran\")\ngreenxsky.register_user(3,\"Lau\")\ngreenxsky.register_user(4,\"Jaz\")\ngreenxsky.register_user(5,\"Carl\")\ngreenxsky.register_user(6,\"John\")\ngreenxsky.register_user(3,\"Juan\") # Falla\ngreenxsky.register_user(3,\"Clark\") # Falla\n# Probando el follow\ngreenxsky.validate_and_run_user_un_follow(\"follow_user\",3,1)\ngreenxsky.validate_and_run_user_un_follow(\"follow_user\",3,1) # Falla\ngreenxsky.validate_and_run_user_un_follow(\"follow_user\",4,1)\ngreenxsky.validate_and_run_user_un_follow(\"follow_user\",5,1)\ngreenxsky.validate_and_run_user_un_follow(\"follow_user\",1,4)\ngreenxsky.validate_and_run_user_un_follow(\"follow_user\",1,5)\ngreenxsky.validate_and_run_user_un_follow(\"follow_user\",1,6)\n# Viendo los followed\ngreenxsky.show_user_followed(1)\ngreenxsky.show_user_followed(2)\n# Creando un post\ngreenxsky.create_post(\n    4,\n    1,\n    \"Hola mundo como estan!!\",\n    \"07/05/2025\"\n)\ngreenxsky.create_post(\n    4,\n    2,\n    \"Hola mundo como estan 2 !!\",\n    \"08/05/2025\"\n)\ngreenxsky.create_post(\n    4,\n    3,\n    \"Hola mundo como estan 3!!\",\n    \"09/05/2025\"\n)\ngreenxsky.create_post(\n    4,\n    4,\n    \"Hola mundo como estan 4 en el pasado!!\",\n    \"01/05/2025\"\n)\ngreenxsky.create_post(\n    4,\n    5,\n    \"Hola mundo como estan 5!!\",\n    \"10/05/2025\"\n)\ngreenxsky.create_post(\n    4,\n    6,\n    \"Hola mundo como estan 6!!\",\n    \"11/05/2025\"\n)\ngreenxsky.create_post(\n    4,\n    7,\n    \"Hola mundo como estan 7!!\",\n    \"12/05/2025\"\n)\ngreenxsky.create_post(\n    4,\n    8,\n    \"Hola mundo como estan 8!!\",\n    \"13/05/2025\"\n)\ngreenxsky.create_post(\n    4,\n    9,\n    \"Hola mundo como estan 9!!\",\n    \"14/05/2025\"\n)\ngreenxsky.create_post(\n    4,\n    10,\n    \"Hola mundo como estan 10!!\",\n    \"15/05/2025\"\n)\ngreenxsky.create_post(\n    4,\n    11,\n    \"Hola mundo como estan 11, el mejor!!\",\n    \"16/05/2025\"\n)\ngreenxsky.create_post(\n    4,\n    12,\n    \"Hola mundo como estan 12!!\",\n    \"17/05/2025\"\n)\n# A partir de aca es de 5\ngreenxsky.create_post(\n    5,\n    13,\n    \"Hola mundo como estan 13!!\",\n    \"12/05/2025\"\n)\ngreenxsky.create_post(\n    5,\n    14,\n    \"Hola mundo como estan 14!!\",\n    \"15/05/2025\"\n)\ngreenxsky.create_post(\n    5,\n    15,\n    \"Hola mundo como estan 15!!\",\n    \"20/05/2025\"\n)\ngreenxsky.create_post(\n    5,\n    16,\n    \"Hola mundo como estan 16!!\",\n    \"19/05/2025\"\n)\n# A partir de aca es el 6\ngreenxsky.create_post(\n    6,\n    17,\n    \"Hola mundo como estan 17!!\",\n    \"20/05/2025\"\n)\ngreenxsky.create_post(\n    6,\n    18,\n    \"Hola mundo como estan 18!!\",\n    \"19/05/2025\"\n)\ngreenxsky.create_post(\n    3,\n    19,\n    \"Hola mundo como estan 19!!\",\n    \"20/05/2025\"\n)\n\n# Borrando post\ngreenxsky.del_post(2)\n# Dando like a los post\ngreenxsky.like_post(1,11)\ngreenxsky.like_post(2,11)\ngreenxsky.like_post(3,11)\ngreenxsky.like_post(4,1)\n# Quitando like a los post\ngreenxsky.unlike_post(2,11)\ngreenxsky.unlike_post(4,5)\n# Mostrado el los ultimos 10 feeds\n# greenxsky.show_user_feed(4)\nprint()\ngreenxsky.show_user_followed_feed(1)"
  },
  {
    "path": "Roadmap/46 - X VS BLUESKY/python/JesusWay69.py",
    "content": "from __future__ import annotations\nimport os, platform\nfrom datetime import datetime as dt\nfrom typing import Dict, Set, TypedDict\n\n\nif (platform.platform().startswith(\"macOS\") or platform.platform().startswith(\"Linux\")):\n    os.system('clear')\nelse:\n    os.system('cls')\n\n\"\"\"\n * EJERCICIO:\n * La alternativa descentralizada a X, Bluesky, comienza a atraer\n * a nuevos usuarios. ¿Cómo funciona una red de este estilo?\n * \n * Implementa un sistema que simule el comportamiento de estas\n * redes sociales.\n * \n * Debes crear las siguientes operaciones:\n * - Registrar un usuario por nombre e identificador único. \n * - Un usuario puede seguir/dejar de seguir a otro. \n * - Creación de post asociado a un usuario. Debe poseer\n *   texto (200 caracteres máximo), fecha de creación \n *   e identificador único.                            \n * - Eliminación de un post.                           \n * - Posibilidad de hacer like (y eliminarlo) en un post. \n * - Visualización del feed de un usuario con sus 10 publicaciones\n *   más actuales ordenadas desde la más reciente.                 \n * - Visualización del feed de un usuario con las 10 publicaciones\n *   más actuales de los usuarios que sigue ordenadas \n *   desde la más reciente.\n *   \n * Cuando se visualiza un post, debe mostrarse:\n * ID de usuario, nombre de usuario, texto del post, \n * fecha de creación y número total de likes.\n * \n * Controla errores en duplicados o acciones no permitidas.\n\"\"\"\nclass Post(TypedDict):\n    message: str\n    date: dt\n    likes: Set[User]\n\nclass User:\n    auto_increment_user_id:int = 0\n    \n    def __init__(self, name:str) -> None:\n        self.name: str = name  \n        User.auto_increment_user_id += 1\n        self.id = User.auto_increment_user_id\n        self.user_posts: Dict[int, Post] = {}\n        self.index_message: int = 0\n        self.following: Set[User] = set()\n        self.followers: Set[User] = set()\n\n    def create_post(self, message: str) -> None:\n        if (len(message) > 200):\n            print(\"No se puede crear un post de más de 200 caracteres\")\n        else:\n            self.index_message +=1\n            self.user_posts[self.index_message] = {\n    \"message\": message,\n    \"date\": dt.now(),\n    \"likes\": set()\n}\n\n    def follow_users(self, *users: User) -> None:\n        for user in users:\n            if user.name == self.name:\n                continue\n            self.following.add(user)\n            user.followers.add(self)\n    \n    \n    def unfollow(self, user: User) -> None:  \n        if user in self.following:\n            self.following.remove(user) \n            user.followers.remove(self)\n            print(f\"{self.name} ha dejado de seguir a {user.name}\")\n        else:\n            print(f\"{self.name} no puede dejar de seguir a {user.name} porque no lo estaba siguiendo anteriormente\")\n\n\n    def show_posts(self) -> None:    \n        if len(self.user_posts) == 0:\n                print(f\"{self.name} no tiene nigún mensaje\")\n                return\n        print(f\"\\nMensajes de {self.name}:\\n\")\n        for key, value in reversed(self.user_posts.items()):\n            likes_counter = len(value[\"likes\"])\n            date = value[\"date\"]\n            print(f\"- {value[\"message\"]},  creado el \" \n                  f\"{date.strftime('%d/%m/%Y %H:%M:%S')},\"\n                  f\" message id: {self.id}-{key}, número de likes: {likes_counter}\"\n                  )\n        \n\n    def show_user_profile(self) -> None:\n        print(\n        f\"\\nINFORMACIÓN DE USUARIO\\n -------------------\\n\"\n        f\"Nombre: {self.name}, ID: {self.id}\\n\"\n        f\"\\nLe {'siguen' if len(self.followers) != 1 else 'sigue'} {len(self.followers)} \"\n        f\"{'usuarios' if len(self.followers) != 1 else 'usuario'}:\\n\"\n        )\n        for follower in self.followers:\n            print(\"-\", follower.name)\n        print(\n            f\"\\nSiguiendo a {len(self.following)}\"\n            f\" {'usuario:' if len(self.following) == 1 else ('usuarios' if len(self.following) == 0 else 'usuarios:')}\\n\"\n            )\n        for follower in self.following:\n            print(\"-\", follower.name)\n        self.show_posts()\n        self.show_following_feed()   \n        print()\n        \n    def show_following_feed(self) -> None:  \n        if len(self.following) == 0:\n            return\n        posts = []\n        for user in self.following:\n            for post_id, post in user.user_posts.items():\n                posts.append((user, post_id, post))\n\n        posts.sort(key=lambda x: x[2][\"date\"], reverse=True)\n        \n        print(f\"\\nFeed de {self.name} con publicaciones de usuarios seguidos:\\n\")\n        for user, post_id, post in posts[:10]:\n            likes_counter = len(post[\"likes\"])\n            date = post[\"date\"]\n            print(f\"- {user.name}: {post['message']} \"\n                f\"(ID {user.id}-{post_id}, {date.strftime('%d/%m/%Y %H:%M:%S')} \"\n                f\"{likes_counter} {'like' if likes_counter == 1 else 'likes'})\")\n        \n    def delete_post(self, messageID:int) -> None:\n        if type(messageID) != int:\n            print(\"Sólo se admite un dato numérico\")\n            return\n        if messageID not in self.user_posts:\n            print(f\"{self.name} no puede borrar el mensaje con id {self.id}-{messageID} porque no existe\")\n        else:\n            print(f\"{self.name} ha borrado su mensaje con id {self.id}-{messageID}\")\n            del(self.user_posts[messageID])\n    \n\n    def like_post(self, user:User, postId:int) -> None:\n        print(\"---------------------------\\n\")\n\n        if postId not in user.user_posts:\n            print(f\"{user.name} no tiene ningún mensaje con id {user.id}-{postId}\\n\")\n            return\n\n        message = user.user_posts[postId][\"message\"]\n\n        if self in user.user_posts[postId][\"likes\"]: \n            print(f\"{self.name} no puede dar like al mensaje '{message}' porque ya le dio like antes\\n\")\n            return\n\n        user.user_posts[postId][\"likes\"].add(self)\n        likes_counter = len(user.user_posts[postId][\"likes\"]) \n       \n        print(f\"{self.name} ha dado like al mensaje con id:{user.id}-{postId} de {user.name}\"\n            f\", el mensaje de {user.name} '{message}' acumula {likes_counter} {'like' if likes_counter == 1 else 'likes'}\\n\")\n\n\n    def unlike_post(self, user:User, postId:int):\n        print(\"---------------------------\\n\") \n        if postId not in user.user_posts:\n            print(f\"el usuario {user.name} no tiene ningún mensaje con id {postId}\\n\")\n            return\n        \n        message = user.user_posts[postId][\"message\"]\n\n        if self not in user.user_posts[postId][\"likes\"]:\n            print(f\"{self.name} no puede quitar el like del mensaje con id {postId} de {user.name}\",\n                  \"porque no le había dado like antes\\n\")\n            return\n        \n        user.user_posts[postId][\"likes\"].discard(self)\n        likes_counter = len(user.user_posts[postId][\"likes\"]) \n\n        print(f\"{self.name} ha quitado el like al mensaje con id:{postId} de {user.name}\"\n        f\", el mensaje de {user.name} '{message}' acumula {likes_counter} {'like' if likes_counter == 1 else 'likes'}\\n\")\n        return\n        \n#LISTA DE USUARIOS\nusers_list = [\"Jesus\", \"Sara\", \"Luis\", \"Ana\", \"Kevin\", \"Sandra\", \"Pedro\", \"Megan\", \"Victor\", \"Paula\",\n               \"Miguel\", \"Silvia\", \"Pablo\", \"Rocío\", \"Joseph\", \"Isabel\", \"Tony\", \"Cristina\", \"Marco\", \"Elena\"]\n\n#CREACIÓN DE INSTANCIAS DE CLASE\nusers = [User(name) for name in users_list]\njesus, sara, luis, ana, kevin, sandra, pedro, megan, victor, paula, \\\nmiguel, silvia, pablo, rocio, joseph, isabel, tony, cristina, marco, elena = users\n\n#CREACIÓN DE MENSAJES\njesus.create_post(f\"Este es el primer mensaje de {jesus.name}\")\njesus.create_post(f\"Este es el segundo mensaje de {jesus.name}\")\nsara.create_post(f\"Este es el primer mensaje de {sara.name}\")\npedro.create_post(f\"Este es el primer mensaje de {pedro.name}\")\nkevin.create_post(f\"Este es el primer mensaje de {kevin.name}\")\nsara.create_post(f\"Este es el segundo mensaje de {sara.name}\")\nelena.create_post(f\"Este es el primer mensaje de {elena.name}\")\nvictor.create_post(f\"Este es el primer mensaje de {victor.name}\")\nmiguel.create_post(f\"Este es el primer mensaje de {miguel.name}\")\njesus.create_post(f\"Este es el tercer mensaje de {jesus.name}\")\npaula.create_post(f\"Este es el primer mensaje de {paula.name}\")\nmarco.create_post(f\"Este es el primer mensaje de {marco.name}\")\njoseph.create_post(f\"Este es el primer mensaje de {joseph.name}\")\npaula.create_post(f\"Este es el segundo mensaje de {paula.name}\")\ncristina.create_post(f\"Este es el primer mensaje de {cristina.name}\")\nisabel.create_post(f\"Este es el primer mensaje de {isabel.name}\")\njesus.create_post(f\"Este es el cuarto mensaje de {jesus.name}\")\nkevin.create_post(f\"Este es el segundo mensaje de {kevin.name}\")\nmiguel.create_post(f\"Este es el primer mensaje de {miguel.name}\")\nmegan.create_post(f\"Este es el primer mensaje de {megan.name}\")\nkevin.create_post(f\"Este es el tercer mensaje de {kevin.name}\")\nluis.create_post(f\"Este es el primer mensaje de {luis.name}\")\nsilvia.create_post(f\"Este es el primer mensaje de {silvia.name}\")\n\n\n#CREACIÓN DE USUARIOS SEGUIDOS\njesus.follow_users(luis, ana, rocio, paula, sara, joseph, megan)\nsara.follow_users(pedro)\ncristina.follow_users(victor, jesus, paula, joseph, luis)\nana.follow_users(pedro, elena, joseph)\nvictor.follow_users(jesus, paula, tony, pablo)\nrocio.follow_users(megan, pedro, paula)\nisabel.follow_users(kevin, marco, victor, cristina, paula, megan, jesus, cristina)\nelena.follow_users(paula, isabel, kevin, joseph, victor, miguel, rocio, luis)\nmegan.follow_users(pedro, joseph, tony, cristina, megan)\nkevin.follow_users(marco, miguel, elena, pablo, jesus, sandra)\nsandra.follow_users(megan, paula, cristina, sara, silvia)\n\n#EL USUARIO marco INTENTA SEGUIRSE A SÍ MISMO, EL SISTEMA LO OBVIA Y NO LO REGISTRA\nmarco.follow_users(cristina, elena, megan, jesus, rocio, marco) \n\n#EL USUARIO miguel ABRE LA FUNCIÓN PARA SEGUIR A OTROS PERO NO NOMBRA A NADIE, EL SISTEMA LO OBVIA Y NO LO REGISTRA\nmiguel.follow_users()\n\n#EL USUARIO jesus INTENTA BORRAR UNA PUBLICACIÓN INEXISTENTE CON ID 4\njesus.show_user_profile()\njesus.delete_post(8)\n\n#EL USUARIO jesus BORRA SU SEGUNDA PUBLICACIÓN CON ID 2\njesus.delete_post(2)\njesus.show_user_profile()\n\n#LA USUARIA ISABEL INTENTA DEJAR DE SEGUIR A jesus AL QUE NO SEGUÍA ANTERIORMENTE\nisabel.unfollow(jesus)\n\n#LA USUARIA ISABEL DEJA DE SEGUIR A VICTOR\nvictor.show_user_profile()\nisabel.unfollow(victor)\nisabel.show_user_profile()\nvictor.show_user_profile()              \n\n#CREACIÓN DE VARIOS LIKES A MENSAJES CONCRETOS POR SU ID\ncristina.like_post(jesus, 1)\nelena.like_post(jesus, 1)\nisabel.like_post(victor, 1)\nkevin.like_post(jesus, 1)\nmegan.like_post(jesus, 3)\ncristina.like_post(jesus, 1)\njesus.like_post(kevin, 2)\nsara.like_post(luis, 1)\nmegan.like_post(jesus, 4)\njesus.like_post(silvia, 1)\n#jesus INTENTA DAR LIKE A UN MENSAJE DE JOSEPH QUE NO EXISTE\njesus.like_post(joseph, 2)\n\n#LA USUARIA cristina QUITA EL LIKE AL MENSAJE CON ID1 DE jesus\ncristina.unlike_post(jesus, 1)\n\n#LA USUARIA cristina INTENTA QUITAR UN LIKE A UN MENSAJE QUE NO HABÍA DADO LIKE ANTES\ncristina.unlike_post(joseph, 1)\n\n#MUESTRA DE PERFIL COMPLETO DE VARIOS USUARIOS\njesus.show_user_profile()\nsara.show_user_profile()\nmegan.show_user_profile()\npedro.show_user_profile() \nkevin.show_user_profile()\nmarco.show_user_profile()\nvictor.show_user_profile()\nelena.show_user_profile()\ncristina.show_user_profile()\nisabel.show_user_profile()\nmiguel.show_user_profile()\n\n\n\n\n"
  },
  {
    "path": "Roadmap/46 - X VS BLUESKY/python/Juanppdev.py",
    "content": "\"\"\"\n * EJERCICIO:\n * La alternativa descentralizada a X, Bluesky, comienza a atraer\n * a nuevos usuarios. ¿Cómo funciona una red de este estilo?\n * \n * Implementa un sistema que simule el comportamiento de estas\n * redes sociales.\n * \n * Debes crear las siguientes operaciones:\n * - crear login y register usando una base de datos usando json, pero que si el nombre de usuario ya existe decirlo\n * - crear un sistema de publicaciones\n * - crear un sistema de comentarios\n * - crear un sistema de likes\n * - crear un sistema de amigos\n * - poder buscar a amigos y seguirlos \n * - hacer retuits a los posts\n * - Registrar un usuario por nombre e identificador único.\n * - Un usuario puede seguir/dejar de seguir a otro.\n * - Creación de post asociado a un usuario. Debe poseer\n *   texto (200 caracteres máximo), fecha de creación \n *   e identificador único.\n * - Un usuario puede darle \"me gusta\" a un post.\n * - con una interface grafica  y con una sabe de datos json\n * - Eliminación de un post.\n * - Posibilidad de hacer like (y eliminarlo) en un post.\n * - Visualización del feed de un usuario con sus 10 publicaciones\n *   más actuales ordenadas desde la más reciente.\n * - Visualización del feed de un usuario con las 10 publicaciones\n *   más actuales de los usuarios que sigue ordenadas \n *   desde la más reciente.\n *   \n * Cuando se visualiza un post, debe mostrarse:\n * ID de usuario, nombre de usuario, texto del post, \n * fecha de creación y número total de likes.\n * \n * Controla errores en duplicados o acciones no permitidas.\n\n * Que hayan difrentes pantallas por ejemplo [\"login\", \"register\", \"feed\", \"profile\", \"config\", \"friends\", \"ver posts\"] y más\n\"\"\"\n\nimport json\nimport os\nimport hashlib\nfrom datetime import datetime\nimport tkinter as tk\nfrom tkinter import messagebox, ttk\n\n# Paths de las bases de datos\nUSERS_DB = \"./data/usuarios.json\"\nPOSTS_DB = \"./data/posts.json\"\n\n# === Gestión de Usuarios ===\n\ndef load_users():\n    if not os.path.exists(\"./data\"):\n        os.makedirs(\"./data\")  # Crea la carpeta data si no existe\n    if not os.path.exists(USERS_DB):\n        with open(USERS_DB, \"w\") as db:\n            json.dump({\"usuarios\": []}, db)\n    with open(USERS_DB, \"r\") as db:\n        return json.load(db)\n\ndef save_users(data):\n    with open(USERS_DB, \"w\") as db:\n        json.dump(data, db, indent=4)\n\ndef register(username, password):\n    data = load_users()\n    for user in data[\"usuarios\"]:\n        if user[\"username\"] == username:\n            return False, \"El nombre de usuario ya existe.\"\n    hashed_password = hashlib.sha256(password.encode()).hexdigest()\n    new_user = {\n        \"id\": len(data[\"usuarios\"]) + 1,\n        \"username\": username,\n        \"password\": hashed_password,\n        \"friends\": [],\n        \"following\": [],\n        \"followers\": []\n    }\n    data[\"usuarios\"].append(new_user)\n    save_users(data)\n    return True, \"Usuario registrado con éxito.\"\n\ndef login(username, password):\n    data = load_users()\n    hashed_password = hashlib.sha256(password.encode()).hexdigest()\n    for user in data[\"usuarios\"]:\n        if user[\"username\"] == username and user[\"password\"] == hashed_password:\n            return True, user[\"id\"]\n    return False, \"Nombre de usuario o contraseña incorrectos.\"\n\ndef follow_user(current_user_id, target_user_id):\n    data = load_users()\n    current_user = next((u for u in data[\"usuarios\"] if u[\"id\"] == current_user_id), None)\n    target_user = next((u for u in data[\"usuarios\"] if u[\"id\"] == target_user_id), None)\n\n    if not current_user or not target_user:\n        return False, \"Usuario no encontrado.\"\n    \n    if target_user_id in current_user[\"following\"]:\n        current_user[\"following\"].remove(target_user_id)\n        target_user[\"followers\"].remove(current_user_id)\n        message = f\"Dejaste de seguir a {target_user['username']}.\"\n    else:\n        current_user[\"following\"].append(target_user_id)\n        target_user[\"followers\"].append(current_user_id)\n        message = f\"Ahora sigues a {target_user['username']}.\"\n    \n    save_users(data)\n    return True, message\n\ndef search_users(username):\n    data = load_users()\n    return [u for u in data[\"usuarios\"] if username.lower() in u[\"username\"].lower()]\n\n# === Gestión de Publicaciones ===\n\ndef load_posts():\n    if not os.path.exists(POSTS_DB):\n        with open(POSTS_DB, \"w\") as db:\n            json.dump({\"posts\": []}, db)\n    with open(POSTS_DB, \"r\") as db:\n        return json.load(db)\n\ndef save_posts(data):\n    with open(POSTS_DB, \"w\") as db:\n        json.dump(data, db, indent=4)\n\ndef create_post(user_id, text):\n    if len(text) > 200:\n        return False, \"El texto supera los 200 caracteres.\"\n    data = load_posts()\n    new_post = {\n        \"id\": len(data[\"posts\"]) + 1,\n        \"user_id\": user_id,\n        \"text\": text,\n        \"likes\": [],\n        \"comments\": [],\n        \"created_at\": datetime.now().isoformat()\n    }\n    data[\"posts\"].append(new_post)\n    save_posts(data)\n    return True, \"Publicación creada con éxito.\"\n\ndef like_post(user_id, post_id):\n    data = load_posts()\n    for post in data[\"posts\"]:\n        if post[\"id\"] == post_id:\n            if user_id in post[\"likes\"]:\n                post[\"likes\"].remove(user_id)\n                message = \"Like eliminado.\"\n            else:\n                post[\"likes\"].append(user_id)\n                message = \"Like añadido.\"\n            save_posts(data)\n            return True, message\n    return False, \"Publicación no encontrada.\"\n\ndef retweet_post(user_id, post_id):\n    data = load_posts()\n    post = next((p for p in data[\"posts\"] if p[\"id\"] == post_id), None)\n\n    if not post:\n        return False, \"Publicación no encontrada.\"\n    \n    retweeted_post = {\n        \"id\": len(data[\"posts\"]) + 1,\n        \"user_id\": user_id,\n        \"text\": f\"RT: {post['text']}\",\n        \"likes\": [],\n        \"comments\": [],\n        \"created_at\": datetime.now().isoformat()\n    }\n    data[\"posts\"].append(retweeted_post)\n    save_posts(data)\n    return True, \"Retweet realizado con éxito.\"\n\ndef user_feed(user_id):\n    data = load_posts()\n    posts = [p for p in data[\"posts\"] if p[\"user_id\"] == user_id]\n    return sorted(posts, key=lambda x: x[\"created_at\"], reverse=True)[:10]\n\ndef following_feed(user_id):\n    user_data = load_users()\n    current_user = next((u for u in user_data[\"usuarios\"] if u[\"id\"] == user_id), None)\n    if not current_user:\n        return []\n\n    data = load_posts()\n    posts = [p for p in data[\"posts\"] if p[\"user_id\"] in current_user[\"following\"]]\n    return sorted(posts, key=lambda x: x[\"created_at\"], reverse=True)[:10]\n\ndef general_feed():\n    data = load_posts()\n    return sorted(data[\"posts\"], key=lambda x: x[\"created_at\"], reverse=True)\n\n# === Interfaz Gráfica ===\n\nclass App:\n    def __init__(self, root):\n        self.root = root\n        self.user_id = None  # ID del usuario logueado\n        self.setup_login()\n\n    def setup_login(self):\n        self.clear_window()\n\n        tk.Label(self.root, text=\"Usuario:\").pack()\n        self.username_entry = tk.Entry(self.root)\n        self.username_entry.pack()\n\n        tk.Label(self.root, text=\"Contraseña:\").pack()\n        self.password_entry = tk.Entry(self.root, show=\"*\")\n        self.password_entry.pack()\n\n        tk.Button(self.root, text=\"Iniciar Sesión\", command=self.login).pack()\n        tk.Button(self.root, text=\"Registrar\", command=self.register).pack()\n\n    def setup_feed(self):\n        self.clear_window()\n\n        tk.Button(self.root, text=\"Crear Publicación\", command=self.create_post_window).pack()\n        tk.Button(self.root, text=\"Feed Personal\", command=self.show_personal_feed).pack()  # Cambio aquí\n        tk.Button(self.root, text=\"Feed General\", command=self.show_general_feed).pack()\n        tk.Button(self.root, text=\"Perfil\", command=self.show_personal_feed).pack()\n        tk.Button(self.root, text=\"Buscar Amigos\", command=self.search_users_window).pack()\n\n    def search_users_window(self):\n        self.clear_window()\n\n        tk.Label(self.root, text=\"Buscar usuarios por nombre:\").pack()\n        self.search_entry = tk.Entry(self.root)\n        self.search_entry.pack()\n\n        tk.Button(self.root, text=\"Buscar\", command=self.search_users).pack()\n        tk.Button(self.root, text=\"Volver\", command=self.setup_feed).pack()\n\n    def search_users(self):\n        username = self.search_entry.get()\n        users = search_users(username)\n        self.clear_window()\n        if users:\n            for user in users:\n                tk.Label(self.root, text=f\"Usuario: {user['username']}\").pack()\n                follow_button = tk.Button(self.root, text=\"Seguir\", command=lambda u=user: self.follow_user(u))\n                follow_button.pack()\n        else:\n            tk.Label(self.root, text=\"No se encontraron usuarios.\").pack()\n\n        tk.Button(self.root, text=\"Volver\", command=self.setup_feed).pack()\n\n    def follow_user(self, user):\n        success, message = follow_user(self.user_id, user[\"id\"])\n        messagebox.showinfo(\"Seguir Usuario\", message)\n\n    def show_personal_feed(self):  # Definir la función que muestra el feed personal\n        self.clear_window()\n\n        posts = user_feed(self.user_id)\n        for post in posts:\n            user = next((u for u in load_users()[\"usuarios\"] if u[\"id\"] == post[\"user_id\"]), None)\n            if user:\n                post_text = f\"{user['username']}: {post['text']} (Likes: {len(post['likes'])})\"\n                tk.Label(self.root, text=post_text).pack()\n\n                def like_action(post_id=post[\"id\"]):\n                    success, message = like_post(self.user_id, post_id)\n                    messagebox.showinfo(\"Like\", message)\n\n                tk.Button(self.root, text=\"Me Gusta\", command=like_action).pack()\n\n        tk.Button(self.root, text=\"Volver\", command=self.setup_feed).pack()\n\n    def show_general_feed(self):\n        self.clear_window()\n\n        posts = general_feed()\n        for post in posts:\n            user = next((u for u in load_users()[\"usuarios\"] if u[\"id\"] == post[\"user_id\"]), None)\n            if user:\n                post_text = f\"{user['username']}: {post['text']} (Likes: {len(post['likes'])})\"\n                tk.Label(self.root, text=post_text).pack()\n\n                def like_action(post_id=post[\"id\"]):\n                    success, message = like_post(self.user_id, post_id)\n                    messagebox.showinfo(\"Like\", message)\n\n                tk.Button(self.root, text=\"Me Gusta\", command=like_action).pack()\n\n        tk.Button(self.root, text=\"Volver\", command=self.setup_feed).pack()\n\n    def create_post_window(self):\n        self.clear_window()\n\n        tk.Label(self.root, text=\"Texto de la Publicación:\").pack()\n        self.post_text = tk.Entry(self.root)\n        self.post_text.pack()\n\n        tk.Button(self.root, text=\"Crear\", command=self.create_post).pack()\n\n    def create_post(self):\n        text = self.post_text.get()\n        success, message = create_post(self.user_id, text)\n        messagebox.showinfo(\"Crear Publicación\", message)\n        self.setup_feed()\n\n    def register(self):\n        username = self.username_entry.get()\n        password = self.password_entry.get()\n        success, message = register(username, password)\n        messagebox.showinfo(\"Registro\", message)\n        if success:\n            self.setup_login()\n\n    def login(self):\n        username = self.username_entry.get()\n        password = self.password_entry.get()\n        success, result = login(username, password)\n        if success:\n            self.user_id = result\n            self.setup_feed()\n        else:\n            messagebox.showerror(\"Error\", result)\n\n    def clear_window(self):\n        for widget in self.root.winfo_children():\n            widget.destroy()\n\n# === Main ===\n\nif __name__ == \"__main__\":\n    root = tk.Tk()\n    root.title(\"Twitter Descentralizado\")\n    app = App(root)\n    root.mainloop()\n"
  },
  {
    "path": "Roadmap/46 - X VS BLUESKY/python/Nicojsuarez2.py",
    "content": "# #46 X VS BLUESKY\n> #### Dificultad: Media | Publicación: 18/11/24 | Corrección: 25/11/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * La alternativa descentralizada a X, Bluesky, comienza a atraer\n * a nuevos usuarios. ¿Cómo funciona una red de este estilo?\n * \n * Implementa un sistema que simule el comportamiento de estas\n * redes sociales.\n * \n * Debes crear las siguientes operaciones:\n * - Registrar un usuario por nombre e identificador único.\n * - Un usuario puede seguir/dejar de seguir a otro.\n * - Creación de post asociado a un usuario. Debe poseer\n *   texto (200 caracteres máximo), fecha de creación \n *   e identificador único.   \n * - Eliminación de un post.\n * - Posibilidad de hacer like (y eliminarlo) en un post.\n * - Visualización del feed de un usuario con sus 10 publicaciones\n *   más actuales ordenadas desde la más reciente.\n * - Visualización del feed de un usuario con las 10 publicaciones\n *   más actuales de los usuarios que sigue ordenadas \n *   desde la más reciente.\n *   \n * Cuando se visualiza un post, debe mostrarse:\n * ID de usuario, nombre de usuario, texto del post, \n * fecha de creación y número total de likes.\n * \n * Controla errores en duplicados o acciones no permitidas.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/46 - X VS BLUESKY/python/OpaHostil.py",
    "content": "from random import randint\nfrom datetime import datetime\nimport os, platform\n\n#Variables globales para simluar la base de datos\n\nposts_repo = {}\nusers_repo = {}\n\n# Clase Post\nclass Post:\n\n    # Constructor\n    def __init__(self):\n        self.__text = None\n        self.__creation_date = datetime.now().strftime(\"%d/%m/%Y %H:%M:%S\")\n        self.__likes = 0\n        self.__id = self._generate_id()\n\n    # Metodo para generar identificadores aleatorios y unicos\n    def _generate_id(self):\n        try:\n            while True:\n                unique_id = randint(1, 20000)\n                if unique_id not in posts_repo:\n                    posts_repo[unique_id] =  self\n                    return unique_id\n        except:\n            input(\"Numero maximo de post publicados.\\nPulsa una tecla para volver al menu de inicio.\")\n    \n    # Metodos getters y setters del texto\n    def _get_text(self):\n        return self.__text\n    \n    def _set_text(self, text):\n        self.__text = text\n    \n    def _get_likes(self):\n        return self.__likes\n    \n    def _set_likes(self):\n        self.__likes += 1\n    \n    def _get_id(self):\n        return self.__id\n\n    def _get_creation_date(self):\n        return self.__creation_date\n    \n    # Metodo para imprimir los datos de un post que nos solicitan\n    def _print_post(self):\n        return f\"Text: {self._get_text()}\\nCreacion: {self._get_creation_date()}\\nLikes: {self._get_likes()}\"\n\n# Clase User\nclass User:\n\n    #Constructor\n    def __init__(self, name):\n        self.__name = name\n        self.__id = self._generate_id()\n        self.__follows = list()\n        self.__posts = list()\n    \n    # Metodo para generar identificadores aleatorios y unicos\n    def _generate_id(self):\n        try:\n            while True:\n                unique_id = randint(1,2000)\n                if unique_id not in users_repo:\n                    users_repo[unique_id] = self\n                    return unique_id\n        except:\n            clean_console()\n            print(\"Numero maximo de usuarios permitidos\")\n            input(\"Pulsa una tecla para volver al menu inicial\")\n\n    # Metodos getters       \n    def _get_id(self):\n        return self.__id\n            \n    def _get_name(self):\n        return self.__name\n    \n    def _get_posts(self):\n        return self.__posts\n\n    def _get_follows(self):\n        return self.__follows\n\n    # Funcion para añadir un post\n    def _add_post(self, post):\n        self.__posts.append(post)\n    \n    def _add_follows(self, user):\n        self.__follows.append(user)\n\n    # Metodo para imprimir datos del usuario\n    def _print_user(self):\n        return f\"ID usuario: {self._get_id()}\\nName: {self._get_name()}\\nFollows: {self._get_follows()}\\nPosts: {self._get_posts()}\"\n\n# Funcion menu inicial\ndef welcome_menu():\n\n    clean_console()\n    print(\"Bienvenido a MoureXSky\\n\\n1. Iniciar sesion\\n2. Crear usuario\\n3. Cerrar sesion\\n\")\n    opcion = input(\"Elige una opcion: \")\n    if opcion == \"1\":\n        login_user()\n    elif opcion == \"2\":\n        create_user()\n    elif opcion == \"3\":\n        clean_console()\n        print(\"Hasta pronto! Recuerda lavarte las manos despues de mear\")\n        quit()\n    elif opcion == \"4\":\n        print(users_repo)\n        input()\n    else:\n        print(\"Opcion incorrecta.\")\n        input(\"Pulsa cualquier tecla para volver al menu.. \")\n        \n# Funcion para crear usuario\ndef create_user():\n    clean_console()\n    name = input(\"Introduce nombre: \")\n    if search_user(name):\n        input(\"Usuario en uso. Pulse una tecla para volver al menu.. \")\n    else:\n        user = User(name)\n        input(f\"Usuario {user._get_name()} creado satisfactoriamente con el ID {user._get_id()}\")\n \n# Funcion para buscar usuario en el diccionario\ndef search_user(name):\n    for user in users_repo.values():\n        if user._get_name() == name:\n            return user\n    return False    \n    \n# Funcion para limpiar cl\ndef clean_console():\n    if platform.system() == \"Windows\":\n        os.system(\"cls\")\n    else:\n        os.system(\"clean\")\n\n# Funcion de login\ndef login_user():\n    clean_console()\n    name = input(\"Introduce usuario: \")\n    user = search_user(name)\n    if not user:\n        input(\"No se encuentra el usuario. Pulse una tecla para volver al menu\")\n    else:\n        user_menu(user)\n        \n# Funcion para el Menu de usuario\ndef user_menu(user : User):\n    \n    option = 0\n    while option != None:\n        clean_console()\n        print(f\"Usuario logado: {user._get_name()}\")\n        print(\"1. Crear un post\")\n        print(\"2. Eliminar un post\")\n        print(\"3. Ver post de un usuario\")\n        print(\"4. Ver post de usuarios que sigues\")\n        print(\"5. Cerrar sesion usuario\\n\")\n        option = input(\"Elige una opcion: \")\n        if option == \"1\":\n            new_post(user)\n        elif option == \"2\":\n            delete_post(user)\n        elif option == \"3\":\n            view_user_post(user)\n        elif option == \"4\":\n            view_follows_post(user)\n        elif option == \"5\":\n            clean_console()\n            input(\"Cerrando sesion de usuario, pulse una tecla para volver al inicio\")\n            welcome_menu()\n        else:\n            input(\"Opcion incorrecta. Pulse una tecla para nueva opcion\")\n            \n# Funcion de crear un post\ndef new_post(user : User):\n    text = input(\"Escribe el texto del post ( max 200 caracteres, no se tendran en cuenta los caracteries que superen ): \\n\"[:200])\n    post = Post()\n    post._set_text(text)\n    user._add_post(post)\n    clean_console()\n    post._print_post()\n    input(f\"Añadido post con ID {post._get_id()} al usuario {user._get_name()}\\n \")\n\n# Funcion para ver los post de un usuario\ndef view_user_post(user_logado : User):\n    clean_console()\n    name = input(\"Introduce el usuario del que quieres ver los post: \")\n    user = search_user(name)\n    if user:\n        for index, post in enumerate(reversed(user._get_posts())):\n            if index == 10:\n                break\n            print(f\"ID Usuaio: {user._get_id()}\\nNombre Usuario: {user._get_name()}\\nText: {post._get_text()}\\nFecha de creacion: {post._get_creation_date()}\\nLikes: {post._get_likes()}\")\n            choice = input(\"Quieres darle like al post?(s/n): \")\n            if choice.upper() == 'S':\n                post._set_likes()\n            clean_console()\n        choice = input(\"Te gustaria seguir a este usuario?(s/n): \")\n        if choice.upper() == 'S':\n            user_logado._add_follows(user)\n    else:\n        input(\"Usuario no encontrado, pulsa una tecla para volver al menu\")\n    \n# Funcion Eliminar post\ndef delete_post(user):\n    clean_console()\n    print(\"Estos son los post que tienes:\")\n    for post in user._get_posts():\n        print(f\"ID: {post._get_id()} - Breve texto: {post._get_text()[:20]}...\")\n    while True:\n        try:\n            id = int(input(\"Introduce el ID del post que quieres eliminar, 0 para salir sin borrar ninguno: \"))\n            if id == 0:\n                break\n            elif not int(id) in posts_repo.keys():\n                print(\"El Id introducino no corresponde a ningun post.\")\n            else:\n                del posts_repo[id]\n                for post in user._get_posts():\n                    if id == post._get_id():\n                        user._get_posts().remove(post)         \n                input(\"Post eliminado, Pulsa cualquie tecla para volver al menu.\")\n                break\n        except ValueError:\n            input(\"Valor introducido no soportado. Pulsa una tecla para intentarlo de nuevo\")\n\n# Funcion para ver post de follows\ndef view_follows_post(user : User):\n\n    followers_list = user._get_follows()\n    for index, follower_user in enumerate(reversed(followers_list)):\n        if index == 10:\n            break\n        print(\"---------------------------------\")\n        print(f\"Post del usuario {follower_user._get_name()}:\")\n        print(\"---------------------------------\")\n        for follower_post in follower_user._get_posts():\n            print(follower_post._print_post())\n            print(\"---------------------------------\")\n    input(\"Pulsa cualquier tecla para volver al menu.\")\n\n    \n# Inicio de aplicacion\nwhile True:\n    welcome_menu()"
  },
  {
    "path": "Roadmap/46 - X VS BLUESKY/python/cdryampi.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * La alternativa descentralizada a X, Bluesky, comienza a atraer\n#  * a nuevos usuarios. ¿Cómo funciona una red de este estilo?\n#  * \n#  * Implementa un sistema que simule el comportamiento de estas\n#  * redes sociales.\n#  * \n#  * Debes crear las siguientes operaciones:\n#  * - Registrar un usuario por nombre e identificador único.\n#  * - Un usuario puede seguir/dejar de seguir a otro.\n#  * - Creación de post asociado a un usuario. Debe poseer\n#  *   texto (200 caracteres máximo), fecha de creación \n#  *   e identificador único.   \n#  * - Eliminación de un post.\n#  * - Posibilidad de hacer like (y eliminarlo) en un post.\n#  * - Visualización del feed de un usuario con sus 10 publicaciones\n#  *   más actuales ordenadas desde la más reciente.\n#  * - Visualización del feed de un usuario con las 10 publicaciones\n#  *   más actuales de los usuarios que sigue ordenadas \n#  *   desde la más reciente.\n#  *   \n#  * Cuando se visualiza un post, debe mostrarse:\n#  * ID de usuario, nombre de usuario, texto del post, \n#  * fecha de creación y número total de likes.\n#  * \n#  * Controla errores en duplicados o acciones no permitidas.\n#  */\nimport uuid\nfrom datetime import datetime\nimport os\n\nclass User():\n\n    def __init__(self, name: str) ->None:\n        self.id = uuid.uuid4()\n        self.name = name\n        self.tweets = []\n        self.followers = []\n        self.likes = []\n        self.dislikes = []\n        self.following = []\n\n    def follow_unfollow(self, user) -> None:\n        \"\"\"Función para seguir o dejar de seguir a un usuario.\"\"\"\n        if user.id == self.id:\n            raise ValueError(\"No podemos seguirnos a nosotros mismos.\")\n        \n        if user not in self.following:\n            self.following.append(user)\n            user.followers.append(self)\n            print(f\"Acabas de seguir al usuario '{user.name}'.\")\n        else:\n            self.following.remove(user)\n            user.followers.remove(self)\n            print(f\"Haz dejado de seguir al usuario '{user.name}'.\")\n\n\n    def add_tweet(self, tweet)-> None:\n\n        local_tweet = next((t for t in self.tweets if t.id ==tweet.id), None)\n        \n        if local_tweet == None:\n            self.tweets.append(tweet)\n            print(f'Tweet anañadido por el usuario {self}')\n        else:\n            print(f'Ya has publicado el tweet {tweet.id}')\n\n    def delete_tweet(self, tweet)-> None:\n\n       local_tweet = next((u for u in self.tweets if u.id ==tweet.id), None)\n       if local_tweet:\n           self.tweets.remove(tweet)\n\n    def like_dislike(self, tweet)-> None:\n        if tweet not in self.likes:\n            if tweet in self.dislikes:\n                self.dislikes.remove(tweet)\n            self.likes.append(tweet)\n            print(f'Le acabas de dar like a {tweet.id}')\n        else:\n            if tweet in self.likes:\n                if tweet in self.dislikes:\n                    self.dislikes.append(tweet)\n                self.likes.remove(tweet)\n                print(f'Le acabas de dar dislike a {tweet.id}')\n    \n\n    def print_feed(self)->None:\n        for tweet in self.ordered_tweets_list():\n            print(tweet)\n    \n    def ordered_tweets_list(self)->list:\n        return sorted(self.tweets, key=lambda d: d.data)\n\n    def get_following(self)->list:\n        return [f'{user.name}' for user in self.following]\n    \n    def user_feed(self)-> None:\n\n        print(f\"{self}:\\n\")\n        print(f\"Número de seguidores: {len(self.followers)}\")\n        print(f\"Número de seguidos: {len(self.following)}\")\n\n        if len(self.tweets) > 0:\n            print(f\"Últimos post:\")\n            for tweet in self.ordered_tweets_list()[:10]:\n                print()\n                print(tweet)\n                print()\n\n        print(f\"likes: {len(self.likes)}\")\n        print(f\"Dislikes: {len(self.dislikes)}\")\n\n\n    def __str__(self)-> str:\n        return f'{self.name}@{self.id}'\n    \nclass Tweet():\n\n    def __init__(self, user:User, msg:str, hora=datetime.now())-> None:\n        self.id = uuid.uuid4()\n        self.user= user\n        if len(msg) >=200:\n            raise(\"No puedes tener un Tweet tan largo\")\n        self.msg = msg\n        self.data = hora\n\n    def __str__(self):\n        return f'{self.user}:\\n{self.msg}\\n{self.data.strftime(\"%d/%m/%Y %H:%M:%S\")}'\n\nclass Twitter():\n    def __init__(self):\n        self.users = []\n    \n    def order_tweets(self)-> list:\n        local_tweets= []\n        if len(self.users) > 0:\n            for user in self.users:\n                list_tweets = user.ordered_tweets_list()\n                if list_tweets:\n                    local_tweets.extend(list_tweets)\n\n        return sorted(local_tweets, key=lambda d: d.data, reverse=True)\n\n    def add_user(self, user:User)-> None:\n        local_user = next((u for u in self.users if u.id == user.id), None)\n        if local_user == None:\n            self.users.append(user)\n        print(f'Usuario {user} Añadido a Twitter')\n\n    def add_tweet(self, user:User, msg:Tweet)-> None:\n        local_user = next((u for u in self.users if u.id == user.id),None)\n        if local_user == None:\n            self.add_user(user)\n            local_user = next((u for u in self.users if u.id == user.id),None)\n        local_user.add_tweet(msg)\n\n    def user_exist(self, user_name:str)-> bool:\n        local_user = next((u for u in self.users if u.name == user_name), None)\n        return True if local_user is not None else False\n\n    def print_last_tweets(self)->None:\n        tweets = self.order_tweets()[:10]\n\n        for tweet in tweets:\n            print(tweet)\n\n    def get_users(self)->list:\n        return self.users\n\n    def print_user_info(self, user_name:str)-> None:\n        local_user = next((u for u in self.users if u.name == user_name), None)\n        if local_user:\n            local_user.user_feed()\n        else:\n            print(f\"El usuario '{user_name}' no existe\")\n\n    def safe_execute_clear_from_cmd(self) -> None:\n        \"\"\"Limpia la consola dependiendo del sistema operativo\"\"\"\n        try:\n            if os.name == 'nt':\n                os.system('cls')\n            else:\n                os.system('clear')\n        except Exception as e:\n            print(f\"Error al limpiar la consola: {e}\")\n\ndef main():\n    twitter = Twitter()\n\n    for user in [User(f\"User{i}\") for i in range(10)]:\n        twitter.add_user(user)\n\n    for user in twitter.get_users():\n\n        for i in range(10):\n            tweet_date = datetime(2024, 11, 20, 21, (50 + i) % 24, (30 + i * 3) % 60)\n            tweet = Tweet(user, f\"Tweet {i + 1} from {user.name}\", tweet_date)\n            twitter.add_tweet(user, tweet)\n\n    for i, user in enumerate(twitter.get_users()):\n        if i + 1 < len(twitter.get_users()):\n            user.follow_unfollow(twitter.get_users()[i + 1])\n\n    for i, user in enumerate(twitter.users):\n        if i + 1 < len(twitter.get_users()):\n            next_user = twitter.get_users()[i + 1]\n            if twitter.user_exist(next_user.name):\n                for tweet in next_user.tweets[:5]:\n                    user.like_dislike(tweet)\n\n    twitter.safe_execute_clear_from_cmd()\n\n    while True:\n            print(\"\\n--- Twitter Management ---\")\n            print(\"1. Crear usuario\")\n            print(\"2. Publicar un tweet\")\n            print(\"3. Seguir o dejar de seguir a un usuario\")\n            print(\"4. Dar like a un tweet o dislike\")\n            print(\"5. Mostrar últimos tweets\")\n            print(\"6. Mostrar todo el feed de un usuario\")\n            print(\"7. Mostrar nombres de los usuarios\")\n            print(\"8. Salir\")\n            choice = input(\"Elige una opción: \")\n            match choice:\n                case \"1\":\n                    # Crear usuario\n                    name = input(\"Introduce el nombre del usuario: \")\n                    if twitter.user_exist(name):\n                        print(f\"El usuario {name} ya existe en Twitter\")\n                    else:\n                        user = User(name)\n                        twitter.add_user(user)\n\n                case \"2\":\n                    # Publicar un tweet\n                    if not twitter.get_users():\n                        print(\"Primero debes crear usuarios.\")\n                        continue\n                    user_name = input(\"¿Quién publicará el tweet? Ingresa el nombre: \")\n                    user = next((u for u in twitter.get_users() if u.name == user_name), None)\n                    if user:\n                        msg = input(\"Escribe tu tweet (máx 200 caracteres): \")\n                        tweet = Tweet(user, msg)\n                        twitter.add_tweet(user, tweet)\n                    else:\n                        print(\"Usuario no encontrado.\")\n\n                case \"3\":\n                    # Seguir a un usuario\n                    if len(twitter.get_users()) < 2:\n                        print(\"Debes tener al menos dos usuarios para seguirse entre sí.\")\n                        continue\n                    follower_name = input(\"¿Quién seguirá a otro usuario? Ingresa el nombre: \")\n                    followee_name = input(\"¿A quién quieres seguir? Ingresa el nombre: \")\n                    follower = next((u for u in twitter.get_users() if u.name == follower_name), None)\n                    followee = next((u for u in twitter.get_users() if u.name == followee_name), None)\n                    if follower and followee:\n                        try:\n                            follower.follow_unfollow(followee)\n                        except ValueError as e:\n                            print(e)\n                    else:\n                        print(\"Uno o ambos usuarios no existen.\")\n\n                case \"4\":\n                    # Dar like a un tweet\n                    if not twitter.get_users():\n                        print(\"Primero debes crear usuarios.\")\n                        continue\n                    liker_name = input(\"¿Quién dará like? Ingresa el nombre: \")\n                    user = next((u for u in twitter.get_users() if u.name == liker_name), None)\n                    if user:\n                        tweet_owner_name = input(\"¿De quién es el tweet? Ingresa el nombre: \")\n                        tweet_owner = next((u for u in twitter.get_users() if u.name == tweet_owner_name), None)\n                        if tweet_owner and tweet_owner.tweets:\n                            print(\"Tweets disponibles:\")\n                            for i, tweet in enumerate(tweet_owner.tweets, 1):\n                                print(f\"{i}. {tweet.msg}\")\n                            tweet_index = int(input(\"Selecciona el número del tweet: \")) - 1\n                            if 0 <= tweet_index < len(tweet_owner.tweets):\n                                tweet = tweet_owner.tweets[tweet_index]\n                                user.like_dislike(tweet)\n                            else:\n                                print(\"Número de tweet inválido.\")\n                        else:\n                            print(\"Usuario no encontrado o no tiene tweets.\")\n                    else:\n                        print(\"Usuario no encontrado.\")\n\n                case \"5\":\n                    # Mostrar últimos tweets\n                    print(\"\\nÚltimos tweets publicados:\")\n                    twitter.print_last_tweets()\n\n                case \"6\":\n                    # Mostrar feed\n                    name = input(\"Introduce el nombre del usuario: \")\n                    if twitter.user_exist(name):\n                        twitter.print_user_info(name)\n                    else:\n                        print(f\"El usuario {name} no existe.\")\n\n                case \"7\":\n                    # Mostrar nombres de los usuarios\n                    for user in twitter.get_users():\n                        print(user.name)\n                case \"8\":\n                    # Salir\n                    print(\"Saliendo del programa. ¡Hasta luego!\")\n                    break\n                case _:\n                    print(\"Opción no válida, por favor elige una opción del menú.\")\n\n\nif __name__ == '__main__':\n    main()"
  },
  {
    "path": "Roadmap/46 - X VS BLUESKY/python/davidrguez98.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * La alternativa descentralizada a X, Bluesky, comienza a atraer\n * a nuevos usuarios. ¿Cómo funciona una red de este estilo?\n * \n * Implementa un sistema que simule el comportamiento de estas\n * redes sociales.\n * \n * Debes crear las siguientes operaciones:\n * - Registrar un usuario por nombre e identificador único.\n * - Un usuario puede seguir/dejar de seguir a otro.\n * - Creación de post asociado a un usuario. Debe poseer\n *   texto (200 caracteres máximo), fecha de creación \n *   e identificador único.   \n * - Eliminación de un post.\n * - Posibilidad de hacer like (y eliminarlo) en un post.\n * - Visualización del feed de un usuario con sus 10 publicaciones\n *   más actuales ordenadas desde la más reciente.\n * - Visualización del feed de un usuario con las 10 publicaciones\n *   más actuales de los usuarios que sigue ordenadas \n *   desde la más reciente.\n *   \n * Cuando se visualiza un post, debe mostrarse:\n * ID de usuario, nombre de usuario, texto del post, \n * fecha de creación y número total de likes.\n * \n * Controla errores en duplicados o acciones no permitidas.\n */ \"\"\"\n\nfrom datetime import datetime\n\nclass SocialNetwork:\n\n    def __init__(self):\n        self.post_id = 0\n        self.users = {}\n        self.post = {}\n\n    def register_user(self, user_id: str, name: str):\n\n        if user_id in self.users:\n            print(f\"El usuario con el ID {user_id} ya existe.\")\n            return\n        \n        self.users[user_id] = {\n            \"name\": name,\n            \"following\": set(),\n            \"followers\": set(),\n            \"post\": []\n            }\n        print(f\"Usuario con ID {user_id} y nombre {name} registrado correctamente.\")\n\n    def follow_user(self, user_id: str, follow_id: str):\n\n        if user_id not in self.users or follow_id not in self.users:\n            print(\"Alguno de los usuarios no existe. No se puede realizar el follow.\")\n            return\n        \n        self.users[user_id][\"following\"].add(follow_id)\n        self.users[follow_id][\"followers\"].add(user_id)\n        print(f\"El usuario {self.users[user_id][\"name\"]} ahora sigue a {self.users[follow_id][\"name\"]}.\")\n\n    def unfollow_user(self, user_id: str, unfollow_id: str):\n        \n        if user_id not in self.users or unfollow_id not in self.users:\n            print(\"Alguno de los usuarios no existe. No se puede realizar el follow.\")\n            return\n        \n        self.users[user_id][\"following\"].discard(unfollow_id)\n        self.users[unfollow_id][\"followers\"].discard(user_id)\n        print(f\"El usuario {self.users[user_id][\"name\"]} ya no sigue a {self.users[unfollow_id][\"name\"]}.\")\n\n    def create_post(self, user_id: str, text: str):\n\n        if user_id not in self.users:\n            print(f\"El usuario '{user_id}' no existe.\")\n            return\n        \n        if len(text) > 200:\n            print(\"El post no puede tener más de 200 caracteres.\")\n            return\n        \n        self.post_id += 1\n        \n        self.post[self.post_id] = {\n            \"user_id\": user_id,\n            \"text\": text,\n            \"created_at\": datetime.now(),\n            \"likes\": set()\n        }\n\n        self.users[user_id][\"post\"].append(self.post_id)\n        print(\"Post creado correctamente.\")\n\n    def delete_post(self, post_id: int):\n\n        if post_id not in self.post:\n            print(f\"El post con IF {post_id} no existe.\")\n            return\n        \n        user_id = self.post[post_id][\"user_id\"]\n        self.users[user_id][\"post\"].remove(post_id)\n        del self.post[post_id]\n        print(\"Post eliminado correctamente.\")\n\n    def like_post(self, user_id: str, post_id: int):\n\n        if user_id not in self.users:\n            print(f\"El usuario '{user_id}' no existe.\")\n            return\n        \n        if post_id not in self.post:\n            print(f\"El post '{post_id}' no existe.\")\n            return\n        \n        self.post[post_id][\"likes\"].add(user_id)\n        print(f\"Nuevo like en post '{post_id}'.\")\n\n    def unlike_post(self, user_id: str, post_id: int):\n        \n        if user_id not in self.users:\n            print(f\"El usuario '{user_id}' no existe.\")\n            return\n        \n        if post_id not in self.post:\n            print(f\"El post '{post_id}' no existe.\")\n            return\n        \n        self.post[post_id][\"likes\"].discard(user_id)\n        print(f\"Like eliminado en post {post_id}\")\n\n    def view_user_feed(self, user_id: str):\n\n        if user_id not in self.users:\n            print(f\"El usuario '{user_id}' no existe.\")\n            return\n        \n        feed = sorted((self.post[post_id] for post_id in self.users[user_id][\"post\"]), key=lambda x: x[\"created_at\"], reverse=True)[:10]\n\n        for post in feed:\n            print(f\"\"\"\nID de usuario: {post[\"user_id\"]}\nUsuario: {self.users[post[\"user_id\"]][\"name\"]}\nTexto: {post[\"text\"]}\nFecha: {post[\"created_at\"]}\nLikes: {len(post[\"likes\"])}\n                  \"\"\")\n            \n    def view_following_feed(self, user_id: str):\n\n        if user_id not in self.users:\n            print(f\"El usuario '{user_id}' no existe.\")\n            return\n        \n        following_post_ids = []\n        \n        for following_id in self.users[user_id][\"following\"]:\n            following_post_ids.extend(self.users[following_id][\"post\"])\n\n        feed = sorted((self.post[post_id] for post_id in following_post_ids), key=lambda x: x[\"created_at\"], reverse=True)[:10]\n\n        for post in feed:\n            print(f\"\"\"\nID de usuario: {post[\"user_id\"]}\nUsuario: {self.users[post[\"user_id\"]][\"name\"]}\nTexto: {post[\"text\"]}\nFecha: {post[\"created_at\"]}\nLikes: {len(post[\"likes\"])}\n                  \"\"\")\n            \nsocial_network = SocialNetwork()\n\nsocial_network.register_user(\"davidrguez98\", \"David\")\nsocial_network.register_user(\"pepitogomez\", \"Pepe\")\n\nsocial_network.create_post(\"davidrguez98\", \"Hola mundo\")\nsocial_network.create_post(\"davidrguez98\", \"Hola mundo2\")\nsocial_network.create_post(\"davidrguez98\", \"Hola mundo3\")\n\nsocial_network.create_post(\"pepitogomez\", \"Hola mundo\")\nsocial_network.create_post(\"pepitogomez\", \"Hola mundo2\")\nsocial_network.create_post(\"pepitogomez\", \"Hola mundo3\")\n\nsocial_network.follow_user(\"pepitogomez\", \"davidrguez98\")\n\nsocial_network.like_post(\"pepitogomez\", 1)\n\nsocial_network.view_user_feed(\"davidrguez98\")\nsocial_network.view_following_feed(\"pepitogomez\")\n\nsocial_network.unlike_post(\"pepitogomez\", 1)\nsocial_network.view_following_feed(\"pepitogomez\")"
  },
  {
    "path": "Roadmap/46 - X VS BLUESKY/python/duendeintemporal.py",
    "content": "#46 { Retos para Programadores } X VS BLUESKY \n\n# Bibliography reference:\n# I use GPT as a reference and sometimes to correct or generate proper comments.\n\n\"\"\"\n * EJERCICIO:\n * La alternativa descentralizada a X, Bluesky, comienza a atraer\n * a nuevos usuarios. ¿Cómo funciona una red de este estilo?\n *\n * Implementa un sistema que simule el comportamiento de estas\n * redes sociales.\n *\n * Debes crear las siguientes operaciones:\n * - Registrar un usuario por nombre e identificador único.\n * - Un usuario puede seguir/dejar de seguir a otro.\n * - Creación de post asociado a un usuario. Debe poseer\n *   texto (200 caracteres máximo), fecha de creación \n *   e identificador único.  \n * - Eliminación de un post.\n * - Posibilidad de hacer like (y eliminarlo) en un post.\n * - Visualización del feed de un usuario con sus 10 publicaciones\n *   más actuales ordenadas desde la más reciente.\n * - Visualización del feed de un usuario con las 10 publicaciones\n *   más actuales de los usuarios que sigue ordenadas \n *   desde la más reciente.\n *\n * Cuando se visualiza un post, debe mostrarse:\n * ID de usuario, nombre de usuario, texto del post,\n * fecha de creación y número total de likes.\n *\n * Controla errores en duplicados o acciones no permitidas.\n\n\"\"\"\n\nlog = print\n\nimport uuid\nfrom datetime import datetime\nimport time\n\nclass Post:\n    def __init__(self, user, text):\n        if len(text) > 200:\n            raise ValueError(\"Post text cannot exceed 200 characters.\")\n        self.id = str(uuid.uuid4())\n        self.user = user\n        self.text = text\n        self.created_at = datetime.now()\n        self.likes = set()\n\n    def like(self, user):\n        self.likes.add(user)\n\n    def unlike(self, user):\n        self.likes.discard(user)\n\n    def get_total_likes(self):\n        return len(self.likes)\n\n    def __str__(self):\n        return f\"Post by {self.user.name}: {self.text} (Likes: {self.get_total_likes()})\"\n\nclass User:\n    def __init__(self, name, user_id):\n        self.name = name\n        self.id = user_id\n        self.following = set()\n        self.posts = []\n\n    def follow(self, user):\n        self.following.add(user)\n\n    def unfollow(self, user):\n        self.following.discard(user)\n\n    def create_post(self, text):\n        post = Post(self, text)\n        self.posts.append(post)\n        return post\n\n    def delete_post(self, post):\n        if post not in self.posts:\n            raise ValueError(\"Post not found.\")\n        self.posts.remove(post)\n\n    def get_feed(self):\n        feed = sorted(self.posts, key=lambda p: p.created_at, reverse=True)[:10]\n        return feed\n\n    def get_following_feed(self):\n        feed = []\n        for user in self.following:\n            feed.extend(sorted(user.posts, key=lambda p: p.created_at, reverse=True)[:10])\n        return sorted(feed, key=lambda p: p.created_at, reverse=True)[:10]\n\n# Simulating the behavior of the JavaScript code\ndef main():\n    log(\"Retosparaprogramadores #46.\")\n\n    user1 = User(\"Niko Zen\", 1)\n    user2 = User(\"Bob Marley\", 2)\n    user3 = User(\"Psicotrogato\", 3)\n\n    user1.follow(user2)\n    user1.follow(user3)\n\n    post1 = user1.create_post(\"I'm almost finishing this roadmap for developers.\")\n    post1_1 = user1.create_post(\"I'm thinking in the possibility of start some of the developer course in mouredev, to get more possibilities to find a remote job.\")\n    post1_2 = user1.create_post(\"I start to feel comfortable with Javascript and its ecosystem, right now I'm studying Next.js.\")\n    post2 = user2.create_post(\"But Jamming!\")\n    post2_1 = user2.create_post(\"I'm not going to wait in vain for your love!\")\n    post2_2 = user2.create_post(\"I shot the sheriff, but I didn't shoot the deputy!\")\n    post3 = user3.create_post(\"In a society that has abolished every kind of adventure, the only adventure that remains is abolishing the society.\")\n    post3_1 = user3.create_post(\"My life is perfect because I accept it as it is.\")\n\n    post1.like(user2)\n    post1.like(user3)\n\n    # log the feeds with meaningful output\n    log([str(post) for post in user1.get_feed()])\n    log([str(post) for post in user1.get_following_feed()])\n    log([str(post) for post in user2.get_feed()])\n    log([str(post) for post in user2.get_following_feed()])\n    log([str(post) for post in user3.get_feed()])\n    log([str(post) for post in user3.get_following_feed()])\n\nif __name__ == \"__main__\":\n    main()\n\n# Output:\n\"\"\"   \nRetosparaprogramadores #46.\n[\"Post by Niko Zen: I'm almost finishing this roadmap for developers. (Likes: 2)\", \"Post by Niko Zen: I'm thinking in the possibility of start some of the developer course in mouredev, to get more possibilities to find a remote job. (Likes: 0)\", \"Post by Niko Zen: I start to feel comfortable with Javascript and its ecosystem, right now I'm studying Next.js. (Likes: 0)\"]\n[\"Post by Bob Marley: I'm not going to wait in vain for your love! (Likes: 0)\", \"Post by Bob Marley: I shot the sheriff, but I didn't shoot the deputy! (Likes: 0)\", 'Post by Psicotrogato: In a society that has abolished every kind of adventure, the only adventure that remains is abolishing the society. (Likes: 0)', 'Post by Psicotrogato: My life is perfect because I accept it as it is. (Likes: 0)', 'Post by Bob Marley: But Jamming! (Likes: 0)']\n[\"Post by Bob Marley: I'm not going to wait in vain for your love! (Likes: 0)\", \"Post by Bob Marley: I shot the sheriff, but I didn't shoot the deputy! (Likes: 0)\", 'Post by Bob Marley: But Jamming! (Likes: 0)']\n[]\n['Post by Psicotrogato: In a society that has abolished every kind of adventure, the only adventure that remains is abolishing the society. (Likes: 0)', 'Post by Psicotrogato: My life is perfect because I accept it as it is. (Likes: 0)']\n\n\"\"\""
  },
  {
    "path": "Roadmap/46 - X VS BLUESKY/python/hectorio23.py",
    "content": "# Autor: Héctor Adán\n# GitHub: https://github.com/hectorio23\n\nfrom datetime import datetime\nfrom collections import defaultdict\n\nclass SocialNetwork:\n    def __init__(self):\n        self.users = {}\n        self.posts = {}\n        self.following = defaultdict(set)\n\n    def register_user(self, user_id, name):\n        if user_id in self.users:\n            raise ValueError(\"User ID already exists.\")\n        self.users[user_id] = name\n\n    def toggle_follow(self, follower_id, followed_id):\n        if follower_id not in self.users or followed_id not in self.users:\n            raise ValueError(\"User ID not found.\")\n        if followed_id in self.following[follower_id]:\n            self.following[follower_id].remove(followed_id)\n        else:\n            self.following[follower_id].add(followed_id)\n\n    def create_post(self, user_id, post_id, text):\n        if user_id not in self.users:\n            raise ValueError(\"User ID not found.\")\n        if post_id in self.posts:\n            raise ValueError(\"Post ID already exists.\")\n        if len(text) > 200:\n            raise ValueError(\"Text exceeds maximum length of 200 characters.\")\n        self.posts[post_id] = {\n            \"user_id\": user_id,\n            \"text\": text,\n            \"created_at\": datetime.now(),\n            \"likes\": 0\n        }\n\n    def delete_post(self, post_id):\n        if post_id not in self.posts:\n            raise ValueError(\"Post ID not found.\")\n        del self.posts[post_id]\n\n    def toggle_like(self, post_id):\n        if post_id not in self.posts:\n            raise ValueError(\"Post ID not found.\")\n        self.posts[post_id][\"likes\"] += 1 if self.posts[post_id][\"likes\"] == 0 else -1\n\n    def get_user_feed(self, user_id):\n        if user_id not in self.users:\n            raise ValueError(\"User ID not found.\")\n        user_posts = [post for post in self.posts.values() if post[\"user_id\"] == user_id]\n        user_posts.sort(key=lambda x: x[\"created_at\"], reverse=True)\n        self._display_feed(user_posts[:10])\n\n    def get_following_feed(self, user_id):\n        if user_id not in self.users:\n            raise ValueError(\"User ID not found.\")\n        feed = []\n        for followed_id in self.following[user_id]:\n            feed.extend([post for post in self.posts.values() if post[\"user_id\"] == followed_id])\n        feed.sort(key=lambda x: x[\"created_at\"], reverse=True)\n        self._display_feed(feed[:10])\n\n    def _display_feed(self, posts):\n        for post in posts:\n            user_name = self.users[post[\"user_id\"]]\n            print(f\"User ID: {post['user_id']}, Name: {user_name}, Text: {post['text']}, \"\n                  f\"Created At: {post['created_at']}, Likes: {post['likes']}\")\n\n\n# Example Usage\nif __name__ == \"__main__\":\n    sn = SocialNetwork()\n    sn.register_user(\"u1\", \"Alice\")\n    sn.register_user(\"u2\", \"Bob\")\n\n    sn.toggle_follow(\"u1\", \"u2\")\n\n    sn.create_post(\"u1\", \"p1\", \"Hello, this is Alice!\")\n    sn.create_post(\"u2\", \"p2\", \"Hi, this is Bob's post.\")\n    sn.toggle_like(\"p2\")\n\n    print(\"\\n[+] - User Feed for Alice:\")\n    sn.get_user_feed(\"u1\")\n\n    print(\"\\n[+] - Following Feed for Alice:\")\n    sn.get_following_feed(\"u1\")\n\n    sn.delete_post(\"p1\")\n    print(\"\\n[+] - After Deleting Alice's Post:\")\n    sn.get_user_feed(\"u1\")\n"
  },
  {
    "path": "Roadmap/46 - X VS BLUESKY/python/hozlucas28.py",
    "content": "# pylint: disable=missing-module-docstring,missing-class-docstring,missing-function-docstring,broad-exception-raised,raise-missing-from\n\nfrom abc import ABCMeta, abstractmethod\nfrom datetime import datetime\nfrom typing import Any\nfrom uuid import UUID, uuid4\n\n# ---------------------------------------------------------------------------- #\n#                                    CLASSES                                   #\n# ---------------------------------------------------------------------------- #\n\n# ----------------------------------- Post ----------------------------------- #\n\n\nclass AbcPost(metaclass=ABCMeta):\n    @property\n    @abstractmethod\n    def uid(self) -> UUID:\n        pass\n\n    @property\n    @abstractmethod\n    def content(self) -> str:\n        pass\n\n    @property\n    @abstractmethod\n    def date(self) -> datetime:\n        pass\n\n    @property\n    @abstractmethod\n    def author(self) -> str:\n        pass\n\n    @property\n    @abstractmethod\n    def likes(self) -> list[str]:\n        pass\n\n    @abstractmethod\n    def add_like(self, *, _u_name: str) -> None:\n        pass\n\n    @abstractmethod\n    def remove_like(self, *, _u_name: str) -> None:\n        pass\n\n\nclass Post(AbcPost):\n    __uid: UUID\n    __content: str\n    __date: datetime\n    __author: str\n    __likes: list[str]\n\n    def __init__(self, *, author: str, content: str) -> None:\n        if len(content) > 200:\n            raise Exception(\"Content of the post exceed the maximum length (200 chars)\")\n\n        self.__uid = uuid4()\n        self.__content = content\n        self.__date = datetime.now()\n        self.__author = author\n        self.__likes = []\n\n    @property\n    def uid(self) -> UUID:\n        return self.__uid\n\n    @property\n    def content(self) -> str:\n        return self.__content\n\n    @property\n    def date(self) -> datetime:\n        return self.__date\n\n    @property\n    def author(self) -> str:\n        return self.__author\n\n    @property\n    def likes(self) -> list[str]:\n        return self.__likes\n\n    def add_like(self, *, _u_name: str) -> None:\n        try:\n            self.__likes.index(_u_name)\n            raise Exception(f\"'{_u_name}' like already exists\")\n        except ValueError:\n            self.__likes.append(_u_name)\n\n    def remove_like(self, *, _u_name: str) -> None:\n        try:\n            like_index: int = self.__likes.index(_u_name)\n            self.__likes.pop(like_index)\n        except ValueError:\n            raise Exception(f\"'{_u_name}' like doesn't  exist\")\n\n\n# ----------------------------------- User ----------------------------------- #\n\n\nclass AbcUser(metaclass=ABCMeta):\n    @property\n    @abstractmethod\n    def u_name(self) -> str:\n        pass\n\n    @property\n    @abstractmethod\n    def followers(self) -> list[str]:\n        pass\n\n    @property\n    @abstractmethod\n    def followings(self) -> list[str]:\n        pass\n\n    @property\n    @abstractmethod\n    def posts(self) -> list[UUID]:\n        pass\n\n    @abstractmethod\n    def add_follower(self, *, _u_name: str) -> None:\n        pass\n\n    @abstractmethod\n    def remove_follower(self, *, _u_name: str) -> None:\n        pass\n\n    @abstractmethod\n    def create_post(self, *, content: str) -> None:\n        pass\n\n    @abstractmethod\n    def delete_post(self, *, uid: UUID) -> None:\n        pass\n\n    @abstractmethod\n    def follow(self, *, _u_name: str) -> None:\n        pass\n\n    @abstractmethod\n    def like_post(self, *, uid: UUID) -> None:\n        pass\n\n    @abstractmethod\n    def unfollow(self, *, _u_name: str) -> None:\n        pass\n\n    @abstractmethod\n    def unlike_post(self, *, uid: UUID) -> None:\n        pass\n\n\nclass User(AbcUser):\n    __followers: list[str]\n    __followings: list[str]\n    __posts: list[UUID]\n    __u_name: str\n\n    def __init__(self, *, _u_name: str) -> None:\n        self.__followers = []\n        self.__followings = []\n        self.__posts = []\n        self.__u_name = _u_name\n\n    @property\n    def u_name(self) -> str:\n        return self.__u_name\n\n    @property\n    def followers(self) -> list[str]:\n        return self.__followers\n\n    @property\n    def followings(self) -> list[str]:\n        return self.__followings\n\n    @property\n    def posts(self) -> list[UUID]:\n        return self.__posts\n\n    def add_follower(self, *, _u_name: str) -> None:\n        self.__followers.append(_u_name)\n\n    def remove_follower(self, *, _u_name: str) -> None:\n        try:\n            follower_index: int = self.__followers.index(_u_name)\n            self.__followers.pop(follower_index)\n        except ValueError:\n            raise Exception(f\"'{self.__u_name}' isn't follow by '{_u_name}'\")\n\n    def create_post(self, *, content: str) -> None:\n        _post: AbcPost = Post(author=self.u_name, content=content)\n        _database: Database = Database()\n\n        _database.add_new_post(new_post=_post)\n        self.__posts.append(_post.uid)\n\n    def delete_post(self, *, uid: UUID) -> None:\n        _database: Database = Database()\n\n        try:\n            post_index: int = self.__posts.index(uid)\n            _database.delete_post(uid=uid)\n            self.__posts.pop(post_index)\n        except ValueError:\n            raise Exception(f\"'{self.u_name}' doesn't posted the post with '{uid}' id\")\n\n    def follow(self, *, _u_name: str) -> None:\n        _database: Database = Database()\n\n        try:\n            self.__followings.index(_u_name)\n            raise Exception(f\"'{self.u_name}' already follows '{_u_name}'\")\n        except ValueError:\n            user_followed: AbcUser | None = _database.get_user(_u_name=_u_name)\n            if user_followed is None:\n                raise Exception(f\"'{self.u_name}' doesn't exist\")\n\n            user_followed.add_follower(_u_name=self.u_name)\n            self.__followings.append(_u_name)\n\n    def like_post(self, *, uid: UUID) -> None:\n        _database: Database = Database()\n\n        _post: AbcPost | None = _database.get_post(uid=uid)\n        if _post is None:\n            raise Exception(f\"'{uid}' post doesn't exist\")\n\n        _post.add_like(_u_name=self.u_name)\n\n    def unfollow(self, *, _u_name: str) -> None:\n        _database: Database = Database()\n\n        try:\n            _following_index: int = self.__followings.index(_u_name)\n\n            user_unfollowed: AbcUser | None = _database.get_user(_u_name=_u_name)\n            if user_unfollowed is None:\n                raise Exception(f\"'{self.u_name}' doesn't exist\")\n\n            user_unfollowed.remove_follower(_u_name=self.u_name)\n            self.__followings.pop(_following_index)\n        except ValueError:\n            raise Exception(f\"'{self.u_name}' doesn't follow '{_u_name}'\")\n\n    def unlike_post(self, *, uid: UUID) -> None:\n        _database: Database = Database()\n\n        _post: AbcPost | None = _database.get_post(uid=uid)\n        if _post is None:\n            raise Exception(f\"'{uid}' post doesn't exist\")\n\n        _post.remove_like(_u_name=self.u_name)\n\n\n# --------------------------------- Database --------------------------------- #\n\n\nclass Singleton(type):\n    __instances: dict[Any, Any] = {}\n\n    def __call__(cls, *args: Any, **kwds: Any) -> Any:\n        if cls not in cls.__instances:\n            instance: Any = super().__call__(*args, **kwds)\n            cls.__instances[cls] = instance\n\n        return cls.__instances[cls]\n\n\n# class AbcDatabase(metaclass=ABCMeta):\n#     @property\n#     @abstractmethod\n#     def posts(self) -> list[AbcPost]:\n#         pass\n\n#     @property\n#     @abstractmethod\n#     def users(self) -> list[AbcUser]:\n#         pass\n\n#     @abstractmethod\n#     def get_user(self, *, u_name: str) -> AbcUser | None:\n#         pass\n\n#     @abstractmethod\n#     def get_post(self, *, uid: UUID) -> AbcPost | None:\n#         pass\n\n#     @abstractmethod\n#     def get_user_followings_posts(self, *, u_name: str) -> list[AbcPost]:\n#         pass\n\n#     @abstractmethod\n#     def get_user_posts(self, *, u_name: str) -> list[AbcPost]:\n#         pass\n\n#     @abstractmethod\n#     def delete_user(self, *, u_name: str) -> None:\n#         pass\n\n#     @abstractmethod\n#     def post_user(self, *, new_user: AbcUser) -> None:\n#         pass\n\n#     @abstractmethod\n#     def add_new_post(self, *, new_post: AbcPost) -> None:\n#         pass\n\n#     @abstractmethod\n#     def delete_post(self, *, uid: UUID) -> None:\n#         pass\n\n\nclass Database(metaclass=Singleton):\n    __posts: list[AbcPost]\n    __users: list[AbcUser]\n\n    def __init__(self) -> None:\n        self.__posts = []\n        self.__users = []\n\n    @property\n    def posts(self) -> list[AbcPost]:\n        return self.__posts\n\n    @property\n    def users(self) -> list[AbcUser]:\n        return self.__users\n\n    def get_user(self, *, _u_name: str) -> AbcUser | None:\n        for _user in self.__users:\n            if _user.u_name == _u_name:\n                return _user\n\n        return None\n\n    def get_post(self, *, uid: UUID) -> AbcPost | None:\n        for _post in self.__posts:\n            if str(_post.uid) == str(object=uid):\n                return _post\n\n        return None\n\n    def get_user_followings_posts(self, *, _u_name: str) -> list[AbcPost]:\n        followings_posts: list[AbcPost] = []\n\n        _user: AbcUser | None = self.get_user(_u_name=_u_name)\n        if _user is None:\n            raise Exception(f\"'{_u_name}' doesn't exist\")\n\n        for following in _user.followings:\n            following_posts: list[AbcPost] = self.get_user_posts(_u_name=following)\n            followings_posts.append(*following_posts)\n\n        return followings_posts\n\n    def get_user_posts(self, *, _u_name: str) -> list[AbcPost]:\n        user_posts: list[AbcPost] = []\n\n        _user: AbcUser | None = self.get_user(_u_name=_u_name)\n        if _user is None:\n            raise Exception(f\"'{_u_name}' doesn't exist\")\n\n        for uid in _user.posts:\n            _post: AbcPost | None = self.get_post(uid=uid)\n            if _post is not None:\n                user_posts.append(_post)\n\n        return user_posts\n\n    def delete_user(self, *, _u_name: str) -> None:\n        user_index: int = -1\n\n        for _i, _user in enumerate(iterable=self.__users):\n            if _user.u_name == _u_name:\n                user_index = _i\n                break\n\n        if user_index < 0:\n            raise Exception(f\"'{_u_name}' doesn't exist\")\n\n        self.__users.pop(user_index)\n\n    def post_user(self, *, new_user: AbcUser) -> None:\n        user_index: int = -1\n\n        for _i, _user in enumerate(iterable=self.__users):\n            if _user.u_name == new_user.u_name:\n                user_index = _i\n                break\n\n        if user_index >= 0:\n            raise Exception(f\"'{new_user.u_name}' already exists\")\n\n        self.__users.append(new_user)\n\n    def add_new_post(self, *, new_post: AbcPost) -> None:\n        self.__posts.append(new_post)\n\n    def delete_post(self, *, uid: UUID) -> None:\n        post_index: int = -1\n\n        for _i, _post in enumerate(iterable=self.__posts):\n            if str(_post.uid) == str(uid):\n                post_index = _i\n                break\n\n        if post_index < 0:\n            raise Exception(f\"'{uid}' doesn't exist\")\n\n        self.__posts.pop(post_index)\n\n\n# ---------------------------------------------------------------------------- #\n#                                     MAIN                                     #\n# ---------------------------------------------------------------------------- #\n\ndatabase: Database = Database()\n\nprint(str(uuid4()))\n\nprint(\n    \"> Available operations...\\n\\n\"\n    \"  1 - Sign up a new user.\\n\"\n    \"  2 - Sign in as user.\\n\"\n    \"  0 - Exit.\"\n)\n\ninput_01: str = input(\"\\n> Enter an operation: \").strip()\n\nwhile input_01 != \"0\":\n    match input_01:\n        case \"0\":\n            pass\n\n        case \"1\":\n            u_name: str = input(\"\\n> Username: \").strip()\n            user = User(_u_name=u_name)\n            database.post_user(new_user=user)\n\n        case \"2\":\n            u_name = input(\"\\n> Username: \").strip()\n            user: AbcUser | None = database.get_user(_u_name=u_name)\n            if user is not None:\n                print(\n                    \"\\n> Available operations...\\n\\n\"\n                    \"  1 - Create a new post.\\n\"\n                    \"  2 - Show personal feed.\\n\"\n                    \"  3 - Show following feed.\\n\"\n                    \"  4 - Delete post.\\n\"\n                    \"  5 - Follow user.\\n\"\n                    \"  6 - Unfollow user.\\n\"\n                    \"  7 - Like post.\\n\"\n                    \"  8 - Unlike post.\\n\"\n                    \"  0 - Exit.\"\n                )\n\n                input_02: str = input(\"\\n> Enter an operation: \").strip()\n\n                while input_02 != \"0\":\n                    match input_02:\n                        case \"0\":\n                            pass\n\n                        case \"1\":\n                            post_content: str = input(\n                                \"\\n> Post content (maximum 200 characters): \"\n                            ).strip()\n                            user.create_post(content=post_content)\n\n                        case \"2\":\n                            posts: list[AbcPost] = database.get_user_posts(\n                                _u_name=user.u_name\n                            )\n\n                            posts.sort(key=lambda post: post.date, reverse=True)\n\n                            for i, post in enumerate(iterable=posts):\n                                if i > 10:\n                                    break\n\n                                print(f\"\\n> ID: '{post.uid}'.\")\n                                print(f\"> Author: '{post.author}'.\")\n                                print(f\"> Content: '{post.content}'.\")\n                                print(f\"> Creation date: '{post.date}'.\")\n                                print(f\"> Likes: {len(post.likes)}.\")\n\n                        case \"3\":\n                            posts = database.get_user_followings_posts(\n                                _u_name=user.u_name\n                            )\n\n                            posts.sort(key=lambda post: post.date, reverse=True)\n\n                            for i, post in enumerate(iterable=posts):\n                                if i > 10:\n                                    break\n\n                                print(f\"\\n> ID: '{post.uid}'.\")\n                                print(f\"> Author: '{post.author}'.\")\n                                print(f\"> Content: '{post.content}'.\")\n                                print(f\"> Creation date: '{post.date}'.\")\n                                print(f\"> Likes: {len(post.likes)}.\")\n\n                        case \"4\":\n                            post_uid: UUID = input(\"\\n> Post ID: \").strip()  # type: ignore\n                            user.delete_post(uid=post_uid)\n\n                        case \"5\":\n                            u_name = input(\"\\n> Username: \").strip()\n                            user.follow(_u_name=u_name)\n\n                        case \"6\":\n                            u_name = input(\"\\n> Username: \").strip()\n                            user.unfollow(_u_name=u_name)\n\n                        case \"7\":\n                            post_uid = input(\"\\n> Post ID: \").strip()  # type: ignore\n                            user.like_post(uid=post_uid)\n\n                        case \"8\":\n                            post_uid = input(\"\\n> Post ID: \").strip()  # type: ignore\n                            user.unlike_post(uid=post_uid)\n\n                        case _:\n                            print(\"\\n> Invalid operation! Try again...\")\n\n                    print(\n                        \"\\n> Available operations...\\n\\n\"\n                        \"  1 - Create a new post.\\n\"\n                        \"  2 - Show personal feed.\\n\"\n                        \"  3 - Show following feed.\\n\"\n                        \"  4 - Delete post.\\n\"\n                        \"  5 - Follow user.\\n\"\n                        \"  6 - Unfollow user.\\n\"\n                        \"  7 - Like post.\\n\"\n                        \"  8 - Unlike post.\\n\"\n                        \"  0 - Exit.\"\n                    )\n\n                    input_02: str = input(\"\\n> Enter an operation: \").strip()\n            else:\n                print(\"> Username not found.\")\n\n        case _:\n            print(\"\\n> Invalid operation! Try again...\")\n\n    print(\n        \"\\n> Available operations...\\n\\n\"\n        \"  1 - Sign up a new user.\\n\"\n        \"  2 - Sign in as user.\\n\"\n        \"  0 - Exit.\"\n    )\n\n    input_01: str = input(\"\\n> Enter an operation: \").strip()\n"
  },
  {
    "path": "Roadmap/46 - X VS BLUESKY/python/idiegorojas.py",
    "content": "\"\"\"\n# 46 - Bluesky vs X\n\"\"\"\n# Implementa un sistema que simule el comportamiento de estas redes sociales.\n# Debes crear las siguientes operaciones:\n    # Registrar un usuario por nombre e identificador único.\n    # Un usuario puede seguir/dejar de seguir a otro.\n    # Creación de post asociado a un usuario. Debe poseer texto (200 caracteres máximo), fecha de creación e identificador único.  \n    # Eliminación de un post.\n    # Posibilidad de hacer like (y eliminarlo) en un post.\n    # Visualización del feed de un usuario con sus 10 publicaciones más actuales ordenadas desde la más reciente.\n    # Visualización del feed de un usuario con las 10 publicaciones más actuales de los usuarios que sigue ordenadas desde la más reciente.\n    # Cuando se visualiza un post, debe mostrarse:\n    # ID de usuario\n    # nombre de usuario\n    # texto del post,\n    # fecha de creación\n    # número total de likes.\n# Controla errores en duplicados o acciones no permitidas.\nimport datetime\n\nclass SocialMedia():\n    def __init__(self):\n        self.users = {} # Id User {name: user name} \n        self.posts = {} # {post: [id, description, created date]}\n        self.followers = {} # {user: [# followers]}\n\n    \n    def create_user(self):\n        username = input(\"Ingresa tu nombre de usuario: \")\n\n        if username in self.users:\n            print(f\"Lo sentimos el nombre de usuario {username} no esta disponible\")\n            return False\n        \n        user_id = len(self.users) + 1\n\n        self.users[username] = {\"id\": user_id, \"name\":username}\n        self.followers[username] = []\n\n        print(f\"Usuario {username} creado exitosamente con el ID: {user_id}\")\n        return True\n    \n\n    def create_post(self):\n        username = input(\"Ingresa tu usuario: \")\n\n        if username not in self.users:\n            print(f\"Lo sentimos el usuario {username} no se encuentra registrado\")\n            return False\n        \n        post_text = input(\"Ingresa el post (maximo 200 caracteres): \")\n\n        if len(post_text) > 200:\n            print(\"Lo sentimos el post excede el numero de caracteres. (Maximo 200)\")\n            return False\n        \n        post_id = len(self.posts) + 1\n\n        creation_date = datetime.datetime.now().strftime(\"%Y-%m-%d %H:%M:%S\")\n\n        self.posts[post_id] = {\n            \"id\": post_id,\n            \"user_id\": self.users[username][\"id\"],\n            \"username\": username,\n            \"text\": post_text,\n            \"created_at\": creation_date,\n            \"likes\": []\n        }\n\n        print(f\"Post con ID: {post_id} creado exitosamente.\")\n        return True\n    \n    def follow_user(self):\n        follower = input(\"Ingresa tu nombre de usuario: \")\n        \n        if follower not in self.users:\n            print(f\"Lo sentimos, el usuario {follower} no existe\")\n            return False\n        \n        to_follow = input(\"Ingresa el nombre del usuario que deseas seguir: \")\n        \n        if to_follow not in self.users:\n            print(f\"Lo sentimos, el usuario {to_follow} no existe\")\n            return False\n        \n        if follower == to_follow:\n            print(\"No puedes seguirte a ti mismo\")\n            return False\n            \n        if to_follow in self.followers[follower]:\n            print(f\"Ya estás siguiendo a {to_follow}\")\n            return False\n            \n        self.followers[follower].append(to_follow)\n        print(f\"Ahora estás siguiendo a {to_follow}\")\n        return True\n    \n    def unfollow_user(self):\n        follower = input(\"Ingresa tu nombre de usuario: \")\n        \n        if follower not in self.users:\n            print(f\"Lo sentimos, el usuario {follower} no existe\")\n            return False\n        \n        to_unfollow = input(\"Ingresa el nombre del usuario que deseas dejar de seguir: \")\n        \n        if to_unfollow not in self.followers[follower]:\n            print(f\"No estás siguiendo a {to_unfollow}\")\n            return False\n            \n        self.followers[follower].remove(to_unfollow)\n        print(f\"Has dejado de seguir a {to_unfollow}\")\n        return True\n    \n    def delete_post(self):\n        username = input(\"Ingresa tu nombre de usuario: \")\n        \n        if username not in self.users:\n            print(f\"Lo sentimos, el usuario {username} no existe\")\n            return False\n        \n        post_id = input(\"Ingresa el ID del post que deseas eliminar: \")\n        \n        try:\n            post_id = int(post_id)\n        except ValueError:\n            print(\"El ID del post debe ser un número\")\n            return False\n            \n        if post_id not in self.posts:\n            print(f\"El post con ID {post_id} no existe\")\n            return False\n            \n        if self.posts[post_id][\"username\"] != username:\n            print(\"No puedes eliminar un post que no te pertenece\")\n            return False\n            \n        del self.posts[post_id]\n        print(f\"Post con ID {post_id} eliminado exitosamente\")\n        return True\n    \n    def like_post(self):\n        username = input(\"Ingresa tu nombre de usuario: \")\n        \n        if username not in self.users:\n            print(f\"Lo sentimos, el usuario {username} no existe\")\n            return False\n        \n        post_id = input(\"Ingresa el ID del post que deseas dar like: \")\n        \n        try:\n            post_id = int(post_id)\n        except ValueError:\n            print(\"El ID del post debe ser un número\")\n            return False\n            \n        if post_id not in self.posts:\n            print(f\"El post con ID {post_id} no existe\")\n            return False\n            \n        if username in self.posts[post_id][\"likes\"]:\n            print(\"Ya has dado like a este post\")\n            return False\n            \n        self.posts[post_id][\"likes\"].append(username)\n        print(f\"Has dado like al post con ID {post_id}\")\n        return True\n    \n    def unlike_post(self):\n        username = input(\"Ingresa tu nombre de usuario: \")\n        \n        if username not in self.users:\n            print(f\"Lo sentimos, el usuario {username} no existe\")\n            return False\n        \n        post_id = input(\"Ingresa el ID del post que deseas quitar like: \")\n        \n        try:\n            post_id = int(post_id)\n        except ValueError:\n            print(\"El ID del post debe ser un número\")\n            return False\n            \n        if post_id not in self.posts:\n            print(f\"El post con ID {post_id} no existe\")\n            return False\n            \n        if username not in self.posts[post_id][\"likes\"]:\n            print(\"No has dado like a este post\")\n            return False\n            \n        self.posts[post_id][\"likes\"].remove(username)\n        print(f\"Has quitado el like al post con ID {post_id}\")\n        return True\n    \n    def show_post(self, post_id):\n        if post_id not in self.posts:\n            print(f\"El post con ID {post_id} no existe\")\n            return False\n            \n        post = self.posts[post_id]\n        print(f\"ID de usuario: {post['user_id']}\")\n        print(f\"Nombre de usuario: {post['username']}\")\n        print(f\"Texto: {post['text']}\")\n        print(f\"Fecha de creación: {post['created_at']}\")\n        print(f\"Número de likes: {len(post['likes'])}\")\n        return True\n    \n    def user_feed(self):\n        username = input(\"Ingresa tu nombre de usuario: \")\n        \n        if username not in self.users:\n            print(f\"Lo sentimos, el usuario {username} no existe\")\n            return False\n            \n        # Encuentra todos los posts del usuario\n        user_posts = []\n        for post_id, post in self.posts.items():\n            if post[\"username\"] == username:\n                user_posts.append((post_id, post[\"created_at\"]))\n                \n        # Ordena por fecha de creación (más reciente primero)\n        user_posts.sort(key=lambda x: x[1], reverse=True)\n        \n        # Obtiene los 10 posts más recientes\n        recent_posts = user_posts[:10]\n        \n        if not recent_posts:\n            print(f\"El usuario {username} no tiene publicaciones\")\n            return False\n            \n        print(f\"Feed de {username} (publicaciones propias):\")\n        for idx, (post_id, _) in enumerate(recent_posts, 1):\n            print(f\"\\nPost {idx}:\")\n            self.show_post(post_id)\n            \n        return True\n    \n    def following_feed(self):\n        username = input(\"Ingresa tu nombre de usuario: \")\n        \n        if username not in self.users:\n            print(f\"Lo sentimos, el usuario {username} no existe\")\n            return False\n            \n        # Obtiene la lista de usuarios seguidos\n        following = self.followers[username]\n        \n        if not following:\n            print(f\"El usuario {username} no sigue a nadie\")\n            return False\n            \n        # Encuentra todos los posts de los usuarios seguidos\n        followed_posts = []\n        for post_id, post in self.posts.items():\n            if post[\"username\"] in following:\n                followed_posts.append((post_id, post[\"created_at\"]))\n                \n        # Ordena por fecha de creación (más reciente primero)\n        followed_posts.sort(key=lambda x: x[1], reverse=True)\n        \n        # Obtiene los 10 posts más recientes\n        recent_posts = followed_posts[:10]\n        \n        if not recent_posts:\n            print(f\"Los usuarios seguidos por {username} no tienen publicaciones\")\n            return False\n            \n        print(f\"Feed de {username} (publicaciones de usuarios seguidos):\")\n        for idx, (post_id, _) in enumerate(recent_posts, 1):\n            print(f\"\\nPost {idx}:\")\n            self.show_post(post_id)\n            \n        return True\n    \n    def main_menu(self):\n        menu = \"\"\"\n        SISTEMA DE REDES SOCIALES\n        ------------------------\n        1. Crear usuario\n        2. Crear post\n        3. Seguir a un usuario\n        4. Dejar de seguir a un usuario\n        5. Eliminar post\n        6. Dar like a un post\n        7. Quitar like a un post\n        8. Ver feed propio\n        9. Ver feed de usuarios seguidos\n        0. Salir\n        \n        Selecciona una opción: \"\"\"\n        \n        while True:\n            option = input(menu)\n            \n            if option == \"1\":\n                self.create_user()\n            elif option == \"2\":\n                self.create_post()\n            elif option == \"3\":\n                self.follow_user()\n            elif option == \"4\":\n                self.unfollow_user()\n            elif option == \"5\":\n                self.delete_post()\n            elif option == \"6\":\n                self.like_post()\n            elif option == \"7\":\n                self.unlike_post()\n            elif option == \"8\":\n                self.user_feed()\n            elif option == \"9\":\n                self.following_feed()\n            elif option == \"0\":\n                print(\"¡Hasta pronto!\")\n                break\n            else:\n                print(\"Opción no válida. Intenta de nuevo.\")\n                \n            input(\"\\nPresiona Enter para continuar...\")\n\n# Ejecutar el programa\nif __name__ == \"__main__\":\n    app = SocialMedia()\n    app.main_menu()"
  },
  {
    "path": "Roadmap/46 - X VS BLUESKY/python/ignaciovihe.py",
    "content": "\"\"\"\n* EJERCICIO:\n * La alternativa descentralizada a X, Bluesky, comienza a atraer\n * a nuevos usuarios. ¿Cómo funciona una red de este estilo?\n * \n * Implementa un sistema que simule el comportamiento de estas\n * redes sociales.\n * \n * Debes crear las siguientes operaciones:\n * - Registrar un usuario por nombre e identificador único.\n * - Un usuario puede seguir/dejar de seguir a otro.\n * - Creación de post asociado a un usuario. Debe poseer\n *   texto (200 caracteres máximo), fecha de creación \n *   e identificador único.   \n * - Eliminación de un post.\n * - Posibilidad de hacer like (y eliminarlo) en un post.\n * - Visualización del feed de un usuario con sus 10 publicaciones\n *   más actuales ordenadas desde la más reciente.\n * - Visualización del feed de un usuario con las 10 publicaciones\n *   más actuales de los usuarios que sigue ordenadas \n *   desde la más reciente.\n *   \n * Cuando se visualiza un post, debe mostrarse:\n * ID de usuario, nombre de usuario, texto del post, \n * fecha de creación y número total de likes.\n * \n * Controla errores en duplicados o acciones no permitidas.\n\"\"\"\nfrom __future__ import annotations\nimport uuid\nfrom datetime import datetime\nimport os\nimport textwrap\nfrom abc import ABC, abstractmethod\n\n# =========================\n# Estrategias de búsqueda\n# =========================\nclass PostSearchStrategy(ABC):\n    @abstractmethod\n    def get_posts(self, users: list[User], **filters) -> list[Post]:\n        pass\n\nclass AllPostsStrategy(PostSearchStrategy):\n    def get_posts(self, users: list[User], **filters) -> list[Post]:\n        result = []\n        for user in users:\n            result.extend(user.posts.values())\n        return list(reversed(result))\n\nclass LastTenPostsStrategy(PostSearchStrategy):\n    def get_posts(self, users: list[User], **filters) -> list[Post]:\n        result = []\n        for user in users:\n            result.extend(user.posts.values())\n        sorted_result = sorted(result, key=lambda i: i.date, reverse=True)\n        return sorted_result[:10]\n\nclass OneSinglePostStrategy(PostSearchStrategy):\n    def get_posts(self, users: list[User], **filters) -> list[Post]:\n        id_post = filters.get(\"id_post\")\n        if not id_post:\n            return []\n        result = []\n        for user in users:\n            result.extend(user.posts.values())\n        for post in result:\n            if post.id == uuid.UUID(id_post):\n                return [post]\n        return []\n\nclass LikedPostStrategy(PostSearchStrategy):\n    def get_posts(self, users: list[User], **filters) -> list[Post]:\n        result = []\n        for user in users:\n            result.extend(user.likes.values())\n        return result\n\n\n# =========================\n# Funciones de utilidad\n# =========================\ndef clear_console():\n    os.system('cls' if os.name == 'nt' else 'clear')\n\ndef pausar():\n    input(\"ENTER para continuar\")\n\n\n# =========================\n# Entidades\n# =========================\nclass User:\n    def __init__(self, name: str) -> None:\n        self.name = name\n        self.following = dict()\n        self.followers = dict()\n        self.posts = dict()\n        self.likes = dict()\n\nclass Post:\n    def __init__(self, user_id, text: str) -> None:\n        self.id = uuid.uuid4()\n        self.user_id = user_id\n        self.date = datetime.now()\n        self.text = text\n        self.likes = []\n\n\n# =========================\n# Lógica de negocio de posts\n# =========================\nclass PostService:\n    def __init__(self, user: User):\n        self.user = user\n\n    def create_post(self, text: str) -> Post:\n        if not (0 < len(text) < 200):\n            raise ValueError(\"El texto debe tener entre 1 y 200 caracteres.\")\n        new_post = Post(self.user.name, text)\n        self.user.posts[new_post.id] = new_post\n        return new_post\n\n    def delete_post(self, post_id: uuid.UUID) -> bool:\n        if post_id in self.user.posts:\n            del self.user.posts[post_id]\n            return True\n        return False\n\n    def like_post(self, post: Post) -> bool:\n        post_id_str = str(post.id)\n        if post_id_str not in self.user.likes:\n            post.likes.append(self.user.name)\n            self.user.likes[post_id_str] = post\n            return True\n        return False\n\n    def unlike_post(self, post: Post) -> bool:\n        post_id_str = str(post.id)\n        if post_id_str in self.user.likes:\n            del self.user.likes[post_id_str]\n            if self.user.name in post.likes:\n                post.likes.remove(self.user.name)\n            return True\n        return False\n\n\n# =========================\n# Presentación en consola de posts\n# =========================\nclass PostConsoleUI:\n\n    def show_posts(self, posts: list[Post]):\n        if not posts:\n            print(\"No hay posts para mostrar.\")\n            return\n        for post in posts:\n            print(f\"{'Post id: ' + str(post.id):<50}   {'Usuario:' + post.user_id:>47}\")\n            for line in textwrap.wrap(post.text, width=100):\n                print(f\"{line:<100}\")\n            print(f\"{str(post.date):<50}   {'Likes:' + str(len(post.likes)):>47}\")\n            print(\"=\" * 100)\n\n\n# =========================\n# Gestión de usuarios\n# =========================\nclass UserManager:\n    def __init__(self) -> None:\n        self.users = dict()\n\n    def register_user(self, user_name: str):\n        new_user = User(user_name)\n        self.users[new_user.name] = new_user\n        print(f\"Usuario con nombre {user_name} registrado con éxito.\")\n\n    def get_user(self, user_name):\n        return self.users[user_name]\n    \n    def search_users(self, name: str):\n        results = []\n        for id, user in self.users.items():\n            if name:\n                if name in id:\n                    results.append(user)\n            else:\n                results.append(user)\n        return results\n\n\n# =========================\n# Gestión de sesión\n# =========================\nclass SessionManager:\n    def __init__(self, user_manager: UserManager) -> None:\n        self.user_manager = user_manager\n\n    def register_new_user(self):\n        user_name = \"\"\n        while not user_name or user_name in self.user_manager.users:\n            user_name = input(\"Introduce un nombre de usuario nuevo a registrar: \")\n            if not user_name:\n                print(\"El nombre de usuario no puede estar vacío. Elige otro.\")\n            if user_name in self.user_manager.users:\n                print(\"El nombre de usuario ya existe. Elige otro.\")\n        self.user_manager.register_user(user_name)\n        pausar()\n\n    def start_new_session(self):\n        if not self.user_manager.users:\n            print(\"Todavía no hay usuarios registrados. Registra uno primero.\")\n            pausar()\n            return\n        user_name = \"\"\n        while not user_name or user_name not in self.user_manager.users:\n            user_name = input(\"Introduce un nombre de usuario con el que iniciar sesión: \")\n            if not user_name:\n                print(\"El nombre de usuario no puede estar vacío. Elige otro.\")\n            if user_name not in self.user_manager.users:\n                print(\"El nombre de usuario no existe. Elige otro o crea uno nuevo.\")\n                option = \"0\"\n                while option not in [\"1\", \"2\"]:\n                    print(\"\\t1. Probar otro nombre\")\n                    print(\"\\t2. Registrar nuevo usuario\")\n                    option = input(\"Introduce una opción correcta: \")\n                if option == \"1\":\n                    continue\n                else:\n                    self.register_new_user()\n                    user_name = \"\"\n        return user_name\n    \n    def log_in(self):\n        while True:\n            clear_console()\n            print(\"Bienvenido a 'J' la nueva red social de microblogging.\")\n            print(\"\\t1. Inicia sesión.\")\n            print(\"\\t2. Registrar nuevo usuario\")\n            print(\"\\t3. Salir\")\n            option = \"0\"\n            while option not in [\"1\", \"2\", \"3\"]:\n                option = input(\"Introduce una opción correcta:  \")\n            \n            match option:\n                case \"1\":\n                    active_name = self.start_new_session()\n                    if active_name:\n                        return self.user_manager.get_user(active_name)\n                case \"2\":\n                    self.register_new_user()\n                case \"3\":\n                    return None\n\n\n# =========================\n# Gestión de seguidores\n# =========================\nclass FollowersManager:\n    def __init__(self, user: User, user_manager: UserManager) -> None:\n        self.active_user = user\n        self.user_manager = user_manager\n\n    def follow_user(self):\n        print(\"Introduce un nombre de usuario a buscar.\")\n        user_name_to_search = input(\"Puedes escribir parte del nombre, o no escribir nada para buscar todos los usuarios: \")\n        results: list[User] = self.user_manager.search_users(user_name_to_search)\n        if results:\n            for i, found_user in enumerate(results):\n                print(\n                    f\"{i + 1} - {found_user.name} \"\n                    f\"{'(tú)' if found_user.name == self.active_user.name else ''} \"\n                    f\"{'(ya seguido)' if found_user.name in self.active_user.following else ''} \"\n                )\n            option = \"0\"\n            valid_options = [str(i) for i in range(1, len(results) + 1)]\n            while option not in valid_options:\n                option = input(\"Introduce una opción válida: \")\n            selected_user = results[int(option) - 1]\n            if selected_user.name != self.active_user.name:\n                if selected_user.name not in self.active_user.following:\n                    self.active_user.following[selected_user.name] = selected_user\n                    selected_user.followers[self.active_user.name] = self.active_user\n                    print(f\"{self.active_user.name} ahora sigue a {selected_user.name}.\")\n                else:\n                    print(\"Ya sigues a ese usuario.\")\n            else:\n                print(\"No puedes seguirte a ti mismo.\")\n        else:\n            print(\"No hay usuarios que coincidan con el nombre introducido\")\n        pausar()\n\n    def unfollow_user(self):\n        if self.active_user.following:\n            for i, (name, user) in enumerate(self.active_user.following.items()):\n                print(\n                    f\"{i + 1} - {user.name} \"\n                    f\"{'(tú)' if user.name == self.active_user.name else ''} \"\n                    f\"{'(ya seguido)' if user.name in self.active_user.following else ''} \"\n                )\n            option = \"0\"\n            valid_options = [str(i) for i in range(1, len(self.active_user.following) + 1)]\n            while option not in valid_options:\n                option = input(\"Introduce una opción válida: \")\n            selected_user = list(self.active_user.following.values())[int(option) - 1]\n            del self.active_user.following[selected_user.name]\n            del selected_user.followers[self.active_user.name]\n            print(f\"{self.active_user.name} ya no sigue a {selected_user.name}.\")\n        else:\n            print(\"Todavía no sigues a nadie.\")\n        pausar()\n\n\n# =========================\n# Sesión activa\n# =========================\nclass ActiveSession:\n    def __init__(self, user: User, user_manager: UserManager) -> None:\n        self.user = user\n        self.user_manager = user_manager\n        self.post_service = PostService(self.user)\n        self.post_ui = PostConsoleUI()\n        self.followers_manager = FollowersManager(self.user, self.user_manager)\n\n    def show_menu(self):\n        clear_console()\n        print(f\"Sesión iniciada como: {self.user.name} - Followers: {len(self.user.followers)}\")\n        print()\n        print(\"\\t1. Crear nuevo post.\")\n        print(\"\\t2. Borrar post.\")\n        print(\"\\t3. Ver post propios.\")\n        print(\"\\t4. Ver post de usuarios seguidos.\")\n        print(\"\\t5. Eliminar like.\")\n        print(\"\\t6. Seguir usuario.\")\n        print(\"\\t7. Dejar de seguir usuario\")\n        print(\"\\t8. Cerrar sesión.\")\n        print(\"\\t9. Salir\")\n\n        option = \"0\"\n        while option not in map(str, range(1, 10)):\n            option = input(\"Introduce una opción correcta: \")\n\n        return option\n\n\n# =========================\n# Aplicación principal\n# =========================\nclass SocialNetwork:\n    def __init__(self) -> None:\n        self.user_manager = UserManager()\n        self.session_manager = SessionManager(self.user_manager)\n        self.active_user: User | None = None\n\n    def log_in(self):\n        self.active_user = self.session_manager.log_in()\n        return self.active_user is None\n                \n    def run_program(self):\n        if self.active_user:\n            session = ActiveSession(self.active_user, self.user_manager)\n            option = session.show_menu()\n\n            match option:\n                case \"1\":\n                    text = input(\"Introduce el texto del post: \")\n                    try:\n                        session.post_service.create_post(text)\n                        print(\"Post creado con éxito.\")\n                    except ValueError as e:\n                        print(e)\n                    pausar()\n\n                case \"2\":\n                    posts = AllPostsStrategy().get_posts([self.active_user])\n                    session.post_ui.show_posts(posts)\n                    id_post = input(\"Introduce el id del post a borrar: \")\n                    try:\n                        if session.post_service.delete_post(uuid.UUID(id_post)):\n                            print(\"Post borrado con éxito.\")\n                        else:\n                            print(\"No se encontró un post con ese ID.\")\n                    except Exception:\n                        print(\"ID inválido.\")\n                    pausar()\n\n                case \"3\":\n                    posts = LastTenPostsStrategy().get_posts([self.active_user])\n                    session.post_ui.show_posts(posts)\n                    pausar()\n\n                case \"4\":\n                    posts = LastTenPostsStrategy().get_posts(list(self.active_user.following.values()))\n                    session.post_ui.show_posts(posts)\n                    option_like = input(\"¿Quieres darle like a algún post? (s/n): \")\n                    if option_like.lower() == \"s\":\n                        id_post = input(\"Introduce el id del post a dar like: \")\n                        found = OneSinglePostStrategy().get_posts(list(self.user_manager.users.values()), id_post=id_post)\n                        if found:\n                            if session.post_service.like_post(found[0]):\n                                print(\"Like realizado con éxito.\")\n                            else:\n                                print(\"Ya habías dado like a este post.\")\n                        else:\n                            print(\"No se encontró el post.\")\n                    pausar()\n\n                case \"5\":\n                    posts = LikedPostStrategy().get_posts([self.active_user])\n                    session.post_ui.show_posts(posts)\n                    id_post = input(\"Introduce el id del post para quitar el like: \")\n                    found = OneSinglePostStrategy().get_posts(list(self.user_manager.users.values()), id_post=id_post)\n                    if found:\n                        if session.post_service.unlike_post(found[0]):\n                            print(\"Like eliminado con éxito.\")\n                        else:\n                            print(\"No tenías like en este post.\")\n                    pausar()\n\n                case \"6\":\n                    session.followers_manager.follow_user()\n\n                case \"7\":\n                    session.followers_manager.unfollow_user()\n\n                case \"8\":\n                    self.active_user = None\n\n                case \"9\":\n                    return True\n\n\n# =========================\n# Ejecución\n# =========================\nmy_social_network = SocialNetwork()\nfinish = False\nwhile not finish:\n    while not my_social_network.active_user and not finish:\n        finish = my_social_network.log_in()\n\n    while my_social_network.active_user and not finish:\n        finish = my_social_network.run_program()"
  },
  {
    "path": "Roadmap/46 - X VS BLUESKY/python/kenysdev.py",
    "content": "# _____________________________________\n# https://github.com/kenysdev\n# 2024 - Python\n# _____________________________________\n# #46 X VS BLUESKY\n# ------------------------------------\n\n\"\"\"\n* EJERCICIO:\n * La alternativa descentralizada a X, Bluesky, comienza a atraer\n * a nuevos usuarios. ¿Cómo funciona una red de este estilo?\n * \n * Implementa un sistema que simule el comportamiento de estas\n * redes sociales.\n * \n * Debes crear las siguientes operaciones:\n * - Registrar un usuario por nombre e identificador único.\n * - Un usuario puede seguir/dejar de seguir a otro.\n * - Creación de post asociado a un usuario. Debe poseer\n *   texto (200 caracteres máximo), fecha de creación \n *   e identificador único.   \n * - Eliminación de un post.\n * - Posibilidad de hacer like (y eliminarlo) en un post.\n * - Visualización del feed de un usuario con sus 10 publicaciones\n *   más actuales ordenadas desde la más reciente.\n * - Visualización del feed de un usuario con las 10 publicaciones\n *   más actuales de los usuarios que sigue ordenadas \n *   desde la más reciente.\n *   \n * Cuando se visualiza un post, debe mostrarse:\n * ID de usuario, nombre de usuario, texto del post, \n * fecha de creación y número total de likes.\n * \n * Controla errores en duplicados o acciones no permitidas.\n\"\"\"\n\n# ____________________________________________________________________________\nimport logging\nfrom datetime import datetime\nfrom operator import itemgetter\n\n# ____________\nclass Posts:\n    def __init__(self) -> None:\n        self.__post_dt: dict = {}\n\n    def __verify_post(self, id_user: int, id_post, name_func: str) -> bool:\n        if id_user not in self.__post_dt:\n            logging.error(\"'%s': El ID %s no tiene posts.\", name_func, id_user)\n            return False\n\n        if id_post not in self.__post_dt[id_user]:\n            logging.error(\"'%s': El Post (%s) no existe.\", name_func, id_post)\n            return False\n\n        return True\n\n    def create_post(self, id_user: int, content: str) -> None:\n        if len(content) > 200:\n            logging.error(\"'create_post': content > 200 caracteres.\")\n            return\n\n        if id_user not in self.__post_dt:\n            self.__post_dt[id_user] = {}\n\n        id_post = len(self.__post_dt[id_user]) + 1\n        self.__post_dt[id_user][id_post] = {\n            \"content\": content,\n            \"timestamp\": datetime.now(),\n            \"likes\": set()\n        }\n\n        logging.info(\"El ID %s creó un post(ID: %s).\", id_user, id_post)\n\n    def delete_post(self, id_user: int, id_post: int) -> None:\n        if self.__verify_post(id_user, id_post, \"delete_post\"):\n            del self.__post_dt[id_user][id_post]\n            logging.info(\n                \"El post: %s de usuario: %s ha sido eliminado.\", id_post, id_user\n            )\n\n    def like_post(self, id_user: int, id_author: int, id_post: int) -> None:\n        if self.__verify_post(id_author, id_post, \"like_post\"):\n            self.__post_dt[id_author][id_post][\"likes\"].add(id_user)\n            logging.info(\n                \"El usuario %s dio like al post %s de usuario %s.\", \n                id_user, id_post, id_author\n            )\n\n    def remove_like(self, id_user: int, id_author: int, id_post: int) -> None:\n        if self.__verify_post(id_author, id_post, \"remove_like\"):\n            self.__post_dt[id_author][id_post][\"likes\"].discard(id_user)\n            logging.info(\n                \"El usuario %s anuló el like al post %s de usuario %s.\", \n                id_user, id_post, id_author\n            )\n\n    def get_recent_posts(self, id_user: int, limit=10) -> list:\n        if id_user in self.__post_dt:        \n            sorted_posts: list = sorted(\n                self.__post_dt[id_user].values(), \n                key=itemgetter('timestamp'), \n                reverse=True\n            )\n\n            return sorted_posts[:limit]\n        \n        return []\n\n# ____________\nclass Users:\n    def __init__(self) -> None:\n        self.__users_dt: dict = {}\n    \n    def __id_exists(self, id_: int, name_func: str = \"\") -> bool:\n        if id_ in self.__users_dt:\n            return True\n\n        logging.warning(\"'%s': ID: %s no encontrada.\", name_func, id_)\n        return False\n    \n    def add_user(self, name) -> None:\n        id_ = len(self.__users_dt) + 1\n        self.__users_dt[id_] = {\n            \"name\": name,\n            \"following\": set(),\n            \"followers\": set(),\n        }\n\n        logging.info(\"Usuario %s-%s registrado.\", id_, name)\n\n    def follow_user(self, id_: int, to_id: int) -> None:\n        if (\n            self.__id_exists(id_, \"follow_user\")\n            and self.__id_exists(to_id, \"follow_user\")\n        ):\n            self.__users_dt[id_][\"following\"].add(to_id)\n            self.__users_dt[to_id][\"followers\"].add(id_)\n            logging.info(\"ID: %s está siguiendo a ID: %s.\", id_, to_id)\n\n    def unfollow_user(self, id_: int, to_id: int) -> None:\n        if (\n            self.__id_exists(id_, \"unfollow_use\") \n            and self.__id_exists(to_id, \"unfollow_use\")\n        ):\n            self.__users_dt[id_][\"following\"].discard(to_id)\n            self.__users_dt[to_id][\"followers\"].discard(id_)\n            logging.info(\"El ID: %s dejó de seguir al ID: %s.\", id_, to_id)\n\n    def get_name(self, id_user: int) -> str:\n        if self.__id_exists(id_user, \"get_name\"):\n            return self.__users_dt[id_user][\"name\"]\n\n        return \"\"\n\n# ____________________________________________________________________________\n# ____________\nclass Program:\n    def __init__(self, posts, users) -> None:\n        self.__posts = posts()\n        self.__users = users()\n\n    def __print_feed(self, id_user: int):\n        name: str = self.__users.get_name(id_user)\n        if not name:\n            print(f\"Usuario ID: {id_user} no encontrado.\")\n            return\n\n        last_10: dict = self.__posts.get_recent_posts(id_user, limit=10)\n        print(f\"\\nFeed\\n_______\\nID: '{id_user}' - Nombre: '{name}'\")\n        if not last_10:\n            print(\"No tiene publicaciones.\")\n            return\n        for post in last_10:\n            print(f\"_______\\n{post['content']}\")\n            print(f\"Creado: '{post['timestamp']}'\")\n            print(f\"Likes: '{len(post['likes'])}'\")\n    \n    def run(self):\n        # CLI\n        pass\n\n    def tests(self):\n        self.__users.add_user(name=\"Ken\") # id=1\n        self.__users.add_user(\"Zoe\") # id=2\n\n        self.__users.follow_user(id_=1, to_id=2)\n        self.__users.follow_user(2, 1)\n        self.__users.unfollow_user(2, 1)\n\n        self.__posts.create_post(id_user=2, content=\"Primer post.\") # id=1\n        self.__posts.create_post(2, \"Segundo post.\") # id=2\n        self.__posts.delete_post(id_user=2, id_post=2)\n        self.__posts.create_post(2, \"Otro post.\") # id=2\n        self.__posts.like_post(id_user=1, id_author=2, id_post=1)\n        self.__posts.remove_like(1, 2, 1)\n        self.__posts.like_post(1, 2, 2)\n\n        self.__print_feed(id_user=2)\n        self.__print_feed(id_user=1)\n\n# ____________\nif __name__ == \"__main__\":\n    logging.basicConfig(\n        level=logging.DEBUG, \n        format='%(asctime)s - %(levelname)s - %(message)s'\n    )\n\n    program = Program(Posts, Users)\n    program.tests()\n    #program.run()\n"
  },
  {
    "path": "Roadmap/46 - X VS BLUESKY/python/ljoecordoba.py",
    "content": "import uuid\nfrom datetime import datetime\n\n# Almacenamos los usuarios y posts globalmente\nusers = {}\nposts = {}\n\n# Límite de caracteres para los posts\nPOST_TEXT_LIMIT = 200\n\n\n# Función para registrar un usuario\ndef register_user(name):\n    if name in [user[\"name\"] for user in users.values()]:\n        raise ValueError(f\"El nombre de usuario '{name}' ya existe.\")\n    user_id = str(uuid.uuid4())  # Genera un identificador único\n    users[user_id] = {\n        \"id\": user_id,\n        \"name\": name,\n        \"following\": set(),  # Usuarios que sigue\n    }\n    return user_id\n\n\n# Función para seguir a otro usuario\ndef follow_user(follower_id, followee_id):\n    if follower_id not in users or followee_id not in users:\n        raise ValueError(\"Uno o ambos IDs de usuario no existen.\")\n    if follower_id == followee_id:\n        raise ValueError(\"Un usuario no puede seguirse a sí mismo.\")\n    users[follower_id][\"following\"].add(followee_id)\n\n\n# Función para dejar de seguir a otro usuario\ndef unfollow_user(follower_id, followee_id):\n    if follower_id not in users or followee_id not in users:\n        raise ValueError(\"Uno o ambos IDs de usuario no existen.\")\n    users[follower_id][\"following\"].discard(followee_id)  # No arroja error si no lo sigue\n\n\n# Función para crear un post\ndef create_post(user_id, text):\n    if user_id not in users:\n        raise ValueError(\"El usuario no existe.\")\n    if len(text) > POST_TEXT_LIMIT:\n        raise ValueError(f\"El texto del post no puede superar los {POST_TEXT_LIMIT} caracteres.\")\n    post_id = str(uuid.uuid4())  # Genera un identificador único\n    posts[post_id] = {\n        \"id\": post_id,\n        \"author_id\": user_id,\n        \"text\": text,\n        \"created_at\": datetime.now(),\n        \"likes\": set(),  # IDs de usuarios que dieron like\n    }\n    return post_id\n\n\n# Función para eliminar un post\ndef delete_post(post_id):\n    if post_id not in posts:\n        raise ValueError(\"El post no existe.\")\n    del posts[post_id]\n\n\n# Función para dar like a un post\ndef like_post(user_id, post_id):\n    if user_id not in users:\n        raise ValueError(\"El usuario no existe.\")\n    if post_id not in posts:\n        raise ValueError(\"El post no existe.\")\n    posts[post_id][\"likes\"].add(user_id)\n\n\n# Función para quitar un like de un post\ndef unlike_post(user_id, post_id):\n    if user_id not in users:\n        raise ValueError(\"El usuario no existe.\")\n    if post_id not in posts:\n        raise ValueError(\"El post no existe.\")\n    posts[post_id][\"likes\"].discard(user_id)\n\n\n# Función para visualizar el feed de un usuario\ndef view_feed(user_id, include_following=False):\n    if user_id not in users:\n        raise ValueError(\"El usuario no existe.\")\n    # Filtrar los posts relevantes\n    if include_following:\n        relevant_posts = [\n            post for post in posts.values()\n            if post[\"author_id\"] == user_id or post[\"author_id\"] in users[user_id][\"following\"]\n        ]\n    else:\n        relevant_posts = [\n            post for post in posts.values() if post[\"author_id\"] == user_id\n        ]\n    # Ordenar por fecha de creación (más recientes primero)\n    relevant_posts.sort(key=lambda x: x[\"created_at\"], reverse=True)\n    # Limitar a los 10 más recientes\n    relevant_posts = relevant_posts[:10]\n    # Mostrar los posts\n    for post in relevant_posts:\n        author = users[post[\"author_id\"]]\n        print(f\"[{post['created_at']}] {author['name']} (ID: {author['id']}):\")\n        print(f\"    {post['text']}\")\n        print(f\"    Likes: {len(post['likes'])}\")\n        print()\n\n\n# Pruebas iniciales\nif __name__ == \"__main__\":\n    # Crear usuarios\n    user1 = register_user(\"Alice\")\n    user2 = register_user(\"Bob\")\n    user3 = register_user(\"Charlie\")\n\n    # Seguir usuarios\n    follow_user(user1, user2)\n    follow_user(user1, user3)\n\n    # Crear posts\n    post1 = create_post(user1, \"Hola, este es mi primer post.\")\n    post2 = create_post(user2, \"¡Hola a todos! Este es Bob.\")\n    post3 = create_post(user3, \"Charlie en la casa.\")\n\n    # Likes\n    like_post(user1, post2)\n    like_post(user3, post2)\n    like_post(user2, post3)\n\n    # Ver feeds\n    print(\"\\n--- Feed de Alice (siguiendo a Bob y Charlie) ---\")\n    view_feed(user1, include_following=True)\n\n    print(\"\\n--- Feed propio de Bob ---\")\n    view_feed(user2, include_following=False)\n\n    # Eliminar un post\n    delete_post(post1)\n\n    print(\"\\n--- Feed de Alice después de eliminar un post ---\")\n    view_feed(user1, include_following=True)\n"
  },
  {
    "path": "Roadmap/46 - X VS BLUESKY/python/markbus-ai.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * La alternativa descentralizada a X, Bluesky, comienza a atraer\n * a nuevos usuarios. ¿Cómo funciona una red de este estilo?\n * \n * Implementa un sistema que simule el comportamiento de estas\n * redes sociales.\n * \n * Debes crear las siguientes operaciones:\n * - Registrar un usuario por nombre e identificador único.\n * - Un usuario puede seguir/dejar de seguir a otro.\n * - Creación de post asociado a un usuario. Debe poseer\n *   texto (200 caracteres máximo), fecha de creación \n *   e identificador único.   \n * - Eliminación de un post.\n * - Posibilidad de hacer like (y eliminarlo) en un post.\n * - Visualización del feed de un usuario con sus 10 publicaciones\n *   más actuales ordenadas desde la más reciente.\n * - Visualización del feed de un usuario con las 10 publicaciones\n *   más actuales de los usuarios que sigue ordenadas \n *   desde la más reciente.\n *   \n * Cuando se visualiza un post, debe mostrarse:\n * ID de usuario, nombre de usuario, texto del post, \n * fecha de creación y número total de likes.\n * \n * Controla errores en duplicados o acciones no permitidas.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\"\"\"\nimport sys\nfrom datetime import datetime\nfrom PyQt6.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, \n                            QHBoxLayout, QPushButton, QLineEdit, QLabel, \n                            QTextEdit, QScrollArea, QMessageBox, QComboBox,\n                            QStackedWidget, QFrame)\nfrom PyQt6.QtCore import Qt\nfrom PyQt6.QtGui import QFont, QPixmap, QPalette, QColor\n\nclass CustomButton(QPushButton):\n    def __init__(self, text, color=\"#1da1f2\", hover_color=\"#1991db\"):\n        super().__init__(text)\n        self.setStyleSheet(f\"\"\"\n            QPushButton {{\n                background-color: {color};\n                color: white;\n                border-radius: 20px;\n                padding: 10px 20px;\n                font-size: 14px;\n                font-weight: bold;\n                border: none;\n            }}\n            QPushButton:hover {{\n                background-color: {hover_color};\n            }}\n        \"\"\")\n\nclass LoginRegisterWindow(QWidget):\n    def __init__(self, parent=None):\n        super().__init__(parent)\n        self.parent = parent\n        self.initUI()\n\n    def initUI(self):\n        self.setStyleSheet(\"\"\"\n            QWidget {\n                background-color: #15202b;\n            }\n            QLabel {\n                color: #ffffff;\n            }\n            QLineEdit {\n                background-color: #253341;\n                color: #ffffff;\n                border: 1px solid #38444d;\n                border-radius: 4px;\n                padding: 12px;\n                font-size: 15px;\n                margin: 5px 0px;\n            }\n            QLineEdit:focus {\n                border: 1px solid #1da1f2;\n                background-color: #192734;\n            }\n            QLineEdit::placeholder {\n                color: #8899a6;\n            }\n            QPushButton {\n                border-radius: 4px;\n                padding: 12px;\n                font-size: 15px;\n                font-weight: bold;\n            }\n            QPushButton#login_btn {\n                background-color: #1da1f2;\n                color: white;\n                border: none;\n            }\n            QPushButton#login_btn:hover {\n                background-color: #1991db;\n            }\n            QPushButton#register_btn {\n                background-color: transparent;\n                color: #1da1f2;\n                border: 1px solid #1da1f2;\n            }\n            QPushButton#register_btn:hover {\n                background-color: rgba(29, 161, 242, 0.1);\n            }\n        \"\"\")\n\n        layout = QVBoxLayout()\n        layout.setSpacing(0)\n        layout.setContentsMargins(0, 0, 0, 0)\n        \n        # Container principal centrado\n        main_container = QWidget()\n        main_layout = QVBoxLayout(main_container)\n        main_layout.setAlignment(Qt.AlignmentFlag.AlignCenter)\n        \n        # Logo y título\n        logo_container = QWidget()\n        logo_layout = QVBoxLayout(logo_container)\n        \n        # Logo de mariposa naranja\n        logo_label = QLabel(\"🦋\")\n        logo_label.setStyleSheet(\"\"\"\n            font-size: 48px;\n            color: #f2994a;\n            margin-bottom: 15px;\n        \"\"\")\n        logo_label.setAlignment(Qt.AlignmentFlag.AlignCenter)\n        \n        # Título Bluesky\n        title_label = QLabel(\"Bluesky\")\n        title_label.setStyleSheet(\"\"\"\n            font-size: 36px;\n            font-weight: bold;\n            color: #1da1f2;\n            margin-bottom: 5px;\n        \"\"\")\n        title_label.setAlignment(Qt.AlignmentFlag.AlignCenter)\n        \n        # Subtítulo\n        subtitle = QLabel(\"Tu red social descentralizada\")\n        subtitle.setStyleSheet(\"\"\"\n            font-size: 16px;\n            color: #8899a6;\n            margin-bottom: 30px;\n        \"\"\")\n        subtitle.setAlignment(Qt.AlignmentFlag.AlignCenter)\n        \n        logo_layout.addWidget(logo_label)\n        logo_layout.addWidget(title_label)\n        logo_layout.addWidget(subtitle)\n        \n        # Formulario\n        form_container = QWidget()\n        form_container.setFixedWidth(400)\n        form_layout = QVBoxLayout(form_container)\n        form_layout.setSpacing(15)\n        \n        # Campos de entrada\n        self.username_input = QLineEdit()\n        self.username_input.setPlaceholderText('Usuario')\n        self.username_input.setFixedWidth(380)\n        \n        self.password_input = QLineEdit()\n        self.password_input.setPlaceholderText('Contraseña')\n        self.password_input.setEchoMode(QLineEdit.EchoMode.Password)\n        self.password_input.setFixedWidth(380)\n        \n        # Botones\n        login_btn = QPushButton('Iniciar Sesión')\n        login_btn.setObjectName(\"login_btn\")\n        login_btn.setFixedWidth(380)\n        \n        register_btn = QPushButton('Crear cuenta nueva')\n        register_btn.setObjectName(\"register_btn\")\n        register_btn.setFixedWidth(380)\n        \n        login_btn.clicked.connect(self.login)\n        register_btn.clicked.connect(self.register)\n        \n        # Agregar widgets al formulario\n        form_layout.addWidget(self.username_input, alignment=Qt.AlignmentFlag.AlignCenter)\n        form_layout.addWidget(self.password_input, alignment=Qt.AlignmentFlag.AlignCenter)\n        form_layout.addSpacing(10)\n        form_layout.addWidget(login_btn, alignment=Qt.AlignmentFlag.AlignCenter)\n        form_layout.addWidget(register_btn, alignment=Qt.AlignmentFlag.AlignCenter)\n        \n        # Agregar todo al layout principal\n        main_layout.addWidget(logo_container)\n        main_layout.addWidget(form_container)\n        \n        # Centrar todo en la ventana\n        layout.addWidget(main_container)\n        self.setLayout(layout)\n\n    def login(self):\n        username = self.username_input.text()\n        password = self.password_input.text()\n        \n        if not username or not password:\n            QMessageBox.warning(self, \"Error\", \"Por favor completa todos los campos\")\n            return\n            \n        if username in self.parent.users:\n            self.parent.current_user = self.parent.users[username]\n            self.parent.show_main_window()\n        else:\n            QMessageBox.warning(self, \"Error\", \"Usuario no encontrado\")\n\n    def register(self):\n        username = self.username_input.text()\n        password = self.password_input.text()\n        \n        if not username or not password:\n            QMessageBox.warning(self, \"Error\", \"Por favor completa todos los campos\")\n            return\n            \n        if username in self.parent.users:\n            QMessageBox.warning(self, \"Error\", \"Este usuario ya existe\")\n            return\n            \n        user_id = len(self.parent.users) + 1\n        new_user = User(username, user_id)\n        self.parent.users[username] = new_user\n        self.parent.current_user = new_user\n        self.parent.show_main_window()\n\nclass SocialNetworkGUI(QMainWindow):\n    def __init__(self):\n        super().__init__()\n        self.users = {}\n        self.posts = []\n        self.current_user = None\n        self.stacked_widget = QStackedWidget()\n        self.setCentralWidget(self.stacked_widget)\n        \n        # Crear las ventanas\n        self.login_window = LoginRegisterWindow(self)\n        self.main_window = QWidget()\n        \n        # Agregar las ventanas al stacked widget\n        self.stacked_widget.addWidget(self.login_window)\n        self.stacked_widget.addWidget(self.main_window)\n        \n        # Cargar datos de ejemplo\n        self.load_sample_data()\n        \n        self.initUI()\n        # Configurar ventana en pantalla completa\n        self.showMaximized()\n        self.setWindowTitle('Bluesky')\n\n    def load_sample_data(self):\n        # Crear usuarios de ejemplo\n        sample_users = [\n            (\"alice\", \"La exploradora del código\"),\n            (\"bob\", \"Desarrollador entusiasta\"),\n            (\"carol\", \"Tech lover\"),\n            (\"david\", \"Python fanático\"),\n            (\"eva\", \"Full-stack developer\")\n        ]\n        \n        for username, post_text in sample_users:\n            user_id = len(self.users) + 1\n            user = User(username, user_id)\n            self.users[username] = user\n            \n            # Crear algunos posts para cada usuario\n            post = Post(post_text, datetime.now().strftime(\"%Y-%m-%d %H:%M:%S\"), len(self.posts) + 1)\n            post.user = user\n            self.posts.append(post)\n        \n        # Crear algunas relaciones de seguimiento\n        self.users[\"alice\"].follow(self.users[\"bob\"])\n        self.users[\"alice\"].follow(self.users[\"carol\"])\n        self.users[\"bob\"].follow(self.users[\"alice\"])\n        self.users[\"carol\"].follow(self.users[\"alice\"])\n        self.users[\"david\"].follow(self.users[\"eva\"])\n        \n        # Agregar algunos likes\n        self.posts[0].likes.append(self.users[\"bob\"])\n        self.posts[0].likes.append(self.users[\"carol\"])\n        self.posts[1].likes.append(self.users[\"alice\"])\n        self.posts[2].likes.append(self.users[\"david\"])\n\n    def initUI(self):\n        main_layout = QHBoxLayout()\n        main_layout.setSpacing(0)\n        main_layout.setContentsMargins(0, 0, 0, 0)\n        self.main_window.setLayout(main_layout)\n\n        # Panel izquierdo (más compacto)\n        left_panel = QWidget()\n        left_layout = QVBoxLayout()\n        left_layout.setContentsMargins(10, 20, 10, 20)\n        left_layout.setSpacing(5)\n        left_panel.setLayout(left_layout)\n        left_panel.setFixedWidth(250)  # Más estrecho\n        left_panel.setStyleSheet(\"\"\"\n            QWidget {\n                background-color: #192734;\n                border-right: 1px solid #38444d;\n            }\n        \"\"\")\n\n        # Logo más compacto\n        logo_label = QLabel(\"🦋\")\n        logo_label.setStyleSheet(\"\"\"\n            font-size: 32px;\n            color: #1da1f2;\n            padding: 10px;\n        \"\"\")\n        left_layout.addWidget(logo_label)\n\n        # Botones de navegación más compactos\n        nav_buttons = [\n            (\"🏠 Inicio\", lambda: self.update_feed('all_posts')),  # Cambiado a all_posts\n            (\"👤 Perfil\", lambda: self.update_feed('my_posts')),\n            (\"🔍 Explorar\", lambda: None),\n        ]\n        \n        for text, callback in nav_buttons:\n            btn = QPushButton(text)\n            btn.setStyleSheet(\"\"\"\n                QPushButton {\n                    background-color: transparent;\n                    color: white;\n                    text-align: left;\n                    padding: 12px 15px;\n                    font-size: 15px;\n                    border-radius: 15px;\n                    margin: 2px 0px;\n                }\n                QPushButton:hover {\n                    background-color: #253341;\n                }\n            \"\"\")\n            btn.clicked.connect(callback)\n            left_layout.addWidget(btn)\n\n        left_layout.addStretch()\n\n        # Panel central (más ancho)\n        center_panel = QWidget()\n        center_layout = QVBoxLayout()\n        center_layout.setContentsMargins(10, 10, 10, 10)\n        center_layout.setSpacing(10)\n        center_panel.setLayout(center_layout)\n        center_panel.setStyleSheet(\"\"\"\n            QWidget {\n                background-color: #15202b;\n            }\n        \"\"\")\n\n        # Área de crear post más compacta\n        post_widget = QWidget()\n        post_widget.setObjectName(\"post_widget\")\n        post_layout = QVBoxLayout()\n        post_layout.setContentsMargins(15, 15, 15, 15)\n        post_layout.setSpacing(10)\n        post_widget.setLayout(post_layout)\n        \n        self.post_input = QTextEdit()\n        self.post_input.setPlaceholderText('¿Qué está pasando?')\n        self.post_input.setStyleSheet(\"\"\"\n            QTextEdit {\n                background-color: #253341;\n                border: none;\n                color: white;\n                font-size: 15px;\n                padding: 10px;\n                border-radius: 15px;\n            }\n        \"\"\")\n        self.post_input.setFixedHeight(80)  # Más compacto\n        \n        post_btn = QPushButton('Publicar')\n        post_btn.setStyleSheet(\"\"\"\n            QPushButton {\n                background-color: #1da1f2;\n                color: white;\n                border-radius: 15px;\n                padding: 8px 15px;\n                font-size: 13px;\n                font-weight: bold;\n            }\n            QPushButton:hover {\n                background-color: #1991db;\n            }\n        \"\"\")\n        post_btn.setFixedWidth(80)\n        post_btn.clicked.connect(self.create_post)\n        \n        post_layout.addWidget(self.post_input)\n        post_layout.addWidget(post_btn, alignment=Qt.AlignmentFlag.AlignRight)\n        center_layout.addWidget(post_widget)\n\n        # Feed mejorado\n        scroll = QScrollArea()\n        scroll.setWidgetResizable(True)\n        scroll.setStyleSheet(\"\"\"\n            QScrollArea {\n                border: none;\n                background-color: transparent;\n            }\n            QScrollBar:vertical {\n                background-color: #192734;\n                width: 8px;\n                margin: 0px;\n            }\n            QScrollBar::handle:vertical {\n                background-color: #38444d;\n                min-height: 30px;\n                border-radius: 4px;\n            }\n            QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical {\n                height: 0px;\n            }\n        \"\"\")\n        \n        self.feed_widget = QWidget()\n        self.feed_layout = QVBoxLayout()\n        self.feed_layout.setContentsMargins(0, 0, 0, 0)\n        self.feed_layout.setSpacing(5)  # Menos espacio entre posts\n        self.feed_widget.setLayout(self.feed_layout)\n        scroll.setWidget(self.feed_widget)\n        center_layout.addWidget(scroll)\n\n        # Panel derecho (20% del ancho)\n        right_panel = QWidget()\n        right_layout = QVBoxLayout()\n        right_layout.setContentsMargins(20, 20, 20, 20)\n        right_layout.setSpacing(10)\n        right_panel.setLayout(right_layout)\n        right_panel.setMinimumWidth(280)\n        right_panel.setMaximumWidth(350)\n        right_panel.setStyleSheet(\"\"\"\n            QWidget {\n                background-color: #192734;\n            }\n        \"\"\")\n\n        # Área de seguir usuarios\n        follow_widget = QWidget()\n        follow_widget.setObjectName(\"follow_widget\")\n        follow_layout = QVBoxLayout()\n        follow_layout.setContentsMargins(15, 15, 15, 15)\n        follow_layout.setSpacing(10)\n        follow_widget.setLayout(follow_layout)\n        \n        follow_title = QLabel(\"A quién seguir\")\n        follow_title.setStyleSheet(\"\"\"\n            font-size: 18px;\n            font-weight: bold;\n            color: white;\n            padding: 5px 0px;\n        \"\"\")\n        \n        self.user_combo = QComboBox()\n        self.user_combo.setStyleSheet(\"\"\"\n            QComboBox {\n                background-color: #253341;\n                color: white;\n                border: 1px solid #38444d;\n                border-radius: 15px;\n                padding: 8px;\n                min-height: 35px;\n            }\n            QComboBox::drop-down {\n                border: none;\n            }\n            QComboBox::down-arrow {\n                image: none;\n            }\n        \"\"\")\n        \n        follow_btn = QPushButton('Seguir/Dejar de seguir')\n        follow_btn.setStyleSheet(\"\"\"\n            QPushButton {\n                background-color: #1da1f2;\n                color: white;\n                border-radius: 20px;\n                padding: 10px;\n                font-weight: bold;\n            }\n            QPushButton:hover {\n                background-color: #1991db;\n            }\n        \"\"\")\n        follow_btn.clicked.connect(self.toggle_follow)\n        \n        follow_layout.addWidget(follow_title)\n        follow_layout.addWidget(self.user_combo)\n        follow_layout.addWidget(follow_btn)\n        right_layout.addWidget(follow_widget)\n        right_layout.addStretch()\n\n        # Ajustar proporciones de los paneles\n        main_layout.addWidget(left_panel)\n        main_layout.addWidget(center_panel, 4)  # Dar más espacio al centro\n        main_layout.addWidget(right_panel)\n\n        # Establecer estilos globales\n        self.setStyleSheet(\"\"\"\n            QMainWindow, QWidget {\n                background-color: #15202b;\n            }\n            QLabel {\n                color: #ffffff;\n            }\n            QTextEdit, QLineEdit, QComboBox {\n                background-color: #253341;\n                color: #ffffff;\n                border: 1px solid #38444d;\n                border-radius: 15px;\n                padding: 8px;\n            }\n            QWidget#post_widget, QWidget#follow_widget {\n                background-color: #253341;\n                border-radius: 15px;\n                padding: 15px;\n                margin: 10px;\n            }\n        \"\"\")\n\n    def create_post(self):\n        if not self.current_user:\n            self.show_error(\"Debes iniciar sesión primero\")\n            return\n        \n        text = self.post_input.toPlainText()\n        if len(text) > 200:\n            self.show_error(\"El post no puede exceder los 200 caracteres\")\n            return\n        \n        if not text:\n            self.show_error(\"El post no puede estar vacío\")\n            return\n        \n        new_post = Post(text, datetime.now().strftime(\"%Y-%m-%d %H:%M:%S\"), len(self.posts) + 1)\n        new_post.user = self.current_user  # Asignar el usuario al post\n        self.posts.append(new_post)\n        self.post_input.clear()\n        self.update_feed()\n        self.show_message(\"Post creado exitosamente\")\n\n    def update_feed(self, feed_type='all_posts'):\n        # Limpiar feed actual\n        for i in reversed(range(self.feed_layout.count())): \n            widget = self.feed_layout.itemAt(i).widget()\n            if widget:\n                widget.setParent(None)\n        \n        if not self.current_user:\n            return\n\n        # Obtener posts según el tipo de feed\n        if feed_type == 'my_posts':\n            relevant_posts = [(p, p.user) for p in self.posts if p.user == self.current_user]\n        elif feed_type == 'all_posts':\n            # Mostrar posts propios y de usuarios seguidos\n            relevant_posts = [(p, p.user) for p in self.posts \n                            if p.user == self.current_user or p.user in self.current_user.following]\n        else:\n            relevant_posts = [(p, p.user) for p in self.posts]\n\n        # Ordenar por fecha\n        sorted_posts = sorted(relevant_posts, key=lambda x: x[0].date, reverse=True)\n        \n        # Mostrar los posts\n        for post, user in sorted_posts[:10]:\n            post_widget = self.create_post_widget(post, user)\n            self.feed_layout.addWidget(post_widget)\n\n    def show_main_window(self):\n        self.stacked_widget.setCurrentIndex(1)\n        self.update_user_combo()\n        self.update_feed()\n\n    def show_error(self, message):\n        QMessageBox.critical(self, \"Error\", message)\n\n    def show_message(self, message):\n        QMessageBox.information(self, \"Información\", message)\n\n    def update_user_combo(self):\n        self.user_combo.clear()\n        for username in self.users.keys():\n            if username != self.current_user.username:\n                self.user_combo.addItem(username)\n\n    def toggle_follow(self):\n        if not self.current_user:\n            self.show_error(\"Debes iniciar sesión primero\")\n            return\n        \n        selected_username = self.user_combo.currentText()\n        if not selected_username:\n            self.show_error(\"Selecciona un usuario para seguir\")\n            return\n            \n        if selected_username == self.current_user.username:\n            self.show_error(\"No puedes seguirte a ti mismo\")\n            return\n        \n        target_user = self.users[selected_username]\n        \n        if target_user in self.current_user.following:\n            self.current_user.unfollow(target_user)\n            self.show_message(f\"Has dejado de seguir a {selected_username}\")\n        else:\n            self.current_user.follow(target_user)\n            self.show_message(f\"Ahora sigues a {selected_username}\")\n        \n        self.update_feed()\n\n    def create_post_widget(self, post, user):\n        post_widget = QWidget()\n        post_widget.setStyleSheet(\"\"\"\n            QWidget {\n                background-color: #1a2634;\n                border: 1px solid #2f3336;\n                border-radius: 0px;\n                margin: 1px 0px;\n            }\n            QWidget:hover {\n                background-color: #1e2732;\n            }\n            QLabel {\n                color: #ffffff;\n                background: transparent;\n            }\n            QPushButton {\n                background-color: transparent;\n                border: none;\n                padding: 5px;\n                border-radius: 4px;\n            }\n            QPushButton:hover {\n                background-color: rgba(29, 161, 242, 0.1);\n            }\n        \"\"\")\n        \n        main_layout = QVBoxLayout()\n        main_layout.setContentsMargins(16, 12, 16, 12)\n        main_layout.setSpacing(4)\n        \n        # Header\n        header = QHBoxLayout()\n        header.setSpacing(10)\n        \n        # Avatar\n        avatar = QLabel(\"👤\")\n        avatar.setStyleSheet(\"\"\"\n            font-size: 20px;\n            background-color: #253341;\n            border-radius: 15px;\n            padding: 5px;\n            min-width: 20px;\n            min-height: 20px;\n        \"\"\")\n        \n        # Info del usuario y fecha en la misma línea\n        user_info = QHBoxLayout()\n        user_info.setSpacing(8)\n        \n        name = QLabel(user.username)\n        name.setStyleSheet(\"font-weight: bold; font-size: 15px;\")\n        \n        handle = QLabel(f\"@{user.username}\")\n        handle.setStyleSheet(\"color: #71767b; font-size: 14px;\")\n        \n        dot = QLabel(\"·\")\n        dot.setStyleSheet(\"color: #71767b; font-size: 14px; margin: 0px 4px;\")\n        \n        date = QLabel(post.date)\n        date.setStyleSheet(\"color: #71767b; font-size: 14px;\")\n        \n        user_info.addWidget(name)\n        user_info.addWidget(handle)\n        user_info.addWidget(dot)\n        user_info.addWidget(date)\n        user_info.addStretch()\n        \n        header.addWidget(avatar)\n        header.addLayout(user_info)\n        \n        # Contenido del post\n        content = QLabel(post.text)\n        content.setWordWrap(True)\n        content.setStyleSheet(\"\"\"\n            font-size: 15px;\n            color: #e7e9ea;\n            padding: 0px;\n            margin-left: 35px;\n            line-height: 1.3;\n        \"\"\")\n        \n        # Acciones\n        actions = QHBoxLayout()\n        actions.setContentsMargins(35, 0, 0, 0)\n        actions.setSpacing(0)\n        \n        # Like con contador\n        like_container = QWidget()\n        like_layout = QHBoxLayout(like_container)\n        like_layout.setSpacing(4)\n        like_layout.setContentsMargins(0, 0, 0, 0)\n        \n        like_btn = QPushButton('❤️' if self.current_user not in post.likes else '💖')\n        like_btn.setStyleSheet(\"\"\"\n            QPushButton {\n                font-size: 16px;\n                padding: 5px 8px;\n                margin: 0;\n            }\n            QPushButton:hover {\n                background-color: rgba(249, 24, 128, 0.1);\n            }\n        \"\"\")\n        like_btn.clicked.connect(lambda: self.toggle_like(post, like_btn))\n        \n        likes = QLabel(str(len(post.likes)))\n        likes.setStyleSheet(\"color: #71767b; font-size: 13px;\")\n        \n        like_layout.addWidget(like_btn)\n        like_layout.addWidget(likes)\n        \n        actions.addWidget(like_container)\n        \n        # Delete (si es el autor)\n        if user == self.current_user:\n            delete_container = QWidget()\n            delete_layout = QHBoxLayout(delete_container)\n            delete_layout.setSpacing(4)\n            delete_layout.setContentsMargins(0, 0, 0, 0)\n            \n            delete_btn = QPushButton('🗑️')\n            delete_btn.setStyleSheet(\"\"\"\n                QPushButton {\n                    font-size: 16px;\n                    padding: 5px 8px;\n                    margin: 0;\n                }\n                QPushButton:hover {\n                    background-color: rgba(244, 33, 46, 0.1);\n                }\n            \"\"\")\n            delete_btn.clicked.connect(lambda: self.delete_post(post))\n            delete_layout.addWidget(delete_btn)\n            \n            actions.addWidget(delete_container)\n        \n        actions.addStretch()\n        \n        # Agregar todo al layout principal\n        main_layout.addLayout(header)\n        main_layout.addWidget(content)\n        main_layout.addLayout(actions)\n        \n        post_widget.setLayout(main_layout)\n        return post_widget\n\n    def toggle_like(self, post, like_btn):\n        if not self.current_user:\n            self.show_error(\"Debes iniciar sesión primero\")\n            return\n        \n        if self.current_user in post.likes:\n            post.likes.remove(self.current_user)\n            like_btn.setText('❤️')\n        else:\n            post.likes.append(self.current_user)\n            like_btn.setText('💖')\n        \n        self.update_feed()\n\n    def delete_post(self, post):\n        if post in self.posts:\n            self.posts.remove(post)\n            self.update_feed()\n            self.show_message(\"Post eliminado exitosamente\")\n\nclass User:\n    def __init__(self, username: str, id: int):\n        self.username = username\n        self.id = id\n        self.followers = []\n        self.following = []\n        self.likes = []\n\n    def follow(self, user):\n        if user not in self.following:\n            self.following.append(user)\n            user.followers.append(self)\n\n    def unfollow(self, user):\n        if user in self.following:\n            self.following.remove(user)\n            user.followers.remove(self)\n\nclass Post:\n    def __init__(self, text: str, date: str, id: int):\n        self.text = text\n        self.date = date\n        self.id = id\n        self.likes = []\n        self.user = None  # Agregar referencia al usuario que creó el post\n\nif __name__ == '__main__':\n    app = QApplication(sys.argv)\n    ex = SocialNetworkGUI()\n    ex.show()\n    sys.exit(app.exec())\n    \n"
  },
  {
    "path": "Roadmap/46 - X VS BLUESKY/python/mhayhem.py",
    "content": "# @Author Daniel Grande (Mhayhem)\n\n# EJERCICIO:\n# La alternativa descentralizada a X, Bluesky, comienza a atraer\n# a nuevos usuarios. ¿Cómo funciona una red de este estilo?\n# \n# Implementa un sistema que simule el comportamiento de estas\n# redes sociales.\n# \n# Debes crear las siguientes operaciones:\n# - Registrar un usuario por nombre e identificador único.\n# - Un usuario puede seguir/dejar de seguir a otro.\n# - Creación de post asociado a un usuario. Debe poseer\n#   texto (200 caracteres máximo), fecha de creación \n#   e identificador único.   \n# - Eliminación de un post.\n# - Posibilidad de hacer like (y eliminarlo) en un post.\n# - Visualización del feed de un usuario con sus 10 publicaciones\n#   más actuales ordenadas desde la más reciente.\n# - Visualización del feed de un usuario con las 10 publicaciones\n#   más actuales de los usuarios que sigue ordenadas \n#   desde la más reciente.\n#   \n# Cuando se visualiza un post, debe mostrarse:\n# ID de usuario, nombre de usuario, texto del post, \n# fecha de creación y número total de likes.\n# \n# Controla errores en duplicados o acciones no permitidas.\n\nimport datetime\n\nclass User:\n    def __init__(self, nickname: str, password: str, id: int):\n        self.nickname = nickname\n        self.password = password\n        self.id = id\n        self.followings = set()\n        self.posts = []\n        self.post_id = 0\n    \n    def following(self, user: object):\n        self.followings.add(user)\n    \n    def unfollowing(self, user: object):\n        self.followings.remove(user)\n    \n    def display_followings(self):\n        for person in self.followings:\n            print(f\"{person.id} {person.nickname}\")\n    \n    def choose_following(self, name: str):\n        for person in self.followings:\n            if name == person.nickname:\n                return person\n            else:\n                return None\n    \n    def add_post(self, message: str):\n        self.post_id += 1\n        post = Post(message, self.post_id, self)\n        self.posts.insert(0, post)\n    \n    def substract_post(self, post: object):\n        self.posts.remove(post)\n    \n    def display_last_ten_posts(self):\n        for post in self.posts[:10]:\n            print(post)\n    \n    def display_following_feed(self):\n        following_last_post = []\n        \n        for person in self.followings:\n            following_last_post.extend(person.posts)\n        \n        last_feed = sorted(following_last_post,\n                        key=lambda post: post.creation_date,\n                        reverse=True)[:10]\n        \n        for post in last_feed:\n            print(post.__str__())\n\nclass Post:\n    def __init__(self, message: str, id: int, user: object):\n        self.message = message\n        self.id = id\n        self.user = user\n        self.creation_date = datetime.datetime.now(datetime.UTC)\n        self.likes = 0\n        self.liked = set()\n    \n    def add_likes(self, user: object):\n        if user not in self.liked:\n            self.likes += 1\n            self.liked.add(user)\n            return True\n        else:\n            return False\n    \n    def substract_like(self, user: object):\n        if user.nickname in self.liked:\n            self.likes -= 1\n            self.liked.remove(user)\n    \n    def display_post_id(self, array: list):\n        for post in array:\n            print(f\"{post.id} - {post.message}\")\n    \n    def __str__(self):\n        return f\"{self.user.id} {self.user.nickname}\\n{self.message}\\n{self.creation_date}   ❤️{self.likes}\"\n\nclass SocialNetwork:\n    def __init__(self):\n        self.users = []\n        self.id = 0\n    \n    def create_user(self, nickname: str, password: str):\n        self.id += 1\n        user = User(nickname, password, self.id)\n        return user\n    \n    def add_user(self, user: object):\n        self.users.append(user)\n    \n    def display_last_posts(self, user: object):\n        for post in user.posts:\n            return user.__str__(), post.__str__()\n    \n    def login(self, nickname: str, password: str):\n        for user in self.users:\n            if nickname == user.nickname and password == user.password:\n                return user\n        print(\"Usuario o contraseña incorrectos\")\n        return \n\ndef main():\n    social_network = SocialNetwork()\n    while True:\n        print(f\"{'#' * 5} MySocial NetWork {'#' * 5}\")\n        print(\"1. Login.\\n\"\n            \"2. Salir\")\n        start = int(input())\n        match start:\n            case 1:\n                if social_network.users:\n                    attempts = 3\n                    while attempts > 0:\n                        nickname = input(\"Usuario: \")\n                        password = input(\"Contraseña: \")\n                        user = social_network.login(nickname, password)\n                        if not user:\n                            attempts -= 1\n                            print(f\"Intentos restantes {attempts}\")\n                        else:\n                            while True:\n                                print(\"1. Escribir post.\\n\" \n                                    \"2. Eliminar post.\\n\"\n                                    \"3. Seguir usuario.\\n\"\n                                    \"4. Dejar de seguir a usuario.\\n\"\n                                    \"5. Ver posts de usuarios seguidos.\\n\"\n                                    \"6. like a post.\\n\" \n                                    \"7. Dislike post.\\n\"\n                                    \"8. Mostrar posts propios.\\n\"\n                                    \"10. Logout.\")\n                                options = int(input())\n                                match options:\n                                    case 1:\n                                        while True:\n                                            message = input(\"Escriba el post.\")\n                                            if len(message) < 200:\n                                                user.add_post(message)\n                                                break\n                                    case 2:\n                                        for post in user.posts:\n                                            print(f\"{post.id} - {post.message}\")\n                                        id_del = int(input(\"Indiqué el número de id: \"))\n                                        for post in user.posts:\n                                            if post.id == id_del:\n                                                user.substract_post(post)\n                                                break\n                                            print(f\"El id {id_del}, no existe.\")\n                                    case 3:\n                                        print(social_network.users)\n                                        user_to_follow = input(\"Indique el usuario a seguir: \")\n                                        for nickname in social_network.users:\n                                            if nickname.nickname == user_to_follow:\n                                                user.following(nickname)\n                                    case 4:\n                                        print(user.followings)\n                                        user_to_unfollow = input(\"Indique el usuario a dejar de seguir: \")\n                                        for nickname in user.followings:\n                                            if nickname.nickname == user_to_unfollow:\n                                                user.unfollowing(nickname)\n                                    case 5:\n                                        user.display_following_feed()\n                                    case 6:\n                                        user.display_followings()\n                                        name = input(\"Indique el usuario: \")\n                                        person = user.choose_following(name)\n                                        post_id = int(input(\"Indique id del post a dear like: \"))\n                                        found = False\n                                        for post in person.posts:\n                                            if post.id == post_id:\n                                                result = post.add_likes(user)\n                                                found = True\n                                                break\n                                            \n                                        if result == None:\n                                            print(\"Ya le has dado like a este post.\")\n                                    case 7:\n                                        user.display_followings()\n                                        name = input(\"Indique el usuario: \")\n                                        person = user.choose_following(name)\n                                        post_id = int(input(\"Indique id del post a dear like: \"))\n                                        found = False\n                                        for post in person.posts:\n                                            if user.nickname in post.liked and post_id == post.id:\n                                                post.substract_like(user)\n                                                found = True\n                                                break\n                                        if not found:\n                                            print(f\"No diste like a nigún post con id {post_id}\")\n                                    case 8:\n                                        user.display_last_ten_posts()\n                                    case 9:\n                                        print(\"Saliendo de la red social.\")\n                                        break\n                                    case _:\n                                        print(\"La opción no es valida.\")\n                    print(\"se ha suoerado el número de intentos\")\n                    break\n                else:\n                    print(\"Lista de usuarios vacía, crearemos nuevo usuario\")\n                    nickname = input(\"Nombre de usuario: \")\n                    password = input(\"Crear contraseña: \")\n                    user = social_network.create_user(nickname, password)\n                    social_network.add_user(user)\n                    print(f\"Usuario {nickname} creado correctamente.\")\n            case 2:\n                print(\"Cerrando red social.\")\n                break"
  },
  {
    "path": "Roadmap/46 - X VS BLUESKY/python/miguelex.py",
    "content": "import datetime\n\nclass User:\n    def __init__(self, user_id, name):\n        self.id = user_id\n        self.name = name\n        self.following = []\n        self.posts = []\n\n    def follow(self, user):\n        if user.id in self.following:\n            print(f\"{self.name} ya sigue a {user.name}.\")\n            return\n        self.following.append(user.id)\n        print(f\"{self.name} comenzó a seguir a {user.name}.\")\n\n    def unfollow(self, user):\n        if user.id not in self.following:\n            print(f\"{self.name} no sigue a {user.name}.\")\n            return\n        self.following.remove(user.id)\n        print(f\"{self.name} dejó de seguir a {user.name}.\")\n\nclass Post:\n    def __init__(self, post_id, text, user_id):\n        self.id = post_id\n        self.text = text[:200]\n        self.user_id = user_id\n        self.created_at = datetime.datetime.now()\n        self.likes = 0\n\n    def like(self):\n        self.likes += 1\n\n    def unlike(self):\n        if self.likes > 0:\n            self.likes -= 1\n\nclass SocialNetwork:\n    def __init__(self):\n        self.users = {}\n        self.posts = {}\n\n    def register_user(self, user_id, name):\n        if user_id in self.users:\n            print(f\"El usuario con ID {user_id} ya existe.\")\n            return\n        self.users[user_id] = User(user_id, name)\n        print(f\"Usuario {name} registrado con éxito.\")\n\n    def create_post(self, user_id, text):\n        if user_id not in self.users:\n            print(f\"El usuario con ID {user_id} no existe.\")\n            return\n        post_id = f\"post_{len(self.posts) + 1}\"\n        post = Post(post_id, text, user_id)\n        self.posts[post_id] = post\n        self.users[user_id].posts.append(post)\n        print(\"Post creado con éxito.\")\n\n    def delete_post(self, post_id):\n        if post_id not in self.posts:\n            print(f\"El post con ID {post_id} no existe.\")\n            return\n        post = self.posts[post_id]\n        self.users[post.user_id].posts = [p for p in self.users[post.user_id].posts if p.id != post_id]\n        del self.posts[post_id]\n        print(\"Post eliminado con éxito.\")\n\n    def like_post(self, post_id):\n        if post_id not in self.posts:\n            print(f\"El post con ID {post_id} no existe.\")\n            return\n        self.posts[post_id].like()\n        print(f\"Post {post_id} recibió un like.\")\n\n    def unlike_post(self, post_id):\n        if post_id not in self.posts:\n            print(f\"El post con ID {post_id} no existe.\")\n            return\n        self.posts[post_id].unlike()\n        print(f\"Like eliminado del post {post_id}.\")\n\n    def view_feed(self, user_id):\n        if user_id not in self.users:\n            print(f\"El usuario con ID {user_id} no existe.\")\n            return\n        posts = sorted(self.users[user_id].posts, key=lambda p: p.created_at, reverse=True)\n        print(f\"Feed de {self.users[user_id].name}:\")\n        for post in posts[:10]:\n            self.display_post(post)\n\n    def view_followed_feed(self, user_id):\n        if user_id not in self.users:\n            print(f\"El usuario con ID {user_id} no existe.\")\n            return\n        followed_posts = []\n        for followed_id in self.users[user_id].following:\n            if followed_id in self.users:\n                followed_posts.extend(self.users[followed_id].posts)\n        followed_posts = sorted(followed_posts, key=lambda p: p.created_at, reverse=True)\n        print(f\"Feed de usuarios seguidos por {self.users[user_id].name}:\")\n        for post in followed_posts[:10]:\n            self.display_post(post)\n\n    def display_post(self, post):\n        print(f\"ID: {post.id}, Usuario: {post.user_id}, Texto: {post.text}, Fecha: {post.created_at}, Likes: {post.likes}\")\n\n    def interactive_menu(self):\n        while True:\n            print(\"\\n--- Menú Principal ---\")\n            print(\"1. Registrar usuario\")\n            print(\"2. Crear post\")\n            print(\"3. Eliminar post\")\n            print(\"4. Dar like a un post\")\n            print(\"5. Quitar like de un post\")\n            print(\"6. Ver feed del usuario\")\n            print(\"7. Ver feed de usuarios seguidos\")\n            print(\"8. Seguir a un usuario\")\n            print(\"9. Dejar de seguir a un usuario\")\n            print(\"10. Salir\")\n            option = input(\"Seleccione una opción: \")\n            if option == \"1\":\n                user_id = input(\"Ingrese ID del usuario: \")\n                name = input(\"Ingrese nombre del usuario: \")\n                self.register_user(user_id, name)\n            elif option == \"2\":\n                user_id = input(\"Ingrese ID del usuario: \")\n                text = input(\"Ingrese texto del post: \")\n                self.create_post(user_id, text)\n            elif option == \"3\":\n                post_id = input(\"Ingrese ID del post: \")\n                self.delete_post(post_id)\n            elif option == \"4\":\n                post_id = input(\"Ingrese ID del post: \")\n                self.like_post(post_id)\n            elif option == \"5\":\n                post_id = input(\"Ingrese ID del post: \")\n                self.unlike_post(post_id)\n            elif option == \"6\":\n                user_id = input(\"Ingrese ID del usuario: \")\n                self.view_feed(user_id)\n            elif option == \"7\":\n                user_id = input(\"Ingrese ID del usuario: \")\n                self.view_followed_feed(user_id)\n            elif option == \"8\":\n                follower_id = input(\"Ingrese tu ID: \")\n                follow_id = input(\"Ingrese ID del usuario a seguir: \")\n                if follower_id in self.users and follow_id in self.users:\n                    self.users[follower_id].follow(self.users[follow_id])\n                else:\n                    print(\"Usuario no encontrado.\")\n            elif option == \"9\":\n                unfollower_id = input(\"Ingrese tu ID: \")\n                unfollow_id = input(\"Ingrese ID del usuario a dejar de seguir: \")\n                if unfollower_id in self.users and unfollow_id in self.users:\n                    self.users[unfollower_id].unfollow(self.users[unfollow_id])\n                else:\n                    print(\"Usuario no encontrado.\")\n            elif option == \"10\":\n                print(\"Saliendo...\")\n                break\n            else:\n                print(\"Opción no válida.\")\n\nif __name__ == \"__main__\":\n    network = SocialNetwork()\n    network.interactive_menu()\n"
  },
  {
    "path": "Roadmap/46 - X VS BLUESKY/python/mouredev.py",
    "content": "from datetime import datetime\n\n\nclass SocialNetwork:\n\n    def __init__(self):\n        self.post_id = 0\n        self.users = {}\n        self.post = {}\n\n    def register_user(self, user_id: str, name: str):\n\n        if user_id in self.users:\n            print(f\"El usuario con el ID {user_id} ya existe.\")\n            return\n\n        self.users[user_id] = {\n            \"name\": name,\n            \"following\": set(),\n            \"followers\": set(),\n            \"post\": []\n        }\n        print(\n            f\"Usuario con ID '{user_id}' y nombre '{\n                name}' registrado correctamente.\"\n        )\n\n    def follow_user(self, user_id: str, follow_id: str):\n\n        if user_id not in self.users or follow_id not in self.users:\n            print(\"Alguno de los usuarios no existe. No se puede realizar el follow.\")\n            return\n\n        self.users[user_id][\"following\"].add(follow_id)\n        self.users[follow_id][\"followers\"].add(user_id)\n        print(\n            f\"{self.users[user_id][\"name\"]} ahora sigue a {\n                self.users[follow_id][\"name\"]}.\"\n        )\n\n    def unfollow_user(self, user_id: str, unfollow_id: str):\n\n        if user_id not in self.users or unfollow_id not in self.users:\n            print(\"Alguno de los usuarios no existe. No se puede realizar el unfollow.\")\n            return\n\n        self.users[user_id][\"following\"].discard(unfollow_id)\n        self.users[unfollow_id][\"followers\"].discard(user_id)\n        print(\n            f\"{self.users[user_id][\"name\"]} ha dejado de seguir a {\n                self.users[unfollow_id][\"name\"]}.\"\n        )\n\n    def create_post(self, user_id: str, text: str):\n\n        if user_id not in self.users:\n            print(f\"El usuario '{user_id}' no existe.\")\n            return\n\n        if len(text) > 200:\n            print(\"El post no puede tener más de 200 caracteres.\")\n            return\n\n        self.post_id += 1\n\n        post_id = self.post_id\n\n        self.post[post_id] = {\n            \"user_id\": user_id,\n            \"text\": text,\n            \"created_at\": datetime.now(),\n            \"likes\": set()\n        }\n\n        self.users[user_id][\"post\"].append(post_id)\n\n        print(\"Post creado correctamente.\")\n\n    def delete_post(self, post_id: int):\n\n        if post_id not in self.post:\n            print(f\"El post con ID {post_id} no existe.\")\n            return\n\n        user_id = self.post[post_id][\"user_id\"]\n        self.users[user_id][\"post\"].remove(post_id)\n        del self.post[post_id]\n        print(\"Post eliminado correctamente.\")\n\n    def like_post(self, user_id: str, post_id: int):\n\n        if user_id not in self.users:\n            print(f\"El usuario '{user_id}' no existe.\")\n            return\n\n        if post_id not in self.post:\n            print(f\"El post '{post_id}' no existe.\")\n            return\n\n        self.post[post_id][\"likes\"].add(user_id)\n        print(f\"Nuevo like en post '{post_id}'.\")\n\n    def unlike_post(self, user_id: str, post_id: int):\n\n        if user_id not in self.users:\n            print(f\"El usuario '{user_id}' no existe.\")\n            return\n\n        if post_id not in self.post:\n            print(f\"El post '{post_id}' no existe.\")\n            return\n\n        self.post[post_id][\"likes\"].discard(user_id)\n        print(f\"Like eliminado en post '{post_id}'.\")\n\n    def view_user_feed(self, user_id: str):\n\n        if user_id not in self.users:\n            print(f\"El usuario '{user_id}' no existe.\")\n            return\n\n        feed = sorted(\n            (self.post[post_id] for post_id in self.users[user_id][\"post\"]),\n            key=lambda x: x[\"created_at\"],\n            reverse=True\n        )[:10]\n\n        for post in feed:\n            print(f\"\"\"\nID usuario: {post[\"user_id\"]}\nUsuario: {self.users[post[\"user_id\"]][\"name\"]}\nTexto: {post[\"text\"]}\nFecha: {post[\"created_at\"]}\nLikes: {len(post[\"likes\"])}\n                    \"\"\")\n\n    def view_following_feed(self, user_id: str):\n\n        if user_id not in self.users:\n            print(f\"El usuario '{user_id}' no existe.\")\n            return\n\n        following_post_ids = []\n\n        for following_id in self.users[user_id][\"following\"]:\n            following_post_ids.extend(self.users[following_id][\"post\"])\n\n        feed = sorted(\n            (self.post[post_id] for post_id in following_post_ids),\n            key=lambda x: x[\"created_at\"],\n            reverse=True\n        )[:10]\n\n        for post in feed:\n            print(f\"\"\"\nID usuario: {post[\"user_id\"]}\nUsuario: {self.users[post[\"user_id\"]][\"name\"]}\nTexto: {post[\"text\"]}\nFecha: {post[\"created_at\"]}\nLikes: {len(post[\"likes\"])}\n                    \"\"\")\n\n\nsocial_network = SocialNetwork()\nsocial_network.register_user(\"mouredev\", \"Brais Moure\")\nsocial_network.register_user(\"manolo\", \"Manolo 87\")\n\nsocial_network.create_post(\"mouredev\", \"Hola mundo!\")\nsocial_network.create_post(\"mouredev\", \"Hola mundo 2!\")\nsocial_network.create_post(\"mouredev\", \"Hola mundo 3!\")\n\nsocial_network.create_post(\"manolo\", \"Hola mundo!\")\nsocial_network.create_post(\"manolo\", \"Hola mundo 2!\")\nsocial_network.create_post(\"manolo\", \"Hola mundo 3!\")\n\nsocial_network.follow_user(\"manolo\", \"mouredev\")\n\nsocial_network.like_post(\"manolo\", 1)\n\nsocial_network.view_user_feed(\"mouredev\")\nsocial_network.view_following_feed(\"manolo\")\n\nsocial_network.unlike_post(\"manolo\", 1)\n\nsocial_network.view_following_feed(\"manolo\")\n"
  },
  {
    "path": "Roadmap/46 - X VS BLUESKY/python/neslarra.py",
    "content": "r\"\"\"\n EJERCICIO:\n La alternativa descentralizada a X, Bluesky, comienza a atraer\n a nuevos usuarios. ¿Cómo funciona una red de este estilo?\n \n Implementa un sistema que simule el comportamiento de estas\n redes sociales.\n \n Debes crear las siguientes operaciones:\n - Registrar un usuario por nombre e identificador único.\n - Un usuario puede seguir/dejar de seguir a otro.\n - Creación de post asociado a un usuario. Debe poseer\n   texto (200 caracteres máximo), fecha de creación \n   e identificador único.   \n - Eliminación de un post.\n - Posibilidad de hacer like (y eliminarlo) en un post.\n - Visualización del feed de un usuario con sus 10 publicaciones\n   más actuales ordenadas desde la más reciente.\n - Visualización del feed de un usuario con las 10 publicaciones\n   más actuales de los usuarios que sigue ordenadas \n   desde la más reciente.\n   \n Cuando se visualiza un post, debe mostrarse:\n ID de usuario, nombre de usuario, texto del post, \n fecha de creación y número total de likes.\n \n Controla errores en duplicados o acciones no permitidas.\n\"\"\"\nfrom datetime import datetime as dt, timedelta as td\nfrom random import randint as rndi\nfrom time import sleep\n\nusers = [\n    {\"userid\": 1, \"username\": \"neslarra\", \"following\": [1, 2, 3, 4]},\n    {\"userid\": 2, \"username\": \"toribio\", \"following\": [2, 6]},\n    {\"userid\": 3, \"username\": \"pepapig\", \"following\": [3, 1, 2, 4, 5]},\n    {\"userid\": 4, \"username\": \"sandmanteo\", \"following\": [4, 3]},\n    {\"userid\": 5, \"username\": \"eltartufo\", \"following\": [5, 3, 1, 2]},\n    {\"userid\": 6, \"username\": \"gorilin\", \"following\": [6, 2, 4]}\n]\nposts = [\n    {\"postid\": 1, \"userid\": 1, \"post\": \"Hoy es un buen día para empezar de nuevo\", \"time\": dt.now() - td(days=rndi(1, 7), hours=rndi(1, 24), minutes=rndi(1, 60), seconds=rndi(1, 60)), \"likedby\": [3]},\n    {\"postid\": 2, \"userid\": 1, \"post\": \"La clave del éxito está en la persistencia.\", \"time\": dt.now() - td(days=rndi(1, 7), hours=rndi(1, 24), minutes=rndi(1, 60), seconds=rndi(1, 60)), \"likedby\": [3, 5]},\n    {\"postid\": 3, \"userid\": 2, \"post\": \"Haz que cada momento cuente.\", \"time\": dt.now() - td(days=rndi(1, 7), hours=rndi(1, 24), minutes=rndi(1, 60), seconds=rndi(1, 60)), \"likedby\": [1, 3, 5, 6]},\n    {\"postid\": 4, \"userid\": 3, \"post\": \"Menos perfección, más autenticidad.\", \"time\": dt.now() - td(days=rndi(1, 7), hours=rndi(1, 24), minutes=rndi(1, 60), seconds=rndi(1, 60)), \"likedby\": []},\n    {\"postid\": 5, \"userid\": 3, \"post\": \"El futuro es creado por lo que haces hoy\", \"time\": dt.now() - td(days=rndi(1, 7), hours=rndi(1, 24), minutes=rndi(1, 60), seconds=rndi(1, 60)), \"likedby\": []},\n    {\"postid\": 6, \"userid\": 2, \"post\": \"La actitud positiva es la clave de todo.\", \"time\": dt.now() - td(days=rndi(1, 7), hours=rndi(1, 24), minutes=rndi(1, 60), seconds=rndi(1, 60)), \"likedby\": []},\n    {\"postid\": 7, \"userid\": 3, \"post\": \"A veces, los pequeños pasos nos llevan lejos.\", \"time\": dt.now() - td(days=rndi(1, 7), hours=rndi(1, 24), minutes=rndi(1, 60), seconds=rndi(1, 60)), \"likedby\": [1, 5]},\n    {\"postid\": 8, \"userid\": 4, \"post\": \"La vida es un reflejo de tus pensamientos.\", \"time\": dt.now() - td(days=rndi(1, 7), hours=rndi(1, 24), minutes=rndi(1, 60), seconds=rndi(1, 60)), \"likedby\": []},\n    {\"postid\": 9, \"userid\": 3, \"post\": \"No se trata de esperar, se trata de crear.\", \"time\": dt.now() - td(days=rndi(1, 7), hours=rndi(1, 24), minutes=rndi(1, 60), seconds=rndi(1, 60)), \"likedby\": []},\n    {\"postid\": 10, \"userid\": 4, \"post\": \"Lo importante no es lo que haces, sino cómo lo haces.\", \"time\": dt.now() - td(days=rndi(1, 7), hours=rndi(1, 24), minutes=rndi(1, 60), seconds=rndi(1, 60)), \"likedby\": []},\n    {\"postid\": 11, \"userid\": 5, \"post\": \"El cambio comienza desde adentro.\", \"time\": dt.now() - td(days=rndi(1, 7), hours=rndi(1, 24), minutes=rndi(1, 60), seconds=rndi(1, 60)), \"likedby\": []},\n    {\"postid\": 12, \"userid\": 6, \"post\": \"Sueña en grande, actúa más grande.\", \"time\": dt.now() - td(days=rndi(1, 7), hours=rndi(1, 24), minutes=rndi(1, 60), seconds=rndi(1, 60)), \"likedby\": []},\n    {\"postid\": 13, \"userid\": 5, \"post\": \"Si no arriesgas, nunca sabrás lo que podrías lograr.\", \"time\": dt.now() - td(days=rndi(1, 7), hours=rndi(1, 24), minutes=rndi(1, 60), seconds=rndi(1, 60)), \"likedby\": []},\n    {\"postid\": 14, \"userid\": 4, \"post\": \"La vida no se mide en respiraciones, sino en momentos\", \"time\": dt.now() - td(days=rndi(1, 7), hours=rndi(1, 24), minutes=rndi(1, 60), seconds=rndi(1, 60)), \"likedby\": [6]},\n    {\"postid\": 15, \"userid\": 5, \"post\": \"Lo único imposible es lo que no intentas.\", \"time\": dt.now() - td(days=rndi(1, 7), hours=rndi(1, 24), minutes=rndi(1, 60), seconds=rndi(1, 60)), \"likedby\": []},\n    {\"postid\": 16, \"userid\": 5, \"post\": \"Hoy es un buen día para aprender algo nuevo.\", \"time\": dt.now() - td(days=rndi(1, 7), hours=rndi(1, 24), minutes=rndi(1, 60), seconds=rndi(1, 60)), \"likedby\": [3]},\n    {\"postid\": 17, \"userid\": 5, \"post\": \"La felicidad es una elección, no un destino.\", \"time\": dt.now() - td(days=rndi(1, 7), hours=rndi(1, 24), minutes=rndi(1, 60), seconds=rndi(1, 60)), \"likedby\": []},\n    {\"postid\": 18, \"userid\": 1, \"post\": \"Cada error es una lección disfrazada.\", \"time\": dt.now() - td(days=rndi(1, 7), hours=rndi(1, 24), minutes=rndi(1, 60), seconds=rndi(1, 60)), \"likedby\": []},\n    {\"postid\": 19, \"userid\": 1, \"post\": \"Todo lo que necesitas está dentro de ti.\", \"time\": dt.now() - td(days=rndi(1, 7), hours=rndi(1, 24), minutes=rndi(1, 60), seconds=rndi(1, 60)), \"likedby\": []},\n    {\"postid\": 20, \"userid\": 1, \"post\": \"El éxito no es el final, es el camino.\", \"time\": dt.now() - td(days=rndi(1, 7), hours=rndi(1, 24), minutes=rndi(1, 60), seconds=rndi(1, 60)), \"likedby\": []},\n    {\"postid\": 21, \"userid\": 6, \"post\": \"Cambia tus pensamientos y cambiarás tu vida.\", \"time\": dt.now() - td(days=rndi(1, 7), hours=rndi(1, 24), minutes=rndi(1, 60), seconds=rndi(1, 60)), \"likedby\": [2]}\n]\ncurrent_user = \"\"\n\n\ndef login(username: str = \"\") -> bool:\n    global current_user\n    username = input(\"LOGIN: Ingrese nombre ed usuario: \").lower() if not username else username\n    if not (username and username in [x[\"username\"] for x in users]):\n        return False\n    current_user = username\n    return True\n\n\ndef sign_up_user() -> bool:\n    global users\n    username = input(\"REGISTRACIÓN: Ingrese nombre ed usuario: \").lower()\n    if not username or username in [x[\"username\"] for x in users]:\n        return False\n    userid = users.__len__() + 1\n    users.append({\"userid\": userid, \"username\": username, \"following\": [userid]})\n    return True if login(username) else False\n\n\ndef add_post(post: str) -> None:\n    global posts\n    userid = [x[\"userid\"] for x in users if x[\"username\"] == current_user][0]\n    posts.append({\"postid\": posts.__len__() + 1, \"userid\": userid, \"post\": post, \"time\": dt.now()})\n    print(\"Nuevo post agregado\")\n    sleep(1)\n    show_posts()\n\n\ndef show_posts() -> None:\n    followed = [x[\"following\"] for x in users if x[\"username\"] == current_user][0]\n    for followed_user in followed:\n        available_posts = [x for x in posts if x[\"userid\"] == followed_user]\n        available_posts = sorted(available_posts, key=lambda x: x[\"time\"], reverse=True)\n        print(f\"{'-' * 100}\")\n        for post in available_posts[0:10]:\n            username = [x[\"username\"] for x in users if x[\"userid\"] == post[\"userid\"]][0]\n            my_id = [user[\"userid\"] for user in users if user[\"username\"] == current_user][0]\n            liked = \"TE GUSTÓ\" if my_id in post['likedby'] else \"(es tuyo)\" if username == current_user else \"¿Te gusta?\"\n            print(f\"{post['time'].strftime('%d-%b-%Y %H:%M:%S')} {username}: {post['post']}\")\n            print(f\"\\tpostId: {post['postid']} likes: {post['likedby'].__len__()} => {liked}\")\n\n\ndef remove_post():\n    my_id = [user[\"userid\"] for user in users if user[\"username\"] == current_user][0]\n    print(\"\\nIndique el número de post a eliminar: \")\n    while True:\n        remove_postid = input(\"PostId (0 para cancelar): \")\n        if remove_postid.isalnum():\n            remove_postid = int(remove_postid)\n            break\n    if remove_postid > 0:\n        post_index = -1\n        for index, post in enumerate(posts):\n            if post[\"postid\"] == remove_postid and post[\"userid\"] == my_id:\n                post_index = index\n                break\n        if post_index > -1:\n            post_ = posts.pop(post_index)\n            print(f\"Post {post_['postid']} eliminado.\")\n            sleep(1)\n            show_posts()\n        else:\n            print(f\"Post {remove_postid} NO Encontrado (SOLO podés eliminar tus propios posteos).\")\n\n\ndef menu() -> int:\n    print(f\"\\nBienvenido {current_user}\")\n    print(\"\\n\\t1- Cambiar de usuario\")\n    print(\"\\t2- Hacer un posteo\")\n    print(\"\\t3- Eliminar un posteo\")\n    print(\"\\t4- ver posteos\")\n    print(\"\\t5- Like/unLike un posteo\")\n    print(\"\\t6- Segir/Dejar a otro usuario\")\n    print(\"\\t0- Salir\")\n    while True:\n        option = input(\"\\n\\t Ingresa opción => \")\n        if option and option.isalnum() and 0 <= int(option) <= 6:\n            break\n    return int(option)\n\n\ndef follow():\n    my_id = [user[\"userid\"] for user in users if user[\"username\"] == current_user][0]\n    my_followings = [x[\"following\"] for x in users if x[\"username\"] == current_user][0]\n    for user in users:\n        followed = \"LO SIGO\" if user[\"userid\"] in my_followings else \"NO LO SIGO\"\n        if user[\"userid\"] != my_id:\n            print(f\"{user['userid']} {user['username']} {followed}\")\n    print(\"\\nIndicá el id de usuario a seguir (o dejar de seguir): \")\n    while True:\n        user_id = input(\"UserId (0 para cancelar): \")\n        if user_id.isalnum():\n            user_id = int(user_id)\n            break\n    if user_id > 0:\n        user_index = -1\n        for index, user in enumerate(users):\n            if user[\"userid\"] == user_id:\n                user_index = index\n                break\n        if user_index > -1 and user_id != my_id:\n            if users[user_index][\"userid\"] in my_followings:\n                my_followings.remove(users[user_index][\"userid\"])\n                new_state = f\"Dejé de seguir a {users[user_index][\"username\"]}\"\n            else:\n                my_followings.append(users[user_index][\"userid\"])\n                new_state = f\"Empecé de seguir a {users[user_index][\"username\"]}\"\n            print(f\"{new_state}\")\n            sleep(1)\n            show_posts()\n        else:\n            print(f\"Usuario no encontrado (y no te podés seguir/dejar a vos mismo).\")\n\n\ndef like():\n    my_id = [user[\"userid\"] for user in users if user[\"username\"] == current_user][0]\n    print(\"\\nIndicá el número de post que te gusta (o dejó de gustar): \")\n    while True:\n        liked_postid = input(\"PostId (0 para cancelar): \")\n        if liked_postid.isalnum():\n            liked_postid = int(liked_postid)\n            break\n    if liked_postid > 0:\n        post_index = -1\n        for index, post in enumerate(posts):\n            if post[\"postid\"] == liked_postid and post[\"userid\"] != my_id:\n                post_index = index\n                break\n        if post_index > -1:\n            if my_id in posts[post_index][\"likedby\"]:\n                posts[post_index][\"likedby\"].remove(my_id)\n                new_state = \"DEJÓ DE GUSTARME\"\n            else:\n                posts[post_index][\"likedby\"].append(my_id)\n                new_state = \"ME GUSTA\"\n            print(f\"Post {liked_postid} {new_state}.\")\n            sleep(1)\n            show_posts()\n        else:\n            print(f\"Post {liked_postid} NO Encontrado (SOLO podés 'gustar' posts de tus seguidos).\")\n\n\ndef main():\n    global current_user\n    while True:\n        if not current_user:\n            if not login():\n                if not sign_up_user():\n                    break\n        option = menu()\n        match int(option):\n            case 0:\n                quit()\n            case 1:\n                current_user = \"\"\n                login()\n            case 2:\n                post = input(\"Ingrese el mensaje a postear: \")\n                post = post if post.__len__() <= 200 else post[0:200]\n                add_post(post)\n            case 3:\n                remove_post()\n            case 4:\n                show_posts()\n            case 5:\n                like()\n            case 6:\n                follow()\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/46 - X VS BLUESKY/python/pyramsd.py",
    "content": "from datetime import datetime\nfrom collections import defaultdict\n\nclass RedSocial:\n    def __init__(self):\n        self.usuarios = {}\n        self.posts = {}\n        self.siguiendo = defaultdict(set)\n\n    def registrar_usuario(self, user_id, name):\n        if user_id in self.usuarios:\n            raise ValueError(\"ID de usuario ya existente\")\n        self.usuarios[user_id] = name\n\n    def seguir_usuario(self, follower_id, followed_id):\n        if follower_id not in self.usuarios or followed_id not in self.usuarios:\n            raise ValueError(\"ID de usuario no encontrado\")\n        if followed_id in self.siguiendo[follower_id]:\n            self.siguiendo[follower_id].remove(followed_id)\n        else:\n            self.siguiendo[follower_id].add(followed_id)\n\n    def crear_post(self, user_id, post_id, text):\n        if user_id not in self.usuarios:\n            raise ValueError(\"ID de usuario no encontrado\")\n        if post_id in self.posts:\n            raise ValueError(\"ID de post ya existente\")\n        if len(text) > 200:\n            raise ValueError(\"Execede de los 200 carácteres\")\n        self.posts[post_id] = {\n            \"user_id\": user_id,\n            \"text\": text,\n            \"created_at\": datetime.now(),\n            \"likes\": 0\n        }\n\n    def delete_post(self, post_id):\n        if post_id not in self.posts:\n            raise ValueError(\"ID de post no encontrado\")\n        del self.posts[post_id]\n\n    def dar_like(self, post_id):\n        if post_id not in self.posts:\n            raise ValueError(\"ID de post no encontrado\")\n        self.posts[post_id][\"likes\"] += 1 if self.posts[post_id][\"likes\"] == 0 else -1\n\n    def get_usuario_feed(self, user_id):\n        if user_id not in self.usuarios:\n            raise ValueError(\"ID de usuario no encontrado\")\n        user_posts = [post for post in self.posts.values() if post[\"user_id\"] == user_id]\n        user_posts.sort(key=lambda x: x[\"created_at\"], reverse=True)\n        self._display_feed(user_posts[:10])\n\n    def get_following_feed(self, user_id):\n        if user_id not in self.usuarios:\n            raise ValueError(\"ID de usuario no encontrado\")\n        feed = []\n        for followed_id in self.siguiendo[user_id]:\n            feed.extend([post for post in self.posts.values() if post[\"user_id\"] == followed_id])\n        feed.sort(key=lambda x: x[\"created_at\"], reverse=True)\n        self._display_feed(feed[:10])\n\n    def _display_feed(self, posts):\n        for post in posts:\n            user_name = self.usuarios[post[\"user_id\"]]\n            print(f\"User ID: {post['user_id']}, Name: {user_name}, Text: {post['text']}, \"\n                  f\"Created At: {post['created_at']}, Likes: {post['likes']}\")\n\n\n# Example Usage\nif __name__ == \"__main__\":\n    sn = RedSocial()\n    sn.registrar_usuario(\"u1\", \"Alice\")\n    sn.registrar_usuario(\"u2\", \"Bob\")\n\n    sn.seguir_usuario(\"u1\", \"u2\")\n\n    sn.crear_post(\"u1\", \"p1\", \"Soy Alice!\")\n    sn.crear_post(\"u2\", \"p2\", \"Hola, esto es de Bob\")\n    sn.dar_like(\"p2\")\n    sn.dar_like(\"p1\")\n\n    print(\"\\n[+] - Feed de Alice:\")\n    sn.get_usuario_feed(\"u1\")\n    sn.get_usuario_feed(\"u2\")\n\n    print(\"\\n[+] - Following Feed de Alice:\")\n    sn.get_following_feed(\"u1\")\n"
  },
  {
    "path": "Roadmap/46 - X VS BLUESKY/python/rigo93acosta.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * La alternativa descentralizada a X, Bluesky, comienza a atraer\n * a nuevos usuarios. ¿Cómo funciona una red de este estilo?\n * \n * Implementa un sistema que simule el comportamiento de estas\n * redes sociales.\n * \n * Debes crear las siguientes operaciones:\n * - Registrar un usuario por nombre e identificador único.\n * - Un usuario puede seguir/dejar de seguir a otro.\n * - Creación de post asociado a un usuario. Debe poseer\n *   texto (200 caracteres máximo), fecha de creación \n *   e identificador único.   \n * - Eliminación de un post.\n * - Posibilidad de hacer like (y eliminarlo) en un post.\n * - Visualización del feed de un usuario con sus 10 publicaciones\n *   más actuales ordenadas desde la más reciente.\n * - Visualización del feed de un usuario con las 10 publicaciones\n *   más actuales de los usuarios que sigue ordenadas \n *   desde la más reciente.\n *   \n * Cuando se visualiza un post, debe mostrarse:\n * ID de usuario, nombre de usuario, texto del post, \n * fecha de creación y número total de likes.\n * \n * Controla errores en duplicados o acciones no permitidas.\n */\n\"\"\"\nfrom datetime import datetime \n\nclass SocialNetwork():\n\n    def __init__(self, msg_test=False) -> None:\n        self.postId = 0\n        self.users = {}\n        self.posts = {}\n        self.msg_test = msg_test\n\n    def __str__(self) -> str:\n        text_output = ''.join([f\"User ID: {id} - Name: {user['name']}\\n\" \n                        for id, user in self.users.items()])\n        return text_output\n    \n    def register_user(self, name: str, id: int) -> None:\n        if id in self.users:\n            print(f\"User ID:{id} already\")\n            return\n        self.users[id] = {\"name\": name, \n                          \"following\": set(),\n                          \"followers\": set(),\n                          \"post\": []}\n        \n    def follow_user(self, id: int, id_to_follow: int) -> None:\n\n        if id not in self.users and id_to_follow not in self.users:\n            print(f\"User ID:{id} or ID:{id_to_follow} not found\")\n            return\n        \n        self.users[id][\"following\"].add(id_to_follow)\n        self.users[id_to_follow][\"followers\"].add(id)\n\n        if self.msg_test:\n            print(\n                f\"{self.users[id]['name']} ahora sigue a \" +\n                f\"{self.users[id_to_follow]['name']}.\"\n            )\n\n    def unfollow_user(self, id: int, id_to_unfollow: int) -> None:\n        \n        if id not in self.users and id_to_unfollow not in self.users:\n            print(f\"User ID:{id} or ID:{id_to_unfollow} not found\")\n            return\n        \n        self.users[id][\"following\"].discard(id_to_unfollow)\n        self.users[id_to_unfollow][\"followers\"].discard(id)\n\n        if self.msg_test:\n            print(\n                f\"{self.users[id]['name']} ahora dejó de seguir a \" +\n                f\"{self.users[id_to_unfollow]['name']}.\"\n            )\n\n    def create_post(self, userId: int, text: str) -> None:\n        if userId not in self.users:\n            print(f\"User ID:{userId} not found\")\n            return\n        if len(text) > 200:\n            print(\"Post text too long, maximum 200 characters\")\n            return\n\n        self.postId += 1\n\n        postId = self.postId\n        \n        self.users[userId][\"post\"].append(postId)\n        # Create post\n        self.posts[postId] = {\n            \"userId\": userId,\n            \"text\": text,\n            \"date\": datetime.now(),\n            \"likes\": set()\n        }\n        if self.msg_test:\n            print(f\"Post created with ID: {postId}\")\n\n    def delete_post(self, post_id: int) -> None:\n        if post_id not in self.posts:\n            print(f\"Post ID:{post_id} not found\")\n            return\n        \n        userId = self.posts[post_id][\"userId\"]\n        self.users[userId][\"post\"].remove(post_id)\n        del self.posts[post_id]\n        if self.msg_test:\n            print(f\"Post ID:{post_id} deleted\")\n\n    def like_post(self, userId: int, postId: int) -> None:\n        if userId not in self.users:\n            print(f\"User ID:{userId} not found\")\n            return\n        if postId not in self.posts:\n            print(f\"Post ID:{postId} not found\")\n            return\n        \n        self.posts[postId][\"likes\"].add(userId)\n        if self.msg_test:\n            print(f\"New like in post ID:{postId}\")\n\n    def unlike_post(self, userId: int, postId: int) -> None:\n        if userId not in self.users:\n            print(f\"User ID:{userId} not found\")\n            return\n        if postId not in self.posts:\n            print(f\"Post ID:{postId} not found\")\n            return\n        \n        self.posts[postId][\"likes\"].discard(userId)\n        if self.msg_test:\n            print(f\"Like removed in post ID:{postId}\")\n    \n    def visualization_feed_user(self, userId: int):\n        \n        if userId not in self.users:\n            print(f\"User ID:{id} not found\")\n            return\n        \n        feed = sorted((self.posts[postId] \n                       for postId in self.users[userId][\"post\"]), \n                      key=lambda x: x[\"date\"], reverse=True)\n        \n        for counter, postId in enumerate(feed):\n            if counter == 10:\n                break\n            print(\n                f\"User ID: {userId} - {self.users[userId]['name']}\\n\" +\n                f\"Text: {postId['text']}\\n\\n\" +\n                f\"Likes: {len(postId['likes'])} - Publication date: {postId['date']}\\n\"\n            )\n\n    def visualization_feed_follow(self, userId: int):\n        \n        if userId not in self.users:\n            print(f\"User ID:{id} not found\")\n            return\n        \n\n        postFollowId = []\n        for followId in self.users[userId][\"following\"]:\n            postFollowId.extend(self.users[followId][\"post\"])\n\n        feed = sorted((self.posts[postId] \n                       for postId in postFollowId), \n                      key=lambda x: x[\"date\"], reverse=True)\n\n        for counter, postId in enumerate(feed):\n            if counter == 10:\n                break\n            userPostId = postId[\"userId\"]\n            userPostName = self.users[userPostId][\"name\"]\n            print(\n                f\"User ID: {userPostId} - {userPostName}\\n\" +\n                f\"Text: {postId['text']}\\n\\n\" +\n                f\"Likes: {len(postId['likes'])} - Publication date: {postId['date']}\\n\"\n            )\n\nif __name__ == \"__main__\":\n    \n    TestSocialNetwork = SocialNetwork()\n    TestSocialNetwork.register_user(\"Rigo\", 1)\n    TestSocialNetwork.register_user(\"Mary\", 2)\n    TestSocialNetwork.register_user(\"John\", 3)\n\n    TestSocialNetwork.follow_user(1, 2)\n    TestSocialNetwork.follow_user(1, 3)\n    TestSocialNetwork.follow_user(2, 1)\n\n    TestSocialNetwork.follow_user(3, 1)\n    TestSocialNetwork.follow_user(3, 2)\n    TestSocialNetwork.follow_user(2, 3)\n    TestSocialNetwork.unfollow_user(3, 2)\n\n    TestSocialNetwork.create_post(1, \"Hello World\")\n\n    TestSocialNetwork.create_post(2, \"Hola a todos bienvenidos\")\n    TestSocialNetwork.create_post(2, \"Hola a todos bienvenidos\")\n    TestSocialNetwork.create_post(3, \"Hola a todos bienvenidos\")\n    TestSocialNetwork.delete_post(1)\n    TestSocialNetwork.create_post(1, \"Nuevo post\")\n    TestSocialNetwork.like_post(1, 4)\n    TestSocialNetwork.like_post(2, 4)\n    \n    print(\"\\n----------------------\")\n    print(\"Testing Social Network\")\n    print(\"----------------------\\n\")\n    print(TestSocialNetwork)\n    print(\"\\nUser feed\")\n    TestSocialNetwork.visualization_feed_user(1)\n    print(\"\\nUser Following feed\")\n    TestSocialNetwork.visualization_feed_follow(1)"
  },
  {
    "path": "Roadmap/46 - X VS BLUESKY/rust/kenysdev.rs",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - Rust\n_____________________________________\n46 X VS BLUESKY\n------------------------------------\n\n * EJERCICIO:\n * La alternativa descentralizada a X, Bluesky, comienza a atraer\n * a nuevos usuarios. ¿Cómo funciona una red de este estilo?\n *\n * Implementa un sistema que simule el comportamiento de estas\n * redes sociales.\n *\n * Debes crear las siguientes operaciones:\n * - Registrar un usuario por nombre e identificador único.\n * - Un usuario puede seguir/dejar de seguir a otro.\n * - Creación de post asociado a un usuario. Debe poseer\n *   texto (200 caracteres máximo), fecha de creación\n *   e identificador único.\n * - Eliminación de un post.\n * - Posibilidad de hacer like (y eliminarlo) en un post.\n * - Visualización del feed de un usuario con sus 10 publicaciones\n *   más actuales ordenadas desde la más reciente.\n * - Visualización del feed de un usuario con las 10 publicaciones\n *   más actuales de los usuarios que sigue ordenadas\n *   desde la más reciente.\n *\n * Cuando se visualiza un post, debe mostrarse:\n * ID de usuario, nombre de usuario, texto del post,\n * fecha de creación y número total de likes.\n *\n * Controla errores en duplicados o acciones no permitidas.\n\n[dependencies]\nchrono = \"0.4.37\"\nlog = \"0.4.22\"\nsimple_logger = \"5.0.0\"\n*/\n\nuse chrono::{DateTime, Local};\nuse log::{error, info, warn};\nuse simple_logger::SimpleLogger;\nuse std::collections::{HashMap, HashSet};\n\n#[derive(Clone)]\nstruct PostData {\n    content: String,\n    timestamp: DateTime<Local>,\n    likes: HashSet<i32>,\n}\n\nstruct Posts {\n    post_dt: HashMap<i32, HashMap<i32, PostData>>,\n}\n\nimpl Posts {\n    fn new() -> Self {\n        Posts {\n            post_dt: HashMap::new(),\n        }\n    }\n\n    fn verify_post(&self, id_user: i32, id_post: i32, name_func: &str) -> bool {\n        if !self.post_dt.contains_key(&id_user) {\n            error!(\"'{}': El ID {} no tiene posts.\", name_func, id_user);\n            return false;\n        }\n\n        if !self.post_dt[&id_user].contains_key(&id_post) {\n            error!(\"'{}': El Post ({}) no existe.\", name_func, id_post);\n            return false;\n        }\n\n        true\n    }\n\n    fn create_post(&mut self, id_user: i32, content: &str) {\n        if content.len() > 200 {\n            error!(\"'create_post': content > 200 caracteres.\");\n            return;\n        }\n\n        let user_posts = self.post_dt.entry(id_user).or_insert_with(HashMap::new);\n        let id_post = user_posts.len() as i32 + 1;\n\n        user_posts.insert(\n            id_post,\n            PostData {\n                content: content.to_string(),\n                timestamp: Local::now(),\n                likes: HashSet::new(),\n            },\n        );\n\n        info!(\"El ID {} creó un post(ID: {}).\", id_user, id_post);\n    }\n\n    fn delete_post(&mut self, id_user: i32, id_post: i32) {\n        if self.verify_post(id_user, id_post, \"delete_post\") {\n            self.post_dt.get_mut(&id_user).unwrap().remove(&id_post);\n            info!(\n                \"El post: {} de usuario: {} ha sido eliminado.\",\n                id_post, id_user\n            );\n        }\n    }\n\n    fn like_post(&mut self, id_user: i32, id_author: i32, id_post: i32) {\n        if self.verify_post(id_author, id_post, \"like_post\") {\n            self.post_dt\n                .get_mut(&id_author)\n                .unwrap()\n                .get_mut(&id_post)\n                .unwrap()\n                .likes\n                .insert(id_user);\n\n            info!(\n                \"El usuario {} dio like al post {} de usuario {}.\",\n                id_user, id_post, id_author\n            );\n        }\n    }\n\n    fn remove_like(&mut self, id_user: i32, id_author: i32, id_post: i32) {\n        if self.verify_post(id_author, id_post, \"remove_like\") {\n            self.post_dt\n                .get_mut(&id_author)\n                .unwrap()\n                .get_mut(&id_post)\n                .unwrap()\n                .likes\n                .remove(&id_user);\n\n            info!(\n                \"El usuario {} anuló el like al post {} de usuario {}.\",\n                id_user, id_post, id_author\n            );\n        }\n    }\n\n    fn get_recent_posts(&self, id_user: i32, limit: usize) -> Vec<PostData> {\n        if let Some(user_posts) = self.post_dt.get(&id_user) {\n            let mut posts: Vec<_> = user_posts.values().cloned().collect();\n            posts.sort_by(|a, b| b.timestamp.cmp(&a.timestamp));\n            posts.truncate(limit);\n            posts\n        } else {\n            Vec::new()\n        }\n    }\n}\n\nstruct UserData {\n    name: String,\n    following: HashSet<i32>,\n    followers: HashSet<i32>,\n}\n\nstruct Users {\n    users_dt: HashMap<i32, UserData>,\n}\n\nimpl Users {\n    fn new() -> Self {\n        Users {\n            users_dt: HashMap::new(),\n        }\n    }\n\n    fn id_exists(&self, id: i32, name_func: &str) -> bool {\n        if self.users_dt.contains_key(&id) {\n            return true;\n        }\n\n        warn!(\"'{}': ID: {} no encontrada.\", name_func, id);\n        false\n    }\n\n    fn add_user(&mut self, name: &str) {\n        let id = self.users_dt.len() as i32 + 1;\n        self.users_dt.insert(\n            id,\n            UserData {\n                name: name.to_string(),\n                following: HashSet::new(),\n                followers: HashSet::new(),\n            },\n        );\n\n        info!(\"Usuario {}-{} registrado.\", id, name);\n    }\n\n    fn follow_user(&mut self, id: i32, to_id: i32) {\n        if self.id_exists(id, \"follow_user\") && self.id_exists(to_id, \"follow_user\") {\n            self.users_dt.get_mut(&id).unwrap().following.insert(to_id);\n            self.users_dt.get_mut(&to_id).unwrap().followers.insert(id);\n            info!(\"ID: {} está siguiendo a ID: {}.\", id, to_id);\n        }\n    }\n\n    fn unfollow_user(&mut self, id: i32, to_id: i32) {\n        if self.id_exists(id, \"unfollow_user\") && self.id_exists(to_id, \"unfollow_user\") {\n            self.users_dt.get_mut(&id).unwrap().following.remove(&to_id);\n            self.users_dt.get_mut(&to_id).unwrap().followers.remove(&id);\n            info!(\"El ID: {} dejó de seguir al ID: {}.\", id, to_id);\n        }\n    }\n\n    fn get_name(&self, id_user: i32) -> String {\n        if self.id_exists(id_user, \"get_name\") {\n            self.users_dt[&id_user].name.clone()\n        } else {\n            String::new()\n        }\n    }\n}\n\nstruct Program {\n    posts: Posts,\n    users: Users,\n}\n\nimpl Program {\n    fn new() -> Self {\n        Program {\n            posts: Posts::new(),\n            users: Users::new(),\n        }\n    }\n\n    fn print_feed(&self, id_user: i32) {\n        let name = self.users.get_name(id_user);\n        if name.is_empty() {\n            println!(\"Usuario ID: {} no encontrado.\", id_user);\n            return;\n        }\n\n        let last_10 = self.posts.get_recent_posts(id_user, 10);\n        println!(\"\\nFeed\\n_______\\nID: '{}' - Nombre: '{}'\", id_user, name);\n\n        if last_10.is_empty() {\n            println!(\"No tiene publicaciones.\");\n            return;\n        }\n\n        for post in last_10 {\n            println!(\"_______\\n{}\", post.content);\n            println!(\"Creado: '{}'\", post.timestamp);\n            println!(\"Likes: '{}'\", post.likes.len());\n        }\n    }\n\n    fn run(&self) {\n        // CLI\n    }\n\n    fn tests(&mut self) {\n        self.users.add_user(\"Ken\"); // id=1\n        self.users.add_user(\"Zoe\"); // id=2\n\n        self.users.follow_user(1, 2);\n        self.users.follow_user(2, 1);\n        self.users.unfollow_user(2, 1);\n\n        self.posts.create_post(2, \"Primer post.\"); // id=1\n        self.posts.create_post(2, \"Segundo post.\"); // id=2\n        self.posts.delete_post(2, 2);\n        self.posts.create_post(2, \"Otro post.\"); // id=2\n        self.posts.like_post(1, 2, 1);\n        self.posts.remove_like(1, 2, 1);\n        self.posts.like_post(1, 2, 2);\n\n        self.print_feed(2);\n        self.print_feed(1);\n    }\n}\n\nfn main() {\n    SimpleLogger::new().init().unwrap();\n\n    let mut program = Program::new();\n    program.tests();\n    //program.run();\n}\n"
  },
  {
    "path": "Roadmap/46 - X VS BLUESKY/sql/Nicojsuarez2.sql",
    "content": "# #46 X VS BLUESKY\n> #### Dificultad: Media | Publicación: 18/11/24 | Corrección: 25/11/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * La alternativa descentralizada a X, Bluesky, comienza a atraer\n * a nuevos usuarios. ¿Cómo funciona una red de este estilo?\n * \n * Implementa un sistema que simule el comportamiento de estas\n * redes sociales.\n * \n * Debes crear las siguientes operaciones:\n * - Registrar un usuario por nombre e identificador único.\n * - Un usuario puede seguir/dejar de seguir a otro.\n * - Creación de post asociado a un usuario. Debe poseer\n *   texto (200 caracteres máximo), fecha de creación \n *   e identificador único.   \n * - Eliminación de un post.\n * - Posibilidad de hacer like (y eliminarlo) en un post.\n * - Visualización del feed de un usuario con sus 10 publicaciones\n *   más actuales ordenadas desde la más reciente.\n * - Visualización del feed de un usuario con las 10 publicaciones\n *   más actuales de los usuarios que sigue ordenadas \n *   desde la más reciente.\n *   \n * Cuando se visualiza un post, debe mostrarse:\n * ID de usuario, nombre de usuario, texto del post, \n * fecha de creación y número total de likes.\n * \n * Controla errores en duplicados o acciones no permitidas.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/46 - X VS BLUESKY/typescript/hozlucas28.ts",
    "content": "import type {UUID} from 'crypto'\nimport {randomUUID} from 'crypto'\nimport readline from 'node:readline/promises'\n\n/* -------------------------------------------------------------------------- */\n/*                                   CLASSES                                  */\n/* -------------------------------------------------------------------------- */\n\n/* ---------------------------------- Post ---------------------------------- */\n\ninterface IPost {\n    getID: () => UUID\n    getContent: () => string\n    getDate: () => Date\n    getAuthor: () => string\n    getLikes: () => string[]\n\n    addLike: (uName: string) => void\n    removeLike: (uName: string) => void\n}\n\ninterface PostConstructor {\n    author: string\n    content: string\n}\n\nclass Post implements IPost {\n    private likes: string[]\n    private readonly author: string\n    private readonly content: string\n    private readonly date: Date\n    private readonly id: UUID\n\n    public constructor({author, content}: PostConstructor) {\n        if (content.length > 200)\n            throw new Error(\n                'Content of the post exceed the maximum length (200 chars)'\n            )\n\n        this.author = author\n        this.content = content\n        this.date = new Date()\n        this.id = randomUUID()\n        this.likes = []\n    }\n\n    public getAuthor(): string {\n        return this.author\n    }\n\n    public getContent(): string {\n        return this.content\n    }\n\n    public getDate(): Date {\n        return this.date\n    }\n\n    public getID(): UUID {\n        return this.id\n    }\n\n    public getLikes(): string[] {\n        return this.likes\n    }\n\n    private getLikeIndex(uName: string): number {\n        return this.likes.findIndex((likeUName) => likeUName === uName)\n    }\n\n    public addLike(uName: string): void {\n        const likeI: number = this.getLikeIndex(uName)\n        if (likeI != -1) throw new Error(`\"${uName}\" like already exists`)\n\n        this.likes.push(uName)\n    }\n\n    public removeLike(uName: string): void {\n        const likeI: number = this.getLikeIndex(uName)\n        if (likeI == -1) throw new Error(`\"${uName}\" like doesn't  exist`)\n\n        this.likes.splice(likeI, 1)\n    }\n}\n\n/* ---------------------------------- User ---------------------------------- */\n\ninterface IUser {\n    getUName: () => string\n    getFollowers: () => string[]\n    getFollowings: () => string[]\n    getPosts: () => UUID[]\n\n    __addFollower: (uName: string) => void\n    __removeFollower: (uName: string) => void\n    createPost: (content: string) => void\n    deletePost: (id: UUID) => void\n    follow: (uName: string) => void\n    likePost: (id: UUID) => void\n    unfollow: (uName: string) => void\n    unlikePost: (id: UUID) => void\n}\n\ninterface UserConstructor {\n    uName: string\n}\n\nclass User implements IUser {\n    private followers: string[]\n    private followings: string[]\n    private posts: UUID[]\n    private readonly uName: string\n\n    public constructor({uName}: UserConstructor) {\n        this.followers = []\n        this.followings = []\n        this.posts = []\n        this.uName = uName\n    }\n\n    public getFollowers(): string[] {\n        return this.followers\n    }\n\n    public getFollowings(): string[] {\n        return this.followings\n    }\n\n    public getPosts(): UUID[] {\n        return this.posts\n    }\n\n    public getUName(): string {\n        return this.uName\n    }\n\n    private getFollowerIndex(uName: string): number {\n        return this.followers.findIndex(\n            (followerUName) => followerUName == uName\n        )\n    }\n\n    private getFollowingIndex(uName: string): number {\n        return this.followings.findIndex(\n            (followingUName) => followingUName == uName\n        )\n    }\n\n    private getPostIndex(id: UUID): number {\n        return this.posts.findIndex((postID) => postID == id)\n    }\n\n    public createPost(content: string): void {\n        const post: IPost = new Post({author: this.uName, content})\n        const database: IDatabase = Database.getInstance()\n\n        database.__addNewPost(post)\n        this.posts.push(post.getID())\n    }\n\n    public deletePost(id: UUID): void {\n        const postI: number = this.getPostIndex(id)\n        if (postI == -1)\n            throw new Error(\n                `\"${this.uName}\" doesn't posted the post with \"${id}\" id`\n            )\n\n        const database: IDatabase = Database.getInstance()\n\n        database.__deletePost(id)\n        this.posts.splice(postI, 1)\n    }\n\n    public follow(uName: string): void {\n        const followingI: number = this.getFollowingIndex(uName)\n        if (followingI != -1)\n            throw new Error(`\"${this.uName}\" already follows \"${uName}\"`)\n\n        const database: IDatabase = Database.getInstance()\n\n        const userFollowed: IUser | undefined = database.getUser(uName)\n        if (!userFollowed) throw new Error(`\"${this.uName}\" doesn't exist`)\n\n        userFollowed.__addFollower(this.uName)\n        this.followings.push(uName)\n    }\n\n    public likePost(id: UUID): void {\n        const database: IDatabase = Database.getInstance()\n        const post: IPost | undefined = database.getPost(id)\n        if (!post) throw new Error(`${id} post doesn't exist`)\n\n        post.addLike(this.uName)\n    }\n\n    public unfollow(uName: string): void {\n        const followingI: number = this.getFollowingIndex(uName)\n        if (followingI == -1)\n            throw new Error(`\"${this.uName}\" doesn't follow \"${uName}\"`)\n\n        const database: IDatabase = Database.getInstance()\n\n        const userUnfollowed: IUser | undefined = database.getUser(uName)\n        if (!userUnfollowed) throw new Error(`\"${this.uName}\" doesn't exist`)\n\n        userUnfollowed.__removeFollower(this.uName)\n        this.followings.splice(followingI, 1)\n    }\n\n    public unlikePost(id: UUID): void {\n        const database: IDatabase = Database.getInstance()\n        const post: IPost | undefined = database.getPost(id)\n        if (!post) throw new Error(`${id} post doesn't exist`)\n\n        post.removeLike(this.uName)\n    }\n\n    public __addFollower(uName: string): void {\n        this.followers.push(uName)\n    }\n\n    public __removeFollower(uName: string): void {\n        const followerI: number = this.getFollowerIndex(uName)\n        if (followerI == -1)\n            throw new Error(`\"${this.uName}\" isn't follow by \"${uName}\"`)\n\n        this.followers.splice(followerI, 1)\n    }\n}\n\n/* -------------------------------- Database -------------------------------- */\n\ninterface IDatabase {\n    getPosts: () => IPost[]\n    getUsers: () => IUser[]\n\n    getUser: (uName: string) => IUser | undefined\n\n    getPost: (id: UUID) => IPost | undefined\n    getUserFollowingsPosts: (uName: string) => IPost[]\n    getUserPosts: (uName: string) => IPost[]\n\n    deleteUser: (uName: string) => void\n    postUser: (newUser: IUser) => void\n    __addNewPost: (newPost: IPost) => void\n    __deletePost: (post: UUID) => void\n}\n\nclass Database implements IDatabase {\n    private static instance: IDatabase\n\n    private posts: IPost[]\n    private users: IUser[]\n\n    public constructor() {\n        this.posts = []\n        this.users = []\n    }\n\n    public static getInstance(): IDatabase {\n        if (!Database.instance) Database.instance = new Database()\n        return Database.instance\n    }\n\n    public getPosts(): IPost[] {\n        return this.posts\n    }\n\n    public getUsers(): IUser[] {\n        return this.users\n    }\n\n    public getUser(uName: string): IUser | undefined {\n        return this.users.find((user) => user.getUName() == uName)\n    }\n\n    public getPost(id: UUID): IPost | undefined {\n        return this.posts.find((post) => post.getID() == id)\n    }\n\n    public getUserFollowingsPosts(uName: string): IPost[] {\n        const user: IUser | undefined = this.getUser(uName)\n        if (!user) throw new Error(`\"${uName} doesn't exist\"`)\n\n        const followings: string[] = user.getFollowings()\n\n        let followingPosts: IPost[]\n        let followingsPosts: IPost[] = []\n\n        for (const following of followings) {\n            followingPosts = this.getUserPosts(following)\n            followingsPosts.push(...followingPosts)\n        }\n\n        return followingsPosts\n    }\n\n    public getUserPosts(uName: string): IPost[] {\n        const user: IUser | undefined = this.getUser(uName)\n        if (!user) throw new Error(`\"${uName} doesn't exist\"`)\n\n        const userPostsIDs: UUID[] = user.getPosts()\n\n        let post: IPost | undefined\n        const userPosts: IPost[] = []\n\n        for (const postID of userPostsIDs) {\n            post = this.getPost(postID)\n            if (post) userPosts.push(post)\n        }\n\n        return userPosts\n    }\n\n    public deleteUser(uName: string): void {\n        const userI: number = this.users.findIndex(\n            (user) => user.getUName() === uName\n        )\n        if (userI == -1) throw new Error(`\"${uName}\" doesn't exist`)\n\n        this.users.splice(userI, 1)\n    }\n\n    public postUser(newUser: IUser): void {\n        if (this.getUserIndex(newUser) != -1)\n            throw new Error(`\"${newUser.getUName()}\" already exists`)\n\n        this.users.push(newUser)\n    }\n\n    public __addNewPost(newPost: IPost): void {\n        this.posts.push(newPost)\n    }\n\n    public __deletePost(post: UUID): void {\n        const postI: number = this.getPostIndex(post)\n        if (postI == -1) throw new Error(`\"${post}\" doesn't exist`)\n\n        this.posts.splice(postI, 1)\n    }\n\n    private getUserIndex(user: IUser): number {\n        return this.users.findIndex((u) => u.getUName() === user.getUName())\n    }\n\n    private getPostIndex(post: UUID): number {\n        return this.posts.findIndex((p) => p.getID() === post)\n    }\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\n;(async () => {\n    const database: IDatabase = Database.getInstance()\n\n    const rl: readline.Interface = readline.createInterface({\n        output: process.stdout,\n        input: process.stdin,\n    })\n\n    let input01: string\n    let input02: string\n    let uName: string\n    let user: IUser | undefined\n    let posts: IPost[]\n    let postContent: string\n    let postID: UUID\n    let post: IPost\n    let i: number\n\n    do {\n        console.log(\n            '> Available operations...\\n\\n' +\n                '  1 - Sign up a new user.\\n' +\n                '  2 - Sign in as user.\\n' +\n                '  0 - Exit.'\n        )\n\n        input01 = (await rl.question('\\n> Enter an operation: ')).trim()\n\n        switch (input01) {\n            case '0':\n                break\n\n            case '1':\n                uName = (await rl.question('\\n> Username: ')).trim()\n                user = new User({uName})\n                database.postUser(user)\n                break\n\n            case '2':\n                uName = (await rl.question('\\n> Username: ')).trim()\n                user = database.getUser(uName)\n                if (!user) {\n                    console.log('> Username not found.')\n                    break\n                }\n\n                do {\n                    console.log(\n                        '\\n> Available operations...\\n\\n' +\n                            '  1 - Create a new post.\\n' +\n                            '  2 - Show personal feed.\\n' +\n                            '  3 - Show following feed.\\n' +\n                            '  4 - Delete post.\\n' +\n                            '  5 - Follow user.\\n' +\n                            '  6 - Unfollow user.\\n' +\n                            '  7 - Like post.\\n' +\n                            '  8 - Unlike post.\\n' +\n                            '  0 - Exit.'\n                    )\n\n                    input02 = (\n                        await rl.question('\\n> Enter an operation: ')\n                    ).trim()\n\n                    switch (input02) {\n                        case '0':\n                            break\n\n                        case '1':\n                            postContent = (\n                                await rl.question(\n                                    '\\n> Post content (maximum 200 characters): '\n                                )\n                            ).trim()\n                            user.createPost(postContent)\n                            break\n\n                        case '2':\n                            posts = database.getUserPosts(user.getUName())\n\n                            posts = posts.sort(\n                                (a, b) =>\n                                    b.getDate().valueOf() -\n                                    a.getDate().valueOf()\n                            )\n\n                            for (i = 0; i < 10 && i < posts.length; i++) {\n                                post = posts[i]\n                                console.log(`\\n> ID: \"${post.getID()}\".`)\n                                console.log(`> Author: \"${post.getAuthor()}\".`)\n                                console.log(\n                                    `> Content: \"${post.getContent()}\".`\n                                )\n                                console.log(\n                                    `> Creation date: \"${post.getDate()}\".`\n                                )\n                                console.log(\n                                    `> Likes: ${post.getLikes().length}.`\n                                )\n                            }\n                            break\n\n                        case '3':\n                            posts = database.getUserFollowingsPosts(\n                                user.getUName()\n                            )\n\n                            posts = posts.sort(\n                                (a, b) =>\n                                    b.getDate().valueOf() -\n                                    a.getDate().valueOf()\n                            )\n\n                            for (i = 0; i < 10 && i < posts.length; i++) {\n                                post = posts[i]\n                                console.log(`\\n> ID: \"${post.getID()}\".`)\n                                console.log(`> Author: \"${post.getAuthor()}\".`)\n                                console.log(\n                                    `> Content: \"${post.getContent()}\".`\n                                )\n                                console.log(\n                                    `> Creation date: \"${post.getDate()}\".`\n                                )\n                                console.log(\n                                    `> Likes: ${post.getLikes().length}.`\n                                )\n                            }\n                            break\n\n                        case '4':\n                            postID = (\n                                await rl.question('\\n> Post ID: ')\n                            ).trim() as UUID\n                            user.deletePost(postID)\n                            break\n\n                        case '5':\n                            uName = (await rl.question('\\n> Username: ')).trim()\n                            user.follow(uName)\n                            break\n\n                        case '6':\n                            uName = (await rl.question('\\n> Username: ')).trim()\n                            user.unfollow(uName)\n                            break\n\n                        case '7':\n                            postID = (\n                                await rl.question('\\n> Post ID: ')\n                            ).trim() as UUID\n                            user.likePost(postID)\n                            break\n\n                        case '8':\n                            postID = (\n                                await rl.question('\\n> Post ID: ')\n                            ).trim() as UUID\n                            user.unlikePost(postID)\n                            break\n\n                        default:\n                            console.log('\\n> Invalid operation! Try again...')\n                    }\n                } while (input02 != '0')\n                break\n\n            default:\n                console.log('\\n> Invalid operation! Try again...')\n        }\n\n        console.log()\n    } while (input01 != '0')\n\n    rl.close()\n})()\n"
  },
  {
    "path": "Roadmap/46 - X VS BLUESKY/typescript/miguelex.ts",
    "content": "import readline from 'readline';\n\nclass User {\n    id: string;\n    name: string;\n    following: string[];\n    posts: Post[];\n\n    constructor(id: string, name: string) {\n        this.id = id;\n        this.name = name;\n        this.following = [];\n        this.posts = [];\n    }\n\n    follow(user: User): void {\n        if (this.following.includes(user.id)) {\n            console.log(`${this.name} ya sigue a ${user.name}.`);\n            return;\n        }\n        this.following.push(user.id);\n        console.log(`${this.name} comenzó a seguir a ${user.name}.`);\n    }\n\n    unfollow(user: User): void {\n        if (!this.following.includes(user.id)) {\n            console.log(`${this.name} no sigue a ${user.name}.`);\n            return;\n        }\n        this.following = this.following.filter(id => id !== user.id);\n        console.log(`${this.name} dejó de seguir a ${user.name}.`);\n    }\n}\n\nclass Post {\n    id: string;\n    text: string;\n    userId: string;\n    createdAt: Date;\n    likes: number;\n\n    constructor(id: string, text: string, userId: string) {\n        this.id = id;\n        this.text = text.slice(0, 200);\n        this.userId = userId;\n        this.createdAt = new Date();\n        this.likes = 0;\n    }\n\n    like(): void {\n        this.likes++;\n    }\n\n    unlike(): void {\n        if (this.likes > 0) {\n            this.likes--;\n        }\n    }\n}\n\nclass SocialNetwork {\n    users: Record<string, User>;\n    posts: Record<string, Post>;\n\n    constructor() {\n        this.users = {};\n        this.posts = {};\n    }\n\n    registerUser(id: string, name: string): void {\n        if (this.users[id]) {\n            console.log(`El usuario con ID ${id} ya existe.`);\n            return;\n        }\n        this.users[id] = new User(id, name);\n        console.log(`Usuario ${name} registrado con éxito.`);\n    }\n\n    createPost(userId: string, text: string): void {\n        if (!this.users[userId]) {\n            console.log(`El usuario con ID ${userId} no existe.`);\n            return;\n        }\n        const postId = `post_${Date.now()}`;\n        const post = new Post(postId, text, userId);\n        this.posts[postId] = post;\n        this.users[userId].posts.push(post);\n        console.log(`Post creado con éxito.`);\n    }\n\n    deletePost(postId: string): void {\n        const post = this.posts[postId];\n        if (!post) {\n            console.log(`El post con ID ${postId} no existe.`);\n            return;\n        }\n        const user = this.users[post.userId];\n        user.posts = user.posts.filter(p => p.id !== postId);\n        delete this.posts[postId];\n        console.log(`Post eliminado con éxito.`);\n    }\n\n    likePost(postId: string): void {\n        const post = this.posts[postId];\n        if (!post) {\n            console.log(`El post con ID ${postId} no existe.`);\n            return;\n        }\n        post.like();\n        console.log(`Post ${postId} recibió un like.`);\n    }\n\n    unlikePost(postId: string): void {\n        const post = this.posts[postId];\n        if (!post) {\n            console.log(`El post con ID ${postId} no existe.`);\n            return;\n        }\n        post.unlike();\n        console.log(`Like eliminado del post ${postId}.`);\n    }\n\n    viewFeed(userId: string): void {\n        const user = this.users[userId];\n        if (!user) {\n            console.log(`El usuario con ID ${userId} no existe.`);\n            return;\n        }\n\n        const posts = user.posts.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());\n\n        console.log(`Feed de ${user.name}:`);\n        posts.slice(0, 10).forEach(post => this.displayPost(post));\n    }\n\n    viewFollowedFeed(userId: string): void {\n        const user = this.users[userId];\n        if (!user) {\n            console.log(`El usuario con ID ${userId} no existe.`);\n            return;\n        }\n\n        let followedPosts: Post[] = [];\n        user.following.forEach(followedId => {\n            const followedUser = this.users[followedId];\n            if (followedUser) {\n                followedPosts = followedPosts.concat(followedUser.posts);\n            }\n        });\n\n        followedPosts.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());\n\n        console.log(`Feed de usuarios seguidos por ${user.name}:`);\n        followedPosts.slice(0, 10).forEach(post => this.displayPost(post));\n    }\n\n    displayPost(post: Post): void {\n        console.log(`ID: ${post.id}, Usuario: ${post.userId}, Texto: ${post.text}, Fecha: ${post.createdAt.toISOString()}, Likes: ${post.likes}`);\n    }\n\n    async interactiveMenu(): Promise<void> {\n        const rl = readline.createInterface({\n            input: process.stdin,\n            output: process.stdout\n        });\n\n        const ask = (question: string): Promise<string> => new Promise(resolve => rl.question(question, resolve));\n\n        while (true) {\n            console.log(`\\n--- Menú Principal ---`);\n            console.log(`1. Registrar usuario`);\n            console.log(`2. Crear post`);\n            console.log(`3. Eliminar post`);\n            console.log(`4. Dar like a un post`);\n            console.log(`5. Quitar like de un post`);\n            console.log(`6. Ver feed del usuario`);\n            console.log(`7. Ver feed de usuarios seguidos`);\n            console.log(`8. Seguir a un usuario`);\n            console.log(`9. Dejar de seguir a un usuario`);\n            console.log(`10. Salir`);\n\n            const option = await ask(`Seleccione una opción: `);\n\n            switch (option) {\n                case \"1\":\n                    const id = await ask(`Ingrese ID del usuario: `);\n                    const name = await ask(`Ingrese nombre del usuario: `);\n                    this.registerUser(id, name);\n                    break;\n                case \"2\":\n                    const userId = await ask(`Ingrese ID del usuario: `);\n                    const text = await ask(`Ingrese texto del post: `);\n                    this.createPost(userId, text);\n                    break;\n                case \"3\":\n                    const postId = await ask(`Ingrese ID del post: `);\n                    this.deletePost(postId);\n                    break;\n                case \"4\":\n                    const likePostId = await ask(`Ingrese ID del post: `);\n                    this.likePost(likePostId);\n                    break;\n                case \"5\":\n                    const unlikePostId = await ask(`Ingrese ID del post: `);\n                    this.unlikePost(unlikePostId);\n                    break;\n                case \"6\":\n                    const feedUserId = await ask(`Ingrese ID del usuario: `);\n                    this.viewFeed(feedUserId);\n                    break;\n                case \"7\":\n                    const followedFeedUserId = await ask(`Ingrese ID del usuario: `);\n                    this.viewFollowedFeed(followedFeedUserId);\n                    break;\n                case \"8\":\n                    const followerId = await ask(`Ingrese tu ID: `);\n                    const followId = await ask(`Ingrese ID del usuario a seguir: `);\n                    if (this.users[followerId] && this.users[followId]) {\n                        this.users[followerId].follow(this.users[followId]);\n                    } else {\n                        console.log(`Usuario no encontrado.`);\n                    }\n                    break;\n                case \"9\":\n                    const unfollowerId = await ask(`Ingrese tu ID: `);\n                    const unfollowId = await ask(`Ingrese ID del usuario a dejar de seguir: `);\n                    if (this.users[unfollowerId] && this.users[unfollowId]) {\n                        this.users[unfollowerId].unfollow(this.users[unfollowId]);\n                    } else {\n                        console.log(`Usuario no encontrado.`);\n                    }\n                    break;\n                case \"10\":\n                    rl.close();\n                    console.log(`Saliendo...`);\n                    return;\n                default:\n                    console.log(`Opción no válida.`);\n            }\n        }\n    }\n}\n\n(async () => {\n    const socialNetwork = new SocialNetwork();\n    await socialNetwork.interactiveMenu();\n})();\n"
  },
  {
    "path": "Roadmap/46 - X VS BLUESKY/vb.net/kenysdev.vb",
    "content": "' _____________________________________\n' https://github.com/kenysdev\n' 2024 - vb.net\n' _____________________________________\n' 46 X VS BLUESKY\n' ------------------------------------\n'* EJERCICIO:\n' * La alternativa descentralizada a X, Bluesky, comienza a atraer\n' * a nuevos usuarios. ¿Cómo funciona una red de este estilo?\n' * \n' * Implementa un sistema que simule el comportamiento de estas\n' * redes sociales.\n' * \n' * Debes crear las siguientes operaciones:\n' * - Registrar un usuario por nombre e identificador único.\n' * - Un usuario puede seguir/dejar de seguir a otro.\n' * - Creación de post asociado a un usuario. Debe poseer\n' *   texto (200 caracteres máximo), fecha de creación \n' *   e identificador único.   \n' * - Eliminación de un post.\n' * - Posibilidad de hacer Like (y eliminarlo) en un post.\n' * - Visualización del feed de un usuario con sus 10 publicaciones\n' *   más actuales ordenadas desde la más reciente.\n' * - Visualización del feed de un usuario con las 10 publicaciones\n' *   más actuales de los usuarios que sigue ordenadas \n' *   desde la más reciente.\n' *   \n' * Cuando se visualiza un post, debe mostrarse:\n' * ID de usuario, nombre de usuario, texto del post, \n' * fecha de creación y número total de likes.\n' * \n' * Controla errores en duplicados o acciones no permitidas.\n\nImports System\nImports System.Collections.Generic\nImports System.Linq\nImports Microsoft.Extensions.Logging\nImports Microsoft.Extensions.DependencyInjection\n\nPublic Class Posts\n    Private ReadOnly _postDt As New Dictionary(Of Integer, Dictionary(Of Integer, PostData))\n    Private ReadOnly _logger As ILogger(Of Posts)\n\n    Public Sub New(logger As ILogger(Of Posts))\n        _logger = logger\n    End Sub\n\n    Public Class PostData\n        Public Property Content As String = String.Empty\n        Public Property Timestamp As DateTime\n        Public Property Likes As New HashSet(Of Integer)\n    End Class\n\n    Private Function VerifyPost(idUser As Integer, idPost As Integer, nameFuncStr As String) As Boolean\n        Dim userPosts As Dictionary(Of Integer, PostData) = Nothing\n        If Not _postDt.TryGetValue(idUser, userPosts) Then\n            _logger.LogError(\"{NameFunc}: El ID {IdUser} no tiene posts.\", nameFuncStr, idUser)\n            Return False\n        End If\n\n        If Not userPosts.ContainsKey(idPost) Then\n            _logger.LogError(\"{NameFunc}: El Post ({IdPost}) no existe.\", nameFuncStr, idPost)\n            Return False\n        End If\n\n        Return True\n    End Function\n\n    Public Sub CreatePost(idUser As Integer, content As String)\n        If content.Length > 200 Then\n            _logger.LogError(\"'create_post': content > 200 caracteres.\")\n            Return\n        End If\n\n        Dim userPosts As Dictionary(Of Integer, PostData) = Nothing\n        If Not _postDt.TryGetValue(idUser, userPosts) Then\n            userPosts = New Dictionary(Of Integer, PostData)()\n            _postDt(idUser) = userPosts\n        End If\n\n        Dim idPost = userPosts.Count + 1\n        userPosts(idPost) = New PostData With {\n            .Content = content,\n            .Timestamp = DateTime.Now,\n            .Likes = New HashSet(Of Integer)()\n        }\n\n        _logger.LogInformation(\"El ID {IdUser} creó un post(ID: {IdPost}).\", idUser, idPost)\n    End Sub\n\n    Public Sub DeletePost(idUser As Integer, idPost As Integer)\n        If VerifyPost(idUser, idPost, \"DeletePost\") Then\n            _postDt(idUser).Remove(idPost)\n            _logger.LogInformation(\"El post: {IdPost} de usuario: {IdUser} ha sido eliminado.\", idPost, idUser)\n        End If\n    End Sub\n\n    Public Sub LikePost(idUser As Integer, idAuthor As Integer, idPost As Integer)\n        If VerifyPost(idAuthor, idPost, \"LikePost\") Then\n            _postDt(idAuthor)(idPost).Likes.Add(idUser)\n            _logger.LogInformation(\"El usuario {IdUser} dio like al post {IdPost} de usuario {IdAuthor}.\",\n                idUser, idPost, idAuthor)\n        End If\n    End Sub\n\n    Public Sub RemoveLike(idUser As Integer, idAuthor As Integer, idPost As Integer)\n        If VerifyPost(idAuthor, idPost, \"RemoveLike\") Then\n            _postDt(idAuthor)(idPost).Likes.Remove(idUser)\n            _logger.LogInformation(\"El usuario {IdUser} anuló el like al post {IdPost} de usuario {IdAuthor}.\",\n                idUser, idPost, idAuthor)\n        End If\n    End Sub\n\n    Public Function GetRecentPosts(idUser As Integer, Optional limit As Integer = 10) As List(Of PostData)\n        Dim userPosts As Dictionary(Of Integer, PostData) = Nothing\n        If _postDt.TryGetValue(idUser, userPosts) Then\n            Return userPosts.Values _\n                .OrderByDescending(Function(p) p.Timestamp) _\n                .Take(limit) _\n                .ToList()\n        End If\n\n        Return New List(Of PostData)()\n    End Function\nEnd Class\n\nPublic Class Users\n    Private ReadOnly _usersDt As New Dictionary(Of Integer, UserData)\n    Private ReadOnly _logger As ILogger(Of Users)\n\n    Public Sub New(logger As ILogger(Of Users))\n        _logger = logger\n    End Sub\n\n    Private Class UserData\n        Public Property Name As String = String.Empty\n        Public Property Following As New HashSet(Of Integer)\n        Public Property Followers As New HashSet(Of Integer)\n    End Class\n\n    Private Function IdExists(id As Integer, nameFuncStr As String) As Boolean\n        If _usersDt.ContainsKey(id) Then\n            Return True\n        End If\n\n        _logger.LogWarning(\"'{NameFunc}': ID: {Id} no encontrada.\", nameFuncStr, id)\n        Return False\n    End Function\n\n    Public Sub AddUser(name As String)\n        Dim id = _usersDt.Count + 1\n        _usersDt(id) = New UserData With {\n            .Name = name,\n            .Following = New HashSet(Of Integer)(),\n            .Followers = New HashSet(Of Integer)()\n        }\n\n        _logger.LogInformation(\"Usuario {Id}-{Name} registrado.\", id, name)\n    End Sub\n\n    Public Sub FollowUser(id As Integer, toId As Integer)\n        If IdExists(id, \"FollowUser\") AndAlso IdExists(toId, \"FollowUser\") Then\n            _usersDt(id).Following.Add(toId)\n            _usersDt(toId).Followers.Add(id)\n            _logger.LogInformation(\"ID: {Id} está siguiendo a ID: {ToId}.\", id, toId)\n        End If\n    End Sub\n\n    Public Sub UnfollowUser(id As Integer, toId As Integer)\n        If IdExists(id, \"UnfollowUser\") AndAlso IdExists(toId, \"UnfollowUser\") Then\n            _usersDt(id).Following.Remove(toId)\n            _usersDt(toId).Followers.Remove(id)\n            _logger.LogInformation(\"El ID: {Id} dejó de seguir al ID: {ToId}.\", id, toId)\n        End If\n    End Sub\n\n    Public Function GetName(idUser As Integer) As String\n        If IdExists(idUser, \"GetName\") Then\n            Return _usersDt(idUser).Name\n        End If\n\n        Return String.Empty\n    End Function\nEnd Class\n\nPublic Class Program\n    Private ReadOnly _posts As Posts\n    Private ReadOnly _users As Users\n\n    Public Sub New(postsLogger As ILogger(Of Posts), usersLogger As ILogger(Of Users))\n        _posts = New Posts(postsLogger)\n        _users = New Users(usersLogger)\n    End Sub\n\n    Private Sub PrintFeed(idUser As Integer)\n        Dim name = _users.GetName(idUser)\n        If String.IsNullOrEmpty(name) Then\n            Console.WriteLine($\"Usuario ID: {idUser} no encontrado.\")\n            Return\n        End If\n\n        Dim last10 = _posts.GetRecentPosts(idUser, 10)\n        Console.WriteLine($\"{vbCrLf}Feed{vbCrLf}________{vbCrLf}ID: '{idUser}' - Nombre: '{name}'\")\n\n        If last10.Count = 0 Then\n            Console.WriteLine(\"No tiene publicaciones.\")\n            Return\n        End If\n\n        For Each post In last10\n            Console.WriteLine($\"________{vbCrLf}{post.Content}\")\n            Console.WriteLine($\"Creado: '{post.Timestamp}'\")\n            Console.WriteLine($\"Likes: '{post.Likes.Count}'\")\n        Next\n    End Sub\n\n    Public Sub Run()\n        ' CLI\n    End Sub\n\n    Public Sub Tests()\n        _users.AddUser(\"Ken\") ' id=1\n        _users.AddUser(\"Zoe\") ' id=2\n\n        _users.FollowUser(1, 2)\n        _users.FollowUser(2, 1)\n        _users.UnfollowUser(2, 1)\n\n        _posts.CreatePost(2, \"Primer post.\") ' id=1\n        _posts.CreatePost(2, \"Segundo post.\") ' id=2\n        _posts.DeletePost(2, 2)\n        _posts.CreatePost(2, \"Otro post.\") ' id=2\n        _posts.LikePost(1, 2, 1)\n        _posts.RemoveLike(1, 2, 1)\n        _posts.LikePost(1, 2, 2)\n\n        PrintFeed(2)\n        PrintFeed(1)\n    End Sub\n\n    Public Shared Sub Main()\n        Dim services = New ServiceCollection()\n        services.AddLogging(Sub(builder)\n                                builder.SetMinimumLevel(LogLevel.Debug)\n                                builder.AddConsole()\n                            End Sub)\n\n        Using serviceProvider = services.BuildServiceProvider()\n            Dim loggerFactory = serviceProvider.GetRequiredService(Of ILoggerFactory)()\n            Dim postsLogger = loggerFactory.CreateLogger(Of Posts)()\n            Dim usersLogger = loggerFactory.CreateLogger(Of Users)()\n\n            Dim program = New Program(postsLogger, usersLogger)\n            program.Tests()\n            'program.Run()\n        End Using\n    End Sub\nEnd Class\n"
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/c#/hequebo.cs",
    "content": "class AdventCalendar\n{\n    private bool[] _days = new bool[24];\n\n    public AdventCalendar() \n    {\n        for (int i = 0; i < 24; i++)\n        {\n            _days[i] = false;\n        }\n    }\n    public void Display()\n    {\n        string line = string.Join(\"\\t\", Enumerable.Repeat(\"****\", 6));\n        for (int i = 0; i < 4;i++)\n        {\n            Console.Write($\"{line}\\n\");\n            for (int j = i * 6; j < (i * 6) + 6; j++)\n                Console.Write($\"*{(!_days[j] ? (j < 9 ? $\"0{j + 1}\" : j +1 ) : \"**\")}*\\t\");\n            \n            Console.Write($\"\\n{line}\\n\\n\");\n        }\n    }\n    public void SelectDay(int day)\n    {\n        if (day <= 0 || day > 24)\n        {\n            Console.WriteLine(\"El día debe estar entre 1 y 24...\");\n            return;\n        }\n        if (_days[day - 1])\n        {\n            Console.WriteLine($\"El día {day} ya ha sido revelado\");\n            return;\n        }\n        _days[day - 1] = true;\n        Console.WriteLine($\"Has abierto el día {day}\");\n    }\n\n}\nclass Program\n{\n    static void Main(string[] args)\n    {\n        var calendar = new AdventCalendar();\n        bool exit = false;\n        do\n        {\n            Console.WriteLine(\"-----------CALENDARIO DE ADVIENTO-----------\");\n            calendar.Display();\n            Console.WriteLine(\"Selecciona el día que quieras descubir o escribe 'salir' para finalizar\");\n\n            string? input = Console.ReadLine();\n            Console.Clear();\n            if (input.ToLower() == \"salir\")\n            {\n                exit = true;\n                Console.WriteLine(\"Hasta la próxima...\");\n            }\n            else\n            {\n                int.TryParse(input, out int option);\n                calendar.SelectDay(option);\n            }\n        } while (!exit);\n\n    }\n}"
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/c#/kenysdev.cs",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - C#\n_____________________________________\n47  CALENDARIO DE ADVIENTO\n------------------------------------\n\n * EJERCICIO:\n * ¡Cada año celebramos el aDEViento! 24 días, 24 regalos para\n * developers. Del 1 al 24 de diciembre: https://adviento.dev\n * \n * Dibuja un calendario por terminal e implementa una\n * funcionalidad para seleccionar días y mostrar regalos.\n * - El calendario mostrará los días del 1 al 24 repartidos\n *   en 6 columnas a modo de cuadrícula.\n * - Cada cuadrícula correspondiente a un día tendrá un tamaño \n *   de 4x3 caracteres, y sus bordes serán asteríscos.\n * - Las cuadrículas dejarán un espacio entre ellas.\n * - En el medio de cada cuadrícula aparecerá el día entre el\n *   01 y el 24.\n *\n * Ejemplo de cuadrículas:\n * **** **** ****\n * *01* *02* *03* ...\n * **** **** ****\n *\n * - El usuario seleccioná qué día quiere descubrir.\n * - Si está sin descubrir, se le dirá que ha abierto ese día\n *   y se mostrará de nuevo el calendario con esa cuadrícula\n *   cubierta de asteríscos (sin mostrar el día).\n *\n * Ejemplo de selección del día 1\n * **** **** ****\n * **** *02* *03* ...\n * **** **** ****\n *   \n * - Si se selecciona un número ya descubierto, se le notifica\n *   al usuario.\n*/\n\nstring[,] mtx = new string[4, 6];\nfor (int i = 0; i < 4; i++)\n{\n    for (int j = 0; j < 6; j++)\n    {\n        mtx[i, j] = $\"*{(i * 6 + j + 1):00}*\";\n    }\n}\n\nstring ln = string.Join(\" \", Enumerable.Repeat(\"****\", 6));\n\nwhile (true)\n{\n    for (int i = 0; i < 4; i++)\n    {\n        Console.WriteLine(ln);\n        int currentRow = i;\n\n        for (int j = 0; j < 6; j++)\n        {\n            Console.Write(mtx[currentRow, j] + \" \");\n        }\n        Console.WriteLine(\"\\n\" + ln + \"\\n\");\n    }\n\n    Console.Write(\"Día a descubrir: \");\n    string? day = Console.ReadLine();\n\n    if (!int.TryParse(day, out int dayInt))\n    {\n        Console.WriteLine(\"Entrada inválida. Debe ser un número.\");\n        continue;\n    }\n\n    if (dayInt < 1 || dayInt > 24)\n    {\n        Console.WriteLine(\"Día inválido, debe ser entre 1 y 24.\");\n        continue;\n    }\n\n    int r = (dayInt - 1) / 6;\n    int c = (dayInt - 1) % 6;\n\n    if (mtx[r, c] == \"****\")\n    {\n        Console.WriteLine($\"El día {day} ya está descubierto.\");\n        continue;\n    }\n\n    mtx[r, c] = \"****\";\n}\n"
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/c++/hectorio23.cpp",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\n#include <iostream>\n#include <iomanip>\n#include <vector>\n#include <string>\n\n// Constantes para las dimensiones de las cuadrículas y el rango de días\nconst int GRID_WIDTH = 4;\nconst int GRID_HEIGHT = 3;\nconst int TOTAL_DAYS = 24;\nconst int COLUMNS = 6;\n\n// Función para dibujar el calendario\nvoid drawCalendar(const std::vector<bool>& openedDays) {\n    for (int row = 0; row < TOTAL_DAYS / COLUMNS; ++row) {\n        for (int h = 0; h < GRID_HEIGHT; ++h) { // Cada fila de la cuadrícula\n            for (int col = 0; col < COLUMNS; ++col) {\n                int day = row * COLUMNS + col + 1; // Día correspondiente\n\n                if (h == 0 || h == GRID_HEIGHT - 1) {\n                    // Bordes superior e inferior\n                    std::cout << \"**** \";\n                } else if (h == GRID_HEIGHT / 2) {\n                    // Línea central con el número del día o asteriscos si está descubierto\n                    if (openedDays[day - 1]) {\n                        std::cout << \"**** \";\n                    } else {\n                        std::cout << \"*\" << std::setw(2) << std::setfill('0') << day << \"* \";\n                    }\n                } else {\n                    // Espaciado intermedio\n                    std::cout << \"*  * \";\n                }\n            }\n            std::cout << std::endl;\n        }\n    }\n}\n\n// Función principal\nint main() {\n    std::vector<bool> openedDays(TOTAL_DAYS, false); // Seguimiento de días descubiertos\n    std::string input;\n\n    std::cout << \"\\nBienvenido al calendario de aDEViento!\\n\";\n    while (true) {\n        drawCalendar(openedDays);\n        std::cout << \"\\nSelecciona un día (1-24) o escribe 'salir' para terminar: \";\n        std::cin >> input;\n\n        if (input == \"salir\") {\n            std::cout << \"Gracias por participar!\\n\";\n            break;\n        }\n\n        // Validar la entrada\n        int selectedDay;\n        try {\n            selectedDay = stoi(input);\n        } catch (...) {\n            std::cout << \"Entrada no válida. Inténtalo de nuevo.\\n\";\n            continue;\n        }\n\n        if (selectedDay < 1 || selectedDay > TOTAL_DAYS) {\n            std::cout << \"Número fuera de rango. Inténtalo de nuevo.\\n\";\n            continue;\n        }\n\n        // Verificar el estado del día seleccionado\n        if (openedDays[selectedDay - 1]) {\n            std::cout << \"El día \" << selectedDay << \" ya ha sido descubierto.\\n\";\n        } else {\n            openedDays[selectedDay - 1] = true;\n            std::cout << \"Has descubierto el día \" << selectedDay << \"! Felicidades!\\n\";\n        }\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/ejercicio.md",
    "content": "# #47 CALENDARIO DE ADVIENTO\n> #### Dificultad: Fácil | Publicación: 25/11/24 | Corrección: 02/12/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * ¡Cada año celebramos el aDEViento! 24 días, 24 regalos para\n * developers. Del 1 al 24 de diciembre: https://adviento.dev\n * \n * Dibuja un calendario por terminal e implementa una\n * funcionalidad para seleccionar días y mostrar regalos.\n * - El calendario mostrará los días del 1 al 24 repartidos\n *   en 6 columnas a modo de cuadrícula.\n * - Cada cuadrícula correspondiente a un día tendrá un tamaño \n *   de 4x3 caracteres, y sus bordes serán asteríscos.\n * - Las cuadrículas dejarán un espacio entre ellas.\n * - En el medio de cada cuadrícula aparecerá el día entre el\n *   01 y el 24.\n *\n * Ejemplo de cuadrículas:\n * **** **** ****\n * *01* *02* *03* ...\n * **** **** ****\n *\n * - El usuario selecciona qué día quiere descubrir.\n * - Si está sin descubrir, se le dirá que ha abierto ese día\n *   y se mostrará de nuevo el calendario con esa cuadrícula\n *   cubierta de asteríscos (sin mostrar el día).\n *\n * Ejemplo de selección del día 1\n * **** **** ****\n * **** *02* *03* ...\n * **** **** ****\n *   \n * - Si se selecciona un número ya descubierto, se le notifica\n *   al usuario.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/go/hozlucas28.go",
    "content": "package main\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"os/exec\"\n\t\"strings\"\n)\n\n/* -------------------------------------------------------------------------- */\n/*                                   ERRORS                                   */\n/* -------------------------------------------------------------------------- */\n\n/* ----------------------- CalendarCellDiscoveredError ---------------------- */\n\ntype CalendarCellDiscoveredError struct {\n\tCell CalendarCell\n\t_    struct{}\n}\n\nfunc (err CalendarCellDiscoveredError) Error() string {\n\treturn fmt.Sprintf(\n\t\t\"%d calendar cell is already discovered\",\n\t\terr.Cell.Id,\n\t)\n}\n\n/* ------------------------ CalendarDayNotFoundError ------------------------ */\n\ntype CalendarDayNotFoundError struct {\n\tDay uint16\n\t_   struct{}\n}\n\nfunc (err *CalendarDayNotFoundError) Error() string {\n\treturn fmt.Sprintf(\n\t\t\"%d calendar day not found\",\n\t\terr.Day,\n\t)\n}\n\n/* ------------------------ CalendarDayOuOfRangeError ----------------------- */\n\ntype CalendarDayOuOfRangeError struct {\n\tDay  uint16\n\tFrom uint16\n\tTo   uint16\n\t_    struct{}\n}\n\nfunc (err *CalendarDayOuOfRangeError) Error() string {\n\treturn fmt.Sprintf(\n\t\t\"%d calendar day is out of range, it must be between %d and %d (both included)\",\n\t\terr.Day,\n\t\terr.From,\n\t\terr.To,\n\t)\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                   STRUCTS                                  */\n/* -------------------------------------------------------------------------- */\n\n/* ------------------------------ CalendarCell ------------------------------ */\n\ntype CalendarCell struct {\n\tDiscovered bool\n\tId         uint16\n\t_          struct{}\n}\n\n/* -------------------------------- Calendar -------------------------------- */\n\ntype Calendar interface {\n\tGetArray2D() [][]CalendarCell\n\tGetFrom() uint16\n\tGetTo() uint16\n\n\tDiscoverDay(day uint16) error\n\tToPrint() string\n}\n\nconst rows uint16 = 4\nconst cols uint16 = 6\n\ntype calendar struct {\n\tarray2D [][]CalendarCell\n\tfrom    uint16\n\tto      uint16\n}\n\nfunc NewCalendar(from uint16, to uint16) Calendar {\n\tvar counter uint16 = from\n\n\tvar calendar calendar = calendar{\n\t\tarray2D: make([][]CalendarCell, rows),\n\t\tfrom:    from,\n\t\tto:      to,\n\t}\n\n\tfor i := range calendar.array2D {\n\t\tcalendar.array2D[i] = make([]CalendarCell, cols)\n\t\tfor j := range calendar.array2D[i] {\n\t\t\tcalendar.array2D[i][j].Id = counter\n\t\t\tcounter++\n\t\t}\n\t}\n\n\treturn &calendar\n}\n\nfunc (calendar *calendar) GetArray2D() [][]CalendarCell {\n\treturn calendar.array2D\n}\n\nfunc (calendar *calendar) GetFrom() uint16 {\n\treturn calendar.from\n}\n\nfunc (calendar *calendar) GetTo() uint16 {\n\treturn calendar.to\n}\n\nfunc (calendar *calendar) DiscoverDay(day uint16) error {\n\tvar i int\n\tvar j int\n\tvar flag bool = false\n\tvar counter uint16 = calendar.from\n\n\tif day < calendar.from || day > calendar.to {\n\t\treturn &CalendarDayOuOfRangeError{\n\t\t\tDay:  day,\n\t\t\tFrom: calendar.from,\n\t\t\tTo:   calendar.to,\n\t\t}\n\t}\n\n\tfor i = 0; counter <= calendar.to && i < len(calendar.array2D); i++ {\n\t\tfor j = 0; counter <= calendar.to && j < len(calendar.array2D[i]); j++ {\n\t\t\tif calendar.array2D[i][j].Id == day {\n\t\t\t\tif calendar.array2D[i][j].Discovered {\n\t\t\t\t\treturn &CalendarCellDiscoveredError{\n\t\t\t\t\t\tCell: calendar.array2D[i][j],\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tcalendar.array2D[i][j].Discovered = true\n\t\t\t\tflag = true\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tcounter++\n\t\t}\n\n\t\tif flag {\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif !flag {\n\t\treturn &CalendarDayNotFoundError{Day: day}\n\t}\n\n\treturn nil\n}\n\nfunc (calendar *calendar) ToPrint() string {\n\tvar calendarPrintable []string = []string{}\n\n\tvar i int\n\tvar j int\n\tvar counter uint16 = calendar.from\n\n\tvar row []CalendarCell\n\tvar col CalendarCell\n\tvar rowPrintable string\n\n\tfor i = 0; counter <= calendar.to && i < len(calendar.array2D); i++ {\n\t\trow = calendar.array2D[i]\n\n\t\trowPrintable = \"\"\n\t\tif i != 0 {\n\t\t\trowPrintable = \"\\n\"\n\t\t}\n\n\t\trowPrintable += strings.TrimSpace(\n\t\t\tstrings.Repeat(\n\t\t\t\tstrings.Repeat(\"*\", 4)+\" \", len(row),\n\t\t\t),\n\t\t) + \"\\n\"\n\n\t\tfor j = 0; counter <= calendar.to && j < len(row); j++ {\n\t\t\tcol = row[j]\n\n\t\t\trowPrintable += \"*\"\n\t\t\tif col.Discovered {\n\t\t\t\trowPrintable += strings.Repeat(\"*\", 2)\n\t\t\t} else {\n\t\t\t\trowPrintable += fmt.Sprintf(\"%02d\", col.Id)\n\t\t\t}\n\t\t\trowPrintable += \"* \"\n\n\t\t\tcounter++\n\t\t}\n\n\t\trowPrintable = strings.TrimSpace(rowPrintable) + \"\\n\"\n\n\t\trowPrintable += strings.TrimSpace(\n\t\t\tstrings.Repeat(\n\t\t\t\tstrings.Repeat(\"*\", 4)+\" \", len(row),\n\t\t\t),\n\t\t)\n\n\t\tif i != len(calendar.array2D)-1 {\n\t\t\trowPrintable += \"\\n\"\n\t\t}\n\n\t\tcalendarPrintable = append(calendarPrintable, rowPrintable)\n\t}\n\n\treturn strings.Join(calendarPrintable, \"\\n\")\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\nfunc main() {\n\tvar calendar Calendar = NewCalendar(1, 24)\n\n\tvar input01 uint16\n\tvar input02 uint16\n\tvar cmd *exec.Cmd\n\n\tvar err error\n\tvar calendarDayOuOfRangeError *CalendarDayOuOfRangeError\n\tvar calendarCellDiscoveredError *CalendarCellDiscoveredError\n\tvar calendarDayNotFoundError *CalendarDayNotFoundError\n\n\tfmt.Printf(\"%s\\n\", calendar.ToPrint())\n\n\tfmt.Println(\n\t\t\"\\n> Available operations...\\n\\n\",\n\t\t\"  1 - Discover day.\\n\",\n\t\t\"  0 - Exit.\",\n\t)\n\n\tfmt.Printf(\"\\n> Enter an operation: \")\n\tfmt.Scanf(\"%d\\n\", &input01)\n\n\tfor input01 != 0 {\n\t\tswitch input01 {\n\t\tcase 1:\n\t\t\tfmt.Printf(\"\\n> Enter the day to discover: \")\n\t\t\tfmt.Scanf(\"%d\\n\", &input02)\n\n\t\t\tcmd = exec.Command(\"clear\")\n\t\t\tcmd.Stdout = os.Stdout\n\t\t\tcmd.Run()\n\n\t\t\terr = calendar.DiscoverDay(input02)\n\t\t\tif err == nil {\n\t\t\t\tfmt.Printf(\"> Day %d discovered!\\n\", input02)\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tif errors.As(err, &calendarDayOuOfRangeError) {\n\t\t\t\tfmt.Printf(\n\t\t\t\t\t\"> The day %d must be between %d and %d (both included)!\",\n\t\t\t\t\tinput02,\n\t\t\t\t\tcalendar.GetFrom(),\n\t\t\t\t\tcalendar.GetTo(),\n\t\t\t\t)\n\t\t\t} else if errors.As(err, &calendarCellDiscoveredError) {\n\t\t\t\tfmt.Printf(\"> The day %d is already discovered!\\n\", input02)\n\t\t\t} else if errors.As(err, &calendarDayNotFoundError) {\n\t\t\t\tfmt.Printf(\"> %d day not found in the calendar!\\n\", input02)\n\t\t\t} else {\n\t\t\t\tfmt.Println(\"> An error occurred on discover the day!\")\n\t\t\t}\n\t\t\tbreak\n\n\t\tdefault:\n\t\t\tcmd = exec.Command(\"clear\")\n\t\t\tcmd.Stdout = os.Stdout\n\t\t\tcmd.Run()\n\n\t\t\tfmt.Println(\"\\n> Invalid operation! Try again...\")\n\t\t}\n\n\t\tfmt.Printf(\"\\n%s\\n\", calendar.ToPrint())\n\n\t\tfmt.Println(\n\t\t\t\"\\n> Available operations...\\n\\n\",\n\t\t\t\"  1 - Discover day.\\n\",\n\t\t\t\"  0 - Exit.\",\n\t\t)\n\n\t\tfmt.Printf(\"\\n> Enter an operation: \")\n\t\tfmt.Scanf(\"%d\\n\", &input01)\n\t}\n}\n"
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/java/JohnAlexGuerrero.java",
    "content": "package org.example;\n\nimport java.util.Scanner;\n\n// Press Shift twice to open the Search Everywhere dialog and type `show whitespaces`,\n// then press Enter. You can now see whitespace characters in your code.\npublic class Main {\n        // * - El calendario mostrará los días del 1 al 24 repartidos\n        // *   en 6 columnas a modo de cuadrícula.\n        //- Cada cuadrícula correspondiente a un día tendrá un tamaño\n        // *   de 4x3 caracteres, y sus bordes serán asteríscos.\n        //* Ejemplo de cuadrículas:\n        //* **** **** ****\n        //* *01* *02* *03* ...\n        //* **** **** ****\n    static int [][] calendar = {\n            {1,2,3,4,5,6}, {7,8,9,10,11,12}, {13,14,15,16,17,18}, {19,20,21,22,23,24}\n    };\n\n    public static void showCalendar(){\n        for(int[] row: calendar){\n            System.out.println(\"**** **** **** **** **** **** \");\n            for(int i: row){\n                String day = (i < 10)? \"0\"+i : \"\"+i;\n                if(i == 0){\n                    day = \"**\";\n                }\n                System.out.printf(\"*\"+day+\"* \");\n            }\n            System.out.println();\n        }\n        System.out.println(\"**** **** **** **** **** **** \");\n        System.out.println();\n    }\n\n    public static boolean avalableDay(int d){\n        for (int i = 0; i < calendar.length; i++){\n            for (int j = 0; j < calendar[i].length; j++){\n                if(calendar[i][j] == d){\n                    selectDayInCalendar(i,j);\n                    return true;\n                }\n            }\n        }\n        return false;\n    }\n\n    public static void selectDayInCalendar(int indexX, int indexY){\n        // *   cubierta de asteríscos (sin mostrar el día).\n        // * Ejemplo de selección del día 1\n        // * **** **** ****\n        // * **** *02* *03* ...\n        // * **** **** ****\n        calendar[indexX][indexY] = 0;\n    }\n\n    public static void main(String[] args) {\n        // Press Alt+Intro with your caret at the highlighted text to see how\n        Scanner scanner = new Scanner(System.in);\n        boolean flag = true;\n\n        while(flag){\n            showCalendar();\n            //* - El usuario seleccioná qué día quiere descubrir.\n            System.out.println(\"select one day or exit: \");\n            String selectDay = scanner.nextLine();\n\n            if(selectDay.equals(\"exit\")){\n                flag = false;\n            }\n\n            try{\n                int selectedDay = Integer.parseInt(selectDay);\n\n                //Si está sin descubrir, se le dirá que ha abierto ese día\n                if(avalableDay(selectedDay)){\n                    System.out.println(\"This day is avalable.\");\n                }else{\n                    //* - Si se selecciona un número ya descubierto, se le notifica\n                    // *   al usuario.\n                    System.out.println(\"Day is not avalable.\");\n                }\n\n            }catch(NumberFormatException ex){\n                System.out.println(\"select on number.\");\n            }\n        }\n\n        // *   y se mostrará de nuevo el calendario con esa cuadrícula\n\n    }\n}"
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/java/Josegs95.java",
    "content": "import java.util.ArrayList;\nimport java.util.List;\nimport java.util.Scanner;\n\npublic class Josegs95 {\n    public static void main(String[] args) {\n        new Josegs95().adventCalendar();\n    }\n\n    final private Scanner sc = new Scanner(System.in);\n    private List<Integer> calendar;\n\n    public void adventCalendar(){\n        initCalendar();\n\n        try(sc){\n            while(true){\n                printCalendar();\n                int option = askDayToUser();\n                if (option == 0) {\n                    System.out.println(\"Saliendo de la aplicación...\");\n                    break;\n                }\n\n                openDay(option);\n                System.out.println();\n            }\n        }\n    }\n\n    private Integer askDayToUser(){\n        boolean validDay = false;\n        Integer option = 0;\n        do{\n            try{\n                System.out.print(\"Selecciona un día del calendario (0 para salir): \");\n                option = Integer.parseInt(sc.nextLine());\n                if (option < 0 || option > 24)\n                    System.out.println(\"Debe elegir un número del 1-24\");\n                else\n                    validDay = true;\n            } catch (NumberFormatException e) {\n                System.out.println(\"Introduzca un número entero por favor\");\n            }\n        }while(!validDay);\n\n        return option;\n    }\n\n    private void openDay(Integer day){\n        if (!calendar.contains(day)){\n            System.out.println(\"El día \" + day + \" ya se ha descubierto\");\n        }\n\n        calendar.remove(day);\n    }\n\n    private void initCalendar(){\n        calendar = new ArrayList<>();\n\n        for (Integer i = 1; i < 25; i++){\n            calendar.add(i);\n        }\n    }\n\n    private void printCalendar(){\n        int dayCount = 1;\n        for (int row = 0; row < 4; row++){\n            for (int aux = 0; aux < 3; aux++){\n                for (int column = 0; column < 6; column++){\n                    if (aux % 2 == 0)\n                        System.out.print(\"**** \");\n                    else{\n                        if (calendar.contains(dayCount))\n                            System.out.print(\"*\" + getFormattedDay(dayCount++) + \"* \");\n                        else{\n                            System.out.print(\"**** \");\n                            dayCount++;\n                        }\n                    }\n\n                }\n                System.out.println();\n            }\n            System.out.println();\n        }\n    }\n\n    private String getFormattedDay(int day){\n        return String.format(\"%02d\", day);\n    }\n}"
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/java/MohamedElderkaoui.java",
    "content": "import java.util.*;\n\npublic class MohamedElderkaoui {\n\n    // Lista de regalos para los días\n    static final String[] prices = {\n            \"Curso de lógica de programación\", \"Diplomado sobre Metodologías Ágiles\", \n            \"Desarrollo de interfaces con Qt4\", \"Introducción a la programación funcional\", \n            \"Desarrollo en C#\", \"Buenas prácticas de programación en Java Springboot\", \n            \"¿Cómo hacer Smart Commits?\", \"Uso básico de la terminal Linux\", \n            \"Primeros pasos en Django Rest Framework (DRF)\", \n            \"Práctica aplicada de los patrones SOLID en Java\", \n            \"Introducción de Base de Datos\", \"Buenas prácticas dentro de Python\", \n            \"Paradigma de Metodologías Tradicionales ¿Aún tienen uso? ¿En qué casos es aplicable?\", \n            \"Data Science con Python y R\", \"GO ¿El lenguaje del futuro?\", \n            \"Patrones de Diseño de Software aplicados en Python\", \n            \"Algoritmos de optimización aplicados en C++\", \n            \"Fundamentos de la Inteligencia Artificial\", \n            \"Aplicación en la actualidad del IoT\", \n            \"Uso de librería numpy y pandas dentro de Python\", \n            \"POO aplicada en Java\", \"0 a héroe en PostgreSQL\", \n            \"Generación de servicios REST con AWS Api Gateway y Lambda\"\n    };\n\n    public static void main(String[] args) {\n        // Array para rastrear los días descubiertos\n        boolean[] discovered = new boolean[24];\n        Scanner scanner = new Scanner(System.in);\n\n        while (true) {\n            printCalendar(discovered);\n            System.out.println(\"Ingrese el día que quiere descubrir (1-24) o 0 para salir:\");\n            \n            int dia;\n            try {\n                dia = scanner.nextInt();\n                if (dia == 0) {\n                    System.out.println(\"¡Gracias por participar en el aDEViento! 🎉\");\n                    break;\n                }\n                if (dia < 1 || dia > 24) {\n                    System.out.println(\"⚠️ El día debe estar entre 1 y 24.\");\n                    continue;\n                }\n\n                // Revisar si el día ya está descubierto\n                if (discovered[dia - 1]) {\n                    System.out.println(\"⚠️ Ya has descubierto este día.\");\n                } else {\n                    discovered[dia - 1] = true; // Marcar como descubierto\n                    System.out.println(\"🎁 Regalo del día \" + dia + \": \" + prices[dia - 1]);\n                }\n            } catch (InputMismatchException e) {\n                System.out.println(\"⚠️ Entrada no válida. Debes ingresar un número.\");\n                scanner.next(); // Limpiar el scanner\n            }\n        }\n        scanner.close();\n    }\n\n    // Método para imprimir el calendario\n    private static void printCalendar(boolean[] discovered) {\n        System.out.println(\"Calendario de aDEViento:\");\n        for (int i = 0; i < 24; i++) {\n            if (i % 6 == 0) System.out.println(); // Nueva fila cada 6 días\n\n            if (discovered[i]) {\n                // Si el día ya está descubierto, mostramos cuadrícula llena\n                System.out.print(\"**** \");\n            } else {\n                // Mostrar día con formato\n                System.out.printf(\"*%02d* \", i + 1);\n            }\n        }\n        System.out.println(\"\\n\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/java/alb-martinez.java",
    "content": "import java.util.Scanner;\n\npublic class alb-martinez {\n\n    private static final int TOTAL_DAYS = 24;\n    private static final int ROWS = 4;\n    private static final int COLS = 6;\n\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n\n        // Inicialización de los días (false = cerrado; true = abierto)\n        boolean[] openDays = new boolean[TOTAL_DAYS];\n\n        // Mostrar calendario inicial\n        showCalendar(openDays);\n\n        // Código para permitir al usuario seleccionar un día\n        while (true) {\n            int selectedDay = getUserSelection(scanner);\n\n            if (selectedDay == 0) {\n                break;\n            }\n\n            handleDaySelection(openDays, selectedDay);\n\n            showCalendar(openDays);\n\n        }\n    }\n\n    // Solicita y devuelve la selección del usuario\n    private static int getUserSelection(Scanner scanner) {\n        int selectedDay;\n\n        while (true) {\n            System.out.println(\"Selecciona un día (1-24) para abrir, o 0 para salir:\");\n\n            // Verificar si el input es un número\n            if (scanner.hasNextInt()) {\n                selectedDay = scanner.nextInt();\n                // Validar que el número esté en el rango permitido\n                if (selectedDay >= 0 && selectedDay <= TOTAL_DAYS) {\n                    break;\n                } else {\n                    System.out.println(\"¡Entrada inválida! Ingresa un número entre 1 y 24, o 0 para salir.\");\n                }\n            } else {\n                // Si el input no es un número, lo ignoramos y pedimos uno nuevo\n                System.out.println(\"¡Entrada inválida! Debes ingresar un número.\");\n                scanner.next();\n            }\n        }\n\n        return selectedDay;\n    }\n\n    // Maneja la selección de un día\n    private static void handleDaySelection(boolean[] openDays, int selectedDay) {\n        // Comprobar si el día ya está abierto\n        if (openDays[selectedDay - 1]) {\n            System.out.println(\"¡Este día ya está abierto!\");\n        } else {\n            openDays[selectedDay - 1] = true;\n            System.out.println(\"¡Has abierto el día \" + selectedDay + \"!\");\n        }\n    }\n\n    // Método para mostrar el calendario\n    private static void showCalendar(boolean[] openDays) {\n        for (int row = 0; row < ROWS; row++) {\n            printGridBorders();\n            printDaysInRow(row, openDays);\n            printGridBorders();\n        }\n    }\n\n    // Imprimir los bordes de la cuadrícula (superior e inferior)\n    private static void printGridBorders() {\n        for (int col = 0; col < COLS; col++) {\n            System.out.print(\"**** \");\n        }\n        System.out.println();\n    }\n\n    // Imprimir los días en una fila\n    private static void printDaysInRow(int row, boolean[] openDays) {\n        for (int col = 0; col < COLS; col++) {\n            int dayIndex = row * COLS + col;\n            if (dayIndex >= TOTAL_DAYS) break;\n\n            // Si el día está abierto, mostramos \"****\", de lo contrario el número del día\n            if (openDays[dayIndex]) {\n                System.out.print(\"**** \");\n            } else {\n                System.out.print(\"*\" + (dayIndex + 1 < 10 ? \"0\" + (dayIndex + 1) : (dayIndex + 1)) + \"* \");\n            }\n        }\n        System.out.println();\n    }\n}\n"
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/java/asjordi.java",
    "content": "import java.util.Scanner;\n\npublic class Main {\n\n    private static final int FILAS = 4;\n    private static final int COLUMNAS = 6;\n    private static final int DIAS = 24;\n    private boolean[] descubiertos = new boolean[DIAS];\n\n    public static void main(String[] args) {\n        Main m = new Main();\n        Scanner sc = new Scanner(System.in);\n\n        while (true) {\n            m.dibujarCalendario();\n            System.out.print(\"Selecciona un día para descubrir (1-24) o 0 para salir: \");\n            int dia = sc.nextInt();\n            if (dia == 0) break;\n            m.seleccionarDia(dia);\n        }\n\n        sc.close();\n    }\n\n    public void dibujarCalendario() {\n        for (int i = 0; i < FILAS; i++) {\n            for (int j = 0; j < COLUMNAS; j++) {\n                int dia = i * COLUMNAS + j + 1;\n                if (dia > DIAS) break;\n                System.out.print(\"**** \");\n            }\n            System.out.println();\n            for (int j = 0; j < COLUMNAS; j++) {\n                int dia = i * COLUMNAS + j + 1;\n                if (dia > DIAS) break;\n                if (descubiertos[dia - 1]) {\n                    System.out.print(\"**** \");\n                } else {\n                    System.out.printf(\"*%02d* \", dia);\n                }\n            }\n            System.out.println();\n            for (int j = 0; j < COLUMNAS; j++) {\n                int dia = i * COLUMNAS + j + 1;\n                if (dia > DIAS) break;\n                System.out.print(\"**** \");\n            }\n            System.out.println();\n            System.out.println();\n        }\n    }\n\n    public void seleccionarDia(int dia) {\n        if (dia < 1 || dia > DIAS) {\n            System.out.println(\"Día inválido.\");\n            return;\n        }\n        if (descubiertos[dia - 1]) {\n            System.out.println(\"El día \" + dia + \" ya ha sido descubierto.\");\n        } else {\n            descubiertos[dia - 1] = true;\n            System.out.println(\"Has descubierto el día \" + dia + \"!\");\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/java/miguelex.java",
    "content": "import java.util.Scanner;\n\npublic class miguelex {\n\n    private static final int GRID_WIDTH = 4;\n    private static final int GRID_HEIGHT = 3;\n    private static final int DAYS = 24;\n    private static boolean[] discovered = new boolean[DAYS];\n\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n\n        while (true) {\n            drawCalendar();\n\n            System.out.print(\"\\nSeleccione un día (1-\" + DAYS + \") para descubrir o escriba 0 para salir: \");\n            String input = scanner.nextLine();\n\n            if (input.equals(\"0\")) {\n                System.out.println(\"¡Gracias por participar en el aDEViento!\");\n                break;\n            }\n\n            try {\n                int day = Integer.parseInt(input);\n                if (day < 1 || day > DAYS) {\n                    System.out.println(\"Por favor, elija un número válido entre 1 y \" + DAYS + \".\");\n                } else if (discovered[day - 1]) {\n                    System.out.println(\"El día \" + day + \" ya ha sido descubierto.\");\n                } else {\n                    discovered[day - 1] = true;\n                    System.out.println(\"¡Has descubierto el día \" + day + \"!\");\n                }\n            } catch (NumberFormatException e) {\n                System.out.println(\"Entrada inválida. Por favor, ingrese un número válido.\");\n            }\n        }\n\n        scanner.close();\n    }\n\n    private static void drawCalendar() {\n        for (int row = 0; row < Math.ceil(DAYS / 6.0); row++) {\n            for (int line = 0; line < GRID_HEIGHT; line++) {\n                StringBuilder rowOutput = new StringBuilder();\n\n                for (int col = 0; col < 6; col++) {\n                    int day = row * 6 + col + 1;\n                    if (day > DAYS) break;\n\n                    switch (line) {\n                        case 0, 2 -> rowOutput.append(\"**** \");\n                        case 1 -> {\n                            rowOutput.append(\"*\");\n                            if (discovered[day - 1]) {\n                                rowOutput.append(\"**\");\n                            } else {\n                                String dayStr = String.format(\"%02d\", day);\n                                rowOutput.append(dayStr);\n                            }\n                            rowOutput.append(\"* \");\n                        }\n                    }\n                }\n                System.out.println(rowOutput);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #47 - JavaScript -> Jesus Antonio Escamilla */\n\n/**\n * CALENDARIO DE ADVIENTO.\n * Utilizando la Terminal para pedir datos y agregarlos.\n */\n\nconst readline = require('readline');\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout,\n});\n\nconst DAYS = 24;\n\nconst calendar = Array.from({ length: DAYS }, (_, i) => ({\n    day: (i + 1).toString().padStart(2, '0'),\n    discovered: false,\n}));\n\nfunction drawCalendar() {\n    let output = '';\n\n    for (let i = 0; i < DAYS; i += 6) {\n        output += '**** '.repeat(6).trim() + '\\n';\n\n        output += calendar\n            .slice(i, i + 6)\n            .map((cell) => (cell.discovered ? '****' : `*${cell.day}*`))\n            .join(' ') + '\\n';\n\n        output += '**** '.repeat(6).trim() + '\\n';    \n    }\n\n    console.log(output);\n}\n\nfunction discoverDay(day) {\n    const index = day - 1;\n\n    if (index < 0 || index >= DAYS) {\n        console.log(\"Por favor, selecciona un número entre 1 y 24.\\n\");\n        return;\n    }\n\n    if (calendar[index].discovered) {\n        console.log(`El dia ${day} ya ha sido descubierto\\n`);\n    } else {\n        console.log(`¡Has abierto el dia ${day}!\\n`);\n        calendar[index].discovered = true;\n    }\n}\n\nfunction runCalendar() {\n    drawCalendar();\n    rl.question('Selecciona una dia par abrir (1-24): ', (input) => {\n        if (input.toLowerCase() == \" \") {\n            rl.close();\n            return;\n        }\n\n        const day = parseInt(input, 10);\n\n        if (!isNaN(day) && day >= 1 && day <= 25) {\n            discoverDay(day);\n        }else {\n            console.log(\"Por favor, ingresa un número válido.\\n\");\n        }\n\n        runCalendar();\n    });\n}\n\n// Mostrar el calendario de adviento\nconsole.log('¡Bienvenido al calendario del aDEViento!');\nrunCalendar();"
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/javascript/MohamedElderkaoui.js",
    "content": "const prices = [\n    \"Curso de lógica de programación\", \"Diplomado sobre Metodologías Ágiles\",\n    \"Desarrollo de interfaces con Qt4\", \"Introducción a la programación funcional\",\n    \"Desarrollo en C#\", \"Buenas prácticas de programación en Java Springboot\",\n    \"¿Cómo hacer Smart Commits?\", \"Uso básico de la terminal Linux\",\n    \"Primeros pasos en Django Rest Framework (DRF)\",\n    \"Práctica aplicada de los patrones SOLID en Java\",\n    \"Introducción de Base de Datos\", \"Buenas prácticas dentro de Python\",\n    \"Paradigma de Metodologías Tradicionales ¿Aún tienen uso? ¿En qué casos es aplicable?\",\n    \"Data Science con Python y R\", \"GO ¿El lenguaje del futuro?\",\n    \"Patrones de Diseño de Software aplicados en Python\",\n    \"Algoritmos de optimización aplicados en C++\",\n    \"Fundamentos de la Inteligencia Artificial\",\n    \"Aplicación en la actualidad del IoT\",\n    \"Uso de librería numpy y pandas dentro de Python\",\n    \"POO aplicada en Java\", \"0 a héroe en PostgreSQL\",\n    \"Generación de servicios REST con AWS Api Gateway y Lambda\"\n];\n\n// Array para rastrear los días descubiertos\nconst discovered = Array(24).fill(false);\n\n// Función para imprimir el calendario\nfunction printCalendar() {\n    console.clear();\n    console.log(\"Calendario de aDEViento:\");\n    for (let i = 0; i < 24; i++) {\n        if (i % 6 === 0) console.log(); // Nueva fila cada 6 días\n\n        if (discovered[i]) {\n            // Mostrar cuadrícula llena si el día está descubierto\n            process.stdout.write(\"**** \");\n        } else {\n            // Mostrar cuadrícula con el número del día\n            process.stdout.write(`*${String(i + 1).padStart(2, '0')}* `);\n        }\n    }\n    console.log(\"\\n\");\n}\n\n// Función principal\nfunction startAdventCalendar() {\n    while (true) {\n        printCalendar();\n\n        let input = prompt(\"Ingrese el día que quiere descubrir (1-24) o 0 para salir:\");\n        if (input === null) break; // Salir si el usuario cierra el prompt\n\n        const day = parseInt(input, 10);\n\n        if (isNaN(day)) {\n            console.log(\"⚠️ Entrada no válida. Debes ingresar un número.\");\n            continue;\n        }\n\n        if (day === 0) {\n            console.log(\"¡Gracias por participar en el aDEViento! 🎉\");\n            break;\n        }\n\n        if (day < 1 || day > 24) {\n            console.log(\"⚠️ El día debe estar entre 1 y 24.\");\n            continue;\n        }\n\n        if (discovered[day - 1]) {\n            console.log(`⚠️ El día ${day} ya ha sido descubierto.`);\n        } else {\n            discovered[day - 1] = true;\n            console.log(`🎁 Regalo del día ${day}: ${prices[day - 1]}`);\n        }\n    }\n}\n\n// Iniciar el calendario\nstartAdventCalendar();\n"
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/javascript/RaulDoezon.js",
    "content": "/*\n  EJERCICIO:\n  ¡Cada año celebramos el aDEViento! 24 días, 24 regalos para\n  developers. Del 1 al 24 de diciembre: https://adviento.dev\n\n  Dibuja un calendario por terminal e implementa una\n  funcionalidad para seleccionar días y mostrar regalos.\n  - El calendario mostrará los días del 1 al 24 repartidos\n    en 6 columnas a modo de cuadrícula.\n  - Cada cuadrícula correspondiente a un día tendrá un tamaño \n    de 4x3 caracteres, y sus bordes serán asteríscos.\n  - Las cuadrículas dejarán un espacio entre ellas.\n  - En el medio de cada cuadrícula aparecerá el día entre el\n    01 y el 24.\n \n  Ejemplo de cuadrículas:\n  **** **** ****\n  *01* *02* *03* ...\n  **** **** ****\n \n  - El usuario seleccioná qué día quiere descubrir.\n  - Si está sin descubrir, se le dirá que ha abierto ese día\n    y se mostrará de nuevo el calendario con esa cuadrícula\n    cubierta de asteríscos (sin mostrar el día).\n \n  Ejemplo de selección del día 1\n  **** **** ****\n  **** *02* *03* ...\n  **** **** ****\n\n  - Si se selecciona un número ya descubierto, se le notifica\n    al usuario.\n*/\n\nclass Calendar {\n  constructor() {\n    this.daysRevealed = [];\n  }\n\n  build() {\n    let dayCounter = 1;\n\n    console.log(\"********* aDEViento 2024 *********\");\n\n    for ( let row = 0; row < 4; row++) {\n      let top = \"\";\n      let center = \"\";\n      let bottom = \"\";\n\n      for ( let column = 0; column < 6; column++) {\n        let findDay = this.daysRevealed.findIndex((number) => number === dayCounter);\n        let dayNumber = `${findDay === -1 ? `*${dayCounter < 10 ? 0 : ''}${dayCounter}*` : \"****\"}`;\n\n        top = top + \" \" + \"****\";\n        center = center + \" \" + dayNumber;\n        bottom = bottom + \" \" + \"****\";\n        dayCounter++;\n      }\n\n      console.log(top);\n      console.log(center);\n      console.log(bottom);\n      console.log(\"\\n\");\n    }\n  }\n\n  reveal(day) {\n    if (day > 0 && day <= 24) {\n      const checkDay = this.daysRevealed.findIndex((number) => number === day);\n\n      if (checkDay === -1) {\n        this.daysRevealed.push(day);\n\n        alert(`Revelaste el número: ${day}`);\n      } else {\n        alert(\"El día ingresado ya fue revelado.\");\n      }\n    } else {\n      alert(\"Debes ingresar un número que esté dentro del rango\");\n    }\n  }\n\n  markDay() {\n    let menu = 0;\n\n    do {\n      menu = parseInt(prompt(\"1). Selecciona un día del calendario.\\n2). Cerrar el calendario.\"), 10);\n\n      this.build();\n\n      switch (menu) {\n        case 1:\n          let selectDay = parseInt(prompt(\"Ingresa un número del 01 al 24\"), 10);\n\n          this.reveal(selectDay);\n\n          break;\n\n        case 2:\n          alert(\"Cerrando el calendario...\");\n\n          break;\n\n        default:\n          alert(\"Ingresa alguno de los números 1 o 2.\");\n\n          break;\n      }\n    } while (menu !== 2);\n  }\n}\n\nlet calendar = new Calendar();\n\ncalendar.markDay();\n"
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/javascript/duendeintemporal.js",
    "content": "//#47 - CALENDARIO DE ADVIENTO \n/*\n * EJERCICIO:\n * ¡Cada año celebramos el aDEViento! 24 días, 24 regalos para\n * developers. Del 1 al 24 de diciembre: https://adviento.dev\n *\n * Dibuja un calendario por terminal e implementa una\n * funcionalidad para seleccionar días y mostrar regalos.\n * - El calendario mostrará los días del 1 al 24 repartidos\n *   en 6 columnas a modo de cuadrícula.\n * - Cada cuadrícula correspondiente a un día tendrá un tamaño\n *   de 4x3 caracteres, y sus bordes serán asteríscos.\n * - Las cuadrículas dejarán un espacio entre ellas.\n * - En el medio de cada cuadrícula aparecerá el día entre el\n *   01 y el 24.\n *\n * Ejemplo de cuadrículas:\n * **** **** ****\n * *01* *02* *03* ...\n * **** **** ****\n *\n * - El usuario seleccioná qué día quiere descubrir.\n * - Si está sin descubrir, se le dirá que ha abierto ese día\n *   y se mostrará de nuevo el calendario con esa cuadrícula\n *   cubierta de asteríscos (sin mostrar el día).\n *\n * Ejemplo de selección del día 1\n * **** **** ****\n * **** *02* *03* ...\n * **** **** ****\n *\n * - Si se selecciona un número ya descubierto, se le notifica\n *   al usuario.\n */\n\nlet log = console.log;\n\nconst readline = require('readline');\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nfunction drawCalendar(discoveredDays) {\n    const COLUMNS_COUNT = 6;\n    const CELL_WIDTH = 4;\n    const CELL_HEIGHT = 3;\n\n    let calendar = '';\n\n    for (let row = 0; row < CELL_HEIGHT; row++) {\n        for (let day = 1; day <= 24; day++) {\n            if (row === 1) {\n                calendar += discoveredDays.includes(day) ? '*'.repeat(CELL_WIDTH) : `*${String(day).padStart(2, '0')}*`;\n            } else {\n                calendar += '*'.repeat(CELL_WIDTH);\n            }\n            if (day % COLUMNS_COUNT === 0) {\n                calendar += '\\n';\n            } else {\n                calendar += ' ';\n            }\n        }\n        calendar += '\\n';\n    }\n\n    return calendar;\n}\n\nfunction handleUserInput(discoveredDays) {\n    return new Promise((resolve) => {\n        rl.question('Enter the day you want to discover (1-24):', (input) => {\n            const day = parseInt(input, 10);\n\n            if (isNaN(day) || day < 1 || day > 24) {\n                log('\\nInvalid day. Please enter a number between 1 and 24.\\n');\n                return resolve(discoveredDays);\n            }\n\n            if (discoveredDays.includes(day)) {\n                log(`\\nDay ${day} has already been discovered.\\n`);\n                return resolve(discoveredDays);\n            } else {\n                log(`\\nGift of the day ${day}: ${prices[day - 1]} 🎁 `);\n            }\n\n            log(`\\nYou have discovered day ${day}!\\n`);\n            return resolve([...discoveredDays, day]);\n        });\n    });\n}\n\nasync function main() {\n    let discoveredDays = [];\n\n    while (discoveredDays.length < 24) {\n        log('\\n     Adviento Calendar!\\n');\n        log(drawCalendar(discoveredDays));\n        discoveredDays = await handleUserInput(discoveredDays);\n    }\n\n    log('\\n     Adviento Calendar!\\n');\n    log(drawCalendar(discoveredDays));\n    log('Congratulations! You have discovered all 24 days.');\n    rl.close();\n}\n\nconst prices = [\n    \"$29.99 and Basic Linux Terminal Usage course\",\n    \"$39.99 and How to Perform Smart Commits? course\",\n    \"$49.99 and Introduction to Programming Logic course\",\n    \"$49.99 and Database Fundamentals course\",\n    \"$49.99 and Best Practices in Python course\",\n    \"$59.99 and Functional Programming Fundamentals course\",\n    \"$59.99 and IoT: Current Applications course\",\n    \"$69.99 and Software Design Patterns in Python course\",\n    \"$69.99 and 0 to Hero in PostgreSQL course\",\n    \"$79.99 and Qt4 Interface Development course\",\n    \"$79.99 and Applying SOLID Patterns in Java course\",\n    \"$79.99 and Go: The Language of the Future? course\",\n    \"$89.99 and C# Development course\",\n    \"$89.99 and Artificial Intelligence Fundamentals course\",\n    \"$99.99 and Agile Methodologies Diploma course\",\n    \"$99.99 and Django Rest Framework (DRF) Primer course\",\n    \"$99.99 and Optimization Algorithms in C++ course\",\n    \"$109.99 and Building REST Services with AWS API Gateway and Lambda course\",\n    \"$119.99 and Data Science with Python and R course\",\n    \"$79.99 and Object-Oriented Programming in Java course\",\n    \"$89.99 and Traditional Methodologies Paradigm: Still Relevant? Applicable Cases course\",\n    \"$69.99 and NumPy and Pandas in Python course\",\n    \"$59.99 and Blockchain Fundamentals course\",\n    \"$79.99 and Microservices Architecture with Spring Boot course\",\n    \"$89.99 and Ethical Hacking and Cybersecurity Essentials course\"\n];\n\n\nmain();\n"
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/javascript/hectorio23.js",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\nconst TOTAL_DAYS = 24;\nconst COLUMNS = 6;\nconst GRID_WIDTH = 4;\nconst GRID_HEIGHT = 3;\n\n// Función para dibujar el calendario\nfunction drawCalendar(openedDays) {\n    for (let row = 0; row < TOTAL_DAYS / COLUMNS; row++) {\n        for (let h = 0; h < GRID_HEIGHT; h++) { // Cada fila de la cuadrícula\n            let line = \"\";\n\n            for (let col = 0; col < COLUMNS; col++) {\n                const day = row * COLUMNS + col + 1;\n\n                if (h === 0 || h === GRID_HEIGHT - 1) {\n                    // Bordes superior e inferior\n                    line += \"**** \";\n                } else if (h === Math.floor(GRID_HEIGHT / 2)) {\n                    // Línea central con el número del día o asteriscos si está descubierto\n                    if (openedDays[day - 1]) {\n                        line += \"**** \";\n                    } else {\n                        line += `*${String(day).padStart(2, '0')}* `;\n                    }\n                } else {\n                    // Espaciado intermedio\n                    line += \"*  * \";\n                }\n            }\n            console.log(line);\n        }\n    }\n}\n\n// Programa principal\nfunction main() {\n    const readline = require('readline');\n    const rl = readline.createInterface({\n        input: process.stdin,\n        output: process.stdout\n    });\n\n    const openedDays = new Array(TOTAL_DAYS).fill(false);\n\n    console.log(\"\\nBienvenido al calendario de aDEViento!\\n\");\n\n    function askUser() {\n        drawCalendar(openedDays);\n        rl.question(\"\\nSelecciona un día (1-24) o escribe 'salir' para terminar: \", (userInput) => {\n            if (userInput.toLowerCase() === \"salir\") {\n                console.log(\"Gracias por participar!\\n\");\n                rl.close();\n                return;\n            }\n\n            // Validar la entrada\n            const selectedDay = parseInt(userInput, 10);\n            if (isNaN(selectedDay)) {\n                console.log(\"Entrada no válida. Inténtalo de nuevo.\\n\");\n                return askUser();\n            }\n\n            if (selectedDay < 1 || selectedDay > TOTAL_DAYS) {\n                console.log(\"Número fuera de rango. Inténtalo de nuevo.\\n\");\n                return askUser();\n            }\n\n            // Verificar el estado del día seleccionado\n            if (openedDays[selectedDay - 1]) {\n                console.log(`El día ${selectedDay} ya ha sido descubierto.\\n`);\n            } else {\n                openedDays[selectedDay - 1] = true;\n                console.log(`Has descubierto el día ${selectedDay}! Felicidades!\\n`);\n            }\n            askUser();\n        });\n    }\n\n    askUser();\n}\n\nmain();\n"
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n_______________________________________________________\n#47 CALENDARIO DE ADVIENTO\n-------------------------------------------------------\n* EJERCICIO:\n * ¡Cada año celebramos el aDEViento! 24 días, 24 regalos para\n * developers. Del 1 al 24 de diciembre: https://adviento.dev\n * \n * Dibuja un calendario por terminal e implementa una\n * funcionalidad para seleccionar días y mostrar regalos.\n * - El calendario mostrará los días del 1 al 24 repartidos\n *   en 6 columnas a modo de cuadrícula.\n * - Cada cuadrícula correspondiente a un día tendrá un tamaño \n *   de 4x3 caracteres, y sus bordes serán asteríscos.\n * - Las cuadrículas dejarán un espacio entre ellas.\n * - En el medio de cada cuadrícula aparecerá el día entre el\n *   01 y el 24.\n *\n * Ejemplo de cuadrículas:\n * **** **** ****\n * *01* *02* *03* ...\n * **** **** ****\n *\n * - El usuario seleccioná qué día quiere descubrir.\n * - Si está sin descubrir, se le dirá que ha abierto ese día\n *   y se mostrará de nuevo el calendario con esa cuadrícula\n *   cubierta de asteríscos (sin mostrar el día).\n *\n * Ejemplo de selección del día 1\n * **** **** ****\n * **** *02* *03* ...\n * **** **** ****\n *   \n * - Si se selecciona un número ya descubierto, se le notifica\n *   al usuario.\n */\n// ________________________________________________________\n\nconst readlineSync = require('readline-sync');\n\nlet mtx = [];\nfor (let i = 0; i < 4; i++) {\n    let row = [];\n    for (let j = 0; j < 6; j++) {\n        row.push(`*${(i * 6 + j + 1).toString().padStart(2, '0')}*`);\n    }\n    mtx.push(row);\n}\n\nconst ln = \"**** \".repeat(6) + \"\\n\";\n\nfunction printMatrix() {\n    mtx.forEach(row => {\n        console.log(ln + row.join(\" \") + \"\\n\" + ln);\n    });\n}\n\nwhile (true) {\n    printMatrix();\n\n    let day = readlineSync.question(\"A descubrir: \");\n    \n    if (day.match(/^\\d+$/) && parseInt(day) > 0 && parseInt(day) <= 24) {\n        let r = Math.floor((parseInt(day) - 1) / 6);\n        let c = (parseInt(day) - 1) % 6;\n\n        if (mtx[r][c] === \"****\") {\n            console.log(`El día ${day} ya está descubierto.`);\n        } else {\n            mtx[r][c] = \"****\";\n        }\n    } else {\n        console.log(\"Día inválido, debe ser entre 1 y 24.\");\n    }\n}\n"
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/javascript/miguelex.js",
    "content": "const GRID_WIDTH = 4;\nconst GRID_HEIGHT = 3;\nconst DAYS = 24;\n\nconst discovered = Array(DAYS).fill(false);\n\nfunction drawCalendar(discovered) {\n    for (let row = 0; row < Math.ceil(DAYS / 6); row++) {\n        for (let line = 0; line < GRID_HEIGHT; line++) {\n            let rowOutput = \"\";\n            for (let col = 0; col < 6; col++) {\n                const day = row * 6 + col + 1;\n                if (day > DAYS) break;\n\n                switch (line) {\n                    case 0:\n                    case 2:\n                        rowOutput += \"*\".repeat(GRID_WIDTH) + \" \";\n                        break;\n                    case 1:\n                        rowOutput += \"*\";\n                        rowOutput += discovered[day - 1] \n                            ? \"*\".repeat(GRID_WIDTH - 2) \n                            : day.toString().padStart(2, \"0\").padEnd(GRID_WIDTH - 2, \" \");\n                        rowOutput += \"* \";\n                        break;\n                }\n            }\n            console.log(rowOutput);\n        }\n    }\n}\n\nconst readline = require(\"readline\");\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nfunction promptUser() {\n    drawCalendar(discovered);\n\n    rl.question(`\\nSeleccione un día (1-${DAYS}) para descubrir o escriba 0 para salir: `, (input) => {\n        const day = parseInt(input, 10);\n\n        if (day === 0) {\n            console.log(\"¡Gracias por participar en el aDEViento!\");\n            rl.close();\n            return;\n        }\n\n        if (isNaN(day) || day < 1 || day > DAYS) {\n            console.log(`Por favor, elija un número válido entre 1 y ${DAYS}.`);\n        } else if (discovered[day - 1]) {\n            console.log(`El día ${day} ya ha sido descubierto.`);\n        } else {\n            discovered[day - 1] = true;\n            console.log(`¡Has descubierto el día ${day}!`);\n        }\n\n        promptUser();\n    });\n}\n\npromptUser();\n"
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/javascript/siderio2.js",
    "content": "/**\n * @author Desiderio Martínez Silva aka siderio2\n * @version 1.0\n * @description \"Javascript implementation of the Advent Calendar exercise 48 from MoureDev Roadmap\"\n * @see https://retosdeprogramacion.com/roadmap/\n *\n */\n\n/**\n * Module for reading data from the terminal\n *\n * @see https://nodejs.org/api/readline.html\n */\nconst readline = require(\"readline\");\n\nclass AdventCalendar {\n  /**\n   * Constructor for the advent calendar class\n   *\n   * @returns {AdventCalendar}\n   *\n   * @property {Array<string>} calendar - Array of strings representing the days of the advent calendar\n   * @property {Set<number>} openedDays - Set of numbers representing the days that have been opened\n   * @property {Object} rl - Instance of the readline module to read data from the terminal\n   */\n  constructor() {\n    this.calendar = [];\n    this.openedDays = new Set();\n    this.rl = readline.createInterface({\n      input: process.stdin,\n      output: process.stdout,\n    });\n  }\n\n  /**\n   * Populates the calendar array with string representations of days 1-24.\n   * Each day is represented as a two-character string, with a leading zero for days 1-9.\n   */\n  populateCalendar() {\n    for (let i = 1; i <= 24; i++) {\n      if (i < 10) {\n        this.calendar.push(\"0\" + i.toString());\n        continue;\n      }\n      this.calendar.push(i.toString());\n    }\n  }\n\n  /**\n   * Prints the advent calendar to the console.\n   *\n   * Each day is represented as a two-character string, with a leading zero for days 1-9.\n   * Opened days are represented as '**** ' and unopened days are represented as '*XX* '.\n   * The calendar is printed as a 4x6 grid of strings, with a space between each day and a newline between each row.\n   */\n  printCalendar() {\n    process.stdout.write(\"\\n\");\n    for (let i = 0; i < 4; i++) {\n      process.stdout.write(\"**** \".repeat(6) + \"\\n\");\n      for (let j = 0; j < 6; j++) {\n        const day = this.calendar[i * 6 + j];\n        process.stdout.write(\n          this.openedDays.has(parseInt(day)) ? \"**** \" : \"*\" + day + \"* \"\n        );\n      }\n      process.stdout.write(\"\\n\" + \"**** \".repeat(6) + \"\\n\\n\");\n    }\n  }\n\n  /**\n   * Prints the days that have been opened to the console.\n   *\n   * If no days have been opened, prints \"Ninguno día abierto todavía.\".\n   * Otherwise, prints a comma-separated list of the opened days.\n   */\n  printOpenedDays() {\n    if (this.openedDays.size == 0) {\n      console.log(\"Ninguno día abierto todavía.\\n\");\n      return;\n    }\n    console.log(\"Días abiertos: \" + [...this.openedDays].join(\", \") + \"\\n\");\n  }\n\n  /**\n   * Asks the user which day they want to open, and then opens that day\n   * and prints the updated calendar and list of opened days.\n   * If the user enters 'x', the program exits.\n   * If the user enters a non-integer, an integer outside the range of 1-24,\n   * or an integer that has already been opened, the program will print\n   * an error message and ask again.\n   */\n  selectDay() {\n    this.rl.question(\"Que día deseas abrir ('x' para salir): \", (dia) => {\n      if (dia.toLowerCase() == \"x\") {\n        this.rl.close();\n        return;\n      }\n\n      dia = parseInt(dia);\n\n      if (isNaN(dia) || !Number.isInteger(dia)) {\n        console.log(\"El dia debe ser un entero\");\n        this.selectDay();\n      } else if (dia < 1 || dia > 24) {\n        console.log(\"El dia debe estar entre 1 y 24\");\n        this.selectDay();\n      } else if (this.openedDays.has(dia)) {\n        console.log(\"El dia ya estaba abierto\");\n        this.selectDay();\n      } else {\n        this.openedDays.add(dia);\n        this.printCalendar();\n        this.printOpenedDays();\n        this.selectDay();\n      }\n    });\n  }\n}\n\nconst calendar = new AdventCalendar();\ncalendar.populateCalendar();\ncalendar.printCalendar();\ncalendar.printOpenedDays();\ncalendar.selectDay();\n"
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/kotlin/blackriper.kt",
    "content": "\nimport java.util.Scanner\n\n\nconst val DAYS=24\nval Dimensions= Pair(4,6)\n\nval gifts = listOf(\n    \"Cupon 50% en mouredev pro\", \"Taza java\", \"Libro github\", \"Cupon 50% metalcode\", \"Consulta gratuita doc Mouredev\", \"Kotlin pet\",\n    \"Descuento 50% en Be native\", \"Mac mini m4\", \"Curso swift\", \"Termo comunidad\", \"Playera\", \"Curso Reflex\",\n    \"Curso python\", \"Descuento 30% udemy\", \"Taza Adviento\", \"Teclado\", \"Monitor de programador\", \"Stickers de mouredev\",\n    \"Curso swift\", \"Curso javascript\", \"Curso go\", \"Mouredev pro cuenta gratis\", \"Poster\", \"Calendar gopher\"\n)\n\ntypealias Calendar=  Array<Array<String?>>\n\nfun createAdviento(): Calendar{\n    val calendar = Array(Dimensions.first) { arrayOfNulls<String>(Dimensions.second) }\n    var day = 1\n\n    // Fill the calendar with days\n    for (i in 0 until Dimensions.first) {\n        for (j in 0 until Dimensions.second) {\n            if (day <= DAYS)\n                calendar[i][j] = String.format(\"%02d\", day)\n                day++\n\n        }\n    }\n    return calendar;\n}\n\n\n\nfun printCalendar(calendar: Calendar,selected: Int=0) {\n    for (i in calendar.indices) {\n        for (j in calendar[i].indices) {\n            if (calendar[i][j] != null) {\n                print(\"**** \")\n            } else {\n                print(\"     \")\n            }\n        }\n        println()\n        for (j in calendar[i].indices) {\n            if (calendar[i][j] != null) {\n                print(if (calendar[i][j]?.toInt()==selected) \"**** \" else \"*${calendar[i][j]}* \")\n            } else {\n                print(\"     \")\n            }\n        }\n        println()\n        for (j in calendar[i].indices) {\n            if (calendar[i][j] != null) {\n                print(\"**** \")\n            } else {\n                print(\"     \")\n            }\n        }\n        println()\n    }\n}\n\nfun selectDay(calendar: Calendar) {\n    var daySelected=0\n    val daysSelected=mutableListOf<Int>()\n    while (true) {\n        printCalendar(calendar,daySelected)\n        print(\"Selecciona un día (1-24) o 0 para salir: \")\n         daySelected = readLine()!!.toInt()\n\n        if (daySelected == 0)  break\n        else if (daySelected < 1 || daySelected > 24)  println(\"Por favor, selecciona un día válido.\")\n        else if (daysSelected.contains(daySelected)) println(\"El dia ya ha sido descubierto\")\n        else  println(\"Regalo para el día $daySelected: ${gifts[daySelected - 1]}\")\n        daysSelected.add(daySelected)\n   }\n  }\n\nfun main() {\n    val calendar=createAdviento()\n    selectDay(calendar)\n}"
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/php/miguelex.php",
    "content": "<?php\n// Definimos el tamaño de las cuadrículas y el rango de días\nconst GRID_WIDTH = 4;\nconst GRID_HEIGHT = 3;\nconst DAYS = 24;\n\n// Inicializamos los días descubiertos\n$discovered = array_fill(1, DAYS, false);\n\nfunction drawCalendar($discovered) {\n    for ($row = 0; $row < ceil(DAYS / 6); $row++) {\n        // Líneas superiores de las cuadrículas\n        for ($line = 0; $line < GRID_HEIGHT; $line++) {\n            for ($col = 0; $col < 6; $col++) {\n                $day = $row * 6 + $col + 1;\n                if ($day > DAYS) break;\n\n                switch ($line) {\n                    case 0:\n                    case 2:\n                        echo str_repeat(\"*\", GRID_WIDTH) . \" \";\n                        break;\n                    case 1:\n                        echo \"*\";\n                        echo $discovered[$day] \n                            ? str_repeat(\"*\", GRID_WIDTH - 2) \n                            : str_pad(sprintf(\"%02d\", $day), GRID_WIDTH - 2, \" \", STR_PAD_BOTH);\n                        echo \"* \";\n                        break;\n                }\n            }\n            echo \"\\n\";\n        }\n    }\n}\n\nwhile (true) {\n    // Dibujamos el calendario\n    drawCalendar($discovered);\n\n    // Pedimos al usuario que elija un día\n    echo \"\\nSeleccione un día (1-\" . DAYS . \") para descubrir o escriba 0 para salir: \";\n    $input = trim(fgets(STDIN));\n\n    if ($input == 0) {\n        echo \"¡Gracias por participar en el aDEViento!\\n\";\n        break;\n    }\n\n    if (!is_numeric($input) || $input < 1 || $input > DAYS) {\n        echo \"Por favor, elija un número válido entre 1 y \" . DAYS . \".\\n\";\n        continue;\n    }\n\n    if ($discovered[$input]) {\n        echo \"El día $input ya ha sido descubierto.\\n\";\n    } else {\n        $discovered[$input] = true;\n        echo \"¡Has descubierto el día $input!\\n\";\n    }\n}\n"
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/python/Gordo-Master.py",
    "content": "# 47 - Calendario de Adviento\nclass EventCalendar:\n    def __init__(self):\n        self.gifs = [f\"{x:02}\" for x in range(1,25)]\n\n    def show_calendar(self):\n        for y in range(0,24,6):\n            print(\"**** \"*6)\n            for x in range(6):\n                print(\"*\"+self.gifs[x+y]+\"* \", end=\"\")\n            print()\n            print(\"**** \"*6)\n            print()\n            \n    def select_day(self):\n        day = input(\"Ingrese el día a describrir (o escribe 'salir' para finalizar): \")\n        if day.lower() == 'salir':\n            print(\"Saliendo del calendario de adviento...\")\n            return \n        if not day.isdigit() or int(day)<=0  or int(day) > 24:\n            print(\"Valor invalido, debe ser un numero entero entre 1 y 24!\")\n            return True\n        try:\n            day = f\"{int(day):02}\"\n            self.gifs[self.gifs.index(day)] = \"**\"\n        except ValueError:\n            print(\"Ya se ha abierto ese día!\")\n            return True\n        input(f\"Se ha abierto el día {day}!\")\n        return True\n    \n    def verify_list_exist_int(self):\n        for day in self.gifs:\n            if day.isdigit():\n                return True\n        return False\n\n    def run_adviento(self):\n        while True:    \n            self.show_calendar()\n            ok = self.select_day()\n            if not ok:\n                    break\n            if not self.verify_list_exist_int():\n                break\n\nadviento = EventCalendar()\nadviento.run_adviento()"
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/python/JesusWay69.py",
    "content": "import os, platform\n\nif (platform.platform().startswith(\"macOS\") or platform.platform().startswith(\"Linux\")):\n    os.system('clear')\nelse:\n    os.system('cls')\n\n\"\"\" * EJERCICIO:\n * ¡Cada año celebramos el aDEViento! 24 días, 24 regalos para\n * developers. Del 1 al 24 de diciembre: https://adviento.dev\n *\n * Dibuja un calendario por terminal e implementa una\n * funcionalidad para seleccionar días y mostrar regalos.\n * - El calendario mostrará los días del 1 al 24 repartidos\n *   en 6 columnas a modo de cuadrícula.\n * - Cada cuadrícula correspondiente a un día tendrá un tamaño\n *   de 4x3 caracteres, y sus bordes serán asteríscos.\n * - Las cuadrículas dejarán un espacio entre ellas.\n * - En el medio de cada cuadrícula aparecerá el día entre el\n *   01 y el 24.\n *\n * Ejemplo de cuadrículas:\n * **** **** **** **** **** ****\n * *01* *02* *03* *04* *05* *06*\n * **** **** **** **** **** ****\n *\n * - El usuario seleccioná qué día quiere descubrir.\n * - Si está sin descubrir, se le dirá que ha abierto ese día\n *   y se mostrará de nuevo el calendario con esa cuadrícula\n *   cubierta de asteríscos (sin mostrar el día).\n *\n * Ejemplo de selección del día 1\n * **** **** **** \n * **** *02* *03* ...\n * **** **** ****\n *\n * - Si se selecciona un número ya descubierto, se le notifica\n *   al usuario.\"\"\"\n\ncalendar = []\nused_numbers = set()\nfor i in range(6):\n            calendar.append(\"****\")\n\nfor i in range(1, 25):\n    day:str = f\"*{str(i).zfill(2)}*\"\n    calendar.append(day)\n    if i % 6 == 0:\n        for i in range(6):\n            calendar.append(\"****\")\n\ndef show_calendar(calendar:list):\n    for i in range (1, len(calendar) + 1):\n        print(calendar[i-1], end=' ')\n        if i % 6 == 0:\n            print()\n    \nwhile True:\n    show_calendar(calendar)\n    number:str = input(\"\\nIntroduzca el día del calendario del 1 al 24 o enter para salir: \")\n    if number == '':\n         break\n\n    elif not number.isdigit or int(number) > 24 or int(number) < 1:\n        print(\"El dato debe ser numérico entre 1 y 24, intente de nuevo\")\n        continue\n    \n    else:\n        target:str = number.zfill(2)\n        for number in used_numbers:\n            if number == target:\n                print(f\"El número {target} ya se ha seleccionado antes, intente con otro\") \n            continue  \n        for j in range(len(calendar)):\n            if target in calendar[j]:\n                calendar[j] = \"****\"\n                used_numbers.add(target)\n          \n        "
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/python/Nicojsuarez2.py",
    "content": "# #47 CALENDARIO DE ADVIENTO\n> #### Dificultad: Fácil | Publicación: 25/11/24 | Corrección: 02/12/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * ¡Cada año celebramos el aDEViento! 24 días, 24 regalos para\n * developers. Del 1 al 24 de diciembre: https://adviento.dev\n * \n * Dibuja un calendario por terminal e implementa una\n * funcionalidad para seleccionar días y mostrar regalos.\n * - El calendario mostrará los días del 1 al 24 repartidos\n *   en 6 columnas a modo de cuadrícula.\n * - Cada cuadrícula correspondiente a un día tendrá un tamaño \n *   de 4x3 caracteres, y sus bordes serán asteríscos.\n * - Las cuadrículas dejarán un espacio entre ellas.\n * - En el medio de cada cuadrícula aparecerá el día entre el\n *   01 y el 24.\n *\n * Ejemplo de cuadrículas:\n * **** **** ****\n * *01* *02* *03* ...\n * **** **** ****\n *\n * - El usuario selecciona qué día quiere descubrir.\n * - Si está sin descubrir, se le dirá que ha abierto ese día\n *   y se mostrará de nuevo el calendario con esa cuadrícula\n *   cubierta de asteríscos (sin mostrar el día).\n *\n * Ejemplo de selección del día 1\n * **** **** ****\n * **** *02* *03* ...\n * **** **** ****\n *   \n * - Si se selecciona un número ya descubierto, se le notifica\n *   al usuario.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/python/Yisusocanto.py",
    "content": "calendario = \"\"\"**** **** **** **** **** ****\n*01* *02* *03* *04* *05* *06*\n**** **** **** **** **** ****\n**** **** **** **** **** ****\n*07* *08* *09* *10* *11* *12*\n**** **** **** **** **** ****\n**** **** **** **** **** ****\n*13* *14* *15* *16* *17* *18*\n**** **** **** **** **** ****\n**** **** **** **** **** ****\n*19* *20* *21* *22* *23* *24*\n**** **** **** **** **** ****\n\"\"\"\n\nwhile True:\n    print(\"CALENDARIO ADEVIENTO\\n\")\n    print(calendario)\n    dia = input(\"\\nSelecciona el dia que quieres ver: \")\n    \n    match dia:\n        case \"01\":\n            if calendario[31:33] == \"**\":\n                print(\"Ya has abierto este dia, selecciona otro por favor.\\n\")\n            else:\n                print(\"El regalo del dia (01) es una subscripcion de un mes a una web de cursos.\\n\")\n                calendario = calendario.replace(\"01\", \"**\")\n        case \"02\":\n            if calendario[36:38] == \"**\":\n                print(\"Ya has abierto este dia, selecciona otro por favor.\\n\")\n            else:\n                print(\"El regalo del dia (02) es una laptop.\\n\")\n                calendario = calendario.replace(\"02\", \"**\")  \n        case \"03\":\n            if calendario[41:43] == \"**\":\n                print(\"Ya has abierto este dia, selecciona otro por favor.\\n\")\n            else:\n                print(\"El regalo del dia (03) es un carro.\\n\")\n                calendario = calendario.replace(\"03\", \"**\")\n        case \"04\":\n            if calendario[46:48] == \"**\":\n                print(\"Ya has abierto este dia, selecciona otro por favor.\\n\")\n            else:\n                print(\"El regalo del dia (04) es un viaje a madrid.\\n\")\n                calendario = calendario.replace(\"04\", \"**\")\n        case \"05\":\n            if calendario[51:53] == \"**\":\n                print(\"Ya has abierto este dia, selecciona otro por favor.\\n\")\n            else:\n                print(\"El regalo del dia (05) es una TV.\\n\")\n                calendario = calendario.replace(\"05\", \"**\")\n        case \"06\":\n            if calendario[56:58] == \"**\":\n                print(\"Ya has abierto este dia, selecciona otro por favor.\\n\")\n            else:\n                print(\"El regalo del dia (06) es 100$.\\n\")\n                calendario = calendario.replace(\"06\", \"**\")\n        case \"07\":\n            if calendario[121:123] == \"**\":\n                print(\"Ya has abierto este dia, selecciona otro por favor.\\n\")\n            else:\n                print(\"El regalo del dia (07) es un libro de programacion.\\n\")\n                calendario = calendario.replace(\"07\", \"**\")\n        case \"08\":\n            if calendario[126:128] == \"**\":\n                print(\"Ya has abierto este dia, selecciona otro por favor.\\n\")\n            else:\n                print(\"El regalo del dia (08) es una PC.\\n\")\n                calendario = calendario.replace(\"08\", \"**\")\n        case \"09\":\n            if calendario[131:133] == \"**\":\n                print(\"Ya has abierto este dia, selecciona otro por favor.\\n\")\n            else:\n                print(\"El regalo del dia (09) es una pagina web gratis.\\n\")\n                calendario = calendario.replace(\"09\", \"**\")\n        case \"10\":\n            if calendario[136:138] == \"**\":\n                print(\"Ya has abierto este dia, selecciona otro por favor.\\n\")\n            else:\n                print(\"El regalo del dia (10) es un dominio web.\\n\")\n                calendario = calendario.replace(\"10\", \"**\")\n        case \"11\":\n            if calendario[141:143] == \"**\":\n                print(\"Ya has abierto este dia, selecciona otro por favor.\\n\")\n            else:\n                print(\"El regalo del dia (11) es un perro.\\n\")\n                calendario = calendario.replace(\"1\", \"**\")\n        case \"12\":\n            if calendario[146:148] == \"**\":\n                print(\"Ya has abierto este dia, selecciona otro por favor.\\n\")\n            else:\n                print(\"El regalo del dia (12) es un album musical.\\n\")\n                calendario = calendario.replace(\"12\", \"**\")\n        case \"13\":\n            if calendario[211:213] == \"**\":\n                print(\"Ya has abierto este dia, selecciona otro por favor.\\n\")\n            else:\n                print(\"El regalo del dia (13) es una clase gratis.\\n\")\n                calendario = calendario.replace(\"13\", \"**\")\n        case \"14\":\n            if calendario[216:218] == \"**\":\n                print(\"Ya has abierto este dia, selecciona otro por favor.\\n\")\n            else:\n                print(\"El regalo del dia (14) es gato.\\n\")\n                calendario = calendario.replace(\"14\", \"**\")\n        case \"15\":\n            if calendario[221:223] == \"**\":\n                print(\"Ya has abierto este dia, selecciona otro por favor.\\n\")\n            else:\n                print(\"El regalo del dia (15) es una subscripcion de tres meses a una web de cursos.\\n\")\n                calendario = calendario.replace(\"15\", \"**\")\n        case \"16\":\n            if calendario[226:228] == \"**\":\n                print(\"Ya has abierto este dia, selecciona otro por favor.\\n\")\n            else:\n                print(\"El regalo del dia (16) es un regalo x.\\n\")\n                calendario = calendario.replace(\"16\", \"**\")\n        case \"17\":\n            if calendario[231:233] == \"**\":\n                print(\"Ya has abierto este dia, selecciona otro por favor.\\n\")\n            else:\n                print(\"El regalo del dia (17) es una foto con el bicho.\\n\")\n                calendario = calendario.replace(\"17\", \"**\")\n        case \"18\":\n            if calendario[236:238] == \"**\":\n                print(\"Ya has abierto este dia, selecciona otro por favor.\\n\")\n            else:\n                print(\"El regalo del dia (18) es una avioneta.\\n\")\n                calendario = calendario.replace(\"18\", \"**\")\n        case \"19\":\n            if calendario[301:303] == \"**\":\n                print(\"Ya has abierto este dia, selecciona otro por favor.\\n\")\n            else:\n                print(\"El regalo del dia (19) es nada.\\n\")\n                calendario = calendario.replace(\"19\", \"**\")\n        case \"20\":\n            if calendario[306:308] == \"**\":\n                print(\"Ya has abierto este dia, selecciona otro por favor.\\n\")\n            else:\n                print(\"El regalo del dia (20) es no se.\\n\")\n                calendario = calendario.replace(\"20\", \"**\")\n        case \"21\":\n            if calendario[311:313] == \"**\":\n                print(\"Ya has abierto este dia, selecciona otro por favor.\\n\")\n            else:\n                print(\"El regalo del dia (21) es una subscripcion de un mes a una web de cursos.\\n\")\n                calendario = calendario.replace(\"21\", \"**\")\n        case \"22\":\n            if calendario[316:318] == \"**\":\n                print(\"Ya has abierto este dia, selecciona otro por favor.\\n\")\n            else:\n                print(\"El regalo del dia (22) es una subscripcion de un mes a una web de cursos.\\n\")\n                calendario = calendario.replace(\"22\", \"**\")\n        case \"23\":\n            if calendario[321:323] == \"**\":\n                print(\"Ya has abierto este dia, selecciona otro por favor.\\n\")\n            else:\n                print(\"El regalo del dia (23) es una subscripcion de un mes a una web de cursos.\\n\")\n                calendario = calendario.replace(\"23\", \"**\")\n        case \"24\":\n            if calendario[326:328] == \"**\":\n                print(\"Ya has abierto este dia, selecciona otro por favor.\\n\")\n            else:\n                print(\"El regalo del dia (24) es una subscripcion de un mes a una web de cursos.\\n\")\n                calendario = calendario.replace(\"24\", \"**\")\n        case _:\n            print(\"seleccione una opcion valida.\\n\")\n            \n"
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/python/cdryampi.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * ¡Cada año celebramos el aDEViento! 24 días, 24 regalos para\n#  * developers. Del 1 al 24 de diciembre: https://adviento.dev\n#  * \n#  * Dibuja un calendario por terminal e implementa una\n#  * funcionalidad para seleccionar días y mostrar regalos.\n#  * - El calendario mostrará los días del 1 al 24 repartidos\n#  *   en 6 columnas a modo de cuadrícula.\n#  * - Cada cuadrícula correspondiente a un día tendrá un tamaño \n#  *   de 4x3 caracteres, y sus bordes serán asteríscos.\n#  * - Las cuadrículas dejarán un espacio entre ellas.\n#  * - En el medio de cada cuadrícula aparecerá el día entre el\n#  *   01 y el 24.\n#  *\n#  * Ejemplo de cuadrículas:\n#  * **** **** ****\n#  * *01* *02* *03* ...\n#  * **** **** ****\n#  *\n#  * - El usuario seleccioná qué día quiere descubrir.\n#  * - Si está sin descubrir, se le dirá que ha abierto ese día\n#  *   y se mostrará de nuevo el calendario con esa cuadrícula\n#  *   cubierta de asteríscos (sin mostrar el día).\n#  *\n#  * Ejemplo de selección del día 1\n#  * **** **** ****\n#  * **** *02* *03* ...\n#  * **** **** ****\n#  *   \n#  * - Si se selecciona un número ya descubierto, se le notifica\n#  *   al usuario.\n#  */\n\nclass Cuadricula():\n\n    def __init__(self, num):\n        self.__num = num\n        self.__old = num\n\n        self.__cuadrado =[\n        [['*'],['*'],['*'],['*']],\n        [['*'],[f'{self.__num:02d}'], ['*']],\n        [['*'],['*'],['*'],['*']],\n    ]\n     \n    @property\n    def get_cuadrado(self)-> list:\n        return self.__cuadrado\n    \n    def __flip(self)->None:\n        if self.__num == '**':\n            self.__num = self.__old\n            self.__cuadrado =[\n                [['*'],['*'],['*'],['*']],\n                [['*'],[f'{self.__num:02d}'], ['*']],\n                [['*'],['*'],['*'],['*']],\n            ]\n        else:\n            self.__num = '**'\n            self.__cuadrado =[\n                [['*'],['*'],['*'],['*']],\n                [['*'],[f'{self.__num}'], ['*']],\n                [['*'],['*'],['*'],['*']],\n            ]\n\n        #print(self.__num)\n    def is_flipped(self):\n        if self.__num == '**': \n            print(\"El día ya se ha revelado!\")\n        else:\n            self.__flip()\n            \n    \n    def __str__(self) -> str:\n        total_string = ''\n        for fila in self.__cuadrado:\n            for columna in fila:\n                total_string += columna[0]\n        return total_string\n\n\n    def is_equals(self, number:int) -> bool:\n        return True if number == self.__old else False\n\nclass Calendario():\n    __mes = [\n        [Cuadricula(num) for num in range(1, 25) ],\n    ]\n    \n    def print_calendario(self):\n        semana = [\n            [],\n            [],\n            [],\n        ]\n        \n        contador_dia = 0\n\n        for __semana in self.__mes:\n            for dia in __semana:\n                for index, fila in enumerate(semana):  \n                    for index_b, borde in enumerate(dia.get_cuadrado):  \n                        if index_b == index:\n                            valor = ''\n                            for v in borde:\n                                valor += v[0]\n                            semana[index] += valor + '\\t'\n\n                contador_dia += 1\n\n                if contador_dia % 7 == 0:\n                    for fila in semana:\n                        print(''.join(fila))\n                    print()\n\n                    semana = [[], [], []]\n\n        if any(semana):\n            for fila in semana:\n                print(''.join(fila))\n\n\n    def find_day(self, day: int):\n        for fila in self.__mes:\n            cuadricula = next((c for c in fila if c.is_equals(day)), None)\n            if cuadricula:\n                #print(\"Encontrado\")\n                return cuadricula\n        print(\"No encontrado\")\n        return None\n\n    def flip_day(self, day:int) -> bool:\n        day_flip = self.find_day(day=day)\n\n        if day_flip:\n            day_flip.is_flipped()\n            return True\n        return False\n\n\n\n\n\n\ndef main():\n    c = Calendario()\n    c.print_calendario()\n\n    while True:\n            print(\"\\n--- Calendario de adviento ---\")\n            print(\"1. mostrar día\")\n            print(\"2. Salir\")\n            choice = input(\"Elige una opción: \")\n            match choice:\n                case \"1\":\n                    # Crear usuario\n                    day = input(\"Introduce el día del adviento: \")\n                    try:\n                        if c.flip_day(int(day)) == False:\n                            print(\"Selecciona un día del calendario.\")\n                    except ValueError as v:\n                        print(\"Elije un número no una letra.\")\n                    c.print_calendario()\n                    \n                case \"2\":\n                    print(\"Saliendo del calendario\")\n                    break\n                case _:\n                    print(\"Elige una opción válida del menú\")\n\n\nif __name__ == '__main__':\n    main()"
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/python/davidrguez98.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * ¡Cada año celebramos el aDEViento! 24 días, 24 regalos para\n * developers. Del 1 al 24 de diciembre: https://adviento.dev\n * \n * Dibuja un calendario por terminal e implementa una\n * funcionalidad para seleccionar días y mostrar regalos.\n * - El calendario mostrará los días del 1 al 24 repartidos\n *   en 6 columnas a modo de cuadrícula.\n * - Cada cuadrícula correspondiente a un día tendrá un tamaño \n *   de 4x3 caracteres, y sus bordes serán asteríscos.\n * - Las cuadrículas dejarán un espacio entre ellas.\n * - En el medio de cada cuadrícula aparecerá el día entre el\n *   01 y el 24.\n *\n * Ejemplo de cuadrículas:\n * **** **** ****\n * *01* *02* *03* ...\n * **** **** ****\n *\n * - El usuario seleccioná qué día quiere descubrir.\n * - Si está sin descubrir, se le dirá que ha abierto ese día\n *   y se mostrará de nuevo el calendario con esa cuadrícula\n *   cubierta de asteríscos (sin mostrar el día).\n *\n * Ejemplo de selección del día 1\n * **** **** ****\n * **** *02* *03* ...\n * **** **** ****\n *   \n * - Si se selecciona un número ya descubierto, se le notifica\n *   al usuario.\n */ \"\"\"\n\nclass AdventCalendar:\n\n    def __init__(self):\n        self.days = [False] * 24\n\n    def display(self):\n\n        for row in range(0, 24, 6):\n\n            print(\"**** \" * 6)\n            print(\" \".join([f\"*{str(day).zfill(2)}*\" if not self.days[day - 1] else \"****\" for day in range(row + 1, row + 7)]))\n            print(\"**** \" * 6)\n            print()\n\n    def select(self, day):\n\n        is_digit = day.isdigit()\n\n        if is_digit and int(day) > 0 and int(day) <= 24:\n            day = int(day)\n\n            if self.days[day - 1]:\n                print(f\"El día {day} ya está abierto. Selecciona otro día.\")\n            else:\n                self.days[day - 1] = True\n                print(f\"Has abierto el día {day}.\")\n\n        else: \n            print(\"Selección inválida. Debes introducir un número.\")\n           \nadvent_calendar = AdventCalendar()\n\nwhile True:\n\n    advent_calendar.display()\n\n    selection = input(\"Selecciona un día para descubrir (o escribe salir para finalizar): \")\n\n    if selection.lower() == \"salir\":\n        print(\"Finalizando calendario de adviento.\")\n        break\n\n    advent_calendar.select(selection)"
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/python/duendeintemporal.py",
    "content": "#47 { Retos para Programadores } CALENDARIO DE ADVIENTO \n\n# Bibliography reference:\n# I use GPT as a reference and sometimes to correct or generate proper comments.\n\n\"\"\"\n * EJERCICIO:\n * ¡Cada año celebramos el aDEViento! 24 días, 24 regalos para\n * developers. Del 1 al 24 de diciembre: https://adviento.dev\n *\n * Dibuja un calendario por terminal e implementa una\n * funcionalidad para seleccionar días y mostrar regalos.\n * - El calendario mostrará los días del 1 al 24 repartidos\n *   en 6 columnas a modo de cuadrícula.\n * - Cada cuadrícula correspondiente a un día tendrá un tamaño\n *   de 4x3 caracteres, y sus bordes serán asteríscos.\n * - Las cuadrículas dejarán un espacio entre ellas.\n * - En el medio de cada cuadrícula aparecerá el día entre el\n *   01 y el 24.\n *\n * Ejemplo de cuadrículas:\n * **** **** ****\n * *01* *02* *03* ...\n * **** **** ****\n *\n * - El usuario seleccioná qué día quiere descubrir.\n * - Si está sin descubrir, se le dirá que ha abierto ese día\n *   y se mostrará de nuevo el calendario con esa cuadrícula\n *   cubierta de asteríscos (sin mostrar el día).\n *\n * Ejemplo de selección del día 1\n * **** **** ****\n * **** *02* *03* ...\n * **** **** ****\n *\n * - Si se selecciona un número ya descubierto, se le notifica\n *   al usuario.\n\n\"\"\"\n\nlog = print\n\nimport sys\n\nprices = [\n    \"$29.99 and Basic Linux Terminal Usage course\",\n    \"$39.99 and How to Perform Smart Commits? course\",\n    \"$49.99 and Introduction to Programming Logic course\",\n    \"$49.99 and Database Fundamentals course\",\n    \"$49.99 and Best Practices in Python course\",\n    \"$59.99 and Functional Programming Fundamentals course\",\n    \"$59.99 and IoT: Current Applications course\",\n    \"$69.99 and Software Design Patterns in Python course\",\n    \"$69.99 and 0 to Hero in PostgreSQL course\",\n    \"$79.99 and Qt4 Interface Development course\",\n    \"$79.99 and Applying SOLID Patterns in Java course\",\n    \"$79.99 and Go: The Language of the Future? course\",\n    \"$89.99 and C# Development course\",\n    \"$89.99 and Artificial Intelligence Fundamentals course\",\n    \"$99.99 and Agile Methodologies Diploma course\",\n    \"$99.99 and Django Rest Framework (DRF) Primer course\",\n    \"$99.99 and Optimization Algorithms in C++ course\",\n    \"$109.99 and Building REST Services with AWS API Gateway and Lambda course\",\n    \"$119.99 and Data Science with Python and R course\",\n    \"$79.99 and Object-Oriented Programming in Java course\",\n    \"$89.99 and Traditional Methodologies Paradigm: Still Relevant? Applicable Cases course\",\n    \"$69.99 and NumPy and Pandas in Python course\",\n    \"$59.99 and Blockchain Fundamentals course\",\n    \"$79.99 and Microservices Architecture with Spring Boot course\",\n    \"$89.99 and Ethical Hacking and Cybersecurity Essentials course\"\n]\n\ndef draw_calendar(discovered_days):\n    COLUMNS_COUNT = 6\n    CELL_WIDTH = 4\n    CELL_HEIGHT = 3\n\n    calendar = ''\n\n    for row in range(CELL_HEIGHT):\n        for day in range(1, 25):\n            if row == 1:\n                if day in discovered_days:\n                    calendar += '*' * CELL_WIDTH\n                else:\n                    calendar += f'*{str(day).zfill(2)}*'\n            else:\n                calendar += '*' * CELL_WIDTH\n            \n            if day % COLUMNS_COUNT == 0:\n                calendar += '\\n'\n            else:\n                calendar += ' '\n        calendar += '\\n'\n\n    return calendar\n\ndef handle_user_input(discovered_days):\n    while True:\n        try:\n            day = int(input('Enter the day you want to discover (1-24): '))\n            if day < 1 or day > 24:\n                log('\\nInvalid day. Please enter a number between 1 and 24.\\n')\n                continue\n\n            if day in discovered_days:\n                log(f'\\nDay {day} has already been discovered.\\n')\n            else:\n                log(f'\\nGift of the day {day}: {prices[day - 1]} 🎁 ')\n                log(f'\\nYou have discovered day {day}!\\n')\n                return discovered_days + [day]\n        except ValueError:\n            log('\\nInvalid input. Please enter a number between 1 and 24.\\n')\n\ndef main():\n    discovered_days = []\n\n    while len(discovered_days) < 24:\n        log('\\n     Adviento Calendar!\\n')\n        log(draw_calendar(discovered_days))\n        discovered_days = handle_user_input(discovered_days)\n\n    log('\\n     Adviento Calendar!\\n')\n    log(draw_calendar(discovered_days))\n    log('Congratulations! You have discovered all 24 days.')\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/python/edaagapu.py",
    "content": "\n# EJERCICIO:\n# ¡Cada año celebramos el aDEViento! 24 días, 24 regalos para\n# developers. Del 1 al 24 de diciembre: https://adviento.dev\n# \n# Dibuja un calendario por terminal e implementa una\n# funcionalidad para seleccionar días y mostrar regalos.\n# - El calendario mostrará los días del 1 al 24 repartidos\n#   en 6 columnas a modo de cuadrícula.\n# - Cada cuadrícula correspondiente a un día tendrá un tamaño \n#   de 4x3 caracteres, y sus bordes serán asteríscos.\n# - Las cuadrículas dejarán un espacio entre ellas.\n# - En el medio de cada cuadrícula aparecerá el día entre el\n#   01 y el 24.\n#\n# Ejemplo de cuadrículas:\n# **** **** ****\n# *01* *02* *03* ...\n# **** **** ****\n#\n# - El usuario seleccioná qué día quiere descubrir.\n# - Si está sin descubrir, se le dirá que ha abierto ese día\n#   y se mostrará de nuevo el calendario con esa cuadrícula\n#   cubierta de asteríscos (sin mostrar el día).\n#\n# Ejemplo de selección del día 1\n# **** **** ****\n# **** *02* *03* ...\n# **** **** ****\n#   \n# - Si se selecciona un número ya descubierto, se le notifica\n#   al usuario.\n\nnumbers = []\n\ncolumns = 6\nrows = 4\n\nprices = ['Curso de lógica de programación', 'Diplomado sobre Metodologías Ágiles', 'Desarrollo de interfaces con Qt4', \n  'Introducción a la programación funcional', 'Desarrollo en C#', 'Buenas prácticas de programación en Java Springboot', \n  '¿Cómo hacer Smart Commits?', 'Uso básico de la terminal Linux', 'Primeros pasos en Django Rest Framework (DRF)',\n  'Práctica aplicada de los patrones SOLID en Java', 'Introducción de Base de Datos', 'Buenas prácticas dentro de Python',\n  'Paradigma de Metodologías Tradicionales ¿Aún tienen uso? ¿En qué casos es aplicable?', 'Data Science con Python y R',\n  'GO ¿El lenguaje del futuro?', 'Patrones de Diseño de Software aplicados en Python', 'Algoritmos de optimización aplicados en C++',\n  'Fundamentos de la Inteligencia Artificial', 'Aplicación en la actualidad del IoT', 'Uso de librería numpy y pandas dentro de Python',\n  'POO aplicada en Java', '0 a héroe en PostgreSQL', 'Generación de servicios REST con AWS Api Gateway y Lambda',\n  'Programación básica en C#'\n]\n\ndef gen_grid(width:int=4):\n  borders = ['*'*width for _ in range(columns)]\n\n  matrix = []\n  for i in range(rows):\n    row = []\n    for j in range(columns):\n      value = (j+1)+(columns*(i))\n      number = f'*{str(value).zfill(width-2)}*' if value not in numbers else '*'*width\n      row.append(number)\n    matrix.append(row[:])\n\n  print(' '.join(borders))\n  for row in matrix:\n    print(' '.join(row))\n    print(' '.join(borders))\n\nif __name__ == '__main__':\n  num = 1\n  gen_grid()\n  while (num!=0):\n    num = int(input('Escriba un dia entre 1 y 24 (O si desea terminar el proceso escriba 0): '))\n    if (num in numbers):\n      print('El numero ya fue escogido. Intente nuevamente')\n      continue\n    if (1<=num<=24):\n      print(f'¡Felicitaciones! Su premio es: \"{prices[num-1]}\"')\n      numbers.append(num)\n      gen_grid()\n"
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/python/giulianovfz.py",
    "content": "# 47 Calendario de adviento\n\n# funcionalidades\n# - seleccionar días del 1 al 24 repartidos\n# en 6 columnas a modo de cuadrícula\n# - Cada cuadrícula correspodiente a un día tendrá\n# un tamaño de 4x3 caracteres, y sus bordes serán asteríscos\n# - Las cuadrículas dejarán un espacio entre ellas.\n# - En el medio de cada cuadrícula aparecerá el día\n# entre el 01 y 24\n# - El usuario seleccioná qué día quiere descubrir\n# - Si esta sin descubrir, se le dirá que ha abierto\n#  ese día y se mostrará de nuevo el calendario con esa\n#  cuadrícula cubierta de asteríscos (sin mostrar el día)\n# - Si selecciona un número ya descubierto, se le\n#  notifica al usuario\n\"\"\"k→ 0  | 1  | 2  | 3  | 4  | 5   |f↓\n     **** **** **** **** **** **** |0\n     *01* *02* *03* *04* *05* *06* |1\n     **** **** **** **** **** **** |2\n    \n     **** **** **** **** **** **** |3\n     *07* *08* *09* *10* *11* *12* |4\n     **** **** **** **** **** **** |5\n\n     **** **** **** **** **** **** |6\n     *13* *14* *15* *16* *17* *18* |7\n     **** **** **** **** **** **** |8\n\n     **** **** **** **** **** **** |9\n     *19* *20* *21* *22* *23* *24* |10\n     **** **** **** **** **** **** |11\n\"\"\"\n\n\nclass Adviento:\n    \"\"\"\n    Adviento, nos crea el calendario, para mostrar en la terminal\n    permitiendo que se interactue con el, seleccionando los días\n    que quieres ver\n    \"\"\"\n\n    def __init__(self):\n        self.valores_dia = []\n        self.matriz = [[\"*\"*4 if x % 2 == 0 else \" \" for x in range(0, 11)]\n                       for _ in range(0, 12)]\n\n        for f in range(1, 12, 3):\n            t = (f*2)-1\n            for c, v in enumerate(range(0, 11, 2), t):\n                self.matriz[f][v] = f'*{str(c).zfill(2)}*'\n\n    def imprimir(self):\n        \"\"\"\n        Esta función solo sirve para dibujar el calendario\n        en la terminal, y le añade un salto de línea entre\n        los grupos de números.      \n        \"\"\"\n\n        print('')\n\n        for vuelta, fila in enumerate(self.matriz):\n\n            print(''.join(fila))\n            # salto de línea para cada fila\n            if vuelta in (2, 5, 8, 11):\n                print('')\n\n    def descubrir_dia(self, dia):\n        \"\"\"\n        Si el parámetro día no se encuentra en la lista self.valores_dia, \n        entonces comienzan los ciclos iterativos hasta que se modifique el\n        valor del elemento de la lista self.matriz por **. Adicionalmente, \n        se agrega a la lista self.valores_dia el día, así se determina que\n        fue seleccionado. Por tanto, si se vuelve a ingresar el mismo día ya\n        mostrado, muestra el mensaje: \"El día {día} ya fue seleccionado, elige otro\".\n        \"\"\"\n        if dia not in self.valores_dia:\n            print(f'\\nHas seleccionado el día {dia}')\n            for f in range(1, 12, 3):\n\n                for k in range(0, 11, 2):\n\n                    if self.matriz[f][k] == f'*{str(dia).zfill(2)}*':\n                        self.matriz[f][k] = '****'\n                        self.valores_dia.append(dia)\n\n        else:\n            print(f'\\nEl día {dia} ya fue seleccionado, elige otro')\n\n\ndef main():\n    \"\"\"\n    Se llama a la clase Adviento y se guarda en un objeto para poder\n    instanciarla posteriormente.\n    Acá se solicita al usuario que ingrese el número que desea mostrar\n    \"\"\"\n    calendario = Adviento()\n\n    while True:\n        calendario.imprimir()\n\n        try:\n            s_dia = input(\n                '\\ningresa el a descubrir, si quieres salir escribe la letra s o S: ')\n\n        except ValueError:\n            print('\\nSolo ingresar números del 1 al 24, con la letra s o S para salir\\n')\n\n        if s_dia.casefold() == \"s\":\n            break\n\n        elif s_dia.isdigit() and 0 < int(s_dia) <= 24:\n            calendario.descubrir_dia(int(s_dia))\n        else:\n            print('\\nSolo ingresar números del 1 al 24, con la letra s o S para salir\\n')\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/python/hectorio23.py",
    "content": "# Autor: Héctor Adán\n# GitHub: https://github.com/hectorio23\n\nTOTAL_DAYS = 24\nCOLUMNS = 6\nGRID_WIDTH = 4\nGRID_HEIGHT = 3\n\n# Función para dibujar el calendario\ndef draw_calendar(opened_days):\n    for row in range(TOTAL_DAYS // COLUMNS):\n        for h in range(GRID_HEIGHT):  # Cada fila de la cuadrícula\n            for col in range(COLUMNS):\n                day = row * COLUMNS + col + 1\n\n                if h == 0 or h == GRID_HEIGHT - 1:\n                    # Bordes superior e inferior\n                    print(\"****\", end=\" \")\n                elif h == GRID_HEIGHT // 2:\n                    # Línea central con el número del día o asteriscos si está descubierto\n                    if opened_days[day - 1]:\n                        print(\"****\", end=\" \")\n                    else:\n                        print(f\"*{day:02}*\", end=\" \")\n                else:\n                    # Espaciado intermedio\n                    print(\"*  *\", end=\" \")\n            print()\n\n# Programa principal\nif __name__ == \"__main__\":\n    opened_days = [False] * TOTAL_DAYS\n\n    print(\"\\nBienvenido al calendario de aDEViento!\\n\")\n    while True:\n        draw_calendar(opened_days)\n        user_input = input(\"\\nSelecciona un día (1-24) o escribe 'salir' para terminar: \")\n\n        if user_input.lower() == \"salir\":\n            print(\"Gracias por participar!\\n\")\n            break\n\n        # Validar la entrada\n        try:\n            selected_day = int(user_input)\n        except ValueError:\n            print(\"Entrada no válida. Inténtalo de nuevo.\\n\")\n            continue\n\n        if selected_day < 1 or selected_day > TOTAL_DAYS:\n            print(\"Número fuera de rango. Inténtalo de nuevo.\\n\")\n            continue\n\n        # Verificar el estado del día seleccionado\n        if opened_days[selected_day - 1]:\n            print(f\"El día {selected_day} ya ha sido descubierto.\\n\")\n        else:\n            opened_days[selected_day - 1] = True\n            print(f\"Has descubierto el día {selected_day}! Felicidades!\\n\")\n"
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/python/hozlucas28.py",
    "content": "# pylint: disable=missing-module-docstring,missing-class-docstring,broad-exception-caught,missing-function-docstring,line-too-long\n\nfrom abc import ABCMeta, abstractmethod\nfrom os import system\nfrom typing import TypedDict\n\n# ---------------------------------------------------------------------------- #\n#                                     TYPES                                    #\n# ---------------------------------------------------------------------------- #\n\nCalendarCell = TypedDict(\"CalendarCell\", {\"discovered\": bool, \"id\": int})\n\n# ---------------------------------------------------------------------------- #\n#                                    ERRORS                                    #\n# ---------------------------------------------------------------------------- #\n\n\nclass CalendarCellDiscoveredError(Exception):\n    def __init__(self, *, cell: CalendarCell) -> None:\n        super().__init__(f\"{cell[\"id\"]} calendar cell is already discovered\")\n\n\nclass CalendarDayNotFoundError(Exception):\n    def __init__(self, *, day: int) -> None:\n        super().__init__(f\"{day} calendar day not found\")\n\n\nclass CalendarDayOuOfRangeError(Exception):\n    def __init__(self, *, _day: int, _from: int, _to: int) -> None:\n        super().__init__(\n            f\"{_day} calendar day is out of range, it must be between {_from} and {_to} (both included)\"\n        )\n\n\n# ---------------------------------------------------------------------------- #\n#                                    CLASSES                                   #\n# ---------------------------------------------------------------------------- #\n\n# --------------------------------- Calendar --------------------------------- #\n\n\nclass AbcCalendar(metaclass=ABCMeta):\n    @property\n    @abstractmethod\n    def _array(self) -> list[list[CalendarCell]]:\n        pass\n\n    @property\n    @abstractmethod\n    def from_(self) -> int:\n        pass\n\n    @property\n    @abstractmethod\n    def to_(self) -> int:\n        pass\n\n    @abstractmethod\n    def discover_day(self, *, day: int) -> None:\n        pass\n\n    @abstractmethod\n    def to_print(self) -> str:\n        pass\n\n\nclass Calendar(AbcCalendar):\n    __array: list[list[CalendarCell]]\n    __from: int\n    __to: int\n\n    def __init__(self, *, _from: int, _to: int) -> None:\n        counter: int = _from\n\n        self.__from = _from\n        self.__to = _to\n\n        self.__array: list[list[CalendarCell]] = []\n        for i in range(0, Calendar.rows()):\n            self.__array.append([])\n\n            for _ in range(0, Calendar.cols()):\n                self.__array[i].append({\"discovered\": False, \"id\": counter})\n                counter += 1\n\n    @staticmethod\n    def rows() -> int:\n        return 4\n\n    @staticmethod\n    def cols() -> int:\n        return 6\n\n    @property\n    def _array(self) -> list[list[CalendarCell]]:\n        return self.__array\n\n    @property\n    def from_(self) -> int:\n        return self.__from\n\n    @property\n    def to_(self) -> int:\n        return self.__to\n\n    def discover_day(self, *, day: int) -> None:\n        flag: bool = False\n        counter: int = self.__from\n\n        if day < self.__from or day > self.__to:\n            raise CalendarDayOuOfRangeError(_day=day, _from=self.__from, _to=self.__to)\n\n        for i, _ in enumerate(iterable=self.__array):\n            if counter > self.__to:\n                break\n\n            for j, _ in enumerate(iterable=self.__array[i]):\n                if counter > self.__to:\n                    break\n\n                if self.__array[i][j][\"id\"] == day:\n                    if self.__array[i][j][\"discovered\"]:\n                        raise CalendarCellDiscoveredError(cell=self.__array[i][j])\n\n                    self.__array[i][j][\"discovered\"] = True\n                    flag = True\n                    break\n\n                counter += 1\n\n            if flag:\n                break\n\n        if not flag:\n            raise CalendarDayNotFoundError(day=day)\n\n    def to_print(self) -> str:\n        calendar_printable: list[str] = []\n\n        counter: int = self.__from\n\n        for i, row in enumerate(iterable=self.__array):\n            if counter > self.__to:\n                break\n\n            row: list[CalendarCell] = self.__array[i]\n\n            row_printable: str = \"\" if i == 0 else \"\\n\"\n            row_printable += (f\"{'*'*4} \" * len(row)).rstrip() + \"\\n\"\n\n            for _, col in enumerate(iterable=row):\n                if counter > self.__to:\n                    break\n\n                row_printable += f\"*{''.ljust(2,'*') if col['discovered'] else str(object=col['id']).rjust(2, '0')}* \"\n                counter += 1\n\n            row_printable = f\"{row_printable.rstrip()}\\n\"\n            row_printable += (f\"{'*'*4} \" * len(row)).rstrip()\n\n            calendar_printable.append(row_printable)\n\n        calendar_printable_str: str = \"\"\n        for i, tempo in enumerate(iterable=calendar_printable):\n            calendar_printable_str += tempo if (i == 0) else f\"\\n{tempo}\"\n\n        return calendar_printable_str\n\n\n# ---------------------------------------------------------------------------- #\n#                                     MAIN                                     #\n# ---------------------------------------------------------------------------- #\n\n\ncalendar: AbcCalendar = Calendar(_from=1, _to=24)\n\nprint(calendar.to_print())\n\nprint(\n    \"\\n> Available operations...\\n\\n\",\n    \"  1 - Discover day.\\n\",\n    \"  0 - Exit.\",\n)\n\ninput01: str = input(\"\\n> Enter an operation: \").strip()\n\nwhile input01 != \"0\":\n    match (input01):\n        case \"1\":\n            input02: str = input(\"\\n> Enter the day to discover: \").strip()\n\n            try:\n                calendar.discover_day(day=int(input02))\n                system(command=\"clear\")\n                print(f\"> Day {input02} discovered!\")\n\n            except CalendarDayOuOfRangeError as error:\n                system(command=\"clear\")\n                print(\n                    f\"\\n> The day {input02} must be between {calendar.from_} and {calendar.to_} (both included)!\"\n                )\n\n            except CalendarCellDiscoveredError as error:\n                system(command=\"clear\")\n                print(f\"\\n> The day {input02} is already discovered!\")\n\n            except CalendarDayNotFoundError as error:\n                system(command=\"clear\")\n                print(f\"\\n> {input02} day not found in the calendar!\")\n\n            except Exception as error:\n                system(command=\"clear\")\n                print(\"\\n> An error occurred on discover the day!\")\n\n        case _:\n            system(command=\"clear\")\n            print(\"\\n> Invalid operation! Try again...\")\n\n    print(f\"\\n{calendar.to_print()}\")\n\n    print(\n        \"\\n> Available operations...\\n\\n\",\n        \"  1 - Discover day.\\n\",\n        \"  0 - Exit.\",\n    )\n\n    input01 = input(\"\\n> Enter an operation: \").strip()\n"
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/python/idiegorojas.py",
    "content": "\"\"\" \n# 47 - Calendario de adviento\n\"\"\"\n# Dibuja un calendario por terminal e implementa una funcionalidad para seleccionar días y mostrar regalos.\n    # El calendario mostrará los días del 1 al 24 repartidos en 6 columnas a modo de cuadrícula.\n    # Cada cuadrícula correspondiente a un día tendrá un tamaño de 4x3 caracteres, y sus bordes serán asteríscos.\n    # Las cuadrículas dejarán un espacio entre ellas.\n    # En el medio de cada cuadrícula aparecerá el día entre el 01 y el 24.#\n\n# Ejemplo de cuadrículas:\n    # **** **** ****\n    # *01* *02* *03* ...\n    # **** **** ****#\n\n# - El usuario selecciona qué día quiere descubrir.\n# - Si está sin descubrir, se le dirá que ha abierto ese día y se mostrará de nuevo el calendario con esa cuadrícula cubierta de asteríscos (sin mostrar el día).#\n\n# Ejemplo de selección del día 1\n    # **** **** ****\n    # **** *02* *03* ...\n    # **** **** ****#\n# Si se selecciona un número ya descubierto, se le notifica al usuario.\n\ndef crear_calendario():\n    # Crear un diccionario para representar el calendario\n    # Días del 1 al 24, inicialmente todos sin descubrir (False)\n    return {i: False for i in range(1, 25)}\n\ndef mostrar_calendario(calendario):\n    # Mostrar el calendario en una cuadrícula de 6 columnas\n    dias_por_fila = 6\n    \n    for fila in range(0, 24, dias_por_fila):\n        dias_en_esta_fila = range(fila + 1, min(fila + dias_por_fila + 1, 25))\n        \n        # Primera línea de asteriscos (parte superior de las cuadrículas)\n        for i, dia in enumerate(dias_en_esta_fila):\n            print(\"****\", end=\" \" if i < len(dias_en_esta_fila) - 1 else \"\")\n        print()\n        \n        # Línea con los números\n        for i, dia in enumerate(dias_en_esta_fila):\n            if calendario[dia]:  # Si el día está descubierto\n                print(\"****\", end=\" \" if i < len(dias_en_esta_fila) - 1 else \"\")\n            else:\n                print(f\"*{dia:02d}*\", end=\" \" if i < len(dias_en_esta_fila) - 1 else \"\")\n        print()\n        \n        # Tercera línea de asteriscos (parte inferior de las cuadrículas)\n        for i, dia in enumerate(dias_en_esta_fila):\n            print(\"****\", end=\" \" if i < len(dias_en_esta_fila) - 1 else \"\")\n        print()\n        \n        # Añadir una línea en blanco entre filas, excepto después de la última fila\n        if fila + dias_por_fila < 24:\n            print()\n\ndef seleccionar_dia(calendario, dia):\n    if dia < 1 or dia > 24:\n        print(\"Día inválido. Debe estar entre 1 y 24.\")\n        return calendario\n    \n    if calendario[dia]:\n        print(f\"El día {dia} ya ha sido descubierto.\")\n    else:\n        calendario[dia] = True\n        print(f\"¡Has abierto el día {dia}!\")\n    \n    return calendario\n\ndef main():\n    calendario = crear_calendario()\n    \n    while True:\n        mostrar_calendario(calendario)\n        \n        try:\n            opcion = input(\"Selecciona un día (1-24) o 'q' para salir: \")\n            \n            if opcion.lower() == 'q':\n                break\n            \n            dia = int(opcion)\n            calendario = seleccionar_dia(calendario, dia)\n            \n        except ValueError:\n            print(\"Entrada inválida. Ingresa un número entre 1 y 24 o 'q' para salir.\")\n        \n        print(\"\\n\")\n\nif __name__ == \"__main__\":\n    main()"
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/python/ignaciovihe.py",
    "content": "\"\"\"\n * ¡Cada año celebramos el aDEViento! 24 días, 24 regalos para\n * developers. Del 1 al 24 de diciembre: https://adviento.dev\n * \n * Dibuja un calendario por terminal e implementa una\n * funcionalidad para seleccionar días y mostrar regalos.\n * - El calendario mostrará los días del 1 al 24 repartidos\n *   en 6 columnas a modo de cuadrícula.\n * - Cada cuadrícula correspondiente a un día tendrá un tamaño \n *   de 4x3 caracteres, y sus bordes serán asteríscos.\n * - Las cuadrículas dejarán un espacio entre ellas.\n * - En el medio de cada cuadrícula aparecerá el día entre el\n *   01 y el 24.\n *\n * Ejemplo de cuadrículas:\n * **** **** ****\n * *01* *02* *03* ...\n * **** **** ****\n *\n * - El usuario selecciona qué día quiere descubrir.\n * - Si está sin descubrir, se le dirá que ha abierto ese día\n *   y se mostrará de nuevo el calendario con esa cuadrícula\n *   cubierta de asteríscos (sin mostrar el día).\n *\n * Ejemplo de selección del día 1\n * **** **** ****\n * **** *02* *03* ...\n * **** **** ****\n *   \n * - Si se selecciona un número ya descubierto, se le notifica\n *   al usuario.\n\"\"\"\nimport os\n\ndef clear_console():\n    \"\"\"\n    Limpia la consola, tneiendo en cuenta el sistema operativo.\n    \"\"\"\n    os.system('cls' if os.name =='nt' else 'clear')\n\nclass AdventCalendar:\n\n    def __init__(self) -> None:\n        self.closed_days = [i for i in range(1,25)]\n\n    def open_day(self, selection: str):\n        if selection.isdigit() and int(selection) in range(1,25):\n            day = int(selection)\n            if day in self.closed_days:\n                self.closed_days.remove(day)\n                clear_console()\n                print(f\"Has abierto el día {day}\")\n            else:\n                clear_console()\n                print(f\"El día {day} ya esta abierto.\")\n            \n        else:\n            clear_console()\n            print(\"Has introducido una opción invalida. Vuelve a intentarlo\")\n\n\n    def show_calendar(self):\n\n        for row in range(1, 25, 6):\n            print(\"**** \" * 6)\n\n            print(\" \".join([f\"*{str(day).zfill(2)}*\" if day in self.closed_days else \"****\" for day in range(row, row + 6)]))\n\n            print(\"**** \" * 6)\n            print()\n\n\nmy_calendar = AdventCalendar()\n\nwhile True:\n\n    my_calendar.show_calendar()\n    print()\n    option = input(\"Introduce un día para abrir(1,24) o escribe 'salir' para terminar.\")\n\n    if option.lower() == 'salir':\n        break\n\n    my_calendar.open_day(option)\n    if not my_calendar.closed_days:\n        break\n\nclear_console()\nprint(\"Has terminado con el calendario. Felices Fiestas!\")\nmy_calendar.show_calendar()\n"
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/python/javierfiestasbotella.py",
    "content": "'''\n/*\n * EJERCICIO:\n * ¡Cada año celebramos el aDEViento! 24 días, 24 regalos para\n * developers. Del 1 al 24 de diciembre: https://adviento.dev\n * \n * Dibuja un calendario por terminal e implementa una\n * funcionalidad para seleccionar días y mostrar regalos.\n * - El calendario mostrará los días del 1 al 24 repartidos\n *   en 6 columnas a modo de cuadrícula.\n * - Cada cuadrícula correspondiente a un día tendrá un tamaño \n *   de 4x3 caracteres, y sus bordes serán asteríscos.\n * - Las cuadrículas dejarán un espacio entre ellas.\n * - En el medio de cada cuadrícula aparecerá el día entre el\n *   01 y el 24.\n *\n * Ejemplo de cuadrículas:\n * **** **** ****\n * *01* *02* *03* ...\n * **** **** ****\n *\n * - El usuario seleccioná qué día quiere descubrir.\n * - Si está sin descubrir, se le dirá que ha abierto ese día\n *   y se mostrará de nuevo el calendario con esa cuadrícula\n *   cubierta de asteríscos (sin mostrar el día).\n *\n * Ejemplo de selección del día 1\n * **** **** ****\n * **** *02* *03* ...\n * **** **** ****\n *   \n * - Si se selecciona un número ya descubierto, se le notifica\n *   al usuario.\n */\n'''\n\n\ndias = ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24']\nregalos = [\n    \"Chocolatina\",\n    \"Chicle\",\n    \"Mini paquete de caramelos\",\n    \"Nota con un mensaje positivo\",\n    \"Calcetines navideños\",\n    \"Llavero pequeño\",\n    \"Bálsamo labial\",\n    \"Velita aromática\",\n    \"Mini juguete (tipo figurita)\",\n    \"Bolsa de té o infusión\",\n    \"Pegatinas decorativas\",\n    \"Lápiz o bolígrafo bonito\",\n    \"Pequeña libreta\",\n    \"Imán decorativo\",\n    \"Mini botellita de gel o crema\",\n    \"Paquete de galletas pequeñas\",\n    \"Mini figura de madera o cerámica (como una estrella o un árbol)\",\n    \"Esponja de baño en forma navideña\",\n    \"Pinza para el pelo o goma elástica decorativa\",\n    \"Set de clips de papel bonitos\",\n    \"Mini chocolate caliente en sobre\",\n    \"Mini adorno para el árbol de Navidad\",\n    \"Tattoo temporal decorativo\",\n    \"Tarjeta para escribir deseos navideños\"\n]\ndef crea_calendario(dias):\n    # Inicializamos un índice para recorrer la lista 'dias'\n    index = 0\n\n    # Crear la matriz con valores de 'dias'\n    matriz = []\n    for _ in range(6):  # 6 filas\n        fila = []\n        for _ in range(4):  # 4 columnas\n            # Añadir el elemento actual de 'dias' a la fila\n            fila.append(f'****\\n*{dias[index]}*\\n****')\n            index += 1  # Pasar al siguiente día\n        matriz.append(fila)  # Añadir la fila a la matriz\n\n    # Mostrar la matriz\n    for fila in matriz:\n        print(fila)\nif __name__ == \"__main__\":\n    while True:\n        crea_calendario(dias)\n        print()\n        seleccion=input('Quieres seleccionar un día: s/n: ').lower()\n        if seleccion=='n':\n            break\n        elif seleccion=='s':\n            dia_seleccionado=input('Selecciona el día del calendario: ')\n            if len(dia_seleccionado)<2:\n                dia_seleccionado='0'+dia_seleccionado\n            while True:\n                if dia_seleccionado not in dias:\n                    print('El día ya ha sido abierto o no existe... prueba de nuevo: \\n')\n                    break\n                else:\n                    print(f'El Regalo para el dia {dia_seleccionado} es un : {regalos[int(dia_seleccionado)-1]}\\n')\n                    for i in range(len(dias)):\n                        if dias[i] == dia_seleccionado:\n                            dias[i] = '**'\n                    break        \n                "
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/python/juanppdev.py",
    "content": "\"\"\"\n * EJERCICIO:\n * ¡Cada año celebramos el aDEViento! 24 días, 24 regalos para\n * developers. Del 1 al 24 de diciembre: https://adviento.dev\n * \n * Dibuja un calendario por terminal e implementa una\n * funcionalidad para seleccionar días y mostrar regalos.\n * - El calendario mostrará los días del 1 al 24 repartidos\n *   en 6 columnas a modo de cuadrícula.\n * - Cada cuadrícula correspondiente a un día tendrá un tamaño \n *   de 4x3 caracteres, y sus bordes serán asteríscos.\n * - Las cuadrículas dejarán un espacio entre ellas.\n * - En el medio de cada cuadrícula aparecerá el día entre el\n *   01 y el 24.\n *\n * Ejemplo de cuadrículas:\n * **** **** ****\n * *01* *02* *03* ...\n * **** **** ****\n *\n * - El usuario seleccioná qué día quiere descubrir.\n * - Si está sin descubrir, se le dirá que ha abierto ese día\n *   y se mostrará de nuevo el calendario con esa cuadrícula\n *   cubierta de asteríscos (sin mostrar el día).\n *\n * Ejemplo de selección del día 1\n * **** **** ****\n * **** *02* *03* ...\n * **** **** ****\n *   \n * - Si se selecciona un número ya descubierto, se le notifica\n *   al usuario.\n\"\"\"\n\n# Diccionario para almacenar los estados de los días (True = descubierto, False = no descubierto)\ndias = {i: False for i in range(1, 25)}\n\ndef mostrar_calendario():\n    \"\"\"Muestra el calendario por terminal.\"\"\"\n    for fila in range(0, 24, 6):  # Dividir en filas de 6 días\n        # Parte superior de las celdas\n        print(\" \".join([\"****\" for _ in range(fila + 1, fila + 7)]))\n        # Parte central con los días o asteriscos si ya están descubiertos\n        print(\" \".join([f\"*{str(dia).zfill(2)}*\" if not dias[dia] else \"****\" for dia in range(fila + 1, fila + 7)]))\n        # Parte inferior de las celdas\n        print(\" \".join([\"****\" for _ in range(fila + 1, fila + 7)]))\n    print()  # Espaciado final\n\ndef seleccionar_dia():\n    \"\"\"Permite al usuario seleccionar un día.\"\"\"\n    while True:\n        try:\n            dia = int(input(\"Selecciona un día (1-24): \"))\n            if dia < 1 or dia > 24:\n                print(\"Por favor, selecciona un número entre 1 y 24.\")\n            elif dias[dia]:\n                print(f\"El día {dia} ya ha sido descubierto. Intenta con otro.\")\n            else:\n                dias[dia] = True\n                print(f\"Has abierto el día {dia}.\")\n                break\n        except ValueError:\n            print(\"Por favor, introduce un número válido.\")\n\ndef main():\n    \"\"\"Función principal.\"\"\"\n    print(\"¡Bienvenido al calendario de adviento para developers!\\n\")\n    while not all(dias.values()):\n        mostrar_calendario()\n        seleccionar_dia()\n    print(\"¡Has descubierto todos los días! Feliz adviento.\")\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/python/kenysdev.py",
    "content": "# _____________________________________\n# https://github.com/kenysdev\n# 2024 - Python\n# _____________________________________\n# #47  CALENDARIO DE ADVIENTO\n# ------------------------------------\n\n\"\"\"\n* EJERCICIO:\n * ¡Cada año celebramos el aDEViento! 24 días, 24 regalos para\n * developers. Del 1 al 24 de diciembre: https://adviento.dev\n * \n * Dibuja un calendario por terminal e implementa una\n * funcionalidad para seleccionar días y mostrar regalos.\n * - El calendario mostrará los días del 1 al 24 repartidos\n *   en 6 columnas a modo de cuadrícula.\n * - Cada cuadrícula correspondiente a un día tendrá un tamaño \n *   de 4x3 caracteres, y sus bordes serán asteríscos.\n * - Las cuadrículas dejarán un espacio entre ellas.\n * - En el medio de cada cuadrícula aparecerá el día entre el\n *   01 y el 24.\n *\n * Ejemplo de cuadrículas:\n * **** **** ****\n * *01* *02* *03* ...\n * **** **** ****\n *\n * - El usuario seleccioná qué día quiere descubrir.\n * - Si está sin descubrir, se le dirá que ha abierto ese día\n *   y se mostrará de nuevo el calendario con esa cuadrícula\n *   cubierta de asteríscos (sin mostrar el día).\n *\n * Ejemplo de selección del día 1\n * **** **** ****\n * **** *02* *03* ...\n * **** **** ****\n *   \n * - Si se selecciona un número ya descubierto, se le notifica\n *   al usuario.\n \"\"\"\n\nmtx = [[f\"*{i*6+j+1:02d}*\" for j in range(6)] for i in range(4)]\nln = \"**** \" * 6 + \"\\n\"\n\nwhile True:\n    for row in mtx:\n        print(ln +\" \".join(row) + \"\\n\" + ln)\n\n    day = input(\"Día a descubrir: \")\n    if day.isdigit() and int(day) > 0 and int(day) <= 24:\n        r = (int(day) - 1) // 6 \n        c = (int(day) - 1) % 6\n        if mtx[r][c] == \"****\":\n            print(f\"El día {day} ya está descubierto.\")\n        else:\n            mtx[r][c] = \"****\"\n    else:\n        print(\"Día inválido, debe ser entre 1 y 24.\")\n"
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/python/ljoecordoba.py",
    "content": "\"\"\"\nEste programa simula un calendario de Adviento interactivo llamado \"aDEViento\".\nFuncionamiento:\n1. Se representa un calendario con 24 días, distribuidos en una cuadrícula de 6 filas y 4 columnas.\n2. Los días que aún no han sido descubiertos se muestran con su número dentro de asteriscos (*XX*).\n3. Los días que han sido descubiertos se representan con asteriscos (****).\n4. El usuario puede seleccionar un día para descubrirlo hasta que todos los días sean abiertos.\n5. Se valida la entrada del usuario para evitar selecciones inválidas o repetidas.\n6. Cuando todos los días han sido descubiertos, el programa finaliza con un mensaje de felicitación.\n\"\"\"\n\ndef dibujar_calendario(dias_descubiertos):\n    # Definir la cuadrícula de 6x4x3 (6 filas, 4 columnas, cada día 4x3)\n    for fila in range(6):\n        for columna in range(4):\n            dia = fila * 4 + columna + 1  # Calcula el número de día\n            if dia > 24:  # No dibujar días fuera del rango 1-24\n                break\n            # Si el día está descubierto, dibujar los asteriscos, si no, mostrar el día\n            if dia in dias_descubiertos:\n                print(\"****\", end=\" \")\n            else:\n                print(f\"*{dia:02}*\", end=\" \")\n        print()\n\ndef seleccionar_dia(dias_descubiertos):\n    # Solicitar al usuario que seleccione un día\n    try:\n        dia = int(input(\"Selecciona el día que quieres descubrir (1-24): \"))\n        if dia < 1 or dia > 24:\n            print(\"Por favor, ingresa un número de día válido (1-24).\")\n            return\n        if dia in dias_descubiertos:\n            print(f\"¡El día {dia} ya ha sido descubierto!\")\n        else:\n            dias_descubiertos.add(dia)  # Marcar el día como descubierto\n            print(f\"¡Has abierto el día {dia}!\")\n    except ValueError:\n        print(\"Por favor, ingresa un número válido.\")\n\n\ndef main():\n    dias_descubiertos = set()  # Usamos un conjunto para almacenar los días descubiertos\n\n    while len(dias_descubiertos) < 24:  # Mientras no todos los días estén descubiertos\n        print(\"\\nCalendario de aDEViento:\")\n        dibujar_calendario(dias_descubiertos)\n        seleccionar_dia(dias_descubiertos)\n\n    print(\"\\n¡Has descubierto todos los días del aDEViento! 🎉\")\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/python/mhayhem.py",
    "content": "# @Author Daniel Grande (Mhayhem)\n\n# EJERCICIO:\n# ¡Cada año celebramos el aDEViento! 24 días, 24 regalos para\n# developers. Del 1 al 24 de diciembre: https://adviento.dev\n# \n# Dibuja un calendario por terminal e implementa una\n# funcionalidad para seleccionar días y mostrar regalos.\n# - El calendario mostrará los días del 1 al 24 repartidos\n#   en 6 columnas a modo de cuadrícula.\n# - Cada cuadrícula correspondiente a un día tendrá un tamaño \n#   de 4x3 caracteres, y sus bordes serán asteríscos.\n# - Las cuadrículas dejarán un espacio entre ellas.\n# - En el medio de cada cuadrícula aparecerá el día entre el\n#   01 y el 24.\n#\n# Ejemplo de cuadrículas:\n# **** **** ****\n# *01* *02* *03* ...\n# **** **** ****\n#\n# - El usuario selecciona qué día quiere descubrir.\n# - Si está sin descubrir, se le dirá que ha abierto ese día\n#   y se mostrará de nuevo el calendario con esa cuadrícula\n#   cubierta de asteríscos (sin mostrar el día).\n#\n# Ejemplo de selección del día 1\n# **** **** ****\n# **** *02* *03* ...\n# **** **** ****\n#   \n# - Si se selecciona un número ya descubierto, se le notifica\n#   al usuario.\n\n\ndef create_adeviento():\n    adeviento = []\n    for i in range(1, 25):\n        if i < 10:\n            adeviento.append([f\"0{int(i)}\", False])\n        else:\n                adeviento.append([str(i), False])\n    return adeviento\n\ndef show_calendar(adeviento: list):\n    row = \"**** \"\n    top_line = \"\"\n    middle_line = \"\"\n    bottom_line = \"\"\n    for i , cell in enumerate(adeviento):\n        top_line += row\n        if not cell[1]:\n            middle_line += f\"*{cell[0]}* \"\n        else:\n            middle_line += row\n        bottom_line += row\n        if (i + 1) % 6 == 0:\n            print(top_line)\n            print(middle_line)\n            print(bottom_line)\n            print()\n            top_line = \"\"\n            middle_line = \"\"\n            bottom_line = \"\"\n\ndef open_box(adeviento: list, day: int):\n    day -= 1\n    if not  adeviento[day][1]:\n        adeviento[day][1] = True\n        print(\"Caja abierta.\")\n    else:\n        print(\"La caja ya esta abierta.\")\n\ndef main():\n    adeviento = create_adeviento()\n    show_calendar(adeviento)\n    print(\"Calendario de aDEViento.\")\n    while True:\n        choose = input(\"1. Abrir caja\\n2. salir\\n\")\n        match choose:\n            case \"1\":\n                try:\n                    day = int(input(\"Indique un número del calendario de aDEViento: \"))\n                    if day < 1 or day > 24:\n                        print(\"El número ha de ser entre 1 y 24.\")\n                        continue\n                    open_box(adeviento, day)\n                except ValueError as e:\n                    print(f\"ERROR: {e}\")\n                    continue\n                show_calendar(adeviento)\n            case \"2\":\n                print(\"Saliendo del calendario de aDEViento.\")\n                break\n            case _:\n                print(\"Opción no valida.\")\n\nif __name__==\"__main__\":\n    main()"
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/python/miguelex.py",
    "content": "import math\n\nGRID_WIDTH = 4\nGRID_HEIGHT = 3\nDAYS = 24\n\ndiscovered = [False] * DAYS\n\ndef draw_calendar():\n    for row in range(math.ceil(DAYS / 6)):\n        for line in range(GRID_HEIGHT):\n            row_output = \"\"\n            for col in range(6):\n                day = row * 6 + col + 1\n                if day > DAYS:\n                    break\n\n                if line == 0 or line == 2:\n                    row_output += \"**** \"\n                elif line == 1:\n                    row_output += \"*\"\n                    if discovered[day - 1]:\n                        row_output += \"**\"\n                    else:\n                        day_str = str(day).zfill(2)\n                        row_output += day_str\n                    row_output += \"* \"\n            print(row_output)\n\ndef main():\n    while True:\n        draw_calendar()\n        try:\n            user_input = input(f\"\\nSeleccione un día (1-{DAYS}) para descubrir o escriba 0 para salir: \")\n            day = int(user_input)\n\n            if day == 0:\n                print(\"¡Gracias por participar en el aDEViento!\")\n                break\n\n            if day < 1 or day > DAYS:\n                print(f\"Por favor, elija un número válido entre 1 y {DAYS}.\")\n            elif discovered[day - 1]:\n                print(f\"El día {day} ya ha sido descubierto.\")\n            else:\n                discovered[day - 1] = True\n                print(f\"¡Has descubierto el día {day}!\")\n        except ValueError:\n            print(\"Entrada inválida. Por favor, ingrese un número válido.\")\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/python/mouredev.py",
    "content": "import calendar\n\n\nclass AdventCalendar:\n\n    def __init__(self):\n        self.days = [False] * 24\n\n    def display(self):\n\n        for row in range(0, 24, 6):\n\n            print(\"**** \" * 6)\n            print(\n                \" \".join([f\"*{str(day).zfill(2)}*\" if not self.days[day - 1] else \"****\" for day in range(row + 1, row + 7)]))\n            print(\"**** \" * 6)\n            print()\n\n    def select(self, day):\n\n        is_digit = day.isdigit()\n\n        if is_digit and int(day) > 0 and int(day) <= 24:\n            day = int(day)\n\n            if self.days[day - 1]:\n                print(\n                    f\"El día {day} ya está descubierto. Selecciona otro diferente.\")\n            else:\n                self.days[day - 1] = True\n                print(f\"Has abierto el día {day}.\")\n\n        else:\n            print(\"Selección inválida. Debes introducir un número entre 1 y 24.\")\n\n\nadvent_calendar = AdventCalendar()\n\nwhile True:\n\n    advent_calendar.display()\n\n    selection = input(\n        \"Selecciona el día que quieres descubrir (o escribe 'salir' para finalizar): \")\n\n    if selection.lower() == \"salir\":\n        print(\"Finalizando el calendario de adviento... ¡Felices fiestas!\")\n        break\n\n    advent_calendar.select(selection)\n"
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/python/neslarra.py",
    "content": "r\"\"\"\n EJERCICIO:\n ¡Cada año celebramos el aDEViento! 24 días, 24 regalos para\n developers. Del 1 al 24 de diciembre: https://adviento.dev\n \n Dibuja un calendario por terminal e implementa una\n funcionalidad para seleccionar días y mostrar regalos.\n - El calendario mostrará los días del 1 al 24 repartidos\n   en 6 columnas a modo de cuadrícula.\n - Cada cuadrícula correspondiente a un día tendrá un tamaño \n   de 4x3 caracteres, y sus bordes serán asteríscos.\n - Las cuadrículas dejarán un espacio entre ellas.\n - En el medio de cada cuadrícula aparecerá el día entre el\n   01 y el 24.\n\n Ejemplo de cuadrículas:\n **** **** ****\n *01* *02* *03* ...\n **** **** ****\n\n - El usuario seleccioná qué día quiere descubrir.\n - Si está sin descubrir, se le dirá que ha abierto ese día\n   y se mostrará de nuevo el calendario con esa cuadrícula\n   cubierta de asteríscos (sin mostrar el día).\n\n Ejemplo de selección del día 1\n **** **** ****\n ****02*03* ...\n **** **** ****\n   \n - Si se selecciona un número ya descubierto, se le notifica\n   al usuario.\n\"\"\"\n\n\ndef create_calendar(available_days: list) -> list:\n    sep_h = \"**** \" * 6\n    calendar = []\n    line = 0\n    for row in range(0, 9):\n        if not row % 2:\n            calendar.append(sep_h)\n        else:\n            row = \"*\"\n            for num in range(1, 7):\n                row += (str(num + line).rjust(2, \"0\") if num + line in available_days else \"**\") + (\"*\" if num == 6 else \"* *\")\n            line += 6\n            calendar.append(row)\n    return calendar\n\n\ndef draw_calendar(calendar: list) -> None:\n    for r in calendar:\n        print(r)\n\n\ndef menu() -> int:\n    while True:\n        day = input(\"\\nCalendario de aDEViento... selecciona uno de los días diponibles (0 para Salir): \")\n        if day.isnumeric() and 0 <= int(day) <= 24:\n            break\n        print(f\"{day} NO e sun día válido.\")\n    return int(day)\n\n\ndef validate_day(day: int, available_days: list):\n    if day in available_days:\n        return True\n    return False\n\n\ndef main():\n    available_days = list(range(1, 25))\n    while True:\n        calendar = create_calendar(available_days)\n        draw_calendar(calendar)\n        day = menu()\n        if not day:\n            break\n        if validate_day(day, available_days):\n            print(f\"Abriendo el día {day}\")\n            available_days.remove(day)\n        else:\n            print(f\"El día {day} NO está disponible.\")\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/python/rigo93acosta.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * ¡Cada año celebramos el aDEViento! 24 días, 24 regalos para\n * developers. Del 1 al 24 de diciembre: https://adviento.dev\n * \n * Dibuja un calendario por terminal e implementa una\n * funcionalidad para seleccionar días y mostrar regalos.\n * - El calendario mostrará los días del 1 al 24 repartidos\n *   en 6 columnas a modo de cuadrícula.\n * - Cada cuadrícula correspondiente a un día tendrá un tamaño \n *   de 4x3 caracteres, y sus bordes serán asteríscos.\n * - Las cuadrículas dejarán un espacio entre ellas.\n * - En el medio de cada cuadrícula aparecerá el día entre el\n *   01 y el 24.\n *\n * Ejemplo de cuadrículas:\n * **** **** ****\n * *01* *02* *03* ...\n * **** **** ****\n *\n * - El usuario seleccioná qué día quiere descubrir.\n * - Si está sin descubrir, se le dirá que ha abierto ese día\n *   y se mostrará de nuevo el calendario con esa cuadrícula\n *   cubierta de asteríscos (sin mostrar el día).\n *\n * Ejemplo de selección del día 1\n * **** **** ****\n * **** *02* *03* ...\n * **** **** ****\n *   \n * - Si se selecciona un número ya descubierto, se le notifica\n *   al usuario.\n */\n\"\"\"\n\nclass AdventCalendar:\n\n    def __init__(self):\n        self.days = set(range(1,25))\n\n    def draw_calendar(self):\n        for row in range(4):\n            for x_row in range(3):\n                for x_col in range(6):\n                    if x_row == 1:\n                        val_day = row * 6 + x_col + 1\n                        if val_day not in self.days:\n                            print('*'*4, end=\" \")\n                        else:\n                            print(f'*{row * 6 + x_col + 1:>02}*', end=\" \")\n                    else:\n                        print('*'*4, end=\" \")\n                print()\n            print()\n\n\n    def select_day(self, day) -> bool:\n        \n        if day in self.days:\n            self.days.discard(day)\n            return True\n        return False\n\nif __name__ == \"__main__\":\n\n    calendar = AdventCalendar()\n\n    while True:\n        day = input(\"Seleccione un dia: ('s' para salir) \")\n        if day.isnumeric() and 1 <= int(day) <= 24:\n            day = int(day)\n            if calendar.select_day(day):\n                print(f\"Has abierto el día {day}!\\n\")\n                calendar.draw_calendar()\n            else:\n                print(\"El día {day} ya fue descubierto!\\n\")\n        else:\n            if day == \"s\":\n                break\n            else:\n                print(\"El valor ingresado no es un número\"+\n                      \" o no está en el rango de 1 a 24.\\n\"\n                      )\n        \n"
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/rust/kenysdev.rs",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - Rust\n_____________________________________\n47  CALENDARIO DE ADVIENTO\n------------------------------------\n\n * EJERCICIO:\n * ¡Cada año celebramos el aDEViento! 24 días, 24 regalos para\n * developers. Del 1 al 24 de diciembre: https://adviento.dev\n * \n * Dibuja un calendario por terminal e implementa una\n * funcionalidad para seleccionar días y mostrar regalos.\n * - El calendario mostrará los días del 1 al 24 repartidos\n *   en 6 columnas a modo de cuadrícula.\n * - Cada cuadrícula correspondiente a un día tendrá un tamaño \n *   de 4x3 caracteres, y sus bordes serán asteríscos.\n * - Las cuadrículas dejarán un espacio entre ellas.\n * - En el medio de cada cuadrícula aparecerá el día entre el\n *   01 y el 24.\n *\n * Ejemplo de cuadrículas:\n * **** **** ****\n * *01* *02* *03* ...\n * **** **** ****\n *\n * - El usuario seleccioná qué día quiere descubrir.\n * - Si está sin descubrir, se le dirá que ha abierto ese día\n *   y se mostrará de nuevo el calendario con esa cuadrícula\n *   cubierta de asteríscos (sin mostrar el día).\n *\n * Ejemplo de selección del día 1\n * **** **** ****\n * **** *02* *03* ...\n * **** **** ****\n *   \n * - Si se selecciona un número ya descubierto, se le notifica\n *   al usuario.\n*/\n\nuse std::io::{self, Write};\n\nfn main() {\n    let mut mtx: [[String; 6]; 4] = Default::default();\n    for i in 0..4 {\n        for j in 0..6 {\n            mtx[i][j] = format!(\"*{:02}*\", i * 6 + j + 1);\n        }\n    }\n\n    let ln = \"**** \".repeat(6).trim_end().to_string();\n\n    loop {\n        for i in 0..4 {\n            println!(\"{}\", ln);\n            let current_row = i;\n\n            for j in 0..6 {\n                print!(\"{} \", mtx[current_row][j]);\n            }\n            println!(\"\\n{}\\n\", ln);\n        }\n\n        print!(\"Día a descubrir: \");\n        io::stdout().flush().unwrap();\n        let mut day = String::new();\n        io::stdin().read_line(&mut day).unwrap();\n        let day = day.trim();\n\n        let day_int: i32 = match day.parse() {\n            Ok(num) => num,\n            Err(_) => {\n                println!(\"Entrada inválida. Debe ser un número.\");\n                continue;\n            }\n        };\n\n        if day_int < 1 || day_int > 24 {\n            println!(\"Día inválido, debe ser entre 1 y 24.\");\n            continue;\n        }\n\n        let r = (day_int - 1) / 6;\n        let c = (day_int - 1) % 6;\n\n        if mtx[r as usize][c as usize] == \"****\" {\n            println!(\"El día {} ya está descubierto.\", day);\n            continue;\n        }\n\n        mtx[r as usize][c as usize] = \"****\".to_string();\n    }\n}\n"
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/sql/Nicojsuarez2.sql",
    "content": "# #47 CALENDARIO DE ADVIENTO\n> #### Dificultad: Fácil | Publicación: 25/11/24 | Corrección: 02/12/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * ¡Cada año celebramos el aDEViento! 24 días, 24 regalos para\n * developers. Del 1 al 24 de diciembre: https://adviento.dev\n * \n * Dibuja un calendario por terminal e implementa una\n * funcionalidad para seleccionar días y mostrar regalos.\n * - El calendario mostrará los días del 1 al 24 repartidos\n *   en 6 columnas a modo de cuadrícula.\n * - Cada cuadrícula correspondiente a un día tendrá un tamaño \n *   de 4x3 caracteres, y sus bordes serán asteríscos.\n * - Las cuadrículas dejarán un espacio entre ellas.\n * - En el medio de cada cuadrícula aparecerá el día entre el\n *   01 y el 24.\n *\n * Ejemplo de cuadrículas:\n * **** **** ****\n * *01* *02* *03* ...\n * **** **** ****\n *\n * - El usuario selecciona qué día quiere descubrir.\n * - Si está sin descubrir, se le dirá que ha abierto ese día\n *   y se mostrará de nuevo el calendario con esa cuadrícula\n *   cubierta de asteríscos (sin mostrar el día).\n *\n * Ejemplo de selección del día 1\n * **** **** ****\n * **** *02* *03* ...\n * **** **** ****\n *   \n * - Si se selecciona un número ya descubierto, se le notifica\n *   al usuario.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/typescript/hozlucas28.ts",
    "content": "import readline from 'node:readline/promises'\n\n/* -------------------------------------------------------------------------- */\n/*                                    TYPES                                   */\n/* -------------------------------------------------------------------------- */\n\ninterface CalendarCell {\n    discovered: boolean\n    id: number\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                   ERRORS                                   */\n/* -------------------------------------------------------------------------- */\n\nclass CalendarCellDiscoveredError extends Error {\n    public constructor(cell: CalendarCell) {\n        super(`${cell.id} calendar cell is already discovered`)\n        this.name = 'CalendarCellDiscoveredError'\n    }\n}\n\nclass CalendarDayNotFoundError extends Error {\n    public constructor(day: number) {\n        super(`${day} calendar day not found`)\n        this.name = 'CalendarDayNotFoundError'\n    }\n}\n\ninterface CalendarDayOuOfRangeErrorConstructor {\n    day: number\n    from: number\n    to: number\n}\n\nclass CalendarDayOuOfRangeError extends Error {\n    public constructor({day, from, to}: CalendarDayOuOfRangeErrorConstructor) {\n        super(\n            `${day} calendar day is out of range, it must be between ${from} and ${to} (both included)`\n        )\n        this.name = 'CalendarDayOuOfRangeError'\n    }\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                   CLASSES                                  */\n/* -------------------------------------------------------------------------- */\n\n/* -------------------------------- Calendar -------------------------------- */\n\ninterface ICalendar {\n    getArray2D: () => CalendarCell[][]\n    getFrom: () => number\n    getTo: () => number\n\n    discoverDay: (day: number) => void\n    toPrint: () => string\n}\n\ninterface CalendarConstructor {\n    from: number\n    to: number\n}\n\nclass Calendar implements ICalendar {\n    static rows: number = 4\n    static cols: number = 6\n\n    private array2D: CalendarCell[][]\n    private readonly from: number\n    private readonly to: number\n\n    public constructor({from, to}: CalendarConstructor) {\n        let i: number\n        let j: number\n        let counter: number = from\n\n        this.from = from\n        this.to = to\n\n        this.array2D = Array(Calendar.rows)\n        for (i = 0; i < Calendar.rows; i++) {\n            this.array2D[i] = Array(Calendar.cols)\n\n            for (j = 0; j < Calendar.cols; j++) {\n                this.array2D[i][j] = {discovered: false, id: counter}\n                counter++\n            }\n        }\n    }\n\n    public getArray2D(): CalendarCell[][] {\n        return this.array2D\n    }\n\n    public getFrom(): number {\n        return this.from\n    }\n\n    public getTo(): number {\n        return this.to\n    }\n\n    public discoverDay(day: number): void {\n        let i: number\n        let j: number\n        let flag: boolean = false\n        let counter: number = this.from\n\n        if (day < this.from || day > this.to)\n            throw new CalendarDayOuOfRangeError({\n                day,\n                from: this.from,\n                to: this.to,\n            })\n\n        for (i = 0; counter <= this.to && i < this.array2D.length; i++) {\n            for (j = 0; counter <= this.to && j < this.array2D[i].length; j++) {\n                if (this.array2D[i][j].id === day) {\n                    if (this.array2D[i][j].discovered)\n                        throw new CalendarCellDiscoveredError(\n                            this.array2D[i][j]\n                        )\n\n                    this.array2D[i][j].discovered = true\n                    flag = true\n                    break\n                }\n\n                counter++\n            }\n\n            if (flag) break\n        }\n\n        if (!flag) throw new CalendarDayNotFoundError(day)\n    }\n\n    public toPrint(): string {\n        let calendarPrintable: string[] = []\n\n        let i: number\n        let j: number\n        let counter: number = this.from\n\n        let row: CalendarCell[]\n        let col: CalendarCell\n        let rowPrintable: string\n\n        for (i = 0; counter <= this.to && i < this.array2D.length; i++) {\n            row = this.array2D[i]\n\n            rowPrintable = i === 0 ? '' : '\\n'\n            rowPrintable +=\n                `${'*'.repeat(4)} `.repeat(row.length).trimEnd() + '\\n'\n\n            for (j = 0; counter <= this.to && j < row.length; j++) {\n                col = row[j]\n\n                rowPrintable += `*${\n                    col.discovered\n                        ? ''.padStart(2, '*')\n                        : col.id.toString().padStart(2, '0')\n                }* `\n\n                counter++\n            }\n\n            rowPrintable = rowPrintable.trimEnd() + '\\n'\n            rowPrintable += `${'*'.repeat(4)} `.repeat(row.length).trimEnd()\n\n            calendarPrintable.push(rowPrintable)\n        }\n\n        return calendarPrintable.join('\\n')\n    }\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\n;(async () => {\n    const calendar: ICalendar = new Calendar({\n        from: 1,\n        to: 24,\n    })\n\n    const rl: readline.Interface = readline.createInterface({\n        input: process.stdin,\n        output: process.stdout,\n    })\n\n    let input01: string\n    let input02: string\n\n    console.log(calendar.toPrint())\n\n    console.log(\n        '\\n> Available operations...\\n\\n' +\n            '  1 - Discover day.\\n' +\n            '  0 - Exit.'\n    )\n\n    input01 = (await rl.question('\\n> Enter an operation: ')).trim()\n\n    while (input01 != '0') {\n        switch (input01) {\n            case '1':\n                input02 = (\n                    await rl.question('\\n> Enter the day to discover: ')\n                ).trim()\n\n                try {\n                    calendar.discoverDay(parseInt(input02))\n                    console.clear()\n                    console.log(`> Day ${input02} discovered!`)\n                } catch (error) {\n                    if (error instanceof CalendarDayOuOfRangeError) {\n                        console.clear()\n                        console.error(\n                            `\\n> The day ${input02} must be between ${calendar.getFrom()} and ${calendar.getTo()} (both included)!`\n                        )\n                    } else if (error instanceof CalendarCellDiscoveredError) {\n                        console.clear()\n                        console.error(\n                            `\\n> The day ${input02} is already discovered!`\n                        )\n                    } else if (error instanceof CalendarDayNotFoundError) {\n                        console.clear()\n                        console.error(\n                            `\\n> ${input02} day not found in the calendar!`\n                        )\n                    } else {\n                        console.clear()\n                        console.error(\n                            '\\n> An error occurred on discover the day!'\n                        )\n                    }\n                }\n                break\n\n            default:\n                console.clear()\n                console.log('\\n> Invalid operation! Try again...')\n        }\n\n        console.log(`\\n${calendar.toPrint()}`)\n\n        console.log(\n            '\\n> Available operations...\\n\\n' +\n                '  1 - Discover day.\\n' +\n                '  0 - Exit.'\n        )\n\n        input01 = (await rl.question('\\n> Enter an operation: ')).trim()\n    }\n\n    rl.close()\n})()\n"
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/typescript/miguelex.ts",
    "content": "const GRID_WIDTH = 4;\nconst GRID_HEIGHT = 3;\nconst DAYS = 24;\n\nconst discovered: boolean[] = Array(DAYS).fill(false);\n\nfunction drawCalendar(discovered: boolean[]): void {\n    for (let row = 0; row < Math.ceil(DAYS / 6); row++) {\n        for (let line = 0; line < GRID_HEIGHT; line++) {\n            let rowOutput = \"\";\n            for (let col = 0; col < 6; col++) {\n                const day = row * 6 + col + 1;\n                if (day > DAYS) break;\n\n                switch (line) {\n                    case 0:\n                    case 2:\n                        rowOutput += \"*\".repeat(GRID_WIDTH) + \" \";\n                        break;\n                    case 1:\n                        rowOutput += \"*\";\n                        rowOutput += discovered[day - 1]\n                            ? \"*\".repeat(GRID_WIDTH - 2)\n                            : day.toString().padStart(2, \"0\").padEnd(GRID_WIDTH - 2, \" \");\n                        rowOutput += \"* \";\n                        break;\n                }\n            }\n            console.log(rowOutput);\n        }\n    }\n}\n\nfunction promptUser(): void {\n    drawCalendar(discovered);\n\n    const readline = require(\"readline\");\n    const rl = readline.createInterface({\n        input: process.stdin,\n        output: process.stdout\n    });\n\n    rl.question(`\\nSeleccione un día (1-${DAYS}) para descubrir o escriba 0 para salir: `, (input: string) => {\n        const day = parseInt(input, 10);\n\n        if (day === 0) {\n            console.log(\"¡Gracias por participar en el aDEViento!\");\n            rl.close();\n            return;\n        }\n\n        if (isNaN(day) || day < 1 || day > DAYS) {\n            console.log(`Por favor, elija un número válido entre 1 y ${DAYS}.`);\n        } else if (discovered[day - 1]) {\n            console.log(`El día ${day} ya ha sido descubierto.`);\n        } else {\n            discovered[day - 1] = true;\n            console.log(`¡Has descubierto el día ${day}!`);\n        }\n\n        rl.close();\n        promptUser();\n    });\n}\n\n\npromptUser();\n"
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/typescript/teren91.ts",
    "content": "/*\n * EJERCICIO:\n * ¡Cada año celebramos el aDEViento! 24 días, 24 regalos para\n * developers. Del 1 al 24 de diciembre: https://adviento.dev\n * \n * Dibuja un calendario por terminal e implementa una\n * funcionalidad para seleccionar días y mostrar regalos.\n * - El calendario mostrará los días del 1 al 24 repartidos\n *   en 6 columnas a modo de cuadrícula.\n * - Cada cuadrícula correspondiente a un día tendrá un tamaño \n *   de 4x3 caracteres, y sus bordes serán asteríscos.\n * - Las cuadrículas dejarán un espacio entre ellas.\n * - En el medio de cada cuadrícula aparecerá el día entre el\n *   01 y el 24.\n *\n * Ejemplo de cuadrículas:\n * **** **** ****\n * *01* *02* *03* ...\n * **** **** ****\n *\n * - El usuario seleccioná qué día quiere descubrir.\n * - Si está sin descubrir, se le dirá que ha abierto ese día\n *   y se mostrará de nuevo el calendario con esa cuadrícula\n *   cubierta de asteríscos (sin mostrar el día).\n *\n * Ejemplo de selección del día 1\n * **** **** ****\n * **** *02* *03* ...\n * **** **** ****\n *   \n * - Si se selecciona un número ya descubierto, se le notifica\n *   al usuario.\n */\nimport * as promptSync from \"prompt-sync\";\n\nconst prompt = promptSync();\n\n\nfunction calendario() {\n    var dia: number = 0;\n    var calendario: string = \"\";\n    var opcion: string | null = \"\";\n    var diaElegido: number = 0;\n    var diasRegalos: number[] = [];\n\n    while(opcion != \"salir\")\n    {\n        opcion = prompt(\"¿Qué día quieres descubrir? (1-24). Escribe 'salir' para salir del programa: \");\n        \n        if(opcion == null)\n        {\n            console.log(\"No has introducido ninguna opción, por favor intentalo de nuevo.\");\n            continue;\n        }\n        if(opcion == \"salir\")\n        {\n            console.log(\"Hasta pronto!\");\n            break;\n        }\n\n        diaElegido = parseInt(opcion);\n\n        if(isNaN(diaElegido)){ \n            console.log(\"No has introducido ninguna opción, por favor intentalo de nuevo.\");\n            continue;\n        }\n\n        if(diaElegido < 1 || diaElegido > 24){\n            console.log(\"El día no es correcto, por favor intentalo de nuevo.\");\n            continue;\n        }\n\n        if(diasRegalos.includes(diaElegido)){\n            console.log(\"Ya has descubierto ese día, por favor intentalo de nuevo.\");\n            continue;\n        }\n\n        diasRegalos.push(diaElegido);\n\n        console.log(\"Enhorabuena!! Has descubierto el día \" + diaElegido);\n\n        dia = 0;\n        calendario = \"\";\n        for (let i = 0; i < 4; i++) {      \n            //Inicio del calendario\n            for(let j = 0; j < 6; j++) {\n                calendario += \"\".repeat(j) + \"*\".repeat(4) + \" \";\n            }\n    \n            calendario += \"\\n\";\n            for(let j = 0; j < 6; j++) {\n                dia++;\n                if(diasRegalos.includes(dia))\n                {                    \n                    calendario += \"**** \";                         \n                }else\n                {\n                    if(dia < 10)\n                    {\n                        calendario += \"*\" + \"\".padStart(1, \"0\") + dia + \"* \" ;     \n                    }\n                    else{\n                        calendario += \"*\" + dia + \"* \"; \n                    }\n                }            \n            }\n            calendario += \"\\n\"\n        }\n        //Cierre del calendario\n        for(let j = 0; j < 6; j++) {\n            calendario += \"\".repeat(j) + \"*\".repeat(4) + \" \";\n        }\n\n        calendario += \"\\n\";\n        console.log(calendario);\n    }\n}\n\ncalendario();\n"
  },
  {
    "path": "Roadmap/47 - CALENDARIO DE ADVIENTO/vb.net/kenysdev.vb",
    "content": "' _____________________________________\n' https://github.com/kenysdev\n' 2024 - vb.net\n' _____________________________________\n' 47  CALENDARIO DE ADVIENTO\n' ------------------------------------\n'* EJERCICIO:\n'* ¡Cada año celebramos el aDEViento! 24 días, 24 regalos para\n'* developers. Del 1 al 24 de diciembre: https : //adviento.dev\n'* \n'* Dibuja un calendario por terminal e implementa una\n'* funcionalidad para seleccionar días y mostrar regalos.\n'* - El calendario mostrará los días del 1 al 24 repartidos\n'*   en 6 columnas a modo de cuadrícula.\n'* - Cada cuadrícula correspondiente a un día tendrá un tamaño \n'*   de 4x3 caracteres, y sus bordes serán asteríscos.\n'* - Las cuadrículas dejarán un espacio entre ellas.\n'* - En el medio de cada cuadrícula aparecerá el día entre el\n'*   01 y el 24.\n'*\n'* Ejemplo de cuadrículas:\n'* **** **** ****\n'* *01* *02* *03* ...\n'* **** **** ****\n'*\n'* - El usuario seleccioná qué día quiere descubrir.\n'* - Si está sin descubrir, se le dirá que ha abierto ese día\n'*   y se mostrará de nuevo el calendario con esa cuadrícula\n'*   cubierta de asteríscos (sin mostrar el día).\n'*\n'* Ejemplo de selección del día 1\n'* **** **** ****\n'* **** *02* *03* ...\n'* **** **** ****\n'*   \n'* - Si se selecciona un número ya descubierto, se le notifica\n'*   al usuario.\n\nModule exs47\n    Sub Main()\n        Dim mtx(3, 5) As String\n        For i As Integer = 0 To 3\n            For j As Integer = 0 To 5\n                mtx(i, j) = $\"*{(i * 6 + j + 1):00}*\"\n            Next\n        Next\n\n        Dim ln As String = String.Join(\" \", Enumerable.Repeat(\"****\", 6))\n\n        While True\n            For i As Integer = 0 To 3\n                Console.WriteLine(ln)\n                Dim currentRow As Integer = i\n                For j As Integer = 0 To 5\n                    Console.Write(mtx(currentRow, j) & \" \")\n                Next\n                Console.WriteLine(vbCrLf & ln & vbCrLf)\n            Next\n\n            Console.Write(\"Día a descubrir: \")\n            Dim day As String = Console.ReadLine()\n\n            If Not Integer.TryParse(day, Nothing) Then\n                Console.WriteLine(\"Entrada inválida. Debe ser un número.\")\n                Continue While\n            End If\n\n            Dim dayInt As Integer = Convert.ToInt32(day)\n            If dayInt < 1 Or dayInt > 24 Then\n                Console.WriteLine(\"Día inválido, debe ser entre 1 y 24.\")\n                Continue While\n            End If\n\n            Dim r As Integer = (dayInt - 1) \\ 6\n            Dim c As Integer = (dayInt - 1) Mod 6\n\n            If mtx(r, c) = \"****\" Then\n                Console.WriteLine($\"El día {day} ya está descubierto.\")\n                Continue While\n            End If\n\n            mtx(r, c) = \"****\"\n        End While\n    End Sub\nEnd Module\n"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/bash/arturonavas.sh",
    "content": "#!/bin/bash\n: '\n/*\n * EJERCICIO:\n * ¡Ha comenzado diciembre! Es hora de montar nuestro\n * árbol de Navidad...\n *\n * Desarrolla un programa que cree un árbol de Navidad\n * con una altura dinámica definida por el usuario por terminal.\n *\n * Ejemplo de árbol de altura 5 (el tronco siempre será igual):\n *\n *     *\n *    ***\n *   *****\n *  *******\n * *********\n *    |||\n *    |||\n *\n * El usuario podrá seleccionar las siguientes acciones:\n * \n * - Añadir o eliminar la estrella en la copa del árbol (@)\n * - Añadir o eliminar bolas de dos en dos (o) aleatoriamente\n * - Añadir o eliminar luces de tres en tres (+) aleatoriamente\n * - Apagar (*) o encender (+) las luces (conservando su posición)\n * - Una luz y una bola no pueden estar en el mismo sitio\n *\n * Sólo puedes añadir una estrella, y tantas luces o bolas\n * como tengan cabida en el árbol. El programa debe notificar\n * cada una de las acciones (o por el contrario, cuando no\n * se pueda realizar alguna).\n */\n'\n# variables basicas (son booleanas)\naltura=0\nestrella=0\nbola=0\nluz=0\nluz_on=1\n\ndibujar() {\n    clear\n    echo \":::::. arbol de navidad .:::::\"\n    echo\n    echo\n    \n    # parte de arriba | hojasd\n    for ((i=1; i<=$altura; i++)); do\n        espacios=$((altura - i+1)) #para que no este pegado al borde\n        printf \"%${espacios}s\"\n        \n    # no se como agregar aleatoriamente los simbolos al arbol\n\n        for ((j=1; j<=2*i-1; j++)); do\n            if ((i == 1)) && ((estrella == 1)); then\n                echo -n \"@\"\n            elif ((bola == 1)) && ((j % 2 == 0)); then\n                echo -n \"o\"\n            elif ((luz == 1)) && ((j % 3 == 0)); then\n                ((luz_on)) && echo -n \"+\" || echo -n \"-\"\n            else\n                echo -n \"*\"\n            fi\n        done\n        echo\n    done\n    \n    # tronco\n    printf \"%$((altura - 1))s\"\n        echo \"|||\"\n    printf \"%$((altura - 1))s\"\n        echo \"|||\"\n}\n\nmenu() {\n    echo\n    echo \"1. poner o quitar estrella (@)\"\n    echo \"2. poner o quitar bolas (o)\"\n    echo \"3. poner o quitar luces (+)\"\n    echo \"4. prender o apagar luces\"\n    echo \"5. salir\"\n}\n\nmain() {\n    read -p \"altura del arbol: \" altura\n    \n    while true; do\n        dibujar\n        menu\n        read -p \"opcion: \" op\n\n# este operador \"\"variable ^=1\" hace la funcion de un switch enciende y apaga (1 o 0) al activarse\n        \n        case $op in\n            1) ((estrella ^=1)) ;;\n            2) ((bola ^=1)) ;;\n            3) ((luz ^=1)) ;;\n            4) ((luz_on ^=1)) ;;\n            5) exit ;;\n            *) echo \"error opcion no valida x_x\" ;;\n        esac\n    done\n}\n\nmain"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/c#/hequebo.cs",
    "content": "class ChristmasTree\n{\n    private int _height;\n    private int _width;\n    private int _center;\n    private char[,] _tree;\n    private List<(int, int)> _balls;\n    private List<(int, int)> _lights;\n    private bool _lightsOn;\n\n    public ChristmasTree(int height)\n    {\n        _height = height;\n        _width = _height * 2 - 1;\n        _tree = new char[_width, _height + 2];\n        _center = _width / 2;\n        _balls = new List<(int, int)>();\n        _lights = new List<(int, int)>();\n        _lightsOn = false;\n\n        for (int i = 0; i < _width; i++)\n            for (int j = 0; j < _height + 2; j++)\n                _tree[i, j] = ' ';\n\n        for (int i = 0; i < _height; i++)\n            for (int j = _center - i; j <= _center + i; j++)\n                _tree[j, i] = '*';\n\n        for (int i = _height; i < _height + 2; i++)\n            for (int j = _center - 1; j <= _center + 1; j++)\n                _tree[j, i] = '|';\n        DrawTree();\n    }\n    private void DrawTree()\n    {\n        for (int i = 0; i < _height + 2; i++)\n        {\n            for (int j = 0; j < _width; j++)\n                Console.Write(_tree[j, i]);\n            Console.WriteLine();\n        }\n    }\n    public void AddStar()\n    {\n        if (_tree[_center, 0] == '@')\n            Console.WriteLine(\"El arbol ya tiene una estrella...\");\n        else\n        {\n            _tree[_center, 0] = '@';\n            Console.WriteLine(\"Se ha agregado una estrella al árbol...\");\n        }\n            \n        DrawTree();\n    }\n    public void RemoveStar()\n    {\n        if (_tree[_center, 0] != '@')\n            Console.WriteLine(\"El arbol no cuenta con una estrella...\");\n        else\n        {\n            _tree[_center, 0] = '*';\n            Console.WriteLine(\"Se quitado la estrella en el árbol\");\n        }\n            \n        DrawTree();\n    }\n    public void AddBalls()\n    {\n        var availableSpots = GetAvailableSpots();\n        if (availableSpots.Count < 2)\n            Console.WriteLine(\"No hay espacio suficiente para añadir más esferas...\");\n        else\n        {\n            _balls.AddRange(new List<(int, int)> {\n            (availableSpots[0].Item1, availableSpots[0].Item2),\n            (availableSpots[1].Item1, availableSpots[1].Item2)\n            }\n            );\n            _tree[availableSpots[0].Item1, availableSpots[0].Item2] = 'o';\n            _tree[availableSpots[1].Item1, availableSpots[1].Item2] = 'o';\n            Console.WriteLine(\"Se han agregado dos esferas al árbol...\");\n        }\n        DrawTree();\n    }\n    public void RemoveBalls()\n    {\n        if (_balls.Count < 2)\n            Console.WriteLine(\"No ha suficientes esferas para quitar...\");\n        else\n        {\n            Random random = new Random();\n            var balls = _balls.OrderBy(a => random.Next()).ToList();\n\n            _tree[balls[0].Item1, balls[0].Item2] = '*';\n            _tree[balls[1].Item1, balls[1].Item2] = '*';\n\n            _balls.Remove((balls[0].Item1, balls[0].Item2));\n            _balls.Remove((balls[1].Item1, balls[1].Item2));\n            Console.WriteLine(\"Se han removido dos esferas del árbol...\");\n        }\n        DrawTree();\n    }\n    public void AddLights()\n    {\n        var availableSpots = GetAvailableSpots();\n        if (availableSpots.Count < 3)\n            Console.WriteLine(\"No hay espacios suficientes para colocar las luces\");\n        else\n        {\n            _lights.AddRange(new List<(int, int)>\n            {\n                (availableSpots[0].Item1, availableSpots[0].Item2),\n                (availableSpots[1].Item1, availableSpots[1].Item2),\n                (availableSpots[2].Item1, availableSpots[2].Item2)\n            });\n\n            _tree[availableSpots[0].Item1, availableSpots[0].Item2] = _lightsOn ? '+' : '*';\n            _tree[availableSpots[1].Item1, availableSpots[1].Item2] = _lightsOn ? '+' : '*';\n            _tree[availableSpots[2].Item1, availableSpots[2].Item2] = _lightsOn ? '+' : '*';\n\n            Console.WriteLine(\"Se agregaron tres luces al árbol...\");\n        }\n        DrawTree();\n    }\n    public void RemoveLights()\n    {\n        if (_lights.Count < 3)\n            Console.WriteLine(\"No ha suficientes luces para quitar...\");\n        else\n        {\n            Random random = new Random();\n            var lights = _lights.OrderBy(l => random.Next()).ToList();\n\n            _tree[lights[0].Item1, lights[0].Item2] = '*';\n            _tree[lights[1].Item1, lights[1].Item2] = '*';\n            _tree[lights[2].Item1, lights[2].Item2] = '*';\n\n            _lights.Remove((lights[0].Item1, lights[0].Item2));\n            _lights.Remove((lights[1].Item1, lights[1].Item2));\n            _lights.Remove((lights[2].Item1, lights[2].Item2));\n            Console.WriteLine(\"Se han removido tres luces del árbol...\");\n        }\n        DrawTree();\n    }\n    public void ToggleLights(bool turnOn)\n    {\n        if (_lights.Count == 0)\n            Console.WriteLine(\"No hay luces disponibles...\");\n        else\n        {\n            _lightsOn = turnOn;\n            foreach (var light in _lights)\n                _tree[light.Item1, light.Item2] = _lightsOn ? '+' : '*';\n        }\n        DrawTree();\n\n    }\n    public void LightAnimation()\n    {\n        int i = 0;\n        while (i < 30)\n        {\n            Console.Clear();\n            ToggleLights(!_lightsOn);\n            i++;\n            Thread.Sleep(600);\n        }\n    }\n    private List<(int, int)> GetAvailableSpots()\n    {\n        List<(int, int)> availableSpots = new List<(int, int)>();\n\n        for (int i = 0; i < _height; i++)\n        {\n            for (int j = 0; j < _width; j++)\n            {\n                if (_tree[j, i] == '*' && !_lights.Contains((j, i)))\n                    availableSpots.Add((j, i));\n            }\n        }\n        availableSpots.Remove((_center, 0));\n        Random random = new Random();\n        availableSpots = availableSpots.OrderBy(a => random.Next()).ToList();\n        return availableSpots;\n    }\n}\nclass Program\n{\n    static void Main(string[] args)\n    {\n        Console.WriteLine(\"----ARBOL DE NAVIDAD----\");\n        Console.WriteLine(\"Ingresa la altura de tu árbol\");\n        int.TryParse(Console.ReadLine(), out int height);\n        if (height <= 3)\n        {\n            Console.WriteLine(\"La altura de tu árbol debe de ser por lo menos de tres (3) unidades...\");\n            return;\n        }\n        ChristmasTree tree = new ChristmasTree(height);\n        bool exit = false;\n\n        do\n        {\n            Menu();\n            int.TryParse(Console.ReadLine() , out int option);\n            switch (option)\n            {\n                case 1:\n                    Console.Clear();\n                    tree.AddStar();\n                    break;\n                case 2:\n                    Console.Clear();\n                    tree.RemoveStar();\n                    break;\n                case 3: \n                    Console.Clear();\n                    tree.AddBalls();\n                    break;\n                case 4:\n                    Console.Clear();\n                    tree.RemoveBalls();\n                    break;\n                case 5:\n                    Console.Clear();\n                    tree.AddLights();\n                    break;\n                case 6:\n                    Console.Clear();\n                    tree.RemoveLights();\n                    break;\n                case 7:\n                    Console.Clear();\n                    tree.ToggleLights(true);\n                    break;\n                case 8:\n                    Console.Clear();\n                    tree.ToggleLights(false);\n                    break;\n                case 9:\n                    tree.LightAnimation();\n                    break;\n                case 10:\n                    Console.Clear();\n                    exit = true;\n                    Console.WriteLine(\"Hasta la próxima y feliz navidad...\");\n                    Thread.Sleep(1000);\n                    break;\n                default:\n                    Console.Clear();\n                    Console.WriteLine(\"Opción no válida...\");\n                    break;\n            }\n        } while (!exit);\n    }\n    static void Menu()\n    {\n        Console.WriteLine(\"----ACCIONES DISPONIBLES----\");\n        Console.WriteLine(\"1.- Agregar una estrella en la copa.\");\n        Console.WriteLine(\"2.- Remover estrella de la copa.\");\n        Console.WriteLine(\"3.- Agregar esferas.\");\n        Console.WriteLine(\"4.- Remover esferas.\");\n        Console.WriteLine(\"5.- Agregar luces.\");\n        Console.WriteLine(\"6.- Remover luces.\");\n        Console.WriteLine(\"7.- Encender luces.\");\n        Console.WriteLine(\"8.- Apagar luces.\");\n        Console.WriteLine(\"9.- Animación de luces.\");\n        Console.WriteLine(\"10.- Salir.\");\n        Console.WriteLine(\"Selecciona la opción deseada...\");\n    }\n}"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/c#/kenysdev.cs",
    "content": "namespace exs48;\n/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - C#\n_____________________________________\n48 ÁRBOL DE NAVIDAD\n------------------------------------\n\n * EJERCICIO:\n * ¡Ha comenzado diciembre! Es hora de montar nuestro\n * árbol de Navidad...\n * \n * Desarrolla un programa que cree un árbol de Navidad\n * con una altura dinámica definida por el usuario por terminal.\n * \n * Ejemplo de árbol de altura 5 (el tronco siempre será igual):\n * \n *     *\n *    ***\n *   *****\n *  *******\n * *********\n *    |||\n *    |||\n *\n * El usuario podrá seleccionar las siguientes acciones:\n * \n * - Añadir o eliminar la estrella en la copa del árbol (@)\n * - Añadir o eliminar bolas de dos en dos (o) aleatoriamente\n * - Añadir o eliminar luces de tres en tres (+) aleatoriamente\n * - Apagar (*) o encender (+) las luces (conservando su posición)\n * - Una luz y una bola no pueden estar en el mismo sitio\n *\n * Sólo puedes añadir una estrella, y tantas luces o bolas\n * como tengan cabida en el árbol. El programa debe notificar\n * cada una de las acciones (o por el contrario, cuando no\n * se pueda realizar alguna).\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Threading;\n\nclass ChristmasTree\n{\n    private readonly int _size;\n    private readonly char[,] _matrix;\n    private readonly (int Row, int Col) _star;\n    private readonly List<(int Row, int Col)> _treeTop = [];\n    private readonly List<(int Row, int Col)> _balls = [];\n    private readonly List<(int Row, int Col)> _lights = [];\n\n    public ChristmasTree(int size)\n    {\n        _size = size;\n        _matrix = new char[size, size * 2 - 1];\n        _star = (0, size - 1);\n        \n        for (int i = 0; i < size; i++)\n        {\n            for (int j = 0; j < size * 2 - 1; j++)\n            {\n                _matrix[i, j] = ' ';\n            }\n        }\n    }\n\n    public void PrintTree()\n    {\n        Console.WriteLine();\n        for (int i = 0; i < _size; i++)\n        {\n            for (int j = 0; j < _size * 2 - 1; j++)\n            {\n                Console.Write(_matrix[i, j]);\n            }\n            Console.WriteLine();\n        }\n\n        var spaces = (_size * 2 - 4) / 2;\n        Console.WriteLine(new string(' ', spaces) + \"|||\");\n        Console.WriteLine(new string(' ', spaces) + \"|||\");\n    }\n\n    public void CreateTree()\n    {\n        var center = _size - 1;\n        for (int i = 0; i < _size; i++)\n        {\n            var asterisks = new string('*', i * 2 + 1);\n            for (int j = 0; j < asterisks.Length; j++)\n            {\n                var col = center - i + j;\n                _matrix[i, col] = asterisks[j];\n                _treeTop.Add((i, col));\n            }\n        }\n\n        _treeTop.RemoveAt(0);\n    }\n\n    public void AddRemoveStar()\n    {\n        var (row, col) = _star;\n        _matrix[row, col] = _matrix[row, col] == '*' ? '@' : '*';\n    }\n\n    public void AddBalls()\n    {\n        if (_treeTop.Count < 2)\n        {\n            Console.WriteLine(\"Ya no hay espacio para poner bolas.\");\n            return;\n        }\n\n        var random = Random.Shared;\n        var positions = new List<(int Row, int Col)>();\n        \n        for (int i = 0; i < 2; i++)\n        {\n            var idx = random.Next(_treeTop.Count);\n            positions.Add(_treeTop[idx]);\n            _treeTop.RemoveAt(idx);\n        }\n\n        foreach (var pos in positions)\n        {\n            _balls.Add(pos);\n            _matrix[pos.Row, pos.Col] = 'o';\n        }\n    }\n\n    public void RemoveBalls()\n    {\n        if (_balls.Count == 0)\n        {\n            Console.WriteLine(\"No hay bolas que eliminar.\");\n            return;\n        }\n\n        var random = Random.Shared;\n        var positions = new List<(int Row, int Col)>();\n        \n        for (int i = 0; i < 2 && _balls.Count > 0; i++)\n        {\n            var idx = random.Next(_balls.Count);\n            positions.Add(_balls[idx]);\n            _balls.RemoveAt(idx);\n        }\n\n        foreach (var pos in positions)\n        {\n            _treeTop.Add(pos);\n            _matrix[pos.Row, pos.Col] = '*';\n        }\n    }\n\n    public void AddLights()\n    {\n        if (_treeTop.Count < 3)\n        {\n            Console.WriteLine(\"Ya no hay espacio para poner luces.\");\n            return;\n        }\n\n        var random = Random.Shared;\n        var positions = new List<(int Row, int Col)>();\n        \n        for (int i = 0; i < 3; i++)\n        {\n            var idx = random.Next(_treeTop.Count);\n            positions.Add(_treeTop[idx]);\n            _treeTop.RemoveAt(idx);\n        }\n\n        foreach (var pos in positions)\n        {\n            _lights.Add(pos);\n            _matrix[pos.Row, pos.Col] = '+';\n        }\n    }\n\n    public void RemoveLights()\n    {\n        if (_lights.Count == 0)\n        {\n            Console.WriteLine(\"No hay luces que eliminar.\");\n            return;\n        }\n\n        var random = Random.Shared;\n        var positions = new List<(int Row, int Col)>();\n        \n        for (int i = 0; i < 3 && _lights.Count > 0; i++)\n        {\n            var idx = random.Next(_lights.Count);\n            positions.Add(_lights[idx]);\n            _lights.RemoveAt(idx);\n        }\n\n        foreach (var pos in positions)\n        {\n            _treeTop.Add(pos);\n            _matrix[pos.Row, pos.Col] = '*';\n        }\n    }\n\n    public void OnOffLights()\n    {\n        if (_lights.Count == 0)\n        {\n            Console.WriteLine(\"No hay luces.\");\n            return;\n        }\n\n        foreach (var (Row, Col) in _lights)\n        {\n            _matrix[Row, Col] = _matrix[Row, Col] == '*' ? '+' : '*';\n        }\n    }\n\n    public void AutomaticLights()\n    {\n        while (true)\n        {\n            Console.Clear();\n            foreach (var (Row, Col) in _lights)\n            {\n                _matrix[Row, Col] = _matrix[Row, Col] == '*' ? '+' : '*';\n            }\n            PrintTree();\n            Thread.Sleep(1000);\n        }\n    }\n}\n\nclass Program\n{\n    private const string Menu = @\"\n1 - Agregar/Remover estrella.\n2 - Agregar bolas.    | 3 - Quitar bolas.\n4 - Agregar luces.    | 5 - Quitar luces.\n6 - Encender/Apagar luces.\n7 - Luces automáticas.| 8 - Salir\n\";\n\n    private static void ShowMenu(ChristmasTree tree)\n    {\n        while (true)\n        {\n            tree.PrintTree();\n            Console.WriteLine(Menu);\n            Console.Write(\"Opción: \");\n            var option = Console.ReadLine();\n\n            switch (option)\n            {\n                case \"1\": tree.AddRemoveStar(); break;\n                case \"2\": tree.AddBalls(); break;\n                case \"3\": tree.RemoveBalls(); break;\n                case \"4\": tree.AddLights(); break;\n                case \"5\": tree.RemoveLights(); break;\n                case \"6\": tree.OnOffLights(); break;\n                case \"7\": tree.AutomaticLights(); break;\n                case \"8\": return;\n                default: Console.WriteLine(\"Opción inválida.\"); break;\n            }\n        }\n    }\n\n    private static int GetSize()\n    {\n        while (true)\n        {\n            Console.Write(\"Tamaño: \");\n            if (int.TryParse(Console.ReadLine(), out int size) && size % 2 != 0 && size >= 3)\n            {\n                return size;\n            }\n            Console.WriteLine(\"Debe ser un número impar >= 3.\");\n        }\n    }\n\n    public static void Main()\n    {\n        var size = GetSize();\n        var christmasTree = new ChristmasTree(size);\n        christmasTree.CreateTree();\n        ShowMenu(christmasTree);\n    }\n}\n"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/c++/hectorio23.cpp",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\n#include <iostream>\n#include <vector>\n#include <string>\n#include <cstdlib>\n#include <ctime>\n\nusing namespace std;\n\n// Estructura para representar el árbol\ntypedef vector<string> Tree;\n\nvoid drawTree(const Tree& tree) {\n    for (const string& line : tree) {\n        cout << line << endl;\n    }\n    cout << endl;\n}\n\nvoid initializeTree(Tree& tree, int height, bool hasStar) {\n    tree.clear();\n\n    if (hasStar) {\n        tree.push_back(string(height, ' ') + \"@\");\n    }\n\n    for (int i = 0; i < height; i++) {\n        int width = 2 * i + 1;\n        string row = string(height - i - 1, ' ') + string(width, '*');\n        tree.push_back(row);\n    }\n\n    string trunk = string(height - 1, ' ') + \"|||\";\n    tree.push_back(trunk);\n    tree.push_back(trunk);\n}\n\nvoid toggleStar(Tree& tree, int height, bool& hasStar) {\n    hasStar = !hasStar;\n    initializeTree(tree, height, hasStar);\n    cout << \"Estrella \" << (hasStar ? \"añadida.\" : \"eliminada.\") << endl;\n}\n\nvoid addOrRemove(Tree& tree, int height, char symbol, int count, bool add) {\n    srand(time(0));\n    int modifications = 0;\n\n    for (int i = 1; i <= height; i++) {\n        for (int j = 0; j < tree[i].size(); j++) {\n            if (tree[i][j] == (add ? '*' : symbol)) {\n                if (add && rand() % 2 == 0 && (j == 0 || tree[i][j - 1] != symbol)) {\n                    tree[i][j] = symbol;\n                    modifications++;\n                } else if (!add && tree[i][j] == symbol) {\n                    tree[i][j] = '*';\n                    modifications++;\n                }\n                if (modifications == count) break;\n            }\n        }\n        if (modifications == count) break;\n    }\n\n    cout << (add ? \"Añadido\" : \"Eliminado\") << \" \" << modifications << \" de \" << symbol << \".\\n\";\n}\n\nvoid toggleLights(Tree& tree, int height, bool& lightsOn) {\n    lightsOn = !lightsOn;\n\n    for (int i = 1; i <= height; i++) {\n        for (int j = 0; j < tree[i].size(); j++) {\n            if (tree[i][j] == (lightsOn ? '*' : '+')) {\n                tree[i][j] = lightsOn ? '+' : '*';\n            }\n        }\n    }\n\n    cout << \"Luces \" << (lightsOn ? \"encendidas.\" : \"apagadas.\") << endl;\n}\n\nint main() {\n    int height;\n    cout << \"Ingresa la altura del árbol: \";\n    cin >> height;\n\n    Tree tree;\n    bool hasStar = true;\n    bool lightsOn = false;\n\n    initializeTree(tree, height, hasStar);\n\n    string option;\n    while (true) {\n        drawTree(tree);\n        cout << \"Opciones: [estrella, bolas, luces, apagar, salir]: \";\n        cin >> option;\n\n        if (option == \"estrella\") {\n            toggleStar(tree, height, hasStar);\n        } else if (option == \"bolas\") {\n            addOrRemove(tree, height, 'o', 2, true);\n        } else if (option == \"luces\") {\n            addOrRemove(tree, height, '+', 3, true);\n        } else if (option == \"apagar\") {\n            toggleLights(tree, height, lightsOn);\n        } else if (option == \"salir\") {\n            cout << \"Gracias por decorar el árbol!\\n\";\n            break;\n        } else {\n            cout << \"Opción no válida.\\n\";\n        }\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/ejercicio.md",
    "content": "# #48 ÁRBOL DE NAVIDAD\n> #### Dificultad: Media | Publicación: 02/12/24 | Corrección: 09/12/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * ¡Ha comenzado diciembre! Es hora de montar nuestro\n * árbol de Navidad...\n * \n * Desarrolla un programa que cree un árbol de Navidad\n * con una altura dinámica definida por el usuario por terminal.\n * \n * Ejemplo de árbol de altura 5 (el tronco siempre será igual):\n * \n *     *\n *    ***\n *   *****\n *  *******\n * *********\n *    |||\n *    |||\n *\n * El usuario podrá seleccionar las siguientes acciones:\n * \n * - Añadir o eliminar la estrella en la copa del árbol (@)\n * - Añadir o eliminar bolas de dos en dos (o) aleatoriamente\n * - Añadir o eliminar luces de tres en tres (+) aleatoriamente\n * - Apagar (*) o encender (+) las luces (conservando su posición)\n * - Una luz y una bola no pueden estar en el mismo sitio\n *\n * Sólo puedes añadir una estrella, y tantas luces o bolas\n * como tengan cabida en el árbol. El programa debe notificar\n * cada una de las acciones (o por el contrario, cuando no\n * se pueda realizar alguna).\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/go/hozlucas28.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"os/exec\"\n\t\"slices\"\n\t\"strings\"\n)\n\n/* -------------------------------------------------------------------------- */\n/*                                   CLASSES                                  */\n/* -------------------------------------------------------------------------- */\n\ntype ChristmasTree interface {\n\tGetHeight() uint8\n\tGetTree() string\n\n\tAddBalls(ball rune) ChristmasTree\n\tAddLights(light rune) ChristmasTree\n\tAddStar(star rune) ChristmasTree\n\tRemoveBalls(ball rune) ChristmasTree\n\tRemoveLights(light rune) ChristmasTree\n\tRemoveStar(star rune) ChristmasTree\n\tTurnOffLights(lightOff rune) ChristmasTree\n\tTurnOnLights(lightOn rune) ChristmasTree\n}\n\ntype christmasTree struct {\n\theight        uint8\n\ttree          []string\n\tlightsIndexes [][2]uint8\n\t_             struct{}\n}\n\nfunc NewChristmasTree(height uint8) ChristmasTree {\n\tvar tree []string = []string{}\n\n\tfor i := 0; i < int(height); i++ {\n\t\tvar branchBlankSpaces string = \" \"\n\t\tif height >= 2 {\n\t\t\tbranchBlankSpaces = strings.Repeat(\" \", int(height)-i-1)\n\t\t}\n\n\t\ttree = append(tree, branchBlankSpaces+strings.Repeat(\"*\", i*2+1))\n\n\t}\n\n\tvar trunkBlankSpaces string\n\tif height >= 2 {\n\t\ttrunkBlankSpaces = strings.Repeat(\" \", int(height)-2)\n\t}\n\n\ttree = append(tree, trunkBlankSpaces+\"|||\")\n\ttree = append(tree, trunkBlankSpaces+\"|||\")\n\n\tvar christmasTree christmasTree = christmasTree{height: height, tree: tree, lightsIndexes: [][2]uint8{}}\n\n\treturn &christmasTree\n}\n\nfunc (christmasTree *christmasTree) GetHeight() uint8 {\n\treturn christmasTree.height\n}\n\nfunc (christmasTree *christmasTree) GetTree() string {\n\treturn strings.Join(christmasTree.tree, \"\\n\")\n\n}\n\nfunc (christmasTree *christmasTree) AddBalls(ball rune) ChristmasTree {\n\tfor i := 1; i < len(christmasTree.tree)-2; i++ {\n\t\tvar branch string = christmasTree.tree[i]\n\t\tvar counter int = 0\n\n\t\tvar newBranch string\n\n\t\tfor _, char := range branch {\n\t\t\tif counter%2 == 0 && char == '*' {\n\t\t\t\tnewBranch += string(ball)\n\t\t\t} else {\n\t\t\t\tnewBranch += string(char)\n\t\t\t}\n\n\t\t\tcounter++\n\t\t}\n\n\t\tchristmasTree.tree[i] = newBranch\n\t}\n\n\treturn christmasTree\n}\n\nfunc (christmasTree *christmasTree) AddLights(light rune) ChristmasTree {\n\tfor i := 1; i < len(christmasTree.tree)-2; i++ {\n\t\tvar branch string = christmasTree.tree[i]\n\t\tvar counter int = 0\n\n\t\tvar newBranch string\n\n\t\tfor j := 0; j < len(branch); j++ {\n\t\t\tvar char byte = branch[j]\n\n\t\t\tif counter%2 != 0 && char == '*' {\n\t\t\t\tvar lightIndex [2]uint8 = [2]uint8{uint8(i), uint8(j)}\n\n\t\t\t\tnewBranch += string(light)\n\t\t\t\tchristmasTree.lightsIndexes = append(christmasTree.lightsIndexes, lightIndex)\n\t\t\t} else {\n\t\t\t\tnewBranch += string(char)\n\t\t\t}\n\n\t\t\tcounter++\n\t\t}\n\n\t\tchristmasTree.tree[i] = newBranch\n\t}\n\n\treturn christmasTree\n}\n\nfunc (christmasTree *christmasTree) AddStar(star rune) ChristmasTree {\n\tchristmasTree.tree[0] = strings.Replace(christmasTree.tree[0], \"*\", string(star), 1)\n\treturn christmasTree\n}\n\nfunc (christmasTree *christmasTree) RemoveBalls(ball rune) ChristmasTree {\n\tfor i := 1; i < len(christmasTree.tree)-2; i++ {\n\t\tchristmasTree.tree[i] = strings.ReplaceAll(christmasTree.tree[i], string(ball), \"*\")\n\n\t}\n\n\treturn christmasTree\n}\n\nfunc (christmasTree *christmasTree) RemoveLights(light rune) ChristmasTree {\n\n\tfor len(christmasTree.lightsIndexes) != 0 {\n\t\tvar lightIndex [2]uint8 = christmasTree.lightsIndexes[0]\n\t\tvar branch uint8 = lightIndex[0]\n\t\tvar index uint8 = lightIndex[1]\n\n\t\tvar newBranch string\n\n\t\tfor j := 0; j < len(christmasTree.tree[branch]); j++ {\n\t\t\tif j == int(index) {\n\t\t\t\tnewBranch += \"*\"\n\t\t\t\tchristmasTree.lightsIndexes = slices.Delete(christmasTree.lightsIndexes, 0, 1)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tnewBranch += string(christmasTree.tree[branch][j])\n\t\t}\n\n\t\tchristmasTree.tree[branch] = newBranch\n\t}\n\n\treturn christmasTree\n}\n\nfunc (christmasTree *christmasTree) RemoveStar(star rune) ChristmasTree {\n\tchristmasTree.tree[0] = strings.Replace(christmasTree.tree[0], string(star), \"*\", 1)\n\treturn christmasTree\n}\n\nfunc (christmasTree *christmasTree) TurnOffLights(lightOff rune) ChristmasTree {\n\tfor i := 0; i < len(christmasTree.lightsIndexes); i++ {\n\t\tvar lightIndex [2]uint8 = christmasTree.lightsIndexes[i]\n\t\tvar branch uint8 = lightIndex[0]\n\t\tvar index uint8 = lightIndex[1]\n\n\t\tvar newBranch string\n\n\t\tfor j := 0; j < len(christmasTree.tree[branch]); j++ {\n\t\t\tif j == int(index) {\n\t\t\t\tnewBranch += string(lightOff)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tnewBranch += string(christmasTree.tree[branch][j])\n\t\t}\n\n\t\tchristmasTree.tree[branch] = newBranch\n\t}\n\n\treturn christmasTree\n}\n\nfunc (christmasTree *christmasTree) TurnOnLights(lightOn rune) ChristmasTree {\n\tfor i := 0; i < len(christmasTree.lightsIndexes); i++ {\n\t\tvar lightIndex [2]uint8 = christmasTree.lightsIndexes[i]\n\t\tvar branch uint8 = lightIndex[0]\n\t\tvar index uint8 = lightIndex[1]\n\n\t\tvar newBranch string = \"\"\n\n\t\tfor j := 0; j < len(christmasTree.tree[branch]); j++ {\n\t\t\tif j == int(index) {\n\t\t\t\tnewBranch += string(lightOn)\n\t\t\t\tcontinue\n\n\t\t\t}\n\n\t\t\tnewBranch += string(christmasTree.tree[branch][j])\n\t\t}\n\n\t\tchristmasTree.tree[branch] = newBranch\n\t}\n\n\treturn christmasTree\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\nfunc main() {\n\tvar christmasTree ChristmasTree\n\n\tvar input uint8\n\tvar cmd *exec.Cmd\n\n\tfmt.Printf(\"> Enter the height of the christmas tree: \")\n\tfmt.Scanf(\"%d\\n\", &input)\n\n\tchristmasTree = NewChristmasTree(input)\n\n\tcmd = exec.Command(\"clear\")\n\tcmd.Stdout = os.Stdout\n\tcmd.Run()\n\n\tfmt.Println(christmasTree.GetTree())\n\n\tfmt.Println(\n\t\t\"\\n> Available operations...\\n\\n\",\n\t\t\" 1 - Add star.\\n\",\n\t\t\" 2 - Remove star.\\n\",\n\t\t\" 3 - Add balls.\\n\",\n\t\t\" 4 - Remove balls.\\n\",\n\t\t\" 5 - Add lights.\\n\",\n\t\t\" 6 - Remove lights.\\n\",\n\t\t\" 7 - Turn on lights.\\n\",\n\t\t\" 8 - Turn off lights.\\n\",\n\t\t\" 0 - Exit.\",\n\t)\n\n\tfmt.Printf(\"\\n> Enter an operation: \")\n\tfmt.Scanf(\"%d\\n\", &input)\n\n\tfor input != 0 {\n\t\tswitch input {\n\t\tcase 1:\n\t\t\tchristmasTree.AddStar('@')\n\n\t\t\tcmd = exec.Command(\"clear\")\n\t\t\tcmd.Stdout = os.Stdout\n\t\t\tcmd.Run()\n\n\t\t\tfmt.Println(christmasTree.GetTree())\n\n\t\tcase 2:\n\t\t\tchristmasTree.RemoveStar('@')\n\n\t\t\tcmd = exec.Command(\"clear\")\n\t\t\tcmd.Stdout = os.Stdout\n\t\t\tcmd.Run()\n\n\t\t\tfmt.Println(christmasTree.GetTree())\n\n\t\tcase 3:\n\t\t\tchristmasTree.AddBalls('o')\n\n\t\t\tcmd = exec.Command(\"clear\")\n\t\t\tcmd.Stdout = os.Stdout\n\t\t\tcmd.Run()\n\n\t\t\tfmt.Println(christmasTree.GetTree())\n\n\t\tcase 4:\n\t\t\tchristmasTree.RemoveBalls('o')\n\n\t\t\tcmd = exec.Command(\"clear\")\n\t\t\tcmd.Stdout = os.Stdout\n\t\t\tcmd.Run()\n\n\t\t\tfmt.Println(christmasTree.GetTree())\n\n\t\tcase 5:\n\t\t\tchristmasTree.AddLights('+')\n\n\t\t\tcmd = exec.Command(\"clear\")\n\t\t\tcmd.Stdout = os.Stdout\n\t\t\tcmd.Run()\n\n\t\t\tfmt.Println(christmasTree.GetTree())\n\n\t\tcase 6:\n\t\t\tchristmasTree.RemoveLights('*')\n\n\t\t\tcmd = exec.Command(\"clear\")\n\t\t\tcmd.Stdout = os.Stdout\n\t\t\tcmd.Run()\n\n\t\t\tfmt.Println(christmasTree.GetTree())\n\n\t\tcase 7:\n\t\t\tchristmasTree.TurnOnLights('+')\n\n\t\t\tcmd = exec.Command(\"clear\")\n\t\t\tcmd.Stdout = os.Stdout\n\t\t\tcmd.Run()\n\n\t\t\tfmt.Println(christmasTree.GetTree())\n\n\t\tcase 8:\n\t\t\tchristmasTree.TurnOffLights('*')\n\n\t\t\tcmd = exec.Command(\"clear\")\n\t\t\tcmd.Stdout = os.Stdout\n\t\t\tcmd.Run()\n\n\t\t\tfmt.Println(christmasTree.GetTree())\n\n\t\tdefault:\n\t\t\tfmt.Println(\"\\n> Invalid operation! Try again...\")\n\t\t}\n\n\t\tfmt.Println(\n\t\t\t\"\\n> Available operations...\\n\\n\",\n\t\t\t\" 1 - Add star.\\n\",\n\t\t\t\" 2 - Remove star.\\n\",\n\t\t\t\" 3 - Add balls.\\n\",\n\t\t\t\" 4 - Remove balls.\\n\",\n\t\t\t\" 5 - Add lights.\\n\",\n\t\t\t\" 6 - Remove lights.\\n\",\n\t\t\t\" 7 - Turn on lights.\\n\",\n\t\t\t\" 8 - Turn off lights.\\n\",\n\t\t\t\" 0 - Exit.\",\n\t\t)\n\n\t\tfmt.Printf(\"\\n> Enter an operation: \")\n\t\tfmt.Scanf(\"%d\\n\", &input)\n\t}\n}\n"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/java/JesusWay69.java",
    "content": "package reto_49;\n\nimport java.util.ArrayList;\nimport java.util.Scanner;\n\npublic class JesusWay69 {\n\n    public static ArrayList<Integer> coordinates = new ArrayList<>();\n\n    public static void main(String[] args) {\n\n        char[][] myTree = null;\n\n        do {\n            Scanner sc = new Scanner(System.in);\n            System.out.println(\"\"\"\n              1- Crear nuevo árbol\n              2- Añadir estrella \n              3- Eliminar estrella \n              4- Añadir 2 bolas aleatoriamente\n              5- Quitar todas las bolas\n              6- Añadir 3 luces aleatoriamente \n              7- Encender las luces\n              8- Apagar las luces\n                             \"\"\");\n            System.out.print(\"Elija una opción (enter para salir): \");\n            String option = sc.nextLine();\n            if (option.equals(\"\"))  break;\n\n            switch (option) {\n                case \"1\" -> {\n                    System.out.print(\"Introduzca la altura del árbol (mayor de 3): \");\n                    int hight = sc.nextInt();\n                    myTree = createTree(hight);\n                    showTree(myTree);\n                }\n                case \"2\" -> showTree(topStar(myTree, true));               \n                case \"3\" -> showTree(topStar(myTree, false));               \n                case \"4\" -> showTree(addBalls(myTree));              \n                case \"5\" -> showTree(removeBalls(myTree));               \n                case \"6\" -> showTree(addLights(myTree));           \n                case \"7\" -> showTree(turnOnLights(myTree, coordinates));              \n                case \"8\" ->showTree(turnOffLigths(myTree));\n                default -> System.out.println(\"El dato tiene que ser numérico del 1 al 8\\n\");               \n            }\n        } while (true);\n    }\n\n    public static ArrayList<Integer> storageCoordinates(int x, int y) {\n        coordinates.add(x);\n        coordinates.add(y);\n        return coordinates;\n    }\n\n    public static char[][] createTree(int files) {\n        int columns = files * 2 - 1;\n        int branch = 1;\n        char[][] tree = new char[files + 2][columns];\n\n        if (files <= 3) {\n            System.out.println(\"No se puede crear un árbol de menos de 4 alturas\");\n            tree = null;\n            return tree;\n        }\n        for (int i = 0; i < files; i++) {\n            for (int j = 0; j < columns / 2; j++) tree[i][j] = ' '; \n            for (int k = columns / 2; k < columns / 2 + branch; k++) tree[i][k] = '*';\n            for (int l = columns / 2 + branch; l < files * 2 - 1; l++) tree[i][l] = ' ';\n            columns -= 2;\n            branch += 2;\n        }\n        for (int m = 0; m < 2; m++) {\n            for (int n = 0; n < files - 2; n++) tree[files + m][n] = ' ';\n            for (int p = files - 2; p < files + 1; p++) tree[files + m][p] = '|';\n            for (int q = files + 1; q < files * 2 - 1; q++) tree[files + m][q] = ' ';   \n        }\n        return tree;\n    }\n    public static void showTree(char[][] tree) {\n        if (tree != null) {\n            int i = 0;\n            for (char[] branch : tree) {\n                i++;\n                for (char c : branch) System.out.print(c);\n                System.out.println();\n            }\n        }\n    }\n\n    public static char[][] topStar(char[][] tree, boolean switchStar) {\n        if (tree == null) {\n            System.out.println(\"ERROR: Hay que crear un árbol antes de poder modificarlo (opción 1)\");\n            return null;\n        } else if (switchStar) {\n            tree[0][tree[0].length / 2] = '@';\n            System.out.println(\"\\n--- ESTRELLA AÑADIDA ---\");\n        } else {\n            tree[0][tree[0].length / 2] = '*';\n            System.out.println(\"\\n--- ESTRELLA ELIMINADA ---\");\n        }\n        return tree;\n    }\n\n    public static char[][] addBalls(char[][] tree) {\n        if (tree == null) {\n            System.out.println(\"ERROR: Hay que crear un árbol antes de poder modificarlo (opción 1)\");\n            return null;\n        }\n        for (int i = 0; i < 2; i++) {\n            int randomFile = (int) (Math.random() * tree.length - 2 + 1);\n            int randomColumn = (int) (Math.random() * tree[0].length);\n            if (tree[randomFile][randomColumn] == '*') tree[randomFile][randomColumn] = 'O';      \n            else i--;   \n        }\n        System.out.println(\"\\n--- SE AÑADEN 2 BOLAS DE ADORNO ---\");\n        return tree;\n    }\n\n    public static char[][] removeBalls(char[][] tree) {\n        if (tree == null) {\n            System.out.println(\"ERROR: Hay que crear un árbol antes de poder modificarlo (opción 1)\");\n            return null;\n        }\n        for (int i = 1; i < tree.length - 2; i++) {\n            for (int j = 0; j < tree[i].length; j++) {\n                if (tree[i][j] == 'O') tree[i][j] = '*';      \n            }\n        }\n        System.out.println(\"\\n--- BOLAS DE ADORNO ELIMINADAS ---\");\n        return tree;\n    }\n\n    public static char[][] addLights(char[][] tree) {\n        if (tree == null) {\n            System.out.println(\"ERROR: Hay que crear un árbol antes de poder modificarlo (opción 1)\");\n            return null;\n        }\n        for (int i = 0; i < 3; i++) {\n            int randomFile = (int) (Math.random() * tree.length - 2) + 1;\n            int randomColumn = (int) (Math.random() * tree[0].length);\n            if (tree[randomFile][randomColumn] == '*') {\n                tree[randomFile][randomColumn] = 'X';\n                storageCoordinates(randomFile, randomColumn);\n            } else i--;   \n        }\n        System.out.println(\"\\n--- AÑADIDAS 3 LUCES ENCENDIDAS AL ÁRBOL ---\");\n        return tree;\n    }\n\n    public static char[][] turnOnLights(char[][] tree, ArrayList<Integer> coordinates) {\n        if (tree == null) {\n            System.out.println(\"ERROR: Hay que crear un árbol antes de poder modificarlo (opción 1)\");\n            return null;\n        }\n        int x = 0;\n        for (int j = 0; j < coordinates.size(); j++) {\n            if (j % 2 == 0) {\n                x = coordinates.get(j);\n            } else {\n                int y = coordinates.get(j);\n                tree[x][y] = 'X';\n            }\n        }\n        System.out.println(\"\\n--- TODAS LAS LUCES ENCENDIDAS ---\");\n        return tree;\n    }\n\n    public static char[][] turnOffLigths(char[][] tree) {\n        if (tree == null) {\n            System.out.println(\"ERROR: Hay que crear un árbol antes de poder modificarlo (opción 1)\");\n            return null;\n        }\n        for (int i = 1; i < tree.length - 2; i++) {\n            for (int j = 0; j < tree[i].length; j++) {\n                if (tree[i][j] == 'X') tree[i][j] = '*';   \n            }\n        }\n        System.out.println(\"\\n--- TODAS LAS LUCES APAGADAS ---\");\n        return tree;\n    }\n}\n"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/java/JohnAlexGuerrero.java",
    "content": "/*\n * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license\n */\n\npackage com.mycompany.christmastree;\n\nimport java.util.Scanner;\n\n/**\n *\n * @author JOHN\n */\npublic class ChristmasTree {\n    static class Tree{\n        private String treeDraw;\n        private int column;\n        private int row;\n        private boolean star;\n        private boolean onLight;\n        private int balls;\n        private int lights;\n\n        public Tree(int heigth, boolean star) {\n            this.setColumn(heigth);\n            this.setRow(heigth);\n            this.star = star;\n            this.balls = 0;\n            this.lights = 0;\n            this.treeDraw = \"\";\n        }\n        \n        public void setRow(int h){\n            this.row = h;\n        }\n        \n        public void setColumn(int h){\n            for(int i=0; i<h; i++){\n                this.column = (2*i)+1;\n            }\n        }\n\n        public int getBalls() {\n            return balls;\n        }\n\n        public void setBalls(int balls) {\n            this.balls = balls;\n        }\n\n        public String getTreeDraw() {\n            return treeDraw;\n        }\n\n        public int getLights() {\n            return lights;\n        }\n\n        public void setLights(int lights) {\n            this.lights = lights;\n        }\n\n        public boolean isOnLight() {\n            return onLight;\n        }\n\n        public void setOnLight(boolean onLight) {\n            this.onLight = onLight;\n        }\n        \n        public String draw(){\n            String tree = \"\";\n            int amountBall = this.getBalls();\n            int amountLight = this.getLights();\n            \n            for(int x=0; x<this.row; x++){\n                tree += \"\\n\";\n                int asterisksNumber = (2*x)+1;\n                int spacesNumber = this.column - asterisksNumber;\n                \n                for(int j=0; j<spacesNumber; j++){\n                    tree += \" \";\n                    if(j == ((spacesNumber/2)-1)){\n                        for(int i=0; i<asterisksNumber; i++){\n                            if(this.star && x < 1){\n                                tree += \"@\";\n                                continue;\n                            }else if(amountBall > 0 && (i+1)%2 == 0 ){\n                                tree += \"o\";\n                                amountBall -= 1;\n                            }else if(amountLight > 0 && (i+1)%3 == 0 && this.isOnLight()){\n                                tree += \"+\";\n                                amountLight -= 1;\n                            }else{\n                                tree += \"*\";\n                            }\n                        }\n                    }\n                }\n            }\n            \n            //base\n            for(int k=0; k<this.column; k++){\n                tree += \"*\";\n            }\n            \n            //tronco\n            tree += \"\\n\";\n            int base2 = 0;\n            int base = this.column - 3;\n            \n            while(base2 < 2){\n                base2 += 1;\n                for(int p=0; p<base; p++){\n                    tree += \" \";\n                    if(p == ((base/2)-1)){\n                        tree += \"|||\";\n                    }\n                }\n                tree += \"\\n\";\n            }\n            \n            return tree;\n        }\n    }\n\n    public static void main(String[] args) {\n        System.out.println(\"Christmas Tree!\");\n        Scanner scanner = new Scanner(System.in);\n        /*El usuario podrá seleccionar las siguientes acciones:\n            * - Una luz y una bola no pueden estar en el mismo sitio\n        */\n        //  * - Altura del arbol\n        System.out.println(\"Ingresa la altura del arbol: \");\n        String heigth = scanner.nextLine();\n        boolean star = false;\n        \n        //  * - Añadir o eliminar la estrella en la copa del árbol (@)\n        System.out.println(\"Colocar estrella en la copa del arbol (@) (si/no):\");\n        String q = scanner.nextLine();\n        switch(q.toLowerCase()){\n            case \"si\":\n                star = true;\n                break;\n            case \"no\":\n                star = false;\n                break;\n            default:\n                System.out.println(\"Respuesta no permirida\");\n        }\n        \n        Tree t = new Tree(Integer.parseInt(heigth), star);\n        \n        //  * - Añadir o eliminar bolas de dos en dos (o) aleatoriamente\n        int countBall = 0;\n        boolean flap = true;\n        \n        do{\n            System.out.println(\"Añadir (+2/-2) bolas (0) o exit para AÑADIR: \");\n            String addOrDelete = scanner.nextLine();\n            \n            switch(addOrDelete){\n                case \"+2\":\n                    countBall += 2;\n                    System.out.println(\"añadir: \"+ countBall+\"bolas\");\n                    break;\n                case \"-2\":\n                    if(countBall == 0) break;\n                    countBall -= 2;\n                    System.out.println(\"Eliminar: \"+ countBall+\"bolas\");\n                    break;\n                case \"exit\":\n                    flap = false;\n                    break;\n                default:\n                    System.out.println(\"operacion no permitida.\");\n            }\n            \n        }while(flap);\n        \n        t.setBalls(countBall);\n        \n        // * - Añadir o eliminar luces de tres en tres (+) aleatoriamente\n        int countLight = 0;\n        flap = true;\n        \n        do{\n            System.out.println(\"Añadir (+3/-3) luces (+) o exit para AÑADIR: \");\n            String addOrDeleteLight = scanner.nextLine();\n            \n            switch(addOrDeleteLight){\n                case \"+3\":\n                    countLight += 3;\n                    System.out.println(\"añadir: \"+ countLight+ \" luces\");\n                    break;\n                case \"-3\":\n                    if(countLight == 0) break;\n                    countLight -= 3;\n                    System.out.println(\"Eliminar: \"+ countLight+\" luces\");\n                    break;\n                case \"exit\":\n                    flap = false;\n                    break;\n                default:\n                    System.out.println(\"operacion no permitida.\");\n            }\n            \n        }while(flap);\n        \n        t.setLights(countLight);\n        \n        //  * - Apagar (*) o encender (+) las luces (conservando su posición)\n        flap = true;\n        \n        do{\n            System.out.println(\"Encender o Apagar luces (on/off): \");\n            String onOff = scanner.nextLine();\n            switch(onOff){\n                case \"on\":\n                    t.setOnLight(true);\n                    break;\n                case \"off\":\n                    t.setOnLight(false);\n                    break;\n                default:\n                    System.out.println(\"operacion no permitida.\");\n            }\n\n            System.out.println(\"=======================================\");\n            String status = (t.isOnLight())?\"Encendidas\":\"Apagadas\";\n            System.out.println(countBall+ \" bolas, \"+countLight+\" luces, luces: \"+status);\n            System.out.println(t.draw());\n            System.out.println(\"=======================================\");\n            \n        }while(flap);\n        \n    }\n}\n"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/java/Josegs95.java",
    "content": "import java.util.*;\n\npublic class Josegs95 {\n    public static void main(String[] args) {\n        new Josegs95().createChristmasTree();\n    }\n\n    private char[][] tree;\n    private char[][] trunk;\n    private int treeHeight;\n    private int treeWidth;\n\n    private Random rnd = new Random();\n    final private Scanner sc = new Scanner(System.in);\n    private List<TreeDecoration> decorationList = new ArrayList<>();\n    private boolean isLightON = true;\n\n    public void createChristmasTree(){\n        try(sc){\n            System.out.print(\"Selecciona la altura del árbol de navidad (+2): \");\n            treeHeight = Integer.parseInt(sc.nextLine());\n            treeWidth = treeHeight * 2 - 1;\n\n            tree = new char[treeHeight][treeWidth];\n            trunk = new char[2][treeWidth];\n\n            createBasicTree();\n            createTrunk();\n\n            app:\n            while(true){\n                printChristmasTree();\n                printMenu();\n                System.out.print(\"Selecciona una opción: \");\n                String option = sc.nextLine();\n                switch (option){\n                    case \"1\" -> addTreeTopper(true);\n                    case \"2\" -> addTreeTopper(false);\n                    case \"3\" -> addDecoration(TreeDecoration.Type.BALL, 2);\n                    case \"4\" -> deleteDecoration(TreeDecoration.Type.BALL, 2);\n                    case \"5\" -> addDecoration(TreeDecoration.Type.LIGHT, 3);\n                    case \"6\" -> deleteDecoration(TreeDecoration.Type.LIGHT, 3);\n                    case \"7\" -> turnLightON(!isLightON);\n                    case \"8\" -> {\n                        System.out.println(\"Saliendo de la aplicación...\");\n                        break app;\n                    }\n                    default -> System.out.println(\"Error, opción no válida.\");\n                }\n                System.out.println();\n            }\n        }\n    }\n\n    private void printMenu(){\n        System.out.println(\"========= Menu =========\");\n        System.out.println(\"1. Añadir la estrella en la copa del árbol\");\n        System.out.println(\"2. Eliminar la estrella en la copa del árbol\");\n        System.out.println(\"3. Añadir bolas de Navidad (cantidad: 2)\");\n        System.out.println(\"4. Eliminar bolas de Navidad (cantidad: 2)\");\n        System.out.println(\"5. Añadir luces de Navidad (cantidad: 3)\");\n        System.out.println(\"6. Eliminar luces de Navidad (cantidad: 3)\");\n        System.out.println(\"7. Encender/apagar luces de Navidad\");\n        System.out.println(\"8. Salir de la aplicación\");\n        System.out.println(\"========================\");\n    }\n\n    private void addTreeTopper(boolean addOperation){\n        tree[0][treeWidth / 2] = addOperation ? '@' : '*';\n    }\n\n    private void addDecoration(TreeDecoration.Type type, int amount){\n        if (decorationList.size() + amount > Math.pow(treeHeight, 2) - 1){\n            System.out.println(\"No caben esa cantidad de objetos en el árbol\");\n            return;\n        }\n\n        loop:\n        for (int i = 0; i < amount; i++){\n            int a = rnd.nextInt(1, treeHeight);\n            int b = rnd.nextInt(treeWidth / 2 - a, treeWidth / 2 + a + 1);\n\n            TreeDecoration decoration = new TreeDecoration(type, b, a);\n\n            for (TreeDecoration aux : decorationList){\n                if (decoration.isInSamePlace(aux)){\n                    i--;\n                    continue loop;\n                }\n            }\n\n            decorationList.add(decoration);\n        }\n    }\n\n    private void deleteDecoration(TreeDecoration.Type type, int amount){\n        List<TreeDecoration> auxList = new ArrayList<>(decorationList.stream()\n                .filter(x -> x.getType() == type)\n                .toList());\n        if (auxList.size() < amount){\n            System.out.println(\"El árbol de Navidad no tiene suficientes objetos que quitar\");\n            return;\n        }\n\n        Collections.shuffle(auxList);\n        for (int i = 0; i < amount; i++)\n            decorationList.remove(auxList.get(i));\n    }\n\n    private void turnLightON(boolean turnLights){\n        isLightON = turnLights;\n    }\n\n    private char[][] decorateChristmasTree(char[][] tree){\n        for (TreeDecoration decoration :  decorationList) {\n            tree[decoration.getYCoord()][decoration.getXCoord()] = decoration.getIcon(isLightON);\n        }\n\n        return tree;\n    }\n\n    private void createBasicTree(){\n        Arrays.stream(tree).forEach(x -> Arrays.fill(x, ' '));\n\n        for (int i = 0; i < treeHeight; i++){\n            int aux = 1 + 2 * i;\n            for (int j = 0; j < aux; j++){\n                tree[i][treeWidth / 2 - i + j] = '*';\n            }\n        }\n    }\n\n    private void createTrunk(){\n        Arrays.stream(trunk).forEach(x -> Arrays.fill(x, ' '));\n\n        for (int i = 0; i < 2; i++){\n            for (int j = 0; j < 3; j++){\n                trunk[i][treeWidth / 2 - 1 + j] = '|';\n            }\n        }\n    }\n\n    private void printChristmasTree(){\n        char[][] cloneTree = Arrays.stream(tree).map(char[]::clone).toArray(char[][]::new);\n        printGrid(decorateChristmasTree(cloneTree));\n        printGrid(trunk);\n        System.out.println();\n    }\n\n    private void printGrid(char[][] grid){\n        for (int i = 0; i < grid.length; i++){\n            for (int j = 0; j < grid[0].length; j++){\n                System.out.print(grid[i][j]);\n            }\n            System.out.println();\n        }\n    }\n\n    public class TreeDecoration{\n        enum Type {\n            BALL,\n            LIGHT\n        }\n\n        private Type type;\n        private int xCoord;\n        private int yCoord;\n\n        public TreeDecoration(Type type, int x, int y) {\n            this.type = type;\n            this.xCoord = x;\n            this.yCoord = y;\n        }\n\n        public boolean isInSamePlace(TreeDecoration other) {\n            return xCoord == other.getXCoord() && yCoord == other.getYCoord();\n        }\n\n        public char getIcon(boolean isLightON){\n            switch (type){\n                case BALL -> {\n                    return 'o';\n                }\n                case LIGHT -> {\n                    return isLightON ? '+' : '*';\n                }\n                default -> {\n                    return ' ';\n                }\n            }\n        }\n\n        public Type getType() {\n            return type;\n        }\n\n        public int getXCoord() {\n            return xCoord;\n        }\n\n        public int getYCoord() {\n            return yCoord;\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/java/MohamedElderkaoui.java",
    "content": "import java.util.ArrayList;\nimport java.util.List;\nimport java.util.Random;\nimport java.util.Scanner;\npublic class MohamedElderkaoui {\n    private int altura;\n    private boolean tieneEstrella;\n    private boolean lucesEncendidas;\n    private List<String[]> arbol;\n\n    public ArbolNavidad(int altura) {\n        this.altura = altura;\n        this.tieneEstrella = false;\n        this.lucesEncendidas = false;\n        this.arbol = new ArrayList<>();\n        generarArbolBase();\n    }\n\n    private void generarArbolBase() {\n        arbol.clear();\n        for (int i = 0; i < altura; i++) {\n            int ancho = 1 + 2 * i;\n            char[] fila = new char[altura + i];\n            for (int j = 0; j < fila.length; j++) {\n                fila[j] = (j >= altura - i - 1 && j < altura + i) ? '*' : ' ';\n            }\n            arbol.addAll(new String(fila).toCharArray());\n        }\n        // Agregar el tronco\n        for (int i = 0; i < 2; i++) {\n            char[] tronco = new char[2 * altura - 1];\n            for (int j = 0; j < tronco.length; j++) {\n                tronco[j] = (j >= altura - 2 && j <= altura) ? '|' : ' ';\n            }\n            arbol.add(tronco);\n        }\n    }\n\n    public void toggleEstrella() {\n        if (tieneEstrella) {\n            arbol.get(0)[altura - 1] = '*';\n            System.out.println(\"Se ha eliminado la estrella del árbol.\");\n        } else {\n            arbol.get(0)[altura - 1] = '@';\n            System.out.println(\"Se ha añadido la estrella al árbol.\");\n        }\n        tieneEstrella = !tieneEstrella;\n    }\n\n    public void añadirBolas(int cantidad) {\n        Random rand = new Random();\n        for (int i = 0; i < cantidad; i++) {\n            int fila;\n            int columna;\n            do {\n                fila = rand.nextInt(altura);\n                columna = rand.nextInt(altura + fila);\n            } while (arbol.get(fila)[columna] != '*');\n            arbol.get(fila)[columna] = 'o';\n        }\n        System.out.println(cantidad + \" bola(s) añadida(s).\");\n    }\n\n    public void eliminarBolas(int cantidad) {\n        int eliminadas = 0;\n        for (int i = 0; i < altura; i++) {\n            for (int j = 0; j < arbol.get(i).length; j++) {\n                if (arbol.get(i)[j] == 'o') {\n                    arbol.get(i)[j] = '*';\n                    eliminadas++;\n                    if (eliminadas == cantidad) break;\n                }\n            }\n        }\n        System.out.println(eliminadas + \" bola(s) eliminada(s).\");\n    }\n\n    public void añadirLuces(int cantidad) {\n        Random rand = new Random();\n        for (int i = 0; i < cantidad; i++) {\n            int fila;\n            int columna;\n            do {\n                fila = rand.nextInt(altura);\n                columna = rand.nextInt(altura + fila);\n            } while (arbol.get(fila)[columna] != '*');\n            arbol.get(fila)[columna] = '+';\n        }\n        System.out.println(cantidad + \" luz/luces añadida(s).\");\n    }\n\n    public void eliminarLuces(int cantidad) {\n        int eliminadas = 0;\n        for (int i = 0; i < altura; i++) {\n            for (int j = 0; j < arbol.get(i).length; j++) {\n                if (arbol.get(i)[j] == '+') {\n                    arbol.get(i)[j] = '*';\n                    eliminadas++;\n                    if (eliminadas == cantidad) break;\n                }\n            }\n        }\n        System.out.println(eliminadas + \" luz/luces eliminada(s).\");\n    }\n\n    public void encenderApagarLuces() {\n        for (int i = 0; i < altura; i++) {\n            for (int j = 0; j < arbol.get(i).length; j++) {\n                if (arbol.get(i)[j] == '+') {\n                    arbol.get(i)[j] = lucesEncendidas ? '*' : '+';\n                }\n            }\n        }\n        lucesEncendidas = !lucesEncendidas;\n        System.out.println(lucesEncendidas ? \"Luces encendidas.\" : \"Luces apagadas.\");\n    }\n\n    public void mostrarArbol() {\n        for (char[] fila : arbol) {\n            System.out.println(new String(fila));\n        }\n    }\n\n    public static void main(String[] args) {\n        Scanner sc = new Scanner(System.in);\n        System.out.print(\"Introduce la altura del árbol: \");\n        int altura = sc.nextInt();\n        ArbolNavidad arbol = new ArbolNavidad(altura);\n\n        int opcion;\n        do {\n            System.out.println(\"\\nOpciones:\");\n            System.out.println(\"1. Alternar estrella\");\n            System.out.println(\"2. Añadir bolas (2)\");\n            System.out.println(\"3. Eliminar bolas (2)\");\n            System.out.println(\"4. Añadir luces (3)\");\n            System.out.println(\"5. Eliminar luces (3)\");\n            System.out.println(\"6. Encender/Apagar luces\");\n            System.out.println(\"7. Mostrar árbol\");\n            System.out.println(\"0. Salir\");\n            System.out.print(\"Selecciona una opción: \");\n            opcion = sc.nextInt();\n\n            switch (opcion) {\n                case 1 -> arbol.toggleEstrella();\n                case 2 -> arbol.añadirBolas(2);\n                case 3 -> arbol.eliminarBolas(2);\n                case 4 -> arbol.añadirLuces(3);\n                case 5 -> arbol.eliminarLuces(3);\n                case 6 -> arbol.encenderApagarLuces();\n                case 7 -> arbol.mostrarArbol();\n                case 0 -> System.out.println(\"¡Feliz Navidad!\");\n                default -> System.out.println(\"Opción inválida.\");\n            }\n        } while (opcion != 0);\n\n        sc.close();\n    }    \n}\n"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/java/alb-martinez.java",
    "content": "import java.util.*;\n\npublic class alb-martinez {\n\n    static class ArbolNavidad {\n        private int altura;\n        private char[][] arbol;\n        private boolean estrellaCopa;\n        private List<int[]> bolas;\n        private List<int[]> luces;\n\n        public ArbolNavidad(int altura) {\n            this.altura = altura;\n            this.arbol = new char[altura + 2][2 * altura - 1];\n            this.bolas = new ArrayList<>();\n            this.luces = new ArrayList<>();\n            this.estrellaCopa = false;\n            contruirArbol();\n        }\n\n        private void contruirArbol() {\n            for (int i = 0; i < arbol.length; i++) {\n                for (int j = 0; j < arbol[i].length; j++) {\n                    arbol[i][j] = ' ';\n                }\n            }\n\n            for (int i = 0; i < altura; i++) {\n                for (int j = altura - i - 1; j <= altura + i - 1; j++) {\n                    arbol[i][j] = '*';\n                }\n            }\n\n            int troncoInicio = (arbol[altura].length - 3) / 2;\n            for (int i = altura; i < altura + 2; i++) {\n                for (int j = troncoInicio; j < troncoInicio + 3; j++) {\n                    arbol[i][j] = '|';\n                }\n            }\n        }\n\n        public void imprimirArbol() {\n\n            for (int i = 0; i < altura; i++) {\n                for (int j = 0; j < arbol[i].length; j++) {\n                    System.out.print(arbol[i][j]);;\n                }\n                System.out.println();\n            }\n\n            for (int i = altura; i < altura + 2; i++) {\n                for (int j = 0; j < arbol[i].length; j++) {\n                    System.out.print(arbol[i][j]);\n                }\n                System.out.println();\n            }\n\n        }\n\n        public void añadirEstrella() {\n            if (!estrellaCopa) {\n                arbol[0][altura - 1] = '@';\n                estrellaCopa = true;\n                System.out.println(\"Se ha añadido una estrella en la copa del arbol.\");\n            } else {\n                System.out.println(\"Ya existe una estrella en la copa\");\n            }\n        }\n\n        public void eliminarEstrella() {\n            if (estrellaCopa) {\n                arbol[0][altura - 1] = '*';\n                estrellaCopa = false;\n                System.out.println(\"Se ha eliminado la estrella de la copa del arbol.\");\n            } else {\n                System.out.println(\"No hay entrella en la copa del arbol.\");\n            }\n        }\n\n        public void añadirBola() {\n            Random random = new Random();\n            int x, y;\n            do {\n                x = random.nextInt(altura);\n                y = random.nextInt(2 * altura - 1);\n            } while (arbol[x][y] != '*' || contieneBolaOLuces(x, y));\n\n            arbol[x][y] = 'o';\n            bolas.add(new int[]{x, y});\n            System.out.println(\"Se ha añadido una bola en la posición (\" + x + \", \" + y + \").\");\n        }\n\n        public void eliminarBola() {\n            if (bolas.isEmpty()) {\n                System.out.println(\"No hay bolas para eliminar\");\n                return;\n            }\n\n            int [] bola = bolas.remove(bolas.size() - 1);\n            arbol[bola[0]][bola[1]] = '*';\n            System.out.println(\"Se ha eliminado una bola en la posición (\" + bola[0] + \", \" + bola[1] + \").\");\n        }\n\n        public void añadirLuz() {\n            Random random = new Random();\n            int x, y;\n            do {\n                x = random.nextInt(altura);\n                y = random.nextInt(2 * altura - 1);\n            } while (arbol[x][y] != '*' || contieneBolaOLuces(x, y));\n\n            arbol[x][y] = '+';\n            luces.add(new int[]{x, y});\n            System.out.println(\"Se ha añadido una luz en la posición (\" + x + \", \" + y + \").\");\n        }\n\n        public void eliminarLuz() {\n            if (luces.isEmpty()) {\n                System.out.println(\"No hay luces para eliminar.\");\n                return;\n            }\n\n            int[] luz = luces.remove(luces.size() - 1);\n            arbol[luz[0]][luz[1]] = '*';\n            System.out.println(\"Se ha eliminado una luz en la posición (\" + luz[0] + \", \" + luz[1] + \").\");\n        }\n\n        private boolean contieneBolaOLuces(int x, int y) {\n            for (int[] bola : bolas) {\n                if (bola[0] == x && bola[1] == y) return true;\n            }\n            for (int[] luz : luces) {\n                if (luz[0] == x && luz[1] == y) return true;\n            }\n            return false;\n        }\n    }\n\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n\n        int altura = 0;\n        boolean entradaValida = false;\n        while (!entradaValida) {\n            System.out.print(\"Introduce la altura del árbol: \");\n            if (scanner.hasNextInt()) {\n                altura = scanner.nextInt();\n                if (altura > 0) {\n                    entradaValida = true;\n                } else {\n                    System.out.println(\"Por favor, introduce un número positivo.\");\n                }\n            } else {\n                System.out.println(\"Entrada no válida. Debes introducir un número.\");\n                scanner.next();\n            }\n        }\n\n        ArbolNavidad arbol = new ArbolNavidad(altura);\n\n        boolean salir = false;\n        while (!salir) {\n            arbol.imprimirArbol();\n            System.out.println(\"\\n¿Qué acción deseas realizar?\");\n            System.out.println(\"1. Añadir estrella\");\n            System.out.println(\"2. Eliminar estrella\");\n            System.out.println(\"3. Añadir Bola\");\n            System.out.println(\"4. Eliminar Bola\");\n            System.out.println(\"5. Añadir luz\");\n            System.out.println(\"6. Eliminar luz\");\n            System.out.println(\"7. Salir\");\n\n            int opcion = 0;\n            boolean opcionValida = false;\n            while (!opcionValida) {\n                if (scanner.hasNextInt()) {\n                    opcion = scanner.nextInt();\n                    if (opcion >= 1 && opcion <= 7) {\n                        opcionValida = true;\n                    } else {\n                        System.out.println(\"Opción no válida. Introduce un número entre 1 y 7.\");\n                    }\n                } else {\n                    System.out.println(\"Entrada no válida. Debes introducir un número.\");\n                    scanner.next();\n                }\n            }\n\n            switch (opcion) {\n                case 1 -> arbol.añadirEstrella();\n                case 2 -> arbol.eliminarEstrella();\n                case 3 -> arbol.añadirBola();\n                case 4 -> arbol.eliminarBola();\n                case 5 -> arbol.añadirLuz();\n                case 6 -> arbol.eliminarLuz();\n                case 7 -> salir = true;\n                default -> System.out.println(\"Opción no válida.\");\n            }\n        }\n        scanner.close();\n    }\n}\n"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/java/asjordi.java",
    "content": "import java.util.Random;\nimport java.util.Scanner;\n\npublic class Main {\n\n    private static Random random = new Random();\n\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n        System.out.print(\"Introduce la altura del árbol: \");\n        int altura = scanner.nextInt();\n        scanner.nextLine();\n\n        boolean estrella = true;\n        boolean lucesEncendidas = true;\n        char[][] arbol = crearArbol(altura, estrella);\n\n        while (true) {\n            imprimirArbol(arbol, lucesEncendidas);\n            System.out.println(\"Selecciona una acción:\");\n            System.out.println(\"1. Añadir/eliminar estrella\");\n            System.out.println(\"2. Añadir/eliminar bolas\");\n            System.out.println(\"3. Añadir/eliminar luces\");\n            System.out.println(\"4. Apagar/encender luces\");\n            System.out.println(\"5. Salir\");\n\n            int opcion = scanner.nextInt();\n            scanner.nextLine();\n\n            switch (opcion) {\n                case 1 -> {\n                    estrella = !estrella;\n                    arbol = crearArbol(altura, estrella);\n                }\n                case 2 -> modificarBolas(arbol);\n                case 3 -> modificarLuces(arbol);\n                case 4 -> lucesEncendidas = !lucesEncendidas;\n                case 5 -> {\n                    return;\n                }\n                default -> System.out.println(\"Opción no válida\");\n            }\n        }\n    }\n\n    private static char[][] crearArbol(int altura, boolean estrella) {\n        char[][] arbol = new char[altura + 2][altura * 2 - 1];\n\n        for (int i = 0; i < altura; i++) {\n            for (int j = 0; j < altura * 2 - 1; j++) {\n                if (j >= altura - 1 - i && j <= altura - 1 + i) {\n                    arbol[i][j] = '*';\n                } else {\n                    arbol[i][j] = ' ';\n                }\n            }\n        }\n\n        if (estrella) arbol[0][altura - 1] = '@';\n\n        for (int i = 0; i < altura * 2 - 1; i++) {\n            arbol[altura][i] = ' ';\n            arbol[altura + 1][i] = ' ';\n        }\n\n        arbol[altura][altura - 1] = '|';\n        arbol[altura + 1][altura - 1] = '|';\n\n        return arbol;\n    }\n\n    private static void imprimirArbol(char[][] arbol, boolean lucesEncendidas) {\n        for (char[] fila : arbol) {\n            for (char c : fila) {\n                if (c == '+' && !lucesEncendidas) System.out.print('*');\n                else System.out.print(c);\n            }\n            System.out.println();\n        }\n    }\n\n    private static void modificarBolas(char[][] arbol) {\n        for (int i = 1; i < arbol.length - 2; i++) {\n            for (int j = 0; j < arbol[i].length; j++) {\n                if (arbol[i][j] == '*' && random.nextBoolean()) arbol[i][j] = 'o';\n                else if (arbol[i][j] == 'o' && random.nextBoolean()) arbol[i][j] = '*';\n            }\n        }\n    }\n\n    private static void modificarLuces(char[][] arbol) {\n        for (int i = 1; i < arbol.length - 2; i++) {\n            for (int j = 0; j < arbol[i].length; j++) {\n                if (arbol[i][j] == '*' && random.nextBoolean()) arbol[i][j] = '+';\n                else if (arbol[i][j] == '+' && random.nextBoolean()) arbol[i][j] = '*';\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/java/miguelex.java",
    "content": "import java.util.*;\nimport java.util.stream.Collectors;\n\npublic class miguelex {\n\n    private static void displayTree(List<String> tree) {\n        for (String line : tree) {\n            System.out.println(line);\n        }\n    }\n\n    private static List<String> createTree(int height, boolean hasStar, Map<Integer, Map<Integer, String>> decorations, boolean lightsOn) {\n        List<String> tree = new ArrayList<>();\n\n        // Estrella opcional\n        if (hasStar) {\n            tree.add(\" \".repeat(height - 1) + \"@\");\n        }\n\n        // Ramas\n        for (int i = 1; i <= height; i++) {\n            StringBuilder line = new StringBuilder(\" \".repeat(height - i));\n            for (int j = 0; j < 2 * i - 1; j++) {\n                String deco = decorations.getOrDefault(i, Collections.emptyMap()).get(j);\n                line.append(deco != null ? deco : \"*\");\n            }\n            tree.add(line.toString());\n        }\n\n        // Tronco\n        String trunkPadding = \" \".repeat(height - 2);\n        tree.add(trunkPadding + \"|||\");\n        tree.add(trunkPadding + \"|||\");\n\n        return tree;\n    }\n\n    private static void addRandomDecoration(Map<Integer, Map<Integer, String>> decorations, int height, String type, int count) {\n        Random random = new Random();\n        int added = 0;\n\n        while (added < count) {\n            int row = random.nextInt(height) + 1;\n            int col = random.nextInt(2 * row - 1);\n\n            decorations.putIfAbsent(row, new HashMap<>());\n            if (!decorations.get(row).containsKey(col)) {\n                decorations.get(row).put(col, type);\n                added++;\n            }\n        }\n    }\n\n    private static void removeRandomDecoration(Map<Integer, Map<Integer, String>> decorations, String type, int count) {\n        int removed = 0;\n\n        for (Integer row : new ArrayList<>(decorations.keySet())) {\n            for (Integer col : new ArrayList<>(decorations.get(row).keySet())) {\n                if (decorations.get(row).get(col).equals(type) && removed < count) {\n                    decorations.get(row).remove(col);\n                    removed++;\n                }\n            }\n        }\n    }\n\n    private static void toggleLights(Map<Integer, Map<Integer, String>> decorations, boolean lightsOn) {\n        for (Map<Integer, String> row : decorations.values()) {\n            for (Map.Entry<Integer, String> entry : row.entrySet()) {\n                if (entry.getValue().equals(\"+\")) {\n                    entry.setValue(lightsOn ? \"+\" : \"*\");\n                }\n            }\n        }\n    }\n\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n        System.out.print(\"Ingrese la altura del árbol: \");\n        int height = scanner.nextInt();\n\n        boolean hasStar = true;\n        Map<Integer, Map<Integer, String>> decorations = new HashMap<>();\n        boolean lightsOn = true;\n\n        while (true) {\n            List<String> tree = createTree(height, hasStar, decorations, lightsOn);\n            displayTree(tree);\n\n            System.out.println(\"\\nOpciones:\");\n            System.out.println(\"1. Añadir/Eliminar estrella\");\n            System.out.println(\"2. Añadir bolas (o)\");\n            System.out.println(\"3. Eliminar bolas (o)\");\n            System.out.println(\"4. Añadir luces (+)\");\n            System.out.println(\"5. Eliminar luces (+)\");\n            System.out.println(\"6. Apagar/Encender luces\");\n            System.out.println(\"7. Salir\");\n\n            System.out.print(\"Seleccione una opción: \");\n            int option = scanner.nextInt();\n\n            switch (option) {\n                case 1:\n                    hasStar = !hasStar;\n                    System.out.println(hasStar ? \"Estrella añadida.\" : \"Estrella eliminada.\");\n                    break;\n                case 2:\n                    addRandomDecoration(decorations, height, \"o\", 2);\n                    System.out.println(\"Bolas añadidas.\");\n                    break;\n                case 3:\n                    removeRandomDecoration(decorations, \"o\", 2);\n                    System.out.println(\"Bolas eliminadas.\");\n                    break;\n                case 4:\n                    addRandomDecoration(decorations, height, \"+\", 3);\n                    System.out.println(\"Luces añadidas.\");\n                    break;\n                case 5:\n                    removeRandomDecoration(decorations, \"+\", 3);\n                    System.out.println(\"Luces eliminadas.\");\n                    break;\n                case 6:\n                    lightsOn = !lightsOn;\n                    toggleLights(decorations, lightsOn);\n                    System.out.println(lightsOn ? \"Luces encendidas.\" : \"Luces apagadas.\");\n                    break;\n                case 7:\n                    System.out.println(\"¡Feliz Navidad!\");\n                    scanner.close();\n                    return;\n                default:\n                    System.out.println(\"Opción no válida.\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/java/rcellas.java",
    "content": "\nimport java.util.Random;\nimport java.util.Scanner;\n\n\npublic class rcellas {\n    public static void main(String[] args) {\n\n        Scanner scanner = new Scanner(System.in);\n        Random random = new Random();\n\n        // declaración de la altura del arbol\n        System.out.println(\"¿De cuantas altura quieres tu árbol de navidad?\");\n        int heightTree = Integer.parseInt(scanner.nextLine());\n\n        System.out.println(\"\\n¿Cómo de largo quieres tú tronco?\");\n        int trunkTree = Integer.parseInt(scanner.nextLine());\n\n        System.out.println(\"\\n¿Quieres añadir una estrella (@) en la copa del árbol? (s/n)\");\n        boolean starTree = scanner.nextLine().equalsIgnoreCase(\"s\");\n\n        System.out.println(\"\\n¿Quieres añadir la decoración (o) al árbol? (s/n)\");\n        boolean  ballsTree = scanner.nextLine().equalsIgnoreCase(\"s\");\n\n        System.out.println(\"\\n¿Quieres añadir las luces (+) al árbol? (s/n)\");\n        boolean  lightTree = scanner.nextLine().equalsIgnoreCase(\"s\");\n\n        System.out.println(\"\\n¿Has sido bueno durante este años? (s/n)\");\n        boolean presentTrunk = scanner.nextLine().equalsIgnoreCase(\"s\");\n\n        // tree\n        for (int rows =0; rows < heightTree; rows++){\n            for(int space =0;space < (heightTree-rows-1);space++){\n                System.out.print(\" \");\n            }\n\n            if(rows ==0 && starTree){\n                System.out.print(\"\\u001B[33m@\");\n            }else{\n                for(int asterisk =0;asterisk<(rows*2)+1;asterisk++){\n                    String symbol = \"\\u001b[32m*\";\n                    if(lightTree && asterisk %2 == 0 && random.nextBoolean()){\n                        symbol = \"\\u001B[31mo\";\n                    }\n                    if(ballsTree && asterisk %2 == 1 && random.nextBoolean()){\n                        symbol = \"\\u001B[34m+\";\n                    }\n                    System.out.print(symbol);\n                }\n            }\n            System.out.println(\" \");\n\n        }\n\n        //trunk\n        for (int base= 0; base <trunkTree;base++){\n            for(int space = 0;space<(heightTree-2);space++){\n                System.out.print(\" \");\n            }\n            for(int tronco=0;tronco<3;tronco++){\n                System.out.print(\"|\");\n            }\n            System.out.println(\" \");\n        }\n\n        // presents\n        if(presentTrunk){\n            for (int base= 0; base <heightTree;base++){\n                System.out.print(\"\\u001B[35m[ ]\");\n            }\n        }else{\n            System.out.print(\" \");\n        }\n        scanner.close();\n\n    }\n}"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #47 - JavaScript -> Jesus Antonio Escamilla */\n\n/**\n * ÁRBOL DE NAVIDAD.\n * Utilizando la Terminal para pedir datos y agregarlos.\n */\n\nconst readline = require('readline');\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout,\n});\n\nlet height = 0;\nlet star = true;\nlet balls = [];\nlet lights = [];\nlet lightsLit = true;\n\nconst generateTree = () => {\n    let tree = [];\n\n    if (star) {\n        tree.push(' '.repeat(height - 1) + '@');\n    }\n\n    for (let i = 0; i < height; i++) {\n        const spaces = ' '.repeat(height - i - 1);\n        let row = '*'.repeat(i * 2 + 1);\n\n        for (let j = 0; j < row.length; j++) {\n            if (balls.includes(`${i}-${j}`)) {\n                row = row.substring(0, j) + 'o' + row.substring(j + 1);\n            } else if (lights.includes(`${i}-${j}`)) {\n                row = row.substring(0, j) + (lightsLit ? '+' : '*') + row.substring(j + 1);\n            }\n        }\n\n        tree.push(spaces + row)\n    }\n\n    const trunk = ' '.repeat(height - 2) + '|||';\n    tree.push(trunk);\n    tree.push(trunk);\n\n    return tree.join('\\n');\n};\n\nconst showTree = () => {\n    console.log(generateTree());\n};\n\nconst getPositionRandom = (height) => {\n    const level = Math.floor(Math.random() * height);\n    const position = Math.floor(Math.random() * (level * 2 + 1));\n    return `${level}-${position}`;\n};\n\nconst handleOptions = () => {\n    console.log('\\nOpciones:');\n    console.log('1. Añadir/eliminar estrella');\n    console.log('2. Añadir/eliminar bolas (de dos en dos)');\n    console.log('3. Añadir/eliminar luces (de tres en tres)');\n    console.log('4. Apagar/encender luces');\n    console.log('5. Salir');\n\n    rl.question('Seleccione una opción: ', (option) =>{\n        switch (option) {\n            case '1':\n                star = !star;\n                console.log(`Estrella ${star ? 'añadida' : 'eliminada'}.`);\n                break;\n\n            case '2': {\n                for (let i = 0; i < 2; i++) {\n                    const position = getPositionRandom(height);\n                    if (balls.includes(position)) {\n                        balls = balls.filter((b) => b !== position);\n                        console.log(`Bola eliminada en ${position}.\\n`);\n                    } else if (!lights.includes(position)){\n                        balls.push(position);\n                        console.log(`Bola añadida en ${position}.\\n`);\n                    }\n                }\n                break;\n            }\n\n            case '3':{\n                for (let i = 0; i < 3; i++) {\n                    const position = getPositionRandom(height);\n                    if (lights.includes(position)) {\n                        lights = lights.filter((l) => l !== position);\n                        console.log(`Luz eliminada en ${position}.\\n`);\n                    } else if (!balls.includes(position)) {\n                        lights.push(position);\n                        console.log(`Luz añadida en ${position}.\\n`);\n                    }\n                }\n                break;\n            }\n\n            case '4':\n                lightsLit = !lightsLit;\n                console.log(`Luces ${lightsLit ? 'encendidas' : 'apagadas'}.`);\n                break;\n\n            case '5':\n                rl.close()\n                return;\n\n            default:\n                console.log(\"Opción no válida.\");\n        }\n\n        showTree();\n        handleOptions();\n    });\n};\n\nrl.question('Introduce la altura del árbol: ', (input) =>{\n    const newHeight = parseInt(input);\n    if (!isNaN(newHeight) && newHeight > 0) {\n        height = newHeight\n    } else {\n        console.log(\"Altura no válida.\");\n    }\n\n    showTree();\n    handleOptions();\n});"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/javascript/RaulDoezon.js",
    "content": "/*\n  EJERCICIO:\n  ¡Ha comenzado diciembre! Es hora de montar nuestro\n  árbol de Navidad...\n\n  Desarrolla un programa que cree un árbol de Navidad\n  con una altura dinámica definida por el usuario por terminal.\n  \n  Ejemplo de árbol de altura 5 (el tronco siempre será igual):\n\n      *\n     ***\n    *****\n   *******\n  *********\n     |||\n     |||\n\n  El usuario podrá seleccionar las siguientes acciones:\n\n  - Añadir o eliminar la estrella en la copa del árbol (@)\n  - Añadir o eliminar bolas de dos en dos (o) aleatoriamente\n  - Añadir o eliminar luces de tres en tres (+) aleatoriamente\n  - Apagar (*) o encender (+) las luces (conservando su posición)\n  - Una luz y una bola no pueden estar en el mismo sitio\n\n  Sólo puedes añadir una estrella, y tantas luces o bolas\n  como tengan cabida en el árbol. El programa debe notificar\n  cada una de las acciones (o por el contrario, cuando no\n  se pueda realizar alguna).\n*/\n\nclass ChristmasTree {\n  constructor() {\n    this.treePlan = [];\n    this.spaces = [];\n    this.spheresSpaces = [];\n    this.lightsSpaces = [];\n    this.lighsOffSpaces = [];\n    this.lightsOnSpaces = [];\n    this.treeHeight = parseInt(prompt(\"Ingresa un número mayor a 0 (cero) para definir la altura del árbol:\"), 10);\n    this.treeWidth = this.treeHeight * 2 - 1;\n    this.pin = \".\";\n  }\n\n  structure() {\n    let rangeStart = this.treeHeight - 1;\n    let rangeEnd = this.treeHeight;\n    let rangeCenter = Math.floor(this.treeWidth / 2) - 1;\n\n    for (let row = 0; row < this.treeHeight + 2; row++) {\n      let space = \" \";\n      let pipe = \"|\";\n\n      this.treePlan[row] = [];\n\n      for (let column = 0; column < this.treeWidth; column++) {\n        this.treePlan[row].push(space);\n      }\n\n      if (row < this.treeHeight) {\n        this.treePlan[row].fill(this.pin, rangeStart, rangeEnd);\n\n        rangeStart = rangeStart - 1;\n        rangeEnd = rangeEnd + 1;\n      }\n\n      if (row >= this.treeHeight) {\n        this.treePlan[row].fill(pipe, rangeCenter, rangeCenter + 3);\n      }\n    }\n  }\n\n  availablePositions(destinyArray, firstElement, secondElement) {\n    for (let column = 1; column < this.treePlan.length; column++) {\n      for (let row = 0; row < this.treePlan[column].length; row++) {\n        if (secondElement == undefined) {\n          if (this.treePlan[column][row] === firstElement) {\n            destinyArray.push([column, row]);\n          }\n        } else {\n          if (this.treePlan[column][row] === firstElement || this.treePlan[column][row] === secondElement) {\n            destinyArray.push([column, row]);\n          }\n        }\n      }\n    }\n  }\n\n  shufflePositions(array) {\n    for (let index = array.length - 1; index > 0; index--) {\n      const shufflePosition = Math.floor(Math.random() * (index + 1));\n\n      [array[index], array[shufflePosition]] = [array[shufflePosition], array[index]];\n    }\n  }\n\n  star(option) {\n    let star = \"@\";\n    let checkStar = this.treePlan[0].findIndex((starElement) => starElement === star);\n    let starPosition = Math.floor(this.treeWidth / 2);\n\n    if (option === 1) {\n      if (checkStar === -1) {\n        this.treePlan[0][starPosition] = star;\n\n        alert(\"La estrella fue colocada.\");\n      } else {\n        alert(\"No puede realizarse la acción porque la estrella ya está colocada.\");\n      }\n    } else if (option === 2) {\n      if (checkStar > -1) {\n        this.treePlan[0][starPosition] = this.pin;\n\n        alert(\"La estrella fue retirada.\");\n      } else {\n        alert(\"No puede realizarse la acción porque la estrella no ha sido colocada.\");\n      }\n    } else {\n      alert(\"Debes ingresar un número dentro de las opciones.\");\n    }\n  }\n\n  spheres(option) {\n    const sphere = \"o\";\n\n    if (option === 1) {\n      if (this.spaces.length > 1) {\n        this.treePlan[this.spaces[0][0]][this.spaces[0][1]] = sphere;\n        this.treePlan[this.spaces[1][0]][this.spaces[1][1]] = sphere;\n\n        alert(\"Se colocaron 2 esferas.\");\n      } else {\n        alert(\"No hay espacio para colocar las esferas.\");\n      }\n    } else if (option === 2) {\n      this.spheresSpaces = [];\n\n      this.availablePositions(this.spheresSpaces, sphere);\n      this.shufflePositions(this.spheresSpaces);\n\n      if (this.spheresSpaces.length > 1) {\n        this.treePlan[this.spheresSpaces[0][0]][this.spheresSpaces[0][1]] = this.pin;\n        this.treePlan[this.spheresSpaces[1][0]][this.spheresSpaces[1][1]] = this.pin;\n\n        alert(\"Se retiraron dos esferas.\");\n      } else {\n        alert(\"No puede realizarse la acción porque no hay esferas para eliminar.\");\n      }\n    } else {\n      alert(\"Debes ingresar un número dentro de las opciones.\");\n    }\n  }\n\n  lights(option) {\n    const lightOn = \"+\";\n    const lightOff = \"-\";\n\n    if (option === 1) {\n      if (this.spaces.length > 1) {\n        this.treePlan[this.spaces[0][0]][this.spaces[0][1]] = lightOn;\n        this.treePlan[this.spaces[1][0]][this.spaces[1][1]] = lightOn;\n        this.treePlan[this.spaces[2][0]][this.spaces[2][1]] = lightOn;\n\n        alert(\"Se colocaron 3 luces.\");\n      } else {\n        alert(\"No hay espacio para colocar las luces.\");\n      }\n      \n    } else if (option === 2) {\n      this.lighsOffSpaces = [];\n\n      this.availablePositions(this.lighsOffSpaces, lightOff);\n\n      if (this.lighsOffSpaces.length > 0) {\n        for (let index = 0; index < this.lighsOffSpaces.length; index++) {\n          this.treePlan[this.lighsOffSpaces[index][0]][this.lighsOffSpaces[index][1]] = lightOn;\n        }\n\n        alert(\"Se encendieron las luces.\");\n      } else {\n        alert(\"No hay luces por encender.\");\n      }\n    } else if (option === 3) {\n      this.lightsOnSpaces = [];\n\n      this.availablePositions(this.lightsOnSpaces, lightOn);\n\n      if (this.lightsOnSpaces.length > 0) {\n        for (let index = 0; index < this.lightsOnSpaces.length; index++) {\n          this.treePlan[this.lightsOnSpaces[index][0]][this.lightsOnSpaces[index][1]] = lightOff;\n        }\n\n        alert(\"Se apagaron las luces.\");\n      } else {\n        alert(\"No hay luces por apagar.\");\n      }\n    } else if (option === 4) {\n      this.lightsSpaces = [];\n\n      this.availablePositions(this.lightsSpaces, lightOn, lightOff);\n      this.shufflePositions(this.lightsSpaces);\n\n      if (this.lightsSpaces.length > 1) {\n        this.treePlan[this.lightsSpaces[0][0]][this.lightsSpaces[0][1]] = this.pin;\n        this.treePlan[this.lightsSpaces[1][0]][this.lightsSpaces[1][1]] = this.pin;\n        this.treePlan[this.lightsSpaces[2][0]][this.lightsSpaces[2][1]] = this.pin;\n\n        alert(\"Se retiraron tres luces.\");\n      } else {\n        alert(\"No puede realizarse la acción porque no hay luces para eliminar.\");\n      }\n    } else {\n      alert(\"Debes ingresar un número dentro de las opciones.\");\n    }\n  }\n\n  userActions() {\n    let menu = 0;\n\n    this.structure();\n\n    do {\n      this.spaces = [];\n      menu = parseInt(prompt(\"Ingresa el número de la acción a realizar:\\n1) Estrella.\\n2) Esferas.\\n3) Luces.\\n4) Salir.\"), 10);\n\n      this.availablePositions(this.spaces, this.pin);\n      this.shufflePositions(this.spaces);\n\n      switch (menu) {\n        case 1:\n          let starOption = parseInt(prompt(\"1) Colocar estrella.\\n2) Retirar estrella.\"), 10);\n\n          this.star(starOption);\n\n          break;\n\n        case 2:\n          let spheresOption = parseInt(prompt(\"1) Colocar esferas.\\n2) Retirar esferas.\"), 10);\n\n          this.spheres(spheresOption);\n\n          break;\n\n        case 3:\n          let lightsOption = parseInt(prompt(\"1) Colocar luces.\\n2) Encender luces.\\n3) Apagar luces.\\n4) Retirar luces.\"), 10);\n\n          this.lights(lightsOption);\n\n          break;\n\n        case 4:\n          alert(\"Saliendo del programa...\");\n          break;\n\n        default:\n          alert(\"Por favor, ingresa un número del 1 al 4 para realizar alguna de las acciones del menú.\");\n          break;\n      }\n\n      console.table(this.treePlan);\n    } while (menu !== 4);\n  }\n}\n\nlet christmasTree = new ChristmasTree();\n\nchristmasTree.userActions();\n"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/javascript/duendeintemporal.js",
    "content": "//#48 - ARBOL DE NAVIDAD\n/*\n * EJERCICIO:\n * ¡Ha comenzado diciembre! Es hora de montar nuestro\n * árbol de Navidad...\n *\n * Desarrolla un programa que cree un árbol de Navidad\n * con una altura dinámica definida por el usuario por terminal.\n *\n * Ejemplo de árbol de altura 5 (el tronco siempre será igual):\n *\n *     *\n *    ***\n *   *****\n *  *******\n * *********\n *    |||\n *    |||\n *\n * El usuario podrá seleccionar las siguientes acciones:\n * \n * - Añadir o eliminar la estrella en la copa del árbol (@)\n * - Añadir o eliminar bolas de dos en dos (o) aleatoriamente\n * - Añadir o eliminar luces de tres en tres (+) aleatoriamente\n * - Apagar (*) o encender (+) las luces (conservando su posición)\n * - Una luz y una bola no pueden estar en el mismo sitio\n *\n * Sólo puedes añadir una estrella, y tantas luces o bolas\n * como tengan cabida en el árbol. El programa debe notificar\n * cada una de las acciones (o por el contrario, cuando no\n * se pueda realizar alguna).\n */\n\nlet log = console.log; \n\nconst readline = require('readline');\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\n// Prompt the user to enter the height of the tree\nrl.question('Enter the height of the Christmas tree (between 3 and 20): ', (heightInput) => {\n    const treeHeight = parseInt(heightInput, 10);\n\n    if (isNaN(treeHeight) || treeHeight < 3 || treeHeight > 20) {\n        console.log('\\nInvalid tree height. Please enter a number between 3 and 20.\\n');\n        rl.close();\n        return;\n    }\n\n    // Define the initial state of the tree\n    let tree = [];\n    let star = false;\n    let lights = [];\n    let ornaments = [];\n\n    // Function to create the initial tree\n    function createTree() {\n        for (let i = 0; i < treeHeight; i++) {\n            let row = \"\";\n            for (let j = 0; j < treeHeight - i - 1; j++) {\n                row += \" \";\n            }\n            for (let k = 0; k < 2 * i + 1; k++) {\n                row += \"*\";\n            }\n            tree.push(row);\n        }\n        // Center the trunk based on the maximum width of the tree\n        const trunkWidth = 3; // Width of the trunk\n        const trunkSpace = (2 * treeHeight - 1 - trunkWidth) / 2; // Calculate spaces to center the trunk\n        tree.push(\" \".repeat(trunkSpace) + \"|||\");\n        tree.push(\" \".repeat(trunkSpace) + \"|||\");\n    }\n\n    createTree();\n\n    // Function to add the star\n    function addStar() {\n        if (!star) {\n            tree[0] = \" \".repeat(treeHeight - 1) + \"@\";\n            star = true;\n            log(\"Star added to the tree.\");\n        } else {\n            log(\"There is already a star on the tree.\");\n        }\n    }\n\n    // Function to remove the star\n    function removeStar() {\n        if (star) {\n            tree[0] = \" \".repeat(treeHeight - 1) + \"*\";\n            star = false;\n            log(\"Star removed from the tree.\");\n        } else {\n            log(\"There is no star on the tree.\");\n        }\n    }\n\n    // Function to add lights\n    function addLights() {\n        const numLights = Math.floor(Math.random() * (treeHeight * 3 - lights.length));\n        for (let i = 0; i < numLights; i++) {\n            const row = Math.floor(Math.random() * treeHeight);\n            const col = Math.floor(Math.random() * (2 * row + 1));\n            if (tree[row][col] === \"*\" && !ornaments.includes(`${row},${col}`)) {\n                tree[row] = tree[row].substring(0, col) + \"+\" + tree[row].substring(col + 1);\n                lights.push(`${row},${col}`);\n                log(\"Lights added to the tree.\");\n            }\n        }\n    }\n\n    // Function to remove lights\n    function removeLights() {\n        const numLights = Math.floor(Math.random() * (lights.length / 3));\n        for (let i = 0; i < numLights; i++) {\n            if (lights.length > 0) {\n                const index = Math.floor(Math.random() * lights.length);\n                const [row, col] = lights[index].split(\",\").map(Number);\n                tree[row] = tree[row].substring(0, col) + \"*\" + tree[row].substring(col + 1);\n                lights.splice(index, 1);\n                log(\"Lights removed from the tree.\");\n            } else {\n                log(\"There are no lights on the tree.\");\n                break;\n            }\n        }\n    }\n\n    // Function to add ornaments\n    function addOrnaments() {\n        const numOrnaments = Math.floor(Math.random() * (treeHeight * 3 - ornaments.length));\n        for (let i = 0; i < numOrnaments; i++) {\n            const row = Math.floor(Math.random() * treeHeight);\n            const col = Math.floor(Math.random() * (2 * row + 1));\n            if (tree[row][col] === \"*\" && !lights.includes(`${row},${col}`)) {\n                tree[row] = tree[row].substring(0, col) + \"o\" + tree[row].substring(col + 1);\n                ornaments.push(`${row},${col}`);\n                log(\"Ornaments added to the tree.\");\n            }\n        }\n    }\n\n    // Function to toggle lights\n    function toggleLights() {\n        for (let i = 0; i < lights.length; i++) {\n            const [row, col] = lights[i].split(\",\").map(Number);\n            if (tree[row][col] === \"+\") {\n                tree[row] = tree[row].substring(0, col) + \"*\" + tree[row].substring(col + 1);\n            } else {\n                tree[row] = tree[row].substring(0, col) + \"+\" + tree[row].substring(col + 1);\n            }\n        }\n        log(\"Lights toggled.\");\n    }\n\n    // Main function\n    function main() {\n        log('\\n     Merry Christmas!\\n');\n        log(tree.join('\\n'));\n        log('\\nCongratulations! Enjoy your Christmas Tree.\\n');\n        log('Now you can decorate your tree as you prefer. Choose an option below:\\n');\n        log('1. Add Star');\n        log('2. Remove Star');\n        log('3. Add Lights');\n        log('4. Remove Lights');\n        log('5. Add Ornaments');\n        log('6. Toggle Lights');\n        log('7. Exit');\n\n        rl.question('Type the Option Number: ', (input) => {\n            switch (input) {\n                case '1':\n                    addStar();\n                    break;\n                case '2':\n                    removeStar();\n                    break;\n                case '3':\n                    addLights();\n                    break;\n                case '4':\n                    removeLights();\n                    break;\n                case '5':\n                    addOrnaments();\n                    break;\n                case '6':\n                    toggleLights();\n                    break;\n                case '7':\n                    log('\\nGoodbye! Merry Christmas!');\n                    rl.close();\n                    return;\n                default:\n                    log('\\nInvalid Option. Please try again.\\n');\n                    break;\n            }\n\n            // log(tree.join('\\n'));\n            main();\n        });\n    };\n\n    main();\n});\n\n"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/javascript/hectorio23.js",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\nconst readline = require('readline');\n\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout\n});\n\nfunction drawTree(tree) {\n  console.clear();\n  tree.forEach(line => console.log(line));\n  console.log();\n}\n\nfunction initializeTree(height, hasStar) {\n  const tree = [];\n\n  if (hasStar) {\n    tree.push(' '.repeat(height) + '@');\n  }\n\n  for (let i = 0; i < height; i++) {\n    const width = 2 * i + 1;\n    const row = ' '.repeat(height - i - 1) + '*'.repeat(width);\n    tree.push(row);\n  }\n\n  const trunk = ' '.repeat(height - 1) + '|||';\n  tree.push(trunk);\n  tree.push(trunk);\n\n  return tree;\n}\n\nfunction toggleStar(tree, height, hasStar) {\n  hasStar = !hasStar;\n  const newTree = initializeTree(height, hasStar);\n  console.log(`Estrella ${hasStar ? 'añadida' : 'eliminada'}.`);\n  return { tree: newTree, hasStar };\n}\n\nfunction addOrRemove(tree, height, symbol, count, add) {\n  let modifications = 0;\n\n  for (let i = 1; i <= height; i++) {\n    const row = tree[i].split('');\n\n    for (let j = 0; j < row.length; j++) {\n      if ((add && row[j] === '*' && Math.random() < 0.5) || (!add && row[j] === symbol)) {\n        row[j] = add ? symbol : '*';\n        modifications++;\n      }\n      if (modifications === count) break;\n    }\n\n    tree[i] = row.join('');\n    if (modifications === count) break;\n  }\n\n  console.log(`${add ? 'Añadido' : 'Eliminado'} ${modifications} de ${symbol}.`);\n  return tree;\n}\n\nfunction toggleLights(tree, height, lightsOn) {\n  lightsOn = !lightsOn;\n\n  for (let i = 1; i <= height; i++) {\n    const row = tree[i].split('');\n    for (let j = 0; j < row.length; j++) {\n      if (row[j] === '*' || row[j] === '+') {\n        row[j] = lightsOn ? '+' : '*';\n      }\n    }\n    tree[i] = row.join('');\n  }\n\n  console.log(`Luces ${lightsOn ? 'encendidas' : 'apagadas'}.`);\n  return { tree, lightsOn };\n}\n\nfunction main() {\n  rl.question('Ingresa la altura del árbol: ', input => {\n    const height = parseInt(input, 10);\n    if (isNaN(height) || height <= 0) {\n      console.log('Altura inválida.');\n      rl.close();\n      return;\n    }\n\n    let hasStar = true;\n    let lightsOn = false;\n    let tree = initializeTree(height, hasStar);\n\n    function menu() {\n      drawTree(tree);\n      rl.question('Opciones: [estrella, bolas, luces, apagar, salir]: ', option => {\n        switch (option.trim().toLowerCase()) {\n          case 'estrella':\n            ({ tree, hasStar } = toggleStar(tree, height, hasStar));\n            break;\n          case 'bolas':\n            tree = addOrRemove(tree, height, 'o', 2, true);\n            break;\n          case 'luces':\n            tree = addOrRemove(tree, height, '+', 3, true);\n            break;\n          case 'apagar':\n            ({ tree, lightsOn } = toggleLights(tree, height, lightsOn));\n            break;\n          case 'salir':\n            console.log('Gracias por decorar el árbol!');\n            rl.close();\n            return;\n          default:\n            console.log('Opción no válida.');\n        }\n        menu();\n      });\n    }\n\n    menu();\n  });\n}\n\nmain();\n"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n_______________________________________________________\n#48 ÁRBOL DE NAVIDAD\n-------------------------------------------------------\n* EJERCICIO:\n * ¡Ha comenzado diciembre! Es hora de montar nuestro\n * árbol de Navidad...\n * \n * Desarrolla un programa que cree un árbol de Navidad\n * con una altura dinámica definida por el usuario por terminal.\n * \n * Ejemplo de árbol de altura 5 (el tronco siempre será igual):\n * \n *     *\n *    ***\n *   *****\n *  *******\n * *********\n *    |||\n *    |||\n *\n * El usuario podrá seleccionar las siguientes acciones:\n * \n * - Añadir o eliminar la estrella en la copa del árbol (@)\n * - Añadir o eliminar bolas de dos en dos (o) aleatoriamente\n * - Añadir o eliminar luces de tres en tres (+) aleatoriamente\n * - Apagar (*) o encender (+) las luces (conservando su posición)\n * - Una luz y una bola no pueden estar en el mismo sitio\n *\n * Sólo puedes añadir una estrella, y tantas luces o bolas\n * como tengan cabida en el árbol. El programa debe notificar\n * cada una de las acciones (o por el contrario, cuando no\n * se pueda realizar alguna).\n */\n// ________________________________________________________\nconst readlineSync = require('readline-sync');\nconst clear = require('clear');\nconst sleep = ms => new Promise(resolve => setTimeout(resolve, ms));\n\nclass ChristmasTree {\n    constructor(size) {\n        this.size = size;\n        this.mtx = Array.from({ length: size }, () => Array(size * 2 - 1).fill(\" \"));\n        this.star = [0, size - 1];\n        this.treeTop = [];\n        this.balls = [];\n        this.lights = [];\n    }\n\n    printTree() {\n        console.log();\n        this.mtx.forEach(row => console.log(row.join('')));\n        let spaces = Math.floor((this.size * 2 - 4) / 2);\n        console.log(\" \".repeat(spaces) + \"|||\");\n        console.log(\" \".repeat(spaces) + \"|||\");\n    }\n\n    createTree() {\n        let center = this.size - 1;\n        for (let i = 0; i < this.size; i++) {\n            let ast = \"*\".repeat(i * 2 + 1);\n            for (let j = 0; j < ast.length; j++) {\n                let col = center - i + j;\n                this.mtx[i][col] = ast[j];\n                this.treeTop.push([i, col]);\n            }\n        }\n        this.treeTop.shift();\n    }\n\n    addRemoveStar() {\n        let [r, c] = this.star;\n        if (this.mtx[r][c] === \"*\") {\n            this.mtx[r][c] = \"@\";\n        } else {\n            this.mtx[r][c] = \"*\";\n        }\n    }\n\n    addBalls() {\n        if (this.treeTop.length < 2) {\n            console.log(\"Ya no hay espacio para poner bolas.\");\n            return;\n        }\n\n        let randomLocations = this.randomSample(this.treeTop, 2);\n        randomLocations.forEach(([r, c]) => {\n            this.balls.push([r, c]);\n            this.treeTop = this.treeTop.filter(pos => pos[0] !== r || pos[1] !== c);\n            this.mtx[r][c] = \"o\";\n        });\n    }\n\n    removeBalls() {\n        if (this.balls.length === 0) {\n            console.log(\"No hay bolas que eliminar.\");\n            return;\n        }\n\n        let randomLocations = this.randomSample(this.balls, 2);\n        randomLocations.forEach(([r, c]) => {\n            this.balls = this.balls.filter(pos => pos[0] !== r || pos[1] !== c);\n            this.treeTop.push([r, c]);\n            this.mtx[r][c] = \"*\";\n        });\n    }\n\n    addLights() {\n        if (this.treeTop.length < 3) {\n            console.log(\"Ya no hay espacio para poner luces.\");\n            return;\n        }\n\n        let randomLocations = this.randomSample(this.treeTop, 3);\n        randomLocations.forEach(([r, c]) => {\n            this.lights.push([r, c]);\n            this.treeTop = this.treeTop.filter(pos => pos[0] !== r || pos[1] !== c);\n            this.mtx[r][c] = \"+\";\n        });\n    }\n\n    removeLights() {\n        if (this.lights.length === 0) {\n            console.log(\"Ya no hay luces que eliminar.\");\n            return;\n        }\n\n        let randomLocations = this.randomSample(this.lights, 3);\n        randomLocations.forEach(([r, c]) => {\n            this.lights = this.lights.filter(pos => pos[0] !== r || pos[1] !== c);\n            this.treeTop.push([r, c]);\n            this.mtx[r][c] = \"*\";\n        });\n    }\n\n    onOffLights() {\n        if (this.lights.length === 0) {\n            console.log(\"No hay luces.\");\n            return;\n        }\n\n        this.lights.forEach(([r, c]) => {\n            this.mtx[r][c] = this.mtx[r][c] === \"*\" ? \"+\" : \"*\";\n        });\n    }\n\n    async automaticLights() {\n        while (true) {\n            clear();\n            this.lights.forEach(([r, c]) => {\n                this.mtx[r][c] = this.mtx[r][c] === \"*\" ? \"+\" : \"*\";\n            });\n            this.printTree();\n            await sleep(1000);\n        }\n    }\n\n    randomSample(arr, size) {\n        const sampled = [];\n        while (sampled.length < size) {\n            let randIndex = Math.floor(Math.random() * arr.length);\n            sampled.push(arr.splice(randIndex, 1)[0]);\n        }\n        return sampled;\n    }\n}\n\nasync function menu(menu, tree) {\n    while (true) {\n        tree.printTree();\n        console.log(menu);\n        let option = readlineSync.question(\"Option: \");\n\n        switch (option) {\n            case '1': tree.addRemoveStar(); break;\n            case '2': tree.addBalls(); break;\n            case '3': tree.removeBalls(); break;\n            case '4': tree.addLights(); break;\n            case '5': tree.removeLights(); break;\n            case '6': tree.onOffLights(); break;\n            case '7': await tree.automaticLights(); break;\n            case '8': return;\n            default: console.log(\"Opción inválida.\");\n        }\n    }\n}\n\nfunction getSize() {\n    while (true) {\n        let size = readlineSync.question(\"Size: \");\n        if (size.match(/^\\d+$/) && parseInt(size) % 2 !== 0 && parseInt(size) >= 3) {\n            return parseInt(size);\n        }\n        console.log(\"Debe ser un número impar >= 3.\");\n    }\n}\n\nconst MENU = `\n1 - Agregar/Remover estrella.\n2 - Agregar bolas.    | 3 - Quitar bolas.\n4 - Agregar luces.    | 5 - Quitar luces.\n6 - Encender/Apagar luces.\n7 - Luces automáticas.| 8 - Salir\n`;\n\n(async () => {\n    let size = getSize();\n    let christmasTree = new ChristmasTree(size);\n    christmasTree.createTree();\n    await menu(MENU, christmasTree);\n})();\n"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/javascript/miguelex.js",
    "content": "const readline = require(\"readline\");\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nfunction createTree(height, hasStar, decorations, lightsOn) {\n    let tree = [];\n\n    // Estrella opcional\n    if (hasStar) {\n        tree.push(\" \".repeat(height - 1) + \"@\");\n    }\n\n    // Ramas\n    for (let i = 1; i <= height; i++) {\n        let line = \" \".repeat(height - i);\n        for (let j = 0; j < 2 * i - 1; j++) {\n            if (decorations[i] && decorations[i][j]) {\n                line += decorations[i][j];\n            } else {\n                line += \"*\";\n            }\n        }\n        tree.push(line);\n    }\n\n    // Tronco\n    const trunkPadding = \" \".repeat(height - 2);\n    tree.push(trunkPadding + \"|||\");\n    tree.push(trunkPadding + \"|||\");\n\n    return tree;\n}\n\nfunction displayTree(tree) {\n    console.log(tree.join(\"\\n\"));\n}\n\nfunction addRandomDecoration(decorations, height, type, count) {\n    let added = 0;\n    while (added < count) {\n        const row = Math.floor(Math.random() * height) + 1;\n        const col = Math.floor(Math.random() * (2 * row - 1));\n\n        if (!decorations[row]) decorations[row] = {};\n        if (!decorations[row][col]) {\n            decorations[row][col] = type;\n            added++;\n        }\n    }\n}\n\nfunction removeRandomDecoration(decorations, type, count) {\n    let removed = 0;\n    for (const row in decorations) {\n        for (const col in decorations[row]) {\n            if (decorations[row][col] === type && removed < count) {\n                delete decorations[row][col];\n                removed++;\n            }\n        }\n    }\n}\n\nfunction toggleLights(decorations, lightsOn) {\n    for (const row in decorations) {\n        for (const col in decorations[row]) {\n            if (decorations[row][col] === \"+\") {\n                decorations[row][col] = lightsOn ? \"+\" : \"*\";\n            }\n        }\n    }\n}\n\nfunction promptUser(query) {\n    return new Promise(resolve => rl.question(query, resolve));\n}\n\n(async function main() {\n    const height = parseInt(await promptUser(\"Ingrese la altura del árbol: \"), 10);\n    let hasStar = true;\n    let decorations = {};\n    let lightsOn = true;\n\n    while (true) {\n        const tree = createTree(height, hasStar, decorations, lightsOn);\n        displayTree(tree);\n\n        console.log(\"\\nOpciones:\");\n        console.log(\"1. Añadir/Eliminar estrella\");\n        console.log(\"2. Añadir bolas (o)\");\n        console.log(\"3. Eliminar bolas (o)\");\n        console.log(\"4. Añadir luces (+)\");\n        console.log(\"5. Eliminar luces (+)\");\n        console.log(\"6. Apagar/Encender luces\");\n        console.log(\"7. Salir\");\n\n        const option = parseInt(await promptUser(\"Seleccione una opción: \"), 10);\n\n        switch (option) {\n            case 1:\n                hasStar = !hasStar;\n                console.log(hasStar ? \"Estrella añadida.\" : \"Estrella eliminada.\");\n                break;\n            case 2:\n                addRandomDecoration(decorations, height, \"o\", 2);\n                console.log(\"Bolas añadidas.\");\n                break;\n            case 3:\n                removeRandomDecoration(decorations, \"o\", 2);\n                console.log(\"Bolas eliminadas.\");\n                break;\n            case 4:\n                addRandomDecoration(decorations, height, \"+\", 3);\n                console.log(\"Luces añadidas.\");\n                break;\n            case 5:\n                removeRandomDecoration(decorations, \"+\", 3);\n                console.log(\"Luces eliminadas.\");\n                break;\n            case 6:\n                lightsOn = !lightsOn;\n                toggleLights(decorations, lightsOn);\n                console.log(lightsOn ? \"Luces encendidas.\" : \"Luces apagadas.\");\n                break;\n            case 7:\n                console.log(\"¡Feliz Navidad!\");\n                rl.close();\n                return;\n            default:\n                console.log(\"Opción no válida.\");\n        }\n    }\n})();\n"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/javascript/siderio2.js",
    "content": "/**\n * @author Desiderio Martínez Silva aka siderio2\n * @version 1.0\n * @description \"Javascript implementation of the Christmas Tree exercise 48 from MoureDev Roadmap\"\n * @see https://retosdeprogramacion.com/roadmap/\n *\n */\n\n/**\n * Module for reading data from the terminal\n *\n * @see https://nodejs.org/api/readline.html\n */\nconst readline = require(\"readline\");\n\nclass ChristmasTree {\n  /**\n   * Creates a new Christmas tree.\n   *\n   * By default, the tree has 5 rows, no star on top, no lights on, and no\n   * decorations. The `readline` interface is also initialized for reading\n   * user input from the terminal.\n   */\n  constructor() {\n    this.rows = 5;\n    this.hasStar = false;\n    this.lightsOn = false;\n    this.lights = [];\n    this.balls = [];\n\n    this.rl = readline.createInterface({\n      input: process.stdin,\n      output: process.stdout,\n    });\n  }\n\n  /**\n   * Prints the Christmas tree to the console.\n   * The tree consists of an optional star or top decoration, rows of branches,\n   * and a trunk at the bottom. Decorations such as lights and balls\n   * can be displayed based on the current state of the tree.\n   *\n   * @param {boolean} repeat - If true, allows for changing decorations\n   *                           after printing the tree.\n   */\n  pintChristmasTree(repeat = true) {\n    let offset = this.rows - 1;\n    process.stdout.write(\n      \"\\n\" +\n        \" \".repeat(offset) +\n        (this.hasStar ? \"@\" : this.lightsOn ? \"+\" : \"*\") +\n        \"\\n\"\n    );\n    for (let i = 2; i <= this.rows; i++) {\n      offset--;\n      process.stdout.write(\" \".repeat(offset));\n      const rowLength = 2 * i - 1;\n      for (let j = 1; j <= rowLength; j++) {\n        const coord = [i, j];\n        const char = this.calculateChar(coord);\n        process.stdout.write(char);\n      }\n      process.stdout.write(\"\\n\");\n    }\n    this.printTreeTrunk();\n    if (repeat) {\n      this.changeDecoration();\n    }\n  }\n\n  /**\n   * Prints the trunk of the Christmas tree to the console.\n   * The trunk is represented by a combination of underscores and\n   * pipe characters. The trunk is positioned at the bottom of the\n   * tree, and is decorated with three small present boxes.\n   */\n  printTreeTrunk() {\n    const offset = this.rows - 2;\n    process.stdout.write(\" \".repeat(offset) + \"|||\\u{1F381}\\n\");\n    process.stdout.write(\n      \"_\".repeat(offset - 1) +\n        \"// \\u{1F381}\\u{1F381}\" +\n        \"_\".repeat(offset - 3) +\n        \"\\n\"\n    );\n  }\n\n  /**\n   * Determines the character representation for a given coordinate on the Christmas tree.\n   *\n   * The character is determined based on the presence of balls and the state\n   * of the lights on the tree. If the coordinate matches a ball location,\n   * an 'O' is returned. If a light is matched, and the lights are on,  a '+' is returned.\n   * Otherwise, if the lights are off a '*' is returned.\n   *\n   * @param {Array<number>} coord - The coordinate on the tree in the format [row, column].\n   * @returns {string} The character representing the decoration at the given coordinate.\n   */\n  calculateChar(coord) {\n    coord = JSON.stringify(coord);\n    const balls = JSON.stringify(this.balls);\n\n    if (balls.indexOf(coord) != -1) {\n      return \"O\";\n    } else if (this.lightsOn) {\n      return \"+\";\n    } else {\n      return \"*\";\n    }\n  }\n\n  /**\n   * Creates the default decorations for the Christmas tree with the given number of rows.\n   *\n   * The tree is decorated by assigning a light to each coordinate\n   * on the tree. The tree is then printed to the console.\n   *\n   * @param {number} rows - The number of rows to decorate the tree with.\n   */\n  decorateTree(rows) {\n    if (rows < 2) {\n      console.log(\"Rows must be greater than 1.\");\n      return;\n    }\n    this.rows = rows;\n    for (let i = 2; i <= this.rows; i++) {\n      const rowLength = 2 * i - 1;\n      for (let j = 1; j <= rowLength; j++) {\n        const coord = [i, j];\n        this.lights.push(coord);\n      }\n    }\n    this.pintChristmasTree();\n  }\n\n  /**\n   * Changes the state of the star on top of the Christmas tree.\n   *\n   * If the star is currently on, it is removed. If the star is currently off,\n   * it is added. After changing the state, the tree is redrawn.\n   */\n  changeStarState() {\n    this.hasStar = !this.hasStar;\n    this.pintChristmasTree();\n  }\n\n  /**\n   * Changes the state of the lights on the Christmas tree.\n   *\n   * If the lights are currently on, they are turned off. If the lights are currently off,\n   * they are turned on. After changing the state, the tree is redrawn.\n   */\n  changeLightsState() {\n    this.lightsOn = !this.lightsOn;\n    this.pintChristmasTree();\n  }\n\n  /**\n   * Adds balls to the Christmas tree. If possible, two balls are added at a time.\n   * The coordinates of the added balls are calculated randomly.\n   *\n   * The balls are added in place of the lights on the tree. If there are\n   * no lights on the tree (i.e., the tree is full of balls), no balls are added.\n   * After adding the balls, the tree is redrawn.\n   */\n  addBalls() {\n    const positions = this.lights.length > 1 ? 2 : this.lights.length;\n\n    if (!positions) {\n      console.log(\"Ball-Full-Tree!!! There are no space to add balls.\");\n      return;\n    }\n\n    for (let i = 0; i < positions; i++) {\n      const index = Math.floor(Math.random() * this.lights.length);\n      this.balls.push(this.lights[index]);\n      this.lights.splice(index, 1);\n    }\n    this.pintChristmasTree();\n  }\n\n  /**\n   * Removes balls from the Christmas tree. If possible, two balls are removed at a time.\n   * The coordinates of the removed balls are calculated randomly.\n   *\n   * The balls are removed from the tree and replaced by lights. If there are\n   * no balls on the tree (i.e., the tree is full of lights), no balls are removed.\n   * After removing the balls, the tree is redrawn.\n   */\n  removeBalls() {\n    const positions = this.balls.length > 1 ? 2 : this.balls.length;\n\n    if (!positions) {\n      console.log(\"Ball-Empty-Tree!!! There are no balls to remove.\");\n      return;\n    }\n\n    for (let i = 0; i < positions; i++) {\n      const index = Math.floor(Math.random() * this.balls.length);\n      this.lights.push(this.balls[index]);\n      this.balls.splice(index, 1);\n    }\n    this.pintChristmasTree();\n  }\n\n  /**\n   * Adds lights to the Christmas tree. If possible, three lights are added at a time.\n   * The coordinates of the added lights are calculated randomly.\n   *\n   * The lights are added to the tree and replace balls. If there are\n   * no balls on the tree (i.e., the tree is full of lights), no lights are added.\n   * After adding the lights, the tree is redrawn.\n   */\n  addLights() {\n    const positions = this.balls.length > 2 ? 3 : this.balls.length;\n\n    if (!positions) {\n      console.log(\"Lights-Full-Tree!!! There are no space to add lights.\");\n      return;\n    }\n\n    for (let i = 0; i < positions; i++) {\n      const index = Math.floor(Math.random() * this.balls.length);\n      this.lights.push(this.balls[index]);\n      this.balls.splice(index, 1);\n    }\n    this.pintChristmasTree();\n  }\n\n  /**\n   * Removes lights from the Christmas tree. If possible, three lights are removed at a time.\n   * The coordinates of the removed lights are calculated randomly.\n   *\n   * The lights are removed from the tree and replaced by balls. If there are\n   * no lights on the tree (i.e., the tree is full of balls), no lights are removed.\n   * After removing the lights, the tree is redrawn.\n   */\n  removeLights() {\n    const positions = this.lights.length > 2 ? 3 : this.lights.length;\n\n    if (!positions) {\n      console.log(\"Lights-Empty-Tree!!! There are no lights to remove.\");\n      return;\n    }\n\n    for (let i = 0; i < positions; i++) {\n      const index = Math.floor(Math.random() * this.lights.length);\n      this.balls.push(this.lights[index]);\n      this.lights.splice(index, 1);\n    }\n    this.pintChristmasTree();\n  }\n\n  /**\n   * Prompts the user to define the size of the Christmas tree.\n   *\n   * The user is asked to input a number between 5 and 25, which represents\n   * the number of rows for the tree. If the input is not a valid integer\n   * within this range, the function will prompt again. Once a valid\n   * size is provided, the tree is decorated with the specified number of rows.\n   */\n  defineSize() {\n    this.rl.question(\n      \"How big do you want the tree?? Minimum is 5 and Maximum is 25 rows high: \",\n      (rows) => {\n        rows = parseInt(rows.trim());\n\n        if (isNaN(rows) || !Number.isInteger(rows)) {\n          console.log(\"Please, enter an integer value.\");\n          this.defineSize();\n        } else if (rows < 5 || rows > 25) {\n          console.log(\"Please, enter a value between 5 and 25.\");\n          this.defineSize();\n        } else {\n          this.decorateTree(rows);\n        }\n      }\n    );\n  }\n\n  /**\n   * Allows the user to interactively change the decorations of the Christmas tree.\n   *\n   * The user is presented with a menu of options to change the decorations of the tree.\n   * The options are:\n   * 1. Add/Remove Star\n   * 2. Lights On/Off\n   * 3. Add 2 balls\n   * 4. Remove 2 balls\n   * 5. Add 3 lights\n   * 6. Remove 3 lights\n   * 7. Exit\n   *\n   * The user is asked to input a number between 1 and 7, which\n   * corresponds to one of the options above. If the input is not a valid\n   * integer within this range, the function will prompt again. Once a valid\n   * option is selected, the tree is decorated with the corresponding\n   * change. If the user selects 7, the function will exit and the Christmas\n   * tree will be printed with a message on an empty console.\n   */\n  changeDecoration() {\n    this.rl.question(\n      \"\\nSelect what changes do you want to make:\\n1) Add/Remove Star.\\n2) Lights On/Off.\\n3) Add 2 balls.\\n4) Remove 2 balls.\\n5) Add 3 lights.\\n6) Remove 3 lights.\\n7) Exit.\\n\",\n      (option) => {\n        option = parseInt(option.trim());\n        if (isNaN(option) || !Number.isInteger(option)) {\n          console.log(\n            \"\\nPlease, enter an valid option (an integer between 1 and 7).\"\n          );\n          this.changeDecoration();\n        }\n        if (parseInt(option) < 1 || parseInt(option) > 7) {\n          console.log(\n            \"\\nPlease, enter a valid option (an integer between 1 and 7).\"\n          );\n          this.changeDecoration();\n        } else {\n          switch (option) {\n            case 1:\n              this.changeStarState();\n              this.changeDecoration();\n              break;\n            case 2:\n              this.changeLightsState();\n              this.changeDecoration();\n              break;\n            case 3:\n              this.addBalls();\n              this.changeDecoration();\n              break;\n            case 4:\n              this.removeBalls();\n              this.changeDecoration();\n              break;\n            case 5:\n              this.addLights();\n              this.changeDecoration();\n              break;\n            case 6:\n              this.removeLights();\n              this.changeDecoration();\n              break;\n            case 7:\n              console.clear();\n              console.log(\"\\nGoodbye and enjoy your Christmas Tree!\\n\");\n              this.pintChristmasTree(false);\n              console.log(\"\\n\");\n              this.rl.close();\n              break;\n          }\n        }\n      }\n    );\n  }\n}\n\nconst tree = new ChristmasTree();\ntree.defineSize();\n"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/kotlin/blackriper.kt",
    "content": "import kotlin.random.Random\n\n// al seleccionar una vez se ponen o quitan adornos eso evita llenar el arbol\n\nclass ChrismasTree {\n\n    private var height=0\n    private var addStar=false\n    private var addSpheres=false\n    private var addFocus=false\n    private var focusOn=true\n    private var lisOfSpheres= mutableListOf<Int>()\n\n    fun createTree(){\n        println(\"Introduce la altura del arbol: \")\n        height = readLine()!!.toInt()\n    }\n\n    fun actionsUser(){\n        while (true){\n           drawChristmasTree()\n            println(\"selecciona una accion\")\n            println(\"1. Añadir o eliminar estrella en la copa (@)\")\n            println(\"2. Añadir o eliminar bolas de dos en dos (O) aleatoriamente\")\n            println(\"3. Añadir o eliminar luces de tres en tres (+) aleatoriamente\")\n            println(\"4. Apagar (*) o encender (+) las luces\")\n            println(\"5.- exit\")\n            var option= readLine()!!.toInt()\n            when(option){\n                1->{\n                    addStar=!addStar\n                    if (addStar) println(\"se ha agregado la estrella al arbol\")\n                    else println(\"se ha quitado la estrella del arbol\")\n                }\n                2->{\n                    addSpheres=!addSpheres\n                    if (addSpheres) println(\"se han agregado esferas al arbol\")\n                    else println(\"se ha quitado las esferas del arbol\")\n\n\n                }\n                3->{\n                    addFocus=!addFocus\n                    if (addFocus) println(\"se han agregado luces al arbol \")\n                    else println(\"se han quitado las luces del arbol\")\n                }\n                4->{\n                    focusOn=!focusOn\n                    if (focusOn) println(\"se han prendido las  luces del  arbol \")\n                    else println(\"se han apagado las luces del arbol\")\n                }\n                5->break\n            }\n        }\n    }\n\n   private  fun drawChristmasTree() {\n        if (lisOfSpheres.size>0) lisOfSpheres.clear()\n\n        //dibujar arbol\n        for (i in 0..<height) {\n            for (j in 0..<height - i - 1) {\n                print(\" \")\n            }\n            for (k in 0..<2 * i + 1) {\n                if (addStar && i==0)print(\"@\")\n                else if (k%2==0 && addSpheres){\n                    print(\"O\")\n                    lisOfSpheres.add(k)\n                }\n                else if (k%3==0 && addFocus && !lisOfSpheres.contains(k)){\n                    if (focusOn) print(\"+\") else print(\"*\")\n                }\n                else print(\"*\")\n\n            }\n            println()\n        }\n        //dibujar el tronco\n        for (i in 0..<2) {\n            for (j in 0..<height - 2) {\n                print(\" \")\n            }\n            println(\"|||\")\n        }\n    }\n\n\n\n\n}\n\nfun main() {\n  val tree=ChrismasTree()\n  tree.createTree()\n  tree.actionsUser()\n}"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/php/miguelex.php",
    "content": "<?php\n\nfunction createTree($height, $hasStar, $decorations, $lightsOn) {\n    $tree = [];\n    // Estrella opcional\n    if ($hasStar) {\n        $tree[] = str_repeat(\" \", $height - 1) . \"@\";\n    }\n\n    // Ramas\n    for ($i = 1; $i <= $height; $i++) {\n        $line = str_repeat(\" \", $height - $i);\n        for ($j = 0; $j < (2 * $i - 1); $j++) {\n            if (isset($decorations[$i][$j])) {\n                $line .= $decorations[$i][$j];\n            } else {\n                $line .= \"*\";\n            }\n        }\n        $tree[] = $line;\n    }\n\n    // Tronco\n    $trunkPadding = str_repeat(\" \", $height - 2); // Ajustamos el padding para centrar\n    $tree[] = $trunkPadding . \"|||\";\n    $tree[] = $trunkPadding . \"|||\";\n\n    return $tree;\n}\n\nfunction displayTree($tree) {\n    foreach ($tree as $line) {\n        echo $line . PHP_EOL;\n    }\n}\n\nfunction addRandomDecoration(&$decorations, $height, $type, $count) {\n    $added = 0;\n    while ($added < $count) {\n        $row = rand(1, $height);\n        $col = rand(0, 2 * $row - 2);\n\n        if (!isset($decorations[$row][$col])) {\n            $decorations[$row][$col] = $type;\n            $added++;\n        }\n    }\n}\n\nfunction removeRandomDecoration(&$decorations, $type, $count) {\n    $removed = 0;\n    foreach ($decorations as $row => &$cols) {\n        foreach ($cols as $col => $decor) {\n            if ($decor === $type && $removed < $count) {\n                unset($cols[$col]);\n                $removed++;\n            }\n        }\n    }\n}\n\nfunction toggleLights(&$decorations, $lightsOn) {\n    foreach ($decorations as &$cols) {\n        foreach ($cols as &$decor) {\n            if ($decor === \"+\") {\n                $decor = $lightsOn ? \"+\" : \"*\";\n            }\n        }\n    }\n}\n\n$height = (int)readline(\"Ingrese la altura del árbol: \");\n$hasStar = true;\n$decorations = [];\n$lightsOn = true;\n\nwhile (true) {\n    $tree = createTree($height, $hasStar, $decorations, $lightsOn);\n    displayTree($tree);\n\n    echo PHP_EOL . \"Opciones: \" . PHP_EOL;\n    echo \"1. Añadir/Eliminar estrella\" . PHP_EOL;\n    echo \"2. Añadir bolas (o)\" . PHP_EOL;\n    echo \"3. Eliminar bolas (o)\" . PHP_EOL;\n    echo \"4. Añadir luces (+)\" . PHP_EOL;\n    echo \"5. Eliminar luces (+)\" . PHP_EOL;\n    echo \"6. Apagar/Encender luces\" . PHP_EOL;\n    echo \"7. Salir\" . PHP_EOL;\n\n    $option = (int)readline(\"Seleccione una opción: \");\n\n    switch ($option) {\n        case 1:\n            $hasStar = !$hasStar;\n            echo $hasStar ? \"Estrella añadida.\" : \"Estrella eliminada.\" . PHP_EOL;\n            break;\n        case 2:\n            addRandomDecoration($decorations, $height, \"o\", 2);\n            echo \"Bolas añadidas.\" . PHP_EOL;\n            break;\n        case 3:\n            removeRandomDecoration($decorations, \"o\", 2);\n            echo \"Bolas eliminadas.\" . PHP_EOL;\n            break;\n        case 4:\n            addRandomDecoration($decorations, $height, \"+\", 3);\n            echo \"Luces añadidas.\" . PHP_EOL;\n            break;\n        case 5:\n            removeRandomDecoration($decorations, \"+\", 3);\n            echo \"Luces eliminadas.\" . PHP_EOL;\n            break;\n        case 6:\n            $lightsOn = !$lightsOn;\n            toggleLights($decorations, $lightsOn);\n            echo $lightsOn ? \"Luces encendidas.\" : \"Luces apagadas.\" . PHP_EOL;\n            break;\n        case 7:\n            echo \"¡Feliz Navidad!\" . PHP_EOL;\n            exit;\n        default:\n            echo \"Opción no válida.\" . PHP_EOL;\n    }\n}\n"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/python/Gordo-Master.py",
    "content": "# 48 - Arbol de navidad\nimport random\n\nclass ChristmasTree:\n    def __init__(self, heigth):\n        self.heigth = heigth\n        self.tree = []\n        self.create_tree()\n        self.trunk = \"|||\"\n        self.null_position = self.get_char_positions(\"*\")\n        self.lights_position = set()\n        self.balls_position = set()\n        self.star_position = set()\n\n    def create_tree(self):\n        for n in range(1, self.heigth+1):\n            ocup = [\"*\" for x in range(2*n-1)]\n            self.tree.append(ocup)\n    \n    def display_tree(self):\n        for n in range(0, self.heigth):\n            free = \" \"*(self.heigth - n -1)\n            ocup = self.tree[n]\n            print(free,*ocup,sep=\"\")\n        free = \" \"*(self.heigth - 2)\n        print(\"\".join([free,self.trunk]))\n        print(\"\".join([free,self.trunk]))\n\n    def get_char_positions(self, char) -> set:\n        position_list = set()\n        for row, sublist in enumerate(self.tree):\n            for column, item in enumerate(sublist):\n                if item == char:\n                    position_list.add((row,column))\n        return position_list\n    \n    def star(self, command):\n        match command:\n            case \"on\":\n                if (0,0) in self.null_position:\n                    self.tree[0][0] = \"@\"\n                    self.null_position.discard((0,0))\n                    self.star_position.add((0,0))\n                    print(\"Se ha añadido la estrella de la copa\")\n                elif (0,0) in self.star_position:\n                    print(\"La estrella ya se encuentra en la copa del arbol\")\n                else:\n                    print(f\"Ya se encuentra un'{self.tree[0][0]}' en la copa del arbol\")\n\n            case \"off\":\n                if (0,0) in self.star_position:\n                    self.tree[0][0] = \"*\"\n                    self.null_position.add((0,0))\n                    self.star_position.discard((0,0))\n                    print(\"Se ha eliminado la estrella de la copa\")\n                elif (0,0) in self.null_position:\n                    print(\"No hay estrella en la copa del arbol\")\n                else:\n                    print(f\"Ya se encuentra un '{self.tree[0][0]}' en la copa del arbol\")\n\n            case _:\n                print(f\"Comando ({command}) invalido.\")\n\n    def balls(self, command: str):\n        # Cada ves que se llama al comando se coloca o quita 2 bolas si o si\n        # Validar el comando de \"on\" o \"off\".\n        match command:\n            case \"on\":\n                if not len(self.null_position) >= 2:\n                    print(\"No hay espacio para colocar las bolas\")\n                    return\n                position = random.sample(sorted(self.null_position), k=2)\n                for element in position:\n                    self.tree[element[0]][element[1]] = 'o'\n                    self.null_position.discard(element)\n                    self.balls_position.add(element)\n                print( f\"Se han añadido 2 bolas al arbol!\")\n            case \"off\":\n                if not len(self.balls_position) >= 2:\n                    print(\"No hay bolas para sacar.\")\n                    return\n                position = random.sample(sorted(self.balls_position), k=2)\n                for element in position:\n                    self.tree[element[0]][element[1]] = '*'\n                    self.balls_position.discard(element)\n                    self.balls_position.add(element)\n                print(f\"Se han eliminado 2 bolas al arbol!\")\n            case _:\n                print(f\"Instruccion: '{command}' invalida!\")\n                return\n\n    def light(self, command: str):\n        # Cada ves que se llama al comando se coloca o quita 3 luces si o si\n        # Validar el comando de \"on\" o \"off\".\n        match command:\n            case \"on\":\n                if not len(self.null_position) >= 3:\n                    print(\"No hay espacio para colocar las luces\")\n                    return\n                position = random.sample(sorted(self.null_position), k=3)\n                for element in position:\n                    self.tree[element[0]][element[1]] = '+'\n                    self.null_position.discard(element)\n                    self.lights_position.add(element)\n                print( f\"Se han añadido 3 luces al arbol!\")\n            case \"off\":\n                if not len(self.lights_position) >= 3:\n                    print(\"No hay luces para sacar.\")\n                    return\n                position = random.sample(sorted(self.lights_position), k=3)\n                for element in position:\n                    self.tree[element[0]][element[1]] = '*'\n                    self.lights_position.discard(element)\n                    self.lights_position.add(element)\n                print(f\"Se han eliminado 3 luces al arbol!\")\n            case _:\n                print(f\"Instruccion: {command} invalida!\")\n                return\n\n    def on_off(self):\n        if self.lights_position:\n            aux = next(iter(self.lights_position))\n            if self.tree[aux[0]][aux[1]] == \"+\":\n                condition = \"on\"\n            elif self.tree[aux[0]][aux[1]] == \"*\":\n                condition = \"off\"\n            else:\n                raise ValueError(\"Se ha corrompido el codigo\")\n        else:\n            print(\"No hay luces en el arbol\")\n            return\n        \n        match condition:\n            case \"on\":\n                for element in self.lights_position:\n                    self.tree[element[0]][element[1]] = \"*\"\n                print(\"Se apagaron las luces!\")\n            case \"off\":\n                for element in self.lights_position:\n                    self.tree[element[0]][element[1]] = \"+\"\n                print(\"Se encendieron las luces!\")\n\ndef selection():\n    print(\"Opciones disponibles para ejecutar: \")\n    print(\"1. Añadir o eliminar la estrella en la copa del arbol\")\n    print(\"2. Añadir o eliminar las bolas del arbol (de 2 en 2)\")\n    print(\"3. Añadir o eliminar las luces del arbol (de 3 en 3)\")\n    print(\"4. Apagar o enceder las luces\")\n    print(\"5. Salir\")\n    option = input(\"Opcion: \")\n    return option\n\ndef sub_selection():\n    print(\"Que quieres hacer:\")\n    print(\"1. Añadir\")\n    print(\"2. Eliminar\")\n    option = input(\"Accion: \")\n    return option\n\ndef main():\n    print(\"Bienvenido al arbol de navidad!\")\n    heigth = input(\"Ingrese la altura del arbol: \")\n    try:\n        heigth = int(heigth)\n        if heigth <= 0:\n            raise ValueError()\n    except:\n        print(\"Valor invalido. Debe ingresar un numero entero mayor que cero.\")\n    else:\n        christmas_tree = ChristmasTree(heigth)\n        while True:\n            christmas_tree.display_tree()\n            option = selection()\n            match option:\n                case \"1\":\n                    option2 = sub_selection()\n                    if option2 == \"1\":\n                        christmas_tree.star(\"on\")\n                    elif option2 == \"2\":\n                        christmas_tree.star(\"off\")\n                    else:\n                        print(\"Valor invalido\")\n                case \"2\":\n                    option2 = sub_selection()\n                    if option2 == \"1\":\n                        christmas_tree.balls(\"on\")\n                    elif option2 == \"2\":\n                        christmas_tree.balls(\"off\")\n                    else:\n                        print(\"Valor invalido\")\n                case \"3\":\n                    option2 = sub_selection()\n                    if option2 == \"1\":\n                        christmas_tree.light(\"on\")\n                    elif option2 == \"2\":\n                        christmas_tree.light(\"off\")\n                    else:\n                        print(\"Valor invalido\")\n                case \"4\":\n                    christmas_tree.on_off()\n                case \"5\":\n                    print(\"Saliendo...\\nFelices Fiestas! Nos vemos!\")\n                    break\n                case _:\n                    print(\"Valor invalido...\")\n\nif __name__ == \"__main__\":\n    main()"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/python/JesusWay69.py",
    "content": "import os, platform, random\n\nif (platform.platform().startswith(\"macOS\") or platform.platform().startswith(\"Linux\")):\n    os.system('clear')\nelse:\n    os.system('cls')\n\n\n\"\"\" * EJERCICIO:\n * ¡Ha comenzado diciembre! Es hora de montar nuestro\n * árbol de Navidad...\n *\n * Desarrolla un programa que cree un árbol de Navidad\n * con una altura dinámica definida por el usuario por terminal.\n *\n * Ejemplo de árbol de altura 5 (el tronco siempre será igual):\n *\n *     *\n *    ***\n *   *****\n *  *******\n * *********\n *    |||\n *    |||\n *\n * El usuario podrá seleccionar las siguientes acciones:\n * \n * - Añadir o eliminar la estrella en la copa del árbol (@)\n * - Añadir o eliminar bolas de dos en dos (o) aleatoriamente\n * - Añadir o eliminar luces de tres en tres (X) aleatoriamente\n * - Apagar (*) o encender (+) las luces (conservando su posición)\n * - Una luz y una bola no pueden estar en el mismo sitio\n *\n * Sólo puedes añadir una estrella, y tantas luces o bolas\n * como tengan cabida en el árbol. El programa debe notificar\n * cada una de las acciones (o por el contrario, cuando no\n * se pueda realizar alguna).\"\"\"\n\ndef create_tree(hight:int)->list:\n    if hight <= 3:\n        print(\"No se puede crear un árbol de menos de 4 alturas\")\n        return\n    tree = []\n    base = hight * 2 - 1\n    branch = 1\n    for i in range(hight):\n        tree.append([])\n        [tree[i].append(' ') for j in range(base // 2)]\n        [tree[i].append('*') for k in range(branch)]\n        [tree[i].append(' ') for l in range(base // 2)]\n        base -= 2\n        branch += 2\n    for m in range (1, 3):\n        tree.append([])\n        [tree[i + m].append(' ') for n in range(hight - 2)]\n        [tree[i + m].append('|') for o in range(3)]\n        [tree[i + m].append(' ') for p in range(hight - 2)]\n\n    return tree\n\ndef show_tree(tree:list):\n    if tree == None:\n        return\n    print()\n    for row in tree:\n        for column in row:\n            print(column, end='')\n        print()\n\ndef top_star(tree:list, switch:bool)->list:\n    if tree == None:\n        print(\"ERROR: Hay que crear un árbol antes de poder modificarlo (opción 1)\")\n        return\n    if switch:\n        star = ['@' if x == '*' else x for x in tree[0]]\n        print(\"\\n--- ESTRELLA AÑADIDA ---\")\n    else:\n        star = ['*' if x == '@' else x for x in tree[0]]\n        print(\"\\n--- ESTRELLA ELIMINADA ---\")\n    tree[0] = star\n    return tree\n\ndef add_balls(tree:list)->list:\n    if tree == None:\n        print(\"ERROR: Hay que crear un árbol antes de poder modificarlo (opción 1)\")\n        return\n    i=0\n    while i !=2:\n        branch = random.randint(1, len(tree)-3)\n        ball = random.randint(0, len(tree[branch]))\n        if tree[branch][ball-1] != '*':\n            continue\n        else:\n            tree[branch][ball-1] = 'o'\n            i+=1\n    print(\"\\n--- SE AÑADEN 2 BOLAS DE ADORNO ---\")\n    return tree\n\ndef remove_balls(tree:list):\n    if tree == None:\n        print(\"ERROR: Hay que crear un árbol antes de poder modificarlo (opción 1)\")\n        return\n    for row in range(1, len(tree)-2):\n        for column in range(len(tree[row])):\n            if tree[row][column] == 'o':\n                tree[row][column] = '*'\n    print(\"\\n--- BOLAS DE ADORNO ELIMINADAS ---\")\n    return tree\n\ndef add_ligths(tree:list)->tuple:\n    if tree == None:\n        print(\"ERROR: Hay que crear un árbol antes de poder modificarlo (opción 1)\")\n        return None, None\n    i=0\n    lights_position = []\n    while i !=3:\n        branch = random.randint(1, len(tree)-3)\n        light = random.randint(0, len(tree[branch]))\n        if tree[branch][light-1] != '*':\n            continue\n        else:\n            tree[branch][light-1] = 'X'\n            lights_position.append(branch)\n            lights_position.append(light-1)\n            i+=1\n    print(\"\\n--- AÑADIDAS 3 LUCES ENCENDIDAS AL ÁRBOL ---\")\n    return tree, lights_position\n\ndef turn_on_lights(tree:list, coordinates:list)->list:\n    if tree == None:\n        print(\"ERROR: Hay que crear un árbol antes de poder modificarlo (opción 1)\")\n        return\n    for pos in coordinates:\n        tree[pos[0]][pos[1]], tree[pos[2]][pos[3]], tree[pos[4]][pos[5]] = 'X', 'X', 'X'\n    print(\"\\n--- TODAS LAS LUCES ENCENDIDAS ---\")\n    return tree\n\ndef turn_off_lights(tree:list)->list:\n    if tree == None:\n        print(\"ERROR: Hay que crear un árbol antes de poder modificarlo (opción 1)\")\n        return\n    for row in range(1, len(tree)-2):\n        for column in range(len(tree[row])):\n            if tree[row][column] == 'X':\n                tree[row][column] = '*'\n    print(\"\\n--- TODAS LAS LUCES APAGADAS ---\")\n    return tree\n\ncoordinates = []\ntree = None\nwhile True:\n    print(\"\"\"\n          \n    1- Crear árbol\n    2- Añadir estrella \n    3- Eliminar estrella \n    4- Añadir 2 bolas aleatoriamente\n    5- Quitar todas las bolas\n    6- Añadir 3 luces aleatoriamente \n    7- Encender las luces\n    8- Apagar las luces\n          \n    \"\"\")\n    option = input(\"Selecciona una opción del 1 al 6 (enter para salir): \") \n    \n    match option:\n        case \"1\":\n            hight = input(\"Indroduzca la altura del árbol a crear: \")\n            if not hight.isdigit():\n                print(\"ERROR: la altura del árbol debe ser un valor numérico\")\n                continue\n            tree = create_tree(int(hight))\n            print(f\"--- ARBOL DE {hight} ALTURAS CREADO ---\")\n            show_tree(tree)\n        case \"2\":\n            show_tree(top_star(tree, True))\n        case \"3\":           \n            show_tree(top_star(tree, False))\n        case \"4\":           \n            show_tree(add_balls(tree))\n        case \"5\":            \n            show_tree(remove_balls(tree))\n        case \"6\":          \n            tree, position = add_ligths(tree)\n            coordinates.append(position)\n            show_tree(tree)\n        case \"7\":       \n            show_tree(turn_on_lights(tree, coordinates))\n        case \"8\":        \n            show_tree(turn_off_lights(tree))\n        case \"\":\n            break\n        case _:\n            print(\"ERROR: sólo se pueden introducir números del 1 al 8 o enter para salir\")\n\n\n"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/python/Nicojsuarez2.py",
    "content": "# #48 ÁRBOL DE NAVIDAD\n> #### Dificultad: Media | Publicación: 02/12/24 | Corrección: 09/12/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * ¡Ha comenzado diciembre! Es hora de montar nuestro\n * árbol de Navidad...\n * \n * Desarrolla un programa que cree un árbol de Navidad\n * con una altura dinámica definida por el usuario por terminal.\n * \n * Ejemplo de árbol de altura 5 (el tronco siempre será igual):\n * \n *     *\n *    ***\n *   *****\n *  *******\n * *********\n *    |||\n *    |||\n *\n * El usuario podrá seleccionar las siguientes acciones:\n * \n * - Añadir o eliminar la estrella en la copa del árbol (@)\n * - Añadir o eliminar bolas de dos en dos (o) aleatoriamente\n * - Añadir o eliminar luces de tres en tres (+) aleatoriamente\n * - Apagar (*) o encender (+) las luces (conservando su posición)\n * - Una luz y una bola no pueden estar en el mismo sitio\n *\n * Sólo puedes añadir una estrella, y tantas luces o bolas\n * como tengan cabida en el árbol. El programa debe notificar\n * cada una de las acciones (o por el contrario, cuando no\n * se pueda realizar alguna).\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/python/cdryampi.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * ¡Ha comenzado diciembre! Es hora de montar nuestro\n#  * árbol de Navidad...\n#  * \n#  * Desarrolla un programa que cree un árbol de Navidad\n#  * con una altura dinámica definida por el usuario por terminal.\n#  * \n#  * Ejemplo de árbol de altura 5 (el tronco siempre será igual):\n#  * \n#  *     *\n#  *    ***\n#  *   *****\n#  *  *******\n#  * *********\n#  *    |||\n#  *    |||\n#  *\n#  * El usuario podrá seleccionar las siguientes acciones:\n#  * \n#  * - Añadir o eliminar la estrella en la copa del árbol (@)\n#  * - Añadir o eliminar bolas de dos en dos (o) aleatoriamente\n#  * - Añadir o eliminar luces de tres en tres (+) aleatoriamente\n#  * - Apagar (*) o encender (+) las luces (conservando su posición)\n#  * - Una luz y una bola no pueden estar en el mismo sitio\n#  *\n#  * Sólo puedes añadir una estrella, y tantas luces o bolas\n#  * como tengan cabida en el árbol. El programa debe notificar\n#  * cada una de las acciones (o por el contrario, cuando no\n#  * se pueda realizar alguna).\n#  */\nimport random\n\ndef gen_arbol(altura:int):\n    base_arbol = [[\" \" for _ in range(2*altura-1)] for _ in range(altura)]\n    for fila in range(altura):\n        num_sim = 2 * fila + 1\n        inicio = (2*altura-1-num_sim) // 2\n        fin =inicio + num_sim\n        for col in range(inicio, fin):\n            base_arbol[fila][col] = '*'\n    return base_arbol\n\ndef imprimir_arbol(arbol)-> None:\n    ancho_maximo = len(arbol[-1]) * 2\n    arbol_str = ''\n    for fila in arbol:\n        aux_str= ''.join(fila)\n        arbol_str += f'{aux_str}'.center(ancho_maximo)\n        arbol_str +='\\n'\n    \n    arbol_str += '|||'.center(ancho_maximo)\n    arbol_str += '\\n'\n    arbol_str += '|||'.center(ancho_maximo)\n    print(arbol_str)\n\n\ndef encender_luces_o_apagar(arbol:list, simbolo_origen:str, simbolo_destino:str)->list:\n    posiciones_libres = [\n        (i, j) for i, fila in enumerate(arbol) for j, celda in enumerate(fila) if celda == f\"{simbolo_origen}\"\n    ]\n\n    if len(posiciones_libres) > 3:\n        print(\"Se necesitan añadir más luces para poder encenderlas\")\n        return arbol\n    for i,j in posiciones_libres:\n        arbol[i][j] = simbolo_destino\n\n    if simbolo_destino == '(*)':\n        print(\"Se han encendido todas las luces\")\n    else:\n        print(\"Se han apagado todas las luces.\")\n    return arbol\n\ndef agregar_adornos_o_quitar(simbolo_origen:str, simbolo_final:str, numero_simbolos:int, arbol: list)-> list:\n    # Buscar todas las posiciones libres (fila, columna)\n    posiciones_libres = [\n        (i, j) for i, fila in enumerate(arbol) for j, celda in enumerate(fila) if celda == f\"{simbolo_origen}\"\n    ]\n\n    # Verificar si hay suficientes espacios para quitar 2 bolas\n    if len(posiciones_libres) < numero_simbolos:\n        msg = 'No podemos quitar o poner más {adornos}.'\n        match simbolo_final:\n            case \"(o)\":\n                msg = msg.format(adornos = \"bolas\")\n            case \"(+)\":\n                msg = msg.format(adornos = \"luces\")\n            case \"(*)\":\n                msg = msg.format(adornos = \"luces\")\n            case _:\n                print(\"Valor no encontrado o no válido\")\n                return\n        print(msg)\n        return arbol\n\n    # Seleccionar dos posiciones aleatorias\n    posiciones_seleccionadas = random.sample(posiciones_libres, numero_simbolos)\n\n    # Colocar las bolas en las posiciones seleccionadas\n    for fila, col in posiciones_seleccionadas:\n        arbol[fila][col] = f\"{simbolo_final}\"\n    \n    return arbol\n\n\ndef agregar_copa(arbol):\n    if next((copa for copa in arbol[0] if copa == '@'), None) == None:\n        for index, col in enumerate(arbol[0]):\n            if col == '*':\n                arbol[0][index] = '@'\n        print('Haz añadido una estrella al árbol.')\n    else:\n        print(\"Ya tenemos una copa en el árbol.\")\n\n    return arbol\n\nif __name__ == '__main__':\n    # Generar el arbol del tamaño básico\n    arbol = gen_arbol(15)\n    arbol = agregar_copa(arbol)\n    arbol = agregar_adornos_o_quitar(simbolo_origen = '*', simbolo_final = '(o)', numero_simbolos = 2, arbol = arbol)\n    arbol = agregar_adornos_o_quitar(simbolo_origen = '*', simbolo_final = '(+)', numero_simbolos = 3, arbol = arbol)\n    arbol = encender_luces_o_apagar(arbol = arbol, simbolo_origen = '(+)', simbolo_destino = '(*)')\n    imprimir_arbol(arbol)\n"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/python/davidrguez98.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * ¡Ha comenzado diciembre! Es hora de montar nuestro\n * árbol de Navidad...\n * \n * Desarrolla un programa que cree un árbol de Navidad\n * con una altura dinámica definida por el usuario por terminal.\n * \n * Ejemplo de árbol de altura 5 (el tronco siempre será igual):\n * \n *     *\n *    ***\n *   *****\n *  *******\n * *********\n *    |||\n *    |||\n *\n * El usuario podrá seleccionar las siguientes acciones:\n * \n * - Añadir o eliminar la estrella en la copa del árbol (@)\n * - Añadir o eliminar bolas de dos en dos (o) aleatoriamente\n * - Añadir o eliminar luces de tres en tres (+) aleatoriamente\n * - Apagar (*) o encender (+) las luces (conservando su posición)\n * - Una luz y una bola no pueden estar en el mismo sitio\n *\n * Sólo puedes añadir una estrella, y tantas luces o bolas\n * como tengan cabida en el árbol. El programa debe notificar\n * cada una de las acciones (o por el contrario, cuando no\n * se pueda realizar alguna).\n */ \"\"\"\n\n\nimport random\n\nclass ChristmasTree:\n\n    def __init__(self, height: int):\n\n        self.height = height\n        self.tree = [\n            [\" \" for _ in range(2 * height - 1)]\n            for _ in range(height)\n             \n        ]\n\n        for i in range(height):\n            for j in range(height - i - 1, height + i):\n                self.tree[i][j] = \"*\"\n\n        self.trunk = [\n            [\" \" for _ in range(2 * height - 1)]\n            for _ in range(2)\n        ]\n\n        for i in range(2):\n            for j in range(height - 2, height + 1):\n                self.trunk[i][j] = \"|\"\n\n        self.star = False\n        self.balls = []\n        self.lights = []\n        self.lights_on = False\n\n    def display_tree(self):\n\n        for index, row in enumerate(self.tree):\n            if index == 0 and self.star:\n                print(\"\".join(row).replace(\"*\", \"@\"))\n            else:\n                print(\"\".join(row))\n\n        for row in self.trunk:\n            print(\"\".join(row))\n\n    def add_star(self):\n        if self.star:\n            print(\"Ya existe una estrella en el árbol.\")\n        else:\n            self.star = True\n            print(\"Se ha añadido la estrella en el árbol.\")\n\n    def remove_star(self):\n        if not self.star:\n            print(\"No existe una estrella en el árbol para quitar.\")\n        else:\n            self.star = False\n            print(\"Se ha eliminado la estrella del árbol.\")\n\n    def add_balls(self):\n        \n        available = self.available()\n\n        if len(available) < 2:\n            print(\"No hay espacio para añadir más bolas.\")\n        else:\n            selected = random.sample(available, 2)\n            for i, j in selected:\n                self.tree[i][j] = \"o\"\n                self.balls.append((i, j))\n            print(\"Se han añadido dos bolas al árbol.\")\n\n    def remove_balls(self):\n        \n        if len(self.balls) < 2:\n            print(\"No hay suficientes bolas para quitar.\")\n        else:\n            selected = random.sample(self.balls, 2)\n            for i, j in selected:\n                self.tree[i][j] = \"*\"\n                self.balls.remove((i, j))\n            print(\"Se han eliminado dos bolas del árbol.\")\n\n    def add_lights(self):\n        \n        available = self.available()\n\n        if len(available) < 3:\n            print(\"No hay espacio para añadir más luces.\")\n        else:\n            selected = random.sample(available, 3)\n            for i, j in selected:\n                self.tree[i][j] = \"+\" if self.lights_on else \"*\"\n                self.lights.append((i, j))\n            print(\"Se han añadido tres luces al árbol.\")\n\n    def remove_lights(self):\n        \n        if len(self.lights) < 3:\n            print(\"No hay suficientes luces para quitar.\")\n        else:\n            selected = random.sample(self.lights, 3)\n            for i, j in selected:\n                self.tree[i][j] = \"*\"\n                self.lights.remove((i, j))\n            print(\"Se han eliminado tres luces del árbol.\")\n\n    def toggle_lights(self, turn_on):\n        \n        if not self.lights:\n            print(\"No hay luces en el árbol.\")\n        \n        self.lights_on = turn_on\n        for i, j in self.lights:\n            self.tree[i][j] = \"+\" if turn_on else \"*\"\n        print(f\"Las luces fueron {'encendidas' if turn_on else 'apagadas'}.\")\n\n    def available(self):\n\n        available =  [(i, j) for i in range(1, self.height) for j in range(self.height - i - 1, self.height + i) if self.tree[i][j] == \"*\"]\n\n        if not self.lights_on:\n            for i, j in self.lights:\n                available.remove((i, j))\n        return available\n\n\n\n\nheight = input(\"Introduce la altura del árbol: \")\n\nif height.isdigit() and int(height) > 0:\n\n    tree = ChristmasTree(int(height))\n\n    while True:\n\n        tree.display_tree()\n\n        print(\"\\nAcciones:\")\n        print(\"1. Añadir estrella\")\n        print(\"2. Quitar estrella\")\n        print(\"3. Añadir bolas\")\n        print(\"4. Quitar bolas\")\n        print(\"5. Añadir luces\")\n        print(\"6. Quitar luces\")\n        print(\"7. Encender luces\")\n        print(\"8. Apagar luces\")\n        print(\"9. Salir\")\n\n        action = input(\"Selecciona una acción: \")\n\n        match action:\n            case \"1\":\n                tree.add_star()\n            case \"2\":\n                tree.remove_star()\n            case \"3\":\n                tree.add_balls()\n            case \"4\":\n                tree.remove_balls()\n            case \"5\":\n                tree.add_lights()\n            case \"6\":\n                tree.remove_lights()\n            case \"7\":\n                tree.toggle_lights(True)\n            case \"8\":\n                tree.toggle_lights(False)\n\n            case \"9\":\n                print(\"Saliendo del programa.\")\n                break\n            case _:\n                print(\"Respuesta no válida. Seleccione un número del 1 al 9.\")\n\nelse:\n    print(f\"Altura {height} no válida.\")"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/python/duendeintemporal.py",
    "content": "#48 { Retos para Programadores } ARBOL DE NAVIDAD \n\n# Bibliography reference:\n# I use GPT as a reference and sometimes to correct or generate proper comments.\n\n\"\"\"\n * EJERCICIO:\n * ¡Ha comenzado diciembre! Es hora de montar nuestro\n * árbol de Navidad...\n *\n * Desarrolla un programa que cree un árbol de Navidad\n * con una altura dinámica definida por el usuario por terminal.\n *\n * Ejemplo de árbol de altura 5 (el tronco siempre será igual):\n *\n *     *\n *    ***\n *   *****\n *  *******\n * *********\n *    |||\n *    |||\n *\n * El usuario podrá seleccionar las siguientes acciones:\n * \n * - Añadir o eliminar la estrella en la copa del árbol (@)\n * - Añadir o eliminar bolas de dos en dos (o) aleatoriamente\n * - Añadir o eliminar luces de tres en tres (+) aleatoriamente\n * - Apagar (*) o encender (+) las luces (conservando su posición)\n * - Una luz y una bola no pueden estar en el mismo sitio\n *\n * Sólo puedes añadir una estrella, y tantas luces o bolas\n * como tengan cabida en el árbol. El programa debe notificar\n * cada una de las acciones (o por el contrario, cuando no\n * se pueda realizar alguna).\n\n\"\"\"\n\nlog = print\n\nimport random\n\ndef create_tree(tree_height):\n    tree = []\n    for i in range(tree_height):\n        row = \" \" * (tree_height - i - 1) + \"*\" * (2 * i + 1)\n        tree.append(row)\n    \n    # Center the trunk based on the maximum width of the tree\n    trunk_width = 3  # Width of the trunk\n    trunk_space = (2 * tree_height - 1 - trunk_width) // 2  # Calculate spaces to center the trunk\n    tree.append(\" \" * trunk_space + \"|||\")\n    tree.append(\" \" * trunk_space + \"|||\")\n    \n    return tree\n\ndef add_star(tree, tree_height, star):\n    if not star:\n        tree[0] = \" \" * (tree_height - 1) + \"@\"\n        star = True\n        log(\"Star added to the tree.\")\n    else:\n        log(\"There is already a star on the tree.\")\n    return star\n\ndef remove_star(tree, tree_height, star):\n    if star:\n        tree[0] = \" \" * (tree_height - 1) + \"*\"\n        star = False\n        log(\"Star removed from the tree.\")\n    else:\n        log(\"There is no star on the tree.\")\n    return star\n\ndef add_lights(tree, tree_height, lights):\n    max_lights = tree_height * 3\n    if len(lights) >= max_lights:\n        print(\"The tree already has the maximum number of lights.\")\n        return\n\n    num_lights = random.randint(1, max_lights - len(lights))\n    for _ in range(num_lights):\n        row = random.randint(0, tree_height - 1)\n        col = random.randint(0, 2 * row)\n        if tree[row][col] == \"*\" and f\"{row},{col}\" not in lights:\n            tree[row] = tree[row][:col] + \"+\" + tree[row][col + 1:]\n            lights.append(f\"{row},{col}\")\n            print(\"Lights added to the tree.\")\n\n\ndef remove_lights(tree, lights):\n    if not lights:\n        log(\"There are no lights on the tree.\")\n        return\n\n    num_lights = random.randint(1, max(1, len(lights) // 3))\n    for _ in range(num_lights):\n        index = random.randint(0, len(lights) - 1)\n        row, col = map(int, lights[index].split(\",\"))\n        tree[row] = tree[row][:col] + \"*\" + tree[row][col + 1:]\n        lights.pop(index)\n        log(\"Lights removed from the tree.\")\n\ndef add_ornaments(tree, tree_height, lights, ornaments):\n    num_ornaments = random.randint(1, max(0, tree_height * 3 - len(ornaments)))\n    for _ in range(num_ornaments):\n        row = random.randint(0, tree_height - 1)\n        col = random.randint(0, 2 * row)\n        if tree[row][col] == \"*\" and f\"{row},{col}\" not in lights:\n            tree[row] = tree[row][:col] + \"o\" + tree[row][col + 1:]\n            ornaments.append(f\"{row},{col}\")\n            log(\"Ornaments added to the tree.\")\n\ndef toggle_lights(tree, lights):\n    for light in lights:\n        row, col = map(int, light.split(\",\"))\n        if tree[row][col] == \"+\":\n            tree[row] = tree[row][:col] + \"*\" + tree[row][col + 1:]\n        else:\n            tree[row] = tree[row][:col] + \"+\" + tree[row][col + 1:]\n    log(\"Lights toggled.\")\n\ndef main():\n    tree_height = int(input('Enter the height of the Christmas tree (between 3 and 20): '))\n    \n    if tree_height < 3 or tree_height > 20:\n        log('\\nInvalid tree height. Please enter a number between 3 and 20.\\n')\n        return\n\n    tree = create_tree(tree_height)\n    star = False\n    lights = []\n    ornaments = []\n\n    log('\\n     Merry Christmas!\\n')\n    log('\\n'.join(tree))\n    log('\\nCongratulations! Enjoy your Christmas Tree.\\n')\n    \n    while True:\n        log('Now you can decorate your tree as you prefer. Choose an option below:\\n')\n        log('1. Add Star')\n        log('2. Remove Star')\n        log('3. Add Lights')\n        log('4. Remove Lights')\n        log('5. Add Ornaments')\n        log('6. Toggle Lights')\n        log('7. Exit')\n\n        option = input('Type the Option Number: ')\n        if option == '1':\n            star = add_star(tree, tree_height, star)\n        elif option == '2':\n            star = remove_star(tree, star)\n        elif option == '3':\n            add_lights(tree, tree_height, lights)\n        elif option == '4':\n            remove_lights(tree, tree_height, star)\n        elif option == '5':\n            add_ornaments(tree, tree_height, lights, ornaments)\n        elif option == '6':\n            toggle_lights(tree, lights)\n        elif option == '7':\n            log('\\nGoodbye! Merry Christmas!')\n            break\n        else:\n            log('\\nInvalid Option. Please try again.\\n')\n\n        log('\\n'.join(tree))  # Print the current state of the tree after each action\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/python/edaagapu.py",
    "content": "# EJERCICIO:\n# ¡Ha comenzado diciembre! Es hora de montar nuestro\n# árbol de Navidad...\n# \n# Desarrolla un programa que cree un árbol de Navidad\n# con una altura dinámica definida por el usuario por terminal.\n# \n# Ejemplo de árbol de altura 5 (el tronco siempre será igual):\n# \n#     *\n#    ***\n#   *****\n#  *******\n# *********\n#    |||\n#    |||\n# \n# El usuario podrá seleccionar las siguientes acciones:\n# \n# - Añadir o eliminar la estrella en la copa del árbol (@)\n# - Añadir o eliminar bolas de dos en dos (o) aleatoriamente\n# - Añadir o eliminar luces de tres en tres (+) aleatoriamente\n# - Apagar (*) o encender (+) las luces (conservando su posición)\n# - Una luz y una bola no pueden estar en el mismo sitio\n# \n# Sólo puedes añadir una estrella, y tantas luces o bolas\n# como tengan cabida en el árbol. El programa debe notificar\n# cada una de las acciones (o por el contrario, cuando no\n# se pueda realizar alguna).\n\n# 0 = ' ' Vacio\n# 1 = '*' Rama\n# 2 = 'o' Bola\n# 3 = '*' Luz apagada\n# 4 = '+' Luz encendida\n# 5 = '@' Estrella\n# 6 = '|' Tronco\n\nfrom random import randint\n\nclass ChristmasTree:\n  def __init__(self, height=3):\n    self.height = height\n    self.ml_holiday_tree = [[0 for _ in range(2*height -1 )]]\n    self.mapper_dict = ' ,*,o,*,+,@,|'.split(',')\n    self.md_holiday_tree = []\n\n    for i_row in range(1,height+1):\n      tree_cells = [1 for _ in range((2*i_row - 1))]\n      empty_cells = [0 for _ in range(height-i_row)]\n      self.ml_holiday_tree.append(empty_cells + tree_cells + empty_cells)\n\n    empty_cells = [0 for _ in range(height-2)]\n    base_cells = [6, 6, 6]\n    for _ in range(2):\n      self.ml_holiday_tree.append(empty_cells + base_cells + empty_cells)\n\n  def change_star(self, put):\n    self.ml_holiday_tree[0][self.height-1] = 5 if put else 0\n\n  def __change_object__(self, put, obj, quantity):\n    flag = 0\n    while not put and flag < quantity:\n      options = []\n      for row in self.ml_holiday_tree[1:-2]:\n        i_row = self.ml_holiday_tree.index(row)\n        if obj in row:\n          options.extend([(i_row, index) for index in range(len(row)) if row[index] == obj])\n      \n      if 0 <= len(options) <= quantity:\n        for i_row, i_cell in options:\n          self.ml_holiday_tree[i_row, i_cell] = 1\n        flag = quantity + 1\n      \n      if len(options) > quantity:\n        while flag < quantity:\n          i_row, i_cell = options.pop(randint(0, len(options)-1))\n          self.ml_holiday_tree[i_row][i_cell] = 1\n          flag+=1\n  \n    while flag < quantity and put:\n      i_row = randint(0, len(self.ml_holiday_tree)-1)\n      i_cell = randint(0, len(self.ml_holiday_tree[i_row])-1)\n      if self.ml_holiday_tree[i_row][i_cell] == 1:\n        self.ml_holiday_tree[i_row][i_cell] = obj\n        flag+=1\n\n  def change_lights(self, put):\n    self.__change_object__(put, 4, 3)\n\n  def change_balls(self, put):\n    self.__change_object__(put, 2, 2)\n\n  def display(self):\n    print('\\n'.join(\n      [''.join(\n        [self.mapper_dict[cell] for cell in row]\n      ) for row in self.ml_holiday_tree if max(row) > 0]\n    ))\n    print()\n  \n  def turn_on_lights(self):\n    for i_row in range(len(self.ml_holiday_tree)):\n      self.ml_holiday_tree[i_row] = [4 if value == 3 else value for value in self.ml_holiday_tree[i_row]]\n      \n  def turn_off_lights(self):\n    for i_row in range(len(self.ml_holiday_tree)):\n      self.ml_holiday_tree[i_row] = [3 if value == 4 else value for value in self.ml_holiday_tree[i_row]]\n\n\nif __name__ == '__main__':\n  menu_list = [\n    'Terminar ejecución', 'Mostrar árbol de navidad', 'Agregar luces', 'Quitar luces',\n    'Encender luces', 'Apagar luces', 'Agregar bolas navideñas', 'Quitar bolas navideñas', \n    'Agregar estrella', 'Quitar estrella'\n  ]\n\n  height = 0\n  while height <= 1:\n    try:\n      height = int(input('¿Cuál será la altura del árbol?: '))\n      if 1 >= height:\n        raise Exception()\n    except:\n      print('Dato incorrecto, por favor ingresar un número positivo mayor a 1.')\n  \n  tree = ChristmasTree(height)\n  tree.display()\n\n  option = 1\n\n  while option:\n    menu_string = ['Ingresa la opción según corresponda:']\n    menu_string.extend([f'({menu_list.index(menu_option)}) {menu_option}' for menu_option in menu_list[1:]])\n    menu_string.append('-'*25)\n    menu_string.append(f'(0) {menu_list[0]}')\n    menu_string.append('-'*25)\n    menu_string.append('Escribe una opción: ')\n\n    menu = '\\n'.join(menu_string)\n    try:\n      option = int(input(menu))\n      match option:\n        case 0:\n          continue\n        case 1:\n          tree.display()\n        case 2:\n          tree.change_lights(True)\n          tree.display()\n        case 3:\n          tree.change_lights(False)\n          tree.display()\n        case 4:\n          tree.turn_on_lights()\n          tree.display()\n        case 5:\n          tree.turn_off_lights()\n          tree.display()\n        case 6:\n          tree.change_balls(True)\n          tree.display()\n        case 7:\n          tree.change_balls(False)\n          tree.display()\n        case 8:\n          tree.change_star(True)\n          tree.display()\n        case 9:\n          tree.change_star(False)\n          tree.display()\n\n        case _:\n          raise Exception()\n    except:\n      print('Dato incorrecto. Intente nuevamente.')"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/python/giulianovfz.py",
    "content": "# reto de programación n°48\n# importamos random para agregar,eliminar bolas y luces\n\"\"\"\n * EJERCICIO:\n * ¡Ha comenzado diciembre! Es hora de montar nuestro\n * árbol de Navidad...\n *\n * Desarrolla un programa que cree un árbol de Navidad\n * con una altura dinámica definida por el usuario por terminal.\n *\n * Ejemplo de árbol de altura 5 (el tronco siempre será igual):\n *\n *     *\n *    ***\n *   *****\n *  *******\n * *********\n *    |||\n *    |||\n *\n * El usuario podrá seleccionar las siguientes acciones:\n * \n * - Añadir o eliminar la estrella en la copa del árbol (@)\n * - Añadir o eliminar bolas de dos en dos (o) aleatoriamente\n * - Añadir o eliminar luces de tres en tres (+) aleatoriamente\n * - Apagar (*) o encender (+) las luces (conservando su posición)\n * - Una luz y una bola no pueden estar en el mismo sitio\n *\n * Sólo puedes añadir una estrella, y tantas luces o bolas\n * como tengan cabida en el árbol. El programa debe notificar\n * cada una de las acciones (o por el contrario, cuando no\n * se pueda realizar alguna).\n\"\"\"\nimport random\n\n\nclass ArbolDeNavidad():\n\n    def __init__(self, h: int):\n        self.h = h\n        self.estrella = False\n\n        # ramas del árbol\n        for ciclo in range(0, h):\n            if ciclo == 0:\n                estrella = 1\n                espacio = h - 1\n                self.ramas = [[\" \"]*espacio + [\"*\"] + [\" \"]*espacio]\n\n            else:\n                estrella += 2\n                espacio -= 1\n                self.ramas.append([\" \"]*espacio + [\"*\"] *\n                                  estrella + [\" \"]*espacio)\n\n        # tronco\n        self.tronco = [[\" \"]*(h-2) + [\"|\"]*3 + [\" \"]*(h-2) for _ in range(2)]\n        self.luces = []\n        self.estado_luces = False\n\n    def imprimir(self):\n        # imprimir el árbol\n        for ciclo, fila in enumerate(self.ramas):\n            if ciclo == 0 and self.estrella:\n                print(\"\".join(fila).replace(\"*\", \"@\"))\n            else:\n                print(\"\".join(fila))\n\n        # imprimir el tronco\n        for f in self.tronco:\n            print(\"\".join(f))\n\n    def agregar_copa(self):\n        \"\"\"\n        Añadir la estrella en la copa del árbol (@)\n        \"\"\"\n        if self.estrella:\n            print('\\nYa colocaste la estrella en la copa del árbol\\n')\n        else:\n            self.estrella = True\n            print('\\nSe coloca la estrella en la copa del árbol\\n')\n\n    def quitar_copa(self):\n        \"\"\"\n        Eliminar la estrella en la copa del árbol (@)\n        \"\"\"\n        if not self.estrella:\n            print('\\nYa quitaste la estrella en la copa del árbol\\n')\n        else:\n            self.estrella = False\n            print('\\nSe quita la estrella en la copa del árbol\\n')\n\n    def agregar_bolas(self):\n        \"\"\"\n        Añadir bolas de dos en dos (o) aleatoriamente\n        \"\"\"\n        posiciones = self.disponible(\"*\")\n\n        if len(posiciones) >= 2:\n            print('\\nSe agregaron 2 bolas al árbol\\n')\n\n            selected = random.sample(posiciones, 2)\n            for ns, ms in selected:\n                self.ramas[ns][ms] = 'o'\n\n        else:\n            print('\\nNo hay suficiente espacio para agregar más bolas al árbol')\n\n    def quitar_bolas(self):\n        \"\"\"\n        Eliminar bolas de dos en dos (o) aleatoriamente\n        \"\"\"\n\n        posiciones = self.disponible(\"o\")\n\n        if len(posiciones) > 1:\n            print('\\nSe quitaron 2 bolas del árbol\\n')\n\n            selected = random.sample(posiciones, 2)\n            for ns, ms in selected:\n                self.ramas[ns][ms] = '*'\n        else:\n            print('\\nYa no se pueden quitar más bolas del árbol')\n\n    def agregar_luces(self):\n        \"\"\"\n        Añadir luces de tres en tres (+) aleatoriamente\n        \"\"\"\n\n        posiciones = self.disponible(\"*\")\n\n        if len(posiciones) > 2:\n            print('\\nSe agregaron 3 luces al árbol\\n')\n\n            selected = random.sample(posiciones, 3)\n            for ns, ms in selected:\n                if self.luces in posiciones:\n                    continue\n                else:\n                    self.ramas[ns][ms] = '+' if self.estado_luces else \"*\"\n                    self.luces.append((ns, ms))\n\n        else:\n            print('\\nNo hay espacio suficiente para agregar luces')\n\n    def eliminar_luces(self):\n        \"\"\"\n        Eliminar luces de tres en tres (+) aleatoriamente\n        \"\"\"\n\n        if len(self.luces) > 2:\n            print('\\nSe quitaron 3 luces del árbol\\n')\n\n            selected = random.sample(self.luces, 3)\n            for ns, ms in selected:\n                self.ramas[ns][ms] = '*'\n                self.luces.remove((ns, ms))\n\n        else:\n            print('\\nNo hay luces para quitar')\n\n    def interruptor_luces(self, estado):\n        \"\"\"\n        Apaga o enciende las luces del árbol\n        \"\"\"\n        self.estado_luces = estado\n\n        if len(self.luces) > 0:\n            for ns, ms in self.luces:\n                self.ramas[ns][ms] = '+' if self.estado_luces else \"*\"\n            print(\n                f'\\nLas luces se encuentran {'Encendidas' if self.estado_luces else 'Apagadas'}\\n')\n\n        else:\n            print('\\nPrimero debes agregar las luces al árbol para enceder o apagar')\n\n    def disponible(self, buscar: str):\n        posiciones = [(n, m) for n in range(1, self.h)\n                      for m in range(0, (self.h*2)-1) if self.ramas[n][m] == buscar]\n\n        if not self.estado_luces:\n            for n, m in self.luces:\n                posiciones.remove((n, m))\n\n        return posiciones\n\n\ndef definir_altura():\n\n    try:\n        altura = int(input('\\nIngresa la altura del arbol navideño: '))\n        print(f'\\nla altura ingresada es: {altura}\\n')\n        return altura\n\n    except ValueError:\n        print('\\nSólo puedes ingresar números\\n')\n        definir_altura()\n\n\ndef menu():\n\n    modificar = [\n        \"1. Añadir estrella\",\n        \"2. Quitar estrella\",\n        \"3. Añadir bolas\",\n        \"4. Quitar bolas\",\n        \"5. Añadir luces(debes encender las luces para ver las)\",\n        \"6. Quitar luces\",\n        \"7. Encender luces\",\n        \"8. Apagar luces\",\n        \"9. Salir\",\n    ]\n\n    h = definir_altura()\n\n    arbol = ArbolDeNavidad(h)\n\n    while True:\n\n        arbol.imprimir()\n\n        print('\\n')\n        for menus in modificar:\n            print(f'\\t{menus}')\n\n        try:\n            opcion_menu = int(input('\\nIngresa el número: '))\n\n        except ValueError:\n            opcion_menu = \"_\"\n\n        match opcion_menu:\n            case 1:\n                arbol.agregar_copa()\n            case 2:\n                arbol.quitar_copa()\n            case 3:\n                arbol.agregar_bolas()\n            case 4:\n                arbol.quitar_bolas()\n            case 5:\n                arbol.agregar_luces()\n            case 6:\n                arbol.eliminar_luces()\n            case 7:\n                arbol.interruptor_luces(True)\n            case 8:\n                arbol.interruptor_luces(False)\n            case 9:\n                print('\\n\\tFeliz Navidad\\n')\n                break\n            case _:\n                print(\"\\nOpción no encontrada, ingresa sólo los números del menú\\n\")\n\n\nif __name__ == '__main__':\n    menu()\n"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/python/hectorio23.py",
    "content": "# Autor: Héctor Adán\n# GitHub: https://github.com/hectorio23\n\nimport random\n\ndef draw_tree(tree):\n    for line in tree:\n        print(line)\n    print()\n\ndef initialize_tree(height, has_star):\n    tree = []\n\n    if has_star:\n        tree.append(\" \" * height + \"@\")\n\n    for i in range(height):\n        width = 2 * i + 1\n        row = \" \" * (height - i - 1) + \"*\" * width\n        tree.append(row)\n\n    trunk = \" \" * (height - 1) + \"|||\"\n    tree.append(trunk)\n    tree.append(trunk)\n\n    return tree\n\ndef toggle_star(tree, height, has_star):\n    has_star = not has_star\n    tree = initialize_tree(height, has_star)\n    print(\"Estrella\", \"añadida.\" if has_star else \"eliminada.\")\n    return tree, has_star\n\ndef add_or_remove(tree, height, symbol, count, add):\n    modifications = 0\n\n    for i in range(1, height + 1):\n        row = list(tree[i])\n        for j in range(len(row)):\n            if (add and row[j] == '*' and random.choice([True, False])) or (not add and row[j] == symbol):\n                row[j] = symbol if add else '*'\n                modifications += 1\n            if modifications == count:\n                break\n        tree[i] = \"\".join(row)\n        if modifications == count:\n            break\n\n    print(f\"{'Añadido' if add else 'Eliminado'} {modifications} de {symbol}.\")\n    return tree\n\ndef toggle_lights(tree, height, lights_on):\n    lights_on = not lights_on\n\n    for i in range(1, height + 1):\n        row = list(tree[i])\n        for j in range(len(row)):\n            if row[j] in ('*', '+'):\n                row[j] = '+' if lights_on else '*'\n        tree[i] = \"\".join(row)\n\n    print(\"Luces\", \"encendidas.\" if lights_on else \"apagadas.\")\n    return tree, lights_on\n\ndef main():\n    height = int(input(\"Ingresa la altura del árbol: \"))\n\n    has_star = True\n    lights_on = False\n\n    tree = initialize_tree(height, has_star)\n\n    while True:\n        draw_tree(tree)\n        option = input(\"Opciones: [estrella, bolas, luces, apagar, salir]: \").strip().lower()\n\n        if option == \"estrella\":\n            tree, has_star = toggle_star(tree, height, has_star)\n        elif option == \"bolas\":\n            tree = add_or_remove(tree, height, 'o', 2, True)\n        elif option == \"luces\":\n            tree = add_or_remove(tree, height, '+', 3, True)\n        elif option == \"apagar\":\n            tree, lights_on = toggle_lights(tree, height, lights_on)\n        elif option == \"salir\":\n            print(\"Gracias por decorar el árbol!\")\n            break\n        else:\n            print(\"Opción no válida.\")\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/python/hozlucas28.py",
    "content": "# pylint: disable=missing-module-docstring,missing-class-docstring,missing-function-docstring\n\nfrom abc import ABCMeta, abstractmethod\nfrom typing import Self\nfrom os import system\n\n# ---------------------------------------------------------------------------- #\n#                                    CLASSES                                   #\n# ---------------------------------------------------------------------------- #\n\n\nclass AbcChristmasTree(metaclass=ABCMeta):\n    @property\n    @abstractmethod\n    def height(self) -> int:\n        pass\n\n    @property\n    @abstractmethod\n    def tree(self) -> str:\n        pass\n\n    @abstractmethod\n    def add_balls(self, *, ball: str) -> Self:\n        pass\n\n    @abstractmethod\n    def add_lights(self, *, light: str) -> Self:\n        pass\n\n    @abstractmethod\n    def add_star(self, *, star: str) -> Self:\n        pass\n\n    @abstractmethod\n    def remove_balls(self, *, ball: str) -> Self:\n        pass\n\n    @abstractmethod\n    def remove_lights(self, *, light: str) -> Self:\n        pass\n\n    @abstractmethod\n    def remove_star(self, *, star: str) -> Self:\n        pass\n\n    @abstractmethod\n    def turn_off_lights(self, *, light_off: str) -> Self:\n        pass\n\n    @abstractmethod\n    def turn_on_lights(self, *, light_on: str) -> Self:\n        pass\n\n\nclass ChristmasTree(AbcChristmasTree):\n    __height: int\n    __tree: list[str]\n    __lights_indexes: list[list[int]]\n\n    def __init__(self, *, height: int) -> None:\n        tree: list[str] = []\n\n        for i in range(height):\n            branch_blank_spaces: str = \" \" * (height - i - 1) if height >= 2 else \" \"\n            tree.append(branch_blank_spaces + \"*\" * (i * 2 + 1))\n\n        trunk_blank_spaces: str = \" \" * (height - 2) if height >= 2 else \"\"\n        tree.append(trunk_blank_spaces + \"|||\")\n        tree.append(trunk_blank_spaces + \"|||\")\n\n        self.__height = height\n        self.__lights_indexes = []\n        self.__tree = tree\n\n    @property\n    def height(self) -> int:\n        return self.__height\n\n    @property\n    def tree(self) -> str:\n        return \"\\n\".join(self.__tree)\n\n    def add_balls(self, *, ball: str) -> Self:\n        for i in range(1, len(self.__tree) - 2):\n            branch: str = self.__tree[i]\n            counter: int = 0\n\n            new_branch: str = \"\"\n\n            for char in branch:\n                new_branch += ball if not (counter % 2) and char == \"*\" else char\n                counter += 1\n\n            self.__tree[i] = new_branch\n\n        return self\n\n    def add_lights(self, *, light: str) -> Self:\n        for i in range(1, len(self.__tree) - 1):\n            branch: str = self.__tree[i]\n            counter: int = 0\n\n            new_branch: str = \"\"\n\n            for j, char in enumerate(iterable=branch):\n                if counter % 2 and char == \"*\":\n                    new_branch += light\n                    self.__lights_indexes.append([i, j])\n                else:\n                    new_branch += char\n\n                counter += 1\n\n            self.__tree[i] = new_branch\n\n        return self\n\n    def add_star(self, *, star: str) -> Self:\n        self.__tree[0] = self.__tree[0].replace(\"*\", star, 1)\n        return self\n\n    def remove_balls(self, *, ball: str) -> Self:\n        for i in range(1, len(self.__tree) - 2):\n            self.__tree[i] = self.__tree[i].replace(ball, \"*\")\n\n        return self\n\n    def remove_lights(self, *, light: str) -> Self:\n        while len(self.__lights_indexes) != 0:\n            [branch, index] = self.__lights_indexes[0]\n\n            new_branch: str = \"\"\n\n            for j in range(len(self.__tree[branch])):\n                if j == index:\n                    new_branch += \"*\"\n                    self.__lights_indexes.pop(0)\n                    continue\n\n                new_branch += self.__tree[branch][j]\n\n            self.__tree[branch] = new_branch\n\n        return self\n\n    def remove_star(self, *, star: str) -> Self:\n        self.__tree[0] = self.__tree[0].replace(star, \"*\", 1)\n        return self\n\n    def turn_off_lights(self, *, light_off: str) -> Self:\n        for [branch, index] in self.__lights_indexes:\n            new_branch: str = \"\"\n\n            for j in range(len(self.__tree[branch])):\n                new_branch += light_off if j == index else self.__tree[branch][j]\n\n            self.__tree[branch] = new_branch\n\n        return self\n\n    def turn_on_lights(self, *, light_on: str) -> Self:\n        for [branch, index] in self.__lights_indexes:\n            new_branch: str = \"\"\n\n            for j in range(len(self.__tree[branch])):\n                new_branch += light_on if j == index else self.__tree[branch][j]\n\n            self.__tree[branch] = new_branch\n\n        return self\n\n\n# ---------------------------------------------------------------------------- #\n#                                     MAIN                                     #\n# ---------------------------------------------------------------------------- #\n\n\nuser_input: str = (input(\"> Enter the height of the christmas tree: \")).strip()\n\nchristmas_tree: AbcChristmasTree = ChristmasTree(height=int(user_input))\n\nsystem(command=\"clear\")\nprint(christmas_tree.tree)\n\nprint(\n    \"\\n> Available operations...\\n\\n\",\n    \"  1 - Add star.\\n\",\n    \"  2 - Remove star.\\n\",\n    \"  3 - Add balls.\\n\",\n    \"  4 - Remove balls.\\n\",\n    \"  5 - Add lights.\\n\",\n    \"  6 - Remove lights.\\n\",\n    \"  7 - Turn on lights.\\n\",\n    \"  8 - Turn off lights.\\n\",\n    \"  0 - Exit.\",\n)\n\nuser_input = (input(\"\\n> Enter an operation: \")).strip()\n\nwhile user_input != \"0\":\n    match user_input:\n        case \"1\":\n            christmas_tree.add_star(star=\"@\")\n\n            system(command=\"clear\")\n            print(christmas_tree.tree)\n\n        case \"2\":\n            christmas_tree.remove_star(star=\"@\")\n\n            system(command=\"clear\")\n            print(christmas_tree.tree)\n\n        case \"3\":\n            christmas_tree.add_balls(ball=\"o\")\n\n            system(command=\"clear\")\n            print(christmas_tree.tree)\n\n        case \"4\":\n            christmas_tree.remove_balls(ball=\"o\")\n\n            system(command=\"clear\")\n            print(christmas_tree.tree)\n\n        case \"5\":\n            christmas_tree.add_lights(light=\"+\")\n\n            system(command=\"clear\")\n            print(christmas_tree.tree)\n\n        case \"6\":\n            christmas_tree.remove_lights(light=\"*\")\n\n            system(command=\"clear\")\n            print(christmas_tree.tree)\n\n        case \"7\":\n            christmas_tree.turn_on_lights(light_on=\"+\")\n\n            system(command=\"clear\")\n            print(christmas_tree.tree)\n\n        case \"8\":\n            christmas_tree.turn_off_lights(light_off=\"*\")\n\n            system(command=\"clear\")\n            print(christmas_tree.tree)\n\n        case _:\n            print(\"\\n> Invalid operation! Try again...\")\n\n    print(\n        \"\\n> Available operations...\\n\\n\",\n        \"  1 - Add star.\\n\",\n        \"  2 - Remove star.\\n\",\n        \"  3 - Add balls.\\n\",\n        \"  4 - Remove balls.\\n\",\n        \"  5 - Add lights.\\n\",\n        \"  6 - Remove lights.\\n\",\n        \"  7 - Turn on lights.\\n\",\n        \"  8 - Turn off lights.\\n\",\n        \"  0 - Exit.\",\n    )\n\n    user_input = (input(\"\\n> Enter an operation: \")).strip()\n"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/python/idiegorojas.py",
    "content": "\"\"\"\n# 48 - Arbol de navidad\n\"\"\"\n# Desarrolla un programa que cree un árbol de Navidad\n# con una altura dinámica definida por el usuario por terminal. \n# Ejemplo de árbol de altura 5 (el tronco siempre será igual):\n\n#     *\n#    ***\n#   *****\n#  *******\n# *********\n#    |||\n#    |||\n\n# El usuario podrá seleccionar las siguientes acciones: \n    # Añadir o eliminar la estrella en la copa del árbol (@)\n    # Añadir o eliminar bolas de dos en dos (o) aleatoriamente\n    # Añadir o eliminar luces de tres en tres (+) aleatoriamente\n    # Apagar (*) o encender (+) las luces (conservando su posición)\n    # Una luz y una bola no pueden estar en el mismo sitio\n\n# Sólo puedes añadir una estrella, y tantas luces o bolas como tengan cabida en el árbol. El programa debe notificar cada una de las acciones (o por el contrario, cuando no se pueda realizar alguna).\n\nimport random\n\nclass ArbolNavidad:\n    def __init__(self, altura):\n        self.altura = altura\n        self.estrella = False  # Sin estrella inicialmente\n        self.luces = []        # Lista de tuplas (fila, columna, encendida)\n        self.bolas = []        # Lista de tuplas (fila, columna)\n    \n    def posicion_ocupada(self, fila, columna):\n        \"\"\"Comprobar si una posición ya tiene una decoración\"\"\"\n        if self.estrella and fila == 0 and columna == self.altura - 1:\n            return True\n        \n        for luz_fila, luz_col, _ in self.luces:\n            if luz_fila == fila and luz_col == columna:\n                return True\n                \n        for bola_fila, bola_col in self.bolas:\n            if bola_fila == fila and bola_col == columna:\n                return True\n                \n        return False\n    \n    def agregar_estrella(self):\n        \"\"\"Añadir una estrella a la copa del árbol\"\"\"\n        if self.estrella:\n            print(\"Ya hay una estrella en el árbol\")\n            return False\n        \n        self.estrella = True\n        print(\"Estrella añadida\")\n        return True\n        \n    def quitar_estrella(self):\n        \"\"\"Quitar la estrella de la copa del árbol\"\"\"\n        if not self.estrella:\n            print(\"No hay estrella para eliminar\")\n            return False\n            \n        self.estrella = False\n        print(\"Estrella eliminada\")\n        return True\n    \n    def agregar_bolas(self):\n        \"\"\"Añadir dos bolas aleatoriamente al árbol\"\"\"\n        posiciones_disponibles = []\n        \n        # Encontrar posiciones disponibles para bolas\n        for fila in range(self.altura):\n            ancho = 2 * fila + 1\n            for col in range(ancho):\n                col_real = col + (self.altura - fila - 1)\n                if not self.posicion_ocupada(fila, col_real):\n                    posiciones_disponibles.append((fila, col_real))\n        \n        if len(posiciones_disponibles) < 2:\n            print(\"No hay suficiente espacio para añadir más bolas\")\n            return False\n            \n        # Seleccionar dos posiciones aleatorias\n        posiciones = random.sample(posiciones_disponibles, 2)\n        self.bolas.extend(posiciones)\n        print(\"Dos bolas añadidas aleatoriamente\")\n        return True\n        \n    def quitar_bolas(self):\n        \"\"\"Quitar dos bolas aleatoriamente del árbol\"\"\"\n        if len(self.bolas) < 2:\n            print(f\"Solo hay {len(self.bolas)} bolas para eliminar\")\n            return False\n            \n        for _ in range(2):\n            if self.bolas:\n                posicion = random.choice(self.bolas)\n                self.bolas.remove(posicion)\n        \n        print(\"Dos bolas eliminadas aleatoriamente\")\n        return True\n    \n    def agregar_luces(self):\n        \"\"\"Añadir tres luces aleatoriamente al árbol\"\"\"\n        posiciones_disponibles = []\n        \n        # Encontrar posiciones disponibles para luces\n        for fila in range(self.altura):\n            ancho = 2 * fila + 1\n            for col in range(ancho):\n                col_real = col + (self.altura - fila - 1)\n                if not self.posicion_ocupada(fila, col_real):\n                    posiciones_disponibles.append((fila, col_real))\n        \n        if len(posiciones_disponibles) < 3:\n            print(\"No hay suficiente espacio para añadir más luces\")\n            return False\n            \n        # Seleccionar tres posiciones aleatorias\n        posiciones = random.sample(posiciones_disponibles, 3)\n        self.luces.extend([(fila, col, True) for fila, col in posiciones])  # Luces comienzan encendidas (+)\n        print(\"Tres luces añadidas aleatoriamente\")\n        return True\n        \n    def quitar_luces(self):\n        \"\"\"Quitar tres luces aleatoriamente del árbol\"\"\"\n        if len(self.luces) < 3:\n            print(f\"Solo hay {len(self.luces)} luces para eliminar\")\n            return False\n            \n        for _ in range(3):\n            if self.luces:\n                posicion = random.choice(self.luces)\n                self.luces.remove(posicion)\n        \n        print(\"Tres luces eliminadas aleatoriamente\")\n        return True\n    \n    def cambiar_luces(self, encender):\n        \"\"\"Encender o apagar las luces\"\"\"\n        if not self.luces:\n            print(\"No hay luces en el árbol\")\n            return False\n            \n        nuevo_estado = []\n        for fila, col, _ in self.luces:\n            nuevo_estado.append((fila, col, encender))\n            \n        self.luces = nuevo_estado\n        print(f\"Luces {'encendidas' if encender else 'apagadas'}\")\n        return True\n    \n    def dibujar(self):\n        \"\"\"Dibujar el árbol con todas las decoraciones\"\"\"\n        arbol = []\n        \n        # Generar la forma básica del árbol\n        for fila in range(self.altura):\n            linea = [' '] * (2 * self.altura - 1)\n            ancho = 2 * fila + 1\n            col_inicio = self.altura - fila - 1\n            \n            for col in range(ancho):\n                linea[col_inicio + col] = '*'\n                \n            arbol.append(linea)\n        \n        # Añadir el tronco\n        for _ in range(2):\n            linea = [' '] * (2 * self.altura - 1)\n            inicio_tronco = self.altura - 2\n            linea[inicio_tronco:inicio_tronco+3] = ['|', '|', '|']\n            arbol.append(linea)\n        \n        # Añadir estrella si está presente\n        if self.estrella:\n            arbol[0][self.altura - 1] = '@'\n        \n        # Añadir luces\n        for fila, col, encendida in self.luces:\n            if 0 <= fila < self.altura and 0 <= col < len(arbol[fila]):\n                arbol[fila][col] = '+' if encendida else '*'\n        \n        # Añadir bolas\n        for fila, col in self.bolas:\n            if 0 <= fila < self.altura and 0 <= col < len(arbol[fila]):\n                arbol[fila][col] = 'o'\n        \n        # Convertir a cadenas y devolver\n        return '\\n'.join([''.join(linea) for linea in arbol])\n\ndef main():\n    print(\"Bienvenido al generador de árboles de Navidad\")\n    \n    while True:\n        try:\n            altura = int(input(\"Introduzca la altura del árbol (3-20): \"))\n            if 3 <= altura <= 20:\n                break\n            print(\"La altura debe estar entre 3 y 20\")\n        except ValueError:\n            print(\"Por favor, introduzca un número válido\")\n    \n    arbol = ArbolNavidad(altura)\n    \n    while True:\n        print(\"\\n\" + arbol.dibujar() + \"\\n\")\n        print(\"Seleccione una acción:\")\n        print(\"1. Añadir estrella (@)\")\n        print(\"2. Eliminar estrella\")\n        print(\"3. Añadir bolas (o) aleatoriamente\")\n        print(\"4. Eliminar bolas aleatoriamente\")\n        print(\"5. Añadir luces (+) aleatoriamente\")\n        print(\"6. Eliminar luces aleatoriamente\")\n        print(\"7. Encender luces (+)\")\n        print(\"8. Apagar luces (*)\")\n        print(\"9. Salir\")\n        \n        opcion = input(\"Elección: \")\n        \n        if opcion == '1':\n            arbol.agregar_estrella()\n        elif opcion == '2':\n            arbol.quitar_estrella()\n        elif opcion == '3':\n            arbol.agregar_bolas()\n        elif opcion == '4':\n            arbol.quitar_bolas()\n        elif opcion == '5':\n            arbol.agregar_luces()\n        elif opcion == '6':\n            arbol.quitar_luces()\n        elif opcion == '7':\n            arbol.cambiar_luces(True)\n        elif opcion == '8':\n            arbol.cambiar_luces(False)\n        elif opcion == '9':\n            print(\"¡Feliz Navidad!\")\n            break\n        else:\n            print(\"Opción no válida\")\n\nif __name__ == \"__main__\":\n    main()"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/python/ignaciovihe.py",
    "content": "\"\"\"\n * EJERCICIO:\n * ¡Ha comenzado diciembre! Es hora de montar nuestro\n * árbol de Navidad...\n * \n * Desarrolla un programa que cree un árbol de Navidad\n * con una altura dinámica definida por el usuario por terminal.\n * \n * Ejemplo de árbol de altura 5 (el tronco siempre será igual):\n * \n *     *\n *    ***\n *   *****\n *  *******\n * *********\n *    |||\n *    |||\n *\n * El usuario podrá seleccionar las siguientes acciones:\n * \n * - Añadir o eliminar la estrella en la copa del árbol (@)\n * - Añadir o eliminar bolas de dos en dos (o) aleatoriamente\n * - Añadir o eliminar luces de tres en tres (+) aleatoriamente\n * - Apagar (*) o encender (+) las luces (conservando su posición)\n * - Una luz y una bola no pueden estar en el mismo sitio\n *\n * Sólo puedes añadir una estrella, y tantas luces o bolas\n * como tengan cabida en el árbol. El programa debe notificar\n * cada una de las acciones (o por el contrario, cuando no\n * se pueda realizar alguna).\n\"\"\"\nimport random\nimport os\n\nclass ChristmastTree:\n    def __init__(self, size: int) -> None:\n        self.size = size\n        self.branches = [\"*\"] * (size**2)\n        self.available_branches = (size ** 2) -1\n        self.trunk = \" \" * ((((size * 2) - 1) - 3) // 2) + \"|||\" + \" \" * ((((size * 2) - 1) - 3) // 2) + \"\\n\"\n        self.star = False\n        self.balls = []\n        self.lights = []\n        self.turned_on = False\n\nclass TreeRender:\n    def __init__(self, tree: ChristmastTree) -> None:\n        self.tree = tree\n\n    def display_tree(self):\n        for row in range(1, self.tree.size + 1):\n            row_start = 0\n            if row != 1:\n                row_start = (row-1) **2\n            actual_branch = self.tree.branches[row_start: (row ** 2)]\n            actual_branch = \"\".join(actual_branch)\n            print(actual_branch.center((self.tree.size * 2)-1))\n        print(self.tree.trunk * 2)\n\nclass TreeDecorator:\n    def __init__(self, tree: ChristmastTree) -> None:\n        self.tree = tree\n\n    def toggle_star(self):\n        if self.tree.star:\n            self.tree.branches[0] = \"*\"\n            self.tree.star = False\n        else:\n            self.tree.branches[0] = \"@\"\n            self.tree.star = True\n\n    def add_balls(self):\n        if self.tree.available_branches >= 1:\n            exclude = self.tree.balls + self.tree.lights\n            free_branches = [b for b in range(1, self.tree.size ** 2) if b not in exclude]\n            new_balls = random.sample(free_branches, min(2,self.tree.available_branches))\n            for ball in new_balls:\n                self.tree.branches[ball] = \"o\"\n                self.tree.balls.append(ball)\n            self.tree.available_branches -= len(new_balls)\n        else:\n            print(\"No hay suficiente espacio para más bolas\")\n\n    def delete_balls(self):\n        if self.tree.balls:\n            old_balls = random.sample(self.tree.balls, min(2,len(self.tree.balls)))\n            for ball in old_balls:\n                self.tree.branches[ball] = \"*\"\n                self.tree.balls.remove(ball)\n            self.tree.available_branches += len(old_balls)\n\n        else:\n            print(\"No hay bolas en el árbol.\")\n\n    def add_lights(self):\n        if self.tree.available_branches >= 1:\n            exclude = self.tree.balls + self.tree.lights\n            free_branches = [b for b in range(1, self.tree.size ** 2) if b not in exclude]\n            new_lights = random.sample(free_branches, min(3,self.tree.available_branches))\n            for light in new_lights:\n                if self.tree.turned_on:\n                    self.tree.branches[light] = \"+\"\n                self.tree.lights.append(light)\n            self.tree.available_branches -= len(new_lights)\n        else:\n            print(\"No hay suficiente espacio para más luces.\")\n\n    def delete_lights(self):\n        if self.tree.lights:\n            old_lights = random.sample(self.tree.lights, min(3,len(self.tree.lights)))\n            for light in old_lights:\n                if self.tree.turned_on:\n                    self.tree.branches[light] = \"*\"\n                self.tree.lights.remove(light)\n            self.tree.available_branches += len(old_lights)\n\n        else:\n            print(\"No hay luces en el árbol.\")\n\n    def toggle_lights(self):\n        if self.tree.lights:\n            if self.tree.turned_on:\n                for light in self.tree.lights:\n                    self.tree.branches[light] = \"*\"\n                    self.tree.turned_on = False\n            else:\n                for light in self.tree.lights:\n                    self.tree.branches[light] = \"+\"\n                    self.tree.turned_on = True\n        else:\n            print(\"No hay luces en el árbol\")\n\nclass TreeController:\n    def __init__(self, tree: ChristmastTree, tree_decorator: TreeDecorator, tree_render: TreeRender) -> None:\n        self.tree = tree\n        self.tree_decorator = tree_decorator\n        self.tree_render = tree_render\n\n    def run(self):\n\n        while True:\n            \n            print(\"\\n--- Menú ---\")\n            print(\"1. Poner/quitar estrella\")\n            print(\"2. Añadir bolas\")\n            print(\"3. Quitar bolas\")\n            print(\"4. Añadir luces\")\n            print(\"5. Quitar luces\")\n            print(\"6. Encender/apagar luces\")\n            print(\"0. Salir\")\n\n            self.tree_render.display_tree()\n            choice = \"a\"\n            while not choice.isdigit() or int(choice) not in range(0,7):\n                choice = input(\"Elige una opción correcta: \")\n            clear_console()\n            match choice:\n                case \"1\":\n                    self.tree_decorator.toggle_star()\n                case \"2\":\n                    self.tree_decorator.add_balls()\n                case \"3\":\n                    self.tree_decorator.delete_balls()\n                case \"4\":\n                    self.tree_decorator.add_lights()\n                case \"5\":\n                    self.tree_decorator.delete_lights()\n                case \"6\":\n                    self.tree_decorator.toggle_lights()\n                case \"0\":\n                    break\n\ndef clear_console():\n    \"\"\"\n    Limpia la consola, tneiendo en cuenta el sistema operativo.\n    \"\"\"\n    os.system('cls' if os.name =='nt' else 'clear')\n\n\ntree_size = \"a\"\nwhile not tree_size.isdigit():\n    tree_size = input(\"Introduce el tamaño del árbol: \")\nmy_chrismast_tree = ChristmastTree(int(tree_size))\ntree_decorator = TreeDecorator(my_chrismast_tree)\ntree_render = TreeRender(my_chrismast_tree)\ntree_controller = TreeController(my_chrismast_tree, tree_decorator, tree_render)\n\ntree_controller.run()\n"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/python/javierfiestasbotella.py",
    "content": "import random\nfrom colorama import Fore, Back, Style, init\n\n# Inicializar colorama\ninit()\n\n\nhoja = Back.BLACK + Style.DIM + Fore.GREEN + \"*\"\ntronco = Back.BLACK + Style.DIM + Fore.RED + '|'\nestrella = Fore.YELLOW + \"@\"\nbola = Back.BLACK + Style.BRIGHT + Fore.RED + \"o\"\nluz_encendida = Back.BLACK + Style.BRIGHT + Fore.YELLOW + \"+\"\nluz_apagada = Back.BLACK + Style.DIM + Fore.YELLOW + \"+\"\n\n# Función para dibujar el árbol\ndef dibujar_arbol(pisos, tiene_estrella, posiciones_bolas, posiciones_luces, luces_encendidas):\n    if tiene_estrella:\n        print(' ' * (pisos - 1) + estrella)  # Dibuja la estrella\n    for i in range(pisos):\n        fila = []\n        for j in range(2 * i + 1):\n            pos = (i, j)\n            if pos in posiciones_bolas:  # Coloca bolas\n                fila.append(bola)\n            elif pos in posiciones_luces:  # Coloca luces\n                fila.append(luz_encendida if luces_encendidas else luz_apagada)\n            else:  # Hoja normal\n                fila.append(hoja)\n        # Imprime la fila con espacios\n        print(' ' * (pisos - i - 1) + ''.join(fila))\n   \n    tronco_espacios = ' ' * (pisos - 1)\n    for _ in range(2):  # Altura del tronco\n        print(tronco_espacios + tronco)\n\n\npisos = int(input('Indica número de pisos: '))\ntiene_estrella = input('¿Quieres poner la estrella al árbol? (si/no): ').lower() == 'si'\nposiciones_bolas = set()\nposiciones_luces = set()\nluces_encendidas = True\n\n# Funciones para modificar el árbol\ndef agregar_bolas():\n    global posiciones_bolas\n    for _ in range(2):  # Añade de dos en dos\n        while True:\n            fila = random.randint(0, pisos - 1)\n            columna = random.randint(0, 2 * fila)\n            if (fila, columna) not in posiciones_bolas and (fila, columna) not in posiciones_luces:\n                posiciones_bolas.add((fila, columna))\n                break\n\ndef eliminar_bolas():\n    global posiciones_bolas\n    for _ in range(2):  # Elimina de dos en dos\n        if posiciones_bolas:\n            posiciones_bolas.pop()\n\ndef agregar_luces():\n    global posiciones_luces\n    for _ in range(3):  # Añade de tres en tres\n        while True:\n            fila = random.randint(0, pisos - 1)\n            columna = random.randint(0, 2 * fila)\n            if (fila, columna) not in posiciones_bolas and (fila, columna) not in posiciones_luces:\n                posiciones_luces.add((fila, columna))\n                break\n\ndef eliminar_luces():\n    global posiciones_luces\n    for _ in range(3):  # Elimina de tres en tres\n        if posiciones_luces:\n            posiciones_luces.pop()\n\ndef apagar_encender_luces():\n    global luces_encendidas\n    luces_encendidas = not luces_encendidas\n\nwhile True:\n \n    print(\"\\n--- ÁRBOL ACTUAL ---\")\n    dibujar_arbol(pisos, tiene_estrella, posiciones_bolas, posiciones_luces, luces_encendidas)\n\n    print(\"\\nOpciones:\")\n    print(\"1. Añadir bolas\")\n    print(\"2. Eliminar bolas\")\n    print(\"3. Añadir luces\")\n    print(\"4. Eliminar luces\")\n    print(\"5. Apagar/Encender luces\")\n    print(\"6. Salir\")\n\n    opcion = input(\"Elige una opción: \")\n    if opcion == '1':\n        agregar_bolas()\n    elif opcion == '2':\n        eliminar_bolas()\n    elif opcion == '3':\n        agregar_luces()\n    elif opcion == '4':\n        eliminar_luces()\n    elif opcion == '5':\n        apagar_encender_luces()\n    elif opcion == '6':\n        break\n    else:\n        print(\"Opción no válida.\")\n"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/python/juanppdev.py",
    "content": "\"\"\"\n * EJERCICIO:\n * ¡Ha comenzado diciembre! Es hora de montar nuestro\n * árbol de Navidad...\n * \n * Desarrolla un programa que cree un árbol de Navidad en 3d\n * con una altura dinámica definida por el usuario por terminal.\n * \n * Ejemplo de árbol de altura 5 (el tronco siempre será igual):\n * \n *     *\n *    ***\n *   *****\n *  *******\n * *********\n *    |||\n *    |||\n *\n * El usuario podrá seleccionar las siguientes acciones:\n * \n * - Añadir o eliminar la estrella en la copa del árbol (@)\n * - Añadir o eliminar bolas de dos en dos (o) aleatoriamente\n * - Añadir o eliminar luces de tres en tres (+) aleatoriamente\n * - Apagar (*) o encender (+) las luces (conservando su posición)\n * - Una luz y una bola no pueden estar en el mismo sitio\n *\n * Sólo puedes añadir una estrella, y tantas luces o bolas\n * como tengan cabida en el árbol. El programa debe notificar\n * cada una de las acciones (o por el contrario, cuando no\n * se pueda realizar alguna).\n\"\"\"\n\nimport random\n\ndef construir_arbol(altura, estrella=True):\n    arbol = []\n    \n    # Agregar la estrella si está habilitada\n    if estrella:\n        arbol.append(\" \" * (altura - 1) + \"@\")\n    \n    # Crear las capas del árbol\n    for i in range(altura):\n        espacios = \" \" * (altura - i - 1)\n        ramas = \"*\" * (2 * i + 1)\n        arbol.append(espacios + ramas)\n    \n    # Agregar el tronco\n    tronco = \" \" * (altura - 1) + \"|||\"\n    arbol.append(tronco)\n    arbol.append(tronco)  # Segundo nivel del tronco\n    \n    return arbol\n\ndef mostrar_arbol(arbol):\n    for linea in arbol:\n        print(linea)\n\ndef agregar_quitar_estrella(arbol, altura, agregar=True):\n    if agregar:\n        if \"@\" not in arbol[0]:\n            arbol.insert(0, \" \" * (altura - 1) + \"@\")\n        else:\n            print(\"La estrella ya está en la copa.\")\n    else:\n        if \"@\" in arbol[0]:\n            arbol.pop(0)\n        else:\n            print(\"No hay estrella para quitar.\")\n    return arbol\n\ndef agregar_elementos(arbol, altura, elemento, cantidad):\n    espacios_disponibles = [\n        (i, j)\n        for i in range(1, altura + 1)\n        for j in range(len(arbol[i]))\n        if arbol[i][j] == \"*\"\n    ]\n    \n    if len(espacios_disponibles) < cantidad:\n        print(f\"No hay suficientes espacios para agregar {cantidad} {elemento}(s).\")\n        return arbol\n\n    for _ in range(cantidad):\n        i, j = random.choice(espacios_disponibles)\n        fila = list(arbol[i])\n        fila[j] = elemento\n        arbol[i] = \"\".join(fila)\n        espacios_disponibles.remove((i, j))\n    \n    return arbol\n\ndef quitar_elementos(arbol, elemento, cantidad):\n    posiciones = [\n        (i, j)\n        for i in range(1, len(arbol) - 2)\n        for j in range(len(arbol[i]))\n        if arbol[i][j] == elemento\n    ]\n    \n    if len(posiciones) < cantidad:\n        print(f\"No hay suficientes {elemento}(s) para quitar.\")\n        return arbol\n\n    for _ in range(cantidad):\n        i, j = posiciones.pop(0)\n        fila = list(arbol[i])\n        fila[j] = \"*\"\n        arbol[i] = \"\".join(fila)\n    \n    return arbol\n\ndef encender_apagar_luces(arbol, encender=True):\n    for i in range(1, len(arbol) - 2):\n        fila = list(arbol[i])\n        for j in range(len(fila)):\n            if fila[j] == \"+\":\n                fila[j] = \"+\" if encender else \"*\"\n        arbol[i] = \"\".join(fila)\n    return arbol\n\ndef menu():\n    print(\"\\nOpciones:\")\n    print(\"1. Añadir o quitar estrella\")\n    print(\"2. Añadir bolas\")\n    print(\"3. Quitar bolas\")\n    print(\"4. Añadir luces\")\n    print(\"5. Quitar luces\")\n    print(\"6. Encender luces\")\n    print(\"7. Apagar luces\")\n    print(\"8. Salir\")\n\n# Programa principal\naltura = int(input(\"Introduce la altura del árbol: \"))\narbol = construir_arbol(altura)\n\nwhile True:\n    mostrar_arbol(arbol)\n    menu()\n    opcion = input(\"Selecciona una opción: \")\n\n    if opcion == \"1\":\n        accion = input(\"¿Agregar o quitar estrella? (agregar/quitar): \").strip().lower()\n        arbol = agregar_quitar_estrella(arbol, altura, accion == \"agregar\")\n    elif opcion == \"2\":\n        arbol = agregar_elementos(arbol, altura, \"o\", 2)\n    elif opcion == \"3\":\n        arbol = quitar_elementos(arbol, \"o\", 2)\n    elif opcion == \"4\":\n        arbol = agregar_elementos(arbol, altura, \"+\", 3)\n    elif opcion == \"5\":\n        arbol = quitar_elementos(arbol, \"+\", 3)\n    elif opcion == \"6\":\n        arbol = encender_apagar_luces(arbol, encender=True)\n    elif opcion == \"7\":\n        arbol = encender_apagar_luces(arbol, encender=False)\n    elif opcion == \"8\":\n        print(\"¡Feliz Navidad!\")\n        break\n    else:\n        print(\"Opción no válida.\")\n"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/python/kenysdev.py",
    "content": "# _____________________________________\n# https://github.com/kenysdev\n# 2024 - Python\n# _____________________________________\n# #48 ÁRBOL DE NAVIDAD\n# ------------------------------------\n\n\"\"\"\n* EJERCICIO:\n * ¡Ha comenzado diciembre! Es hora de montar nuestro\n * árbol de Navidad...\n * \n * Desarrolla un programa que cree un árbol de Navidad\n * con una altura dinámica definida por el usuario por terminal.\n * \n * Ejemplo de árbol de altura 5 (el tronco siempre será igual):\n * \n *     *\n *    ***\n *   *****\n *  *******\n * *********\n *    |||\n *    |||\n *\n * El usuario podrá seleccionar las siguientes acciones:\n * \n * - Añadir o eliminar la estrella en la copa del árbol (@)\n * - Añadir o eliminar bolas de dos en dos (o) aleatoriamente\n * - Añadir o eliminar luces de tres en tres (+) aleatoriamente\n * - Apagar (*) o encender (+) las luces (conservando su posición)\n * - Una luz y una bola no pueden estar en el mismo sitio\n *\n * Sólo puedes añadir una estrella, y tantas luces o bolas\n * como tengan cabida en el árbol. El programa debe notificar\n * cada una de las acciones (o por el contrario, cuando no\n * se pueda realizar alguna).\n \"\"\"\n\n# ____________________________________________________________________________\nimport random\nimport time\nimport os\n\nclass ChristmasTree:\n    def __init__(self, size) -> None:\n        self.__size: int = size\n        self.__mtx = [[\" \" for _ in range(size * 2 - 1)] for _ in range(size)]\n        self.__star: tuple = (0, size -1)\n        self.__tree_top: list = []\n        self.__balls: list = []\n        self.__lights: list = []\n\n    def print_tree(self) -> None:\n        print()\n        for row in self.__mtx:\n            print(\"\".join(row))\n\n        spaces = (size * 2 - 4) // 2\n        print(\" \" * spaces + \"|||\")\n        print(\" \" * spaces + \"|||\")\n\n    def create_tree(self) -> None:\n        center = self.__size - 1\n        for i in range(self.__size):\n            ast = \"*\" * (i * 2 + 1)\n            for j in range(len(ast)):\n                col = center - i + j\n                self.__mtx[i][col] = ast[j]\n                self.__tree_top.append((i, col))\n\n        self.__tree_top.pop(0)\n\n    def add_remove_star(self) -> None:\n        r, c = self.__star\n        if self.__mtx[r][c] == \"*\":\n            self.__mtx[r][c] = \"@\"\n            return\n        \n        self.__mtx[r][c] = \"*\"\n\n    def add_balls(self) -> None:\n        if len(self.__tree_top) < 2:\n            print(\"Ya no hay espacio para poner bolas.\")\n            return\n\n        random_locations = random.sample(self.__tree_top, 2)\n        for e in random_locations:\n            self.__balls.append(e)\n            self.__tree_top.remove(e)\n            self.__mtx[e[0]][e[1]] = \"o\"\n\n    def remove_balls(self) -> None:\n        if not self.__balls:\n            print(\"No hay bolas que eliminar.\")\n            return\n            \n        random_locations = random.sample(self.__balls, 2)\n        for e in random_locations:\n            self.__balls.remove(e)\n            self.__tree_top.append(e)\n            self.__mtx[e[0]][e[1]] = \"*\"\n\n    def add_lights(self):\n        if len(self.__tree_top) < 3:\n            print(\"Ya no hay espacio para poner luces.\")\n            return\n\n        random_locations = random.sample(self.__tree_top, 3)\n        for e in random_locations:\n            self.__lights.append(e)\n            self.__tree_top.remove(e)\n            self.__mtx[e[0]][e[1]] = \"+\"\n\n    def remove_lights(self):\n        if not self.__lights:\n            print(\"Ya no hay luces que eliminar.\")\n            return\n\n        random_locations = random.sample(self.__lights, 3)\n        for e in random_locations:\n            self.__lights.remove(e)\n            self.__tree_top.append(e)\n            self.__mtx[e[0]][e[1]] = \"*\"\n\n    def on_off_lights(self):\n        if not self.__lights:\n            print(\"No hay luces.\")\n            return\n\n        for e in self.__lights:\n            if self.__mtx[e[0]][e[1]] == \"*\":\n                self.__mtx[e[0]][e[1]] = \"+\"\n            else:\n                self.__mtx[e[0]][e[1]] = \"*\"\n\n    def automatic_lights(self):\n        while True:\n            os.system('cls' if os.name == 'nt' else 'clear')\n            for e in self.__lights:\n                if self.__mtx[e[0]][e[1]] == \"*\":\n                    self.__mtx[e[0]][e[1]] = \"+\"\n                else:\n                    self.__mtx[e[0]][e[1]] = \"*\"\n\n            self.print_tree()\n            time.sleep(1)\n\n# ____________________________________________________________________________\ndef menu(menu: str, tree) -> None:\n    while True:\n        tree.print_tree()\n        print(menu)\n        option: str = input(\"Opción: \")\n\n        match option:\n            case '1': \n                tree.add_remove_star()\n            case '2': \n                tree.add_balls()\n            case '3': \n                tree.remove_balls()\n            case '4': \n                tree.add_lights()\n            case '5': \n                tree.remove_lights()\n            case '6': \n                tree.on_off_lights()\n            case '7':\n                tree.automatic_lights( )\n            case '8':\n                break\n            case _ : \n                print(\"Opción inválida.\")\n\ndef get_size() -> int:\n    while True:\n        size: str = input(\"Tamaño: \")\n        if size.isdigit() and int(size) % 2 != 0 and int(size) >=3:\n            return int(size)\n\n        print(\"Debe ser un número impar >= 3.\")\n\nMENU = \"\"\"\n1 - Agregar/Remover estrella.\n2 - Agregar bolas.    | 3 - Quitar bolas.\n4 - Agregar luces.    | 5 - Quitar luces.\n6 - Encender/Apagar luces.\n7 - Luces automáticas.| 8 - Salir\n\"\"\"\n\nif __name__ == \"__main__\":\n    size: int = get_size()\n    christmas_tree = ChristmasTree(size)\n    christmas_tree.create_tree()\n    menu(MENU, christmas_tree)\n    \n"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/python/ljoecordoba.py",
    "content": "import random\n\ndef generar_arbol(altura, estrella, bolas, luces, encendidas):\n    arbol = []\n    for i in range(altura):\n        nivel = [' '] * (altura + i + 1)\n        start = altura - i\n        for j in range(i * 2 + 1):\n            if (start + j) in luces and encendidas:\n                nivel[start + j] = '+'\n            elif (start + j) in bolas:\n                nivel[start + j] = 'o'\n            else:\n                nivel[start + j] = '*'\n        arbol.append(\"\".join(nivel))\n    \n    if estrella:\n        arbol[0] = arbol[0][:altura] + '@' + arbol[0][altura+1:]\n    \n    tronco = [' ' * (altura - 1) + '|||' for _ in range(2)]\n    return \"\\n\".join(arbol + tronco)\n\ndef agregar_bolas(bolas, altura):\n    posibles = [i for i in range(altura*2-1) if i not in bolas]\n    if len(posibles) >= 2:\n        bolas.update(random.sample(posibles, 2))\n        print(\"Se añadieron dos bolas al árbol.\")\n    else:\n        print(\"No hay espacio suficiente para más bolas.\")\n\ndef eliminar_bolas(bolas):\n    if len(bolas) >= 2:\n        bolas -= set(random.sample(list(bolas), 2))\n        print(\"Se eliminaron dos bolas del árbol.\")\n    else:\n        print(\"No hay bolas suficientes para eliminar.\")\n\ndef agregar_luces(luces, bolas, altura):\n    posibles = [i for i in range(altura*2-1) if i not in luces and i not in bolas]\n    if len(posibles) >= 3:\n        luces.update(random.sample(posibles, 3))\n        print(\"Se añadieron tres luces al árbol.\")\n    else:\n        print(\"No hay espacio suficiente para más luces.\")\n\ndef eliminar_luces(luces):\n    if len(luces) >= 3:\n        luces -= set(random.sample(list(luces), 3))\n        print(\"Se eliminaron tres luces del árbol.\")\n    else:\n        print(\"No hay luces suficientes para eliminar.\")\n\ndef main():\n    altura = int(input(\"Ingrese la altura del árbol: \"))\n    estrella = True\n    bolas = set()\n    luces = set()\n    encendidas = True\n    \n    while True:\n        print(\"\\n\" + generar_arbol(altura, estrella, bolas, luces, encendidas))\n        print(\"Opciones: (1) Estrella (2) Bolas (3) Luces (4) Apagar/Encender (5) Salir\")\n        opcion = input(\"Seleccione una opción: \")\n        \n        if opcion == '1':\n            estrella = not estrella\n            print(\"Se ha modificado la estrella.\")\n        elif opcion == '2':\n            subopcion = input(\"(A) Añadir bolas (B) Eliminar bolas: \").upper()\n            if subopcion == 'A':\n                agregar_bolas(bolas, altura)\n            elif subopcion == 'B':\n                eliminar_bolas(bolas)\n        elif opcion == '3':\n            subopcion = input(\"(A) Añadir luces (B) Eliminar luces: \").upper()\n            if subopcion == 'A':\n                agregar_luces(luces, bolas, altura)\n            elif subopcion == 'B':\n                eliminar_luces(luces)\n        elif opcion == '4':\n            encendidas = not encendidas\n            print(\"Se han \" + (\"encendido\" if encendidas else \"apagado\") + \" las luces.\")\n        elif opcion == '5':\n            break\n        else:\n            print(\"Opción no válida.\")\n\nif __name__ == \"__main__\":\n    main()"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/python/miguelex.py",
    "content": "import random\n\ndef create_tree(height, has_star, decorations, lights_on):\n    tree = []\n\n    # Estrella opcional\n    if has_star:\n        tree.append(\" \" * (height - 1) + \"@\")\n\n    # Ramas\n    for i in range(1, height + 1):\n        line = \" \" * (height - i)\n        for j in range(2 * i - 1):\n            if decorations.get(i, {}).get(j):\n                line += decorations[i][j]\n            else:\n                line += \"*\"\n        tree.append(line)\n\n    # Tronco\n    trunk_padding = \" \" * (height - 2)\n    tree.append(trunk_padding + \"|||\")\n    tree.append(trunk_padding + \"|||\")\n\n    return tree\n\ndef display_tree(tree):\n    print(\"\\n\".join(tree))\n\ndef add_random_decoration(decorations, height, deco_type, count):\n    added = 0\n    while added < count:\n        row = random.randint(1, height)\n        col = random.randint(0, 2 * row - 2)\n\n        if row not in decorations:\n            decorations[row] = {}\n\n        if col not in decorations[row]:\n            decorations[row][col] = deco_type\n            added += 1\n\ndef remove_random_decoration(decorations, deco_type, count):\n    removed = 0\n    for row in list(decorations.keys()):\n        for col in list(decorations[row].keys()):\n            if decorations[row][col] == deco_type and removed < count:\n                del decorations[row][col]\n                removed += 1\n\ndef toggle_lights(decorations, lights_on):\n    for row in decorations:\n        for col in decorations[row]:\n            if decorations[row][col] == \"+\":\n                decorations[row][col] = \"+\" if lights_on else \"*\"\n\ndef main():\n    height = int(input(\"Ingrese la altura del árbol: \"))\n    has_star = True\n    decorations = {}\n    lights_on = True\n\n    while True:\n        tree = create_tree(height, has_star, decorations, lights_on)\n        display_tree(tree)\n\n        print(\"\\nOpciones:\")\n        print(\"1. Añadir/Eliminar estrella\")\n        print(\"2. Añadir bolas (o)\")\n        print(\"3. Eliminar bolas (o)\")\n        print(\"4. Añadir luces (+)\")\n        print(\"5. Eliminar luces (+)\")\n        print(\"6. Apagar/Encender luces\")\n        print(\"7. Salir\")\n\n        option = int(input(\"Seleccione una opción: \"))\n\n        if option == 1:\n            has_star = not has_star\n            print(\"Estrella añadida.\" if has_star else \"Estrella eliminada.\")\n        elif option == 2:\n            add_random_decoration(decorations, height, \"o\", 2)\n            print(\"Bolas añadidas.\")\n        elif option == 3:\n            remove_random_decoration(decorations, \"o\", 2)\n            print(\"Bolas eliminadas.\")\n        elif option == 4:\n            add_random_decoration(decorations, height, \"+\", 3)\n            print(\"Luces añadidas.\")\n        elif option == 5:\n            remove_random_decoration(decorations, \"+\", 3)\n            print(\"Luces eliminadas.\")\n        elif option == 6:\n            lights_on = not lights_on\n            toggle_lights(decorations, lights_on)\n            print(\"Luces encendidas.\" if lights_on else \"Luces apagadas.\")\n        elif option == 7:\n            print(\"¡Feliz Navidad!\")\n            break\n        else:\n            print(\"Opción no válida.\")\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/python/mouredev.py",
    "content": "import random\n\n\nclass ChristmasTree:\n\n    def __init__(self, height: int):\n\n        self.height = height\n        self.tree = [\n            [\" \" for _ in range(2 * height - 1)]\n            for _ in range(height)\n        ]\n\n        for i in range(height):\n            for j in range(height - i - 1, height + i):\n                self.tree[i][j] = \"*\"\n\n        self.trunk = [\n            [\" \" for _ in range(2 * height - 1)]\n            for _ in range(2)\n        ]\n\n        for i in range(2):\n            for j in range(height - 2, height + 1):\n                self.trunk[i][j] = \"|\"\n\n        self.star = False\n        self.balls = []\n        self.lights = []\n        self.lights_on = False\n\n    def display_tree(self):\n        for index, row in enumerate(self.tree):\n            if index == 0 and self.star:\n                print(\"\".join(row).replace(\"*\", \"@\"))\n            else:\n                print(\"\".join(row))\n        for row in self.trunk:\n            print(\"\".join(row))\n\n    def add_star(self):\n        if self.star:\n            print(\"Ya existe una estrella en el árbol.\")\n        else:\n            self.star = True\n            print(\"Se ha puesto la estrella en el árbol.\")\n\n    def remove_star(self):\n        if not self.star:\n            print(\"No existe una estrella en el árbol para quitar.\")\n        else:\n            self.star = False\n            print(\"Se ha quitado la estrella en el árbol.\")\n\n    def add_balls(self):\n        available = self.available()\n        if len(available) < 2:\n            print(\"No hay suficiente espacio para añadir más bolas.\")\n        else:\n            selected = random.sample(available, 2)\n            for i, j in selected:\n                self.tree[i][j] = \"o\"\n                self.balls.append((i, j))\n            print(\"Se han añadido 2 bolas al árbol.\")\n\n    def remove_balls(self):\n        if len(self.balls) < 2:\n            print(\"No hay suficientes bolas para quitar.\")\n        else:\n            selected = random.sample(self.balls, 2)\n            for i, j in selected:\n                self.tree[i][j] = \"*\"\n                self.balls.remove((i, j))\n            print(\"Se han eliminado 2 bolas del árbol.\")\n\n    def add_lights(self):\n        available = self.available()\n        if len(available) < 3:\n            print(\"No hay suficiente espacio para añadir más luces.\")\n        else:\n            selected = random.sample(available, 3)\n            for i, j in selected:\n                self.tree[i][j] = \"+\" if self.lights_on else \"*\"\n                self.lights.append((i, j))\n            print(\"Se han añadido 3 luces al árbol.\")\n\n    def remove_lights(self):\n        if len(self.lights) < 2:\n            print(\"No hay suficientes luces para quitar.\")\n        else:\n            selected = random.sample(self.lights, 3)\n            for i, j in selected:\n                self.tree[i][j] = \"*\"\n                self.lights.remove((i, j))\n            print(\"Se han eliminado 3 luces del árbol.\")\n\n    def toggle_lights(self, turn_on):\n        if not self.lights:\n            print(\"No hay luces en el árbol.\")\n\n        self.lights_on = turn_on\n        for i, j in self.lights:\n            self.tree[i][j] = \"+\" if turn_on else \"*\"\n        print(f\"Las luces fueron {'encendidas' if turn_on else 'apagadas'}.\")\n\n    def available(self):\n        available_tree = [\n            (i, j) for i in range(1, self.height) for j in range(\n                self.height - i - 1, self.height + i) if self.tree[i][j] == \"*\"\n        ]\n        if not self.lights_on:\n            for i, j in self.lights:\n                available_tree.remove((i, j))\n        return available_tree\n\n\nheight = input(\"Introduce la altura del árbol: \")\n\nif height.isdigit() and int(height) > 0:\n\n    tree = ChristmasTree(int(height))\n\n    while True:\n\n        tree.display_tree()\n\n        print(\"\\nAcciones:\")\n        print(\"1. Añadir estrella\")\n        print(\"2. Quitar estrella\")\n        print(\"3. Añadir bolas\")\n        print(\"4. Quitar bolas\")\n        print(\"5. Añadir luces\")\n        print(\"6. Quitar luces\")\n        print(\"7. Encender luces\")\n        print(\"8. Apagar luces\")\n        print(\"9. Salir\")\n\n        action = input(\"Selecciona una acción: \")\n\n        match action:\n            case \"1\":\n                tree.add_star()\n            case \"2\":\n                tree.remove_star()\n            case \"3\":\n                tree.add_balls()\n            case \"4\":\n                tree.remove_balls()\n            case \"5\":\n                tree.add_lights()\n            case \"6\":\n                tree.remove_lights()\n            case \"7\":\n                tree.toggle_lights(True)\n            case \"8\":\n                tree.toggle_lights(False)\n            case \"9\":\n                print(\"¡Feliz Navidad!\")\n                break\n            case _:\n                print(\"Opción no válida.\")\n\n    else:\n        print(f\"Altura '{height}' no válida\")\n"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/python/neslarra.py",
    "content": "r\"\"\"\n EJERCICIO:\n ¡Ha comenzado diciembre! Es hora de montar nuestro\n árbol de Navidad...\n \n Desarrolla un programa que cree un árbol de Navidad\n con una altura dinámica definida por el usuario por terminal.\n \n Ejemplo de árbol de altura 5 (el tronco siempre será igual):\n \n     *\n    ***\n   *****\n  *******\n *********\n    |||\n    |||\n\n El usuario podrá seleccionar las siguientes acciones:\n \n - Añadir o eliminar la estrella en la copa del árbol (@)\n - Añadir o eliminar bolas de dos en dos (o) aleatoriamente\n - Añadir o eliminar luces de tres en tres (+) aleatoriamente\n - Apagar (*) o encender (+) las luces (conservando su posición)\n - Una luz y una bola no pueden estar en el mismo sitio\n\n Sólo puedes añadir una estrella, y tantas luces o bolas\n como tengan cabida en el árbol. El programa debe notificar\n cada una de las acciones (o por el contrario, cuando no\n se pueda realizar alguna).\n\"\"\"\nfrom os import system, name\nfrom random import randint\nfrom time import sleep\n\naccesories = {\"log\": \"|||\", \"leaf\": \"*\", \"star\": \"@\", \"ball\": \"O\", \"light_on\": \"+\", \"light_off\": \"-\"}\n\n\ndef put_up_tree(height: int) -> list:\n    if not 2 <= height <= 15:\n        print(f\"{height} fuera de rango.\")\n        return []\n    max_width = (2 * height) - 1\n    lodge_sep = (max_width - accesories[\"log\"].__len__()) // 2\n    tree = [\" \" * lodge_sep + accesories[\"log\"] + \" \" * lodge_sep] * 2\n    for index, branch in enumerate(range(height, 0, -1)):\n        tree.append(\" \" * index + accesories[\"leaf\"] * (max_width - (2 * index)) + \" \" * index)\n    return tree\n\n\ndef manage_balls(tree: list, on: bool = True) -> list:\n    if on:\n        char_to = accesories[\"leaf\"]\n        char_with = accesories[\"ball\"]\n    else:\n        char_to = accesories[\"ball\"]\n        char_with = accesories[\"leaf\"]\n    tries = tree.__len__() - 2\n    for _ in range(0, 2):\n        while tries:\n            index = randint(2, tree.__len__() - 2)\n            if char_to in tree[index]:\n                while True:\n                    pos = randint(0, tree[index].__len__() - 1)\n                    if tree[index][pos] == char_to:\n                        tree[index] = tree[index][0:pos] + char_with + (tree[index][pos + 1:] if pos <= tree[index].__len__() - 1 else \"\")\n                        break\n                    break\n            tries -= 1\n    return tree\n\n\ndef manage_lights(tree: list, on: bool = True) -> list:\n    if on:\n        char_to = accesories[\"leaf\"]\n        char_with = accesories[\"light_on\"]\n    else:\n        char_to = accesories[\"light_on\"]\n        char_with = accesories[\"leaf\"]\n    tries = tree.__len__() - 2\n    for _ in range(0, 2):\n        while tries:\n            index = randint(2, tree.__len__() - 2)\n            if char_to in tree[index]:\n                while True:\n                    pos = randint(0, tree[index].__len__() - 1)\n                    if tree[index][pos] == char_to:\n                        tree[index] = tree[index][0:pos] + char_with + (tree[index][pos + 1:] if pos <= tree[index].__len__() - 1 else \"\")\n                        break\n                    break\n            tries -= 1\n    return tree\n\n\ndef manage_star(tree: list, on: bool = True) -> list:\n    if on:\n        tree[-1] = tree[-1].replace(accesories[\"leaf\"], accesories[\"star\"])\n    else:\n        tree[-1] = tree[-1].replace(accesories[\"star\"], accesories[\"leaf\"])\n    return tree\n\n\ndef show_tree(tree: list) -> None:\n    if name == \"posix\":\n        system(\"clear\")\n    else:\n        system(\"cls\")\n    for x in tree[::-1]:\n        print(x)\n\n\ndef turn_on(tree: list, on: bool = True) -> list:\n    if on:\n        char_to = accesories[\"light_off\"]\n        char_with = accesories[\"light_on\"]\n    else:\n        char_to = accesories[\"light_on\"]\n        char_with = accesories[\"light_off\"]\n    for index in range(2, tree.__len__() - 1):\n        tree[index] = tree[index].replace(char_to, char_with)\n    return tree\n\n\ndef menu() -> int:\n    print(\"\\nDecorar el arbolito...\")\n    print(\"\\t1- Agregar estrella\")\n    print(\"\\t2- Quitar estrella\")\n    print(\"\\t3- Agregar bolas\")\n    print(\"\\t4- Quitar bolas\")\n    print(\"\\t5- Agregar luces\")\n    print(\"\\t6- Quitar luces\")\n    print(\"\\t7- Enchufar\")\n    print(\"\\t0- Salir\")\n    while True:\n        opcion = input(f\"\\nIngresar opción [0-7]: \")\n        if opcion.isnumeric() and 0 <= int(opcion) <= 7:\n            return int(opcion)\n\n\ndef main():\n    tree = put_up_tree(int(input(\"Ingrese altura (mínimo 2, máximo 15): \")))\n    if tree:\n        while True:\n            show_tree(tree)\n            opcion = menu()\n            match opcion:\n                case 0:\n                    break\n                case 1:\n                    tree = manage_star(tree, True)\n                case 2:\n                    tree = manage_star(tree, False)\n                case 3:\n                    tree = manage_balls(tree, True)\n                case 4:\n                    tree = manage_balls(tree, False)\n                case 5:\n                    tree = manage_lights(tree, True)\n                case 6:\n                    tree = manage_lights(tree, False)\n                case 7:\n                    for _ in range(0, 30):\n                        show_tree(turn_on(tree, False))\n                        sleep(0.5)\n                        show_tree(turn_on(tree, True))\n                        sleep(0.5)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/python/rigo93acosta.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * ¡Ha comenzado diciembre! Es hora de montar nuestro\n * árbol de Navidad...\n * \n * Desarrolla un programa que cree un árbol de Navidad\n * con una altura dinámica definida por el usuario por terminal.\n * \n * Ejemplo de árbol de altura 5 (el tronco siempre será igual):\n * \n *     *\n *    ***\n *   *****\n *  *******\n * *********\n *    |||\n *    |||\n *\n * El usuario podrá seleccionar las siguientes acciones:\n * \n * - Añadir o eliminar la estrella en la copa del árbol (@)\n * - Añadir o eliminar bolas de dos en dos (o) aleatoriamente\n * - Añadir o eliminar luces de tres en tres (+) aleatoriamente\n * - Apagar (*) o encender (+) las luces (conservando su posición)\n * - Una luz y una bola no pueden estar en el mismo sitio\n *\n * Sólo puedes añadir una estrella, y tantas luces o bolas\n * como tengan cabida en el árbol. El programa debe notificar\n * cada una de las acciones (o por el contrario, cuando no\n * se pueda realizar alguna).\n */\n\"\"\"\nfrom random import randint as rint\n\nclass ArbolNavidad:\n\n    def __init__(self, altura: int):\n        self.altura = altura\n        self.tree = []\n        self.lightsPos = []\n        self.totalBalls = 0\n        self.create_tree()\n    \n    def check_light(self, altura, rama):\n        for pos in self.lightsPos:\n            if pos[0] == altura and pos[1] == rama:\n                return False\n        return True\n\n\n    def create_tree(self):\n        all_poss = [i*2-1 for i in range(1, self.altura+1)]\n        self.max = max(all_poss)\n        self.totalTreeSpaces = sum(all_poss)\n        for val in all_poss:\n            self.tree.append(f\"{'*'*val: ^{self.max}}\")\n\n    def add_star(self):\n        self.tree.pop(0)\n        self.tree.insert(0, f\"{'@': ^{self.max}}\")\n    \n    def eleminate_star(self):\n        self.tree.pop(0)\n        self.tree.insert(0, f\"{'*': ^{self.max}}\")\n\n    def add_balls(self):\n        if self.totalTreeSpaces <= 2:\n            print(\"No hay espacio para bolas.\\n\")\n            return\n        check = 0\n        while True:\n            pos_altura = rint(1, self.altura-1)\n            pos_rama = rint(0, self.max-1)\n            if self.tree[pos_altura][pos_rama] == '*' \\\n                and self.check_light(pos_altura, pos_rama):\n\n                tmp = list(self.tree[pos_altura])\n                tmp[pos_rama] = 'o'\n                self.tree[pos_altura] = \"\".join(tmp)\n                self.totalBalls += 1\n                self.totalTreeSpaces -= 1\n                check += 1\n\n            if check == 2:\n                break\n\n    def eleminate_balls(self):\n        if self.totalBalls == 0:\n            print(\"No hay bolas para eliminar.\\n\")\n            return\n        check = 0\n        while True:\n            pos_altura = rint(1, self.altura-1)\n            pos_rama = rint(0, self.max-1)\n            if self.tree[pos_altura][pos_rama] == 'o':\n                tmp = list(self.tree[pos_altura])\n                tmp[pos_rama] = '*'\n                self.tree[pos_altura] = \"\".join(tmp)\n                self.totalBalls -= 1\n                self.totalTreeSpaces += 1\n                check += 1\n\n            if check == 2:\n                break\n\n    def add_lights(self):\n        if self.totalTreeSpaces <= 3:\n            print(\"No hay espacio para luces.\\n\")\n            return\n        check = 0\n        while True:\n            pos_altura = rint(1, self.altura-1)\n            pos_rama = rint(0, self.max-1)\n            if self.tree[pos_altura][pos_rama] == '*' \\\n                and self.check_light(pos_altura, pos_rama):\n                tmp = list(self.tree[pos_altura])\n                tmp[pos_rama] = '+'\n                self.tree[pos_altura] = \"\".join(tmp)\n                self.lightsPos.append((pos_altura, pos_rama))\n                self.totalTreeSpaces -= 1\n                check += 1\n\n            if check == 3:\n                break\n\n    def eleminate_lights(self):\n        if not self.lightsPos:\n            print(\"No hay luces para eliminar.\\n\")\n            return\n        check = 0\n        while True:\n            pos_altura = rint(1, self.altura-1)\n            pos_rama = rint(0, self.max-1)\n            if self.tree[pos_altura][pos_rama] == '+':\n                tmp = list(self.tree[pos_altura])\n                tmp[pos_rama] = '*'\n                self.tree[pos_altura] = \"\".join(tmp)\n                self.lightsPos.remove((pos_altura, pos_rama))\n                self.totalTreeSpaces += 1\n                check += 1\n\n            if check == 3:\n                break\n    \n    def turnOnLights(self):\n        print(\"Encendiendo luces...\\n\")\n        for pos in self.lightsPos:\n            tmp = list(self.tree[pos[0]])\n            tmp[pos[1]] = '+'\n            self.tree[pos[0]] = \"\".join(tmp)\n        \n    def turnOffLights(self):\n        print(\"Apagando luces...\\n\")\n        for pos in self.lightsPos:\n            tmp = list(self.tree[pos[0]])\n            tmp[pos[1]] = '*'\n            self.tree[pos[0]] = \"\".join(tmp)\n\n    def __str__(self):\n\n        s = self.tree.copy()\n        s.append(f\"{'|'*3: ^{self.max}}\")\n        s.append(f\"{'|'*3: ^{self.max}}\")\n        return \"\\n\".join(s)\n\n\nif __name__ == \"__main__\":\n\n    altura = input(\"Introduce la altura del árbol: \")\n\n    if altura.isdigit() and int(altura) > 0:\n        arbol = ArbolNavidad(int(altura))\n        while True:\n            print(\"\\nAcciones: \")\n            print(\"1. Añadir estrella.\")\n            print(\"2. Eliminar estrella.\")\n            print(\"3. Añadir bolas.\")\n            print(\"4. Eliminar bolas.\")\n            print(\"5. Añadir luces.\")\n            print(\"6. Eliminar luces.\")\n            print(\"7. Encender luces.\")\n            print(\"8. Apagar luces.\")\n            print(\"9. Salir.\\n\")\n\n            option = input(\"Introduce una opción: \")\n\n            match int(option):\n\n                case 1:\n                    arbol.add_star()\n                case 2:\n                    arbol.eleminate_star()\n                case 3:\n                    arbol.add_balls()\n                case 4:\n                    arbol.eleminate_balls()\n                case 5:\n                    arbol.add_lights()\n                case 6:\n                    arbol.eleminate_lights()\n                case 7:\n                    arbol.turnOnLights()\n                case 8:\n                    arbol.turnOffLights()\n                case 9:\n                    break\n                case _:\n                    print(\"Introduce una opción válida.\\n\")\n            print(arbol)\n    else:\n        print(\"Introduce una altura válida.\")"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/rust/kenysdev.rs",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - Rust\n_____________________________________\n#48 ÁRBOL DE NAVIDAD\n------------------------------------\n\n * EJERCICIO:\n * ¡Ha comenzado diciembre! Es hora de montar nuestro\n * árbol de Navidad...\n * \n * Desarrolla un programa que cree un árbol de Navidad\n * con una altura dinámica definida por el usuario por terminal.\n * \n * Ejemplo de árbol de altura 5 (el tronco siempre será igual):\n * \n *     *\n *    ***\n *   *****\n *  *******\n * *********\n *    |||\n *    |||\n *\n * El usuario podrá seleccionar las siguientes acciones:\n * \n * - Añadir o eliminar la estrella en la copa del árbol (@)\n * - Añadir o eliminar bolas de dos en dos (o) aleatoriamente\n * - Añadir o eliminar luces de tres en tres (+) aleatoriamente\n * - Apagar (*) o encender (+) las luces (conservando su posición)\n * - Una luz y una bola no pueden estar en el mismo sitio\n *\n * Sólo puedes añadir una estrella, y tantas luces o bolas\n * como tengan cabida en el árbol. El programa debe notificar\n * cada una de las acciones (o por el contrario, cuando no\n * se pueda realizar alguna).\n\n[dependencies]\nrand = \"0.8.5\"\n*/\n\nuse std::io::{self, Write};\nuse std::thread;\nuse std::time::Duration;\nuse rand::seq::SliceRandom;\n\n#[derive(Debug)]\nstruct ChristmasTree {\n    size: usize,\n    matrix: Vec<Vec<char>>,\n    star: (usize, usize),\n    tree_top: Vec<(usize, usize)>,\n    balls: Vec<(usize, usize)>,\n    lights: Vec<(usize, usize)>,\n}\n\nimpl ChristmasTree {\n    fn new(size: usize) -> Self {\n        let cols = size * 2 - 1;\n        let matrix = vec![vec![' '; cols]; size];\n        let star = (0, size - 1);\n        \n        Self {\n            size,\n            matrix,\n            star,\n            tree_top: Vec::new(),\n            balls: Vec::new(),\n            lights: Vec::new(),\n        }\n    }\n\n    fn print_tree(&self) {\n        println!();\n        for row in &self.matrix {\n            println!(\"{}\", row.iter().collect::<String>());\n        }\n\n        let spaces = (self.size * 2 - 4) / 2;\n        println!(\"{}{}\", \" \".repeat(spaces), \"|||\");\n        println!(\"{}{}\", \" \".repeat(spaces), \"|||\");\n    }\n\n    fn create_tree(&mut self) {\n        let center = self.size - 1;\n        for i in 0..self.size {\n            let asterisks = \"*\".repeat(i * 2 + 1);\n            for (j, c) in asterisks.chars().enumerate() {\n                let col = center - i + j;\n                self.matrix[i][col] = c;\n                self.tree_top.push((i, col));\n            }\n        }\n        self.tree_top.remove(0);\n    }\n\n    fn add_remove_star(&mut self) {\n        let (row, col) = self.star;\n        self.matrix[row][col] = if self.matrix[row][col] == '*' { '@' } else { '*' };\n    }\n\n    fn add_balls(&mut self) {\n        if self.tree_top.len() < 2 {\n            println!(\"Ya no hay espacio para poner bolas.\");\n            return;\n        }\n    \n        let mut rng = rand::thread_rng();\n        let count = std::cmp::min(2, self.tree_top.len());\n    \n        for _ in 0..count {\n            if let Some(&pos) = self.tree_top.choose(&mut rng) {\n                if let Some(idx) = self.tree_top.iter().position(|&x| x == pos) {\n                    let removed_pos = self.tree_top.remove(idx);\n                    self.balls.push(removed_pos);\n                    self.matrix[removed_pos.0][removed_pos.1] = 'o';\n                }\n            }\n        }\n    }\n    \n    fn remove_balls(&mut self) {\n        if self.balls.is_empty() {\n            println!(\"No hay bolas que eliminar.\");\n            return;\n        }\n    \n        let mut rng = rand::thread_rng();\n        let count = std::cmp::min(2, self.balls.len());\n\n        for _ in 0..count {\n            if let Some(&pos) = self.balls.choose(&mut rng) {\n                if let Some(idx) = self.balls.iter().position(|&x| x == pos) {\n                    let removed_pos = self.balls.remove(idx);\n                    self.tree_top.push(removed_pos);\n                    self.matrix[removed_pos.0][removed_pos.1] = '*';\n                }\n            }\n        }\n    }\n    fn add_lights(&mut self) {\n        if self.tree_top.len() < 3 {\n            println!(\"Ya no hay espacio para poner luces.\");\n            return;\n        }\n    \n        let mut rng = rand::thread_rng();\n        let count = std::cmp::min(3, self.tree_top.len());\n\n        for _ in 0..count {\n            if let Some(&pos) = self.tree_top.choose(&mut rng) {\n                if let Some(idx) = self.tree_top.iter().position(|&x| x == pos) {\n                    let removed_pos = self.tree_top.remove(idx);\n                    self.lights.push(removed_pos);\n                    self.matrix[removed_pos.0][removed_pos.1] = '+';\n                }\n            }\n        }\n    }\n    \n    fn remove_lights(&mut self) {\n        if self.lights.is_empty() {\n            println!(\"No hay luces que eliminar.\");\n            return;\n        }\n    \n        let mut rng = rand::thread_rng();\n        let count = std::cmp::min(3, self.lights.len());\n    \n        for _ in 0..count {\n            if let Some(&pos) = self.lights.choose(&mut rng) {\n                if let Some(idx) = self.lights.iter().position(|&x| x == pos) {\n                    let removed_pos = self.lights.remove(idx);\n                    self.tree_top.push(removed_pos);\n                    self.matrix[removed_pos.0][removed_pos.1] = '*';\n                }\n            }\n        }\n    }\n\n    fn on_off_lights(&mut self) {\n        if self.lights.is_empty() {\n            println!(\"No hay luces.\");\n            return;\n        }\n\n        for &(row, col) in &self.lights {\n            self.matrix[row][col] = if self.matrix[row][col] == '*' { '+' } else { '*' };\n        }\n    }\n\n    fn automatic_lights(&mut self) -> io::Result<()> {\n        loop {\n            print!(\"\\x1B[2J\\x1B[1;1H\"); // Clear screen\n            io::stdout().flush()?;\n            \n            for &(row, col) in &self.lights {\n                self.matrix[row][col] = if self.matrix[row][col] == '*' { '+' } else { '*' };\n            }\n            \n            self.print_tree();\n            thread::sleep(Duration::from_secs(1));\n        }\n    }\n}\n\nconst MENU: &str = r#\"\n1 - Agregar/Remover estrella.\n2 - Agregar bolas.    | 3 - Quitar bolas.\n4 - Agregar luces.    | 5 - Quitar luces.\n6 - Encender/Apagar luces.\n7 - Luces automáticas.| 8 - Salir\n\"#;\n\nfn show_menu(tree: &mut ChristmasTree) -> io::Result<()> {\n    loop {\n        tree.print_tree();\n        println!(\"{}\", MENU);\n        print!(\"Opción: \");\n        io::stdout().flush()?;\n\n        let mut option = String::new();\n        io::stdin().read_line(&mut option)?;\n\n        match option.trim() {\n            \"1\" => tree.add_remove_star(),\n            \"2\" => tree.add_balls(),\n            \"3\" => tree.remove_balls(),\n            \"4\" => tree.add_lights(),\n            \"5\" => tree.remove_lights(),\n            \"6\" => tree.on_off_lights(),\n            \"7\" => tree.automatic_lights()?,\n            \"8\" => break,\n            _ => println!(\"Opción inválida.\"),\n        }\n    }\n    Ok(())\n}\n\nfn get_size() -> io::Result<usize> {\n    loop {\n        print!(\"Tamaño: \");\n        io::stdout().flush()?;\n\n        let mut input = String::new();\n        io::stdin().read_line(&mut input)?;\n\n        if let Ok(size) = input.trim().parse::<usize>() {\n            if size % 2 != 0 && size >= 3 {\n                return Ok(size);\n            }\n        }\n        println!(\"Debe ser un número impar >= 3.\");\n    }\n}\n\nfn main() -> io::Result<()> {\n    let size = get_size()?;\n    let mut christmas_tree = ChristmasTree::new(size);\n    christmas_tree.create_tree();\n    show_menu(&mut christmas_tree)?;\n    Ok(())\n}\n"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/sql/Nicojsuarez2.sql",
    "content": "# #48 ÁRBOL DE NAVIDAD\n> #### Dificultad: Media | Publicación: 02/12/24 | Corrección: 09/12/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * ¡Ha comenzado diciembre! Es hora de montar nuestro\n * árbol de Navidad...\n * \n * Desarrolla un programa que cree un árbol de Navidad\n * con una altura dinámica definida por el usuario por terminal.\n * \n * Ejemplo de árbol de altura 5 (el tronco siempre será igual):\n * \n *     *\n *    ***\n *   *****\n *  *******\n * *********\n *    |||\n *    |||\n *\n * El usuario podrá seleccionar las siguientes acciones:\n * \n * - Añadir o eliminar la estrella en la copa del árbol (@)\n * - Añadir o eliminar bolas de dos en dos (o) aleatoriamente\n * - Añadir o eliminar luces de tres en tres (+) aleatoriamente\n * - Apagar (*) o encender (+) las luces (conservando su posición)\n * - Una luz y una bola no pueden estar en el mismo sitio\n *\n * Sólo puedes añadir una estrella, y tantas luces o bolas\n * como tengan cabida en el árbol. El programa debe notificar\n * cada una de las acciones (o por el contrario, cuando no\n * se pueda realizar alguna).\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/typescript/hozlucas28.ts",
    "content": "import readline from 'node:readline/promises'\n\n/* -------------------------------------------------------------------------- */\n/*                                   CLASSES                                  */\n/* -------------------------------------------------------------------------- */\n\ninterface IChristmasTree {\n    getHeight: () => number\n    getTree: () => string\n\n    addBalls: (ball: string) => this\n    addLights: (light: string) => this\n    addStar: (star: string) => this\n    removeBalls: (ball: string) => this\n    removeLights: (light: string) => this\n    removeStar: (star: string) => this\n    turnOffLights: (lightOff: string) => this\n    turnOnLights: (lightOn: string) => this\n}\n\ninterface ChristmasTreeConstructor {\n    height: number\n}\n\nclass ChristmasTree implements IChristmasTree {\n    private lightsIndexes: [number, number][]\n    private readonly height: number\n    private tree: string[]\n\n    public constructor({height}: ChristmasTreeConstructor) {\n        let tree: string[] = []\n\n        for (let i = 0; i < height; i++) {\n            const branchBlankSpaces = height >= 2 ? ' '.repeat(height - i - 1) : ' '\n            tree.push(`${branchBlankSpaces}${'*'.repeat(i * 2 + 1)}`)\n        }\n\n        const trunkBlankSpaces: string = height >= 2 ? ' '.repeat(height - 2) : ''\n        tree.push(`${trunkBlankSpaces}|||`, `${trunkBlankSpaces}|||`)\n\n        this.height = height\n        this.lightsIndexes = []\n        this.tree = tree\n    }\n\n    public getHeight(): number {\n        return this.height\n    }\n\n    public getTree(): string {\n        return this.tree.join('\\n')\n    }\n\n    public addBalls(ball: string): this {\n        for (let i = 1; i < this.tree.length - 2; i++) {\n            const branch: string = this.tree[i]\n            let counter: number = 0\n\n            let newBranch: string = ''\n\n            for (let j = 0; j < branch.length; j++) {\n                const char = branch[j]\n                newBranch += !(counter % 2) && char === '*' ? ball : char\n                counter++\n            }\n\n            this.tree[i] = newBranch\n        }\n\n        return this\n    }\n\n    public addLights(ball: string): this {\n        for (let i = 1; i < this.tree.length - 2; i++) {\n            const branch: string = this.tree[i]\n            let counter: number = 0\n\n            let newBranch: string = ''\n\n            for (let j = 0; j < branch.length; j++) {\n                const char = branch[j]\n\n                if (counter % 2 && char === '*') {\n                    newBranch += ball\n                    this.lightsIndexes.push([i, j])\n                } else newBranch += char\n\n                counter++\n            }\n\n            this.tree[i] = newBranch\n        }\n\n        return this\n    }\n\n    public addStar(star: string): this {\n        this.tree[0] = this.tree[0].replace('*', star)\n        return this\n    }\n\n    public removeBalls(ball: string): this {\n        for (let i = 1; i < this.tree.length - 2; i++) {\n            this.tree[i] = this.tree[i].replaceAll(ball, '*')\n        }\n\n        return this\n    }\n\n    public removeLights(light: string): this {\n        while (this.lightsIndexes.length != 0) {\n            const [branch, index]: [number, number] = this.lightsIndexes[0]\n\n            let newBranch: string = ''\n\n            for (let j = 0; j < this.tree[branch].length; j++) {\n                if (j === index) {\n                    newBranch += '*'\n                    this.lightsIndexes.splice(0, 1)\n                    continue\n                }\n\n                newBranch += this.tree[branch][j]\n            }\n\n            this.tree[branch] = newBranch\n        }\n\n        return this\n    }\n\n    public removeStar(star: string): this {\n        this.tree[0] = this.tree[0].replace(star, '*')\n        return this\n    }\n\n    public turnOffLights(lightOff: string): this {\n        for (let i = 0; i < this.lightsIndexes.length; i++) {\n            const [branch, index]: [number, number] = this.lightsIndexes[i]\n\n            let newBranch: string = ''\n\n            for (let j = 0; j < this.tree[branch].length; j++) {\n                newBranch += j === index ? lightOff : this.tree[branch][j]\n            }\n\n            this.tree[branch] = newBranch\n        }\n\n        return this\n    }\n\n    public turnOnLights(lightOn: string): this {\n        for (let i = 0; i < this.lightsIndexes.length; i++) {\n            const [branch, index]: [number, number] = this.lightsIndexes[i]\n\n            let newBranch: string = ''\n\n            for (let j = 0; j < this.tree[branch].length; j++) {\n                newBranch += j === index ? lightOn : this.tree[branch][j]\n            }\n\n            this.tree[branch] = newBranch\n        }\n\n        return this\n    }\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\n;(async () => {\n    const rl: readline.Interface = readline.createInterface({output: process.stdout, input: process.stdin})\n\n    let input: string = (await rl.question('> Enter the height of the christmas tree: ')).trim()\n\n    const christmasTree: IChristmasTree = new ChristmasTree({height: parseInt(input)})\n\n    console.clear()\n    console.log(christmasTree.getTree())\n\n    console.log(\n        '\\n> Available operations...\\n\\n' +\n            '  1 - Add star.\\n' +\n            '  2 - Remove star.\\n' +\n            '  3 - Add balls.\\n' +\n            '  4 - Remove balls.\\n' +\n            '  5 - Add lights.\\n' +\n            '  6 - Remove lights.\\n' +\n            '  7 - Turn on lights.\\n' +\n            '  8 - Turn off lights.\\n' +\n            '  0 - Exit.'\n    )\n\n    input = (await rl.question('\\n> Enter an operation: ')).trim()\n\n    while (input !== '0') {\n        switch (input) {\n            case '1':\n                christmasTree.addStar('@')\n\n                console.clear()\n                console.log(christmasTree.getTree())\n                break\n\n            case '2':\n                christmasTree.removeStar('@')\n\n                console.clear()\n                console.log(christmasTree.getTree())\n                break\n\n            case '3':\n                christmasTree.addBalls('o')\n\n                console.clear()\n                console.log(christmasTree.getTree())\n                break\n\n            case '4':\n                christmasTree.removeBalls('o')\n\n                console.clear()\n                console.log(christmasTree.getTree())\n                break\n\n            case '5':\n                christmasTree.addLights('+')\n\n                console.clear()\n                console.log(christmasTree.getTree())\n                break\n\n            case '6':\n                christmasTree.removeLights('*')\n\n                console.clear()\n                console.log(christmasTree.getTree())\n                break\n\n            case '7':\n                christmasTree.turnOnLights('+')\n\n                console.clear()\n                console.log(christmasTree.getTree())\n                break\n\n            case '8':\n                christmasTree.turnOffLights('*')\n\n                console.clear()\n                console.log(christmasTree.getTree())\n                break\n\n            default:\n                console.log('\\n> Invalid operation! Try again...')\n        }\n\n        console.log(\n            '\\n> Available operations...\\n\\n' +\n                '  1 - Add star.\\n' +\n                '  2 - Remove star.\\n' +\n                '  3 - Add balls.\\n' +\n                '  4 - Remove balls.\\n' +\n                '  5 - Add lights.\\n' +\n                '  6 - Remove lights.\\n' +\n                '  7 - Turn on lights.\\n' +\n                '  8 - Turn off lights.\\n' +\n                '  0 - Exit.'\n        )\n\n        input = (await rl.question('\\n> Enter an operation: ')).trim()\n    }\n\n    rl.close()\n})()\n"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/typescript/marialunatito.ts",
    "content": "// use this command for run npx ts-node \"Roadmap/48 - ÁRBOL DE NAVIDAD/typescript/marialunatito.ts\"\n\nconst readlline = require(\"readline\").createInterface({\n  input: process.stdin,\n  output: process.stdout,\n});\n\nfunction start() {\n  readlline.question(\n    \"Crea un arbol de navidad, ingresa la altura: \",\n    (height: string) => {\n      const treeModel = new Tree(parseInt(height));\n      treeModel.create();\n      menu(treeModel);\n    }\n  );\n}\n\nfunction menu(tree: Tree) {\n  console.log(`\n    0. Mostrar arbolito\n    1. Añade la estrella en la copa (@)\n    2. Elimina la estrella en la copa (@)\n    3. Añade bolas de dos en dos (o) aleatoriamente\n    4. Elimina bolas de dos en dos (o) aleatoriamente\n    5. Añade luces de tres en tres (+) aleatoriamente\n    6. Eliminar luces de tres en tres (+) aleatoriamente\n    7. Apagar (*) las luces (conservando su posición)\n    8. Encender (+) las luces (conservando su posición)\n    10. Salir del sistema\n    `);\n\n  readlline.question(\"Seleccione una option: \", (option: string) => {\n    switch (option) {\n      case \"0\":\n        console.log(tree.Tree);\n        menu(tree);\n        break;\n      case \"1\":\n        tree.addStart();\n        break;\n      case \"2\":\n        tree.removeStart();\n        break;\n      case \"3\":\n        tree.addBalls();\n        break;\n      case \"4\":\n        tree.removedBalls();\n        break;\n      case \"5\":\n        tree.addLights();\n        break;\n      case \"6\":\n        tree.removeLights();\n        break;\n      case \"7\":\n        tree.turnOff();\n        break;\n      case \"8\":\n        tree.turnOn();\n        break;\n      case \"10\":\n        console.log(\"Ha salido del sistema\");\n        readlline.close();\n        break;\n\n      default:\n        console.log(`La opción ${option} es invalida.. vuelva a intentar`);\n        menu(tree);\n        break;\n    }\n  });\n}\n\nclass Tree {\n  private tree: string;\n  private height: number;\n\n  constructor(height: number) {\n    this.height = height;\n    this.tree = \"\";\n  }\n\n  create() {\n    let space = \"\";\n    let asterisk = \"\";\n\n    //   height = 2\n    for (let i = 1; i <= this.height; i++) {\n      Array.from({ length: this.height - i }).forEach((_) => {\n        space += \" \";\n      });\n\n      Array.from({ length: 2 * i - 1 }).forEach((_) => {\n        asterisk += \"*\";\n      });\n\n      this.tree += `${space}${asterisk}\\n`;\n      space = \"\";\n      asterisk = \"\";\n    }\n\n    let spaceTrunk = \"\";\n\n    Array.from({ length: (2 * this.height - 1 - 3) / 2 }).forEach((_) => {\n      spaceTrunk += \" \";\n    });\n    const trunk = `${spaceTrunk}|||\\n${spaceTrunk}|||`;\n\n    this.tree += trunk;\n    /// RESULT\n    console.log(\"\\n\");\n    console.log(this.tree);\n    console.log(\"\\n\");\n\n    return this.tree;\n  }\n\n  addStart() {\n    if (this.tree.includes(\"@\")) {\n      console.log(\"El tree ya contiene la estrella\");\n    } else {\n      const indexStart = this.getIndexStart();\n      const treeWithStart =\n        this.tree.substring(0, indexStart) +\n        \"@\" +\n        this.tree.substring(indexStart + 1, this.tree.length);\n      this.tree = treeWithStart;\n      console.log(this.tree);\n    }\n\n    menu(this);\n  }\n\n  private getIndexStart() {\n    let index = this.tree.indexOf(\"*\");\n    if (index === -1) {\n      index = this.tree.indexOf(\"+\");\n    }\n    return index;\n  }\n\n  removeStart() {\n    if (this.tree.includes(\"@\")) {\n      const treeWithStart = this.tree.replace(\"@\", \"*\");\n      this.tree = treeWithStart;\n      console.log(this.tree);\n    } else {\n      console.log(\"***********Se quitó la estrella***********\");\n    }\n\n    menu(this);\n  }\n\n  turnOn() {\n    if (this.tree.includes(\"*\")) {\n      this.tree = this.tree.replaceAll(\"*\", \"+\");\n      console.log(this.tree);\n    } else {\n      console.log(\"El arbolito está encendido o tiene bolas!\");\n    }\n\n    menu(this);\n  }\n\n  turnOff() {\n    if (this.tree.includes(\"+\")) {\n      this.tree = this.tree.replaceAll(\"+\", \"*\");\n      console.log(this.tree);\n    } else {\n      console.log(\"El arbolito está apagado!\");\n    }\n\n    menu(this);\n  }\n\n  addBalls() {\n    let count = 0;\n    let canBeBall = false;\n\n    let cant = 0;\n    Array.from({ length: this.tree.length }).forEach((_, i) => {\n      if (this.tree.substring(i, i + 1).includes(\"*\")) {\n        cant++;\n      }\n    });\n\n    if (cant >= 2) {\n      canBeBall = true;\n    } else {\n      canBeBall = false;\n      console.log(\n        \"************Ya no hay espacios posibles para colocar bolas************\"\n      );\n    }\n\n    while (canBeBall) {\n      const index = this.indexRandom();\n      const indexTreeForChange = this.tree.substring(index, index + 1);\n      if (indexTreeForChange.includes(\"*\")) {\n        const newTree =\n          this.tree.substring(0, index) +\n          \"o\" +\n          this.tree.substring(index + 1, this.tree.length);\n\n        // set new tree\n        this.tree = newTree;\n\n        count++;\n        if (count === 2) {\n          // stop the while\n          canBeBall = false;\n        }\n      }\n    }\n\n    console.log(this.tree);\n    menu(this);\n  }\n\n  removedBalls() {\n    let count = 0;\n    let canBeRemoveBall = false;\n\n    let cant = 0;\n    Array.from({ length: this.tree.length }).forEach((_, i) => {\n      if (this.tree.substring(i, i + 1).includes(\"o\")) {\n        cant++;\n      }\n    });\n\n    if (cant >= 2) {\n      canBeRemoveBall = true;\n    } else {\n      canBeRemoveBall = false;\n      console.log(\"************Ya no hay bolas que quitar!************\");\n    }\n\n    while (canBeRemoveBall) {\n      const index = this.indexRandom();\n      const indexTreeForChange = this.tree.substring(index, index + 1);\n      if (indexTreeForChange.includes(\"o\")) {\n        const newTree =\n          this.tree.substring(0, index) +\n          \"*\" +\n          this.tree.substring(index + 1, this.tree.length);\n\n        // set new tree\n        this.tree = newTree;\n\n        count++;\n        if (count === 2) {\n          // stop the while\n          canBeRemoveBall = false;\n        }\n      }\n    }\n\n    console.log(this.tree);\n    menu(this);\n  }\n\n  addLights() {\n    let count = 0;\n    let canBeLights = false;\n\n    let cant = 0;\n    Array.from({ length: this.tree.length }).forEach((_, i) => {\n      if (this.tree.substring(i, i + 1).includes(\"*\")) {\n        cant++;\n      }\n    });\n\n    if (cant >= 3) {\n      canBeLights = true;\n    } else {\n      canBeLights = false;\n      console.log(\n        \"************Ya no hay espacios posibles para colocar más luces************\"\n      );\n    }\n\n    while (canBeLights) {\n      const index = this.indexRandom();\n      const indexTreeForChange = this.tree.substring(index, index + 1);\n      if (indexTreeForChange.includes(\"*\")) {\n        const newTree =\n          this.tree.substring(0, index) +\n          \"+\" +\n          this.tree.substring(index + 1, this.tree.length);\n\n        // set new tree\n        this.tree = newTree;\n\n        count++;\n        if (count === 3) {\n          // stop the while\n          canBeLights = false;\n        }\n      }\n    }\n\n    console.log(this.tree);\n    menu(this);\n  }\n\n  removeLights() {\n    let count = 0;\n    let canBeLights = false;\n\n    let cant = 0;\n    Array.from({ length: this.tree.length }).forEach((_, i) => {\n      if (this.tree.substring(i, i + 1).includes(\"+\")) {\n        cant++;\n      }\n    });\n\n    if (cant >= 3) {\n      canBeLights = true;\n    } else {\n      canBeLights = false;\n      console.log(\"************No hay mas luces que quitar!!************\");\n    }\n\n    while (canBeLights) {\n      const index = this.indexRandom();\n      const indexTreeForChange = this.tree.substring(index, index + 1);\n      if (indexTreeForChange.includes(\"+\")) {\n        const newTree =\n          this.tree.substring(0, index) +\n          \"*\" +\n          this.tree.substring(index + 1, this.tree.length);\n\n        // set new tree\n        this.tree = newTree;\n\n        count++;\n        if (count === 3) {\n          // stop the while\n          canBeLights = false;\n        }\n      }\n    }\n\n    console.log(this.tree);\n    menu(this);\n  }\n\n  private indexRandom(): number {\n    const indexRandom = Math.floor(Math.random() * this.tree.length);\n    const indexStart = this.getIndexStart();\n    if (indexRandom != indexStart) {\n      return indexRandom;\n    }\n    return this.indexRandom();\n  }\n\n  get Tree() {\n    return this.tree;\n  }\n\n  set Tree(tree: string) {\n    this.tree = tree;\n  }\n}\n\nstart();\n"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/typescript/miguelex.ts",
    "content": "import readline from \"readline\";\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\ntype Decorations = Record<number, Record<number, string>>;\n\nfunction createTree(height: number, hasStar: boolean, decorations: Decorations, lightsOn: boolean): string[] {\n    const tree: string[] = [];\n\n    // Estrella opcional\n    if (hasStar) {\n        tree.push(\" \".repeat(height - 1) + \"@\");\n    }\n\n    // Ramas\n    for (let i = 1; i <= height; i++) {\n        let line = \" \".repeat(height - i);\n        for (let j = 0; j < 2 * i - 1; j++) {\n            if (decorations[i] && decorations[i][j]) {\n                line += decorations[i][j];\n            } else {\n                line += \"*\";\n            }\n        }\n        tree.push(line);\n    }\n\n    // Tronco\n    const trunkPadding = \" \".repeat(height - 2);\n    tree.push(trunkPadding + \"|||\");\n    tree.push(trunkPadding + \"|||\");\n\n    return tree;\n}\n\nfunction displayTree(tree: string[]): void {\n    console.log(tree.join(\"\\n\"));\n}\n\nfunction addRandomDecoration(decorations: Decorations, height: number, type: string, count: number): void {\n    let added = 0;\n    while (added < count) {\n        const row = Math.floor(Math.random() * height) + 1;\n        const col = Math.floor(Math.random() * (2 * row - 1));\n\n        if (!decorations[row]) decorations[row] = {};\n        if (!decorations[row][col]) {\n            decorations[row][col] = type;\n            added++;\n        }\n    }\n}\n\nfunction removeRandomDecoration(decorations: Decorations, type: string, count: number): void {\n    let removed = 0;\n    for (const row in decorations) {\n        for (const col in decorations[row]) {\n            if (decorations[row][col] === type && removed < count) {\n                delete decorations[row][col];\n                removed++;\n            }\n        }\n    }\n}\n\nfunction toggleLights(decorations: Decorations, lightsOn: boolean): void {\n    for (const row in decorations) {\n        for (const col in decorations[row]) {\n            if (decorations[row][col] === \"+\") {\n                decorations[row][col] = lightsOn ? \"+\" : \"*\";\n            }\n        }\n    }\n}\n\nfunction promptUser(query: string): Promise<string> {\n    return new Promise(resolve => rl.question(query, resolve));\n}\n\n(async function main() {\n    const height = parseInt(await promptUser(\"Ingrese la altura del árbol: \"), 10);\n    let hasStar = true;\n    let decorations: Decorations = {};\n    let lightsOn = true;\n\n    while (true) {\n        const tree = createTree(height, hasStar, decorations, lightsOn);\n        displayTree(tree);\n\n        console.log(\"\\nOpciones:\");\n        console.log(\"1. Añadir/Eliminar estrella\");\n        console.log(\"2. Añadir bolas (o)\");\n        console.log(\"3. Eliminar bolas (o)\");\n        console.log(\"4. Añadir luces (+)\");\n        console.log(\"5. Eliminar luces (+)\");\n        console.log(\"6. Apagar/Encender luces\");\n        console.log(\"7. Salir\");\n\n        const option = parseInt(await promptUser(\"Seleccione una opción: \"), 10);\n\n        switch (option) {\n            case 1:\n                hasStar = !hasStar;\n                console.log(hasStar ? \"Estrella añadida.\" : \"Estrella eliminada.\");\n                break;\n            case 2:\n                addRandomDecoration(decorations, height, \"o\", 2);\n                console.log(\"Bolas añadidas.\");\n                break;\n            case 3:\n                removeRandomDecoration(decorations, \"o\", 2);\n                console.log(\"Bolas eliminadas.\");\n                break;\n            case 4:\n                addRandomDecoration(decorations, height, \"+\", 3);\n                console.log(\"Luces añadidas.\");\n                break;\n            case 5:\n                removeRandomDecoration(decorations, \"+\", 3);\n                console.log(\"Luces eliminadas.\");\n                break;\n            case 6:\n                lightsOn = !lightsOn;\n                toggleLights(decorations, lightsOn);\n                console.log(lightsOn ? \"Luces encendidas.\" : \"Luces apagadas.\");\n                break;\n            case 7:\n                console.log(\"¡Feliz Navidad!\");\n                rl.close();\n                return;\n            default:\n                console.log(\"Opción no válida.\");\n        }\n    }\n})();\n"
  },
  {
    "path": "Roadmap/48 - ÁRBOL DE NAVIDAD/vb.net/kenysdev.vb",
    "content": "' _____________________________________\n' https://github.com/kenysdev\n' 2024 - vb.net\n' _____________________________________\n' 48 ÁRBOL DE NAVIDAD\n' ------------------------------------\n'* EJERCICIO:\n' * ¡Ha comenzado diciembre! Es hora de montar nuestro\n' * árbol de Navidad...\n' * \n' * Desarrolla un programa que cree un árbol de Navidad\n' * con una altura dinámica definida por el usuario por terminal.\n' * \n' * Ejemplo de árbol de altura 5 (el tronco siempre será igual):\n' * \n' *     *\n' *    ***\n' *   *****\n' *  *******\n' * *********\n' *    |||\n' *    |||\n' *\n' * El usuario podrá seleccionar las siguientes acciones:\n' * \n' * - Añadir o eliminar la estrella en la copa del árbol (@)\n' * - Añadir o eliminar bolas de dos en dos (o) aleatoriamente\n' * - Añadir o eliminar luces de tres en tres (+) aleatoriamente\n' * - Apagar (*) o encender (+) las luces (conservando su posición)\n' * - Una luz y una bola no pueden estar en el mismo sitio\n' *\n' * Sólo puedes añadir una estrella, y tantas luces o bolas\n' * como tengan cabida en el árbol. El programa debe notificar\n' * cada una de las acciones (o por el contrario, cuando no\n' * se pueda realizar alguna).\n\nImports System\nImports System.Threading\nImports System.Collections.Generic\n\nPublic Class ChristmasTree\n    Private ReadOnly _size As Integer\n    Private ReadOnly _matrix(,) As Char\n    Private ReadOnly _starRow As Integer\n    Private ReadOnly _starCol As Integer\n    Private ReadOnly _treeTop As New List(Of Tuple(Of Integer, Integer))\n    Private ReadOnly _balls As New List(Of Tuple(Of Integer, Integer))\n    Private ReadOnly _lights As New List(Of Tuple(Of Integer, Integer))\n\n    Public Sub New(size As Integer)\n        _size = size\n        _matrix = New Char(_size - 1, (size * 2) - 2) {}\n        _starRow = 0\n        _starCol = size - 1\n\n        For i As Integer = 0 To _size - 1\n            For j As Integer = 0 To (size * 2) - 2\n                _matrix(i, j) = \" \"c\n            Next\n        Next\n    End Sub\n\n    Public Sub PrintTree()\n        Console.WriteLine()\n        For i As Integer = 0 To _size - 1\n            For j As Integer = 0 To (_size * 2) - 2\n                Console.Write(_matrix(i, j))\n            Next\n            Console.WriteLine()\n        Next\n\n        Dim spaces As Integer = (_size * 2 - 4) \\ 2\n        Console.WriteLine(New String(\" \"c, spaces) & \"|||\")\n        Console.WriteLine(New String(\" \"c, spaces) & \"|||\")\n    End Sub\n\n    Public Sub CreateTree()\n        Dim center As Integer = _size - 1\n        For i As Integer = 0 To _size - 1\n            Dim asterisks As New String(\"*\"c, (i * 2) + 1)\n            For j As Integer = 0 To asterisks.Length - 1\n                Dim col As Integer = center - i + j\n                _matrix(i, col) = asterisks(j)\n                _treeTop.Add(New Tuple(Of Integer, Integer)(i, col))\n            Next\n        Next\n\n        _treeTop.RemoveAt(0)\n    End Sub\n\n    Public Sub AddRemoveStar()\n        If _matrix(_starRow, _starCol) = \"*\"c Then\n            _matrix(_starRow, _starCol) = \"@\"c\n        Else\n            _matrix(_starRow, _starCol) = \"*\"c\n        End If\n    End Sub\n\n    Public Sub AddBalls()\n        If _treeTop.Count < 2 Then\n            Console.WriteLine(\"Ya no hay espacio para poner bolas.\")\n            Return\n        End If\n\n        Dim rnd As New Random()\n        Dim positions As New List(Of Tuple(Of Integer, Integer))\n        For i As Integer = 0 To 1\n            Dim idx As Integer = rnd.Next(_treeTop.Count)\n            positions.Add(_treeTop(idx))\n            _treeTop.RemoveAt(idx)\n        Next\n\n        For Each pos In positions\n            _balls.Add(pos)\n            _matrix(pos.Item1, pos.Item2) = \"o\"c\n        Next\n    End Sub\n\n    Public Sub RemoveBalls()\n        If _balls.Count = 0 Then\n            Console.WriteLine(\"No hay bolas que eliminar.\")\n            Return\n        End If\n\n        Dim rnd As New Random()\n        Dim positions As New List(Of Tuple(Of Integer, Integer))\n        For i As Integer = 0 To 1\n            If _balls.Count > 0 Then\n                Dim idx As Integer = rnd.Next(_balls.Count)\n                positions.Add(_balls(idx))\n                _balls.RemoveAt(idx)\n            End If\n        Next\n\n        For Each pos In positions\n            _treeTop.Add(pos)\n            _matrix(pos.Item1, pos.Item2) = \"*\"c\n        Next\n    End Sub\n\n    Public Sub AddLights()\n        If _treeTop.Count < 3 Then\n            Console.WriteLine(\"Ya no hay espacio para poner luces.\")\n            Return\n        End If\n\n        Dim rnd As New Random()\n        Dim positions As New List(Of Tuple(Of Integer, Integer))\n        For i As Integer = 0 To 2\n            Dim idx As Integer = rnd.Next(_treeTop.Count)\n            positions.Add(_treeTop(idx))\n            _treeTop.RemoveAt(idx)\n        Next\n\n        For Each pos In positions\n            _lights.Add(pos)\n            _matrix(pos.Item1, pos.Item2) = \"+\"c\n        Next\n    End Sub\n\n    Public Sub RemoveLights()\n        If _lights.Count = 0 Then\n            Console.WriteLine(\"No hay luces que eliminar.\")\n            Return\n        End If\n\n        Dim rnd As New Random()\n        Dim positions As New List(Of Tuple(Of Integer, Integer))\n        For i As Integer = 0 To 2\n            If _lights.Count > 0 Then\n                Dim idx As Integer = rnd.Next(_lights.Count)\n                positions.Add(_lights(idx))\n                _lights.RemoveAt(idx)\n            End If\n        Next\n\n        For Each pos In positions\n            _treeTop.Add(pos)\n            _matrix(pos.Item1, pos.Item2) = \"*\"c\n        Next\n    End Sub\n\n    Public Sub OnOffLights()\n        If _lights.Count = 0 Then\n            Console.WriteLine(\"No hay luces.\")\n            Return\n        End If\n\n        For Each pos In _lights\n            If _matrix(pos.Item1, pos.Item2) = \"*\"c Then\n                _matrix(pos.Item1, pos.Item2) = \"+\"c\n            Else\n                _matrix(pos.Item1, pos.Item2) = \"*\"c\n            End If\n        Next\n    End Sub\n\n    Public Sub AutomaticLights()\n        While True\n            Console.Clear()\n            For Each pos In _lights\n                If _matrix(pos.Item1, pos.Item2) = \"*\"c Then\n                    _matrix(pos.Item1, pos.Item2) = \"+\"c\n                Else\n                    _matrix(pos.Item1, pos.Item2) = \"*\"c\n                End If\n            Next\n            PrintTree()\n            Thread.Sleep(1000)\n        End While\n    End Sub\nEnd Class\n\nPublic Module Program\n    Private Const MenuText As String = \"\n1 - Agregar/Remover estrella.\n2 - Agregar bolas.    | 3 - Quitar bolas.\n4 - Agregar luces.    | 5 - Quitar luces.\n6 - Encender/Apagar luces.\n7 - Luces automáticas.| 8 - Salir\n\"\n\n    Private Sub ShowMenu(tree As ChristmasTree)\n        While True\n            tree.PrintTree()\n            Console.WriteLine(MenuText)\n            Console.Write(\"Opción: \")\n            Dim option_ As String = Console.ReadLine()\n\n            Select Case option_\n                Case \"1\"\n                    tree.AddRemoveStar()\n                Case \"2\"\n                    tree.AddBalls()\n                Case \"3\"\n                    tree.RemoveBalls()\n                Case \"4\"\n                    tree.AddLights()\n                Case \"5\"\n                    tree.RemoveLights()\n                Case \"6\"\n                    tree.OnOffLights()\n                Case \"7\"\n                    tree.AutomaticLights()\n                Case \"8\"\n                    Return\n                Case Else\n                    Console.WriteLine(\"Opción inválida.\")\n            End Select\n        End While\n    End Sub\n\n    Private Function GetSize() As Integer\n        While True\n            Console.Write(\"Tamaño: \")\n            Dim sizeStr As String = Console.ReadLine()\n            Dim size As Integer\n\n            If Integer.TryParse(sizeStr, size) AndAlso size Mod 2 <> 0 AndAlso size >= 3 Then\n                Return size\n            End If\n\n            Console.WriteLine(\"Debe ser un número impar >= 3.\")\n        End While\n        Return 3\n    End Function\n\n    Public Sub Main()\n        Dim size As Integer = GetSize()\n        Dim christmasTree As New ChristmasTree(size)\n        christmasTree.CreateTree()\n        ShowMenu(christmasTree)\n    End Sub\nEnd Module\n"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/c#/hequebo.cs",
    "content": "class Program\n{\n    static void Main(string[] args)\n    {\n        Random random = new Random();\n        List<char> chars = new List<char>{ 'a', 'b', 'c', '1', '2', '3' };\n        var secretPassword = string.Join(\"\", chars.OrderBy(c =>  random.Next()).ToList().Slice(0, 4));\n\n        int attempts = 0;\n\n        while (attempts < 10)\n        {\n            Console.WriteLine($\"----INTENTO {attempts + 1}----\");\n            Console.WriteLine(\"Ingresa la contraseña\");\n            string? password = Console.ReadLine();\n            attempts++;\n            if (string.IsNullOrEmpty(password))\n            {\n                Console.WriteLine(\"No se ingreso ninguna contraseña...\");\n                continue;\n            }\n            if (password.Length != 4)\n            {\n                Console.WriteLine(\"La contraseña debe de ser de 4 caracteres...\");\n                continue;\n            }\n            if (password.Where(p => chars.Contains(p)).Count() != 4)\n            {\n                Console.WriteLine($\"La contraseña solo permite los siguientes carácters: {string.Join(\",\", chars)}\");\n                continue;\n            }\n            if (password == secretPassword)\n            {\n                Console.WriteLine(\"¡Contraseña correcta!\");\n                break;\n            }\n            else\n            {\n                foreach ((char c, int index) in password.Select((item, index) => (item, index)))\n                {\n                    if (c == secretPassword[index])\n                        Console.WriteLine($\"{c}: Correcto.\");\n                    else if (secretPassword.Contains(c))\n                        Console.WriteLine($\"{c}: Se encuentra en la contraseña.\");\n                    else\n                        Console.WriteLine($\"{c}: Incorecto\");\n                }\n            }\n        }\n        if (attempts >= 10)\n            Console.WriteLine(\"Se han fallado los 10 intentos\");\n    }\n}"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/c#/kenysdev.cs",
    "content": "namespace exs49;\n/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - C#\n_____________________________________\n#49 EL ALMACÉN DE PAPÁ NOEL\n------------------------------------\n\n* EJERCICIO:\n * Papá Noel tiene que comenzar a repartir los regalos...\n * ¡Pero ha olvidado el código secreto de apertura del almacén!\n *\n * Crea un programa donde introducir códigos y obtener pistas.\n * \n * Código:\n * - El código es una combinación de letras y números aleatorios\n *   de longitud 4. (Letras: de la A a la C, Números: del 1 al 3)\n * - No hay repetidos.\n * - Se genera de manera aleatoria al iniciar el programa.\n * \n * Usuario:\n * - Dispone de 10 intentos para acertarlo.\n * - En cada turno deberá escribir un código de 4 caracteres, y \n *   el programa le indicará para cada uno lo siguiente:\n *   - Correcto: Si el caracter está en la posición correcta.\n *   - Presente: Si el caracter existe, pero esa no es su posición.\n *   - Incorrecto: Si el caracter no existe en el código secreto.\n * - Deben controlarse errores de longitud y caracteres soportados.\n * \n * Finalización:\n * - Papa Noel gana si descrifra el código antes de 10 intentos.\n * - Pierde si no lo logra, ya que no podría entregar los regalos.\n*/\n\nusing System;\nusing System.Linq;\n\nclass Program\n{\n    static bool VerifyAllowedChar(string codeEntry)\n    {\n        foreach (char ch in codeEntry)\n        {\n            if (!\"abc123\".Contains(ch))\n            {\n                Console.WriteLine(\"Uno de los caracteres no está entre los permitidos.\\n\");\n                return false;\n            }\n        }\n        return true;\n    }\n\n    static string GetEntry()\n    {\n        while (true)\n        {\n            Console.Write(\"Código: \");\n            string? codeEntry = Console.ReadLine();\n\n            if (string.IsNullOrEmpty(codeEntry) || codeEntry.Length != 4)\n            {\n                Console.WriteLine(\"El código debe ser de 4 dígitos.\\n\");\n                continue;\n            }\n\n            if (VerifyAllowedChar(codeEntry))\n            {\n                return codeEntry;\n            }\n        }\n    }\n\n    static bool IsOpen(string code)\n    {\n        string codeEntry = GetEntry();\n\n        if (codeEntry == code)\n        {\n            return true;\n        }\n\n        Console.WriteLine(\"Código inválido.\\n\");\n\n        for (int i = 0; i < codeEntry.Length; i++)\n        {\n            char ch = codeEntry[i];\n\n            if (ch == code[i])\n            {\n                Console.WriteLine($\"'{ch}' está en la posición correcta.\");\n            }\n            else if (code.Contains(ch))\n            {\n                Console.WriteLine($\"'{ch}' está en el código, pero en otra posición.\");\n            }\n            else\n            {\n                Console.WriteLine($\"'{ch}' no está presente en el código.\");\n            }\n        }\n\n        return false;\n    }\n\n    static void Main()\n    {\n        Console.WriteLine(@\"\n* Papá Noel tiene que comenzar a repartir los regalos...\n* ¡Pero ha olvidado el código secreto de apertura del almacén!\n\n- Tienes 10 intentos para adivinar el código que abre el almacén.\n- Código de 4 caracteres. Permitidos: a, b, c, 1, 2, 3.\n- Nota: No hay dígitos repetidos.\");\n\n        Random random = new();\n        string characters = \"abc123\";\n        string code = new(characters.OrderBy(x => random.Next()).Take(4).ToArray());\n\n        for (int attempts = 1; attempts < 11; attempts++)\n        {\n            Console.WriteLine($\"\\n___________\\nIntento #{attempts}\");\n\n            if (IsOpen(code))\n            {\n                Console.WriteLine(\"Código correcto, almacén abierto.\");\n                Console.WriteLine(\"Papá Noel ahora podrá entregar los regalos.\");\n                break;\n            }\n\n            if (attempts == 10)\n            {\n                Console.WriteLine(\"\\n___________\\nHas perdido.\");\n                Console.WriteLine(\"Papá Noel ya no podrá entregar los regalos.\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/c++/EdiedRamos.cpp",
    "content": "// * EdiedRamos\n\n#include <iostream>\n#include <time.h>\n#include <stdlib.h>\n\nusing namespace std;\n\n#define OPTIONS {'A', 'B', 'C', '1', '2', '3'}\n\nconst int codeLength = 4;\n\nstring createCode()\n{\n  string code = \"\";\n\n  char options[] = OPTIONS;\n  const int optionsLength = sizeof(options) / sizeof(options[0]);\n\n  srand(time(NULL));\n  for (int i = optionsLength - 1; i > 0; i--)\n  {\n    int random = rand() % (i + 1);\n    swap(options[i], options[random]);\n  }\n\n  for (int i = 0; i < codeLength; i++)\n    code += options[i];\n\n  return code;\n}\n\nchar toUpper(char c)\n{\n  return c >= 'a' && c <= 'z' ? c & 0x5F : c;\n}\n\nvoid toUpper(string &s)\n{\n  for (char &c : s)\n    c = toUpper(c);\n}\n\nbool isCorrectFormat(string code)\n{\n  if (code.size() != codeLength)\n    return false;\n\n  char options[] = OPTIONS;\n  bool characterExists;\n  for (char codeCharacter : code)\n  {\n    characterExists = false;\n    for (char optionCharacter : options)\n      if (toUpper(codeCharacter) == optionCharacter)\n      {\n        characterExists = true;\n        break;\n      }\n    if (!characterExists)\n      return false;\n  }\n\n  return true;\n}\n\nbool contains(string a, char b)\n{\n  for (char c : a)\n    if (c == b)\n      return true;\n  return false;\n}\n\nvoid start()\n{\n  const string secretCode = createCode();\n  const int maxAttempts = 10;\n  int attempts = 1;\n  string userCode = \"\";\n  bool codeChecked;\n  while (attempts <= maxAttempts)\n  {\n    codeChecked = false;\n    cout << \"Intento #\" << attempts << endl;\n    while (!codeChecked)\n    {\n      cout << \"Ingrese un código de 4 caracteres utilizando [ABC123]:\";\n      getline(cin, userCode);\n      codeChecked = isCorrectFormat(userCode);\n      if (!codeChecked)\n        cout << \"El código ingresado no cumple el formato\" << endl;\n    }\n    toUpper(userCode);\n\n    if (userCode == secretCode)\n    {\n      cout << \"Código encontrado en \" << attempts << \" intentos.\" << endl;\n      break;\n    }\n\n    for (int i = 0; i < codeLength; i++)\n    {\n      cout << userCode[i] << \": \";\n      if (secretCode[i] == userCode[i])\n        cout << \"Correcto\" << endl;\n      else if (contains(secretCode, userCode[i]))\n        cout << \"Presente\" << endl;\n      else\n        cout << \"Incorrecto\" << endl;\n    }\n\n    attempts++;\n  }\n\n  if (attempts > maxAttempts)\n    cout << \"El código no fue encontrado\" << endl;\n}\n\nint main()\n{\n  start();\n  return 0;\n}"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/c++/hectorio23.cpp",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\n#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm> // Para std::shuffle\n#include <random>    // Para std::default_random_engine\n#include <string>\n#include <unordered_set>\n\nstd::string generateSecretCode() {\n    std::vector<char> pool = {'A', 'B', 'C', '1', '2', '3'};\n    std::random_device rd;                         // Generador de números aleatorios basado en hardware\n    std::default_random_engine rng(rd());         // Motor de generación de números aleatorios\n    std::shuffle(pool.begin(), pool.end(), rng);  // Usa std::shuffle con un motor RNG\n\n    return std::string(pool.begin(), pool.begin() + 4); // Combina los primeros 4 caracteres en un string\n}\n\nvoid evaluateGuess(const std::string &secret, const std::string &guess) {\n    for (int i = 0; i < 4; i++) {\n        if (guess[i] == secret[i]) {\n            std::cout << guess[i] << \": Correcto\" << std::endl;\n        } else if (find(secret.begin(), secret.end(), guess[i]) != secret.end()) {\n            std::cout << guess[i] << \": Presente\" << std::endl;\n        } else {\n            std::cout << guess[i] << \": Incorrecto\" << std::endl;\n        }\n    }\n}\n\nbool isValidGuess(const std::string &guess) {\n    if (guess.length() != 4) {\n        std::cout << \"El código debe tener exactamente 4 caracteres.\" << std::endl;\n        return false;\n    }\n\n    std::unordered_set<char> validChars = {'A', 'B', 'C', '1', '2', '3'};\n    for (char c : guess) {\n        if (validChars.find(c) == validChars.end()) {\n            std::cout << \"Caracter inválido encontrado: \" << c << std::endl;\n            return false;\n        }\n    }\n\n    return true;\n}\n\nint main() {\n    srand(static_cast<unsigned>(time(0)));\n    std::string secretCode = generateSecretCode();\n    int attempts = 10;\n\n    std::cout << \"\\n¡Bienvenido al juego del código secreto de Papá Noel!\\n\";\n    std::cout << \"Debes adivinar el código secreto de 4 caracteres.\\n\";\n    std::cout << \"Letras: A, B, C | Números: 1, 2, 3\\n\";\n\n    while (attempts > 0) {\n        std::cout << \"\\nIntentos restantes: \" << attempts << std::endl;\n        std::cout << \"Introduce tu código: \";\n        std::string guess;\n        std::cin >> guess;\n\n        if (!isValidGuess(guess)) {\n            continue;\n        }\n\n        if (guess == secretCode) {\n            std::cout << \"¡Felicidades! Has descifrado el código secreto: \" << secretCode << std::endl;\n            return 0;\n        }\n\n        evaluateGuess(secretCode, guess);\n        attempts--;\n    }\n\n    std::cout << \"\\nLo siento, no has logrado descifrar el código secreto. Era: \" << secretCode << std::endl;\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/ejercicio.md",
    "content": "# #49 EL ALMACÉN DE PAPÁ NOEL\n> #### Dificultad: Media | Publicación: 09/12/24 | Corrección: 23/12/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Papá Noel tiene que comenzar a repartir los regalos...\n * ¡Pero ha olvidado el código secreto de apertura del almacén!\n *\n * Crea un programa donde introducir códigos y obtener pistas.\n * \n * Código:\n * - El código es una combinación de letras y números aleatorios\n *   de longitud 4. (Letras: de la A a la C, Números: del 1 al 3)\n * - No hay repetidos.\n * - Se genera de manera aleatoria al iniciar el programa.\n * \n * Usuario:\n * - Dispone de 10 intentos para acertarlo.\n * - En cada turno deberá escribir un código de 4 caracteres, y \n *   el programa le indicará para cada uno lo siguiente:\n *   - Correcto: Si el caracter está en la posición correcta.\n *   - Presente: Si el caracter existe, pero esa no es su posición.\n *   - Incorrecto: Si el caracter no existe en el código secreto.\n * - Deben controlarse errores de longitud y caracteres soportados.\n * \n * Finalización:\n * - Papa Noel gana si descifra el código antes de 10 intentos.\n * - Pierde si no lo logra, ya que no podría entregar los regalos.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/go/hozlucas28.go",
    "content": "package main\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"math/rand/v2\"\n\t\"os\"\n\t\"regexp\"\n\t\"strings\"\n)\n\n/* -------------------------------------------------------------------------- */\n/*                                   CLASSES                                  */\n/* -------------------------------------------------------------------------- */\n\n/* ---------------------------- PasswordGenerator --------------------------- */\n\ntype passwordGenerator struct {\n\t_hash        string\n\tfailAttempts uint\n\tlength       uint\n\tpassword     string\n\t_            struct{}\n}\n\ntype PasswordGenerator interface {\n\tGetFailAttempts() uint\n\tGetMaximumLength() uint\n\n\tGetAdvice(password string) string\n\tIsThePassword(password string) bool\n}\n\nfunc NewPasswordGenerator(_hash string, length uint) PasswordGenerator {\n\tvar passwordGenerator passwordGenerator = passwordGenerator{\n\t\t_hash:  _hash,\n\t\tlength: length,\n\t}\n\n\tfor len(passwordGenerator.password) < int(length) {\n\t\tvar rndChar rune = (rune)(_hash[rand.IntN(len(_hash))])\n\t\tif !strings.ContainsRune(passwordGenerator.password, rndChar) {\n\t\t\tpasswordGenerator.password += (string)(rndChar)\n\t\t}\n\t}\n\n\treturn &passwordGenerator\n}\n\nfunc (generator *passwordGenerator) GetFailAttempts() uint {\n\treturn generator.failAttempts\n}\n\nfunc (generator *passwordGenerator) GetMaximumLength() uint {\n\treturn generator.length\n}\n\nfunc (generator *passwordGenerator) GetAdvice(password string) string {\n\tvar advice []string\n\n\tfor i, char := range password {\n\t\tvar passwordChar rune = (rune)(generator.password[i])\n\n\t\tif char == passwordChar {\n\t\t\tadvice = append(advice, fmt.Sprintf(\"  - \\\"%c\\\" is in the correct position.\", char))\n\t\t\tcontinue\n\t\t}\n\n\t\tif strings.ContainsRune(generator.password, char) {\n\t\t\tadvice = append(advice, fmt.Sprintf(\"  - \\\"%c\\\" exist but it's not in the %dth position.\", char, i+1))\n\t\t\tcontinue\n\t\t}\n\n\t\tadvice = append(advice, fmt.Sprintf(\"  - \\\"%c\\\" not exist in the password.\", char))\n\t}\n\n\treturn strings.Join(advice, \"\\n\")\n}\n\nfunc (generator *passwordGenerator) IsThePassword(password string) bool {\n\tif generator.password == password {\n\t\treturn true\n\t}\n\n\tgenerator.failAttempts++\n\treturn false\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\nfunc main() {\n\tvar _hash string = \"ABC123\"\n\tvar length uint = 4\n\n\tvar passwordGenerator PasswordGenerator = NewPasswordGenerator(\n\t\t_hash,\n\t\tlength,\n\t)\n\n\tregex, err := regexp.Compile(fmt.Sprintf(\"^[%s]{%d}$\", _hash, length))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tvar reader *bufio.Reader = bufio.NewReader(os.Stdin)\n\n\tfmt.Printf(\"> Enter the password (maximum of 4 chars): \")\n\tuserInput, err := reader.ReadString('\\n')\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tuserInput = strings.TrimSpace(userInput)\n\n\tfor !regex.MatchString(userInput) {\n\t\tfmt.Printf(\n\t\t\t\"\\n> Error! The password length must be 4 characters, \"+\n\t\t\t\t\"and it should contain any of these characters: \\\"%s\\\". Try again...\",\n\t\t\t_hash,\n\t\t)\n\n\t\tfmt.Printf(\"\\n\\n> Enter the password (maximum of 4 chars): \")\n\t\tuserInput, err = reader.ReadString('\\n')\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\n\t\tuserInput = strings.TrimSpace(userInput)\n\t}\n\n\tfor !passwordGenerator.IsThePassword(userInput) && passwordGenerator.GetFailAttempts() < 10 {\n\t\tfmt.Printf(\"\\n%s\", passwordGenerator.GetAdvice(userInput))\n\n\t\tfmt.Println(\"\\n\\n> Invalid password! Try again...\")\n\n\t\tfmt.Printf(\"\\n> Enter the password (maximum of 4 chars): \")\n\t\tuserInput, err = reader.ReadString('\\n')\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\n\t\tuserInput = strings.TrimSpace(userInput)\n\n\t\tfor !regex.MatchString(userInput) {\n\t\t\tfmt.Printf(\n\t\t\t\t\"\\n> Error! The password length must be 4 characters, \"+\n\t\t\t\t\t\"and it should contain any of these characters: \\\"%s\\\". Try again...\",\n\t\t\t\t_hash,\n\t\t\t)\n\n\t\t\tfmt.Printf(\"\\n\\n> Enter the password (maximum of 4 chars): \")\n\t\t\tuserInput, err = reader.ReadString('\\n')\n\t\t\tif err != nil {\n\t\t\t\tpanic(err)\n\t\t\t}\n\n\t\t\tuserInput = strings.TrimSpace(userInput)\n\t\t}\n\t}\n\n\tif passwordGenerator.GetFailAttempts() < 10 {\n\t\tfmt.Printf(\"\\n> Santa won! The password is \\\"%s\\\".\", userInput)\n\t} else {\n\t\tfmt.Println(\"\\n> Santa lost! Storage will be closed forever.\")\n\t}\n}\n"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/java/JesusWay69.java",
    "content": "package roadmap.ejercicio_49;\nimport java.util.Arrays;\nimport java.util.HashSet;\nimport java.util.Scanner;\n\n/*\n * EJERCICIO: Papá Noel tiene que comenzar a repartir los regalos... ¡Pero ha\n * olvidado el código secreto de apertura del almacén!\n *\n * Crea un programa donde introducir códigos y obtener pistas.\n *\n * Código: - El código es una combinación de letras y números aleatorios de\n * longitud 4. (Letras: de la A a la C, Números: del 1 al 3) - No hay repetidos.\n * - Se genera de manera aleatoria al iniciar el programa.\n *\n * Usuario: - Dispone de 10 intentos para acertarlo. - En cada turno deberá\n * escribir un código de 4 caracteres, y el programa le indicará para cada uno\n * lo siguiente: - Correcto: Si el caracter está en la posición correcta. -\n * Presente: Si el caracter existe, pero esa no es su posición. - Incorrecto: Si\n * el caracter no existe en el código secreto. - Deben controlarse errores de\n * longitud y caracteres soportados.\n *\n * Finalización: - Papa Noel gana si descrifra el código antes de 10 intentos. -\n * Pierde si no lo logra, ya que no podría entregar los regalos.\n */\npublic class JesusWay69 {\n\n    public static void main(String[] args) {\n\n        Character hiddenCode[] = {'?', '?', '?', '?'};\n        final char allow[] = {'A', 'B', 'C', '1', '2', '3'};\n        int attempts = 10;\n        Scanner sc = new Scanner(System.in);\n        var  password = new HashSet<Character>();\n        while (password.size() < 4) password.add(allow[(char) (Math.random() * 6)]);\n        \n        System.out.println(\"Introduzca una clave de 4 caracteres que contenga A, B, C, 1, 2 0 3 sin repeticiones: \");\n\n        while (attempts > 0) {\n            System.out.print(\"Introduzca la clave: \");\n            String attempt = sc.next().toUpperCase();\n            if (attempt.matches(\"[A-C1-3]{4}\")) {\n                    int i =0;\n                    for (char key : password) {\n                        if (attempt.charAt(i) == key) {\n                            System.out.println(\"El caracter \" + attempt.charAt(i) + \" está en la contraseña en su posición \");\n                            hiddenCode[i] = attempt.charAt(i);\n                        } else if (password.contains(attempt.charAt(i))) {\n                            System.out.println(\"El caracter \" + attempt.charAt(i) + \" está en la contraseña pero no lo has puesto en su posición\");\n                        } else {\n                            System.out.println(\"El caracter \" + attempt.charAt(i) + \" no está en la contraseña\");\n                        }\n                            i++;\n                    }\n                    \n                    System.out.print(\"Contraseña: \");\n                    for (char element : hiddenCode) System.out.print(element + \" \");\n                    if (!Arrays.asList(hiddenCode).contains('?')){\n                        System.out.println(\"\\n\\n¡¡ENHORABUENA, HAS ADIVINADO LA CONTRASEÑA!!\");\n                        System.out.println(\"\\n      *****FELIZ NAVIDAD*****\\n\");\n                        break;\n                    }\n\n            } else {\n                System.out.println(\"\\nEl código introducido tiene una longitud diferente a 4 o tiene algún caracter no válido.\");\n            }\n            attempts--;\n            if (attempts > 0) System.out.println((attempts > 1) ? \"\\nTe quedan \" + attempts + \" intentos\"  : \"\\nTe queda 1 intento\");\n            if (attempts == 0) System.out.println(\"\\n\\nSe te han acabado los intentos, Papá Noel no podrá entregar los regalos 😔\"); \n        }\n\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/java/JohnAlexGuerrero.java",
    "content": "/*\n * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license\n */\n\npackage com.mycompany.codesecretchristmas;\n\nimport java.util.HashSet;\nimport java.util.Scanner;\nimport java.util.Set;\n\n/**\n *\n * @author JOHN\n * * EJERCICIO:\n * Papá Noel tiene que comenzar a repartir los regalos...\n * ¡Pero ha olvidado el código secreto de apertura del almacén!\n *\n * Crea un programa donde introducir códigos y obtener pistas.\n *\n * Código:\n * x El código es una combinación de letras y números aleatorios\n *   de longitud 4. (Letras: de la A a la C, Números: del 1 al 3)\n * x No hay repetidos.\n * x Se genera de manera aleatoria al iniciar el programa.\n *\n * Usuario:\n * x Dispone de 10 intentos para acertarlo.\n * x En cada turno deberá escribir un código de 4 caracteres, y\n *   el programa le indicará para cada uno lo siguiente:\n *   - Correcto: Si el caracter está en la posición correcta.\n *   - Presente: Si el caracter existe, pero esa no es su posición.\n *   - Incorrecto: Si el caracter no existe en el código secreto.\n * - Deben controlarse errores de longitud y caracteres soportados.\n *\n * Finalización:\n * - Papa Noel gana si descrifra el código antes de 10 intentos.\n * - Pierde si no lo logra, ya que no podría entregar los regalos.\n\n */\n\npublic class CodeSecretChristmas {\n    static int attemps = 10;\n    \n    public static String[] getLetters(){\n        String[] letters = {\"A\",\"B\",\"C\",\"1\",\"2\",\"3\"};\n        \n        return letters;\n    }\n    \n    public static String generatedKey(){\n        Set<String> key = new HashSet<>();\n        String[] ls = getLetters();\n        \n        while(key.size() < 4){\n            int number = (int) (Math.random()* ls.length);\n            key.add(ls[number]);\n        }\n        String s = String.join(\"\", key);\n        \n        return s;\n    }\n    \n    \n    public static String validKey(String keyGenerated, char character, int index){\n        String flap = \"\";\n        if(keyGenerated.charAt(index) == character && keyGenerated.indexOf(\"\"+character) == index){\n            flap = \"c\";\n        }else if(keyGenerated.contains(\"\"+character)){\n            flap = \"p\";\n        }else{\n            flap = \"i\";\n        }\n        return flap;\n    }\n    \n    public static boolean isValid(String code){\n        boolean f = false;\n        for(int x=0; x < getLetters().length; x++){\n            if(code.contains(getLetters()[x])){\n                f = true;\n            }else{\n                f = false;\n            }\n        }\n        \n        return f;\n    }\n\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n        String code;\n        String keyGenerated = generatedKey();\n        \n        System.out.println(\"Almacen de Santa\");\n        \n        while(attemps < 11){\n            \n            System.out.println(\"Ingresa codigo de seguridad: \");\n            code = scanner.nextLine().toUpperCase();\n            \n            while(!isValid(code)){\n                System.out.println(\"Ingresa codigo de seguridad (A,B,C y 1, 2, 3): \");\n                code = scanner.nextLine().toUpperCase();\n                System.out.println(\"Hay uno o mas caracter(es) que no son permitidos\");\n                System.out.printf(\"son permitidos: \");\n                for(String k: getLetters()){\n                    System.out.printf(k+\", \");\n                    \n                }\n                System.out.println(\"\");\n            }\n            \n            \n            if(code.length() == 4){\n               for(int i=0; i<4; i++){\n                    switch(validKey(keyGenerated,code.charAt(i), i)){\n                        case \"c\":\n                            System.out.println(\"Correcto: \"+code.charAt(i));\n                            break;\n                        case \"p\":\n                            System.out.println(\"Presente: \"+code.charAt(i));\n                            break;\n                        case \"i\":\n                            System.out.println(code.charAt(i)+ \" No concuerda con el codigo generado.\");\n                            break;\n                    }\n               } \n            }else{\n                System.out.println(\"el codigo debe contener solo 4 caracteres\");\n                System.out.println(\"codigo: \"+code.toLowerCase());\n            }\n            \n            if(keyGenerated.equals(\"\"+code)){\n                System.out.println(\"Acceso concedido clave: \"+keyGenerated);\n            }else{\n                attemps -= 1;\n                System.out.println(\"Te quedan #\"+attemps+\" intentos\");\n            }\n        }\n\n    }\n}\n"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/java/Josegs95.java",
    "content": "import java.util.*;\n\npublic class Josegs95 {\n    public static void main(String[] args) {\n        new Josegs95().warehouseCombination();\n    }\n\n    private List<String> validCharacters;\n    private String warehouseCode;\n\n    public void warehouseCombination(){\n        validCharacters = Arrays.asList(\"A\", \"B\", \"C\", \"1\", \"2\", \"3\");\n        warehouseCode = generateCode();\n\n        int nTries = 10;\n        while(nTries > 0){\n            System.out.println(\"Intentos: \" + nTries);\n            String userInputCode = askCodeToUser();\n            if (warehouseCode.equals(userInputCode))\n                break;\n            analyzeUserCode(userInputCode);\n            nTries--;\n        }\n\n        if (nTries == 0)\n            System.out.println(\"¡Has perdido! Papá Noel ya no tiene tiempo para repartir los regalos...\");\n        else\n            System.out.println(\"¡Felicidades, has acertado el código en \" + (11 - nTries) + \" intento/s!\");\n    }\n\n    private String askCodeToUser(){\n        Scanner sc = new Scanner(System.in);\n        boolean validInput = false;\n        String input = \"\";\n\n        loop:\n        while(!validInput){\n            System.out.print(\"Introduzca un código (4 carácteres, solo A-C y 1-3): \");\n            input = sc.nextLine().toUpperCase();\n            if (input.length() != 4){\n                System.out.println(\"Error. El código debe tener 4 carácteres\");\n                continue;\n            }\n            for (String character : input.split(\"\")){\n                if (!validCharacters.contains(character)){\n                    System.out.println(\"Error. El código solo puede contener: 'A', 'B', 'C', '1', '2' o '3'\");\n                    continue loop;\n                }\n                if (input.indexOf(character) != input.lastIndexOf(character)){\n                    System.out.println(\"Error. El código no puede contener carácteres repetidos\");\n                    continue loop;\n                }\n            }\n            validInput = true;\n        }\n\n        return input;\n    }\n\n    private void analyzeUserCode(String code){\n        for (String character : code.split(\"\")){\n            if (!warehouseCode.contains(character)){\n                System.out.println(\"El carácter '\" + character + \"' NO EXISTE en el código secreto\");\n                continue;\n            }\n            int index = code.indexOf(character);\n            if (warehouseCode.indexOf(character) == index){\n                System.out.println(\"El carácter '\" + character + \"' EXISTE en el código secreto \" +\n                        \"y ESTÁ en el lugar correcto\");\n                continue;\n            }\n            System.out.println(\"El carácter '\" + character + \"' EXISTE en el código secreto \" +\n                    \"pero NO ESTÁ en el lugar correcto\");\n        }\n        System.out.println();\n    }\n\n    private String generateCode(){\n        Collections.shuffle(validCharacters);\n        return validCharacters.subList(0, 4).stream()\n                .reduce(String::concat)\n                .get();\n    }\n}\n"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/java/MohamedElderkaoui.java",
    "content": "import java.util.*;\n\npublic class MohamedElderkaoui {\n    public static void main(String[] args) {\n        /*\n * EJERCICIO:\n * Papá Noel tiene que comenzar a repartir los regalos...\n * ¡Pero ha olvidado el código secreto de apertura del almacén!\n *\n * Crea un programa donde introducir códigos y obtener pistas.\n * \n * Código:\n * - El código es una combinación de letras y números aleatorios\n *   de longitud 4. (Letras: de la A a la C, Números: del 1 al 3)\n * - No hay repetidos.\n * - Se genera de manera aleatoria al iniciar el programa.\n * \n * Usuario:\n * - Dispone de 10 intentos para acertarlo.\n * - En cada turno deberá escribir un código de 4 caracteres, y \n *   el programa le indicará para cada uno lo siguiente:\n *   - Correcto: Si el caracter está en la posición correcta.\n *   - Presente: Si el caracter existe, pero esa no es su posición.\n *   - Incorrecto: Si el caracter no existe en el código secreto.\n * - Deben controlarse errores de longitud y caracteres soportados.\n * \n * Finalización:\n * - Papa Noel gana si descrifra el código antes de 10 intentos.\n * - Pierde si no lo logra, ya que no podría entregar los regalos.\n */\n\n // Aquí va tu código...\n\n String secretCode = generateSecretCode();\n System.out.println(\"¡El almacén de Papá Noel está cerrado!\");\n System.out.println(\"Intenta adivinar el código secreto de 4 caracteres (Letras: A-C, Números: 1-3).\");\n System.out.println(\"Tienes 10 intentos. ¡Buena suerte!\");\n \n Scanner scanner = new Scanner(System.in);\n int attempts = 0;\n boolean hasGuessed = false;\n\n while (attempts < 10 && !hasGuessed) {\n     System.out.printf(\"Intento %d/10: \", attempts + 1);\n     String userInput = scanner.nextLine().toUpperCase();\n\n     // Validar entrada del usuario\n     if (!isValidInput(userInput)) {\n         System.out.println(\"Entrada inválida. Asegúrate de que sea de 4 caracteres (A-C y 1-3) sin repetidos.\");\n         continue;\n     }\n\n     // Evaluar el intento\n     String feedback = evaluateGuess(userInput, secretCode);\n     System.out.println(feedback);\n\n     if (userInput.equals(secretCode)) {\n         hasGuessed = true;\n     } else {\n         attempts++;\n     }\n }\n\n // Resultado final\n if (hasGuessed) {\n     System.out.println(\"¡Felicidades! Has descifrado el código secreto y salvado la Navidad. 🎅🎁\");\n } else {\n     System.out.println(\"Oh no, no has logrado descifrar el código. 😔 El código era: \" + secretCode);\n }\n\n scanner.close();\n}\n\n// Genera un código secreto de 4 caracteres aleatorios sin repetidos\nprivate static String generateSecretCode() {\n List<Character> pool = Arrays.asList('A', 'B', 'C', '1', '2', '3');\n Collections.shuffle(pool);\n StringBuilder code = new StringBuilder();\n for (int i = 0; i < 4; i++) {\n     code.append(pool.get(i));\n }\n return code.toString();\n}\n\n// Valida que la entrada del usuario sea de 4 caracteres, sin repetidos y permitidos\nprivate static boolean isValidInput(String input) {\n if (input.length() != 4) {\n     return false;\n }\n Set<Character> validChars = new HashSet<>(Arrays.asList('A', 'B', 'C', '1', '2', '3'));\n Set<Character> seenChars = new HashSet<>();\n for (char c : input.toCharArray()) {\n     if (!validChars.contains(c) || seenChars.contains(c)) {\n         return false;\n     }\n     seenChars.add(c);\n }\n return true;\n}\n\n// Evalúa el intento del usuario y genera pistas\nprivate static String evaluateGuess(String guess, String secretCode) {\n StringBuilder feedback = new StringBuilder();\n for (int i = 0; i < guess.length(); i++) {\n     char userChar = guess.charAt(i);\n     if (userChar == secretCode.charAt(i)) {\n         feedback.append(userChar).append(\": Correcto \");\n     } else if (secretCode.indexOf(userChar) != -1) {\n         feedback.append(userChar).append(\": Presente \");\n     } else {\n         feedback.append(userChar).append(\": Incorrecto \");\n     }\n }\n return feedback.toString().trim();\n}\n}"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/java/alb-martinez.java",
    "content": "import java.util.*;\n\npublic class alb-martinez {\n\n    public static void main(String[] args) {\n\n        Scanner scanner = new Scanner(System.in);\n\n        // Generación del código secreto aleatorio\n        String secretCode = generateSecretCode();\n\n        // Contador de intentos\n        int attempts = 0;\n        boolean guessedCorrectly = false;\n\n        // Bucle hasta que el usuario se quede sin intentos o adivine el código\n        while (attempts < 10 && !guessedCorrectly) {\n            System.out.println(\"Attempt \" + (attempts + 1) + \" - Enter a 4-character code (A-C and 1-3): \");\n            String userGuess = scanner.nextLine();\n\n            // Validar longitud y caracteres\n            if (userGuess.length() != 4 || !isValidCode(userGuess)) {\n                System.out.println(\"Invalid code! Make sure to use a 4 characters between A-C and 1-3.\");\n                continue;\n            }\n\n            // Comprobar el intento del usuario y dar pistas\n            String hint = getHint(secretCode, userGuess);\n            System.out.println(\"Hints: \" + hint);\n\n            // Comprobar si el usuario ha adivinado el código secreto\n            if (userGuess.equals(secretCode)) {\n                guessedCorrectly = true;\n                System.out.println(\"Congratulations! You've guessed the secret code!\");\n            }\n\n            attempts++;\n        }\n\n        // Si el usuario no adivina el codigo en 10 intentos\n        if (!guessedCorrectly) {\n            System.out.println(\"Sorry, you've exhausted your 10 attemps! The secret code was: \" + secretCode);\n        }\n\n        scanner.close();\n    }\n\n    // Metodo para generar el código secreto\n    private static String generateSecretCode() {\n        List<Character> availableChars = Arrays.asList('A', 'B', 'C', '1', '2', '3');\n        Collections.shuffle(availableChars);\n\n        // Tomamos los primeros 4 caracteres de la lista barajada\n        StringBuilder code = new StringBuilder();\n        for (int i = 0; i < 4; i++) {\n            code.append(availableChars.get(i));\n        }\n\n        return code.toString();\n    }\n\n    // Método para validar si el código ingresado es correcto\n    private static boolean isValidCode(String code) {\n        return code.matches(\"[A-C1-3]{4}\");\n    }\n\n    // Método para comparar el código secreto con el intento del usuario y dar pistas\n    private static String getHint(String secretCode, String userGuess) {\n        StringBuilder hint = new StringBuilder();\n\n        // Recorremos cada carácter del intento y los comparamos con el código secreto\n        for (int i = 0; i < 4; i++) {\n            char c = userGuess.charAt(i);\n            if (c == secretCode.charAt(i)) {\n                hint.append(\"Correct \");\n            } else if (secretCode.contains(String.valueOf(c))) {\n                hint.append(\"Present \");\n            } else {\n                hint.append(\"Incorrect \");\n            }\n        }\n\n        return hint.toString().trim();\n    }\n}\n"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/java/asjordi.java",
    "content": "import java.security.SecureRandom;\nimport java.util.Random;\nimport java.util.Scanner;\n\npublic class Main {\n\n    private final Random r = new SecureRandom();\n    private final Scanner sc = new Scanner(System.in);\n    private final String ALPHABET = \"ABC123\";\n    private final int CODE_LENGTH = 4;\n    private final String secretCode;\n\n    public static void main(String[] args) {\n        Main m = new Main();\n        m.start();\n    }\n\n    public Main() {\n        this.secretCode = generateSecretCode();\n    }\n\n    private String generateSecretCode() {\n        StringBuilder sb = new StringBuilder();\n        while (sb.length() < CODE_LENGTH) {\n            char c = ALPHABET.charAt(r.nextInt(ALPHABET.length()));\n            if (sb.indexOf(String.valueOf(c)) == -1) sb.append(c);\n        }\n\n        return sb.toString();\n    }\n\n    public void start() {\n        int attempts = 0;\n\n        while (attempts < 10) {\n            System.out.println(\"Enter a code:\");\n            String code = sc.nextLine();\n            checkCode(code.toUpperCase());\n            attempts++;\n        }\n\n    }\n\n    public void checkCode(String code) {\n        if (code.isBlank()) {\n            System.out.println(\"Please enter a code\");\n            return;\n        }\n\n        if (code.length() != CODE_LENGTH) {\n            System.out.println(\"The code must be 4 characters long\");\n            return;\n        }\n\n        if (code.equals(secretCode)) {\n            System.out.println(\"Congratulations! You have guessed the secret code.\");\n            System.exit(0);\n        }\n\n        for (int i = 0; i < CODE_LENGTH; i++) {\n            char current = code.charAt(i);\n\n            if (current == secretCode.charAt(i)) System.out.println(\"Character \" + current + \" is in the correct position\");\n            else if (secretCode.indexOf(current) != -1) System.out.println(\"Character \" + current + \" is in the secret code, but in the wrong position\");\n            else System.out.println(\"Character \" + current + \" is not in the secret code\");\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/java/miguelex.java",
    "content": "import java.util.*;\n\npublic class miguelex {\n    public static void main(String[] args) {\n        List<Character> chars = Arrays.asList('A', 'B', 'C', '1', '2', '3');\n        Collections.shuffle(chars);\n        String code = chars.subList(0, 4).stream().map(String::valueOf).reduce(\"\", String::concat);\n\n        Scanner scanner = new Scanner(System.in);\n        int attempts = 10;\n\n        System.out.println(\"¡Bienvenido! Tienes 10 intentos para descifrar el código.\");\n\n        while (attempts > 0) {\n            System.out.println(\"Intento #\" + attempts + \": Ingresa un código de 4 caracteres:\");\n            String input = scanner.nextLine().toUpperCase();\n\n            if (input.length() != 4 || !input.matches(\"[A-C1-3]{4}\")) {\n                System.out.println(\"Código inválido. Debe tener 4 caracteres (letras A-C, números 1-3).\");\n                continue;\n            }\n\n            StringBuilder result = new StringBuilder();\n            for (int i = 0; i < 4; i++) {\n                if (input.charAt(i) == code.charAt(i)) {\n                    result.append(\"Correcto, \");\n                } else if (code.indexOf(input.charAt(i)) != -1) {\n                    result.append(\"Presente, \");\n                } else {\n                    result.append(\"Incorrecto, \");\n                }\n            }\n\n            System.out.println(result.substring(0, result.length() - 2));\n\n            if (input.equals(code)) {\n                System.out.println(\"¡Felicidades! Descifraste el código: \" + code);\n                return;\n            }\n\n            attempts--;\n        }\n\n        System.out.println(\"Lo siento, no lograste descifrar el código: \" + code);\n    }\n}\n"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #49 - JavaScript -> Jesus Antonio Escamilla */\n\n/**\n * EL ALMACÉN DE PAPÁ NOEL.\n * Utilizando la Terminal para pedir datos y agregarlos.\n */\n\nconst readline = require('readline');\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout,\n});\n\nfunction generateCodeSecret() {\n    const item = ['A', 'B', 'C', '1', '2', '3'];\n    let code = '';\n\n    while (code.length < 4) {\n        const indexRandom = Math.floor(Math.random() * item.length);\n        const chart = item[indexRandom];\n        if (!code.includes(chart)) {\n            code += chart;\n        }\n    }\n\n    return code;\n}\n\nfunction validateEntry(entrance) {\n    if (entrance.length !== 4) {\n        console.log('El código debe tener exactamente 4 caracteres.');\n        return false;\n    }\n\n    const pattern = /^[A-C1-3]{4}$/;\n    if (!pattern.test(entrance)) {\n        console.log('El código solo puede contener letras (A-C) y números (1-3).');\n        return false;\n    }\n\n    const uniqueCharacters = new Set(entrance);\n    if (uniqueCharacters.size !== 4) {\n        console.log('El código no debe contener caracteres repetidos.');\n        return false;\n    }\n\n    return true;\n}\n\nfunction evaluateAttempt(secretCode, attempt) {\n    const result = [];\n\n    for (let i = 0; i < attempt.length; i++) {\n        if (attempt[i] === secretCode[i]) {\n            result.push('Correcto');\n        } else if (secretCode.includes(attempt[i])) {\n            result.push('Presente');\n        } else {\n            result.push('Incorrecto');\n        }\n    }\n\n    return result;\n}\n\n\nfunction Security() {\n    const codeSecret = generateCodeSecret();\n    console.log('Papá Noel necesita tu ayuda para abrir el almacén de regalos.');\n    console.log('Descifra el código secreto de 4 caracteres (letras: A-C, números: 1-3).');\n    console.log('Tienes 10 intentos. ¡Buena suerte!');\n\n    let remainingAttempt = 10;\n\n    const askTry = () => {\n        if (remainingAttempt <= 0) {\n            console.log('Lo siento, has perdido. El código secreto era: ' + codeSecret);\n            rl.close();\n            return;\n        }\n\n        rl.question(`Introduce tu intento (${remainingAttempt} intentos restantes): `, (userInput) => {\n            userInput = userInput.toUpperCase();\n\n            if (!validateEntry(userInput)) {\n                askTry();\n                return;\n            }\n\n            const result = evaluateAttempt(codeSecret, userInput);\n            console.log(`Resultado: ${result.join(', ')}`);\n\n            if (userInput === codeSecret) {\n                console.log('¡Felicidades! Has descifrado el código secreto y salvado la Navidad.');\n                rl.close();\n                return;\n            }\n\n            remainingAttempt--;\n            askTry();\n        });\n    };\n\n    askTry();\n}\n\nSecurity();"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/javascript/MohamedElderkaoui.js",
    "content": "const readline = require('readline');\n\n// Configuración para capturar la entrada del usuario\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout,\n});\n\n// Generar el código secreto\nfunction generateSecretCode() {\n    const pool = ['A', 'B', 'C', '1', '2', '3'];\n    const shuffled = pool.sort(() => Math.random() - 0.5);\n    return shuffled.slice(0, 4).join('');\n}\n\n// Validar la entrada del usuario\nfunction isValidInput(input) {\n    if (input.length !== 4) return false;\n    const validChars = new Set(['A', 'B', 'C', '1', '2', '3']);\n    const seenChars = new Set();\n    for (let char of input) {\n        if (!validChars.has(char) || seenChars.has(char)) {\n            return false;\n        }\n        seenChars.add(char);\n    }\n    return true;\n}\n\n// Evaluar el intento del usuario y generar pistas\nfunction evaluateGuess(guess, secretCode) {\n    const feedback = [];\n    for (let i = 0; i < guess.length; i++) {\n        if (guess[i] === secretCode[i]) {\n            feedback.push(`${guess[i]}: Correcto`);\n        } else if (secretCode.includes(guess[i])) {\n            feedback.push(`${guess[i]}: Presente`);\n        } else {\n            feedback.push(`${guess[i]}: Incorrecto`);\n        }\n    }\n    return feedback.join(' | ');\n}\n\n// Lógica principal del juego\nfunction playGame() {\n    const secretCode = generateSecretCode();\n    console.log(\"¡El almacén de Papá Noel está cerrado!\");\n    console.log(\"Intenta adivinar el código secreto de 4 caracteres (Letras: A-C, Números: 1-3).\");\n    console.log(\"Tienes 10 intentos. ¡Buena suerte!\");\n\n    let attempts = 0;\n    let hasGuessed = false;\n\n    const askInput = () => {\n        if (attempts >= 10 || hasGuessed) {\n            if (hasGuessed) {\n                console.log(\"¡Felicidades! Has descifrado el código secreto y salvado la Navidad. 🎅🎁\");\n            } else {\n                console.log(`Oh no, no has logrado descifrar el código. 😔 El código era: ${secretCode}`);\n            }\n            rl.close();\n            return;\n        }\n\n        rl.question(`Intento ${attempts + 1}/10: Escribe tu código: `, (userInput) => {\n            userInput = userInput.toUpperCase();\n\n            if (!isValidInput(userInput)) {\n                console.log(\"Entrada inválida. Asegúrate de que sea de 4 caracteres (A-C y 1-3) sin repetidos.\");\n                askInput();\n                return;\n            }\n\n            const feedback = evaluateGuess(userInput, secretCode);\n            console.log(feedback);\n\n            if (userInput === secretCode) {\n                hasGuessed = true;\n            } else {\n                attempts++;\n            }\n\n            askInput();\n        });\n    };\n\n    askInput();\n}\n\n// Iniciar el juego\nplayGame();\n"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/javascript/Rafacv23.js",
    "content": "// Autor: Rafael Canosa, Github: https://github.com/rafacv23\nconst readline = require(\"node:readline\")\nconst { stdin: input, stdout: output } = require(\"node:process\")\n\nconst rl = readline.createInterface({ input, output })\nconst characters = [\"A\", \"B\", \"C\", 1, 2, 3]\n\n/* crear algoritmo que genere la contraseña secreta\n * tiene que tener 4 caracteres\n * letras: A, B o C\n * numeros: 1, 2 o 3\n * no se pueden repetir caracteres\n */\nfunction generateSecretCode() {\n  // lista con los posibles caracteres\n\n  let secretCode = \"\"\n\n  // generamos los 4 caracteres\n  for (let i = 0; i <= 4; i++) {\n    const randomCharacter =\n      characters[Math.floor(Math.random() * characters.length)]\n\n    // si el caracter es repetido, volvemos a generar\n    if (secretCode.includes(randomCharacter)) {\n      continue\n    }\n    secretCode += randomCharacter\n  }\n\n  // solo terminamos el bucle si la contraseña tiene 4 caracteres\n  if (secretCode.length !== 4) {\n    return generateSecretCode()\n  }\n\n  return secretCode\n}\n\n// funcion que compara la respuesta con la contraseña secreta\nfunction compare(secretCode, answer) {\n  // comprobamos que la respuesta tiene 4 caracteres\n  if (answer.length !== 4) {\n    console.log(\"❌ El código debe tener exactamente 4 caracteres.\")\n    return\n  }\n\n  // comprobamos que los characters son los correctos\n  if (![...answer].every((char) => characters.includes(char))) {\n    console.log(\"❌ Solo se permiten los caracteres A, B, C, 1, 2, 3.\")\n    return\n  }\n\n  let feedback = []\n\n  for (let i = 0; i < 4; i++) {\n    if (answer[i] === secretCode[i]) {\n      feedback.push(\"✅ Correcto\")\n    } else if (secretCode.includes(answer[i])) {\n      feedback.push(\"🟡 Presente\")\n    } else {\n      feedback.push(\"❌ Incorrecto\")\n    }\n  }\n\n  console.log(\"Pista:\", feedback.join(\" | \"))\n}\n\n// Creamos la funcion que iniciara el juego y que se autoinvoque\n;(function play() {\n  console.log(\"🎅 ¡Hola! Soy Papá Noel. Intenta descifrar el código secreto.\")\n  const secretCode = generateSecretCode()\n\n  // debug  console.log(secretCode)\n  let attempts = 0\n\n  function ask() {\n    if (attempts >= 10) {\n      console.log(`🎄 Lo siento, has perdido. El código era: ${secretCode}`)\n      rl.close()\n      return\n    }\n\n    rl.question(\n      `Intento ${attempts + 1}/10. Introduce tu código: `,\n      (answer) => {\n        compare(secretCode, answer)\n\n        if (answer === secretCode) {\n          console.log(\"🎉 ¡Felicidades! Has descifrado el código.\")\n          rl.close()\n        } else {\n          attempts++\n          ask()\n        }\n      }\n    )\n  }\n\n  ask()\n})()\n"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/javascript/RaulDoezon.js",
    "content": "/*\n * EJERCICIO:\n * Papá Noel tiene que comenzar a repartir los regalos...\n * ¡Pero ha olvidado el código secreto de apertura del almacén!\n *\n * Crea un programa donde introducir códigos y obtener pistas.\n * \n * Código:\n * - El código es una combinación de letras y números aleatorios\n *   de longitud 4. (Letras: de la A a la C, Números: del 1 al 3)\n * - No hay repetidos.\n * - Se genera de manera aleatoria al iniciar el programa.\n * \n * Usuario:\n * - Dispone de 10 intentos para acertarlo.\n * - En cada turno deberá escribir un código de 4 caracteres, y \n *   el programa le indicará para cada uno lo siguiente:\n *   - Correcto: Si el caracter está en la posición correcta.\n *   - Presente: Si el caracter existe, pero esa no es su posición.\n *   - Incorrecto: Si el caracter no existe en el código secreto.\n * - Deben controlarse errores de longitud y caracteres soportados.\n * \n * Finalización:\n * - Papa Noel gana si descrifra el código antes de 10 intentos.\n * - Pierde si no lo logra, ya que no podría entregar los regalos.\n*/\n\nlet enterCode;\nlet codeCounter = 1;\nlet alphanumerics = [\"A\", \"B\", \"C\", 1, 2, 3];\nlet secretCode = \"\";\n\nconst generateCode = (array) => {\n  for (let index = array.length - 1; index > 0; index--) {\n    const randomIndex = Math.floor(Math.random() * (index + 1));\n\n    [array[index], array[randomIndex]] = [array[randomIndex], array[index]];\n  }\n\n  for (let index = 0; index < 4; index++) {\n    secretCode += alphanumerics[index];\n  }\n};\n\ngenerateCode(alphanumerics);\n\nalert(\"Santa, introduce el código secreto para abrir el almacen.\\nEl código está conformado por alguno de los siguientes caracteres: A - C, 1 - 3:\");\n\nfor (let index = 1; index <= 10; index++) {\n  enterCode = prompt(`Intento #${index}:`);\n\n  if (enterCode === secretCode) {\n    alert(\"Código correcto. Acceso autorizado al almacen.\");\n\n    break;\n  } else {\n    let errorMessage = `Código ingresado: ${enterCode}\\n\\n`;\n\n    for (let index = 0; index < secretCode.length; index++) {\n      let position = index + 1;\n\n      if (secretCode[index] === enterCode[index]) {\n        errorMessage += `· El caracter de la posición ${position} es correcto.\\n`;\n      }\n\n      if (secretCode[index] !== enterCode[index] && secretCode.indexOf(enterCode[index]) > -1) {\n        errorMessage += `· El caracter de la posición ${position} es incorrecto, pero existe en el código.\\n`;\n      }\n\n      if (secretCode[index] !== enterCode[index] && secretCode.indexOf(enterCode[index]) === -1) {\n        errorMessage += `· El caracter de la posición ${position} no existe.\\n`;\n      }\n    }\n\n    if (enterCode.length !== 4) {\n      errorMessage += \"· La longitud debe ser de cuatro caracteres.\\n\";\n    }\n\n    alert(errorMessage);\n\n    if (index === 10) {\n      alert(\"No decifraste el código y los regalos no podrán entregarse a tiempo.\");\n    }\n  }\n}\n"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/javascript/duendeintemporal.js",
    "content": "//#49 - ALMACEN DE PAPÁ NOEL\n/*\nEJERCICIO:\n * Papá Noel tiene que comenzar a repartir los regalos...\n * ¡Pero ha olvidado el código secreto de apertura del almacén!\n *\n * Crea un programa donde introducir códigos y obtener pistas.\n *\n * Código:\n * - El código es una combinación de letras y números aleatorios\n *   de longitud 4. (Letras: de la A a la C, Números: del 1 al 3)\n * - No hay repetidos.\n * - Se genera de manera aleatoria al iniciar el programa.\n *\n * Usuario:\n * - Dispone de 10 intentos para acertarlo.\n * - En cada turno deberá escribir un código de 4 caracteres, y\n *   el programa le indicará para cada uno lo siguiente:\n *   - Correcto: Si el caracter está en la posición correcta.\n *   - Presente: Si el caracter existe, pero esa no es su posición.\n *   - Incorrecto: Si el caracter no existe en el código secreto.\n * - Deben controlarse errores de longitud y caracteres soportados.\n *\n * Finalización:\n * - Papa Noel gana si descrifra el código antes de 10 intentos.\n * - Pierde si no lo logra, ya que no podría entregar los regalos.\n */\n\n//Note: Run => Node + filename in a Node.js enviroitment to display the game interfaz\n\nlet log = console.log;\n\nconst readline = require('readline');\n\n// Create an interface for input and output\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\n// Function to generate a random code\nfunction generateCode() {\n    const characters = ['A', 'B', 'C', '1', '2', '3'];\n    const codeSet = new Set();\n\n    while (codeSet.size < 4) {\n        const randomIndex = Math.floor(Math.random() * characters.length);\n        codeSet.add(characters[randomIndex]);\n    }\n\n    return Array.from(codeSet).join('');\n}\n\n// Function to provide feedback on the user's guess\nfunction provideFeedback(secretCode, userGuess) {\n    let feedback = {\n        correct: 0,\n        present: 0,\n        incorrect: 0\n    };\n\n    const checkedIndices = new Set(); \n    const guessChecked = Array(userGuess.length).fill(false);\n\n    // Check for correct positions\n    for (let i = 0; i < secretCode.length; i++) {\n        if (userGuess[i] === secretCode[i]) {\n            feedback.correct++;\n            checkedIndices.add(i); \n            guessChecked[i] = true; \n        }\n    }\n\n    // Check for present characters\n    for (let i = 0; i < userGuess.length; i++) {\n        if (!guessChecked[i]) {\n            for (let j = 0; j < secretCode.length; j++) {\n                if (userGuess[i] === secretCode[j] && !checkedIndices.has(j)) {\n                    feedback.present++;\n                    checkedIndices.add(j);\n                    guessChecked[i] = true; \n                    break;\n                }\n            }\n        }\n    }\n\n    // Calculate incorrect characters\n    feedback.incorrect = userGuess.length - feedback.correct - feedback.present;\n\n    return feedback;\n}\n\nconst startGame = () => {\n    const secretCode = generateCode();\n    let attempts = 10;\n    let gameWon = false;\n\n    log(\"Welcome to the Secret Code Game!\");\n    log(\"You have 10 attempts to guess the 4-character code.\");\n    log(\"The code consists of letters (A, B, C) and numbers (1, 2, 3) without repetitions.\");\n\n    const askForGuess = () => {\n        rl.question(`You have ${attempts} attempts left. Enter your guess (4 characters): `, (userGuess) => {\n            // Validate input\n            if (userGuess.length !== 4 || !/^[A-C1-3]+$/.test(userGuess)) {\n                log(\"Invalid input. Please enter exactly 4 characters using A, B, C, 1, 2, or 3.\");\n                askForGuess(); // Ask again\n                return;\n            }\n\n            const feedback = provideFeedback(secretCode, userGuess);\n            log(`Feedback: Correct: ${feedback.correct}, Present: ${feedback.present}, Incorrect: ${feedback.incorrect}`);\n\n            if (feedback.correct === 4) {\n                gameWon = true;\n                log(\"Congratulations! You've guessed the secret code!\");\n                rl.close(); // Close the readline interface\n                return;\n            }\n\n            attempts--;\n            if (attempts > 0) {\n                askForGuess(); // Ask for the next guess\n            } else {\n                log(`Sorry, you've run out of attempts. The secret code was: ${secretCode}`);\n                rl.close(); \n            }\n        });\n    };\n\n    askForGuess(); \n}\n\nstartGame();\n"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/javascript/hectorio23.js",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\nconst readline = require(\"readline\");\n\nfunction generateSecretCode() {\n    const pool = ['A', 'B', 'C', '1', '2', '3'];\n    for (let i = pool.length - 1; i > 0; i--) {\n        const j = Math.floor(Math.random() * (i + 1));\n        [pool[i], pool[j]] = [pool[j], pool[i]];\n    }\n    return pool.slice(0, 4).join(\"\");\n}\n\nfunction evaluateGuess(secret, guess) {\n    for (let i = 0; i < 4; i++) {\n        if (guess[i] === secret[i]) {\n            console.log(`${guess[i]}: Correcto`);\n        } else if (secret.includes(guess[i])) {\n            console.log(`${guess[i]}: Presente`);\n        } else {\n            console.log(`${guess[i]}: Incorrecto`);\n        }\n    }\n}\n\nfunction isValidGuess(guess) {\n    if (guess.length !== 4) {\n        console.log(\"El código debe tener exactamente 4 caracteres.\");\n        return false;\n    }\n\n    const validChars = new Set(['A', 'B', 'C', '1', '2', '3']);\n    for (const char of guess) {\n        if (!validChars.has(char)) {\n            console.log(`Caracter inválido encontrado: ${char}`);\n            return false;\n        }\n    }\n\n    return true;\n}\n\nasync function main() {\n    const secretCode = generateSecretCode();\n    let attempts = 10;\n\n    console.log(\"\\n¡Bienvenido al juego del código secreto de Papá Noel!\");\n    console.log(\"Debes adivinar el código secreto de 4 caracteres.\");\n    console.log(\"Letras: A, B, C | Números: 1, 2, 3\\n\");\n\n    const rl = readline.createInterface({\n        input: process.stdin,\n        output: process.stdout\n    });\n\n    while (attempts > 0) {\n        console.log(`\\nIntentos restantes: ${attempts}`);\n        const guess = await new Promise(resolve => rl.question(\"Introduce tu código: \", resolve));\n\n        if (!isValidGuess(guess)) {\n            continue;\n        }\n\n        if (guess === secretCode) {\n            console.log(`¡Felicidades! Has descifrado el código secreto: ${secretCode}`);\n            rl.close();\n            return;\n        }\n\n        evaluateGuess(secretCode, guess);\n        attempts--;\n    }\n\n    console.log(`\\nLo siento, no has logrado descifrar el código secreto. Era: ${secretCode}`);\n    rl.close();\n}\n\nmain();\n"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n_______________________________________________________\n#49 EL ALMACÉN DE PAPÁ NOEL\n-------------------------------------------------------\n* EJERCICIO:\n * Papá Noel tiene que comenzar a repartir los regalos...\n * ¡Pero ha olvidado el código secreto de apertura del almacén!\n *\n * Crea un programa donde introducir códigos y obtener pistas.\n * \n * Código:\n * - El código es una combinación de letras y números aleatorios\n *   de longitud 4. (Letras: de la A a la C, Números: del 1 al 3)\n * - No hay repetidos.\n * - Se genera de manera aleatoria al iniciar el programa.\n * \n * Usuario:\n * - Dispone de 10 intentos para acertarlo.\n * - En cada turno deberá escribir un código de 4 caracteres, y \n *   el programa le indicará para cada uno lo siguiente:\n *   - Correcto: Si el caracter está en la posición correcta.\n *   - Presente: Si el caracter existe, pero esa no es su posición.\n *   - Incorrecto: Si el caracter no existe en el código secreto.\n * - Deben controlarse errores de longitud y caracteres soportados.\n * \n * Finalización:\n * - Papa Noel gana si descrifra el código antes de 10 intentos.\n * - Pierde si no lo logra, ya que no podría entregar los regalos.\n */\n// ________________________________________________________\nconst readlineSync = require('readline-sync');\n\nfunction verifyAllowedChar(codeEntry) {\n    for (let ch of codeEntry) {\n        if (!'abc123'.includes(ch)) {\n            console.log(\"Uno de los caracteres no está entre los permitidos.\\n\");\n            return false;\n        }\n    }\n    return true;\n}\n\nfunction getEntry() {\n    while (true) {\n        const codeEntry = readlineSync.question(\"Código: \");\n\n        if (codeEntry.length !== 4) {\n            console.log(\"El código debe ser de 4 dígitos.\\n\");\n            continue;\n        }\n\n        if (verifyAllowedChar(codeEntry)) {\n            return codeEntry;\n        }\n    }\n}\n\nfunction isOpen(code) {\n    const codeEntry = getEntry();\n    if (codeEntry === code) {\n        return true;\n    }\n    console.log(\"Código inválido.\\n\");\n\n    for (let i = 0; i < codeEntry.length; i++) {\n        if (codeEntry[i] === code[i]) {\n            console.log(`'${codeEntry[i]}' está en la posición correcta.`);\n        } else if (code.includes(codeEntry[i])) {\n            console.log(`'${codeEntry[i]}' está en el código, pero en otra posición.`);\n        } else {\n            console.log(`'${codeEntry[i]}' no está presente en el código.`);\n        }\n    }\n\n    return false;\n}\n\n// ____________________________________________________________________________\nconsole.log(`\n* Papá Noel tiene que comenzar a repartir los regalos...\n* ¡Pero ha olvidado el código secreto de apertura del almacén!\n\n- Tienes 10 intentos para adivinar el código que abre el almacén.\n- Código de 4 caracteres. Permitidos: a, b, c, 1, 2, 3.\n- Nota: No hay dígitos repetidos.`);\n\nconst code = shuffle(\"abc123\").slice(0, 4);\n\nfor (let attempts = 0; attempts < 10; attempts++) {\n    console.log(`\\n___________\\nIntento #${attempts + 1}`);\n\n    if (isOpen(code)) {\n        console.log(\"Código correcto, almacén abierto.\");\n        console.log(\"Papá Noel ahora podrá entregar los regalos.\");\n        break;\n    }\n\n    if (attempts === 9) {\n        console.log(\"\\n___________\\nHas perdido.\");\n        console.log(\"Papá Noel ya no podrá entregar los regalos.\");\n    }\n}\n\nfunction shuffle(str) {\n    const arr = str.split('');\n    for (let i = arr.length - 1; i > 0; i--) {\n        const j = Math.floor(Math.random() * (i + 1));\n        [arr[i], arr[j]] = [arr[j], arr[i]];\n    }\n    return arr.join('');\n}\n"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/javascript/miguelex.js",
    "content": "const readline = require('readline');\n\nfunction generateCode() {\n    const chars = ['A', 'B', 'C', '1', '2', '3'];\n    return chars.sort(() => Math.random() - 0.5).slice(0, 4).join('');\n}\n\nconst code = generateCode();\nlet attempts = 10;\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout,\n});\n\nconsole.log(\"¡Bienvenido! Tienes 10 intentos para descifrar el código.\");\n\nfunction askForInput() {\n    if (attempts === 0) {\n        console.log(`Lo siento, no lograste descifrar el código: ${code}`);\n        rl.close();\n        return;\n    }\n\n    rl.question(`Intento #${attempts}: Ingresa un código de 4 caracteres: `, (input) => {\n        input = input.toUpperCase();\n\n        if (input.length !== 4 || !/^[A-C1-3]{4}$/.test(input)) {\n            console.log(\"Código inválido. Debe tener 4 caracteres (letras A-C, números 1-3).\");\n            return askForInput();\n        }\n\n        const result = input.split('').map((char, i) => {\n            if (char === code[i]) return \"Correcto\";\n            if (code.includes(char)) return \"Presente\";\n            return \"Incorrecto\";\n        });\n\n        console.log(result.join(\", \"));\n\n        if (input === code) {\n            console.log(`¡Felicidades! Descifraste el código: ${code}`);\n            rl.close();\n        } else {\n            attempts--;\n            askForInput();\n        }\n    });\n}\n\naskForInput();\n"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/javascript/raulG91.js",
    "content": "const prompt = require('prompt-sync')();\n\nconst CHAR_SET = ['A', 'B', 'C', \"1\", \"2\", \"3\"];\n\nfunction getRandomNumber(min, max) {\n\n    const minCeiled = Math.ceil(min);\n    const maxFloored = Math.floor(max);\n    return Math.floor(Math.random() * (maxFloored - minCeiled + 1) + minCeiled);\n}\n\nfunction generateCode() {\n\n    let char_set_string = CHAR_SET.join(\"\")\n    let i = 0;\n    let final_code = \"\"\n\n    while (i < 4) {\n        let pos = getRandomNumber(0, char_set_string.length - 1)\n        final_code += char_set_string.charAt(pos)\n        char_set_string = char_set_string.slice(0, pos) + char_set_string.slice(pos + 1)\n        i++\n    }\n    return final_code\n}\n\nfunction check_input(input) {\n\n    let correct = true\n\n    //First check if the length of the input is 4\n    if (input.length != 4) {\n        console.log(\"El codigo debe tener una longitud de 4 caracteres\")\n        correct = false\n    }\n    else {\n        //Check if the input contains non allowed characters\n        for (let char of input) {\n            if (!(CHAR_SET.includes(char))) {\n                console.log(`Caracter ${char} no esta permitido`)\n                correct = false\n                break\n               \n            }\n            else {\n                //Count if the char appears more than 1\n                let count = (input.match(new RegExp(char, \"g\")) || []).length;\n                if (count > 1) {\n                    console.log(`Caracter ${char} esta duplicado`)\n                    correct = false\n                    break\n                  \n                }\n            }\n        }\n    }\n    return correct\n}\n\nfunction main() {\n    let code = generateCode()\n    let tries = 0;\n    let exit = false\n\n    console.log(code)\n    while (tries < 10 && !exit) {\n        console.log(`Numero de intentos restantes ${10 - tries}`)\n        //User imput\n        let input = prompt('Introduce codigo de entrada ')\n        //If length is different to 4 throw an error\n        if (check_input(input)) {\n            // Check if the code entered by the user is the one that we are looking for\n            if (input === code) {\n                exit = true\n                console.log(\"El codigo es correcto \")\n            }\n            else {\n                // Checks how many characters the user input correctly\n                for (let i = 0; i < input.length; i++) {\n                    if (input.at(i) == code.at(i)) {\n                        //Char is in the same position\n                        console.log(`Caracter ${input.at(i)} es Correcto`)\n                    }\n                    else {\n                        let current_char = input.at(i)\n                        if (code.includes(current_char)) {\n                            //Char exist in the code but the position is not correct\n                            console.log(`Caracter ${current_char}  esta presente`)\n                        }\n                        else {\n                            console.log(`Caracter ${current_char} es Incorrecto`)\n                        }\n                    }\n                } \n\n            }\n        }\n\n        tries++\n\n    }\n}\n\nmain()"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/kotlin/blackriper.kt",
    "content": "import kotlin.random.Random\n\n// estados de los caracteres\nenum class CharacterStatus{\n    CORRECT,PRESENT,INCORRECT\n}\n\nclass LongitudException(override val message: String): Exception(message)\n\n\n// generar password de la bodega\nfun generatePassword(): String {\n    var password = \"\"\n    while (true) {\n        val character = (if (Random.nextBoolean()) (1..3).random() else listOf(\"A\", \"B\", \"C\").random()).toString()\n        if (password.contains(character)) continue\n        else password += character\n\n        if (password.length==4) break\n    }\n return password\n}\n\n//manejar las contraseñas introduccidas por el usuario\nclass DadNoelStorage(generator:()-> String){\n    private var password=\"\"\n    private val regex = Regex(\"^[A-C1-3]+$\")\n\n    init {\n        password=generator()\n    }\n\n   private  fun evaluateUserPassword(passCha: Char,position: Int):CharacterStatus{\n        if (password.contains(passCha) && password[position] ==passCha) return CharacterStatus.CORRECT\n        if (password.contains(passCha) && password[position] !=passCha) return  CharacterStatus.PRESENT\n        return CharacterStatus.INCORRECT\n    }\n\n    private fun validatePassword(pass: String) = runCatching{\n      if (regex.matches(pass).not())\n          throw IllegalArgumentException(\"el password solo puede contener numeros del 1 al 3 y letras de la A la C\")\n\n      if (pass.length>4) throw LongitudException(\"el password solo puede tener una longitud de 4 caracteres\")\n\n      return@runCatching pass\n    }\n\n    private fun findAndShow(userPass: String){\n        var ind=0\n        for (ch in userPass){\n            val result=evaluateUserPassword(ch,ind)\n            when(result){\n                CharacterStatus.CORRECT -> println(\"el caracter $ch es correcto\")\n                CharacterStatus.PRESENT -> println(\"el caracter  $ch es parte de la contraseña pero no esta en la posicion correcta\")\n                CharacterStatus.INCORRECT ->println(\"el caracter $ch no es parte de la contraseña \")\n            }\n            ind++\n        }\n     }\n\n\n\n\n    fun questionPasswordStorage(){\n        var intents=1\n        while (true){\n            println(\"introduce la contraseña del almacen \")\n            val userPass= readLine()!!.uppercase()\n            val valid=validatePassword(userPass)\n            if (valid.isFailure){\n                println(\"passowrd erroneo porque ${valid.exceptionOrNull()?.message}\")\n                continue\n            }\n            if (valid.isSuccess){\n                 findAndShow(valid.getOrDefault(\"234\"))\n                 println(\"$intents/10 intentos\")\n                 intents++\n\n                if (password==valid.getOrNull()){\n                    println(\" contraseña correcta bienvenido santa\")\n                    break\n                }\n\n                if (intents==10) {\n                    println(\"has agotado tus 10 intentos has perdido\")\n                    break\n                }\n            }\n        }\n\n    }\n\n\n}\n\n\n\n\n\n\nfun main() {\n    val storage=DadNoelStorage(::generatePassword)\n    storage.questionPasswordStorage()\n}"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/php/miguelex.php",
    "content": "<?php\nfunction generateCode() {\n    $characters = array_merge(range('A', 'C'), range(1, 3));\n    shuffle($characters);\n    return implode('', array_slice($characters, 0, 4));\n}\n\n$code = generateCode();\n$attempts = 10;\n\necho \"¡Bienvenido! Tienes 10 intentos para descifrar el código.\\n\";\n\nwhile ($attempts > 0) {\n    echo \"Intento #{$attempts}. Ingresa un código de 4 caracteres: \";\n    $input = trim(fgets(STDIN));\n    \n    if (strlen($input) != 4 || !preg_match('/^[A-C1-3]{4}$/', $input)) {\n        echo \"Código inválido. Debe tener 4 caracteres (letras A-C, números 1-3).\\n\";\n        continue;\n    }\n\n    $result = [];\n    $used = array_fill(0, 4, false);\n\n    for ($i = 0; $i < 4; $i++) {\n        if ($input[$i] === $code[$i]) {\n            $result[] = \"Correcto\";\n            $used[$i] = true;\n        } elseif (strpos($code, $input[$i]) !== false && !$used[array_search($input[$i], str_split($code))]) {\n            $result[] = \"Presente\";\n        } else {\n            $result[] = \"Incorrecto\";\n        }\n    }\n\n    echo implode(\", \", $result) . \"\\n\";\n\n    if ($input === $code) {\n        echo \"¡Felicidades! Descifraste el código: {$code}\\n\";\n        exit;\n    }\n\n    $attempts--;\n}\n\necho \"Lo siento, no lograste descifrar el código: {$code}\\n\";"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/php/siderio2.php",
    "content": "<?php\n\n/**\n * @author Desiderio Martínez Silva aka siderio2\n * @version 1.0\n * @link https://github.com/siderio2\n * @see https://retosdeprogramacion.com/roadmap/\n *\n * PHP implementation of the Santa Claus Warehouse 49 exercise from Mouredev Roadmap\n *\n * Generates a random key of 4 non-repeating characters from the set {A, B, C, 1, 2, 3}\n *\n * Then asks the user to try to guess the key, 10 attempts given\n *\n * After each attempt, the program tells if a character is in the correct position,\n * if it is in the key but in the wrong position, or if it is not in the key\n *\n */\n\n// Defining constants\nconst KEY_LENGTH = 4;\nconst ATTEMPTS = 10;\nconst LETTERS = ['A', 'B', 'C'];\nconst NUMBERS = ['1', '2', '3'];\ndefine('ALPHABET', array_merge(LETTERS, NUMBERS));\n\n/**\n * Checks if the given guess is valid.\n *\n * A guess is valid if it has exactly $KEY_LENGTH characters and only contains\n * characters from $LETTERS and $NUMBERS.\n *\n * @param string $guess\n * @return string \"OK\" if the guess is valid, an error message otherwise\n */\nfunction checkGuess(string $guess): string\n{\n  if (strlen($guess) != KEY_LENGTH) {\n    return \"The key must be exactly \" . KEY_LENGTH . \" characters long\\n\";\n  }\n\n  for ($i = 0; $i < KEY_LENGTH; $i++) {\n    if (!in_array($guess[$i], LETTERS) && !in_array($guess[$i], NUMBERS)) {\n      return \"Unauthorized character; only characaters in this list are allowed: - \" . implode(\" \", ALPHABET) . \" -\\n\";\n    }\n  }\n\n  return \"OK\";\n}\n\n/**\n * Generates a feedback string for a given guess and key.\n *\n * The feedback string tells if each character of the guess is in the correct\n * position, if it is in the key but in the wrong position, or if it is not in\n * the key.\n *\n * @param string $guess The guess to generate the feedback for\n * @param string $key The key to compare the guess against\n * @return string A string with the feedback, with \"correct\",\n * \"wrong position\", or \"incorrect\" appended to each character\n */\nfunction generateFeedback(string $guess, string $key): string\n{\n  $feedback = \"\\n\";\n  for ($i = 0; $i < KEY_LENGTH; $i++) {\n    if ($guess[$i] === $key[$i]) {\n      $feedback .= $guess[$i] . \" -> correct\\t\";\n    } elseif (strpos($key, $guess[$i]) !== false) {\n      $feedback .= $guess[$i] . \" -> wrong position\\t\";\n    } else {\n      $feedback .= $guess[$i] . \" -> incorrect\\t\";\n    }\n  }\n  $feedback .= \"\\n\\n\";\n\n  return $feedback;\n}\n\n/**\n * Generates a random key of $KEY_LENGTH characters from the set\n * defined in the ALPHABET constant.\n *\n * @return string A random key of $KEY_LENGTH characters\n */\nfunction generateKey(): string\n{\n  $key = [];\n  $random_keys = array_rand(ALPHABET, KEY_LENGTH);\n  for ($j = 0; $j < KEY_LENGTH; $j++) {\n    $key[] = ALPHABET[$random_keys[$j]];\n  }\n  $key = implode(\"\", $key);\n\n  return $key;\n}\n\n$key = generateKey();\n$unguessed = TRUE; // Initializing unguessed flag\n\n// Main loop\nfor ($i = 0; $i < ATTEMPTS; $i++) {\n  $guess = readline(\"Attempt #\" . ($i + 1) . \". Guess the Santa's warehouse key: \");\n  $guess = strtoupper($guess);\n\n  $check = checkGuess($guess); // Check if the guess is valid\n  if ($check !== \"OK\") {\n    $i--; // Attempt doesn't count\n    echo \"\\n*ERROR* -> \" . $check . \"\\n\";\n    continue; // Skip the rest of the loop if the guess is invalid\n  }\n\n  if ($guess === $key) { // Check if the guess is correct\n    echo \"\\nCONGRATS!! We've got the key, now Santa can open his warehouse!\\n\\n\";\n    $unguessed = FALSE; // Changing the unguessed flag\n    break;  // Exit the loop if the guess is correct\n  }\n\n  // If the guess is valid but not correct, generate feedback and print it\n  echo (generateFeedback($guess, $key));\n}\n\n// Final message if the key was not guessed\nif ($unguessed) {\n  echo \"Shame on you: nobody will have presents this year. The key was: \" . $key . \"\\n\\n\";\n}\n"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/python/CarlosVR48.py",
    "content": "\"\"\"EJERCICIO:\n * Papá Noel tiene que comenzar a repartir los regalos...\n * ¡Pero ha olvidado el código secreto de apertura del almacén!\n *\n * Crea un programa donde introducir códigos y obtener pistas.\n *\n * Código:\n * - El código es una combinación de letras y números aleatorios\n *   de longitud 4. (Letras: de la A a la C, Números: del 1 al 3)\n * - No hay repetidos.\n * - Se genera de manera aleatoria al iniciar el programa.\n *\n * Usuario:\n * - Dispone de 10 intentos para acertarlo.\n * - En cada turno deberá escribir un código de 4 caracteres, y\n *   el programa le indicará para cada uno lo siguiente:\n *   - Correcto: Si el caracter está en la posición correcta.\n *   - Presente: Si el caracter existe, pero esa no es su posición.\n *   - Incorrecto: Si el caracter no existe en el código secreto.\n * - Deben controlarse errores de longitud y caracteres soportados.\n *\n * Finalización:\n * - Papa Noel gana si descrifra el código antes de 10 intentos.\n * - Pierde si no lo logra, ya que no podría entregar los regalos.\n \"\"\"\n\nimport random\n\nclave_original = list()\nclave_bak = list()\nclave_Acertar = list()\ncontador = 10\nsalir = True\n\n# Creamos la contraseña principal la longitus es de cuatro variables \n# 3 letras y 3 numeros . En total son seis digitos  \n\nwhile len(clave_bak) <= 3:\n    caracter = random.randint (1 , 6)\n    \n    if clave_bak.count(caracter) == 0:\n        clave_bak.append(caracter)\n    \nfor index in clave_bak:\n    if index == 1:\n        clave_original.append(\"A\")\n    elif index == 2:\n        clave_original.append(\"B\")\n    elif index == 3:\n        clave_original.append(\"C\")\n    elif index == 4:\n        clave_original.append(\"1\") \n    elif index == 5:\n        clave_original.append(\"2\") \n    elif index == 6:\n        clave_original.append(\"3\")            \n\n# Funcion que coje cada valor de la clave_bak y los compara con cada valor\n# de la clave_original.Dandoles el valor correspondiente.\n\ndef comparar():\n    clave_Acertar.clear()\n\n    for index in range(0,4):\n        if clave_bak[index] == clave_original[index]:\n            clave_Acertar.append(\"CORRECTO\")\n        else:\n            if clave_original.count(clave_bak[index]) > 0:\n                clave_Acertar.append(\"PRESENTE\")\n            else:\n                clave_Acertar.append(\"INCORRECTO\")\n\n# Funcion para pedir los digitos por consola enmarcados en los valores dados\ndef valor(posicion):\n    while True:\n        numero = input (f\"DIME EL DIGITO {posicion} ? \").upper()\n        if numero == \"A\" or numero == \"B\" or numero == \"C\" or numero == \"1\" or numero == \"2\" or numero == \"3\":\n            return numero\n        else:\n            print (\"\\nVALOR INCORRECTO\\n\")\n\nwhile contador > 0 and clave_Acertar.count(\"CORRECTO\") < 4:\n    print (\"\\nLA CLAVE ES DE CUATRO DIGITOS LOS CUALES PUEDEN SER A , B , C , 1 , 2 Y 3 . SIN REPETIR\\n\")\n    print (f\"NUMERO DE POSIBILIDADES: {contador}\\n\")\n    \n    while salir:\n        digito_uno = valor(1)\n        digito_dos = valor(2)\n        digito_tres = valor(3)\n        digito_cuatro = valor(4)\n        \n        clave_bak.clear()\n        clave_bak.append(digito_uno)\n        clave_bak.append(digito_dos)\n        clave_bak.append(digito_tres)\n        clave_bak.append(digito_cuatro)\n        \n        if clave_bak.count(\"A\") < 2 and clave_bak.count(\"B\") < 2 and clave_bak.count(\"C\") < 2 and clave_bak.count(\"1\") < 2 and clave_bak.count(\"2\") < 2 and clave_bak.count(\"3\") < 2:\n            salir = False\n        else :\n            print (\"\\nHAY DIGITOS REPETIDOS\\n\")\n\n    comparar()\n    contador = contador - 1\n    print (f\"\\n{clave_Acertar}\\n\")\n    salir = True\n\nif contador == 0 and clave_Acertar.count(\"CORRECTO\") < 4:\n    print (\"NO TIENES ACCESO !!!!\")\nelse:\n    print (\"BIEN TIENES ACCESO !!!!\")            "
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/python/Gordo-Master.py",
    "content": "# 49 - El almacén de papá noel\nimport random\n\nclass WorkshopAccess:\n    def __init__(self):\n        self.letters = \"abc\"\n        self.numbers = \"123\"\n        self.valid_characters = self.letters + self.numbers\n        self.access_code = self.generate_code(self.valid_characters)\n\n    def generate_code(self,text):\n        caracters = list(text.lower())\n        code = \"\".join(random.sample(caracters,k=4))\n        return code\n    \n    def valid_text(self, text):\n        if len(text) != 4:\n            print(\"Numero de caracteres incorrecto.\")\n            return False\n        for char in text:\n            if char not in list(self.valid_characters):\n                print(\"Caracter no soportado encontrado.\")\n                return False\n        return True\n\n    def try_code(self, text):\n        if text == self.access_code:\n            print(\"Codigo correcto. Acceso concedido.\")\n            print(\"Bienvenido Santa!\")\n            return True\n        for index, char in enumerate(text):\n            if char == self.access_code[index]:\n                print(f\"Caracter '{char}' (posición: {index+1}) es correcto.\")\n            elif char in self.access_code:\n                print(f\"Caracter '{char}' esta presente, pero no en la posición: {index+1}.\")\n            else:\n                print(f\"Caracter '{char}' incorrecto: no existe en el codigo secreto.\")\n        return False\n    \n    def entry_acceess(self):\n        print(\"Bienvenido\")\n        for i in range(10):\n            print(f\"Ingrese el codigo de acceso (caracteres disponibles {self.valid_characters} y longitud 4): \")\n            code = input(f\"Intento {i+1}: \").lower()\n            if santa_workshop_access.valid_text(code):\n                status = santa_workshop_access.try_code(code)\n                if status:\n                    break\n        if not status:\n            print(\"Ha fallado en los 10 intentos, bloque permanente activado!\")\n            print(\"No habra regalos en esta navidad! :(\")\n\nsanta_workshop_access = WorkshopAccess()\nsanta_workshop_access.entry_acceess()    \n"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/python/JesusWay69.py",
    "content": "import os, platform, random, re\n\nif (platform.platform().startswith(\"macOS\") or platform.platform().startswith(\"Linux\")):\n    os.system('clear')\nelse:\n    os.system('cls')\n\n\"\"\" * EJERCICIO:\n * Papá Noel tiene que comenzar a repartir los regalos...\n * ¡Pero ha olvidado el código secreto de apertura del almacén!\n *\n * Crea un programa donde introducir códigos y obtener pistas.\n *\n * Código:\n * - El código es una combinación de letras y números aleatorios\n *   de longitud 4. (Letras: de la A a la C, Números: del 1 al 3)\n * - No hay repetidos.\n * - Se genera de manera aleatoria al iniciar el programa.\n *\n * Usuario:\n * - Dispone de 10 intentos para acertarlo.\n * - En cada turno deberá escribir un código de 4 caracteres, y\n *   el programa le indicará para cada uno lo siguiente:\n *   - Correcto: Si el caracter está en la posición correcta.\n *   - Presente: Si el caracter existe, pero esa no es su posición.\n *   - Incorrecto: Si el caracter no existe en el código secreto.\n * - Deben controlarse errores de longitud y caracteres soportados.\n *\n * Finalización:\n * - Papa Noel gana si descrifra el código antes de 10 intentos.\n * - Pierde si no lo logra, ya que no podría entregar los regalos.\"\"\"\n\nhidden_code = [\"?\",\"?\",\"?\",\"?\"]\npassword = random.sample((\"A\", \"B\", \"C\", \"1\", \"2\", \"3\"), 4)\nattempts = 10\n\nprint(\"Introduzca una clave de 4 caracteres que contenga A, B, C, 1, 2 0 3 sin repeticiones\")\n\nwhile attempts > 0:\n    attempt = input(\"Introduzca la clave: \").upper()\n    if re.match(\"[A-C1-3]{4}\", attempt):\n        for index, (item1, item2) in enumerate(zip(password, attempt)):\n            if item1 == item2:\n                print(f\"El caracter '{item1}' está en la contraseña en su posición \")\n                hidden_code[index] = password[index]\n            elif item2 in password:\n                print(f\"El caracter '{item2}' está en la contraseña pero no lo has puesto en su posición\")\n            else:\n                print(f\"El caracter '{item2}' no está en la contraseña\")\n                \n        print(\"Contraseña:\", end=\" \")\n        [print(\"\\b\", char, end=' ') for char in hidden_code]\n        if hidden_code.count(\"?\") == 1: print(\"\\n¡ANIMO! YA CASI LO  TIENES\") \n        if \"\".join(hidden_code) == attempt:\n            print(\"\\n\\n¡¡ENHORABUENA, HAS ADIVINADO LA CONTRASEÑA!!\")\n            print(\"\\n      *****FELIZ NAVIDAD*****\")\n            break\n    else:\n        print(\"\\nEl código introducido tiene una longitud diferente a 4 o tiene algún caracter no válido.\")\n        print(\"Pierdes un intento.\")\n    \n    attempts -= 1\n    if attempts > 0: print(f\"\\n\\nTe {f\"quedan {attempts} intentos\" if attempts > 1 else f\"queda 1 intento\"} para adivinar la contraseña\")\n    if attempts == 0:\n        print(\"\\n\\nSe te han acabado los intentos, Papá Noel no podrá entregar los regalos 😔\")\n        print(f\"La contraseña es: {\"\".join(password)} , era muy sencilla.. \")\n        \n    \n"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/python/Nicojsuarez2.py",
    "content": "# #49 EL ALMACÉN DE PAPÁ NOEL\n> #### Dificultad: Media | Publicación: 09/12/24 | Corrección: 23/12/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Papá Noel tiene que comenzar a repartir los regalos...\n * ¡Pero ha olvidado el código secreto de apertura del almacén!\n *\n * Crea un programa donde introducir códigos y obtener pistas.\n * \n * Código:\n * - El código es una combinación de letras y números aleatorios\n *   de longitud 4. (Letras: de la A a la C, Números: del 1 al 3)\n * - No hay repetidos.\n * - Se genera de manera aleatoria al iniciar el programa.\n * \n * Usuario:\n * - Dispone de 10 intentos para acertarlo.\n * - En cada turno deberá escribir un código de 4 caracteres, y \n *   el programa le indicará para cada uno lo siguiente:\n *   - Correcto: Si el caracter está en la posición correcta.\n *   - Presente: Si el caracter existe, pero esa no es su posición.\n *   - Incorrecto: Si el caracter no existe en el código secreto.\n * - Deben controlarse errores de longitud y caracteres soportados.\n * \n * Finalización:\n * - Papa Noel gana si descifra el código antes de 10 intentos.\n * - Pierde si no lo logra, ya que no podría entregar los regalos.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/python/cdryampi.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * Papá Noel tiene que comenzar a repartir los regalos...\n#  * ¡Pero ha olvidado el código secreto de apertura del almacén!\n#  *\n#  * Crea un programa donde introducir códigos y obtener pistas.\n#  * \n#  * Código:\n#  * - El código es una combinación de letras y números aleatorios\n#  *   de longitud 4. (Letras: de la A a la C, Números: del 1 al 3)\n#  * - No hay repetidos.\n#  * - Se genera de manera aleatoria al iniciar el programa.\n#  * \n#  * Usuario:\n#  * - Dispone de 10 intentos para acertarlo.\n#  * - En cada turno deberá escribir un código de 4 caracteres, y \n#  *   el programa le indicará para cada uno lo siguiente:\n#  *   - Correcto: Si el caracter está en la posición correcta.\n#  *   - Presente: Si el caracter existe, pero esa no es su posición.\n#  *   - Incorrecto: Si el caracter no existe en el código secreto.\n#  * - Deben controlarse errores de longitud y caracteres soportados.\n#  * \n#  * Finalización:\n#  * - Papa Noel gana si descrifra el código antes de 10 intentos.\n#  * - Pierde si no lo logra, ya que no podría entregar los regalos.\n#  */\n\nimport random\n\nclass Codigo:\n    BASE = ['A', 'B', 'C', '1', '2', '3']\n    CORRECTO = 'Correcto'\n    PRESENTE = 'Presente'\n    INCORRECTO = 'Incorrecto'\n\n    def __init__(self):\n        self.code = random.sample(self.BASE, 4)\n    def check_character_valid(self, character: str) -> bool:\n        return character in self.BASE\n\n    def check_character_status(self, value: str, pos: int) -> str:\n        if value == self.code[pos]:\n            return self.CORRECTO\n        if value in self.code:\n            return self.PRESENTE\n        return self.INCORRECTO\n\n    def __str__(self) -> str:\n        return \"\".join(self.code)\n\n\nclass UserControl:\n    MAX_INTENTOS = 10\n\n    def __init__(self):\n        self.codigo = Codigo()\n        self.intentos = self.MAX_INTENTOS\n        print(\"Bienvenido al Almacén de Papá Noel.\\nUtiliza letras de la A a la C y números del 1 al 3.\")\n        self.run_game()\n\n    def run_game(self):\n        while self.intentos > 0:\n            if self.new_code():\n                break\n            print(f\"Te quedan {self.intentos} intentos.\")\n\n    def new_code(self) -> bool:\n        if self.intentos <= 0:\n            print(\"Has perdido el juego. Has superado los 10 intentos.\")\n            return False\n\n        self.__NEW_CODE = input(\"Introduce un código de 4 dígitos:\\n\").strip().upper()\n        self.intentos -= 1\n\n        if len(self.__NEW_CODE) != 4 or not all(self.codigo.check_character_valid(c) for c in self.__NEW_CODE):\n            print(\"El código que has introducido no es válido.\\nPor favor, introduce un código de 4 dígitos.\\nLos dígitos válidos son letras de la A a la C y números del 1 al 3.\")\n            return False\n\n        if self.check_code():\n            return True\n        return False\n\n    def check_code(self) -> bool:\n        status = [self.codigo.check_character_status(c, i) for i, c in enumerate(self.__NEW_CODE)]\n        if all(s == Codigo.CORRECTO for s in status):\n            print(\"¡El código que has introducido es correcto!\\nHas descifrado el código del Almacén.\")\n            return True\n        else:\n            result = [f\"{c} - {s} \" for c,s in zip(self.__NEW_CODE, status)]\n            print(\" \".join(result))\n\n        return False\n\n\nif __name__ == \"__main__\":\n    control = UserControl()"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/python/davidrguez98.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * Papá Noel tiene que comenzar a repartir los regalos...\n * ¡Pero ha olvidado el código secreto de apertura del almacén!\n *\n * Crea un programa donde introducir códigos y obtener pistas.\n * \n * Código:\n * - El código es una combinación de letras y números aleatorios\n *   de longitud 4. (Letras: de la A a la C, Números: del 1 al 3)\n * - No hay repetidos.\n * - Se genera de manera aleatoria al iniciar el programa.\n * \n * Usuario:\n * - Dispone de 10 intentos para acertarlo.\n * - En cada turno deberá escribir un código de 4 caracteres, y \n *   el programa le indicará para cada uno lo siguiente:\n *   - Correcto: Si el caracter está en la posición correcta.\n *   - Presente: Si el caracter existe, pero esa no es su posición.\n *   - Incorrecto: Si el caracter no existe en el código secreto.\n * - Deben controlarse errores de longitud y caracteres soportados.\n * \n * Finalización:\n * - Papa Noel gana si descrifra el código antes de 10 intentos.\n * - Pierde si no lo logra, ya que no podría entregar los regalos.\n */ \"\"\"\n\nimport random\n\nletters = [\"A\", \"B\", \"C\"]\nnumbers = [\"1\", \"2\", \"3\"]\npassword_elements = letters + numbers\n\ndef generate_password() -> str:\n    return \"\".join(random.sample(password_elements, 4))\n\nsecret_password = generate_password()\nattemps = 1\n\nwhile attemps <= 10:\n    \n    print(f\"Intento {attemps}\")\n\n    password = input(\"Introduce la contraseña: \").upper()\n\n    if len(password) != 4:\n        print(\"La contraseña debe de tener 4 caracteres.\")\n        continue\n    if not all(character in password_elements for character in password):\n        print(f\"Solo se permiten los caracteres {password_elements}\")\n        continue\n\n    if password == secret_password:\n        print(\"¡Contraseña correcta! Has descifrado el código del almacén.\")\n        break\n    \n    attemps += 1\n\n    if attemps > 10:\n        print(\"Los 10 intentos para descrifrar el código han finalizado.\")\n    else:\n        for index, character in enumerate(password):\n            if character == secret_password[index]:\n                print(f\"{character}: Correcto.\")\n            elif character in secret_password:\n                print(f\"{character}: Presente\")\n            else:\n                print(f\"{character}: Incorrecto\")"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/python/duendeintemporal.py",
    "content": "#49 { Retos para Programadores } ALMACEN DE PAPÁ NOEL \n\n# Bibliography reference:\n# I use GPT as a reference and sometimes to correct or generate proper comments.\n\n\"\"\"\nEJERCICIO:\n * Papá Noel tiene que comenzar a repartir los regalos...\n * ¡Pero ha olvidado el código secreto de apertura del almacén!\n *\n * Crea un programa donde introducir códigos y obtener pistas.\n *\n * Código:\n * - El código es una combinación de letras y números aleatorios\n *   de longitud 4. (Letras: de la A a la C, Números: del 1 al 3)\n * - No hay repetidos.\n * - Se genera de manera aleatoria al iniciar el programa.\n *\n * Usuario:\n * - Dispone de 10 intentos para acertarlo.\n * - En cada turno deberá escribir un código de 4 caracteres, y\n *   el programa le indicará para cada uno lo siguiente:\n *   - Correcto: Si el caracter está en la posición correcta.\n *   - Presente: Si el caracter existe, pero esa no es su posición.\n *   - Incorrecto: Si el caracter no existe en el código secreto.\n * - Deben controlarse errores de longitud y caracteres soportados.\n *\n * Finalización:\n * - Papa Noel gana si descrifra el código antes de 10 intentos.\n * - Pierde si no lo logra, ya que no podría entregar los regalos.\n\n\"\"\"\n\nlog = print\n\nimport random\nimport re\n\n# Function to generate a random code\ndef generate_code():\n    characters = ['A', 'B', 'C', '1', '2', '3']\n    code_set = set()\n\n    while len(code_set) < 4:\n        random_character = random.choice(characters)\n        code_set.add(random_character)\n\n    return ''.join(code_set)\n\n# Function to provide feedback on the user's guess\ndef provide_feedback(secret_code, user_guess):\n    feedback = {\n        'correct': 0,\n        'present': 0,\n        'incorrect': 0\n    }\n\n    checked_indices = set()\n    guess_checked = [False] * len(user_guess)\n\n    # Check for correct positions\n    for i in range(len(secret_code)):\n        if user_guess[i] == secret_code[i]:\n            feedback['correct'] += 1\n            checked_indices.add(i)\n            guess_checked[i] = True\n\n    # Check for present characters\n    for i in range(len(user_guess)):\n        if not guess_checked[i]:\n            for j in range(len(secret_code)):\n                if user_guess[i] == secret_code[j] and j not in checked_indices:\n                    feedback['present'] += 1\n                    checked_indices.add(j)\n                    guess_checked[i] = True\n                    break\n\n    # Calculate incorrect characters\n    feedback['incorrect'] = len(user_guess) - feedback['correct'] - feedback['present']\n\n    return feedback\n\ndef start_game():\n    secret_code = generate_code()\n    attempts = 10\n    game_won = False\n\n    log(\"Welcome to the Secret Code Game!\")\n    log(\"You have 10 attempts to guess the 4-character code.\")\n    log(\"The code consists of letters (A, B, C) and numbers (1, 2, 3) without repetitions.\")\n\n    def ask_for_guess():\n        nonlocal attempts, game_won\n        user_guess = input(f\"You have {attempts} attempts left. Enter your guess (4 characters): \")\n\n        # Validate input\n        if len(user_guess) != 4 or not re.match(r'^[A-C1-3]+$', user_guess):\n            log(\"Invalid input. Please enter exactly 4 characters using A, B, C, 1, 2, or 3.\")\n            ask_for_guess()  # Ask again\n            return\n\n        feedback = provide_feedback(secret_code, user_guess)\n        log(f\"Feedback: Correct: {feedback['correct']}, Present: {feedback['present']}, Incorrect: {feedback['incorrect']}\")\n\n        if feedback['correct'] == 4:\n            game_won = True\n            log(\"Congratulations! You've guessed the secret code!\")\n            return\n\n        attempts -= 1\n        if attempts > 0:\n            ask_for_guess()  # Ask for the next guess\n        else:\n            log(f\"Sorry, you've run out of attempts. The secret code was: {secret_code}\")\n\n    ask_for_guess()\n\nstart_game()\n\n"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/python/edaagapu.py",
    "content": "#  EJERCICIO:\n#  Papá Noel tiene que comenzar a repartir los regalos...\n#  ¡Pero ha olvidado el código secreto de apertura del almacén!\n\n#  Crea un programa donde introducir códigos y obtener pistas.\n \n#  Código:\n#  - El código es una combinación de letras y números aleatorios\n#    de longitud 4. (Letras: de la A a la C, Números: del 1 al 3)\n#  - No hay repetidos.\n#  - Se genera de manera aleatoria al iniciar el programa.\n \n#  Usuario:\n#  - Dispone de 10 intentos para acertarlo.\n#  - En cada turno deberá escribir un código de 4 caracteres, y \n#    el programa le indicará para cada uno lo siguiente:\n#    - Correcto: Si el caracter está en la posición correcta.\n#    - Presente: Si el caracter existe, pero esa no es su posición.\n#    - Incorrecto: Si el caracter no existe en el código secreto.\n#  - Deben controlarse errores de longitud y caracteres soportados.\n \n#  Finalización:\n#  - Papa Noel gana si descrifra el código antes de 10 intentos.\n#  - Pierde si no lo logra, ya que no podría entregar los regalos.\n\nfrom random import randint\n\nclass Password:\n  def __init__(self):\n    self.available_characters = ['1', '2', '3', 'A', 'B', 'C']\n    self.password_size = 4\n    self._password = self.__generate_password__()\n  \n  def __generate_password__(self) -> str:\n    password = ''\n    while len(password) < self.password_size:\n      select_character = self.available_characters[randint(0, len(self.available_characters)-1)]\n      if select_character not in password:\n        password += select_character\n    return password\n  \n  def __eq__(self, value : list) -> tuple:\n    validation = []\n    if len(value) != self.password_size:\n      raise Exception(f'La longitud de la contraseña debe ser de {self.password_size}')\n\n    for f_char, s_char in zip(list(self._password), value):\n      if s_char not in self.available_characters:\n        raise Exception(f'El/los caracter(es) ingresados no hacen parte del vocabulario, recuerde que los permitidos son: {self.available_characters}')\n      if f_char == s_char:\n        validation.append((s_char, 'Correcto'))\n      elif s_char in self._password:\n        validation.append((s_char, 'Presente'))\n      else:\n        validation.append((s_char, 'Incorrecto'))\n    \n    return (''.join(value) == self._password, validation)\n\nif __name__ == '__main__':\n  pass_obj = Password()\n  print(f\"\"\"Bienvenido al almacén de Papá Noel:\n  Tu objetivo es adivinar la contraseña del almacen para poder entregar los regalos a tiempo.\n  ¡Tienes 10 intentos!\n  Recuerda:\n    - Los caracteres permitidos son: {pass_obj.available_characters}\n    - La longitud de la contraseña es: {pass_obj.password_size}\n  \"\"\")\n  for turn in range(1,11):\n    try:\n      user_password = list(input(f'(Turno No. {turn}) Ingresa tu contraseña: '))\n      validation, position_chars = pass_obj == user_password\n      if validation:\n        break\n      print(' | '.join([f'({character}) {validation}' for character, validation in position_chars]))\n    except Exception as error:\n      print(error)\n      continue\n  if validation and turn <= 10:\n    print('Felicitaciones has logrado descifrar la contraseña del almacen')\n  else:\n    print('Infortunadamente Papá Noel no podrá entregar los regalos, ya que no descifraste la contraseña del almacen')"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/python/edisonlmg.py",
    "content": "#=======================================================================================================================\n# 49 El almacen de Papá Noel\n#=======================================================================================================================\n\n# Importar librerias\nimport random\nimport re\n\n# Expresion regular para password\npattern = r'^(?!.*(.).*\\1)[ABC123]{4}$'\n\n# Generar password aleatorio\npsw = ''.join(random.sample('ABC123', k=4))\n\n# Inicio de juego\nprint('''\n    \\n¡Bienvenido Papá Noel, es hora de repartir regalos!\n    \\nPara abrir al almacén de juguetes digita la clave de ingreso\n(tienes 10 intentos).\n    \\nPista: La contraseña debe contener 4 caracteres sin repeticiones y solo acepta\nlos valores A,B,C,1,2 y 3.\n    ''')\n\n# Inicio de bucle\n\nintento = 0\n\nwhile intento <= 10:\n\n    # Iniciar contador\n    intento += 1\n\n    # Si se excedio de 10 intentos terminar el juego\n    if intento > 10:\n        print('''\n            \\n¡Oh, no. Papá Noel has olvidado la contraseña!\n    Ya no te quedan más intentos.\n          ''')\n        break\n\n    # Solicitar el ingreso de un password\n    print(f'\\nIntento n.° {intento}:')\n    psw_in = input('\\nIngresa contraseña: ').upper()\n\n    # Comprobar si el passwor ingresado es valido\n    if bool(re.match(pattern, psw_in)):\n        pass\n    else:\n        print('''\n        \\nLa contarseña ingresada no es válida. La contraseña debe contener 4\ncaracteres sin repeticiones y solo acepta los valores A,B,C,1,2 y 3.\n        ''')\n        continue\n\n    # Si el password fue valido comprobar si es el correcto\n    if psw_in == psw:\n        print('''\n        \\n La contraseña es correcta.\n        \\n¡Felicidades, a repartir juguetes!\n        ''')\n        break\n    else: # Si el password es incorrecto dar las pistas por cada caracter\n        print(f'''\n        \\nLa contraseña es incorrecta. Pero descuida, te doy unas pistas:\n        ''')\n        for x, y in zip(psw_in, psw):\n            if x == y:\n                print(f'\\n{x}: Correcto')\n            elif x in psw:\n                print(f'\\n{x}: Presente')\n            else:\n                print(f'\\n{x}: Incorrecto')\n        print('\\n¡Vuelve a intentarlo, Papá Noel!')"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/python/giulianovfz.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Papá Noel tiene que comenzar a repartir los regalos...\n * ¡Pero ha olvidado el código secreto de apertura del almacén!\n *\n * Crea un programa donde introducir códigos y obtener pistas.\n *\n * Código:\n * - El código es una combinación de letras y números aleatorios\n *   de longitud 4. (Letras: de la A a la C, Números: del 1 al 3)\n * - No hay repetidos.\n * - Se genera de manera aleatoria al iniciar el programa.\n *\n * Usuario:\n * - Dispone de 10 intentos para acertarlo.\n * - En cada turno deberá escribir un código de 4 caracteres, y\n *   el programa le indicará para cada uno lo siguiente:\n *   - Correcto: Si el caracter está en la posición correcta.\n *   - Presente: Si el caracter existe, pero esa no es su posición.\n *   - Incorrecto: Si el caracter no existe en el código secreto.\n * - Deben controlarse errores de longitud y caracteres soportados.\n *\n * Finalización:\n * - Papa Noel gana si descrifra el código antes de 10 intentos.\n * - Pierde si no lo logra, ya que no podría entregar los regalos.\n \"\"\"\nimport random\n\n\ndef generar_clave():\n    \"\"\"\n    Se genera la clave que debe descubrir el usuario, y solo tiene 4 caracteres\n    \"\"\"\n\n    letras = [\"A\", \"B\", \"C\"]\n    numeros = [1, 2, 3]\n    union = letras + numeros\n\n    return random.sample(union, k=4)\n\n\ndef validar_clave(clave, ingreso):\n    \"\"\"\n    Evalua caracter por caracter para saber su estado si es correcto, presente o incorrecto\n    \"\"\"\n    valida_caracter = []\n\n    def evaluar(valor):\n\n        if valor in clave and (ingreso.index(str(valor)) == clave.index(valor)):\n            valida_caracter.append('Correcto')\n        elif valor in clave:\n            valida_caracter.append('Presente')\n        else:\n            valida_caracter.append('Incorrecto')\n\n    for valor in ingreso:\n\n        if valor.isdigit():\n            numero = int(valor)\n            evaluar(numero)\n        else:\n            evaluar(valor)\n\n    return valida_caracter\n\n\ndef main():\n    \"\"\"\n    Se le solicita al usuario ingresar una contraseña para realizar su validación\n    \"\"\"\n    clave = generar_clave()\n    i = 0\n\n    mensaje = '''\\n\\tDebes ayudar al viejo pascuero; se le olvidó la contraseña del almacén.\n        Tienes que descubrir la contraseña, la cual \\033[1;37;47mestá compuesta por letras de la A a la C \\033[0;m \n        \\033[1;37;47my por números del 1 al 3.\\033[0;m Tiene una longitud de 4 caracteres.\n        A continuación, se solicitará que ingreses la clave, tienes solo 10 intentos.\n        '''\n    print(mensaje)\n\n    while i < 10:\n        i += 1\n        print(f'\\n\\tIntento {i} |{\"»\"*40}')\n        clave_ingresada = input(\n            '\\n\\t• Ingresa la clave(de 4 Caracteres):').upper()\n\n        if len(clave_ingresada) > 5:\n            print(\n                '\\n\\nError, desperdiciaste una oportunidad, recuerda ingresa solo 4 Caracteres\\n')\n        else:\n\n            validacion = validar_clave(clave, clave_ingresada)\n\n            print(f'\\n\\t{validacion}\\n')\n\n            if i == 10 and (validacion.count(\"Correcto\") != 4):\n                print(\n                    '\\n\\tLamentablemente, finalizaron los intentos para descubrir la contraseña del almacén')\n                print(\n                    '\\n\\tPor lo tanto, el viejo pascuero no puede entregar los regalos.')\n\n            elif validacion.count(\"Correcto\") == 4:\n                print(\n                    '\\n\\t¡Felicitaciones! Lograste adivinar la clave, pueden abrir el almacén\\n')\n                break\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/python/hectorio23.py",
    "content": "# Autor: Héctor Adán\n# GitHub: https://github.com/hectorio23\n\nimport random\n\ndef generate_secret_code():\n    pool = ['A', 'B', 'C', '1', '2', '3']\n    random.shuffle(pool)\n    return ''.join(pool[:4])\n\ndef evaluate_guess(secret, guess):\n    for i in range(4):\n        if guess[i] == secret[i]:\n            print(f\"{guess[i]}: Correcto\")\n        elif guess[i] in secret:\n            print(f\"{guess[i]}: Presente\")\n        else:\n            print(f\"{guess[i]}: Incorrecto\")\n\ndef is_valid_guess(guess):\n    if len(guess) != 4:\n        print(\"El código debe tener exactamente 4 caracteres.\")\n        return False\n\n    valid_chars = {'A', 'B', 'C', '1', '2', '3'}\n    for char in guess:\n        if char not in valid_chars:\n            print(f\"Caracter inválido encontrado: {char}\")\n            return False\n\n    return True\n\ndef main():\n    secret_code = generate_secret_code()\n    attempts = 10\n\n    print(\"\\n¡Bienvenido al juego del código secreto de Papá Noel!\")\n    print(\"Debes adivinar el código secreto de 4 caracteres.\")\n    print(\"Letras: A, B, C | Números: 1, 2, 3\\n\")\n\n    while attempts > 0:\n        print(f\"\\nIntentos restantes: {attempts}\")\n        guess = input(\"Introduce tu código: \").strip().upper()\n\n        if not is_valid_guess(guess):\n            continue\n\n        if guess == secret_code:\n            print(f\"¡Felicidades! Has descifrado el código secreto: {secret_code}\")\n            return\n\n        evaluate_guess(secret_code, guess)\n        attempts -= 1\n\n    print(f\"\\nLo siento, no has logrado descifrar el código secreto. Era: {secret_code}\")\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/python/hozlucas28.py",
    "content": "# pylint: disable=missing-module-docstring,missing-class-docstring,missing-function-docstring\n\nfrom abc import ABCMeta, abstractmethod\nfrom random import choice\nfrom re import match\n\n# ---------------------------------------------------------------------------- #\n#                                    CLASSES                                   #\n# ---------------------------------------------------------------------------- #\n\n\nclass AbcPasswordGenerator(metaclass=ABCMeta):\n    @property\n    @abstractmethod\n    def fail_attempts(self) -> int:\n        pass\n\n    @property\n    @abstractmethod\n    def length(self) -> int:\n        pass\n\n    @abstractmethod\n    def get_advice(self, *, password: str) -> str:\n        pass\n\n    @abstractmethod\n    def is_password(self, *, password: str) -> bool:\n        pass\n\n\nclass PasswordGenerator(AbcPasswordGenerator):\n    __fail_attempts: int\n    __length: int\n    __password_hash: str\n    __password: str\n\n    def __init__(self, *, _hash: str, length: int) -> None:\n        self.__fail_attempts = 0\n        self.__password_hash = _hash\n        self.__length = length\n\n        password: str = \"\"\n        while len(password) < self.__length:\n            rnd_char: str = choice(seq=self.__password_hash)\n            if not rnd_char in password:\n                password += rnd_char\n\n        self.__password = password\n\n    def get_advice(self, *, password: str) -> str:\n        advice: list[str] = []\n\n        for i, char in enumerate(iterable=password):\n            password_char: str = self.__password[i]\n\n            if char == password_char:\n                advice.append(f'  - \"{char}\" is in the correct position.')\n                continue\n\n            if char in self.__password:\n                advice.append(\n                    f'  - \"{char}\" exist but it\\'s not in the {i + 1}th position.'\n                )\n                continue\n\n            advice.append(f'  - \"{char}\" not exist in the password.')\n\n        return \"\\n\".join(advice)\n\n    @property\n    def fail_attempts(self) -> int:\n        return self.__fail_attempts\n\n    @property\n    def length(self) -> int:\n        return self.__length\n\n    def is_password(self, *, password: str) -> bool:\n        if self.__password == password:\n            return True\n\n        self.__fail_attempts += 1\n        return False\n\n\n# ---------------------------------------------------------------------------- #\n#                                     MAIN                                     #\n# ---------------------------------------------------------------------------- #\n\n_hash: str = \"ABC123\"\n_length: int = 4\n\npasswordGenerator: AbcPasswordGenerator = PasswordGenerator(_hash=_hash, length=_length)\n\nregex: str = rf\"^[{_hash}]{{{_length}}}$\"\n\nuserInput: str = input(\"> Enter the password (maximum of 4 chars): \").strip()\n\nwhile match(pattern=regex, string=userInput) is None:\n    print(\n        \"\\n> Error! The password length must be 4 characters, \"\n        f'and it should contain any of these characters: \"{_hash}\". Try again...'\n    )\n    userInput = input(\"\\n> Enter the password (maximum of 4 chars): \").strip()\n\n\nwhile (\n    not passwordGenerator.is_password(password=userInput)\n    and passwordGenerator.fail_attempts < 10\n):\n    print(f\"\\n{passwordGenerator.get_advice(password=userInput)}\")\n\n    print(\"\\n> Invalid password! Try again...\")\n\n    userInput: str = input(\"\\n> Enter the password (maximum of 4 chars): \").strip()\n\n    while match(pattern=regex, string=userInput) is None:\n        print(\n            \"\\n> Error! The password length must be 4 characters, \"\n            f'and it should contain any of these characters: \"{_hash}\". Try again...'\n        )\n        userInput = input(\"\\n> Enter the password (maximum of 4 chars): \").strip()\n\n\nif passwordGenerator.fail_attempts < 10:\n    print(f'\\n> Santa won! The password is \"{userInput}\".')\nelse:\n    print(\"\\n> Santa lost! Storage will be closed forever.\")\n"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/python/idiegorojas.py",
    "content": "\"\"\"\n# 49 - Almacen de papa noel\n\"\"\"\n# Crea un programa donde introducir códigos y obtener pistas.\n\n# Código:\n# El código es una combinación de letras y números aleatorios de longitud 4. (Letras: de la A a la C, Números: del 1 al 3)\n# No hay repetidos.\n# Se genera de manera aleatoria al iniciar el programa.\n\n# Usuario:\n# Dispone de 10 intentos para acertarlo.\n# En cada turno deberá escribir un código de 4 caracteres, y el programa le indicará para cada uno lo siguiente:\n    # Correcto: Si el caracter está en la posición correcta.\n    # Presente: Si el caracter existe, pero esa no es su posición.\n    # Incorrecto: Si el caracter no existe en el código secreto.\n# Deben controlarse errores de longitud y caracteres soportados.\n\n# Finalización:\n# Papa Noel gana si descifra el código antes de 10 intentos.\n# Pierde si no lo logra, ya que no podría entregar los regalos.\n\nimport random\n\n# Generar código secreto aleatorio (4 caracteres sin repetición)\nposibles_caracteres = ['A', 'B', 'C', '1', '2', '3']\ncodigo_secreto = ''.join(random.sample(posibles_caracteres, 4))\n\n# Configurar número de intentos\nintentos_maximos = 10\nintentos_usados = 0\nvictoria = False\n\n# Lista de caracteres válidos para validación\ncaracteres_validos = set(posibles_caracteres)\n\nprint(\"¡Bienvenido al Almacén de Papa Noel!\")\nprint(\"Tienes que adivinar el código secreto para entrar.\")\nprint(\"El código tiene 4 caracteres (letras A-C y números 1-3) sin repeticiones.\")\nprint(f\"Tienes {intentos_maximos} intentos para adivinarlo.\")\n\n# Bucle principal del juego\nwhile intentos_usados < intentos_maximos and not victoria:\n    intentos_usados += 1\n    print(f\"\\nIntento {intentos_usados} de {intentos_maximos}\")\n    \n    # Obtener y validar la entrada del usuario\n    while True:\n        intento = input(\"Ingresa tu código de 4 caracteres: \").upper()\n        \n        # Verificar longitud\n        if len(intento) != 4:\n            print(\"Error: El código debe tener exactamente 4 caracteres.\")\n            continue\n        \n        # Verificar caracteres válidos\n        if not all(c in caracteres_validos for c in intento):\n            print(\"Error: Solo se permiten letras A-C y números 1-3.\")\n            continue\n        \n        # Verificar que no haya repeticiones\n        if len(set(intento)) != 4:\n            print(\"Error: El código no debe contener caracteres repetidos.\")\n            continue\n        \n        break  # Si pasamos todas las validaciones, salimos del bucle\n    \n    # Analizar el intento\n    resultado = []\n    aciertos = 0\n    \n    for i in range(4):\n        if intento[i] == codigo_secreto[i]:\n            resultado.append(\"Correcto\")\n            aciertos += 1\n        elif intento[i] in codigo_secreto:\n            resultado.append(\"Presente\")\n        else:\n            resultado.append(\"Incorrecto\")\n    \n    # Mostrar resultado\n    for i in range(4):\n        print(f\"Posición {i+1} ({intento[i]}): {resultado[i]}\")\n    \n    # Verificar victoria\n    if aciertos == 4:\n        victoria = True\n\n# Mensaje final\nif victoria:\n    print(f\"\\n¡FELICIDADES! Has descifrado el código secreto en {intentos_usados} intentos.\")\n    print(\"Papa Noel podrá entregar los regalos a tiempo.\")\nelse:\n    print(f\"\\nLo siento, has agotado tus {intentos_maximos} intentos.\")\n    print(f\"El código secreto era: {codigo_secreto}\")\n    print(\"Papa Noel no podrá entregar los regalos este año.\")"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/python/ignaciovihe.py",
    "content": "\"\"\"\n * EJERCICIO:\n * Papá Noel tiene que comenzar a repartir los regalos...\n * ¡Pero ha olvidado el código secreto de apertura del almacén!\n *\n * Crea un programa donde introducir códigos y obtener pistas.\n * \n * Código:\n * - El código es una combinación de letras y números aleatorios\n *   de longitud 4. (Letras: de la A a la C, Números: del 1 al 3)\n * - No hay repetidos.\n * - Se genera de manera aleatoria al iniciar el programa.\n * \n * Usuario:\n * - Dispone de 10 intentos para acertarlo.\n * - En cada turno deberá escribir un código de 4 caracteres, y \n *   el programa le indicará para cada uno lo siguiente:\n *   - Correcto: Si el caracter está en la posición correcta.\n *   - Presente: Si el caracter existe, pero esa no es su posición.\n *   - Incorrecto: Si el caracter no existe en el código secreto.\n * - Deben controlarse errores de longitud y caracteres soportados.\n * \n * Finalización:\n * - Papa Noel gana si descifra el código antes de 10 intentos.\n * - Pierde si no lo logra, ya que no podría entregar los regalos.\n\"\"\"\n\nimport random\nimport string\n\nclass Code:\n    def __init__(self) -> None:\n        self.chars = list(string.ascii_lowercase[:3]) + list(map(str, range(1,4)))\n        self.target_code = random.sample(self.chars, 4)\n\n    def get_code(self):\n        return self.target_code\n\nclass CodeChecker:\n    def __init__(self, code: Code) -> None:\n        self.code = code\n        \n    def check_code(self, user_code: str) -> list:\n        user_code_list = list(user_code)\n        feedback =[]\n\n        for index in range(4):\n            if user_code_list[index] == self.code.target_code[index]:\n                feedback.append(\"ok\")\n            elif user_code_list[index] in self.code.target_code:\n                feedback.append(\"!\")\n            else:\n                feedback.append(\"X\")\n        \n        return feedback\n    \n\nclass AcessController:\n    def __init__(self, code: Code, code_checker: CodeChecker) -> None:\n        self.code = code\n        self.code_checker = code_checker\n\n    def check_valid_input(self, user_code) -> bool:\n\n        valid_chars = [\"a\", \"b\", \"c\", \"1\", \"2\", \"3\"]\n        \n        if len(user_code) != 4:\n            print(\"El código debe tener 4 caracteres.\")\n            return False\n        \n        if len(set(user_code)) != 4:\n            print(\"Todos los caracteres deben ser diferentes\")\n            return False\n    \n        if not all(char in valid_chars for char in user_code):\n            print(\"Has introducido un caracter no válido.\")\n            return False\n        \n        return True\n\n\n    def run(self):\n        print(\"Introduce el código de acceso. Tienes 10 intentos para descubrirlo.\")\n        print(\"Debe tener 4 caracteres no repetidos y que esten entre (a, b, c, 1, 2, 3)\")\n        print(\"La respuesta de feedback funciona como sigue:\")\n        print(\"\\tok -> caracter y posición correcta\")\n        print(\"\\t ! -> caracter correcto pero posición incorrecta\")\n        print(\"\\t X -> caracter incorrecto\")\n\n        round = 0\n        while round < 10:\n            round += 1\n            print(f\"ROUND {round}\")\n\n            valid = False\n            while not valid:\n                user_try = input(\"Introduce tu código:\").lower()\n                valid = self.check_valid_input(user_try)\n\n            print(f\"Tu codigo: {list(user_try)}\")\n            feedback = self.code_checker.check_code(user_try)\n            print(f\"Feedback : {feedback}\")\n\n            if len(set(feedback)) == 1 and feedback[1] == \"ok\":\n                print(f\"Correcto : {self.code.get_code()}\")\n                print(f\"Has adivinado el código en {round} rondas.\")\n                break\n        if round == 10:\n            print(f\"Correcto : {self.code.get_code()}\")\n            print(\"Has perdido. No has logrado descubrir el codigo en 10 intentos.\")\n\nnew_code = Code()\ncode_checker = CodeChecker(new_code)\nacces_controller = AcessController(new_code, code_checker)\nacces_controller.run()\n"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/python/javierfiestasbotella.py",
    "content": "'''\n/*\n * EJERCICIO:\n * Papá Noel tiene que comenzar a repartir los regalos...\n * ¡Pero ha olvidado el código secreto de apertura del almacén!\n *\n * Crea un programa donde introducir códigos y obtener pistas.\n * \n * Código:\n * - El código es una combinación de letras y números aleatorios\n *   de longitud 4. (Letras: de la A a la C, Números: del 1 al 3)\n * - No hay repetidos.\n * - Se genera de manera aleatoria al iniciar el programa.\n * \n * Usuario:\n * - Dispone de 10 intentos para acertarlo.\n * - En cada turno deberá escribir un código de 4 caracteres, y \n *   el programa le indicará para cada uno lo siguiente:\n *   - Correcto: Si el caracter está en la posición correcta.\n *   - Presente: Si el caracter existe, pero esa no es su posición.\n *   - Incorrecto: Si el caracter no existe en el código secreto.\n * - Deben controlarse errores de longitud y caracteres soportados.\n * \n * Finalización:\n * - Papa Noel gana si descrifra el código antes de 10 intentos.\n * - Pierde si no lo logra, ya que no podría entregar los regalos.\n */\n'''\nimport random\n\nfabrica=['a','b','c','1','2','3']\ndef crea_contraseña(l):\n    password=''\n    while len(password)<4:\n        digito=random.choice(l)\n        if digito not in password:\n            password+=digito\n    return password\n\npassword_1=crea_contraseña(fabrica)\nprint(password_1)\n\nintento=0\nwhile intento <10:\n    sol=input('Escribe la Contraseña: ')\n    if sol==password_1:\n        print('Bien Acertaste PapáNoél Ganó')\n        break\n    else:\n        buena = [letra for letra in password_1 if letra != ' ']\n        mala = [letra for letra in sol if letra != ' ']\n        for i in range(len(password_1)):\n            if sol[i]==password_1[i]:\n                print(sol[i], 'Correcto')\n            elif sol[i] in password_1:\n                print(sol[i], 'Presente')\n            else:\n                print(sol[i], 'Incorrecto')\n    intento+=1\nif intento==10:\n    print('Lo siento no lo conseguiste')"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/python/kenysdev.py",
    "content": "# _____________________________________\n# https://github.com/kenysdev\n# 2024 - Python\n# _____________________________________\n# #49 EL ALMACÉN DE PAPÁ NOEL\n# ------------------------------------\n\n\"\"\"\n* EJERCICIO:\n * Papá Noel tiene que comenzar a repartir los regalos...\n * ¡Pero ha olvidado el código secreto de apertura del almacén!\n *\n * Crea un programa donde introducir códigos y obtener pistas.\n * \n * Código:\n * - El código es una combinación de letras y números aleatorios\n *   de longitud 4. (Letras: de la A a la C, Números: del 1 al 3)\n * - No hay repetidos.\n * - Se genera de manera aleatoria al iniciar el programa.\n * \n * Usuario:\n * - Dispone de 10 intentos para acertarlo.\n * - En cada turno deberá escribir un código de 4 caracteres, y \n *   el programa le indicará para cada uno lo siguiente:\n *   - Correcto: Si el caracter está en la posición correcta.\n *   - Presente: Si el caracter existe, pero esa no es su posición.\n *   - Incorrecto: Si el caracter no existe en el código secreto.\n * - Deben controlarse errores de longitud y caracteres soportados.\n * \n * Finalización:\n * - Papa Noel gana si descrifra el código antes de 10 intentos.\n * - Pierde si no lo logra, ya que no podría entregar los regalos.\n\"\"\"\n\n# ____________________________________________________________________________\nfrom random import sample\n\ndef verify_allowed_char(code_entry: str) -> bool:\n    for ch in code_entry:\n        if ch not in 'abc123':\n            print(\"Uno de los caracteres no está entre los permitidos.\\n\")\n            return False\n    \n    return True\n\ndef get_entry() -> str:\n    while True:\n        code_entry: str = input(\"Código: \")\n\n        if len(code_entry) != 4:\n            print(\"El código debe ser de 4 dígitos.\\n\")\n            continue\n        \n        if verify_allowed_char(code_entry):\n            return code_entry\n\ndef is_open(code: str) -> bool:\n    code_entry: str = get_entry()\n    if code_entry == code:\n        return True\n    print(\"Código inválido.\\n\")\n\n    for i, ch in enumerate(code_entry):\n        if ch == code[i]:\n            print(f\"'{ch}' está en la posición correcta.\")\n\n        elif ch in code:\n            print(f\"'{ch}' está en el código, pero en otra posición.\")\n\n        else:\n            print(f\"'{ch}' no está presente en el código.\")\n    \n    return False\n\n# ____________________________________________________________________________\nprint(\"\"\"\n* Papá Noel tiene que comenzar a repartir los regalos...\n* ¡Pero ha olvidado el código secreto de apertura del almacén!\n\n- Tienes 10 intentos para adivinar el código que abre el almacén.\n- Código de 4 caracteres. Permitidos: a, b, c, 1, 2, 3.\n- Nota: No hay dígitos repetidos.\"\"\")\n\ncode : str = ''.join(sample(\"abc123\", 4))\n\nfor attempts in range(10):\n    print(f\"\\n___________\\nIntento #{attempts + 1}\")\n\n    if is_open(code):\n        print(\"Código correcto, almacén abierto.\")\n        print(\"Papá Noel ahora podrá entregar los regalos.\")\n        break\n\n    if attempts == 9:\n        print(\"\\n___________\\nHas perdido.\")\n        print(\"Papá Noel ya no podrá entregar los regalos.\")\n\n"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/python/miguelex.py",
    "content": "import random\n\ndef generate_code():\n    return ''.join(random.sample('ABC123', 4))\n\ncode = generate_code()\nattempts = 10\n\nprint(\"¡Bienvenido! Tienes 10 intentos para descifrar el código.\")\n\nwhile attempts > 0:\n    input_code = input(f\"Intento #{attempts}. Ingresa un código de 4 caracteres: \").upper()\n\n    if len(input_code) != 4 or not all(c in 'ABC123' for c in input_code):\n        print(\"Código inválido. Debe tener 4 caracteres (letras A-C, números 1-3).\")\n        continue\n\n    result = []\n    for i, char in enumerate(input_code):\n        if char == code[i]:\n            result.append(\"Correcto\")\n        elif char in code:\n            result.append(\"Presente\")\n        else:\n            result.append(\"Incorrecto\")\n\n    print(\", \".join(result))\n\n    if input_code == code:\n        print(f\"¡Felicidades! Descifraste el código: {code}\")\n        break\n\n    attempts -= 1\n\nif attempts == 0:\n    print(f\"Lo siento, no lograste descifrar el código: {code}\")\n"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/python/mouredev.py",
    "content": "import random\n\nletters = [\"A\", \"B\", \"C\"]\nnumbers = [\"1\", \"2\", \"3\"]\npassword_elements = letters + numbers\n\n\ndef generate_password() -> str:\n    return \"\".join(random.sample(password_elements, 4))\n\n\nsecret_password = generate_password()\nattempts = 1\n\nprint(\"Adivina la contraseña del almacén de Papá Noel.\")\n\nwhile attempts <= 10:\n\n    print(f\"Intento: {attempts}\")\n\n    password = input(\"Introduce la contraseña: \").upper()\n\n    if len(password) != 4:\n        print(\"Error: La contraseña debe tener 4 caracteres.\")\n        continue\n    if not all(character in password_elements for character in password):\n        print(f\"Error: Sólo se permiten los caracteres {password_elements}.\")\n        continue\n\n    if password == secret_password:\n        print(\"¡Contraseña correcta! Has descifrado el código del almacén. Feliz Navidad.\")\n        break\n\n    attempts += 1\n\n    if attempts > 10:\n        print(\"Lo siento, los 10 intentos para descifrar el código han finalizado.\")\n        print(\"Papá Noel no ha podido entregar los regalos.\")\n    else:\n        for index, character in enumerate(password):\n            if character == secret_password[index]:\n                print(f\"{character}: Correcto\")\n            elif character in secret_password:\n                print(f\"{character}: Presente\")\n            else:\n                print(f\"{character}: Incorrecto\")\n"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/python/neslarra.py",
    "content": "r\"\"\"\n EJERCICIO:\n Papá Noel tiene que comenzar a repartir los regalos...\n ¡Pero ha olvidado el código secreto de apertura del almacén!\n\n Crea un programa donde introducir códigos y obtener pistas.\n \n Código:\n - El código es una combinación de letras y números aleatorios\n   de longitud 4. (Letras: de la A a la C, Números: del 1 al 3)\n - No hay repetidos.\n - Se genera de manera aleatoria al iniciar el programa.\n \n Usuario:\n - Dispone de 10 intentos para acertarlo.\n - En cada turno deberá escribir un código de 4 caracteres, y \n   el programa le indicará para cada uno lo siguiente:\n   - Correcto: Si el caracter está en la posición correcta.\n   - Presente: Si el caracter existe, pero esa no es su posición.\n   - Incorrecto: Si el caracter no existe en el código secreto.\n - Deben controlarse errores de longitud y caracteres soportados.\n \n Finalización:\n - Papa Noel gana si descrifra el código antes de 10 intentos.\n - Pierde si no lo logra, ya que no podría entregar los regalos.\n\"\"\"\nfrom random import randint\ncharacters = [\"a\", \"1\", \"b\", \"2\", \"c\", \"3\"]\ntries = 10\naccess_granted = False\n\n\ndef create_passkey() -> str:\n    pass_characters = characters.copy()\n    passkey = \"\"\n    while passkey.__len__() < 4:\n        character = pass_characters.pop(randint(0, pass_characters.__len__() - 1))\n        passkey += character\n\n    return passkey\n\n\ndef validate_entry(word: str, passkey: str) -> bool:\n    if word == passkey:\n        print(\"Acceso Permitido.\")\n        return True\n    if word.__len__() != 4:\n        print(\"Error: la longitud DEBE ser igual a cuatro caracteres.\")\n        return False\n    if [x for x in word if x in characters].__len__() != 4:\n        print(\"Error: solo son válidos los carateres a, b, c, 1, 2, 3\")\n        return False\n    for x, y in zip(word, passkey):\n        if x not in passkey:\n            print(f\"{x} no es parte de la clave\")\n        elif x == y:\n            print(f\"{x} está en la posioción CORRECTA\")\n        else:\n            print(f\"{x} está en la posioción INCORRECTA\")\n    print(\"Acceso DENEGADO\")\n    return False\n\n\npasskey = create_passkey()\n# print(passkey)\nwhile tries > 0 and not access_granted:\n    word = input(f\"Ingrese la palabra clave (intento# {11 - tries}): \")\n    access_granted = validate_entry(word, passkey)\n    tries -= 1\n"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/rust/kenysdev.rs",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - Rust\n_____________________________________\n#49 EL ALMACÉN DE PAPÁ NOEL\n------------------------------------\n\n * EJERCICIO:\n * Papá Noel tiene que comenzar a repartir los regalos...\n * ¡Pero ha olvidado el código secreto de apertura del almacén!\n *\n * Crea un programa donde introducir códigos y obtener pistas.\n * \n * Código:\n * - El código es una combinación de letras y números aleatorios\n *   de longitud 4. (Letras: de la A a la C, Números: del 1 al 3)\n * - No hay repetidos.\n * - Se genera de manera aleatoria al iniciar el programa.\n * \n * Usuario:\n * - Dispone de 10 intentos para acertarlo.\n * - En cada turno deberá escribir un código de 4 caracteres, y \n *   el programa le indicará para cada uno lo siguiente:\n *   - Correcto: Si el caracter está en la posición correcta.\n *   - Presente: Si el caracter existe, pero esa no es su posición.\n *   - Incorrecto: Si el caracter no existe en el código secreto.\n * - Deben controlarse errores de longitud y caracteres soportados.\n * \n * Finalización:\n * - Papa Noel gana si descrifra el código antes de 10 intentos.\n * - Pierde si no lo logra, ya que no podría entregar los regalos.\n\n[dependencies]\nrand = \"0.8.5\"\n*/\n\nuse rand::seq::SliceRandom;\nuse std::io;\n\nfn verify_allowed_char(code_entry: &str) -> bool {\n    for ch in code_entry.chars() {\n        if !\"abc123\".contains(ch) {\n            println!(\"Uno de los caracteres no está entre los permitidos.\\n\");\n            return false;\n        }\n    }\n    true\n}\n\nfn get_entry() -> String {\n    loop {\n        println!(\"Código: \");\n        let mut code_entry = String::new();\n        io::stdin().read_line(&mut code_entry).unwrap();\n        let code_entry = code_entry.trim();\n\n        if code_entry.len() != 4 {\n            println!(\"El código debe ser de 4 dígitos.\\n\");\n            continue;\n        }\n\n        if verify_allowed_char(code_entry) {\n            return code_entry.to_string();\n        }\n    }\n}\n\nfn is_open(code: &str) -> bool {\n    let code_entry = get_entry();\n\n    if code_entry == code {\n        return true;\n    }\n\n    println!(\"Código inválido.\\n\");\n\n    for (i, ch) in code_entry.chars().enumerate() {\n        if code.chars().nth(i).unwrap() == ch {\n            println!(\"'{}' está en la posición correcta.\", ch);\n        } else if code.contains(ch) {\n            println!(\"'{}' está en el código, pero en otra posición.\", ch);\n        } else {\n            println!(\"'{}' no está presente en el código.\", ch);\n        }\n    }\n\n    false\n}\n\nfn main() {\n    println!(\"\n* Papá Noel tiene que comenzar a repartir los regalos...\n* ¡Pero ha olvidado el código secreto de apertura del almacén!\n\n- Tienes 10 intentos para adivinar el código que abre el almacén.\n- Código de 4 caracteres. Permitidos: a, b, c, 1, 2, 3.\n- Nota: No hay dígitos repetidos.\");\n\n    let characters = [\"a\", \"b\", \"c\", \"1\", \"2\", \"3\"];\n    let mut rng = rand::thread_rng();\n    let code: String = characters\n        .choose_multiple(&mut rng, 4)\n        .cloned()\n        .collect::<String>();\n\n    for attempts in 1..11 {\n        println!(\"\\n___________\\nIntento #{}\", attempts);\n        if is_open(&code) {\n            println!(\"Código correcto, almacén abierto.\");\n            println!(\"Papá Noel ahora podrá entregar los regalos.\");\n            break;\n        }\n\n        if attempts == 10 {\n            println!(\"\\n___________\\nHas perdido.\");\n            println!(\"Papá Noel ya no podrá entregar los regalos.\");\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/sql/Nicojsuarez2.sql",
    "content": "# #49 EL ALMACÉN DE PAPÁ NOEL\n> #### Dificultad: Media | Publicación: 09/12/24 | Corrección: 23/12/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * Papá Noel tiene que comenzar a repartir los regalos...\n * ¡Pero ha olvidado el código secreto de apertura del almacén!\n *\n * Crea un programa donde introducir códigos y obtener pistas.\n * \n * Código:\n * - El código es una combinación de letras y números aleatorios\n *   de longitud 4. (Letras: de la A a la C, Números: del 1 al 3)\n * - No hay repetidos.\n * - Se genera de manera aleatoria al iniciar el programa.\n * \n * Usuario:\n * - Dispone de 10 intentos para acertarlo.\n * - En cada turno deberá escribir un código de 4 caracteres, y \n *   el programa le indicará para cada uno lo siguiente:\n *   - Correcto: Si el caracter está en la posición correcta.\n *   - Presente: Si el caracter existe, pero esa no es su posición.\n *   - Incorrecto: Si el caracter no existe en el código secreto.\n * - Deben controlarse errores de longitud y caracteres soportados.\n * \n * Finalización:\n * - Papa Noel gana si descifra el código antes de 10 intentos.\n * - Pierde si no lo logra, ya que no podría entregar los regalos.\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/swift/rcellas.swift",
    "content": "import Foundation\n\nfunc generatePassword() -> String {\n    let letters = [\"A\", \"B\", \"C\"]\n    let numbers = [\"1\", \"2\", \"3\"]\n    let passwordElements = letters + numbers\n    return passwordElements.shuffled().prefix(4).joined()\n}\n\nfunc runGame() {\n    let secretPassword = generatePassword()\n    var attempts = 1\n    let passwordElements = [\"A\", \"B\", \"C\", \"1\", \"2\", \"3\"]\n\n    print(\"Adivina la contraseña del almacén de Papá Noel.\")\n\n    while attempts <= 10 {\n        print(\"Intento: \\(attempts)\")\n        print(\"Introduce la contraseña: \", terminator: \"\")\n        \n        if let input = readLine()?.uppercased() {\n            if input.count != 4 {\n                print(\"Error: La contraseña debe tener 4 caracteres.\")\n                continue\n            }\n            if !input.allSatisfy({ passwordElements.contains(String($0)) }) {\n                print(\"Error: Sólo se permiten los caracteres \\(passwordElements).\")\n                continue\n            }\n\n            if input == secretPassword {\n                print(\"¡Contraseña correcta! Has descifrado el código del almacén. Feliz Navidad.\")\n                break\n            }\n\n            for (index, character) in input.enumerated() {\n                if character == secretPassword[secretPassword.index(secretPassword.startIndex, offsetBy: index)] {\n                    print(\"\\(character): Correcto\")\n                } else if secretPassword.contains(character) {\n                    print(\"\\(character): Presente\")\n                } else {\n                    print(\"\\(character): Incorrecto\")\n                }\n            }\n\n            attempts += 1\n\n            if attempts > 10 {\n                print(\"Lo siento, los 10 intentos para descifrar el código han finalizado.\")\n                print(\"Papá Noel no ha podido entregar los regalos.\")\n            }\n        }\n    }\n}\n\nrunGame()"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/typescript/hozlucas28.ts",
    "content": "import readline from 'node:readline/promises'\n\n/* -------------------------------------------------------------------------- */\n/*                                   CLASSES                                  */\n/* -------------------------------------------------------------------------- */\n\ninterface IPasswordGenerator {\n    getAdvice: (password: string) => string\n    getFailAttempts: () => number\n    getMaximumLength: () => number\n    isThePassword: (password: string) => boolean\n}\n\ninterface PasswordGeneratorConstructor {\n    hash: string\n    maximumLength: number\n}\n\nclass PasswordGenerator implements IPasswordGenerator {\n    private failAttempts: number\n    private readonly hash: string\n    private readonly maximumLength: number\n    private readonly password: string\n\n    public constructor({hash, maximumLength}: PasswordGeneratorConstructor) {\n        this.failAttempts = 0\n        this.hash = hash\n        this.maximumLength = maximumLength\n\n        let password: string = ''\n        while (password.length < maximumLength) {\n            const rndChar = hash[Math.floor(Math.random() * hash.length)]\n            if (!password.includes(rndChar)) password += rndChar\n        }\n\n        this.password = password\n    }\n\n    public getAdvice(password: string): string {\n        let advice: string[] = []\n\n        console.log(this.password)\n\n        for (let i = 0; i < password.length; i++) {\n            const char = password[i]\n            const rPasswordChar = this.password[i]\n\n            if (char === rPasswordChar) {\n                advice.push(`  - \"${char}\" is in the correct position.`)\n                continue\n            }\n\n            if (this.password.includes(char)) {\n                advice.push(`  - \"${char}\" exist but it's not in the ${i + 1}th position.`)\n                continue\n            }\n\n            advice.push(`  - \"${char}\" not exist in the password.`)\n        }\n\n        return advice.join('\\n')\n    }\n\n    public getFailAttempts(): number {\n        return this.failAttempts\n    }\n\n    public getMaximumLength(): number {\n        return this.maximumLength\n    }\n\n    public isThePassword(password: string): boolean {\n        if (this.password === password) return true\n\n        this.failAttempts++\n        return false\n    }\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\n;(async () => {\n    const hash: string = 'ABC123'\n    const maximumLength: number = 4\n\n    const passwordGenerator: IPasswordGenerator = new PasswordGenerator({\n        hash,\n        maximumLength,\n    })\n\n    const rl: readline.Interface = readline.createInterface({\n        input: process.stdin,\n        output: process.stdout,\n    })\n\n    const regex: RegExp = new RegExp(`^[${hash}]{${maximumLength}}$`)\n    const formatter: Intl.ListFormat = new Intl.ListFormat('en', {style: 'long', type: 'disjunction'})\n\n    let userInput: string = (await rl.question('> Enter the password (maximum of 4 chars): ')).trim()\n\n    while (!regex.test(userInput)) {\n        console.log(\n            `\\n> Error! The password length must be less than 4 characters, and it should contain ${formatter.format(\n                hash\n            )}. Try again...`\n        )\n        userInput = (await rl.question('\\n> Enter the password (maximum of 4 chars): ')).trim()\n    }\n\n    while (passwordGenerator.getFailAttempts() < 10) {\n        console.log(`\\n${passwordGenerator.getAdvice(userInput)}`)\n\n        console.log('\\n> Invalid password! Try again...')\n\n        userInput = (await rl.question('\\n> Enter the password (maximum of 4 chars): ')).trim()\n\n        while (!regex.test(userInput)) {\n            console.log(\n                `\\n> Error! The password length must be less than 4 characters, and it should contain ${formatter.format(\n                    hash\n                )}. Try again...`\n            )\n            userInput = (await rl.question('\\n> Enter the password (maximum of 4 chars): ')).trim()\n        }\n\n        if (passwordGenerator.isThePassword(userInput)) break\n    }\n\n    passwordGenerator.getFailAttempts() < 10\n        ? console.log(`\\n> Santa won! The password is \"${userInput}\".`)\n        : console.log('\\n> Santa lost! Storage will be closed forever.')\n\n    rl.close()\n})()\n"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/typescript/miguelex.ts",
    "content": "function generateCode(): string {\n    const chars = ['A', 'B', 'C', '1', '2', '3'];\n    return chars.sort(() => Math.random() - 0.5).slice(0, 4).join('');\n}\n\nconst code: string = generateCode();\nlet attempts: number = 10;\n\nconsole.log(\"¡Bienvenido! Tienes 10 intentos para descifrar el código.\");\n\nwhile (attempts > 0) {\n    const input: string | null = prompt(`Intento #${attempts}: Ingresa un código de 4 caracteres:`)?.toUpperCase() || '';\n\n    if (input.length !== 4 || !/^[A-C1-3]{4}$/.test(input)) {\n        console.log(\"Código inválido. Debe tener 4 caracteres (letras A-C, números 1-3).\");\n        continue;\n    }\n\n    const result = input.split('').map((char, i) => {\n        if (char === code[i]) return \"Correcto\";\n        if (code.includes(char)) return \"Presente\";\n        return \"Incorrecto\";\n    });\n\n    console.log(result.join(\", \"));\n\n    if (input === code) {\n        console.log(`¡Felicidades! Descifraste el código: ${code}`);\n        break;\n    }\n\n    attempts--;\n}\n\nif (attempts === 0) {\n    console.log(`Lo siento, no lograste descifrar el código: ${code}`);\n}\n"
  },
  {
    "path": "Roadmap/49 - EL ALMACÉN DE PAPÁ NOEL/vb.net/kenysdev.vb",
    "content": "' _____________________________________\n' https://github.com/kenysdev\n' 2024 - vb.net\n' _____________________________________\n' 49 EL ALMACÉN DE PAPÁ NOEL\n' ------------------------------------\n'* EJERCICIO\n' * Papá Noel tiene que comenzar a repartir los regalos...\n' * ¡Pero ha olvidado el código secreto de apertura del almacén!\n' *\n' * Crea un programa donde introducir códigos y obtener pistas.\n' * \n' * Código:\n' * - El código es una combinación de letras y números aleatorios\n' *   de longitud 4. (Letras: de la A a la C, Números: del 1 al 3)\n' * - No hay repetidos.\n' * - Se genera de manera aleatoria al iniciar el programa.\n' * \n' * Usuario:\n' * - Dispone de 10 intentos para acertarlo.\n' * - En cada turno deberá escribir un código de 4 caracteres, y \n' *   el programa le indicará para cada uno lo siguiente:\n' *   - Correcto: Si el caracter está en la posición correcta.\n' *   - Presente: Si el caracter existe, pero esa no es su posición.\n' *   - Incorrecto: Si el caracter no existe en el código secreto.\n' * - Deben controlarse errores de longitud y caracteres soportados.\n' * \n' * Finalización:\n' * - Papa Noel gana si descrifra el código antes de 10 intentos.\n' * - Pierde si no lo logra, ya que no podría entregar los regalos.\n\nModule Program\n    Function VerifyAllowedChar(codeEntry As String) As Boolean\n        For Each ch As Char In codeEntry\n            If Not \"abc123\".Contains(ch) Then\n                Console.WriteLine(\"Uno de los caracteres no está entre los permitidos.\" & vbCrLf)\n                Return False\n            End If\n        Next\n        Return True\n    End Function\n\n    Function GetEntry() As String\n        Do\n            Console.Write(\"Código: \")\n            Dim codeEntry As String = Console.ReadLine()\n\n            If String.IsNullOrEmpty(codeEntry) OrElse codeEntry.Length <> 4 Then\n                Console.WriteLine(\"El código debe ser de 4 dígitos.\" & vbCrLf)\n                Continue Do\n            End If\n\n            If VerifyAllowedChar(codeEntry) Then\n                Return codeEntry\n            End If\n        Loop\n    End Function\n\n    Function IsOpen(code As String) As Boolean\n        Dim codeEntry As String = GetEntry()\n\n        If codeEntry = code Then\n            Return True\n        End If\n\n        Console.WriteLine(\"Código inválido.\" & vbCrLf)\n\n        For i As Integer = 0 To codeEntry.Length - 1\n            Dim ch As Char = codeEntry(i)\n\n            If ch = code(i) Then\n                Console.WriteLine($\"'{ch}' está en la posición correcta.\")\n            ElseIf code.Contains(ch) Then\n                Console.WriteLine($\"'{ch}' está en el código, pero en otra posición.\")\n            Else\n                Console.WriteLine($\"'{ch}' no está presente en el código.\")\n            End If\n        Next\n\n        Return False\n    End Function\n\n    Sub Main()\n        Console.WriteLine(\"*\" & vbCrLf &\n                  \"* Papá Noel tiene que comenzar a repartir los regalos...\" & vbCrLf &\n                  \"* ¡Pero ha olvidado el código secreto de apertura del almacén!\" & vbCrLf & vbCrLf &\n                  \"- Tienes 10 intentos para adivinar el código que abre el almacén.\" & vbCrLf &\n                  \"- Código de 4 caracteres. Permitidos: a, b, c, 1, 2, 3.\" & vbCrLf &\n                  \"- Nota: No hay dígitos repetidos.\")\n\n        Dim characters As String = \"abc123\"\n        Dim random As New Random()\n        Dim code As New String(characters.OrderBy(Function(x) random.Next()).Take(4).ToArray())\n\n        For attempts As Integer = 1 To 10\n            Console.WriteLine(vbCrLf & \"___________\" & vbCrLf & $\"Intento #{attempts}\")\n\n            If IsOpen(code) Then\n                Console.WriteLine(\"Código correcto, almacén abierto.\")\n                Console.WriteLine(\"Papá Noel ahora podrá entregar los regalos.\")\n                Exit For\n            End If\n\n            If attempts = 10 Then\n                Console.WriteLine(vbCrLf & \"___________\" & vbCrLf & \"Has perdido.\")\n                Console.WriteLine(\"Papá Noel ya no podrá entregar los regalos.\")\n            End If\n        Next\n    End Sub\nEnd Module\n"
  },
  {
    "path": "Roadmap/50 - PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO/c#/kenysdev.cs",
    "content": "namespace exs50;\n/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - C#\n__________________________________________\n#50 PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO\n------------------------------------------\n* EJERCICIO:\n * El nuevo año está a punto de comenzar...\n * ¡Voy a ayudarte a planificar tus propósitos de nuevo año!\n *\n * Programa un gestor de objetivos con las siguientes características:\n * - Permite añadir objetivos (máximo 10)\n * - Calcular el plan detallado\n * - Guardar la planificación\n * \n * Cada entrada de un objetivo está formado por (con un ejemplo):\n * - Meta: Leer libros\n * - Cantidad: 12\n * - Unidades: libros\n * - Plazo (en meses): 12 (máximo 12)\n *\n * El cálculo del plan detallado generará la siguiente salida:\n * - Un apartado para cada mes\n * - Un listado de objetivos calculados a cumplir en cada mes\n *   (ejemplo: si quiero leer 12 libros, dará como resultado \n *   uno al mes)\n * - Cada objetivo debe poseer su nombre, la cantidad de\n *   unidades a completar en cada mes y su total. Por ejemplo:\n *\n *   Enero:\n *   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n *   [ ] 2. Estudiar Git (1 curso/mes). Total: 1.\n *   Febrero:\n *   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n *   ...\n *   Diciembre:\n *   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n *\n * - Si la duración es menor a un año, finalizará en el mes\n *   correspondiente.\n *   \n * Por último, el cálculo detallado debe poder exportarse a .txt\n * (No subir el fichero)\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Globalization;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\n\nclass Goal\n{\n    public required string Name { get; init; }\n    public required int Quantity { get; init; }\n    public required string Units { get; init; }\n    public required int Months { get; init; }\n}\n\nclass ObjectivePlanner\n{\n    private readonly List<Goal> _goals = [];\n    private readonly List<string> _months;\n    private readonly Dictionary<int, List<int>> _pendingMonthly = [];\n\n    public ObjectivePlanner()\n    {\n        _months = Enumerable.Range(1, 12)\n            .Select(m => CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(m))\n            .ToList();\n    }\n\n    private void Add()\n    {\n        if (_goals.Count >= 10)\n        {\n            Console.WriteLine(\"\\nMáximo de 10 objetivos alcanzado.\");\n            return;\n        }\n\n        try\n        {\n            Console.Write(\"Meta: \");\n            var name = Console.ReadLine()?.Trim() ?? string.Empty;\n\n            Console.Write(\"Cantidad: \");\n            var quantity = int.Parse(Console.ReadLine() ?? \"0\");\n\n            Console.Write(\"Unidades: \");\n            var units = Console.ReadLine()?.Trim() ?? string.Empty;\n\n            Console.Write(\"Plazo (en meses): \");\n            var monthCount = Math.Min(int.Parse(Console.ReadLine() ?? \"0\"), 12);\n\n            if (!string.IsNullOrEmpty(name) && quantity > 0 && \n                !string.IsNullOrEmpty(units) && monthCount > 0)\n            {\n                var goal = new Goal\n                {\n                    Name = name,\n                    Quantity = quantity,\n                    Units = units,\n                    Months = monthCount\n                };\n\n                var goalId = _goals.Count;\n                _goals.Add(goal);\n\n                var (monthly, extra) = Math.DivRem(quantity, monthCount);\n                _pendingMonthly[goalId] = Enumerable.Range(0, monthCount)\n                    .Select(m => monthly + (m < extra ? 1 : 0))\n                    .ToList();\n\n                Console.WriteLine(\"\\nObjetivo añadido exitosamente.\");\n            }\n            else\n            {\n                Console.WriteLine(\"\\nDatos inválidos.\");\n            }\n        }\n        catch (FormatException)\n        {\n            Console.WriteLine(\"\\nError: Ingrese valores numéricos válidos.\");\n        }\n    }\n\n    private Dictionary<string, List<string>>? CalculatePlan()\n    {\n        if (_goals.Count == 0)\n            return null;\n\n        var plan = new Dictionary<string, List<string>>();\n\n        for (var goalId = 0; goalId < _goals.Count; goalId++)\n        {\n            var goal = _goals[goalId];\n            var monthlyQuantities = _pendingMonthly[goalId];\n\n            for (var month = 0; month < monthlyQuantities.Count; month++)\n            {\n                var quantity = monthlyQuantities[month];\n                if (quantity > 0)\n                {\n                    var monthName = _months[month];\n                    if (!plan.ContainsKey(monthName))\n                        plan[monthName] = [];\n\n                    plan[monthName].Add(\n                        $\"[ ] {goal.Name} ({quantity} {goal.Units}/mes). \" +\n                        $\"Total: {goal.Quantity}.\");\n                }\n            }\n        }\n\n        return plan.Where(kvp => kvp.Value.Count != 0)\n                  .ToDictionary(kvp => kvp.Key, kvp => kvp.Value);\n    }\n\n    private void SavePlan()\n    {\n        var plan = CalculatePlan();\n        if (plan is null)\n        {\n            Console.WriteLine(\"\\nNo hay planificación para guardar.\");\n            return;\n        }\n\n        var filename = $\"plan_{DateTime.Now:yyyyMMdd_HHmm}.txt\";\n        try\n        {\n            using var writer = new StreamWriter(filename, false, Encoding.UTF8);\n            foreach (var (month, tasks) in plan)\n            {\n                writer.WriteLine($\"{month}:\");\n                foreach (var task in tasks)\n                {\n                    writer.WriteLine($\"  {task}\");\n                }\n                writer.WriteLine();\n            }\n\n            Console.WriteLine($\"\\nPlan guardado en {filename}.\");\n        }\n        catch (IOException)\n        {\n            Console.WriteLine(\"\\nError al guardar el archivo.\");\n        }\n    }\n\n    private void DisplayPlan()\n    {\n        var plan = CalculatePlan();\n        if (plan is not null)\n        {\n            foreach (var (month, tasks) in plan)\n            {\n                Console.WriteLine($\"\\n{month}:\");\n                foreach (var task in tasks)\n                {\n                    Console.WriteLine($\"  {task}\");\n                }\n            }\n        }\n    }\n\n    public void Run()\n    {\n        Console.Clear();\n\n        while (true)\n        {\n            Console.WriteLine(\"\\nGestor de Objetivos:\");\n            Console.WriteLine(\"1. Añadir objetivo\");\n            Console.WriteLine(\"2. Calcular plan detallado\");\n            Console.WriteLine(\"3. Guardar planificación\");\n            Console.WriteLine(\"4. Salir\");\n\n            Console.Write(\"\\nSeleccione una opción: \");\n            var option = Console.ReadLine()?.Trim();\n\n            switch (option)\n            {\n                case \"1\":\n                    Add();\n                    break;\n                case \"2\":\n                    DisplayPlan();\n                    break;\n                case \"3\":\n                    SavePlan();\n                    break;\n                case \"4\":\n                    Console.WriteLine(\"\\n¡Adiós!\");\n                    return;\n                default:\n                    Console.WriteLine(\"\\nOpción inválida.\");\n                    break;\n            }\n        }\n    }\n}\n\nclass Program\n{\n    static void Main()\n    {\n        var planner = new ObjectivePlanner();\n        planner.Run();\n    }\n}\n"
  },
  {
    "path": "Roadmap/50 - PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO/c++/hectorio23.cpp",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <map>\n#include <fstream>\n#include <memory>\n#include <stdexcept>\n#include <uuid/uuid.h>\n\n// NOTE: COMPILE the program useing the following instruction:\n// g++ -o run hectorio23.cpp -luuid\n\n\n// Goal class represents a single goal with all necessary attributes.\nclass Goal {\nprivate:\n    std::string id;\n    std::string description;\n    int amount;\n    int monthsLimit;\n    std::string units;\n\n    std::string generateUUID() {\n        uuid_t uuid;\n        char uuidStr[37];\n        uuid_generate(uuid);\n        uuid_unparse(uuid, uuidStr);\n        return std::string(uuidStr);\n    }\n\npublic:\n    Goal(const std::string& desc, int amt, int months, const std::string& unit)\n        : description(desc), amount(amt), monthsLimit(months), units(unit), id(generateUUID()) {\n        if (monthsLimit < 1 || monthsLimit > 12) {\n            throw std::out_of_range(\"Months limit must be between 1 and 12.\");\n        }\n    }\n\n    const std::string& getId() const { return id; }\n    const std::string& getDescription() const { return description; }\n    int getAmount() const { return amount; }\n    int getMonthsLimit() const { return monthsLimit; }\n    const std::string& getUnits() const { return units; }\n};\n\n// YearGoals manages a collection of goals and their monthly plans.\nclass YearGoals {\nprivate:\n    std::vector<std::shared_ptr<Goal>> goals;\n    std::map<std::string, std::vector<std::pair<std::shared_ptr<Goal>, int>>> plan;\n\n    const std::vector<std::string> months = {\n        \"January\", \"February\", \"March\", \"April\", \"May\", \"June\",\n        \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"};\n\n    void initializePlan() {\n        for (const auto& month : months) {\n            plan[month] = {};\n        }\n    }\n\npublic:\n    YearGoals() {\n        initializePlan();\n    }\n\n    bool addGoal(const std::shared_ptr<Goal>& goal) {\n        if (goals.size() >= 10) {\n            std::cerr << \"Maximum number of goals reached.\" << std::endl;\n            return false;\n        }\n\n        goals.push_back(goal);\n        distributeGoalAcrossMonths(goal);\n        return true;\n    }\n\n    void distributeGoalAcrossMonths(const std::shared_ptr<Goal>& goal) {\n        int remainingAmount = goal->getAmount();\n        int monthsLimit = goal->getMonthsLimit();\n        for (size_t i = 0; i < months.size() && remainingAmount > 0 && monthsLimit > 0; ++i, --monthsLimit) {\n            int monthlyAmount = std::min(remainingAmount, 1);\n            plan[months[i]].emplace_back(goal, monthlyAmount);\n            remainingAmount -= monthlyAmount;\n        }\n    }\n\n    void displayGoals() const {\n        if (goals.empty()) {\n            std::cout << \"No goals added yet.\\n\";\n            return;\n        }\n\n        for (const auto& goal : goals) {\n            std::cout << \"ID: \" << goal->getId() << \"\\n\"\n                      << \"Description: \" << goal->getDescription() << \"\\n\"\n                      << \"Amount: \" << goal->getAmount() << \"\\n\"\n                      << \"Units: \" << goal->getUnits() << \"\\n\"\n                      << \"Months Limit: \" << goal->getMonthsLimit() << \"\\n\\n\";\n        }\n    }\n\n    void displayPlan() const {\n        for (const auto& month : months) {\n            std::cout << month << \":\\n\";\n            const auto& goalsForMonth = plan.at(month);\n            for (size_t i = 0; i < goalsForMonth.size(); ++i) {\n                const auto& [goal, amount] = goalsForMonth[i];\n                std::cout << \"  [ ] \" << i + 1 << \". \" << goal->getDescription()\n                          << \" (\" << amount << \" \" << goal->getUnits() << \"/month). Total: \"\n                          << goal->getAmount() << \".\\n\";\n            }\n            std::cout << \"\\n\";\n        }\n    }\n\n    void savePlanToFile(const std::string& filePath) const {\n        std::ofstream file(filePath);\n        if (!file.is_open()) {\n            std::cerr << \"Failed to open file: \" << filePath << std::endl;\n            return;\n        }\n\n        for (const auto& month : months) {\n            file << month << \":\\n\";\n            const auto& goalsForMonth = plan.at(month);\n            for (size_t i = 0; i < goalsForMonth.size(); ++i) {\n                const auto& [goal, amount] = goalsForMonth[i];\n                file << \"  [ ] \" << i + 1 << \". \" << goal->getDescription()\n                     << \" (\" << amount << \" \" << goal->getUnits() << \"/month). Total: \"\n                     << goal->getAmount() << \".\\n\";\n            }\n            file << \"\\n\";\n        }\n\n        file.close();\n        std::cout << \"Plan saved to \" << filePath << \"\\n\";\n    }\n};\n\nvoid displayMenu() {\n    std::cout << \"\\nNew Year Goals Manager\\n\"\n              << \"========================\\n\"\n              << \"1. Add a Goal\\n\"\n              << \"2. View Goals\\n\"\n              << \"3. View Detailed Plan\\n\"\n              << \"4. Save Plan to File\\n\"\n              << \"0. Exit\\n\"\n              << \"Select an option: \";\n}\n\nint main() {\n    YearGoals yearGoals;\n    int option;\n\n    do {\n        displayMenu();\n        std::cin >> option;\n        std::cin.ignore();\n\n        switch (option) {\n        case 1: {\n            std::string description, units;\n            int amount, monthsLimit;\n\n            std::cout << \"Enter description: \";\n            std::getline(std::cin, description);\n\n            std::cout << \"Enter amount: \";\n            std::cin >> amount;\n\n            std::cout << \"Enter months limit (1-12): \";\n            std::cin >> monthsLimit;\n            while (monthsLimit < 1 || monthsLimit > 12) {\n                std::cout << \"Invalid input. Enter months limit (1-12): \";\n                std::cin >> monthsLimit;\n            }\n\n            std::cout << \"Enter units: \";\n            std::cin.ignore();\n            std::getline(std::cin, units);\n\n            try {\n                auto goal = std::make_shared<Goal>(description, amount, monthsLimit, units);\n                if (yearGoals.addGoal(goal)) {\n                    std::cout << \"Goal added successfully.\\n\";\n                } else {\n                    std::cout << \"Failed to add goal. Maximum limit reached.\\n\";\n                }\n            } catch (const std::exception& e) {\n                std::cerr << e.what() << \"\\n\";\n            }\n\n            break;\n        }\n        case 2:\n            yearGoals.displayGoals();\n            break;\n        case 3:\n            yearGoals.displayPlan();\n            break;\n        case 4: {\n            std::string filePath;\n            std::cout << \"Enter file path to save plan: \";\n            std::cin.ignore();\n            std::getline(std::cin, filePath);\n            yearGoals.savePlanToFile(filePath);\n            break;\n        }\n        case 0:\n            std::cout << \"Exiting program. Goodbye!\\n\";\n            break;\n        default:\n            std::cout << \"Invalid option. Please try again.\\n\";\n        }\n    } while (option != 0);\n\n    return 0;\n}\n"
  },
  {
    "path": "Roadmap/50 - PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO/ejercicio.md",
    "content": "# #50 PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO\n> #### Dificultad: Difícil | Publicación: 23/12/24 | Corrección: 30/12/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * El nuevo año está a punto de comenzar...\n * ¡Voy a ayudarte a planificar tus propósitos de nuevo año!\n *\n * Programa un gestor de objetivos con las siguientes características:\n * - Permite añadir objetivos (máximo 10)\n * - Calcular el plan detallado\n * - Guardar la planificación\n * \n * Cada entrada de un objetivo está formado por (con un ejemplo):\n * - Meta: Leer libros\n * - Cantidad: 12\n * - Unidades: libros\n * - Plazo (en meses): 12 (máximo 12)\n *\n * El cálculo del plan detallado generará la siguiente salida:\n * - Un apartado para cada mes\n * - Un listado de objetivos calculados a cumplir en cada mes\n *   (ejemplo: si quiero leer 12 libros, dará como resultado \n *   uno al mes)\n * - Cada objetivo debe poseer su nombre, la cantidad de\n *   unidades a completar en cada mes y su total. Por ejemplo:\n *\n *   Enero:\n *   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n *   [ ] 2. Estudiar Git (1 curso/mes). Total: 1.\n *   Febrero:\n *   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n *   ...\n *   Diciembre:\n *   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n *\n * - Si la duración es menor a un año, finalizará en el mes\n *   correspondiente.\n *   \n * Por último, el cálculo detallado debe poder exportarse a .txt\n * (No subir el fichero)\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**."
  },
  {
    "path": "Roadmap/50 - PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO/go/hozlucas28.go",
    "content": "package main\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"os\"\n\t\"slices\"\n\t\"strings\"\n\t\"time\"\n)\n\n/* -------------------------------------------------------------------------- */\n/*                                   ERRORS                                   */\n/* -------------------------------------------------------------------------- */\n\n/* ----------------------------- InvalidMonthErr ---------------------------- */\n\ntype InvalidMonthErr struct {\n\tMonth string\n\t_     struct{}\n}\n\nfunc (err *InvalidMonthErr) Error() string {\n\treturn fmt.Sprintf(\"\\\"%s\\\" is an invalid month\", err.Month)\n}\n\n/* --------------------------- MonthsOutOfRangeErr -------------------------- */\n\ntype MonthOutOfRangeErr struct {\n\tMonth uint8\n\t_     struct{}\n}\n\nfunc (err *MonthOutOfRangeErr) Error() string {\n\treturn fmt.Sprintf(\"%d is out of a month range\", err.Month)\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                   CLASSES                                  */\n/* -------------------------------------------------------------------------- */\n\n/* -------------------------------- YearPlan -------------------------------- */\n\nvar MONTHS [12]string = [12]string{\n\t\"january\",\n\t\"february\",\n\t\"march\",\n\t\"april\",\n\t\"may\",\n\t\"june\",\n\t\"july\",\n\t\"august\",\n\t\"september\",\n\t\"october\",\n\t\"november\",\n\t\"december\",\n}\n\ntype GoalPlan struct {\n\tAmount uint\n\tGoal   Goal\n}\n\ntype YearPlan struct {\n\tjanuary   []GoalPlan\n\tfebruary  []GoalPlan\n\tmarch     []GoalPlan\n\tapril     []GoalPlan\n\tmay       []GoalPlan\n\tjune      []GoalPlan\n\tjuly      []GoalPlan\n\taugust    []GoalPlan\n\tseptember []GoalPlan\n\toctober   []GoalPlan\n\tnovember  []GoalPlan\n\tdecember  []GoalPlan\n}\n\nfunc (instance *YearPlan) GetMonth(month string) ([]GoalPlan, error) {\n\tswitch month {\n\tcase \"january\":\n\t\treturn instance.january, nil\n\n\tcase \"february\":\n\t\treturn instance.february, nil\n\n\tcase \"march\":\n\t\treturn instance.march, nil\n\n\tcase \"april\":\n\t\treturn instance.april, nil\n\n\tcase \"may\":\n\t\treturn instance.may, nil\n\n\tcase \"june\":\n\t\treturn instance.june, nil\n\n\tcase \"july\":\n\t\treturn instance.july, nil\n\n\tcase \"august\":\n\t\treturn instance.august, nil\n\n\tcase \"september\":\n\t\treturn instance.september, nil\n\n\tcase \"october\":\n\t\treturn instance.october, nil\n\n\tcase \"november\":\n\t\treturn instance.november, nil\n\n\tcase \"december\":\n\t\treturn instance.december, nil\n\n\t}\n\n\treturn nil, &InvalidMonthErr{Month: month}\n}\n\nfunc (instance *YearPlan) SetMonth(month string, goalPlans []GoalPlan) error {\n\tswitch month {\n\tcase \"january\":\n\t\tinstance.january = goalPlans\n\n\tcase \"february\":\n\t\tinstance.february = goalPlans\n\n\tcase \"march\":\n\t\tinstance.march = goalPlans\n\n\tcase \"april\":\n\t\tinstance.april = goalPlans\n\n\tcase \"may\":\n\t\tinstance.may = goalPlans\n\n\tcase \"june\":\n\t\tinstance.june = goalPlans\n\n\tcase \"july\":\n\t\tinstance.july = goalPlans\n\n\tcase \"august\":\n\t\tinstance.august = goalPlans\n\n\tcase \"september\":\n\t\tinstance.september = goalPlans\n\n\tcase \"october\":\n\t\tinstance.october = goalPlans\n\n\tcase \"november\":\n\t\tinstance.november = goalPlans\n\n\tcase \"december\":\n\t\tinstance.december = goalPlans\n\n\tdefault:\n\t\treturn &InvalidMonthErr{Month: month}\n\t}\n\n\treturn nil\n}\n\nfunc (instance *YearPlan) Append(month string, goalPlan GoalPlan) error {\n\tswitch month {\n\tcase \"january\":\n\t\tinstance.january = append(instance.january, goalPlan)\n\n\tcase \"february\":\n\t\tinstance.february = append(instance.february, goalPlan)\n\n\tcase \"march\":\n\t\tinstance.march = append(instance.march, goalPlan)\n\n\tcase \"april\":\n\t\tinstance.april = append(instance.april, goalPlan)\n\n\tcase \"may\":\n\t\tinstance.may = append(instance.may, goalPlan)\n\n\tcase \"june\":\n\t\tinstance.june = append(instance.june, goalPlan)\n\n\tcase \"july\":\n\t\tinstance.july = append(instance.july, goalPlan)\n\n\tcase \"august\":\n\t\tinstance.august = append(instance.august, goalPlan)\n\n\tcase \"september\":\n\t\tinstance.september = append(instance.september, goalPlan)\n\n\tcase \"october\":\n\t\tinstance.october = append(instance.october, goalPlan)\n\n\tcase \"november\":\n\t\tinstance.november = append(instance.november, goalPlan)\n\n\tcase \"december\":\n\t\tinstance.december = append(instance.december, goalPlan)\n\n\tdefault:\n\t\treturn &InvalidMonthErr{Month: month}\n\t}\n\n\treturn nil\n}\n\n/* ---------------------------------- Goal ---------------------------------- */\n\nconst MAX_MONTHS_LIMIT uint8 = 12\n\ntype Goal struct {\n\tamount      uint\n\tdescription string\n\tid          string\n\tmonthsLimit uint8\n\tunits       string\n\t_           struct{}\n}\n\nfunc NewGoal(amount uint, description string, monthsLimit uint8, units string) (*Goal, error) {\n\tvar goal Goal = Goal{\n\t\tamount:      amount,\n\t\tdescription: description,\n\t\tid:          fmt.Sprintf(\"%s %d %s\", units, amount, time.Now().Local().String()),\n\t\tunits:       units,\n\t}\n\n\tif monthsLimit < 1 || monthsLimit > MAX_MONTHS_LIMIT {\n\t\treturn nil, &MonthOutOfRangeErr{Month: monthsLimit}\n\t}\n\n\tgoal.monthsLimit = monthsLimit\n\n\treturn &goal, nil\n}\n\nfunc (instance *Goal) GetAmount() uint {\n\treturn instance.amount\n}\n\nfunc (instance *Goal) GetDescription() string {\n\treturn instance.description\n}\n\nfunc (instance *Goal) GetId() string {\n\treturn instance.id\n}\n\nfunc (instance *Goal) GetMonthsLimit() uint8 {\n\treturn instance.monthsLimit\n}\n\nfunc (instance *Goal) GetUnits() string {\n\treturn instance.units\n}\n\nfunc (instance *Goal) ToYearPlan() YearPlan {\n\tvar yearPlan YearPlan\n\n\tvar counter uint = instance.amount\n\tfor counter != 0 {\n\t\tvar monthCounter uint8 = instance.monthsLimit\n\t\tfor _, month := range MONTHS {\n\t\t\tif counter == 0 || monthCounter == 0 {\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tmonthGoals, err := yearPlan.GetMonth(month)\n\t\t\tif err != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tvar goalPlan GoalPlan\n\t\t\tif len(monthGoals) == 0 {\n\t\t\t\tgoalPlan.Amount = 1\n\t\t\t\tgoalPlan.Goal = *instance\n\t\t\t} else {\n\t\t\t\tgoalPlan = monthGoals[0]\n\t\t\t\tgoalPlan.Amount++\n\t\t\t}\n\n\t\t\tyearPlan.SetMonth(month, []GoalPlan{goalPlan})\n\n\t\t\tmonthCounter--\n\t\t\tcounter--\n\t\t}\n\t}\n\n\treturn yearPlan\n}\n\n/* -------------------------------- YearGoals ------------------------------- */\n\nconst MAX_GOALS uint = 10\n\ntype YearGoals struct {\n\tgoals []Goal\n\tplan  YearPlan\n\t_     struct{}\n}\n\nfunc NewYearGoals() *YearGoals {\n\tvar yearGoals YearGoals = YearGoals{\n\t\tgoals: []Goal{},\n\t\tplan:  YearPlan{},\n\t}\n\n\treturn &yearGoals\n}\n\nfunc (instance *YearGoals) GetGoals() []Goal {\n\treturn instance.goals\n}\n\nfunc (instance *YearGoals) GetPlan() YearPlan {\n\treturn instance.plan\n}\n\nfunc (instance *YearGoals) appendGoalToPlan(goal *Goal) {\n\tvar goalYearPlan YearPlan = goal.ToYearPlan()\n\n\tfor _, month := range MONTHS {\n\t\tgoalPlan, err := goalYearPlan.GetMonth(month)\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\n\t\tfor i := range goalPlan {\n\t\t\tinstance.plan.Append(month, goalPlan[i])\n\t\t}\n\t}\n}\n\nfunc (instance *YearGoals) removeGoalFromPlan(id string) {\n\tfor _, _month := range MONTHS {\n\t\tmonthGoals, err := instance.plan.GetMonth(_month)\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\n\t\tvar goalI int = slices.IndexFunc(monthGoals, func(gPlan GoalPlan) bool {\n\t\t\treturn gPlan.Goal.GetId() == id\n\t\t})\n\t\tif goalI == -1 {\n\t\t\tbreak\n\t\t}\n\n\t\tinstance.plan.SetMonth(_month, slices.Concat(monthGoals[:goalI], monthGoals[goalI+1:]))\n\t}\n}\n\nfunc (instance *YearGoals) AddGoal(newGoal *Goal) bool {\n\tif len(instance.goals) == int(MAX_GOALS) {\n\t\treturn false\n\t}\n\n\tvar goalI int = slices.IndexFunc(instance.goals, func(goal Goal) bool {\n\t\treturn goal.GetId() == newGoal.GetId()\n\t})\n\tif goalI != -1 {\n\t\treturn false\n\t}\n\n\tinstance.goals = append(instance.goals, *newGoal)\n\tinstance.appendGoalToPlan(newGoal)\n\n\treturn true\n}\n\nfunc (instance *YearGoals) RemoveGoal(id string) bool {\n\tvar goalI int = slices.IndexFunc(instance.goals, func(goal Goal) bool {\n\t\treturn goal.GetId() == id\n\t})\n\tif goalI == -1 {\n\t\treturn false\n\t}\n\n\tinstance.goals = slices.Concat(instance.goals[:goalI], instance.goals[goalI+1:])\n\tinstance.removeGoalFromPlan(id)\n\n\treturn true\n}\n\nfunc (instance *YearGoals) SavePlan(\n\tpath string,\n\tgoalToRow func(goal Goal, amount uint, index uint) string,\n\tmonthTitle func(month string) string,\n) error {\n\tfile, err := os.Create(path)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfor _, month := range MONTHS {\n\t\tmonthGoals, err := instance.plan.GetMonth(month)\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\n\t\tvar rows []string = []string{monthTitle(month)}\n\t\tfor i, goalMonth := range monthGoals {\n\t\t\trows = append(rows, goalToRow(goalMonth.Goal, goalMonth.Amount, uint(i)))\n\t\t}\n\n\t\tfile.WriteString(strings.Join(rows, \"\\n\") + \"\\n\")\n\t}\n\n\terr = file.Close()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\nfunc main() {\n\tvar yearGoals *YearGoals = NewYearGoals()\n\n\tfmt.Println(\n\t\t\"> Available operations:\\n\\n\",\n\t\t\" 1 - Add goal.\\n\",\n\t\t\" 2 - Remove goal.\\n\",\n\t\t\" 3 - Show goals.\\n\",\n\t\t\" 4 - Show plan.\\n\",\n\t\t\" 5 - Save plan.\\n\",\n\t\t\" 0 - Exit.\",\n\t)\n\n\tvar input uint\n\tfmt.Printf(\"\\n> Select an operation: \")\n\tfmt.Scanf(\"%d\\n\", &input)\n\n\tvar reader *bufio.Reader = bufio.NewReader(os.Stdin)\n\n\tfor input != 0 {\n\t\tswitch input {\n\t\tcase 1:\n\t\t\tfmt.Println(\"\\n> Complete the following goal data...\")\n\n\t\t\tfmt.Printf(\"\\n> Units: \")\n\t\t\tunits, err := reader.ReadString('\\n')\n\t\t\tif err != nil {\n\t\t\t\tpanic(err)\n\t\t\t}\n\n\t\t\tunits = strings.TrimSpace(units)\n\n\t\t\tvar amount uint\n\t\t\tfmt.Printf(\"\\n> Amount (as a number): \")\n\t\t\tfmt.Scanf(\"%d\\n\", &amount)\n\n\t\t\tfmt.Printf(\"\\n> Description: \")\n\t\t\tdescription, err := reader.ReadString('\\n')\n\t\t\tif err != nil {\n\t\t\t\tpanic(err)\n\t\t\t}\n\n\t\t\tdescription = strings.TrimSpace(description)\n\n\t\t\tvar monthsLimit uint8\n\t\t\tfmt.Printf(\"\\n> Months limit (as a number): \")\n\t\t\tfmt.Scanf(\"%d\\n\", &monthsLimit)\n\n\t\t\tfor monthsLimit < 1 || monthsLimit > MAX_MONTHS_LIMIT {\n\t\t\t\tfmt.Println(\"\\n> Error! Months limit must be between 1 and 12 (both included). Try again...\")\n\t\t\t\tfmt.Printf(\"\\n> Months limit (as a number): \")\n\t\t\t\tfmt.Scanf(\"%d\\n\", &monthsLimit)\n\t\t\t}\n\n\t\t\tgoal, err := NewGoal(amount, description, monthsLimit, units)\n\t\t\tif err != nil {\n\t\t\t\tfmt.Println(err.Error())\n\t\t\t}\n\n\t\t\tif yearGoals.AddGoal(goal) {\n\t\t\t\tfmt.Println(\"\\n> Goal added!\")\n\t\t\t} else {\n\t\t\t\tfmt.Println(\"\\n> An error occurred! The goal was not added.\")\n\t\t\t}\n\n\t\tcase 2:\n\t\t\tfmt.Printf(\"\\n> Goal id to remove: \")\n\n\t\t\tgoalId, err := reader.ReadString('\\n')\n\t\t\tif err != nil {\n\t\t\t\tpanic(err)\n\t\t\t}\n\n\t\t\tgoalId = strings.TrimSpace(goalId)\n\n\t\t\tif yearGoals.RemoveGoal(goalId) {\n\t\t\t\tfmt.Printf(\"\\n> Goal \\\"%s\\\" removed!\\n\", goalId)\n\t\t\t} else {\n\t\t\t\tfmt.Println(\"\\n> An error occurred! The goal was not removed.\")\n\t\t\t}\n\n\t\tcase 3:\n\t\t\tvar goals []Goal = yearGoals.GetGoals()\n\n\t\t\tvar goalsRows []string\n\t\t\tfor _, goal := range goals {\n\t\t\t\tgoalsRows = append(goalsRows, fmt.Sprintf(\"\\n• Goal \\\"%s\\\"...\\n\", goal.GetId()),\n\t\t\t\t\tfmt.Sprintf(\" - ID: \\\"%s\\\".\", goal.GetId()),\n\t\t\t\t\tfmt.Sprintf(\" - Description: \\\"%s\\\".\", goal.GetDescription()),\n\t\t\t\t\tfmt.Sprintf(\" - Months limit: %d.\", goal.GetMonthsLimit()),\n\t\t\t\t\tfmt.Sprintf(\" - Amount: %d.\", goal.GetAmount()),\n\t\t\t\t\tfmt.Sprintf(\" - Units: \\\"%s\\\".\", goal.GetUnits()))\n\n\t\t\t}\n\n\t\t\tif len(goalsRows) > 0 {\n\t\t\t\tfmt.Println(strings.Join(goalsRows, \"\\n\"))\n\t\t\t}\n\n\t\tcase 4:\n\t\t\tvar plan YearPlan = yearGoals.GetPlan()\n\n\t\t\tvar planRows []string\n\t\t\tfor _, month := range MONTHS {\n\t\t\t\tmonthGoals, err := plan.GetMonth(month)\n\t\t\t\tif err != nil {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tvar planRow string = fmt.Sprintf(\"\\n%s%s:\", strings.ToUpper(month[:1]), month[1:])\n\t\t\t\tfor i, monthGoal := range monthGoals {\n\t\t\t\t\tvar goal Goal = monthGoal.Goal\n\t\t\t\t\tvar desc string = goal.GetDescription()\n\t\t\t\t\tvar units string = goal.GetUnits()\n\t\t\t\t\tvar totalAmount uint = goal.GetAmount()\n\t\t\t\t\tplanRow += fmt.Sprintf(\"\\n[ ] %d. %s (%d %s/mes). Total: %d.\", i+1, desc, monthGoal.Amount, units, totalAmount)\n\t\t\t\t}\n\n\t\t\t\tplanRows = append(planRows, planRow)\n\t\t\t}\n\n\t\t\tif len(planRows) > 0 {\n\t\t\t\tfmt.Println(strings.Join(planRows, \"\\n\"))\n\t\t\t}\n\n\t\tcase 5:\n\t\t\tvar currentDate time.Time = time.Now()\n\n\t\t\tif wd, err := os.Getwd(); err == nil {\n\t\t\t\tvar savePlanPath string = fmt.Sprintf(\"%s\\\\plan-%d.txt\", wd, currentDate.Year())\n\n\t\t\t\tyearGoals.SavePlan(\n\t\t\t\t\tsavePlanPath,\n\t\t\t\t\tfunc(goal Goal, amount, index uint) string {\n\t\t\t\t\t\tvar desc string = goal.GetDescription()\n\t\t\t\t\t\tvar units string = goal.GetUnits()\n\t\t\t\t\t\tvar totalAmount uint = goal.GetAmount()\n\t\t\t\t\t\treturn fmt.Sprintf(\"[ ] %d. %s (%d %s/mes). Total: %d.\", index+1, desc, amount, units, totalAmount)\n\t\t\t\t\t},\n\t\t\t\t\tfunc(month string) string { return fmt.Sprintf(\"\\n%s%s:\", strings.ToUpper(month[:1]), month[1:]) },\n\t\t\t\t)\n\n\t\t\t\tfmt.Printf(\"\\n> Plan saved in \\\"%s\\\" path.\\n\", savePlanPath)\n\t\t\t} else {\n\t\t\t\tfmt.Println(\"\\n> Error! An error occurred on get working directory path\")\n\t\t\t}\n\n\t\tdefault:\n\t\t\tfmt.Println(\"\\n> Invalid operation! Try again...\")\n\t\t}\n\n\t\tfmt.Println(\n\t\t\t\"\\n> Available operations:\\n\\n\",\n\t\t\t\" 1 - Add goal.\\n\",\n\t\t\t\" 2 - Remove goal.\\n\",\n\t\t\t\" 3 - Show goals.\\n\",\n\t\t\t\" 4 - Show plan.\\n\",\n\t\t\t\" 5 - Save plan.\\n\",\n\t\t\t\" 0 - Exit.\",\n\t\t)\n\n\t\tfmt.Printf(\"\\n> Select an operation: \")\n\t\tfmt.Scanf(\"%d\\n\", &input)\n\t}\n}\n"
  },
  {
    "path": "Roadmap/50 - PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO/java/JohnAlexGuerrero.java",
    "content": "package org.example;\n\nimport java.io.File;\nimport java.io.FileWriter;\nimport java.io.IOException;\nimport java.lang.reflect.Array;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.Paths;\nimport java.util.*;\nimport java.util.stream.Collectors;\n\n// Press Shift twice to open the Search Everywhere dialog and type `show whitespaces`,\n// then press Enter. You can now see whitespace characters in your code.\npublic class Main {\n    public static void main(String[] args) {\n        // agregar una lista de 10 objetivos para alcanzar en el nuevo año\n        List<Goal> goals = Arrays.asList(\n                new Goal(\"Leer Libros\",24, \"Libro\", 12),\n                new Goal(\"Estudiar Git\", 1, \"curso\", 1),\n                new Goal(\"Hablar Ingles\", 1, \"Curso\", 6),\n                new Goal(\"Aprender a Tocar Guitarra\", 8, \"Curso\", 8),\n                new Goal(\"Aprender a Nadar\", 2, \"Curso\", 2),\n                new Goal(\"ldkfldkf\", 45, \"Curso\", 6)\n        );\n\n        // permitir añadir solo 10 objetivos como maximo\n        if(goals.size() > 10){\n            System.out.println(\"Solo es permitido maximo 10 Objetivos\");\n            System.out.println(\"Debes eliminar \" + (goals.size() - 10));\n            System.exit(1);\n        }\n        System.out.println(\"Total Objetivos: \" + goals.size());\n\n        // Cada objetivo tiene un plazo maximo de 12 meses\n        boolean anyHaveTimeMaxTwelveMonths = goals.stream()\n                .anyMatch(e -> e.getNumberMonths() > 12);\n\n        if(anyHaveTimeMaxTwelveMonths){\n            System.out.println(\"existe un objetivo con plazo mayor a 12 meses.\");\n            System.out.println(\"revisa el plazo de tus objetivos.\");\n            System.exit(1);\n        }\n\n        // Calcular el plan detallado\n        // arreglo type String con los meses del año\n        String [] months = {\"Enero\",\"Febrero\",\"Marzo\",\"Abril\",\"Mayo\",\"Junio\",\"Julio\",\"Agosto\",\"Septiembre\",\"Octubre\",\"Noviembre\",\"Diciembre\"};\n        // map type key-value donde la key es el plazo en meses para alcanzar el objetivo\n        // el value es una lista de objetivos que tienen la misma duración en meses\n        Map<Integer, List<Goal>> goalsByAmount = goals.stream()\n                .collect(Collectors.groupingBy(Goal::getNumberMonths));\n        // HashMap <String, List<Goal>> para\n        HashMap <String, List<Goal>> plan = new HashMap<>();\n\n        for(String m : months){\n            List <Goal> goalList = new ArrayList<>();\n            for (Integer i: goalsByAmount.keySet()){\n                if(plan.size() >= i){\n                    continue;\n                }else{\n                    for(Goal g : goalsByAmount.get(i)){\n                        goalList.add(g);\n                    }\n\n                }\n            }\n            plan.put(m, goalList);\n        }\n\n        //Mostrar la planificación de objetivos por mes\n        for (String m: months) {\n            System.out.println(m + \":\");\n            for(Goal g: plan.get(m)){\n                System.out.println(g);\n\n            }\n        }\n\n        // Guardar la planificación en archivo txt\n        try {\n            File fileData = new File(\"planificacion.txt\");\n            if(fileData.createNewFile()){\n                FileWriter fileWriter = new FileWriter(fileData.getPath());\n                for (String m: months) {\n                    fileWriter.write(m + \"\\n\");\n                    for(Goal g: plan.get(m)){\n                        fileWriter.write(g.toString() + \"\\n\");\n                    }\n                }\n                fileWriter.close();\n                System.out.println(\"fichero: \" + fileData.getName() + \" creado\");\n                System.out.println(fileData.getPath());\n            }else{\n                System.out.println(\"No se ha podido crear el fichero.\");\n                System.out.println(fileData.getPath());\n            }\n        }catch (IOException error){\n            System.out.println(\"Error de creacion de fichero.\");\n            error.printStackTrace();\n        }\n    }\n\n\n    static class Goal{\n        private String title;\n        private int amount;\n        private String units;\n        private int numberMonths;\n\n        public Goal(String title, int amount, String units, int numberMonths) {\n            this.title = title;\n            this.amount = amount;\n            this.units = units;\n            this.numberMonths = numberMonths;\n\n        }\n\n        public String getTitle() {\n            return title;\n        }\n\n        public int getAmount() {\n            return amount;\n        }\n\n        public String getUnits() {\n            return units;\n        }\n\n        public int getNumberMonths() {\n            return numberMonths;\n        }\n\n        // calcular el numero de unidades aplicadas en cada mes\n        public int getUnitByMonth(){\n            if(this.amount == this.numberMonths) return (this.amount / this.numberMonths);\n            if(this.amount < this.numberMonths) return 1;\n            if(this.amount > this.numberMonths) {\n                var resM = Math.round((float) this.amount / this.numberMonths);\n                var resU = this.amount % this.numberMonths;\n                //System.out.println(\"r:\"+resU);\n                if(resU == 0) return resM;\n                return resM;\n            }\n\n            return 3;\n        }\n\n        // cada objetivo debe poseer un nombre, la cantidad de unidades a completar y su total\n        @Override\n        public String toString() {\n            return \"[] 1. \" + this.getTitle() + \" (\"+ this.getUnitByMonth() + \" \" + this.getUnits() + \"/mes). Total: \" + this.getAmount() + \".\";\n        }\n    }\n\n}"
  },
  {
    "path": "Roadmap/50 - PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO/java/Josegs95.java",
    "content": "import java.io.IOException;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.StandardOpenOption;\nimport java.util.*;\n\npublic class Josegs95 {\n    public static void main(String[] args) {\n        new Josegs95().newYearPlanner();\n    }\n\n    final private Scanner sc = new Scanner(System.in);\n    private List<Plan> planList = new ArrayList<>();\n\n    public void newYearPlanner(){\n\n        try(sc){\n            app:\n            while(true){\n                printMenu();\n                System.out.print(\"Selecciona la opción que desees: \");\n                String option = sc.nextLine();\n                switch (option){\n                    case \"1\" -> createGoal();\n                    case \"2\" -> System.out.println(calculatePlanning());\n                    case \"3\" -> savePlanningInAFile();\n                    case \"4\" -> {\n                        System.out.println(\"Saliendo de la aplicación...\");\n                        break app;\n                    }\n                    default -> System.out.println(\"Error, opción no válida.\");\n                }\n            }\n        }\n    }\n\n    private boolean createGoal(){\n        if (planList.size() > 10){\n            System.out.println(\"Solo puedes tener 10 objetivos de forma simultánea\");\n            return false;\n        }\n\n        System.out.print(\"Introduzca el objetivo: \");\n        String goal = sc.nextLine();\n        Integer amount = askIntegerToUser(\"Introduzca la cantidad: \");\n        System.out.print(\"Introduzca las unidades: \");\n        String unit = sc.nextLine();\n\n        while(true){\n            Integer deadline = askIntegerToUser(\"Introduzca el plazo (en meses): \");\n            if (deadline > 12)\n                System.out.println(\"El plazo máximo permitido son 12 meses.\");\n            else\n                return planList.add(new Plan(goal, amount, unit, deadline));\n        }\n    }\n\n    private String calculatePlanning(){\n        String[][] planning = initPlanning();\n\n        for (Plan plan : planList){\n            int amountPerMonth = plan.getAmount() / plan.getDeadline();\n            int rest = plan.getAmount() % plan.getDeadline();\n            months:\n            for (int i = 0; (rest > 0 || amountPerMonth > 0) && i < plan.getDeadline(); i++){\n                for (int j = 0; j < planning[0].length; j++){\n                    if (planning[i][j] != null)\n                        continue;\n\n                    int amount = amountPerMonth + (rest-- > 0 ? 1 : 0);\n                    planning[i][j] = plan.getGoal() + \"(\" + amount + \" \" + plan.getUnit() +\n                            \"/mes). Total: \" + plan.getAmount();\n                    continue months;\n                }\n            }\n        }\n\n        return getPlanningAsString(planning);\n    }\n\n    private boolean savePlanningInAFile(){\n        String planningString = calculatePlanning();\n        Path filePath = Path.of(\"planning.txt\");\n        try {\n            Files.writeString(filePath, planningString,\n                    StandardOpenOption.CREATE,\n                    StandardOpenOption.TRUNCATE_EXISTING);\n            System.out.println(\"Planificación guardada exitosamente en: '\" + filePath.toFile().getAbsolutePath() + \"'\");\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        }\n\n        return true;\n    }\n\n    private String[][] initPlanning(){\n        String[][] matrix = new String[12][11];\n        matrix[0][0] = \"Enero\";\n        matrix[1][0] = \"Febrero\";\n        matrix[2][0] = \"Marzo\";\n        matrix[3][0] = \"Abril\";\n        matrix[4][0] = \"Mayo\";\n        matrix[5][0] = \"Junio\";\n        matrix[6][0] = \"Julio\";\n        matrix[7][0] = \"Agosto\";\n        matrix[8][0] = \"Septiembre\";\n        matrix[9][0] = \"Octubre\";\n        matrix[10][0] = \"Noviembre\";\n        matrix[11][0] = \"Diciembre\";\n\n        return matrix;\n    }\n\n    private String getPlanningAsString(String[][] planning){\n        StringBuilder sb = new StringBuilder();\n\n        for (int i = 0; i < planning.length; i++){\n            sb.append(planning[i][0] + \":\" + System.lineSeparator());\n            for (int j = 1; j < planning[0].length; j++){\n                if (planning[i][j] == null){\n                    if (j == 1)\n                        sb.append(\"Nada.\" + System.lineSeparator());\n                    break;\n                }\n\n                sb.append(\"[ ] \" + j + \". \" + planning[i][j] + System.lineSeparator());\n            }\n            sb.append(System.lineSeparator());\n        }\n\n        return sb.toString();\n    }\n\n    private Integer askIntegerToUser(String message){\n        while(true){\n            try{\n                System.out.print(message);\n                Integer userInput = Integer.parseInt(sc.nextLine());\n                return userInput;\n            } catch (NumberFormatException e) {\n                System.out.println(\"Error, debes introducir un número entero\");\n            }\n        }\n    }\n\n    private void printMenu(){\n        System.out.println(\"===== Menu =====\");\n        System.out.println(\"1. Añadir objetivo al 'planning'\");\n        System.out.println(\"2. Calcular el plan detallado\");\n        System.out.println(\"3. Guardar la planificación\");\n        System.out.println(\"4. Salir de la aplicación\");\n        System.out.println(\"================\");\n    }\n\n    public class Plan{\n        private String goal;\n        private Integer amount;\n        private String unit;\n        private Integer deadline;\n\n        public Plan(String goal, Integer amount, String unit, Integer deadline) {\n            this.goal = goal;\n            this.amount = amount;\n            this.unit = unit;\n            this.deadline = deadline;\n        }\n\n        public String getGoal() {\n            return goal;\n        }\n\n        public Integer getAmount() {\n            return amount;\n        }\n\n        public String getUnit() {\n            return unit;\n        }\n\n        public Integer getDeadline() {\n            return deadline;\n        }\n    }\n}\n"
  },
  {
    "path": "Roadmap/50 - PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO/java/asjordi.java",
    "content": "package dev.asjordi.five.r50;\n\nimport java.io.*;\nimport java.nio.file.Path;\nimport java.nio.file.Paths;\nimport java.util.*;\n\npublic class Main {\n\n    public static void main(String[] args) {\n        Main plan = new Main();\n        Scanner sc = new Scanner(System.in);\n\n        System.out.println(\"Plan de objetivos 2025\\nAgrega tus objetivos para el 2025\\n\");\n\n        while (plan.getTotalObjetivos() < 10) {\n            System.out.println(\"Objetivo \" + (plan.getTotalObjetivos() + 1) + \":\");\n            System.out.print(\"Meta: \");\n            String meta = sc.nextLine();\n            System.out.print(\"Cantidad: \");\n            int cantidad = sc.nextInt();\n            sc.nextLine();\n            System.out.print(\"Unidad: \");\n            String unidad = sc.nextLine();\n            System.out.print(\"Plazo (meses): \");\n            int plazo = sc.nextInt();\n            sc.nextLine();\n\n            plan.addObjetivo(new Objetivo(meta, cantidad, unidad, plazo));\n\n            System.out.println(\"¿Quieres añadir otro objetivo? (s/n)\");\n            if (sc.nextLine().equalsIgnoreCase(\"n\")) break;\n        }\n\n        plan.calcularObjetivos();\n\n    }\n\n    private final List<Objetivo> objetivos;\n    private final String[] months = {\"Enero\", \"Febrero\", \"Marzo\", \"Abril\", \"Mayo\", \"Junio\", \"Julio\", \"Agosto\", \"Septiembre\", \"Octubre\", \"Noviembre\", \"Diciembre\"};\n    private final StringBuilder plan;\n\n    public Main() {\n        this.objetivos = new ArrayList<>();\n        this.plan = new StringBuilder();\n    }\n\n    public void addObjetivo(Objetivo objetivo) {\n        if (this.objetivos.size() < 10) this.objetivos.add(objetivo);\n        else System.out.println(\"No se pueden añadir más de 10 objetivos\");\n    }\n\n    public void calcularObjetivos() {\n        int maxMonth = objetivos.stream()\n                .map(o -> o.getPlazo())\n                .max(Integer::compareTo).orElseGet(() -> 12);\n\n        System.out.println(\"Plan de objetivos 2025\\n\");\n        this.plan.append(\"Plan de objetivos 2025\\n\\n\");\n\n        for (int i = 0; i < maxMonth; i++) {\n            System.out.println(months[i] + \":\");\n            this.plan.append(months[i]).append(\":\\n\");\n            int c = 1;\n            for (var objetivo : objetivos) {\n                if (objetivo.getPlazo() > i) {\n                    System.out.print(\"[ ] \" + c + \". \" + objetivo + \"\\n\");\n                    this.plan.append(\"[ ] \").append(c).append(\". \").append(objetivo).append(\"\\n\");\n                    c++;\n                }\n            }\n            System.out.println();\n            this.plan.append(\"\\n\");\n        }\n\n        guardarPlan();\n    }\n\n    public void guardarPlan() {\n        Path path = Paths.get(\"plan.txt\");\n\n        try (BufferedWriter bw = new BufferedWriter(new FileWriter(path.toFile()))) {\n\n            if (this.plan.isEmpty()) {\n                System.out.println(\"No hay ningún plan que guardar\");\n                return;\n            }\n\n            bw.write(this.plan.toString());\n            bw.flush();\n            System.out.println(\"Plan guardado correctamente\");\n        } catch (IOException e) {\n            System.out.println(\"Error al guardar el plan\");\n            e.printStackTrace();\n        }\n    }\n\n    public int getTotalObjetivos() {\n        return this.objetivos.size();\n    }\n\n    static class Objetivo {\n        private final String meta;\n        private final int cantidad;\n        private final String unidad;\n        private final int plazo;\n        private final double porMes;\n\n        public Objetivo(String meta, int cantidad, String unidad, int plazo) {\n            this.meta = meta;\n            this.cantidad = cantidad;\n            this.unidad = unidad;\n            this.plazo = Math.min(plazo, 12);\n            this.porMes = (double) this.cantidad / this.plazo;\n        }\n\n        public int getPlazo() {\n            return plazo;\n        }\n\n        @Override\n        public String toString() {\n            return this.meta + \" (\" + this.porMes + \" \" + this.unidad + \"/mes). Total: \" + this.cantidad;\n        }\n    }\n\n}\n"
  },
  {
    "path": "Roadmap/50 - PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO/javascript/JesusAntonioEEscamilla.js",
    "content": "/** #50 - JavaScript -> Jesus Antonio Escamilla */\n\n/**\n * PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO.\n * Utilizando la Terminal para pedir datos y agregarlos.\n */\n\nconst fs = require('fs');\n\nclass GoalManager {\n    constructor() {\n        this.goals = [];\n    }\n\n    addGoal(name, quantity, unit, months){\n        if (this.goals.length >= 10) {\n            console.log(\"\\nNo puedes añadir más de 10 objetivos.\");\n            return;\n        }\n\n        if (months > 12 || months <= 0) {\n            console.log(\"\\nEl plazo debe ser entre 1 y 12 meses.\");\n            return;\n        }\n\n        this.goals.push({\n            name,\n            quantity,\n            unit,\n            months\n        });\n\n        console.log(`\\nObjetivo añadido: ${name} (${quantity} ${unit}, ${months} meses).`);\n    }\n\n    generateDetailedPlan(){\n        if (this.goals.length === 0) {\n            console.log(\"\\nNo hay objetivos para planificar.\");\n            return;\n        }\n\n        let plan = \"\\nPlanificación detallada:\\n\\n\";\n        const monthsNames = [\n        \"Enero\",\n        \"Febrero\",\n        \"Marzo\",\n        \"Abril\",\n        \"Mayo\",\n        \"Junio\",\n        \"Julio\",\n        \"Agosto\",\n        \"Septiembre\",\n        \"Octubre\",\n        \"Noviembre\",\n        \"Diciembre\",\n        ];\n\n        for (let i = 0; i < 12; i++) {\n            let currentMothGoals = [];\n            this.goals.forEach((goal, index) => {\n                if (i < goal.months) {\n                    const monthlyQuantity = Math.ceil(goal.quantity / goal.months);\n                    currentMothGoals.push(\n                        `[ ] ${index + 1}. ${goal.name} (${monthlyQuantity} ${goal.unit}/mes). Total: ${goal.quantity}.\\n`\n                    );\n                }\n            });\n\n            if (currentMothGoals.length > 0) {\n                plan += `\\n${monthsNames[i]}:\\n`;\n                plan += currentMothGoals.join(\"\\n\" + \"\\n\\n\");\n            }\n        }\n\n        return plan;\n    }\n\n    savePlanToFile(filename = \"detailed_plan.txt\"){\n        const plan = this.generateDetailedPlan();\n        if (!plan) return;\n\n        fs.writeFile(filename, plan, (err) => {\n            if (err) {\n                console.log(\"\\nError al guardar el archivo:\", err);\n            } else {\n                console.log(`\\nPlanificación guardada en el archivo: ${filename}`);\n            }\n        });\n    }\n}\n\n// Ejemplo para usarlo\nconst manager = new GoalManager();\n\nmanager.addGoal(\"Leer libros\", 12, \"libros\", 12);\nmanager.addGoal(\"Estudiar Git\", 1, \"curso\", 6);\nmanager.addGoal(\"Correr\", 500, \"km\", 12);\n\nconst detailedPlan = manager.generateDetailedPlan();\nif (detailedPlan) {\n    console.log(detailedPlan);\n}\nmanager.savePlanToFile();"
  },
  {
    "path": "Roadmap/50 - PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO/javascript/Rafacv23.js",
    "content": "// Autor: Rafael Canosa, Github: https://github.com/rafacv23\n\n/* crear objetivo con los siguientes atributos:\n * meta\n * cantidad\n * unidades\n * plazo\n */\n\nlet objectives = []\n\nconst months = [\n  {\n    name: \"enero\",\n    value: 1,\n  },\n  {\n    name: \"febrero\",\n    value: 2,\n  },\n  {\n    name: \"marzo\",\n    value: 3,\n  },\n  {\n    name: \"abril\",\n    value: 4,\n  },\n  {\n    name: \"mayo\",\n    value: 5,\n  },\n  {\n    name: \"junio\",\n    value: 6,\n  },\n  {\n    name: \"julio\",\n    value: 7,\n  },\n  {\n    name: \"agosto\",\n    value: 8,\n  },\n  {\n    name: \"septiembre\",\n    value: 9,\n  },\n  {\n    name: \"octubre\",\n    value: 10,\n  },\n  {\n    name: \"noviembre\",\n    value: 11,\n  },\n  {\n    name: \"diciembre\",\n    value: 12,\n  },\n]\n\nclass Objective {\n  constructor(meta, cantidad, unidades, plazo) {\n    this.meta = meta\n    this.cantidad = cantidad\n    this.unidades = unidades\n    this.plazo = plazo\n\n    // comprobramos que el plazo no sea superior a 12\n    if (this.plazo > 12) {\n      console.log(\"❌ El plazo no puede ser superior a 12 meses.\")\n      return\n    }\n    // agregar objetivo a la lista\n    objectives.push(this)\n  }\n\n  // crear funcion que imprima el objetivo\n  show() {\n    console.log(`Objetivo: ${this.meta}`)\n    console.log(`Cantidad: ${this.cantidad}`)\n    console.log(`Unidades: ${this.unidades}`)\n    console.log(`Plazo: ${this.plazo}`)\n  }\n}\n\nfunction printObjectives() {\n  for (let i = 0; i < objectives.length; i++) {\n    console.log(`Objetivo ${i + 1}: ${objectives[i].meta}`)\n  }\n}\n\nfunction calculate() {\n  months.forEach((month) => {\n    // calculamos las tareas de cada mes\n    console.log(`📅 ${month.name}`)\n    objectives.forEach((objective) => {\n      const target = objective.cantidad / objective.plazo // calculamos el objetivo a lo largo de los 12 meses\n\n      if (objective.plazo >= month.value) {\n        console.log(\n          `${objective.meta} (${target} ${objective.unidades}/mes). Total: ${objective.cantidad}`\n        )\n      }\n    })\n  })\n}\n\nnew Objective(\"leer libros\", 12, \"libros\", 12)\nnew Objective(\"escribir artículos\", 12, \"artículos\", 6)\nnew Objective(\"escribir informes\", 24, \"informes\", 12)\nnew Objective(\"programar\", 24, \"programas\", 8)\n//new Objective(\"programar\", 24, \"informes\", 69)\n\nprintObjectives()\ncalculate()\n"
  },
  {
    "path": "Roadmap/50 - PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO/javascript/RaulDoezon.js",
    "content": "/*\n * EJERCICIO:\n * El nuevo año está a punto de comenzar...\n * ¡Voy a ayudarte a planificar tus propósitos de nuevo año!\n *\n * Programa un gestor de objetivos con las siguientes características:\n * - Permite añadir objetivos (máximo 10)\n * - Calcular el plan detallado\n * - Guardar la planificación\n * \n * Cada entrada de un objetivo está formado por (con un ejemplo):\n * - Meta: Leer libros\n * - Cantidad: 12\n * - Unidades: libros\n * - Plazo (en meses): 12 (máximo 12)\n *\n * El cálculo del plan detallado generará la siguiente salida:\n * - Un apartado para cada mes\n * - Un listado de objetivos calculados a cumplir en cada mes\n *   (ejemplo: si quiero leer 12 libros, dará como resultado \n *   uno al mes)\n * - Cada objetivo debe poseer su nombre, la cantidad de\n *   unidades a completar en cada mes y su total. Por ejemplo:\n *\n *   Enero:\n *   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n *   [ ] 2. Estudiar Git (1 curso/mes). Total: 1.\n *   Febrero:\n *   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n *   ...\n *   Diciembre:\n *   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n *\n * - Si la duración es menor a un año, finalizará en el mes\n *   correspondiente.\n *   \n * Por último, el cálculo detallado debe poder exportarse a .txt\n * (No subir el fichero)\n*/\n\nconst readlinePromises = require(\"readline/promises\");\nconst fs = require('fs');\nconst rl = readlinePromises.createInterface({\n  input: process.stdin,\n  output: process.stdout,\n});\n\nconst inputs = [\"Meta\", \"Cantidad\", \"Unidades\", \"Plazo\"];\nconst months = [\"Enero\", \"Febrero\", \"Marzo\", \"Abril\", \"Mayo\", \"Junio\", \"Julio\", \"Agosto\", \"Septiembre\", \"Octubre\", \"Noviembre\", \"Diciembre\"];\nlet purposes = [];\nlet monthCounter = 1;\nlet results = 'Planificación de objetivos - 2025\\n';\n\n(async () => {\n  for (let objectiveIndex = 0; objectiveIndex < 2; objectiveIndex++) {\n    let objectiveNumber = objectiveIndex + 1;\n\n    purposes.push({});\n\n    console.log(`\\nObjetivo #${objectiveNumber}\\n`);\n\n    for (let index = 0; index < inputs.length; index++) {\n      const input = await rl.question(`${inputs[index]}: `);\n\n      purposes[objectiveIndex][inputs[index]] = input;\n    }\n  }\n\n  purposes.forEach(function(key) {\n    key[\"Cantidad\"] = parseInt(key[\"Cantidad\"]);\n    key[\"Plazo\"] = parseInt(key[\"Plazo\"]);\n  });\n\n  for (let month = 0; month < months.length; month++) {\n    results = results + `\\n${months[month]}:\\n`;\n\n    purposes.forEach((purpose, index) => {\n      let goalNumber = index + 1;\n      let goal = purpose[\"Meta\"];\n      let units = purpose[\"Unidades\"];\n      let total = purpose[\"Cantidad\"];\n      let deadLine = purpose[\"Plazo\"];\n      let unitsPerMonth = purpose[\"Cantidad\"] / purpose[\"Plazo\"];\n\n      if (monthCounter <= deadLine) {\n        results = results + `[] ${goalNumber}. ${goal} (${unitsPerMonth} ${units}/mes). Total: ${total}.\\n`;\n      }\n    });\n\n    monthCounter++;\n  }\n\n  fs.writeFile('objetivos-2025.txt', results, 'utf8', (error) => {\n    if (error) {\n      console.error('Ocurrió un error al intentar exportar el archivo: ', error);\n\n      return;\n    }\n\n    console.log('El archivo fue creado exitosamente.');\n  });\n\n  rl.close();\n})();\n"
  },
  {
    "path": "Roadmap/50 - PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO/javascript/duendeintemporal.js",
    "content": "//#50 { Retos para Programadores } PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO\n/*\n * EJERCICIO:\n * El nuevo año está a punto de comenzar...\n * ¡Voy a ayudarte a planificar tus propósitos de nuevo año!\n *\n * Programa un gestor de objetivos con las siguientes características:\n * - Permite añadir objetivos (máximo 10)\n * - Calcular el plan detallado\n * - Guardar la planificación\n *\n * Cada entrada de un objetivo está formado por (con un ejemplo):\n * - Meta: Leer libros\n * - Cantidad: 12\n * - Unidades: libros\n * - Plazo (en meses): 12 (máximo 12)\n *\n * El cálculo del plan detallado generará la siguiente salida:\n * - Un apartado para cada mes\n * - Un listado de objetivos calculados a cumplir en cada mes\n *   (ejemplo: si quiero leer 12 libros, dará como resultado\n *   uno al mes)\n * - Cada objetivo debe poseer su nombre, la cantidad de\n *   unidades a completar en cada mes y su total. Por ejemplo:\n *\n *   Enero:\n *   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n *   [ ] 2. Estudiar Git (1 curso/mes). Total: 1.\n *   Febrero:\n *   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n *   ...\n *   Diciembre:\n *   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n *\n * - Si la duración es menor a un año, finalizará en el mes\n *   correspondiente.\n *\n * Por último, el cálculo detallado debe poder exportarse a .txt\n * (No subir el fichero)\n */\n\nconst fs = require('fs');\nconst readline = require('readline');\n\nconst filePath = 'goals.txt';\nconst maxGoals = 10;\nconst log = console.log;\n\nconst rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout\n});\n\nlet goals = [];\n\nconst monthNames = [\n    \"January\", \"February\", \"March\", \"April\", \"May\", \"June\",\n    \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"\n];\n\nconst menu = () => {\n    log('\\n--- New Year Goals Planner ---');\n    log('1. Add Goal');\n    log('2. View Goals');\n    log('3. Calculate Detailed Year Plan');\n    log('4. Export Plan to .txt');\n    log('5. Exit');\n    rl.question('Select an option: ', handleMenuOption);\n};\n\nconst handleMenuOption = (option) => {\n    switch (option) {\n        case '1':\n            addGoal();\n            break;\n        case '2':\n            viewGoals();\n            break;\n        case '3':\n            calculateDetailedYearPlan();\n            break;\n        case '4':\n            exportPlan();\n            break;\n        case '5':\n            exitProgram();\n            break;\n        default:\n            log('Invalid option, choose a number between 1 and 5. Please try again.');\n            menu();\n            break;\n    }\n};\n\nconst addGoal = () => {\n    if (goals.length >= maxGoals) {\n        log('Maximum number of goals reached.');\n        return menu();\n    }\n\n    askGoalName();\n};\n\nconst askGoalName = () => {\n    log('Examples of goals: Learn, Read, Practice');\n    rl.question('Goal Name: ', (name) => {\n        if (!name) {\n            log('Goal name cannot be empty. Please try again.');\n            return askGoalName();\n        }\n        askQuantity(name);\n    });\n};\n\nconst askQuantity = (name) => {\n    log('Please enter a positive number for the quantity.');\n    rl.question('Quantity: ', (quantity) => {\n        const quantityNum = parseInt(quantity);\n        if (isNaN(quantityNum) || quantityNum <= 0) {\n            log('Quantity must be a positive number. Please try again.');\n            return askQuantity(name);\n        }\n        askUnits(name, quantityNum);\n    });\n};\n\nconst askUnits = (name, quantity) => {\n    log('Examples of units: Books, Courses, Languages');\n    rl.question('Units: ', (units) => {\n        if (!units) {\n            log('Units cannot be empty. Please try again.');\n            return askUnits(name, quantity);\n        }\n        askDeadline(name, quantity, units);\n    });\n};\n\nconst askDeadline = (name, quantity, units) => {\n    log('Deadline must be a number between 1 and 12 months.');\n    rl.question('Deadline (in months, max 12): ', (deadline) => {\n        const deadlineNum = parseInt(deadline);\n        if (isNaN(deadlineNum) || deadlineNum < 1 || deadlineNum > 12) {\n            log('Deadline must be a number between 1 and 12. Please try again.');\n            return askDeadline(name, quantity, units);\n        }\n        goals.push({ name, quantity, units, deadline: deadlineNum });\n        log('Goal added!');\n        menu();\n    });\n};\n\nconst viewGoals = () => {\n    if (goals.length === 0) {\n        log('No goals registered.');\n    } else {\n        log('\\nGoals:');\n        goals.forEach((goal, index) => {\n            log(`${index + 1}. ${goal.name} - ${goal.quantity} ${goal.units} over ${goal.deadline} months`);\n        });\n    }\n    menu();\n};\n\nconst capitalizeFirstLetterOfEachWord = (string) => {\n    return string.split(' ').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' ');\n};\n\n\nconst calculateDetailedYearPlan = () => {\n    if (goals.length === 0) {\n        log('No goals to calculate.');\n        return menu();\n    }\n\n    const plan = {};\n    goals.forEach(goal => {\n        const totalTasks = goal.quantity;\n        const totalMonths = goal.deadline;\n        const monthlyGoal = Math.floor(totalTasks / totalMonths);\n        const remainder = totalTasks % totalMonths;\n\n        for (let month = 1; month <= totalMonths; month++) {\n            if (!plan[month]) {\n                plan[month] = [];\n            }\n\n            // Calculate the number of tasks for the current month\n            let tasksForMonth = monthlyGoal;\n            if (month <= remainder) {\n                tasksForMonth += 1; // Distribute the remainder tasks\n            }\n\n            const capitalizedGoalName = capitalizeFirstLetterOfEachWord(goal.name);\n            const capitalizeGoalUnits = capitalizeFirstLetterOfEachWord(goal.units);\n\n            plan[month].push(`${capitalizedGoalName} (${tasksForMonth} ${capitalizeGoalUnits}/month). Total: ${goal.quantity}. Deadline: ${monthNames[totalMonths - 1]}.`);\n        }\n    });\n\n    log('\\n--- Detailed Year Plan ---');\n    for (let month = 1; month <= 12; month++) {\n        log(`${monthNames[month - 1]}:`);\n        if (plan[month]) {\n            plan[month].forEach((item, index) => {\n                log(`[ ] ${index + 1}. ${item}`);\n            });\n        } else {\n            log('No goals for this month.');\n        }\n    }\n    menu();\n};\n\nconst exportPlan = () => {\n    const plan = [];\n    goals.forEach(goal => {\n        const monthlyGoal = Math.ceil(goal.quantity / goal.deadline);\n            for (let month = 1; month <= goal.deadline; month++) {\n                plan.push(`Month ${month}: ${goal.name} (${monthlyGoal} ${goal.units}/month). Total: ${goal.quantity}.`);\n            }\n        });\n    \n        fs.writeFile(filePath, plan.join('\\n'), (err) => {\n            if (err) throw err;\n            log(`Plan exported to ${filePath}`);\n            menu();\n        });\n    };\n    \n    const exitProgram = () => {\n        log('Exiting the program.');\n        rl.close();\n    };\n    \n    menu();\n    \n/* Output example:\n\n--- Detailed Year Plan ---\nJanuary:\n[ ] 1. Learn Programing Languages (2 Languages/month). Total: 6. Deadline: April.\n[ ] 2. Read Fiction Books (1 Books/month). Total: 10. Deadline: November.\n[ ] 3. Practice Martial Arts (2 Kunfu Style/month). Total: 8. Deadline: April.\nFebruary:\n[ ] 1. Learn Programing Languages (2 Languages/month). Total: 6. Deadline: April.\n[ ] 2. Read Fiction Books (1 Books/month). Total: 10. Deadline: November.\n[ ] 3. Practice Martial Arts (2 Kunfu Style/month). Total: 8. Deadline: April.\nMarch:\n[ ] 1. Learn Programing Languages (1 Languages/month). Total: 6. Deadline: April.\n[ ] 2. Read Fiction Books (1 Books/month). Total: 10. Deadline: November.\n[ ] 3. Practice Martial Arts (2 Kunfu Style/month). Total: 8. Deadline: April.\nApril:\n[ ] 1. Learn Programing Languages (1 Languages/month). Total: 6. Deadline: April.\n[ ] 2. Read Fiction Books (1 Books/month). Total: 10. Deadline: November.\n[ ] 3. Practice Martial Arts (2 Kunfu Style/month). Total: 8. Deadline: April.\nMay:\n[ ] 1. Read Fiction Books (1 Books/month). Total: 10. Deadline: November.\nJune:\n[ ] 1. Read Fiction Books (1 Books/month). Total: 10. Deadline: November.\nJuly:\n[ ] 1. Read Fiction Books (1 Books/month). Total: 10. Deadline: November.\nAugust:\n[ ] 1. Read Fiction Books (1 Books/month). Total: 10. Deadline: November.\nSeptember:\n[ ] 1. Read Fiction Books (1 Books/month). Total: 10. Deadline: November.\nOctober:\n[ ] 1. Read Fiction Books (1 Books/month). Total: 10. Deadline: November.\nNovember:\n[ ] 1. Read Fiction Books (0 Books/month). Total: 10. Deadline: November.\n*/    "
  },
  {
    "path": "Roadmap/50 - PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO/javascript/hectorio23.js",
    "content": "// Autor: Héctor Adán\n// GitHub: https://github.com/hectorio23\n\nconst { v4: uuidv4 } = require('uuid');\nconst fs = require('fs').promises;\n\n\n/**\n * Represents a goal with a specific amount, description, unit, and time limit.\n */\nclass Goal {\n  static MAX_MONTHS_LIMIT = 12;\n\n  constructor({ amount, description, monthsLimit, units }) {\n    if (monthsLimit < 1 || monthsLimit > Goal.MAX_MONTHS_LIMIT) {\n      throw new Error(`Months limit must be between 1 and ${Goal.MAX_MONTHS_LIMIT}.`);\n    }\n\n    this.id = uuidv4();\n    this.amount = amount;\n    this.description = description;\n    this.monthsLimit = monthsLimit;\n    this.units = units;\n  }\n\n  /**\n   * Generates a year plan based on the goal's properties.\n   * @returns {Object} The year plan for the goal.\n   */\n  toYearPlan() {\n    const yearPlan = Goal.initializeYearPlan();\n    let remainingAmount = this.amount;\n    let monthsAvailable = this.monthsLimit;\n\n    for (const month of Object.keys(yearPlan)) {\n      if (remainingAmount === 0 || monthsAvailable === 0) break;\n\n      const monthlyAmount = Math.min(remainingAmount, 1); // Distribute one unit per month\n      yearPlan[month].push({ goal: this, amount: monthlyAmount });\n\n      remainingAmount -= monthlyAmount;\n      monthsAvailable--;\n    }\n\n    return yearPlan;\n  }\n\n  static initializeYearPlan() {\n    return {\n      january: [],\n      february: [],\n      march: [],\n      april: [],\n      may: [],\n      june: [],\n      july: [],\n      august: [],\n      september: [],\n      october: [],\n      november: [],\n      december: []\n    };\n  }\n}\n\n/**\n * Manages a collection of goals and their yearly plans.\n */\nclass YearGoals {\n  static MAX_GOALS = 10;\n\n  constructor() {\n    this.goals = [];\n    this.plan = Goal.initializeYearPlan();\n  }\n\n  /**\n   * Adds a new goal to the collection and updates the yearly plan.\n   * @param {Goal} goal - The goal to be added.\n   * @returns {boolean} True if the goal was added, false otherwise.\n   */\n  addGoal(goal) {\n    if (this.goals.length >= YearGoals.MAX_GOALS) return false;\n\n    if (this.goals.some(g => g.id === goal.id)) return false;\n\n    this.goals.push(goal);\n    this.updatePlan(goal.toYearPlan());\n    return true;\n  }\n\n  /**\n   * Removes a goal from the collection and updates the yearly plan.\n   * @param {string} goalId - The ID of the goal to remove.\n   * @returns {boolean} True if the goal was removed, false otherwise.\n   */\n  removeGoal(goalId) {\n    const goalIndex = this.goals.findIndex(goal => goal.id === goalId);\n    if (goalIndex === -1) return false;\n\n    this.goals.splice(goalIndex, 1);\n    this.rebuildPlan();\n    return true;\n  }\n\n  /**\n   * Saves the yearly plan to a file.\n   * @param {string} filePath - The path to save the plan.\n   * @returns {Promise<void>}\n   */\n  async savePlan(filePath) {\n    const data = Object.entries(this.plan)\n      .map(([month, goals]) => {\n        const goalsText = goals\n          .map(({ goal, amount }, index) => `${index + 1}. ${goal.description} (${amount} ${goal.units}/month)`)\n          .join('\\n');\n\n        return `${month.toUpperCase()}\\n${goalsText}\\n`;\n      })\n      .join('\\n');\n\n    await fs.writeFile(filePath, data, 'utf-8');\n  }\n\n  /**\n   * Updates the yearly plan with a new goal's plan.\n   * @param {Object} goalPlan - The plan of the goal to add.\n   */\n  updatePlan(goalPlan) {\n    for (const [month, goals] of Object.entries(goalPlan)) {\n      this.plan[month].push(...goals);\n    }\n  }\n\n  /**\n   * Rebuilds the yearly plan based on current goals.\n   */\n  rebuildPlan() {\n    this.plan = Goal.initializeYearPlan();\n    this.goals.forEach(goal => this.updatePlan(goal.toYearPlan()));\n  }\n}\n\n\nconst yearGoals = new YearGoals();\n\nconst operations = `\nAvailable Operations:\n1 - Add a new goal\n2 - Remove a goal\n3 - Show all goals\n4 - Show yearly plan\n5 - Save plan to file\n0 - Exit\n`;\n\nconst promptUser = async () => {\n  console.log(operations);\n\n  const userInput = (await import('readline/promises')).createInterface({\n    input: process.stdin,\n    output: process.stdout\n  });\n\n  const choice = await userInput.question('Select an operation: ');\n  switch (choice) {\n    case '1': {\n      const amount = parseInt(await userInput.question('Enter goal amount: '), 10);\n      const description = await userInput.question('Enter goal description: ');\n      const monthsLimit = parseInt(await userInput.question('Enter months limit (1-12): '), 10);\n      const units = await userInput.question('Enter goal units: ');\n\n      const goal = new Goal({ amount, description, monthsLimit, units });\n      if (yearGoals.addGoal(goal)) {\n        console.log('Goal added successfully.');\n      } else {\n        console.log('Failed to add goal. Maximum limit reached or duplicate goal.');\n      }\n      break;\n    }\n    case '2': {\n      const goalId = await userInput.question('Enter the goal ID to remove: ');\n      if (yearGoals.removeGoal(goalId)) {\n        console.log('Goal removed successfully.');\n      } else {\n        console.log('Goal not found.');\n      }\n      break;\n    }\n    case '3': {\n      yearGoals.goals.forEach((goal, index) => {\n        console.log(`${index + 1}. ${goal.description} - ${goal.amount} ${goal.units} (ID: ${goal.id})`);\n      });\n      break;\n    }\n    case '4': {\n      Object.entries(yearGoals.plan).forEach(([month, goals]) => {\n        console.log(`${month.toUpperCase()}:`);\n        goals.forEach(({ goal, amount }, index) => {\n          console.log(`${index + 1}. ${goal.description} (${amount} ${goal.units}/month)`);\n        });\n      });\n      break;\n    }\n    case '5': {\n      const filePath = await userInput.question('Enter file path to save the plan: ');\n      await yearGoals.savePlan(filePath);\n      console.log(`Plan saved to ${filePath}`);\n      break;\n    }\n    case '0': {\n      console.log('Exiting...');\n      process.exit(0);\n    }\n    default:\n      console.log('Invalid choice.');\n  }\n\n  userInput.close();\n  promptUser();\n};\n\n// Start the CLI application\npromptUser();\n"
  },
  {
    "path": "Roadmap/50 - PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO/javascript/kenysdev.js",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - JavaScript\n_______________________________________________________\n#50 PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO\n-------------------------------------------------------\n* EJERCICIO:\n * El nuevo año está a punto de comenzar...\n * ¡Voy a ayudarte a planificar tus propósitos de nuevo año!\n *\n * Programa un gestor de objetivos con las siguientes características:\n * - Permite añadir objetivos (máximo 10)\n * - Calcular el plan detallado\n * - Guardar la planificación\n * \n * Cada entrada de un objetivo está formado por (con un ejemplo):\n * - Meta: Leer libros\n * - Cantidad: 12\n * - Unidades: libros\n * - Plazo (en meses): 12 (máximo 12)\n *\n * El cálculo del plan detallado generará la siguiente salida:\n * - Un apartado para cada mes\n * - Un listado de objetivos calculados a cumplir en cada mes\n *   (ejemplo: si quiero leer 12 libros, dará como resultado \n *   uno al mes)\n * - Cada objetivo debe poseer su nombre, la cantidad de\n *   unidades a completar en cada mes y su total. Por ejemplo:\n *\n *   Enero:\n *   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n *   [ ] 2. Estudiar Git (1 curso/mes). Total: 1.\n *   Febrero:\n *   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n *   ...\n *   Diciembre:\n *   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n *\n * - Si la duración es menor a un año, finalizará en el mes\n *   correspondiente.\n *   \n * Por último, el cálculo detallado debe poder exportarse a .txt\n * (No subir el fichero)\n */\n// ________________________________________________________\n\nimport { createInterface } from 'node:readline/promises';\nimport { stdin as input, stdout as output } from 'node:process';\nimport { writeFile } from 'node:fs/promises';\n\nclass ObjectivePlanner {\n    #goals = [];\n    #months = [\n        'Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio',\n        'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'\n    ];\n    #pendingMonthly = new Map();\n    #rl;\n\n    constructor() {\n        this.#rl = createInterface({ input, output });\n    }\n\n    async #add() {\n        if (this.#goals.length >= 10) {\n            console.log('\\nMáximo de 10 objetivos alcanzado.');\n            return;\n        }\n\n        try {\n            const name = (await this.#rl.question('Meta: ')).trim();\n            const quantity = parseInt(await this.#rl.question('Cantidad: '), 10);\n            const units = (await this.#rl.question('Unidades: ')).trim();\n            const months = Math.min(\n                parseInt(await this.#rl.question('Plazo (en meses): '), 10),\n                12\n            );\n\n            if (name && quantity > 0 && units && months > 0) {\n                const goal = { name, quantity, units };\n                const goalId = this.#goals.length;\n\n                const monthly = Math.floor(quantity / months);\n                const extra = quantity % months;\n\n                const monthlyQuantities = Array.from(\n                    { length: months },\n                    (_, m) => monthly + (m < extra ? 1 : 0)\n                );\n\n                this.#pendingMonthly.set(goalId, monthlyQuantities);\n                this.#goals.push(goal);\n                console.log('\\nObjetivo añadido exitosamente.');\n            } else {\n                console.log('\\nDatos inválidos.');\n            }\n        } catch (error) {\n            console.log('\\nError: Ingrese valores numéricos válidos.');\n        }\n    }\n\n    #calculatePlan() {\n        if (this.#goals.length === 0) return null;\n\n        const plan = new Map();\n\n        for (let goalId = 0; goalId < this.#goals.length; goalId++) {\n            const monthlyQuantities = this.#pendingMonthly.get(goalId);\n            const goal = this.#goals[goalId];\n\n            if (monthlyQuantities) {\n                for (let month = 0; month < monthlyQuantities.length; month++) {\n                    const quantity = monthlyQuantities[month];\n                    if (quantity > 0) {\n                        const monthName = this.#months[month];\n                        const task = `[ ] ${goal.name} (${quantity} ${goal.units}/mes). Total: ${goal.quantity}.`;\n\n                        if (!plan.has(monthName)) {\n                            plan.set(monthName, []);\n                        }\n                        plan.get(monthName).push(task);\n                    }\n                }\n            }\n        }\n\n        return plan.size > 0 ? plan : null;\n    }\n\n    async #savePlan() {\n        const plan = this.#calculatePlan();\n        if (!plan) {\n            console.log('\\nNo hay planificación para guardar.');\n            return;\n        }\n\n        const filename = `plan_${new Date().toISOString()\n            .replace(/[:.]/g, '')\n            .slice(0, 15)}.txt`;\n\n        try {\n            let content = '';\n            for (const month of this.#months) {\n                const tasks = plan.get(month);\n                if (tasks) {\n                    content += `${month}:\\n`;\n                    content += tasks.map(task => `  ${task}`).join('\\n');\n                    content += '\\n\\n';\n                }\n            }\n\n            await writeFile(filename, content, 'utf-8');\n            console.log(`\\nPlan guardado en ${filename}.`);\n        } catch (error) {\n            console.log('\\nError al guardar el archivo.');\n        }\n    }\n\n    #displayPlan() {\n        const plan = this.#calculatePlan();\n        if (!plan) {\n            console.log('\\nNo hay objetivos planificados.');\n            return;\n        }\n\n        for (const month of this.#months) {\n            const tasks = plan.get(month);\n            if (tasks) {\n                console.log(`\\n${month}:`);\n                for (const task of tasks) {\n                    console.log(`  ${task}`);\n                }\n            }\n        }\n    }\n\n    #clearScreen() {\n        if (process.platform === 'win32') {\n            process.stdout.write('\\x1Bc');\n        } else {\n            process.stdout.write('\\x1B[2J\\x1B[0f');\n        }\n    }\n\n    async run() {\n        this.#clearScreen();\n\n        while (true) {\n            console.log('\\nGestor de Objetivos:');\n            console.log('1. Añadir objetivo');\n            console.log('2. Calcular plan detallado');\n            console.log('3. Guardar planificación');\n            console.log('4. Salir');\n\n            const option = (await this.#rl.question('\\nSeleccione una opción: ')).trim();\n\n            switch (option) {\n                case '1':\n                    await this.#add();\n                    break;\n                case '2':\n                    this.#displayPlan();\n                    break;\n                case '3':\n                    await this.#savePlan();\n                    break;\n                case '4':\n                    console.log('\\n¡Adiós!');\n                    this.#rl.close();\n                    return;\n                default:\n                    console.log('\\nOpción inválida.');\n            }\n        }\n    }\n}\n\ntry {\n    const planner = new ObjectivePlanner();\n    await planner.run();\n} catch (error) {\n    console.error('Error en la aplicación:', error);\n    process.exit(1);\n}\n"
  },
  {
    "path": "Roadmap/50 - PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO/kotlin/blackriper.kt",
    "content": "import kotlinx.coroutines.flow.Flow\nimport kotlinx.coroutines.flow.emptyFlow\nimport kotlinx.coroutines.flow.flow\nimport kotlinx.coroutines.runBlocking\nimport java.io.File\nimport java.io.FileWriter\nimport java.io.PrintWriter\n\n//models\n\ndata class Task(\n    val goal: String,\n    val cant: Int,\n    val unit: String,\n    val term: Int\n)\n\n\n\ninterface ManagerTask{\n    suspend fun saveTask()\n    suspend fun calculatePlanning()\n    suspend fun savePlanning()\n}\n\n// implementation\n\nclass TaskManager(private val src: String):ManagerTask{\n\n    private val tasks= mutableListOf<Task>()\n    private lateinit var terms: Flow<String>\n    private val months=mapOf(\n        1 to \"Enero\",\n        2 to \"Febrero\",\n        3 to \"Marzo\",\n        4 to \"Abril\",\n        5 to \"Mayo\",\n        6 to \"Junio\",\n        7 to \"Julio\",\n        8 to \"Agosoto\",\n        9 to \"Septiembre\",\n        10 to \"Octubre\",\n        11 to \"Noviembre\",\n        12 to \"Diciembre\"\n    )\n\n    override suspend fun saveTask() {\n        while (true){\n            println(\"¿Cual es la meta a cumplir?\")\n            val goal= readLine()!!\n            println(\"cantidad de pasos para lograr la meta \")\n            val cant= readLine()!!.toInt()\n            println(\"unidad para lograr la meta \")\n            val unit=readLine()!!\n            println(\"Define un plazo para cumplir tu meta \")\n            val term=readLine()!!.toInt()\n            if (term>12){\n                println(\"El plazo maximo es de 12 meses \")\n                continue\n            }\n            if (tasks.size>=10) println(\"solo se permiten un maximo de 10 metas \")\n            else tasks.add(Task(goal,cant,unit,term))\n\n            println(\"¿Deseas agregar otra meta S/N ?\")\n            val option = readLine()!!.uppercase()\n            if (option==\"N\") break\n\n        }\n    }\n\n    override suspend fun calculatePlanning() {\n        terms = flow {\n            repeat(12) {\n              emit(months[it+1]!!)\n              tasks.forEach { task->\n                   if (it<task.term){\n                      val unitMon=task.cant/task.term\n                      emit(\"[] ${task.goal} ($unitMon ${task.unit}/mes) Total: ${task.cant}\")\n                  }\n              }\n            }\n        }\n    }\n\n    override suspend fun savePlanning() {\n       terms.collect { item ->\n           println(item)\n           PrintWriter(FileWriter(src,true)).use {\n                  it.write(\"$item \\n\")\n          }\n       }\n    }\n\n}\n\nfun main() = runBlocking{\n    val manager=TaskManager(\"src/main/resources/terms.txt\")\n    manager.saveTask()\n    manager.calculatePlanning()\n    manager.savePlanning()\n}"
  },
  {
    "path": "Roadmap/50 - PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO/php/siderio2.php",
    "content": "<?php\n\n/**\n * @author Desiderio Martínez Silva aka siderio2\n * @version 1.0\n * @link https://github.com/siderio2\n * @see https://retosdeprogramacion.com/roadmap/\n *\n * PHP implementation of the New Year Goals Planner 50 exercise from Mouredev Roadmap\n * Program a goal manager with the following features:\n *  - Allows you to add goals (maximum 10)\n *  - Calculate the detailed plan\n *  - Save the planning\n *\n * Each goal entry is made up of (with an example):\n *  - Goal: Read books\n *  - Quantity: 12\n *  - Units: books\n *  - Deadline (in months): 12 (maximum 12)\n *\n * The detailed plan calculation will generate the following output:\n * - A section for each month\n * - A list of calculated goals to be met in each month\n * (example: if I want to read 12 books, it will result in\n * one per month)\n * - Each goal must have its name, the number of\n * units to be completed in each month and its total. For example:\n *\n * January:\n * [ ] 1. Read books (1 book/month). Total: 12.\n * [ ] 2. Study Git (1 course/month). Total: 1.\n * February:\n * [ ] 1. Read books (1 book/month). Total: 12.\n * ...\n * December:\n * [ ] 1. Read books (1 book/month). Total: 12.\n *\n * - If the duration is less than a year, it will end in the corresponding\n * month.\n *\n * Finally, the detailed calculation must be exportable to .txt\n */\n\n// Defining constants\nconst YEAR = ['January:', 'February:', 'March:', 'April:', 'May:', 'June:', 'July:', 'August:', 'September:', 'October:', 'November:', 'December:'];\nconst MAX_GOALS = 10;\n\n// Defining the varible to store the goals\n$goals = [];\n\n/*\n * Main loop\n * Allows user to add goals (maximum determined by MAX_GOALS constant)\n * Each iteration of the loop allows the user to add a goal\n * If the user does not want to add a goal, the loop will end\n * If the user wants to add a goal, the loop will ask for the goal details,\n * checking that they are valid and adding them to the goal array\n */\ndo {\n  do {\n    $opt = readline(\"Do you want to add a goal to your 2025 calendar? (y)es / (n)o:\");\n    $opt = strtolower($opt);\n  } while ($opt != 'y' && $opt != 'n');\n\n  if ($opt === 'n') {\n    break;\n  }\n\n  $goal = [];\n  do {\n    $goal['name'] = readline(\"Goal name (min 3 / máx. 30 chars): \");\n  } while (strlen($goal['name']) < 2 || strlen($goal['name']) > 30);\n\n  do {\n    $goal['unity'] = readline(\"Unities (min 3 / máx. 30 chars): \");\n  } while (strlen($goal['unity']) < 2 || strlen($goal['unity']) > 30);\n\n  do {\n    $quantity = readline(\"How many \" . $goal['unity'] . \" (1 at least)? \");\n  } while (!is_numeric($quantity) || (int)$quantity <= 0);\n  $goal['quantity'] = (int)$quantity;\n\n  do {\n    $deadline = readline(\"How many months to reach the goal (1 - 12)? \");\n  } while (!is_numeric($deadline) || (int)$deadline < 1 || (int)$deadline > 12);\n  $goal['deadline'] = (int)$deadline;\n\n  $goals[] = $goal;\n} while (count($goals) < MAX_GOALS);\n\n/**\n * Generates a yearly plan based on the given goals.\n *\n * The plan is broken down per month and will show the goal name, the number of\n * units to be completed in each month and its total.\n *\n * @param array $goals The goals to generate the plan for.\n * @return array The yearly plan, one item per month.\n */\nfunction calculatePlan(array $goals): array\n{\n  $yearlyPlan = [];\n  foreach (YEAR as $month) {\n    $monthlyPlan = $month . \"\\n\";\n    $goalOrder = 1;\n\n    foreach ($goals as $goal) {\n      if (array_search($month, YEAR) >= $goal['deadline']) {\n        continue;\n      }\n      $monthlyGoal = $goal['quantity'] / $goal['deadline'];\n      if (is_float($monthlyGoal)) {\n        $monthlyGoal = number_format($monthlyGoal, 2);\n      }\n      $monthlyPlan .= \"[ ] \" . $goalOrder . \". \" . $goal['name'] . \" (\" . $monthlyGoal . \" \" . $goal['unity'] . \"/month). Total: \" . $goal['quantity'] . \".\\n\";\n      $goalOrder++;\n    }\n\n    $yearlyPlan[] = $monthlyPlan;\n  }\n  return $yearlyPlan;\n}\n\n/**\n * Prints the given yearly plan to the console.\n *\n * @param array $yearlyPlan The yearly plan to print, one item per month.\n */\nfunction printPlan(array $yearlyPlan): void\n{\n  foreach ($yearlyPlan as $monthlyPlan) {\n    echo $monthlyPlan;\n  }\n}\n\n/**\n * Saves the given yearly plan to a file named \"plan_2025.txt\"\n *\n * @param array $yearlyPlan The yearly plan to save, one item per month.\n */\nfunction planToFile(array $yearlyPlan): void\n{\n  $fileName = \"plan_2025.txt\";\n  $content = \"\\n2025 Goals:\\n\";\n  foreach ($yearlyPlan as $monthlyPlan) {\n    $content .= $monthlyPlan;\n  }\n\n  $file = fopen($fileName, 'w');\n\n  if ($file === FALSE) {\n    echo \"\\nOOOPS! There's been a problem opening the \" . $fileName . \" file: \" . error_get_last()['message'];\n  } else {\n    if (fwrite($file, $content) === FALSE) {\n      echo \"\\nOOOPS! There's been a problem writing the content to \" . $fileName . \" file: \" . error_get_last()['message'];\n    } else {\n      echo \"\\nThe \" . $fileName . \" with your 2025 goals is ready!\";\n    }\n  }\n}\n\n$yearlyPlan = calculatePlan($goals);\nprintPlan($yearlyPlan);\nplanToFile($yearlyPlan);\n"
  },
  {
    "path": "Roadmap/50 - PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO/python/Gordo-Master.py",
    "content": "# 50 - Planificador de objetivos de Año Nuevo\nimport os\nfrom enum import Enum\n\nclass Month(Enum):\n    ENERO = 1\n    FEBRERO = 2\n    MARZO = 3\n    ABRIL = 4\n    MAYO = 5\n    JUNIO = 6\n    JULIO = 7\n    AGOSTO = 8\n    SEPTIEMBRE = 9\n    OCTUBRE = 10\n    NOVIEMBRE = 11\n    DICIEMBRE = 12\n\nclass Goals:\n    def __init__(self):\n        self.goal: str = None\n        self.count = 0\n        self.unit: str = None\n        self.time_frame: int = 0\n        self.calculated_goal = {Month(x).name: \"\" for x in range(1,13)}\n        # {goal} ({.calculated_goal[month]} {.unit}/mes). Total: {.count}\n\n    def create(self):\n        valid_data = True\n        print(\"Creador de objetivos: \")\n        goal = input(\"Meta: \")\n        count = input(\"Cantidad: \")\n        unit = input(\"Unidad de medida: \")\n        time_frame = input(\"Plazo en meses (máximo 12): \")\n\n        if not count.isdigit() or int(count) < 0:\n            print(\"\\nLa cantidad debe ser un numero entero mayor que 0\")\n            valid_data = False\n        if not time_frame.isdigit() or int(time_frame) < 0:\n            print(\"\\nEl plazo debe ser un numero entero mayor que 0\")\n            valid_data = False\n            if int(time_frame) > 12:\n                print(\"\\nEl plazo maximo es de 12 meses\")\n                valid_data = False\n        if valid_data:\n            self.goal = goal\n            self.count = int(count)\n            self.unit = unit\n            self.time_frame = int(time_frame)\n        else:\n            print(\"\\nError: no se pudo crear el objetivo\")        \n\n\n    def calculate(self):\n        media = self.count/self.time_frame\n        media = round(media,2)\n        for i in range(1,self.time_frame+1):\n            self.calculated_goal[Month(i).name] = media\n\n\nclass Planner:\n    def __init__(self):\n        self.goals = []\n        self.planner_text = {Month(x+1).name:[] for x in range(12)}\n    \n    def add_goal(self):\n        if len(self.goals) < 10:\n            goal = Goals()\n            try:\n                goal.create()\n                goal.calculate()\n                self.goals.append(goal)\n            except Exception as e:\n                print(f\"\\nError en la creacción de la meta\")\n        else:\n            print(\"\\nError: Solo se puede tener un maximo de 10 objetivos!\")\n            return\n\n    def calculate_planner(self):\n        if not self.goals:\n            print(\"\\nError: No se ha agregado ningun objetivo.\")\n            return\n        \n        self.planner_text = {Month(x+1).name:[] for x in range(12)}\n        for goal in self.goals:\n            for x in range(1,13):\n                if goal.calculated_goal[Month(x).name]:\n                    text = f\"{goal.goal} ({goal.calculated_goal[Month(x).name]} {goal.unit}/mes). Total: {goal.count}\"\n                    self.planner_text[Month(x).name].append(text)\n        \n    def show_planner(self):\n        if not self.goals:\n            return\n        print(\"\\nImprimiendo plan detallado:\")\n        for month, texts_list in self.planner_text.items():\n            if not self.planner_text[month]:\n                continue\n            print(f\"\\n{month}:\")\n            for index, text in enumerate(texts_list):\n                print(f\"[ ] {index+1}. {text}\")\n\n    def save_planner(self):\n        if not self.goals:\n            print(\"\\nError: No se ha agregado ningun objetivo.\")\n            return\n        \n        file_path = os.path.join(os.path.dirname(\n            os.path.abspath(__file__)), \"plan.txt\")\n        \n        with open(file_path, \"w\", encoding=\"utf-8\") as f:\n            f.write(\"Plan detallado\\n\")\n            for month, texts_list in self.planner_text.items():\n                if not self.planner_text[month]:\n                    continue\n                f.write(f\"\\n{month}:\")\n                for index, text in enumerate(texts_list):\n                    f.write(f\"[ ] {index+1}. {text}\\n\")\n        print(f\"\\nDocumento generado con exito en la ruta {file_path}!\")\n\nplanner_2025 = Planner()\n\n\ndef show_menu():\n    print(\"\\nPlanificador de objetivos:\")\n    print(\"1. Añadir objetivo\")\n    print(\"2. Calcular plan detallado\")\n    print(\"3. Guardar la planificación\")\n    print(\"4. Salir\")\n\nwhile True:\n\n    show_menu()\n\n    option = input(\"Elige una opción: \")\n\n    match option:\n        case \"1\":\n            planner_2025.add_goal()\n        case \"2\":\n            planner_2025.calculate_planner()\n            planner_2025.show_planner()\n        case \"3\":\n            planner_2025.calculate_planner()\n            planner_2025.save_planner()\n        case \"4\":\n            print(\"Saliendo del planificador...\")\n            break\n        case _:\n            print(\"Valor invalido.\")"
  },
  {
    "path": "Roadmap/50 - PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO/python/Nicojsuarez2.py",
    "content": "# #50 PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO\n> #### Dificultad: Difícil | Publicación: 23/12/24 | Corrección: 30/12/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * El nuevo año está a punto de comenzar...\n * ¡Voy a ayudarte a planificar tus propósitos de nuevo año!\n *\n * Programa un gestor de objetivos con las siguientes características:\n * - Permite añadir objetivos (máximo 10)\n * - Calcular el plan detallado\n * - Guardar la planificación\n * \n * Cada entrada de un objetivo está formado por (con un ejemplo):\n * - Meta: Leer libros\n * - Cantidad: 12\n * - Unidades: libros\n * - Plazo (en meses): 12 (máximo 12)\n *\n * El cálculo del plan detallado generará la siguiente salida:\n * - Un apartado para cada mes\n * - Un listado de objetivos calculados a cumplir en cada mes\n *   (ejemplo: si quiero leer 12 libros, dará como resultado \n *   uno al mes)\n * - Cada objetivo debe poseer su nombre, la cantidad de\n *   unidades a completar en cada mes y su total. Por ejemplo:\n *\n *   Enero:\n *   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n *   [ ] 2. Estudiar Git (1 curso/mes). Total: 1.\n *   Febrero:\n *   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n *   ...\n *   Diciembre:\n *   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n *\n * - Si la duración es menor a un año, finalizará en el mes\n *   correspondiente.\n *   \n * Por último, el cálculo detallado debe poder exportarse a .txt\n * (No subir el fichero)\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/50 - PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO/python/cdryampi.py",
    "content": "# /*\n#  * EJERCICIO:\n#  * El nuevo año está a punto de comenzar...\n#  * ¡Voy a ayudarte a planificar tus propósitos de nuevo año!\n#  *\n#  * Programa un gestor de objetivos con las siguientes características:\n#  * - Permite añadir objetivos (máximo 10)\n#  * - Calcular el plan detallado\n#  * - Guardar la planificación\n#  * \n#  * Cada entrada de un objetivo está formado por (con un ejemplo):\n#  * - Meta: Leer libros\n#  * - Cantidad: 12\n#  * - Unidades: libros\n#  * - Plazo (en meses): 12 (máximo 12)\n#  *\n#  * El cálculo del plan detallado generará la siguiente salida:\n#  * - Un apartado para cada mes\n#  * - Un listado de objetivos calculados a cumplir en cada mes\n#  *   (ejemplo: si quiero leer 12 libros, dará como resultado \n#  *   uno al mes)\n#  * - Cada objetivo debe poseer su nombre, la cantidad de\n#  *   unidades a completar en cada mes y su total. Por ejemplo:\n#  *\n#  *   Enero:\n#  *   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n#  *   [ ] 2. Estudiar Git (1 curso/mes). Total: 1.\n#  *   Febrero:\n#  *   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n#  *   ...\n#  *   Diciembre:\n#  *   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n#  *\n#  * - Si la duración es menor a un año, finalizará en el mes\n#  *   correspondiente.\n#  *   \n#  * Por último, el cálculo detallado debe poder exportarse a .txt\n#  * (No subir el fichero)\n#  */\nimport math\nimport os\n\nclass Gestor:\n    __LIMIT = 10 # Máximo de objetivos permitidos por usuario, restaremos cada vez que se añada un objetivo.\n    __LIMIT_MONTHS = 12 # Máximo de meses permitidos para el plazo de un objetivo.\n    __MONTHS = ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre']\n    __PROCECED_DATA = [] # Datos procesados para poder guardarlos en un archivo además de mostrarlos en consola.\n\n    def __init__(self):\n        self.objetivos = [] # Lista de objetivos\n        self.__LIMIT_MONTHS = 12\n\n    def calcular(self):\n        \"\"\"\n        Calcula los objetivos mensuales y los estructura para cada mes.\n        en los objetivos que tengan plazo impar, se redondeará hacia arriba para no tener decimales.\n        \"\"\"\n        self.__PROCECED_DATA = []  # Limpieza de datos procesados\n\n        # Recorremos los objetivos para calcular su distribución mensual\n        for objetivo in self.objetivos:\n            # Obtenemos los datos del objetivo\n            cantidad = objetivo['cantidad']  # Total de unidades\n            plazo = objetivo['plazo']  # Meses disponibles\n            meta = objetivo['meta']  # Descripción del objetivo\n            unidad = objetivo['unidad']  # Unidad del objetivo\n\n            restante = cantidad  # Inicializamos el restante\n            cuota_mensual = cantidad / plazo  # Cálculo de cuota base por mes\n\n            for mes in range(plazo):\n                cantidad_mes = max(math.ceil(cuota_mensual),1)  # Cuota redondeada minimizando a 1\n                if restante < cantidad_mes:\n                    cantidad_mes = restante  # Ajustamos la cuota al restante\n\n                restante -= cantidad_mes  # Reducimos el restante\n                nuevo_objetivo = {\n                    'mes': self.__MONTHS[mes],  # Mes correspondiente\n                    'meta': meta,  # Meta del objetivo\n                    'cantidad': cantidad_mes,  # Cantidad para el mes\n                    'unidad': unidad,  # Unidad asociada\n                    'total': cantidad,  # Total del objetivo\n                }\n                if cantidad_mes > 0:\n                    self.__PROCECED_DATA.append(nuevo_objetivo)  # Añadimos al resultado\n\n        self.mostrar_objetivos()  # Muestra los objetivos procesados\n\n\n    def limpiar_fichero(self):\n        \"\"\"\n        Limpia el archivo de texto donde se guardan los objetivos\n        \"\"\"\n        file_ruta = self.obtener_fichero()\n        with open(file_ruta, 'w', encoding=\"utf-8\") as file:\n            file.write('')\n\n    def obtener_fichero(self):\n        \"\"\"\n        Obtiene el archivo de texto donde se guardan los objetivos\n        \"\"\"\n        return os.path.join(os.getcwd(), 'objetivos.txt')\n    \n    def guardar(self):\n        \"\"\"\n        Guarda los objetivos procesados en un archivo de texto\n        \"\"\"\n        #limpiamos el archivo de texto\n        self.limpiar_fichero()\n        #obtenemos la ruta del archivo de texto\n        file_ruta = self.obtener_fichero()\n\n        objetivos_por_mes = {}\n\n        # Agrupamos los objetivos por mes\n\n        for objetivo in self.__PROCECED_DATA:\n            # Obtenemos el mes del objetivo\n            mes = objetivo['mes']\n            # Si el mes no está en el diccionario, lo añadimos\n            if mes not in objetivos_por_mes:\n                # Inicializamos la lista de objetivos\n                objetivos_por_mes[mes] = []\n            # Añadimos el objetivo a la lista correspondiente\n            objetivos_por_mes[mes].append(objetivo)\n\n            # Abrimos el archivo de texto y sobre escribimos mes a mes\n            with open(file_ruta, 'r+', encoding=\"utf-8\") as file:\n                for mes, objetivos in objetivos_por_mes.items():\n                    # Mostramos el mes\n                    file.write(f'{mes}:\\n')\n                    # Mostramos los objetivos del mes\n                    for i, objetivo in enumerate(objetivos):\n                        #escribimos en el archivo de texto con el objetivo\n                        file.write(f'[{i+1}] {objetivo[\"meta\"]} ({objetivo[\"cantidad\"]} {objetivo[\"unidad\"]}/mes). Total: {objetivo[\"total\"]}.\\n')\n                    #saltamos una linea\n                    file.write('\\n')\n            #cerramos el archivo de texto\n            file.close()    \n\n    def add_objetivo(self,meta: str, cantidad:int, unidad:str, plazo:int)->None:\n        \"\"\"\n        Añade un objetivo a la lista de objetivos.\n        - Meta: Leer libros\n        - Cantidad: 12\n        - Unidades: libros\n        - Plazo (en meses): 12 (máximo 12)\n        \"\"\"\n        # Validaciones\n        if(self.__LIMIT == 0):\n            print('Has alcanzado el máximo de objetivos permitidos.')\n            return\n        \n        if(plazo > self.__LIMIT_MONTHS):\n            print(f'El plazo no puede ser mayor a {self.__LIMIT_MONTHS} meses.')\n            return\n        \n        if cantidad <= 0:\n            print('La cantidad no puede ser menor o igual a 0.')\n            return\n        \n        # añadir objetivo cuando se cumplan las validaciones.\n        self.objetivos.append({\n            'meta': meta,\n            'cantidad': cantidad,\n            'unidad': unidad,\n            'plazo': plazo\n        })\n        self.__LIMIT -= 1\n        print(f'Objetivo añadido: {meta}')\n        \n\n\n    def mostrar_objetivos(self):\n        \"\"\"\n        Muestra los objetivos procesados por mes en el formato requerido.\n        \"\"\"\n        if not self.__PROCECED_DATA:\n            print(\"No hay objetivos procesados.\")\n            return\n\n        objetivos_por_mes = {}\n        # Agrupamos los objetivos por mes\n        for objetivo in self.__PROCECED_DATA:\n            # Obtenemos el mes del objetivo\n            mes = objetivo['mes']\n            # Si el mes no está en el diccionario, lo añadimos\n            if mes not in objetivos_por_mes:\n                # Inicializamos la lista de objetivos\n                objetivos_por_mes[mes] = []\n            # Añadimos el objetivo a la lista correspondiente\n            objetivos_por_mes[mes].append(objetivo)\n        for mes, objetivos in objetivos_por_mes.items():\n            # Mostramos el mes\n            print(f'{mes}:')\n            # Mostramos los objetivos del mes\n            for i, objetivo in enumerate(objetivos):\n                print(f'[{i+1}] {objetivo[\"meta\"]} ({objetivo[\"cantidad\"]} {objetivo[\"unidad\"]}/mes). Total: {objetivo[\"total\"]}.')\n            print()\n\n\nif __name__ == '__main__':\n    gestor = Gestor()\n    # Añadimos los objetivos al gestor.\n\n    gestor.add_objetivo('Leer libros', 12, 'libros', 12)\n    gestor.add_objetivo('Estudiar Git', 1, 'curso', 1)\n    gestor.add_objetivo('Hacer ejercicio', 12, 'rutina', 12)\n    gestor.add_objetivo('Aprender Python', 12, 'curso', 7)\n    gestor.add_objetivo('Aprender Javascript', 7, 'curso', 12)\n    gestor.add_objetivo('Aprender Vue', 8, 'curso', 9)\n    gestor.add_objetivo('Aprender Svelte', 12, 'curso', 4)\n    gestor.add_objetivo('Aprender React', 10, 'curso', 4)\n    gestor.add_objetivo('Aprender Angular', 2, 'curso', 4)\n    gestor.add_objetivo('Aprender Node', 8, 'curso', 4)\n\n    gestor.calcular()\n    gestor.guardar()"
  },
  {
    "path": "Roadmap/50 - PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO/python/davidrguez98.py",
    "content": "\"\"\" /*\n * EJERCICIO:\n * El nuevo año está a punto de comenzar...\n * ¡Voy a ayudarte a planificar tus propósitos de nuevo año!\n *\n * Programa un gestor de objetivos con las siguientes características:\n * - Permite añadir objetivos (máximo 10)\n * - Calcular el plan detallado\n * - Guardar la planificación\n * \n * Cada entrada de un objetivo está formado por (con un ejemplo):\n * - Meta: Leer libros\n * - Cantidad: 12\n * - Unidades: libros\n * - Plazo (en meses): 12 (máximo 12)\n *\n * El cálculo del plan detallado generará la siguiente salida:\n * - Un apartado para cada mes\n * - Un listado de objetivos calculados a cumplir en cada mes\n *   (ejemplo: si quiero leer 12 libros, dará como resultado \n *   uno al mes)\n * - Cada objetivo debe poseer su nombre, la cantidad de\n *   unidades a completar en cada mes y su total. Por ejemplo:\n *\n *   Enero:\n *   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n *   [ ] 2. Estudiar Git (1 curso/mes). Total: 1.\n *   Febrero:\n *   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n *   ...\n *   Diciembre:\n *   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n *\n * - Si la duración es menor a un año, finalizará en el mes\n *   correspondiente.\n *   \n * Por último, el cálculo detallado debe poder exportarse a .txt\n * (No subir el fichero)\n */ \"\"\"\n\nimport os\n\nMONTHS = [\"Enero\", \"Febrero\", \"Marzo\", \"Abril\", \"Mayo\", \"Junio\", \"Julio\", \"Agosto\", \"Septiembre\", \"Octubre\", \"Noviembre\", \"Diciembre\"]\n\ndef show_menu():\n\n    print(\"\\nPlanificador de objetivos\")\n    print(\"1. Añadir objetivo.\")\n    print(\"2. Calcular el plan detallado\")\n    print(\"3. Guardar la planificación\")\n    print(\"4. Salir\")\n\nclass Goal:\n    \n    def __init__(self, goal_name: str, amount: int, units: str, limit: int):\n        self.goal_name = goal_name\n        self.amount = amount\n        self.units = units\n        self.limit = limit   \n\ndef request_goal() -> Goal:\n\n    goal_name = input(\"Meta: \")\n\n    while True:\n        try:\n            amount = int(input(\"Cantidad: \"))\n            if amount <= 0:\n                print(\"La cantidad debe ser un número positivo.\")\n                continue\n            break\n        except:\n            print(\"Introduce un número entero válido.\")\n\n    units = input(\"Unidades: \")\n\n    while True:\n        try:\n            limit = int(input(\"Plazo en meses (máx. 12): \"))\n            if limit <= 0 or limit > len(MONTHS):\n                print(\"El plazo debe ser de 1 a 12 meses.\")\n                continue\n            break\n        except:\n            print(\"Introduce un número entre 1 y 12.\")\n\n    return Goal(goal_name, amount, units, limit)\n\ndef calculate_detailed_plan(goals: list[Goal]) -> dict:\n\n    plan = {month: [] for month in range(1, len(MONTHS) + 1)}\n\n    for goal in goals:\n\n        month_amount = goal.amount / goal.limit\n\n        for month in range(1, goal.limit + 1):\n\n            plan[month].append(Goal(goal.goal_name, round(month_amount, 1), goal.units, goal.amount))\n\n    return plan\n\ndef show_detailed_plan(plan: dict):\n\n    for month in range(1, len(MONTHS) + 1):\n\n        if not plan[month]:\n            break\n        \n        print(f\"\\n{MONTHS[month - 1]}: \")\n\n        for index, goal in enumerate(plan[month], start=1):\n            print(f\"[ ] {index}. {goal.goal_name} ({goal.amount} {goal.units}/mes). Total: {goal.limit}.\")\n\ndef save_detailed_plan(plan: dict):\n\n    file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), \"plan.txt\")\n\n    with open(file_path, \"w\", encoding=\"utf-8\") as file:\n        file.write(\"Plan detallado\")\n\n        for month in range(1, len(MONTHS) + 1):\n\n            if not plan[month]:\n                break\n            \n            file.write(f\"\\n{MONTHS[month - 1]}:\\n\")\n\n            for index, goal in enumerate(plan[month], start=1):\n                file.write(f\"[ ] {index}. {goal.goal_name} ({goal.amount} {goal.units}/mes). Total: {goal.limit}.\\n\")\n\n    print(f\"Plan guardado con éxito en {file_path}\")\n\n\n\n\ngoals = []\n\nwhile True:\n\n    show_menu()\n\n    option = input(\"\\nElige una opción: \")\n\n    if option == \"1\":\n        if len(goals) >= 10:\n            print(\"Has alcanzado el número máximo de objetivos (10).\")\n            continue\n        else:\n            goal = request_goal()\n            goals.append(goal)\n            print(\"Objetivo añadido correctamente.\")\n            continue\n\n    if option == \"2\":\n        if len(goals) == 0:\n            print(\"No hay objetivos añadidos.\")\n            continue\n        else:\n            plan = calculate_detailed_plan(goals)\n            show_detailed_plan(plan)\n            continue\n\n    if option == \"3\":\n        if len(goals) == 0:\n            print(\"No hay objetivos para guardar.\")\n            continue\n        else:\n            plan = calculate_detailed_plan(goals)\n            save_detailed_plan(plan)\n\n    if option == \"4\":\n        print(\"Saliendo del planificador.\")\n        break\n    else:\n        print(\"Opción no válida. Elige una opción entre el 1 y 4.\")\n        \n"
  },
  {
    "path": "Roadmap/50 - PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO/python/duendeintemporal.py",
    "content": "#50 { Retos para Programadores } PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO \n\n# Bibliography reference:\n# I use GPT as a reference and sometimes to correct or generate proper comments.\n\n\"\"\"\n * EJERCICIO:\n * El nuevo año está a punto de comenzar...\n * ¡Voy a ayudarte a planificar tus propósitos de nuevo año!\n *\n * Programa un gestor de objetivos con las siguientes características:\n * - Permite añadir objetivos (máximo 10)\n * - Calcular el plan detallado\n * - Guardar la planificación\n *\n * Cada entrada de un objetivo está formado por (con un ejemplo):\n * - Meta: Leer libros\n * - Cantidad: 12\n * - Unidades: libros\n * - Plazo (en meses): 12 (máximo 12)\n *\n * El cálculo del plan detallado generará la siguiente salida:\n * - Un apartado para cada mes\n * - Un listado de objetivos calculados a cumplir en cada mes\n *   (ejemplo: si quiero leer 12 libros, dará como resultado\n *   uno al mes)\n * - Cada objetivo debe poseer su nombre, la cantidad de\n *   unidades a completar en cada mes y su total. Por ejemplo:\n *\n *   Enero:\n *   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n *   [ ] 2. Estudiar Git (1 curso/mes). Total: 1.\n *   Febrero:\n *   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n *   ...\n *   Diciembre:\n *   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n *\n * - Si la duración es menor a un año, finalizará en el mes\n *   correspondiente.\n *\n * Por último, el cálculo detallado debe poder exportarse a .txt\n * (No subir el fichero)\n\n\"\"\"\n\nlog = print\n\nimport os\n\nfile_path = 'goals.txt'\nmax_goals = 10\ngoals = []\n\nmonth_names = [\n    \"January\", \"February\", \"March\", \"April\", \"May\", \"June\",\n    \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"\n]\n\ndef menu():\n    log('\\n--- New Year Goals Planner ---')\n    log('1. Add Goal')\n    log('2. View Goals')\n    log('3. Calculate Detailed Year Plan')\n    log('4. Export Plan to .txt')\n    log('5. Exit')\n    option = input('Select an option: ')\n    handle_menu_option(option)\n\ndef handle_menu_option(option):\n    if option == '1':\n        add_goal()\n    elif option == '2':\n        view_goals()\n    elif option == '3':\n        calculate_detailed_year_plan()\n    elif option == '4':\n        export_plan()\n    elif option == '5':\n        exit_program()\n    else:\n        log('Invalid option, choose a number between 1 and 5. Please try again.')\n        menu()\n\ndef add_goal():\n    if len(goals) >= max_goals:\n        log('Maximum number of goals reached.')\n        return menu()\n\n    ask_goal_name()\n\ndef ask_goal_name():\n    log('Examples of goals: Learn, Read, Practice')\n    name = input('Goal Name: ')\n    if not name:\n        log('Goal name cannot be empty. Please try again.')\n        return ask_goal_name()\n    ask_quantity(name)\n\ndef ask_quantity(name):\n    log('Please enter a positive number for the quantity.')\n    quantity = input('Quantity: ')\n    try:\n        quantity_num = int(quantity)\n        if quantity_num <= 0:\n            raise ValueError\n    except ValueError:\n        log('Quantity must be a positive number. Please try again.')\n        return ask_quantity(name)\n    ask_units(name, quantity_num)\n\ndef ask_units(name, quantity):\n    log('Examples of units: Books, Courses, Languages')\n    units = input('Units: ')\n    if not units:\n        log('Units cannot be empty. Please try again.')\n        return ask_units(name, quantity)\n    ask_deadline(name, quantity, units)\n\ndef ask_deadline(name, quantity, units):\n    log('Deadline must be a number between 1 and 12 months.')\n    deadline = input('Deadline (in months, max 12): ')\n    try:\n        deadline_num = int(deadline)\n        if deadline_num < 1 or deadline_num > 12:\n            raise ValueError\n    except ValueError:\n        log('Deadline must be a number between 1 and 12. Please try again.')\n        return ask_deadline(name, quantity, units)\n    \n    goals.append({'name': name, 'quantity': quantity, 'units': units, 'deadline': deadline_num})\n    log('Goal added!')\n    menu()\n\ndef view_goals():\n    if not goals:\n        log('No goals registered.')\n    else:\n        log('\\nGoals:')\n        for index, goal in enumerate(goals):\n            log(f\"{index + 1}. {goal['name']} - {goal['quantity']} {goal['units']} over {goal['deadline']} months\")\n    menu()\n\ndef capitalize_first_letter_of_each_word(string):\n    return ' '.join(word.capitalize() for word in string.split())\n\ndef calculate_detailed_year_plan():\n    if not goals:\n        log('No goals to calculate.')\n        return menu()\n\n    plan = {}\n    for goal in goals:\n        total_tasks = goal['quantity']\n        total_months = goal['deadline']\n        monthly_goal = total_tasks // total_months\n        remainder = total_tasks % total_months\n\n        for month in range(1, total_months + 1):\n            if month not in plan:\n                plan[month] = []\n\n            tasks_for_month = monthly_goal\n            if month <= remainder:\n                tasks_for_month += 1  # Distribute the remainder tasks\n\n            capitalized_goal_name = capitalize_first_letter_of_each_word(goal['name'])\n            capitalized_goal_units = capitalize_first_letter_of_each_word(goal['units'])\n\n            plan[month].append(f\"{capitalized_goal_name} ({tasks_for_month} {capitalized_goal_units}/month). Total: {goal['quantity']}. Deadline: {month_names[total_months - 1]}.\")\n\n    log('\\n--- Detailed Year Plan ---')\n    for month in range(1, 13):\n        log(f\"{month_names[month - 1]}:\")\n        if month in plan:\n            for index, item in enumerate(plan[month]):\n                log(f\"[ ] {index + 1}. {item}\")\n        else:\n            log('No goals for this month.')\n    menu()\n\ndef export_plan():\n    plan = []\n    for goal in goals:\n        monthly_goal = -(-goal['quantity'] // goal['deadline'])  # Ceiling division\n        for month in range(1, goal['deadline'] + 1):\n            plan.append(f\"Month {month}: {goal['name']} ({monthly_goal} {goal['units']}/month). Total: {goal['quantity']}.\")\n\n    with open(file_path, 'w') as file:\n        file.write('\\n'.join(plan))\n    \n    log(f'Plan exported to {file_path}')\n    menu()\n\ndef exit_program():\n    log('Exiting the program.')\n    exit()\n\n# Start the program\nmenu()\n\n# Output Example:\n\"\"\"   \n--- Detailed Year Plan ---\nJanuary:\n[ ] 1. Learn (3 Martial Arts Skills/month). Total: 30. Deadline: December.\n[ ] 2. Read (4 Diverse Articules/month). Total: 48. Deadline: December.\n[ ] 3. Practice (1 Languages/month). Total: 8. Deadline: December.\nFebruary:\n[ ] 1. Learn (3 Martial Arts Skills/month). Total: 30. Deadline: December.\n[ ] 2. Read (4 Diverse Articules/month). Total: 48. Deadline: December.\n[ ] 3. Practice (1 Languages/month). Total: 8. Deadline: December.\nMarch:\n[ ] 1. Learn (3 Martial Arts Skills/month). Total: 30. Deadline: December.\n[ ] 2. Read (4 Diverse Articules/month). Total: 48. Deadline: December.\n[ ] 3. Practice (1 Languages/month). Total: 8. Deadline: December.\nApril:\n[ ] 1. Learn (3 Martial Arts Skills/month). Total: 30. Deadline: December.\n[ ] 2. Read (4 Diverse Articules/month). Total: 48. Deadline: December.\n[ ] 3. Practice (1 Languages/month). Total: 8. Deadline: December.\nMay:\n[ ] 1. Learn (3 Martial Arts Skills/month). Total: 30. Deadline: December.\n[ ] 2. Read (4 Diverse Articules/month). Total: 48. Deadline: December.\n[ ] 3. Practice (1 Languages/month). Total: 8. Deadline: December.\nJune:\n[ ] 1. Learn (3 Martial Arts Skills/month). Total: 30. Deadline: December.\n[ ] 2. Read (4 Diverse Articules/month). Total: 48. Deadline: December.\n[ ] 3. Practice (1 Languages/month). Total: 8. Deadline: December.\nJuly:\n[ ] 1. Learn (2 Martial Arts Skills/month). Total: 30. Deadline: December.\n[ ] 2. Read (4 Diverse Articules/month). Total: 48. Deadline: December.\n[ ] 3. Practice (1 Languages/month). Total: 8. Deadline: December.\nAugust:\n[ ] 1. Learn (2 Martial Arts Skills/month). Total: 30. Deadline: December.\n[ ] 2. Read (4 Diverse Articules/month). Total: 48. Deadline: December.\n[ ] 3. Practice (1 Languages/month). Total: 8. Deadline: December.\nSeptember:\n[ ] 1. Learn (2 Martial Arts Skills/month). Total: 30. Deadline: December.\n[ ] 2. Read (4 Diverse Articules/month). Total: 48. Deadline: December.\n[ ] 3. Practice (0 Languages/month). Total: 8. Deadline: December.\nOctober:\n[ ] 1. Learn (2 Martial Arts Skills/month). Total: 30. Deadline: December.\n[ ] 2. Read (4 Diverse Articules/month). Total: 48. Deadline: December.\n[ ] 3. Practice (0 Languages/month). Total: 8. Deadline: December.\nNovember:\n[ ] 1. Learn (2 Martial Arts Skills/month). Total: 30. Deadline: December.\n[ ] 2. Read (4 Diverse Articules/month). Total: 48. Deadline: December.\n[ ] 3. Practice (0 Languages/month). Total: 8. Deadline: December.\nDecember:\n[ ] 1. Learn (2 Martial Arts Skills/month). Total: 30. Deadline: December.\n[ ] 2. Read (4 Diverse Articules/month). Total: 48. Deadline: December.\n[ ] 3. Practice (0 Languages/month). Total: 8. Deadline: December.\n\n\"\"\""
  },
  {
    "path": "Roadmap/50 - PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO/python/edisonlmg.py",
    "content": "import pandas as pd\n\nprint('''\\n\n#=======================================================================================================================\n# 50 - Planificador de objetivos de año nuevo\n#=======================================================================================================================\n''')\n\nprint('''\nTe ayudaré a planificar tus objetivo para el nuevo año.\n\nTus objetivos deben seguir el siguiente modelo:\n- Meta: Leer libros\n- Cantidad: 12\n- Unidades: libros\n- Plazo (en meses): 12 (máximo 12)\n\nPor favor ingresa la información necesaria y sigue las indicaciones:\n''')\n\nobjectives = pd.DataFrame()\ncount = 0\n\nwhile count <= 10:\n\n    count += 1\n\n    if count > 10:\n        print('Has ingresado el numero maximo de objetivos.')\n        break\n\n    print(f'''\nIngresa informacion del objetivo {count}:\n    ''')\n\n    objective = {}\n\n    objective['Meta'] = [input('Nombre de la meta: ')]\n    objective['Cantidad'] = [int(input('Cantidad: '))]\n    objective['Unidad'] = [input('Unidad de medida: ')]\n    objective['Plazo'] = [int(input('Plazo: '))]\n\n    objectives = pd.concat([objectives, pd.DataFrame(objective)], ignore_index=True)\n\n    action = int(input('''\nPara ingresar el siguiente objetivo digita 0.\nPara terminar digita 1.\n                '''))\n\n    if action > 0:\n        break\n\nobjectives['Frecuencia'] = objectives['Cantidad'] / objectives['Plazo']\n\nmounths = ['Enero','Febrero','Marzo','Abril','Mayo','Junio','Julio','Agosto','Setiembre','Octubre','Noviembre','Diciembre']\n\nmounth_num = 0\n\ntext = ''\n\nfor mounth in mounths[:objectives['Plazo'].max()]:\n\n    mounth_num += 1\n\n    text += f'\\n{mounth}:'\n\n    for index, row in objectives.iterrows():\n        if mounth_num <= row['Plazo']:\n            text += f'\\n{index+1}. {objectives['Meta'][index]} ({objectives['Frecuencia'][index]} {objectives['Unidad'][index]}/mes): Total: {objectives[\"Cantidad\"][index]}'\n        else:\n            pass\n\nprint(f'\\nFelicidades, aquí tienes tu planificación de objetivos:\\n{text}')\n\nsave = input('\\n¿Desea exportar su planificación (SI/NO)?: ').upper()\n\nif save == 'SI':\n    with open(\"planificacion_2025.txt\", \"w\") as archivo:\n        archivo.write(text)\n\n    print('Archivo exporta exitosamente ¡Adios!')\n\nelse:\n    print('\\nNo hay problema ¡Adios!')\n"
  },
  {
    "path": "Roadmap/50 - PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO/python/giulianovfz.py",
    "content": "\"\"\"\n * EJERCICIO:\n * El nuevo año está a punto de comenzar...\n * ¡Voy a ayudarte a planificar tus propósitos de nuevo año!\n *\n * Programa un gestor de objetivos con las siguientes características:\n * - Permite añadir objetivos (máximo 10)\n * - Calcular el plan detallado\n * - Guardar la planificación\n *\n * Cada entrada de un objetivo está formado por (con un ejemplo):\n * - Meta: Leer libros\n * - Cantidad: 12\n * - Unidades: libros\n * - Plazo (en meses): 12 (máximo 12)\n *\n * El cálculo del plan detallado generará la siguiente salida:\n * - Un apartado para cada mes\n * - Un listado de objetivos calculados a cumplir en cada mes\n *   (ejemplo: si quiero leer 12 libros, dará como resultado\n *   uno al mes)\n * - Cada objetivo debe poseer su nombre, la cantidad de\n *   unidades a completar en cada mes y su total. Por ejemplo:\n *\n *   Enero:\n *   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n *   [ ] 2. Estudiar Git (1 curso/mes). Total: 1.\n *   Febrero:\n *   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n *   ...\n *   Diciembre:\n *   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n *\n * - Si la duración es menor a un año, finalizará en el mes\n *   correspondiente.\n *\n * Por último, el cálculo detallado debe poder exportarse a .txt\n * (No subir el fichero)\n\"\"\"\nimport os\n\n\nclass Planificador:\n\n    def __init__(self):\n        self.objetivos = {}\n        self.planificacion = []\n\n    def agregar_objetivos(self, numero_objetivos):\n        contador = 1\n\n        while 11 > numero_objetivos > 0:\n\n            numero_objetivos -= 1\n            print(f\"\"\"\\n| Ingresando el objetivo {\n                  contador} |\"\"\", end=f'\\n{\"¯\"*28}')\n\n            meta = input('\\n\\t• Ingresa la meta: ')\n\n            try:\n                cantidad = int(input('\\n\\t• Ingresa la cantidad: '))\n            except ValueError:\n                print('\\nIngresa sólo números\\n')\n\n            unidades = input('\\n\\t• Ingresa las unidades: ')\n\n            try:\n                plazo = int(\n                    input('\\n\\t• Ingresa el plazo(en meses y máximo 12): '))\n            except ValueError:\n                print('\\nIngresa sólo números\\n')\n\n            if plazo > 12:\n                print(\n                    '\\nNo puedes ingresar más de 12 meses, ingresa todos los datos nuevamente\\n')\n                numero_objetivos += 1\n\n            else:\n                self.objetivos.update(\n                    {f\"objetivo{contador}\": {\"Meta\": meta,\n                                             \"Cantidad\": cantidad,\n                                             \"Unidades\": unidades,\n                                             \"Plazo\": plazo}\n                     })\n                contador += 1\n\n    def calcular_plan(self):\n        \"\"\"\n        Calcula el plan de objetivos y los muestra en la terminal\n        \"\"\"\n        if self.objetivos:\n            objetivos = [objetivo[1] for objetivo in self.objetivos.items()]\n            mes_plazo = [objetivo[1]['Plazo']\n                         for objetivo in self.objetivos.items()]\n\n            max_mes = max(mes_plazo)\n\n            meses = [\"Enero\",\n                     \"Febrero\",\n                     \"Marzo\",\n                     \"Abril\",\n                     \"Mayo\",\n                     \"Junio\",\n                     \"Julio\",\n                     \"Agosto\",\n                     \"Septiembre\",\n                     \"Octubre\",\n                     \"Noviembre\",\n                     \"Diciembre\"\n                     ]\n\n            for valor_mes in range(0, max_mes):\n\n                mes = meses[valor_mes]\n                self.planificacion.append([mes])\n\n                print(f'\\n\\n{mes} {\"—\"*(11 - len(mes))}|{\"—\"*60}\\n')\n\n                for ciclo, dato in enumerate(objetivos, 1):\n\n                    if dato['Plazo'] >= (valor_mes + 1):\n\n                        cantidad_mensual = dato['Cantidad'] / \\\n                            dato['Plazo'] if dato['Cantidad'] > 1 else dato['Cantidad']\n\n                        cantidad_total = f'{dato['Plazo']} {\n                            \"Meses\" if dato['Plazo'] > 1 else \"Mes\"}'\n\n                        objetivo_mes = f'[ ] {ciclo}. {dato['Meta']} ({cantidad_mensual} {\n                            dato['Unidades']}/mes). Cantidad total: {cantidad_total}'\n\n                        self.planificacion[valor_mes].append(objetivo_mes)\n\n                        print(f'{\" \"*12}{objetivo_mes}')\n        else:\n            print(\n                '\\n\\tDebes agregar los objetivos para realizar el calculo del plan detallado\\n')\n\n    def exportar_planificacion(self):\n        \"\"\"\n        Acá se guarda el archivo en plan_detallado.txt con\n        el contenido de los objetivos\n        \"\"\"\n        if self.planificacion:\n            nombre_archivo = \"plan_detallado.txt\"\n            ruta = os.path.join(os.path.dirname(__file__), nombre_archivo)\n\n            with open(ruta, \"w\", encoding=\"utf-8\") as archivo:\n                print('\\n\\tComenzado la exportación del archivo')\n\n                archivo.write('\\t\\t\\tPlanificación de objetivos\\n')\n                for mes_planificado in self.planificacion:\n                    for planificacion in mes_planificado:\n\n                        if mes_planificado[0] == planificacion:\n                            archivo.write(f\"\"\"\\n\\n{planificacion} {\n                                \"—\"*(11 - len(planificacion))}|{\"—\"*60}\\n\"\"\")\n                        else:\n                            archivo.write(f'\\n{\" \"*12}{planificacion}')\n\n                print(f'\\n\\tSe realizo con exito la exportación del plan detallado, busca el archivo: {\n                    nombre_archivo}')\n        else:\n            print(\n                '\\n\\tPara exportar, primero debes realizar el calculo de la planificación\\n')\n\n\ndef cantidad_objetivos(ciclo):\n\n    while ciclo:\n\n        try:\n            objetivos = input(\n                '\\n• Ingresa la cantidad de Objetivos(Máximo 10): ')\n\n        except ValueError:\n            print('\\nSolo puedes ingresar números\\n')\n\n        if objetivos.isdigit():\n            n_objetivo = int(objetivos)\n\n            if n_objetivo > 10:\n                print('\\nRecuerda solo puedes ingresar 10 objetivos\\n')\n\n            elif n_objetivo < 0:\n                print('\\nNo puedes ingresar números negativos\\n')\n            else:\n                ciclo = False\n                return n_objetivo\n\n\ndef menu():\n\n    opciones = [\n        \"1. Ingresar objetivo\",\n        \"2. Calcular la planificación\",\n        \"3. Exportar la planifición a un archivo .txt\",\n        \"4. Salir\"\n    ]\n\n    print('\\n\\n\\tPlanificado de objetivos de año nuevo\\n')\n    for opcion in opciones:\n        print(f'\\t{opcion}')\n\n    try:\n        n_opcion = int(input('\\nIngresa una opción del menu: '))\n\n    except ValueError:\n        n_opcion = '_'\n\n    return n_opcion\n\n\ndef main():\n\n    plan = Planificador()\n\n    print('\\n\\tBienvenidos al Gestor de Objetivos del año nuevo')\n\n    while True:\n        n_opcion = menu()\n\n        match n_opcion:\n            case 1:\n                c_objetivo = cantidad_objetivos(True)\n                plan.agregar_objetivos(c_objetivo)\n            case 2:\n                plan.calcular_plan()\n            case 3:\n                plan.exportar_planificacion()\n            case 4:\n                break\n            case _:\n                print('\\n\\tError, Opción no encontrada, ingresa sólo números del menú\\n')\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Roadmap/50 - PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO/python/hectorio23.py",
    "content": "# Autor: Héctor Adán\n# GitHub: https://github.com/hectorio23\n\nfrom datetime import datetime\nfrom pathlib import Path\nfrom typing import TypedDict, Union, TypeVar, Iterable, Callable\nfrom uuid import UUID, uuid4\n\n##################################\n########## Data Types ############            \n##################################\n\nclass YearPlan(TypedDict):\n    \"\"\"Represents a detailed plan for goals across the months of a year.\"\"\"\n    january: list[list[Union[\"Goal\", int]]]\n    february: list[list[Union[\"Goal\", int]]]\n    march: list[list[Union[\"Goal\", int]]]\n    april: list[list[Union[\"Goal\", int]]]\n    may: list[list[Union[\"Goal\", int]]]\n    june: list[list[Union[\"Goal\", int]]]\n    july: list[list[Union[\"Goal\", int]]]\n    august: list[list[Union[\"Goal\", int]]]\n    september: list[list[Union[\"Goal\", int]]]\n    october: list[list[Union[\"Goal\", int]]]\n    november: list[list[Union[\"Goal\", int]]]\n    december: list[list[Union[\"Goal\", int]]]\n\n###################################\n######## Custom Exceptions ########       \n###################################\n\nclass MonthsOutOfRangeException(Exception):\n    \"\"\"Exception raised when the month limit for a goal is out of valid range.\"\"\"\n    def __init__(self) -> None:\n        super().__init__(\"Months out of range. Valid range is 1 to 12.\")\n\n###################################\n########### Core Classes ##########           \n###################################\n\nclass Goal:\n    \"\"\"Represents an individual goal with its details and constraints.\"\"\"\n\n    def __init__(self, *, amount: int, description: str, months_limit: int, units: str) -> None:\n        self.amount = amount\n        self.description = description\n        self.uid = uuid4()\n        self.units = units\n\n        if months_limit < 1 or months_limit > self.max_months_limit():\n            raise MonthsOutOfRangeException()\n\n        self.months_limit = months_limit\n\n    @staticmethod\n    def max_months_limit() -> int:\n        \"\"\"Returns the maximum allowed months for a goal.\"\"\"\n        return 12\n\n    def to_monthly_plan(self) -> YearPlan:\n        \"\"\"Generates a yearly plan for the goal based on its amount and months limit.\"\"\"\n        year_plan: YearPlan = {month: [] for month in YearPlan.__annotations__.keys()}\n        remaining_amount = self.amount\n\n        for month in year_plan:\n            if remaining_amount <= 0:\n                break\n\n            month_amount = min(remaining_amount, self.months_limit)\n            year_plan[month].append([self, month_amount])\n            remaining_amount -= month_amount\n\n        return year_plan\n\n\nclass YearGoals:\n    \"\"\"Manages a collection of goals and their aggregated yearly plan.\"\"\"\n\n    def __init__(self) -> None:\n        self.goals = []\n        self.plan = {month: [] for month in YearPlan.__annotations__.keys()}\n\n    @staticmethod\n    def max_goals() -> int:\n        \"\"\"Returns the maximum number of goals allowed.\"\"\"\n        return 10\n\n    def add_goal(self, goal: Goal) -> None:\n        \"\"\"Adds a new goal to the collection and updates the yearly plan.\"\"\"\n        if len(self.goals) >= self.max_goals():\n            raise ValueError(\"Maximum number of goals reached.\")\n\n        self.goals.append(goal)\n        self._update_plan_with_goal(goal)\n\n    def _update_plan_with_goal(self, goal: Goal) -> None:\n        \"\"\"Incorporates a new goal into the existing yearly plan.\"\"\"\n        goal_plan = goal.to_monthly_plan()\n\n        for month, tasks in goal_plan.items():\n            self.plan[month].extend(tasks)\n\n    def save_plan(self, file_path: str) -> None:\n        \"\"\"Saves the yearly plan to a text file.\"\"\"\n        with open(file_path, \"w\", encoding=\"utf-8\") as file:\n            for month, tasks in self.plan.items():\n                file.write(f\"{month.capitalize()}:\\n\")\n                for idx, (goal, amount) in enumerate(tasks):\n                    file.write(f\"[ ] {idx + 1}. {goal.description} ({amount} {goal.units}/month). Total: {goal.amount}.\\n\")\n                file.write(\"\\n\")\n\n####################################\n######## Utility Functions #########        \n####################################\n\ndef get_user_input(prompt: str, validate: Callable[[str], bool] = lambda x: True) -> str:\n    \"\"\"Prompts the user for input and validates the response.\"\"\"\n    while True:\n        response = input(prompt).strip()\n        if validate(response):\n            return response\n        print(\"Invalid input. Please try again.\")\n\n####################################\n########## Main Program Loop #######        \n####################################\n\ndef main() -> None:\n    \"\"\"Main entry point for the Goal Management application.\"\"\"\n    year_goals = YearGoals()\n\n    menu = (\n        \"\\nGoal Management System\\n\"\n        \"------------------------\\n\"\n        \"1. Add a new goal\\n\"\n        \"2. Remove an existing goal\\n\"\n        \"3. Display all goals\\n\"\n        \"4. Show detailed plan\\n\"\n        \"5. Save plan to file\\n\"\n        \"0. Exit\\n\"\n    )\n\n    while True:\n        print(menu)\n        choice = get_user_input(\"Select an option: \", lambda x: x.isdigit() and 0 <= int(x) <= 5)\n\n        if choice == \"0\":\n            print(\"Goodbye!\")\n            break\n\n        if choice == \"1\":\n            description = get_user_input(\"Enter goal description: \")\n            units = get_user_input(\"Enter units (e.g., books, hours): \")\n            amount = int(get_user_input(\"Enter amount: \", lambda x: x.isdigit()))\n            months_limit = int(get_user_input(\"Enter months limit (1-12): \", lambda x: x.isdigit() and 1 <= int(x) <= 12))\n\n            try:\n                goal = Goal(amount=amount, description=description, months_limit=months_limit, units=units)\n                year_goals.add_goal(goal)\n                print(\"Goal added successfully.\")\n            except Exception as e:\n                print(f\"Error: {e}\")\n\n        elif choice == \"2\":\n            goal_uid = get_user_input(\"Enter the ID of the goal to remove: \")\n            year_goals.goals = [g for g in year_goals.goals if str(g.uid) != goal_uid]\n            print(\"Goal removed, if it existed.\")\n\n        elif choice == \"3\":\n            if not year_goals.goals:\n                print(\"No goals available.\")\n            else:\n                for goal in year_goals.goals:\n                    print(f\"- {goal.description} ({goal.amount} {goal.units} over {goal.months_limit} months)\")\n\n        elif choice == \"4\":\n            for month, tasks in year_goals.plan.items():\n                print(f\"{month.capitalize()}:\\n\")\n                for idx, (goal, amount) in enumerate(tasks):\n                    print(f\"  [ ] {idx + 1}. {goal.description} ({amount} {goal.units}/month). Total: {goal.amount}.\")\n                print()\n\n        elif choice == \"5\":\n            file_path = f\"plan_{datetime.now().strftime('%Y%m%d_%H%M%S')}.txt\"\n            year_goals.save_plan(file_path)\n            print(f\"Plan saved to {file_path}\")\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Roadmap/50 - PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO/python/hozlucas28.py",
    "content": "# pylint: disable=missing-module-docstring,missing-class-docstring,missing-function-docstring,consider-using-dict-items,line-too-long\n\nfrom datetime import datetime\nfrom pathlib import Path\nfrom typing import TypedDict, Union, TypeVar, Iterable, Callable\nfrom uuid import UUID, uuid4\n\n# ---------------------------------------------------------------------------- #\n#                                     TYPES                                    #\n# ---------------------------------------------------------------------------- #\n\nYearPlan = TypedDict(\n    \"YearPlan\",\n    {\n        \"january\": list[list[Union[\"Goal\", int]]],\n        \"february\": list[list[Union[\"Goal\", int]]],\n        \"march\": list[list[Union[\"Goal\", int]]],\n        \"april\": list[list[Union[\"Goal\", int]]],\n        \"may\": list[list[Union[\"Goal\", int]]],\n        \"june\": list[list[Union[\"Goal\", int]]],\n        \"july\": list[list[Union[\"Goal\", int]]],\n        \"august\": list[list[Union[\"Goal\", int]]],\n        \"september\": list[list[Union[\"Goal\", int]]],\n        \"october\": list[list[Union[\"Goal\", int]]],\n        \"november\": list[list[Union[\"Goal\", int]]],\n        \"december\": list[list[Union[\"Goal\", int]]],\n    },\n)\n\n# ---------------------------------------------------------------------------- #\n#                                  EXCEPTIONS                                  #\n# ---------------------------------------------------------------------------- #\n\n\nclass MonthsOutOfRangeException(Exception):\n    def __init__(self) -> None:\n        super().__init__(\"Months out of range\")\n\n\n# ---------------------------------------------------------------------------- #\n#                                    CLASSES                                   #\n# ---------------------------------------------------------------------------- #\n\n\n# ----------------------------------- Goal ----------------------------------- #\n\n\nclass Goal:\n    __amount: int\n    __description: str\n    __uid: UUID\n    __months_limit: int\n    __units: str\n\n    def __init__(\n        self, *, _amount: int, _description: str, _months_limit: int, _units: str\n    ) -> None:\n        self.__amount = _amount\n        self.__description = _description\n        self.__uid = uuid4()\n        self.__units = _units\n\n        if _months_limit < 1 or _months_limit > Goal.max_months_limit():\n            raise MonthsOutOfRangeException()\n\n        self.__months_limit = _months_limit\n\n    @staticmethod\n    def max_months_limit() -> int:\n        return 12\n\n    @property\n    def amount(self) -> int:\n        return self.__amount\n\n    @property\n    def description(self) -> str:\n        return self.__description\n\n    @property\n    def uid(self) -> UUID:\n        return self.__uid\n\n    @property\n    def months_limit(self) -> int:\n        return self.__months_limit\n\n    @property\n    def units(self) -> str:\n        return self.__units\n\n    def to_year_plan(self) -> YearPlan:\n        year_plan: YearPlan = {\n            \"january\": [],\n            \"february\": [],\n            \"march\": [],\n            \"april\": [],\n            \"may\": [],\n            \"june\": [],\n            \"july\": [],\n            \"august\": [],\n            \"september\": [],\n            \"october\": [],\n            \"november\": [],\n            \"december\": [],\n        }\n\n        counter: int = self.__amount\n        while counter:\n            month_counter: int = self.__months_limit\n            for _key in year_plan:\n                if not counter or not month_counter:\n                    break\n\n                try:\n                    year_plan[_key][0][1] += 1\n                except IndexError:\n                    year_plan[_key].append([self, 1])\n\n                month_counter -= 1\n                counter -= 1\n\n        return year_plan\n\n\n# --------------------------------- YearGoals -------------------------------- #\n\n\nclass YearGoals:\n    __goals: list[Goal]\n    __plan: YearPlan\n\n    def __init__(self) -> None:\n        self.__goals = []\n\n        self.__plan = {\n            \"january\": [],\n            \"february\": [],\n            \"march\": [],\n            \"april\": [],\n            \"may\": [],\n            \"june\": [],\n            \"july\": [],\n            \"august\": [],\n            \"september\": [],\n            \"october\": [],\n            \"november\": [],\n            \"december\": [],\n        }\n\n    @staticmethod\n    def max_goals() -> int:\n        return 10\n\n    @property\n    def goals(self) -> list[Goal]:\n        return self.__goals\n\n    @property\n    def plan(self) -> YearPlan:\n        return self.__plan\n\n    def __append_goal_to_plan(self, *, _goal: Goal) -> None:\n        goal_year_plan: YearPlan = _goal.to_year_plan()\n\n        aux: YearPlan = self.plan\n\n        for _key in goal_year_plan:\n            if goal_year_plan[_key]:\n                aux[_key].append(*goal_year_plan[_key])\n                continue\n            break\n\n        self.__plan = aux\n\n    def __remove_goal_from_plan(self, *, uid: UUID) -> None:\n        def __fn(element: list[Union[Goal, int]]) -> bool:\n            return element[0].uid == uid  # type: ignore\n\n        aux: YearPlan = self.plan\n\n        for _key in self.__plan:\n            goal_i: int = index_fn(iterable=aux[_key], fn=__fn)\n            if goal_i == -1:\n                break\n\n            aux[_key] = [*aux[_key][:goal_i], aux[_key][goal_i + 1 :]]\n\n    def add_goal(self, *, new_goal: Goal) -> bool:\n        if len(self.__goals) == YearGoals.max_goals():\n            return False\n\n        new_goal_uid: UUID = new_goal.uid\n\n        goal_i: int = index_fn(\n            iterable=self.__goals, fn=lambda value: value.uid == new_goal_uid\n        )\n        if goal_i != -1:\n            return False\n\n        self.__goals.append(new_goal)\n        self.__append_goal_to_plan(_goal=new_goal)\n\n        return True\n\n    def remove_goal(self, *, uid: UUID) -> bool:\n        goal_i: int = index_fn(iterable=self.__goals, fn=lambda goal: goal.uid == uid)\n        if goal_i == -1:\n            return False\n\n        self.__goals = [*self.__goals[:goal_i], *self.__goals[goal_i + 1 :]]\n        self.__remove_goal_from_plan(uid=uid)\n\n        return True\n\n    def save_plan(\n        self,\n        *,\n        _path: str,\n        row: Callable[[Goal, int, int], str],\n        month_title: Callable[[str], str] = lambda month: month.capitalize(),\n    ) -> None:\n        data: list[str] = []\n\n        for _key in self.__plan:\n            goals_month: list[list[Union[Goal, int]]] = self.__plan[_key]\n\n            rows: list[str] = [month_title(_key)]\n            for _i, [_goal, _amount] in enumerate(iterable=goals_month):\n                rows.append(row(_goal, _amount, _i))  # type: ignore\n\n            data.append(\"\\n\".join(rows))\n            data.append(\"\\n\\n\")\n\n        with open(file=_path, mode=\"wt\", encoding=\"utf-8\") as file:\n            file.writelines(data)\n            file.close()\n\n\n# ---------------------------------------------------------------------------- #\n#                                   UTILITIES                                  #\n# ---------------------------------------------------------------------------- #\n\nT = TypeVar(\"T\")\n\n\ndef index_fn(*, iterable: Iterable[T], fn: Callable[[T], bool]) -> int:\n    for _i, element in enumerate(iterable=iterable):\n        if fn(element):\n            return _i\n    return -1\n\n\ndef goal_to_row(_goal: Goal, _amount: int, index: int) -> str:\n    _desc: str = _goal.description\n    _units: str = _goal.units\n    _total_amount: int = _goal.amount\n    return f\"[ ] {index + 1}. {_desc} ({_amount} {_units}/mes). Total: {_total_amount}.\"\n\n\n# ---------------------------------------------------------------------------- #\n#                                     MAIN                                     #\n# ---------------------------------------------------------------------------- #\n\nyear_goals: YearGoals = YearGoals()\n\n\nprint(\n    \"> Available operations:\\n\\n\"\n    + \" 1 - Add goal.\\n\"\n    + \" 2 - Remove goal.\\n\"\n    + \" 3 - Show goals.\\n\"\n    + \" 4 - Show plan.\\n\"\n    + \" 5 - Save plan.\\n\"\n    + \" 0 - Exit.\"\n)\n\nuser_input: str = input(\"\\n> Select an operation: \").strip()\n\nwhile user_input != \"0\":\n    match (user_input):\n        case \"1\":\n            print(\"\\n> Complete the following goal data...\")\n            units: str = input(\"\\n> Units: \").strip()\n            amount: int = int(input(\"\\n> Amount (as a number): \").strip())\n            description: str = input(\"\\n> Description: \").strip()\n\n            months_limit: int = int(input(\"\\n> Months limit (as a number): \").strip())\n            while months_limit < 1 or months_limit > Goal.max_months_limit():\n                print(\n                    \"\\n> Error! Months limit must be between 1 and 12 (both included). Try again...\"\n                )\n                months_limit = int(input(\"\\n> Months limit (as a number): \").strip())\n\n            goal: Goal = Goal(\n                _amount=amount,\n                _description=description,\n                _months_limit=months_limit,\n                _units=units,\n            )\n\n            if year_goals.add_goal(new_goal=goal):\n                print(\"\\n> Goal added!\")\n            else:\n                print(\"\\n> An error occurred! The goal was not added.\")\n\n        case \"2\":\n            goal_uid: UUID = UUID(input(\"\\n> Goal id to remove: \").strip())\n\n            if year_goals.remove_goal(uid=goal_uid):\n                print(f'\\n> Goal \"{goal_uid}\" removed!')\n            else:\n                print(\"\\n> An error occurred! The goal was not removed.\")\n\n        case \"3\":\n            goals_rows: list[str] = []\n            for _goal in year_goals.goals:\n                goals_rows.append(\n                    f'\\n• Goal \"{_goal.uid}\"...'\n                    + f'\\n\\n  - ID: \"{_goal.uid}\".'\n                    + f'\\n  - Description: \"{_goal.description}\".'\n                    + f\"\\n  - Months limit: {_goal.months_limit}.\"\n                    + f\"\\n  - Amount: {_goal.amount}.\"\n                    + f'\\n  - Units: \"{_goal.units}\".'\n                )\n\n            if goals_rows:\n                print(\"\\n\".join(goals_rows))\n\n        case \"4\":\n            plan: YearPlan = year_goals.plan\n\n            plan_rows: list[str] = []\n            for key in plan:\n                goals: list[list[Union[Goal, int]]] = plan[key]\n\n                plan_row: str = f\"\\n{key.capitalize()}:\"\n                for i, [goal, amount] in enumerate(iterable=goals):  # type: ignore\n                    desc: str = goal.description\n                    units: str = goal.units\n                    total_amount: int = goal.amount\n                    plan_row += f\"\\n[ ] {i + 1}. {desc} ({amount} {units}/mes). Total: {total_amount}.\"\n\n                plan_rows.append(plan_row)\n\n            if plan_rows:\n                print(\"\\n\".join(plan_rows))\n\n        case \"5\":\n            current_date: datetime = datetime.now()\n            path: str = f\"{Path().absolute()}\\\\plan-{current_date.year}.txt\"\n            year_goals.save_plan(_path=path, row=goal_to_row)\n\n            print(f'\\n> Plan saved in \"{path}\" path.')\n\n        case \"_\":\n            print(\"\\n> Invalid operation! Try again...\")\n\n    print(\n        \"\\n> Available operations:\\n\\n\"\n        + \" 1 - Add goal.\\n\"\n        + \" 2 - Remove goal.\\n\"\n        + \" 3 - Show goals.\\n\"\n        + \" 4 - Show plan.\\n\"\n        + \" 5 - Save plan.\\n\"\n        + \" 0 - Exit.\"\n    )\n\n    user_input = input(\"\\n> Select an operation: \").strip()\n"
  },
  {
    "path": "Roadmap/50 - PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO/python/idiegorojas.py",
    "content": "\"\"\" \n# 50 - Planificador de ano nuevo \n\"\"\"\n# Programa un gestor de objetivos con las siguientes características:\n    # Permite añadir objetivos (máximo 10)\n    # Calcular el plan detallado\n    # Guardar la planificación\n# Cada entrada de un objetivo está formado por (con un ejemplo):\n    # Meta: Leer libros\n    # Cantidad: 12\n    # Unidades: libros\n    # Plazo (en meses): 12 (máximo 12)\n# El cálculo del plan detallado generará la siguiente salida:\n   # Un apartado para cada mes\n   # Un listado de objetivos calculados a cumplir en cada mes\n   # (ejemplo: si quiero leer 12 libros, dará como resultado\n   # uno al mes)\n   # Cada objetivo debe poseer su nombre, la cantidad de\n   # unidades a completar en cada mes y su total. Por ejemplo:\n   # Enero:\n   # [ ] 1. Leer libros (1 libro/mes). Total: 12.\n   # [ ] 2. Estudiar Git (1 curso/mes). Total: 1.\n   # Febrero:\n   # [ ] 1. Leer libros (1 libro/mes). Total: 12.\n   # ...\n   # Diciembre:\n   # [ ] 1. Leer libros (1 libro/mes). Total: 12.\n   # Si la duración es menor a un año, finalizará en el mes\n   # correspondiente.\n# Por último, el cálculo detallado debe poder exportarse a .txt\n\n\nclass Objetivo:\n    def __init__(self, meta, cantidad, unidades, plazo):\n        self.meta = meta\n        self.cantidad = cantidad\n        self.unidades = unidades\n        self.plazo = min(plazo, 12)  # Máximo 12 meses\n        self.cantidad_mensual = self.cantidad / self.plazo\n\nclass Planificador:\n    def __init__(self):\n        self.objetivos = []\n        self.meses = [\"Enero\", \"Febrero\", \"Marzo\", \"Abril\", \"Mayo\", \"Junio\", \n                      \"Julio\", \"Agosto\", \"Septiembre\", \"Octubre\", \"Noviembre\", \"Diciembre\"]\n    \n    def anadir_objetivo(self, meta, cantidad, unidades, plazo):\n        if len(self.objetivos) >= 10:\n            print(\"¡Has alcanzado el máximo de 10 objetivos!\")\n            return False\n        \n        try:\n            cantidad = float(cantidad)\n            plazo = int(plazo)\n            \n            if cantidad <= 0 or plazo <= 0 or plazo > 12:\n                print(\"La cantidad debe ser mayor que 0 y el plazo entre 1 y 12 meses.\")\n                return False\n            \n            objetivo = Objetivo(meta, cantidad, unidades, plazo)\n            self.objetivos.append(objetivo)\n            print(f\"Objetivo '{meta}' añadido correctamente.\")\n            return True\n        except ValueError:\n            print(\"Error: Los valores de cantidad y plazo deben ser números.\")\n            return False\n    \n    def calcular_plan(self):\n        if not self.objetivos:\n            print(\"No hay objetivos para calcular el plan.\")\n            return None\n        \n        plan = {}\n        for mes_idx, mes in enumerate(self.meses):\n            plan[mes] = []\n            for obj in self.objetivos:\n                if mes_idx < obj.plazo:\n                    plan[mes].append(obj)\n        \n        return plan\n    \n    def mostrar_plan(self):\n        plan = self.calcular_plan()\n        if not plan:\n            return \"\"\n        \n        resultado = []\n        for mes, objetivos in plan.items():\n            if not objetivos:\n                continue\n                \n            resultado.append(f\"{mes}:\")\n            for i, obj in enumerate(objetivos, 1):\n                cantidad_mensual = obj.cantidad_mensual\n                # Formatear cantidad mensual sin decimales si es un número entero\n                if cantidad_mensual == int(cantidad_mensual):\n                    cantidad_mensual = int(cantidad_mensual)\n                \n                resultado.append(f\"[ ] {i}. {obj.meta} ({cantidad_mensual} {obj.unidades}/mes). \"\n                                f\"Total: {obj.cantidad}.\")\n        \n        return \"\\n\".join(resultado)\n    \n    def exportar_plan(self, nombre_archivo=\"plan_anual.txt\"):\n        plan_texto = self.mostrar_plan()\n        if not plan_texto:\n            print(\"No hay plan para exportar.\")\n            return False\n        \n        try:\n            with open(nombre_archivo, \"w\", encoding=\"utf-8\") as archivo:\n                archivo.write(\"PLAN DE OBJETIVOS ANUALES\\n\")\n                archivo.write(\"=========================\\n\\n\")\n                archivo.write(plan_texto)\n            print(f\"Plan exportado correctamente a '{nombre_archivo}'.\")\n            return True\n        except Exception as e:\n            print(f\"Error al exportar el plan: {str(e)}\")\n            return False\n\ndef menu_principal():\n    planificador = Planificador()\n    \n    while True:\n        print(\"\\n==== PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO ====\")\n        print(\"1. Añadir objetivo\")\n        print(\"2. Ver plan detallado\")\n        print(\"3. Exportar plan a archivo .txt\")\n        print(\"4. Salir\")\n        \n        opcion = input(\"\\nSelecciona una opción (1-4): \")\n        \n        if opcion == \"1\":\n            if len(planificador.objetivos) >= 10:\n                print(\"Ya has alcanzado el máximo de 10 objetivos.\")\n                continue\n                \n            print(\"\\n-- NUEVO OBJETIVO --\")\n            meta = input(\"Meta: \")\n            cantidad = input(\"Cantidad: \")\n            unidades = input(\"Unidades: \")\n            plazo = input(\"Plazo (en meses, máximo 12): \")\n            \n            planificador.anadir_objetivo(meta, cantidad, unidades, plazo)\n            \n        elif opcion == \"2\":\n            print(\"\\n-- PLAN DETALLADO --\")\n            plan = planificador.mostrar_plan()\n            if plan:\n                print(plan)\n            else:\n                print(\"No hay objetivos para mostrar.\")\n                \n        elif opcion == \"3\":\n            nombre_archivo = input(\"Nombre del archivo (o Enter para usar 'plan_anual.txt'): \")\n            if not nombre_archivo:\n                nombre_archivo = \"plan_anual.txt\"\n            planificador.exportar_plan(nombre_archivo)\n            \n        elif opcion == \"4\":\n            print(\"¡Gracias por usar el Planificador de Objetivos!\")\n            break\n            \n        else:\n            print(\"Opción no válida. Por favor, selecciona una opción del 1 al 4.\")\n\nif __name__ == \"__main__\":\n    menu_principal()"
  },
  {
    "path": "Roadmap/50 - PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO/python/ignaciovihe.py",
    "content": "\"\"\"\n * EJERCICIO:\n * El nuevo año está a punto de comenzar...\n * ¡Voy a ayudarte a planificar tus propósitos de nuevo año!\n *\n * Programa un gestor de objetivos con las siguientes características:\n * - Permite añadir objetivos (máximo 10)\n * - Calcular el plan detallado\n * - Guardar la planificación\n * \n * Cada entrada de un objetivo está formado por (con un ejemplo):\n * - Meta: Leer libros\n * - Cantidad: 12\n * - Unidades: libros\n * - Plazo (en meses): 12 (máximo 12)\n *\n * El cálculo del plan detallado generará la siguiente salida:\n * - Un apartado para cada mes\n * - Un listado de objetivos calculados a cumplir en cada mes\n *   (ejemplo: si quiero leer 12 libros, dará como resultado \n *   uno al mes)\n * - Cada objetivo debe poseer su nombre, la cantidad de\n *   unidades a completar en cada mes y su total. Por ejemplo:\n *\n *   Enero:\n *   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n *   [ ] 2. Estudiar Git (1 curso/mes). Total: 1.\n *   Febrero:\n *   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n *   ...\n *   Diciembre:\n *   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n *\n * - Si la duración es menor a un año, finalizará en el mes\n *   correspondiente.\n *   \n * Por último, el cálculo detallado debe poder exportarse a .txt\n * (No subir el fichero)\n\"\"\"\n\nfrom abc import ABC, abstractmethod\nfrom enum import Enum\n\n\nclass Month(Enum):\n    ENERO = 1\n    FEBRERO = 2\n    MARZO = 3\n    ABRIL = 4\n    MAYO = 5\n    JUNIO = 6\n    JULIO = 7\n    AGOSTO = 8\n    SEPTIEMBRE = 9\n    OCTUBRE = 10\n    NOVIEMBRE = 11\n    DICIEMBRE = 12\n\n    def __str__(self):\n        return self.name.capitalize()    \n\nclass Resolution:\n    def __init__(self, goal: str, amount: int, units: str, deadline:int) -> None:\n        self.goal = goal\n        self.amount = amount\n        self.units = units\n        self.deadline = deadline\n\n\nclass ResolutionsManager:\n    def __init__(self) -> None:\n        self.resolutions = []\n\n    def add_resolution(self, resolution: Resolution) -> bool:\n        if len(self.resolutions) > 9:\n            return False\n        \n        self.resolutions.append(resolution)\n        return True\n    \n    def generate_plan(self) -> str:\n        plan_lines = []\n        for i in range(1,13):\n            plan_lines.append(f\"\\n{Month(i)}\")\n            for resolution in self.resolutions:\n                if resolution.deadline >= i:\n                    plan_lines.append(\n                        f\"\\t{i}. {resolution.goal}\"\n                        f\"({resolution.amount / resolution.deadline} {resolution.units}/mes.\"\n                        f\"Total {resolution.amount})\"\n                    )\n        return \"\\n\".join(plan_lines)\n\n\nclass UIService:\n\n    def display_menu(self) -> int:\n\n        print(\"Planificador de objetivos.\")\n        print(\"1.- Agregar proposito\")\n        print(\"2.- Calcular plan detallado.\")\n        print(\"3.- Guardar plan\")\n        print(\"4.- Salir\")\n\n        selection = 0\n        while selection not in range(1,5): \n            selection = input(\"Introduce una opción correcta: \")\n            if not selection.isdigit():\n                continue\n            selection = int(selection)\n        return int(selection)\n    \n\nclass MenuAction(ABC):\n    @abstractmethod\n    def execute(self):\n        pass\n\nclass AddResolutionAction(MenuAction):\n    def __init__(self, resolutions_manager : ResolutionsManager) -> None:\n        self.resolutions_manager = resolutions_manager\n\n    def execute(self):\n        goal = input(\"Proposito: \")\n\n        while True:\n            amount = input(\"Cantidad: \")\n            if not amount.isdigit():\n                print(\"Debes introducir un número\")\n                continue\n            amount = int(amount)\n            break\n\n        units = input(\"Unidad:\")\n        while True:\n            deadline = input(\"Plazo (meses): \")\n            if not deadline.isdigit():\n                print(\"Debes introducir un número\")\n                continue\n            deadline = int(deadline)\n            break\n\n        resolution = Resolution(goal, amount, units, deadline)\n\n        if resolutions_manager.add_resolution(resolution):\n            print(\"Proposito añadido correctamente.\")\n        else:\n            print(\"Ya has añadido el máximo de propositos.\")\n\nclass CalculatePlanAction(MenuAction):\n    def __init__(self, resolutions_manager : ResolutionsManager) -> None:\n        self.resolutions_manager = resolutions_manager\n\n    def execute(self):\n        print(self.resolutions_manager.generate_plan())\n\n\nclass SavePlanAction(MenuAction):\n    def __init__(self, resolutions_manager : ResolutionsManager) -> None:\n        self.resolutions_manager = resolutions_manager\n\n    def execute(self):\n        \n        plan = self.resolutions_manager.generate_plan()\n        with open('my_plan.txt', \"w\", encoding=\"utf-8\") as file:\n            file.write(plan)\n        print(\"Plan guardado en 'my_plan.txt\")\n\n\n\nclass ResolutionPlanner:\n    def __init__(self, ui_service: UIService, resolutions_manager: ResolutionsManager ) -> None:\n        self.ui_service = ui_service\n        self.resolutions_manager = resolutions_manager\n\n        self.menu_actions = {\n            1: AddResolutionAction(resolutions_manager),\n            2: CalculatePlanAction(resolutions_manager),\n            3: SavePlanAction(resolutions_manager)\n        }\n\n    def run(self):\n        while True:\n            selection = self.ui_service.display_menu()\n\n            if selection == 4:\n                break\n            \n            action = self.menu_actions.get(selection)\n            if action:\n                action.execute()\n            else:\n                print(\"Opción no valida.\")\n\nui_service = UIService()\nresolutions_manager = ResolutionsManager()\nresolution_planner = ResolutionPlanner(ui_service, resolutions_manager)\n\nresolution_planner.run()"
  },
  {
    "path": "Roadmap/50 - PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO/python/kenysdev.py",
    "content": "# _____________________________________\n# https://github.com/kenysdev\n# 2024 - Python\n# _____________________________________\n# #50 PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO\n# ------------------------------------\n\"\"\"\n* EJERCICIO:\n * El nuevo año está a punto de comenzar...\n * ¡Voy a ayudarte a planificar tus propósitos de nuevo año!\n *\n * Programa un gestor de objetivos con las siguientes características:\n * - Permite añadir objetivos (máximo 10)\n * - Calcular el plan detallado\n * - Guardar la planificación\n *\n * Cada entrada de un objetivo está formado por (con un ejemplo):\n * - Meta: Leer libros\n * - Cantidad: 12\n * - Unidades: libros\n * - Plazo (en meses): 12 (máximo 12)\n *\n * El cálculo del plan detallado generará la siguiente salida:\n * - Un apartado para cada mes\n * - Un listado de objetivos calculados a cumplir en cada mes\n *   (ejemplo: si quiero leer 12 libros, dará como resultado\n *   uno al mes)\n * - Cada objetivo debe poseer su nombre, la cantidad de\n *   unidades a completar en cada mes y su total. Por ejemplo:\n *\n *   Enero:\n *   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n *   [ ] 2. Estudiar Git (1 curso/mes). Total: 1.\n *   Febrero:\n *   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n *   ...\n *   Diciembre:\n *   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n *\n * - Si la duración es menor a un año, finalizará en el mes\n *   correspondiente.\n *\n * Por último, el cálculo detallado debe poder exportarse a .txt\n * (No subir el fichero)\n\"\"\"\n\nimport os\nfrom calendar import month_name as calendar_months\nfrom datetime import datetime\n\nclass ObjectivePlanner:\n    def __init__(self):\n        self.goals = []\n        self.months = list(calendar_months)[1:]\n        self.pending_monthly = {}\n        \n    def add(self):\n        if len(self.goals) >= 10:\n            print(\"\\nMáximo de 10 objetivos alcanzado.\")\n            return\n\n        try:\n            goal = {\n                'name': input(\"Meta: \").strip(),\n                'quantity': int(input(\"Cantidad: \")),\n                'units': input(\"Unidades: \").strip(),\n                'months': min(int(input(\"Plazo (en meses): \")), 12)\n            }\n            \n            if all(goal.values()):\n                goal_id = len(self.goals)\n                self.goals.append(goal)\n                monthly, extra = divmod(goal['quantity'], goal['months'])\n                self.pending_monthly[goal_id] = [monthly + (1 if m < extra else 0) \n                                               for m in range(goal['months'])]\n                print(\"\\nObjetivo añadido exitosamente.\")\n            else:\n                print(\"\\nDatos inválidos.\")\n                \n        except ValueError:\n            print(\"\\nError: Ingrese valores numéricos válidos.\")\n\n    def calculate_plan(self):\n        if not self.goals:\n            return None\n\n        plan = {}\n        for goal_id, goal in enumerate(self.goals):\n            monthly_quantities = self.pending_monthly[goal_id]\n            \n            for month, quantity in enumerate(monthly_quantities):\n                if quantity > 0:\n                    month_name = self.months[month]\n                    plan.setdefault(month_name, []).append(\n                        f\"[ ] {goal['name']} ({quantity} \"\n                        f\"{goal['units']}/mes). Total: {goal['quantity']}.\"\n                    )\n        \n        return {month: tasks for month, tasks in plan.items() if tasks}\n\n    def save_plan(self, plan):\n        if not plan:\n            print(\"\\nNo hay planificación para guardar.\")\n            return\n\n        filename = f\"plan_{datetime.now():%Y%m%d_%H%M}.txt\"\n        try:\n            with open(filename, \"w\", encoding=\"utf-8\") as f:\n                for month, tasks in plan.items():\n                    f.write(f\"{month}:\\n\")\n                    for task in tasks:\n                        f.write(f\"  {task}\\n\")\n                    \n                    f.write(\"\\n\")\n                    \n            print(f\"\\nPlan guardado en {filename}.\")\n            \n        except IOError:\n            print(\"\\nError al guardar el archivo.\")\n\n    def display_plan(self):\n        if plan := self.calculate_plan():\n            for month, tasks in plan.items():\n                print(f\"\\n{month}:\")\n                print('\\n'.join(f\"  {task}\" for task in tasks))\n\n    def run(self):\n        os.system(\"cls\" if os.name == \"nt\" else \"clear\")\n        menu = {\n            \"1\": lambda: self.add(),\n            \"2\": lambda: self.display_plan(),\n            \"3\": lambda: self.save_plan(self.calculate_plan()),\n            \"4\": lambda: exit(\"\\n¡Adiós!\")\n        }\n        \n        while True:\n            print(\"\\nGestor de Objetivos:\")\n            print(\"1. Añadir objetivo\")\n            print(\"2. Calcular plan detallado\")\n            print(\"3. Guardar planificación\")\n            print(\"4. Salir\")\n            \n            if action := menu.get(input(\"\\nSeleccione una opción: \").strip()):\n                action()\n            else:\n                print(\"\\nOpción inválida.\")\n\nif __name__ == \"__main__\":\n    ObjectivePlanner().run()\n"
  },
  {
    "path": "Roadmap/50 - PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO/python/mouredev.py",
    "content": "import os\n\nMONTHS = [\n    \"Enero\", \"Febrero\", \"Marzo\", \"Abril\", \"Mayo\", \"Junio\",\n    \"Julio\", \"Agosto\", \"Septiembre\", \"Octubre\", \"Noviembre\", \"Diciembre\"\n]\n\n\ndef show_menu():\n    print(\"\\nPlanificador de objetivos:\")\n    print(\"1. Añadir objetivo\")\n    print(\"2. Calcular el plan detallado\")\n    print(\"3. Guardar la planificación\")\n    print(\"4. Salir\")\n\n\nclass Goal:\n\n    def __init__(self, goal_name: str, amount: int, units: str, limit: int):\n        self.goal_name = goal_name\n        self.amount = amount\n        self.units = units\n        self.limit = limit\n\n\ndef request_goal() -> Goal:\n\n    goal_name = input(\"Meta: \")\n\n    while True:\n        try:\n            amount = int(input(\"Cantidad: \"))\n            if amount <= 0:\n                print(\"La cantidad debe ser un número positivo.\")\n                continue\n            break\n        except:\n            print(\"Por favor, introduce un número entero válido.\")\n\n    units = input(\"Unidades: \")\n\n    while True:\n        try:\n            limit = int(input(\"Plazo en meses (máximo 12): \"))\n            if limit <= 0 or limit > len(MONTHS):\n                print(\"El plazo debe ser un número entre 1 y 12 (meses).\")\n                continue\n            break\n        except:\n            print(\"Por favor, introduce un número entre 1 y 12 (meses).\")\n\n    return Goal(goal_name, amount, units, limit)\n\n\ndef calculate_detailed_plan(goals: list[Goal]) -> dict:\n\n    plan = {month: [] for month in range(1, len(MONTHS) + 1)}\n\n    for goal in goals:\n        month_amount = goal.amount / goal.limit\n\n        for month in range(1, goal.limit + 1):\n            plan[month].append(\n                Goal(goal.goal_name, round(month_amount, 2), goal.units, goal.amount))\n\n    return plan\n\n\ndef show_detailed_plan(plan: dict):\n\n    for month in range(1, len(MONTHS) + 1):\n\n        if not plan[month]:\n            # No hay objetivos en este mes\n            break\n\n        print(f\"\\n{MONTHS[month - 1]}: \")\n\n        for index, goal in enumerate(plan[month], start=1):\n            print(\n                f\"[ ] {index}. {goal.goal_name} ({\n                    goal.amount} {goal.units}/mes). Total: {goal.limit}.\")\n\n\ndef save_detailed_plan(plan: dict):\n\n    file_path = os.path.join(os.path.dirname(\n        os.path.abspath(__file__)), \"plan.txt\")\n\n    with open(file_path, \"w\", encoding=\"utf-8\") as file:\n        file.write(\"Plan detallado\\n\")\n\n        for month in range(1, len(MONTHS) + 1):\n\n            if not plan[month]:\n                # No hay objetivos en este mes\n                break\n\n            file.write(f\"\\n{MONTHS[month - 1]}:\\n\")\n\n            for index, goal in enumerate(plan[month], start=1):\n                file.write(\n                    f\"[ ] {index}. {goal.goal_name} ({\n                        goal.amount} {goal.units}/mes). Total: {goal.limit}.\\n\")\n\n    print(f\"Plan guardado con éxito en {file_path}\")\n\n\ngoals = []\n\nwhile True:\n\n    show_menu()\n\n    option = input(\"Elige una opción: \")\n\n    if option == \"1\":\n        if len(goals) >= 10:\n            print(\"Has alcanzado el número máximo de objetivos (10).\")\n        else:\n            goal = request_goal()\n            goals.append(goal)\n            print(\"Objetivo añadido con éxito.\")\n\n    elif option == \"2\":\n        if len(goals) == 0:\n            print(\"No hay objetivos añadidos.\")\n        else:\n            plan = calculate_detailed_plan(goals)\n            show_detailed_plan(plan)\n\n    elif option == \"3\":\n        if len(goals) == 0:\n            print(\"No hay objetivos para guardar.\")\n        else:\n            plan = calculate_detailed_plan(goals)\n            save_detailed_plan(plan)\n\n    elif option == \"4\":\n        print(\"Saliendo del planificador.\")\n        break\n    else:\n        print(\"Opción inválida. Elige una opción entre 1 y 4.\")\n"
  },
  {
    "path": "Roadmap/50 - PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO/python/neslarra.py",
    "content": "r\"\"\"\n EJERCICIO:\n El nuevo año está a punto de comenzar...\n ¡Voy a ayudarte a planificar tus propósitos de nuevo año!\n\n Programa un gestor de objetivos con las siguientes características:\n - Permite añadir objetivos (máximo 10)\n - Calcular el plan detallado\n - Guardar la planificación\n \n Cada entrada de un objetivo está formado por (con un ejemplo):\n - Meta: Leer libros\n - Cantidad: 12\n - Unidades: libros\n - Plazo (en meses): 12 (máximo 12)\n\n El cálculo del plan detallado generará la siguiente salida:\n - Un apartado para cada mes\n - Un listado de objetivos calculados a cumplir en cada mes\n   (ejemplo: si quiero leer 12 libros, dará como resultado \n   uno al mes)\n - Cada objetivo debe poseer su nombre, la cantidad de\n   unidades a completar en cada mes y su total. Por ejemplo:\n\n   Enero:\n   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n   [ ] 2. Estudiar Git (1 curso/mes). Total: 1.\n   Febrero:\n   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n   ...\n   Diciembre:\n   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n\n - Si la duración es menor a un año, finalizará en el mes\n   correspondiente.\n   \n Por último, el cálculo detallado debe poder exportarse a .txt\n (No subir el fichero)\n\"\"\"\n\n\nclass Target:\n    target_list = []\n\n    def __new__(cls, target: str, target_unit: str, amount: int = 1, period: int = 12):\n        if cls.number_of_targets() >= 10:\n            raise \"No se puede agregar más objetivos (10/10 máximo alcanzado).\"\n        if not (target and target_unit):\n            raise \"Debe indicar un objetivo específico y la unidad en la que se evaluará el avace.\"\n        if not (0 < period < 13):\n            raise \"El período debe estar entr 1 y 12 meses.\"\n        instance = super().__new__(cls)\n        cls.target_list.append(instance)\n        return instance\n\n    def __init__(self, target: str, target_unit: str, amount: int = 1, period: int = 12):\n        self.target = target\n        self.target_unit = target_unit\n        self.amount = amount\n        self.period = period\n\n    @classmethod\n    def number_of_targets(cls):\n        return cls.target_list.__len__()\n\n    def __str__(self):\n        return f\"Objetivo: {self.target}\\n\\tPeríodo: {self.period}\\n\\tCantidad: {self.amount}\\n\\tUnidades: {self.target_unit}\"\n\n    def get_target(self):\n        return self.target\n\n    def get_target_unit(self):\n        return self.target_unit\n\n    def get_amount(self):\n        return self.amount\n\n    def get_period(self):\n        return self.period\n\n\nclass TargetManager:\n    def __init__(self, target_list: list[Target]):\n        self.target_list = target_list\n\n    def show_monthy_targets(self):\n        months = {1: \"Enero\", 2: \"Febrero\", 3: \"Marzo\", 4: \"Abril\", 5: \"Mayo\", 6: \"Junio\",\n                  7: \"Julio\", 8: \"Agosto\", 9: \"Septiembre\", 10: \"Octubre\", 11: \"Noviembre\", 12: \"Diciembre\"}\n        print(\"\\nObjetivos para este año ----------------\")\n        for target in self.target_list:\n            print(f\"{target.__str__()}\")\n        for month in range(1, 13):\n            print(f\"\\nObjetivos {months[month]}\\n{'#' * 30}\")\n            for target in self.target_list:\n                monthly_activity = (target.get_amount() / target.get_period()).__round__(2)\n                if target.get_amount() <= target.get_period():\n                    if target.get_amount() >= month:\n                        print(f\"\\t{target.get_target()}: 1 {target.get_target_unit()}\")\n                        continue\n                if target.get_amount() > target.get_period():\n                    if month <= target.get_period():\n                        print(f\"\\t{target.get_target()}: {monthly_activity} {target.get_target_unit()}\")\n                        continue\n                if monthly_activity > 1 and target.get_period() >= month:\n                    print(f\"\\t{target.get_target()}: {monthly_activity} {target.get_target_unit()}\")\n\n\nobjetivo1 = Target(\"Leer\", \"libros\", 7, 12)\nobjetivo2 = Target(\"Ver\", \"videos\", 12, 12)\nobjetivo3 = Target(\"Escribir\", \"Artículos\", 17, 9)\n\ngestor = TargetManager(Target.target_list)\n\ngestor.show_monthy_targets()\n\nobjetivo4 = Target(\"Tomar\", \"Clases de tenis\", 24, 6)\n\ngestor.show_monthy_targets()\n"
  },
  {
    "path": "Roadmap/50 - PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO/python/santyjl.py",
    "content": "\"\"\"\n/*\n * EJERCICIO:\n * El nuevo año está a punto de comenzar...\n * ¡Voy a ayudarte a planificar tus propósitos de nuevo año!\n *\n * Programa un gestor de objetivos con las siguientes características:\n * - Permite añadir objetivos (máximo 10)\n * - Calcular el plan detallado\n * - Guardar la planificación\n *\n * Cada entrada de un objetivo está formado por (con un ejemplo):\n * - Meta: Leer libros\n * - Cantidad: 12\n * - Unidades: libros\n * - Plazo (en meses): 12 (máximo 12)\n *\n * El cálculo del plan detallado generará la siguiente salida:\n * - Un apartado para cada mes\n * - Un listado de objetivos calculados a cumplir en cada mes\n *   (ejemplo: si quiero leer 12 libros, dará como resultado\n *   uno al mes)\n * - Cada objetivo debe poseer su nombre, la cantidad de\n *   unidades a completar en cada mes y su total. Por ejemplo:\n *\n *   Enero:\n *   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n *   [ ] 2. Estudiar Git (1 curso/mes). Total: 1.\n *   Febrero:\n *   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n *   ...\n *   Diciembre:\n *   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n *\n * - Si la duración es menor a un año, finalizará en el mes\n *   correspondiente.\n *\n * Por último, el cálculo detallado debe poder exportarse a .txt\n * (No subir el fichero)\n */\n\"\"\"\nimport os\n\nMAX_OBJETIVOS: int = 10\nOBJETIVOS: list = []\nMESES_DEL_AÑO: list = [\n    'Enero', 'Febrero', 'Marzo', 'Abril',\n    'Mayo', 'Junio', 'Julio', 'Agosto',\n    'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'\n]\n\ndef crear_objetivo():\n    objetivo = {}\n    objetivo['meta'] = input('Introduce la meta: ')\n    objetivo['cantidad'] = int(input('Introduce la cantidad: '))\n    objetivo['unidades'] = input('Introduce las unidades: ')\n    objetivo['plazo'] = int(input('Introduce el plazo (en meses): '))\n    return objetivo\n\ndef objetivos_calculados(objetivo: dict) -> list:\n    cantidad_total = objetivo['cantidad']\n    plazo = objetivo['plazo']\n\n    cantidad_mensual = cantidad_total // plazo\n    resto = cantidad_total % plazo\n\n    cantidades = [cantidad_mensual] * plazo\n\n    for i in range(resto):\n        cantidades[i] += 1\n\n    return cantidades\n\ndef crear_txt(objetivos: list):\n    with open(\"objetivos_de_año_nuevo.txt\", \"w\") as fichero:\n        for objetivo in objetivos:\n            cantidades = objetivos_calculados(objetivo)\n            fichero.write(f\"Meta: {objetivo['meta']}\\n\")\n            fichero.write(f\"Cantidad total: {objetivo['cantidad']} {objetivo['unidades']}\\n\")\n            fichero.write(f\"Plazo: {objetivo['plazo']} meses\\n\")\n            fichero.write(\"Distribucion mensual:\\n\")\n            for i, cantidad in enumerate(cantidades):\n                fichero.write(f\"{MESES_DEL_AÑO[i]}: {cantidad} {objetivo['unidades']}\\n\")\n            fichero.write(\"\\n\")\n\ndef mostrar_objetivos():\n    for mes in MESES_DEL_AÑO:\n        print(f\"-----------{mes}-----------\")\n        for objetivo in OBJETIVOS:\n            cantidades = objetivos_calculados(objetivo)\n            for i in range(objetivo['plazo']):\n                if i < len(MESES_DEL_AÑO):\n                    if MESES_DEL_AÑO[i] == mes:\n                        print(f\"[ ] {objetivo['meta']} ({cantidades[i]} {objetivo['unidades']}/mes). Total: {objetivo['cantidad']}.\")\n\n# Ejemplo de uso\nwhile True:\n    opcion = input(\"Elige una opción:\\n0. Mostrar objetivos\\n1. Crear objetivo\\n2. Mostrar objetivos por mes\\n3. Exportar a txt\\n4. Salir\\nIntroduce el número de la opción: \")\n\n    if opcion == '0':\n        mostrar_objetivos()\n\n    elif opcion == '1':\n        if not len(OBJETIVOS) >= MAX_OBJETIVOS:\n            OBJETIVOS.append(crear_objetivo())\n        else:\n            print(\"Has alcanzado el límite de objetivos.\")\n\n    elif opcion == '2':\n        for mes in MESES_DEL_AÑO:\n            print(f\"-----------{mes}-----------\")\n            for objetivo in OBJETIVOS:\n                cantidades = objetivos_calculados(objetivo)\n                for i in range(objetivo['plazo']):\n                    if i < len(MESES_DEL_AÑO):\n                        if MESES_DEL_AÑO[i] == mes:\n                            print(f\"[ ] {objetivo['meta']} ({cantidades[i]} {objetivo['unidades']}/mes). Total: {objetivo['cantidad']}.\")\n\n    elif opcion == '3':\n        crear_txt(OBJETIVOS)\n\n    elif opcion == '4':\n        break"
  },
  {
    "path": "Roadmap/50 - PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO/rust/kenysdev.rs",
    "content": "/*\n_____________________________________\nhttps://github.com/kenysdev\n2024 - Rust\n__________________________________________\n#50 PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO\n------------------------------------------\n* EJERCICIO:\n * El nuevo año está a punto de comenzar...\n * ¡Voy a ayudarte a planificar tus propósitos de nuevo año!\n *\n * Programa un gestor de objetivos con las siguientes características:\n * - Permite añadir objetivos (máximo 10)\n * - Calcular el plan detallado\n * - Guardar la planificación\n * \n * Cada entrada de un objetivo está formado por (con un ejemplo):\n * - Meta: Leer libros\n * - Cantidad: 12\n * - Unidades: libros\n * - Plazo (en meses): 12 (máximo 12)\n *\n * El cálculo del plan detallado generará la siguiente salida:\n * - Un apartado para cada mes\n * - Un listado de objetivos calculados a cumplir en cada mes\n *   (ejemplo: si quiero leer 12 libros, dará como resultado \n *   uno al mes)\n * - Cada objetivo debe poseer su nombre, la cantidad de\n *   unidades a completar en cada mes y su total. Por ejemplo:\n *\n *   Enero:\n *   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n *   [ ] 2. Estudiar Git (1 curso/mes). Total: 1.\n *   Febrero:\n *   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n *   ...\n *   Diciembre:\n *   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n *\n * - Si la duración es menor a un año, finalizará en el mes\n *   correspondiente.\n *   \n * Por último, el cálculo detallado debe poder exportarse a .txt\n * (No subir el fichero)\n*/\n\nuse std::collections::HashMap;\nuse std::io::{self, Write};\nuse std::process::Command;\nuse chrono::Local;\nuse std::fs::File;\n\n#[derive(Debug)]\nstruct Goal {\n    name: String,\n    quantity: i32,\n    units: String,\n}\n\nstruct ObjectivePlanner {\n    goals: Vec<Goal>,\n    months: Vec<String>,\n    pending_monthly: HashMap<usize, Vec<i32>>,\n}\n\nimpl ObjectivePlanner {\n    fn new() -> Self {\n        let months = vec![\n            \"Enero\", \"Febrero\", \"Marzo\", \"Abril\", \"Mayo\", \"Junio\",\n            \"Julio\", \"Agosto\", \"Septiembre\", \"Octubre\", \"Noviembre\", \"Diciembre\"\n        ].iter().map(|&s| s.to_string()).collect();\n\n        ObjectivePlanner {\n            goals: Vec::new(),\n            months,\n            pending_monthly: HashMap::new(),\n        }\n    }\n\n    fn read_line(prompt: &str) -> String {\n        print!(\"{}\", prompt);\n        io::stdout().flush().unwrap();\n        let mut input = String::new();\n        io::stdin().read_line(&mut input).unwrap();\n        input.trim().to_string()\n    }\n\n    fn add(&mut self) -> io::Result<()> {\n        if self.goals.len() >= 10 {\n            println!(\"\\nMáximo de 10 objetivos alcanzado.\");\n            return Ok(());\n        }\n\n        println!(\"Ingrese los detalles del objetivo:\");\n        let name = Self::read_line(\"Meta: \");\n        \n        let quantity = match Self::read_line(\"Cantidad: \").parse::<i32>() {\n            Ok(n) if n > 0 => n,\n            _ => {\n                println!(\"\\nError: Ingrese una cantidad válida.\");\n                return Ok(());\n            }\n        };\n\n        let units = Self::read_line(\"Unidades: \");\n\n        let months = match Self::read_line(\"Plazo (en meses): \").parse::<i32>() {\n            Ok(n) if (1..=12).contains(&n) => n,\n            _ => {\n                println!(\"\\nError: Ingrese un plazo válido (1-12 meses).\");\n                return Ok(());\n            }\n        };\n\n        if !name.is_empty() && !units.is_empty() {\n            let goal = Goal {\n                name,\n                quantity,\n                units,\n            };\n\n            let goal_id = self.goals.len();\n            let monthly = quantity / months;\n            let extra = quantity % months;\n\n            let monthly_quantities: Vec<i32> = (0..months)\n                .map(|m| monthly + if m < extra { 1 } else { 0 })\n                .collect();\n\n            self.pending_monthly.insert(goal_id, monthly_quantities);\n            self.goals.push(goal);\n            println!(\"\\nObjetivo añadido exitosamente.\");\n        } else {\n            println!(\"\\nDatos inválidos.\");\n        }\n\n        Ok(())\n    }\n\n    fn calculate_plan(&self) -> Option<HashMap<String, Vec<String>>> {\n        if self.goals.is_empty() {\n            return None;\n        }\n\n        let mut plan: HashMap<String, Vec<String>> = HashMap::new();\n\n        for (goal_id, goal) in self.goals.iter().enumerate() {\n            if let Some(monthly_quantities) = self.pending_monthly.get(&goal_id) {\n                for (month, &quantity) in monthly_quantities.iter().enumerate() {\n                    if quantity > 0 {\n                        let month_name = &self.months[month];\n                        let task = format!(\n                            \"[ ] {} ({} {}/mes). Total: {}.\",\n                            goal.name, quantity, goal.units, goal.quantity\n                        );\n                        plan.entry(month_name.clone())\n                            .or_insert_with(Vec::new)\n                            .push(task);\n                    }\n                }\n            }\n        }\n\n        if plan.is_empty() {\n            None\n        } else {\n            Some(plan)\n        }\n    }\n\n    fn write_ordered_plan<W: Write>(&self, mut writer: W) -> io::Result<()> {\n        if let Some(plan) = self.calculate_plan() {\n            for month in &self.months {\n                if let Some(tasks) = plan.get(month) {\n                    writeln!(writer, \"{}:\", month)?;\n                    for task in tasks {\n                        writeln!(writer, \"  {}\", task)?;\n                    }\n                    writeln!(writer)?;\n                }\n            }\n        }\n        Ok(())\n    }\n\n    fn save_plan(&self) -> io::Result<()> {\n        if self.calculate_plan().is_none() {\n            println!(\"\\nNo hay planificación para guardar.\");\n            return Ok(());\n        }\n\n        let filename = format!(\n            \"plan_{}.txt\",\n            Local::now().format(\"%Y%m%d_%H%M\")\n        );\n\n        let file = File::create(&filename)?;\n        self.write_ordered_plan(file)?;\n        println!(\"\\nPlan guardado en {}.\", filename);\n        Ok(())\n    }\n\n    fn display_plan(&self) {\n        if self.calculate_plan().is_none() {\n            println!(\"\\nNo hay objetivos planificados.\");\n            return;\n        }\n\n        self.write_ordered_plan(io::stdout())\n            .expect(\"Error al mostrar el plan\");\n    }\n\n    fn clear_screen() {\n        if cfg!(target_os = \"windows\") {\n            Command::new(\"cmd\").args([\"/c\", \"cls\"]).status().unwrap();\n        } else {\n            Command::new(\"clear\").status().unwrap();\n        }\n    }\n\n    pub fn run(&mut self) -> io::Result<()> {\n        Self::clear_screen();\n\n        loop {\n            println!(\"\\nGestor de Objetivos:\");\n            println!(\"1. Añadir objetivo\");\n            println!(\"2. Calcular plan detallado\");\n            println!(\"3. Guardar planificación\");\n            println!(\"4. Salir\");\n\n            match Self::read_line(\"\\nSeleccione una opción: \").as_str() {\n                \"1\" => self.add()?,\n                \"2\" => self.display_plan(),\n                \"3\" => self.save_plan()?,\n                \"4\" => {\n                    println!(\"\\n¡Adiós!\");\n                    break;\n                }\n                _ => println!(\"\\nOpción inválida.\"),\n            }\n        }\n        Ok(())\n    }\n}\n\nfn main() -> io::Result<()> {\n    let mut planner = ObjectivePlanner::new();\n    planner.run()\n}\n"
  },
  {
    "path": "Roadmap/50 - PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO/sql/Nicojsuarez2.sql",
    "content": "# #50 PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO\n> #### Dificultad: Difícil | Publicación: 23/12/24 | Corrección: 30/12/24\n\n## Ejercicio\n\n```\n/*\n * EJERCICIO:\n * El nuevo año está a punto de comenzar...\n * ¡Voy a ayudarte a planificar tus propósitos de nuevo año!\n *\n * Programa un gestor de objetivos con las siguientes características:\n * - Permite añadir objetivos (máximo 10)\n * - Calcular el plan detallado\n * - Guardar la planificación\n * \n * Cada entrada de un objetivo está formado por (con un ejemplo):\n * - Meta: Leer libros\n * - Cantidad: 12\n * - Unidades: libros\n * - Plazo (en meses): 12 (máximo 12)\n *\n * El cálculo del plan detallado generará la siguiente salida:\n * - Un apartado para cada mes\n * - Un listado de objetivos calculados a cumplir en cada mes\n *   (ejemplo: si quiero leer 12 libros, dará como resultado \n *   uno al mes)\n * - Cada objetivo debe poseer su nombre, la cantidad de\n *   unidades a completar en cada mes y su total. Por ejemplo:\n *\n *   Enero:\n *   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n *   [ ] 2. Estudiar Git (1 curso/mes). Total: 1.\n *   Febrero:\n *   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n *   ...\n *   Diciembre:\n *   [ ] 1. Leer libros (1 libro/mes). Total: 12.\n *\n * - Si la duración es menor a un año, finalizará en el mes\n *   correspondiente.\n *   \n * Por último, el cálculo detallado debe poder exportarse a .txt\n * (No subir el fichero)\n */\n```\n#### Tienes toda la información extendida sobre el roadmap de retos de programación en **[retosdeprogramacion.com/roadmap](https://retosdeprogramacion.com/roadmap)**.\n\nSigue las **[instrucciones](../../README.md)**, consulta las correcciones y aporta la tuya propia utilizando el lenguaje de programación que quieras.\n\n> Recuerda que cada semana se publica un nuevo ejercicio y se corrige el de la semana anterior en directo desde **[Twitch](https://twitch.tv/mouredev)**. Tienes el horario en la sección \"eventos\" del servidor de **[Discord](https://discord.gg/mouredev)**.\n"
  },
  {
    "path": "Roadmap/50 - PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO/typescript/Rafacv23.ts",
    "content": "// Autor: Rafael Canosa, Github: https://github.com/rafacv23\n\n/* crear objetivo con los siguientes atributos:\n * meta\n * cantidad\n * unidades\n * plazo\n */\n\nlet objectives: Objective[] = []\n\nconst months = [\n  {\n    name: \"enero\",\n    value: 1,\n  },\n  {\n    name: \"febrero\",\n    value: 2,\n  },\n  {\n    name: \"marzo\",\n    value: 3,\n  },\n  {\n    name: \"abril\",\n    value: 4,\n  },\n  {\n    name: \"mayo\",\n    value: 5,\n  },\n  {\n    name: \"junio\",\n    value: 6,\n  },\n  {\n    name: \"julio\",\n    value: 7,\n  },\n  {\n    name: \"agosto\",\n    value: 8,\n  },\n  {\n    name: \"septiembre\",\n    value: 9,\n  },\n  {\n    name: \"octubre\",\n    value: 10,\n  },\n  {\n    name: \"noviembre\",\n    value: 11,\n  },\n  {\n    name: \"diciembre\",\n    value: 12,\n  },\n]\n\ninterface Objective {\n  meta: string\n  cantidad: number\n  unidades: string\n  plazo: number\n}\n\nclass Objective {\n  constructor(meta: string, cantidad: number, unidades: string, plazo: number) {\n    this.meta = meta\n    this.cantidad = cantidad\n    this.unidades = unidades\n    this.plazo = plazo\n\n    // comprobramos que el plazo no sea superior a 12\n    if (this.plazo > 12) {\n      console.log(\"❌ El plazo no puede ser superior a 12 meses.\")\n      return\n    }\n    // agregar objetivo a la lista\n    objectives.push(this)\n  }\n\n  // crear funcion que imprima el objetivo\n  show() {\n    console.log(`Objetivo: ${this.meta}`)\n    console.log(`Cantidad: ${this.cantidad}`)\n    console.log(`Unidades: ${this.unidades}`)\n    console.log(`Plazo: ${this.plazo}`)\n  }\n}\n\nfunction printObjectives() {\n  for (let i = 0; i < objectives.length; i++) {\n    console.log(`Objetivo ${i + 1}: ${objectives[i].meta}`)\n  }\n}\n\nfunction calculate() {\n  months.forEach((month) => {\n    // calculamos las tareas de cada mes\n    console.log(`📅 ${month.name}`)\n    objectives.forEach((objective) => {\n      const target = objective.cantidad / objective.plazo // calculamos el objetivo a lo largo de los 12 meses\n\n      if (objective.plazo >= month.value) {\n        console.log(\n          `${objective.meta} (${target} ${objective.unidades}/mes). Total: ${objective.cantidad}`\n        )\n      }\n    })\n  })\n}\n\nnew Objective(\"leer libros\", 12, \"libros\", 12)\nnew Objective(\"escribir artículos\", 12, \"artículos\", 6)\nnew Objective(\"escribir informes\", 24, \"informes\", 12)\nnew Objective(\"programar\", 24, \"programas\", 8)\n//new Objective(\"programar\", 24, \"informes\", 69)\n\nprintObjectives()\ncalculate()\n"
  },
  {
    "path": "Roadmap/50 - PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO/typescript/hozlucas28.ts",
    "content": "import type {UUID} from 'node:crypto'\nimport {randomUUID} from 'node:crypto'\nimport fs from 'node:fs/promises'\nimport readline from 'node:readline/promises'\n\n/* -------------------------------------------------------------------------- */\n/*                                    TYPES                                   */\n/* -------------------------------------------------------------------------- */\n\ninterface YearPlan {\n    january: [Goal, number][]\n    february: [Goal, number][]\n    march: [Goal, number][]\n    april: [Goal, number][]\n    may: [Goal, number][]\n    june: [Goal, number][]\n    july: [Goal, number][]\n    august: [Goal, number][]\n    september: [Goal, number][]\n    october: [Goal, number][]\n    november: [Goal, number][]\n    december: [Goal, number][]\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                   ERRORS                                   */\n/* -------------------------------------------------------------------------- */\n\nclass MonthsOutOfRange extends Error {\n    public constructor() {\n        super('Months out of range')\n        this.name = 'MonthsOutOfRange'\n    }\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                   CLASSES                                  */\n/* -------------------------------------------------------------------------- */\n\n/* ---------------------------------- Goal ---------------------------------- */\n\ninterface GoalConstructor {\n    amount: number\n    description: string\n    monthsLimit: number\n    units: string\n}\n\nclass Goal {\n    static maxMonthsLimit: number = 12\n\n    private readonly amount: number\n    private readonly description: string\n    private readonly id: UUID\n    private readonly monthsLimit: number\n    private readonly units: string\n\n    public constructor({amount, description, monthsLimit, units}: GoalConstructor) {\n        this.amount = amount\n        this.description = description\n        this.id = randomUUID()\n        this.units = units\n\n        if (monthsLimit < 1 || monthsLimit > Goal.maxMonthsLimit) throw new MonthsOutOfRange()\n\n        this.monthsLimit = monthsLimit\n    }\n\n    public getAmount(): number {\n        return this.amount\n    }\n\n    public getDescription(): string {\n        return this.description\n    }\n\n    public getId(): UUID {\n        return this.id\n    }\n\n    public getMonthsLimit(): number {\n        return this.monthsLimit\n    }\n\n    public getUnits(): string {\n        return this.units\n    }\n\n    public toYearPlan(): YearPlan {\n        const yearPlan: YearPlan = {\n            january: [],\n            february: [],\n            march: [],\n            april: [],\n            may: [],\n            june: [],\n            july: [],\n            august: [],\n            september: [],\n            october: [],\n            november: [],\n            december: [],\n        }\n\n        let counter: number = this.amount\n        while (counter) {\n            let monthCounter: number = this.monthsLimit\n            for (const key in yearPlan) {\n                if (!counter || !monthCounter) break\n\n                if ((yearPlan[key] as [Goal, number][])[0]) {\n                    ;(yearPlan[key] as [Goal, number][])[0][1]++\n                } else {\n                    ;(yearPlan[key] as [Goal, number][])[0] = [this, 1]\n                }\n\n                monthCounter--\n                counter--\n            }\n        }\n\n        return yearPlan\n    }\n}\n\n/* -------------------------------- YearGoals ------------------------------- */\n\nclass YearGoals {\n    static maxGoals: number = 10\n\n    private goals: Goal[]\n    private plan: YearPlan\n\n    public constructor() {\n        this.goals = []\n\n        this.plan = {\n            january: [],\n            february: [],\n            march: [],\n            april: [],\n            may: [],\n            june: [],\n            july: [],\n            august: [],\n            september: [],\n            october: [],\n            november: [],\n            december: [],\n        }\n    }\n\n    public getGoals(): Goal[] {\n        return this.goals\n    }\n\n    public getPlan(): YearPlan {\n        return this.plan\n    }\n\n    private appendGoalToPlan(goal: Goal): void {\n        const goalYearPlan: YearPlan = goal.toYearPlan()\n\n        for (const key in goalYearPlan) {\n            ;(this.plan[key] as [Goal, number][]).push(...(goalYearPlan[key] as [Goal, number][]))\n        }\n    }\n\n    private removeGoalFromPlan(id: UUID): void {\n        for (const key in this.plan) {\n            const goalI: number = this.plan[key].findIndex(([goal]: [Goal, number]) => goal.getId() === id)\n            if (goalI === -1) break\n\n            this.plan[key].splice(goalI, 1)\n        }\n    }\n\n    public addGoal(newGoal: Goal): boolean {\n        if (this.goals.length === YearGoals.maxGoals) return false\n        const newGoalID: UUID = newGoal.getId()\n\n        const goalI: number = this.goals.findIndex((goal) => goal.getId() === newGoalID)\n        if (goalI !== -1) return false\n\n        this.goals.push(newGoal)\n        this.appendGoalToPlan(newGoal)\n\n        return true\n    }\n\n    public removeGoal(id: UUID): boolean {\n        const goalI: number = this.goals.findIndex((goal) => goal.getId() === id)\n        if (goalI === -1) return false\n\n        this.goals.splice(goalI, 1)\n        this.removeGoalFromPlan(id)\n\n        return true\n    }\n\n    public async savePlan(\n        path: `${string}.txt`,\n        goalToRow: (goal: Goal, amount: number, index: number) => string,\n        monthTitle: (key: string) => string = (month) => `${month[0].toUpperCase()}${month.slice(1)}:`\n    ): Promise<void> {\n        const data: string[] = []\n\n        for (const key in this.plan) {\n            const goalsMonth: [Goal, number][] = this.plan[key]\n\n            const rows: string[] = [monthTitle(key)]\n            for (let i = 0; i < goalsMonth.length; i++) {\n                const [goal, amount] = goalsMonth[i]\n                rows.push(goalToRow(goal, amount, i))\n            }\n\n            data.push(rows.join('\\n'), '\\n\\n')\n        }\n\n        await fs.writeFile(path, data, {encoding: 'utf-8'})\n    }\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    MAIN                                    */\n/* -------------------------------------------------------------------------- */\n\n;(async () => {\n    const yearGoals: YearGoals = new YearGoals()\n\n    const rl: readline.Interface = readline.createInterface({\n        input: process.stdin,\n        output: process.stdout,\n    })\n\n    console.log(\n        '> Available operations:\\n\\n' +\n            ' 1 - Add goal.\\n' +\n            ' 2 - Remove goal.\\n' +\n            ' 3 - Show goals.\\n' +\n            ' 4 - Show plan.\\n' +\n            ' 5 - Save plan.\\n' +\n            ' 0 - Exit.'\n    )\n\n    let input: string = (await rl.question('\\n> Select an operation: ')).trim()\n\n    while (input !== '0') {\n        switch (input) {\n            case '1':\n                console.log('\\n> Complete the following goal data...')\n                const units: string = (await rl.question('\\n> Units: ')).trim()\n                const amount: number = parseInt((await rl.question('\\n> Amount (as a number): ')).trim())\n                const description: string = (await rl.question('\\n> Description: ')).trim()\n\n                let monthsLimit: number = parseInt((await rl.question('\\n> Months limit (as a number): ')).trim())\n                while (monthsLimit < 1 || monthsLimit > Goal.maxMonthsLimit) {\n                    console.log('\\n> Error! Months limit must be between 1 and 12 (both included). Try again...')\n                    monthsLimit = parseInt((await rl.question('\\n> Months limit (as a number): ')).trim())\n                }\n\n                const goal: Goal = new Goal({amount, description, monthsLimit, units})\n\n                yearGoals.addGoal(goal)\n                    ? console.log('\\n> Goal added!')\n                    : console.log('\\n> An error occurred! The goal was not added.')\n                break\n\n            case '2':\n                const goalId: UUID = (await rl.question('\\n> Goal id to remove: ')).trim() as UUID\n\n                yearGoals.removeGoal(goalId)\n                    ? console.log(`\\n> Goal \"${goalId}\" removed!`)\n                    : console.log('\\n> An error occurred! The goal was not removed.')\n                break\n\n            case '3':\n                const goals: Goal[] = yearGoals.getGoals()\n\n                const goalsRows: string[] = []\n                for (const goal of goals) {\n                    goalsRows.push(\n                        `\\n• Goal \"${goal.getId()}\"...` +\n                            `\\n\\n  - ID: \"${goal.getId()}\".` +\n                            `\\n  - Description: \\\"${goal.getDescription()}\\\".` +\n                            `\\n  - Months limit: ${goal.getMonthsLimit()}.` +\n                            `\\n  - Amount: ${goal.getAmount()}.` +\n                            `\\n  - Units: \"${goal.getUnits()}\".`\n                    )\n                }\n\n                goalsRows.length && console.log(goalsRows.join('\\n'))\n                break\n\n            case '4':\n                const plan: YearPlan = yearGoals.getPlan()\n\n                const planRows: string[] = []\n                for (const key in plan) {\n                    const goals: [Goal, number][] = plan[key]\n\n                    let planRow: string = `\\n${key[0].toUpperCase()}${key.slice(1)}:`\n                    for (let i = 0; i < goals.length; i++) {\n                        const [goal, amount] = goals[i]\n                        const desc: string = goal.getDescription()\n                        const units: string = goal.getUnits()\n                        const totalAmount: number = goal.getAmount()\n                        planRow += `\\n[ ] ${i + 1}. ${desc} (${amount} ${units}/mes). Total: ${totalAmount}.`\n                    }\n\n                    planRows.push(planRow)\n                }\n\n                planRows.length && console.log(planRows.join('\\n'))\n                break\n\n            case '5':\n                const currentDate: Date = new Date()\n                const savePlanPath = `${process.cwd()}\\\\plan-${currentDate.getFullYear()}.txt` as const\n                await yearGoals.savePlan(savePlanPath, (goal, amount, index) => {\n                    const desc: string = goal.getDescription()\n                    const units: string = goal.getUnits()\n                    const totalAmount: number = goal.getAmount()\n                    return `[ ] ${index + 1}. ${desc} (${amount} ${units}/mes). Total: ${totalAmount}.`\n                })\n\n                console.log(`\\n> Plan saved in \"${savePlanPath}\" path.`)\n                break\n\n            default:\n                console.log('\\n> Invalid operation! Try again...')\n                break\n        }\n\n        console.log(\n            '\\n> Available operations:\\n\\n' +\n                ' 1 - Add goal.\\n' +\n                ' 2 - Remove goal.\\n' +\n                ' 3 - Show goals.\\n' +\n                ' 4 - Show plan.\\n' +\n                ' 5 - Save plan.\\n' +\n                ' 0 - Exit.'\n        )\n\n        input = (await rl.question('\\n> Select an operation: ')).trim()\n    }\n\n    rl.close()\n})()\n"
  },
  {
    "path": "Roadmap/50 - PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO/vb.net/kenysdev.vb",
    "content": "' _____________________________________\n' https://github.com/kenysdev\n' 2024 - vb.net\n' _____________________________________\n' 50 PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO\n' ------------------------------------\n'* EJERCICIO\n' * El nuevo año está a punto de comenzar...\n' * ¡Voy a ayudarte a planificar tus propósitos de nuevo año!\n' *\n' * Programa un gestor de objetivos con las siguientes características:\n' * - Permite añadir objetivos (máximo 10)\n' * - Calcular el plan detallado\n' * - Guardar la planificación\n' * \n' * Cada entrada de un objetivo está formado por (con un ejemplo):\n' * - Meta: Leer libros\n' * - Cantidad: 12\n' * - Unidades: libros\n' * - Plazo (en meses): 12 (máximo 12)\n' *\n' * El cálculo del plan detallado generará la siguiente salida:\n' * - Un apartado para cada mes\n' * - Un listado de objetivos calculados a cumplir en cada mes\n' *   (ejemplo: si quiero leer 12 libros, dará como resultado \n' *   uno al mes)\n' * - Cada objetivo debe poseer su nombre, la cantidad de\n' *   unidades a completar en cada mes y su total. Por ejemplo:\n' *\n' *   Enero:\n' *   [ ] 1. Leer libros (1 libro/mes). Total 12.\n' *   [ ] 2. Estudiar Git (1 curso/mes). Total: 1.\n' *   Febrero:\n' *   [ ] 1. Leer libros (1 libro/mes). Total 12.\n' *   ...\n' *   Diciembre:\n' *   [ ] 1. Leer libros (1 libro/mes). Total 12.\n' *\n' * - Si la duración es menor a un año, finalizará en el mes\n' *   correspondiente.\n' *   \n' * Por último, el cálculo detallado debe poder exportarse a .txt\n' * (No subir el fichero)\n\nImports System\nImports System.IO\nImports System.Collections.Generic\nImports System.Globalization\n\nPublic Class ObjectivePlanner\n    Private ReadOnly goals As New List(Of Dictionary(Of String, Object))\n    Private ReadOnly months As List(Of String)\n    Private ReadOnly pendingMonthly As New Dictionary(Of Integer, List(Of Integer))\n\n    Public Sub New()\n        months = Enumerable.Range(1, 12).[Select](Function(m) DateTimeFormatInfo.CurrentInfo.GetMonthName(m)).ToList()\n        goals = New List(Of Dictionary(Of String, Object))\n        pendingMonthly = New Dictionary(Of Integer, List(Of Integer))\n    End Sub\n\n    Private Sub Add()\n        If goals.Count >= 10 Then\n            Console.WriteLine(vbLf & \"Máximo de 10 objetivos alcanzado.\")\n            Return\n        End If\n\n        Try\n            Console.Write(\"Meta: \")\n            Dim name As String = Console.ReadLine().Trim()\n\n            Console.Write(\"Cantidad: \")\n            Dim quantity As Integer = Integer.Parse(Console.ReadLine())\n\n            Console.Write(\"Unidades: \")\n            Dim units As String = Console.ReadLine().Trim()\n\n            Console.Write(\"Plazo (en meses): \")\n            Dim monthCount As Integer = Math.Min(Integer.Parse(Console.ReadLine()), 12)\n\n            If Not String.IsNullOrEmpty(name) AndAlso quantity > 0 AndAlso\n               Not String.IsNullOrEmpty(units) AndAlso monthCount > 0 Then\n\n                Dim goal As New Dictionary(Of String, Object) From {\n                    {\"name\", name},\n                    {\"quantity\", quantity},\n                    {\"units\", units},\n                    {\"months\", monthCount}\n                }\n\n                Dim goalId As Integer = goals.Count\n                goals.Add(goal)\n\n                Dim monthly As Integer = quantity \\ monthCount\n                Dim extra As Integer = quantity Mod monthCount\n\n                pendingMonthly(goalId) = Enumerable.Range(0, monthCount).[Select](\n                    Function(m) monthly + If(m < extra, 1, 0)).ToList()\n\n                Console.WriteLine(vbLf & \"Objetivo añadido exitosamente.\")\n            Else\n                Console.WriteLine(vbLf & \"Datos inválidos.\")\n            End If\n\n        Catch ex As FormatException\n            Console.WriteLine(vbLf & \"Error: Ingrese valores numéricos válidos.\")\n        End Try\n    End Sub\n\n    Private Function CalculatePlan() As Dictionary(Of String, List(Of String))\n        If goals.Count = 0 Then Return Nothing\n\n        Dim plan As New Dictionary(Of String, List(Of String))\n\n        For goalId As Integer = 0 To goals.Count - 1\n            Dim goal As Dictionary(Of String, Object) = goals(goalId)\n            Dim monthlyQuantities As List(Of Integer) = pendingMonthly(goalId)\n\n            For month As Integer = 0 To monthlyQuantities.Count - 1\n                Dim quantity As Integer = monthlyQuantities(month)\n                If quantity > 0 Then\n                    Dim monthName As String = months(month)\n\n                    Dim value As List(Of String) = Nothing\n\n                    If Not plan.TryGetValue(monthName, value) Then\n                        value = New List(Of String)\n                        plan(monthName) = value\n                    End If\n\n                    value.Add(\n                        $\"[ ] {goal(\"name\")} ({quantity} {goal(\"units\")}/mes). \" &\n                        $\"Total: {goal(\"quantity\")}.\")\n                End If\n            Next\n        Next\n\n        Return plan.Where(Function(kvp) kvp.Value.Count > 0).\n               ToDictionary(Function(kvp) kvp.Key, Function(kvp) kvp.Value)\n    End Function\n\n    Private Shared Sub SavePlan(plan As Dictionary(Of String, List(Of String)))\n        If plan Is Nothing Then\n            Console.WriteLine(vbLf & \"No hay planificación para guardar.\")\n            Return\n        End If\n\n        Dim filename As String = $\"plan_{DateTime.Now:yyyyMMdd_HHmm}.txt\"\n        Try\n            Using writer As New StreamWriter(filename, False, Text.Encoding.UTF8)\n                For Each kvp In plan\n                    writer.WriteLine($\"{kvp.Key}:\")\n                    For Each task In kvp.Value\n                        writer.WriteLine($\"  {task}\")\n                    Next\n                    writer.WriteLine()\n                Next\n            End Using\n\n            Console.WriteLine(vbLf & $\"Plan guardado en {filename}.\")\n\n        Catch ex As IOException\n            Console.WriteLine(vbLf & \"Error al guardar el archivo.\")\n        End Try\n    End Sub\n\n    Private Sub DisplayPlan()\n        Dim plan As Dictionary(Of String, List(Of String)) = CalculatePlan()\n        If plan IsNot Nothing Then\n            For Each kvp In plan\n                Console.WriteLine(vbLf & $\"{kvp.Key}:\")\n                For Each task In kvp.Value\n                    Console.WriteLine($\"  {task}\")\n                Next\n            Next\n        End If\n    End Sub\n\n    Public Sub Run()\n        Console.Clear()\n\n        While True\n            Console.WriteLine(vbLf & \"Gestor de Objetivos:\")\n            Console.WriteLine(\"1. Añadir objetivo\")\n            Console.WriteLine(\"2. Calcular plan detallado\")\n            Console.WriteLine(\"3. Guardar planificación\")\n            Console.WriteLine(\"4. Salir\")\n\n            Console.Write(vbLf & \"Seleccione una opción: \")\n            Dim option_ As String = Console.ReadLine().Trim()\n\n            Select Case option_\n                Case \"1\"\n                    Add()\n                Case \"2\"\n                    DisplayPlan()\n                Case \"3\"\n                    SavePlan(CalculatePlan())\n                Case \"4\"\n                    Console.WriteLine(vbLf & \"¡Adiós!\")\n                    Return\n                Case Else\n                    Console.WriteLine(vbLf & \"Opción inválida.\")\n            End Select\n        End While\n    End Sub\nEnd Class\n\nPublic Module Program\n    Public Sub Main()\n        Dim planner As New ObjectivePlanner()\n        planner.Run()\n    End Sub\nEnd Module\n"
  },
  {
    "path": "Roadmap/stats.json",
    "content": "{\n    \"challenges_total\": 51,\n    \"languages_total\": 54,\n    \"files_total\": 11246,\n    \"users_total\": 1852,\n    \"challenges_ranking\": [\n        {\n            \"order\": 1,\n            \"name\": \"00 - SINTAXIS, VARIABLES, TIPOS DE DATOS Y HOLA MUNDO\",\n            \"count\": 1989\n        },\n        {\n            \"order\": 2,\n            \"name\": \"01 - OPERADORES Y ESTRUCTURAS DE CONTROL\",\n            \"count\": 1177\n        },\n        {\n            \"order\": 3,\n            \"name\": \"02 - FUNCIONES Y ALCANCE\",\n            \"count\": 873\n        },\n        {\n            \"order\": 4,\n            \"name\": \"03 - ESTRUCTURAS DE DATOS\",\n            \"count\": 629\n        },\n        {\n            \"order\": 5,\n            \"name\": \"04 - CADENAS DE CARACTERES\",\n            \"count\": 510\n        },\n        {\n            \"order\": 6,\n            \"name\": \"06 - RECURSIVIDAD\",\n            \"count\": 453\n        },\n        {\n            \"order\": 7,\n            \"name\": \"05 - VALOR Y REFERENCIA\",\n            \"count\": 432\n        },\n        {\n            \"order\": 8,\n            \"name\": \"07 - PILAS Y COLAS\",\n            \"count\": 349\n        },\n        {\n            \"order\": 9,\n            \"name\": \"08 - CLASES\",\n            \"count\": 320\n        },\n        {\n            \"order\": 10,\n            \"name\": \"09 - HERENCIA\",\n            \"count\": 306\n        },\n        {\n            \"order\": 11,\n            \"name\": \"10 - EXCEPCIONES\",\n            \"count\": 265\n        },\n        {\n            \"order\": 12,\n            \"name\": \"11 - MANEJO DE FICHEROS\",\n            \"count\": 229\n        },\n        {\n            \"order\": 13,\n            \"name\": \"12 - JSON Y XML\",\n            \"count\": 191\n        },\n        {\n            \"order\": 14,\n            \"name\": \"14 - FECHAS\",\n            \"count\": 182\n        },\n        {\n            \"order\": 15,\n            \"name\": \"13 - PRUEBAS UNITARIAS\",\n            \"count\": 180\n        },\n        {\n            \"order\": 16,\n            \"name\": \"16 - EXPRESIONES REGULARES\",\n            \"count\": 178\n        },\n        {\n            \"order\": 17,\n            \"name\": \"15 - ASINCRON\\u00cdA\",\n            \"count\": 173\n        },\n        {\n            \"order\": 18,\n            \"name\": \"17 - ITERACIONES\",\n            \"count\": 166\n        },\n        {\n            \"order\": 19,\n            \"name\": \"18 - CONJUNTOS\",\n            \"count\": 163\n        },\n        {\n            \"order\": 20,\n            \"name\": \"19 - ENUMERACIONES\",\n            \"count\": 148\n        },\n        {\n            \"order\": 21,\n            \"name\": \"20 - PETICIONES HTTP\",\n            \"count\": 145\n        },\n        {\n            \"order\": 22,\n            \"name\": \"21 - CALLBACKS\",\n            \"count\": 127\n        },\n        {\n            \"order\": 23,\n            \"name\": \"22 - FUNCIONES DE ORDEN SUPERIOR\",\n            \"count\": 122\n        },\n        {\n            \"order\": 24,\n            \"name\": \"23 - SINGLETON\",\n            \"count\": 121\n        },\n        {\n            \"order\": 25,\n            \"name\": \"24 - DECORADORES\",\n            \"count\": 111\n        },\n        {\n            \"order\": 26,\n            \"name\": \"25 - LOGS\",\n            \"count\": 104\n        },\n        {\n            \"order\": 27,\n            \"name\": \"26 - SOLID SRP\",\n            \"count\": 102\n        },\n        {\n            \"order\": 28,\n            \"name\": \"27 - SOLID OCP\",\n            \"count\": 99\n        },\n        {\n            \"order\": 29,\n            \"name\": \"28 - SOLID LSP\",\n            \"count\": 92\n        },\n        {\n            \"order\": 30,\n            \"name\": \"29 - SOLID ISP\",\n            \"count\": 90\n        },\n        {\n            \"order\": 31,\n            \"name\": \"31 - SIMULADOR JUEGOS OL\\u00cdMPICOS\",\n            \"count\": 89\n        },\n        {\n            \"order\": 32,\n            \"name\": \"30 - SOLID DIP\",\n            \"count\": 85\n        },\n        {\n            \"order\": 33,\n            \"name\": \"32 - BATALLA DEADPOOL Y WOLVERINE\",\n            \"count\": 85\n        },\n        {\n            \"order\": 34,\n            \"name\": \"33 - RESCATANDO A MICKEY\",\n            \"count\": 75\n        },\n        {\n            \"order\": 35,\n            \"name\": \"36 - EL SOMBRERO SELECCIONADOR\",\n            \"count\": 68\n        },\n        {\n            \"order\": 36,\n            \"name\": \"35 - REPARTIENDO LOS ANILLOS DE PODER\",\n            \"count\": 68\n        },\n        {\n            \"order\": 37,\n            \"name\": \"38 - MOUREDEV PRO\",\n            \"count\": 66\n        },\n        {\n            \"order\": 38,\n            \"name\": \"34 - \\u00c1RBOL GENEAL\\u00d3GICO LA CASA DEL DRAG\\u00d3N\",\n            \"count\": 63\n        },\n        {\n            \"order\": 39,\n            \"name\": \"37 - OASIS VS LINKIN PARK\",\n            \"count\": 60\n        },\n        {\n            \"order\": 40,\n            \"name\": \"42 - TORNEO DRAGON BALL\",\n            \"count\": 59\n        },\n        {\n            \"order\": 41,\n            \"name\": \"41 - CAMISETA RAR\",\n            \"count\": 57\n        },\n        {\n            \"order\": 42,\n            \"name\": \"39 - BATMAN DAY\",\n            \"count\": 49\n        },\n        {\n            \"order\": 43,\n            \"name\": \"49 - EL ALMAC\\u00c9N DE PAP\\u00c1 NOEL\",\n            \"count\": 49\n        },\n        {\n            \"order\": 44,\n            \"name\": \"48 - \\u00c1RBOL DE NAVIDAD\",\n            \"count\": 48\n        },\n        {\n            \"order\": 45,\n            \"name\": \"47 - CALENDARIO DE ADVIENTO\",\n            \"count\": 48\n        },\n        {\n            \"order\": 46,\n            \"name\": \"46 - X VS BLUESKY\",\n            \"count\": 45\n        },\n        {\n            \"order\": 47,\n            \"name\": \"40 - FORTNITE RUBIUS CUP\",\n            \"count\": 45\n        },\n        {\n            \"order\": 48,\n            \"name\": \"43 - GIT GITHUB CLI\",\n            \"count\": 44\n        },\n        {\n            \"order\": 49,\n            \"name\": \"45 - GITHUB OCTOVERSE\",\n            \"count\": 44\n        },\n        {\n            \"order\": 50,\n            \"name\": \"44 - CUENTA ATR\\u00c1S MOUREDEV PRO\",\n            \"count\": 39\n        },\n        {\n            \"order\": 51,\n            \"name\": \"50 - PLANIFICADOR DE OBJETIVOS DE A\\u00d1O NUEVO\",\n            \"count\": 34\n        }\n    ],\n    \"languages_ranking\": [\n        {\n            \"order\": 1,\n            \"name\": \"python\",\n            \"count\": 4961,\n            \"percentage\": 44.11\n        },\n        {\n            \"order\": 2,\n            \"name\": \"javascript\",\n            \"count\": 2264,\n            \"percentage\": 20.13\n        },\n        {\n            \"order\": 3,\n            \"name\": \"java\",\n            \"count\": 1122,\n            \"percentage\": 9.98\n        },\n        {\n            \"order\": 4,\n            \"name\": \"typescript\",\n            \"count\": 567,\n            \"percentage\": 5.04\n        },\n        {\n            \"order\": 5,\n            \"name\": \"c#\",\n            \"count\": 389,\n            \"percentage\": 3.46\n        },\n        {\n            \"order\": 6,\n            \"name\": \"go\",\n            \"count\": 283,\n            \"percentage\": 2.52\n        },\n        {\n            \"order\": 7,\n            \"name\": \"kotlin\",\n            \"count\": 261,\n            \"percentage\": 2.32\n        },\n        {\n            \"order\": 8,\n            \"name\": \"php\",\n            \"count\": 235,\n            \"percentage\": 2.09\n        },\n        {\n            \"order\": 9,\n            \"name\": \"c++\",\n            \"count\": 196,\n            \"percentage\": 1.74\n        },\n        {\n            \"order\": 10,\n            \"name\": \"swift\",\n            \"count\": 186,\n            \"percentage\": 1.65\n        },\n        {\n            \"order\": 11,\n            \"name\": \"rust\",\n            \"count\": 132,\n            \"percentage\": 1.17\n        },\n        {\n            \"order\": 12,\n            \"name\": \"c\",\n            \"count\": 95,\n            \"percentage\": 0.84\n        },\n        {\n            \"order\": 13,\n            \"name\": \"dart\",\n            \"count\": 81,\n            \"percentage\": 0.72\n        },\n        {\n            \"order\": 14,\n            \"name\": \"sql\",\n            \"count\": 71,\n            \"percentage\": 0.63\n        },\n        {\n            \"order\": 15,\n            \"name\": \"bash\",\n            \"count\": 65,\n            \"percentage\": 0.58\n        },\n        {\n            \"order\": 16,\n            \"name\": \"vb.net\",\n            \"count\": 53,\n            \"percentage\": 0.47\n        },\n        {\n            \"order\": 17,\n            \"name\": \"ruby\",\n            \"count\": 40,\n            \"percentage\": 0.36\n        },\n        {\n            \"order\": 18,\n            \"name\": \"ocaml\",\n            \"count\": 35,\n            \"percentage\": 0.31\n        },\n        {\n            \"order\": 19,\n            \"name\": \"lua\",\n            \"count\": 31,\n            \"percentage\": 0.28\n        },\n        {\n            \"order\": 20,\n            \"name\": \"pascal\",\n            \"count\": 20,\n            \"percentage\": 0.18\n        },\n        {\n            \"order\": 21,\n            \"name\": \"scala\",\n            \"count\": 14,\n            \"percentage\": 0.12\n        },\n        {\n            \"order\": 22,\n            \"name\": \"cobol\",\n            \"count\": 14,\n            \"percentage\": 0.12\n        },\n        {\n            \"order\": 23,\n            \"name\": \"fortran\",\n            \"count\": 13,\n            \"percentage\": 0.12\n        },\n        {\n            \"order\": 24,\n            \"name\": \"r\",\n            \"count\": 12,\n            \"percentage\": 0.11\n        },\n        {\n            \"order\": 25,\n            \"name\": \"arduino\",\n            \"count\": 12,\n            \"percentage\": 0.11\n        },\n        {\n            \"order\": 26,\n            \"name\": \"nasm\",\n            \"count\": 11,\n            \"percentage\": 0.1\n        },\n        {\n            \"order\": 27,\n            \"name\": \"julia\",\n            \"count\": 11,\n            \"percentage\": 0.1\n        },\n        {\n            \"order\": 28,\n            \"name\": \"delphi\",\n            \"count\": 9,\n            \"percentage\": 0.08\n        },\n        {\n            \"order\": 29,\n            \"name\": \"elixir\",\n            \"count\": 9,\n            \"percentage\": 0.08\n        },\n        {\n            \"order\": 30,\n            \"name\": \"haskell\",\n            \"count\": 6,\n            \"percentage\": 0.05\n        },\n        {\n            \"order\": 31,\n            \"name\": \"erlang\",\n            \"count\": 5,\n            \"percentage\": 0.04\n        },\n        {\n            \"order\": 32,\n            \"name\": \"mql4\",\n            \"count\": 4,\n            \"percentage\": 0.04\n        },\n        {\n            \"order\": 33,\n            \"name\": \"gdscript\",\n            \"count\": 4,\n            \"percentage\": 0.04\n        },\n        {\n            \"order\": 34,\n            \"name\": \"mojo\",\n            \"count\": 3,\n            \"percentage\": 0.03\n        },\n        {\n            \"order\": 35,\n            \"name\": \"prolog\",\n            \"count\": 3,\n            \"percentage\": 0.03\n        },\n        {\n            \"order\": 36,\n            \"name\": \"d\",\n            \"count\": 3,\n            \"percentage\": 0.03\n        },\n        {\n            \"order\": 37,\n            \"name\": \"ada\",\n            \"count\": 3,\n            \"percentage\": 0.03\n        },\n        {\n            \"order\": 38,\n            \"name\": \"racket\",\n            \"count\": 3,\n            \"percentage\": 0.03\n        },\n        {\n            \"order\": 39,\n            \"name\": \"solidity\",\n            \"count\": 2,\n            \"percentage\": 0.02\n        },\n        {\n            \"order\": 40,\n            \"name\": \"raku\",\n            \"count\": 2,\n            \"percentage\": 0.02\n        },\n        {\n            \"order\": 41,\n            \"name\": \"zig\",\n            \"count\": 2,\n            \"percentage\": 0.02\n        },\n        {\n            \"order\": 42,\n            \"name\": \"tcl\",\n            \"count\": 2,\n            \"percentage\": 0.02\n        },\n        {\n            \"order\": 43,\n            \"name\": \"clojure\",\n            \"count\": 1,\n            \"percentage\": 0.01\n        },\n        {\n            \"order\": 44,\n            \"name\": \"harbour\",\n            \"count\": 1,\n            \"percentage\": 0.01\n        },\n        {\n            \"order\": 45,\n            \"name\": \"perl\",\n            \"count\": 1,\n            \"percentage\": 0.01\n        },\n        {\n            \"order\": 46,\n            \"name\": \"gleam\",\n            \"count\": 1,\n            \"percentage\": 0.01\n        },\n        {\n            \"order\": 47,\n            \"name\": \"abap\",\n            \"count\": 1,\n            \"percentage\": 0.01\n        },\n        {\n            \"order\": 48,\n            \"name\": \"lisp\",\n            \"count\": 1,\n            \"percentage\": 0.01\n        },\n        {\n            \"order\": 49,\n            \"name\": \"elm\",\n            \"count\": 1,\n            \"percentage\": 0.01\n        },\n        {\n            \"order\": 50,\n            \"name\": \"objectivec\",\n            \"count\": 1,\n            \"percentage\": 0.01\n        },\n        {\n            \"order\": 51,\n            \"name\": \"f#\",\n            \"count\": 1,\n            \"percentage\": 0.01\n        },\n        {\n            \"order\": 52,\n            \"name\": \"al\",\n            \"count\": 1,\n            \"percentage\": 0.01\n        },\n        {\n            \"order\": 53,\n            \"name\": \"maxmsp\",\n            \"count\": 1,\n            \"percentage\": 0.01\n        },\n        {\n            \"order\": 54,\n            \"name\": \"32 - batalla deadpool y wolverine\",\n            \"count\": 1,\n            \"percentage\": 0.01\n        }\n    ],\n    \"users_ranking\": [\n        {\n            \"order\": 1,\n            \"name\": \"kenysdev\",\n            \"count\": 255,\n            \"languages\": 5\n        },\n        {\n            \"order\": 2,\n            \"name\": \"miguelex\",\n            \"count\": 221,\n            \"languages\": 15\n        },\n        {\n            \"order\": 3,\n            \"name\": \"eulogioep\",\n            \"count\": 153,\n            \"languages\": 8\n        },\n        {\n            \"order\": 4,\n            \"name\": \"hectorio23\",\n            \"count\": 153,\n            \"languages\": 3\n        },\n        {\n            \"order\": 5,\n            \"name\": \"hozlucas28\",\n            \"count\": 141,\n            \"languages\": 3\n        },\n        {\n            \"order\": 6,\n            \"name\": \"duendeintemporal\",\n            \"count\": 133,\n            \"languages\": 3\n        },\n        {\n            \"order\": 7,\n            \"name\": \"nicojsuarez2\",\n            \"count\": 102,\n            \"languages\": 2\n        },\n        {\n            \"order\": 8,\n            \"name\": \"sac-corts\",\n            \"count\": 92,\n            \"languages\": 3\n        },\n        {\n            \"order\": 9,\n            \"name\": \"qwik-zgheib\",\n            \"count\": 83,\n            \"languages\": 4\n        },\n        {\n            \"order\": 10,\n            \"name\": \"blackriper\",\n            \"count\": 82,\n            \"languages\": 2\n        },\n        {\n            \"order\": 11,\n            \"name\": \"nlarrea\",\n            \"count\": 80,\n            \"languages\": 3\n        },\n        {\n            \"order\": 12,\n            \"name\": \"kodenook\",\n            \"count\": 77,\n            \"languages\": 9\n        },\n        {\n            \"order\": 13,\n            \"name\": \"edalmava\",\n            \"count\": 75,\n            \"languages\": 25\n        },\n        {\n            \"order\": 14,\n            \"name\": \"jesusantonioeescamilla\",\n            \"count\": 73,\n            \"languages\": 3\n        },\n        {\n            \"order\": 15,\n            \"name\": \"achapeton\",\n            \"count\": 72,\n            \"languages\": 3\n        },\n        {\n            \"order\": 16,\n            \"name\": \"agusrosero\",\n            \"count\": 65,\n            \"languages\": 6\n        },\n        {\n            \"order\": 17,\n            \"name\": \"jesusway69\",\n            \"count\": 64,\n            \"languages\": 3\n        },\n        {\n            \"order\": 18,\n            \"name\": \"cesar-ch\",\n            \"count\": 63,\n            \"languages\": 6\n        },\n        {\n            \"order\": 19,\n            \"name\": \"rantamhack\",\n            \"count\": 63,\n            \"languages\": 3\n        },\n        {\n            \"order\": 20,\n            \"name\": \"raynerpv2022\",\n            \"count\": 62,\n            \"languages\": 2\n        },\n        {\n            \"order\": 21,\n            \"name\": \"raulg91\",\n            \"count\": 60,\n            \"languages\": 2\n        },\n        {\n            \"order\": 22,\n            \"name\": \"santyjl\",\n            \"count\": 59,\n            \"languages\": 4\n        },\n        {\n            \"order\": 23,\n            \"name\": \"juanppdev\",\n            \"count\": 59,\n            \"languages\": 3\n        },\n        {\n            \"order\": 24,\n            \"name\": \"victor-casta\",\n            \"count\": 56,\n            \"languages\": 3\n        },\n        {\n            \"order\": 25,\n            \"name\": \"cesarcarmona30\",\n            \"count\": 54,\n            \"languages\": 4\n        },\n        {\n            \"order\": 26,\n            \"name\": \"amadorquispe\",\n            \"count\": 54,\n            \"languages\": 2\n        },\n        {\n            \"order\": 27,\n            \"name\": \"idiegorojas\",\n            \"count\": 53,\n            \"languages\": 2\n        },\n        {\n            \"order\": 28,\n            \"name\": \"neslarra\",\n            \"count\": 52,\n            \"languages\": 2\n        },\n        {\n            \"order\": 29,\n            \"name\": \"ricjdev\",\n            \"count\": 52,\n            \"languages\": 2\n        },\n        {\n            \"order\": 30,\n            \"name\": \"gordo-master\",\n            \"count\": 51,\n            \"languages\": 1\n        },\n        {\n            \"order\": 31,\n            \"name\": \"ignaciovihe\",\n            \"count\": 51,\n            \"languages\": 1\n        },\n        {\n            \"order\": 32,\n            \"name\": \"davidrguez98\",\n            \"count\": 51,\n            \"languages\": 1\n        },\n        {\n            \"order\": 33,\n            \"name\": \"mouredev\",\n            \"count\": 51,\n            \"languages\": 1\n        },\n        {\n            \"order\": 34,\n            \"name\": \"asjordi\",\n            \"count\": 51,\n            \"languages\": 1\n        },\n        {\n            \"order\": 35,\n            \"name\": \"josegs95\",\n            \"count\": 51,\n            \"languages\": 1\n        },\n        {\n            \"order\": 36,\n            \"name\": \"rauldoezon\",\n            \"count\": 51,\n            \"languages\": 1\n        },\n        {\n            \"order\": 37,\n            \"name\": \"rigo93acosta\",\n            \"count\": 49,\n            \"languages\": 1\n        },\n        {\n            \"order\": 38,\n            \"name\": \"mhayhem\",\n            \"count\": 48,\n            \"languages\": 1\n        },\n        {\n            \"order\": 39,\n            \"name\": \"hequebo\",\n            \"count\": 48,\n            \"languages\": 1\n        },\n        {\n            \"order\": 40,\n            \"name\": \"adrs1166ma\",\n            \"count\": 47,\n            \"languages\": 4\n        },\n        {\n            \"order\": 41,\n            \"name\": \"martinbohorquez\",\n            \"count\": 47,\n            \"languages\": 3\n        },\n        {\n            \"order\": 42,\n            \"name\": \"pyramsd\",\n            \"count\": 46,\n            \"languages\": 1\n        },\n        {\n            \"order\": 43,\n            \"name\": \"pedamoci\",\n            \"count\": 46,\n            \"languages\": 1\n        },\n        {\n            \"order\": 44,\n            \"name\": \"emmanuelmmontesinos\",\n            \"count\": 45,\n            \"languages\": 1\n        },\n        {\n            \"order\": 45,\n            \"name\": \"garos01\",\n            \"count\": 44,\n            \"languages\": 2\n        },\n        {\n            \"order\": 46,\n            \"name\": \"oriaj3\",\n            \"count\": 43,\n            \"languages\": 1\n        },\n        {\n            \"order\": 47,\n            \"name\": \"aldroide\",\n            \"count\": 42,\n            \"languages\": 4\n        },\n        {\n            \"order\": 48,\n            \"name\": \"soohav\",\n            \"count\": 42,\n            \"languages\": 1\n        },\n        {\n            \"order\": 49,\n            \"name\": \"chrisdev00\",\n            \"count\": 41,\n            \"languages\": 2\n        },\n        {\n            \"order\": 50,\n            \"name\": \"didacdev\",\n            \"count\": 40,\n            \"languages\": 5\n        },\n        {\n            \"order\": 51,\n            \"name\": \"gabrielmoris\",\n            \"count\": 40,\n            \"languages\": 3\n        },\n        {\n            \"order\": 52,\n            \"name\": \"alexdevrep\",\n            \"count\": 38,\n            \"languages\": 3\n        },\n        {\n            \"order\": 53,\n            \"name\": \"fborjalv\",\n            \"count\": 38,\n            \"languages\": 1\n        },\n        {\n            \"order\": 54,\n            \"name\": \"qv1ko\",\n            \"count\": 37,\n            \"languages\": 4\n        },\n        {\n            \"order\": 55,\n            \"name\": \"luishendrix92\",\n            \"count\": 37,\n            \"languages\": 2\n        },\n        {\n            \"order\": 56,\n            \"name\": \"juanmax2\",\n            \"count\": 37,\n            \"languages\": 1\n        },\n        {\n            \"order\": 57,\n            \"name\": \"adra-dev\",\n            \"count\": 37,\n            \"languages\": 1\n        },\n        {\n            \"order\": 58,\n            \"name\": \"n0hagonada\",\n            \"count\": 36,\n            \"languages\": 3\n        },\n        {\n            \"order\": 59,\n            \"name\": \"avcenal\",\n            \"count\": 36,\n            \"languages\": 1\n        },\n        {\n            \"order\": 60,\n            \"name\": \"h4ckxel\",\n            \"count\": 35,\n            \"languages\": 5\n        },\n        {\n            \"order\": 61,\n            \"name\": \"angelsanchezt\",\n            \"count\": 34,\n            \"languages\": 12\n        },\n        {\n            \"order\": 62,\n            \"name\": \"rikmij\",\n            \"count\": 34,\n            \"languages\": 2\n        },\n        {\n            \"order\": 63,\n            \"name\": \"mrodara\",\n            \"count\": 34,\n            \"languages\": 1\n        },\n        {\n            \"order\": 64,\n            \"name\": \"pedroomar23\",\n            \"count\": 33,\n            \"languages\": 3\n        },\n        {\n            \"order\": 65,\n            \"name\": \"zetared92\",\n            \"count\": 33,\n            \"languages\": 3\n        },\n        {\n            \"order\": 66,\n            \"name\": \"caverobrandon\",\n            \"count\": 33,\n            \"languages\": 2\n        },\n        {\n            \"order\": 67,\n            \"name\": \"jheisonquiroga\",\n            \"count\": 33,\n            \"languages\": 2\n        },\n        {\n            \"order\": 68,\n            \"name\": \"worlion\",\n            \"count\": 33,\n            \"languages\": 2\n        },\n        {\n            \"order\": 69,\n            \"name\": \"alanshakir\",\n            \"count\": 33,\n            \"languages\": 1\n        },\n        {\n            \"order\": 70,\n            \"name\": \"cristianfloyd\",\n            \"count\": 33,\n            \"languages\": 1\n        },\n        {\n            \"order\": 71,\n            \"name\": \"danhingar\",\n            \"count\": 33,\n            \"languages\": 1\n        },\n        {\n            \"order\": 72,\n            \"name\": \"caterinarodriguezdev\",\n            \"count\": 33,\n            \"languages\": 1\n        },\n        {\n            \"order\": 73,\n            \"name\": \"juandaherrera\",\n            \"count\": 32,\n            \"languages\": 5\n        },\n        {\n            \"order\": 74,\n            \"name\": \"davidmoralesdeveloper\",\n            \"count\": 32,\n            \"languages\": 1\n        },\n        {\n            \"order\": 75,\n            \"name\": \"ronipg\",\n            \"count\": 31,\n            \"languages\": 4\n        },\n        {\n            \"order\": 76,\n            \"name\": \"jhoshmc\",\n            \"count\": 31,\n            \"languages\": 3\n        },\n        {\n            \"order\": 77,\n            \"name\": \"juserdev\",\n            \"count\": 31,\n            \"languages\": 3\n        },\n        {\n            \"order\": 78,\n            \"name\": \"simonguzman\",\n            \"count\": 31,\n            \"languages\": 1\n        },\n        {\n            \"order\": 79,\n            \"name\": \"parababire\",\n            \"count\": 31,\n            \"languages\": 1\n        },\n        {\n            \"order\": 80,\n            \"name\": \"marcode24\",\n            \"count\": 30,\n            \"languages\": 3\n        },\n        {\n            \"order\": 81,\n            \"name\": \"analaudb\",\n            \"count\": 30,\n            \"languages\": 1\n        },\n        {\n            \"order\": 82,\n            \"name\": \"any7dev\",\n            \"count\": 29,\n            \"languages\": 2\n        },\n        {\n            \"order\": 83,\n            \"name\": \"isaacus98\",\n            \"count\": 28,\n            \"languages\": 4\n        },\n        {\n            \"order\": 84,\n            \"name\": \"allbertomd\",\n            \"count\": 28,\n            \"languages\": 2\n        },\n        {\n            \"order\": 85,\n            \"name\": \"bernatcs\",\n            \"count\": 28,\n            \"languages\": 2\n        },\n        {\n            \"order\": 86,\n            \"name\": \"frandev200\",\n            \"count\": 28,\n            \"languages\": 1\n        },\n        {\n            \"order\": 87,\n            \"name\": \"mariovelascodev\",\n            \"count\": 27,\n            \"languages\": 3\n        },\n        {\n            \"order\": 88,\n            \"name\": \"gallitofast\",\n            \"count\": 27,\n            \"languages\": 3\n        },\n        {\n            \"order\": 89,\n            \"name\": \"thegera4\",\n            \"count\": 27,\n            \"languages\": 2\n        },\n        {\n            \"order\": 90,\n            \"name\": \"isilanes\",\n            \"count\": 27,\n            \"languages\": 1\n        },\n        {\n            \"order\": 91,\n            \"name\": \"lucasrebuffo\",\n            \"count\": 27,\n            \"languages\": 1\n        },\n        {\n            \"order\": 92,\n            \"name\": \"nightblockchain30\",\n            \"count\": 26,\n            \"languages\": 2\n        },\n        {\n            \"order\": 93,\n            \"name\": \"ggilperez\",\n            \"count\": 26,\n            \"languages\": 1\n        },\n        {\n            \"order\": 94,\n            \"name\": \"irenetitor\",\n            \"count\": 26,\n            \"languages\": 1\n        },\n        {\n            \"order\": 95,\n            \"name\": \"jimsimrodev\",\n            \"count\": 26,\n            \"languages\": 1\n        },\n        {\n            \"order\": 96,\n            \"name\": \"monicavaquerano\",\n            \"count\": 25,\n            \"languages\": 2\n        },\n        {\n            \"order\": 97,\n            \"name\": \"juandaw37\",\n            \"count\": 25,\n            \"languages\": 1\n        },\n        {\n            \"order\": 98,\n            \"name\": \"fedeairala\",\n            \"count\": 24,\n            \"languages\": 1\n        },\n        {\n            \"order\": 99,\n            \"name\": \"victoriaparraf\",\n            \"count\": 24,\n            \"languages\": 1\n        },\n        {\n            \"order\": 100,\n            \"name\": \"jamerrq\",\n            \"count\": 24,\n            \"languages\": 1\n        },\n        {\n            \"order\": 101,\n            \"name\": \"deyvid-10\",\n            \"count\": 24,\n            \"languages\": 1\n        },\n        {\n            \"order\": 102,\n            \"name\": \"ycanas\",\n            \"count\": 23,\n            \"languages\": 2\n        },\n        {\n            \"order\": 103,\n            \"name\": \"miguelp-dev\",\n            \"count\": 23,\n            \"languages\": 2\n        },\n        {\n            \"order\": 104,\n            \"name\": \"christian-jfr\",\n            \"count\": 23,\n            \"languages\": 1\n        },\n        {\n            \"order\": 105,\n            \"name\": \"7r0n1x\",\n            \"count\": 23,\n            \"languages\": 1\n        },\n        {\n            \"order\": 106,\n            \"name\": \"fabianrpv\",\n            \"count\": 22,\n            \"languages\": 2\n        },\n        {\n            \"order\": 107,\n            \"name\": \"danielhdzr\",\n            \"count\": 22,\n            \"languages\": 1\n        },\n        {\n            \"order\": 108,\n            \"name\": \"jptxaya\",\n            \"count\": 22,\n            \"languages\": 1\n        },\n        {\n            \"order\": 109,\n            \"name\": \"emedevelopa\",\n            \"count\": 22,\n            \"languages\": 1\n        },\n        {\n            \"order\": 110,\n            \"name\": \"hyromy\",\n            \"count\": 22,\n            \"languages\": 1\n        },\n        {\n            \"order\": 111,\n            \"name\": \"mohamedelderkaoui\",\n            \"count\": 21,\n            \"languages\": 2\n        },\n        {\n            \"order\": 112,\n            \"name\": \"complex303\",\n            \"count\": 21,\n            \"languages\": 2\n        },\n        {\n            \"order\": 113,\n            \"name\": \"giovanyosorio\",\n            \"count\": 21,\n            \"languages\": 2\n        },\n        {\n            \"order\": 114,\n            \"name\": \"gringoam\",\n            \"count\": 21,\n            \"languages\": 1\n        },\n        {\n            \"order\": 115,\n            \"name\": \"restevean\",\n            \"count\": 21,\n            \"languages\": 1\n        },\n        {\n            \"order\": 116,\n            \"name\": \"mvidalb\",\n            \"count\": 21,\n            \"languages\": 1\n        },\n        {\n            \"order\": 117,\n            \"name\": \"igledev\",\n            \"count\": 21,\n            \"languages\": 1\n        },\n        {\n            \"order\": 118,\n            \"name\": \"fravelz\",\n            \"count\": 20,\n            \"languages\": 3\n        },\n        {\n            \"order\": 119,\n            \"name\": \"victorfer69\",\n            \"count\": 20,\n            \"languages\": 1\n        },\n        {\n            \"order\": 120,\n            \"name\": \"wapastorv\",\n            \"count\": 20,\n            \"languages\": 1\n        },\n        {\n            \"order\": 121,\n            \"name\": \"chartypes\",\n            \"count\": 19,\n            \"languages\": 2\n        },\n        {\n            \"order\": 122,\n            \"name\": \"trufoplus\",\n            \"count\": 19,\n            \"languages\": 1\n        },\n        {\n            \"order\": 123,\n            \"name\": \"barrancus\",\n            \"count\": 19,\n            \"languages\": 1\n        },\n        {\n            \"order\": 124,\n            \"name\": \"sorubadguy\",\n            \"count\": 19,\n            \"languages\": 1\n        },\n        {\n            \"order\": 125,\n            \"name\": \"yenneralayon142\",\n            \"count\": 19,\n            \"languages\": 1\n        },\n        {\n            \"order\": 126,\n            \"name\": \"saezmd\",\n            \"count\": 19,\n            \"languages\": 1\n        },\n        {\n            \"order\": 127,\n            \"name\": \"daniqb99\",\n            \"count\": 19,\n            \"languages\": 1\n        },\n        {\n            \"order\": 128,\n            \"name\": \"pguillo02\",\n            \"count\": 18,\n            \"languages\": 5\n        },\n        {\n            \"order\": 129,\n            \"name\": \"estuardodev\",\n            \"count\": 18,\n            \"languages\": 4\n        },\n        {\n            \"order\": 130,\n            \"name\": \"franxiscodev\",\n            \"count\": 18,\n            \"languages\": 1\n        },\n        {\n            \"order\": 131,\n            \"name\": \"lumanet\",\n            \"count\": 18,\n            \"languages\": 1\n        },\n        {\n            \"order\": 132,\n            \"name\": \"mikelm2020\",\n            \"count\": 18,\n            \"languages\": 1\n        },\n        {\n            \"order\": 133,\n            \"name\": \"juanchernandezdev\",\n            \"count\": 18,\n            \"languages\": 1\n        },\n        {\n            \"order\": 134,\n            \"name\": \"mensius87\",\n            \"count\": 17,\n            \"languages\": 4\n        },\n        {\n            \"order\": 135,\n            \"name\": \"kuroz00\",\n            \"count\": 17,\n            \"languages\": 4\n        },\n        {\n            \"order\": 136,\n            \"name\": \"kevined11\",\n            \"count\": 17,\n            \"languages\": 3\n        },\n        {\n            \"order\": 137,\n            \"name\": \"saicobys\",\n            \"count\": 17,\n            \"languages\": 2\n        },\n        {\n            \"order\": 138,\n            \"name\": \"raulfauli\",\n            \"count\": 17,\n            \"languages\": 2\n        },\n        {\n            \"order\": 139,\n            \"name\": \"javierfiestasbotella\",\n            \"count\": 17,\n            \"languages\": 1\n        },\n        {\n            \"order\": 140,\n            \"name\": \"andreavzqz\",\n            \"count\": 17,\n            \"languages\": 1\n        },\n        {\n            \"order\": 141,\n            \"name\": \"glitzypanic\",\n            \"count\": 17,\n            \"languages\": 1\n        },\n        {\n            \"order\": 142,\n            \"name\": \"sniker1223\",\n            \"count\": 16,\n            \"languages\": 4\n        },\n        {\n            \"order\": 143,\n            \"name\": \"pakiuh\",\n            \"count\": 16,\n            \"languages\": 4\n        },\n        {\n            \"order\": 144,\n            \"name\": \"jesuses1312\",\n            \"count\": 16,\n            \"languages\": 3\n        },\n        {\n            \"order\": 145,\n            \"name\": \"rxvlc\",\n            \"count\": 16,\n            \"languages\": 3\n        },\n        {\n            \"order\": 146,\n            \"name\": \"sergiogi99\",\n            \"count\": 16,\n            \"languages\": 2\n        },\n        {\n            \"order\": 147,\n            \"name\": \"davstudy\",\n            \"count\": 16,\n            \"languages\": 2\n        },\n        {\n            \"order\": 148,\n            \"name\": \"tofedev\",\n            \"count\": 16,\n            \"languages\": 2\n        },\n        {\n            \"order\": 149,\n            \"name\": \"andrewcodev\",\n            \"count\": 16,\n            \"languages\": 2\n        },\n        {\n            \"order\": 150,\n            \"name\": \"adolfolozaa\",\n            \"count\": 16,\n            \"languages\": 1\n        },\n        {\n            \"order\": 151,\n            \"name\": \"oniricoh\",\n            \"count\": 16,\n            \"languages\": 1\n        },\n        {\n            \"order\": 152,\n            \"name\": \"kontroldev\",\n            \"count\": 16,\n            \"languages\": 1\n        },\n        {\n            \"order\": 153,\n            \"name\": \"artickun\",\n            \"count\": 16,\n            \"languages\": 1\n        },\n        {\n            \"order\": 154,\n            \"name\": \"eugeniasoria\",\n            \"count\": 15,\n            \"languages\": 2\n        },\n        {\n            \"order\": 155,\n            \"name\": \"rianojnicolas\",\n            \"count\": 15,\n            \"languages\": 2\n        },\n        {\n            \"order\": 156,\n            \"name\": \"alvaro-neyra\",\n            \"count\": 15,\n            \"languages\": 2\n        },\n        {\n            \"order\": 157,\n            \"name\": \"ceciliarava1\",\n            \"count\": 15,\n            \"languages\": 2\n        },\n        {\n            \"order\": 158,\n            \"name\": \"rafacv23\",\n            \"count\": 15,\n            \"languages\": 2\n        },\n        {\n            \"order\": 159,\n            \"name\": \"elmer125\",\n            \"count\": 15,\n            \"languages\": 1\n        },\n        {\n            \"order\": 160,\n            \"name\": \"jesusgdev\",\n            \"count\": 15,\n            \"languages\": 1\n        },\n        {\n            \"order\": 161,\n            \"name\": \"jafeito\",\n            \"count\": 15,\n            \"languages\": 1\n        },\n        {\n            \"order\": 162,\n            \"name\": \"dkp-dev\",\n            \"count\": 15,\n            \"languages\": 1\n        },\n        {\n            \"order\": 163,\n            \"name\": \"david-git-dev\",\n            \"count\": 15,\n            \"languages\": 1\n        },\n        {\n            \"order\": 164,\n            \"name\": \"seandsun\",\n            \"count\": 15,\n            \"languages\": 1\n        },\n        {\n            \"order\": 165,\n            \"name\": \"sisaroot\",\n            \"count\": 14,\n            \"languages\": 14\n        },\n        {\n            \"order\": 166,\n            \"name\": \"redom69\",\n            \"count\": 14,\n            \"languages\": 4\n        },\n        {\n            \"order\": 167,\n            \"name\": \"nightalchemist\",\n            \"count\": 14,\n            \"languages\": 3\n        },\n        {\n            \"order\": 168,\n            \"name\": \"bert008\",\n            \"count\": 14,\n            \"languages\": 3\n        },\n        {\n            \"order\": 169,\n            \"name\": \"d3rk1us\",\n            \"count\": 14,\n            \"languages\": 2\n        },\n        {\n            \"order\": 170,\n            \"name\": \"andresgcastillo\",\n            \"count\": 14,\n            \"languages\": 2\n        },\n        {\n            \"order\": 171,\n            \"name\": \"ygriegasb\",\n            \"count\": 14,\n            \"languages\": 2\n        },\n        {\n            \"order\": 172,\n            \"name\": \"inmortalnight\",\n            \"count\": 14,\n            \"languages\": 2\n        },\n        {\n            \"order\": 173,\n            \"name\": \"ericjoel-code\",\n            \"count\": 14,\n            \"languages\": 2\n        },\n        {\n            \"order\": 174,\n            \"name\": \"gonzadev28\",\n            \"count\": 14,\n            \"languages\": 2\n        },\n        {\n            \"order\": 175,\n            \"name\": \"deathwing696\",\n            \"count\": 14,\n            \"languages\": 2\n        },\n        {\n            \"order\": 176,\n            \"name\": \"cdryampi\",\n            \"count\": 14,\n            \"languages\": 1\n        },\n        {\n            \"order\": 177,\n            \"name\": \"paula2409\",\n            \"count\": 14,\n            \"languages\": 1\n        },\n        {\n            \"order\": 178,\n            \"name\": \"vincentrodriguezr\",\n            \"count\": 14,\n            \"languages\": 1\n        },\n        {\n            \"order\": 179,\n            \"name\": \"diegoibb\",\n            \"count\": 13,\n            \"languages\": 3\n        },\n        {\n            \"order\": 180,\n            \"name\": \"volumidev\",\n            \"count\": 13,\n            \"languages\": 3\n        },\n        {\n            \"order\": 181,\n            \"name\": \"djsurgeon\",\n            \"count\": 13,\n            \"languages\": 3\n        },\n        {\n            \"order\": 182,\n            \"name\": \"manjaitan\",\n            \"count\": 13,\n            \"languages\": 2\n        },\n        {\n            \"order\": 183,\n            \"name\": \"devcherry1\",\n            \"count\": 13,\n            \"languages\": 2\n        },\n        {\n            \"order\": 184,\n            \"name\": \"a-mayans\",\n            \"count\": 13,\n            \"languages\": 2\n        },\n        {\n            \"order\": 185,\n            \"name\": \"d1d4cum\",\n            \"count\": 13,\n            \"languages\": 2\n        },\n        {\n            \"order\": 186,\n            \"name\": \"neosv\",\n            \"count\": 13,\n            \"languages\": 1\n        },\n        {\n            \"order\": 187,\n            \"name\": \"tito-delpino\",\n            \"count\": 13,\n            \"languages\": 1\n        },\n        {\n            \"order\": 188,\n            \"name\": \"jav-mol\",\n            \"count\": 13,\n            \"languages\": 1\n        },\n        {\n            \"order\": 189,\n            \"name\": \"tomu98\",\n            \"count\": 13,\n            \"languages\": 1\n        },\n        {\n            \"order\": 190,\n            \"name\": \"rayn1er\",\n            \"count\": 13,\n            \"languages\": 1\n        },\n        {\n            \"order\": 191,\n            \"name\": \"c-gabs\",\n            \"count\": 13,\n            \"languages\": 1\n        },\n        {\n            \"order\": 192,\n            \"name\": \"santiagobailleres\",\n            \"count\": 13,\n            \"languages\": 1\n        },\n        {\n            \"order\": 193,\n            \"name\": \"paprikaistkrieg\",\n            \"count\": 13,\n            \"languages\": 1\n        },\n        {\n            \"order\": 194,\n            \"name\": \"rodrigogit87\",\n            \"count\": 13,\n            \"languages\": 1\n        },\n        {\n            \"order\": 195,\n            \"name\": \"julian98789\",\n            \"count\": 13,\n            \"languages\": 1\n        },\n        {\n            \"order\": 196,\n            \"name\": \"freyfonseca117\",\n            \"count\": 13,\n            \"languages\": 1\n        },\n        {\n            \"order\": 197,\n            \"name\": \"airesesteban\",\n            \"count\": 13,\n            \"languages\": 1\n        },\n        {\n            \"order\": 198,\n            \"name\": \"ocram1304\",\n            \"count\": 13,\n            \"languages\": 1\n        },\n        {\n            \"order\": 199,\n            \"name\": \"dan-corbo\",\n            \"count\": 13,\n            \"languages\": 1\n        },\n        {\n            \"order\": 200,\n            \"name\": \"m-doce\",\n            \"count\": 12,\n            \"languages\": 3\n        },\n        {\n            \"order\": 201,\n            \"name\": \"juanrcoder\",\n            \"count\": 12,\n            \"languages\": 2\n        },\n        {\n            \"order\": 202,\n            \"name\": \"andresmcardenas\",\n            \"count\": 12,\n            \"languages\": 2\n        },\n        {\n            \"order\": 203,\n            \"name\": \"keltoi-dev\",\n            \"count\": 12,\n            \"languages\": 2\n        },\n        {\n            \"order\": 204,\n            \"name\": \"bluefeatherdev\",\n            \"count\": 12,\n            \"languages\": 2\n        },\n        {\n            \"order\": 205,\n            \"name\": \"pipe281\",\n            \"count\": 12,\n            \"languages\": 1\n        },\n        {\n            \"order\": 206,\n            \"name\": \"haroldalb\",\n            \"count\": 12,\n            \"languages\": 1\n        },\n        {\n            \"order\": 207,\n            \"name\": \"nicoheguaburu\",\n            \"count\": 12,\n            \"languages\": 1\n        },\n        {\n            \"order\": 208,\n            \"name\": \"dataciriano\",\n            \"count\": 12,\n            \"languages\": 1\n        },\n        {\n            \"order\": 209,\n            \"name\": \"javierjoyera\",\n            \"count\": 12,\n            \"languages\": 1\n        },\n        {\n            \"order\": 210,\n            \"name\": \"briansilvero\",\n            \"count\": 12,\n            \"languages\": 1\n        },\n        {\n            \"order\": 211,\n            \"name\": \"josealberto13\",\n            \"count\": 12,\n            \"languages\": 1\n        },\n        {\n            \"order\": 212,\n            \"name\": \"clmiranda\",\n            \"count\": 12,\n            \"languages\": 1\n        },\n        {\n            \"order\": 213,\n            \"name\": \"allanysalazarg\",\n            \"count\": 12,\n            \"languages\": 1\n        },\n        {\n            \"order\": 214,\n            \"name\": \"ipfabio\",\n            \"count\": 12,\n            \"languages\": 1\n        },\n        {\n            \"order\": 215,\n            \"name\": \"jeronimocardu\",\n            \"count\": 12,\n            \"languages\": 1\n        },\n        {\n            \"order\": 216,\n            \"name\": \"pancratzia\",\n            \"count\": 12,\n            \"languages\": 1\n        },\n        {\n            \"order\": 217,\n            \"name\": \"evilpotato04\",\n            \"count\": 12,\n            \"languages\": 1\n        },\n        {\n            \"order\": 218,\n            \"name\": \"llonardo798\",\n            \"count\": 11,\n            \"languages\": 6\n        },\n        {\n            \"order\": 219,\n            \"name\": \"arkmiguel379\",\n            \"count\": 11,\n            \"languages\": 2\n        },\n        {\n            \"order\": 220,\n            \"name\": \"switchdays\",\n            \"count\": 11,\n            \"languages\": 2\n        },\n        {\n            \"order\": 221,\n            \"name\": \"jchavescaceres\",\n            \"count\": 11,\n            \"languages\": 2\n        },\n        {\n            \"order\": 222,\n            \"name\": \"teren91\",\n            \"count\": 11,\n            \"languages\": 2\n        },\n        {\n            \"order\": 223,\n            \"name\": \"evanz2608\",\n            \"count\": 11,\n            \"languages\": 1\n        },\n        {\n            \"order\": 224,\n            \"name\": \"aleran07\",\n            \"count\": 11,\n            \"languages\": 1\n        },\n        {\n            \"order\": 225,\n            \"name\": \"m1l0j05\",\n            \"count\": 11,\n            \"languages\": 1\n        },\n        {\n            \"order\": 226,\n            \"name\": \"majinka10\",\n            \"count\": 11,\n            \"languages\": 1\n        },\n        {\n            \"order\": 227,\n            \"name\": \"mordevspt\",\n            \"count\": 11,\n            \"languages\": 1\n        },\n        {\n            \"order\": 228,\n            \"name\": \"alainmartz\",\n            \"count\": 11,\n            \"languages\": 1\n        },\n        {\n            \"order\": 229,\n            \"name\": \"k-90\",\n            \"count\": 11,\n            \"languages\": 1\n        },\n        {\n            \"order\": 230,\n            \"name\": \"mirandayuber\",\n            \"count\": 11,\n            \"languages\": 1\n        },\n        {\n            \"order\": 231,\n            \"name\": \"warclimb\",\n            \"count\": 11,\n            \"languages\": 1\n        },\n        {\n            \"order\": 232,\n            \"name\": \"59822\",\n            \"count\": 11,\n            \"languages\": 1\n        },\n        {\n            \"order\": 233,\n            \"name\": \"maanghel\",\n            \"count\": 11,\n            \"languages\": 1\n        },\n        {\n            \"order\": 234,\n            \"name\": \"jeigar2\",\n            \"count\": 11,\n            \"languages\": 1\n        },\n        {\n            \"order\": 235,\n            \"name\": \"abelade\",\n            \"count\": 11,\n            \"languages\": 1\n        },\n        {\n            \"order\": 236,\n            \"name\": \"gustavogomez19\",\n            \"count\": 11,\n            \"languages\": 1\n        },\n        {\n            \"order\": 237,\n            \"name\": \"robertoamarohub\",\n            \"count\": 11,\n            \"languages\": 1\n        },\n        {\n            \"order\": 238,\n            \"name\": \"ialmontedr0\",\n            \"count\": 11,\n            \"languages\": 1\n        },\n        {\n            \"order\": 239,\n            \"name\": \"charlerodriguez3\",\n            \"count\": 11,\n            \"languages\": 1\n        },\n        {\n            \"order\": 240,\n            \"name\": \"oleojake\",\n            \"count\": 11,\n            \"languages\": 1\n        },\n        {\n            \"order\": 241,\n            \"name\": \"bertomp\",\n            \"count\": 10,\n            \"languages\": 5\n        },\n        {\n            \"order\": 242,\n            \"name\": \"othamae\",\n            \"count\": 10,\n            \"languages\": 3\n        },\n        {\n            \"order\": 243,\n            \"name\": \"vixxtory\",\n            \"count\": 10,\n            \"languages\": 2\n        },\n        {\n            \"order\": 244,\n            \"name\": \"mauricio-leyva\",\n            \"count\": 10,\n            \"languages\": 1\n        },\n        {\n            \"order\": 245,\n            \"name\": \"javi-kl\",\n            \"count\": 10,\n            \"languages\": 1\n        },\n        {\n            \"order\": 246,\n            \"name\": \"marcose-ferretoe\",\n            \"count\": 10,\n            \"languages\": 1\n        },\n        {\n            \"order\": 247,\n            \"name\": \"xemita007\",\n            \"count\": 10,\n            \"languages\": 1\n        },\n        {\n            \"order\": 248,\n            \"name\": \"thonys07\",\n            \"count\": 10,\n            \"languages\": 1\n        },\n        {\n            \"order\": 249,\n            \"name\": \"josecox13\",\n            \"count\": 10,\n            \"languages\": 1\n        },\n        {\n            \"order\": 250,\n            \"name\": \"littlemabbit\",\n            \"count\": 10,\n            \"languages\": 1\n        },\n        {\n            \"order\": 251,\n            \"name\": \"daparradom\",\n            \"count\": 10,\n            \"languages\": 1\n        },\n        {\n            \"order\": 252,\n            \"name\": \"lautarorisso\",\n            \"count\": 10,\n            \"languages\": 1\n        },\n        {\n            \"order\": 253,\n            \"name\": \"kleyner098\",\n            \"count\": 10,\n            \"languages\": 1\n        },\n        {\n            \"order\": 254,\n            \"name\": \"pinerodev\",\n            \"count\": 10,\n            \"languages\": 1\n        },\n        {\n            \"order\": 255,\n            \"name\": \"gianbordon\",\n            \"count\": 10,\n            \"languages\": 1\n        },\n        {\n            \"order\": 256,\n            \"name\": \"natalyjoanna\",\n            \"count\": 10,\n            \"languages\": 1\n        },\n        {\n            \"order\": 257,\n            \"name\": \"popmaquin\",\n            \"count\": 10,\n            \"languages\": 1\n        },\n        {\n            \"order\": 258,\n            \"name\": \"ricardijulio\",\n            \"count\": 10,\n            \"languages\": 1\n        },\n        {\n            \"order\": 259,\n            \"name\": \"julianbuitragocharry-dev\",\n            \"count\": 9,\n            \"languages\": 3\n        },\n        {\n            \"order\": 260,\n            \"name\": \"luisolivaresj\",\n            \"count\": 9,\n            \"languages\": 2\n        },\n        {\n            \"order\": 261,\n            \"name\": \"blancowilson\",\n            \"count\": 9,\n            \"languages\": 2\n        },\n        {\n            \"order\": 262,\n            \"name\": \"salazarprogrammer\",\n            \"count\": 9,\n            \"languages\": 2\n        },\n        {\n            \"order\": 263,\n            \"name\": \"joseesmil04\",\n            \"count\": 9,\n            \"languages\": 2\n        },\n        {\n            \"order\": 264,\n            \"name\": \"johnalexguerrero\",\n            \"count\": 9,\n            \"languages\": 2\n        },\n        {\n            \"order\": 265,\n            \"name\": \"troynebula\",\n            \"count\": 9,\n            \"languages\": 1\n        },\n        {\n            \"order\": 266,\n            \"name\": \"lio7master\",\n            \"count\": 9,\n            \"languages\": 1\n        },\n        {\n            \"order\": 267,\n            \"name\": \"fishellvvv\",\n            \"count\": 9,\n            \"languages\": 1\n        },\n        {\n            \"order\": 268,\n            \"name\": \"therednoob\",\n            \"count\": 9,\n            \"languages\": 1\n        },\n        {\n            \"order\": 269,\n            \"name\": \"yoezequiel\",\n            \"count\": 9,\n            \"languages\": 1\n        },\n        {\n            \"order\": 270,\n            \"name\": \"gjbecerrae\",\n            \"count\": 9,\n            \"languages\": 1\n        },\n        {\n            \"order\": 271,\n            \"name\": \"jcdm60\",\n            \"count\": 9,\n            \"languages\": 1\n        },\n        {\n            \"order\": 272,\n            \"name\": \"alcaan16\",\n            \"count\": 9,\n            \"languages\": 1\n        },\n        {\n            \"order\": 273,\n            \"name\": \"vid92\",\n            \"count\": 9,\n            \"languages\": 1\n        },\n        {\n            \"order\": 274,\n            \"name\": \"karys4\",\n            \"count\": 9,\n            \"languages\": 1\n        },\n        {\n            \"order\": 275,\n            \"name\": \"adridoce\",\n            \"count\": 9,\n            \"languages\": 1\n        },\n        {\n            \"order\": 276,\n            \"name\": \"leandrocfd\",\n            \"count\": 9,\n            \"languages\": 1\n        },\n        {\n            \"order\": 277,\n            \"name\": \"shevotool\",\n            \"count\": 9,\n            \"languages\": 1\n        },\n        {\n            \"order\": 278,\n            \"name\": \"joapalobael\",\n            \"count\": 9,\n            \"languages\": 1\n        },\n        {\n            \"order\": 279,\n            \"name\": \"cmejiajulian\",\n            \"count\": 9,\n            \"languages\": 1\n        },\n        {\n            \"order\": 280,\n            \"name\": \"omarland\",\n            \"count\": 9,\n            \"languages\": 1\n        },\n        {\n            \"order\": 281,\n            \"name\": \"brockar\",\n            \"count\": 9,\n            \"languages\": 1\n        },\n        {\n            \"order\": 282,\n            \"name\": \"fduron\",\n            \"count\": 9,\n            \"languages\": 1\n        },\n        {\n            \"order\": 283,\n            \"name\": \"sperezsa\",\n            \"count\": 9,\n            \"languages\": 1\n        },\n        {\n            \"order\": 284,\n            \"name\": \"angel-delg\",\n            \"count\": 8,\n            \"languages\": 4\n        },\n        {\n            \"order\": 285,\n            \"name\": \"domo2pdev\",\n            \"count\": 8,\n            \"languages\": 3\n        },\n        {\n            \"order\": 286,\n            \"name\": \"pcosin\",\n            \"count\": 8,\n            \"languages\": 2\n        },\n        {\n            \"order\": 287,\n            \"name\": \"ansuzgs\",\n            \"count\": 8,\n            \"languages\": 2\n        },\n        {\n            \"order\": 288,\n            \"name\": \"ancarlu\",\n            \"count\": 8,\n            \"languages\": 2\n        },\n        {\n            \"order\": 289,\n            \"name\": \"xmunder\",\n            \"count\": 8,\n            \"languages\": 2\n        },\n        {\n            \"order\": 290,\n            \"name\": \"ediedramos\",\n            \"count\": 8,\n            \"languages\": 2\n        },\n        {\n            \"order\": 291,\n            \"name\": \"cyberdidac\",\n            \"count\": 8,\n            \"languages\": 1\n        },\n        {\n            \"order\": 292,\n            \"name\": \"bytecodesky\",\n            \"count\": 8,\n            \"languages\": 1\n        },\n        {\n            \"order\": 293,\n            \"name\": \"carlosvr48\",\n            \"count\": 8,\n            \"languages\": 1\n        },\n        {\n            \"order\": 294,\n            \"name\": \"pipngpop\",\n            \"count\": 8,\n            \"languages\": 1\n        },\n        {\n            \"order\": 295,\n            \"name\": \"linerlander\",\n            \"count\": 8,\n            \"languages\": 1\n        },\n        {\n            \"order\": 296,\n            \"name\": \"abelperezcollado\",\n            \"count\": 8,\n            \"languages\": 1\n        },\n        {\n            \"order\": 297,\n            \"name\": \"ivangdev\",\n            \"count\": 8,\n            \"languages\": 1\n        },\n        {\n            \"order\": 298,\n            \"name\": \"victorrivero1204\",\n            \"count\": 8,\n            \"languages\": 1\n        },\n        {\n            \"order\": 299,\n            \"name\": \"jorgeadamowicz\",\n            \"count\": 8,\n            \"languages\": 1\n        },\n        {\n            \"order\": 300,\n            \"name\": \"toral24\",\n            \"count\": 8,\n            \"languages\": 1\n        },\n        {\n            \"order\": 301,\n            \"name\": \"cbuenrostrovalverde\",\n            \"count\": 8,\n            \"languages\": 1\n        },\n        {\n            \"order\": 302,\n            \"name\": \"sarismejiasanchez\",\n            \"count\": 8,\n            \"languages\": 1\n        },\n        {\n            \"order\": 303,\n            \"name\": \"jacmac45\",\n            \"count\": 8,\n            \"languages\": 1\n        },\n        {\n            \"order\": 304,\n            \"name\": \"jtrujilloalcocer\",\n            \"count\": 8,\n            \"languages\": 1\n        },\n        {\n            \"order\": 305,\n            \"name\": \"ainaragmt\",\n            \"count\": 8,\n            \"languages\": 1\n        },\n        {\n            \"order\": 306,\n            \"name\": \"eliasbonnin\",\n            \"count\": 8,\n            \"languages\": 1\n        },\n        {\n            \"order\": 307,\n            \"name\": \"zequy40\",\n            \"count\": 8,\n            \"languages\": 1\n        },\n        {\n            \"order\": 308,\n            \"name\": \"gerthai08\",\n            \"count\": 8,\n            \"languages\": 1\n        },\n        {\n            \"order\": 309,\n            \"name\": \"westwbn\",\n            \"count\": 8,\n            \"languages\": 1\n        },\n        {\n            \"order\": 310,\n            \"name\": \"arturonavas\",\n            \"count\": 8,\n            \"languages\": 1\n        },\n        {\n            \"order\": 311,\n            \"name\": \"srvariable\",\n            \"count\": 8,\n            \"languages\": 1\n        },\n        {\n            \"order\": 312,\n            \"name\": \"isj-code\",\n            \"count\": 8,\n            \"languages\": 1\n        },\n        {\n            \"order\": 313,\n            \"name\": \"jaxi86\",\n            \"count\": 8,\n            \"languages\": 1\n        },\n        {\n            \"order\": 314,\n            \"name\": \"matitc\",\n            \"count\": 8,\n            \"languages\": 1\n        },\n        {\n            \"order\": 315,\n            \"name\": \"andres54-coder\",\n            \"count\": 8,\n            \"languages\": 1\n        },\n        {\n            \"order\": 316,\n            \"name\": \"glossypath\",\n            \"count\": 8,\n            \"languages\": 1\n        },\n        {\n            \"order\": 317,\n            \"name\": \"yisusocanto\",\n            \"count\": 8,\n            \"languages\": 1\n        },\n        {\n            \"order\": 318,\n            \"name\": \"darubiano\",\n            \"count\": 7,\n            \"languages\": 7\n        },\n        {\n            \"order\": 319,\n            \"name\": \"nwpablodeveloper\",\n            \"count\": 7,\n            \"languages\": 3\n        },\n        {\n            \"order\": 320,\n            \"name\": \"bladi23\",\n            \"count\": 7,\n            \"languages\": 3\n        },\n        {\n            \"order\": 321,\n            \"name\": \"cubandeveloper89\",\n            \"count\": 7,\n            \"languages\": 3\n        },\n        {\n            \"order\": 322,\n            \"name\": \"miguelangelec\",\n            \"count\": 7,\n            \"languages\": 3\n        },\n        {\n            \"order\": 323,\n            \"name\": \"dimasb69\",\n            \"count\": 7,\n            \"languages\": 2\n        },\n        {\n            \"order\": 324,\n            \"name\": \"danielbelenguer\",\n            \"count\": 7,\n            \"languages\": 2\n        },\n        {\n            \"order\": 325,\n            \"name\": \"younes0-0\",\n            \"count\": 7,\n            \"languages\": 2\n        },\n        {\n            \"order\": 326,\n            \"name\": \"brahiams7\",\n            \"count\": 7,\n            \"languages\": 1\n        },\n        {\n            \"order\": 327,\n            \"name\": \"gabodev23\",\n            \"count\": 7,\n            \"languages\": 1\n        },\n        {\n            \"order\": 328,\n            \"name\": \"dgrex\",\n            \"count\": 7,\n            \"languages\": 1\n        },\n        {\n            \"order\": 329,\n            \"name\": \"ruhlmirko\",\n            \"count\": 7,\n            \"languages\": 1\n        },\n        {\n            \"order\": 330,\n            \"name\": \"rusanov16\",\n            \"count\": 7,\n            \"languages\": 1\n        },\n        {\n            \"order\": 331,\n            \"name\": \"albertomorilla\",\n            \"count\": 7,\n            \"languages\": 1\n        },\n        {\n            \"order\": 332,\n            \"name\": \"aquiles735\",\n            \"count\": 7,\n            \"languages\": 1\n        },\n        {\n            \"order\": 333,\n            \"name\": \"giulianovfz\",\n            \"count\": 7,\n            \"languages\": 1\n        },\n        {\n            \"order\": 334,\n            \"name\": \"yani-git\",\n            \"count\": 7,\n            \"languages\": 1\n        },\n        {\n            \"order\": 335,\n            \"name\": \"maxirica\",\n            \"count\": 7,\n            \"languages\": 1\n        },\n        {\n            \"order\": 336,\n            \"name\": \"franvozzi\",\n            \"count\": 7,\n            \"languages\": 1\n        },\n        {\n            \"order\": 337,\n            \"name\": \"jose-larss\",\n            \"count\": 7,\n            \"languages\": 1\n        },\n        {\n            \"order\": 338,\n            \"name\": \"mtirador\",\n            \"count\": 7,\n            \"languages\": 1\n        },\n        {\n            \"order\": 339,\n            \"name\": \"ldre3\",\n            \"count\": 7,\n            \"languages\": 1\n        },\n        {\n            \"order\": 340,\n            \"name\": \"guillermo-munoz\",\n            \"count\": 7,\n            \"languages\": 1\n        },\n        {\n            \"order\": 341,\n            \"name\": \"alextc35\",\n            \"count\": 7,\n            \"languages\": 1\n        },\n        {\n            \"order\": 342,\n            \"name\": \"18miguelgalarza\",\n            \"count\": 7,\n            \"languages\": 1\n        },\n        {\n            \"order\": 343,\n            \"name\": \"marinaortells\",\n            \"count\": 7,\n            \"languages\": 1\n        },\n        {\n            \"order\": 344,\n            \"name\": \"ocandodev\",\n            \"count\": 7,\n            \"languages\": 1\n        },\n        {\n            \"order\": 345,\n            \"name\": \"markc1234\",\n            \"count\": 7,\n            \"languages\": 1\n        },\n        {\n            \"order\": 346,\n            \"name\": \"sharah07\",\n            \"count\": 7,\n            \"languages\": 1\n        },\n        {\n            \"order\": 347,\n            \"name\": \"victormugo\",\n            \"count\": 7,\n            \"languages\": 1\n        },\n        {\n            \"order\": 348,\n            \"name\": \"abrahamraies\",\n            \"count\": 7,\n            \"languages\": 1\n        },\n        {\n            \"order\": 349,\n            \"name\": \"joseandresgc\",\n            \"count\": 7,\n            \"languages\": 1\n        },\n        {\n            \"order\": 350,\n            \"name\": \"usermatthew\",\n            \"count\": 7,\n            \"languages\": 1\n        },\n        {\n            \"order\": 351,\n            \"name\": \"juancaicedo1024\",\n            \"count\": 7,\n            \"languages\": 1\n        },\n        {\n            \"order\": 352,\n            \"name\": \"maximiliano1997\",\n            \"count\": 7,\n            \"languages\": 1\n        },\n        {\n            \"order\": 353,\n            \"name\": \"aarxnmendez\",\n            \"count\": 7,\n            \"languages\": 1\n        },\n        {\n            \"order\": 354,\n            \"name\": \"ljoecordoba\",\n            \"count\": 7,\n            \"languages\": 1\n        },\n        {\n            \"order\": 355,\n            \"name\": \"hectordbh\",\n            \"count\": 7,\n            \"languages\": 1\n        },\n        {\n            \"order\": 356,\n            \"name\": \"pwrxman\",\n            \"count\": 7,\n            \"languages\": 1\n        },\n        {\n            \"order\": 357,\n            \"name\": \"jgutierrez9891\",\n            \"count\": 7,\n            \"languages\": 1\n        },\n        {\n            \"order\": 358,\n            \"name\": \"curtobrull\",\n            \"count\": 6,\n            \"languages\": 3\n        },\n        {\n            \"order\": 359,\n            \"name\": \"abel-ade\",\n            \"count\": 6,\n            \"languages\": 3\n        },\n        {\n            \"order\": 360,\n            \"name\": \"fidelysla\",\n            \"count\": 6,\n            \"languages\": 3\n        },\n        {\n            \"order\": 361,\n            \"name\": \"eberstr\",\n            \"count\": 6,\n            \"languages\": 2\n        },\n        {\n            \"order\": 362,\n            \"name\": \"luisk0706\",\n            \"count\": 6,\n            \"languages\": 2\n        },\n        {\n            \"order\": 363,\n            \"name\": \"danilo0203\",\n            \"count\": 6,\n            \"languages\": 2\n        },\n        {\n            \"order\": 364,\n            \"name\": \"devknn\",\n            \"count\": 6,\n            \"languages\": 2\n        },\n        {\n            \"order\": 365,\n            \"name\": \"luterfloyd\",\n            \"count\": 6,\n            \"languages\": 2\n        },\n        {\n            \"order\": 366,\n            \"name\": \"kronstadt-lambda\",\n            \"count\": 6,\n            \"languages\": 2\n        },\n        {\n            \"order\": 367,\n            \"name\": \"oixild\",\n            \"count\": 6,\n            \"languages\": 2\n        },\n        {\n            \"order\": 368,\n            \"name\": \"isaias-alt\",\n            \"count\": 6,\n            \"languages\": 2\n        },\n        {\n            \"order\": 369,\n            \"name\": \"douglasdiazr\",\n            \"count\": 6,\n            \"languages\": 2\n        },\n        {\n            \"order\": 370,\n            \"name\": \"misterdan100\",\n            \"count\": 6,\n            \"languages\": 2\n        },\n        {\n            \"order\": 371,\n            \"name\": \"troleomotor10\",\n            \"count\": 6,\n            \"languages\": 2\n        },\n        {\n            \"order\": 372,\n            \"name\": \"elhacedordecosas\",\n            \"count\": 6,\n            \"languages\": 2\n        },\n        {\n            \"order\": 373,\n            \"name\": \"roswer13\",\n            \"count\": 6,\n            \"languages\": 2\n        },\n        {\n            \"order\": 374,\n            \"name\": \"rserradev\",\n            \"count\": 6,\n            \"languages\": 2\n        },\n        {\n            \"order\": 375,\n            \"name\": \"eduhumanes91\",\n            \"count\": 6,\n            \"languages\": 1\n        },\n        {\n            \"order\": 376,\n            \"name\": \"lioomx\",\n            \"count\": 6,\n            \"languages\": 1\n        },\n        {\n            \"order\": 377,\n            \"name\": \"abascal92\",\n            \"count\": 6,\n            \"languages\": 1\n        },\n        {\n            \"order\": 378,\n            \"name\": \"juanma0416\",\n            \"count\": 6,\n            \"languages\": 1\n        },\n        {\n            \"order\": 379,\n            \"name\": \"ramirofordev\",\n            \"count\": 6,\n            \"languages\": 1\n        },\n        {\n            \"order\": 380,\n            \"name\": \"lazar171717ech\",\n            \"count\": 6,\n            \"languages\": 1\n        },\n        {\n            \"order\": 381,\n            \"name\": \"agustindamonte17\",\n            \"count\": 6,\n            \"languages\": 1\n        },\n        {\n            \"order\": 382,\n            \"name\": \"pytordev\",\n            \"count\": 6,\n            \"languages\": 1\n        },\n        {\n            \"order\": 383,\n            \"name\": \"marcelosanchez166\",\n            \"count\": 6,\n            \"languages\": 1\n        },\n        {\n            \"order\": 384,\n            \"name\": \"c3sarmx\",\n            \"count\": 6,\n            \"languages\": 1\n        },\n        {\n            \"order\": 385,\n            \"name\": \"yeisonagm\",\n            \"count\": 6,\n            \"languages\": 1\n        },\n        {\n            \"order\": 386,\n            \"name\": \"gliadev\",\n            \"count\": 6,\n            \"languages\": 1\n        },\n        {\n            \"order\": 387,\n            \"name\": \"ceciliaporras01\",\n            \"count\": 6,\n            \"languages\": 1\n        },\n        {\n            \"order\": 388,\n            \"name\": \"luis-vb\",\n            \"count\": 6,\n            \"languages\": 1\n        },\n        {\n            \"order\": 389,\n            \"name\": \"mikelroset\",\n            \"count\": 6,\n            \"languages\": 1\n        },\n        {\n            \"order\": 390,\n            \"name\": \"mxtrar23\",\n            \"count\": 6,\n            \"languages\": 1\n        },\n        {\n            \"order\": 391,\n            \"name\": \"guillemduno\",\n            \"count\": 6,\n            \"languages\": 1\n        },\n        {\n            \"order\": 392,\n            \"name\": \"miguelangelmtz000414\",\n            \"count\": 6,\n            \"languages\": 1\n        },\n        {\n            \"order\": 393,\n            \"name\": \"dannymarperone\",\n            \"count\": 6,\n            \"languages\": 1\n        },\n        {\n            \"order\": 394,\n            \"name\": \"dobledj\",\n            \"count\": 6,\n            \"languages\": 1\n        },\n        {\n            \"order\": 395,\n            \"name\": \"kaesar84\",\n            \"count\": 6,\n            \"languages\": 1\n        },\n        {\n            \"order\": 396,\n            \"name\": \"facundo-muoio\",\n            \"count\": 6,\n            \"languages\": 1\n        },\n        {\n            \"order\": 397,\n            \"name\": \"zunigaj1101\",\n            \"count\": 6,\n            \"languages\": 1\n        },\n        {\n            \"order\": 398,\n            \"name\": \"ssanjua\",\n            \"count\": 6,\n            \"languages\": 1\n        },\n        {\n            \"order\": 399,\n            \"name\": \"ralphmcralph\",\n            \"count\": 6,\n            \"languages\": 1\n        },\n        {\n            \"order\": 400,\n            \"name\": \"wolffcode\",\n            \"count\": 6,\n            \"languages\": 1\n        },\n        {\n            \"order\": 401,\n            \"name\": \"dafi02\",\n            \"count\": 6,\n            \"languages\": 1\n        },\n        {\n            \"order\": 402,\n            \"name\": \"elbarbero\",\n            \"count\": 6,\n            \"languages\": 1\n        },\n        {\n            \"order\": 403,\n            \"name\": \"annnerssv\",\n            \"count\": 6,\n            \"languages\": 1\n        },\n        {\n            \"order\": 404,\n            \"name\": \"eamartin96\",\n            \"count\": 6,\n            \"languages\": 1\n        },\n        {\n            \"order\": 405,\n            \"name\": \"m-hadz\",\n            \"count\": 5,\n            \"languages\": 5\n        },\n        {\n            \"order\": 406,\n            \"name\": \"bryan112094\",\n            \"count\": 5,\n            \"languages\": 3\n        },\n        {\n            \"order\": 407,\n            \"name\": \"owen-ian\",\n            \"count\": 5,\n            \"languages\": 3\n        },\n        {\n            \"order\": 408,\n            \"name\": \"alabacw74\",\n            \"count\": 5,\n            \"languages\": 3\n        },\n        {\n            \"order\": 409,\n            \"name\": \"espinoleandroo\",\n            \"count\": 5,\n            \"languages\": 2\n        },\n        {\n            \"order\": 410,\n            \"name\": \"jandresalvar\",\n            \"count\": 5,\n            \"languages\": 2\n        },\n        {\n            \"order\": 411,\n            \"name\": \"rgeditv1\",\n            \"count\": 5,\n            \"languages\": 2\n        },\n        {\n            \"order\": 412,\n            \"name\": \"icedrek\",\n            \"count\": 5,\n            \"languages\": 2\n        },\n        {\n            \"order\": 413,\n            \"name\": \"alejandrodave\",\n            \"count\": 5,\n            \"languages\": 2\n        },\n        {\n            \"order\": 414,\n            \"name\": \"andresmendozaf\",\n            \"count\": 5,\n            \"languages\": 2\n        },\n        {\n            \"order\": 415,\n            \"name\": \"tizog\",\n            \"count\": 5,\n            \"languages\": 2\n        },\n        {\n            \"order\": 416,\n            \"name\": \"xhuaspy\",\n            \"count\": 5,\n            \"languages\": 2\n        },\n        {\n            \"order\": 417,\n            \"name\": \"jalivur\",\n            \"count\": 5,\n            \"languages\": 2\n        },\n        {\n            \"order\": 418,\n            \"name\": \"vmatmarco\",\n            \"count\": 5,\n            \"languages\": 2\n        },\n        {\n            \"order\": 419,\n            \"name\": \"thaishdz\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 420,\n            \"name\": \"bastianalq\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 421,\n            \"name\": \"emilianoangel\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 422,\n            \"name\": \"alejo-digital\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 423,\n            \"name\": \"nomellamodante\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 424,\n            \"name\": \"zakkdrte\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 425,\n            \"name\": \"thephobos01\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 426,\n            \"name\": \"joshu725\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 427,\n            \"name\": \"njaimev\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 428,\n            \"name\": \"thezhizn\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 429,\n            \"name\": \"daniel-sanabria0419\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 430,\n            \"name\": \"yharyarias\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 431,\n            \"name\": \"d0ubt0\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 432,\n            \"name\": \"alberba\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 433,\n            \"name\": \"craphaelam\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 434,\n            \"name\": \"franz-arzapalo\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 435,\n            \"name\": \"pirrin22\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 436,\n            \"name\": \"gabrielramos02\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 437,\n            \"name\": \"jose-luis-lanza\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 438,\n            \"name\": \"augustdev2003\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 439,\n            \"name\": \"gmbarrios\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 440,\n            \"name\": \"javitron100\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 441,\n            \"name\": \"pabloche73\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 442,\n            \"name\": \"santiago434c\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 443,\n            \"name\": \"yah1r404\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 444,\n            \"name\": \"iban99\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 445,\n            \"name\": \"kilianhc\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 446,\n            \"name\": \"jcrodmir\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 447,\n            \"name\": \"karolle\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 448,\n            \"name\": \"lucasag01\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 449,\n            \"name\": \"alvarofernandezavalos\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 450,\n            \"name\": \"jeyker-dev\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 451,\n            \"name\": \"drvito1977\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 452,\n            \"name\": \"rubenplazavi\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 453,\n            \"name\": \"micromantic\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 454,\n            \"name\": \"xperiargluna\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 455,\n            \"name\": \"esaens12\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 456,\n            \"name\": \"vasilealexandru02\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 457,\n            \"name\": \"vixito\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 458,\n            \"name\": \"fdcorreadev\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 459,\n            \"name\": \"darkhouselab08\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 460,\n            \"name\": \"joanfv-git\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 461,\n            \"name\": \"1nonamed\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 462,\n            \"name\": \"d4-n1\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 463,\n            \"name\": \"yesidl12\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 464,\n            \"name\": \"n1sek\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 465,\n            \"name\": \"lauracastrillonmp\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 466,\n            \"name\": \"robmxz\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 467,\n            \"name\": \"rlores-edison\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 468,\n            \"name\": \"danielbustos342\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 469,\n            \"name\": \"boterop\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 470,\n            \"name\": \"w00k\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 471,\n            \"name\": \"eloychavezdev\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 472,\n            \"name\": \"alb-martinez\",\n            \"count\": 5,\n            \"languages\": 1\n        },\n        {\n            \"order\": 473,\n            \"name\": \"jehiselruth\",\n            \"count\": 4,\n            \"languages\": 4\n        },\n        {\n            \"order\": 474,\n            \"name\": \"zarakilancelot\",\n            \"count\": 4,\n            \"languages\": 3\n        },\n        {\n            \"order\": 475,\n            \"name\": \"h4cker0n\",\n            \"count\": 4,\n            \"languages\": 2\n        },\n        {\n            \"order\": 476,\n            \"name\": \"super490\",\n            \"count\": 4,\n            \"languages\": 2\n        },\n        {\n            \"order\": 477,\n            \"name\": \"ruthmp\",\n            \"count\": 4,\n            \"languages\": 2\n        },\n        {\n            \"order\": 478,\n            \"name\": \"alejosor\",\n            \"count\": 4,\n            \"languages\": 2\n        },\n        {\n            \"order\": 479,\n            \"name\": \"willr30\",\n            \"count\": 4,\n            \"languages\": 2\n        },\n        {\n            \"order\": 480,\n            \"name\": \"daeduol\",\n            \"count\": 4,\n            \"languages\": 2\n        },\n        {\n            \"order\": 481,\n            \"name\": \"cikethebear\",\n            \"count\": 4,\n            \"languages\": 2\n        },\n        {\n            \"order\": 482,\n            \"name\": \"fullovellas\",\n            \"count\": 4,\n            \"languages\": 2\n        },\n        {\n            \"order\": 483,\n            \"name\": \"josefuentes-dev\",\n            \"count\": 4,\n            \"languages\": 2\n        },\n        {\n            \"order\": 484,\n            \"name\": \"k3nvd\",\n            \"count\": 4,\n            \"languages\": 2\n        },\n        {\n            \"order\": 485,\n            \"name\": \"eonozux\",\n            \"count\": 4,\n            \"languages\": 2\n        },\n        {\n            \"order\": 486,\n            \"name\": \"yablik\",\n            \"count\": 4,\n            \"languages\": 2\n        },\n        {\n            \"order\": 487,\n            \"name\": \"mendozalz\",\n            \"count\": 4,\n            \"languages\": 2\n        },\n        {\n            \"order\": 488,\n            \"name\": \"victorjaimesr\",\n            \"count\": 4,\n            \"languages\": 2\n        },\n        {\n            \"order\": 489,\n            \"name\": \"salkalero\",\n            \"count\": 4,\n            \"languages\": 2\n        },\n        {\n            \"order\": 490,\n            \"name\": \"carlosmqz969\",\n            \"count\": 4,\n            \"languages\": 2\n        },\n        {\n            \"order\": 491,\n            \"name\": \"annaviper\",\n            \"count\": 4,\n            \"languages\": 2\n        },\n        {\n            \"order\": 492,\n            \"name\": \"siderio2\",\n            \"count\": 4,\n            \"languages\": 2\n        },\n        {\n            \"order\": 493,\n            \"name\": \"jairo-alejandro\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 494,\n            \"name\": \"davidvilem\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 495,\n            \"name\": \"jadraz\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 496,\n            \"name\": \"yorjanvarela\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 497,\n            \"name\": \"mplatab\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 498,\n            \"name\": \"luissssoto\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 499,\n            \"name\": \"buriticasara\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 500,\n            \"name\": \"txuky\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 501,\n            \"name\": \"anvildestroyer\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 502,\n            \"name\": \"axelprz\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 503,\n            \"name\": \"danirojasdev\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 504,\n            \"name\": \"pablo25\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 505,\n            \"name\": \"nox456\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 506,\n            \"name\": \"pedro-blasco\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 507,\n            \"name\": \"rickubb\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 508,\n            \"name\": \"santiagobima\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 509,\n            \"name\": \"angell4s\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 510,\n            \"name\": \"tobibordino\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 511,\n            \"name\": \"elbam\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 512,\n            \"name\": \"carl6289\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 513,\n            \"name\": \"seni889\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 514,\n            \"name\": \"rodrigoghr\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 515,\n            \"name\": \"javirub\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 516,\n            \"name\": \"cdbiancotti\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 517,\n            \"name\": \"jfdacovich\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 518,\n            \"name\": \"ramxv\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 519,\n            \"name\": \"annerssv\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 520,\n            \"name\": \"knowledgesoftdev\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 521,\n            \"name\": \"victorzm0h\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 522,\n            \"name\": \"albertorevel\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 523,\n            \"name\": \"zerek247\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 524,\n            \"name\": \"guillermo-k\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 525,\n            \"name\": \"mercedesdf\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 526,\n            \"name\": \"vicman-182\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 527,\n            \"name\": \"harrisonguerrero18\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 528,\n            \"name\": \"sunjamer\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 529,\n            \"name\": \"gmigues\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 530,\n            \"name\": \"inkhemi\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 531,\n            \"name\": \"mallcca\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 532,\n            \"name\": \"caleb699-hub\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 533,\n            \"name\": \"carrenoalexander\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 534,\n            \"name\": \"dlgai12\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 535,\n            \"name\": \"domingoandres\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 536,\n            \"name\": \"davidsorroche\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 537,\n            \"name\": \"blasbarragan\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 538,\n            \"name\": \"juanca2805\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 539,\n            \"name\": \"dredux2\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 540,\n            \"name\": \"clarancedev\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 541,\n            \"name\": \"marianoemir\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 542,\n            \"name\": \"verschlingendenacht\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 543,\n            \"name\": \"juanguzmang\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 544,\n            \"name\": \"afoxjones\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 545,\n            \"name\": \"jerrysantana\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 546,\n            \"name\": \"password1989\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 547,\n            \"name\": \"xooseph\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 548,\n            \"name\": \"carzep09\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 549,\n            \"name\": \"hugovrc\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 550,\n            \"name\": \"mayerga\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 551,\n            \"name\": \"lia-m3dusa\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 552,\n            \"name\": \"deivitdev\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 553,\n            \"name\": \"traver79\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 554,\n            \"name\": \"confley\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 555,\n            \"name\": \"santiago-munoz-garcia\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 556,\n            \"name\": \"miguelangelmz21\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 557,\n            \"name\": \"andeveling\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 558,\n            \"name\": \"04khaos\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 559,\n            \"name\": \"somaxb\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 560,\n            \"name\": \"ivancalero04\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 561,\n            \"name\": \"mor39a\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 562,\n            \"name\": \"jcubero12\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 563,\n            \"name\": \"joaquinlopez14\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 564,\n            \"name\": \"elianisdev\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 565,\n            \"name\": \"pype-dev\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 566,\n            \"name\": \"reinaldosanchez\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 567,\n            \"name\": \"mateo423\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 568,\n            \"name\": \"cristophher087\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 569,\n            \"name\": \"socramwd\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 570,\n            \"name\": \"angelurrutdev\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 571,\n            \"name\": \"joshbaez\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 572,\n            \"name\": \"eloyparga\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 573,\n            \"name\": \"omegatroy\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 574,\n            \"name\": \"septarian\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 575,\n            \"name\": \"josuevh07\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 576,\n            \"name\": \"levsistemas\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 577,\n            \"name\": \"andyfg0289\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 578,\n            \"name\": \"fernandog25\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 579,\n            \"name\": \"ant000o\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 580,\n            \"name\": \"dieswae\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 581,\n            \"name\": \"marcoslombardo\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 582,\n            \"name\": \"vsunix0\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 583,\n            \"name\": \"lrpeset\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 584,\n            \"name\": \"joselorentelopez\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 585,\n            \"name\": \"willianl731\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 586,\n            \"name\": \"sbs24\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 587,\n            \"name\": \"juperdev\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 588,\n            \"name\": \"quejuan52\",\n            \"count\": 4,\n            \"languages\": 1\n        },\n        {\n            \"order\": 589,\n            \"name\": \"juitomg\",\n            \"count\": 3,\n            \"languages\": 3\n        },\n        {\n            \"order\": 590,\n            \"name\": \"angelo-eyama\",\n            \"count\": 3,\n            \"languages\": 3\n        },\n        {\n            \"order\": 591,\n            \"name\": \"manuelgomezg\",\n            \"count\": 3,\n            \"languages\": 3\n        },\n        {\n            \"order\": 592,\n            \"name\": \"xebaztiandev\",\n            \"count\": 3,\n            \"languages\": 3\n        },\n        {\n            \"order\": 593,\n            \"name\": \"akaisombra\",\n            \"count\": 3,\n            \"languages\": 3\n        },\n        {\n            \"order\": 594,\n            \"name\": \"oskarcali\",\n            \"count\": 3,\n            \"languages\": 3\n        },\n        {\n            \"order\": 595,\n            \"name\": \"abelsrzz\",\n            \"count\": 3,\n            \"languages\": 3\n        },\n        {\n            \"order\": 596,\n            \"name\": \"didix16\",\n            \"count\": 3,\n            \"languages\": 3\n        },\n        {\n            \"order\": 597,\n            \"name\": \"slaughtbear\",\n            \"count\": 3,\n            \"languages\": 2\n        },\n        {\n            \"order\": 598,\n            \"name\": \"eloitr\",\n            \"count\": 3,\n            \"languages\": 2\n        },\n        {\n            \"order\": 599,\n            \"name\": \"diegopc-dev\",\n            \"count\": 3,\n            \"languages\": 2\n        },\n        {\n            \"order\": 600,\n            \"name\": \"seba9906\",\n            \"count\": 3,\n            \"languages\": 2\n        },\n        {\n            \"order\": 601,\n            \"name\": \"skala2301\",\n            \"count\": 3,\n            \"languages\": 2\n        },\n        {\n            \"order\": 602,\n            \"name\": \"pablotaber\",\n            \"count\": 3,\n            \"languages\": 2\n        },\n        {\n            \"order\": 603,\n            \"name\": \"jaennova\",\n            \"count\": 3,\n            \"languages\": 2\n        },\n        {\n            \"order\": 604,\n            \"name\": \"clotrack\",\n            \"count\": 3,\n            \"languages\": 2\n        },\n        {\n            \"order\": 605,\n            \"name\": \"gamitocu\",\n            \"count\": 3,\n            \"languages\": 2\n        },\n        {\n            \"order\": 606,\n            \"name\": \"allanoscoding\",\n            \"count\": 3,\n            \"languages\": 2\n        },\n        {\n            \"order\": 607,\n            \"name\": \"augustosdev\",\n            \"count\": 3,\n            \"languages\": 2\n        },\n        {\n            \"order\": 608,\n            \"name\": \"alfarog507\",\n            \"count\": 3,\n            \"languages\": 2\n        },\n        {\n            \"order\": 609,\n            \"name\": \"robindev1812\",\n            \"count\": 3,\n            \"languages\": 2\n        },\n        {\n            \"order\": 610,\n            \"name\": \"arliumdev\",\n            \"count\": 3,\n            \"languages\": 2\n        },\n        {\n            \"order\": 611,\n            \"name\": \"jotarose\",\n            \"count\": 3,\n            \"languages\": 2\n        },\n        {\n            \"order\": 612,\n            \"name\": \"n-skot\",\n            \"count\": 3,\n            \"languages\": 2\n        },\n        {\n            \"order\": 613,\n            \"name\": \"marlonleon2023\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 614,\n            \"name\": \"ikeragi05\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 615,\n            \"name\": \"joandevpy\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 616,\n            \"name\": \"ramon-almeida\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 617,\n            \"name\": \"cevicheconaji\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 618,\n            \"name\": \"alejomazov\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 619,\n            \"name\": \"sandrogmz\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 620,\n            \"name\": \"dgjuancho\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 621,\n            \"name\": \"monikgbar\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 622,\n            \"name\": \"antii16\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 623,\n            \"name\": \"strooplab\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 624,\n            \"name\": \"ggtorca\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 625,\n            \"name\": \"tonywarcode\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 626,\n            \"name\": \"carlosalberto05\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 627,\n            \"name\": \"estelacode\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 628,\n            \"name\": \"bertolini-victor\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 629,\n            \"name\": \"jucedinv\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 630,\n            \"name\": \"mstaz4\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 631,\n            \"name\": \"marcoh2325\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 632,\n            \"name\": \"mizadlogcia\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 633,\n            \"name\": \"exanderguitar\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 634,\n            \"name\": \"danielperezrubio\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 635,\n            \"name\": \"lpassword012\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 636,\n            \"name\": \"guillesese\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 637,\n            \"name\": \"minn09\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 638,\n            \"name\": \"dandrusco\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 639,\n            \"name\": \"macova96\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 640,\n            \"name\": \"frostbitepy\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 641,\n            \"name\": \"ibuetab\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 642,\n            \"name\": \"elder202\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 643,\n            \"name\": \"marktwin25\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 644,\n            \"name\": \"oscarhub90\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 645,\n            \"name\": \"elkin-dev\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 646,\n            \"name\": \"bryanalzate007\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 647,\n            \"name\": \"oscargeovannyrincon\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 648,\n            \"name\": \"betzadev\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 649,\n            \"name\": \"camilo-zuluaga\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 650,\n            \"name\": \"emilianohoyos\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 651,\n            \"name\": \"dchevesich\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 652,\n            \"name\": \"juliand89\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 653,\n            \"name\": \"fernando-antoni0\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 654,\n            \"name\": \"eliskopun\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 655,\n            \"name\": \"jhonmarin12\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 656,\n            \"name\": \"jorgegarcia-dev\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 657,\n            \"name\": \"luistecnocode\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 658,\n            \"name\": \"saulmrto\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 659,\n            \"name\": \"tekatoki\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 660,\n            \"name\": \"zzepu\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 661,\n            \"name\": \"antoniosuero\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 662,\n            \"name\": \"jofedev\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 663,\n            \"name\": \"notj0s3\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 664,\n            \"name\": \"ivanpelu7\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 665,\n            \"name\": \"suescun845\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 666,\n            \"name\": \"clainu04\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 667,\n            \"name\": \"yeam-10\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 668,\n            \"name\": \"jackziel-sumoza\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 669,\n            \"name\": \"artdugarte\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 670,\n            \"name\": \"mmacalli\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 671,\n            \"name\": \"13sauca13\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 672,\n            \"name\": \"natalinacn\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 673,\n            \"name\": \"yaretzyrb\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 674,\n            \"name\": \"rubioj17\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 675,\n            \"name\": \"david-quinones\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 676,\n            \"name\": \"dmauricio4\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 677,\n            \"name\": \"fluna29\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 678,\n            \"name\": \"swifty0705\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 679,\n            \"name\": \"freedainew\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 680,\n            \"name\": \"ainoaran\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 681,\n            \"name\": \"marce1084\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 682,\n            \"name\": \"alexisdiaz000\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 683,\n            \"name\": \"kingsaul22\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 684,\n            \"name\": \"davidr1594\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 685,\n            \"name\": \"zugarramurdi\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 686,\n            \"name\": \"pbjmg\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 687,\n            \"name\": \"francofmv\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 688,\n            \"name\": \"xurxogz\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 689,\n            \"name\": \"chakerr\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 690,\n            \"name\": \"kine-jdf\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 691,\n            \"name\": \"14davidnkt\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 692,\n            \"name\": \"eltitojet\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 693,\n            \"name\": \"mavigareli\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 694,\n            \"name\": \"tomytsa\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 695,\n            \"name\": \"carlosguariglia\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 696,\n            \"name\": \"crisvigas\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 697,\n            \"name\": \"davidvela-306\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 698,\n            \"name\": \"paola-itzel-martinez\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 699,\n            \"name\": \"guido2288\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 700,\n            \"name\": \"githjuan\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 701,\n            \"name\": \"jonathanj20\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 702,\n            \"name\": \"rocallejas\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 703,\n            \"name\": \"sitnestic\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 704,\n            \"name\": \"sebasgrdev\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 705,\n            \"name\": \"carlosavargas7\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 706,\n            \"name\": \"jaimerocel96\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 707,\n            \"name\": \"arnodchirivi08\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 708,\n            \"name\": \"axelsparta\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 709,\n            \"name\": \"tolomero\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 710,\n            \"name\": \"dannyvera1234\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 711,\n            \"name\": \"gitperalta\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 712,\n            \"name\": \"samuelarandia\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 713,\n            \"name\": \"rendonnm\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 714,\n            \"name\": \"heliercamejo\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 715,\n            \"name\": \"barbafebles\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 716,\n            \"name\": \"justorlo\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 717,\n            \"name\": \"aggranadoss\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 718,\n            \"name\": \"cristopherfdev\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 719,\n            \"name\": \"isco-mtz\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 720,\n            \"name\": \"tebaah\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 721,\n            \"name\": \"juanpvelasquezr\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 722,\n            \"name\": \"matteozhao98\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 723,\n            \"name\": \"kvr0th3c4t\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 724,\n            \"name\": \"orlas135\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 725,\n            \"name\": \"raqueltejada\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 726,\n            \"name\": \"daniback95\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 727,\n            \"name\": \"aitorlcom\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 728,\n            \"name\": \"josueeeee\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 729,\n            \"name\": \"sebascmb\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 730,\n            \"name\": \"davidb313\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 731,\n            \"name\": \"r4kso\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 732,\n            \"name\": \"carles11\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 733,\n            \"name\": \"derlingr\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 734,\n            \"name\": \"oscar503sv\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 735,\n            \"name\": \"hatorob\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 736,\n            \"name\": \"victorsschz\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 737,\n            \"name\": \"matiascba27\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 738,\n            \"name\": \"gpinedaoviedo\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 739,\n            \"name\": \"migueltfangche\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 740,\n            \"name\": \"alexandertejedor\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 741,\n            \"name\": \"zuluangel\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 742,\n            \"name\": \"magupe09\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 743,\n            \"name\": \"legs30011\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 744,\n            \"name\": \"yedixdev\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 745,\n            \"name\": \"sans6114\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 746,\n            \"name\": \"singularpigeon\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 747,\n            \"name\": \"emaenriquez\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 748,\n            \"name\": \"faga01\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 749,\n            \"name\": \"tasymed\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 750,\n            \"name\": \"sandracalatayud\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 751,\n            \"name\": \"nathaliamf\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 752,\n            \"name\": \"erysnell\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 753,\n            \"name\": \"adant11235\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 754,\n            \"name\": \"uyarra73\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 755,\n            \"name\": \"hectoriglesias\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 756,\n            \"name\": \"asaelz\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 757,\n            \"name\": \"jacarrillob\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 758,\n            \"name\": \"andresargote\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 759,\n            \"name\": \"dumbnoxx\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 760,\n            \"name\": \"ppinilla\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 761,\n            \"name\": \"dev-marco-dev\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 762,\n            \"name\": \"dariorfm\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 763,\n            \"name\": \"edisplai\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 764,\n            \"name\": \"sjho-406\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 765,\n            \"name\": \"arbenisacosta\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 766,\n            \"name\": \"juancamilo3821\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 767,\n            \"name\": \"jelozanov\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 768,\n            \"name\": \"matrix-miguel\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 769,\n            \"name\": \"agusbelp\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 770,\n            \"name\": \"ahinar\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 771,\n            \"name\": \"javiearth\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 772,\n            \"name\": \"atienzar\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 773,\n            \"name\": \"coshiloco\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 774,\n            \"name\": \"blfuentes\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 775,\n            \"name\": \"juxxon23\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 776,\n            \"name\": \"lesterdavid31\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 777,\n            \"name\": \"dylanb55\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 778,\n            \"name\": \"matc-channel\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 779,\n            \"name\": \"beonzj\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 780,\n            \"name\": \"misaelbentperez\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 781,\n            \"name\": \"frangarmez21\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 782,\n            \"name\": \"juanmjimenezs\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 783,\n            \"name\": \"vandresca\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 784,\n            \"name\": \"mantaras96\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 785,\n            \"name\": \"nikorasu-d\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 786,\n            \"name\": \"mellamoomar\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 787,\n            \"name\": \"marialunatito\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 788,\n            \"name\": \"edaagapu\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 789,\n            \"name\": \"hernanr\",\n            \"count\": 3,\n            \"languages\": 1\n        },\n        {\n            \"order\": 790,\n            \"name\": \"andreessj\",\n            \"count\": 2,\n            \"languages\": 2\n        },\n        {\n            \"order\": 791,\n            \"name\": \"juan-wills\",\n            \"count\": 2,\n            \"languages\": 2\n        },\n        {\n            \"order\": 792,\n            \"name\": \"ct-zodiako\",\n            \"count\": 2,\n            \"languages\": 2\n        },\n        {\n            \"order\": 793,\n            \"name\": \"devvdroid01\",\n            \"count\": 2,\n            \"languages\": 2\n        },\n        {\n            \"order\": 794,\n            \"name\": \"lurtur\",\n            \"count\": 2,\n            \"languages\": 2\n        },\n        {\n            \"order\": 795,\n            \"name\": \"ddanone\",\n            \"count\": 2,\n            \"languages\": 2\n        },\n        {\n            \"order\": 796,\n            \"name\": \"lemito66\",\n            \"count\": 2,\n            \"languages\": 2\n        },\n        {\n            \"order\": 797,\n            \"name\": \"angel-alvarez-dev\",\n            \"count\": 2,\n            \"languages\": 2\n        },\n        {\n            \"order\": 798,\n            \"name\": \"lilberick\",\n            \"count\": 2,\n            \"languages\": 2\n        },\n        {\n            \"order\": 799,\n            \"name\": \"berentolkien\",\n            \"count\": 2,\n            \"languages\": 2\n        },\n        {\n            \"order\": 800,\n            \"name\": \"jmofuture\",\n            \"count\": 2,\n            \"languages\": 2\n        },\n        {\n            \"order\": 801,\n            \"name\": \"manueld95\",\n            \"count\": 2,\n            \"languages\": 2\n        },\n        {\n            \"order\": 802,\n            \"name\": \"diegoasebey\",\n            \"count\": 2,\n            \"languages\": 2\n        },\n        {\n            \"order\": 803,\n            \"name\": \"chuanmi\",\n            \"count\": 2,\n            \"languages\": 2\n        },\n        {\n            \"order\": 804,\n            \"name\": \"carresoft\",\n            \"count\": 2,\n            \"languages\": 2\n        },\n        {\n            \"order\": 805,\n            \"name\": \"caleb-acarapi\",\n            \"count\": 2,\n            \"languages\": 2\n        },\n        {\n            \"order\": 806,\n            \"name\": \"hackyn3t\",\n            \"count\": 2,\n            \"languages\": 2\n        },\n        {\n            \"order\": 807,\n            \"name\": \"raghnus\",\n            \"count\": 2,\n            \"languages\": 2\n        },\n        {\n            \"order\": 808,\n            \"name\": \"felipedev303\",\n            \"count\": 2,\n            \"languages\": 2\n        },\n        {\n            \"order\": 809,\n            \"name\": \"tecfer\",\n            \"count\": 2,\n            \"languages\": 2\n        },\n        {\n            \"order\": 810,\n            \"name\": \"camiloforero1997\",\n            \"count\": 2,\n            \"languages\": 2\n        },\n        {\n            \"order\": 811,\n            \"name\": \"albertosogasol\",\n            \"count\": 2,\n            \"languages\": 2\n        },\n        {\n            \"order\": 812,\n            \"name\": \"claudio-ortiz-dev\",\n            \"count\": 2,\n            \"languages\": 2\n        },\n        {\n            \"order\": 813,\n            \"name\": \"jorgesilencio\",\n            \"count\": 2,\n            \"languages\": 2\n        },\n        {\n            \"order\": 814,\n            \"name\": \"gianninagit\",\n            \"count\": 2,\n            \"languages\": 2\n        },\n        {\n            \"order\": 815,\n            \"name\": \"raul-progr\",\n            \"count\": 2,\n            \"languages\": 2\n        },\n        {\n            \"order\": 816,\n            \"name\": \"akaidmaru\",\n            \"count\": 2,\n            \"languages\": 2\n        },\n        {\n            \"order\": 817,\n            \"name\": \"nievesyonathan\",\n            \"count\": 2,\n            \"languages\": 2\n        },\n        {\n            \"order\": 818,\n            \"name\": \"ismaelmatiz\",\n            \"count\": 2,\n            \"languages\": 2\n        },\n        {\n            \"order\": 819,\n            \"name\": \"enrgarvic\",\n            \"count\": 2,\n            \"languages\": 2\n        },\n        {\n            \"order\": 820,\n            \"name\": \"elsanty08\",\n            \"count\": 2,\n            \"languages\": 2\n        },\n        {\n            \"order\": 821,\n            \"name\": \"sgb004\",\n            \"count\": 2,\n            \"languages\": 2\n        },\n        {\n            \"order\": 822,\n            \"name\": \"alexsamboy\",\n            \"count\": 2,\n            \"languages\": 2\n        },\n        {\n            \"order\": 823,\n            \"name\": \"jovany-java\",\n            \"count\": 2,\n            \"languages\": 2\n        },\n        {\n            \"order\": 824,\n            \"name\": \"jrvdev\",\n            \"count\": 2,\n            \"languages\": 2\n        },\n        {\n            \"order\": 825,\n            \"name\": \"lydaf\",\n            \"count\": 2,\n            \"languages\": 2\n        },\n        {\n            \"order\": 826,\n            \"name\": \"jurgen-alfaro\",\n            \"count\": 2,\n            \"languages\": 2\n        },\n        {\n            \"order\": 827,\n            \"name\": \"jlcareglio\",\n            \"count\": 2,\n            \"languages\": 2\n        },\n        {\n            \"order\": 828,\n            \"name\": \"joseptarres\",\n            \"count\": 2,\n            \"languages\": 2\n        },\n        {\n            \"order\": 829,\n            \"name\": \"juancamilogomezalvarez\",\n            \"count\": 2,\n            \"languages\": 2\n        },\n        {\n            \"order\": 830,\n            \"name\": \"rickmij\",\n            \"count\": 2,\n            \"languages\": 2\n        },\n        {\n            \"order\": 831,\n            \"name\": \"rcellas\",\n            \"count\": 2,\n            \"languages\": 2\n        },\n        {\n            \"order\": 832,\n            \"name\": \"jhonatanmustiolacas\",\n            \"count\": 2,\n            \"languages\": 2\n        },\n        {\n            \"order\": 833,\n            \"name\": \"diegosilval\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 834,\n            \"name\": \"raulallue\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 835,\n            \"name\": \"aserranot\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 836,\n            \"name\": \"hendrycode\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 837,\n            \"name\": \"vdroiid\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 838,\n            \"name\": \"roy-garcia-rendon\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 839,\n            \"name\": \"bytiagoghost\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 840,\n            \"name\": \"luciarf\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 841,\n            \"name\": \"yowcloud\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 842,\n            \"name\": \"lorenamesa\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 843,\n            \"name\": \"hawkbott\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 844,\n            \"name\": \"tiaguiito3\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 845,\n            \"name\": \"elmarqueli\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 846,\n            \"name\": \"reaien\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 847,\n            \"name\": \"poetry0354\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 848,\n            \"name\": \"tomasmarquez81\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 849,\n            \"name\": \"santiagocuevas2003\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 850,\n            \"name\": \"rikar20\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 851,\n            \"name\": \"lmedina96\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 852,\n            \"name\": \"jmichael39\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 853,\n            \"name\": \"deivisaherreraj\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 854,\n            \"name\": \"lioarce01\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 855,\n            \"name\": \"zonnen69\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 856,\n            \"name\": \"lordzzz777\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 857,\n            \"name\": \"angelargumedo\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 858,\n            \"name\": \"nachodev7\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 859,\n            \"name\": \"eckoseal89\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 860,\n            \"name\": \"adogdev\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 861,\n            \"name\": \"tashidian\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 862,\n            \"name\": \"berlinbeltranavila\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 863,\n            \"name\": \"adirv5\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 864,\n            \"name\": \"ramon01-ing\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 865,\n            \"name\": \"aloween\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 866,\n            \"name\": \"dans182\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 867,\n            \"name\": \"monisstar\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 868,\n            \"name\": \"fjsubero\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 869,\n            \"name\": \"nevaito\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 870,\n            \"name\": \"jowelgod\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 871,\n            \"name\": \"print-alan\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 872,\n            \"name\": \"xcoreyx0\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 873,\n            \"name\": \"dokeys28\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 874,\n            \"name\": \"nach012\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 875,\n            \"name\": \"lauradiazm29\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 876,\n            \"name\": \"eriickm\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 877,\n            \"name\": \"lattemiguelangel\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 878,\n            \"name\": \"pedrojog\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 879,\n            \"name\": \"s384\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 880,\n            \"name\": \"mick2332-q\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 881,\n            \"name\": \"culebropalido\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 882,\n            \"name\": \"fernandoatello\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 883,\n            \"name\": \"inf015\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 884,\n            \"name\": \"christiancoc\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 885,\n            \"name\": \"santiagodc8\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 886,\n            \"name\": \"kateamador\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 887,\n            \"name\": \"josegago27\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 888,\n            \"name\": \"steven9708m\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 889,\n            \"name\": \"pakomor\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 890,\n            \"name\": \"martinzeta\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 891,\n            \"name\": \"zeti1231\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 892,\n            \"name\": \"etrauco\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 893,\n            \"name\": \"oscardrd\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 894,\n            \"name\": \"lilitr09\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 895,\n            \"name\": \"baauus\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 896,\n            \"name\": \"fabianpa505\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 897,\n            \"name\": \"e-techgod\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 898,\n            \"name\": \"victore16\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 899,\n            \"name\": \"tic4\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 900,\n            \"name\": \"lordaguakate\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 901,\n            \"name\": \"soydianaibarra\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 902,\n            \"name\": \"noaregui\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 903,\n            \"name\": \"julind0\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 904,\n            \"name\": \"dariangl\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 905,\n            \"name\": \"soyjosep\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 906,\n            \"name\": \"zalazarmartin\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 907,\n            \"name\": \"adridlth\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 908,\n            \"name\": \"kcx46\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 909,\n            \"name\": \"ignaciogm1973\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 910,\n            \"name\": \"sofia-d-p\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 911,\n            \"name\": \"snaoj\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 912,\n            \"name\": \" jesusacst\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 913,\n            \"name\": \"ziellucio01\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 914,\n            \"name\": \"yuliobno\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 915,\n            \"name\": \"aboredllama\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 916,\n            \"name\": \"csaraugusto2\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 917,\n            \"name\": \"winstons6079\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 918,\n            \"name\": \"josephfaster\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 919,\n            \"name\": \"hendryavila\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 920,\n            \"name\": \"codeskin-r\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 921,\n            \"name\": \"pablosalme\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 922,\n            \"name\": \"rojasricoo\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 923,\n            \"name\": \"anblackter\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 924,\n            \"name\": \"varoblanco\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 925,\n            \"name\": \"vesubius\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 926,\n            \"name\": \"soydaviddev\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 927,\n            \"name\": \"jsacristanbeltri\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 928,\n            \"name\": \"jmontoyac\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 929,\n            \"name\": \"gregfc95\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 930,\n            \"name\": \"blonsh\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 931,\n            \"name\": \"freyfonseca\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 932,\n            \"name\": \"patrickfer99\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 933,\n            \"name\": \"miguelberrio0810\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 934,\n            \"name\": \"josue-py\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 935,\n            \"name\": \"juanseevn\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 936,\n            \"name\": \"alejandro-mantilla\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 937,\n            \"name\": \"alejandrovelasquezr\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 938,\n            \"name\": \"carlosmarte23\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 939,\n            \"name\": \"cipollalucas\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 940,\n            \"name\": \"martaprog\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 941,\n            \"name\": \"deriancastillop\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 942,\n            \"name\": \"dota43ver\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 943,\n            \"name\": \"josandgon12\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 944,\n            \"name\": \"aegpgrafologo\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 945,\n            \"name\": \"victorpolo28\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 946,\n            \"name\": \"danymarsan1\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 947,\n            \"name\": \"arhl2023\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 948,\n            \"name\": \"b3nkos\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 949,\n            \"name\": \"julianjra\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 950,\n            \"name\": \"francescvm8\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 951,\n            \"name\": \"marioyellowy\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 952,\n            \"name\": \"rumacar05\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 953,\n            \"name\": \"anaroncero\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 954,\n            \"name\": \"peeanoot\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 955,\n            \"name\": \"ismx17\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 956,\n            \"name\": \"hersac\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 957,\n            \"name\": \"ariaslopez\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 958,\n            \"name\": \"ricarditodev\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 959,\n            \"name\": \"isidrojng\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 960,\n            \"name\": \"jcknot\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 961,\n            \"name\": \"zemanue\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 962,\n            \"name\": \"coronelsam\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 963,\n            \"name\": \"dotero-dciencia\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 964,\n            \"name\": \"0pio\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 965,\n            \"name\": \"whiterunjarl\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 966,\n            \"name\": \"itsthemasii\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 967,\n            \"name\": \"porto1090\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 968,\n            \"name\": \"peibolstrike\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 969,\n            \"name\": \"nahuelborromeo\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 970,\n            \"name\": \"marcsl2014\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 971,\n            \"name\": \"samuel20-dev\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 972,\n            \"name\": \"johannhsdev\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 973,\n            \"name\": \"jago86\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 974,\n            \"name\": \"maussho\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 975,\n            \"name\": \"cristiansystem\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 976,\n            \"name\": \"evelynnobile\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 977,\n            \"name\": \"vikkanh\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 978,\n            \"name\": \"saracorraless\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 979,\n            \"name\": \"crisdev3\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 980,\n            \"name\": \"frealexandro\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 981,\n            \"name\": \"elpeque29\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 982,\n            \"name\": \"juaruibr\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 983,\n            \"name\": \"diegokarabin\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 984,\n            \"name\": \"lestaat\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 985,\n            \"name\": \"zerpajose\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 986,\n            \"name\": \"gugliio\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 987,\n            \"name\": \"roilhi\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 988,\n            \"name\": \"nathanaellara\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 989,\n            \"name\": \"barbarasg92\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 990,\n            \"name\": \"kraltar\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 991,\n            \"name\": \"waldid32\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 992,\n            \"name\": \"navarroemiliano\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 993,\n            \"name\": \"dararod\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 994,\n            \"name\": \"fsfigueroa77\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 995,\n            \"name\": \"fefestuve\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 996,\n            \"name\": \"julian-arias\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 997,\n            \"name\": \"hazartd\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 998,\n            \"name\": \"protpus98\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 999,\n            \"name\": \"nicolastapiasanz\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1000,\n            \"name\": \"freddyasierraj\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1001,\n            \"name\": \"vicgallego\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1002,\n            \"name\": \"gomezcamilo9701\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1003,\n            \"name\": \"lordibzn\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1004,\n            \"name\": \"reanthonyh\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1005,\n            \"name\": \"christianhernandezb\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1006,\n            \"name\": \"mbbellini\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1007,\n            \"name\": \"januarasprilla\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1008,\n            \"name\": \"franciscocuminilondero\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1009,\n            \"name\": \"wesborland-github\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1010,\n            \"name\": \"esdras-josue\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1011,\n            \"name\": \"08bll\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1012,\n            \"name\": \"jeisonredondo\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1013,\n            \"name\": \"jhonf1992\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1014,\n            \"name\": \"andnikdev\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1015,\n            \"name\": \"doblea74\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1016,\n            \"name\": \"srsury\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1017,\n            \"name\": \"fiedri\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1018,\n            \"name\": \"glaboryp\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1019,\n            \"name\": \"samrdx\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1020,\n            \"name\": \"alanox1\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1021,\n            \"name\": \"davidgar42\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1022,\n            \"name\": \"cpcarlosprieto\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1023,\n            \"name\": \"angelvelasco1\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1024,\n            \"name\": \"jaimemunozdev\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1025,\n            \"name\": \"farthaz\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1026,\n            \"name\": \"jfigueroa24\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1027,\n            \"name\": \"haryblanco20\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1028,\n            \"name\": \"elitedev-44\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1029,\n            \"name\": \"akzorla\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1030,\n            \"name\": \"pogo182028\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1031,\n            \"name\": \"murquisdev\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1032,\n            \"name\": \"mickel-arroz\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1033,\n            \"name\": \"crisscde\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1034,\n            \"name\": \"gerardovguzman\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1035,\n            \"name\": \"ovjohn\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1036,\n            \"name\": \"willicar27\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1037,\n            \"name\": \"jrcoste6\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1038,\n            \"name\": \"frankqv\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1039,\n            \"name\": \"daxterdev\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1040,\n            \"name\": \"cesarocbu\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1041,\n            \"name\": \"aleoe01\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1042,\n            \"name\": \"bmayo08\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1043,\n            \"name\": \"christianumb\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1044,\n            \"name\": \"k4rv3r\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1045,\n            \"name\": \"nestord23\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1046,\n            \"name\": \"soldochris\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1047,\n            \"name\": \"davhage\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1048,\n            \"name\": \"evaristojs\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1049,\n            \"name\": \"matiasfarfan89\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1050,\n            \"name\": \"hugoluqueperez\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1051,\n            \"name\": \"erikayeah\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1052,\n            \"name\": \"valeriatorrealba\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1053,\n            \"name\": \"herwingx-dev\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1054,\n            \"name\": \"anjamape1972\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1055,\n            \"name\": \"elimejiap\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1056,\n            \"name\": \"memogv\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1057,\n            \"name\": \"rikar2o\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1058,\n            \"name\": \"leonardo291024\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1059,\n            \"name\": \"juangomezn\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1060,\n            \"name\": \"santiagocamachocamino\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1061,\n            \"name\": \"dhbellini\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1062,\n            \"name\": \"jorge186414\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1063,\n            \"name\": \"miguelrejon96\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1064,\n            \"name\": \"rolo27s\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1065,\n            \"name\": \"jolimadev2\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1066,\n            \"name\": \"nxl22\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1067,\n            \"name\": \"juandbc\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1068,\n            \"name\": \"raul-anton-2005\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1069,\n            \"name\": \"vecinacoo\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1070,\n            \"name\": \"armentaangel\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1071,\n            \"name\": \"bereverte\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1072,\n            \"name\": \"juamax2\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1073,\n            \"name\": \"frannmv\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1074,\n            \"name\": \"edisonlmg\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1075,\n            \"name\": \"rrcoder\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1076,\n            \"name\": \"sdm29gh\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1077,\n            \"name\": \"nandaalf\",\n            \"count\": 2,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1078,\n            \"name\": \"raynerpv2022_1\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1079,\n            \"name\": \"kerunaru\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1080,\n            \"name\": \"francomyburg\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1081,\n            \"name\": \"miguel2rar\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1082,\n            \"name\": \"agustinfccll\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1083,\n            \"name\": \"eamartin\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1084,\n            \"name\": \"evilpodato04\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1085,\n            \"name\": \"gabriel-dangelo\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1086,\n            \"name\": \"anitandil\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1087,\n            \"name\": \"miquelrr\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1088,\n            \"name\": \"neicervb\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1089,\n            \"name\": \"josephinoo\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1090,\n            \"name\": \"diegoguaman\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1091,\n            \"name\": \"larasoft123\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1092,\n            \"name\": \"tilordqwerty\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1093,\n            \"name\": \"cyberingeniero\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1094,\n            \"name\": \"complex.303\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1095,\n            \"name\": \"alfaroo1\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1096,\n            \"name\": \"drolo18\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1097,\n            \"name\": \"ezecc-eze\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1098,\n            \"name\": \"rusian69\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1099,\n            \"name\": \"emilceinfante\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1100,\n            \"name\": \"vickalc\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1101,\n            \"name\": \"jaldana1006\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1102,\n            \"name\": \"riukac\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1103,\n            \"name\": \"wijimenezz\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1104,\n            \"name\": \"rafapg93\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1105,\n            \"name\": \"nicoloboo02\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1106,\n            \"name\": \"sergiopq\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1107,\n            \"name\": \"rocha30\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1108,\n            \"name\": \"markayala13\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1109,\n            \"name\": \"jony-english22\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1110,\n            \"name\": \"righelch\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1111,\n            \"name\": \"angeloro\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1112,\n            \"name\": \"albertovf\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1113,\n            \"name\": \"deathbat00\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1114,\n            \"name\": \"analauradb\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1115,\n            \"name\": \"acirdeveloper\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1116,\n            \"name\": \"orzefox\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1117,\n            \"name\": \"marcosalvarezcalabria\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1118,\n            \"name\": \"edgarmedranoa\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1119,\n            \"name\": \"balta16\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1120,\n            \"name\": \"sve-nnn\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1121,\n            \"name\": \"franciscorocha\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1122,\n            \"name\": \"sy-codelico\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1123,\n            \"name\": \"emiliordev\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1124,\n            \"name\": \"miguelangelmtz\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1125,\n            \"name\": \"davidbastosg\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1126,\n            \"name\": \"dandreara-boop\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1127,\n            \"name\": \"matinbohorquez\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1128,\n            \"name\": \"franespina\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1129,\n            \"name\": \"santyjl44\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1130,\n            \"name\": \"zebenpixel\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1131,\n            \"name\": \"luism95\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1132,\n            \"name\": \"dgquintero\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1133,\n            \"name\": \"torvicv\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1134,\n            \"name\": \"javosss\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1135,\n            \"name\": \"markbus-ai\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1136,\n            \"name\": \"opahostil\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1137,\n            \"name\": \"eduardo282\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1138,\n            \"name\": \"nightmare79\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1139,\n            \"name\": \"cub-tor\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1140,\n            \"name\": \"vikernes27666\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1141,\n            \"name\": \"carlosmperezm\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1142,\n            \"name\": \"mmariob\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1143,\n            \"name\": \"emanuelgauler\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1144,\n            \"name\": \"daichiko\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1145,\n            \"name\": \"girngoma\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1146,\n            \"name\": \"juampaweb\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1147,\n            \"name\": \"alecraft8\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1148,\n            \"name\": \"arperezinf\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1149,\n            \"name\": \"greenalpak\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1150,\n            \"name\": \"natanaelzubiri\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1151,\n            \"name\": \"jgarteag\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1152,\n            \"name\": \"diazyy\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1153,\n            \"name\": \"manuelrtl\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1154,\n            \"name\": \"smelo0\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1155,\n            \"name\": \"mylorobot2024\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1156,\n            \"name\": \"chrispro-afk\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1157,\n            \"name\": \"sofiamfernandez\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1158,\n            \"name\": \"demegorash\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1159,\n            \"name\": \"dacaldev\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1160,\n            \"name\": \"adricego\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1161,\n            \"name\": \"alejandro000\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1162,\n            \"name\": \"henrydavidprimera\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1163,\n            \"name\": \"vice29\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1164,\n            \"name\": \"josmarobh\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1165,\n            \"name\": \"eljavi0\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1166,\n            \"name\": \"migue1lll\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1167,\n            \"name\": \"niconbravo\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1168,\n            \"name\": \"carlosbb70\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1169,\n            \"name\": \"joamgreen\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1170,\n            \"name\": \"turudev1979\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1171,\n            \"name\": \"juli-m4\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1172,\n            \"name\": \"jabgnecco\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1173,\n            \"name\": \"miguelangel861\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1174,\n            \"name\": \"neusier101\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1175,\n            \"name\": \"jean1129\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1176,\n            \"name\": \"walyfigueroa\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1177,\n            \"name\": \"wilsonbarrera\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1178,\n            \"name\": \"amitchellg\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1179,\n            \"name\": \"manueldenisdev\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1180,\n            \"name\": \"jgregoris\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1181,\n            \"name\": \"billy-ugalde\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1182,\n            \"name\": \"pedroomar23 2\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1183,\n            \"name\": \"crisky94\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1184,\n            \"name\": \"salas89\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1185,\n            \"name\": \"jalonso76\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1186,\n            \"name\": \"cbobadil2006\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1187,\n            \"name\": \"vickalck\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1188,\n            \"name\": \"latorredev\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1189,\n            \"name\": \"vsxr\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1190,\n            \"name\": \"manuu42\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1191,\n            \"name\": \"humbertomorales1416\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1192,\n            \"name\": \"marcos0803\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1193,\n            \"name\": \"magicdev-rc\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1194,\n            \"name\": \"jgcmurcia\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1195,\n            \"name\": \"amg-aa\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1196,\n            \"name\": \"copamire\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1197,\n            \"name\": \"jm158960-beep\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1198,\n            \"name\": \"xalejandrow\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1199,\n            \"name\": \"oxtornado\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1200,\n            \"name\": \"devjerez\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1201,\n            \"name\": \"nicolascalderonbolivar\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1202,\n            \"name\": \"trasherzzzz\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1203,\n            \"name\": \"jorlegp\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1204,\n            \"name\": \"alejarandro\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1205,\n            \"name\": \"neshurtado\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1206,\n            \"name\": \"aldousfv\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1207,\n            \"name\": \"bhairava11\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1208,\n            \"name\": \"jrgranadosb\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1209,\n            \"name\": \"obed-tc\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1210,\n            \"name\": \"fabiancz95\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1211,\n            \"name\": \"osneidert\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1212,\n            \"name\": \"dieguillo1985\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1213,\n            \"name\": \"ingothik\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1214,\n            \"name\": \"cesar-rosado\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1215,\n            \"name\": \"josem17-cyber\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1216,\n            \"name\": \"luxilith\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1217,\n            \"name\": \"gyser17\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1218,\n            \"name\": \"anexo01\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1219,\n            \"name\": \"javiers123\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1220,\n            \"name\": \"cris10026\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1221,\n            \"name\": \"g4nd4lf\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1222,\n            \"name\": \"juand1q94\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1223,\n            \"name\": \"vmarialuzm\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1224,\n            \"name\": \"caterinaarata\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1225,\n            \"name\": \"m4xxdev\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1226,\n            \"name\": \"francgci\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1227,\n            \"name\": \"franmux01\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1228,\n            \"name\": \"josuelopez5\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1229,\n            \"name\": \"pandawangt\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1230,\n            \"name\": \"santifer26\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1231,\n            \"name\": \"djordanv\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1232,\n            \"name\": \"hardynsnet\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1233,\n            \"name\": \"emmanuelmmontesinos \",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1234,\n            \"name\": \"zka21\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1235,\n            \"name\": \"nico70012\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1236,\n            \"name\": \"miguezzb\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1237,\n            \"name\": \"dakkaj\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1238,\n            \"name\": \"juan-cruz01\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1239,\n            \"name\": \"yamiyugi25\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1240,\n            \"name\": \"adry2024salt\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1241,\n            \"name\": \"jeisson-castro\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1242,\n            \"name\": \"aztharoth87\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1243,\n            \"name\": \"ihunivers\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1244,\n            \"name\": \"claralopezgonzalez\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1245,\n            \"name\": \"kkstrofico\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1246,\n            \"name\": \"fergz1988\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1247,\n            \"name\": \"rastaxico\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1248,\n            \"name\": \"tecno85\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1249,\n            \"name\": \"therealinfinity2\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1250,\n            \"name\": \"kai2908\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1251,\n            \"name\": \"bassalex27\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1252,\n            \"name\": \"randy7394\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1253,\n            \"name\": \"jordevoro\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1254,\n            \"name\": \"x1ph3r\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1255,\n            \"name\": \"kata-lg\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1256,\n            \"name\": \"gersonoroz\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1257,\n            \"name\": \"judithernandez\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1258,\n            \"name\": \"adamtormer\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1259,\n            \"name\": \"ale_cervi\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1260,\n            \"name\": \"zyodev1\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1261,\n            \"name\": \"cesir72\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1262,\n            \"name\": \"lauvis11\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1263,\n            \"name\": \"initkey\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1264,\n            \"name\": \"nuoldev\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1265,\n            \"name\": \"dvidmdina\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1266,\n            \"name\": \"breiner712\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1267,\n            \"name\": \"gl-informatica\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1268,\n            \"name\": \"luisfglondono\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1269,\n            \"name\": \"luiscalle17\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1270,\n            \"name\": \"sharguidev\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1271,\n            \"name\": \"theewiick\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1272,\n            \"name\": \"luceldasilva\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1273,\n            \"name\": \"giovanni-schmaily\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1274,\n            \"name\": \"perezfacundo\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1275,\n            \"name\": \"johannmanrique\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1276,\n            \"name\": \"xcortes\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1277,\n            \"name\": \"lluistech\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1278,\n            \"name\": \"andres-54-coder\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1279,\n            \"name\": \"ndepaul82\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1280,\n            \"name\": \"julioorozco05\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1281,\n            \"name\": \"luisangeles20\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1282,\n            \"name\": \"eddyfals0\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1283,\n            \"name\": \"omar8102\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1284,\n            \"name\": \"juanalbornoz32\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1285,\n            \"name\": \"marcelinoarias369\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1286,\n            \"name\": \"j0nvthvn\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1287,\n            \"name\": \"sherete2000\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1288,\n            \"name\": \"dieggop0\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1289,\n            \"name\": \"erickcis\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1290,\n            \"name\": \"experthacker444\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1291,\n            \"name\": \"jereaguilar\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1292,\n            \"name\": \"dfnevar\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1293,\n            \"name\": \"geridage\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1294,\n            \"name\": \"byte-punk\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1295,\n            \"name\": \"hectralvz\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1296,\n            \"name\": \"devkenn\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1297,\n            \"name\": \"pr1de-23\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1298,\n            \"name\": \"claudios1980\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1299,\n            \"name\": \"javict14\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1300,\n            \"name\": \"howlett9999\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1301,\n            \"name\": \"hermanyepes\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1302,\n            \"name\": \"eddyelx\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1303,\n            \"name\": \"dgroes\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1304,\n            \"name\": \"juananguloardila\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1305,\n            \"name\": \"wallsified\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1306,\n            \"name\": \"smsprogramacion1236\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1307,\n            \"name\": \"josueperez004\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1308,\n            \"name\": \"ycmorejon\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1309,\n            \"name\": \"sergiomhernandez\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1310,\n            \"name\": \"e-xtian\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1311,\n            \"name\": \"gomezjustine\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1312,\n            \"name\": \"gmedinat911\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1313,\n            \"name\": \"vicvilla30\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1314,\n            \"name\": \"luisantoniob18\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1315,\n            \"name\": \"leo18q\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1316,\n            \"name\": \"leanaren\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1317,\n            \"name\": \"javirr4\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1318,\n            \"name\": \"facundorsabia\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1319,\n            \"name\": \"krisipo\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1320,\n            \"name\": \"mrf1989\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1321,\n            \"name\": \"snowcardenas\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1322,\n            \"name\": \"masenace\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1323,\n            \"name\": \"mamartinez14\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1324,\n            \"name\": \"xtinarita\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1325,\n            \"name\": \"dmiaan\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1326,\n            \"name\": \"trosky-wolf\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1327,\n            \"name\": \"chema-dw\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1328,\n            \"name\": \"hanns87\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1329,\n            \"name\": \"sbngl\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1330,\n            \"name\": \"and-y21\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1331,\n            \"name\": \"sergiovelayos\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1332,\n            \"name\": \"neyan52\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1333,\n            \"name\": \"tarlomin\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1334,\n            \"name\": \"nyxtbytex\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1335,\n            \"name\": \"pol-fradera\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1336,\n            \"name\": \"cit-star\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1337,\n            \"name\": \"arturodlapaz17\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1338,\n            \"name\": \"perla-zg\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1339,\n            \"name\": \"manueldes27\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1340,\n            \"name\": \"033a130\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1341,\n            \"name\": \"v0l0v\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1342,\n            \"name\": \"akrxb\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1343,\n            \"name\": \"ariel-plaza\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1344,\n            \"name\": \"ambrociojrdelacruz\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1345,\n            \"name\": \"damaas1925-alt\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1346,\n            \"name\": \"adcarret\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1347,\n            \"name\": \"decinx1\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1348,\n            \"name\": \"isaacdci\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1349,\n            \"name\": \"juang482\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1350,\n            \"name\": \"cd1974\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1351,\n            \"name\": \"snowale\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1352,\n            \"name\": \"cristianfer1991\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1353,\n            \"name\": \"adrianruizc\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1354,\n            \"name\": \"sherkla12e\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1355,\n            \"name\": \"mjordanaam\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1356,\n            \"name\": \"yeisongil\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1357,\n            \"name\": \"kronoscba\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1358,\n            \"name\": \"zeraven09\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1359,\n            \"name\": \"jorge23-blip\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1360,\n            \"name\": \"josded21\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1361,\n            \"name\": \"eduardoherrarte\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1362,\n            \"name\": \"salazar-sys\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1363,\n            \"name\": \"miguelmancebo\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1364,\n            \"name\": \"danidan1214\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1365,\n            \"name\": \"charly024\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1366,\n            \"name\": \"90dread\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1367,\n            \"name\": \"pepitoladino\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1368,\n            \"name\": \"ferngpv\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1369,\n            \"name\": \"jafuma0320\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1370,\n            \"name\": \"xhinto\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1371,\n            \"name\": \"testiman-78\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1372,\n            \"name\": \"jchernandez87\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1373,\n            \"name\": \"jordanurzua\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1374,\n            \"name\": \"javidp01\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1375,\n            \"name\": \"johao23\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1376,\n            \"name\": \"lisandroarnodo\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1377,\n            \"name\": \"pushodev\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1378,\n            \"name\": \"aritapia19\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1379,\n            \"name\": \"betulioo\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1380,\n            \"name\": \"sagro27\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1381,\n            \"name\": \"ejaram3\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1382,\n            \"name\": \"paolof16\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1383,\n            \"name\": \"lagoausente\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1384,\n            \"name\": \"ignacioskm\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1385,\n            \"name\": \"ysmoraa\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1386,\n            \"name\": \"fernando0gallego\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1387,\n            \"name\": \"cisneros2404\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1388,\n            \"name\": \"pepemn23\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1389,\n            \"name\": \"acobo3\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1390,\n            \"name\": \"carlostoledoe\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1391,\n            \"name\": \"gilbertho502\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1392,\n            \"name\": \"jansua\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1393,\n            \"name\": \"davidgramiro\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1394,\n            \"name\": \"lean993\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1395,\n            \"name\": \"m4nu3il\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1396,\n            \"name\": \"rodrigolopez25\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1397,\n            \"name\": \"jandortiz\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1398,\n            \"name\": \"neftalyr\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1399,\n            \"name\": \"cristianvergaraf\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1400,\n            \"name\": \"harry-gns\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1401,\n            \"name\": \"hnaranjog\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1402,\n            \"name\": \"vomsavc\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1403,\n            \"name\": \"dimanu-py\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1404,\n            \"name\": \"joselin0407\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1405,\n            \"name\": \"kshields51\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1406,\n            \"name\": \"daftfunked\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1407,\n            \"name\": \"deivimiller\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1408,\n            \"name\": \"yetlanezils\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1409,\n            \"name\": \"eatsangels\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1410,\n            \"name\": \"lizzymaken\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1411,\n            \"name\": \"tallahashee\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1412,\n            \"name\": \"pablom-2015\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1413,\n            \"name\": \"diegogomezcor4\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1414,\n            \"name\": \"derkopath\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1415,\n            \"name\": \"robermejia\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1416,\n            \"name\": \"nicofgt\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1417,\n            \"name\": \"zyn7e\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1418,\n            \"name\": \"pvigo10\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1419,\n            \"name\": \"bycris13\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1420,\n            \"name\": \"gianellannie\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1421,\n            \"name\": \"ev3thlm\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1422,\n            \"name\": \"danisaurio94\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1423,\n            \"name\": \"algeloro\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1424,\n            \"name\": \"sxxnzdev\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1425,\n            \"name\": \"iguerrerov\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1426,\n            \"name\": \"angeldevsarrollo\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1427,\n            \"name\": \"victhorma\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1428,\n            \"name\": \"obidiotimoteo\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1429,\n            \"name\": \"det3992\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1430,\n            \"name\": \"canrosss\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1431,\n            \"name\": \"cristobalbelcor\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1432,\n            \"name\": \"nazhiravila\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1433,\n            \"name\": \"nolemoon\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1434,\n            \"name\": \"chrystiancalderon\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1435,\n            \"name\": \"javiir\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1436,\n            \"name\": \"matisuarezm\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1437,\n            \"name\": \"jose-zga\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1438,\n            \"name\": \"diegopardomontero\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1439,\n            \"name\": \"hanzd07\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1440,\n            \"name\": \"adriansaint07\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1441,\n            \"name\": \"santiagopereiraviroga\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1442,\n            \"name\": \"jossfullstack\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1443,\n            \"name\": \"devsantiagoo\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1444,\n            \"name\": \"xhaloidx\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1445,\n            \"name\": \"maximilianofuentesalcocer-cibern\\u00e9tico\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1446,\n            \"name\": \"danycrk\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1447,\n            \"name\": \"vikinghost\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1448,\n            \"name\": \"rreyes0424\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1449,\n            \"name\": \"queralesdev\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1450,\n            \"name\": \"ppsystemsmx\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1451,\n            \"name\": \"dovinhoyos\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1452,\n            \"name\": \"cybersutro\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1453,\n            \"name\": \"lautimorales\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1454,\n            \"name\": \"mewynt\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1455,\n            \"name\": \"gipsydavy\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1456,\n            \"name\": \"josepilco7501\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1457,\n            \"name\": \"alefine\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1458,\n            \"name\": \"chalaito88\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1459,\n            \"name\": \"lizandev\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1460,\n            \"name\": \"mathiur\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1461,\n            \"name\": \"jaimenar\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1462,\n            \"name\": \"maynor06\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1463,\n            \"name\": \"deathbato\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1464,\n            \"name\": \"josuesaga14\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1465,\n            \"name\": \"adriannq99\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1466,\n            \"name\": \"sanuka78\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1467,\n            \"name\": \"antoniojzp86\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1468,\n            \"name\": \"cristian-encalada\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1469,\n            \"name\": \"martinaq\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1470,\n            \"name\": \"brayandelaossa\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1471,\n            \"name\": \"gian247\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1472,\n            \"name\": \"clespinosa2024\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1473,\n            \"name\": \"alexeigio\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1474,\n            \"name\": \"albert-29\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1475,\n            \"name\": \"bohorquezjael\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1476,\n            \"name\": \"durwian\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1477,\n            \"name\": \"rballestercoll\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1478,\n            \"name\": \"feliduarte\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1479,\n            \"name\": \"lewisoneil\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1480,\n            \"name\": \"ivanserran\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1481,\n            \"name\": \"javierincio\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1482,\n            \"name\": \"jaquelinetorres\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1483,\n            \"name\": \"dany3gs\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1484,\n            \"name\": \"fredylopez01\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1485,\n            \"name\": \"adriangonzalezroble\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1486,\n            \"name\": \"jrgim\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1487,\n            \"name\": \"reneguzman7\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1488,\n            \"name\": \"jony_english22\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1489,\n            \"name\": \"alvaropg15\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1490,\n            \"name\": \"samfuentes11\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1491,\n            \"name\": \"serg_pq\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1492,\n            \"name\": \"ignaciiodev\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1493,\n            \"name\": \"benja0501\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1494,\n            \"name\": \"dsmhp0\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1495,\n            \"name\": \"federicolazarte\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1496,\n            \"name\": \"suaveseda\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1497,\n            \"name\": \"frankmon03\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1498,\n            \"name\": \"pguillo\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1499,\n            \"name\": \"robledom10\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1500,\n            \"name\": \"kgrc05\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1501,\n            \"name\": \"eleite_d\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1502,\n            \"name\": \"andresdevp\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1503,\n            \"name\": \"jlrojano\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1504,\n            \"name\": \"v1k770r\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1505,\n            \"name\": \"dariel800xd\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1506,\n            \"name\": \"cristianmr87\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1507,\n            \"name\": \"kennwudi\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1508,\n            \"name\": \"bjchavez\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1509,\n            \"name\": \" shadowsmen-cyber\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1510,\n            \"name\": \"sanet0512\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1511,\n            \"name\": \"kevin05m\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1512,\n            \"name\": \"darkohokage\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1513,\n            \"name\": \"diegomm27\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1514,\n            \"name\": \"fede6299\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1515,\n            \"name\": \"pablo-lnx\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1516,\n            \"name\": \"jrmantilla66\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1517,\n            \"name\": \"roscelidcode\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1518,\n            \"name\": \"over-kr\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1519,\n            \"name\": \"hades-dark-x\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1520,\n            \"name\": \"marcosjarrin\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1521,\n            \"name\": \"sirvega83\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1522,\n            \"name\": \"franpua\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1523,\n            \"name\": \"corvo-99\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1524,\n            \"name\": \"devm0nk3y\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1525,\n            \"name\": \"cardonagustavo\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1526,\n            \"name\": \"danielcastillo1112\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1527,\n            \"name\": \"malkarmah\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1528,\n            \"name\": \"nicolascampos-git\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1529,\n            \"name\": \"palons29\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1530,\n            \"name\": \"jhonnfl\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1531,\n            \"name\": \"zakeyo\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1532,\n            \"name\": \"trollface77\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1533,\n            \"name\": \"rob-gon\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1534,\n            \"name\": \"edm1ya\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1535,\n            \"name\": \"cmahecha291-beep\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1536,\n            \"name\": \"maurspi\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1537,\n            \"name\": \"alexvasquez199914\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1538,\n            \"name\": \"alejandroruiz23\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1539,\n            \"name\": \"jaimesoftdev\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1540,\n            \"name\": \"jarzatedev\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1541,\n            \"name\": \"luisfcaro\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1542,\n            \"name\": \"eloy1290\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1543,\n            \"name\": \"brunom-93\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1544,\n            \"name\": \"franckdot\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1545,\n            \"name\": \"martireyes\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1546,\n            \"name\": \"ca2puntosv\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1547,\n            \"name\": \"luisalberto22\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1548,\n            \"name\": \"bokysherlo\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1549,\n            \"name\": \"braiso-22\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1550,\n            \"name\": \"r-flavio\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1551,\n            \"name\": \"donchuy846\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1552,\n            \"name\": \"davidcv-dev\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1553,\n            \"name\": \"alvarominarro\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1554,\n            \"name\": \"mbmaeso\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1555,\n            \"name\": \"francisleble\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1556,\n            \"name\": \"highscorec1\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1557,\n            \"name\": \"borjadelgadodev\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1558,\n            \"name\": \"deiiviitdev\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1559,\n            \"name\": \"jhordanluyo\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1560,\n            \"name\": \"daniel-cas\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1561,\n            \"name\": \"acirdevelper\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1562,\n            \"name\": \"lara-vel-dev\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1563,\n            \"name\": \"stiware\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1564,\n            \"name\": \"alexisbarradev\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1565,\n            \"name\": \"serg-pq\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1566,\n            \"name\": \"kelvincb\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1567,\n            \"name\": \"tartabullroberto\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1568,\n            \"name\": \"implevacui\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1569,\n            \"name\": \"angelcruzg23\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1570,\n            \"name\": \"juandevian\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1571,\n            \"name\": \"urigroisman\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1572,\n            \"name\": \"van-02\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1573,\n            \"name\": \"x3mboy\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1574,\n            \"name\": \"joferpg\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1575,\n            \"name\": \"franciscokarriere\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1576,\n            \"name\": \"jancalos\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1577,\n            \"name\": \"rulo77\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1578,\n            \"name\": \"gizelads\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1579,\n            \"name\": \"manugonzalito\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1580,\n            \"name\": \"javi8d\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1581,\n            \"name\": \"serg032\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1582,\n            \"name\": \"fhdzleon\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1583,\n            \"name\": \"seigigim\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1584,\n            \"name\": \"azfe\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1585,\n            \"name\": \"jmcavilla\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1586,\n            \"name\": \"axelwestman\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1587,\n            \"name\": \"lucc4sz\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1588,\n            \"name\": \"mauricioyair\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1589,\n            \"name\": \"cibacoa\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1590,\n            \"name\": \"feliaguirre7\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1591,\n            \"name\": \"javodevon\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1592,\n            \"name\": \"deaconst\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1593,\n            \"name\": \"coletonosh\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1594,\n            \"name\": \"is2095\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1595,\n            \"name\": \"marcosapodaca\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1596,\n            \"name\": \"manuhssj\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1597,\n            \"name\": \"paluzz\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1598,\n            \"name\": \"carlitoindev\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1599,\n            \"name\": \"ossytosis\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1600,\n            \"name\": \"marianofernandezs\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1601,\n            \"name\": \"arathhh8\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1602,\n            \"name\": \"theposi\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1603,\n            \"name\": \"omarroman29\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1604,\n            \"name\": \"1cel4nc3\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1605,\n            \"name\": \"vec70rr\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1606,\n            \"name\": \"vinyoles\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1607,\n            \"name\": \"sergio-strazzacappa\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1608,\n            \"name\": \"georgehaz\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1609,\n            \"name\": \"wilibac\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1610,\n            \"name\": \"jcrobles99\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1611,\n            \"name\": \"guufy12\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1612,\n            \"name\": \"wabish0\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1613,\n            \"name\": \"rocadev2714\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1614,\n            \"name\": \"yojansamuel\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1615,\n            \"name\": \"ledyam\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1616,\n            \"name\": \"chrisfelixgil\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1617,\n            \"name\": \"jatomas\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1618,\n            \"name\": \"jean-carlos-backend-developer\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1619,\n            \"name\": \"sandrarg85\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1620,\n            \"name\": \"angelsoft01\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1621,\n            \"name\": \"marqitos\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1622,\n            \"name\": \"ishimaku\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1623,\n            \"name\": \"paalvarador\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1624,\n            \"name\": \"santiagorf23\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1625,\n            \"name\": \"lobogeekmx\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1626,\n            \"name\": \"pkmaventura\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1627,\n            \"name\": \"fgxmboa\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1628,\n            \"name\": \"lovera7\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1629,\n            \"name\": \"marvinagui\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1630,\n            \"name\": \"analianovoa\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1631,\n            \"name\": \"gquintal\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1632,\n            \"name\": \"astriebeck\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1633,\n            \"name\": \"angel-tineo\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1634,\n            \"name\": \"miguelgargallo\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1635,\n            \"name\": \"rootqui\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1636,\n            \"name\": \"nunezlagos\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1637,\n            \"name\": \"afacorroloscos\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1638,\n            \"name\": \"armm77\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1639,\n            \"name\": \"mickysoft\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1640,\n            \"name\": \"nicorey89\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1641,\n            \"name\": \"cliverjimny123\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1642,\n            \"name\": \"luchof5\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1643,\n            \"name\": \"francomoreira\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1644,\n            \"name\": \"memoo77\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1645,\n            \"name\": \"codejoss\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1646,\n            \"name\": \"lfam200\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1647,\n            \"name\": \"ovmiguel16\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1648,\n            \"name\": \"manuelleon225\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1649,\n            \"name\": \"benjaminsk09\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1650,\n            \"name\": \"carlosguerra1997\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1651,\n            \"name\": \"vainsito1\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1652,\n            \"name\": \"santaravena\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1653,\n            \"name\": \"joshua0730-star\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1654,\n            \"name\": \"kinrgdev\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1655,\n            \"name\": \"joseperesini\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1656,\n            \"name\": \"s9code\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1657,\n            \"name\": \"afl0r3s\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1658,\n            \"name\": \"albabp\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1659,\n            \"name\": \"anto-dasein\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1660,\n            \"name\": \"isnatthy\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1661,\n            \"name\": \"gc796\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1662,\n            \"name\": \"alankevinct\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1663,\n            \"name\": \"jacobrwx\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1664,\n            \"name\": \"leydimadrid\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1665,\n            \"name\": \"johnniew81\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1666,\n            \"name\": \"maximotoro\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1667,\n            \"name\": \"siuldev\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1668,\n            \"name\": \"santiixs\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1669,\n            \"name\": \"kevinramirez28\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1670,\n            \"name\": \"conrado85\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1671,\n            \"name\": \"lucianogriffa\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1672,\n            \"name\": \"dacronik\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1673,\n            \"name\": \"bruno1084\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1674,\n            \"name\": \"royhuamanavila\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1675,\n            \"name\": \"ricarsur\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1676,\n            \"name\": \"mhrosariom\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1677,\n            \"name\": \"brayancordova1\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1678,\n            \"name\": \"dianelis1\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1679,\n            \"name\": \"fernandofl\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1680,\n            \"name\": \"juanflp30\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1681,\n            \"name\": \"dragneelito\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1682,\n            \"name\": \"cgomezadolfo\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1683,\n            \"name\": \"sirnaze0\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1684,\n            \"name\": \"juanserdev\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1685,\n            \"name\": \"quirogapau\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1686,\n            \"name\": \"madelefonb\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1687,\n            \"name\": \"patricioguerra30\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1688,\n            \"name\": \"ljbarajas\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1689,\n            \"name\": \"mdemena\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1690,\n            \"name\": \"nnunezmedina\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1691,\n            \"name\": \"juanpablo-a\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1692,\n            \"name\": \"flarien\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1693,\n            \"name\": \"yessikamichelle\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1694,\n            \"name\": \"recamalesdev\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1695,\n            \"name\": \"nozodev\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1696,\n            \"name\": \"aidicoop\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1697,\n            \"name\": \"cris575\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1698,\n            \"name\": \"pierre-ol\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1699,\n            \"name\": \"imista\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1700,\n            \"name\": \"m4xisil\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1701,\n            \"name\": \"ronnieruuz\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1702,\n            \"name\": \"jd-gm\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1703,\n            \"name\": \"nfom24\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1704,\n            \"name\": \"sejotaz\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1705,\n            \"name\": \"ronitzdev\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1706,\n            \"name\": \"jose-miguel1\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1707,\n            \"name\": \"lopesteban\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1708,\n            \"name\": \"beccaribenjamin\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1709,\n            \"name\": \"antonioverdugo\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1710,\n            \"name\": \"mvillegas18\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1711,\n            \"name\": \"andsoria\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1712,\n            \"name\": \"lugryssd3v\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1713,\n            \"name\": \"sergioab7\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1714,\n            \"name\": \"lytsar\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1715,\n            \"name\": \"sixtodev\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1716,\n            \"name\": \"romanocoder\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1717,\n            \"name\": \"cristiantorres53\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1718,\n            \"name\": \"gerespinosa\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1719,\n            \"name\": \"abengl\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1720,\n            \"name\": \"edgonzz\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1721,\n            \"name\": \"pointfs\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1722,\n            \"name\": \"kouski\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1723,\n            \"name\": \"alexxawada\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1724,\n            \"name\": \"antonioclaros93\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1725,\n            \"name\": \"ercky1980\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1726,\n            \"name\": \"agus-ig\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1727,\n            \"name\": \"jonassegdev\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1728,\n            \"name\": \"xnomada\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1729,\n            \"name\": \"josesalazar1312\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1730,\n            \"name\": \"alvarommedia\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1731,\n            \"name\": \"bebebo79\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1732,\n            \"name\": \"fzcarlitos\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1733,\n            \"name\": \"kronomio\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1734,\n            \"name\": \"diego-santana23\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1735,\n            \"name\": \"victormdev24\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1736,\n            \"name\": \"fullstackarlo\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1737,\n            \"name\": \"hfvaronb\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1738,\n            \"name\": \"jpiacaruso\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1739,\n            \"name\": \"charlscrxs\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1740,\n            \"name\": \"edperez07\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1741,\n            \"name\": \"wdiegow\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1742,\n            \"name\": \"frcan89\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1743,\n            \"name\": \"denisortega\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1744,\n            \"name\": \"alemar16\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1745,\n            \"name\": \"kenzambrano\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1746,\n            \"name\": \"rodmiggithub\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1747,\n            \"name\": \"miguelsarm\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1748,\n            \"name\": \"oscarletelier\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1749,\n            \"name\": \"diegoxxd\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1750,\n            \"name\": \"l3v1xx\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1751,\n            \"name\": \"saintsluis\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1752,\n            \"name\": \"chwdev\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1753,\n            \"name\": \"krrattoss5\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1754,\n            \"name\": \"augustbs\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1755,\n            \"name\": \"abraham9804\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1756,\n            \"name\": \"estefrac\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1757,\n            \"name\": \"xbrianos\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1758,\n            \"name\": \"1978acb\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1759,\n            \"name\": \"ja-bell\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1760,\n            \"name\": \"francisorocha\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1761,\n            \"name\": \"chriszaldana\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1762,\n            \"name\": \"vmga09\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1763,\n            \"name\": \"gonzalo-cordoba\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1764,\n            \"name\": \"rotsenn\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1765,\n            \"name\": \"walkerlyna\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1766,\n            \"name\": \"mekanicas\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1767,\n            \"name\": \"kocho03\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1768,\n            \"name\": \"datrujillog\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1769,\n            \"name\": \"yaojema\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1770,\n            \"name\": \"mryanxx\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1771,\n            \"name\": \"jsruedatorres\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1772,\n            \"name\": \"max23esau\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1773,\n            \"name\": \"rojasvargas\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1774,\n            \"name\": \"javieradev\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1775,\n            \"name\": \"juanfeoru\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1776,\n            \"name\": \"drfcozapata\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1777,\n            \"name\": \"johanrv\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1778,\n            \"name\": \"aleclto7\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1779,\n            \"name\": \"brigham09\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1780,\n            \"name\": \"francescoalterio\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1781,\n            \"name\": \"gustavoguerrero\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1782,\n            \"name\": \"lfwzk\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1783,\n            \"name\": \"omaritoatpoly\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1784,\n            \"name\": \"jrincondev\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1785,\n            \"name\": \"carlosdiaz-dev\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1786,\n            \"name\": \"nixoo657\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1787,\n            \"name\": \"jesus30cano\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1788,\n            \"name\": \"frannm29\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1789,\n            \"name\": \"dmhenaopa\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1790,\n            \"name\": \"chrissr0\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1791,\n            \"name\": \"peticas\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1792,\n            \"name\": \"alexis0717\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1793,\n            \"name\": \"santiagomac\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1794,\n            \"name\": \"tetotille\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1795,\n            \"name\": \"vorosdev\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1796,\n            \"name\": \"luisgarm\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1797,\n            \"name\": \"pipeyz21\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1798,\n            \"name\": \"eabalde\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1799,\n            \"name\": \"deimoshall\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1800,\n            \"name\": \"gabrielcharibpolls\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1801,\n            \"name\": \"leonardo-henao\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1802,\n            \"name\": \"juancamilofvx\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1803,\n            \"name\": \"ldpc999\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1804,\n            \"name\": \"c-blskv\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1805,\n            \"name\": \"emaerniquez\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1806,\n            \"name\": \"carolhs92\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1807,\n            \"name\": \"melonconyogurt\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1808,\n            \"name\": \"astrarothdlcxvi\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1809,\n            \"name\": \"antroc\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1810,\n            \"name\": \"almartinez\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1811,\n            \"name\": \"ddaniel27\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1812,\n            \"name\": \"jjaljuria\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1813,\n            \"name\": \"jstr14\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1814,\n            \"name\": \"thompson6626\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1815,\n            \"name\": \"snaisel\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1816,\n            \"name\": \"emersonxinay\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1817,\n            \"name\": \"h4cker54n\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1818,\n            \"name\": \"angel-agis\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1819,\n            \"name\": \"cuervo23alpha\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1820,\n            \"name\": \"ingjavierpinilla\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1821,\n            \"name\": \"mauricioobgo\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1822,\n            \"name\": \"joancharles07\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1823,\n            \"name\": \"batmarc91\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1824,\n            \"name\": \"derobpe\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1825,\n            \"name\": \"lordzzz\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1826,\n            \"name\": \"jonadev19\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1827,\n            \"name\": \"jferchotorres\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1828,\n            \"name\": \"alinares94\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1829,\n            \"name\": \"micendev\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1830,\n            \"name\": \"713avo\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1831,\n            \"name\": \"bellodeveloper\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1832,\n            \"name\": \"nachitoe\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1833,\n            \"name\": \"willypaz243\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1834,\n            \"name\": \"sandleon\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1835,\n            \"name\": \"qwik-zghieb\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1836,\n            \"name\": \"carlosmares\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1837,\n            \"name\": \"ouendinga\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1838,\n            \"name\": \"albmartinez\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1839,\n            \"name\": \"jetiradoro\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1840,\n            \"name\": \"mikefig99\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1841,\n            \"name\": \"lesclaz\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1842,\n            \"name\": \"giovannipeirone\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1843,\n            \"name\": \"adridiazz\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1844,\n            \"name\": \"euu92\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1845,\n            \"name\": \"jesus2421\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1846,\n            \"name\": \"whiterbb\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1847,\n            \"name\": \"angelramirez02\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1848,\n            \"name\": \"aaronlopezbarros\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1849,\n            \"name\": \"dfc201692\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1850,\n            \"name\": \"gonzalinuz18\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1851,\n            \"name\": \"wapastor\",\n            \"count\": 1,\n            \"languages\": 1\n        },\n        {\n            \"order\": 1852,\n            \"name\": \"rawc1nnamon\",\n            \"count\": 1,\n            \"languages\": 1\n        }\n    ]\n}"
  },
  {
    "path": "Roadmap/stats.py",
    "content": "import os\nimport re\nimport json\n\nCHALLENGE_PATTERN = r\"^\\d{2} - \"\nEXCLUDED = [\"stats.py\", \"stats.json\", \"ejercicio.md\",\n            \".ds_store\", \"tempcoderunnerfile.py\"]\n\npath = os.path.dirname(__file__)\n\nchallenges = {}\ncurrent_challenge = \"\"\nlanguages = {}\nusers = {}\nfiles_total = 0\n\nfor dirpath, _, files in os.walk(path):\n\n    challenge = os.path.basename(dirpath)\n    if re.match(CHALLENGE_PATTERN, challenge):\n        current_challenge = challenge\n\n    language_files = 0\n\n    for file in files:\n\n        if file.lower() not in EXCLUDED:\n\n            language = os.path.basename(dirpath).lower()\n            languages[language] = languages.get(language, 0) + 1\n\n            user = os.path.splitext(file)[0].lower()\n            user_files = users.get(user, (0, []))[0] + 1\n            user_languages = users.get(user, (0, []))[1]\n            if language not in user_languages:\n                user_languages.append(language)\n\n            users[user] = (user_files, user_languages)\n\n            language_files += 1\n            files_total += 1\n\n    if current_challenge != \"\":\n        challenges[current_challenge] = challenges.get(\n            current_challenge, 0) + language_files\n\nsorted_challenges = sorted(\n    challenges.items(), key=lambda challenge: challenge[1], reverse=True)\n\nsorted_languages = sorted(\n    languages.items(), key=lambda language: language[1], reverse=True)\n\nsorted_users = sorted(\n    users.items(), key=lambda user: (user[1][0], len(user[1][1])), reverse=True)\n\nchallenges_total = len(challenges)\nlanguages_total = len(languages)\nusers_total = len(users)\n\nchallenges_ranking = []\nlanguages_ranking = []\nusers_ranking = []\n\nprint(\"ESTADÍSTICAS:\\n\")\n\nprint(f\"Retos: {challenges_total}\")\nprint(f\"Lenguajes de programación: {languages_total}\")\nprint(f\"Correcciones: {files_total}\")\nprint(f\"Usuarios: {users_total}\")\n\nprint(\"\\nRanking de retos:\")\nfor index, challenge in enumerate(sorted_challenges):\n\n    order = index + 1\n    name = challenge[0]\n    count = challenge[1]\n\n    challenges_ranking.append({\n        \"order\": order,\n        \"name\": name,\n        \"count\": count\n    })\n\n    print(f\"#{order} {name} (Ejercicios: {count})\")\n\nprint(\"\\nRanking de lenguajes:\")\nfor index, language in enumerate(sorted_languages):\n\n    order = index + 1\n    name = language[0]\n    count = language[1]\n    percentage = round((language[1] * 100) / files_total, 2)\n\n    languages_ranking.append({\n        \"order\": order,\n        \"name\": name,\n        \"count\": count,\n        \"percentage\": percentage\n    })\n\n    print(f\"#{order} {name} (Ejercicios: {count}) (Porcentaje: {percentage}%)\")\n\nprint(\"\\nRanking de usuarios:\")\nfor index, user in enumerate(sorted_users):\n\n    order = index + 1\n    name = user[0]\n    count = user[1][0]\n    languages = len(user[1][1])\n\n    users_ranking.append({\n        \"order\": order,\n        \"name\": name,\n        \"count\": count,\n        \"languages\": languages\n    })\n\n    print(\n        f\"#{order} {name} (Ejercicios: {count}) (Lenguajes: {languages})\")\n\ndata = {\n    \"challenges_total\": challenges_total,\n    \"languages_total\": languages_total,\n    \"files_total\": files_total,\n    \"users_total\": users_total,\n    \"challenges_ranking\": challenges_ranking,\n    \"languages_ranking\": languages_ranking,\n    \"users_ranking\": users_ranking\n}\n\njson_data = json.dumps(data, indent=4)\nwith open(os.path.join(path, \"stats.json\"), \"w\") as file:\n    file.write(json_data)\n"
  }
]